Version 1.14.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb7f875..30c91802 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,131 @@
+## 1.14.0 - 2016-1-28
+
+### Core library changes
+* `dart:async`
+  * Added `Future.any` static method.
+  * Added `Stream.fromFutures` constructor.
+
+* `dart:convert`
+  * `Base64Decoder.convert` now takes optional `start` and `end` parameters.
+
+* `dart:core`
+  * Added `current` getter to `StackTrace` class.
+  * `Uri` class added support for data URIs
+      * Added two new constructors: `dataFromBytes` and `dataFromString`.
+      * Added a `data` getter for `data:` URIs with a new `UriData` class for
+      the return type.
+  * Added `growable` parameter to `List.filled` constructor.
+  * Added microsecond support to `DateTime`: `DateTime.microsecond`,
+    `DateTime.microsecondsSinceEpoch`, and
+    `new DateTime.fromMicrosecondsSinceEpoch`.
+
+* `dart:math`
+  * `Random` added a `secure` constructor returning a cryptographically secure
+    random generator which reads from the entropy source provided by the
+    embedder for every generated random value.
+
+* `dart:io`
+  * `Platform` added a static `isIOS` getter and `Platform.operatingSystem` may
+    now return `ios`.
+  * `Platform` added a static `packageConfig` getter.
+  * Added support for WebSocket compression as standardized in RFC 7692.
+  * Compression is enabled by default for all WebSocket connections.
+      * The optionally named parameter `compression` on the methods
+      `WebSocket.connect`, `WebSocket.fromUpgradedSocket`, and
+      `WebSocketTransformer.upgrade` and  the `WebSocketTransformer`
+      constructor can be used to modify or disable compression using the new
+      `CompressionOptions` class.
+
+* `dart:isolate`
+  * Added **_experimental_** support for [Package Resolution Configuration].
+    * Added `packageConfig` and `packageRoot` instance getters to `Isolate`.
+    * Added a `resolvePackageUri` method to `Isolate`.
+    * Added named arguments `packageConfig` and `automaticPackageResolution` to
+    the `Isolate.spawnUri` constructor.
+
+[Package Resolution Configuration]: https://github.com/dart-lang/dart_enhancement_proposals/blob/master/Accepted/0005%20-%20Package%20Specification/DEP-pkgspec.md
+
+### Tool changes
+
+* `dartfmt`
+
+  * Better line splitting in a variety of cases.
+
+  * Other optimizations and bug fixes.
+
+* Pub
+
+  * **Breaking:** Pub now eagerly emits an error when a pubspec's "name" field
+    is not a valid Dart identifier. Since packages with non-identifier names
+    were never allowed to be published, and some of them already caused crashes
+    when being written to a `.packages` file, this is unlikely to break many
+    people in practice.
+
+  * **Breaking:** Support for `barback` versions prior to 0.15.0 (released July
+    2014) has been dropped. Pub will no longer install these older barback
+    versions.
+
+  * `pub serve` now GZIPs the assets it serves to make load times more similar
+    to real-world use-cases.
+
+  * `pub deps` now supports a `--no-dev` flag, which causes it to emit the
+    dependency tree as it would be if no `dev_dependencies` were in use. This
+    makes it easier to see your package's dependency footprint as your users
+    will experience it.
+
+  * `pub global run` now detects when a global executable's SDK constraint is no
+    longer met and errors out, rather than trying to run the executable anyway.
+
+  * Pub commands that check whether the lockfile is up-to-date (`pub run`, `pub
+    deps`, `pub serve`, and `pub build`) now do additional verification. They
+    ensure that any path dependencies' pubspecs haven't been changed, and they
+    ensure that the current SDK version is compatible with all dependencies.
+
+  * Fixed a crashing bug when using `pub global run` on a global script that
+    didn't exist.
+
+  * Fixed a crashing bug when a pubspec contains a dependency without a source
+    declared.
+
+## 1.13.2 - 2016-01-06
+
+Patch release, resolves one issue:
+
+* dart2js: Stack traces are not captured correctly (SDK issue [25235]
+(https://github.com/dart-lang/sdk/issues/25235))
+
+## 1.13.1 - 2015-12-17
+
+Patch release, resolves three issues:
+
+* VM type propagation fix: Resolves a potential crash in the Dart VM (SDK commit
+ [dff13be]
+(https://github.com/dart-lang/sdk/commit/dff13bef8de104d33b04820136da2d80f3c835d7))
+
+* dart2js crash fix: Resolves a crash in pkg/js and dart2js (SDK issue [24974]
+(https://github.com/dart-lang/sdk/issues/24974))
+
+* Pub get crash on ARM: Fixes a crash triggered when running 'pub get' on ARM
+ processors such as those on a Raspberry Pi (SDK issue [24855]
+(https://github.com/dart-lang/sdk/issues/24855))
+
 ## 1.13.0 - 2015-11-18
 
 ### Core library changes
 * `dart:async`
+  * `StreamController` added getters for `onListen`, `onPause`, and `onResume`
+    with the corresponding new `typedef void ControllerCallback()`.
+  * `StreamController` added a getter for `onCancel` with the corresponding
+    new `typedef ControllerCancelCallback()`;
   * `StreamTransformer` instances created with `fromHandlers` with no
     `handleError` callback now forward stack traces along with errors to the
     resulting streams.
 
+* `dart:convert`
+  * Added support for Base-64 encoding and decoding.
+    * Added new classes `Base64Codec`, `Base64Encoder`, and `Base64Decoder`.
+    * Added new top-level `const Base64Codec BASE64`.
+
 * `dart:core`
   * `Uri` added `removeFragment` method.
   * `String.allMatches` (implementing `Pattern.allMatches`) is now lazy,
@@ -15,7 +135,18 @@
 * `dart:developer`
   * Added `Timeline` class for interacting with Observatory's timeline feature.
   * Added `ServiceExtensionHandler`, `ServiceExtensionResponse`, and `registerExtension` which enable developers to provide their own VM service protocol extensions.
-  
+
+* `dart:html`, `dart:indexed_db`, `dart:svg`, `dart:web_audio`, `dart:web_gl`, `dart:web_sql`
+  * The return type of some APIs changed from `double` to `num`. Dartium is now
+    using
+    JS interop for most operations. JS does not distinguish between numeric
+    types, and will return a number as an int if it fits in an int. This will
+    mostly cause an error if you assign to something typed `double` in
+    checked mode. You may
+    need to insert a `toDouble()` call or accept `num`. Examples of APIs that
+    are affected include `Element.getBoundingClientRect` and
+    `TextMetrics.width`.
+
 * `dart:io`
   * **Breaking:** Secure networking has changed, replacing the NSS library
     with the BoringSSL library. `SecureSocket`, `SecureServerSocket`,
@@ -33,16 +164,23 @@
     allowed by the HTTP protocol.
     The `HttpServer` still gracefully receives fragments, but discards them
     before delivering the request.
-  * Removed server socket references. The use of server socket references
-    was deprecated back in 1.9. Use the `shared` flag when creating listening
-    sockets and `HttpServer` to distribute accepted sockets between isolates.
+  * To allow connections to be accepted on the same port across different
+    isolates, set the `shared` argument to `true` when creating server socket
+    and `HttpServer` instances.
+    * The deprecated `ServerSocketReference` and `RawServerSocketReference`
+      classes have been removed.
+    * The corresponding `reference` properties on `ServerSocket` and
+      `RawServerSocket` have been removed.
 
 * `dart:isolate`
   * `spawnUri` added an `environment` named argument.
 
 ### Tool changes
 
-* `docgen` and 'dartdocgen' no longer ship in the sdk. The `docgen` sources have
+* `dart2js` and Dartium now support improved Javascript Interoperability via the
+  [js package](https://pub.dartlang.org/packages/js).
+
+* `docgen` and `dartdocgen` no longer ship in the SDK. The `docgen` sources have
    been removed from the repository.
 
 * This is the last release to ship the VM's "legacy debug protocol".
@@ -52,6 +190,17 @@
   of a number of issues uncovered by the first few non-observatory
   clients.  This is a potentially breaking change for clients.
 
+* Dartium has been substantially changed. Rather than using C++ calls into
+  Chromium internals for DOM operations it now uses JS interop.
+  The DOM objects in `dart:html` and related libraries now wrap
+  a JavaScript object and delegate operations to it. This should be
+  mostly transparent to users. However, performance and memory characteristics
+  may be different from previous versions. There may be some changes in which
+  DOM objects are wrapped as Dart objects. For example, if you get a reference
+  to a Window object, even through JS interop, you will always see it as a
+  Dart Window, even when used cross-frame. We expect the change to using
+  JS interop will make it much simpler to update to new Chrome versions.
+
 ## 1.12.2 - 2015-10-21
 
 ### Core library changes
diff --git a/DEPS b/DEPS
index 1b0567c..fbe59dc 100644
--- a/DEPS
+++ b/DEPS
@@ -7,16 +7,6 @@
   # simply sdk, but if using special gclient specs it can be different.
   "dart_root": "sdk",
 
-  # The svn location to pull out dependencies from
-  "third_party": "http://dart.googlecode.com/svn/third_party",
-
-  # The svn location for pulling pinned revisions of bleeding edge dependencies.
-  "bleeding_edge": "http://dart.googlecode.com/svn/branches/bleeding_edge",
-
-  # Use this googlecode_url variable only if there is an internal mirror for it.
-  # If you do not know, use the full path while defining your new deps entry.
-  "googlecode_url": "http://%s.googlecode.com/svn",
-
   # We use mirrors of all github repos to guarantee reproducibility and
   # consistency between what users see and what the bots see.
   # We need the mirrors to not have 100+ bots pulling github constantly.
@@ -32,65 +22,58 @@
       "https://chromium.googlesource.com/external/github.com/dart-lang/%s.git",
 
   "gyp_rev": "@6ee91ad8659871916f9aa840d42e1513befdf638",
-  "co19_rev": "@ead3698f33d2cd41e75b6ce5d4a1203767cedd50",
-  "chromium_url": "http://src.chromium.org/svn",
+  "co19_rev": "@3ed795ea02e022ef19c77cf1b6095b7c8f5584d0",
   "chromium_git": "https://chromium.googlesource.com",
 
   # Revisions of /third_party/* dependencies.
-  "7zip_rev" : "@19997",
-  "analyzer_cli_rev" : "@c7a22746baaa8ee6b3e6b0378f9ad9de6e486186",
   "args_tag": "@0.13.0",
-  "async_tag": "@1.2.0",
+  "async_tag": "@1.4.0",
   "barback_tag" : "@0.15.2+7",
   "boringssl_rev" : "@daeafc22c66ad48f6b32fc8d3362eb9ba31b774e",
   "charcode_tag": "@1.1.0",
   "chrome_rev" : "@19997",
-  "clang_rev" : "@28450",
   "cli_util_tag" : "@0.0.1+2",
-  "collection_rev": "@1da9a07f32efa2ba0c391b289e2037391e31da0e",
+  "collection_rev": "@f6135e6350c63eb3f4dd12953b8d4363faff16fc",
+  "convert_tag": "@1.0.0",
   "crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
   "csslib_tag" : "@0.12.0",
-  "dart2js_info_rev" : "@c4ad464717e3a304fb0d44a6937c25ff2049b863",
-  "dartdoc_rev" : "@18f85ff0b389c417550e541055a84b04273f2b38",
+  "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
+  "dartdoc_tag" : "@v0.8.5",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
-  "dart_style_tag": "@0.2.0",
+  "dart_style_tag": "@0.2.2",
   "dev_compiler_rev": "@0.1.9",
-  "fake_async_rev" : "@38614",
-  "firefox_jsshell_rev" : "@45554",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
-  "gsutil_rev" : "@33376",
   "html_tag" : "@0.12.1+1",
-  "http_rev" : "@9b93e1542c753090c50b46ef1592d44bc858bfe7",
-  "http_multi_server_tag" : "@1.3.2",
-  "http_parser_rev" : "@8b179e36aba985208e4c5fb15cfddd386b6370a4",
+  "http_tag" : "@0.11.3+3",
+  "http_multi_server_tag" : "@2.0.0",
+  "http_parser_tag" : "@1.1.0",
   "http_throttle_rev" : "@a81f08be942cdd608883c7b67795c12226abc235",
   "idl_parser_rev": "@6316d5982dc24b34d09dd8b10fbeaaff28d83a48",
-  "intl_rev": "@32047558bd220a53c1f4d93a26d54b83533b1475",
+  "intl_rev": "@a8b480b9c436f6c0ec16730804c914bdb4e30d53",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@1.1.1",
-  "linter_rev": "@99e2607faf0e9bc522f2f12a24ba50f2954dbbff",
+  "linter_rev": "@5a599fd32d3b6ef00ffa7c330d1f32bbad287228",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
   "matcher_tag": "@0.12.0",
   "metatest_rev": "@e5aa8e4e19fc4188ac2f6d38368a47d8f07c3df1",
   "mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
   "mustache4dart_rev" : "@5724cfd85151e5b6b53ddcd3380daf188fe47f92",
-  "oauth2_rev": "@1bff41f4d54505c36f2d1a001b83b8b745c452f5",
+  "oauth2_tag": "@1.0.0",
   "observe_rev": "@eee2b8ec34236fa46982575fbccff84f61202ac6",
-  "observatory_pub_packages_rev": "@5c199c5954146747f75ed127871207718dc87786",
+  "observatory_pub_packages_rev": "@cf90eb9077177d3d6b3fd5e8289477c2385c026a",
   "package_config_rev": "@0.1.3",
   "path_tag": "@1.3.6",
-  "petitparser_rev" : "@37878",
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "plugin_tag": "@0.1.0",
-  "pool_rev": "@e454b4b54d2987e8d2f0fbd3ac519641ada9bd0f",
-  "pub_rev": "@1c08b841158e33b8090bb07e5c39df830db58d44",
+  "pool_tag": "@1.2.1",
+  "pub_rev": "@57a17f2567d1ff3325960d0960f939fa243b5fd7",
   "pub_cache_tag": "@v0.1.0",
   "pub_semver_tag": "@1.2.1",
   "quiver_tag": "@0.21.4",
   "root_certificates_rev": "@c3a41df63afacec62fcb8135196177e35fe72f71",
-  "scheduled_test_tag": "@0.12.1+2",
-  "shelf_tag": "@0.6.2+1",
+  "scheduled_test_tag": "@0.12.4+2",
+  "shelf_tag": "@0.6.4+3",
   "smoke_rev" : "@f3361191cc2a85ebc1e4d4c33aec672d7915aba9",
   "source_maps_tag": "@0.10.1",
   "shelf_static_tag": "@0.2.3+1",
@@ -100,7 +83,7 @@
   "stack_trace_tag": "@1.4.2",
   "string_scanner_tag": "@0.1.4",
   "sunflower_rev": "@879b704933413414679396b129f5dfa96f7a0b1e",
-  "test_tag": "@0.12.3+8",
+  "test_tag": "@0.12.6+1",
   "test_reflective_loader_tag": "@0.0.3",
   "utf_rev": "@1f55027068759e2d52f2c12de6a57cce5f3c5ee6",
   "unittest_tag": "@0.11.6",
@@ -109,10 +92,9 @@
   "when_tag": "@0.2.0+2",
   "which_tag": "@0.1.3+1",
   "web_components_rev": "@0e636b534d9b12c9e96f841e6679398e91a986ec",
-  "WebCore_rev" : "@44061",
+  "WebCore_rev": "@4f90b41b0165f23f412cecdba07b7d81d3fbb5b5",
   "yaml_tag": "@2.1.5",
   "zlib_rev": "@c3d0a6190f2f8c924a05ab6cc97b8f975bddd33f",
-  "font_awesome_rev": "@31824",
   "barback-0.13.0_rev": "@34853",
   "barback-0.14.0_rev": "@36398",
   "barback-0.14.1_rev": "@38525",
@@ -151,29 +133,9 @@
       Var("chromium_git") + "/chromium/src/tools/idl_parser.git" +
       Var("idl_parser_rev"),
 
-  Var("dart_root") + "/third_party/7zip":
-     Var("third_party") + "/7zip" + Var("7zip_rev"),
-  Var("dart_root") + "/third_party/chrome":
-      Var("third_party") + "/chrome" + Var("chrome_rev"),
-  Var("dart_root") + "/third_party/pkg/fake_async":
-      Var("third_party") + "/fake_async" + Var("fake_async_rev"),
-  Var("dart_root") + "/third_party/firefox_jsshell":
-      Var("third_party") + "/firefox_jsshell" + Var("firefox_jsshell_rev"),
-  Var("dart_root") + "/third_party/font-awesome":
-      Var("third_party") + "/font-awesome" + Var("font_awesome_rev"),
-  Var("dart_root") + "/third_party/gsutil":
-      Var("third_party") + "/gsutil" + Var("gsutil_rev"),
-  Var("dart_root") + "/third_party/pkg/petitparser":
-      Var("third_party") + "/petitparser" + Var("petitparser_rev"),
   Var("dart_root") + "/third_party/WebCore":
-      Var("third_party") + "/WebCore" + Var("WebCore_rev"),
+      "https://github.com/dart-lang/webcore.git" + Var("WebCore_rev"),
 
-  Var("dart_root") + "/third_party/dart-services":
-      (Var("github_mirror") % "dart-services") +
-      Var("dart_services_rev"),
-
-  Var("dart_root") + "/third_party/pkg/analyzer_cli":
-      (Var("github_mirror") % "analyzer_cli") + Var("analyzer_cli_rev"),
   Var("dart_root") + "/third_party/pkg/args":
       (Var("github_mirror") % "args") + Var("args_tag"),
   Var("dart_root") + "/third_party/pkg/async":
@@ -186,16 +148,21 @@
       (Var("github_mirror") % "cli_util") + Var("cli_util_tag"),
   Var("dart_root") + "/third_party/pkg/collection":
       (Var("github_mirror") % "collection") + Var("collection_rev"),
+  Var("dart_root") + "/third_party/pkg/convert":
+      "https://github.com/dart-lang/convert.git" + Var("convert_tag"),
   Var("dart_root") + "/third_party/pkg/crypto":
       (Var("github_mirror") % "crypto") + Var("crypto_rev"),
   Var("dart_root") + "/third_party/pkg/csslib":
       (Var("github_mirror") % "csslib") + Var("csslib_tag"),
+  Var("dart_root") + "/third_party/dart-services":
+      (Var("github_mirror") % "dart-services") +
+      Var("dart_services_rev"),
   Var("dart_root") + "/third_party/pkg_tested/dart_style":
       (Var("github_mirror") % "dart_style") + Var("dart_style_tag"),
   Var("dart_root") + "/third_party/pkg/dart2js_info":
       (Var("github_mirror") % "dart2js_info") + Var("dart2js_info_rev"),
   Var("dart_root") + "/third_party/pkg/dartdoc":
-      (Var("github_mirror") % "dartdoc") + Var("dartdoc_rev"),
+      (Var("github_mirror") % "dartdoc") + Var("dartdoc_tag"),
   Var("dart_root") + "/third_party/pkg/dev_compiler":
       (Var("github_mirror") % "dev_compiler") + Var("dev_compiler_rev"),
   Var("dart_root") + "/third_party/pkg/glob":
@@ -203,12 +170,12 @@
   Var("dart_root") + "/third_party/pkg/html":
       (Var("github_mirror") % "html") + Var("html_tag"),
   Var("dart_root") + "/third_party/pkg/http":
-      (Var("github_mirror") % "http") + Var("http_rev"),
+      (Var("github_mirror") % "http") + Var("http_tag"),
   Var("dart_root") + "/third_party/pkg/http_multi_server":
       (Var("github_mirror") % "http_multi_server") +
       Var("http_multi_server_tag"),
   Var("dart_root") + "/third_party/pkg/http_parser":
-      (Var("github_mirror") % "http_parser") + Var("http_parser_rev"),
+      (Var("github_mirror") % "http_parser") + Var("http_parser_tag"),
   Var("dart_root") + "/third_party/pkg/http_throttle":
       (Var("github_mirror") % "http_throttle") +
       Var("http_throttle_rev"),
@@ -233,7 +200,7 @@
       + "/external/github.com/valotas/mustache4dart.git"
       + Var("mustache4dart_rev"),
   Var("dart_root") + "/third_party/pkg/oauth2":
-      (Var("github_mirror") % "oauth2") + Var("oauth2_rev"),
+      (Var("github_mirror") % "oauth2") + Var("oauth2_tag"),
   Var("dart_root") + "/third_party/pkg/observe":
       (Var("github_mirror") % "observe") + Var("observe_rev"),
   Var("dart_root") + "/third_party/observatory_pub_packages":
@@ -247,7 +214,7 @@
   Var("dart_root") + "/third_party/pkg/plugin":
       (Var("github_mirror") % "plugin") + Var("plugin_tag"),
   Var("dart_root") + "/third_party/pkg/pool":
-      (Var("github_mirror") % "pool") + Var("pool_rev"),
+      (Var("github_mirror") % "pool") + Var("pool_tag"),
   Var("dart_root") + "/third_party/pkg/pub_semver":
       (Var("github_mirror") % "pub_semver") + Var("pub_semver_tag"),
   Var("dart_root") + "/third_party/pkg/pub":
@@ -306,18 +273,6 @@
       (Var("github_mirror") % "which") + Var("which_tag"),
   Var("dart_root") + "/third_party/pkg/yaml":
       (Var("github_mirror") % "yaml") + Var("yaml_tag"),
-
-  # These specific versions of barback and source_maps are used for testing and
-  # should be pulled from bleeding_edge even on channels.
-  Var("dart_root") + "/third_party/pkg/barback-0.13.0":
-      Var("bleeding_edge") + "/dart/pkg/barback" + Var("barback-0.13.0_rev"),
-  Var("dart_root") + "/third_party/pkg/barback-0.14.0+3":
-      Var("bleeding_edge") + "/dart/pkg/barback" + Var("barback-0.14.0_rev"),
-  Var("dart_root") + "/third_party/pkg/barback-0.14.1+4":
-      Var("bleeding_edge") + "/dart/pkg/barback" + Var("barback-0.14.1_rev"),
-  Var("dart_root") + "/third_party/pkg/source_maps-0.9.4":
-      Var("bleeding_edge") + "/dart/pkg/source_maps" +
-      Var("source_maps-0.9.4_rev"),
 }
 
 deps_os = {
@@ -330,13 +285,6 @@
     Var("dart_root") + "/third_party/cygwin":
       Var("chromium_git") + "/chromium/deps/cygwin.git" +
       "@c89e446b273697fadf3a10ff1007a97c0b7de6df",
-    Var("dart_root") + "/third_party/drt_resources":
-      Var("chromium_url") +
-      "/trunk/src/webkit/tools/test_shell/resources@157099",
-  },
-  "unix": {
-    Var("dart_root") + "/third_party/clang":
-      Var("third_party") + "/clang" + Var("clang_rev"),
   },
 }
 
@@ -391,4 +339,92 @@
       Var('dart_root') + "/tools/sdks",
     ],
   },
+  {
+    "name": "firefox_jsshell",
+    "pattern": ".",
+    "action": [
+      "download_from_google_storage",
+      "--no_auth",
+      "--no_resume",
+      "--bucket",
+      "dart-dependencies",
+      "--recursive",
+      "--auto_platform",
+      "--extract",
+      "--directory",
+      Var('dart_root') + "/third_party/firefox_jsshell",
+    ],
+  },
+  {
+    "name": "drt_resources",
+    "pattern": ".",
+    "action": [
+      "download_from_google_storage",
+      "--no_auth",
+      "--no_resume",
+      "--bucket",
+      "dart-dependencies",
+      "--platform=win32",
+      "--directory",
+      Var('dart_root') + "/third_party/drt_resources",
+    ],
+  },
+  {
+    "name": "petitparser",
+    "pattern": ".",
+    "action": [
+      "download_from_google_storage",
+      "--no_auth",
+      "--no_resume",
+      "--bucket",
+      "dart-dependencies",
+      "--extract",
+      "-s",
+      Var('dart_root') + "/third_party/pkg/petitparser.tar.gz.sha1",
+    ],
+  },
+  {
+    "name": "7zip",
+    "pattern": ".",
+    "action": [
+      "download_from_google_storage",
+      "--no_auth",
+      "--no_resume",
+      "--bucket",
+      "dart-dependencies",
+      "--platform=win32",
+      "--extract",
+      "-s",
+      Var('dart_root') + "/third_party/7zip.tar.gz.sha1",
+    ],
+  },
+  {
+    "name": "gsutil",
+    "pattern": ".",
+    "action": [
+      "download_from_google_storage",
+      "--no_auth",
+      "--no_resume",
+      "--bucket",
+      "dart-dependencies",
+      "--extract",
+      "-s",
+      Var('dart_root') + "/third_party/gsutil.tar.gz.sha1",
+    ],
+  },
+  {
+    "name": "clang",
+    "pattern": ".",
+    "action": [
+      "download_from_google_storage",
+      "--no_auth",
+      "--no_resume",
+      "--bucket",
+      "dart-dependencies",
+      "--platform=linux*",
+      "--extract",
+      "-s",
+      Var('dart_root') + "/third_party/clang.tar.gz.sha1",
+    ],
+  },
 ]
diff --git a/LICENSE b/LICENSE
index fa95f12..68bcabf 100644
--- a/LICENSE
+++ b/LICENSE
@@ -9,7 +9,6 @@
 bzip2 - in third_party/bzip2
 Commons IO - in third_party/commons-io
 Commons Lang in third_party/commons-lang
-dromaeo - in samples/third_party/dromaeo
 Eclipse - in third_party/eclipse
 gsutil - in third_party/gsutil
 Guava - in third_party/guava
diff --git a/create_sdk.gyp b/create_sdk.gyp
index 769f502..749cda5 100644
--- a/create_sdk.gyp
+++ b/create_sdk.gyp
@@ -20,14 +20,15 @@
         {
           'action_name': 'create_sdk_py',
           'inputs': [
-            # This is neccessary because we have all the pub test files inside
-            # the pub directory instead of in tests/pub. Xcode can only handle
-            # a certain amount of files in one list (also depending on the
-            # length of the path from where you run). This regexp excludes
-            # pub/test
+            # Xcode can only handle a certain amount of files in one list
+            # (also depending on the length of the path from where you run).
             '<!@(["python", "tools/list_files.py",'
-                '"^(?!.*pub/test).*dart$",'
+                '"dart$",'
                 '"sdk/lib"])',
+            'sdk/lib/dart2dart.platform',
+            'sdk/lib/dart_client.platform',
+            'sdk/lib/dart_server.platform',
+            'sdk/lib/dart_shared.platform',
             '<!@(["python", "tools/list_files.py", "", '
                 '"sdk/lib/_internal/js_runtime/lib/preambles"])',
             '<!@(["python", "tools/list_files.py", "", "sdk/bin"])',
diff --git a/dart.gyp b/dart.gyp
index 81a8f05..3e73877 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -25,6 +25,7 @@
       'type': 'none',
       'dependencies': [
         'runtime/dart-runtime.gyp:dart',
+        'runtime/dart-runtime.gyp:dart_precompiled',
         'runtime/dart-runtime.gyp:dart_no_snapshot',
         'runtime/dart-runtime.gyp:run_vm_tests',
         'runtime/dart-runtime.gyp:process_test',
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 3850f20..fb3a9e4 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -2435,6 +2435,7 @@
 \item An expression of the form \code{$e_1 + e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numeric or string value or to \NULL{}.
 \item An expression of one of the forms \code{$-e$}, \code{$e_1$ - $e_2$}, \code{$e_1$ * $e_2$}, \code{$e_1$ / $e_2$,} \code{$e_1$ \~{}/ $e_2$},  \code{$e_1  >  e_2$}, \code{$e_1  <  e_2$}, \code{$e_1$ $>$= $e_2$}, \code{$e_1$ $<$= $e_2$} or \code{$e_1$ \% $e_2$},  where $e$, $e_1$ and $e_2$ are constant expressions that evaluate to a numeric value  or to \NULL{}.
 \item An expression of the form \code{$e_1$?$e_2$:$e3$} where $e_1$, $e_2$ and $e_3$ are constant expressions and $e_1$ evaluates to a boolean value.
+\item An expression of the form \code{$e_1 ?? e_2$} where $e_1$ and $e_2$ are constant expressions.
 \item An expression of the form \code{$e$.length} where $e$ is a constant expression that evaluates to a string value.
 \end{itemize}
 
diff --git a/pkg/analysis_server/.analysis_options b/pkg/analysis_server/.analysis_options
new file mode 100644
index 0000000..7b230dd
--- /dev/null
+++ b/pkg/analysis_server/.analysis_options
@@ -0,0 +1,4 @@
+linter:
+  rules:
+    - unnecessary_brace_in_string_interp
+    - empty_constructor_bodies
diff --git a/pkg/analysis_server/benchmark/integration/README.md b/pkg/analysis_server/benchmark/integration/README.md
index 78431f9..9955c11 100644
--- a/pkg/analysis_server/benchmark/integration/README.md
+++ b/pkg/analysis_server/benchmark/integration/README.md
@@ -20,9 +20,7 @@
 * **inputFile** = the instrumentation or log file
 
 Additional arguments are passed directly to main.dart.
-For example, you may want to specify --newTaskModel to measure performance
-with the new task model versus the old task model,
-or if the log was recorded on one machine and is played back on another,
+For example, if the log was recorded on one machine and is played back on another,
 then you might need to specify -m<oldSrcPath>,<newSrcPath>
 to map the source paths for playback.
 When specifying additional arguments, any occurrences of @tmpSrcDir@
@@ -49,7 +47,6 @@
 *  **-t, --tmpSrcDir         <dirPath>**
 The temporary directory containing source used during performance measurement.
 WARNING: The contents of the target directory will be modified
-*  **--newTaskModel**       enable the use of the new task model
 *  **-d, --diagnosticPort** localhost port on which server
                             will provide diagnostic web pages
 *  **-v, --verbose**        Verbose logging
diff --git a/pkg/analysis_server/benchmark/integration/driver.dart b/pkg/analysis_server/benchmark/integration/driver.dart
index 80aec4c1..aac45a2 100644
--- a/pkg/analysis_server/benchmark/integration/driver.dart
+++ b/pkg/analysis_server/benchmark/integration/driver.dart
@@ -45,8 +45,6 @@
 
   final Logger logger = new Logger('Driver');
 
-  final bool newTaskModel;
-
   /**
    * The diagnostic port for Analysis Server or `null` if none.
    */
@@ -70,7 +68,7 @@
    */
   Completer<Results> _runCompleter = new Completer<Results>();
 
-  Driver({this.newTaskModel, this.diagnosticPort});
+  Driver({this.diagnosticPort});
 
   /**
    * Return a [Future] that completes with the [Results] of running
@@ -114,9 +112,7 @@
     });
     running = true;
     return server
-        .start(
-            diagnosticPort: diagnosticPort,
-            newTaskModel: newTaskModel /*profileServer: true*/)
+        .start(diagnosticPort: diagnosticPort /*profileServer: true*/)
         .then((params) {
       server.listenToOutput(dispatchNotification);
       server.exitCode.then((_) {
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index 100ab6f..e0fbc80 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -26,8 +26,7 @@
   });
   PerfArgs args = parseArgs(rawArgs);
 
-  Driver driver = new Driver(
-      diagnosticPort: args.diagnosticPort, newTaskModel: args.newTaskModel);
+  Driver driver = new Driver(diagnosticPort: args.diagnosticPort);
   Stream<Operation> stream = openInput(args);
   StreamSubscription<Operation> subscription;
   subscription = stream.listen((Operation op) {
@@ -57,7 +56,6 @@
 const HELP_CMDLINE_OPTION = 'help';
 const INPUT_CMDLINE_OPTION = 'input';
 const MAP_OPTION = 'map';
-const NEW_TASK_MODEL_OPTION = 'newTaskModel';
 
 /**
  * The amount of time to give the server to respond to a shutdown request
@@ -94,10 +92,6 @@
       help: '<dirPath>\n'
           'The temporary directory containing source used during performance measurement.\n'
           'WARNING: The contents of the target directory will be modified');
-  _argParser.addFlag(NEW_TASK_MODEL_OPTION,
-      help: "enable the use of the new task model",
-      defaultsTo: false,
-      negatable: false);
   _argParser.addOption(DIAGNOSTIC_PORT_OPTION,
       abbr: 'd',
       help: 'localhost port on which server will provide diagnostic web pages');
@@ -181,8 +175,6 @@
     showHelp = true;
   }
 
-  perfArgs.newTaskModel = args[NEW_TASK_MODEL_OPTION];
-
   String portText = args[DIAGNOSTIC_PORT_OPTION];
   if (portText != null) {
     perfArgs.diagnosticPort = int.parse(portText, onError: (s) {
@@ -253,9 +245,4 @@
    * The diagnostic port for Analysis Server or `null` if none.
    */
   int diagnosticPort;
-
-  /**
-   * `true` if the server should run using the new task model.
-   */
-  bool newTaskModel;
 }
diff --git a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart b/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
index f28ccf4..a36a54a 100644
--- a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
@@ -78,7 +78,7 @@
     await analysisFinished;
 
     print('analysis completed in ${stopwatch.elapsed}');
-    print('completion received at : ${timings}');
+    print('completion received at : $timings');
     await shutdown();
   }
 }
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 707246a..f2c4df2 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -61,7 +61,7 @@
 </style></head>
   <body>
     <h1>Analysis Server API Specification</h1>
-    <h1 style="color:#999999">Version 1.12.0</h1>
+    <h1 style="color:#999999">Version 1.14.0</h1>
     <p>
       This document contains a specification of the API provided by the
       analysis server.  The API in this document is currently under
@@ -405,6 +405,7 @@
       
       
       
+      
      
       
       
@@ -515,6 +516,46 @@
               in multiple contexts in conflicting ways (such as a
               part that is included in multiple libraries).
             </p>
+          </dd></dl></dd><dt class="request"><a name="request_analysis.getReachableSources">analysis.getReachableSources</a> (<a href="#request_analysis.getReachableSources">#</a>)</dt><dd><div class="box"><pre>request: {
+  "id": String
+  "method": "analysis.getReachableSources"
+  "params": {
+    "<b>file</b>": <a href="#type_FilePath">FilePath</a>
+  }
+}</pre><br><pre>response: {
+  "id": String
+  "error": <span style="color:#999999">optional</span> <a href="#type_RequestError">RequestError</a>
+  "result": {
+    "<b>sources</b>": Map&lt;String, List&lt;String&gt;&gt;
+  }
+}</pre></div>
+        <p>
+          Return the transitive closure of reachable sources for a given file.
+        </p>
+        <p>
+          If a request is made for a file which does not exist, or
+          which is not currently subject to analysis (e.g. because it
+          is not associated with any analysis root specified to
+          analysis.setAnalysisRoots), an error of type
+          <tt>GET_REACHABLE_SOURCES_INVALID_FILE</tt> will be generated.
+        </p>
+        
+        
+      <h4>Parameters</h4><dl><dt class="field"><b><i>file ( <a href="#type_FilePath">FilePath</a> )</i></b></dt><dd>
+            
+            <p>
+              The file for which reachable source information is being requested.
+            </p>
+          </dd></dl><h4>Returns</h4><dl><dt class="field"><b><i>sources ( Map&lt;String, List&lt;String&gt;&gt; )</i></b></dt><dd>
+            
+            <p>
+              A mapping from source URIs to directly reachable source URIs. For example,
+              a file "foo.dart" that imports "bar.dart" would have the corresponding mapping
+              { "file:///foo.dart" : ["file:///bar.dart"] }.  If "bar.dart" has further imports
+              (or exports) there will be a mapping from the URI "file:///bar.dart" to them.
+              To check if a specific URI is reachable from a given file, clients can check
+              for its presence in the resulting key set.
+            </p>
           </dd></dl></dd><dt class="request"><a name="request_analysis.getLibraryDependencies">analysis.getLibraryDependencies</a> (<a href="#request_analysis.getLibraryDependencies">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.getLibraryDependencies"
@@ -2263,6 +2304,27 @@
               field is omitted if the file is not an HTML file.
             </p>
           </dd></dl></dd></dl>
+    <h2 class="domain"><a name="domain_diagnostic">Domain: diagnostic</a></h2>
+      <p>
+        The diagnostic domain contains server diagnostics APIs.
+      </p>
+      
+    <h3>Requests</h3><dl><dt class="request"><a name="request_diagnostic.getDiagnostics">diagnostic.getDiagnostics</a> (<a href="#request_diagnostic.getDiagnostics">#</a>)</dt><dd><div class="box"><pre>request: {
+  "id": String
+  "method": "diagnostic.getDiagnostics"
+}</pre><br><pre>response: {
+  "id": String
+  "error": <span style="color:#999999">optional</span> <a href="#type_RequestError">RequestError</a>
+  "result": {
+    "<b>contexts</b>": List&lt;<a href="#type_ContextData">ContextData</a>&gt;
+  }
+}</pre></div>
+        <p>Return server diagnostics.</p>
+        
+      <h4>Returns</h4><dl><dt class="field"><b><i>contexts ( List&lt;<a href="#type_ContextData">ContextData</a>&gt; )</i></b></dt><dd>
+            
+            <p>The list of analysis contexts.</p>
+          </dd></dl></dd></dl>
     
       <h2 class="domain"><a name="types">Types</a></h2>
       <p>
@@ -2327,6 +2389,7 @@
       
       
       
+      
     <dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
         <p>
           A directive to begin overlaying the contents of a file.  The
@@ -2712,7 +2775,37 @@
               For suggestions of this kind, the completion is
               the named argument identifier including a trailing ':' and space.
             </p>
-          </dd><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_Element">Element: object</a></dt><dd>
+          </dd><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_ContextData">ContextData: object</a></dt><dd>
+        <p>
+          Information about an analysis context.
+        </p>
+        
+      <dl><dt class="field"><b><i>name ( String )</i></b></dt><dd>
+            
+            <p>
+              The name of the context.
+            </p>
+          </dd><dt class="field"><b><i>explicitFileCount ( int )</i></b></dt><dd>
+            
+            <p>
+              Explicitly analyzed files.
+            </p>
+          </dd><dt class="field"><b><i>implicitFileCount ( int )</i></b></dt><dd>
+            
+            <p>
+              Implicitly analyzed files.
+            </p>
+          </dd><dt class="field"><b><i>workItemQueueLength ( int )</i></b></dt><dd>
+            
+            <p>
+              The number of work items in the queue.
+            </p>
+          </dd><dt class="field"><b><i>cacheEntryExceptions ( List&lt;String&gt; )</i></b></dt><dd>
+            
+            <p>
+              Exceptions associated with cache entries.
+            </p>
+          </dd></dl></dd><dt class="typeDefinition"><a name="type_Element">Element: object</a></dt><dd>
         <p>
           Information about an element (something that can be declared
           in code).
@@ -2776,7 +2869,13 @@
           An enumeration of the kinds of elements.
         </p>
         
-      <dl><dt class="value">CLASS</dt><dt class="value">CLASS_TYPE_ALIAS</dt><dt class="value">COMPILATION_UNIT</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dt class="value">FILE</dt><dt class="value">FUNCTION</dt><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY</dt><dt class="value">LOCAL_VARIABLE</dt><dt class="value">METHOD</dt><dt class="value">PARAMETER</dt><dt class="value">PREFIX</dt><dt class="value">SETTER</dt><dt class="value">TOP_LEVEL_VARIABLE</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNIT_TEST_GROUP</dt><dt class="value">UNIT_TEST_TEST</dt><dt class="value">UNKNOWN</dt></dl></dd><dt class="typeDefinition"><a name="type_ExecutableFile">ExecutableFile: object</a></dt><dd>
+      <dl><dt class="value">CLASS</dt><dt class="value">CLASS_TYPE_ALIAS</dt><dt class="value">COMPILATION_UNIT</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dt class="value">FILE</dt><dt class="value">FUNCTION</dt><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY</dt><dt class="value">LOCAL_VARIABLE</dt><dt class="value">METHOD</dt><dt class="value">PARAMETER</dt><dt class="value">PREFIX</dt><dt class="value">SETTER</dt><dt class="value">TOP_LEVEL_VARIABLE</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNIT_TEST_GROUP</dt><dd>
+            
+            <p><b><i>Deprecated</i></b>: support for tests was removed.</p>
+          </dd><dt class="value">UNIT_TEST_TEST</dt><dd>
+            
+            <p><b><i>Deprecated</i></b>: support for tests was removed.</p>
+          </dd><dt class="value">UNKNOWN</dt></dl></dd><dt class="typeDefinition"><a name="type_ExecutableFile">ExecutableFile: object</a></dt><dd>
         <p>
           A description of an executable file.
         </p>
@@ -2815,7 +2914,12 @@
       <dl><dt class="value">LIBRARY</dt><dt class="value">PART</dt></dl></dd><dt class="typeDefinition"><a name="type_FilePath">FilePath: String</a></dt><dd>
         
         <p>
-          The absolute path of a file.
+          The absolute, normalized path of a file.
+        </p>
+        <p>
+          If the format of a file path in a request is not valid, e.g. the
+          path is not absolute or is not normalized, then an error of type
+          <tt>INVALID_FILE_PATH_FORMAT</tt> will be generated.
         </p>
       </dd><dt class="typeDefinition"><a name="type_FoldingKind">FoldingKind: String</a></dt><dd>
         <p>
@@ -3574,6 +3678,13 @@
               which does not match a file currently subject to
               analysis.
             </p>
+          </dd><dt class="value">GET_REACHABLE_SOURCES_INVALID_FILE</dt><dd>
+            
+            <p>
+              An "analysis.getReachableSources" request specified a FilePath
+              which does not match a file currently subject to
+              analysis.
+            </p>
           </dd><dt class="value">INVALID_ANALYSIS_ROOT</dt><dd>
             
             <p>
@@ -3586,6 +3697,12 @@
               The context root used to create an execution context does not
               exist.
             </p>
+          </dd><dt class="value">INVALID_FILE_PATH_FORMAT</dt><dd>
+            
+            <p>
+              The format of the given file path is invalid, e.g. is not
+              absolute and normalized.
+            </p>
           </dd><dt class="value">INVALID_OVERLAY_CHANGE</dt><dd>
             
             <p>
@@ -3964,13 +4081,13 @@
         </p>
         
         
-      <h4>Feedback</h4><dl><dt class="field"><b><i>coveringExpressionOffsets ( List&lt;int&gt; )</i></b></dt><dd>
+      <h4>Feedback</h4><dl><dt class="field"><b><i>coveringExpressionOffsets ( <span style="color:#999999">optional</span> List&lt;int&gt; )</i></b></dt><dd>
             
             <p>
               The offsets of the expressions that cover the specified
               selection, from the down most to the up most.
             </p>
-          </dd><dt class="field"><b><i>coveringExpressionLengths ( List&lt;int&gt; )</i></b></dt><dd>
+          </dd><dt class="field"><b><i>coveringExpressionLengths ( <span style="color:#999999">optional</span> List&lt;int&gt; )</i></b></dt><dd>
             
             <p>
               The lengths of the expressions that cover the specified
@@ -4251,7 +4368,7 @@
       TBD
     </p>
     <h2 class="domain"><a name="index">Index</a></h2>
-    <h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
+    <h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li></ul></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
   
 
 </body></html>
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
index d4903e6..14bdcb3 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
@@ -4,6 +4,8 @@
 
 library analysis_server.plugin.edit.assist.assist_core;
 
+import 'dart:async';
+
 import 'package:analysis_server/plugin/protocol/protocol.dart'
     show SourceChange;
 import 'package:analyzer/src/generated/engine.dart';
@@ -50,19 +52,42 @@
 }
 
 /**
+ * An object used to provide context information for [AssistContributor]s.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class AssistContext {
+  /**
+   * The [AnalysisContext] to get assists in.
+   */
+  AnalysisContext get analysisContext;
+
+  /**
+   * The length of the selection.
+   */
+  int get selectionLength;
+
+  /**
+   * The start of the selection.
+   */
+  int get selectionOffset;
+
+  /**
+   * The source to get assists in.
+   */
+  Source get source;
+}
+
+/**
  * An object used to produce assists for a specific location.
  *
  * Clients may implement this class when implementing plugins.
  */
 abstract class AssistContributor {
   /**
-   * Return a list of assists for a location in the given [source]. The location
-   * is specified by the [offset] and [length] of the selected region. The
-   * [context] can be used to get additional information that is useful for
-   * computing assists.
+   * Completes with a list of assists for the given [context].
    */
-  List<Assist> computeAssists(
-      AnalysisContext context, Source source, int offset, int length);
+  Future<List<Assist>> computeAssists(AssistContext context);
 }
 
 /**
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
index ccdc123..2da3812 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
@@ -4,42 +4,109 @@
 
 library analysis_server.plugin.edit.assist.assist_dart;
 
+import 'dart:async';
+
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
- * An [AssistContributor] that can be used to contribute assists for Dart
- * files.
+ * An object used to provide context information for [DartAssistContributor]s.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DartAssistContext {
+  /**
+   * The [AnalysisContext] to get assists in.
+   */
+  AnalysisContext get analysisContext;
+
+  /**
+   * The length of the selection.
+   */
+  int get selectionLength;
+
+  /**
+   * The start of the selection.
+   */
+  int get selectionOffset;
+
+  /**
+   * The source to get assists in.
+   */
+  Source get source;
+
+  /**
+   * The [CompilationUnit] to compute assists in.
+   */
+  CompilationUnit get unit;
+}
+
+/**
+ * An [AssistContributor] that can be used to contribute assists for Dart files.
  *
  * Clients may extend this class when implementing plugins.
  */
 abstract class DartAssistContributor implements AssistContributor {
   @override
-  List<Assist> computeAssists(
-      AnalysisContext context, Source source, int offset, int length) {
+  Future<List<Assist>> computeAssists(AssistContext context) async {
+    AnalysisContext analysisContext = context.analysisContext;
+    Source source = context.source;
     if (!AnalysisEngine.isDartFileName(source.fullName)) {
       return Assist.EMPTY_LIST;
     }
-    List<Source> libraries = context.getLibrariesContaining(source);
+    List<Source> libraries = analysisContext.getLibrariesContaining(source);
     if (libraries.isEmpty) {
       return Assist.EMPTY_LIST;
     }
     CompilationUnit unit =
-        context.resolveCompilationUnit2(source, libraries[0]);
+        analysisContext.resolveCompilationUnit2(source, libraries[0]);
     if (unit == null) {
       return Assist.EMPTY_LIST;
     }
-    return internalComputeAssists(unit, offset, length);
+    DartAssistContext dartContext = new _DartAssistContextImpl(context, unit);
+    return internalComputeAssists(dartContext);
   }
 
   /**
-   * Return a list of assists for a location in the given [source]. The location
-   * is specified by the [offset] and [length] of the selected region. The
-   * [context] can be used to get additional information that is useful for
-   * computing assists.
+   * Completes with a list of assists for the given [context].
    */
-  List<Assist> internalComputeAssists(
-      CompilationUnit unit, int offset, int length);
+  Future<List<Assist>> internalComputeAssists(DartAssistContext context);
+}
+
+/**
+ * The implementation of [DartAssistContext].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class _DartAssistContextImpl implements DartAssistContext {
+  final AssistContext _context;
+
+  /**
+   * The [CompilationUnit] to compute assists in.
+   */
+  final CompilationUnit unit;
+
+  _DartAssistContextImpl(this._context, this.unit);
+
+  /**
+   * The [AnalysisContext] to get assists in.
+   */
+  AnalysisContext get analysisContext => _context.analysisContext;
+
+  /**
+   * The length of the selection.
+   */
+  int get selectionLength => _context.selectionLength;
+
+  /**
+   * The start of the selection.
+   */
+  int get selectionOffset => _context.selectionOffset;
+
+  /**
+   * The source to get assists in.
+   */
+  Source get source => _context.source;
 }
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
index 123fa24..0ff626f 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
@@ -4,6 +4,8 @@
 
 library analysis_server.plugin.edit.fix.fix_core;
 
+import 'dart:async';
+
 import 'package:analysis_server/plugin/protocol/protocol.dart'
     show SourceChange;
 import 'package:analyzer/file_system/file_system.dart';
@@ -51,6 +53,28 @@
 }
 
 /**
+ * An object used to provide context information for [FixContributor]s.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FixContext {
+  /**
+   * The [AnalysisContext] to get fixes in.
+   */
+  AnalysisContext get analysisContext;
+
+  /**
+   * The error to fix, should be reported in the given [analysisContext].
+   */
+  AnalysisError get error;
+
+  /**
+   * The [ResourceProvider] to access files and folders.
+   */
+  ResourceProvider get resourceProvider;
+}
+
+/**
  * An object used to produce fixes for a specific error. Fix contributors are
  * long-lived objects and must not retain any state between invocations of
  * [computeFixes].
@@ -59,11 +83,9 @@
  */
 abstract class FixContributor {
   /**
-   * Return a list of fixes for the given [error]. The error was reported
-   * after it's source was analyzed in the given [context].
+   * Return a list of fixes for the given [context].
    */
-  List<Fix> computeFixes(ResourceProvider resourceProvider,
-      AnalysisContext context, AnalysisError error);
+  Future<List<Fix>> computeFixes(FixContext context);
 }
 
 /**
@@ -71,8 +93,8 @@
  * information that is common across a number of fixes and to be shared by those
  * fixes. For example, if an unnecessary cast is found then one of the suggested
  * fixes will be to remove the cast. If there are multiple unnecessary casts in
- * a single file, then there will be multiple fixes, one per occurance, but they
- * will all share the same kind.
+ * a single file, then there will be multiple fixes, one per occurrence, but
+ * they will all share the same kind.
  *
  * Clients may not extend, implement or mix-in this class.
  */
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
index 54baa7c..e8f7104 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
@@ -4,14 +4,28 @@
 
 library analysis_server.plugin.edit.fix.fix_dart;
 
+import 'dart:async';
+
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
-import 'package:analyzer/file_system/file_system.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart'
+    show DartFixContextImpl;
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
+ * An object used to provide context information for [DartFixContributor]s.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DartFixContext implements FixContext {
+  /**
+   * The [CompilationUnit] to compute fixes in.
+   */
+  CompilationUnit get unit;
+}
+
+/**
  * A [FixContributor] that can be used to contribute fixes for errors in Dart
  * files.
  *
@@ -19,28 +33,27 @@
  */
 abstract class DartFixContributor implements FixContributor {
   @override
-  List<Fix> computeFixes(ResourceProvider resourceProvider,
-      AnalysisContext context, AnalysisError error) {
-    Source source = error.source;
+  Future<List<Fix>> computeFixes(FixContext context) async {
+    AnalysisContext analysisContext = context.analysisContext;
+    Source source = context.error.source;
     if (!AnalysisEngine.isDartFileName(source.fullName)) {
       return Fix.EMPTY_LIST;
     }
-    List<Source> libraries = context.getLibrariesContaining(source);
+    List<Source> libraries = analysisContext.getLibrariesContaining(source);
     if (libraries.isEmpty) {
       return Fix.EMPTY_LIST;
     }
     CompilationUnit unit =
-        context.resolveCompilationUnit2(source, libraries[0]);
+        analysisContext.resolveCompilationUnit2(source, libraries[0]);
     if (unit == null) {
       return Fix.EMPTY_LIST;
     }
-    return internalComputeFixes(resourceProvider, unit, error);
+    DartFixContext dartContext = new DartFixContextImpl(context, unit);
+    return internalComputeFixes(dartContext);
   }
 
   /**
-   * Return a list of fixes for the given [error]. The error was reported
-   * against the given compilation [unit].
+   * Return a list of fixes for the given [context].
    */
-  List<Fix> internalComputeFixes(ResourceProvider resourceProvider,
-      CompilationUnit unit, AnalysisError error);
+  Future<List<Fix>> internalComputeFixes(DartFixContext context);
 }
diff --git a/pkg/analysis_server/lib/plugin/edit/utilities/change_builder_dart.dart b/pkg/analysis_server/lib/plugin/edit/utilities/change_builder_dart.dart
deleted file mode 100644
index 7d0e0c7..0000000
--- a/pkg/analysis_server/lib/plugin/edit/utilities/change_builder_dart.dart
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analysis_server.plugin.edit.utilities.change_builder_dart;
-
-import 'package:analysis_server/plugin/edit/utilities/change_builder_core.dart';
-import 'package:analysis_server/src/utilities/change_builder_dart.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-
-/**
- * A [ChangeBuilder] used to build changes in Dart files.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DartChangeBuilder extends ChangeBuilder {
-  /**
-   * Initialize a newly created change builder.
-   */
-  factory DartChangeBuilder(AnalysisContext context) = DartChangeBuilderImpl;
-}
-
-/**
- * An [EditBuilder] used to build edits in Dart files.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DartEditBuilder extends EditBuilder {
-  /**
-   * The group-id used for the name of a declaration.
-   */
-  static const String NAME_GROUP_ID = 'NAME';
-
-  /**
-   * The group-id used for the return type of a function, getter or method.
-   */
-  static const String RETURN_TYPE_GROUP_ID = 'RETURN_TYPE';
-
-  /**
-   * The group-id used for the name of the superclass in a class declaration.
-   */
-  static const String SUPERCLASS_GROUP_ID = 'SUPERCLASS';
-
-  /**
-   * Write the code for a declaration of a class with the given [name]. If a
-   * list of [interfaces] is provided, then the class will implement those
-   * interfaces. If [isAbstract] is `true`, then the class will be abstract. If
-   * a [memberWriter] is provided, then it will be invoked to allow members to
-   * be generated. (The members will automatically be preceeded and followed by
-   * end-of-line markers.) If a list of [mixins] is provided, then the class
-   * will mix in those classes. If a [nameGroupName] is provided, then the name
-   * of the class will be included in the linked edit group with that name. If a
-   * [superclass] is given then it will be the superclass of the class. (If a
-   * list of [mixins] is provided but no [superclass] is given then the class
-   * will extend `Object`.)
-   */
-  void writeClassDeclaration(String name,
-      {Iterable<DartType> interfaces,
-      bool isAbstract: false,
-      void memberWriter(),
-      Iterable<DartType> mixins,
-      String nameGroupName,
-      DartType superclass});
-
-  /**
-   * Write the code for a declaration of a field with the given [name]. If an
-   * [initializerWriter] is provided, it will be invoked to write the content of
-   * the initializer. (The equal sign separating the field name from the
-   * initializer expression will automatically be written.) If [isConst] is
-   * `true`, then the declaration will be preceeded by the `const` keyword. If
-   * [isFinal] is `true`, then the declaration will be preceeded by the `final`
-   * keyword. (If both [isConst] and [isFinal] are `true`, then only the `const`
-   * keyword will be written.) If [isStatic] is `true`, then the declaration
-   * will be preceeded by the `static` keyword. If a [nameGroupName] is
-   * provided, the name of the field will be included in the linked edit group
-   * with that name. If a [type] is provided, then it will be used as the type
-   * of the field. (The keyword `var` will be provided automatically when
-   * required.) If a [typeGroupName] is provided, then if a type was written
-   * it will be in the linked edit group with that name.
-   */
-  void writeFieldDeclaration(String name,
-      {void initializerWriter(),
-      bool isConst: false,
-      bool isFinal: false,
-      bool isStatic: false,
-      String nameGroupName,
-      DartType type,
-      String typeGroupName});
-
-  /**
-   * Write the code for a declaration of a getter with the given [name]. If a
-   * [bodyWriter] is provided, it will be invoked to write the body of the
-   * getter. (The space between the name and the body will automatically be
-   * written.) If [isStatic] is `true`, then the declaration will be preceeded
-   * by the `static` keyword. If a [nameGroupName] is provided, the name of the
-   * getter will be included in the linked edit group with that name. If a
-   * [returnType] is provided, then it will be used as the return type of the
-   * getter. If a [returnTypeGroupName] is provided, then if a return type was
-   * written it will be in the linked edit group with that name.
-   */
-  void writeGetterDeclaration(String name,
-      {void bodyWriter(),
-      bool isStatic: false,
-      String nameGroupName,
-      DartType returnType,
-      String returnTypeGroupName});
-
-  /**
-   * Append a placeholder for an override of the specified inherited [member].
-   */
-  void writeOverrideOfInheritedMember(ExecutableElement member);
-
-  /**
-   * Write the code for a list of [parameters], including the surrounding
-   * parentheses.
-   */
-  void writeParameters(Iterable<ParameterElement> parameters);
-
-  /**
-   * Write the code for a list of parameters that would match the given list of
-   * [arguments], including the surrounding parentheses.
-   */
-  void writeParametersMatchingArguments(ArgumentList arguments);
-
-  /**
-   * Write the code for a single parameter with the given [type] and [name].
-   * The [type] can be `null` if no type is to be specified for the parameter.
-   */
-  void writeParameterSource(DartType type, String name);
-
-  /**
-   * Write the code for a type annotation for the given [type]. If the [type] is
-   * either `null` or represents the type 'dynamic', then the behavior depends
-   * on whether a type is [required]. If [required] is `true`, then 'var' will
-   * be written; otherwise, nothing is written.
-   *
-   * If the [groupName] is not `null`, then the name of the type (including type
-   * parameters) will be included as a region in the linked edit group with that
-   * name. If the [groupName] is not `null` and [addSupertypeProposals] is
-   * `true`, then all of the supertypes of the [type] will be added as
-   * suggestions for alternatives to the type name.
-   */
-  bool writeType(DartType type,
-      {bool addSupertypeProposals: false,
-      String groupName,
-      bool required: false});
-}
-
-/**
- * A [FileEditBuilder] used to build edits for Dart files.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DartFileEditBuilder extends FileEditBuilder {}
diff --git a/pkg/analysis_server/lib/plugin/index/index.dart b/pkg/analysis_server/lib/plugin/index/index.dart
deleted file mode 100644
index b87fce9..0000000
--- a/pkg/analysis_server/lib/plugin/index/index.dart
+++ /dev/null
@@ -1,43 +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.
-
-/**
- * Support for client code that extends the analysis server by adding new index
- * contributors.
- *
- * Plugins can register index contributors. The registered contributors will be
- * used to contribute relationships to the index when the analysis of a file has
- * been completed.
- *
- * Typical relationships include things like "this variable is referenced here"
- * or "this method is invoked here". The index is used to improve the
- * performance of operations such as search or building a type hierarchy by
- * pre-computing some of the information needed by those operations.
- *
- * If a plugin wants to contribute information to the index, it should implement
- * the class [IndexContributor] and then register the contributor by including
- * code like the following in the plugin's registerExtensions method:
- *
- *     @override
- *     void registerExtensions(RegisterExtension registerExtension) {
- *       ...
- *       registerExtension(
- *           INDEX_CONTRIBUTOR_EXTENSION_POINT_ID,
- *           new MyIndexContributor());
- *       ...
- *     }
- */
-library analysis_server.plugin.index.index;
-
-import 'package:analysis_server/plugin/index/index_core.dart';
-import 'package:analysis_server/src/plugin/server_plugin.dart';
-import 'package:plugin/plugin.dart';
-
-/**
- * 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,
-    ServerPlugin.INDEX_CONTRIBUTOR_EXTENSION_POINT);
diff --git a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
index db3e626..d90344f 100644
--- a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
@@ -938,6 +938,176 @@
     return JenkinsSmiHash.finish(hash);
   }
 }
+
+/**
+ * analysis.getReachableSources params
+ *
+ * {
+ *   "file": FilePath
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class AnalysisGetReachableSourcesParams implements HasToJson {
+  String _file;
+
+  /**
+   * The file for which reachable source information is being requested.
+   */
+  String get file => _file;
+
+  /**
+   * The file for which reachable source information is being requested.
+   */
+  void set file(String value) {
+    assert(value != null);
+    this._file = value;
+  }
+
+  AnalysisGetReachableSourcesParams(String file) {
+    this.file = file;
+  }
+
+  factory AnalysisGetReachableSourcesParams.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String file;
+      if (json.containsKey("file")) {
+        file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "file");
+      }
+      return new AnalysisGetReachableSourcesParams(file);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "analysis.getReachableSources params", json);
+    }
+  }
+
+  factory AnalysisGetReachableSourcesParams.fromRequest(Request request) {
+    return new AnalysisGetReachableSourcesParams.fromJson(
+        new RequestDecoder(request), "params", request._params);
+  }
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["file"] = file;
+    return result;
+  }
+
+  Request toRequest(String id) {
+    return new Request(id, "analysis.getReachableSources", toJson());
+  }
+
+  @override
+  String toString() => JSON.encode(toJson());
+
+  @override
+  bool operator==(other) {
+    if (other is AnalysisGetReachableSourcesParams) {
+      return file == other.file;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, file.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * analysis.getReachableSources result
+ *
+ * {
+ *   "sources": Map<String, List<String>>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class AnalysisGetReachableSourcesResult implements HasToJson {
+  Map<String, List<String>> _sources;
+
+  /**
+   * A mapping from source URIs to directly reachable source URIs. For example,
+   * a file "foo.dart" that imports "bar.dart" would have the corresponding
+   * mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If "bar.dart" has
+   * further imports (or exports) there will be a mapping from the URI
+   * "file:///bar.dart" to them. To check if a specific URI is reachable from a
+   * given file, clients can check for its presence in the resulting key set.
+   */
+  Map<String, List<String>> get sources => _sources;
+
+  /**
+   * A mapping from source URIs to directly reachable source URIs. For example,
+   * a file "foo.dart" that imports "bar.dart" would have the corresponding
+   * mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If "bar.dart" has
+   * further imports (or exports) there will be a mapping from the URI
+   * "file:///bar.dart" to them. To check if a specific URI is reachable from a
+   * given file, clients can check for its presence in the resulting key set.
+   */
+  void set sources(Map<String, List<String>> value) {
+    assert(value != null);
+    this._sources = value;
+  }
+
+  AnalysisGetReachableSourcesResult(Map<String, List<String>> sources) {
+    this.sources = sources;
+  }
+
+  factory AnalysisGetReachableSourcesResult.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      Map<String, List<String>> sources;
+      if (json.containsKey("sources")) {
+        sources = jsonDecoder.decodeMap(jsonPath + ".sources", json["sources"], valueDecoder: (String jsonPath, Object json) => jsonDecoder.decodeList(jsonPath, json, jsonDecoder.decodeString));
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "sources");
+      }
+      return new AnalysisGetReachableSourcesResult(sources);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "analysis.getReachableSources result", json);
+    }
+  }
+
+  factory AnalysisGetReachableSourcesResult.fromResponse(Response response) {
+    return new AnalysisGetReachableSourcesResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), "result", response._result);
+  }
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["sources"] = sources;
+    return result;
+  }
+
+  Response toResponse(String id) {
+    return new Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => JSON.encode(toJson());
+
+  @override
+  bool operator==(other) {
+    if (other is AnalysisGetReachableSourcesResult) {
+      return mapEqual(sources, other.sources, (List<String> a, List<String> b) => listEqual(a, b, (String a, String b) => a == b));
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, sources.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
 /**
  * analysis.getLibraryDependencies params
  *
@@ -7421,6 +7591,109 @@
     return JenkinsSmiHash.finish(hash);
   }
 }
+/**
+ * diagnostic.getDiagnostics params
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class DiagnosticGetDiagnosticsParams {
+  Request toRequest(String id) {
+    return new Request(id, "diagnostic.getDiagnostics", null);
+  }
+
+  @override
+  bool operator==(other) {
+    if (other is DiagnosticGetDiagnosticsParams) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    return 587526202;
+  }
+}
+
+/**
+ * diagnostic.getDiagnostics result
+ *
+ * {
+ *   "contexts": List<ContextData>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class DiagnosticGetDiagnosticsResult implements HasToJson {
+  List<ContextData> _contexts;
+
+  /**
+   * The list of analysis contexts.
+   */
+  List<ContextData> get contexts => _contexts;
+
+  /**
+   * The list of analysis contexts.
+   */
+  void set contexts(List<ContextData> value) {
+    assert(value != null);
+    this._contexts = value;
+  }
+
+  DiagnosticGetDiagnosticsResult(List<ContextData> contexts) {
+    this.contexts = contexts;
+  }
+
+  factory DiagnosticGetDiagnosticsResult.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<ContextData> contexts;
+      if (json.containsKey("contexts")) {
+        contexts = jsonDecoder.decodeList(jsonPath + ".contexts", json["contexts"], (String jsonPath, Object json) => new ContextData.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "contexts");
+      }
+      return new DiagnosticGetDiagnosticsResult(contexts);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "diagnostic.getDiagnostics result", json);
+    }
+  }
+
+  factory DiagnosticGetDiagnosticsResult.fromResponse(Response response) {
+    return new DiagnosticGetDiagnosticsResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), "result", response._result);
+  }
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["contexts"] = contexts.map((ContextData value) => value.toJson()).toList();
+    return result;
+  }
+
+  Response toResponse(String id) {
+    return new Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => JSON.encode(toJson());
+
+  @override
+  bool operator==(other) {
+    if (other is DiagnosticGetDiagnosticsResult) {
+      return listEqual(contexts, other.contexts, (ContextData a, ContextData b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, contexts.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
 
 /**
  * AddContentOverlay
@@ -9167,6 +9440,181 @@
 }
 
 /**
+ * ContextData
+ *
+ * {
+ *   "name": String
+ *   "explicitFileCount": int
+ *   "implicitFileCount": int
+ *   "workItemQueueLength": int
+ *   "cacheEntryExceptions": List<String>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class ContextData implements HasToJson {
+  String _name;
+
+  int _explicitFileCount;
+
+  int _implicitFileCount;
+
+  int _workItemQueueLength;
+
+  List<String> _cacheEntryExceptions;
+
+  /**
+   * The name of the context.
+   */
+  String get name => _name;
+
+  /**
+   * The name of the context.
+   */
+  void set name(String value) {
+    assert(value != null);
+    this._name = value;
+  }
+
+  /**
+   * Explicitly analyzed files.
+   */
+  int get explicitFileCount => _explicitFileCount;
+
+  /**
+   * Explicitly analyzed files.
+   */
+  void set explicitFileCount(int value) {
+    assert(value != null);
+    this._explicitFileCount = value;
+  }
+
+  /**
+   * Implicitly analyzed files.
+   */
+  int get implicitFileCount => _implicitFileCount;
+
+  /**
+   * Implicitly analyzed files.
+   */
+  void set implicitFileCount(int value) {
+    assert(value != null);
+    this._implicitFileCount = value;
+  }
+
+  /**
+   * The number of work items in the queue.
+   */
+  int get workItemQueueLength => _workItemQueueLength;
+
+  /**
+   * The number of work items in the queue.
+   */
+  void set workItemQueueLength(int value) {
+    assert(value != null);
+    this._workItemQueueLength = value;
+  }
+
+  /**
+   * Exceptions associated with cache entries.
+   */
+  List<String> get cacheEntryExceptions => _cacheEntryExceptions;
+
+  /**
+   * Exceptions associated with cache entries.
+   */
+  void set cacheEntryExceptions(List<String> value) {
+    assert(value != null);
+    this._cacheEntryExceptions = value;
+  }
+
+  ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, List<String> cacheEntryExceptions) {
+    this.name = name;
+    this.explicitFileCount = explicitFileCount;
+    this.implicitFileCount = implicitFileCount;
+    this.workItemQueueLength = workItemQueueLength;
+    this.cacheEntryExceptions = cacheEntryExceptions;
+  }
+
+  factory ContextData.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String name;
+      if (json.containsKey("name")) {
+        name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "name");
+      }
+      int explicitFileCount;
+      if (json.containsKey("explicitFileCount")) {
+        explicitFileCount = jsonDecoder.decodeInt(jsonPath + ".explicitFileCount", json["explicitFileCount"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "explicitFileCount");
+      }
+      int implicitFileCount;
+      if (json.containsKey("implicitFileCount")) {
+        implicitFileCount = jsonDecoder.decodeInt(jsonPath + ".implicitFileCount", json["implicitFileCount"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "implicitFileCount");
+      }
+      int workItemQueueLength;
+      if (json.containsKey("workItemQueueLength")) {
+        workItemQueueLength = jsonDecoder.decodeInt(jsonPath + ".workItemQueueLength", json["workItemQueueLength"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "workItemQueueLength");
+      }
+      List<String> cacheEntryExceptions;
+      if (json.containsKey("cacheEntryExceptions")) {
+        cacheEntryExceptions = jsonDecoder.decodeList(jsonPath + ".cacheEntryExceptions", json["cacheEntryExceptions"], jsonDecoder.decodeString);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "cacheEntryExceptions");
+      }
+      return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, cacheEntryExceptions);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "ContextData", json);
+    }
+  }
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["name"] = name;
+    result["explicitFileCount"] = explicitFileCount;
+    result["implicitFileCount"] = implicitFileCount;
+    result["workItemQueueLength"] = workItemQueueLength;
+    result["cacheEntryExceptions"] = cacheEntryExceptions;
+    return result;
+  }
+
+  @override
+  String toString() => JSON.encode(toJson());
+
+  @override
+  bool operator==(other) {
+    if (other is ContextData) {
+      return name == other.name &&
+          explicitFileCount == other.explicitFileCount &&
+          implicitFileCount == other.implicitFileCount &&
+          workItemQueueLength == other.workItemQueueLength &&
+          listEqual(cacheEntryExceptions, other.cacheEntryExceptions, (String a, String b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, name.hashCode);
+    hash = JenkinsSmiHash.combine(hash, explicitFileCount.hashCode);
+    hash = JenkinsSmiHash.combine(hash, implicitFileCount.hashCode);
+    hash = JenkinsSmiHash.combine(hash, workItemQueueLength.hashCode);
+    hash = JenkinsSmiHash.combine(hash, cacheEntryExceptions.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * Element
  *
  * {
@@ -9516,8 +9964,14 @@
 
   static const TYPE_PARAMETER = const ElementKind._("TYPE_PARAMETER");
 
+  /**
+   * Deprecated: support for tests was removed.
+   */
   static const UNIT_TEST_GROUP = const ElementKind._("UNIT_TEST_GROUP");
 
+  /**
+   * Deprecated: support for tests was removed.
+   */
   static const UNIT_TEST_TEST = const ElementKind._("UNIT_TEST_TEST");
 
   static const UNKNOWN = const ElementKind._("UNKNOWN");
@@ -13614,8 +14068,10 @@
  *   FORMAT_WITH_ERRORS
  *   GET_ERRORS_INVALID_FILE
  *   GET_NAVIGATION_INVALID_FILE
+ *   GET_REACHABLE_SOURCES_INVALID_FILE
  *   INVALID_ANALYSIS_ROOT
  *   INVALID_EXECUTION_CONTEXT
+ *   INVALID_FILE_PATH_FORMAT
  *   INVALID_OVERLAY_CHANGE
  *   INVALID_PARAMETER
  *   INVALID_REQUEST
@@ -13672,6 +14128,12 @@
   static const GET_NAVIGATION_INVALID_FILE = const RequestErrorCode._("GET_NAVIGATION_INVALID_FILE");
 
   /**
+   * An "analysis.getReachableSources" request specified a FilePath which does
+   * not match a file currently subject to analysis.
+   */
+  static const GET_REACHABLE_SOURCES_INVALID_FILE = const RequestErrorCode._("GET_REACHABLE_SOURCES_INVALID_FILE");
+
+  /**
    * A path passed as an argument to a request (such as analysis.reanalyze) is
    * required to be an analysis root, but isn't.
    */
@@ -13683,6 +14145,12 @@
   static const INVALID_EXECUTION_CONTEXT = const RequestErrorCode._("INVALID_EXECUTION_CONTEXT");
 
   /**
+   * The format of the given file path is invalid, e.g. is not absolute and
+   * normalized.
+   */
+  static const INVALID_FILE_PATH_FORMAT = const RequestErrorCode._("INVALID_FILE_PATH_FORMAT");
+
+  /**
    * An "analysis.updateContent" request contained a ChangeContentOverlay
    * object which can't be applied, due to an edit having an offset or length
    * that is out of range.
@@ -13777,7 +14245,7 @@
   /**
    * A list containing all of the enum values that are defined.
    */
-  static const List<RequestErrorCode> VALUES = const <RequestErrorCode>[CONTENT_MODIFIED, FILE_NOT_ANALYZED, FORMAT_INVALID_FILE, FORMAT_WITH_ERRORS, GET_ERRORS_INVALID_FILE, GET_NAVIGATION_INVALID_FILE, INVALID_ANALYSIS_ROOT, INVALID_EXECUTION_CONTEXT, INVALID_OVERLAY_CHANGE, INVALID_PARAMETER, INVALID_REQUEST, NO_INDEX_GENERATED, ORGANIZE_DIRECTIVES_ERROR, REFACTORING_REQUEST_CANCELLED, SERVER_ALREADY_STARTED, SERVER_ERROR, SORT_MEMBERS_INVALID_FILE, SORT_MEMBERS_PARSE_ERRORS, UNANALYZED_PRIORITY_FILES, UNKNOWN_REQUEST, UNKNOWN_SOURCE, UNSUPPORTED_FEATURE];
+  static const List<RequestErrorCode> VALUES = const <RequestErrorCode>[CONTENT_MODIFIED, FILE_NOT_ANALYZED, FORMAT_INVALID_FILE, FORMAT_WITH_ERRORS, GET_ERRORS_INVALID_FILE, GET_NAVIGATION_INVALID_FILE, GET_REACHABLE_SOURCES_INVALID_FILE, INVALID_ANALYSIS_ROOT, INVALID_EXECUTION_CONTEXT, INVALID_FILE_PATH_FORMAT, INVALID_OVERLAY_CHANGE, INVALID_PARAMETER, INVALID_REQUEST, NO_INDEX_GENERATED, ORGANIZE_DIRECTIVES_ERROR, REFACTORING_REQUEST_CANCELLED, SERVER_ALREADY_STARTED, SERVER_ERROR, SORT_MEMBERS_INVALID_FILE, SORT_MEMBERS_PARSE_ERRORS, UNANALYZED_PRIORITY_FILES, UNKNOWN_REQUEST, UNKNOWN_SOURCE, UNSUPPORTED_FEATURE];
 
   final String name;
 
@@ -13797,10 +14265,14 @@
         return GET_ERRORS_INVALID_FILE;
       case "GET_NAVIGATION_INVALID_FILE":
         return GET_NAVIGATION_INVALID_FILE;
+      case "GET_REACHABLE_SOURCES_INVALID_FILE":
+        return GET_REACHABLE_SOURCES_INVALID_FILE;
       case "INVALID_ANALYSIS_ROOT":
         return INVALID_ANALYSIS_ROOT;
       case "INVALID_EXECUTION_CONTEXT":
         return INVALID_EXECUTION_CONTEXT;
+      case "INVALID_FILE_PATH_FORMAT":
+        return INVALID_FILE_PATH_FORMAT;
       case "INVALID_OVERLAY_CHANGE":
         return INVALID_OVERLAY_CHANGE;
       case "INVALID_PARAMETER":
@@ -15000,8 +15472,8 @@
  * extractLocalVariable feedback
  *
  * {
- *   "coveringExpressionOffsets": List<int>
- *   "coveringExpressionLengths": List<int>
+ *   "coveringExpressionOffsets": optional List<int>
+ *   "coveringExpressionLengths": optional List<int>
  *   "names": List<String>
  *   "offsets": List<int>
  *   "lengths": List<int>
@@ -15031,7 +15503,6 @@
    * the down most to the up most.
    */
   void set coveringExpressionOffsets(List<int> value) {
-    assert(value != null);
     this._coveringExpressionOffsets = value;
   }
 
@@ -15046,7 +15517,6 @@
    * the down most to the up most.
    */
   void set coveringExpressionLengths(List<int> value) {
-    assert(value != null);
     this._coveringExpressionLengths = value;
   }
 
@@ -15097,7 +15567,7 @@
     this._lengths = value;
   }
 
-  ExtractLocalVariableFeedback(List<int> coveringExpressionOffsets, List<int> coveringExpressionLengths, List<String> names, List<int> offsets, List<int> lengths) {
+  ExtractLocalVariableFeedback(List<String> names, List<int> offsets, List<int> lengths, {List<int> coveringExpressionOffsets, List<int> coveringExpressionLengths}) {
     this.coveringExpressionOffsets = coveringExpressionOffsets;
     this.coveringExpressionLengths = coveringExpressionLengths;
     this.names = names;
@@ -15113,14 +15583,10 @@
       List<int> coveringExpressionOffsets;
       if (json.containsKey("coveringExpressionOffsets")) {
         coveringExpressionOffsets = jsonDecoder.decodeList(jsonPath + ".coveringExpressionOffsets", json["coveringExpressionOffsets"], jsonDecoder.decodeInt);
-      } else {
-        throw jsonDecoder.missingKey(jsonPath, "coveringExpressionOffsets");
       }
       List<int> coveringExpressionLengths;
       if (json.containsKey("coveringExpressionLengths")) {
         coveringExpressionLengths = jsonDecoder.decodeList(jsonPath + ".coveringExpressionLengths", json["coveringExpressionLengths"], jsonDecoder.decodeInt);
-      } else {
-        throw jsonDecoder.missingKey(jsonPath, "coveringExpressionLengths");
       }
       List<String> names;
       if (json.containsKey("names")) {
@@ -15140,7 +15606,7 @@
       } else {
         throw jsonDecoder.missingKey(jsonPath, "lengths");
       }
-      return new ExtractLocalVariableFeedback(coveringExpressionOffsets, coveringExpressionLengths, names, offsets, lengths);
+      return new ExtractLocalVariableFeedback(names, offsets, lengths, coveringExpressionOffsets: coveringExpressionOffsets, coveringExpressionLengths: coveringExpressionLengths);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "extractLocalVariable feedback", json);
     }
@@ -15148,8 +15614,12 @@
 
   Map<String, dynamic> toJson() {
     Map<String, dynamic> result = {};
-    result["coveringExpressionOffsets"] = coveringExpressionOffsets;
-    result["coveringExpressionLengths"] = coveringExpressionLengths;
+    if (coveringExpressionOffsets != null) {
+      result["coveringExpressionOffsets"] = coveringExpressionOffsets;
+    }
+    if (coveringExpressionLengths != null) {
+      result["coveringExpressionLengths"] = coveringExpressionLengths;
+    }
     result["names"] = names;
     result["offsets"] = offsets;
     result["lengths"] = lengths;
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol.dart b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
index 823ffd6..9daa9f0 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
@@ -20,7 +20,7 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class DomainHandler extends RequestHandler {
+abstract class DomainHandler implements RequestHandler {
   /**
    * Perform any operations associated with the shutdown of the domain. It is
    * not guaranteed that this method will be called. If it is, it will be
@@ -411,6 +411,16 @@
                 'Error during `analysis.getNavigation`: invalid file.'));
 
   /**
+   * Initialize a newly created instance to represent the
+   * GET_REACHABLE_SOURCES_INVALID_FILE error condition.
+   */
+  Response.getReachableSourcesInvalidFile(Request request)
+      : this(request.id,
+            error: new RequestError(
+                RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE,
+                'Error during `analysis.getReachableSources`: invalid file.'));
+
+  /**
    * Initialize a newly created instance to represent an error condition caused
    * by an analysis.reanalyze [request] that specifies an analysis root that is
    * not in the current list of analysis roots.
@@ -431,6 +441,15 @@
                 "Invalid execution context: $contextId"));
 
   /**
+   * Initialize a newly created instance to represent the
+   * INVALID_FILE_PATH_FORMAT error condition.
+   */
+  Response.invalidFilePathFormat(Request request, path)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.INVALID_FILE_PATH_FORMAT,
+                'Invalid file path format: $path'));
+
+  /**
    * Initialize a newly created instance to represent an error condition caused
    * by a [request] that had invalid parameter.  [path] is the path to the
    * invalid parameter, in Javascript notation (e.g. "foo.bar" means that the
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index c27a188..2c2c2cb 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -10,7 +10,7 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/protocol_server.dart';
-import 'package:analyzer/src/generated/element.dart' as engine;
+import 'package:analyzer/dart/element/element.dart' as engine;
 import 'package:analyzer/src/generated/utilities_dart.dart' as engine;
 
 /**
diff --git a/pkg/analysis_server/lib/src/analysis_logger.dart b/pkg/analysis_server/lib/src/analysis_logger.dart
index 04ad6c6..8b9c9b6 100644
--- a/pkg/analysis_server/lib/src/analysis_logger.dart
+++ b/pkg/analysis_server/lib/src/analysis_logger.dart
@@ -43,13 +43,7 @@
     } else {
       baseLogger.severe(message, exception.exception, exception.stackTrace);
     }
-    server.sendServerErrorNotification(
-        message, exception, exception?.stackTrace);
-  }
-
-  @override
-  void logError2(String message, Object exception) {
-    baseLogger.severe(message, exception);
+    server.sendServerErrorNotification(message, exception, null);
   }
 
   @override
@@ -60,9 +54,4 @@
       baseLogger.info(message, exception.exception, exception.stackTrace);
     }
   }
-
-  @override
-  void logInformation2(String message, Object exception) {
-    baseLogger.info(message, exception);
-  }
 }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 60f8d8c..f0d7931 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -21,11 +21,12 @@
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -33,7 +34,8 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:glob/glob.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/util/glob.dart';
 import 'package:plugin/plugin.dart';
 
 typedef void OptionUpdater(AnalysisOptionsImpl options);
@@ -71,7 +73,7 @@
    * The version of the analysis server. The value should be replaced
    * automatically during the build.
    */
-  static final String VERSION = '1.12.0';
+  static final String VERSION = '1.14.0';
 
   /**
    * The number of milliseconds to perform operations before inserting
@@ -184,8 +186,8 @@
    * A table mapping [AnalysisContext]s to the completers that should be
    * completed when analysis of this context is finished.
    */
-  Map<AnalysisContext,
-          Completer<AnalysisDoneReason>> contextAnalysisDoneCompleters =
+  Map<AnalysisContext, Completer<AnalysisDoneReason>>
+      contextAnalysisDoneCompleters =
       new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>();
 
   /**
@@ -472,22 +474,16 @@
   }
 
   /**
-   * Return the [AnalysisContext] that contains the given [path].
-   * Return `null` if no context contains the [path].
+   * Return the [AnalysisContext] for the "innermost" context whose associated
+   * folder is or contains the given path.  ("innermost" refers to the nesting
+   * of contexts, so if there is a context for path /foo and a context for
+   * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is
+   * the context for /foo/bar.)
+   *
+   * If no context contains the given path, `null` is returned.
    */
   AnalysisContext getContainingContext(String path) {
-    Folder containingFolder = null;
-    AnalysisContext containingContext = null;
-    folderMap.forEach((Folder folder, AnalysisContext context) {
-      if (folder.isOrContains(path)) {
-        if (containingFolder == null ||
-            containingFolder.path.length < folder.path.length) {
-          containingFolder = folder;
-          containingContext = context;
-        }
-      }
-    });
-    return containingContext;
+    return contextManager.getContextFor(path);
   }
 
   /**
@@ -737,6 +733,15 @@
   }
 
   /**
+   * Return `true` if the given path is a valid `FilePath`.
+   *
+   * This means that it is absolute and normalized.
+   */
+  bool isValidFilePath(String path) {
+    return resourceProvider.absolutePathContext.isValid(path);
+  }
+
+  /**
    * Returns a [Future] completing when [file] has been completely analyzed, in
    * particular, all its errors have been computed.  The future is completed
    * with an [AnalysisDoneReason] indicating what caused the file's analysis to
@@ -757,6 +762,10 @@
     if (context == null) {
       return null;
     }
+    // done if everything is already analyzed
+    if (isAnalysisComplete()) {
+      return new Future.value(AnalysisDoneReason.COMPLETE);
+    }
     // schedule context analysis
     schedulePerformAnalysisOperation(context);
     // associate with the context completer
@@ -893,35 +902,28 @@
   /**
    * Sends a `server.error` notification.
    */
-  void sendServerErrorNotification(String msg, exception, stackTrace,
+  void sendServerErrorNotification(String message, exception, stackTrace,
       {bool fatal: false}) {
-    // prepare exception.toString()
-    String exceptionString;
+    StringBuffer buffer = new StringBuffer();
     if (exception != null) {
-      exceptionString = exception.toString();
+      buffer.write(exception);
     } else {
-      exceptionString = 'null exception';
+      buffer.write('null exception');
     }
-    // prepare message
-    String message = msg != null ? '$msg\n$exceptionString' : exceptionString;
-    // prepare stackTrace.toString()
-    String stackTraceString;
     if (stackTrace != null) {
-      stackTraceString = stackTrace.toString();
-    } else {
+      buffer.writeln();
+      buffer.write(stackTrace);
+    } else if (exception is! CaughtException) {
       try {
         throw 'ignored';
       } catch (ignored, stackTrace) {
-        stackTraceString = stackTrace.toString();
-      }
-      if (stackTraceString == null) {
-        // This code should be unreachable.
-        stackTraceString = 'null stackTrace';
+        buffer.writeln();
+        buffer.write(stackTrace);
       }
     }
     // send the notification
     channel.sendNotification(
-        new ServerErrorParams(fatal, message, stackTraceString)
+        new ServerErrorParams(fatal, message, buffer.toString())
             .toNotification());
   }
 
@@ -978,8 +980,11 @@
       Set<String> todoFiles =
           oldFiles != null ? newFiles.difference(oldFiles) : newFiles;
       for (String file in todoFiles) {
-        ContextSourcePair contextSource = getContextSourcePair(file);
+        if (contextManager.isIgnored(file)) {
+          continue;
+        }
         // prepare context
+        ContextSourcePair contextSource = getContextSourcePair(file);
         AnalysisContext context = contextSource.context;
         if (context == null) {
           continue;
@@ -1067,6 +1072,11 @@
     List<String> unanalyzed = new List<String>();
     Source firstSource = null;
     files.forEach((String file) {
+      if (contextManager.isIgnored(file)) {
+        unanalyzed.add(file);
+        return;
+      }
+      // Prepare the context/source pair.
       ContextSourcePair contextSource = getContextSourcePair(file);
       AnalysisContext preferredContext = contextSource.context;
       Source source = contextSource.source;
@@ -1094,7 +1104,8 @@
         contextFound = true;
       }
       for (AnalysisContext context in folderMap.values) {
-        if (context.getKindOf(source) != SourceKind.UNKNOWN) {
+        if (context != preferredContext &&
+            context.getKindOf(source) != SourceKind.UNKNOWN) {
           sourceMap.putIfAbsent(context, () => <Source>[]).add(source);
           contextFound = true;
         }
@@ -1320,7 +1331,7 @@
     }
     // if library has not been resolved yet, the unit will be resolved later
     Source librarySource = librarySources[0];
-    if (context.getLibraryElement(librarySource) == null) {
+    if (context.getResult(librarySource, LIBRARY_ELEMENT5) == null) {
       return null;
     }
     // if library has been already resolved, resolve unit
@@ -1430,7 +1441,7 @@
       for (String pattern in patterns) {
         try {
           _analyzedFilesGlobs
-              .add(new Glob(pattern, context: JavaFile.pathContext));
+              .add(new Glob(JavaFile.pathContext.separator, pattern));
         } catch (exception, stackTrace) {
           AnalysisEngine.instance.logger.logError(
               'Invalid glob pattern: "$pattern"',
@@ -1447,7 +1458,8 @@
         AnalysisEngine.instance.createAnalysisContext();
     context.contentCache = analysisServer.overlayState;
     analysisServer.folderMap[folder] = context;
-    context.sourceFactory = _createSourceFactory(disposition);
+    _locateEmbedderYamls(context, disposition);
+    context.sourceFactory = _createSourceFactory(context, disposition);
     context.analysisOptions =
         new AnalysisOptionsImpl.from(analysisServer.defaultContextOptions);
     analysisServer._onContextsChangedController
@@ -1460,8 +1472,10 @@
   void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) {
     AnalysisContext context = analysisServer.folderMap[contextFolder];
     if (context != null) {
-      context.applyChanges(changeSet);
-      analysisServer.schedulePerformAnalysisOperation(context);
+      ApplyChangesStatus changesStatus = context.applyChanges(changeSet);
+      if (changesStatus.hasChanges) {
+        analysisServer.schedulePerformAnalysisOperation(context);
+      }
       List<String> flushedFiles = new List<String>();
       for (Source source in changeSet.removedSources) {
         flushedFiles.add(source.fullName);
@@ -1516,7 +1530,7 @@
   void updateContextPackageUriResolver(
       Folder contextFolder, FolderDisposition disposition) {
     AnalysisContext context = analysisServer.folderMap[contextFolder];
-    context.sourceFactory = _createSourceFactory(disposition);
+    context.sourceFactory = _createSourceFactory(context, disposition);
     analysisServer._onContextsChangedController
         .add(new ContextsChangedEvent(changed: [context]));
     analysisServer.schedulePerformAnalysisOperation(context);
@@ -1534,15 +1548,39 @@
    * Set up a [SourceFactory] that resolves packages as appropriate for the
    * given [disposition].
    */
-  SourceFactory _createSourceFactory(FolderDisposition disposition) {
-    UriResolver dartResolver = new DartUriResolver(analysisServer.defaultSdk);
-    UriResolver resourceResolver = new ResourceUriResolver(resourceProvider);
+  SourceFactory _createSourceFactory(
+      InternalAnalysisContext context, FolderDisposition disposition) {
     List<UriResolver> resolvers = [];
-    resolvers.add(dartResolver);
-    resolvers.addAll(disposition.createPackageUriResolvers(resourceProvider));
-    resolvers.add(resourceResolver);
+    List<UriResolver> packageUriResolvers =
+        disposition.createPackageUriResolvers(resourceProvider);
+    EmbedderUriResolver embedderUriResolver =
+        new EmbedderUriResolver(context.embedderYamlLocator.embedderYamls);
+    if (embedderUriResolver.length == 0) {
+      // The embedder uri resolver has no mappings. Use the default Dart SDK
+      // uri resolver.
+      resolvers.add(new DartUriResolver(analysisServer.defaultSdk));
+    } else {
+      // The embedder uri resolver has mappings, use it instead of the default
+      // Dart SDK uri resolver.
+      resolvers.add(embedderUriResolver);
+    }
+    resolvers.addAll(packageUriResolvers);
+    resolvers.add(new ResourceUriResolver(resourceProvider));
     return new SourceFactory(resolvers, disposition.packages);
   }
+
+  /// If [disposition] has a package map, attempt to locate `_embedder.yaml`
+  /// files.
+  void _locateEmbedderYamls(
+      InternalAnalysisContext context, FolderDisposition disposition) {
+    Map<String, List<Folder>> packageMap;
+    if (disposition is PackageMapDisposition) {
+      packageMap = disposition.packageMap;
+    } else if (disposition is PackagesFileDisposition) {
+      packageMap = disposition.buildPackageMap(resourceProvider);
+    }
+    context.embedderYamlLocator.refresh(packageMap);
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 1fc175b..a91e47d 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -5,8 +5,9 @@
 library computer.highlights;
 
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
index ddab12f..fc0d77e 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
@@ -5,8 +5,9 @@
 library computer.highlights2;
 
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index a6f7337..45467ca 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -6,54 +6,12 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart'
     show HoverInformation;
+import 'package:analysis_server/src/utilities/documentation.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 
 /**
- * Converts [str] from a Dart Doc string with slashes and stars to a plain text
- * representation of the comment.
- */
-String _removeDartDocDelimiters(String str) {
-  if (str == null) {
-    return null;
-  }
-  // remove /** */
-  if (str.startsWith('/**')) {
-    str = str.substring(3);
-  }
-  if (str.endsWith("*/")) {
-    str = str.substring(0, str.length - 2);
-  }
-  str = str.trim();
-  // remove leading '* '
-  List<String> lines = str.split('\n');
-  StringBuffer sb = new StringBuffer();
-  bool firstLine = true;
-  for (String line in lines) {
-    line = line.trim();
-    if (line.startsWith("*")) {
-      line = line.substring(1);
-      if (line.startsWith(" ")) {
-        line = line.substring(1);
-      }
-    } else if (line.startsWith("///")) {
-      line = line.substring(3);
-      if (line.startsWith(" ")) {
-        line = line.substring(1);
-      }
-    }
-    if (!firstLine) {
-      sb.write('\n');
-    }
-    firstLine = false;
-    sb.write(line);
-  }
-  str = sb.toString();
-  // done
-  return str;
-}
-
-/**
  * A computer for the hover at the specified offset of a Dart [CompilationUnit].
  */
 class DartUnitHoverComputer {
@@ -102,7 +60,7 @@
           ClassElement containingClass =
               element.getAncestor((e) => e is ClassElement);
           if (containingClass != null) {
-            hover.containingClassDescription = containingClass.toString();
+            hover.containingClassDescription = containingClass.displayName;
           }
           // containing library
           LibraryElement library = element.library;
@@ -111,13 +69,16 @@
             hover.containingLibraryPath = library.source.fullName;
           }
         }
+
         // documentation
         hover.dartdoc = _computeDocumentation(element);
       }
       // parameter
       hover.parameter = _safeToString(expression.bestParameterElement);
       // types
-      hover.staticType = _safeToString(expression.staticType);
+      if (element == null || element is VariableElement) {
+        hover.staticType = _safeToString(expression.staticType);
+      }
       hover.propagatedType = _safeToString(expression.propagatedType);
       // done
       return hover;
@@ -130,8 +91,7 @@
     if (element is ParameterElement) {
       element = element.enclosingElement;
     }
-    String dartDoc = element.computeDocumentationComment();
-    return _removeDartDocDelimiters(dartDoc);
+    return removeDartDocDelimiters(element.documentationComment);
   }
 
   static _safeToString(obj) => obj != null ? obj.toString() : null;
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 9b4c9b7..55c6560 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -6,8 +6,9 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/collections.dart';
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart' as engine;
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -199,7 +200,7 @@
     if (constructorNameNode != null) {
       String constructorName = constructorNameNode.name;
       isPrivate = Identifier.isPrivateName(constructorName);
-      name += '.${constructorName}';
+      name += '.$constructorName';
       offset = constructorNameNode.offset;
       length = constructorNameNode.length;
     }
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index b817147..4e2e00b 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
@@ -6,13 +6,34 @@
 
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart' as engine;
 
 /**
  * A computer for class member overrides in a Dart [CompilationUnit].
  */
 class DartUnitOverridesComputer {
+  static const List<ElementKind> FIELD_KINDS = const <ElementKind>[
+    ElementKind.FIELD,
+    ElementKind.GETTER,
+    ElementKind.SETTER
+  ];
+
+  static const List<ElementKind> GETTER_KINDS = const <ElementKind>[
+    ElementKind.FIELD,
+    ElementKind.GETTER
+  ];
+
+  static const List<ElementKind> METHOD_KINDS = const <ElementKind>[
+    ElementKind.METHOD
+  ];
+
+  static const List<ElementKind> SETTER_KINDS = const <ElementKind>[
+    ElementKind.FIELD,
+    ElementKind.SETTER
+  ];
+
   final CompilationUnit _unit;
 
   final List<Override> _overrides = <Override>[];
@@ -33,7 +54,16 @@
               continue;
             }
             SimpleIdentifier nameNode = classMember.name;
-            _addOverride(nameNode.offset, nameNode.length, nameNode.name);
+            List<ElementKind> kinds;
+            if (classMember.isGetter) {
+              kinds = GETTER_KINDS;
+            } else if (classMember.isSetter) {
+              kinds = SETTER_KINDS;
+            } else {
+              kinds = METHOD_KINDS;
+            }
+            _addOverride(
+                nameNode.offset, nameNode.length, nameNode.name, kinds);
           }
           if (classMember is FieldDeclaration) {
             if (classMember.isStatic) {
@@ -42,7 +72,8 @@
             List<VariableDeclaration> fields = classMember.fields.variables;
             for (VariableDeclaration field in fields) {
               SimpleIdentifier nameNode = field.name;
-              _addOverride(nameNode.offset, nameNode.length, nameNode.name);
+              _addOverride(
+                  nameNode.offset, nameNode.length, nameNode.name, FIELD_KINDS);
             }
           }
         }
@@ -54,6 +85,7 @@
   void _addInterfaceOverrides(
       Set<engine.Element> elements,
       String name,
+      List<ElementKind> kinds,
       engine.InterfaceType type,
       bool checkType,
       Set<engine.InterfaceType> visited) {
@@ -65,7 +97,7 @@
     }
     // check type
     if (checkType) {
-      engine.Element element = _lookupMember(type.element, name);
+      engine.Element element = _lookupMember(type.element, name, kinds);
       if (element != null) {
         elements.add(element);
         return;
@@ -73,25 +105,28 @@
     }
     // check interfaces
     for (engine.InterfaceType interfaceType in type.interfaces) {
-      _addInterfaceOverrides(elements, name, interfaceType, true, visited);
+      _addInterfaceOverrides(
+          elements, name, kinds, interfaceType, true, visited);
     }
     // check super
-    _addInterfaceOverrides(elements, name, type.superclass, checkType, visited);
+    _addInterfaceOverrides(
+        elements, name, kinds, type.superclass, checkType, visited);
   }
 
-  void _addOverride(int offset, int length, String name) {
+  void _addOverride(
+      int offset, int length, String name, List<ElementKind> kinds) {
     // super
     engine.Element superEngineElement;
     {
       engine.InterfaceType superType = _currentClass.supertype;
       if (superType != null) {
-        superEngineElement = _lookupMember(superType.element, name);
+        superEngineElement = _lookupMember(superType.element, name, kinds);
       }
     }
     // interfaces
     Set<engine.Element> interfaceEngineElements = new Set<engine.Element>();
-    _addInterfaceOverrides(interfaceEngineElements, name, _currentClass.type,
-        false, new Set<engine.InterfaceType>());
+    _addInterfaceOverrides(interfaceEngineElements, name, kinds,
+        _currentClass.type, false, new Set<engine.InterfaceType>());
     interfaceEngineElements.remove(superEngineElement);
     // is there any override?
     if (superEngineElement != null || interfaceEngineElements.isNotEmpty) {
@@ -108,25 +143,32 @@
   }
 
   static engine.Element _lookupMember(
-      engine.ClassElement classElement, String name) {
+      engine.ClassElement classElement, String name, List<ElementKind> kinds) {
     if (classElement == null) {
       return null;
     }
     engine.LibraryElement library = classElement.library;
+    engine.Element member;
     // method
-    engine.Element member = classElement.lookUpMethod(name, library);
-    if (member != null) {
-      return member;
+    if (kinds.contains(ElementKind.METHOD)) {
+      member = classElement.lookUpMethod(name, library);
+      if (member != null) {
+        return member;
+      }
     }
     // getter
-    member = classElement.lookUpGetter(name, library);
-    if (member != null) {
-      return member;
+    if (kinds.contains(ElementKind.GETTER)) {
+      member = classElement.lookUpGetter(name, library);
+      if (member != null) {
+        return member;
+      }
     }
     // setter
-    member = classElement.lookUpSetter(name + '=', library);
-    if (member != null) {
-      return member;
+    if (kinds.contains(ElementKind.SETTER)) {
+      member = classElement.lookUpSetter(name + '=', library);
+      if (member != null) {
+        return member;
+      }
     }
     // not found
     return null;
diff --git a/pkg/analysis_server/lib/src/constants.dart b/pkg/analysis_server/lib/src/constants.dart
index a32ad98..0d90251 100644
--- a/pkg/analysis_server/lib/src/constants.dart
+++ b/pkg/analysis_server/lib/src/constants.dart
@@ -26,6 +26,7 @@
 const String ANALYSIS_GET_LIBRARY_DEPENDENCIES =
     'analysis.getLibraryDependencies';
 const String ANALYSIS_GET_NAVIGATION = 'analysis.getNavigation';
+const String ANALYSIS_GET_REACHABLE_SOURCES = 'analysis.getReachableSources';
 const String ANALYSIS_REANALYZE = 'analysis.reanalyze';
 const String ANALYSIS_SET_ANALYSIS_ROOTS = 'analysis.setAnalysisRoots';
 const String ANALYSIS_SET_GENERAL_SUBSCRIPTIONS =
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index e232607..d0862f0 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/source/path_filter.dart';
@@ -26,6 +27,9 @@
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
+import 'package:analyzer/src/util/yaml.dart';
 import 'package:package_config/packages.dart';
 import 'package:package_config/packages_file.dart' as pkgfile show parse;
 import 'package:package_config/src/packages_impl.dart' show MapPackages;
@@ -177,6 +181,31 @@
   void setDependencies(Iterable<String> newDependencies) {
     _dependencies = newDependencies.toSet();
   }
+
+  /**
+   * Return `true` if the given [path] is managed by this context or by
+   * any of its children.
+   */
+  bool _managesOrHasChildThatManages(String path) {
+    if (parent == null) {
+      for (ContextInfo child in children) {
+        if (child._managesOrHasChildThatManages(path)) {
+          return true;
+        }
+      }
+      return false;
+    } else {
+      if (!folder.isOrContains(path)) {
+        return false;
+      }
+      for (ContextInfo child in children) {
+        if (child._managesOrHasChildThatManages(path)) {
+          return true;
+        }
+      }
+      return !pathFilter.ignored(path);
+    }
+  }
 }
 
 /**
@@ -226,6 +255,23 @@
   List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot);
 
   /**
+   * Return the [AnalysisContext] for the "innermost" context whose associated
+   * folder is or contains the given path.  ("innermost" refers to the nesting
+   * of contexts, so if there is a context for path /foo and a context for
+   * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is
+   * the context for /foo/bar.)
+   *
+   * If no context contains the given path, `null` is returned.
+   */
+  AnalysisContext getContextFor(String path);
+
+  /**
+   * Return `true` if the given [path] is ignored by a [ContextInfo] whose
+   * folder contains it.
+   */
+  bool isIgnored(String path);
+
+  /**
    * Return `true` if the given absolute [path] is in one of the current
    * root folders and is not excluded.
    */
@@ -341,6 +387,13 @@
   final ResourceProvider resourceProvider;
 
   /**
+   * The context used to work with absolute file system paths.
+   *
+   * TODO(scheglov) remove [pathContext].
+   */
+  AbsolutePathContext absolutePathContext;
+
+  /**
    * The context used to work with file system paths.
    */
   pathos.Context pathContext;
@@ -397,17 +450,18 @@
    * Virtual [ContextInfo] which acts as the ancestor of all other
    * [ContextInfo]s.
    */
-  final ContextInfo _rootInfo = new ContextInfo._root();
+  final ContextInfo rootInfo = new ContextInfo._root();
 
   /**
    * Stream subscription we are using to watch each analysis root directory for
    * changes.
    */
-  final Map<Folder, StreamSubscription<WatchEvent>> _changeSubscriptions =
+  final Map<Folder, StreamSubscription<WatchEvent>> changeSubscriptions =
       <Folder, StreamSubscription<WatchEvent>>{};
 
   ContextManagerImpl(this.resourceProvider, this.packageResolverProvider,
       this._packageMapProvider, this._instrumentationService) {
+    absolutePathContext = resourceProvider.absolutePathContext;
     pathContext = resourceProvider.pathContext;
   }
 
@@ -434,6 +488,11 @@
     return contexts;
   }
 
+  @override
+  AnalysisContext getContextFor(String path) {
+    return _getInnermostContextInfoFor(path)?.context;
+  }
+
   /**
    * For testing: get the [ContextInfo] object for the given [folder], if any.
    */
@@ -446,13 +505,27 @@
   }
 
   @override
+  bool isIgnored(String path) {
+    ContextInfo info = rootInfo;
+    do {
+      info = info.findChildInfoFor(path);
+      if (info == null) {
+        return false;
+      }
+      if (info.ignored(path)) {
+        return true;
+      }
+    } while (true);
+  }
+
+  @override
   bool isInAnalysisRoot(String path) {
     // check if excluded
     if (_isExcluded(path)) {
       return false;
     }
     // check if in one of the roots
-    for (ContextInfo info in _rootInfo.children) {
+    for (ContextInfo info in rootInfo.children) {
       if (info.folder.contains(path)) {
         return true;
       }
@@ -466,25 +539,35 @@
    */
   void processOptionsForContext(ContextInfo info, Folder folder,
       {bool optionsRemoved: false}) {
-    Map<String, YamlNode> options;
+    Map<String, Object> options;
     try {
       options = analysisOptionsProvider.getOptions(folder);
-    } catch (e, stacktrace) {
-      AnalysisEngine.instance.logger.logError(
-          'Error processing .analysis_options',
-          new CaughtException(e, stacktrace));
-      // TODO(pquitslund): contribute plugin that sends error notification on
-      // options file.
-      // Related test:
-      //   context_manager_test.test_analysis_options_parse_failure()
-      // AnalysisEngine.instance.optionsPlugin.optionsProcessors
-      //      .forEach((OptionsProcessor p) => p.onError(e));
+    } catch (_) {
+      // Parse errors are reported by GenerateOptionsErrorsTask.
     }
 
     if (options == null && !optionsRemoved) {
       return;
     }
 
+    // In case options files are removed, revert to defaults.
+    if (optionsRemoved) {
+      // Start with defaults.
+      info.context.analysisOptions = new AnalysisOptionsImpl();
+
+      // Apply inherited options.
+      options = _getEmbeddedOptions(info.context);
+      if (options != null) {
+        configureContextOptions(info.context, options);
+      }
+    } else {
+      // Check for embedded options.
+      YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
+      if (embeddedOptions != null) {
+        options = new Merger().merge(embeddedOptions, options);
+      }
+    }
+
     // Notify options processors.
     AnalysisEngine.instance.optionsPlugin.optionsProcessors
         .forEach((OptionsProcessor p) {
@@ -497,31 +580,21 @@
       }
     });
 
-    // In case options files are removed, revert to default options.
-    if (optionsRemoved) {
-      info.context.analysisOptions = new AnalysisOptionsImpl();
+    configureContextOptions(info.context, options);
+
+    // Nothing more to do.
+    if (options == null) {
       return;
     }
 
-    // Analysis options are processed 'in-line'.
-    YamlMap analyzer = options['analyzer'];
-    if (analyzer == null) {
-      // No options for analyzer.
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! Map) {
+      // Done.
       return;
     }
 
-    // Set strong mode (default is false).
-    bool strongMode = analyzer['strong-mode'] ?? false;
-    AnalysisContext context = info.context;
-    if (context.analysisOptions.strongMode != strongMode) {
-      AnalysisOptionsImpl options =
-          new AnalysisOptionsImpl.from(context.analysisOptions);
-      options.strongMode = strongMode;
-      context.analysisOptions = options;
-    }
-
     // Set ignore patterns.
-    YamlList exclude = analyzer['exclude'];
+    YamlList exclude = analyzer[AnalyzerOptions.exclude];
     if (exclude != null) {
       setIgnorePatternsForContext(info, exclude);
     }
@@ -530,7 +603,7 @@
   @override
   void refresh(List<Resource> roots) {
     // Destroy old contexts
-    List<ContextInfo> contextInfos = _rootInfo.descendants.toList();
+    List<ContextInfo> contextInfos = rootInfo.descendants.toList();
     if (roots == null) {
       contextInfos.forEach(_destroyContext);
     } else {
@@ -571,22 +644,31 @@
       }
     });
 
-    List<ContextInfo> contextInfos = _rootInfo.descendants.toList();
+    List<ContextInfo> contextInfos = rootInfo.descendants.toList();
     // included
-    Set<Folder> includedFolders = new HashSet<Folder>();
-    for (int i = 0; i < includedPaths.length; i++) {
-      String path = includedPaths[i];
-      Resource resource = resourceProvider.getResource(path);
-      if (resource is Folder) {
-        includedFolders.add(resource);
-      } else if (!resource.exists) {
-        // Non-existent resources are ignored.  TODO(paulberry): we should set
-        // up a watcher to ensure that if the resource appears later, we will
-        // begin analyzing it.
-      } else {
-        // TODO(scheglov) implemented separate files analysis
-        throw new UnimplementedError('$path is not a folder. '
-            'Only support for folder analysis is implemented currently.');
+    List<Folder> includedFolders = <Folder>[];
+    {
+      // Sort paths to ensure that outer roots are handled before inner roots,
+      // so we can correctly ignore inner roots, which are already managed
+      // by outer roots.
+      LinkedHashSet<String> uniqueIncludedPaths =
+          new LinkedHashSet<String>.from(includedPaths);
+      List<String> sortedIncludedPaths = uniqueIncludedPaths.toList();
+      sortedIncludedPaths.sort((a, b) => a.length - b.length);
+      // Convert paths to folders.
+      for (String path in sortedIncludedPaths) {
+        Resource resource = resourceProvider.getResource(path);
+        if (resource is Folder) {
+          includedFolders.add(resource);
+        } else if (!resource.exists) {
+          // Non-existent resources are ignored.  TODO(paulberry): we should set
+          // up a watcher to ensure that if the resource appears later, we will
+          // begin analyzing it.
+        } else {
+          // TODO(scheglov) implemented separate files analysis
+          throw new UnimplementedError('$path is not a folder. '
+              'Only support for folder analysis is implemented currently.');
+        }
       }
     }
     this.includedPaths = includedPaths;
@@ -603,7 +685,7 @@
       }
     }
     // Update package roots for existing contexts
-    for (ContextInfo info in _rootInfo.descendants) {
+    for (ContextInfo info in rootInfo.descendants) {
       String newPackageRoot = normalizedPackageRoots[info.folder.path];
       if (info.packageRoot != newPackageRoot) {
         info.packageRoot = newPackageRoot;
@@ -612,17 +694,17 @@
     }
     // create new contexts
     for (Folder includedFolder in includedFolders) {
-      bool wasIncluded = contextInfos.any((info) {
-        return info.folder.isOrContains(includedFolder.path);
-      });
-      if (!wasIncluded) {
-        _changeSubscriptions[includedFolder] =
+      String includedPath = includedFolder.path;
+      bool isManaged = rootInfo._managesOrHasChildThatManages(includedPath);
+      if (!isManaged) {
+        ContextInfo parent = _getParentForNewContext(includedPath);
+        changeSubscriptions[includedFolder] =
             includedFolder.changes.listen(_handleWatchEvent);
-        _createContexts(_rootInfo, includedFolder, false);
+        _createContexts(parent, includedFolder, false);
       }
     }
     // remove newly excluded sources
-    for (ContextInfo info in _rootInfo.descendants) {
+    for (ContextInfo info in rootInfo.descendants) {
       // prepare excluded sources
       Map<String, Source> excludedSources = new HashMap<String, Source>();
       info.sources.forEach((String path, Source source) {
@@ -640,7 +722,7 @@
       callbacks.applyChangesToContext(info.folder, changeSet);
     }
     // add previously excluded sources
-    for (ContextInfo info in _rootInfo.descendants) {
+    for (ContextInfo info in rootInfo.descendants) {
       ChangeSet changeSet = new ChangeSet();
       _addPreviouslyExcludedSources(
           info, changeSet, info.folder, oldExcludedPaths);
@@ -752,7 +834,7 @@
       String path, ContextInfo info, Folder folder) {
     // Check to see if this is the .packages file for this context and if so,
     // update the context's source factory.
-    if (pathContext.basename(path) == PACKAGE_SPEC_NAME &&
+    if (absolutePathContext.basename(path) == PACKAGE_SPEC_NAME &&
         info.isPathToPackageDescription(path)) {
       File packagespec = resourceProvider.getFile(path);
       if (packagespec.exists) {
@@ -777,7 +859,7 @@
     for (Source source in context.sources) {
       flushedFiles.add(source.fullName);
     }
-    for (ContextInfo contextInfo in _rootInfo.descendants) {
+    for (ContextInfo contextInfo in rootInfo.descendants) {
       AnalysisContext contextN = contextInfo.context;
       if (context != contextN) {
         for (Source source in contextN.sources) {
@@ -835,7 +917,8 @@
       callbacks.beginComputePackageMap();
       try {
         // Try .packages first.
-        if (pathContext.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
+        if (absolutePathContext.basename(packagespecFile.path) ==
+            PACKAGE_SPEC_NAME) {
           Packages packages = _readPackagespec(packagespecFile);
           return new PackagesFileDisposition(packages);
         }
@@ -845,6 +928,7 @@
             return new CustomPackageResolverDisposition(resolver);
           }
         }
+
         ServerPerformanceStatistics.pub.makeCurrentWhile(() {
           packageMapInfo = _packageMapProvider.computePackageMap(folder);
         });
@@ -949,9 +1033,7 @@
    * Clean up and destroy the context associated with the given folder.
    */
   void _destroyContext(ContextInfo info) {
-    if (_changeSubscriptions.containsKey(info.folder)) {
-      _changeSubscriptions[info.folder].cancel();
-    }
+    changeSubscriptions.remove(info.folder)?.cancel();
     callbacks.removeContext(info.folder, _computeFlushedFiles(info));
     bool wasRemoved = info.parent.children.remove(info);
     assert(wasRemoved);
@@ -1013,6 +1095,20 @@
     return packageSpec;
   }
 
+  /// Get analysis options associated with an `_embedder.yaml`. If there is
+  /// more than one `_embedder.yaml` associated with the given context, `null`
+  /// is returned.
+  YamlMap _getEmbeddedOptions(AnalysisContext context) {
+    if (context is InternalAnalysisContext) {
+      EmbedderYamlLocator locator = context.embedderYamlLocator;
+      Iterable<YamlMap> maps = locator.embedderYamls.values;
+      if (maps.length == 1) {
+        return maps.first;
+      }
+    }
+    return null;
+  }
+
   /**
    * Return the [ContextInfo] for the "innermost" context whose associated
    * folder is or contains the given path.  ("innermost" refers to the nesting
@@ -1023,7 +1119,7 @@
    * If no context contains the given path, `null` is returned.
    */
   ContextInfo _getInnermostContextInfoFor(String path) {
-    ContextInfo info = _rootInfo.findChildInfoFor(path);
+    ContextInfo info = rootInfo.findChildInfoFor(path);
     if (info == null) {
       return null;
     }
@@ -1036,6 +1132,17 @@
     }
   }
 
+  /**
+   * Return the parent for a new [ContextInfo] with the given [path] folder.
+   */
+  ContextInfo _getParentForNewContext(String path) {
+    ContextInfo parent = _getInnermostContextInfoFor(path);
+    if (parent != null) {
+      return parent;
+    }
+    return rootInfo;
+  }
+
   void _handleWatchEvent(WatchEvent event) {
     // Figure out which context this event applies to.
     // TODO(brianwilkerson) If a file is explicitly included in one context
@@ -1077,7 +1184,7 @@
       case ChangeType.ADD:
         Resource resource = resourceProvider.getResource(path);
 
-        String directoryPath = pathContext.dirname(path);
+        String directoryPath = absolutePathContext.dirname(path);
 
         // Check to see if we need to create a new context.
         if (info.isTopLevel) {
@@ -1087,7 +1194,8 @@
             if (_isPubspec(path)) {
               // Check for a sibling .packages file.
               if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PACKAGE_SPEC_NAME))
+                  .getFile(absolutePathContext.append(
+                      directoryPath, PACKAGE_SPEC_NAME))
                   .exists) {
                 _extractContext(info, resource);
                 return;
@@ -1096,7 +1204,8 @@
             if (_isPackagespec(path)) {
               // Check for a sibling pubspec.yaml file.
               if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
+                  .getFile(
+                      absolutePathContext.append(directoryPath, PUBSPEC_NAME))
                   .exists) {
                 _extractContext(info, resource);
                 return;
@@ -1125,14 +1234,15 @@
         // Note that it's important to verify that there is NEITHER a .packages nor a
         // lingering pubspec.yaml before merging.
         if (!info.isTopLevel) {
-          String directoryPath = pathContext.dirname(path);
+          String directoryPath = absolutePathContext.dirname(path);
 
           // Only merge if this is the same directory described by our info object.
           if (info.folder.path == directoryPath) {
             if (_isPubspec(path)) {
               // Check for a sibling .packages file.
               if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PACKAGE_SPEC_NAME))
+                  .getFile(absolutePathContext.append(
+                      directoryPath, PACKAGE_SPEC_NAME))
                   .exists) {
                 _mergeContext(info);
                 return;
@@ -1141,7 +1251,8 @@
             if (_isPackagespec(path)) {
               // Check for a sibling pubspec.yaml file.
               if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
+                  .getFile(
+                      absolutePathContext.append(directoryPath, PUBSPEC_NAME))
                   .exists) {
                 _mergeContext(info);
                 return;
@@ -1180,9 +1291,12 @@
    * context root [root], contains a folder whose name starts with '.'.
    */
   bool _isContainedInDotFolder(String root, String path) {
-    String relativePath =
-        pathContext.relative(pathContext.dirname(path), from: root);
-    for (String pathComponent in pathContext.split(relativePath)) {
+    String pathDir = absolutePathContext.dirname(path);
+    String suffixPath = absolutePathContext.suffix(root, pathDir);
+    if (suffixPath == null) {
+      return false;
+    }
+    for (String pathComponent in absolutePathContext.split(suffixPath)) {
       if (pathComponent.startsWith('.') &&
           pathComponent != '.' &&
           pathComponent != '..') {
@@ -1202,7 +1316,7 @@
    */
   bool _isExcludedBy(List<String> excludedPaths, String path) {
     return excludedPaths.any((excludedPath) {
-      if (pathContext.isWithin(excludedPath, path)) {
+      if (absolutePathContext.isWithin(excludedPath, path)) {
         return true;
       }
       return path == excludedPath;
@@ -1214,8 +1328,11 @@
    * context root [root], contains a 'packages' folder.
    */
   bool _isInPackagesDir(String root, String path) {
-    String relativePath = pathContext.relative(path, from: root);
-    List<String> pathParts = pathContext.split(relativePath);
+    String suffixPath = absolutePathContext.suffix(root, path);
+    if (suffixPath == null) {
+      return false;
+    }
+    List<String> pathParts = absolutePathContext.split(suffixPath);
     return pathParts.contains(PACKAGES_NAME);
   }
 
@@ -1224,15 +1341,19 @@
    * context root [root].
    */
   bool _isInTopLevelDocDir(String root, String path) {
-    String relativePath = pathContext.relative(path, from: root);
-    return relativePath == DOC_DIR_NAME ||
-        relativePath.startsWith(DOC_DIR_NAME + pathContext.separator);
+    String suffixPath = absolutePathContext.suffix(root, path);
+    if (suffixPath == null) {
+      return false;
+    }
+    return suffixPath == DOC_DIR_NAME ||
+        suffixPath.startsWith(DOC_DIR_NAME + absolutePathContext.separator);
   }
 
   bool _isPackagespec(String path) =>
-      pathContext.basename(path) == PACKAGE_SPEC_NAME;
+      absolutePathContext.basename(path) == PACKAGE_SPEC_NAME;
 
-  bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME;
+  bool _isPubspec(String path) =>
+      absolutePathContext.basename(path) == PUBSPEC_NAME;
 
   /**
    * Merges [info] context into its parent.
@@ -1445,23 +1566,31 @@
   @override
   final Packages packages;
 
-  PackagesFileDisposition(this.packages) {}
+  PackagesFileDisposition(this.packages);
 
   @override
   String get packageRoot => null;
 
+  Map<String, List<Folder>> buildPackageMap(ResourceProvider resourceProvider) {
+    Map<String, List<Folder>> packageMap = <String, List<Folder>>{};
+    if (packages == null) {
+      return packageMap;
+    }
+    packages.asMap().forEach((String name, Uri uri) {
+      if (uri.scheme == 'file' || uri.scheme == '' /* unspecified */) {
+        var path = resourceProvider.pathContext.fromUri(uri);
+        packageMap[name] = <Folder>[resourceProvider.getFolder(path)];
+      }
+    });
+    return packageMap;
+  }
+
   @override
   Iterable<UriResolver> createPackageUriResolvers(
       ResourceProvider resourceProvider) {
     if (packages != null) {
       // Construct package map for the SdkExtUriResolver.
-      Map<String, List<Folder>> packageMap = <String, List<Folder>>{};
-      packages.asMap().forEach((String name, Uri uri) {
-        if (uri.scheme == 'file' || uri.scheme == '' /* unspecified */) {
-          var path = resourceProvider.pathContext.fromUri(uri);
-          packageMap[name] = <Folder>[resourceProvider.getFolder(path)];
-        }
-      });
+      Map<String, List<Folder>> packageMap = buildPackageMap(resourceProvider);
       return <UriResolver>[new SdkExtUriResolver(packageMap)];
     } else {
       return const <UriResolver>[];
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 494d37c..0c8d28b 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -21,9 +21,10 @@
 import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/dependencies/library_dependencies.dart';
+import 'package:analysis_server/src/services/dependencies/reachable_source_collector.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
 import 'package:analyzer/src/generated/source.dart';
@@ -64,8 +65,9 @@
           if (errorInfo == null) {
             server.sendResponse(new Response.getErrorsInvalidFile(request));
           } else {
+            engine.AnalysisContext context = server.getAnalysisContext(file);
             errors = doAnalysisError_listFromEngine(
-                errorInfo.lineInfo, errorInfo.errors);
+                context, errorInfo.lineInfo, errorInfo.errors);
             server.sendResponse(
                 new AnalysisGetErrorsResult(errors).toResponse(request.id));
           }
@@ -164,6 +166,23 @@
     return Response.DELAYED_RESPONSE;
   }
 
+  /**
+   * Implement the `analysis.getReachableSources` request.
+   */
+  Response getReachableSources(Request request) {
+    AnalysisGetReachableSourcesParams params =
+        new AnalysisGetReachableSourcesParams.fromRequest(request);
+    ContextSourcePair pair = server.getContextSourcePair(params.file);
+    if (pair.context == null || pair.source == null) {
+      return new Response.getReachableSourcesInvalidFile(request);
+    }
+    Map<String, List<String>> sources =
+        new ReachableSourceCollector(pair.source, pair.context)
+            .collectSources();
+    return new AnalysisGetReachableSourcesResult(sources)
+        .toResponse(request.id);
+  }
+
   @override
   Response handleRequest(Request request) {
     try {
@@ -176,6 +195,8 @@
         return getLibraryDependencies(request);
       } else if (requestName == ANALYSIS_GET_NAVIGATION) {
         return getNavigation(request);
+      } else if (requestName == ANALYSIS_GET_REACHABLE_SOURCES) {
+        return getReachableSources(request);
       } else if (requestName == ANALYSIS_REANALYZE) {
         return reanalyze(request);
       } else if (requestName == ANALYSIS_SET_ANALYSIS_ROOTS) {
@@ -226,9 +247,22 @@
    */
   Response setAnalysisRoots(Request request) {
     var params = new AnalysisSetAnalysisRootsParams.fromRequest(request);
+    List<String> includedPathList = params.included;
+    List<String> excludedPathList = params.excluded;
+    // validate
+    for (String path in includedPathList) {
+      if (!server.isValidFilePath(path)) {
+        return new Response.invalidFilePathFormat(request, path);
+      }
+    }
+    for (String path in excludedPathList) {
+      if (!server.isValidFilePath(path)) {
+        return new Response.invalidFilePathFormat(request, path);
+      }
+    }
     // continue in server
-    server.setAnalysisRoots(request.id, params.included, params.excluded,
-        params.packageRoots == null ? {} : params.packageRoots);
+    server.setAnalysisRoots(request.id, includedPathList, excludedPathList,
+        params.packageRoots ?? <String, String>{});
     return new AnalysisSetAnalysisRootsResult().toResponse(request.id);
   }
 
@@ -328,8 +362,8 @@
 class AnalysisDomainImpl implements AnalysisDomain {
   final AnalysisServer server;
 
-  final Map<ResultDescriptor,
-          StreamController<engine.ComputedResult>> controllers =
+  final Map<ResultDescriptor, StreamController<engine.ComputedResult>>
+      controllers =
       <ResultDescriptor, StreamController<engine.ComputedResult>>{};
 
   AnalysisDomainImpl(this.server) {
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 6d43e53..8810ff6 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -9,17 +9,12 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/constants.dart';
-import 'package:analysis_server/src/context_manager.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart'
-    show CompletionRequest, CompletionResult;
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
-export 'package:analysis_server/src/services/completion/completion_manager.dart'
-    show CompletionPerformance, CompletionRequest, OperationPerformance;
-
 /**
  * Instances of the class [CompletionDomainHandler] implement a [RequestHandler]
  * that handles requests in the search domain.
@@ -36,27 +31,11 @@
   final AnalysisServer server;
 
   /**
-   * The [SearchEngine] for this server.
-   */
-  SearchEngine searchEngine;
-
-  /**
    * The next completion response id.
    */
   int _nextCompletionId = 0;
 
   /**
-   * The completion manager for most recent [Source] and [AnalysisContext],
-   * or `null` if none.
-   */
-  CompletionManager _manager;
-
-  /**
-   * The subscription for the cached context's source change stream.
-   */
-  StreamSubscription<SourcesChangedEvent> _sourcesChangedSubscription;
-
-  /**
    * Code completion performance for the last completion operation.
    */
   CompletionPerformance performance;
@@ -76,59 +55,44 @@
   /**
    * Initialize a new request handler for the given [server].
    */
-  CompletionDomainHandler(this.server) {
-    server.onContextsChanged.listen(contextsChanged);
-    server.onPriorityChange.listen(priorityChanged);
-    searchEngine = server.searchEngine;
-  }
+  CompletionDomainHandler(this.server);
 
   /**
-   * Return the completion manager for most recent [Source] and [AnalysisContext],
-   * or `null` if none.
+   * Compute completion results for the given reqeust and append them to the stream.
+   * Clients should not call this method directly as it is automatically called
+   * when a client listens to the stream returned by [results].
+   * Subclasses should override this method, append at least one result
+   * to the [controller], and close the controller stream once complete.
    */
-  CompletionManager get manager => _manager;
+  Future<CompletionResult> computeSuggestions(
+      CompletionRequestImpl request) async {
+    Iterable<CompletionContributor> newContributors =
+        server.serverPlugin.completionContributors;
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
 
-  /**
-   * Return the [CompletionManager] for the given [context] and [source],
-   * creating a new manager or returning an existing manager as necessary.
-   */
-  CompletionManager completionManagerFor(
-      AnalysisContext context, Source source) {
-    if (_manager != null) {
-      if (_manager.context == context && _manager.source == source) {
-        return _manager;
-      }
-      _discardManager();
-    }
-    _manager = createCompletionManager(context, source, searchEngine);
-    if (context != null) {
-      _sourcesChangedSubscription =
-          context.onSourcesChanged.listen(sourcesChanged);
-    }
-    return _manager;
-  }
+    const COMPUTE_SUGGESTIONS_TAG = 'computeSuggestions';
+    performance.logStartTime(COMPUTE_SUGGESTIONS_TAG);
 
-  /**
-   * If the context associated with the cache has changed or been removed
-   * then discard the cache.
-   */
-  void contextsChanged(ContextsChangedEvent event) {
-    if (_manager != null) {
-      AnalysisContext context = _manager.context;
-      if (event.changed.contains(context) || event.removed.contains(context)) {
-        _discardManager();
-      }
+    for (CompletionContributor contributor in newContributors) {
+      String contributorTag = 'computeSuggestions - ${contributor.runtimeType}';
+      performance.logStartTime(contributorTag);
+      suggestions.addAll(await contributor.computeSuggestions(request));
+      performance.logElapseTime(contributorTag);
     }
-  }
 
-  CompletionManager createCompletionManager(
-      AnalysisContext context, Source source, SearchEngine searchEngine) {
-    return new CompletionManager.create(context, source, searchEngine);
+    performance.logElapseTime(COMPUTE_SUGGESTIONS_TAG);
+
+    // TODO (danrubel) if request is obsolete
+    // (processAnalysisRequest returns false)
+    // then send empty results
+
+    return new CompletionResult(
+        request.replacementOffset, request.replacementLength, suggestions);
   }
 
   @override
   Response handleRequest(Request request) {
-    if (searchEngine == null) {
+    if (server.searchEngine == null) {
       return new Response.noIndexGenerated(request);
     }
     return runZoned(() {
@@ -150,70 +114,55 @@
   }
 
   /**
-   * If the set the priority files has changed, then pre-cache completion
-   * information related to the first priority file.
-   */
-  void priorityChanged(PriorityChangeEvent event) {
-    Source source = event.firstSource;
-    CompletionPerformance performance = new CompletionPerformance();
-    computeCachePerformance = performance;
-    if (source == null) {
-      performance.complete('priorityChanged caching: no source');
-      return;
-    }
-    performance.source = source;
-    AnalysisContext context = server.getAnalysisContextForSource(source);
-    if (context != null) {
-      String computeTag = 'computeCache';
-      performance.logStartTime(computeTag);
-      CompletionManager manager = completionManagerFor(context, source);
-      manager.computeCache().catchError((_) => false).then((bool success) {
-        performance.logElapseTime(computeTag);
-        performance.complete('priorityChanged caching: $success');
-      });
-    }
-  }
-
-  /**
    * Process a `completion.getSuggestions` request.
    */
-  Response processRequest(Request request, [CompletionManager manager]) {
+  Response processRequest(Request request) {
     performance = new CompletionPerformance();
-    // extract params
+
+    // extract and validate params
     CompletionGetSuggestionsParams params =
         new CompletionGetSuggestionsParams.fromRequest(request);
-    // schedule completion analysis
-    String completionId = (_nextCompletionId++).toString();
     ContextSourcePair contextSource = server.getContextSourcePair(params.file);
     AnalysisContext context = contextSource.context;
     Source source = contextSource.source;
     if (context == null || !context.exists(source)) {
       return new Response.unknownSource(request);
     }
-    recordRequest(performance, context, source, params.offset);
-    if (manager == null) {
-      manager = completionManagerFor(context, source);
+    TimestampedData<String> contents = context.getContents(source);
+    if (params.offset < 0 || params.offset > contents.data.length) {
+      return new Response.invalidParameter(
+          request,
+          'params.offset',
+          'Expected offset between 0 and source length inclusive,'
+          ' but found ${params.offset}');
     }
-    CompletionRequest completionRequest =
-        new CompletionRequestImpl(server, context, source, params.offset);
-    int notificationCount = 0;
-    manager.results(completionRequest).listen((CompletionResult result) {
-      ++notificationCount;
-      bool isLast = result is CompletionResultImpl ? result.isLast : true;
-      performance.logElapseTime("notification $notificationCount send", () {
-        sendCompletionNotification(completionId, result.replacementOffset,
-            result.replacementLength, result.suggestions, isLast);
-      });
-      if (notificationCount == 1) {
-        performance.logFirstNotificationComplete('notification 1 complete');
-        performance.suggestionCountFirst = result.suggestions.length;
-      }
-      if (isLast) {
-        performance.notificationCount = notificationCount;
-        performance.suggestionCountLast = result.suggestions.length;
-        performance.complete();
-      }
+
+    recordRequest(performance, context, source, params.offset);
+
+    CompletionRequest completionRequest = new CompletionRequestImpl(
+        context,
+        server.resourceProvider,
+        server.searchEngine,
+        source,
+        params.offset,
+        performance);
+    String completionId = (_nextCompletionId++).toString();
+
+    // Compute suggestions in the background
+    computeSuggestions(completionRequest).then((CompletionResult result) {
+      const SEND_NOTIFICATION_TAG = 'send notification';
+      performance.logStartTime(SEND_NOTIFICATION_TAG);
+      sendCompletionNotification(completionId, result.replacementOffset,
+          result.replacementLength, result.suggestions);
+      performance.logElapseTime(SEND_NOTIFICATION_TAG);
+
+      performance.notificationCount = 1;
+      performance.logFirstNotificationComplete('notification 1 complete');
+      performance.suggestionCountFirst = result.suggestions.length;
+      performance.suggestionCountLast = result.suggestions.length;
+      performance.complete();
     });
+
     // initial response without results
     return new CompletionGetSuggestionsResult(completionId)
         .toResponse(request.id);
@@ -243,51 +192,38 @@
   /**
    * Send completion notification results.
    */
-  void sendCompletionNotification(
-      String completionId,
-      int replacementOffset,
-      int replacementLength,
-      Iterable<CompletionSuggestion> results,
-      bool isLast) {
+  void sendCompletionNotification(String completionId, int replacementOffset,
+      int replacementLength, Iterable<CompletionSuggestion> results) {
     server.sendNotification(new CompletionResultsParams(
-            completionId, replacementOffset, replacementLength, results, isLast)
+            completionId, replacementOffset, replacementLength, results, true)
         .toNotification());
   }
+}
+
+/**
+ * The result of computing suggestions for code completion.
+ */
+class CompletionResult {
+  /**
+   * The length of the text to be replaced if the remainder of the identifier
+   * containing the cursor is to be replaced when the suggestion is applied
+   * (that is, the number of characters in the existing identifier).
+   */
+  final int replacementLength;
 
   /**
-   * Discard the cache if a source other than the source referenced by
-   * the cache changes or if any source is added, removed, or deleted.
+   * The offset of the start of the text to be replaced. This will be different
+   * than the offset used to request the completion suggestions if there was a
+   * portion of an identifier before the original offset. In particular, the
+   * replacementOffset will be the offset of the beginning of said identifier.
    */
-  void sourcesChanged(SourcesChangedEvent event) {
-    bool shouldDiscardManager(SourcesChangedEvent event) {
-      if (_manager == null) {
-        return false;
-      }
-      if (event.wereSourcesAdded || event.wereSourcesRemovedOrDeleted) {
-        return true;
-      }
-      var changedSources = event.changedSources;
-      return changedSources.length > 2 ||
-          (changedSources.length == 1 &&
-              !changedSources.contains(_manager.source));
-    }
-
-    if (shouldDiscardManager(event)) {
-      _discardManager();
-    }
-  }
+  final int replacementOffset;
 
   /**
-   * Discard the sourcesChanged subscription if any
+   * The suggested completions.
    */
-  void _discardManager() {
-    if (_sourcesChangedSubscription != null) {
-      _sourcesChangedSubscription.cancel();
-      _sourcesChangedSubscription = null;
-    }
-    if (_manager != null) {
-      _manager.dispose();
-      _manager = null;
-    }
-  }
+  final List<CompletionSuggestion> suggestions;
+
+  CompletionResult(
+      this.replacementOffset, this.replacementLength, this.suggestions);
 }
diff --git a/pkg/analysis_server/lib/src/domain_diagnostic.dart b/pkg/analysis_server/lib/src/domain_diagnostic.dart
new file mode 100644
index 0000000..e9bd0c3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/domain_diagnostic.dart
@@ -0,0 +1,97 @@
+// 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 analysis_server.src.domain_diagnostic;
+
+import 'dart:collection';
+import 'dart:core' hide Resource;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/driver.dart';
+import 'package:analyzer/task/model.dart';
+
+int _workItemCount(AnalysisContextImpl context) {
+  AnalysisDriver driver = context.driver;
+  List<WorkItem> items = driver.currentWorkOrder?.workItems;
+  return items?.length ?? 0;
+}
+
+/// Instances of the class [DiagnosticDomainHandler] implement a
+/// [RequestHandler] that handles requests in the `diagnostic` domain.
+class DiagnosticDomainHandler implements RequestHandler {
+  /// The name of the request used to get diagnostic information.
+  static const String DIAGNOSTICS = 'diagnostic.getDiagnostics';
+
+  /// The analysis server that is using this handler to process requests.
+  final AnalysisServer server;
+
+  /// Initialize a newly created handler to handle requests for the given
+  /// [server].
+  DiagnosticDomainHandler(this.server);
+
+  /// Answer the `diagnostic.diagnostics` request.
+  Response computeDiagnostics(Request request) {
+    List<ContextData> infos = <ContextData>[];
+    server.folderMap.forEach((Folder folder, AnalysisContext context) {
+      infos.add(extractData(folder, context));
+    });
+
+    return new DiagnosticGetDiagnosticsResult(infos).toResponse(request.id);
+  }
+
+  /// Extract context data from the given [context].
+  ContextData extractData(Folder folder, AnalysisContext context) {
+    int explicitFiles = 0;
+    int implicitFiles = 0;
+    int workItems = 0;
+    Set<String> exceptions = new HashSet<String>();
+    if (context is AnalysisContextImpl) {
+      workItems = _workItemCount(context);
+      var cache = context.analysisCache;
+      if (cache is AnalysisCache) {
+        Set<AnalysisTarget> countedTargets = new HashSet<AnalysisTarget>();
+        MapIterator<AnalysisTarget, CacheEntry> iterator = cache.iterator();
+        while (iterator.moveNext()) {
+          AnalysisTarget target = iterator.key;
+          if (countedTargets.add(target)) {
+            CacheEntry cacheEntry = iterator.value;
+            if (target is Source) {
+              if (cacheEntry.explicitlyAdded) {
+                explicitFiles++;
+              } else {
+                implicitFiles++;
+              }
+            }
+            // Caught exceptions.
+            if (cacheEntry.exception != null) {
+              exceptions.add(cacheEntry.exception.toString());
+            }
+          }
+        }
+      }
+    }
+    return new ContextData(context.name, explicitFiles, implicitFiles,
+        workItems, exceptions.toList());
+  }
+
+  @override
+  Response handleRequest(Request request) {
+    try {
+      String requestName = request.method;
+      if (requestName == DIAGNOSTICS) {
+        return computeDiagnostics(request);
+      }
+    } on RequestFailure catch (exception) {
+      return exception.response;
+    }
+    return null;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index 470d3c3..3988de2 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -117,7 +117,11 @@
       }
       ContextSourcePair contextSource = server.getContextSourcePair(file);
       Source source = contextSource.source;
-      uri = context.sourceFactory.restoreUri(source).toString();
+      if (source.uriKind != UriKind.FILE_URI) {
+        uri = source.uri.toString();
+      } else {
+        uri = context.sourceFactory.restoreUri(source).toString();
+      }
       return new ExecutionMapUriResult(uri: uri).toResponse(request.id);
     } else if (uri != null) {
       Source source = context.sourceFactory.forUri(uri);
@@ -157,8 +161,7 @@
       String filePath = source.fullName;
       // check files
       bool isDartFile = notice.resolvedDartUnit != null;
-      bool isHtmlFile = notice.resolvedHtmlUnit != null;
-      if (!isDartFile && !isHtmlFile) {
+      if (!isDartFile) {
         return;
       }
       // prepare context
@@ -180,10 +183,6 @@
         server.sendNotification(
             new ExecutionLaunchDataParams(filePath, kind: kind)
                 .toNotification());
-      } 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/domain_experimental.dart b/pkg/analysis_server/lib/src/domain_experimental.dart
deleted file mode 100644
index 43631f2..0000000
--- a/pkg/analysis_server/lib/src/domain_experimental.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library src.domain_experimental;
-
-import 'dart:core' hide Resource;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/analysis_server.dart';
-
-/**
- * Instances of the class [ExperimentalDomainHandler] implement a
- * [RequestHandler] that handles requests in the `experimental` domain.
- */
-class ExperimentalDomainHandler implements RequestHandler {
-  /**
-   * The analysis server that is using this handler to process requests.
-   */
-  final AnalysisServer server;
-
-  /**
-   * The name of the request used to get diagnostic information.
-   */
-  static const String EXPERIMENTAL_DIAGNOSTICS = 'experimental.diagnostics';
-
-  /**
-   * Initialize a newly created handler to handle requests for the given [server].
-   */
-  ExperimentalDomainHandler(this.server);
-
-  @override
-  Response handleRequest(Request request) {
-    try {
-      String requestName = request.method;
-      if (requestName == EXPERIMENTAL_DIAGNOSTICS) {
-        return computeDiagnostics(request);
-      }
-    } on RequestFailure catch (exception) {
-      return exception.response;
-    }
-    return null;
-  }
-
-  /**
-   * Implement the `experimental.diagnostics` request.
-   */
-  Response computeDiagnostics(Request request) {
-    return new Response.unknownRequest(request);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
index f96f42f..5391d5e 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
@@ -7,7 +7,7 @@
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 
 class ImplementedComputer {
   final SearchEngine searchEngine;
@@ -54,23 +54,38 @@
   }
 
   void _addMemberIfImplemented(Element element) {
-    if (!element.isSynthetic) {
-      String name = element.displayName;
-      if (name != null && _hasOverride(name)) {
-        _addImplementedMember(element);
-      }
+    if (element.isSynthetic || _isStatic(element)) {
+      return;
+    }
+    String name = element.displayName;
+    if (name != null && _hasOverride(name)) {
+      _addImplementedMember(element);
     }
   }
 
   bool _hasOverride(String name) {
     for (ClassElement subtype in subtypes) {
-      if (subtype.getMethod(name) != null) {
-        return true;
+      MethodElement method = subtype.getMethod(name);
+      if (method != null) {
+        return !method.isStatic;
       }
-      if (subtype.getField(name) != null) {
-        return true;
+      FieldElement field = subtype.getField(name);
+      if (field != null) {
+        return !field.isStatic;
       }
     }
     return false;
   }
+
+  /**
+   * Return `true` if the given [element] is a static element.
+   */
+  static bool _isStatic(Element element) {
+    if (element is ExecutableElement) {
+      return element.isStatic;
+    } else if (element is PropertyInducingElement) {
+      return element.isStatic;
+    }
+    return false;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation.dart b/pkg/analysis_server/lib/src/domains/analysis/navigation.dart
index 9911d92..c991353 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/navigation.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/navigation.dart
@@ -13,7 +13,7 @@
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisEngine;
 import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
-import 'package:analyzer/src/generated/source.dart' show Source;
+import 'package:analyzer/src/generated/source.dart' show Source, SourceRange;
 
 /**
  * Compute all known navigation information for the given part of [source].
@@ -32,7 +32,7 @@
           new CaughtException(exception, stackTrace));
     }
   }
-  collector.sortRegions();
+  collector.createRegions();
   return collector;
 }
 
@@ -44,6 +44,8 @@
    * A list of navigation regions.
    */
   final List<protocol.NavigationRegion> regions = <protocol.NavigationRegion>[];
+  final Map<SourceRange, List<int>> regionMap =
+      new HashMap<SourceRange, List<int>>();
 
   /**
    * All the unique targets referenced by [regions].
@@ -61,13 +63,24 @@
   @override
   void addRegion(int offset, int length, protocol.ElementKind targetKind,
       protocol.Location targetLocation) {
+    SourceRange range = new SourceRange(offset, length);
+    // prepare targets
+    List<int> targets = regionMap[range];
+    if (targets == null) {
+      targets = <int>[];
+      regionMap[range] = targets;
+    }
+    // add new target
     int targetIndex = _addTarget(targetKind, targetLocation);
-    protocol.NavigationRegion region =
-        new protocol.NavigationRegion(offset, length, <int>[targetIndex]);
-    regions.add(region);
+    targets.add(targetIndex);
   }
 
-  void sortRegions() {
+  void createRegions() {
+    regionMap.forEach((range, targets) {
+      protocol.NavigationRegion region =
+          new protocol.NavigationRegion(range.offset, range.length, targets);
+      regions.add(region);
+    });
     regions.sort((a, b) {
       return a.offset - b.offset;
     });
diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
index dc4616f..931d87f 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
@@ -6,8 +6,9 @@
 
 import 'package:analysis_server/plugin/analysis/navigation/navigation_core.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -243,6 +244,19 @@
   }
 
   @override
+  visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    Element element = node.staticElement;
+    if (element != null && element.isSynthetic) {
+      element = element.enclosingElement;
+    }
+    // add region
+    computer._addRegionForToken(node.thisKeyword, element);
+    computer._addRegionForNode(node.constructorName, element);
+    // process arguments
+    _safelyVisit(node.argumentList);
+  }
+
+  @override
   visitSimpleIdentifier(SimpleIdentifier node) {
     if (node.parent is ConstructorDeclaration) {
       return;
@@ -258,12 +272,8 @@
       element = element.enclosingElement;
     }
     // add region
-    SimpleIdentifier name = node.constructorName;
-    if (name != null) {
-      computer._addRegion_nodeStart_nodeEnd(node, name, element);
-    } else {
-      computer._addRegionForToken(node.superKeyword, element);
-    }
+    computer._addRegionForToken(node.superKeyword, element);
+    computer._addRegionForNode(node.constructorName, element);
     // process arguments
     _safelyVisit(node.argumentList);
   }
@@ -279,7 +289,16 @@
     }
     // add regions
     TypeName typeName = node.type;
-    computer._addRegionForNode(typeName.name, element);
+    // [prefix].ClassName
+    {
+      Identifier name = typeName.name;
+      Identifier className = name;
+      if (name is PrefixedIdentifier) {
+        name.prefix.accept(this);
+        className = name.identifier;
+      }
+      computer._addRegionForNode(className, element);
+    }
     // <TypeA, TypeB>
     TypeArgumentList typeArguments = typeName.typeArguments;
     if (typeArguments != null) {
diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
index adf253e..7eea646 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
@@ -6,8 +6,10 @@
 
 import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 3931907..ce2b38c 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -19,8 +19,8 @@
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:analyzer/src/generated/error.dart' as engine;
 import 'package:analyzer/src/generated/parser.dart' as engine;
@@ -130,23 +130,25 @@
         .toResponse(request.id);
   }
 
-  Response getAssists(Request request) {
+  Future getAssists(Request request) async {
     EditGetAssistsParams params = new EditGetAssistsParams.fromRequest(request);
     ContextSourcePair pair = server.getContextSourcePair(params.file);
     engine.AnalysisContext context = pair.context;
     Source source = pair.source;
     List<SourceChange> changes = <SourceChange>[];
     if (context != null && source != null) {
-      List<Assist> assists = computeAssists(
+      List<Assist> assists = await computeAssists(
           server.serverPlugin, context, source, params.offset, params.length);
       assists.forEach((Assist assist) {
         changes.add(assist.change);
       });
     }
-    return new EditGetAssistsResult(changes).toResponse(request.id);
+    Response response =
+        new EditGetAssistsResult(changes).toResponse(request.id);
+    server.sendResponse(response);
   }
 
-  Response getFixes(Request request) {
+  getFixes(Request request) async {
     var params = new EditGetFixesParams.fromRequest(request);
     String file = params.file;
     int offset = params.offset;
@@ -161,7 +163,7 @@
         for (engine.AnalysisError error in errorInfo.errors) {
           int errorLine = lineInfo.getLocation(error.offset).lineNumber;
           if (errorLine == requestLine) {
-            List<Fix> fixes = computeFixes(server.serverPlugin,
+            List<Fix> fixes = await computeFixes(server.serverPlugin,
                 server.resourceProvider, unit.element.context, error);
             if (fixes.isNotEmpty) {
               AnalysisError serverError =
@@ -178,7 +180,8 @@
       }
     }
     // respond
-    return new EditGetFixesResult(errorFixesList).toResponse(request.id);
+    return server.sendResponse(
+        new EditGetFixesResult(errorFixesList).toResponse(request.id));
   }
 
   @override
@@ -188,11 +191,13 @@
       if (requestName == EDIT_FORMAT) {
         return format(request);
       } else if (requestName == EDIT_GET_ASSISTS) {
-        return getAssists(request);
+        getAssists(request);
+        return Response.DELAYED_RESPONSE;
       } else if (requestName == EDIT_GET_AVAILABLE_REFACTORINGS) {
         return _getAvailableRefactorings(request);
       } else if (requestName == EDIT_GET_FIXES) {
-        return getFixes(request);
+        getFixes(request);
+        return Response.DELAYED_RESPONSE;
       } else if (requestName == EDIT_GET_REFACTORING) {
         return _getRefactoring(request);
       } else if (requestName == EDIT_ORGANIZE_DIRECTIVES) {
@@ -245,15 +250,20 @@
     if (!engine.AnalysisEngine.isDartFileName(file)) {
       return new Response.sortMembersInvalidFile(request);
     }
-    // prepare resolved units
-    List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
-    if (units.isEmpty) {
+    // prepare location
+    ContextSourcePair contextSource = server.getContextSourcePair(file);
+    engine.AnalysisContext context = contextSource.context;
+    Source source = contextSource.source;
+    if (context == null || source == null) {
       return new Response.sortMembersInvalidFile(request);
     }
-    // prepare context
-    CompilationUnit unit = units.first;
-    engine.AnalysisContext context = unit.element.context;
-    Source source = unit.element.source;
+    // prepare parsed unit
+    CompilationUnit unit;
+    try {
+      unit = context.parseCompilationUnit(source);
+    } catch (e) {
+      return new Response.sortMembersInvalidFile(request);
+    }
     // check if there are scan/parse errors in the file
     engine.AnalysisErrorInfo errors = context.getErrors(source);
     int numScanParseErrors = _getNumberOfScanParseErrors(errors.errors);
@@ -558,7 +568,9 @@
       if (units.isNotEmpty) {
         refactoring = new ExtractLocalRefactoring(units[0], offset, length);
         feedback = new ExtractLocalVariableFeedback(
-            <int>[], <int>[], <String>[], <int>[], <int>[]);
+            <String>[], <int>[], <int>[],
+            coveringExpressionOffsets: <int>[],
+            coveringExpressionLengths: <int>[]);
       }
     }
     if (kind == RefactoringKind.EXTRACT_METHOD) {
@@ -626,6 +638,10 @@
       feedback.names = refactoring.names;
       feedback.offsets = refactoring.offsets;
       feedback.lengths = refactoring.lengths;
+      feedback.coveringExpressionOffsets =
+          refactoring.coveringExpressionOffsets;
+      feedback.coveringExpressionLengths =
+          refactoring.coveringExpressionLengths;
     }
     if (refactoring is ExtractMethodRefactoring) {
       ExtractMethodRefactoring refactoring = this.refactoring;
diff --git a/pkg/analysis_server/lib/src/get_handler.dart b/pkg/analysis_server/lib/src/get_handler.dart
deleted file mode 100644
index fbf70a1..0000000
--- a/pkg/analysis_server/lib/src/get_handler.dart
+++ /dev/null
@@ -1,1655 +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 analysis_server.src.get_handler;
-
-import 'dart:async';
-import 'dart:collection';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domain_completion.dart';
-import 'package:analysis_server/src/domain_execution.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/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_index.dart';
-import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analysis_server/src/socket_server.dart';
-import 'package:analysis_server/src/status/ast_writer.dart';
-import 'package:analysis_server/src/status/element_writer.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/task/model.dart' as newTask;
-import 'package:plugin/plugin.dart';
-
-/**
- * A function that can be used to generate HTML output into the given [buffer].
- * The HTML that is generated must be valid (special characters must already be
- * encoded).
- */
-typedef void HtmlGenerator(StringBuffer buffer);
-
-/**
- * Instances of the class [GetHandler] handle GET requests.
- */
-class GetHandler {
-  /**
-   * The path used to request overall performance information.
-   */
-  static const String ANALYSIS_PERFORMANCE_PATH = '/perf/analysis';
-
-  /**
-   * The path used to request information about a element model.
-   */
-  static const String AST_PATH = '/ast';
-
-  /**
-   * The path used to request information about the cache entry corresponding
-   * to a single file.
-   */
-  static const String CACHE_ENTRY_PATH = '/cache_entry';
-
-  /**
-   * The path used to request the list of source files in a certain cache
-   * state.
-   */
-  static const String CACHE_STATE_PATH = '/cache_state';
-
-  /**
-   * The path used to request code completion information.
-   */
-  static const String COMPLETION_PATH = '/completion';
-
-  /**
-   * The path used to request communication performance information.
-   */
-  static const String COMMUNICATION_PERFORMANCE_PATH = '/perf/communication';
-
-  /**
-   * The path used to request information about a specific context.
-   */
-  static const String CONTEXT_PATH = '/context';
-
-  /**
-   * The path used to request information about a element model.
-   */
-  static const String ELEMENT_PATH = '/element';
-
-  /**
-   * The path used to request information about elements with the given name.
-   */
-  static const String INDEX_ELEMENT_BY_NAME = '/index/element-by-name';
-
-  /**
-   * The path used to request an overlay contents.
-   */
-  static const String OVERLAY_PATH = '/overlay';
-
-  /**
-   * The path used to request overlays information.
-   */
-  static const String OVERLAYS_PATH = '/overlays';
-
-  /**
-   * The path used to request the status of the analysis server as a whole.
-   */
-  static const String STATUS_PATH = '/status';
-
-  /**
-   * Query parameter used to represent the context to search for, when
-   * accessing [CACHE_ENTRY_PATH] or [CACHE_STATE_PATH].
-   */
-  static const String CONTEXT_QUERY_PARAM = 'context';
-
-  /**
-   * Query parameter used to represent the descriptor to search for, when
-   * accessing [CACHE_STATE_PATH].
-   */
-  static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';
-
-  /**
-   * Query parameter used to represent the name of elements to search for, when
-   * accessing [INDEX_ELEMENT_BY_NAME].
-   */
-  static const String INDEX_ELEMENT_NAME = 'name';
-
-  /**
-   * Query parameter used to represent the path of an overlayed file.
-   */
-  static const String PATH_PARAM = 'path';
-
-  /**
-   * Query parameter used to represent the source to search for, when accessing
-   * [CACHE_ENTRY_PATH].
-   */
-  static const String SOURCE_QUERY_PARAM = 'entry';
-
-  /**
-   * Query parameter used to represent the cache state to search for, when
-   * accessing [CACHE_STATE_PATH].
-   */
-  static const String STATE_QUERY_PARAM = 'state';
-
-  static final ContentType _htmlContent =
-      new ContentType("text", "html", charset: "utf-8");
-
-  /**
-   * The socket server whose status is to be reported on.
-   */
-  SocketServer _server;
-
-  /**
-   * Buffer containing strings printed by the analysis server.
-   */
-  List<String> _printBuffer;
-
-  /**
-   * Contents of overlay files.
-   */
-  final Map<String, String> _overlayContents = <String, String>{};
-
-  /**
-   * Initialize a newly created handler for GET requests.
-   */
-  GetHandler(this._server, this._printBuffer);
-
-  /**
-   * Return the active [CompletionDomainHandler]
-   * or `null` if either analysis server is not running
-   * or there is no completion domain handler.
-   */
-  CompletionDomainHandler get _completionDomainHandler {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return null;
-    }
-    return analysisServer.handlers
-        .firstWhere((h) => h is CompletionDomainHandler, orElse: () => null);
-  }
-
-  /**
-   * Handle a GET request received by the HTTP server.
-   */
-  void handleGetRequest(HttpRequest request) {
-    String path = request.uri.path;
-    if (path == STATUS_PATH) {
-      _returnServerStatus(request);
-    } else if (path == ANALYSIS_PERFORMANCE_PATH) {
-      _returnAnalysisPerformance(request);
-    } else if (path == AST_PATH) {
-      _returnAst(request);
-    } else if (path == CACHE_STATE_PATH) {
-      _returnCacheState(request);
-    } else if (path == CACHE_ENTRY_PATH) {
-      _returnCacheEntry(request);
-    } else if (path == COMPLETION_PATH) {
-      _returnCompletionInfo(request);
-    } else if (path == COMMUNICATION_PERFORMANCE_PATH) {
-      _returnCommunicationPerformance(request);
-    } else if (path == CONTEXT_PATH) {
-      _returnContextInfo(request);
-    } else if (path == ELEMENT_PATH) {
-      _returnElement(request);
-    } else if (path == INDEX_ELEMENT_BY_NAME) {
-      _returnIndexElementByName(request);
-    } else if (path == OVERLAY_PATH) {
-      _returnOverlayContents(request);
-    } else if (path == OVERLAYS_PATH) {
-      _returnOverlaysInfo(request);
-    } else {
-      _returnUnknownRequest(request);
-    }
-  }
-
-  /**
-   * Return the folder being managed by the given [analysisServer] that matches
-   * the given [contextFilter], or `null` if there is none.
-   */
-  Folder _findFolder(AnalysisServer analysisServer, String contextFilter) {
-    return analysisServer.folderMap.keys.firstWhere(
-        (Folder folder) => folder.path == contextFilter,
-        orElse: () => null);
-  }
-
-  /**
-   * Return `true` if the given analysis [context] has at least one entry with
-   * an exception.
-   */
-  bool _hasException(AnalysisContextImpl context) {
-    bool hasException = false;
-    context.visitCacheItems((Source source, SourceEntry sourceEntry,
-        DataDescriptor rowDesc, CacheState state) {
-      if (sourceEntry.exception != null) {
-        hasException = true;
-      }
-    });
-    return hasException;
-  }
-
-  /**
-   * Return the folder in the [folderMap] with which the given [context] is
-   * associated.
-   */
-  Folder _keyForValue(
-      Map<Folder, AnalysisContext> folderMap, AnalysisContext context) {
-    for (Folder folder in folderMap.keys) {
-      if (folderMap[folder] == context) {
-        return folder;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return a response displaying overall performance information.
-   */
-  void _returnAnalysisPerformance(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server is not running');
-    }
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Analysis Performance', [],
-          (StringBuffer buffer) {
-        buffer.write('<h3>Analysis Performance</h3>');
-
-        //
-        // Write performance tags.
-        //
-        {
-          buffer.write('<p><b>Time spent in each phase of analysis</b></p>');
-          buffer.write(
-              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
-          _writeRow(buffer, ['Time (in ms)', 'Percent', 'Analysis Phase'],
-              header: true);
-          // prepare sorted tags
-          List<PerformanceTag> tags = PerformanceTag.all.toList();
-          tags.remove(ServerPerformanceStatistics.idle);
-          tags.sort((a, b) => b.elapsedMs - a.elapsedMs);
-          // prepare total time
-          int totalTime = 0;
-          tags.forEach((PerformanceTag tag) {
-            totalTime += tag.elapsedMs;
-          });
-          // write rows
-          void writeRow(PerformanceTag tag) {
-            double percent = (tag.elapsedMs * 100) / totalTime;
-            String percentStr = '${percent.toStringAsFixed(2)}%';
-            _writeRow(buffer, [tag.elapsedMs, percentStr, tag.label],
-                classes: ["right", "right", null]);
-          }
-          tags.forEach(writeRow);
-          buffer.write('</table>');
-        }
-
-        //
-        // Write new task model timing information.
-        //
-        if (AnalysisEngine.instance.useTaskModel) {
-          buffer.write('<p><b>Task performace data</b></p>');
-          buffer.write(
-              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
-          _writeRow(
-              buffer,
-              [
-                'Task Name',
-                'Count',
-                'Total Time (in ms)',
-                'Average Time (in ms)'
-              ],
-              header: true);
-
-          Map<Type, int> countMap = newTask.AnalysisTask.countMap;
-          Map<Type, Stopwatch> stopwatchMap = newTask.AnalysisTask.stopwatchMap;
-          List<Type> taskClasses = stopwatchMap.keys.toList();
-          taskClasses.sort((Type first, Type second) =>
-              first.toString().compareTo(second.toString()));
-          int totalTime = 0;
-          taskClasses.forEach((Type taskClass) {
-            int count = countMap[taskClass];
-            if (count == null) {
-              count = 0;
-            }
-            int taskTime = stopwatchMap[taskClass].elapsedMilliseconds;
-            totalTime += taskTime;
-            _writeRow(buffer, [
-              taskClass.toString(),
-              count,
-              taskTime,
-              count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3)
-            ], classes: [
-              null,
-              "right",
-              "right",
-              "right"
-            ]);
-          });
-          _writeRow(buffer, ['Total', '-', totalTime, '-'],
-              classes: [null, "right", "right", "right"]);
-          buffer.write('</table>');
-        }
-
-        //
-        // Write old task model transition information.
-        //
-        {
-          Map<DataDescriptor, Map<CacheState, int>> transitionMap =
-              SourceEntry.transitionMap;
-          buffer.write(
-              '<p><b>Number of times a state transitioned to VALID (grouped by descriptor)</b></p>');
-          if (transitionMap.isEmpty) {
-            buffer.write('<p>none</p>');
-          } else {
-            List<DataDescriptor> descriptors = transitionMap.keys.toList();
-            descriptors.sort((DataDescriptor first, DataDescriptor second) =>
-                first.toString().compareTo(second.toString()));
-            for (DataDescriptor key in descriptors) {
-              Map<CacheState, int> countMap = transitionMap[key];
-              List<CacheState> oldStates = countMap.keys.toList();
-              oldStates.sort((CacheState first, CacheState second) =>
-                  first.toString().compareTo(second.toString()));
-              buffer.write('<p>${key.toString()}</p>');
-              buffer.write(
-                  '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
-              _writeRow(buffer, ['Count', 'Previous State'], header: true);
-              for (CacheState state in oldStates) {
-                _writeRow(buffer, [countMap[state], state.toString()],
-                    classes: ["right", null]);
-              }
-              buffer.write('</table>');
-            }
-          }
-        }
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about an AST structure.
-   */
-  void _returnAst(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    if (folder == null) {
-      return _returnFailure(request, 'Invalid context: $contextFilter');
-    }
-    String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
-    if (sourceUri == null) {
-      return _returnFailure(
-          request, 'Query parameter $SOURCE_QUERY_PARAM required');
-    }
-
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - AST Structure',
-          ['Context: $contextFilter', 'File: $sourceUri'], (HttpResponse) {
-        Source source = context.sourceFactory.forUri(sourceUri);
-        if (source == null) {
-          buffer.write('<p>Not found.</p>');
-          return;
-        }
-        SourceEntry entry = context.getReadableSourceEntryOrNull(source);
-        if (entry == null) {
-          buffer.write('<p>Not found.</p>');
-          return;
-        }
-        CompilationUnit ast = (entry as DartEntry).anyParsedCompilationUnit;
-        if (ast == null) {
-          buffer.write('<p>null</p>');
-          return;
-        }
-        AstWriter writer = new AstWriter(buffer);
-        ast.accept(writer);
-        if (writer.exceptions.isNotEmpty) {
-          buffer.write('<h3>Exceptions while creating page</h3>');
-          for (CaughtException exception in writer.exceptions) {
-            _writeException(buffer, exception);
-          }
-        }
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about a single source file in the
-   * cache.
-   */
-  void _returnCacheEntry(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    if (folder == null) {
-      return _returnFailure(request, 'Invalid context: $contextFilter');
-    }
-    String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
-    if (sourceUri == null) {
-      return _returnFailure(
-          request, 'Query parameter $SOURCE_QUERY_PARAM required');
-    }
-
-    List<Folder> allContexts = <Folder>[];
-    Map<Folder, SourceEntry> entryMap = new HashMap<Folder, SourceEntry>();
-    analysisServer.folderMap
-        .forEach((Folder folder, AnalysisContextImpl context) {
-      Source source = context.sourceFactory.forUri(sourceUri);
-      if (source != null) {
-        SourceEntry entry = context.getReadableSourceEntryOrNull(source);
-        if (entry != null) {
-          allContexts.add(folder);
-          entryMap[folder] = entry;
-        }
-      }
-    });
-    allContexts.sort((Folder firstFolder, Folder secondFolder) =>
-        firstFolder.path.compareTo(secondFolder.path));
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Cache Entry',
-          ['Context: $contextFilter', 'File: $sourceUri'], (HttpResponse) {
-        buffer.write('<h3>Analyzing Contexts</h3><p>');
-        bool first = true;
-        allContexts.forEach((Folder folder) {
-          if (first) {
-            first = false;
-          } else {
-            buffer.write('<br>');
-          }
-          AnalysisContextImpl analyzingContext =
-              analysisServer.folderMap[folder];
-          if (analyzingContext == context) {
-            buffer.write(folder.path);
-          } else {
-            buffer.write(makeLink(
-                CACHE_ENTRY_PATH,
-                {
-                  CONTEXT_QUERY_PARAM: folder.path,
-                  SOURCE_QUERY_PARAM: sourceUri
-                },
-                HTML_ESCAPE.convert(folder.path)));
-          }
-          if (entryMap[folder].explicitlyAdded) {
-            buffer.write(' (explicit)');
-          } else {
-            buffer.write(' (implicit)');
-          }
-        });
-        buffer.write('</p>');
-
-        SourceEntry entry = entryMap[folder];
-        if (entry == null) {
-          buffer.write('<p>Not being analyzed in this context.</p>');
-          return;
-        }
-        Map<String, String> linkParameters = <String, String>{
-          CONTEXT_QUERY_PARAM: folder.path,
-          SOURCE_QUERY_PARAM: sourceUri
-        };
-
-        buffer.write('<h3>Library Independent</h3>');
-        _writeDescriptorTable(buffer, entry.descriptors, entry.getState,
-            entry.getValue, linkParameters);
-        if (entry is DartEntry) {
-          for (Source librarySource in entry.containingLibraries) {
-            String libraryName = HTML_ESCAPE.convert(librarySource.fullName);
-            buffer.write('<h3>In library $libraryName:</h3>');
-            _writeDescriptorTable(
-                buffer,
-                entry.libraryDescriptors,
-                (DataDescriptor descriptor) =>
-                    entry.getStateInLibrary(descriptor, librarySource),
-                (DataDescriptor descriptor) =>
-                    entry.getValueInLibrary(descriptor, librarySource),
-                linkParameters);
-          }
-        }
-        if (entry.exception != null) {
-          buffer.write('<h3>Exception</h3>');
-          _writeException(buffer, entry.exception);
-        }
-      });
-    });
-  }
-
-  /**
-   * Return a response indicating the set of source files in a certain cache
-   * state.
-   */
-  void _returnCacheState(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    // Figure out which context is being searched within.
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    // Figure out what CacheState is being searched for.
-    String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
-    if (stateQueryParam == null) {
-      return _returnFailure(
-          request, 'Query parameter $STATE_QUERY_PARAM required');
-    }
-    CacheState stateFilter = null;
-    for (CacheState value in CacheState.values) {
-      if (value.toString() == stateQueryParam) {
-        stateFilter = value;
-      }
-    }
-    if (stateFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $STATE_QUERY_PARAM is invalid');
-    }
-    // Figure out which descriptor is being searched for.
-    String descriptorFilter =
-        request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM];
-    if (descriptorFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $DESCRIPTOR_QUERY_PARAM required');
-    }
-
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-    List<String> links = <String>[];
-    context.visitCacheItems((Source source, SourceEntry dartEntry,
-        DataDescriptor rowDesc, CacheState state) {
-      if (state != stateFilter || rowDesc.toString() != descriptorFilter) {
-        return;
-      }
-      String link = makeLink(
-          CACHE_ENTRY_PATH,
-          {
-            CONTEXT_QUERY_PARAM: folder.path,
-            SOURCE_QUERY_PARAM: source.uri.toString()
-          },
-          HTML_ESCAPE.convert(source.fullName));
-      links.add(link);
-    });
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Cache Search', [
-        'Context: $contextFilter',
-        'Descriptor: ${HTML_ESCAPE.convert(descriptorFilter)}',
-        'State: ${HTML_ESCAPE.convert(stateQueryParam)}'
-      ], (StringBuffer buffer) {
-        buffer.write('<p>${links.length} files found</p>');
-        buffer.write('<ul>');
-        links.forEach((String link) {
-          buffer.write('<li>$link</li>');
-        });
-        buffer.write('</ul>');
-      });
-    });
-  }
-
-  /**
-   * Return a response displaying overall performance information.
-   */
-  void _returnCommunicationPerformance(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server is not running');
-    }
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Communication Performance', [],
-          (StringBuffer buffer) {
-        buffer.write('<h3>Communication Performance</h3>');
-        _writeTwoColumns(buffer, (StringBuffer buffer) {
-          ServerPerformance perf = analysisServer.performanceDuringStartup;
-          int requestCount = perf.requestCount;
-          num averageLatency = requestCount > 0
-              ? (perf.requestLatency / requestCount).round()
-              : 0;
-          int maximumLatency = perf.maxLatency;
-          num slowRequestPercent = requestCount > 0
-              ? (perf.slowRequestCount * 100 / requestCount).round()
-              : 0;
-          buffer.write('<h4>Startup</h4>');
-          buffer.write('<table>');
-          _writeRow(buffer, [requestCount, 'requests'],
-              classes: ["right", null]);
-          _writeRow(buffer, [averageLatency, 'ms average latency'],
-              classes: ["right", null]);
-          _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
-              classes: ["right", null]);
-          _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
-              classes: ["right", null]);
-          if (analysisServer.performanceAfterStartup != null) {
-            int startupTime = analysisServer.performanceAfterStartup.startTime -
-                perf.startTime;
-            _writeRow(
-                buffer, [startupTime, 'ms for initial analysis to complete']);
-          }
-          buffer.write('</table>');
-        }, (StringBuffer buffer) {
-          ServerPerformance perf = analysisServer.performanceAfterStartup;
-          if (perf == null) {
-            return;
-          }
-          int requestCount = perf.requestCount;
-          num averageLatency = requestCount > 0
-              ? (perf.requestLatency * 10 / requestCount).round() / 10
-              : 0;
-          int maximumLatency = perf.maxLatency;
-          num slowRequestPercent = requestCount > 0
-              ? (perf.slowRequestCount * 100 / requestCount).round()
-              : 0;
-          buffer.write('<h4>Current</h4>');
-          buffer.write('<table>');
-          _writeRow(buffer, [requestCount, 'requests'],
-              classes: ["right", null]);
-          _writeRow(buffer, [averageLatency, 'ms average latency'],
-              classes: ["right", null]);
-          _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
-              classes: ["right", null]);
-          _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
-              classes: ["right", null]);
-          buffer.write('</table>');
-        });
-      });
-    });
-  }
-
-  /**
-   * Return a response displaying code completion information.
-   */
-  void _returnCompletionInfo(HttpRequest request) {
-    String value = request.requestedUri.queryParameters['index'];
-    int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Completion Stats', [],
-          (StringBuffer buffer) {
-        _writeCompletionPerformanceDetail(buffer, index);
-        _writeCompletionPerformanceList(buffer);
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about a single source file in the
-   * cache.
-   */
-  void _returnContextInfo(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    if (folder == null) {
-      return _returnFailure(request, 'Invalid context: $contextFilter');
-    }
-
-    List<String> priorityNames;
-    List<String> explicitNames = <String>[];
-    List<String> implicitNames = <String>[];
-    Map<String, String> links = new HashMap<String, String>();
-    List<CaughtException> exceptions = <CaughtException>[];
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-    priorityNames = context.prioritySources
-        .map((Source source) => source.fullName)
-        .toList();
-    context.visitCacheItems((Source source, SourceEntry sourceEntry,
-        DataDescriptor rowDesc, CacheState state) {
-      String sourceName = source.fullName;
-      if (!links.containsKey(sourceName)) {
-        CaughtException exception = sourceEntry.exception;
-        if (exception != null) {
-          exceptions.add(exception);
-        }
-        String link = makeLink(
-            CACHE_ENTRY_PATH,
-            {
-              CONTEXT_QUERY_PARAM: folder.path,
-              SOURCE_QUERY_PARAM: source.uri.toString()
-            },
-            sourceName,
-            exception != null);
-        if (sourceEntry.explicitlyAdded) {
-          explicitNames.add(sourceName);
-        } else {
-          implicitNames.add(sourceName);
-        }
-        links[sourceName] = link;
-      }
-    });
-    explicitNames.sort();
-    implicitNames.sort();
-
-    _overlayContents.clear();
-    context.visitContentCache((String fullName, int stamp, String contents) {
-      _overlayContents[fullName] = contents;
-    });
-
-    void _writeFiles(
-        StringBuffer buffer, String title, List<String> fileNames) {
-      buffer.write('<h3>$title</h3>');
-      if (fileNames == null || fileNames.isEmpty) {
-        buffer.write('<p>None</p>');
-      } else {
-        buffer.write('<table style="width: 100%">');
-        for (String fileName in fileNames) {
-          buffer.write('<tr><td>');
-          buffer.write(links[fileName]);
-          buffer.write('</td><td>');
-          if (_overlayContents.containsKey(fileName)) {
-            buffer.write(
-                makeLink(OVERLAY_PATH, {PATH_PARAM: fileName}, 'overlay'));
-          }
-          buffer.write('</td></tr>');
-        }
-        buffer.write('</table>');
-      }
-    }
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(
-          buffer, 'Analysis Server - Context', ['Context: $contextFilter'],
-          (StringBuffer buffer) {
-        List headerRowText = ['Context'];
-        headerRowText.addAll(CacheState.values);
-        buffer.write('<h3>Summary</h3>');
-        buffer.write('<table>');
-        _writeRow(buffer, headerRowText, header: true);
-        AnalysisContextStatistics statistics = context.statistics;
-        statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
-          List rowText = [row.name];
-          for (CacheState state in CacheState.values) {
-            String text = row.getCount(state).toString();
-            Map<String, String> params = <String, String>{
-              STATE_QUERY_PARAM: state.toString(),
-              CONTEXT_QUERY_PARAM: folder.path,
-              DESCRIPTOR_QUERY_PARAM: row.name
-            };
-            rowText.add(makeLink(CACHE_STATE_PATH, params, text));
-          }
-          _writeRow(buffer, rowText, classes: [null, "right"]);
-        });
-        buffer.write('</table>');
-
-        _writeFiles(buffer, 'Priority Files', priorityNames);
-        _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
-        _writeFiles(buffer, 'Implicitly Analyzed Files', implicitNames);
-
-        buffer.write('<h3>Exceptions</h3>');
-        if (exceptions.isEmpty) {
-          buffer.write('<p>None</p>');
-        } else {
-          exceptions.forEach((CaughtException exception) {
-            _writeException(buffer, exception);
-          });
-        }
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about an element structure.
-   */
-  void _returnElement(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    if (folder == null) {
-      return _returnFailure(request, 'Invalid context: $contextFilter');
-    }
-    String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
-    if (sourceUri == null) {
-      return _returnFailure(
-          request, 'Query parameter $SOURCE_QUERY_PARAM required');
-    }
-
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Element Model', [
-        'Context: $contextFilter',
-        'File: $sourceUri'
-      ], (StringBuffer buffer) {
-        Source source = context.sourceFactory.forUri(sourceUri);
-        if (source == null) {
-          buffer.write('<p>Not found.</p>');
-          return;
-        }
-        SourceEntry entry = context.getReadableSourceEntryOrNull(source);
-        if (entry == null) {
-          buffer.write('<p>Not found.</p>');
-          return;
-        }
-        LibraryElement element = entry.getValue(DartEntry.ELEMENT);
-        if (element == null) {
-          buffer.write('<p>null</p>');
-          return;
-        }
-        element.accept(new ElementWriter(buffer));
-      });
-    });
-  }
-
-  void _returnFailure(HttpRequest request, String message) {
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Failure', [],
-          (StringBuffer buffer) {
-        buffer.write(HTML_ESCAPE.convert(message));
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about elements with the given
-   * name.
-   */
-  Future _returnIndexElementByName(HttpRequest request) async {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    Index index = analysisServer.index;
-    if (index == null) {
-      return _returnFailure(request, 'Indexing is disabled');
-    }
-    String name = request.uri.queryParameters[INDEX_ELEMENT_NAME];
-    if (name == null) {
-      return _returnFailure(
-          request, 'Query parameter $INDEX_ELEMENT_NAME required');
-    }
-    if (index is LocalIndex) {
-      Map<List<String>, List<InspectLocation>> relations =
-          await index.findElementsByName(name);
-      _writeResponse(request, (StringBuffer buffer) {
-        _writePage(buffer, 'Analysis Server - Index Elements', ['Name: $name'],
-            (StringBuffer buffer) {
-          buffer.write('<table border="1">');
-          _writeRow(buffer, ['Element', 'Relationship', 'Location'],
-              header: true);
-          relations.forEach(
-              (List<String> elementPath, List<InspectLocation> relations) {
-            String elementLocation = elementPath.join(' ');
-            relations.forEach((InspectLocation location) {
-              var relString = location.relationship.identifier;
-              var locString = '${location.path} offset=${location.offset} '
-                  'length=${location.length} flags=${location.flags}';
-              _writeRow(buffer, [elementLocation, relString, locString]);
-            });
-          });
-          buffer.write('</table>');
-        });
-      });
-    } else {
-      return _returnFailure(request, 'LocalIndex expected, but $index found.');
-    }
-  }
-
-  void _returnOverlayContents(HttpRequest request) {
-    String path = request.requestedUri.queryParameters[PATH_PARAM];
-    if (path == null) {
-      return _returnFailure(request, 'Query parameter $PATH_PARAM required');
-    }
-    String contents = _overlayContents[path];
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Overlay', [],
-          (StringBuffer buffer) {
-        buffer.write('<pre>${HTML_ESCAPE.convert(contents)}</pre>');
-      });
-    });
-  }
-
-  /**
-   * Return a response displaying overlays information.
-   */
-  void _returnOverlaysInfo(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server is not running');
-    }
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Overlays', [],
-          (StringBuffer buffer) {
-        buffer.write('<table border="1">');
-        _overlayContents.clear();
-        ContentCache overlayState = analysisServer.overlayState;
-        overlayState.accept((String fullName, int stamp, String contents) {
-          buffer.write('<tr>');
-          String link =
-              makeLink(OVERLAY_PATH, {PATH_PARAM: fullName}, fullName);
-          DateTime time = new DateTime.fromMillisecondsSinceEpoch(stamp);
-          _writeRow(buffer, [link, time]);
-          _overlayContents[fullName] = contents;
-        });
-        int count = _overlayContents.length;
-        buffer.write('<tr><td colspan="2">Total: $count entries.</td></tr>');
-        buffer.write('</table>');
-      });
-    });
-  }
-
-  /**
-   * Return a response indicating the status of the analysis server.
-   */
-  void _returnServerStatus(HttpRequest request) {
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Status', [], (StringBuffer buffer) {
-        if (_writeServerStatus(buffer)) {
-          _writeAnalysisStatus(buffer);
-          _writeEditStatus(buffer);
-          _writeExecutionStatus(buffer);
-          _writePluginStatus(buffer);
-          _writeRecentOutput(buffer);
-        }
-      });
-    });
-  }
-
-  /**
-   * Return an error in response to an unrecognized request received by the HTTP
-   * server.
-   */
-  void _returnUnknownRequest(HttpRequest request) {
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server', [], (StringBuffer buffer) {
-        buffer.write('<h3>Pages</h3>');
-        buffer.write('<p>');
-        buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer
-            .write(makeLink(COMMUNICATION_PERFORMANCE_PATH, {}, 'Performance'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer.write(makeLink(STATUS_PATH, {}, 'Server status'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer.write(makeLink(OVERLAYS_PATH, {}, 'File overlays'));
-        buffer.write('</p>');
-      });
-    });
-  }
-
-  /**
-   * Return a two digit decimal representation of the given non-negative integer
-   * [value].
-   */
-  String _twoDigit(int value) {
-    if (value < 10) {
-      return '0$value';
-    }
-    return value.toString();
-  }
-
-  /**
-   * Write the status of the analysis domain (on the main status page) to the
-   * given [buffer] object.
-   */
-  void _writeAnalysisStatus(StringBuffer buffer) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    Map<Folder, AnalysisContext> folderMap = analysisServer.folderMap;
-    List<Folder> folders = folderMap.keys.toList();
-    folders.sort((Folder first, Folder second) =>
-        first.shortName.compareTo(second.shortName));
-    AnalysisOptionsImpl options = analysisServer.defaultContextOptions;
-    ServerOperationQueue operationQueue = analysisServer.operationQueue;
-
-    buffer.write('<h3>Analysis Domain</h3>');
-    _writeTwoColumns(buffer, (StringBuffer buffer) {
-      if (operationQueue.isEmpty) {
-        buffer.write('<p>Status: Done analyzing</p>');
-      } else {
-        ServerOperation operation = operationQueue.peek();
-        if (operation is PerformAnalysisOperation) {
-          Folder folder = _keyForValue(folderMap, operation.context);
-          if (folder == null) {
-            buffer.write('<p>Status: Analyzing in unmapped context</p>');
-          } else {
-            buffer.write('<p>Status: Analyzing in ${folder.path}</p>');
-          }
-        } else {
-          buffer.write('<p>Status: Analyzing</p>');
-        }
-      }
-
-      buffer.write('<p><b>Analysis Contexts</b></p>');
-      buffer.write('<p>');
-      bool first = true;
-      folders.forEach((Folder folder) {
-        if (first) {
-          first = false;
-        } else {
-          buffer.write('<br>');
-        }
-        String key = folder.shortName;
-        buffer.write(makeLink(CONTEXT_PATH, {CONTEXT_QUERY_PARAM: folder.path},
-            key, _hasException(folderMap[folder])));
-      });
-      buffer.write('</p>');
-
-      buffer.write('<p><b>Options</b></p>');
-      buffer.write('<p>');
-      _writeOption(
-          buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
-      _writeOption(buffer, 'Cache size', options.cacheSize);
-      _writeOption(
-          buffer, 'Enable strict call checks', options.enableStrictCallChecks);
-      _writeOption(buffer, 'Enable super mixins', options.enableSuperMixins);
-      _writeOption(buffer, 'Generate hints', options.hint);
-      _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
-      _writeOption(buffer, 'Generate errors in implicit files',
-          options.generateImplicitErrors);
-      _writeOption(
-          buffer, 'Generate errors in SDK files', options.generateSdkErrors);
-      _writeOption(buffer, 'Incremental resolution', options.incremental);
-      _writeOption(buffer, 'Incremental resolution with API changes',
-          options.incrementalApi);
-      _writeOption(buffer, 'Preserve comments', options.preserveComments,
-          last: true);
-      buffer.write('</p>');
-      int freq = AnalysisServer.performOperationDelayFreqency;
-      String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
-      buffer.write('<p><b>perform operation delay:</b> $delay</p>');
-
-      buffer.write('<p><b>Performance Data</b></p>');
-      buffer.write('<p>');
-      buffer.write(makeLink(ANALYSIS_PERFORMANCE_PATH, {}, 'Task data'));
-      buffer.write('</p>');
-    }, (StringBuffer buffer) {
-      _writeSubscriptionMap(
-          buffer, AnalysisService.VALUES, analysisServer.analysisServices);
-    });
-  }
-
-  /**
-   * Write performance information about a specific completion request
-   * to the given [buffer] object.
-   */
-  void _writeCompletionPerformanceDetail(StringBuffer buffer, int index) {
-    CompletionDomainHandler handler = _completionDomainHandler;
-    CompletionPerformance performance;
-    if (handler != null) {
-      List<CompletionPerformance> list = handler.performanceList;
-      if (list != null && list.isNotEmpty) {
-        performance = list[max(0, min(list.length - 1, index))];
-      }
-    }
-    if (performance == null) {
-      buffer.write('<h3>Completion Performance Detail</h3>');
-      buffer.write('<p>No completions yet</p>');
-      return;
-    }
-    buffer.write('<h3>Completion Performance Detail</h3>');
-    buffer.write('<p>${performance.startTimeAndMs} for ${performance.source}');
-    buffer.write('<table>');
-    _writeRow(buffer, ['Elapsed', '', 'Operation'], header: true);
-    performance.operations.forEach((OperationPerformance op) {
-      String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
-      _writeRow(buffer, [elapsed, '&nbsp;&nbsp;', op.name]);
-    });
-    buffer.write('</table>');
-    buffer.write('<p><b>Compute Cache Performance</b>: ');
-    if (handler.computeCachePerformance == null) {
-      buffer.write('none');
-    } else {
-      int elapsed = handler.computeCachePerformance.elapsedInMilliseconds;
-      Source source = handler.computeCachePerformance.source;
-      buffer.write(' $elapsed ms for $source');
-    }
-    buffer.write('</p>');
-  }
-
-  /**
-   * Write a table showing summary information for the last several
-   * completion requests to the given [buffer] object.
-   */
-  void _writeCompletionPerformanceList(StringBuffer buffer) {
-    CompletionDomainHandler handler = _completionDomainHandler;
-    buffer.write('<h3>Completion Performance List</h3>');
-    if (handler == null) {
-      return;
-    }
-    buffer.write('<table>');
-    _writeRow(
-        buffer,
-        [
-          'Start Time',
-          '',
-          'First (ms)',
-          '',
-          'Complete (ms)',
-          '',
-          '# Notifications',
-          '',
-          '# Suggestions',
-          '',
-          'Snippet'
-        ],
-        header: true);
-    int index = 0;
-    for (CompletionPerformance performance in handler.performanceList) {
-      String link = makeLink(COMPLETION_PATH, {'index': '$index'},
-          '${performance.startTimeAndMs}');
-      _writeRow(buffer, [
-        link,
-        '&nbsp;&nbsp;',
-        performance.firstNotificationInMilliseconds,
-        '&nbsp;&nbsp;',
-        performance.elapsedInMilliseconds,
-        '&nbsp;&nbsp;',
-        performance.notificationCount,
-        '&nbsp;&nbsp;',
-        performance.suggestionCount,
-        '&nbsp;&nbsp;',
-        HTML_ESCAPE.convert(performance.snippet)
-      ]);
-      ++index;
-    }
-
-    buffer.write('</table>');
-    buffer.write('''
-      <p><strong>First (ms)</strong> - the number of milliseconds
-        from when completion received the request until the first notification
-        with completion results was queued for sending back to the client.
-      <p><strong>Complete (ms)</strong> - the number of milliseconds
-        from when completion received the request until the final notification
-        with completion results was queued for sending back to the client.
-      <p><strong># Notifications</strong> - the total number of notifications
-        sent to the client with completion results for this request.
-      <p><strong># Suggestions</strong> - the number of suggestions
-        sent to the client in the first notification, followed by a comma,
-        followed by the number of suggestions send to the client
-        in the last notification. If there is only one notification,
-        then there will be only one number in this column.''');
-  }
-
-  /**
-   * Generate a table showing the cache values corresponding to the given
-   * [descriptors], using [getState] to get the cache state corresponding to
-   * each descriptor, and [getValue] to get the cached value corresponding to
-   * each descriptor.  Append the resulting HTML to the given [buffer]. The
-   * [linkParameters] will be used if the value is too large to be displayed on
-   * the current page and needs to be linked to a separate page.
-   */
-  void _writeDescriptorTable(
-      StringBuffer buffer,
-      List<DataDescriptor> descriptors,
-      CacheState getState(DataDescriptor),
-      dynamic getValue(DataDescriptor),
-      Map<String, String> linkParameters) {
-    buffer.write('<dl>');
-    for (DataDescriptor descriptor in descriptors) {
-      String descriptorName = HTML_ESCAPE.convert(descriptor.toString());
-      String descriptorState =
-          HTML_ESCAPE.convert(getState(descriptor).toString());
-      buffer.write('<dt>$descriptorName ($descriptorState)</dt><dd>');
-      try {
-        _writeValueAsHtml(buffer, getValue(descriptor), linkParameters);
-      } catch (exception) {
-        buffer.write('(${HTML_ESCAPE.convert(exception.toString())})');
-      }
-      buffer.write('</dd>');
-    }
-    buffer.write('</dl>');
-  }
-
-  /**
-   * Write the status of the edit domain (on the main status page) to the given
-   * [buffer].
-   */
-  void _writeEditStatus(StringBuffer buffer) {
-    buffer.write('<h3>Edit Domain</h3>');
-    _writeTwoColumns(buffer, (StringBuffer buffer) {
-      buffer.write('<p><b>Performance Data</b></p>');
-      buffer.write('<p>');
-      buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
-      buffer.write('</p>');
-    }, (StringBuffer buffer) {});
-  }
-
-  /**
-   * Write a representation of the given [caughtException] to the given
-   * [buffer]. If [isCause] is `true`, then the exception was a cause for
-   * another exception.
-   */
-  void _writeException(StringBuffer buffer, CaughtException caughtException,
-      {bool isCause: false}) {
-    Object exception = caughtException.exception;
-
-    if (exception is AnalysisException) {
-      buffer.write('<p>');
-      if (isCause) {
-        buffer.write('Caused by ');
-      }
-      buffer.write(exception.message);
-      buffer.write('</p>');
-      _writeStackTrace(buffer, caughtException.stackTrace);
-      CaughtException cause = exception.cause;
-      if (cause != null) {
-        buffer.write('<blockquote>');
-        _writeException(buffer, cause, isCause: true);
-        buffer.write('</blockquote>');
-      }
-    } else {
-      buffer.write('<p>');
-      if (isCause) {
-        buffer.write('Caused by ');
-      }
-      buffer.write(exception.toString());
-      buffer.write('<p>');
-      _writeStackTrace(buffer, caughtException.stackTrace);
-    }
-  }
-
-  /**
-   * Write the status of the execution domain (on the main status page) to the
-   * given [buffer].
-   */
-  void _writeExecutionStatus(StringBuffer buffer) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    ExecutionDomainHandler handler = analysisServer.handlers.firstWhere(
-        (RequestHandler handler) => handler is ExecutionDomainHandler,
-        orElse: () => null);
-    Set<ExecutionService> services = new Set<ExecutionService>();
-    if (handler.onFileAnalyzed != null) {
-      services.add(ExecutionService.LAUNCH_DATA);
-    }
-
-    if (handler != null) {
-      buffer.write('<h3>Execution Domain</h3>');
-      _writeTwoColumns(buffer, (StringBuffer buffer) {
-        _writeSubscriptionList(buffer, ExecutionService.VALUES, services);
-      }, (StringBuffer buffer) {});
-    }
-  }
-
-  /**
-   * Write a representation of an analysis option with the given [name] and
-   * [value] to the given [buffer]. The option should be separated from other
-   * options unless the [last] flag is true, indicating that this is the last
-   * option in the list of options.
-   */
-  void _writeOption(StringBuffer buffer, String name, Object value,
-      {bool last: false}) {
-    buffer.write(name);
-    buffer.write(' = ');
-    buffer.write(value.toString());
-    if (!last) {
-      buffer.write('<br>');
-    }
-  }
-
-  /**
-   * Write a standard HTML page to the given [buffer]. The page will have the
-   * given [title] and a body that is generated by the given [body] generator.
-   */
-  void _writePage(StringBuffer buffer, String title, List<String> subtitles,
-      HtmlGenerator body) {
-    DateTime now = new DateTime.now();
-    String date = "${now.month}/${now.day}/${now.year}";
-    String time =
-        "${now.hour}:${_twoDigit(now.minute)}:${_twoDigit(now.second)}.${now.millisecond}";
-
-    buffer.write('<!DOCTYPE html>');
-    buffer.write('<html>');
-    buffer.write('<head>');
-    buffer.write('<meta charset="utf-8">');
-    buffer.write(
-        '<meta name="viewport" content="width=device-width, initial-scale=1.0">');
-    buffer.write('<title>$title</title>');
-    buffer.write('<style>');
-    buffer.write('a {color: #0000DD; text-decoration: none;}');
-    buffer.write('a:link.error {background-color: #FFEEEE;}');
-    buffer.write('a:visited.error {background-color: #FFEEEE;}');
-    buffer.write('a:hover.error {background-color: #FFEEEE;}');
-    buffer.write('a:active.error {background-color: #FFEEEE;}');
-    buffer.write(
-        'h3 {background-color: #DDDDDD; margin-top: 0em; margin-bottom: 0em;}');
-    buffer.write('p {margin-top: 0.5em; margin-bottom: 0.5em;}');
-//    response.write('span.error {text-decoration-line: underline; text-decoration-color: red; text-decoration-style: wavy;}');
-    buffer.write(
-        'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}');
-    buffer.write('td.column {vertical-align: top; width: 50%;}');
-    buffer.write('td.right {text-align: right;}');
-    buffer.write('</style>');
-    buffer.write('</head>');
-
-    buffer.write('<body>');
-    buffer.write(
-        '<h2>$title <small><small>(as of $time on $date)</small></small></h2>');
-    if (subtitles != null && subtitles.isNotEmpty) {
-      buffer.write('<blockquote>');
-      bool first = true;
-      for (String subtitle in subtitles) {
-        if (first) {
-          first = false;
-        } else {
-          buffer.write('<br>');
-        }
-        buffer.write('<b>');
-        buffer.write(subtitle);
-        buffer.write('</b>');
-      }
-      buffer.write('</blockquote>');
-    }
-    try {
-      body(buffer);
-    } catch (exception, stackTrace) {
-      buffer.write('<h3>Exception while creating page</h3>');
-      _writeException(buffer, new CaughtException(exception, stackTrace));
-    }
-    buffer.write('</body>');
-    buffer.write('</html>');
-  }
-
-  /**
-   * Write the recent output section (on the main status page) to the given
-   * [buffer] object.
-   */
-  void _writePluginStatus(StringBuffer buffer) {
-    void writePlugin(Plugin plugin) {
-      buffer.write(plugin.uniqueIdentifier);
-      buffer.write(' (');
-      buffer.write(plugin.runtimeType);
-      buffer.write(')<br>');
-    }
-    buffer.write('<h3>Plugin Status</h3><p>');
-    writePlugin(AnalysisEngine.instance.enginePlugin);
-    writePlugin(_server.serverPlugin);
-    for (Plugin plugin in _server.analysisServer.userDefinedPlugins) {
-      writePlugin(plugin);
-    }
-    buffer.write('<p>');
-  }
-
-  /**
-   * Write the recent output section (on the main status page) to the given
-   * [buffer] object.
-   */
-  void _writeRecentOutput(StringBuffer buffer) {
-    buffer.write('<h3>Recent Output</h3>');
-    String output = HTML_ESCAPE.convert(_printBuffer.join('\n'));
-    if (output.isEmpty) {
-      buffer.write('<i>none</i>');
-    } else {
-      buffer.write('<pre>');
-      buffer.write(output);
-      buffer.write('</pre>');
-    }
-  }
-
-  void _writeResponse(HttpRequest request, HtmlGenerator writePage) {
-    HttpResponse response = request.response;
-    response.statusCode = HttpStatus.OK;
-    response.headers.contentType = _htmlContent;
-    try {
-      StringBuffer buffer = new StringBuffer();
-      try {
-        writePage(buffer);
-      } catch (exception, stackTrace) {
-        buffer.clear();
-        _writePage(buffer, 'Internal Exception', [], (StringBuffer buffer) {
-          _writeException(buffer, new CaughtException(exception, stackTrace));
-        });
-      }
-      response.write(buffer.toString());
-    } finally {
-      response.close();
-    }
-  }
-
-  /**
-   * Write a single row within a table to the given [buffer]. The row will have
-   * one cell for each of the [columns], and will be a header row if [header] is
-   * `true`.
-   */
-  void _writeRow(StringBuffer buffer, List<Object> columns,
-      {bool header: false, List<String> classes}) {
-    buffer.write('<tr>');
-    int count = columns.length;
-    int maxClassIndex = classes == null ? 0 : classes.length - 1;
-    for (int i = 0; i < count; i++) {
-      String classAttribute = '';
-      if (classes != null) {
-        String className = classes[min(i, maxClassIndex)];
-        if (className != null) {
-          classAttribute = ' class="$className"';
-        }
-      }
-      if (header) {
-        buffer.write('<th$classAttribute>');
-      } else {
-        buffer.write('<td$classAttribute>');
-      }
-      buffer.write(columns[i]);
-      if (header) {
-        buffer.write('</th>');
-      } else {
-        buffer.write('</td>');
-      }
-    }
-    buffer.write('</tr>');
-  }
-
-  /**
-   * Write the status of the service domain (on the main status page) to the
-   * given [response] object.
-   */
-  bool _writeServerStatus(StringBuffer buffer) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    Set<ServerService> services = analysisServer.serverServices;
-
-    buffer.write('<h3>Server Domain</h3>');
-    _writeTwoColumns(buffer, (StringBuffer buffer) {
-      if (analysisServer == null) {
-        buffer.write('Status: <span style="color:red">Not running</span>');
-        return false;
-      }
-      buffer.write('<p>');
-      buffer.write('Status: Running<br>');
-      buffer.write('Instrumentation: ');
-      if (AnalysisEngine.instance.instrumentationService.isActive) {
-        buffer.write('<span style="color:red">Active</span>');
-      } else {
-        buffer.write('Inactive');
-      }
-      buffer.write('<br>');
-      buffer.write('Version: ');
-      buffer.write(AnalysisServer.VERSION);
-      buffer.write('</p>');
-
-      buffer.write('<p><b>Performance Data</b></p>');
-      buffer.write('<p>');
-      buffer.write(makeLink(
-          COMMUNICATION_PERFORMANCE_PATH, {}, 'Communication performance'));
-      buffer.write('</p>');
-    }, (StringBuffer buffer) {
-      _writeSubscriptionList(buffer, ServerService.VALUES, services);
-    });
-    return true;
-  }
-
-  /**
-   * Write a representation of the given [stackTrace] to the given [buffer].
-   */
-  void _writeStackTrace(StringBuffer buffer, StackTrace stackTrace) {
-    if (stackTrace != null) {
-      String trace = stackTrace.toString().replaceAll('#', '<br>#');
-      if (trace.startsWith('<br>#')) {
-        trace = trace.substring(4);
-      }
-      buffer.write('<p>');
-      buffer.write(trace);
-      buffer.write('</p>');
-    }
-  }
-
-  /**
-   * Given a [service] that could be subscribed to and a set of the services
-   * that are actually subscribed to ([subscribedServices]), write a
-   * representation of the service to the given [buffer].
-   */
-  void _writeSubscriptionInList(
-      StringBuffer buffer, Enum service, Set<Enum> subscribedServices) {
-    if (subscribedServices.contains(service)) {
-      buffer.write('<code>+ </code>');
-    } else {
-      buffer.write('<code>- </code>');
-    }
-    buffer.write(service.name);
-    buffer.write('<br>');
-  }
-
-  /**
-   * Given a [service] that could be subscribed to and a set of paths that are
-   * subscribed to the services ([subscribedPaths]), write a representation of
-   * the service to the given [buffer].
-   */
-  void _writeSubscriptionInMap(
-      StringBuffer buffer, Enum service, Set<String> subscribedPaths) {
-    buffer.write('<p>');
-    buffer.write(service.name);
-    buffer.write('</p>');
-    if (subscribedPaths == null || subscribedPaths.isEmpty) {
-      buffer.write('none');
-    } else {
-      List<String> paths = subscribedPaths.toList();
-      paths.sort();
-      for (String path in paths) {
-        buffer.write('<p>');
-        buffer.write(path);
-        buffer.write('</p>');
-      }
-    }
-  }
-
-  /**
-   * Given a list containing all of the services that can be subscribed to in a
-   * single domain ([allServices]) and a set of the services that are actually
-   * subscribed to ([subscribedServices]), write a representation of the
-   * subscriptions to the given [buffer].
-   */
-  void _writeSubscriptionList(StringBuffer buffer, List<Enum> allServices,
-      Set<Enum> subscribedServices) {
-    buffer.write('<p><b>Subscriptions</b></p>');
-    buffer.write('<p>');
-    for (Enum service in allServices) {
-      _writeSubscriptionInList(buffer, service, subscribedServices);
-    }
-    buffer.write('</p>');
-  }
-
-  /**
-   * Given a list containing all of the services that can be subscribed to in a
-   * single domain ([allServices]) and a set of the services that are actually
-   * subscribed to ([subscribedServices]), write a representation of the
-   * subscriptions to the given [buffer].
-   */
-  void _writeSubscriptionMap(StringBuffer buffer, List<Enum> allServices,
-      Map<Enum, Set<String>> subscribedServices) {
-    buffer.write('<p><b>Subscriptions</b></p>');
-    for (Enum service in allServices) {
-      _writeSubscriptionInMap(buffer, service, subscribedServices[service]);
-    }
-  }
-
-  /**
-   * Write two columns of information to the given [buffer], where the
-   * [leftColumn] and [rightColumn] functions are used to generate the content
-   * of those columns.
-   */
-  void _writeTwoColumns(StringBuffer buffer, HtmlGenerator leftColumn,
-      HtmlGenerator rightColumn) {
-    buffer
-        .write('<table class="column"><tr class="column"><td class="column">');
-    leftColumn(buffer);
-    buffer.write('</td><td class="column">');
-    rightColumn(buffer);
-    buffer.write('</td></tr></table>');
-  }
-
-  /**
-   * Render the given [value] as HTML and append it to the given [buffer]. The
-   * [linkParameters] will be used if the value is too large to be displayed on
-   * the current page and needs to be linked to a separate page.
-   */
-  void _writeValueAsHtml(
-      StringBuffer buffer, Object value, Map<String, String> linkParameters) {
-    if (value == null) {
-      buffer.write('<i>null</i>');
-    } else if (value is String) {
-      buffer.write('<pre>${HTML_ESCAPE.convert(value)}</pre>');
-    } else if (value is List) {
-      buffer.write('List containing ${value.length} entries');
-      buffer.write('<ul>');
-      for (var entry in value) {
-        buffer.write('<li>');
-        _writeValueAsHtml(buffer, entry, linkParameters);
-        buffer.write('</li>');
-      }
-      buffer.write('</ul>');
-    } else if (value is AstNode) {
-      String link =
-          makeLink(AST_PATH, linkParameters, value.runtimeType.toString());
-      buffer.write('<i>$link</i>');
-    } else if (value is Element) {
-      String link =
-          makeLink(ELEMENT_PATH, linkParameters, value.runtimeType.toString());
-      buffer.write('<i>$link</i>');
-    } else {
-      buffer.write(HTML_ESCAPE.convert(value.toString()));
-      buffer.write(' <i>(${value.runtimeType.toString()})</i>');
-    }
-  }
-
-  /**
-   * Create a link to [path] with query parameters [params], with inner HTML
-   * [innerHtml]. If [hasError] is `true`, then the link will have the class
-   * 'error'.
-   */
-  static String makeLink(
-      String path, Map<String, String> params, String innerHtml,
-      [bool hasError = false]) {
-    Uri uri = new Uri(path: path, queryParameters: params);
-    String href = HTML_ESCAPE.convert(uri.toString());
-    String classAttribute = hasError ? ' class="error"' : '';
-    return '<a href="$href"$classAttribute>$innerHtml</a>';
-  }
-}
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index aeb8d03..2267250 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -17,11 +17,10 @@
 import 'package:analysis_server/src/services/dependencies/library_dependencies.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -152,14 +151,18 @@
   });
 }
 
-void sendAnalysisNotificationErrors(AnalysisServer server, String file,
-    LineInfo lineInfo, List<AnalysisError> errors) {
+void sendAnalysisNotificationErrors(
+    AnalysisServer server,
+    AnalysisContext context,
+    String file,
+    LineInfo lineInfo,
+    List<AnalysisError> errors) {
   _sendNotification(server, () {
     if (errors == null) {
       errors = <AnalysisError>[];
     }
     var serverErrors =
-        protocol.doAnalysisError_listFromEngine(lineInfo, errors);
+        protocol.doAnalysisError_listFromEngine(context, lineInfo, errors);
     var params = new protocol.AnalysisErrorsParams(file, serverErrors);
     server.sendNotification(params.toNotification());
   });
@@ -347,7 +350,8 @@
     }
   }
 
-  bool get _isPriorityContext => context is InternalAnalysisContext &&
+  bool get _isPriorityContext =>
+      context is InternalAnalysisContext &&
       (context as InternalAnalysisContext).prioritySources.isNotEmpty;
 
   @override
@@ -422,16 +426,6 @@
         server.sendServerErrorNotification(
             'Failed to index Dart file: $file', exception, stackTrace);
       }
-      // HTML
-      try {
-        HtmlUnit htmlUnit = notice.resolvedHtmlUnit;
-        if (htmlUnit != null) {
-          server.addOperation(new _HtmlIndexOperation(context, file, htmlUnit));
-        }
-      } catch (exception, stackTrace) {
-        server.sendServerErrorNotification(
-            'Failed to index HTML file: $file', exception, stackTrace);
-      }
     }
   }
 }
@@ -510,24 +504,6 @@
   }
 }
 
-class _HtmlIndexOperation extends _SingleFileOperation {
-  final HtmlUnit unit;
-
-  _HtmlIndexOperation(AnalysisContext context, String file, this.unit)
-      : super(context, file);
-
-  @override
-  ServerOperationPriority get priority {
-    return ServerOperationPriority.ANALYSIS_INDEX;
-  }
-
-  @override
-  void perform(AnalysisServer server) {
-    Index index = server.index;
-    index.index(context, unit);
-  }
-}
-
 class _NotificationErrorsOperation extends _SingleFileOperation {
   final LineInfo lineInfo;
   final List<AnalysisError> errors;
@@ -543,7 +519,7 @@
 
   @override
   void perform(AnalysisServer server) {
-    sendAnalysisNotificationErrors(server, file, lineInfo, errors);
+    sendAnalysisNotificationErrors(server, context, file, lineInfo, errors);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/plugin/server_plugin.dart b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
index b4de83f..b35d5bd 100644
--- a/pkg/analysis_server/lib/src/plugin/server_plugin.dart
+++ b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
@@ -14,19 +14,19 @@
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
 import 'package:analysis_server/plugin/edit/fix/fix.dart';
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
-import 'package:analysis_server/plugin/index/index.dart';
-import 'package:analysis_server/plugin/index/index_core.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
 import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/domain_diagnostic.dart';
 import 'package:analysis_server/src/domain_execution.dart';
-import 'package:analysis_server/src/domain_experimental.dart';
 import 'package:analysis_server/src/domain_server.dart';
 import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
 import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/provisional/index/index.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 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';
@@ -189,8 +189,9 @@
    * Return a list containing all of the completion contributors that were
    * contributed.
    */
-  List<CompletionContributor> get completionContributors =>
-      completionContributorExtensionPoint.extensions;
+  Iterable<CompletionContributor> get completionContributors =>
+      completionContributorExtensionPoint.extensions
+          .map((CompletionContributorFactory factory) => factory());
 
   /**
    * Return a list containing all of the fix contributors that were contributed.
@@ -276,10 +277,10 @@
     // Register analyzed file patterns.
     //
     List<String> patterns = <String>[
-      '{*:/,/}**/*.${AnalysisEngine.SUFFIX_DART}',
-      '{*:/,/}**/*.${AnalysisEngine.SUFFIX_HTML}',
-      '{*:/,/}**/*.${AnalysisEngine.SUFFIX_HTM}',
-      '{*:/,/}**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}'
+      '**/*.${AnalysisEngine.SUFFIX_DART}',
+      '**/*.${AnalysisEngine.SUFFIX_HTML}',
+      '**/*.${AnalysisEngine.SUFFIX_HTM}',
+      '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}'
     ];
     registerExtension(ANALYZED_FILE_PATTERNS_EXTENSION_POINT_ID, patterns);
     //
@@ -291,7 +292,7 @@
     // Register completion contributors.
     //
     // TODO(brianwilkerson) Register the completion contributors.
-//    registerExtension(COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID, ???);
+    //registerExtension(COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID, ???);
     //
     // Register analysis contributors.
     //
@@ -316,7 +317,7 @@
     registerExtension(domainId,
         (AnalysisServer server) => new ExecutionDomainHandler(server));
     registerExtension(domainId,
-        (AnalysisServer server) => new ExperimentalDomainHandler(server));
+        (AnalysisServer server) => new DiagnosticDomainHandler(server));
     //
     // Register fix contributors.
     //
@@ -370,10 +371,10 @@
    * valid completion contributor.
    */
   void _validateCompletionContributorExtension(Object extension) {
-    if (extension is! CompletionContributor) {
+    if (extension is! CompletionContributorFactory) {
       String id = completionContributorExtensionPoint.uniqueIdentifier;
       throw new ExtensionError(
-          'Extensions to $id must be an CompletionContributor');
+          'Extensions to $id must be an CompletionContributorFactory');
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 678361f..822727c 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -9,8 +9,10 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart'
     as engine;
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/ast.dart' as engine;
-import 'package:analyzer/src/generated/element.dart' as engine;
 import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:analyzer/src/generated/error.dart' as engine;
 import 'package:analyzer/src/generated/source.dart' as engine;
@@ -20,14 +22,29 @@
 export 'package:analysis_server/plugin/protocol/protocol_dart.dart';
 
 /**
- * Returns a list of AnalysisErrors correponding to the given list of Engine
+ * Returns a list of AnalysisErrors corresponding to the given list of Engine
  * errors.
  */
 List<AnalysisError> doAnalysisError_listFromEngine(
-    engine.LineInfo lineInfo, List<engine.AnalysisError> errors) {
-  return errors.map((engine.AnalysisError error) {
-    return newAnalysisError_fromEngine(lineInfo, error);
-  }).toList();
+    engine.AnalysisContext context,
+    engine.LineInfo lineInfo,
+    List<engine.AnalysisError> errors) {
+  List<AnalysisError> serverErrors = <AnalysisError>[];
+  for (engine.AnalysisError error in errors) {
+    ErrorProcessor processor = ErrorProcessor.getProcessor(context, error);
+    if (processor != null) {
+      engine.ErrorSeverity severity = processor.severity;
+      // Errors with null severity are filtered out.
+      if (severity != null) {
+        // Specified severities override.
+        serverErrors
+            .add(newAnalysisError_fromEngine(lineInfo, error, severity));
+      }
+    } else {
+      serverErrors.add(newAnalysisError_fromEngine(lineInfo, error));
+    }
+  }
+  return serverErrors;
 }
 
 /**
@@ -55,7 +72,7 @@
     if (element.kind == engine.ElementKind.SETTER) {
       return null;
     } else {
-      return element.returnType.toString();
+      return element.returnType?.toString();
     }
   } else if (element is engine.VariableElement) {
     engine.DartType type = element.type;
@@ -69,9 +86,12 @@
 
 /**
  * Construct based on error information from the analyzer engine.
+ *
+ * If an [errorSeverity] is specified, it will override the one in [error].
  */
 AnalysisError newAnalysisError_fromEngine(
-    engine.LineInfo lineInfo, engine.AnalysisError error) {
+    engine.LineInfo lineInfo, engine.AnalysisError error,
+    [engine.ErrorSeverity errorSeverity]) {
   engine.ErrorCode errorCode = error.errorCode;
   // prepare location
   Location location;
@@ -90,8 +110,12 @@
     }
     location = new Location(file, offset, length, startLine, startColumn);
   }
+
+  // Deafult to the error's severity if none is specified.
+  errorSeverity ??= errorCode.errorSeverity;
+
   // done
-  var severity = new AnalysisErrorSeverity(errorCode.errorSeverity.name);
+  var severity = new AnalysisErrorSeverity(errorSeverity.name);
   var type = new AnalysisErrorType(errorCode.type.name);
   String message = error.message;
   String correction = error.correction;
diff --git a/pkg/analysis_server/lib/src/provisional/completion/completion.dart b/pkg/analysis_server/lib/src/provisional/completion/completion.dart
index 9a71bc0..68eb362 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/completion.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/completion.dart
@@ -6,12 +6,13 @@
  * Support for client code that extends the analysis server by adding new code
  * completion contributors.
  *
- * Plugins can register completion contributors. The registered contributors
- * will be used to get completions any time a client issues a
- * 'completion.getSuggestions' request.
+ * Plugins can register completion contributor factories.
+ * The registered contributor factories will be used to instantiate new
+ * contributors to get completions any time a client issues
+ * a 'completion.getSuggestions' request.
  *
- * If a plugin wants to add completions, it should implement the class
- * [CompletionContributor] and then register the contributor by including code
+ * If a plugin wants to add completions, it should implement
+ * [CompletionContributorFactory] by including code
  * like the following in the plugin's registerExtensions method:
  *
  *     @override
@@ -19,20 +20,19 @@
  *       ...
  *       registerExtension(
  *           COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
- *           new MyCompletionContributor());
+ *           () => new MyCompletionContributor());
  *       ...
  *     }
  */
-library analysis_server.src.provisional.completion.completion;
+library analysis_server.src.provisional.completion.core;
 
 import 'package:analysis_server/src/plugin/server_plugin.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart';
 import 'package:plugin/plugin.dart';
 
 /**
  * The identifier of the extension point that allows plugins to register code
  * completion contributors. The object used as an extension must be a
- * [CompletionContributor].
+ * [CompletionContributorFactory].
  */
 final String COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID = Plugin.join(
     ServerPlugin.UNIQUE_IDENTIFIER,
diff --git a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart b/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
index 75f830b..9a585dd 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
@@ -4,24 +4,39 @@
 
 library analysis_server.src.provisional.completion.completion_core;
 
+import 'dart:async';
+
 import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/source.dart';
 
 /**
- * An object used to produce completions for a specific error. Completion
- * contributors are long-lived objects and must not retain any state between
- * invocations of [computeSuggestions].
+ * An empty list returned by [CompletionContributor]s
+ * when they have no suggestions to contribute.
+ */
+const EMPTY_LIST = const <CompletionSuggestion>[];
+
+/**
+ * An object used to instantiate a [CompletionContributor] instance
+ * for each 'completion.getSuggestions' request.
+ * Contributors should *not* be cached between requests.
+ */
+typedef CompletionContributor CompletionContributorFactory();
+
+/**
+ * An object used to produce completions at a specific location within a file.
  *
  * Clients may implement this class when implementing plugins.
  */
 abstract class CompletionContributor {
   /**
-   * Compute a list of completion suggestions based on the given completion
-   * [request]. Return the suggestions that were computed.
+   * Return a [Future] that completes with a list of suggestions
+   * for the given completion [request].
    */
-  List<CompletionSuggestion> computeSuggestions(CompletionRequest request);
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      CompletionRequest request);
 }
 
 /**
@@ -47,38 +62,12 @@
   ResourceProvider get resourceProvider;
 
   /**
+   * Return the search engine.
+   */
+  SearchEngine get searchEngine;
+
+  /**
    * Return the source in which the completion is being requested.
    */
   Source get source;
 }
-
-/**
- * The result of computing suggestions for code completion.
- *
- * Clients may implement this class when implementing plugins.
- */
-abstract class CompletionResult {
-  /**
-   * Return the length of the text to be replaced. This will be zero (0) if the
-   * suggestion is to be inserted, otherwise it will be greater than zero. For
-   * example, if the remainder of the identifier containing the cursor is to be
-   * replaced when the suggestion is applied, in which case the length will be
-   * the number of characters in the existing identifier.
-   */
-  int get replacementLength;
-
-  /**
-   * Return the offset of the start of the text to be replaced. This will be
-   * different than the offset used to request the completion suggestions if
-   * there was a portion of text that needs to be replaced. For example, if a
-   * partial identifier is immediately before the original offset, in which case
-   * the replacementOffset will be the offset of the beginning of the
-   * identifier.
-   */
-  int get replacementOffset;
-
-  /**
-   * Return the list of suggestions being contributed by the contributor.
-   */
-  List<CompletionSuggestion> get suggestions;
-}
diff --git a/pkg/analysis_server/lib/src/provisional/completion/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/completion_dart.dart
deleted file mode 100644
index e52c433..0000000
--- a/pkg/analysis_server/lib/src/provisional/completion/completion_dart.dart
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analysis_server.src.provisional.completion.completion_dart;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart';
-import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * An object used to produce completions for a specific error within a Dart
- * file. Completion contributors are long-lived objects and must not retain any
- * state between invocations of [computeSuggestions].
- *
- * Clients may extend this class when implementing plugins.
- */
-abstract class DartCompletionContributor implements CompletionContributor {
-  @override
-  List<CompletionSuggestion> computeSuggestions(CompletionRequest request) {
-    if (request is DartCompletionRequest) {
-      return internalComputeSuggestions(request);
-    }
-    AnalysisContext context = request.context;
-    Source source = request.source;
-    List<Source> libraries = context.getLibrariesContaining(source);
-    if (libraries.length < 1) {
-      return null;
-    }
-//    CompilationUnit unit =
-//        context.getResolvedCompilationUnit2(source, libraries[0]);
-//    bool isResolved = true;
-//    if (unit == null) {
-//      // TODO(brianwilkerson) Implement a method for getting a parsed
-//      // compilation unit without parsing the unit if it hasn't been parsed.
-//      unit = context.getParsedCompilationUnit(source);
-//      if (unit == null) {
-//        return null;
-//      }
-//      isResolved = false;
-//    }
-//    DartCompletionRequest dartRequest =
-//        new DartCompletionRequestImpl(request, unit, isResolved);
-//    return internalComputeSuggestions(dartRequest);
-    return null;
-  }
-
-  /**
-   * Compute a list of completion suggestions based on the given completion
-   * [request]. Return the suggestions that were computed.
-   */
-  List<CompletionSuggestion> internalComputeSuggestions(
-      DartCompletionRequest request);
-}
-
-/**
- * The information about a requested list of completions within a Dart file.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DartCompletionRequest extends CompletionRequest {
-  /**
-   * Return `true` if the compilation [unit] is resolved.
-   */
-  bool get isResolved;
-
-  /**
-   * Return the completion target.  This determines what part of the parse tree
-   * will receive the newly inserted text.
-   */
-  CompletionTarget get target;
-
-  /**
-   * Cached information from a prior code completion operation.
-   */
-  //DartCompletionCache get cache;
-
-  /**
-   * Return the compilation unit in which the completion was requested.
-   */
-  CompilationUnit get unit;
-
-  /**
-   * Information about the types of suggestions that should be included.
-   */
-  //OpType get _optype;
-}
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion.dart
new file mode 100644
index 0000000..4d6601d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Support for client code that extends the analysis server by adding new
+ * Dart specific completion contributors.
+ *
+ * Plugins can register Dart specific completion contributor factories.
+ * The registered contributor factories will be used to instantiate new
+ * contributors to get completions any time a client issues
+ * a 'completion.getSuggestions' request.
+ *
+ * If a plugin wants to add completions, it should implement
+ * [DartCompletionContributorFactory] by including code
+ * like the following in the plugin's registerExtensions method:
+ *
+ *     @override
+ *     void registerExtensions(RegisterExtension registerExtension) {
+ *       ...
+ *       registerExtension(
+ *           DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+ *           () => new MyDartCompletionContributor());
+ *       ...
+ *     }
+ */
+library analysis_server.src.provisional.completion.dart;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_plugin.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * The identifier of the extension point that allows plugins to register code
+ * completion contributors. The object used as an extension must be a
+ * [DartCompletionContributorFactory].
+ */
+final String DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID = Plugin.join(
+    DartCompletionPlugin.UNIQUE_IDENTIFIER,
+    DartCompletionPlugin.CONTRIBUTOR_EXTENSION_POINT);
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
new file mode 100644
index 0000000..c6a9a74
--- /dev/null
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
@@ -0,0 +1,128 @@
+// 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 analysis_server.src.provisional.completion.completion_dart;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+export 'package:analysis_server/src/provisional/completion/completion_core.dart'
+    show EMPTY_LIST;
+
+const int DART_RELEVANCE_COMMON_USAGE = 1200;
+const int DART_RELEVANCE_DEFAULT = 1000;
+const int DART_RELEVANCE_HIGH = 2000;
+const int DART_RELEVANCE_INHERITED_ACCESSOR = 1057;
+const int DART_RELEVANCE_INHERITED_FIELD = 1058;
+const int DART_RELEVANCE_INHERITED_METHOD = 1057;
+const int DART_RELEVANCE_KEYWORD = 1055;
+const int DART_RELEVANCE_LOCAL_ACCESSOR = 1057;
+const int DART_RELEVANCE_LOCAL_FIELD = 1058;
+const int DART_RELEVANCE_LOCAL_FUNCTION = 1056;
+const int DART_RELEVANCE_LOCAL_METHOD = 1057;
+const int DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE = 1056;
+const int DART_RELEVANCE_LOCAL_VARIABLE = 1059;
+const int DART_RELEVANCE_LOW = 500;
+const int DART_RELEVANCE_NAMED_PARAMETER = 1060;
+const int DART_RELEVANCE_PARAMETER = 1059;
+
+/**
+ * An object used to instantiate a [DartCompletionContributor] instance
+ * for each 'completion.getSuggestions' request.
+ * Contributors should *not* be cached between requests.
+ */
+typedef DartCompletionContributor DartCompletionContributorFactory();
+
+/**
+ * An object used to produce completions
+ * at a specific location within a Dart file.
+ *
+ * Clients may implement this class when implementing plugins.
+ */
+abstract class DartCompletionContributor {
+  /**
+   * Return a [Future] that completes with a list of suggestions
+   * for the given completion [request].
+   */
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request);
+}
+
+/**
+ * The information about a requested list of completions within a Dart file.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DartCompletionRequest extends CompletionRequest {
+  /**
+   * Return the dart:core library element
+   */
+  LibraryElement get coreLib;
+
+  /**
+   * Return the expression to the right of the "dot" or "dot dot",
+   * or `null` if this is not a "dot" completion (e.g. `foo.b`).
+   */
+  Expression get dotTarget;
+
+  /**
+   * Return `true` if free standing identifiers should be suggested
+   */
+  bool get includeIdentifiers;
+
+  /**
+   * Return the library element which contains the unit in which the completion
+   * is occurring. This may return `null` if the library cannot be determined
+   * (e.g. unlinked part file).
+   */
+  LibraryElement get libraryElement;
+
+  /**
+   * The source for the library containing the completion request.
+   * This may be different from the source in which the completion is requested
+   * if the completion is being requested in a part file.
+   * This may be `null` if the library for a part file cannot be determined.
+   */
+  Source get librarySource;
+
+  /**
+   * Answer the [DartType] for Object in dart:core
+   */
+  DartType get objectType;
+
+  /**
+   * Return the completion target.  This determines what part of the parse tree
+   * will receive the newly inserted text.
+   * At a minimum, all declarations in the completion scope in [target.unit]
+   * will be resolved if they can be resolved.
+   */
+  CompletionTarget get target;
+
+  /**
+   * Return a [Future] that completes with a list of directives for the library
+   * in which in which the completion is occurring.
+   * The [Future] may return `null` if the library unit cannot be determined
+   * (e.g. unlinked part file).
+   * Any information obtained from [target] prior to calling this method
+   * should be discarded as it may have changed.
+   */
+  Future<List<Directive>> resolveDirectives();
+
+  /**
+   * Return a [Future] that completes when the element associated with
+   * the given [expression] in the target compilation unit is available.
+   * It may also complete if the expression cannot be resolved
+   * (e.g. unknown identifier, completion aborted, etc).
+   * Any information obtained from [target] prior to calling this method
+   * should be discarded as it may have changed.
+   */
+  Future resolveExpression(Expression expression);
+}
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
new file mode 100644
index 0000000..f1a8a05
--- /dev/null
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
@@ -0,0 +1,131 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analysis_server.src.provisional.completion.dart.plugin;
+
+import 'package:analysis_server/src/provisional/completion/completion.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/combinator_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/label_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/local_constructor_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * The shared dart completion plugin instance.
+ */
+final DartCompletionPlugin dartCompletionPlugin = new DartCompletionPlugin();
+
+class DartCompletionPlugin implements Plugin {
+  /**
+   * The simple identifier of the extension point that allows plugins to
+   * register Dart specific completion contributor factories.
+   * Use [DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID]
+   * when registering contributors.
+   */
+  static const String CONTRIBUTOR_EXTENSION_POINT = 'contributor';
+
+  /**
+   * The unique identifier of this plugin.
+   */
+  static const String UNIQUE_IDENTIFIER = 'dart.completion';
+
+  /**
+   * The extension point that allows plugins to register Dart specific
+   * completion contributor factories.
+   */
+  ExtensionPoint _contributorExtensionPoint;
+
+  @override
+  String get uniqueIdentifier => UNIQUE_IDENTIFIER;
+
+  /**
+   * Return a list containing all of the Dart specific completion contributors.
+   */
+  Iterable<DartCompletionContributorFactory> get contributors =>
+      _contributorExtensionPoint.extensions
+          .map((DartCompletionContributorFactory factory) => factory());
+
+  @override
+  void registerExtensionPoints(RegisterExtensionPoint registerExtensionPoint) {
+    _contributorExtensionPoint = registerExtensionPoint(
+        CONTRIBUTOR_EXTENSION_POINT,
+        _validateDartCompletionContributorExtension);
+  }
+
+  @override
+  void registerExtensions(RegisterExtension registerExtension) {
+    //
+    // Register DartCompletionManager as a CompletionContributor
+    // which delegates to all the DartCompletionContributors
+    //
+    registerExtension(COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new DartCompletionManager());
+    //
+    // Register the default DartCompletionContributors
+    //
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new ArgListContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new CombinatorContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new FieldFormalContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new ImportedReferenceContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new InheritedReferenceContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new KeywordContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LabelContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LibraryMemberContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LibraryPrefixContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LocalConstructorContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LocalLibraryContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LocalReferenceContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new NamedConstructorContributor());
+    // Revisit this contributor and these tests
+    // once DartChangeBuilder API has solidified.
+    // registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+    //     () => new OverrideContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new StaticMemberContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new TypeMemberContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new UriContributor());
+  }
+
+  /**
+   * Validate the given extension by throwing an [ExtensionError] if it is not a
+   * valid Dart specific completion contributor.
+   */
+  void _validateDartCompletionContributorExtension(Object extension) {
+    if (extension is! DartCompletionContributorFactory) {
+      String id = _contributorExtensionPoint.uniqueIdentifier;
+      throw new ExtensionError(
+          'Extensions to $id must be a DartCompletionContributorFactory');
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
index e94016a..c04ce43 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
@@ -4,8 +4,9 @@
 
 library analysis_server.src.provisional.completion.dart.completion_target;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
@@ -86,6 +87,16 @@
  */
 class CompletionTarget {
   /**
+   * The compilation unit in which the completion is occurring.
+   */
+  final CompilationUnit unit;
+
+  /**
+   * The offset within the source at which the completion is being requested.
+   */
+  final int offset;
+
+  /**
    * The context in which the completion is occurring.  This is the AST node
    * which is a direct parent of [entity].
    */
@@ -156,10 +167,12 @@
             // Try to replace with a comment token.
             Token commentToken = _getContainingCommentToken(entity, offset);
             if (commentToken != null) {
-              return new CompletionTarget._(containingNode, commentToken, true);
+              return new CompletionTarget._(
+                  compilationUnit, offset, containingNode, commentToken, true);
             }
             // Target found.
-            return new CompletionTarget._(containingNode, entity, false);
+            return new CompletionTarget._(
+                compilationUnit, offset, containingNode, entity, false);
           } else {
             // Since entity is a token, we don't need to look inside it; just
             // proceed to the next entity.
@@ -188,11 +201,12 @@
               if (docComment != null) {
                 containingNode = docComment;
               } else {
-                return new CompletionTarget._(
+                return new CompletionTarget._(compilationUnit, offset,
                     compilationUnit, commentToken, true);
               }
             }
-            return new CompletionTarget._(containingNode, entity, false);
+            return new CompletionTarget._(
+                compilationUnit, offset, containingNode, entity, false);
           }
 
           // Otherwise, the completion target is somewhere inside the entity,
@@ -216,7 +230,8 @@
 
       // Since no completion target was found, we set the completion target
       // entity to null and use the compilationUnit as the parent.
-      return new CompletionTarget._(compilationUnit, null, false);
+      return new CompletionTarget._(
+          compilationUnit, offset, compilationUnit, null, false);
     }
   }
 
@@ -224,24 +239,39 @@
    * Create a [CompletionTarget] holding the given [containingNode] and
    * [entity].
    */
-  CompletionTarget._(AstNode containingNode, Object entity, this.isCommentText)
+  CompletionTarget._(this.unit, this.offset, AstNode containingNode,
+      Object entity, this.isCommentText)
       : this.containingNode = containingNode,
         this.entity = entity,
         this.argIndex = _computeArgIndex(containingNode, entity);
 
   /**
+   * Return `true` if the [containingNode] is a cascade
+   * and the completion insertion is not between the two dots.
+   * For example, `..d^` and `..^d` are considered a cascade
+   * from a completion standpoint, but `.^.d` is not.
+   */
+  bool get isCascade {
+    AstNode node = containingNode;
+    if (node is PropertyAccess) {
+      return node.isCascaded && offset > node.operator.offset + 1;
+    }
+    if (node is MethodInvocation) {
+      return node.isCascaded && offset > node.operator.offset + 1;
+    }
+    return false;
+  }
+
+  /**
    * Return `true` if the target is a functional argument in an argument list.
    * The target [AstNode] hierarchy *must* be resolved for this to work.
+   * See [maybeFunctionalArgument].
    */
   bool isFunctionalArgument() {
-    if (argIndex == null) {
+    if (!maybeFunctionalArgument()) {
       return false;
     }
-    AstNode argList = containingNode;
-    if (argList is! ArgumentList) {
-      return false;
-    }
-    AstNode parent = argList.parent;
+    AstNode parent = containingNode.parent;
     if (parent is InstanceCreationExpression) {
       DartType instType = parent.bestType;
       if (instType != null) {
@@ -270,6 +300,22 @@
   }
 
   /**
+   * Return `true` if the target maybe a functional argument in an argument list.
+   * This is used in determining whether the target [AstNode] hierarchy
+   * needs to be resolved so that [isFunctionalArgument] will work.
+   */
+  bool maybeFunctionalArgument() {
+    if (argIndex == null) {
+      return false;
+    }
+    AstNode argList = containingNode;
+    if (argList is! ArgumentList) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
    * Determine if the offset is contained in a preceding comment token
    * and return that token, otherwise return `null`.
    */
diff --git a/pkg/analysis_server/lib/plugin/edit/utilities/change_builder_core.dart b/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_core.dart
similarity index 100%
rename from pkg/analysis_server/lib/plugin/edit/utilities/change_builder_core.dart
rename to pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_core.dart
diff --git a/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart b/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart
new file mode 100644
index 0000000..bdc0931
--- /dev/null
+++ b/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart
@@ -0,0 +1,157 @@
+// 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 analysis_server.plugin.edit.utilities.change_builder_dart;
+
+import 'package:analysis_server/src/provisional/edit/utilities/change_builder_core.dart';
+import 'package:analysis_server/src/utilities/change_builder_dart.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+
+/**
+ * A [ChangeBuilder] used to build changes in Dart files.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DartChangeBuilder extends ChangeBuilder {
+  /**
+   * Initialize a newly created change builder.
+   */
+  factory DartChangeBuilder(AnalysisContext context) = DartChangeBuilderImpl;
+}
+
+/**
+ * An [EditBuilder] used to build edits in Dart files.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DartEditBuilder extends EditBuilder {
+  /**
+   * The group-id used for the name of a declaration.
+   */
+  static const String NAME_GROUP_ID = 'NAME';
+
+  /**
+   * The group-id used for the return type of a function, getter or method.
+   */
+  static const String RETURN_TYPE_GROUP_ID = 'RETURN_TYPE';
+
+  /**
+   * The group-id used for the name of the superclass in a class declaration.
+   */
+  static const String SUPERCLASS_GROUP_ID = 'SUPERCLASS';
+
+  /**
+   * Write the code for a declaration of a class with the given [name]. If a
+   * list of [interfaces] is provided, then the class will implement those
+   * interfaces. If [isAbstract] is `true`, then the class will be abstract. If
+   * a [memberWriter] is provided, then it will be invoked to allow members to
+   * be generated. (The members will automatically be preceeded and followed by
+   * end-of-line markers.) If a list of [mixins] is provided, then the class
+   * will mix in those classes. If a [nameGroupName] is provided, then the name
+   * of the class will be included in the linked edit group with that name. If a
+   * [superclass] is given then it will be the superclass of the class. (If a
+   * list of [mixins] is provided but no [superclass] is given then the class
+   * will extend `Object`.)
+   */
+  void writeClassDeclaration(String name,
+      {Iterable<DartType> interfaces,
+      bool isAbstract: false,
+      void memberWriter(),
+      Iterable<DartType> mixins,
+      String nameGroupName,
+      DartType superclass});
+
+  /**
+   * Write the code for a declaration of a field with the given [name]. If an
+   * [initializerWriter] is provided, it will be invoked to write the content of
+   * the initializer. (The equal sign separating the field name from the
+   * initializer expression will automatically be written.) If [isConst] is
+   * `true`, then the declaration will be preceeded by the `const` keyword. If
+   * [isFinal] is `true`, then the declaration will be preceeded by the `final`
+   * keyword. (If both [isConst] and [isFinal] are `true`, then only the `const`
+   * keyword will be written.) If [isStatic] is `true`, then the declaration
+   * will be preceeded by the `static` keyword. If a [nameGroupName] is
+   * provided, the name of the field will be included in the linked edit group
+   * with that name. If a [type] is provided, then it will be used as the type
+   * of the field. (The keyword `var` will be provided automatically when
+   * required.) If a [typeGroupName] is provided, then if a type was written
+   * it will be in the linked edit group with that name.
+   */
+  void writeFieldDeclaration(String name,
+      {void initializerWriter(),
+      bool isConst: false,
+      bool isFinal: false,
+      bool isStatic: false,
+      String nameGroupName,
+      DartType type,
+      String typeGroupName});
+
+  /**
+   * Write the code for a declaration of a getter with the given [name]. If a
+   * [bodyWriter] is provided, it will be invoked to write the body of the
+   * getter. (The space between the name and the body will automatically be
+   * written.) If [isStatic] is `true`, then the declaration will be preceeded
+   * by the `static` keyword. If a [nameGroupName] is provided, the name of the
+   * getter will be included in the linked edit group with that name. If a
+   * [returnType] is provided, then it will be used as the return type of the
+   * getter. If a [returnTypeGroupName] is provided, then if a return type was
+   * written it will be in the linked edit group with that name.
+   */
+  void writeGetterDeclaration(String name,
+      {void bodyWriter(),
+      bool isStatic: false,
+      String nameGroupName,
+      DartType returnType,
+      String returnTypeGroupName});
+
+  /**
+   * Append a placeholder for an override of the specified inherited [member].
+   */
+  void writeOverrideOfInheritedMember(ExecutableElement member);
+
+  /**
+   * Write the code for a list of [parameters], including the surrounding
+   * parentheses.
+   */
+  void writeParameters(Iterable<ParameterElement> parameters);
+
+  /**
+   * Write the code for a list of parameters that would match the given list of
+   * [arguments], including the surrounding parentheses.
+   */
+  void writeParametersMatchingArguments(ArgumentList arguments);
+
+  /**
+   * Write the code for a single parameter with the given [type] and [name].
+   * The [type] can be `null` if no type is to be specified for the parameter.
+   */
+  void writeParameterSource(DartType type, String name);
+
+  /**
+   * Write the code for a type annotation for the given [type]. If the [type] is
+   * either `null` or represents the type 'dynamic', then the behavior depends
+   * on whether a type is [required]. If [required] is `true`, then 'var' will
+   * be written; otherwise, nothing is written.
+   *
+   * If the [groupName] is not `null`, then the name of the type (including type
+   * parameters) will be included as a region in the linked edit group with that
+   * name. If the [groupName] is not `null` and [addSupertypeProposals] is
+   * `true`, then all of the supertypes of the [type] will be added as
+   * suggestions for alternatives to the type name.
+   */
+  bool writeType(DartType type,
+      {bool addSupertypeProposals: false,
+      String groupName,
+      bool required: false});
+}
+
+/**
+ * A [FileEditBuilder] used to build edits for Dart files.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DartFileEditBuilder extends FileEditBuilder {}
diff --git a/pkg/analysis_server/lib/src/provisional/index/index.dart b/pkg/analysis_server/lib/src/provisional/index/index.dart
new file mode 100644
index 0000000..c67feb2
--- /dev/null
+++ b/pkg/analysis_server/lib/src/provisional/index/index.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Support for client code that extends the analysis server by adding new index
+ * contributors.
+ *
+ * Plugins can register index contributors. The registered contributors will be
+ * used to contribute relationships to the index when the analysis of a file has
+ * been completed.
+ *
+ * Typical relationships include things like "this variable is referenced here"
+ * or "this method is invoked here". The index is used to improve the
+ * performance of operations such as search or building a type hierarchy by
+ * pre-computing some of the information needed by those operations.
+ *
+ * If a plugin wants to contribute information to the index, it should implement
+ * the class [IndexContributor] and then register the contributor by including
+ * code like the following in the plugin's registerExtensions method:
+ *
+ *     @override
+ *     void registerExtensions(RegisterExtension registerExtension) {
+ *       ...
+ *       registerExtension(
+ *           INDEX_CONTRIBUTOR_EXTENSION_POINT_ID,
+ *           new MyIndexContributor());
+ *       ...
+ *     }
+ */
+library analysis_server.plugin.index.index;
+
+import 'package:analysis_server/src/plugin/server_plugin.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * 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,
+    ServerPlugin.INDEX_CONTRIBUTOR_EXTENSION_POINT);
diff --git a/pkg/analysis_server/lib/plugin/index/index_core.dart b/pkg/analysis_server/lib/src/provisional/index/index_core.dart
similarity index 100%
rename from pkg/analysis_server/lib/plugin/index/index_core.dart
rename to pkg/analysis_server/lib/src/provisional/index/index_core.dart
diff --git a/pkg/analysis_server/lib/src/provisional/refactoring/refactoring_core.dart b/pkg/analysis_server/lib/src/provisional/refactoring/refactoring_core.dart
index 086ce71..f865bb5 100644
--- a/pkg/analysis_server/lib/src/provisional/refactoring/refactoring_core.dart
+++ b/pkg/analysis_server/lib/src/provisional/refactoring/refactoring_core.dart
@@ -88,7 +88,9 @@
  */
 abstract class RefactoringKind {
   factory RefactoringKind(String name, bool requiresOptions) {
-  } // TODO(brianwilkerson) Redirect to impl class.
+    // TODO(brianwilkerson) Redirect to impl class.
+    return null;
+  }
   bool get requiresOptions;
 }
 
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index d470afe..112db5d 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -11,7 +11,7 @@
     show SearchResult, newSearchResult_fromMatch;
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index c0650e0..c60d4a5 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -6,17 +6,17 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/plugin/index/index_core.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/search/element_references.dart';
 import 'package:analysis_server/src/search/type_hierarchy.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/indexable_file.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 /**
  * Instances of the class [SearchDomainHandler] implement a [RequestHandler]
@@ -178,8 +178,9 @@
       TypeHierarchyComputer computer =
           new TypeHierarchyComputer(searchEngine, element);
       List<protocol.TypeHierarchyItem> items = computer.computeSuper();
-      protocol.Response response = new protocol.SearchGetTypeHierarchyResult(
-          hierarchyItems: items).toResponse(request.id);
+      protocol.Response response =
+          new protocol.SearchGetTypeHierarchyResult(hierarchyItems: items)
+              .toResponse(request.id);
       server.sendResponse(response);
       return;
     }
@@ -187,8 +188,9 @@
     TypeHierarchyComputer computer =
         new TypeHierarchyComputer(searchEngine, element);
     List<protocol.TypeHierarchyItem> items = await computer.compute();
-    protocol.Response response = new protocol.SearchGetTypeHierarchyResult(
-        hierarchyItems: items).toResponse(request.id);
+    protocol.Response response =
+        new protocol.SearchGetTypeHierarchyResult(hierarchyItems: items)
+            .toResponse(request.id);
     server.sendResponse(response);
   }
 
diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
index 0a666f3..793e471 100644
--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
@@ -11,7 +11,8 @@
     show TypeHierarchyItem, convertElement;
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 
 /**
  * A computer for a type hierarchy of an [Element].
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index f00f452..5833af4 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -12,6 +12,7 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/plugin/linter_plugin.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_plugin.dart';
 import 'package:analysis_server/src/server/http_server.dart';
 import 'package:analysis_server/src/server/stdio_server.dart';
 import 'package:analysis_server/src/socket_server.dart';
@@ -26,6 +27,7 @@
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:args/args.dart';
 import 'package:linter/src/plugin/linter_plugin.dart';
+import 'package:plugin/manager.dart';
 import 'package:plugin/plugin.dart';
 
 /**
@@ -207,11 +209,6 @@
   static const String CLIENT_VERSION = "client-version";
 
   /**
-   * The name of the option used to disable the use of the new task model.
-   */
-  static const String DISABLE_NEW_TASK_MODEL = "disable-new-task-model";
-
-  /**
    * The name of the option used to enable incremental resolution of API
    * changes.
    */
@@ -383,6 +380,7 @@
     //
     String logFilePath = results[INSTRUMENTATION_LOG_FILE];
     if (logFilePath != null) {
+      _rollLogFiles(logFilePath, 5);
       FileInstrumentationServer fileBasedServer =
           new FileInstrumentationServer(logFilePath);
       instrumentationServer = instrumentationServer != null
@@ -396,24 +394,21 @@
         results[CLIENT_VERSION], AnalysisServer.VERSION, defaultSdk.sdkVersion);
     AnalysisEngine.instance.instrumentationService = service;
     //
-    // Enable the new task model, if appropriate.
-    //
-    AnalysisEngine.instance.useTaskModel = !results[DISABLE_NEW_TASK_MODEL];
-    //
     // Process all of the plugins so that extensions are registered.
     //
     ServerPlugin serverPlugin = new ServerPlugin();
     List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
     plugins.add(serverPlugin);
-    plugins.addAll(_userDefinedPlugins);
     plugins.add(linterPlugin);
     plugins.add(linterServerPlugin);
+    plugins.add(dartCompletionPlugin);
+    plugins.addAll(_userDefinedPlugins);
 
-    // Defer to the extension manager in AE for plugin registration.
-    AnalysisEngine.instance.userDefinedPlugins = plugins;
-    // Force registration.
-    AnalysisEngine.instance.taskManager;
-
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
     //
     // Create the sockets and start listening for requests.
     //
@@ -428,11 +423,11 @@
     }
 
     _captureExceptions(service, () {
-      stdioServer.serveStdio().then((_) {
+      stdioServer.serveStdio().then((_) async {
         if (serve_http) {
           httpServer.close();
         }
-        service.shutdown();
+        await service.shutdown();
         exit(0);
       });
     },
@@ -477,11 +472,6 @@
     parser.addOption(CLIENT_ID,
         help: "an identifier used to identify the client");
     parser.addOption(CLIENT_VERSION, help: "the version of the client");
-    parser.addFlag(DISABLE_NEW_TASK_MODEL,
-        help: "disable the use of the new task model",
-        defaultsTo: false,
-        hide: true,
-        negatable: false);
     parser.addFlag(ENABLE_INCREMENTAL_RESOLUTION_API,
         help: "enable using incremental resolution for API changes",
         defaultsTo: false,
@@ -578,4 +568,20 @@
     }
     return uuid;
   }
+
+  /**
+   * Perform log files rolling.
+   *
+   * Rename existing files with names `[path].(x)` to `[path].(x+1)`.
+   * Keep at most [numOld] files.
+   * Rename the file with the given [path] to `[path].1`.
+   */
+  static void _rollLogFiles(String path, int numOld) {
+    for (int i = numOld - 1; i >= 0; i--) {
+      try {
+        String oldPath = i == 0 ? path : '$path.$i';
+        new File(oldPath).renameSync('$path.${i+1}');
+      } catch (e) {}
+    }
+  }
 }
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index c047d1f..85aabea 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -2,16 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library http.server;
+library analysis_server.src.server.http_server;
 
 import 'dart:async';
 import 'dart:io';
 
 import 'package:analysis_server/src/channel/web_socket_channel.dart';
-import 'package:analysis_server/src/get_handler.dart';
 import 'package:analysis_server/src/socket_server.dart';
-import 'package:analysis_server/src/status/get_handler.dart' as newHandler;
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
 
 /**
  * Instances of the class [HttpServer] implement a simple HTTP server. The
@@ -36,11 +34,6 @@
   GetHandler getHandler;
 
   /**
-   * An object that can handle GET requests when the new task model is in use.
-   */
-  newHandler.GetHandler newGetHandler;
-
-  /**
    * Future that is completed with the HTTP server once it is running.
    */
   Future<HttpServer> _server;
@@ -76,37 +69,25 @@
    * Begin serving HTTP requests over the given port.
    */
   void serveHttp(int port) {
-    try {
-      _server = HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port);
-      _server.then(_handleServer);
-    } catch (exception) {
-      // We were unable to start the server, and there's nothing we can do about
-      // it.
-    }
+    _server = HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port);
+    _server.then(_handleServer).catchError((_) {/* Ignore errors. */});
   }
 
   /**
    * Handle a GET request received by the HTTP server.
    */
   void _handleGetRequest(HttpRequest request) {
-    if (AnalysisEngine.instance.useTaskModel) {
-      if (newGetHandler == null) {
-        newGetHandler = new newHandler.GetHandler(socketServer, _printBuffer);
-      }
-      newGetHandler.handleGetRequest(request);
-    } else {
-      if (getHandler == null) {
-        getHandler = new GetHandler(socketServer, _printBuffer);
-      }
-      getHandler.handleGetRequest(request);
+    if (getHandler == null) {
+      getHandler = new GetHandler(socketServer, _printBuffer);
     }
+    getHandler.handleGetRequest(request);
   }
 
   /**
    * Attach a listener to a newly created HTTP server.
    */
-  void _handleServer(HttpServer httServer) {
-    httServer.listen((HttpRequest request) {
+  void _handleServer(HttpServer httpServer) {
+    httpServer.listen((HttpRequest request) {
       List<String> updateValues = request.headers[HttpHeaders.UPGRADE];
       if (updateValues != null && updateValues.indexOf('websocket') >= 0) {
         WebSocketTransformer.upgrade(request).then((WebSocket websocket) {
diff --git a/pkg/analysis_server/lib/src/services/completion/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/arglist_contributor.dart
deleted file mode 100644
index 4f7780d..0000000
--- a/pkg/analysis_server/lib/src/services/completion/arglist_contributor.dart
+++ /dev/null
@@ -1,421 +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 services.completion.contributor.dart.arglist;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-
-void _addNamedParameterSuggestion(
-    DartCompletionRequest request, List<String> namedArgs, String name) {
-  if (name != null && name.length > 0 && !namedArgs.contains(name)) {
-    request.addSuggestion(new CompletionSuggestion(
-        CompletionSuggestionKind.NAMED_ARGUMENT,
-        DART_RELEVANCE_NAMED_PARAMETER,
-        '$name: ',
-        name.length + 2,
-        0,
-        false,
-        false));
-  }
-}
-
-/**
- * Determine the number of arguments.
- */
-int _argCount(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  if (node is ArgumentList) {
-    return node.arguments.length;
-  }
-  return 0;
-}
-
-/**
- * Determine if the completion target is at the end of the list of arguments.
- */
-bool _isAppendingToArgList(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  if (node is ArgumentList) {
-    var entity = request.target.entity;
-    if (entity == node.rightParenthesis) {
-      return true;
-    }
-    if (node.arguments.length > 0 && node.arguments.last == entity) {
-      return entity is SimpleIdentifier;
-    }
-  }
-  return false;
-}
-
-/**
- * Determine if the completion target is an emtpy argument list.
- */
-bool _isEmptyArgList(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  return node is ArgumentList &&
-      node.leftParenthesis.next == node.rightParenthesis;
-}
-
-/**
- * Return a collection of currently specified named arguments
- */
-Iterable<String> _namedArgs(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  List<String> namedArgs = new List<String>();
-  if (node is ArgumentList) {
-    for (Expression arg in node.arguments) {
-      if (arg is NamedExpression) {
-        namedArgs.add(arg.name.label.name);
-      }
-    }
-  }
-  return namedArgs;
-}
-
-/**
- * A contributor for calculating `completion.getSuggestions` request results
- * when the cursor position is inside the arguments to a method call.
- */
-class ArgListContributor extends DartCompletionContributor {
-  _ArgSuggestionBuilder builder;
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    builder =
-        request.target.containingNode.accept(new _ArgListAstVisitor(request));
-    return builder == null;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    if (builder != null) {
-      return builder.compute(request.target.containingNode);
-    }
-    return new Future.value(false);
-  }
-}
-
-/**
- * A visitor for determining whether an argument list suggestion is needed
- * and instantiating the builder to create the suggestion.
- */
-class _ArgListAstVisitor extends GeneralizingAstVisitor<_ArgSuggestionBuilder> {
-  final DartCompletionRequest request;
-
-  _ArgListAstVisitor(this.request);
-
-  @override
-  _ArgSuggestionBuilder visitArgumentList(ArgumentList node) {
-    Token leftParen = node.leftParenthesis;
-    if (leftParen != null && request.offset > leftParen.offset) {
-      AstNode parent = node.parent;
-      if (parent is MethodInvocation) {
-        SimpleIdentifier selector = parent.methodName;
-        if (selector != null) {
-          String name = selector.name;
-          if (name != null && name.length > 0) {
-            if (parent.operator == null) {
-              /*
-               * If a local declaration is found, then return null
-               * indicating that suggestions were added
-               * and no further action is necessary
-               */
-              if (new _LocalArgSuggestionBuilder(request, request.offset, name)
-                  .visit(node)) {
-                return null;
-              }
-            } else {
-              // determine target
-            }
-            return new _ArgSuggestionBuilder(request, name);
-          }
-        }
-      }
-      String constructorName;
-      if (parent is Annotation && parent.name != null) {
-        constructorName = parent.name.toSource();
-      }
-      if (parent is InstanceCreationExpression &&
-          parent.constructorName != null) {
-        constructorName = parent.constructorName.toSource();
-      }
-      if (constructorName != null && constructorName.length > 0) {
-        if (new _LocalArgSuggestionBuilder(
-            request, request.offset, constructorName).visit(node)) {
-          return null;
-        }
-        return new _ArgSuggestionBuilder(request, constructorName);
-      }
-    }
-    return null;
-  }
-
-  @override
-  _ArgSuggestionBuilder visitNode(AstNode node) {
-    return null;
-  }
-}
-
-/**
- * A [_ArgSuggestionBuilder] determines which method or function is being
- * invoked, then builds the argument list suggestion.
- * This operation is instantiated during `computeFast`
- * and calculates the suggestions during `computeFull`.
- */
-class _ArgSuggestionBuilder {
-  final DartCompletionRequest request;
-  final String methodName;
-
-  _ArgSuggestionBuilder(this.request, this.methodName);
-
-  Future<bool> compute(ArgumentList node) {
-    AstNode parent = node.parent;
-    if (parent is MethodInvocation) {
-      SimpleIdentifier methodName = parent.methodName;
-      if (methodName != null) {
-        Element methodElem = methodName.bestElement;
-        if (methodElem is ExecutableElement) {
-          _addSuggestions(methodElem.parameters);
-        }
-      }
-    }
-    if (parent is InstanceCreationExpression) {
-      ConstructorName constructorName = parent.constructorName;
-      if (constructorName != null) {
-        ConstructorElement element = constructorName.staticElement;
-        if (element is ExecutableElement) {
-          _addSuggestions(element.parameters);
-        }
-      }
-    }
-    return new Future.value(false);
-  }
-
-  void _addArgListSuggestion(Iterable<ParameterElement> requiredParam) {
-    StringBuffer completion = new StringBuffer('(');
-    List<String> paramNames = new List<String>();
-    List<String> paramTypes = new List<String>();
-    for (ParameterElement param in requiredParam) {
-      String name = param.name;
-      if (name != null && name.length > 0) {
-        if (completion.length > 1) {
-          completion.write(', ');
-        }
-        completion.write(name);
-        paramNames.add(name);
-        paramTypes.add(_getParamType(param));
-      }
-    }
-    completion.write(')');
-    CompletionSuggestion suggestion = new CompletionSuggestion(
-        CompletionSuggestionKind.ARGUMENT_LIST,
-        DART_RELEVANCE_HIGH,
-        completion.toString(),
-        completion.length,
-        0,
-        false,
-        false);
-    suggestion.parameterNames = paramNames;
-    suggestion.parameterTypes = paramTypes;
-    request.addSuggestion(suggestion);
-  }
-
-  void _addDefaultParamSuggestions(Iterable<ParameterElement> parameters) {
-    Iterable<String> namedArgs = _namedArgs(request);
-    for (ParameterElement param in parameters) {
-      if (param.parameterKind == ParameterKind.NAMED) {
-        _addNamedParameterSuggestion(request, namedArgs, param.name);
-      }
-    }
-  }
-
-  void _addSuggestions(Iterable<ParameterElement> parameters) {
-    if (parameters == null || parameters.length == 0) {
-      return;
-    }
-    Iterable<ParameterElement> requiredParam = parameters.where(
-        (ParameterElement p) => p.parameterKind == ParameterKind.REQUIRED);
-    int requiredCount = requiredParam.length;
-    if (requiredCount > 0 && _isEmptyArgList(request)) {
-      _addArgListSuggestion(requiredParam);
-      return;
-    }
-    if (_isAppendingToArgList(request)) {
-      if (requiredCount == 0 || requiredCount < _argCount(request)) {
-        _addDefaultParamSuggestions(parameters);
-      }
-    }
-  }
-
-  String _getParamType(ParameterElement param) {
-    DartType type = param.type;
-    if (type != null) {
-      return type.displayName;
-    }
-    return 'dynamic';
-  }
-}
-
-/**
- * [_LocalArgSuggestionBuilder] visits an [AstNode] and its parent recursively
- * looking for a matching declaration. If found, it adds the appropriate
- * suggestions and sets finished to `true`.
- */
-class _LocalArgSuggestionBuilder extends LocalDeclarationVisitor {
-  final DartCompletionRequest request;
-  final String name;
-
-  _LocalArgSuggestionBuilder(this.request, int offset, this.name)
-      : super(offset);
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {
-    String className = null;
-    if (declaration.name != null) {
-      className = declaration.name.name;
-    }
-    if (className != null && className.length > 0) {
-      for (ClassMember member in declaration.members) {
-        if (member is ConstructorDeclaration) {
-          String selector = className;
-          if (member.name != null) {
-            selector = '$selector.${member.name.name}';
-          }
-          if (selector == name) {
-            _addSuggestions(member.parameters);
-            finished();
-          }
-        }
-      }
-    }
-  }
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {}
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {}
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {
-    SimpleIdentifier selector = declaration.name;
-    if (selector != null && name == selector.name) {
-      _addSuggestions(declaration.functionExpression.parameters);
-      finished();
-    }
-  }
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {}
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {}
-
-  @override
-  void declaredLocalVar(SimpleIdentifier name, TypeName type) {}
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {
-    SimpleIdentifier selector = declaration.name;
-    if (selector != null && name == selector.name) {
-      _addSuggestions(declaration.parameters);
-      finished();
-    }
-  }
-
-  @override
-  void declaredParam(SimpleIdentifier name, TypeName type) {}
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {}
-
-  void _addArgListSuggestion(Iterable<FormalParameter> requiredParam) {
-    StringBuffer completion = new StringBuffer('(');
-    List<String> paramNames = new List<String>();
-    List<String> paramTypes = new List<String>();
-    for (FormalParameter param in requiredParam) {
-      SimpleIdentifier paramId = param.identifier;
-      if (paramId != null) {
-        String name = paramId.name;
-        if (name != null && name.length > 0) {
-          if (completion.length > 1) {
-            completion.write(', ');
-          }
-          completion.write(name);
-          paramNames.add(name);
-          paramTypes.add(_getParamType(param));
-        }
-      }
-    }
-    completion.write(')');
-    CompletionSuggestion suggestion = new CompletionSuggestion(
-        CompletionSuggestionKind.ARGUMENT_LIST,
-        DART_RELEVANCE_HIGH,
-        completion.toString(),
-        completion.length,
-        0,
-        false,
-        false);
-    suggestion.parameterNames = paramNames;
-    suggestion.parameterTypes = paramTypes;
-    request.addSuggestion(suggestion);
-  }
-
-  void _addDefaultParamSuggestions(FormalParameterList parameters) {
-    Iterable<String> namedArgs = _namedArgs(request);
-    for (FormalParameter param in parameters.parameters) {
-      if (param.kind == ParameterKind.NAMED) {
-        SimpleIdentifier paramId = param.identifier;
-        if (paramId != null) {
-          _addNamedParameterSuggestion(request, namedArgs, paramId.name);
-        }
-      }
-    }
-  }
-
-  void _addSuggestions(FormalParameterList parameters) {
-    if (parameters == null || parameters.parameters.length == 0) {
-      return;
-    }
-    Iterable<FormalParameter> requiredParam = parameters.parameters
-        .where((FormalParameter p) => p.kind == ParameterKind.REQUIRED);
-    int requiredCount = requiredParam.length;
-    if (requiredCount > 0 && _isEmptyArgList(request)) {
-      _addArgListSuggestion(requiredParam);
-      return;
-    }
-    if (_isAppendingToArgList(request)) {
-      if (requiredCount == 0 || requiredCount < _argCount(request)) {
-        _addDefaultParamSuggestions(parameters);
-      }
-    }
-  }
-
-  String _getParamType(FormalParameter param) {
-    TypeName type;
-    if (param is SimpleFormalParameter) {
-      type = param.type;
-    }
-    if (type != null) {
-      Identifier id = type.name;
-      if (id != null) {
-        String name = id.name;
-        if (name != null && name.length > 0) {
-          return name;
-        }
-      }
-    }
-    return 'dynamic';
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/combinator_contributor.dart
deleted file mode 100644
index a8ef022..0000000
--- a/pkg/analysis_server/lib/src/services/completion/combinator_contributor.dart
+++ /dev/null
@@ -1,82 +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 services.completion.contributor.dart.combinator;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-
-/**
- * A contributor for calculating `completion.getSuggestions` request results
- * for the import combinators show and hide.
- */
-class CombinatorContributor extends DartCompletionContributor {
-  _CombinatorSuggestionBuilder builder;
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    builder = request.target.containingNode
-        .accept(new _CombinatorAstVisitor(request));
-    return builder == null;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    if (builder != null) {
-      return builder.execute(request.target.containingNode);
-    }
-    return new Future.value(false);
-  }
-}
-
-/**
- * A visitor for determining which imported classes and top level variables
- * should be suggested and building those suggestions.
- */
-class _CombinatorAstVisitor
-    extends GeneralizingAstVisitor<_CombinatorSuggestionBuilder> {
-  final DartCompletionRequest request;
-
-  _CombinatorAstVisitor(this.request);
-
-  @override
-  _CombinatorSuggestionBuilder visitCombinator(Combinator node) {
-    return new _CombinatorSuggestionBuilder(
-        request, CompletionSuggestionKind.IDENTIFIER);
-  }
-
-  @override
-  _CombinatorSuggestionBuilder visitNode(AstNode node) {
-    return null;
-  }
-}
-
-/**
- * A `_CombinatorSuggestionBuilder` determines which imported classes
- * and top level variables should be suggested and builds those suggestions.
- * This operation is instantiated during `computeFast`
- * and calculates the suggestions during `computeFull`.
- */
-class _CombinatorSuggestionBuilder extends LibraryElementSuggestionBuilder {
-  _CombinatorSuggestionBuilder(
-      DartCompletionRequest request, CompletionSuggestionKind kind)
-      : super(request, kind, false, false);
-
-  Future<bool> execute(AstNode node) {
-    var directive = node.getAncestor((parent) => parent is NamespaceDirective);
-    if (directive is NamespaceDirective) {
-      LibraryElement library = directive.uriElement;
-      if (library != null) {
-        library.visitChildren(this);
-      }
-    }
-    return new Future.value(false);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/common_usage_computer.dart b/pkg/analysis_server/lib/src/services/completion/common_usage_computer.dart
deleted file mode 100644
index e3c44ce..0000000
--- a/pkg/analysis_server/lib/src/services/completion/common_usage_computer.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.completion.computer.dart.relevance;
-
-import 'package:analysis_server/src/protocol_server.dart' as protocol;
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind;
-import 'package:analysis_server/src/provisional/completion/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/contribution_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart'
-    show DART_RELEVANCE_COMMON_USAGE;
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-
-part 'common_usage_generated.dart';
-
-/**
- * A computer for adjusting the relevance of completions computed by others
- * based upon common Dart usage patterns. This is a long-lived object
- * that should not maintain state between calls to it's [sort] method.
- */
-class CommonUsageComputer implements ContributionSorter {
-  /**
-   * A map of <library>.<classname> to an ordered list of method names,
-   * field names, getter names, and named constructors.
-   * The names are ordered from most relevant to least relevant.
-   * Names not listed are considered equally less relevant than those listed.
-   */
-  Map<String, List<String>> selectorRelevance;
-
-  CommonUsageComputer([this.selectorRelevance = defaultSelectorRelevance]);
-
-  @override
-  void sort(DartCompletionRequest request,
-      Iterable<CompletionSuggestion> suggestions) {
-    _update(request, suggestions);
-  }
-
-  /**
-   * Adjusts the relevance based on the given completion context.
-   * The compilation unit and completion node
-   * in the given completion context may not be resolved.
-   */
-  void _update(DartCompletionRequest request,
-      Iterable<CompletionSuggestion> suggestions) {
-    var visitor = new _BestTypeVisitor(request.target.entity);
-    DartType type = request.target.containingNode.accept(visitor);
-    if (type != null) {
-      Element typeElem = type.element;
-      if (typeElem != null) {
-        LibraryElement libElem = typeElem.library;
-        if (libElem != null) {
-          _updateInvocationRelevance(request, type, libElem, suggestions);
-        }
-      }
-    }
-  }
-
-  /**
-   * Adjusts the relevance of all method suggestions based upon the given
-   * target type and library.
-   */
-  void _updateInvocationRelevance(DartCompletionRequest request, DartType type,
-      LibraryElement libElem, Iterable<CompletionSuggestion> suggestions) {
-    String typeName = type.name;
-    List<String> selectors = selectorRelevance['${libElem.name}.${typeName}'];
-    if (selectors != null) {
-      for (CompletionSuggestion suggestion in suggestions) {
-        protocol.Element element = suggestion.element;
-        if (element != null &&
-            (element.kind == protocol.ElementKind.CONSTRUCTOR ||
-                element.kind == protocol.ElementKind.FIELD ||
-                element.kind == protocol.ElementKind.GETTER ||
-                element.kind == protocol.ElementKind.METHOD ||
-                element.kind == protocol.ElementKind.SETTER) &&
-            suggestion.kind == CompletionSuggestionKind.INVOCATION &&
-            suggestion.declaringType == typeName) {
-          int index = selectors.indexOf(suggestion.completion);
-          if (index != -1) {
-            suggestion.relevance = DART_RELEVANCE_COMMON_USAGE - index;
-          }
-        }
-      }
-    }
-  }
-}
-
-/**
- * An [AstVisitor] used to determine the best defining type of a node.
- */
-class _BestTypeVisitor extends GeneralizingAstVisitor {
-  /**
-   * The entity which the completed text will replace (or which will be
-   * displaced once the completed text is inserted).  This may be an AstNode or
-   * a Token, or it may be null if the cursor is after all tokens in the file.
-   * See field of the same name in [CompletionTarget].
-   */
-  final Object entity;
-
-  _BestTypeVisitor(this.entity);
-
-  DartType visitConstructorName(ConstructorName node) {
-    if (node.period != null && node.name == entity) {
-      TypeName typeName = node.type;
-      if (typeName != null) {
-        return typeName.type;
-      }
-    }
-    return null;
-  }
-
-  DartType visitNode(AstNode node) {
-    return null;
-  }
-
-  DartType visitPrefixedIdentifier(PrefixedIdentifier node) {
-    if (node.identifier == entity) {
-      SimpleIdentifier prefix = node.prefix;
-      if (prefix != null) {
-        return prefix.bestType;
-      }
-    }
-    return null;
-  }
-
-  DartType visitPropertyAccess(PropertyAccess node) {
-    if (node.propertyName == entity) {
-      Expression target = node.realTarget;
-      if (target != null) {
-        return target.bestType;
-      }
-    }
-    return null;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/common_usage_generated.dart b/pkg/analysis_server/lib/src/services/completion/common_usage_generated.dart
deleted file mode 100644
index f6899ec..0000000
--- a/pkg/analysis_server/lib/src/services/completion/common_usage_generated.dart
+++ /dev/null
@@ -1,427 +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 services.completion.computer.dart.relevance;
-
-// Auto-generated, please do not edit.
-
-/**
- * A map of <library>.<classname> to an ordered list of method names,
- * field names, getter names, and named constructors.
- * The names are ordered from most relevant to least relevant.
- * Names not listed are considered equally less relevant than those listed.
- */
-const Map<String, List<String>> defaultSelectorRelevance = const {
-'dart.core.Comparable': const ['compareTo','compare',],
-'dart.math.Random': const ['nextInt','nextDouble','nextBool',],
-'dart.core.List': const ['add','map','length','removeLast','addAll','join','forEach','contains','removeAt','where','last','clear','setRange','sort','insert','remove','sublist','indexOf','isEmpty','any','insertAll','first','removeRange','replaceRange','take','getRange','skip','toList','retainWhere','fillRange','removeWhere','expand','fold','reversed','firstWhere','every','setAll','asMap','isNotEmpty','lastIndexOf','singleWhere','lastWhere','shuffle','takeWhile','iterator','toString','toSet','single','reduce','elementAt','skipWhile','insertRange','filter','push','mappedBy','addLast','some','slice','retainMatching','firstMatching','removeAll','retainAll','removeMatching','min','lastMatching','singleMatching','max','get','toArray','runtimeType','reverse','addd','asByteArray',],
-'dart.core.Iterable': const ['toList','map','join','toSet','where','forEach','expand','fold','every','any','contains','firstWhere','length','elementAt','skipWhile','reduce','iterator','take','skip','toString','singleWhere','lastWhere','takeWhile','isEmpty','first','single','last','isNotEmpty','addAll','indexOf','add','sort','toArray','mappedBy','filter',],
-'dart.core.Set': const ['add','contains','remove','addAll','clear','difference','map','containsAll','union','removeWhere','removeAll','intersection','retainAll','retainWhere','forEach','toSet','every','lookup','any','toString','toList','where','length','join','skip','firstWhere','isEmpty','first','iterator','singleWhere','expand','elementAt','fold','reduce','single','lastWhere','isNotEmpty','take','takeWhile','skipWhile','last','findBy','toArray','filter',],
-'dart.collection.Queue': const ['add','removeFirst','clear','removeLast','remove','addAll','addLast','addFirst','removeWhere','retainWhere','length','toList','where','contains','forEach','map','isNotEmpty','first','isEmpty','fold','skip','any','elementAt',],
-'dart.core.Map': const ['containsKey','forEach','remove','putIfAbsent','clear','addAll','length','keys','values','containsValue','toString','isNotEmpty','isEmpty','get','getKeys','put','getValues','clone','keySet','hashCode','runtimeType',],
-'dart.core.Iterator': const ['moveNext','current','next','hasNext',],
-'dart.pkg.collection.equality.Equality': const ['hash','equals','isValidKey',],
-'dart.pkg.collection.equality.SetEquality': const ['equals','hash',],
-'dart.pkg.collection.equality.MapEquality': const ['equals','hash',],
-'dart.pkg.collection.equality.ListEquality': const ['equals','hash',],
-'dart.pkg.collection.equality.IterableEquality': const ['hash','equals',],
-'dart.pkg.collection.equality.UnorderedIterableEquality': const ['hash','equals',],
-'dart.async.StreamSubscription': const ['cancel','pause','onDone','resume','onError','asFuture','onData','isPaused',],
-'dart.async.StreamController': const ['add','close','addError','addStream','stream','hasListener','signalError','sink','done',],
-'dart.async.Stream': const ['listen','transform','pipe','first','toList','forEach','firstWhere','where','join','fold','asyncMap','map','isEmpty','asBroadcastStream','handleError','capture','asyncExpand','take','single','expand','onFile','skip','any','timeout','add','last','runtimeType','isBroadcast','drain','elementAt','skipWhile','distinct','singleWhere','lastWhere','contains','every','takeWhile','emit','onDir','onError','onDone','onData','length',],
-'dart.async.Future': const ['then','catchError','wait','whenComplete','forEach','asStream','timeout','map','packages','where','firstWhere','chain','transform','doWhile','onError','onResponse','onRequest','handleException',],
-'dart.core.String': const ['substring','codeUnitAt','startsWith','replaceAll','split','contains','indexOf','toLowerCase','trim','length','endsWith','lastIndexOf','compareTo','isEmpty','toUpperCase','replaceFirst','toString','replaceAllMapped','allMatches','padLeft','codeUnits','hashCode','splitMapJoin','isNotEmpty','runes','charCodeAt','charCodes','trimRight','padRight','concat','equalsIgnoreCase','splitChars','trimLeft','matchAsPrefix','equals','map','toLoweCase','match','slice','getBytes','toCharArray','runtimeType','charAt','valueOf',],
-'dart.core.StringBuffer': const ['write','toString','writeln','writeCharCode','clear','writeAll','add','addAll','addCharCode','isEmpty',],
-'dart.core.RegExp': const ['firstMatch','hasMatch','allMatches','matchAsPrefix','pattern','stringMatch','toString','exec',],
-'dart.core.double': const ['parse','toInt','compareTo','floor','toString','abs','round','toStringAsPrecision','toDouble','floorToDouble','ceil','truncate','toStringAsFixed','roundToDouble','clamp','isNaN','isFinite','toStringAsExponential','ceilToDouble','truncateToDouble','isNan','isNegative','isInfinite','hashCode',],
-'dart.core.Type': const ['toString','hashCode','runtimeType',],
-'dart.mirrors.InstanceMirror': const ['reflectee','getField','type','invoke','setField','delegate','function','then','apply','hasReflectee',],
-'dart.collection.IterableBase': const ['iterableToFullString',],
-'dart.pkg.collection.utils.Pair': const ['last',],
-'dart.collection.Maps': const ['mapToString','length','putIfAbsent','clear','containsKey','getValues','forEach','containsValue','isNotEmpty','isEmpty',],
-'dart.collection.SplayTreeSet': const ['add','addAll','where',],
-'dart.core.StackTrace': const ['toString','frames',],
-'dart.convert.JsonCodec': const ['encode','decode','fuse',],
-'dart.mirrors.MirrorSystem': const ['getName','libraries','findLibrary','isolate','dynamicType','getSymbol','voidType',],
-'dart.mirrors.ClassMirror': const ['newInstance','isSubtypeOf','reflectedType','qualifiedName','metadata','getField','owner','declarations','superclass','simpleName','isSubclassOf','invoke','instanceMembers','mixin','isAbstract','originalDeclaration','typeVariables','setField','isOriginalDeclaration','superinterfaces','isAssignableTo','owners',],
-'dart.io.Process': const ['start','runSync','run','kill','exitCode',],
-'dart.core.int': const ['parse','toDouble','toString','toInt','compareTo','toRadixString','abs','remainder','toUnsigned','toSigned','clamp','round','floor','substr','ceil','isEven','id','append','truncate','hashCode','toStringAsFixed','ceilToDouble','roundToDouble','floorToDouble','truncateToDouble','isNegative','length','isNaN','isInfinite','runtimeType','bitLength',],
-'dart.core.Sink': const ['add','close',],
-'dart.async.EventSink': const ['close','add','addError',],
-'dart.async.Completer': const ['complete','completeError','future','isCompleted','completeException','then',],
-'dart.io.FileStat': const ['mode','stat','type','statSync','changed','modified','size',],
-'dart.io.Link': const ['existsSync','createSync','resolveSymbolicLinksSync','exists','delete','targetSync','deleteSync','target','create','updateSync',],
-'dart.io.FileSystemEntityType': const ['toString','NOT_FOUND','DIRECTORY','FILE',],
-'dart.io.Directory': const ['existsSync','list','listSync','watch','path','exists','createSync','create','deleteSync','delete','createTemp','createTempSync','renameSync','parent','absolute','stat','current','createRecursivelySync','resolveSymbolicLinksSync','rename','statSync',],
-'dart.io.File': const ['existsSync','readAsStringSync','openRead','writeAsStringSync','readAsString','openWrite','lastModifiedSync','exists','resolveSymbolicLinksSync','writeAsString','path','resolveSymbolicLinks','statSync','deleteSync','createSync','delete','openSync','parent','readAsBytesSync','copy','open','absolute','fullPathSync','length','writeAsBytesSync','lastModified','writeAsBytes','readAsLinesSync','fullPath','readAsBytes','copySync','create','lengthSync','readAsLines','isFileSync','isFile','rename','openOutputStream','openInputStream','stat','renameSync','watch','directorySync','isAbsolute','directory',],
-'dart.io.Stdout': const ['writeln','close','write','flush','addStream','writeString','add','writeCharCode','addString',],
-'dart.io.IOSink': const ['write','close','writeln','flush','add','addStream','writeAll','writeCharCode','encoding','addError','done',],
-'dart.mirrors.LibraryMirror': const ['uri','getField','declarations','invoke','topLevelMembers','setField','classes','first',],
-'dart.core.Match': const ['group','end','start','groups','toString',],
-'dart.isolate.SendPort': const ['send','call','hashCode',],
-'dart.core.DateTime': const ['parse','toIso8601String','millisecondsSinceEpoch','difference','toUtc','add','day','year','month','isAfter','toString','compareTo','subtract','isBefore','millisecond','toLocal','timeZoneName','timeZoneOffset','isUtc','weekday','isAtSameMomentAs','second','hour','minute','hashCode','now','runtimeType',],
-'dart.core.Duration': const ['inMilliseconds','toString','inSeconds','inMicroseconds','inHours','inMinutes','inDays','isNegative','compareTo',],
-'dart.core.Uri': const ['parse','toString','toFilePath','path','resolve','decodeComponent','encodeFull','decodeQueryComponent','scheme','encodeComponent','resolveUri','encodeQueryComponent','query','decodeFull','pathSegments','queryParameters','origin','authority','splitQueryString','replace','host','isAbsolute','port','fragment','hasAuthority','userInfo','parseIPv4Address','parseIPv6Address','hasQuery','endsWith','startsWith',],
-'dart.typed_data.Uint32List': const ['sublist','setAll','fillRange','setRange','removeRange','removeLast','clear','addAll','add',],
-'dart.typed_data.TypedData': const ['buffer',],
-'dart.io.BytesBuilder': const ['takeBytes','addByte','add','clear','toBytes',],
-'dart.isolate.ReceivePort': const ['close','transform','listen','receive','toSendPort','takeWhile','sendPort','asBroadcastStream',],
-'dart.convert.Encoding': const ['decode','encode','getByName','decodeStream','name',],
-'dart.convert.Utf8Codec': const ['encode','decode','decoder','decodeStream',],
-'dart.core.Stopwatch': const ['start','stop','reset','elapsedMicroseconds','elapsedMilliseconds','elapsed','elapsedInMs',],
-'dart.async.ZoneDelegate': const ['handleUncaughtError','registerUnaryCallback','registerCallback','registerBinaryCallback','runBinary','errorCallback','scheduleMicrotask','run','createTimer',],
-'dart.async.Zone': const ['handleUncaughtError','run','fork','inSameErrorZone','runGuarded','bindUnaryCallback','bindBinaryCallback','runUnary','bindCallback','scheduleMicrotask','createTimer',],
-'dart.dom.html.BodyElement': const ['innerHtml','children','nodes','append','style','onContextMenu','onMouseDown','onMouseWheel','scrollTop','onMouseUp','onClick','scrollLeft','clientHeight','clientWidth','onBlur','onFocus','onDoubleClick','scrollHeight','onMouseMove','elements','createFragment','classes','ownerDocument','query','onKeyDown','querySelector','offsetWidth','scrollWidth','offsetHeight','setInnerHtml','childNodes','requestFullscreen','offsetTop',],
-'dart.dom.html.Location': const ['hash','search','reload','pathname','toString','href','host','assign','replace','protocol','hostname','port','origin',],
-'dart.convert.HtmlEscape': const ['convert',],
-'dart.dom.html.Window': const ['postMessage','btoa','lookupPort','document','requestAnimationFrame','alert','navigator','devicePixelRatio','pageYOffset','pageXOffset','onAnimationEnd','innerWidth','onResize','getSelection','cancelAnimationFrame','animationEndEvent','innerHeight','registerPort','dispatchEvent','onAnimationStart','onMouseUp','onMouseMove','open','screen','indexedDB','setTimeout','scrollX','scrollY','onScroll','openDatabase','confirm','getContainer','location','onKeyUp','atob','scrollTo','localStorage','scrollBy','setInterval','setImmediate','requestLayoutFrame','requestFileSystem','onHashChange','close','console','onError','onMessage','animationFrame',],
-'dart.core.Function': const ['apply','toString','call','bind',],
-'dart.async.Timer': const ['cancel','run',],
-'dart.dom.html.HeadElement': const ['append','querySelector','query','children','style','elements','querySelectorAll','nodes','id','insertBefore','text',],
-'dart.dom.html.ElementStream': const ['listen','where','first','matches','forEach','map',],
-'dart.dom.html.Element': const ['query','onClick','innerHtml','style','querySelector','nodes','children','remove','append','querySelectorAll','classes','attributes','setInnerHtml','getComputedStyle','onChange','parent','matches','getBoundingClientRect','focus','dispatchEvent','addEventListener','insertAllBefore','clone','getAttribute','blur','createShadowRoot','contains','text','setAttribute','insertAdjacentElement','appendText','scrollIntoView','shadowRoot','getNamespacedAttributes','removeEventListener','insertBefore','appendHtml','click','offsetWidth','insertAdjacentHtml','insertAdjacentText','getClientRects','getElementsByClassName','replaceWith','scrollByLines','scrollByPages','hasChildNodes','requestFullscreen','requestPointerLock','queryAll','setAttributeNS','getAttributeNS','dataset','offsetHeight','on','createFragment','offsetTo','getDestinationInsertionPoints','matchesWithAncestors','attributeChanged','onMouseDown','nextElementSibling','getRegionFlowRanges','onContextMenu','animate','onTouchStart','scrollTop','offsetTop','onTouchMove','onTouchEnd','onMouseWheel','clientWidth','scrollLeft','clientHeight','isTagSupported','parentNode','onMouseUp','bind','onKeyDown','ownerDocument','unbind','unbindAll','init','createInstance','render','update','onKeyUp','onMouseMove','xtag','offsetLeft','tabIndex','client','requestFullScreen','getInputContext','borderEdge','clearModel','id','disabled','value','getContext','lastChild','firstChild','nextNode','innerHTML','onMouseEnter','onMouseLeave','contentEdge','elements','matchesSelector','webkitRequestPointerLock','tagName','childNodes','webkitRequestFullscreen','webkitRequestFullScreen','marginEdge','paddingEdge','outerHtml','onMouseOver','onMouseOut','onDragEnd','boolean','scrollHeight','hidden','onDragStart','onDoubleClick','nodeType','hashCode','onDrag','onInput','selectionStart','selectionEnd','onDrop','onDragLeave','hideOrShowNavigation','onDragOver','model','scrollEvent','onDragEnter','previousElementSibling','className','namespaceUri','onSubmit','selection','setItemSelected','runtimeType','apply','createBinding','values','onBlur','onTouchCancel','show','insertAdjacentHTML','nodeName','selected','contentEditable','localName','number','draggable','src','addText','addHTML','select','clear','str','clearSelection',],
-'dart.dom.html.HtmlElement': const ['querySelector','query','append','classes','style','getComputedStyle','remove','getBoundingClientRect','querySelectorAll','clone','attributes','focus','tabIndex','onClick','parent','onMouseLeave','replaceWith','onContextMenu','onMouseEnter','onKeyDown','blur','setInnerText','scrollTop','appendHtml','dataset','lastChild','onSelectStart','onDrop','onDragOver','onDragLeave','onDragEnter','onDragEnd','onDragStart','onDrag','onDoubleClick','children','onScroll','getAttribute','nodes','outerHtml','click','createShadowRoot',],
-'dart.dom.html.ElementList': const ['forEach','length','contains','last','style','addAll','first','where','onMouseLeave','onMouseEnter','toList','some','onClick','map','classes','indexOf',],
-'dart.dom.html.HtmlDocument': const ['query','querySelectorAll','querySelector','queryAll','createElement','body','title','createElementUpgrader','documentElement','timeline','onKeyDown','getElementById','registerElement','onClick','addEventListener','onMouseUp','onMouseMove','activeElement','createElementNS','createDocumentFragment','createRange','adoptNode','getElementsByTagName','onKeyUp','elementFromPoint','contains','getElementsByName','head','exitFullscreen','onMouseWheel','register',],
-'dart.collection.LinkedHashMap': const ['containsKey','forEach','remove','putIfAbsent','keys','length','clear','values','isNotEmpty',],
-'dart.dom.html.Navigator': const ['userAgent','language','appVersion','appName','geolocation','vendor','appCodeName','dartEnabled','getUserMedia','onLine','platform','storageQuota',],
-'dart.dom.html.CssStyleDeclaration': const ['display','width','height','top','setProperty','left','position','zIndex','cssText','right','maxHeight','visibility','bottom','background','removeProperty','cursor','overflow','getPropertyValue','opacity','backgroundColor','float','transform','padding','border','borderRadius','paddingBottom','transition','paddingTop','overflowY','color','outline','backgroundImage','transformStyle','pointerEvents','marginLeft','textAlign','backgroundPosition','boxSizing','paddingLeft','backgroundSize','margin','fontFamily','userSelect','fontSize','lineHeight','willChange','fontWeight','getProperty','marginRight','whiteSpace','overflowX','textDecoration','perspective','perspectiveOrigin','appearance','borderLeftWidth','paddingRight','borderColor','borderBottomWidth','borderTopWidth','webkitOverflowScrolling','borderRightWidth','marginBottom','transitionProperty','transitionTimingFunction','transitionDuration','animation','animationDelay','animationFillMode','animationDirection','animationIterationCount','animationTimingFunction','animationDuration','animationName','verticalAlign','marginTop','boxShadow','getPropertyPriority','textStrokeColor','borderBottom','font','supportsProperty','textShadow','maxWidth','minWidth','minHeight','outlineColor','filter','borderWidth','animationPlayState','fontStyle','borderRight','borderLeft','borderTop',],
-'dart.io.ProcessResult': const ['stdout','exitCode',],
-'dart.io.FileSystemEvent': const ['path','isDirectory','type','MODIFY','CREATE','DELETE',],
-'dart.collection.HashSet': const ['add','contains','remove','clear','addAll','retainAll','length','isEmpty','toList','removeAll','any','forEach','map',],
-'dart.collection.HashMap': const ['remove','containsKey','forEach','clear','keys','putIfAbsent','addAll','values',],
-'dart.io.FileSystemEntity': const ['isDirectorySync','path','typeSync','existsSync','isDirectory','identicalSync','isFileSync','type','isFile','statSync','deleteSync','isLinkSync','parentOf','renameSync','isLink','readAsStringSync','identical','rename','toString','delete','exists','parent','stat',],
-'dart.io.OSError': const ['errorCode','toString',],
-'dart.async.StreamTransformer': const ['bind',],
-'dart.core.Runes': const ['toList','any','elementAt','iterator','single','first','forEach','last',],
-'dart.core.Object': const ['toString','toJson','hashCode','discardListChages','reverse','map','lightDom','getName','where','add','containsKey','format','setTable','getClass','getNamespace','getId','getCell','getSize','setNamespace','equals','setColumn','getColumnName','getForeignTableName','setDatabase','setAttribute','setId','getChild','body','setPrevious','getIndex','getParent','getChildAt','getChildCount','getValue','getRoot','POST','GET','getPackage','setSchema','clone','getType','then','isInheritance','isVisible','getDartName','getPlatform','setPosition','setPackage','requiresTransactionInPostgres','setAppData','getSchema','getBuildProperty','getPrevious','getTerminal','n','replaceWith','setChild','setPlatform','run','removeItem','getAllItems','bytes','compareTo','getAttribute','setPreviousIndex','isEmpty','getEdgeAt','isVertex','writeExternal','isEdge','getEdgeCount','isConnectable','setValue','isCollapsed','getStyles','setRoot','getStyle','getGeometry','noSuchMethod','contains','elementAt','e',],
-'dart.core.StringSink': const ['write','writeln','writeCharCode','toString','writeAll',],
-'dart.io.Stdin': const ['pipe','readLineSync','transform','listen',],
-'dart.io.HttpServer': const ['bind','listen','close','connectionsInfo','bindSecure','address','port','idleTimeout','serverHeader','autoCompress','asBroadcastStream','transform','addRequestHandler','listenOn','on',],
-'dart.io.HttpResponse': const ['close','write','statusCode','headers','add','done','redirect','addStream','detachSocket','reasonPhrase','writeln','addError','writeCharCode','writeAll','flush','toString','when','cookies','contentLength','addString','getLogs','listen','persistentConnection','deadline',],
-'dart.io.HttpRequest': const ['listen','uri','session','drain','transform','response','toString','cookies','method','fold','connectionInfo','pipe','asBroadcastStream','toList','timeout','takeWhile','take','skipWhile','singleWhere','map','lastWhere','join','handleError','skip','firstWhere','expand','every','elementAt','distinct','asyncMap','asyncExpand','any','toSet','contains','where','reduce','forEach','headers','path',],
-'dart.collection.SplayTreeMap': const ['forEach','containsKey','remove','keys','values','firstKeyAfter','lastKeyBefore','clear','length',],
-'dart.io.HttpClient': const ['post','getUrl','openUrl','close','postUrl','get','open','addCredentials','patchUrl','shutdown','put','delete','addProxyCredentials','findProxyFromEnvironment',],
-'dart.io.HttpClientRequest': const ['close','add','write','addStream','cookies',],
-'dart.io.Platform': const ['isWindows','script','environment','operatingSystem','pathSeparator',],
-'dart.collection.LinkedHashSet': const ['add','map','contains','toList','addAll','remove',],
-'dart.io.RandomAccessFile': const ['lengthSync','readIntoSync','close','closeSync','writeStringSync','writeString','writeFromSync','length','readInto','read','readSync','writeFrom','readListSync','flushSync','positionSync','setPosition','writeListSync','setPositionSync','unlock','lock','unlockSync','readList','lockSync','readByteSync','position','writeList','writeByteSync',],
-'dart.core.num': const ['round','toDouble','toInt','floor','abs','toString','parse','ceil','toStringAsFixed','isNaN','compareTo','roundToDouble','remainder','hashCode','clamp','isInfinite','isNegative','truncate','toStringAsPrecision','toStringAsExponential','isFinite','truncateToDouble','toRadixString',],
-'dart.dom.html.HttpRequest': const ['send','open','getString','abort','setRequestHeader','request','getAllResponseHeaders','overrideMimeType','requestCrossOrigin','getResponseHeader','postFormData','onLoadEnd','onError','onLoad','DONE','withCredentials','onReadyStateChange','onLoadStart',],
-'dart.dom.html.Event': const ['preventDefault','toString','stopImmediatePropagation','stopPropagation','target','currentTarget',],
-'dart.dom.html.FileReader': const ['readAsArrayBuffer','readAsDataUrl','readAsText','onError','onLoadEnd','result',],
-'dart.core.Pattern': const ['allMatches','matchAsPrefix','toString','firstMatch','pattern','codeUnitAt',],
-'dart.io.ContentType': const ['parse','toString','charset','mimeType','value','parameters','subType','primaryType',],
-'dart.io.HttpHeaders': const ['set','contentType','ifModifiedSince','value','add','host','forEach','date','removeAll','clear','remove','noFolding','contentLength','port','expires','chunkedTransferEncoding','persistentConnection','toString','CONTENT_TYPE','data',],
-'dart.typed_data.Uint8List': const ['setRange','sublist','fillRange','setAll','length','buffer','toString','toList','lastIndexOf','indexOf','join','removeRange','removeLast','clear','addAll','add',],
-'dart.async.StreamSink': const ['close','addStream','add','addError',],
-'dart.typed_data.ByteData': const ['getUint32','setUint32','getUint8','setUint64','getInt32','getUint16','getUint64','setUint16','getInt16','setInt64','setInt32','setInt16','setFloat64','getInt64','setInt8','getFloat64','getFloat32','setFloat32','getInt8','setUint8',],
-'dart.io.HttpClientResponse': const ['listen','toList','transform','drain','fold','pipe','detachSocket',],
-'dart.core.BidirectionalIterator': const ['moveNext','movePrevious',],
-'dart.mirrors.ClosureMirror': const ['invoke','apply','function',],
-'dart.typed_data.Int32x4': const ['x','signMask','select',],
-'dart.js.JsObject': const ['callMethod','hasProperty','toString','deleteProperty','instanceof',],
-'dart.dom.html.Node': const ['remove','ELEMENT_NODE','insertBefore','replaceWith','insertAllBefore','querySelector','localName','text','append','setMenubarOrientation','getElementsByTagName','getElementsByClassName','nodes','parentNode','getElementById','firstChild','parent','contains','tagName','value','toString','name','querySelectorAll','clone','attributes','nextNode','nodeType','click','bind','outerHtml','dispatchEvent','on','childNodes',],
-'dart.core.RuneIterator': const ['moveNext','reset',],
-'dart.mirrors.DeclarationMirror': const ['isPrivate','simpleName','metadata','isSubclassOf','qualifiedName','parameters','invoke',],
-'dart.dom.html.History': const ['pushState','back','replaceState','length',],
-'dart.dom.html.CssClassSet': const ['add','remove','toggle','clear','contains','addAll','removeAll','toString','firstWhere','first','toggleAll','length','containsAll',],
-'dart.dom.html.Document': const ['querySelector','querySelectorAll','documentElement','createElement','title','body','removeEventListener','addEventListener','getElementsByTagName','createElementNS','query','window','queryAll',],
-'dart.mirrors.IsolateMirror': const ['rootLibrary',],
-'dart.mirrors.ObjectMirror': const ['invoke','getField','setField',],
-'dart.dom.html.DivElement': const ['append','classes','style','setInnerHtml','remove','querySelector','id','getComputedStyle','appendText','text','querySelectorAll','onDragEnd','onDrag','onDragStart','draggable','innerHtml','insertAdjacentElement','appendHtml','className','children','focus','query','nodes','createShadowRoot','clone','attributes','queryAll','click','onMouseDown','onClick','hidden','addEventListener','onMouseMove','scrollIntoView','onKeyDown','title','getBoundingClientRect','onMouseUp','dispatchEvent','insertAdjacentText','contentEditable','scrollTop','scrollByLines','bind','insertBefore','xtag','insertAdjacentHtml','matches','setAttribute','on','onKeyUp','getElementsByClassName',],
-'dart.dom.html.NodeValidatorBuilder': const ['allowNavigation','allowElement','allowHtml5','allowSvg','allowInlineStyles','allowTextElements','allowTemplating','allowCustomElement','allowTagExtension','allowImages',],
-'dart.dom.html.Console': const ['timeEnd','time','timeStamp','warn','log','error','groupEnd','info','debug','groupCollapsed','group','dir',],
-'dart.dom.html.ElementUpgrader': const ['upgrade',],
-'dart.async.StreamIterator': const ['moveNext','cancel',],
-'dart.io.SystemEncoding': const ['decode',],
-'dart.collection.UnmodifiableListView': const ['where','contains','any','length','join','firstWhere',],
-'dart.core.Error': const ['safeToString','toString',],
-'dart.convert.Utf8Encoder': const ['bind','convert','startChunkedConversion',],
-'dart.dom.html.DomImplementation': const ['createHtmlDocument',],
-'dart.dom.html.DocumentFragment': const ['querySelectorAll','append','clone','nodes','children','setInnerHtml','querySelector','queryAll','query','remove','ownerDocument',],
-'dart.dom.html.ShadowRoot': const ['querySelector','querySelectorAll','host','children','append','contains','query','activeElement','supported','nodes','firstChild','getElementsByTagName','text','innerHtml','olderShadowRoot',],
-'dart.mirrors.TypeMirror': const ['qualifiedName','isSubtypeOf','reflectedType','newInstance','isAssignableTo','simpleName','typeArguments','originalDeclaration','toString','referent','hasReflectedType','isPrivate','typeVariables','owner','invoke','isOriginalDeclaration',],
-'dart.io.ServerSocket': const ['bind','close','listen',],
-'dart.dom.html.PerformanceNavigation': const ['type','redirectCount',],
-'dart.dom.html.Performance': const ['now','timing','navigation',],
-'dart.dom.html.PerformanceTiming': const ['navigationStart',],
-'dart.typed_data.ByteBuffer': const ['asUint8List','asUint32List','asInt32List','asByteData','asFloat64x2List','asInt32x4List','asFloat32x4List','asFloat64List','asFloat32List','asUint64List','asInt64List','asUint16List','asInt16List','asUint8ClampedList','asInt8List',],
-'dart.io.WebSocket': const ['add','listen','close','connect','where','map','send',],
-'dart.convert.JsonEncoder': const ['convert','startChunkedConversion',],
-'dart.convert.JsonDecoder': const ['convert','startChunkedConversion',],
-'dart.core.bool': const ['toString','should','hashCode','isAssignableFrom','parse','containsKey',],
-'dart.core.FormatException': const ['toString',],
-'dart.dom.html.WindowBase': const ['postMessage','navigator','close','alert',],
-'dart.dom.html.ButtonElement': const ['text','onClick','classes','attributes','style','append','type','setInnerHtml','children','onMouseOut','onMouseOver','click','disabled','dataset','appendText',],
-'dart.core.Exception': const ['toString','printStackTrace',],
-'dart.dom.html.DataTransfer': const ['setData','setDragImage','types','effectAllowed','dropEffect','getData','files',],
-'dart.math.Point': const ['x','y','distanceTo','magnitude',],
-'dart.dom.html.LIElement': const ['classes','append','style','text','querySelector','innerHtml','dispatchEvent','children','dataset','className','nodes','remove','value',],
-'dart.dom.html.CanvasRenderingContext2D': const ['lineTo','beginPath','fillRect','moveTo','stroke','drawImage','closePath','restore','translate','save','scale','fill','getImageData','clearRect','setTransform','strokeRect','rotate','putImageData','fillStyle','arc','transform','fillText','strokeStyle','createImageData','createPatternFromImage','clip','lineWidth','drawImageToRect','strokeText','font','rect','drawImageScaledFromSource','setFillColorRgb','createLinearGradient','bezierCurveTo','drawImageScaled','measureText','setLineDash','shadowBlur','shadowOffsetX','shadowOffsetY','shadowColor','quadraticCurveTo','imageSmoothingEnabled','textAlign','createRadialGradient','textBaseline','globalAlpha','lineCap',],
-'dart.io.HeaderValue': const ['parse',],
-'dart.dom.html.ScriptElement': const ['src','type','async','remove','text',],
-'dart.dom.html.MouseEvent': const ['preventDefault','stopPropagation','target','dataTransfer','page','client','ctrlKey','stopImmediatePropagation','metaKey','shiftKey',],
-'dart.io.RawSocket': const ['write','listen','close','connect','read','available','shutdown','setOption',],
-'dart.io.RawSecureSocket': const ['secure','connect','shutdown','listen','secureServer','write','read',],
-'dart.dom.web_sql.SqlDatabase': const ['transaction','supported',],
-'dart.dom.web_sql.SqlTransaction': const ['executeSql',],
-'dart.dom.web_sql.SqlResultSetRowList': const ['length','elementAt','isNotEmpty','item','forEach',],
-'dart.convert.AsciiCodec': const ['encode','decode',],
-'dart.dom.html.EventStreamProvider': const ['forTarget','forElement',],
-'dart.dom.html.MutationObserver': const ['observe','disconnect','takeRecords',],
-'dart.dom.html.UListElement': const ['queryAll','append','style','id','children','remove','query','insertBefore','classes',],
-'dart.dom.html.VideoElement': const ['canPlayType','load','pause','play','autoplay','remove','src',],
-'dart.dom.html.MediaError': const ['code',],
-'dart.dom.html.TimeRanges': const ['start','end',],
-'dart.dom.html.SourceElement': const ['remove',],
-'dart.dom.html.ObjectElement': const ['remove','getAttribute',],
-'dart.dom.html.OptionElement': const ['value','text','selected','label','appendText',],
-'dart.dom.html.SpanElement': const ['classes','text','style','append','appendText','onMouseOut','onMouseOver','onClick','attributes','remove','draggable','id','outerHtml','innerHtml','setAttribute','querySelector','scrollIntoView',],
-'dart.dom.html.Geolocation': const ['getCurrentPosition','watchPosition',],
-'dart.dom.html.Coordinates': const ['accuracy','longitude','latitude','speed','heading','altitudeAccuracy','altitude',],
-'dart.dom.html.ImageElement': const ['remove','width','height','onLoad','src','style','crossOrigin','classes','className','id','onDragStart',],
-'dart.mirrors.MethodMirror': const ['parameters','isGetter','isConstructor','returnType','owner','simpleName','location','source','isStatic',],
-'dart.dom.html.Storage': const ['containsKey','clear','remove','length','keys','containsValue',],
-'dart.convert.ChunkedConversionSink': const ['add','close','specialI',],
-'dart.collection.ListQueue': const ['add','removeFirst','addAll','addLast','removeLast','forEach','toList','removeWhere','addFirst',],
-'dart.dom.html.CanvasElement': const ['getContext','style','width','height','context2D','toDataUrl','getContext3d','onMouseUp','onMouseDown','getBoundingClientRect','onMouseMove','onClick','onMouseOut','className','onMouseOver','setAttribute','remove','context2d','focus',],
-'dart.dom.html.KeyboardEvent': const ['preventDefault','which','stopPropagation','ctrlKey','keyCode','stopImmediatePropagation','metaKey','altKey','shiftKey','getModifierState',],
-'dart.dom.html.WebSocket': const ['send','close','onMessage','onClose','onError','onOpen','readyState','url','sendTypedData','binaryType',],
-'dart.io.WebSocketTransformer': const ['upgrade','isUpgradeRequest',],
-'dart.core.Symbol': const ['toString','length',],
-'dart.js.JsFunction': const ['apply',],
-'dart.io.InternetAddress': const ['address','host','lookup','toString','isLoopback',],
-'dart.convert.Latin1Codec': const ['decode',],
-'dart.dom.html.ElementEvents': const ['click','load','change','keyPress','drop','dragOver','dragEnter','input','keyDown','dragLeave','dragEnd','dragStart','mouseOut','mouseMove','keyUp','loadedMetadata',],
-'dart.dom.html.TableCellElement': const ['setInnerHtml','style','append','text','insertAdjacentElement','colSpan','setAttribute','innerHtml','cellIndex',],
-'dart.dom.html.TableRowElement': const ['append','attributes','classes','onClick','children','onMouseOut','onMouseOver','remove','insertCell','cells','createFragment','addCell','query','outerHtml',],
-'dart.convert.Converter': const ['convert','startChunkedConversion',],
-'dart.dom.html.FormData': const ['append','appendBlob',],
-'dart.io.ProcessException': const ['toString',],
-'dart.dom.html.Text': const ['remove','text','toString',],
-'dart.dom.html.AnchorElement': const ['href','text','onClick','id','classes','append','dispatchEvent','replaceWith','download','click','setAttribute','appendText',],
-'dart.dom.svg.LineElement': const ['setAttribute',],
-'dart.dom.svg.RectElement': const ['setAttribute','attributes',],
-'dart.dom.svg.EllipseElement': const ['setAttribute',],
-'dart.dom.svg.PolylineElement': const ['attributes',],
-'dart.dom.svg.CircleElement': const ['setAttribute',],
-'dart.dom.svg.PathElement': const ['setAttribute','createSvgPathSegLinetoAbs','createSvgPathSegMovetoAbs',],
-'dart.dom.html.HeadingElement': const ['text','classes','appendText','append','id',],
-'dart.dom.html.TableElement': const ['insertRow','createFragment','append','children','createTBody','deleteRow','addRow','query','querySelector',],
-'dart.io.HttpConnectionInfo': const ['remoteAddress','remotePort','localPort','remoteHost',],
-'dart.dom.html.FormElement': const ['append','submit','children','remove',],
-'dart.io.Cookie': const ['value','toString','path',],
-'dart.dom.html.InputElement': const ['focus','select','value','remove','type','checkValidity','dataset','onKeyDown','setSelectionRange','dispatchEvent','selectionStart','selectionEnd','setAttribute','bind','checked','attributes','blur','setRangeText','click','onChange','placeholder','id','onKeyUp','onBlur','onKeyPress','autocomplete','onPaste','defaultChecked','onFocus','disabled',],
-'dart.io.Socket': const ['close','connect','transform','destroy','add','listen','write','addStream','pipe','address','read','writeList','setOption','flush','map','readList','available',],
-'dart.mirrors.ParameterMirror': const ['type','isOptional','defaultValue',],
-'dart.convert.Codec': const ['fuse','encode','decode',],
-'dart.dom.indexed_db.Database': const ['transaction','createObjectStore','close',],
-'dart.dom.indexed_db.Transaction': const ['objectStore','onAbort','onError','onComplete',],
-'dart.dom.indexed_db.ObjectStore': const ['put','delete','createIndex','getObject','index','openCursor','clear',],
-'dart.dom.svg.SvgSvgElement': const ['append','setAttribute','createFragment','createSvgPoint','getScreenCtm','onMouseUp','onMouseMove',],
-'dart.dom.svg.Point': const ['matrixTransform',],
-'dart.dom.svg.Matrix': const ['inverse',],
-'dart.dom.html.WheelEvent': const ['preventDefault','stopPropagation',],
-'dart.dom.svg.AnimatedRect': const ['baseVal',],
-'dart.dom.html.SelectElement': const ['append','focus','remove','classes','tabIndex','options','selectedIndex','querySelectorAll','multiple','value',],
-'dart.dom.html.LabelElement': const ['query','text','append','htmlFor','style','appendText','classes',],
-'dart.io.HttpSession': const ['id','destroy','clear','containsKey','isNew','remove','onTimeout',],
-'dart.dom.indexed_db.IdbFactory': const ['open','deleteDatabase','supported','supportsDatabaseNames','getDatabaseNames',],
-'dart.dom.indexed_db.Request': const ['result',],
-'dart.dom.indexed_db.Index': const ['openCursor',],
-'dart.dom.indexed_db.KeyRange': const ['upperBound_','bound_','lowerBound_','only_',],
-'dart.dom.indexed_db.CursorWithValue': const ['delete',],
-'dart.core.NoSuchMethodError': const ['toString',],
-'dart.isolate.Isolate': const ['spawn','spawnUri','resume','addOnExitListener','removeErrorListener','addErrorListener','kill','ping','pause','setErrorsFatal',],
-'dart.dom.html.TemplateElement': const ['decorate','content',],
-'dart.dom.html.TreeWalker': const ['nextNode',],
-'dart.dom.html.StyleElement': const ['remove','appendText','text','sheet','attributes','type','appendHtml','dataset','append','innerHtml',],
-'dart.dom.html.EventTarget': const ['error','result','matchesWithAncestors','nodeName','matches','classes','dispatchEvent','removeEventListener','addEventListener','status','parent','value','hashCode',],
-'dart.collection_helpers.equality.Equality': const ['hash','equals','isValidKey',],
-'dart.collection_helpers.equality.SetEquality': const ['hash','equals',],
-'dart.collection_helpers.equality.MapEquality': const ['hash','equals',],
-'dart.collection_helpers.equality.ListEquality': const ['hash','equals',],
-'dart.collection_helpers.equality.IterableEquality': const ['hash','equals',],
-'dart.collection_helpers.equality.UnorderedIterableEquality': const ['hash','equals',],
-'dart.io.SecureSocket': const ['initialize','close','connect','listen','write','add','fold','writeln','secure','transform',],
-'dart.io.HttpDate': const ['parse','format',],
-'dart.math.Rectangle': const ['top','left','containsPoint','height','width','topLeft','intersection','topRight','intersects','containsRectangle','boundingBox','snap',],
-'dart.dom.html.ContentElement': const ['getDistributedNodes',],
-'dart.io.SocketException': const ['toString',],
-'dart.dom.html.TextAreaElement': const ['style','focus','select','rows','attributes','setSelectionRange','value','appendText','remove',],
-'dart.dom.html.LinkElement': const ['href','replaceWith','rel',],
-'dart.dom.html.ParagraphElement': const ['text','appendHtml','classes','addHtml','hidden',],
-'dart.typed_data.Int32List': const ['setRange','indexOf','sublist','removeRange','removeLast','clear','addAll','add','setAll',],
-'dart.dom.web_gl.RenderingContext': const ['ARRAY_BUFFER','texParameteri','bindBuffer','bindFramebuffer','TEXTURE_2D','enable','deleteShader','getUniformLocation','bindTexture','clear','createTexture','detachShader','attachShader','getAttribLocation','createBuffer','enableVertexAttribArray','vertexAttribPointer','FLOAT','STATIC_DRAW','createShader','shaderSource','compileShader','viewport','useProgram','clearColor','bufferDataTyped','getShaderParameter','uniformMatrix4fv','getShaderInfoLog','bindRenderbuffer','deleteTexture','deleteProgram','RGBA','linkProgram','createProgram','disableVertexAttribArray','disable','getProgramParameter','blendFunc','drawArrays','getProgramInfoLog','TRIANGLES','lineWidth','COMPILE_STATUS','texImage2DTyped','NEAREST','createFramebuffer','getExtension','framebufferTexture2D','framebufferRenderbuffer','renderbufferStorage','createRenderbuffer','ELEMENT_ARRAY_BUFFER','uniformMatrix3fv','uniform2f','UNSIGNED_BYTE','deleteFramebuffer','deleteRenderbuffer','TEXTURE_MIN_FILTER','TEXTURE_MAG_FILTER','CLAMP_TO_EDGE','DEPTH_TEST','DEPTH_BUFFER_BIT','texImage2DImage','COLOR_BUFFER_BIT','LINK_STATUS','FRAGMENT_SHADER','VERTEX_SHADER','bufferData','TEXTURE_WRAP_S','TEXTURE_WRAP_T','texImage2DCanvas','LINEAR','UNSIGNED_SHORT','texImage2D','drawElements','pixelStorei','colorMask','depthFunc','TRIANGLE_STRIP','activeTexture','TEXTURE0','depthMask','FRAMEBUFFER','UNPACK_FLIP_Y_WEBGL','generateMipmap','uniform1i',],
-'dart.typed_data.Float32List': const ['sublist','indexOf','buffer','setRange','length',],
-'dart.dom.html.DirectoryEntry': const ['getFile','createDirectory','createFile','createReader','getDirectory','removeRecursively','toUrl','fullPath','toString',],
-'dart.dom.html.Entry': const ['moveTo','isFile','copyTo','isDirectory','fullPath','name','remove','getMetadata','createWriter','file','getParent','toUrl',],
-'dart.dom.html.DirectoryReader': const ['readEntries',],
-'dart.dom.html.KeyCode': const ['DOWN','RIGHT','LEFT','TAB','UP','ESC','ENTER','isCharacterKey','SPACE','NUM_SOUTH','NUM_NORTH','NUM_EAST','NUM_WEST','NUM_NORTH_EAST','NUM_SOUTH_EAST','R',],
-'dart.pkg.collection.iterable_zip.IterableZip': const ['map','toList',],
-'dart.convert.LineSplitter': const ['convert',],
-'dart.dom.html.HttpRequestUpload': const ['onProgress','onError','onTimeout',],
-'dart.dom.html.File': const ['name','slice','readAsBytesSync','existsSync',],
-'dart.dom.html.Events': const ['error','message','load','hashChange','popState','resize','loadEnd',],
-'dart.dom.html.Url': const ['createObjectUrl','revokeObjectUrl','createObjectUrlFromBlob','createObjectUrlFromStream',],
-'dart.dom.html.RtcIceCandidate': const ['candidate','sdpMLineIndex',],
-'dart.dom.html.RtcPeerConnection': const ['setLocalDescription','createDataChannel','createOffer','createAnswer',],
-'dart.io.RawDatagramSocket': const ['bind','close','receive','send','listen',],
-'dart.pkg.collection.equality.DeepCollectionEquality': const ['equals','hash',],
-'dart.pkg.collection.priority_queue.PriorityQueue': const ['addAll','contains','removeFirst','add','removeAll',],
-'dart.convert.StringConversionSink': const ['add','asUtf8Sink','close','asStringSink','addSlice',],
-'dart.dom.html.ImageData': const ['data',],
-'dart.dom.html.PreElement': const ['appendText','text','append','classes',],
-'dart.dom.html.MediaStream': const ['stop',],
-'dart.dom.html.DomParser': const ['parseFromString',],
-'dart.dom.html.CustomEvent': const ['stopImmediatePropagation','preventDefault','stopPropagation',],
-'dart.typed_data.Uint16List': const ['buffer','sublist','setRange','removeRange','removeLast','clear','addAll','add','length',],
-'dart.dom.html.CanvasGradient': const ['addColorStop',],
-'dart.dom.html.Notification': const ['requestPermission',],
-'dart.dom.svg.Length': const ['value','valueAsString',],
-'dart.dom.svg.AnimatedLength': const ['baseVal',],
-'dart.dom.svg.PointList': const ['getItem',],
-'dart.mirrors.SourceLocation': const ['line',],
-'dart.DartGrammarDefinition': const ['build',],
-'dart.dom.html.TextMetrics': const ['width',],
-'dart.dom.html.CssRect': const ['width','height','top','left','topLeft',],
-'dart.dom.html.KeyboardEventStream': const ['onKeyDown',],
-'dart.dom.html.CssRule': const ['selectorText',],
-'dart.dom.html.CssStyleRule': const ['style','selectorText',],
-'dart.dom.html.Selection': const ['removeAllRanges','collapse','getRangeAt',],
-'dart.dom.html.CheckboxInputElement': const ['checked','attributes','classes','value',],
-'dart.dom.html.TextInputElement': const ['classes','value','focus','select','className','onKeyDown','style',],
-'dart.dom.html.DateInputElement': const ['classes',],
-'dart.dom.html.RangeInputElement': const ['style','attributes','onChange','value','step','max','min',],
-'dart.dom.html.AnimationTimeline': const ['play',],
-'dart.dom.html.AnimationPlayer': const ['play',],
-'dart.dom.html.GlobalEventHandlers': const ['clickEvent',],
-'dart.dom.html.TouchEvent': const ['preventDefault','supported','stopPropagation',],
-'dart.dom.html.AudioElement': const ['canPlayType','load','append','play','pause','remove',],
-'dart.io.ProcessSignal': const ['watch',],
-'dart.convert.Utf8Decoder': const ['convert','startChunkedConversion',],
-'dart.dom.html.AnimationEvent': const ['preventDefault','stopImmediatePropagation',],
-'dart.dom.html.FocusEvent': const ['stopImmediatePropagation',],
-'dart.dom.html.Touch': const ['page','client',],
-'dart.async.DeferredLibrary': const ['load',],
-'dart.dom.html.TableSectionElement': const ['append','innerHtml','rows','createFragment','addRow',],
-'dart.mirrors.Mirror': const ['methods','invoke','type','delegate','members',],
-'dart.core.StateError': const ['toString',],
-'dart.io.FileMode': const ['APPEND','READ','WRITE',],
-'dart.dom.html.CssStyleDeclarationBase': const ['display','backgroundColor','opacity','borderLeftWidth',],
-'dart.dom.html.IFrameElement': const ['style','src',],
-'dart.io.FileSystemException': const ['toString',],
-'dart.dom.html.Screen': const ['width','height','pixelDepth',],
-'dart.core.ArgumentError': const ['toString',],
-'dart.dom.html.Blob': const ['slice',],
-'dart.dom.svg.PatternElement': const ['setAttribute','append',],
-'dart.dom.svg.DefsElement': const ['append',],
-'dart.dom.svg.PathSegList': const ['appendItem','clear','length','getItem',],
-'dart.dom.html.FileList': const ['length','item',],
-'dart.dom.html.FileError': const ['NOT_FOUND_ERR','code',],
-'dart.mirrors.VariableMirror': const ['type','isFinal','isStatic',],
-'dart.io.HttpStatus': const ['NOT_FOUND',],
-'dart.typed_data.Float64List': const ['sublist','indexOf','setRange',],
-'dart.typed_data.Float32x4': const ['shuffle','shuffleMix','scale','signMask','clamp','withX','withY','w','z','y','x',],
-'dart.pkg.typed_data.typed_buffers.Int32x4Buffer': const ['add',],
-'dart.dom.html.NumberInputElement': const ['step','max','min','valueAsNumber',],
-'dart.dom.html.ValidityState': const ['valid',],
-'dart.dom.html.CssStyleSheet': const ['ownerNode','insertRule','addRule',],
-'dart.io.ZLibCodec': const ['decode',],
-'dart.collection.HasNextIterator': const ['next',],
-'dart.isolate.RawReceivePort': const ['close',],
-'dart.mirrors.TypeVariableMirror': const ['simpleName','isSubtypeOf','isAssignableTo','owner',],
-'dart.typed_data.implementation.NativeByteBuffer': const ['asFloat64List','asFloat32List','asInt32List',],
-'dart.typed_data.implementation.NativeFloat32x4List': const ['length',],
-'dart.typed_data.implementation.NativeFloat32List': const ['sublist',],
-'dart.typed_data.implementation.NativeInt32x4List': const ['length',],
-'dart.typed_data.implementation.NativeFloat64x2List': const ['length',],
-'dart.typed_data.implementation.NativeFloat64List': const ['sublist',],
-'dart.typed_data.implementation.NativeTypedArray': const ['length',],
-'dart.typed_data.implementation.NativeTypedArrayOfDouble': const ['setRange',],
-'dart.typed_data.implementation.NativeTypedArrayOfInt': const ['setRange',],
-'dart.typed_data.implementation.NativeInt32x4': const ['w','z','y','x',],
-'dart.dom.svg.SvgElement': const ['isTagSupported','clone','setAttribute','children','setInnerHtml','attributes',],
-'dart.dom.svg.GElement': const ['append','querySelector','id',],
-'dart.dom.html.ProgressEvent': const ['toString',],
-'dart.core.RangeError': const ['toString','checkValidRange','checkNotNegative','checkValueInInterval','checkValidIndex',],
-'dart.dom.html.TouchList': const ['length','first','isEmpty','isNotEmpty',],
-'dart.dom.html.FieldSetElement': const ['append','querySelector',],
-'dart.dom.html.ShadowElement': const ['getDistributedNodes',],
-'dart.dom.html.KeyEvent': const ['keyCode','type','preventDefault',],
-'dart.dom.html.NodeList': const ['length','add',],
-'dart.dom.html.DomStringList': const ['length',],
-'dart.dom.html.HtmlCollection': const ['length','forEach','contains',],
-'dart.dom.html.Range': const ['createContextualFragment','selectNodeContents','insertNode','setEndAfter',],
-'dart.dom.html.NodeTreeSanitizer': const ['sanitizeTree',],
-'dart.dom.html.MimeTypeArray': const ['length',],
-'dart.dom.html.PluginArray': const ['length',],
-'dart.dom.html.SourceBufferList': const ['length',],
-'dart.dom.html.SpeechGrammarList': const ['length',],
-'dart.dom.html.TextTrackCueList': const ['length',],
-'dart.dom.html.TextTrackList': const ['length',],
-'dart.dom.html.Dimension': const ['value','toString',],
-'dart.dom.html.UriPolicy': const ['allowsUri',],
-'dart.dom.html.NodeValidator': const ['allowsAttribute','allowsElement',],
-'dart.dom.html.Worker': const ['terminate',],
-'dart.typed_data.Int16List': const ['sublist','buffer','contains','setRange','removeRange','removeLast','clear','addAll','add',],
-'dart.dom.indexed_db.Cursor': const ['next',],
-'dart.dom.svg.LengthList': const ['length','getItem',],
-'dart.dom.svg.NumberList': const ['length','getItem',],
-'dart.dom.svg.StringList': const ['length','getItem',],
-'dart.dom.svg.TransformList': const ['length','getItem',],
-'dart.js.JsArray': const ['length','addAll','insert','removeRange','removeAt','add','setRange','removeLast',],
-'dart.dom.html.ApplicationCache': const ['swapCache',],
-'dart.dom.web_audio.AudioContext': const ['createBufferSource','createOscillator','destination','createPanner','createGain',],
-'dart.dom.html.FileUploadInputElement': const ['click',],
-'dart.dom.html.DomRectReadOnly': const ['top','left','height','width',],
-'dart.typed_data.Int8List': const ['sublist','setRange','removeRange','removeLast','clear','addAll','add','buffer',],
-'dart.dom.web_audio.AudioBufferSourceNode': const ['connectNode','start','stop',],
-'dart.dom.html.FileEntry': const ['file','getParent','toUrl','getMetadata',],
-'dart.dom.html.CustomStream': const ['listen',],
-'dart.dom.html.TrackElement': const ['defaultValue',],
-'dart.dom.web_audio.OscillatorNode': const ['connectNode',],
-'dart.dom.html.StorageQuota': const ['queryInfo',],
-'dart.collection.DoubleLinkedQueue': const ['add',],
-'dart.core.TypeError': const ['toString',],
-'dart.core.AssertionError': const ['toString',],
-'dart.profiler.Metrics': const ['register',],
-'dart.collection.LinkedList': const ['remove','addFirst','clear','add',],
-'dart.typed_data.Uint8ClampedList': const ['sublist',],
-'dart.typed_data.Float64x2': const ['y','x','withX',],
-'dart.convert.ByteConversionSink': const ['close','add','addSlice',],
-'dart.convert.ClosableStringSink': const ['close','write',],
-'dart.mirrors.TypedefMirror': const ['isSubtypeOf','isAssignableTo','referent',],
-'dart.mirrors.FunctionTypeMirror': const ['isSubtypeOf','isAssignableTo','returnType','parameters','isOriginalDeclaration',],
-'dart.mirrors.LibraryDependencyMirror': const ['metadata',],
-'dart.test.stream_from_iterable.IterableTest': const ['run',],
-'dart.io.SecureServerSocket': const ['bind','close','listen',],
-'dart.io.RawServerSocket': const ['bind','listen','close',],
-'dart.typed_data.Uint64List': const ['sublist','setRange','removeRange','removeLast','clear','addAll','add',],
-'dart.typed_data.Int64List': const ['sublist','setRange','removeRange','removeLast','clear','addAll','add',],
-'dart.io.StdioType': const ['name',],
-'dart.io.HttpConnectionsInfo': const ['total','idle','active',],
-'dart.io.RawSecureServerSocket': const ['bind','close','listen',],
-'dart.io.ServerSocketReference': const ['create',],
-'dart.io.NetworkInterface': const ['list',],
-'dart.io.ZLibDecoder': const ['convert',],
-'dart.io.ZLibEncoder': const ['convert',],
-'dart.pkg.async.results.ValueResult': const ['value',],
-'dart.pkg.async.stream_zip.StreamZip': const ['toList',],
-'dart.pkg.async.results.Result': const ['flatten','release',],
-'dart.pkg.async.results.ErrorResult': const ['stackTrace','error',],
-'dart.dom.html.OptGroupElement': const ['append',],
-'dart.dom.html.UnknownElement': const ['query',],
-'dart.dom.web_audio.AudioParam': const ['value','setValueAtTime',],
-'dart.dom.html.RadioButtonInputElement': const ['checked',],
-'dart.dom.web_audio.BiquadFilterNode': const ['connectNode',],
-'dart.async.StreamConsumer': const ['addStream','close',],
-'dart.dom.html.FileSystem': const ['root',],
-'dart.dom.html.FileWriter': const ['write','abort',],
-'dart.dom.html.OutputElement': const ['scrollIntoView',],
-'dart.dom.html.Css': const ['supports',],
-'dart.io.IOException': const ['toString',],
-'dart.dom.html.ButtonInputElement': const ['value','onClick',],
-};
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_core.dart b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
index 68fa732..e0635aa 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
@@ -2,9 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analysis_server.src.services.completion.completion_dart;
+library analysis_server.src.services.completion.completion_core;
 
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -13,29 +15,58 @@
  * The information about a requested list of completions.
  */
 class CompletionRequestImpl implements CompletionRequest {
-  /**
-   * The analysis context in which the completion is being requested.
-   */
-  AnalysisContext context;
+  @override
+  final AnalysisContext context;
+
+  @override
+  final Source source;
+
+  @override
+  final int offset;
 
   /**
-   * The resource provider associated with this request.
+   * The offset of the start of the text to be replaced.
+   * This will be different than the [offset] used to request the completion
+   * suggestions if there was a portion of an identifier before the original
+   * [offset]. In particular, the [replacementOffset] will be the offset of the
+   * beginning of said identifier.
    */
-  ResourceProvider resourceProvider;
+  int replacementOffset;
 
   /**
-   * The source in which the completion is being requested.
+   * The length of the text to be replaced if the remainder of the identifier
+   * containing the cursor is to be replaced when the suggestion is applied
+   * (that is, the number of characters in the existing identifier).
+   * This will be different than the [replacementOffset] - [offset]
+   * if the [offset] is in the middle of an existing identifier.
    */
-  Source source;
+  int replacementLength;
 
-  /**
-   * The offset within the source at which the completion is being requested.
-   */
-  int offset;
+  @override
+  final ResourceProvider resourceProvider;
+
+  @override
+  final SearchEngine searchEngine;
+
+  final CompletionPerformance performance;
 
   /**
    * Initialize a newly created completion request based on the given arguments.
    */
-  CompletionRequestImpl(
-      this.context, this.resourceProvider, this.source, this.offset);
+  CompletionRequestImpl(this.context, this.resourceProvider, this.searchEngine,
+      this.source, this.offset, this.performance) {
+    replacementOffset = offset;
+    replacementLength = 0;
+  }
+
+  /**
+   * Return the original text from the [replacementOffset] to the [offset]
+   * that can be used to filter the suggestions on the server side.
+   */
+  String get filterText {
+    return context
+        .getContents(source)
+        .data
+        .substring(replacementOffset, offset);
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_dart.dart b/pkg/analysis_server/lib/src/services/completion/completion_dart.dart
deleted file mode 100644
index 1cfff04..0000000
--- a/pkg/analysis_server/lib/src/services/completion/completion_dart.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analysis_server.src.services.completion.completion_dart;
-
-import 'package:analysis_server/src/provisional/completion/completion_core.dart';
-import 'package:analysis_server/src/provisional/completion/completion_dart.dart';
-import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
-import 'package:analysis_server/src/services/completion/completion_core.dart';
-import 'package:analyzer/src/generated/ast.dart';
-
-/**
- * The information about a requested list of completions within a Dart file.
- */
-class DartCompletionRequestImpl extends CompletionRequestImpl
-    implements DartCompletionRequest {
-  /**
-   * The compilation unit in which the completion was requested.
-   */
-  final CompilationUnit unit;
-
-  /**
-   * A flag indicating whether the compilation [unit] is resolved.
-   */
-  final bool isResolved;
-
-  /**
-   * The completion target.  This determines what part of the parse tree
-   * will receive the newly inserted text.
-   */
-  final CompletionTarget target;
-
-  /**
-   * Initialize a newly created completion request based on the given arguments.
-   */
-  DartCompletionRequestImpl(
-      CompletionRequest request, this.unit, this.isResolved, this.target)
-      : super(request.context, request.resourceProvider, request.source,
-            request.offset);
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/completion_manager.dart
deleted file mode 100644
index 2ba4340..0000000
--- a/pkg/analysis_server/lib/src/services/completion/completion_manager.dart
+++ /dev/null
@@ -1,306 +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 services.completion.manager;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart'
-    show CompletionRequest, CompletionResult;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * [CompletionCache] contains information about the prior code completion
- * for use in the next code completion.
- */
-abstract class CompletionCache {
-  /**
-   * The context in which the completion was computed.
-   */
-  final AnalysisContext context;
-
-  /**
-   * The source in which the completion was computed.
-   */
-  final Source source;
-
-  CompletionCache(this.context, this.source);
-}
-
-/**
- * Manages completion contributors for a given completion request.
- */
-abstract class CompletionManager {
-  /**
-   * The context in which the completion was computed.
-   */
-  final AnalysisContext context;
-
-  /**
-   * The source in which the completion was computed.
-   */
-  final Source source;
-
-  /**
-   * The controller used for returning completion results.
-   */
-  StreamController<CompletionResult> controller;
-
-  CompletionManager(this.context, this.source);
-
-  /**
-   * Create a manager for the given request.
-   */
-  factory CompletionManager.create(
-      AnalysisContext context, Source source, SearchEngine searchEngine) {
-    if (context != null) {
-      if (AnalysisEngine.isDartFileName(source.shortName)) {
-        return new DartCompletionManager.create(context, searchEngine, source);
-      }
-      if (AnalysisEngine.isHtmlFileName(source.shortName)) {
-        //TODO (danrubel) implement
-//        return new HtmlCompletionManager(context, searchEngine, source, offset);
-      }
-    }
-    return new NoOpCompletionManager(source);
-  }
-
-  /**
-   * Compute and cache information in preparation for a possible code
-   * completion request sometime in the future. The default implementation
-   * of this method does nothing. Subclasses may override but should not
-   * count on this method being called before [computeSuggestions].
-   * Return a future that completes when the cache is computed with a bool
-   * indicating success.
-   */
-  Future<bool> computeCache() {
-    return new Future.value(true);
-  }
-
-  /**
-   * Compute completion results for the given reqeust and append them to the stream.
-   * Clients should not call this method directly as it is automatically called
-   * when a client listens to the stream returned by [results].
-   * Subclasses should override this method, append at least one result
-   * to the [controller], and close the controller stream once complete.
-   */
-  void computeSuggestions(CompletionRequest request);
-
-  /**
-   * Discard any pending operations.
-   * Subclasses may override but should call super.dispose
-   */
-  void dispose() {}
-
-  /**
-   * Generate a stream of code completion results.
-   */
-  Stream<CompletionResult> results(CompletionRequest request) {
-    controller = new StreamController<CompletionResult>(onListen: () {
-      scheduleMicrotask(() {
-        computeSuggestions(request);
-      });
-    });
-    return controller.stream;
-  }
-}
-
-/**
- * Overall performance of a code completion operation.
- */
-class CompletionPerformance {
-  final DateTime start = new DateTime.now();
-  final Map<String, Duration> _startTimes = new Map<String, Duration>();
-  final Stopwatch _stopwatch = new Stopwatch();
-  final List<OperationPerformance> operations = <OperationPerformance>[];
-
-  Source source;
-  String snippet = '';
-  int notificationCount = -1;
-  int suggestionCountFirst = -1;
-  int suggestionCountLast = -1;
-  Duration _firstNotification;
-
-  CompletionPerformance() {
-    _stopwatch.start();
-  }
-
-  int get elapsedInMilliseconds =>
-      operations.length > 0 ? operations.last.elapsed.inMilliseconds : 0;
-
-  int get firstNotificationInMilliseconds =>
-      _firstNotification != null ? _firstNotification.inMilliseconds : 0;
-
-  String get startTimeAndMs => '${start.millisecondsSinceEpoch} - $start';
-
-  String get suggestionCount {
-    if (notificationCount < 1) return '';
-    if (notificationCount == 1) return '$suggestionCountFirst';
-    return '$suggestionCountFirst,  $suggestionCountLast';
-  }
-
-  void complete([String tag = null]) {
-    _stopwatch.stop();
-    _logDuration(tag != null ? tag : 'total time', _stopwatch.elapsed);
-  }
-
-  logElapseTime(String tag, [f() = null]) {
-    Duration start;
-    Duration end = _stopwatch.elapsed;
-    var result;
-    if (f == null) {
-      start = _startTimes[tag];
-      if (start == null) {
-        _logDuration(tag, null);
-        return null;
-      }
-    } else {
-      result = f();
-      start = end;
-      end = _stopwatch.elapsed;
-    }
-    _logDuration(tag, end - start);
-    return result;
-  }
-
-  void logFirstNotificationComplete(String tag) {
-    _firstNotification = _stopwatch.elapsed;
-    _logDuration(tag, _firstNotification);
-  }
-
-  void logStartTime(String tag) {
-    _startTimes[tag] = _stopwatch.elapsed;
-  }
-
-  void setContentsAndOffset(String contents, int offset) {
-    snippet = _computeSnippet(contents, offset);
-  }
-
-  void _logDuration(String tag, Duration elapsed) {
-    operations.add(new OperationPerformance(tag, elapsed));
-  }
-
-  static String _computeSnippet(String contents, int offset) {
-    if (contents == null ||
-        offset == null ||
-        offset < 0 ||
-        contents.length < offset) {
-      return '???';
-    }
-    int start = offset;
-    while (start > 0) {
-      String ch = contents[start - 1];
-      if (ch == '\r' || ch == '\n') {
-        break;
-      }
-      --start;
-    }
-    int end = offset;
-    while (end < contents.length) {
-      String ch = contents[end];
-      if (ch == '\r' || ch == '\n') {
-        break;
-      }
-      ++end;
-    }
-    String prefix = contents.substring(start, offset);
-    String suffix = contents.substring(offset, end);
-    return '$prefix^$suffix';
-  }
-}
-
-/**
- * Encapsulates information specific to a particular completion request.
- */
-class CompletionRequestImpl implements CompletionRequest {
-  /**
-   * The underlying analysis server for this completion request.
-   */
-  final AnalysisServer server;
-
-  @override
-  final AnalysisContext context;
-
-  @override
-  final Source source;
-
-  @override
-  final int offset;
-
-  CompletionRequestImpl(this.server, this.context, this.source, this.offset);
-
-  @override
-  ResourceProvider get resourceProvider => server.resourceProvider;
-}
-
-/**
- * Code completion result generated by an [CompletionManager].
- */
-class CompletionResultImpl implements CompletionResult {
-  /**
-   * The length of the text to be replaced if the remainder of the identifier
-   * containing the cursor is to be replaced when the suggestion is applied
-   * (that is, the number of characters in the existing identifier).
-   */
-  final int replacementLength;
-
-  /**
-   * The offset of the start of the text to be replaced. This will be different
-   * than the offset used to request the completion suggestions if there was a
-   * portion of an identifier before the original offset. In particular, the
-   * replacementOffset will be the offset of the beginning of said identifier.
-   */
-  final int replacementOffset;
-
-  /**
-   * The suggested completions.
-   */
-  final List<CompletionSuggestion> suggestions;
-
-  /**
-   * `true` if this is that last set of results that will be returned
-   * for the indicated completion.
-   */
-  final bool last;
-
-  CompletionResultImpl(this.replacementOffset, this.replacementLength,
-      this.suggestions, this.last);
-
-  /**
-   * Return `true` if this is the last completion result that will be produced.
-   */
-  bool get isLast => last;
-}
-
-class NoOpCompletionManager extends CompletionManager {
-  NoOpCompletionManager(Source source) : super(null, source);
-
-  @override
-  void computeSuggestions(CompletionRequest request) {
-    controller.add(new CompletionResultImpl(request.offset, 0, [], true));
-  }
-}
-
-/**
- * The performance of an operation when computing code completion.
- */
-class OperationPerformance {
-  /**
-   * The name of the operation
-   */
-  final String name;
-
-  /**
-   * The elapse time or `null` if undefined.
-   */
-  final Duration elapsed;
-
-  OperationPerformance(this.name, this.elapsed);
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
new file mode 100644
index 0000000..0272fb8
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
@@ -0,0 +1,119 @@
+// 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 services.completion.manager;
+
+import 'package:analyzer/src/generated/source.dart';
+
+/**
+ * Overall performance of a code completion operation.
+ */
+class CompletionPerformance {
+  final DateTime start = new DateTime.now();
+  final Map<String, Duration> _startTimes = new Map<String, Duration>();
+  final Stopwatch _stopwatch = new Stopwatch();
+  final List<OperationPerformance> operations = <OperationPerformance>[];
+
+  Source source;
+  String snippet = '';
+  int notificationCount = -1;
+  int suggestionCountFirst = -1;
+  int suggestionCountLast = -1;
+  Duration _firstNotification;
+
+  CompletionPerformance() {
+    _stopwatch.start();
+  }
+
+  int get elapsedInMilliseconds =>
+      operations.length > 0 ? operations.last.elapsed.inMilliseconds : 0;
+
+  int get firstNotificationInMilliseconds =>
+      _firstNotification != null ? _firstNotification.inMilliseconds : 0;
+
+  String get startTimeAndMs => '${start.millisecondsSinceEpoch} - $start';
+
+  String get suggestionCount {
+    if (notificationCount < 1) return '';
+    if (notificationCount == 1) return '$suggestionCountFirst';
+    return '$suggestionCountFirst,  $suggestionCountLast';
+  }
+
+  void complete([String tag = null]) {
+    _stopwatch.stop();
+    _logDuration(tag != null ? tag : 'total time', _stopwatch.elapsed);
+  }
+
+  void logElapseTime(String tag) {
+    Duration end = _stopwatch.elapsed;
+    Duration start = _startTimes[tag];
+    if (start == null) {
+      _logDuration(tag, null);
+      return null;
+    }
+    _logDuration(tag, end - start);
+  }
+
+  void logFirstNotificationComplete(String tag) {
+    _firstNotification = _stopwatch.elapsed;
+    _logDuration(tag, _firstNotification);
+  }
+
+  void logStartTime(String tag) {
+    _startTimes[tag] = _stopwatch.elapsed;
+  }
+
+  void setContentsAndOffset(String contents, int offset) {
+    snippet = _computeSnippet(contents, offset);
+  }
+
+  void _logDuration(String tag, Duration elapsed) {
+    operations.add(new OperationPerformance(tag, elapsed));
+  }
+
+  static String _computeSnippet(String contents, int offset) {
+    if (contents == null ||
+        offset == null ||
+        offset < 0 ||
+        contents.length < offset) {
+      return '???';
+    }
+    int start = offset;
+    while (start > 0) {
+      String ch = contents[start - 1];
+      if (ch == '\r' || ch == '\n') {
+        break;
+      }
+      --start;
+    }
+    int end = offset;
+    while (end < contents.length) {
+      String ch = contents[end];
+      if (ch == '\r' || ch == '\n') {
+        break;
+      }
+      ++end;
+    }
+    String prefix = contents.substring(start, offset);
+    String suffix = contents.substring(offset, end);
+    return '$prefix^$suffix';
+  }
+}
+
+/**
+ * The performance of an operation when computing code completion.
+ */
+class OperationPerformance {
+  /**
+   * The name of the operation
+   */
+  final String name;
+
+  /**
+   * The elapse time or `null` if undefined.
+   */
+  final Duration elapsed;
+
+  OperationPerformance(this.name, this.elapsed);
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/contribution_sorter.dart b/pkg/analysis_server/lib/src/services/completion/contribution_sorter.dart
deleted file mode 100644
index 3d9dd87..0000000
--- a/pkg/analysis_server/lib/src/services/completion/contribution_sorter.dart
+++ /dev/null
@@ -1,26 +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 services.completion.sorter;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/provisional/completion/completion_dart.dart';
-
-/**
- * The abstract class `ContributionSorter` defines the behavior of objects
- * that are used to adjust the relevance of an existing list of suggestions.
- * This is a long-lived object that should not maintain state between
- * calls to it's [sort] method.
- */
-abstract class ContributionSorter {
-  /**
-   * After [CompletionSuggestion]s have been computed,
-   * this method is called to adjust the relevance of those suggestions.
-   * The compilation unit and completion node
-   * in the given completion context may not be resolved.
-   * This method should execute quickly and not block.
-   */
-  void sort(DartCompletionRequest request,
-      Iterable<CompletionSuggestion> suggestions);
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
new file mode 100644
index 0000000..5036e08
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -0,0 +1,262 @@
+// 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 services.completion.contributor.dart.arglist;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/protocol_server.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * Determine the number of arguments.
+ */
+int _argCount(DartCompletionRequest request) {
+  AstNode node = request.target.containingNode;
+  if (node is ArgumentList) {
+    return node.arguments.length;
+  }
+  return 0;
+}
+
+/**
+ * If the containing [node] is an argument list
+ * or named expression in an argument list
+ * then return the simple identifier for the method, constructor, or annotation
+ * to which the argument list is associated
+ */
+SimpleIdentifier _getTargetId(AstNode node) {
+  if (node is NamedExpression) {
+    return _getTargetId(node.parent);
+  }
+  if (node is ArgumentList) {
+    AstNode parent = node.parent;
+    if (parent is MethodInvocation) {
+      return parent.methodName;
+    }
+    if (parent is InstanceCreationExpression) {
+      ConstructorName constructorName = parent.constructorName;
+      if (constructorName != null) {
+        if (constructorName.name != null) {
+          return constructorName.name;
+        }
+        Identifier typeName = constructorName.type.name;
+        if (typeName is SimpleIdentifier) {
+          return typeName;
+        }
+        if (typeName is PrefixedIdentifier) {
+          return typeName.identifier;
+        }
+      }
+    }
+    if (parent is Annotation) {
+      return parent.constructorName ?? parent.name;
+    }
+  }
+  return null;
+}
+
+/**
+ * Determine if the completion target is at the end of the list of arguments.
+ */
+bool _isAppendingToArgList(DartCompletionRequest request) {
+  AstNode node = request.target.containingNode;
+  if (node is ArgumentList) {
+    var entity = request.target.entity;
+    if (entity == node.rightParenthesis) {
+      return true;
+    }
+    if (node.arguments.length > 0 && node.arguments.last == entity) {
+      return entity is SimpleIdentifier;
+    }
+  }
+  return false;
+}
+
+/**
+ * Determine if the completion target is the label for a named argument.
+ */
+bool _isEditingNamedArgLabel(DartCompletionRequest request) {
+  AstNode node = request.target.containingNode;
+  if (node is ArgumentList) {
+    var entity = request.target.entity;
+    if (entity is NamedExpression) {
+      int offset = request.offset;
+      if (entity.offset <= offset && offset < entity.end) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+/**
+ * Determine if the completion target is an emtpy argument list.
+ */
+bool _isEmptyArgList(DartCompletionRequest request) {
+  AstNode node = request.target.containingNode;
+  return node is ArgumentList &&
+      node.leftParenthesis.next == node.rightParenthesis;
+}
+
+/**
+ * Return a collection of currently specified named arguments
+ */
+Iterable<String> _namedArgs(DartCompletionRequest request) {
+  AstNode node = request.target.containingNode;
+  List<String> namedArgs = new List<String>();
+  if (node is ArgumentList) {
+    for (Expression arg in node.arguments) {
+      if (arg is NamedExpression) {
+        namedArgs.add(arg.name.label.name);
+      }
+    }
+  }
+  return namedArgs;
+}
+
+/**
+ * A contributor for calculating `completion.getSuggestions` request results
+ * when the cursor position is inside the arguments to a method call.
+ */
+class ArgListContributor extends DartCompletionContributor {
+  DartCompletionRequest request;
+  List<CompletionSuggestion> suggestions;
+
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    this.request = request;
+    this.suggestions = <CompletionSuggestion>[];
+
+    // Determine if the target is in an argument list
+    // for a method or a constructor or an annotation
+    // and resolve the identifier
+    SimpleIdentifier targetId = _getTargetId(request.target.containingNode);
+    if (targetId == null) {
+      return EMPTY_LIST;
+    }
+
+    // Resolve the target expression to determine the arguments
+    await request.resolveExpression(targetId);
+    // Gracefully degrade if the element could not be resolved
+    // e.g. target changed, completion aborted
+    targetId = _getTargetId(request.target.containingNode);
+    if (targetId == null) {
+      return EMPTY_LIST;
+    }
+    Element elem = targetId.bestElement;
+    if (elem == null) {
+      return EMPTY_LIST;
+    }
+
+    // Generate argument list suggestion based upon the type of element
+    if (elem is ClassElement) {
+      for (ConstructorElement constructor in elem.constructors) {
+        if (!constructor.isFactory) {
+          _addSuggestions(constructor.parameters);
+          return suggestions;
+        }
+      }
+    }
+    if (elem is ConstructorElement) {
+      _addSuggestions(elem.parameters);
+      return suggestions;
+    }
+    if (elem is FunctionElement) {
+      _addSuggestions(elem.parameters);
+      return suggestions;
+    }
+    if (elem is MethodElement) {
+      _addSuggestions(elem.parameters);
+      return suggestions;
+    }
+    return EMPTY_LIST;
+  }
+
+  void _addArgListSuggestion(Iterable<ParameterElement> requiredParam) {
+    // DEPRECATED... argument lists are no longer suggested.
+    // See https://github.com/dart-lang/sdk/issues/25197
+
+    // String _getParamType(ParameterElement param) {
+    //   DartType type = param.type;
+    //   if (type != null) {
+    //     return type.displayName;
+    //   }
+    //   return 'dynamic';
+    // }
+
+    // StringBuffer completion = new StringBuffer('(');
+    // List<String> paramNames = new List<String>();
+    // List<String> paramTypes = new List<String>();
+    // for (ParameterElement param in requiredParam) {
+    //   String name = param.name;
+    //   if (name != null && name.length > 0) {
+    //     if (completion.length > 1) {
+    //       completion.write(', ');
+    //     }
+    //     completion.write(name);
+    //     paramNames.add(name);
+    //     paramTypes.add(_getParamType(param));
+    //   }
+    // }
+    // completion.write(')');
+    // CompletionSuggestion suggestion = new CompletionSuggestion(
+    //     CompletionSuggestionKind.ARGUMENT_LIST,
+    //     DART_RELEVANCE_HIGH,
+    //     completion.toString(),
+    //     completion.length,
+    //     0,
+    //     false,
+    //     false);
+    // suggestion.parameterNames = paramNames;
+    // suggestion.parameterTypes = paramTypes;
+    // suggestions.add(suggestion);
+  }
+
+  void _addDefaultParamSuggestions(Iterable<ParameterElement> parameters) {
+    Iterable<String> namedArgs = _namedArgs(request);
+    for (ParameterElement param in parameters) {
+      if (param.parameterKind == ParameterKind.NAMED) {
+        _addNamedParameterSuggestion(request, namedArgs, param.name);
+      }
+    }
+  }
+
+  void _addNamedParameterSuggestion(
+      DartCompletionRequest request, List<String> namedArgs, String name) {
+    if (name != null && name.length > 0 && !namedArgs.contains(name)) {
+      suggestions.add(new CompletionSuggestion(
+          CompletionSuggestionKind.NAMED_ARGUMENT,
+          DART_RELEVANCE_NAMED_PARAMETER,
+          '$name: ',
+          name.length + 2,
+          0,
+          false,
+          false));
+    }
+  }
+
+  void _addSuggestions(Iterable<ParameterElement> parameters) {
+    if (parameters == null || parameters.length == 0) {
+      return;
+    }
+    Iterable<ParameterElement> requiredParam = parameters.where(
+        (ParameterElement p) => p.parameterKind == ParameterKind.REQUIRED);
+    int requiredCount = requiredParam.length;
+    if (requiredCount > 0 && _isEmptyArgList(request)) {
+      _addArgListSuggestion(requiredParam);
+      return;
+    }
+    if (_isEditingNamedArgLabel(request) || _isAppendingToArgList(request)) {
+      if (requiredCount == 0 || requiredCount < _argCount(request)) {
+        _addDefaultParamSuggestions(parameters);
+      }
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
new file mode 100644
index 0000000..26437e2
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -0,0 +1,43 @@
+// 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 services.completion.contributor.dart.combinator;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/protocol_server.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+
+/**
+ * A contributor for calculating `completion.getSuggestions` request results
+ * for the import combinators show and hide.
+ */
+class CombinatorContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    AstNode node = request.target.containingNode;
+    if (node is! Combinator) {
+      return EMPTY_LIST;
+    }
+
+    // Build list of suggestions
+    var directive = node.getAncestor((parent) => parent is NamespaceDirective);
+    if (directive is NamespaceDirective) {
+      LibraryElement library = directive.uriElement;
+      if (library != null) {
+        LibraryElementSuggestionBuilder builder =
+            new LibraryElementSuggestionBuilder(request.libraryElement,
+                CompletionSuggestionKind.IDENTIFIER, false, false);
+        library.visitChildren(builder);
+        return builder.suggestions;
+      }
+    }
+    return EMPTY_LIST;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
new file mode 100644
index 0000000..6e8049b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
@@ -0,0 +1,164 @@
+// 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 services.completion.dart.sorter.common;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analysis_server/src/protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+
+part 'common_usage_sorter.g.dart';
+
+/**
+ * A computer for adjusting the relevance of completions computed by others
+ * based upon common Dart usage patterns. This is a long-lived object
+ * that should not maintain state between calls to it's [sort] method.
+ */
+class CommonUsageSorter implements DartContributionSorter {
+  /**
+   * A map of <library>.<classname> to an ordered list of method names,
+   * field names, getter names, and named constructors.
+   * The names are ordered from most relevant to least relevant.
+   * Names not listed are considered equally less relevant than those listed.
+   */
+  Map<String, List<String>> selectorRelevance;
+
+  CommonUsageSorter([this.selectorRelevance = defaultSelectorRelevance]);
+
+  @override
+  Future sort(DartCompletionRequest request,
+      Iterable<CompletionSuggestion> suggestions) {
+    _update(request, suggestions);
+    return new Future.value();
+  }
+
+  CompletionTarget _getCompletionTarget(CompletionRequest request) {
+    // TODO (danrubel) get cached completion target
+    var libSrcs = request.context.getLibrariesContaining(request.source);
+    if (libSrcs.length == 0) {
+      return null;
+    }
+    var libElem = request.context.getResult(libSrcs[0], LIBRARY_ELEMENT1);
+    if (libElem is LibraryElement) {
+      var unit = request.context.getResult(
+          new LibrarySpecificUnit(libElem.source, request.source),
+          RESOLVED_UNIT3);
+      if (unit is CompilationUnit) {
+        return new CompletionTarget.forOffset(unit, request.offset);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Adjusts the relevance based on the given completion context.
+   * The compilation unit and completion node
+   * in the given completion context may not be resolved.
+   */
+  void _update(
+      CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
+    var target = _getCompletionTarget(request);
+    if (target != null) {
+      var visitor = new _BestTypeVisitor(target.entity);
+      DartType type = target.containingNode.accept(visitor);
+      if (type != null) {
+        Element typeElem = type.element;
+        if (typeElem != null) {
+          LibraryElement libElem = typeElem.library;
+          if (libElem != null) {
+            _updateInvocationRelevance(type, libElem, suggestions);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Adjusts the relevance of all method suggestions based upon the given
+   * target type and library.
+   */
+  void _updateInvocationRelevance(DartType type, LibraryElement libElem,
+      Iterable<CompletionSuggestion> suggestions) {
+    String typeName = type.name;
+    List<String> selectors = selectorRelevance['${libElem.name}.$typeName'];
+    if (selectors != null) {
+      for (CompletionSuggestion suggestion in suggestions) {
+        protocol.Element element = suggestion.element;
+        if (element != null &&
+            (element.kind == protocol.ElementKind.CONSTRUCTOR ||
+                element.kind == protocol.ElementKind.FIELD ||
+                element.kind == protocol.ElementKind.GETTER ||
+                element.kind == protocol.ElementKind.METHOD ||
+                element.kind == protocol.ElementKind.SETTER) &&
+            suggestion.kind == CompletionSuggestionKind.INVOCATION &&
+            suggestion.declaringType == typeName) {
+          int index = selectors.indexOf(suggestion.completion);
+          if (index != -1) {
+            suggestion.relevance = DART_RELEVANCE_COMMON_USAGE - index;
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
+ * An [AstVisitor] used to determine the best defining type of a node.
+ */
+class _BestTypeVisitor extends GeneralizingAstVisitor {
+  /**
+   * The entity which the completed text will replace (or which will be
+   * displaced once the completed text is inserted).  This may be an AstNode or
+   * a Token, or it may be null if the cursor is after all tokens in the file.
+   * See field of the same name in [CompletionTarget].
+   */
+  final Object entity;
+
+  _BestTypeVisitor(this.entity);
+
+  DartType visitConstructorName(ConstructorName node) {
+    if (node.period != null && node.name == entity) {
+      TypeName typeName = node.type;
+      if (typeName != null) {
+        return typeName.type;
+      }
+    }
+    return null;
+  }
+
+  DartType visitNode(AstNode node) {
+    return null;
+  }
+
+  DartType visitPrefixedIdentifier(PrefixedIdentifier node) {
+    if (node.identifier == entity) {
+      SimpleIdentifier prefix = node.prefix;
+      if (prefix != null) {
+        return prefix.bestType;
+      }
+    }
+    return null;
+  }
+
+  DartType visitPropertyAccess(PropertyAccess node) {
+    if (node.propertyName == entity) {
+      Expression target = node.realTarget;
+      if (target != null) {
+        return target.bestType;
+      }
+    }
+    return null;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart
new file mode 100644
index 0000000..f065701
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart
@@ -0,0 +1,427 @@
+// 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 services.completion.dart.sorter.common;
+
+// Auto-generated, please do not edit.
+
+/**
+ * A map of <library>.<classname> to an ordered list of method names,
+ * field names, getter names, and named constructors.
+ * The names are ordered from most relevant to least relevant.
+ * Names not listed are considered equally less relevant than those listed.
+ */
+const Map<String, List<String>> defaultSelectorRelevance = const {
+'dart.core.Comparable': const ['compareTo','compare',],
+'dart.math.Random': const ['nextInt','nextDouble','nextBool',],
+'dart.core.List': const ['add','map','length','removeLast','addAll','join','forEach','contains','removeAt','where','last','clear','setRange','sort','insert','remove','sublist','indexOf','isEmpty','any','insertAll','first','removeRange','replaceRange','take','getRange','skip','toList','retainWhere','fillRange','removeWhere','expand','fold','reversed','firstWhere','every','setAll','asMap','isNotEmpty','lastIndexOf','singleWhere','lastWhere','shuffle','takeWhile','iterator','toString','toSet','single','reduce','elementAt','skipWhile','insertRange','filter','push','mappedBy','addLast','some','slice','retainMatching','firstMatching','removeAll','retainAll','removeMatching','min','lastMatching','singleMatching','max','get','toArray','runtimeType','reverse','addd','asByteArray',],
+'dart.core.Iterable': const ['toList','map','join','toSet','where','forEach','expand','fold','every','any','contains','firstWhere','length','elementAt','skipWhile','reduce','iterator','take','skip','toString','singleWhere','lastWhere','takeWhile','isEmpty','first','single','last','isNotEmpty','addAll','indexOf','add','sort','toArray','mappedBy','filter',],
+'dart.core.Set': const ['add','contains','remove','addAll','clear','difference','map','containsAll','union','removeWhere','removeAll','intersection','retainAll','retainWhere','forEach','toSet','every','lookup','any','toString','toList','where','length','join','skip','firstWhere','isEmpty','first','iterator','singleWhere','expand','elementAt','fold','reduce','single','lastWhere','isNotEmpty','take','takeWhile','skipWhile','last','findBy','toArray','filter',],
+'dart.collection.Queue': const ['add','removeFirst','clear','removeLast','remove','addAll','addLast','addFirst','removeWhere','retainWhere','length','toList','where','contains','forEach','map','isNotEmpty','first','isEmpty','fold','skip','any','elementAt',],
+'dart.core.Map': const ['containsKey','forEach','remove','putIfAbsent','clear','addAll','length','keys','values','containsValue','toString','isNotEmpty','isEmpty','get','getKeys','put','getValues','clone','keySet','hashCode','runtimeType',],
+'dart.core.Iterator': const ['moveNext','current','next','hasNext',],
+'dart.pkg.collection.equality.Equality': const ['hash','equals','isValidKey',],
+'dart.pkg.collection.equality.SetEquality': const ['equals','hash',],
+'dart.pkg.collection.equality.MapEquality': const ['equals','hash',],
+'dart.pkg.collection.equality.ListEquality': const ['equals','hash',],
+'dart.pkg.collection.equality.IterableEquality': const ['hash','equals',],
+'dart.pkg.collection.equality.UnorderedIterableEquality': const ['hash','equals',],
+'dart.async.StreamSubscription': const ['cancel','pause','onDone','resume','onError','asFuture','onData','isPaused',],
+'dart.async.StreamController': const ['add','close','addError','addStream','stream','hasListener','signalError','sink','done',],
+'dart.async.Stream': const ['listen','transform','pipe','first','toList','forEach','firstWhere','where','join','fold','asyncMap','map','isEmpty','asBroadcastStream','handleError','capture','asyncExpand','take','single','expand','onFile','skip','any','timeout','add','last','runtimeType','isBroadcast','drain','elementAt','skipWhile','distinct','singleWhere','lastWhere','contains','every','takeWhile','emit','onDir','onError','onDone','onData','length',],
+'dart.async.Future': const ['then','catchError','wait','whenComplete','forEach','asStream','timeout','map','packages','where','firstWhere','chain','transform','doWhile','onError','onResponse','onRequest','handleException',],
+'dart.core.String': const ['substring','codeUnitAt','startsWith','replaceAll','split','contains','indexOf','toLowerCase','trim','length','endsWith','lastIndexOf','compareTo','isEmpty','toUpperCase','replaceFirst','toString','replaceAllMapped','allMatches','padLeft','codeUnits','hashCode','splitMapJoin','isNotEmpty','runes','charCodeAt','charCodes','trimRight','padRight','concat','equalsIgnoreCase','splitChars','trimLeft','matchAsPrefix','equals','map','toLoweCase','match','slice','getBytes','toCharArray','runtimeType','charAt','valueOf',],
+'dart.core.StringBuffer': const ['write','toString','writeln','writeCharCode','clear','writeAll','add','addAll','addCharCode','isEmpty',],
+'dart.core.RegExp': const ['firstMatch','hasMatch','allMatches','matchAsPrefix','pattern','stringMatch','toString','exec',],
+'dart.core.double': const ['parse','toInt','compareTo','floor','toString','abs','round','toStringAsPrecision','toDouble','floorToDouble','ceil','truncate','toStringAsFixed','roundToDouble','clamp','isNaN','isFinite','toStringAsExponential','ceilToDouble','truncateToDouble','isNan','isNegative','isInfinite','hashCode',],
+'dart.core.Type': const ['toString','hashCode','runtimeType',],
+'dart.mirrors.InstanceMirror': const ['reflectee','getField','type','invoke','setField','delegate','function','then','apply','hasReflectee',],
+'dart.collection.IterableBase': const ['iterableToFullString',],
+'dart.pkg.collection.utils.Pair': const ['last',],
+'dart.collection.Maps': const ['mapToString','length','putIfAbsent','clear','containsKey','getValues','forEach','containsValue','isNotEmpty','isEmpty',],
+'dart.collection.SplayTreeSet': const ['add','addAll','where',],
+'dart.core.StackTrace': const ['toString','frames',],
+'dart.convert.JsonCodec': const ['encode','decode','fuse',],
+'dart.mirrors.MirrorSystem': const ['getName','libraries','findLibrary','isolate','dynamicType','getSymbol','voidType',],
+'dart.mirrors.ClassMirror': const ['newInstance','isSubtypeOf','reflectedType','qualifiedName','metadata','getField','owner','declarations','superclass','simpleName','isSubclassOf','invoke','instanceMembers','mixin','isAbstract','originalDeclaration','typeVariables','setField','isOriginalDeclaration','superinterfaces','isAssignableTo','owners',],
+'dart.io.Process': const ['start','runSync','run','kill','exitCode',],
+'dart.core.int': const ['parse','toDouble','toString','toInt','compareTo','toRadixString','abs','remainder','toUnsigned','toSigned','clamp','round','floor','substr','ceil','isEven','id','append','truncate','hashCode','toStringAsFixed','ceilToDouble','roundToDouble','floorToDouble','truncateToDouble','isNegative','length','isNaN','isInfinite','runtimeType','bitLength',],
+'dart.core.Sink': const ['add','close',],
+'dart.async.EventSink': const ['close','add','addError',],
+'dart.async.Completer': const ['complete','completeError','future','isCompleted','completeException','then',],
+'dart.io.FileStat': const ['mode','stat','type','statSync','changed','modified','size',],
+'dart.io.Link': const ['existsSync','createSync','resolveSymbolicLinksSync','exists','delete','targetSync','deleteSync','target','create','updateSync',],
+'dart.io.FileSystemEntityType': const ['toString','NOT_FOUND','DIRECTORY','FILE',],
+'dart.io.Directory': const ['existsSync','list','listSync','watch','path','exists','createSync','create','deleteSync','delete','createTemp','createTempSync','renameSync','parent','absolute','stat','current','createRecursivelySync','resolveSymbolicLinksSync','rename','statSync',],
+'dart.io.File': const ['existsSync','readAsStringSync','openRead','writeAsStringSync','readAsString','openWrite','lastModifiedSync','exists','resolveSymbolicLinksSync','writeAsString','path','resolveSymbolicLinks','statSync','deleteSync','createSync','delete','openSync','parent','readAsBytesSync','copy','open','absolute','fullPathSync','length','writeAsBytesSync','lastModified','writeAsBytes','readAsLinesSync','fullPath','readAsBytes','copySync','create','lengthSync','readAsLines','isFileSync','isFile','rename','openOutputStream','openInputStream','stat','renameSync','watch','directorySync','isAbsolute','directory',],
+'dart.io.Stdout': const ['writeln','close','write','flush','addStream','writeString','add','writeCharCode','addString',],
+'dart.io.IOSink': const ['write','close','writeln','flush','add','addStream','writeAll','writeCharCode','encoding','addError','done',],
+'dart.mirrors.LibraryMirror': const ['uri','getField','declarations','invoke','topLevelMembers','setField','classes','first',],
+'dart.core.Match': const ['group','end','start','groups','toString',],
+'dart.isolate.SendPort': const ['send','call','hashCode',],
+'dart.core.DateTime': const ['parse','toIso8601String','millisecondsSinceEpoch','difference','toUtc','add','day','year','month','isAfter','toString','compareTo','subtract','isBefore','millisecond','toLocal','timeZoneName','timeZoneOffset','isUtc','weekday','isAtSameMomentAs','second','hour','minute','hashCode','now','runtimeType',],
+'dart.core.Duration': const ['inMilliseconds','toString','inSeconds','inMicroseconds','inHours','inMinutes','inDays','isNegative','compareTo',],
+'dart.core.Uri': const ['parse','toString','toFilePath','path','resolve','decodeComponent','encodeFull','decodeQueryComponent','scheme','encodeComponent','resolveUri','encodeQueryComponent','query','decodeFull','pathSegments','queryParameters','origin','authority','splitQueryString','replace','host','isAbsolute','port','fragment','hasAuthority','userInfo','parseIPv4Address','parseIPv6Address','hasQuery','endsWith','startsWith',],
+'dart.typed_data.Uint32List': const ['sublist','setAll','fillRange','setRange','removeRange','removeLast','clear','addAll','add',],
+'dart.typed_data.TypedData': const ['buffer',],
+'dart.io.BytesBuilder': const ['takeBytes','addByte','add','clear','toBytes',],
+'dart.isolate.ReceivePort': const ['close','transform','listen','receive','toSendPort','takeWhile','sendPort','asBroadcastStream',],
+'dart.convert.Encoding': const ['decode','encode','getByName','decodeStream','name',],
+'dart.convert.Utf8Codec': const ['encode','decode','decoder','decodeStream',],
+'dart.core.Stopwatch': const ['start','stop','reset','elapsedMicroseconds','elapsedMilliseconds','elapsed','elapsedInMs',],
+'dart.async.ZoneDelegate': const ['handleUncaughtError','registerUnaryCallback','registerCallback','registerBinaryCallback','runBinary','errorCallback','scheduleMicrotask','run','createTimer',],
+'dart.async.Zone': const ['handleUncaughtError','run','fork','inSameErrorZone','runGuarded','bindUnaryCallback','bindBinaryCallback','runUnary','bindCallback','scheduleMicrotask','createTimer',],
+'dart.dom.html.BodyElement': const ['innerHtml','children','nodes','append','style','onContextMenu','onMouseDown','onMouseWheel','scrollTop','onMouseUp','onClick','scrollLeft','clientHeight','clientWidth','onBlur','onFocus','onDoubleClick','scrollHeight','onMouseMove','elements','createFragment','classes','ownerDocument','query','onKeyDown','querySelector','offsetWidth','scrollWidth','offsetHeight','setInnerHtml','childNodes','requestFullscreen','offsetTop',],
+'dart.dom.html.Location': const ['hash','search','reload','pathname','toString','href','host','assign','replace','protocol','hostname','port','origin',],
+'dart.convert.HtmlEscape': const ['convert',],
+'dart.dom.html.Window': const ['postMessage','btoa','lookupPort','document','requestAnimationFrame','alert','navigator','devicePixelRatio','pageYOffset','pageXOffset','onAnimationEnd','innerWidth','onResize','getSelection','cancelAnimationFrame','animationEndEvent','innerHeight','registerPort','dispatchEvent','onAnimationStart','onMouseUp','onMouseMove','open','screen','indexedDB','setTimeout','scrollX','scrollY','onScroll','openDatabase','confirm','getContainer','location','onKeyUp','atob','scrollTo','localStorage','scrollBy','setInterval','setImmediate','requestLayoutFrame','requestFileSystem','onHashChange','close','console','onError','onMessage','animationFrame',],
+'dart.core.Function': const ['apply','toString','call','bind',],
+'dart.async.Timer': const ['cancel','run',],
+'dart.dom.html.HeadElement': const ['append','querySelector','query','children','style','elements','querySelectorAll','nodes','id','insertBefore','text',],
+'dart.dom.html.ElementStream': const ['listen','where','first','matches','forEach','map',],
+'dart.dom.html.Element': const ['query','onClick','innerHtml','style','querySelector','nodes','children','remove','append','querySelectorAll','classes','attributes','setInnerHtml','getComputedStyle','onChange','parent','matches','getBoundingClientRect','focus','dispatchEvent','addEventListener','insertAllBefore','clone','getAttribute','blur','createShadowRoot','contains','text','setAttribute','insertAdjacentElement','appendText','scrollIntoView','shadowRoot','getNamespacedAttributes','removeEventListener','insertBefore','appendHtml','click','offsetWidth','insertAdjacentHtml','insertAdjacentText','getClientRects','getElementsByClassName','replaceWith','scrollByLines','scrollByPages','hasChildNodes','requestFullscreen','requestPointerLock','queryAll','setAttributeNS','getAttributeNS','dataset','offsetHeight','on','createFragment','offsetTo','getDestinationInsertionPoints','matchesWithAncestors','attributeChanged','onMouseDown','nextElementSibling','getRegionFlowRanges','onContextMenu','animate','onTouchStart','scrollTop','offsetTop','onTouchMove','onTouchEnd','onMouseWheel','clientWidth','scrollLeft','clientHeight','isTagSupported','parentNode','onMouseUp','bind','onKeyDown','ownerDocument','unbind','unbindAll','init','createInstance','render','update','onKeyUp','onMouseMove','xtag','offsetLeft','tabIndex','client','requestFullScreen','getInputContext','borderEdge','clearModel','id','disabled','value','getContext','lastChild','firstChild','nextNode','innerHTML','onMouseEnter','onMouseLeave','contentEdge','elements','matchesSelector','webkitRequestPointerLock','tagName','childNodes','webkitRequestFullscreen','webkitRequestFullScreen','marginEdge','paddingEdge','outerHtml','onMouseOver','onMouseOut','onDragEnd','boolean','scrollHeight','hidden','onDragStart','onDoubleClick','nodeType','hashCode','onDrag','onInput','selectionStart','selectionEnd','onDrop','onDragLeave','hideOrShowNavigation','onDragOver','model','scrollEvent','onDragEnter','previousElementSibling','className','namespaceUri','onSubmit','selection','setItemSelected','runtimeType','apply','createBinding','values','onBlur','onTouchCancel','show','insertAdjacentHTML','nodeName','selected','contentEditable','localName','number','draggable','src','addText','addHTML','select','clear','str','clearSelection',],
+'dart.dom.html.HtmlElement': const ['querySelector','query','append','classes','style','getComputedStyle','remove','getBoundingClientRect','querySelectorAll','clone','attributes','focus','tabIndex','onClick','parent','onMouseLeave','replaceWith','onContextMenu','onMouseEnter','onKeyDown','blur','setInnerText','scrollTop','appendHtml','dataset','lastChild','onSelectStart','onDrop','onDragOver','onDragLeave','onDragEnter','onDragEnd','onDragStart','onDrag','onDoubleClick','children','onScroll','getAttribute','nodes','outerHtml','click','createShadowRoot',],
+'dart.dom.html.ElementList': const ['forEach','length','contains','last','style','addAll','first','where','onMouseLeave','onMouseEnter','toList','some','onClick','map','classes','indexOf',],
+'dart.dom.html.HtmlDocument': const ['query','querySelectorAll','querySelector','queryAll','createElement','body','title','createElementUpgrader','documentElement','timeline','onKeyDown','getElementById','registerElement','onClick','addEventListener','onMouseUp','onMouseMove','activeElement','createElementNS','createDocumentFragment','createRange','adoptNode','getElementsByTagName','onKeyUp','elementFromPoint','contains','getElementsByName','head','exitFullscreen','onMouseWheel','register',],
+'dart.collection.LinkedHashMap': const ['containsKey','forEach','remove','putIfAbsent','keys','length','clear','values','isNotEmpty',],
+'dart.dom.html.Navigator': const ['userAgent','language','appVersion','appName','geolocation','vendor','appCodeName','dartEnabled','getUserMedia','onLine','platform','storageQuota',],
+'dart.dom.html.CssStyleDeclaration': const ['display','width','height','top','setProperty','left','position','zIndex','cssText','right','maxHeight','visibility','bottom','background','removeProperty','cursor','overflow','getPropertyValue','opacity','backgroundColor','float','transform','padding','border','borderRadius','paddingBottom','transition','paddingTop','overflowY','color','outline','backgroundImage','transformStyle','pointerEvents','marginLeft','textAlign','backgroundPosition','boxSizing','paddingLeft','backgroundSize','margin','fontFamily','userSelect','fontSize','lineHeight','willChange','fontWeight','getProperty','marginRight','whiteSpace','overflowX','textDecoration','perspective','perspectiveOrigin','appearance','borderLeftWidth','paddingRight','borderColor','borderBottomWidth','borderTopWidth','webkitOverflowScrolling','borderRightWidth','marginBottom','transitionProperty','transitionTimingFunction','transitionDuration','animation','animationDelay','animationFillMode','animationDirection','animationIterationCount','animationTimingFunction','animationDuration','animationName','verticalAlign','marginTop','boxShadow','getPropertyPriority','textStrokeColor','borderBottom','font','supportsProperty','textShadow','maxWidth','minWidth','minHeight','outlineColor','filter','borderWidth','animationPlayState','fontStyle','borderRight','borderLeft','borderTop',],
+'dart.io.ProcessResult': const ['stdout','exitCode',],
+'dart.io.FileSystemEvent': const ['path','isDirectory','type','MODIFY','CREATE','DELETE',],
+'dart.collection.HashSet': const ['add','contains','remove','clear','addAll','retainAll','length','isEmpty','toList','removeAll','any','forEach','map',],
+'dart.collection.HashMap': const ['remove','containsKey','forEach','clear','keys','putIfAbsent','addAll','values',],
+'dart.io.FileSystemEntity': const ['isDirectorySync','path','typeSync','existsSync','isDirectory','identicalSync','isFileSync','type','isFile','statSync','deleteSync','isLinkSync','parentOf','renameSync','isLink','readAsStringSync','identical','rename','toString','delete','exists','parent','stat',],
+'dart.io.OSError': const ['errorCode','toString',],
+'dart.async.StreamTransformer': const ['bind',],
+'dart.core.Runes': const ['toList','any','elementAt','iterator','single','first','forEach','last',],
+'dart.core.Object': const ['toString','toJson','hashCode','discardListChages','reverse','map','lightDom','getName','where','add','containsKey','format','setTable','getClass','getNamespace','getId','getCell','getSize','setNamespace','equals','setColumn','getColumnName','getForeignTableName','setDatabase','setAttribute','setId','getChild','body','setPrevious','getIndex','getParent','getChildAt','getChildCount','getValue','getRoot','POST','GET','getPackage','setSchema','clone','getType','then','isInheritance','isVisible','getDartName','getPlatform','setPosition','setPackage','requiresTransactionInPostgres','setAppData','getSchema','getBuildProperty','getPrevious','getTerminal','n','replaceWith','setChild','setPlatform','run','removeItem','getAllItems','bytes','compareTo','getAttribute','setPreviousIndex','isEmpty','getEdgeAt','isVertex','writeExternal','isEdge','getEdgeCount','isConnectable','setValue','isCollapsed','getStyles','setRoot','getStyle','getGeometry','noSuchMethod','contains','elementAt','e',],
+'dart.core.StringSink': const ['write','writeln','writeCharCode','toString','writeAll',],
+'dart.io.Stdin': const ['pipe','readLineSync','transform','listen',],
+'dart.io.HttpServer': const ['bind','listen','close','connectionsInfo','bindSecure','address','port','idleTimeout','serverHeader','autoCompress','asBroadcastStream','transform','addRequestHandler','listenOn','on',],
+'dart.io.HttpResponse': const ['close','write','statusCode','headers','add','done','redirect','addStream','detachSocket','reasonPhrase','writeln','addError','writeCharCode','writeAll','flush','toString','when','cookies','contentLength','addString','getLogs','listen','persistentConnection','deadline',],
+'dart.io.HttpRequest': const ['listen','uri','session','drain','transform','response','toString','cookies','method','fold','connectionInfo','pipe','asBroadcastStream','toList','timeout','takeWhile','take','skipWhile','singleWhere','map','lastWhere','join','handleError','skip','firstWhere','expand','every','elementAt','distinct','asyncMap','asyncExpand','any','toSet','contains','where','reduce','forEach','headers','path',],
+'dart.collection.SplayTreeMap': const ['forEach','containsKey','remove','keys','values','firstKeyAfter','lastKeyBefore','clear','length',],
+'dart.io.HttpClient': const ['post','getUrl','openUrl','close','postUrl','get','open','addCredentials','patchUrl','shutdown','put','delete','addProxyCredentials','findProxyFromEnvironment',],
+'dart.io.HttpClientRequest': const ['close','add','write','addStream','cookies',],
+'dart.io.Platform': const ['isWindows','script','environment','operatingSystem','pathSeparator',],
+'dart.collection.LinkedHashSet': const ['add','map','contains','toList','addAll','remove',],
+'dart.io.RandomAccessFile': const ['lengthSync','readIntoSync','close','closeSync','writeStringSync','writeString','writeFromSync','length','readInto','read','readSync','writeFrom','readListSync','flushSync','positionSync','setPosition','writeListSync','setPositionSync','unlock','lock','unlockSync','readList','lockSync','readByteSync','position','writeList','writeByteSync',],
+'dart.core.num': const ['round','toDouble','toInt','floor','abs','toString','parse','ceil','toStringAsFixed','isNaN','compareTo','roundToDouble','remainder','hashCode','clamp','isInfinite','isNegative','truncate','toStringAsPrecision','toStringAsExponential','isFinite','truncateToDouble','toRadixString',],
+'dart.dom.html.HttpRequest': const ['send','open','getString','abort','setRequestHeader','request','getAllResponseHeaders','overrideMimeType','requestCrossOrigin','getResponseHeader','postFormData','onLoadEnd','onError','onLoad','DONE','withCredentials','onReadyStateChange','onLoadStart',],
+'dart.dom.html.Event': const ['preventDefault','toString','stopImmediatePropagation','stopPropagation','target','currentTarget',],
+'dart.dom.html.FileReader': const ['readAsArrayBuffer','readAsDataUrl','readAsText','onError','onLoadEnd','result',],
+'dart.core.Pattern': const ['allMatches','matchAsPrefix','toString','firstMatch','pattern','codeUnitAt',],
+'dart.io.ContentType': const ['parse','toString','charset','mimeType','value','parameters','subType','primaryType',],
+'dart.io.HttpHeaders': const ['set','contentType','ifModifiedSince','value','add','host','forEach','date','removeAll','clear','remove','noFolding','contentLength','port','expires','chunkedTransferEncoding','persistentConnection','toString','CONTENT_TYPE','data',],
+'dart.typed_data.Uint8List': const ['setRange','sublist','fillRange','setAll','length','buffer','toString','toList','lastIndexOf','indexOf','join','removeRange','removeLast','clear','addAll','add',],
+'dart.async.StreamSink': const ['close','addStream','add','addError',],
+'dart.typed_data.ByteData': const ['getUint32','setUint32','getUint8','setUint64','getInt32','getUint16','getUint64','setUint16','getInt16','setInt64','setInt32','setInt16','setFloat64','getInt64','setInt8','getFloat64','getFloat32','setFloat32','getInt8','setUint8',],
+'dart.io.HttpClientResponse': const ['listen','toList','transform','drain','fold','pipe','detachSocket',],
+'dart.core.BidirectionalIterator': const ['moveNext','movePrevious',],
+'dart.mirrors.ClosureMirror': const ['invoke','apply','function',],
+'dart.typed_data.Int32x4': const ['x','signMask','select',],
+'dart.js.JsObject': const ['callMethod','hasProperty','toString','deleteProperty','instanceof',],
+'dart.dom.html.Node': const ['remove','ELEMENT_NODE','insertBefore','replaceWith','insertAllBefore','querySelector','localName','text','append','setMenubarOrientation','getElementsByTagName','getElementsByClassName','nodes','parentNode','getElementById','firstChild','parent','contains','tagName','value','toString','name','querySelectorAll','clone','attributes','nextNode','nodeType','click','bind','outerHtml','dispatchEvent','on','childNodes',],
+'dart.core.RuneIterator': const ['moveNext','reset',],
+'dart.mirrors.DeclarationMirror': const ['isPrivate','simpleName','metadata','isSubclassOf','qualifiedName','parameters','invoke',],
+'dart.dom.html.History': const ['pushState','back','replaceState','length',],
+'dart.dom.html.CssClassSet': const ['add','remove','toggle','clear','contains','addAll','removeAll','toString','firstWhere','first','toggleAll','length','containsAll',],
+'dart.dom.html.Document': const ['querySelector','querySelectorAll','documentElement','createElement','title','body','removeEventListener','addEventListener','getElementsByTagName','createElementNS','query','window','queryAll',],
+'dart.mirrors.IsolateMirror': const ['rootLibrary',],
+'dart.mirrors.ObjectMirror': const ['invoke','getField','setField',],
+'dart.dom.html.DivElement': const ['append','classes','style','setInnerHtml','remove','querySelector','id','getComputedStyle','appendText','text','querySelectorAll','onDragEnd','onDrag','onDragStart','draggable','innerHtml','insertAdjacentElement','appendHtml','className','children','focus','query','nodes','createShadowRoot','clone','attributes','queryAll','click','onMouseDown','onClick','hidden','addEventListener','onMouseMove','scrollIntoView','onKeyDown','title','getBoundingClientRect','onMouseUp','dispatchEvent','insertAdjacentText','contentEditable','scrollTop','scrollByLines','bind','insertBefore','xtag','insertAdjacentHtml','matches','setAttribute','on','onKeyUp','getElementsByClassName',],
+'dart.dom.html.NodeValidatorBuilder': const ['allowNavigation','allowElement','allowHtml5','allowSvg','allowInlineStyles','allowTextElements','allowTemplating','allowCustomElement','allowTagExtension','allowImages',],
+'dart.dom.html.Console': const ['timeEnd','time','timeStamp','warn','log','error','groupEnd','info','debug','groupCollapsed','group','dir',],
+'dart.dom.html.ElementUpgrader': const ['upgrade',],
+'dart.async.StreamIterator': const ['moveNext','cancel',],
+'dart.io.SystemEncoding': const ['decode',],
+'dart.collection.UnmodifiableListView': const ['where','contains','any','length','join','firstWhere',],
+'dart.core.Error': const ['safeToString','toString',],
+'dart.convert.Utf8Encoder': const ['bind','convert','startChunkedConversion',],
+'dart.dom.html.DomImplementation': const ['createHtmlDocument',],
+'dart.dom.html.DocumentFragment': const ['querySelectorAll','append','clone','nodes','children','setInnerHtml','querySelector','queryAll','query','remove','ownerDocument',],
+'dart.dom.html.ShadowRoot': const ['querySelector','querySelectorAll','host','children','append','contains','query','activeElement','supported','nodes','firstChild','getElementsByTagName','text','innerHtml','olderShadowRoot',],
+'dart.mirrors.TypeMirror': const ['qualifiedName','isSubtypeOf','reflectedType','newInstance','isAssignableTo','simpleName','typeArguments','originalDeclaration','toString','referent','hasReflectedType','isPrivate','typeVariables','owner','invoke','isOriginalDeclaration',],
+'dart.io.ServerSocket': const ['bind','close','listen',],
+'dart.dom.html.PerformanceNavigation': const ['type','redirectCount',],
+'dart.dom.html.Performance': const ['now','timing','navigation',],
+'dart.dom.html.PerformanceTiming': const ['navigationStart',],
+'dart.typed_data.ByteBuffer': const ['asUint8List','asUint32List','asInt32List','asByteData','asFloat64x2List','asInt32x4List','asFloat32x4List','asFloat64List','asFloat32List','asUint64List','asInt64List','asUint16List','asInt16List','asUint8ClampedList','asInt8List',],
+'dart.io.WebSocket': const ['add','listen','close','connect','where','map','send',],
+'dart.convert.JsonEncoder': const ['convert','startChunkedConversion',],
+'dart.convert.JsonDecoder': const ['convert','startChunkedConversion',],
+'dart.core.bool': const ['toString','should','hashCode','isAssignableFrom','parse','containsKey',],
+'dart.core.FormatException': const ['toString',],
+'dart.dom.html.WindowBase': const ['postMessage','navigator','close','alert',],
+'dart.dom.html.ButtonElement': const ['text','onClick','classes','attributes','style','append','type','setInnerHtml','children','onMouseOut','onMouseOver','click','disabled','dataset','appendText',],
+'dart.core.Exception': const ['toString','printStackTrace',],
+'dart.dom.html.DataTransfer': const ['setData','setDragImage','types','effectAllowed','dropEffect','getData','files',],
+'dart.math.Point': const ['x','y','distanceTo','magnitude',],
+'dart.dom.html.LIElement': const ['classes','append','style','text','querySelector','innerHtml','dispatchEvent','children','dataset','className','nodes','remove','value',],
+'dart.dom.html.CanvasRenderingContext2D': const ['lineTo','beginPath','fillRect','moveTo','stroke','drawImage','closePath','restore','translate','save','scale','fill','getImageData','clearRect','setTransform','strokeRect','rotate','putImageData','fillStyle','arc','transform','fillText','strokeStyle','createImageData','createPatternFromImage','clip','lineWidth','drawImageToRect','strokeText','font','rect','drawImageScaledFromSource','setFillColorRgb','createLinearGradient','bezierCurveTo','drawImageScaled','measureText','setLineDash','shadowBlur','shadowOffsetX','shadowOffsetY','shadowColor','quadraticCurveTo','imageSmoothingEnabled','textAlign','createRadialGradient','textBaseline','globalAlpha','lineCap',],
+'dart.io.HeaderValue': const ['parse',],
+'dart.dom.html.ScriptElement': const ['src','type','async','remove','text',],
+'dart.dom.html.MouseEvent': const ['preventDefault','stopPropagation','target','dataTransfer','page','client','ctrlKey','stopImmediatePropagation','metaKey','shiftKey',],
+'dart.io.RawSocket': const ['write','listen','close','connect','read','available','shutdown','setOption',],
+'dart.io.RawSecureSocket': const ['secure','connect','shutdown','listen','secureServer','write','read',],
+'dart.dom.web_sql.SqlDatabase': const ['transaction','supported',],
+'dart.dom.web_sql.SqlTransaction': const ['executeSql',],
+'dart.dom.web_sql.SqlResultSetRowList': const ['length','elementAt','isNotEmpty','item','forEach',],
+'dart.convert.AsciiCodec': const ['encode','decode',],
+'dart.dom.html.EventStreamProvider': const ['forTarget','forElement',],
+'dart.dom.html.MutationObserver': const ['observe','disconnect','takeRecords',],
+'dart.dom.html.UListElement': const ['queryAll','append','style','id','children','remove','query','insertBefore','classes',],
+'dart.dom.html.VideoElement': const ['canPlayType','load','pause','play','autoplay','remove','src',],
+'dart.dom.html.MediaError': const ['code',],
+'dart.dom.html.TimeRanges': const ['start','end',],
+'dart.dom.html.SourceElement': const ['remove',],
+'dart.dom.html.ObjectElement': const ['remove','getAttribute',],
+'dart.dom.html.OptionElement': const ['value','text','selected','label','appendText',],
+'dart.dom.html.SpanElement': const ['classes','text','style','append','appendText','onMouseOut','onMouseOver','onClick','attributes','remove','draggable','id','outerHtml','innerHtml','setAttribute','querySelector','scrollIntoView',],
+'dart.dom.html.Geolocation': const ['getCurrentPosition','watchPosition',],
+'dart.dom.html.Coordinates': const ['accuracy','longitude','latitude','speed','heading','altitudeAccuracy','altitude',],
+'dart.dom.html.ImageElement': const ['remove','width','height','onLoad','src','style','crossOrigin','classes','className','id','onDragStart',],
+'dart.mirrors.MethodMirror': const ['parameters','isGetter','isConstructor','returnType','owner','simpleName','location','source','isStatic',],
+'dart.dom.html.Storage': const ['containsKey','clear','remove','length','keys','containsValue',],
+'dart.convert.ChunkedConversionSink': const ['add','close','specialI',],
+'dart.collection.ListQueue': const ['add','removeFirst','addAll','addLast','removeLast','forEach','toList','removeWhere','addFirst',],
+'dart.dom.html.CanvasElement': const ['getContext','style','width','height','context2D','toDataUrl','getContext3d','onMouseUp','onMouseDown','getBoundingClientRect','onMouseMove','onClick','onMouseOut','className','onMouseOver','setAttribute','remove','context2d','focus',],
+'dart.dom.html.KeyboardEvent': const ['preventDefault','which','stopPropagation','ctrlKey','keyCode','stopImmediatePropagation','metaKey','altKey','shiftKey','getModifierState',],
+'dart.dom.html.WebSocket': const ['send','close','onMessage','onClose','onError','onOpen','readyState','url','sendTypedData','binaryType',],
+'dart.io.WebSocketTransformer': const ['upgrade','isUpgradeRequest',],
+'dart.core.Symbol': const ['toString','length',],
+'dart.js.JsFunction': const ['apply',],
+'dart.io.InternetAddress': const ['address','host','lookup','toString','isLoopback',],
+'dart.convert.Latin1Codec': const ['decode',],
+'dart.dom.html.ElementEvents': const ['click','load','change','keyPress','drop','dragOver','dragEnter','input','keyDown','dragLeave','dragEnd','dragStart','mouseOut','mouseMove','keyUp','loadedMetadata',],
+'dart.dom.html.TableCellElement': const ['setInnerHtml','style','append','text','insertAdjacentElement','colSpan','setAttribute','innerHtml','cellIndex',],
+'dart.dom.html.TableRowElement': const ['append','attributes','classes','onClick','children','onMouseOut','onMouseOver','remove','insertCell','cells','createFragment','addCell','query','outerHtml',],
+'dart.convert.Converter': const ['convert','startChunkedConversion',],
+'dart.dom.html.FormData': const ['append','appendBlob',],
+'dart.io.ProcessException': const ['toString',],
+'dart.dom.html.Text': const ['remove','text','toString',],
+'dart.dom.html.AnchorElement': const ['href','text','onClick','id','classes','append','dispatchEvent','replaceWith','download','click','setAttribute','appendText',],
+'dart.dom.svg.LineElement': const ['setAttribute',],
+'dart.dom.svg.RectElement': const ['setAttribute','attributes',],
+'dart.dom.svg.EllipseElement': const ['setAttribute',],
+'dart.dom.svg.PolylineElement': const ['attributes',],
+'dart.dom.svg.CircleElement': const ['setAttribute',],
+'dart.dom.svg.PathElement': const ['setAttribute','createSvgPathSegLinetoAbs','createSvgPathSegMovetoAbs',],
+'dart.dom.html.HeadingElement': const ['text','classes','appendText','append','id',],
+'dart.dom.html.TableElement': const ['insertRow','createFragment','append','children','createTBody','deleteRow','addRow','query','querySelector',],
+'dart.io.HttpConnectionInfo': const ['remoteAddress','remotePort','localPort','remoteHost',],
+'dart.dom.html.FormElement': const ['append','submit','children','remove',],
+'dart.io.Cookie': const ['value','toString','path',],
+'dart.dom.html.InputElement': const ['focus','select','value','remove','type','checkValidity','dataset','onKeyDown','setSelectionRange','dispatchEvent','selectionStart','selectionEnd','setAttribute','bind','checked','attributes','blur','setRangeText','click','onChange','placeholder','id','onKeyUp','onBlur','onKeyPress','autocomplete','onPaste','defaultChecked','onFocus','disabled',],
+'dart.io.Socket': const ['close','connect','transform','destroy','add','listen','write','addStream','pipe','address','read','writeList','setOption','flush','map','readList','available',],
+'dart.mirrors.ParameterMirror': const ['type','isOptional','defaultValue',],
+'dart.convert.Codec': const ['fuse','encode','decode',],
+'dart.dom.indexed_db.Database': const ['transaction','createObjectStore','close',],
+'dart.dom.indexed_db.Transaction': const ['objectStore','onAbort','onError','onComplete',],
+'dart.dom.indexed_db.ObjectStore': const ['put','delete','createIndex','getObject','index','openCursor','clear',],
+'dart.dom.svg.SvgSvgElement': const ['append','setAttribute','createFragment','createSvgPoint','getScreenCtm','onMouseUp','onMouseMove',],
+'dart.dom.svg.Point': const ['matrixTransform',],
+'dart.dom.svg.Matrix': const ['inverse',],
+'dart.dom.html.WheelEvent': const ['preventDefault','stopPropagation',],
+'dart.dom.svg.AnimatedRect': const ['baseVal',],
+'dart.dom.html.SelectElement': const ['append','focus','remove','classes','tabIndex','options','selectedIndex','querySelectorAll','multiple','value',],
+'dart.dom.html.LabelElement': const ['query','text','append','htmlFor','style','appendText','classes',],
+'dart.io.HttpSession': const ['id','destroy','clear','containsKey','isNew','remove','onTimeout',],
+'dart.dom.indexed_db.IdbFactory': const ['open','deleteDatabase','supported','supportsDatabaseNames','getDatabaseNames',],
+'dart.dom.indexed_db.Request': const ['result',],
+'dart.dom.indexed_db.Index': const ['openCursor',],
+'dart.dom.indexed_db.KeyRange': const ['upperBound_','bound_','lowerBound_','only_',],
+'dart.dom.indexed_db.CursorWithValue': const ['delete',],
+'dart.core.NoSuchMethodError': const ['toString',],
+'dart.isolate.Isolate': const ['spawn','spawnUri','resume','addOnExitListener','removeErrorListener','addErrorListener','kill','ping','pause','setErrorsFatal',],
+'dart.dom.html.TemplateElement': const ['decorate','content',],
+'dart.dom.html.TreeWalker': const ['nextNode',],
+'dart.dom.html.StyleElement': const ['remove','appendText','text','sheet','attributes','type','appendHtml','dataset','append','innerHtml',],
+'dart.dom.html.EventTarget': const ['error','result','matchesWithAncestors','nodeName','matches','classes','dispatchEvent','removeEventListener','addEventListener','status','parent','value','hashCode',],
+'dart.collection_helpers.equality.Equality': const ['hash','equals','isValidKey',],
+'dart.collection_helpers.equality.SetEquality': const ['hash','equals',],
+'dart.collection_helpers.equality.MapEquality': const ['hash','equals',],
+'dart.collection_helpers.equality.ListEquality': const ['hash','equals',],
+'dart.collection_helpers.equality.IterableEquality': const ['hash','equals',],
+'dart.collection_helpers.equality.UnorderedIterableEquality': const ['hash','equals',],
+'dart.io.SecureSocket': const ['initialize','close','connect','listen','write','add','fold','writeln','secure','transform',],
+'dart.io.HttpDate': const ['parse','format',],
+'dart.math.Rectangle': const ['top','left','containsPoint','height','width','topLeft','intersection','topRight','intersects','containsRectangle','boundingBox','snap',],
+'dart.dom.html.ContentElement': const ['getDistributedNodes',],
+'dart.io.SocketException': const ['toString',],
+'dart.dom.html.TextAreaElement': const ['style','focus','select','rows','attributes','setSelectionRange','value','appendText','remove',],
+'dart.dom.html.LinkElement': const ['href','replaceWith','rel',],
+'dart.dom.html.ParagraphElement': const ['text','appendHtml','classes','addHtml','hidden',],
+'dart.typed_data.Int32List': const ['setRange','indexOf','sublist','removeRange','removeLast','clear','addAll','add','setAll',],
+'dart.dom.web_gl.RenderingContext': const ['ARRAY_BUFFER','texParameteri','bindBuffer','bindFramebuffer','TEXTURE_2D','enable','deleteShader','getUniformLocation','bindTexture','clear','createTexture','detachShader','attachShader','getAttribLocation','createBuffer','enableVertexAttribArray','vertexAttribPointer','FLOAT','STATIC_DRAW','createShader','shaderSource','compileShader','viewport','useProgram','clearColor','bufferDataTyped','getShaderParameter','uniformMatrix4fv','getShaderInfoLog','bindRenderbuffer','deleteTexture','deleteProgram','RGBA','linkProgram','createProgram','disableVertexAttribArray','disable','getProgramParameter','blendFunc','drawArrays','getProgramInfoLog','TRIANGLES','lineWidth','COMPILE_STATUS','texImage2DTyped','NEAREST','createFramebuffer','getExtension','framebufferTexture2D','framebufferRenderbuffer','renderbufferStorage','createRenderbuffer','ELEMENT_ARRAY_BUFFER','uniformMatrix3fv','uniform2f','UNSIGNED_BYTE','deleteFramebuffer','deleteRenderbuffer','TEXTURE_MIN_FILTER','TEXTURE_MAG_FILTER','CLAMP_TO_EDGE','DEPTH_TEST','DEPTH_BUFFER_BIT','texImage2DImage','COLOR_BUFFER_BIT','LINK_STATUS','FRAGMENT_SHADER','VERTEX_SHADER','bufferData','TEXTURE_WRAP_S','TEXTURE_WRAP_T','texImage2DCanvas','LINEAR','UNSIGNED_SHORT','texImage2D','drawElements','pixelStorei','colorMask','depthFunc','TRIANGLE_STRIP','activeTexture','TEXTURE0','depthMask','FRAMEBUFFER','UNPACK_FLIP_Y_WEBGL','generateMipmap','uniform1i',],
+'dart.typed_data.Float32List': const ['sublist','indexOf','buffer','setRange','length',],
+'dart.dom.html.DirectoryEntry': const ['getFile','createDirectory','createFile','createReader','getDirectory','removeRecursively','toUrl','fullPath','toString',],
+'dart.dom.html.Entry': const ['moveTo','isFile','copyTo','isDirectory','fullPath','name','remove','getMetadata','createWriter','file','getParent','toUrl',],
+'dart.dom.html.DirectoryReader': const ['readEntries',],
+'dart.dom.html.KeyCode': const ['DOWN','RIGHT','LEFT','TAB','UP','ESC','ENTER','isCharacterKey','SPACE','NUM_SOUTH','NUM_NORTH','NUM_EAST','NUM_WEST','NUM_NORTH_EAST','NUM_SOUTH_EAST','R',],
+'dart.pkg.collection.iterable_zip.IterableZip': const ['map','toList',],
+'dart.convert.LineSplitter': const ['convert',],
+'dart.dom.html.HttpRequestUpload': const ['onProgress','onError','onTimeout',],
+'dart.dom.html.File': const ['name','slice','readAsBytesSync','existsSync',],
+'dart.dom.html.Events': const ['error','message','load','hashChange','popState','resize','loadEnd',],
+'dart.dom.html.Url': const ['createObjectUrl','revokeObjectUrl','createObjectUrlFromBlob','createObjectUrlFromStream',],
+'dart.dom.html.RtcIceCandidate': const ['candidate','sdpMLineIndex',],
+'dart.dom.html.RtcPeerConnection': const ['setLocalDescription','createDataChannel','createOffer','createAnswer',],
+'dart.io.RawDatagramSocket': const ['bind','close','receive','send','listen',],
+'dart.pkg.collection.equality.DeepCollectionEquality': const ['equals','hash',],
+'dart.pkg.collection.priority_queue.PriorityQueue': const ['addAll','contains','removeFirst','add','removeAll',],
+'dart.convert.StringConversionSink': const ['add','asUtf8Sink','close','asStringSink','addSlice',],
+'dart.dom.html.ImageData': const ['data',],
+'dart.dom.html.PreElement': const ['appendText','text','append','classes',],
+'dart.dom.html.MediaStream': const ['stop',],
+'dart.dom.html.DomParser': const ['parseFromString',],
+'dart.dom.html.CustomEvent': const ['stopImmediatePropagation','preventDefault','stopPropagation',],
+'dart.typed_data.Uint16List': const ['buffer','sublist','setRange','removeRange','removeLast','clear','addAll','add','length',],
+'dart.dom.html.CanvasGradient': const ['addColorStop',],
+'dart.dom.html.Notification': const ['requestPermission',],
+'dart.dom.svg.Length': const ['value','valueAsString',],
+'dart.dom.svg.AnimatedLength': const ['baseVal',],
+'dart.dom.svg.PointList': const ['getItem',],
+'dart.mirrors.SourceLocation': const ['line',],
+'dart.DartGrammarDefinition': const ['build',],
+'dart.dom.html.TextMetrics': const ['width',],
+'dart.dom.html.CssRect': const ['width','height','top','left','topLeft',],
+'dart.dom.html.KeyboardEventStream': const ['onKeyDown',],
+'dart.dom.html.CssRule': const ['selectorText',],
+'dart.dom.html.CssStyleRule': const ['style','selectorText',],
+'dart.dom.html.Selection': const ['removeAllRanges','collapse','getRangeAt',],
+'dart.dom.html.CheckboxInputElement': const ['checked','attributes','classes','value',],
+'dart.dom.html.TextInputElement': const ['classes','value','focus','select','className','onKeyDown','style',],
+'dart.dom.html.DateInputElement': const ['classes',],
+'dart.dom.html.RangeInputElement': const ['style','attributes','onChange','value','step','max','min',],
+'dart.dom.html.AnimationTimeline': const ['play',],
+'dart.dom.html.AnimationPlayer': const ['play',],
+'dart.dom.html.GlobalEventHandlers': const ['clickEvent',],
+'dart.dom.html.TouchEvent': const ['preventDefault','supported','stopPropagation',],
+'dart.dom.html.AudioElement': const ['canPlayType','load','append','play','pause','remove',],
+'dart.io.ProcessSignal': const ['watch',],
+'dart.convert.Utf8Decoder': const ['convert','startChunkedConversion',],
+'dart.dom.html.AnimationEvent': const ['preventDefault','stopImmediatePropagation',],
+'dart.dom.html.FocusEvent': const ['stopImmediatePropagation',],
+'dart.dom.html.Touch': const ['page','client',],
+'dart.async.DeferredLibrary': const ['load',],
+'dart.dom.html.TableSectionElement': const ['append','innerHtml','rows','createFragment','addRow',],
+'dart.mirrors.Mirror': const ['methods','invoke','type','delegate','members',],
+'dart.core.StateError': const ['toString',],
+'dart.io.FileMode': const ['APPEND','READ','WRITE',],
+'dart.dom.html.CssStyleDeclarationBase': const ['display','backgroundColor','opacity','borderLeftWidth',],
+'dart.dom.html.IFrameElement': const ['style','src',],
+'dart.io.FileSystemException': const ['toString',],
+'dart.dom.html.Screen': const ['width','height','pixelDepth',],
+'dart.core.ArgumentError': const ['toString',],
+'dart.dom.html.Blob': const ['slice',],
+'dart.dom.svg.PatternElement': const ['setAttribute','append',],
+'dart.dom.svg.DefsElement': const ['append',],
+'dart.dom.svg.PathSegList': const ['appendItem','clear','length','getItem',],
+'dart.dom.html.FileList': const ['length','item',],
+'dart.dom.html.FileError': const ['NOT_FOUND_ERR','code',],
+'dart.mirrors.VariableMirror': const ['type','isFinal','isStatic',],
+'dart.io.HttpStatus': const ['NOT_FOUND',],
+'dart.typed_data.Float64List': const ['sublist','indexOf','setRange',],
+'dart.typed_data.Float32x4': const ['shuffle','shuffleMix','scale','signMask','clamp','withX','withY','w','z','y','x',],
+'dart.pkg.typed_data.typed_buffers.Int32x4Buffer': const ['add',],
+'dart.dom.html.NumberInputElement': const ['step','max','min','valueAsNumber',],
+'dart.dom.html.ValidityState': const ['valid',],
+'dart.dom.html.CssStyleSheet': const ['ownerNode','insertRule','addRule',],
+'dart.io.ZLibCodec': const ['decode',],
+'dart.collection.HasNextIterator': const ['next',],
+'dart.isolate.RawReceivePort': const ['close',],
+'dart.mirrors.TypeVariableMirror': const ['simpleName','isSubtypeOf','isAssignableTo','owner',],
+'dart.typed_data.implementation.NativeByteBuffer': const ['asFloat64List','asFloat32List','asInt32List',],
+'dart.typed_data.implementation.NativeFloat32x4List': const ['length',],
+'dart.typed_data.implementation.NativeFloat32List': const ['sublist',],
+'dart.typed_data.implementation.NativeInt32x4List': const ['length',],
+'dart.typed_data.implementation.NativeFloat64x2List': const ['length',],
+'dart.typed_data.implementation.NativeFloat64List': const ['sublist',],
+'dart.typed_data.implementation.NativeTypedArray': const ['length',],
+'dart.typed_data.implementation.NativeTypedArrayOfDouble': const ['setRange',],
+'dart.typed_data.implementation.NativeTypedArrayOfInt': const ['setRange',],
+'dart.typed_data.implementation.NativeInt32x4': const ['w','z','y','x',],
+'dart.dom.svg.SvgElement': const ['isTagSupported','clone','setAttribute','children','setInnerHtml','attributes',],
+'dart.dom.svg.GElement': const ['append','querySelector','id',],
+'dart.dom.html.ProgressEvent': const ['toString',],
+'dart.core.RangeError': const ['toString','checkValidRange','checkNotNegative','checkValueInInterval','checkValidIndex',],
+'dart.dom.html.TouchList': const ['length','first','isEmpty','isNotEmpty',],
+'dart.dom.html.FieldSetElement': const ['append','querySelector',],
+'dart.dom.html.ShadowElement': const ['getDistributedNodes',],
+'dart.dom.html.KeyEvent': const ['keyCode','type','preventDefault',],
+'dart.dom.html.NodeList': const ['length','add',],
+'dart.dom.html.DomStringList': const ['length',],
+'dart.dom.html.HtmlCollection': const ['length','forEach','contains',],
+'dart.dom.html.Range': const ['createContextualFragment','selectNodeContents','insertNode','setEndAfter',],
+'dart.dom.html.NodeTreeSanitizer': const ['sanitizeTree',],
+'dart.dom.html.MimeTypeArray': const ['length',],
+'dart.dom.html.PluginArray': const ['length',],
+'dart.dom.html.SourceBufferList': const ['length',],
+'dart.dom.html.SpeechGrammarList': const ['length',],
+'dart.dom.html.TextTrackCueList': const ['length',],
+'dart.dom.html.TextTrackList': const ['length',],
+'dart.dom.html.Dimension': const ['value','toString',],
+'dart.dom.html.UriPolicy': const ['allowsUri',],
+'dart.dom.html.NodeValidator': const ['allowsAttribute','allowsElement',],
+'dart.dom.html.Worker': const ['terminate',],
+'dart.typed_data.Int16List': const ['sublist','buffer','contains','setRange','removeRange','removeLast','clear','addAll','add',],
+'dart.dom.indexed_db.Cursor': const ['next',],
+'dart.dom.svg.LengthList': const ['length','getItem',],
+'dart.dom.svg.NumberList': const ['length','getItem',],
+'dart.dom.svg.StringList': const ['length','getItem',],
+'dart.dom.svg.TransformList': const ['length','getItem',],
+'dart.js.JsArray': const ['length','addAll','insert','removeRange','removeAt','add','setRange','removeLast',],
+'dart.dom.html.ApplicationCache': const ['swapCache',],
+'dart.dom.web_audio.AudioContext': const ['createBufferSource','createOscillator','destination','createPanner','createGain',],
+'dart.dom.html.FileUploadInputElement': const ['click',],
+'dart.dom.html.DomRectReadOnly': const ['top','left','height','width',],
+'dart.typed_data.Int8List': const ['sublist','setRange','removeRange','removeLast','clear','addAll','add','buffer',],
+'dart.dom.web_audio.AudioBufferSourceNode': const ['connectNode','start','stop',],
+'dart.dom.html.FileEntry': const ['file','getParent','toUrl','getMetadata',],
+'dart.dom.html.CustomStream': const ['listen',],
+'dart.dom.html.TrackElement': const ['defaultValue',],
+'dart.dom.web_audio.OscillatorNode': const ['connectNode',],
+'dart.dom.html.StorageQuota': const ['queryInfo',],
+'dart.collection.DoubleLinkedQueue': const ['add',],
+'dart.core.TypeError': const ['toString',],
+'dart.core.AssertionError': const ['toString',],
+'dart.profiler.Metrics': const ['register',],
+'dart.collection.LinkedList': const ['remove','addFirst','clear','add',],
+'dart.typed_data.Uint8ClampedList': const ['sublist',],
+'dart.typed_data.Float64x2': const ['y','x','withX',],
+'dart.convert.ByteConversionSink': const ['close','add','addSlice',],
+'dart.convert.ClosableStringSink': const ['close','write',],
+'dart.mirrors.TypedefMirror': const ['isSubtypeOf','isAssignableTo','referent',],
+'dart.mirrors.FunctionTypeMirror': const ['isSubtypeOf','isAssignableTo','returnType','parameters','isOriginalDeclaration',],
+'dart.mirrors.LibraryDependencyMirror': const ['metadata',],
+'dart.test.stream_from_iterable.IterableTest': const ['run',],
+'dart.io.SecureServerSocket': const ['bind','close','listen',],
+'dart.io.RawServerSocket': const ['bind','listen','close',],
+'dart.typed_data.Uint64List': const ['sublist','setRange','removeRange','removeLast','clear','addAll','add',],
+'dart.typed_data.Int64List': const ['sublist','setRange','removeRange','removeLast','clear','addAll','add',],
+'dart.io.StdioType': const ['name',],
+'dart.io.HttpConnectionsInfo': const ['total','idle','active',],
+'dart.io.RawSecureServerSocket': const ['bind','close','listen',],
+'dart.io.ServerSocketReference': const ['create',],
+'dart.io.NetworkInterface': const ['list',],
+'dart.io.ZLibDecoder': const ['convert',],
+'dart.io.ZLibEncoder': const ['convert',],
+'dart.pkg.async.results.ValueResult': const ['value',],
+'dart.pkg.async.stream_zip.StreamZip': const ['toList',],
+'dart.pkg.async.results.Result': const ['flatten','release',],
+'dart.pkg.async.results.ErrorResult': const ['stackTrace','error',],
+'dart.dom.html.OptGroupElement': const ['append',],
+'dart.dom.html.UnknownElement': const ['query',],
+'dart.dom.web_audio.AudioParam': const ['value','setValueAtTime',],
+'dart.dom.html.RadioButtonInputElement': const ['checked',],
+'dart.dom.web_audio.BiquadFilterNode': const ['connectNode',],
+'dart.async.StreamConsumer': const ['addStream','close',],
+'dart.dom.html.FileSystem': const ['root',],
+'dart.dom.html.FileWriter': const ['write','abort',],
+'dart.dom.html.OutputElement': const ['scrollIntoView',],
+'dart.dom.html.Css': const ['supports',],
+'dart.io.IOException': const ['toString',],
+'dart.dom.html.ButtonInputElement': const ['value','onClick',],
+};
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
new file mode 100644
index 0000000..602503e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -0,0 +1,407 @@
+// 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 services.completion.dart.manager;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/completion_core.dart'
+    show CompletionContributor, CompletionRequest;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_plugin.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analysis_server/src/services/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
+import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context.dart'
+    show AnalysisFutureHelper, AnalysisContextImpl;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+
+/**
+ * [DartCompletionManager] determines if a completion request is Dart specific
+ * and forwards those requests to all [DartCompletionContributor]s.
+ */
+class DartCompletionManager implements CompletionContributor {
+  /**
+   * The [contributionSorter] is a long-lived object that isn't allowed
+   * to maintain state between calls to [DartContributionSorter#sort(...)].
+   */
+  static DartContributionSorter contributionSorter = new CommonUsageSorter();
+
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      CompletionRequest request) async {
+    if (!AnalysisEngine.isDartFileName(request.source.shortName)) {
+      return EMPTY_LIST;
+    }
+
+    CompletionPerformance performance =
+        (request as CompletionRequestImpl).performance;
+    const BUILD_REQUEST_TAG = 'build DartCompletionRequestImpl';
+    performance.logStartTime(BUILD_REQUEST_TAG);
+    DartCompletionRequestImpl dartRequest =
+        await DartCompletionRequestImpl.from(request);
+    performance.logElapseTime(BUILD_REQUEST_TAG);
+
+    // Don't suggest in comments.
+    if (dartRequest.target.isCommentText) {
+      return EMPTY_LIST;
+    }
+
+    ReplacementRange range =
+        new ReplacementRange.compute(dartRequest.offset, dartRequest.target);
+    (request as CompletionRequestImpl)
+      ..replacementOffset = range.offset
+      ..replacementLength = range.length;
+
+    // Request Dart specific completions from each contributor
+    Map<String, CompletionSuggestion> suggestionMap =
+        <String, CompletionSuggestion>{};
+    for (DartCompletionContributor contributor
+        in dartCompletionPlugin.contributors) {
+      String contributorTag =
+          'DartCompletionManager - ${contributor.runtimeType}';
+      performance.logStartTime(contributorTag);
+      List<CompletionSuggestion> contributorSuggestions =
+          await contributor.computeSuggestions(dartRequest);
+      performance.logElapseTime(contributorTag);
+
+      for (CompletionSuggestion newSuggestion in contributorSuggestions) {
+        var oldSuggestion = suggestionMap.putIfAbsent(
+            newSuggestion.completion, () => newSuggestion);
+        if (newSuggestion != oldSuggestion &&
+            newSuggestion.relevance > oldSuggestion.relevance) {
+          suggestionMap[newSuggestion.completion] = newSuggestion;
+        }
+      }
+    }
+
+    // Adjust suggestion relevance before returning
+    List<CompletionSuggestion> suggestions = suggestionMap.values.toList();
+    const SORT_TAG = 'DartCompletionManager - sort';
+    performance.logStartTime(SORT_TAG);
+    await contributionSorter.sort(dartRequest, suggestions);
+    performance.logElapseTime(SORT_TAG);
+    return suggestions;
+  }
+}
+
+/**
+ * The information about a requested list of completions within a Dart file.
+ */
+class DartCompletionRequestImpl implements DartCompletionRequest {
+  @override
+  final AnalysisContext context;
+
+  @override
+  final Source source;
+
+  @override
+  final int offset;
+
+  @override
+  Expression dotTarget;
+
+  @override
+  Source librarySource;
+
+  @override
+  final ResourceProvider resourceProvider;
+
+  @override
+  final SearchEngine searchEngine;
+
+  @override
+  CompletionTarget target;
+
+  /**
+   * The [LibraryElement] representing dart:core
+   */
+  LibraryElement _coreLib;
+
+  /**
+   * The [DartType] for Object in dart:core
+   */
+  InterfaceType _objectType;
+
+  OpType _opType;
+
+  final CompletionPerformance performance;
+
+  DartCompletionRequestImpl._(
+      this.context,
+      this.resourceProvider,
+      this.searchEngine,
+      this.librarySource,
+      this.source,
+      this.offset,
+      CompilationUnit unit,
+      this.performance) {
+    _updateTargets(unit);
+  }
+
+  @override
+  LibraryElement get coreLib {
+    if (_coreLib == null) {
+      Source coreUri = context.sourceFactory.forUri('dart:core');
+      _coreLib = context.computeLibraryElement(coreUri);
+    }
+    return _coreLib;
+  }
+
+  @override
+  bool get includeIdentifiers {
+    opType; // <<< ensure _opType is initialized
+    return !_opType.isPrefixed &&
+        (_opType.includeReturnValueSuggestions ||
+            _opType.includeTypeNameSuggestions ||
+            _opType.includeVoidReturnSuggestions ||
+            _opType.includeConstructorSuggestions);
+  }
+
+  @override
+  LibraryElement get libraryElement {
+    //TODO(danrubel) build the library element rather than all the declarations
+    CompilationUnit unit = target.unit;
+    if (unit != null) {
+      CompilationUnitElement elem = unit.element;
+      if (elem != null) {
+        return elem.library;
+      }
+    }
+    return null;
+  }
+
+  @override
+  InterfaceType get objectType {
+    if (_objectType == null) {
+      _objectType = coreLib.getType('Object').type;
+    }
+    return _objectType;
+  }
+
+  OpType get opType {
+    if (_opType == null) {
+      _opType = new OpType.forCompletion(target, offset);
+    }
+    return _opType;
+  }
+
+  // For internal use only
+  @override
+  Future<List<Directive>> resolveDirectives() async {
+    CompilationUnit libUnit;
+    if (librarySource != null) {
+      // TODO(danrubel) only resolve the directives
+      const RESOLVE_DIRECTIVES_TAG = 'resolve directives';
+      performance.logStartTime(RESOLVE_DIRECTIVES_TAG);
+      libUnit = await new AnalysisFutureHelper<CompilationUnit>(
+              context,
+              new LibrarySpecificUnit(librarySource, librarySource),
+              RESOLVED_UNIT3)
+          .computeAsync();
+      performance.logElapseTime(RESOLVE_DIRECTIVES_TAG);
+    }
+    return libUnit?.directives;
+  }
+
+  @override
+  Future resolveExpression(Expression expression) async {
+    // Return immediately if the expression has already been resolved
+    if (expression.propagatedType != null) {
+      return;
+    }
+
+    // Gracefully degrade if librarySource cannot be determined
+    if (librarySource == null) {
+      return;
+    }
+
+    // Resolve declarations in the target unit
+    // TODO(danrubel) resolve the expression or containing method
+    // rather than the entire complilation unit
+    const RESOLVE_EXPRESSION_TAG = 'resolve expression';
+    performance.logStartTime(RESOLVE_EXPRESSION_TAG);
+    CompilationUnit resolvedUnit =
+        await new AnalysisFutureHelper<CompilationUnit>(context,
+                new LibrarySpecificUnit(librarySource, source), RESOLVED_UNIT)
+            .computeAsync();
+    performance.logElapseTime(RESOLVE_EXPRESSION_TAG);
+
+    // TODO(danrubel) determine if the underlying source has been modified
+    // in a way that invalidates the completion request
+    // and return null
+
+    // Gracefully degrade if unit cannot be resolved
+    if (resolvedUnit == null) {
+      return;
+    }
+
+    // Recompute the target for the newly resolved unit
+    _updateTargets(resolvedUnit);
+  }
+
+  /**
+   * Update the completion [target] and [dotTarget] based on the given [unit].
+   */
+  void _updateTargets(CompilationUnit unit) {
+    _opType = null;
+    dotTarget = null;
+    target = new CompletionTarget.forOffset(unit, offset);
+    AstNode node = target.containingNode;
+    if (node is MethodInvocation) {
+      if (identical(node.methodName, target.entity)) {
+        dotTarget = node.realTarget;
+      } else if (node.isCascaded && node.operator.offset + 1 == target.offset) {
+        dotTarget = node.realTarget;
+      }
+    }
+    if (node is PropertyAccess) {
+      if (identical(node.propertyName, target.entity)) {
+        dotTarget = node.realTarget;
+      } else if (node.isCascaded && node.operator.offset + 1 == target.offset) {
+        dotTarget = node.realTarget;
+      }
+    }
+    if (node is PrefixedIdentifier) {
+      if (identical(node.identifier, target.entity)) {
+        dotTarget = node.prefix;
+      }
+    }
+  }
+
+  /**
+   * Return a [Future] that completes with a newly created completion request
+   * based on the given [request].
+   */
+  static Future<DartCompletionRequest> from(CompletionRequest request) async {
+    CompletionPerformance performance =
+        (request as CompletionRequestImpl).performance;
+    const BUILD_REQUEST_TAG = 'build DartCompletionRequest';
+    performance.logStartTime(BUILD_REQUEST_TAG);
+
+    Source source = request.source;
+    AnalysisContext context = request.context;
+
+    const PARSE_TAG = 'parse unit';
+    performance.logStartTime(PARSE_TAG);
+    CompilationUnit unit = request.context.computeResult(source, PARSED_UNIT);
+    performance.logElapseTime(PARSE_TAG);
+
+    Source libSource;
+    if (unit.directives.any((d) => d is PartOfDirective)) {
+      List<Source> libraries = context.getLibrariesContaining(source);
+      if (libraries.isNotEmpty) {
+        libSource = libraries[0];
+      }
+    } else {
+      libSource = source;
+    }
+
+    // Most (all?) contributors need declarations in scope to be resolved
+    if (libSource != null) {
+      const RESOLVE_DECLARATIONS_TAG = 'resolve declarations';
+      performance.logStartTime(RESOLVE_DECLARATIONS_TAG);
+      unit = await new AnalysisFutureHelper<CompilationUnit>(context,
+              new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3)
+          .computeAsync();
+      performance.logElapseTime(RESOLVE_DECLARATIONS_TAG);
+    }
+
+    DartCompletionRequestImpl dartRequest = new DartCompletionRequestImpl._(
+        request.context,
+        request.resourceProvider,
+        request.searchEngine,
+        libSource,
+        request.source,
+        request.offset,
+        unit,
+        performance);
+
+    // Resolve the expression in which the completion occurs
+    // to properly determine if identifiers should be suggested
+    // rather than invocations.
+    if (dartRequest.target.maybeFunctionalArgument()) {
+      AstNode node = dartRequest.target.containingNode.parent;
+      if (node is Expression) {
+        const FUNCTIONAL_ARG_TAG = 'resolve expression for isFunctionalArg';
+        performance.logStartTime(FUNCTIONAL_ARG_TAG);
+        await dartRequest.resolveExpression(node);
+        performance.logElapseTime(FUNCTIONAL_ARG_TAG);
+      }
+    }
+
+    performance.logElapseTime(BUILD_REQUEST_TAG);
+    return dartRequest;
+  }
+}
+
+/**
+ * Utility class for computing the code completion replacement range
+ */
+class ReplacementRange {
+  int offset;
+  int length;
+
+  ReplacementRange(this.offset, this.length);
+
+  factory ReplacementRange.compute(int requestOffset, CompletionTarget target) {
+    bool isKeywordOrIdentifier(Token token) =>
+        token.type == TokenType.KEYWORD || token.type == TokenType.IDENTIFIER;
+
+    //TODO(danrubel) Ideally this needs to be pushed down into the contributors
+    // but that implies that each suggestion can have a different
+    // replacement offsent/length which would mean an API change
+
+    var entity = target.entity;
+    Token token = entity is AstNode ? entity.beginToken : entity;
+    if (token != null && requestOffset < token.offset) {
+      token = token.previous;
+    }
+    if (token != null) {
+      if (requestOffset == token.offset && !isKeywordOrIdentifier(token)) {
+        // If the insertion point is at the beginning of the current token
+        // and the current token is not an identifier
+        // then check the previous token to see if it should be replaced
+        token = token.previous;
+      }
+      if (token != null && isKeywordOrIdentifier(token)) {
+        if (token.offset <= requestOffset && requestOffset <= token.end) {
+          // Replacement range for typical identifier completion
+          return new ReplacementRange(token.offset, token.length);
+        }
+      }
+      if (token is StringToken) {
+        SimpleStringLiteral uri = new SimpleStringLiteral(token, token.lexeme);
+        Token previous = token.previous;
+        if (previous is KeywordToken) {
+          Keyword keyword = previous.keyword;
+          if (keyword == Keyword.IMPORT ||
+              keyword == Keyword.EXPORT ||
+              keyword == Keyword.PART) {
+            int start = uri.contentsOffset;
+            var end = uri.contentsEnd;
+            if (start <= requestOffset && requestOffset <= end) {
+              // Replacement range for import URI
+              return new ReplacementRange(start, end - start);
+            }
+          }
+        }
+      }
+    }
+    return new ReplacementRange(requestOffset, 0);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart b/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart
new file mode 100644
index 0000000..667b883
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart
@@ -0,0 +1,26 @@
+// 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 services.completion.dart.sorter;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+
+/**
+ * The abstract class [DartContributionSorter] defines the behavior of objects
+ * that are used to adjust the relevance of an existing list of suggestions.
+ * This is a long-lived object that should not maintain state between
+ * calls to it's [sort] method.
+ */
+abstract class DartContributionSorter {
+  /**
+   * After [CompletionSuggestion]s have been computed,
+   * this method is called to adjust the relevance of those suggestions.
+   * Return a [Future] that completes when the suggestions have been updated.
+   */
+  Future sort(DartCompletionRequest request,
+      Iterable<CompletionSuggestion> suggestions);
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
new file mode 100644
index 0000000..3c16a7d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
@@ -0,0 +1,76 @@
+// 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 services.completion.contributor.dart.field_formal;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/protocol_server.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/generated/ast.dart';
+
+/**
+ * A contributor for calculating invocation / access suggestions
+ * `completion.getSuggestions` request results.
+ */
+class FieldFormalContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    AstNode node = request.target.containingNode;
+    if (node is! FieldFormalParameter) {
+      return EMPTY_LIST;
+    }
+
+    // If this is a constructor declaration
+    // then compute fields already referenced
+    ConstructorDeclaration constructorDecl =
+        node.getAncestor((p) => p is ConstructorDeclaration);
+    if (constructorDecl == null) {
+      return EMPTY_LIST;
+    }
+
+    // Compute the list of fields already referenced in the constructor
+    List<String> referencedFields = new List<String>();
+    for (FormalParameter param in constructorDecl.parameters.parameters) {
+      if (param is FieldFormalParameter) {
+        SimpleIdentifier fieldId = param.identifier;
+        if (fieldId != null && fieldId != request.target.entity) {
+          String fieldName = fieldId.name;
+          if (fieldName != null && fieldName.length > 0) {
+            referencedFields.add(fieldName);
+          }
+        }
+      }
+    }
+
+    // Add suggestions for fields that are not already referenced
+    ClassDeclaration classDecl =
+        constructorDecl.getAncestor((p) => p is ClassDeclaration);
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    for (ClassMember member in classDecl.members) {
+      if (member is FieldDeclaration && !member.isStatic) {
+        for (VariableDeclaration varDecl in member.fields.variables) {
+          SimpleIdentifier fieldId = varDecl.name;
+          if (fieldId != null) {
+            String fieldName = fieldId.name;
+            if (fieldName != null && fieldName.length > 0) {
+              if (!referencedFields.contains(fieldName)) {
+                CompletionSuggestion suggestion = createSuggestion(
+                    fieldId.bestElement,
+                    relevance: DART_RELEVANCE_LOCAL_FIELD);
+                if (suggestion != null) {
+                  suggestions.add(suggestion);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    return suggestions;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
new file mode 100644
index 0000000..736f2a0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
@@ -0,0 +1,96 @@
+// 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 services.completion.contributor.dart.imported_ref;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+import 'package:analyzer/src/generated/resolver.dart';
+
+/**
+ * A contributor for calculating suggestions for imported top level members.
+ */
+class ImportedReferenceContributor extends DartCompletionContributor {
+  DartCompletionRequest request;
+  OpType optype;
+
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    if (!request.includeIdentifiers) {
+      return EMPTY_LIST;
+    }
+
+    List<Directive> directives = await request.resolveDirectives();
+    if (directives == null) {
+      return EMPTY_LIST;
+    }
+
+    this.request = request;
+    this.optype = (request as DartCompletionRequestImpl).opType;
+
+    // Traverse dart:core
+    List<CompletionSuggestion> suggestions =
+        _buildSuggestions(request.coreLib.exportNamespace);
+
+    // Traverse imports
+    for (Directive directive in directives) {
+      if (directive is ImportDirective) {
+        ImportElement importElem = directive.element;
+        LibraryElement libElem = importElem?.importedLibrary;
+        if (libElem != null) {
+          suggestions.addAll(_buildSuggestions(libElem.exportNamespace,
+              prefix: importElem.prefix?.name,
+              showNames: showNamesIn(importElem),
+              hiddenNames: hiddenNamesIn(importElem)));
+        }
+      }
+    }
+
+    return suggestions;
+  }
+
+  List<CompletionSuggestion> _buildSuggestions(Namespace namespace,
+      {String prefix, List<String> showNames, List<String> hiddenNames}) {
+    LibraryElementSuggestionBuilder visitor =
+        new LibraryElementSuggestionBuilder(request, optype, prefix);
+    for (Element elem in namespace.definedNames.values) {
+      if (showNames != null && !showNames.contains(elem.name)) {
+        continue;
+      }
+      if (hiddenNames != null && hiddenNames.contains(elem.name)) {
+        continue;
+      }
+      elem.accept(visitor);
+    }
+    return visitor.suggestions;
+  }
+}
+
+List<String> showNamesIn(ImportElement importElem) {
+  for (NamespaceCombinator combinator in importElem.combinators) {
+    if (combinator is ShowElementCombinator) {
+      return combinator.shownNames;
+    }
+  }
+  return null;
+}
+
+List<String> hiddenNamesIn(ImportElement importElem) {
+  for (NamespaceCombinator combinator in importElem.combinators) {
+    if (combinator is HideElementCombinator) {
+      return combinator.hiddenNames;
+    }
+  }
+  return null;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
new file mode 100644
index 0000000..bf1633e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library services.completion.contributor.dart.inherited_ref;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating suggestions for inherited references.
+ */
+class InheritedReferenceContributor extends DartCompletionContributor
+    with ElementSuggestionBuilder {
+  @override
+  LibraryElement containingLibrary;
+
+  @override
+  CompletionSuggestionKind kind;
+
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    if (!request.includeIdentifiers) {
+      return EMPTY_LIST;
+    }
+    ClassDeclaration classDecl = _enclosingClass(request.target);
+    if (classDecl == null || classDecl.element == null) {
+      return EMPTY_LIST;
+    }
+
+    containingLibrary = request.libraryElement;
+    bool isFunctionalArgument = request.target.isFunctionalArgument();
+    kind = isFunctionalArgument
+        ? CompletionSuggestionKind.IDENTIFIER
+        : CompletionSuggestionKind.INVOCATION;
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+    for (InterfaceType type in classDecl.element.allSupertypes) {
+      if (!isFunctionalArgument) {
+        for (PropertyAccessorElement elem in type.accessors) {
+          if (elem.isGetter) {
+            if (optype.includeReturnValueSuggestions) {
+              addSuggestion(elem);
+            }
+          } else {
+            if (optype.includeVoidReturnSuggestions) {
+              addSuggestion(elem);
+            }
+          }
+        }
+      }
+      for (MethodElement elem in type.methods) {
+        if (elem.returnType == null) {
+          addSuggestion(elem);
+        } else if (!elem.returnType.isVoid) {
+          if (optype.includeReturnValueSuggestions) {
+            addSuggestion(elem);
+          }
+        } else {
+          if (optype.includeVoidReturnSuggestions) {
+            addSuggestion(elem);
+          }
+        }
+      }
+    }
+    return suggestions;
+  }
+}
+
+/**
+ * Return the class containing the target
+ * or `null` if the target is in a static method or field
+ * or not in a class.
+ */
+ClassDeclaration _enclosingClass(CompletionTarget target) {
+  AstNode node = target.containingNode;
+  while (node != null) {
+    if (node is ClassDeclaration) {
+      return node;
+    }
+    if (node is MethodDeclaration) {
+      if (node.isStatic) {
+        return null;
+      }
+    }
+    if (node is FieldDeclaration) {
+      if (node.isStatic) {
+        return null;
+      }
+    }
+    node = node.parent;
+  }
+  return null;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
new file mode 100644
index 0000000..9892a10
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -0,0 +1,557 @@
+// 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 services.completion.dart.keyword;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+
+const ASYNC = 'async';
+const ASYNC_STAR = 'async*';
+const AWAIT = 'await';
+const SYNC_STAR = 'sync*';
+const YIELD = 'yield';
+const YIELD_STAR = 'yield*';
+
+/**
+ * A contributor for calculating `completion.getSuggestions` request results
+ * for the local library in which the completion is requested.
+ */
+class KeywordContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    request.target.containingNode
+        .accept(new _KeywordVisitor(request, suggestions));
+    return suggestions;
+  }
+}
+
+/**
+ * A visitor for generating keyword suggestions.
+ */
+class _KeywordVisitor extends GeneralizingAstVisitor {
+  final DartCompletionRequest request;
+  final Object entity;
+  final List<CompletionSuggestion> suggestions;
+
+  _KeywordVisitor(DartCompletionRequest request, this.suggestions)
+      : this.request = request,
+        this.entity = request.target.entity;
+
+  @override
+  visitArgumentList(ArgumentList node) {
+    if (entity == node.rightParenthesis) {
+      _addExpressionKeywords(node);
+      Token previous = (entity as Token).previous;
+      if (previous.isSynthetic) {
+        previous = previous.previous;
+      }
+      if (previous.lexeme == ')') {
+        _addSuggestion2(ASYNC);
+        _addSuggestion2(ASYNC_STAR);
+        _addSuggestion2(SYNC_STAR);
+      }
+    }
+    if (entity is SimpleIdentifier && node.arguments.contains(entity)) {
+      _addExpressionKeywords(node);
+    }
+  }
+
+  @override
+  visitBlock(Block node) {
+    if (entity is ExpressionStatement) {
+      Expression expression = (entity as ExpressionStatement).expression;
+      if (expression is SimpleIdentifier) {
+        Token token = expression.token;
+        Token previous = token.previous;
+        if (previous.isSynthetic) {
+          previous = previous.previous;
+        }
+        Token next = token.next;
+        if (next.isSynthetic) {
+          next = next.next;
+        }
+        if (previous.lexeme == ')' && next.lexeme == '{') {
+          _addSuggestion2(ASYNC);
+          _addSuggestion2(ASYNC_STAR);
+          _addSuggestion2(SYNC_STAR);
+        }
+      }
+    }
+    _addStatementKeywords(node);
+    if (_inCatchClause(node)) {
+      _addSuggestion(Keyword.RETHROW, DART_RELEVANCE_KEYWORD - 1);
+    }
+  }
+
+  @override
+  visitClassDeclaration(ClassDeclaration node) {
+    // Don't suggest class name
+    if (entity == node.name) {
+      return;
+    }
+    if (entity == node.rightBracket) {
+      _addClassBodyKeywords();
+    } else if (entity is ClassMember) {
+      _addClassBodyKeywords();
+      int index = node.members.indexOf(entity);
+      ClassMember previous = index > 0 ? node.members[index - 1] : null;
+      if (previous is MethodDeclaration && previous.body is EmptyFunctionBody) {
+        _addSuggestion2(ASYNC);
+        _addSuggestion2(ASYNC_STAR);
+        _addSuggestion2(SYNC_STAR);
+      }
+    } else {
+      _addClassDeclarationKeywords(node);
+    }
+  }
+
+  @override
+  visitCompilationUnit(CompilationUnit node) {
+    var previousMember = null;
+    for (var member in node.childEntities) {
+      if (entity == member) {
+        break;
+      }
+      previousMember = member;
+    }
+    if (previousMember is ClassDeclaration) {
+      if (previousMember.leftBracket == null ||
+          previousMember.leftBracket.isSynthetic) {
+        // If the prior member is an unfinished class declaration
+        // then the user is probably finishing that
+        _addClassDeclarationKeywords(previousMember);
+        return;
+      }
+    }
+    if (previousMember is ImportDirective) {
+      if (previousMember.semicolon == null ||
+          previousMember.semicolon.isSynthetic) {
+        // If the prior member is an unfinished import directive
+        // then the user is probably finishing that
+        _addImportDirectiveKeywords(previousMember);
+        return;
+      }
+    }
+    if (previousMember == null || previousMember is Directive) {
+      if (previousMember == null &&
+          !node.directives.any((d) => d is LibraryDirective)) {
+        _addSuggestions([Keyword.LIBRARY], DART_RELEVANCE_HIGH);
+      }
+      _addSuggestions(
+          [Keyword.IMPORT, Keyword.EXPORT, Keyword.PART], DART_RELEVANCE_HIGH);
+    }
+    if (entity == null || entity is Declaration) {
+      if (previousMember is FunctionDeclaration &&
+          previousMember.functionExpression is FunctionExpression &&
+          previousMember.functionExpression.body is EmptyFunctionBody) {
+        _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+        _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+        _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+      }
+      _addCompilationUnitKeywords();
+    }
+  }
+
+  @override
+  visitExpression(Expression node) {
+    _addExpressionKeywords(node);
+  }
+
+  @override
+  visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    if (entity == node.expression) {
+      _addExpressionKeywords(node);
+    }
+  }
+
+  @override
+  visitForEachStatement(ForEachStatement node) {
+    if (entity == node.inKeyword) {
+      Token previous = node.inKeyword.previous;
+      if (previous is SyntheticStringToken && previous.lexeme == 'in') {
+        previous = previous.previous;
+      }
+      if (previous != null && previous.type == TokenType.EQ) {
+        _addSuggestions([
+          Keyword.CONST,
+          Keyword.FALSE,
+          Keyword.NEW,
+          Keyword.NULL,
+          Keyword.TRUE
+        ]);
+      } else {
+        _addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH);
+      }
+    }
+  }
+
+  @override
+  visitFormalParameterList(FormalParameterList node) {
+    AstNode constructorDeclaration =
+        node.getAncestor((p) => p is ConstructorDeclaration);
+    if (constructorDeclaration != null) {
+      _addSuggestions([Keyword.THIS]);
+    }
+  }
+
+  @override
+  visitForStatement(ForStatement node) {
+    // Handle the degenerate case while typing - for (int x i^)
+    if (node.condition == entity && entity is SimpleIdentifier) {
+      Token entityToken = (entity as SimpleIdentifier).beginToken;
+      if (entityToken.previous.isSynthetic &&
+          entityToken.previous.type == TokenType.SEMICOLON) {
+        _addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH);
+      }
+    }
+  }
+
+  @override
+  visitFunctionExpression(FunctionExpression node) {
+    if (entity == node.body) {
+      FunctionBody body = node.body;
+      if (!body.isAsynchronous) {
+        _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+        if (body is! ExpressionFunctionBody) {
+          _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+          _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+        }
+      }
+      if (node.body is EmptyFunctionBody &&
+          node.parent is FunctionDeclaration &&
+          node.parent.parent is CompilationUnit) {
+        _addCompilationUnitKeywords();
+      }
+    }
+  }
+
+  @override
+  visitIfStatement(IfStatement node) {
+    if (entity == node.thenStatement) {
+      _addStatementKeywords(node);
+    } else if (entity == node.condition) {
+      _addExpressionKeywords(node);
+    }
+  }
+
+  @override
+  visitImportDirective(ImportDirective node) {
+    if (entity == node.asKeyword) {
+      if (node.deferredKeyword == null) {
+        _addSuggestion(Keyword.DEFERRED, DART_RELEVANCE_HIGH);
+      }
+    }
+    // Handle degenerate case where import statement does not have a semicolon
+    // and the cursor is in the uri string
+    if ((entity == node.semicolon &&
+            node.uri != null &&
+            node.uri.offset + 1 != request.offset) ||
+        node.combinators.contains(entity)) {
+      _addImportDirectiveKeywords(node);
+    }
+  }
+
+  @override
+  visitInstanceCreationExpression(InstanceCreationExpression node) {
+    if (entity == node.constructorName) {
+      // no keywords in 'new ^' expression
+    } else {
+      super.visitInstanceCreationExpression(node);
+    }
+  }
+
+  @override
+  visitIsExpression(IsExpression node) {
+    if (entity == node.isOperator) {
+      _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH);
+    } else {
+      _addExpressionKeywords(node);
+    }
+  }
+
+  @override
+  visitLibraryIdentifier(LibraryIdentifier node) {
+    // no suggestions
+  }
+
+  @override
+  visitMethodDeclaration(MethodDeclaration node) {
+    if (entity == node.body) {
+      if (node.body is EmptyFunctionBody) {
+        _addClassBodyKeywords();
+        _addSuggestion2(ASYNC);
+        _addSuggestion2(ASYNC_STAR);
+        _addSuggestion2(SYNC_STAR);
+      } else {
+        _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+        if (node.body is! ExpressionFunctionBody) {
+          _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+          _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+        }
+      }
+    }
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    if (entity == node.methodName) {
+      // no keywords in '.' expression
+    } else {
+      super.visitMethodInvocation(node);
+    }
+  }
+
+  @override
+  visitNamedExpression(NamedExpression node) {
+    if (entity is SimpleIdentifier && entity == node.expression) {
+      _addExpressionKeywords(node);
+    }
+  }
+
+  @override
+  visitNode(AstNode node) {
+    // ignored
+  }
+
+  @override
+  visitPrefixedIdentifier(PrefixedIdentifier node) {
+    if (entity != node.identifier) {
+      _addExpressionKeywords(node);
+    }
+  }
+
+  @override
+  visitPropertyAccess(PropertyAccess node) {
+    // suggestions before '.' but not after
+    if (entity != node.propertyName) {
+      super.visitPropertyAccess(node);
+    }
+  }
+
+  @override
+  visitReturnStatement(ReturnStatement node) {
+    if (entity == node.expression) {
+      _addExpressionKeywords(node);
+    }
+  }
+
+  @override
+  visitStringLiteral(StringLiteral node) {
+    // ignored
+  }
+
+  @override
+  visitSwitchStatement(SwitchStatement node) {
+    if (entity == node.expression) {
+      _addExpressionKeywords(node);
+    } else if (entity == node.rightBracket) {
+      if (node.members.isEmpty) {
+        _addSuggestions([Keyword.CASE, Keyword.DEFAULT], DART_RELEVANCE_HIGH);
+      } else {
+        _addSuggestions([Keyword.CASE, Keyword.DEFAULT]);
+        _addStatementKeywords(node);
+      }
+    }
+    if (node.members.contains(entity)) {
+      if (entity == node.members.first) {
+        _addSuggestions([Keyword.CASE, Keyword.DEFAULT], DART_RELEVANCE_HIGH);
+      } else {
+        _addSuggestions([Keyword.CASE, Keyword.DEFAULT]);
+        _addStatementKeywords(node);
+      }
+    }
+  }
+
+  @override
+  visitVariableDeclaration(VariableDeclaration node) {
+    if (entity == node.initializer) {
+      _addExpressionKeywords(node);
+    }
+  }
+
+  void _addClassBodyKeywords() {
+    _addSuggestions([
+      Keyword.CONST,
+      Keyword.DYNAMIC,
+      Keyword.FACTORY,
+      Keyword.FINAL,
+      Keyword.GET,
+      Keyword.OPERATOR,
+      Keyword.SET,
+      Keyword.STATIC,
+      Keyword.VAR,
+      Keyword.VOID
+    ]);
+  }
+
+  void _addClassDeclarationKeywords(ClassDeclaration node) {
+    // Very simplistic suggestion because analyzer will warn if
+    // the extends / with / implements keywords are out of order
+    if (node.extendsClause == null) {
+      _addSuggestion(Keyword.EXTENDS, DART_RELEVANCE_HIGH);
+    } else if (node.withClause == null) {
+      _addSuggestion(Keyword.WITH, DART_RELEVANCE_HIGH);
+    }
+    if (node.implementsClause == null) {
+      _addSuggestion(Keyword.IMPLEMENTS, DART_RELEVANCE_HIGH);
+    }
+  }
+
+  void _addCompilationUnitKeywords() {
+    _addSuggestions([
+      Keyword.ABSTRACT,
+      Keyword.CLASS,
+      Keyword.CONST,
+      Keyword.DYNAMIC,
+      Keyword.FINAL,
+      Keyword.TYPEDEF,
+      Keyword.VAR,
+      Keyword.VOID
+    ], DART_RELEVANCE_HIGH);
+  }
+
+  void _addExpressionKeywords(AstNode node) {
+    _addSuggestions([
+      Keyword.CONST,
+      Keyword.FALSE,
+      Keyword.NEW,
+      Keyword.NULL,
+      Keyword.TRUE,
+    ]);
+    if (_inClassMemberBody(node)) {
+      _addSuggestions([Keyword.SUPER, Keyword.THIS,]);
+    }
+    if (_inAsyncMethodOrFunction(node)) {
+      _addSuggestion2(AWAIT);
+    }
+  }
+
+  void _addImportDirectiveKeywords(ImportDirective node) {
+    bool hasDeferredKeyword = node.deferredKeyword != null;
+    bool hasAsKeyword = node.asKeyword != null;
+    if (!hasAsKeyword) {
+      _addSuggestion(Keyword.AS, DART_RELEVANCE_HIGH);
+    }
+    if (!hasDeferredKeyword) {
+      if (!hasAsKeyword) {
+        _addSuggestion2('deferred as', relevance: DART_RELEVANCE_HIGH);
+      } else if (entity == node.asKeyword) {
+        _addSuggestion(Keyword.DEFERRED, DART_RELEVANCE_HIGH);
+      }
+    }
+    if (!hasDeferredKeyword || hasAsKeyword) {
+      if (node.combinators.isEmpty) {
+        _addSuggestion2('show', relevance: DART_RELEVANCE_HIGH);
+        _addSuggestion2('hide', relevance: DART_RELEVANCE_HIGH);
+      }
+    }
+  }
+
+  void _addStatementKeywords(AstNode node) {
+    if (_inClassMemberBody(node)) {
+      _addSuggestions([Keyword.SUPER, Keyword.THIS,]);
+    }
+    if (_inAsyncMethodOrFunction(node)) {
+      _addSuggestion2(AWAIT);
+    } else if (_inAsyncStarOrSyncStarMethodOrFunction(node)) {
+      _addSuggestion2(AWAIT);
+      _addSuggestion2(YIELD);
+      _addSuggestion2(YIELD_STAR);
+    }
+    if (_inLoop(node)) {
+      _addSuggestions([Keyword.BREAK, Keyword.CONTINUE]);
+    }
+    if (_inSwitch(node)) {
+      _addSuggestions([Keyword.BREAK]);
+    }
+    _addSuggestions([
+      Keyword.ASSERT,
+      Keyword.CONST,
+      Keyword.DO,
+      Keyword.FINAL,
+      Keyword.FOR,
+      Keyword.IF,
+      Keyword.NEW,
+      Keyword.RETURN,
+      Keyword.SWITCH,
+      Keyword.THROW,
+      Keyword.TRY,
+      Keyword.VAR,
+      Keyword.VOID,
+      Keyword.WHILE
+    ]);
+  }
+
+  void _addSuggestion(Keyword keyword,
+      [int relevance = DART_RELEVANCE_KEYWORD]) {
+    _addSuggestion2(keyword.syntax, relevance: relevance);
+  }
+
+  void _addSuggestion2(String completion,
+      {int offset, int relevance: DART_RELEVANCE_KEYWORD}) {
+    if (offset == null) {
+      offset = completion.length;
+    }
+    suggestions.add(new CompletionSuggestion(CompletionSuggestionKind.KEYWORD,
+        relevance, completion, offset, 0, false, false));
+  }
+
+  void _addSuggestions(List<Keyword> keywords,
+      [int relevance = DART_RELEVANCE_KEYWORD]) {
+    keywords.forEach((Keyword keyword) {
+      _addSuggestion(keyword, relevance);
+    });
+  }
+
+  bool _inAsyncMethodOrFunction(AstNode node) {
+    FunctionBody body = node.getAncestor((n) => n is FunctionBody);
+    return body != null && body.isAsynchronous && body.star == null;
+  }
+
+  bool _inAsyncStarOrSyncStarMethodOrFunction(AstNode node) {
+    FunctionBody body = node.getAncestor((n) => n is FunctionBody);
+    return body != null && body.keyword != null && body.star != null;
+  }
+
+  bool _inCatchClause(Block node) =>
+      node.getAncestor((p) => p is CatchClause) != null;
+
+  bool _inClassMemberBody(AstNode node) {
+    while (true) {
+      AstNode body = node.getAncestor((n) => n is FunctionBody);
+      if (body == null) {
+        return false;
+      }
+      AstNode parent = body.parent;
+      if (parent is ConstructorDeclaration || parent is MethodDeclaration) {
+        return true;
+      }
+      node = parent;
+    }
+  }
+
+  bool _inDoLoop(AstNode node) =>
+      node.getAncestor((p) => p is DoStatement) != null;
+
+  bool _inForLoop(AstNode node) =>
+      node.getAncestor((p) => p is ForStatement || p is ForEachStatement) !=
+      null;
+
+  bool _inLoop(AstNode node) =>
+      _inDoLoop(node) || _inForLoop(node) || _inWhileLoop(node);
+
+  bool _inSwitch(AstNode node) =>
+      node.getAncestor((p) => p is SwitchStatement) != null;
+
+  bool _inWhileLoop(AstNode node) =>
+      node.getAncestor((p) => p is WhileStatement) != null;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
new file mode 100644
index 0000000..014d4ee
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -0,0 +1,286 @@
+// 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 services.completion.contributor.dart.label;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
+    show DartCompletionRequestImpl;
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart'
+    show LocalDeclarationVisitor;
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind, Location;
+
+const DYNAMIC = 'dynamic';
+
+final TypeName NO_RETURN_TYPE = new TypeName(
+    new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null);
+
+/**
+ * A contributor for calculating label suggestions.
+ */
+class LabelContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+
+    // Collect suggestions from the specific child [AstNode] that contains
+    // the completion offset and all of its parents recursively.
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    if (!optype.isPrefixed) {
+      if (optype.includeStatementLabelSuggestions ||
+          optype.includeCaseLabelSuggestions) {
+        new _LabelVisitor(request, optype.includeStatementLabelSuggestions,
+                optype.includeCaseLabelSuggestions, suggestions)
+            .visit(request.target.containingNode);
+      }
+    }
+    return suggestions;
+  }
+}
+
+/**
+ * A visitor for collecting suggestions for break and continue labels.
+ */
+class _LabelVisitor extends LocalDeclarationVisitor {
+  final DartCompletionRequest request;
+  final List<CompletionSuggestion> suggestions;
+
+  /**
+   * True if statement labels should be included as suggestions.
+   */
+  final bool includeStatementLabels;
+
+  /**
+   * True if case labels should be included as suggestions.
+   */
+  final bool includeCaseLabels;
+
+  _LabelVisitor(DartCompletionRequest request, this.includeStatementLabels,
+      this.includeCaseLabels, this.suggestions)
+      : super(request.offset),
+        request = request;
+
+  @override
+  void declaredClass(ClassDeclaration declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredClassTypeAlias(ClassTypeAlias declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+    // ignored
+  }
+
+  @override
+  void declaredFunction(FunctionDeclaration declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredLabel(Label label, bool isCaseLabel) {
+    if (isCaseLabel ? includeCaseLabels : includeStatementLabels) {
+      CompletionSuggestion suggestion = _addSuggestion(label.label);
+      if (suggestion != null) {
+        suggestion.element = createLocalElement(
+            request.source, protocol.ElementKind.LABEL, label.label,
+            returnType: NO_RETURN_TYPE);
+      }
+    }
+  }
+
+  @override
+  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
+    // ignored
+  }
+
+  @override
+  void declaredMethod(MethodDeclaration declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredParam(SimpleIdentifier name, TypeName type) {
+    // ignored
+  }
+
+  @override
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl) {
+    // ignored
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    // Labels are only accessible within the local function, so stop visiting
+    // once we reach a function boundary.
+    finished();
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    // Labels are only accessible within the local function, so stop visiting
+    // once we reach a function boundary.
+    finished();
+  }
+
+  CompletionSuggestion _addSuggestion(SimpleIdentifier id) {
+    if (id != null) {
+      String completion = id.name;
+      if (completion != null && completion.length > 0 && completion != '_') {
+        CompletionSuggestion suggestion = new CompletionSuggestion(
+            CompletionSuggestionKind.IDENTIFIER,
+            DART_RELEVANCE_DEFAULT,
+            completion,
+            completion.length,
+            0,
+            false,
+            false);
+        suggestions.add(suggestion);
+        return suggestion;
+      }
+    }
+    return null;
+  }
+}
+
+/**
+* Create a new protocol Element for inclusion in a completion suggestion.
+*/
+protocol.Element createLocalElement(
+    Source source, protocol.ElementKind kind, SimpleIdentifier id,
+    {String parameters,
+    TypeName returnType,
+    bool isAbstract: false,
+    bool isDeprecated: false}) {
+  String name;
+  Location location;
+  if (id != null) {
+    name = id.name;
+    // TODO(danrubel) use lineInfo to determine startLine and startColumn
+    location = new Location(source.fullName, id.offset, id.length, 0, 0);
+  } else {
+    name = '';
+    location = new Location(source.fullName, -1, 0, 1, 0);
+  }
+  int flags = protocol.Element.makeFlags(
+      isAbstract: isAbstract,
+      isDeprecated: isDeprecated,
+      isPrivate: Identifier.isPrivateName(name));
+  return new protocol.Element(kind, name, flags,
+      location: location,
+      parameters: parameters,
+      returnType: nameForType(returnType));
+}
+
+/**
+* Create a new suggestion for the given field.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion createLocalFieldSuggestion(
+    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+  bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
+  TypeName type = fieldDecl.fields.type;
+  return createLocalSuggestion(
+      varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
+      classDecl: fieldDecl.parent,
+      element: createLocalElement(
+          source, protocol.ElementKind.FIELD, varDecl.name,
+          returnType: type, isDeprecated: deprecated));
+}
+
+/**
+* Create a new suggestion based upon the given information.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion createLocalSuggestion(SimpleIdentifier id,
+    bool isDeprecated, int defaultRelevance, TypeName returnType,
+    {ClassDeclaration classDecl, protocol.Element element}) {
+  if (id == null) {
+    return null;
+  }
+  String completion = id.name;
+  if (completion == null || completion.length <= 0 || completion == '_') {
+    return null;
+  }
+  CompletionSuggestion suggestion = new CompletionSuggestion(
+      CompletionSuggestionKind.INVOCATION,
+      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
+      completion,
+      completion.length,
+      0,
+      isDeprecated,
+      false,
+      returnType: nameForType(returnType),
+      element: element);
+  if (classDecl != null) {
+    SimpleIdentifier classId = classDecl.name;
+    if (classId != null) {
+      String className = classId.name;
+      if (className != null && className.length > 0) {
+        suggestion.declaringType = className;
+      }
+    }
+  }
+  return suggestion;
+}
+
+/**
+* Return `true` if the @deprecated annotation is present
+*/
+bool isDeprecated(AnnotatedNode node) {
+  if (node != null) {
+    NodeList<Annotation> metadata = node.metadata;
+    if (metadata != null) {
+      return metadata.any((Annotation a) {
+        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
+      });
+    }
+  }
+  return false;
+}
+
+/**
+* Return the name for the given type.
+*/
+String nameForType(TypeName type) {
+  if (type == NO_RETURN_TYPE) {
+    return null;
+  }
+  if (type == null) {
+    return DYNAMIC;
+  }
+  Identifier id = type.name;
+  if (id == null) {
+    return DYNAMIC;
+  }
+  String name = id.name;
+  if (name == null || name.length <= 0) {
+    return DYNAMIC;
+  }
+  TypeArgumentList typeArgs = type.typeArguments;
+  if (typeArgs != null) {
+    //TODO (danrubel) include type arguments
+  }
+  return name;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
new file mode 100644
index 0000000..c7b9590
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -0,0 +1,90 @@
+// 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 services.completion.contributor.dart.library_member;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating prefixed import library member suggestions
+ * `completion.getSuggestions` request results.
+ */
+class LibraryMemberContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    // Determine if the target looks like a library prefix
+    if (request.dotTarget is! SimpleIdentifier) {
+      return EMPTY_LIST;
+    }
+
+    // Resolve the expression and the containing library
+    await request.resolveExpression(request.dotTarget);
+
+    // Recompute the target since resolution may have changed it
+    Expression targetId = request.dotTarget;
+    if (targetId is SimpleIdentifier && !request.target.isCascade) {
+      Element elem = targetId.bestElement;
+      if (elem is PrefixElement) {
+        List<Directive> directives = await request.resolveDirectives();
+        LibraryElement containingLibrary = request.libraryElement;
+        // Gracefully degrade if the library or directives
+        // could not be determined (e.g. detached part file or source change)
+        if (containingLibrary != null && directives != null) {
+          return _buildSuggestions(
+              request, elem, containingLibrary, directives);
+        }
+      }
+    }
+    return EMPTY_LIST;
+  }
+
+  List<CompletionSuggestion> _buildSuggestions(
+      DartCompletionRequest request,
+      PrefixElement elem,
+      LibraryElement containingLibrary,
+      List<Directive> directives) {
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    for (Directive directive in directives) {
+      if (directive is ImportDirective) {
+        if (directive.prefix != null) {
+          if (directive.prefix.name == elem.name) {
+            LibraryElement library = directive.uriElement;
+
+            // Suggest elements from the imported library
+            if (library != null) {
+              AstNode parent = request.target.containingNode.parent;
+              bool isConstructor = parent.parent is ConstructorName;
+              bool typesOnly = parent is TypeName;
+              bool instCreation = typesOnly && isConstructor;
+              LibraryElementSuggestionBuilder builder =
+                  new LibraryElementSuggestionBuilder(
+                      containingLibrary,
+                      CompletionSuggestionKind.INVOCATION,
+                      typesOnly,
+                      instCreation);
+              library.visitChildren(builder);
+              suggestions.addAll(builder.suggestions);
+
+              // If the import is 'deferred' then suggest 'loadLibrary'
+              if (directive.deferredKeyword != null) {
+                FunctionElement loadLibFunct = library.loadLibraryFunction;
+                suggestions.add(createSuggestion(loadLibFunct));
+              }
+            }
+          }
+        }
+      }
+    }
+    return suggestions;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
new file mode 100644
index 0000000..194e741
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
@@ -0,0 +1,55 @@
+// 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 services.completion.contributor.dart.library_prefix;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating prefixed import library member suggestions
+ * `completion.getSuggestions` request results.
+ */
+class LibraryPrefixContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    if (!request.includeIdentifiers) {
+      return EMPTY_LIST;
+    }
+
+    List<Directive> directives = await request.resolveDirectives();
+    if (directives == null) {
+      return EMPTY_LIST;
+    }
+
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    for (Directive directive in directives) {
+      if (directive is ImportDirective) {
+        SimpleIdentifier prefix = directive.prefix;
+        ImportElement element = directive.element;
+        if (prefix != null && element != null) {
+          String completion = prefix.name;
+          LibraryElement libElem = element.importedLibrary;
+          if (completion != null && completion.length > 0 && libElem != null) {
+            CompletionSuggestion suggestion = createSuggestion(libElem,
+                completion: completion,
+                kind: CompletionSuggestionKind.IDENTIFIER);
+            if (suggestion != null) {
+              suggestions.add(suggestion);
+            }
+          }
+        }
+      }
+    }
+    return suggestions;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
new file mode 100644
index 0000000..d8d4e36
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
@@ -0,0 +1,281 @@
+// 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 services.completion.contributor.dart.constructor;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
+    show DartCompletionRequestImpl;
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart'
+    show LocalDeclarationVisitor;
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind, Location;
+
+const DYNAMIC = 'dynamic';
+
+final TypeName NO_RETURN_TYPE = new TypeName(
+    new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null);
+
+/**
+* Create a new protocol Element for inclusion in a completion suggestion.
+*/
+protocol.Element createLocalElement(
+    Source source, protocol.ElementKind kind, SimpleIdentifier id,
+    {String parameters,
+    TypeName returnType,
+    bool isAbstract: false,
+    bool isDeprecated: false}) {
+  String name;
+  Location location;
+  if (id != null) {
+    name = id.name;
+    // TODO(danrubel) use lineInfo to determine startLine and startColumn
+    location = new Location(source.fullName, id.offset, id.length, 0, 0);
+  } else {
+    name = '';
+    location = new Location(source.fullName, -1, 0, 1, 0);
+  }
+  int flags = protocol.Element.makeFlags(
+      isAbstract: isAbstract,
+      isDeprecated: isDeprecated,
+      isPrivate: Identifier.isPrivateName(name));
+  return new protocol.Element(kind, name, flags,
+      location: location,
+      parameters: parameters,
+      returnType: nameForType(returnType));
+}
+
+/**
+* Create a new suggestion for the given field.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion createLocalFieldSuggestion(
+    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+  bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
+  TypeName type = fieldDecl.fields.type;
+  return createLocalSuggestion(
+      varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
+      classDecl: fieldDecl.parent,
+      element: createLocalElement(
+          source, protocol.ElementKind.FIELD, varDecl.name,
+          returnType: type, isDeprecated: deprecated));
+}
+
+/**
+* Create a new suggestion based upon the given information.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion createLocalSuggestion(SimpleIdentifier id,
+    bool isDeprecated, int defaultRelevance, TypeName returnType,
+    {ClassDeclaration classDecl, protocol.Element element}) {
+  if (id == null) {
+    return null;
+  }
+  String completion = id.name;
+  if (completion == null || completion.length <= 0 || completion == '_') {
+    return null;
+  }
+  CompletionSuggestion suggestion = new CompletionSuggestion(
+      CompletionSuggestionKind.INVOCATION,
+      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
+      completion,
+      completion.length,
+      0,
+      isDeprecated,
+      false,
+      returnType: nameForType(returnType),
+      element: element);
+  if (classDecl != null) {
+    SimpleIdentifier classId = classDecl.name;
+    if (classId != null) {
+      String className = classId.name;
+      if (className != null && className.length > 0) {
+        suggestion.declaringType = className;
+      }
+    }
+  }
+  return suggestion;
+}
+
+/**
+* Return `true` if the @deprecated annotation is present
+*/
+bool isDeprecated(AnnotatedNode node) {
+  if (node != null) {
+    NodeList<Annotation> metadata = node.metadata;
+    if (metadata != null) {
+      return metadata.any((Annotation a) {
+        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
+      });
+    }
+  }
+  return false;
+}
+
+/**
+* Return the name for the given type.
+*/
+String nameForType(TypeName type) {
+  if (type == NO_RETURN_TYPE) {
+    return null;
+  }
+  if (type == null) {
+    return DYNAMIC;
+  }
+  Identifier id = type.name;
+  if (id == null) {
+    return DYNAMIC;
+  }
+  String name = id.name;
+  if (name == null || name.length <= 0) {
+    return DYNAMIC;
+  }
+  TypeArgumentList typeArgs = type.typeArguments;
+  if (typeArgs != null) {
+    //TODO (danrubel) include type arguments
+  }
+  return name;
+}
+
+/**
+ * A contributor for calculating constructor suggestions
+ * for declarations in the local file.
+ */
+class LocalConstructorContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+
+    // Collect suggestions from the specific child [AstNode] that contains
+    // the completion offset and all of its parents recursively.
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    if (!optype.isPrefixed) {
+      if (optype.includeConstructorSuggestions) {
+        _Visitor visitor = new _Visitor(request, suggestions);
+        visitor.visit(request.target.containingNode);
+      }
+    }
+    return suggestions;
+  }
+}
+
+/**
+ * A visitor for collecting constructor suggestions.
+ */
+class _Visitor extends LocalDeclarationVisitor {
+  final DartCompletionRequest request;
+  final List<CompletionSuggestion> suggestions;
+
+  _Visitor(DartCompletionRequest request, this.suggestions)
+      : super(request.offset),
+        request = request;
+
+  @override
+  void declaredClass(ClassDeclaration declaration) {
+    bool found = false;
+    for (ClassMember member in declaration.members) {
+      if (member is ConstructorDeclaration) {
+        found = true;
+        _addSuggestion(declaration, member);
+      }
+    }
+    if (!found) {
+      _addSuggestion(declaration, null);
+    }
+  }
+
+  @override
+  void declaredClassTypeAlias(ClassTypeAlias declaration) {}
+
+  @override
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {}
+
+  @override
+  void declaredFunction(FunctionDeclaration declaration) {}
+
+  @override
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {}
+
+  @override
+  void declaredLabel(Label label, bool isCaseLabel) {}
+
+  @override
+  void declaredLocalVar(SimpleIdentifier name, TypeName type) {}
+
+  @override
+  void declaredMethod(MethodDeclaration declaration) {}
+
+  @override
+  void declaredParam(SimpleIdentifier name, TypeName type) {}
+
+  @override
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl) {}
+
+  /**
+   * For the given class and constructor,
+   * add a suggestion of the form B(...) or B.name(...).
+   * If the given constructor is `null`
+   * then add a default constructor suggestion.
+   */
+  void _addSuggestion(
+      ClassDeclaration classDecl, ConstructorDeclaration constructorDecl) {
+    String completion = classDecl.name.name;
+    SimpleIdentifier elemId;
+
+    // Build a suggestion for explicitly declared constructor
+    if (constructorDecl != null) {
+      elemId = constructorDecl.name;
+      ConstructorElement elem = constructorDecl.element;
+      if (elemId != null) {
+        String name = elemId.name;
+        if (name != null && name.length > 0) {
+          completion = '$completion.$name';
+        }
+      }
+      if (elem != null) {
+        CompletionSuggestion suggestion =
+            createSuggestion(elem, completion: completion);
+        if (suggestion != null) {
+          suggestions.add(suggestion);
+        }
+      }
+    }
+
+    // Build a suggestion for an implicit constructor
+    else {
+      protocol.Element element = createLocalElement(
+          request.source, protocol.ElementKind.CONSTRUCTOR, elemId,
+          parameters: '()');
+      element.returnType = classDecl.name.name;
+      CompletionSuggestion suggestion = new CompletionSuggestion(
+          CompletionSuggestionKind.INVOCATION,
+          DART_RELEVANCE_DEFAULT,
+          completion,
+          completion.length,
+          0,
+          false,
+          false,
+          declaringType: classDecl.name.name,
+          element: element,
+          parameterNames: [],
+          parameterTypes: [],
+          requiredParameterCount: 0,
+          hasNamedParameters: false);
+      suggestions.add(suggestion);
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart
new file mode 100644
index 0000000..964c6b4
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart
@@ -0,0 +1,270 @@
+// 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 services.completion.dart.local.declaration.visitor;
+
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+
+/**
+ * `LocalDeclarationCollector` visits an [AstNode] and its parent recursively
+ * along with any declarations in those nodes. Consumers typically call [visit]
+ * which catches the exception thrown by [finished()].
+ */
+abstract class LocalDeclarationVisitor extends GeneralizingAstVisitor {
+  static final TypeName STACKTRACE_TYPE = new TypeName(
+      new SimpleIdentifier(
+          new StringToken(TokenType.IDENTIFIER, 'StackTrace', 0)),
+      null);
+
+  final int offset;
+
+  LocalDeclarationVisitor(this.offset);
+
+  void declaredClass(ClassDeclaration declaration);
+
+  void declaredClassTypeAlias(ClassTypeAlias declaration);
+
+  void declaredEnum(EnumDeclaration declaration) {}
+
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl);
+
+  void declaredFunction(FunctionDeclaration declaration);
+
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration);
+
+  void declaredLabel(Label label, bool isCaseLabel);
+
+  void declaredLocalVar(SimpleIdentifier name, TypeName type);
+
+  void declaredMethod(MethodDeclaration declaration);
+
+  void declaredParam(SimpleIdentifier name, TypeName type);
+
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl);
+
+  /**
+   * Throw an exception indicating that [LocalDeclarationVisitor] should
+   * stop visiting. This is caught in [visit] which then exits normally.
+   */
+  void finished() {
+    throw new _LocalDeclarationVisitorFinished();
+  }
+
+  /**
+   * Visit the given [AstNode] and its parent recursively along with any
+   * declarations in those nodes. Return `true` if [finished] is called
+   * while visiting, else `false`.
+   */
+  bool visit(AstNode node) {
+    try {
+      node.accept(this);
+      return false;
+    } on _LocalDeclarationVisitorFinished {
+      return true;
+    }
+  }
+
+  @override
+  void visitBlock(Block node) {
+    for (Statement stmt in node.statements) {
+      if (stmt.offset < offset) {
+        if (stmt is VariableDeclarationStatement) {
+          VariableDeclarationList varList = stmt.variables;
+          if (varList != null) {
+            for (VariableDeclaration varDecl in varList.variables) {
+              if (varDecl.end < offset) {
+                declaredLocalVar(varDecl.name, varList.type);
+              }
+            }
+          }
+        } else if (stmt is FunctionDeclarationStatement) {
+          FunctionDeclaration declaration = stmt.functionDeclaration;
+          if (declaration != null && declaration.offset < offset) {
+            SimpleIdentifier id = declaration.name;
+            if (id != null) {
+              String name = id.name;
+              if (name != null && name.length > 0) {
+                declaredFunction(declaration);
+              }
+            }
+          }
+        }
+      }
+    }
+    visitNode(node);
+  }
+
+  @override
+  void visitCatchClause(CatchClause node) {
+    SimpleIdentifier param = node.exceptionParameter;
+    if (param != null) {
+      declaredParam(param, node.exceptionType);
+    }
+    param = node.stackTraceParameter;
+    if (param != null) {
+      declaredParam(param, STACKTRACE_TYPE);
+    }
+    visitNode(node);
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    _visitClassDeclarationMembers(node);
+    visitNode(node);
+  }
+
+  @override
+  void visitCompilationUnit(CompilationUnit node) {
+    node.declarations.forEach((Declaration declaration) {
+      if (declaration is ClassDeclaration) {
+        declaredClass(declaration);
+      } else if (declaration is EnumDeclaration) {
+        declaredEnum(declaration);
+      } else if (declaration is FunctionDeclaration) {
+        declaredFunction(declaration);
+      } else if (declaration is TopLevelVariableDeclaration) {
+        var varList = declaration.variables;
+        if (varList != null) {
+          varList.variables.forEach((VariableDeclaration varDecl) {
+            declaredTopLevelVar(varList, varDecl);
+          });
+        }
+      } else if (declaration is ClassTypeAlias) {
+        declaredClassTypeAlias(declaration);
+      } else if (declaration is FunctionTypeAlias) {
+        declaredFunctionTypeAlias(declaration);
+      }
+    });
+  }
+
+  @override
+  visitConstructorDeclaration(ConstructorDeclaration node) {
+    _visitParamList(node.parameters);
+    visitNode(node);
+  }
+
+  @override
+  void visitForEachStatement(ForEachStatement node) {
+    SimpleIdentifier id;
+    TypeName type;
+    DeclaredIdentifier loopVar = node.loopVariable;
+    if (loopVar != null) {
+      id = loopVar.identifier;
+      type = loopVar.type;
+    } else {
+      id = node.identifier;
+      type = null;
+    }
+    if (id != null) {
+      // If there is no loop variable, don't declare it.
+      declaredLocalVar(id, type);
+    }
+    visitNode(node);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    VariableDeclarationList varList = node.variables;
+    if (varList != null) {
+      varList.variables.forEach((VariableDeclaration varDecl) {
+        declaredLocalVar(varDecl.name, varList.type);
+      });
+    }
+    visitNode(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    // declaredFunction is called by the compilation unit containing it
+    visitNode(node);
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    _visitParamList(node.parameters);
+    visitNode(node);
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    visitNode(node);
+  }
+
+  @override
+  void visitLabeledStatement(LabeledStatement node) {
+    for (Label label in node.labels) {
+      declaredLabel(label, false);
+    }
+    visitNode(node);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    _visitParamList(node.parameters);
+    visitNode(node);
+  }
+
+  @override
+  void visitNode(AstNode node) {
+    node.parent.accept(this);
+  }
+
+  @override
+  void visitStringInterpolation(StringInterpolation node) {
+    visitNode(node);
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    for (SwitchMember member in node.members) {
+      for (Label label in member.labels) {
+        declaredLabel(label, true);
+      }
+    }
+    visitNode(node);
+  }
+
+  void _visitClassDeclarationMembers(ClassDeclaration node) {
+    for (ClassMember member in node.members) {
+      if (member is FieldDeclaration) {
+        member.fields.variables.forEach((VariableDeclaration varDecl) {
+          declaredField(member, varDecl);
+        });
+      } else if (member is MethodDeclaration) {
+        declaredMethod(member);
+      }
+    }
+  }
+
+  void _visitParamList(FormalParameterList paramList) {
+    if (paramList != null) {
+      paramList.parameters.forEach((FormalParameter param) {
+        NormalFormalParameter normalParam;
+        if (param is DefaultFormalParameter) {
+          normalParam = param.parameter;
+        } else if (param is NormalFormalParameter) {
+          normalParam = param;
+        }
+        TypeName type = null;
+        if (normalParam is FieldFormalParameter) {
+          type = normalParam.type;
+        } else if (normalParam is FunctionTypedFormalParameter) {
+          type = normalParam.returnType;
+        } else if (normalParam is SimpleFormalParameter) {
+          type = normalParam.type;
+        }
+        SimpleIdentifier name = param.identifier;
+        declaredParam(name, type);
+      });
+    }
+  }
+}
+
+/**
+ * Internal exception used to indicate that [LocalDeclarationVisitor]
+ * should stop visiting.
+ */
+class _LocalDeclarationVisitorFinished {}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
new file mode 100644
index 0000000..9469154
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -0,0 +1,185 @@
+// 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 services.completion.contributor.dart.local_lib;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
+    show createSuggestion, ElementSuggestionBuilder;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating suggestions for top level members
+ * in the library in which the completion is requested
+ * but outside the file in which the completion is requested.
+ */
+class LocalLibraryContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    if (!request.includeIdentifiers) {
+      return EMPTY_LIST;
+    }
+
+    List<Directive> directives = await request.resolveDirectives();
+    if (directives == null) {
+      return EMPTY_LIST;
+    }
+
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+    LibraryElementSuggestionBuilder visitor =
+        new LibraryElementSuggestionBuilder(request, optype);
+    if (request.librarySource != request.source) {
+      request.libraryElement.definingCompilationUnit.accept(visitor);
+    }
+    for (Directive directive in directives) {
+      if (directive is PartDirective) {
+        CompilationUnitElement partElem = directive.element;
+        if (partElem != null && partElem.source != request.source) {
+          partElem.accept(visitor);
+        }
+      }
+    }
+    return visitor.suggestions;
+  }
+}
+
+/**
+ * A visitor for building suggestions based upon the elements defined by
+ * a source file contained in the same library but not the same as
+ * the source in which the completions are being requested.
+ */
+class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
+    with ElementSuggestionBuilder {
+  final DartCompletionRequest request;
+  final OpType optype;
+  CompletionSuggestionKind kind;
+  final String prefix;
+  List<String> showNames;
+  List<String> hiddenNames;
+
+  LibraryElementSuggestionBuilder(this.request, this.optype, [this.prefix]) {
+    this.kind = request.target.isFunctionalArgument()
+        ? CompletionSuggestionKind.IDENTIFIER
+        : optype.suggestKind;
+  }
+
+  @override
+  LibraryElement get containingLibrary => request.libraryElement;
+
+  @override
+  void visitClassElement(ClassElement element) {
+    if (optype.includeTypeNameSuggestions) {
+      addSuggestion(element, prefix: prefix, relevance: DART_RELEVANCE_DEFAULT);
+    }
+    if (optype.includeConstructorSuggestions) {
+      _addConstructorSuggestions(element, DART_RELEVANCE_DEFAULT);
+    }
+  }
+
+  @override
+  void visitCompilationUnitElement(CompilationUnitElement element) {
+    element.visitChildren(this);
+  }
+
+  @override
+  void visitElement(Element element) {
+    // ignored
+  }
+
+  @override
+  void visitFunctionElement(FunctionElement element) {
+    // Do not suggest operators or local functions
+    if (element.isOperator) {
+      return;
+    }
+    if (element.enclosingElement is! CompilationUnitElement) {
+      return;
+    }
+    int relevance = element.library == containingLibrary
+        ? DART_RELEVANCE_LOCAL_FUNCTION
+        : DART_RELEVANCE_DEFAULT;
+    DartType returnType = element.returnType;
+    if (returnType != null && returnType.isVoid) {
+      if (optype.includeVoidReturnSuggestions) {
+        addSuggestion(element, prefix: prefix, relevance: relevance);
+      }
+    } else {
+      if (optype.includeReturnValueSuggestions) {
+        addSuggestion(element, prefix: prefix, relevance: relevance);
+      }
+    }
+  }
+
+  @override
+  void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    if (optype.includeTypeNameSuggestions) {
+      int relevance = element.library == containingLibrary
+          ? DART_RELEVANCE_LOCAL_FUNCTION
+          : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element, prefix: prefix, relevance: relevance);
+    }
+  }
+
+  @override
+  void visitLibraryElement(LibraryElement element) {
+    element.visitChildren(this);
+  }
+
+  @override
+  void visitPropertyAccessorElement(PropertyAccessorElement element) {
+    int relevance;
+    if (element.library == containingLibrary) {
+      if (element.enclosingElement is ClassElement) {
+        relevance = DART_RELEVANCE_LOCAL_FIELD;
+      } else {
+        relevance = DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
+      }
+    } else {
+      relevance = DART_RELEVANCE_DEFAULT;
+    }
+    addSuggestion(element, prefix: prefix, relevance: relevance);
+  }
+
+  @override
+  void visitTopLevelVariableElement(TopLevelVariableElement element) {
+    if (optype.includeReturnValueSuggestions) {
+      int relevance = element.library == containingLibrary
+          ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
+          : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element, prefix: prefix, relevance: relevance);
+    }
+  }
+
+  /**
+   * Add constructor suggestions for the given class.
+   */
+  void _addConstructorSuggestions(ClassElement classElem, int relevance) {
+    String className = classElem.name;
+    for (ConstructorElement constructor in classElem.constructors) {
+      if (!constructor.isPrivate) {
+        CompletionSuggestion suggestion =
+            createSuggestion(constructor, relevance: relevance);
+        if (suggestion != null) {
+          String name = suggestion.completion;
+          name = name.length > 0 ? '$className.$name' : className;
+          if (prefix != null && prefix.length > 0) {
+            name = '$prefix.$name';
+          }
+          suggestion.completion = name;
+          suggestion.selectionOffset = suggestion.completion.length;
+          suggestions.add(suggestion);
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
new file mode 100644
index 0000000..966f1d9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -0,0 +1,450 @@
+// 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 services.completion.contributor.dart.local_ref;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
+    show DartCompletionRequestImpl;
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart'
+    show LocalDeclarationVisitor;
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind, Location;
+
+const DYNAMIC = 'dynamic';
+
+final TypeName NO_RETURN_TYPE = new TypeName(
+    new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null);
+
+/**
+ * A contributor for calculating suggestions for declarations in the local
+ * file and containing library.
+ */
+class LocalReferenceContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+
+    // Collect suggestions from the specific child [AstNode] that contains
+    // the completion offset and all of its parents recursively.
+    if (!optype.isPrefixed) {
+      if (optype.includeReturnValueSuggestions ||
+          optype.includeTypeNameSuggestions ||
+          optype.includeVoidReturnSuggestions) {
+        _LocalVisitor visitor =
+            new _LocalVisitor(request, request.offset, optype);
+        AstNode node = request.target.containingNode;
+
+        // Do not suggest local vars within the current expression
+        while (node is Expression) {
+          node = node.parent;
+        }
+
+        // Do not suggest loop variable of a ForEachStatement
+        // when completing the expression of the ForEachStatement
+        if (node is ForEachStatement) {
+          node = node.parent;
+        }
+
+        visitor.visit(node);
+        return visitor.suggestions;
+      }
+    }
+    return EMPTY_LIST;
+  }
+}
+
+/**
+ * A visitor for collecting suggestions from the most specific child [AstNode]
+ * that contains the completion offset to the [CompilationUnit].
+ */
+class _LocalVisitor extends LocalDeclarationVisitor {
+  final DartCompletionRequest request;
+  final OpType optype;
+  final Map<String, CompletionSuggestion> suggestionMap =
+      <String, CompletionSuggestion>{};
+  int privateMemberRelevance = DART_RELEVANCE_DEFAULT;
+  bool targetIsFunctionalArgument;
+
+  _LocalVisitor(this.request, int offset, this.optype) : super(offset) {
+    // Suggestions for inherited members provided by InheritedReferenceContributor
+    targetIsFunctionalArgument = request.target.isFunctionalArgument();
+
+    // If user typed identifier starting with '_'
+    // then do not suppress the relevance of private members
+    var contents = request.context.getContents(request.source);
+    if (contents != null) {
+      String data = contents.data;
+      int offset = request.offset;
+      if (data != null && 0 < offset && offset <= data.length) {
+        bool isIdentifierChar(int index) {
+          int code = data.codeUnitAt(index);
+          return isLetterOrDigit(code) || code == CHAR_UNDERSCORE;
+        }
+        if (isIdentifierChar(offset - 1)) {
+          while (offset > 0 && isIdentifierChar(offset - 1)) {
+            --offset;
+          }
+          if (data.codeUnitAt(offset) == CHAR_UNDERSCORE) {
+            privateMemberRelevance = null;
+          }
+        }
+      }
+    }
+  }
+
+  List<CompletionSuggestion> get suggestions => suggestionMap.values.toList();
+
+  @override
+  void declaredClass(ClassDeclaration declaration) {
+    if (optype.includeTypeNameSuggestions) {
+      _addLocalSuggestion(
+          declaration.name, NO_RETURN_TYPE, protocol.ElementKind.CLASS,
+          isAbstract: declaration.isAbstract,
+          isDeprecated: _isDeprecated(declaration));
+    }
+  }
+
+  @override
+  void declaredClassTypeAlias(ClassTypeAlias declaration) {
+    if (optype.includeTypeNameSuggestions) {
+      _addLocalSuggestion(declaration.name, NO_RETURN_TYPE,
+          protocol.ElementKind.CLASS_TYPE_ALIAS,
+          isAbstract: true, isDeprecated: _isDeprecated(declaration));
+    }
+  }
+
+  @override
+  void declaredEnum(EnumDeclaration declaration) {
+    if (optype.includeTypeNameSuggestions) {
+      _addLocalSuggestion(
+          declaration.name, NO_RETURN_TYPE, protocol.ElementKind.ENUM,
+          isDeprecated: _isDeprecated(declaration));
+    }
+  }
+
+  @override
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+    if (optype.includeReturnValueSuggestions &&
+        (!optype.inStaticMethodBody || fieldDecl.isStatic)) {
+      bool deprecated = _isDeprecated(fieldDecl) || _isDeprecated(varDecl);
+      TypeName typeName = fieldDecl.fields.type;
+      _addLocalSuggestion(varDecl.name, typeName, protocol.ElementKind.FIELD,
+          isDeprecated: deprecated,
+          relevance: DART_RELEVANCE_LOCAL_FIELD,
+          classDecl: fieldDecl.parent);
+    }
+  }
+
+  @override
+  void declaredFunction(FunctionDeclaration declaration) {
+    if (optype.includeReturnValueSuggestions ||
+        optype.includeVoidReturnSuggestions) {
+      TypeName typeName = declaration.returnType;
+      protocol.ElementKind elemKind;
+      int relevance = DART_RELEVANCE_DEFAULT;
+      if (declaration.isGetter) {
+        elemKind = protocol.ElementKind.GETTER;
+        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
+      } else if (declaration.isSetter) {
+        if (!optype.includeVoidReturnSuggestions) {
+          return;
+        }
+        elemKind = protocol.ElementKind.SETTER;
+        typeName = NO_RETURN_TYPE;
+        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
+      } else {
+        if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) {
+          return;
+        }
+        elemKind = protocol.ElementKind.FUNCTION;
+        relevance = DART_RELEVANCE_LOCAL_FUNCTION;
+      }
+      _addLocalSuggestion(declaration.name, typeName, elemKind,
+          isDeprecated: _isDeprecated(declaration),
+          param: declaration.functionExpression.parameters,
+          relevance: relevance);
+    }
+  }
+
+  @override
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
+    if (optype.includeTypeNameSuggestions) {
+      // TODO (danrubel) determine parameters and return type
+      _addLocalSuggestion(declaration.name, declaration.returnType,
+          protocol.ElementKind.FUNCTION_TYPE_ALIAS,
+          isAbstract: true, isDeprecated: _isDeprecated(declaration));
+    }
+  }
+
+  @override
+  void declaredLabel(Label label, bool isCaseLabel) {
+    // ignored
+  }
+
+  @override
+  void declaredLocalVar(SimpleIdentifier id, TypeName typeName) {
+    if (optype.includeReturnValueSuggestions) {
+      _addLocalSuggestion(id, typeName, protocol.ElementKind.LOCAL_VARIABLE,
+          relevance: DART_RELEVANCE_LOCAL_VARIABLE);
+    }
+  }
+
+  @override
+  void declaredMethod(MethodDeclaration declaration) {
+    if ((optype.includeReturnValueSuggestions ||
+            optype.includeVoidReturnSuggestions) &&
+        (!optype.inStaticMethodBody || declaration.isStatic)) {
+      protocol.ElementKind elemKind;
+      FormalParameterList param;
+      TypeName typeName = declaration.returnType;
+      int relevance = DART_RELEVANCE_DEFAULT;
+      if (declaration.isGetter) {
+        elemKind = protocol.ElementKind.GETTER;
+        param = null;
+        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
+      } else if (declaration.isSetter) {
+        if (!optype.includeVoidReturnSuggestions) {
+          return;
+        }
+        elemKind = protocol.ElementKind.SETTER;
+        typeName = NO_RETURN_TYPE;
+        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
+      } else {
+        if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) {
+          return;
+        }
+        elemKind = protocol.ElementKind.METHOD;
+        param = declaration.parameters;
+        relevance = DART_RELEVANCE_LOCAL_METHOD;
+      }
+      _addLocalSuggestion(declaration.name, typeName, elemKind,
+          isAbstract: declaration.isAbstract,
+          isDeprecated: _isDeprecated(declaration),
+          classDecl: declaration.parent,
+          param: param,
+          relevance: relevance);
+    }
+  }
+
+  @override
+  void declaredParam(SimpleIdentifier id, TypeName typeName) {
+    if (optype.includeReturnValueSuggestions) {
+      _addLocalSuggestion(id, typeName, protocol.ElementKind.PARAMETER,
+          relevance: DART_RELEVANCE_PARAMETER);
+    }
+  }
+
+  @override
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl) {
+    if (optype.includeReturnValueSuggestions) {
+      _addLocalSuggestion(
+          varDecl.name, varList.type, protocol.ElementKind.TOP_LEVEL_VARIABLE,
+          isDeprecated: _isDeprecated(varList) || _isDeprecated(varDecl),
+          relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    }
+  }
+
+  void _addParameterInfo(
+      CompletionSuggestion suggestion, FormalParameterList parameters) {
+    var paramList = parameters.parameters;
+    suggestion.parameterNames = paramList
+        .map((FormalParameter param) => param.identifier.name)
+        .toList();
+    suggestion.parameterTypes = paramList.map((FormalParameter param) {
+      TypeName type = null;
+      if (param is DefaultFormalParameter) {
+        NormalFormalParameter child = param.parameter;
+        if (child is SimpleFormalParameter) {
+          type = child.type;
+        } else if (child is FieldFormalParameter) {
+          type = child.type;
+        }
+      }
+      if (param is SimpleFormalParameter) {
+        type = param.type;
+      } else if (param is FieldFormalParameter) {
+        type = param.type;
+      }
+      if (type == null) {
+        return 'dynamic';
+      }
+      Identifier typeId = type.name;
+      if (typeId == null) {
+        return 'dynamic';
+      }
+      return typeId.name;
+    }).toList();
+    suggestion.requiredParameterCount = paramList
+        .where((FormalParameter param) => param is! DefaultFormalParameter)
+        .length;
+    suggestion.hasNamedParameters = paramList
+        .any((FormalParameter param) => param.kind == ParameterKind.NAMED);
+  }
+
+  void _addLocalSuggestion(
+      SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind,
+      {bool isAbstract: false,
+      bool isDeprecated: false,
+      ClassDeclaration classDecl,
+      FormalParameterList param,
+      int relevance: DART_RELEVANCE_DEFAULT}) {
+    CompletionSuggestionKind kind = targetIsFunctionalArgument
+        ? CompletionSuggestionKind.IDENTIFIER
+        : optype.suggestKind;
+    CompletionSuggestion suggestion = _createLocalSuggestion(
+        id, kind, isDeprecated, relevance, typeName,
+        classDecl: classDecl);
+    if (suggestion != null) {
+      if (privateMemberRelevance != null &&
+          suggestion.completion.startsWith('_')) {
+        suggestion.relevance = privateMemberRelevance;
+      }
+      suggestionMap.putIfAbsent(suggestion.completion, () => suggestion);
+      suggestion.element = _createLocalElement(request.source, elemKind, id,
+          isAbstract: isAbstract,
+          isDeprecated: isDeprecated,
+          parameters: param != null ? param.toSource() : null,
+          returnType: typeName);
+      if ((elemKind == protocol.ElementKind.METHOD ||
+              elemKind == protocol.ElementKind.FUNCTION) &&
+          param != null) {
+        _addParameterInfo(suggestion, param);
+      }
+    }
+  }
+
+  bool _isVoid(TypeName returnType) {
+    if (returnType != null) {
+      Identifier id = returnType.name;
+      if (id != null && id.name == 'void') {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/**
+* Create a new protocol Element for inclusion in a completion suggestion.
+*/
+protocol.Element _createLocalElement(
+    Source source, protocol.ElementKind kind, SimpleIdentifier id,
+    {String parameters,
+    TypeName returnType,
+    bool isAbstract: false,
+    bool isDeprecated: false}) {
+  String name;
+  Location location;
+  if (id != null) {
+    name = id.name;
+    // TODO(danrubel) use lineInfo to determine startLine and startColumn
+    location = new Location(source.fullName, id.offset, id.length, 0, 0);
+  } else {
+    name = '';
+    location = new Location(source.fullName, -1, 0, 1, 0);
+  }
+  int flags = protocol.Element.makeFlags(
+      isAbstract: isAbstract,
+      isDeprecated: isDeprecated,
+      isPrivate: Identifier.isPrivateName(name));
+  return new protocol.Element(kind, name, flags,
+      location: location,
+      parameters: parameters,
+      returnType: _nameForType(returnType));
+}
+
+/**
+* Create a new suggestion based upon the given information.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion _createLocalSuggestion(
+    SimpleIdentifier id,
+    CompletionSuggestionKind kind,
+    bool isDeprecated,
+    int defaultRelevance,
+    TypeName returnType,
+    {ClassDeclaration classDecl,
+    protocol.Element element}) {
+  if (id == null) {
+    return null;
+  }
+  String completion = id.name;
+  if (completion == null || completion.length <= 0 || completion == '_') {
+    return null;
+  }
+  CompletionSuggestion suggestion = new CompletionSuggestion(
+      kind,
+      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
+      completion,
+      completion.length,
+      0,
+      isDeprecated,
+      false,
+      returnType: _nameForType(returnType),
+      element: element);
+  if (classDecl != null) {
+    SimpleIdentifier classId = classDecl.name;
+    if (classId != null) {
+      String className = classId.name;
+      if (className != null && className.length > 0) {
+        suggestion.declaringType = className;
+      }
+    }
+  }
+  return suggestion;
+}
+
+/**
+* Return `true` if the @deprecated annotation is present
+*/
+bool _isDeprecated(AnnotatedNode node) {
+  if (node != null) {
+    NodeList<Annotation> metadata = node.metadata;
+    if (metadata != null) {
+      return metadata.any((Annotation a) {
+        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
+      });
+    }
+  }
+  return false;
+}
+
+/**
+* Return the name for the given type.
+*/
+String _nameForType(TypeName type) {
+  if (type == NO_RETURN_TYPE) {
+    return null;
+  }
+  if (type == null) {
+    return DYNAMIC;
+  }
+  Identifier id = type.name;
+  if (id == null) {
+    return DYNAMIC;
+  }
+  String name = id.name;
+  if (name == null || name.length <= 0) {
+    return DYNAMIC;
+  }
+  TypeArgumentList typeArgs = type.typeArguments;
+  if (typeArgs != null) {
+    //TODO (danrubel) include type arguments
+  }
+  return name;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
new file mode 100644
index 0000000..760274e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -0,0 +1,84 @@
+// 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 services.completion.contributor.dart.named_constructor;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+
+/**
+ * A contributor for calculating named constructor suggestions
+ * such as suggesting `bar` in `new Foo.bar()`.
+ */
+class NamedConstructorContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    // Determine if the target looks like a named constructor.
+    AstNode parsedNode = request.target.containingNode;
+    SimpleIdentifier targetId;
+    if (parsedNode is ConstructorName) {
+      TypeName type = parsedNode.type;
+      if (type != null) {
+        targetId = type.name;
+      }
+    } else if (parsedNode is PrefixedIdentifier) {
+      // Some PrefixedIdentifier nodes are transformed into
+      // ConstructorName nodes during the resolution process.
+      targetId = parsedNode.prefix;
+    }
+    if (targetId == null) {
+      return EMPTY_LIST;
+    }
+
+    // Resolve the target to determine the type
+    await request.resolveExpression(targetId);
+
+    // Recompute the target since resolution may have changed it
+    AstNode node = request.target.containingNode;
+    LibraryElement libElem = request.libraryElement;
+    if (libElem == null) {
+      return EMPTY_LIST;
+    }
+
+    // Build the list of suggestions
+    if (node is ConstructorName) {
+      TypeName typeName = node.type;
+      if (typeName != null) {
+        DartType type = typeName.type;
+        if (type != null) {
+          Element classElem = type.element;
+          if (classElem is ClassElement) {
+            return _buildSuggestions(libElem, classElem);
+          }
+        }
+      }
+    }
+    return EMPTY_LIST;
+  }
+
+  List<CompletionSuggestion> _buildSuggestions(
+      LibraryElement libElem, ClassElement classElem) {
+    bool isLocalClassDecl = classElem.library == libElem;
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    for (ConstructorElement elem in classElem.constructors) {
+      if (isLocalClassDecl || !elem.isPrivate) {
+        String name = elem.name;
+        if (name != null) {
+          CompletionSuggestion s = createSuggestion(elem, completion: name);
+          if (s != null) {
+            suggestions.add(s);
+          }
+        }
+      }
+    }
+    return suggestions;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
new file mode 100644
index 0000000..9acbf07
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
@@ -0,0 +1,696 @@
+// 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 services.completion.dart.optype;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+
+/**
+ * An [AstVisitor] for determining whether top level suggestions or invocation
+ * suggestions should be made based upon the type of node in which the
+ * suggestions were requested.
+ */
+class OpType {
+  /**
+   * Indicates whether constructor suggestions should be included.
+   */
+  bool includeConstructorSuggestions = false;
+
+  /**
+   * Indicates whether type names should be suggested.
+   */
+  bool includeTypeNameSuggestions = false;
+
+  /**
+   * Indicates whether setters along with methods and functions that
+   * have a [void] return type should be suggested.
+   */
+  bool includeVoidReturnSuggestions = false;
+
+  /**
+   * Indicates whether fields and getters along with methods and functions that
+   * have a non-[void] return type should be suggested.
+   */
+  bool includeReturnValueSuggestions = false;
+
+  /**
+   * Indicates whether statement labels should be suggested.
+   */
+  bool includeStatementLabelSuggestions = false;
+
+  /**
+   * Indicates whether case labels should be suggested.
+   */
+  bool includeCaseLabelSuggestions = false;
+
+  /**
+   * Indicates whether the completion location is in the body of a static method.
+   */
+  bool inStaticMethodBody = false;
+
+  /**
+   * Indicates whether the completion target is prefixed.
+   */
+  bool isPrefixed = false;
+
+  /**
+   * The suggested completion kind.
+   */
+  CompletionSuggestionKind suggestKind = CompletionSuggestionKind.INVOCATION;
+
+  /**
+   * Determine the suggestions that should be made based upon the given
+   * [CompletionTarget] and [offset].
+   */
+  factory OpType.forCompletion(CompletionTarget target, int offset) {
+    OpType optype = new OpType._();
+    target.containingNode
+        .accept(new _OpTypeAstVisitor(optype, target.entity, offset));
+    var mthDecl =
+        target.containingNode.getAncestor((p) => p is MethodDeclaration);
+    optype.inStaticMethodBody =
+        mthDecl is MethodDeclaration && mthDecl.isStatic;
+    return optype;
+  }
+
+  OpType._();
+
+  /**
+   * Indicate whether only type names should be suggested
+   */
+  bool get includeOnlyTypeNameSuggestions => includeTypeNameSuggestions &&
+      !includeReturnValueSuggestions &&
+      !includeVoidReturnSuggestions;
+}
+
+class _OpTypeAstVisitor extends GeneralizingAstVisitor {
+  /**
+   * The entity (AstNode or Token) which will be replaced or displaced by the
+   * added text.
+   */
+  final Object entity;
+
+  /**
+   * The offset within the source at which the completion is requested.
+   */
+  final int offset;
+
+  /**
+   * The [OpType] being initialized
+   */
+  final OpType optype;
+
+  _OpTypeAstVisitor(this.optype, this.entity, this.offset);
+
+  @override
+  void visitAnnotation(Annotation node) {
+    if (identical(entity, node.name)) {
+      optype.includeTypeNameSuggestions = true;
+      optype.includeReturnValueSuggestions = true;
+    } else if (identical(entity, node.constructorName)) {
+      optype.includeTypeNameSuggestions = true;
+      optype.includeReturnValueSuggestions = true;
+      optype.isPrefixed = true;
+    }
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitAsExpression(AsExpression node) {
+    if (identical(entity, node.type)) {
+      optype.includeTypeNameSuggestions = true;
+      // TODO (danrubel) Possible future improvement:
+      // on the RHS of an "is" or "as" expression, don't suggest types that are
+      // guaranteed to pass or guaranteed to fail the cast.
+      // See dartbug.com/18860
+    }
+  }
+
+@override
+  void visitAssertStatement(AssertStatement node) {
+    if (identical(entity, node.condition)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  void visitAssignmentExpression(AssignmentExpression node) {
+    if (identical(entity, node.rightHandSide)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitAwaitExpression(AwaitExpression node) {
+    if (identical(entity, node.expression)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    if (identical(entity, node.rightOperand)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitBlock(Block node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+    optype.includeVoidReturnSuggestions = true;
+  }
+
+  @override
+  void visitBreakStatement(BreakStatement node) {
+    if (node.label == null || identical(entity, node.label)) {
+      optype.includeStatementLabelSuggestions = true;
+    }
+  }
+
+  @override
+  void visitCascadeExpression(CascadeExpression node) {
+    if (node.cascadeSections.contains(entity)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+      optype.isPrefixed = true;
+    }
+  }
+
+  @override
+  void visitCatchClause(CatchClause node) {
+    if (identical(entity, node.exceptionType)) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    // Make suggestions in the body of the class declaration
+    if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitClassMember(ClassMember node) {}
+
+  @override
+  void visitCommentReference(CommentReference node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+    optype.includeVoidReturnSuggestions = true;
+    optype.suggestKind = CompletionSuggestionKind.IDENTIFIER;
+  }
+
+  void visitCompilationUnit(CompilationUnit node) {
+    if (entity is! CommentToken) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  visitConstructorName(ConstructorName node) {
+    // some PrefixedIdentifier nodes are transformed into
+    // ConstructorName nodes during the resolution process.
+    if (identical(entity, node.name)) {
+      TypeName type = node.type;
+      if (type != null) {
+        SimpleIdentifier prefix = type.name;
+        if (prefix != null) {
+          optype.includeConstructorSuggestions = true;
+          optype.isPrefixed = true;
+        }
+      }
+    }
+  }
+
+  @override
+  void visitContinueStatement(ContinueStatement node) {
+    if (node.label == null || identical(entity, node.label)) {
+      optype.includeStatementLabelSuggestions = true;
+      optype.includeCaseLabelSuggestions = true;
+    }
+  }
+
+  @override
+  void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    if (identical(entity, node.defaultValue)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    if (identical(entity, node.condition)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitEmptyStatement(EmptyStatement node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+    optype.includeVoidReturnSuggestions = true;
+  }
+
+  @override
+  void visitExpression(Expression node) {
+    // This should never be called; we should always dispatch to the visitor
+    // for a particular kind of expression.
+    assert(false);
+  }
+
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    if (identical(entity, node.expression)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitExpressionStatement(ExpressionStatement node) {
+    // Given f[], the parser drops the [] from the expression statement
+    // but the [] token is the CompletionTarget entity
+    if (entity is Token) {
+      Token token = entity;
+      if (token.lexeme == '[]' && offset == token.offset + 1) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitExtendsClause(ExtendsClause node) {
+    if (identical(entity, node.superclass)) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    if (entity == node.identifier) {
+      optype.isPrefixed = true;
+    } else {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitForEachStatement(ForEachStatement node) {
+    if (identical(entity, node.identifier)) {
+      optype.includeTypeNameSuggestions = true;
+    }
+    if (identical(entity, node.loopVariable)) {
+      optype.includeTypeNameSuggestions = true;
+    }
+    if (identical(entity, node.inKeyword) && offset <= node.inKeyword.offset) {
+      if (node.identifier == null && node.loopVariable == null) {
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+    if (identical(entity, node.iterable)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitFormalParameterList(FormalParameterList node) {
+    dynamic entity = this.entity;
+    if (entity is Token && entity.previous != null) {
+      TokenType type = entity.previous.type;
+      if (type == TokenType.OPEN_PAREN || type == TokenType.COMMA) {
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+    // Handle default normal parameter just as a normal parameter.
+    if (entity is DefaultFormalParameter) {
+      entity = entity.parameter;
+    }
+    // "(^ this.field)"
+    if (entity is FieldFormalParameter) {
+      if (offset < entity.thisKeyword.offset) {
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+    // "(Type name)"
+    if (entity is SimpleFormalParameter) {
+      // "(Type^)" is parsed as a parameter with the _name_ "Type".
+      if (entity.type == null) {
+        optype.includeTypeNameSuggestions = true;
+      }
+      // If inside of "Type" in "(Type^ name)", then include types.
+      if (entity.type != null &&
+          entity.type.offset <= offset &&
+          offset <= entity.type.end) {
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+    optype.includeVoidReturnSuggestions = true;
+    // TODO (danrubel) void return suggestions only belong after
+    // the 2nd semicolon.  Return value suggestions only belong after the
+    // e1st or second semicolon.
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    if (identical(entity, node.returnType) ||
+        identical(entity, node.name) && node.returnType == null) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {}
+
+  @override
+  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {}
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    if (identical(entity, node.returnType) ||
+        identical(entity, node.name) && node.returnType == null) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitIfStatement(IfStatement node) {
+    if (identical(entity, node.condition)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    } else if (identical(entity, node.thenStatement) ||
+        identical(entity, node.elseStatement)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+    }
+  }
+
+  @override
+  void visitImplementsClause(ImplementsClause node) {
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    if (identical(entity, node.constructorName)) {
+      optype.includeConstructorSuggestions = true;
+    }
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    if (identical(entity, node.expression)) {
+      optype.includeReturnValueSuggestions = true;
+      // Only include type names in a ${ } expression
+      optype.includeTypeNameSuggestions =
+          node.leftBracket != null && node.leftBracket.length > 1;
+    }
+  }
+
+  @override
+  void visitIsExpression(IsExpression node) {
+    if (identical(entity, node.type)) {
+      optype.includeTypeNameSuggestions = true;
+      // TODO (danrubel) Possible future improvement:
+      // on the RHS of an "is" or "as" expression, don't suggest types that are
+      // guaranteed to pass or guaranteed to fail the cast.
+      // See dartbug.com/18860
+    }
+  }
+
+  void visitLibraryIdentifier(LibraryIdentifier node) {
+    // No suggestions.
+  }
+
+  @override
+  void visitMapLiteralEntry(MapLiteralEntry node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    bool isThis = node.target is ThisExpression;
+    if (identical(entity, node.operator) && offset > node.operator.offset) {
+      // The cursor is between the two dots of a ".." token, so we need to
+      // generate the completions we would generate after a "." token.
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = !isThis;
+      optype.includeVoidReturnSuggestions = true;
+      optype.isPrefixed = true;
+    } else if (identical(entity, node.methodName)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = !isThis;
+      optype.includeVoidReturnSuggestions = true;
+      optype.isPrefixed = true;
+    }
+  }
+
+  @override
+  void visitNamedExpression(NamedExpression node) {
+    if (identical(entity, node.expression)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitNode(AstNode node) {
+    // no suggestion by default
+  }
+
+  @override
+  void visitNormalFormalParameter(NormalFormalParameter node) {
+    if (node.identifier != entity) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  void visitParenthesizedExpression(ParenthesizedExpression node) {
+    if (identical(entity, node.expression)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitPostfixExpression(PostfixExpression node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    if (identical(entity, node.identifier) ||
+        // In addition to the standard case,
+        // handle the exceptional case where the parser considers the would-be
+        // identifier to be a keyword and inserts a synthetic identifier
+        (node.identifier != null &&
+            node.identifier.isSynthetic &&
+            identical(entity, node.identifier.beginToken.previous))) {
+      optype.isPrefixed = true;
+      if (node.parent is TypeName && node.parent.parent is ConstructorName) {
+        optype.includeConstructorSuggestions = true;
+      } else {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+        optype.includeVoidReturnSuggestions =
+            node.parent is ExpressionStatement;
+      }
+    }
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    if (identical(entity, node.operand)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    bool isThis = node.target is ThisExpression;
+    if (node.realTarget is SimpleIdentifier && node.realTarget.isSynthetic) {
+      // If the access has no target (empty string)
+      // then don't suggest anything
+      return;
+    }
+    if (identical(entity, node.operator) && offset > node.operator.offset) {
+      // The cursor is between the two dots of a ".." token, so we need to
+      // generate the completions we would generate after a "." token.
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = !isThis;
+      optype.includeVoidReturnSuggestions = true;
+      optype.isPrefixed = true;
+    } else if (identical(entity, node.propertyName)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions =
+          !isThis && (node.parent is! CascadeExpression);
+      optype.includeVoidReturnSuggestions = true;
+      optype.isPrefixed = true;
+    }
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    if (identical(entity, node.expression)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    // This should never happen; the containingNode will always be some node
+    // higher up in the parse tree, and the SimpleIdentifier will be the
+    // entity.
+    assert(false);
+  }
+
+  @override
+  void visitStringLiteral(StringLiteral node) {
+    // no suggestions
+  }
+
+  @override
+  void visitSwitchCase(SwitchCase node) {
+    if (identical(entity, node.expression)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    if (identical(entity, node.expression)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+    if (identical(entity, node.rightBracket)) {
+      if (node.members.isNotEmpty) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+        optype.includeVoidReturnSuggestions = true;
+      }
+    }
+    if (entity is SwitchMember && entity != node.members.first) {
+      SwitchMember member = entity as SwitchMember;
+      if (offset <= member.offset) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+        optype.includeVoidReturnSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitThrowExpression(ThrowExpression node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitTypeArgumentList(TypeArgumentList node) {
+    NodeList<TypeName> arguments = node.arguments;
+    for (TypeName typeName in arguments) {
+      if (identical(entity, typeName)) {
+        optype.includeTypeNameSuggestions = true;
+        break;
+      }
+    }
+  }
+
+  @override
+  void visitTypedLiteral(TypedLiteral node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    // The entity won't be the first child entity (node.name), since
+    // CompletionTarget would have chosen an edge higher in the parse tree.  So
+    // it must be node.typeArguments, meaning that the cursor is between the
+    // type name and the "<" that starts the type arguments.  In this case,
+    // we have no completions to offer.
+    assert(identical(entity, node.typeArguments));
+  }
+
+  @override
+  void visitTypeParameter(TypeParameter node) {
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    // Make suggestions for the RHS of a variable declaration
+    if (identical(entity, node.initializer)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    if ((node.keyword == null || node.keyword.lexeme != 'var') &&
+        (node.type == null || identical(entity, node.type))) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {}
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    if (identical(entity, node.condition)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
new file mode 100644
index 0000000..e61ebbe
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -0,0 +1,152 @@
+// 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 services.completion.dart.override;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind, SourceChange;
+import 'package:analysis_server/src/protocol_server.dart' as protocol
+    hide CompletionSuggestion, CompletionSuggestionKind;
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+/**
+ * A completion contributor used to suggest replacing partial identifiers inside
+ * a class declaration with templates for inherited members.
+ */
+class OverrideContributor implements DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    SimpleIdentifier targetId = _getTargetId(request.target);
+    if (targetId == null) {
+      return EMPTY_LIST;
+    }
+    ClassDeclaration classDecl =
+        targetId.getAncestor((p) => p is ClassDeclaration);
+    if (classDecl == null) {
+      return EMPTY_LIST;
+    }
+
+    // Generate a collection of inherited members
+    ClassElement classElem = classDecl.element;
+    InheritanceManager manager = new InheritanceManager(classElem.library);
+    MemberMap map = manager.getMapOfMembersInheritedFromInterfaces(classElem);
+    List<String> memberNames = _computeMemberNames(map, classElem);
+
+    // Build suggestions
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    for (String memberName in memberNames) {
+      ExecutableElement element = map.get(memberName);
+      // Gracefully degrade if the overridden element has not been resolved.
+      if (element.returnType != null) {
+        CompletionSuggestion suggestion =
+            _buildSuggestion(request, targetId, element);
+        if (suggestion != null) {
+          suggestions.add(suggestion);
+        }
+      }
+    }
+    return suggestions;
+  }
+
+  /**
+   * Return a template for an override of the given [element] in the given
+   * [source]. If selected, the template will replace [targetId].
+   */
+  String _buildRepacementText(Source source, SimpleIdentifier targetId,
+      CompilationUnit unit, ExecutableElement element) {
+    // AnalysisContext context = element.context;
+    // Inject partially resolved unit for use by change builder
+    // DartChangeBuilder builder = new DartChangeBuilder(context, unit);
+    // builder.addFileEdit(source, context.getModificationStamp(source),
+    //     (DartFileEditBuilder builder) {
+    //   builder.addReplacement(targetId.offset, targetId.length,
+    //       (DartEditBuilder builder) {
+    //     builder.writeOverrideOfInheritedMember(element);
+    //   });
+    // });
+    // return builder.sourceChange.edits[0].edits[0].replacement.trim();
+    return '';
+  }
+
+  /**
+   * Build a suggestion to replace [targetId] in the given [unit]
+   * with an override of the given [element].
+   */
+  CompletionSuggestion _buildSuggestion(DartCompletionRequest request,
+      SimpleIdentifier targetId, ExecutableElement element) {
+    String completion = _buildRepacementText(
+        request.source, targetId, request.target.unit, element);
+    if (completion == null || completion.length == 0) {
+      return null;
+    }
+    CompletionSuggestion suggestion = new CompletionSuggestion(
+        CompletionSuggestionKind.IDENTIFIER,
+        DART_RELEVANCE_HIGH,
+        completion,
+        targetId.offset,
+        0,
+        element.isDeprecated,
+        false);
+    suggestion.element = protocol.convertElement(element);
+    return suggestion;
+  }
+
+  /**
+   * Return a list containing the names of all of the inherited but not
+   * implemented members of the class represented by the given [element].
+   * The [map] is used to find all of the members that are inherited.
+   */
+  List<String> _computeMemberNames(MemberMap map, ClassElement element) {
+    List<String> memberNames = <String>[];
+    int count = map.size;
+    for (int i = 0; i < count; i++) {
+      String memberName = map.getKey(i);
+      if (!_hasMember(element, memberName)) {
+        memberNames.add(memberName);
+      }
+    }
+    return memberNames;
+  }
+
+  /**
+   * If the target looks like a partial identifier inside a class declaration
+   * then return that identifier, otherwise return `null`.
+   */
+  SimpleIdentifier _getTargetId(CompletionTarget target) {
+    AstNode node = target.containingNode;
+    if (node is ClassDeclaration) {
+      Object entity = target.entity;
+      if (entity is FieldDeclaration) {
+        NodeList<VariableDeclaration> variables = entity.fields.variables;
+        if (variables.length == 1) {
+          SimpleIdentifier targetId = variables[0].name;
+          if (targetId.name.isEmpty) {
+            return targetId;
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Return `true` if the given [classElement] directly declares a member with
+   * the given [memberName].
+   */
+  bool _hasMember(ClassElement classElement, String memberName) {
+    return classElement.getField(memberName) != null ||
+        classElement.getGetter(memberName) != null ||
+        classElement.getMethod(memberName) != null ||
+        classElement.getSetter(memberName) != null;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
new file mode 100644
index 0000000..3ed05b3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -0,0 +1,144 @@
+// 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 services.completion.contributor.dart.static_member;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/generated/ast.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating static member invocation / access suggestions
+ * `completion.getSuggestions` request results.
+ */
+class StaticMemberContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    // Determine if the target looks like a static method invocation,
+    // or a static property access
+    if (request.dotTarget is! Identifier || request.target.isCascade) {
+      return EMPTY_LIST;
+    }
+
+    // Resolve the expression and the containing library
+    await request.resolveExpression(request.dotTarget);
+
+    // Recompute the target since resolution may have changed it
+    Expression targetId = request.dotTarget;
+    if (targetId is Identifier && !request.target.isCascade) {
+      Element elem = targetId.bestElement;
+      if (elem is ClassElement) {
+        LibraryElement containingLibrary = request.libraryElement;
+        // Gracefully degrade if the library could not be determined
+        // e.g. detached part file or source change
+        if (containingLibrary == null) {
+          return EMPTY_LIST;
+        }
+
+        _SuggestionBuilder builder = new _SuggestionBuilder(containingLibrary);
+        elem.accept(builder);
+        return builder.suggestions;
+      }
+    }
+    return EMPTY_LIST;
+  }
+}
+
+/**
+ * This class visits elements in a class and provides suggestions based upon
+ * the visible static members in that class.
+ */
+class _SuggestionBuilder extends GeneralizingElementVisitor {
+  /**
+   * The library containing the unit in which the completion is requested.
+   */
+  final LibraryElement containingLibrary;
+
+  /**
+   * A collection of completion suggestions.
+   */
+  final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+
+  _SuggestionBuilder(this.containingLibrary);
+
+  @override
+  visitClassElement(ClassElement element) {
+    element.visitChildren(this);
+  }
+
+  @override
+  visitElement(Element element) {
+    // ignored
+  }
+
+  @override
+  visitFieldElement(FieldElement element) {
+    if (element.isStatic) {
+      _addSuggestion(element);
+    }
+  }
+
+  @override
+  visitMethodElement(MethodElement element) {
+    if (element.isStatic && !element.isOperator) {
+      _addSuggestion(element);
+    }
+  }
+
+  @override
+  visitPropertyAccessorElement(PropertyAccessorElement element) {
+    if (element.isStatic) {
+      _addSuggestion(element);
+    }
+  }
+
+  /**
+     * Add a suggestion based upon the given element.
+     */
+  void _addSuggestion(Element element) {
+    if (element.isPrivate) {
+      if (element.library != containingLibrary) {
+        // Do not suggest private members for imported libraries
+        return;
+      }
+    }
+    if (element.isSynthetic) {
+      if ((element is PropertyAccessorElement) ||
+          element is FieldElement && !_isSpecialEnumField(element)) {
+        return;
+      }
+    }
+    String completion = element.displayName;
+    if (completion == null || completion.length <= 0) {
+      return;
+    }
+    CompletionSuggestion suggestion =
+        createSuggestion(element, completion: completion);
+    if (suggestion != null) {
+      suggestions.add(suggestion);
+    }
+  }
+
+  /**
+     * Determine if the given element is one of the synthetic enum accessors
+     * for which we should generate a suggestion.
+     */
+  bool _isSpecialEnumField(FieldElement element) {
+    Element parent = element.enclosingElement;
+    if (parent is ClassElement && parent.isEnum) {
+      if (element.name == 'values') {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
new file mode 100644
index 0000000..2a537bf
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -0,0 +1,283 @@
+// 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 services.completion.dart.suggestion.builder;
+
+import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analysis_server/src/protocol_server.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/utilities/documentation.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:path/path.dart' as path;
+
+const String DYNAMIC = 'dynamic';
+
+/**
+ * Return a suggestion based upon the given element
+ * or `null` if a suggestion is not appropriate for the given element.
+ * If the suggestion is not currently in scope, then specify
+ * importForSource as the source to which an import should be added.
+ */
+CompletionSuggestion createSuggestion(Element element,
+    {String completion,
+    CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+    int relevance: DART_RELEVANCE_DEFAULT,
+    Source importForSource}) {
+  if (element is ExecutableElement && element.isOperator) {
+    // Do not include operators in suggestions
+    return null;
+  }
+  if (completion == null) {
+    completion = element.displayName;
+  }
+  bool isDeprecated = element.isDeprecated;
+  CompletionSuggestion suggestion = new CompletionSuggestion(
+      kind,
+      isDeprecated ? DART_RELEVANCE_LOW : relevance,
+      completion,
+      completion.length,
+      0,
+      isDeprecated,
+      false);
+
+  // Attach docs.
+  String doc = removeDartDocDelimiters(element.documentationComment);
+  suggestion.docComplete = doc;
+  suggestion.docSummary = getDartDocSummary(doc);
+
+  suggestion.element = protocol.convertElement(element);
+  Element enclosingElement = element.enclosingElement;
+  if (enclosingElement is ClassElement) {
+    suggestion.declaringType = enclosingElement.displayName;
+  }
+  suggestion.returnType = getReturnTypeString(element);
+  if (element is ExecutableElement && element is! PropertyAccessorElement) {
+    suggestion.parameterNames = element.parameters
+        .map((ParameterElement parameter) => parameter.name)
+        .toList();
+    suggestion.parameterTypes =
+        element.parameters.map((ParameterElement parameter) {
+      DartType paramType = parameter.type;
+      // Gracefully degrade if type not resolved yet
+      return paramType != null ? paramType.displayName : 'var';
+    }).toList();
+    suggestion.requiredParameterCount = element.parameters
+        .where((ParameterElement parameter) =>
+            parameter.parameterKind == ParameterKind.REQUIRED)
+        .length;
+    suggestion.hasNamedParameters = element.parameters.any(
+        (ParameterElement parameter) =>
+            parameter.parameterKind == ParameterKind.NAMED);
+  }
+  if (importForSource != null) {
+    String srcPath = path.dirname(importForSource.fullName);
+    LibraryElement libElem = element.library;
+    if (libElem != null) {
+      Source libSource = libElem.source;
+      if (libSource != null) {
+        UriKind uriKind = libSource.uriKind;
+        if (uriKind == UriKind.DART_URI) {
+          suggestion.importUri = libSource.uri.toString();
+        } else if (uriKind == UriKind.PACKAGE_URI) {
+          suggestion.importUri = libSource.uri.toString();
+        } else if (uriKind == UriKind.FILE_URI &&
+            element.source.uriKind == UriKind.FILE_URI) {
+          try {
+            suggestion.importUri =
+                path.relative(libSource.fullName, from: srcPath);
+          } catch (_) {
+            // ignored
+          }
+        }
+      }
+    }
+    if (suggestion.importUri == null) {
+      // Do not include out of scope suggestions
+      // for which we cannot determine an import
+      return null;
+    }
+  }
+  return suggestion;
+}
+
+/**
+ * Common mixin for sharing behavior
+ */
+abstract class ElementSuggestionBuilder {
+  /**
+   * A collection of completion suggestions.
+   */
+  final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+
+  /**
+   * A set of existing completions used to prevent duplicate suggestions.
+   */
+  final Set<String> _completions = new Set<String>();
+
+  /**
+   * A map of element names to suggestions for synthetic getters and setters.
+   */
+  final Map<String, CompletionSuggestion> _syntheticMap =
+      <String, CompletionSuggestion>{};
+
+  /**
+   * Return the library in which the completion is requested.
+   */
+  LibraryElement get containingLibrary;
+
+  /**
+   * Return the kind of suggestions that should be built.
+   */
+  CompletionSuggestionKind get kind;
+
+  /**
+   * Add a suggestion based upon the given element.
+   */
+  void addSuggestion(Element element,
+      {String prefix, int relevance: DART_RELEVANCE_DEFAULT}) {
+    if (element.isPrivate) {
+      if (element.library != containingLibrary) {
+        return;
+      }
+    }
+    String completion = element.displayName;
+    if (prefix != null && prefix.length > 0) {
+      if (completion == null || completion.length <= 0) {
+        completion = prefix;
+      } else {
+        completion = '$prefix.$completion';
+      }
+    }
+    if (completion == null || completion.length <= 0) {
+      return;
+    }
+    CompletionSuggestion suggestion = createSuggestion(element,
+        completion: completion, kind: kind, relevance: relevance);
+    if (suggestion != null) {
+      if (element.isSynthetic && element is PropertyAccessorElement) {
+        String cacheKey;
+        if (element.isGetter) {
+          cacheKey = element.name;
+        }
+        if (element.isSetter) {
+          cacheKey = element.name;
+          cacheKey = cacheKey.substring(0, cacheKey.length - 1);
+        }
+        if (cacheKey != null) {
+          CompletionSuggestion existingSuggestion = _syntheticMap[cacheKey];
+
+          // Pair getter/setter by updating the existing suggestion
+          if (existingSuggestion != null) {
+            CompletionSuggestion getter =
+                element.isGetter ? suggestion : existingSuggestion;
+            protocol.ElementKind elemKind =
+                element.enclosingElement is ClassElement
+                    ? protocol.ElementKind.FIELD
+                    : protocol.ElementKind.TOP_LEVEL_VARIABLE;
+            existingSuggestion.element = new protocol.Element(
+                elemKind,
+                existingSuggestion.element.name,
+                existingSuggestion.element.flags,
+                location: getter.element.location,
+                typeParameters: getter.element.typeParameters,
+                parameters: null,
+                returnType: getter.returnType);
+            return;
+          }
+
+          // Cache lone getter/setter so that it can be paired
+          _syntheticMap[cacheKey] = suggestion;
+        }
+      }
+      if (_completions.add(suggestion.completion)) {
+        suggestions.add(suggestion);
+      }
+    }
+  }
+}
+
+/**
+ * This class visits elements in a library and provides suggestions based upon
+ * the visible members in that library.
+ */
+class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
+    with ElementSuggestionBuilder {
+  final LibraryElement containingLibrary;
+  final CompletionSuggestionKind kind;
+  final bool typesOnly;
+  final bool instCreation;
+
+  LibraryElementSuggestionBuilder(
+      this.containingLibrary, this.kind, this.typesOnly, this.instCreation);
+
+  @override
+  visitClassElement(ClassElement element) {
+    if (instCreation) {
+      element.visitChildren(this);
+    } else {
+      addSuggestion(element);
+    }
+  }
+
+  @override
+  visitCompilationUnitElement(CompilationUnitElement element) {
+    element.visitChildren(this);
+    LibraryElement containingLibrary = element.library;
+    if (containingLibrary != null) {
+      for (var lib in containingLibrary.exportedLibraries) {
+        lib.visitChildren(this);
+      }
+    }
+  }
+
+  @override
+  visitConstructorElement(ConstructorElement element) {
+    if (instCreation) {
+      ClassElement classElem = element.enclosingElement;
+      if (classElem != null) {
+        String prefix = classElem.name;
+        if (prefix != null && prefix.length > 0) {
+          addSuggestion(element, prefix: prefix);
+        }
+      }
+    }
+  }
+
+  @override
+  visitElement(Element element) {
+    // ignored
+  }
+
+  @override
+  visitFunctionElement(FunctionElement element) {
+    if (!typesOnly) {
+      int relevance = element.library == containingLibrary
+          ? DART_RELEVANCE_LOCAL_FUNCTION
+          : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element, relevance: relevance);
+    }
+  }
+
+  @override
+  visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    if (!instCreation) {
+      addSuggestion(element);
+    }
+  }
+
+  @override
+  visitTopLevelVariableElement(TopLevelVariableElement element) {
+    if (!typesOnly) {
+      int relevance = element.library == containingLibrary
+          ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
+          : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element, relevance: relevance);
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
new file mode 100644
index 0000000..257527b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -0,0 +1,413 @@
+// 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 services.completion.contributor.dart.type_member;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating instance invocation / access suggestions
+ * `completion.getSuggestions` request results.
+ */
+class TypeMemberContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    // Determine if the target looks like a prefixed identifier,
+    // a method invocation, or a property access
+    Expression parsedExpression = request.dotTarget;
+    if (parsedExpression == null) {
+      return EMPTY_LIST;
+    }
+
+    // Resolve the expression and the containing library
+    await request.resolveExpression(parsedExpression);
+    LibraryElement containingLibrary = request.libraryElement;
+    // Gracefully degrade if the library element could not be resolved
+    // e.g. detached part file or source change
+    if (containingLibrary == null) {
+      return EMPTY_LIST;
+    }
+
+    // Recompute the target since resolution may have changed it
+    Expression expression = request.dotTarget;
+    if (expression == null || expression.isSynthetic) {
+      return EMPTY_LIST;
+    }
+    if (expression is Identifier) {
+      Element elem = expression.bestElement;
+      if (elem is ClassElement) {
+        // Suggestions provided by StaticMemberContributor
+        return EMPTY_LIST;
+      }
+      if (elem is PrefixElement) {
+        // Suggestions provided by LibraryMemberContributor
+        return EMPTY_LIST;
+      }
+    }
+
+    // Determine the target expression's type
+    DartType type = expression.bestType;
+    if (type.isDynamic) {
+      // If the expression does not provide a good type
+      // then attempt to get a better type from the element
+      if (expression is Identifier) {
+        Element elem = expression.bestElement;
+        if (elem is FunctionTypedElement) {
+          type = elem.returnType;
+        } else if (elem is ParameterElement) {
+          type = elem.type;
+        } else if (elem is LocalVariableElement) {
+          type = elem.type;
+        }
+        if (type.isDynamic && expression is SimpleIdentifier) {
+          // If the element does not provide a good type
+          // then attempt to get a better type from a local declaration
+          _LocalBestTypeVisitor visitor =
+              new _LocalBestTypeVisitor(expression.name, request.offset);
+          if (visitor.visit(expression) && visitor.typeFound != null) {
+            type = visitor.typeFound;
+          }
+        }
+      }
+    }
+    String containingMethodName;
+    if (expression is SuperExpression && type is InterfaceType) {
+      // Suggest members from superclass if target is "super"
+      type = (type as InterfaceType).superclass;
+      // Determine the name of the containing method because
+      // the most likely completion is a super expression with same name
+      MethodDeclaration containingMethod =
+          expression.getAncestor((p) => p is MethodDeclaration);
+      if (containingMethod != null) {
+        SimpleIdentifier id = containingMethod.name;
+        if (id != null) {
+          containingMethodName = id.name;
+        }
+      }
+    }
+    if (type.isDynamic) {
+      // Suggest members from object if target is "dynamic"
+      type = request.objectType;
+    }
+
+    // Build the suggestions
+    if (type is InterfaceType) {
+      _SuggestionBuilder builder = new _SuggestionBuilder(containingLibrary);
+      builder.buildSuggestions(type, containingMethodName);
+      return builder.suggestions.toList();
+    }
+    return EMPTY_LIST;
+  }
+}
+
+/**
+ * An [AstVisitor] which looks for a declaration with the given name
+ * and if found, tries to determine a type for that declaration.
+ */
+class _LocalBestTypeVisitor extends LocalDeclarationVisitor {
+  /**
+   * The name for the declaration to be found.
+   */
+  final String targetName;
+
+  /**
+   * The best type for the found declaration,
+   * or `null` if no declaration found or failed to determine a type.
+   */
+  DartType typeFound;
+
+  /**
+   * Construct a new instance to search for a declaration
+   */
+  _LocalBestTypeVisitor(this.targetName, int offset) : super(offset);
+
+  @override
+  void declaredClass(ClassDeclaration declaration) {
+    if (declaration.name.name == targetName) {
+      // no type
+      finished();
+    }
+  }
+
+  @override
+  void declaredClassTypeAlias(ClassTypeAlias declaration) {
+    if (declaration.name.name == targetName) {
+      // no type
+      finished();
+    }
+  }
+
+  @override
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+    if (varDecl.name.name == targetName) {
+      // Type provided by the element in computeFull above
+      finished();
+    }
+  }
+
+  @override
+  void declaredFunction(FunctionDeclaration declaration) {
+    if (declaration.name.name == targetName) {
+      TypeName typeName = declaration.returnType;
+      if (typeName != null) {
+        typeFound = typeName.type;
+      }
+      finished();
+    }
+  }
+
+  @override
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
+    if (declaration.name.name == targetName) {
+      TypeName typeName = declaration.returnType;
+      if (typeName != null) {
+        typeFound = typeName.type;
+      }
+      finished();
+    }
+  }
+
+  @override
+  void declaredLabel(Label label, bool isCaseLabel) {
+    if (label.label.name == targetName) {
+      // no type
+      finished();
+    }
+  }
+
+  @override
+  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
+    if (name.name == targetName) {
+      typeFound = name.bestType;
+      finished();
+    }
+  }
+
+  @override
+  void declaredMethod(MethodDeclaration declaration) {
+    if (declaration.name.name == targetName) {
+      TypeName typeName = declaration.returnType;
+      if (typeName != null) {
+        typeFound = typeName.type;
+      }
+      finished();
+    }
+  }
+
+  @override
+  void declaredParam(SimpleIdentifier name, TypeName type) {
+    if (name.name == targetName) {
+      // Type provided by the element in computeFull above
+      finished();
+    }
+  }
+
+  @override
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl) {
+    if (varDecl.name.name == targetName) {
+      // Type provided by the element in computeFull above
+      finished();
+    }
+  }
+}
+
+/**
+ * This class provides suggestions based upon the visible instance members in
+ * an interface type.
+ */
+class _SuggestionBuilder {
+  /**
+   * Enumerated value indicating that we have not generated any completions for
+   * a given identifier yet.
+   */
+  static const int _COMPLETION_TYPE_NONE = 0;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * getter.
+   */
+  static const int _COMPLETION_TYPE_GETTER = 1;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * setter.
+   */
+  static const int _COMPLETION_TYPE_SETTER = 2;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * field, a method, or a getter/setter pair.
+   */
+  static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
+
+  /**
+   * The library containing the unit in which the completion is requested.
+   */
+  final LibraryElement containingLibrary;
+
+  /**
+   * Map indicating, for each possible completion identifier, whether we have
+   * already generated completions for a getter, setter, or both.  The "both"
+   * case also handles the case where have generated a completion for a method
+   * or a field.
+   *
+   * Note: the enumerated values stored in this map are intended to be bitwise
+   * compared.
+   */
+  Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
+
+  /**
+   * Map from completion identifier to completion suggestion
+   */
+  Map<String, CompletionSuggestion> _suggestionMap =
+      <String, CompletionSuggestion>{};
+
+  _SuggestionBuilder(this.containingLibrary);
+
+  Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
+
+  /**
+   * Return completion suggestions for 'dot' completions on the given [type].
+   * If the 'dot' completion is a super expression, then [containingMethodName]
+   * is the name of the method in which the completion is requested.
+   */
+  void buildSuggestions(InterfaceType type, String containingMethodName) {
+    // Visit all of the types in the class hierarchy, collecting possible
+    // completions.  If multiple elements are found that complete to the same
+    // identifier, addSuggestion will discard all but the first (with a few
+    // exceptions to handle getter/setter pairs).
+    List<InterfaceType> types = _getTypeOrdering(type);
+    for (InterfaceType targetType in types) {
+      for (MethodElement method in targetType.methods) {
+        // Exclude static methods when completion on an instance
+        if (!method.isStatic) {
+          // Boost the relevance of a super expression
+          // calling a method of the same name as the containing method
+          _addSuggestion(method,
+              relevance: method.name == containingMethodName
+                  ? DART_RELEVANCE_HIGH
+                  : DART_RELEVANCE_DEFAULT);
+        }
+      }
+      for (PropertyAccessorElement propertyAccessor in targetType.accessors) {
+        if (!propertyAccessor.isStatic) {
+          if (propertyAccessor.isSynthetic) {
+            // Avoid visiting a field twice
+            if (propertyAccessor.isGetter) {
+              _addSuggestion(propertyAccessor.variable);
+            }
+          } else {
+            _addSuggestion(propertyAccessor);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Add a suggestion based upon the given element, provided that it is not
+   * shadowed by a previously added suggestion.
+   */
+  void _addSuggestion(Element element,
+      {int relevance: DART_RELEVANCE_DEFAULT}) {
+    if (element.isPrivate) {
+      if (element.library != containingLibrary) {
+        // Do not suggest private members for imported libraries
+        return;
+      }
+    }
+    String identifier = element.displayName;
+    int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
+        identifier, () => _COMPLETION_TYPE_NONE);
+    if (element is MethodElement) {
+      // Anything shadows a method.
+      if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
+        return;
+      }
+      _completionTypesGenerated[identifier] =
+          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+    } else if (element is PropertyAccessorElement) {
+      if (element.isGetter) {
+        // Getters, fields, and methods shadow a getter.
+        if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
+          return;
+        }
+        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
+      } else {
+        // Setters, fields, and methods shadow a setter.
+        if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
+          return;
+        }
+        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
+      }
+    } else if (element is FieldElement) {
+      // Fields and methods shadow a field.  A getter/setter pair shadows a
+      // field, but a getter or setter by itself doesn't.
+      if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
+        return;
+      }
+      _completionTypesGenerated[identifier] =
+          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+    } else {
+      // Unexpected element type; skip it.
+      assert(false);
+      return;
+    }
+    CompletionSuggestion suggestion =
+        createSuggestion(element, relevance: relevance);
+    if (suggestion != null) {
+      _suggestionMap[suggestion.completion] = suggestion;
+    }
+  }
+
+  /**
+   * Get a list of [InterfaceType]s that should be searched to find the
+   * possible completions for an object having type [type].
+   */
+  List<InterfaceType> _getTypeOrdering(InterfaceType type) {
+    // Candidate completions can come from [type] as well as any types above it
+    // in the class hierarchy (including mixins, superclasses, and interfaces).
+    // If a given completion identifier shows up in multiple types, we should
+    // use the element that is nearest in the superclass chain, so we will
+    // visit [type] first, then its mixins, then its superclass, then its
+    // superclass's mixins, etc., and only afterwards visit interfaces.
+    //
+    // We short-circuit loops in the class hierarchy by keeping track of the
+    // classes seen (not the interfaces) so that we won't be fooled by nonsense
+    // like "class C<T> extends C<List<T>> {}"
+    List<InterfaceType> result = <InterfaceType>[];
+    Set<ClassElement> classesSeen = new HashSet<ClassElement>();
+    List<InterfaceType> typesToVisit = <InterfaceType>[type];
+    while (typesToVisit.isNotEmpty) {
+      InterfaceType nextType = typesToVisit.removeLast();
+      if (!classesSeen.add(nextType.element)) {
+        // Class had already been seen, so ignore this type.
+        continue;
+      }
+      result.add(nextType);
+      // typesToVisit is a stack, so push on the interfaces first, then the
+      // superclass, then the mixins.  This will ensure that they are visited
+      // in the reverse order.
+      typesToVisit.addAll(nextType.interfaces);
+      if (nextType.superclass != null) {
+        typesToVisit.add(nextType.superclass);
+      }
+      typesToVisit.addAll(nextType.mixins);
+    }
+    return result;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
new file mode 100644
index 0000000..7e849b1
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
@@ -0,0 +1,195 @@
+// 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 services.completion.contributor.dart.importuri;
+
+import 'dart:async';
+import 'dart:core' hide Resource;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:path/path.dart' show posix;
+import 'package:path/src/context.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating uri suggestions
+ * for import and part directives.
+ */
+class UriContributor extends DartCompletionContributor {
+  _UriSuggestionBuilder builder;
+
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    builder = new _UriSuggestionBuilder(request);
+    request.target.containingNode.accept(builder);
+    return builder.suggestions;
+  }
+}
+
+class _UriSuggestionBuilder extends SimpleAstVisitor {
+  final DartCompletionRequest request;
+  final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+
+  _UriSuggestionBuilder(this.request);
+
+  @override
+  visitExportDirective(ExportDirective node) {
+    visitNamespaceDirective(node);
+  }
+
+  @override
+  visitImportDirective(ImportDirective node) {
+    visitNamespaceDirective(node);
+  }
+
+  visitNamespaceDirective(NamespaceDirective node) {
+    StringLiteral uri = node.uri;
+    if (uri is SimpleStringLiteral) {
+      int offset = request.offset;
+      if (uri.offset < offset &&
+          (offset < uri.end || offset == uri.offset + 1)) {
+        // Handle degenerate case where import or export is only line in file
+        // and there is no semicolon
+        visitSimpleStringLiteral(uri);
+      }
+    }
+  }
+
+  @override
+  visitSimpleStringLiteral(SimpleStringLiteral node) {
+    AstNode parent = node.parent;
+    if (parent is NamespaceDirective && parent.uri == node) {
+      String partialUri = _extractPartialUri(node);
+      if (partialUri != null) {
+        _addDartSuggestions();
+        _addPackageSuggestions(partialUri);
+        _addFileSuggestions(partialUri);
+      }
+    } else if (parent is PartDirective && parent.uri == node) {
+      String partialUri = _extractPartialUri(node);
+      if (partialUri != null) {
+        _addFileSuggestions(partialUri);
+      }
+    }
+  }
+
+  void _addDartSuggestions() {
+    _addSuggestion('dart:');
+    SourceFactory factory = request.context.sourceFactory;
+    for (SdkLibrary lib in factory.dartSdk.sdkLibraries) {
+      if (!lib.isInternal && !lib.isImplementation) {
+        if (!lib.shortName.startsWith('dart:_')) {
+          _addSuggestion(lib.shortName,
+              relevance: lib.shortName == 'dart:core'
+                  ? DART_RELEVANCE_LOW
+                  : DART_RELEVANCE_DEFAULT);
+        }
+      }
+    }
+  }
+
+  void _addFileSuggestions(String partialUri) {
+    ResourceProvider resProvider = request.resourceProvider;
+    Context resContext = resProvider.pathContext;
+    Source source = request.source;
+
+    String parentUri;
+    if ((partialUri.endsWith('/'))) {
+      parentUri = partialUri;
+    } else {
+      parentUri = posix.dirname(partialUri);
+      if (parentUri != '.' && !parentUri.endsWith('/')) {
+        parentUri = '$parentUri/';
+      }
+    }
+    String uriPrefix = parentUri == '.' ? '' : parentUri;
+
+    String dirPath = resContext.normalize(parentUri);
+    if (resContext.isRelative(dirPath)) {
+      String sourceDirPath = resContext.dirname(source.fullName);
+      if (resContext.isAbsolute(sourceDirPath)) {
+        dirPath = resContext.normalize(resContext.join(sourceDirPath, dirPath));
+      } else {
+        return;
+      }
+      // Do not suggest relative paths reaching outside the 'lib' directory.
+      bool srcInLib = resContext.split(sourceDirPath).contains('lib');
+      bool dstInLib = resContext.split(dirPath).contains('lib');
+      if (srcInLib && !dstInLib) {
+        return;
+      }
+    }
+    if (dirPath.endsWith('\\.')) {
+      dirPath = dirPath.substring(0, dirPath.length - 1);
+    }
+
+    Resource dir = resProvider.getResource(dirPath);
+    if (dir is Folder) {
+      for (Resource child in dir.getChildren()) {
+        String completion;
+        if (child is Folder) {
+          completion = '$uriPrefix${child.shortName}/';
+        } else {
+          completion = '$uriPrefix${child.shortName}';
+        }
+        if (completion != source.shortName) {
+          _addSuggestion(completion);
+        }
+      }
+    }
+  }
+
+  void _addPackageFolderSuggestions(
+      String partial, String prefix, Folder folder) {
+    for (Resource child in folder.getChildren()) {
+      if (child is Folder) {
+        String childPrefix = '$prefix${child.shortName}/';
+        _addSuggestion(childPrefix);
+        if (partial.startsWith(childPrefix)) {
+          _addPackageFolderSuggestions(partial, childPrefix, child);
+        }
+      } else {
+        _addSuggestion('$prefix${child.shortName}');
+      }
+    }
+  }
+
+  void _addPackageSuggestions(String partial) {
+    SourceFactory factory = request.context.sourceFactory;
+    Map<String, List<Folder>> packageMap = factory.packageMap;
+    if (packageMap != null) {
+      _addSuggestion('package:');
+      packageMap.forEach((String pkgName, List<Folder> folders) {
+        String prefix = 'package:$pkgName/';
+        _addSuggestion(prefix);
+        for (Folder folder in folders) {
+          if (folder.exists) {
+            _addPackageFolderSuggestions(partial, prefix, folder);
+          }
+        }
+      });
+    }
+  }
+
+  void _addSuggestion(String completion,
+      {int relevance: DART_RELEVANCE_DEFAULT}) {
+    suggestions.add(new CompletionSuggestion(CompletionSuggestionKind.IMPORT,
+        relevance, completion, completion.length, 0, false, false));
+  }
+
+  String _extractPartialUri(SimpleStringLiteral node) {
+    if (request.offset < node.contentsOffset) {
+      return null;
+    }
+    return node.literal.lexeme.substring(
+        node.contentsOffset - node.offset, request.offset - node.offset);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
deleted file mode 100644
index 2fbe91e..0000000
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
+++ /dev/null
@@ -1,422 +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 services.completion.dart.cache;
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * The `DartCompletionCache` contains cached information from a prior code
- * completion operation.
- */
-class DartCompletionCache extends CompletionCache {
-  /**
-   * A hash of the import directives
-   * or `null` if nothing has been cached.
-   */
-  String _importKey;
-
-  /**
-   * Library prefix suggestions based upon imports,
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> libraryPrefixSuggestions;
-
-  /**
-   * Type suggestions based upon imports,
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> importedTypeSuggestions;
-
-  /**
-   * Suggestions for methods and functions that have void return type,
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> importedVoidReturnSuggestions;
-
-  /**
-   * Other suggestions based upon imports,
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> otherImportedSuggestions;
-
-  /**
-   * Suggestions for constructors
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> importedConstructorSuggestions;
-
-  /**
-   * A collection of all imported completions
-   * or `null` if nothing has been cached.
-   */
-  HashSet<String> _importedCompletions;
-
-  /**
-   * A map of simple identifier to imported class element
-   * or `null` if nothing has been cached.
-   */
-  Map<String, ClassElement> importedClassMap;
-
-  /**
-   * The [ClassElement] for Object.
-   */
-  ClassElement _objectClassElement;
-
-  DartCompletionCache(AnalysisContext context, Source source)
-      : super(context, source);
-
-  /**
-   * Return a hash of the import directives for the cached import info
-   * or `null` if nothing has been cached.
-   */
-  String get importKey => _importKey;
-
-  /**
-   * Return the [ClassElement] for Object.
-   */
-  ClassElement get objectClassElement {
-    if (_objectClassElement == null) {
-      Source coreUri = context.sourceFactory.forUri('dart:core');
-      LibraryElement coreLib = context.getLibraryElement(coreUri);
-      _objectClassElement = coreLib.getType('Object');
-    }
-    return _objectClassElement;
-  }
-
-  /**
-   * Given a resolved compilation unit, compute suggestions based upon the
-   * imports and other dart files (e.g. "part" files) in the library containing
-   * the given compilation unit. The returned future completes when the cache
-   * is populated.
-   *
-   * If [shouldWaitForLowPrioritySuggestions] is `true` then the returned
-   * future will complete when the cache is fully populated. If `false`,
-   * the returned future will complete sooner, but the cache will not include
-   * the lower priority suggestions added as a result of a global search.
-   * In this case, those lower priority suggestions will be added later
-   * when the index has been updated and the global search completes.
-   */
-  Future<bool> computeImportInfo(CompilationUnit unit,
-      SearchEngine searchEngine, bool shouldWaitForLowPrioritySuggestions) {
-    importedTypeSuggestions = <CompletionSuggestion>[];
-    libraryPrefixSuggestions = <CompletionSuggestion>[];
-    otherImportedSuggestions = <CompletionSuggestion>[];
-    importedConstructorSuggestions = <CompletionSuggestion>[];
-    importedVoidReturnSuggestions = <CompletionSuggestion>[];
-    importedClassMap = new Map<String, ClassElement>();
-    _importedCompletions = new HashSet<String>();
-
-    // Assert that the compilation unit is resolved
-    // and represents the expected source
-    assert(unit.element.source == source);
-
-    // Exclude elements from local library
-    // because they are provided by LocalReferenceContributor
-    Set<LibraryElement> excludedLibs = new Set<LibraryElement>();
-    excludedLibs.add(unit.element.enclosingElement);
-
-    // Determine the compilation unit defining the library containing
-    // this compilation unit
-    List<Source> libraries = context.getLibrariesContaining(source);
-    assert(libraries != null);
-    Source libSource = libraries.length > 0 ? libraries[0] : null;
-    Future<CompilationUnit> futureLibUnit = _computeLibUnit(libSource, unit);
-
-    // Include implicitly imported dart:core elements
-    _addDartCoreSuggestions();
-
-    // Include explicitly imported and part elements
-    Future futureImportsCached = futureLibUnit.then((CompilationUnit libUnit) {
-      _addImportedElemSuggestions(libSource, libUnit, excludedLibs);
-      // Don't wait for search of lower relevance results to complete.
-      // Set key indicating results are ready, and lower relevance results
-      // will be added to the cache when the search completes.
-      _importKey = _computeImportKey(unit);
-      return true;
-    });
-
-    // Add non-imported elements as low relevance
-    // after the imported element suggestions have been added
-    Future<bool> futureAllCached = futureImportsCached.then((_) {
-      return searchEngine
-          .searchTopLevelDeclarations('')
-          .then((List<SearchMatch> matches) {
-        _addNonImportedElementSuggestions(matches, excludedLibs);
-        return true;
-      });
-    });
-
-    return shouldWaitForLowPrioritySuggestions
-        ? futureAllCached
-        : futureImportsCached;
-  }
-
-  /**
-   * Return `true` if the import information is cached for the given
-   * compilation unit.
-   */
-  bool isImportInfoCached(CompilationUnit unit) =>
-      _importKey != null && _importKey == _computeImportKey(unit);
-
-  /**
-   * Add constructor suggestions for the given class.
-   */
-  void _addConstructorSuggestions(
-      ClassElement classElem, int relevance, Source importForSource) {
-    String className = classElem.name;
-    for (ConstructorElement constructor in classElem.constructors) {
-      if (!constructor.isPrivate) {
-        CompletionSuggestion suggestion = createSuggestion(constructor,
-            relevance: relevance, importForSource: importForSource);
-        if (suggestion != null) {
-          String name = suggestion.completion;
-          name = name.length > 0 ? '$className.$name' : className;
-          suggestion.completion = name;
-          suggestion.selectionOffset = suggestion.completion.length;
-          importedConstructorSuggestions.add(suggestion);
-        }
-      }
-    }
-  }
-
-  /**
-   * Add suggestions for implicitly imported elements in dart:core.
-   */
-  void _addDartCoreSuggestions() {
-    Source coreUri = context.sourceFactory.forUri('dart:core');
-    LibraryElement coreLib = context.getLibraryElement(coreUri);
-    if (coreLib == null) {
-      // If the core library has not been analyzed yet, then we cannot add any
-      // suggestions from it.
-      return;
-    }
-    Namespace coreNamespace =
-        new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
-    coreNamespace.definedNames.forEach((String name, Element elem) {
-      if (elem is ClassElement) {
-        importedClassMap[name] = elem;
-      }
-      _addSuggestion(elem, DART_RELEVANCE_DEFAULT);
-    });
-  }
-
-  /**
-   * Add suggestions for explicitly imported and part elements in the given
-   * library. Add libraries that should not have their elements suggested
-   * even as low priority to [excludedLibs].
-   */
-  void _addImportedElemSuggestions(Source libSource, CompilationUnit libUnit,
-      Set<LibraryElement> excludedLibs) {
-    if (libUnit != null) {
-      libUnit.directives.forEach((Directive directive) {
-        if (directive is ImportDirective) {
-          ImportElement importElem = directive.element;
-          if (importElem != null && importElem.importedLibrary != null) {
-            if (directive.prefix == null) {
-              Namespace importNamespace = new NamespaceBuilder()
-                  .createImportNamespaceForDirective(importElem);
-              // Include top level elements
-              importNamespace.definedNames.forEach((String name, Element elem) {
-                if (elem is ClassElement) {
-                  importedClassMap[name] = elem;
-                }
-                _addSuggestion(elem, DART_RELEVANCE_DEFAULT);
-              });
-            } else {
-              // Exclude elements from prefixed imports
-              // because they are provided by PrefixedElementContributor
-              _addLibraryPrefixSuggestion(importElem);
-              excludedLibs.add(importElem.importedLibrary);
-            }
-          }
-        } else if (directive is PartDirective) {
-          CompilationUnitElement partElem = directive.element;
-          if (partElem != null && partElem.source != source) {
-            partElem.accept(new _NonLocalElementCacheVisitor(this));
-          }
-        }
-      });
-      if (libSource != source) {
-        libUnit.element.accept(new _NonLocalElementCacheVisitor(this));
-      }
-    }
-  }
-
-  void _addLibraryPrefixSuggestion(ImportElement importElem) {
-    CompletionSuggestion suggestion = null;
-    String completion = importElem.prefix.displayName;
-    if (completion != null && completion.length > 0) {
-      suggestion = new CompletionSuggestion(
-          CompletionSuggestionKind.INVOCATION,
-          DART_RELEVANCE_DEFAULT,
-          completion,
-          completion.length,
-          0,
-          importElem.isDeprecated,
-          false);
-      LibraryElement lib = importElem.importedLibrary;
-      if (lib != null) {
-        suggestion.element = convertElement(lib);
-      }
-      libraryPrefixSuggestions.add(suggestion);
-      _importedCompletions.add(suggestion.completion);
-    }
-  }
-
-  /**
-   * Add suggestions for all top level elements in the context
-   * excluding those elemnents for which suggestions have already been added.
-   */
-  void _addNonImportedElementSuggestions(
-      List<SearchMatch> matches, Set<LibraryElement> excludedLibs) {
-    // Exclude internal Dart SDK libraries
-    for (var lib in context.sourceFactory.dartSdk.sdkLibraries) {
-      if (lib.isInternal) {
-        Source libUri = context.sourceFactory.forUri(lib.shortName);
-        if (libUri != null) {
-          LibraryElement libElem = context.getLibraryElement(libUri);
-          if (libElem != null) {
-            excludedLibs.add(libElem);
-          }
-        }
-      }
-    }
-
-    AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
-    matches.forEach((SearchMatch match) {
-      if (match.kind == MatchKind.DECLARATION) {
-        Element element = match.element;
-        if ((element.context == context || element.context == sdkContext) &&
-            element.isPublic &&
-            !excludedLibs.contains(element.library) &&
-            !_importedCompletions.contains(element.displayName)) {
-          _addSuggestion(element, DART_RELEVANCE_LOW, importForSource: source);
-        }
-      }
-    });
-  }
-
-  /**
-   * Add a suggestion for the given element.
-   */
-  void _addSuggestion(Element element, int relevance,
-      {Source importForSource}) {
-    if (element is ExecutableElement) {
-      // Do not suggest operators or local functions
-      if (element.isOperator) {
-        return;
-      }
-      if (element is FunctionElement) {
-        if (element.enclosingElement is! CompilationUnitElement) {
-          return;
-        }
-      }
-    }
-
-    CompletionSuggestion suggestion = createSuggestion(element,
-        relevance: relevance, importForSource: importForSource);
-
-    if (suggestion != null) {
-      if (element is ExecutableElement) {
-        DartType returnType = element.returnType;
-        if (returnType != null && returnType.isVoid) {
-          importedVoidReturnSuggestions.add(suggestion);
-        } else {
-          otherImportedSuggestions.add(suggestion);
-        }
-      } else if (element is FunctionTypeAliasElement) {
-        importedTypeSuggestions.add(suggestion);
-      } else if (element is ClassElement) {
-        importedTypeSuggestions.add(suggestion);
-        _addConstructorSuggestions(element, relevance, importForSource);
-      } else {
-        otherImportedSuggestions.add(suggestion);
-      }
-      _importedCompletions.add(suggestion.completion);
-    }
-  }
-
-  /**
-   * Compute the hash of the imports for the given compilation unit.
-   */
-  String _computeImportKey(CompilationUnit unit) {
-    StringBuffer sb = new StringBuffer();
-    unit.directives.forEach((Directive directive) {
-      sb.write(directive.toSource());
-    });
-    return sb.toString();
-  }
-
-  /**
-   * Compute the library unit for the given library source,
-   * where the [unit] is the resolved compilation unit associated with [source].
-   */
-  Future<CompilationUnit> _computeLibUnit(
-      Source libSource, CompilationUnit unit) {
-    // If the sources are the same then we already have the library unit
-    if (libSource == source) {
-      return new Future.value(unit);
-    }
-    // If [source] is a part, then compute the library unit
-    if (libSource != null) {
-      return context.computeResolvedCompilationUnitAsync(libSource, libSource);
-    }
-    return new Future.value(null);
-  }
-}
-
-/**
- * A visitor for building suggestions based upon the elements defined by
- * a source file contained in the same library but not the same as
- * the source in which the completions are being requested.
- */
-class _NonLocalElementCacheVisitor extends GeneralizingElementVisitor {
-  final DartCompletionCache cache;
-
-  _NonLocalElementCacheVisitor(this.cache);
-
-  @override
-  void visitClassElement(ClassElement element) {
-    cache._addSuggestion(element, DART_RELEVANCE_DEFAULT);
-  }
-
-  @override
-  void visitCompilationUnitElement(CompilationUnitElement element) {
-    element.visitChildren(this);
-  }
-
-  @override
-  void visitElement(Element element) {
-    // ignored
-  }
-
-  @override
-  void visitFunctionElement(FunctionElement element) {
-    cache._addSuggestion(element, DART_RELEVANCE_DEFAULT);
-  }
-
-  @override
-  void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    cache._addSuggestion(element, DART_RELEVANCE_DEFAULT);
-  }
-
-  @override
-  void visitTopLevelVariableElement(TopLevelVariableElement element) {
-    cache._addSuggestion(element, DART_RELEVANCE_DEFAULT);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
deleted file mode 100644
index 161197d..0000000
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
+++ /dev/null
@@ -1,499 +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 services.completion.dart;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart'
-    show CompletionRequest;
-import 'package:analysis_server/src/provisional/completion/completion_dart.dart'
-    as newApi;
-import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
-import 'package:analysis_server/src/services/completion/arglist_contributor.dart';
-import 'package:analysis_server/src/services/completion/combinator_contributor.dart';
-import 'package:analysis_server/src/services/completion/common_usage_computer.dart';
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/contribution_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
-import 'package:analysis_server/src/services/completion/keyword_contributor.dart';
-import 'package:analysis_server/src/services/completion/local_reference_contributor.dart';
-import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analysis_server/src/services/completion/prefixed_element_contributor.dart';
-import 'package:analysis_server/src/services/completion/uri_contributor.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-const int DART_RELEVANCE_COMMON_USAGE = 1200;
-const int DART_RELEVANCE_DEFAULT = 1000;
-const int DART_RELEVANCE_HIGH = 2000;
-const int DART_RELEVANCE_INHERITED_ACCESSOR = 1057;
-const int DART_RELEVANCE_INHERITED_FIELD = 1058;
-const int DART_RELEVANCE_INHERITED_METHOD = 1057;
-const int DART_RELEVANCE_KEYWORD = 1055;
-const int DART_RELEVANCE_LOCAL_ACCESSOR = 1057;
-const int DART_RELEVANCE_LOCAL_FIELD = 1058;
-const int DART_RELEVANCE_LOCAL_FUNCTION = 1056;
-const int DART_RELEVANCE_LOCAL_METHOD = 1057;
-const int DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE = 1056;
-const int DART_RELEVANCE_LOCAL_VARIABLE = 1059;
-const int DART_RELEVANCE_LOW = 500;
-const int DART_RELEVANCE_NAMED_PARAMETER = 1060;
-const int DART_RELEVANCE_PARAMETER = 1059;
-
-/**
- * The base class for contributing code completion suggestions.
- */
-abstract class DartCompletionContributor {
-  /**
-   * Computes the initial set of [CompletionSuggestion]s based on
-   * the given completion context. The compilation unit and completion node
-   * in the given completion context may not be resolved.
-   * This method should execute quickly and not block waiting for any analysis.
-   * Returns `true` if the contributor's work is complete
-   * or `false` if [computeFull] should be called to complete the work.
-   */
-  bool computeFast(DartCompletionRequest request);
-
-  /**
-   * Computes the complete set of [CompletionSuggestion]s based on
-   * the given completion context.  The compilation unit and completion node
-   * in the given completion context are resolved.
-   * Returns `true` if the receiver modified the list of suggestions.
-   */
-  Future<bool> computeFull(DartCompletionRequest request);
-}
-
-/**
- * Manages code completion for a given Dart file completion request.
- */
-class DartCompletionManager extends CompletionManager {
-  /**
-   * The [defaultContributionSorter] is a long-lived object that isn't allowed
-   * to maintain state between calls to [ContributionSorter#sort(...)].
-   */
-  static ContributionSorter defaultContributionSorter =
-      new CommonUsageComputer();
-
-  final SearchEngine searchEngine;
-  final DartCompletionCache cache;
-  List<DartCompletionContributor> contributors;
-  ContributionSorter contributionSorter;
-
-  DartCompletionManager(
-      AnalysisContext context, this.searchEngine, Source source, this.cache,
-      [this.contributors, this.contributionSorter])
-      : super(context, source) {
-    if (contributors == null) {
-      contributors = [
-        // LocalReferenceContributor before ImportedReferenceContributor
-        // because local suggestions take precedence
-        // and can hide other suggestions with the same name
-        new LocalReferenceContributor(),
-        new ImportedReferenceContributor(),
-        new KeywordContributor(),
-        new ArgListContributor(),
-        new CombinatorContributor(),
-        new PrefixedElementContributor(),
-        new UriContributor(),
-        // TODO(brianwilkerson) Use the completion contributor extension point
-        // to add the contributor below (and eventually, all the contributors).
-//        new NewCompletionWrapper(new InheritedContributor())
-      ];
-    }
-    if (contributionSorter == null) {
-      contributionSorter = defaultContributionSorter;
-    }
-  }
-
-  /**
-   * Create a new initialized Dart source completion manager
-   */
-  factory DartCompletionManager.create(
-      AnalysisContext context, SearchEngine searchEngine, Source source) {
-    return new DartCompletionManager(context, searchEngine, source,
-        new DartCompletionCache(context, source));
-  }
-
-  @override
-  Future<bool> computeCache() {
-    return waitForAnalysis().then((CompilationUnit unit) {
-      if (unit != null && !cache.isImportInfoCached(unit)) {
-        return cache.computeImportInfo(unit, searchEngine, true);
-      } else {
-        return new Future.value(false);
-      }
-    });
-  }
-
-  /**
-   * Compute suggestions based upon cached information only
-   * then send an initial response to the client.
-   * Return a list of contributors for which [computeFull] should be called
-   */
-  List<DartCompletionContributor> computeFast(
-      DartCompletionRequest request, CompletionPerformance performance) {
-    bool isKeywordOrIdentifier(Token token) =>
-        token.type == TokenType.KEYWORD || token.type == TokenType.IDENTIFIER;
-
-    return performance.logElapseTime('computeFast', () {
-      CompilationUnit unit = context.parseCompilationUnit(source);
-      request.unit = unit;
-      request.target = new CompletionTarget.forOffset(unit, request.offset);
-      request.replacementOffset = request.offset;
-      request.replacementLength = 0;
-      if (request.offset < 0 || request.offset > unit.end) {
-        sendResults(request, true);
-        return [];
-      }
-
-      var entity = request.target.entity;
-      Token token = entity is AstNode ? entity.beginToken : entity;
-      if (token != null && request.offset < token.offset) {
-        token = token.previous;
-      }
-      if (token != null) {
-        if (request.offset == token.offset && !isKeywordOrIdentifier(token)) {
-          // If the insertion point is at the beginning of the current token
-          // and the current token is not an identifier
-          // then check the previous token to see if it should be replaced
-          token = token.previous;
-        }
-        if (token != null && isKeywordOrIdentifier(token)) {
-          if (token.offset <= request.offset && request.offset <= token.end) {
-            request.replacementOffset = token.offset;
-            request.replacementLength = token.length;
-          }
-        }
-      }
-
-      List<DartCompletionContributor> todo = new List.from(contributors);
-      todo.removeWhere((DartCompletionContributor c) {
-        return performance.logElapseTime('computeFast ${c.runtimeType}', () {
-          return c.computeFast(request);
-        });
-      });
-      contributionSorter.sort(
-          new OldRequestWrapper(request), request.suggestions);
-
-      if (todo.isEmpty) {
-        sendResults(request, todo.isEmpty);
-      }
-      return todo;
-    });
-  }
-
-  /**
-   * If there is remaining work to be done, then wait for the unit to be
-   * resolved and request that each remaining contributor finish their work.
-   * Return a [Future] that completes when the last notification has been sent.
-   */
-  Future computeFull(DartCompletionRequest request,
-      CompletionPerformance performance, List<DartCompletionContributor> todo) {
-    performance.logStartTime('waitForAnalysis');
-    return waitForAnalysis().then((CompilationUnit unit) {
-      if (controller.isClosed) {
-        return;
-      }
-      performance.logElapseTime('waitForAnalysis');
-      if (unit == null) {
-        sendResults(request, true);
-        return;
-      }
-      performance.logElapseTime('computeFull', () {
-        request.unit = unit;
-        // TODO(paulberry): Do we need to invoke _ReplacementOffsetBuilder
-        // again?
-        request.target = new CompletionTarget.forOffset(unit, request.offset);
-        int count = todo.length;
-        todo.forEach((DartCompletionContributor c) {
-          String name = c.runtimeType.toString();
-          String completeTag = 'computeFull $name complete';
-          performance.logStartTime(completeTag);
-          performance.logElapseTime('computeFull $name', () {
-            c.computeFull(request).then((bool changed) {
-              performance.logElapseTime(completeTag);
-              bool last = --count == 0;
-              if (changed || last) {
-                contributionSorter.sort(
-                    new OldRequestWrapper(request), request.suggestions);
-                sendResults(request, last);
-              }
-            });
-          });
-        });
-      });
-    });
-  }
-
-  @override
-  void computeSuggestions(CompletionRequest completionRequest) {
-    DartCompletionRequest request =
-        new DartCompletionRequest.from(completionRequest, cache);
-    CompletionPerformance performance = new CompletionPerformance();
-    performance.logElapseTime('compute', () {
-      List<DartCompletionContributor> todo = computeFast(request, performance);
-      if (!todo.isEmpty) {
-        computeFull(request, performance, todo);
-      }
-    });
-  }
-
-  /**
-   * Send the current list of suggestions to the client.
-   */
-  void sendResults(DartCompletionRequest request, bool last) {
-    if (controller == null || controller.isClosed) {
-      return;
-    }
-    controller.add(new CompletionResultImpl(request.replacementOffset,
-        request.replacementLength, request.suggestions, last));
-    if (last) {
-      controller.close();
-    }
-  }
-
-  /**
-   * Return a future that either (a) completes with the resolved compilation
-   * unit when analysis is complete, or (b) completes with null if the
-   * compilation unit is never going to be resolved.
-   */
-  Future<CompilationUnit> waitForAnalysis() {
-    List<Source> libraries = context.getLibrariesContaining(source);
-    assert(libraries != null);
-    if (libraries.length == 0) {
-      return new Future.value(null);
-    }
-    Source libSource = libraries[0];
-    assert(libSource != null);
-    return context
-        .computeResolvedCompilationUnitAsync(source, libSource)
-        .catchError((_) {
-      // This source file is not scheduled for analysis, so a resolved
-      // compilation unit is never going to get computed.
-      return null;
-    }, test: (e) => e is AnalysisNotScheduledError);
-  }
-}
-
-/**
- * The context in which the completion is requested.
- */
-class DartCompletionRequest extends CompletionRequestImpl {
-  /**
-   * Cached information from a prior code completion operation.
-   */
-  final DartCompletionCache cache;
-
-  /**
-   * The compilation unit in which the completion was requested. This unit
-   * may or may not be resolved when [DartCompletionContributor.computeFast]
-   * is called but is resolved when [DartCompletionContributor.computeFull].
-   */
-  CompilationUnit unit;
-
-  /**
-   * The completion target.  This determines what part of the parse tree
-   * will receive the newly inserted text.
-   */
-  CompletionTarget target;
-
-  /**
-   * Information about the types of suggestions that should be included.
-   */
-  OpType _optype;
-
-  /**
-   * The offset of the start of the text to be replaced.
-   * This will be different than the offset used to request the completion
-   * suggestions if there was a portion of an identifier before the original
-   * offset. In particular, the replacementOffset will be the offset of the
-   * beginning of said identifier.
-   */
-  int replacementOffset;
-
-  /**
-   * The length of the text to be replaced if the remainder of the identifier
-   * containing the cursor is to be replaced when the suggestion is applied
-   * (that is, the number of characters in the existing identifier).
-   */
-  int replacementLength;
-
-  /**
-   * The list of suggestions to be sent to the client.
-   */
-  final List<CompletionSuggestion> _suggestions = <CompletionSuggestion>[];
-
-  /**
-   * The set of completions used to prevent duplicates
-   */
-  final Set<String> _completions = new Set<String>();
-
-  DartCompletionRequest(AnalysisServer server, AnalysisContext context,
-      Source source, int offset, this.cache)
-      : super(server, context, source, offset);
-
-  factory DartCompletionRequest.from(
-          CompletionRequestImpl request, DartCompletionCache cache) =>
-      new DartCompletionRequest(request.server, request.context, request.source,
-          request.offset, cache);
-
-  /**
-   * Return the original text from the [replacementOffset] to the [offset]
-   * that can be used to filter the suggestions on the server side.
-   */
-  String get filterText {
-    return context
-        .getContents(source)
-        .data
-        .substring(replacementOffset, offset);
-  }
-
-  /**
-   * Information about the types of suggestions that should be included.
-   * The [target] must be set first.
-   */
-  OpType get optype {
-    if (_optype == null) {
-      _optype = new OpType.forCompletion(target, offset);
-    }
-    return _optype;
-  }
-
-  /**
-   * The search engine for use when building suggestions.
-   */
-  SearchEngine get searchEngine => server.searchEngine;
-
-  /**
-   * The list of suggestions to be sent to the client.
-   */
-  Iterable<CompletionSuggestion> get suggestions => _suggestions;
-
-  /**
-   * Add the given suggestion to the list that is returned to the client as long
-   * as a suggestion with an identical completion has not already been added.
-   */
-  void addSuggestion(CompletionSuggestion suggestion) {
-    if (_completions.add(suggestion.completion)) {
-      _suggestions.add(suggestion);
-    }
-  }
-
-  /**
-   * Convert all [CompletionSuggestionKind.INVOCATION] suggestions
-   * to [CompletionSuggestionKind.IDENTIFIER] suggestions.
-   */
-  void convertInvocationsToIdentifiers() {
-    for (int index = _suggestions.length - 1; index >= 0; --index) {
-      CompletionSuggestion suggestion = _suggestions[index];
-      if (suggestion.kind == CompletionSuggestionKind.INVOCATION) {
-        // Create a copy rather than just modifying the existing suggestion
-        // because [DartCompletionCache] may be caching that suggestion
-        // for future completion requests
-        _suggestions[index] = new CompletionSuggestion(
-            CompletionSuggestionKind.IDENTIFIER,
-            suggestion.relevance,
-            suggestion.completion,
-            suggestion.selectionOffset,
-            suggestion.selectionLength,
-            suggestion.isDeprecated,
-            suggestion.isPotential,
-            declaringType: suggestion.declaringType,
-            parameterNames: suggestion.parameterNames,
-            parameterTypes: suggestion.parameterTypes,
-            requiredParameterCount: suggestion.requiredParameterCount,
-            hasNamedParameters: suggestion.hasNamedParameters,
-            returnType: suggestion.returnType,
-            element: suggestion.element);
-      }
-    }
-  }
-}
-
-/**
- * A wrapper around a new dart completion contributor that makes it usable where
- * an old dart completion contributor is expected.
- */
-class NewCompletionWrapper implements DartCompletionContributor {
-  /**
-   * The new-style contributor that is being wrapped.
-   */
-  final newApi.DartCompletionContributor contributor;
-
-  /**
-   * Initialize a newly created wrapper for the given [contributor].
-   */
-  NewCompletionWrapper(this.contributor);
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    List<CompletionSuggestion> suggestions =
-        contributor.computeSuggestions(new OldRequestWrapper(request));
-    if (suggestions == null) {
-      return false;
-    }
-    for (CompletionSuggestion suggestion in suggestions) {
-      request.addSuggestion(suggestion);
-    }
-    return true;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) async {
-    List<CompletionSuggestion> suggestions =
-        contributor.computeSuggestions(new OldRequestWrapper(request));
-    if (suggestions != null) {
-      for (CompletionSuggestion suggestion in suggestions) {
-        request.addSuggestion(suggestion);
-      }
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  String toString() => 'wrapped $contributor';
-}
-
-/**
- * A wrapper around an old dart completion request that makes it usable where a
- * new dart completion request is expected.
- */
-class OldRequestWrapper implements newApi.DartCompletionRequest {
-  final DartCompletionRequest request;
-
-  OldRequestWrapper(this.request);
-
-  @override
-  AnalysisContext get context => request.context;
-
-  @override
-  bool get isResolved => request.unit.element != null;
-
-  @override
-  int get offset => request.offset;
-
-  @override
-  ResourceProvider get resourceProvider => request.resourceProvider;
-
-  @override
-  Source get source => request.source;
-
-  @override
-  CompletionTarget get target => request.target;
-
-  @override
-  CompilationUnit get unit => request.unit;
-
-  @override
-  String toString() => 'wrapped $request';
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
deleted file mode 100644
index b283ce9..0000000
--- a/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
+++ /dev/null
@@ -1,270 +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 services.completion.contributor.dart.toplevel;
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-
-/**
- * A contributor for calculating imported class and top level variable
- * `completion.getSuggestions` request results.
- */
-class ImportedReferenceContributor extends DartCompletionContributor {
-  bool shouldWaitForLowPrioritySuggestions;
-  bool suggestionsComputed;
-  _ImportedSuggestionBuilder builder;
-
-  ImportedReferenceContributor(
-      {this.shouldWaitForLowPrioritySuggestions: false});
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    // Don't suggest in comments.
-    if (request.target.isCommentText) {
-      return true;
-    }
-
-    OpType optype = request.optype;
-    if (!optype.isPrefixed) {
-      if (optype.includeReturnValueSuggestions ||
-          optype.includeTypeNameSuggestions ||
-          optype.includeVoidReturnSuggestions ||
-          optype.includeConstructorSuggestions) {
-        builder = new _ImportedSuggestionBuilder(request, optype);
-        builder.shouldWaitForLowPrioritySuggestions =
-            shouldWaitForLowPrioritySuggestions;
-        // If target is an argument in an argument list
-        // then suggestions may need to be adjusted
-        suggestionsComputed =
-            builder.computeFast(request.target.containingNode);
-        return suggestionsComputed && request.target.argIndex == null;
-      }
-    }
-    return true;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) async {
-    if (builder != null) {
-      if (!suggestionsComputed) {
-        bool result = await builder.computeFull(request.target.containingNode);
-        _updateSuggestions(request);
-        return result;
-      }
-      _updateSuggestions(request);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * If target is a function argument, suggest identifiers not invocations
-   */
-  void _updateSuggestions(DartCompletionRequest request) {
-    if (request.target.isFunctionalArgument()) {
-      request.convertInvocationsToIdentifiers();
-    }
-  }
-}
-
-/**
- * [_ImportedSuggestionBuilder] traverses the imports and builds suggestions
- * based upon imported elements.
- */
-class _ImportedSuggestionBuilder extends ElementSuggestionBuilder
-    implements SuggestionBuilder {
-  bool shouldWaitForLowPrioritySuggestions;
-  final DartCompletionRequest request;
-  final OpType optype;
-  DartCompletionCache cache;
-
-  _ImportedSuggestionBuilder(this.request, this.optype) {
-    cache = request.cache;
-  }
-
-  @override
-  CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
-  /**
-   * If the needed information is cached, then add suggestions and return `true`
-   * else return `false` indicating that additional work is necessary.
-   */
-  bool computeFast(AstNode node) {
-    CompilationUnit unit = request.unit;
-    if (cache.isImportInfoCached(unit)) {
-      _addSuggestions(node);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Compute suggested based upon imported elements.
-   */
-  Future<bool> computeFull(AstNode node) {
-    Future<bool> addSuggestions(_) {
-      _addSuggestions(node);
-      return new Future.value(true);
-    }
-
-    Future future = null;
-    if (!cache.isImportInfoCached(request.unit)) {
-      future = cache.computeImportInfo(request.unit, request.searchEngine,
-          shouldWaitForLowPrioritySuggestions);
-    }
-    if (future != null) {
-      return future.then(addSuggestions);
-    }
-    return addSuggestions(true);
-  }
-
-  /**
-   * Add constructor and library prefix suggestions from the cache.
-   * To reduce the number of suggestions sent to the client,
-   * filter the suggestions based upon the first character typed.
-   * If no characters are available to use for filtering,
-   * then exclude all low priority suggestions.
-   */
-  void _addConstructorSuggestions() {
-    String filterText = request.filterText;
-    if (filterText.length > 1) {
-      filterText = filterText.substring(0, 1);
-    }
-    DartCompletionCache cache = request.cache;
-    _addFilteredSuggestions(filterText, cache.importedConstructorSuggestions);
-    _addFilteredSuggestions(filterText, cache.libraryPrefixSuggestions);
-  }
-
-  /**
-   * Add imported element suggestions.
-   */
-  void _addElementSuggestions(List<Element> elements,
-      {int relevance: DART_RELEVANCE_DEFAULT}) {
-    for (Element elem in elements) {
-      if (elem is! ClassElement) {
-        if (optype.includeOnlyTypeNameSuggestions) {
-          return;
-        }
-        if (elem is ExecutableElement) {
-          DartType returnType = elem.returnType;
-          if (returnType != null && returnType.isVoid) {
-            if (!optype.includeVoidReturnSuggestions) {
-              return;
-            }
-          }
-        }
-      }
-      addSuggestion(elem, relevance: relevance);
-    }
-    ;
-  }
-
-  /**
-   * Add suggestions which start with the given text.
-   */
-  _addFilteredSuggestions(
-      String filterText, List<CompletionSuggestion> unfiltered) {
-    //TODO (danrubel) Revisit this filtering once paged API has been added
-    unfiltered.forEach((CompletionSuggestion suggestion) {
-      if (filterText.length > 0) {
-        if (suggestion.completion.startsWith(filterText)) {
-          request.addSuggestion(suggestion);
-        }
-      } else {
-        if (suggestion.relevance != DART_RELEVANCE_LOW) {
-          request.addSuggestion(suggestion);
-        }
-      }
-    });
-  }
-
-  /**
-   * Add suggestions for any inherited imported members.
-   */
-  void _addInheritedSuggestions(AstNode node) {
-    var classDecl = node.getAncestor((p) => p is ClassDeclaration);
-    if (classDecl is ClassDeclaration && !optype.inStaticMethodBody) {
-      // Build a list of inherited types that are imported
-      // and include any inherited imported members
-      List<String> inheritedTypes = new List<String>();
-      // local declarations are handled by the local reference contributor
-      visitInheritedTypes(classDecl, importedTypeName: (String typeName) {
-        inheritedTypes.add(typeName);
-      });
-      HashSet<String> visited = new HashSet<String>();
-      while (inheritedTypes.length > 0) {
-        String name = inheritedTypes.removeLast();
-        ClassElement elem = cache.importedClassMap[name];
-        if (visited.add(name) && elem != null) {
-          _addElementSuggestions(elem.fields,
-              relevance: DART_RELEVANCE_INHERITED_FIELD);
-          _addElementSuggestions(elem.accessors,
-              relevance: DART_RELEVANCE_INHERITED_ACCESSOR);
-          _addElementSuggestions(elem.methods,
-              relevance: DART_RELEVANCE_INHERITED_METHOD);
-          elem.allSupertypes.forEach((InterfaceType type) {
-            if (visited.add(type.name) && type.element != null) {
-              _addElementSuggestions(type.element.fields,
-                  relevance: DART_RELEVANCE_INHERITED_FIELD);
-              _addElementSuggestions(type.element.accessors,
-                  relevance: DART_RELEVANCE_INHERITED_ACCESSOR);
-              _addElementSuggestions(type.element.methods,
-                  relevance: DART_RELEVANCE_INHERITED_METHOD);
-            }
-          });
-        }
-      }
-    }
-  }
-
-  /**
-   * Add suggested based upon imported elements.
-   */
-  void _addSuggestions(AstNode node) {
-    if (optype.includeConstructorSuggestions) {
-      _addConstructorSuggestions();
-    }
-    if (optype.includeReturnValueSuggestions ||
-        optype.includeTypeNameSuggestions ||
-        optype.includeVoidReturnSuggestions) {
-      _addInheritedSuggestions(node);
-      _addTopLevelSuggestions();
-    }
-  }
-
-  /**
-   * Add top level suggestions from the cache.
-   * To reduce the number of suggestions sent to the client,
-   * filter the suggestions based upon the first character typed.
-   * If no characters are available to use for filtering,
-   * then exclude all low priority suggestions.
-   */
-  void _addTopLevelSuggestions() {
-    String filterText = request.filterText;
-    if (filterText.length > 1) {
-      filterText = filterText.substring(0, 1);
-    }
-    DartCompletionCache cache = request.cache;
-    if (optype.includeTypeNameSuggestions) {
-      _addFilteredSuggestions(filterText, cache.importedTypeSuggestions);
-      _addFilteredSuggestions(filterText, cache.libraryPrefixSuggestions);
-    }
-    if (optype.includeReturnValueSuggestions) {
-      _addFilteredSuggestions(filterText, cache.otherImportedSuggestions);
-    }
-    if (optype.includeVoidReturnSuggestions) {
-      _addFilteredSuggestions(filterText, cache.importedVoidReturnSuggestions);
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/inherited_contributor.dart b/pkg/analysis_server/lib/src/services/completion/inherited_contributor.dart
deleted file mode 100644
index 451da53..0000000
--- a/pkg/analysis_server/lib/src/services/completion/inherited_contributor.dart
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.completion.computer.dart.invocation;
-
-import 'package:analysis_server/plugin/edit/utilities/change_builder_dart.dart';
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind, SourceChange;
-import 'package:analysis_server/src/protocol_server.dart' as protocol
-    hide CompletionSuggestion, CompletionSuggestionKind;
-import 'package:analysis_server/src/provisional/completion/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart'
-    show DART_RELEVANCE_HIGH;
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * A completion contributor used to suggest replacing partial identifiers inside
- * a class declaration with templates for inherited members.
- */
-class InheritedContributor extends DartCompletionContributor {
-  @override
-  List<CompletionSuggestion> internalComputeSuggestions(
-      DartCompletionRequest request) {
-    if (!request.isResolved) {
-      return null;
-    }
-    AstNode node = new NodeLocator(request.offset).searchWithin(request.unit);
-    if (node == null || !_isMemberLevelIdentifier(node)) {
-      return null;
-    }
-    ClassDeclaration classDeclaration =
-        node.getAncestor((AstNode node) => node is ClassDeclaration);
-    if (classDeclaration != null) {
-      ClassElement element = classDeclaration.element;
-      if (element == null) {
-        return null;
-      }
-      return _suggestInheritedMembers(request, node, element);
-    }
-    return null;
-  }
-
-  /**
-   * Return a template for an override of the given [element] in the given
-   * [source]. If selected, the template will replace the given [identifier].
-   */
-  String _buildRepacementText(
-      Source source, SimpleIdentifier identifier, Element element) {
-    AnalysisContext context = element.context;
-    DartChangeBuilder builder = new DartChangeBuilder(context);
-    builder.addFileEdit(source, context.getModificationStamp(source),
-        (DartFileEditBuilder builder) {
-      builder.addReplacement(identifier.offset, identifier.length,
-          (DartEditBuilder builder) {
-        builder.writeOverrideOfInheritedMember(element);
-      });
-    });
-    return builder.sourceChange.edits[0].edits[0].replacement.trim();
-  }
-
-  /**
-   * Build a suggestion to replace the partial [identifier] in the given
-   * [source] with an override of the given [element].
-   */
-  CompletionSuggestion _buildSuggestion(
-      Source source, SimpleIdentifier identifier, Element element) {
-    String completion = _buildRepacementText(source, identifier, element);
-    CompletionSuggestion suggestion = new CompletionSuggestion(
-        CompletionSuggestionKind.IDENTIFIER,
-        DART_RELEVANCE_HIGH,
-        completion,
-        identifier.offset,
-        0,
-        element.isDeprecated,
-        false);
-    suggestion.element = protocol.convertElement(element);
-    return suggestion;
-  }
-
-  /**
-   * Return a list containing the names of all of the inherited by not
-   * implemented members of the class represented by the given [element] that
-   * start with the given [prefix]. The [map] is used to find all of the members
-   * that are inherited.
-   */
-  List<String> _computeMemberNames(
-      MemberMap map, ClassElement element, String prefix) {
-    List<String> memberNames = <String>[];
-    int count = map.size;
-    for (int i = 0; i < count; i++) {
-      String memberName = map.getKey(i);
-      if (memberName.startsWith(prefix) && !_hasMember(element, memberName)) {
-        memberNames.add(memberName);
-      }
-    }
-    return memberNames;
-  }
-
-  /**
-   * Return `true` if the given [classElement] directly declares a member with
-   * the given [memberName].
-   */
-  bool _hasMember(ClassElement classElement, String memberName) {
-    return classElement.getField(memberName) != null ||
-        classElement.getGetter(memberName) != null ||
-        classElement.getMethod(memberName) != null ||
-        classElement.getSetter(memberName) != null;
-  }
-
-  /**
-   * Return `true` if the given [node] looks like a partial identifier inside a
-   * class declaration.
-   */
-  bool _isMemberLevelIdentifier(AstNode node) {
-    if (node is SimpleIdentifier) {
-      AstNode parent1 = node.parent;
-      if (parent1 is TypeName) {
-        AstNode parent2 = parent1.parent;
-        if (parent2 is VariableDeclarationList) {
-          AstNode parent3 = parent2.parent;
-          if (parent3 is FieldDeclaration) {
-            NodeList<VariableDeclaration> variables = parent2.variables;
-            return variables.length == 1 && variables[0].name.name.isEmpty;
-          }
-        }
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Add any suggestions that are appropriate to the given [request], using the
-   * given [element] to find inherited members whose name has the given
-   * [identifier] as a prefix.
-   */
-  List<CompletionSuggestion> _suggestInheritedMembers(
-      DartCompletionRequest request,
-      SimpleIdentifier identifier,
-      ClassElement element) {
-    String name = identifier.name;
-    InheritanceManager manager = new InheritanceManager(element.library);
-    MemberMap map = manager.getMapOfMembersInheritedFromInterfaces(element);
-    List<String> memberNames = _computeMemberNames(map, element, name);
-    memberNames.sort();
-    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
-    for (String memberName in memberNames) {
-      CompletionSuggestion suggestion =
-          _buildSuggestion(request.source, identifier, map.get(memberName));
-      if (suggestion != null) {
-        suggestions.add(suggestion);
-      }
-    }
-    return suggestions;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/keyword_contributor.dart
deleted file mode 100644
index 0da2c8c..0000000
--- a/pkg/analysis_server/lib/src/services/completion/keyword_contributor.dart
+++ /dev/null
@@ -1,525 +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 services.completion.contributor.dart.keyword;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-
-const ASYNC = 'async';
-const AWAIT = 'await';
-
-/**
- * A contributor for calculating `completion.getSuggestions` request results
- * for the local library in which the completion is requested.
- */
-class KeywordContributor extends DartCompletionContributor {
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    if (!request.target.isCommentText) {
-      request.target.containingNode.accept(new _KeywordVisitor(request));
-    }
-    return true;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    return new Future.value(false);
-  }
-}
-
-/**
- * A visitor for generating keyword suggestions.
- */
-class _KeywordVisitor extends GeneralizingAstVisitor {
-  final DartCompletionRequest request;
-  final Object entity;
-
-  _KeywordVisitor(DartCompletionRequest request)
-      : this.request = request,
-        this.entity = request.target.entity;
-
-  @override
-  visitArgumentList(ArgumentList node) {
-    if (entity == node.rightParenthesis ||
-        (entity is SimpleIdentifier && node.arguments.contains(entity))) {
-      _addExpressionKeywords(node);
-    }
-  }
-
-  @override
-  visitBlock(Block node) {
-    if (entity is ExpressionStatement) {
-      Expression expression = (entity as ExpressionStatement).expression;
-      if (expression is SimpleIdentifier) {
-        Token token = expression.token;
-        Token previous = token.previous;
-        if (previous.isSynthetic) {
-          previous = previous.previous;
-        }
-        Token next = token.next;
-        if (next.isSynthetic) {
-          next = next.next;
-        }
-        if (previous.lexeme == ')' && next.lexeme == '{') {
-          _addSuggestion2(ASYNC);
-        }
-      }
-    }
-    _addStatementKeywords(node);
-    if (_inCatchClause(node)) {
-      _addSuggestion(Keyword.RETHROW, DART_RELEVANCE_KEYWORD - 1);
-    }
-  }
-
-  @override
-  visitClassDeclaration(ClassDeclaration node) {
-    // Don't suggest class name
-    if (entity == node.name) {
-      return;
-    }
-    if (entity == node.rightBracket) {
-      _addClassBodyKeywords();
-    } else if (entity is ClassMember) {
-      _addClassBodyKeywords();
-      int index = node.members.indexOf(entity);
-      ClassMember previous = index > 0 ? node.members[index - 1] : null;
-      if (previous is MethodDeclaration && previous.body is EmptyFunctionBody) {
-        _addSuggestion2(ASYNC);
-      }
-    } else {
-      _addClassDeclarationKeywords(node);
-    }
-  }
-
-  @override
-  visitCompilationUnit(CompilationUnit node) {
-    var previousMember = null;
-    for (var member in node.childEntities) {
-      if (entity == member) {
-        break;
-      }
-      previousMember = member;
-    }
-    if (previousMember is ClassDeclaration) {
-      if (previousMember.leftBracket == null ||
-          previousMember.leftBracket.isSynthetic) {
-        // If the prior member is an unfinished class declaration
-        // then the user is probably finishing that
-        _addClassDeclarationKeywords(previousMember);
-        return;
-      }
-    }
-    if (previousMember is ImportDirective) {
-      if (previousMember.semicolon == null ||
-          previousMember.semicolon.isSynthetic) {
-        // If the prior member is an unfinished import directive
-        // then the user is probably finishing that
-        _addImportDirectiveKeywords(previousMember);
-        return;
-      }
-    }
-    if (previousMember == null || previousMember is Directive) {
-      if (previousMember == null &&
-          !node.directives.any((d) => d is LibraryDirective)) {
-        _addSuggestions([Keyword.LIBRARY], DART_RELEVANCE_HIGH);
-      }
-      _addSuggestions(
-          [Keyword.IMPORT, Keyword.EXPORT, Keyword.PART], DART_RELEVANCE_HIGH);
-    }
-    if (entity == null || entity is Declaration) {
-      if (previousMember is FunctionDeclaration &&
-          previousMember.functionExpression is FunctionExpression &&
-          previousMember.functionExpression.body is EmptyFunctionBody) {
-        _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
-      }
-      _addCompilationUnitKeywords();
-    }
-  }
-
-  @override
-  visitExpression(Expression node) {
-    _addExpressionKeywords(node);
-  }
-
-  @override
-  visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    if (entity == node.expression) {
-      _addExpressionKeywords(node);
-    }
-  }
-
-  @override
-  visitForEachStatement(ForEachStatement node) {
-    if (entity == node.inKeyword) {
-      Token previous = node.inKeyword.previous;
-      if (previous is SyntheticStringToken && previous.lexeme == 'in') {
-        previous = previous.previous;
-      }
-      if (previous != null && previous.type == TokenType.EQ) {
-        _addSuggestions([
-          Keyword.CONST,
-          Keyword.FALSE,
-          Keyword.NEW,
-          Keyword.NULL,
-          Keyword.TRUE
-        ]);
-      } else {
-        _addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH);
-      }
-    }
-  }
-
-  @override
-  visitFormalParameterList(FormalParameterList node) {
-    AstNode constructorDeclaration =
-        node.getAncestor((p) => p is ConstructorDeclaration);
-    if (constructorDeclaration != null) {
-      _addSuggestions([Keyword.THIS]);
-    }
-  }
-
-  @override
-  visitForStatement(ForStatement node) {
-    // Handle the degenerate case while typing - for (int x i^)
-    if (node.condition == entity && entity is SimpleIdentifier) {
-      Token entityToken = (entity as SimpleIdentifier).beginToken;
-      if (entityToken.previous.isSynthetic &&
-          entityToken.previous.type == TokenType.SEMICOLON) {
-        _addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH);
-      }
-    }
-  }
-
-  @override
-  visitFunctionExpression(FunctionExpression node) {
-    if (entity == node.body) {
-      if (!node.body.isAsynchronous) {
-        _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
-      }
-      if (node.body is EmptyFunctionBody &&
-          node.parent is FunctionDeclaration &&
-          node.parent.parent is CompilationUnit) {
-        _addCompilationUnitKeywords();
-      }
-    }
-  }
-
-  @override
-  visitIfStatement(IfStatement node) {
-    if (entity == node.thenStatement) {
-      _addStatementKeywords(node);
-    } else if (entity == node.condition) {
-      _addExpressionKeywords(node);
-    }
-  }
-
-  @override
-  visitImportDirective(ImportDirective node) {
-    if (entity == node.asKeyword) {
-      if (node.deferredKeyword == null) {
-        _addSuggestion(Keyword.DEFERRED, DART_RELEVANCE_HIGH);
-      }
-    }
-    // Handle degenerate case where import statement does not have a semicolon
-    // and the cursor is in the uri string
-    if ((entity == node.semicolon &&
-            node.uri != null &&
-            node.uri.offset + 1 != request.offset) ||
-        node.combinators.contains(entity)) {
-      _addImportDirectiveKeywords(node);
-    }
-  }
-
-  @override
-  visitInstanceCreationExpression(InstanceCreationExpression node) {
-    if (entity == node.constructorName) {
-      // no keywords in 'new ^' expression
-    } else {
-      super.visitInstanceCreationExpression(node);
-    }
-  }
-
-  @override
-  visitIsExpression(IsExpression node) {
-    if (entity == node.isOperator) {
-      _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH);
-    } else {
-      _addExpressionKeywords(node);
-    }
-  }
-
-  @override
-  visitLibraryIdentifier(LibraryIdentifier node) {
-    // no suggestions
-  }
-
-  @override
-  visitMethodDeclaration(MethodDeclaration node) {
-    if (entity == node.body) {
-      if (node.body is EmptyFunctionBody) {
-        _addClassBodyKeywords();
-        _addSuggestion2(ASYNC);
-      } else {
-        _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
-      }
-    }
-  }
-
-  @override
-  visitMethodInvocation(MethodInvocation node) {
-    if (entity == node.methodName) {
-      // no keywords in '.' expression
-    } else {
-      super.visitMethodInvocation(node);
-    }
-  }
-
-  @override
-  visitNamedExpression(NamedExpression node) {
-    if (entity is SimpleIdentifier && entity == node.expression) {
-      _addExpressionKeywords(node);
-    }
-  }
-
-  @override
-  visitNode(AstNode node) {
-    // ignored
-  }
-
-  @override
-  visitPrefixedIdentifier(PrefixedIdentifier node) {
-    if (entity != node.identifier) {
-      _addExpressionKeywords(node);
-    }
-  }
-
-  @override
-  visitPropertyAccess(PropertyAccess node) {
-    // suggestions before '.' but not after
-    if (entity != node.propertyName) {
-      super.visitPropertyAccess(node);
-    }
-  }
-
-  @override
-  visitReturnStatement(ReturnStatement node) {
-    if (entity == node.expression) {
-      _addExpressionKeywords(node);
-    }
-  }
-
-  @override
-  visitStringLiteral(StringLiteral node) {
-    // ignored
-  }
-
-  @override
-  visitSwitchStatement(SwitchStatement node) {
-    if (entity == node.expression) {
-      _addExpressionKeywords(node);
-    } else if (entity == node.rightBracket) {
-      if (node.members.isEmpty) {
-        _addSuggestions([Keyword.CASE, Keyword.DEFAULT], DART_RELEVANCE_HIGH);
-      } else {
-        _addSuggestions([Keyword.CASE, Keyword.DEFAULT]);
-        _addStatementKeywords(node);
-      }
-    }
-    if (node.members.contains(entity)) {
-      if (entity == node.members.first) {
-        _addSuggestions([Keyword.CASE, Keyword.DEFAULT], DART_RELEVANCE_HIGH);
-      } else {
-        _addSuggestions([Keyword.CASE, Keyword.DEFAULT]);
-        _addStatementKeywords(node);
-      }
-    }
-  }
-
-  @override
-  visitVariableDeclaration(VariableDeclaration node) {
-    if (entity == node.initializer) {
-      _addExpressionKeywords(node);
-    }
-  }
-
-  void _addClassBodyKeywords() {
-    _addSuggestions([
-      Keyword.CONST,
-      Keyword.DYNAMIC,
-      Keyword.FACTORY,
-      Keyword.FINAL,
-      Keyword.GET,
-      Keyword.OPERATOR,
-      Keyword.SET,
-      Keyword.STATIC,
-      Keyword.VAR,
-      Keyword.VOID
-    ]);
-  }
-
-  void _addClassDeclarationKeywords(ClassDeclaration node) {
-    // Very simplistic suggestion because analyzer will warn if
-    // the extends / with / implements keywords are out of order
-    if (node.extendsClause == null) {
-      _addSuggestion(Keyword.EXTENDS, DART_RELEVANCE_HIGH);
-    } else if (node.withClause == null) {
-      _addSuggestion(Keyword.WITH, DART_RELEVANCE_HIGH);
-    }
-    if (node.implementsClause == null) {
-      _addSuggestion(Keyword.IMPLEMENTS, DART_RELEVANCE_HIGH);
-    }
-  }
-
-  void _addCompilationUnitKeywords() {
-    _addSuggestions([
-      Keyword.ABSTRACT,
-      Keyword.CLASS,
-      Keyword.CONST,
-      Keyword.DYNAMIC,
-      Keyword.FINAL,
-      Keyword.TYPEDEF,
-      Keyword.VAR,
-      Keyword.VOID
-    ], DART_RELEVANCE_HIGH);
-  }
-
-  void _addExpressionKeywords(AstNode node) {
-    _addSuggestions([
-      Keyword.CONST,
-      Keyword.FALSE,
-      Keyword.NEW,
-      Keyword.NULL,
-      Keyword.TRUE,
-    ]);
-    if (_inClassMemberBody(node)) {
-      _addSuggestions([Keyword.SUPER, Keyword.THIS,]);
-    }
-    if (_inAsyncMethodOrFunction(node)) {
-      _addSuggestion2(AWAIT);
-    }
-  }
-
-  void _addImportDirectiveKeywords(ImportDirective node) {
-    bool hasDeferredKeyword = node.deferredKeyword != null;
-    bool hasAsKeyword = node.asKeyword != null;
-    if (!hasAsKeyword) {
-      _addSuggestion(Keyword.AS, DART_RELEVANCE_HIGH);
-    }
-    if (!hasDeferredKeyword) {
-      if (!hasAsKeyword) {
-        _addSuggestion2('deferred as', relevance: DART_RELEVANCE_HIGH);
-      } else if (entity == node.asKeyword) {
-        _addSuggestion(Keyword.DEFERRED, DART_RELEVANCE_HIGH);
-      }
-    }
-    if (!hasDeferredKeyword || hasAsKeyword) {
-      if (node.combinators.isEmpty) {
-        _addSuggestion2('show', relevance: DART_RELEVANCE_HIGH);
-        _addSuggestion2('hide', relevance: DART_RELEVANCE_HIGH);
-      }
-    }
-  }
-
-  void _addStatementKeywords(AstNode node) {
-    if (_inClassMemberBody(node)) {
-      _addSuggestions([Keyword.SUPER, Keyword.THIS,]);
-    }
-    if (_inAsyncMethodOrFunction(node)) {
-      _addSuggestion2(AWAIT);
-    }
-    if (_inLoop(node)) {
-      _addSuggestions([Keyword.BREAK, Keyword.CONTINUE]);
-    }
-    if (_inSwitch(node)) {
-      _addSuggestions([Keyword.BREAK]);
-    }
-    _addSuggestions([
-      Keyword.ASSERT,
-      Keyword.CONST,
-      Keyword.DO,
-      Keyword.FINAL,
-      Keyword.FOR,
-      Keyword.IF,
-      Keyword.NEW,
-      Keyword.RETURN,
-      Keyword.SWITCH,
-      Keyword.THROW,
-      Keyword.TRY,
-      Keyword.VAR,
-      Keyword.VOID,
-      Keyword.WHILE
-    ]);
-  }
-
-  void _addSuggestion(Keyword keyword,
-      [int relevance = DART_RELEVANCE_KEYWORD]) {
-    _addSuggestion2(keyword.syntax, relevance: relevance);
-  }
-
-  void _addSuggestion2(String completion,
-      {int offset, int relevance: DART_RELEVANCE_KEYWORD}) {
-    if (offset == null) {
-      offset = completion.length;
-    }
-    request.addSuggestion(new CompletionSuggestion(
-        CompletionSuggestionKind.KEYWORD,
-        relevance,
-        completion,
-        offset,
-        0,
-        false,
-        false));
-  }
-
-  void _addSuggestions(List<Keyword> keywords,
-      [int relevance = DART_RELEVANCE_KEYWORD]) {
-    keywords.forEach((Keyword keyword) {
-      _addSuggestion(keyword, relevance);
-    });
-  }
-
-  bool _inAsyncMethodOrFunction(AstNode node) {
-    FunctionBody body = node.getAncestor((n) => n is FunctionBody);
-    return body != null && body.isAsynchronous;
-  }
-
-  bool _inCatchClause(Block node) =>
-      node.getAncestor((p) => p is CatchClause) != null;
-
-  bool _inClassMemberBody(AstNode node) {
-    while (true) {
-      AstNode body = node.getAncestor((n) => n is FunctionBody);
-      if (body == null) {
-        return false;
-      }
-      AstNode parent = body.parent;
-      if (parent is ConstructorDeclaration || parent is MethodDeclaration) {
-        return true;
-      }
-      node = parent;
-    }
-  }
-
-  bool _inDoLoop(AstNode node) =>
-      node.getAncestor((p) => p is DoStatement) != null;
-
-  bool _inForLoop(AstNode node) =>
-      node.getAncestor((p) => p is ForStatement || p is ForEachStatement) !=
-          null;
-
-  bool _inLoop(AstNode node) =>
-      _inDoLoop(node) || _inForLoop(node) || _inWhileLoop(node);
-
-  bool _inSwitch(AstNode node) =>
-      node.getAncestor((p) => p is SwitchStatement) != null;
-
-  bool _inWhileLoop(AstNode node) =>
-      node.getAncestor((p) => p is WhileStatement) != null;
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart b/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart
deleted file mode 100644
index 360774a..0000000
--- a/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart
+++ /dev/null
@@ -1,282 +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 services.completion.dart.local.declaration.visitor;
-
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-
-/**
- * `LocalDeclarationCollector` visits an [AstNode] and its parent recursively
- * along with any declarations in those nodes. Consumers typically call [visit]
- * which catches the exception thrown by [finished()].
- */
-abstract class LocalDeclarationVisitor extends GeneralizingAstVisitor {
-  static final TypeName STACKTRACE_TYPE = new TypeName(
-      new SimpleIdentifier(
-          new StringToken(TokenType.IDENTIFIER, 'StackTrace', 0)),
-      null);
-
-  final int offset;
-
-  /**
-   * `true` if local inherited types should be visited.
-   */
-  bool includeLocalInheritedTypes = true;
-
-  LocalDeclarationVisitor(this.offset);
-
-  void declaredClass(ClassDeclaration declaration);
-
-  void declaredClassTypeAlias(ClassTypeAlias declaration);
-
-  void declaredEnum(EnumDeclaration declaration) {}
-
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl);
-
-  void declaredFunction(FunctionDeclaration declaration);
-
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration);
-
-  void declaredLabel(Label label, bool isCaseLabel);
-
-  void declaredLocalVar(SimpleIdentifier name, TypeName type);
-
-  void declaredMethod(MethodDeclaration declaration);
-
-  void declaredParam(SimpleIdentifier name, TypeName type);
-
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl);
-
-  /**
-   * Throw an exception indicating that [LocalDeclarationVisitor] should
-   * stop visiting. This is caught in [visit] which then exits normally.
-   */
-  void finished() {
-    throw new _LocalDeclarationVisitorFinished();
-  }
-
-  /**
-   * Visit the given [AstNode] and its parent recursively along with any
-   * declarations in those nodes. Return `true` if [finished] is called
-   * while visiting, else `false`.
-   */
-  bool visit(AstNode node) {
-    try {
-      node.accept(this);
-      return false;
-    } on _LocalDeclarationVisitorFinished {
-      return true;
-    }
-  }
-
-  @override
-  void visitBlock(Block node) {
-    for (Statement stmt in node.statements) {
-      if (stmt.offset < offset) {
-        if (stmt is VariableDeclarationStatement) {
-          VariableDeclarationList varList = stmt.variables;
-          if (varList != null) {
-            for (VariableDeclaration varDecl in varList.variables) {
-              if (varDecl.end < offset) {
-                declaredLocalVar(varDecl.name, varList.type);
-              }
-            }
-          }
-        } else if (stmt is FunctionDeclarationStatement) {
-          FunctionDeclaration declaration = stmt.functionDeclaration;
-          if (declaration != null && declaration.offset < offset) {
-            SimpleIdentifier id = declaration.name;
-            if (id != null) {
-              String name = id.name;
-              if (name != null && name.length > 0) {
-                declaredFunction(declaration);
-              }
-            }
-          }
-        }
-      }
-    }
-    visitNode(node);
-  }
-
-  @override
-  void visitCatchClause(CatchClause node) {
-    SimpleIdentifier param = node.exceptionParameter;
-    if (param != null) {
-      declaredParam(param, node.exceptionType);
-    }
-    param = node.stackTraceParameter;
-    if (param != null) {
-      declaredParam(param, STACKTRACE_TYPE);
-    }
-    visitNode(node);
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    _visitClassDeclarationMembers(node);
-    // imported types are handled by the imported reference contributor
-    if (includeLocalInheritedTypes) {
-      visitInheritedTypes(node, localDeclaration: (ClassDeclaration classNode) {
-        _visitClassDeclarationMembers(classNode);
-      });
-    }
-    visitNode(node);
-  }
-
-  @override
-  void visitCompilationUnit(CompilationUnit node) {
-    node.declarations.forEach((Declaration declaration) {
-      if (declaration is ClassDeclaration) {
-        declaredClass(declaration);
-      } else if (declaration is EnumDeclaration) {
-        declaredEnum(declaration);
-      } else if (declaration is FunctionDeclaration) {
-        declaredFunction(declaration);
-      } else if (declaration is TopLevelVariableDeclaration) {
-        var varList = declaration.variables;
-        if (varList != null) {
-          varList.variables.forEach((VariableDeclaration varDecl) {
-            declaredTopLevelVar(varList, varDecl);
-          });
-        }
-      } else if (declaration is ClassTypeAlias) {
-        declaredClassTypeAlias(declaration);
-      } else if (declaration is FunctionTypeAlias) {
-        declaredFunctionTypeAlias(declaration);
-      }
-    });
-  }
-
-  @override
-  visitConstructorDeclaration(ConstructorDeclaration node) {
-    _visitParamList(node.parameters);
-    visitNode(node);
-  }
-
-  @override
-  void visitForEachStatement(ForEachStatement node) {
-    SimpleIdentifier id;
-    TypeName type;
-    DeclaredIdentifier loopVar = node.loopVariable;
-    if (loopVar != null) {
-      id = loopVar.identifier;
-      type = loopVar.type;
-    } else {
-      id = node.identifier;
-      type = null;
-    }
-    if (id != null) {
-      // If there is no loop variable, don't declare it.
-      declaredLocalVar(id, type);
-    }
-    visitNode(node);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    VariableDeclarationList varList = node.variables;
-    if (varList != null) {
-      varList.variables.forEach((VariableDeclaration varDecl) {
-        declaredLocalVar(varDecl.name, varList.type);
-      });
-    }
-    visitNode(node);
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    // declaredFunction is called by the compilation unit containing it
-    visitNode(node);
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    _visitParamList(node.parameters);
-    visitNode(node);
-  }
-
-  @override
-  void visitInterpolationExpression(InterpolationExpression node) {
-    visitNode(node);
-  }
-
-  @override
-  void visitLabeledStatement(LabeledStatement node) {
-    for (Label label in node.labels) {
-      declaredLabel(label, false);
-    }
-    visitNode(node);
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    _visitParamList(node.parameters);
-    visitNode(node);
-  }
-
-  @override
-  void visitNode(AstNode node) {
-    node.parent.accept(this);
-  }
-
-  @override
-  void visitStringInterpolation(StringInterpolation node) {
-    visitNode(node);
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    for (SwitchMember member in node.members) {
-      for (Label label in member.labels) {
-        declaredLabel(label, true);
-      }
-    }
-    visitNode(node);
-  }
-
-  void _visitClassDeclarationMembers(ClassDeclaration node) {
-    for (ClassMember member in node.members) {
-      if (member is FieldDeclaration) {
-        member.fields.variables.forEach((VariableDeclaration varDecl) {
-          declaredField(member, varDecl);
-        });
-      } else if (member is MethodDeclaration) {
-        declaredMethod(member);
-      }
-    }
-  }
-
-  void _visitParamList(FormalParameterList paramList) {
-    if (paramList != null) {
-      paramList.parameters.forEach((FormalParameter param) {
-        NormalFormalParameter normalParam;
-        if (param is DefaultFormalParameter) {
-          normalParam = param.parameter;
-        } else if (param is NormalFormalParameter) {
-          normalParam = param;
-        }
-        TypeName type = null;
-        if (normalParam is FieldFormalParameter) {
-          type = normalParam.type;
-        } else if (normalParam is FunctionTypedFormalParameter) {
-          type = normalParam.returnType;
-        } else if (normalParam is SimpleFormalParameter) {
-          type = normalParam.type;
-        }
-        SimpleIdentifier name = param.identifier;
-        declaredParam(name, type);
-      });
-    }
-  }
-}
-
-/**
- * Internal exception used to indicate that [LocalDeclarationVisitor]
- * should stop visiting.
- */
-class _LocalDeclarationVisitorFinished {}
diff --git a/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart
deleted file mode 100644
index 6753a40..0000000
--- a/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart
+++ /dev/null
@@ -1,601 +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 services.completion.contributor.dart.local;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
-import 'package:analysis_server/src/services/completion/local_suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-
-/**
- * A contributor for calculating `completion.getSuggestions` request results
- * for the local library in which the completion is requested.
- */
-class LocalReferenceContributor extends DartCompletionContributor {
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    // Don't suggest in comments.
-    if (request.target.isCommentText) {
-      return true;
-    }
-
-    OpType optype = request.optype;
-
-    // Collect suggestions from the specific child [AstNode] that contains
-    // the completion offset and all of its parents recursively.
-    if (!optype.isPrefixed) {
-      if (optype.includeReturnValueSuggestions ||
-          optype.includeTypeNameSuggestions ||
-          optype.includeVoidReturnSuggestions) {
-        _LocalVisitor localVisitor =
-            new _LocalVisitor(request, request.offset, optype);
-        localVisitor.visit(request.target.containingNode);
-      }
-      if (optype.includeStatementLabelSuggestions ||
-          optype.includeCaseLabelSuggestions) {
-        _LabelVisitor labelVisitor = new _LabelVisitor(
-            request,
-            optype.includeStatementLabelSuggestions,
-            optype.includeCaseLabelSuggestions);
-        labelVisitor.visit(request.target.containingNode);
-      }
-      if (optype.includeConstructorSuggestions) {
-        new _ConstructorVisitor(request).visit(request.target.containingNode);
-      }
-    }
-
-    // If target is an argument in an argument list
-    // then suggestions may need to be adjusted
-    return request.target.argIndex == null;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    _updateSuggestions(request);
-    return new Future.value(false);
-  }
-
-  /**
-   * If target is a function argument, suggest identifiers not invocations
-   */
-  void _updateSuggestions(DartCompletionRequest request) {
-    if (request.target.isFunctionalArgument()) {
-      request.convertInvocationsToIdentifiers();
-    }
-  }
-}
-
-/**
- * A visitor for collecting constructor suggestions.
- */
-class _ConstructorVisitor extends LocalDeclarationVisitor {
-  final DartCompletionRequest request;
-
-  _ConstructorVisitor(DartCompletionRequest request)
-      : super(request.offset),
-        request = request;
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {
-    bool found = false;
-    for (ClassMember member in declaration.members) {
-      if (member is ConstructorDeclaration) {
-        found = true;
-        _addSuggestion(declaration, member);
-      }
-    }
-    if (!found) {
-      _addSuggestion(declaration, null);
-    }
-  }
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {}
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {}
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {}
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {}
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {}
-
-  @override
-  void declaredLocalVar(SimpleIdentifier name, TypeName type) {}
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {}
-
-  @override
-  void declaredParam(SimpleIdentifier name, TypeName type) {}
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {}
-
-  /**
-   * For the given class and constructor,
-   * add a suggestion of the form B(...) or B.name(...).
-   * If the given constructor is `null`
-   * then add a default constructor suggestion.
-   */
-  CompletionSuggestion _addSuggestion(
-      ClassDeclaration classDecl, ConstructorDeclaration constructorDecl) {
-    SimpleIdentifier elemId;
-    String completion = classDecl.name.name;
-    if (constructorDecl != null) {
-      elemId = constructorDecl.name;
-      if (elemId != null) {
-        String name = elemId.name;
-        if (name != null && name.length > 0) {
-          completion = '$completion.$name';
-        }
-      }
-    }
-    bool deprecated = constructorDecl != null && isDeprecated(constructorDecl);
-    List<String> parameterNames = new List<String>();
-    List<String> parameterTypes = new List<String>();
-    int requiredParameterCount = 0;
-    bool hasNamedParameters = false;
-    StringBuffer paramBuf = new StringBuffer();
-    paramBuf.write('(');
-    int paramCount = 0;
-    if (constructorDecl != null) {
-      for (FormalParameter param in constructorDecl.parameters.parameters) {
-        if (paramCount > 0) {
-          paramBuf.write(', ');
-        }
-        String paramName;
-        String typeName;
-        if (param is NormalFormalParameter) {
-          paramName = param.identifier.name;
-          typeName = _nameForParamType(param);
-          ++requiredParameterCount;
-        } else if (param is DefaultFormalParameter) {
-          NormalFormalParameter childParam = param.parameter;
-          paramName = childParam.identifier.name;
-          typeName = _nameForParamType(childParam);
-          if (param.kind == ParameterKind.NAMED) {
-            hasNamedParameters = true;
-          }
-          if (paramCount == requiredParameterCount) {
-            paramBuf.write(hasNamedParameters ? '{' : '[');
-          }
-        }
-        parameterNames.add(paramName);
-        parameterTypes.add(typeName);
-        paramBuf.write(typeName);
-        paramBuf.write(' ');
-        paramBuf.write(paramName);
-        ++paramCount;
-      }
-    }
-    if (paramCount > requiredParameterCount) {
-      paramBuf.write(hasNamedParameters ? '}' : ']');
-    }
-    paramBuf.write(')');
-    protocol.Element element = createElement(
-        request.source, protocol.ElementKind.CONSTRUCTOR, elemId,
-        parameters: paramBuf.toString());
-    element.returnType = classDecl.name.name;
-    CompletionSuggestion suggestion = new CompletionSuggestion(
-        CompletionSuggestionKind.INVOCATION,
-        deprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT,
-        completion,
-        completion.length,
-        0,
-        deprecated,
-        false,
-        declaringType: classDecl.name.name,
-        element: element,
-        parameterNames: parameterNames,
-        parameterTypes: parameterTypes,
-        requiredParameterCount: requiredParameterCount,
-        hasNamedParameters: hasNamedParameters);
-    request.addSuggestion(suggestion);
-    return suggestion;
-  }
-
-  /**
-   * Determine the name of the type for the given constructor parameter.
-   */
-  String _nameForParamType(NormalFormalParameter param) {
-    if (param is SimpleFormalParameter) {
-      return nameForType(param.type);
-    }
-    SimpleIdentifier id = param.identifier;
-    if (param is FieldFormalParameter && id != null) {
-      String fieldName = id.name;
-      AstNode classDecl = param.getAncestor((p) => p is ClassDeclaration);
-      if (classDecl is ClassDeclaration) {
-        for (ClassMember member in classDecl.members) {
-          if (member is FieldDeclaration) {
-            for (VariableDeclaration field in member.fields.variables) {
-              if (field.name.name == fieldName) {
-                return nameForType(member.fields.type);
-              }
-            }
-          }
-        }
-      }
-    }
-    return DYNAMIC;
-  }
-}
-
-/**
- * A visitor for collecting suggestions for break and continue labels.
- */
-class _LabelVisitor extends LocalDeclarationVisitor {
-  final DartCompletionRequest request;
-
-  /**
-   * True if statement labels should be included as suggestions.
-   */
-  final bool includeStatementLabels;
-
-  /**
-   * True if case labels should be included as suggestions.
-   */
-  final bool includeCaseLabels;
-
-  _LabelVisitor(DartCompletionRequest request, this.includeStatementLabels,
-      this.includeCaseLabels)
-      : super(request.offset),
-        request = request;
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-    // ignored
-  }
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {
-    if (isCaseLabel ? includeCaseLabels : includeStatementLabels) {
-      CompletionSuggestion suggestion = _addSuggestion(label.label);
-      if (suggestion != null) {
-        suggestion.element = createElement(
-            request.source, protocol.ElementKind.LABEL, label.label,
-            returnType: NO_RETURN_TYPE);
-      }
-    }
-  }
-
-  @override
-  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
-    // ignored
-  }
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredParam(SimpleIdentifier name, TypeName type) {
-    // ignored
-  }
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {
-    // ignored
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    // Labels are only accessible within the local function, so stop visiting
-    // once we reach a function boundary.
-    finished();
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    // Labels are only accessible within the local function, so stop visiting
-    // once we reach a function boundary.
-    finished();
-  }
-
-  CompletionSuggestion _addSuggestion(SimpleIdentifier id) {
-    if (id != null) {
-      String completion = id.name;
-      if (completion != null && completion.length > 0 && completion != '_') {
-        CompletionSuggestion suggestion = new CompletionSuggestion(
-            CompletionSuggestionKind.IDENTIFIER,
-            DART_RELEVANCE_DEFAULT,
-            completion,
-            completion.length,
-            0,
-            false,
-            false);
-        request.addSuggestion(suggestion);
-        return suggestion;
-      }
-    }
-    return null;
-  }
-}
-
-/**
- * A visitor for collecting suggestions from the most specific child [AstNode]
- * that contains the completion offset to the [CompilationUnit].
- */
-class _LocalVisitor extends LocalDeclarationVisitor {
-  final DartCompletionRequest request;
-  final OpType optype;
-  int privateMemberRelevance = DART_RELEVANCE_DEFAULT;
-
-  _LocalVisitor(this.request, int offset, this.optype) : super(offset) {
-    includeLocalInheritedTypes = !optype.inStaticMethodBody;
-    if (request.replacementLength > 0) {
-      var contents = request.context.getContents(request.source);
-      if (contents != null &&
-          contents.data != null &&
-          contents.data.startsWith('_', request.replacementOffset)) {
-        // If user typed identifier starting with '_'
-        // then do not suppress the relevance of private members
-        privateMemberRelevance = null;
-      }
-    }
-  }
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {
-    if (optype.includeTypeNameSuggestions) {
-      _addSuggestion(
-          declaration.name, NO_RETURN_TYPE, protocol.ElementKind.CLASS,
-          isAbstract: declaration.isAbstract,
-          isDeprecated: isDeprecated(declaration));
-    }
-  }
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {
-    if (optype.includeTypeNameSuggestions) {
-      _addSuggestion(declaration.name, NO_RETURN_TYPE,
-          protocol.ElementKind.CLASS_TYPE_ALIAS,
-          isAbstract: true, isDeprecated: isDeprecated(declaration));
-    }
-  }
-
-  @override
-  void declaredEnum(EnumDeclaration declaration) {
-    if (optype.includeTypeNameSuggestions) {
-      _addSuggestion(
-          declaration.name, NO_RETURN_TYPE, protocol.ElementKind.ENUM,
-          isDeprecated: isDeprecated(declaration));
-    }
-  }
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-    if (optype.includeReturnValueSuggestions &&
-        (!optype.inStaticMethodBody || fieldDecl.isStatic)) {
-      CompletionSuggestion suggestion =
-          createFieldSuggestion(request.source, fieldDecl, varDecl);
-      if (suggestion != null) {
-        request.addSuggestion(suggestion);
-      }
-    }
-  }
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {
-    if (optype.includeReturnValueSuggestions ||
-        optype.includeVoidReturnSuggestions) {
-      TypeName typeName = declaration.returnType;
-      protocol.ElementKind elemKind;
-      int relevance = DART_RELEVANCE_DEFAULT;
-      if (declaration.isGetter) {
-        elemKind = protocol.ElementKind.GETTER;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else if (declaration.isSetter) {
-        if (!optype.includeVoidReturnSuggestions) {
-          return;
-        }
-        elemKind = protocol.ElementKind.SETTER;
-        typeName = NO_RETURN_TYPE;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else {
-        if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) {
-          return;
-        }
-        elemKind = protocol.ElementKind.FUNCTION;
-        relevance = DART_RELEVANCE_LOCAL_FUNCTION;
-      }
-      _addSuggestion(declaration.name, typeName, elemKind,
-          isDeprecated: isDeprecated(declaration),
-          param: declaration.functionExpression.parameters,
-          relevance: relevance);
-    }
-  }
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
-    if (optype.includeTypeNameSuggestions) {
-      // TODO (danrubel) determine parameters and return type
-      _addSuggestion(declaration.name, declaration.returnType,
-          protocol.ElementKind.FUNCTION_TYPE_ALIAS,
-          isAbstract: true, isDeprecated: isDeprecated(declaration));
-    }
-  }
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {
-    // ignored
-  }
-
-  @override
-  void declaredLocalVar(SimpleIdentifier id, TypeName typeName) {
-    if (optype.includeReturnValueSuggestions) {
-      _addSuggestion(id, typeName, protocol.ElementKind.LOCAL_VARIABLE,
-          relevance: DART_RELEVANCE_LOCAL_VARIABLE);
-    }
-  }
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {
-    if ((optype.includeReturnValueSuggestions ||
-            optype.includeVoidReturnSuggestions) &&
-        (!optype.inStaticMethodBody || declaration.isStatic)) {
-      protocol.ElementKind elemKind;
-      FormalParameterList param;
-      TypeName typeName = declaration.returnType;
-      int relevance = DART_RELEVANCE_DEFAULT;
-      if (declaration.isGetter) {
-        elemKind = protocol.ElementKind.GETTER;
-        param = null;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else if (declaration.isSetter) {
-        if (!optype.includeVoidReturnSuggestions) {
-          return;
-        }
-        elemKind = protocol.ElementKind.SETTER;
-        typeName = NO_RETURN_TYPE;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else {
-        if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) {
-          return;
-        }
-        elemKind = protocol.ElementKind.METHOD;
-        param = declaration.parameters;
-        relevance = DART_RELEVANCE_LOCAL_METHOD;
-      }
-      _addSuggestion(declaration.name, typeName, elemKind,
-          isAbstract: declaration.isAbstract,
-          isDeprecated: isDeprecated(declaration),
-          classDecl: declaration.parent,
-          param: param,
-          relevance: relevance);
-    }
-  }
-
-  @override
-  void declaredParam(SimpleIdentifier id, TypeName typeName) {
-    if (optype.includeReturnValueSuggestions) {
-      _addSuggestion(id, typeName, protocol.ElementKind.PARAMETER,
-          relevance: DART_RELEVANCE_PARAMETER);
-    }
-  }
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {
-    if (optype.includeReturnValueSuggestions) {
-      _addSuggestion(
-          varDecl.name, varList.type, protocol.ElementKind.TOP_LEVEL_VARIABLE,
-          isDeprecated: isDeprecated(varList) || isDeprecated(varDecl),
-          relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
-    }
-  }
-
-  void _addParameterInfo(
-      CompletionSuggestion suggestion, FormalParameterList parameters) {
-    var paramList = parameters.parameters;
-    suggestion.parameterNames = paramList
-        .map((FormalParameter param) => param.identifier.name)
-        .toList();
-    suggestion.parameterTypes = paramList.map((FormalParameter param) {
-      TypeName type = null;
-      if (param is DefaultFormalParameter) {
-        NormalFormalParameter child = param.parameter;
-        if (child is SimpleFormalParameter) {
-          type = child.type;
-        } else if (child is FieldFormalParameter) {
-          type = child.type;
-        }
-      }
-      if (param is SimpleFormalParameter) {
-        type = param.type;
-      } else if (param is FieldFormalParameter) {
-        type = param.type;
-      }
-      if (type == null) {
-        return 'dynamic';
-      }
-      Identifier typeId = type.name;
-      if (typeId == null) {
-        return 'dynamic';
-      }
-      return typeId.name;
-    }).toList();
-    suggestion.requiredParameterCount = paramList
-        .where((FormalParameter param) => param is! DefaultFormalParameter)
-        .length;
-    suggestion.hasNamedParameters = paramList
-        .any((FormalParameter param) => param.kind == ParameterKind.NAMED);
-  }
-
-  void _addSuggestion(
-      SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind,
-      {bool isAbstract: false,
-      bool isDeprecated: false,
-      ClassDeclaration classDecl,
-      FormalParameterList param,
-      int relevance: DART_RELEVANCE_DEFAULT}) {
-    CompletionSuggestion suggestion = createSuggestion(
-        id, isDeprecated, relevance, typeName,
-        classDecl: classDecl);
-    if (suggestion != null) {
-      if (privateMemberRelevance != null &&
-          suggestion.completion.startsWith('_')) {
-        suggestion.relevance = privateMemberRelevance;
-      }
-      request.addSuggestion(suggestion);
-      suggestion.element = createElement(request.source, elemKind, id,
-          isAbstract: isAbstract,
-          isDeprecated: isDeprecated,
-          parameters: param != null ? param.toSource() : null,
-          returnType: typeName);
-      if ((elemKind == protocol.ElementKind.METHOD ||
-              elemKind == protocol.ElementKind.FUNCTION) &&
-          param != null) {
-        _addParameterInfo(suggestion, param);
-      }
-    }
-  }
-
-  bool _isVoid(TypeName returnType) {
-    if (returnType != null) {
-      Identifier id = returnType.name;
-      if (id != null && id.name == 'void') {
-        return true;
-      }
-    }
-    return false;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart
deleted file mode 100644
index 4981136..0000000
--- a/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart
+++ /dev/null
@@ -1,139 +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 services.completion.suggestion.builder.local;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-const DYNAMIC = 'dynamic';
-
-final TypeName NO_RETURN_TYPE = new TypeName(
-    new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null);
-
-/**
- * Create a new protocol Element for inclusion in a completion suggestion.
- */
-protocol.Element createElement(
-    Source source, protocol.ElementKind kind, SimpleIdentifier id,
-    {String parameters,
-    TypeName returnType,
-    bool isAbstract: false,
-    bool isDeprecated: false}) {
-  String name;
-  Location location;
-  if (id != null) {
-    name = id.name;
-    // TODO(danrubel) use lineInfo to determine startLine and startColumn
-    location = new Location(source.fullName, id.offset, id.length, 0, 0);
-  } else {
-    name = '';
-    location = new Location(source.fullName, -1, 0, 1, 0);
-  }
-  int flags = protocol.Element.makeFlags(
-      isAbstract: isAbstract,
-      isDeprecated: isDeprecated,
-      isPrivate: Identifier.isPrivateName(name));
-  return new protocol.Element(kind, name, flags,
-      location: location,
-      parameters: parameters,
-      returnType: nameForType(returnType));
-}
-
-/**
- * Create a new suggestion for the given field.
- * Return the new suggestion or `null` if it could not be created.
- */
-CompletionSuggestion createFieldSuggestion(
-    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-  bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
-  TypeName type = fieldDecl.fields.type;
-  return createSuggestion(
-      varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
-      classDecl: fieldDecl.parent,
-      element: createElement(source, protocol.ElementKind.FIELD, varDecl.name,
-          returnType: type, isDeprecated: deprecated));
-}
-
-/**
- * Create a new suggestion based upon the given information.
- * Return the new suggestion or `null` if it could not be created.
- */
-CompletionSuggestion createSuggestion(SimpleIdentifier id, bool isDeprecated,
-    int defaultRelevance, TypeName returnType,
-    {ClassDeclaration classDecl, protocol.Element element}) {
-  if (id == null) {
-    return null;
-  }
-  String completion = id.name;
-  if (completion == null || completion.length <= 0 || completion == '_') {
-    return null;
-  }
-  CompletionSuggestion suggestion = new CompletionSuggestion(
-      CompletionSuggestionKind.INVOCATION,
-      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
-      completion,
-      completion.length,
-      0,
-      isDeprecated,
-      false,
-      returnType: nameForType(returnType),
-      element: element);
-  if (classDecl != null) {
-    SimpleIdentifier classId = classDecl.name;
-    if (classId != null) {
-      String className = classId.name;
-      if (className != null && className.length > 0) {
-        suggestion.declaringType = className;
-      }
-    }
-  }
-  return suggestion;
-}
-
-/**
- * Return `true` if the @deprecated annotation is present
- */
-bool isDeprecated(AnnotatedNode node) {
-  if (node != null) {
-    NodeList<Annotation> metadata = node.metadata;
-    if (metadata != null) {
-      return metadata.any((Annotation a) {
-        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
-      });
-    }
-  }
-  return false;
-}
-
-/**
- * Return the name for the given type.
- */
-String nameForType(TypeName type) {
-  if (type == NO_RETURN_TYPE) {
-    return null;
-  }
-  if (type == null) {
-    return DYNAMIC;
-  }
-  Identifier id = type.name;
-  if (id == null) {
-    return DYNAMIC;
-  }
-  String name = id.name;
-  if (name == null || name.length <= 0) {
-    return DYNAMIC;
-  }
-  TypeArgumentList typeArgs = type.typeArguments;
-  if (typeArgs != null) {
-    //TODO (danrubel) include type arguments
-  }
-  return name;
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/optype.dart b/pkg/analysis_server/lib/src/services/completion/optype.dart
deleted file mode 100644
index 3408e96..0000000
--- a/pkg/analysis_server/lib/src/services/completion/optype.dart
+++ /dev/null
@@ -1,681 +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 services.completion.dart.optype;
-
-import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-
-/**
- * An [AstVisitor] for determining whether top level suggestions or invocation
- * suggestions should be made based upon the type of node in which the
- * suggestions were requested.
- */
-class OpType {
-  /**
-   * Indicates whether constructor suggestions should be included.
-   */
-  bool includeConstructorSuggestions = false;
-
-  /**
-   * Indicates whether type names should be suggested.
-   */
-  bool includeTypeNameSuggestions = false;
-
-  /**
-   * Indicates whether setters along with methods and functions that
-   * have a [void] return type should be suggested.
-   */
-  bool includeVoidReturnSuggestions = false;
-
-  /**
-   * Indicates whether fields and getters along with methods and functions that
-   * have a non-[void] return type should be suggested.
-   */
-  bool includeReturnValueSuggestions = false;
-
-  /**
-   * Indicates whether statement labels should be suggested.
-   */
-  bool includeStatementLabelSuggestions = false;
-
-  /**
-   * Indicates whether case labels should be suggested.
-   */
-  bool includeCaseLabelSuggestions = false;
-
-  /**
-   * Indicates whether the completion location is in the body of a static method.
-   */
-  bool inStaticMethodBody = false;
-
-  /**
-   * Indicates whether the completion target is prefixed.
-   */
-  bool isPrefixed = false;
-
-  /**
-   * Determine the suggestions that should be made based upon the given
-   * [CompletionTarget] and [offset].
-   */
-  factory OpType.forCompletion(CompletionTarget target, int offset) {
-    OpType optype = new OpType._();
-    target.containingNode
-        .accept(new _OpTypeAstVisitor(optype, target.entity, offset));
-    var mthDecl =
-        target.containingNode.getAncestor((p) => p is MethodDeclaration);
-    optype.inStaticMethodBody =
-        mthDecl is MethodDeclaration && mthDecl.isStatic;
-    return optype;
-  }
-
-  OpType._();
-
-  /**
-   * Indicate whether only type names should be suggested
-   */
-  bool get includeOnlyTypeNameSuggestions => includeTypeNameSuggestions &&
-      !includeReturnValueSuggestions &&
-      !includeVoidReturnSuggestions;
-}
-
-class _OpTypeAstVisitor extends GeneralizingAstVisitor {
-  /**
-   * The entity (AstNode or Token) which will be replaced or displaced by the
-   * added text.
-   */
-  final Object entity;
-
-  /**
-   * The offset within the source at which the completion is requested.
-   */
-  final int offset;
-
-  /**
-   * The [OpType] being initialized
-   */
-  final OpType optype;
-
-  _OpTypeAstVisitor(this.optype, this.entity, this.offset);
-
-  @override
-  void visitAnnotation(Annotation node) {
-    if (identical(entity, node.name)) {
-      optype.includeTypeNameSuggestions = true;
-      optype.includeReturnValueSuggestions = true;
-    } else if (identical(entity, node.constructorName)) {
-      optype.includeTypeNameSuggestions = true;
-      optype.includeReturnValueSuggestions = true;
-      optype.isPrefixed = true;
-    }
-  }
-
-  @override
-  void visitArgumentList(ArgumentList node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  void visitAsExpression(AsExpression node) {
-    if (identical(entity, node.type)) {
-      optype.includeTypeNameSuggestions = true;
-      // TODO (danrubel) Possible future improvement:
-      // on the RHS of an "is" or "as" expression, don't suggest types that are
-      // guaranteed to pass or guaranteed to fail the cast.
-      // See dartbug.com/18860
-    }
-  }
-
-  void visitAssignmentExpression(AssignmentExpression node) {
-    if (identical(entity, node.rightHandSide)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitAwaitExpression(AwaitExpression node) {
-    if (identical(entity, node.expression)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitBinaryExpression(BinaryExpression node) {
-    if (identical(entity, node.rightOperand)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitBlock(Block node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-    optype.includeVoidReturnSuggestions = true;
-  }
-
-  @override
-  void visitBreakStatement(BreakStatement node) {
-    if (node.label == null || identical(entity, node.label)) {
-      optype.includeStatementLabelSuggestions = true;
-    }
-  }
-
-  @override
-  void visitCascadeExpression(CascadeExpression node) {
-    if (node.cascadeSections.contains(entity)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeVoidReturnSuggestions = true;
-      optype.isPrefixed = true;
-    }
-  }
-
-  @override
-  void visitCatchClause(CatchClause node) {
-    if (identical(entity, node.exceptionType)) {
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    // Make suggestions in the body of the class declaration
-    if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitClassMember(ClassMember node) {}
-
-  @override
-  void visitCommentReference(CommentReference node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-    optype.includeVoidReturnSuggestions = true;
-  }
-
-  void visitCompilationUnit(CompilationUnit node) {
-    if (entity is! CommentToken) {
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitConditionalExpression(ConditionalExpression node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  visitConstructorName(ConstructorName node) {
-    // some PrefixedIdentifier nodes are transformed into
-    // ConstructorName nodes during the resolution process.
-    if (identical(entity, node.name)) {
-      TypeName type = node.type;
-      if (type != null) {
-        SimpleIdentifier prefix = type.name;
-        if (prefix != null) {
-          optype.includeConstructorSuggestions = true;
-          optype.isPrefixed = true;
-        }
-      }
-    }
-  }
-
-  @override
-  void visitContinueStatement(ContinueStatement node) {
-    if (node.label == null || identical(entity, node.label)) {
-      optype.includeStatementLabelSuggestions = true;
-      optype.includeCaseLabelSuggestions = true;
-    }
-  }
-
-  @override
-  void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    if (identical(entity, node.defaultValue)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    if (identical(entity, node.condition)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitEmptyStatement(EmptyStatement node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-    optype.includeVoidReturnSuggestions = true;
-  }
-
-  @override
-  void visitExpression(Expression node) {
-    // This should never be called; we should always dispatch to the visitor
-    // for a particular kind of expression.
-    assert(false);
-  }
-
-  @override
-  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    if (identical(entity, node.expression)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitExpressionStatement(ExpressionStatement node) {
-    // Given f[], the parser drops the [] from the expression statement
-    // but the [] token is the CompletionTarget entity
-    if (entity is Token) {
-      Token token = entity;
-      if (token.lexeme == '[]' && offset == token.offset + 1) {
-        optype.includeReturnValueSuggestions = true;
-        optype.includeTypeNameSuggestions = true;
-      }
-    }
-  }
-
-  @override
-  void visitExtendsClause(ExtendsClause node) {
-    if (identical(entity, node.superclass)) {
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitFieldFormalParameter(FieldFormalParameter node) {
-    if (entity == node.identifier) {
-      optype.isPrefixed = true;
-    } else {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitForEachStatement(ForEachStatement node) {
-    if (identical(entity, node.identifier)) {
-      optype.includeTypeNameSuggestions = true;
-    }
-    if (identical(entity, node.loopVariable)) {
-      optype.includeTypeNameSuggestions = true;
-    }
-    if (identical(entity, node.inKeyword) && offset <= node.inKeyword.offset) {
-      if (node.identifier == null && node.loopVariable == null) {
-        optype.includeTypeNameSuggestions = true;
-      }
-    }
-    if (identical(entity, node.iterable)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitFormalParameterList(FormalParameterList node) {
-    dynamic entity = this.entity;
-    if (entity is Token && entity.previous != null) {
-      TokenType type = entity.previous.type;
-      if (type == TokenType.OPEN_PAREN || type == TokenType.COMMA) {
-        optype.includeTypeNameSuggestions = true;
-      }
-    }
-    // Handle default normal parameter just as a normal parameter.
-    if (entity is DefaultFormalParameter) {
-      entity = entity.parameter;
-    }
-    // "(^ this.field)"
-    if (entity is FieldFormalParameter) {
-      if (offset < entity.thisKeyword.offset) {
-        optype.includeTypeNameSuggestions = true;
-      }
-    }
-    // "(Type name)"
-    if (entity is SimpleFormalParameter) {
-      // "(Type^)" is parsed as a parameter with the _name_ "Type".
-      if (entity.type == null) {
-        optype.includeTypeNameSuggestions = true;
-      }
-      // If inside of "Type" in "(Type^ name)", then include types.
-      if (entity.type != null &&
-          entity.type.offset <= offset &&
-          offset <= entity.type.end) {
-        optype.includeTypeNameSuggestions = true;
-      }
-    }
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-    optype.includeVoidReturnSuggestions = true;
-    // TODO (danrubel) void return suggestions only belong after
-    // the 2nd semicolon.  Return value suggestions only belong after the
-    // e1st or second semicolon.
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    if (identical(entity, node.returnType) ||
-        identical(entity, node.name) && node.returnType == null) {
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {}
-
-  @override
-  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {}
-
-  @override
-  void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    if (identical(entity, node.returnType) ||
-        identical(entity, node.name) && node.returnType == null) {
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitIfStatement(IfStatement node) {
-    if (identical(entity, node.condition)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    } else if (identical(entity, node.thenStatement) ||
-        identical(entity, node.elseStatement)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-      optype.includeVoidReturnSuggestions = true;
-    }
-  }
-
-  @override
-  void visitImplementsClause(ImplementsClause node) {
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  void visitIndexExpression(IndexExpression node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    if (identical(entity, node.constructorName)) {
-      optype.includeConstructorSuggestions = true;
-    }
-  }
-
-  @override
-  void visitInterpolationExpression(InterpolationExpression node) {
-    if (identical(entity, node.expression)) {
-      optype.includeReturnValueSuggestions = true;
-      // Only include type names in a ${ } expression
-      optype.includeTypeNameSuggestions =
-          node.leftBracket != null && node.leftBracket.length > 1;
-    }
-  }
-
-  @override
-  void visitIsExpression(IsExpression node) {
-    if (identical(entity, node.type)) {
-      optype.includeTypeNameSuggestions = true;
-      // TODO (danrubel) Possible future improvement:
-      // on the RHS of an "is" or "as" expression, don't suggest types that are
-      // guaranteed to pass or guaranteed to fail the cast.
-      // See dartbug.com/18860
-    }
-  }
-
-  void visitLibraryIdentifier(LibraryIdentifier node) {
-    // No suggestions.
-  }
-
-  @override
-  void visitMapLiteralEntry(MapLiteralEntry node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  void visitMethodInvocation(MethodInvocation node) {
-    bool isThis = node.target is ThisExpression;
-    if (identical(entity, node.operator) && offset > node.operator.offset) {
-      // The cursor is between the two dots of a ".." token, so we need to
-      // generate the completions we would generate after a "." token.
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = !isThis;
-      optype.includeVoidReturnSuggestions = true;
-      optype.isPrefixed = true;
-    } else if (identical(entity, node.methodName)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = !isThis;
-      optype.includeVoidReturnSuggestions = true;
-      optype.isPrefixed = true;
-    }
-  }
-
-  @override
-  void visitNamedExpression(NamedExpression node) {
-    if (identical(entity, node.expression)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitNode(AstNode node) {
-    // no suggestion by default
-  }
-
-  @override
-  void visitNormalFormalParameter(NormalFormalParameter node) {
-    if (node.identifier != entity) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  void visitParenthesizedExpression(ParenthesizedExpression node) {
-    if (identical(entity, node.expression)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitPostfixExpression(PostfixExpression node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  void visitPrefixedIdentifier(PrefixedIdentifier node) {
-    if (identical(entity, node.identifier) ||
-        // In addition to the standard case,
-        // handle the exceptional case where the parser considers the would-be
-        // identifier to be a keyword and inserts a synthetic identifier
-        (node.identifier != null &&
-            node.identifier.isSynthetic &&
-            identical(entity, node.identifier.beginToken.previous))) {
-      optype.isPrefixed = true;
-      if (node.parent is TypeName && node.parent.parent is ConstructorName) {
-        optype.includeConstructorSuggestions = true;
-      } else {
-        optype.includeReturnValueSuggestions = true;
-        optype.includeTypeNameSuggestions = true;
-        optype.includeVoidReturnSuggestions =
-            node.parent is ExpressionStatement;
-      }
-    }
-  }
-
-  @override
-  void visitPrefixExpression(PrefixExpression node) {
-    if (identical(entity, node.operand)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitPropertyAccess(PropertyAccess node) {
-    bool isThis = node.target is ThisExpression;
-    if (node.realTarget is SimpleIdentifier && node.realTarget.isSynthetic) {
-      // If the access has no target (empty string)
-      // then don't suggest anything
-      return;
-    }
-    if (identical(entity, node.operator) && offset > node.operator.offset) {
-      // The cursor is between the two dots of a ".." token, so we need to
-      // generate the completions we would generate after a "." token.
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = !isThis;
-      optype.includeVoidReturnSuggestions = true;
-      optype.isPrefixed = true;
-    } else if (identical(entity, node.propertyName)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions =
-          !isThis && (node.parent is! CascadeExpression);
-      optype.includeVoidReturnSuggestions = true;
-      optype.isPrefixed = true;
-    }
-  }
-
-  @override
-  void visitReturnStatement(ReturnStatement node) {
-    if (identical(entity, node.expression)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    // This should never happen; the containingNode will always be some node
-    // higher up in the parse tree, and the SimpleIdentifier will be the
-    // entity.
-    assert(false);
-  }
-
-  @override
-  void visitStringLiteral(StringLiteral node) {
-    // no suggestions
-  }
-
-  @override
-  void visitSwitchCase(SwitchCase node) {
-    if (identical(entity, node.expression)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    if (identical(entity, node.expression)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-    if (identical(entity, node.rightBracket)) {
-      if (node.members.isNotEmpty) {
-        optype.includeReturnValueSuggestions = true;
-        optype.includeTypeNameSuggestions = true;
-        optype.includeVoidReturnSuggestions = true;
-      }
-    }
-    if (entity is SwitchMember && entity != node.members.first) {
-      SwitchMember member = entity as SwitchMember;
-      if (offset <= member.offset) {
-        optype.includeReturnValueSuggestions = true;
-        optype.includeTypeNameSuggestions = true;
-        optype.includeVoidReturnSuggestions = true;
-      }
-    }
-  }
-
-  @override
-  void visitThrowExpression(ThrowExpression node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  void visitTypeArgumentList(TypeArgumentList node) {
-    NodeList<TypeName> arguments = node.arguments;
-    for (TypeName typeName in arguments) {
-      if (identical(entity, typeName)) {
-        optype.includeTypeNameSuggestions = true;
-        break;
-      }
-    }
-  }
-
-  @override
-  void visitTypedLiteral(TypedLiteral node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  void visitTypeName(TypeName node) {
-    // The entity won't be the first child entity (node.name), since
-    // CompletionTarget would have chosen an edge higher in the parse tree.  So
-    // it must be node.typeArguments, meaning that the cursor is between the
-    // type name and the "<" that starts the type arguments.  In this case,
-    // we have no completions to offer.
-    assert(identical(entity, node.typeArguments));
-  }
-
-  @override
-  void visitTypeParameter(TypeParameter node) {
-    optype.includeTypeNameSuggestions = true;
-  }
-
-  @override
-  void visitVariableDeclaration(VariableDeclaration node) {
-    // Make suggestions for the RHS of a variable declaration
-    if (identical(entity, node.initializer)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    if ((node.keyword == null || node.keyword.lexeme != 'var') &&
-        (node.type == null || identical(entity, node.type))) {
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-
-  @override
-  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {}
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    if (identical(entity, node.condition)) {
-      optype.includeReturnValueSuggestions = true;
-      optype.includeTypeNameSuggestions = true;
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart b/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart
deleted file mode 100644
index 5a52da8..0000000
--- a/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart
+++ /dev/null
@@ -1,442 +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 services.completion.contributor.dart.invocation;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
-import 'package:analysis_server/src/services/completion/local_suggestion_builder.dart'
-    hide createSuggestion;
-import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart'
-    show createSuggestion;
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-
-import '../../protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind;
-
-/**
- * A contributor for calculating invocation / access suggestions
- * `completion.getSuggestions` request results.
- */
-class PrefixedElementContributor extends DartCompletionContributor {
-  SuggestionBuilder builder;
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    OpType optype = request.optype;
-    if (optype.isPrefixed) {
-      builder = request.target.containingNode
-          .accept(new _InvocationAstVisitor(request));
-      if (builder != null) {
-        return builder.computeFast(request.target.containingNode);
-      }
-    }
-
-    return true;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    if (builder != null) {
-      return builder.computeFull(request.target.containingNode);
-    }
-    return new Future.value(false);
-  }
-}
-
-class _ExpressionSuggestionBuilder implements SuggestionBuilder {
-  final DartCompletionRequest request;
-
-  _ExpressionSuggestionBuilder(this.request);
-
-  @override
-  bool computeFast(AstNode node) {
-    return false;
-  }
-
-  @override
-  Future<bool> computeFull(AstNode node) {
-    if (node is MethodInvocation) {
-      node = (node as MethodInvocation).realTarget;
-    } else if (node is PropertyAccess) {
-      node = (node as PropertyAccess).realTarget;
-    }
-    if (node is Identifier) {
-      Element elem = node.bestElement;
-      if (elem is ClassElement || elem is PrefixElement) {
-        elem.accept(new _PrefixedIdentifierSuggestionBuilder(request));
-        return new Future.value(true);
-      }
-    }
-    if (node is Expression) {
-      String containingMethodName;
-      bool isSuper = node is SuperExpression;
-      if (isSuper) {
-        MethodDeclaration containingMethod =
-            node.getAncestor((p) => p is MethodDeclaration);
-        if (containingMethod != null) {
-          SimpleIdentifier id = containingMethod.name;
-          if (id != null) {
-            containingMethodName = id.name;
-          }
-        }
-      }
-      InterfaceTypeSuggestionBuilder.suggestionsFor(request, node.bestType,
-          isSuper: isSuper, containingMethodName: containingMethodName);
-      return new Future.value(true);
-    }
-    return new Future.value(false);
-  }
-}
-
-/**
- * A suggestion builder for 'this.' constructor arguments.
- */
-class _FieldFormalSuggestionBuilder implements SuggestionBuilder {
-  final DartCompletionRequest request;
-
-  _FieldFormalSuggestionBuilder(this.request);
-
-  @override
-  bool computeFast(AstNode node) {
-    if (node is FieldFormalParameter) {
-      ConstructorDeclaration constructorDecl =
-          node.getAncestor((p) => p is ConstructorDeclaration);
-      if (constructorDecl != null) {
-        // Compute fields already referenced
-        List<String> referencedFields = new List<String>();
-        for (FormalParameter param in constructorDecl.parameters.parameters) {
-          if (param is FieldFormalParameter) {
-            SimpleIdentifier fieldId = param.identifier;
-            if (fieldId != null && fieldId != request.target.entity) {
-              String fieldName = fieldId.name;
-              if (fieldName != null && fieldName.length > 0) {
-                referencedFields.add(fieldName);
-              }
-            }
-          }
-        }
-
-        // Add suggestions for fields that are not already referenced
-        ClassDeclaration classDecl =
-            constructorDecl.getAncestor((p) => p is ClassDeclaration);
-        for (ClassMember member in classDecl.members) {
-          if (member is FieldDeclaration && !member.isStatic) {
-            for (VariableDeclaration varDecl in member.fields.variables) {
-              SimpleIdentifier fieldId = varDecl.name;
-              if (fieldId != null) {
-                String fieldName = fieldId.name;
-                if (fieldName != null && fieldName.length > 0) {
-                  if (!referencedFields.contains(fieldName)) {
-                    CompletionSuggestion suggestion =
-                        createFieldSuggestion(request.source, member, varDecl);
-                    if (suggestion != null) {
-                      request.addSuggestion(suggestion);
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    } else {
-      // This should never be called with a case not handled above.
-      assert(false);
-    }
-    return true;
-  }
-
-  @override
-  Future<bool> computeFull(AstNode node) {
-    // This should never be called; we should always be able to compute
-    // suggestions and return true in computeFast method.
-    assert(false);
-    return null;
-  }
-}
-
-/**
- * An [AstNode] vistor for determining which suggestion builder
- * should be used to build invocation/access suggestions.
- */
-class _InvocationAstVisitor extends GeneralizingAstVisitor<SuggestionBuilder> {
-  final DartCompletionRequest request;
-
-  _InvocationAstVisitor(this.request);
-
-  @override
-  SuggestionBuilder visitConstructorName(ConstructorName node) {
-    // some PrefixedIdentifier nodes are transformed into
-    // ConstructorName nodes during the resolution process.
-    return new _PrefixedIdentifierSuggestionBuilder(request);
-  }
-
-  @override
-  SuggestionBuilder visitFieldFormalParameter(FieldFormalParameter node) {
-    return new _FieldFormalSuggestionBuilder(request);
-  }
-
-  @override
-  SuggestionBuilder visitMethodInvocation(MethodInvocation node) {
-    return new _ExpressionSuggestionBuilder(request);
-  }
-
-  @override
-  SuggestionBuilder visitNode(AstNode node) {
-    return null;
-  }
-
-  @override
-  SuggestionBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
-    // some PrefixedIdentifier nodes are transformed into
-    // ConstructorName nodes during the resolution process.
-    return new _PrefixedIdentifierSuggestionBuilder(request);
-  }
-
-  @override
-  SuggestionBuilder visitPropertyAccess(PropertyAccess node) {
-    return new _ExpressionSuggestionBuilder(request);
-  }
-}
-
-/**
- * An [AstVisitor] which looks for a declaration with the given name
- * and if found, tries to determine a type for that declaration.
- */
-class _LocalBestTypeVisitor extends LocalDeclarationVisitor {
-  /**
-   * The name for the declaration to be found.
-   */
-  final String targetName;
-
-  /**
-   * The best type for the found declaration,
-   * or `null` if no declaration found or failed to determine a type.
-   */
-  DartType typeFound;
-
-  /**
-   * Construct a new instance to search for a declaration
-   */
-  _LocalBestTypeVisitor(this.targetName, int offset) : super(offset);
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {
-    if (declaration.name.name == targetName) {
-      // no type
-      finished();
-    }
-  }
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {
-    if (declaration.name.name == targetName) {
-      // no type
-      finished();
-    }
-  }
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-    if (varDecl.name.name == targetName) {
-      // Type provided by the element in computeFull above
-      finished();
-    }
-  }
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {
-    if (declaration.name.name == targetName) {
-      TypeName typeName = declaration.returnType;
-      if (typeName != null) {
-        typeFound = typeName.type;
-      }
-      finished();
-    }
-  }
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
-    if (declaration.name.name == targetName) {
-      TypeName typeName = declaration.returnType;
-      if (typeName != null) {
-        typeFound = typeName.type;
-      }
-      finished();
-    }
-  }
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {
-    if (label.label.name == targetName) {
-      // no type
-      finished();
-    }
-  }
-
-  @override
-  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
-    if (name.name == targetName) {
-      typeFound = name.bestType;
-      finished();
-    }
-  }
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {
-    if (declaration.name.name == targetName) {
-      TypeName typeName = declaration.returnType;
-      if (typeName != null) {
-        typeFound = typeName.type;
-      }
-      finished();
-    }
-  }
-
-  @override
-  void declaredParam(SimpleIdentifier name, TypeName type) {
-    if (name.name == targetName) {
-      // Type provided by the element in computeFull above
-      finished();
-    }
-  }
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {
-    if (varDecl.name.name == targetName) {
-      // Type provided by the element in computeFull above
-      finished();
-    }
-  }
-}
-
-/**
- * An [Element] visitor for determining the appropriate invocation/access
- * suggestions based upon the element for which the completion is requested.
- */
-class _PrefixedIdentifierSuggestionBuilder
-    extends GeneralizingElementVisitor<Future<bool>>
-    implements SuggestionBuilder {
-  final DartCompletionRequest request;
-
-  _PrefixedIdentifierSuggestionBuilder(this.request);
-
-  @override
-  bool computeFast(AstNode node) {
-    return false;
-  }
-
-  @override
-  Future<bool> computeFull(AstNode node) {
-    if (node is ConstructorName) {
-      // some PrefixedIdentifier nodes are transformed into
-      // ConstructorName nodes during the resolution process.
-      return new NamedConstructorSuggestionBuilder(request).computeFull(node);
-    }
-    if (node is PrefixedIdentifier) {
-      SimpleIdentifier prefix = node.prefix;
-      if (prefix != null) {
-        Element element = prefix.bestElement;
-        DartType type = prefix.bestType;
-        if (element is! ClassElement) {
-          if (type == null || type.isDynamic) {
-            //
-            // Given `g. int y = 0;`, the parser interprets `g` as a prefixed
-            // identifier with no type.
-            // If the user is requesting completions for `g`,
-            // then check for a function, getter, or similar with a type.
-            //
-            _LocalBestTypeVisitor visitor =
-                new _LocalBestTypeVisitor(prefix.name, request.offset);
-            if (visitor.visit(prefix)) {
-              type = visitor.typeFound;
-            }
-          }
-          if (type != null && !type.isDynamic) {
-            InterfaceTypeSuggestionBuilder.suggestionsFor(request, type);
-            return new Future.value(true);
-          }
-        }
-        if (element != null) {
-          return element.accept(this);
-        }
-      }
-    }
-    return new Future.value(false);
-  }
-
-  @override
-  Future<bool> visitClassElement(ClassElement element) {
-    if (element != null) {
-      InterfaceType type = element.type;
-      if (type != null) {
-        StaticClassElementSuggestionBuilder.suggestionsFor(
-            request, type.element);
-      }
-    }
-    return new Future.value(false);
-  }
-
-  @override
-  Future<bool> visitElement(Element element) {
-    return new Future.value(false);
-  }
-
-  @override
-  Future<bool> visitPrefixElement(PrefixElement element) {
-    bool modified = false;
-    // Find the import directive with the given prefix
-    for (Directive directive in request.unit.directives) {
-      if (directive is ImportDirective) {
-        if (directive.prefix != null) {
-          if (directive.prefix.name == element.name) {
-            // Suggest elements from the imported library
-            LibraryElement library = directive.uriElement;
-            AstNode node = request.target.containingNode;
-            bool typesOnly = node.parent is TypeName;
-            bool instCreation =
-                typesOnly && node.parent.parent is ConstructorName;
-            LibraryElementSuggestionBuilder.suggestionsFor(
-                request,
-                CompletionSuggestionKind.INVOCATION,
-                library,
-                typesOnly,
-                instCreation);
-            modified = true;
-            if (directive.deferredKeyword != null) {
-              FunctionElement loadLibFunct = library.loadLibraryFunction;
-              request.addSuggestion(createSuggestion(loadLibFunct));
-            }
-          }
-        }
-      }
-    }
-    return new Future.value(modified);
-  }
-
-  @override
-  Future<bool> visitPropertyAccessorElement(PropertyAccessorElement element) {
-    if (element != null) {
-      PropertyInducingElement elemVar = element.variable;
-      if (elemVar != null) {
-        InterfaceTypeSuggestionBuilder.suggestionsFor(request, elemVar.type);
-      }
-      return new Future.value(true);
-    }
-    return new Future.value(false);
-  }
-
-  @override
-  Future<bool> visitVariableElement(VariableElement element) {
-    InterfaceTypeSuggestionBuilder.suggestionsFor(request, element.type);
-    return new Future.value(true);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
deleted file mode 100644
index 5117855..0000000
--- a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
+++ /dev/null
@@ -1,684 +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 services.completion.suggestion.builder;
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:analysis_server/src/protocol_server.dart' as protocol;
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart' as engine;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:path/path.dart' as path;
-
-const String DYNAMIC = 'dynamic';
-
-/**
- * Return a suggestion based upon the given element
- * or `null` if a suggestion is not appropriate for the given element.
- * If the suggestion is not currently in scope, then specify
- * importForSource as the source to which an import should be added.
- */
-CompletionSuggestion createSuggestion(Element element,
-    {String completion,
-    CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-    int relevance: DART_RELEVANCE_DEFAULT,
-    Source importForSource}) {
-  if (element is ExecutableElement && element.isOperator) {
-    // Do not include operators in suggestions
-    return null;
-  }
-  if (completion == null) {
-    completion = element.displayName;
-  }
-  bool isDeprecated = element.isDeprecated;
-  CompletionSuggestion suggestion = new CompletionSuggestion(
-      kind,
-      isDeprecated ? DART_RELEVANCE_LOW : relevance,
-      completion,
-      completion.length,
-      0,
-      isDeprecated,
-      false);
-  suggestion.element = protocol.convertElement(element);
-  Element enclosingElement = element.enclosingElement;
-  if (enclosingElement is ClassElement) {
-    suggestion.declaringType = enclosingElement.displayName;
-  }
-  suggestion.returnType = getReturnTypeString(element);
-  if (element is ExecutableElement && element is! PropertyAccessorElement) {
-    suggestion.parameterNames = element.parameters
-        .map((ParameterElement parameter) => parameter.name)
-        .toList();
-    suggestion.parameterTypes = element.parameters
-        .map((ParameterElement parameter) => parameter.type.displayName)
-        .toList();
-    suggestion.requiredParameterCount = element.parameters
-        .where((ParameterElement parameter) =>
-            parameter.parameterKind == ParameterKind.REQUIRED)
-        .length;
-    suggestion.hasNamedParameters = element.parameters.any(
-        (ParameterElement parameter) =>
-            parameter.parameterKind == ParameterKind.NAMED);
-  }
-  if (importForSource != null) {
-    String srcPath = path.dirname(importForSource.fullName);
-    LibraryElement libElem = element.library;
-    if (libElem != null) {
-      Source libSource = libElem.source;
-      if (libSource != null) {
-        UriKind uriKind = libSource.uriKind;
-        if (uriKind == UriKind.DART_URI) {
-          suggestion.importUri = libSource.uri.toString();
-        } else if (uriKind == UriKind.PACKAGE_URI) {
-          suggestion.importUri = libSource.uri.toString();
-        } else if (uriKind == UriKind.FILE_URI &&
-            element.source.uriKind == UriKind.FILE_URI) {
-          try {
-            suggestion.importUri =
-                path.relative(libSource.fullName, from: srcPath);
-          } catch (_) {
-            // ignored
-          }
-        }
-      }
-    }
-    if (suggestion.importUri == null) {
-      // Do not include out of scope suggestions
-      // for which we cannot determine an import
-      return null;
-    }
-  }
-  return suggestion;
-}
-
-/**
- * Call the given function with each non-null non-empty inherited type name
- * that is defined in the given class.
- */
-visitInheritedTypeNames(ClassDeclaration node, void inherited(String name)) {
-  void visit(TypeName type) {
-    if (type != null) {
-      Identifier id = type.name;
-      if (id != null) {
-        String name = id.name;
-        if (name != null && name.length > 0) {
-          inherited(name);
-        }
-      }
-    }
-  }
-
-  ExtendsClause extendsClause = node.extendsClause;
-  if (extendsClause != null) {
-    visit(extendsClause.superclass);
-  }
-  ImplementsClause implementsClause = node.implementsClause;
-  if (implementsClause != null) {
-    NodeList<TypeName> interfaces = implementsClause.interfaces;
-    if (interfaces != null) {
-      interfaces.forEach((TypeName type) {
-        visit(type);
-      });
-    }
-  }
-  WithClause withClause = node.withClause;
-  if (withClause != null) {
-    NodeList<TypeName> mixinTypes = withClause.mixinTypes;
-    if (mixinTypes != null) {
-      mixinTypes.forEach((TypeName type) {
-        visit(type);
-      });
-    }
-  }
-}
-
-/**
- * Starting with the given class node, traverse the inheritance hierarchy
- * calling the given functions with each non-null non-empty inherited class
- * declaration. For each locally defined declaration, call [localDeclaration].
- * For each class identifier in the hierarchy that is not defined locally,
- * call the [importedTypeName] function.
- */
-void visitInheritedTypes(ClassDeclaration node,
-    {void localDeclaration(ClassDeclaration classNode),
-    void importedTypeName(String typeName)}) {
-  CompilationUnit unit = node.getAncestor((p) => p is CompilationUnit);
-  List<ClassDeclaration> todo = new List<ClassDeclaration>();
-  todo.add(node);
-  Set<String> visited = new Set<String>();
-  while (todo.length > 0) {
-    node = todo.removeLast();
-    visitInheritedTypeNames(node, (String name) {
-      if (visited.add(name)) {
-        var classNode = unit.declarations.firstWhere((member) {
-          if (member is ClassDeclaration) {
-            SimpleIdentifier id = member.name;
-            if (id != null && id.name == name) {
-              return true;
-            }
-          }
-          return false;
-        }, orElse: () => null);
-        if (classNode is ClassDeclaration) {
-          if (localDeclaration != null) {
-            localDeclaration(classNode);
-          }
-          todo.add(classNode);
-        } else {
-          if (importedTypeName != null) {
-            importedTypeName(name);
-          }
-        }
-      }
-    });
-  }
-}
-
-/**
- * Common mixin for sharing behavior
- */
-abstract class ElementSuggestionBuilder {
-  /**
-   * Return the kind of suggestions that should be built.
-   */
-  CompletionSuggestionKind get kind;
-
-  /**
-   * Return the request on which the builder is operating.
-   */
-  DartCompletionRequest get request;
-
-  /**
-   * Add a suggestion based upon the given element.
-   */
-  void addSuggestion(Element element,
-      {String prefix, int relevance: DART_RELEVANCE_DEFAULT}) {
-    if (element.isPrivate) {
-      LibraryElement elementLibrary = element.library;
-      CompilationUnitElement unitElem = request.unit.element;
-      if (unitElem == null) {
-        return;
-      }
-      LibraryElement unitLibrary = unitElem.library;
-      if (elementLibrary != unitLibrary) {
-        return;
-      }
-    }
-    if (prefix == null && element.isSynthetic) {
-      if ((element is PropertyAccessorElement) ||
-          element is FieldElement && !_isSpecialEnumField(element)) {
-        return;
-      }
-    }
-    String completion = element.displayName;
-    if (prefix != null && prefix.length > 0) {
-      if (completion == null || completion.length <= 0) {
-        completion = prefix;
-      } else {
-        completion = '$prefix.$completion';
-      }
-    }
-    if (completion == null || completion.length <= 0) {
-      return;
-    }
-    CompletionSuggestion suggestion = createSuggestion(element,
-        completion: completion, kind: kind, relevance: relevance);
-    if (suggestion != null) {
-      request.addSuggestion(suggestion);
-    }
-  }
-
-  /**
-   * Determine if the given element is one of the synthetic enum accessors
-   * for which we should generate a suggestion.
-   */
-  bool _isSpecialEnumField(FieldElement element) {
-    Element parent = element.enclosingElement;
-    if (parent is ClassElement && parent.isEnum) {
-      if (element.name == 'values') {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-/**
- * This class provides suggestions based upon the visible instance members in
- * an interface type.  Clients should call
- * [InterfaceTypeSuggestionBuilder.suggestionsFor].
- */
-class InterfaceTypeSuggestionBuilder {
-  /**
-   * Enumerated value indicating that we have not generated any completions for
-   * a given identifier yet.
-   */
-  static const int _COMPLETION_TYPE_NONE = 0;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * getter.
-   */
-  static const int _COMPLETION_TYPE_GETTER = 1;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * setter.
-   */
-  static const int _COMPLETION_TYPE_SETTER = 2;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * field, a method, or a getter/setter pair.
-   */
-  static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
-
-  final DartCompletionRequest request;
-
-  /**
-   * Map indicating, for each possible completion identifier, whether we have
-   * already generated completions for a getter, setter, or both.  The "both"
-   * case also handles the case where have generated a completion for a method
-   * or a field.
-   *
-   * Note: the enumerated values stored in this map are intended to be bitwise
-   * compared.
-   */
-  Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
-
-  InterfaceTypeSuggestionBuilder(this.request);
-
-  CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
-  /**
-   * Add a suggestion based upon the given element, provided that it is not
-   * shadowed by a previously added suggestion.
-   */
-  void addSuggestion(Element element, {int relevance: DART_RELEVANCE_DEFAULT}) {
-    if (element.isPrivate) {
-      LibraryElement elementLibrary = element.library;
-      LibraryElement unitLibrary = request.unit.element.library;
-      if (elementLibrary != unitLibrary) {
-        return;
-      }
-    }
-    String identifier = element.displayName;
-    int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
-        identifier, () => _COMPLETION_TYPE_NONE);
-    if (element is MethodElement) {
-      // Anything shadows a method.
-      if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
-        return;
-      }
-      _completionTypesGenerated[identifier] =
-          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
-    } else if (element is PropertyAccessorElement) {
-      if (element.isGetter) {
-        // Getters, fields, and methods shadow a getter.
-        if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
-          return;
-        }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
-      } else {
-        // Setters, fields, and methods shadow a setter.
-        if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
-          return;
-        }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
-      }
-    } else if (element is FieldElement) {
-      // Fields and methods shadow a field.  A getter/setter pair shadows a
-      // field, but a getter or setter by itself doesn't.
-      if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
-        return;
-      }
-      _completionTypesGenerated[identifier] =
-          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
-    } else {
-      // Unexpected element type; skip it.
-      assert(false);
-      return;
-    }
-    CompletionSuggestion suggestion =
-        createSuggestion(element, kind: kind, relevance: relevance);
-    if (suggestion != null) {
-      request.addSuggestion(suggestion);
-    }
-  }
-
-  void _buildSuggestions(InterfaceType type, LibraryElement library,
-      bool isSuper, String containingMethodName) {
-    if (isSuper) {
-      // Suggest members from superclass if the target is "super"
-      type = type.superclass;
-      if (type == null) {
-        return;
-      }
-    }
-    // Visit all of the types in the class hierarchy, collecting possible
-    // completions.  If multiple elements are found that complete to the same
-    // identifier, addSuggestion will discard all but the first (with a few
-    // exceptions to handle getter/setter pairs).
-    List<InterfaceType> types = _getTypeOrdering(type);
-    for (InterfaceType targetType in types) {
-      for (MethodElement method in targetType.methods) {
-        // Exclude static methods when completion on an instance
-        if (!method.isStatic) {
-          addSuggestion(method,
-              relevance: method.name == containingMethodName
-                  ? DART_RELEVANCE_HIGH
-                  : DART_RELEVANCE_DEFAULT);
-        }
-      }
-      for (PropertyAccessorElement propertyAccessor in targetType.accessors) {
-        if (!propertyAccessor.isStatic) {
-          if (propertyAccessor.isSynthetic) {
-            // Avoid visiting a field twice
-            if (propertyAccessor.isGetter) {
-              addSuggestion(propertyAccessor.variable);
-            }
-          } else {
-            addSuggestion(propertyAccessor);
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Get a list of [InterfaceType]s that should be searched to find the
-   * possible completions for an object having type [type].
-   */
-  List<InterfaceType> _getTypeOrdering(InterfaceType type) {
-    // Candidate completions can come from [type] as well as any types above it
-    // in the class hierarchy (including mixins, superclasses, and interfaces).
-    // If a given completion identifier shows up in multiple types, we should
-    // use the element that is nearest in the superclass chain, so we will
-    // visit [type] first, then its mixins, then its superclass, then its
-    // superclass's mixins, etc., and only afterwards visit interfaces.
-    //
-    // We short-circuit loops in the class hierarchy by keeping track of the
-    // classes seen (not the interfaces) so that we won't be fooled by nonsense
-    // like "class C<T> extends C<List<T>> {}"
-    List<InterfaceType> result = <InterfaceType>[];
-    Set<ClassElement> classesSeen = new HashSet<ClassElement>();
-    List<InterfaceType> typesToVisit = <InterfaceType>[type];
-    while (typesToVisit.isNotEmpty) {
-      InterfaceType nextType = typesToVisit.removeLast();
-      if (!classesSeen.add(nextType.element)) {
-        // Class had already been seen, so ignore this type.
-        continue;
-      }
-      result.add(nextType);
-      // typesToVisit is a stack, so push on the interfaces first, then the
-      // superclass, then the mixins.  This will ensure that they are visited
-      // in the reverse order.
-      typesToVisit.addAll(nextType.interfaces);
-      if (nextType.superclass != null) {
-        typesToVisit.add(nextType.superclass);
-      }
-      typesToVisit.addAll(nextType.mixins);
-    }
-    return result;
-  }
-
-  /**
-   * Add suggestions for the visible members in the given interface
-   */
-  static void suggestionsFor(DartCompletionRequest request, DartType type,
-      {bool isSuper: false, String containingMethodName: null}) {
-    CompilationUnit compilationUnit =
-        request.target.containingNode.getAncestor((n) => n is CompilationUnit);
-    CompilationUnitElement unitElem = compilationUnit.element;
-    if (unitElem == null) {
-      engine.AnalysisEngine.instance.logger
-          .logInformation('Completion expected resolved AST');
-      return;
-    }
-    LibraryElement library = unitElem.library;
-    if (type is DynamicTypeImpl) {
-      type = request.cache.objectClassElement.type;
-    }
-    if (type is InterfaceType) {
-      new InterfaceTypeSuggestionBuilder(request)
-          ._buildSuggestions(type, library, isSuper, containingMethodName);
-    }
-  }
-}
-
-/**
- * This class visits elements in a library and provides suggestions based upon
- * the visible members in that library. Clients should call
- * [LibraryElementSuggestionBuilder.suggestionsFor].
- */
-class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
-    with ElementSuggestionBuilder {
-  final DartCompletionRequest request;
-  final CompletionSuggestionKind kind;
-  final bool typesOnly;
-  final bool instCreation;
-
-  LibraryElementSuggestionBuilder(
-      this.request, this.kind, this.typesOnly, this.instCreation);
-
-  @override
-  visitClassElement(ClassElement element) {
-    if (instCreation) {
-      element.visitChildren(this);
-    } else {
-      addSuggestion(element);
-    }
-  }
-
-  @override
-  visitCompilationUnitElement(CompilationUnitElement element) {
-    element.visitChildren(this);
-    LibraryElement containingLibrary = element.library;
-    if (containingLibrary != null) {
-      for (var lib in containingLibrary.exportedLibraries) {
-        lib.visitChildren(this);
-      }
-    }
-  }
-
-  @override
-  visitConstructorElement(ConstructorElement element) {
-    if (instCreation) {
-      ClassElement classElem = element.enclosingElement;
-      if (classElem != null) {
-        String prefix = classElem.name;
-        if (prefix != null && prefix.length > 0) {
-          addSuggestion(element, prefix: prefix);
-        }
-      }
-    }
-  }
-
-  @override
-  visitElement(Element element) {
-    // ignored
-  }
-
-  @override
-  visitFunctionElement(FunctionElement element) {
-    if (!typesOnly) {
-      addSuggestion(element);
-    }
-  }
-
-  @override
-  visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    if (!instCreation) {
-      addSuggestion(element);
-    }
-  }
-
-  @override
-  visitTopLevelVariableElement(TopLevelVariableElement element) {
-    if (!typesOnly) {
-      addSuggestion(element);
-    }
-  }
-
-  /**
-   * Add suggestions for the visible members in the given library
-   */
-  static void suggestionsFor(
-      DartCompletionRequest request,
-      CompletionSuggestionKind kind,
-      LibraryElement library,
-      bool typesOnly,
-      bool instCreation) {
-    if (library != null) {
-      library.visitChildren(new LibraryElementSuggestionBuilder(
-          request, kind, typesOnly, instCreation));
-    }
-  }
-}
-
-/**
- * This class visits elements in a class and provides suggestions based upon
- * the visible named constructors in that class.
- */
-class NamedConstructorSuggestionBuilder extends GeneralizingElementVisitor
-    with ElementSuggestionBuilder
-    implements SuggestionBuilder {
-  final DartCompletionRequest request;
-
-  NamedConstructorSuggestionBuilder(this.request);
-
-  @override
-  CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
-  @override
-  bool computeFast(AstNode node) {
-    return false;
-  }
-
-  @override
-  Future<bool> computeFull(AstNode node) {
-    if (node is SimpleIdentifier) {
-      node = node.parent;
-    }
-    if (node is ConstructorName) {
-      TypeName typeName = node.type;
-      if (typeName != null) {
-        DartType type = typeName.type;
-        if (type != null) {
-          if (type.element is ClassElement) {
-            type.element.accept(this);
-          }
-          return new Future.value(true);
-        }
-      }
-    }
-    return new Future.value(false);
-  }
-
-  @override
-  visitClassElement(ClassElement element) {
-    element.visitChildren(this);
-  }
-
-  @override
-  visitConstructorElement(ConstructorElement element) {
-    addSuggestion(element);
-  }
-
-  @override
-  visitElement(Element element) {
-    // ignored
-  }
-}
-
-/**
- * This class visits elements in a class and provides suggestions based upon
- * the visible static members in that class. Clients should call
- * [StaticClassElementSuggestionBuilder.suggestionsFor].
- */
-class StaticClassElementSuggestionBuilder extends GeneralizingElementVisitor
-    with ElementSuggestionBuilder {
-  final DartCompletionRequest request;
-
-  StaticClassElementSuggestionBuilder(this.request);
-
-  @override
-  CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
-  @override
-  visitClassElement(ClassElement element) {
-    element.visitChildren(this);
-    element.allSupertypes.forEach((InterfaceType type) {
-      type.element.visitChildren(this);
-    });
-  }
-
-  @override
-  visitElement(Element element) {
-    // ignored
-  }
-
-  @override
-  visitFieldElement(FieldElement element) {
-    if (!element.isStatic) {
-      return;
-    }
-    addSuggestion(element);
-  }
-
-  @override
-  visitMethodElement(MethodElement element) {
-    if (!element.isStatic) {
-      return;
-    }
-    if (element.isOperator) {
-      return;
-    }
-    addSuggestion(element);
-  }
-
-  @override
-  visitPropertyAccessorElement(PropertyAccessorElement element) {
-    if (!element.isStatic) {
-      return;
-    }
-    addSuggestion(element);
-  }
-
-  /**
-   * Add suggestions for the visible members in the given class
-   */
-  static void suggestionsFor(DartCompletionRequest request, Element element) {
-    if (element == DynamicElementImpl.instance) {
-      element = request.cache.objectClassElement;
-    }
-    if (element is ClassElement) {
-      return element.accept(new StaticClassElementSuggestionBuilder(request));
-    }
-  }
-}
-
-/**
- * Common interface implemented by suggestion builders.
- */
-abstract class SuggestionBuilder {
-  /**
-   * Compute suggestions and return `true` if building is complete,
-   * or `false` if [computeFull] should be called.
-   */
-  bool computeFast(AstNode node);
-
-  /**
-   * Return a future that computes the suggestions given a fully resolved AST.
-   * The future returns `true` if suggestions were added, else `false`.
-   */
-  Future<bool> computeFull(AstNode node);
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/uri_contributor.dart
deleted file mode 100644
index c6b20d3..0000000
--- a/pkg/analysis_server/lib/src/services/completion/uri_contributor.dart
+++ /dev/null
@@ -1,202 +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 services.completion.contributor.dart.importuri;
-
-import 'dart:async';
-import 'dart:core' hide Resource;
-
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:path/path.dart' show posix;
-import 'package:path/src/context.dart';
-
-import '../../protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind;
-
-/**
- * A contributor for calculating uri suggestions
- * for import and part directives.
- */
-class UriContributor extends DartCompletionContributor {
-  _UriSuggestionBuilder builder;
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    builder = new _UriSuggestionBuilder(request);
-    return builder.computeFast(request.target.containingNode);
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    return new Future.value(false);
-  }
-}
-
-class _UriSuggestionBuilder extends SimpleAstVisitor {
-  final DartCompletionRequest request;
-
-  _UriSuggestionBuilder(this.request);
-
-  bool computeFast(AstNode node) {
-    node.accept(this);
-    return true;
-  }
-
-  @override
-  visitExportDirective(ExportDirective node) {
-    visitNamespaceDirective(node);
-  }
-
-  @override
-  visitImportDirective(ImportDirective node) {
-    visitNamespaceDirective(node);
-  }
-
-  visitNamespaceDirective(NamespaceDirective node) {
-    StringLiteral uri = node.uri;
-    if (uri is SimpleStringLiteral) {
-      int offset = request.offset;
-      if (uri.offset < offset &&
-          (offset < uri.end || offset == uri.offset + 1)) {
-        // Handle degenerate case where import or export is only line in file
-        // and there is no semicolon
-        visitSimpleStringLiteral(uri);
-      }
-    }
-  }
-
-  @override
-  visitSimpleStringLiteral(SimpleStringLiteral node) {
-    AstNode parent = node.parent;
-    if (parent is NamespaceDirective && parent.uri == node) {
-      String partialUri = _extractPartialUri(node);
-      if (partialUri != null) {
-        _addDartSuggestions();
-        _addPackageSuggestions(partialUri);
-        _addFileSuggestions(partialUri);
-      }
-    } else if (parent is PartDirective && parent.uri == node) {
-      String partialUri = _extractPartialUri(node);
-      if (partialUri != null) {
-        _addFileSuggestions(partialUri);
-      }
-    }
-  }
-
-  void _addDartSuggestions() {
-    _addSuggestion('dart:');
-    SourceFactory factory = request.context.sourceFactory;
-    for (SdkLibrary lib in factory.dartSdk.sdkLibraries) {
-      if (!lib.isInternal && !lib.isImplementation) {
-        if (!lib.shortName.startsWith('dart:_')) {
-          _addSuggestion(lib.shortName,
-              relevance: lib.shortName == 'dart:core'
-                  ? DART_RELEVANCE_LOW
-                  : DART_RELEVANCE_DEFAULT);
-        }
-      }
-    }
-  }
-
-  void _addFileSuggestions(String partialUri) {
-    ResourceProvider resProvider = request.resourceProvider;
-    Context resContext = resProvider.pathContext;
-    Source source = request.source;
-
-    String parentUri;
-    if ((partialUri.endsWith('/'))) {
-      parentUri = partialUri;
-    } else {
-      parentUri = posix.dirname(partialUri);
-      if (parentUri != '.' && !parentUri.endsWith('/')) {
-        parentUri = '$parentUri/';
-      }
-    }
-    String uriPrefix = parentUri == '.' ? '' : parentUri;
-
-    String dirPath = resContext.normalize(parentUri);
-    if (resContext.isRelative(dirPath)) {
-      String sourceDirPath = resContext.dirname(source.fullName);
-      if (resContext.isAbsolute(sourceDirPath)) {
-        dirPath = resContext.join(sourceDirPath, dirPath);
-      } else {
-        return;
-      }
-    }
-
-    Resource dir = resProvider.getResource(dirPath);
-    if (dir is Folder) {
-      for (Resource child in dir.getChildren()) {
-        String completion;
-        if (child is Folder) {
-          completion = '$uriPrefix${child.shortName}/';
-        } else {
-          completion = '$uriPrefix${child.shortName}';
-        }
-        if (completion != source.shortName) {
-          _addSuggestion(completion);
-        }
-      }
-    }
-  }
-
-  void _addPackageFolderSuggestions(
-      String partial, String prefix, Folder folder) {
-    for (Resource child in folder.getChildren()) {
-      if (child is Folder) {
-        String childPrefix = '$prefix${child.shortName}/';
-        _addSuggestion(childPrefix);
-        if (partial.startsWith(childPrefix)) {
-          _addPackageFolderSuggestions(partial, childPrefix, child);
-        }
-      } else {
-        _addSuggestion('$prefix${child.shortName}');
-      }
-    }
-  }
-
-  void _addPackageSuggestions(String partial) {
-    SourceFactory factory = request.context.sourceFactory;
-    Map<String, List<Folder>> packageMap = factory.packageMap;
-    if (packageMap != null) {
-      _addSuggestion('package:');
-      packageMap.forEach((String pkgName, List<Folder> folders) {
-        String prefix = 'package:$pkgName/';
-        _addSuggestion(prefix);
-        for (Folder folder in folders) {
-          if (folder.exists) {
-            _addPackageFolderSuggestions(partial, prefix, folder);
-          }
-        }
-      });
-    }
-  }
-
-  void _addSuggestion(String completion,
-      {int relevance: DART_RELEVANCE_DEFAULT}) {
-    request.addSuggestion(new CompletionSuggestion(
-        CompletionSuggestionKind.IMPORT,
-        relevance,
-        completion,
-        completion.length,
-        0,
-        false,
-        false));
-  }
-
-  String _extractPartialUri(SimpleStringLiteral node) {
-    if (request.offset < node.contentsOffset) {
-      return null;
-    }
-    String partial = node.literal.lexeme.substring(
-        node.contentsOffset - node.offset, request.offset - node.offset);
-    request.replacementOffset = node.contentsOffset;
-    request.replacementLength = node.contentsEnd - node.contentsOffset;
-    return partial;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 45ad25f..f4c51be 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -9,21 +9,28 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'dart:async';
 
 /**
  * Compute and return the assists available at the given selection (described by
  * the [offset] and [length]) in the given [source]. The source was analyzed in
- * the given [context]. The [plugin] is used to get the list of assist
+ * the given [analysisContext]. The [plugin] is used to get the list of assist
  * contributors.
  */
-List<Assist> computeAssists(ServerPlugin plugin, AnalysisContext context,
-    Source source, int offset, int length) {
+Future<List<Assist>> computeAssists(
+    ServerPlugin plugin,
+    AnalysisContext analysisContext,
+    Source source,
+    int offset,
+    int length) async {
   List<Assist> assists = <Assist>[];
   List<AssistContributor> contributors = plugin.assistContributors;
+  AssistContextImpl assistContext =
+      new AssistContextImpl(analysisContext, source, offset, length);
   for (AssistContributor contributor in contributors) {
     try {
       List<Assist> contributedAssists =
-          contributor.computeAssists(context, source, offset, length);
+          await contributor.computeAssists(assistContext);
       if (contributedAssists != null) {
         assists.addAll(contributedAssists);
       }
@@ -38,6 +45,26 @@
 }
 
 /**
+ * The implementation of [AssistContext].
+ */
+class AssistContextImpl implements AssistContext {
+  @override
+  final AnalysisContext analysisContext;
+
+  @override
+  final Source source;
+
+  @override
+  final int selectionOffset;
+
+  @override
+  final int selectionLength;
+
+  AssistContextImpl(this.analysisContext, this.source, this.selectionOffset,
+      this.selectionLength);
+}
+
+/**
  * An enumeration of possible assist kinds.
  */
 class DartAssistKind {
@@ -47,6 +74,14 @@
       const AssistKind('ADD_TYPE_ANNOTATION', 30, "Add type annotation");
   static const ASSIGN_TO_LOCAL_VARIABLE = const AssistKind(
       'ASSIGN_TO_LOCAL_VARIABLE', 30, "Assign value to new local variable");
+  static const CONVERT_DOCUMENTATION_INTO_BLOCK = const AssistKind(
+      'CONVERT_DOCUMENTATION_INTO_BLOCK',
+      30,
+      "Convert into block documentation comment");
+  static const CONVERT_DOCUMENTATION_INTO_LINE = const AssistKind(
+      'CONVERT_DOCUMENTATION_INTO_LINE',
+      30,
+      "Convert into line documentation comment");
   static const CONVERT_INTO_BLOCK_BODY = const AssistKind(
       'CONVERT_INTO_BLOCK_BODY', 30, "Convert into block body");
   static const CONVERT_INTO_EXPRESSION_BODY = const AssistKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index d83ca2f..a683638 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -4,6 +4,7 @@
 
 library services.src.correction.assist;
 
+import 'dart:async';
 import 'dart:collection';
 
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
@@ -16,8 +17,9 @@
 import 'package:analysis_server/src/services/correction/statement_analyzer.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -30,38 +32,49 @@
  * The computer for Dart assists.
  */
 class AssistProcessor {
+  AnalysisContext analysisContext;
+
   Source source;
   String file;
   int fileStamp;
-  final CompilationUnit unit;
-  final int selectionOffset;
-  final int selectionLength;
-  AnalysisContext context;
+
+  CompilationUnit unit;
   CompilationUnitElement unitElement;
+
   LibraryElement unitLibraryElement;
   String unitLibraryFile;
   String unitLibraryFolder;
 
+  int selectionOffset;
+  int selectionLength;
+  int selectionEnd;
+
   final List<Assist> assists = <Assist>[];
   final Map<String, LinkedEditGroup> linkedPositionGroups =
       <String, LinkedEditGroup>{};
   Position exitPosition = null;
 
-  int selectionEnd;
   CorrectionUtils utils;
   AstNode node;
 
   SourceChange change = new SourceChange('<message>');
 
-  AssistProcessor(this.unit, this.selectionOffset, this.selectionLength) {
-    source = unit.element.source;
-    file = source.fullName;
-    unitElement = unit.element;
-    context = unitElement.context;
-    unitLibraryElement = unitElement.library;
+  AssistProcessor(DartAssistContext dartContext) {
+    analysisContext = dartContext.analysisContext;
+    // source
+    source = dartContext.source;
+    file = dartContext.source.fullName;
+    fileStamp = analysisContext.getModificationStamp(source);
+    // unit
+    unit = dartContext.unit;
+    unitElement = dartContext.unit.element;
+    // library
+    unitLibraryElement = dartContext.unit.element.library;
     unitLibraryFile = unitLibraryElement.source.fullName;
     unitLibraryFolder = dirname(unitLibraryFile);
-    fileStamp = unitElement.context.getModificationStamp(source);
+    // selection
+    selectionOffset = dartContext.selectionOffset;
+    selectionLength = dartContext.selectionLength;
     selectionEnd = selectionOffset + selectionLength;
   }
 
@@ -70,7 +83,7 @@
    */
   String get eol => utils.endOfLine;
 
-  List<Assist> compute() {
+  Future<List<Assist>> compute() async {
     utils = new CorrectionUtils(unit);
     node = new NodeLocator(selectionOffset, selectionEnd).searchWithin(unit);
     if (node == null) {
@@ -81,6 +94,8 @@
     _addProposal_addTypeAnnotation_SimpleFormalParameter();
     _addProposal_addTypeAnnotation_VariableDeclaration();
     _addProposal_assignToLocalVariable();
+    _addProposal_convertDocumentationIntoBlock();
+    _addProposal_convertDocumentationIntoLine();
     _addProposal_convertToBlockFunctionBody();
     _addProposal_convertToExpressionFunctionBody();
     _addProposal_convertToForIndexLoop();
@@ -388,6 +403,80 @@
     _addAssist(DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE, []);
   }
 
+  void _addProposal_convertDocumentationIntoBlock() {
+    Comment comment = node.getAncestor((n) => n is Comment);
+    if (comment != null && comment.isDocumentation) {
+      String prefix = utils.getNodePrefix(comment);
+      SourceBuilder sb = new SourceBuilder(file, comment.offset);
+      sb.append('/**');
+      sb.append(eol);
+      for (Token token in comment.tokens) {
+        if (token is DocumentationCommentToken &&
+            token.type == TokenType.SINGLE_LINE_COMMENT) {
+          sb.append(prefix);
+          sb.append(' *');
+          sb.append(token.lexeme.substring('///'.length));
+          sb.append(eol);
+        } else {
+          return;
+        }
+      }
+      sb.append(prefix);
+      sb.append(' */');
+      _insertBuilder(sb, comment.length);
+    }
+    // add proposal
+    _addAssist(DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK, []);
+  }
+
+  void _addProposal_convertDocumentationIntoLine() {
+    Comment comment = node.getAncestor((n) => n is Comment);
+    if (comment != null && comment.isDocumentation) {
+      if (comment.tokens.length == 1) {
+        Token token = comment.tokens.first;
+        if (token.type == TokenType.MULTI_LINE_COMMENT) {
+          String text = token.lexeme;
+          List<String> lines = text.split('\n');
+          String prefix = utils.getNodePrefix(comment);
+          SourceBuilder sb = new SourceBuilder(file, comment.offset);
+          bool firstLine = true;
+          String linePrefix = '';
+          for (String line in lines) {
+            if (firstLine) {
+              firstLine = false;
+              String expectedPrefix = '/**';
+              if (!line.startsWith(expectedPrefix)) {
+                return;
+              }
+              line = line.substring(expectedPrefix.length).trim();
+              if (line.isNotEmpty) {
+                sb.append('/// ');
+                sb.append(line);
+                linePrefix = eol + prefix;
+              }
+            } else {
+              if (line.startsWith(prefix + ' */')) {
+                break;
+              }
+              String expectedPrefix = prefix + ' * ';
+              if (!line.startsWith(expectedPrefix)) {
+                return;
+              }
+              line = line.substring(expectedPrefix.length).trim();
+              sb.append(linePrefix);
+              sb.append('/// ');
+              sb.append(line);
+              linePrefix = eol + prefix;
+            }
+          }
+          _insertBuilder(sb, comment.length);
+        }
+      }
+    }
+    // add proposal
+    _addAssist(DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE, []);
+  }
+
   void _addProposal_convertToBlockFunctionBody() {
     FunctionBody body = getEnclosingFunctionBody();
     // prepare expression body
@@ -579,7 +668,7 @@
     // iterable should be List
     {
       DartType iterableType = iterable.bestType;
-      InterfaceType listType = context.typeProvider.listType;
+      InterfaceType listType = analysisContext.typeProvider.listType;
       if (iterableType is! InterfaceType ||
           iterableType.element != listType.element) {
         _coverageMarker();
@@ -811,19 +900,19 @@
 
   void _addProposal_encapsulateField() {
     // find FieldDeclaration
-    FieldDeclaration fieldDeclaraton =
+    FieldDeclaration fieldDeclaration =
         node.getAncestor((x) => x is FieldDeclaration);
-    if (fieldDeclaraton == null) {
+    if (fieldDeclaration == null) {
       _coverageMarker();
       return;
     }
     // not interesting for static
-    if (fieldDeclaraton.isStatic) {
+    if (fieldDeclaration.isStatic) {
       _coverageMarker();
       return;
     }
     // has a parse error
-    VariableDeclarationList variableList = fieldDeclaraton.fields;
+    VariableDeclarationList variableList = fieldDeclaration.fields;
     if (variableList.keyword == null && variableList.type == null) {
       _coverageMarker();
       return;
@@ -856,7 +945,7 @@
     // rename field
     _addReplaceEdit(rangeNode(nameNode), '_$name');
     // update references in constructors
-    ClassDeclaration classDeclaration = fieldDeclaraton.parent;
+    ClassDeclaration classDeclaration = fieldDeclaration.parent;
     for (ClassMember member in classDeclaration.members) {
       if (member is ConstructorDeclaration) {
         for (FormalParameter parameter in member.parameters.parameters) {
@@ -874,10 +963,10 @@
         variableList.type != null ? _getNodeText(variableList.type) + ' ' : '';
     String getterCode = '$eol2  ${typeNameCode}get $name => _$name;';
     String setterCode = '$eol2'
-        '  void set $name(${typeNameCode}$name) {$eol'
+        '  void set $name($typeNameCode$name) {$eol'
         '    _$name = $name;$eol'
         '  }';
-    _addInsertEdit(fieldDeclaraton.end, getterCode + setterCode);
+    _addInsertEdit(fieldDeclaration.end, getterCode + setterCode);
     // add proposal
     _addAssist(DartAssistKind.ENCAPSULATE_FIELD, []);
   }
@@ -1163,6 +1252,10 @@
     // prepare outer "if" statement
     AstNode parent = targetIfStatement.parent;
     if (parent is Block) {
+      if ((parent as Block).statements.length != 1) {
+        _coverageMarker();
+        return;
+      }
       parent = parent.parent;
     }
     if (parent is! IfStatement) {
@@ -2047,9 +2140,8 @@
  */
 class DefaultAssistContributor extends DartAssistContributor {
   @override
-  List<Assist> internalComputeAssists(
-      CompilationUnit unit, int offset, int length) {
-    AssistProcessor processor = new AssistProcessor(unit, offset, length);
+  Future<List<Assist>> internalComputeAssists(DartAssistContext context) {
+    AssistProcessor processor = new AssistProcessor(context);
     return processor.compute();
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 3fe6567..7525b74f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -4,6 +4,8 @@
 
 library analysis_server.src.services.correction.fix;
 
+import 'dart:async';
+
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -17,14 +19,17 @@
  * reported after it's source was analyzed in the given [context]. The [plugin]
  * is used to get the list of fix contributors.
  */
-List<Fix> computeFixes(ServerPlugin plugin, ResourceProvider resourceProvider,
-    AnalysisContext context, AnalysisError error) {
+Future<List<Fix>> computeFixes(
+    ServerPlugin plugin,
+    ResourceProvider resourceProvider,
+    AnalysisContext context,
+    AnalysisError error) async {
   List<Fix> fixes = <Fix>[];
   List<FixContributor> contributors = plugin.fixContributors;
+  FixContext fixContext = new FixContextImpl(resourceProvider, context, error);
   for (FixContributor contributor in contributors) {
     try {
-      List<Fix> contributedFixes =
-          contributor.computeFixes(resourceProvider, context, error);
+      List<Fix> contributedFixes = await contributor.computeFixes(fixContext);
       if (contributedFixes != null) {
         fixes.addAll(contributedFixes);
       }
@@ -72,6 +77,7 @@
     errorCode ==
         CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT ||
     errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST ||
+    errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE ||
     errorCode == HintCode.DEAD_CODE ||
     errorCode == HintCode.DIVISION_OPTIMIZATION ||
     errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL ||
@@ -121,6 +127,8 @@
   static const CHANGE_TO = const FixKind('CHANGE_TO', 49, "Change to '{0}'");
   static const CHANGE_TO_STATIC_ACCESS = const FixKind(
       'CHANGE_TO_STATIC_ACCESS', 50, "Change access to static using '{0}'");
+  static const CHANGE_TYPE_ANNOTATION = const FixKind(
+      'CHANGE_TYPE_ANNOTATION', 50, "Change '{0}' to '{1}' type annotation");
   static const CREATE_CLASS =
       const FixKind('CREATE_CLASS', 50, "Create class '{0}'");
   static const CREATE_CONSTRUCTOR =
@@ -161,6 +169,8 @@
       const FixKind('MAKE_CLASS_ABSTRACT', 50, "Make class '{0}' abstract");
   static const REMOVE_DEAD_CODE =
       const FixKind('REMOVE_DEAD_CODE', 50, "Remove dead code");
+  static const MAKE_FIELD_NOT_FINAL =
+      const FixKind('MAKE_FIELD_NOT_FINAL', 50, "Make field '{0}' not final");
   static const REMOVE_PARAMETERS_IN_GETTER_DECLARATION = const FixKind(
       'REMOVE_PARAMETERS_IN_GETTER_DECLARATION',
       50,
@@ -169,8 +179,8 @@
       'REMOVE_PARENTHESIS_IN_GETTER_INVOCATION',
       50,
       "Remove parentheses in getter invocation");
-  static const REMOVE_UNNECASSARY_CAST =
-      const FixKind('REMOVE_UNNECASSARY_CAST', 50, "Remove unnecessary cast");
+  static const REMOVE_UNNECESSARY_CAST =
+      const FixKind('REMOVE_UNNECESSARY_CAST', 50, "Remove unnecessary cast");
   static const REMOVE_UNUSED_CATCH_CLAUSE =
       const FixKind('REMOVE_UNUSED_CATCH', 50, "Remove unused 'catch' clause");
   static const REMOVE_UNUSED_CATCH_STACK = const FixKind(
@@ -187,6 +197,10 @@
       'REPLACE_RETURN_TYPE_FUTURE',
       50,
       "Return 'Future' from 'async' function");
+  static const REPLACE_WITH_NULL_AWARE = const FixKind(
+      'REPLACE_WITH_NULL_AWARE',
+      50,
+      "Replace the '.' with a '?.' in the invocation");
   static const USE_CONST = const FixKind('USE_CONST', 50, "Change to constant");
   static const USE_EFFECTIVE_INTEGER_DIVISION = const FixKind(
       'USE_EFFECTIVE_INTEGER_DIVISION',
@@ -197,3 +211,24 @@
   static const USE_NOT_EQ_NULL =
       const FixKind('USE_NOT_EQ_NULL', 50, "Use != null instead of 'is! Null'");
 }
+
+/**
+ * The implementation of [FixContext].
+ */
+class FixContextImpl implements FixContext {
+  @override
+  final ResourceProvider resourceProvider;
+
+  @override
+  final AnalysisContext analysisContext;
+
+  @override
+  final AnalysisError error;
+
+  FixContextImpl(this.resourceProvider, this.analysisContext, this.error);
+
+  FixContextImpl.from(FixContext other)
+      : resourceProvider = other.resourceProvider,
+        analysisContext = other.analysisContext,
+        error = other.error;
+}
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 a6f3099..fa16435 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -4,6 +4,7 @@
 
 library analysis_server.src.services.correction.fix_internal;
 
+import 'dart:async';
 import 'dart:collection';
 import 'dart:core' hide Resource;
 
@@ -23,9 +24,13 @@
 import 'package:analysis_server/src/services/correction/strings.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -34,6 +39,7 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/dart.dart';
 import 'package:path/path.dart';
 
 /**
@@ -42,13 +48,26 @@
 typedef bool ElementPredicate(Element argument);
 
 /**
+ * The implementation of [DartFixContext].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class DartFixContextImpl extends FixContextImpl implements DartFixContext {
+  /**
+   * The [CompilationUnit] to compute fixes in.
+   */
+  final CompilationUnit unit;
+
+  DartFixContextImpl(FixContext fixContext, this.unit) : super.from(fixContext);
+}
+
+/**
  * A [FixContributor] that provides the default set of fixes.
  */
 class DefaultFixContributor extends DartFixContributor {
   @override
-  List<Fix> internalComputeFixes(ResourceProvider resourceProvider,
-      CompilationUnit unit, AnalysisError error) {
-    FixProcessor processor = new FixProcessor(resourceProvider, unit, error);
+  Future<List<Fix>> internalComputeFixes(DartFixContext context) {
+    FixProcessor processor = new FixProcessor(context);
     return processor.compute();
   }
 }
@@ -59,9 +78,9 @@
 class FixProcessor {
   static const int MAX_LEVENSHTEIN_DISTANCE = 3;
 
-  final ResourceProvider resourceProvider;
-  final CompilationUnit unit;
-  final AnalysisError error;
+  ResourceProvider resourceProvider;
+  CompilationUnit unit;
+  AnalysisError error;
   AnalysisContext context;
   String file;
   int fileStamp;
@@ -87,15 +106,22 @@
   AstNode node;
   AstNode coveredNode;
 
-  FixProcessor(this.resourceProvider, this.unit, this.error) {
+  FixProcessor(DartFixContext dartContext) {
+    resourceProvider = dartContext.resourceProvider;
+    context = dartContext.analysisContext;
+    // unit
+    unit = dartContext.unit;
     unitElement = unit.element;
-    context = unitElement.context;
     unitSource = unitElement.source;
+    // file
     file = unitSource.fullName;
     fileStamp = context.getModificationStamp(unitSource);
+    // library
     unitLibraryElement = unitElement.library;
     unitLibraryFile = unitLibraryElement.source.fullName;
     unitLibraryFolder = dirname(unitLibraryFile);
+    // error
+    error = dartContext.error;
   }
 
   DartType get coreTypeBool => _getCoreType('bool');
@@ -105,15 +131,15 @@
    */
   String get eol => utils.endOfLine;
 
-  List<Fix> compute() {
+  Future<List<Fix>> compute() async {
     utils = new CorrectionUtils(unit);
     errorOffset = error.offset;
     errorLength = error.length;
     errorEnd = errorOffset + errorLength;
     errorRange = new SourceRange(errorOffset, errorLength);
-    node = new NodeLocator(errorOffset).searchWithin(unit);
-    coveredNode = new NodeLocator(errorOffset, errorOffset + errorLength)
-        .searchWithin(unit);
+    node = new NodeLocator2(errorOffset).searchWithin(unit);
+    coveredNode =
+        new NodeLocator2(errorOffset, errorEnd - 1).searchWithin(unit);
     // analyze ErrorCode
     ErrorCode errorCode = error.errorCode;
     if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) {
@@ -159,6 +185,9 @@
       _addFix_createPartUri();
       _addFix_replaceImportUri();
     }
+    if (errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE) {
+      _addFix_canBeNullAfterNullAware();
+    }
     if (errorCode == HintCode.DEAD_CODE) {
       _addFix_removeDeadCode();
     }
@@ -201,6 +230,9 @@
     if (errorCode == ParserErrorCode.VAR_AS_TYPE_NAME) {
       _addFix_replaceVarWithDynamic();
     }
+    if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL) {
+      _addFix_makeFieldNotFinal();
+    }
     if (errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER) {
       _addFix_makeEnclosingClassAbstract();
     }
@@ -211,15 +243,19 @@
     if (errorCode == StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR) {
       _addFix_createConstructor_named();
     }
-    if (errorCode == StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE ||
+    if (errorCode ==
+            StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE ||
         errorCode ==
             StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO ||
         errorCode ==
-            StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE ||
+            StaticWarningCode
+                .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE ||
         errorCode ==
-            StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR ||
+            StaticWarningCode
+                .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR ||
         errorCode ==
-            StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) {
+            StaticWarningCode
+                .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) {
       // make class abstract
       _addFix_makeEnclosingClassAbstract();
       // implement methods
@@ -268,6 +304,9 @@
       _addFix_useStaticAccess_method();
       _addFix_useStaticAccess_property();
     }
+    if (errorCode == StaticTypeWarningCode.INVALID_ASSIGNMENT) {
+      _addFix_changeTypeAnnotation();
+    }
     if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) {
       _addFix_removeParentheses_inGetterInvocation();
     }
@@ -356,61 +395,66 @@
   }
 
   void _addFix_addMissingParameter() {
-    if (node is SimpleIdentifier && node.parent is MethodInvocation) {
+    if (node is ArgumentList && node.parent is MethodInvocation) {
+      ArgumentList argumentList = node;
       MethodInvocation invocation = node.parent;
       SimpleIdentifier methodName = invocation.methodName;
-      ArgumentList argumentList = invocation.argumentList;
-      if (methodName == node && argumentList != null) {
-        Element targetElement = methodName.bestElement;
-        List<Expression> arguments = argumentList.arguments;
-        if (targetElement is ExecutableElement) {
-          List<ParameterElement> parameters = targetElement.parameters;
-          int numParameters = parameters.length;
-          Expression argument = arguments[numParameters];
-          // prepare target
-          int targetOffset;
-          if (numParameters != 0) {
-            ParameterElement parameterElement = parameters.last;
-            AstNode parameterNode = parameterElement.computeNode();
-            targetOffset = parameterNode.end;
+      Element targetElement = methodName.bestElement;
+      List<Expression> arguments = argumentList.arguments;
+      if (targetElement is ExecutableElement) {
+        List<ParameterElement> parameters = targetElement.parameters;
+        int numParameters = parameters.length;
+        Iterable<ParameterElement> requiredParameters = parameters
+            .takeWhile((p) => p.parameterKind == ParameterKind.REQUIRED);
+        Iterable<ParameterElement> optionalParameters = parameters
+            .skipWhile((p) => p.parameterKind == ParameterKind.REQUIRED);
+        int numRequired = requiredParameters.length;
+        Expression argument = arguments[numRequired];
+        // prepare target
+        int targetOffset;
+        if (numRequired != 0) {
+          AstNode parameterNode = requiredParameters.last.computeNode();
+          targetOffset = parameterNode.end;
+        } else {
+          AstNode targetNode = targetElement.computeNode();
+          if (targetNode is FunctionDeclaration) {
+            FunctionExpression function = targetNode.functionExpression;
+            targetOffset = function.parameters.leftParenthesis.end;
+          } else if (targetNode is MethodDeclaration) {
+            targetOffset = targetNode.parameters.leftParenthesis.end;
           } else {
-            AstNode targetNode = targetElement.computeNode();
-            if (targetNode is FunctionDeclaration) {
-              FunctionExpression function = targetNode.functionExpression;
-              targetOffset = function.parameters.leftParenthesis.end;
-            } else if (targetNode is MethodDeclaration) {
-              targetOffset = targetNode.parameters.leftParenthesis.end;
-            } else {
-              return;
-            }
+            return;
           }
-          String targetFile = targetElement.source.fullName;
-          // required
-          {
-            SourceBuilder sb = new SourceBuilder(targetFile, targetOffset);
-            // append source
-            if (numParameters != 0) {
-              sb.append(', ');
-            }
-            _appendParameterForArgument(sb, numParameters, argument);
-            // add proposal
-            _insertBuilder(sb, targetElement);
-            _addFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, []);
+        }
+        String targetFile = targetElement.source.fullName;
+        // required
+        {
+          SourceBuilder sb = new SourceBuilder(targetFile, targetOffset);
+          // append source
+          if (numRequired != 0) {
+            sb.append(', ');
           }
-          // optional positional
-          {
-            SourceBuilder sb = new SourceBuilder(targetFile, targetOffset);
-            // append source
-            if (numParameters != 0) {
-              sb.append(', ');
-            }
-            sb.append('[');
-            _appendParameterForArgument(sb, numParameters, argument);
-            sb.append(']');
-            // add proposal
-            _insertBuilder(sb, targetElement);
-            _addFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL, []);
+          _appendParameterForArgument(sb, numRequired, argument);
+          if (numRequired != numParameters) {
+            sb.append(', ');
           }
+          // add proposal
+          _insertBuilder(sb, targetElement);
+          _addFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, []);
+        }
+        // optional positional
+        if (optionalParameters.isEmpty) {
+          SourceBuilder sb = new SourceBuilder(targetFile, targetOffset);
+          // append source
+          if (numRequired != 0) {
+            sb.append(', ');
+          }
+          sb.append('[');
+          _appendParameterForArgument(sb, numRequired, argument);
+          sb.append(']');
+          // add proposal
+          _insertBuilder(sb, targetElement);
+          _addFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL, []);
         }
       }
     }
@@ -421,11 +465,7 @@
       PartDirective directive = node.parent;
       Source partSource = directive.source;
       CompilationUnit partUnit;
-      if (AnalysisEngine.instance.useTaskModel) {
-        partUnit = context.getResolvedCompilationUnit2(partSource, partSource);
-      } else {
-        partUnit = context.getResolvedCompilationUnit2(partSource, unitSource);
-      }
+      partUnit = context.getResolvedCompilationUnit2(partSource, partSource);
       if (partUnit != null) {
         CorrectionUtils partUtils = new CorrectionUtils(partUnit);
         CorrectionUtils_InsertDesc desc = partUtils.getInsertDescTop();
@@ -445,6 +485,48 @@
     _addFix(DartFixKind.REPLACE_BOOLEAN_WITH_BOOL, []);
   }
 
+  void _addFix_canBeNullAfterNullAware() {
+    AstNode node = coveredNode;
+    if (node is Expression) {
+      AstNode parent = node.parent;
+      while (parent != null) {
+        if (parent is MethodInvocation && parent.target == node) {
+          _addReplaceEdit(rf.rangeToken(parent.operator), '?.');
+        } else if (parent is PropertyAccess && parent.target == node) {
+          _addReplaceEdit(rf.rangeToken(parent.operator), '?.');
+        } else {
+          break;
+        }
+        node = parent;
+        parent = node.parent;
+      }
+      _addFix(DartFixKind.REPLACE_WITH_NULL_AWARE, []);
+    }
+  }
+
+  void _addFix_changeTypeAnnotation() {
+    AstNode declaration = coveredNode.parent;
+    if (declaration is VariableDeclaration &&
+        declaration.initializer == coveredNode) {
+      AstNode variableList = declaration.parent;
+      if (variableList is VariableDeclarationList &&
+          variableList.variables.length == 1) {
+        TypeName typeNode = variableList.type;
+        if (typeNode != null) {
+          Expression initializer = coveredNode;
+          DartType newType = initializer.bestType;
+          if (newType is InterfaceType || newType is FunctionType) {
+            String newTypeSource =
+                utils.getTypeSource(newType, librariesToImport);
+            _addReplaceEdit(rf.rangeNode(typeNode), newTypeSource);
+            _addFix(DartFixKind.CHANGE_TYPE_ANNOTATION,
+                [typeNode.type.displayName, newTypeSource]);
+          }
+        }
+      }
+    }
+  }
+
   void _addFix_createClass() {
     Element prefixElement = null;
     String name = null;
@@ -576,45 +658,26 @@
   }
 
   void _addFix_createConstructor_insteadOfSyntheticDefault() {
-    TypeName typeName = null;
-    ConstructorName constructorName = null;
-    InstanceCreationExpression instanceCreation = null;
-    if (node is SimpleIdentifier) {
-      if (node.parent is TypeName) {
-        typeName = node.parent as TypeName;
-        if (typeName.name == node && typeName.parent is ConstructorName) {
-          constructorName = typeName.parent as ConstructorName;
-          // should be synthetic default constructor
-          {
-            ConstructorElement constructorElement =
-                constructorName.staticElement;
-            if (constructorElement == null ||
-                !constructorElement.isDefaultConstructor ||
-                !constructorElement.isSynthetic) {
-              return;
-            }
-          }
-          // prepare InstanceCreationExpression
-          if (constructorName.parent is InstanceCreationExpression) {
-            instanceCreation =
-                constructorName.parent as InstanceCreationExpression;
-            if (instanceCreation.constructorName != constructorName) {
-              return;
-            }
-          }
-        }
-      }
+    if (node is! ArgumentList) {
+      return;
     }
-    // do we have enough information?
-    if (instanceCreation == null) {
+    if (node.parent is! InstanceCreationExpression) {
+      return;
+    }
+    InstanceCreationExpression instanceCreation = node.parent;
+    ConstructorName constructorName = instanceCreation.constructorName;
+    // should be synthetic default constructor
+    ConstructorElement constructorElement = constructorName.staticElement;
+    if (constructorElement == null ||
+        !constructorElement.isDefaultConstructor ||
+        !constructorElement.isSynthetic) {
       return;
     }
     // prepare target
-    DartType targetType = typeName.type;
-    if (targetType is! InterfaceType) {
+    if (constructorElement.enclosingElement is! ClassElement) {
       return;
     }
-    ClassElement targetElement = targetType.element as ClassElement;
+    ClassElement targetElement = constructorElement.enclosingElement;
     String targetFile = targetElement.source.fullName;
     ClassDeclaration targetClass = getParsedClassElementNode(targetElement);
     _ConstructorLocation targetLocation =
@@ -702,6 +765,10 @@
   }
 
   void _addFix_createConstructorSuperExplicit() {
+    if (node.parent is! ConstructorDeclaration ||
+        node.parent.parent is! ClassDeclaration) {
+      return;
+    }
     ConstructorDeclaration targetConstructor =
         node.parent as ConstructorDeclaration;
     ClassDeclaration targetClassNode =
@@ -1063,7 +1130,7 @@
       Source source = importDirective.source;
       if (source != null) {
         String file = source.fullName;
-        if (isAbsolute(file)) {
+        if (isAbsolute(file) && AnalysisEngine.isDartFileName(file)) {
           String libName = _computeLibraryName(file);
           SourceEdit edit = new SourceEdit(0, 0, 'library $libName;$eol$eol');
           doSourceChange_addSourceEdit(change, context, source, edit);
@@ -1396,7 +1463,7 @@
             sdkSourceFactory.resolveUri(unitSource, libraryUri);
         // prepare LibraryElement
         LibraryElement libraryElement =
-            context.getLibraryElement(librarySource);
+            context.getResult(librarySource, LIBRARY_ELEMENT1);
         if (libraryElement == null) {
           continue;
         }
@@ -1429,7 +1496,7 @@
         }
         // prepare LibraryElement
         LibraryElement libraryElement =
-            context.getLibraryElement(librarySource);
+            context.getResult(librarySource, LIBRARY_ELEMENT8);
         if (libraryElement == null) {
           continue;
         }
@@ -1526,6 +1593,41 @@
     _addFix(DartFixKind.MAKE_CLASS_ABSTRACT, [className]);
   }
 
+  void _addFix_makeFieldNotFinal() {
+    AstNode node = this.node;
+    if (node is SimpleIdentifier &&
+        node.bestElement is PropertyAccessorElement) {
+      PropertyAccessorElement getter = node.bestElement;
+      if (getter.isGetter &&
+          getter.isSynthetic &&
+          !getter.variable.isSynthetic &&
+          getter.variable.setter == null &&
+          getter.enclosingElement is ClassElement) {
+        AstNode variable = getter.variable.computeNode();
+        if (variable is VariableDeclaration &&
+            variable.parent is VariableDeclarationList &&
+            variable.parent.parent is FieldDeclaration) {
+          VariableDeclarationList declarationList = variable.parent;
+          Token keywordToken = declarationList.keyword;
+          if (declarationList.variables.length == 1 &&
+              keywordToken is KeywordToken &&
+              keywordToken.keyword == Keyword.FINAL) {
+            if (declarationList.type != null) {
+              SourceRange range =
+                  rf.rangeStartStart(keywordToken, declarationList.type);
+              _addRemoveEdit(range);
+            } else {
+              SourceRange range = rf.rangeStartStart(keywordToken, variable);
+              _addReplaceEdit(range, 'var ');
+            }
+            String fieldName = getter.variable.displayName;
+            _addFix(DartFixKind.MAKE_FIELD_NOT_FINAL, [fieldName]);
+          }
+        }
+      }
+    }
+  }
+
   void _addFix_nonBoolCondition_addNotNull() {
     _addInsertEdit(error.offset + error.length, ' != null');
     _addFix(DartFixKind.ADD_NE_NULL, []);
@@ -1564,11 +1666,12 @@
   }
 
   void _addFix_removeParameters_inGetterDeclaration() {
-    if (node is SimpleIdentifier && node.parent is MethodDeclaration) {
-      MethodDeclaration method = node.parent as MethodDeclaration;
+    if (node is MethodDeclaration) {
+      MethodDeclaration method = node as MethodDeclaration;
+      SimpleIdentifier name = method.name;
       FunctionBody body = method.body;
-      if (method.name == node && body != null) {
-        _addReplaceEdit(rf.rangeEndStart(node, body), ' ');
+      if (name != null && body != null) {
+        _addReplaceEdit(rf.rangeEndStart(name, body), ' ');
         _addFix(DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION, []);
       }
     }
@@ -1595,7 +1698,7 @@
     _addRemoveEdit(rf.rangeEndEnd(expression, asExpression));
     _removeEnclosingParentheses(asExpression, expressionPrecedence);
     // done
-    _addFix(DartFixKind.REMOVE_UNNECASSARY_CAST, []);
+    _addFix(DartFixKind.REMOVE_UNNECESSARY_CAST, []);
   }
 
   void _addFix_removeUnusedCatchClause() {
@@ -1929,6 +2032,7 @@
     // append parameters
     sb.append('(');
     List<Expression> arguments = argumentList.arguments;
+    bool hasNamedParameters = false;
     for (int i = 0; i < arguments.length; i++) {
       Expression argument = arguments[i];
       // append separator
@@ -1936,8 +2040,15 @@
         sb.append(', ');
       }
       // append parameter
+      if (argument is NamedExpression && !hasNamedParameters) {
+        hasNamedParameters = true;
+        sb.append('{');
+      }
       _appendParameterForArgument(sb, i, argument);
     }
+    if (hasNamedParameters) {
+      sb.append('}');
+    }
   }
 
   void _addFix_undefinedMethod_useSimilar() {
@@ -2231,7 +2342,9 @@
       sb.append(' ');
     }
     // append parameter name
-    {
+    if (argument is NamedExpression) {
+      sb.append(argument.name.label.name);
+    } else {
       Set<String> excluded = new Set<String>();
       List<String> suggestions =
           _getArgumentNameSuggestions(excluded, type, argument, index);
@@ -2332,7 +2445,7 @@
       if (relPathParts[0].toLowerCase() == 'lib') {
         relPathParts.removeAt(0);
       }
-      {
+      if (relPathParts.isNotEmpty) {
         String nameWithoutExt = pathContext.withoutExtension(relPathParts.last);
         relPathParts[relPathParts.length - 1] = nameWithoutExt;
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
index 5234405..1c80559 100644
--- a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
+++ b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
@@ -5,8 +5,9 @@
 library services.src.correction.name_suggestion;
 
 import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 List<String> _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to'];
 
diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart
index 1ca99ba..f1086fc 100644
--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart
+++ b/pkg/analysis_server/lib/src/services/correction/namespace.dart
@@ -4,8 +4,8 @@
 
 library services.src.correction.namespace;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/correction/source_range.dart b/pkg/analysis_server/lib/src/services/correction/source_range.dart
index 779dde7..bf52759 100644
--- a/pkg/analysis_server/lib/src/services/correction/source_range.dart
+++ b/pkg/analysis_server/lib/src/services/correction/source_range.dart
@@ -4,8 +4,8 @@
 
 library services.src.correction.source_range_factory;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
index e7c8361..c25f77a 100644
--- a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
@@ -9,8 +9,8 @@
 import 'package:analysis_server/src/services/correction/source_range.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/correction/strings.dart b/pkg/analysis_server/lib/src/services/correction/strings.dart
index c2ea6cb..1689c7c 100644
--- a/pkg/analysis_server/lib/src/services/correction/strings.dart
+++ b/pkg/analysis_server/lib/src/services/correction/strings.dart
@@ -41,6 +41,17 @@
   return a.compareTo(b);
 }
 
+int countLeadingWhitespaces(String str) {
+  int i = 0;
+  for (; i < str.length; i++) {
+    int c = str.codeUnitAt(i);
+    if (!isWhitespace(c)) {
+      break;
+    }
+  }
+  return i;
+}
+
 /**
  * Counts how many times [sub] appears in [str].
  */
@@ -57,6 +68,17 @@
   return count;
 }
 
+int countTrailingWhitespaces(String str) {
+  int i = 0;
+  for (; i < str.length; i++) {
+    int c = str.codeUnitAt(str.length - 1 - i);
+    if (!isWhitespace(c)) {
+      break;
+    }
+  }
+  return i;
+}
+
 /**
  * Returns the number of characters common to the end of [a] and the start
  * of [b].
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index a74488f..33a3105 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -12,9 +12,9 @@
     show doSourceChange_addElementEdit;
 import 'package:analysis_server/src/services/correction/source_range.dart';
 import 'package:analysis_server/src/services/correction/strings.dart';
-import 'package:analysis_server/src/services/search/element_visitors.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -78,7 +78,7 @@
 }
 
 /**
- * Climbs up [PrefixedIdentifier] and [ProperyAccess] nodes that include [node].
+ * Climbs up [PrefixedIdentifier] and [PropertyAccess] nodes that include [node].
  */
 Expression climbPropertyAccess(AstNode node) {
   while (true) {
@@ -667,20 +667,9 @@
     AstNode enclosingNode = findNode(offset);
     Block enclosingBlock = enclosingNode.getAncestor((node) => node is Block);
     if (enclosingBlock != null) {
-      SourceRange newRange = rangeStartEnd(offset, enclosingBlock.end);
-      ExecutableElement enclosingExecutable =
-          getEnclosingExecutableElement(enclosingNode);
-      if (enclosingExecutable != null) {
-        visitChildren(enclosingExecutable, (Element element) {
-          if (element is LocalElement) {
-            SourceRange elementRange = element.visibleRange;
-            if (elementRange != null && elementRange.intersects(newRange)) {
-              conflicts.add(element.displayName);
-            }
-          }
-          return true;
-        });
-      }
+      _CollectReferencedUnprefixedNames visitor = new _CollectReferencedUnprefixedNames();
+      enclosingBlock.accept(visitor);
+      return visitor.names;
     }
     return conflicts;
   }
@@ -726,7 +715,7 @@
       result.offset = prevDirective.end;
       String eol = endOfLine;
       if (prevDirective is LibraryDirective) {
-        result.prefix = "${eol}${eol}";
+        result.prefix = "$eol$eol";
       } else {
         result.prefix = eol;
       }
@@ -753,7 +742,7 @@
       if (prevDirective is PartDirective) {
         result.prefix = eol;
       } else {
-        result.prefix = "${eol}${eol}";
+        result.prefix = "$eol$eol";
       }
       return result;
     }
@@ -1133,7 +1122,7 @@
       }
       // update line
       if (right) {
-        line = "${indent}${line}";
+        line = "$indent$line";
       } else {
         line = removeStart(line, indent);
       }
@@ -1204,7 +1193,7 @@
       lineOffset += line.length + eol.length;
       // update line indent
       if (!inString) {
-        line = "${newIndent}${removeStart(line, oldIndent)}";
+        line = "$newIndent${removeStart(line, oldIndent)}";
       }
       // append line
       sb.write(line);
@@ -1235,30 +1224,6 @@
   }
 
   /**
-   * @return <code>true</code> if given range of [BinaryExpression] can be extracted.
-   */
-  bool validateBinaryExpressionRange(
-      BinaryExpression binaryExpression, SourceRange range) {
-    // only parts of associative expression are safe to extract
-    if (!binaryExpression.operator.type.isAssociativeOperator) {
-      return false;
-    }
-    // prepare selected operands
-    List<Expression> operands = _getOperandsInOrderFor(binaryExpression);
-    List<Expression> subOperands = _getOperandsForSourceRange(operands, range);
-    // if empty, then something wrong with selection
-    if (subOperands.isEmpty) {
-      return false;
-    }
-    // may be some punctuation included into selection - operators, braces, etc
-    if (_selectionIncludesNonWhitespaceOutsideOperands(range, subOperands)) {
-      return false;
-    }
-    // OK
-    return true;
-  }
-
-  /**
    * @return the [ImportElement] used to import given [Element] into [library].
    *         May be `null` if was not imported, i.e. declared in the same library.
    */
@@ -1323,11 +1288,9 @@
       String expressionSource = getNodeText(isExpression.expression);
       String typeSource = getNodeText(isExpression.type);
       if (isExpression.notOperator == null) {
-        return _InvertedCondition
-            ._simple("${expressionSource} is! ${typeSource}");
+        return _InvertedCondition._simple("$expressionSource is! $typeSource");
       } else {
-        return _InvertedCondition
-            ._simple("${expressionSource} is ${typeSource}");
+        return _InvertedCondition._simple("$expressionSource is $typeSource");
       }
     }
     if (expression is PrefixExpression) {
@@ -1344,11 +1307,12 @@
     }
     if (expression is ParenthesizedExpression) {
       ParenthesizedExpression pe = expression;
-      Expression innerExpresion = pe.expression;
-      while (innerExpresion is ParenthesizedExpression) {
-        innerExpresion = (innerExpresion as ParenthesizedExpression).expression;
+      Expression innerExpression = pe.expression;
+      while (innerExpression is ParenthesizedExpression) {
+        innerExpression =
+            (innerExpression as ParenthesizedExpression).expression;
       }
-      return _invertCondition0(innerExpresion);
+      return _invertCondition0(innerExpression);
     }
     DartType type = expression.bestType;
     if (type.displayName == "bool") {
@@ -1369,12 +1333,6 @@
     return true;
   }
 
-  bool _selectionIncludesNonWhitespaceOutsideOperands(
-      SourceRange selection, List<Expression> operands) {
-    return _selectionIncludesNonWhitespaceOutsideRange(
-        selection, rangeNodes(operands));
-  }
-
   /**
    * @return <code>true</code> if "selection" covers "range" and there are any non-whitespace tokens
    *         between "selection" and "range" start/end.
@@ -1396,66 +1354,6 @@
     // only whitespace in selection around range
     return false;
   }
-
-  /**
-   * @return [Expression]s from <code>operands</code> which are completely covered by given
-   *         [SourceRange]. Range should start and end between given [Expression]s.
-   */
-  static List<Expression> _getOperandsForSourceRange(
-      List<Expression> operands, SourceRange range) {
-    assert(!operands.isEmpty);
-    List<Expression> subOperands = [];
-    // track range enter/exit
-    bool entered = false;
-    bool exited = false;
-    // may be range starts before or on first operand
-    if (range.offset <= operands[0].offset) {
-      entered = true;
-    }
-    // iterate over gaps between operands
-    for (int i = 0; i < operands.length - 1; i++) {
-      Expression operand = operands[i];
-      Expression nextOperand = operands[i + 1];
-      SourceRange inclusiveGap =
-          rangeEndStart(operand, nextOperand).getMoveEnd(1);
-      // add operand, if already entered range
-      if (entered) {
-        subOperands.add(operand);
-        // may be last operand in range
-        if (range.endsIn(inclusiveGap)) {
-          exited = true;
-        }
-      } else {
-        // may be first operand in range
-        if (range.startsIn(inclusiveGap)) {
-          entered = true;
-        }
-      }
-    }
-    // check if last operand is in range
-    Expression lastGroupMember = operands[operands.length - 1];
-    if (range.end == lastGroupMember.end) {
-      subOperands.add(lastGroupMember);
-      exited = true;
-    }
-    // we expect that range covers only given operands
-    if (!exited) {
-      return [];
-    }
-    // done
-    return subOperands;
-  }
-
-  /**
-   * @return all operands of the given [BinaryExpression] and its children with the same
-   *         operator.
-   */
-  static List<Expression> _getOperandsInOrderFor(BinaryExpression groupRoot) {
-    List<Expression> operands = [];
-    TokenType groupOperatorType = groupRoot.operator.type;
-    groupRoot.accept(new _OrderedOperandsVisitor(groupOperatorType, operands));
-    return operands;
-  }
 }
 
 /**
@@ -1527,6 +1425,26 @@
       tokens.length == 1 && tokens[0].type == type;
 }
 
+class _CollectReferencedUnprefixedNames extends RecursiveAstVisitor {
+  final Set<String> names = new Set<String>();
+
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    if (!_isPrefixed(node)) {
+      names.add(node.name);
+    }
+  }
+
+  static bool _isPrefixed(SimpleIdentifier node) {
+    AstNode parent = node.parent;
+    return parent is ConstructorName && parent.name == node ||
+        parent is MethodInvocation &&
+            parent.methodName == node &&
+            parent.realTarget != null ||
+        parent is PrefixedIdentifier && parent.identifier == node ||
+        parent is PropertyAccess && parent.target == node;
+  }
+}
+
 /**
  * A container with a source and its precedence.
  */
@@ -1547,9 +1465,9 @@
 
   static _InvertedCondition _binary2(
       _InvertedCondition left, String operation, _InvertedCondition right) {
-    // TODO(scheglov) conside merging with "_binary()" after testing
+    // TODO(scheglov) consider merging with "_binary()" after testing
     return new _InvertedCondition(
-        1 << 20, "${left._source}${operation}${right._source}");
+        1 << 20, "${left._source}$operation${right._source}");
   }
 
   /**
@@ -1567,19 +1485,3 @@
   static _InvertedCondition _simple(String source) =>
       new _InvertedCondition(2147483647, source);
 }
-
-class _OrderedOperandsVisitor extends GeneralizingAstVisitor {
-  final TokenType groupOperatorType;
-  final List<Expression> operands;
-
-  _OrderedOperandsVisitor(this.groupOperatorType, this.operands);
-
-  @override
-  Object visitExpression(Expression node) {
-    if (node is BinaryExpression && node.operator.type == groupOperatorType) {
-      return super.visitNode(node);
-    }
-    operands.add(node);
-    return null;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/dependencies/library_dependencies.dart b/pkg/analysis_server/lib/src/services/dependencies/library_dependencies.dart
index e55993d..0c30918 100644
--- a/pkg/analysis_server/lib/src/services/dependencies/library_dependencies.dart
+++ b/pkg/analysis_server/lib/src/services/dependencies/library_dependencies.dart
@@ -4,8 +4,8 @@
 
 library services.dependencies.library;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
@@ -42,13 +42,6 @@
     return _dependencies;
   }
 
-  Map<AnalysisContext, Folder> _reverse(Map<Folder, AnalysisContext> map) {
-    Map<AnalysisContext, Folder> reverseMap =
-        new Map<AnalysisContext, Folder>();
-    map.forEach((Folder f, AnalysisContext c) => reverseMap[c] = f);
-    return reverseMap;
-  }
-
   void _addDependencies(LibraryElement libraryElement) {
     if (libraryElement == null) {
       return;
@@ -66,4 +59,11 @@
           (ExportElement export) => _addDependencies(export.exportedLibrary));
     }
   }
+
+  Map<AnalysisContext, Folder> _reverse(Map<Folder, AnalysisContext> map) {
+    Map<AnalysisContext, Folder> reverseMap =
+        new Map<AnalysisContext, Folder>();
+    map.forEach((Folder f, AnalysisContext c) => reverseMap[c] = f);
+    return reverseMap;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/dependencies/reachable_source_collector.dart b/pkg/analysis_server/lib/src/services/dependencies/reachable_source_collector.dart
new file mode 100644
index 0000000..a0273ce
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/dependencies/reachable_source_collector.dart
@@ -0,0 +1,53 @@
+// 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 services.dependencies.reachable_source_collector;
+
+import 'dart:collection';
+
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/task/dart.dart';
+
+/// Collects reachable sources.
+class ReachableSourceCollector {
+  final Map<String, List<String>> _sourceMap =
+      new HashMap<String, List<String>>();
+
+  final Source source;
+  final AnalysisContext context;
+  ReachableSourceCollector(this.source, this.context) {
+    if (source == null) {
+      throw new ArgumentError.notNull('source');
+    }
+    if (context == null) {
+      throw new ArgumentError.notNull('context');
+    }
+  }
+
+  /// Collect reachable sources.
+  Map<String, List<String>> collectSources() {
+    _addDependencies(source);
+    return _sourceMap;
+  }
+
+  void _addDependencies(Source source) {
+
+    String sourceUri = source.uri.toString();
+
+    // Careful not to revisit.
+    if (_sourceMap[source.uri.toString()] != null) {
+      return;
+    }
+
+    List<Source> sources = <Source>[];
+    sources.addAll(context.computeResult(source, IMPORTED_LIBRARIES));
+    sources.addAll(context.computeResult(source, EXPORTED_LIBRARIES));
+
+    _sourceMap[sourceUri] =
+        sources.map((source) => source.uri.toString()).toList();
+
+    sources.forEach((s) => _addDependencies(s));
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/index/index.dart b/pkg/analysis_server/lib/src/services/index/index.dart
index 5b2204c..d86b322 100644
--- a/pkg/analysis_server/lib/src/services/index/index.dart
+++ b/pkg/analysis_server/lib/src/services/index/index.dart
@@ -6,9 +6,9 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 
 /**
@@ -307,7 +307,7 @@
     if (isResolved) {
       flagsStr += ' resolved';
     }
-    return '[${offset} - ${(offset + length)}) $flagsStr in ${indexable}';
+    return '[$offset - ${offset + length}) $flagsStr in $indexable';
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/index/index_contributor.dart b/pkg/analysis_server/lib/src/services/index/index_contributor.dart
index 6fcd934..b5eee6b 100644
--- a/pkg/analysis_server/lib/src/services/index/index_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/index/index_contributor.dart
@@ -6,14 +6,15 @@
 
 import 'dart:collection' show Queue;
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/index_store.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/index/indexable_file.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
diff --git a/pkg/analysis_server/lib/src/services/index/index_store.dart b/pkg/analysis_server/lib/src/services/index/index_store.dart
index 574a727..f5bebe1 100644
--- a/pkg/analysis_server/lib/src/services/index/index_store.dart
+++ b/pkg/analysis_server/lib/src/services/index/index_store.dart
@@ -4,9 +4,9 @@
 
 library services.index_store;
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/index/indexable_element.dart b/pkg/analysis_server/lib/src/services/index/indexable_element.dart
index 57f8659..916a099 100644
--- a/pkg/analysis_server/lib/src/services/index/indexable_element.dart
+++ b/pkg/analysis_server/lib/src/services/index/indexable_element.dart
@@ -6,8 +6,8 @@
 
 import 'dart:collection';
 
-import 'package:analysis_server/plugin/index/index_core.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
diff --git a/pkg/analysis_server/lib/src/services/index/indexable_file.dart b/pkg/analysis_server/lib/src/services/index/indexable_file.dart
index 7babfef..4e1c873 100644
--- a/pkg/analysis_server/lib/src/services/index/indexable_file.dart
+++ b/pkg/analysis_server/lib/src/services/index/indexable_file.dart
@@ -4,7 +4,7 @@
 
 library services.index.indexable_file;
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analyzer/src/generated/engine.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/index/local_index.dart b/pkg/analysis_server/lib/src/services/index/local_index.dart
index 624d3ff..34c0e76 100644
--- a/pkg/analysis_server/lib/src/services/index/local_index.dart
+++ b/pkg/analysis_server/lib/src/services/index/local_index.dart
@@ -6,10 +6,10 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/index/local_memory_index.dart b/pkg/analysis_server/lib/src/services/index/local_memory_index.dart
index 484085f..ec69627 100644
--- a/pkg/analysis_server/lib/src/services/index/local_memory_index.dart
+++ b/pkg/analysis_server/lib/src/services/index/local_memory_index.dart
@@ -4,7 +4,7 @@
 
 library services.index.memory_file_index;
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/index_contributor.dart';
 import 'package:analysis_server/src/services/index/local_index.dart';
diff --git a/pkg/analysis_server/lib/src/services/index/store/codec.dart b/pkg/analysis_server/lib/src/services/index/store/codec.dart
index 8fd23ab..9771f56 100644
--- a/pkg/analysis_server/lib/src/services/index/store/codec.dart
+++ b/pkg/analysis_server/lib/src/services/index/store/codec.dart
@@ -6,7 +6,7 @@
 
 import 'dart:collection';
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analyzer/src/generated/engine.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/index/store/split_store.dart b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
index 880cad3..86e463b 100644
--- a/pkg/analysis_server/lib/src/services/index/store/split_store.dart
+++ b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
@@ -8,15 +8,15 @@
 import 'dart:collection';
 import 'dart:typed_data';
 
-import 'package:analysis_server/plugin/index/index_core.dart';
 import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/index_store.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/index/store/codec.dart';
 import 'package:analysis_server/src/services/index/store/collection.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart' show CompilationUnit;
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -168,7 +168,7 @@
     String unitName = unit.fullName;
     int libraryNameIndex = site.encodeString(libraryName);
     int unitNameIndex = site.encodeString(unitName);
-    return 'DartUnitElement_${libraryNameIndex}_${unitNameIndex}.index';
+    return 'DartUnitElement_${libraryNameIndex}_$unitNameIndex.index';
   }
 
   void _recordLibraryWithUnit(
@@ -271,7 +271,7 @@
       _DataInputStream stream = new _DataInputStream(bytes);
       return _readNode(stream);
     }).catchError((exception, stackTrace) {
-      _logger.logError('Exception during reading index file ${name}',
+      _logger.logError('Exception during reading index file $name',
           new CaughtException(exception, stackTrace));
     });
   }
@@ -305,7 +305,7 @@
         return _fileManager.write(name, bytes);
       });
     }).catchError((exception, stackTrace) {
-      _logger.logError('Exception during reading index file ${name}',
+      _logger.logError('Exception during reading index file $name',
           new CaughtException(exception, stackTrace));
     });
   }
@@ -349,8 +349,7 @@
     {
       int version = stream.readInt();
       if (version != _VERSION) {
-        throw new StateError(
-            'Version ${_VERSION} expected, but ${version} found.');
+        throw new StateError('Version $_VERSION expected, but $version found.');
       }
     }
     // context
diff --git a/pkg/analysis_server/lib/src/services/linter/linter.dart b/pkg/analysis_server/lib/src/services/linter/linter.dart
index 87692ea..675836ce 100644
--- a/pkg/analysis_server/lib/src/services/linter/linter.dart
+++ b/pkg/analysis_server/lib/src/services/linter/linter.dart
@@ -4,11 +4,10 @@
 
 library services.src.linter;
 
-import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/analyzer.dart';
-import 'package:yaml/yaml.dart';
+import 'package:analyzer/plugin/options.dart';
 import 'package:linter/src/rules.dart';
-import 'package:linter/src/linter.dart';
+import 'package:yaml/yaml.dart';
 
 /**
  * An error code indicating an undefined lint rule.
@@ -18,7 +17,7 @@
  */
 const AnalysisOptionsWarningCode UNDEFINED_LINT_WARNING =
     const AnalysisOptionsWarningCode(
-        'UNDEFINED_LINT_WARNING', "Undefined lint rule '{0}'");
+        'UNDEFINED_LINT_WARNING', "'{0}' is not a recognized lint rule");
 
 /// Validates `linter` rule configurations.
 class LinterRuleOptionsValidator extends OptionsValidator {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
index aabe616..51db1c2 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
@@ -14,7 +14,7 @@
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
index 0bcf9c2..59803be 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
@@ -13,8 +13,8 @@
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index 6cfd951..a17bfda 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -17,8 +17,8 @@
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -40,6 +40,8 @@
 
   String name;
   bool extractAll = true;
+  final List<int> coveringExpressionOffsets = <int>[];
+  final List<int> coveringExpressionLengths = <int>[];
   final List<String> names = <String>[];
   final List<int> offsets = <int>[];
   final List<int> lengths = <int>[];
@@ -57,6 +59,7 @@
     unitElement = unit.element;
     selectionRange = new SourceRange(selectionOffset, selectionLength);
     utils = new CorrectionUtils(unit);
+    file = unitElement.source.fullName;
   }
 
   @override
@@ -73,11 +76,7 @@
   @override
   Future<RefactoringStatus> checkFinalConditions() {
     RefactoringStatus result = new RefactoringStatus();
-    if (excludedVariableNames.contains(name)) {
-      result.addWarning(format(
-          "A variable with name '{0}' is already defined in the visible scope.",
-          name));
-    }
+    result.addStatus(checkName());
     return new Future.value(result);
   }
 
@@ -102,7 +101,13 @@
 
   @override
   RefactoringStatus checkName() {
-    return validateVariableName(name);
+    RefactoringStatus result = new RefactoringStatus();
+    result.addStatus(validateVariableName(name));
+    if (excludedVariableNames.contains(name)) {
+      result.addError(
+          format("The name '{0}' is already used in the scope.", name));
+    }
+    return result;
   }
 
   @override
@@ -115,6 +120,7 @@
     } else {
       occurrences = [selectionRange];
     }
+    occurrences.sort((a, b) => a.offset - b.offset);
     // If the whole expression of a statement is selected, like '1 + 2',
     // then convert it into a variable declaration statement.
     if (wholeStatementExpression && occurrences.length == 1) {
@@ -125,36 +131,53 @@
       doSourceChange_addElementEdit(change, unitElement, edit);
       return new Future.value(change);
     }
+    // prepare positions
+    List<Position> positions = <Position>[];
+    int occurrencesShift = 0;
+    void addPosition(int offset) {
+      positions.add(new Position(file, offset));
+    }
     // add variable declaration
     {
-      String declarationSource;
+      String declarationCode;
+      int nameOffsetInDeclarationCode;
       if (stringLiteralPart != null) {
-        declarationSource = "var $name = '$stringLiteralPart';";
+        declarationCode = 'var ';
+        nameOffsetInDeclarationCode = declarationCode.length;
+        declarationCode += "$name = '$stringLiteralPart';";
       } else {
         String keyword = _declarationKeyword;
-        String initializerSource = utils.getRangeText(selectionRange);
-        declarationSource = "$keyword $name = $initializerSource;";
+        String initializerCode = utils.getRangeText(selectionRange);
+        declarationCode = '$keyword ';
+        nameOffsetInDeclarationCode = declarationCode.length;
+        declarationCode += '$name = $initializerCode;';
       }
-      String eol = utils.endOfLine;
       // prepare location for declaration
       AstNode target = _findDeclarationTarget(occurrences);
+      String eol = utils.endOfLine;
       // insert variable declaration
       if (target is Statement) {
         String prefix = utils.getNodePrefix(target);
         SourceEdit edit =
-            new SourceEdit(target.offset, 0, declarationSource + eol + prefix);
+            new SourceEdit(target.offset, 0, declarationCode + eol + prefix);
         doSourceChange_addElementEdit(change, unitElement, edit);
+        addPosition(edit.offset + nameOffsetInDeclarationCode);
+        occurrencesShift = edit.replacement.length;
       } else if (target is ExpressionFunctionBody) {
         String prefix = utils.getNodePrefix(target.parent);
         String indent = utils.getIndent(1);
-        String declStatement = prefix + indent + declarationSource + eol;
-        String exprStatement = prefix + indent + 'return ';
         Expression expr = target.expression;
-        doSourceChange_addElementEdit(
-            change,
-            unitElement,
-            new SourceEdit(target.offset, expr.offset - target.offset,
-                '{' + eol + declStatement + exprStatement));
+        {
+          String code = '{' + eol + prefix + indent;
+          addPosition(
+              target.offset + code.length + nameOffsetInDeclarationCode);
+          code += declarationCode + eol;
+          code += prefix + indent + 'return ';
+          SourceEdit edit =
+              new SourceEdit(target.offset, expr.offset - target.offset, code);
+          occurrencesShift = target.offset + code.length - expr.offset;
+          doSourceChange_addElementEdit(change, unitElement, edit);
+        }
         doSourceChange_addElementEdit(change, unitElement,
             new SourceEdit(expr.end, 0, ';' + eol + prefix + '}'));
       }
@@ -163,12 +186,23 @@
     String occurrenceReplacement = name;
     if (stringLiteralPart != null) {
       occurrenceReplacement = "\${$name}";
+      occurrencesShift += 2;
     }
     // replace occurrences with variable reference
     for (SourceRange range in occurrences) {
       SourceEdit edit = newSourceEdit_range(range, occurrenceReplacement);
+      addPosition(range.offset + occurrencesShift);
+      occurrencesShift += name.length - range.length;
       doSourceChange_addElementEdit(change, unitElement, edit);
     }
+    // add the linked group
+    change.addLinkedEditGroup(new LinkedEditGroup(
+        positions,
+        name.length,
+        names
+            .map((name) => new LinkedEditSuggestion(
+                name, LinkedEditSuggestionKind.VARIABLE))
+            .toList()));
     // done
     return new Future.value(change);
   }
@@ -178,19 +212,89 @@
 
   /**
    * Checks if [selectionRange] selects [Expression] which can be extracted, and
-   * location of this [DartExpression] in AST allows extracting.
+   * location of this [Expression] in AST allows extracting.
    */
   RefactoringStatus _checkSelection() {
-    _ExtractExpressionAnalyzer _selectionAnalyzer =
-        new _ExtractExpressionAnalyzer(selectionRange);
-    unit.accept(_selectionAnalyzer);
-    AstNode coveringNode = _selectionAnalyzer.coveringNode;
-    // may be fatal error
+    String selectionStr;
+    // exclude whitespaces
     {
-      RefactoringStatus status = _selectionAnalyzer.status;
-      if (status.hasFatalError) {
-        return status;
+      selectionStr = utils.getRangeText(selectionRange);
+      int numLeading = countLeadingWhitespaces(selectionStr);
+      int numTrailing = countTrailingWhitespaces(selectionStr);
+      int offset = selectionRange.offset + numLeading;
+      int end = selectionRange.end - numTrailing;
+      selectionRange = new SourceRange(offset, end - offset);
+    }
+    // get covering node
+    AstNode coveringNode =
+        new NodeLocator(selectionRange.offset, selectionRange.end)
+            .searchWithin(unit);
+    // compute covering expressions
+    for (AstNode node = coveringNode; node != null; node = node.parent) {
+      AstNode parent = node.parent;
+      // skip some nodes
+      if (node is ArgumentList ||
+          node is AssignmentExpression ||
+          node is NamedExpression ||
+          node is TypeArgumentList) {
+        continue;
       }
+      if (node is ConstructorName || node is Label || node is TypeName) {
+        rootExpression = null;
+        coveringExpressionOffsets.clear();
+        coveringExpressionLengths.clear();
+        continue;
+      }
+      // cannot extract the name part of a property access
+      if (parent is PrefixedIdentifier && parent.identifier == node ||
+          parent is PropertyAccess && parent.propertyName == node) {
+        continue;
+      }
+      // stop if not an Expression
+      if (node is! Expression) {
+        break;
+      }
+      // stop at void method invocations
+      if (node is MethodInvocation) {
+        MethodInvocation invocation = node;
+        Element element = invocation.methodName.bestElement;
+        if (element is ExecutableElement &&
+            element.returnType != null &&
+            element.returnType.isVoid) {
+          if (rootExpression == null) {
+            return new RefactoringStatus.fatal(
+                'Cannot extract the void expression.',
+                newLocation_fromNode(node));
+          }
+          break;
+        }
+      }
+      // fatal selection problems
+      if (coveringExpressionOffsets.isEmpty) {
+        if (node is SimpleIdentifier) {
+          if (node.inDeclarationContext()) {
+            return new RefactoringStatus.fatal(
+                'Cannot extract the name part of a declaration.',
+                newLocation_fromNode(node));
+          }
+          Element element = node.bestElement;
+          if (element is FunctionElement || element is MethodElement) {
+            continue;
+          }
+        }
+        if (parent is AssignmentExpression && parent.leftHandSide == node) {
+          return new RefactoringStatus.fatal(
+              'Cannot extract the left-hand side of an assignment.',
+              newLocation_fromNode(node));
+        }
+      }
+      // set selected expression
+      if (coveringExpressionOffsets.isEmpty) {
+        rootExpression = node;
+      }
+      // add the expression range
+      coveringExpressionOffsets.add(node.offset);
+      coveringExpressionLengths.add(node.length);
     }
     // we need enclosing block to add variable declaration statement
     if (coveringNode == null ||
@@ -201,38 +305,19 @@
     }
     // part of string literal
     if (coveringNode is StringLiteral) {
-      stringLiteralPart = utils.getRangeText(selectionRange);
-      if (stringLiteralPart.startsWith("'") ||
-          stringLiteralPart.startsWith('"') ||
-          stringLiteralPart.endsWith("'") ||
-          stringLiteralPart.endsWith('"')) {
-        return new RefactoringStatus.fatal(
-            'Cannot extract only leading or trailing quote of string literal.');
+      if (selectionRange.length != 0 &&
+          selectionRange.offset > coveringNode.offset &&
+          selectionRange.end < coveringNode.end) {
+        stringLiteralPart = selectionStr;
+        return new RefactoringStatus();
       }
-      return new RefactoringStatus();
     }
     // single node selected
-    if (_selectionAnalyzer.selectedNodes.length == 1 &&
-        !utils.selectionIncludesNonWhitespaceOutsideNode(
-            selectionRange, _selectionAnalyzer.firstSelectedNode)) {
-      AstNode selectedNode = _selectionAnalyzer.firstSelectedNode;
-      if (selectedNode is Expression) {
-        rootExpression = selectedNode;
-        singleExpression = rootExpression;
-        wholeStatementExpression =
-            singleExpression.parent is ExpressionStatement;
-        return new RefactoringStatus();
-      }
-    }
-    // fragment of binary expression selected
-    if (coveringNode is BinaryExpression) {
-      BinaryExpression binaryExpression = coveringNode;
-      if (utils.validateBinaryExpressionRange(
-          binaryExpression, selectionRange)) {
-        rootExpression = binaryExpression;
-        singleExpression = null;
-        return new RefactoringStatus();
-      }
+    if (rootExpression != null) {
+      singleExpression = rootExpression;
+      selectionRange = rangeNode(singleExpression);
+      wholeStatementExpression = singleExpression.parent is ExpressionStatement;
+      return new RefactoringStatus();
     }
     // invalid selection
     return new RefactoringStatus.fatal(
@@ -259,7 +344,7 @@
    * Returns an [Element]-sensitive encoding of [tokens].
    * Each [Token] with a [LocalVariableElement] has a suffix of the element id.
    *
-   * So, we can distingush different local variables with the same name, if
+   * So, we can distinguish different local variables with the same name, if
    * there are multiple variables with the same name are declared in the
    * function we are searching occurrences in.
    */
@@ -475,7 +560,7 @@
   }
 
   /**
-   * Records fatal error with given message and [Locatiom].
+   * Records fatal error with given [message] and [location].
    */
   void _invalidSelection(String message, Location location) {
     status.addFatalError(message, location);
@@ -523,7 +608,7 @@
   @override
   Object visitStringLiteral(StringLiteral node) {
     if (ref.stringLiteralPart != null) {
-      int occuLength = ref.stringLiteralPart.length;
+      int length = ref.stringLiteralPart.length;
       String value = ref.utils.getNodeText(node);
       int lastIndex = 0;
       while (true) {
@@ -531,10 +616,10 @@
         if (index == -1) {
           break;
         }
-        lastIndex = index + occuLength;
-        int occuStart = node.offset + index;
-        SourceRange occuRange = rangeStartLength(occuStart, occuLength);
-        occurrences.add(occuRange);
+        lastIndex = index + length;
+        int start = node.offset + index;
+        SourceRange range = rangeStartLength(start, length);
+        occurrences.add(range);
       }
       return null;
     }
@@ -560,8 +645,8 @@
     List<Token> nodeTokens = TokenUtils.getTokens(nodeSource);
     nodeSource = ref._encodeExpressionTokens(node, nodeTokens);
     if (nodeSource == selectionSource) {
-      SourceRange occuRange = rangeNode(node);
-      _addOccurrence(occuRange);
+      SourceRange range = rangeNode(node);
+      _addOccurrence(range);
     }
   }
 
@@ -587,10 +672,10 @@
       Token startToken = nodeTokens[startTokenIndex];
       Token endToken = nodeTokens[endTokenIndex];
       // add occurrence range
-      int occuStart = nodeOffset + startToken.offset;
-      int occuEnd = nodeOffset + endToken.end;
-      SourceRange occuRange = rangeStartEnd(occuStart, occuEnd);
-      _addOccurrence(occuRange);
+      int start = nodeOffset + startToken.offset;
+      int end = nodeOffset + endToken.end;
+      SourceRange range = rangeStartEnd(start, end);
+      _addOccurrence(range);
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index e83082b..6135237 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -20,8 +20,9 @@
 import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/resolver.dart' show ExitDetector;
@@ -219,10 +220,10 @@
   Future<SourceChange> createChange() async {
     SourceChange change = new SourceChange(refactoringName);
     // replace occurrences with method invocation
-    for (_Occurrence occurence in _occurrences) {
-      SourceRange range = occurence.range;
+    for (_Occurrence occurrence in _occurrences) {
+      SourceRange range = occurrence.range;
       // may be replacement of duplicates disabled
-      if (!extractAll && !occurence.isSelection) {
+      if (!extractAll && !occurrence.isSelection) {
         continue;
       }
       // prepare invocation source
@@ -236,7 +237,7 @@
           // single variable assignment / return statement
           if (_returnVariableName != null) {
             String occurrenceName =
-                occurence._parameterOldToOccurrenceName[_returnVariableName];
+                occurrence._parameterOldToOccurrenceName[_returnVariableName];
             // may be declare variable
             if (!_parametersMap.containsKey(_returnVariableName)) {
               if (variableType.isEmpty) {
@@ -272,7 +273,7 @@
             // argument name
             {
               String argumentName =
-                  occurence._parameterOldToOccurrenceName[parameter.id];
+                  occurrence._parameterOldToOccurrenceName[parameter.id];
               sb.write(argumentName);
             }
           }
@@ -307,7 +308,7 @@
         String returnExpressionSource = _getMethodBodySource();
         // closure
         if (_selectionFunctionExpression != null) {
-          declarationSource = '${name}${returnExpressionSource}';
+          declarationSource = '$name$returnExpressionSource';
           if (_selectionFunctionExpression.body is ExpressionFunctionBody) {
             declarationSource += ';';
           }
@@ -332,17 +333,16 @@
           declarationSource = '$annotations$signature$asyncKeyword {$eol';
           declarationSource += returnExpressionSource;
           if (_returnVariableName != null) {
-            declarationSource +=
-                '${prefix}  return ${_returnVariableName};$eol';
+            declarationSource += '$prefix  return $_returnVariableName;$eol';
           }
-          declarationSource += '${prefix}}';
+          declarationSource += '$prefix}';
         }
       }
       // insert declaration
       if (declarationSource != null) {
         int offset = _parentMember.end;
-        SourceEdit edit = new SourceEdit(
-            offset, 0, '${eol}${eol}${prefix}${declarationSource}');
+        SourceEdit edit =
+            new SourceEdit(offset, 0, '$eol$eol$prefix$declarationSource');
         doSourceChange_addElementEdit(change, unitElement, edit);
       }
     }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
index f0a345a..1fe699a 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
@@ -13,8 +13,8 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index 7c7e6356..3b3c786 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -16,8 +16,8 @@
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
@@ -523,7 +523,7 @@
             ref._methodExpressionPart, _refUtils, usage, target, arguments);
         if (getExpressionPrecedence(ref._methodExpression) <
             getExpressionParentPrecedence(usage)) {
-          source = "(${source})";
+          source = "($source)";
         }
         // do replace
         SourceRange methodUsageRange = rangeNode(usage);
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 d5663403..4a25e6d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -12,8 +12,8 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:path/path.dart' as pathos;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index a4d3c6b..5bf3194 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -24,9 +24,9 @@
 import 'package:analysis_server/src/services/refactoring/rename_local.dart';
 import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
@@ -72,6 +72,18 @@
   }
 
   /**
+   * The lengths of the expressions that cover the specified selection,
+   * from the down most to the up most.
+   */
+  List<int> get coveringExpressionLengths;
+
+  /**
+   * The offsets of the expressions that cover the specified selection,
+   * from the down most to the up most.
+   */
+  List<int> get coveringExpressionOffsets;
+
+  /**
    * True if all occurrences of the expression within the scope in which the
    * variable will be defined should be replaced by a reference to the local
    * variable. The expression used to initiate the refactoring will always be
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
index fbff2f6..f435ff9 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
@@ -11,7 +11,7 @@
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -101,5 +101,5 @@
   }
 
   @override
-  String toString() => '${file}@${range}';
+  String toString() => '$file@$range';
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
index a9bdb74..ec36d00 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
@@ -13,7 +13,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 00fa3b9..6080479 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -16,8 +16,8 @@
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart' show Identifier;
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 
 /**
@@ -102,7 +102,6 @@
       }
       // ignore references from SDK and pub cache
       if (isElementInSdkOrPubCache(reference.element)) {
-        print('ignore: $reference');
         continue;
       }
       // check the element being renamed is accessible
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
index d5c489a..460896e 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
@@ -16,7 +16,7 @@
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
 
@@ -59,7 +59,7 @@
       // append declaration
       references.add(_createDeclarationReference());
       // update references
-      String replacement = newName.isEmpty ? '' : '.${newName}';
+      String replacement = newName.isEmpty ? '' : '.$newName';
       for (SourceReference reference in references) {
         reference.addEdit(change, replacement);
       }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
index 4dcd752..d82a56d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
@@ -14,8 +14,8 @@
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -60,7 +60,7 @@
       } else {
         if (prefix == null) {
           SourceRange range = rangeStartLength(element.uriEnd, 0);
-          edit = newSourceEdit_range(range, " as ${newName}");
+          edit = newSourceEdit_range(range, " as $newName");
         } else {
           int offset = element.prefixOffset;
           int length = prefix.nameLength;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
index 7776b00..71c9026 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
@@ -11,7 +11,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 
 /**
  * A [Refactoring] for renaming [LabelElement]s.
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
index 54b6948..831fadb 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
@@ -12,7 +12,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 
 /**
  * A [Refactoring] for renaming [LibraryElement]s.
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
index 2d1b221..4f1f150 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
@@ -14,8 +14,8 @@
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
@@ -142,7 +142,7 @@
           haveIntersectingRanges(refactoring.element, nodeElement)) {
         conflictingLocals.add(nodeElement);
         String nodeKind = nodeElement.kind.displayName;
-        String message = "Duplicate ${nodeKind} '$newName'.";
+        String message = "Duplicate $nodeKind '$newName'.";
         result.addError(message, newLocation_fromElement(nodeElement));
         return;
       }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
index 8ab7de3..4f59af7 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
@@ -15,8 +15,8 @@
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart' show Identifier;
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 
 /**
@@ -26,7 +26,8 @@
 Future<RefactoringStatus> validateCreateFunction(
     SearchEngine searchEngine, LibraryElement library, String name) {
   return new _RenameUnitMemberValidator.forCreate(
-      searchEngine, library, ElementKind.FUNCTION, name).validate();
+          searchEngine, library, ElementKind.FUNCTION, name)
+      .validate();
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/search/element_visitors.dart b/pkg/analysis_server/lib/src/services/search/element_visitors.dart
index d7338d0..5448f3f 100644
--- a/pkg/analysis_server/lib/src/services/search/element_visitors.dart
+++ b/pkg/analysis_server/lib/src/services/search/element_visitors.dart
@@ -4,7 +4,8 @@
 
 library services.search.element_visitors;
 
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 
 /**
  * Uses [processor] to visit all of the children of [element].
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 496a4c0..f3ad992 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -9,7 +9,8 @@
 
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 
 /**
  * Returns direct children of [parent].
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine.dart b/pkg/analysis_server/lib/src/services/search/search_engine.dart
index 4e294bd..dbae817 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine.dart
@@ -8,7 +8,7 @@
 
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
index cfe43eb..12681f7 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
@@ -6,12 +6,13 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/correction/source_range.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/status/ast_writer.dart b/pkg/analysis_server/lib/src/status/ast_writer.dart
index 6cb30db..5488a59 100644
--- a/pkg/analysis_server/lib/src/status/ast_writer.dart
+++ b/pkg/analysis_server/lib/src/status/ast_writer.dart
@@ -50,6 +50,9 @@
     } else if (node is ExportDirective) {
       properties['element'] = node.element;
       properties['source'] = node.source;
+    } else if (node is FunctionDeclaration) {
+      properties['external keyword'] = node.externalKeyword;
+      properties['property keyword'] = node.propertyKeyword;
     } else if (node is FunctionExpressionInvocation) {
       properties['static element'] = node.staticElement;
       properties['static type'] = node.staticType;
@@ -60,6 +63,11 @@
       properties['source'] = node.source;
     } else if (node is LibraryDirective) {
       properties['element'] = node.element;
+    } else if (node is MethodDeclaration) {
+      properties['external keyword'] = node.externalKeyword;
+      properties['modifier keyword'] = node.modifierKeyword;
+      properties['operator keyword'] = node.operatorKeyword;
+      properties['property keyword'] = node.propertyKeyword;
     } else if (node is PartDirective) {
       properties['element'] = node.element;
       properties['source'] = node.source;
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index fd73cef..aa6a406 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -7,9 +7,11 @@
 import 'dart:collection';
 import 'dart:convert';
 
-import 'package:analysis_server/src/get_handler.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
 import 'package:analysis_server/src/status/tree_writer.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 
 /**
  * A visitor that will produce an HTML representation of an element structure.
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index a83d95e..7260013 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -13,28 +13,35 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/domain_diagnostic.dart';
 import 'package:analysis_server/src/domain_execution.dart';
 import 'package:analysis_server/src/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/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/local_index.dart';
 import 'package:analysis_server/src/services/index/store/split_store.dart';
 import 'package:analysis_server/src/socket_server.dart';
 import 'package:analysis_server/src/status/ast_writer.dart';
 import 'package:analysis_server/src/status/element_writer.dart';
+import 'package:analysis_server/src/status/validator.dart';
+import 'package:analysis_server/src/utilities/average.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisCache, AnalysisContextImpl, AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/html.dart';
@@ -52,6 +59,141 @@
  */
 typedef void HtmlGenerator(StringBuffer buffer);
 
+class ElementCounter extends RecursiveElementVisitor {
+  Map<Type, int> counts = new HashMap<Type, int>();
+  int elementsWithDocs = 0;
+  int totalDocSpan = 0;
+
+  void visit(Element element) {
+    SourceRange docRange = element.docRange;
+    if (docRange != null) {
+      ++elementsWithDocs;
+      totalDocSpan += docRange.length;
+    }
+
+    Type type = element.runtimeType;
+    if (counts[type] == null) {
+      counts[type] = 1;
+    } else {
+      counts[type]++;
+    }
+  }
+
+  @override
+  visitClassElement(ClassElement element) {
+    visit(element);
+    super.visitClassElement(element);
+  }
+
+  @override
+  visitCompilationUnitElement(CompilationUnitElement element) {
+    visit(element);
+    super.visitCompilationUnitElement(element);
+  }
+
+  @override
+  visitConstructorElement(ConstructorElement element) {
+    visit(element);
+    super.visitConstructorElement(element);
+  }
+
+  @override
+  visitExportElement(ExportElement element) {
+    visit(element);
+    super.visitExportElement(element);
+  }
+
+  @override
+  visitFieldElement(FieldElement element) {
+    visit(element);
+    super.visitFieldElement(element);
+  }
+
+  @override
+  visitFieldFormalParameterElement(FieldFormalParameterElement element) {
+    visit(element);
+    super.visitFieldFormalParameterElement(element);
+  }
+
+  @override
+  visitFunctionElement(FunctionElement element) {
+    visit(element);
+    super.visitFunctionElement(element);
+  }
+
+  @override
+  visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    visit(element);
+    super.visitFunctionTypeAliasElement(element);
+  }
+
+  @override
+  visitImportElement(ImportElement element) {
+    visit(element);
+    super.visitImportElement(element);
+  }
+
+  @override
+  visitLabelElement(LabelElement element) {
+    visit(element);
+    super.visitLabelElement(element);
+  }
+
+  @override
+  visitLibraryElement(LibraryElement element) {
+    visit(element);
+    super.visitLibraryElement(element);
+  }
+
+  @override
+  visitLocalVariableElement(LocalVariableElement element) {
+    visit(element);
+    super.visitLocalVariableElement(element);
+  }
+
+  @override
+  visitMethodElement(MethodElement element) {
+    visit(element);
+    super.visitMethodElement(element);
+  }
+
+  @override
+  visitMultiplyDefinedElement(MultiplyDefinedElement element) {
+    visit(element);
+    super.visitMultiplyDefinedElement(element);
+  }
+
+  @override
+  visitParameterElement(ParameterElement element) {
+    visit(element);
+    super.visitParameterElement(element);
+  }
+
+  @override
+  visitPrefixElement(PrefixElement element) {
+    visit(element);
+    super.visitPrefixElement(element);
+  }
+
+  @override
+  visitPropertyAccessorElement(PropertyAccessorElement element) {
+    visit(element);
+    super.visitPropertyAccessorElement(element);
+  }
+
+  @override
+  visitTopLevelVariableElement(TopLevelVariableElement element) {
+    visit(element);
+    super.visitTopLevelVariableElement(element);
+  }
+
+  @override
+  visitTypeParameterElement(TypeParameterElement element) {
+    visit(element);
+    super.visitTypeParameterElement(element);
+  }
+}
+
 /**
  * Instances of the class [GetHandler] handle GET requests.
  */
@@ -89,11 +231,27 @@
   static const String COMMUNICATION_PERFORMANCE_PATH = '/perf/communication';
 
   /**
+   * The path used to request diagnostic information for a single context.
+   */
+  static const String CONTEXT_DIAGNOSTICS_PATH = '/diagnostic/context';
+
+  /**
+   * The path used to request running a validation report for a single context.
+   */
+  static const String CONTEXT_VALIDATION_DIAGNOSTICS_PATH =
+      '/diagnostic/contextValidation';
+
+  /**
    * The path used to request information about a specific context.
    */
   static const String CONTEXT_PATH = '/context';
 
   /**
+   * The path used to request diagnostic information.
+   */
+  static const String DIAGNOSTIC_PATH = '/diagnostic';
+
+  /**
    * The path used to request information about a element model.
    */
   static const String ELEMENT_PATH = '/element';
@@ -157,6 +315,11 @@
       new ContentType("text", "html", charset: "utf-8");
 
   /**
+   * Rolling average of calls to get diagnostics.
+   */
+  Average _diagnosticCallAverage = new Average();
+
+  /**
    * The socket server whose status is to be reported on.
    */
   SocketServer _server;
@@ -172,10 +335,22 @@
   final Map<String, String> _overlayContents = <String, String>{};
 
   /**
+   * Handler for diagnostics requests.
+   */
+  DiagnosticDomainHandler _diagnosticHandler;
+
+  /**
    * Initialize a newly created handler for GET requests.
    */
   GetHandler(this._server, this._printBuffer);
 
+  DiagnosticDomainHandler get diagnosticHandler {
+    if (_diagnosticHandler == null) {
+      _diagnosticHandler = new DiagnosticDomainHandler(_server.analysisServer);
+    }
+    return _diagnosticHandler;
+  }
+
   /**
    * Return the active [CompletionDomainHandler]
    * or `null` if either analysis server is not running
@@ -195,7 +370,7 @@
    */
   void handleGetRequest(HttpRequest request) {
     String path = request.uri.path;
-    if (path == STATUS_PATH) {
+    if (path == '/' || path == STATUS_PATH) {
       _returnServerStatus(request);
     } else if (path == ANALYSIS_PERFORMANCE_PATH) {
       _returnAnalysisPerformance(request);
@@ -209,8 +384,14 @@
       _returnCompletionInfo(request);
     } else if (path == COMMUNICATION_PERFORMANCE_PATH) {
       _returnCommunicationPerformance(request);
+    } else if (path == CONTEXT_DIAGNOSTICS_PATH) {
+      _returnContextDiagnostics(request);
+    } else if (path == CONTEXT_VALIDATION_DIAGNOSTICS_PATH) {
+      _returnContextValidationDiagnostics(request);
     } else if (path == CONTEXT_PATH) {
       _returnContextInfo(request);
+    } else if (path == DIAGNOSTIC_PATH) {
+      _returnDiagnosticInfo(request);
     } else if (path == ELEMENT_PATH) {
       _returnElement(request);
     } else if (path == INDEX_ELEMENT_BY_NAME) {
@@ -282,6 +463,10 @@
     if (unit != null) {
       return unit;
     }
+    unit = entry.getValue(RESOLVED_UNIT11);
+    if (unit != null) {
+      return unit;
+    }
     return entry.getValue(RESOLVED_UNIT);
   }
 
@@ -350,6 +535,7 @@
       results.add(RESOLVED_UNIT8);
       results.add(RESOLVED_UNIT9);
       results.add(RESOLVED_UNIT10);
+      results.add(RESOLVED_UNIT11);
       results.add(RESOLVED_UNIT);
       results.add(STRONG_MODE_ERRORS);
       results.add(USED_IMPORTED_ELEMENTS);
@@ -515,7 +701,7 @@
           //
           // Write task model timing information.
           //
-          buffer.write('<p><b>Task performace data</b></p>');
+          buffer.write('<p><b>Task performance data</b></p>');
           buffer.write(
               '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
           _writeRow(
@@ -557,51 +743,6 @@
               classes: [null, "right", "right", "right"]);
           buffer.write('</table>');
         });
-        //
-        // Write task model inputs timing information.
-        //
-        {
-          buffer.write('<p><b>Task inputs performace data</b></p>');
-          buffer.write(
-              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
-          _writeRow(
-              buffer,
-              [
-                'Task Name',
-                'Count',
-                'Total Time (in ms)',
-                'Average Time (in ms)'
-              ],
-              header: true);
-
-          Map<TaskDescriptor, int> countMap = WorkItem.countMap;
-          Map<TaskDescriptor, Stopwatch> stopwatchMap = WorkItem.stopwatchMap;
-          List<TaskDescriptor> taskClasses = stopwatchMap.keys.toList();
-          taskClasses.sort((TaskDescriptor first, TaskDescriptor second) {
-            String firstName = first.name;
-            String secondName = second.name;
-            return firstName.compareTo(secondName);
-          });
-          taskClasses.forEach((TaskDescriptor descriptor) {
-            int count = countMap[descriptor];
-            if (count == null) {
-              count = 0;
-            }
-            int taskTime = stopwatchMap[descriptor].elapsedMilliseconds;
-            _writeRow(buffer, [
-              descriptor.name,
-              count,
-              taskTime,
-              count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3)
-            ], classes: [
-              null,
-              "right",
-              "right",
-              "right"
-            ]);
-          });
-          buffer.write('</table>');
-        }
       });
     });
   }
@@ -693,6 +834,7 @@
     List<Folder> allContexts = <Folder>[];
     Map<Folder, List<CacheEntry>> entryMap =
         new HashMap<Folder, List<CacheEntry>>();
+    StringBuffer invalidKeysBuffer = new StringBuffer();
     analysisServer.folderMap
         .forEach((Folder folder, InternalAnalysisContext context) {
       Source source = context.sourceFactory.forUri(sourceUri);
@@ -709,7 +851,15 @@
               entries = <CacheEntry>[];
               entryMap[folder] = entries;
             }
-            entries.add(iterator.value);
+            CacheEntry value = iterator.value;
+            if (value == null) {
+              if (invalidKeysBuffer.isNotEmpty) {
+                invalidKeysBuffer.write(', ');
+              }
+              invalidKeysBuffer.write(iterator.key.toString());
+            } else {
+              entries.add(value);
+            }
           }
         }
       }
@@ -721,6 +871,11 @@
     _writeResponse(request, (StringBuffer buffer) {
       _writePage(buffer, 'Analysis Server - Cache Entry',
           ['Context: $contextFilter', 'File: $sourceUri'], (HttpResponse) {
+        if (invalidKeysBuffer.isNotEmpty) {
+          buffer.write('<h3>Targets with null Entries</h3><p>');
+          buffer.write(invalidKeysBuffer.toString());
+          buffer.write('</p>');
+        }
         List<CacheEntry> entries = entryMap[folder];
         buffer.write('<h3>Analyzing Contexts</h3><p>');
         bool first = true;
@@ -971,6 +1126,34 @@
   }
 
   /**
+   * Return a response displaying diagnostic information for a single context.
+   */
+  void _returnContextDiagnostics(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    Folder folder = _findFolder(analysisServer, contextFilter);
+    if (folder == null) {
+      return _returnFailure(request, 'Invalid context: $contextFilter');
+    }
+
+    InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Context Diagnostics',
+          ['Context: $contextFilter'], (StringBuffer buffer) {
+        _writeContextDiagnostics(buffer, context);
+      });
+    });
+  }
+
+  /**
    * Return a response containing information about a single source file in the
    * cache.
    */
@@ -1030,9 +1213,6 @@
     explicitNames.sort();
     implicitNames.sort();
 
-    AnalysisDriver driver = (context as AnalysisContextImpl).driver;
-    List<WorkItem> workItems = driver.currentWorkOrder?.workItems;
-
     _overlayContents.clear();
     context.visitContentCache((String fullName, int stamp, String contents) {
       _overlayContents[fullName] = contents;
@@ -1063,26 +1243,55 @@
       _writePage(
           buffer, 'Analysis Server - Context', ['Context: $contextFilter'],
           (StringBuffer buffer) {
-        buffer.write('<h3>Most Recently Perfomed Tasks</h3>');
-        AnalysisTask.LAST_TASKS.forEach((String description) {
-          buffer.write('<p>$description</p>');
-        });
+        buffer.write('<h3>Configuration</h3>');
 
-        String _describe(WorkItem item) {
-          if (item == null) {
-            return 'None';
+        _writeTwoColumns(buffer, (StringBuffer buffer) {
+          AnalysisOptionsImpl options = context.analysisOptions;
+          buffer.write('<p><b>Options</b></p>');
+          buffer.write('<p>');
+          _writeOption(
+              buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
+          _writeOption(buffer, 'Cache size', options.cacheSize);
+          _writeOption(buffer, 'Enable async support', options.enableAsync);
+          _writeOption(
+              buffer, 'Enable generic methods', options.enableGenericMethods);
+          _writeOption(buffer, 'Enable strict call checks',
+              options.enableStrictCallChecks);
+          _writeOption(
+              buffer, 'Enable super mixins', options.enableSuperMixins);
+          _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
+          _writeOption(buffer, 'Generate errors in implicit files',
+              options.generateImplicitErrors);
+          _writeOption(buffer, 'Generate errors in SDK files',
+              options.generateSdkErrors);
+          _writeOption(buffer, 'Generate hints', options.hint);
+          _writeOption(buffer, 'Incremental resolution', options.incremental);
+          _writeOption(buffer, 'Incremental resolution with API changes',
+              options.incrementalApi);
+          _writeOption(buffer, 'Preserve comments', options.preserveComments);
+          _writeOption(buffer, 'Strong mode', options.strongMode);
+          _writeOption(buffer, 'Strong mode hints', options.strongModeHints,
+              last: true);
+          buffer.write('</p>');
+        }, (StringBuffer buffer) {
+          List<Linter> lints =
+              context.getConfigurationData(CONFIGURED_LINTS_KEY);
+          buffer.write('<p><b>Lints</b></p>');
+          if (lints.isEmpty) {
+            buffer.write('<p>none</p>');
+          } else {
+            for (Linter lint in lints) {
+              buffer.write('<p>');
+              buffer.write(lint.runtimeType);
+              buffer.write('</p>');
+            }
           }
-          return '${item.descriptor?.name} computing ${item.spawningResult?.name} for ${item.target?.toString()}';
-        }
 
-        buffer.write('<h3>Work Items</h3>');
-        buffer.write(
-            '<p><b>Current:</b> ${_describe(driver.currentWorkOrder?.current)}</p>');
-        if (workItems != null) {
-          buffer.writeAll(workItems.reversed
-              .map((item) => '<p>${_describe(item)}</p>')
-              ?.toList());
-        }
+          List<ErrorProcessor> errorProcessors =
+              context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+          int processorCount = errorProcessors?.length ?? 0;
+          buffer.write('<p><b>Error Processor count</b>: $processorCount</p>');
+        });
 
         _writeFiles(buffer, 'Priority Files', priorityNames);
         _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
@@ -1090,12 +1299,71 @@
 
         buffer.write('<h3>Exceptions</h3>');
         if (exceptions.isEmpty) {
-          buffer.write('<p>None</p>');
+          buffer.write('<p>none</p>');
         } else {
           exceptions.forEach((CaughtException exception) {
             _writeException(buffer, exception);
           });
         }
+
+        buffer.write('<h3>Targets Without Entries</h3>');
+        bool foundEntry = false;
+        MapIterator<AnalysisTarget, CacheEntry> iterator =
+            context.analysisCache.iterator(context: context);
+        while (iterator.moveNext()) {
+          if (iterator.value == null) {
+            foundEntry = true;
+            buffer.write('<p>');
+            buffer.write(iterator.key.toString());
+            buffer.write(' (');
+            buffer.write(iterator.key.runtimeType.toString());
+            buffer.write(')</p>');
+          }
+        }
+        if (!foundEntry) {
+          buffer.write('<p>none</p>');
+        }
+      });
+    });
+  }
+
+  /**
+   * Return a response displaying the results of running a validation report on
+   * a single context.
+   */
+  void _returnContextValidationDiagnostics(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    Folder folder = _findFolder(analysisServer, contextFilter);
+    if (folder == null) {
+      return _returnFailure(request, 'Invalid context: $contextFilter');
+    }
+
+    InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Context Validation Diagnostics',
+          ['Context: $contextFilter'], (StringBuffer buffer) {
+        _writeContextValidationDiagnostics(buffer, context);
+      });
+    });
+  }
+
+  /**
+   * Return a response displaying diagnostic information.
+   */
+  void _returnDiagnosticInfo(HttpRequest request) {
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Diagnostic info', [],
+          (StringBuffer buffer) {
+        _writeDiagnosticStatus(buffer);
       });
     });
   }
@@ -1273,20 +1541,19 @@
   void _returnUnknownRequest(HttpRequest request) {
     _writeResponse(request, (StringBuffer buffer) {
       _writePage(buffer, 'Analysis Server', [], (StringBuffer buffer) {
-        buffer.write('<h3>Pages</h3>');
-        buffer.write('<p>');
-        buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer
-            .write(makeLink(COMMUNICATION_PERFORMANCE_PATH, {}, 'Performance'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer.write(makeLink(STATUS_PATH, {}, 'Server status'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer.write(makeLink(OVERLAYS_PATH, {}, 'File overlays'));
-        buffer.write('</p>');
+        buffer.write('<h3>Unknown page: ');
+        buffer.write(request.uri.path);
+        buffer.write('</h3>');
+        buffer.write('''
+        <p>
+        You have reached an un-recognized page. If you reached this page by
+        following a link from a status page, please report the broken link to
+        the Dart analyzer team:
+        <a>https://github.com/dart-lang/sdk/issues/new</a>.
+        </p><p>
+        If you mistyped the URL, you can correct it or return to
+        ${makeLink(STATUS_PATH, {}, 'the main status page')}.
+        </p>''');
       });
     });
   }
@@ -1312,7 +1579,6 @@
     List<Folder> folders = folderMap.keys.toList();
     folders.sort((Folder first, Folder second) =>
         first.shortName.compareTo(second.shortName));
-    AnalysisOptionsImpl options = analysisServer.defaultContextOptions;
     ServerOperationQueue operationQueue = analysisServer.operationQueue;
 
     buffer.write('<h3>Analysis Domain</h3>');
@@ -1332,6 +1598,9 @@
           buffer.write('<p>Status: Analyzing</p>');
         }
       }
+      buffer.write('<p>');
+      buffer.write(makeLink(OVERLAYS_PATH, {}, 'All overlay information'));
+      buffer.write('</p>');
 
       buffer.write('<p><b>Analysis Contexts</b></p>');
       buffer.write('<p>');
@@ -1345,38 +1614,22 @@
         String key = folder.shortName;
         buffer.write(makeLink(CONTEXT_PATH, {CONTEXT_QUERY_PARAM: folder.path},
             key, _hasException(folderMap[folder])));
+        buffer.write(' <small><b>[');
+        buffer.write(makeLink(CONTEXT_DIAGNOSTICS_PATH,
+            {CONTEXT_QUERY_PARAM: folder.path}, 'diagnostics'));
+        buffer.write(']</b></small>');
         if (!folder.getChild('.packages').exists) {
-          buffer.write(' <b>[No .packages file]</b>');
+          buffer.write(' <small>[no .packages file]</small>');
         }
       });
       // TODO(brianwilkerson) Add items for the SDK contexts (currently only one).
       buffer.write('</p>');
 
-      buffer.write('<p><b>Options</b></p>');
-      buffer.write('<p>');
-      _writeOption(
-          buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
-      _writeOption(buffer, 'Cache size', options.cacheSize);
-      _writeOption(
-          buffer, 'Enable strict call checks', options.enableStrictCallChecks);
-      _writeOption(buffer, 'Enable super mixins', options.enableSuperMixins);
-      _writeOption(buffer, 'Generate hints', options.hint);
-      _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
-      _writeOption(buffer, 'Generate errors in implicit files',
-          options.generateImplicitErrors);
-      _writeOption(
-          buffer, 'Generate errors in SDK files', options.generateSdkErrors);
-      _writeOption(buffer, 'Incremental resolution', options.incremental);
-      _writeOption(buffer, 'Incremental resolution with API changes',
-          options.incrementalApi);
-      _writeOption(buffer, 'Preserve comments', options.preserveComments,
-          last: true);
-      buffer.write('</p>');
       int freq = AnalysisServer.performOperationDelayFreqency;
       String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
-      buffer.write('<p><b>perform operation delay:</b> $delay</p>');
 
       buffer.write('<p><b>Performance Data</b></p>');
+      buffer.write('<p>Perform operation delay: $delay</p>');
       buffer.write('<p>');
       buffer.write(makeLink(ANALYSIS_PERFORMANCE_PATH, {}, 'Task data'));
       buffer.write('</p>');
@@ -1489,6 +1742,164 @@
   }
 
   /**
+   * Write diagnostic information about the given [context] to the given
+   * [buffer].
+   */
+  void _writeContextDiagnostics(
+      StringBuffer buffer, InternalAnalysisContext context) {
+    AnalysisDriver driver = (context as AnalysisContextImpl).driver;
+    List<WorkItem> workItems = driver.currentWorkOrder?.workItems;
+
+    buffer.write('<p>');
+    buffer.write(makeLink(CONTEXT_VALIDATION_DIAGNOSTICS_PATH,
+        {CONTEXT_QUERY_PARAM: context.name}, 'Run validation'));
+    buffer.write('</p>');
+
+    buffer.write('<h3>Most Recently Perfomed Tasks</h3>');
+    AnalysisTask.LAST_TASKS.forEach((String description) {
+      buffer.write('<p>');
+      buffer.write(description);
+      buffer.write('</p>');
+    });
+
+    void writeWorkItem(StringBuffer buffer, WorkItem item) {
+      if (item == null) {
+        buffer.write('none');
+      } else {
+        buffer.write(item.descriptor?.name);
+        buffer.write(' computing ');
+        buffer.write(item.spawningResult?.name);
+        buffer.write(' for ');
+        buffer.write(item.target);
+      }
+    }
+
+    buffer.write('<h3>Work Items</h3>');
+    buffer.write('<p><b>Current:</b> ');
+    writeWorkItem(buffer, driver.currentWorkOrder?.current);
+    buffer.write('</p>');
+    if (workItems != null) {
+      workItems.reversed.forEach((WorkItem item) {
+        buffer.write('<p>');
+        writeWorkItem(buffer, item);
+        buffer.write('</p>');
+      });
+    }
+  }
+
+  /**
+   * Write diagnostic information about the given [context] to the given
+   * [buffer].
+   */
+  void _writeContextValidationDiagnostics(
+      StringBuffer buffer, InternalAnalysisContext context) {
+    Stopwatch stopwatch = new Stopwatch();
+    stopwatch.start();
+    ValidationResults results = new ValidationResults(context);
+    stopwatch.stop();
+
+    buffer.write('<h3>Validation Results</h3>');
+    buffer.write('<p>Re-analysis took ');
+    buffer.write(stopwatch.elapsedMilliseconds);
+    buffer.write(' ms</p>');
+    results.writeOn(buffer);
+  }
+
+  /**
+   * Write the status of the diagnostic domain to the given [buffer].
+   */
+  void _writeDiagnosticStatus(StringBuffer buffer) {
+    var request = new DiagnosticGetDiagnosticsParams().toRequest('0');
+
+    var stopwatch = new Stopwatch();
+    stopwatch.start();
+    var response = diagnosticHandler.handleRequest(request);
+    stopwatch.stop();
+
+    int elapsedMs = stopwatch.elapsedMilliseconds;
+    _diagnosticCallAverage.addSample(elapsedMs);
+
+    buffer.write('<h3>Timing</h3>');
+
+    buffer.write('<p>getDiagnostic (last call): ');
+    buffer.write(elapsedMs);
+    buffer.write(' (ms)</p>');
+    buffer.write('<p>getDiagnostic (rolling average): ');
+    buffer.write(_diagnosticCallAverage.value);
+    buffer.write(' (ms)</p>&nbsp;');
+
+    var json = response.toJson()[Response.RESULT];
+    List contexts = json['contexts'];
+    contexts.sort((first, second) => first['name'].compareTo(second['name']));
+
+    // Track visited libraries.
+    Set<LibraryElement> libraries = new HashSet<LibraryElement>();
+
+    // Count SDK elements separately.
+    ElementCounter sdkCounter = new ElementCounter();
+
+    for (var context in contexts) {
+      buffer.write('<p><h3>');
+      buffer.write(context['name']);
+      buffer.write('</h3></p>');
+      buffer.write('<p>explicitFileCount: ');
+      buffer.write(context['explicitFileCount']);
+      buffer.write('</p>');
+      buffer.write('<p>implicitFileCount: ');
+      buffer.write(context['implicitFileCount']);
+      buffer.write('</p>');
+      buffer.write('<p>workItemQueueLength: ');
+      buffer.write(context['workItemQueueLength']);
+      buffer.write('</p>');
+
+      AnalysisServer server = _server.analysisServer;
+
+      if (server != null) {
+        Folder folder = _findFolder(server, context['name']);
+        InternalAnalysisContext ac = _server.analysisServer.folderMap[folder];
+        ElementCounter counter = new ElementCounter();
+
+        for (Source source in ac.librarySources) {
+          LibraryElement libraryElement = ac.getLibraryElement(source);
+          if (libraries.add(libraryElement)) {
+            if (libraryElement != null) {
+              if (libraryElement.isInSdk) {
+                libraryElement.accept(sdkCounter);
+              } else {
+                libraryElement.accept(counter);
+              }
+            }
+          }
+        }
+        buffer.write('<p>element count: ');
+        buffer.write(
+            counter.counts.values.fold(0, (prev, element) => prev + element));
+        buffer.write('</p>');
+        buffer.write('<p>  (w/docs): ');
+        buffer.write(counter.elementsWithDocs);
+        buffer.write('</p>');
+        buffer.write('<p>total doc span: ');
+        buffer.write(counter.totalDocSpan);
+        buffer.write('</p>');
+      }
+    }
+
+    buffer.write('<p><h3>');
+    buffer.write('SDK');
+    buffer.write('</h3></p>');
+    buffer.write('<p>element count: ');
+    buffer.write(
+        sdkCounter.counts.values.fold(0, (prev, element) => prev + element));
+    buffer.write('</p>');
+    buffer.write('<p>  (w/docs): ');
+    buffer.write(sdkCounter.elementsWithDocs);
+    buffer.write('</p>');
+    buffer.write('<p>total doc span: ');
+    buffer.write(sdkCounter.totalDocSpan);
+    buffer.write('</p>');
+  }
+
+  /**
    * Write the status of the edit domain (on the main status page) to the given
    * [buffer].
    */
@@ -1558,6 +1969,12 @@
     }
   }
 
+  void _writeListItem(StringBuffer buffer, writer()) {
+    buffer.write('<li>');
+    writer();
+    buffer.write('</li>');
+  }
+
   void _writeListOfStrings(
       StringBuffer buffer, String listName, Iterable<String> items) {
     List<String> itemList = items.toList();
@@ -1566,12 +1983,12 @@
       b = b.toLowerCase();
       return a.compareTo(b);
     });
-    buffer.write('List "listName" containing ${itemList.length} entries:');
+    buffer.write('List "$listName" containing ${itemList.length} entries:');
     buffer.write('<ul>');
     for (String member in itemList) {
-      buffer.write('<li>');
-      buffer.write(member);
-      buffer.write('</li>');
+      _writeListItem(buffer, () {
+        buffer.write(member);
+      });
     }
     buffer.write('</ul>');
   }
@@ -1619,6 +2036,8 @@
     buffer.write(
         'h3 {background-color: #DDDDDD; margin-top: 0em; margin-bottom: 0em;}');
     buffer.write('p {margin-top: 0.5em; margin-bottom: 0.5em;}');
+    buffer.write(
+        'p.commentary {margin-top: 1em; margin-bottom: 1em; margin-left: 2em; font-style: italic;}');
 //    response.write('span.error {text-decoration-line: underline; text-decoration-color: red; text-decoration-style: wavy;}');
     buffer.write(
         'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}');
@@ -1769,6 +2188,9 @@
       buffer.write('<br>');
       buffer.write('Version: ');
       buffer.write(AnalysisServer.VERSION);
+      buffer.write('<br>');
+      buffer.write('Process ID: ');
+      buffer.write(pid);
       buffer.write('</p>');
 
       buffer.write('<p><b>Performance Data</b></p>');
@@ -1776,6 +2198,9 @@
       buffer.write(makeLink(
           COMMUNICATION_PERFORMANCE_PATH, {}, 'Communication performance'));
       buffer.write('</p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(DIAGNOSTIC_PATH, {}, 'General diagnostics'));
+      buffer.write('</p>');
     }, (StringBuffer buffer) {
       _writeSubscriptionList(buffer, ServerService.VALUES, services);
     });
@@ -1929,9 +2354,9 @@
       buffer.write('List containing ${value.length} entries');
       buffer.write('<ul>');
       for (var entry in value) {
-        buffer.write('<li>');
-        _writeValueAsHtml(buffer, entry, linkParameters);
-        buffer.write('</li>');
+        _writeListItem(buffer, () {
+          _writeValueAsHtml(buffer, entry, linkParameters);
+        });
       }
       buffer.write('</ul>');
     } else if (value is AstNode) {
@@ -1944,19 +2369,24 @@
       buffer.write('<i>$link</i>');
     } else if (value is UsedLocalElements) {
       buffer.write('<ul>');
-      {
+      _writeListItem(buffer, () {
         HashSet<Element> elements = value.elements;
         buffer.write('List "elements" containing ${elements.length} entries');
         buffer.write('<ul>');
         for (Element element in elements) {
-          buffer.write('<li>');
-          buffer.write('<i>${element.runtimeType}</i>  $element');
-          buffer.write('</li>');
+          _writeListItem(buffer, () {
+            String elementStr = HTML_ESCAPE.convert(element.toString());
+            buffer.write('<i>${element.runtimeType}</i>  $elementStr');
+          });
         }
         buffer.write('</ul>');
-      }
-      _writeListOfStrings(buffer, 'members', value.members);
-      _writeListOfStrings(buffer, 'readMembers', value.readMembers);
+      });
+      _writeListItem(buffer, () {
+        _writeListOfStrings(buffer, 'members', value.members);
+      });
+      _writeListItem(buffer, () {
+        _writeListOfStrings(buffer, 'readMembers', value.readMembers);
+      });
       buffer.write('</ul>');
     } else {
       buffer.write(HTML_ESCAPE.convert(value.toString()));
diff --git a/pkg/analysis_server/lib/src/status/tree_writer.dart b/pkg/analysis_server/lib/src/status/tree_writer.dart
index 4b5b3a4..d50a78e 100644
--- a/pkg/analysis_server/lib/src/status/tree_writer.dart
+++ b/pkg/analysis_server/lib/src/status/tree_writer.dart
@@ -2,13 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analysis_server.src.status.ast_writer;
+library analysis_server.src.status.tree_writer;
 
 import 'dart:convert';
 
-import 'package:analysis_server/src/get_handler.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/status/validator.dart b/pkg/analysis_server/lib/src/status/validator.dart
new file mode 100644
index 0000000..10dc8ac
--- /dev/null
+++ b/pkg/analysis_server/lib/src/status/validator.dart
@@ -0,0 +1,1788 @@
+// 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 analysis_server.src.status.validator;
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisEngine, AnalysisResult, CacheState, ChangeSet;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/task/html.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:html/dom.dart' as html;
+
+/**
+ * A class used to compare two element models for equality.
+ */
+class ElementComparator {
+  /**
+   * The buffer to which any discovered differences will be recorded.
+   */
+  final StringBuffer _buffer = new StringBuffer();
+
+  /**
+   * A flag indicating whether a line break should be added the next time data
+   * is written to the [_buffer].
+   */
+  bool _needsLineBreak = false;
+
+  /**
+   * Initialize a newly created comparator.
+   */
+  ElementComparator();
+
+  /**
+   * A textual description of the differences that were found.
+   */
+  String get description => _buffer.toString();
+
+  /**
+   * Return `true` if at least one difference was found between the expected and
+   * actual elements.
+   */
+  bool get hasDifference => _buffer.length > 0;
+
+  /**
+   * Compare the [expected] and [actual] elements. The results of the comparison
+   * can be accessed via the [hasDifference] and [description] getters.
+   */
+  void compareElements(Element expected, Element actual) {
+    if (expected == null) {
+      if (actual != null) {
+        _writeMismatch(expected, actual, (Element element) {
+          return element == null ? 'null' : 'non null ${element.runtimeType}';
+        });
+      }
+    } else if (actual == null) {
+      _writeMismatch(expected, actual, (Element element) {
+        return element == null ? 'null' : 'non null ${element.runtimeType}';
+      });
+    } else if (expected is ClassElement && actual is ClassElement) {
+      _compareClassElements(expected, actual);
+    } else if (expected is CompilationUnitElement &&
+        actual is CompilationUnitElement) {
+      _compareCompilationUnitElements(expected, actual);
+    } else if (expected is ConstructorElement && actual is ConstructorElement) {
+      _compareConstructorElements(expected, actual);
+    } else if (expected is ExportElement && actual is ExportElement) {
+      _compareExportElements(expected, actual);
+    } else if (expected is FieldElement && actual is FieldElement) {
+      _compareFieldElements(expected, actual);
+    } else if (expected is FieldFormalParameterElement &&
+        actual is FieldFormalParameterElement) {
+      _compareFieldFormalParameterElements(expected, actual);
+    } else if (expected is FunctionElement && actual is FunctionElement) {
+      _compareFunctionElements(expected, actual);
+    } else if (expected is FunctionTypeAliasElement &&
+        actual is FunctionTypeAliasElement) {
+      _compareFunctionTypeAliasElements(expected, actual);
+    } else if (expected is ImportElement && actual is ImportElement) {
+      _compareImportElements(expected, actual);
+    } else if (expected is LabelElement && actual is LabelElement) {
+      _compareLabelElements(expected, actual);
+    } else if (expected is LibraryElement && actual is LibraryElement) {
+      _compareLibraryElements(expected, actual);
+    } else if (expected is LocalVariableElement &&
+        actual is LocalVariableElement) {
+      _compareLocalVariableElements(expected, actual);
+    } else if (expected is MethodElement && actual is MethodElement) {
+      _compareMethodElements(expected, actual);
+    } else if (expected is MultiplyDefinedElement &&
+        actual is MultiplyDefinedElement) {
+      _compareMultiplyDefinedElements(expected, actual);
+    } else if (expected is ParameterElement && actual is ParameterElement) {
+      _compareParameterElements(expected, actual);
+    } else if (expected is PrefixElement && actual is PrefixElement) {
+      _comparePrefixElements(expected, actual);
+    } else if (expected is PropertyAccessorElement &&
+        actual is PropertyAccessorElement) {
+      _comparePropertyAccessorElements(expected, actual);
+    } else if (expected is TopLevelVariableElement &&
+        actual is TopLevelVariableElement) {
+      _compareTopLevelVariableElements(expected, actual);
+    } else if (expected is TypeParameterElement &&
+        actual is TypeParameterElement) {
+      _compareTypeParameterElements(expected, actual);
+    } else {
+      _write('Expected an instance of ');
+      _write(expected.runtimeType);
+      _write('; found an instance of ');
+      _writeln(actual.runtimeType);
+    }
+  }
+
+  void _compareClassElements(ClassElement expected, ClassElement actual) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if (expected.hasReferenceToSuper != actual.hasReferenceToSuper) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) => element.hasReferenceToSuper
+              ? 'a class that references super'
+              : 'a class that does not reference super');
+    }
+    if (expected.isAbstract != actual.isAbstract) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) =>
+              element.isAbstract ? 'an abstract class' : 'a concrete class');
+    }
+    if (expected.isEnum != actual.isEnum ||
+        expected.isMixinApplication != actual.isMixinApplication) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) => element.isEnum
+              ? 'an enum'
+              : (element.isMixinApplication
+                  ? 'a mixin application'
+                  : 'a class'));
+    }
+    if (expected.isOrInheritsProxy != actual.isOrInheritsProxy) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) => element.isOrInheritsProxy
+              ? 'a class that is marked as a proxy'
+              : 'a class that is not marked as a proxy');
+    }
+    if (expected.isValidMixin != actual.isValidMixin) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) =>
+              element.isValidMixin ? 'a valid mixin' : 'an invalid mixin');
+    }
+    _compareTypes('supertype', expected.supertype, actual.supertype);
+    _compareTypeLists('mixin', expected.mixins, actual.mixins);
+    _compareTypeLists('interface', expected.interfaces, actual.interfaces);
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.accessors, actual.accessors);
+    _compareElementLists(expected.constructors, actual.constructors);
+    _compareElementLists(expected.fields, actual.fields);
+    _compareElementLists(expected.methods, actual.methods);
+    _compareElementLists(expected.typeParameters, actual.typeParameters);
+  }
+
+  void _compareCompilationUnitElements(
+      CompilationUnitElement expected, CompilationUnitElement actual) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.accessors, actual.accessors);
+    _compareElementLists(expected.enums, actual.enums);
+    _compareElementLists(expected.functions, actual.functions);
+    _compareElementLists(
+        expected.functionTypeAliases, actual.functionTypeAliases);
+    _compareElementLists(expected.topLevelVariables, actual.topLevelVariables);
+    _compareElementLists(expected.types, actual.types);
+  }
+
+  void _compareConstructorElements(
+      ConstructorElement expected, ConstructorElement actual) {
+    _compareExecutableElements(expected, actual, 'constructor');
+    //
+    // Compare attributes.
+    //
+    if (expected.isConst != actual.isConst) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ConstructorElement element) => element.isConst
+              ? 'a const constructor'
+              : 'a non-const constructor');
+    }
+    if (expected.isFactory != actual.isFactory) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ConstructorElement element) => element.isFactory
+              ? 'a factory constructor'
+              : 'a non-factory constructor');
+    }
+    if (expected.periodOffset != actual.periodOffset) {
+      _write('Expected a period offset of ');
+      _write(expected.periodOffset);
+      _write('; found ');
+      _writeln(actual.periodOffset);
+    }
+    if ((expected.redirectedConstructor == null) !=
+        (actual.redirectedConstructor == null)) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ConstructorElement element) => element.redirectedConstructor == null
+              ? 'a redirecting constructor'
+              : 'a non-redirecting constructor');
+    }
+  }
+
+  void _compareElementLists(List expected, List actual) {
+    Set<Element> extraElements = new HashSet<Element>();
+    Map<Element, Element> commonElements = new HashMap<Element, Element>();
+
+    Map<String, Element> expectedElements = new HashMap<String, Element>();
+    for (Element expectedElement in expected) {
+      expectedElements[expectedElement.name] = expectedElement;
+    }
+    for (Element actualElement in actual) {
+      String name = actualElement.name;
+      Element expectedElement = expectedElements[name];
+      if (expectedElement == null) {
+        extraElements.add(actualElement);
+      } else {
+        commonElements[expectedElement] = actualElement;
+        expectedElements.remove(name);
+      }
+    }
+
+    commonElements.forEach((Element expected, Element actual) {
+      compareElements(expected, actual);
+    });
+    void writeElement(Element element) {
+      _write('an instance of ');
+      _write(element.runtimeType);
+      if (element.name == null) {
+        _write(' with no name');
+      } else {
+        _write(' named ');
+        _write(element.name);
+      }
+    }
+    expectedElements.forEach((String name, Element element) {
+      _write('Expected ');
+      writeElement(element);
+      _writeln('; found no match');
+    });
+    extraElements.forEach((Element element) {
+      _write('Expected nothing; found ');
+      writeElement(element);
+    });
+  }
+
+  void _compareExecutableElements(
+      ExecutableElement expected, ExecutableElement actual, String kind) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if (expected.hasImplicitReturnType != actual.hasImplicitReturnType) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.hasImplicitReturnType
+              ? 'an implicit return type'
+              : 'an explicit return type');
+    }
+    if (expected.isAbstract != actual.isAbstract) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) =>
+              element.isAbstract ? 'an abstract $kind' : 'a concrete $kind');
+    }
+    if (expected.isAsynchronous != actual.isAsynchronous) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.isAsynchronous
+              ? 'an asynchronous $kind'
+              : 'a synchronous $kind');
+    }
+    if (expected.isExternal != actual.isExternal) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.isExternal
+              ? 'an external $kind'
+              : 'a non-external $kind');
+    }
+    if (expected.isGenerator != actual.isGenerator) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.isGenerator
+              ? 'a generator $kind'
+              : 'a non-generator $kind');
+    }
+    if (expected.isOperator != actual.isOperator) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) =>
+              element.isOperator ? 'an operator' : 'a non-operator $kind');
+    }
+    if (expected.isStatic != actual.isStatic) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) =>
+              element.isStatic ? 'a static $kind' : 'an instance $kind');
+    }
+    if ((expected.returnType == null) != (actual.returnType == null)) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.returnType == null
+              ? 'a $kind with no return type'
+              : 'a $kind with a return type');
+    } else {
+      _compareTypes('return type', expected.returnType, actual.returnType);
+    }
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.functions, actual.functions);
+    _compareElementLists(expected.labels, actual.labels);
+    _compareElementLists(expected.localVariables, actual.localVariables);
+    _compareElementLists(expected.parameters, actual.parameters);
+    _compareElementLists(expected.typeParameters, actual.typeParameters);
+  }
+
+  void _compareExportElements(ExportElement expected, ExportElement actual) {
+    _compareUriReferencedElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if ((expected.exportedLibrary == null) !=
+        (actual.exportedLibrary == null)) {
+      // TODO(brianwilkerson) Check for more than existence?
+      _writeMismatch(
+          expected,
+          actual,
+          (ExportElement element) => element.exportedLibrary == null
+              ? 'unresolved uri'
+              : 'uri resolved to ${element.exportedLibrary.source.fullName}');
+    }
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.combinators, actual.combinators);
+  }
+
+  void _compareFieldElements(FieldElement expected, FieldElement actual) {
+    _comparePropertyInducingElements(expected, actual, 'field');
+    //
+    // Compare attributes.
+    //
+    if (expected.isEnumConstant != actual.isEnumConstant) {
+      _writeMismatch(
+          expected,
+          actual,
+          (FieldElement element) =>
+              element.isEnumConstant ? 'an enum constant' : 'a normal field');
+    }
+  }
+
+  void _compareFieldFormalParameterElements(
+      FieldFormalParameterElement expected,
+      FieldFormalParameterElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareFunctionElements(
+      FunctionElement expected, FunctionElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareFunctionTypeAliasElements(
+      FunctionTypeAliasElement expected, FunctionTypeAliasElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareGenericElements(Element expected, Element actual) {
+    _compareMetadata(expected.metadata, actual.metadata);
+    if (expected.nameOffset != actual.nameOffset) {
+      _write('Expected name offset of ');
+      _write(expected.nameOffset);
+      _write('; found ');
+      _writeln(actual.nameOffset);
+    }
+    SourceRange expectedRange = expected.docRange;
+    SourceRange actualRange = actual.docRange;
+    if (expectedRange.offset != actualRange.offset ||
+        expectedRange.length != actualRange.length) {
+      _write('Expected documentation range of ');
+      _write(expectedRange);
+      _write('; found ');
+      _writeln(actualRange);
+    }
+  }
+
+  void _compareImportElements(ImportElement expected, ImportElement actual) {
+    _compareUriReferencedElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if (expected.isDeferred != actual.isDeferred) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ImportElement element) => element.isDeferred
+              ? 'a deferred import'
+              : 'a non-deferred import');
+    }
+    if ((expected.importedLibrary == null) !=
+        (actual.importedLibrary == null)) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ImportElement element) => element.importedLibrary == null
+              ? 'unresolved uri'
+              : 'uri resolved to ${element.importedLibrary.source.fullName}');
+    }
+    if ((expected.prefix == null) != (actual.prefix == null)) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ImportElement element) => element.prefix == null
+              ? 'no prefix'
+              : 'a prefix named ${element.prefix.name}');
+    }
+    if (expected.prefixOffset != actual.prefixOffset) {
+      _write('Expected a prefix offset of ');
+      _write(expected.prefixOffset);
+      _write('; found ');
+      _writeln(actual.prefixOffset);
+    }
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.combinators, actual.combinators);
+  }
+
+  void _compareLabelElements(LabelElement expected, LabelElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareLibraryElements(LibraryElement expected, LibraryElement actual) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    // TODO(brianwilkerson) Implement this
+    expected.hasLoadLibraryFunction;
+    expected.name;
+    expected.source;
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.imports, actual.imports);
+    _compareElementLists(expected.exports, actual.exports);
+    _compareElementLists(expected.units, actual.units);
+  }
+
+  void _compareLocalVariableElements(
+      LocalVariableElement expected, LocalVariableElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareMetadata(
+      List<ElementAnnotation> expected, List<ElementAnnotation> actual) {
+    // TODO(brianwilkerson) Implement this
+  }
+
+  void _compareMethodElements(MethodElement expected, MethodElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareExecutableElements(expected, actual, 'method');
+    //
+    // Compare attributes.
+    //
+    if (expected.isStatic != actual.isStatic) {
+      _writeMismatch(
+          expected,
+          actual,
+          (FieldElement element) =>
+              element.isStatic ? 'a static field' : 'an instance field');
+    }
+  }
+
+  void _compareMultiplyDefinedElements(
+      MultiplyDefinedElement expected, MultiplyDefinedElement actual) {
+    // TODO(brianwilkerson) Implement this
+  }
+
+  void _compareParameterElements(
+      ParameterElement expected, ParameterElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _comparePrefixElements(PrefixElement expected, PrefixElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _comparePropertyAccessorElements(
+      PropertyAccessorElement expected, PropertyAccessorElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _comparePropertyInducingElements(PropertyInducingElement expected,
+      PropertyInducingElement actual, String kind) {
+    _compareVariableElements(expected, actual, kind);
+  }
+
+  void _compareTopLevelVariableElements(
+      TopLevelVariableElement expected, TopLevelVariableElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareTypeLists(String descriptor, List<InterfaceType> expected,
+      List<InterfaceType> actual) {
+    int expectedLength = expected.length;
+    if (expectedLength != actual.length) {
+      _write('Expected ');
+      _write(expectedLength);
+      _write(' ');
+      _write(descriptor);
+      _write('s; found ');
+      _write(actual.length);
+    } else {
+      for (int i = 0; i < expectedLength; i++) {
+        _compareTypes(descriptor, expected[i], actual[i]);
+      }
+    }
+  }
+
+  void _compareTypeParameterElements(
+      TypeParameterElement expected, TypeParameterElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+    expected.bound;
+  }
+
+  void _compareTypes(String descriptor, DartType expected, DartType actual) {
+    void compareNames() {
+      if (expected.name != actual.name) {
+        _write('Expected a ');
+        _write(descriptor);
+        _write(' named ');
+        _write(expected.name);
+        _write('; found a ');
+        _write(descriptor);
+        _write(' named ');
+        _write(actual.name);
+      }
+    }
+    void compareTypeArguments(
+        ParameterizedType expected, ParameterizedType actual) {
+      List<DartType> expectedArguments = expected.typeArguments;
+      List<DartType> actualArguments = actual.typeArguments;
+      int expectedLength = expectedArguments.length;
+      if (expectedLength != actualArguments.length) {
+        _write('Expected ');
+        _write(expectedLength);
+        _write(' type arguments; found ');
+        _write(actualArguments.length);
+      } else {
+        for (int i = 0; i < expectedLength; i++) {
+          _compareTypes(
+              'type argument', expectedArguments[i], actualArguments[i]);
+        }
+      }
+    }
+
+    if (expected == null) {
+      if (actual != null) {
+        _write('Expected no ');
+        _write(descriptor);
+        _write('; found a ');
+        _write(descriptor);
+        _write(' named ');
+        _write(actual.name);
+      }
+    } else if (actual == null) {
+      _write('Expected a ');
+      _write(descriptor);
+      _write(' named ');
+      _write(expected.name);
+      _write('; found none');
+    } else if ((expected.isBottom && actual.isBottom) ||
+        (expected.isDynamic && actual.isDynamic) ||
+        (expected.isVoid && actual.isVoid)) {
+      // The types are the same
+    } else if (expected is InterfaceType && actual is InterfaceType) {
+      compareNames();
+      compareTypeArguments(expected, actual);
+    } else if (expected is FunctionType && actual is FunctionType) {
+      compareNames();
+      compareTypeArguments(expected, actual);
+    } else if (expected is TypeParameterType && actual is TypeParameterType) {
+      compareNames();
+      _compareTypes('bound', expected.element.bound, actual.element.bound);
+    } else {
+      _write('Expected an instance of ');
+      _write(expected.runtimeType);
+      _write(' named ');
+      _write(expected.name);
+      _write('; found an instance of ');
+      _writeln(actual.runtimeType);
+      _write(' named ');
+      _write(actual.name);
+    }
+  }
+
+  void _compareUriReferencedElements(
+      UriReferencedElement expected, UriReferencedElement actual) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if (expected.uri != actual.uri) {
+      _write('Expected a uri of ');
+      _write(expected.uri);
+      _write('; found ');
+      _writeln(actual.uri);
+    }
+    if (expected.uriOffset != actual.uriOffset) {
+      _write('Expected a uri offset of ');
+      _write(expected.uriOffset);
+      _write('; found ');
+      _writeln(actual.uriOffset);
+    }
+  }
+
+  void _compareVariableElements(
+      VariableElement expected, VariableElement actual, String kind) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if ((expected.constantValue == null) != (actual.constantValue == null)) {
+      // TODO(brianwilkerson) Check for more than existence.
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) => element.constantValue == null
+              ? 'a $kind with no constant value'
+              : 'a $kind with a constant value');
+    }
+    if (expected.hasImplicitType != actual.hasImplicitType) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) => element.hasImplicitType
+              ? 'a $kind with an implicit type'
+              : 'a $kind with an explicit type');
+    }
+    if (expected.isConst != actual.isConst) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) =>
+              element.isConst ? 'a const $kind' : 'a non-const $kind');
+    }
+    if (expected.isFinal != actual.isFinal) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) =>
+              element.isFinal ? 'a final $kind' : 'a non-final $kind');
+    }
+    if (expected.isPotentiallyMutatedInClosure !=
+        actual.isPotentiallyMutatedInClosure) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) => element.isPotentiallyMutatedInClosure
+              ? 'a $kind that is potentially mutated in a closure'
+              : 'a $kind that is not mutated in a closure');
+    }
+    if (expected.isPotentiallyMutatedInScope !=
+        actual.isPotentiallyMutatedInScope) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) => element.isPotentiallyMutatedInScope
+              ? 'a $kind that is potentially mutated in its scope'
+              : 'a $kind that is not mutated in its scope');
+    }
+    if (expected.isStatic != actual.isStatic) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) =>
+              element.isStatic ? 'a static $kind' : 'an instance $kind');
+    }
+    //
+    // Compare children.
+    //
+    compareElements(expected.initializer, actual.initializer);
+  }
+
+  void _write(Object value) {
+    if (_needsLineBreak) {
+      _buffer.write('</p><p>');
+      _needsLineBreak = false;
+    }
+    _buffer.write(value);
+  }
+
+  void _writeln(Object value) {
+    _buffer.write(value);
+    _needsLineBreak = true;
+  }
+
+  /**
+   * Write a simple message explaining that the [expected] and [actual] values
+   * were different, using the [describe] function to describe the values.
+   */
+  void _writeMismatch /*<E>*/ (Object /*=E*/ expected, Object /*=E*/ actual,
+      String describe(Object /*=E*/ value)) {
+    _write('Expected ');
+    _write(describe(expected));
+    _write('; found ');
+    _writeln(describe(actual));
+  }
+}
+
+/**
+ * The comparison of two analyses of the same target.
+ */
+class EntryComparison {
+  /**
+   * The target that was analyzed.
+   */
+  final AnalysisTarget target;
+
+  /**
+   * The cache entry from the original context.
+   */
+  final CacheEntry originalEntry;
+
+  /**
+   * The cache entry from the re-analysis in a cloned context.
+   */
+  final CacheEntry cloneEntry;
+
+  /**
+   * A flag indicating whether the target is obsolete. A target is obsolete if
+   * it is an element in an element model that was replaced at a some point.
+   */
+  bool obsoleteTarget = false;
+
+  /**
+   * A table mapping the results that were computed for the target to
+   * comparisons of the values of those results. The table only contains entries
+   * for results for which the comparison produced interesting data.
+   */
+  Map<ResultDescriptor, ResultComparison> resultMap =
+      new HashMap<ResultDescriptor, ResultComparison>();
+
+  /**
+   * Initialize a newly created comparison of the given [target]'s analysis,
+   * given the [originalEntry] from the original context and the [cloneEntry]
+   * from the cloned context.
+   */
+  EntryComparison(this.target, this.originalEntry, this.cloneEntry) {
+    _performComparison();
+  }
+
+  /**
+   * Return `true` if there is something interesting about the analysis of this
+   * target that should be reported.
+   */
+  bool hasInterestingState() => obsoleteTarget || resultMap.isNotEmpty;
+
+  /**
+   * Write an HTML formatted description of the validation results to the given
+   * [buffer].
+   */
+  void writeOn(StringBuffer buffer) {
+    buffer.write('<p>');
+    buffer.write(target);
+    buffer.write('</p>');
+    buffer.write('<blockquote>');
+    if (obsoleteTarget) {
+      buffer.write('<p><b>This target is obsolete.</b></p>');
+    }
+    List<ResultDescriptor> results = resultMap.keys.toList();
+    results.sort((ResultDescriptor first, ResultDescriptor second) =>
+        first.toString().compareTo(second.toString()));
+    for (ResultDescriptor result in results) {
+      resultMap[result].writeOn(buffer);
+    }
+    buffer.write('</blockquote>');
+  }
+
+  /**
+   * Compare all of the results that were computed in the two contexts, adding
+   * the interesting comparisons to the [resultMap].
+   */
+  void _compareResults() {
+    Set<ResultDescriptor> results = new Set<ResultDescriptor>();
+    results.addAll(originalEntry.nonInvalidResults);
+    results.addAll(cloneEntry.nonInvalidResults);
+
+    for (ResultDescriptor result in results) {
+      ResultComparison difference = new ResultComparison(this, result);
+      if (difference.hasInterestingState()) {
+        resultMap[result] = difference;
+      }
+    }
+  }
+
+  /**
+   * Return `true` if the target of this entry is an obsolete element.
+   */
+  bool _isTargetObsolete() {
+    if (target is Element) {
+      LibraryElement library = (target as Element).library;
+      AnalysisContextImpl context = library.context;
+      CacheEntry entry = context.analysisCache.get(library.source);
+      LibraryElement value = entry.getValue(LIBRARY_ELEMENT);
+      return value != library;
+    }
+    return false;
+  }
+
+  /**
+   * Determine whether or not there is any interesting difference between the
+   * original and cloned contexts.
+   */
+  void _performComparison() {
+    obsoleteTarget = _isTargetObsolete();
+    _compareResults();
+  }
+}
+
+/**
+ * The comparison of the value of a single result computed for a single target.
+ */
+class ResultComparison {
+  /**
+   * The entry for the target for which the result was computed.
+   */
+  final EntryComparison entry;
+
+  /**
+   * The result that was computed for the target.
+   */
+  final ResultDescriptor result;
+
+  /**
+   * A flag indicating whether the state of the result is different.
+   */
+  bool differentStates = false;
+
+  /**
+   * The result of comparing the values of the results, or `null` if the states
+   * are different or if the values are the same.
+   */
+  ValueComparison valueComparison;
+
+  /**
+   * Initialize a newly created result comparison.
+   */
+  ResultComparison(this.entry, this.result) {
+    _performComparison();
+  }
+
+  /**
+   * Return `true` if this object represents a difference between the original
+   * and cloned contexts.
+   */
+  bool hasInterestingState() => differentStates || valueComparison != null;
+
+  /**
+   * Write an HTML formatted description of the validation results to the given
+   * [buffer].
+   */
+  void writeOn(StringBuffer buffer) {
+    buffer.write('<p>');
+    buffer.write(result);
+    buffer.write('</p>');
+    buffer.write('<blockquote>');
+    if (differentStates) {
+      CacheState originalState = entry.originalEntry.getState(result);
+      CacheState cloneState = entry.cloneEntry.getState(result);
+      buffer.write('<p>Original state = ');
+      buffer.write(originalState.name);
+      buffer.write('; clone state = ');
+      buffer.write(cloneState.name);
+      buffer.write('</p>');
+    }
+    if (valueComparison != null) {
+      valueComparison.writeOn(buffer);
+    }
+    buffer.write('</blockquote>');
+  }
+
+  /**
+   * Determine whether the state of the result is different between the
+   * original and cloned contexts.
+   */
+  bool _areStatesDifferent(CacheState originalState, CacheState cloneState) {
+    if (originalState == cloneState) {
+      return false;
+    } else if (originalState == CacheState.FLUSHED &&
+        cloneState == CacheState.VALID) {
+      return false;
+    } else if (originalState == CacheState.VALID &&
+        cloneState == CacheState.FLUSHED) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Determine whether the value of the result is different between the
+   * original and cloned contexts.
+   */
+  void _compareValues(CacheState originalState, CacheState cloneState) {
+    if (originalState != cloneState || originalState != CacheState.VALID) {
+      return null;
+    }
+    ValueComparison comparison = new ValueComparison(
+        entry.originalEntry.getValue(result),
+        entry.cloneEntry.getValue(result));
+    if (comparison.hasInterestingState()) {
+      valueComparison = comparison;
+    }
+  }
+
+  /**
+   * Determine whether or not there is any interesting difference between the
+   * original and cloned contexts.
+   */
+  void _performComparison() {
+    CacheState originalState = entry.originalEntry.getState(result);
+    CacheState cloneState = entry.cloneEntry.getState(result);
+    if (_areStatesDifferent(originalState, cloneState)) {
+      differentStates = true;
+      _compareValues(originalState, cloneState);
+    }
+  }
+}
+
+/**
+ * The results of validating an analysis context.
+ *
+ * Validation is done by re-analyzing all of the explicitly added source in a
+ * new analysis context that is configured to be the same as the original
+ * context.
+ */
+class ValidationResults {
+  /**
+   * A set of targets that were in the original context that were not included
+   * in the re-created context.
+   */
+  Set<AnalysisTarget> extraTargets;
+
+  /**
+   * A set of targets that were in the re-created context that were not included
+   * in the original context.
+   */
+  Set<AnalysisTarget> missingTargets;
+
+  /**
+   * A table, keyed by targets, whose values are comparisons of the analysis of
+   * those targets. The table only contains entries for targets for which the
+   * comparison produced interesting data.
+   */
+  Map<AnalysisTarget, EntryComparison> targetMap =
+      new HashMap<AnalysisTarget, EntryComparison>();
+
+  /**
+   * Initialize a newly created validation result by validating the given
+   * [context].
+   */
+  ValidationResults(AnalysisContextImpl context) {
+    _validate(context);
+  }
+
+  /**
+   * Write an HTML formatted description of the validation results to the given
+   * [buffer].
+   */
+  void writeOn(StringBuffer buffer) {
+    if (extraTargets.isEmpty && missingTargets.isEmpty && targetMap.isEmpty) {
+      buffer.write('<p>No interesting results.</p>');
+      return;
+    }
+    if (extraTargets.isNotEmpty) {
+      buffer.write('<h4>Extra Targets</h4>');
+      buffer.write('<p style="commentary">');
+      buffer.write('Targets that exist in the original context that were not ');
+      buffer.write('re-created in the cloned context.');
+      buffer.write('</p>');
+      _writeTargetList(buffer, extraTargets.toList());
+    }
+    if (missingTargets.isNotEmpty) {
+      buffer.write('<h4>Missing Targets</h4>');
+      buffer.write('<p style="commentary">');
+      buffer.write('Targets that do <b>not</b> exist in the original context ');
+      buffer.write('but do exist in the cloned context.');
+      buffer.write('</p>');
+      _writeTargetList(buffer, missingTargets.toList());
+    }
+    if (targetMap.isNotEmpty) {
+      buffer.write('<h4>Differing Targets</h4>');
+      // TODO(brianwilkerson) Sort the list of targets.
+      for (EntryComparison comparison in targetMap.values) {
+        comparison.writeOn(buffer);
+      }
+    }
+  }
+
+  /**
+   * Analyze all of the explicit sources in the given [context].
+   */
+  void _analyze(AnalysisContextImpl context) {
+    while (true) {
+      AnalysisResult result = context.performAnalysisTask();
+      if (!result.hasMoreWork) {
+        return;
+      }
+    }
+  }
+
+  /**
+   * Create and return a new analysis context that will analyze files in the
+   * same way as the given [context].
+   */
+  AnalysisContextImpl _clone(AnalysisContextImpl context) {
+    AnalysisContextImpl clone = AnalysisEngine.instance.createAnalysisContext();
+
+    clone.analysisOptions = context.analysisOptions;
+    //clone.declaredVariables = context.declaredVariables;
+    clone.sourceFactory = context.sourceFactory.clone();
+    // TODO(brianwilkerson) Check content cache. We either need to copy the
+    // cache into the clone or ensure that the context's cache is empty.
+
+    ChangeSet changeSet = new ChangeSet();
+    for (AnalysisTarget target in context.explicitTargets) {
+      if (target is Source) {
+        changeSet.addedSource(target);
+      }
+    }
+    clone.applyChanges(changeSet);
+    return clone;
+  }
+
+  /**
+   * Compare the results produced in the [original] context to those produced in
+   * the [clone].
+   */
+  void _compareContexts(
+      AnalysisContextImpl original, AnalysisContextImpl clone) {
+    AnalysisCache originalCache = original.analysisCache;
+    AnalysisCache cloneCache = clone.analysisCache;
+    List<AnalysisTarget> originalTargets = _getKeys(original, originalCache);
+    List<AnalysisTarget> cloneTargets = _getKeys(clone, cloneCache);
+
+    extraTargets =
+        new HashSet<AnalysisTarget>(equals: _equal, hashCode: _hashCode);
+    extraTargets.addAll(originalTargets);
+    extraTargets.removeAll(cloneTargets);
+
+    missingTargets =
+        new HashSet<AnalysisTarget>(equals: _equal, hashCode: _hashCode);
+    missingTargets.addAll(cloneTargets);
+    missingTargets.removeAll(originalTargets);
+
+    for (AnalysisTarget cloneTarget in cloneTargets) {
+      if (!missingTargets.contains(cloneTarget)) {
+        AnalysisTarget originalTarget = _find(originalTargets, cloneTarget);
+        CacheEntry originalEntry = originalCache.get(originalTarget);
+        CacheEntry cloneEntry = cloneCache.get(cloneTarget);
+        EntryComparison comparison =
+            new EntryComparison(cloneTarget, originalEntry, cloneEntry);
+        if (comparison.hasInterestingState()) {
+          targetMap[cloneTarget] = comparison;
+        }
+      }
+    }
+  }
+
+  /**
+   * Find the target in the list of [originalTargets] that is equal to the
+   * [cloneTarget].
+   */
+  AnalysisTarget _find(
+      List<AnalysisTarget> originalTargets, AnalysisTarget cloneTarget) {
+    for (AnalysisTarget originalTarget in originalTargets) {
+      if (_equal(originalTarget, cloneTarget)) {
+        return originalTarget;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Return a list of the analysis targets in the given [cache] that are owned
+   * by the given [context].
+   */
+  List<AnalysisTarget> _getKeys(
+      AnalysisContextImpl context, AnalysisCache cache) {
+    List<AnalysisTarget> targets = <AnalysisTarget>[];
+    MapIterator<AnalysisTarget, CacheEntry> iterator =
+        cache.iterator(context: context);
+    while (iterator.moveNext()) {
+      targets.add(iterator.key);
+    }
+    return targets;
+  }
+
+  /**
+   * Validate the given [context].
+   */
+  void _validate(AnalysisContextImpl context) {
+    AnalysisContextImpl clone = _clone(context);
+    _analyze(clone);
+    _compareContexts(context, clone);
+  }
+
+  /**
+   * Write the list of [targets] to the [buffer].
+   */
+  void _writeTargetList(StringBuffer buffer, List<AnalysisTarget> targets) {
+    // TODO(brianwilkerson) Sort the list of targets.
+    //targets.sort();
+    for (AnalysisTarget target in targets) {
+      buffer.write('<p>');
+      buffer.write(target);
+      buffer.write(' (');
+      buffer.write(target.runtimeType);
+      buffer.write(')');
+      buffer.write('</p>');
+    }
+  }
+
+  /**
+   * Return `true` if the [first] and [second] objects are equal.
+   */
+  static bool _equal(Object first, Object second) {
+    //
+    // Compare possible null values.
+    //
+    if (first == null) {
+      return second == null;
+    } else if (second == null) {
+      return false;
+    }
+    //
+    // Handle special cases.
+    //
+    if (first is ConstantEvaluationTarget_Annotation &&
+        second is ConstantEvaluationTarget_Annotation) {
+      return _equal(first.source, second.source) &&
+          _equal(first.librarySource, second.librarySource) &&
+          _equal(first.annotation, second.annotation);
+    } else if (first is AstNode && second is AstNode) {
+      return first.runtimeType == second.runtimeType &&
+          first.offset == second.offset &&
+          first.length == second.length;
+    }
+    //
+    // Handle the general case.
+    //
+    return first == second;
+  }
+
+  /**
+   * Return a hash code for the given [object].
+   */
+  static int _hashCode(Object object) {
+    //
+    // Handle special cases.
+    //
+    if (object is ConstantEvaluationTarget_Annotation) {
+      return object.source.hashCode;
+    } else if (object is AstNode) {
+      return object.offset;
+    }
+    //
+    // Handle the general case.
+    //
+    return object.hashCode;
+  }
+}
+
+class ValueComparison {
+  /**
+   * The result value from the original context.
+   */
+  final Object originalValue;
+
+  /**
+   * The result value from the cloned context.
+   */
+  final Object cloneValue;
+
+  /**
+   * A description of the difference between the original and clone values, or
+   * `null` if the values are equal.
+   */
+  String description = null;
+
+  /**
+   * Initialize a newly created value comparison to represents the difference,
+   * if any, between the [originalValue] and the [cloneValue].
+   */
+  ValueComparison(this.originalValue, this.cloneValue) {
+    _performComparison();
+  }
+
+  /**
+   * Return `true` if this object represents a difference between the original
+   * and cloned values.
+   */
+  bool hasInterestingState() => description != null;
+
+  /**
+   * Write an HTML formatted description of the validation results to the given
+   * [buffer].
+   */
+  void writeOn(StringBuffer buffer) {
+    buffer.write('<p>');
+    buffer.write(description);
+    buffer.write('</p>');
+  }
+
+  bool _compareAnalysisErrors(
+      AnalysisError expected, AnalysisError actual, StringBuffer buffer) {
+    if (actual.errorCode == expected.errorCode &&
+        actual.source == expected.source &&
+        actual.offset == expected.offset) {
+      return true;
+    }
+    if (buffer != null) {
+      void write(AnalysisError originalError) {
+        buffer.write('a ');
+        buffer.write(originalError.errorCode.uniqueName);
+        buffer.write(' in ');
+        buffer.write(originalError.source.fullName);
+        buffer.write(' at ');
+        buffer.write(originalError.offset);
+      }
+
+      buffer.write('Expected ');
+      write(expected);
+      buffer.write('; found ');
+      write(actual);
+    }
+    return false;
+  }
+
+  bool _compareAstNodes(AstNode expected, AstNode actual, StringBuffer buffer) {
+    if (AstComparator.equalNodes(actual, expected)) {
+      return true;
+    }
+    if (buffer != null) {
+      // TODO(brianwilkerson) Compute where the difference is rather than just
+      // whether there is a difference.
+      buffer.write('Different AST nodes');
+    }
+    return false;
+  }
+
+  bool _compareConstantEvaluationTargets(ConstantEvaluationTarget expected,
+      ConstantEvaluationTarget actual, StringBuffer buffer) {
+    if (actual is ConstantEvaluationTarget_Annotation) {
+      ConstantEvaluationTarget_Annotation expectedAnnotation = expected;
+      ConstantEvaluationTarget_Annotation actualAnnotation = actual;
+      if (actualAnnotation.source == expectedAnnotation.source &&
+          actualAnnotation.librarySource == expectedAnnotation.librarySource &&
+          actualAnnotation.annotation == expectedAnnotation.annotation) {
+        return true;
+      }
+      if (buffer != null) {
+        void write(ConstantEvaluationTarget_Annotation target) {
+          Annotation annotation = target.annotation;
+          buffer.write(annotation);
+          buffer.write(' at ');
+          buffer.write(annotation.offset);
+          buffer.write(' in ');
+          buffer.write(target.source);
+          buffer.write(' in ');
+          buffer.write(target.librarySource);
+        }
+
+        buffer.write('Expected ');
+        write(expectedAnnotation);
+        buffer.write('; found ');
+        write(actualAnnotation);
+      }
+      return false;
+    }
+    if (buffer != null) {
+      buffer.write('Unknown class of ConstantEvaluationTarget: ');
+      buffer.write(actual.runtimeType);
+    }
+    return false;
+  }
+
+  bool _compareDartScripts(
+      DartScript expected, DartScript actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  bool _compareDocuments(
+      html.Document expected, html.Document actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  bool _compareElements(Element expected, Element actual, StringBuffer buffer) {
+    ElementComparator comparator = new ElementComparator();
+    comparator.compareElements(expected, actual);
+    if (comparator.hasDifference) {
+      if (buffer != null) {
+        buffer.write(comparator.description);
+      }
+      return false;
+    }
+    return true;
+  }
+
+  bool _compareLibrarySpecificUnits(LibrarySpecificUnit expected,
+      LibrarySpecificUnit actual, StringBuffer buffer) {
+    if (actual.library.fullName == expected.library.fullName &&
+        actual.unit.fullName == expected.unit.fullName) {
+      return true;
+    }
+    if (buffer != null) {
+      buffer.write('Expected ');
+      buffer.write(expected);
+      buffer.write('; found ');
+      buffer.write(actual);
+    }
+    return false;
+  }
+
+  bool _compareLineInfos(
+      LineInfo expected, LineInfo actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  bool _compareLists(List expected, List actual, StringBuffer buffer) {
+    int expectedLength = expected.length;
+    int actualLength = actual.length;
+    int left = 0;
+    while (left < expectedLength &&
+        left < actualLength &&
+        _compareObjects(expected[left], actual[left], null)) {
+      left++;
+    }
+    if (left == actualLength) {
+      if (left == expectedLength) {
+        // The lists are the same length and the elements are equal.
+        return true;
+      }
+      if (buffer != null) {
+        buffer.write('Expected a list of length ');
+        buffer.write(expectedLength);
+        buffer.write('; found a list of length ');
+        buffer.write(actualLength);
+        buffer.write(' that was a prefix of the expected list');
+      }
+      return false;
+    } else if (left == expectedLength) {
+      if (buffer != null) {
+        buffer.write('Expected a list of length ');
+        buffer.write(expectedLength);
+        buffer.write('; found a list of length ');
+        buffer.write(actualLength);
+        buffer.write(' that was an extension of the expected list');
+      }
+      return false;
+    }
+    int expectedRight = expectedLength - 1;
+    int actualRight = actualLength - 1;
+    while (expectedRight > left &&
+        actualRight > left &&
+        _compareObjects(expected[expectedRight], actual[actualRight], null)) {
+      actualRight--;
+      expectedRight--;
+    }
+    if (buffer != null) {
+      void write(int left, int right, int length) {
+        buffer.write('the elements (');
+        buffer.write(left);
+        buffer.write('..');
+        buffer.write(right);
+        buffer.write(') in a list of length ');
+        buffer.write(length);
+      }
+
+      buffer.write('Expected ');
+      write(left, expectedRight, expectedLength);
+      buffer.write(' to match ');
+      write(left, actualRight, actualLength);
+      buffer.write(' but they did not');
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` if the [expected] and [actual] objects are equal. If they are
+   * not equal, and the given [buffer] is not `null`, then a description of the
+   * difference will be written to the [buffer].
+   */
+  bool _compareObjects(Object expected, Object actual, StringBuffer buffer) {
+    //
+    // Compare possible null values.
+    //
+    if (actual == null) {
+      if (expected == null) {
+        return true;
+      } else {
+        if (buffer != null) {
+          buffer.write('Expected an instance of ');
+          buffer.write(expected.runtimeType);
+          buffer.write('; found null');
+        }
+        return false;
+      }
+    }
+    Type actualType = actual.runtimeType;
+    if (expected == null) {
+      if (buffer != null) {
+        buffer.write('Expected null; found an instance of ');
+        buffer.write(actualType);
+      }
+      return false;
+    }
+    Type expectedType = expected.runtimeType;
+    //
+    // Compare the types.
+    //
+    if (expectedType != actualType) {
+      if (buffer != null) {
+        buffer.write('Expected an instance of ');
+        buffer.write(expectedType);
+        buffer.write('; found an instance of ');
+        buffer.write(actualType);
+      }
+      return false;
+    }
+    //
+    // Compare non-null values of the same type.
+    //
+    if (actual is bool) {
+      return _comparePrimitives(expected, actual, buffer);
+    } else if (actual is int) {
+      return _comparePrimitives(expected, actual, buffer);
+    } else if (actual is String) {
+      return _compareStrings(expected, actual, buffer);
+    } else if (actual is List) {
+      return _compareLists(expected, actual, buffer);
+    } else if (actual is AnalysisError) {
+      return _compareAnalysisErrors(expected, actual, buffer);
+    } else if (actual is AstNode) {
+      return _compareAstNodes(expected, actual, buffer);
+    } else if (actual is DartScript) {
+      return _compareDartScripts(expected, actual, buffer);
+    } else if (actual is html.Document) {
+      return _compareDocuments(expected, actual, buffer);
+    } else if (actual is Element) {
+      return _compareElements(expected, actual, buffer);
+    } else if (actual is LibrarySpecificUnit) {
+      return _compareLibrarySpecificUnits(expected, actual, buffer);
+    } else if (actual is LineInfo) {
+      return _compareLineInfos(expected, actual, buffer);
+    } else if (actual is ReferencedNames) {
+      return _compareReferencedNames(expected, actual, buffer);
+    } else if (actual is Source) {
+      return _compareSources(expected, actual, buffer);
+    } else if (actual is SourceKind) {
+      return _comparePrimitives(expected, actual, buffer);
+    } else if (actual is Token) {
+      return _compareTokenStreams(expected, actual, buffer);
+    } else if (actual is TypeProvider) {
+      return true;
+    } else if (actual is UsedLocalElements) {
+      return _compareUsedLocalElements(expected, actual, buffer);
+    } else if (actual is UsedImportedElements) {
+      return _compareUsedImportedElements(expected, actual, buffer);
+    } else if (actual is ConstantEvaluationTarget) {
+      return _compareConstantEvaluationTargets(expected, actual, buffer);
+    }
+    if (buffer != null) {
+      buffer.write('Cannot compare values of type ');
+      buffer.write(actualType);
+    }
+    return false;
+  }
+
+  bool _comparePrimitives(Object expected, Object actual, StringBuffer buffer) {
+    if (actual == expected) {
+      return true;
+    }
+    if (buffer != null) {
+      buffer.write('Expected ');
+      buffer.write(expected);
+      buffer.write('; found ');
+      buffer.write(actual);
+    }
+    return false;
+  }
+
+  bool _compareReferencedNames(
+      ReferencedNames expected, ReferencedNames actual, StringBuffer buffer) {
+    Set<String> expectedNames = expected.names;
+    Map<String, Set<String>> expectedUserToDependsOn = expected.userToDependsOn;
+    Set<String> expectedKeys = expectedUserToDependsOn.keys.toSet();
+
+    Set<String> actualNames = actual.names;
+    Map<String, Set<String>> actualUserToDependsOn = actual.userToDependsOn;
+    Set<String> actualKeys = actualUserToDependsOn.keys.toSet();
+
+    Set<String> missingNames = expectedNames.difference(actualNames);
+    Set<String> extraNames = actualNames.difference(expectedNames);
+    Set<String> missingKeys = expectedKeys.difference(actualKeys);
+    Set<String> extraKeys = actualKeys.difference(expectedKeys);
+    Map<String, List<Set<String>>> mismatchedDependencies =
+        new HashMap<String, List<Set<String>>>();
+    Set<String> commonKeys = expectedKeys.intersection(actualKeys);
+    for (String key in commonKeys) {
+      Set<String> expectedDependencies = expectedUserToDependsOn[key];
+      Set<String> actualDependencies = actualUserToDependsOn[key];
+      Set<String> missingDependencies =
+          expectedDependencies.difference(actualDependencies);
+      Set<String> extraDependencies =
+          actualDependencies.difference(expectedDependencies);
+      if (missingDependencies.isNotEmpty || extraDependencies.isNotEmpty) {
+        mismatchedDependencies[key] = [missingDependencies, extraDependencies];
+      }
+    }
+
+    if (missingNames.isEmpty &&
+        extraNames.isEmpty &&
+        missingKeys.isEmpty &&
+        extraKeys.isEmpty &&
+        mismatchedDependencies.isEmpty) {
+      return true;
+    }
+    if (buffer != null) {
+      void write(String title, Set<String> names) {
+        buffer.write(names.length);
+        buffer.write(' ');
+        buffer.write(title);
+        buffer.write(': {');
+        bool first = true;
+        for (String name in names) {
+          if (first) {
+            first = false;
+          } else {
+            buffer.write(', ');
+          }
+          buffer.write(name);
+        }
+        buffer.write('}');
+      }
+      bool needsNewline = false;
+      if (missingNames.isNotEmpty) {
+        buffer.write('Has ');
+        write('missing names', missingNames);
+        needsNewline = true;
+      }
+      if (extraNames.isNotEmpty) {
+        if (needsNewline) {
+          buffer.write('</p><p>');
+        }
+        buffer.write('Has ');
+        write('extra names', extraNames);
+        needsNewline = true;
+      }
+      if (missingKeys.isNotEmpty) {
+        if (needsNewline) {
+          buffer.write('</p><p>');
+        }
+        buffer.write('Has ');
+        write('missing keys', missingKeys);
+        needsNewline = true;
+      }
+      if (extraKeys.isNotEmpty) {
+        if (needsNewline) {
+          buffer.write('</p><p>');
+        }
+        buffer.write('Has ');
+        write('extra keys', extraKeys);
+        needsNewline = true;
+      }
+      mismatchedDependencies.forEach((String key, List<Set<String>> value) {
+        Set<String> missingDependencies = value[0];
+        Set<String> extraDependencies = value[1];
+        if (needsNewline) {
+          buffer.write('</p><p>');
+        }
+        buffer.write('The key ');
+        buffer.write(key);
+        buffer.write(' has ');
+        bool needsConjunction = false;
+        if (missingNames.isNotEmpty) {
+          write('missing dependencies', missingDependencies);
+          needsConjunction = true;
+        }
+        if (extraNames.isNotEmpty) {
+          if (needsConjunction) {
+            buffer.write(' and ');
+          }
+          write('extra dependencies', extraDependencies);
+        }
+        needsNewline = true;
+      });
+    }
+    return true;
+  }
+
+  bool _compareSources(Source expected, Source actual, StringBuffer buffer) {
+    if (actual.fullName == expected.fullName) {
+      return true;
+    }
+    if (buffer != null) {
+      buffer.write('Expected a source for ');
+      buffer.write(expected.fullName);
+      buffer.write('; found a source for ');
+      buffer.write(actual.fullName);
+    }
+    return false;
+  }
+
+  bool _compareStrings(String expected, String actual, StringBuffer buffer) {
+    if (actual == expected) {
+      return true;
+    }
+    int expectedLength = expected.length;
+    int actualLength = actual.length;
+    int left = 0;
+    while (left < actualLength &&
+        left < expectedLength &&
+        actual.codeUnitAt(left) == expected.codeUnitAt(left)) {
+      left++;
+    }
+    if (left == actualLength) {
+      if (buffer != null) {
+        buffer.write('Expected ...[');
+        buffer.write(expected.substring(left));
+        buffer.write(']; found ...[]');
+      }
+      return false;
+    } else if (left == expectedLength) {
+      if (buffer != null) {
+        buffer.write('Expected ...[]; found ...[');
+        buffer.write(actual.substring(left));
+        buffer.write(']');
+      }
+      return false;
+    }
+    int actualRight = actualLength - 1;
+    int expectedRight = expectedLength - 1;
+    while (actualRight > left &&
+        expectedRight > left &&
+        actual.codeUnitAt(actualRight) == expected.codeUnitAt(expectedRight)) {
+      actualRight--;
+      expectedRight--;
+    }
+    if (buffer != null) {
+      void write(String string, int left, int right) {
+        buffer.write('...[');
+        buffer.write(string.substring(left, right));
+        buffer.write(']... (');
+        buffer.write(left);
+        buffer.write('..');
+        buffer.write(right);
+        buffer.write(')');
+      }
+
+      buffer.write('Expected ');
+      write(expected, left, expectedRight);
+      buffer.write('; found ');
+      write(actual, left, actualRight);
+    }
+    return false;
+  }
+
+  bool _compareTokenStreams(Token expected, Token actual, StringBuffer buffer) {
+    bool equals(Token originalToken, Token cloneToken) {
+      return originalToken.type == cloneToken.type &&
+          originalToken.offset == cloneToken.offset &&
+          originalToken.lexeme == cloneToken.lexeme;
+    }
+
+    Token actualLeft = actual;
+    Token expectedLeft = expected;
+    while (actualLeft.type != TokenType.EOF &&
+        expectedLeft.type != TokenType.EOF &&
+        equals(actualLeft, expectedLeft)) {
+      actualLeft = actualLeft.next;
+      expectedLeft = expectedLeft.next;
+    }
+    if (actualLeft.type == TokenType.EOF &&
+        expectedLeft.type == TokenType.EOF) {
+      return true;
+    }
+    if (buffer != null) {
+      void write(Token token) {
+        buffer.write(token.type);
+        buffer.write(' at ');
+        buffer.write(token.offset);
+        buffer.write(' (');
+        buffer.write(token.lexeme);
+        buffer.write(')');
+      }
+
+      buffer.write('Expected ');
+      write(expectedLeft);
+      buffer.write('; found ');
+      write(actualLeft);
+    }
+    return false;
+  }
+
+  bool _compareUsedImportedElements(UsedImportedElements expected,
+      UsedImportedElements actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  bool _compareUsedLocalElements(UsedLocalElements expected,
+      UsedLocalElements actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  /**
+   * Determine whether or not there is any interesting difference between the
+   * original and cloned values.
+   */
+  void _performComparison() {
+    StringBuffer buffer = new StringBuffer();
+    if (!_compareObjects(cloneValue, originalValue, buffer)) {
+      description = buffer.toString();
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/utilities/average.dart b/pkg/analysis_server/lib/src/utilities/average.dart
new file mode 100644
index 0000000..a20ad88
--- /dev/null
+++ b/pkg/analysis_server/lib/src/utilities/average.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.
+
+library analysis_server.src.utilities.average;
+
+/// Simple rolling average sample counter.
+class Average {
+  num _val;
+  final int _sampleCount;
+
+  /// Create an average with the given (optional) sample count size.
+  Average([this._sampleCount = 20]);
+
+  /// The current average.
+  num get value => _val ?? 0;
+
+  /// Add the given [sample].
+  void addSample(num sample) {
+    if (_val == null) {
+      _val = sample;
+    } else {
+      _val = _val * ((_sampleCount - 1) / _sampleCount) +
+          sample * (1 / _sampleCount);
+    }
+  }
+
+  @override
+  String toString() => 'average: $value';
+}
diff --git a/pkg/analysis_server/lib/src/utilities/change_builder_core.dart b/pkg/analysis_server/lib/src/utilities/change_builder_core.dart
index a5fe204..cb103f8 100644
--- a/pkg/analysis_server/lib/src/utilities/change_builder_core.dart
+++ b/pkg/analysis_server/lib/src/utilities/change_builder_core.dart
@@ -4,8 +4,8 @@
 
 library analysis_server.src.utilities.change_builder_core;
 
-import 'package:analysis_server/plugin/edit/utilities/change_builder_core.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/edit/utilities/change_builder_core.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart b/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
index f40dd36..bac921d 100644
--- a/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
+++ b/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
@@ -4,14 +4,15 @@
 
 library analysis_server.src.utilities.change_builder_dart;
 
-import 'package:analysis_server/plugin/edit/utilities/change_builder_core.dart';
-import 'package:analysis_server/plugin/edit/utilities/change_builder_dart.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide ElementKind;
+import 'package:analysis_server/src/provisional/edit/utilities/change_builder_core.dart';
+import 'package:analysis_server/src/provisional/edit/utilities/change_builder_dart.dart';
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/utilities/change_builder_core.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/utilities/documentation.dart b/pkg/analysis_server/lib/src/utilities/documentation.dart
new file mode 100644
index 0000000..8e8e696
--- /dev/null
+++ b/pkg/analysis_server/lib/src/utilities/documentation.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analysis_server.src.utilities.documentation;
+
+String getDartDocSummary(String str) {
+  if (str == null) {
+    return null;
+  }
+  List<String> lines = str.split('\n');
+  StringBuffer sb = new StringBuffer();
+  bool firstLine = true;
+  for (String line in lines) {
+    if (sb.length != 0 && line.isEmpty) {
+      return sb.toString();
+    }
+    if (!firstLine) {
+      sb.write('\n');
+    }
+    firstLine = false;
+    sb.write(line);
+  }
+  return sb.toString();
+}
+
+/**
+ * Converts [str] from a Dart Doc string with slashes and stars to a plain text
+ * representation of the comment.
+ */
+String removeDartDocDelimiters(String str) {
+  if (str == null) {
+    return null;
+  }
+  // remove /** */
+  if (str.startsWith('/**')) {
+    str = str.substring(3);
+  }
+  if (str.endsWith("*/")) {
+    str = str.substring(0, str.length - 2);
+  }
+  str = str.trim();
+  // remove leading '* ' and '/// '
+  List<String> lines = str.split('\n');
+  StringBuffer sb = new StringBuffer();
+  bool firstLine = true;
+  for (String line in lines) {
+    line = line.trim();
+    if (line.startsWith("*")) {
+      line = line.substring(1);
+      if (line.startsWith(" ")) {
+        line = line.substring(1);
+      }
+    } else if (line.startsWith("///")) {
+      line = line.substring(3);
+      if (line.startsWith(" ")) {
+        line = line.substring(1);
+      }
+    }
+    if (!firstLine) {
+      sb.write('\n');
+    }
+    firstLine = false;
+    sb.write(line);
+  }
+  str = sb.toString();
+  // done
+  return str;
+}
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 3f53b5b..dff1fd7 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -6,10 +6,10 @@
 environment:
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
-  analyzer: '>=0.26.1+16 <0.27.0'
+  analyzer: ^0.27.0
   args: '>=0.13.0 <0.14.0'
   dart_style: '>=0.2.0 <0.3.0'
-  linter: ^0.1.3+2
+  linter: ^0.1.10
   logging: any
   path: any
   plugin: <0.2.0
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 46f0dbf..eded4062 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -4,12 +4,14 @@
 
 library testing.abstract_context;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 
@@ -74,6 +76,10 @@
     }
   }
 
+  void processRequiredPlugins() {
+    AnalysisEngine.instance.processRequiredPlugins();
+  }
+
   CompilationUnit resolveDartUnit(Source unitSource, Source librarySource) {
     return context.resolveCompilationUnit2(unitSource, librarySource);
   }
@@ -83,6 +89,7 @@
   }
 
   void setUp() {
+    processRequiredPlugins();
     setupResourceProvider();
     resourceResolver = new ResourceUriResolver(provider);
     packageMap = new Map<String, List<Folder>>();
@@ -91,6 +98,7 @@
     context = AnalysisEngine.instance.createAnalysisContext();
     context.sourceFactory =
         new SourceFactory([SDK_RESOLVER, packageResolver, resourceResolver]);
+    AnalysisEngine.instance.logger = PrintLogger.instance;
   }
 
   void setupResourceProvider() {
@@ -100,6 +108,30 @@
   void tearDown() {
     context = null;
     provider = null;
+    AnalysisEngine.instance.logger = null;
+  }
+}
+
+/**
+ * Instances of the class [PrintLogger] print all of the errors.
+ */
+class PrintLogger implements Logger {
+  static final Logger instance = new PrintLogger();
+
+  @override
+  void logError(String message, [CaughtException exception]) {
+    print(message);
+    if (exception != null) {
+      print(exception);
+    }
+  }
+
+  @override
+  void logInformation(String message, [CaughtException exception]) {
+    print(message);
+    if (exception != null) {
+      print(exception);
+    }
   }
 }
 
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index 757c819..4b0be0e 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -4,8 +4,8 @@
 
 library test.services.src.index.abstract_single_file;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index 65a524a4..a665cfa 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_test.dart
@@ -8,7 +8,6 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
-import 'package:analyzer/file_system/file_system.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -31,17 +30,42 @@
     createProject();
   }
 
-  test_afterAnalysisComplete() {
+  test_afterAnalysisComplete() async {
     addTestFile('''
 main() {
   print(42)
 }
 ''');
-    return waitForTasksFinished().then((_) {
-      return _getErrors(testFile).then((List<AnalysisError> errors) {
-        expect(errors, hasLength(1));
-      });
-    });
+    await waitForTasksFinished();
+    List<AnalysisError> errors = await _getErrors(testFile);
+    expect(errors, hasLength(1));
+  }
+
+  test_errorInPart() async {
+    String libPath = '$testFolder/main.dart';
+    String partPath = '$testFolder/main_part.dart';
+    addFile(
+        libPath,
+        r'''
+library main;
+part 'main_part.dart';
+class A {}
+''');
+    addFile(
+        partPath,
+        r'''
+part of main;
+class A {}
+''');
+    await waitForTasksFinished();
+    {
+      List<AnalysisError> libErrors = await _getErrors(libPath);
+      expect(libErrors, isEmpty);
+    }
+    {
+      List<AnalysisError> partErrors = await _getErrors(partPath);
+      expect(partErrors, hasLength(1));
+    }
   }
 
   test_fileDoesNotExist() {
@@ -61,72 +85,64 @@
     return _checkInvalid(file);
   }
 
-  test_hasErrors() {
+  test_hasErrors() async {
     addTestFile('''
 main() {
   print(42)
 }
 ''');
-    return _getErrors(testFile).then((List<AnalysisError> errors) {
-      expect(errors, hasLength(1));
-      {
-        AnalysisError error = errors[0];
-        expect(error.severity, AnalysisErrorSeverity.ERROR);
-        expect(error.type, AnalysisErrorType.SYNTACTIC_ERROR);
-        expect(error.location.file, testFile);
-        expect(error.location.startLine, 2);
-      }
-    });
+    List<AnalysisError> errors = await _getErrors(testFile);
+    expect(errors, hasLength(1));
+    {
+      AnalysisError error = errors[0];
+      expect(error.severity, AnalysisErrorSeverity.ERROR);
+      expect(error.type, AnalysisErrorType.SYNTACTIC_ERROR);
+      expect(error.location.file, testFile);
+      expect(error.location.startLine, 2);
+    }
   }
 
-  test_noErrors() {
+  test_noErrors() async {
     addTestFile('''
 main() {
   print(42);
 }
 ''');
-    return _getErrors(testFile).then((List<AnalysisError> errors) {
-      expect(errors, isEmpty);
-    });
+    List<AnalysisError> errors = await _getErrors(testFile);
+    expect(errors, isEmpty);
   }
 
-  test_removeContextAfterRequest() {
+  test_removeContextAfterRequest() async {
     addTestFile('''
 main() {
   print(42)
 }
 ''');
     // handle the request synchronously
-    Request request = _createGetErrorsRequest();
+    Request request = _createGetErrorsRequest(testFile);
     server.handleRequest(request);
     // remove context, causes sending an "invalid file" error
-    {
-      Folder projectFolder = resourceProvider.getResource(projectPath);
-      server.contextManager.callbacks.removeContext(projectFolder, <String>[]);
-    }
+    resourceProvider.deleteFolder(projectPath);
     // wait for an error response
-    return serverChannel.waitForResponse(request).then((Response response) {
-      expect(response.error, isNotNull);
-      expect(response.error.code, RequestErrorCode.GET_ERRORS_INVALID_FILE);
-    });
+    Response response = await serverChannel.waitForResponse(request);
+    expect(response.error, isNotNull);
+    expect(response.error.code, RequestErrorCode.GET_ERRORS_INVALID_FILE);
   }
 
-  Future _checkInvalid(String file) {
-    Request request = _createGetErrorsRequest();
-    return serverChannel.sendRequest(request).then((Response response) {
-      expect(response.error, isNotNull);
-      expect(response.error.code, RequestErrorCode.GET_ERRORS_INVALID_FILE);
-    });
+  Future _checkInvalid(String file) async {
+    Request request = _createGetErrorsRequest(file);
+    Response response = await serverChannel.sendRequest(request);
+    expect(response.error, isNotNull);
+    expect(response.error.code, RequestErrorCode.GET_ERRORS_INVALID_FILE);
   }
 
-  Request _createGetErrorsRequest() {
-    return new AnalysisGetErrorsParams(testFile).toRequest(requestId);
+  Request _createGetErrorsRequest(String file) {
+    return new AnalysisGetErrorsParams(file).toRequest(requestId);
   }
 
-  Future<List<AnalysisError>> _getErrors(String file) {
-    Request request = _createGetErrorsRequest();
-    return serverChannel.sendRequest(request).then((Response response) {
-      return new AnalysisGetErrorsResult.fromResponse(response).errors;
-    });
+  Future<List<AnalysisError>> _getErrors(String file) async {
+    Request request = _createGetErrorsRequest(file);
+    Response response = await serverChannel.sendRequest(request);
+    return new AnalysisGetErrorsResult.fromResponse(response).errors;
   }
 }
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index 34db510..cc1a4e4 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -25,15 +25,14 @@
     return prepareHoverAt(offset);
   }
 
-  Future<HoverInformation> prepareHoverAt(int offset) {
-    return waitForTasksFinished().then((_) {
-      Request request =
-          new AnalysisGetHoverParams(testFile, offset).toRequest('0');
-      Response response = handleSuccessfulRequest(request);
-      var result = new AnalysisGetHoverResult.fromResponse(response);
-      List<HoverInformation> hovers = result.hovers;
-      return hovers.isNotEmpty ? hovers.first : null;
-    });
+  Future<HoverInformation> prepareHoverAt(int offset) async {
+    await waitForTasksFinished();
+    Request request =
+        new AnalysisGetHoverParams(testFile, offset).toRequest('0');
+    Response response = handleSuccessfulRequest(request);
+    var result = new AnalysisGetHoverResult.fromResponse(response);
+    List<HoverInformation> hovers = result.hovers;
+    return hovers.isNotEmpty ? hovers.first : null;
   }
 
   @override
@@ -42,7 +41,36 @@
     createProject();
   }
 
-  test_dartdoc_clunky() {
+  test_class() async {
+    addTestFile('''
+class A<E> {}
+class I1<K, V> {}
+class I2<E> {}
+class M1 {}
+class M2<E> {}
+class B<T> extends A<T> with M1, M2<int> implements I1<int, String>, I2 {}
+''');
+    HoverInformation hover = await prepareHover('B<T>');
+    expect(
+        hover.elementDescription,
+        'class B<T> extends A<T> with M1, M2<int> '
+        'implements I1<int, String>, I2');
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+  }
+
+  test_class_abstract() async {
+    addTestFile('''
+class A {}
+abstract class B extends A {}
+''');
+    HoverInformation hover = await prepareHover('B extends');
+    expect(hover.elementDescription, 'abstract class B extends A');
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+  }
+
+  test_dartdoc_clunky() async {
     addTestFile('''
 library my.library;
 /**
@@ -52,12 +80,11 @@
 main() {
 }
 ''');
-    return prepareHover('main() {').then((HoverInformation hover) {
-      expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-    });
+    HoverInformation hover = await prepareHover('main() {');
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
   }
 
-  test_dartdoc_elegant() {
+  test_dartdoc_elegant() async {
     addTestFile('''
 library my.library;
 /// doc aaa
@@ -65,12 +92,21 @@
 main() {
 }
 ''');
-    return prepareHover('main() {').then((HoverInformation hover) {
-      expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-    });
+    HoverInformation hover = await prepareHover('main() {');
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
   }
 
-  test_expression_function() {
+  test_enum() async {
+    addTestFile('''
+enum MyEnum {AAA, BBB, CCC}
+''');
+    HoverInformation hover = await prepareHover('MyEnum');
+    expect(hover.elementDescription, 'enum MyEnum');
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+  }
+
+  test_expression_function() async {
     addTestFile('''
 library my.library;
 /// doc aaa
@@ -78,43 +114,41 @@
 List<String> fff(int a, String b) {
 }
 ''');
-    return prepareHover('fff(int a').then((HoverInformation hover) {
-      // element
-      expect(hover.containingLibraryName, 'my.library');
-      expect(hover.containingLibraryPath, testFile);
-      expect(hover.containingClassDescription, isNull);
-      expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-      expect(hover.elementDescription, 'fff(int a, String b) → List<String>');
-      expect(hover.elementKind, 'function');
-      // types
-      expect(hover.staticType, '(int, String) → List<String>');
-      expect(hover.propagatedType, isNull);
-      // no parameter
-      expect(hover.parameter, isNull);
-    });
+    HoverInformation hover = await prepareHover('fff(int a');
+    // element
+    expect(hover.containingLibraryName, 'my.library');
+    expect(hover.containingLibraryPath, testFile);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
+    expect(hover.elementDescription, 'fff(int a, String b) → List<String>');
+    expect(hover.elementKind, 'function');
+    // types
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+    // no parameter
+    expect(hover.parameter, isNull);
   }
 
-  test_expression_literal_noElement() {
+  test_expression_literal_noElement() async {
     addTestFile('''
 main() {
   foo(123);
 }
 foo(Object myParameter) {}
 ''');
-    return prepareHover('123').then((HoverInformation hover) {
-      // literal, no Element
-      expect(hover.containingClassDescription, isNull);
-      expect(hover.elementDescription, isNull);
-      expect(hover.elementKind, isNull);
-      // types
-      expect(hover.staticType, 'int');
-      expect(hover.propagatedType, isNull);
-      // parameter
-      expect(hover.parameter, 'Object myParameter');
-    });
+    HoverInformation hover = await prepareHover('123');
+    // literal, no Element
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.elementDescription, isNull);
+    expect(hover.elementKind, isNull);
+    // types
+    expect(hover.staticType, 'int');
+    expect(hover.propagatedType, isNull);
+    // parameter
+    expect(hover.parameter, 'Object myParameter');
   }
 
-  test_expression_method() {
+  test_expression_method() async {
     addTestFile('''
 library my.library;
 class A {
@@ -124,23 +158,22 @@
   }
 }
 ''');
-    return prepareHover('mmm(int a').then((HoverInformation hover) {
-      // element
-      expect(hover.containingLibraryName, 'my.library');
-      expect(hover.containingLibraryPath, testFile);
-      expect(hover.containingClassDescription, 'A');
-      expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-      expect(hover.elementDescription, 'mmm(int a, String b) → List<String>');
-      expect(hover.elementKind, 'method');
-      // types
-      expect(hover.staticType, '(int, String) → List<String>');
-      expect(hover.propagatedType, isNull);
-      // no parameter
-      expect(hover.parameter, isNull);
-    });
+    HoverInformation hover = await prepareHover('mmm(int a');
+    // element
+    expect(hover.containingLibraryName, 'my.library');
+    expect(hover.containingLibraryPath, testFile);
+    expect(hover.containingClassDescription, 'A');
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
+    expect(hover.elementDescription, 'mmm(int a, String b) → List<String>');
+    expect(hover.elementKind, 'method');
+    // types
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+    // no parameter
+    expect(hover.parameter, isNull);
   }
 
-  test_expression_method_invocation() {
+  test_expression_method_invocation() async {
     addTestFile('''
 library my.library;
 class A {
@@ -151,24 +184,23 @@
   a.mmm(42, 'foo');
 }
 ''');
-    return prepareHover('mm(42, ').then((HoverInformation hover) {
-      // range
-      expect(hover.offset, findOffset('mmm(42, '));
-      expect(hover.length, 'mmm'.length);
-      // element
-      expect(hover.containingLibraryName, 'my.library');
-      expect(hover.containingLibraryPath, testFile);
-      expect(hover.elementDescription, 'mmm(int a, String b) → List<String>');
-      expect(hover.elementKind, 'method');
-      // types
-      expect(hover.staticType, isNull);
-      expect(hover.propagatedType, isNull);
-      // no parameter
-      expect(hover.parameter, isNull);
-    });
+    HoverInformation hover = await prepareHover('mm(42, ');
+    // range
+    expect(hover.offset, findOffset('mmm(42, '));
+    expect(hover.length, 'mmm'.length);
+    // element
+    expect(hover.containingLibraryName, 'my.library');
+    expect(hover.containingLibraryPath, testFile);
+    expect(hover.elementDescription, 'mmm(int a, String b) → List<String>');
+    expect(hover.elementKind, 'method');
+    // types
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+    // no parameter
+    expect(hover.parameter, isNull);
   }
 
-  test_expression_parameter() {
+  test_expression_parameter() async {
     addTestFile('''
 library my.library;
 class A {
@@ -177,23 +209,22 @@
   }
 }
 ''');
-    return prepareHover('p) {').then((HoverInformation hover) {
-      // element
-      expect(hover.containingLibraryName, isNull);
-      expect(hover.containingLibraryPath, isNull);
-      expect(hover.containingClassDescription, isNull);
-      expect(hover.dartdoc, 'The method documentation.');
-      expect(hover.elementDescription, 'int p');
-      expect(hover.elementKind, 'parameter');
-      // types
-      expect(hover.staticType, 'int');
-      expect(hover.propagatedType, isNull);
-      // no parameter
-      expect(hover.parameter, isNull);
-    });
+    HoverInformation hover = await prepareHover('p) {');
+    // element
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, 'The method documentation.');
+    expect(hover.elementDescription, 'int p');
+    expect(hover.elementKind, 'parameter');
+    // types
+    expect(hover.staticType, 'int');
+    expect(hover.propagatedType, isNull);
+    // no parameter
+    expect(hover.parameter, isNull);
   }
 
-  test_expression_syntheticGetter() {
+  test_expression_syntheticGetter_invocation() async {
     addTestFile('''
 library my.library;
 class A {
@@ -205,21 +236,20 @@
   print(a.fff);
 }
 ''');
-    return prepareHover('fff);').then((HoverInformation hover) {
-      // element
-      expect(hover.containingLibraryName, 'my.library');
-      expect(hover.containingLibraryPath, testFile);
-      expect(hover.containingClassDescription, 'A');
-      expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-      expect(hover.elementDescription, 'String fff');
-      expect(hover.elementKind, 'field');
-      // types
-      expect(hover.staticType, 'String');
-      expect(hover.propagatedType, isNull);
-    });
+    HoverInformation hover = await prepareHover('fff);');
+    // element
+    expect(hover.containingLibraryName, 'my.library');
+    expect(hover.containingLibraryPath, testFile);
+    expect(hover.containingClassDescription, 'A');
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
+    expect(hover.elementDescription, 'String fff');
+    expect(hover.elementKind, 'field');
+    // types
+    expect(hover.staticType, 'String');
+    expect(hover.propagatedType, isNull);
   }
 
-  test_expression_variable_hasPropagatedType() {
+  test_expression_variable_hasPropagatedType() async {
     addTestFile('''
 library my.library;
 main() {
@@ -227,21 +257,20 @@
   print(vvv);
 }
 ''');
-    return prepareHover('vvv);').then((HoverInformation hover) {
-      // element
-      expect(hover.containingLibraryName, isNull);
-      expect(hover.containingLibraryPath, isNull);
-      expect(hover.containingClassDescription, isNull);
-      expect(hover.dartdoc, isNull);
-      expect(hover.elementDescription, 'dynamic vvv');
-      expect(hover.elementKind, 'local variable');
-      // types
-      expect(hover.staticType, 'dynamic');
-      expect(hover.propagatedType, 'int');
-    });
+    HoverInformation hover = await prepareHover('vvv);');
+    // element
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, 'dynamic vvv');
+    expect(hover.elementKind, 'local variable');
+    // types
+    expect(hover.staticType, 'dynamic');
+    expect(hover.propagatedType, 'int');
   }
 
-  test_expression_variable_inMethod() {
+  test_expression_variable_inMethod() async {
     addTestFile('''
 library my.library;
 class A {
@@ -250,23 +279,22 @@
   }
 }
 ''');
-    return prepareHover('vvv = 42').then((HoverInformation hover) {
-      // element
-      expect(hover.containingLibraryName, isNull);
-      expect(hover.containingLibraryPath, isNull);
-      expect(hover.containingClassDescription, isNull);
-      expect(hover.dartdoc, isNull);
-      expect(hover.elementDescription, 'num vvv');
-      expect(hover.elementKind, 'local variable');
-      // types
-      expect(hover.staticType, 'num');
-      expect(hover.propagatedType, 'int');
-      // no parameter
-      expect(hover.parameter, isNull);
-    });
+    HoverInformation hover = await prepareHover('vvv = 42');
+    // element
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, 'num vvv');
+    expect(hover.elementKind, 'local variable');
+    // types
+    expect(hover.staticType, 'num');
+    expect(hover.propagatedType, 'int');
+    // no parameter
+    expect(hover.parameter, isNull);
   }
 
-  test_instanceCreation_implicit() {
+  test_instanceCreation_implicit() async {
     addTestFile('''
 library my.library;
 class A {
@@ -275,25 +303,24 @@
   new A();
 }
 ''');
-    return prepareHover('new A').then((HoverInformation hover) {
-      // range
-      expect(hover.offset, findOffset('new A'));
-      expect(hover.length, 'new A()'.length);
-      // element
-      expect(hover.containingLibraryName, 'my.library');
-      expect(hover.containingLibraryPath, testFile);
-      expect(hover.dartdoc, isNull);
-      expect(hover.elementDescription, 'A() → A');
-      expect(hover.elementKind, 'constructor');
-      // types
-      expect(hover.staticType, 'A');
-      expect(hover.propagatedType, isNull);
-      // no parameter
-      expect(hover.parameter, isNull);
-    });
+    HoverInformation hover = await prepareHover('new A');
+    // range
+    expect(hover.offset, findOffset('new A'));
+    expect(hover.length, 'new A()'.length);
+    // element
+    expect(hover.containingLibraryName, 'my.library');
+    expect(hover.containingLibraryPath, testFile);
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, 'A() → A');
+    expect(hover.elementKind, 'constructor');
+    // types
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+    // no parameter
+    expect(hover.parameter, isNull);
   }
 
-  test_instanceCreation_implicit_withTypeArgument() {
+  test_instanceCreation_implicit_withTypeArgument() async {
     addTestFile('''
 library my.library;
 class A<T> {}
@@ -301,7 +328,7 @@
   new A<String>();
 }
 ''');
-    Function onConstructor = (HoverInformation hover) {
+    void onConstructor(HoverInformation hover) {
       // range
       expect(hover.offset, findOffset('new A<String>'));
       expect(hover.length, 'new A<String>()'.length);
@@ -312,22 +339,28 @@
       expect(hover.elementDescription, 'A() → A<String>');
       expect(hover.elementKind, 'constructor');
       // types
-      expect(hover.staticType, 'A<String>');
+      expect(hover.staticType, isNull);
       expect(hover.propagatedType, isNull);
       // no parameter
       expect(hover.parameter, isNull);
-    };
-    var futureNewA = prepareHover('new A').then(onConstructor);
-    var futureA = prepareHover('A<String>()').then(onConstructor);
-    var futureString = prepareHover('String>').then((HoverInformation hover) {
+    }
+    {
+      HoverInformation hover = await prepareHover('new A');
+      onConstructor(hover);
+    }
+    {
+      HoverInformation hover = await prepareHover('A<String>()');
+      onConstructor(hover);
+    }
+    {
+      HoverInformation hover = await prepareHover('String>');
       expect(hover.offset, findOffset('String>'));
       expect(hover.length, 'String'.length);
       expect(hover.elementKind, 'class');
-    });
-    return Future.wait([futureNewA, futureA, futureString]);
+    }
   }
 
-  test_instanceCreation_named() {
+  test_instanceCreation_named() async {
     addTestFile('''
 library my.library;
 class A {
@@ -338,7 +371,7 @@
   new A.named();
 }
 ''');
-    var onConstructor = (HoverInformation hover) {
+    void onConstructor(HoverInformation hover) {
       // range
       expect(hover.offset, findOffset('new A'));
       expect(hover.length, 'new A.named()'.length);
@@ -346,21 +379,25 @@
       expect(hover.dartdoc, 'my doc');
       expect(hover.elementDescription, 'A.named() → A');
       expect(hover.elementKind, 'constructor');
-    };
-    var futureCreation = prepareHover('new A').then(onConstructor);
-    var futureName = prepareHover('named();').then(onConstructor);
-    return Future.wait([futureCreation, futureName]);
+    }
+    {
+      HoverInformation hover = await prepareHover('new A');
+      onConstructor(hover);
+    }
+    {
+      HoverInformation hover = await prepareHover('named();');
+      onConstructor(hover);
+    }
   }
 
-  test_noHoverInfo() {
+  test_noHoverInfo() async {
     addTestFile('''
 library my.library;
 main() {
   // nothing
 }
 ''');
-    return prepareHover('nothing').then((HoverInformation hover) {
-      expect(hover, isNull);
-    });
+    HoverInformation hover = await prepareHover('nothing');
+    expect(hover, isNull);
   }
 }
diff --git a/pkg/analysis_server/test/analysis/navigation_collector_test.dart b/pkg/analysis_server/test/analysis/navigation_collector_test.dart
new file mode 100644
index 0000000..e0f118f
--- /dev/null
+++ b/pkg/analysis_server/test/analysis/navigation_collector_test.dart
@@ -0,0 +1,80 @@
+// 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 test.analysis.navigation_collector;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/domains/analysis/navigation.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(NavigationCollectorImplTest);
+}
+
+@reflectiveTest
+class NavigationCollectorImplTest {
+  NavigationCollectorImpl collector = new NavigationCollectorImpl();
+
+  void test_multipleTargets() {
+    collector.addRegion(
+        10, 5, ElementKind.CLASS, new Location('file', 11, 12, 13, 14));
+    collector.addRegion(
+        10, 5, ElementKind.CLASS, new Location('file', 21, 22, 23, 24));
+    collector.createRegions();
+    List<NavigationRegion> regions = collector.regions;
+    expect(regions, hasLength(1));
+    {
+      NavigationRegion region = regions[0];
+      expect(region.offset, 10);
+      expect(region.length, 5);
+      expect(region.targets, hasLength(2));
+      {
+        NavigationTarget target = collector.targets[region.targets[0]];
+        expect(target.offset, 11);
+        expect(target.length, 12);
+      }
+      {
+        NavigationTarget target = collector.targets[region.targets[1]];
+        expect(target.offset, 21);
+        expect(target.length, 22);
+      }
+    }
+  }
+
+  void test_unique() {
+    collector.addRegion(
+        100, 10, ElementKind.CLASS, new Location('file', 11, 12, 13, 14));
+    collector.addRegion(
+        200, 20, ElementKind.CLASS, new Location('file', 21, 22, 23, 24));
+    collector.createRegions();
+    List<NavigationRegion> regions = collector.regions;
+    expect(regions, hasLength(2));
+    {
+      NavigationRegion region = regions[0];
+      expect(region.offset, 100);
+      expect(region.length, 10);
+      expect(region.targets, hasLength(1));
+      {
+        NavigationTarget target = collector.targets[region.targets[0]];
+        expect(target.offset, 11);
+        expect(target.length, 12);
+      }
+    }
+    {
+      NavigationRegion region = regions[1];
+      expect(region.offset, 200);
+      expect(region.length, 20);
+      expect(region.targets, hasLength(1));
+      {
+        NavigationTarget target = collector.targets[region.targets[0]];
+        expect(target.offset, 21);
+        expect(target.length, 22);
+      }
+    }
+  }
+}
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index 1d4c9d1..a24b811 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
@@ -23,9 +23,6 @@
 
 @reflectiveTest
 class AnalysisOptionsFileNotificationTest extends AbstractAnalysisTest {
-  /// Cached model state in case tests need to set task model to on/off.
-  bool wasTaskModelEnabled;
-
   Map<String, List<AnalysisError>> filesErrors = {};
 
   final testSource = '''
@@ -43,6 +40,8 @@
 
   AnalysisContext get testContext => server.getContainingContext(testFile);
 
+  List<AnalysisError> get testFileErrors => filesErrors[testFile];
+
   void addOptionsFile(String contents) {
     addFile(optionsFilePath, contents);
   }
@@ -76,16 +75,78 @@
   void setUp() {
     super.setUp();
     server.handlers = [new AnalysisDomainHandler(server)];
-    wasTaskModelEnabled = AnalysisEngine.instance.useTaskModel;
-    AnalysisEngine.instance.useTaskModel = true;
   }
 
   @override
   void tearDown() {
-    AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
+    filesErrors[optionsFilePath] = [];
+    filesErrors[testFile] = [];
     super.tearDown();
   }
 
+  test_error_filter() async {
+    addOptionsFile('''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+''');
+
+    addTestFile('''
+main() {
+  String unused = "";
+}
+''');
+
+    setAnalysisRoot();
+
+    await waitForTasksFinished();
+
+    // Verify options file.
+    expect(optionsFileErrors, isEmpty);
+
+    // Verify test file.
+    expect(testFileErrors, isEmpty);
+  }
+
+  test_error_filter_removed() async {
+    addOptionsFile('''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+''');
+
+    addTestFile('''
+main() {
+  String unused = "";
+}
+''');
+
+    setAnalysisRoot();
+
+    await waitForTasksFinished();
+
+    // Verify options file.
+    expect(optionsFileErrors, isEmpty);
+
+    // Verify test file.
+    expect(testFileErrors, isEmpty);
+
+    addOptionsFile('''
+analyzer:
+  errors:
+  #  unused_local_variable: ignore
+''');
+
+    await pumpEventQueue();
+    await waitForTasksFinished();
+
+    // Verify options file.
+    expect(optionsFileErrors, isEmpty);
+
+    // Verify test file.
+    expect(testFileErrors, hasLength(1));
+  }
+
   test_lint_options_changes() async {
     addOptionsFile('''
 linter:
@@ -185,7 +246,7 @@
     verifyStrongMode(enabled: false);
   }
 
-  test_strong_mode_changed() async {
+  test_strong_mode_changed_off() async {
     setStrongMode(true);
 
     addTestFile(testSource);
@@ -206,6 +267,24 @@
     verifyStrongMode(enabled: false);
   }
 
+  test_strong_mode_changed_on() async {
+    setStrongMode(false);
+
+    addTestFile(testSource);
+    setAnalysisRoot();
+
+    await waitForTasksFinished();
+
+    verifyStrongMode(enabled: false);
+
+    setStrongMode(true);
+
+    await pumpEventQueue();
+    await waitForTasksFinished();
+
+    verifyStrongMode(enabled: true);
+  }
+
   void verifyLintsEnabled(List<String> lints) {
     expect(testContext.analysisOptions.lint, true);
     var rules = getLints(testContext).map((rule) => rule.name);
diff --git a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
index 13c5073..0ce9e164 100644
--- a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
@@ -49,24 +49,21 @@
     createProject();
   }
 
-  test_afterAnalysis() {
+  test_afterAnalysis() async {
     addTestFile('''
 class A {}
 ''');
-    return waitForTasksFinished().then((_) {
-      return prepareAnalyzedFiles().then((_) {
-        assertHasFile(testFile);
-      });
-    });
+    await waitForTasksFinished();
+    await prepareAnalyzedFiles();
+    assertHasFile(testFile);
   }
 
-  test_beforeAnalysis() {
+  test_beforeAnalysis() async {
     addTestFile('''
 class A {}
 ''');
-    return prepareAnalyzedFiles().then((_) {
-      assertHasFile(testFile);
-    });
+    await prepareAnalyzedFiles();
+    assertHasFile(testFile);
   }
 
   test_insignificant_change() async {
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index 46de68d..02b05ec 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -25,9 +25,6 @@
 class NotificationErrorsTest extends AbstractAnalysisTest {
   Map<String, List<AnalysisError>> filesErrors = {};
 
-  /// Cached model state in case tests need to set task model to on/off.
-  bool wasTaskModelEnabled;
-
   void processNotification(Notification notification) {
     if (notification.event == ANALYSIS_ERRORS) {
       var decoded = new AnalysisErrorsParams.fromNotification(notification);
@@ -39,37 +36,26 @@
   void setUp() {
     super.setUp();
     server.handlers = [new AnalysisDomainHandler(server),];
-    wasTaskModelEnabled = AnalysisEngine.instance.useTaskModel;
   }
 
-  @override
-  void tearDown() {
-    AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
-    super.tearDown();
-  }
-
-  test_importError() {
+  test_importError() async {
     createProject();
 
     addTestFile('''
 import 'does_not_exist.dart';
 ''');
-    return waitForTasksFinished().then((_) {
-      List<AnalysisError> errors = filesErrors[testFile];
-      // Verify that we are generating only 1 error for the bad URI.
-      // https://github.com/dart-lang/sdk/issues/23754
-      expect(errors, hasLength(1));
-      AnalysisError error = errors[0];
-      expect(error.severity, AnalysisErrorSeverity.ERROR);
-      expect(error.type, AnalysisErrorType.COMPILE_TIME_ERROR);
-      expect(error.message, startsWith('Target of URI does not exist'));
-    });
+    await waitForTasksFinished();
+    List<AnalysisError> errors = filesErrors[testFile];
+    // Verify that we are generating only 1 error for the bad URI.
+    // https://github.com/dart-lang/sdk/issues/23754
+    expect(errors, hasLength(1));
+    AnalysisError error = errors[0];
+    expect(error.severity, AnalysisErrorSeverity.ERROR);
+    expect(error.type, AnalysisErrorType.COMPILE_TIME_ERROR);
+    expect(error.message, startsWith('Target of URI does not exist'));
   }
 
-  test_lintError() {
-    // Requires task model.
-    AnalysisEngine.instance.useTaskModel = true;
-
+  test_lintError() async {
     var camelCaseTypesLintName = 'camel_case_types';
 
     addFile(
@@ -86,69 +72,64 @@
         new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
     handleSuccessfulRequest(request);
 
-    return waitForTasksFinished().then((_) {
-      AnalysisContext testContext = server.getContainingContext(testFile);
-      List<Linter> lints = getLints(testContext);
-      // Registry should only contain single lint rule.
-      expect(lints, hasLength(1));
-      LintRule lint = lints.first as LintRule;
-      expect(lint.name, camelCaseTypesLintName);
-      // Verify lint error result.
-      List<AnalysisError> errors = filesErrors[testFile];
-      expect(errors, hasLength(1));
-      AnalysisError error = errors[0];
-      expect(error.location.file, '/project/bin/test.dart');
-      expect(error.severity, AnalysisErrorSeverity.INFO);
-      expect(error.type, AnalysisErrorType.LINT);
-      expect(error.message, lint.description);
-    });
+    await waitForTasksFinished();
+    AnalysisContext testContext = server.getContainingContext(testFile);
+    List<Linter> lints = getLints(testContext);
+    // Registry should only contain single lint rule.
+    expect(lints, hasLength(1));
+    LintRule lint = lints.first as LintRule;
+    expect(lint.name, camelCaseTypesLintName);
+    // Verify lint error result.
+    List<AnalysisError> errors = filesErrors[testFile];
+    expect(errors, hasLength(1));
+    AnalysisError error = errors[0];
+    expect(error.location.file, '/project/bin/test.dart');
+    expect(error.severity, AnalysisErrorSeverity.INFO);
+    expect(error.type, AnalysisErrorType.LINT);
+    expect(error.message, lint.description);
   }
 
-  test_notInAnalysisRoot() {
+  test_notInAnalysisRoot() async {
     createProject();
     String otherFile = '/other.dart';
     addFile(otherFile, 'UnknownType V;');
     addTestFile('''
 import '/other.dart';
-
 main() {
   print(V);
 }
 ''');
-    return waitForTasksFinished().then((_) {
-      expect(filesErrors[otherFile], isNull);
-    });
+    await waitForTasksFinished();
+    expect(filesErrors[otherFile], isNull);
   }
 
-  test_ParserError() {
+  test_ParserError() async {
     createProject();
     addTestFile('library lib');
-    return waitForTasksFinished().then((_) {
-      List<AnalysisError> errors = filesErrors[testFile];
-      expect(errors, hasLength(1));
-      AnalysisError error = errors[0];
-      expect(error.location.file, '/project/bin/test.dart');
-      expect(error.location.offset, isPositive);
-      expect(error.location.length, isNonNegative);
-      expect(error.severity, AnalysisErrorSeverity.ERROR);
-      expect(error.type, AnalysisErrorType.SYNTACTIC_ERROR);
-      expect(error.message, isNotNull);
-    });
+    await waitForTasksFinished();
+    List<AnalysisError> errors = filesErrors[testFile];
+    expect(errors, hasLength(1));
+    AnalysisError error = errors[0];
+    expect(error.location.file, '/project/bin/test.dart');
+    expect(error.location.offset, isPositive);
+    expect(error.location.length, isNonNegative);
+    expect(error.severity, AnalysisErrorSeverity.ERROR);
+    expect(error.type, AnalysisErrorType.SYNTACTIC_ERROR);
+    expect(error.message, isNotNull);
   }
 
-  test_StaticWarning() {
+  test_StaticWarning() async {
     createProject();
     addTestFile('''
 main() {
   print(UNKNOWN);
 }
 ''');
-    return waitForTasksFinished().then((_) {
-      List<AnalysisError> errors = filesErrors[testFile];
-      expect(errors, hasLength(1));
-      AnalysisError error = errors[0];
-      expect(error.severity, AnalysisErrorSeverity.WARNING);
-      expect(error.type, AnalysisErrorType.STATIC_WARNING);
-    });
+    await waitForTasksFinished();
+    List<AnalysisError> errors = filesErrors[testFile];
+    expect(errors, hasLength(1));
+    AnalysisError error = errors[0];
+    expect(error.severity, AnalysisErrorSeverity.WARNING);
+    expect(error.type, AnalysisErrorType.STATIC_WARNING);
   }
 }
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
index a44d798..6c2b57a3 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
@@ -108,58 +108,54 @@
     createProject();
   }
 
-  test_ANNOTATION_hasArguments() {
+  test_ANNOTATION_hasArguments() async {
     addTestFile('''
 class AAA {
   const AAA(a, b, c);
 }
 @AAA(1, 2, 3) main() {}
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA(', '@AAA('.length);
-      assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length);
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA(', '@AAA('.length);
+    assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length);
   }
 
-  test_ANNOTATION_noArguments() {
+  test_ANNOTATION_noArguments() async {
     addTestFile('''
 const AAA = 42;
 @AAA main() {}
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA');
   }
 
-  test_BUILT_IN_abstract() {
+  test_BUILT_IN_abstract() async {
     addTestFile('''
 abstract class A {};
 abstract class B = Object with A;
 main() {
   var abstract = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class A');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class B');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'abstract = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class A');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class B');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'abstract = 42');
   }
 
-  test_BUILT_IN_as() {
+  test_BUILT_IN_as() async {
     addTestFile('''
 import 'dart:math' as math;
 main() {
   p as int;
   var as = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'as math');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'as int');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'as = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'as math');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'as int');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'as = 42');
   }
 
-  test_BUILT_IN_async() {
+  test_BUILT_IN_async() async {
     addTestFile('''
 fa() async {}
 fb() async* {}
@@ -167,14 +163,13 @@
   bool async = false;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async');
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async*');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'async = false');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async');
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async*');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'async = false');
   }
 
-  test_BUILT_IN_await() {
+  test_BUILT_IN_await() async {
     addTestFile('''
 main() async {
   await 42;
@@ -183,37 +178,34 @@
   }
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'await 42');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'await for');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'await 42');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'await for');
   }
 
-  test_BUILT_IN_deferred() {
+  test_BUILT_IN_deferred() async {
     addTestFile('''
 import 'dart:math' deferred as math;
 main() {
   var deferred = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'deferred as math');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'deferred = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'deferred as math');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'deferred = 42');
   }
 
-  test_BUILT_IN_export() {
+  test_BUILT_IN_export() async {
     addTestFile('''
 export "dart:math";
 main() {
   var export = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'export "dart:');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'export = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'export "dart:');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'export = 42');
   }
 
-  test_BUILT_IN_external() {
+  test_BUILT_IN_external() async {
     addTestFile('''
 class A {
   external A();
@@ -222,15 +214,14 @@
 external main() {
   var external = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'external A()');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'external aaa()');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'external main()');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'external = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'external A()');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'external aaa()');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'external main()');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'external = 42');
   }
 
-  test_BUILT_IN_factory() {
+  test_BUILT_IN_factory() async {
     addTestFile('''
 class A {
   factory A() => null;
@@ -238,13 +229,12 @@
 main() {
   var factory = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'factory A()');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'factory A()');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42');
   }
 
-  test_BUILT_IN_get() {
+  test_BUILT_IN_get() async {
     addTestFile('''
 get aaa => 1;
 class A {
@@ -253,63 +243,58 @@
 main() {
   var get = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'get aaa =>');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'get bbb =>');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'get = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'get aaa =>');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'get bbb =>');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'get = 42');
   }
 
-  test_BUILT_IN_hide() {
+  test_BUILT_IN_hide() async {
     addTestFile('''
 import 'foo.dart' hide Foo;
 main() {
   var hide = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'hide Foo');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'hide = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'hide Foo');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'hide = 42');
   }
 
-  test_BUILT_IN_implements() {
+  test_BUILT_IN_implements() async {
     addTestFile('''
 class A {}
 class B implements A {}
 main() {
   var implements = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'implements A {}');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'implements = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'implements A {}');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'implements = 42');
   }
 
-  test_BUILT_IN_import() {
+  test_BUILT_IN_import() async {
     addTestFile('''
 import "foo.dart";
 main() {
   var import = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'import "');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'import = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'import "');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'import = 42');
   }
 
-  test_BUILT_IN_library() {
+  test_BUILT_IN_library() async {
     addTestFile('''
 library lib;
 main() {
   var library = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'library lib;');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'library = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'library lib;');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'library = 42');
   }
 
-  test_BUILT_IN_native() {
+  test_BUILT_IN_native() async {
     addTestFile('''
 class A native "A_native" {}
 class B {
@@ -318,14 +303,13 @@
 main() {
   var native = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'native "A_');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'native "bbb_');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'native "A_');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'native "bbb_');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42');
   }
 
-  test_BUILT_IN_on() {
+  test_BUILT_IN_on() async {
     addTestFile('''
 main() {
   try {
@@ -333,13 +317,12 @@
   }
   var on = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'on int');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'on = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'on int');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'on = 42');
   }
 
-  test_BUILT_IN_operator() {
+  test_BUILT_IN_operator() async {
     addTestFile('''
 class A {
   operator +(x) => null;
@@ -347,26 +330,24 @@
 main() {
   var operator = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'operator +(');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'operator = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'operator +(');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'operator = 42');
   }
 
-  test_BUILT_IN_part() {
+  test_BUILT_IN_part() async {
     addTestFile('''
 part "my_part.dart";
 main() {
   var part = 42;
 }''');
     addFile('/project/bin/my_part.dart', 'part of lib;');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
   }
 
-  test_BUILT_IN_partOf() {
+  test_BUILT_IN_partOf() async {
     addTestFile('''
 part of lib;
 main() {
@@ -374,15 +355,13 @@
   var of = 2;
 }''');
     _addLibraryForTestPart();
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.BUILT_IN, 'part of', 'part of'.length);
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 1');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'part of', 'part of'.length);
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 1');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2');
   }
 
-  test_BUILT_IN_set() {
+  test_BUILT_IN_set() async {
     addTestFile('''
 set aaa(x) {}
 class A
@@ -391,26 +370,24 @@
 main() {
   var set = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'set aaa(');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'set bbb(');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'set = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'set aaa(');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'set bbb(');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'set = 42');
   }
 
-  test_BUILT_IN_show() {
+  test_BUILT_IN_show() async {
     addTestFile('''
 import 'foo.dart' show Foo;
 main() {
   var show = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'show Foo');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'show = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'show Foo');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'show = 42');
   }
 
-  test_BUILT_IN_static() {
+  test_BUILT_IN_static() async {
     addTestFile('''
 class A {
   static aaa;
@@ -419,14 +396,13 @@
 main() {
   var static = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'static aaa;');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'static bbb()');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'static = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'static aaa;');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'static bbb()');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'static = 42');
   }
 
-  test_BUILT_IN_sync() {
+  test_BUILT_IN_sync() async {
     addTestFile('''
 fa() sync {}
 fb() sync* {}
@@ -434,81 +410,74 @@
   bool sync = false;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync');
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync*');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'sync = false');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync');
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync*');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'sync = false');
   }
 
-  test_BUILT_IN_typedef() {
+  test_BUILT_IN_typedef() async {
     addTestFile('''
 typedef A();
 main() {
   var typedef = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42');
   }
 
-  test_BUILT_IN_yield() {
+  test_BUILT_IN_yield() async {
     addTestFile('''
 main() async* {
   yield 42;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'yield 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'yield 42');
   }
 
-  test_BUILT_IN_yieldStar() {
+  test_BUILT_IN_yieldStar() async {
     addTestFile('''
 main() async* {
   yield* [];
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'yield*');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'yield*');
   }
 
-  test_CLASS() {
+  test_CLASS() async {
     addTestFile('''
 class AAA {}
 AAA aaa;
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.CLASS, 'AAA {}');
-      assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.CLASS, 'AAA {}');
+    assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa');
   }
 
-  test_CLASS_notDynamic() {
+  test_CLASS_notDynamic() async {
     addTestFile('''
 dynamic f() {}
 ''');
-    return prepareHighlights().then((_) {
-      assertNoRegion(HighlightRegionType.CLASS, 'dynamic f()');
-    });
+    await prepareHighlights();
+    assertNoRegion(HighlightRegionType.CLASS, 'dynamic f()');
   }
 
-  test_CLASS_notVoid() {
+  test_CLASS_notVoid() async {
     addTestFile('''
 void f() {}
 ''');
-    return prepareHighlights().then((_) {
-      assertNoRegion(HighlightRegionType.CLASS, 'void f()');
-    });
+    await prepareHighlights();
+    assertNoRegion(HighlightRegionType.CLASS, 'void f()');
   }
 
-  test_COMMENT() {
+  test_COMMENT() async {
     addTestFile('''
 /**
  * documentation comment
- */ 
+ */
 void main() {
   // end-of-line comment
   my_function(1);
@@ -518,14 +487,13 @@
  /* block comment */
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.COMMENT_DOCUMENTATION, '/**', 32);
-      assertHasRegion(HighlightRegionType.COMMENT_END_OF_LINE, '//', 22);
-      assertHasRegion(HighlightRegionType.COMMENT_BLOCK, '/* b', 19);
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.COMMENT_DOCUMENTATION, '/**', 32);
+    assertHasRegion(HighlightRegionType.COMMENT_END_OF_LINE, '//', 22);
+    assertHasRegion(HighlightRegionType.COMMENT_BLOCK, '/* b', 19);
   }
 
-  test_CONSTRUCTOR() {
+  test_CONSTRUCTOR() async {
     addTestFile('''
 class AAA {
   AAA() {}
@@ -536,42 +504,37 @@
   new AAA.name(42);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
-      assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
-      assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA() {}');
-      assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA();');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
+    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
+    assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA() {}');
+    assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA();');
   }
 
-  test_DIRECTIVE() {
+  test_DIRECTIVE() async {
     addTestFile('''
 library lib;
 import 'dart:math';
 export 'dart:math';
 part 'part.dart';
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.DIRECTIVE, "library lib;");
-      assertHasStringRegion(
-          HighlightRegionType.DIRECTIVE, "import 'dart:math';");
-      assertHasStringRegion(
-          HighlightRegionType.DIRECTIVE, "export 'dart:math';");
-      assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part 'part.dart';");
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "library lib;");
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "import 'dart:math';");
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "export 'dart:math';");
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part 'part.dart';");
   }
 
-  test_DIRECTIVE_partOf() {
+  test_DIRECTIVE_partOf() async {
     addTestFile('''
 part of lib;
 ''');
     _addLibraryForTestPart();
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part of lib;");
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part of lib;");
   }
 
-  test_DYNAMIC_TYPE() {
+  test_DYNAMIC_TYPE() async {
     addTestFile('''
 f() {}
 main(p) {
@@ -581,26 +544,24 @@
   var v3 = v2;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'p)');
-      assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'v1 =');
-      assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v2;');
-      assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v3 =');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'p)');
+    assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'v1 =');
+    assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v2;');
+    assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v3 =');
   }
 
-  test_ENUM() {
+  test_ENUM() async {
     addTestFile('''
 enum MyEnum {A, B, C}
 MyEnum value;
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.ENUM, 'MyEnum {');
-      assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.ENUM, 'MyEnum {');
+    assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;');
   }
 
-  test_ENUM_CONSTANT() {
+  test_ENUM_CONSTANT() async {
     addTestFile('''
 enum MyEnum {AAA, BBB}
 main() {
@@ -608,15 +569,14 @@
   print(MyEnum.BBB);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, ');
-      assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}');
-      assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);');
-      assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, ');
+    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}');
+    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);');
+    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);');
   }
 
-  test_FIELD() {
+  test_FIELD() async {
     addTestFile('''
 class A {
   int aaa = 1;
@@ -628,16 +588,15 @@
   a.bbb = 5;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.FIELD, 'aaa = 1');
-      assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
-      assertHasRegion(HighlightRegionType.FIELD, 'bbb = 3');
-      assertHasRegion(HighlightRegionType.FIELD, 'aaa = 4');
-      assertHasRegion(HighlightRegionType.FIELD, 'bbb = 5');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.FIELD, 'aaa = 1');
+    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
+    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 3');
+    assertHasRegion(HighlightRegionType.FIELD, 'aaa = 4');
+    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 5');
   }
 
-  test_FIELD_STATIC() {
+  test_FIELD_STATIC() async {
     addTestFile('''
 class A {
   static aaa = 1;
@@ -650,40 +609,37 @@
   A.ccc = 3;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 1');
-      assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 2');
-      assertHasRegion(HighlightRegionType.FIELD_STATIC, 'bbb;');
-      assertHasRegion(HighlightRegionType.FIELD_STATIC, 'ccc = 3');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 1');
+    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 2');
+    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'bbb;');
+    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'ccc = 3');
   }
 
-  test_FUNCTION() {
+  test_FUNCTION() async {
     addTestFile('''
 fff(p) {}
 main() {
   fff(42);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.FUNCTION_DECLARATION, 'fff(p) {}');
-      assertHasRegion(HighlightRegionType.FUNCTION, 'fff(42)');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.FUNCTION_DECLARATION, 'fff(p) {}');
+    assertHasRegion(HighlightRegionType.FUNCTION, 'fff(42)');
   }
 
-  test_FUNCTION_TYPE_ALIAS() {
+  test_FUNCTION_TYPE_ALIAS() async {
     addTestFile('''
 typedef FFF(p);
 main(FFF fff) {
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)');
-      assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)');
+    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)');
   }
 
-  test_GETTER_DECLARATION() {
+  test_GETTER_DECLARATION() async {
     addTestFile('''
 get aaa => null;
 class A {
@@ -694,15 +650,14 @@
   a.bbb;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'aaa => null');
-      assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'bbb => null');
-      assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa;');
-      assertHasRegion(HighlightRegionType.FIELD, 'bbb;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'aaa => null');
+    assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'bbb => null');
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa;');
+    assertHasRegion(HighlightRegionType.FIELD, 'bbb;');
   }
 
-  test_IDENTIFIER_DEFAULT() {
+  test_IDENTIFIER_DEFAULT() async {
     addTestFile('''
 main() {
   aaa = 42;
@@ -710,27 +665,25 @@
   CCC ccc;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'aaa = 42');
-      assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'bbb(84)');
-      assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'CCC ccc');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'aaa = 42');
+    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'bbb(84)');
+    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'CCC ccc');
   }
 
-  test_IMPORT_PREFIX() {
+  test_IMPORT_PREFIX() async {
     addTestFile('''
 import 'dart:math' as ma;
 main() {
   ma.max(1, 2);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma;');
-      assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma.max');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma;');
+    assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma.max');
   }
 
-  test_KEYWORD() {
+  test_KEYWORD() async {
     addTestFile('''
 main() {
   assert(true);
@@ -763,49 +716,47 @@
 }
 class C = Object with A;
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.KEYWORD, 'assert(true)');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'for (;;)');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'for (var v4 in');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'break;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'case 0:');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'catch (e) {}');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'class A {}');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'const v1');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'continue;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'default:');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'do {} while');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'if (true)');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'false;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'final v3 =');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'finally {}');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'in []');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'is int');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'new A();');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'rethrow;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'return this');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'super();');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'switch (0)');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'this;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'true;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'try {');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'while (true) {}');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'while (true);');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'assert(true)');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for (;;)');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for (var v4 in');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'break;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'case 0:');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'catch (e) {}');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'class A {}');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'const v1');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'continue;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'default:');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'do {} while');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if (true)');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'false;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'final v3 =');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'finally {}');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'in []');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'is int');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'new A();');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'rethrow;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'return this');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'super();');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'switch (0)');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'this;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'true;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'try {');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'while (true) {}');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'while (true);');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
   }
 
-  test_KEYWORD_void() {
+  test_KEYWORD_void() async {
     addTestFile('''
 void main() {
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.KEYWORD, 'void main()');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'void main()');
   }
 
-  test_LABEL() {
+  test_LABEL() async {
     addTestFile('''
 main() {
 myLabel:
@@ -814,57 +765,50 @@
   }
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.LABEL, 'myLabel:');
-      assertHasRegion(HighlightRegionType.LABEL, 'myLabel;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LABEL, 'myLabel:');
+    assertHasRegion(HighlightRegionType.LABEL, 'myLabel;');
   }
 
-  test_LITERAL_BOOLEAN() {
+  test_LITERAL_BOOLEAN() async {
     addTestFile('var V = true;');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.LITERAL_BOOLEAN, 'true;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LITERAL_BOOLEAN, 'true;');
   }
 
-  test_LITERAL_DOUBLE() {
+  test_LITERAL_DOUBLE() async {
     addTestFile('var V = 4.2;');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.LITERAL_DOUBLE, '4.2;', '4.2'.length);
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LITERAL_DOUBLE, '4.2;', '4.2'.length);
   }
 
-  test_LITERAL_INTEGER() {
+  test_LITERAL_INTEGER() async {
     addTestFile('var V = 42;');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '42;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '42;');
   }
 
-  test_LITERAL_LIST() {
+  test_LITERAL_LIST() async {
     addTestFile('var V = <int>[1, 2, 3];');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
   }
 
-  test_LITERAL_MAP() {
+  test_LITERAL_MAP() async {
     addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
-          "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
+        "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
   }
 
-  test_LITERAL_STRING() {
+  test_LITERAL_STRING() async {
     addTestFile('var V = "abc";');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.LITERAL_STRING, '"abc";', '"abc"'.length);
-    });
+    await prepareHighlights();
+    assertHasRegion(
+        HighlightRegionType.LITERAL_STRING, '"abc";', '"abc"'.length);
   }
 
-  test_LOCAL_VARIABLE() {
+  test_LOCAL_VARIABLE() async {
     addTestFile('''
 main() {
   int vvv = 0;
@@ -872,15 +816,13 @@
   vvv = 1;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.LOCAL_VARIABLE_DECLARATION, 'vvv = 0');
-      assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv;');
-      assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv = 1;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, 'vvv = 0');
+    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv;');
+    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv = 1;');
   }
 
-  test_METHOD() {
+  test_METHOD() async {
     addTestFile('''
 class A {
   aaa() {}
@@ -893,18 +835,16 @@
   A.bbb;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.METHOD_DECLARATION, 'aaa() {}');
-      assertHasRegion(
-          HighlightRegionType.METHOD_DECLARATION_STATIC, 'bbb() {}');
-      assertHasRegion(HighlightRegionType.METHOD, 'aaa();');
-      assertHasRegion(HighlightRegionType.METHOD, 'aaa;');
-      assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb();');
-      assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.METHOD_DECLARATION, 'aaa() {}');
+    assertHasRegion(HighlightRegionType.METHOD_DECLARATION_STATIC, 'bbb() {}');
+    assertHasRegion(HighlightRegionType.METHOD, 'aaa();');
+    assertHasRegion(HighlightRegionType.METHOD, 'aaa;');
+    assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb();');
+    assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb;');
   }
 
-  test_METHOD_bestType() {
+  test_METHOD_bestType() async {
     addTestFile('''
 main(p) {
   if (p is List) {
@@ -912,26 +852,24 @@
   }
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.METHOD, 'add(null)');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.METHOD, 'add(null)');
   }
 
-  test_PARAMETER() {
+  test_PARAMETER() async {
     addTestFile('''
 main(int p) {
   p;
   p = 42;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.PARAMETER, 'p) {');
-      assertHasRegion(HighlightRegionType.PARAMETER, 'p;');
-      assertHasRegion(HighlightRegionType.PARAMETER, 'p = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.PARAMETER, 'p) {');
+    assertHasRegion(HighlightRegionType.PARAMETER, 'p;');
+    assertHasRegion(HighlightRegionType.PARAMETER, 'p = 42');
   }
 
-  test_SETTER_DECLARATION() {
+  test_SETTER_DECLARATION() async {
     addTestFile('''
 set aaa(x) {}
 class A {
@@ -942,15 +880,14 @@
   a.bbb = 2;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'aaa(x)');
-      assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'bbb(x)');
-      assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa = 1');
-      assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'aaa(x)');
+    assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'bbb(x)');
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa = 1');
+    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
   }
 
-  test_TOP_LEVEL_VARIABLE() {
+  test_TOP_LEVEL_VARIABLE() async {
     addTestFile('''
 const VVV = 0;
 @VVV // annotation
@@ -959,41 +896,38 @@
   VVV = 1;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 0');
-      assertHasRegion(
-          HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV // annotation');
-      assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV);');
-      assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 1');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 0');
+    assertHasRegion(
+        HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV // annotation');
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV);');
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 1');
   }
 
-  test_TYPE_NAME_DYNAMIC() {
+  test_TYPE_NAME_DYNAMIC() async {
     addTestFile('''
 dynamic main() {
   dynamic = 42;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic main()');
-      assertNoRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'dynamic main()');
-      assertNoRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic main()');
+    assertNoRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'dynamic main()');
+    assertNoRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic = 42');
   }
 
-  test_TYPE_PARAMETER() {
+  test_TYPE_PARAMETER() async {
     addTestFile('''
 class A<T> {
   T fff;
   T mmm(T p) => null;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T> {');
-      assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T fff;');
-      assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm(');
-      assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T> {');
+    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T fff;');
+    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm(');
+    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)');
   }
 
   void _addLibraryForTestPart() {
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
index 28eda94..0342c89 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
@@ -109,58 +109,54 @@
     createProject();
   }
 
-  test_ANNOTATION_hasArguments() {
+  test_ANNOTATION_hasArguments() async {
     addTestFile('''
 class AAA {
   const AAA(a, b, c);
 }
 @AAA(1, 2, 3) main() {}
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA(', '@AAA('.length);
-      assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length);
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA(', '@AAA('.length);
+    assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length);
   }
 
-  test_ANNOTATION_noArguments() {
+  test_ANNOTATION_noArguments() async {
     addTestFile('''
 const AAA = 42;
 @AAA main() {}
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA');
   }
 
-  test_BUILT_IN_abstract() {
+  test_BUILT_IN_abstract() async {
     addTestFile('''
 abstract class A {};
 abstract class B = Object with A;
 main() {
   var abstract = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class A');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class B');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'abstract = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class A');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class B');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'abstract = 42');
   }
 
-  test_BUILT_IN_as() {
+  test_BUILT_IN_as() async {
     addTestFile('''
 import 'dart:math' as math;
 main() {
   p as int;
   var as = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'as math');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'as int');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'as = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'as math');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'as int');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'as = 42');
   }
 
-  test_BUILT_IN_async() {
+  test_BUILT_IN_async() async {
     addTestFile('''
 fa() async {}
 fb() async* {}
@@ -168,14 +164,13 @@
   bool async = false;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async');
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async*');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'async = false');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async');
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async*');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'async = false');
   }
 
-  test_BUILT_IN_await() {
+  test_BUILT_IN_await() async {
     addTestFile('''
 main() async {
   await 42;
@@ -184,37 +179,34 @@
   }
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'await 42');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'await for');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'await 42');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'await for');
   }
 
-  test_BUILT_IN_deferred() {
+  test_BUILT_IN_deferred() async {
     addTestFile('''
 import 'dart:math' deferred as math;
 main() {
   var deferred = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'deferred as math');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'deferred = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'deferred as math');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'deferred = 42');
   }
 
-  test_BUILT_IN_export() {
+  test_BUILT_IN_export() async {
     addTestFile('''
 export "dart:math";
 main() {
   var export = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'export "dart:');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'export = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'export "dart:');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'export = 42');
   }
 
-  test_BUILT_IN_external() {
+  test_BUILT_IN_external() async {
     addTestFile('''
 class A {
   external A();
@@ -223,15 +215,14 @@
 external main() {
   var external = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'external A()');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'external aaa()');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'external main()');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'external = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'external A()');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'external aaa()');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'external main()');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'external = 42');
   }
 
-  test_BUILT_IN_factory() {
+  test_BUILT_IN_factory() async {
     addTestFile('''
 class A {
   factory A() => null;
@@ -239,13 +230,12 @@
 main() {
   var factory = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'factory A()');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'factory A()');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42');
   }
 
-  test_BUILT_IN_get() {
+  test_BUILT_IN_get() async {
     addTestFile('''
 get aaa => 1;
 class A {
@@ -254,63 +244,58 @@
 main() {
   var get = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'get aaa =>');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'get bbb =>');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'get = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'get aaa =>');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'get bbb =>');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'get = 42');
   }
 
-  test_BUILT_IN_hide() {
+  test_BUILT_IN_hide() async {
     addTestFile('''
 import 'foo.dart' hide Foo;
 main() {
   var hide = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'hide Foo');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'hide = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'hide Foo');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'hide = 42');
   }
 
-  test_BUILT_IN_implements() {
+  test_BUILT_IN_implements() async {
     addTestFile('''
 class A {}
 class B implements A {}
 main() {
   var implements = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'implements A {}');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'implements = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'implements A {}');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'implements = 42');
   }
 
-  test_BUILT_IN_import() {
+  test_BUILT_IN_import() async {
     addTestFile('''
 import "foo.dart";
 main() {
   var import = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'import "');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'import = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'import "');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'import = 42');
   }
 
-  test_BUILT_IN_library() {
+  test_BUILT_IN_library() async {
     addTestFile('''
 library lib;
 main() {
   var library = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'library lib;');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'library = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'library lib;');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'library = 42');
   }
 
-  test_BUILT_IN_native() {
+  test_BUILT_IN_native() async {
     addTestFile('''
 class A native "A_native" {}
 class B {
@@ -319,14 +304,13 @@
 main() {
   var native = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'native "A_');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'native "bbb_');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'native "A_');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'native "bbb_');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42');
   }
 
-  test_BUILT_IN_on() {
+  test_BUILT_IN_on() async {
     addTestFile('''
 main() {
   try {
@@ -334,13 +318,12 @@
   }
   var on = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'on int');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'on = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'on int');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'on = 42');
   }
 
-  test_BUILT_IN_operator() {
+  test_BUILT_IN_operator() async {
     addTestFile('''
 class A {
   operator +(x) => null;
@@ -348,26 +331,24 @@
 main() {
   var operator = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'operator +(');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'operator = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'operator +(');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'operator = 42');
   }
 
-  test_BUILT_IN_part() {
+  test_BUILT_IN_part() async {
     addTestFile('''
 part "my_part.dart";
 main() {
   var part = 42;
 }''');
     addFile('/project/bin/my_part.dart', 'part of lib;');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
   }
 
-  test_BUILT_IN_partOf() {
+  test_BUILT_IN_partOf() async {
     addTestFile('''
 part of lib;
 main() {
@@ -375,15 +356,13 @@
   var of = 2;
 }''');
     _addLibraryForTestPart();
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.BUILT_IN, 'part of', 'part of'.length);
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 1');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'part of', 'part of'.length);
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 1');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2');
   }
 
-  test_BUILT_IN_set() {
+  test_BUILT_IN_set() async {
     addTestFile('''
 set aaa(x) {}
 class A
@@ -392,26 +371,24 @@
 main() {
   var set = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'set aaa(');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'set bbb(');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'set = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'set aaa(');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'set bbb(');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'set = 42');
   }
 
-  test_BUILT_IN_show() {
+  test_BUILT_IN_show() async {
     addTestFile('''
 import 'foo.dart' show Foo;
 main() {
   var show = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'show Foo');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'show = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'show Foo');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'show = 42');
   }
 
-  test_BUILT_IN_static() {
+  test_BUILT_IN_static() async {
     addTestFile('''
 class A {
   static aaa;
@@ -420,14 +397,13 @@
 main() {
   var static = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'static aaa;');
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'static bbb()');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'static = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'static aaa;');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'static bbb()');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'static = 42');
   }
 
-  test_BUILT_IN_sync() {
+  test_BUILT_IN_sync() async {
     addTestFile('''
 fa() sync {}
 fb() sync* {}
@@ -435,81 +411,74 @@
   bool sync = false;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync');
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync*');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'sync = false');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync');
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync*');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'sync = false');
   }
 
-  test_BUILT_IN_typedef() {
+  test_BUILT_IN_typedef() async {
     addTestFile('''
 typedef A();
 main() {
   var typedef = 42;
 }''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();');
-      assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42');
   }
 
-  test_BUILT_IN_yield() {
+  test_BUILT_IN_yield() async {
     addTestFile('''
 main() async* {
   yield 42;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.BUILT_IN, 'yield 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'yield 42');
   }
 
-  test_BUILT_IN_yieldStar() {
+  test_BUILT_IN_yieldStar() async {
     addTestFile('''
 main() async* {
   yield* [];
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.BUILT_IN, 'yield*');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'yield*');
   }
 
-  test_CLASS() {
+  test_CLASS() async {
     addTestFile('''
 class AAA {}
 AAA aaa;
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.CLASS, 'AAA {}');
-      assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.CLASS, 'AAA {}');
+    assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa');
   }
 
-  test_CLASS_notDynamic() {
+  test_CLASS_notDynamic() async {
     addTestFile('''
 dynamic f() {}
 ''');
-    return prepareHighlights().then((_) {
-      assertNoRegion(HighlightRegionType.CLASS, 'dynamic f()');
-    });
+    await prepareHighlights();
+    assertNoRegion(HighlightRegionType.CLASS, 'dynamic f()');
   }
 
-  test_CLASS_notVoid() {
+  test_CLASS_notVoid() async {
     addTestFile('''
 void f() {}
 ''');
-    return prepareHighlights().then((_) {
-      assertNoRegion(HighlightRegionType.CLASS, 'void f()');
-    });
+    await prepareHighlights();
+    assertNoRegion(HighlightRegionType.CLASS, 'void f()');
   }
 
-  test_COMMENT() {
+  test_COMMENT() async {
     addTestFile('''
 /**
  * documentation comment
- */ 
+ */
 void main() {
   // end-of-line comment
   my_function(1);
@@ -519,14 +488,13 @@
  /* block comment */
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.COMMENT_DOCUMENTATION, '/**', 32);
-      assertHasRegion(HighlightRegionType.COMMENT_END_OF_LINE, '//', 22);
-      assertHasRegion(HighlightRegionType.COMMENT_BLOCK, '/* b', 19);
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.COMMENT_DOCUMENTATION, '/**', 32);
+    assertHasRegion(HighlightRegionType.COMMENT_END_OF_LINE, '//', 22);
+    assertHasRegion(HighlightRegionType.COMMENT_BLOCK, '/* b', 19);
   }
 
-  test_CONSTRUCTOR() {
+  test_CONSTRUCTOR() async {
     addTestFile('''
 class AAA {
   AAA() {}
@@ -537,42 +505,37 @@
   new AAA.name(42);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
-      assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
-      assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA() {}');
-      assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA();');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
+    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
+    assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA() {}');
+    assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA();');
   }
 
-  test_DIRECTIVE() {
+  test_DIRECTIVE() async {
     addTestFile('''
 library lib;
 import 'dart:math';
 export 'dart:math';
 part 'part.dart';
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.DIRECTIVE, "library lib;");
-      assertHasStringRegion(
-          HighlightRegionType.DIRECTIVE, "import 'dart:math';");
-      assertHasStringRegion(
-          HighlightRegionType.DIRECTIVE, "export 'dart:math';");
-      assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part 'part.dart';");
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "library lib;");
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "import 'dart:math';");
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "export 'dart:math';");
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part 'part.dart';");
   }
 
-  test_DIRECTIVE_partOf() {
+  test_DIRECTIVE_partOf() async {
     addTestFile('''
 part of lib;
 ''');
     _addLibraryForTestPart();
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part of lib;");
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part of lib;");
   }
 
-  test_DYNAMIC_LOCAL_VARIABLE() {
+  test_DYNAMIC_LOCAL_VARIABLE() async {
     addTestFile('''
 f() {}
 main(p) {
@@ -580,27 +543,24 @@
   v;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, 'v = f()');
-      assertHasRegion(
-          HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, 'v;');
-    });
+    await prepareHighlights();
+    assertHasRegion(
+        HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, 'v = f()');
+    assertHasRegion(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, 'v;');
   }
 
-  test_DYNAMIC_PARAMETER() {
+  test_DYNAMIC_PARAMETER() async {
     addTestFile('''
 main(p) {
   print(p);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, 'p)');
-      assertHasRegion(HighlightRegionType.DYNAMIC_PARAMETER_REFERENCE, 'p);');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, 'p)');
+    assertHasRegion(HighlightRegionType.DYNAMIC_PARAMETER_REFERENCE, 'p);');
   }
 
-  test_DYNAMIC_VARIABLE_field() {
+  test_DYNAMIC_VARIABLE_field() async {
     addTestFile('''
 class A {
   var f;
@@ -609,24 +569,22 @@
   }
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'f;');
-      assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'f = 1');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'f;');
+    assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'f = 1');
   }
 
-  test_ENUM() {
+  test_ENUM() async {
     addTestFile('''
 enum MyEnum {A, B, C}
 MyEnum value;
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.ENUM, 'MyEnum {');
-      assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.ENUM, 'MyEnum {');
+    assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;');
   }
 
-  test_ENUM_CONSTANT() {
+  test_ENUM_CONSTANT() async {
     addTestFile('''
 enum MyEnum {AAA, BBB}
 main() {
@@ -634,27 +592,25 @@
   print(MyEnum.BBB);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, ');
-      assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}');
-      assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);');
-      assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, ');
+    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}');
+    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);');
+    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);');
   }
 
-  test_FUNCTION_TYPE_ALIAS() {
+  test_FUNCTION_TYPE_ALIAS() async {
     addTestFile('''
 typedef FFF(p);
 main(FFF fff) {
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)');
-      assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)');
+    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)');
   }
 
-  test_GETTER() {
+  test_GETTER() async {
     addTestFile('''
 get aaa => null;
 class A {
@@ -667,20 +623,19 @@
   A.ccc;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION, 'aaa => null');
-      assertHasRegion(
-          HighlightRegionType.INSTANCE_GETTER_DECLARATION, 'bbb => null');
-      assertHasRegion(
-          HighlightRegionType.STATIC_GETTER_DECLARATION, 'ccc => null');
-      assertHasRegion(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'aaa;');
-      assertHasRegion(HighlightRegionType.INSTANCE_GETTER_REFERENCE, 'bbb;');
-      assertHasRegion(HighlightRegionType.STATIC_GETTER_REFERENCE, 'ccc;');
-    });
+    await prepareHighlights();
+    assertHasRegion(
+        HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION, 'aaa => null');
+    assertHasRegion(
+        HighlightRegionType.INSTANCE_GETTER_DECLARATION, 'bbb => null');
+    assertHasRegion(
+        HighlightRegionType.STATIC_GETTER_DECLARATION, 'ccc => null');
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'aaa;');
+    assertHasRegion(HighlightRegionType.INSTANCE_GETTER_REFERENCE, 'bbb;');
+    assertHasRegion(HighlightRegionType.STATIC_GETTER_REFERENCE, 'ccc;');
   }
 
-  test_IDENTIFIER_DEFAULT() {
+  test_IDENTIFIER_DEFAULT() async {
     addTestFile('''
 main() {
   aaa = 42;
@@ -688,27 +643,25 @@
   CCC ccc;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'aaa = 42');
-      assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'bbb(84)');
-      assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'CCC ccc');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'aaa = 42');
+    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'bbb(84)');
+    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'CCC ccc');
   }
 
-  test_IMPORT_PREFIX() {
+  test_IMPORT_PREFIX() async {
     addTestFile('''
 import 'dart:math' as ma;
 main() {
   ma.max(1, 2);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma;');
-      assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma.max');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma;');
+    assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma.max');
   }
 
-  test_INSTANCE_FIELD() {
+  test_INSTANCE_FIELD() async {
     addTestFile('''
 class A {
   int aaa = 1;
@@ -720,31 +673,27 @@
   a.bbb = 5;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'aaa = 1');
-      assertHasRegion(
-          HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'bbb = 2');
-      assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'bbb = 3');
-      assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'aaa = 4');
-      assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'bbb = 5');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'aaa = 1');
+    assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'bbb = 2');
+    assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'bbb = 3');
+    assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'aaa = 4');
+    assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'bbb = 5');
   }
 
-  test_INSTANCE_FIELD_dynamic() {
+  test_INSTANCE_FIELD_dynamic() async {
     addTestFile('''
 class A {
   var f;
   A(this.f);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'f;');
-      assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'f);');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'f;');
+    assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'f);');
   }
 
-  test_KEYWORD() {
+  test_KEYWORD() async {
     addTestFile('''
 main() {
   assert(true);
@@ -777,49 +726,47 @@
 }
 class C = Object with A;
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.KEYWORD, 'assert(true)');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'for (;;)');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'for (var v4 in');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'break;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'case 0:');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'catch (e) {}');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'class A {}');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'const v1');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'continue;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'default:');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'do {} while');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'if (true)');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'false;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'final v3 =');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'finally {}');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'in []');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'is int');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'new A();');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'rethrow;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'return this');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'super();');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'switch (0)');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'this;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'true;');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'try {');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'while (true) {}');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'while (true);');
-      assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'assert(true)');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for (;;)');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for (var v4 in');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'break;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'case 0:');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'catch (e) {}');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'class A {}');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'const v1');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'continue;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'default:');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'do {} while');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if (true)');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'false;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'final v3 =');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'finally {}');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'in []');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'is int');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'new A();');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'rethrow;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'return this');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'super();');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'switch (0)');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'this;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'true;');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'try {');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'while (true) {}');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'while (true);');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
   }
 
-  test_KEYWORD_void() {
+  test_KEYWORD_void() async {
     addTestFile('''
 void main() {
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.KEYWORD, 'void main()');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'void main()');
   }
 
-  test_LABEL() {
+  test_LABEL() async {
     addTestFile('''
 main() {
 myLabel:
@@ -828,76 +775,67 @@
   }
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.LABEL, 'myLabel:');
-      assertHasRegion(HighlightRegionType.LABEL, 'myLabel;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LABEL, 'myLabel:');
+    assertHasRegion(HighlightRegionType.LABEL, 'myLabel;');
   }
 
-  test_LIBRARY_NAME_libraryDirective() {
+  test_LIBRARY_NAME_libraryDirective() async {
     addTestFile('''
 library my.lib.name;
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.LIBRARY_NAME, 'my.lib.name');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LIBRARY_NAME, 'my.lib.name');
   }
 
-  test_LIBRARY_NAME_partOfDirective() {
+  test_LIBRARY_NAME_partOfDirective() async {
     _addLibraryForTestPart();
     addTestFile('''
 part of my.lib.name;
 ''');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.LIBRARY_NAME, 'my.lib.name');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LIBRARY_NAME, 'my.lib.name');
   }
 
-  test_LITERAL_BOOLEAN() {
+  test_LITERAL_BOOLEAN() async {
     addTestFile('var V = true;');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.LITERAL_BOOLEAN, 'true;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LITERAL_BOOLEAN, 'true;');
   }
 
-  test_LITERAL_DOUBLE() {
+  test_LITERAL_DOUBLE() async {
     addTestFile('var V = 4.2;');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.LITERAL_DOUBLE, '4.2;', '4.2'.length);
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LITERAL_DOUBLE, '4.2;', '4.2'.length);
   }
 
-  test_LITERAL_INTEGER() {
+  test_LITERAL_INTEGER() async {
     addTestFile('var V = 42;');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '42;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '42;');
   }
 
-  test_LITERAL_LIST() {
+  test_LITERAL_LIST() async {
     addTestFile('var V = <int>[1, 2, 3];');
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
   }
 
-  test_LITERAL_MAP() {
+  test_LITERAL_MAP() async {
     addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
-    return prepareHighlights().then((_) {
-      assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
-          "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
-    });
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
+        "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
   }
 
-  test_LITERAL_STRING() {
+  test_LITERAL_STRING() async {
     addTestFile('var V = "abc";');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.LITERAL_STRING, '"abc";', '"abc"'.length);
-    });
+    await prepareHighlights();
+    assertHasRegion(
+        HighlightRegionType.LITERAL_STRING, '"abc";', '"abc"'.length);
   }
 
-  test_LOCAL_FUNCTION() {
+  test_LOCAL_FUNCTION() async {
     addTestFile('''
 main() {
   fff() {}
@@ -905,15 +843,13 @@
   fff;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.LOCAL_FUNCTION_DECLARATION, 'fff() {}');
-      assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_REFERENCE, 'fff();');
-      assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_REFERENCE, 'fff;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_DECLARATION, 'fff() {}');
+    assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_REFERENCE, 'fff();');
+    assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_REFERENCE, 'fff;');
   }
 
-  test_LOCAL_VARIABLE() {
+  test_LOCAL_VARIABLE() async {
     addTestFile('''
 main() {
   int vvv = 0;
@@ -921,15 +857,13 @@
   vvv = 1;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.LOCAL_VARIABLE_DECLARATION, 'vvv = 0');
-      assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_REFERENCE, 'vvv;');
-      assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_REFERENCE, 'vvv = 1;');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, 'vvv = 0');
+    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_REFERENCE, 'vvv;');
+    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_REFERENCE, 'vvv = 1;');
   }
 
-  test_METHOD() {
+  test_METHOD() async {
     addTestFile('''
 class A {
   aaa() {}
@@ -942,19 +876,17 @@
   A.bbb;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.INSTANCE_METHOD_DECLARATION, 'aaa() {}');
-      assertHasRegion(
-          HighlightRegionType.STATIC_METHOD_DECLARATION, 'bbb() {}');
-      assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'aaa();');
-      assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'aaa;');
-      assertHasRegion(HighlightRegionType.STATIC_METHOD_REFERENCE, 'bbb();');
-      assertHasRegion(HighlightRegionType.STATIC_METHOD_REFERENCE, 'bbb;');
-    });
+    await prepareHighlights();
+    assertHasRegion(
+        HighlightRegionType.INSTANCE_METHOD_DECLARATION, 'aaa() {}');
+    assertHasRegion(HighlightRegionType.STATIC_METHOD_DECLARATION, 'bbb() {}');
+    assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'aaa();');
+    assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'aaa;');
+    assertHasRegion(HighlightRegionType.STATIC_METHOD_REFERENCE, 'bbb();');
+    assertHasRegion(HighlightRegionType.STATIC_METHOD_REFERENCE, 'bbb;');
   }
 
-  test_METHOD_bestType() {
+  test_METHOD_bestType() async {
     addTestFile('''
 main(p) {
   if (p is List) {
@@ -962,27 +894,24 @@
   }
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'add(null)');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'add(null)');
   }
 
-  test_PARAMETER() {
+  test_PARAMETER() async {
     addTestFile('''
 main(int p) {
   p;
   p = 42;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'p) {');
-      assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'p;');
-      assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'p = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'p) {');
+    assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'p;');
+    assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'p = 42');
   }
 
-  test_SETTER_DECLARATION() {
+  test_SETTER_DECLARATION() async {
     addTestFile('''
 set aaa(x) {}
 class A {
@@ -995,20 +924,16 @@
   A.ccc = 3;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION, 'aaa(x)');
-      assertHasRegion(
-          HighlightRegionType.INSTANCE_SETTER_DECLARATION, 'bbb(x)');
-      assertHasRegion(HighlightRegionType.STATIC_SETTER_DECLARATION, 'ccc(x)');
-      assertHasRegion(
-          HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE, 'aaa = 1');
-      assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'bbb = 2');
-      assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'ccc = 3');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION, 'aaa(x)');
+    assertHasRegion(HighlightRegionType.INSTANCE_SETTER_DECLARATION, 'bbb(x)');
+    assertHasRegion(HighlightRegionType.STATIC_SETTER_DECLARATION, 'ccc(x)');
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE, 'aaa = 1');
+    assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'bbb = 2');
+    assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'ccc = 3');
   }
 
-  test_STATIC_FIELD() {
+  test_STATIC_FIELD() async {
     addTestFile('''
 class A {
   static aaa = 1;
@@ -1021,30 +946,28 @@
   A.ccc = 3;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.STATIC_FIELD_DECLARATION, 'aaa = 1');
-      assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'aaa = 2');
-      assertHasRegion(HighlightRegionType.STATIC_GETTER_REFERENCE, 'bbb;');
-      assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'ccc = 3');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.STATIC_FIELD_DECLARATION, 'aaa = 1');
+    assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'aaa = 2');
+    assertHasRegion(HighlightRegionType.STATIC_GETTER_REFERENCE, 'bbb;');
+    assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'ccc = 3');
   }
 
-  test_TOP_LEVEL_FUNCTION() {
+  test_TOP_LEVEL_FUNCTION() async {
     addTestFile('''
 fff(p) {}
 main() {
   fff(42);
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, 'fff(p) {}');
-      assertHasRegion(
-          HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, 'fff(42)');
-    });
+    await prepareHighlights();
+    assertHasRegion(
+        HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, 'fff(p) {}');
+    assertHasRegion(
+        HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, 'fff(42)');
   }
 
-  test_TOP_LEVEL_VARIABLE() {
+  test_TOP_LEVEL_VARIABLE() async {
     addTestFile('''
 const V1 = 1;
 var V2 = 2;
@@ -1054,47 +977,44 @@
   V2 = 3;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(
-          HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION, 'V1 = 1');
-      assertHasRegion(
-          HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION, 'V2 = 2');
-      assertHasRegion(
-          HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'V1 // annotation');
-      assertHasRegion(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'V1);');
-      assertHasRegion(HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE, 'V2 = 3');
-    });
+    await prepareHighlights();
+    assertHasRegion(
+        HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION, 'V1 = 1');
+    assertHasRegion(
+        HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION, 'V2 = 2');
+    assertHasRegion(
+        HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'V1 // annotation');
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'V1);');
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE, 'V2 = 3');
   }
 
-  test_TYPE_NAME_DYNAMIC() {
+  test_TYPE_NAME_DYNAMIC() async {
     addTestFile('''
 dynamic main() {
   dynamic = 42;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic main()');
-      assertNoRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'dynamic main()');
-      assertNoRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic = 42');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic main()');
+    assertNoRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'dynamic main()');
+    assertNoRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic = 42');
   }
 
-  test_TYPE_PARAMETER() {
+  test_TYPE_PARAMETER() async {
     addTestFile('''
 class A<T> {
   T fff;
   T mmm(T p) => null;
 }
 ''');
-    return prepareHighlights().then((_) {
-      assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T> {');
-      assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T fff;');
-      assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm(');
-      assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)');
-    });
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T> {');
+    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T fff;');
+    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm(');
+    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)');
   }
 
-  test_UNRESOLVED_INSTANCE_MEMBER_REFERENCE_dynamicVarTarget() {
+  test_UNRESOLVED_INSTANCE_MEMBER_REFERENCE_dynamicVarTarget() async {
     addTestFile('''
 main(p) {
   p.aaa;
@@ -1106,20 +1026,19 @@
   ''.length.ccc().ddd();
 }
 ''');
-    return prepareHighlights().then((_) {
-      HighlightRegionType type =
-          HighlightRegionType.UNRESOLVED_INSTANCE_MEMBER_REFERENCE;
-      assertHasRegion(type, 'aaa');
-      assertHasRegion(type, 'aaa++');
-      assertHasRegion(type, 'aaa += 0');
-      assertHasRegion(type, 'aaa; // ++');
-      assertHasRegion(type, 'aaa =');
-      assertHasRegion(type, 'bbb(');
-      assertHasRegion(type, 'ddd()');
-    });
+    await prepareHighlights();
+    HighlightRegionType type =
+        HighlightRegionType.UNRESOLVED_INSTANCE_MEMBER_REFERENCE;
+    assertHasRegion(type, 'aaa');
+    assertHasRegion(type, 'aaa++');
+    assertHasRegion(type, 'aaa += 0');
+    assertHasRegion(type, 'aaa; // ++');
+    assertHasRegion(type, 'aaa =');
+    assertHasRegion(type, 'bbb(');
+    assertHasRegion(type, 'ddd()');
   }
 
-  test_UNRESOLVED_INSTANCE_MEMBER_REFERENCE_nonDynamicTarget() {
+  test_UNRESOLVED_INSTANCE_MEMBER_REFERENCE_nonDynamicTarget() async {
     addTestFile('''
 import 'dart:math' as math;
 main(String str) {
@@ -1135,15 +1054,14 @@
   }
 }
 ''');
-    return prepareHighlights().then((_) {
-      HighlightRegionType type = HighlightRegionType.IDENTIFIER_DEFAULT;
-      assertHasRegion(type, 'aaa()');
-      assertHasRegion(type, 'bbb()');
-      assertHasRegion(type, 'ccc()');
-      assertHasRegion(type, 'unresolved(1)');
-      assertHasRegion(type, 'unresolved(2)');
-      assertHasRegion(type, 'unresolved(3)');
-    });
+    await prepareHighlights();
+    HighlightRegionType type = HighlightRegionType.IDENTIFIER_DEFAULT;
+    assertHasRegion(type, 'aaa()');
+    assertHasRegion(type, 'bbb()');
+    assertHasRegion(type, 'ccc()');
+    assertHasRegion(type, 'unresolved(1)');
+    assertHasRegion(type, 'unresolved(2)');
+    assertHasRegion(type, 'unresolved(3)');
   }
 
   void _addLibraryForTestPart() {
diff --git a/pkg/analysis_server/test/analysis/notification_implemented_test.dart b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
index 5c1c6ed..d5cde86 100644
--- a/pkg/analysis_server/test/analysis/notification_implemented_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
@@ -315,6 +315,84 @@
     assertHasImplementedMember('f(_) {} // A');
   }
 
+  test_static_field_instanceStatic() async {
+    addTestFile('''
+class A {
+  int F = 0;
+}
+class B extends A {
+  static int F = 1;
+}
+''');
+    await prepareImplementedElements();
+    assertNoImplementedMember('F = 0');
+  }
+
+  test_static_field_staticInstance() async {
+    addTestFile('''
+class A {
+  static int F = 0;
+}
+class B extends A {
+  int F = 1;
+}
+''');
+    await prepareImplementedElements();
+    assertNoImplementedMember('F = 0');
+  }
+
+  test_static_field_staticStatic() async {
+    addTestFile('''
+class A {
+  static int F = 0;
+}
+class B extends A {
+  static int F = 1;
+}
+''');
+    await prepareImplementedElements();
+    assertNoImplementedMember('F = 0');
+  }
+
+  test_static_method_instanceStatic() async {
+    addTestFile('''
+class A {
+  int m() => 0;
+}
+class B extends A {
+  static int m() => 1;
+}
+''');
+    await prepareImplementedElements();
+    assertNoImplementedMember('m() => 0');
+  }
+
+  test_static_method_staticInstance() async {
+    addTestFile('''
+class A {
+  static int m() => 0;
+}
+class B extends A {
+  int m() => 1;
+}
+''');
+    await prepareImplementedElements();
+    assertNoImplementedMember('m() => 0');
+  }
+
+  test_static_method_staticStatic() async {
+    addTestFile('''
+class A {
+  static int m() => 0;
+}
+class B extends A {
+  static int m() => 1;
+}
+''');
+    await prepareImplementedElements();
+    assertNoImplementedMember('m() => 0');
+  }
+
   Future waitForImplementedElements() {
     Future waitForNotification(int times) {
       if (times == 0 || implementedClasses != null) {
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index 68b347c..b1fd5f1 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -44,7 +44,7 @@
     }
     fail(
         'Expected to find target (file=$file; offset=$offset; length=$length) in\n'
-        '${testRegion} in\n'
+        '$testRegion in\n'
         '${testTargets.join('\n')}');
   }
 
@@ -179,11 +179,10 @@
 
 @reflectiveTest
 class AnalysisNotificationNavigationTest extends AbstractNavigationTest {
-  Future prepareNavigation() {
+  Future prepareNavigation() async {
     addAnalysisSubscription(AnalysisService.NAVIGATION, testFile);
-    return waitForTasksFinished().then((_) {
-      assertRegionsSorted();
-    });
+    await waitForTasksFinished();
+    assertRegionsSorted();
   }
 
   void processNotification(Notification notification) {
@@ -203,16 +202,14 @@
     createProject();
   }
 
-  test_afterAnalysis() {
+  test_afterAnalysis() async {
     addTestFile('''
 class AAA {}
 AAA aaa;
 ''');
-    return waitForTasksFinished().then((_) {
-      return prepareNavigation().then((_) {
-        assertHasRegionTarget('AAA aaa;', 'AAA {}');
-      });
-    });
+    await waitForTasksFinished();
+    await prepareNavigation();
+    assertHasRegionTarget('AAA aaa;', 'AAA {}');
   }
 
   test_annotationConstructor_implicit() async {
@@ -322,55 +319,52 @@
     assertHasRegion('myan // ref');
   }
 
-  test_class_fromSDK() {
+  test_class_fromSDK() async {
     addTestFile('''
 int V = 42;
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegion('int V');
-      int targetIndex = testTargetIndexes[0];
-      NavigationTarget target = targets[targetIndex];
-      expect(target.startLine, greaterThan(0));
-      expect(target.startColumn, greaterThan(0));
-    });
+    await prepareNavigation();
+    assertHasRegion('int V');
+    int targetIndex = testTargetIndexes[0];
+    NavigationTarget target = targets[targetIndex];
+    expect(target.startLine, greaterThan(0));
+    expect(target.startColumn, greaterThan(0));
   }
 
-  test_constructor_named() {
+  test_constructor_named() async {
     addTestFile('''
 class A {
   A.named(BBB p) {}
 }
 class BBB {}
 ''');
-    return prepareNavigation().then((_) {
-      // has region for complete "A.named"
-      assertHasRegionString('A.named');
-      assertHasTarget('named(BBB');
-      // no separate regions for "A" and "named"
-      assertNoRegion('A.named(', 'A'.length);
-      assertNoRegion('named(', 'named'.length);
-      // validate that we don't forget to resolve parameters
-      assertHasRegionTarget('BBB p', 'BBB {}');
-    });
+    await prepareNavigation();
+    // has region for complete "A.named"
+    assertHasRegionString('A.named');
+    assertHasTarget('named(BBB');
+    // no separate regions for "A" and "named"
+    assertNoRegion('A.named(', 'A'.length);
+    assertNoRegion('named(', 'named'.length);
+    // validate that we don't forget to resolve parameters
+    assertHasRegionTarget('BBB p', 'BBB {}');
   }
 
-  test_constructor_unnamed() {
+  test_constructor_unnamed() async {
     addTestFile('''
 class A {
   A(BBB p) {}
 }
 class BBB {}
 ''');
-    return prepareNavigation().then((_) {
-      // has region for complete "A.named"
-      assertHasRegion("A(BBB");
-      assertHasTarget("A(BBB", 0);
-      // validate that we don't forget to resolve parameters
-      assertHasRegionTarget('BBB p', 'BBB {}');
-    });
+    await prepareNavigation();
+    // has region for complete "A.named"
+    assertHasRegion("A(BBB");
+    assertHasTarget("A(BBB", 0);
+    // validate that we don't forget to resolve parameters
+    assertHasRegionTarget('BBB p', 'BBB {}');
   }
 
-  test_factoryRedirectingConstructor_implicit() {
+  test_factoryRedirectingConstructor_implicit() async {
     addTestFile('''
 class A {
   factory A() = B;
@@ -378,13 +372,12 @@
 class B {
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegion('B;');
-      assertHasTarget('B {');
-    });
+    await prepareNavigation();
+    assertHasRegion('B;');
+    assertHasTarget('B {');
   }
 
-  test_factoryRedirectingConstructor_implicit_withTypeArgument() {
+  test_factoryRedirectingConstructor_implicit_withTypeArgument() async {
     addTestFile('''
 class A {}
 class B {
@@ -392,19 +385,18 @@
 }
 class C<T> {}
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegion('C<A>');
-        assertHasTarget('C<T> {');
-      }
-      {
-        assertHasRegion('A>;');
-        assertHasTarget('A {');
-      }
-    });
+    await prepareNavigation();
+    {
+      assertHasRegion('C<A>');
+      assertHasTarget('C<T> {');
+    }
+    {
+      assertHasRegion('A>;');
+      assertHasTarget('A {');
+    }
   }
 
-  test_factoryRedirectingConstructor_named() {
+  test_factoryRedirectingConstructor_named() async {
     addTestFile('''
 class A {
   factory A() = B.named;
@@ -413,19 +405,18 @@
   B.named();
 }
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegionString('B.named;', 'B'.length);
-        assertHasTarget('named();');
-      }
-      {
-        assertHasRegionString('named;', 'named'.length);
-        assertHasTarget('named();');
-      }
-    });
+    await prepareNavigation();
+    {
+      assertHasRegionString('B.named;', 'B'.length);
+      assertHasTarget('named();');
+    }
+    {
+      assertHasRegionString('named;', 'named'.length);
+      assertHasTarget('named();');
+    }
   }
 
-  test_factoryRedirectingConstructor_named_withTypeArgument() {
+  test_factoryRedirectingConstructor_named_withTypeArgument() async {
     addTestFile('''
 class A {}
 class B {
@@ -435,23 +426,22 @@
   C.named() {}
 }
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegion('C<A>');
-        assertHasTarget('named() {}');
-      }
-      {
-        assertHasRegion('A>.named');
-        assertHasTarget('A {');
-      }
-      {
-        assertHasRegion('named;', 'named'.length);
-        assertHasTarget('named() {}');
-      }
-    });
+    await prepareNavigation();
+    {
+      assertHasRegion('C<A>');
+      assertHasTarget('named() {}');
+    }
+    {
+      assertHasRegion('A>.named');
+      assertHasTarget('A {');
+    }
+    {
+      assertHasRegion('named;', 'named'.length);
+      assertHasTarget('named() {}');
+    }
   }
 
-  test_factoryRedirectingConstructor_unnamed() {
+  test_factoryRedirectingConstructor_unnamed() async {
     addTestFile('''
 class A {
   factory A() = B;
@@ -460,13 +450,12 @@
   B() {}
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegion('B;');
-      assertHasTarget('B() {}', 0);
-    });
+    await prepareNavigation();
+    assertHasRegion('B;');
+    assertHasTarget('B() {}', 0);
   }
 
-  test_factoryRedirectingConstructor_unnamed_withTypeArgument() {
+  test_factoryRedirectingConstructor_unnamed_withTypeArgument() async {
     addTestFile('''
 class A {}
 class B {
@@ -476,53 +465,49 @@
   C() {}
 }
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegion('C<A>');
-        assertHasTarget('C() {}', 0);
-      }
-      {
-        assertHasRegion('A>;');
-        assertHasTarget('A {');
-      }
-    });
+    await prepareNavigation();
+    {
+      assertHasRegion('C<A>');
+      assertHasTarget('C() {}', 0);
+    }
+    {
+      assertHasRegion('A>;');
+      assertHasTarget('A {');
+    }
   }
 
-  test_factoryRedirectingConstructor_unresolved() {
+  test_factoryRedirectingConstructor_unresolved() async {
     addTestFile('''
 class A {
   factory A() = B;
 }
 ''');
-    return prepareNavigation().then((_) {
-      // don't check regions, but there should be no exceptions
-    });
+    await prepareNavigation();
+    // don't check regions, but there should be no exceptions
   }
 
-  test_fieldFormalParameter() {
+  test_fieldFormalParameter() async {
     addTestFile('''
 class AAA {
   int fff = 123;
   AAA(this.fff);
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegionTarget('fff);', 'fff = 123');
-    });
+    await prepareNavigation();
+    assertHasRegionTarget('fff);', 'fff = 123');
   }
 
-  test_fieldFormalParameter_unresolved() {
+  test_fieldFormalParameter_unresolved() async {
     addTestFile('''
 class AAA {
   AAA(this.fff);
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertNoRegion('fff);', 3);
-    });
+    await prepareNavigation();
+    assertNoRegion('fff);', 3);
   }
 
-  test_identifier_resolved() {
+  test_identifier_resolved() async {
     addTestFile('''
 class AAA {}
 main() {
@@ -530,25 +515,23 @@
   print(aaa);
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegionTarget('AAA aaa', 'AAA {}');
-      assertHasRegionTarget('aaa);', 'aaa = null');
-      assertHasRegionTarget('main() {', 'main() {');
-    });
+    await prepareNavigation();
+    assertHasRegionTarget('AAA aaa', 'AAA {}');
+    assertHasRegionTarget('aaa);', 'aaa = null');
+    assertHasRegionTarget('main() {', 'main() {');
   }
 
-  test_identifier_unresolved() {
+  test_identifier_unresolved() async {
     addTestFile('''
 main() {
   print(vvv);
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertNoRegionString('vvv');
-    });
+    await prepareNavigation();
+    assertNoRegionString('vvv');
   }
 
-  test_identifier_whenStrayImportDirective() {
+  test_identifier_whenStrayImportDirective() async {
     addTestFile('''
 main() {
   int aaa = 42;
@@ -556,9 +539,8 @@
 }
 import 'dart:math';
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegionTarget('aaa);', 'aaa = 42');
-    });
+    await prepareNavigation();
+    assertHasRegionTarget('aaa);', 'aaa = 42');
   }
 
   test_inComment() async {
@@ -578,7 +560,7 @@
     assertHasRegionTarget('FirstClass(', 'FirstClass {');
   }
 
-  test_instanceCreation_implicit() {
+  test_instanceCreation_implicit() async {
     addTestFile('''
 class A {
 }
@@ -586,13 +568,12 @@
   new A();
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegionString('A()', 'A'.length);
-      assertHasTarget('A {');
-    });
+    await prepareNavigation();
+    assertHasRegionString('A()', 'A'.length);
+    assertHasTarget('A {');
   }
 
-  test_instanceCreation_implicit_withTypeArgument() {
+  test_instanceCreation_implicit_withTypeArgument() async {
     addTestFile('''
 class A {}
 class B<T> {}
@@ -600,19 +581,18 @@
   new B<A>();
 }
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegion('B<A>', 'B'.length);
-        assertHasTarget('B<T> {');
-      }
-      {
-        assertHasRegion('A>();', 'A'.length);
-        assertHasTarget('A {');
-      }
-    });
+    await prepareNavigation();
+    {
+      assertHasRegion('B<A>', 'B'.length);
+      assertHasTarget('B<T> {');
+    }
+    {
+      assertHasRegion('A>();', 'A'.length);
+      assertHasTarget('A {');
+    }
   }
 
-  test_instanceCreation_named() {
+  test_instanceCreation_named() async {
     addTestFile('''
 class A {
   A.named() {}
@@ -621,19 +601,18 @@
   new A.named();
 }
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegionString('A.named();', 'A'.length);
-        assertHasTarget('named() {}');
-      }
-      {
-        assertHasRegionString('named();', 'named'.length);
-        assertHasTarget('named() {}');
-      }
-    });
+    await prepareNavigation();
+    {
+      assertHasRegionString('A.named();', 'A'.length);
+      assertHasTarget('named() {}');
+    }
+    {
+      assertHasRegionString('named();', 'named'.length);
+      assertHasTarget('named() {}');
+    }
   }
 
-  test_instanceCreation_named_withTypeArgument() {
+  test_instanceCreation_named_withTypeArgument() async {
     addTestFile('''
 class A {}
 class B<T> {
@@ -643,23 +622,22 @@
   new B<A>.named();
 }
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegionString('B<A>', 'B'.length);
-        assertHasTarget('named() {}');
-      }
-      {
-        assertHasRegion('A>.named');
-        assertHasTarget('A {');
-      }
-      {
-        assertHasRegion('named();', 'named'.length);
-        assertHasTarget('named() {}');
-      }
-    });
+    await prepareNavigation();
+    {
+      assertHasRegionString('B<A>', 'B'.length);
+      assertHasTarget('named() {}');
+    }
+    {
+      assertHasRegion('A>.named');
+      assertHasTarget('A {');
+    }
+    {
+      assertHasRegion('named();', 'named'.length);
+      assertHasTarget('named() {}');
+    }
   }
 
-  test_instanceCreation_unnamed() {
+  test_instanceCreation_unnamed() async {
     addTestFile('''
 class A {
   A() {}
@@ -668,13 +646,12 @@
   new A();
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegionString('A();', 'A'.length);
-      assertHasTarget('A() {}', 0);
-    });
+    await prepareNavigation();
+    assertHasRegionString('A();', 'A'.length);
+    assertHasTarget('A() {}', 0);
   }
 
-  test_instanceCreation_unnamed_withTypeArgument() {
+  test_instanceCreation_unnamed_withTypeArgument() async {
     addTestFile('''
 class A {}
 class B<T> {
@@ -684,29 +661,43 @@
   new B<A>();
 }
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegionString('B<A>();', 'B'.length);
-        assertHasTarget('B() {}', 0);
-      }
-      {
-        assertHasRegion('A>();');
-        assertHasTarget('A {');
-      }
-    });
+    await prepareNavigation();
+    {
+      assertHasRegionString('B<A>();', 'B'.length);
+      assertHasTarget('B() {}', 0);
+    }
+    {
+      assertHasRegion('A>();');
+      assertHasTarget('A {');
+    }
   }
 
-  test_library() {
+  test_instanceCreation_withImportPrefix_named() async {
+    addTestFile('''
+import 'dart:async' as ppp;
+main() {
+  new ppp.Future.value(42);
+}
+''');
+    await prepareNavigation();
+    {
+      assertHasRegion('ppp.');
+      assertHasTarget('ppp;');
+    }
+    assertHasRegion('Future.value');
+    assertHasRegion('value(42)');
+  }
+
+  test_library() async {
     addTestFile('''
 library my.lib;
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegionString('my.lib');
-      assertHasTargetString('my.lib');
-    });
+    await prepareNavigation();
+    assertHasRegionString('my.lib');
+    assertHasTargetString('my.lib');
   }
 
-  test_multiplyDefinedElement() {
+  test_multiplyDefinedElement() async {
     addFile('$projectPath/bin/libA.dart', 'library A; int TEST = 1;');
     addFile('$projectPath/bin/libB.dart', 'library B; int TEST = 2;');
     addTestFile('''
@@ -716,12 +707,11 @@
   TEST;
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertNoRegionAt('TEST');
-    });
+    await prepareNavigation();
+    assertNoRegionAt('TEST');
   }
 
-  test_operator_arithmetic() {
+  test_operator_arithmetic() async {
     addTestFile('''
 class A {
   A operator +(other) => null;
@@ -745,22 +735,21 @@
   a /= 6;
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertHasOperatorRegion('- 1', 1, '-(other) => null', 1);
-      assertHasOperatorRegion('+ 2', 1, '+(other) => null', 1);
-      assertHasOperatorRegion('-a; // unary', 1, '-() => null', 1);
-      assertHasOperatorRegion('--a;', 2, '-(other) => null', 1);
-      assertHasOperatorRegion('++a;', 2, '+(other) => null', 1);
-      assertHasOperatorRegion('--; // mm', 2, '-(other) => null', 1);
-      assertHasOperatorRegion('++; // pp', 2, '+(other) => null', 1);
-      assertHasOperatorRegion('-= 3', 2, '-(other) => null', 1);
-      assertHasOperatorRegion('+= 4', 2, '+(other) => null', 1);
-      assertHasOperatorRegion('*= 5', 2, '*(other) => null', 1);
-      assertHasOperatorRegion('/= 6', 2, '/(other) => null', 1);
-    });
+    await prepareNavigation();
+    assertHasOperatorRegion('- 1', 1, '-(other) => null', 1);
+    assertHasOperatorRegion('+ 2', 1, '+(other) => null', 1);
+    assertHasOperatorRegion('-a; // unary', 1, '-() => null', 1);
+    assertHasOperatorRegion('--a;', 2, '-(other) => null', 1);
+    assertHasOperatorRegion('++a;', 2, '+(other) => null', 1);
+    assertHasOperatorRegion('--; // mm', 2, '-(other) => null', 1);
+    assertHasOperatorRegion('++; // pp', 2, '+(other) => null', 1);
+    assertHasOperatorRegion('-= 3', 2, '-(other) => null', 1);
+    assertHasOperatorRegion('+= 4', 2, '+(other) => null', 1);
+    assertHasOperatorRegion('*= 5', 2, '*(other) => null', 1);
+    assertHasOperatorRegion('/= 6', 2, '/(other) => null', 1);
   }
 
-  test_operator_index() {
+  test_operator_index() async {
     addTestFile('''
 class A {
   A operator +(other) => null;
@@ -776,92 +765,106 @@
   b[2] += 2;
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertHasOperatorRegion('[0', 1, '[](index)', 2);
-      assertHasOperatorRegion('] // []', 1, '[](index)', 2);
-      assertHasOperatorRegion('[1', 1, '[]=(index,', 3);
-      assertHasOperatorRegion('] = 1;', 1, '[]=(index,', 3);
-      assertHasOperatorRegion('[2', 1, '[]=(index,', 3);
-      assertHasOperatorRegion('] += 2;', 1, '[]=(index,', 3);
-      assertHasOperatorRegion('+= 2;', 2, '+(other)', 1);
-    });
+    await prepareNavigation();
+    assertHasOperatorRegion('[0', 1, '[](index)', 2);
+    assertHasOperatorRegion('] // []', 1, '[](index)', 2);
+    assertHasOperatorRegion('[1', 1, '[]=(index,', 3);
+    assertHasOperatorRegion('] = 1;', 1, '[]=(index,', 3);
+    assertHasOperatorRegion('[2', 1, '[]=(index,', 3);
+    assertHasOperatorRegion('] += 2;', 1, '[]=(index,', 3);
+    assertHasOperatorRegion('+= 2;', 2, '+(other)', 1);
   }
 
-  test_partOf() {
+  test_partOf() async {
     var libCode = 'library lib; part "test.dart";';
     var libFile = addFile('$projectPath/bin/lib.dart', libCode);
     addTestFile('part of lib;');
-    return prepareNavigation().then((_) {
-      assertHasRegionString('lib');
-      assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
-    });
+    await prepareNavigation();
+    assertHasRegionString('lib');
+    assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
   }
 
-  test_string_export() {
+  test_redirectingConstructorInvocation() async {
+    addTestFile('''
+class A {
+  A() {}
+  A.foo() : this();
+  A.bar() : this.foo();
+}
+''');
+    await prepareNavigation();
+    {
+      assertHasRegion('this();');
+      assertHasTarget('A() {}', 0);
+    }
+    {
+      assertHasRegion('this.foo');
+      assertHasTarget('foo() :');
+    }
+    {
+      assertHasRegion('foo();');
+      assertHasTarget('foo() :');
+    }
+  }
+
+  test_string_export() async {
     var libCode = 'library lib;';
     var libFile = addFile('$projectPath/bin/lib.dart', libCode);
     addTestFile('export "lib.dart";');
-    return prepareNavigation().then((_) {
-      assertHasRegionString('"lib.dart"');
-      assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
-    });
+    await prepareNavigation();
+    assertHasRegionString('"lib.dart"');
+    assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
   }
 
-  test_string_export_unresolvedUri() {
+  test_string_export_unresolvedUri() async {
     addTestFile('export "no.dart";');
-    return prepareNavigation().then((_) {
-      assertNoRegionString('"no.dart"');
-    });
+    await prepareNavigation();
+    assertNoRegionString('"no.dart"');
   }
 
-  test_string_import() {
+  test_string_import() async {
     var libCode = 'library lib;';
     var libFile = addFile('$projectPath/bin/lib.dart', libCode);
     addTestFile('import "lib.dart";');
-    return prepareNavigation().then((_) {
-      assertHasRegionString('"lib.dart"');
-      assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
-    });
+    await prepareNavigation();
+    assertHasRegionString('"lib.dart"');
+    assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
   }
 
-  test_string_import_noUri() {
+  test_string_import_noUri() async {
     addTestFile('import ;');
-    return prepareNavigation().then((_) {
-      assertNoRegionAt('import ;');
-    });
+    await prepareNavigation();
+    assertNoRegionAt('import ;');
   }
 
-  test_string_import_unresolvedUri() {
+  test_string_import_unresolvedUri() async {
     addTestFile('import "no.dart";');
-    return prepareNavigation().then((_) {
-      assertNoRegionString('"no.dart"');
-    });
+    await prepareNavigation();
+    assertNoRegionString('"no.dart"');
   }
 
-  test_string_part() {
+  test_string_part() async {
     var unitCode = 'part of lib;  f() {}';
     var unitFile = addFile('$projectPath/bin/test_unit.dart', unitCode);
     addTestFile('''
 library lib;
 part "test_unit.dart";
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegionString('"test_unit.dart"');
-      assertHasFileTarget(unitFile, 0, 0);
-    });
+    await prepareNavigation();
+    assertHasRegionString('"test_unit.dart"');
+    assertHasFileTarget(unitFile, 0, 0);
   }
 
-  test_string_part_unresolvedUri() {
+  test_string_part_unresolvedUri() async {
     addTestFile('''
 library lib;
 part "test_unit.dart";
 ''');
-    return prepareNavigation().then((_) {
-      assertNoRegionString('"test_unit.dart"');
-    });
+    await prepareNavigation();
+    assertNoRegionString('"test_unit.dart"');
   }
 
-  test_superConstructorInvocation() {
+  test_superConstructorInvocation() async {
     addTestFile('''
 class A {
   A() {}
@@ -872,19 +875,22 @@
   B.named() : super.named();
 }
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegionString('super');
-        assertHasTarget('A() {}', 0);
-      }
-      {
-        assertHasRegionString('super.named');
-        assertHasTarget('named() {}');
-      }
-    });
+    await prepareNavigation();
+    {
+      assertHasRegionString('super');
+      assertHasTarget('A() {}', 0);
+    }
+    {
+      assertHasRegion('super.named');
+      assertHasTarget('named() {}');
+    }
+    {
+      assertHasRegion('named();');
+      assertHasTarget('named() {}');
+    }
   }
 
-  test_superConstructorInvocation_synthetic() {
+  test_superConstructorInvocation_synthetic() async {
     addTestFile('''
 class A {
 }
@@ -892,45 +898,39 @@
   B() : super();
 }
 ''');
-    return prepareNavigation().then((_) {
-      {
-        assertHasRegionString('super');
-        assertHasTarget('A {');
-      }
-    });
+    await prepareNavigation();
+    assertHasRegionString('super');
+    assertHasTarget('A {');
   }
 
-  test_targetElement() {
+  test_targetElement() async {
     addTestFile('''
 class AAA {}
 main() {
   AAA aaa = null;
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertHasRegionTarget('AAA aaa', 'AAA {}');
-      expect(testTarget.kind, ElementKind.CLASS);
-    });
+    await prepareNavigation();
+    assertHasRegionTarget('AAA aaa', 'AAA {}');
+    expect(testTarget.kind, ElementKind.CLASS);
   }
 
-  test_type_dynamic() {
+  test_type_dynamic() async {
     addTestFile('''
 main() {
   dynamic v = null;
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertNoRegionAt('dynamic');
-    });
+    await prepareNavigation();
+    assertNoRegionAt('dynamic');
   }
 
-  test_type_void() {
+  test_type_void() async {
     addTestFile('''
 void main() {
 }
 ''');
-    return prepareNavigation().then((_) {
-      assertNoRegionAt('void');
-    });
+    await prepareNavigation();
+    assertNoRegionAt('void');
   }
 }
diff --git a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart b/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
index cc7ebab..c27fa10 100644
--- a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
@@ -22,14 +22,14 @@
 @reflectiveTest
 class AnalysisNotificationOccurrencesTest extends AbstractAnalysisTest {
   List<Occurrences> occurrencesList;
-  Occurrences testOccurences;
+  Occurrences testOccurrences;
 
   /**
-   * Asserts that there is an offset of [search] in [testOccurences].
+   * Asserts that there is an offset of [search] in [testOccurrences].
    */
   void assertHasOffset(String search) {
     int offset = findOffset(search);
-    expect(testOccurences.offsets, contains(offset));
+    expect(testOccurrences.offsets, contains(offset));
   }
 
   /**
@@ -49,7 +49,7 @@
    * Finds an [Occurrences] with the given [offset] and [length].
    *
    * If [exists] is `true`, then fails if such [Occurrences] does not exist.
-   * Otherwise remembers this it into [testOccurences].
+   * Otherwise remembers this it into [testOccurrences].
    *
    * If [exists] is `false`, then fails if such [Occurrences] exists.
    */
@@ -64,7 +64,7 @@
             fail('Not expected to find (offset=$offset; length=$length) in\n'
                 '${occurrencesList.join('\n')}');
           }
-          testOccurences = occurrences;
+          testOccurrences = occurrences;
           return;
         }
       }
@@ -95,25 +95,23 @@
     createProject();
   }
 
-  test_afterAnalysis() {
+  test_afterAnalysis() async {
     addTestFile('''
 main() {
   var vvv = 42;
   print(vvv);
 }
 ''');
-    return waitForTasksFinished().then((_) {
-      return prepareOccurrences().then((_) {
-        assertHasRegion('vvv =');
-        expect(testOccurences.element.kind, ElementKind.LOCAL_VARIABLE);
-        expect(testOccurences.element.name, 'vvv');
-        assertHasOffset('vvv = 42');
-        assertHasOffset('vvv);');
-      });
-    });
+    await waitForTasksFinished();
+    await prepareOccurrences();
+    assertHasRegion('vvv =');
+    expect(testOccurrences.element.kind, ElementKind.LOCAL_VARIABLE);
+    expect(testOccurrences.element.name, 'vvv');
+    assertHasOffset('vvv = 42');
+    assertHasOffset('vvv);');
   }
 
-  test_field() {
+  test_field() async {
     addTestFile('''
 class A {
   int fff;
@@ -124,26 +122,25 @@
   }
 }
 ''');
-    return prepareOccurrences().then((_) {
-      assertHasRegion('fff;');
-      expect(testOccurences.element.kind, ElementKind.FIELD);
-      assertHasOffset('fff); // constructor');
-      assertHasOffset('fff = 42;');
-      assertHasOffset('fff); // print');
-    });
+    await prepareOccurrences();
+    assertHasRegion('fff;');
+    expect(testOccurrences.element.kind, ElementKind.FIELD);
+    assertHasOffset('fff); // constructor');
+    assertHasOffset('fff = 42;');
+    assertHasOffset('fff); // print');
   }
 
-  test_field_unresolved() {
+  test_field_unresolved() async {
     addTestFile('''
 class A {
   A(this.noSuchField);
 }
 ''');
     // no checks for occurrences, just ensure that there is no NPE
-    return prepareOccurrences();
+    await prepareOccurrences();
   }
 
-  test_localVariable() {
+  test_localVariable() async {
     addTestFile('''
 main() {
   var vvv = 42;
@@ -151,17 +148,16 @@
   print(vvv);
 }
 ''');
-    return prepareOccurrences().then((_) {
-      assertHasRegion('vvv =');
-      expect(testOccurences.element.kind, ElementKind.LOCAL_VARIABLE);
-      expect(testOccurences.element.name, 'vvv');
-      assertHasOffset('vvv = 42');
-      assertHasOffset('vvv += 5');
-      assertHasOffset('vvv);');
-    });
+    await prepareOccurrences();
+    assertHasRegion('vvv =');
+    expect(testOccurrences.element.kind, ElementKind.LOCAL_VARIABLE);
+    expect(testOccurrences.element.name, 'vvv');
+    assertHasOffset('vvv = 42');
+    assertHasOffset('vvv += 5');
+    assertHasOffset('vvv);');
   }
 
-  test_memberField() {
+  test_memberField() async {
     addTestFile('''
 class A<T> {
   T fff;
@@ -173,15 +169,14 @@
   b.fff = 2;
 }
 ''');
-    return prepareOccurrences().then((_) {
-      assertHasRegion('fff;');
-      expect(testOccurences.element.kind, ElementKind.FIELD);
-      assertHasOffset('fff = 1;');
-      assertHasOffset('fff = 2;');
-    });
+    await prepareOccurrences();
+    assertHasRegion('fff;');
+    expect(testOccurrences.element.kind, ElementKind.FIELD);
+    assertHasOffset('fff = 1;');
+    assertHasOffset('fff = 2;');
   }
 
-  test_memberMethod() {
+  test_memberMethod() async {
     addTestFile('''
 class A<T> {
   T mmm() {}
@@ -193,15 +188,14 @@
   b.mmm(); // b
 }
 ''');
-    return prepareOccurrences().then((_) {
-      assertHasRegion('mmm() {}');
-      expect(testOccurences.element.kind, ElementKind.METHOD);
-      assertHasOffset('mmm(); // a');
-      assertHasOffset('mmm(); // b');
-    });
+    await prepareOccurrences();
+    assertHasRegion('mmm() {}');
+    expect(testOccurrences.element.kind, ElementKind.METHOD);
+    assertHasOffset('mmm(); // a');
+    assertHasOffset('mmm(); // b');
   }
 
-  test_topLevelVariable() {
+  test_topLevelVariable() async {
     addTestFile('''
 var VVV = 1;
 main() {
@@ -209,15 +203,14 @@
   print(VVV);
 }
 ''');
-    return prepareOccurrences().then((_) {
-      assertHasRegion('VVV = 1;');
-      expect(testOccurences.element.kind, ElementKind.TOP_LEVEL_VARIABLE);
-      assertHasOffset('VVV = 2;');
-      assertHasOffset('VVV);');
-    });
+    await prepareOccurrences();
+    assertHasRegion('VVV = 1;');
+    expect(testOccurrences.element.kind, ElementKind.TOP_LEVEL_VARIABLE);
+    assertHasOffset('VVV = 2;');
+    assertHasOffset('VVV);');
   }
 
-  test_type_class() {
+  test_type_class() async {
     addTestFile('''
 main() {
   int a = 1;
@@ -226,18 +219,17 @@
 }
 int VVV = 4;
 ''');
-    return prepareOccurrences().then((_) {
-      assertHasRegion('int a');
-      expect(testOccurences.element.kind, ElementKind.CLASS);
-      expect(testOccurences.element.name, 'int');
-      assertHasOffset('int a');
-      assertHasOffset('int b');
-      assertHasOffset('int c');
-      assertHasOffset('int VVV');
-    });
+    await prepareOccurrences();
+    assertHasRegion('int a');
+    expect(testOccurrences.element.kind, ElementKind.CLASS);
+    expect(testOccurrences.element.name, 'int');
+    assertHasOffset('int a');
+    assertHasOffset('int b');
+    assertHasOffset('int c');
+    assertHasOffset('int VVV');
   }
 
-  test_type_dynamic() {
+  test_type_dynamic() async {
     addTestFile('''
 main() {
   dynamic a = 1;
@@ -245,20 +237,18 @@
 }
 dynamic V = 3;
 ''');
-    return prepareOccurrences().then((_) {
-      int offset = findOffset('dynamic a');
-      findRegion(offset, 'dynamic'.length, false);
-    });
+    await prepareOccurrences();
+    int offset = findOffset('dynamic a');
+    findRegion(offset, 'dynamic'.length, false);
   }
 
-  test_type_void() {
+  test_type_void() async {
     addTestFile('''
 void main() {
 }
 ''');
-    return prepareOccurrences().then((_) {
-      int offset = findOffset('void main()');
-      findRegion(offset, 'void'.length, false);
-    });
+    await prepareOccurrences();
+    int offset = findOffset('void main()');
+    findRegion(offset, 'void'.length, false);
   }
 }
diff --git a/pkg/analysis_server/test/analysis/notification_outline_test.dart b/pkg/analysis_server/test/analysis/notification_outline_test.dart
index 679baae..1230dbc 100644
--- a/pkg/analysis_server/test/analysis/notification_outline_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_outline_test.dart
@@ -47,24 +47,22 @@
     createProject();
   }
 
-  test_afterAnalysis() {
+  test_afterAnalysis() async {
     addTestFile('''
 class AAA {
 }
 class BBB {
 }
 ''');
-    return waitForTasksFinished().then((_) {
-      expect(outline, isNull);
-      return prepareOutline().then((_) {
-        Outline unitOutline = outline;
-        List<Outline> outlines = unitOutline.children;
-        expect(outlines, hasLength(2));
-      });
-    });
+    await waitForTasksFinished();
+    expect(outline, isNull);
+    await prepareOutline();
+    Outline unitOutline = outline;
+    List<Outline> outlines = unitOutline.children;
+    expect(outlines, hasLength(2));
   }
 
-  test_class() {
+  test_class() async {
     addTestFile('''
 class A<K, V> {
   int fa, fb;
@@ -81,218 +79,216 @@
   B(int p);
 }");
 ''');
-    return prepareOutline().then((_) {
-      Outline unitOutline = outline;
-      List<Outline> topOutlines = unitOutline.children;
-      expect(topOutlines, hasLength(2));
-      // A
+    await prepareOutline();
+    Outline unitOutline = outline;
+    List<Outline> topOutlines = unitOutline.children;
+    expect(topOutlines, hasLength(2));
+    // A
+    {
+      Outline outline_A = topOutlines[0];
+      Element element_A = outline_A.element;
+      expect(element_A.kind, ElementKind.CLASS);
+      expect(element_A.name, "A");
+      expect(element_A.typeParameters, "<K, V>");
       {
-        Outline outline_A = topOutlines[0];
-        Element element_A = outline_A.element;
-        expect(element_A.kind, ElementKind.CLASS);
-        expect(element_A.name, "A");
-        expect(element_A.typeParameters, "<K, V>");
-        {
-          Location location = element_A.location;
-          expect(location.offset, testCode.indexOf("A<K, V> {"));
-          expect(location.length, 1);
-        }
-        expect(element_A.parameters, null);
-        expect(element_A.returnType, null);
-        // A children
-        List<Outline> outlines_A = outline_A.children;
-        expect(outlines_A, hasLength(10));
-        {
-          Outline outline = outlines_A[0];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.FIELD);
-          expect(element.name, "fa");
-          expect(element.parameters, isNull);
-          expect(element.returnType, "int");
-        }
-        {
-          Outline outline = outlines_A[1];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.FIELD);
-          expect(element.name, "fb");
-          expect(element.parameters, isNull);
-          expect(element.returnType, "int");
-        }
-        {
-          Outline outline = outlines_A[2];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.FIELD);
-          expect(element.name, "fc");
-          expect(element.parameters, isNull);
-          expect(element.returnType, "String");
-        }
-        {
-          Outline outline = outlines_A[3];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.CONSTRUCTOR);
-          expect(element.name, "A");
-          {
-            Location location = element.location;
-            expect(location.offset, testCode.indexOf("A(int i, String s);"));
-            expect(location.length, "A".length);
-          }
-          expect(element.parameters, "(int i, String s)");
-          expect(element.returnType, isNull);
-          expect(element.isAbstract, isFalse);
-          expect(element.isStatic, isFalse);
-        }
-        {
-          Outline outline = outlines_A[4];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.CONSTRUCTOR);
-          expect(element.name, "A.name");
-          {
-            Location location = element.location;
-            expect(location.offset, testCode.indexOf("name(num p);"));
-            expect(location.length, "name".length);
-          }
-          expect(element.parameters, "(num p)");
-          expect(element.returnType, isNull);
-          expect(element.isAbstract, isFalse);
-          expect(element.isStatic, isFalse);
-        }
-        {
-          Outline outline = outlines_A[5];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.CONSTRUCTOR);
-          expect(element.name, "A._privateName");
-          {
-            Location location = element.location;
-            expect(location.offset, testCode.indexOf("_privateName(num p);"));
-            expect(location.length, "_privateName".length);
-          }
-          expect(element.parameters, "(num p)");
-          expect(element.returnType, isNull);
-          expect(element.isAbstract, isFalse);
-          expect(element.isStatic, isFalse);
-        }
-        {
-          Outline outline = outlines_A[6];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.METHOD);
-          expect(element.name, "ma");
-          {
-            Location location = element.location;
-            expect(location.offset, testCode.indexOf("ma(int pa) => null;"));
-            expect(location.length, "ma".length);
-          }
-          expect(element.parameters, "(int pa)");
-          expect(element.returnType, "String");
-          expect(element.isAbstract, isFalse);
-          expect(element.isStatic, isTrue);
-        }
-        {
-          Outline outline = outlines_A[7];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.METHOD);
-          expect(element.name, "_mb");
-          {
-            Location location = element.location;
-            expect(location.offset, testCode.indexOf("_mb(int pb);"));
-            expect(location.length, "_mb".length);
-          }
-          expect(element.parameters, "(int pb)");
-          expect(element.returnType, "");
-          expect(element.isAbstract, isTrue);
-          expect(element.isStatic, isFalse);
-        }
-        {
-          Outline outline = outlines_A[8];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.GETTER);
-          expect(element.name, "propA");
-          {
-            Location location = element.location;
-            expect(location.offset, testCode.indexOf("propA => null;"));
-            expect(location.length, "propA".length);
-          }
-          expect(element.parameters, isNull);
-          expect(element.returnType, "String");
-        }
-        {
-          Outline outline = outlines_A[9];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.SETTER);
-          expect(element.name, "propB");
-          {
-            Location location = element.location;
-            expect(location.offset, testCode.indexOf("propB(int v) {}"));
-            expect(location.length, "propB".length);
-          }
-          expect(element.parameters, "(int v)");
-          expect(element.returnType, "");
-        }
+        Location location = element_A.location;
+        expect(location.offset, testCode.indexOf("A<K, V> {"));
+        expect(location.length, 1);
       }
-      // B
+      expect(element_A.parameters, null);
+      expect(element_A.returnType, null);
+      // A children
+      List<Outline> outlines_A = outline_A.children;
+      expect(outlines_A, hasLength(10));
       {
-        Outline outline_B = topOutlines[1];
-        Element element_B = outline_B.element;
-        expect(element_B.kind, ElementKind.CLASS);
-        expect(element_B.name, "B");
-        expect(element_B.typeParameters, isNull);
-        {
-          Location location = element_B.location;
-          expect(location.offset, testCode.indexOf("B {"));
-          expect(location.length, 1);
-        }
-        expect(element_B.parameters, null);
-        expect(element_B.returnType, null);
-        // B children
-        List<Outline> outlines_B = outline_B.children;
-        expect(outlines_B, hasLength(1));
-        {
-          Outline outline = outlines_B[0];
-          Element element = outline.element;
-          expect(element.kind, ElementKind.CONSTRUCTOR);
-          expect(element.name, "B");
-          {
-            Location location = element.location;
-            expect(location.offset, testCode.indexOf("B(int p);"));
-            expect(location.length, "B".length);
-          }
-          expect(element.parameters, "(int p)");
-          expect(element.returnType, isNull);
-        }
+        Outline outline = outlines_A[0];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.FIELD);
+        expect(element.name, "fa");
+        expect(element.parameters, isNull);
+        expect(element.returnType, "int");
       }
-    });
+      {
+        Outline outline = outlines_A[1];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.FIELD);
+        expect(element.name, "fb");
+        expect(element.parameters, isNull);
+        expect(element.returnType, "int");
+      }
+      {
+        Outline outline = outlines_A[2];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.FIELD);
+        expect(element.name, "fc");
+        expect(element.parameters, isNull);
+        expect(element.returnType, "String");
+      }
+      {
+        Outline outline = outlines_A[3];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.CONSTRUCTOR);
+        expect(element.name, "A");
+        {
+          Location location = element.location;
+          expect(location.offset, testCode.indexOf("A(int i, String s);"));
+          expect(location.length, "A".length);
+        }
+        expect(element.parameters, "(int i, String s)");
+        expect(element.returnType, isNull);
+        expect(element.isAbstract, isFalse);
+        expect(element.isStatic, isFalse);
+      }
+      {
+        Outline outline = outlines_A[4];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.CONSTRUCTOR);
+        expect(element.name, "A.name");
+        {
+          Location location = element.location;
+          expect(location.offset, testCode.indexOf("name(num p);"));
+          expect(location.length, "name".length);
+        }
+        expect(element.parameters, "(num p)");
+        expect(element.returnType, isNull);
+        expect(element.isAbstract, isFalse);
+        expect(element.isStatic, isFalse);
+      }
+      {
+        Outline outline = outlines_A[5];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.CONSTRUCTOR);
+        expect(element.name, "A._privateName");
+        {
+          Location location = element.location;
+          expect(location.offset, testCode.indexOf("_privateName(num p);"));
+          expect(location.length, "_privateName".length);
+        }
+        expect(element.parameters, "(num p)");
+        expect(element.returnType, isNull);
+        expect(element.isAbstract, isFalse);
+        expect(element.isStatic, isFalse);
+      }
+      {
+        Outline outline = outlines_A[6];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.METHOD);
+        expect(element.name, "ma");
+        {
+          Location location = element.location;
+          expect(location.offset, testCode.indexOf("ma(int pa) => null;"));
+          expect(location.length, "ma".length);
+        }
+        expect(element.parameters, "(int pa)");
+        expect(element.returnType, "String");
+        expect(element.isAbstract, isFalse);
+        expect(element.isStatic, isTrue);
+      }
+      {
+        Outline outline = outlines_A[7];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.METHOD);
+        expect(element.name, "_mb");
+        {
+          Location location = element.location;
+          expect(location.offset, testCode.indexOf("_mb(int pb);"));
+          expect(location.length, "_mb".length);
+        }
+        expect(element.parameters, "(int pb)");
+        expect(element.returnType, "");
+        expect(element.isAbstract, isTrue);
+        expect(element.isStatic, isFalse);
+      }
+      {
+        Outline outline = outlines_A[8];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.GETTER);
+        expect(element.name, "propA");
+        {
+          Location location = element.location;
+          expect(location.offset, testCode.indexOf("propA => null;"));
+          expect(location.length, "propA".length);
+        }
+        expect(element.parameters, isNull);
+        expect(element.returnType, "String");
+      }
+      {
+        Outline outline = outlines_A[9];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.SETTER);
+        expect(element.name, "propB");
+        {
+          Location location = element.location;
+          expect(location.offset, testCode.indexOf("propB(int v) {}"));
+          expect(location.length, "propB".length);
+        }
+        expect(element.parameters, "(int v)");
+        expect(element.returnType, "");
+      }
+    }
+    // B
+    {
+      Outline outline_B = topOutlines[1];
+      Element element_B = outline_B.element;
+      expect(element_B.kind, ElementKind.CLASS);
+      expect(element_B.name, "B");
+      expect(element_B.typeParameters, isNull);
+      {
+        Location location = element_B.location;
+        expect(location.offset, testCode.indexOf("B {"));
+        expect(location.length, 1);
+      }
+      expect(element_B.parameters, null);
+      expect(element_B.returnType, null);
+      // B children
+      List<Outline> outlines_B = outline_B.children;
+      expect(outlines_B, hasLength(1));
+      {
+        Outline outline = outlines_B[0];
+        Element element = outline.element;
+        expect(element.kind, ElementKind.CONSTRUCTOR);
+        expect(element.name, "B");
+        {
+          Location location = element.location;
+          expect(location.offset, testCode.indexOf("B(int p);"));
+          expect(location.length, "B".length);
+        }
+        expect(element.parameters, "(int p)");
+        expect(element.returnType, isNull);
+      }
+    }
   }
 
-  test_enum() {
+  test_enum() async {
     addTestFile('''
 enum MyEnum {
   A, B, C
 }
 ''');
-    return prepareOutline().then((_) {
-      Outline unitOutline = outline;
-      List<Outline> topOutlines = unitOutline.children;
-      expect(topOutlines, hasLength(1));
-      // MyEnum
+    await prepareOutline();
+    Outline unitOutline = outline;
+    List<Outline> topOutlines = unitOutline.children;
+    expect(topOutlines, hasLength(1));
+    // MyEnum
+    {
+      Outline outline_MyEnum = topOutlines[0];
+      Element element_MyEnum = outline_MyEnum.element;
+      expect(element_MyEnum.kind, ElementKind.ENUM);
+      expect(element_MyEnum.name, "MyEnum");
       {
-        Outline outline_MyEnum = topOutlines[0];
-        Element element_MyEnum = outline_MyEnum.element;
-        expect(element_MyEnum.kind, ElementKind.ENUM);
-        expect(element_MyEnum.name, "MyEnum");
-        {
-          Location location = element_MyEnum.location;
-          expect(location.offset, testCode.indexOf("MyEnum {"));
-          expect(location.length, 'MyEnum'.length);
-        }
-        expect(element_MyEnum.parameters, null);
-        expect(element_MyEnum.returnType, null);
-        // MyEnum children
-        List<Outline> outlines_MyEnum = outline_MyEnum.children;
-        expect(outlines_MyEnum, hasLength(3));
-        _isEnumConstant(outlines_MyEnum[0], 'A');
-        _isEnumConstant(outlines_MyEnum[1], 'B');
-        _isEnumConstant(outlines_MyEnum[2], 'C');
+        Location location = element_MyEnum.location;
+        expect(location.offset, testCode.indexOf("MyEnum {"));
+        expect(location.length, 'MyEnum'.length);
       }
-    });
+      expect(element_MyEnum.parameters, null);
+      expect(element_MyEnum.returnType, null);
+      // MyEnum children
+      List<Outline> outlines_MyEnum = outline_MyEnum.children;
+      expect(outlines_MyEnum, hasLength(3));
+      _isEnumConstant(outlines_MyEnum[0], 'A');
+      _isEnumConstant(outlines_MyEnum[1], 'B');
+      _isEnumConstant(outlines_MyEnum[2], 'C');
+    }
   }
 
   /**
@@ -300,7 +296,7 @@
    *
    * https://code.google.com/p/dart/issues/detail?id=21373
    */
-  test_invalidGetterInConstructor() {
+  test_invalidGetterInConstructor() async {
     addTestFile('''
 class A {
   A() {
@@ -310,9 +306,8 @@
   }
 }
 ''');
-    return prepareOutline().then((_) {
-      expect(outline, isNotNull);
-    });
+    await prepareOutline();
+    expect(outline, isNotNull);
   }
 
   test_libraryName_hasLibraryDirective() async {
@@ -352,7 +347,7 @@
     expect(libraryName, isNull);
   }
 
-  test_localFunctions() {
+  test_localFunctions() async {
     addTestFile('''
 class A {
   A() {
@@ -369,254 +364,251 @@
   }
 }
 ''');
-    return prepareOutline().then((_) {
-      Outline unitOutline = outline;
-      List<Outline> topOutlines = unitOutline.children;
-      expect(topOutlines, hasLength(2));
-      // A
+    await prepareOutline();
+    Outline unitOutline = outline;
+    List<Outline> topOutlines = unitOutline.children;
+    expect(topOutlines, hasLength(2));
+    // A
+    {
+      Outline outline_A = topOutlines[0];
+      Element element_A = outline_A.element;
+      expect(element_A.kind, ElementKind.CLASS);
+      expect(element_A.name, "A");
       {
-        Outline outline_A = topOutlines[0];
-        Element element_A = outline_A.element;
-        expect(element_A.kind, ElementKind.CLASS);
-        expect(element_A.name, "A");
+        Location location = element_A.location;
+        expect(location.offset, testCode.indexOf("A {"));
+        expect(location.length, "A".length);
+      }
+      expect(element_A.parameters, null);
+      expect(element_A.returnType, null);
+      // A children
+      List<Outline> outlines_A = outline_A.children;
+      expect(outlines_A, hasLength(2));
+      {
+        Outline constructorOutline = outlines_A[0];
+        Element constructorElement = constructorOutline.element;
+        expect(constructorElement.kind, ElementKind.CONSTRUCTOR);
+        expect(constructorElement.name, "A");
         {
-          Location location = element_A.location;
-          expect(location.offset, testCode.indexOf("A {"));
+          Location location = constructorElement.location;
+          expect(location.offset, testCode.indexOf("A() {"));
           expect(location.length, "A".length);
         }
-        expect(element_A.parameters, null);
-        expect(element_A.returnType, null);
-        // A children
-        List<Outline> outlines_A = outline_A.children;
-        expect(outlines_A, hasLength(2));
+        expect(constructorElement.parameters, "()");
+        expect(constructorElement.returnType, isNull);
+        // local function
+        List<Outline> outlines_constructor = constructorOutline.children;
+        expect(outlines_constructor, hasLength(1));
         {
-          Outline constructorOutline = outlines_A[0];
-          Element constructorElement = constructorOutline.element;
-          expect(constructorElement.kind, ElementKind.CONSTRUCTOR);
-          expect(constructorElement.name, "A");
+          Outline outline = outlines_constructor[0];
+          Element element = outline.element;
+          expect(element.kind, ElementKind.FUNCTION);
+          expect(element.name, "local_A");
           {
-            Location location = constructorElement.location;
-            expect(location.offset, testCode.indexOf("A() {"));
-            expect(location.length, "A".length);
+            Location location = element.location;
+            expect(location.offset, testCode.indexOf("local_A() {}"));
+            expect(location.length, "local_A".length);
           }
-          expect(constructorElement.parameters, "()");
-          expect(constructorElement.returnType, isNull);
-          // local function
-          List<Outline> outlines_constructor = constructorOutline.children;
-          expect(outlines_constructor, hasLength(1));
-          {
-            Outline outline = outlines_constructor[0];
-            Element element = outline.element;
-            expect(element.kind, ElementKind.FUNCTION);
-            expect(element.name, "local_A");
-            {
-              Location location = element.location;
-              expect(location.offset, testCode.indexOf("local_A() {}"));
-              expect(location.length, "local_A".length);
-            }
-            expect(element.parameters, "()");
-            expect(element.returnType, "int");
-          }
-        }
-        {
-          Outline outline_m = outlines_A[1];
-          Element element_m = outline_m.element;
-          expect(element_m.kind, ElementKind.METHOD);
-          expect(element_m.name, "m");
-          {
-            Location location = element_m.location;
-            expect(location.offset, testCode.indexOf("m() {"));
-            expect(location.length, "m".length);
-          }
-          expect(element_m.parameters, "()");
-          expect(element_m.returnType, "");
-          // local function
-          List<Outline> methodChildren = outline_m.children;
-          expect(methodChildren, hasLength(1));
-          {
-            Outline outline = methodChildren[0];
-            Element element = outline.element;
-            expect(element.kind, ElementKind.FUNCTION);
-            expect(element.name, "local_m");
-            {
-              Location location = element.location;
-              expect(location.offset, testCode.indexOf("local_m() {}"));
-              expect(location.length, "local_m".length);
-            }
-            expect(element.parameters, "()");
-            expect(element.returnType, "");
-          }
+          expect(element.parameters, "()");
+          expect(element.returnType, "int");
         }
       }
-      // f()
       {
-        Outline outline_f = topOutlines[1];
-        Element element_f = outline_f.element;
-        expect(element_f.kind, ElementKind.FUNCTION);
-        expect(element_f.name, "f");
+        Outline outline_m = outlines_A[1];
+        Element element_m = outline_m.element;
+        expect(element_m.kind, ElementKind.METHOD);
+        expect(element_m.name, "m");
         {
-          Location location = element_f.location;
-          expect(location.offset, testCode.indexOf("f() {"));
-          expect(location.length, "f".length);
+          Location location = element_m.location;
+          expect(location.offset, testCode.indexOf("m() {"));
+          expect(location.length, "m".length);
         }
-        expect(element_f.parameters, "()");
-        expect(element_f.returnType, "");
-        // f() children
-        List<Outline> outlines_f = outline_f.children;
-        expect(outlines_f, hasLength(2));
+        expect(element_m.parameters, "()");
+        expect(element_m.returnType, "");
+        // local function
+        List<Outline> methodChildren = outline_m.children;
+        expect(methodChildren, hasLength(1));
         {
-          Outline outline_f1 = outlines_f[0];
-          Element element_f1 = outline_f1.element;
-          expect(element_f1.kind, ElementKind.FUNCTION);
-          expect(element_f1.name, "local_f1");
+          Outline outline = methodChildren[0];
+          Element element = outline.element;
+          expect(element.kind, ElementKind.FUNCTION);
+          expect(element.name, "local_m");
           {
-            Location location = element_f1.location;
-            expect(location.offset, testCode.indexOf("local_f1(int i) {}"));
-            expect(location.length, "local_f1".length);
+            Location location = element.location;
+            expect(location.offset, testCode.indexOf("local_m() {}"));
+            expect(location.length, "local_m".length);
           }
-          expect(element_f1.parameters, "(int i)");
-          expect(element_f1.returnType, "");
-        }
-        {
-          Outline outline_f2 = outlines_f[1];
-          Element element_f2 = outline_f2.element;
-          expect(element_f2.kind, ElementKind.FUNCTION);
-          expect(element_f2.name, "local_f2");
-          {
-            Location location = element_f2.location;
-            expect(location.offset, testCode.indexOf("local_f2(String s) {"));
-            expect(location.length, "local_f2".length);
-          }
-          expect(element_f2.parameters, "(String s)");
-          expect(element_f2.returnType, "");
-          // local_f2() local function
-          List<Outline> outlines_f2 = outline_f2.children;
-          expect(outlines_f2, hasLength(1));
-          {
-            Outline outline_f21 = outlines_f2[0];
-            Element element_f21 = outline_f21.element;
-            expect(element_f21.kind, ElementKind.FUNCTION);
-            expect(element_f21.name, "local_f21");
-            {
-              Location location = element_f21.location;
-              expect(location.offset, testCode.indexOf("local_f21(int p) {"));
-              expect(location.length, "local_f21".length);
-            }
-            expect(element_f21.parameters, "(int p)");
-            expect(element_f21.returnType, "");
-          }
+          expect(element.parameters, "()");
+          expect(element.returnType, "");
         }
       }
-    });
+    }
+    // f()
+    {
+      Outline outline_f = topOutlines[1];
+      Element element_f = outline_f.element;
+      expect(element_f.kind, ElementKind.FUNCTION);
+      expect(element_f.name, "f");
+      {
+        Location location = element_f.location;
+        expect(location.offset, testCode.indexOf("f() {"));
+        expect(location.length, "f".length);
+      }
+      expect(element_f.parameters, "()");
+      expect(element_f.returnType, "");
+      // f() children
+      List<Outline> outlines_f = outline_f.children;
+      expect(outlines_f, hasLength(2));
+      {
+        Outline outline_f1 = outlines_f[0];
+        Element element_f1 = outline_f1.element;
+        expect(element_f1.kind, ElementKind.FUNCTION);
+        expect(element_f1.name, "local_f1");
+        {
+          Location location = element_f1.location;
+          expect(location.offset, testCode.indexOf("local_f1(int i) {}"));
+          expect(location.length, "local_f1".length);
+        }
+        expect(element_f1.parameters, "(int i)");
+        expect(element_f1.returnType, "");
+      }
+      {
+        Outline outline_f2 = outlines_f[1];
+        Element element_f2 = outline_f2.element;
+        expect(element_f2.kind, ElementKind.FUNCTION);
+        expect(element_f2.name, "local_f2");
+        {
+          Location location = element_f2.location;
+          expect(location.offset, testCode.indexOf("local_f2(String s) {"));
+          expect(location.length, "local_f2".length);
+        }
+        expect(element_f2.parameters, "(String s)");
+        expect(element_f2.returnType, "");
+        // local_f2() local function
+        List<Outline> outlines_f2 = outline_f2.children;
+        expect(outlines_f2, hasLength(1));
+        {
+          Outline outline_f21 = outlines_f2[0];
+          Element element_f21 = outline_f21.element;
+          expect(element_f21.kind, ElementKind.FUNCTION);
+          expect(element_f21.name, "local_f21");
+          {
+            Location location = element_f21.location;
+            expect(location.offset, testCode.indexOf("local_f21(int p) {"));
+            expect(location.length, "local_f21".length);
+          }
+          expect(element_f21.parameters, "(int p)");
+          expect(element_f21.returnType, "");
+        }
+      }
+    }
   }
 
-  test_sourceRange_inClass() {
+  test_sourceRange_inClass() async {
     addTestFile('''
 class A { // leftA
   int methodA() {} // endA
   int methodB() {} // endB
 }
 ''');
-    return prepareOutline().then((_) {
-      Outline unitOutline = outline;
-      List<Outline> outlines = unitOutline.children[0].children;
-      expect(outlines, hasLength(2));
-      // methodA
+    await prepareOutline();
+    Outline unitOutline = outline;
+    List<Outline> outlines = unitOutline.children[0].children;
+    expect(outlines, hasLength(2));
+    // methodA
+    {
+      Outline outline = outlines[0];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.METHOD);
+      expect(element.name, "methodA");
       {
-        Outline outline = outlines[0];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.METHOD);
-        expect(element.name, "methodA");
-        {
-          int offset = testCode.indexOf(" // leftA");
-          int end = testCode.indexOf(" // endA");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(" // leftA");
+        int end = testCode.indexOf(" // endA");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-      // methodB
+    }
+    // methodB
+    {
+      Outline outline = outlines[1];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.METHOD);
+      expect(element.name, "methodB");
       {
-        Outline outline = outlines[1];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.METHOD);
-        expect(element.name, "methodB");
-        {
-          int offset = testCode.indexOf(" // endA");
-          int end = testCode.indexOf(" // endB");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(" // endA");
+        int end = testCode.indexOf(" // endB");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-    });
+    }
   }
 
-  test_sourceRange_inClass_inVariableList() {
+  test_sourceRange_inClass_inVariableList() async {
     addTestFile('''
 class A { // leftA
   int fieldA, fieldB, fieldC; // marker
   int fieldD; // marker2
 }
 ''');
-    return prepareOutline().then((_) {
-      Outline unitOutline = outline;
-      List<Outline> outlines = unitOutline.children[0].children;
-      expect(outlines, hasLength(4));
-      // fieldA
+    await prepareOutline();
+    Outline unitOutline = outline;
+    List<Outline> outlines = unitOutline.children[0].children;
+    expect(outlines, hasLength(4));
+    // fieldA
+    {
+      Outline outline = outlines[0];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.FIELD);
+      expect(element.name, "fieldA");
       {
-        Outline outline = outlines[0];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.FIELD);
-        expect(element.name, "fieldA");
-        {
-          int offset = testCode.indexOf(" // leftA");
-          int end = testCode.indexOf(", fieldB");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(" // leftA");
+        int end = testCode.indexOf(", fieldB");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-      // fieldB
+    }
+    // fieldB
+    {
+      Outline outline = outlines[1];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.FIELD);
+      expect(element.name, "fieldB");
       {
-        Outline outline = outlines[1];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.FIELD);
-        expect(element.name, "fieldB");
-        {
-          int offset = testCode.indexOf(", fieldB");
-          int end = testCode.indexOf(", fieldC");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(", fieldB");
+        int end = testCode.indexOf(", fieldC");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-      // fieldC
+    }
+    // fieldC
+    {
+      Outline outline = outlines[2];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.FIELD);
+      expect(element.name, "fieldC");
       {
-        Outline outline = outlines[2];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.FIELD);
-        expect(element.name, "fieldC");
-        {
-          int offset = testCode.indexOf(", fieldC");
-          int end = testCode.indexOf(" // marker");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(", fieldC");
+        int end = testCode.indexOf(" // marker");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-      // fieldD
+    }
+    // fieldD
+    {
+      Outline outline = outlines[3];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.FIELD);
+      expect(element.name, "fieldD");
       {
-        Outline outline = outlines[3];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.FIELD);
-        expect(element.name, "fieldD");
-        {
-          int offset = testCode.indexOf(" // marker");
-          int end = testCode.indexOf(" // marker2");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(" // marker");
+        int end = testCode.indexOf(" // marker2");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-    });
+    }
   }
 
-  test_sourceRange_inUnit() {
+  test_sourceRange_inUnit() async {
     addTestFile('''
 library lib;
 /// My first class.
@@ -625,104 +617,102 @@
 class B {
 } // endB
 ''');
-    return prepareOutline().then((_) {
-      Outline unitOutline = outline;
-      List<Outline> topOutlines = unitOutline.children;
-      expect(topOutlines, hasLength(2));
-      // A
+    await prepareOutline();
+    Outline unitOutline = outline;
+    List<Outline> topOutlines = unitOutline.children;
+    expect(topOutlines, hasLength(2));
+    // A
+    {
+      Outline outline = topOutlines[0];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.CLASS);
+      expect(element.name, "A");
       {
-        Outline outline = topOutlines[0];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.CLASS);
-        expect(element.name, "A");
-        {
-          int offset = testCode.indexOf("/// My first class.");
-          int end = testCode.indexOf(" // endA");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf("/// My first class.");
+        int end = testCode.indexOf(" // endA");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-      // B
+    }
+    // B
+    {
+      Outline outline = topOutlines[1];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.CLASS);
+      expect(element.name, "B");
       {
-        Outline outline = topOutlines[1];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.CLASS);
-        expect(element.name, "B");
-        {
-          int offset = testCode.indexOf(" // endA");
-          int end = testCode.indexOf(" // endB");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(" // endA");
+        int end = testCode.indexOf(" // endB");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-    });
+    }
   }
 
-  test_sourceRange_inUnit_inVariableList() {
+  test_sourceRange_inUnit_inVariableList() async {
     addTestFile('''
 int fieldA, fieldB, fieldC; // marker
 int fieldD; // marker2
 ''');
-    return prepareOutline().then((_) {
-      Outline unitOutline = outline;
-      List<Outline> outlines = unitOutline.children;
-      expect(outlines, hasLength(4));
-      // fieldA
+    await prepareOutline();
+    Outline unitOutline = outline;
+    List<Outline> outlines = unitOutline.children;
+    expect(outlines, hasLength(4));
+    // fieldA
+    {
+      Outline outline = outlines[0];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE);
+      expect(element.name, "fieldA");
       {
-        Outline outline = outlines[0];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE);
-        expect(element.name, "fieldA");
-        {
-          int offset = 0;
-          int end = testCode.indexOf(", fieldB");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = 0;
+        int end = testCode.indexOf(", fieldB");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-      // fieldB
+    }
+    // fieldB
+    {
+      Outline outline = outlines[1];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE);
+      expect(element.name, "fieldB");
       {
-        Outline outline = outlines[1];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE);
-        expect(element.name, "fieldB");
-        {
-          int offset = testCode.indexOf(", fieldB");
-          int end = testCode.indexOf(", fieldC");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(", fieldB");
+        int end = testCode.indexOf(", fieldC");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-      // fieldC
+    }
+    // fieldC
+    {
+      Outline outline = outlines[2];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE);
+      expect(element.name, "fieldC");
       {
-        Outline outline = outlines[2];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE);
-        expect(element.name, "fieldC");
-        {
-          int offset = testCode.indexOf(", fieldC");
-          int end = testCode.indexOf(" // marker");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(", fieldC");
+        int end = testCode.indexOf(" // marker");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-      // fieldD
+    }
+    // fieldD
+    {
+      Outline outline = outlines[3];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE);
+      expect(element.name, "fieldD");
       {
-        Outline outline = outlines[3];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE);
-        expect(element.name, "fieldD");
-        {
-          int offset = testCode.indexOf(" // marker");
-          int end = testCode.indexOf(" // marker2");
-          expect(outline.offset, offset);
-          expect(outline.length, end - offset);
-        }
+        int offset = testCode.indexOf(" // marker");
+        int end = testCode.indexOf(" // marker2");
+        expect(outline.offset, offset);
+        expect(outline.length, end - offset);
       }
-    });
+    }
   }
 
-  test_topLevel() {
+  test_topLevel() async {
     addTestFile('''
 typedef String FTA<K, V>(int i, String s);
 typedef FTB(int p);
@@ -735,121 +725,120 @@
 String get propA => null;
 set propB(int v) {}
 ''');
-    return prepareOutline().then((_) {
-      Outline unitOutline = outline;
-      List<Outline> topOutlines = unitOutline.children;
-      expect(topOutlines, hasLength(10));
-      // FTA
+    await prepareOutline();
+    Outline unitOutline = outline;
+    List<Outline> topOutlines = unitOutline.children;
+    expect(topOutlines, hasLength(10));
+    // FTA
+    {
+      Outline outline = topOutlines[0];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS);
+      expect(element.name, "FTA");
+      expect(element.typeParameters, "<K, V>");
       {
-        Outline outline = topOutlines[0];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS);
-        expect(element.name, "FTA");
-        expect(element.typeParameters, "<K, V>");
-        {
-          Location location = element.location;
-          expect(location.offset, testCode.indexOf("FTA<K, V>("));
-          expect(location.length, "FTA".length);
-        }
-        expect(element.parameters, "(int i, String s)");
-        expect(element.returnType, "String");
+        Location location = element.location;
+        expect(location.offset, testCode.indexOf("FTA<K, V>("));
+        expect(location.length, "FTA".length);
       }
-      // FTB
+      expect(element.parameters, "(int i, String s)");
+      expect(element.returnType, "String");
+    }
+    // FTB
+    {
+      Outline outline = topOutlines[1];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS);
+      expect(element.name, "FTB");
+      expect(element.typeParameters, isNull);
       {
-        Outline outline = topOutlines[1];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS);
-        expect(element.name, "FTB");
-        expect(element.typeParameters, isNull);
-        {
-          Location location = element.location;
-          expect(location.offset, testCode.indexOf("FTB("));
-          expect(location.length, "FTB".length);
-        }
-        expect(element.parameters, "(int p)");
-        expect(element.returnType, "");
+        Location location = element.location;
+        expect(location.offset, testCode.indexOf("FTB("));
+        expect(location.length, "FTB".length);
       }
-      // CTA
+      expect(element.parameters, "(int p)");
+      expect(element.returnType, "");
+    }
+    // CTA
+    {
+      Outline outline = topOutlines[4];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.CLASS_TYPE_ALIAS);
+      expect(element.name, "CTA");
+      expect(element.typeParameters, '<T>');
       {
-        Outline outline = topOutlines[4];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.CLASS_TYPE_ALIAS);
-        expect(element.name, "CTA");
-        expect(element.typeParameters, '<T>');
-        {
-          Location location = element.location;
-          expect(location.offset, testCode.indexOf("CTA<T> ="));
-          expect(location.length, "CTA".length);
-        }
-        expect(element.parameters, isNull);
-        expect(element.returnType, isNull);
+        Location location = element.location;
+        expect(location.offset, testCode.indexOf("CTA<T> ="));
+        expect(location.length, "CTA".length);
       }
-      // CTB
+      expect(element.parameters, isNull);
+      expect(element.returnType, isNull);
+    }
+    // CTB
+    {
+      Outline outline = topOutlines[5];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.CLASS_TYPE_ALIAS);
+      expect(element.name, 'CTB');
+      expect(element.typeParameters, isNull);
+      expect(element.returnType, isNull);
+    }
+    // fA
+    {
+      Outline outline = topOutlines[6];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.FUNCTION);
+      expect(element.name, "fA");
       {
-        Outline outline = topOutlines[5];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.CLASS_TYPE_ALIAS);
-        expect(element.name, 'CTB');
-        expect(element.typeParameters, isNull);
-        expect(element.returnType, isNull);
+        Location location = element.location;
+        expect(location.offset, testCode.indexOf("fA("));
+        expect(location.length, "fA".length);
       }
-      // fA
+      expect(element.parameters, "(int i, String s)");
+      expect(element.returnType, "String");
+    }
+    // fB
+    {
+      Outline outline = topOutlines[7];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.FUNCTION);
+      expect(element.name, "fB");
       {
-        Outline outline = topOutlines[6];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.FUNCTION);
-        expect(element.name, "fA");
-        {
-          Location location = element.location;
-          expect(location.offset, testCode.indexOf("fA("));
-          expect(location.length, "fA".length);
-        }
-        expect(element.parameters, "(int i, String s)");
-        expect(element.returnType, "String");
+        Location location = element.location;
+        expect(location.offset, testCode.indexOf("fB("));
+        expect(location.length, "fB".length);
       }
-      // fB
+      expect(element.parameters, "(int p)");
+      expect(element.returnType, "");
+    }
+    // propA
+    {
+      Outline outline = topOutlines[8];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.GETTER);
+      expect(element.name, "propA");
       {
-        Outline outline = topOutlines[7];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.FUNCTION);
-        expect(element.name, "fB");
-        {
-          Location location = element.location;
-          expect(location.offset, testCode.indexOf("fB("));
-          expect(location.length, "fB".length);
-        }
-        expect(element.parameters, "(int p)");
-        expect(element.returnType, "");
+        Location location = element.location;
+        expect(location.offset, testCode.indexOf("propA => null;"));
+        expect(location.length, "propA".length);
       }
-      // propA
+      expect(element.parameters, "");
+      expect(element.returnType, "String");
+    }
+    // propB
+    {
+      Outline outline = topOutlines[9];
+      Element element = outline.element;
+      expect(element.kind, ElementKind.SETTER);
+      expect(element.name, "propB");
       {
-        Outline outline = topOutlines[8];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.GETTER);
-        expect(element.name, "propA");
-        {
-          Location location = element.location;
-          expect(location.offset, testCode.indexOf("propA => null;"));
-          expect(location.length, "propA".length);
-        }
-        expect(element.parameters, "");
-        expect(element.returnType, "String");
+        Location location = element.location;
+        expect(location.offset, testCode.indexOf("propB(int v) {}"));
+        expect(location.length, "propB".length);
       }
-      // propB
-      {
-        Outline outline = topOutlines[9];
-        Element element = outline.element;
-        expect(element.kind, ElementKind.SETTER);
-        expect(element.name, "propB");
-        {
-          Location location = element.location;
-          expect(location.offset, testCode.indexOf("propB(int v) {}"));
-          expect(location.length, "propB".length);
-        }
-        expect(element.parameters, "(int v)");
-        expect(element.returnType, "");
-      }
-    });
+      expect(element.parameters, "(int v)");
+      expect(element.returnType, "");
+    }
   }
 
   void _isEnumConstant(Outline outline, String name) {
diff --git a/pkg/analysis_server/test/analysis/notification_overrides_test.dart b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
index fa1a0b5..ae7551e 100644
--- a/pkg/analysis_server/test/analysis/notification_overrides_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
@@ -71,6 +71,20 @@
   }
 
   /**
+   * Validates that there is no [Override] at the offset of [search].
+   *
+   * If [length] is not specified explicitly, then length of an identifier
+   * from [search] is used.
+   */
+  void assertNoOverride(String search, [int length = -1]) {
+    int offset = findOffset(search);
+    if (length == -1) {
+      length = findIdentifierLength(search);
+    }
+    findOverride(offset, length, false);
+  }
+
+  /**
    * Asserts that there are no overridden member from the superclass.
    */
   void assertNoSuperMember() {
@@ -121,7 +135,7 @@
     createProject();
   }
 
-  test_afterAnalysis() {
+  test_afterAnalysis() async {
     addTestFile('''
 class A {
   m() {} // in A
@@ -130,16 +144,118 @@
   m() {} // in B
 }
 ''');
-    return waitForTasksFinished().then((_) {
-      return prepareOverrides().then((_) {
-        assertHasOverride('m() {} // in B');
-        assertNoSuperMember();
-        assertHasInterfaceMember('m() {} // in A');
-      });
-    });
+    await waitForTasksFinished();
+    await prepareOverrides();
+    assertHasOverride('m() {} // in B');
+    assertNoSuperMember();
+    assertHasInterfaceMember('m() {} // in A');
   }
 
-  test_definedInInterface_ofInterface() {
+  test_BAD_fieldByMethod() async {
+    addTestFile('''
+class A {
+  int fff; // in A
+}
+class B extends A {
+  fff() {} // in B
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff() {} // in B');
+  }
+
+  test_BAD_getterByMethod() async {
+    addTestFile('''
+class A {
+  get fff => null;
+}
+class B extends A {
+  fff() {}
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff() {}');
+  }
+
+  test_BAD_getterBySetter() async {
+    addTestFile('''
+class A {
+  get fff => null;
+}
+class B extends A {
+  set fff(x) {}
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff(x) {}');
+  }
+
+  test_BAD_methodByField() async {
+    addTestFile('''
+class A {
+  fff() {} // in A
+}
+class B extends A {
+  int fff; // in B
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff; // in B');
+  }
+
+  test_BAD_methodByGetter() async {
+    addTestFile('''
+class A {
+  fff() {}
+}
+class B extends A {
+  int get fff => null;
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff => null');
+  }
+
+  test_BAD_methodBySetter() async {
+    addTestFile('''
+class A {
+  fff(x) {} // A
+}
+class B extends A {
+  set fff(x) {} // B
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff(x) {} // B');
+  }
+
+  test_BAD_setterByGetter() async {
+    addTestFile('''
+class A {
+  set fff(x) {}
+}
+class B extends A {
+  get fff => null;
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff => null;');
+  }
+
+  test_BAD_setterByMethod() async {
+    addTestFile('''
+class A {
+  set fff(x) {} // A
+}
+class B extends A {
+  fff(x) {} // B
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff(x) {} // B');
+  }
+
+  test_definedInInterface_ofInterface() async {
     addTestFile('''
 class A {
   m() {} // in A
@@ -149,14 +265,13 @@
   m() {} // in C
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('m() {} // in C');
-      assertNoSuperMember();
-      assertHasInterfaceMember('m() {} // in A');
-    });
+    await prepareOverrides();
+    assertHasOverride('m() {} // in C');
+    assertNoSuperMember();
+    assertHasInterfaceMember('m() {} // in A');
   }
 
-  test_definedInInterface_ofSuper() {
+  test_definedInInterface_ofSuper() async {
     addTestFile('''
 class A {
   m() {} // in A
@@ -166,14 +281,13 @@
   m() {} // in C
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('m() {} // in C');
-      assertNoSuperMember();
-      assertHasInterfaceMember('m() {} // in A');
-    });
+    await prepareOverrides();
+    assertHasOverride('m() {} // in C');
+    assertNoSuperMember();
+    assertHasInterfaceMember('m() {} // in A');
   }
 
-  test_interface_method_direct_multiple() {
+  test_interface_method_direct_multiple() async {
     addTestFile('''
 class IA {
   m() {} // in IA
@@ -185,15 +299,14 @@
   m() {} // in A
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('m() {} // in A');
-      assertNoSuperMember();
-      assertHasInterfaceMember('m() {} // in IA');
-      assertHasInterfaceMember('m() {} // in IB');
-    });
+    await prepareOverrides();
+    assertHasOverride('m() {} // in A');
+    assertNoSuperMember();
+    assertHasInterfaceMember('m() {} // in IA');
+    assertHasInterfaceMember('m() {} // in IB');
   }
 
-  test_interface_method_direct_single() {
+  test_interface_method_direct_single() async {
     addTestFile('''
 class A {
   m() {} // in A
@@ -202,14 +315,13 @@
   m() {} // in B
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('m() {} // in B');
-      assertNoSuperMember();
-      assertHasInterfaceMember('m() {} // in A');
-    });
+    await prepareOverrides();
+    assertHasOverride('m() {} // in B');
+    assertNoSuperMember();
+    assertHasInterfaceMember('m() {} // in A');
   }
 
-  test_interface_method_indirect_single() {
+  test_interface_method_indirect_single() async {
     addTestFile('''
 class A {
   m() {} // in A
@@ -220,14 +332,13 @@
   m() {} // in C
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('m() {} // in C');
-      assertNoSuperMember();
-      assertHasInterfaceMember('m() {} // in A');
-    });
+    await prepareOverrides();
+    assertHasOverride('m() {} // in C');
+    assertNoSuperMember();
+    assertHasInterfaceMember('m() {} // in A');
   }
 
-  test_interface_stopWhenFound() {
+  test_interface_stopWhenFound() async {
     addTestFile('''
 class A {
   m() {} // in A
@@ -239,14 +350,13 @@
   m() {} // in C
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('m() {} // in C');
-      expect(override.interfaceMembers, hasLength(1));
-      assertHasInterfaceMember('m() {} // in B');
-    });
+    await prepareOverrides();
+    assertHasOverride('m() {} // in C');
+    expect(override.interfaceMembers, hasLength(1));
+    assertHasInterfaceMember('m() {} // in B');
   }
 
-  test_mix_sameMethod() {
+  test_mix_sameMethod() async {
     addTestFile('''
 class A {
   m() {} // in A
@@ -257,14 +367,13 @@
   m() {} // in C
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('m() {} // in C');
-      assertHasSuperElement('m() {} // in A');
-      assertNoInterfaceMembers();
-    });
+    await prepareOverrides();
+    assertHasOverride('m() {} // in C');
+    assertHasSuperElement('m() {} // in A');
+    assertNoInterfaceMembers();
   }
 
-  test_mix_sameMethod_Object_hashCode() {
+  test_mix_sameMethod_Object_hashCode() async {
     addTestFile('''
 class A {}
 abstract class B {}
@@ -272,14 +381,13 @@
   int get hashCode => 42;
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('hashCode => 42;');
-      expect(override.superclassMember, isNotNull);
-      expect(override.interfaceMembers, isNull);
-    });
+    await prepareOverrides();
+    assertHasOverride('hashCode => 42;');
+    expect(override.superclassMember, isNotNull);
+    expect(override.interfaceMembers, isNull);
   }
 
-  test_staticMembers() {
+  test_staticMembers() async {
     addTestFile('''
 class A {
   static int F = 0;
@@ -294,12 +402,11 @@
   static void set S(int v) {}
 }
 ''');
-    return prepareOverrides().then((_) {
-      expect(overridesList, isEmpty);
-    });
+    await prepareOverrides();
+    expect(overridesList, isEmpty);
   }
 
-  test_super_fieldByField() {
+  test_super_fieldByField() async {
     addTestFile('''
 class A {
   int fff; // in A
@@ -308,14 +415,13 @@
   int fff; // in B
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('fff; // in B');
-      assertHasSuperElement('fff; // in A');
-      assertNoInterfaceMembers();
-    });
+    await prepareOverrides();
+    assertHasOverride('fff; // in B');
+    assertHasSuperElement('fff; // in A');
+    assertNoInterfaceMembers();
   }
 
-  test_super_fieldByGetter() {
+  test_super_fieldByGetter() async {
     addTestFile('''
 class A {
   int fff; // in A
@@ -324,30 +430,13 @@
   get fff => 0; // in B
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('fff => 0; // in B');
-      assertHasSuperElement('fff; // in A');
-      assertNoInterfaceMembers();
-    });
+    await prepareOverrides();
+    assertHasOverride('fff => 0; // in B');
+    assertHasSuperElement('fff; // in A');
+    assertNoInterfaceMembers();
   }
 
-  test_super_fieldByMethod() {
-    addTestFile('''
-class A {
-  int fff; // in A
-}
-class B extends A {
-  fff() {} // in B
-}
-''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('fff() {} // in B');
-      assertHasSuperElement('fff; // in A');
-      assertNoInterfaceMembers();
-    });
-  }
-
-  test_super_fieldBySetter() {
+  test_super_fieldBySetter() async {
     addTestFile('''
 class A {
   int fff; // in A
@@ -356,14 +445,13 @@
   set fff(x) {} // in B
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('fff(x) {} // in B');
-      assertHasSuperElement('fff; // in A');
-      assertNoInterfaceMembers();
-    });
+    await prepareOverrides();
+    assertHasOverride('fff(x) {} // in B');
+    assertHasSuperElement('fff; // in A');
+    assertNoInterfaceMembers();
   }
 
-  test_super_getterByField() {
+  test_super_getterByField() async {
     addTestFile('''
 class A {
   get fff => 0; // in A
@@ -373,14 +461,13 @@
   int fff; // in B
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('fff; // in B');
-      assertHasSuperElement('fff => 0; // in A');
-      assertNoInterfaceMembers();
-    });
+    await prepareOverrides();
+    assertHasOverride('fff; // in B');
+    assertHasSuperElement('fff => 0; // in A');
+    assertNoInterfaceMembers();
   }
 
-  test_super_getterByGetter() {
+  test_super_getterByGetter() async {
     addTestFile('''
 class A {
   get fff => 0; // in A
@@ -389,14 +476,13 @@
   get fff => 0; // in B
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('fff => 0; // in B');
-      assertHasSuperElement('fff => 0; // in A');
-      assertNoInterfaceMembers();
-    });
+    await prepareOverrides();
+    assertHasOverride('fff => 0; // in B');
+    assertHasSuperElement('fff => 0; // in A');
+    assertNoInterfaceMembers();
   }
 
-  test_super_method_direct() {
+  test_super_method_direct() async {
     addTestFile('''
 class A {
   m() {} // in A
@@ -405,14 +491,13 @@
   m() {} // in B
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('m() {} // in B');
-      assertHasSuperElement('m() {} // in A');
-      assertNoInterfaceMembers();
-    });
+    await prepareOverrides();
+    assertHasOverride('m() {} // in B');
+    assertHasSuperElement('m() {} // in A');
+    assertNoInterfaceMembers();
   }
 
-  test_super_method_indirect() {
+  test_super_method_indirect() async {
     addTestFile('''
 class A {
   m() {} // in A
@@ -423,14 +508,13 @@
   m() {} // in C
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('m() {} // in C');
-      assertHasSuperElement('m() {} // in A');
-      assertNoInterfaceMembers();
-    });
+    await prepareOverrides();
+    assertHasOverride('m() {} // in C');
+    assertHasSuperElement('m() {} // in A');
+    assertNoInterfaceMembers();
   }
 
-  test_super_method_superTypeCycle() {
+  test_super_method_superTypeCycle() async {
     addTestFile('''
 class A extends B {
   m() {} // in A
@@ -439,12 +523,11 @@
   m() {} // in B
 }
 ''');
-    return prepareOverrides().then((_) {
-      // must finish
-    });
+    await prepareOverrides();
+    // must finish
   }
 
-  test_super_setterBySetter() {
+  test_super_setterBySetter() async {
     addTestFile('''
 class A {
   set fff(x) {} // in A
@@ -453,10 +536,9 @@
   set fff(x) {} // in B
 }
 ''');
-    return prepareOverrides().then((_) {
-      assertHasOverride('fff(x) {} // in B');
-      assertHasSuperElement('fff(x) {} // in A');
-      assertNoInterfaceMembers();
-    });
+    await prepareOverrides();
+    assertHasOverride('fff(x) {} // in B');
+    assertHasSuperElement('fff(x) {} // in A');
+    assertNoInterfaceMembers();
   }
 }
diff --git a/pkg/analysis_server/test/analysis/reanalyze_test.dart b/pkg/analysis_server/test/analysis/reanalyze_test.dart
index 310e6d7..0b39e88 100644
--- a/pkg/analysis_server/test/analysis/reanalyze_test.dart
+++ b/pkg/analysis_server/test/analysis/reanalyze_test.dart
@@ -44,31 +44,32 @@
     expect(newContext, isNot(same(oldContext)));
   }
 
-  test_reanalyze_with_overlay() {
+  test_reanalyze_with_overlay() async {
     createProject();
     resourceProvider.newFolder(testFolder);
     resourceProvider.newFile(testFile, 'main() {}');
-    return waitForTasksFinished().then((_) {
-      // Update the content with an overlay that contains a syntax error.
-      server.updateContent('1', {testFile: new AddContentOverlay('main() {')});
-      return waitForTasksFinished();
-    }).then((_) {
-      // Verify that the syntax error was detected.
+    await waitForTasksFinished();
+    // Update the content with an overlay that contains a syntax error.
+    server.updateContent('1', {testFile: new AddContentOverlay('main() {')});
+    await waitForTasksFinished();
+    // Verify that the syntax error was detected.
+    {
       List<AnalysisError> errors = filesErrors[testFile];
       expect(errors, hasLength(1));
-      // Remove testFile from filesErrors so that we'll notice when the file is
-      // re-analyzed.
-      filesErrors.remove(testFile);
-      // Reanalyze.
-      server.reanalyze(null);
-      return waitForTasksFinished();
-    }).then((_) {
-      // The file should have been reanalyzed.
-      expect(filesErrors, contains(testFile));
-      // Verify that the syntax error is present (this indicates that the
-      // content introduced by the call to updateContent is still in effect).
+    }
+    // Remove testFile from filesErrors so that we'll notice when the file is
+    // re-analyzed.
+    filesErrors.remove(testFile);
+    // Reanalyze.
+    server.reanalyze(null);
+    await waitForTasksFinished();
+    // The file should have been reanalyzed.
+    expect(filesErrors, contains(testFile));
+    // Verify that the syntax error is present (this indicates that the
+    // content introduced by the call to updateContent is still in effect).
+    {
       List<AnalysisError> errors = filesErrors[testFile];
       expect(errors, hasLength(1));
-    });
+    }
   }
 }
diff --git a/pkg/analysis_server/test/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
index 8626ef8..f89ba30 100644
--- a/pkg/analysis_server/test/analysis/set_priority_files_test.dart
+++ b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
@@ -6,6 +6,9 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show InternalAnalysisContext;
+import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -35,15 +38,30 @@
 
   test_fileInAnalysisRoot() async {
     addTestFile('');
+    // wait for analysis to ensure that the file is known to the context
+    await server.onAnalysisComplete;
+    // set priority files
     Response response = await _setPriorityFile(testFile);
     expect(response, isResponseSuccess('0'));
+    // verify
+    InternalAnalysisContext context = server.getContainingContext(testFile);
+    List<Source> prioritySources = context.prioritySources;
+    expect(prioritySources, hasLength(1));
+    expect(prioritySources.first.fullName, testFile);
   }
 
   test_fileInSdk() async {
     addTestFile('');
     await server.onAnalysisComplete;
-    Response response = await _setPriorityFile('/lib/convert/convert.dart');
+    // set priority files
+    String filePath = '/lib/convert/convert.dart';
+    Response response = await _setPriorityFile(filePath);
     expect(response, isResponseSuccess('0'));
+    // verify
+    InternalAnalysisContext sdkContext = server.defaultSdk.context;
+    List<Source> prioritySources = sdkContext.prioritySources;
+    expect(prioritySources, hasLength(1));
+    expect(prioritySources.first.fullName, filePath);
   }
 
   test_fileNotInAnalysisRoot() async {
@@ -54,6 +72,58 @@
     expect(response.error.code, RequestErrorCode.UNANALYZED_PRIORITY_FILES);
   }
 
+  test_ignoredInAnalysisOptions() async {
+    String sampleFile = '$projectPath/samples/sample.dart';
+    addFile(
+        '$projectPath/.analysis_options',
+        r'''
+analyzer:
+  exclude:
+    - 'samples/**'
+''');
+    addFile(sampleFile, '');
+    // attempt to set priority file
+    Response response = await _setPriorityFile(sampleFile);
+    expect(response.error, isNotNull);
+    expect(response.error.code, RequestErrorCode.UNANALYZED_PRIORITY_FILES);
+  }
+
+  test_ignoredInAnalysisOptions_inChildContext() async {
+    addFile('$projectPath/.packages', '');
+    addFile('$projectPath/child/.packages', '');
+    String sampleFile = '$projectPath/child/samples/sample.dart';
+    addFile(
+        '$projectPath/child/.analysis_options',
+        r'''
+analyzer:
+  exclude:
+    - 'samples/**'
+''');
+    addFile(sampleFile, '');
+    // attempt to set priority file
+    Response response = await _setPriorityFile(sampleFile);
+    expect(response.error, isNotNull);
+    expect(response.error.code, RequestErrorCode.UNANALYZED_PRIORITY_FILES);
+  }
+
+  test_ignoredInAnalysisOptions_inRootContext() async {
+    addFile('$projectPath/.packages', '');
+    addFile('$projectPath/child/.packages', '');
+    String sampleFile = '$projectPath/child/samples/sample.dart';
+    addFile(
+        '$projectPath/.analysis_options',
+        r'''
+analyzer:
+  exclude:
+    - 'child/samples/**'
+''');
+    addFile(sampleFile, '');
+    // attempt to set priority file
+    Response response = await _setPriorityFile(sampleFile);
+    expect(response.error, isNotNull);
+    expect(response.error.code, RequestErrorCode.UNANALYZED_PRIORITY_FILES);
+  }
+
   _setPriorityFile(String file) async {
     Request request =
         new AnalysisSetPriorityFilesParams(<String>[file]).toRequest('0');
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index 05b49f3d..a0cd6d3 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -9,7 +9,9 @@
 import 'get_errors_test.dart' as get_errors_test;
 import 'get_hover_test.dart' as get_hover_test;
 import 'get_navigation_test.dart' as get_navigation_test;
-import 'notification_analysis_options_test.dart' as notification_analysis_options_test;
+import 'navigation_collector_test.dart' as navigation_collector_test;
+import 'notification_analysis_options_test.dart'
+    as notification_analysis_options_test;
 import 'notification_analyzedFiles_test.dart'
     as notification_analyzedFiles_test;
 import 'notification_errors_test.dart' as notification_errors_test;
@@ -32,6 +34,7 @@
     get_errors_test.main();
     get_hover_test.main();
     get_navigation_test.main();
+    navigation_collector_test.main();
     notification_analysis_options_test.main();
     notification_analyzedFiles_test.main();
     notification_errors_test.main();
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index 6fbc5d8..3e09632 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -107,11 +107,7 @@
     server.updateContent('2', {testFile: new RemoveContentOverlay()});
     // Validate that at the end the unit was indexed.
     await server.onAnalysisComplete;
-    if (AnalysisEngine.instance.useTaskModel) {
-      verify(server.index.index(anyObject, testUnitMatcher)).times(3);
-    } else {
-      verify(server.index.index(anyObject, testUnitMatcher)).times(2);
-    }
+    verify(server.index.index(anyObject, testUnitMatcher)).times(3);
   }
 
   test_multiple_contexts() async {
@@ -136,8 +132,9 @@
 library baz;
 f(int i) {}
 ''');
-    Request request = new AnalysisSetAnalysisRootsParams(
-        ['/project1', '/project2'], []).toRequest('0');
+    Request request =
+        new AnalysisSetAnalysisRootsParams(['/project1', '/project2'], [])
+            .toRequest('0');
     handleSuccessfulRequest(request);
     {
       await server.onAnalysisComplete;
@@ -166,8 +163,9 @@
     String filePath = '/User/project1/test.dart';
     Folder folder1 = resourceProvider.newFolder('/User/project1');
     Folder folder2 = resourceProvider.newFolder('/User/project2');
-    Request request = new AnalysisSetAnalysisRootsParams(
-        [folder1.path, folder2.path], []).toRequest('0');
+    Request request =
+        new AnalysisSetAnalysisRootsParams([folder1.path, folder2.path], [])
+            .toRequest('0');
     handleSuccessfulRequest(request);
     // exactly 2 contexts
     expect(server.folderMap, hasLength(2));
@@ -274,6 +272,4 @@
   }
 }
 
-class _MockIndex extends TypedMock implements Index {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockIndex extends TypedMock implements Index {}
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index c367665..5c0616e 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -12,6 +12,7 @@
 import 'package:analysis_server/src/domain_analysis.dart';
 import 'package:analysis_server/src/plugin/linter_plugin.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_plugin.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';
@@ -96,21 +97,27 @@
   }
 
   AnalysisServer createAnalysisServer(Index index) {
+    //
+    // Collect plugins
+    //
     ServerPlugin serverPlugin = new ServerPlugin();
-    // TODO(pq): this convoluted extension registry dance needs cleanup.
-    List<Plugin> plugins = <Plugin>[
-      serverPlugin,
-      linterPlugin,
-      linterServerPlugin
-    ];
-    // Accessing `taskManager` ensures that AE plugins are registered.
-    AnalysisEngine.instance.taskManager;
-    plugins.addAll(AnalysisEngine.instance.supportedPlugins);
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    plugins.add(serverPlugin);
+    plugins.add(dartCompletionPlugin);
+    plugins.add(linterPlugin);
+    plugins.add(linterServerPlugin);
     addServerPlugins(plugins);
-    // process plugins
+    //
+    // Process plugins
+    //
     ExtensionManager manager = new ExtensionManager();
     manager.processPlugins(plugins);
-    // create server
+    //
+    // Create server
+    //
     return new AnalysisServer(
         serverChannel,
         resourceProvider,
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index d964390..14d9fd6 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -21,6 +21,7 @@
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
@@ -119,23 +120,31 @@
     });
   }
 
+  void processRequiredPlugins() {
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    plugins.add(server.serverPlugin);
+
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+  }
+
   void setUp() {
     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,
-        serverPlugin,
+        new ServerPlugin(),
         new AnalysisServerOptions(),
         new MockSdk(),
         InstrumentationService.NULL_SERVICE,
         rethrowExceptions: true);
+    processRequiredPlugins();
   }
 
   Future test_contextDisposed() {
@@ -242,20 +251,15 @@
     String dir1Path = '/dir1';
     String dir2Path = dir1Path + '/dir2';
     String filePath = dir2Path + '/file.dart';
-    Folder dir1 = resourceProvider.newFolder(dir1Path);
-    Folder dir2 = resourceProvider.newFolder(dir2Path);
+    resourceProvider.newFile('$dir1Path/.packages', '');
+    resourceProvider.newFile('$dir2Path/.packages', '');
     resourceProvider.newFile(filePath, 'library lib;');
-
-    AnalysisContext context1 = AnalysisEngine.instance.createAnalysisContext();
-    AnalysisContext context2 = AnalysisEngine.instance.createAnalysisContext();
-    _configureSourceFactory(context1);
-    _configureSourceFactory(context2);
-    server.folderMap[dir1] = context1;
-    server.folderMap[dir2] = context2;
-
+    // create contexts
+    server.setAnalysisRoots('0', [dir1Path], [], {});
+    // get pair
     ContextSourcePair pair = server.getContextSourcePair(filePath);
     Source source = pair.source;
-    expect(pair.context, same(context2));
+    _assertContextOfFolder(pair.context, dir2Path);
     expect(source, isNotNull);
     expect(source.uri.scheme, 'file');
     expect(source.fullName, filePath);
@@ -284,14 +288,12 @@
     packageMapProvider.packageMap = <String, List<Folder>>{
       'my_package': <Folder>[rootFolder]
     };
-
-    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
-    _configureSourceFactory(context);
-    server.folderMap[rootFolder] = context;
-
+    // create contexts
+    server.setAnalysisRoots('0', [rootPath], [], {});
+    // get pair
     ContextSourcePair pair = server.getContextSourcePair(filePath);
     Source source = pair.source;
-    expect(pair.context, same(context));
+    _assertContextOfFolder(pair.context, rootPath);
     expect(source, isNotNull);
     expect(source.uri.scheme, 'package');
     expect(source.fullName, filePath);
@@ -300,16 +302,13 @@
   test_getContextSourcePair_simple() {
     String dirPath = '/dir';
     String filePath = dirPath + '/file.dart';
-    Folder dir = resourceProvider.newFolder(dirPath);
     resourceProvider.newFile(filePath, 'library lib;');
-
-    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
-    _configureSourceFactory(context);
-    server.folderMap[dir] = context;
-
+    // create contexts
+    server.setAnalysisRoots('0', [dirPath], [], {});
+    // get pair
     ContextSourcePair pair = server.getContextSourcePair(filePath);
     Source source = pair.source;
-    expect(pair.context, same(context));
+    _assertContextOfFolder(pair.context, dirPath);
     expect(source, isNotNull);
     expect(source.uri.scheme, 'file');
     expect(source.fullName, filePath);
@@ -333,12 +332,12 @@
       subscriptions[service] = <String>[bar.path].toSet();
     }
     server.setAnalysisSubscriptions(subscriptions);
-    await pumpEventQueue(500);
+    await pumpEventQueue(1000);
     expect(server.statusAnalyzing, isFalse);
     channel.notificationsReceived.clear();
     server.updateContent(
         '0', {bar.path: new AddContentOverlay('library bar; void f() {}')});
-    await pumpEventQueue(500);
+    await pumpEventQueue(1000);
     expect(server.statusAnalyzing, isFalse);
     expect(channel.notificationsReceived, isNotEmpty);
     Set<String> notificationTypesReceived = new Set<String>();
@@ -466,6 +465,27 @@
     });
   }
 
+  test_setAnalysisSubscriptions_fileInIgnoredFolder() async {
+    String path = '/project/samples/sample.dart';
+    resourceProvider.newFile(path, '');
+    resourceProvider.newFile(
+        '/project/.analysis_options',
+        r'''
+analyzer:
+  exclude:
+    - 'samples/**'
+''');
+    server.setAnalysisRoots('0', ['/project'], [], {});
+    server.setAnalysisSubscriptions(<AnalysisService, Set<String>>{
+      AnalysisService.NAVIGATION: new Set<String>.from([path])
+    });
+    // the file is excluded, so no navigation notification
+    await server.onAnalysisComplete;
+    expect(channel.notificationsReceived.any((notification) {
+      return notification.event == ANALYSIS_NAVIGATION;
+    }), isFalse);
+  }
+
   Future test_shutdown() {
     server.handlers = [new ServerDomainHandler(server)];
     var request = new Request('my28', SERVER_SHUTDOWN);
@@ -484,6 +504,37 @@
     });
   }
 
+  test_watch_modifyFile_hasOverlay() async {
+    server.serverServices.add(ServerService.STATUS);
+    // configure the project
+    String projectPath = '/root';
+    String filePath = '/root/test.dart';
+    resourceProvider.newFolder(projectPath);
+    resourceProvider.newFile(filePath, '// 111');
+    server.setAnalysisRoots('0', ['/root'], [], {});
+    await pumpEventQueue();
+    // add overlay
+    server.updateContent('1', {filePath: new AddContentOverlay('// 222')});
+    await pumpEventQueue();
+    // update the file
+    channel.notificationsReceived.clear();
+    resourceProvider.modifyFile(filePath, '// 333');
+    await pumpEventQueue();
+    // the file has an overlay, so the file-system change was ignored
+    expect(channel.notificationsReceived.any((notification) {
+      return notification.event == SERVER_STATUS;
+    }), isFalse);
+  }
+
+  void _assertContextOfFolder(
+      AnalysisContext context, String expectedFolderPath) {
+    Folder expectedFolder = resourceProvider.newFolder(expectedFolderPath);
+    ContextInfo expectedContextInfo = (server.contextManager
+        as ContextManagerImpl).getContextInfoFor(expectedFolder);
+    expect(expectedContextInfo, isNotNull);
+    expect(context, same(expectedContextInfo.context));
+  }
+
   void _configureSourceFactory(AnalysisContext context) {
     var resourceUriResolver = new ResourceUriResolver(resourceProvider);
     var packageUriResolver = new PackageMapUriResolver(
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 7fc8d23..86defe8 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -1121,9 +1121,8 @@
     buildTests(
         'testCompletion_combinator_afterComma',
         '''
-"import 'dart:math' show cos, !1;''',
-        <String>["1+PI", "1+sin", "1+Random", "1-String"],
-        failingTests: '1');
+import 'dart:math' show cos, !1;''',
+        <String>["1+PI", "1+sin", "1+Random", "1-String"]);
 
     buildTests(
         'testCompletion_combinator_ended',
@@ -1896,8 +1895,7 @@
 main() {
   B.!1;
 }''',
-        <String>["1+FIELD_B", "1-FIELD_A", "1+methodB", "1-methodA"],
-        failingTests: '1');
+        <String>["1+FIELD_B", "1-FIELD_A", "1+methodB", "1-methodA"]);
 
     buildTests(
         'testCompletion_propertyAccess_whenInstanceTarget',
@@ -2119,7 +2117,7 @@
     sources.clear();
     sources["/lib.dart"] = '''
 library lib
-class _A 
+class _A
   foo() {}
 
 class A extends _A {
@@ -2851,7 +2849,7 @@
 
     // test analysis of untyped fields and top-level vars
     buildTests('test035', '''class Y {final x='hi';mth() {x.!1length;}}''',
-        <String>["1+length"], failingTests: '1');
+        <String>["1+length"]);
 
     // TODO(scheglov) decide what to do with Type for untyped field (not
     // supported by the new store)
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index 0f00d1e..c2fb7a1 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -16,7 +16,7 @@
 /**
  * A base class for classes containing completion tests.
  */
-class CompletionTestCase extends CompletionTest {
+class CompletionTestCase extends CompletionDomainHandlerTest {
   static const String CURSOR_MARKER = '!';
 
   List get suggestedCompletions => suggestions
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 081c8b6..f6eff47 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -10,11 +10,19 @@
 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:analyzer/source/embedder.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/services/lint.dart';
+import 'package:linter/src/plugin/linter_plugin.dart';
+import 'package:linter/src/rules/avoid_as.dart';
 import 'package:package_config/packages.dart';
 import 'package:path/path.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -65,6 +73,37 @@
 
   String projPath = '/my/proj';
 
+  AnalysisError missing_return =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
+    ['x']
+  ]);
+
+  AnalysisError invalid_assignment_error =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
+    ['x'],
+    ['y']
+  ]);
+
+  AnalysisError unused_local_variable = new AnalysisError(
+      new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+    ['x']
+  ]);
+
+  List<ErrorProcessor> get errorProcessors => callbacks.currentContext
+      .getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+
+  List<Linter> get lints => getLints(callbacks.currentContext);
+
+  AnalysisOptions get options => callbacks.currentContext.analysisOptions;
+
+  void deleteFile(List<String> pathComponents) {
+    String filePath = posix.joinAll(pathComponents);
+    resourceProvider.deleteFile(filePath);
+  }
+
+  ErrorProcessor getProcessor(AnalysisError error) =>
+      ErrorProcessor.getProcessor(callbacks.currentContext, error);
+
   String newFile(List<String> pathComponents, [String content = '']) {
     String filePath = posix.joinAll(pathComponents);
     resourceProvider.newFile(filePath, content);
@@ -77,11 +116,22 @@
     return folderPath;
   }
 
+  void processRequiredPlugins() {
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    plugins.add(linterPlugin);
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+  }
+
   UriResolver providePackageResolver(Folder folder) {
     return packageResolver;
   }
 
   void setUp() {
+    processRequiredPlugins();
     resourceProvider = new MemoryResourceProvider();
     packageMapProvider = new MockPackageMapProvider();
     manager = new ContextManagerImpl(resourceProvider, providePackageResolver,
@@ -91,6 +141,99 @@
     resourceProvider.newFolder(projPath);
   }
 
+  test_analysis_options_file_delete() async {
+    // Setup .analysis_options
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+embedder_libs:
+  "dart:foobar": "../sdk_ext/entry.dart"
+analyzer:
+  language:
+    enableGenericMethods: true
+  errors:
+    unused_local_variable: false
+linter:
+  rules:
+    - camel_case_types
+''');
+
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    await pumpEventQueue();
+
+    // Verify options were set.
+    expect(errorProcessors, hasLength(1));
+    expect(lints, hasLength(1));
+    expect(options.enableGenericMethods, isTrue);
+
+    // Remove options.
+    deleteFile([projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE]);
+    await pumpEventQueue();
+
+    // Verify defaults restored.
+    expect(errorProcessors, isEmpty);
+    expect(lints, isEmpty);
+    expect(options.enableGenericMethods, isFalse);
+  }
+
+  test_analysis_options_file_delete_with_embedder() async {
+    // Setup _embedder.yaml.
+    String libPath = newFolder([projPath, LIB_NAME]);
+    newFile(
+        [libPath, '_embedder.yaml'],
+        r'''
+analyzer:
+  strong-mode: true
+  errors:
+    missing_return: false
+linter:
+  rules:
+    - avoid_as
+''');
+
+    // Setup .packages file
+    newFile(
+        [projPath, '.packages'],
+        r'''
+test_pack:lib/''');
+
+    // Setup .analysis_options
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  language:
+    enableGenericMethods: true
+  errors:
+    unused_local_variable: false
+linter:
+  rules:
+    - camel_case_types
+''');
+
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    await pumpEventQueue();
+
+    // Verify options were set.
+    expect(options.enableGenericMethods, isTrue);
+    expect(options.strongMode, isTrue);
+    expect(errorProcessors, hasLength(2));
+    expect(lints, hasLength(2));
+
+    // Remove options.
+    deleteFile([projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE]);
+    await pumpEventQueue();
+
+    // Verify defaults restored.
+    expect(options.enableGenericMethods, isFalse);
+    expect(lints, hasLength(1));
+    expect(lints.first, new isInstanceOf<AvoidAs>());
+    expect(errorProcessors, hasLength(1));
+    expect(getProcessor(missing_return).severity, isNull);
+  }
+
   test_analysis_options_parse_failure() async {
     // Create files.
     String libPath = newFolder([projPath, LIB_NAME]);
@@ -136,6 +279,210 @@
     expect(contexts, contains(subProjContextInfo.context));
   }
 
+  test_embedder_options() async {
+    // Create files.
+    String libPath = newFolder([projPath, LIB_NAME]);
+    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
+    newFile([projPath, 'test', 'test.dart']);
+    newFile([sdkExtPath, 'entry.dart']);
+    // Setup _embedder.yaml.
+    newFile(
+        [libPath, '_embedder.yaml'],
+        r'''
+embedder_libs:
+  "dart:foobar": "../sdk_ext/entry.dart"
+analyzer:
+  strong-mode: true
+  language:
+    enableSuperMixins: true
+  errors:
+    missing_return: false
+linter:
+  rules:
+    - avoid_as
+''');
+    // Setup .packages file
+    newFile(
+        [projPath, '.packages'],
+        r'''
+test_pack:lib/''');
+
+    // Setup .analysis_options
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  exclude:
+    - 'test/**'
+  language:
+    enableGenericMethods: true
+    enableAsync: false
+  errors:
+    unused_local_variable: false
+linter:
+  rules:
+    - camel_case_types
+''');
+
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    await pumpEventQueue();
+
+    // Confirm that one context was created.
+    var contexts =
+        manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
+    expect(contexts, isNotNull);
+    expect(contexts, hasLength(1));
+    var context = contexts[0];
+
+    // Verify options.
+    // * from `_embedder.yaml`:
+    expect(context.analysisOptions.strongMode, isTrue);
+    expect(context.analysisOptions.enableSuperMixins, isTrue);
+    expect(context.analysisOptions.enableAsync, isFalse);
+    // * from `.analysis_options`:
+    expect(context.analysisOptions.enableGenericMethods, isTrue);
+    // * verify tests are excluded
+    expect(callbacks.currentContextFilePaths[projPath].keys,
+        ['/my/proj/sdk_ext/entry.dart']);
+
+    // Verify filter setup.
+    expect(errorProcessors, hasLength(2));
+
+    // * (embedder.)
+    expect(getProcessor(missing_return).severity, isNull);
+
+    // * (options.)
+    expect(getProcessor(unused_local_variable).severity, isNull);
+
+    // Verify lints.
+    var lintNames = lints.map((lint) => lint.name);
+
+    expect(
+        lintNames,
+        unorderedEquals(
+            ['avoid_as' /* embedder */, 'camel_case_types' /* options */]));
+
+    // Sanity check embedder libs.
+    var source = context.sourceFactory.forUri('dart:foobar');
+    expect(source, isNotNull);
+    expect(source.fullName, '/my/proj/sdk_ext/entry.dart');
+  }
+
+  test_embedder_packagespec() async {
+    // Create files.
+    String libPath = newFolder([projPath, LIB_NAME]);
+    newFile([libPath, 'main.dart']);
+    newFile([libPath, 'nope.dart']);
+    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
+    newFile([sdkExtPath, 'entry.dart']);
+    String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
+    newFile([sdkExtSrcPath, 'part.dart']);
+    // Setup _embedder.yaml.
+    newFile(
+        [libPath, '_embedder.yaml'],
+        r'''
+embedder_libs:
+  "dart:foobar": "../sdk_ext/entry.dart"
+  "dart:typed_data": "../sdk_ext/src/part"
+  ''');
+    // Setup .packages file
+    newFile(
+        [projPath, '.packages'],
+        r'''
+test_pack:lib/''');
+    // Setup context.
+
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    await pumpEventQueue();
+    // Confirm that one context was created.
+    var contexts =
+        manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
+    expect(contexts, isNotNull);
+    expect(contexts.length, equals(1));
+    var context = contexts[0];
+    var source = context.sourceFactory.forUri('dart:foobar');
+    expect(source, isNotNull);
+    expect(source.fullName, equals('/my/proj/sdk_ext/entry.dart'));
+    // We can't find dart:core because we didn't list it in our
+    // embedder_libs map.
+    expect(context.sourceFactory.forUri('dart:core'), isNull);
+    // We can find dart:typed_data because we listed it in our
+    // embedder_libs map.
+    expect(context.sourceFactory.forUri('dart:typed_data'), isNotNull);
+  }
+
+  test_error_filter_analysis_option() async {
+    // Create files.
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+
+    // Verify filter setup.
+    expect(errorProcessors, hasLength(1));
+    expect(getProcessor(unused_local_variable).severity, isNull);
+  }
+
+  test_error_filter_analysis_option_multiple_filters() async {
+    // Create files.
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  errors:
+    invalid_assignment: ignore
+    unused_local_variable: error
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+
+    // Verify filter setup.
+    expect(errorProcessors, hasLength(2));
+
+    expect(getProcessor(invalid_assignment_error).severity, isNull);
+    expect(getProcessor(unused_local_variable).severity, ErrorSeverity.ERROR);
+  }
+
+  test_error_filter_analysis_option_synonyms() async {
+    // Create files.
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+    ambiguous_import: false
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+
+    // Verify filter setup.
+    expect(errorProcessors, isNotNull);
+    expect(errorProcessors, hasLength(2));
+  }
+
+  test_error_filter_analysis_option_unpsecified() async {
+    // Create files.
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+#  errors:
+#    unused_local_variable: ignore
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+
+    // Verify filter setup.
+    expect(errorProcessors, isEmpty);
+  }
+
   test_ignoreFilesInPackagesFolder() {
     // create a context with a pubspec.yaml file
     String pubspecPath = posix.join(projPath, 'pubspec.yaml');
@@ -233,7 +580,7 @@
     newFile([sdkExtSrcPath, 'part.dart']);
     // Setup analysis options file with ignore list.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   exclude:
@@ -270,7 +617,7 @@
     // Setup analysis options file with ignore list that ignores the 'other_lib'
     // directory by name.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   exclude:
@@ -306,7 +653,7 @@
     // Setup analysis options file with ignore list that ignores 'other_lib'
     // and all descendants.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   exclude:
@@ -342,7 +689,7 @@
     // Setup analysis options file with ignore list that ignores 'other_lib'
     // and all immediate children.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   exclude:
@@ -490,8 +837,7 @@
     newFile(
         [projPath, '.packages'],
         r'''
-test_pack:lib/
-''');
+test_pack:lib/''');
     // Setup context.
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // Confirm that one context was created.
@@ -928,6 +1274,158 @@
     callbacks.assertContextFiles(project, [fileA, fileB]);
   }
 
+  void test_setRoots_nested_excludedByOuter() {
+    String project = '/project';
+    String projectPubspec = '$project/pubspec.yaml';
+    String example = '$project/example';
+    String examplePubspec = '$example/pubspec.yaml';
+    // create files
+    resourceProvider.newFile(projectPubspec, 'name: project');
+    resourceProvider.newFile(examplePubspec, 'name: example');
+    newFile(
+        [project, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  exclude:
+    - 'example'
+''');
+    manager.setRoots(
+        <String>[project, example], <String>[], <String, String>{});
+    // verify
+    {
+      ContextInfo rootInfo = manager.rootInfo;
+      expect(rootInfo.children, hasLength(1));
+      {
+        ContextInfo projectInfo = rootInfo.children[0];
+        expect(projectInfo.folder.path, project);
+        expect(projectInfo.children, hasLength(1));
+        {
+          ContextInfo exampleInfo = projectInfo.children[0];
+          expect(exampleInfo.folder.path, example);
+          expect(exampleInfo.children, isEmpty);
+        }
+      }
+    }
+    expect(callbacks.currentContextPaths, hasLength(2));
+    expect(callbacks.currentContextPaths, unorderedEquals([project, example]));
+  }
+
+  void test_setRoots_nested_excludedByOuter_deep() {
+    String a = '/a';
+    String c = '$a/b/c';
+    String aPubspec = '$a/pubspec.yaml';
+    String cPubspec = '$c/pubspec.yaml';
+    // create files
+    resourceProvider.newFile(aPubspec, 'name: aaa');
+    resourceProvider.newFile(cPubspec, 'name: ccc');
+    newFile(
+        [a, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  exclude:
+    - 'b**'
+''');
+    manager.setRoots(<String>[a, c], <String>[], <String, String>{});
+    // verify
+    {
+      ContextInfo rootInfo = manager.rootInfo;
+      expect(rootInfo.children, hasLength(1));
+      {
+        ContextInfo aInfo = rootInfo.children[0];
+        expect(aInfo.folder.path, a);
+        expect(aInfo.children, hasLength(1));
+        {
+          ContextInfo cInfo = aInfo.children[0];
+          expect(cInfo.folder.path, c);
+          expect(cInfo.children, isEmpty);
+        }
+      }
+    }
+    expect(callbacks.currentContextPaths, hasLength(2));
+    expect(callbacks.currentContextPaths, unorderedEquals([a, c]));
+  }
+
+  void test_setRoots_nested_includedByOuter_innerFirst() {
+    String project = '/project';
+    String projectPubspec = '$project/pubspec.yaml';
+    String example = '$project/example';
+    String examplePubspec = '$example/pubspec.yaml';
+    // create files
+    resourceProvider.newFile(projectPubspec, 'name: project');
+    resourceProvider.newFile(examplePubspec, 'name: example');
+    manager.setRoots(
+        <String>[example, project], <String>[], <String, String>{});
+    // verify
+    {
+      ContextInfo rootInfo = manager.rootInfo;
+      expect(rootInfo.children, hasLength(1));
+      {
+        ContextInfo projectInfo = rootInfo.children[0];
+        expect(projectInfo.folder.path, project);
+        expect(projectInfo.children, hasLength(1));
+        {
+          ContextInfo exampleInfo = projectInfo.children[0];
+          expect(exampleInfo.folder.path, example);
+          expect(exampleInfo.children, isEmpty);
+        }
+      }
+    }
+    expect(callbacks.currentContextPaths, hasLength(2));
+    expect(callbacks.currentContextPaths, unorderedEquals([project, example]));
+  }
+
+  void test_setRoots_nested_includedByOuter_outerPubspec() {
+    String project = '/project';
+    String projectPubspec = '$project/pubspec.yaml';
+    String example = '$project/example';
+    // create files
+    resourceProvider.newFile(projectPubspec, 'name: project');
+    resourceProvider.newFolder(example);
+    manager.setRoots(
+        <String>[project, example], <String>[], <String, String>{});
+    // verify
+    {
+      ContextInfo rootInfo = manager.rootInfo;
+      expect(rootInfo.children, hasLength(1));
+      {
+        ContextInfo projectInfo = rootInfo.children[0];
+        expect(projectInfo.folder.path, project);
+        expect(projectInfo.children, isEmpty);
+      }
+    }
+    expect(callbacks.currentContextPaths, hasLength(1));
+    expect(callbacks.currentContextPaths, unorderedEquals([project]));
+  }
+
+  void test_setRoots_nested_includedByOuter_twoPubspecs() {
+    String project = '/project';
+    String projectPubspec = '$project/pubspec.yaml';
+    String example = '$project/example';
+    String examplePubspec = '$example/pubspec.yaml';
+    // create files
+    resourceProvider.newFile(projectPubspec, 'name: project');
+    resourceProvider.newFile(examplePubspec, 'name: example');
+    manager.setRoots(
+        <String>[project, example], <String>[], <String, String>{});
+    // verify
+    {
+      ContextInfo rootInfo = manager.rootInfo;
+      expect(rootInfo.children, hasLength(1));
+      {
+        ContextInfo projectInfo = rootInfo.children[0];
+        expect(projectInfo.folder.path, project);
+        expect(projectInfo.children, hasLength(1));
+        {
+          ContextInfo exampleInfo = projectInfo.children[0];
+          expect(exampleInfo.folder.path, example);
+          expect(exampleInfo.children, isEmpty);
+        }
+      }
+    }
+    expect(callbacks.currentContextPaths, hasLength(2));
+    expect(callbacks.currentContextPaths, unorderedEquals([project, example]));
+  }
+
   void test_setRoots_newFolderWithPackageRoot() {
     String packageRootPath = '/package';
     manager.setRoots(<String>[projPath], <String>[],
@@ -1025,9 +1523,11 @@
     resourceProvider.newFile(pubspecPath, '');
     // add one root - there is a context
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    expect(manager.changeSubscriptions, hasLength(1));
     expect(callbacks.currentContextPaths, hasLength(1));
     // set empty roots - no contexts
     manager.setRoots(<String>[], <String>[], <String, String>{});
+    expect(manager.changeSubscriptions, hasLength(0));
     expect(callbacks.currentContextPaths, hasLength(0));
     expect(callbacks.currentContextFilePaths, hasLength(0));
   }
@@ -1146,7 +1646,7 @@
   test_strong_mode_analysis_option() async {
     // Create files.
     newFile(
-        [projPath, '.analysis_options'],
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
 analyzer:
   strong-mode: true
@@ -1809,7 +2309,19 @@
     currentContextSources[path] = new HashSet<Source>();
     currentContextDispositions[path] = disposition;
     currentContext = AnalysisEngine.instance.createAnalysisContext();
+    _locateEmbedderYamls(currentContext, disposition);
     List<UriResolver> resolvers = [];
+    if (currentContext is InternalAnalysisContext) {
+      EmbedderYamlLocator embedderYamlLocator =
+          (currentContext as InternalAnalysisContext).embedderYamlLocator;
+      EmbedderUriResolver embedderUriResolver =
+          new EmbedderUriResolver(embedderYamlLocator.embedderYamls);
+      if (embedderUriResolver.length > 0) {
+        // We have some embedder dart: uri mappings, add the resolver
+        // to the list.
+        resolvers.add(embedderUriResolver);
+      }
+    }
     resolvers.addAll(disposition.createPackageUriResolvers(resourceProvider));
     resolvers.add(new FileUriResolver());
     currentContext.sourceFactory =
@@ -1878,6 +2390,19 @@
       Folder contextFolder, FolderDisposition disposition) {
     currentContextDispositions[contextFolder.path] = disposition;
   }
+
+  /// If [disposition] has a package map, attempt to locate `_embedder.yaml`
+  /// files.
+  void _locateEmbedderYamls(
+      InternalAnalysisContext context, FolderDisposition disposition) {
+    Map<String, List<Folder>> packageMap;
+    if (disposition is PackageMapDisposition) {
+      packageMap = disposition.packageMap;
+    } else if (disposition is PackagesFileDisposition) {
+      packageMap = disposition.buildPackageMap(resourceProvider);
+    }
+    context.embedderYamlLocator.refresh(packageMap);
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 640d2fd..b7f4b34 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -55,6 +55,46 @@
   group('updateContent', testUpdateContent);
 
   group('AnalysisDomainHandler', () {
+    group('getReachableSources', () {
+      test('valid sources', () async {
+        String fileA = '/project/a.dart';
+        String fileB = '/project/b.dart';
+        resourceProvider.newFile(fileA, 'import "b.dart";');
+        resourceProvider.newFile(fileB, '');
+
+        server.setAnalysisRoots('0', ['/project/'], [], {});
+
+        await server.onAnalysisComplete;
+
+        var request =
+            new AnalysisGetReachableSourcesParams(fileA).toRequest('0');
+        var response = handler.handleRequest(request);
+
+        var json = response.toJson()[Response.RESULT];
+
+        // Sanity checks.
+        expect(json['sources'], hasLength(6));
+        expect(json['sources']['file:///project/a.dart'],
+            unorderedEquals(['dart:core', 'file:///project/b.dart']));
+        expect(json['sources']['file:///project/b.dart'], ['dart:core']);
+      });
+
+      test('invalid source', () async {
+        resourceProvider.newFile('/project/a.dart', 'import "b.dart";');
+        server.setAnalysisRoots('0', ['/project/'], [], {});
+
+        await server.onAnalysisComplete;
+
+        var request =
+            new AnalysisGetReachableSourcesParams('/does/not/exist.dart')
+                .toRequest('0');
+        var response = handler.handleRequest(request);
+        expect(response.error, isNotNull);
+        expect(response.error.code,
+            RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE);
+      });
+    });
+
     group('setAnalysisRoots', () {
       Response testSetAnalysisRoots(
           List<String> included, List<String> excluded) {
@@ -79,6 +119,22 @@
             expect(serverRef.getResolvedCompilationUnits(fileB), isEmpty);
           });
         });
+
+        test('not absolute', () async {
+          var response = testSetAnalysisRoots([], ['foo/bar']);
+          expect(
+              response,
+              isResponseFailure(
+                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+        });
+
+        test('not normalized', () async {
+          var response = testSetAnalysisRoots([], ['/foo/../bar']);
+          expect(
+              response,
+              isResponseFailure(
+                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+        });
       });
 
       group('included', () {
@@ -107,6 +163,22 @@
           await server.onAnalysisComplete;
           expect(serverRef.getResolvedCompilationUnits(fileB), hasLength(1));
         });
+
+        test('not absolute', () async {
+          var response = testSetAnalysisRoots(['foo/bar'], []);
+          expect(
+              response,
+              isResponseFailure(
+                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+        });
+
+        test('not normalized', () async {
+          var response = testSetAnalysisRoots(['/foo/../bar'], []);
+          expect(
+              response,
+              isResponseFailure(
+                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+        });
       });
     });
 
@@ -127,8 +199,9 @@
         resourceProvider.newFile('/p2/b.dart', 'library b;');
         resourceProvider.newFile('/p2/c.dart', 'library c;');
 
-        var setRootsRequest = new AnalysisSetAnalysisRootsParams(
-            ['/p1', '/p2'], []).toRequest('0');
+        var setRootsRequest =
+            new AnalysisSetAnalysisRootsParams(['/p1', '/p2'], [])
+                .toRequest('0');
         var setRootsResponse = handler.handleRequest(setRootsRequest);
         expect(setRootsResponse, isResponseSuccess('0'));
 
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index f0d6f83..acff007 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -7,369 +7,26 @@
 import 'dart:async';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/channel/channel.dart';
-import 'package:analysis_server/src/constants.dart';
-import 'package:analysis_server/src/context_manager.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/provisional/completion/completion_core.dart'
-    show CompletionRequest, CompletionResult;
-import 'package:analysis_server/src/provisional/completion/completion_dart.dart'
-    as newApi;
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/contribution_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/index/index.dart' show Index;
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
-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:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
 import 'analysis_abstract.dart';
-import 'mock_sdk.dart';
-import 'mocks.dart';
+import 'domain_completion_util.dart';
 import 'utils.dart';
 
 main() {
   initializeTestEnvironment();
-  defineReflectiveTests(CompletionManagerTest);
-  defineReflectiveTests(CompletionTest);
+  defineReflectiveTests(CompletionDomainHandlerTest);
   defineReflectiveTests(_NoSearchEngine);
 }
 
 @reflectiveTest
-class CompletionManagerTest extends AbstractAnalysisTest {
-  AnalysisDomainHandler analysisDomain;
-  Test_CompletionDomainHandler completionDomain;
-  Request request;
-  int requestCount = 0;
-  String testFile2 = '/project/bin/test2.dart';
-
-  /// Cached model state in case tests need to set task model to on/off.
-  bool wasTaskModelEnabled;
-
-  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,
-        serverPlugin,
-        new AnalysisServerOptions(),
-        new MockSdk(),
-        InstrumentationService.NULL_SERVICE);
-  }
-
-  @override
-  Index createIndex() {
-    return createLocalMemoryIndex();
-  }
-
-  void sendRequest(String path) {
-    String id = (++requestCount).toString();
-    request = new CompletionGetSuggestionsParams(path, 0).toRequest(id);
-    Response response = handler.handleRequest(request);
-    expect(response, isResponseSuccess(id));
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    wasTaskModelEnabled = AnalysisEngine.instance.useTaskModel;
-    AnalysisEngine.instance.useTaskModel = true;
-    createProject();
-    analysisDomain = handler;
-    completionDomain = new Test_CompletionDomainHandler(server);
-    handler = completionDomain;
-    addTestFile('^library A; cl');
-    addFile(testFile2, 'library B; cl');
-  }
-
-  void tearDown() {
-    super.tearDown();
-    analysisDomain = null;
-    completionDomain = null;
-    AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
-  }
-
-  /**
-   * Assert different managers are used for different sources
-   */
-  test_2_requests_different_sources() {
-    expect(completionDomain.manager, isNull);
-    sendRequest(testFile);
-    expect(completionDomain.manager, isNotNull);
-    MockCompletionManager expectedManager = completionDomain.manager;
-    expect(expectedManager.disposeCallCount, 0);
-    expect(completionDomain.mockContext.mockStream.listenCount, 1);
-    expect(completionDomain.mockContext.mockStream.cancelCount, 0);
-    return pumpEventQueue().then((_) {
-      expect(completionDomain.manager, expectedManager);
-      expect(completionDomain.mockManager.computeCallCount, 1);
-      sendRequest(testFile2);
-      expect(completionDomain.manager, isNotNull);
-      expect(completionDomain.manager, isNot(expectedManager));
-      expect(expectedManager.disposeCallCount, 1);
-      expectedManager = completionDomain.manager;
-      expect(completionDomain.mockContext.mockStream.listenCount, 2);
-      expect(completionDomain.mockContext.mockStream.cancelCount, 1);
-      return pumpEventQueue();
-    }).then((_) {
-      expect(completionDomain.manager, expectedManager);
-      expect(completionDomain.mockContext.mockStream.listenCount, 2);
-      expect(completionDomain.mockContext.mockStream.cancelCount, 1);
-      expect(completionDomain.mockManager.computeCallCount, 1);
-    });
-  }
-
-  /**
-   * Assert same manager is used for multiple requests on same source
-   */
-  test_2_requests_same_source() {
-    expect(completionDomain.manager, isNull);
-    sendRequest(testFile);
-    expect(completionDomain.manager, isNotNull);
-    expect(completionDomain.manager.source, isNotNull);
-    CompletionManager expectedManager = completionDomain.manager;
-    expect(completionDomain.mockContext.mockStream.listenCount, 1);
-    expect(completionDomain.mockContext.mockStream.cancelCount, 0);
-    return pumpEventQueue().then((_) {
-      expect(completionDomain.manager, expectedManager);
-      expect(completionDomain.mockManager.computeCallCount, 1);
-      sendRequest(testFile);
-      expect(completionDomain.manager, expectedManager);
-      expect(completionDomain.mockContext.mockStream.listenCount, 1);
-      expect(completionDomain.mockContext.mockStream.cancelCount, 0);
-      return pumpEventQueue();
-    }).then((_) {
-      expect(completionDomain.manager, expectedManager);
-      expect(completionDomain.mockContext.mockStream.listenCount, 1);
-      expect(completionDomain.mockContext.mockStream.cancelCount, 0);
-      expect(completionDomain.mockManager.computeCallCount, 2);
-    });
-  }
-
-  /**
-   * Assert manager is NOT cleared when context NOT associated with manager changes.
-   */
-  test_contextsChanged_different() {
-    sendRequest(testFile);
-    CompletionManager expectedManager;
-    return pumpEventQueue().then((_) {
-      expect(completionDomain.manager, isNotNull);
-      expectedManager = completionDomain.manager;
-      completionDomain.contextsChangedRaw(
-          new ContextsChangedEvent(changed: [new MockContext()]));
-      return pumpEventQueue();
-    }).then((_) {
-      expect(completionDomain.manager, expectedManager);
-    });
-  }
-
-  /**
-   * Assert manager is cleared when context associated with manager changes.
-   */
-  test_contextsChanged_same() {
-    sendRequest(testFile);
-    return pumpEventQueue().then((_) {
-      expect(completionDomain.manager, isNotNull);
-      completionDomain.contextsChangedRaw(
-          new ContextsChangedEvent(changed: [completionDomain.mockContext]));
-      return pumpEventQueue();
-    }).then((_) {
-      expect(completionDomain.manager, isNull);
-    });
-  }
-
-  /**
-   * Assert manager is cleared when analysis roots are set
-   */
-  test_setAnalysisRoots() {
-    sendRequest(testFile);
-    return pumpEventQueue().then((_) {
-      expect(completionDomain.manager, isNotNull);
-      request = new AnalysisSetAnalysisRootsParams([], []).toRequest('7');
-      Response response = analysisDomain.handleRequest(request);
-      expect(response, isResponseSuccess('7'));
-      return pumpEventQueue();
-    }).then((_) {
-      expect(completionDomain.manager, isNull);
-    });
-  }
-
-  /**
-   * Assert manager is cleared when source NOT associated with manager is changed.
-   */
-  test_sourcesChanged_different_source_changed() {
-    sendRequest(testFile);
-    return pumpEventQueue().then((_) {
-      expect(completionDomain.manager, isNotNull);
-      ContextSourcePair contextSource = server.getContextSourcePair(testFile2);
-      ChangeSet changeSet = new ChangeSet();
-      changeSet.changedSource(contextSource.source);
-      completionDomain.sourcesChanged(new SourcesChangedEvent(changeSet));
-      expect(completionDomain.manager, isNull);
-    });
-  }
-
-  /**
-   * Assert manager is NOT cleared when source associated with manager is changed.
-   */
-  test_sourcesChanged_same_source_changed() {
-    sendRequest(testFile);
-    return pumpEventQueue().then((_) {
-      expect(completionDomain.manager, isNotNull);
-      CompletionManager expectedManager = completionDomain.manager;
-      ChangeSet changeSet = new ChangeSet();
-      changeSet.changedSource(completionDomain.manager.source);
-      completionDomain.sourcesChanged(new SourcesChangedEvent(changeSet));
-      expect(completionDomain.manager, expectedManager);
-    });
-  }
-
-  /**
-   * Assert manager is cleared when source is deleted
-   */
-  test_sourcesChanged_source_deleted() {
-    sendRequest(testFile);
-    return pumpEventQueue().then((_) {
-      expect(completionDomain.manager, isNotNull);
-      ChangeSet changeSet = new ChangeSet();
-      changeSet.deletedSource(completionDomain.manager.source);
-      completionDomain.sourcesChanged(new SourcesChangedEvent(changeSet));
-      expect(completionDomain.manager, isNull);
-    });
-  }
-
-  /**
-   * Assert manager is cleared when source is removed
-   */
-  test_sourcesChanged_source_removed() {
-    sendRequest(testFile);
-    return pumpEventQueue().then((_) {
-      expect(completionDomain.manager, isNotNull);
-      ChangeSet changeSet = new ChangeSet();
-      changeSet.removedSource(completionDomain.manager.source);
-      completionDomain.sourcesChanged(new SourcesChangedEvent(changeSet));
-      expect(completionDomain.manager, isNull);
-    });
-  }
-}
-
-@reflectiveTest
-class CompletionTest extends AbstractAnalysisTest {
-  String completionId;
-  int completionOffset;
-  int replacementOffset;
-  int replacementLength;
-  List<CompletionSuggestion> suggestions = [];
-  bool suggestionsDone = false;
-
-  String addTestFile(String content, {int offset}) {
-    completionOffset = content.indexOf('^');
-    if (offset != null) {
-      expect(completionOffset, -1, reason: 'cannot supply offset and ^');
-      completionOffset = offset;
-      return super.addTestFile(content);
-    }
-    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
-    int nextOffset = content.indexOf('^', completionOffset + 1);
-    expect(nextOffset, equals(-1), reason: 'too many ^');
-    return super.addTestFile(content.substring(0, completionOffset) +
-        content.substring(completionOffset + 1));
-  }
-
-  void assertHasResult(CompletionSuggestionKind kind, String completion,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      bool isDeprecated: false,
-      bool isPotential: false,
-      int selectionOffset}) {
-    var cs;
-    suggestions.forEach((s) {
-      if (s.completion == completion) {
-        if (cs == null) {
-          cs = s;
-        } else {
-          fail('expected exactly one $completion but found > 1');
-        }
-      }
-    });
-    if (cs == null) {
-      var completions = suggestions.map((s) => s.completion).toList();
-      fail('expected "$completion" but found\n $completions');
-    }
-    expect(cs.kind, equals(kind));
-    expect(cs.relevance, equals(relevance));
-    expect(cs.selectionOffset, selectionOffset ?? completion.length);
-    expect(cs.selectionLength, equals(0));
-    expect(cs.isDeprecated, equals(isDeprecated));
-    expect(cs.isPotential, equals(isPotential));
-  }
-
-  void assertNoResult(String completion) {
-    if (suggestions.any((cs) => cs.completion == completion)) {
-      fail('did not expect completion: $completion');
-    }
-  }
-
-  void assertValidId(String id) {
-    expect(id, isNotNull);
-    expect(id.isNotEmpty, isTrue);
-  }
-
-  @override
-  Index createIndex() {
-    return createLocalMemoryIndex();
-  }
-
-  Future getSuggestions() {
-    return waitForTasksFinished().then((_) {
-      Request request = new CompletionGetSuggestionsParams(
-          testFile, completionOffset).toRequest('0');
-      Response response = handleSuccessfulRequest(request);
-      completionId = response.id;
-      assertValidId(completionId);
-      return pumpEventQueue().then((_) {
-        expect(suggestionsDone, isTrue);
-      });
-    });
-  }
-
-  void processNotification(Notification notification) {
-    if (notification.event == COMPLETION_RESULTS) {
-      var params = new CompletionResultsParams.fromNotification(notification);
-      String id = params.id;
-      assertValidId(id);
-      if (id == completionId) {
-        expect(suggestionsDone, isFalse);
-        replacementOffset = params.replacementOffset;
-        replacementLength = params.replacementLength;
-        suggestionsDone = params.isLast;
-        expect(suggestionsDone, isNotNull);
-        suggestions = params.results;
-      }
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    createProject();
-    handler = new CompletionDomainHandler(server);
-  }
-
+class CompletionDomainHandlerTest extends AbstractCompletionDomainTest {
   test_html() {
     testFile = '/project/web/test.html';
     addTestFile('''
@@ -464,12 +121,25 @@
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
       assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
+      assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
       assertNoResult('HtmlElement');
       assertNoResult('test');
     });
   }
 
+  test_imports_prefixed2() {
+    addTestFile('''
+      import 'dart:html' as foo;
+      main() {foo.^}
+    ''');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset));
+      expect(replacementLength, equals(0));
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
+      assertNoResult('test');
+    });
+  }
+
   test_invocation() {
     addTestFile('class A {b() {}} main() {A a; a.^}');
     return getSuggestions().then((_) {
@@ -480,15 +150,15 @@
   }
 
   test_invocation_sdk_relevancy_off() {
-    var originalSorter = DartCompletionManager.defaultContributionSorter;
+    var originalSorter = DartCompletionManager.contributionSorter;
     var mockSorter = new MockRelevancySorter();
-    DartCompletionManager.defaultContributionSorter = mockSorter;
+    DartCompletionManager.contributionSorter = mockSorter;
     addTestFile('main() {Map m; m.^}');
     return getSuggestions().then((_) {
       // Assert that the CommonUsageComputer has been replaced
       expect(suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE),
           isFalse);
-      DartCompletionManager.defaultContributionSorter = originalSorter;
+      DartCompletionManager.contributionSorter = originalSorter;
       mockSorter.enabled = false;
     });
   }
@@ -511,6 +181,102 @@
     });
   }
 
+  test_inComment_block_beforeNode() async {
+    addTestFile('''
+  main(aaa, bbb) {
+    /* text ^ */
+    print(42);
+  }
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inComment_endOfLine_beforeNode() async {
+    addTestFile('''
+  main(aaa, bbb) {
+    // text ^
+    print(42);
+  }
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inComment_endOfLine_beforeToken() async {
+    addTestFile('''
+  main(aaa, bbb) {
+    // text ^
+  }
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inDartDoc1() async {
+    addTestFile('''
+  /// ^
+  main(aaa, bbb) {}
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inDartDoc2() async {
+    addTestFile('''
+  /// Some text^
+  main(aaa, bbb) {}
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inDartDoc_reference1() async {
+    addFile(
+        '/testA.dart',
+        '''
+  part of libA;
+  foo(bar) => 0;''');
+    addTestFile('''
+  library libA;
+  part "/testA.dart";
+  import "dart:math";
+  /// The [^]
+  main(aaa, bbb) {}
+  ''');
+    await getSuggestions();
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'min');
+  }
+
+  test_inDartDoc_reference2() async {
+    addTestFile('''
+  /// The [m^]
+  main(aaa, bbb) {}
+  ''');
+    await getSuggestions();
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+  }
+
+  test_inherited() {
+    addFile('/libA.dart', 'class A {m() {}}');
+    addTestFile('''
+import '/libA.dart';
+class B extends A {
+  x() {^}
+}
+''');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset));
+      expect(replacementLength, equals(0));
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
+    });
+  }
+
   test_keyword() {
     addTestFile('library A; cl^');
     return getSuggestions().then((_) {
@@ -533,6 +299,23 @@
     });
   }
 
+  test_local_override() {
+    addFile('/libA.dart', 'class A {m() {}}');
+    addTestFile('''
+import '/libA.dart';
+class B extends A {
+  m() {}
+  x() {^}
+}
+''');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset));
+      expect(replacementLength, equals(0));
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
+          relevance: DART_RELEVANCE_LOCAL_METHOD);
+    });
+  }
+
   test_locals() {
     addTestFile('class A {var a; x() {var b;^}} class DateTime { }');
     return getSuggestions().then((_) {
@@ -551,12 +334,12 @@
 
   test_offset_past_eof() {
     addTestFile('main() { }', offset: 300);
-    return getSuggestions().then((_) {
-      expect(replacementOffset, equals(300));
-      expect(replacementLength, equals(0));
-      expect(suggestionsDone, true);
-      expect(suggestions.length, 0);
-    });
+    Request request =
+        new CompletionGetSuggestionsParams(testFile, completionOffset)
+            .toRequest('0');
+    Response response = handler.handleRequest(request);
+    expect(response.id, '0');
+    expect(response.error.code, RequestErrorCode.INVALID_PARAMETER);
   }
 
   test_overrides() {
@@ -632,6 +415,16 @@
     });
   }
 
+  test_static() {
+    addTestFile('class A {static b() {} c() {}} main() {A.^}');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset));
+      expect(replacementLength, equals(0));
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
+      assertNoResult('c');
+    });
+  }
+
   test_topLevel() {
     addTestFile('''
       typedef foo();
@@ -650,182 +443,16 @@
   }
 }
 
-class MockCache extends CompletionCache {
-  MockCache(AnalysisContext context, Source source) : super(context, source);
-}
-
-class MockCompletionManager implements CompletionManager {
-  final AnalysisContext context;
-  final Source source;
-  final SearchEngine searchEngine;
-  StreamController<CompletionResult> controller;
-  int computeCallCount = 0;
-  int disposeCallCount = 0;
-
-  MockCompletionManager(this.context, this.source, this.searchEngine);
-
-  @override
-  Future<bool> computeCache() {
-    return new Future.value(true);
-  }
-
-  @override
-  void computeSuggestions(CompletionRequest request) {
-    ++computeCallCount;
-    CompletionResult result = new CompletionResultImpl(0, 0, [], true);
-    controller.add(result);
-  }
-
-  @override
-  void dispose() {
-    ++disposeCallCount;
-  }
-
-  @override
-  Stream<CompletionResult> results(CompletionRequest request) {
-    controller = new StreamController<CompletionResult>(onListen: () {
-      scheduleMicrotask(() {
-        computeSuggestions(request);
-      });
-    });
-    return controller.stream;
-  }
-}
-
-/**
- * Mock [AnaysisContext] for tracking usage of onSourcesChanged.
- */
-class MockContext implements AnalysisContext {
-  static final SourceFactory DEFAULT_SOURCE_FACTORY = new SourceFactory([]);
-
-  MockStream<SourcesChangedEvent> mockStream;
-
-  SourceFactory sourceFactory = DEFAULT_SOURCE_FACTORY;
-
-  MockContext() {
-    mockStream = new MockStream<SourcesChangedEvent>();
-  }
-
-  @override
-  Stream<SourcesChangedEvent> get onSourcesChanged => mockStream;
-
-  @override
-  bool exists(Source source) {
-    return source != null && source.exists();
-  }
-
-  @override
-  TimestampedData<String> getContents(Source source) {
-    return source.contents;
-  }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-class MockRelevancySorter implements ContributionSorter {
+class MockRelevancySorter implements DartContributionSorter {
   bool enabled = true;
 
   @override
-  void sort(newApi.DartCompletionRequest request,
-      List<CompletionSuggestion> suggestions) {
+  Future sort(
+      CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
     if (!enabled) {
       throw 'unexpected sort';
     }
-  }
-}
-
-/**
- * Mock stream for tracking calls to listen and subscription.cancel.
- */
-class MockStream<E> implements Stream<E> {
-  MockSubscription<E> mockSubscription = new MockSubscription<E>();
-  int listenCount = 0;
-
-  int get cancelCount => mockSubscription.cancelCount;
-
-  @override
-  StreamSubscription<E> listen(void onData(E event),
-      {Function onError, void onDone(), bool cancelOnError}) {
-    ++listenCount;
-    return mockSubscription;
-  }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/**
- * Mock subscription for tracking calls to subscription.cancel.
- */
-class MockSubscription<E> implements StreamSubscription<E> {
-  int cancelCount = 0;
-
-  Future cancel() {
-    ++cancelCount;
-    return new Future.value(true);
-  }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-class Test_AnalysisServer extends AnalysisServer {
-  final MockContext mockContext = new MockContext();
-
-  Test_AnalysisServer(
-      ServerCommunicationChannel channel,
-      ResourceProvider resourceProvider,
-      PubPackageMapProvider packageMapProvider,
-      Index index,
-      ServerPlugin serverPlugin,
-      AnalysisServerOptions analysisServerOptions,
-      DartSdk defaultSdk,
-      InstrumentationService instrumentationService)
-      : super(
-            channel,
-            resourceProvider,
-            packageMapProvider,
-            index,
-            serverPlugin,
-            analysisServerOptions,
-            defaultSdk,
-            instrumentationService);
-
-  @override
-  AnalysisContext getAnalysisContext(String path) {
-    return mockContext;
-  }
-
-  @override
-  ContextSourcePair getContextSourcePair(String path) {
-    ContextSourcePair pair = super.getContextSourcePair(path);
-    return new ContextSourcePair(mockContext, pair.source);
-  }
-}
-
-/**
- * A [CompletionDomainHandler] subclass that returns a mock completion manager
- * so that the domain handler cache management can be tested.
- */
-class Test_CompletionDomainHandler extends CompletionDomainHandler {
-  Test_CompletionDomainHandler(Test_AnalysisServer server) : super(server);
-
-  MockContext get mockContext => (server as Test_AnalysisServer).mockContext;
-
-  MockCompletionManager get mockManager => manager;
-
-  void contextsChanged(ContextsChangedEvent event) {
-    contextsChangedRaw(new ContextsChangedEvent(
-        added: event.added.length > 0 ? [mockContext] : [],
-        changed: event.changed.length > 0 ? [mockContext] : [],
-        removed: event.removed.length > 0 ? [mockContext] : []));
-  }
-
-  void contextsChangedRaw(ContextsChangedEvent newEvent) {
-    super.contextsChanged(newEvent);
-  }
-
-  CompletionManager createCompletionManager(
-      AnalysisContext context, Source source, SearchEngine searchEngine) {
-    return new MockCompletionManager(mockContext, source, searchEngine);
+    return new Future.value();
   }
 }
 
diff --git a/pkg/analysis_server/test/domain_completion_util.dart b/pkg/analysis_server/test/domain_completion_util.dart
new file mode 100644
index 0000000..29cff99
--- /dev/null
+++ b/pkg/analysis_server/test/domain_completion_util.dart
@@ -0,0 +1,123 @@
+// 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 test.domain.completion;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/constants.dart';
+import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/index/index.dart' show Index;
+import 'package:analysis_server/src/services/index/local_memory_index.dart';
+import 'package:unittest/unittest.dart';
+
+import 'analysis_abstract.dart';
+import 'mocks.dart';
+
+class AbstractCompletionDomainTest extends AbstractAnalysisTest {
+  String completionId;
+  int completionOffset;
+  int replacementOffset;
+  int replacementLength;
+  List<CompletionSuggestion> suggestions = [];
+  bool suggestionsDone = false;
+
+  String addTestFile(String content, {int offset}) {
+    completionOffset = content.indexOf('^');
+    if (offset != null) {
+      expect(completionOffset, -1, reason: 'cannot supply offset and ^');
+      completionOffset = offset;
+      return super.addTestFile(content);
+    }
+    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
+    int nextOffset = content.indexOf('^', completionOffset + 1);
+    expect(nextOffset, equals(-1), reason: 'too many ^');
+    return super.addTestFile(content.substring(0, completionOffset) +
+        content.substring(completionOffset + 1));
+  }
+
+  void assertHasResult(CompletionSuggestionKind kind, String completion,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      bool isDeprecated: false,
+      bool isPotential: false,
+      int selectionOffset}) {
+    var cs;
+    suggestions.forEach((s) {
+      if (s.completion == completion) {
+        if (cs == null) {
+          cs = s;
+        } else {
+          fail('expected exactly one $completion but found > 1');
+        }
+      }
+    });
+    if (cs == null) {
+      var completions = suggestions.map((s) => s.completion).toList();
+      fail('expected "$completion" but found\n $completions');
+    }
+    expect(cs.kind, equals(kind));
+    expect(cs.relevance, equals(relevance));
+    expect(cs.selectionOffset, selectionOffset ?? completion.length);
+    expect(cs.selectionLength, equals(0));
+    expect(cs.isDeprecated, equals(isDeprecated));
+    expect(cs.isPotential, equals(isPotential));
+  }
+
+  void assertNoResult(String completion) {
+    if (suggestions.any((cs) => cs.completion == completion)) {
+      fail('did not expect completion: $completion');
+    }
+  }
+
+  void assertValidId(String id) {
+    expect(id, isNotNull);
+    expect(id.isNotEmpty, isTrue);
+  }
+
+  @override
+  Index createIndex() {
+    return createLocalMemoryIndex();
+  }
+
+  Future getSuggestions() {
+    return waitForTasksFinished().then((_) {
+      Request request =
+          new CompletionGetSuggestionsParams(testFile, completionOffset)
+              .toRequest('0');
+      Response response = handleSuccessfulRequest(request);
+      completionId = response.id;
+      assertValidId(completionId);
+      return pumpEventQueue().then((_) {
+        expect(suggestionsDone, isTrue);
+      });
+    });
+  }
+
+  void processNotification(Notification notification) {
+    if (notification.event == COMPLETION_RESULTS) {
+      var params = new CompletionResultsParams.fromNotification(notification);
+      String id = params.id;
+      assertValidId(id);
+      if (id == completionId) {
+        expect(suggestionsDone, isFalse);
+        replacementOffset = params.replacementOffset;
+        replacementLength = params.replacementLength;
+        suggestionsDone = params.isLast;
+        expect(suggestionsDone, isNotNull);
+        suggestions = params.results;
+      }
+    } else if (notification.event == SERVER_ERROR) {
+      fail('server error: ${notification.toJson()}');
+    }
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    createProject();
+    handler = new CompletionDomainHandler(server);
+  }
+}
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
new file mode 100644
index 0000000..f234463
--- /dev/null
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -0,0 +1,92 @@
+// 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 test.domain.diagnostic;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domain_diagnostic.dart';
+import 'package:analysis_server/src/plugin/server_plugin.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
+import 'package:unittest/unittest.dart';
+
+import 'mock_sdk.dart';
+import 'mocks.dart';
+import 'utils.dart';
+
+main() {
+  AnalysisServer server;
+  DiagnosticDomainHandler handler;
+  MemoryResourceProvider resourceProvider;
+
+  initializeTestEnvironment();
+
+  setUp(() {
+    //
+    // Collect plugins
+    //
+    ServerPlugin serverPlugin = new ServerPlugin();
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    plugins.add(serverPlugin);
+    //
+    // Process plugins
+    //
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+    //
+    // Create the server
+    //
+    var serverChannel = new MockServerChannel();
+    resourceProvider = new MemoryResourceProvider();
+    server = new AnalysisServer(
+        serverChannel,
+        resourceProvider,
+        new MockPackageMapProvider(),
+        null,
+        serverPlugin,
+        new AnalysisServerOptions(),
+        new MockSdk(),
+        InstrumentationService.NULL_SERVICE);
+    handler = new DiagnosticDomainHandler(server);
+  });
+
+  group('DiagnosticDomainHandler', () {
+    test('getDiagnostics', () async {
+      String file = '/project/bin/test.dart';
+      resourceProvider.newFile('/project/pubspec.yaml', 'name: project');
+      resourceProvider.newFile(file, 'main() {}');
+
+      server.setAnalysisRoots('0', ['/project/'], [], {});
+
+      await server.onAnalysisComplete;
+
+      var request = new DiagnosticGetDiagnosticsParams().toRequest('0');
+      var response = handler.handleRequest(request);
+
+      int fileCount = MockSdk.LIBRARIES.length + 1 /* test.dart */;
+
+      var json = response.toJson()[Response.RESULT];
+      expect(json['contexts'], hasLength(1));
+      var context = json['contexts'][0];
+      expect(context['name'], '/project');
+      expect(context['explicitFileCount'], fileCount);
+      expect(context['implicitFileCount'], 0);
+      expect(context['workItemQueueLength'], isNotNull);
+    });
+
+    test('getDiagnostics - (no root)', () async {
+      var request = new DiagnosticGetDiagnosticsParams().toRequest('0');
+      var response = handler.handleRequest(request);
+      var json = response.toJson()[Response.RESULT];
+      expect(json['contexts'], hasLength(0));
+    });
+  });
+}
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 927d46d..a142adb 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -19,9 +19,11 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.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';
 
+import 'analysis_abstract.dart';
 import 'mock_sdk.dart';
 import 'mocks.dart';
 import 'operation/operation_queue_test.dart';
@@ -29,6 +31,7 @@
 
 main() {
   initializeTestEnvironment();
+  defineReflectiveTests(ExecutionDomainTest);
   group('ExecutionDomainHandler', () {
     MemoryResourceProvider provider = new MemoryResourceProvider();
     AnalysisServer server;
@@ -90,6 +93,15 @@
     group('mapUri', () {
       String contextId;
 
+      void createExecutionContextIdForFile(String path) {
+        Request request = new ExecutionCreateContextParams(path).toRequest('0');
+        Response response = handler.handleRequest(request);
+        expect(response, isResponseSuccess('0'));
+        ExecutionCreateContextResult result =
+            new ExecutionCreateContextResult.fromResponse(response);
+        contextId = result.id;
+      }
+
       setUp(() {
         Folder folder = provider.newFile('/a/b.dart', '').parent;
         server.folderMap.putIfAbsent(folder, () {
@@ -100,13 +112,7 @@
           context.sourceFactory = factory;
           return context;
         });
-        Request request =
-            new ExecutionCreateContextParams('/a/b.dart').toRequest('0');
-        Response response = handler.handleRequest(request);
-        expect(response, isResponseSuccess('0'));
-        ExecutionCreateContextResult result =
-            new ExecutionCreateContextResult.fromResponse(response);
-        contextId = result.id;
+        createExecutionContextIdForFile('/a/b.dart');
       });
 
       tearDown(() {
@@ -131,17 +137,6 @@
           Response response = handler.handleRequest(request);
           expect(response, isResponseFailure('2'));
         });
-
-        test('valid', () {
-          Request request = new ExecutionMapUriParams(contextId,
-              file: '/a/b.dart').toRequest('2');
-          Response response = handler.handleRequest(request);
-          expect(response, isResponseSuccess('2'));
-          ExecutionMapUriResult result =
-              new ExecutionMapUriResult.fromResponse(response);
-          expect(result.file, isNull);
-          expect(result.uri, 'file:///a/b.dart');
-        });
       });
 
       group('URI to file', () {
@@ -151,17 +146,6 @@
           Response response = handler.handleRequest(request);
           expect(response, isResponseFailure('2'));
         });
-
-        test('valid', () {
-          Request request = new ExecutionMapUriParams(contextId,
-              uri: 'file:///a/b.dart').toRequest('2');
-          Response response = handler.handleRequest(request);
-          expect(response, isResponseSuccess('2'));
-          ExecutionMapUriResult result =
-              new ExecutionMapUriResult.fromResponse(response);
-          expect(result.file, '/a/b.dart');
-          expect(result.uri, isNull);
-        });
       });
 
       test('invalid context id', () {
@@ -287,35 +271,74 @@
   });
 }
 
-/**
- * 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].
- */
-class IsExecutableFile extends Matcher {
-  String expectedFile;
-  ExecutableKind expectedKind;
-
-  IsExecutableFile(this.expectedFile, this.expectedKind);
+@reflectiveTest
+class ExecutionDomainTest extends AbstractAnalysisTest {
+  String contextId;
 
   @override
-  Description describe(Description description) {
-    return description.add('ExecutableFile($expectedFile, $expectedKind)');
+  void setUp() {
+    super.setUp();
+    createProject();
+    handler = new ExecutionDomainHandler(server);
+    _createExecutionContext(testFile);
   }
 
   @override
-  bool matches(item, Map matchState) {
-    if (item is! ExecutableFile) {
-      return false;
-    }
-    return item.file == expectedFile && item.kind == expectedKind;
+  void tearDown() {
+    super.tearDown();
+    _disposeExecutionContext();
+  }
+
+  void test_mapUri_file() {
+    String path = '/a/b.dart';
+    resourceProvider.newFile(path, '');
+    // map the file
+    ExecutionMapUriResult result = _mapUri(file: path);
+    expect(result.file, isNull);
+    expect(result.uri, 'file:///a/b.dart');
+  }
+
+  void test_mapUri_file_dartUriKind() {
+    String path = server.defaultSdk.mapDartUri('dart:async').fullName;
+    // hack - pretend that the SDK file exists in the project FS
+    resourceProvider.newFile(path, '// hack');
+    // map file
+    ExecutionMapUriResult result = _mapUri(file: path);
+    expect(result.file, isNull);
+    expect(result.uri, 'dart:async');
+  }
+
+  void test_mapUri_uri() {
+    String path = '/a/b.dart';
+    resourceProvider.newFile(path, '');
+    // map the uri
+    ExecutionMapUriResult result = _mapUri(uri: 'file://$path');
+    expect(result.file, '/a/b.dart');
+    expect(result.uri, isNull);
+  }
+
+  void _createExecutionContext(String path) {
+    Request request = new ExecutionCreateContextParams(path).toRequest('0');
+    Response response = handler.handleRequest(request);
+    expect(response, isResponseSuccess('0'));
+    ExecutionCreateContextResult result =
+        new ExecutionCreateContextResult.fromResponse(response);
+    contextId = result.id;
+  }
+
+  void _disposeExecutionContext() {
+    Request request =
+        new ExecutionDeleteContextParams(contextId).toRequest('1');
+    Response response = handler.handleRequest(request);
+    expect(response, isResponseSuccess('1'));
+  }
+
+  ExecutionMapUriResult _mapUri({String file, String uri}) {
+    Request request = new ExecutionMapUriParams(contextId, file: file, uri: uri)
+        .toRequest('2');
+    Response response = handler.handleRequest(request);
+    expect(response, isResponseSuccess('2'));
+    return new ExecutionMapUriResult.fromResponse(response);
   }
 }
 
diff --git a/pkg/analysis_server/test/edit/assists_test.dart b/pkg/analysis_server/test/edit/assists_test.dart
index b6572c4..538a04e 100644
--- a/pkg/analysis_server/test/edit/assists_test.dart
+++ b/pkg/analysis_server/test/edit/assists_test.dart
@@ -4,8 +4,6 @@
 
 library test.edit.assists;
 
-import 'dart:async';
-
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:plugin/manager.dart';
@@ -24,15 +22,15 @@
 class AssistsTest extends AbstractAnalysisTest {
   List<SourceChange> changes;
 
-  void prepareAssists(String search, [int length = 0]) {
+  prepareAssists(String search, [int length = 0]) async {
     int offset = findOffset(search);
-    prepareAssistsAt(offset, length);
+    await prepareAssistsAt(offset, length);
   }
 
-  void prepareAssistsAt(int offset, int length) {
+  prepareAssistsAt(int offset, int length) async {
     Request request =
         new EditGetAssistsParams(testFile, offset, length).toRequest('0');
-    Response response = handleSuccessfulRequest(request);
+    Response response = await waitResponse(request);
     var result = new EditGetAssistsResult.fromResponse(response);
     changes = result.assists;
   }
@@ -46,14 +44,14 @@
     handler = new EditDomainHandler(server);
   }
 
-  Future test_removeTypeAnnotation() async {
+  test_removeTypeAnnotation() async {
     addTestFile('''
 main() {
   int v = 1;
 }
 ''');
     await waitForTasksFinished();
-    prepareAssists('v =');
+    await prepareAssists('v =');
     _assertHasChange(
         'Remove type annotation',
         '''
@@ -63,14 +61,14 @@
 ''');
   }
 
-  Future test_splitVariableDeclaration() async {
+  test_splitVariableDeclaration() async {
     addTestFile('''
 main() {
   int v = 1;
 }
 ''');
     await waitForTasksFinished();
-    prepareAssists('v =');
+    await prepareAssists('v =');
     _assertHasChange(
         'Split variable declaration',
         '''
@@ -81,7 +79,7 @@
 ''');
   }
 
-  Future test_surroundWithIf() async {
+  test_surroundWithIf() async {
     addTestFile('''
 main() {
   print(1);
@@ -91,7 +89,7 @@
     await waitForTasksFinished();
     int offset = findOffset('  print(1)');
     int length = findOffset('}') - offset;
-    prepareAssistsAt(offset, length);
+    await prepareAssistsAt(offset, length);
     _assertHasChange(
         "Surround with 'if'",
         '''
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 531bf43..fb2ee76 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -33,14 +33,14 @@
     handler = new EditDomainHandler(server);
   }
 
-  Future test_fixUndefinedClass() async {
+  test_fixUndefinedClass() async {
     addTestFile('''
 main() {
   Future<String> x = null;
 }
 ''');
     await waitForTasksFinished();
-    List<AnalysisErrorFixes> errorFixes = _getFixesAt('Future<String>');
+    List<AnalysisErrorFixes> errorFixes = await _getFixesAt('Future<String>');
     expect(errorFixes, hasLength(1));
     AnalysisError error = errorFixes[0].error;
     expect(error.severity, AnalysisErrorSeverity.WARNING);
@@ -51,7 +51,7 @@
     expect(fixes[1].message, matches('Create class'));
   }
 
-  Future test_hasFixes() async {
+  test_hasFixes() async {
     addTestFile('''
 foo() {
   print(1)
@@ -63,20 +63,20 @@
     await waitForTasksFinished();
     // print(1)
     {
-      List<AnalysisErrorFixes> errorFixes = _getFixesAt('print(1)');
+      List<AnalysisErrorFixes> errorFixes = await _getFixesAt('print(1)');
       expect(errorFixes, hasLength(1));
       _isSyntacticErrorWithSingleFix(errorFixes[0]);
     }
     // print(10)
     {
-      List<AnalysisErrorFixes> errorFixes = _getFixesAt('print(10)');
+      List<AnalysisErrorFixes> errorFixes = await _getFixesAt('print(10)');
       expect(errorFixes, hasLength(2));
       _isSyntacticErrorWithSingleFix(errorFixes[0]);
       _isSyntacticErrorWithSingleFix(errorFixes[1]);
     }
   }
 
-  Future test_overlayOnlyFile() async {
+  test_overlayOnlyFile() async {
     // add an overlay-only file
     {
       testCode = '''
@@ -92,21 +92,21 @@
     }
     // ask for fixes
     await waitForTasksFinished();
-    List<AnalysisErrorFixes> errorFixes = _getFixesAt('print(1)');
+    List<AnalysisErrorFixes> errorFixes = await _getFixesAt('print(1)');
     expect(errorFixes, hasLength(1));
     _isSyntacticErrorWithSingleFix(errorFixes[0]);
   }
 
-  List<AnalysisErrorFixes> _getFixes(int offset) {
+  Future<List<AnalysisErrorFixes>> _getFixes(int offset) async {
     Request request = new EditGetFixesParams(testFile, offset).toRequest('0');
-    Response response = handleSuccessfulRequest(request);
+    Response response = await waitResponse(request);
     var result = new EditGetFixesResult.fromResponse(response);
     return result.fixes;
   }
 
-  List<AnalysisErrorFixes> _getFixesAt(String search) {
+  Future<List<AnalysisErrorFixes>> _getFixesAt(String search) async {
     int offset = findOffset(search);
-    return _getFixes(offset);
+    return await _getFixes(offset);
   }
 
   void _isSyntacticErrorWithSingleFix(AnalysisErrorFixes fixes) {
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index 0cc4971..fcb0568 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -275,6 +275,26 @@
     super.tearDown();
   }
 
+  test_coveringExpressions() {
+    addTestFile('''
+main() {
+  var v = 111 + 222 + 333;
+}
+''');
+    return getRefactoringResult(() {
+      return sendExtractRequest(testCode.indexOf('222 +'), 0, 'res', true);
+    }).then((result) {
+      ExtractLocalVariableFeedback feedback = result.feedback;
+      expect(feedback.coveringExpressionOffsets, [
+        testCode.indexOf('222 +'),
+        testCode.indexOf('111 +'),
+        testCode.indexOf('111 +')
+      ]);
+      expect(feedback.coveringExpressionLengths,
+          ['222'.length, '111 + 222'.length, '111 + 222 + 333'.length]);
+    });
+  }
+
   test_extractAll() {
     addTestFile('''
 main() {
@@ -1881,7 +1901,7 @@
     await waitForTasksFinished();
     Request request =
         new EditGetAvailableRefactoringsParams(testFile, 0, 0).toRequest('0');
-    return _assertErrorResposeNoIndex(request);
+    return _assertErrorResponseNoIndex(request);
   }
 
   test_getRefactoring_noSearchEngine() async {
@@ -1894,10 +1914,10 @@
     Request request = new EditGetRefactoringParams(
             RefactoringKind.EXTRACT_LOCAL_VARIABLE, testFile, 0, 0, true)
         .toRequest('0');
-    return _assertErrorResposeNoIndex(request);
+    return _assertErrorResponseNoIndex(request);
   }
 
-  _assertErrorResposeNoIndex(Request request) async {
+  _assertErrorResponseNoIndex(Request request) async {
     Response response = await serverChannel.sendRequest(request);
     expect(response.error, isNotNull);
     expect(response.error.code, RequestErrorCode.NO_INDEX_GENERATED);
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index 8bae43f..a955360 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -34,8 +34,7 @@
     handler = new EditDomainHandler(server);
   }
 
-  Future test_BAD_doesNotExist() async {
-    await waitForTasksFinished();
+  test_BAD_doesNotExist() async {
     Request request =
         new EditSortMembersParams('/no/such/file.dart').toRequest('0');
     Response response = handler.handleRequest(request);
@@ -43,21 +42,19 @@
         isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
   }
 
-  Future test_BAD_hasParseError() async {
+  test_BAD_hasParseError() async {
     addTestFile('''
 main() {
   print()
 }
 ''');
-    await waitForTasksFinished();
     Request request = new EditSortMembersParams(testFile).toRequest('0');
     Response response = handler.handleRequest(request);
     expect(response,
         isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_PARSE_ERRORS));
   }
 
-  Future test_BAD_notDartFile() async {
-    await waitForTasksFinished();
+  test_BAD_notDartFile() async {
     Request request =
         new EditSortMembersParams('/not-a-Dart-file.txt').toRequest('0');
     Response response = handler.handleRequest(request);
@@ -65,7 +62,21 @@
         isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
   }
 
-  Future test_OK_classMembers_method() {
+  test_OK_afterWaitForAnalysis() async {
+    addTestFile('''
+class C {}
+class A {}
+class B {}
+''');
+    await waitForTasksFinished();
+    return _assertSorted(r'''
+class A {}
+class B {}
+class C {}
+''');
+  }
+
+  test_OK_classMembers_method() async {
     addTestFile('''
 class A {
   c() {}
@@ -82,7 +93,7 @@
 ''');
   }
 
-  Future test_OK_directives() {
+  test_OK_directives() async {
     addTestFile('''
 library lib;
 
@@ -133,7 +144,7 @@
 ''');
   }
 
-  Future test_OK_unitMembers_class() {
+  test_OK_unitMembers_class() async {
     addTestFile('''
 class C {}
 class A {}
@@ -147,7 +158,6 @@
   }
 
   Future _assertSorted(String expectedCode) async {
-    await waitForTasksFinished();
     _requestSort();
     String resultCode = SourceEdit.applySequence(testCode, fileEdit.edits);
     expect(resultCode, expectedCode);
diff --git a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
index c1cabe0..33ad500 100644
--- a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
@@ -1,4 +1,4 @@
-// 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.
 
diff --git a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
index b42cd9e..076ae9d 100644
--- a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
@@ -150,13 +150,13 @@
       tests.add(checkHover('topLevelVar;', 11, ['List', 'topLevelVar'],
           'top level variable', ['List']));
       tests.add(checkHover(
-          'func(', 4, ['func', 'int', 'param'], 'function', ['int', 'void'],
+          'func(', 4, ['func', 'int', 'param'], 'function', null,
           docRegexp: 'Documentation for func'));
-      tests.add(checkHover('int param', 3, ['int'], 'class', ['int'],
+      tests.add(checkHover('int param', 3, ['int'], 'class', null,
           isCore: true, docRegexp: '.*'));
       tests.add(checkHover('param)', 5, ['int', 'param'], 'parameter', ['int'],
           isLocal: true, docRegexp: 'Documentation for func'));
-      tests.add(checkHover('num localVar', 3, ['num'], 'class', ['num'],
+      tests.add(checkHover('num localVar', 3, ['num'], 'class', null,
           isCore: true, docRegexp: '.*'));
       tests.add(checkHover(
           'localVar =', 8, ['num', 'localVar'], 'local variable', ['num'],
@@ -164,10 +164,10 @@
       tests.add(checkHover('topLevelVar.length;', 11, ['List', 'topLevelVar'],
           'top level variable', ['List']));
       tests.add(checkHover(
-          'length;', 6, ['get', 'length', 'int'], 'getter', ['int'],
+          'length;', 6, ['get', 'length', 'int'], 'getter', null,
           isCore: true, docRegexp: '.*'));
       tests.add(checkHover(
-          'length =', 6, ['set', 'length', 'int'], 'setter', ['int'],
+          'length =', 6, ['set', 'length', 'int'], 'setter', null,
           isCore: true, docRegexp: '.*'));
       tests.add(checkHover('param;', 5, ['int', 'param'], 'parameter', ['int'],
           isLocal: true,
diff --git a/pkg/analysis_server/test/integration/integration_test_methods.dart b/pkg/analysis_server/test/integration/integration_test_methods.dart
index bfe19dd..af165f2 100644
--- a/pkg/analysis_server/test/integration/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/integration_test_methods.dart
@@ -238,6 +238,41 @@
   }
 
   /**
+   * Return the transitive closure of reachable sources for a given file.
+   *
+   * If a request is made for a file which does not exist, or which is not
+   * currently subject to analysis (e.g. because it is not associated with any
+   * analysis root specified to analysis.setAnalysisRoots), an error of type
+   * GET_REACHABLE_SOURCES_INVALID_FILE will be generated.
+   *
+   * Parameters
+   *
+   * file ( FilePath )
+   *
+   *   The file for which reachable source information is being requested.
+   *
+   * Returns
+   *
+   * sources ( Map<String, List<String>> )
+   *
+   *   A mapping from source URIs to directly reachable source URIs. For
+   *   example, a file "foo.dart" that imports "bar.dart" would have the
+   *   corresponding mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If
+   *   "bar.dart" has further imports (or exports) there will be a mapping from
+   *   the URI "file:///bar.dart" to them. To check if a specific URI is
+   *   reachable from a given file, clients can check for its presence in the
+   *   resulting key set.
+   */
+  Future<AnalysisGetReachableSourcesResult> sendAnalysisGetReachableSources(String file) {
+    var params = new AnalysisGetReachableSourcesParams(file).toJson();
+    return server.send("analysis.getReachableSources", params)
+        .then((result) {
+      ResponseDecoder decoder = new ResponseDecoder(null);
+      return new AnalysisGetReachableSourcesResult.fromJson(decoder, 'result', result);
+    });
+  }
+
+  /**
    * Return library dependency information for use in client-side indexing and
    * package URI resolution.
    *
@@ -1629,6 +1664,23 @@
   StreamController<ExecutionLaunchDataParams> _onExecutionLaunchData;
 
   /**
+   * Return server diagnostics.
+   *
+   * Returns
+   *
+   * contexts ( List<ContextData> )
+   *
+   *   The list of analysis contexts.
+   */
+  Future<DiagnosticGetDiagnosticsResult> sendDiagnosticGetDiagnostics() {
+    return server.send("diagnostic.getDiagnostics", null)
+        .then((result) {
+      ResponseDecoder decoder = new ResponseDecoder(null);
+      return new DiagnosticGetDiagnosticsResult.fromJson(decoder, 'result', result);
+    });
+  }
+
+  /**
    * Initialize the fields in InttestMixin, and ensure that notifications will
    * be handled.
    */
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 5004f86..f05a775 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -11,7 +11,6 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/constants.dart';
-import 'package:analysis_server/src/server/driver.dart' as analysisServer;
 import 'package:path/path.dart';
 import 'package:unittest/unittest.dart';
 
@@ -583,7 +582,7 @@
     _pendingCommands[id] = completer;
     String line = JSON.encode(command);
     _recordStdio('SEND: $line');
-    _process.stdin.add(UTF8.encoder.convert("${line}\n"));
+    _process.stdin.add(UTF8.encoder.convert("$line\n"));
     return completer.future;
   }
 
@@ -597,7 +596,6 @@
       {bool debugServer: false,
       int diagnosticPort,
       bool profileServer: false,
-      bool newTaskModel: true,
       bool useAnalysisHighlight2: false}) {
     if (_process != null) {
       throw new Exception('Process already started');
@@ -615,7 +613,7 @@
       arguments.add('--observe');
       arguments.add('--pause-isolates-on-exit');
     }
-    if (Platform.packageRoot.isNotEmpty) {
+    if (Platform.packageRoot != null) {
       arguments.add('--package-root=${Platform.packageRoot}');
     }
     arguments.add('--checked');
@@ -627,9 +625,6 @@
     if (useAnalysisHighlight2) {
       arguments.add('--useAnalysisHighlight2');
     }
-    if (!newTaskModel) {
-      arguments.add('--${analysisServer.Driver.DISABLE_NEW_TASK_MODEL}');
-    }
 //    print('Launching $serverPath');
 //    print('$dartBinary ${arguments.join(' ')}');
     return Process.start(dartBinary, arguments).then((Process process) {
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 6d0ec42..6266cb9 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -153,6 +153,30 @@
   }));
 
 /**
+ * analysis.getReachableSources params
+ *
+ * {
+ *   "file": FilePath
+ * }
+ */
+final Matcher isAnalysisGetReachableSourcesParams = new LazyMatcher(() => new MatchesJsonObject(
+  "analysis.getReachableSources params", {
+    "file": isFilePath
+  }));
+
+/**
+ * analysis.getReachableSources result
+ *
+ * {
+ *   "sources": Map<String, List<String>>
+ * }
+ */
+final Matcher isAnalysisGetReachableSourcesResult = new LazyMatcher(() => new MatchesJsonObject(
+  "analysis.getReachableSources result", {
+    "sources": isMapOf(isString, isListOf(isString))
+  }));
+
+/**
  * analysis.getLibraryDependencies params
  */
 final Matcher isAnalysisGetLibraryDependenciesParams = isNull;
@@ -1007,6 +1031,23 @@
   }));
 
 /**
+ * diagnostic.getDiagnostics params
+ */
+final Matcher isDiagnosticGetDiagnosticsParams = isNull;
+
+/**
+ * diagnostic.getDiagnostics result
+ *
+ * {
+ *   "contexts": List<ContextData>
+ * }
+ */
+final Matcher isDiagnosticGetDiagnosticsResult = new LazyMatcher(() => new MatchesJsonObject(
+  "diagnostic.getDiagnostics result", {
+    "contexts": isListOf(isContextData)
+  }));
+
+/**
  * AddContentOverlay
  *
  * {
@@ -1259,6 +1300,26 @@
 ]);
 
 /**
+ * ContextData
+ *
+ * {
+ *   "name": String
+ *   "explicitFileCount": int
+ *   "implicitFileCount": int
+ *   "workItemQueueLength": int
+ *   "cacheEntryExceptions": List<String>
+ * }
+ */
+final Matcher isContextData = new LazyMatcher(() => new MatchesJsonObject(
+  "ContextData", {
+    "name": isString,
+    "explicitFileCount": isInt,
+    "implicitFileCount": isInt,
+    "workItemQueueLength": isInt,
+    "cacheEntryExceptions": isListOf(isString)
+  }));
+
+/**
  * Element
  *
  * {
@@ -2038,8 +2099,10 @@
  *   FORMAT_WITH_ERRORS
  *   GET_ERRORS_INVALID_FILE
  *   GET_NAVIGATION_INVALID_FILE
+ *   GET_REACHABLE_SOURCES_INVALID_FILE
  *   INVALID_ANALYSIS_ROOT
  *   INVALID_EXECUTION_CONTEXT
+ *   INVALID_FILE_PATH_FORMAT
  *   INVALID_OVERLAY_CHANGE
  *   INVALID_PARAMETER
  *   INVALID_REQUEST
@@ -2063,8 +2126,10 @@
   "FORMAT_WITH_ERRORS",
   "GET_ERRORS_INVALID_FILE",
   "GET_NAVIGATION_INVALID_FILE",
+  "GET_REACHABLE_SOURCES_INVALID_FILE",
   "INVALID_ANALYSIS_ROOT",
   "INVALID_EXECUTION_CONTEXT",
+  "INVALID_FILE_PATH_FORMAT",
   "INVALID_OVERLAY_CHANGE",
   "INVALID_PARAMETER",
   "INVALID_REQUEST",
@@ -2243,8 +2308,8 @@
  * extractLocalVariable feedback
  *
  * {
- *   "coveringExpressionOffsets": List<int>
- *   "coveringExpressionLengths": List<int>
+ *   "coveringExpressionOffsets": optional List<int>
+ *   "coveringExpressionLengths": optional List<int>
  *   "names": List<String>
  *   "offsets": List<int>
  *   "lengths": List<int>
@@ -2252,11 +2317,12 @@
  */
 final Matcher isExtractLocalVariableFeedback = new LazyMatcher(() => new MatchesJsonObject(
   "extractLocalVariable feedback", {
-    "coveringExpressionOffsets": isListOf(isInt),
-    "coveringExpressionLengths": isListOf(isInt),
     "names": isListOf(isString),
     "offsets": isListOf(isInt),
     "lengths": isListOf(isInt)
+  }, optionalFields: {
+    "coveringExpressionOffsets": isListOf(isInt),
+    "coveringExpressionLengths": isListOf(isInt)
   }));
 
 /**
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 99be8fc..1fbb426 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -6,7 +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/context/context.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -219,11 +219,7 @@
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      if (AnalysisEngine.instance.useTaskModel) {
-        _analysisContext = new newContext.SdkAnalysisContext();
-      } else {
-        _analysisContext = new SdkAnalysisContext();
-      }
+      _analysisContext = new SdkAnalysisContext();
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
       ChangeSet changeSet = new ChangeSet();
@@ -273,7 +269,7 @@
       }
       if (filePath.startsWith("$libraryPath/")) {
         String pathInLibrary = filePath.substring(libraryPath.length + 1);
-        String path = '${library.shortName}/${pathInLibrary}';
+        String path = '${library.shortName}/$pathInLibrary';
         try {
           resource.File file = provider.getResource(uri.path);
           Uri dartUri = new Uri(scheme: 'dart', path: path);
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 428f53b..d47638f 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -15,11 +15,11 @@
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/operation/operation.dart';
 import 'package:analysis_server/src/operation/operation_analysis.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:typed_mock/typed_mock.dart';
@@ -72,23 +72,19 @@
 
 class MockAnalysisContext extends StringTypedMock implements AnalysisContext {
   MockAnalysisContext(String name) : super(name);
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockClassElement extends TypedMock implements ClassElement {
   final ElementKind kind = ElementKind.CLASS;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockCompilationUnitElement extends TypedMock
     implements CompilationUnitElement {
   final ElementKind kind = ElementKind.COMPILATION_UNIT;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockConstructorElement extends TypedMock implements ConstructorElement {
   final kind = ElementKind.CONSTRUCTOR;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockElement extends StringTypedMock implements Element {
@@ -99,55 +95,39 @@
 
   @override
   String get name => _toString;
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockFieldElement extends TypedMock implements FieldElement {
   final ElementKind kind = ElementKind.FIELD;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockFunctionElement extends TypedMock implements FunctionElement {
   final ElementKind kind = ElementKind.FUNCTION;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockFunctionTypeAliasElement extends TypedMock
     implements FunctionTypeAliasElement {
   final ElementKind kind = ElementKind.FUNCTION_TYPE_ALIAS;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-class MockHtmlElement extends TypedMock implements HtmlElement {
-  final ElementKind kind = ElementKind.HTML;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockImportElement extends TypedMock implements ImportElement {
   final ElementKind kind = ElementKind.IMPORT;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockLibraryElement extends TypedMock implements LibraryElement {
   final ElementKind kind = ElementKind.LIBRARY;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockLocalVariableElement extends TypedMock
     implements LocalVariableElement {
   final ElementKind kind = ElementKind.LOCAL_VARIABLE;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class MockLogger extends TypedMock implements Logger {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLogger extends TypedMock implements Logger {}
 
 class MockMethodElement extends StringTypedMock implements MethodElement {
   final kind = ElementKind.METHOD;
   MockMethodElement([String name = 'method']) : super(name);
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /**
@@ -192,14 +172,12 @@
 
 class MockParameterElement extends TypedMock implements ParameterElement {
   final ElementKind kind = ElementKind.PARAMETER;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockPropertyAccessorElement extends TypedMock
     implements PropertyAccessorElement {
   final ElementKind kind;
   MockPropertyAccessorElement(this.kind);
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /**
@@ -255,7 +233,7 @@
     if (_closed) {
       throw new Exception('sendRequest after connection closed');
     }
-    // Wrap send request in future to simulate websocket
+    // Wrap send request in future to simulate WebSocket.
     new Future(() => requestController.add(request));
     return waitForResponse(request);
   }
@@ -267,7 +245,7 @@
       return;
     }
     responsesReceived.add(response);
-    // Wrap send response in future to simulate websocket
+    // Wrap send response in future to simulate WebSocket.
     new Future(() => responseController.add(response));
   }
 
@@ -342,19 +320,16 @@
 
 class MockSource extends StringTypedMock implements Source {
   MockSource([String name = 'mocked.dart']) : super(name);
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockTopLevelVariableElement extends TypedMock
     implements TopLevelVariableElement {
   final ElementKind kind = ElementKind.TOP_LEVEL_VARIABLE;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockTypeParameterElement extends TypedMock
     implements TypeParameterElement {
   final ElementKind kind = ElementKind.TYPE_PARAMETER;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class NoResponseException implements Exception {
diff --git a/pkg/analysis_server/test/operation/operation_queue_test.dart b/pkg/analysis_server/test/operation/operation_queue_test.dart
index ed7fbca..e6926c9 100644
--- a/pkg/analysis_server/test/operation/operation_queue_test.dart
+++ b/pkg/analysis_server/test/operation/operation_queue_test.dart
@@ -36,8 +36,6 @@
 
 class AnalysisContextMock extends TypedMock implements InternalAnalysisContext {
   List<Source> prioritySources = <Source>[];
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class AnalysisServerMock extends TypedMock implements AnalysisServer {
@@ -48,13 +46,9 @@
   final SearchEngine searchEngine;
 
   AnalysisServerMock({this.resourceProvider, this.searchEngine});
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class ServerContextManagerMock extends TypedMock implements ContextManager {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class ServerContextManagerMock extends TypedMock implements ContextManager {}
 
 @reflectiveTest
 class ServerOperationQueueTest {
@@ -230,21 +224,15 @@
   ServerOperationPriority get priority {
     return ServerOperationPriority.ANALYSIS_NOTIFICATION;
   }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class _ServerOperationMock extends TypedMock implements ServerOperation {
   final AnalysisContext context;
 
   _ServerOperationMock([this.context]);
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class _SourceMock extends TypedMock implements Source {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _SourceMock extends TypedMock implements Source {}
 
 class _SourceSensitiveOperationMock extends TypedMock
     implements SourceSensitiveOperation {
@@ -257,8 +245,6 @@
     return ServerOperationPriority.ANALYSIS_NOTIFICATION;
   }
 
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
   @override
   bool shouldBeDiscardedOnSourceChange(Source source) {
     return source == this.source;
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index 35cf37d..2d0eddd 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -6,8 +6,10 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/plugin/protocol/protocol_dart.dart';
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
+import 'package:analyzer/src/dart/element/element.dart' as engine;
 import 'package:analyzer/src/generated/ast.dart' as engine;
-import 'package:analyzer/src/generated/element.dart' as engine;
 import 'package:analyzer/src/generated/error.dart' as engine;
 import 'package:analyzer/src/generated/source.dart' as engine;
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart b/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
index 592b8dd..a92c943 100644
--- a/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
+++ b/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
@@ -25,9 +25,7 @@
 
 main() {
   initializeTestEnvironment();
-  if (AnalysisEngine.instance.useTaskModel) {
-    defineReflectiveTests(SetAnalysisDomainTest);
-  }
+  defineReflectiveTests(SetAnalysisDomainTest);
 }
 
 /**
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 5f503b6..24d03a3 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -9,8 +9,9 @@
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
 import 'package:analyzer/src/generated/ast.dart' as engine;
-import 'package:analyzer/src/generated/element.dart' as engine;
 import 'package:analyzer/src/generated/error.dart' as engine;
 import 'package:analyzer/src/generated/source.dart' as engine;
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -26,9 +27,7 @@
   defineReflectiveTests(EnumTest);
 }
 
-class AnalysisErrorMock extends TypedMock implements engine.AnalysisError {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class AnalysisErrorMock extends TypedMock implements engine.AnalysisError {}
 
 @reflectiveTest
 class AnalysisErrorTest {
@@ -131,11 +130,8 @@
         .run(convertElementKind, exceptions: {
       // TODO(paulberry): do any of the exceptions below constitute bugs?
       engine.ElementKind.DYNAMIC: ElementKind.UNKNOWN,
-      engine.ElementKind.EMBEDDED_HTML_SCRIPT: ElementKind.UNKNOWN,
       engine.ElementKind.ERROR: ElementKind.UNKNOWN,
       engine.ElementKind.EXPORT: ElementKind.UNKNOWN,
-      engine.ElementKind.EXTERNAL_HTML_SCRIPT: ElementKind.UNKNOWN,
-      engine.ElementKind.HTML: ElementKind.UNKNOWN,
       engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
       engine.ElementKind.NAME: ElementKind.UNKNOWN,
       engine.ElementKind.UNIVERSE: ElementKind.UNKNOWN
diff --git a/pkg/analysis_server/test/services/completion/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/arglist_contributor_test.dart
deleted file mode 100644
index 9bb8aa7..0000000
--- a/pkg/analysis_server/test/services/completion/arglist_contributor_test.dart
+++ /dev/null
@@ -1,531 +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 test.services.completion.dart.arglist;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/services/completion/arglist_contributor.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(ArgListContributorTest);
-}
-
-@reflectiveTest
-class ArgListContributorTest extends AbstractCompletionTest {
-  void assertNoOtherSuggestions(Iterable<CompletionSuggestion> expected) {
-    for (CompletionSuggestion suggestion in request.suggestions) {
-      if (!expected.contains(suggestion)) {
-        failedCompletion('did not expect completion: '
-            '${suggestion.completion}\n  $suggestion');
-      }
-    }
-  }
-
-  void assertSuggestArgumentList(
-      List<String> paramNames, List<String> paramTypes) {
-    CompletionSuggestionKind csKind = CompletionSuggestionKind.ARGUMENT_LIST;
-    CompletionSuggestion cs = getSuggest(csKind: csKind);
-    if (cs == null) {
-      failedCompletion('expected completion $csKind', request.suggestions);
-    }
-    assertSuggestArgumentList_params(
-        paramNames, paramTypes, cs.parameterNames, cs.parameterTypes);
-    expect(cs.relevance, DART_RELEVANCE_HIGH);
-    assertNoOtherSuggestions([cs]);
-  }
-
-  void assertSuggestArgumentList_params(
-      List<String> expectedNames,
-      List<String> expectedTypes,
-      List<String> actualNames,
-      List<String> actualTypes) {
-    if (actualNames != null &&
-        actualNames.length == expectedNames.length &&
-        actualTypes != null &&
-        actualTypes.length == expectedTypes.length) {
-      int index = 0;
-      while (index < expectedNames.length) {
-        if (actualNames[index] != expectedNames[index] ||
-            actualTypes[index] != expectedTypes[index]) {
-          break;
-        }
-        ++index;
-      }
-      if (index == expectedNames.length) {
-        return;
-      }
-    }
-    StringBuffer msg = new StringBuffer();
-    msg.writeln('Argument list not the same');
-    msg.writeln('  Expected names: $expectedNames');
-    msg.writeln('           found: $actualNames');
-    msg.writeln('  Expected types: $expectedTypes');
-    msg.writeln('           found: $actualTypes');
-    fail(msg.toString());
-  }
-
-  /**
-   * Assert that the specified suggestions are the only suggestions.
-   */
-  void assertSuggestArguments({List<String> namedArguments}) {
-    List<CompletionSuggestion> expected = new List<CompletionSuggestion>();
-    for (String name in namedArguments) {
-      expected.add(assertSuggest('$name: ',
-          csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
-          relevance: DART_RELEVANCE_NAMED_PARAMETER));
-    }
-    assertNoOtherSuggestions(expected);
-  }
-
-  @override
-  void setUpContributor() {
-    contributor = new ArgListContributor();
-  }
-
-  test_Annotation_local_constructor_named_param() {
-    //
-    addTestSource('''
-class A { A({int one, String two: 'defaultValue'}) { } }
-@A(^) main() { }''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['one', 'two']);
-    });
-  }
-
-  test_ArgumentList_getter() {
-    addTestSource('class A {int get foo => 7; main() {foo(^)}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_imported_constructor_named_param() {
-    //
-    addSource('/libA.dart', 'library libA; class A{A({int one}){}}');
-    addTestSource('import "/libA.dart"; main() { new A(^);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['one']);
-    });
-  }
-
-  test_ArgumentList_imported_constructor_named_param2() {
-    //
-    addSource('/libA.dart', 'library libA; class A{A.foo({int one}){}}');
-    addTestSource('import "/libA.dart"; main() { new A.foo(^);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['one']);
-    });
-  }
-
-  test_ArgumentList_imported_function_0() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect() { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect(a^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_imported_function_1() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArgumentList(['arg'], ['String']);
-    });
-  }
-
-  test_ArgumentList_imported_function_2() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg1, int arg2) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArgumentList(['arg1', 'arg2'], ['String', 'int']);
-    });
-  }
-
-  test_ArgumentList_imported_function_3() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg1, int arg2, {bool arg3}) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArgumentList(['arg1', 'arg2'], ['String', 'int']);
-    });
-  }
-
-  test_ArgumentList_imported_function_3a() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg1, int arg2, {bool arg3}) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect('hello', ^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_imported_function_3b() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg1, int arg2, {bool arg3}) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect('hello', ^x)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_imported_function_3c() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg1, int arg2, {bool arg3}) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect('hello', x^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_imported_function_3d() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg1, int arg2, {bool arg3}) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect('hello', x ^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_imported_function_named_param() {
-    //
-    addTestSource('main() { int.parse("16", ^);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['radix', 'onError']);
-    });
-  }
-
-  test_ArgumentList_imported_function_named_param1() {
-    //
-    addTestSource('main() { int.parse("16", r^);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['radix', 'onError']);
-    });
-  }
-
-  test_ArgumentList_imported_function_named_param2() {
-    //
-    addTestSource('main() { int.parse("16", radix: 7, ^);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['onError']);
-    });
-  }
-
-  test_ArgumentList_imported_function_named_param2a() {
-    //
-    addTestSource('main() { int.parse("16", radix: ^);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_local_constructor_named_param() {
-    //
-    addTestSource('''
-class A { A({int one, String two: 'defaultValue'}) { } }
-main() { new A(^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['one', 'two']);
-    });
-  }
-
-  test_ArgumentList_local_constructor_named_param2() {
-    //
-    addTestSource('''
-class A { A.foo({int one, String two: 'defaultValue'}) { } }
-main() { new A.foo(^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['one', 'two']);
-    });
-  }
-
-  test_ArgumentList_local_function_1() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      import '/libA.dart'
-      expect(arg) { }
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArgumentList(['arg'], ['dynamic']);
-    });
-  }
-
-  test_ArgumentList_local_function_2() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      import '/libA.dart'
-      expect(arg1, int arg2) { }
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArgumentList(['arg1', 'arg2'], ['dynamic', 'int']);
-    });
-  }
-
-  test_ArgumentList_local_function_3() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      import '/libA.dart'
-      expect(arg1, int arg2) { }
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArgumentList(['arg1', 'arg2'], ['dynamic', 'int']);
-    });
-  }
-
-  test_ArgumentList_local_function_3a() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      import '/libA.dart'
-      expect(arg1, int arg2, {bool arg3}) { }
-      class B { }
-      String bar() => true;
-      void main() {expect('hello', ^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_local_function_3b() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      import '/libA.dart'
-      expect(arg1, int arg2, {bool arg3}) { }
-      class B { }
-      String bar() => true;
-      void main() {expect('hello', ^x)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_local_function_3c() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      import '/libA.dart'
-      expect(arg1, int arg2, {bool arg3}) { }
-      class B { }
-      String bar() => true;
-      void main() {expect('hello', x^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_local_function_3d() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      import '/libA.dart'
-      expect(arg1, int arg2, {bool arg3}) { }
-      class B { }
-      String bar() => true;
-      void main() {expect('hello', x ^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_local_function_named_param() {
-    //
-    addTestSource('''
-f(v,{int radix, int onError(String s)}){}
-main() { f("16", ^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['radix', 'onError']);
-    });
-  }
-
-  test_ArgumentList_local_function_named_param1() {
-    //
-    addTestSource('''
-f(v,{int radix, int onError(String s)}){}
-main() { f("16", r^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['radix', 'onError']);
-    });
-  }
-
-  test_ArgumentList_local_function_named_param2() {
-    //
-    addTestSource('''
-f(v,{int radix, int onError(String s)}){}
-main() { f("16", radix: 7, ^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArguments(namedArguments: ['onError']);
-    });
-  }
-
-  test_ArgumentList_local_function_named_param2a() {
-    //
-    addTestSource('''
-f(v,{int radix, int onError(String s)}){}
-main() { f("16", radix: ^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_local_method_0() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B {
-        expect() { }
-        void foo() {expect(^)}}
-      String bar() => true;''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ArgumentList_local_method_2() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B {
-        expect(arg, int blat) { }
-        void foo() {expect(^)}}
-      String bar() => true;''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestArgumentList(['arg', 'blat'], ['dynamic', 'int']);
-    });
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/combinator_contributor_test.dart
deleted file mode 100644
index f0698a0..0000000
--- a/pkg/analysis_server/test/services/completion/combinator_contributor_test.dart
+++ /dev/null
@@ -1,141 +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 test.services.completion.dart.combinator;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/services/completion/combinator_contributor.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(CombinatorContributorTest);
-}
-
-@reflectiveTest
-class CombinatorContributorTest extends AbstractCompletionTest {
-  @override
-  void setUpContributor() {
-    contributor = new CombinatorContributor();
-  }
-
-  test_Block_inherited_local() {
-    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addTestSource('''
-      class F { var f1; f2() { } }
-      class E extends F { var e1; e2() { } }
-      class I { int i1; i2() { } }
-      class M { var m1; int m2() { } }
-      class A extends E implements I with M {a() {^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_Combinator_hide() {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource(
-        '/testAB.dart',
-        '''
-      library libAB;
-      part '/partAB.dart';
-      class A { }
-      class B { }''');
-    addSource(
-        '/partAB.dart',
-        '''
-      part of libAB;
-      var T1;
-      PB F1() => new PB();
-      class PB { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      class C { }
-      class D { }''');
-    addTestSource('''
-      import "/testAB.dart" hide ^;
-      import "/testCD.dart";
-      class X {}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestClass('A',
-          relevance: DART_RELEVANCE_DEFAULT,
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestClass('B',
-          relevance: DART_RELEVANCE_DEFAULT,
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestClass('PB',
-          relevance: DART_RELEVANCE_DEFAULT,
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestTopLevelVar('T1', null, DART_RELEVANCE_DEFAULT,
-          CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestFunction('F1', 'PB',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('C');
-      assertNotSuggested('D');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-    });
-  }
-
-  test_Combinator_show() {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource(
-        '/testAB.dart',
-        '''
-      library libAB;
-      part '/partAB.dart';
-      class A { }
-      class B { }''');
-    addSource(
-        '/partAB.dart',
-        '''
-      part of libAB;
-      var T1;
-      PB F1() => new PB();
-      typedef PB2 F2(int blat);
-      class Clz = Object with Object;
-      class PB { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      class C { }
-      class D { }''');
-    addTestSource('''
-      import "/testAB.dart" show ^;
-      import "/testCD.dart";
-      class X {}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestClass('A',
-          relevance: DART_RELEVANCE_DEFAULT,
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestClass('B',
-          relevance: DART_RELEVANCE_DEFAULT,
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestClass('PB',
-          relevance: DART_RELEVANCE_DEFAULT,
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestTopLevelVar('T1', null, DART_RELEVANCE_DEFAULT,
-          CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestFunction('F1', 'PB',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestClass('Clz',
-          relevance: DART_RELEVANCE_DEFAULT,
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestFunctionTypeAlias('F2', null, false, DART_RELEVANCE_DEFAULT,
-          CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('C');
-      assertNotSuggested('D');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-    });
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/common_usage_computer_test.dart b/pkg/analysis_server/test/services/completion/common_usage_computer_test.dart
deleted file mode 100644
index 3e15f2e..0000000
--- a/pkg/analysis_server/test/services/completion/common_usage_computer_test.dart
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.completion.computer.dart.relevance;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/analysis_server.dart'
-    show ContextSourcePair;
-import 'package:analysis_server/src/constants.dart';
-import 'package:analysis_server/src/domain_completion.dart';
-import 'package:analysis_server/src/services/completion/common_usage_computer.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../analysis_abstract.dart';
-import '../../mocks.dart';
-import '../../utils.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(CommonUsageComputerTest);
-}
-
-@reflectiveTest
-class CommonUsageComputerTest extends AbstractAnalysisTest {
-  String completionId;
-  int completionOffset;
-  int replacementOffset;
-  int replacementLength;
-  List<CompletionSuggestion> suggestions = [];
-  bool suggestionsDone = false;
-
-  String addTestFile(String content) {
-    completionOffset = content.indexOf('^');
-    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
-    int nextOffset = content.indexOf('^', completionOffset + 1);
-    expect(nextOffset, equals(-1), reason: 'too many ^');
-    return super.addTestFile(content.substring(0, completionOffset) +
-        content.substring(completionOffset + 1));
-  }
-
-  void assertHasResult(CompletionSuggestionKind kind, String completion,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      bool isDeprecated = false,
-      bool isPotential = false]) {
-    var cs;
-    suggestions.forEach((s) {
-      if (s.completion == completion) {
-        if (cs == null) {
-          cs = s;
-        } else {
-          fail('expected exactly one $completion but found > 1');
-        }
-      }
-    });
-    if (cs == null) {
-      var completions = suggestions.map((s) => s.completion).toList();
-      fail('expected "$completion" but found\n $completions');
-    }
-    expect(cs.kind, equals(kind));
-    expect(cs.relevance, equals(relevance));
-    expect(cs.selectionOffset, equals(completion.length));
-    expect(cs.selectionLength, equals(0));
-    expect(cs.isDeprecated, equals(isDeprecated));
-    expect(cs.isPotential, equals(isPotential));
-  }
-
-  void assertNoResult(String completion) {
-    if (suggestions.any((cs) => cs.completion == completion)) {
-      fail('did not expect completion: $completion');
-    }
-  }
-
-  void assertValidId(String id) {
-    expect(id, isNotNull);
-    expect(id.isNotEmpty, isTrue);
-  }
-
-  @override
-  Index createIndex() {
-    return createLocalMemoryIndex();
-  }
-
-  Future getSuggestions(Map<String, List<String>> selectorRelevance) async {
-    await waitForTasksFinished();
-    CompletionGetSuggestionsParams params =
-        new CompletionGetSuggestionsParams(testFile, completionOffset);
-    Request request = params.toRequest('0');
-    CompletionDomainHandler domainHandler = new CompletionDomainHandler(server);
-    handler = domainHandler;
-
-    ContextSourcePair contextSource = server.getContextSourcePair(params.file);
-    AnalysisContext context = contextSource.context;
-    Source source = contextSource.source;
-    DartCompletionManager completionManager = new DartCompletionManager(
-        context,
-        server.searchEngine,
-        source,
-        new DartCompletionCache(context, source),
-        null,
-        new CommonUsageComputer(selectorRelevance));
-
-    Response response =
-        domainHandler.processRequest(request, completionManager);
-    expect(response, isResponseSuccess('0'));
-    completionId = response.id;
-    assertValidId(completionId);
-    await pumpEventQueue();
-    expect(suggestionsDone, isTrue);
-  }
-
-  void processNotification(Notification notification) {
-    if (notification.event == COMPLETION_RESULTS) {
-      var params = new CompletionResultsParams.fromNotification(notification);
-      String id = params.id;
-      assertValidId(id);
-      if (id == completionId) {
-        expect(suggestionsDone, isFalse);
-        replacementOffset = params.replacementOffset;
-        replacementLength = params.replacementLength;
-        suggestionsDone = params.isLast;
-        expect(suggestionsDone, isNotNull);
-        suggestions = params.results;
-      }
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    createProject();
-  }
-
-  test_ConstructorName() async {
-    // SimpleIdentifier  ConstructorName  InstanceCreationExpression
-    addTestFile('import "dart:async"; class A {x() {new Future.^}}');
-    await getSuggestions({
-      'dart.async.Future': ['value', 'wait']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'delayed');
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'value',
-        DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  test_PrefixedIdentifier_field() async {
-    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
-    addTestFile('class A {static int s1; static int s2; x() {A.^}}');
-    await getSuggestions({
-      '.A': ['s2']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1');
-    assertHasResult(
-        CompletionSuggestionKind.INVOCATION, 's2', DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  test_PrefixedIdentifier_getter() async {
-    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
-    addTestFile('class A {int get g1 => 1; int get g2 => 2; x() {new A().^}}');
-    await getSuggestions({
-      '.A': ['g2']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'g1');
-    assertHasResult(
-        CompletionSuggestionKind.INVOCATION, 'g2', DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  test_PrefixedIdentifier_setter() async {
-    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
-    addTestFile('class A {set s1(v) {}; set s2(v) {}; x() {new A().^}}');
-    await getSuggestions({
-      '.A': ['s2']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1');
-    assertHasResult(
-        CompletionSuggestionKind.INVOCATION, 's2', DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  test_PrefixedIdentifier_static_method() async {
-    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
-    addTestFile('import "dart:async"; class A {x() {Future.^}}');
-    await getSuggestions({
-      'dart.async.Future': ['value', 'wait']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'wait',
-        DART_RELEVANCE_COMMON_USAGE - 1);
-    assertNoResult('Future');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-
-  test_PropertyAccess() async {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addTestFile('import "dart:math"; class A {x() {new Random().^}}');
-    await getSuggestions({
-      'dart.math.Random': ['nextInt', 'nextDouble']
-    });
-    expect(replacementOffset, equals(completionOffset));
-    expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextBool');
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextDouble',
-        DART_RELEVANCE_COMMON_USAGE - 1);
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextInt',
-        DART_RELEVANCE_COMMON_USAGE);
-    assertNoResult('Random');
-    assertNoResult('Object');
-    assertNoResult('A');
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/completion_computer_test.dart b/pkg/analysis_server/test/services/completion/completion_computer_test.dart
deleted file mode 100644
index 21b3393..0000000
--- a/pkg/analysis_server/test/services/completion/completion_computer_test.dart
+++ /dev/null
@@ -1,207 +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 test.services.completion.suggestion;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart'
-    show CompletionRequest, CompletionResult;
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_single_unit.dart';
-import '../../operation/operation_queue_test.dart';
-import '../../utils.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(DartCompletionManagerTest);
-}
-
-/**
- * Returns a [Future] that completes after pumping the event queue [times]
- * times. By default, this should pump the event queue enough times to allow
- * any code to run, as long as it's not waiting on some external event.
- */
-Future pumpEventQueue([int times = 20]) {
-  if (times == 0) return new Future.value();
-  // We use a delayed future to allow microtask events to finish. The
-  // Future.value or Future() constructors use scheduleMicrotask themselves and
-  // would therefore not wait for microtask callbacks that are scheduled after
-  // invoking this method.
-  return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1));
-}
-
-@reflectiveTest
-class DartCompletionManagerTest extends AbstractSingleUnitTest {
-  Index index;
-  SearchEngineImpl searchEngine;
-  Source source;
-  DartCompletionManager manager;
-  MockCompletionContributor contributor1;
-  MockCompletionContributor contributor2;
-  CompletionSuggestion suggestion1;
-  CompletionSuggestion suggestion2;
-  bool _continuePerformingAnalysis = true;
-
-  void resolveLibrary() {
-    context.resolveCompilationUnit(
-        source, context.computeLibraryElement(source));
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    index = createLocalMemoryIndex();
-    searchEngine = new SearchEngineImpl(index);
-    source = addSource('/does/not/exist.dart', '');
-    manager = new DartCompletionManager.create(context, searchEngine, source);
-    suggestion1 = new CompletionSuggestion(CompletionSuggestionKind.INVOCATION,
-        DART_RELEVANCE_DEFAULT, "suggestion1", 1, 1, false, false);
-    suggestion2 = new CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER,
-        DART_RELEVANCE_DEFAULT, "suggestion2", 2, 2, false, false);
-    new Future(_performAnalysis);
-  }
-
-  @override
-  void tearDown() {
-    _continuePerformingAnalysis = false;
-  }
-
-  test_compute_fastAndFull() {
-    contributor1 = new MockCompletionContributor(suggestion1, null);
-    contributor2 = new MockCompletionContributor(null, suggestion2);
-    manager.contributors = [contributor1, contributor2];
-    int count = 0;
-    bool done = false;
-    AnalysisServer server = new AnalysisServerMock(searchEngine: searchEngine);
-    CompletionRequest completionRequest =
-        new CompletionRequestImpl(server, context, source, 0);
-    manager.results(completionRequest).listen((CompletionResult r) {
-      bool isLast = r is CompletionResultImpl ? r.isLast : true;
-      switch (++count) {
-        case 1:
-          contributor1.assertCalls(context, source, 0, searchEngine);
-          expect(contributor1.fastCount, equals(1));
-          expect(contributor1.fullCount, equals(0));
-          contributor2.assertCalls(context, source, 0, searchEngine);
-          expect(contributor2.fastCount, equals(1));
-          expect(contributor2.fullCount, equals(1));
-          expect(isLast, isTrue);
-          expect(r.suggestions, hasLength(2));
-          expect(r.suggestions, contains(suggestion1));
-          expect(r.suggestions, contains(suggestion2));
-          resolveLibrary();
-          break;
-        default:
-          fail('unexpected');
-      }
-    }, onDone: () {
-      done = true;
-      // There is only one notification
-      expect(count, equals(1));
-    });
-    return pumpEventQueue(150).then((_) {
-      expect(done, isTrue);
-    });
-  }
-
-  test_compute_fastOnly() {
-    contributor1 = new MockCompletionContributor(suggestion1, null);
-    contributor2 = new MockCompletionContributor(suggestion2, null);
-    manager.contributors = [contributor1, contributor2];
-    int count = 0;
-    bool done = false;
-    AnalysisServer server = new AnalysisServerMock(searchEngine: searchEngine);
-    CompletionRequest completionRequest =
-        new CompletionRequestImpl(server, context, source, 0);
-    manager.results(completionRequest).listen((CompletionResult r) {
-      bool isLast = r is CompletionResultImpl ? r.isLast : true;
-      switch (++count) {
-        case 1:
-          contributor1.assertCalls(context, source, 0, searchEngine);
-          expect(contributor1.fastCount, equals(1));
-          expect(contributor1.fullCount, equals(0));
-          contributor2.assertCalls(context, source, 0, searchEngine);
-          expect(contributor2.fastCount, equals(1));
-          expect(contributor2.fullCount, equals(0));
-          expect(isLast, isTrue);
-          expect(r.suggestions, hasLength(2));
-          expect(r.suggestions, contains(suggestion1));
-          expect(r.suggestions, contains(suggestion2));
-          break;
-        default:
-          fail('unexpected');
-      }
-    }, onDone: () {
-      done = true;
-      expect(count, equals(1));
-    });
-    return pumpEventQueue().then((_) {
-      expect(done, isTrue);
-    });
-  }
-
-  void _performAnalysis() {
-    if (!_continuePerformingAnalysis) {
-      return;
-    }
-    context.performAnalysisTask();
-    new Future(_performAnalysis);
-  }
-}
-
-class MockCompletionContributor extends DartCompletionContributor {
-  final CompletionSuggestion fastSuggestion;
-  final CompletionSuggestion fullSuggestion;
-  int fastCount = 0;
-  int fullCount = 0;
-  DartCompletionRequest request;
-
-  MockCompletionContributor(this.fastSuggestion, this.fullSuggestion);
-
-  assertCalls(AnalysisContext context, Source source, int offset,
-      SearchEngine searchEngine) {
-    expect(request.context, equals(context));
-    expect(request.source, equals(source));
-    expect(request.offset, equals(offset));
-    expect(request.searchEngine, equals(searchEngine));
-  }
-
-  assertFull(int fullCount) {
-    expect(this.fastCount, equals(1));
-    expect(this.fullCount, equals(fullCount));
-  }
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    this.request = request;
-    fastCount++;
-    if (fastSuggestion != null) {
-      request.addSuggestion(fastSuggestion);
-    }
-    return fastSuggestion != null;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    this.request = request;
-    fullCount++;
-    if (fullSuggestion != null) {
-      request.addSuggestion(fullSuggestion);
-    }
-    return new Future.value(fullSuggestion != null);
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/completion_manager_test.dart
deleted file mode 100644
index eab5223..0000000
--- a/pkg/analysis_server/test/services/completion/completion_manager_test.dart
+++ /dev/null
@@ -1,48 +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 test.services.completion.manager;
-
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_context.dart';
-import '../../utils.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(CompletionManagerTest);
-}
-
-@reflectiveTest
-class CompletionManagerTest extends AbstractContextTest {
-  var perf = new CompletionPerformance();
-
-  test_dart() {
-    Source source = addSource('/does/not/exist.dart', '');
-    var manager = new CompletionManager.create(context, source, null);
-    expect(manager.runtimeType, DartCompletionManager);
-  }
-
-  test_html() {
-    Source source = addSource('/does/not/exist.html', '');
-    var manager = new CompletionManager.create(context, source, null);
-    expect(manager.runtimeType, NoOpCompletionManager);
-  }
-
-  test_null_context() {
-    Source source = addSource('/does/not/exist.dart', '');
-    var manager = new CompletionManager.create(null, source, null);
-    expect(manager.runtimeType, NoOpCompletionManager);
-  }
-
-  test_other() {
-    Source source = addSource('/does/not/exist.foo', '');
-    var manager = new CompletionManager.create(context, source, null);
-    expect(manager.runtimeType, NoOpCompletionManager);
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/completion_test_util.dart b/pkg/analysis_server/test/services/completion/completion_test_util.dart
deleted file mode 100644
index a533731..0000000
--- a/pkg/analysis_server/test/services/completion/completion_test_util.dart
+++ /dev/null
@@ -1,4729 +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 test.services.completion.util;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
-import 'package:analysis_server/src/services/completion/common_usage_computer.dart';
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
-import 'package:analysis_server/src/services/completion/prefixed_element_contributor.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
-import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_context.dart';
-import '../../operation/operation_queue_test.dart';
-
-int suggestionComparator(CompletionSuggestion s1, CompletionSuggestion s2) {
-  String c1 = s1.completion.toLowerCase();
-  String c2 = s2.completion.toLowerCase();
-  return c1.compareTo(c2);
-}
-
-abstract class AbstractCompletionTest extends AbstractContextTest {
-  Index index;
-  SearchEngineImpl searchEngine;
-  DartCompletionContributor contributor;
-  String testFile = '/completionTest.dart';
-  Source testSource;
-  CompilationUnit testUnit;
-  int completionOffset;
-  AstNode completionNode;
-  bool computeFastResult;
-  DartCompletionRequest request;
-  DartCompletionCache cache;
-  DartCompletionManager _completionManager;
-
-  void addResolvedUnit(String file, String code) {
-    Source source = addSource(file, code);
-    CompilationUnit unit = resolveLibraryUnit(source);
-    index.index(context, unit);
-  }
-
-  void addTestSource(String content) {
-    expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once');
-    completionOffset = content.indexOf('^');
-    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
-    int nextOffset = content.indexOf('^', completionOffset + 1);
-    expect(nextOffset, equals(-1), reason: 'too many ^');
-    content = content.substring(0, completionOffset) +
-        content.substring(completionOffset + 1);
-    testSource = addSource(testFile, content);
-    cache = new DartCompletionCache(context, testSource);
-    AnalysisServer server = new AnalysisServerMock(
-        searchEngine: searchEngine, resourceProvider: provider);
-    request = new DartCompletionRequest(
-        server, context, testSource, completionOffset, cache);
-  }
-
-  void assertHasNoParameterInfo(CompletionSuggestion suggestion) {
-    expect(suggestion.parameterNames, isNull);
-    expect(suggestion.parameterTypes, isNull);
-    expect(suggestion.requiredParameterCount, isNull);
-    expect(suggestion.hasNamedParameters, isNull);
-  }
-
-  void assertHasParameterInfo(CompletionSuggestion suggestion) {
-    expect(suggestion.parameterNames, isNotNull);
-    expect(suggestion.parameterTypes, isNotNull);
-    expect(suggestion.parameterNames.length, suggestion.parameterTypes.length);
-    expect(suggestion.requiredParameterCount,
-        lessThanOrEqualTo(suggestion.parameterNames.length));
-    expect(suggestion.hasNamedParameters, isNotNull);
-  }
-
-  void assertNoSuggestions({CompletionSuggestionKind kind: null}) {
-    if (kind == null) {
-      if (request.suggestions.length > 0) {
-        failedCompletion('Expected no suggestions', request.suggestions);
-      }
-      return;
-    }
-    CompletionSuggestion suggestion = request.suggestions.firstWhere(
-        (CompletionSuggestion cs) => cs.kind == kind,
-        orElse: () => null);
-    if (suggestion != null) {
-      failedCompletion('did not expect completion: $completion\n  $suggestion');
-    }
-  }
-
-  CompletionSuggestion assertNotSuggested(String completion) {
-    CompletionSuggestion suggestion = request.suggestions.firstWhere(
-        (CompletionSuggestion cs) => cs.completion == completion,
-        orElse: () => null);
-    if (suggestion != null) {
-      failedCompletion('did not expect completion: $completion\n  $suggestion');
-    }
-    return null;
-  }
-
-  CompletionSuggestion assertSuggest(String completion,
-      {CompletionSuggestionKind csKind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      protocol.ElementKind elemKind: null,
-      bool isDeprecated: false,
-      bool isPotential: false,
-      String elemFile,
-      int elemOffset}) {
-    CompletionSuggestion cs =
-        getSuggest(completion: completion, csKind: csKind, elemKind: elemKind);
-    if (cs == null) {
-      failedCompletion(
-          'expected $completion $csKind $elemKind', request.suggestions);
-    }
-    expect(cs.kind, equals(csKind));
-    if (isDeprecated) {
-      expect(cs.relevance, equals(DART_RELEVANCE_LOW));
-    } else {
-      expect(cs.relevance, equals(relevance));
-    }
-    expect(cs.importUri, importUri);
-    expect(cs.selectionOffset, equals(completion.length));
-    expect(cs.selectionLength, equals(0));
-    expect(cs.isDeprecated, equals(isDeprecated));
-    expect(cs.isPotential, equals(isPotential));
-    if (cs.element != null) {
-      expect(cs.element.location, isNotNull);
-      expect(cs.element.location.file, isNotNull);
-      expect(cs.element.location.offset, isNotNull);
-      expect(cs.element.location.length, isNotNull);
-      expect(cs.element.location.startColumn, isNotNull);
-      expect(cs.element.location.startLine, isNotNull);
-    }
-    if (elemFile != null) {
-      expect(cs.element.location.file, elemFile);
-    }
-    if (elemOffset != null) {
-      expect(cs.element.location.offset, elemOffset);
-    }
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestClass(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool isDeprecated: false,
-      String elemFile,
-      int elemOffset}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        isDeprecated: isDeprecated,
-        elemFile: elemFile,
-        elemOffset: elemOffset);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.CLASS));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, isNull);
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestClassTypeAlias(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    CompletionSuggestion cs =
-        assertSuggest(name, csKind: kind, relevance: relevance);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.CLASS_TYPE_ALIAS));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, isNull);
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestConstructor(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      int elemOffset}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        relevance: relevance, importUri: importUri, elemOffset: elemOffset);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.CONSTRUCTOR));
-    int index = name.indexOf('.');
-    expect(element.name, index >= 0 ? name.substring(index + 1) : '');
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestField(String name, String type,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool isDeprecated: false}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        elemKind: protocol.ElementKind.FIELD,
-        isDeprecated: isDeprecated);
-    // The returnType represents the type of a field
-    expect(cs.returnType, type != null ? type : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.FIELD));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    // The returnType represents the type of a field
-    expect(element.returnType, type != null ? type : 'dynamic');
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestFunction(String name, String returnType,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool deprecated: false,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        isDeprecated: deprecated);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.FUNCTION));
-    expect(element.name, equals(name));
-    expect(element.isDeprecated, equals(deprecated));
-    String param = element.parameters;
-    expect(param, isNotNull);
-    expect(param[0], equals('('));
-    expect(param[param.length - 1], equals(')'));
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
-    assertHasParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestFunctionTypeAlias(
-      String name, String returnType, bool isDeprecated,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        isDeprecated: isDeprecated);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.FUNCTION_TYPE_ALIAS));
-    expect(element.name, equals(name));
-    expect(element.isDeprecated, equals(isDeprecated));
-    // TODO (danrubel) Determine why params are null
-//    String param = element.parameters;
-//    expect(param, isNotNull);
-//    expect(param[0], equals('('));
-//    expect(param[param.length - 1], equals(')'));
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
-    // TODO (danrubel) Determine why param info is missing
-//    assertHasParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestGetter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool isDeprecated: false}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        elemKind: protocol.ElementKind.GETTER,
-        isDeprecated: isDeprecated);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.GETTER));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestLabel(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.IDENTIFIER]) {
-    CompletionSuggestion cs =
-        assertSuggest(name, csKind: kind, relevance: relevance);
-    expect(cs.returnType, isNull);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.flags, 0);
-    expect(element.kind, equals(protocol.ElementKind.LABEL));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, isNull);
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestLibraryPrefix(String prefix,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    // Library prefix should only be suggested by ImportedReferenceContributor
-    return assertNotSuggested(prefix);
-  }
-
-  CompletionSuggestion assertSuggestMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool isDeprecated: false}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        isDeprecated: isDeprecated);
-    expect(cs.declaringType, equals(declaringType));
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.METHOD));
-    expect(element.name, equals(name));
-    String param = element.parameters;
-    expect(param, isNotNull);
-    expect(param[0], equals('('));
-    expect(param[param.length - 1], equals(')'));
-    expect(element.returnType, returnType != null ? returnType : 'dynamic');
-    assertHasParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestNamedConstructor(
-      String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    if (contributor is PrefixedElementContributor) {
-      CompletionSuggestion cs =
-          assertSuggest(name, csKind: kind, relevance: relevance);
-      protocol.Element element = cs.element;
-      expect(element, isNotNull);
-      expect(element.kind, equals(protocol.ElementKind.CONSTRUCTOR));
-      expect(element.name, equals(name));
-      String param = element.parameters;
-      expect(param, isNotNull);
-      expect(param[0], equals('('));
-      expect(param[param.length - 1], equals(')'));
-      expect(element.returnType, equals(returnType));
-      assertHasParameterInfo(cs);
-      return cs;
-    } else {
-      return assertNotSuggested(name);
-    }
-  }
-
-  CompletionSuggestion assertSuggestParameter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_PARAMETER}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestSetter(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        elemKind: protocol.ElementKind.SETTER);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.SETTER));
-    expect(element.name, equals(name));
-    // TODO (danrubel) assert setter param
-    //expect(element.parameters, isNull);
-    // TODO (danrubel) it would be better if this was always null
-    if (element.returnType != null) {
-      expect(element.returnType, 'dynamic');
-    }
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestTopLevelVar(String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind, relevance: relevance, importUri: importUri);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.TOP_LEVEL_VARIABLE));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, returnType != null ? returnType : 'dynamic');
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  void assertSuggestTopLevelVarGetterSetter(String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT]) {
-    if (contributor is ImportedReferenceContributor) {
-      assertSuggestGetter(name, returnType);
-      assertSuggestSetter(name);
-    } else {
-      assertNotSuggested(name);
-    }
-  }
-
-  bool computeFast() {
-    expect(computeFastResult, isNull);
-    _completionManager = new DartCompletionManager(context, searchEngine,
-        testSource, cache, [contributor], new CommonUsageComputer({}));
-    var result =
-        _completionManager.computeFast(request, new CompletionPerformance());
-    expect(request.replacementOffset, isNotNull);
-    expect(request.replacementLength, isNotNull);
-    computeFastResult = result.isEmpty;
-    return computeFastResult;
-  }
-
-  Future computeFull(assertFunction(bool result), {bool fullAnalysis: true}) {
-    if (computeFastResult == null) {
-      computeFast();
-    }
-    if (computeFastResult) {
-      assertFunction(true);
-      return new Future.value(true);
-    } else {
-      resolve(fullAnalysis);
-      return contributor.computeFull(request).then(assertFunction);
-    }
-  }
-
-  void failedCompletion(String message,
-      [Iterable<CompletionSuggestion> completions]) {
-    StringBuffer sb = new StringBuffer(message);
-    if (completions != null) {
-      sb.write('\n  found');
-      completions.toList()
-        ..sort(suggestionComparator)
-        ..forEach((CompletionSuggestion suggestion) {
-          sb.write('\n    ${suggestion.completion} -> $suggestion');
-        });
-    }
-    if (completionNode != null) {
-      sb.write('\n  in');
-      AstNode node = completionNode;
-      while (node != null) {
-        sb.write('\n    ${node.runtimeType}');
-        node = node.parent;
-      }
-    }
-    fail(sb.toString());
-  }
-
-  CompletionSuggestion getSuggest(
-      {String completion: null,
-      CompletionSuggestionKind csKind: null,
-      protocol.ElementKind elemKind: null}) {
-    CompletionSuggestion cs;
-    request.suggestions.forEach((CompletionSuggestion s) {
-      if (completion != null && completion != s.completion) {
-        return;
-      }
-      if (csKind != null && csKind != s.kind) {
-        return;
-      }
-      if (elemKind != null) {
-        protocol.Element element = s.element;
-        if (element == null || elemKind != element.kind) {
-          return;
-        }
-      }
-      if (cs == null) {
-        cs = s;
-      } else {
-        failedCompletion('expected exactly one $cs',
-            request.suggestions.where((s) => s.completion == completion));
-      }
-    });
-    return cs;
-  }
-
-  void resolve(bool fullAnalysis) {
-    // Index SDK
-    for (Source librarySource in context.librarySources) {
-      CompilationUnit unit =
-          context.getResolvedCompilationUnit2(librarySource, librarySource);
-      if (unit != null) {
-        index.index(context, unit);
-      }
-    }
-
-    var result = context.performAnalysisTask();
-    bool resolved = false;
-    while (result.hasMoreWork) {
-      // Update the index
-      result.changeNotices.forEach((ChangeNotice notice) {
-        CompilationUnit unit = notice.resolvedDartUnit;
-        if (unit != null) {
-          index.index(context, unit);
-        }
-      });
-
-      // If the unit has been resolved, then finish the completion
-      List<Source> libSourceList = context.getLibrariesContaining(testSource);
-      if (libSourceList.length > 0) {
-        LibraryElement library = context.getLibraryElement(libSourceList[0]);
-        if (library != null) {
-          CompilationUnit unit =
-              context.getResolvedCompilationUnit(testSource, library);
-          if (unit != null) {
-            request.unit = unit;
-            request.target =
-                new CompletionTarget.forOffset(unit, completionOffset);
-            resolved = true;
-            if (!fullAnalysis) {
-              break;
-            }
-          }
-        }
-      }
-
-      result = context.performAnalysisTask();
-    }
-    if (!resolved) {
-      fail('expected unit to be resolved');
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    index = createLocalMemoryIndex();
-    searchEngine = new SearchEngineImpl(index);
-    setUpContributor();
-  }
-
-  void setUpContributor();
-}
-
-/**
- * Common tests for `ImportedTypeContributorTest`, `InvocationContributorTest`,
- * and `LocalContributorTest`.
- */
-abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest {
-  /**
-   * Assert that the ImportedReferenceContributor uses cached results
-   * to produce identical suggestions to the original set of suggestions.
-   */
-  void assertCachedCompute(_) {
-    // Subclasses override
-  }
-
-  CompletionSuggestion assertSuggestEnum(String completion,
-      {bool isDeprecated: false}) {
-    CompletionSuggestion suggestion =
-        assertSuggest(completion, isDeprecated: isDeprecated);
-    expect(suggestion.isDeprecated, isDeprecated);
-    expect(suggestion.element.kind, protocol.ElementKind.ENUM);
-    return suggestion;
-  }
-
-  CompletionSuggestion assertSuggestEnumConst(String completion,
-      {bool isDeprecated: false}) {
-    CompletionSuggestion suggestion =
-        assertSuggest(completion, isDeprecated: isDeprecated);
-    expect(suggestion.isDeprecated, isDeprecated);
-    expect(suggestion.element.kind, protocol.ElementKind.ENUM_CONSTANT);
-    return suggestion;
-  }
-
-  CompletionSuggestion assertSuggestImportedClass(String name,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      String elemFile}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedConstructor(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT, String importUri}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedField(String name, String type,
-      {int relevance: DART_RELEVANCE_INHERITED_FIELD}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedFunction(
-      String name, String returnType,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool deprecated: false,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedFunctionTypeAlias(
-      String name, String returnType,
-      [bool isDeprecated = false,
-      int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedGetter(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_INHERITED_METHOD}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedSetter(String name,
-      {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedTopLevelVar(
-      String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestInvocationClass(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT]) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestClass(name, relevance: relevance);
-    } else {
-      return assertNotSuggested(name);
-    }
-  }
-
-  CompletionSuggestion assertSuggestInvocationField(String name, String type,
-      {int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestInvocationGetter(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestGetter(name, returnType,
-          relevance: relevance, isDeprecated: isDeprecated);
-    } else {
-      return assertNotSuggested(name);
-    }
-  }
-
-  CompletionSuggestion assertSuggestInvocationMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_DEFAULT}) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestMethod(name, declaringType, returnType,
-          relevance: relevance);
-    } else {
-      return assertNotSuggested(name);
-    }
-  }
-
-  CompletionSuggestion assertSuggestInvocationSetter(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT]) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestSetter(name);
-    } else {
-      return assertNotSuggested(name);
-    }
-  }
-
-  CompletionSuggestion assertSuggestInvocationTopLevelVar(
-      String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT]) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestTopLevelVar(name, returnType, relevance);
-    } else {
-      return assertNotSuggested(name);
-    }
-  }
-
-  CompletionSuggestion assertSuggestLocalClass(String name,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      bool isDeprecated: false,
-      String elemFile,
-      int elemOffset}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalClassTypeAlias(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalConstructor(String name,
-      {int elemOffset}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalField(String name, String type,
-      {int relevance: DART_RELEVANCE_LOCAL_FIELD, bool deprecated: false}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalFunction(
-      String name, String returnType,
-      {bool deprecated: false,
-      int relevance: DART_RELEVANCE_LOCAL_FUNCTION,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalFunctionTypeAlias(
-      String name, String returnType,
-      {bool deprecated: false, int relevance: DART_RELEVANCE_DEFAULT}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalGetter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_ACCESSOR, bool deprecated: false}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_METHOD, bool deprecated: false}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalSetter(String name,
-      {int relevance: DART_RELEVANCE_LOCAL_ACCESSOR}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalTopLevelVar(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalVariable(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestNonLocalClass(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    return assertSuggestImportedClass(name, relevance: relevance, kind: kind);
-  }
-
-  Future computeFull(assertFunction(bool result), {bool fullAnalysis: true}) {
-    return super
-        .computeFull(assertFunction, fullAnalysis: fullAnalysis)
-        .then(assertCachedCompute);
-  }
-
-  test_ArgumentList() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart';
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertSuggestLocalClass('B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_imported_function() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(arg) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertSuggestLocalClass('B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_InstanceCreationExpression_functionalArg() {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      class A { A(f()) { } }
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'dart:async';
-      import '/libA.dart';
-      class B { }
-      String bar() => true;
-      void main() {new A(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('hasLength', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('identical', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestLocalClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('A',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('Object',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_InstanceCreationExpression_typedefArg() {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      typedef Funct();
-      class A { A(Funct f) { } }
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'dart:async';
-      import '/libA.dart';
-      class B { }
-      String bar() => true;
-      void main() {new A(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('hasLength', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('identical', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestLocalClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('A',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('Object',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_local_function() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      expect(arg) { }
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertSuggestLocalClass('B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_local_method() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B {
-        expect(arg) { }
-        void foo() {expect(^)}}
-      String bar() => true;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertSuggestLocalClass('B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_MethodInvocation_functionalArg() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      class A { A(f()) { } }
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'dart:async';
-      import '/libA.dart';
-      class B { }
-      String bar(f()) => true;
-      void main() {bar(^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('hasLength', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('identical', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestLocalClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('A',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('Object',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_MethodInvocation_methodArg() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      class A { A(f()) { } }
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'dart:async';
-      import '/libA.dart';
-      class B { String bar(f()) => true; }
-      void main() {new B().bar(^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestImportedFunction('hasLength', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('identical', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestLocalClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('A',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('Object',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_namedParam() {
-    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
-    // ExpressionStatement
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }''');
-    addTestSource('''
-      import '/libA.dart'
-      String bar() => true;
-      void main() {expect(foo: ^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertNotSuggested('main');
-    });
-  }
-
-  test_AsExpression() {
-    // SimpleIdentifier  TypeName  AsExpression
-    addTestSource('''
-      class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertSuggestImportedClass('Object');
-      assertSuggestLocalClass('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_AssignmentExpression_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('class A {} main() {int a; int ^b = 1;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_AssignmentExpression_RHS() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('class A {} main() {int a; int b = ^}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestLocalFunction('main', null);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_AssignmentExpression_type() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      class A {} main() {
-        int a;
-        ^ b = 1;}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('int');
-      // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
-      // the user may be either (1) entering a type for the assignment
-      // or (2) starting a new statement.
-      // Consider suggesting only types
-      // if only spaces separates the 1st and 2nd identifiers.
-      //assertNotSuggested('a');
-      //assertNotSuggested('main');
-      //assertNotSuggested('identical');
-    });
-  }
-
-  test_AssignmentExpression_type_newline() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      class A {} main() {
-        int a;
-        ^
-        b = 1;}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('int');
-      // Allow non-types preceding an identifier on LHS of assignment
-      // if newline follows first identifier
-      // because user is probably starting a new statement
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestLocalFunction('main', null);
-      assertSuggestImportedFunction('identical', 'bool');
-    });
-  }
-
-  test_AssignmentExpression_type_partial() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      class A {} main() {
-        int a;
-        int^ b = 1;}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 3);
-      expect(request.replacementLength, 3);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('int');
-      // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
-      // the user may be either (1) entering a type for the assignment
-      // or (2) starting a new statement.
-      // Consider suggesting only types
-      // if only spaces separates the 1st and 2nd identifiers.
-      //assertNotSuggested('a');
-      //assertNotSuggested('main');
-      //assertNotSuggested('identical');
-    });
-  }
-
-  test_AssignmentExpression_type_partial_newline() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      class A {} main() {
-        int a;
-        i^
-        b = 1;}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('int');
-      // Allow non-types preceding an identifier on LHS of assignment
-      // if newline follows first identifier
-      // because user is probably starting a new statement
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestLocalFunction('main', null);
-      assertSuggestImportedFunction('identical', 'bool');
-    });
-  }
-
-  test_AwaitExpression() {
-    // SimpleIdentifier  AwaitExpression  ExpressionStatement
-    addTestSource('''
-      class A {int x; int y() => 0;}
-      main() async {A a; await ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'A');
-      assertSuggestLocalFunction('main', null);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_BinaryExpression_LHS() {
-    // SimpleIdentifier  BinaryExpression  VariableDeclaration
-    // VariableDeclarationList  VariableDeclarationStatement
-    addTestSource('main() {int a = 1, b = ^ + 2;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('b');
-    });
-  }
-
-  test_BinaryExpression_RHS() {
-    // SimpleIdentifier  BinaryExpression  VariableDeclaration
-    // VariableDeclarationList  VariableDeclarationStatement
-    addTestSource('main() {int a = 1, b = 2 + ^;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('b');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_Block() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          var f;
-          localF(int arg1) { }
-          {var x;}
-          ^ var r;
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-
-      assertSuggestLocalClass('X', elemFile: testFile);
-      assertSuggestLocalClass('Z');
-      assertSuggestLocalMethod('a', 'X', null);
-      assertSuggestLocalMethod('b', 'X', 'void');
-      assertSuggestLocalFunction('localF', null);
-      assertSuggestLocalVariable('f', null);
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-      assertNotSuggested('partT8');
-
-      assertSuggestImportedClass('A', elemFile: '/testAB.dart');
-      assertNotSuggested('_B');
-      assertSuggestImportedClass('C');
-      assertNotSuggested('partBoo');
-      // hidden element suggested as low relevance
-      // but imported results are partially filtered
-      //assertSuggestImportedClass('D', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedFunction(
-      //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
-      assertSuggestLocalFunction('D2', 'Z');
-      assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      assertSuggestLibraryPrefix('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      assertSuggestImportedClass('Object');
-      assertSuggestImportedFunction('min', 'num');
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      if (contributor is ImportedReferenceContributor) {
-        // TODO(danrubel) should be top level var suggestion
-        assertSuggestGetter('T1', 'String');
-      }
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      assertSuggestLocalTopLevelVar('T5', 'int');
-      assertSuggestLocalTopLevelVar('_T6', null,
-          relevance: DART_RELEVANCE_DEFAULT);
-      assertNotSuggested('==');
-      assertSuggestLocalGetter('T7', 'String');
-      assertSuggestLocalSetter('T8');
-      assertSuggestLocalGetter('clog', 'int');
-      assertSuggestLocalSetter('blog');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-      assertSuggestImportedClass('Uri');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_final() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          var f;
-          localF(int arg1) { }
-          {var x;}
-          final ^
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-
-      assertSuggestLocalClass('X');
-      assertSuggestLocalClass('Z');
-      assertNotSuggested('a');
-      assertNotSuggested('b');
-      assertNotSuggested('localF');
-      assertNotSuggested('f');
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-      assertNotSuggested('partT8');
-
-      assertSuggestImportedClass('A');
-      assertNotSuggested('_B');
-      assertSuggestImportedClass('C');
-      assertNotSuggested('partBoo');
-      // hidden element suggested as low relevance
-      // but imported results are partially filtered
-      //assertSuggestImportedClass('D', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedFunction(
-      //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('D2');
-      assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      assertSuggestLibraryPrefix('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('min');
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('T1');
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      assertNotSuggested('T5');
-      assertNotSuggested('_T6');
-      assertNotSuggested('==');
-      assertNotSuggested('T7');
-      assertNotSuggested('T8');
-      assertNotSuggested('clog');
-      assertNotSuggested('blog');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-      assertSuggestImportedClass('Uri');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_final2() {
-    addTestSource('main() {final S^ v;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_Block_final3() {
-    addTestSource('main() {final ^ v;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_Block_final_final() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          final ^
-          final var f;
-          localF(int arg1) { }
-          {var x;}
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-
-      assertSuggestLocalClass('X');
-      assertSuggestLocalClass('Z');
-      assertNotSuggested('a');
-      assertNotSuggested('b');
-      assertNotSuggested('localF');
-      assertNotSuggested('f');
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-      assertNotSuggested('partT8');
-
-      assertSuggestImportedClass('A');
-      assertNotSuggested('_B');
-      assertSuggestImportedClass('C');
-      assertNotSuggested('partBoo');
-      // hidden element suggested as low relevance
-      // but imported results are partially filtered
-      //assertSuggestImportedClass('D', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedFunction(
-      //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('D2');
-      assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      assertSuggestLibraryPrefix('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('min');
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('T1');
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      assertNotSuggested('T5');
-      assertNotSuggested('_T6');
-      assertNotSuggested('==');
-      assertNotSuggested('T7');
-      assertNotSuggested('T8');
-      assertNotSuggested('clog');
-      assertNotSuggested('blog');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-      assertSuggestImportedClass('Uri');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_final_var() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          final ^
-          var f;
-          localF(int arg1) { }
-          {var x;}
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-
-      assertSuggestLocalClass('X');
-      assertSuggestLocalClass('Z');
-      assertNotSuggested('a');
-      assertNotSuggested('b');
-      assertNotSuggested('localF');
-      assertNotSuggested('f');
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-      assertNotSuggested('partT8');
-
-      assertSuggestImportedClass('A');
-      assertNotSuggested('_B');
-      assertSuggestImportedClass('C');
-      assertNotSuggested('partBoo');
-      // hidden element suggested as low relevance
-      // but imported results are partially filtered
-      //assertSuggestImportedClass('D', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedFunction(
-      //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('D2');
-      assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      assertSuggestLibraryPrefix('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('min');
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('T1');
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      assertNotSuggested('T5');
-      assertNotSuggested('_T6');
-      assertNotSuggested('==');
-      assertNotSuggested('T7');
-      assertNotSuggested('T8');
-      assertNotSuggested('clog');
-      assertNotSuggested('blog');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-      assertSuggestImportedClass('Uri');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_identifier_partial() {
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      class D3 { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      Z D2() {int x;}
-      class X {a() {var f; {var x;} D^ var r;} void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-
-      assertSuggestLocalClass('X');
-      assertSuggestLocalClass('Z');
-      assertSuggestLocalMethod('a', 'X', null);
-      assertSuggestLocalMethod('b', 'X', 'void');
-      assertSuggestLocalVariable('f', null);
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-
-      // imported elements are portially filtered
-      //assertSuggestImportedClass('A');
-      assertNotSuggested('_B');
-      //assertSuggestImportedClass('C');
-      // hidden element suggested as low relevance
-      assertSuggestImportedClass('D',
-          relevance: DART_RELEVANCE_LOW, importUri: 'testCD.dart');
-      assertSuggestImportedFunction('D1', null,
-          deprecated: true, relevance: DART_RELEVANCE_LOW);
-      assertSuggestLocalFunction('D2', 'Z');
-      // unimported elements suggested with low relevance
-      assertSuggestImportedClass('D3',
-          relevance: DART_RELEVANCE_LOW, importUri: 'testH.dart');
-      //assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestLibraryPrefix('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedClass('Object');
-      //assertSuggestImportedFunction('min', 'num', false);
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      //assertSuggestTopLevelVarGetterSetter('T1', 'String');
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      //assertSuggestLocalTopLevelVar('T5', 'int');
-      //assertSuggestLocalTopLevelVar('_T6', null);
-      assertNotSuggested('==');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-    });
-  }
-
-  test_Block_inherited_imported() {
-    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
-      class E extends F { var e1; e2() { } }
-      class I { int i1; i2() { } }
-      class M { var m1; int m2() { } }''');
-    addTestSource('''
-      import "/testB.dart";
-      class A extends E implements I with M {a() {^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // TODO (danrubel) prefer fields over getters
-      // If add `get e1;` to interface I
-      // then suggestions include getter e1 rather than field e1
-      assertSuggestImportedField('e1', null);
-      assertSuggestImportedField('f1', null);
-      assertSuggestImportedField('i1', 'int');
-      assertSuggestImportedField('m1', null);
-      assertSuggestImportedGetter('f3', null);
-      assertSuggestImportedSetter('f4');
-      assertSuggestImportedMethod('e2', 'E', null);
-      assertSuggestImportedMethod('f2', 'F', null);
-      assertSuggestImportedMethod('i2', 'I', null);
-      //assertSuggestImportedMethod('m2', null, null);
-      assertNotSuggested('==');
-    });
-  }
-
-  test_Block_inherited_local() {
-    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addTestSource('''
-      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
-      class E extends F { var e1; e2() { } }
-      class I { int i1; i2() { } }
-      class M { var m1; int m2() { } }
-      class A extends E implements I with M {a() {^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalField('e1', null);
-      assertSuggestLocalField('f1', null);
-      assertSuggestLocalField('i1', 'int');
-      assertSuggestLocalField('m1', null);
-      assertSuggestLocalGetter('f3', null);
-      assertSuggestLocalSetter('f4');
-      assertSuggestLocalMethod('e2', 'E', null);
-      assertSuggestLocalMethod('f2', 'F', null);
-      assertSuggestLocalMethod('i2', 'I', null);
-      assertSuggestLocalMethod('m2', 'M', 'int');
-    });
-  }
-
-  test_Block_local_function() {
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          var f;
-          localF(int arg1) { }
-          {var x;}
-          p^ var r;
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-
-      assertNotSuggested('partT8');
-      assertNotSuggested('partBoo');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_unimported() {
-    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
-    addSource(
-        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
-    testFile = '/proj/completionTest.dart';
-    addTestSource('class C {foo(){F^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestImportedClass('Foo',
-          relevance: DART_RELEVANCE_LOW, importUri: 'testAB.dart');
-      // TODO(danrubel) implement
-      assertSuggestImportedClass('Foo2',
-          relevance: DART_RELEVANCE_LOW, importUri: 'package:myBar/bar.dart');
-      assertSuggestImportedClass('Future',
-          relevance: DART_RELEVANCE_LOW, importUri: 'dart:async');
-    });
-  }
-
-  test_CascadeExpression_selector1() {
-    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "/testB.dart";
-      class A {var b; X _c;}
-      class X{}
-      // looks like a cascade to the parser
-      // but the user is trying to get completions for a non-cascade
-      main() {A a; a.^.z}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-      assertNotSuggested('B');
-      assertNotSuggested('X');
-      assertNotSuggested('z');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_CascadeExpression_selector2() {
-    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "/testB.dart";
-      class A {var b; X _c;}
-      class X{}
-      main() {A a; a..^z}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 1);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-      assertNotSuggested('B');
-      assertNotSuggested('X');
-      assertNotSuggested('z');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_CascadeExpression_selector2_withTrailingReturn() {
-    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "/testB.dart";
-      class A {var b; X _c;}
-      class X{}
-      main() {A a; a..^ return}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-      assertNotSuggested('B');
-      assertNotSuggested('X');
-      assertNotSuggested('z');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_CascadeExpression_target() {
-    // SimpleIdentifier  CascadeExpression  ExpressionStatement
-    addTestSource('''
-      class A {var b; X _c;}
-      class X{}
-      main() {A a; a^..b}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertSuggestLocalVariable('a', 'A');
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('X');
-      // top level results are partially filtered
-      //assertSuggestImportedClass('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_CatchClause_onType() {
-    // TypeName  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on ^ {}}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('a');
-      assertNotSuggested('x');
-    });
-  }
-
-  test_CatchClause_onType_noBrackets() {
-    // TypeName  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on ^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A', elemOffset: 6);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('x');
-    });
-  }
-
-  test_CatchClause_typed() {
-    // Block  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('e', 'E');
-      assertSuggestLocalMethod('a', 'A', null);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('x');
-    });
-  }
-
-  test_CatchClause_untyped() {
-    // Block  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('e', null);
-      assertSuggestParameter('s', 'StackTrace');
-      assertSuggestLocalMethod('a', 'A', null);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('x');
-    });
-  }
-
-  test_ClassDeclaration_body() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      @deprecated class A {^}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      CompletionSuggestion suggestionA = assertSuggestLocalClass('A',
-          relevance: DART_RELEVANCE_LOW, isDeprecated: true);
-      if (suggestionA != null) {
-        expect(suggestionA.element.isDeprecated, isTrue);
-        expect(suggestionA.element.isPrivate, isFalse);
-      }
-      CompletionSuggestion suggestionB = assertSuggestLocalClass('_B');
-      if (suggestionB != null) {
-        expect(suggestionB.element.isDeprecated, isFalse);
-        expect(suggestionB.element.isPrivate, isTrue);
-      }
-      CompletionSuggestion suggestionO = assertSuggestImportedClass('Object');
-      if (suggestionO != null) {
-        expect(suggestionO.element.isDeprecated, isFalse);
-        expect(suggestionO.element.isPrivate, isFalse);
-      }
-      assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
-    });
-  }
-
-  test_ClassDeclaration_body_final() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      class A {final ^}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
-    });
-  }
-
-  test_ClassDeclaration_body_final_field() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      class A {final ^ A(){}}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('String');
-      assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
-    });
-  }
-
-  test_ClassDeclaration_body_final_field2() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as Soo;
-      class A {final S^ A();}
-      class _B {}
-      A Sew;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('String');
-      assertNotSuggested('Sew');
-      assertSuggestLibraryPrefix('Soo');
-    });
-  }
-
-  test_ClassDeclaration_body_final_final() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      class A {final ^ final foo;}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
-    });
-  }
-
-  test_ClassDeclaration_body_final_var() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      class A {final ^ var foo;}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
-    });
-  }
-
-  test_Combinator_hide() {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource(
-        '/testAB.dart',
-        '''
-      library libAB;
-      part '/partAB.dart';
-      class A { }
-      class B { }''');
-    addSource(
-        '/partAB.dart',
-        '''
-      part of libAB;
-      var T1;
-      PB F1() => new PB();
-      class PB { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      class C { }
-      class D { }''');
-    addTestSource('''
-      import "/testAB.dart" hide ^;
-      import "/testCD.dart";
-      class X {}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_Combinator_show() {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource(
-        '/testAB.dart',
-        '''
-      library libAB;
-      part '/partAB.dart';
-      class A { }
-      class B { }''');
-    addSource(
-        '/partAB.dart',
-        '''
-      part of libAB;
-      var T1;
-      PB F1() => new PB();
-      typedef PB2 F2(int blat);
-      class Clz = Object with Object;
-      class PB { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      class C { }
-      class D { }''');
-    addTestSource('''
-      import "/testAB.dart" show ^;
-      import "/testCD.dart";
-      class X {}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ConditionalExpression_elseExpression() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      // top level results are partially filtered based on first char
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConditionalExpression_elseExpression_empty() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNotSuggested('x');
-      assertSuggestLocalVariable('f', null);
-      assertSuggestLocalMethod('foo', 'C', null);
-      assertSuggestLocalClass('C');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestImportedClass('A');
-      assertSuggestImportedFunction('F1', null);
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConditionalExpression_partial_thenExpression() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? T^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      // top level results are partially filtered based on first char
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConditionalExpression_partial_thenExpression_empty() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNotSuggested('x');
-      assertSuggestLocalVariable('f', null);
-      assertSuggestLocalMethod('foo', 'C', null);
-      assertSuggestLocalClass('C');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestImportedClass('A');
-      assertSuggestImportedFunction('F1', null);
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConditionalExpression_thenExpression() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? T^ : c}}''');
-    computeFast();
-    return computeFull((bool result) {
-      // top level results are partially filtered based on first char
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConstructorName_importedClass() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int T1;
-      F1() { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      var m;
-      main() {new X.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestNamedConstructor('c', 'X');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('_d');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_ConstructorName_importedFactory() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int T1;
-      F1() { }
-      class X {factory X.c(); factory X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      var m;
-      main() {new X.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestNamedConstructor('c', 'X');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('_d');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_ConstructorName_importedFactory2() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('''
-      main() {new String.fr^omCharCodes([]);}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 2);
-      expect(request.replacementLength, 13);
-      assertSuggestNamedConstructor('fromCharCodes', 'String');
-      assertNotSuggested('isEmpty');
-      assertNotSuggested('isNotEmpty');
-      assertNotSuggested('length');
-      assertNotSuggested('Object');
-      assertNotSuggested('String');
-    });
-  }
-
-  test_ConstructorName_localClass() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('''
-      int T1;
-      F1() { }
-      class X {X.c(); X._d(); z() {}}
-      main() {new X.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestNamedConstructor('c', 'X');
-      assertSuggestNamedConstructor('_d', 'X');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_ConstructorName_localFactory() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('''
-      int T1;
-      F1() { }
-      class X {factory X.c(); factory X._d(); z() {}}
-      main() {new X.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestNamedConstructor('c', 'X');
-      assertSuggestNamedConstructor('_d', 'X');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_DefaultFormalParameter_named_expression() {
-    // DefaultFormalParameter FormalParameterList MethodDeclaration
-    addTestSource('''
-      foo() { }
-      void bar() { }
-      class A {a(blat: ^) { }}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalFunction('foo', null);
-      assertSuggestLocalMethod('a', 'A', null);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('String');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertNotSuggested('bar');
-    });
-  }
-
-  test_ExpressionStatement_identifier() {
-    // SimpleIdentifier  ExpressionStatement  Block
-    addSource(
-        '/testA.dart',
-        '''
-      _B F1() { }
-      class A {int x;}
-      class _B { }''');
-    addTestSource('''
-      import "/testA.dart";
-      typedef int F2(int blat);
-      class Clz = Object with Object;
-      class C {foo(){^} void bar() {}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('A');
-      assertSuggestImportedFunction('F1', '_B');
-      assertSuggestLocalClass('C');
-      assertSuggestLocalMethod('foo', 'C', null);
-      assertSuggestLocalMethod('bar', 'C', 'void');
-      assertSuggestLocalFunctionTypeAlias('F2', 'int');
-      assertSuggestLocalClassTypeAlias('Clz');
-      assertSuggestLocalClass('C');
-      assertNotSuggested('x');
-      assertNotSuggested('_B');
-    });
-  }
-
-  test_ExpressionStatement_name() {
-    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testA.dart',
-        '''
-      B T1;
-      class B{}''');
-    addTestSource('''
-      import "/testA.dart";
-      class C {a() {C ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_FieldDeclaration_name_typed() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // FieldDeclaration
-    addSource('/testA.dart', 'class A { }');
-    addTestSource('''
-      import "/testA.dart";
-      class C {A ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_FieldDeclaration_name_var() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // FieldDeclaration
-    addSource('/testA.dart', 'class A { }');
-    addTestSource('''
-      import "/testA.dart";
-      class C {var ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_FieldFormalParameter_in_non_constructor() {
-    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
-    addTestSource('class A {B(this.^foo) {}}');
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 3);
-      assertNoSuggestions();
-    });
-  }
-
-  test_ForEachStatement_body_typed() {
-    // Block  ForEachStatement
-    addTestSource('main(args) {for (int foo in bar) {^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('args', null);
-      assertSuggestLocalVariable('foo', 'int');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_ForEachStatement_body_untyped() {
-    // Block  ForEachStatement
-    addTestSource('main(args) {for (foo in bar) {^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('args', null);
-      assertSuggestLocalVariable('foo', null);
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_ForEachStatement_iterable() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (int foo in ^) {}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('args', null);
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_ForEachStatement_loopVariable() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (^ in args) {}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('args');
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_ForEachStatement_loopVariable_type() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (^ foo in args) {}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('args');
-      assertNotSuggested('foo');
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_ForEachStatement_loopVariable_type2() {
-    // DeclaredIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (S^ foo in args) {}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertNotSuggested('args');
-      assertNotSuggested('foo');
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_FormalParameterList() {
-    // FormalParameterList MethodDeclaration
-    addTestSource('''
-      foo() { }
-      void bar() { }
-      class A {a(^) { }}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('foo');
-      assertNotSuggested('a');
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('String');
-      assertNotSuggested('identical');
-      assertNotSuggested('bar');
-    });
-  }
-
-  test_ForStatement_body() {
-    // Block  ForStatement
-    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('i', 'int');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_ForStatement_condition() {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {for (int index = 0; i^)}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalVariable('index', 'int');
-    });
-  }
-
-  test_ForStatement_initializer() {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {List a; for (^)}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'List');
-      assertSuggestImportedClass('Object');
-      assertSuggestImportedClass('int');
-    });
-  }
-
-  test_ForStatement_updaters() {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {for (int index = 0; index < 10; i^)}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalVariable('index', 'int');
-    });
-  }
-
-  test_ForStatement_updaters_prefix_expression() {
-    // SimpleIdentifier  PrefixExpression  ForStatement
-    addTestSource('''
-      void bar() { }
-      main() {for (int index = 0; index < 10; ++i^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalVariable('index', 'int');
-      assertSuggestLocalFunction('main', null);
-      assertNotSuggested('bar');
-    });
-  }
-
-  test_FunctionDeclaration_returnType_afterComment() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      /* */ ^ zoo(z) { } String name;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_FunctionDeclaration_returnType_afterComment2() {
-    // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      /** */ ^ zoo(z) { } String name;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_FunctionDeclaration_returnType_afterComment3() {
-    // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      /// some dartdoc
-      class C2 { }
-      ^ zoo(z) { } String name;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_FunctionExpression_body_function() {
-    // Block  BlockFunctionBody  FunctionExpression
-    addTestSource('''
-      void bar() { }
-      String foo(List args) {x.then((R b) {^});}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      var f = assertSuggestLocalFunction('foo', 'String', deprecated: false);
-      if (f != null) {
-        expect(f.element.isPrivate, isFalse);
-      }
-      assertSuggestLocalFunction('bar', 'void');
-      assertSuggestParameter('args', 'List');
-      assertSuggestParameter('b', 'R');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_IfStatement() {
-    // SimpleIdentifier  IfStatement
-    addTestSource('''
-      class A {var b; X _c; foo() {A a; if (true) ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalField('b', null);
-      assertSuggestLocalField('_c', 'X');
-      assertSuggestImportedClass('Object');
-      assertSuggestLocalClass('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_IfStatement_condition() {
-    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
-    addTestSource('''
-      class A {int x; int y() => 0;}
-      main(){var a; if (^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', null);
-      assertSuggestLocalFunction('main', null);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_IfStatement_empty() {
-    // SimpleIdentifier  IfStatement
-    addTestSource('''
-      class A {var b; X _c; foo() {A a; if (^) something}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalField('b', null);
-      assertSuggestLocalField('_c', 'X');
-      assertSuggestImportedClass('Object');
-      assertSuggestLocalClass('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_IfStatement_invocation() {
-    // SimpleIdentifier  PrefixIdentifier  IfStatement
-    addTestSource('''
-      main() {var a; if (a.^) something}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationMethod('toString', 'Object', 'String');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ImportDirective_dart() {
-    // SimpleStringLiteral  ImportDirective
-    addTestSource('''
-      import "dart^";
-      main() {}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_IndexExpression() {
-    // ExpressionStatement  Block
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} f[^]}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNotSuggested('x');
-      assertSuggestLocalVariable('f', null);
-      assertSuggestLocalMethod('foo', 'C', null);
-      assertSuggestLocalClass('C');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestImportedClass('A');
-      assertSuggestImportedFunction('F1', null);
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_IndexExpression2() {
-    // SimpleIdentifier IndexExpression ExpressionStatement  Block
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} f[T^]}}''');
-    computeFast();
-    return computeFull((bool result) {
-      // top level results are partially filtered based on first char
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_InstanceCreationExpression_imported() {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {A(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      import "dart:async";
-      int T2;
-      F2() { }
-      class B {B(this.x, [String boo]) { } int x;}
-      class C {foo(){var f; {var x;} new ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedConstructor('Object');
-      assertSuggestImportedConstructor('Future');
-      assertSuggestImportedConstructor('A');
-      assertSuggestLocalConstructor('B');
-      assertSuggestLocalConstructor('C');
-      assertNotSuggested('f');
-      assertNotSuggested('x');
-      assertNotSuggested('foo');
-      assertNotSuggested('F1');
-      assertNotSuggested('F2');
-      assertNotSuggested('T1');
-      assertNotSuggested('T2');
-    });
-  }
-
-  test_InstanceCreationExpression_unimported() {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addSource('/testAB.dart', 'class Foo { }');
-    addTestSource('class C {foo(){new F^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestImportedConstructor('Future',
-          relevance: DART_RELEVANCE_LOW, importUri: 'dart:async');
-      assertSuggestImportedConstructor('Foo',
-          relevance: DART_RELEVANCE_LOW, importUri: 'testAB.dart');
-    });
-  }
-
-  test_InterpolationExpression() {
-    // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      main() {String name; print("hello \$^");}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('Object');
-      // TODO(danrubel) should return top level var rather than getter
-      if (contributor is ImportedReferenceContributor) {
-        //assertSuggestImportedTopLevelVar('T1', 'int');
-        assertSuggestGetter('T1', 'int');
-      }
-      assertSuggestImportedFunction('F1', null);
-      assertNotSuggested('D1');
-      assertNotSuggested('C1');
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestLocalFunction('F2', null);
-      assertNotSuggested('D2');
-      assertNotSuggested('C2');
-      assertSuggestLocalVariable('name', 'String');
-    });
-  }
-
-  test_InterpolationExpression_block() {
-    // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      main() {String name; print("hello \${^}");}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      // TODO(danrubel) should return top level var rather than getter
-      if (contributor is ImportedReferenceContributor) {
-        //assertSuggestImportedTopLevelVar('T1', 'int');
-        assertSuggestGetter('T1', 'int');
-      }
-      assertSuggestImportedFunction('F1', null);
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertSuggestLocalVariable('name', 'String');
-    });
-  }
-
-  test_InterpolationExpression_block2() {
-    // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addTestSource('main() {String name; print("hello \${n^}");}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalVariable('name', 'String');
-      // top level results are partially filtered
-      //assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_InterpolationExpression_prefix_selector() {
-    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
-    addTestSource('main() {String name; print("hello \${name.^}");}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('length', 'int');
-      assertNotSuggested('name');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_InterpolationExpression_prefix_selector2() {
-    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
-    addTestSource('main() {String name; print("hello \$name.^");}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_InterpolationExpression_prefix_target() {
-    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
-    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalVariable('name', 'String');
-      // top level results are partially filtered
-      //assertSuggestImportedClass('Object');
-      assertNotSuggested('length');
-    });
-  }
-
-  test_IsExpression() {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      foo() { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      class Y {Y.c(); Y._d(); z() {}}
-      main() {var x; if (x is ^) { }}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('X');
-      assertSuggestLocalClass('Y');
-      assertNotSuggested('x');
-      assertNotSuggested('main');
-      assertNotSuggested('foo');
-    });
-  }
-
-  test_IsExpression_target() {
-    // IfStatement  Block  BlockFunctionBody
-    addTestSource('''
-      foo() { }
-      void bar() { }
-      class A {int x; int y() => 0;}
-      main(){var a; if (^ is A)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', null);
-      assertSuggestLocalFunction('main', null);
-      assertSuggestLocalFunction('foo', null);
-      assertNotSuggested('bar');
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_IsExpression_type() {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addTestSource('''
-      class A {int x; int y() => 0;}
-      main(){var a; if (a is ^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('a');
-      assertNotSuggested('main');
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_IsExpression_type_partial() {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addTestSource('''
-      class A {int x; int y() => 0;}
-      main(){var a; if (a is Obj^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 3);
-      expect(request.replacementLength, 3);
-      assertNotSuggested('a');
-      assertNotSuggested('main');
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_keyword() {
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int newT1;
-      int T1;
-      nowIsIt() { }
-      class X {factory X.c(); factory X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      String newer() {}
-      var m;
-      main() {new^ X.c();}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 3);
-      expect(request.replacementLength, 3);
-      assertNotSuggested('c');
-      assertNotSuggested('_d');
-      // Imported suggestion are filtered by 1st character
-      assertSuggestImportedFunction('nowIsIt', null);
-      assertNotSuggested('T1');
-      // TODO (danrubel) this really should be TopLevelVar not getter/setter
-      if (contributor is ImportedReferenceContributor) {
-        assertSuggestGetter('newT1', 'int');
-      }
-      assertNotSuggested('z');
-      assertSuggestLocalTopLevelVar('m', 'dynamic');
-      assertSuggestLocalFunction('newer', 'String');
-    });
-  }
-
-  test_Literal_list() {
-    // ']'  ListLiteral  ArgumentList  MethodInvocation
-    addTestSource('main() {var Some; print([^]);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalVariable('Some', null);
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_Literal_list2() {
-    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
-    addTestSource('main() {var Some; print([S^]);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalVariable('Some', null);
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_Literal_string() {
-    // SimpleStringLiteral  ExpressionStatement  Block
-    addTestSource('class A {a() {"hel^lo"}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_MapLiteralEntry() {
-    // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      foo = {^''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      // TODO(danrubel) Should be top level variable
-      if (contributor is ImportedReferenceContributor) {
-        assertSuggestGetter('T1', 'int');
-        // assertSuggestImportedTopLevelVar('T1', 'int');
-      }
-      assertSuggestImportedFunction('F1', null);
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-    });
-  }
-
-  test_MapLiteralEntry1() {
-    // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      foo = {T^''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      // TODO(danrubel) Should be top level variable
-      if (contributor is ImportedReferenceContributor) {
-        assertSuggestGetter('T1', 'int');
-        // assertSuggestImportedTopLevelVar('T1', 'int');
-      }
-      assertSuggestLocalTopLevelVar('T2', 'int');
-    });
-  }
-
-  test_MapLiteralEntry2() {
-    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      foo = {7:T^};''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      // TODO(danrubel) Should be top level variable
-      if (contributor is ImportedReferenceContributor) {
-        assertSuggestGetter('T1', 'int');
-        // assertSuggestImportedTopLevelVar('T1', 'int');
-      }
-      assertSuggestLocalTopLevelVar('T2', 'int');
-    });
-  }
-
-  test_MethodDeclaration_body_getters() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      CompletionSuggestion methodA = assertSuggestLocalMethod('a', 'A', 'Z');
-      if (methodA != null) {
-        expect(methodA.element.isDeprecated, isFalse);
-        expect(methodA.element.isPrivate, isFalse);
-      }
-      CompletionSuggestion getterF = assertSuggestLocalGetter('f', 'X',
-          relevance: DART_RELEVANCE_LOW, deprecated: true);
-      if (getterF != null) {
-        expect(getterF.element.isDeprecated, isTrue);
-        expect(getterF.element.isPrivate, isFalse);
-      }
-      CompletionSuggestion getterG = assertSuggestLocalGetter('_g', null,
-          relevance: DART_RELEVANCE_DEFAULT);
-      if (getterG != null) {
-        expect(getterG.element.isDeprecated, isFalse);
-        expect(getterG.element.isPrivate, isTrue);
-      }
-    });
-  }
-
-  test_MethodDeclaration_body_static() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testC.dart',
-        '''
-      class C {
-        c1() {}
-        var c2;
-        static c3() {}
-        static var c4;}''');
-    addTestSource('''
-      import "/testC.dart";
-      class B extends C {
-        b1() {}
-        var b2;
-        static b3() {}
-        static var b4;}
-      class A extends B {
-        a1() {}
-        var a2;
-        static a3() {}
-        static var a4;
-        static a() {^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNotSuggested('a1');
-      assertNotSuggested('a2');
-      assertSuggestLocalMethod('a3', 'A', null);
-      assertSuggestLocalField('a4', null);
-      assertNotSuggested('b1');
-      assertNotSuggested('b2');
-      assertNotSuggested('b3');
-      assertNotSuggested('b4');
-      assertNotSuggested('c1');
-      assertNotSuggested('c2');
-      assertNotSuggested('c3');
-      assertNotSuggested('c4');
-    });
-  }
-
-  test_MethodDeclaration_members() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      CompletionSuggestion methodA = assertSuggestLocalMethod('_a', 'A', 'Z',
-          relevance: DART_RELEVANCE_DEFAULT);
-      if (methodA != null) {
-        expect(methodA.element.isDeprecated, isFalse);
-        expect(methodA.element.isPrivate, isTrue);
-      }
-      CompletionSuggestion getterF = assertSuggestLocalField('f', 'X',
-          relevance: DART_RELEVANCE_LOW, deprecated: true);
-      if (getterF != null) {
-        expect(getterF.element.isDeprecated, isTrue);
-        expect(getterF.element.isPrivate, isFalse);
-        expect(getterF.element.parameters, isNull);
-      }
-      CompletionSuggestion getterG = assertSuggestLocalField('_g', null);
-      if (getterG != null) {
-        expect(getterG.element.isDeprecated, isFalse);
-        expect(getterG.element.isPrivate, isTrue);
-        expect(getterF.element.parameters, isNull);
-      }
-      assertSuggestImportedClass('bool');
-    });
-  }
-
-  test_MethodDeclaration_parameters_named() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      CompletionSuggestion methodA = assertSuggestLocalMethod('a', 'A', 'Z',
-          relevance: DART_RELEVANCE_LOW, deprecated: true);
-      if (methodA != null) {
-        expect(methodA.element.isDeprecated, isTrue);
-        expect(methodA.element.isPrivate, isFalse);
-      }
-      assertSuggestParameter('x', 'X');
-      assertSuggestParameter('y', null);
-      assertSuggestParameter('b', null);
-      assertSuggestImportedClass('int');
-      assertNotSuggested('_');
-    });
-  }
-
-  test_MethodDeclaration_parameters_positional() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('''
-      foo() { }
-      void bar() { }
-      class A {Z a(X x, [int y=1]) {^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalFunction('foo', null);
-      assertSuggestLocalFunction('bar', 'void');
-      assertSuggestLocalMethod('a', 'A', 'Z');
-      assertSuggestParameter('x', 'X');
-      assertSuggestParameter('y', 'int');
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_MethodDeclaration_returnType() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 {^ zoo(z) { } String name; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_MethodDeclaration_returnType_afterComment() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 {/* */ ^ zoo(z) { } String name; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_MethodDeclaration_returnType_afterComment2() {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 {/** */ ^ zoo(z) { } String name; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_MethodDeclaration_returnType_afterComment3() {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 {
-        /// some dartdoc
-        ^ zoo(z) { } String name; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_MethodInvocation_no_semicolon() {
-    // MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {x.^ m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('f', 'X');
-      assertSuggestInvocationGetter('_g', null);
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('a');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_new_instance() {
-    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationMethod('nextBool', 'Random', 'bool');
-      assertSuggestInvocationMethod('nextDouble', 'Random', 'double');
-      assertSuggestInvocationMethod('nextInt', 'Random', 'int');
-      assertNotSuggested('Random');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-    });
-  }
-
-  test_parameterName_excludeTypes() {
-    addTestSource('m(int ^) {}');
-    return computeFull((bool result) {
-      assertNotSuggested('int');
-      assertNotSuggested('bool');
-    });
-  }
-
-  test_partFile_TypeName() {
-    // SimpleIdentifier  TypeName  ConstructorName
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int T1;
-      F1() { }
-      class X {X.c(); X._d(); z() {}}''');
-    addSource(
-        '/testA.dart',
-        '''
-      library libA;
-      import "/testB.dart";
-      part "$testFile";
-      class A { }
-      var m;''');
-    addTestSource('''
-      part of libA;
-      class B { factory B.bar(int x) => null; }
-      main() {new ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalConstructor('B.bar');
-      assertSuggestImportedConstructor('Object');
-      assertSuggestImportedConstructor('X.c');
-      assertNotSuggested('X._d');
-      assertSuggestImportedConstructor('A');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('_d');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_partFile_TypeName2() {
-    // SimpleIdentifier  TypeName  ConstructorName
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int T1;
-      F1() { }
-      class X {X.c(); X._d(); z() {}}''');
-    addSource(
-        '/testA.dart',
-        '''
-      part of libA;
-      class B { }''');
-    addTestSource('''
-      library libA;
-      import "/testB.dart";
-      part "/testA.dart";
-      class A { A({String boo: 'hoo'}) { } }
-      main() {new ^}
-      var m;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalConstructor('A');
-      assertSuggestImportedConstructor('Object');
-      assertSuggestImportedConstructor('X.c');
-      assertNotSuggested('X._d');
-      assertSuggestImportedConstructor('B');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('_d');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_PrefixedIdentifier_class_const() {
-    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      class I {
-        static const scI = 'boo';
-        X get f => new A();
-        get _g => new A();}
-      class B implements I {
-        static const int scB = 12;
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        set s1(I x) {} set _s2(I x) {}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    addTestSource('''
-      import "/testB.dart";
-      class A extends B {
-        static const String scA = 'foo';
-        w() { }}
-      main() {A.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('scA', 'String');
-      assertSuggestInvocationField('scB', 'int');
-      assertSuggestInvocationField('scI', null);
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('a');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('w');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_class_imported() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        static const int sc = 12;
-        @deprecated var b; X _c;
-        X get d => new A();get _e => new A();
-        set s1(I x) {} set _s2(I x) {}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    addTestSource('''
-      import "/testB.dart";
-      main() {A a; a.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('sc');
-      assertSuggestInvocationField('b', null, isDeprecated: true);
-      assertNotSuggested('_c');
-      assertSuggestInvocationGetter('d', 'X');
-      assertNotSuggested('_e');
-      assertSuggestInvocationGetter('f', 'X');
-      assertNotSuggested('_g');
-      assertSuggestInvocationSetter('s1');
-      assertNotSuggested('_s2');
-      assertSuggestInvocationMethod('m', 'A', null);
-      assertNotSuggested('_n');
-      assertNotSuggested('a');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_class_local() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('''
-      main() {A a; a.^}
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        static const int sc = 12;
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        set s1(I x) {} set _s2(I x) {}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('sc');
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertSuggestInvocationGetter('d', 'X');
-      assertSuggestInvocationGetter('_e', null);
-      assertSuggestInvocationGetter('f', 'X');
-      assertSuggestInvocationGetter('_g', null);
-      assertSuggestInvocationSetter('s1');
-      assertSuggestInvocationSetter('_s2');
-      assertSuggestInvocationMethod('m', 'A', null);
-      assertSuggestInvocationMethod('_n', 'A', 'I');
-      assertNotSuggested('a');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_getter() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('String get g => "one"; f() {g.^}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_library() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      var T1;
-      class X { }
-      class Y { }''');
-    addTestSource('''
-      import "/testB.dart" as b;
-      var T2;
-      class A { }
-      main() {b.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationClass('X');
-      assertSuggestInvocationClass('Y');
-      assertSuggestInvocationTopLevelVar('T1', null);
-      assertNotSuggested('T2');
-      assertNotSuggested('Object');
-      assertNotSuggested('b');
-      assertNotSuggested('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_library_typesOnly() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      var T1;
-      class X { }
-      class Y { }''');
-    addTestSource('''
-      import "/testB.dart" as b;
-      var T2;
-      class A { }
-      foo(b.^ f) {}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationClass('X');
-      assertSuggestInvocationClass('Y');
-      assertNotSuggested('T1');
-      assertNotSuggested('T2');
-      assertNotSuggested('Object');
-      assertNotSuggested('b');
-      assertNotSuggested('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_library_typesOnly2() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      var T1;
-      class X { }
-      class Y { }''');
-    addTestSource('''
-      import "/testB.dart" as b;
-      var T2;
-      class A { }
-      foo(b.^) {}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationClass('X');
-      assertSuggestInvocationClass('Y');
-      assertNotSuggested('T1');
-      assertNotSuggested('T2');
-      assertNotSuggested('Object');
-      assertNotSuggested('b');
-      assertNotSuggested('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_parameter() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      class _W {M y; var _z;}
-      class X extends _W {}
-      class M{}''');
-    addTestSource('''
-      import "/testB.dart";
-      foo(X x) {x.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('y', 'M');
-      assertNotSuggested('_z');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_prefix() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource(
-        '/testA.dart',
-        '''
-      class A {static int bar = 10;}
-      _B() {}''');
-    addTestSource('''
-      import "/testA.dart";
-      class X {foo(){A^.bar}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestImportedClass('A');
-      assertSuggestLocalClass('X');
-      assertSuggestLocalMethod('foo', 'X', null);
-      assertNotSuggested('bar');
-      assertNotSuggested('_B');
-    });
-  }
-
-  test_PrefixedIdentifier_propertyAccess() {
-    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
-    addTestSource('class A {String x; int get foo {x.^}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('isEmpty', 'bool');
-      assertSuggestInvocationMethod('compareTo', 'Comparable', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_propertyAccess_newStmt() {
-    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
-    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('isEmpty', 'bool');
-      assertSuggestInvocationMethod('compareTo', 'Comparable', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_const() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_field() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_function() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_getter() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_local_typed() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('f() {String g; g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_local_untyped() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_method() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_param() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_localVariableDeclarationName() {
-    addTestSource('main() {String m^}');
-    return computeFull((bool result) {
-      assertNotSuggested('main');
-      assertNotSuggested('min');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_param2() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('f(String g) {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_topLevelVar() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('String g; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PropertyAccess_expression() {
-    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
-    addTestSource('class A {a() {"hello".to^String().length}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 2);
-      expect(request.replacementLength, 8);
-      assertSuggestInvocationGetter('length', 'int');
-      assertNotSuggested('A');
-      assertNotSuggested('a');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PropertyAccess_noTarget() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addSource('/testAB.dart', 'class Foo { }');
-    addTestSource('class C {foo(){.^}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_PropertyAccess_noTarget2() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addSource('/testAB.dart', 'class Foo { }');
-    addTestSource('main() {.^}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_PropertyAccess_selector() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
-    addTestSource('class A {a() {"hello".length.^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('isEven', 'bool');
-      assertNotSuggested('A');
-      assertNotSuggested('a');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_SwitchStatement_c() {
-    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_SwitchStatement_case() {
-    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalClass('A');
-      assertSuggestLocalMethod('g', 'A', 'String');
-      assertSuggestLocalVariable('t', null);
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_SwitchStatement_empty() {
-    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {String g(int x) {switch(x) {^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ThisExpression_block() {
-    // MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A() {}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {this.^ m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertSuggestInvocationGetter('d', 'X');
-      assertSuggestInvocationGetter('_e', null);
-      assertSuggestInvocationGetter('f', 'X');
-      assertSuggestInvocationGetter('_g', null);
-      assertSuggestInvocationMethod('m', 'A', null);
-      assertSuggestInvocationMethod('_n', 'A', 'I');
-      assertSuggestInvocationSetter('s1');
-      assertSuggestInvocationSetter('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor() {
-    // MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A() {this.^}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertSuggestInvocationGetter('d', 'X');
-      assertSuggestInvocationGetter('_e', null);
-      assertSuggestInvocationGetter('f', 'X');
-      assertSuggestInvocationGetter('_g', null);
-      assertSuggestInvocationMethod('m', 'A', null);
-      assertSuggestInvocationMethod('_n', 'A', 'I');
-      assertSuggestInvocationSetter('s1');
-      assertSuggestInvocationSetter('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor_param() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A(this.^) {}
-        A.z() {}
-        var b; X _c; static sb;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('b', null,
-          relevance: DART_RELEVANCE_LOCAL_FIELD);
-      assertSuggestInvocationField('_c', 'X',
-          relevance: DART_RELEVANCE_LOCAL_FIELD);
-      assertNotSuggested('sb');
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor_param2() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A(this.b^) {}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestInvocationField('b', null,
-          relevance: DART_RELEVANCE_LOCAL_FIELD);
-      assertSuggestInvocationField('_c', 'X',
-          relevance: DART_RELEVANCE_LOCAL_FIELD);
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor_param3() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A(this.^b) {}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 1);
-      assertSuggestInvocationField('b', null,
-          relevance: DART_RELEVANCE_LOCAL_FIELD);
-      assertSuggestInvocationField('_c', 'X',
-          relevance: DART_RELEVANCE_LOCAL_FIELD);
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor_param4() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A(this.b, this.^) {}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('b');
-      assertSuggestInvocationField('_c', 'X',
-          relevance: DART_RELEVANCE_LOCAL_FIELD);
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_TopLevelVariableDeclaration_typed_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // TopLevelVariableDeclaration
-    addTestSource('class A {} B ^');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_TopLevelVariableDeclaration_untyped_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // TopLevelVariableDeclaration
-    addTestSource('class A {} var ^');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_TypeArgumentList() {
-    // SimpleIdentifier  BinaryExpression  ExpressionStatement
-    addSource(
-        '/testA.dart',
-        '''
-      class C1 {int x;}
-      F1() => 0;
-      typedef String T1(int blat);''');
-    addTestSource('''
-      import "/testA.dart";'
-      class C2 {int x;}
-      F2() => 0;
-      typedef int T2(int blat);
-      class C<E> {}
-      main() { C<^> c; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertSuggestImportedClass('C1');
-      assertSuggestImportedFunctionTypeAlias('T1', 'String');
-      assertSuggestLocalClass('C2');
-      assertSuggestLocalFunctionTypeAlias('T2', 'int');
-      assertNotSuggested('F1');
-      assertNotSuggested('F2');
-    });
-  }
-
-  test_TypeArgumentList2() {
-    // TypeName  TypeArgumentList  TypeName
-    addSource(
-        '/testA.dart',
-        '''
-      class C1 {int x;}
-      F1() => 0;
-      typedef String T1(int blat);''');
-    addTestSource('''
-      import "/testA.dart";'
-      class C2 {int x;}
-      F2() => 0;
-      typedef int T2(int blat);
-      class C<E> {}
-      main() { C<C^> c; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestImportedClass('C1');
-      assertSuggestLocalClass('C2');
-    });
-  }
-
-  test_VariableDeclaration_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      foo() { }
-      class _B { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      class Y {Y.c(); Y._d(); z() {}}
-      main() {var ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_VariableDeclarationList_final() {
-    // VariableDeclarationList  VariableDeclarationStatement  Block
-    addTestSource('main() {final ^} class C { }');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('Object');
-      assertSuggestLocalClass('C');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_VariableDeclarationStatement_RHS() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      foo() { }
-      class _B { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      class Y {Y.c(); Y._d(); z() {}}
-      class C {bar(){var f; {var x;} var e = ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('X');
-      assertNotSuggested('_B');
-      assertSuggestLocalClass('Y');
-      assertSuggestLocalClass('C');
-      assertSuggestLocalVariable('f', null);
-      assertNotSuggested('x');
-      assertNotSuggested('e');
-    });
-  }
-
-  test_VariableDeclarationStatement_RHS_missing_semicolon() {
-    // VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      foo1() { }
-      void bar1() { }
-      class _B { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      foo2() { }
-      void bar2() { }
-      class Y {Y.c(); Y._d(); z() {}}
-      class C {bar(){var f; {var x;} var e = ^ var g}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('X');
-      assertSuggestImportedFunction('foo1', null);
-      assertNotSuggested('bar1');
-      assertSuggestLocalFunction('foo2', null);
-      assertNotSuggested('bar2');
-      assertNotSuggested('_B');
-      assertSuggestLocalClass('Y');
-      assertSuggestLocalClass('C');
-      assertSuggestLocalVariable('f', null);
-      assertNotSuggested('x');
-      assertNotSuggested('e');
-    });
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
new file mode 100644
index 0000000..0a14ef1
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -0,0 +1,503 @@
+// 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 test.services.completion.dart.arglist;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(ArgListContributorTest);
+}
+
+@reflectiveTest
+class ArgListContributorTest extends DartCompletionContributorTest {
+  void assertNoOtherSuggestions(Iterable<CompletionSuggestion> expected) {
+    for (CompletionSuggestion suggestion in suggestions) {
+      if (!expected.contains(suggestion)) {
+        failedCompletion('did not expect completion: '
+            '${suggestion.completion}\n  $suggestion');
+      }
+    }
+  }
+
+  void assertSuggestArgumentList(
+      List<String> paramNames, List<String> paramTypes) {
+    // DEPRECATED... argument lists are no longer suggested.
+    // See https://github.com/dart-lang/sdk/issues/25197
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+
+    // CompletionSuggestionKind csKind = CompletionSuggestionKind.ARGUMENT_LIST;
+    // CompletionSuggestion cs = getSuggest(csKind: csKind);
+    // if (cs == null) {
+    //   failedCompletion('expected completion $csKind', suggestions);
+    // }
+    // assertSuggestArgumentList_params(
+    //     paramNames, paramTypes, cs.parameterNames, cs.parameterTypes);
+    // expect(cs.relevance, DART_RELEVANCE_HIGH);
+    // assertNoOtherSuggestions([cs]);
+  }
+
+  void assertSuggestArgumentList_params(
+      List<String> expectedNames,
+      List<String> expectedTypes,
+      List<String> actualNames,
+      List<String> actualTypes) {
+    if (actualNames != null &&
+        actualNames.length == expectedNames.length &&
+        actualTypes != null &&
+        actualTypes.length == expectedTypes.length) {
+      int index = 0;
+      while (index < expectedNames.length) {
+        if (actualNames[index] != expectedNames[index] ||
+            actualTypes[index] != expectedTypes[index]) {
+          break;
+        }
+        ++index;
+      }
+      if (index == expectedNames.length) {
+        return;
+      }
+    }
+    StringBuffer msg = new StringBuffer();
+    msg.writeln('Argument list not the same');
+    msg.writeln('  Expected names: $expectedNames');
+    msg.writeln('           found: $actualNames');
+    msg.writeln('  Expected types: $expectedTypes');
+    msg.writeln('           found: $actualTypes');
+    fail(msg.toString());
+  }
+
+  /**
+   * Assert that the specified suggestions are the only suggestions.
+   */
+  void assertSuggestArguments({List<String> namedArguments}) {
+    List<CompletionSuggestion> expected = new List<CompletionSuggestion>();
+    for (String name in namedArguments) {
+      expected.add(assertSuggest('$name: ',
+          csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
+          relevance: DART_RELEVANCE_NAMED_PARAMETER));
+    }
+    assertNoOtherSuggestions(expected);
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new ArgListContributor();
+  }
+
+  test_Annotation_local_constructor_named_param() async {
+    addTestSource('''
+class A { A({int one, String two: 'defaultValue'}) { } }
+@A(^) main() { }''');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['one', 'two']);
+  }
+
+  test_Annotation_imported_constructor_named_param() async {
+    addSource(
+        '/libA.dart',
+        '''
+library libA; class A { A({int one, String two: 'defaultValue'}) { } }''');
+    addTestSource('import "/libA.dart"; @A(^) main() { }');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['one', 'two']);
+  }
+
+  test_ArgumentList_getter() async {
+    addTestSource('class A {int get foo => 7; main() {foo(^)}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_imported_constructor_named_param() async {
+    //
+    addSource('/libA.dart', 'library libA; class A{A({int one}){}}');
+    addTestSource('import "/libA.dart"; main() { new A(^);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['one']);
+  }
+
+  test_ArgumentList_imported_constructor_named_param2() async {
+    //
+    addSource('/libA.dart', 'library libA; class A{A.foo({int one}){}}');
+    addTestSource('import "/libA.dart"; main() { new A.foo(^);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['one']);
+  }
+
+  test_ArgumentList_imported_function_0() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      expect() { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B { }
+      String bar() => true;
+      void main() {expect(a^)}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_imported_function_1() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      expect(String arg) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B { }
+      String bar() => true;
+      void main() {expect(^)}''');
+    await computeSuggestions();
+    assertSuggestArgumentList(['arg'], ['String']);
+  }
+
+  test_ArgumentList_imported_function_2() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      expect(String arg1, int arg2) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B { }
+      String bar() => true;
+      void main() {expect(^)}''');
+    await computeSuggestions();
+    assertSuggestArgumentList(['arg1', 'arg2'], ['String', 'int']);
+  }
+
+  test_ArgumentList_imported_function_3() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      expect(String arg1, int arg2, {bool arg3}) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B { }
+      String bar() => true;
+      void main() {expect(^)}''');
+    await computeSuggestions();
+    assertSuggestArgumentList(['arg1', 'arg2'], ['String', 'int']);
+  }
+
+  test_ArgumentList_imported_function_3a() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      expect(String arg1, int arg2, {bool arg3}) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B { }
+      String bar() => true;
+      void main() {expect('hello', ^)}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_imported_function_3b() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      expect(String arg1, int arg2, {bool arg3}) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B { }
+      String bar() => true;
+      void main() {expect('hello', ^x)}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_imported_function_3c() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      expect(String arg1, int arg2, {bool arg3}) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B { }
+      String bar() => true;
+      void main() {expect('hello', x^)}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_imported_function_3d() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      expect(String arg1, int arg2, {bool arg3}) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B { }
+      String bar() => true;
+      void main() {expect('hello', x ^)}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_imported_function_named_param() async {
+    //
+    addTestSource('main() { int.parse("16", ^);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
+  test_ArgumentList_imported_function_named_param1() async {
+    //
+    addTestSource('main() { int.parse("16", r^);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
+  test_ArgumentList_imported_function_named_param2() async {
+    //
+    addTestSource('main() { int.parse("16", radix: 7, ^);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['onError']);
+  }
+
+  test_ArgumentList_imported_function_named_param2a() async {
+    //
+    addTestSource('main() { int.parse("16", radix: ^);}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_imported_function_named_param_label1() async {
+    //
+    addTestSource('main() { int.parse("16", r^: 16);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
+  test_ArgumentList_imported_function_named_param_label2() async {
+    //
+    addTestSource('main() { int.parse("16", ^r: 16);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
+  test_ArgumentList_imported_function_named_param_label3() async {
+    //
+    addTestSource('main() { int.parse("16", ^: 16);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
+  test_ArgumentList_local_constructor_named_param() async {
+    //
+    addTestSource('''
+class A { A({int one, String two: 'defaultValue'}) { } }
+main() { new A(^);}''');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['one', 'two']);
+  }
+
+  test_ArgumentList_local_constructor_named_param2() async {
+    //
+    addTestSource('''
+class A { A.foo({int one, String two: 'defaultValue'}) { } }
+main() { new A.foo(^);}''');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['one', 'two']);
+  }
+
+  test_ArgumentList_local_function_1() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      import '/libA.dart'
+      expect(arg) { }
+      class B { }
+      String bar() => true;
+      void main() {expect(^)}''');
+    await computeSuggestions();
+    assertSuggestArgumentList(['arg'], ['dynamic']);
+  }
+
+  test_ArgumentList_local_function_2() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      import '/libA.dart'
+      expect(arg1, int arg2) { }
+      class B { }
+      String bar() => true;
+      void main() {expect(^)}''');
+    await computeSuggestions();
+    assertSuggestArgumentList(['arg1', 'arg2'], ['dynamic', 'int']);
+  }
+
+  test_ArgumentList_local_function_3() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      import '/libA.dart'
+      expect(arg1, int arg2) { }
+      class B { }
+      String bar() => true;
+      void main() {expect(^)}''');
+    await computeSuggestions();
+    assertSuggestArgumentList(['arg1', 'arg2'], ['dynamic', 'int']);
+  }
+
+  test_ArgumentList_local_function_3a() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      import '/libA.dart'
+      expect(arg1, int arg2, {bool arg3}) { }
+      class B { }
+      String bar() => true;
+      void main() {expect('hello', ^)}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_local_function_3b() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      import '/libA.dart'
+      expect(arg1, int arg2, {bool arg3}) { }
+      class B { }
+      String bar() => true;
+      void main() {expect('hello', ^x)}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_local_function_3c() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      import '/libA.dart'
+      expect(arg1, int arg2, {bool arg3}) { }
+      class B { }
+      String bar() => true;
+      void main() {expect('hello', x^)}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_local_function_3d() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      import '/libA.dart'
+      expect(arg1, int arg2, {bool arg3}) { }
+      class B { }
+      String bar() => true;
+      void main() {expect('hello', x ^)}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_local_function_named_param() async {
+    //
+    addTestSource('''
+f(v,{int radix, int onError(String s)}){}
+main() { f("16", ^);}''');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
+  test_ArgumentList_local_function_named_param1() async {
+    //
+    addTestSource('''
+f(v,{int radix, int onError(String s)}){}
+main() { f("16", r^);}''');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
+  test_ArgumentList_local_function_named_param2() async {
+    //
+    addTestSource('''
+f(v,{int radix, int onError(String s)}){}
+main() { f("16", radix: 7, ^);}''');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['onError']);
+  }
+
+  test_ArgumentList_local_function_named_param2a() async {
+    //
+    addTestSource('''
+f(v,{int radix, int onError(String s)}){}
+main() { f("16", radix: ^);}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_local_method_0() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B {
+        expect() { }
+        void foo() {expect(^)}}
+      String bar() => true;''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ArgumentList_local_method_2() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+      library A;
+      bool hasLength(int expected) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B {
+        expect(arg, int blat) { }
+        void foo() {expect(^)}}
+      String bar() => true;''');
+    await computeSuggestions();
+    assertSuggestArgumentList(['arg', 'blat'], ['dynamic', 'int']);
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
new file mode 100644
index 0000000..921525b
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
@@ -0,0 +1,153 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.services.completion.dart.combinator;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/combinator_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(CombinatorContributorTest);
+}
+
+@reflectiveTest
+class CombinatorContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new CombinatorContributor();
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+      class F { var f1; f2() { } }
+      class E extends F { var e1; e2() { } }
+      class I { int i1; i2() { } }
+      class M { var m1; int m2() { } }
+      class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_Combinator_hide() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    Source importedLibSource = addSource(
+        '/testAB.dart',
+        '''
+      library libAB;
+      part '/partAB.dart';
+      class A { }
+      class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+      part of libAB;
+      var T1;
+      PB F1() => new PB();
+      class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+      class C { }
+      class D { }''');
+    addTestSource('''
+      import "/testAB.dart" hide ^;
+      import "/testCD.dart";
+      class X {}''');
+
+    // Assume that imported libraries have been resolved
+    context.resolveCompilationUnit2(importedLibSource, importedLibSource);
+
+    await computeSuggestions();
+    assertSuggestClass('A',
+        relevance: DART_RELEVANCE_DEFAULT,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('B',
+        relevance: DART_RELEVANCE_DEFAULT,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('PB',
+        relevance: DART_RELEVANCE_DEFAULT,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestTopLevelVar('T1', null,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('F1', 'PB',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('C');
+    assertNotSuggested('D');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+  }
+
+  test_Combinator_show() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    Source importedLibSource = addSource(
+        '/testAB.dart',
+        '''
+      library libAB;
+      part '/partAB.dart';
+      class A { }
+      class B { }
+      class _AB''');
+    addSource(
+        '/partAB.dart',
+        '''
+      part of libAB;
+      var T1;
+      PB F1() => new PB();
+      typedef PB2 F2(int blat);
+      class Clz = Object with Object;
+      class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+      class C { }
+      class D { }''');
+    addTestSource('''
+      import "/testAB.dart" show ^;
+      import "/testCD.dart";
+      class X {}''');
+
+    // Assume that imported libraries have been resolved
+    context.resolveCompilationUnit2(importedLibSource, importedLibSource);
+
+    await computeSuggestions();
+    assertSuggestClass('A',
+        relevance: DART_RELEVANCE_DEFAULT,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('B',
+        relevance: DART_RELEVANCE_DEFAULT,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('_AB');
+    assertSuggestClass('PB',
+        relevance: DART_RELEVANCE_DEFAULT,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestTopLevelVar('T1', null,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('F1', 'PB',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('Clz',
+        relevance: DART_RELEVANCE_DEFAULT,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunctionTypeAlias('F2', null,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('C');
+    assertNotSuggested('D');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+  }
+
+  test_Combinator_show_PI() async {
+    addTestSource('import "dart:math" show ^;');
+    await computeSuggestions();
+    assertSuggestTopLevelVar('PI', 'double',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
new file mode 100644
index 0000000..498b3d1
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
@@ -0,0 +1,150 @@
+// 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 test.services.completion.dart.sorter.common;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../domain_completion_util.dart';
+import '../../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(CommonUsageSorterTest);
+}
+
+@reflectiveTest
+class CommonUsageSorterTest extends AbstractCompletionDomainTest {
+  Future getSuggestionsWith(Map<String, List<String>> selectorRelevance) async {
+    var originalSorter = DartCompletionManager.contributionSorter;
+    DartCompletionManager.contributionSorter =
+        new CommonUsageSorter(selectorRelevance);
+    try {
+      return await getSuggestions();
+    } finally {
+      DartCompletionManager.contributionSorter = originalSorter;
+    }
+  }
+
+  test_ConstructorName() async {
+    // SimpleIdentifier  ConstructorName  InstanceCreationExpression
+    addTestFile('import "dart:async"; class A {x() {new Future.^}}');
+    await getSuggestionsWith({
+      'dart.async.Future': ['value', 'wait']
+    });
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'delayed');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'value',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
+    assertNoResult('Future');
+    assertNoResult('Object');
+    assertNoResult('A');
+  }
+
+  test_PrefixedIdentifier_field() async {
+    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
+    addTestFile('class A {static int s1; static int s2; x() {A.^}}');
+    await getSuggestionsWith({
+      '.A': ['s2']
+    });
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
+    assertNoResult('Future');
+    assertNoResult('Object');
+    assertNoResult('A');
+  }
+
+  test_PrefixedIdentifier_field_inPart() async {
+    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
+    addFile('/project/bin/myLib.dart',
+        'library L; part "$testFile"; class A {static int s2;}');
+    addTestFile('part of L; foo() {A.^}');
+    await getSuggestionsWith({
+      'L.A': ['s2']
+    });
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
+    assertNoResult('Future');
+    assertNoResult('Object');
+    assertNoResult('A');
+  }
+
+  test_PrefixedIdentifier_getter() async {
+    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
+    addTestFile('class A {int get g1 => 1; int get g2 => 2; x() {new A().^}}');
+    await getSuggestionsWith({
+      '.A': ['g2']
+    });
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'g1');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'g2',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
+    assertNoResult('Future');
+    assertNoResult('Object');
+    assertNoResult('A');
+  }
+
+  test_PrefixedIdentifier_setter() async {
+    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
+    addTestFile('class A {set s1(v) {}; set s2(v) {}; x() {new A().^}}');
+    await getSuggestionsWith({
+      '.A': ['s2']
+    });
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
+    assertNoResult('Future');
+    assertNoResult('Object');
+    assertNoResult('A');
+  }
+
+  test_PrefixedIdentifier_static_method() async {
+    // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
+    addTestFile('import "dart:async"; class A {x() {Future.^}}');
+    await getSuggestionsWith({
+      'dart.async.Future': ['value', 'wait']
+    });
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'wait',
+        relevance: DART_RELEVANCE_COMMON_USAGE - 1);
+    assertNoResult('Future');
+    assertNoResult('Object');
+    assertNoResult('A');
+  }
+
+  test_PropertyAccess() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addTestFile('import "dart:math"; class A {x() {new Random().^}}');
+    await getSuggestionsWith({
+      'dart.math.Random': ['nextInt', 'nextDouble']
+    });
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextBool');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextDouble',
+        relevance: DART_RELEVANCE_COMMON_USAGE - 1);
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextInt',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
+    assertNoResult('Random');
+    assertNoResult('Object');
+    assertNoResult('A');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
new file mode 100644
index 0000000..28c6a09
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -0,0 +1,547 @@
+// 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 test.services.completion.dart.util;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
+    show DartCompletionRequestImpl, ReplacementRange;
+import 'package:analysis_server/src/services/index/index.dart';
+import 'package:analysis_server/src/services/index/local_memory_index.dart';
+import 'package:analysis_server/src/services/search/search_engine_internal.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../abstract_context.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+
+int suggestionComparator(CompletionSuggestion s1, CompletionSuggestion s2) {
+  String c1 = s1.completion.toLowerCase();
+  String c2 = s2.completion.toLowerCase();
+  return c1.compareTo(c2);
+}
+
+abstract class DartCompletionContributorTest extends AbstractContextTest {
+  Index index;
+  SearchEngineImpl searchEngine;
+  String testFile = '/completionTest.dart';
+  Source testSource;
+  int completionOffset;
+  int replacementOffset;
+  int replacementLength;
+  DartCompletionContributor contributor;
+  DartCompletionRequest request;
+  List<CompletionSuggestion> suggestions;
+
+  /**
+   * If `true` and `null` is specified as the suggestion's expected returnType
+   * then the actual suggestion is expected to have a `dynamic` returnType.
+   * Newer tests return `false` so that they can distinguish between
+   * `dynamic` and `null`.
+   * Eventually all tests should be converted and this getter removed.
+   */
+  bool get isNullExpectedReturnTypeConsideredDynamic => true;
+
+  void addTestSource(String content) {
+    expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once');
+    completionOffset = content.indexOf('^');
+    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
+    int nextOffset = content.indexOf('^', completionOffset + 1);
+    expect(nextOffset, equals(-1), reason: 'too many ^');
+    content = content.substring(0, completionOffset) +
+        content.substring(completionOffset + 1);
+    testSource = addSource(testFile, content);
+  }
+
+  void assertHasNoParameterInfo(CompletionSuggestion suggestion) {
+    expect(suggestion.parameterNames, isNull);
+    expect(suggestion.parameterTypes, isNull);
+    expect(suggestion.requiredParameterCount, isNull);
+    expect(suggestion.hasNamedParameters, isNull);
+  }
+
+  void assertHasParameterInfo(CompletionSuggestion suggestion) {
+    expect(suggestion.parameterNames, isNotNull);
+    expect(suggestion.parameterTypes, isNotNull);
+    expect(suggestion.parameterNames.length, suggestion.parameterTypes.length);
+    expect(suggestion.requiredParameterCount,
+        lessThanOrEqualTo(suggestion.parameterNames.length));
+    expect(suggestion.hasNamedParameters, isNotNull);
+  }
+
+  void assertNoSuggestions({CompletionSuggestionKind kind: null}) {
+    if (kind == null) {
+      if (suggestions.length > 0) {
+        failedCompletion('Expected no suggestions', suggestions);
+      }
+      return;
+    }
+    CompletionSuggestion suggestion = suggestions.firstWhere(
+        (CompletionSuggestion cs) => cs.kind == kind,
+        orElse: () => null);
+    if (suggestion != null) {
+      failedCompletion('did not expect completion: $completion\n  $suggestion');
+    }
+  }
+
+  void assertNotSuggested(String completion) {
+    CompletionSuggestion suggestion = suggestions.firstWhere(
+        (CompletionSuggestion cs) => cs.completion == completion,
+        orElse: () => null);
+    if (suggestion != null) {
+      failedCompletion('did not expect completion: $completion\n  $suggestion');
+    }
+  }
+
+  CompletionSuggestion assertSuggest(String completion,
+      {CompletionSuggestionKind csKind: CompletionSuggestionKind.INVOCATION,
+      int relevance: DART_RELEVANCE_DEFAULT,
+      String importUri,
+      protocol.ElementKind elemKind: null,
+      bool isDeprecated: false,
+      bool isPotential: false,
+      String elemFile,
+      int elemOffset}) {
+    CompletionSuggestion cs =
+        getSuggest(completion: completion, csKind: csKind, elemKind: elemKind);
+    if (cs == null) {
+      failedCompletion('expected $completion $csKind $elemKind', suggestions);
+    }
+    expect(cs.kind, equals(csKind));
+    if (isDeprecated) {
+      expect(cs.relevance, equals(DART_RELEVANCE_LOW));
+    } else {
+      expect(cs.relevance, equals(relevance), reason: completion);
+    }
+    expect(cs.importUri, importUri);
+    expect(cs.selectionOffset, equals(completion.length));
+    expect(cs.selectionLength, equals(0));
+    expect(cs.isDeprecated, equals(isDeprecated));
+    expect(cs.isPotential, equals(isPotential));
+    if (cs.element != null) {
+      expect(cs.element.location, isNotNull);
+      expect(cs.element.location.file, isNotNull);
+      expect(cs.element.location.offset, isNotNull);
+      expect(cs.element.location.length, isNotNull);
+      expect(cs.element.location.startColumn, isNotNull);
+      expect(cs.element.location.startLine, isNotNull);
+    }
+    if (elemFile != null) {
+      expect(cs.element.location.file, elemFile);
+    }
+    if (elemOffset != null) {
+      expect(cs.element.location.offset, elemOffset);
+    }
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestClass(String name,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      String importUri,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+      bool isDeprecated: false,
+      String elemFile,
+      String elemName,
+      int elemOffset}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: kind,
+        relevance: relevance,
+        importUri: importUri,
+        isDeprecated: isDeprecated,
+        elemFile: elemFile,
+        elemOffset: elemOffset);
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.CLASS));
+    expect(element.name, equals(elemName ?? name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, isNull);
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestClassTypeAlias(String name,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) {
+    CompletionSuggestion cs =
+        assertSuggest(name, csKind: kind, relevance: relevance);
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.CLASS_TYPE_ALIAS));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, isNull);
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestConstructor(String name,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      String importUri,
+      int elemOffset}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        relevance: relevance, importUri: importUri, elemOffset: elemOffset);
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.CONSTRUCTOR));
+    int index = name.indexOf('.');
+    expect(element.name, index >= 0 ? name.substring(index + 1) : '');
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestEnum(String completion,
+      {bool isDeprecated: false}) {
+    CompletionSuggestion suggestion =
+        assertSuggest(completion, isDeprecated: isDeprecated);
+    expect(suggestion.isDeprecated, isDeprecated);
+    expect(suggestion.element.kind, protocol.ElementKind.ENUM);
+    return suggestion;
+  }
+
+  CompletionSuggestion assertSuggestEnumConst(String completion,
+      {bool isDeprecated: false}) {
+    CompletionSuggestion suggestion =
+        assertSuggest(completion, isDeprecated: isDeprecated);
+    expect(suggestion.isDeprecated, isDeprecated);
+    expect(suggestion.element.kind, protocol.ElementKind.ENUM_CONSTANT);
+    return suggestion;
+  }
+
+  CompletionSuggestion assertSuggestField(String name, String type,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      String importUri,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+      bool isDeprecated: false}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: kind,
+        relevance: relevance,
+        importUri: importUri,
+        elemKind: protocol.ElementKind.FIELD,
+        isDeprecated: isDeprecated);
+    // The returnType represents the type of a field
+    expect(cs.returnType, type != null ? type : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.FIELD));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    // The returnType represents the type of a field
+    expect(element.returnType, type != null ? type : 'dynamic');
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestFunction(String name, String returnType,
+      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+      bool isDeprecated: false,
+      int relevance: DART_RELEVANCE_DEFAULT,
+      String importUri}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: kind,
+        relevance: relevance,
+        importUri: importUri,
+        isDeprecated: isDeprecated);
+    if (returnType != null) {
+      expect(cs.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(cs.returnType, 'dynamic');
+    } else {
+      expect(cs.returnType, isNull);
+    }
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.FUNCTION));
+    expect(element.name, equals(name));
+    expect(element.isDeprecated, equals(isDeprecated));
+    String param = element.parameters;
+    expect(param, isNotNull);
+    expect(param[0], equals('('));
+    expect(param[param.length - 1], equals(')'));
+    if (returnType != null) {
+      expect(element.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(element.returnType, 'dynamic');
+    } else {
+      expect(element.returnType, isNull);
+    }
+    assertHasParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestFunctionTypeAlias(
+      String name, String returnType,
+      {bool isDeprecated: false,
+      int relevance: DART_RELEVANCE_DEFAULT,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+      String importUri}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: kind,
+        relevance: relevance,
+        importUri: importUri,
+        isDeprecated: isDeprecated);
+    if (returnType != null) {
+      expect(cs.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(cs.returnType, 'dynamic');
+    } else {
+      expect(cs.returnType, isNull);
+    }
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.FUNCTION_TYPE_ALIAS));
+    expect(element.name, equals(name));
+    expect(element.isDeprecated, equals(isDeprecated));
+    // TODO (danrubel) Determine why params are null
+    //    String param = element.parameters;
+    //    expect(param, isNotNull);
+    //    expect(param[0], equals('('));
+    //    expect(param[param.length - 1], equals(')'));
+    expect(element.returnType,
+        equals(returnType != null ? returnType : 'dynamic'));
+    // TODO (danrubel) Determine why param info is missing
+    //    assertHasParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestGetter(String name, String returnType,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      String importUri,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+      bool isDeprecated: false}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: kind,
+        relevance: relevance,
+        importUri: importUri,
+        elemKind: protocol.ElementKind.GETTER,
+        isDeprecated: isDeprecated);
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.GETTER));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType,
+        equals(returnType != null ? returnType : 'dynamic'));
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestMethod(
+      String name, String declaringType, String returnType,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      String importUri,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+      bool isDeprecated: false}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: kind,
+        relevance: relevance,
+        importUri: importUri,
+        isDeprecated: isDeprecated);
+    expect(cs.declaringType, equals(declaringType));
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.METHOD));
+    expect(element.name, equals(name));
+    String param = element.parameters;
+    expect(param, isNotNull);
+    expect(param[0], equals('('));
+    expect(param[param.length - 1], equals(')'));
+    expect(element.returnType, returnType != null ? returnType : 'dynamic');
+    assertHasParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestSetter(String name,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      String importUri,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: kind,
+        relevance: relevance,
+        importUri: importUri,
+        elemKind: protocol.ElementKind.SETTER);
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.SETTER));
+    expect(element.name, equals(name));
+    // TODO (danrubel) assert setter param
+    //expect(element.parameters, isNull);
+    // TODO (danrubel) it would be better if this was always null
+    if (element.returnType != null) {
+      expect(element.returnType, 'dynamic');
+    }
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestTopLevelVar(String name, String returnType,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+      String importUri}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: kind, relevance: relevance, importUri: importUri);
+    if (returnType != null) {
+      expect(cs.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(cs.returnType, 'dynamic');
+    } else {
+      expect(cs.returnType, isNull);
+    }
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.TOP_LEVEL_VARIABLE));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    if (returnType != null) {
+      expect(element.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(element.returnType, 'dynamic');
+    } else {
+      expect(element.returnType, isNull);
+    }
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  /**
+   * Return a [Future] that completes with the containing library information
+   * after it is accessible via [context.getLibrariesContaining].
+   */
+  Future computeLibrariesContaining([int times = 200]) {
+    List<Source> libraries = context.getLibrariesContaining(testSource);
+    if (libraries.isNotEmpty) {
+      return new Future.value(libraries);
+    }
+    if (times == 0) {
+      fail('failed to determine libraries containing $testSource');
+    }
+    context.performAnalysisTask();
+    // We use a delayed future to allow microtask events to finish. The
+    // Future.value or Future() constructors use scheduleMicrotask themselves and
+    // would therefore not wait for microtask callbacks that are scheduled after
+    // invoking this method.
+    return new Future.delayed(
+        Duration.ZERO, () => computeLibrariesContaining(times - 1));
+  }
+
+  Future computeSuggestions([int times = 200]) async {
+    CompletionRequestImpl baseRequest = new CompletionRequestImpl(
+        context,
+        provider,
+        searchEngine,
+        testSource,
+        completionOffset,
+        new CompletionPerformance());
+
+    // Build the request
+    Completer<DartCompletionRequest> requestCompleter =
+        new Completer<DartCompletionRequest>();
+    DartCompletionRequestImpl
+        .from(baseRequest)
+        .then((DartCompletionRequest request) {
+      requestCompleter.complete(request);
+    });
+    request = await performAnalysis(times, requestCompleter);
+
+    var range = new ReplacementRange.compute(request.offset, request.target);
+    replacementOffset = range.offset;
+    replacementLength = range.length;
+    Completer<List<CompletionSuggestion>> suggestionCompleter =
+        new Completer<List<CompletionSuggestion>>();
+
+    // Request completions
+    contributor
+        .computeSuggestions(request)
+        .then((List<CompletionSuggestion> computedSuggestions) {
+      suggestionCompleter.complete(computedSuggestions);
+    });
+
+    // Perform analysis until the suggestions have been computed
+    // or the max analysis cycles ([times]) has been reached
+    suggestions = await performAnalysis(times, suggestionCompleter);
+    expect(suggestions, isNotNull, reason: 'expected suggestions');
+  }
+
+  DartCompletionContributor createContributor();
+
+  void failedCompletion(String message,
+      [Iterable<CompletionSuggestion> completions]) {
+    StringBuffer sb = new StringBuffer(message);
+    if (completions != null) {
+      sb.write('\n  found');
+      completions.toList()
+        ..sort(suggestionComparator)
+        ..forEach((CompletionSuggestion suggestion) {
+          sb.write('\n    ${suggestion.completion} -> $suggestion');
+        });
+    }
+    fail(sb.toString());
+  }
+
+  CompletionSuggestion getSuggest(
+      {String completion: null,
+      CompletionSuggestionKind csKind: null,
+      protocol.ElementKind elemKind: null}) {
+    CompletionSuggestion cs;
+    if (suggestions != null) {
+      suggestions.forEach((CompletionSuggestion s) {
+        if (completion != null && completion != s.completion) {
+          return;
+        }
+        if (csKind != null && csKind != s.kind) {
+          return;
+        }
+        if (elemKind != null) {
+          protocol.Element element = s.element;
+          if (element == null || elemKind != element.kind) {
+            return;
+          }
+        }
+        if (cs == null) {
+          cs = s;
+        } else {
+          failedCompletion('expected exactly one $cs',
+              suggestions.where((s) => s.completion == completion));
+        }
+      });
+    }
+    return cs;
+  }
+
+  Future performAnalysis(int times, Completer completer) {
+    if (completer.isCompleted) return completer.future;
+    if (times == 0 || context == null) return new Future.value();
+    context.performAnalysisTask();
+    // We use a delayed future to allow microtask events to finish. The
+    // Future.value or Future() constructors use scheduleMicrotask themselves and
+    // would therefore not wait for microtask callbacks that are scheduled after
+    // invoking this method.
+    return new Future.delayed(
+        Duration.ZERO, () => performAnalysis(times - 1, completer));
+  }
+
+  void resolveSource(String path, String content) {
+    Source libSource = addSource(path, content);
+    var target = new LibrarySpecificUnit(libSource, libSource);
+    context.computeResult(target, RESOLVED_UNIT);
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    index = createLocalMemoryIndex();
+    searchEngine = new SearchEngineImpl(index);
+    contributor = createContributor();
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
new file mode 100644
index 0000000..2f39159
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
@@ -0,0 +1,167 @@
+// 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 test.services.completion.field_formal;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(FieldFormalContributorTest);
+}
+
+@reflectiveTest
+class FieldFormalContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new FieldFormalContributor();
+  }
+
+  test_ThisExpression_constructor_param() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^) {}
+          A.z() {}
+          var b; X _c; static sb;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertNotSuggested('sb');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param2() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param3() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^b) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param4() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b, this.^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
new file mode 100644
index 0000000..00d80df
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -0,0 +1,4375 @@
+// 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 test.services.completion.contributor.dart.imported_ref;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../abstract_context.dart';
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(ImportedReferenceContributorTest);
+}
+
+@reflectiveTest
+class ImportedReferenceContributorTest extends DartCompletionContributorTest {
+  @override
+  bool get isNullExpectedReturnTypeConsideredDynamic => false;
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new ImportedReferenceContributor();
+  }
+
+  fail_enum_deprecated() async {
+    addSource('/libA.dart', 'library A; @deprecated enum E { one, two }');
+    addTestSource('import "/libA.dart"; main() {^}');
+    await computeSuggestions();
+    // TODO(danrube) investigate why suggestion/element is not deprecated
+    // when AST node has correct @deprecated annotation
+    assertSuggestEnum('E', isDeprecated: true);
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_doc_class() async {
+    addSource(
+        '/libA.dart',
+        r'''
+library A;
+/// My class.
+/// Short description.
+///
+/// Longer description.
+class A {}
+''');
+    addTestSource('import "/libA.dart"; main() {^}');
+
+    await computeSuggestions();
+
+    CompletionSuggestion suggestion = assertSuggestClass('A');
+    expect(suggestion.docSummary, 'My class.\nShort description.');
+    expect(suggestion.docComplete,
+        'My class.\nShort description.\n\nLonger description.');
+  }
+
+  test_doc_function() async {
+    resolveSource(
+        '/libA.dart',
+        r'''
+library A;
+/// My function.
+/// Short description.
+///
+/// Longer description.
+int myFunc() {}
+''');
+    addTestSource('import "/libA.dart"; main() {^}');
+
+    await computeSuggestions();
+
+    CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int');
+    expect(suggestion.docSummary, 'My function.\nShort description.');
+    expect(suggestion.docComplete,
+        'My function.\nShort description.\n\nLonger description.');
+  }
+
+  test_doc_function_c_style() async {
+    resolveSource(
+        '/libA.dart',
+        r'''
+library A;
+/**
+ * My function.
+ * Short description.
+ *
+ * Longer description.
+ */
+int myFunc() {}
+''');
+    addTestSource('import "/libA.dart"; main() {^}');
+
+    await computeSuggestions();
+
+    CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int');
+    expect(suggestion.docSummary, 'My function.\nShort description.');
+    expect(suggestion.docComplete,
+        'My function.\nShort description.\n\nLonger description.');
+  }
+  
+  test_enum() async {
+    addSource('/libA.dart', 'library A; enum E { one, two }');
+    addTestSource('import "/libA.dart"; main() {^}');
+    await computeSuggestions();
+    assertSuggestEnum('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_function_parameters_mixed_required_and_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+int m(x, {int y}) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'int');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_function_parameters_mixed_required_and_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, [int y]) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m({x, int y}) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_function_parameters_none() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m() {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m([x, int y]) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_required() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, int y) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_InstanceCreationExpression() async {
+    resolveSource(
+        '/testA.dart',
+        '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+    addTestSource('''
+import "/testA.dart";
+import "dart:math" as math;
+main() {new ^ String x = "hello";}''');
+
+    await computeSuggestions();
+    CompletionSuggestion suggestion;
+
+    suggestion = assertSuggestConstructor('Object');
+    expect(suggestion.element.parameters, '()');
+    expect(suggestion.parameterNames, hasLength(0));
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('A');
+    expect(suggestion.element.parameters, '()');
+    expect(suggestion.parameterNames, hasLength(0));
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('B');
+    expect(suggestion.element.parameters, '(int x, [String boo])');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'int');
+    expect(suggestion.parameterNames[1], 'boo');
+    expect(suggestion.parameterTypes[1], 'String');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('C.bar');
+    expect(suggestion.element.parameters, "({dynamic boo: 'hoo', int z: 0})");
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'boo');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'z');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('math');
+  }
+
+  test_internal_sdk_libs() async {
+    addTestSource('main() {p^}');
+
+    await computeSuggestions();
+    assertSuggest('print');
+    // Not imported, so not suggested
+    assertNotSuggested('pow');
+    // Do not suggest completions from internal SDK library
+    assertNotSuggested('printToConsole');
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, {int y}) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, [int y]) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m({x, int y}) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_none() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m() {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m([x, int y]) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_required() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, int y) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_mixin_ordering() async {
+    addSource(
+        '/libA.dart',
+        '''
+class B {}
+class M1 {
+  void m() {}
+}
+class M2 {
+  void m() {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class C extends B with M1, M2 {
+  void f() {
+    ^
+  }
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  /**
+   * Ensure that completions in one context don't appear in another
+   */
+  test_multiple_contexts() async {
+    // Create a 2nd context with source
+    var context2 = AnalysisEngine.instance.createAnalysisContext();
+    context2.sourceFactory =
+        new SourceFactory([AbstractContextTest.SDK_RESOLVER, resourceResolver]);
+    String content2 = 'class ClassFromAnotherContext { }';
+    Source source2 =
+        provider.newFile('/context2/foo.dart', content2).createSource();
+    ChangeSet changeSet = new ChangeSet();
+    changeSet.addedSource(source2);
+    context2.applyChanges(changeSet);
+    context2.setContents(source2, content2);
+
+    // Resolve the source in the 2nd context and update the index
+    var result = context2.performAnalysisTask();
+    while (result.hasMoreWork) {
+      result.changeNotices.forEach((ChangeNotice notice) {
+        CompilationUnit unit = notice.resolvedDartUnit;
+        if (unit != null) {
+          index.index(context2, unit);
+        }
+      });
+      result = context2.performAnalysisTask();
+    }
+
+    // Check that source in 2nd context does not appear in completion in 1st
+    addSource(
+        '/context1/libA.dart',
+        '''
+      library libA;
+      class ClassInLocalContext {int x;}''');
+    testFile = '/context1/completionTest.dart';
+    addTestSource('''
+      import "/context1/libA.dart";
+      import "/foo.dart";
+      main() {C^}
+      ''');
+
+    await computeSuggestions();
+    assertSuggestClass('ClassInLocalContext');
+    // Assert contributor does not include results from 2nd context.
+    assertNotSuggested('ClassFromAnotherContext');
+  }
+
+  test_no_parameters_field() async {
+    addSource(
+        '/libA.dart',
+        '''
+int x;
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestTopLevelVar('x', null);
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_getter() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+int get x => null;
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_setter() async {
+    addSource(
+        '/libA.dart',
+        '''
+set x(int value) {};
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestSetter('x');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_ArgumentList() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    resolveSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('B');
+    assertSuggestClass('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_imported_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    resolveSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        expect(arg) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('B');
+    assertSuggestClass('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {new A(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('identical', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('B');
+    assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        typedef Funct();
+        class A { A(Funct f) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {new A(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('identical', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('B');
+    assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    resolveSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        expect(arg) { }
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('B');
+    assertSuggestClass('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_method() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    resolveSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        class B {
+          expect(arg) { }
+          void foo() {expect(^)}}
+        String bar() => true;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('B');
+    assertSuggestClass('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_functionalArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar(f()) => true;
+        void main() {bar(^);}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('identical', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('B');
+    assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_methodArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { String bar(f()) => true; }
+        void main() {new B().bar(^);}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('hasLength', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('identical', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('B');
+    assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_namedParam() async {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }''');
+    addTestSource('''
+        import '/libA.dart'
+        String bar() => true;
+        void main() {expect(foo: ^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('bar');
+    // An unresolved imported library will produce suggestions
+    // with a null returnType
+    assertSuggestFunction('hasLength', null);
+    assertNotSuggested('main');
+  }
+
+  test_AsExpression() async {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('''
+        class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertSuggestClass('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_AssignmentExpression_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_AssignmentExpression_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_AssignmentExpression_type() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          ^ b = 1;}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertSuggestClass('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          ^
+          b = 1;}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertSuggestClass('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestFunction('identical', 'bool');
+  }
+
+  test_AssignmentExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          int^ b = 1;}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('A');
+    assertSuggestClass('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          i^
+          b = 1;}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertSuggestClass('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestFunction('identical', 'bool');
+  }
+
+  test_AwaitExpression() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main() async {A a; await ^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_AwaitExpression_function() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+Future y() async {return 0;}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  int x;
+  foo() async {await ^}
+}
+''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestFunction('y', 'dynamic');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_AwaitExpression_inherited() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A {
+  Future y() async { return 0; }
+}''');
+    addTestSource('''
+import "/testB.dart";
+class B extends A {
+  foo() async {await ^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestClass('A');
+    assertSuggestClass('Object');
+    assertNotSuggested('y');
+  }
+
+  test_BinaryExpression_LHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertNotSuggested('b');
+  }
+
+  test_BinaryExpression_RHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('==');
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            ^ var r;
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertSuggestClass('A', elemFile: '/testAB.dart');
+    assertNotSuggested('_B');
+    assertSuggestClass('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestFunction(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertSuggestClass('EE');
+    // hidden element suggested as low relevance
+    //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW);
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertSuggestClass('g.G', elemName: 'G');
+    assertNotSuggested('G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    assertSuggestClass('Object');
+    assertSuggestFunction('min', 'num');
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertSuggestClass('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            final ^
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertSuggestClass('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestFunction(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertSuggestClass('EE');
+    // hidden element suggested as low relevance
+    //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW);
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertSuggestClass('g.G', elemName: 'G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    assertSuggestClass('Object');
+    assertNotSuggested('min');
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertSuggestClass('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final2() async {
+    addTestSource('main() {final S^ v;}');
+
+    await computeSuggestions();
+    assertSuggestClass('String');
+  }
+
+  test_Block_final3() async {
+    addTestSource('main() {final ^ v;}');
+
+    await computeSuggestions();
+    assertSuggestClass('String');
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g hide G;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            final ^
+            final var f;
+            localF(int arg1) { }
+            {var x;}
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertSuggestClass('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestFunction(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertSuggestClass('EE');
+    // hidden element suggested as low relevance
+    //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW);
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    // Hidden elements not suggested
+    assertNotSuggested('g.G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    assertSuggestClass('Object');
+    assertNotSuggested('min');
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertSuggestClass('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            final ^
+            var f;
+            localF(int arg1) { }
+            {var x;}
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertSuggestClass('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestFunction(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertSuggestClass('EE');
+    // hidden element suggested as low relevance
+    //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW);
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertSuggestClass('g.G', elemName: 'G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    assertSuggestClass('Object');
+    assertNotSuggested('min');
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertSuggestClass('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_identifier_partial() async {
+    resolveSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class DF { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        class D3 { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        Z D2() {int x;}
+        class X {a() {var f; {var x;} D^ var r;} void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+
+    // imported elements are portially filtered
+    //assertSuggestClass('A');
+    assertNotSuggested('_B');
+    // hidden element not suggested
+    assertNotSuggested('D');
+    assertSuggestFunction('D1', 'dynamic',
+        isDeprecated: true, relevance: DART_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    // Not imported, so not suggested
+    assertNotSuggested('D3');
+    //assertSuggestClass('EE');
+    // hidden element not suggested
+    assertNotSuggested('DF');
+    //assertSuggestLibraryPrefix('g');
+    assertSuggestClass('g.G', elemName: 'G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestClass('Object');
+    //assertSuggestFunction('min', 'num', false);
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    //assertSuggestTopLevelVarGetterSetter('T1', 'String');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    //assertNotSuggested('T5');
+    //assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+        class E extends F { var e1; e2() { } }
+        class I { int i1; i2() { } }
+        class M { var m1; int m2() { } }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends E implements I with M {a() {^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // TODO (danrubel) prefer fields over getters
+    // If add `get e1;` to interface I
+    // then suggestions include getter e1 rather than field e1
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    //assertNotSuggested('m2', null, null);
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+        class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+        class E extends F { var e1; e2() { } }
+        class I { int i1; i2() { } }
+        class M { var m1; int m2() { } }
+        class A extends E implements I with M {a() {^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    assertNotSuggested('m2');
+  }
+
+  test_Block_local_function() async {
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            p^ var r;
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('partT8');
+    assertNotSuggested('partBoo');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_partial_results() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        Z D2() {int x;}
+        class X {a() {var f; {var x;} ^ var r;} void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+    assertSuggestClass('C');
+    assertNotSuggested('H');
+  }
+
+  test_Block_unimported() async {
+    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+    addSource(
+        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
+    testFile = '/proj/completionTest.dart';
+    addTestSource('class C {foo(){F^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Not imported, so not suggested
+    assertNotSuggested('Foo');
+    assertNotSuggested('Foo2');
+    assertNotSuggested('Future');
+  }
+
+  test_CascadeExpression_selector1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        // looks like a cascade to the parser
+        // but the user is trying to get completions for a non-cascade
+        main() {A a; a.^.z}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a..^z}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a..^ return}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_target() async {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('''
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a^..b}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    // top level results are partially filtered
+    //assertSuggestClass('Object');
+    assertNotSuggested('==');
+  }
+
+  test_CatchClause_onType() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_onType_noBrackets() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_typed() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_untyped() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('s');
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        @deprecated class A {^}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    CompletionSuggestion suggestionO = assertSuggestClass('Object');
+    if (suggestionO != null) {
+      expect(suggestionO.element.isDeprecated, isFalse);
+      expect(suggestionO.element.isPrivate, isFalse);
+    }
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ A(){}}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('String');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as Soo;
+        class A {final S^ A();}
+        class _B {}
+        A Sew;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('String');
+    assertNotSuggested('Sew');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('Soo');
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ final foo;}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ var foo;}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_Combinator_hide() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+        library libAB;
+        part '/partAB.dart';
+        class A { }
+        class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+        part of libAB;
+        var T1;
+        PB F1() => new PB();
+        class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        class C { }
+        class D { }''');
+    addTestSource('''
+        import "/testAB.dart" hide ^;
+        import "/testCD.dart";
+        class X {}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_Combinator_show() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+        library libAB;
+        part '/partAB.dart';
+        class A { }
+        class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+        part of libAB;
+        var T1;
+        PB F1() => new PB();
+        typedef PB2 F2(int blat);
+        class Clz = Object with Object;
+        class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        class C { }
+        class D { }''');
+    addTestSource('''
+        import "/testAB.dart" show ^;
+        import "/testCD.dart";
+        class X {}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ConditionalExpression_elseExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
+
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_elseExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
+
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertSuggestClass('A');
+    assertSuggestFunction('F1', 'dynamic');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_partial_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T^}}''');
+
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_partial_thenExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? ^}}''');
+
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertSuggestClass('A');
+    assertSuggestFunction('F1', 'dynamic');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T^ : c}}''');
+
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('fromCharCodes');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}
+        main() {new X.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}
+        main() {new X.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_DefaultFormalParameter_named_expression() async {
+    // DefaultFormalParameter FormalParameterList MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {a(blat: ^) { }}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertSuggestClass('String');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('bar');
+  }
+
+  test_ExpressionStatement_identifier() async {
+    // SimpleIdentifier  ExpressionStatement  Block
+    resolveSource(
+        '/testA.dart',
+        '''
+        _B F1() { }
+        class A {int x;}
+        class _B { }''');
+    addTestSource('''
+        import "/testA.dart";
+        typedef int F2(int blat);
+        class Clz = Object with Object;
+        class C {foo(){^} void bar() {}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestFunction('F1', '_B');
+    assertNotSuggested('C');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('F2');
+    assertNotSuggested('Clz');
+    assertNotSuggested('C');
+    assertNotSuggested('x');
+    assertNotSuggested('_B');
+  }
+
+  test_ExpressionStatement_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        B T1;
+        class B{}''');
+    addTestSource('''
+        import "/testA.dart";
+        class C {a() {C ^}}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_typed() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {A ^}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_var() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {var ^}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldFormalParameter_in_non_constructor() async {
+    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
+    addTestSource('class A {B(this.^foo) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 3);
+    assertNoSuggestions();
+  }
+
+  test_ForEachStatement_body_typed() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertSuggestClass('Object');
+  }
+
+  test_ForEachStatement_body_untyped() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertSuggestClass('Object');
+  }
+
+  test_ForEachStatement_iterable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (int foo in ^) {}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertSuggestClass('Object');
+  }
+
+  test_ForEachStatement_loopVariable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertSuggestClass('String');
+  }
+
+  test_ForEachStatement_loopVariable_type() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertSuggestClass('String');
+  }
+
+  test_ForEachStatement_loopVariable_type2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertSuggestClass('String');
+  }
+
+  test_FormalParameterList() async {
+    // FormalParameterList MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {a(^) { }}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertSuggestClass('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ForStatement_body() async {
+    // Block  ForStatement
+    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('i');
+    assertSuggestClass('Object');
+  }
+
+  test_ForStatement_condition() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_initializer() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertSuggestClass('int');
+  }
+
+  test_ForStatement_updaters() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_updaters_prefix_expression() async {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('''
+        void bar() { }
+        main() {for (int index = 0; index < 10; ++i^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+    assertNotSuggested('main');
+    assertNotSuggested('bar');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        /* */ ^ zoo(z) { } String name;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment2() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        /** */ ^ zoo(z) { } String name;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment3() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        /// some dartdoc
+        class C2 { }
+        ^ zoo(z) { } String name;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionExpression_body_function() async {
+    // Block  BlockFunctionBody  FunctionExpression
+    addTestSource('''
+        void bar() { }
+        String foo(List args) {x.then((R b) {^});}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('args');
+    assertNotSuggested('b');
+    assertSuggestClass('Object');
+  }
+
+  test_IfStatement() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (true) ^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertSuggestClass('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_condition() async {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_IfStatement_empty() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (^) something}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertSuggestClass('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_invocation() async {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+        main() {var a; if (a.^) something}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('toString');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_ImportDirective_dart() async {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+        import "dart^";
+        main() {}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_IndexExpression() async {
+    // ExpressionStatement  Block
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} f[^]}}''');
+
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertSuggestClass('A');
+    assertSuggestFunction('F1', 'dynamic');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_IndexExpression2() async {
+    // SimpleIdentifier IndexExpression ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} f[T^]}}''');
+
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_InstanceCreationExpression_imported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {A(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        import "dart:async";
+        int T2;
+        F2() { }
+        class B {B(this.x, [String boo]) { } int x;}
+        class C {foo(){var f; {var x;} new ^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('Object');
+    assertSuggestConstructor('Future');
+    assertSuggestConstructor('A');
+    // Suggested by ConstructorContributor
+    assertNotSuggested('B');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('foo');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T2');
+  }
+
+  test_InstanceCreationExpression_unimported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){new F^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Not imported, so not suggested
+    assertNotSuggested('Future');
+    assertNotSuggested('Foo');
+  }
+
+  test_InterpolationExpression() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        main() {String name; print("hello \$^");}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertSuggestTopLevelVar('T1', null);
+    assertSuggestFunction('F1', null);
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        main() {String name; print("hello \${^}");}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    // Simulate unresolved imported library
+    // in which case suggestions will have null (unresolved) returnType
+    assertSuggestTopLevelVar('T1', null);
+    assertSuggestFunction('F1', null);
+    assertSuggestFunctionTypeAlias('D1', 'null');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block2() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+
+    await computeSuggestions();
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertSuggestClass('Object');
+  }
+
+  test_InterpolationExpression_prefix_selector() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('length');
+    assertNotSuggested('name');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_InterpolationExpression_prefix_selector2() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \$name.^");}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_InterpolationExpression_prefix_target() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+
+    await computeSuggestions();
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertSuggestClass('Object');
+    assertNotSuggested('length');
+  }
+
+  test_IsExpression() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        main() {var x; if (x is ^) { }}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('x');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+  }
+
+  test_IsExpression_target() async {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {int x; int y() => 0;}
+        main(){var a; if (^ is A)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_IsExpression_type() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (a is ^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_IsExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (a is Obj^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_keyword() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int newT1;
+        int T1;
+        nowIsIt() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        String newer() {}
+        var m;
+        main() {new^ X.c();}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    // Imported suggestion are filtered by 1st character
+    assertSuggestFunction('nowIsIt', 'dynamic');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertSuggestTopLevelVar('newT1', 'int');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+    assertNotSuggested('newer');
+  }
+
+  test_Literal_list() async {
+    // ']'  ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([^]);}');
+
+    await computeSuggestions();
+    assertNotSuggested('Some');
+    assertSuggestClass('String');
+  }
+
+  test_Literal_list2() async {
+    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([S^]);}');
+
+    await computeSuggestions();
+    assertNotSuggested('Some');
+    assertSuggestClass('String');
+  }
+
+  test_Literal_string() async {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_localVariableDeclarationName() async {
+    addTestSource('main() {String m^}');
+    await computeSuggestions();
+    assertNotSuggested('main');
+    assertNotSuggested('min');
+  }
+
+  test_MapLiteralEntry() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {^''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', null);
+    assertSuggestFunction('F1', null);
+    assertSuggestFunctionTypeAlias('D1', 'null');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+  }
+
+  test_MapLiteralEntry1() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {T^''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Simulate unresolved imported library,
+    // in which case suggestions will have null return types (unresolved)
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T2');
+  }
+
+  test_MapLiteralEntry2() async {
+    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {7:T^};''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T2');
+  }
+
+  test_MethodDeclaration_body_getters() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+  }
+
+  test_MethodDeclaration_body_static() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testC.dart',
+        '''
+        class C {
+          c1() {}
+          var c2;
+          static c3() {}
+          static var c4;}''');
+    addTestSource('''
+        import "/testC.dart";
+        class B extends C {
+          b1() {}
+          var b2;
+          static b3() {}
+          static var b4;}
+        class A extends B {
+          a1() {}
+          var a2;
+          static a3() {}
+          static var a4;
+          static a() {^}}''');
+
+    await computeSuggestions();
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    assertNotSuggested('a3');
+    assertNotSuggested('a4');
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    assertNotSuggested('b3');
+    assertNotSuggested('b4');
+    assertNotSuggested('c1');
+    assertNotSuggested('c2');
+    assertNotSuggested('c3');
+    assertNotSuggested('c4');
+  }
+
+  test_MethodDeclaration_members() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('_a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertSuggestClass('bool');
+  }
+
+  test_MethodDeclaration_parameters_named() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('b');
+    assertSuggestClass('int');
+    assertNotSuggested('_');
+  }
+
+  test_MethodDeclaration_parameters_positional() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {Z a(X x, [int y=1]) {^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertSuggestClass('String');
+  }
+
+  test_MethodDeclaration_returnType() async {
+    // ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {^ zoo(z) { } String name; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {/* */ ^ zoo(z) { } String name; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {/** */ ^ zoo(z) { } String name; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment3() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {
+          /// some dartdoc
+          ^ zoo(z) { } String name; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodInvocation_no_semicolon() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {x.^ m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_new_instance() async {
+    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
+
+    await computeSuggestions();
+    assertNotSuggested('nextBool');
+    assertNotSuggested('nextDouble');
+    assertNotSuggested('nextInt');
+    assertNotSuggested('Random');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+  }
+
+  test_parameterName_excludeTypes() async {
+    addTestSource('m(int ^) {}');
+    await computeSuggestions();
+    assertNotSuggested('int');
+    assertNotSuggested('bool');
+  }
+
+  test_partFile_TypeName() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        library libA;
+        import "/testB.dart";
+        part "$testFile";
+        class A { }
+        var m;''');
+    addTestSource('''
+        part of libA;
+        class B { factory B.bar(int x) => null; }
+        main() {new ^}''');
+
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by ConstructorContributor
+    assertNotSuggested('B.bar');
+    assertSuggestConstructor('Object');
+    assertSuggestConstructor('X.c');
+    assertNotSuggested('X._d');
+    // Suggested by LocalLibraryContributor
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib libB;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        part of libA;
+        class B { }''');
+    addTestSource('''
+        library libA;
+        import "/testB.dart";
+        part "/testA.dart";
+        class A { A({String boo: 'hoo'}) { } }
+        main() {new ^}
+        var m;''');
+
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by ConstructorContributor
+    assertNotSuggested('A');
+    assertSuggestConstructor('Object');
+    assertSuggestConstructor('X.c');
+    assertNotSuggested('X._d');
+    // Suggested by LocalLibraryContributor
+    assertNotSuggested('B');
+    assertNotSuggested('F1');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {
+          static const scI = 'boo';
+          X get f => new A();
+          get _g => new A();}
+        class B implements I {
+          static const int scB = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends B {
+          static const String scA = 'foo';
+          w() { }}
+        main() {A.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('scA');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_imported() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          static const int sc = 12;
+          @deprecated var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        main() {A a; a.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_local() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+        main() {A a; a.^}
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          static const int sc = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        main() {b.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^ f) {}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^) {}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class _W {M y; var _z;}
+        class X extends _W {}
+        class M{}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo(X x) {x.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('y');
+    assertNotSuggested('_z');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+        class A {static int bar = 10;}
+        _B() {}''');
+    addTestSource('''
+        import "/testA.dart";
+        class X {foo(){A^.bar}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestClass('A');
+    assertNotSuggested('X');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('_B');
+  }
+
+  test_PrefixedIdentifier_propertyAccess() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_propertyAccess_newStmt() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_const() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_field() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_function() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_typed() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {String g; g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_method() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f(String g) {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g; f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PropertyAccess_expression() async {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 8);
+    assertNotSuggested('length');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PropertyAccess_noTarget() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){.^}}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_noTarget2() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('main() {.^}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_selector() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEven');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_SwitchStatement_c() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_SwitchStatement_case() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
+
+    await computeSuggestions();
+    assertNotSuggested('A');
+    assertNotSuggested('g');
+    assertNotSuggested('t');
+    assertSuggestClass('String');
+  }
+
+  test_SwitchStatement_empty() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {^}}}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ThisExpression_block() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A() {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {this.^ m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A() {this.^}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^) {}
+          A.z() {}
+          var b; X _c; static sb;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('sb');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param2() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param3() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^b) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param4() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b, this.^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_TypeArgumentList() async {
+    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    resolveSource(
+        '/testA.dart',
+        '''
+        class C1 {int x;}
+        F1() => 0;
+        typedef String T1(int blat);''');
+    addTestSource('''
+        import "/testA.dart";'
+        class C2 {int x;}
+        F2() => 0;
+        typedef int T2(int blat);
+        class C<E> {}
+        main() { C<^> c; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestClass('C1');
+    assertSuggestFunctionTypeAlias('T1', 'String');
+    assertNotSuggested('C2');
+    assertNotSuggested('T2');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+  }
+
+  test_TypeArgumentList2() async {
+    // TypeName  TypeArgumentList  TypeName
+    addSource(
+        '/testA.dart',
+        '''
+        class C1 {int x;}
+        F1() => 0;
+        typedef String T1(int blat);''');
+    addTestSource('''
+        import "/testA.dart";'
+        class C2 {int x;}
+        F2() => 0;
+        typedef int T2(int blat);
+        class C<E> {}
+        main() { C<C^> c; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestClass('C1');
+    assertNotSuggested('C2');
+  }
+
+  test_VariableDeclaration_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        main() {var ^}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_VariableDeclarationList_final() async {
+    // VariableDeclarationList  VariableDeclarationStatement  Block
+    addTestSource('main() {final ^} class C { }');
+
+    await computeSuggestions();
+    assertSuggestClass('Object');
+    assertNotSuggested('C');
+    assertNotSuggested('==');
+  }
+
+  test_VariableDeclarationStatement_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        class C {bar(){var f; {var x;} var e = ^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    resolveSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo1() { }
+        void bar1() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo2() { }
+        void bar2() { }
+        class Y {Y.c(); Y._d(); z() {}}
+        class C {bar(){var f; {var x;} var e = ^ var g}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestFunction('foo1', 'dynamic');
+    assertNotSuggested('bar1');
+    assertNotSuggested('foo2');
+    assertNotSuggested('bar2');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
new file mode 100644
index 0000000..a864b34
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
@@ -0,0 +1,619 @@
+// 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 test.services.completion.contributor.dart.inherited_ref;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(InheritedContributorTest);
+}
+
+@reflectiveTest
+class InheritedContributorTest extends DartCompletionContributorTest {
+  @override
+  bool get isNullExpectedReturnTypeConsideredDynamic => false;
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new InheritedReferenceContributor();
+  }
+
+  test_AwaitExpression_inherited() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A {
+  Future y() async {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class B extends A {
+  Future a() async {return 0;}
+  foo() async {await ^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('foo');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertSuggestMethod('y', 'A', 'dynamic');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    resolveSource(
+        '/testB.dart',
+        '''
+      lib B;
+      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+      class E extends F { var e1; e2() { } }
+      class I { int i1; i2() { } }
+      class M { var m1; int m2() { } }''');
+    addTestSource('''
+      import "/testB.dart";
+      class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
+  }
+
+  test_inherited() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+  foo() {^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('foo');
+    assertNotSuggested('A');
+    assertSuggestField('x', 'int');
+    assertSuggestMethod('y', 'A2', 'int');
+    assertSuggestField('x1', 'int');
+    assertSuggestMethod('y1', 'A1', 'int');
+    assertSuggestField('x2', 'int');
+    assertSuggestMethod('y2', 'A2', 'int');
+  }
+
+  test_method_in_class() async {
+    addTestSource('''
+class A {
+  void m(x, int y) {}
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m(x, {int y}) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_named_local() async {
+    addTestSource('''
+class A {
+  void m(x, {int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m(x, [int y]) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_mixed_required_and_positional_local() async {
+    addTestSource('''
+class A {
+  void m(x, [int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m({x, int y}) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_named_local() async {
+    addTestSource('''
+class A {
+  void m({x, int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_none() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m() {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_none_local() async {
+    addTestSource('''
+class A {
+  void m() {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m([x, int y]) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_positional_local() async {
+    addTestSource('''
+class A {
+  void m([x, int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_required() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m(x, int y) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_mixin_ordering() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class B {}
+class M1 {
+  void m() {}
+}
+class M2 {
+  void m() {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class C extends B with M1, M2 {
+  void f() {
+    ^
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('m', 'M1', 'void');
+  }
+
+  test_no_parameters_field() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  int x;
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestField('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_getter() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  int get x => null;
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_setter() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  set x(int value) {};
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestSetter('x');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_ouside_class() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+}
+foo() {^}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('foo');
+    assertNotSuggested('A');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('x1');
+    assertNotSuggested('y1');
+    assertNotSuggested('x2');
+    assertNotSuggested('y2');
+  }
+
+  test_static_field() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+  static foo = ^
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('foo');
+    assertNotSuggested('A');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('x1');
+    assertNotSuggested('y1');
+    assertNotSuggested('x2');
+    assertNotSuggested('y2');
+  }
+
+  test_static_method() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+  static foo() {^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('foo');
+    assertNotSuggested('A');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('x1');
+    assertNotSuggested('y1');
+    assertNotSuggested('x2');
+    assertNotSuggested('y2');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
new file mode 100644
index 0000000..167e3ab
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -0,0 +1,1496 @@
+// 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 test.services.completion.dart.keyword;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(KeywordContributorTest);
+}
+
+@reflectiveTest
+class KeywordContributorTest extends DartCompletionContributorTest {
+  static const List<Keyword> CLASS_BODY_KEYWORDS = const [
+    Keyword.CONST,
+    Keyword.DYNAMIC,
+    Keyword.FACTORY,
+    Keyword.FINAL,
+    Keyword.GET,
+    Keyword.OPERATOR,
+    Keyword.SET,
+    Keyword.STATIC,
+    Keyword.VAR,
+    Keyword.VOID
+  ];
+
+  static const List<Keyword> DECLARATION_KEYWORDS = const [
+    Keyword.ABSTRACT,
+    Keyword.CLASS,
+    Keyword.CONST,
+    Keyword.DYNAMIC,
+    Keyword.FINAL,
+    Keyword.TYPEDEF,
+    Keyword.VAR,
+    Keyword.VOID
+  ];
+
+  static const List<Keyword> DIRECTIVE_AND_DECLARATION_KEYWORDS = const [
+    Keyword.ABSTRACT,
+    Keyword.CLASS,
+    Keyword.CONST,
+    Keyword.DYNAMIC,
+    Keyword.EXPORT,
+    Keyword.FINAL,
+    Keyword.IMPORT,
+    Keyword.PART,
+    Keyword.TYPEDEF,
+    Keyword.VAR,
+    Keyword.VOID
+  ];
+
+  static const List<Keyword> DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS =
+      const [
+    Keyword.ABSTRACT,
+    Keyword.CLASS,
+    Keyword.CONST,
+    Keyword.DYNAMIC,
+    Keyword.EXPORT,
+    Keyword.FINAL,
+    Keyword.IMPORT,
+    Keyword.LIBRARY,
+    Keyword.PART,
+    Keyword.TYPEDEF,
+    Keyword.VAR,
+    Keyword.VOID
+  ];
+
+  static const List<String> NO_PSEUDO_KEYWORDS = const [];
+
+  static const List<Keyword> STMT_START_IN_CLASS = const [
+    Keyword.ASSERT,
+    Keyword.CONST,
+    Keyword.DO,
+    Keyword.FINAL,
+    Keyword.FOR,
+    Keyword.IF,
+    Keyword.NEW,
+    Keyword.RETURN,
+    Keyword.SUPER,
+    Keyword.SWITCH,
+    Keyword.THIS,
+    Keyword.THROW,
+    Keyword.TRY,
+    Keyword.VAR,
+    Keyword.VOID,
+    Keyword.WHILE
+  ];
+
+  static const List<Keyword> STMT_START_IN_LOOP_IN_CLASS = const [
+    Keyword.ASSERT,
+    Keyword.BREAK,
+    Keyword.CONST,
+    Keyword.CONTINUE,
+    Keyword.DO,
+    Keyword.FINAL,
+    Keyword.FOR,
+    Keyword.IF,
+    Keyword.NEW,
+    Keyword.RETURN,
+    Keyword.SUPER,
+    Keyword.SWITCH,
+    Keyword.THIS,
+    Keyword.THROW,
+    Keyword.TRY,
+    Keyword.VAR,
+    Keyword.VOID,
+    Keyword.WHILE
+  ];
+
+  static const List<Keyword> STMT_START_IN_SWITCH_IN_CLASS = const [
+    Keyword.ASSERT,
+    Keyword.BREAK,
+    Keyword.CASE,
+    Keyword.CONST,
+    Keyword.DEFAULT,
+    Keyword.DO,
+    Keyword.FINAL,
+    Keyword.FOR,
+    Keyword.IF,
+    Keyword.NEW,
+    Keyword.RETURN,
+    Keyword.SUPER,
+    Keyword.SWITCH,
+    Keyword.THIS,
+    Keyword.THROW,
+    Keyword.TRY,
+    Keyword.VAR,
+    Keyword.VOID,
+    Keyword.WHILE
+  ];
+
+  static const List<Keyword> STMT_START_IN_SWITCH_OUTSIDE_CLASS = const [
+    Keyword.ASSERT,
+    Keyword.BREAK,
+    Keyword.CASE,
+    Keyword.CONST,
+    Keyword.DEFAULT,
+    Keyword.DO,
+    Keyword.FINAL,
+    Keyword.FOR,
+    Keyword.IF,
+    Keyword.NEW,
+    Keyword.RETURN,
+    Keyword.SWITCH,
+    Keyword.THROW,
+    Keyword.TRY,
+    Keyword.VAR,
+    Keyword.VOID,
+    Keyword.WHILE
+  ];
+
+  static const List<Keyword> STMT_START_OUTSIDE_CLASS = const [
+    Keyword.ASSERT,
+    Keyword.CONST,
+    Keyword.DO,
+    Keyword.FINAL,
+    Keyword.FOR,
+    Keyword.IF,
+    Keyword.NEW,
+    Keyword.RETURN,
+    Keyword.SWITCH,
+    Keyword.THROW,
+    Keyword.TRY,
+    Keyword.VAR,
+    Keyword.VOID,
+    Keyword.WHILE
+  ];
+
+  static const List<Keyword> STMT_START_IN_LOOP_OUTSIDE_CLASS = const [
+    Keyword.ASSERT,
+    Keyword.BREAK,
+    Keyword.CONST,
+    Keyword.CONTINUE,
+    Keyword.DO,
+    Keyword.FINAL,
+    Keyword.FOR,
+    Keyword.IF,
+    Keyword.NEW,
+    Keyword.RETURN,
+    Keyword.SWITCH,
+    Keyword.THROW,
+    Keyword.TRY,
+    Keyword.VAR,
+    Keyword.VOID,
+    Keyword.WHILE
+  ];
+
+  static const List<Keyword> EXPRESSION_START_INSTANCE = const [
+    Keyword.CONST,
+    Keyword.FALSE,
+    Keyword.NEW,
+    Keyword.NULL,
+    Keyword.SUPER,
+    Keyword.THIS,
+    Keyword.TRUE,
+  ];
+
+  static const List<Keyword> EXPRESSION_START_NO_INSTANCE = const [
+    Keyword.CONST,
+    Keyword.FALSE,
+    Keyword.NEW,
+    Keyword.NULL,
+    Keyword.TRUE,
+  ];
+
+  void assertSuggestKeywords(Iterable<Keyword> expectedKeywords,
+      {List<String> pseudoKeywords: NO_PSEUDO_KEYWORDS,
+      int relevance: DART_RELEVANCE_KEYWORD}) {
+    Set<String> expectedCompletions = new Set<String>();
+    Map<String, int> expectedOffsets = <String, int>{};
+    Set<String> actualCompletions = new Set<String>();
+    expectedCompletions.addAll(expectedKeywords.map((k) => k.syntax));
+    expectedCompletions.addAll(pseudoKeywords);
+    for (CompletionSuggestion s in suggestions) {
+      if (s.kind == CompletionSuggestionKind.KEYWORD) {
+        Keyword k = Keyword.keywords[s.completion];
+        if (k == null && !expectedCompletions.contains(s.completion)) {
+          fail('Invalid keyword suggested: ${s.completion}');
+        } else {
+          if (!actualCompletions.add(s.completion)) {
+            fail('Duplicate keyword suggested: ${s.completion}');
+          }
+        }
+      }
+    }
+    if (!_equalSets(expectedCompletions, actualCompletions)) {
+      StringBuffer msg = new StringBuffer();
+      msg.writeln('Expected:');
+      _appendCompletions(msg, expectedCompletions, actualCompletions);
+      msg.writeln('but found:');
+      _appendCompletions(msg, actualCompletions, expectedCompletions);
+      fail(msg.toString());
+    }
+    for (CompletionSuggestion s in suggestions) {
+      if (s.kind == CompletionSuggestionKind.KEYWORD) {
+        if (s.completion.startsWith(Keyword.IMPORT.syntax)) {
+          int importRelevance = relevance;
+          if (importRelevance == DART_RELEVANCE_HIGH &&
+              s.completion == "import '';") {
+            ++importRelevance;
+          }
+          expect(s.relevance, equals(importRelevance), reason: s.completion);
+        } else {
+          if (s.completion == Keyword.RETHROW.syntax) {
+            expect(s.relevance, equals(relevance - 1), reason: s.completion);
+          } else {
+            expect(s.relevance, equals(relevance), reason: s.completion);
+          }
+        }
+        int expectedOffset = expectedOffsets[s.completion];
+        if (expectedOffset == null) {
+          expectedOffset = s.completion.length;
+        }
+        expect(s.selectionOffset, equals(expectedOffset));
+        expect(s.selectionLength, equals(0));
+        expect(s.isDeprecated, equals(false));
+        expect(s.isPotential, equals(false));
+      }
+    }
+  }
+
+  fail_import_partial() async {
+    addTestSource('imp^ import "package:foo/foo.dart"; import "bar.dart";');
+    await computeSuggestions();
+    // TODO(danrubel) should not suggest declaration keywords
+    assertNotSuggested('class');
+  }
+
+  fail_import_partial4() async {
+    addTestSource('^ imp import "package:foo/foo.dart";');
+    await computeSuggestions();
+    // TODO(danrubel) should not suggest declaration keywords
+    assertNotSuggested('class');
+  }
+
+  fail_import_partial5() async {
+    addTestSource('library libA; imp^ import "package:foo/foo.dart";');
+    await computeSuggestions();
+    // TODO(danrubel) should not suggest declaration keywords
+    assertNotSuggested('class');
+  }
+
+  fail_import_partial6() async {
+    addTestSource(
+        'library bar; import "zoo.dart"; imp^ import "package:foo/foo.dart";');
+    await computeSuggestions();
+    // TODO(danrubel) should not suggest declaration keywords
+    assertNotSuggested('class');
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new KeywordContributor();
+  }
+
+  test_after_class() async {
+    addTestSource('class A {} ^');
+    await computeSuggestions();
+    assertSuggestKeywords(DECLARATION_KEYWORDS, relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_after_class2() async {
+    addTestSource('class A {} c^');
+    await computeSuggestions();
+    assertSuggestKeywords(DECLARATION_KEYWORDS, relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_after_import() async {
+    addTestSource('import "foo"; ^');
+    await computeSuggestions();
+    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_after_import2() async {
+    addTestSource('import "foo"; c^');
+    await computeSuggestions();
+    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_anonymous_function_async() async {
+    addTestSource('main() {foo(() ^ {}}}');
+    await computeSuggestions();
+    assertSuggestKeywords([],
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_anonymous_function_async2() async {
+    addTestSource('main() {foo(() a^ {}}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
+  }
+
+  test_anonymous_function_async3() async {
+    addTestSource('main() {foo(() async ^ {}}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_anonymous_function_async4() async {
+    addTestSource('main() {foo(() ^ => 2}}');
+    await computeSuggestions();
+    assertSuggestKeywords([],
+        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_anonymous_function_async5() async {
+    addTestSource('main() {foo(() ^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
+  }
+
+  test_argument() async {
+    addTestSource('main() {foo(^);}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_argument2() async {
+    addTestSource('main() {foo(n^);}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_argument_literal() async {
+    addTestSource('main() {foo("^");}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_argument_named() async {
+    addTestSource('main() {foo(bar: ^);}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_argument_named2() async {
+    addTestSource('main() {foo(bar: n^);}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_argument_named_literal() async {
+    addTestSource('main() {foo(bar: "^");}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_assignment_field() async {
+    addTestSource('class A {var foo = ^}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_assignment_field2() async {
+    addTestSource('class A {var foo = n^}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_assignment_local() async {
+    addTestSource('main() {var foo = ^}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_assignment_local2() async {
+    addTestSource('main() {var foo = n^}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_assignment_local2_async() async {
+    addTestSource('main() async {var foo = n^}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
+        pseudoKeywords: ['await']);
+  }
+
+  test_assignment_local_async() async {
+    addTestSource('main() async {var foo = ^}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
+        pseudoKeywords: ['await']);
+  }
+
+  test_before_import() async {
+    addTestSource('^ import foo;');
+    await computeSuggestions();
+    assertSuggestKeywords(
+        [Keyword.EXPORT, Keyword.IMPORT, Keyword.LIBRARY, Keyword.PART],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_catch() async {
+    addTestSource('main() {try {} catch (e) {^}}}');
+    await computeSuggestions();
+    var keywords = <Keyword>[];
+    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.add(Keyword.RETHROW);
+    assertSuggestKeywords(keywords, relevance: DART_RELEVANCE_KEYWORD);
+  }
+
+  test_class() async {
+    addTestSource('class A e^ { }');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_body() async {
+    addTestSource('class A {^}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
+  }
+
+  test_class_body_beginning() async {
+    addTestSource('class A {^ var foo;}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
+  }
+
+  test_class_body_between() async {
+    addTestSource('class A {var bar; ^ var foo;}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
+  }
+
+  test_class_body_end() async {
+    addTestSource('class A {var foo; ^}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
+  }
+
+  test_class_extends() async {
+    addTestSource('class A extends foo ^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_extends2() async {
+    addTestSource('class A extends foo i^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_extends3() async {
+    addTestSource('class A extends foo i^ { }');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_extends_name() async {
+    addTestSource('class A extends ^');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_class_implements() async {
+    addTestSource('class A ^ implements foo');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.EXTENDS], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_implements2() async {
+    addTestSource('class A e^ implements foo');
+    await computeSuggestions();
+    // TODO (danrubel) refinement: don't suggest implements
+    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_implements3() async {
+    addTestSource('class A e^ implements foo { }');
+    await computeSuggestions();
+    // TODO (danrubel) refinement: don't suggest implements
+    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_implements_name() async {
+    addTestSource('class A implements ^');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_class_name() async {
+    addTestSource('class ^');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_class_noBody() async {
+    addTestSource('class A ^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_noBody2() async {
+    addTestSource('class A e^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_noBody3() async {
+    addTestSource('class A e^ String foo;');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_with() async {
+    addTestSource('class A extends foo with bar ^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IMPLEMENTS], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_with2() async {
+    addTestSource('class A extends foo with bar i^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IMPLEMENTS], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_with3() async {
+    addTestSource('class A extends foo with bar i^ { }');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IMPLEMENTS], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_class_with_name() async {
+    addTestSource('class A extends foo with ^');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_constructor_param() async {
+    addTestSource('class A { A(^) {});}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.THIS]);
+  }
+
+  test_constructor_param2() async {
+    addTestSource('class A { A(t^) {});}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.THIS]);
+  }
+
+  test_do_break_continue() async {
+    addTestSource('main() {do {^} while (true);}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS,
+        relevance: DART_RELEVANCE_KEYWORD);
+  }
+
+  test_do_break_continue2() async {
+    addTestSource('class A {foo() {do {^} while (true);}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS,
+        relevance: DART_RELEVANCE_KEYWORD);
+  }
+
+  test_empty() async {
+    addTestSource('^');
+    await computeSuggestions();
+    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_for_break_continue() async {
+    addTestSource('main() {for (int x in myList) {^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS,
+        relevance: DART_RELEVANCE_KEYWORD);
+  }
+
+  test_for_break_continue2() async {
+    addTestSource('class A {foo() {for (int x in myList) {^}}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS,
+        relevance: DART_RELEVANCE_KEYWORD);
+  }
+
+  test_for_expression_in() async {
+    addTestSource('main() {for (int x i^)}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IN], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_for_expression_in2() async {
+    addTestSource('main() {for (int x in^)}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IN], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_for_expression_init() async {
+    addTestSource('main() {for (int x = i^)}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_for_expression_init2() async {
+    addTestSource('main() {for (int x = in^)}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_function_async() async {
+    addTestSource('main()^');
+    await computeSuggestions();
+    assertSuggestKeywords(DECLARATION_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_function_async2() async {
+    addTestSource('main()^{}');
+    await computeSuggestions();
+    assertSuggestKeywords([],
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_function_async3() async {
+    addTestSource('main()a^');
+    await computeSuggestions();
+    assertSuggestKeywords(DECLARATION_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_function_async4() async {
+    addTestSource('main()a^{}');
+    await computeSuggestions();
+    assertSuggestKeywords(DECLARATION_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_function_async5() async {
+    addTestSource('main()a^ Foo foo;');
+    await computeSuggestions();
+    assertSuggestKeywords(DECLARATION_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_function_body_inClass_constructorInitializer() async {
+    addTestSource(r'''
+foo(p) {}
+class A {
+  final f;
+  A() : f = foo(() {^});
+}
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+  }
+
+  test_function_body_inClass_constructorInitializer_async() async {
+    addTestSource(r'''
+foo(p) {}
+class A {
+  final f;
+  A() : f = foo(() async {^});
+}
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
+  }
+
+  test_function_body_inClass_constructorInitializer_async_star() async {
+    addTestSource(r'''
+  foo(p) {}
+  class A {
+    final f;
+    A() : f = foo(() async* {^});
+  }
+  ''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_function_body_inClass_field() async {
+    addTestSource(r'''
+class A {
+  var f = () {^};
+}
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+  }
+
+  test_function_body_inClass_methodBody() async {
+    addTestSource(r'''
+class A {
+  m() {
+    f() {^};
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS);
+  }
+
+  test_function_body_inClass_methodBody_inFunction() async {
+    addTestSource(r'''
+class A {
+  m() {
+    f() {
+      f2() {^};
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS);
+  }
+
+  test_function_body_inClass_methodBody_inFunction_async() async {
+    addTestSource(r'''
+class A {
+  m() {
+    f() {
+      f2() async {^};
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
+  }
+
+  test_function_body_inClass_methodBody_inFunction_async_star() async {
+    addTestSource(r'''
+  class A {
+    m() {
+      f() {
+        f2() async* {^};
+      };
+    }
+  }
+  ''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_function_body_inUnit() async {
+    addTestSource('main() {^}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+  }
+
+  test_function_body_inUnit_afterBlock() async {
+    addTestSource('main() {{}^}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+  }
+
+  test_function_body_inUnit_async() async {
+    addTestSource('main() async {^}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
+  }
+
+  test_function_body_inUnit_async_star() async {
+    addTestSource('main() async* {n^}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_function_body_inUnit_async_star2() async {
+    addTestSource('main() async* {n^ foo}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_function_body_inUnit_sync_star() async {
+    addTestSource('main() sync* {n^}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_function_body_inUnit_sync_star2() async {
+    addTestSource('main() sync* {n^ foo}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_if_expression_in_class() async {
+    addTestSource('class A {foo() {if (^) }}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
+  }
+
+  test_if_expression_in_class2() async {
+    addTestSource('class A {foo() {if (n^) }}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
+  }
+
+  test_if_expression_in_function() async {
+    addTestSource('foo() {if (^) }');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_if_expression_in_function2() async {
+    addTestSource('foo() {if (n^) }');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_if_in_class() async {
+    addTestSource('class A {foo() {if (true) ^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS);
+  }
+
+  test_if_in_class2() async {
+    addTestSource('class A {foo() {if (true) ^;}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS);
+  }
+
+  test_if_in_class3() async {
+    addTestSource('class A {foo() {if (true) r^;}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS);
+  }
+
+  test_if_in_class4() async {
+    addTestSource('class A {foo() {if (true) ^ go();}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS);
+  }
+
+  test_if_outside_class() async {
+    addTestSource('foo() {if (true) ^}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+  }
+
+  test_if_outside_class2() async {
+    addTestSource('foo() {if (true) ^;}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+  }
+
+  test_if_outside_class3() async {
+    addTestSource('foo() {if (true) r^;}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+  }
+
+  test_if_outside_class4() async {
+    addTestSource('foo() {if (true) ^ go();}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+  }
+
+  test_import() async {
+    addTestSource('import "foo" deferred as foo ^;');
+    await computeSuggestions();
+    assertSuggestKeywords([],
+        pseudoKeywords: ['show', 'hide'], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_as() async {
+    addTestSource('import "foo" deferred ^;');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_as2() async {
+    addTestSource('import "foo" deferred a^;');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_as3() async {
+    addTestSource('import "foo" deferred a^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred() async {
+    addTestSource('import "foo" ^ as foo;');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.DEFERRED], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred2() async {
+    addTestSource('import "foo" d^ as foo;');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.DEFERRED], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred3() async {
+    addTestSource('import "foo" d^ show foo;');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS],
+        pseudoKeywords: ['deferred as'], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred4() async {
+    addTestSource('import "foo" d^ hide foo;');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS],
+        pseudoKeywords: ['deferred as'], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred5() async {
+    addTestSource('import "foo" d^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS],
+        pseudoKeywords: ['deferred as', 'show', 'hide'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred6() async {
+    addTestSource('import "foo" d^ import');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS],
+        pseudoKeywords: ['deferred as', 'show', 'hide'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred_as() async {
+    addTestSource('import "foo" ^;');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS],
+        pseudoKeywords: ['deferred as', 'show', 'hide'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred_as2() async {
+    addTestSource('import "foo" d^;');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS],
+        pseudoKeywords: ['deferred as', 'show', 'hide'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred_as3() async {
+    addTestSource('import "foo" ^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS],
+        pseudoKeywords: ['deferred as', 'show', 'hide'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred_as4() async {
+    addTestSource('import "foo" d^');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS],
+        pseudoKeywords: ['deferred as', 'show', 'hide'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred_as5() async {
+    addTestSource('import "foo" sh^ import "bar"; import "baz";');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.AS],
+        pseudoKeywords: ['deferred as', 'show', 'hide'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred_not() async {
+    addTestSource('import "foo" as foo ^;');
+    await computeSuggestions();
+    assertSuggestKeywords([],
+        pseudoKeywords: ['show', 'hide'], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_deferred_partial() async {
+    addTestSource('import "package:foo/foo.dart" def^ as foo;');
+    await computeSuggestions();
+    expect(replacementOffset, 30);
+    expect(replacementLength, 3);
+    assertSuggestKeywords([Keyword.DEFERRED], relevance: DART_RELEVANCE_HIGH);
+    expect(suggestions[0].selectionOffset, 8);
+    expect(suggestions[0].selectionLength, 0);
+  }
+
+  test_import_incomplete() async {
+    addTestSource('import "^"');
+    await computeSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_import_partial() async {
+    addTestSource('imp^ import "package:foo/foo.dart"; import "bar.dart";');
+    await computeSuggestions();
+    expect(replacementOffset, 0);
+    expect(replacementLength, 3);
+    // TODO(danrubel) should not suggest declaration keywords
+    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_partial2() async {
+    addTestSource('^imp import "package:foo/foo.dart";');
+    await computeSuggestions();
+    expect(replacementOffset, 0);
+    expect(replacementLength, 3);
+    // TODO(danrubel) should not suggest declaration keywords
+    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_partial3() async {
+    addTestSource(' ^imp import "package:foo/foo.dart"; import "bar.dart";');
+    await computeSuggestions();
+    expect(replacementOffset, 1);
+    expect(replacementLength, 3);
+    // TODO(danrubel) should not suggest declaration keywords
+    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_partial4() async {
+    addTestSource('^ imp import "package:foo/foo.dart";');
+    await computeSuggestions();
+    expect(replacementOffset, 0);
+    expect(replacementLength, 0);
+    // TODO(danrubel) should not suggest declaration keywords
+    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_partial5() async {
+    addTestSource('library libA; imp^ import "package:foo/foo.dart";');
+    await computeSuggestions();
+    expect(replacementOffset, 14);
+    expect(replacementLength, 3);
+    // TODO(danrubel) should not suggest declaration keywords
+    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_import_partial6() async {
+    addTestSource(
+        'library bar; import "zoo.dart"; imp^ import "package:foo/foo.dart";');
+    await computeSuggestions();
+    expect(replacementOffset, 32);
+    expect(replacementLength, 3);
+    // TODO(danrubel) should not suggest declaration keywords
+    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_is_expression() async {
+    addTestSource('main() {if (x is^)}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_library() async {
+    addTestSource('library foo;^');
+    await computeSuggestions();
+    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_library_declaration() async {
+    addTestSource('library ^');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_library_declaration2() async {
+    addTestSource('library a^');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_library_declaration3() async {
+    addTestSource('library a.^');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_library_name() async {
+    addTestSource('library ^');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_method_async() async {
+    addTestSource('class A { foo() ^}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
+  }
+
+  test_method_async2() async {
+    addTestSource('class A { foo() ^{}}');
+    await computeSuggestions();
+    assertSuggestKeywords([],
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_method_async3() async {
+    addTestSource('class A { foo() a^}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
+  }
+
+  test_method_async4() async {
+    addTestSource('class A { foo() a^{}}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
+  }
+
+  test_method_async5() async {
+    addTestSource('class A { foo() ^ Foo foo;}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
+  }
+
+  test_method_async6() async {
+    addTestSource('class A { foo() a^ Foo foo;}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
+  }
+
+  test_method_async7() async {
+    addTestSource('class A { foo() ^ => Foo foo;}');
+    await computeSuggestions();
+    assertSuggestKeywords([],
+        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_method_async8() async {
+    addTestSource('class A { foo() a^ Foo foo;}');
+    await computeSuggestions();
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
+  }
+
+  test_method_body() async {
+    addTestSource('class A { foo() {^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS);
+  }
+
+  test_method_body2() async {
+    addTestSource('class A { foo() => ^}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
+  }
+
+  test_method_body3() async {
+    addTestSource('class A { foo() => ^ Foo foo;}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
+  }
+
+  test_method_body4() async {
+    addTestSource('class A { foo() => ^;}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
+  }
+
+  test_method_body_async() async {
+    addTestSource('class A { foo() async {^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
+  }
+
+  test_method_body_async_star() async {
+    addTestSource('class A { foo() async* {^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_method_body_async2() async {
+    addTestSource('class A { foo() async => ^}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']);
+  }
+
+  test_method_body_async3() async {
+    addTestSource('class A { foo() async => ^ Foo foo;}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']);
+  }
+
+  test_method_body_async4() async {
+    addTestSource('class A { foo() async => ^;}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']);
+  }
+
+  test_method_body_expression1() async {
+    addTestSource('class A { foo() {return b == true ? ^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
+  }
+
+  test_method_body_expression2() async {
+    addTestSource('class A { foo() {return b == true ? 1 : ^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
+  }
+
+  test_method_body_return() async {
+    addTestSource('class A { foo() {return ^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
+  }
+
+  test_method_param() async {
+    addTestSource('class A { foo(^) {});}');
+    await computeSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_method_param2() async {
+    addTestSource('class A { foo(t^) {});}');
+    await computeSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_named_constructor_invocation() async {
+    addTestSource('void main() {new Future.^}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_newInstance() async {
+    addTestSource('class A { foo() {new ^}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_newInstance2() async {
+    addTestSource('class A { foo() {new ^ print("foo");}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_newInstance_prefixed() async {
+    addTestSource('class A { foo() {new A.^}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_newInstance_prefixed2() async {
+    addTestSource('class A { foo() {new A.^ print("foo");}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_part_of() async {
+    addTestSource('part of foo;^');
+    await computeSuggestions();
+    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_partial_class() async {
+    addTestSource('cl^');
+    await computeSuggestions();
+    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_partial_class2() async {
+    addTestSource('library a; cl^');
+    await computeSuggestions();
+    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_prefixed_field() async {
+    addTestSource('class A { int x; foo() {x.^}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_prefixed_field2() async {
+    addTestSource('class A { int x; foo() {x.^ print("foo");}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_prefixed_library() async {
+    addTestSource('import "b" as b; class A { foo() {b.^}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_prefixed_local() async {
+    addTestSource('class A { foo() {int x; x.^}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_prefixed_local2() async {
+    addTestSource('class A { foo() {int x; x.^ print("foo");}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_property_access() async {
+    addTestSource('class A { get x => 7; foo() {new A().^}}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_switch_expression() async {
+    addTestSource('main() {switch(^) {}}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_switch_expression2() async {
+    addTestSource('main() {switch(n^) {}}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_switch_expression3() async {
+    addTestSource('main() {switch(n^)}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
+  }
+
+  test_switch_start() async {
+    addTestSource('main() {switch(1) {^}}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_switch_start2() async {
+    addTestSource('main() {switch(1) {^ case 1:}}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_switch_start3() async {
+    addTestSource('main() {switch(1) {^default:}}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_switch_start4() async {
+    addTestSource('main() {switch(1) {^ default:}}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_switch_start5() async {
+    addTestSource('main() {switch(1) {c^ default:}}');
+    await computeSuggestions();
+    expect(replacementOffset, 19);
+    expect(replacementLength, 1);
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_switch_start6() async {
+    addTestSource('main() {switch(1) {c^}}');
+    await computeSuggestions();
+    expect(replacementOffset, 19);
+    expect(replacementLength, 1);
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_switch_start7() async {
+    addTestSource('main() {switch(1) { c^ }}');
+    await computeSuggestions();
+    expect(replacementOffset, 20);
+    expect(replacementLength, 1);
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_switch_statement() async {
+    addTestSource('main() {switch(1) {case 1:^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_SWITCH_OUTSIDE_CLASS);
+  }
+
+  test_switch_statement2() async {
+    addTestSource('class A{foo() {switch(1) {case 1:^}}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_SWITCH_IN_CLASS);
+  }
+
+  test_while_break_continue() async {
+    addTestSource('main() {while (true) {^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS,
+        relevance: DART_RELEVANCE_KEYWORD);
+  }
+
+  test_while_break_continue2() async {
+    addTestSource('class A {foo() {while (true) {^}}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS,
+        relevance: DART_RELEVANCE_KEYWORD);
+  }
+
+  void _appendCompletions(
+      StringBuffer msg, Iterable<String> completions, Iterable<String> other) {
+    List<String> sorted = completions.toList();
+    sorted.sort((c1, c2) => c1.compareTo(c2));
+    sorted.forEach(
+        (c) => msg.writeln('  $c, ${other.contains(c) ? '' : '<<<<<<<<<<<'}'));
+  }
+
+  bool _equalSets(Iterable<String> iter1, Iterable<String> iter2) {
+    if (iter1.length != iter2.length) return false;
+    if (iter1.any((c) => !iter2.contains(c))) return false;
+    if (iter2.any((c) => !iter1.contains(c))) return false;
+    return true;
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart
new file mode 100644
index 0000000..850389c
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart
@@ -0,0 +1,326 @@
+// 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 test.services.completion.contributor.dart.label;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/label_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LabelContributorTest);
+}
+
+@reflectiveTest
+class LabelContributorTest extends DartCompletionContributorTest {
+  CompletionSuggestion assertSuggestLabel(String name,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.IDENTIFIER}) {
+    CompletionSuggestion cs =
+        assertSuggest(name, csKind: kind, relevance: relevance);
+    expect(cs.returnType, isNull);
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.flags, 0);
+    expect(element.kind, equals(protocol.ElementKind.LABEL));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, isNull);
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new LabelContributor();
+  }
+
+  test_break_ignores_outer_functions_using_closure() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    var f = () {
+      bar: while (true) { break ^ }
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_break_ignores_outer_functions_using_local_function() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    void f() {
+      bar: while (true) { break ^ }
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_break_ignores_toplevel_variables() async {
+    addTestSource('''
+int x;
+void main() {
+  while (true) {
+    break ^
+  }
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('x');
+  }
+
+  test_break_ignores_unrelated_statements() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {}
+  while (true) { break ^ }
+  bar: while (true) {}
+}
+''');
+    await computeSuggestions();
+    // The scope of the label defined by a labeled statement is just the
+    // statement itself, so neither "foo" nor "bar" are in scope at the caret
+    // position.
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+  }
+
+  test_break_to_enclosing_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    bar: while (true) {
+      break ^
+    }
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+    assertSuggestLabel('bar');
+  }
+
+  test_continue_from_loop_to_switch() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      break;
+    bar: case 2:
+      while (true) {
+        continue ^;
+      }
+      break;
+    baz: case 3:
+      break;
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+    assertSuggestLabel('bar');
+    assertSuggestLabel('baz');
+  }
+
+  test_continue_from_switch_to_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    switch (x) {
+      case 1:
+        continue ^;
+    }
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+  }
+
+  test_continue_ignores_outer_functions_using_closure_with_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    var f = () {
+      bar: while (true) { continue ^ }
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_continue_ignores_outer_functions_using_closure_with_switch() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      var f = () {
+        bar: while (true) { continue ^ }
+      };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_continue_ignores_outer_functions_using_local_function_with_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    void f() {
+      bar: while (true) { continue ^ }
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_continue_ignores_outer_functions_using_local_function_with_switch() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      void f() {
+        bar: while (true) { continue ^ }
+      };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_continue_ignores_unrelated_statements() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {}
+  while (true) { continue ^ }
+  bar: while (true) {}
+}
+''');
+    await computeSuggestions();
+    // The scope of the label defined by a labeled statement is just the
+    // statement itself, so neither "foo" nor "bar" are in scope at the caret
+    // position.
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+  }
+
+  test_continue_to_earlier_case() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      break;
+    case 2:
+      continue ^;
+    case 3:
+      break;
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+  }
+
+  test_continue_to_enclosing_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    bar: while (true) {
+      continue ^
+    }
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+    assertSuggestLabel('bar');
+  }
+
+  test_continue_to_enclosing_switch() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      break;
+    bar: case 2:
+      switch (y) {
+        case 1:
+          continue ^;
+      }
+      break;
+    baz: case 3:
+      break;
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+    assertSuggestLabel('bar');
+    assertSuggestLabel('baz');
+  }
+
+  test_continue_to_later_case() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    case 1:
+      break;
+    case 2:
+      continue ^;
+    foo: case 3:
+      break;
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+  }
+
+  test_continue_to_same_case() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    case 1:
+      break;
+    foo: case 2:
+      continue ^;
+    case 3:
+      break;
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
new file mode 100644
index 0000000..fd218a0
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -0,0 +1,271 @@
+// 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 test.services.completion.contributor.dart.library_member;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LibraryMemberContributorTest);
+}
+
+@reflectiveTest
+class LibraryMemberContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new LibraryMemberContributor();
+  }
+
+  test_libraryPrefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {bar.^}');
+    await computeSuggestions();
+    assertSuggestClass('Future');
+    assertNotSuggested('loadLibrary');
+  }
+
+  test_libraryPrefix_cascade() async {
+    addTestSource('''
+    import "dart:math" as math;
+    main() {math..^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_libraryPrefix_cascade2() async {
+    addTestSource('''
+    import "dart:math" as math;
+    main() {math.^.}''');
+    await computeSuggestions();
+    assertSuggestFunction('min', 'num');
+  }
+
+  test_libraryPrefix_cascade3() async {
+    addTestSource('''
+    import "dart:math" as math;
+    main() {math..^a}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_libraryPrefix_cascade4() async {
+    addTestSource('''
+    import "dart:math" as math;
+    main() {math.^.a}''');
+    await computeSuggestions();
+    assertSuggestFunction('min', 'num');
+  }
+
+  test_libraryPrefix2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
+    await computeSuggestions();
+    assertSuggestClass('Future');
+  }
+
+  test_libraryPrefix3() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
+    await computeSuggestions();
+    assertSuggestConstructor('Future');
+    assertSuggestConstructor('Future.delayed');
+  }
+
+  test_libraryPrefix_deferred() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
+    await computeSuggestions();
+    assertSuggestClass('Future');
+    assertSuggestFunction('loadLibrary', 'Future<dynamic>');
+  }
+
+  test_libraryPrefix_deferred_inPart() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    var libFile = '${testFile.substring(0, testFile.length - 5)}A.dart';
+    addSource(
+        libFile,
+        '''
+        library testA;
+        import "dart:async" deferred as bar;
+        part "$testFile";''');
+    addTestSource('part of testA; foo() {bar.^}');
+    // Assume that libraries containing has been computed for part files
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    assertSuggestClass('Future');
+    assertSuggestFunction('loadLibrary', 'Future<dynamic>');
+    assertNotSuggested('foo');
+  }
+
+  test_libraryPrefix_with_exports() async {
+    addSource('/libA.dart', 'library libA; class A { }');
+    addSource(
+        '/libB.dart',
+        '''
+        library libB;
+        export "/libA.dart";
+        class B { }
+        @deprecated class B1 { }''');
+    addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
+    await computeSuggestions();
+    assertSuggestClass('B');
+    assertSuggestClass('B1', relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    assertSuggestClass('A');
+    assertNotSuggested('C');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        main() {b.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestClass('Y');
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_inPart() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    var libFile = '${testFile.substring(0, testFile.length - 5)}A.dart';
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addSource(
+        libFile,
+        '''
+        library testA;
+        import "/testB.dart" as b;
+        part "$testFile";
+        var T2;
+        class A { }''');
+    addTestSource('''
+        part of testA;
+        main() {b.^}''');
+    // Assume that libraries containing has been computed for part files
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestClass('Y');
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^ f) {}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestClass('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^) {}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestClass('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class _W {M y; var _z;}
+        class X extends _W {}
+        class M{}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo(X x) {x.^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+        class A {static int bar = 10;}
+        _B() {}''');
+    addTestSource('''
+        import "/testA.dart";
+        class X {foo(){A^.bar}}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
new file mode 100644
index 0000000..2de1f23
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
@@ -0,0 +1,377 @@
+// 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 test.services.completion.contributor.dart.library_prefix;
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LibraryPrefixContributorTest);
+}
+
+@reflectiveTest
+class LibraryPrefixContributorTest extends DartCompletionContributorTest {
+  void assertSuggestLibraryPrefixes(List<String> expectedPrefixes) {
+    for (String prefix in expectedPrefixes) {
+      CompletionSuggestion cs = assertSuggest(prefix,
+          csKind: CompletionSuggestionKind.IDENTIFIER,
+          relevance: DART_RELEVANCE_DEFAULT);
+      Element element = cs.element;
+      expect(element, isNotNull);
+      expect(element.kind, equals(ElementKind.LIBRARY));
+      expect(element.parameters, isNull);
+      expect(element.returnType, isNull);
+      assertHasNoParameterInfo(cs);
+    }
+    if (suggestions.length != expectedPrefixes.length) {
+      failedCompletion('expected only ${expectedPrefixes.length} suggestions');
+    }
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new LibraryPrefixContributor();
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    ^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['g']);
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    final var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['g']);
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['g']);
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+@deprecated class A {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ A(){}}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as Soo;
+class A {final S^ A();}
+class _B {}
+A Sew;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLibraryPrefixes(['Soo']);
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ final foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ var foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_InstanceCreationExpression() async {
+    addSource(
+        '/testA.dart',
+        '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+    addTestSource('''
+import "/testA.dart" as t;
+import "dart:math" as math;
+main() {new ^ String x = "hello";}''');
+    await computeSuggestions();
+    assertSuggestLibraryPrefixes(['math', 't']);
+  }
+
+  test_InstanceCreationExpression2() async {
+    addTestSource('import "dart:convert" as json;f() {var x=new js^}');
+    await computeSuggestions();
+    assertSuggestLibraryPrefixes(['json']);
+  }
+
+  test_InstanceCreationExpression_inPart() async {
+    addSource(
+        '/testA.dart',
+        '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+    addSource(
+        '/testB.dart',
+        '''
+library testB;
+import "/testA.dart" as t;
+import "dart:math" as math;
+part "$testFile"
+main() {new ^ String x = "hello";}''');
+    addTestSource('''
+part of testB;
+main() {new ^ String x = "hello";}''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    assertSuggestLibraryPrefixes(['math', 't']);
+  }
+
+  test_InstanceCreationExpression_inPart_detached() async {
+    addSource(
+        '/testA.dart',
+        '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+    addSource(
+        '/testB.dart',
+        '''
+library testB;
+import "/testA.dart" as t;
+import "dart:math" as math;
+//part "$testFile"
+main() {new ^ String x = "hello";}''');
+    addTestSource('''
+//part of testB;
+main() {new ^ String x = "hello";}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
new file mode 100644
index 0000000..64773f4
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
@@ -0,0 +1,4074 @@
+// 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 test.services.completion.contributor.dart.constructor;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/local_constructor_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LocalConstructorContributorTest);
+}
+
+@reflectiveTest
+class LocalConstructorContributorTest extends DartCompletionContributorTest {
+  CompletionSuggestion assertSuggestLocalVariable(
+      String name, String returnType,
+      {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) {
+    // Local variables should only be suggested by LocalReferenceContributor
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.LOCAL_VARIABLE));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, returnType != null ? returnType : 'dynamic');
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestParameter(String name, String returnType,
+      {int relevance: DART_RELEVANCE_PARAMETER}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.PARAMETER));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType,
+        equals(returnType != null ? returnType : 'dynamic'));
+    return cs;
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new LocalConstructorContributor();
+  }
+
+  test_constructor_parameters_mixed_required_and_named() async {
+    addTestSource('class A {A(x, {int y}) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_constructor_parameters_mixed_required_and_positional() async {
+    addTestSource('class A {A(x, [int y]) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_constructor_parameters_named() async {
+    addTestSource('class A {A({x, int y}) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_constructor_parameters_positional() async {
+    addTestSource('class A {A([x, int y]) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_constructor_parameters_required() async {
+    addTestSource('class A {A(x, int y) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_enum() async {
+    addTestSource('enum E { one, two } main() {^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_enum_deprecated() async {
+    addTestSource('@deprecated enum E { one, two } main() {^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_function_parameters_mixed_required_and_named() async {
+    addTestSource('''
+void m(x, {int y}) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+void m(x, [int y]) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_named() async {
+    addTestSource('''
+void m({x, int y}) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_none() async {
+    addTestSource('''
+void m() {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_positional() async {
+    addTestSource('''
+void m([x, int y]) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_required() async {
+    addTestSource('''
+void m(x, int y) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_ignore_symbol_being_completed() async {
+    addTestSource('class MyClass { } main(MC^) { }');
+    await computeSuggestions();
+    assertNotSuggested('MyClass');
+    assertNotSuggested('MC');
+  }
+
+  test_inDartDoc_reference1() async {
+    addTestSource('''
+/// The [^
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertNotSuggested('main');
+  }
+
+  test_inDartDoc_reference2() async {
+    addTestSource('''
+/// The [m^
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertNotSuggested('main');
+  }
+
+  test_inDartDoc_reference3() async {
+    addTestSource('''
+/// The [^]
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertNotSuggested('main');
+  }
+
+  test_inDartDoc_reference4() async {
+    addTestSource('''
+/// The [m^]
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertNotSuggested('main');
+  }
+
+  test_InstanceCreationExpression() async {
+    addTestSource('''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }
+main() {new ^ String x = "hello";}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion;
+
+    suggestion = assertSuggestConstructor('A', elemOffset: -1);
+    expect(suggestion.element.parameters, '()');
+    expect(suggestion.element.returnType, 'A');
+    expect(suggestion.declaringType, 'A');
+    expect(suggestion.parameterNames, hasLength(0));
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('B');
+    expect(suggestion.element.parameters, '(int x, [String boo])');
+    expect(suggestion.element.returnType, 'B');
+    expect(suggestion.declaringType, 'B');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'int');
+    expect(suggestion.parameterNames[1], 'boo');
+    expect(suggestion.parameterTypes[1], 'String');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('C.bar');
+    expect(suggestion.element.parameters, '({dynamic boo: \'hoo\', int z: 0})');
+    expect(suggestion.element.returnType, 'C');
+    expect(suggestion.declaringType, 'C');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'boo');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'z');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    addTestSource('''
+class A {
+  void m(x, {int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+class A {
+  void m(x, [int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_named() async {
+    addTestSource('''
+class A {
+  void m({x, int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_none() async {
+    addTestSource('''
+class A {
+  void m() {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_positional() async {
+    addTestSource('''
+class A {
+  void m([x, int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_required() async {
+    addTestSource('''
+class A {
+  void m(x, int y) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_missing_params_constructor() async {
+    addTestSource('class C1{C1{} main(){C^}}');
+    await computeSuggestions();
+  }
+
+  test_missing_params_function() async {
+    addTestSource('int f1{} main(){f^}');
+    await computeSuggestions();
+  }
+
+  test_missing_params_method() async {
+    addTestSource('class C1{int f1{} main(){f^}}');
+    await computeSuggestions();
+  }
+
+  test_overrides() async {
+    addTestSource('''
+class A {m() {}}
+class B extends A {m() {^}}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_prioritization() async {
+    addTestSource('main() {var ab; var _ab; ^}');
+    await computeSuggestions();
+    assertNotSuggested('ab');
+    assertNotSuggested('_ab');
+  }
+
+  test_prioritization_private() async {
+    addTestSource('main() {var ab; var _ab; _^}');
+    await computeSuggestions();
+    assertNotSuggested('ab');
+    assertNotSuggested('_ab');
+  }
+
+  test_prioritization_public() async {
+    addTestSource('main() {var ab; var _ab; a^}');
+    await computeSuggestions();
+    assertNotSuggested('ab');
+    assertNotSuggested('_ab');
+  }
+
+  test_shadowed_name() async {
+    addTestSource('var a; class A { var a; m() { ^ } }');
+    await computeSuggestions();
+    assertNotSuggested('a');
+  }
+
+  test_ArgumentList() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_imported_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+expect(arg) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {new A(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+typedef Funct();
+class A { A(Funct f) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {new A(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+expect(arg) { }
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_method() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+class B {
+  expect(arg) { }
+  void foo() {expect(^)}}
+String bar() => true;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_functionalArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar(f()) => true;
+void main() {bar(^);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_methodArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { String bar(f()) => true; }
+void main() {new B().bar(^);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_namedParam() async {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }''');
+    addTestSource('''
+import '/libA.dart'
+String bar() => true;
+void main() {expect(foo: ^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('main');
+  }
+
+  test_AsExpression() async {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('''
+        class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_AssignmentExpression_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_AssignmentExpression_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_AssignmentExpression_type() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  ^ b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  ^
+  b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  int^ b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  i^
+  b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('identical');
+  }
+
+  test_AwaitExpression() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main() async {A a; await ^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_BinaryExpression_LHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+  }
+
+  test_BinaryExpression_RHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('==');
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    ^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    final ^
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final2() async {
+    addTestSource('main() {final S^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final3() async {
+    addTestSource('main() {final ^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    final var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_identifier_partial() async {
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+class D3 { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+Z D2() {int x;}
+class X {a() {var f; {var x;} D^ var r;} void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+
+    // imported elements are portially filtered
+    //assertNotSuggested('A');
+    assertNotSuggested('_B');
+    //assertNotSuggested('C');
+    // hidden element suggested as low relevance
+    assertNotSuggested('D');
+    assertNotSuggested('D1');
+    assertNotSuggested('D2');
+    // unimported elements suggested with low relevance
+    assertNotSuggested('D3');
+    //assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    //assertSuggestLibraryPrefix('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    //assertNotSuggested('Object');
+    //assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    //assertSuggestTopLevelVarGetterSetter('T1', 'String');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    //assertNotSuggested('T5');
+    //assertSuggestTopLevelVar('_T6', null);
+    assertNotSuggested('==');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }''');
+    addTestSource('''
+import "/testB.dart";
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // TODO (danrubel) prefer fields over getters
+    // If add `get e1;` to interface I
+    // then suggestions include getter e1 rather than field e1
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    //assertNotSuggested('m2');
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    assertNotSuggested('m2');
+  }
+
+  test_Block_local_function() async {
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    p^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('partT8');
+    assertNotSuggested('partBoo');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_unimported() async {
+    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+    addSource(
+        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
+    testFile = '/proj/completionTest.dart';
+    addTestSource('class C {foo(){F^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Foo');
+    // TODO(danrubel) implement
+    assertNotSuggested('Foo2');
+    assertNotSuggested('Future');
+  }
+
+  test_CascadeExpression_selector1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+// looks like a cascade to the parser
+// but the user is trying to get completions for a non-cascade
+main() {A a; a.^.z}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+main() {A a; a..^z}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+main() {A a; a..^ return}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_target() async {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('''
+class A {var b; X _c;}
+class X{}
+main() {A a; a^..b}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_CatchClause_onType() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_onType_noBrackets() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_typed() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_untyped() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('s');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+@deprecated class A {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ A(){}}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as Soo;
+class A {final S^ A();}
+class _B {}
+A Sew;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('Sew');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('Soo');
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ final foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ var foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_Combinator_hide() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+library libAB;
+part '/partAB.dart';
+class A { }
+class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+part of libAB;
+var T1;
+PB F1() => new PB();
+class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+class C { }
+class D { }''');
+    addTestSource('''
+import "/testAB.dart" hide ^;
+import "/testCD.dart";
+class X {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_Combinator_show() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+library libAB;
+part '/partAB.dart';
+class A { }
+class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+part of libAB;
+var T1;
+PB F1() => new PB();
+typedef PB2 F2(int blat);
+class Clz = Object with Object;
+class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+class C { }
+class D { }''');
+    addTestSource('''
+import "/testAB.dart" show ^;
+import "/testCD.dart";
+class X {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_ConditionalExpression_elseExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_elseExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_partial_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T^}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_partial_thenExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? ^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T^ : c}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+var m;
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+var m;
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('fromCharCodes');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+int T1;
+F1() { }
+class X {factory X.c(); factory X._d(); z() {}}
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_DefaultFormalParameter_named_expression() async {
+    // DefaultFormalParameter FormalParameterList MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {a(blat: ^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ExpressionStatement_identifier() async {
+    // SimpleIdentifier  ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+_B F1() { }
+class A {int x;}
+class _B { }''');
+    addTestSource('''
+import "/testA.dart";
+typedef int F2(int blat);
+class Clz = Object with Object;
+class C {foo(){^} void bar() {}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('C');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('F2');
+    assertNotSuggested('Clz');
+    assertNotSuggested('C');
+    assertNotSuggested('x');
+    assertNotSuggested('_B');
+  }
+
+  test_ExpressionStatement_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        B T1;
+        class B{}''');
+    addTestSource('''
+        import "/testA.dart";
+        class C {a() {C ^}}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_typed() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {A ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_var() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {var ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldFormalParameter_in_non_constructor() async {
+    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
+    addTestSource('class A {B(this.^foo) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 3);
+    assertNoSuggestions();
+  }
+
+  test_ForEachStatement_body_typed() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_body_untyped() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_iterable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (int foo in ^) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_loopVariable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_FormalParameterList() async {
+    // FormalParameterList MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {a(^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ForStatement_body() async {
+    // Block  ForStatement
+    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('i');
+    assertNotSuggested('Object');
+  }
+
+  test_ForStatement_condition() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_initializer() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('int');
+  }
+
+  test_ForStatement_updaters() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_updaters_prefix_expression() async {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('''
+void bar() { }
+main() {for (int index = 0; index < 10; ++i^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+    assertNotSuggested('main');
+    assertNotSuggested('bar');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+/* */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment2() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+/** */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment3() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+/// some dartdoc
+class C2 { }
+^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionExpression_body_function() async {
+    // Block  BlockFunctionBody  FunctionExpression
+    addTestSource('''
+        void bar() { }
+        String foo(List args) {x.then((R b) {^});}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('args');
+    assertNotSuggested('b');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (true) ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_condition() async {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement_empty() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (^) something}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_invocation() async {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+main() {var a; if (a.^) something}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('toString');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_ImportDirective_dart() async {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+import "dart^";
+main() {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_IndexExpression() async {
+    // ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} f[^]}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_IndexExpression2() async {
+    // SimpleIdentifier IndexExpression ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} f[T^]}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_InstanceCreationExpression_imported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {A(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+import "dart:async";
+int T2;
+F2() { }
+class B {B(this.x, [String boo]) { } int x;}
+class C {foo(){var f; {var x;} new ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('Future');
+    assertNotSuggested('A');
+    assertSuggestConstructor('B');
+    assertSuggestConstructor('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('foo');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_InstanceCreationExpression_unimported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){new F^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Future');
+    assertNotSuggested('Foo');
+  }
+
+  test_InterpolationExpression() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+main() {String name; print("hello \$^");}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+main() {String name; print("hello \${^}");}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block2() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+    await computeSuggestions();
+
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+  }
+
+  test_InterpolationExpression_prefix_selector() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('length');
+    assertNotSuggested('name');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_InterpolationExpression_prefix_selector2() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \$name.^");}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_InterpolationExpression_prefix_target() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+    await computeSuggestions();
+
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('length');
+  }
+
+  test_IsExpression() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+main() {var x; if (x is ^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('x');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+  }
+
+  test_IsExpression_target() async {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {int x; int y() => 0;}
+main(){var a; if (^ is A)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (a is ^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (a is Obj^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_keyword() async {
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int newT1;
+int T1;
+nowIsIt() { }
+class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+String newer() {}
+var m;
+main() {new^ X.c();}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    // Imported suggestion are filtered by 1st character
+    assertNotSuggested('nowIsIt');
+    assertNotSuggested('T1');
+    assertNotSuggested('newT1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+    assertNotSuggested('newer');
+  }
+
+  test_Literal_list() async {
+    // ']'  ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([^]);}');
+    await computeSuggestions();
+
+    assertNotSuggested('Some');
+    assertNotSuggested('String');
+  }
+
+  test_Literal_list2() async {
+    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([S^]);}');
+    await computeSuggestions();
+
+    assertNotSuggested('Some');
+    assertNotSuggested('String');
+  }
+
+  test_Literal_string() async {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_MapLiteralEntry() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {^''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+  }
+
+  test_MapLiteralEntry1() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {T^''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_MapLiteralEntry2() async {
+    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {7:T^};''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_MethodDeclaration_body_getters() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+  }
+
+  test_MethodDeclaration_body_static() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testC.dart',
+        '''
+class C {
+  c1() {}
+  var c2;
+  static c3() {}
+  static var c4;}''');
+    addTestSource('''
+import "/testC.dart";
+class B extends C {
+  b1() {}
+  var b2;
+  static b3() {}
+  static var b4;}
+class A extends B {
+  a1() {}
+  var a2;
+  static a3() {}
+  static var a4;
+  static a() {^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    assertNotSuggested('a3');
+    assertNotSuggested('a4');
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    assertNotSuggested('b3');
+    assertNotSuggested('b4');
+    assertNotSuggested('c1');
+    assertNotSuggested('c2');
+    assertNotSuggested('c3');
+    assertNotSuggested('c4');
+  }
+
+  test_MethodDeclaration_members() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('_a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('bool');
+  }
+
+  test_MethodDeclaration_parameters_named() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('b');
+    assertNotSuggested('int');
+    assertNotSuggested('_');
+  }
+
+  test_MethodDeclaration_parameters_positional() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {Z a(X x, [int y=1]) {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('String');
+  }
+
+  test_MethodDeclaration_returnType() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {/* */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {/** */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment3() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {
+  /// some dartdoc
+  ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodInvocation_no_semicolon() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {x.^ m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_new_instance() async {
+    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
+    await computeSuggestions();
+
+    assertNotSuggested('nextBool');
+    assertNotSuggested('nextDouble');
+    assertNotSuggested('nextInt');
+    assertNotSuggested('Random');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+  }
+
+  test_parameterName_excludeTypes() async {
+    addTestSource('m(int ^) {}');
+    await computeSuggestions();
+
+    assertNotSuggested('int');
+    assertNotSuggested('bool');
+  }
+
+  test_partFile_TypeName() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+library libA;
+import "/testB.dart";
+part "$testFile";
+class A { }
+var m;''');
+    addTestSource('''
+part of libA;
+class B { factory B.bar(int x) => null; }
+main() {new ^}''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('B.bar');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+part of libA;
+class B { }''');
+    addTestSource('''
+library libA;
+import "/testB.dart";
+part "/testA.dart";
+class A { A({String boo: 'hoo'}) { } }
+main() {new ^}
+var m;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('B');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class I {
+  static const scI = 'boo';
+  X get f => new A();
+  get _g => new A();}
+class B implements I {
+  static const int scB = 12;
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    addTestSource('''
+import "/testB.dart";
+class A extends B {
+  static const String scA = 'foo';
+  w() { }}
+main() {A.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('scA');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_imported() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  static const int sc = 12;
+  @deprecated var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    addTestSource('''
+import "/testB.dart";
+main() {A a; a.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_local() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+main() {A a; a.^}
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  static const int sc = 12;
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+main() {b.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+foo(b.^ f) {}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+foo(b.^) {}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class _W {M y; var _z;}
+class X extends _W {}
+class M{}''');
+    addTestSource('''
+import "/testB.dart";
+foo(X x) {x.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('y');
+    assertNotSuggested('_z');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+class A {static int bar = 10;}
+_B() {}''');
+    addTestSource('''
+import "/testA.dart";
+class X {foo(){A^.bar}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('_B');
+  }
+
+  test_PrefixedIdentifier_propertyAccess() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_propertyAccess_newStmt() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_const() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_field() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_function() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_typed() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {String g; g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_method() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_localVariableDeclarationName() async {
+    addTestSource('main() {String m^}');
+    await computeSuggestions();
+
+    assertNotSuggested('main');
+    assertNotSuggested('min');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f(String g) {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PropertyAccess_expression() async {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 8);
+    assertNotSuggested('length');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PropertyAccess_noTarget() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){.^}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_noTarget2() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('main() {.^}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_selector() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEven');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_SwitchStatement_c() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_SwitchStatement_case() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
+    await computeSuggestions();
+
+    assertNotSuggested('A');
+    assertNotSuggested('g');
+    assertNotSuggested('t');
+    assertNotSuggested('String');
+  }
+
+  test_SwitchStatement_empty() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {^}}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_ThisExpression_block() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A() {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {this.^ m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A() {this.^}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.^) {}
+  A.z() {}
+  var b; X _c; static sb;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('sb');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param2() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.b^) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param3() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.^b) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param4() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.b, this.^) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_TypeArgumentList() async {
+    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+class C1 {int x;}
+F1() => 0;
+typedef String T1(int blat);''');
+    addTestSource('''
+import "/testA.dart";'
+class C2 {int x;}
+F2() => 0;
+typedef int T2(int blat);
+class C<E> {}
+main() { C<^> c; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('C1');
+    assertNotSuggested('T1');
+    assertNotSuggested('C2');
+    assertNotSuggested('T2');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+  }
+
+  test_TypeArgumentList2() async {
+    // TypeName  TypeArgumentList  TypeName
+    addSource(
+        '/testA.dart',
+        '''
+class C1 {int x;}
+F1() => 0;
+typedef String T1(int blat);''');
+    addTestSource('''
+import "/testA.dart";'
+class C2 {int x;}
+F2() => 0;
+typedef int T2(int blat);
+class C<E> {}
+main() { C<C^> c; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('C1');
+    assertNotSuggested('C2');
+  }
+
+  test_VariableDeclaration_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+main() {var ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_VariableDeclarationList_final() async {
+    // VariableDeclarationList  VariableDeclarationStatement  Block
+    addTestSource('main() {final ^} class C { }');
+    await computeSuggestions();
+
+    assertNotSuggested('Object');
+    assertNotSuggested('C');
+    assertNotSuggested('==');
+  }
+
+  test_VariableDeclarationStatement_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+class C {bar(){var f; {var x;} var e = ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo1() { }
+void bar1() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+foo2() { }
+void bar2() { }
+class Y {Y.c(); Y._d(); z() {}}
+class C {bar(){var f; {var x;} var e = ^ var g}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('foo1');
+    assertNotSuggested('bar1');
+    assertNotSuggested('foo2');
+    assertNotSuggested('bar2');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
new file mode 100644
index 0000000..f70f720f
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
@@ -0,0 +1,88 @@
+// 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 test.services.completion.local_declaration_visitor_test;
+
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LocalDeclarationVisitorTest);
+}
+
+@reflectiveTest
+class LocalDeclarationVisitorTest {
+  CompilationUnit parseCompilationUnit(String source) {
+    AnalysisErrorListener listener = AnalysisErrorListener.NULL_LISTENER;
+    Scanner scanner =
+        new Scanner(null, new CharSequenceReader(source), listener);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, listener);
+    CompilationUnit unit = parser.parseCompilationUnit(token);
+    expect(unit, isNotNull);
+    return unit;
+  }
+
+  test_visitForEachStatement() {
+    CompilationUnit unit = parseCompilationUnit('''
+class MyClass {}
+f(List<MyClass> list) {
+  for(MyClas( x in list) {}
+}
+''');
+    NodeList<CompilationUnitMember> declarations = unit.declarations;
+    expect(declarations, hasLength(2));
+    FunctionDeclaration f = declarations[1];
+    expect(f, isNotNull);
+    BlockFunctionBody body = f.functionExpression.body;
+    Statement statement = body.block.statements[0];
+    expect(statement, new isInstanceOf<ForEachStatement>());
+    statement.accept(new TestVisitor(statement.offset));
+  }
+}
+
+class TestVisitor extends LocalDeclarationVisitor {
+  TestVisitor(int offset) : super(offset);
+
+  @override
+  void declaredClass(ClassDeclaration declaration) {}
+
+  @override
+  void declaredClassTypeAlias(ClassTypeAlias declaration) {}
+
+  @override
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {}
+
+  @override
+  void declaredFunction(FunctionDeclaration declaration) {}
+
+  @override
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {}
+
+  @override
+  void declaredLabel(Label label, bool isCaseLabel) {}
+
+  @override
+  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
+    expect(name, isNotNull);
+  }
+
+  @override
+  void declaredMethod(MethodDeclaration declaration) {}
+
+  @override
+  void declaredParam(SimpleIdentifier name, TypeName type) {}
+
+  @override
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl) {}
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
new file mode 100644
index 0000000..fc707f9
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -0,0 +1,201 @@
+// 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 test.services.completion.contributor.dart.local_lib;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LocalLibraryContributorTest);
+}
+
+@reflectiveTest
+class LocalLibraryContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new LocalLibraryContributor();
+  }
+
+  test_partFile_Constructor() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        library libA;
+        import "/testB.dart";
+        part "$testFile";
+        class A { }
+        var m;''');
+    addTestSource('''
+        part of libA;
+        class B { factory B.bar(int x) => null; }
+        main() {new ^}''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('A');
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('B.bar');
+    // Suggested by ImportedReferenceContributor
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertSuggestTopLevelVar('m', 'dynamic',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+  }
+
+  test_partFile_TypeName() async {
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        library libA;
+        import "/testB.dart";
+        part "$testFile";
+        class A { var a1; a2(){}}
+        var m;
+        typedef t1(int blue);
+        int af() {return 0;}''');
+    addTestSource('''
+        part of libA;
+        class B { factory B.bar(int x) => null; }
+        main() {^}''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestFunction('af', 'int',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('m', null,
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunctionTypeAlias('t1', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('B.bar');
+    // Suggested by ImportedReferenceContributor
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+  }
+
+  test_partFile_Constructor2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        part of libA;
+        class B { }''');
+    addTestSource('''
+        library libA;
+        import "/testB.dart";
+        part "/testA.dart";
+        class A { A({String boo: 'hoo'}) { } }
+        main() {new ^}
+        var m;''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('B');
+    // Suggested by ConstructorContributor
+    assertNotSuggested('A');
+    // Suggested by ImportedReferenceContributor
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        part of libA;
+        class B { var b1; b2(){}}
+        int bf() => 0;
+        typedef t1(int blue);
+        var n;''');
+    addTestSource('''
+        library libA;
+        import "/testB.dart";
+        part "/testA.dart";
+        class A { A({String boo: 'hoo'}) { } }
+        main() {^}
+        var m;''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('B');
+    assertSuggestFunction('bf', 'int',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('n', null,
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunctionTypeAlias('t1', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    // Suggested by ConstructorContributor
+    assertNotSuggested('A');
+    // Suggested by ImportedReferenceContributor
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
new file mode 100644
index 0000000..e5d854d
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -0,0 +1,4279 @@
+// 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 test.services.completion.contributor.dart.local_ref;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LocalReferenceContributorTest);
+}
+
+@reflectiveTest
+class LocalReferenceContributorTest extends DartCompletionContributorTest {
+  CompletionSuggestion assertSuggestLocalVariable(
+      String name, String returnType,
+      {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) {
+    // Local variables should only be suggested by LocalReferenceContributor
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.LOCAL_VARIABLE));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, returnType != null ? returnType : 'dynamic');
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestParameter(String name, String returnType,
+      {int relevance: DART_RELEVANCE_PARAMETER}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.PARAMETER));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType,
+        equals(returnType != null ? returnType : 'dynamic'));
+    return cs;
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new LocalReferenceContributor();
+  }
+
+  test_constructor_parameters_mixed_required_and_named() async {
+    addTestSource('class A {A(x, {int y}) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_constructor_parameters_mixed_required_and_positional() async {
+    addTestSource('class A {A(x, [int y]) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_constructor_parameters_named() async {
+    addTestSource('class A {A({x, int y}) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_constructor_parameters_positional() async {
+    addTestSource('class A {A([x, int y]) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_constructor_parameters_required() async {
+    addTestSource('class A {A(x, int y) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_enum() async {
+    addTestSource('enum E { one, two } main() {^}');
+    await computeSuggestions();
+    assertSuggestEnum('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_enum_deprecated() async {
+    addTestSource('@deprecated enum E { one, two } main() {^}');
+    await computeSuggestions();
+    assertSuggestEnum('E', isDeprecated: true);
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_function_parameters_mixed_required_and_named() async {
+    addTestSource('''
+void m(x, {int y}) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_function_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+void m(x, [int y]) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_named() async {
+    addTestSource('''
+void m({x, int y}) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_function_parameters_none() async {
+    addTestSource('''
+void m() {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_positional() async {
+    addTestSource('''
+void m([x, int y]) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_required() async {
+    addTestSource('''
+void m(x, int y) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_ignore_symbol_being_completed() async {
+    addTestSource('class MyClass { } main(MC^) { }');
+    await computeSuggestions();
+    assertSuggestClass('MyClass');
+    assertNotSuggested('MC');
+  }
+
+  test_inDartDoc_reference3() async {
+    addTestSource('''
+/// The [^]
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertSuggestFunction('main', null,
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+  }
+
+  test_inDartDoc_reference4() async {
+    addTestSource('''
+/// The [m^]
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertSuggestFunction('main', null,
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+  }
+
+  test_InstanceCreationExpression() async {
+    addTestSource('''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }
+main() {new ^ String x = "hello";}''');
+    await computeSuggestions();
+    // Suggested by LocalConstructorContributor
+    assertNoSuggestions();
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    addTestSource('''
+class A {
+  void m(x, {int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+class A {
+  void m(x, [int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_named() async {
+    addTestSource('''
+class A {
+  void m({x, int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_none() async {
+    addTestSource('''
+class A {
+  void m() {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_positional() async {
+    addTestSource('''
+class A {
+  void m([x, int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_required() async {
+    addTestSource('''
+class A {
+  void m(x, int y) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_missing_params_constructor() async {
+    addTestSource('class C1{C1{} main(){C^}}');
+    await computeSuggestions();
+  }
+
+  test_missing_params_function() async {
+    addTestSource('int f1{} main(){f^}');
+    await computeSuggestions();
+  }
+
+  test_missing_params_method() async {
+    addTestSource('class C1{int f1{} main(){f^}}');
+    await computeSuggestions();
+  }
+
+  test_overrides() async {
+    addTestSource('''
+class A {m() {}}
+class B extends A {m() {^}}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('m', 'B', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+  }
+
+  test_prioritization() async {
+    addTestSource('main() {var ab; var _ab; ^}');
+    await computeSuggestions();
+    assertSuggestLocalVariable('ab', null);
+    assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT);
+  }
+
+  test_prioritization_private() async {
+    addTestSource('main() {var ab; var _ab; _^}');
+    await computeSuggestions();
+    assertSuggestLocalVariable('ab', null);
+    assertSuggestLocalVariable('_ab', null);
+  }
+
+  test_prioritization_public() async {
+    addTestSource('main() {var ab; var _ab; a^}');
+    await computeSuggestions();
+    assertSuggestLocalVariable('ab', null);
+    assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT);
+  }
+
+  test_shadowed_name() async {
+    addTestSource('var a; class A { var a; m() { ^ } }');
+    await computeSuggestions();
+    assertSuggestField('a', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+  }
+
+  test_ArgumentList() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_imported_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+expect(arg) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {new A(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+typedef Funct();
+class A { A(Funct f) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {new A(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+expect(arg) { }
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_method() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+class B {
+  expect(arg) { }
+  void foo() {expect(^)}}
+String bar() => true;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_functionalArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar(f()) => true;
+void main() {bar(^);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_methodArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { String bar(f()) => true; }
+void main() {new B().bar(^);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_namedParam() async {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }''');
+    addTestSource('''
+import '/libA.dart'
+String bar() => true;
+void main() {expect(foo: ^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('main');
+  }
+
+  test_AsExpression() async {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('''
+        class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertSuggestClass('A');
+    assertNotSuggested('==');
+  }
+
+  test_AssignmentExpression_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_AssignmentExpression_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'int');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_AssignmentExpression_type() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  ^ b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  ^
+  b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertSuggestLocalVariable('a', 'int');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  int^ b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertSuggestClass('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  i^
+  b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestClass('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertSuggestLocalVariable('a', 'int');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('identical');
+  }
+
+  test_AwaitExpression() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main() async {A a; await ^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'A');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_AwaitExpression2() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+        class A {
+          int x;
+          Future y() async {return 0;}
+          foo() async {await ^ await y();}
+        }
+        ''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestMethod('y', 'A', 'Future',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_BinaryExpression_LHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'int');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+  }
+
+  test_BinaryExpression_RHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'int');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('==');
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    ^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertSuggestClass('X', elemFile: testFile);
+    assertSuggestClass('Z');
+    assertSuggestMethod('a', 'X', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestMethod('b', 'X', 'void',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestFunction('localF', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestLocalVariable('f', null);
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertSuggestFunction('D2', 'Z', relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertSuggestTopLevelVar('T5', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestTopLevelVar('_T6', null, relevance: DART_RELEVANCE_DEFAULT);
+    assertNotSuggested('==');
+    assertSuggestGetter('T7', 'String',
+        relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
+    assertSuggestSetter('T8', relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
+    assertSuggestGetter('clog', 'int',
+        relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
+    assertSuggestSetter('blog', relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    final ^
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertSuggestClass('X');
+    assertSuggestClass('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final2() async {
+    addTestSource('main() {final S^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final3() async {
+    addTestSource('main() {final ^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    final var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertSuggestClass('X');
+    assertSuggestClass('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertSuggestClass('X');
+    assertSuggestClass('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_identifier_partial() async {
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+class D3 { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+Z D2() {int x;}
+class X {a() {var f; {var x;} D^ var r;} void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertSuggestClass('X');
+    assertSuggestClass('Z');
+    assertSuggestMethod('a', 'X', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestMethod('b', 'X', 'void',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestLocalVariable('f', null);
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+
+    // imported elements are portially filtered
+    //assertNotSuggested('A');
+    assertNotSuggested('_B');
+    //assertNotSuggested('C');
+    // hidden element suggested as low relevance
+    assertNotSuggested('D');
+    assertNotSuggested('D1');
+    assertSuggestFunction('D2', 'Z', relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    // unimported elements suggested with low relevance
+    assertNotSuggested('D3');
+    //assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    //assertSuggestLibraryPrefix('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    //assertNotSuggested('Object');
+    //assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    //assertSuggestTopLevelVarGetterSetter('T1', 'String');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    //assertSuggestTopLevelVar('T5', 'int', relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    //assertSuggestTopLevelVar('_T6', null);
+    assertNotSuggested('==');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    resolveSource(
+        '/testB.dart',
+        '''
+lib B;
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }''');
+    addTestSource('''
+import "/testB.dart";
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // TODO (danrubel) prefer fields over getters
+    // If add `get e1;` to interface I
+    // then suggestions include getter e1 rather than field e1
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    //assertNotSuggested('m2');
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    assertNotSuggested('m2');
+  }
+
+  test_Block_local_function() async {
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    p^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('partT8');
+    assertNotSuggested('partBoo');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_unimported() async {
+    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+    addSource(
+        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
+    testFile = '/proj/completionTest.dart';
+    addTestSource('class C {foo(){F^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Foo');
+    // TODO(danrubel) implement
+    assertNotSuggested('Foo2');
+    assertNotSuggested('Future');
+  }
+
+  test_CascadeExpression_selector1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+// looks like a cascade to the parser
+// but the user is trying to get completions for a non-cascade
+main() {A a; a.^.z}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+main() {A a; a..^z}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+main() {A a; a..^ return}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_target() async {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('''
+class A {var b; X _c;}
+class X{}
+main() {A a; a^..b}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertSuggestLocalVariable('a', 'A');
+    assertSuggestClass('A');
+    assertSuggestClass('X');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_CatchClause_onType() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_onType_noBrackets() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A', elemOffset: 6);
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_typed() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('e', 'E');
+    assertSuggestMethod('a', 'A', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_untyped() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('e', null);
+    assertSuggestParameter('s', 'StackTrace');
+    assertSuggestMethod('a', 'A', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+@deprecated class A {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion suggestionA = assertSuggestClass('A',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (suggestionA != null) {
+      expect(suggestionA.element.isDeprecated, isTrue);
+      expect(suggestionA.element.isPrivate, isFalse);
+    }
+    CompletionSuggestion suggestionB = assertSuggestClass('_B');
+    if (suggestionB != null) {
+      expect(suggestionB.element.isDeprecated, isFalse);
+      expect(suggestionB.element.isPrivate, isTrue);
+    }
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ A(){}}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as Soo;
+class A {final S^ A();}
+class _B {}
+A Sew;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('Sew');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('Soo');
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ final foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ var foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_Combinator_hide() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+library libAB;
+part '/partAB.dart';
+class A { }
+class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+part of libAB;
+var T1;
+PB F1() => new PB();
+class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+class C { }
+class D { }''');
+    addTestSource('''
+import "/testAB.dart" hide ^;
+import "/testCD.dart";
+class X {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_Combinator_show() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+library libAB;
+part '/partAB.dart';
+class A { }
+class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+part of libAB;
+var T1;
+PB F1() => new PB();
+typedef PB2 F2(int blat);
+class Clz = Object with Object;
+class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+class C { }
+class D { }''');
+    addTestSource('''
+import "/testAB.dart" show ^;
+import "/testCD.dart";
+class X {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_ConditionalExpression_elseExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_elseExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertSuggestLocalVariable('f', null);
+    assertSuggestMethod('foo', 'C', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('C');
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_partial_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T^}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_partial_thenExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? ^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertSuggestLocalVariable('f', null);
+    assertSuggestMethod('foo', 'C', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('C');
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T^ : c}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+var m;
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+var m;
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('fromCharCodes');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+int T1;
+F1() { }
+class X {factory X.c(); factory X._d(); z() {}}
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_DefaultFormalParameter_named_expression() async {
+    // DefaultFormalParameter FormalParameterList MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {a(blat: ^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestFunction('foo', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestMethod('a', 'A', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ExpressionStatement_identifier() async {
+    // SimpleIdentifier  ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+_B F1() { }
+class A {int x;}
+class _B { }''');
+    addTestSource('''
+import "/testA.dart";
+typedef int F2(int blat);
+class Clz = Object with Object;
+class C {foo(){^} void bar() {}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertSuggestClass('C');
+    assertSuggestMethod('foo', 'C', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestMethod('bar', 'C', 'void',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestFunctionTypeAlias('F2', 'int');
+    assertSuggestClassTypeAlias('Clz');
+    assertSuggestClass('C');
+    assertNotSuggested('x');
+    assertNotSuggested('_B');
+  }
+
+  test_ExpressionStatement_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        B T1;
+        class B{}''');
+    addTestSource('''
+        import "/testA.dart";
+        class C {a() {C ^}}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_typed() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {A ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_var() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {var ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldFormalParameter_in_non_constructor() async {
+    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
+    addTestSource('class A {B(this.^foo) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 3);
+    assertNoSuggestions();
+  }
+
+  test_ForEachStatement_body_typed() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('args', null);
+    assertSuggestLocalVariable('foo', 'int');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_body_untyped() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('args', null);
+    assertSuggestLocalVariable('foo', null);
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_iterable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (int foo in ^) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('args', null);
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_loopVariable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_FormalParameterList() async {
+    // FormalParameterList MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {a(^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertSuggestClass('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ForEachStatement() async {
+    // SimpleIdentifier  ForEachStatement
+    addTestSource('main() {List<int> values; for (int index in ^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('values', 'List');
+    assertNotSuggested('index');
+  }
+
+  test_ForEachStatement2() async {
+    // SimpleIdentifier  ForEachStatement
+    addTestSource('main() {List<int> values; for (int index in i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('values', 'List');
+    assertNotSuggested('index');
+  }
+
+  test_ForEachStatement3() async {
+    // SimpleIdentifier ParenthesizedExpression  ForEachStatement
+    addTestSource('main() {List<int> values; for (int index in (i^))}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('values', 'List');
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_body() async {
+    // Block  ForStatement
+    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('i', 'int');
+    assertNotSuggested('Object');
+  }
+
+  test_ForStatement_condition() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('index', 'int');
+  }
+
+  test_ForStatement_initializer() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'List');
+    assertNotSuggested('Object');
+    assertNotSuggested('int');
+  }
+
+  test_ForStatement_updaters() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('index', 'int');
+  }
+
+  test_ForStatement_updaters_prefix_expression() async {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('''
+void bar() { }
+main() {for (int index = 0; index < 10; ++i^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('index', 'int');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('bar');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+/* */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment2() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+/** */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment3() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+/// some dartdoc
+class C2 { }
+^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionExpression_body_function() async {
+    // Block  BlockFunctionBody  FunctionExpression
+    addTestSource('''
+        void bar() { }
+        String foo(List args) {x.then((R b) {^});}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    var f = assertSuggestFunction('foo', 'String',
+        isDeprecated: false, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    if (f != null) {
+      expect(f.element.isPrivate, isFalse);
+    }
+    assertSuggestFunction('bar', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestParameter('args', 'List');
+    assertSuggestParameter('b', 'R');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (true) ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_DEFAULT);
+    assertNotSuggested('Object');
+    assertSuggestClass('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_condition() async {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', null);
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement_empty() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (^) something}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_DEFAULT);
+    assertNotSuggested('Object');
+    assertSuggestClass('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_empty_private() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (_^) something}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertNotSuggested('Object');
+    assertSuggestClass('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_invocation() async {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+main() {var a; if (a.^) something}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('toString');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_ImportDirective_dart() async {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+import "dart^";
+main() {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_IndexExpression() async {
+    // ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} f[^]}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertSuggestLocalVariable('f', null);
+    assertSuggestMethod('foo', 'C', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('C');
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_IndexExpression2() async {
+    // SimpleIdentifier IndexExpression ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} f[T^]}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_InstanceCreationExpression_imported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {A(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+import "dart:async";
+int T2;
+F2() { }
+class B {B(this.x, [String boo]) { } int x;}
+class C {foo(){var f; {var x;} new ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('Future');
+    assertNotSuggested('A');
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('B');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('foo');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_InstanceCreationExpression_unimported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){new F^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Future');
+    assertNotSuggested('Foo');
+  }
+
+  test_InterpolationExpression() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+main() {String name; print("hello \$^");}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertSuggestLocalVariable('name', 'String');
+  }
+
+  test_InterpolationExpression_block() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+main() {String name; print("hello \${^}");}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertSuggestLocalVariable('name', 'String');
+  }
+
+  test_InterpolationExpression_block2() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+    await computeSuggestions();
+
+    assertSuggestLocalVariable('name', 'String');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+  }
+
+  test_InterpolationExpression_prefix_selector() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('length');
+    assertNotSuggested('name');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_InterpolationExpression_prefix_selector2() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \$name.^");}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_InterpolationExpression_prefix_target() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+    await computeSuggestions();
+
+    assertSuggestLocalVariable('name', 'String');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('length');
+  }
+
+  test_IsExpression() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+main() {var x; if (x is ^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertSuggestClass('Y');
+    assertNotSuggested('x');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+  }
+
+  test_IsExpression_target() async {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {int x; int y() => 0;}
+main(){var a; if (^ is A)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', null);
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestFunction('foo', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('bar');
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (a is ^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (a is Obj^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_keyword() async {
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int newT1;
+int T1;
+nowIsIt() { }
+class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+String newer() {}
+var m;
+main() {new^ X.c();}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    // Imported suggestion are filtered by 1st character
+    assertNotSuggested('nowIsIt');
+    assertNotSuggested('T1');
+    assertNotSuggested('newT1');
+    assertNotSuggested('z');
+    assertSuggestTopLevelVar('m', 'dynamic',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunction('newer', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+  }
+
+  test_Literal_list() async {
+    // ']'  ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([^]);}');
+    await computeSuggestions();
+
+    assertSuggestLocalVariable('Some', null);
+    assertNotSuggested('String');
+  }
+
+  test_Literal_list2() async {
+    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([S^]);}');
+    await computeSuggestions();
+
+    assertSuggestLocalVariable('Some', null);
+    assertNotSuggested('String');
+  }
+
+  test_Literal_string() async {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_MapLiteralEntry() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {^''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+  }
+
+  test_MapLiteralEntry1() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {T^''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+  }
+
+  test_MapLiteralEntry2() async {
+    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {7:T^};''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+  }
+
+  test_MethodDeclaration_body_getters() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion methodA = assertSuggestMethod('a', 'A', 'Z',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    if (methodA != null) {
+      expect(methodA.element.isDeprecated, isFalse);
+      expect(methodA.element.isPrivate, isFalse);
+    }
+    CompletionSuggestion getterF = assertSuggestGetter('f', 'X',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (getterF != null) {
+      expect(getterF.element.isDeprecated, isTrue);
+      expect(getterF.element.isPrivate, isFalse);
+    }
+    CompletionSuggestion getterG =
+        assertSuggestGetter('_g', null, relevance: DART_RELEVANCE_DEFAULT);
+    if (getterG != null) {
+      expect(getterG.element.isDeprecated, isFalse);
+      expect(getterG.element.isPrivate, isTrue);
+    }
+  }
+
+  test_MethodDeclaration_body_static() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testC.dart',
+        '''
+class C {
+  c1() {}
+  var c2;
+  static c3() {}
+  static var c4;}''');
+    addTestSource('''
+import "/testC.dart";
+class B extends C {
+  b1() {}
+  var b2;
+  static b3() {}
+  static var b4;}
+class A extends B {
+  a1() {}
+  var a2;
+  static a3() {}
+  static var a4;
+  static a() {^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    assertSuggestMethod('a3', 'A', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestField('a4', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    assertNotSuggested('b3');
+    assertNotSuggested('b4');
+    assertNotSuggested('c1');
+    assertNotSuggested('c2');
+    assertNotSuggested('c3');
+    assertNotSuggested('c4');
+  }
+
+  test_MethodDeclaration_members() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion methodA =
+        assertSuggestMethod('_a', 'A', 'Z', relevance: DART_RELEVANCE_DEFAULT);
+    if (methodA != null) {
+      expect(methodA.element.isDeprecated, isFalse);
+      expect(methodA.element.isPrivate, isTrue);
+    }
+    CompletionSuggestion getterF = assertSuggestField('f', 'X',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (getterF != null) {
+      expect(getterF.element.isDeprecated, isTrue);
+      expect(getterF.element.isPrivate, isFalse);
+      expect(getterF.element.parameters, isNull);
+    }
+    // If user did not type '_' then relevance of private members is not raised
+    CompletionSuggestion getterG =
+        assertSuggestField('_g', null, relevance: DART_RELEVANCE_DEFAULT);
+    if (getterG != null) {
+      expect(getterG.element.isDeprecated, isFalse);
+      expect(getterG.element.isPrivate, isTrue);
+      expect(getterF.element.parameters, isNull);
+    }
+    assertNotSuggested('bool');
+  }
+
+  test_MethodDeclaration_members_private() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {_^} var _g;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    CompletionSuggestion methodA = assertSuggestMethod('_a', 'A', 'Z',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    if (methodA != null) {
+      expect(methodA.element.isDeprecated, isFalse);
+      expect(methodA.element.isPrivate, isTrue);
+    }
+    CompletionSuggestion getterF = assertSuggestField('f', 'X',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (getterF != null) {
+      expect(getterF.element.isDeprecated, isTrue);
+      expect(getterF.element.isPrivate, isFalse);
+      expect(getterF.element.parameters, isNull);
+    }
+    // If user prefixed completion with '_' then suggestion of private members
+    // should be the same as public members
+    CompletionSuggestion getterG =
+        assertSuggestField('_g', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    if (getterG != null) {
+      expect(getterG.element.isDeprecated, isFalse);
+      expect(getterG.element.isPrivate, isTrue);
+      expect(getterF.element.parameters, isNull);
+    }
+    assertNotSuggested('bool');
+  }
+
+  test_MethodDeclaration_parameters_named() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion methodA = assertSuggestMethod('a', 'A', 'Z',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (methodA != null) {
+      expect(methodA.element.isDeprecated, isTrue);
+      expect(methodA.element.isPrivate, isFalse);
+    }
+    assertSuggestParameter('x', 'X');
+    assertSuggestParameter('y', null);
+    assertSuggestParameter('b', null);
+    assertNotSuggested('int');
+    assertNotSuggested('_');
+  }
+
+  test_MethodDeclaration_parameters_positional() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {Z a(X x, [int y=1]) {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestFunction('foo', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestFunction('bar', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestMethod('a', 'A', 'Z', relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestParameter('x', 'X');
+    assertSuggestParameter('y', 'int');
+    assertNotSuggested('String');
+  }
+
+  test_MethodDeclaration_returnType() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {/* */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {/** */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment3() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {
+  /// some dartdoc
+  ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodInvocation_no_semicolon() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {x.^ m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_new_instance() async {
+    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
+    await computeSuggestions();
+
+    assertNotSuggested('nextBool');
+    assertNotSuggested('nextDouble');
+    assertNotSuggested('nextInt');
+    assertNotSuggested('Random');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+  }
+
+  test_parameterName_excludeTypes() async {
+    addTestSource('m(int ^) {}');
+    await computeSuggestions();
+
+    assertNotSuggested('int');
+    assertNotSuggested('bool');
+  }
+
+  test_partFile_TypeName() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+library libA;
+import "/testB.dart";
+part "$testFile";
+class A { }
+var m;''');
+    addTestSource('''
+part of libA;
+class B { factory B.bar(int x) => null; }
+main() {new ^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('B.bar');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+part of libA;
+class B { }''');
+    addTestSource('''
+library libA;
+import "/testB.dart";
+part "/testA.dart";
+class A { A({String boo: 'hoo'}) { } }
+main() {new ^}
+var m;''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('B');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class I {
+  static const scI = 'boo';
+  X get f => new A();
+  get _g => new A();}
+class B implements I {
+  static const int scB = 12;
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    addTestSource('''
+import "/testB.dart";
+class A extends B {
+  static const String scA = 'foo';
+  w() { }}
+main() {A.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('scA');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_imported() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  static const int sc = 12;
+  @deprecated var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    addTestSource('''
+import "/testB.dart";
+main() {A a; a.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_local() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+main() {A a; a.^}
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  static const int sc = 12;
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+main() {b.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+foo(b.^ f) {}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+foo(b.^) {}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class _W {M y; var _z;}
+class X extends _W {}
+class M{}''');
+    addTestSource('''
+import "/testB.dart";
+foo(X x) {x.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('y');
+    assertNotSuggested('_z');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+class A {static int bar = 10;}
+_B() {}''');
+    addTestSource('''
+import "/testA.dart";
+class X {foo(){A^.bar}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertSuggestClass('X');
+    assertSuggestMethod('foo', 'X', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertNotSuggested('bar');
+    assertNotSuggested('_B');
+  }
+
+  test_PrefixedIdentifier_propertyAccess() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_propertyAccess_newStmt() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_const() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_field() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_function() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_typed() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {String g; g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_method() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_localVariableDeclarationName() async {
+    addTestSource('main() {String m^}');
+    await computeSuggestions();
+
+    assertNotSuggested('main');
+    assertNotSuggested('min');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f(String g) {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PropertyAccess_expression() async {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 8);
+    assertNotSuggested('length');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PropertyAccess_noTarget() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){.^}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_noTarget2() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('main() {.^}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_selector() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEven');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_SwitchStatement_c() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_SwitchStatement_case() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
+    await computeSuggestions();
+
+    assertSuggestClass('A');
+    assertSuggestMethod('g', 'A', 'String',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestLocalVariable('t', null);
+    assertNotSuggested('String');
+  }
+
+  test_SwitchStatement_empty() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {^}}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_ThisExpression_block() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A() {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {this.^ m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A() {this.^}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.^) {}
+  A.z() {}
+  var b; X _c; static sb;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('sb');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param2() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.b^) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param3() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.^b) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param4() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.b, this.^) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_TypeArgumentList() async {
+    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+class C1 {int x;}
+F1() => 0;
+typedef String T1(int blat);''');
+    addTestSource('''
+import "/testA.dart";'
+class C2 {int x;}
+F2() => 0;
+typedef int T2(int blat);
+class C<E> {}
+main() { C<^> c; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('C1');
+    assertNotSuggested('T1');
+    assertSuggestClass('C2');
+    assertSuggestFunctionTypeAlias('T2', 'int');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+  }
+
+  test_TypeArgumentList2() async {
+    // TypeName  TypeArgumentList  TypeName
+    addSource(
+        '/testA.dart',
+        '''
+class C1 {int x;}
+F1() => 0;
+typedef String T1(int blat);''');
+    addTestSource('''
+import "/testA.dart";'
+class C2 {int x;}
+F2() => 0;
+typedef int T2(int blat);
+class C<E> {}
+main() { C<C^> c; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('C1');
+    assertSuggestClass('C2');
+  }
+
+  test_VariableDeclaration_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+main() {var ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_VariableDeclarationList_final() async {
+    // VariableDeclarationList  VariableDeclarationStatement  Block
+    addTestSource('main() {final ^} class C { }');
+    await computeSuggestions();
+
+    assertNotSuggested('Object');
+    assertSuggestClass('C');
+    assertNotSuggested('==');
+  }
+
+  test_VariableDeclarationStatement_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+class C {bar(){var f; {var x;} var e = ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('_B');
+    assertSuggestClass('Y');
+    assertSuggestClass('C');
+    assertSuggestLocalVariable('f', null);
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo1() { }
+void bar1() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+foo2() { }
+void bar2() { }
+class Y {Y.c(); Y._d(); z() {}}
+class C {bar(){var f; {var x;} var e = ^ var g}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('foo1');
+    assertNotSuggested('bar1');
+    assertSuggestFunction('foo2', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('bar2');
+    assertNotSuggested('_B');
+    assertSuggestClass('Y');
+    assertSuggestClass('C');
+    assertSuggestLocalVariable('f', null);
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
new file mode 100644
index 0000000..0ac517b
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
@@ -0,0 +1,182 @@
+// 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 test.services.completion.contributor.dart.named_constructor;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(NamedConstructorContributorTest);
+}
+
+@reflectiveTest
+class NamedConstructorContributorTest extends DartCompletionContributorTest {
+  CompletionSuggestion assertSuggestNamedConstructor(
+      String name, String returnType,
+      [int relevance = DART_RELEVANCE_DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
+    CompletionSuggestion cs =
+        assertSuggest(name, csKind: kind, relevance: relevance);
+    Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(ElementKind.CONSTRUCTOR));
+    expect(element.name, equals(name));
+    String param = element.parameters;
+    expect(param, isNotNull);
+    expect(param[0], equals('('));
+    expect(param[param.length - 1], equals(')'));
+    expect(element.returnType, equals(returnType));
+    assertHasParameterInfo(cs);
+    return cs;
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new NamedConstructorContributor();
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    Source libSource = addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    // Assume that imported libraries are resolved
+    await resolveLibraryUnit(libSource);
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedClass_unresolved() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    // Assume that imported libraries are NOT resolved
+    //await resolveLibraryUnit(libSource);
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    Source libSource = addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    // Assume that imported libraries are resolved
+    await resolveLibraryUnit(libSource);
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    assertSuggestNamedConstructor('fromCharCodes', 'String');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertSuggestNamedConstructor('_d', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertSuggestNamedConstructor('_d', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/optype_test.dart b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
new file mode 100644
index 0000000..9ed569e
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
@@ -0,0 +1,1484 @@
+// 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 test.services.completion.contributor.dart.optype;
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/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:unittest/unittest.dart';
+
+import '../../../abstract_context.dart';
+import '../../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(OpTypeTest);
+}
+
+@reflectiveTest
+class OpTypeTest {
+  OpType visitor;
+
+  void addTestSource(String content, {bool resolved: false}) {
+    int offset = content.indexOf('^');
+    expect(offset, isNot(equals(-1)), reason: 'missing ^');
+    int nextOffset = content.indexOf('^', offset + 1);
+    expect(nextOffset, equals(-1), reason: 'too many ^');
+    content = content.substring(0, offset) + content.substring(offset + 1);
+    Source source = new _TestSource('/completionTest.dart');
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    context.sourceFactory =
+        new SourceFactory([AbstractContextTest.SDK_RESOLVER]);
+    context.setContents(source, content);
+    CompilationUnit unit = resolved
+        ? context.resolveCompilationUnit2(source, source)
+        : context.parseCompilationUnit(source);
+    CompletionTarget completionTarget =
+        new CompletionTarget.forOffset(unit, offset);
+    visitor = new OpType.forCompletion(completionTarget, offset);
+  }
+
+  void assertOpType(
+      {bool caseLabel: false,
+      bool constructors: false,
+      bool prefixed: false,
+      bool returnValue: false,
+      bool statementLabel: false,
+      bool staticMethodBody: false,
+      bool typeNames: false,
+      bool voidReturn: false,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) {
+    expect(visitor.includeCaseLabelSuggestions, caseLabel, reason: 'caseLabel');
+    expect(visitor.includeConstructorSuggestions, constructors,
+        reason: 'constructors');
+    expect(visitor.includeReturnValueSuggestions, returnValue,
+        reason: 'returnValue');
+    expect(visitor.includeStatementLabelSuggestions, statementLabel,
+        reason: 'statementLabel');
+    expect(visitor.includeTypeNameSuggestions, typeNames, reason: 'typeNames');
+    expect(visitor.includeVoidReturnSuggestions, voidReturn,
+        reason: 'voidReturn');
+    expect(visitor.inStaticMethodBody, staticMethodBody,
+        reason: 'staticMethodBody');
+    expect(visitor.isPrefixed, prefixed, reason: 'prefixed');
+    expect(visitor.suggestKind, kind, reason: 'suggestion kind');
+  }
+
+  void processRequiredPlugins() {
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
+  }
+
+  void setUp() {
+    processRequiredPlugins();
+  }
+
+  test_Annotation() {
+    // SimpleIdentifier  Annotation  MethodDeclaration  ClassDeclaration
+    addTestSource('class C { @A^ }');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ArgumentList() {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('void main() {expect(^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ArgumentList_namedParam() {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addTestSource('void main() {expect(foo: ^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ArgumentList_prefixedIdentifier() {
+    // SimpleIdentifier  PrefixedIdentifier  ArgumentList
+    addTestSource('void main() {expect(aa.^)}');
+    assertOpType(returnValue: true, typeNames: true, prefixed: true);
+  }
+
+  test_AsExpression() {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('class A {var b; X _c; foo() {var a; (a as ^).foo();}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Assert() {
+    addTestSource('main() {assert(^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AssignmentExpression_name() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+    assertOpType();
+  }
+
+  test_AssignmentExpression_RHS() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AssignmentExpression_type() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      main() {
+        int a;
+        ^ b = 1;}''');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_AssignmentExpression_type_newline() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      main() {
+        int a;
+        ^
+        b = 1;}''');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_AssignmentExpression_type_partial() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      main() {
+        int a;
+        int^ b = 1;}''');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_AssignmentExpression_type_partial_newline() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      main() {
+        int a;
+        i^
+        b = 1;}''');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_AwaitExpression() {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('main() async {A a; await ^}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression2() {
+    addTestSource('main() async {A a; await c^ await}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression3() {
+    addTestSource('main() async {A a; await ^ await foo;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression4() {
+    addTestSource('main() async {A a; await ^ await bar();}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression_assignment() {
+    addTestSource('main() async {A a; int x = await ^}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression_assignment2() {
+    addTestSource('main() async {A a; int x = await ^ await foo;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression_assignment3() {
+    addTestSource('main() async {A a; int x = await v^ int y = await foo;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_BinaryExpression_LHS() {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_BinaryExpression_RHS() {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_BinaryExpression_RHS2() {
+    // SimpleIdentifier  BinaryExpression
+    addTestSource('main() {if (c < ^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_Block() {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+      class X {
+        a() {
+          var f;
+          localF(int arg1) { }
+          {var x;}
+          ^ var r;
+        }
+      }''');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_Block_empty() {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('class A extends E implements I with M {a() {^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_Block_final() {
+    addTestSource('main() {final ^}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Block_final2() {
+    addTestSource('main() {final S^ v;}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Block_final3() {
+    addTestSource('main() {final ^ v;}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Block_final_final() {
+    addTestSource('main() {final ^ final S x;}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Block_final_final2() {
+    addTestSource('main() {final S^ final S x;}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Block_identifier_partial() {
+    addTestSource('class X {a() {var f; {var x;} D^ var r;} void b() { }}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_Block_keyword() {
+    addTestSource('class C { static C get instance => null; } main() {C.in^}');
+    assertOpType(
+        prefixed: true, returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_Block_static() {
+    addTestSource('class A {static foo() {^}}');
+    assertOpType(
+        returnValue: true,
+        typeNames: true,
+        staticMethodBody: true,
+        voidReturn: true);
+  }
+
+  test_Break_after_label() {
+    addTestSource('main() { foo: while (true) { break foo ^ ; } }');
+    assertOpType(/* No valid completions */);
+  }
+
+  test_Break_before_label() {
+    addTestSource('main() { foo: while (true) { break ^ foo; } }');
+    assertOpType(statementLabel: true);
+  }
+
+  test_Break_no_label() {
+    addTestSource('main() { foo: while (true) { break ^; } }');
+    assertOpType(statementLabel: true);
+  }
+
+  test_CascadeExpression_selector1() {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addTestSource('''
+      // looks like a cascade to the parser
+      // but the user is trying to get completions for a non-cascade
+      main() {A a; a.^.z}''');
+    assertOpType(
+        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
+  }
+
+  test_CascadeExpression_selector2() {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addTestSource('main() {A a; a..^z}');
+    assertOpType(returnValue: true, voidReturn: true, prefixed: true);
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addTestSource('main() {A a; a..^ return}');
+    assertOpType(returnValue: true, voidReturn: true, prefixed: true);
+  }
+
+  test_CascadeExpression_target() {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('main() {A a; a^..b}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_CatchClause_onType() {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+    assertOpType(typeNames: true);
+  }
+
+  test_CatchClause_onType_noBrackets() {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+    assertOpType(typeNames: true);
+  }
+
+  test_CatchClause_typed() {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_CatchClause_untyped() {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ClassDeclaration_body() {
+    // ClassDeclaration  CompilationUnit
+    addTestSource('@deprecated class A {^}');
+    assertOpType(typeNames: true);
+  }
+
+  test_ClassDeclaration_body2() {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
+    addTestSource('@deprecated class A {^mth() {}}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Combinator_hide() {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addTestSource('''
+      import "/testAB.dart" hide ^;
+      class X {}''');
+    assertOpType();
+  }
+
+  test_Combinator_show() {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addTestSource('''
+      import "/testAB.dart" show ^;
+      import "/testCD.dart";
+      class X {}''');
+    assertOpType();
+  }
+
+  test_CommentReference() {
+    // SimpleIdentifier  CommentReference  Comment  MethodDeclaration
+    addTestSource('class A {/** [^] */ mth() {}');
+    assertOpType(
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true,
+        kind: CompletionSuggestionKind.IDENTIFIER);
+  }
+
+  test_ConditionalExpression_elseExpression() {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addTestSource('class C {foo(){var f; {var x;} return a ? T1 : T^}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ConditionalExpression_elseExpression_empty() {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addTestSource('class C {foo(){var f; {var x;} return a ? T1 : ^}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ConditionalExpression_partial_thenExpression() {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addTestSource('class C {foo(){var f; {var x;} return a ? T^}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ConditionalExpression_partial_thenExpression_empty() {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addTestSource('class C {foo(){var f; {var x;} return a ? ^}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ConditionalExpression_thenExpression() {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addTestSource('class C {foo(){var f; {var x;} return a ? T^ : c}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ConstructorName() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new X.^}');
+    assertOpType(constructors: true, prefixed: true);
+  }
+
+  test_ConstructorName_name_resolved() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new Str^ing.fromCharCodes([]);}', resolved: true);
+    assertOpType(constructors: true);
+  }
+
+  test_ConstructorName_resolved() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new String.fr^omCharCodes([]);}', resolved: true);
+    assertOpType(constructors: true, prefixed: true);
+  }
+
+  test_ConstructorName_unresolved() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new String.fr^omCharCodes([]);}');
+    assertOpType(constructors: true, prefixed: true);
+  }
+
+  test_Continue_after_label() {
+    addTestSource('main() { foo: while (true) { continue foo ^ ; } }');
+    assertOpType(/* No valid completions */);
+  }
+
+  test_Continue_before_label() {
+    addTestSource('main() { foo: while (true) { continue ^ foo; } }');
+    assertOpType(statementLabel: true, caseLabel: true);
+  }
+
+  test_Continue_no_label() {
+    addTestSource('main() { foo: while (true) { continue ^; } }');
+    assertOpType(statementLabel: true, caseLabel: true);
+  }
+
+  test_DefaultFormalParameter_named_expression() {
+    // DefaultFormalParameter FormalParameterList MethodDeclaration
+    addTestSource('class A {a(blat: ^) { }}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_DoStatement() {
+    // SimpleIdentifier  DoStatement  Block
+    addTestSource('main() {do{} while(^x);}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ExpressionFunctionBody() {
+    // SimpleIdentifier  ExpressionFunctionBody  FunctionExpression
+    addTestSource('m(){[1].forEach((x)=>^x);}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ExpressionStatement() {
+    // ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('n(){f(3);^}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ExpressionStatement_name() {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class C {a() {C ^}}');
+    assertOpType();
+  }
+
+  test_ExtendsClause() {
+    // ExtendsClause  ClassDeclaration
+    addTestSource('class x extends ^\n{}');
+    assertOpType(typeNames: true);
+  }
+
+  test_FieldDeclaration_name_typed() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addTestSource('class C {A ^}');
+    assertOpType();
+  }
+
+  test_FieldDeclaration_name_var() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addTestSource('class C {var ^}');
+    assertOpType();
+  }
+
+  test_ForEachStatement() {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main() {for(z in ^zs) {}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ForEachStatement_body_typed() {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ForEachStatement_body_untyped() {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ForEachStatement_iterable() {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (int foo in ^) {}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ForEachStatement_loopVariable() {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+    assertOpType(typeNames: true);
+  }
+
+  test_ForEachStatement_loopVariable_name() {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (String ^ in args) {}}');
+    assertOpType();
+  }
+
+  test_ForEachStatement_loopVariable_name2() {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (String f^ in args) {}}');
+    assertOpType();
+  }
+
+  test_ForEachStatement_loopVariable_type() {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+    assertOpType(typeNames: true);
+  }
+
+  test_ForEachStatement_loopVariable_type2() {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+    assertOpType(typeNames: true);
+  }
+
+  test_FormalParameter_partialType() {
+    // FormalParameterList MethodDeclaration
+    addTestSource('class A {a(b.^ f) { }}');
+    assertOpType(returnValue: true, typeNames: true, prefixed: true);
+  }
+
+  test_FormalParameter_partialType2() {
+    // FormalParameterList MethodDeclaration
+    addTestSource('class A {a(b.z^ f) { }}');
+    assertOpType(returnValue: true, typeNames: true, prefixed: true);
+  }
+
+  test_FormalParameter_partialType3() {
+    // FormalParameterList MethodDeclaration
+    addTestSource('class A {a(b.^) { }}');
+    assertOpType(returnValue: true, typeNames: true, prefixed: true);
+  }
+
+  test_FormalParameterList() {
+    // FormalParameterList MethodDeclaration
+    addTestSource('class A {a(^) { }}');
+    assertOpType(typeNames: true);
+  }
+
+  test_ForStatement_condition() {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+    // TODO (danrubel) may want to exclude methods/functions with void return
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ForStatement_initializer() {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+    // TODO (danrubel) may want to exclude methods/functions with void return
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ForStatement_updaters() {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+    // TODO (danrubel) may want to exclude methods/functions with void return
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ForStatement_updaters_prefix_expression() {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; ++i^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_FunctionDeclaration1() {
+    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
+    addTestSource('const ^Fara();');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration2() {
+    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
+    addTestSource('const F^ara();');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration_inLineComment() {
+    // Comment  CompilationUnit
+    addTestSource('''
+      // normal comment ^
+      zoo(z) { } String name;''');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_inLineComment2() {
+    // Comment  CompilationUnit
+    addTestSource('''
+      // normal ^comment
+      zoo(z) { } String name;''');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_inLineComment3() {
+    // Comment  CompilationUnit
+    addTestSource('''
+      // normal comment ^
+      // normal comment 2
+      zoo(z) { } String name;''');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_inLineComment4() {
+    // Comment  CompilationUnit
+    addTestSource('''
+      // normal comment
+      // normal comment 2^
+      zoo(z) { } String name;''');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_inLineDocComment() {
+    // Comment  FunctionDeclaration  CompilationUnit
+    addTestSource('''
+      /// some dartdoc ^
+      zoo(z) { } String name;''');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_inLineDocComment2() {
+    // Comment  FunctionDeclaration  CompilationUnit
+    addTestSource('''
+      /// some ^dartdoc
+      zoo(z) { } String name;''');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_inStarComment() {
+    // Comment  CompilationUnit
+    addTestSource('/* ^ */ zoo(z) {} String name;');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_inStarComment2() {
+    // Comment  CompilationUnit
+    addTestSource('/*  *^/ zoo(z) {} String name;');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_inStarDocComment() {
+    // Comment  FunctionDeclaration  CompilationUnit
+    addTestSource('/** ^ */ zoo(z) { } String name; ');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_inStarDocComment2() {
+    // Comment  FunctionDeclaration  CompilationUnit
+    addTestSource('/**  *^/ zoo(z) { } String name;');
+    assertOpType();
+  }
+
+  test_FunctionDeclaration_returnType() {
+    // CompilationUnit
+    addTestSource('^ zoo(z) { } String name;');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration_returnType_afterLineComment() {
+    // FunctionDeclaration  CompilationUnit
+    addTestSource('''
+      // normal comment
+      ^ zoo(z) {} String name;''');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration_returnType_afterLineComment2() {
+    // FunctionDeclaration  CompilationUnit
+    // TOD(danrubel) left align all test source
+    addTestSource('''
+// normal comment
+^ zoo(z) {} String name;''');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration_returnType_afterLineDocComment() {
+    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
+    addTestSource('''
+      /// some dartdoc
+      ^ zoo(z) { } String name;''');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration_returnType_afterLineDocComment2() {
+    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
+    addTestSource('''
+/// some dartdoc
+^ zoo(z) { } String name;''');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration_returnType_afterStarComment() {
+    // CompilationUnit
+    addTestSource('/* */ ^ zoo(z) { } String name;');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration_returnType_afterStarComment2() {
+    // CompilationUnit
+    addTestSource('/* */^ zoo(z) { } String name;');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration_returnType_afterStarDocComment() {
+    // FunctionDeclaration  CompilationUnit
+    addTestSource('/** */ ^ zoo(z) { } String name;');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionDeclaration_returnType_afterStarDocComment2() {
+    // FunctionDeclaration  CompilationUnit
+    addTestSource('/** */^ zoo(z) { } String name;');
+    assertOpType(typeNames: true);
+  }
+
+  test_FunctionExpression() {
+    // BlockFunctionBody  FunctionExpression  FunctionDeclaration
+    addTestSource('main()^ { int b = 2; b++; b. }');
+    assertOpType();
+  }
+
+  test_FunctionExpressionInvocation() {
+    // ArgumentList  FunctionExpressionInvocation  ExpressionStatement
+    addTestSource('main() { ((x) => x + 7)^(2) }');
+    assertOpType();
+  }
+
+  test_FunctionTypeAlias() {
+    // SimpleIdentifier  FunctionTypeAlias  CompilationUnit
+    addTestSource('typedef n^ ;');
+    assertOpType(typeNames: true);
+  }
+
+  test_IfStatement() {
+    // EmptyStatement  IfStatement  Block  BlockFunctionBody
+    addTestSource('main(){var a; if (true) ^}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_IfStatement_condition() {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('main(){var a; if (^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_IfStatement_empty() {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('class A {foo() {A a; if (^) something}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_IfStatement_invocation() {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('main() {var a; if (a.^) something}');
+    assertOpType(returnValue: true, typeNames: true, prefixed: true);
+  }
+
+  test_ImplementsClause() {
+    // ImplementsClause  ClassDeclaration
+    addTestSource('class x implements ^\n{}');
+    assertOpType(typeNames: true);
+  }
+
+  test_ImportDirective_dart() {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+      import "dart^";
+      main() {}''');
+    assertOpType();
+  }
+
+  test_IndexExpression() {
+    addTestSource('class C {foo(){var f; {var x;} f[^]}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_IndexExpression2() {
+    addTestSource('class C {foo(){var f; {var x;} f[T^]}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_InstanceCreationExpression() {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addTestSource('class C {foo(){var f; {var x;} new ^}}');
+    assertOpType(constructors: true);
+  }
+
+  test_InstanceCreationExpression_keyword() {
+    // InstanceCreationExpression  ExpressionStatement  Block
+    addTestSource('class C {foo(){var f; {var x;} new^ }}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_InstanceCreationExpression_keyword2() {
+    // InstanceCreationExpression  ExpressionStatement  Block
+    addTestSource('class C {foo(){var f; {var x;} new^ C();}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_InstanceCreationExpression_trailingStmt() {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addTestSource('class C {foo(){var f; {var x;} new ^ int x = 7;}}');
+    assertOpType(constructors: true);
+  }
+
+  test_InterpolationExpression() {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \$^");}');
+    assertOpType(returnValue: true);
+  }
+
+  test_InterpolationExpression_block() {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_InterpolationExpression_prefix_selector() {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+    assertOpType(returnValue: true, typeNames: true, prefixed: true);
+  }
+
+  test_InterpolationExpression_prefix_target() {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_IsExpression() {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('main() {var x; if (x is ^) { }}');
+    assertOpType(typeNames: true);
+  }
+
+  test_IsExpression_target() {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('main(){var a; if (^ is A)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_IsExpression_type_partial() {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('main(){var a; if (a is Obj^)}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Literal_list() {
+    // ']'  ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([^]);}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_Literal_list2() {
+    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([S^]);}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_Literal_string() {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+    assertOpType();
+  }
+
+  test_MapLiteralEntry() {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addTestSource('foo = {^');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_MapLiteralEntry1() {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addTestSource('foo = {T^');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_MapLiteralEntry2() {
+    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
+    addTestSource('foo = {7:T^};');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_MethodDeclaration1() {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
+    addTestSource('class Bar {const ^Fara();}');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration2() {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
+    addTestSource('class Bar {const F^ara();}');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration_inLineComment() {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        // normal comment ^
+        zoo(z) { } String name; }''');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_inLineComment2() {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        // normal ^comment
+        zoo(z) { } String name; }''');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_inLineComment3() {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        // normal comment ^
+        // normal comment 2
+        zoo(z) { } String name; }''');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_inLineComment4() {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        // normal comment
+        // normal comment 2^
+        zoo(z) { } String name; }''');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_inLineDocComment() {
+    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        /// some dartdoc ^
+        zoo(z) { } String name; }''');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_inLineDocComment2() {
+    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        /// some ^dartdoc
+        zoo(z) { } String name; }''');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_inStarComment() {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/* ^ */ zoo(z) {} String name;}');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_inStarComment2() {
+    // Comment  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/*  *^/ zoo(z) {} String name;}');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_inStarDocComment() {
+    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_inStarDocComment2() {
+    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/**  *^/ zoo(z) { } String name; }');
+    assertOpType();
+  }
+
+  test_MethodDeclaration_returnType() {
+    // ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {^ zoo(z) { } String name; }');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration_returnType_afterLineComment() {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        // normal comment
+        ^ zoo(z) {} String name;}''');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration_returnType_afterLineComment2() {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    // TOD(danrubel) left align all test source
+    addTestSource('''
+class C2 {
+  // normal comment
+^ zoo(z) {} String name;}''');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration_returnType_afterLineDocComment() {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+      class C2 {
+        /// some dartdoc
+        ^ zoo(z) { } String name; }''');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration_returnType_afterLineDocComment2() {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+class C2 {
+  /// some dartdoc
+^ zoo(z) { } String name; }''');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration_returnType_afterStarComment() {
+    // ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/* */ ^ zoo(z) { } String name; }');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration_returnType_afterStarComment2() {
+    // ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/* */^ zoo(z) { } String name; }');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration_returnType_afterStarDocComment() {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration_returnType_afterStarDocComment2() {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodInvocation_no_semicolon() {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      class A implements I {
+        // no semicolon between completion point and next statement
+        set _s2(I x) {x.^ m(null);}
+      }''');
+    assertOpType(
+        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
+  }
+
+  test_PostfixExpression() {
+    // SimpleIdentifier  PostfixExpression  ForStatement
+    addTestSource('int x = 0; main() {ax+^+;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_PrefixedIdentifier_class_const() {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addTestSource('main() {A.^}');
+    assertOpType(
+        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
+  }
+
+  test_PrefixedIdentifier_class_imported() {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('main() {A a; a.^}');
+    assertOpType(
+        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
+  }
+
+  test_PrefixedIdentifier_prefix() {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class X {foo(){A^.bar}}');
+    assertOpType(typeNames: true, returnValue: true, voidReturn: true);
+  }
+
+  test_PropertyAccess_expression() {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+    assertOpType(
+        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
+  }
+
+  test_PropertyAccess_noTarget() {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addTestSource('main() {.^}');
+    assertOpType();
+  }
+
+  test_PropertyAccess_noTarget2() {
+    // SimpleIdentifier  PropertyAccess  CascadeExpressions
+    addTestSource('main() {.^.}');
+    assertOpType();
+  }
+
+  test_PropertyAccess_noTarget3() {
+    // SimpleIdentifier  PropertyAccess  CascadeExpressions
+    addTestSource('main() {..^}');
+    assertOpType();
+  }
+
+  test_PropertyAccess_selector() {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+    assertOpType(
+        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
+  }
+
+  test_ReturnStatement() {
+    // ReturnStatement  Block
+    addTestSource('f() { var vvv = 42; return ^ }');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SimpleFormalParameter_closure() {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('mth() { PNGS.sort((String a, Str^) => a.compareTo(b)); }');
+    assertOpType(typeNames: true);
+  }
+
+  test_SimpleFormalParameter_name1() {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('m(String na^) {}');
+    assertOpType(typeNames: false);
+  }
+
+  test_SimpleFormalParameter_name2() {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('m(int first, String na^) {}');
+    assertOpType(typeNames: false);
+  }
+
+  test_SimpleFormalParameter_type_optionalNamed() {
+    // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
+    addTestSource('m({Str^}) {}');
+    assertOpType(typeNames: true);
+  }
+
+  test_SimpleFormalParameter_type_optionalPositional() {
+    // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
+    addTestSource('m([Str^]) {}');
+    assertOpType(typeNames: true);
+  }
+
+  test_SimpleFormalParameter_type_withName() {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('m(Str^ name) {}');
+    assertOpType(typeNames: true);
+  }
+
+  test_SimpleFormalParameter_type_withoutName1() {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('m(Str^) {}');
+    assertOpType(typeNames: true);
+  }
+
+  test_SimpleFormalParameter_type_withoutName2() {
+    // FormalParameterList
+    addTestSource('m(^) {}');
+    assertOpType(typeNames: true);
+  }
+
+  test_SimpleFormalParameter_type_withoutName3() {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('m(int first, Str^) {}');
+    assertOpType(typeNames: true);
+  }
+
+  test_SwitchCase_before() {
+    // SwitchCase  SwitchStatement  Block
+    addTestSource('main() {switch(k) {^case 1:}}');
+    assertOpType();
+  }
+
+  test_SwitchCase_between() {
+    // SwitchCase  SwitchStatement  Block
+    addTestSource('main() {switch(k) {case 1: ^ case 2: return}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_SwitchCase_expression1() {
+    // SimpleIdentifier  SwitchCase  SwitchStatement
+    addTestSource('''m() {switch (x) {case ^D: return;}}''');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SwitchCase_expression2() {
+    // SimpleIdentifier  SwitchCase  SwitchStatement
+    addTestSource('''m() {switch (x) {case ^}}''');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SwitchDefault_before() {
+    // SwitchDefault  SwitchStatement  Block
+    addTestSource('main() {switch(k) { ^ default: return;}}');
+    assertOpType();
+  }
+
+  test_SwitchDefault_between() {
+    // SwitchDefault  SwitchStatement  Block
+    addTestSource('main() {switch(k) {case 1: ^ default: return;}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_SwitchStatement_body_empty() {
+    // Token('}')  SwitchStatement  Block
+    addTestSource('main() {switch(k) {^}}');
+    assertOpType();
+  }
+
+  test_SwitchStatement_body_end() {
+    // Token('}')  SwitchStatement  Block
+    addTestSource('main() {switch(k) {case 1:^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_SwitchStatement_expression1() {
+    // SimpleIdentifier  SwitchStatement  Block
+    addTestSource('main() {switch(^k) {case 1:{}}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SwitchStatement_expression2() {
+    // SimpleIdentifier  SwitchStatement  Block
+    addTestSource('main() {switch(k^) {case 1:{}}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SwitchStatement_expression_empty() {
+    // SimpleIdentifier  SwitchStatement  Block
+    addTestSource('main() {switch(^) {case 1:{}}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ThisExpression_block() {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      class A implements I {
+        // no semicolon between completion point and next statement
+        set s1(I x) {} set _s2(I x) {this.^ m(null);}
+      }''');
+    assertOpType(returnValue: true, voidReturn: true, prefixed: true);
+  }
+
+  test_ThisExpression_constructor() {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addTestSource('''
+      class A implements I {
+        A() {this.^}
+      }''');
+    assertOpType(returnValue: true, voidReturn: true, prefixed: true);
+  }
+
+  test_ThisExpression_constructor_param() {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+      class A implements I {
+        A(this.^) {}
+      }''');
+    assertOpType(prefixed: true);
+  }
+
+  test_ThisExpression_constructor_param2() {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+      class A implements I {
+        A(this.f^) {}
+      }''');
+    assertOpType(prefixed: true);
+  }
+
+  test_ThisExpression_constructor_param3() {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+      class A implements I {
+        A(this.^f) {}
+      }''');
+    assertOpType(prefixed: true);
+  }
+
+  test_ThisExpression_constructor_param4() {
+    // FieldFormalParameter  FormalParameterList  ConstructorDeclaration
+    addTestSource('''
+      class A implements I {
+        A(Str^ this.foo) {}
+      }''');
+    assertOpType(typeNames: true);
+  }
+
+  test_ThrowExpression() {
+    // SimpleIdentifier  ThrowExpression  ExpressionStatement
+    addTestSource('main() {throw ^;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+    assertOpType();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+    assertOpType();
+  }
+
+  test_TypeArgumentList() {
+    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    addTestSource('main() { C<^> c; }');
+    assertOpType(typeNames: true);
+  }
+
+  test_TypeArgumentList2() {
+    // TypeName  TypeArgumentList  TypeName
+    addTestSource('main() { C<C^> c; }');
+    assertOpType(typeNames: true);
+  }
+
+  test_TypeParameter() {
+    // SimpleIdentifier  TypeParameter  TypeParameterList
+    addTestSource('class tezetst <String, ^List> {}');
+    assertOpType();
+  }
+
+  test_TypeParameterList_empty() {
+    // SimpleIdentifier  TypeParameter  TypeParameterList
+    addTestSource('class tezetst <^> {}');
+    assertOpType();
+  }
+
+  test_VariableDeclaration_name() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('main() {var ^}');
+    assertOpType();
+  }
+
+  test_VariableDeclaration_name_hasSome_parameterizedType() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('main() {List<int> m^}');
+    assertOpType();
+  }
+
+  test_VariableDeclaration_name_hasSome_simpleType() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('main() {String m^}');
+    assertOpType();
+  }
+
+  test_VariableDeclarationList_final() {
+    // VariableDeclarationList  VariableDeclarationStatement  Block
+    addTestSource('main() {final ^}');
+    assertOpType(typeNames: true);
+  }
+
+  test_VariableDeclarationStatement_afterSemicolon() {
+    // VariableDeclarationStatement  Block  BlockFunctionBody
+    addTestSource('class A {var a; x() {var b;^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_VariableDeclarationStatement_RHS() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addTestSource('class C {bar(){var f; {var x;} var e = ^}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addTestSource('class C {bar(){var f; {var x;} var e = ^ var g}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_WhileStatement() {
+    // SimpleIdentifier  WhileStatement  Block
+    addTestSource('mth() { while (b^) {} }}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+}
+
+class _TestSource implements Source {
+  String fullName;
+  _TestSource(this.fullName);
+
+  @override
+  bool get isInSystemLibrary => false;
+
+  @override
+  String get shortName => fullName;
+
+  @override
+  Source get source => this;
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
new file mode 100644
index 0000000..e219259
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
@@ -0,0 +1,119 @@
+// 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 test.services.completion.dart.override;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/override_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import 'completion_contributor_util.dart';
+
+main() {
+  // Revisit this contributor and these tests
+  // once DartChangeBuilder API has solidified.
+  // initializeTestEnvironment();
+  // defineReflectiveTests(InheritedContributorTest);
+}
+
+@reflectiveTest
+class OverrideContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new OverrideContributor();
+  }
+
+  test_fromMultipleSuperclasses() async {
+    addTestSource(r'''
+class A {
+  A suggested1(int x) => null;
+  B suggested2(String y) => null;
+}
+class B extends A {
+  B suggested2(String y) => null;
+  C suggested3([String z]) => null;
+}
+class C extends B {
+  sugg^
+}
+''');
+    await computeSuggestions();
+    _assertOverride('''@override
+  A suggested1(int x) {
+    // TODO: implement suggested1
+    return null;
+  }''');
+    _assertOverride(
+        '''@override\n  A suggested1(int x) {\n    // TODO: implement suggested1\n    return null;\n  }''');
+    _assertOverride(
+        '''@override\n  B suggested2(String y) {\n    // TODO: implement suggested2\n    return null;\n  }''');
+    _assertOverride(
+        '''@override\n  C suggested3([String z]) {\n    // TODO: implement suggested3\n    return null;\n  }''');
+  }
+
+  test_fromPart() async {
+    addSource(
+        '/myLib.dart',
+        '''
+library myLib;
+part '$testFile'
+part '/otherPart.dart'
+class A {
+  A suggested1(int x) => null;
+  B suggested2(String y) => null;
+}
+''');
+    addSource(
+        '/otherPart.dart',
+        '''
+part of myLib;
+class B extends A {
+  B suggested2(String y) => null;
+  C suggested3([String z]) => null;
+}
+''');
+    addTestSource(r'''
+part of myLib;
+class C extends B {
+  sugg^
+}
+''');
+    // assume information for context.getLibrariesContaining has been cached
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    _assertOverride('''@override
+  A suggested1(int x) {
+    // TODO: implement suggested1
+    return null;
+  }''');
+    _assertOverride(
+        '''@override\n  A suggested1(int x) {\n    // TODO: implement suggested1\n    return null;\n  }''');
+    _assertOverride(
+        '''@override\n  B suggested2(String y) {\n    // TODO: implement suggested2\n    return null;\n  }''');
+    _assertOverride(
+        '''@override\n  C suggested3([String z]) {\n    // TODO: implement suggested3\n    return null;\n  }''');
+  }
+
+  CompletionSuggestion _assertOverride(String completion) {
+    CompletionSuggestion cs = getSuggest(
+        completion: completion,
+        csKind: CompletionSuggestionKind.IDENTIFIER,
+        elemKind: null);
+    if (cs == null) {
+      failedCompletion('expected $completion', suggestions);
+    }
+    expect(cs.kind, equals(CompletionSuggestionKind.IDENTIFIER));
+    expect(cs.relevance, equals(DART_RELEVANCE_HIGH));
+    expect(cs.importUri, null);
+//    expect(cs.selectionOffset, equals(completion.length));
+//    expect(cs.selectionLength, equals(0));
+    expect(cs.isDeprecated, isFalse);
+    expect(cs.isPotential, isFalse);
+    expect(cs.element, isNotNull);
+    return cs;
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
new file mode 100644
index 0000000..6efd8ab
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -0,0 +1,289 @@
+// 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 test.services.completion.dart.static_member;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(StaticMemberContributorTest);
+}
+
+@reflectiveTest
+class StaticMemberContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new StaticMemberContributor();
+  }
+
+  fail_enumConst_deprecated() async {
+    addTestSource('@deprecated enum E { one, two } main() {E.^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    // TODO(danrubel) Investigate why enum suggestion is not marked
+    // as deprecated if enum ast element is deprecated
+    assertSuggestEnumConst('one', isDeprecated: true);
+    assertSuggestEnumConst('two', isDeprecated: true);
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>', isDeprecated: true);
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {
+          static const scI = 'boo';
+          X get f => new A();
+          get _g => new A();}
+        class B implements I {
+          static const int scB = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends B {
+          static const String scA = 'foo';
+          w() { }}
+        main() {A.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('scA', 'String');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_enumConst() async {
+    addTestSource('enum E { one, two } main() {E.^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_enumConst2() async {
+    addTestSource('enum E { one, two } main() {E.o^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_enumConst3() async {
+    addTestSource('enum E { one, two } main() {E.^ int g;}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_enumConst_cascade1() async {
+    addTestSource('enum E { one, two } main() {E..^}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_enumConst_cascade2() async {
+    addTestSource('enum E { one, two } main() {E.^.}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_enumConst_cascade3() async {
+    addTestSource('enum E { one, two } main() {E..o^}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_enumConst_cascade4() async {
+    addTestSource('enum E { one, two } main() {E.^.o}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_keyword() async {
+    addTestSource('class C { static C get instance => null; } main() {C.in^}');
+    await computeSuggestions();
+    assertSuggestGetter('instance', 'C');
+  }
+
+  test_only_static() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^}''');
+    await computeSuggestions();
+    assertNotSuggested('b1');
+    assertNotSuggested('f1');
+    assertSuggestField('f2', 'int');
+    assertNotSuggested('m1');
+    assertSuggestMethod('m2', 'C', null);
+  }
+
+  test_only_static2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^ print("something");}''');
+    await computeSuggestions();
+    assertNotSuggested('b1');
+    assertNotSuggested('f1');
+    assertSuggestField('f2', 'int');
+    assertNotSuggested('m1');
+    assertSuggestMethod('m2', 'C', null);
+  }
+
+  test_only_static_cascade1() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C..^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_only_static_cascade2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^.}''');
+    await computeSuggestions();
+    assertNotSuggested('b1');
+    assertNotSuggested('f1');
+    assertSuggestField('f2', 'int');
+    assertNotSuggested('m1');
+    assertSuggestMethod('m2', 'C', null);
+  }
+
+  test_only_static_cascade3() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C..m^()}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_only_static_cascade4() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^.m()}''');
+    await computeSuggestions();
+    assertNotSuggested('b1');
+    assertNotSuggested('f1');
+    assertSuggestField('f2', 'int');
+    assertNotSuggested('m1');
+    assertSuggestMethod('m2', 'C', null);
+  }
+
+  test_only_static_cascade_prefixed1() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+import "dart:async" as async;
+void main() {async.Future..w^()}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_only_static_cascade_prefixed2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+import "dart:async" as async;
+void main() {async.Future.^.w()}''');
+    await computeSuggestions();
+    assertSuggestMethod('wait', 'Future', 'Future<dynamic>');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
new file mode 100644
index 0000000..c12f8de
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -0,0 +1,56 @@
+// 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 test.services.completion.dart;
+
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'arglist_contributor_test.dart' as arglist_test;
+import 'combinator_contributor_test.dart' as combinator_test;
+import 'common_usage_sorter_test.dart' as common_usage_test;
+import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
+import 'imported_reference_contributor_test.dart' as imported_ref_test;
+import 'inherited_reference_contributor_test.dart' as inherited_ref_test;
+import 'keyword_contributor_test.dart' as keyword_test;
+import 'label_contributor_test.dart' as label_contributor_test;
+import 'library_member_contributor_test.dart' as library_member_test;
+import 'library_prefix_contributor_test.dart' as library_prefix_test;
+import 'local_constructor_contributor_test.dart' as local_constructor_test;
+import 'local_declaration_visitor_test.dart' as local_decl_visitor_test;
+import 'local_library_contributor_test.dart' as local_lib_test;
+import 'local_reference_contributor_test.dart' as local_ref_test;
+import 'named_constructor_contributor_test.dart' as named_contributor_test;
+import 'optype_test.dart' as optype_test;
+import 'override_contributor_test.dart' as override_contributor_test;
+import 'static_member_contributor_test.dart' as static_contributor_test;
+import 'type_member_contributor_test.dart' as type_member_contributor_test;
+import 'uri_contributor_test.dart' as uri_contributor_test;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('dart/completion', () {
+    arglist_test.main();
+    combinator_test.main();
+    common_usage_test.main();
+    field_formal_contributor_test.main();
+    imported_ref_test.main();
+    inherited_ref_test.main();
+    keyword_test.main();
+    label_contributor_test.main();
+    library_member_test.main();
+    library_prefix_test.main();
+    local_constructor_test.main();
+    local_decl_visitor_test.main();
+    local_lib_test.main();
+    local_ref_test.main();
+    named_contributor_test.main();
+    optype_test.main();
+    override_contributor_test.main();
+    static_contributor_test.main();
+    type_member_contributor_test.main();
+    uri_contributor_test.main();
+  });
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
new file mode 100644
index 0000000..8d176b8
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -0,0 +1,4157 @@
+// 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 test.services.completion.contributor.dart.type_member;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(TypeMemberContributorTest);
+}
+
+@reflectiveTest
+class TypeMemberContributorTest extends DartCompletionContributorTest {
+  /**
+   * Check whether a declaration of the form [shadower] in a derived class
+   * shadows a declaration of the form [shadowee] in a base class, for the
+   * purposes of what is shown during completion.  [shouldBeShadowed] indicates
+   * whether shadowing is expected.
+   */
+  Future check_shadowing(
+      String shadower, String shadowee, bool shouldBeShadowed) async {
+    addTestSource('''
+class Base {
+  $shadowee
+}
+class Derived extends Base {
+  $shadower
+}
+void f(Derived d) {
+  d.^
+}
+''');
+    await computeSuggestions();
+    List<CompletionSuggestion> suggestionsForX = suggestions
+        .where((CompletionSuggestion s) => s.completion == 'x')
+        .toList();
+    expect(suggestionsForX, hasLength(1));
+    if (shouldBeShadowed) {
+      expect(suggestionsForX[0].declaringType, 'Derived');
+    } else {
+      expect(suggestionsForX[0].declaringType, 'Base');
+    }
+  }
+
+  fail_test_PrefixedIdentifier_trailingStmt_const_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const g = "hello"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new TypeMemberContributor();
+  }
+
+  test_enumConst() async {
+    addTestSource('enum E { one, two } main() {E.^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertNotSuggested('index');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst2() async {
+    addTestSource('enum E { one, two } main() {E.o^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertNotSuggested('index');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst3() async {
+    addTestSource('enum E { one, two } main() {E.^ int g;}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertNotSuggested('index');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst_index() async {
+    addTestSource('enum E { one, two } main() {E.one.^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertSuggestField('index', 'int');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst_index2() async {
+    addTestSource('enum E { one, two } main() {E.one.i^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertSuggestField('index', 'int');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst_index3() async {
+    addTestSource('enum E { one, two } main() {E.one.^ int g;}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertSuggestField('index', 'int');
+    assertNotSuggested('values');
+  }
+
+  test_generic_field() async {
+    addTestSource('''
+class C<T> {
+  T t;
+}
+void f(C<int> c) {
+  c.^
+}
+''');
+    await computeSuggestions();
+    assertSuggestField('t', 'int');
+  }
+
+  test_generic_getter() async {
+    addTestSource('''
+class C<T> {
+  T get t => null;
+}
+void f(C<int> c) {
+  c.^
+}
+''');
+    await computeSuggestions();
+    assertSuggestGetter('t', 'int');
+  }
+
+  test_generic_method() async {
+    addTestSource('''
+class C<T> {
+  T m(T t) {}
+}
+void f(C<int> c) {
+  c.^
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'int');
+    expect(suggestion.parameterTypes[0], 'int');
+    expect(suggestion.element.returnType, 'int');
+    expect(suggestion.element.parameters, '(int t)');
+  }
+
+  test_generic_setter() async {
+    addTestSource('''
+class C<T> {
+  set t(T value) {}
+}
+void f(C<int> c) {
+  c.^
+}
+''');
+    await computeSuggestions();
+    // TODO(paulberry): modify assertSuggestSetter so that we can pass 'int'
+    // as a parmeter to it, and it will check the appropriate field in
+    // the suggestion object.
+    CompletionSuggestion suggestion = assertSuggestSetter('t');
+    expect(suggestion.element.parameters, '(int value)');
+  }
+
+  test_keyword() async {
+    addTestSource('class C { static C get instance => null; } main() {C.in^}');
+    await computeSuggestions();
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('instance');
+  }
+
+  test_libraryPrefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {bar.^}');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('Future');
+    assertNotSuggested('loadLibrary');
+  }
+
+  test_libraryPrefix2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('Future');
+  }
+
+  test_libraryPrefix3() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('Future');
+    assertNotSuggested('Future.delayed');
+  }
+
+  test_libraryPrefix_deferred() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('Future');
+    assertNotSuggested('loadLibrary');
+  }
+
+  test_libraryPrefix_with_exports() async {
+    addSource('/libA.dart', 'library libA; class A { }');
+    addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
+    addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+  }
+
+  test_local() async {
+    addTestSource('foo() {String x = "bar"; x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_local_is() async {
+    addTestSource('foo() {var x; if (x is String) x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_local_propogatedType() async {
+    addTestSource('foo() {var x = "bar"; x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    addTestSource('''
+class C {
+  void m(x, {int y}) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+class C {
+  void m(x, [int y]) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_named() async {
+    addTestSource('''
+class C {
+  void m({x, int y}) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_none() async {
+    addTestSource('''
+class C {
+  void m() {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_positional() async {
+    addTestSource('''
+class C {
+  void m([x, int y]) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_required() async {
+    addTestSource('''
+class C {
+  void m(x, int y) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_no_parameters_field() async {
+    addTestSource('''
+class C {
+  int x;
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestField('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_getter() async {
+    addTestSource('''
+class C {
+  int get x => null;
+}
+void main() {int y = new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_setter() async {
+    addTestSource('''
+class C {
+  set x(int value) {};
+}
+void main() {int y = new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestSetter('x');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_only_instance() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addTestSource('''
+class C {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    assertSuggestField('f1', 'int');
+    assertNotSuggested('f2');
+    assertSuggestMethod('m1', 'C', null);
+    assertNotSuggested('m2');
+  }
+
+  test_only_instance2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('''
+class C {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {new C().^ print("something");}''');
+    await computeSuggestions();
+    assertSuggestField('f1', 'int');
+    assertNotSuggested('f2');
+    assertSuggestMethod('m1', 'C', null);
+    assertNotSuggested('m2');
+  }
+
+  test_only_static() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class C {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^}''');
+    await computeSuggestions();
+    assertNotSuggested('f1');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('f2');
+    assertNotSuggested('m1');
+    assertNotSuggested('m2');
+  }
+
+  test_only_static2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('''
+class C {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^ print("something");}''');
+    await computeSuggestions();
+    assertNotSuggested('f1');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('f2');
+    assertNotSuggested('m1');
+    assertNotSuggested('m2');
+  }
+
+  test_param() async {
+    addTestSource('foo(String x) {x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_param_is() async {
+    addTestSource('foo(x) {if (x is String) x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_shadowing_field_over_field() =>
+      check_shadowing('int x;', 'int x;', true);
+
+  test_shadowing_field_over_getter() =>
+      check_shadowing('int x;', 'int get x => null;', true);
+
+  test_shadowing_field_over_method() =>
+      check_shadowing('int x;', 'void x() {}', true);
+
+  test_shadowing_field_over_setter() =>
+      check_shadowing('int x;', 'set x(int value) {}', true);
+
+  test_shadowing_getter_over_field() =>
+      check_shadowing('int get x => null;', 'int x;', false);
+
+  test_shadowing_getter_over_getter() =>
+      check_shadowing('int get x => null;', 'int get x => null;', true);
+
+  test_shadowing_getter_over_method() =>
+      check_shadowing('int get x => null;', 'void x() {}', true);
+
+  test_shadowing_getter_over_setter() =>
+      check_shadowing('int get x => null;', 'set x(int value) {}', false);
+
+  test_shadowing_method_over_field() =>
+      check_shadowing('void x() {}', 'int x;', true);
+
+  test_shadowing_method_over_getter() =>
+      check_shadowing('void x() {}', 'int get x => null;', true);
+
+  test_shadowing_method_over_method() =>
+      check_shadowing('void x() {}', 'void x() {}', true);
+
+  test_shadowing_method_over_setter() =>
+      check_shadowing('void x() {}', 'set x(int value) {}', true);
+
+  test_shadowing_mixin_order() async {
+    addTestSource('''
+class Base {
+}
+class Mixin1 {
+  void f() {}
+}
+class Mixin2 {
+  void f() {}
+}
+class Derived extends Base with Mixin1, Mixin2 {
+}
+void test(Derived d) {
+  d.^
+}
+''');
+    await computeSuggestions();
+    // Note: due to dartbug.com/22069, analyzer currently analyzes mixins in
+    // reverse order.  The correct order is that Derived inherits from
+    // "Base with Mixin1, Mixin2", which inherits from "Base with Mixin1",
+    // which inherits from "Base".  So the definition of f in Mixin2 should
+    // shadow the definition in Mixin1.
+    assertSuggestMethod('f', 'Mixin2', 'void');
+  }
+
+  test_shadowing_mixin_over_superclass() async {
+    addTestSource('''
+class Base {
+  void f() {}
+}
+class Mixin {
+  void f() {}
+}
+class Derived extends Base with Mixin {
+}
+void test(Derived d) {
+  d.^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('f', 'Mixin', 'void');
+  }
+
+  test_shadowing_setter_over_field() =>
+      check_shadowing('set x(int value) {}', 'int x;', false);
+
+  test_shadowing_setter_over_getter() =>
+      check_shadowing('set x(int value) {}', 'int get x => null;', false);
+
+  test_shadowing_setter_over_method() =>
+      check_shadowing('set x(int value) {}', 'void x() {}', true);
+
+  test_shadowing_setter_over_setter() =>
+      check_shadowing('set x(int value) {}', 'set x(int value) {}', true);
+
+  test_shadowing_superclass_over_interface() async {
+    addTestSource('''
+class Base {
+  void f() {}
+}
+class Interface {
+  void f() {}
+}
+class Derived extends Base implements Interface {
+}
+void test(Derived d) {
+  d.^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('f', 'Base', 'void');
+  }
+
+  test_super() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('''
+class C3 {
+  int fi3;
+  static int fs3;
+  m() {}
+  mi3() {}
+  static ms3() {}
+}
+class C2 {
+  int fi2;
+  static int fs2;
+  m() {}
+  mi2() {}
+  static ms2() {}
+}
+class C1 extends C2 implements C3 {
+  int fi1;
+  static int fs1;
+  m() {super.^}
+  mi1() {}
+  static ms1() {}
+}''');
+    await computeSuggestions();
+    assertNotSuggested('fi1');
+    assertNotSuggested('fs1');
+    assertNotSuggested('mi1');
+    assertNotSuggested('ms1');
+    assertSuggestField('fi2', 'int');
+    assertNotSuggested('fs2');
+    assertSuggestMethod('mi2', 'C2', null);
+    assertNotSuggested('ms2');
+    assertSuggestMethod('m', 'C2', null, relevance: DART_RELEVANCE_HIGH);
+    assertNotSuggested('fi3');
+    assertNotSuggested('fs3');
+    assertNotSuggested('mi3');
+    assertNotSuggested('ms3');
+  }
+
+  test_ArgumentList() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_imported_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        expect(arg) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {new A(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        typedef Funct();
+        class A { A(Funct f) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {new A(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        expect(arg) { }
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_method() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        class B {
+          expect(arg) { }
+          void foo() {expect(^)}}
+        String bar() => true;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_functionalArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar(f()) => true;
+        void main() {bar(^);}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_methodArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { String bar(f()) => true; }
+        void main() {new B().bar(^);}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_namedParam() async {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }''');
+    addTestSource('''
+        import '/libA.dart'
+        String bar() => true;
+        void main() {expect(foo: ^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('main');
+  }
+
+  test_AsExpression() async {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('''
+        class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_AssignmentExpression_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_AssignmentExpression_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_AssignmentExpression_type() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          ^ b = 1;}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          ^
+          b = 1;}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          int^ b = 1;}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          i^
+          b = 1;}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('identical');
+  }
+
+  test_AwaitExpression() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main() async {A a; await ^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_BinaryExpression_LHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+  }
+
+  test_BinaryExpression_RHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('==');
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            ^ var r;
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            final ^
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final2() async {
+    addTestSource('main() {final S^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final3() async {
+    addTestSource('main() {final ^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            final ^
+            final var f;
+            localF(int arg1) { }
+            {var x;}
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            final ^
+            var f;
+            localF(int arg1) { }
+            {var x;}
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_identifier_partial() async {
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        class D3 { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        Z D2() {int x;}
+        class X {a() {var f; {var x;} D^ var r;} void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+
+    // imported elements are portially filtered
+    //assertNotSuggested('A');
+    assertNotSuggested('_B');
+    //assertNotSuggested('C');
+    // hidden element suggested as low relevance
+    assertNotSuggested('D');
+    assertNotSuggested('D1');
+    assertNotSuggested('D2');
+    // unimported elements suggested with low relevance
+    assertNotSuggested('D3');
+    //assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    //assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    //assertNotSuggested('Object');
+    //assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    //assertSuggestTopLevelVarGetterSetter('T1', 'String');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    //assertNotSuggested('T5');
+    //assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+        class E extends F { var e1; e2() { } }
+        class I { int i1; i2() { } }
+        class M { var m1; int m2() { } }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // TODO (danrubel) prefer fields over getters
+    // If add `get e1;` to interface I
+    // then suggestions include getter e1 rather than field e1
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    //assertNotSuggested('m2');
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+        class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+        class E extends F { var e1; e2() { } }
+        class I { int i1; i2() { } }
+        class M { var m1; int m2() { } }
+        class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    assertNotSuggested('m2');
+  }
+
+  test_Block_local_function() async {
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            p^ var r;
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('partT8');
+    assertNotSuggested('partBoo');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_unimported() async {
+    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+    addSource(
+        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
+    testFile = '/proj/completionTest.dart';
+    addTestSource('class C {foo(){F^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Foo');
+    // TODO(danrubel) implement
+    assertNotSuggested('Foo2');
+    assertNotSuggested('Future');
+  }
+
+  test_CascadeExpression_method1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        // looks like a cascade to the parser
+        // but the user is trying to get completions for a non-cascade
+        main() {A a; a.^.z()}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        // looks like a cascade to the parser
+        // but the user is trying to get completions for a non-cascade
+        main() {A a; a.^.z}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a..^z}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a..^ return}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_target() async {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('''
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a^..b}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_CatchClause_onType() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_onType_noBrackets() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_typed() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_untyped() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('s');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        @deprecated class A {^}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ A(){}}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as Soo;
+        class A {final S^ A();}
+        class _B {}
+        A Sew;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('Sew');
+    assertNotSuggested('Soo');
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ final foo;}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ var foo;}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_Combinator_hide() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+        library libAB;
+        part '/partAB.dart';
+        class A { }
+        class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+        part of libAB;
+        var T1;
+        PB F1() => new PB();
+        class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        class C { }
+        class D { }''');
+    addTestSource('''
+        import "/testAB.dart" hide ^;
+        import "/testCD.dart";
+        class X {}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_Combinator_show() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+        library libAB;
+        part '/partAB.dart';
+        class A { }
+        class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+        part of libAB;
+        var T1;
+        PB F1() => new PB();
+        typedef PB2 F2(int blat);
+        class Clz = Object with Object;
+        class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        class C { }
+        class D { }''');
+    addTestSource('''
+        import "/testAB.dart" show ^;
+        import "/testCD.dart";
+        class X {}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ConditionalExpression_elseExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_elseExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_partial_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T^}}''');
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_partial_thenExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? ^}}''');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T^ : c}}''');
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('fromCharCodes');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_DefaultFormalParameter_named_expression() async {
+    // DefaultFormalParameter FormalParameterList MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {a(blat: ^) { }}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ExpressionStatement_identifier() async {
+    // SimpleIdentifier  ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+        _B F1() { }
+        class A {int x;}
+        class _B { }''');
+    addTestSource('''
+        import "/testA.dart";
+        typedef int F2(int blat);
+        class Clz = Object with Object;
+        class C {foo(){^} void bar() {}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('C');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('F2');
+    assertNotSuggested('Clz');
+    assertNotSuggested('C');
+    assertNotSuggested('x');
+    assertNotSuggested('_B');
+  }
+
+  test_ExpressionStatement_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        B T1;
+        class B{}''');
+    addTestSource('''
+        import "/testA.dart";
+        class C {a() {C ^}}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_typed() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {A ^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_var() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {var ^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldFormalParameter_in_non_constructor() async {
+    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
+    addTestSource('class A {B(this.^foo) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 3);
+    assertNoSuggestions();
+  }
+
+  test_ForEachStatement_body_typed() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_body_untyped() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_iterable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (int foo in ^) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_loopVariable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_FormalParameterList() async {
+    // FormalParameterList MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {a(^) { }}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ForStatement_body() async {
+    // Block  ForStatement
+    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('i');
+    assertNotSuggested('Object');
+  }
+
+  test_ForStatement_condition() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_initializer() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('int');
+  }
+
+  test_ForStatement_updaters() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_updaters_prefix_expression() async {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('''
+        void bar() { }
+        main() {for (int index = 0; index < 10; ++i^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+    assertNotSuggested('main');
+    assertNotSuggested('bar');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        /* */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment2() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        /** */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment3() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        /// some dartdoc
+        class C2 { }
+        ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionExpression_body_function() async {
+    // Block  BlockFunctionBody  FunctionExpression
+    addTestSource('''
+        void bar() { }
+        String foo(List args) {x.then((R b) {^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('args');
+    assertNotSuggested('b');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (true) ^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_condition() async {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement_empty() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (^) something}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_invocation() async {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+        main() {var a; if (a.^) something}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestMethod('toString', 'Object', 'String');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_ImportDirective_dart() async {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+        import "dart^";
+        main() {}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_IndexExpression() async {
+    // ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} f[^]}}''');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_IndexExpression2() async {
+    // SimpleIdentifier IndexExpression ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} f[T^]}}''');
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_InstanceCreationExpression_imported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {A(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        import "dart:async";
+        int T2;
+        F2() { }
+        class B {B(this.x, [String boo]) { } int x;}
+        class C {foo(){var f; {var x;} new ^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('Future');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('foo');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_InstanceCreationExpression_unimported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){new F^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Future');
+    assertNotSuggested('Foo');
+  }
+
+  test_InterpolationExpression() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        main() {String name; print("hello \$^");}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    // TODO(danrubel) should return top level var rather than getter
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        main() {String name; print("hello \${^}");}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block2() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+    await computeSuggestions();
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+  }
+
+  test_InterpolationExpression_prefix_selector() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('length', 'int');
+    assertNotSuggested('name');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_InterpolationExpression_prefix_selector2() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \$name.^");}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_InterpolationExpression_prefix_target() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+    await computeSuggestions();
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('length');
+  }
+
+  test_IsExpression() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        main() {var x; if (x is ^) { }}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('x');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+  }
+
+  test_IsExpression_target() async {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {int x; int y() => 0;}
+        main(){var a; if (^ is A)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (a is ^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (a is Obj^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_keyword2() async {
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int newT1;
+        int T1;
+        nowIsIt() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        String newer() {}
+        var m;
+        main() {new^ X.c();}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    // Imported suggestion are filtered by 1st character
+    assertNotSuggested('nowIsIt');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+    assertNotSuggested('newer');
+  }
+
+  test_Literal_list() async {
+    // ']'  ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([^]);}');
+    await computeSuggestions();
+    assertNotSuggested('Some');
+    assertNotSuggested('String');
+  }
+
+  test_Literal_list2() async {
+    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([S^]);}');
+    await computeSuggestions();
+    assertNotSuggested('Some');
+    assertNotSuggested('String');
+  }
+
+  test_Literal_string() async {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_MapLiteralEntry() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {^''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+  }
+
+  test_MapLiteralEntry1() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {T^''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T2');
+  }
+
+  test_MapLiteralEntry2() async {
+    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {7:T^};''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T2');
+  }
+
+  test_MethodDeclaration_body_getters() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+  }
+
+  test_MethodDeclaration_body_static() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testC.dart',
+        '''
+        class C {
+          c1() {}
+          var c2;
+          static c3() {}
+          static var c4;}''');
+    addTestSource('''
+        import "/testC.dart";
+        class B extends C {
+          b1() {}
+          var b2;
+          static b3() {}
+          static var b4;}
+        class A extends B {
+          a1() {}
+          var a2;
+          static a3() {}
+          static var a4;
+          static a() {^}}''');
+    await computeSuggestions();
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    assertNotSuggested('a3');
+    assertNotSuggested('a4');
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    assertNotSuggested('b3');
+    assertNotSuggested('b4');
+    assertNotSuggested('c1');
+    assertNotSuggested('c2');
+    assertNotSuggested('c3');
+    assertNotSuggested('c4');
+  }
+
+  test_MethodDeclaration_members() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('_a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('bool');
+  }
+
+  test_MethodDeclaration_parameters_named() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('b');
+    assertNotSuggested('int');
+    assertNotSuggested('_');
+  }
+
+  test_MethodDeclaration_parameters_positional() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {Z a(X x, [int y=1]) {^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('String');
+  }
+
+  test_MethodDeclaration_returnType() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {/* */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {/** */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment3() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {
+          /// some dartdoc
+          ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodInvocation_no_semicolon() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {x.^ m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('f', 'X');
+    assertSuggestGetter('_g', null);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_new_instance() async {
+    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
+    await computeSuggestions();
+    assertSuggestMethod('nextBool', 'Random', 'bool');
+    assertSuggestMethod('nextDouble', 'Random', 'double');
+    assertSuggestMethod('nextInt', 'Random', 'int');
+    assertNotSuggested('Random');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+  }
+
+  test_parameterName_excludeTypes() async {
+    addTestSource('m(int ^) {}');
+    await computeSuggestions();
+    assertNotSuggested('int');
+    assertNotSuggested('bool');
+  }
+
+  test_partFile_TypeName() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        library libA;
+        import "/testB.dart";
+        part "$testFile";
+        class A { }
+        var m;''');
+    addTestSource('''
+        part of libA;
+        class B { factory B.bar(int x) => null; }
+        main() {new ^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('B.bar');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        part of libA;
+        class B { }''');
+    addTestSource('''
+        library libA;
+        import "/testB.dart";
+        part "/testA.dart";
+        class A { A({String boo: 'hoo'}) { } }
+        main() {new ^}
+        var m;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('B');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {
+          static const scI = 'boo';
+          X get f => new A();
+          get _g => new A();}
+        class B implements I {
+          static const int scB = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends B {
+          static const String scA = 'foo';
+          w() { }}
+        main() {A.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('scA');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_imported() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          static const int sc = 12;
+          @deprecated var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        main() {A a; a.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertSuggestField('b', null, isDeprecated: true);
+    assertNotSuggested('_c');
+    assertSuggestGetter('d', 'X');
+    assertNotSuggested('_e');
+    assertSuggestGetter('f', 'X');
+    assertNotSuggested('_g');
+    assertSuggestSetter('s1');
+    assertNotSuggested('_s2');
+    assertSuggestMethod('m', 'A', null);
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_local() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+        main() {A a; a.^}
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          static const int sc = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertSuggestGetter('d', 'X');
+    assertSuggestGetter('_e', null);
+    assertSuggestGetter('f', 'X');
+    assertSuggestGetter('_g', null);
+    assertSuggestSetter('s1');
+    assertSuggestSetter('_s2');
+    assertSuggestMethod('m', 'A', null);
+    assertSuggestMethod('_n', 'A', 'I');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        main() {b.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^ f) {}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^) {}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class _W {M y; var _z;}
+        class X extends _W {}
+        class M{}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo(X x) {x.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('y', 'M');
+    assertNotSuggested('_z');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+        class A {static int bar = 10;}
+        _B() {}''');
+    addTestSource('''
+        import "/testA.dart";
+        class X {foo(){A^.bar}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('_B');
+  }
+
+  test_PrefixedIdentifier_propertyAccess() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('isEmpty', 'bool');
+    assertSuggestMethod('compareTo', 'Comparable', 'int');
+  }
+
+  test_PrefixedIdentifier_propertyAccess_newStmt() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('isEmpty', 'bool');
+    assertSuggestMethod('compareTo', 'Comparable', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_const() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_field() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_function() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_typed() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {String g; g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_method() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_localVariableDeclarationName() async {
+    addTestSource('main() {String m^}');
+    await computeSuggestions();
+    assertNotSuggested('main');
+    assertNotSuggested('min');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f(String g) {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PropertyAccess_expression() async {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 8);
+    assertSuggestGetter('length', 'int');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PropertyAccess_noTarget() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){.^}}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_noTarget2() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('main() {.^}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_selector() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('isEven', 'bool');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_SwitchStatement_c() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_SwitchStatement_case() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
+    await computeSuggestions();
+    assertNotSuggested('A');
+    assertNotSuggested('g');
+    assertNotSuggested('t');
+    assertNotSuggested('String');
+  }
+
+  test_SwitchStatement_empty() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {^}}}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ThisExpression_block() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A() {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {this.^ m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertSuggestGetter('d', 'X');
+    assertSuggestGetter('_e', null);
+    assertSuggestGetter('f', 'X');
+    assertSuggestGetter('_g', null);
+    assertSuggestMethod('m', 'A', null);
+    assertSuggestMethod('_n', 'A', 'I');
+    assertSuggestSetter('s1');
+    assertSuggestSetter('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A() {this.^}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertSuggestGetter('d', 'X');
+    assertSuggestGetter('_e', null);
+    assertSuggestGetter('f', 'X');
+    assertSuggestGetter('_g', null);
+    assertSuggestMethod('m', 'A', null);
+    assertSuggestMethod('_n', 'A', 'I');
+    assertSuggestSetter('s1');
+    assertSuggestSetter('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^) {}
+          A.z() {}
+          var b; X _c; static sb;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('sb');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param2() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param3() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^b) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param4() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b, this.^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_TypeArgumentList() async {
+    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+        class C1 {int x;}
+        F1() => 0;
+        typedef String T1(int blat);''');
+    addTestSource('''
+        import "/testA.dart";'
+        class C2 {int x;}
+        F2() => 0;
+        typedef int T2(int blat);
+        class C<E> {}
+        main() { C<^> c; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('C1');
+    assertNotSuggested('T1');
+    assertNotSuggested('C2');
+    assertNotSuggested('T2');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+  }
+
+  test_TypeArgumentList2() async {
+    // TypeName  TypeArgumentList  TypeName
+    addSource(
+        '/testA.dart',
+        '''
+        class C1 {int x;}
+        F1() => 0;
+        typedef String T1(int blat);''');
+    addTestSource('''
+        import "/testA.dart";'
+        class C2 {int x;}
+        F2() => 0;
+        typedef int T2(int blat);
+        class C<E> {}
+        main() { C<C^> c; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('C1');
+    assertNotSuggested('C2');
+  }
+
+  test_VariableDeclaration_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        main() {var ^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_VariableDeclarationList_final() async {
+    // VariableDeclarationList  VariableDeclarationStatement  Block
+    addTestSource('main() {final ^} class C { }');
+    await computeSuggestions();
+    assertNotSuggested('Object');
+    assertNotSuggested('C');
+    assertNotSuggested('==');
+  }
+
+  test_VariableDeclarationStatement_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        class C {bar(){var f; {var x;} var e = ^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo1() { }
+        void bar1() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo2() { }
+        void bar2() { }
+        class Y {Y.c(); Y._d(); z() {}}
+        class C {bar(){var f; {var x;} var e = ^ var g}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('foo1');
+    assertNotSuggested('bar1');
+    assertNotSuggested('foo2');
+    assertNotSuggested('bar2');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
new file mode 100644
index 0000000..f120744
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
@@ -0,0 +1,561 @@
+// 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 test.services.completion.contributor.dart.importuri;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:path/path.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(UriContributorTest);
+  defineReflectiveTests(UriContributorWindowsTest);
+}
+
+@reflectiveTest
+class UriContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new UriContributor();
+  }
+
+  test_after_import() async {
+    addTestSource('import "p"^');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions();
+  }
+
+  test_after_import_raw() async {
+    addTestSource('import r"p"^');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions();
+  }
+
+  test_before_import() async {
+    addTestSource('import ^"p"');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions();
+  }
+
+  test_before_import_raw() async {
+    addTestSource('import ^r"p"');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions();
+  }
+
+  test_before_import_raw2() async {
+    addTestSource('import r^"p"');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions();
+  }
+
+  test_export_package2() async {
+    addPackageSource('foo', 'foo.dart', 'library foo;');
+    addPackageSource('foo', 'baz/too.dart', 'library too;');
+    addPackageSource('bar', 'bar.dart', 'library bar;');
+    addTestSource('export "package:foo/baz/^" import');
+    await computeSuggestions();
+    assertSuggest('package:foo/baz/too.dart',
+        csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import() async {
+    addTestSource('import "^"');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import2() async {
+    addTestSource('import "^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_dart() async {
+    addTestSource('import "d^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('dart:core',
+        csKind: CompletionSuggestionKind.IMPORT, relevance: DART_RELEVANCE_LOW);
+    assertNotSuggested('dart:_internal');
+    assertSuggest('dart:async', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('dart:math', csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_dart2() async {
+    addTestSource('import "dart:async"; import "d^"');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('dart:core',
+        csKind: CompletionSuggestionKind.IMPORT, relevance: DART_RELEVANCE_LOW);
+    assertNotSuggested('dart:_internal');
+    assertSuggest('dart:async', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('dart:math', csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_file() async {
+    testFile = '/proj/completion.dart';
+    addSource('/proj/other.dart', 'library other;');
+    addSource('/proj/foo/bar.dart', 'library bar;');
+    addSource('/blat.dart', 'library blat;');
+    addTestSource('import "^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('completion.dart');
+    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo');
+    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_import_file2() async {
+    testFile = '/proj/completion.dart';
+    addSource('/proj/other.dart', 'library other;');
+    addSource('/proj/foo/bar.dart', 'library bar;');
+    addSource('/blat.dart', 'library blat;');
+    addTestSource('import "..^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 2);
+    assertNotSuggested('completion.dart');
+    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo');
+    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_import_file_child() async {
+    testFile = '/proj/completion.dart';
+    addSource('/proj/other.dart', 'library other;');
+    addSource('/proj/foo/bar.dart', 'library bar;');
+    addSource('/blat.dart', 'library blat;');
+    addTestSource('import "foo/^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 4);
+    expect(replacementLength, 4);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_import_file_outside_lib() async {
+    testFile = '/proj/lib/completion.dart';
+    addSource('/proj/lib/other.dart', 'library other;');
+    addSource('/proj/lib/foo/bar.dart', 'library bar;');
+    addSource('/proj/blat.dart', 'library blat;');
+    addSource('/proj/bin/boo.dart', 'library boo;');
+    addTestSource('import "../^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../bin');
+    assertNotSuggested('../bin/');
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_import_file_parent() async {
+    testFile = '/proj/completion.dart';
+    addSource('/proj/other.dart', 'library other;');
+    addSource('/proj/foo/bar.dart', 'library bar;');
+    addSource('/blat.dart', 'library blat;');
+    addSource('/proj2/boo.dart', 'library boo;');
+    addTestSource('import "../^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertNotSuggested('foo/bar.dart');
+    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('../proj2/', csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_file_parent2() async {
+    testFile = '/proj/completion.dart';
+    addSource('/proj/other.dart', 'library other;');
+    addSource('/proj/foo/bar.dart', 'library bar;');
+    addSource('/blat.dart', 'library blat;');
+    addTestSource('import "../b^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 4);
+    expect(replacementLength, 4);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertNotSuggested('foo/bar.dart');
+    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_package() async {
+    addPackageSource('foo', 'foo.dart', 'library foo;');
+    addPackageSource('foo', 'baz/too.dart', 'library too;');
+    addPackageSource('bar', 'bar.dart', 'library bar;');
+    addTestSource('import "p^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:foo/foo.dart',
+        csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:foo/baz/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('package:foo/baz/too.dart');
+    assertSuggest('package:bar/', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:bar/bar.dart',
+        csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_package2() async {
+    addPackageSource('foo', 'foo.dart', 'library foo;');
+    addPackageSource('foo', 'baz/too.dart', 'library too;');
+    addPackageSource('bar', 'bar.dart', 'library bar;');
+    addTestSource('import "package:foo/baz/^" import');
+    await computeSuggestions();
+    assertSuggest('package:foo/baz/too.dart',
+        csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_package2_raw() async {
+    addPackageSource('foo', 'foo.dart', 'library foo;');
+    addPackageSource('foo', 'baz/too.dart', 'library too;');
+    addPackageSource('bar', 'bar.dart', 'library bar;');
+    addTestSource('import r"package:foo/baz/^" import');
+    await computeSuggestions();
+    assertSuggest('package:foo/baz/too.dart',
+        csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_package_missing_lib() async {
+    var pkgSrc = addPackageSource('bar', 'bar.dart', 'library bar;');
+    provider.deleteFolder(dirname(pkgSrc.fullName));
+    addTestSource('import "p^" class');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:bar/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('package:bar/bar.dart');
+  }
+
+  test_import_package_raw() async {
+    addPackageSource('foo', 'foo.dart', 'library foo;');
+    addPackageSource('foo', 'baz/too.dart', 'library too;');
+    addPackageSource('bar', 'bar.dart', 'library bar;');
+    addTestSource('import r"p^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:foo/foo.dart',
+        csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:foo/baz/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('package:foo/baz/too.dart');
+    assertSuggest('package:bar/', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:bar/bar.dart',
+        csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_raw() async {
+    addTestSource('import r"^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_outside_import() async {
+    addTestSource('import ^"d" import');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_outside_import2() async {
+    addTestSource('import "d"^ import');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_part_file() async {
+    testFile = '/proj/completion.dart';
+    addSource('/proj/other.dart', 'library other;');
+    addSource('/proj/foo/bar.dart', 'library bar;');
+    addSource('/blat.dart', 'library blat;');
+    addTestSource('library x; part "^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('completion.dart');
+    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo');
+    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_part_file2() async {
+    testFile = '/proj/completion.dart';
+    addSource('/proj/other.dart', 'library other;');
+    addSource('/proj/foo/bar.dart', 'library bar;');
+    addSource('/blat.dart', 'library blat;');
+    addTestSource('library x; part "..^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 2);
+    assertNotSuggested('completion.dart');
+    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo');
+    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_part_file_child() async {
+    testFile = '/proj/completion.dart';
+    addSource('/proj/other.dart', 'library other;');
+    addSource('/proj/foo/bar.dart', 'library bar;');
+    addSource('/blat.dart', 'library blat;');
+    addTestSource('library x; part "foo/^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 4);
+    expect(replacementLength, 4);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_part_file_parent() async {
+    testFile = '/proj/completion.dart';
+    addSource('/proj/other.dart', 'library other;');
+    addSource('/proj/foo/bar.dart', 'library bar;');
+    addSource('/blat.dart', 'library blat;');
+    addTestSource('library x; part "../^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertNotSuggested('foo/bar.dart');
+    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
+  }
+}
+
+@reflectiveTest
+class UriContributorWindowsTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new UriContributor();
+  }
+
+  @override
+  void setupResourceProvider() {
+    provider = new _TestWinResourceProvider();
+  }
+
+  test_import_file() async {
+    testFile = '\\proj\\completion.dart';
+    addSource('\\proj\\other.dart', 'library other;');
+    addSource('\\proj\\foo\\bar.dart', 'library bar;');
+    addSource('\\blat.dart', 'library blat;');
+    addTestSource('import "^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('completion.dart');
+    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo');
+    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_import_file2() async {
+    testFile = '\\proj\\completion.dart';
+    addSource('\\proj\\other.dart', 'library other;');
+    addSource('\\proj\\foo\\bar.dart', 'library bar;');
+    addSource('\\blat.dart', 'library blat;');
+    addTestSource('import "..^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 2);
+    assertNotSuggested('completion.dart');
+    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo');
+    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_import_file_child() async {
+    testFile = '\\proj\\completion.dart';
+    addSource('\\proj\\other.dart', 'library other;');
+    addSource('\\proj\\foo\\bar.dart', 'library bar;');
+    addSource('\\blat.dart', 'library blat;');
+    addTestSource('import "foo/^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 4);
+    expect(replacementLength, 4);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_import_file_parent() async {
+    testFile = '\\proj\\completion.dart';
+    addSource('\\proj\\other.dart', 'library other;');
+    addSource('\\proj\\foo\\bar.dart', 'library bar;');
+    addSource('\\blat.dart', 'library blat;');
+    addTestSource('import "../^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertNotSuggested('foo/bar.dart');
+    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_import_file_parent2() async {
+    testFile = '\\proj\\completion.dart';
+    addSource('\\proj\\other.dart', 'library other;');
+    addSource('\\proj\\foo\\bar.dart', 'library bar;');
+    addSource('\\blat.dart', 'library blat;');
+    addTestSource('import "../b^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 4);
+    expect(replacementLength, 4);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertNotSuggested('foo/bar.dart');
+    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
+  }
+
+  test_part_file() async {
+    testFile = '\\proj\\completion.dart';
+    addSource('\\proj\\other.dart', 'library other;');
+    addSource('\\proj\\foo\\bar.dart', 'library bar;');
+    addSource('\\blat.dart', 'library blat;');
+    addTestSource('library x; part "^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('completion.dart');
+    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo');
+    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_part_file2() async {
+    testFile = '\\proj\\completion.dart';
+    addSource('\\proj\\other.dart', 'library other;');
+    addSource('\\proj\\foo\\bar.dart', 'library bar;');
+    addSource('\\blat.dart', 'library blat;');
+    addTestSource('library x; part "..^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 2);
+    assertNotSuggested('completion.dart');
+    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo');
+    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_part_file_child() async {
+    testFile = '\\proj\\completion.dart';
+    addSource('\\proj\\other.dart', 'library other;');
+    addSource('\\proj\\foo\\bar.dart', 'library bar;');
+    addSource('\\blat.dart', 'library blat;');
+    addTestSource('library x; part "foo/^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 4);
+    expect(replacementLength, 4);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertNotSuggested('../blat.dart');
+  }
+
+  test_part_file_parent() async {
+    testFile = '\\proj\\completion.dart';
+    addSource('\\proj\\other.dart', 'library other;');
+    addSource('\\proj\\foo\\bar.dart', 'library bar;');
+    addSource('\\blat.dart', 'library blat;');
+    addTestSource('library x; part "../^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertNotSuggested('foo/bar.dart');
+    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
+  }
+}
+
+class _TestWinResourceProvider extends MemoryResourceProvider {
+  @override
+  Context get pathContext => windows;
+}
diff --git a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
deleted file mode 100644
index 95cbb70..0000000
--- a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
+++ /dev/null
@@ -1,874 +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 test.services.completion.toplevel;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_context.dart';
-import '../../operation/operation_queue_test.dart';
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(ImportedReferenceContributorTest);
-}
-
-@reflectiveTest
-class ImportedReferenceContributorTest extends AbstractSelectorSuggestionTest {
-  void assertCached(String completion) {
-    DartCompletionCache cache = request.cache;
-    if (!isCached(cache.importedTypeSuggestions, completion) &&
-        !isCached(cache.importedVoidReturnSuggestions, completion) &&
-        !isCached(cache.libraryPrefixSuggestions, completion) &&
-        !isCached(cache.otherImportedSuggestions, completion)) {
-      fail('expected $completion to be cached');
-    }
-  }
-
-  /**
-   * Assert that the ImportedReferenceContributor uses cached results
-   * to produce identical suggestions to the original set of suggestions.
-   */
-  @override
-  assertCachedCompute(_) {
-    if (!(contributor as ImportedReferenceContributor)
-        .shouldWaitForLowPrioritySuggestions) {
-      return null;
-    }
-    List<CompletionSuggestion> oldSuggestions = request.suggestions;
-    /*
-     * Simulate a source change to flush the cached compilation unit
-     */
-    ChangeSet changes = new ChangeSet();
-    changes.addedSource(testSource);
-    context.applyChanges(changes);
-    /*
-     * Calculate a new completion at the same location
-     */
-    setUpContributor();
-    int replacementOffset = request.replacementOffset;
-    int replacementLength = request.replacementLength;
-    AnalysisServer server = new AnalysisServerMock();
-    /*
-     * Pass null for searchEngine to ensure that it is not used
-     * when the cache has been populated.
-     */
-    request = new DartCompletionRequest(
-        server, context, testSource, completionOffset, cache);
-    request.replacementOffset = replacementOffset;
-    request.replacementLength = replacementLength;
-
-    void assertResultsFromCache(List<CompletionSuggestion> oldSuggestions) {
-      List<CompletionSuggestion> newSuggestions = request.suggestions;
-      if (newSuggestions.length == oldSuggestions.length) {
-        if (!oldSuggestions
-            .any((CompletionSuggestion s) => !newSuggestions.contains(s))) {
-          return;
-        }
-      }
-      StringBuffer sb = new StringBuffer(
-          'suggestions based upon cached results do not match expectations');
-      sb.write('\n  Expected:');
-      oldSuggestions.toList()
-        ..sort(suggestionComparator)
-        ..forEach((CompletionSuggestion suggestion) {
-          sb.write('\n    ${suggestion.completion} -> $suggestion');
-        });
-      sb.write('\n  Actual:');
-      newSuggestions.toList()
-        ..sort(suggestionComparator)
-        ..forEach((CompletionSuggestion suggestion) {
-          sb.write('\n    ${suggestion.completion} -> $suggestion');
-        });
-      fail(sb.toString());
-    }
-
-    computeFastResult = null;
-    if (computeFast()) {
-      expect(request.unit.element, isNull);
-      assertResultsFromCache(oldSuggestions);
-    } else {
-      // Results from cache might need to be adjusted
-      // if target is a function argument in an argument list
-      resolve(false);
-      return contributor.computeFull(request).then((bool result) {
-        expect(result, isTrue);
-        expect(request.unit.element, isNotNull);
-        assertResultsFromCache(oldSuggestions);
-      });
-    }
-  }
-
-  void assertNotCached(String completion) {
-    DartCompletionCache cache = request.cache;
-    if (isCached(cache.importedTypeSuggestions, completion) ||
-        isCached(cache.importedVoidReturnSuggestions, completion) ||
-        isCached(cache.libraryPrefixSuggestions, completion) ||
-        isCached(cache.otherImportedSuggestions, completion)) {
-      fail('expected $completion NOT to be cached');
-    }
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedClass(String name,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      String elemFile}) {
-    return assertSuggestClass(name,
-        relevance: relevance,
-        kind: kind,
-        importUri: importUri,
-        elemFile: elemFile);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedConstructor(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT, String importUri}) {
-    return assertSuggestConstructor(name,
-        relevance: relevance, importUri: importUri);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedField(String name, String type,
-      {int relevance: DART_RELEVANCE_INHERITED_FIELD, String importUri}) {
-    return assertSuggestField(name, type,
-        relevance: relevance, importUri: importUri);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedFunction(
-      String name, String returnType,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool deprecated: false,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri}) {
-    return assertSuggestFunction(name, returnType,
-        kind: kind,
-        deprecated: deprecated,
-        relevance: relevance,
-        importUri: importUri);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedFunctionTypeAlias(
-      String name, String returnType,
-      [bool isDeprecated = false,
-      int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    return assertSuggestFunctionTypeAlias(
-        name, returnType, isDeprecated, relevance, kind, importUri);
-  }
-
-  CompletionSuggestion assertSuggestImportedGetter(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR, String importUri}) {
-    return assertSuggestGetter(name, returnType,
-        relevance: relevance, importUri: importUri);
-  }
-
-  CompletionSuggestion assertSuggestImportedMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_INHERITED_METHOD, String importUri}) {
-    return assertSuggestMethod(name, declaringType, returnType,
-        relevance: relevance, importUri: importUri);
-  }
-
-  CompletionSuggestion assertSuggestImportedSetter(String name,
-      {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR, String importUri}) {
-    return assertSuggestSetter(name, relevance, importUri);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedTopLevelVar(
-      String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    return assertSuggestTopLevelVar(
-        name, returnType, relevance, kind, importUri);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLibraryPrefix(String prefix,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    CompletionSuggestion cs =
-        assertSuggest(prefix, csKind: kind, relevance: relevance);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.LIBRARY));
-    expect(element.parameters, isNull);
-    expect(element.returnType, isNull);
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  fail_enum_deprecated() {
-    addSource('/libA.dart', 'library A; @deprecated enum E { one, two }');
-    addTestSource('import "/libA.dart"; main() {^}');
-    return computeFull((bool result) {
-      // TODO(danrube) investigate why suggestion/element is not deprecated
-      // when AST node has correct @deprecated annotation
-      assertSuggestEnum('E', isDeprecated: true);
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-    });
-  }
-
-  bool isCached(List<CompletionSuggestion> suggestions, String completion) =>
-      suggestions.any((CompletionSuggestion s) => s.completion == completion);
-
-  @override
-  void setUpContributor() {
-    contributor = new ImportedReferenceContributor(
-        shouldWaitForLowPrioritySuggestions: true);
-  }
-
-  @override
-  test_ArgumentList() {
-    return super.test_ArgumentList().then((_) {
-      expect(request.cache.importKey, "import '/libA.dart';");
-      ClassElement objClassElem1 = request.cache.importedClassMap['Object'];
-      expect(objClassElem1, isNotNull);
-      ClassElement objClassElem2 = request.cache.objectClassElement;
-      expect(objClassElem1, same(objClassElem2));
-    });
-  }
-
-  @override
-  test_ArgumentList_imported_function() {
-    return super.test_ArgumentList_imported_function().then((_) {
-      expect(request.cache.importKey, "import '/libA.dart';");
-    });
-  }
-
-  @override
-  test_AssignmentExpression_RHS() {
-    return super.test_AssignmentExpression_RHS().then((_) {
-      expect(request.cache.importKey, '');
-    });
-  }
-
-  @override
-  test_Block() {
-    return super.test_Block().then((_) {
-      expect(request.cache.importKey,
-          'import "/testAB.dart";import "/testCD.dart" hide D;import "/testEEF.dart" show EE;import "/testG.dart" as g;');
-      assertCached('A');
-      assertCached('T3');
-    });
-  }
-
-  @override
-  test_Block_inherited_imported() {
-    return super.test_Block_inherited_imported().then((_) {
-      assertCached('E');
-      assertCached('F');
-      assertNotCached('e1');
-      assertNotCached('i2');
-      assertNotCached('m1');
-      assertNotCached('_pf');
-    });
-  }
-
-  test_Block_partial_results() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      Z D2() {int x;}
-      class X {a() {var f; {var x;} ^ var r;} void b() { }}
-      class Z { }''');
-    ImportedReferenceContributor contributor = this.contributor;
-    contributor.shouldWaitForLowPrioritySuggestions = false;
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('C');
-      // Assert contributor does not wait for or include low priority results
-      // from non-imported libraries unless instructed to do so.
-      assertNotSuggested('H');
-    });
-  }
-
-  test_enum() {
-    addSource('/libA.dart', 'library A; enum E { one, two }');
-    addTestSource('import "/libA.dart"; main() {^}');
-    return computeFull((bool result) {
-      assertSuggestEnum('E');
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-    });
-  }
-
-  test_function_parameters_mixed_required_and_named() {
-    addSource(
-        '/libA.dart',
-        '''
-void m(x, {int y}) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_function_parameters_mixed_required_and_positional() {
-    addSource(
-        '/libA.dart',
-        '''
-void m(x, [int y]) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_function_parameters_named() {
-    addSource(
-        '/libA.dart',
-        '''
-void m({x, int y}) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_function_parameters_none() {
-    addSource(
-        '/libA.dart',
-        '''
-void m() {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, isEmpty);
-      expect(suggestion.parameterTypes, isEmpty);
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_function_parameters_positional() {
-    addSource(
-        '/libA.dart',
-        '''
-void m([x, int y]) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_function_parameters_required() {
-    addSource(
-        '/libA.dart',
-        '''
-void m(x, int y) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 2);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_inComment_endOfLine() {
-    addTestSource('''
-main() {
-  // text ^
-}
-''');
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_InstanceCreationExpression() {
-    addSource(
-        '/testA.dart',
-        '''
-class A {foo(){var f; {var x;}}}
-class B {B(this.x, [String boo]) { } int x;}
-class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
-    addTestSource('''
-import "/testA.dart";
-import "dart:math" as math;
-main() {new ^ String x = "hello";}''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion;
-
-      suggestion = assertSuggestImportedConstructor('Object');
-      expect(suggestion.element.parameters, '()');
-      expect(suggestion.parameterNames, hasLength(0));
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestImportedConstructor('A');
-      expect(suggestion.element.parameters, '()');
-      expect(suggestion.parameterNames, hasLength(0));
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestImportedConstructor('B');
-      expect(suggestion.element.parameters, '(int x, [String boo])');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'int');
-      expect(suggestion.parameterNames[1], 'boo');
-      expect(suggestion.parameterTypes[1], 'String');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestImportedConstructor('C.bar');
-      expect(suggestion.element.parameters, "({dynamic boo: 'hoo', int z: 0})");
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'boo');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'z');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-
-      assertSuggestLibraryPrefix('math');
-    });
-  }
-
-  test_internal_sdk_libs() {
-    addTestSource('main() {p^}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggest('print');
-      assertSuggest('pow',
-          relevance: DART_RELEVANCE_LOW, importUri: 'dart:math');
-      // Do not suggest completions from internal SDK library
-      assertNotSuggested('printToConsole');
-    });
-  }
-
-  test_method_parameters_mixed_required_and_named() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m(x, {int y}) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_mixed_required_and_positional() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m(x, [int y]) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_named() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m({x, int y}) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_none() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m() {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, isEmpty);
-      expect(suggestion.parameterTypes, isEmpty);
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_positional() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m([x, int y]) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_required() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m(x, int y) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 2);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_mixin_ordering() {
-    addSource(
-        '/libA.dart',
-        '''
-class B {}
-class M1 {
-  void m() {}
-}
-class M2 {
-  void m() {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class C extends B with M1, M2 {
-  void f() {
-    ^
-  }
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestImportedMethod('m', 'M2', 'void');
-    });
-  }
-
-  /**
-   * Ensure that completions in one context don't appear in another
-   */
-  test_multiple_contexts() {
-    // Create a 2nd context with source
-    var context2 = AnalysisEngine.instance.createAnalysisContext();
-    context2.sourceFactory =
-        new SourceFactory([AbstractContextTest.SDK_RESOLVER, resourceResolver]);
-    String content2 = 'class ClassFromAnotherContext { }';
-    Source source2 =
-        provider.newFile('/context2/foo.dart', content2).createSource();
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source2);
-    context2.applyChanges(changeSet);
-    context2.setContents(source2, content2);
-
-    // Resolve the source in the 2nd context and update the index
-    var result = context2.performAnalysisTask();
-    while (result.hasMoreWork) {
-      result.changeNotices.forEach((ChangeNotice notice) {
-        CompilationUnit unit = notice.resolvedDartUnit;
-        if (unit != null) {
-          index.index(context2, unit);
-        }
-      });
-      result = context2.performAnalysisTask();
-    }
-
-    // Check that source in 2nd context does not appear in completion in 1st
-    addSource(
-        '/context1/libA.dart',
-        '''
-      library libA;
-      class ClassInLocalContext {int x;}''');
-    testFile = '/context1/completionTest.dart';
-    addTestSource('''
-      import "/context1/libA.dart";
-      import "/foo.dart";
-      main() {C^}
-      ''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('ClassInLocalContext');
-      // Assert contributor does not include results from 2nd context.
-      assertNotSuggested('ClassFromAnotherContext');
-    });
-  }
-
-  test_no_parameters_field() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  int x;
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestImportedField('x', 'int');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_no_parameters_getter() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  int get x => null;
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestImportedGetter('x', 'int');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_no_parameters_setter() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  set x(int value) {};
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestImportedSetter('x');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  @override
-  test_partFile_TypeName() {
-    return super.test_partFile_TypeName().then((_) {
-      expect(request.cache.importKey, 'part of libA;');
-    });
-  }
-
-  @override
-  test_partFile_TypeName2() {
-    return super.test_partFile_TypeName2().then((_) {
-      expect(request.cache.importKey,
-          'library libA;import "/testB.dart";part "/testA.dart";');
-    });
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/inherited_computer_test.dart b/pkg/analysis_server/test/services/completion/inherited_computer_test.dart
deleted file mode 100644
index a50fa2f..0000000
--- a/pkg/analysis_server/test/services/completion/inherited_computer_test.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.completion.inherited_computer_test;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/inherited_contributor.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/src/matcher/core_matchers.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-//  defineReflectiveTests(InheritedContributorTest);
-}
-
-@reflectiveTest
-class InheritedContributorTest extends AbstractCompletionTest {
-  @override
-  void setUpContributor() {
-    contributor = new NewCompletionWrapper(new InheritedContributor());
-  }
-
-  test_fromMultipleSuperclasses() {
-    addTestSource(r'''
-class A {
-  notSuggested() => null;
-  A suggested1(int x) => null;
-  B suggested2(String y) => null;
-}
-class B extends A {
-  B suggested2(String y) => null;
-  C suggested3([String z]) => null;
-}
-class C extends B {
-  sugg^
-}
-''');
-    computeFast();
-    return computeFull((bool result) {
-      _assertOverride(
-          '@override\n  A suggested1(int x) {\n    // TODO: implement suggested1\n    return null;\n  }');
-      _assertOverride(
-          '''@override\n  B suggested2(String y) {\n    // TODO: implement suggested2\n    return null;\n  }''');
-      _assertOverride(
-          '''@override\n  C suggested3([String z]) {\n    // TODO: implement suggested3\n    return null;\n  }''');
-      assertNotSuggested(
-          '''@override\n  notSuggested() {\n    // TODO: implement notSuggested\n    return null;\n  }''');
-    });
-  }
-
-  CompletionSuggestion _assertOverride(String completion) {
-    CompletionSuggestion cs = getSuggest(
-        completion: completion,
-        csKind: CompletionSuggestionKind.IDENTIFIER,
-        elemKind: null);
-    if (cs == null) {
-      failedCompletion('expected $completion', request.suggestions);
-    }
-    expect(cs.kind, equals(CompletionSuggestionKind.IDENTIFIER));
-    expect(cs.relevance, equals(DART_RELEVANCE_HIGH));
-    expect(cs.importUri, null);
-//    expect(cs.selectionOffset, equals(completion.length));
-    expect(cs.selectionLength, equals(0));
-    expect(cs.isDeprecated, isFalse);
-    expect(cs.isPotential, isFalse);
-    expect(cs.element, isNotNull);
-    return cs;
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/keyword_contributor_test.dart
deleted file mode 100644
index 4a2085f..0000000
--- a/pkg/analysis_server/test/services/completion/keyword_contributor_test.dart
+++ /dev/null
@@ -1,1424 +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 test.services.completion.dart.keyword;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/keyword_contributor.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(KeywordContributorTest);
-}
-
-@reflectiveTest
-class KeywordContributorTest extends AbstractCompletionTest {
-  static const List<Keyword> CLASS_BODY_KEYWORDS = const [
-    Keyword.CONST,
-    Keyword.DYNAMIC,
-    Keyword.FACTORY,
-    Keyword.FINAL,
-    Keyword.GET,
-    Keyword.OPERATOR,
-    Keyword.SET,
-    Keyword.STATIC,
-    Keyword.VAR,
-    Keyword.VOID
-  ];
-
-  static const List<Keyword> DECLARATION_KEYWORDS = const [
-    Keyword.ABSTRACT,
-    Keyword.CLASS,
-    Keyword.CONST,
-    Keyword.DYNAMIC,
-    Keyword.FINAL,
-    Keyword.TYPEDEF,
-    Keyword.VAR,
-    Keyword.VOID
-  ];
-
-  static const List<Keyword> DIRECTIVE_AND_DECLARATION_KEYWORDS = const [
-    Keyword.ABSTRACT,
-    Keyword.CLASS,
-    Keyword.CONST,
-    Keyword.DYNAMIC,
-    Keyword.EXPORT,
-    Keyword.FINAL,
-    Keyword.IMPORT,
-    Keyword.PART,
-    Keyword.TYPEDEF,
-    Keyword.VAR,
-    Keyword.VOID
-  ];
-
-  static const List<Keyword> DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS =
-      const [
-    Keyword.ABSTRACT,
-    Keyword.CLASS,
-    Keyword.CONST,
-    Keyword.DYNAMIC,
-    Keyword.EXPORT,
-    Keyword.FINAL,
-    Keyword.IMPORT,
-    Keyword.LIBRARY,
-    Keyword.PART,
-    Keyword.TYPEDEF,
-    Keyword.VAR,
-    Keyword.VOID
-  ];
-
-  static const List<String> NO_PSEUDO_KEYWORDS = const [];
-
-  static const List<Keyword> STMT_START_IN_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.CONST,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SUPER,
-    Keyword.SWITCH,
-    Keyword.THIS,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_IN_LOOP_IN_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.BREAK,
-    Keyword.CONST,
-    Keyword.CONTINUE,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SUPER,
-    Keyword.SWITCH,
-    Keyword.THIS,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_IN_SWITCH_IN_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.BREAK,
-    Keyword.CASE,
-    Keyword.CONST,
-    Keyword.DEFAULT,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SUPER,
-    Keyword.SWITCH,
-    Keyword.THIS,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_IN_SWITCH_OUTSIDE_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.BREAK,
-    Keyword.CASE,
-    Keyword.CONST,
-    Keyword.DEFAULT,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SWITCH,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_OUTSIDE_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.CONST,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SWITCH,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_IN_LOOP_OUTSIDE_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.BREAK,
-    Keyword.CONST,
-    Keyword.CONTINUE,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SWITCH,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> EXPRESSION_START_INSTANCE = const [
-    Keyword.CONST,
-    Keyword.FALSE,
-    Keyword.NEW,
-    Keyword.NULL,
-    Keyword.SUPER,
-    Keyword.THIS,
-    Keyword.TRUE,
-  ];
-
-  static const List<Keyword> EXPRESSION_START_NO_INSTANCE = const [
-    Keyword.CONST,
-    Keyword.FALSE,
-    Keyword.NEW,
-    Keyword.NULL,
-    Keyword.TRUE,
-  ];
-
-  void assertSuggestKeywords(Iterable<Keyword> expectedKeywords,
-      {List<String> pseudoKeywords: NO_PSEUDO_KEYWORDS,
-      int relevance: DART_RELEVANCE_KEYWORD}) {
-    Set<String> expectedCompletions = new Set<String>();
-    Map<String, int> expectedOffsets = <String, int>{};
-    Set<String> actualCompletions = new Set<String>();
-    expectedCompletions.addAll(expectedKeywords.map((k) => k.syntax));
-    expectedCompletions.addAll(pseudoKeywords);
-    for (CompletionSuggestion s in request.suggestions) {
-      if (s.kind == CompletionSuggestionKind.KEYWORD) {
-        Keyword k = Keyword.keywords[s.completion];
-        if (k == null && !expectedCompletions.contains(s.completion)) {
-          fail('Invalid keyword suggested: ${s.completion}');
-        } else {
-          if (!actualCompletions.add(s.completion)) {
-            fail('Duplicate keyword suggested: ${s.completion}');
-          }
-        }
-      }
-    }
-    if (!_equalSets(expectedCompletions, actualCompletions)) {
-      StringBuffer msg = new StringBuffer();
-      msg.writeln('Expected:');
-      _appendCompletions(msg, expectedCompletions, actualCompletions);
-      msg.writeln('but found:');
-      _appendCompletions(msg, actualCompletions, expectedCompletions);
-      fail(msg.toString());
-    }
-    for (CompletionSuggestion s in request.suggestions) {
-      if (s.kind == CompletionSuggestionKind.KEYWORD) {
-        if (s.completion.startsWith(Keyword.IMPORT.syntax)) {
-          int importRelevance = relevance;
-          if (importRelevance == DART_RELEVANCE_HIGH &&
-              s.completion == "import '';") {
-            ++importRelevance;
-          }
-          expect(s.relevance, equals(importRelevance), reason: s.completion);
-        } else {
-          if (s.completion == Keyword.RETHROW.syntax) {
-            expect(s.relevance, equals(relevance - 1), reason: s.completion);
-          } else {
-            expect(s.relevance, equals(relevance), reason: s.completion);
-          }
-        }
-        int expectedOffset = expectedOffsets[s.completion];
-        if (expectedOffset == null) {
-          expectedOffset = s.completion.length;
-        }
-        expect(s.selectionOffset, equals(expectedOffset));
-        expect(s.selectionLength, equals(0));
-        expect(s.isDeprecated, equals(false));
-        expect(s.isPotential, equals(false));
-      }
-    }
-  }
-
-  fail_import_partial() {
-    addTestSource('imp^ import "package:foo/foo.dart"; import "bar.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertNotSuggested('class');
-  }
-
-  fail_import_partial4() {
-    addTestSource('^ imp import "package:foo/foo.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertNotSuggested('class');
-  }
-
-  fail_import_partial5() {
-    addTestSource('library libA; imp^ import "package:foo/foo.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertNotSuggested('class');
-  }
-
-  fail_import_partial6() {
-    addTestSource(
-        'library bar; import "zoo.dart"; imp^ import "package:foo/foo.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertNotSuggested('class');
-  }
-
-  @override
-  void setUpContributor() {
-    contributor = new KeywordContributor();
-  }
-
-  test_after_class() {
-    addTestSource('class A {} ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DECLARATION_KEYWORDS, relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_after_class2() {
-    addTestSource('class A {} c^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DECLARATION_KEYWORDS, relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_after_import() {
-    addTestSource('import "foo"; ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_after_import2() {
-    addTestSource('import "foo"; c^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_anonymous_function_async() {
-    addTestSource('main() {foo(() ^ {}}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([],
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_anonymous_function_async2() {
-    addTestSource('main() {foo(() a^ {}}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['async']);
-  }
-
-  test_anonymous_function_async3() {
-    addTestSource('main() {foo(() async ^ {}}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_argument() {
-    addTestSource('main() {foo(^);}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_argument2() {
-    addTestSource('main() {foo(n^);}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_argument_literal() {
-    addTestSource('main() {foo("^");}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_argument_named() {
-    addTestSource('main() {foo(bar: ^);}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_argument_named2() {
-    addTestSource('main() {foo(bar: n^);}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_argument_named_literal() {
-    addTestSource('main() {foo(bar: "^");}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_assignment_field() {
-    addTestSource('class A {var foo = ^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_assignment_field2() {
-    addTestSource('class A {var foo = n^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_assignment_local() {
-    addTestSource('main() {var foo = ^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_assignment_local2() {
-    addTestSource('main() {var foo = n^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_assignment_local2_async() {
-    addTestSource('main() async {var foo = n^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
-        pseudoKeywords: ['await']);
-  }
-
-  test_assignment_local_async() {
-    addTestSource('main() async {var foo = ^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
-        pseudoKeywords: ['await']);
-  }
-
-  test_before_import() {
-    addTestSource('^ import foo;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(
-        [Keyword.EXPORT, Keyword.IMPORT, Keyword.LIBRARY, Keyword.PART],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_catch() {
-    addTestSource('main() {try {} catch (e) {^}}}');
-    expect(computeFast(), isTrue);
-    var keywords = <Keyword>[];
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
-    keywords.add(Keyword.RETHROW);
-    assertSuggestKeywords(keywords, relevance: DART_RELEVANCE_KEYWORD);
-  }
-
-  test_class() {
-    addTestSource('class A e^ { }');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_body() {
-    addTestSource('class A {^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
-  }
-
-  test_class_body_beginning() {
-    addTestSource('class A {^ var foo;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
-  }
-
-  test_class_body_between() {
-    addTestSource('class A {var bar; ^ var foo;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
-  }
-
-  test_class_body_end() {
-    addTestSource('class A {var foo; ^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
-  }
-
-  test_class_extends() {
-    addTestSource('class A extends foo ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_extends2() {
-    addTestSource('class A extends foo i^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_extends3() {
-    addTestSource('class A extends foo i^ { }');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_extends_name() {
-    addTestSource('class A extends ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_class_implements() {
-    addTestSource('class A ^ implements foo');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.EXTENDS], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_implements2() {
-    addTestSource('class A e^ implements foo');
-    expect(computeFast(), isTrue);
-    // TODO (danrubel) refinement: don't suggest implements
-    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_implements3() {
-    addTestSource('class A e^ implements foo { }');
-    expect(computeFast(), isTrue);
-    // TODO (danrubel) refinement: don't suggest implements
-    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_implements_name() {
-    addTestSource('class A implements ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_class_name() {
-    addTestSource('class ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_class_noBody() {
-    addTestSource('class A ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_noBody2() {
-    addTestSource('class A e^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_noBody3() {
-    addTestSource('class A e^ String foo;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_with() {
-    addTestSource('class A extends foo with bar ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.IMPLEMENTS], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_with2() {
-    addTestSource('class A extends foo with bar i^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.IMPLEMENTS], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_with3() {
-    addTestSource('class A extends foo with bar i^ { }');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.IMPLEMENTS], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_class_with_name() {
-    addTestSource('class A extends foo with ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_constructor_param() {
-    addTestSource('class A { A(^) {});}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.THIS]);
-  }
-
-  test_constructor_param2() {
-    addTestSource('class A { A(t^) {});}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.THIS]);
-  }
-
-  test_do_break_continue() {
-    addTestSource('main() {do {^} while (true);}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS,
-        relevance: DART_RELEVANCE_KEYWORD);
-  }
-
-  test_do_break_continue2() {
-    addTestSource('class A {foo() {do {^} while (true);}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS,
-        relevance: DART_RELEVANCE_KEYWORD);
-  }
-
-  test_empty() {
-    addTestSource('^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_for_break_continue() {
-    addTestSource('main() {for (int x in myList) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS,
-        relevance: DART_RELEVANCE_KEYWORD);
-  }
-
-  test_for_break_continue2() {
-    addTestSource('class A {foo() {for (int x in myList) {^}}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS,
-        relevance: DART_RELEVANCE_KEYWORD);
-  }
-
-  test_for_expression_in() {
-    addTestSource('main() {for (int x i^)}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.IN], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_for_expression_in2() {
-    addTestSource('main() {for (int x in^)}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.IN], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_for_expression_init() {
-    addTestSource('main() {for (int x = i^)}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_for_expression_init2() {
-    addTestSource('main() {for (int x = in^)}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_function_async() {
-    addTestSource('main()^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DECLARATION_KEYWORDS,
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_function_async2() {
-    addTestSource('main()^{}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([],
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_function_async3() {
-    addTestSource('main()a^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DECLARATION_KEYWORDS,
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_function_async4() {
-    addTestSource('main()a^{}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DECLARATION_KEYWORDS,
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_function_async5() {
-    addTestSource('main()a^ Foo foo;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DECLARATION_KEYWORDS,
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_function_body_inClass_constructorInitializer() {
-    addTestSource(r'''
-foo(p) {}
-class A {
-  final f;
-  A() : f = foo(() {^});
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
-  }
-
-  test_function_body_inClass_constructorInitializer_async() {
-    addTestSource(r'''
-foo(p) {}
-class A {
-  final f;
-  A() : f = foo(() async {^});
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
-  }
-
-  test_function_body_inClass_field() {
-    addTestSource(r'''
-class A {
-  var f = () {^};
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
-  }
-
-  test_function_body_inClass_methodBody() {
-    addTestSource(r'''
-class A {
-  m() {
-    f() {^};
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_CLASS);
-  }
-
-  test_function_body_inClass_methodBody_inFunction() {
-    addTestSource(r'''
-class A {
-  m() {
-    f() {
-      f2() {^};
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_CLASS);
-  }
-
-  test_function_body_inClass_methodBody_inFunction_async() {
-    addTestSource(r'''
-class A {
-  m() {
-    f() {
-      f2() async {^};
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
-  }
-
-  test_function_body_inUnit() {
-    addTestSource('main() {^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
-  }
-
-  test_function_body_inUnit_afterBlock() {
-    addTestSource('main() {{}^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
-  }
-
-  test_function_body_inUnit_async() {
-    addTestSource('main() async {^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
-  }
-
-  test_if_expression_in_class() {
-    addTestSource('class A {foo() {if (^) }}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
-  }
-
-  test_if_expression_in_class2() {
-    addTestSource('class A {foo() {if (n^) }}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
-  }
-
-  test_if_expression_in_function() {
-    addTestSource('foo() {if (^) }');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_if_expression_in_function2() {
-    addTestSource('foo() {if (n^) }');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_if_in_class() {
-    addTestSource('class A {foo() {if (true) ^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_CLASS);
-  }
-
-  test_if_in_class2() {
-    addTestSource('class A {foo() {if (true) ^;}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_CLASS);
-  }
-
-  test_if_in_class3() {
-    addTestSource('class A {foo() {if (true) r^;}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_CLASS);
-  }
-
-  test_if_in_class4() {
-    addTestSource('class A {foo() {if (true) ^ go();}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_CLASS);
-  }
-
-  test_if_outside_class() {
-    addTestSource('foo() {if (true) ^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
-  }
-
-  test_if_outside_class2() {
-    addTestSource('foo() {if (true) ^;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
-  }
-
-  test_if_outside_class3() {
-    addTestSource('foo() {if (true) r^;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
-  }
-
-  test_if_outside_class4() {
-    addTestSource('foo() {if (true) ^ go();}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
-  }
-
-  test_import() {
-    addTestSource('import "foo" deferred as foo ^;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([],
-        pseudoKeywords: ['show', 'hide'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_as() {
-    addTestSource('import "foo" deferred ^;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_as2() {
-    addTestSource('import "foo" deferred a^;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_as3() {
-    addTestSource('import "foo" deferred a^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred() {
-    addTestSource('import "foo" ^ as foo;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.DEFERRED], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred2() {
-    addTestSource('import "foo" d^ as foo;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.DEFERRED], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred3() {
-    addTestSource('import "foo" d^ show foo;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS],
-        pseudoKeywords: ['deferred as'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred4() {
-    addTestSource('import "foo" d^ hide foo;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS],
-        pseudoKeywords: ['deferred as'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred5() {
-    addTestSource('import "foo" d^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS],
-        pseudoKeywords: ['deferred as', 'show', 'hide'],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred6() {
-    addTestSource('import "foo" d^ import');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS],
-        pseudoKeywords: ['deferred as', 'show', 'hide'],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred_as() {
-    addTestSource('import "foo" ^;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS],
-        pseudoKeywords: ['deferred as', 'show', 'hide'],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred_as2() {
-    addTestSource('import "foo" d^;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS],
-        pseudoKeywords: ['deferred as', 'show', 'hide'],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred_as3() {
-    addTestSource('import "foo" ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS],
-        pseudoKeywords: ['deferred as', 'show', 'hide'],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred_as4() {
-    addTestSource('import "foo" d^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS],
-        pseudoKeywords: ['deferred as', 'show', 'hide'],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred_as5() {
-    addTestSource('import "foo" sh^ import "bar"; import "baz";');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.AS],
-        pseudoKeywords: ['deferred as', 'show', 'hide'],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred_not() {
-    addTestSource('import "foo" as foo ^;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([],
-        pseudoKeywords: ['show', 'hide'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_import_deferred_partial() {
-    addTestSource('import "package:foo/foo.dart" def^ as foo;');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.DEFERRED], relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 30);
-    expect(request.replacementLength, 3);
-  }
-
-  test_import_incomplete() {
-    addTestSource('import "^"');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_import_partial() {
-    addTestSource('imp^ import "package:foo/foo.dart"; import "bar.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 0);
-    expect(request.replacementLength, 3);
-  }
-
-  test_import_partial2() {
-    addTestSource('^imp import "package:foo/foo.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 0);
-    expect(request.replacementLength, 3);
-  }
-
-  test_import_partial3() {
-    addTestSource(' ^imp import "package:foo/foo.dart"; import "bar.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 1);
-    expect(request.replacementLength, 3);
-  }
-
-  test_import_partial4() {
-    addTestSource('^ imp import "package:foo/foo.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 0);
-    expect(request.replacementLength, 0);
-  }
-
-  test_import_partial5() {
-    addTestSource('library libA; imp^ import "package:foo/foo.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 14);
-    expect(request.replacementLength, 3);
-  }
-
-  test_import_partial6() {
-    addTestSource(
-        'library bar; import "zoo.dart"; imp^ import "package:foo/foo.dart";');
-    expect(computeFast(), isTrue);
-    // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 32);
-    expect(request.replacementLength, 3);
-  }
-
-  test_inComment_block() {
-    addTestSource('''
-main() {
-  /* text ^ */
-  print(42);
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_inComment_endOfLine() {
-    addTestSource('''
-main() {
-  // text ^
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_is_expression() {
-    addTestSource('main() {if (x is^)}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_library() {
-    addTestSource('library foo;^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_library_declaration() {
-    addTestSource('library ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_library_declaration2() {
-    addTestSource('library a^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_library_declaration3() {
-    addTestSource('library a.^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_library_name() {
-    addTestSource('library ^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_method_async() {
-    addTestSource('class A { foo() ^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
-  }
-
-  test_method_async2() {
-    addTestSource('class A { foo() ^{}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([],
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_method_async3() {
-    addTestSource('class A { foo() a^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
-  }
-
-  test_method_async4() {
-    addTestSource('class A { foo() a^{}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
-  }
-
-  test_method_async5() {
-    addTestSource('class A { foo() ^ Foo foo;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
-  }
-
-  test_method_async6() {
-    addTestSource('class A { foo() a^ Foo foo;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
-  }
-
-  test_method_async7() {
-    addTestSource('class A { foo() ^ => Foo foo;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([],
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_method_async8() {
-    addTestSource('class A { foo() a^ Foo foo;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
-  }
-
-  test_method_body() {
-    addTestSource('class A { foo() {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_CLASS);
-  }
-
-  test_method_body2() {
-    addTestSource('class A { foo() => ^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
-  }
-
-  test_method_body3() {
-    addTestSource('class A { foo() => ^ Foo foo;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
-  }
-
-  test_method_body4() {
-    addTestSource('class A { foo() => ^;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
-  }
-
-  test_method_body_async() {
-    addTestSource('class A { foo() async {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
-  }
-
-  test_method_body_async2() {
-    addTestSource('class A { foo() async => ^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']);
-  }
-
-  test_method_body_async3() {
-    addTestSource('class A { foo() async => ^ Foo foo;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']);
-  }
-
-  test_method_body_async4() {
-    addTestSource('class A { foo() async => ^;}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']);
-  }
-
-  test_method_body_expression1() {
-    addTestSource('class A { foo() {return b == true ? ^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
-  }
-
-  test_method_body_expression2() {
-    addTestSource('class A { foo() {return b == true ? 1 : ^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
-  }
-
-  test_method_body_return() {
-    addTestSource('class A { foo() {return ^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_INSTANCE);
-  }
-
-  test_method_param() {
-    addTestSource('class A { foo(^) {});}');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_method_param2() {
-    addTestSource('class A { foo(t^) {});}');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_named_constructor_invocation() {
-    addTestSource('void main() {new Future.^}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_newInstance() {
-    addTestSource('class A { foo() {new ^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_newInstance2() {
-    addTestSource('class A { foo() {new ^ print("foo");}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_newInstance_prefixed() {
-    addTestSource('class A { foo() {new A.^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_newInstance_prefixed2() {
-    addTestSource('class A { foo() {new A.^ print("foo");}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_part_of() {
-    addTestSource('part of foo;^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_partial_class() {
-    addTestSource('cl^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_partial_class2() {
-    addTestSource('library a; cl^');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_prefixed_field() {
-    addTestSource('class A { int x; foo() {x.^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_prefixed_field2() {
-    addTestSource('class A { int x; foo() {x.^ print("foo");}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_prefixed_library() {
-    addTestSource('import "b" as b; class A { foo() {b.^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_prefixed_local() {
-    addTestSource('class A { foo() {int x; x.^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_prefixed_local2() {
-    addTestSource('class A { foo() {int x; x.^ print("foo");}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_property_access() {
-    addTestSource('class A { get x => 7; foo() {new A().^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([]);
-  }
-
-  test_switch_expression() {
-    addTestSource('main() {switch(^) {}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_switch_expression2() {
-    addTestSource('main() {switch(n^) {}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_switch_expression3() {
-    addTestSource('main() {switch(n^)}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
-  }
-
-  test_switch_start() {
-    addTestSource('main() {switch(1) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_switch_start2() {
-    addTestSource('main() {switch(1) {^ case 1:}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_switch_start3() {
-    addTestSource('main() {switch(1) {^default:}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_switch_start4() {
-    addTestSource('main() {switch(1) {^ default:}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
-        relevance: DART_RELEVANCE_HIGH);
-  }
-
-  test_switch_start5() {
-    addTestSource('main() {switch(1) {c^ default:}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
-        relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 19);
-    expect(request.replacementLength, 1);
-  }
-
-  test_switch_start6() {
-    addTestSource('main() {switch(1) {c^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
-        relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 19);
-    expect(request.replacementLength, 1);
-  }
-
-  test_switch_start7() {
-    addTestSource('main() {switch(1) { c^ }}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
-        relevance: DART_RELEVANCE_HIGH);
-    expect(request.replacementOffset, 20);
-    expect(request.replacementLength, 1);
-  }
-
-  test_switch_statement() {
-    addTestSource('main() {switch(1) {case 1:^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_SWITCH_OUTSIDE_CLASS);
-  }
-
-  test_switch_statement2() {
-    addTestSource('class A{foo() {switch(1) {case 1:^}}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_SWITCH_IN_CLASS);
-  }
-
-  test_while_break_continue() {
-    addTestSource('main() {while (true) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS,
-        relevance: DART_RELEVANCE_KEYWORD);
-  }
-
-  test_while_break_continue2() {
-    addTestSource('class A {foo() {while (true) {^}}}');
-    expect(computeFast(), isTrue);
-    assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS,
-        relevance: DART_RELEVANCE_KEYWORD);
-  }
-
-  void _appendCompletions(
-      StringBuffer msg, Iterable<String> completions, Iterable<String> other) {
-    List<String> sorted = completions.toList();
-    sorted.sort((c1, c2) => c1.compareTo(c2));
-    sorted.forEach(
-        (c) => msg.writeln('  $c, ${other.contains(c) ? '' : '<<<<<<<<<<<'}'));
-  }
-
-  bool _equalSets(Iterable<String> iter1, Iterable<String> iter2) {
-    if (iter1.length != iter2.length) return false;
-    if (iter1.any((c) => !iter2.contains(c))) return false;
-    if (iter2.any((c) => !iter1.contains(c))) return false;
-    return true;
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart b/pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart
deleted file mode 100644
index e1ab7da..0000000
--- a/pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart
+++ /dev/null
@@ -1,88 +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 test.services.completion.local_declaration_visitor_test;
-
-import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(LocalDeclarationVisitorTest);
-}
-
-@reflectiveTest
-class LocalDeclarationVisitorTest {
-  CompilationUnit parseCompilationUnit(String source) {
-    AnalysisErrorListener listener = AnalysisErrorListener.NULL_LISTENER;
-    Scanner scanner =
-        new Scanner(null, new CharSequenceReader(source), listener);
-    Token token = scanner.tokenize();
-    Parser parser = new Parser(null, listener);
-    CompilationUnit unit = parser.parseCompilationUnit(token);
-    expect(unit, isNotNull);
-    return unit;
-  }
-
-  test_visitForEachStatement() {
-    CompilationUnit unit = parseCompilationUnit('''
-class MyClass {}
-f(List<MyClass> list) {
-  for(MyClas( x in list) {}
-}
-''');
-    NodeList<CompilationUnitMember> declarations = unit.declarations;
-    expect(declarations, hasLength(2));
-    FunctionDeclaration f = declarations[1];
-    expect(f, isNotNull);
-    BlockFunctionBody body = f.functionExpression.body;
-    Statement statement = body.block.statements[0];
-    expect(statement, new isInstanceOf<ForEachStatement>());
-    statement.accept(new TestVisitor(statement.offset));
-  }
-}
-
-class TestVisitor extends LocalDeclarationVisitor {
-  TestVisitor(int offset) : super(offset);
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {}
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {}
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {}
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {}
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {}
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {}
-
-  @override
-  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
-    expect(name, isNotNull);
-  }
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {}
-
-  @override
-  void declaredParam(SimpleIdentifier name, TypeName type) {}
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {}
-}
diff --git a/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart
deleted file mode 100644
index 700f414..0000000
--- a/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart
+++ /dev/null
@@ -1,848 +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 test.services.completion.dart.local;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/local_reference_contributor.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(LocalReferenceContributorTest);
-}
-
-@reflectiveTest
-class LocalReferenceContributorTest extends AbstractSelectorSuggestionTest {
-  @override
-  CompletionSuggestion assertSuggestLocalClass(String name,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      bool isDeprecated: false,
-      String elemFile,
-      int elemOffset}) {
-    return assertSuggestClass(name,
-        elemFile: elemFile,
-        elemOffset: elemOffset,
-        isDeprecated: isDeprecated,
-        kind: kind,
-        relevance: relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalClassTypeAlias(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT}) {
-    return assertSuggestClassTypeAlias(name, relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalConstructor(String name,
-      {int elemOffset}) {
-    return assertSuggestConstructor(name, elemOffset: elemOffset);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalField(String name, String type,
-      {int relevance: DART_RELEVANCE_LOCAL_FIELD, bool deprecated: false}) {
-    return assertSuggestField(name, type,
-        relevance: relevance, isDeprecated: deprecated);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalFunction(
-      String name, String returnType,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool deprecated: false,
-      int relevance: DART_RELEVANCE_LOCAL_FUNCTION}) {
-    return assertSuggestFunction(name, returnType,
-        kind: kind, deprecated: deprecated, relevance: relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalFunctionTypeAlias(
-      String name, String returnType,
-      {bool deprecated: false, int relevance: DART_RELEVANCE_DEFAULT}) {
-    return assertSuggestFunctionTypeAlias(
-        name, returnType, deprecated, relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalGetter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_ACCESSOR, bool deprecated: false}) {
-    return assertSuggestGetter(name, returnType,
-        relevance: relevance, isDeprecated: deprecated);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_METHOD, bool deprecated: false}) {
-    return assertSuggestMethod(name, declaringType, returnType,
-        relevance: relevance, isDeprecated: deprecated);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalSetter(String name,
-      {int relevance: DART_RELEVANCE_LOCAL_ACCESSOR}) {
-    return assertSuggestSetter(name, relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalTopLevelVar(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE}) {
-    return assertSuggestTopLevelVar(name, returnType, relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalVariable(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) {
-    // Local variables should only be suggested by LocalReferenceContributor
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.LOCAL_VARIABLE));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, returnType != null ? returnType : 'dynamic');
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestParameter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_PARAMETER}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.PARAMETER));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
-    return cs;
-  }
-
-  fail_mixin_ordering() {
-    // TODO(paulberry): Duplicates aren't being removed, so we see both M1.m()
-    // and M2.m().
-    addTestSource('''
-class B {}
-class M1 {
-  void m() {}
-}
-class M2 {
-  void m() {}
-}
-class C extends B with M1, M2 {
-  void f() {
-    ^
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestMethod('m', 'M2', 'void');
-  }
-
-  @override
-  void setUpContributor() {
-    contributor = new LocalReferenceContributor();
-  }
-
-  test_break_ignores_outer_functions_using_closure() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    var f = () {
-      bar: while (true) { break ^ }
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_break_ignores_outer_functions_using_local_function() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    void f() {
-      bar: while (true) { break ^ }
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_break_ignores_toplevel_variables() {
-    addTestSource('''
-int x;
-void main() {
-  while (true) {
-    break ^
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNotSuggested('x');
-  }
-
-  test_break_ignores_unrelated_statements() {
-    addTestSource('''
-void main() {
-  foo: while (true) {}
-  while (true) { break ^ }
-  bar: while (true) {}
-}
-''');
-    expect(computeFast(), isTrue);
-    // The scope of the label defined by a labeled statement is just the
-    // statement itself, so neither "foo" nor "bar" are in scope at the caret
-    // position.
-    assertNotSuggested('foo');
-    assertNotSuggested('bar');
-  }
-
-  test_break_to_enclosing_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    bar: while (true) {
-      break ^
-    }
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-    assertSuggestLabel('bar');
-  }
-
-  test_constructor_parameters_mixed_required_and_named() {
-    addTestSource('class A {A(x, {int y}) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_constructor_parameters_mixed_required_and_positional() {
-    addTestSource('class A {A(x, [int y]) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_constructor_parameters_named() {
-    addTestSource('class A {A({x, int y}) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_constructor_parameters_positional() {
-    addTestSource('class A {A([x, int y]) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_constructor_parameters_required() {
-    addTestSource('class A {A(x, int y) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_continue_from_loop_to_switch() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      break;
-    bar: case 2:
-      while (true) {
-        continue ^;
-      }
-      break;
-    baz: case 3:
-      break;
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-    assertSuggestLabel('bar');
-    assertSuggestLabel('baz');
-  }
-
-  test_continue_from_switch_to_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    switch (x) {
-      case 1:
-        continue ^;
-    }
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-  }
-
-  test_continue_ignores_outer_functions_using_closure_with_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    var f = () {
-      bar: while (true) { continue ^ }
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_continue_ignores_outer_functions_using_closure_with_switch() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      var f = () {
-        bar: while (true) { continue ^ }
-      };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_continue_ignores_outer_functions_using_local_function_with_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    void f() {
-      bar: while (true) { continue ^ }
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_continue_ignores_outer_functions_using_local_function_with_switch() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      void f() {
-        bar: while (true) { continue ^ }
-      };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_continue_ignores_unrelated_statements() {
-    addTestSource('''
-void main() {
-  foo: while (true) {}
-  while (true) { continue ^ }
-  bar: while (true) {}
-}
-''');
-    expect(computeFast(), isTrue);
-    // The scope of the label defined by a labeled statement is just the
-    // statement itself, so neither "foo" nor "bar" are in scope at the caret
-    // position.
-    assertNotSuggested('foo');
-    assertNotSuggested('bar');
-  }
-
-  test_continue_to_earlier_case() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      break;
-    case 2:
-      continue ^;
-    case 3:
-      break;
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-  }
-
-  test_continue_to_enclosing_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    bar: while (true) {
-      continue ^
-    }
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-    assertSuggestLabel('bar');
-  }
-
-  test_continue_to_enclosing_switch() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      break;
-    bar: case 2:
-      switch (y) {
-        case 1:
-          continue ^;
-      }
-      break;
-    baz: case 3:
-      break;
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-    assertSuggestLabel('bar');
-    assertSuggestLabel('baz');
-  }
-
-  test_continue_to_later_case() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    case 1:
-      break;
-    case 2:
-      continue ^;
-    foo: case 3:
-      break;
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-  }
-
-  test_continue_to_same_case() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    case 1:
-      break;
-    foo: case 2:
-      continue ^;
-    case 3:
-      break;
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-  }
-
-  test_enum() {
-    addTestSource('enum E { one, two } main() {^}');
-    expect(computeFast(), isTrue);
-    assertSuggestEnum('E');
-    assertNotSuggested('one');
-    assertNotSuggested('two');
-  }
-
-  test_enum_deprecated() {
-    addTestSource('@deprecated enum E { one, two } main() {^}');
-    expect(computeFast(), isTrue);
-    assertSuggestEnum('E', isDeprecated: true);
-    assertNotSuggested('one');
-    assertNotSuggested('two');
-  }
-
-  test_function_parameters_mixed_required_and_named() {
-    addTestSource('''
-void m(x, {int y}) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  test_function_parameters_mixed_required_and_positional() {
-    addTestSource('''
-void m(x, [int y]) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_function_parameters_named() {
-    addTestSource('''
-void m({x, int y}) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  test_function_parameters_none() {
-    addTestSource('''
-void m() {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, isEmpty);
-    expect(suggestion.parameterTypes, isEmpty);
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_function_parameters_positional() {
-    addTestSource('''
-void m([x, int y]) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_function_parameters_required() {
-    addTestSource('''
-void m(x, int y) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 2);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_ignore_symbol_being_completed() {
-    addTestSource('class MyClass { } main(MC^) { }');
-    expect(computeFast(), isTrue);
-    assertSuggestLocalClass('MyClass');
-    assertNotSuggested('MC');
-  }
-
-  test_inComment_block_beforeNode() {
-    addTestSource('''
-main(aaa, bbb) {
-  /* text ^ */
-  print(42);
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_inComment_endOfLine_beforeNode() {
-    addTestSource('''
-main(aaa, bbb) {
-  // text ^
-  print(42);
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_inComment_endOfLine_beforeToken() {
-    addTestSource('''
-main(aaa, bbb) {
-  // text ^
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_InstanceCreationExpression() {
-    addTestSource('''
-class A {foo(){var f; {var x;}}}
-class B {B(this.x, [String boo]) { } int x;}
-class C {C.bar({boo: 'hoo', int z: 0}) { } }
-main() {new ^ String x = "hello";}''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion;
-
-      suggestion = assertSuggestLocalConstructor('A', elemOffset: -1);
-      expect(suggestion.element.parameters, '()');
-      expect(suggestion.element.returnType, 'A');
-      expect(suggestion.declaringType, 'A');
-      expect(suggestion.parameterNames, hasLength(0));
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestLocalConstructor('B');
-      expect(suggestion.element.parameters, '(int x, [String boo])');
-      expect(suggestion.element.returnType, 'B');
-      expect(suggestion.declaringType, 'B');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'int');
-      expect(suggestion.parameterNames[1], 'boo');
-      expect(suggestion.parameterTypes[1], 'String');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestLocalConstructor('C.bar');
-      expect(suggestion.element.parameters, '({dynamic boo, int z})');
-      expect(suggestion.element.returnType, 'C');
-      expect(suggestion.declaringType, 'C');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'boo');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'z');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_mixed_required_and_named() {
-    addTestSource('''
-class A {
-  void m(x, {int y}) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  test_method_parameters_mixed_required_and_positional() {
-    addTestSource('''
-class A {
-  void m(x, [int y]) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_method_parameters_named() {
-    addTestSource('''
-class A {
-  void m({x, int y}) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  test_method_parameters_none() {
-    addTestSource('''
-class A {
-  void m() {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, isEmpty);
-    expect(suggestion.parameterTypes, isEmpty);
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_method_parameters_positional() {
-    addTestSource('''
-class A {
-  void m([x, int y]) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_method_parameters_required() {
-    addTestSource('''
-class A {
-  void m(x, int y) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 2);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_missing_params_constructor() {
-    addTestSource('class C1{C1{} main(){C^}}');
-    expect(computeFast(), isTrue);
-  }
-
-  test_missing_params_function() {
-    addTestSource('int f1{} main(){f^}');
-    expect(computeFast(), isTrue);
-  }
-
-  test_missing_params_method() {
-    addTestSource('class C1{int f1{} main(){f^}}');
-    expect(computeFast(), isTrue);
-  }
-
-  test_overrides() {
-    addTestSource('''
-class A {m() {}}
-class B extends A {m() {^}}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestMethod('m', 'B', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
-  }
-
-  test_prioritization_private() {
-    addTestSource('main() {var ab; var _ab; _^}');
-    expect(computeFast(), isTrue);
-    assertSuggestLocalVariable('ab', null);
-    assertSuggestLocalVariable('_ab', null);
-  }
-
-  test_prioritization_public() {
-    addTestSource('main() {var ab; var _ab; a^}');
-    expect(computeFast(), isTrue);
-    assertSuggestLocalVariable('ab', null);
-    assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT);
-  }
-
-  test_shadowed_name() {
-    addTestSource('var a; class A { var a; m() { ^ } }');
-    expect(computeFast(), isTrue);
-    assertSuggestLocalField('a', null);
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/optype_test.dart b/pkg/analysis_server/test/services/completion/optype_test.dart
deleted file mode 100644
index 94b5daf..0000000
--- a/pkg/analysis_server/test/services/completion/optype_test.dart
+++ /dev/null
@@ -1,1432 +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 test.services.completion.contributor.dart.optype;
-
-import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
-import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_context.dart';
-import '../../utils.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(OpTypeTest);
-}
-
-@reflectiveTest
-class OpTypeTest {
-  OpType visitor;
-
-  void addTestSource(String content, {bool resolved: false}) {
-    int offset = content.indexOf('^');
-    expect(offset, isNot(equals(-1)), reason: 'missing ^');
-    int nextOffset = content.indexOf('^', offset + 1);
-    expect(nextOffset, equals(-1), reason: 'too many ^');
-    content = content.substring(0, offset) + content.substring(offset + 1);
-    Source source = new _TestSource('/completionTest.dart');
-    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
-    context.sourceFactory =
-        new SourceFactory([AbstractContextTest.SDK_RESOLVER]);
-    context.setContents(source, content);
-    CompilationUnit unit = resolved
-        ? context.resolveCompilationUnit2(source, source)
-        : context.parseCompilationUnit(source);
-    CompletionTarget completionTarget =
-        new CompletionTarget.forOffset(unit, offset);
-    visitor = new OpType.forCompletion(completionTarget, offset);
-  }
-
-  void assertOpType(
-      {bool caseLabel: false,
-      bool constructors: false,
-      bool prefixed: false,
-      bool returnValue: false,
-      bool statementLabel: false,
-      bool staticMethodBody: false,
-      bool typeNames: false,
-      bool voidReturn: false}) {
-    expect(visitor.includeCaseLabelSuggestions, caseLabel, reason: 'caseLabel');
-    expect(visitor.includeConstructorSuggestions, constructors,
-        reason: 'constructors');
-    expect(visitor.includeReturnValueSuggestions, returnValue,
-        reason: 'returnValue');
-    expect(visitor.includeStatementLabelSuggestions, statementLabel,
-        reason: 'statementLabel');
-    expect(visitor.includeTypeNameSuggestions, typeNames, reason: 'typeNames');
-    expect(visitor.includeVoidReturnSuggestions, voidReturn,
-        reason: 'voidReturn');
-    expect(visitor.inStaticMethodBody, staticMethodBody,
-        reason: 'staticMethodBody');
-    expect(visitor.isPrefixed, prefixed, reason: 'prefixed');
-  }
-
-  test_Annotation() {
-    // SimpleIdentifier  Annotation  MethodDeclaration  ClassDeclaration
-    addTestSource('class C { @A^ }');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ArgumentList() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('void main() {expect(^)}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ArgumentList_namedParam() {
-    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
-    // ExpressionStatement
-    addTestSource('void main() {expect(foo: ^)}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ArgumentList_prefixedIdentifier() {
-    // SimpleIdentifier  PrefixedIdentifier  ArgumentList
-    addTestSource('void main() {expect(aa.^)}');
-    assertOpType(returnValue: true, typeNames: true, prefixed: true);
-  }
-
-  test_AsExpression() {
-    // SimpleIdentifier  TypeName  AsExpression
-    addTestSource('class A {var b; X _c; foo() {var a; (a as ^).foo();}');
-    assertOpType(typeNames: true);
-  }
-
-  test_AssignmentExpression_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('class A {} main() {int a; int ^b = 1;}');
-    assertOpType();
-  }
-
-  test_AssignmentExpression_RHS() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('class A {} main() {int a; int b = ^}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_AssignmentExpression_type() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      main() {
-        int a;
-        ^ b = 1;}''');
-    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
-    // the user may be either (1) entering a type for the assignment
-    // or (2) starting a new statement.
-    // Consider suggesting only types
-    // if only spaces separates the 1st and 2nd identifiers.
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_AssignmentExpression_type_newline() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      main() {
-        int a;
-        ^
-        b = 1;}''');
-    // Allow non-types preceding an identifier on LHS of assignment
-    // if newline follows first identifier
-    // because user is probably starting a new statement
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_AssignmentExpression_type_partial() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      main() {
-        int a;
-        int^ b = 1;}''');
-    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
-    // the user may be either (1) entering a type for the assignment
-    // or (2) starting a new statement.
-    // Consider suggesting only types
-    // if only spaces separates the 1st and 2nd identifiers.
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_AssignmentExpression_type_partial_newline() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      main() {
-        int a;
-        i^
-        b = 1;}''');
-    // Allow non-types preceding an identifier on LHS of assignment
-    // if newline follows first identifier
-    // because user is probably starting a new statement
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_AwaitExpression() {
-    // SimpleIdentifier  AwaitExpression  ExpressionStatement
-    addTestSource('main() async {A a; await ^}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_BinaryExpression_LHS() {
-    // SimpleIdentifier  BinaryExpression  VariableDeclaration
-    // VariableDeclarationList  VariableDeclarationStatement
-    addTestSource('main() {int a = 1, b = ^ + 2;}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_BinaryExpression_RHS() {
-    // SimpleIdentifier  BinaryExpression  VariableDeclaration
-    // VariableDeclarationList  VariableDeclarationStatement
-    addTestSource('main() {int a = 1, b = 2 + ^;}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_BinaryExpression_RHS2() {
-    // SimpleIdentifier  BinaryExpression
-    addTestSource('main() {if (c < ^)}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_Block() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('''
-      class X {
-        a() {
-          var f;
-          localF(int arg1) { }
-          {var x;}
-          ^ var r;
-        }
-      }''');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_Block_empty() {
-    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addTestSource('class A extends E implements I with M {a() {^}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_Block_final() {
-    addTestSource('main() {final ^}');
-    assertOpType(typeNames: true);
-  }
-
-  test_Block_final2() {
-    addTestSource('main() {final S^ v;}');
-    assertOpType(typeNames: true);
-  }
-
-  test_Block_final3() {
-    addTestSource('main() {final ^ v;}');
-    assertOpType(typeNames: true);
-  }
-
-  test_Block_final_final() {
-    addTestSource('main() {final ^ final S x;}');
-    assertOpType(typeNames: true);
-  }
-
-  test_Block_final_final2() {
-    addTestSource('main() {final S^ final S x;}');
-    assertOpType(typeNames: true);
-  }
-
-  test_Block_identifier_partial() {
-    addTestSource('class X {a() {var f; {var x;} D^ var r;} void b() { }}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_Block_keyword() {
-    addTestSource('class C { static C get instance => null; } main() {C.in^}');
-    assertOpType(
-        prefixed: true, returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_Block_static() {
-    addTestSource('class A {static foo() {^}}');
-    assertOpType(
-        returnValue: true,
-        typeNames: true,
-        staticMethodBody: true,
-        voidReturn: true);
-  }
-
-  test_Break_after_label() {
-    addTestSource('main() { foo: while (true) { break foo ^ ; } }');
-    assertOpType(/* No valid completions */);
-  }
-
-  test_Break_before_label() {
-    addTestSource('main() { foo: while (true) { break ^ foo; } }');
-    assertOpType(statementLabel: true);
-  }
-
-  test_Break_no_label() {
-    addTestSource('main() { foo: while (true) { break ^; } }');
-    assertOpType(statementLabel: true);
-  }
-
-  test_CascadeExpression_selector1() {
-    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addTestSource('''
-      // looks like a cascade to the parser
-      // but the user is trying to get completions for a non-cascade
-      main() {A a; a.^.z}''');
-    assertOpType(
-        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
-  }
-
-  test_CascadeExpression_selector2() {
-    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
-    addTestSource('main() {A a; a..^z}');
-    assertOpType(returnValue: true, voidReturn: true, prefixed: true);
-  }
-
-  test_CascadeExpression_selector2_withTrailingReturn() {
-    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addTestSource('main() {A a; a..^ return}');
-    assertOpType(returnValue: true, voidReturn: true, prefixed: true);
-  }
-
-  test_CascadeExpression_target() {
-    // SimpleIdentifier  CascadeExpression  ExpressionStatement
-    addTestSource('main() {A a; a^..b}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_CatchClause_onType() {
-    // TypeName  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on ^ {}}}');
-    assertOpType(typeNames: true);
-  }
-
-  test_CatchClause_onType_noBrackets() {
-    // TypeName  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on ^}}');
-    assertOpType(typeNames: true);
-  }
-
-  test_CatchClause_typed() {
-    // Block  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_CatchClause_untyped() {
-    // Block  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_ClassDeclaration_body() {
-    // ClassDeclaration  CompilationUnit
-    addTestSource('@deprecated class A {^}');
-    assertOpType(typeNames: true);
-  }
-
-  test_ClassDeclaration_body2() {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
-    addTestSource('@deprecated class A {^mth() {}}');
-    assertOpType(typeNames: true);
-  }
-
-  test_Combinator_hide() {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addTestSource('''
-      import "/testAB.dart" hide ^;
-      class X {}''');
-    assertOpType();
-  }
-
-  test_Combinator_show() {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addTestSource('''
-      import "/testAB.dart" show ^;
-      import "/testCD.dart";
-      class X {}''');
-    assertOpType();
-  }
-
-  test_CommentReference() {
-    // SimpleIdentifier  CommentReference  Comment  MethodDeclaration
-    addTestSource('class A {/** [^] */ mth() {}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_ConditionalExpression_elseExpression() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addTestSource('class C {foo(){var f; {var x;} return a ? T1 : T^}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ConditionalExpression_elseExpression_empty() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addTestSource('class C {foo(){var f; {var x;} return a ? T1 : ^}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ConditionalExpression_partial_thenExpression() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addTestSource('class C {foo(){var f; {var x;} return a ? T^}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ConditionalExpression_partial_thenExpression_empty() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addTestSource('class C {foo(){var f; {var x;} return a ? ^}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ConditionalExpression_thenExpression() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addTestSource('class C {foo(){var f; {var x;} return a ? T^ : c}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ConstructorName() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('main() {new X.^}');
-    assertOpType(constructors: true, prefixed: true);
-  }
-
-  test_ConstructorName_name_resolved() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('main() {new Str^ing.fromCharCodes([]);}', resolved: true);
-    assertOpType(constructors: true);
-  }
-
-  test_ConstructorName_resolved() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('main() {new String.fr^omCharCodes([]);}', resolved: true);
-    assertOpType(constructors: true, prefixed: true);
-  }
-
-  test_ConstructorName_unresolved() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('main() {new String.fr^omCharCodes([]);}');
-    assertOpType(constructors: true, prefixed: true);
-  }
-
-  test_Continue_after_label() {
-    addTestSource('main() { foo: while (true) { continue foo ^ ; } }');
-    assertOpType(/* No valid completions */);
-  }
-
-  test_Continue_before_label() {
-    addTestSource('main() { foo: while (true) { continue ^ foo; } }');
-    assertOpType(statementLabel: true, caseLabel: true);
-  }
-
-  test_Continue_no_label() {
-    addTestSource('main() { foo: while (true) { continue ^; } }');
-    assertOpType(statementLabel: true, caseLabel: true);
-  }
-
-  test_DefaultFormalParameter_named_expression() {
-    // DefaultFormalParameter FormalParameterList MethodDeclaration
-    addTestSource('class A {a(blat: ^) { }}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_DoStatement() {
-    // SimpleIdentifier  DoStatement  Block
-    addTestSource('main() {do{} while(^x);}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ExpressionFunctionBody() {
-    // SimpleIdentifier  ExpressionFunctionBody  FunctionExpression
-    addTestSource('m(){[1].forEach((x)=>^x);}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ExpressionStatement() {
-    // ExpressionStatement  Block  BlockFunctionBody
-    addTestSource('n(){f(3);^}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_ExpressionStatement_name() {
-    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class C {a() {C ^}}');
-    assertOpType();
-  }
-
-  test_ExtendsClause() {
-    // ExtendsClause  ClassDeclaration
-    addTestSource('class x extends ^\n{}');
-    assertOpType(typeNames: true);
-  }
-
-  test_FieldDeclaration_name_typed() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // FieldDeclaration
-    addTestSource('class C {A ^}');
-    assertOpType();
-  }
-
-  test_FieldDeclaration_name_var() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // FieldDeclaration
-    addTestSource('class C {var ^}');
-    assertOpType();
-  }
-
-  test_ForEachStatement() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main() {for(z in ^zs) {}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ForEachStatement_body_typed() {
-    // Block  ForEachStatement
-    addTestSource('main(args) {for (int foo in bar) {^}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_ForEachStatement_body_untyped() {
-    // Block  ForEachStatement
-    addTestSource('main(args) {for (foo in bar) {^}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_ForEachStatement_iterable() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (int foo in ^) {}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ForEachStatement_loopVariable() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (^ in args) {}}');
-    assertOpType(typeNames: true);
-  }
-
-  test_ForEachStatement_loopVariable_name() {
-    // DeclaredIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (String ^ in args) {}}');
-    assertOpType();
-  }
-
-  test_ForEachStatement_loopVariable_name2() {
-    // DeclaredIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (String f^ in args) {}}');
-    assertOpType();
-  }
-
-  test_ForEachStatement_loopVariable_type() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (^ foo in args) {}}');
-    assertOpType(typeNames: true);
-  }
-
-  test_ForEachStatement_loopVariable_type2() {
-    // DeclaredIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (S^ foo in args) {}}');
-    assertOpType(typeNames: true);
-  }
-
-  test_FormalParameter_partialType() {
-    // FormalParameterList MethodDeclaration
-    addTestSource('class A {a(b.^ f) { }}');
-    assertOpType(returnValue: true, typeNames: true, prefixed: true);
-  }
-
-  test_FormalParameter_partialType2() {
-    // FormalParameterList MethodDeclaration
-    addTestSource('class A {a(b.z^ f) { }}');
-    assertOpType(returnValue: true, typeNames: true, prefixed: true);
-  }
-
-  test_FormalParameter_partialType3() {
-    // FormalParameterList MethodDeclaration
-    addTestSource('class A {a(b.^) { }}');
-    assertOpType(returnValue: true, typeNames: true, prefixed: true);
-  }
-
-  test_FormalParameterList() {
-    // FormalParameterList MethodDeclaration
-    addTestSource('class A {a(^) { }}');
-    assertOpType(typeNames: true);
-  }
-
-  test_ForStatement_condition() {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {for (int index = 0; i^)}');
-    // TODO (danrubel) may want to exclude methods/functions with void return
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_ForStatement_initializer() {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {List a; for (^)}');
-    // TODO (danrubel) may want to exclude methods/functions with void return
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_ForStatement_updaters() {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {for (int index = 0; index < 10; i^)}');
-    // TODO (danrubel) may want to exclude methods/functions with void return
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_ForStatement_updaters_prefix_expression() {
-    // SimpleIdentifier  PrefixExpression  ForStatement
-    addTestSource('main() {for (int index = 0; index < 10; ++i^)}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_FunctionDeclaration1() {
-    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    addTestSource('const ^Fara();');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration2() {
-    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    addTestSource('const F^ara();');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration_inLineComment() {
-    // Comment  CompilationUnit
-    addTestSource('''
-      // normal comment ^
-      zoo(z) { } String name;''');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_inLineComment2() {
-    // Comment  CompilationUnit
-    addTestSource('''
-      // normal ^comment
-      zoo(z) { } String name;''');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_inLineComment3() {
-    // Comment  CompilationUnit
-    addTestSource('''
-      // normal comment ^
-      // normal comment 2
-      zoo(z) { } String name;''');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_inLineComment4() {
-    // Comment  CompilationUnit
-    addTestSource('''
-      // normal comment
-      // normal comment 2^
-      zoo(z) { } String name;''');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_inLineDocComment() {
-    // Comment  FunctionDeclaration  CompilationUnit
-    addTestSource('''
-      /// some dartdoc ^
-      zoo(z) { } String name;''');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_inLineDocComment2() {
-    // Comment  FunctionDeclaration  CompilationUnit
-    addTestSource('''
-      /// some ^dartdoc
-      zoo(z) { } String name;''');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_inStarComment() {
-    // Comment  CompilationUnit
-    addTestSource('/* ^ */ zoo(z) {} String name;');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_inStarComment2() {
-    // Comment  CompilationUnit
-    addTestSource('/*  *^/ zoo(z) {} String name;');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_inStarDocComment() {
-    // Comment  FunctionDeclaration  CompilationUnit
-    addTestSource('/** ^ */ zoo(z) { } String name; ');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_inStarDocComment2() {
-    // Comment  FunctionDeclaration  CompilationUnit
-    addTestSource('/**  *^/ zoo(z) { } String name;');
-    assertOpType();
-  }
-
-  test_FunctionDeclaration_returnType() {
-    // CompilationUnit
-    addTestSource('^ zoo(z) { } String name;');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration_returnType_afterLineComment() {
-    // FunctionDeclaration  CompilationUnit
-    addTestSource('''
-      // normal comment
-      ^ zoo(z) {} String name;''');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration_returnType_afterLineComment2() {
-    // FunctionDeclaration  CompilationUnit
-    // TOD(danrubel) left align all test source
-    addTestSource('''
-// normal comment
-^ zoo(z) {} String name;''');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration_returnType_afterLineDocComment() {
-    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    addTestSource('''
-      /// some dartdoc
-      ^ zoo(z) { } String name;''');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration_returnType_afterLineDocComment2() {
-    // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    addTestSource('''
-/// some dartdoc
-^ zoo(z) { } String name;''');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration_returnType_afterStarComment() {
-    // CompilationUnit
-    addTestSource('/* */ ^ zoo(z) { } String name;');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration_returnType_afterStarComment2() {
-    // CompilationUnit
-    addTestSource('/* */^ zoo(z) { } String name;');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration_returnType_afterStarDocComment() {
-    // FunctionDeclaration  CompilationUnit
-    addTestSource('/** */ ^ zoo(z) { } String name;');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionDeclaration_returnType_afterStarDocComment2() {
-    // FunctionDeclaration  CompilationUnit
-    addTestSource('/** */^ zoo(z) { } String name;');
-    assertOpType(typeNames: true);
-  }
-
-  test_FunctionExpression() {
-    // BlockFunctionBody  FunctionExpression  FunctionDeclaration
-    addTestSource('main()^ { int b = 2; b++; b. }');
-    assertOpType();
-  }
-
-  test_FunctionExpressionInvocation() {
-    // ArgumentList  FunctionExpressionInvocation  ExpressionStatement
-    addTestSource('main() { ((x) => x + 7)^(2) }');
-    assertOpType();
-  }
-
-  test_FunctionTypeAlias() {
-    // SimpleIdentifier  FunctionTypeAlias  CompilationUnit
-    addTestSource('typedef n^ ;');
-    assertOpType(typeNames: true);
-  }
-
-  test_IfStatement() {
-    // EmptyStatement  IfStatement  Block  BlockFunctionBody
-    addTestSource('main(){var a; if (true) ^}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_IfStatement_condition() {
-    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
-    addTestSource('main(){var a; if (^)}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_IfStatement_empty() {
-    // SimpleIdentifier  PrefixIdentifier  IfStatement
-    addTestSource('class A {foo() {A a; if (^) something}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_IfStatement_invocation() {
-    // SimpleIdentifier  PrefixIdentifier  IfStatement
-    addTestSource('main() {var a; if (a.^) something}');
-    assertOpType(returnValue: true, typeNames: true, prefixed: true);
-  }
-
-  test_ImplementsClause() {
-    // ImplementsClause  ClassDeclaration
-    addTestSource('class x implements ^\n{}');
-    assertOpType(typeNames: true);
-  }
-
-  test_ImportDirective_dart() {
-    // SimpleStringLiteral  ImportDirective
-    addTestSource('''
-      import "dart^";
-      main() {}''');
-    assertOpType();
-  }
-
-  test_IndexExpression() {
-    addTestSource('class C {foo(){var f; {var x;} f[^]}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_IndexExpression2() {
-    addTestSource('class C {foo(){var f; {var x;} f[T^]}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_InstanceCreationExpression() {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addTestSource('class C {foo(){var f; {var x;} new ^}}');
-    assertOpType(constructors: true);
-  }
-
-  test_InstanceCreationExpression_keyword() {
-    // InstanceCreationExpression  ExpressionStatement  Block
-    addTestSource('class C {foo(){var f; {var x;} new^ }}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_InstanceCreationExpression_keyword2() {
-    // InstanceCreationExpression  ExpressionStatement  Block
-    addTestSource('class C {foo(){var f; {var x;} new^ C();}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_InstanceCreationExpression_trailingStmt() {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addTestSource('class C {foo(){var f; {var x;} new ^ int x = 7;}}');
-    assertOpType(constructors: true);
-  }
-
-  test_InterpolationExpression() {
-    // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addTestSource('main() {String name; print("hello \$^");}');
-    assertOpType(returnValue: true);
-  }
-
-  test_InterpolationExpression_block() {
-    // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addTestSource('main() {String name; print("hello \${n^}");}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_InterpolationExpression_prefix_selector() {
-    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
-    addTestSource('main() {String name; print("hello \${name.^}");}');
-    assertOpType(returnValue: true, typeNames: true, prefixed: true);
-  }
-
-  test_InterpolationExpression_prefix_target() {
-    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
-    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_IsExpression() {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addTestSource('main() {var x; if (x is ^) { }}');
-    assertOpType(typeNames: true);
-  }
-
-  test_IsExpression_target() {
-    // IfStatement  Block  BlockFunctionBody
-    addTestSource('main(){var a; if (^ is A)}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_IsExpression_type_partial() {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addTestSource('main(){var a; if (a is Obj^)}');
-    assertOpType(typeNames: true);
-  }
-
-  test_Literal_list() {
-    // ']'  ListLiteral  ArgumentList  MethodInvocation
-    addTestSource('main() {var Some; print([^]);}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_Literal_list2() {
-    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
-    addTestSource('main() {var Some; print([S^]);}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_Literal_string() {
-    // SimpleStringLiteral  ExpressionStatement  Block
-    addTestSource('class A {a() {"hel^lo"}}');
-    assertOpType();
-  }
-
-  test_MapLiteralEntry() {
-    // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addTestSource('foo = {^');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_MapLiteralEntry1() {
-    // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addTestSource('foo = {T^');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_MapLiteralEntry2() {
-    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
-    addTestSource('foo = {7:T^};');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_MethodDeclaration1() {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
-    addTestSource('class Bar {const ^Fara();}');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration2() {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
-    addTestSource('class Bar {const F^ara();}');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration_inLineComment() {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        // normal comment ^
-        zoo(z) { } String name; }''');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_inLineComment2() {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        // normal ^comment
-        zoo(z) { } String name; }''');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_inLineComment3() {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        // normal comment ^
-        // normal comment 2
-        zoo(z) { } String name; }''');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_inLineComment4() {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        // normal comment
-        // normal comment 2^
-        zoo(z) { } String name; }''');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_inLineDocComment() {
-    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        /// some dartdoc ^
-        zoo(z) { } String name; }''');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_inLineDocComment2() {
-    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        /// some ^dartdoc
-        zoo(z) { } String name; }''');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_inStarComment() {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/* ^ */ zoo(z) {} String name;}');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_inStarComment2() {
-    // Comment  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/*  *^/ zoo(z) {} String name;}');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_inStarDocComment() {
-    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_inStarDocComment2() {
-    // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/**  *^/ zoo(z) { } String name; }');
-    assertOpType();
-  }
-
-  test_MethodDeclaration_returnType() {
-    // ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {^ zoo(z) { } String name; }');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration_returnType_afterLineComment() {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        // normal comment
-        ^ zoo(z) {} String name;}''');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration_returnType_afterLineComment2() {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    // TOD(danrubel) left align all test source
-    addTestSource('''
-class C2 {
-  // normal comment
-^ zoo(z) {} String name;}''');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration_returnType_afterLineDocComment() {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-      class C2 {
-        /// some dartdoc
-        ^ zoo(z) { } String name; }''');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration_returnType_afterLineDocComment2() {
-    // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('''
-class C2 {
-  /// some dartdoc
-^ zoo(z) { } String name; }''');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration_returnType_afterStarComment() {
-    // ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/* */ ^ zoo(z) { } String name; }');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration_returnType_afterStarComment2() {
-    // ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/* */^ zoo(z) { } String name; }');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration_returnType_afterStarDocComment() {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodDeclaration_returnType_afterStarDocComment2() {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
-    assertOpType(typeNames: true);
-  }
-
-  test_MethodInvocation_no_semicolon() {
-    // MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      class A implements I {
-        // no semicolon between completion point and next statement
-        set _s2(I x) {x.^ m(null);}
-      }''');
-    assertOpType(
-        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
-  }
-
-  test_PostfixExpression() {
-    // SimpleIdentifier  PostfixExpression  ForStatement
-    addTestSource('int x = 0; main() {ax+^+;}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_PrefixedIdentifier_class_const() {
-    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
-    addTestSource('main() {A.^}');
-    assertOpType(
-        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
-  }
-
-  test_PrefixedIdentifier_class_imported() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('main() {A a; a.^}');
-    assertOpType(
-        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
-  }
-
-  test_PrefixedIdentifier_prefix() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('class X {foo(){A^.bar}}');
-    assertOpType(typeNames: true, returnValue: true, voidReturn: true);
-  }
-
-  test_PropertyAccess_expression() {
-    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
-    addTestSource('class A {a() {"hello".to^String().length}}');
-    assertOpType(
-        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
-  }
-
-  test_PropertyAccess_noTarget() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addTestSource('main() {.^}');
-    assertOpType();
-  }
-
-  test_PropertyAccess_noTarget2() {
-    // SimpleIdentifier  PropertyAccess  CascadeExpressions
-    addTestSource('main() {.^.}');
-    assertOpType();
-  }
-
-  test_PropertyAccess_noTarget3() {
-    // SimpleIdentifier  PropertyAccess  CascadeExpressions
-    addTestSource('main() {..^}');
-    assertOpType();
-  }
-
-  test_PropertyAccess_selector() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
-    addTestSource('class A {a() {"hello".length.^}}');
-    assertOpType(
-        returnValue: true, typeNames: true, voidReturn: true, prefixed: true);
-  }
-
-  test_ReturnStatement() {
-    // ReturnStatement  Block
-    addTestSource('f() { var vvv = 42; return ^ }');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_SimpleFormalParameter_closure() {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('mth() { PNGS.sort((String a, Str^) => a.compareTo(b)); }');
-    assertOpType(typeNames: true);
-  }
-
-  test_SimpleFormalParameter_name1() {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('m(String na^) {}');
-    assertOpType(typeNames: false);
-  }
-
-  test_SimpleFormalParameter_name2() {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('m(int first, String na^) {}');
-    assertOpType(typeNames: false);
-  }
-
-  test_SimpleFormalParameter_type_optionalNamed() {
-    // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
-    addTestSource('m({Str^}) {}');
-    assertOpType(typeNames: true);
-  }
-
-  test_SimpleFormalParameter_type_optionalPositional() {
-    // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
-    addTestSource('m([Str^]) {}');
-    assertOpType(typeNames: true);
-  }
-
-  test_SimpleFormalParameter_type_withName() {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('m(Str^ name) {}');
-    assertOpType(typeNames: true);
-  }
-
-  test_SimpleFormalParameter_type_withoutName1() {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('m(Str^) {}');
-    assertOpType(typeNames: true);
-  }
-
-  test_SimpleFormalParameter_type_withoutName2() {
-    // FormalParameterList
-    addTestSource('m(^) {}');
-    assertOpType(typeNames: true);
-  }
-
-  test_SimpleFormalParameter_type_withoutName3() {
-    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
-    addTestSource('m(int first, Str^) {}');
-    assertOpType(typeNames: true);
-  }
-
-  test_SwitchCase_before() {
-    // SwitchCase  SwitchStatement  Block
-    addTestSource('main() {switch(k) {^case 1:}}');
-    assertOpType();
-  }
-
-  test_SwitchCase_between() {
-    // SwitchCase  SwitchStatement  Block
-    addTestSource('main() {switch(k) {case 1: ^ case 2: return}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_SwitchCase_expression1() {
-    // SimpleIdentifier  SwitchCase  SwitchStatement
-    addTestSource('''m() {switch (x) {case ^D: return;}}''');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_SwitchCase_expression2() {
-    // SimpleIdentifier  SwitchCase  SwitchStatement
-    addTestSource('''m() {switch (x) {case ^}}''');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_SwitchDefault_before() {
-    // SwitchDefault  SwitchStatement  Block
-    addTestSource('main() {switch(k) { ^ default: return;}}');
-    assertOpType();
-  }
-
-  test_SwitchDefault_between() {
-    // SwitchDefault  SwitchStatement  Block
-    addTestSource('main() {switch(k) {case 1: ^ default: return;}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_SwitchStatement_body_empty() {
-    // Token('}')  SwitchStatement  Block
-    addTestSource('main() {switch(k) {^}}');
-    assertOpType();
-  }
-
-  test_SwitchStatement_body_end() {
-    // Token('}')  SwitchStatement  Block
-    addTestSource('main() {switch(k) {case 1:^}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_SwitchStatement_expression1() {
-    // SimpleIdentifier  SwitchStatement  Block
-    addTestSource('main() {switch(^k) {case 1:{}}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_SwitchStatement_expression2() {
-    // SimpleIdentifier  SwitchStatement  Block
-    addTestSource('main() {switch(k^) {case 1:{}}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_SwitchStatement_expression_empty() {
-    // SimpleIdentifier  SwitchStatement  Block
-    addTestSource('main() {switch(^) {case 1:{}}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ThisExpression_block() {
-    // MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      class A implements I {
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {this.^ m(null);}
-      }''');
-    assertOpType(returnValue: true, voidReturn: true, prefixed: true);
-  }
-
-  test_ThisExpression_constructor() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addTestSource('''
-      class A implements I {
-        A() {this.^}
-      }''');
-    assertOpType(returnValue: true, voidReturn: true, prefixed: true);
-  }
-
-  test_ThisExpression_constructor_param() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      class A implements I {
-        A(this.^) {}
-      }''');
-    assertOpType(prefixed: true);
-  }
-
-  test_ThisExpression_constructor_param2() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      class A implements I {
-        A(this.f^) {}
-      }''');
-    assertOpType(prefixed: true);
-  }
-
-  test_ThisExpression_constructor_param3() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      class A implements I {
-        A(this.^f) {}
-      }''');
-    assertOpType(prefixed: true);
-  }
-
-  test_ThisExpression_constructor_param4() {
-    // FieldFormalParameter  FormalParameterList  ConstructorDeclaration
-    addTestSource('''
-      class A implements I {
-        A(Str^ this.foo) {}
-      }''');
-    assertOpType(typeNames: true);
-  }
-
-  test_ThrowExpression() {
-    // SimpleIdentifier  ThrowExpression  ExpressionStatement
-    addTestSource('main() {throw ^;}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_TopLevelVariableDeclaration_typed_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // TopLevelVariableDeclaration
-    addTestSource('class A {} B ^');
-    assertOpType();
-  }
-
-  test_TopLevelVariableDeclaration_untyped_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // TopLevelVariableDeclaration
-    addTestSource('class A {} var ^');
-    assertOpType();
-  }
-
-  test_TypeArgumentList() {
-    // SimpleIdentifier  BinaryExpression  ExpressionStatement
-    addTestSource('main() { C<^> c; }');
-    assertOpType(typeNames: true);
-  }
-
-  test_TypeArgumentList2() {
-    // TypeName  TypeArgumentList  TypeName
-    addTestSource('main() { C<C^> c; }');
-    assertOpType(typeNames: true);
-  }
-
-  test_TypeParameter() {
-    // SimpleIdentifier  TypeParameter  TypeParameterList
-    addTestSource('class tezetst <String, ^List> {}');
-    assertOpType();
-  }
-
-  test_TypeParameterList_empty() {
-    // SimpleIdentifier  TypeParameter  TypeParameterList
-    addTestSource('class tezetst <^> {}');
-    assertOpType();
-  }
-
-  test_VariableDeclaration_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('main() {var ^}');
-    assertOpType();
-  }
-
-  test_VariableDeclaration_name_hasSome_parameterizedType() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('main() {List<int> m^}');
-    assertOpType();
-  }
-
-  test_VariableDeclaration_name_hasSome_simpleType() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('main() {String m^}');
-    assertOpType();
-  }
-
-  test_VariableDeclarationList_final() {
-    // VariableDeclarationList  VariableDeclarationStatement  Block
-    addTestSource('main() {final ^}');
-    assertOpType(typeNames: true);
-  }
-
-  test_VariableDeclarationStatement_afterSemicolon() {
-    // VariableDeclarationStatement  Block  BlockFunctionBody
-    addTestSource('class A {var a; x() {var b;^}}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
-  }
-
-  test_VariableDeclarationStatement_RHS() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement
-    addTestSource('class C {bar(){var f; {var x;} var e = ^}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_VariableDeclarationStatement_RHS_missing_semicolon() {
-    // VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement
-    addTestSource('class C {bar(){var f; {var x;} var e = ^ var g}}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_WhileStatement() {
-    // SimpleIdentifier  WhileStatement  Block
-    addTestSource('mth() { while (b^) {} }}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-}
-
-class _TestSource implements Source {
-  String fullName;
-  _TestSource(this.fullName);
-
-  @override
-  bool get isInSystemLibrary => false;
-
-  @override
-  String get shortName => fullName;
-
-  @override
-  Source get source => this;
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart b/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart
deleted file mode 100644
index 6e15a0c..0000000
--- a/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart
+++ /dev/null
@@ -1,675 +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 test.services.completion.invocation;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/prefixed_element_contributor.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(PrefixedElementContributorTest);
-}
-
-@reflectiveTest
-class PrefixedElementContributorTest extends AbstractSelectorSuggestionTest {
-  @override
-  CompletionSuggestion assertSuggestInvocationField(String name, String type,
-      {int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
-    return assertSuggestField(name, type,
-        relevance: relevance, isDeprecated: isDeprecated);
-  }
-
-  /**
-   * Check whether a declaration of the form [shadower] in a derived class
-   * shadows a declaration of the form [shadowee] in a base class, for the
-   * purposes of what is shown during completion.  [shouldBeShadowed] indicates
-   * whether shadowing is expected.
-   */
-  Future check_shadowing(
-      String shadower, String shadowee, bool shouldBeShadowed) {
-    addTestSource('''
-class Base {
-  $shadowee
-}
-class Derived extends Base {
-  $shadower
-}
-void f(Derived d) {
-  d.^
-}
-''');
-    return computeFull((bool result) {
-      List<CompletionSuggestion> suggestionsForX = request.suggestions
-          .where((CompletionSuggestion s) => s.completion == 'x')
-          .toList();
-      if (shouldBeShadowed) {
-        expect(suggestionsForX, hasLength(1));
-        expect(suggestionsForX[0].declaringType, 'Derived');
-      } else {
-        expect(suggestionsForX, hasLength(2));
-      }
-    });
-  }
-
-  fail_enumConst_deprecated() {
-    addTestSource('@deprecated enum E { one, two } main() {E.^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      // TODO(danrubel) Investigate why enum suggestion is not marked
-      // as deprecated if enum ast element is deprecated
-      assertSuggestEnumConst('one', isDeprecated: true);
-      assertSuggestEnumConst('two', isDeprecated: true);
-      assertNotSuggested('index');
-      assertSuggestField('values', 'List<E>', isDeprecated: true);
-    });
-  }
-
-  fail_test_PrefixedIdentifier_trailingStmt_const_untyped() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('const g = "hello"; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  @override
-  void setUpContributor() {
-    contributor = new PrefixedElementContributor();
-  }
-
-  test_enumConst() {
-    addTestSource('enum E { one, two } main() {E.^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertSuggestEnumConst('one');
-      assertSuggestEnumConst('two');
-      assertNotSuggested('index');
-      assertSuggestField('values', 'List<E>');
-    });
-  }
-
-  test_enumConst2() {
-    addTestSource('enum E { one, two } main() {E.o^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertSuggestEnumConst('one');
-      assertSuggestEnumConst('two');
-      assertNotSuggested('index');
-      assertSuggestField('values', 'List<E>');
-    });
-  }
-
-  test_enumConst3() {
-    addTestSource('enum E { one, two } main() {E.^ int g;}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertSuggestEnumConst('one');
-      assertSuggestEnumConst('two');
-      assertNotSuggested('index');
-      assertSuggestField('values', 'List<E>');
-    });
-  }
-
-  test_enumConst_index() {
-    addTestSource('enum E { one, two } main() {E.one.^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-      assertSuggestField('index', 'int');
-      assertNotSuggested('values');
-    });
-  }
-
-  test_enumConst_index2() {
-    addTestSource('enum E { one, two } main() {E.one.i^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-      assertSuggestField('index', 'int');
-      assertNotSuggested('values');
-    });
-  }
-
-  test_enumConst_index3() {
-    addTestSource('enum E { one, two } main() {E.one.^ int g;}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-      assertSuggestField('index', 'int');
-      assertNotSuggested('values');
-    });
-  }
-
-  test_generic_field() {
-    addTestSource('''
-class C<T> {
-  T t;
-}
-void f(C<int> c) {
-  c.^
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestField('t', 'int');
-    });
-  }
-
-  test_generic_getter() {
-    addTestSource('''
-class C<T> {
-  T get t => null;
-}
-void f(C<int> c) {
-  c.^
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestGetter('t', 'int');
-    });
-  }
-
-  test_generic_method() {
-    addTestSource('''
-class C<T> {
-  T m(T t) {}
-}
-void f(C<int> c) {
-  c.^
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'int');
-      expect(suggestion.parameterTypes[0], 'int');
-      expect(suggestion.element.returnType, 'int');
-      expect(suggestion.element.parameters, '(int t)');
-    });
-  }
-
-  test_generic_setter() {
-    addTestSource('''
-class C<T> {
-  set t(T value) {}
-}
-void f(C<int> c) {
-  c.^
-}
-''');
-    return computeFull((bool result) {
-      // TODO(paulberry): modify assertSuggestSetter so that we can pass 'int'
-      // as a parmeter to it, and it will check the appropriate field in
-      // the suggestion object.
-      CompletionSuggestion suggestion = assertSuggestSetter('t');
-      expect(suggestion.element.parameters, '(int value)');
-    });
-  }
-
-  test_keyword() {
-    addTestSource('class C { static C get instance => null; } main() {C.in^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('instance', 'C');
-    });
-  }
-
-  test_libraryPrefix() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('import "dart:async" as bar; foo() {bar.^}');
-    return computeFull((bool result) {
-      assertSuggestClass('Future');
-      assertNotSuggested('loadLibrary');
-    });
-  }
-
-  test_libraryPrefix2() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
-    return computeFull((bool result) {
-      assertSuggestClass('Future');
-    });
-  }
-
-  test_libraryPrefix3() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
-    return computeFull((bool result) {
-      assertSuggestConstructor('Future');
-      assertSuggestConstructor('Future.delayed');
-    });
-  }
-
-  test_libraryPrefix_deferred() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
-    return computeFull((bool result) {
-      assertSuggestClass('Future');
-      assertSuggestFunction('loadLibrary', 'Future<dynamic>');
-    });
-  }
-
-  test_libraryPrefix_with_exports() {
-    addSource('/libA.dart', 'library libA; class A { }');
-    addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
-    addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestClass('B');
-      assertSuggestClass('A');
-    });
-  }
-
-  test_local() {
-    addTestSource('foo() {String x = "bar"; x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_local_is() {
-    addTestSource('foo() {var x; if (x is String) x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_local_propogatedType() {
-    addTestSource('foo() {var x = "bar"; x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_method_parameters_mixed_required_and_named() {
-    addTestSource('''
-class C {
-  void m(x, {int y}) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_mixed_required_and_positional() {
-    addTestSource('''
-class C {
-  void m(x, [int y]) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_named() {
-    addTestSource('''
-class C {
-  void m({x, int y}) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_none() {
-    addTestSource('''
-class C {
-  void m() {}
-}
-void main() {new C().^}''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, isEmpty);
-      expect(suggestion.parameterTypes, isEmpty);
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_positional() {
-    addTestSource('''
-class C {
-  void m([x, int y]) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_required() {
-    addTestSource('''
-class C {
-  void m(x, int y) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 2);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_no_parameters_field() {
-    addTestSource('''
-class C {
-  int x;
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestField('x', 'int');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_no_parameters_getter() {
-    addTestSource('''
-class C {
-  int get x => null;
-}
-void main() {int y = new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_no_parameters_setter() {
-    addTestSource('''
-class C {
-  set x(int value) {};
-}
-void main() {int y = new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestSetter('x');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_only_instance() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addTestSource('''
-class C {
-  int f1;
-  static int f2;
-  m1() {}
-  static m2() {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      assertSuggestInvocationField('f1', 'int');
-      assertNotSuggested('f2');
-      assertSuggestMethod('m1', 'C', null);
-      assertNotSuggested('m2');
-    });
-  }
-
-  test_only_instance2() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('''
-class C {
-  int f1;
-  static int f2;
-  m1() {}
-  static m2() {}
-}
-void main() {new C().^ print("something");}''');
-    return computeFull((bool result) {
-      assertSuggestInvocationField('f1', 'int');
-      assertNotSuggested('f2');
-      assertSuggestMethod('m1', 'C', null);
-      assertNotSuggested('m2');
-    });
-  }
-
-  test_only_static() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('''
-class C {
-  int f1;
-  static int f2;
-  m1() {}
-  static m2() {}
-}
-void main() {C.^}''');
-    return computeFull((bool result) {
-      assertNotSuggested('f1');
-      assertSuggestInvocationField('f2', 'int');
-      assertNotSuggested('m1');
-      assertSuggestMethod('m2', 'C', null);
-    });
-  }
-
-  test_only_static2() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('''
-class C {
-  int f1;
-  static int f2;
-  m1() {}
-  static m2() {}
-}
-void main() {C.^ print("something");}''');
-    return computeFull((bool result) {
-      assertNotSuggested('f1');
-      assertSuggestInvocationField('f2', 'int');
-      assertNotSuggested('m1');
-      assertSuggestMethod('m2', 'C', null);
-    });
-  }
-
-  test_param() {
-    addTestSource('foo(String x) {x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_param_is() {
-    addTestSource('foo(x) {if (x is String) x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_shadowing_field_over_field() =>
-      check_shadowing('int x;', 'int x;', true);
-
-  test_shadowing_field_over_getter() =>
-      check_shadowing('int x;', 'int get x => null;', true);
-
-  test_shadowing_field_over_method() =>
-      check_shadowing('int x;', 'void x() {}', true);
-
-  test_shadowing_field_over_setter() =>
-      check_shadowing('int x;', 'set x(int value) {}', true);
-
-  test_shadowing_getter_over_field() =>
-      check_shadowing('int get x => null;', 'int x;', true);
-
-  test_shadowing_getter_over_getter() =>
-      check_shadowing('int get x => null;', 'int get x => null;', true);
-
-  test_shadowing_getter_over_method() =>
-      check_shadowing('int get x => null;', 'void x() {}', true);
-
-  test_shadowing_getter_over_setter() =>
-      check_shadowing('int get x => null;', 'set x(int value) {}', true);
-
-  test_shadowing_method_over_field() =>
-      check_shadowing('void x() {}', 'int x;', true);
-
-  test_shadowing_method_over_getter() =>
-      check_shadowing('void x() {}', 'int get x => null;', true);
-
-  test_shadowing_method_over_method() =>
-      check_shadowing('void x() {}', 'void x() {}', true);
-
-  test_shadowing_method_over_setter() =>
-      check_shadowing('void x() {}', 'set x(int value) {}', true);
-
-  test_shadowing_mixin_order() {
-    addTestSource('''
-class Base {
-}
-class Mixin1 {
-  void f() {}
-}
-class Mixin2 {
-  void f() {}
-}
-class Derived extends Base with Mixin1, Mixin2 {
-}
-void test(Derived d) {
-  d.^
-}
-''');
-    return computeFull((bool result) {
-      // Note: due to dartbug.com/22069, analyzer currently analyzes mixins in
-      // reverse order.  The correct order is that Derived inherits from
-      // "Base with Mixin1, Mixin2", which inherits from "Base with Mixin1",
-      // which inherits from "Base".  So the definition of f in Mixin2 should
-      // shadow the definition in Mixin1.
-      assertSuggestMethod('f', 'Mixin2', 'void');
-    });
-  }
-
-  test_shadowing_mixin_over_superclass() {
-    addTestSource('''
-class Base {
-  void f() {}
-}
-class Mixin {
-  void f() {}
-}
-class Derived extends Base with Mixin {
-}
-void test(Derived d) {
-  d.^
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestMethod('f', 'Mixin', 'void');
-    });
-  }
-
-  test_shadowing_setter_over_field() =>
-      check_shadowing('set x(int value) {}', 'int x;', true);
-
-  test_shadowing_setter_over_getter() =>
-      check_shadowing('set x(int value) {}', 'int get x => null;', true);
-
-  test_shadowing_setter_over_method() =>
-      check_shadowing('set x(int value) {}', 'void x() {}', true);
-
-  test_shadowing_setter_over_setter() =>
-      check_shadowing('set x(int value) {}', 'set x(int value) {}', true);
-
-  test_shadowing_superclass_over_interface() {
-    addTestSource('''
-class Base {
-  void f() {}
-}
-class Interface {
-  void f() {}
-}
-class Derived extends Base implements Interface {
-}
-void test(Derived d) {
-  d.^
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestMethod('f', 'Base', 'void');
-    });
-  }
-
-  test_super() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('''
-class C3 {
-  int fi3;
-  static int fs3;
-  m() {}
-  mi3() {}
-  static ms3() {}
-}
-class C2 {
-  int fi2;
-  static int fs2;
-  m() {}
-  mi2() {}
-  static ms2() {}
-}
-class C1 extends C2 implements C3 {
-  int fi1;
-  static int fs1;
-  m() {super.^}
-  mi1() {}
-  static ms1() {}
-}''');
-    return computeFull((bool result) {
-      assertNotSuggested('fi1');
-      assertNotSuggested('fs1');
-      assertNotSuggested('mi1');
-      assertNotSuggested('ms1');
-      assertSuggestInvocationField('fi2', 'int');
-      assertNotSuggested('fs2');
-      assertSuggestInvocationMethod('mi2', 'C2', null);
-      assertNotSuggested('ms2');
-      assertSuggestInvocationMethod('m', 'C2', null,
-          relevance: DART_RELEVANCE_HIGH);
-      assertNotSuggested('fi3');
-      assertNotSuggested('fs3');
-      assertNotSuggested('mi3');
-      assertNotSuggested('ms3');
-    });
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart
index 69735da..f219dda 100644
--- a/pkg/analysis_server/test/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/test_all.dart
@@ -7,39 +7,14 @@
 import 'package:unittest/unittest.dart';
 
 import '../../utils.dart';
-import 'arglist_contributor_test.dart' as arglist_test;
-import 'combinator_contributor_test.dart' as combinator_test;
-import 'common_usage_computer_test.dart' as common_usage_computer_test;
-import 'completion_computer_test.dart' as completion_computer_test;
-import 'completion_manager_test.dart' as completion_manager_test;
 import 'completion_target_test.dart' as completion_target_test;
-import 'imported_reference_contributor_test.dart' as imported_test;
-import 'inherited_computer_test.dart' as inherited_computer_test;
-import 'keyword_contributor_test.dart' as keyword_test;
-import 'local_declaration_visitor_test.dart' as local_declaration_visitor_test;
-import 'local_reference_contributor_test.dart'
-    as local_reference_contributor_test;
-import 'optype_test.dart' as optype_test;
-import 'prefixed_element_contributor_test.dart' as invocation_test;
-import 'uri_contributor_test.dart' as uri_contributor_test;
+import 'dart/test_all.dart' as dart_contributor_tests;
 
 /// Utility for manually running all tests.
 main() {
   initializeTestEnvironment();
   group('completion', () {
-    arglist_test.main();
-    combinator_test.main();
-    common_usage_computer_test.main();
-    completion_computer_test.main();
-    completion_manager_test.main();
     completion_target_test.main();
-    imported_test.main();
-    inherited_computer_test.main();
-    invocation_test.main();
-    keyword_test.main();
-    local_declaration_visitor_test.main();
-    local_reference_contributor_test.main();
-    optype_test.main();
-    uri_contributor_test.main();
+    dart_contributor_tests.main();
   });
 }
diff --git a/pkg/analysis_server/test/services/completion/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/uri_contributor_test.dart
deleted file mode 100644
index 22ebe15..0000000
--- a/pkg/analysis_server/test/services/completion/uri_contributor_test.dart
+++ /dev/null
@@ -1,543 +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 test.services.completion.contributor.dart.importuri;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/uri_contributor.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:path/path.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(UriContributorTest);
-  defineReflectiveTests(UriContributorWindowsTest);
-}
-
-@reflectiveTest
-class UriContributorTest extends AbstractCompletionTest {
-  @override
-  void setUpContributor() {
-    contributor = new UriContributor();
-  }
-
-  test_after_import() {
-    addTestSource('import "p"^');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertNoSuggestions();
-  }
-
-  test_after_import_raw() {
-    addTestSource('import r"p"^');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertNoSuggestions();
-  }
-
-  test_before_import() {
-    addTestSource('import ^"p"');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertNoSuggestions();
-  }
-
-  test_before_import_raw() {
-    addTestSource('import ^r"p"');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertNoSuggestions();
-  }
-
-  test_before_import_raw2() {
-    addTestSource('import r^"p"');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertNoSuggestions();
-  }
-
-  test_export_package2() {
-    addPackageSource('foo', 'foo.dart', 'library foo;');
-    addPackageSource('foo', 'baz/too.dart', 'library too;');
-    addPackageSource('bar', 'bar.dart', 'library bar;');
-    addTestSource('export "package:foo/baz/^" import');
-    computeFast();
-    assertSuggest('package:foo/baz/too.dart',
-        csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import() {
-    addTestSource('import "^"');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import2() {
-    addTestSource('import "^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_dart() {
-    addTestSource('import "d^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 1);
-    expect(request.replacementLength, 1);
-    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('dart:core',
-        csKind: CompletionSuggestionKind.IMPORT, relevance: DART_RELEVANCE_LOW);
-    assertNotSuggested('dart:_internal');
-    assertSuggest('dart:async', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('dart:math', csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_dart2() {
-    addTestSource('import "dart:async"; import "d^"');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 1);
-    expect(request.replacementLength, 1);
-    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('dart:core',
-        csKind: CompletionSuggestionKind.IMPORT, relevance: DART_RELEVANCE_LOW);
-    assertNotSuggested('dart:_internal');
-    assertSuggest('dart:async', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('dart:math', csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_file() {
-    testFile = '/proj/completion.dart';
-    addSource('/proj/other.dart', 'library other;');
-    addSource('/proj/foo/bar.dart', 'library bar;');
-    addSource('/blat.dart', 'library blat;');
-    addTestSource('import "^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertNotSuggested('completion.dart');
-    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo');
-    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo/bar.dart');
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_import_file2() {
-    testFile = '/proj/completion.dart';
-    addSource('/proj/other.dart', 'library other;');
-    addSource('/proj/foo/bar.dart', 'library bar;');
-    addSource('/blat.dart', 'library blat;');
-    addTestSource('import "..^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 2);
-    expect(request.replacementLength, 2);
-    assertNotSuggested('completion.dart');
-    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo');
-    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo/bar.dart');
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_import_file_child() {
-    testFile = '/proj/completion.dart';
-    addSource('/proj/other.dart', 'library other;');
-    addSource('/proj/foo/bar.dart', 'library bar;');
-    addSource('/blat.dart', 'library blat;');
-    addTestSource('import "foo/^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 4);
-    expect(request.replacementLength, 4);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_import_file_parent() {
-    testFile = '/proj/completion.dart';
-    addSource('/proj/other.dart', 'library other;');
-    addSource('/proj/foo/bar.dart', 'library bar;');
-    addSource('/blat.dart', 'library blat;');
-    addTestSource('import "../^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 3);
-    expect(request.replacementLength, 3);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertNotSuggested('foo/bar.dart');
-    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_file_parent2() {
-    testFile = '/proj/completion.dart';
-    addSource('/proj/other.dart', 'library other;');
-    addSource('/proj/foo/bar.dart', 'library bar;');
-    addSource('/blat.dart', 'library blat;');
-    addTestSource('import "../b^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 4);
-    expect(request.replacementLength, 4);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertNotSuggested('foo/bar.dart');
-    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_package() {
-    addPackageSource('foo', 'foo.dart', 'library foo;');
-    addPackageSource('foo', 'baz/too.dart', 'library too;');
-    addPackageSource('bar', 'bar.dart', 'library bar;');
-    addTestSource('import "p^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 1);
-    expect(request.replacementLength, 1);
-    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:foo/foo.dart',
-        csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:foo/baz/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('package:foo/baz/too.dart');
-    assertSuggest('package:bar/', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:bar/bar.dart',
-        csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_package2() {
-    addPackageSource('foo', 'foo.dart', 'library foo;');
-    addPackageSource('foo', 'baz/too.dart', 'library too;');
-    addPackageSource('bar', 'bar.dart', 'library bar;');
-    addTestSource('import "package:foo/baz/^" import');
-    computeFast();
-    assertSuggest('package:foo/baz/too.dart',
-        csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_package2_raw() {
-    addPackageSource('foo', 'foo.dart', 'library foo;');
-    addPackageSource('foo', 'baz/too.dart', 'library too;');
-    addPackageSource('bar', 'bar.dart', 'library bar;');
-    addTestSource('import r"package:foo/baz/^" import');
-    computeFast();
-    assertSuggest('package:foo/baz/too.dart',
-        csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_package_missing_lib() {
-    var pkgSrc = addPackageSource('bar', 'bar.dart', 'library bar;');
-    provider.deleteFolder(dirname(pkgSrc.fullName));
-    addTestSource('import "p^" class');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 1);
-    expect(request.replacementLength, 1);
-    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:bar/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('package:bar/bar.dart');
-  }
-
-  test_import_package_raw() {
-    addPackageSource('foo', 'foo.dart', 'library foo;');
-    addPackageSource('foo', 'baz/too.dart', 'library too;');
-    addPackageSource('bar', 'bar.dart', 'library bar;');
-    addTestSource('import r"p^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 1);
-    expect(request.replacementLength, 1);
-    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:foo/foo.dart',
-        csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:foo/baz/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('package:foo/baz/too.dart');
-    assertSuggest('package:bar/', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:bar/bar.dart',
-        csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_raw() {
-    addTestSource('import r"^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT);
-    assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_outside_import() {
-    addTestSource('import ^"d" import');
-    computeFast();
-    computeFull((_) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_outside_import2() {
-    addTestSource('import "d"^ import');
-    computeFast();
-    computeFull((_) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_part_file() {
-    testFile = '/proj/completion.dart';
-    addSource('/proj/other.dart', 'library other;');
-    addSource('/proj/foo/bar.dart', 'library bar;');
-    addSource('/blat.dart', 'library blat;');
-    addTestSource('library x; part "^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertNotSuggested('completion.dart');
-    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo');
-    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo/bar.dart');
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_part_file2() {
-    testFile = '/proj/completion.dart';
-    addSource('/proj/other.dart', 'library other;');
-    addSource('/proj/foo/bar.dart', 'library bar;');
-    addSource('/blat.dart', 'library blat;');
-    addTestSource('library x; part "..^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 2);
-    expect(request.replacementLength, 2);
-    assertNotSuggested('completion.dart');
-    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo');
-    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo/bar.dart');
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_part_file_child() {
-    testFile = '/proj/completion.dart';
-    addSource('/proj/other.dart', 'library other;');
-    addSource('/proj/foo/bar.dart', 'library bar;');
-    addSource('/blat.dart', 'library blat;');
-    addTestSource('library x; part "foo/^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 4);
-    expect(request.replacementLength, 4);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_part_file_parent() {
-    testFile = '/proj/completion.dart';
-    addSource('/proj/other.dart', 'library other;');
-    addSource('/proj/foo/bar.dart', 'library bar;');
-    addSource('/blat.dart', 'library blat;');
-    addTestSource('library x; part "../^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 3);
-    expect(request.replacementLength, 3);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertNotSuggested('foo/bar.dart');
-    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
-  }
-}
-
-@reflectiveTest
-class UriContributorWindowsTest extends AbstractCompletionTest {
-  @override
-  void setUpContributor() {
-    contributor = new UriContributor();
-  }
-
-  @override
-  void setupResourceProvider() {
-    provider = new _TestWinResourceProvider();
-  }
-
-  test_import_file() {
-    testFile = '\\proj\\completion.dart';
-    addSource('\\proj\\other.dart', 'library other;');
-    addSource('\\proj\\foo\\bar.dart', 'library bar;');
-    addSource('\\blat.dart', 'library blat;');
-    addTestSource('import "^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertNotSuggested('completion.dart');
-    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo');
-    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo/bar.dart');
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_import_file2() {
-    testFile = '\\proj\\completion.dart';
-    addSource('\\proj\\other.dart', 'library other;');
-    addSource('\\proj\\foo\\bar.dart', 'library bar;');
-    addSource('\\blat.dart', 'library blat;');
-    addTestSource('import "..^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 2);
-    expect(request.replacementLength, 2);
-    assertNotSuggested('completion.dart');
-    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo');
-    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo/bar.dart');
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_import_file_child() {
-    testFile = '\\proj\\completion.dart';
-    addSource('\\proj\\other.dart', 'library other;');
-    addSource('\\proj\\foo\\bar.dart', 'library bar;');
-    addSource('\\blat.dart', 'library blat;');
-    addTestSource('import "foo/^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 4);
-    expect(request.replacementLength, 4);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_import_file_parent() {
-    testFile = '\\proj\\completion.dart';
-    addSource('\\proj\\other.dart', 'library other;');
-    addSource('\\proj\\foo\\bar.dart', 'library bar;');
-    addSource('\\blat.dart', 'library blat;');
-    addTestSource('import "../^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 3);
-    expect(request.replacementLength, 3);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertNotSuggested('foo/bar.dart');
-    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_import_file_parent2() {
-    testFile = '\\proj\\completion.dart';
-    addSource('\\proj\\other.dart', 'library other;');
-    addSource('\\proj\\foo\\bar.dart', 'library bar;');
-    addSource('\\blat.dart', 'library blat;');
-    addTestSource('import "../b^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 4);
-    expect(request.replacementLength, 4);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertNotSuggested('foo/bar.dart');
-    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
-  }
-
-  test_part_file() {
-    testFile = '\\proj\\completion.dart';
-    addSource('\\proj\\other.dart', 'library other;');
-    addSource('\\proj\\foo\\bar.dart', 'library bar;');
-    addSource('\\blat.dart', 'library blat;');
-    addTestSource('library x; part "^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset);
-    expect(request.replacementLength, 0);
-    assertNotSuggested('completion.dart');
-    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo');
-    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo/bar.dart');
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_part_file2() {
-    testFile = '\\proj\\completion.dart';
-    addSource('\\proj\\other.dart', 'library other;');
-    addSource('\\proj\\foo\\bar.dart', 'library bar;');
-    addSource('\\blat.dart', 'library blat;');
-    addTestSource('library x; part "..^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 2);
-    expect(request.replacementLength, 2);
-    assertNotSuggested('completion.dart');
-    assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo');
-    assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('foo/bar.dart');
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_part_file_child() {
-    testFile = '\\proj\\completion.dart';
-    addSource('\\proj\\other.dart', 'library other;');
-    addSource('\\proj\\foo\\bar.dart', 'library bar;');
-    addSource('\\blat.dart', 'library blat;');
-    addTestSource('library x; part "foo/^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 4);
-    expect(request.replacementLength, 4);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT);
-    assertNotSuggested('../blat.dart');
-  }
-
-  test_part_file_parent() {
-    testFile = '\\proj\\completion.dart';
-    addSource('\\proj\\other.dart', 'library other;');
-    addSource('\\proj\\foo\\bar.dart', 'library bar;');
-    addSource('\\blat.dart', 'library blat;');
-    addTestSource('library x; part "../^" import');
-    computeFast();
-    expect(request.replacementOffset, completionOffset - 3);
-    expect(request.replacementLength, 3);
-    assertNotSuggested('completion.dart');
-    assertNotSuggested('other.dart');
-    assertNotSuggested('foo');
-    assertNotSuggested('foo/');
-    assertNotSuggested('foo/bar.dart');
-    assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
-  }
-}
-
-class _TestWinResourceProvider extends MemoryResourceProvider {
-  @override
-  Context get pathContext => windows;
-}
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 2885f27..ed3d7d3 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -4,12 +4,16 @@
 
 library test.services.correction.assist;
 
+import 'dart:async';
+
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -36,8 +40,8 @@
    * Asserts that there is an [Assist] of the given [kind] at [offset] which
    * produces the [expected] code when applied to [testCode].
    */
-  void assertHasAssist(AssistKind kind, String expected) {
-    assist = _assertHasAssist(kind);
+  assertHasAssist(AssistKind kind, String expected) async {
+    assist = await _assertHasAssist(kind);
     change = assist.change;
     // apply to "file"
     List<SourceFileEdit> fileEdits = change.edits;
@@ -50,17 +54,17 @@
   /**
    * Calls [assertHasAssist] at the offset of [offsetSearch] in [testCode].
    */
-  void assertHasAssistAt(
-      String offsetSearch, AssistKind kind, String expected) {
+  assertHasAssistAt(
+      String offsetSearch, AssistKind kind, String expected) async {
     offset = findOffset(offsetSearch);
-    assertHasAssist(kind, expected);
+    await assertHasAssist(kind, expected);
   }
 
   /**
    * Asserts that there is no [Assist] of the given [kind] at [offset].
    */
-  void assertNoAssist(AssistKind kind) {
-    List<Assist> assists = computeAssists(
+  assertNoAssist(AssistKind kind) async {
+    List<Assist> assists = await computeAssists(
         plugin, context, testUnit.element.source, offset, length);
     for (Assist assist in assists) {
       if (assist.kind == kind) {
@@ -72,9 +76,9 @@
   /**
    * Calls [assertNoAssist] at the offset of [offsetSearch] in [testCode].
    */
-  void assertNoAssistAt(String offsetSearch, AssistKind kind) {
+  assertNoAssistAt(String offsetSearch, AssistKind kind) async {
     offset = findOffset(offsetSearch);
-    assertNoAssist(kind);
+    await assertNoAssist(kind);
   }
 
   Position expectedPosition(String search) {
@@ -97,16 +101,24 @@
     }).toList();
   }
 
+  void processRequiredPlugins() {
+    plugin = new ServerPlugin();
+
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(plugin);
+
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+  }
+
   void setUp() {
     super.setUp();
     offset = 0;
     length = 0;
-    ExtensionManager manager = new ExtensionManager();
-    plugin = new ServerPlugin();
-    manager.processPlugins([plugin]);
   }
 
-  void test_addTypeAnnotation_BAD_privateType_closureParameter() {
+  test_addTypeAnnotation_BAD_privateType_closureParameter() async {
     addSource(
         '/my_lib.dart',
         '''
@@ -121,10 +133,10 @@
   foo((test) {});
 }
  ''');
-    assertNoAssistAt('test)', DartAssistKind.ADD_TYPE_ANNOTATION);
+    await assertNoAssistAt('test)', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
-  void test_addTypeAnnotation_BAD_privateType_declaredIdentifier() {
+  test_addTypeAnnotation_BAD_privateType_declaredIdentifier() async {
     addSource(
         '/my_lib.dart',
         '''
@@ -142,10 +154,10 @@
   }
 }
 ''');
-    assertNoAssistAt('var item', DartAssistKind.ADD_TYPE_ANNOTATION);
+    await assertNoAssistAt('var item', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
-  void test_addTypeAnnotation_BAD_privateType_list() {
+  test_addTypeAnnotation_BAD_privateType_list() async {
     addSource(
         '/my_lib.dart',
         '''
@@ -160,10 +172,10 @@
   var v = getValues();
 }
 ''');
-    assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
+    await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
-  void test_addTypeAnnotation_BAD_privateType_variable() {
+  test_addTypeAnnotation_BAD_privateType_variable() async {
     addSource(
         '/my_lib.dart',
         '''
@@ -178,16 +190,16 @@
   var v = getValue();
 }
 ''');
-    assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
+    await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
-  void test_addTypeAnnotation_classField_OK_final() {
+  test_addTypeAnnotation_classField_OK_final() async {
     resolveTestUnit('''
 class A {
   final f = 0;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'final ',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -197,13 +209,13 @@
 ''');
   }
 
-  void test_addTypeAnnotation_classField_OK_int() {
+  test_addTypeAnnotation_classField_OK_int() async {
     resolveTestUnit('''
 class A {
   var f = 0;
 }
 ''');
-    assertHasAssistAt(
+    await await assertHasAssistAt(
         'var ',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -213,17 +225,17 @@
 ''');
   }
 
-  void test_addTypeAnnotation_declaredIdentifier_BAD_hasTypeAnnotation() {
+  test_addTypeAnnotation_declaredIdentifier_BAD_hasTypeAnnotation() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
   }
 }
 ''');
-    assertNoAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION);
+    await assertNoAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
-  void test_addTypeAnnotation_declaredIdentifier_BAD_inForEachBody() {
+  test_addTypeAnnotation_declaredIdentifier_BAD_inForEachBody() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (var item in items) {
@@ -231,10 +243,10 @@
   }
 }
 ''');
-    assertNoAssistAt('42;', DartAssistKind.ADD_TYPE_ANNOTATION);
+    await assertNoAssistAt('42;', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
-  void test_addTypeAnnotation_declaredIdentifier_BAD_unknownType() {
+  test_addTypeAnnotation_declaredIdentifier_BAD_unknownType() async {
     verifyNoTestUnitErrors = false;
     resolveTestUnit('''
 main() {
@@ -242,10 +254,10 @@
   }
 }
 ''');
-    assertNoAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION);
+    await assertNoAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
-  void test_addTypeAnnotation_declaredIdentifier_generic_OK() {
+  test_addTypeAnnotation_declaredIdentifier_generic_OK() async {
     resolveTestUnit('''
 class A<T> {
   main(List<List<T>> items) {
@@ -254,7 +266,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'item in',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -267,7 +279,7 @@
 ''');
   }
 
-  void test_addTypeAnnotation_declaredIdentifier_OK() {
+  test_addTypeAnnotation_declaredIdentifier_OK() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (var item in items) {
@@ -275,7 +287,7 @@
 }
 ''');
     // on identifier
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'item in',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -285,7 +297,7 @@
 }
 ''');
     // on "for"
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'for (',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -296,7 +308,7 @@
 ''');
   }
 
-  void test_addTypeAnnotation_declaredIdentifier_OK_addImport_dartUri() {
+  test_addTypeAnnotation_declaredIdentifier_OK_addImport_dartUri() async {
     addSource(
         '/my_lib.dart',
         r'''
@@ -310,7 +322,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'future in',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -323,14 +335,14 @@
 ''');
   }
 
-  void test_addTypeAnnotation_declaredIdentifier_OK_final() {
+  test_addTypeAnnotation_declaredIdentifier_OK_final() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (final item in items) {
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'item in',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -341,7 +353,54 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_generic_OK_literal() {
+  test_addTypeAnnotation_local_BAD_hasTypeAnnotation() async {
+    resolveTestUnit('''
+main() {
+  int v = 42;
+}
+''');
+    await assertNoAssistAt(' = 42', DartAssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  test_addTypeAnnotation_local_BAD_multiple() async {
+    resolveTestUnit('''
+main() {
+  var a = 1, b = '';
+}
+''');
+    await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  test_addTypeAnnotation_local_BAD_noValue() async {
+    verifyNoTestUnitErrors = false;
+    resolveTestUnit('''
+main() {
+  var v;
+}
+''');
+    await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  test_addTypeAnnotation_local_BAD_null() async {
+    resolveTestUnit('''
+main() {
+  var v = null;
+}
+''');
+    await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  test_addTypeAnnotation_local_BAD_unknown() async {
+    verifyNoTestUnitErrors = false;
+    resolveTestUnit('''
+main() {
+  var v = unknownVar;
+}
+''');
+    await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  test_addTypeAnnotation_local_generic_OK_literal() async {
     resolveTestUnit('''
 class A {
   main(List<int> items) {
@@ -349,7 +408,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -361,7 +420,7 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_generic_OK_local() {
+  test_addTypeAnnotation_local_generic_OK_local() async {
     resolveTestUnit('''
 class A<T> {
   main(List<T> items) {
@@ -369,7 +428,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -381,7 +440,7 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_addImport_dartUri() {
+  test_addTypeAnnotation_local_OK_addImport_dartUri() async {
     addSource(
         '/my_lib.dart',
         r'''
@@ -394,7 +453,7 @@
   var v = getFutureInt();
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -406,7 +465,7 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_addImport_notLibraryUnit() {
+  test_addTypeAnnotation_local_OK_addImport_notLibraryUnit() async {
     // prepare library
     addSource(
         '/my_lib.dart',
@@ -437,7 +496,7 @@
     testLibraryElement = testUnitElement.library;
     // prepare the assist
     offset = findOffset('v = ');
-    assist = _assertHasAssist(DartAssistKind.ADD_TYPE_ANNOTATION);
+    assist = await _assertHasAssist(DartAssistKind.ADD_TYPE_ANNOTATION);
     change = assist.change;
     // verify
     {
@@ -466,7 +525,7 @@
     }
   }
 
-  void test_addTypeAnnotation_local_OK_addImport_relUri() {
+  test_addTypeAnnotation_local_OK_addImport_relUri() async {
     addSource(
         '/aa/bbb/lib_a.dart',
         r'''
@@ -484,7 +543,7 @@
   var v = newMyClass();
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -496,13 +555,13 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_Function() {
+  test_addTypeAnnotation_local_OK_Function() async {
     resolveTestUnit('''
 main() {
   var v = () => 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -512,13 +571,13 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_int() {
+  test_addTypeAnnotation_local_OK_int() async {
     resolveTestUnit('''
 main() {
   var v = 0;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -528,13 +587,13 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_List() {
+  test_addTypeAnnotation_local_OK_List() async {
     resolveTestUnit('''
 main() {
   var v = <String>[];
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -544,7 +603,7 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_localType() {
+  test_addTypeAnnotation_local_OK_localType() async {
     resolveTestUnit('''
 class C {}
 C f() => null;
@@ -552,7 +611,7 @@
   var x = f();
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'x =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -564,13 +623,13 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_onInitializer() {
+  test_addTypeAnnotation_local_OK_onInitializer() async {
     resolveTestUnit('''
 main() {
   var v = 123;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '23',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -580,13 +639,13 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_onName() {
+  test_addTypeAnnotation_local_OK_onName() async {
     resolveTestUnit('''
 main() {
   var abc = 0;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'bc',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -596,13 +655,13 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_onVar() {
+  test_addTypeAnnotation_local_OK_onVar() async {
     resolveTestUnit('''
 main() {
   var v = 0;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'var ',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -612,13 +671,13 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_OK_onVariableDeclarationStatement() {
+  test_addTypeAnnotation_local_OK_onVariableDeclarationStatement() async {
     resolveTestUnit('''
 main() {
   var v = 123; // marker
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         ' // marker',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -628,54 +687,7 @@
 ''');
   }
 
-  void test_addTypeAnnotation_local_wrong_hasTypeAnnotation() {
-    resolveTestUnit('''
-main() {
-  int v = 42;
-}
-''');
-    assertNoAssistAt(' = 42', DartAssistKind.ADD_TYPE_ANNOTATION);
-  }
-
-  void test_addTypeAnnotation_local_wrong_multiple() {
-    resolveTestUnit('''
-main() {
-  var a = 1, b = '';
-}
-''');
-    assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
-  }
-
-  void test_addTypeAnnotation_local_wrong_noValue() {
-    verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
-main() {
-  var v;
-}
-''');
-    assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
-  }
-
-  void test_addTypeAnnotation_local_wrong_null() {
-    resolveTestUnit('''
-main() {
-  var v = null;
-}
-''');
-    assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
-  }
-
-  void test_addTypeAnnotation_local_wrong_unknown() {
-    verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
-main() {
-  var v = unknownVar;
-}
-''');
-    assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
-  }
-
-  void test_addTypeAnnotation_OK_privateType_sameLibrary() {
+  test_addTypeAnnotation_OK_privateType_sameLibrary() async {
     resolveTestUnit('''
 class _A {}
 _A getValue() => new _A();
@@ -683,7 +695,7 @@
   var v = getValue();
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'var ',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -695,34 +707,34 @@
 ''');
   }
 
-  void test_addTypeAnnotation_parameter_BAD_hasExplicitType() {
+  test_addTypeAnnotation_parameter_BAD_hasExplicitType() async {
     resolveTestUnit('''
 foo(f(int p)) {}
 main() {
   foo((num test) {});
 }
 ''');
-    assertNoAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION);
+    await assertNoAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
-  void test_addTypeAnnotation_parameter_BAD_noPropagatedType() {
+  test_addTypeAnnotation_parameter_BAD_noPropagatedType() async {
     resolveTestUnit('''
 foo(f(p)) {}
 main() {
   foo((test) {});
 }
 ''');
-    assertNoAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION);
+    await assertNoAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
-  void test_addTypeAnnotation_parameter_OK() {
+  test_addTypeAnnotation_parameter_OK() async {
     resolveTestUnit('''
 foo(f(int p)) {}
 main() {
   foo((test) {});
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'test',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -733,11 +745,25 @@
 ''');
   }
 
-  void test_addTypeAnnotation_topLevelField_OK_int() {
+  test_addTypeAnnotation_topLevelField_BAD_multiple() async {
+    resolveTestUnit('''
+var A = 1, V = '';
+''');
+    await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  test_addTypeAnnotation_topLevelField_BAD_noValue() async {
+    resolveTestUnit('''
+var V;
+''');
+    await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  test_addTypeAnnotation_topLevelField_OK_int() async {
     resolveTestUnit('''
 var V = 0;
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'var ',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
@@ -745,21 +771,7 @@
 ''');
   }
 
-  void test_addTypeAnnotation_topLevelField_wrong_multiple() {
-    resolveTestUnit('''
-var A = 1, V = '';
-''');
-    assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
-  }
-
-  void test_addTypeAnnotation_topLevelField_wrong_noValue() {
-    resolveTestUnit('''
-var V;
-''');
-    assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
-  }
-
-  void test_assignToLocalVariable() {
+  test_assignToLocalVariable() async {
     resolveTestUnit('''
 main() {
   List<int> bytes;
@@ -767,7 +779,7 @@
 }
 List<int> readBytes() => <int>[];
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'readBytes();',
         DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE,
         '''
@@ -784,17 +796,17 @@
             ['list', 'bytes2', 'readBytes']));
   }
 
-  void test_assignToLocalVariable_alreadyAssignment() {
+  test_assignToLocalVariable_alreadyAssignment() async {
     resolveTestUnit('''
 main() {
   var vvv;
   vvv = 42;
 }
 ''');
-    assertNoAssistAt('vvv =', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
+    await assertNoAssistAt('vvv =', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
   }
 
-  void test_assignToLocalVariable_inClosure() {
+  test_assignToLocalVariable_inClosure() async {
     resolveTestUnit(r'''
 main() {
   print(() {
@@ -802,7 +814,7 @@
   });
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '345',
         DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE,
         '''
@@ -814,42 +826,225 @@
 ''');
   }
 
-  void test_assignToLocalVariable_invocationArgument() {
+  test_assignToLocalVariable_invocationArgument() async {
     resolveTestUnit(r'''
 main() {
   f(12345);
 }
 int f(p) {}
 ''');
-    assertNoAssistAt('345', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
+    await assertNoAssistAt('345', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
   }
 
-  void test_assignToLocalVariable_throw() {
+  test_assignToLocalVariable_throw() async {
     resolveTestUnit('''
 main() {
   throw 42;
 }
 ''');
-    assertNoAssistAt('throw ', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
+    await assertNoAssistAt('throw ', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
   }
 
-  void test_assignToLocalVariable_void() {
+  test_assignToLocalVariable_void() async {
     resolveTestUnit('''
 main() {
   f();
 }
 void f() {}
 ''');
-    assertNoAssistAt('f();', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
+    await assertNoAssistAt('f();', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
   }
 
-  void test_convertToBlockBody_OK_async() {
+  test_convertDocumentationIntoBlock_BAD_alreadyBlock() async {
+    resolveTestUnit('''
+/**
+ * AAAAAAA
+ */
+class A {}
+''');
+    await assertNoAssistAt(
+        'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK);
+  }
+
+  test_convertDocumentationIntoBlock_BAD_notDocumentation() async {
+    resolveTestUnit('''
+// AAAA
+class A {}
+''');
+    await assertNoAssistAt(
+        'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK);
+  }
+
+  test_convertDocumentationIntoBlock_OK_noSpaceBeforeText() async {
+    resolveTestUnit('''
+class A {
+  /// AAAAA
+  ///BBBBB
+  ///
+  /// CCCCC
+  mmm() {}
+}
+''');
+    await assertHasAssistAt(
+        'AAAAA',
+        DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK,
+        '''
+class A {
+  /**
+   * AAAAA
+   *BBBBB
+   *
+   * CCCCC
+   */
+  mmm() {}
+}
+''');
+  }
+
+  test_convertDocumentationIntoBlock_OK_onReference() async {
+    resolveTestUnit('''
+/// AAAAAAA [int] AAAAAAA
+class A {}
+''');
+    await assertHasAssistAt(
+        'nt]',
+        DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK,
+        '''
+/**
+ * AAAAAAA [int] AAAAAAA
+ */
+class A {}
+''');
+  }
+
+  test_convertDocumentationIntoBlock_OK_onText() async {
+    resolveTestUnit('''
+class A {
+  /// AAAAAAA [int] AAAAAAA
+  /// BBBBBBBB BBBB BBBB
+  /// CCC [A] CCCCCCCCCCC
+  mmm() {}
+}
+''');
+    await assertHasAssistAt(
+        'AAA [',
+        DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK,
+        '''
+class A {
+  /**
+   * AAAAAAA [int] AAAAAAA
+   * BBBBBBBB BBBB BBBB
+   * CCC [A] CCCCCCCCCCC
+   */
+  mmm() {}
+}
+''');
+  }
+
+  test_convertDocumentationIntoLine_BAD_alreadyLine() async {
+    resolveTestUnit('''
+/// AAAAAAA
+class A {}
+''');
+    await assertNoAssistAt(
+        'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE);
+  }
+
+  test_convertDocumentationIntoLine_BAD_notDocumentation() async {
+    resolveTestUnit('''
+/* AAAA */
+class A {}
+''');
+    await assertNoAssistAt(
+        'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE);
+  }
+
+  test_convertDocumentationIntoLine_OK_onReference() async {
+    resolveTestUnit('''
+/**
+ * AAAAAAA [int] AAAAAAA
+ */
+class A {}
+''');
+    await assertHasAssistAt(
+        'nt]',
+        DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE,
+        '''
+/// AAAAAAA [int] AAAAAAA
+class A {}
+''');
+  }
+
+  test_convertDocumentationIntoLine_OK_onText() async {
+    resolveTestUnit('''
+class A {
+  /**
+   * AAAAAAA [int] AAAAAAA
+   * BBBBBBBB BBBB BBBB
+   * CCC [A] CCCCCCCCCCC
+   */
+  mmm() {}
+}
+''');
+    await assertHasAssistAt(
+        'AAA [',
+        DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE,
+        '''
+class A {
+  /// AAAAAAA [int] AAAAAAA
+  /// BBBBBBBB BBBB BBBB
+  /// CCC [A] CCCCCCCCCCC
+  mmm() {}
+}
+''');
+  }
+
+  test_convertDocumentationIntoLine_OK_onText_hasFirstLine() async {
+    resolveTestUnit('''
+class A {
+  /** AAAAAAA [int] AAAAAAA
+   * BBBBBBBB BBBB BBBB
+   * CCC [A] CCCCCCCCCCC
+   */
+  mmm() {}
+}
+''');
+    await assertHasAssistAt(
+        'AAA [',
+        DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE,
+        '''
+class A {
+  /// AAAAAAA [int] AAAAAAA
+  /// BBBBBBBB BBBB BBBB
+  /// CCC [A] CCCCCCCCCCC
+  mmm() {}
+}
+''');
+  }
+
+  test_convertToBlockBody_BAD_noEnclosingFunction() async {
+    resolveTestUnit('''
+var v = 123;
+''');
+    await assertNoAssistAt('v =', DartAssistKind.CONVERT_INTO_BLOCK_BODY);
+  }
+
+  test_convertToBlockBody_BAD_notExpressionBlock() async {
+    resolveTestUnit('''
+fff() {
+  return 123;
+}
+''');
+    await assertNoAssistAt('fff() {', DartAssistKind.CONVERT_INTO_BLOCK_BODY);
+  }
+
+  test_convertToBlockBody_OK_async() async {
     resolveTestUnit('''
 class A {
   mmm() async => 123;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'mmm()',
         DartAssistKind.CONVERT_INTO_BLOCK_BODY,
         '''
@@ -861,14 +1056,14 @@
 ''');
   }
 
-  void test_convertToBlockBody_OK_closure() {
+  test_convertToBlockBody_OK_closure() async {
     resolveTestUnit('''
 setup(x) {}
 main() {
   setup(() => 42);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '() => 42',
         DartAssistKind.CONVERT_INTO_BLOCK_BODY,
         '''
@@ -887,14 +1082,14 @@
     }
   }
 
-  void test_convertToBlockBody_OK_closure_voidExpression() {
+  test_convertToBlockBody_OK_closure_voidExpression() async {
     resolveTestUnit('''
 setup(x) {}
 main() {
   setup(() => print('done'));
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '() => print',
         DartAssistKind.CONVERT_INTO_BLOCK_BODY,
         '''
@@ -913,13 +1108,13 @@
     }
   }
 
-  void test_convertToBlockBody_OK_constructor() {
+  test_convertToBlockBody_OK_constructor() async {
     resolveTestUnit('''
 class A {
   factory A() => null;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'A()',
         DartAssistKind.CONVERT_INTO_BLOCK_BODY,
         '''
@@ -931,13 +1126,13 @@
 ''');
   }
 
-  void test_convertToBlockBody_OK_method() {
+  test_convertToBlockBody_OK_method() async {
     resolveTestUnit('''
 class A {
   mmm() => 123;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'mmm()',
         DartAssistKind.CONVERT_INTO_BLOCK_BODY,
         '''
@@ -949,11 +1144,11 @@
 ''');
   }
 
-  void test_convertToBlockBody_OK_onName() {
+  test_convertToBlockBody_OK_onName() async {
     resolveTestUnit('''
 fff() => 123;
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'fff()',
         DartAssistKind.CONVERT_INTO_BLOCK_BODY,
         '''
@@ -963,11 +1158,11 @@
 ''');
   }
 
-  void test_convertToBlockBody_OK_onValue() {
+  test_convertToBlockBody_OK_onValue() async {
     resolveTestUnit('''
 fff() => 123;
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '23;',
         DartAssistKind.CONVERT_INTO_BLOCK_BODY,
         '''
@@ -977,23 +1172,53 @@
 ''');
   }
 
-  void test_convertToBlockBody_wrong_noEnclosingFunction() {
+  test_convertToExpressionBody_BAD_already() async {
     resolveTestUnit('''
-var v = 123;
+fff() => 42;
 ''');
-    assertNoAssistAt('v =', DartAssistKind.CONVERT_INTO_BLOCK_BODY);
+    await assertNoAssistAt(
+        'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
   }
 
-  void test_convertToBlockBody_wrong_notExpressionBlock() {
+  test_convertToExpressionBody_BAD_moreThanOneStatement() async {
     resolveTestUnit('''
 fff() {
-  return 123;
+  var v = 42;
+  return v;
 }
 ''');
-    assertNoAssistAt('fff() {', DartAssistKind.CONVERT_INTO_BLOCK_BODY);
+    await assertNoAssistAt(
+        'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
   }
 
-  void test_convertToExpressionBody_OK_async() {
+  test_convertToExpressionBody_BAD_noEnclosingFunction() async {
+    resolveTestUnit('''
+var V = 42;
+''');
+    await assertNoAssistAt('V = ', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
+  }
+
+  test_convertToExpressionBody_BAD_noReturn() async {
+    resolveTestUnit('''
+fff() {
+  var v = 42;
+}
+''');
+    await assertNoAssistAt(
+        'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
+  }
+
+  test_convertToExpressionBody_BAD_noReturnValue() async {
+    resolveTestUnit('''
+fff() {
+  return;
+}
+''');
+    await assertNoAssistAt(
+        'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
+  }
+
+  test_convertToExpressionBody_OK_async() async {
     resolveTestUnit('''
 class A {
   mmm() async {
@@ -1001,7 +1226,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'mmm',
         DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
         '''
@@ -1011,7 +1236,7 @@
 ''');
   }
 
-  void test_convertToExpressionBody_OK_closure() {
+  test_convertToExpressionBody_OK_closure() async {
     resolveTestUnit('''
 setup(x) {}
 main() {
@@ -1020,7 +1245,7 @@
   });
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '42;',
         DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
         '''
@@ -1031,7 +1256,7 @@
 ''');
   }
 
-  void test_convertToExpressionBody_OK_closure_voidExpression() {
+  test_convertToExpressionBody_OK_closure_voidExpression() async {
     resolveTestUnit('''
 setup(x) {}
 main() {
@@ -1040,7 +1265,7 @@
   });
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'print(',
         DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
         '''
@@ -1051,7 +1276,7 @@
 ''');
   }
 
-  void test_convertToExpressionBody_OK_constructor() {
+  test_convertToExpressionBody_OK_constructor() async {
     resolveTestUnit('''
 class A {
   factory A() {
@@ -1059,7 +1284,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'A()',
         DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
         '''
@@ -1069,13 +1294,13 @@
 ''');
   }
 
-  void test_convertToExpressionBody_OK_function_onBlock() {
+  test_convertToExpressionBody_OK_function_onBlock() async {
     resolveTestUnit('''
 fff() {
   return 42;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '{',
         DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
         '''
@@ -1083,13 +1308,13 @@
 ''');
   }
 
-  void test_convertToExpressionBody_OK_function_onName() {
+  test_convertToExpressionBody_OK_function_onName() async {
     resolveTestUnit('''
 fff() {
   return 42;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'ff()',
         DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
         '''
@@ -1097,7 +1322,7 @@
 ''');
   }
 
-  void test_convertToExpressionBody_OK_method_onBlock() {
+  test_convertToExpressionBody_OK_method_onBlock() async {
     resolveTestUnit('''
 class A {
   m() { // marker
@@ -1105,7 +1330,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '{ // marker',
         DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
         '''
@@ -1115,13 +1340,13 @@
 ''');
   }
 
-  void test_convertToExpressionBody_OK_topFunction_onReturnStatement() {
+  test_convertToExpressionBody_OK_topFunction_onReturnStatement() async {
     resolveTestUnit('''
 fff() {
   return 42;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'return',
         DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
         '''
@@ -1129,49 +1354,7 @@
 ''');
   }
 
-  void test_convertToExpressionBody_wrong_already() {
-    resolveTestUnit('''
-fff() => 42;
-''');
-    assertNoAssistAt('fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
-  }
-
-  void test_convertToExpressionBody_wrong_moreThanOneStatement() {
-    resolveTestUnit('''
-fff() {
-  var v = 42;
-  return v;
-}
-''');
-    assertNoAssistAt('fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
-  }
-
-  void test_convertToExpressionBody_wrong_noEnclosingFunction() {
-    resolveTestUnit('''
-var V = 42;
-''');
-    assertNoAssistAt('V = ', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
-  }
-
-  void test_convertToExpressionBody_wrong_noReturn() {
-    resolveTestUnit('''
-fff() {
-  var v = 42;
-}
-''');
-    assertNoAssistAt('fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
-  }
-
-  void test_convertToExpressionBody_wrong_noReturnValue() {
-    resolveTestUnit('''
-fff() {
-  return;
-}
-''');
-    assertNoAssistAt('fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
-  }
-
-  void test_convertToFieldParameter_BAD_additionalUse() {
+  test_convertToFieldParameter_BAD_additionalUse() async {
     resolveTestUnit('''
 class A {
   int aaa2;
@@ -1179,20 +1362,20 @@
   A(int aaa) : aaa2 = aaa, bbb2 = aaa;
 }
 ''');
-    assertNoAssistAt('aaa)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER);
+    await assertNoAssistAt('aaa)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER);
   }
 
-  void test_convertToFieldParameter_BAD_notPureAssignment() {
+  test_convertToFieldParameter_BAD_notPureAssignment() async {
     resolveTestUnit('''
 class A {
   int aaa2;
   A(int aaa) : aaa2 = aaa * 2;
 }
 ''');
-    assertNoAssistAt('aaa)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER);
+    await assertNoAssistAt('aaa)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER);
   }
 
-  void test_convertToFieldParameter_OK_firstInitializer() {
+  test_convertToFieldParameter_OK_firstInitializer() async {
     resolveTestUnit('''
 class A {
   double aaa2;
@@ -1200,7 +1383,7 @@
   A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'aaa, ',
         DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
         '''
@@ -1212,7 +1395,7 @@
 ''');
   }
 
-  void test_convertToFieldParameter_OK_onParameterName_inInitializer() {
+  test_convertToFieldParameter_OK_onParameterName_inInitializer() async {
     resolveTestUnit('''
 class A {
   int test2;
@@ -1220,7 +1403,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'test {',
         DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
         '''
@@ -1232,7 +1415,7 @@
 ''');
   }
 
-  void test_convertToFieldParameter_OK_onParameterName_inParameters() {
+  test_convertToFieldParameter_OK_onParameterName_inParameters() async {
     resolveTestUnit('''
 class A {
   int test;
@@ -1240,7 +1423,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'test)',
         DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
         '''
@@ -1252,7 +1435,7 @@
 ''');
   }
 
-  void test_convertToFieldParameter_OK_secondInitializer() {
+  test_convertToFieldParameter_OK_secondInitializer() async {
     resolveTestUnit('''
 class A {
   double aaa2;
@@ -1260,7 +1443,7 @@
   A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'bbb)',
         DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
         '''
@@ -1272,16 +1455,17 @@
 ''');
   }
 
-  void test_convertToForIndex_BAD_bodyNotBlock() {
+  test_convertToForIndex_BAD_bodyNotBlock() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) print(item);
 }
 ''');
-    assertNoAssistAt('for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
+    await assertNoAssistAt(
+        'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
   }
 
-  void test_convertToForIndex_BAD_doesNotDeclareVariable() {
+  test_convertToForIndex_BAD_doesNotDeclareVariable() async {
     resolveTestUnit('''
 main(List<String> items) {
   String item;
@@ -1290,10 +1474,10 @@
   }
 }
 ''');
-    assertNoAssistAt('for (item', DartAssistKind.CONVERT_INTO_FOR_INDEX);
+    await assertNoAssistAt('for (item', DartAssistKind.CONVERT_INTO_FOR_INDEX);
   }
 
-  void test_convertToForIndex_BAD_iterableIsNotVariable() {
+  test_convertToForIndex_BAD_iterableIsNotVariable() async {
     resolveTestUnit('''
 main() {
   for (String item in ['a', 'b', 'c']) {
@@ -1301,10 +1485,11 @@
   }
 }
 ''');
-    assertNoAssistAt('for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
+    await assertNoAssistAt(
+        'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
   }
 
-  void test_convertToForIndex_BAD_iterableNotList() {
+  test_convertToForIndex_BAD_iterableNotList() async {
     resolveTestUnit('''
 main(Iterable<String> items) {
   for (String item in items) {
@@ -1312,10 +1497,11 @@
   }
 }
 ''');
-    assertNoAssistAt('for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
+    await assertNoAssistAt(
+        'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
   }
 
-  void test_convertToForIndex_BAD_usesIJK() {
+  test_convertToForIndex_BAD_usesIJK() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
@@ -1324,10 +1510,11 @@
   }
 }
 ''');
-    assertNoAssistAt('for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
+    await assertNoAssistAt(
+        'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
   }
 
-  void test_convertToForIndex_OK_onDeclaredIdentifier_name() {
+  test_convertToForIndex_OK_onDeclaredIdentifier_name() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
@@ -1335,7 +1522,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'item in',
         DartAssistKind.CONVERT_INTO_FOR_INDEX,
         '''
@@ -1348,7 +1535,7 @@
 ''');
   }
 
-  void test_convertToForIndex_OK_onDeclaredIdentifier_type() {
+  test_convertToForIndex_OK_onDeclaredIdentifier_type() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
@@ -1356,7 +1543,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'tring item',
         DartAssistKind.CONVERT_INTO_FOR_INDEX,
         '''
@@ -1369,7 +1556,7 @@
 ''');
   }
 
-  void test_convertToForIndex_OK_onFor() {
+  test_convertToForIndex_OK_onFor() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
@@ -1377,7 +1564,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'for (String',
         DartAssistKind.CONVERT_INTO_FOR_INDEX,
         '''
@@ -1390,7 +1577,7 @@
 ''');
   }
 
-  void test_convertToForIndex_OK_usesI() {
+  test_convertToForIndex_OK_usesI() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
@@ -1398,7 +1585,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'for (String',
         DartAssistKind.CONVERT_INTO_FOR_INDEX,
         '''
@@ -1411,7 +1598,7 @@
 ''');
   }
 
-  void test_convertToForIndex_OK_usesIJ() {
+  test_convertToForIndex_OK_usesIJ() async {
     resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
@@ -1420,7 +1607,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'for (String',
         DartAssistKind.CONVERT_INTO_FOR_INDEX,
         '''
@@ -1434,13 +1621,96 @@
 ''');
   }
 
-  void test_convertToIsNot_OK_childOfIs_left() {
+  test_convertToIsNot_BAD_is_alreadyIsNot() async {
+    resolveTestUnit('''
+main(p) {
+  p is! String;
+}
+''');
+    await assertNoAssistAt('is!', DartAssistKind.CONVERT_INTO_IS_NOT);
+  }
+
+  test_convertToIsNot_BAD_is_noEnclosingParenthesis() async {
+    resolveTestUnit('''
+main(p) {
+  p is String;
+}
+''');
+    await assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT);
+  }
+
+  test_convertToIsNot_BAD_is_noPrefix() async {
+    resolveTestUnit('''
+main(p) {
+  (p is String);
+}
+''');
+    await assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT);
+  }
+
+  test_convertToIsNot_BAD_is_notIsExpression() async {
+    resolveTestUnit('''
+main(p) {
+  123 + 456;
+}
+''');
+    await assertNoAssistAt('123 +', DartAssistKind.CONVERT_INTO_IS_NOT);
+  }
+
+  test_convertToIsNot_BAD_is_notTheNotOperator() async {
+    verifyNoTestUnitErrors = false;
+    resolveTestUnit('''
+main(p) {
+  ++(p is String);
+}
+''');
+    await assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT);
+  }
+
+  test_convertToIsNot_BAD_not_alreadyIsNot() async {
+    resolveTestUnit('''
+main(p) {
+  !(p is! String);
+}
+''');
+    await assertNoAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT);
+  }
+
+  test_convertToIsNot_BAD_not_noEnclosingParenthesis() async {
+    resolveTestUnit('''
+main(p) {
+  !p;
+}
+''');
+    await assertNoAssistAt('!p', DartAssistKind.CONVERT_INTO_IS_NOT);
+  }
+
+  test_convertToIsNot_BAD_not_notIsExpression() async {
+    resolveTestUnit('''
+main(p) {
+  !(p == null);
+}
+''');
+    await assertNoAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT);
+  }
+
+  test_convertToIsNot_BAD_not_notTheNotOperator() async {
+    verifyNoTestUnitErrors = false;
+    resolveTestUnit('''
+main(p) {
+  ++(p is String);
+}
+''');
+    await assertNoAssistAt('++(', DartAssistKind.CONVERT_INTO_IS_NOT);
+  }
+
+  test_convertToIsNot_OK_childOfIs_left() async {
     resolveTestUnit('''
 main(p) {
   !(p is String);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'p is',
         DartAssistKind.CONVERT_INTO_IS_NOT,
         '''
@@ -1450,13 +1720,13 @@
 ''');
   }
 
-  void test_convertToIsNot_OK_childOfIs_right() {
+  test_convertToIsNot_OK_childOfIs_right() async {
     resolveTestUnit('''
 main(p) {
   !(p is String);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'String)',
         DartAssistKind.CONVERT_INTO_IS_NOT,
         '''
@@ -1466,13 +1736,13 @@
 ''');
   }
 
-  void test_convertToIsNot_OK_is() {
+  test_convertToIsNot_OK_is() async {
     resolveTestUnit('''
 main(p) {
   !(p is String);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'is String',
         DartAssistKind.CONVERT_INTO_IS_NOT,
         '''
@@ -1482,13 +1752,13 @@
 ''');
   }
 
-  void test_convertToIsNot_OK_is_higherPrecedencePrefix() {
+  test_convertToIsNot_OK_is_higherPrecedencePrefix() async {
     resolveTestUnit('''
 main(p) {
   !!(p is String);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'is String',
         DartAssistKind.CONVERT_INTO_IS_NOT,
         '''
@@ -1498,13 +1768,13 @@
 ''');
   }
 
-  void test_convertToIsNot_OK_is_not_higherPrecedencePrefix() {
+  test_convertToIsNot_OK_is_not_higherPrecedencePrefix() async {
     resolveTestUnit('''
 main(p) {
   !!(p is String);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '!(p',
         DartAssistKind.CONVERT_INTO_IS_NOT,
         '''
@@ -1514,13 +1784,13 @@
 ''');
   }
 
-  void test_convertToIsNot_OK_not() {
+  test_convertToIsNot_OK_not() async {
     resolveTestUnit('''
 main(p) {
   !(p is String);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '!(p',
         DartAssistKind.CONVERT_INTO_IS_NOT,
         '''
@@ -1530,13 +1800,13 @@
 ''');
   }
 
-  void test_convertToIsNot_OK_parentheses() {
+  test_convertToIsNot_OK_parentheses() async {
     resolveTestUnit('''
 main(p) {
   !(p is String);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '(p is',
         DartAssistKind.CONVERT_INTO_IS_NOT,
         '''
@@ -1546,96 +1816,56 @@
 ''');
   }
 
-  void test_convertToIsNot_wrong_is_alreadyIsNot() {
-    resolveTestUnit('''
-main(p) {
-  p is! String;
-}
-''');
-    assertNoAssistAt('is!', DartAssistKind.CONVERT_INTO_IS_NOT);
-  }
-
-  void test_convertToIsNot_wrong_is_noEnclosingParenthesis() {
-    resolveTestUnit('''
-main(p) {
-  p is String;
-}
-''');
-    assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT);
-  }
-
-  void test_convertToIsNot_wrong_is_noPrefix() {
-    resolveTestUnit('''
-main(p) {
-  (p is String);
-}
-''');
-    assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT);
-  }
-
-  void test_convertToIsNot_wrong_is_notIsExpression() {
-    resolveTestUnit('''
-main(p) {
-  123 + 456;
-}
-''');
-    assertNoAssistAt('123 +', DartAssistKind.CONVERT_INTO_IS_NOT);
-  }
-
-  void test_convertToIsNot_wrong_is_notTheNotOperator() {
+  test_convertToIsNotEmpty_BAD_noBang() async {
     verifyNoTestUnitErrors = false;
     resolveTestUnit('''
-main(p) {
-  ++(p is String);
+main(String str) {
+  ~str.isEmpty;
 }
 ''');
-    assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT);
+    await assertNoAssistAt(
+        'isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
   }
 
-  void test_convertToIsNot_wrong_not_alreadyIsNot() {
+  test_convertToIsNotEmpty_BAD_noIsNotEmpty() async {
     resolveTestUnit('''
-main(p) {
-  !(p is! String);
+class A {
+  bool get isEmpty => false;
+}
+main(A a) {
+  !a.isEmpty;
 }
 ''');
-    assertNoAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT);
+    await assertNoAssistAt(
+        'isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
   }
 
-  void test_convertToIsNot_wrong_not_noEnclosingParenthesis() {
+  test_convertToIsNotEmpty_BAD_notInPrefixExpression() async {
     resolveTestUnit('''
-main(p) {
-  !p;
+main(String str) {
+  str.isEmpty;
 }
 ''');
-    assertNoAssistAt('!p', DartAssistKind.CONVERT_INTO_IS_NOT);
+    await assertNoAssistAt(
+        'isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
   }
 
-  void test_convertToIsNot_wrong_not_notIsExpression() {
+  test_convertToIsNotEmpty_BAD_notIsEmpty() async {
     resolveTestUnit('''
-main(p) {
-  !(p == null);
+main(int p) {
+  !p.isEven;
 }
 ''');
-    assertNoAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT);
+    await assertNoAssistAt('isEven;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
   }
 
-  void test_convertToIsNot_wrong_not_notTheNotOperator() {
-    verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
-main(p) {
-  ++(p is String);
-}
-''');
-    assertNoAssistAt('++(', DartAssistKind.CONVERT_INTO_IS_NOT);
-  }
-
-  void test_convertToIsNotEmpty_OK_on_isEmpty() {
+  test_convertToIsNotEmpty_OK_on_isEmpty() async {
     resolveTestUnit('''
 main(String str) {
   !str.isEmpty;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'isEmpty',
         DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY,
         '''
@@ -1645,13 +1875,13 @@
 ''');
   }
 
-  void test_convertToIsNotEmpty_OK_on_str() {
+  test_convertToIsNotEmpty_OK_on_str() async {
     resolveTestUnit('''
 main(String str) {
   !str.isEmpty;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'str.',
         DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY,
         '''
@@ -1661,13 +1891,13 @@
 ''');
   }
 
-  void test_convertToIsNotEmpty_OK_propertyAccess() {
+  test_convertToIsNotEmpty_OK_propertyAccess() async {
     resolveTestUnit('''
 main(String str) {
   !'text'.isEmpty;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'isEmpty',
         DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY,
         '''
@@ -1677,47 +1907,7 @@
 ''');
   }
 
-  void test_convertToIsNotEmpty_wrong_noBang() {
-    verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
-main(String str) {
-  ~str.isEmpty;
-}
-''');
-    assertNoAssistAt('isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
-  }
-
-  void test_convertToIsNotEmpty_wrong_noIsNotEmpty() {
-    resolveTestUnit('''
-class A {
-  bool get isEmpty => false;
-}
-main(A a) {
-  !a.isEmpty;
-}
-''');
-    assertNoAssistAt('isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
-  }
-
-  void test_convertToIsNotEmpty_wrong_notInPrefixExpression() {
-    resolveTestUnit('''
-main(String str) {
-  str.isEmpty;
-}
-''');
-    assertNoAssistAt('isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
-  }
-
-  void test_convertToIsNotEmpty_wrong_notIsEmpty() {
-    resolveTestUnit('''
-main(int p) {
-  !p.isEven;
-}
-''');
-    assertNoAssistAt('isEven;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
-  }
-
-  void test_convertToNormalParameter_OK_dynamic() {
+  test_convertToNormalParameter_OK_dynamic() async {
     resolveTestUnit('''
 class A {
   var test;
@@ -1725,7 +1915,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'test)',
         DartAssistKind.CONVERT_TO_NORMAL_PARAMETER,
         '''
@@ -1737,7 +1927,7 @@
 ''');
   }
 
-  void test_convertToNormalParameter_OK_firstInitializer() {
+  test_convertToNormalParameter_OK_firstInitializer() async {
     resolveTestUnit('''
 class A {
   int test;
@@ -1745,7 +1935,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'test)',
         DartAssistKind.CONVERT_TO_NORMAL_PARAMETER,
         '''
@@ -1757,7 +1947,7 @@
 ''');
   }
 
-  void test_convertToNormalParameter_OK_secondInitializer() {
+  test_convertToNormalParameter_OK_secondInitializer() async {
     resolveTestUnit('''
 class A {
   double aaa;
@@ -1765,7 +1955,7 @@
   A(this.bbb) : aaa = 1.0;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'bbb)',
         DartAssistKind.CONVERT_TO_NORMAL_PARAMETER,
         '''
@@ -1777,7 +1967,7 @@
 ''');
   }
 
-  void test_encapsulateField_BAD_alreadyPrivate() {
+  test_encapsulateField_BAD_alreadyPrivate() async {
     resolveTestUnit('''
 class A {
   int _test = 42;
@@ -1786,19 +1976,19 @@
   print(a._test);
 }
 ''');
-    assertNoAssistAt('_test =', DartAssistKind.ENCAPSULATE_FIELD);
+    await assertNoAssistAt('_test =', DartAssistKind.ENCAPSULATE_FIELD);
   }
 
-  void test_encapsulateField_BAD_final() {
+  test_encapsulateField_BAD_final() async {
     resolveTestUnit('''
 class A {
   final int test = 42;
 }
 ''');
-    assertNoAssistAt('test =', DartAssistKind.ENCAPSULATE_FIELD);
+    await assertNoAssistAt('test =', DartAssistKind.ENCAPSULATE_FIELD);
   }
 
-  void test_encapsulateField_BAD_multipleFields() {
+  test_encapsulateField_BAD_multipleFields() async {
     resolveTestUnit('''
 class A {
   int aaa, bbb, ccc;
@@ -1807,19 +1997,19 @@
   print(a.bbb);
 }
 ''');
-    assertNoAssistAt('bbb, ', DartAssistKind.ENCAPSULATE_FIELD);
+    await assertNoAssistAt('bbb, ', DartAssistKind.ENCAPSULATE_FIELD);
   }
 
-  void test_encapsulateField_BAD_notOnName() {
+  test_encapsulateField_BAD_notOnName() async {
     resolveTestUnit('''
 class A {
   int test = 1 + 2 + 3;
 }
 ''');
-    assertNoAssistAt('+ 2', DartAssistKind.ENCAPSULATE_FIELD);
+    await assertNoAssistAt('+ 2', DartAssistKind.ENCAPSULATE_FIELD);
   }
 
-  void test_encapsulateField_BAD_parseError() {
+  test_encapsulateField_BAD_parseError() async {
     verifyNoTestUnitErrors = false;
     resolveTestUnit('''
 class A {
@@ -1829,19 +2019,19 @@
   print(a.test);
 }
 ''');
-    assertNoAssistAt('; // marker', DartAssistKind.ENCAPSULATE_FIELD);
+    await assertNoAssistAt('; // marker', DartAssistKind.ENCAPSULATE_FIELD);
   }
 
-  void test_encapsulateField_BAD_static() {
+  test_encapsulateField_BAD_static() async {
     resolveTestUnit('''
 class A {
   static int test = 42;
 }
 ''');
-    assertNoAssistAt('test =', DartAssistKind.ENCAPSULATE_FIELD);
+    await assertNoAssistAt('test =', DartAssistKind.ENCAPSULATE_FIELD);
   }
 
-  void test_encapsulateField_OK_hasType() {
+  test_encapsulateField_OK_hasType() async {
     resolveTestUnit('''
 class A {
   int test = 42;
@@ -1851,7 +2041,7 @@
   print(a.test);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'test = 42',
         DartAssistKind.ENCAPSULATE_FIELD,
         '''
@@ -1871,7 +2061,7 @@
 ''');
   }
 
-  void test_encapsulateField_OK_noType() {
+  test_encapsulateField_OK_noType() async {
     resolveTestUnit('''
 class A {
   var test = 42;
@@ -1880,7 +2070,7 @@
   print(a.test);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'test = 42',
         DartAssistKind.ENCAPSULATE_FIELD,
         '''
@@ -1899,20 +2089,48 @@
 ''');
   }
 
-  void test_exchangeBinaryExpressionArguments_OK_compare() {
-    Map<String, String> operatorMap = {
-      '<': '>',
-      '<=': '>=',
-      '>': '<',
-      '>=': '<='
-    };
-    operatorMap.forEach((initialOperator, resultOperator) {
+  test_exchangeBinaryExpressionArguments_BAD_extraLength() async {
+    resolveTestUnit('''
+main() {
+  111 + 222;
+}
+''');
+    length = 3;
+    await assertNoAssistAt('+ 222', DartAssistKind.EXCHANGE_OPERANDS);
+  }
+
+  test_exchangeBinaryExpressionArguments_BAD_onOperand() async {
+    resolveTestUnit('''
+main() {
+  111 + 222;
+}
+''');
+    length = 3;
+    await assertNoAssistAt('11 +', DartAssistKind.EXCHANGE_OPERANDS);
+  }
+
+  test_exchangeBinaryExpressionArguments_BAD_selectionWithBinary() async {
+    resolveTestUnit('''
+main() {
+  1 + 2 + 3;
+}
+''');
+    length = '1 + 2 + 3'.length;
+    await assertNoAssistAt('1 + 2 + 3', DartAssistKind.EXCHANGE_OPERANDS);
+  }
+
+  test_exchangeBinaryExpressionArguments_OK_compare() async {
+    const initialOperators = const ['<', '<=', '>', '>='];
+    const resultOperators = const ['>', '>=', '<', '<='];
+    for (int i = 0; i <= 0; i++) {
+      String initialOperator = initialOperators[i];
+      String resultOperator = resultOperators[i];
       resolveTestUnit('''
 bool main(int a, int b) {
   return a $initialOperator b;
 }
 ''');
-      assertHasAssistAt(
+      await assertHasAssistAt(
           initialOperator,
           DartAssistKind.EXCHANGE_OPERANDS,
           '''
@@ -1920,16 +2138,16 @@
   return b $resultOperator a;
 }
 ''');
-    });
+    }
   }
 
-  void test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_1() {
+  test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_1() async {
     resolveTestUnit('''
 main() {
   1 * 2 * 3 + 4;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '* 2',
         DartAssistKind.EXCHANGE_OPERANDS,
         '''
@@ -1939,13 +2157,13 @@
 ''');
   }
 
-  void test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_2() {
+  test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_2() async {
     resolveTestUnit('''
 main() {
   1 + 2 - 3 + 4;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '+ 2',
         DartAssistKind.EXCHANGE_OPERANDS,
         '''
@@ -1955,13 +2173,13 @@
 ''');
   }
 
-  void test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterFirst() {
+  test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterFirst() async {
     resolveTestUnit('''
 main() {
   1 + 2 + 3;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '+ 2',
         DartAssistKind.EXCHANGE_OPERANDS,
         '''
@@ -1971,13 +2189,13 @@
 ''');
   }
 
-  void test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterSecond() {
+  test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterSecond() async {
     resolveTestUnit('''
 main() {
   1 + 2 + 3;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '+ 3',
         DartAssistKind.EXCHANGE_OPERANDS,
         '''
@@ -1987,13 +2205,13 @@
 ''');
   }
 
-  void test_exchangeBinaryExpressionArguments_OK_simple_afterOperator() {
+  test_exchangeBinaryExpressionArguments_OK_simple_afterOperator() async {
     resolveTestUnit('''
 main() {
   1 + 2;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         ' 2',
         DartAssistKind.EXCHANGE_OPERANDS,
         '''
@@ -2003,13 +2221,13 @@
 ''');
   }
 
-  void test_exchangeBinaryExpressionArguments_OK_simple_beforeOperator() {
+  test_exchangeBinaryExpressionArguments_OK_simple_beforeOperator() async {
     resolveTestUnit('''
 main() {
   1 + 2;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '+ 2',
         DartAssistKind.EXCHANGE_OPERANDS,
         '''
@@ -2019,14 +2237,14 @@
 ''');
   }
 
-  void test_exchangeBinaryExpressionArguments_OK_simple_fullSelection() {
+  test_exchangeBinaryExpressionArguments_OK_simple_fullSelection() async {
     resolveTestUnit('''
 main() {
   1 + 2;
 }
 ''');
     length = '1 + 2'.length;
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '1 + 2',
         DartAssistKind.EXCHANGE_OPERANDS,
         '''
@@ -2036,14 +2254,14 @@
 ''');
   }
 
-  void test_exchangeBinaryExpressionArguments_OK_simple_withLength() {
+  test_exchangeBinaryExpressionArguments_OK_simple_withLength() async {
     resolveTestUnit('''
 main() {
   1 + 2;
 }
 ''');
     length = 2;
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '+ 2',
         DartAssistKind.EXCHANGE_OPERANDS,
         '''
@@ -2053,61 +2271,31 @@
 ''');
   }
 
-  void test_exchangeBinaryExpressionArguments_wrong_extraLength() {
-    resolveTestUnit('''
-main() {
-  111 + 222;
-}
-''');
-    length = 3;
-    assertNoAssistAt('+ 222', DartAssistKind.EXCHANGE_OPERANDS);
-  }
-
-  void test_exchangeBinaryExpressionArguments_wrong_onOperand() {
-    resolveTestUnit('''
-main() {
-  111 + 222;
-}
-''');
-    length = 3;
-    assertNoAssistAt('11 +', DartAssistKind.EXCHANGE_OPERANDS);
-  }
-
-  void test_exchangeBinaryExpressionArguments_wrong_selectionWithBinary() {
-    resolveTestUnit('''
-main() {
-  1 + 2 + 3;
-}
-''');
-    length = '1 + 2 + 3'.length;
-    assertNoAssistAt('1 + 2 + 3', DartAssistKind.EXCHANGE_OPERANDS);
-  }
-
-  void test_importAddShow_BAD_hasShow() {
+  test_importAddShow_BAD_hasShow() async {
     resolveTestUnit('''
 import 'dart:math' show PI;
 main() {
   PI;
 }
 ''');
-    assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
+    await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
   }
 
-  void test_importAddShow_BAD_unresolvedUri() {
+  test_importAddShow_BAD_unresolvedUri() async {
     resolveTestUnit('''
 import '/no/such/lib.dart';
 ''');
-    assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
+    await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
   }
 
-  void test_importAddShow_BAD_unused() {
+  test_importAddShow_BAD_unused() async {
     resolveTestUnit('''
 import 'dart:math';
 ''');
-    assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
+    await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
   }
 
-  void test_importAddShow_OK_hasUnresolvedIdentifier() {
+  test_importAddShow_OK_hasUnresolvedIdentifier() async {
     resolveTestUnit('''
 import 'dart:math';
 main(x) {
@@ -2115,7 +2303,7 @@
   return x.foo();
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'import ',
         DartAssistKind.IMPORT_ADD_SHOW,
         '''
@@ -2127,7 +2315,7 @@
 ''');
   }
 
-  void test_importAddShow_OK_onDirective() {
+  test_importAddShow_OK_onDirective() async {
     resolveTestUnit('''
 import 'dart:math';
 main() {
@@ -2136,7 +2324,7 @@
   max(1, 2);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'import ',
         DartAssistKind.IMPORT_ADD_SHOW,
         '''
@@ -2149,7 +2337,7 @@
 ''');
   }
 
-  void test_importAddShow_OK_onUri() {
+  test_importAddShow_OK_onUri() async {
     resolveTestUnit('''
 import 'dart:math';
 main() {
@@ -2158,7 +2346,7 @@
   max(1, 2);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'art:math',
         DartAssistKind.IMPORT_ADD_SHOW,
         '''
@@ -2171,27 +2359,27 @@
 ''');
   }
 
-  void test_introduceLocalTestedType_BAD_notBlock() {
+  test_introduceLocalTestedType_BAD_notBlock() async {
     resolveTestUnit('''
 main(p) {
   if (p is String)
     print('not a block');
 }
 ''');
-    assertNoAssistAt('if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE);
+    await assertNoAssistAt('if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE);
   }
 
-  void test_introduceLocalTestedType_BAD_notIsExpression() {
+  test_introduceLocalTestedType_BAD_notIsExpression() async {
     resolveTestUnit('''
 main(p) {
   if (p == null) {
   }
 }
 ''');
-    assertNoAssistAt('if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE);
+    await assertNoAssistAt('if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE);
   }
 
-  void test_introduceLocalTestedType_OK_if_is() {
+  test_introduceLocalTestedType_OK_if_is() async {
     resolveTestUnit('''
 class MyTypeName {}
 main(p) {
@@ -2209,7 +2397,7 @@
   p = null;
 }
 ''';
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'is MyType', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
     _assertLinkedGroup(
         change.linkedEditGroups[0],
@@ -2217,11 +2405,11 @@
         expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
             ['myTypeName', 'typeName', 'name']));
     // another good location
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
   }
 
-  void test_introduceLocalTestedType_OK_if_isNot() {
+  test_introduceLocalTestedType_OK_if_isNot() async {
     resolveTestUnit('''
 class MyTypeName {}
 main(p) {
@@ -2239,7 +2427,7 @@
   MyTypeName myTypeName = p;
 }
 ''';
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'is! MyType', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
     _assertLinkedGroup(
         change.linkedEditGroups[0],
@@ -2247,11 +2435,11 @@
         expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
             ['myTypeName', 'typeName', 'name']));
     // another good location
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
   }
 
-  void test_introduceLocalTestedType_OK_while() {
+  test_introduceLocalTestedType_OK_while() async {
     resolveTestUnit('''
 main(p) {
   while (p is String) {
@@ -2267,20 +2455,20 @@
   p = null;
 }
 ''';
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'is String', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'while (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
   }
 
-  void test_invalidSelection() {
+  test_invalidSelection() async {
     resolveTestUnit('');
     List<Assist> assists =
-        computeAssists(plugin, context, testUnit.element.source, -1, 0);
+        await computeAssists(plugin, context, testUnit.element.source, -1, 0);
     expect(assists, isEmpty);
   }
 
-  void test_invertIfStatement_blocks() {
+  test_invertIfStatement_blocks() async {
     resolveTestUnit('''
 main() {
   if (true) {
@@ -2290,7 +2478,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (',
         DartAssistKind.INVERT_IF_STATEMENT,
         '''
@@ -2304,7 +2492,7 @@
 ''');
   }
 
-  void test_invertIfStatement_statements() {
+  test_invertIfStatement_statements() async {
     resolveTestUnit('''
 main() {
   if (true)
@@ -2313,7 +2501,7 @@
     1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (',
         DartAssistKind.INVERT_IF_STATEMENT,
         '''
@@ -2326,7 +2514,85 @@
 ''');
   }
 
-  void test_joinIfStatementInner_OK_conditionAndOr() {
+  test_joinIfStatementInner_BAD_innerNotIf() async {
+    resolveTestUnit('''
+main() {
+  if (1 == 1) {
+    print(0);
+  }
+}
+''');
+    await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
+  }
+
+  test_joinIfStatementInner_BAD_innerWithElse() async {
+    resolveTestUnit('''
+main() {
+  if (1 == 1) {
+    if (2 == 2) {
+      print(0);
+    } else {
+      print(1);
+    }
+  }
+}
+''');
+    await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
+  }
+
+  test_joinIfStatementInner_BAD_statementAfterInner() async {
+    resolveTestUnit('''
+main() {
+  if (1 == 1) {
+    if (2 == 2) {
+      print(2);
+    }
+    print(1);
+  }
+}
+''');
+    await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
+  }
+
+  test_joinIfStatementInner_BAD_statementBeforeInner() async {
+    resolveTestUnit('''
+main() {
+  if (1 == 1) {
+    print(1);
+    if (2 == 2) {
+      print(2);
+    }
+  }
+}
+''');
+    await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
+  }
+
+  test_joinIfStatementInner_BAD_targetNotIf() async {
+    resolveTestUnit('''
+main() {
+  print(0);
+}
+''');
+    await assertNoAssistAt('print', DartAssistKind.JOIN_IF_WITH_INNER);
+  }
+
+  test_joinIfStatementInner_BAD_targetWithElse() async {
+    resolveTestUnit('''
+main() {
+  if (1 == 1) {
+    if (2 == 2) {
+      print(0);
+    }
+  } else {
+    print(1);
+  }
+}
+''');
+    await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
+  }
+
+  test_joinIfStatementInner_OK_conditionAndOr() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2336,7 +2602,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (1 ==',
         DartAssistKind.JOIN_IF_WITH_INNER,
         '''
@@ -2348,7 +2614,7 @@
 ''');
   }
 
-  void test_joinIfStatementInner_OK_conditionInvocation() {
+  test_joinIfStatementInner_OK_conditionInvocation() async {
     resolveTestUnit('''
 main() {
   if (isCheck()) {
@@ -2359,7 +2625,7 @@
 }
 bool isCheck() => false;
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (isCheck',
         DartAssistKind.JOIN_IF_WITH_INNER,
         '''
@@ -2372,7 +2638,7 @@
 ''');
   }
 
-  void test_joinIfStatementInner_OK_conditionOrAnd() {
+  test_joinIfStatementInner_OK_conditionOrAnd() async {
     resolveTestUnit('''
 main() {
   if (1 == 1 || 2 == 2) {
@@ -2382,7 +2648,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (1 ==',
         DartAssistKind.JOIN_IF_WITH_INNER,
         '''
@@ -2394,7 +2660,7 @@
 ''');
   }
 
-  void test_joinIfStatementInner_OK_onCondition() {
+  test_joinIfStatementInner_OK_onCondition() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2404,7 +2670,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '1 ==',
         DartAssistKind.JOIN_IF_WITH_INNER,
         '''
@@ -2416,7 +2682,7 @@
 ''');
   }
 
-  void test_joinIfStatementInner_OK_simpleConditions_block_block() {
+  test_joinIfStatementInner_OK_simpleConditions_block_block() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2426,7 +2692,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (1 ==',
         DartAssistKind.JOIN_IF_WITH_INNER,
         '''
@@ -2438,7 +2704,7 @@
 ''');
   }
 
-  void test_joinIfStatementInner_OK_simpleConditions_block_single() {
+  test_joinIfStatementInner_OK_simpleConditions_block_single() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2447,7 +2713,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (1 ==',
         DartAssistKind.JOIN_IF_WITH_INNER,
         '''
@@ -2459,7 +2725,7 @@
 ''');
   }
 
-  void test_joinIfStatementInner_OK_simpleConditions_single_blockMulti() {
+  test_joinIfStatementInner_OK_simpleConditions_single_blockMulti() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2471,7 +2737,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (1 ==',
         DartAssistKind.JOIN_IF_WITH_INNER,
         '''
@@ -2485,7 +2751,7 @@
 ''');
   }
 
-  void test_joinIfStatementInner_OK_simpleConditions_single_blockOne() {
+  test_joinIfStatementInner_OK_simpleConditions_single_blockOne() async {
     resolveTestUnit('''
 main() {
   if (1 == 1)
@@ -2494,7 +2760,7 @@
     }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (1 ==',
         DartAssistKind.JOIN_IF_WITH_INNER,
         '''
@@ -2506,7 +2772,7 @@
 ''');
   }
 
-  void test_joinIfStatementInner_wrong_innerNotIf() {
+  test_joinIfStatementOuter_BAD_outerNotIf() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2514,34 +2780,10 @@
   }
 }
 ''');
-    assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
+    await assertNoAssistAt('if (1 == 1', DartAssistKind.JOIN_IF_WITH_OUTER);
   }
 
-  void test_joinIfStatementInner_wrong_innerWithElse() {
-    resolveTestUnit('''
-main() {
-  if (1 == 1) {
-    if (2 == 2) {
-      print(0);
-    } else {
-      print(1);
-    }
-  }
-}
-''');
-    assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
-  }
-
-  void test_joinIfStatementInner_wrong_targetNotIf() {
-    resolveTestUnit('''
-main() {
-  print(0);
-}
-''');
-    assertNoAssistAt('print', DartAssistKind.JOIN_IF_WITH_INNER);
-  }
-
-  void test_joinIfStatementInner_wrong_targetWithElse() {
+  test_joinIfStatementOuter_BAD_outerWithElse() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2553,10 +2795,62 @@
   }
 }
 ''');
-    assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
+    await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
   }
 
-  void test_joinIfStatementOuter_OK_conditionAndOr() {
+  test_joinIfStatementOuter_BAD_statementAfterInner() async {
+    resolveTestUnit('''
+main() {
+  if (1 == 1) {
+    if (2 == 2) {
+      print(2);
+    }
+    print(1);
+  }
+}
+''');
+    await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
+  }
+
+  test_joinIfStatementOuter_BAD_statementBeforeInner() async {
+    resolveTestUnit('''
+main() {
+  if (1 == 1) {
+    print(1);
+    if (2 == 2) {
+      print(2);
+    }
+  }
+}
+''');
+    await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
+  }
+
+  test_joinIfStatementOuter_BAD_targetNotIf() async {
+    resolveTestUnit('''
+main() {
+  print(0);
+}
+''');
+    await assertNoAssistAt('print', DartAssistKind.JOIN_IF_WITH_OUTER);
+  }
+
+  test_joinIfStatementOuter_BAD_targetWithElse() async {
+    resolveTestUnit('''
+main() {
+  if (1 == 1) {
+    if (2 == 2) {
+      print(0);
+    } else {
+      print(1);
+    }
+  }
+}
+''');
+    await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
+  }
+
+  test_joinIfStatementOuter_OK_conditionAndOr() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2566,7 +2860,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (2 ==',
         DartAssistKind.JOIN_IF_WITH_OUTER,
         '''
@@ -2578,7 +2872,7 @@
 ''');
   }
 
-  void test_joinIfStatementOuter_OK_conditionInvocation() {
+  test_joinIfStatementOuter_OK_conditionInvocation() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2589,7 +2883,7 @@
 }
 bool isCheck() => false;
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (isCheck',
         DartAssistKind.JOIN_IF_WITH_OUTER,
         '''
@@ -2602,7 +2896,7 @@
 ''');
   }
 
-  void test_joinIfStatementOuter_OK_conditionOrAnd() {
+  test_joinIfStatementOuter_OK_conditionOrAnd() async {
     resolveTestUnit('''
 main() {
   if (1 == 1 || 2 == 2) {
@@ -2612,7 +2906,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (3 == 3',
         DartAssistKind.JOIN_IF_WITH_OUTER,
         '''
@@ -2624,7 +2918,7 @@
 ''');
   }
 
-  void test_joinIfStatementOuter_OK_onCondition() {
+  test_joinIfStatementOuter_OK_onCondition() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2634,7 +2928,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (2 == 2',
         DartAssistKind.JOIN_IF_WITH_OUTER,
         '''
@@ -2646,7 +2940,7 @@
 ''');
   }
 
-  void test_joinIfStatementOuter_OK_simpleConditions_block_block() {
+  test_joinIfStatementOuter_OK_simpleConditions_block_block() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2656,7 +2950,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (2 == 2',
         DartAssistKind.JOIN_IF_WITH_OUTER,
         '''
@@ -2668,7 +2962,7 @@
 ''');
   }
 
-  void test_joinIfStatementOuter_OK_simpleConditions_block_single() {
+  test_joinIfStatementOuter_OK_simpleConditions_block_single() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2677,7 +2971,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (2 == 2',
         DartAssistKind.JOIN_IF_WITH_OUTER,
         '''
@@ -2689,7 +2983,7 @@
 ''');
   }
 
-  void test_joinIfStatementOuter_OK_simpleConditions_single_blockMulti() {
+  test_joinIfStatementOuter_OK_simpleConditions_single_blockMulti() async {
     resolveTestUnit('''
 main() {
   if (1 == 1) {
@@ -2701,7 +2995,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (2 == 2',
         DartAssistKind.JOIN_IF_WITH_OUTER,
         '''
@@ -2715,7 +3009,7 @@
 ''');
   }
 
-  void test_joinIfStatementOuter_OK_simpleConditions_single_blockOne() {
+  test_joinIfStatementOuter_OK_simpleConditions_single_blockOne() async {
     resolveTestUnit('''
 main() {
   if (1 == 1)
@@ -2724,7 +3018,7 @@
     }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (2 == 2',
         DartAssistKind.JOIN_IF_WITH_OUTER,
         '''
@@ -2736,64 +3030,98 @@
 ''');
   }
 
-  void test_joinIfStatementOuter_wrong_outerNotIf() {
+  test_joinVariableDeclaration_onAssignment_BAD_hasInitializer() async {
     resolveTestUnit('''
 main() {
-  if (1 == 1) {
-    print(0);
+  var v = 1;
+  v = 2;
+}
+''');
+    await assertNoAssistAt('v = 2', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+  }
+
+  test_joinVariableDeclaration_onAssignment_BAD_notAdjacent() async {
+    resolveTestUnit('''
+main() {
+  var v;
+  var bar;
+  v = 1;
+}
+''');
+    await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+  }
+
+  test_joinVariableDeclaration_onAssignment_BAD_notAssignment() async {
+    resolveTestUnit('''
+main() {
+  var v;
+  v += 1;
+}
+''');
+    await assertNoAssistAt('v += 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+  }
+
+  test_joinVariableDeclaration_onAssignment_BAD_notDeclaration() async {
+    resolveTestUnit('''
+main(var v) {
+  v = 1;
+}
+''');
+    await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+  }
+
+  test_joinVariableDeclaration_onAssignment_BAD_notLeftArgument() async {
+    resolveTestUnit('''
+main() {
+  var v;
+  1 + v; // marker
+}
+''');
+    await assertNoAssistAt(
+        'v; // marker', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+  }
+
+  test_joinVariableDeclaration_onAssignment_BAD_notOneVariable() async {
+    resolveTestUnit('''
+main() {
+  var v, v2;
+  v = 1;
+}
+''');
+    await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+  }
+
+  test_joinVariableDeclaration_onAssignment_BAD_notResolved() async {
+    verifyNoTestUnitErrors = false;
+    resolveTestUnit('''
+main() {
+  var v;
+  x = 1;
+}
+''');
+    await assertNoAssistAt('x = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+  }
+
+  test_joinVariableDeclaration_onAssignment_BAD_notSameBlock() async {
+    resolveTestUnit('''
+main() {
+  var v;
+  {
+    v = 1;
   }
 }
 ''');
-    assertNoAssistAt('if (1 == 1', DartAssistKind.JOIN_IF_WITH_OUTER);
+    await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
   }
 
-  void test_joinIfStatementOuter_wrong_outerWithElse() {
-    resolveTestUnit('''
-main() {
-  if (1 == 1) {
-    if (2 == 2) {
-      print(0);
-    }
-  } else {
-    print(1);
-  }
-}
-''');
-    assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
-  }
-
-  void test_joinIfStatementOuter_wrong_targetNotIf() {
-    resolveTestUnit('''
-main() {
-  print(0);
-}
-''');
-    assertNoAssistAt('print', DartAssistKind.JOIN_IF_WITH_OUTER);
-  }
-
-  void test_joinIfStatementOuter_wrong_targetWithElse() {
-    resolveTestUnit('''
-main() {
-  if (1 == 1) {
-    if (2 == 2) {
-      print(0);
-    } else {
-      print(1);
-    }
-  }
-}
-''');
-    assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
-  }
-
-  void test_joinVariableDeclaration_onAssignment_OK() {
+  test_joinVariableDeclaration_onAssignment_OK() async {
     resolveTestUnit('''
 main() {
   var v;
   v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.JOIN_VARIABLE_DECLARATION,
         '''
@@ -2803,97 +3131,74 @@
 ''');
   }
 
-  void test_joinVariableDeclaration_onAssignment_wrong_hasInitializer() {
+  test_joinVariableDeclaration_onDeclaration_BAD_hasInitializer() async {
     resolveTestUnit('''
 main() {
   var v = 1;
   v = 2;
 }
 ''');
-    assertNoAssistAt('v = 2', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+    await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
   }
 
-  void test_joinVariableDeclaration_onAssignment_wrong_notAdjacent() {
+  test_joinVariableDeclaration_onDeclaration_BAD_lastStatement() async {
+    resolveTestUnit('''
+main() {
+  if (true)
+    var v;
+}
+''');
+    await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+  }
+
+  test_joinVariableDeclaration_onDeclaration_BAD_nextNotAssignmentExpression() async {
     resolveTestUnit('''
 main() {
   var v;
-  var bar;
-  v = 1;
+  42;
 }
 ''');
-    assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+    await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
   }
 
-  void test_joinVariableDeclaration_onAssignment_wrong_notAssignment() {
+  test_joinVariableDeclaration_onDeclaration_BAD_nextNotExpressionStatement() async {
+    resolveTestUnit('''
+main() {
+  var v;
+  if (true) return;
+}
+''');
+    await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+  }
+
+  test_joinVariableDeclaration_onDeclaration_BAD_nextNotPureAssignment() async {
     resolveTestUnit('''
 main() {
   var v;
   v += 1;
 }
 ''');
-    assertNoAssistAt('v += 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+    await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
   }
 
-  void test_joinVariableDeclaration_onAssignment_wrong_notDeclaration() {
-    resolveTestUnit('''
-main(var v) {
-  v = 1;
-}
-''');
-    assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_joinVariableDeclaration_onAssignment_wrong_notLeftArgument() {
-    resolveTestUnit('''
-main() {
-  var v;
-  1 + v; // marker
-}
-''');
-    assertNoAssistAt('v; // marker', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_joinVariableDeclaration_onAssignment_wrong_notOneVariable() {
+  test_joinVariableDeclaration_onDeclaration_BAD_notOneVariable() async {
     resolveTestUnit('''
 main() {
   var v, v2;
   v = 1;
 }
 ''');
-    assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
+    await assertNoAssistAt('v, ', DartAssistKind.JOIN_VARIABLE_DECLARATION);
   }
 
-  void test_joinVariableDeclaration_onAssignment_wrong_notResolved() {
-    verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
-main() {
-  var v;
-  x = 1;
-}
-''');
-    assertNoAssistAt('x = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_joinVariableDeclaration_onAssignment_wrong_notSameBlock() {
-    resolveTestUnit('''
-main() {
-  var v;
-  {
-    v = 1;
-  }
-}
-''');
-    assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_joinVariableDeclaration_onDeclaration_OK_onName() {
+  test_joinVariableDeclaration_onDeclaration_OK_onName() async {
     resolveTestUnit('''
 main() {
   var v;
   v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v;',
         DartAssistKind.JOIN_VARIABLE_DECLARATION,
         '''
@@ -2903,14 +3208,14 @@
 ''');
   }
 
-  void test_joinVariableDeclaration_onDeclaration_OK_onType() {
+  test_joinVariableDeclaration_onDeclaration_OK_onType() async {
     resolveTestUnit('''
 main() {
   int v;
   v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'int v',
         DartAssistKind.JOIN_VARIABLE_DECLARATION,
         '''
@@ -2920,14 +3225,14 @@
 ''');
   }
 
-  void test_joinVariableDeclaration_onDeclaration_OK_onVar() {
+  test_joinVariableDeclaration_onDeclaration_OK_onVar() async {
     resolveTestUnit('''
 main() {
   var v;
   v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'var v',
         DartAssistKind.JOIN_VARIABLE_DECLARATION,
         '''
@@ -2937,73 +3242,13 @@
 ''');
   }
 
-  void test_joinVariableDeclaration_onDeclaration_wrong_hasInitializer() {
-    resolveTestUnit('''
-main() {
-  var v = 1;
-  v = 2;
-}
-''');
-    assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_joinVariableDeclaration_onDeclaration_wrong_lastStatement() {
-    resolveTestUnit('''
-main() {
-  if (true)
-    var v;
-}
-''');
-    assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_joinVariableDeclaration_onDeclaration_wrong_nextNotAssignmentExpression() {
-    resolveTestUnit('''
-main() {
-  var v;
-  42;
-}
-''');
-    assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_joinVariableDeclaration_onDeclaration_wrong_nextNotExpressionStatement() {
-    resolveTestUnit('''
-main() {
-  var v;
-  if (true) return;
-}
-''');
-    assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_joinVariableDeclaration_onDeclaration_wrong_nextNotPureAssignment() {
-    resolveTestUnit('''
-main() {
-  var v;
-  v += 1;
-}
-''');
-    assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_joinVariableDeclaration_onDeclaration_wrong_notOneVariable() {
-    resolveTestUnit('''
-main() {
-  var v, v2;
-  v = 1;
-}
-''');
-    assertNoAssistAt('v, ', DartAssistKind.JOIN_VARIABLE_DECLARATION);
-  }
-
-  void test_removeTypeAnnotation_classField_OK() {
+  test_removeTypeAnnotation_classField_OK() async {
     resolveTestUnit('''
 class A {
   int v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v = ',
         DartAssistKind.REMOVE_TYPE_ANNOTATION,
         '''
@@ -3013,13 +3258,13 @@
 ''');
   }
 
-  void test_removeTypeAnnotation_classField_OK_final() {
+  test_removeTypeAnnotation_classField_OK_final() async {
     resolveTestUnit('''
 class A {
   final int v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v = ',
         DartAssistKind.REMOVE_TYPE_ANNOTATION,
         '''
@@ -3029,13 +3274,13 @@
 ''');
   }
 
-  void test_removeTypeAnnotation_localVariable_OK() {
+  test_removeTypeAnnotation_localVariable_OK() async {
     resolveTestUnit('''
 main() {
   int a = 1, b = 2;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'int ',
         DartAssistKind.REMOVE_TYPE_ANNOTATION,
         '''
@@ -3045,13 +3290,13 @@
 ''');
   }
 
-  void test_removeTypeAnnotation_localVariable_OK_const() {
+  test_removeTypeAnnotation_localVariable_OK_const() async {
     resolveTestUnit('''
 main() {
   const int v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'int ',
         DartAssistKind.REMOVE_TYPE_ANNOTATION,
         '''
@@ -3061,13 +3306,13 @@
 ''');
   }
 
-  void test_removeTypeAnnotation_localVariable_OK_final() {
+  test_removeTypeAnnotation_localVariable_OK_final() async {
     resolveTestUnit('''
 main() {
   final int v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'int ',
         DartAssistKind.REMOVE_TYPE_ANNOTATION,
         '''
@@ -3077,11 +3322,11 @@
 ''');
   }
 
-  void test_removeTypeAnnotation_topLevelVariable_OK() {
+  test_removeTypeAnnotation_topLevelVariable_OK() async {
     resolveTestUnit('''
 int V = 1;
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'int ',
         DartAssistKind.REMOVE_TYPE_ANNOTATION,
         '''
@@ -3089,11 +3334,11 @@
 ''');
   }
 
-  void test_removeTypeAnnotation_topLevelVariable_OK_final() {
+  test_removeTypeAnnotation_topLevelVariable_OK_final() async {
     resolveTestUnit('''
 final int V = 1;
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'int ',
         DartAssistKind.REMOVE_TYPE_ANNOTATION,
         '''
@@ -3101,7 +3346,25 @@
 ''');
   }
 
-  void test_replaceConditionalWithIfElse_OK_assignment() {
+  test_replaceConditionalWithIfElse_BAD_noEnclosingStatement() async {
+    resolveTestUnit('''
+var v = true ? 111 : 222;
+''');
+    await assertNoAssistAt(
+        '? 111', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE);
+  }
+
+  test_replaceConditionalWithIfElse_BAD_notConditional() async {
+    resolveTestUnit('''
+main() {
+  var v = 42;
+}
+''');
+    await assertNoAssistAt(
+        'v = 42', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE);
+  }
+
+  test_replaceConditionalWithIfElse_OK_assignment() async {
     resolveTestUnit('''
 main() {
   var v;
@@ -3109,7 +3372,7 @@
 }
 ''');
     // on conditional
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '11 :',
         DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
         '''
@@ -3123,7 +3386,7 @@
 }
 ''');
     // on variable
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
         '''
@@ -3138,13 +3401,13 @@
 ''');
   }
 
-  void test_replaceConditionalWithIfElse_OK_return() {
+  test_replaceConditionalWithIfElse_OK_return() async {
     resolveTestUnit('''
 main() {
   return true ? 111 : 222;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'return ',
         DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
         '''
@@ -3158,13 +3421,13 @@
 ''');
   }
 
-  void test_replaceConditionalWithIfElse_OK_variableDeclaration() {
+  test_replaceConditionalWithIfElse_OK_variableDeclaration() async {
     resolveTestUnit('''
 main() {
   int a = 1, vvv = true ? 111 : 222, b = 2;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '11 :',
         DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
         '''
@@ -3179,23 +3442,48 @@
 ''');
   }
 
-  void test_replaceConditionalWithIfElse_wrong_noEnclosingStatement() {
-    resolveTestUnit('''
-var v = true ? 111 : 222;
-''');
-    assertNoAssistAt('? 111', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE);
-  }
-
-  void test_replaceConditionalWithIfElse_wrong_notConditional() {
+  test_replaceIfElseWithConditional_BAD_expressionVsReturn() async {
     resolveTestUnit('''
 main() {
-  var v = 42;
+  if (true) {
+    print(42);
+  } else {
+    return;
+  }
 }
 ''');
-    assertNoAssistAt('v = 42', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE);
+    await assertNoAssistAt(
+        'else', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
   }
 
-  void test_replaceIfElseWithConditional_OK_assignment() {
+  test_replaceIfElseWithConditional_BAD_notIfStatement() async {
+    resolveTestUnit('''
+main() {
+  print(0);
+}
+''');
+    await assertNoAssistAt(
+        'print', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
+  }
+
+  test_replaceIfElseWithConditional_BAD_notSingleStatement() async {
+    resolveTestUnit('''
+main() {
+  int vvv;
+  if (true) {
+    print(0);
+    vvv = 111;
+  } else {
+    print(0);
+    vvv = 222;
+  }
+}
+''');
+    await assertNoAssistAt(
+        'if (true)', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
+  }
+
+  test_replaceIfElseWithConditional_OK_assignment() async {
     resolveTestUnit('''
 main() {
   int vvv;
@@ -3206,7 +3494,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (true)',
         DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL,
         '''
@@ -3217,7 +3505,7 @@
 ''');
   }
 
-  void test_replaceIfElseWithConditional_OK_return() {
+  test_replaceIfElseWithConditional_OK_return() async {
     resolveTestUnit('''
 main() {
   if (true) {
@@ -3227,7 +3515,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'if (true)',
         DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL,
         '''
@@ -3237,46 +3525,55 @@
 ''');
   }
 
-  void test_replaceIfElseWithConditional_wrong_expressionVsReturn() {
+  test_splitAndCondition_BAD_hasElse() async {
     resolveTestUnit('''
 main() {
-  if (true) {
-    print(42);
+  if (1 == 1 && 2 == 2) {
+    print(1);
   } else {
-    return;
+    print(2);
   }
 }
 ''');
-    assertNoAssistAt('else', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
+    await assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION);
   }
 
-  void test_replaceIfElseWithConditional_wrong_notIfStatement() {
+  test_splitAndCondition_BAD_notAnd() async {
     resolveTestUnit('''
 main() {
-  print(0);
+  if (1 == 1 || 2 == 2) {
+    print(0);
+  }
 }
 ''');
-    assertNoAssistAt('print', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
+    await assertNoAssistAt('|| 2', DartAssistKind.SPLIT_AND_CONDITION);
   }
 
-  void test_replaceIfElseWithConditional_wrong_notSingleStatememt() {
+  test_splitAndCondition_BAD_notPartOfIf() async {
     resolveTestUnit('''
 main() {
-  int vvv;
-  if (true) {
+  print(1 == 1 && 2 == 2);
+}
+''');
+    await assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION);
+  }
+
+  test_splitAndCondition_BAD_notTopLevelAnd() async {
+    resolveTestUnit('''
+main() {
+  if (true || (1 == 1 && 2 == 2)) {
     print(0);
-    vvv = 111;
-  } else {
+  }
+  if (true && (3 == 3 && 4 == 4)) {
     print(0);
-    vvv = 222;
   }
 }
 ''');
-    assertNoAssistAt(
-        'if (true)', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
+    await assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION);
+    await assertNoAssistAt('&& 4', DartAssistKind.SPLIT_AND_CONDITION);
   }
 
-  void test_splitAndCondition_OK_innerAndExpression() {
+  test_splitAndCondition_OK_innerAndExpression() async {
     resolveTestUnit('''
 main() {
   if (1 == 1 && 2 == 2 && 3 == 3) {
@@ -3284,7 +3581,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '&& 2 == 2',
         DartAssistKind.SPLIT_AND_CONDITION,
         '''
@@ -3298,7 +3595,7 @@
 ''');
   }
 
-  void test_splitAndCondition_OK_thenBlock() {
+  test_splitAndCondition_OK_thenBlock() async {
     resolveTestUnit('''
 main() {
   if (true && false) {
@@ -3309,7 +3606,7 @@
   }
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '&& false',
         DartAssistKind.SPLIT_AND_CONDITION,
         '''
@@ -3326,14 +3623,14 @@
 ''');
   }
 
-  void test_splitAndCondition_OK_thenStatement() {
+  test_splitAndCondition_OK_thenStatement() async {
     resolveTestUnit('''
 main() {
   if (true && false)
     print(0);
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         '&& false',
         DartAssistKind.SPLIT_AND_CONDITION,
         '''
@@ -3345,7 +3642,7 @@
 ''');
   }
 
-  void test_splitAndCondition_wrong() {
+  test_splitAndCondition_wrong() async {
     resolveTestUnit('''
 main() {
   if (1 == 1 && 2 == 2) {
@@ -3355,69 +3652,30 @@
 }
 ''');
     // not binary expression
-    assertNoAssistAt('main() {', DartAssistKind.SPLIT_AND_CONDITION);
+    await assertNoAssistAt('main() {', DartAssistKind.SPLIT_AND_CONDITION);
     // selection is not empty and includes more than just operator
     {
       length = 5;
-      assertNoAssistAt('&& 2 == 2', DartAssistKind.SPLIT_AND_CONDITION);
+      await assertNoAssistAt('&& 2 == 2', DartAssistKind.SPLIT_AND_CONDITION);
     }
   }
 
-  void test_splitAndCondition_wrong_hasElse() {
+  test_splitVariableDeclaration_BAD_notOneVariable() async {
     resolveTestUnit('''
 main() {
-  if (1 == 1 && 2 == 2) {
-    print(1);
-  } else {
-    print(2);
-  }
+  var v = 1, v2;
 }
 ''');
-    assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION);
+    await assertNoAssistAt('v = 1', DartAssistKind.SPLIT_VARIABLE_DECLARATION);
   }
 
-  void test_splitAndCondition_wrong_notAnd() {
-    resolveTestUnit('''
-main() {
-  if (1 == 1 || 2 == 2) {
-    print(0);
-  }
-}
-''');
-    assertNoAssistAt('|| 2', DartAssistKind.SPLIT_AND_CONDITION);
-  }
-
-  void test_splitAndCondition_wrong_notPartOfIf() {
-    resolveTestUnit('''
-main() {
-  print(1 == 1 && 2 == 2);
-}
-''');
-    assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION);
-  }
-
-  void test_splitAndCondition_wrong_notTopLevelAnd() {
-    resolveTestUnit('''
-main() {
-  if (true || (1 == 1 && 2 == 2)) {
-    print(0);
-  }
-  if (true && (3 == 3 && 4 == 4)) {
-    print(0);
-  }
-}
-''');
-    assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION);
-    assertNoAssistAt('&& 4', DartAssistKind.SPLIT_AND_CONDITION);
-  }
-
-  void test_splitVariableDeclaration_OK_onName() {
+  test_splitVariableDeclaration_OK_onName() async {
     resolveTestUnit('''
 main() {
   var v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'v =',
         DartAssistKind.SPLIT_VARIABLE_DECLARATION,
         '''
@@ -3428,13 +3686,13 @@
 ''');
   }
 
-  void test_splitVariableDeclaration_OK_onType() {
+  test_splitVariableDeclaration_OK_onType() async {
     resolveTestUnit('''
 main() {
   int v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'int ',
         DartAssistKind.SPLIT_VARIABLE_DECLARATION,
         '''
@@ -3445,13 +3703,13 @@
 ''');
   }
 
-  void test_splitVariableDeclaration_OK_onVar() {
+  test_splitVariableDeclaration_OK_onVar() async {
     resolveTestUnit('''
 main() {
   var v = 1;
 }
 ''');
-    assertHasAssistAt(
+    await assertHasAssistAt(
         'var ',
         DartAssistKind.SPLIT_VARIABLE_DECLARATION,
         '''
@@ -3462,16 +3720,7 @@
 ''');
   }
 
-  void test_splitVariableDeclaration_wrong_notOneVariable() {
-    resolveTestUnit('''
-main() {
-  var v = 1, v2;
-}
-''');
-    assertNoAssistAt('v = 1', DartAssistKind.SPLIT_VARIABLE_DECLARATION);
-  }
-
-  void test_surroundWith_block() {
+  test_surroundWith_block() async {
     resolveTestUnit('''
 main() {
 // start
@@ -3481,7 +3730,7 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(
+    await assertHasAssist(
         DartAssistKind.SURROUND_WITH_BLOCK,
         '''
 main() {
@@ -3495,7 +3744,7 @@
 ''');
   }
 
-  void test_surroundWith_doWhile() {
+  test_surroundWith_doWhile() async {
     resolveTestUnit('''
 main() {
 // start
@@ -3505,7 +3754,7 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(
+    await assertHasAssist(
         DartAssistKind.SURROUND_WITH_DO_WHILE,
         '''
 main() {
@@ -3519,7 +3768,7 @@
 ''');
   }
 
-  void test_surroundWith_for() {
+  test_surroundWith_for() async {
     resolveTestUnit('''
 main() {
 // start
@@ -3529,7 +3778,7 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(
+    await assertHasAssist(
         DartAssistKind.SURROUND_WITH_FOR,
         '''
 main() {
@@ -3543,7 +3792,7 @@
 ''');
   }
 
-  void test_surroundWith_forIn() {
+  test_surroundWith_forIn() async {
     resolveTestUnit('''
 main() {
 // start
@@ -3553,7 +3802,7 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(
+    await assertHasAssist(
         DartAssistKind.SURROUND_WITH_FOR_IN,
         '''
 main() {
@@ -3567,7 +3816,7 @@
 ''');
   }
 
-  void test_surroundWith_if() {
+  test_surroundWith_if() async {
     resolveTestUnit('''
 main() {
 // start
@@ -3577,7 +3826,7 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(
+    await assertHasAssist(
         DartAssistKind.SURROUND_WITH_IF,
         '''
 main() {
@@ -3591,7 +3840,7 @@
 ''');
   }
 
-  void test_surroundWith_tryCatch() {
+  test_surroundWith_tryCatch() async {
     resolveTestUnit('''
 main() {
 // start
@@ -3601,7 +3850,7 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(
+    await assertHasAssist(
         DartAssistKind.SURROUND_WITH_TRY_CATCH,
         '''
 main() {
@@ -3617,7 +3866,7 @@
 ''');
   }
 
-  void test_surroundWith_tryFinally() {
+  test_surroundWith_tryFinally() async {
     resolveTestUnit('''
 main() {
 // start
@@ -3627,7 +3876,7 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(
+    await assertHasAssist(
         DartAssistKind.SURROUND_WITH_TRY_FINALLY,
         '''
 main() {
@@ -3643,7 +3892,7 @@
 ''');
   }
 
-  void test_surroundWith_while() {
+  test_surroundWith_while() async {
     resolveTestUnit('''
 main() {
 // start
@@ -3653,7 +3902,7 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(
+    await assertHasAssist(
         DartAssistKind.SURROUND_WITH_WHILE,
         '''
 main() {
@@ -3670,8 +3919,8 @@
   /**
    * Computes assists and verifies that there is an assist of the given kind.
    */
-  Assist _assertHasAssist(AssistKind kind) {
-    List<Assist> assists = computeAssists(
+  Future<Assist> _assertHasAssist(AssistKind kind) async {
+    List<Assist> assists = await computeAssists(
         plugin, context, testUnit.element.source, offset, length);
     for (Assist assist in assists) {
       if (assist.kind == kind) {
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 14f2fc8..7ce9b90 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -4,7 +4,10 @@
 
 library test.services.correction.fix;
 
+import 'dart:async';
+
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart'
     hide AnalysisError;
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -42,14 +45,14 @@
   SourceChange change;
   String resultCode;
 
-  void assert_undefinedFunction_create_returnType_bool(String lineWithTest) {
+  assert_undefinedFunction_create_returnType_bool(String lineWithTest) async {
     resolveTestUnit('''
 main() {
   bool b = true;
   $lineWithTest
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -62,9 +65,9 @@
 ''');
   }
 
-  void assertHasFix(FixKind kind, String expected) {
+  assertHasFix(FixKind kind, String expected) async {
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(kind, error);
+    fix = await _assertHasFix(kind, error);
     change = fix.change;
     // apply to "file"
     List<SourceFileEdit> fileEdits = change.edits;
@@ -74,9 +77,9 @@
     expect(resultCode, expected);
   }
 
-  void assertNoFix(FixKind kind) {
+  assertNoFix(FixKind kind) async {
     AnalysisError error = _findErrorToFix();
-    List<Fix> fixes = _computeFixes(error);
+    List<Fix> fixes = await _computeFixes(error);
     for (Fix fix in fixes) {
       if (fix.kind == kind) {
         throw fail('Unexpected fix $kind in\n${fixes.join('\n')}');
@@ -109,7 +112,7 @@
     verifyNoTestUnitErrors = false;
   }
 
-  void test_addFieldFormalParameters_hasRequiredParameter() {
+  test_addFieldFormalParameters_hasRequiredParameter() async {
     resolveTestUnit('''
 class Test {
   final int a;
@@ -118,7 +121,7 @@
   Test(this.a);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_FIELD_FORMAL_PARAMETERS,
         '''
 class Test {
@@ -130,7 +133,7 @@
 ''');
   }
 
-  void test_addFieldFormalParameters_noParameters() {
+  test_addFieldFormalParameters_noParameters() async {
     resolveTestUnit('''
 class Test {
   final int a;
@@ -139,7 +142,7 @@
   Test();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_FIELD_FORMAL_PARAMETERS,
         '''
 class Test {
@@ -151,7 +154,7 @@
 ''');
   }
 
-  void test_addFieldFormalParameters_noRequiredParameter() {
+  test_addFieldFormalParameters_noRequiredParameter() async {
     resolveTestUnit('''
 class Test {
   final int a;
@@ -160,7 +163,7 @@
   Test([this.c]);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_FIELD_FORMAL_PARAMETERS,
         '''
 class Test {
@@ -172,14 +175,24 @@
 ''');
   }
 
-  void test_addMissingParameter_function_positional_hasZero() {
+  test_addMissingParameter_function_positional_hasNamed() async {
+    resolveTestUnit('''
+test({int a}) {}
+main() {
+  test(1);
+}
+''');
+    await assertNoFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL);
+  }
+
+  test_addMissingParameter_function_positional_hasZero() async {
     resolveTestUnit('''
 test() {}
 main() {
   test(1);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL,
         '''
 test([int i]) {}
@@ -189,14 +202,31 @@
 ''');
   }
 
-  void test_addMissingParameter_function_required_hasOne() {
+  test_addMissingParameter_function_required_hasNamed() async {
+    resolveTestUnit('''
+test({int a}) {}
+main() {
+  test(1);
+}
+''');
+    await assertHasFix(
+        DartFixKind.ADD_MISSING_PARAMETER_REQUIRED,
+        '''
+test(int i, {int a}) {}
+main() {
+  test(1);
+}
+''');
+  }
+
+  test_addMissingParameter_function_required_hasOne() async {
     resolveTestUnit('''
 test(int a) {}
 main() {
   test(1, 2.0);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_MISSING_PARAMETER_REQUIRED,
         '''
 test(int a, double d) {}
@@ -206,14 +236,14 @@
 ''');
   }
 
-  void test_addMissingParameter_function_required_hasZero() {
+  test_addMissingParameter_function_required_hasZero() async {
     resolveTestUnit('''
 test() {}
 main() {
   test(1);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_MISSING_PARAMETER_REQUIRED,
         '''
 test(int i) {}
@@ -223,7 +253,7 @@
 ''');
   }
 
-  void test_addMissingParameter_method_positional_hasOne() {
+  test_addMissingParameter_method_positional_hasOne() async {
     resolveTestUnit('''
 class A {
   test(int a) {}
@@ -232,7 +262,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL,
         '''
 class A {
@@ -244,7 +274,7 @@
 ''');
   }
 
-  void test_addMissingParameter_method_required_hasOne() {
+  test_addMissingParameter_method_required_hasOne() async {
     resolveTestUnit('''
 class A {
   test(int a) {}
@@ -253,7 +283,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_MISSING_PARAMETER_REQUIRED,
         '''
 class A {
@@ -265,7 +295,7 @@
 ''');
   }
 
-  void test_addMissingParameter_method_required_hasZero() {
+  test_addMissingParameter_method_required_hasZero() async {
     resolveTestUnit('''
 class A {
   test() {}
@@ -274,7 +304,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_MISSING_PARAMETER_REQUIRED,
         '''
 class A {
@@ -286,7 +316,7 @@
 ''');
   }
 
-  void test_addPartOfDirective() {
+  test_addPartOfDirective() async {
     String partCode = r'''
 // Comment first.
 // Comment second.
@@ -300,7 +330,7 @@
 ''');
     _performAnalysis();
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(DartFixKind.ADD_PART_OF, error);
+    fix = await _assertHasFix(DartFixKind.ADD_PART_OF, error);
     change = fix.change;
     // apply to "file"
     List<SourceFileEdit> fileEdits = change.edits;
@@ -319,14 +349,14 @@
 ''');
   }
 
-  void test_addSync_BAD_nullFunctionBody() {
+  test_addSync_BAD_nullFunctionBody() async {
     resolveTestUnit('''
 var F = await;
 ''');
-    assertNoFix(DartFixKind.ADD_ASYNC);
+    await assertNoFix(DartFixKind.ADD_ASYNC);
   }
 
-  void test_addSync_blockFunctionBody() {
+  test_addSync_blockFunctionBody() async {
     resolveTestUnit('''
 foo() {}
 main() {
@@ -335,39 +365,38 @@
 ''');
     List<AnalysisError> errors = context.computeErrors(testSource);
     expect(errors, hasLength(2));
-    // ParserError: Expected to find ';'
-    {
-      AnalysisError error = errors[0];
-      expect(error.message, "Expected to find ';'");
-      List<Fix> fixes = _computeFixes(error);
-      expect(fixes, isEmpty);
-    }
-    // Undefined name 'await'
-    {
-      AnalysisError error = errors[1];
-      expect(error.message, "Undefined name 'await'");
-      List<Fix> fixes = _computeFixes(error);
-      // has exactly one fix
-      expect(fixes, hasLength(1));
-      Fix fix = fixes[0];
-      expect(fix.kind, DartFixKind.ADD_ASYNC);
-      // apply to "file"
-      List<SourceFileEdit> fileEdits = fix.change.edits;
-      expect(fileEdits, hasLength(1));
-      resultCode = SourceEdit.applySequence(testCode, fileEdits[0].edits);
-      // verify
-      expect(
-          resultCode,
-          '''
+    String message1 = "Expected to find ';'";
+    String message2 = "Undefined name 'await'";
+    expect(errors.map((e) => e.message), unorderedEquals([message1, message2]));
+    for (AnalysisError error in errors) {
+      if (error.message == message1) {
+        List<Fix> fixes = await _computeFixes(error);
+        expect(fixes, isEmpty);
+      }
+      if (error.message == message2) {
+        List<Fix> fixes = await _computeFixes(error);
+        // has exactly one fix
+        expect(fixes, hasLength(1));
+        Fix fix = fixes[0];
+        expect(fix.kind, DartFixKind.ADD_ASYNC);
+        // apply to "file"
+        List<SourceFileEdit> fileEdits = fix.change.edits;
+        expect(fileEdits, hasLength(1));
+        resultCode = SourceEdit.applySequence(testCode, fileEdits[0].edits);
+        // verify
+        expect(
+            resultCode,
+            '''
 foo() {}
 main() async {
   await foo();
 }
 ''');
+      }
     }
   }
 
-  void test_addSync_expressionFunctionBody() {
+  test_addSync_expressionFunctionBody() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
     };
@@ -375,7 +404,7 @@
 foo() {}
 main() => await foo();
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_ASYNC,
         '''
 foo() {}
@@ -383,13 +412,13 @@
 ''');
   }
 
-  void test_boolean() {
+  test_boolean() async {
     resolveTestUnit('''
 main() {
   boolean v;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REPLACE_BOOLEAN_WITH_BOOL,
         '''
 main() {
@@ -398,7 +427,52 @@
 ''');
   }
 
-  void test_changeToStaticAccess_method() {
+  test_canBeNullAfterNullAware_chain() async {
+    resolveTestUnit('''
+main(x) {
+  x?.a.b.c;
+}
+''');
+    await assertHasFix(
+        DartFixKind.REPLACE_WITH_NULL_AWARE,
+        '''
+main(x) {
+  x?.a?.b?.c;
+}
+''');
+  }
+
+  test_canBeNullAfterNullAware_methodInvocation() async {
+    resolveTestUnit('''
+main(x) {
+  x?.a.b();
+}
+''');
+    await assertHasFix(
+        DartFixKind.REPLACE_WITH_NULL_AWARE,
+        '''
+main(x) {
+  x?.a?.b();
+}
+''');
+  }
+
+  test_canBeNullAfterNullAware_propertyAccess() async {
+    resolveTestUnit('''
+main(x) {
+  x?.a().b;
+}
+''');
+    await assertHasFix(
+        DartFixKind.REPLACE_WITH_NULL_AWARE,
+        '''
+main(x) {
+  x?.a()?.b;
+}
+''');
+  }
+
+  test_changeToStaticAccess_method() async {
     resolveTestUnit('''
 class A {
   static foo() {}
@@ -407,7 +481,7 @@
   a.foo();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO_STATIC_ACCESS,
         '''
 class A {
@@ -419,7 +493,7 @@
 ''');
   }
 
-  void test_changeToStaticAccess_method_importType() {
+  test_changeToStaticAccess_method_importType() async {
     addSource(
         '/libA.dart',
         r'''
@@ -441,7 +515,7 @@
   b.foo();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO_STATIC_ACCESS,
         '''
 import 'libB.dart';
@@ -452,14 +526,14 @@
 ''');
   }
 
-  void test_changeToStaticAccess_method_prefixLibrary() {
+  test_changeToStaticAccess_method_prefixLibrary() async {
     resolveTestUnit('''
 import 'dart:async' as pref;
 main(pref.Future f) {
   f.wait([]);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO_STATIC_ACCESS,
         '''
 import 'dart:async' as pref;
@@ -469,7 +543,7 @@
 ''');
   }
 
-  void test_changeToStaticAccess_property() {
+  test_changeToStaticAccess_property() async {
     resolveTestUnit('''
 class A {
   static get foo => 42;
@@ -478,7 +552,7 @@
   a.foo;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO_STATIC_ACCESS,
         '''
 class A {
@@ -490,7 +564,7 @@
 ''');
   }
 
-  void test_changeToStaticAccess_property_importType() {
+  test_changeToStaticAccess_property_importType() async {
     addSource(
         '/libA.dart',
         r'''
@@ -512,7 +586,7 @@
   b.foo;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO_STATIC_ACCESS,
         '''
 import 'libB.dart';
@@ -523,13 +597,62 @@
 ''');
   }
 
-  void test_createClass() {
+  test_changeTypeAnnotation_BAD_multipleVariables() async {
+    resolveTestUnit('''
+main() {
+  String a, b = 42;
+}
+''');
+    await assertNoFix(DartFixKind.CHANGE_TYPE_ANNOTATION);
+  }
+
+  test_changeTypeAnnotation_BAD_notVariableDeclaration() async {
+    resolveTestUnit('''
+main() {
+  String v;
+  v = 42;
+}
+''');
+    await assertNoFix(DartFixKind.CHANGE_TYPE_ANNOTATION);
+  }
+
+  test_changeTypeAnnotation_OK_generic() async {
+    resolveTestUnit('''
+main() {
+  String v = <int>[];
+}
+''');
+    await assertHasFix(
+        DartFixKind.CHANGE_TYPE_ANNOTATION,
+        '''
+main() {
+  List<int> v = <int>[];
+}
+''');
+  }
+
+  test_changeTypeAnnotation_OK_simple() async {
+    resolveTestUnit('''
+main() {
+  String v = 'abc'.length;
+}
+''');
+    await assertHasFix(
+        DartFixKind.CHANGE_TYPE_ANNOTATION,
+        '''
+main() {
+  int v = 'abc'.length;
+}
+''');
+  }
+
+  test_createClass() async {
     resolveTestUnit('''
 main() {
   Test v = null;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CLASS,
         '''
 main() {
@@ -542,16 +665,16 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
   }
 
-  void test_createClass_BAD_hasUnresolvedPrefix() {
+  test_createClass_BAD_hasUnresolvedPrefix() async {
     resolveTestUnit('''
 main() {
   prefix.Test v = null;
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_CLASS);
+    await assertNoFix(DartFixKind.CREATE_CLASS);
   }
 
-  void test_createClass_inLibraryOfPrefix() {
+  test_createClass_inLibraryOfPrefix() async {
     String libCode = r'''
 library my.lib;
 
@@ -567,7 +690,7 @@
 }
 ''');
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(DartFixKind.CREATE_CLASS, error);
+    fix = await _assertHasFix(DartFixKind.CREATE_CLASS, error);
     change = fix.change;
     // apply to "lib.dart"
     List<SourceFileEdit> fileEdits = change.edits;
@@ -587,7 +710,7 @@
     expect(change.linkedEditGroups, isEmpty);
   }
 
-  void test_createClass_innerLocalFunction() {
+  test_createClass_innerLocalFunction() async {
     resolveTestUnit('''
 f() {
   g() {
@@ -595,7 +718,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CLASS,
         '''
 f() {
@@ -610,13 +733,13 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
   }
 
-  void test_createClass_itemOfList() {
+  test_createClass_itemOfList() async {
     resolveTestUnit('''
 main() {
   var a = [Test];
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CLASS,
         '''
 main() {
@@ -629,7 +752,7 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['Test];', 'Test {']);
   }
 
-  void test_createClass_itemOfList_inAnnotation() {
+  test_createClass_itemOfList_inAnnotation() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
     };
@@ -640,7 +763,7 @@
 @MyAnnotation(int, const [Test])
 main() {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CLASS,
         '''
 class MyAnnotation {
@@ -655,7 +778,7 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['Test])', 'Test {']);
   }
 
-  void test_createConstructor_forFinalFields() {
+  test_createConstructor_forFinalFields() async {
     errorFilter = (AnalysisError error) {
       return error.message.contains("'a'");
     };
@@ -666,7 +789,7 @@
   final int c;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS,
         '''
 class Test {
@@ -679,7 +802,7 @@
 ''');
   }
 
-  void test_createConstructor_insteadOfSyntheticDefault() {
+  test_createConstructor_insteadOfSyntheticDefault() async {
     resolveTestUnit('''
 class A {
   int field;
@@ -690,7 +813,7 @@
   new A(1, 2.0);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CONSTRUCTOR,
         '''
 class A {
@@ -707,7 +830,7 @@
 ''');
   }
 
-  void test_createConstructor_named() {
+  test_createConstructor_named() async {
     resolveTestUnit('''
 class A {
   method() {}
@@ -716,7 +839,7 @@
   new A.named(1, 2.0);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CONSTRUCTOR,
         '''
 class A {
@@ -732,23 +855,23 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
   }
 
-  void test_createConstructorForFinalFields_inTopLevelMethod() {
+  test_createConstructorForFinalFields_inTopLevelMethod() async {
     resolveTestUnit('''
 main() {
   final int v;
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS);
+    await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS);
   }
 
-  void test_createConstructorForFinalFields_topLevelField() {
+  test_createConstructorForFinalFields_topLevelField() async {
     resolveTestUnit('''
 final int v;
 ''');
-    assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS);
+    await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS);
   }
 
-  void test_createConstructorSuperExplicit() {
+  test_createConstructorSuperExplicit() async {
     resolveTestUnit('''
 class A {
   A(bool p1, int p2, double p3, String p4, {p5});
@@ -757,7 +880,7 @@
   B() {}
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION,
         '''
 class A {
@@ -769,7 +892,7 @@
 ''');
   }
 
-  void test_createConstructorSuperExplicit_hasInitializers() {
+  test_createConstructorSuperExplicit_hasInitializers() async {
     resolveTestUnit('''
 class A {
   A(int p);
@@ -779,7 +902,7 @@
   B() : field = 42 {}
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION,
         '''
 class A {
@@ -792,7 +915,7 @@
 ''');
   }
 
-  void test_createConstructorSuperExplicit_named() {
+  test_createConstructorSuperExplicit_named() async {
     resolveTestUnit('''
 class A {
   A.named(int p);
@@ -801,7 +924,7 @@
   B() {}
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION,
         '''
 class A {
@@ -813,7 +936,7 @@
 ''');
   }
 
-  void test_createConstructorSuperExplicit_named_private() {
+  test_createConstructorSuperExplicit_named_private() async {
     resolveTestUnit('''
 class A {
   A._named(int p);
@@ -822,10 +945,10 @@
   B() {}
 }
 ''');
-    assertNoFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION);
+    await assertNoFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION);
   }
 
-  void test_createConstructorSuperExplicit_typeArgument() {
+  test_createConstructorSuperExplicit_typeArgument() async {
     resolveTestUnit('''
 class A<T> {
   A(T p);
@@ -834,7 +957,7 @@
   B();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION,
         '''
 class A<T> {
@@ -846,7 +969,7 @@
 ''');
   }
 
-  void test_createConstructorSuperImplicit() {
+  test_createConstructorSuperImplicit() async {
     resolveTestUnit('''
 class A {
   A(p1, int p2, List<String> p3, [int p4]);
@@ -857,7 +980,7 @@
   void existingMethod() {}
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CONSTRUCTOR_SUPER,
         '''
 class A {
@@ -873,7 +996,7 @@
 ''');
   }
 
-  void test_createConstructorSuperImplicit_fieldInitializer() {
+  test_createConstructorSuperImplicit_fieldInitializer() async {
     resolveTestUnit('''
 class A {
   int _field;
@@ -885,7 +1008,7 @@
   void existingMethod() {}
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CONSTRUCTOR_SUPER,
         '''
 class A {
@@ -902,7 +1025,7 @@
 ''');
   }
 
-  void test_createConstructorSuperImplicit_importType() {
+  test_createConstructorSuperImplicit_importType() async {
     addSource(
         '/libA.dart',
         r'''
@@ -923,7 +1046,7 @@
 class C extends B {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CONSTRUCTOR_SUPER,
         '''
 import 'libB.dart';
@@ -934,7 +1057,7 @@
 ''');
   }
 
-  void test_createConstructorSuperImplicit_named() {
+  test_createConstructorSuperImplicit_named() async {
     resolveTestUnit('''
 class A {
   A.named(p1, int p2);
@@ -945,7 +1068,7 @@
   void existingMethod() {}
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CONSTRUCTOR_SUPER,
         '''
 class A {
@@ -961,7 +1084,7 @@
 ''');
   }
 
-  void test_createConstructorSuperImplicit_private() {
+  test_createConstructorSuperImplicit_private() async {
     resolveTestUnit('''
 class A {
   A._named(p);
@@ -969,10 +1092,10 @@
 class B extends A {
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER);
+    await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER);
   }
 
-  void test_createConstructorSuperImplicit_typeArgument() {
+  test_createConstructorSuperImplicit_typeArgument() async {
     resolveTestUnit('''
 class C<T> {
   final T x;
@@ -980,7 +1103,7 @@
 }
 class D extends C<int> {
 }''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_CONSTRUCTOR_SUPER,
         '''
 class C<T> {
@@ -992,7 +1115,7 @@
 }''');
   }
 
-  void test_createField_BAD_inEnum() {
+  test_createField_BAD_inEnum() async {
     resolveTestUnit('''
 enum MyEnum {
   AAA, BBB
@@ -1001,19 +1124,19 @@
   MyEnum.foo;
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_FIELD);
+    await assertNoFix(DartFixKind.CREATE_FIELD);
   }
 
-  void test_createField_BAD_inSDK() {
+  test_createField_BAD_inSDK() async {
     resolveTestUnit('''
 main(List p) {
   p.foo = 1;
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_FIELD);
+    await assertNoFix(DartFixKind.CREATE_FIELD);
   }
 
-  void test_createField_getter_multiLevel() {
+  test_createField_getter_multiLevel() async {
     resolveTestUnit('''
 class A {
 }
@@ -1027,7 +1150,7 @@
   int v = c.b.a.test;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1045,7 +1168,7 @@
 ''');
   }
 
-  void test_createField_getter_qualified_instance() {
+  test_createField_getter_qualified_instance() async {
     resolveTestUnit('''
 class A {
 }
@@ -1053,7 +1176,7 @@
   int v = a.test;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1065,7 +1188,7 @@
 ''');
   }
 
-  void test_createField_getter_qualified_instance_dynamicType() {
+  test_createField_getter_qualified_instance_dynamicType() async {
     resolveTestUnit('''
 class A {
   B b;
@@ -1076,7 +1199,7 @@
 class B {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1091,7 +1214,7 @@
 ''');
   }
 
-  void test_createField_getter_unqualified_instance_asInvocationArgument() {
+  test_createField_getter_unqualified_instance_asInvocationArgument() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -1100,7 +1223,7 @@
 }
 f(String s) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1114,7 +1237,7 @@
 ''');
   }
 
-  void test_createField_getter_unqualified_instance_assignmentRhs() {
+  test_createField_getter_unqualified_instance_assignmentRhs() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -1122,7 +1245,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1135,7 +1258,7 @@
 ''');
   }
 
-  void test_createField_getter_unqualified_instance_asStatement() {
+  test_createField_getter_unqualified_instance_asStatement() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -1143,7 +1266,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1156,7 +1279,7 @@
 ''');
   }
 
-  void test_createField_hint() {
+  test_createField_hint() async {
     resolveTestUnit('''
 class A {
 }
@@ -1165,7 +1288,7 @@
   int v = x.test;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1178,7 +1301,7 @@
 ''');
   }
 
-  void test_createField_hint_setter() {
+  test_createField_hint_setter() async {
     resolveTestUnit('''
 class A {
 }
@@ -1187,7 +1310,7 @@
   x.test = 0;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1200,7 +1323,7 @@
 ''');
   }
 
-  void test_createField_importType() {
+  test_createField_importType() async {
     addSource(
         '/libA.dart',
         r'''
@@ -1222,7 +1345,7 @@
   c.test = getA();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 import 'libB.dart';
@@ -1236,7 +1359,7 @@
 ''');
   }
 
-  void test_createField_setter_generic_BAD() {
+  test_createField_setter_generic_BAD() async {
     resolveTestUnit('''
 class A {
 }
@@ -1247,7 +1370,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1262,7 +1385,7 @@
 ''');
   }
 
-  void test_createField_setter_generic_OK_local() {
+  test_createField_setter_generic_OK_local() async {
     resolveTestUnit('''
 class A<T> {
   List<T> items;
@@ -1272,7 +1395,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A<T> {
@@ -1287,7 +1410,7 @@
 ''');
   }
 
-  void test_createField_setter_qualified_instance_hasField() {
+  test_createField_setter_qualified_instance_hasField() async {
     resolveTestUnit('''
 class A {
   int aaa;
@@ -1299,7 +1422,7 @@
   a.test = 5;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1316,7 +1439,7 @@
 ''');
   }
 
-  void test_createField_setter_qualified_instance_hasMethod() {
+  test_createField_setter_qualified_instance_hasMethod() async {
     resolveTestUnit('''
 class A {
   existingMethod() {}
@@ -1325,7 +1448,7 @@
   a.test = 5;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1339,7 +1462,7 @@
 ''');
   }
 
-  void test_createField_setter_qualified_static() {
+  test_createField_setter_qualified_static() async {
     resolveTestUnit('''
 class A {
 }
@@ -1347,7 +1470,7 @@
   A.test = 5;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1359,7 +1482,7 @@
 ''');
   }
 
-  void test_createField_setter_unqualified_instance() {
+  test_createField_setter_unqualified_instance() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -1367,7 +1490,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1380,7 +1503,7 @@
 ''');
   }
 
-  void test_createField_setter_unqualified_static() {
+  test_createField_setter_unqualified_static() async {
     resolveTestUnit('''
 class A {
   static main() {
@@ -1388,7 +1511,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
 class A {
@@ -1401,13 +1524,13 @@
 ''');
   }
 
-  void test_createFile_forImport() {
+  test_createFile_forImport() async {
     testFile = '/my/project/bin/test.dart';
     resolveTestUnit('''
 import 'my_file.dart';
 ''');
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(DartFixKind.CREATE_FILE, error);
+    fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
     List<SourceFileEdit> fileEdits = change.edits;
@@ -1419,7 +1542,24 @@
     expect(fileEdit.edits[0].replacement, contains('library my_file;'));
   }
 
-  void test_createFile_forImport_inPackage_lib() {
+  test_createFile_forImport_BAD_inPackage_lib_justLib() async {
+    provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package');
+    testFile = '/projects/my_package/test.dart';
+    resolveTestUnit('''
+import 'lib';
+''');
+    await assertNoFix(DartFixKind.CREATE_FILE);
+  }
+
+  test_createFile_forImport_BAD_notDart() async {
+    testFile = '/my/project/bin/test.dart';
+    resolveTestUnit('''
+import 'my_file.txt';
+''');
+    await assertNoFix(DartFixKind.CREATE_FILE);
+  }
+
+  test_createFile_forImport_inPackage_lib() async {
     provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package');
     testFile = '/projects/my_package/lib/test.dart';
     provider.newFolder('/projects/my_package/lib');
@@ -1427,7 +1567,7 @@
 import 'a/bb/c_cc/my_lib.dart';
 ''');
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(DartFixKind.CREATE_FILE, error);
+    fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
     List<SourceFileEdit> fileEdits = change.edits;
@@ -1440,14 +1580,14 @@
         contains('library my_package.a.bb.c_cc.my_lib;'));
   }
 
-  void test_createFile_forImport_inPackage_test() {
+  test_createFile_forImport_inPackage_test() async {
     provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package');
     testFile = '/projects/my_package/test/misc/test_all.dart';
     resolveTestUnit('''
 import 'a/bb/my_lib.dart';
 ''');
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(DartFixKind.CREATE_FILE, error);
+    fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
     List<SourceFileEdit> fileEdits = change.edits;
@@ -1460,14 +1600,14 @@
         contains('library my_package.test.misc.a.bb.my_lib;'));
   }
 
-  void test_createFile_forPart() {
+  test_createFile_forPart() async {
     testFile = '/my/project/bin/test.dart';
     resolveTestUnit('''
 library my.lib;
 part 'my_part.dart';
 ''');
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(DartFixKind.CREATE_FILE, error);
+    fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
     List<SourceFileEdit> fileEdits = change.edits;
@@ -1479,7 +1619,7 @@
     expect(fileEdit.edits[0].replacement, contains('part of my.lib;'));
   }
 
-  void test_createFile_forPart_inPackageLib() {
+  test_createFile_forPart_inPackageLib() async {
     provider.newFile(
         '/my/pubspec.yaml',
         r'''
@@ -1501,7 +1641,7 @@
     // prepare fix
     testUnit = resolveLibraryUnit(testSource);
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(DartFixKind.CREATE_FILE, error);
+    fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
     List<SourceFileEdit> fileEdits = change.edits;
@@ -1513,16 +1653,16 @@
     expect(fileEdit.edits[0].replacement, contains('part of my.lib;'));
   }
 
-  void test_createGetter_BAD_inSDK() {
+  test_createGetter_BAD_inSDK() async {
     resolveTestUnit('''
 main(List p) {
   int v = p.foo;
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_GETTER);
+    await assertNoFix(DartFixKind.CREATE_GETTER);
   }
 
-  void test_createGetter_hint_getter() {
+  test_createGetter_hint_getter() async {
     resolveTestUnit('''
 class A {
 }
@@ -1531,7 +1671,7 @@
   int v = x.test;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_GETTER,
         '''
 class A {
@@ -1544,7 +1684,7 @@
 ''');
   }
 
-  void test_createGetter_location_afterLastGetter() {
+  test_createGetter_location_afterLastGetter() async {
     resolveTestUnit('''
 class A {
   int existingField;
@@ -1557,7 +1697,7 @@
   int v = a.test;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_GETTER,
         '''
 class A {
@@ -1575,7 +1715,7 @@
 ''');
   }
 
-  void test_createGetter_multiLevel() {
+  test_createGetter_multiLevel() async {
     resolveTestUnit('''
 class A {
 }
@@ -1589,7 +1729,7 @@
   int v = c.b.a.test;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_GETTER,
         '''
 class A {
@@ -1607,7 +1747,7 @@
 ''');
   }
 
-  void test_createGetter_qualified_instance() {
+  test_createGetter_qualified_instance() async {
     resolveTestUnit('''
 class A {
 }
@@ -1615,7 +1755,7 @@
   int v = a.test;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_GETTER,
         '''
 class A {
@@ -1627,7 +1767,7 @@
 ''');
   }
 
-  void test_createGetter_qualified_instance_dynamicType() {
+  test_createGetter_qualified_instance_dynamicType() async {
     resolveTestUnit('''
 class A {
   B b;
@@ -1638,7 +1778,7 @@
 class B {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_GETTER,
         '''
 class A {
@@ -1653,7 +1793,7 @@
 ''');
   }
 
-  void test_createGetter_setterContext() {
+  test_createGetter_setterContext() async {
     resolveTestUnit('''
 class A {
 }
@@ -1661,10 +1801,10 @@
   a.test = 42;
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_GETTER);
+    await assertNoFix(DartFixKind.CREATE_GETTER);
   }
 
-  void test_createGetter_unqualified_instance_asInvocationArgument() {
+  test_createGetter_unqualified_instance_asInvocationArgument() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -1673,7 +1813,7 @@
 }
 f(String s) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_GETTER,
         '''
 class A {
@@ -1687,7 +1827,7 @@
 ''');
   }
 
-  void test_createGetter_unqualified_instance_assignmentLhs() {
+  test_createGetter_unqualified_instance_assignmentLhs() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -1695,10 +1835,10 @@
   }
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_GETTER);
+    await assertNoFix(DartFixKind.CREATE_GETTER);
   }
 
-  void test_createGetter_unqualified_instance_assignmentRhs() {
+  test_createGetter_unqualified_instance_assignmentRhs() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -1706,7 +1846,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_GETTER,
         '''
 class A {
@@ -1719,7 +1859,7 @@
 ''');
   }
 
-  void test_createGetter_unqualified_instance_asStatement() {
+  test_createGetter_unqualified_instance_asStatement() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -1727,7 +1867,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_GETTER,
         '''
 class A {
@@ -1740,7 +1880,7 @@
 ''');
   }
 
-  void test_createLocalVariable_functionType_named() {
+  test_createLocalVariable_functionType_named() async {
     resolveTestUnit('''
 typedef MY_FUNCTION(int p);
 foo(MY_FUNCTION f) {}
@@ -1748,7 +1888,7 @@
   foo(bar);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_LOCAL_VARIABLE,
         '''
 typedef MY_FUNCTION(int p);
@@ -1760,23 +1900,23 @@
 ''');
   }
 
-  void test_createLocalVariable_functionType_synthetic() {
+  test_createLocalVariable_functionType_synthetic() async {
     resolveTestUnit('''
 foo(f(int p)) {}
 main() {
   foo(bar);
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_LOCAL_VARIABLE);
+    await assertNoFix(DartFixKind.CREATE_LOCAL_VARIABLE);
   }
 
-  void test_createLocalVariable_read_typeAssignment() {
+  test_createLocalVariable_read_typeAssignment() async {
     resolveTestUnit('''
 main() {
   int a = test;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_LOCAL_VARIABLE,
         '''
 main() {
@@ -1786,7 +1926,7 @@
 ''');
   }
 
-  void test_createLocalVariable_read_typeCondition() {
+  test_createLocalVariable_read_typeCondition() async {
     resolveTestUnit('''
 main() {
   if (!test) {
@@ -1794,7 +1934,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_LOCAL_VARIABLE,
         '''
 main() {
@@ -1806,14 +1946,14 @@
 ''');
   }
 
-  void test_createLocalVariable_read_typeInvocationArgument() {
+  test_createLocalVariable_read_typeInvocationArgument() async {
     resolveTestUnit('''
 main() {
   f(test);
 }
 f(String p) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_LOCAL_VARIABLE,
         '''
 main() {
@@ -1826,13 +1966,13 @@
     _assertLinkedGroup(change.linkedEditGroups[1], ['test;', 'test);']);
   }
 
-  void test_createLocalVariable_read_typeInvocationTarget() {
+  test_createLocalVariable_read_typeInvocationTarget() async {
     resolveTestUnit('''
 main() {
   test.add('hello');
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_LOCAL_VARIABLE,
         '''
 main() {
@@ -1843,13 +1983,13 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['test;', 'test.add(']);
   }
 
-  void test_createLocalVariable_write_assignment() {
+  test_createLocalVariable_write_assignment() async {
     resolveTestUnit('''
 main() {
   test = 42;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_LOCAL_VARIABLE,
         '''
 main() {
@@ -1858,13 +1998,13 @@
 ''');
   }
 
-  void test_createLocalVariable_write_assignment_compound() {
+  test_createLocalVariable_write_assignment_compound() async {
     resolveTestUnit('''
 main() {
   test += 42;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_LOCAL_VARIABLE,
         '''
 main() {
@@ -1874,7 +2014,7 @@
 ''');
   }
 
-  void test_createMissingOverrides_functionTypeAlias() {
+  test_createMissingOverrides_functionTypeAlias() async {
     resolveTestUnit('''
 typedef int Binary(int left, int right);
 
@@ -1885,7 +2025,7 @@
 class MyEmulator extends Emulator {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_MISSING_OVERRIDES,
         '''
 typedef int Binary(int left, int right);
@@ -1903,7 +2043,7 @@
 ''');
   }
 
-  void test_createMissingOverrides_functionTypedParameter() {
+  test_createMissingOverrides_functionTypedParameter() async {
     resolveTestUnit('''
 abstract class A {
   forEach(int f(double p1, String p2));
@@ -1912,7 +2052,7 @@
 class B extends A {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_MISSING_OVERRIDES,
         '''
 abstract class A {
@@ -1928,7 +2068,7 @@
 ''');
   }
 
-  void test_createMissingOverrides_generics_typeArguments() {
+  test_createMissingOverrides_generics_typeArguments() async {
     resolveTestUnit('''
 class Iterator<T> {
 }
@@ -1940,7 +2080,7 @@
 class Test extends IterableMixin<int> {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_MISSING_OVERRIDES,
         '''
 class Iterator<T> {
@@ -1958,7 +2098,7 @@
 ''');
   }
 
-  void test_createMissingOverrides_generics_typeParameters() {
+  test_createMissingOverrides_generics_typeParameters() async {
     resolveTestUnit('''
 abstract class ItemProvider<T> {
   List<T> getItems();
@@ -1967,7 +2107,7 @@
 class Test<V> extends ItemProvider<V> {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_MISSING_OVERRIDES,
         '''
 abstract class ItemProvider<T> {
@@ -1983,7 +2123,7 @@
 ''');
   }
 
-  void test_createMissingOverrides_getter() {
+  test_createMissingOverrides_getter() async {
     resolveTestUnit('''
 abstract class A {
   get g1;
@@ -1993,7 +2133,7 @@
 class B extends A {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_MISSING_OVERRIDES,
         '''
 abstract class A {
@@ -2013,7 +2153,7 @@
 ''');
   }
 
-  void test_createMissingOverrides_importPrefix() {
+  test_createMissingOverrides_importPrefix() async {
     resolveTestUnit('''
 import 'dart:async' as aaa;
 abstract class A {
@@ -2023,7 +2163,7 @@
 class B extends A {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_MISSING_OVERRIDES,
         '''
 import 'dart:async' as aaa;
@@ -2040,7 +2180,7 @@
 ''');
   }
 
-  void test_createMissingOverrides_mergeToField_getterSetter() {
+  test_createMissingOverrides_mergeToField_getterSetter() async {
     resolveTestUnit('''
 class A {
   int ma;
@@ -2051,7 +2191,7 @@
 class B implements A {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_MISSING_OVERRIDES,
         '''
 class A {
@@ -2073,7 +2213,7 @@
 ''');
   }
 
-  void test_createMissingOverrides_method() {
+  test_createMissingOverrides_method() async {
     resolveTestUnit('''
 abstract class A {
   m1();
@@ -2129,7 +2269,7 @@
   }
 }
 ''';
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, expectedCode);
+    await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, expectedCode);
     // end position should be on "m1", not on "m2", "m3", etc
     {
       Position endPosition = change.selection;
@@ -2146,7 +2286,7 @@
     }
   }
 
-  void test_createMissingOverrides_operator() {
+  test_createMissingOverrides_operator() async {
     resolveTestUnit('''
 abstract class A {
   int operator [](int index);
@@ -2156,7 +2296,7 @@
 class B extends A {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_MISSING_OVERRIDES,
         '''
 abstract class A {
@@ -2178,7 +2318,7 @@
 ''');
   }
 
-  void test_createMissingOverrides_setter() {
+  test_createMissingOverrides_setter() async {
     resolveTestUnit('''
 abstract class A {
   set s1(x);
@@ -2189,7 +2329,7 @@
 class B extends A {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_MISSING_OVERRIDES,
         '''
 abstract class A {
@@ -2217,7 +2357,7 @@
 ''');
   }
 
-  void test_createNoSuchMethod() {
+  test_createNoSuchMethod() async {
     resolveTestUnit('''
 abstract class A {
   m1();
@@ -2228,7 +2368,7 @@
   existing() {}
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_NO_SUCH_METHOD,
         '''
 abstract class A {
@@ -2244,7 +2384,7 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_cascadeSecond() {
+  test_creationFunction_forFunctionType_cascadeSecond() async {
     resolveTestUnit('''
 class A {
   B ma() => null;
@@ -2258,7 +2398,7 @@
   a..ma().useFunction(test);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 class A {
@@ -2278,14 +2418,14 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_coreFunction() {
+  test_creationFunction_forFunctionType_coreFunction() async {
     resolveTestUnit('''
 main() {
   useFunction(g: test);
 }
 useFunction({Function g}) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -2298,14 +2438,14 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_dynamicArgument() {
+  test_creationFunction_forFunctionType_dynamicArgument() async {
     resolveTestUnit('''
 main() {
   useFunction(test);
 }
 useFunction(int g(a, b)) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -2318,14 +2458,14 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_function() {
+  test_creationFunction_forFunctionType_function() async {
     resolveTestUnit('''
 main() {
   useFunction(test);
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -2338,14 +2478,14 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_function_namedArgument() {
+  test_creationFunction_forFunctionType_function_namedArgument() async {
     resolveTestUnit('''
 main() {
   useFunction(g: test);
 }
 useFunction({int g(double a, String b)}) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -2358,7 +2498,7 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_importType() {
+  test_creationFunction_forFunctionType_importType() async {
     addSource(
         '/libA.dart',
         r'''
@@ -2378,7 +2518,7 @@
   useFunction(test);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 import 'libB.dart';
@@ -2392,7 +2532,7 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_method_enclosingClass_static() {
+  test_creationFunction_forFunctionType_method_enclosingClass_static() async {
     resolveTestUnit('''
 class A {
   static foo() {
@@ -2401,7 +2541,7 @@
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -2416,7 +2556,7 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_method_enclosingClass_static2() {
+  test_creationFunction_forFunctionType_method_enclosingClass_static2() async {
     resolveTestUnit('''
 class A {
   var f;
@@ -2424,7 +2564,7 @@
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -2438,7 +2578,7 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_method_targetClass() {
+  test_creationFunction_forFunctionType_method_targetClass() async {
     resolveTestUnit('''
 main(A a) {
   useFunction(a.test);
@@ -2447,7 +2587,7 @@
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 main(A a) {
@@ -2461,7 +2601,7 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_method_targetClass_hasOtherMember() {
+  test_creationFunction_forFunctionType_method_targetClass_hasOtherMember() async {
     resolveTestUnit('''
 main(A a) {
   useFunction(a.test);
@@ -2471,7 +2611,7 @@
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 main(A a) {
@@ -2487,7 +2627,7 @@
 ''');
   }
 
-  void test_creationFunction_forFunctionType_notFunctionType() {
+  test_creationFunction_forFunctionType_notFunctionType() async {
     resolveTestUnit('''
 main(A a) {
   useFunction(a.test);
@@ -2495,11 +2635,11 @@
 typedef A();
 useFunction(g) {}
 ''');
-    assertNoFix(DartFixKind.CREATE_METHOD);
-    assertNoFix(DartFixKind.CREATE_FUNCTION);
+    await assertNoFix(DartFixKind.CREATE_METHOD);
+    await assertNoFix(DartFixKind.CREATE_FUNCTION);
   }
 
-  void test_creationFunction_forFunctionType_unknownTarget() {
+  test_creationFunction_forFunctionType_unknownTarget() async {
     resolveTestUnit('''
 main(A a) {
   useFunction(a.test);
@@ -2508,16 +2648,16 @@
 }
 useFunction(g) {}
 ''');
-    assertNoFix(DartFixKind.CREATE_METHOD);
+    await assertNoFix(DartFixKind.CREATE_METHOD);
   }
 
-  void test_expectedToken_semicolon() {
+  test_expectedToken_semicolon() async {
     resolveTestUnit('''
 main() {
   print(0)
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.INSERT_SEMICOLON,
         '''
 main() {
@@ -2526,7 +2666,23 @@
 ''');
   }
 
-  void test_illegalAsyncReturnType_asyncLibrary_import() {
+  test_illegalAsyncReturnType_adjacentNodes() async {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+    };
+    resolveTestUnit('''
+import 'dart:async';
+var v;int main() async => 0;
+''');
+    await assertHasFix(
+        DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
+        '''
+import 'dart:async';
+var v;Future<int> main() async => 0;
+''');
+  }
+
+  test_illegalAsyncReturnType_asyncLibrary_import() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
     };
@@ -2535,7 +2691,7 @@
 int main() async {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
         '''
 library main;
@@ -2545,7 +2701,7 @@
 ''');
   }
 
-  void test_illegalAsyncReturnType_asyncLibrary_usePrefix() {
+  test_illegalAsyncReturnType_asyncLibrary_usePrefix() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
     };
@@ -2554,7 +2710,7 @@
 int main() async {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
         '''
 import 'dart:async' as al;
@@ -2563,7 +2719,7 @@
 ''');
   }
 
-  void test_illegalAsyncReturnType_complexTypeName() {
+  test_illegalAsyncReturnType_complexTypeName() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
     };
@@ -2572,7 +2728,7 @@
 List<int> main() async {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
         '''
 import 'dart:async';
@@ -2581,7 +2737,7 @@
 ''');
   }
 
-  void test_illegalAsyncReturnType_void() {
+  test_illegalAsyncReturnType_void() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
     };
@@ -2590,7 +2746,7 @@
 void main() async {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
         '''
 import 'dart:async';
@@ -2599,7 +2755,7 @@
 ''');
   }
 
-  void test_importLibraryPackage_withClass() {
+  test_importLibraryPackage_withClass() async {
     _configureMyPkg('''
 library my_lib;
 class Test {}
@@ -2611,7 +2767,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import 'package:my_pkg/my_lib.dart';
@@ -2622,7 +2778,7 @@
 ''');
   }
 
-  void test_importLibraryProject_withClass_annotation() {
+  test_importLibraryProject_withClass_annotation() async {
     addSource(
         '/lib.dart',
         '''
@@ -2637,7 +2793,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import 'lib.dart';
@@ -2648,7 +2804,7 @@
 ''');
   }
 
-  void test_importLibraryProject_withClass_hasOtherLibraryWithPrefix() {
+  test_importLibraryProject_withClass_hasOtherLibraryWithPrefix() async {
     testFile = '/project/bin/test.dart';
     addSource(
         '/project/bin/a.dart',
@@ -2671,7 +2827,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import 'b.dart' show Two;
@@ -2683,7 +2839,7 @@
 ''');
   }
 
-  void test_importLibraryProject_withClass_inParentFolder() {
+  test_importLibraryProject_withClass_inParentFolder() async {
     testFile = '/project/bin/test.dart';
     addSource(
         '/project/lib.dart',
@@ -2697,7 +2853,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import '../lib.dart';
@@ -2708,7 +2864,7 @@
 ''');
   }
 
-  void test_importLibraryProject_withClass_inRelativeFolder() {
+  test_importLibraryProject_withClass_inRelativeFolder() async {
     testFile = '/project/bin/test.dart';
     addSource(
         '/project/lib/sub/folder/lib.dart',
@@ -2722,7 +2878,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import '../lib/sub/folder/lib.dart';
@@ -2733,7 +2889,7 @@
 ''');
   }
 
-  void test_importLibraryProject_withClass_inSameFolder() {
+  test_importLibraryProject_withClass_inSameFolder() async {
     testFile = '/project/bin/test.dart';
     addSource(
         '/project/bin/lib.dart',
@@ -2747,7 +2903,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import 'lib.dart';
@@ -2758,7 +2914,7 @@
 ''');
   }
 
-  void test_importLibraryProject_withFunction() {
+  test_importLibraryProject_withFunction() async {
     addSource(
         '/lib.dart',
         '''
@@ -2771,7 +2927,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import 'lib.dart';
@@ -2782,7 +2938,7 @@
 ''');
   }
 
-  void test_importLibraryProject_withFunction_unresolvedMethod() {
+  test_importLibraryProject_withFunction_unresolvedMethod() async {
     addSource(
         '/lib.dart',
         '''
@@ -2797,7 +2953,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import 'lib.dart';
@@ -2810,7 +2966,7 @@
 ''');
   }
 
-  void test_importLibraryProject_withFunctionTypeAlias() {
+  test_importLibraryProject_withFunctionTypeAlias() async {
     testFile = '/project/bin/test.dart';
     addSource(
         '/project/bin/lib.dart',
@@ -2824,7 +2980,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import 'lib.dart';
@@ -2835,7 +2991,7 @@
 ''');
   }
 
-  void test_importLibraryProject_withTopLevelVariable() {
+  test_importLibraryProject_withTopLevelVariable() async {
     addSource(
         '/lib.dart',
         '''
@@ -2848,7 +3004,7 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
 import 'lib.dart';
@@ -2859,13 +3015,13 @@
 ''');
   }
 
-  void test_importLibrarySdk_withClass_AsExpression() {
+  test_importLibrarySdk_withClass_AsExpression() async {
     resolveTestUnit('''
 main(p) {
   p as Future;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:async';
@@ -2876,13 +3032,13 @@
 ''');
   }
 
-  void test_importLibrarySdk_withClass_invocationTarget() {
+  test_importLibrarySdk_withClass_invocationTarget() async {
     resolveTestUnit('''
 main() {
   Future.wait(null);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:async';
@@ -2893,13 +3049,13 @@
 ''');
   }
 
-  void test_importLibrarySdk_withClass_IsExpression() {
+  test_importLibrarySdk_withClass_IsExpression() async {
     resolveTestUnit('''
 main(p) {
   p is Future;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:async';
@@ -2910,14 +3066,14 @@
 ''');
   }
 
-  void test_importLibrarySdk_withClass_itemOfList() {
+  test_importLibrarySdk_withClass_itemOfList() async {
     resolveTestUnit('''
 main() {
   var a = [Future];
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:async';
@@ -2928,7 +3084,7 @@
 ''');
   }
 
-  void test_importLibrarySdk_withClass_itemOfList_inAnnotation() {
+  test_importLibrarySdk_withClass_itemOfList_inAnnotation() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
     };
@@ -2939,7 +3095,7 @@
 @MyAnnotation(int, const [Future])
 main() {}
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:async';
@@ -2952,13 +3108,13 @@
 ''');
   }
 
-  void test_importLibrarySdk_withClass_typeAnnotation() {
+  test_importLibrarySdk_withClass_typeAnnotation() async {
     resolveTestUnit('''
 main() {
   Future f = null;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:async';
@@ -2969,13 +3125,13 @@
 ''');
   }
 
-  void test_importLibrarySdk_withClass_typeAnnotation_PrefixedIdentifier() {
+  test_importLibrarySdk_withClass_typeAnnotation_PrefixedIdentifier() async {
     resolveTestUnit('''
 main() {
   Future.wait;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:async';
@@ -2986,13 +3142,13 @@
 ''');
   }
 
-  void test_importLibrarySdk_withClass_typeArgument() {
+  test_importLibrarySdk_withClass_typeArgument() async {
     resolveTestUnit('''
 main() {
   List<Future> futures = [];
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:async';
@@ -3003,14 +3159,14 @@
 ''');
   }
 
-  void test_importLibrarySdk_withTopLevelVariable() {
+  test_importLibrarySdk_withTopLevelVariable() async {
     resolveTestUnit('''
 main() {
   print(PI);
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:math';
@@ -3021,14 +3177,14 @@
 ''');
   }
 
-  void test_importLibrarySdk_withTopLevelVariable_annotation() {
+  test_importLibrarySdk_withTopLevelVariable_annotation() async {
     resolveTestUnit('''
 @PI
 main() {
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SDK,
         '''
 import 'dart:math';
@@ -3039,7 +3195,7 @@
 ''');
   }
 
-  void test_importLibraryShow() {
+  test_importLibraryShow() async {
     resolveTestUnit('''
 import 'dart:async' show Stream;
 main() {
@@ -3047,7 +3203,7 @@
   Future f = null;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_SHOW,
         '''
 import 'dart:async' show Future, Stream;
@@ -3058,13 +3214,13 @@
 ''');
   }
 
-  void test_isNotNull() {
+  test_isNotNull() async {
     resolveTestUnit('''
 main(p) {
   p is! Null;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.USE_NOT_EQ_NULL,
         '''
 main(p) {
@@ -3073,13 +3229,13 @@
 ''');
   }
 
-  void test_isNull() {
+  test_isNull() async {
     resolveTestUnit('''
 main(p) {
   p is Null;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.USE_EQ_EQ_NULL,
         '''
 main(p) {
@@ -3088,13 +3244,13 @@
 ''');
   }
 
-  void test_makeEnclosingClassAbstract_declaresAbstractMethod() {
+  test_makeEnclosingClassAbstract_declaresAbstractMethod() async {
     resolveTestUnit('''
 class A {
   m();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.MAKE_CLASS_ABSTRACT,
         '''
 abstract class A {
@@ -3103,7 +3259,7 @@
 ''');
   }
 
-  void test_makeEnclosingClassAbstract_inheritsAbstractMethod() {
+  test_makeEnclosingClassAbstract_inheritsAbstractMethod() async {
     resolveTestUnit('''
 abstract class A {
   m();
@@ -3111,7 +3267,7 @@
 class B extends A {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.MAKE_CLASS_ABSTRACT,
         '''
 abstract class A {
@@ -3122,18 +3278,60 @@
 ''');
   }
 
-  void test_noException_1() {
+  test_makeFieldNotFinal_hasType() async {
+    resolveTestUnit('''
+class A {
+  final int fff = 1;
+  main() {
+    fff = 2;
+  }
+}
+''');
+    await assertHasFix(
+        DartFixKind.MAKE_FIELD_NOT_FINAL,
+        '''
+class A {
+  int fff = 1;
+  main() {
+    fff = 2;
+  }
+}
+''');
+  }
+
+  test_makeFieldNotFinal_noType() async {
+    resolveTestUnit('''
+class A {
+  final fff = 1;
+  main() {
+    fff = 2;
+  }
+}
+''');
+    await assertHasFix(
+        DartFixKind.MAKE_FIELD_NOT_FINAL,
+        '''
+class A {
+  var fff = 1;
+  main() {
+    fff = 2;
+  }
+}
+''');
+  }
+
+  test_noException_1() async {
     resolveTestUnit('''
 main(p) {
   p i s Null;
 }''');
     List<AnalysisError> errors = context.computeErrors(testSource);
     for (var error in errors) {
-      _computeFixes(error);
+      await _computeFixes(error);
     }
   }
 
-  void test_nonBoolCondition_addNotNull() {
+  test_nonBoolCondition_addNotNull() async {
     resolveTestUnit('''
 main(String p) {
   if (p) {
@@ -3141,7 +3339,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.ADD_NE_NULL,
         '''
 main(String p) {
@@ -3152,7 +3350,7 @@
 ''');
   }
 
-  void test_removeDeadCode_condition() {
+  test_removeDeadCode_condition() async {
     resolveTestUnit('''
 main(int p) {
   if (true || p > 5) {
@@ -3160,7 +3358,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_DEAD_CODE,
         '''
 main(int p) {
@@ -3171,7 +3369,7 @@
 ''');
   }
 
-  void test_removeDeadCode_statements_one() {
+  test_removeDeadCode_statements_one() async {
     resolveTestUnit('''
 int main() {
   print(0);
@@ -3179,7 +3377,7 @@
   print(1);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_DEAD_CODE,
         '''
 int main() {
@@ -3189,7 +3387,7 @@
 ''');
   }
 
-  void test_removeDeadCode_statements_two() {
+  test_removeDeadCode_statements_two() async {
     resolveTestUnit('''
 int main() {
   print(0);
@@ -3198,7 +3396,7 @@
   print(2);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_DEAD_CODE,
         '''
 int main() {
@@ -3208,13 +3406,13 @@
 ''');
   }
 
-  void test_removeParentheses_inGetterDeclaration() {
+  test_removeParentheses_inGetterDeclaration() async {
     resolveTestUnit('''
 class A {
   int get foo() => 0;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION,
         '''
 class A {
@@ -3223,7 +3421,7 @@
 ''');
   }
 
-  void test_removeParentheses_inGetterInvocation() {
+  test_removeParentheses_inGetterInvocation() async {
     resolveTestUnit('''
 class A {
   int get foo => 0;
@@ -3232,7 +3430,7 @@
   a.foo();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION,
         '''
 class A {
@@ -3244,7 +3442,7 @@
 ''');
   }
 
-  void test_removeUnnecessaryCast_assignment() {
+  test_removeUnnecessaryCast_assignment() async {
     resolveTestUnit('''
 main(Object p) {
   if (p is String) {
@@ -3252,8 +3450,8 @@
   }
 }
 ''');
-    assertHasFix(
-        DartFixKind.REMOVE_UNNECASSARY_CAST,
+    await assertHasFix(
+        DartFixKind.REMOVE_UNNECESSARY_CAST,
         '''
 main(Object p) {
   if (p is String) {
@@ -3263,7 +3461,7 @@
 ''');
   }
 
-  void test_removeUnusedCatchClause() {
+  test_removeUnusedCatchClause() async {
     errorFilter = (AnalysisError error) => true;
     resolveTestUnit('''
 main() {
@@ -3273,7 +3471,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE,
         '''
 main() {
@@ -3285,7 +3483,7 @@
 ''');
   }
 
-  void test_removeUnusedCatchStack() {
+  test_removeUnusedCatchStack() async {
     errorFilter = (AnalysisError error) => true;
     resolveTestUnit('''
 main() {
@@ -3295,7 +3493,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_UNUSED_CATCH_STACK,
         '''
 main() {
@@ -3307,13 +3505,13 @@
 ''');
   }
 
-  void test_removeUnusedImport() {
+  test_removeUnusedImport() async {
     resolveTestUnit('''
 import 'dart:math';
 main() {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_UNUSED_IMPORT,
         '''
 main() {
@@ -3321,7 +3519,7 @@
 ''');
   }
 
-  void test_removeUnusedImport_anotherImportOnLine() {
+  test_removeUnusedImport_anotherImportOnLine() async {
     resolveTestUnit('''
 import 'dart:math'; import 'dart:async';
 
@@ -3329,7 +3527,7 @@
   Future f;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_UNUSED_IMPORT,
         '''
 import 'dart:async';
@@ -3340,14 +3538,14 @@
 ''');
   }
 
-  void test_removeUnusedImport_severalLines() {
+  test_removeUnusedImport_severalLines() async {
     resolveTestUnit('''
 import
   'dart:math';
 main() {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REMOVE_UNUSED_IMPORT,
         '''
 main() {
@@ -3355,34 +3553,34 @@
 ''');
   }
 
-  void test_replaceImportUri_inProject() {
+  test_replaceImportUri_inProject() async {
     testFile = '/project/bin/test.dart';
     addSource('/project/foo/bar/lib.dart', '');
     resolveTestUnit('''
 import 'no/matter/lib.dart';
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REPLACE_IMPORT_URI,
         '''
 import '../foo/bar/lib.dart';
 ''');
   }
 
-  void test_replaceImportUri_package() {
+  test_replaceImportUri_package() async {
     _configureMyPkg('');
     resolveTestUnit('''
 import 'no/matter/my_lib.dart';
 ''');
     performAllAnalysisTasks();
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REPLACE_IMPORT_URI,
         '''
 import 'package:my_pkg/my_lib.dart';
 ''');
   }
 
-  void test_replaceVarWithDynamic() {
+  test_replaceVarWithDynamic() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == ParserErrorCode.VAR_AS_TYPE_NAME;
     };
@@ -3391,7 +3589,7 @@
   Map<String, var> m;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.REPLACE_VAR_WITH_DYNAMIC,
         '''
 class A {
@@ -3400,14 +3598,14 @@
 ''');
   }
 
-  void test_replaceWithConstInstanceCreation() {
+  test_replaceWithConstInstanceCreation() async {
     resolveTestUnit('''
 class A {
   const A();
 }
 const a = new A();
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.USE_CONST,
         '''
 class A {
@@ -3417,13 +3615,13 @@
 ''');
   }
 
-  void test_undefinedClass_useSimilar_fromImport() {
+  test_undefinedClass_useSimilar_fromImport() async {
     resolveTestUnit('''
 main() {
   Stirng s = 'abc';
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 main() {
@@ -3432,14 +3630,14 @@
 ''');
   }
 
-  void test_undefinedClass_useSimilar_fromThisLibrary() {
+  test_undefinedClass_useSimilar_fromThisLibrary() async {
     resolveTestUnit('''
 class MyClass {}
 main() {
   MyCalss v = null;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class MyClass {}
@@ -3449,14 +3647,14 @@
 ''');
   }
 
-  void test_undefinedFunction_create_dynamicArgument() {
+  test_undefinedFunction_create_dynamicArgument() async {
     resolveTestUnit('''
 main() {
   dynamic v;
   test(v);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -3469,13 +3667,13 @@
 ''');
   }
 
-  void test_undefinedFunction_create_dynamicReturnType() {
+  test_undefinedFunction_create_dynamicReturnType() async {
     resolveTestUnit('''
 main() {
   dynamic v = test();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -3487,13 +3685,13 @@
 ''');
   }
 
-  void test_undefinedFunction_create_fromFunction() {
+  test_undefinedFunction_create_fromFunction() async {
     resolveTestUnit('''
 main() {
   int v = myUndefinedFunction(1, 2.0, '3');
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -3505,7 +3703,7 @@
 ''');
   }
 
-  void test_undefinedFunction_create_fromMethod() {
+  test_undefinedFunction_create_fromMethod() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -3513,7 +3711,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 class A {
@@ -3527,7 +3725,7 @@
 ''');
   }
 
-  void test_undefinedFunction_create_generic_BAD() {
+  test_undefinedFunction_create_generic_BAD() async {
     resolveTestUnit('''
 class A<T> {
   Map<int, T> items;
@@ -3536,7 +3734,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 class A<T> {
@@ -3551,7 +3749,7 @@
 ''');
   }
 
-  void test_undefinedFunction_create_generic_OK() {
+  test_undefinedFunction_create_generic_OK() async {
     resolveTestUnit('''
 class A {
   List<int> items;
@@ -3560,7 +3758,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 class A {
@@ -3575,7 +3773,7 @@
 ''');
   }
 
-  void test_undefinedFunction_create_importType() {
+  test_undefinedFunction_create_importType() async {
     addSource(
         '/lib.dart',
         r'''
@@ -3589,7 +3787,7 @@
   test(getFuture());
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 import 'lib.dart';
@@ -3603,13 +3801,13 @@
 ''');
   }
 
-  void test_undefinedFunction_create_nullArgument() {
+  test_undefinedFunction_create_nullArgument() async {
     resolveTestUnit('''
 main() {
   test(null);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -3621,29 +3819,31 @@
 ''');
   }
 
-  void test_undefinedFunction_create_returnType_bool_expressions() {
-    assert_undefinedFunction_create_returnType_bool("!test();");
-    assert_undefinedFunction_create_returnType_bool("b && test();");
-    assert_undefinedFunction_create_returnType_bool("test() && b;");
-    assert_undefinedFunction_create_returnType_bool("b || test();");
-    assert_undefinedFunction_create_returnType_bool("test() || b;");
+  test_undefinedFunction_create_returnType_bool_expressions() async {
+    await assert_undefinedFunction_create_returnType_bool("!test();");
+    await assert_undefinedFunction_create_returnType_bool("b && test();");
+    await assert_undefinedFunction_create_returnType_bool("test() && b;");
+    await assert_undefinedFunction_create_returnType_bool("b || test();");
+    await assert_undefinedFunction_create_returnType_bool("test() || b;");
   }
 
-  void test_undefinedFunction_create_returnType_bool_statements() {
-    assert_undefinedFunction_create_returnType_bool("assert ( test() );");
-    assert_undefinedFunction_create_returnType_bool("if ( test() ) {}");
-    assert_undefinedFunction_create_returnType_bool("while ( test() ) {}");
-    assert_undefinedFunction_create_returnType_bool("do {} while ( test() );");
+  test_undefinedFunction_create_returnType_bool_statements() async {
+    await assert_undefinedFunction_create_returnType_bool("assert ( test() );");
+    await assert_undefinedFunction_create_returnType_bool("if ( test() ) {}");
+    await assert_undefinedFunction_create_returnType_bool(
+        "while ( test() ) {}");
+    await assert_undefinedFunction_create_returnType_bool(
+        "do {} while ( test() );");
   }
 
-  void test_undefinedFunction_create_returnType_fromAssignment_eq() {
+  test_undefinedFunction_create_returnType_fromAssignment_eq() async {
     resolveTestUnit('''
 main() {
   int v;
   v = myUndefinedFunction();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -3656,14 +3856,14 @@
 ''');
   }
 
-  void test_undefinedFunction_create_returnType_fromAssignment_plusEq() {
+  test_undefinedFunction_create_returnType_fromAssignment_plusEq() async {
     resolveTestUnit('''
 main() {
   int v;
   v += myUndefinedFunction();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -3676,13 +3876,13 @@
 ''');
   }
 
-  void test_undefinedFunction_create_returnType_fromBinary_right() {
+  test_undefinedFunction_create_returnType_fromBinary_right() async {
     resolveTestUnit('''
 main() {
   0 + myUndefinedFunction();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -3694,13 +3894,13 @@
 ''');
   }
 
-  void test_undefinedFunction_create_returnType_fromInitializer() {
+  test_undefinedFunction_create_returnType_fromInitializer() async {
     resolveTestUnit('''
 main() {
   int v = myUndefinedFunction();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -3712,14 +3912,14 @@
 ''');
   }
 
-  void test_undefinedFunction_create_returnType_fromInvocationArgument() {
+  test_undefinedFunction_create_returnType_fromInvocationArgument() async {
     resolveTestUnit('''
 foo(int p) {}
 main() {
   foo( myUndefinedFunction() );
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 foo(int p) {}
@@ -3732,13 +3932,13 @@
 ''');
   }
 
-  void test_undefinedFunction_create_returnType_fromReturn() {
+  test_undefinedFunction_create_returnType_fromReturn() async {
     resolveTestUnit('''
 int main() {
   return myUndefinedFunction();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 int main() {
@@ -3750,13 +3950,13 @@
 ''');
   }
 
-  void test_undefinedFunction_create_returnType_void() {
+  test_undefinedFunction_create_returnType_void() async {
     resolveTestUnit('''
 main() {
   myUndefinedFunction();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
 main() {
@@ -3768,13 +3968,13 @@
 ''');
   }
 
-  void test_undefinedFunction_useSimilar_fromImport() {
+  test_undefinedFunction_useSimilar_fromImport() async {
     resolveTestUnit('''
 main() {
   pritn(0);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 main() {
@@ -3783,14 +3983,14 @@
 ''');
   }
 
-  void test_undefinedFunction_useSimilar_thisLibrary() {
+  test_undefinedFunction_useSimilar_thisLibrary() async {
     resolveTestUnit('''
 myFunction() {}
 main() {
   myFuntcion();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 myFunction() {}
@@ -3800,7 +4000,7 @@
 ''');
   }
 
-  void test_undefinedGetter_useSimilar_hint() {
+  test_undefinedGetter_useSimilar_hint() async {
     resolveTestUnit('''
 class A {
   int myField;
@@ -3810,7 +4010,7 @@
   print(x.myFild);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -3823,7 +4023,7 @@
 ''');
   }
 
-  void test_undefinedGetter_useSimilar_qualified() {
+  test_undefinedGetter_useSimilar_qualified() async {
     resolveTestUnit('''
 class A {
   int myField;
@@ -3832,7 +4032,7 @@
   print(a.myFild);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -3844,7 +4044,7 @@
 ''');
   }
 
-  void test_undefinedGetter_useSimilar_qualified_static() {
+  test_undefinedGetter_useSimilar_qualified_static() async {
     resolveTestUnit('''
 class A {
   static int MY_NAME = 1;
@@ -3853,7 +4053,7 @@
   A.MY_NAM;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -3865,7 +4065,7 @@
 ''');
   }
 
-  void test_undefinedGetter_useSimilar_unqualified() {
+  test_undefinedGetter_useSimilar_unqualified() async {
     resolveTestUnit('''
 class A {
   int myField;
@@ -3874,7 +4074,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -3886,16 +4086,16 @@
 ''');
   }
 
-  void test_undefinedMethod_create_BAD_inSDK() {
+  test_undefinedMethod_create_BAD_inSDK() async {
     resolveTestUnit('''
 main() {
   List.foo();
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_METHOD);
+    await assertNoFix(DartFixKind.CREATE_METHOD);
   }
 
-  void test_undefinedMethod_create_generic_BAD_argumentType() {
+  test_undefinedMethod_create_generic_BAD_argumentType() async {
     resolveTestUnit('''
 class A<T> {
   B b;
@@ -3908,7 +4108,7 @@
 class B {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A<T> {
@@ -3926,7 +4126,7 @@
 ''');
   }
 
-  void test_undefinedMethod_create_generic_BAD_returnType() {
+  test_undefinedMethod_create_generic_BAD_returnType() async {
     resolveTestUnit('''
 class A<T> {
   main() {
@@ -3937,7 +4137,7 @@
 class B {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A<T> {
@@ -3953,7 +4153,7 @@
 ''');
   }
 
-  void test_undefinedMethod_create_generic_OK_literal() {
+  test_undefinedMethod_create_generic_OK_literal() async {
     resolveTestUnit('''
 class A {
   B b;
@@ -3966,7 +4166,7 @@
 class B {
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -3984,7 +4184,7 @@
 ''');
   }
 
-  void test_undefinedMethod_create_generic_OK_local() {
+  test_undefinedMethod_create_generic_OK_local() async {
     resolveTestUnit('''
 class A<T> {
   List<T> items;
@@ -3993,7 +4193,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A<T> {
@@ -4008,7 +4208,7 @@
 ''');
   }
 
-  void test_undefinedMethod_createQualified_fromClass() {
+  test_undefinedMethod_createQualified_fromClass() async {
     resolveTestUnit('''
 class A {
 }
@@ -4016,7 +4216,7 @@
   A.myUndefinedMethod();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -4029,7 +4229,7 @@
 ''');
   }
 
-  void test_undefinedMethod_createQualified_fromClass_hasOtherMember() {
+  test_undefinedMethod_createQualified_fromClass_hasOtherMember() async {
     resolveTestUnit('''
 class A {
   foo() {}
@@ -4038,7 +4238,7 @@
   A.myUndefinedMethod();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -4053,7 +4253,7 @@
 ''');
   }
 
-  void test_undefinedMethod_createQualified_fromInstance() {
+  test_undefinedMethod_createQualified_fromInstance() async {
     resolveTestUnit('''
 class A {
 }
@@ -4061,7 +4261,7 @@
   a.myUndefinedMethod();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -4074,26 +4274,26 @@
 ''');
   }
 
-  void test_undefinedMethod_createQualified_targetIsFunctionType() {
+  test_undefinedMethod_createQualified_targetIsFunctionType() async {
     resolveTestUnit('''
 typedef A();
 main() {
   A.myUndefinedMethod();
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_METHOD);
+    await assertNoFix(DartFixKind.CREATE_METHOD);
   }
 
-  void test_undefinedMethod_createQualified_targetIsUnresolved() {
+  test_undefinedMethod_createQualified_targetIsUnresolved() async {
     resolveTestUnit('''
 main() {
   NoSuchClass.myUndefinedMethod();
 }
 ''');
-    assertNoFix(DartFixKind.CREATE_METHOD);
+    await assertNoFix(DartFixKind.CREATE_METHOD);
   }
 
-  void test_undefinedMethod_createUnqualified_parameters() {
+  test_undefinedMethod_createUnqualified_parameters() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -4101,7 +4301,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -4139,7 +4339,51 @@
     _assertLinkedGroup(change.linkedEditGroups[index++], ['s)']);
   }
 
-  void test_undefinedMethod_createUnqualified_returnType() {
+  test_undefinedMethod_createUnqualified_parameters_named() async {
+    resolveTestUnit('''
+class A {
+  main() {
+    myUndefinedMethod(0, bbb: 1.0, ccc: '2');
+  }
+}
+''');
+    await assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
+class A {
+  main() {
+    myUndefinedMethod(0, bbb: 1.0, ccc: '2');
+  }
+
+  void myUndefinedMethod(int i, {double bbb, String ccc}) {
+  }
+}
+''');
+    // linked positions
+    int index = 0;
+    _assertLinkedGroup(
+        change.linkedEditGroups[index++], ['void myUndefinedMethod(']);
+    _assertLinkedGroup(change.linkedEditGroups[index++],
+        ['myUndefinedMethod(0', 'myUndefinedMethod(int']);
+    _assertLinkedGroup(
+        change.linkedEditGroups[index++],
+        ['int i'],
+        expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+            ['int', 'num', 'Object', 'Comparable']));
+    _assertLinkedGroup(change.linkedEditGroups[index++], ['i,']);
+    _assertLinkedGroup(
+        change.linkedEditGroups[index++],
+        ['double bbb'],
+        expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+            ['double', 'num', 'Object', 'Comparable']));
+    _assertLinkedGroup(
+        change.linkedEditGroups[index++],
+        ['String ccc'],
+        expectedSuggestions(
+            LinkedEditSuggestionKind.TYPE, ['String', 'Object', 'Comparable']));
+  }
+
+  test_undefinedMethod_createUnqualified_returnType() async {
     resolveTestUnit('''
 class A {
   main() {
@@ -4147,7 +4391,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -4165,13 +4409,13 @@
         ['myUndefinedMethod();', 'myUndefinedMethod() {']);
   }
 
-  void test_undefinedMethod_createUnqualified_staticFromField() {
+  test_undefinedMethod_createUnqualified_staticFromField() async {
     resolveTestUnit('''
 class A {
   static var f = myUndefinedMethod();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -4183,7 +4427,7 @@
 ''');
   }
 
-  void test_undefinedMethod_createUnqualified_staticFromMethod() {
+  test_undefinedMethod_createUnqualified_staticFromMethod() async {
     resolveTestUnit('''
 class A {
   static main() {
@@ -4191,7 +4435,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -4205,7 +4449,7 @@
 ''');
   }
 
-  void test_undefinedMethod_hint_createQualified_fromInstance() {
+  test_undefinedMethod_hint_createQualified_fromInstance() async {
     resolveTestUnit('''
 class A {
 }
@@ -4214,7 +4458,7 @@
   a.myUndefinedMethod();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CREATE_METHOD,
         '''
 class A {
@@ -4228,7 +4472,7 @@
 ''');
   }
 
-  void test_undefinedMethod_parameterType_differentPrefixInTargetUnit() {
+  test_undefinedMethod_parameterType_differentPrefixInTargetUnit() async {
     String code2 = r'''
 library test2;
 import 'test3.dart' as bbb;
@@ -4251,7 +4495,7 @@
 }
 ''');
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(DartFixKind.CREATE_METHOD, error);
+    fix = await _assertHasFix(DartFixKind.CREATE_METHOD, error);
     change = fix.change;
     // apply to "test2.dart"
     List<SourceFileEdit> fileEdits = change.edits;
@@ -4271,7 +4515,7 @@
 ''');
   }
 
-  void test_undefinedMethod_parameterType_inTargetUnit() {
+  test_undefinedMethod_parameterType_inTargetUnit() async {
     String code2 = r'''
 library test2;
 class D {
@@ -4287,7 +4531,7 @@
 }
 ''');
     AnalysisError error = _findErrorToFix();
-    fix = _assertHasFix(DartFixKind.CREATE_METHOD, error);
+    fix = await _assertHasFix(DartFixKind.CREATE_METHOD, error);
     change = fix.change;
     // apply to "test2.dart"
     List<SourceFileEdit> fileEdits = change.edits;
@@ -4306,16 +4550,16 @@
 ''');
   }
 
-  void test_undefinedMethod_useSimilar_ignoreOperators() {
+  test_undefinedMethod_useSimilar_ignoreOperators() async {
     resolveTestUnit('''
 main(Object object) {
   object.then();
 }
 ''');
-    assertNoFix(DartFixKind.CHANGE_TO);
+    await assertNoFix(DartFixKind.CHANGE_TO);
   }
 
-  void test_undefinedMethod_useSimilar_qualified() {
+  test_undefinedMethod_useSimilar_qualified() async {
     resolveTestUnit('''
 class A {
   myMethod() {}
@@ -4325,7 +4569,7 @@
   a.myMehtod();
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -4338,7 +4582,7 @@
 ''');
   }
 
-  void test_undefinedMethod_useSimilar_unqualified_superClass() {
+  test_undefinedMethod_useSimilar_unqualified_superClass() async {
     resolveTestUnit('''
 class A {
   myMethod() {}
@@ -4349,7 +4593,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -4363,7 +4607,7 @@
 ''');
   }
 
-  void test_undefinedMethod_useSimilar_unqualified_thisClass() {
+  test_undefinedMethod_useSimilar_unqualified_thisClass() async {
     resolveTestUnit('''
 class A {
   myMethod() {}
@@ -4372,7 +4616,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -4384,7 +4628,7 @@
 ''');
   }
 
-  void test_undefinedSetter_useSimilar_hint() {
+  test_undefinedSetter_useSimilar_hint() async {
     resolveTestUnit('''
 class A {
   int myField;
@@ -4394,7 +4638,7 @@
   x.myFild = 42;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -4407,7 +4651,7 @@
 ''');
   }
 
-  void test_undefinedSetter_useSimilar_qualified() {
+  test_undefinedSetter_useSimilar_qualified() async {
     resolveTestUnit('''
 class A {
   int myField;
@@ -4416,7 +4660,7 @@
   a.myFild = 42;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -4428,7 +4672,7 @@
 ''');
   }
 
-  void test_undefinedSetter_useSimilar_unqualified() {
+  test_undefinedSetter_useSimilar_unqualified() async {
     resolveTestUnit('''
 class A {
   int myField;
@@ -4437,7 +4681,7 @@
   }
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.CHANGE_TO,
         '''
 class A {
@@ -4449,7 +4693,7 @@
 ''');
   }
 
-  void test_useEffectiveIntegerDivision() {
+  test_useEffectiveIntegerDivision() async {
     resolveTestUnit('''
 main() {
   var a = 5;
@@ -4457,7 +4701,7 @@
   print((a / b).toInt());
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION,
         '''
 main() {
@@ -4468,7 +4712,7 @@
 ''');
   }
 
-  void test_useImportPrefix_withClass() {
+  test_useImportPrefix_withClass() async {
     resolveTestUnit('''
 import 'dart:async' as pref;
 main() {
@@ -4476,7 +4720,7 @@
   Future f = null;
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PREFIX,
         '''
 import 'dart:async' as pref;
@@ -4487,7 +4731,7 @@
 ''');
   }
 
-  void test_useImportPrefix_withTopLevelVariable() {
+  test_useImportPrefix_withTopLevelVariable() async {
     resolveTestUnit('''
 import 'dart:math' as pref;
 main() {
@@ -4495,7 +4739,7 @@
   print(PI);
 }
 ''');
-    assertHasFix(
+    await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PREFIX,
         '''
 import 'dart:math' as pref;
@@ -4509,8 +4753,8 @@
   /**
    * Computes fixes and verifies that there is a fix of the given kind.
    */
-  Fix _assertHasFix(FixKind kind, AnalysisError error) {
-    List<Fix> fixes = _computeFixes(error);
+  Future<Fix> _assertHasFix(FixKind kind, AnalysisError error) async {
+    List<Fix> fixes = await _computeFixes(error);
     for (Fix fix in fixes) {
       if (fix.kind == kind) {
         return fix;
@@ -4531,8 +4775,10 @@
   /**
    * Computes fixes for the given [error] in [testUnit].
    */
-  List<Fix> _computeFixes(AnalysisError error) {
-    FixProcessor processor = new FixProcessor(provider, testUnit, error);
+  Future<List<Fix>> _computeFixes(AnalysisError error) async {
+    DartFixContext dartContext = new DartFixContextImpl(
+        new FixContextImpl(provider, context, error), testUnit);
+    FixProcessor processor = new FixProcessor(dartContext);
     return processor.compute();
   }
 
diff --git a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
index deb386d..1c2a964 100644
--- a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
+++ b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
@@ -5,8 +5,9 @@
 library test.services.correction.name_suggestion;
 
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analysis_server/test/services/correction/source_range_test.dart b/pkg/analysis_server/test/services/correction/source_range_test.dart
index ebb0091..43d080b 100644
--- a/pkg/analysis_server/test/services/correction/source_range_test.dart
+++ b/pkg/analysis_server/test/services/correction/source_range_test.dart
@@ -5,8 +5,8 @@
 library test.services.correction.source_range;
 
 import 'package:analysis_server/src/services/correction/source_range.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart
index 6405e01..555b5824 100644
--- a/pkg/analysis_server/test/services/correction/status_test.dart
+++ b/pkg/analysis_server/test/services/correction/status_test.dart
@@ -8,8 +8,8 @@
 import 'package:analysis_server/src/services/correction/source_range.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/dependencies/library_dependencies_test.dart b/pkg/analysis_server/test/services/dependencies/library_dependencies_test.dart
index 69ccf4b..2c1b7b9 100644
--- a/pkg/analysis_server/test/services/dependencies/library_dependencies_test.dart
+++ b/pkg/analysis_server/test/services/dependencies/library_dependencies_test.dart
@@ -34,7 +34,7 @@
     // Cycles
     expect(libs, contains('/lib1.dart'));
     expect(libs, contains('/lib2.dart'));
-    // Regular sourcs
+    // Regular sources
     expect(libs, contains('/lib3.dart'));
     expect(libs, contains('/lib4.dart'));
     // Non-source, referenced by source
diff --git a/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart b/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
new file mode 100644
index 0000000..b040926
--- /dev/null
+++ b/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
@@ -0,0 +1,84 @@
+// 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 test.services.dependencies.import_collector;
+
+import 'package:analysis_server/src/services/dependencies/reachable_source_collector.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../abstract_context.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(ReachableSourceCollectorTest);
+}
+
+@reflectiveTest
+class ReachableSourceCollectorTest extends AbstractContextTest {
+  CompilationUnit addLibrary(String path, String contents) =>
+      resolveLibraryUnit(addSource(path, contents));
+
+  Map<String, List<String>> importsFor(Source source) =>
+      new ReachableSourceCollector(source, context).collectSources();
+
+  test_null_context() {
+    Source lib = addSource('/lib.dart', '');
+    expect(() => new ReachableSourceCollector(lib, null),
+        throwsA(new isInstanceOf<ArgumentError>()));
+  }
+
+  test_null_source() {
+    expect(() => new ReachableSourceCollector(null, context),
+        throwsA(new isInstanceOf<ArgumentError>()));
+  }
+
+  test_sources() {
+    Source lib1 = addSource(
+        '/lib1.dart',
+        '''
+import "lib2.dart";
+import "dart:html";''');
+    Source lib2 = addSource('/lib2.dart', 'import "lib1.dart";');
+
+    Source lib3 = addSource('/lib3.dart', 'import "lib4.dart";');
+    addSource('/lib4.dart', 'import "lib3.dart";');
+
+    Map<String, List<String>> imports = importsFor(lib1);
+
+    // Verify keys.
+    expect(
+        imports.keys,
+        unorderedEquals([
+          'dart:_internal',
+          'dart:async',
+          'dart:core',
+          'dart:html',
+          'dart:math',
+          'file:///lib1.dart',
+          'file:///lib2.dart',
+        ]));
+    // Values.
+    expect(imports['file:///lib1.dart'],
+        unorderedEquals(['dart:core', 'dart:html', 'file:///lib2.dart']));
+
+    // Check transitivity.
+    expect(importsFor(lib2).keys, contains('dart:html'));
+
+    // Cycles should be OK.
+    expect(
+        importsFor(lib3).keys,
+        unorderedEquals([
+          'dart:_internal',
+          'dart:async',
+          'dart:core',
+          'dart:math',
+          'file:///lib3.dart',
+          'file:///lib4.dart'
+        ]));
+  }
+}
diff --git a/pkg/analysis_server/test/services/dependencies/test_all.dart b/pkg/analysis_server/test/services/dependencies/test_all.dart
index 1874a07..b26ac82 100644
--- a/pkg/analysis_server/test/services/dependencies/test_all.dart
+++ b/pkg/analysis_server/test/services/dependencies/test_all.dart
@@ -7,12 +7,14 @@
 import 'package:unittest/unittest.dart';
 
 import '../../utils.dart';
-import 'library_dependencies_test.dart' as library_dependencies_test;
+import 'library_dependencies_test.dart' as library_dependencies;
+import 'reachable_source_collector_test.dart' as reachable_source_collector;
 
 /// Utility for manually running all tests.
 main() {
   initializeTestEnvironment();
   group('dependencies', () {
-    library_dependencies_test.main();
+    library_dependencies.main();
+    reachable_source_collector.main();
   });
 }
diff --git a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart b/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
index 1830a28..a33bd47 100644
--- a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
+++ b/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
@@ -4,14 +4,14 @@
 
 library test.services.src.index.dart_index_contributor;
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/index_contributor.dart';
 import 'package:analysis_server/src/services/index/index_store.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/index/indexable_file.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -94,27 +94,6 @@
     });
   }
 
-  void test_isReferencedBy_PrefixElement() {
-    _indexTestUnit('''
-import 'dart:async' as ppp;
-main() {
-  ppp.Future a;
-  ppp.Stream b;
-}
-''');
-    // prepare elements
-    PrefixElement element = findNodeElementAtString('ppp;');
-    Element elementA = findElement('a');
-    Element elementB = findElement('b');
-    IndexableElement indexable = new IndexableElement(element);
-    // verify
-    _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
-        _expectedLocation(elementA, 'ppp.Future'));
-    _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
-        _expectedLocation(elementB, 'ppp.Stream'));
-    _assertNoRecordedRelation(indexable, null, _expectedLocation(null, 'ppp;'));
-  }
-
   void test_bad_unresolvedFieldFormalParameter() {
     verifyNoTestUnitErrors = false;
     _indexTestUnit('''
@@ -1423,6 +1402,27 @@
         _expectedLocation(mainElement, 'p: 1'));
   }
 
+  void test_isReferencedBy_PrefixElement() {
+    _indexTestUnit('''
+import 'dart:async' as ppp;
+main() {
+  ppp.Future a;
+  ppp.Stream b;
+}
+''');
+    // prepare elements
+    PrefixElement element = findNodeElementAtString('ppp;');
+    Element elementA = findElement('a');
+    Element elementB = findElement('b');
+    IndexableElement indexable = new IndexableElement(element);
+    // verify
+    _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
+        _expectedLocation(elementA, 'ppp.Future'));
+    _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
+        _expectedLocation(elementB, 'ppp.Stream'));
+    _assertNoRecordedRelation(indexable, null, _expectedLocation(null, 'ppp;'));
+  }
+
   void test_isReferencedBy_TopLevelVariableElement() {
     addSource(
         '/lib.dart',
@@ -1665,7 +1665,7 @@
     for (RecordedRelation recordedRelation in recordedRelations) {
       if (_equalsRecordedRelation(
           recordedRelation, expectedIndexable, relationship, location)) {
-        fail('not expected: ${recordedRelation} in\n' +
+        fail('not expected: $recordedRelation in\n' +
             recordedRelations.join('\n'));
       }
     }
@@ -1781,9 +1781,7 @@
   }
 }
 
-class MockIndexStore extends TypedMock implements InternalIndexStore {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockIndexStore extends TypedMock implements InternalIndexStore {}
 
 /**
  * Information about a relation recorded into {@link IndexStore}.
diff --git a/pkg/analysis_server/test/services/index/local_index_test.dart b/pkg/analysis_server/test/services/index/local_index_test.dart
index dc2e92a..5f318ad 100644
--- a/pkg/analysis_server/test/services/index/local_index_test.dart
+++ b/pkg/analysis_server/test/services/index/local_index_test.dart
@@ -7,8 +7,8 @@
 import 'package:analysis_server/src/services/index/index_contributor.dart';
 import 'package:analysis_server/src/services/index/local_index.dart';
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/index/store/codec_test.dart b/pkg/analysis_server/test/services/index/store/codec_test.dart
index cfc6b97..e7914b8 100644
--- a/pkg/analysis_server/test/services/index/store/codec_test.dart
+++ b/pkg/analysis_server/test/services/index/store/codec_test.dart
@@ -4,11 +4,11 @@
 
 library test.services.src.index.store.codec;
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/index/store/mocks.dart b/pkg/analysis_server/test/services/index/store/mocks.dart
index 9ed78af..a197342 100644
--- a/pkg/analysis_server/test/services/index/store/mocks.dart
+++ b/pkg/analysis_server/test/services/index/store/mocks.dart
@@ -8,18 +8,10 @@
 import 'package:analysis_server/src/services/index/store/codec.dart';
 import 'package:typed_mock/typed_mock.dart';
 
-class MockContextCodec extends TypedMock implements ContextCodec {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockContextCodec extends TypedMock implements ContextCodec {}
 
-class MockElementCodec extends TypedMock implements ElementCodec {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockElementCodec extends TypedMock implements ElementCodec {}
 
-class MockLocation extends TypedMock implements LocationImpl {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLocation extends TypedMock implements LocationImpl {}
 
-class MockRelationshipCodec extends TypedMock implements RelationshipCodec {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockRelationshipCodec extends TypedMock implements RelationshipCodec {}
diff --git a/pkg/analysis_server/test/services/index/store/split_store_test.dart b/pkg/analysis_server/test/services/index/store/split_store_test.dart
index ab91ca6..fbe43d7 100644
--- a/pkg/analysis_server/test/services/index/store/split_store_test.dart
+++ b/pkg/analysis_server/test/services/index/store/split_store_test.dart
@@ -6,13 +6,14 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/plugin/index/index_core.dart';
+import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/index/store/codec.dart';
 import 'package:analysis_server/src/services/index/store/memory_node_manager.dart';
 import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -420,13 +421,9 @@
   }
 }
 
-class _MockFileManager extends TypedMock implements FileManager {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockFileManager extends TypedMock implements FileManager {}
 
-class _MockIndexNode extends TypedMock implements IndexNode {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockIndexNode extends TypedMock implements IndexNode {}
 
 @reflectiveTest
 class _RelationKeyDataTest {
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
index 0dd3c77..f7b036f 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
@@ -7,8 +7,8 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:unittest/unittest.dart';
 
 import 'abstract_refactoring.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
index ca3a1db..4a62450 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
@@ -9,7 +9,7 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide ElementKind;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../utils.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
index 2e3551f..5dca20d 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
@@ -9,7 +9,7 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide ElementKind;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../utils.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index a5dd25a..0ced288 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -5,6 +5,7 @@
 library test.services.refactoring.extract_local;
 
 import 'dart:async';
+import 'dart:convert';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
@@ -35,9 +36,8 @@
     _createRefactoringForString('1 + 2');
     // conflicting name
     RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.WARNING,
-        expectedMessage:
-            "A variable with name 'res' is already defined in the visible scope.");
+    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'res' is already used in the scope.");
   }
 
   test_checkFinalConditions_sameVariable_before() async {
@@ -50,9 +50,8 @@
     _createRefactoringForString('1 + 2');
     // conflicting name
     RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.WARNING,
-        expectedMessage:
-            "A variable with name 'res' is already defined in the visible scope.");
+    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'res' is already used in the scope.");
   }
 
   test_checkInitialConditions_assignmentLeftHandSize() async {
@@ -69,44 +68,16 @@
         expectedMessage: 'Cannot extract the left-hand side of an assignment.');
   }
 
-  test_checkInitialConditions_methodName_reference() async {
+  test_checkInitialConditions_namePartOfDeclaration_function() async {
     indexTestUnit('''
 main() {
-  main();
 }
 ''');
-    _createRefactoringWithSuffix('main', '();');
+    _createRefactoringWithSuffix('main', '()');
     // check conditions
     RefactoringStatus status = await refactoring.checkAllConditions();
     assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage: 'Cannot extract a single method name.');
-  }
-
-  test_checkInitialConditions_nameOfProperty_prefixedIdentifier() async {
-    indexTestUnit('''
-main(p) {
-  p.value; // marker
-}
-''');
-    _createRefactoringWithSuffix('value', '; // marker');
-    // check conditions
-    RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage: 'Cannot extract name part of a property access.');
-  }
-
-  test_checkInitialConditions_nameOfProperty_propertyAccess() async {
-    indexTestUnit('''
-main() {
-  foo().length; // marker
-}
-String foo() => '';
-''');
-    _createRefactoringWithSuffix('length', '; // marker');
-    // check conditions
-    RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage: 'Cannot extract name part of a property access.');
+        expectedMessage: 'Cannot extract the name part of a declaration.');
   }
 
   test_checkInitialConditions_namePartOfDeclaration_variable() async {
@@ -122,6 +93,17 @@
         expectedMessage: 'Cannot extract the name part of a declaration.');
   }
 
+  test_checkInitialConditions_noExpression() async {
+    indexTestUnit('''
+main() {
+  // abc
+}
+''');
+    _createRefactoringForString('abc');
+    // check conditions
+    _assertInitialConditions_fatal_selection();
+  }
+
   test_checkInitialConditions_notPartOfFunction() async {
     indexTestUnit('''
 int a = 1 + 2;
@@ -141,11 +123,13 @@
 }
 ''');
     _createRefactoringForString("'a");
-    // check conditions
-    RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage:
-            'Cannot extract only leading or trailing quote of string literal.');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 'abc';
+  var vvv = res;
+}
+''');
   }
 
   test_checkInitialConditions_stringSelection_trailingQuote() async {
@@ -155,14 +139,29 @@
 }
 ''');
     _createRefactoringForString("c'");
-    // check conditions
-    RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
-        expectedMessage:
-            'Cannot extract only leading or trailing quote of string literal.');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 'abc';
+  var vvv = res;
+}
+''');
   }
 
-  test_checkLocalName() {
+  test_checkInitialConditions_voidExpression() async {
+    indexTestUnit('''
+main() {
+  print(42);
+}
+''');
+    _createRefactoringForString('print');
+    // check conditions
+    RefactoringStatus status = await refactoring.checkInitialConditions();
+    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
+        expectedMessage: 'Cannot extract the void expression.');
+  }
+
+  test_checkName() {
     indexTestUnit('''
 main() {
   int a = 1 + 2;
@@ -185,6 +184,55 @@
     assertRefactoringStatusOK(refactoring.checkName());
   }
 
+  test_checkName_conflict_withInvokedFunction() async {
+    indexTestUnit('''
+main() {
+  int a = 1 + 2;
+  res();
+}
+
+void res() {}
+''');
+    _createRefactoringForString('1 + 2');
+    await refactoring.checkInitialConditions();
+    refactoring.name = 'res';
+    assertRefactoringStatus(
+        refactoring.checkName(), RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'res' is already used in the scope.");
+  }
+
+  test_checkName_conflict_withOtherLocal() async {
+    indexTestUnit('''
+main() {
+  var res;
+  int a = 1 + 2;
+}
+''');
+    _createRefactoringForString('1 + 2');
+    await refactoring.checkInitialConditions();
+    refactoring.name = 'res';
+    assertRefactoringStatus(
+        refactoring.checkName(), RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'res' is already used in the scope.");
+  }
+
+  test_checkName_conflict_withTypeName() async {
+    indexTestUnit('''
+main() {
+  int a = 1 + 2;
+  Res b = null;
+}
+
+class Res {}
+''');
+    _createRefactoringForString('1 + 2');
+    await refactoring.checkInitialConditions();
+    refactoring.name = 'Res';
+    assertRefactoringStatus(
+        refactoring.checkName(), RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'Res' is already used in the scope.");
+  }
+
   test_completeStatementExpression() {
     indexTestUnit('''
 main(p) {
@@ -334,6 +382,153 @@
 ''');
   }
 
+  test_coveringExpressions() async {
+    indexTestUnit('''
+main() {
+  int aaa = 1;
+  int bbb = 2;
+  var c = aaa + bbb * 2 + 3;
+}
+''');
+    _createRefactoring(testCode.indexOf('bb * 2'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions,
+        ['bbb', 'bbb * 2', 'aaa + bbb * 2', 'aaa + bbb * 2 + 3']);
+  }
+
+  test_coveringExpressions_inArgumentList() async {
+    indexTestUnit('''
+main() {
+  foo(111 + 222);
+}
+int foo(int x) => x;
+''');
+    _createRefactoring(testCode.indexOf('11 +'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['111', '111 + 222', 'foo(111 + 222)']);
+  }
+
+  test_coveringExpressions_inInvocationOfVoidFunction() async {
+    indexTestUnit('''
+main() {
+  foo(111 + 222);
+}
+void foo(int x) {}
+''');
+    _createRefactoring(testCode.indexOf('11 +'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['111', '111 + 222']);
+  }
+
+  test_coveringExpressions_namedExpression_value() async {
+    indexTestUnit('''
+main() {
+  foo(ppp: 42);
+}
+int foo({int ppp: 0}) => ppp + 1;
+''');
+    _createRefactoring(testCode.indexOf('42'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['42', 'foo(ppp: 42)']);
+  }
+
+  test_coveringExpressions_skip_assignment() async {
+    indexTestUnit('''
+main() {
+  int v;
+  foo(v = 111 + 222);
+}
+int foo(x) => 42;
+''');
+    _createRefactoring(testCode.indexOf('11 +'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['111', '111 + 222', 'foo(v = 111 + 222)']);
+  }
+
+  test_coveringExpressions_skip_constructorName() async {
+    indexTestUnit('''
+class AAA {
+  AAA.name() {}
+}
+main() {
+  int v = new AAA.name();
+}
+''');
+    _createRefactoring(testCode.indexOf('AA.name();'), 5);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['new AAA.name()']);
+  }
+
+  test_coveringExpressions_skip_constructorName_name() async {
+    indexTestUnit('''
+class A {
+  A.name() {}
+}
+main() {
+  int v = new A.name();
+}
+''');
+    _createRefactoring(testCode.indexOf('ame();'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['new A.name()']);
+  }
+
+  test_coveringExpressions_skip_constructorName_type() async {
+    indexTestUnit('''
+class A {}
+main() {
+  int v = new A();
+}
+''');
+    _createRefactoring(testCode.indexOf('A();'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['new A()']);
+  }
+
+  test_coveringExpressions_skip_constructorName_typeArgument() async {
+    indexTestUnit('''
+class A<T> {}
+main() {
+  int v = new A<String>();
+}
+''');
+    _createRefactoring(testCode.indexOf('ring>'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['new A<String>()']);
+  }
+
+  test_coveringExpressions_skip_namedExpression() async {
+    indexTestUnit('''
+main() {
+  foo(ppp: 42);
+}
+int foo({int ppp: 0}) => ppp + 1;
+''');
+    _createRefactoring(testCode.indexOf('pp: 42'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['foo(ppp: 42)']);
+  }
+
   test_fragmentExpression() {
     indexTestUnit('''
 main() {
@@ -344,8 +539,8 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res = 2 + 3;
-  int a = 1 + res + 4;
+  var res = 1 + 2 + 3;
+  int a = res + 4;
 }
 ''');
   }
@@ -357,8 +552,13 @@
 }
 ''');
     _createRefactoringForString('+ 2');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 1 + 2;
+  int a = res + 3 + 4;
+}
+''');
   }
 
   test_fragmentExpression_leadingPartialSelection() {
@@ -368,8 +568,13 @@
 }
 ''');
     _createRefactoringForString('11 + 2');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 111 + 2;
+  int a = res + 3 + 4;
+}
+''');
   }
 
   test_fragmentExpression_leadingWhitespace() {
@@ -382,8 +587,8 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res =  2 + 3;
-  int a = 1 +res + 4;
+  var res = 1 + 2 + 3;
+  int a = res + 4;
 }
 ''');
   }
@@ -395,8 +600,13 @@
 }
 ''');
     _createRefactoringForString('2 - 3');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 1 - 2 - 3;
+  int a = res - 4;
+}
+''');
   }
 
   test_fragmentExpression_trailingNotWhitespace() {
@@ -405,20 +615,30 @@
   int a = 1 + 2 + 3 + 4;
 }
 ''');
-    _createRefactoringForString('2 + 3 +');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    _createRefactoringForString('1 + 2 +');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 1 + 2 + 3;
+  int a = res + 4;
+}
+''');
   }
 
   test_fragmentExpression_trailingPartialSelection() {
     indexTestUnit('''
 main() {
-  int a = 1 + 2 + 3 + 444;
+  int a = 1 + 2 + 333 + 4;
 }
 ''');
-    _createRefactoringForString('2 + 3 + 44');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    _createRefactoringForString('2 + 33');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 1 + 2 + 333;
+  int a = res + 4;
+}
+''');
   }
 
   test_fragmentExpression_trailingWhitespace() {
@@ -431,8 +651,8 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res = 2 + 3 ;
-  int a = 1 + res+ 4;
+  var res = 1 + 2 + 3;
+  int a = res + 4;
 }
 ''');
   }
@@ -446,7 +666,7 @@
     _createRefactoringForString('222 + 333');
     // check guesses
     await refactoring.checkInitialConditions();
-    expect(refactoring.names, isEmpty);
+    expect(refactoring.names, unorderedEquals(['i']));
   }
 
   test_guessNames_singleExpression() async {
@@ -477,7 +697,7 @@
     expect(refactoring.names, unorderedEquals(['helloBob', 'bob']));
   }
 
-  test_occurences_differentVariable() {
+  test_occurrences_differentVariable() async {
     indexTestUnit('''
 main() {
   {
@@ -493,7 +713,7 @@
 ''');
     _createRefactoringWithSuffix('v + 1', '); // marker');
     // apply refactoring
-    return _assertSuccessfulRefactoring('''
+    await _assertSuccessfulRefactoring('''
 main() {
   {
     int v = 1;
@@ -507,9 +727,11 @@
   }
 }
 ''');
+    _assertSingleLinkedEditGroup(
+        length: 3, offsets: [36, 59, 85], names: ['object', 'i']);
   }
 
-  test_occurences_disableOccurences() {
+  test_occurrences_disableOccurrences() {
     indexTestUnit('''
 int foo() => 42;
 main() {
@@ -530,7 +752,7 @@
 ''');
   }
 
-  test_occurences_ignore_assignmentLeftHandSize() {
+  test_occurrences_ignore_assignmentLeftHandSize() {
     indexTestUnit('''
 main() {
   int v = 1;
@@ -554,7 +776,7 @@
 ''');
   }
 
-  test_occurences_ignore_nameOfVariableDeclariton() {
+  test_occurrences_ignore_nameOfVariableDeclaration() {
     indexTestUnit('''
 main() {
   int v = 1;
@@ -572,7 +794,7 @@
 ''');
   }
 
-  test_occurences_singleExpression() {
+  test_occurrences_singleExpression() {
     indexTestUnit('''
 int foo() => 42;
 main() {
@@ -592,7 +814,7 @@
 ''');
   }
 
-  test_occurences_useDominator() {
+  test_occurrences_useDominator() {
     indexTestUnit('''
 main() {
   if (true) {
@@ -616,7 +838,7 @@
 ''');
   }
 
-  test_occurences_whenComment() {
+  test_occurrences_whenComment() {
     indexTestUnit('''
 int foo() => 42;
 main() {
@@ -636,7 +858,7 @@
 ''');
   }
 
-  test_occurences_withSpace() {
+  test_occurrences_withSpace() {
     indexTestUnit('''
 int foo(String s) => 42;
 main() {
@@ -731,7 +953,7 @@
 ''');
   }
 
-  test_singleExpression_inExpressionBody() {
+  test_singleExpression_inExpressionBody() async {
     indexTestUnit('''
 main() {
   print((x) => x.y * x.y + 1);
@@ -739,7 +961,7 @@
 ''');
     _createRefactoringForString('x.y');
     // apply refactoring
-    return _assertSuccessfulRefactoring('''
+    await _assertSuccessfulRefactoring('''
 main() {
   print((x) {
     var res = x.y;
@@ -747,6 +969,8 @@
   });
 }
 ''');
+    _assertSingleLinkedEditGroup(
+        length: 3, offsets: [31, 53, 59], names: ['y']);
   }
 
   test_singleExpression_inIfElseIf() {
@@ -800,28 +1024,85 @@
 }
 ''');
     _createRefactoringForString('+ 345');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 12 + 345;
+  int a = res;
+}
+''');
   }
 
   test_singleExpression_leadingWhitespace() {
     indexTestUnit('''
 main() {
-  int a = 12 /*abc*/ + 345;
+  int a = 1 /*abc*/ + 2 + 345;
 }
 ''');
-    _createRefactoringForString('12 /*abc*/');
+    _createRefactoringForString('1 /*abc*/');
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res = 12 /*abc*/;
+  var res = 1 /*abc*/ + 2;
   int a = res + 345;
 }
 ''');
   }
 
+  test_singleExpression_methodName_reference() async {
+    indexTestUnit('''
+main() {
+  var v = foo().length;
+}
+String foo() => '';
+''');
+    _createRefactoringWithSuffix('foo', '().');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = foo();
+  var v = res.length;
+}
+String foo() => '';
+''');
+  }
+
+  test_singleExpression_nameOfProperty_prefixedIdentifier() async {
+    indexTestUnit('''
+main(p) {
+  var v = p.value; // marker
+}
+''');
+    _createRefactoringWithSuffix('value', '; // marker');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main(p) {
+  var res = p.value;
+  var v = res; // marker
+}
+''');
+  }
+
+  test_singleExpression_nameOfProperty_propertyAccess() async {
+    indexTestUnit('''
+main() {
+  var v = foo().length; // marker
+}
+String foo() => '';
+''');
+    _createRefactoringWithSuffix('length', '; // marker');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = foo().length;
+  var v = res; // marker
+}
+String foo() => '';
+''');
+  }
+
   /**
-   * Here we use knowledge how exactly `1 + 2 + 3 + 41 is parsed. We know that
+   * Here we use knowledge how exactly `1 + 2 + 3 + 4` is parsed. We know that
    * `1 + 2` will be a separate and complete binary expression, so it can be
    * handled as a single expression.
    */
@@ -841,18 +1122,18 @@
 ''');
   }
 
-  test_singleExpression_trailingComment() {
+  test_singleExpression_string() {
     indexTestUnit('''
-main() {
-  int a =  1 + 2;
+void main() {
+  print("1234");
 }
 ''');
-    _createRefactoringForString(' 1 + 2');
+    _createRefactoringAtString('34"');
     // apply refactoring
     return _assertSuccessfulRefactoring('''
-main() {
-  var res =  1 + 2;
-  int a = res;
+void main() {
+  var res = "1234";
+  print(res);
 }
 ''');
   }
@@ -864,8 +1145,13 @@
 }
 ''');
     _createRefactoringForString('12 +');
-    // check conditions
-    return _assertInitialConditions_fatal_selection();
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+main() {
+  var res = 12 + 345;
+  int a = res;
+}
+''');
   }
 
   test_singleExpression_trailingWhitespace() {
@@ -878,13 +1164,13 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 main() {
-  var res = 1 + 2 ;
-  int a = res;
+  var res = 1 + 2;
+  int a = res ;
 }
 ''');
   }
 
-  test_stringLiteral_part() {
+  test_stringLiteral_part() async {
     indexTestUnit('''
 main() {
   print('abcdefgh');
@@ -892,15 +1178,16 @@
 ''');
     _createRefactoringForString('cde');
     // apply refactoring
-    return _assertSuccessfulRefactoring(r'''
+    await _assertSuccessfulRefactoring(r'''
 main() {
   var res = 'cde';
   print('ab${res}fgh');
 }
 ''');
+    _assertSingleLinkedEditGroup(length: 3, offsets: [15, 41], names: ['cde']);
   }
 
-  test_stringLiteral_whole() {
+  test_stringLiteral_whole() async {
     indexTestUnit('''
 main() {
   print('abc');
@@ -908,15 +1195,17 @@
 ''');
     _createRefactoringForString("'abc'");
     // apply refactoring
-    return _assertSuccessfulRefactoring('''
+    await _assertSuccessfulRefactoring('''
 main() {
   var res = 'abc';
   print(res);
 }
 ''');
+    _assertSingleLinkedEditGroup(
+        length: 3, offsets: [15, 36], names: ['object', 's']);
   }
 
-  test_stringLiteralPart() {
+  test_stringLiteralPart() async {
     indexTestUnit(r'''
 main() {
   int x = 1;
@@ -926,7 +1215,7 @@
 ''');
     _createRefactoringForString(r'$x+$y');
     // apply refactoring
-    return _assertSuccessfulRefactoring(r'''
+    await _assertSuccessfulRefactoring(r'''
 main() {
   int x = 1;
   int y = 2;
@@ -934,6 +1223,7 @@
   print('${res}=${x+y}');
 }
 ''');
+    _assertSingleLinkedEditGroup(length: 3, offsets: [41, 67], names: ['xy']);
   }
 
   Future _assertInitialConditions_fatal_selection() async {
@@ -943,9 +1233,30 @@
             'Expression must be selected to activate this refactoring.');
   }
 
+  void _assertSingleLinkedEditGroup(
+      {int length, List<int> offsets, List<String> names}) {
+    String positionsString = offsets
+        .map((offset) => '{"file": "$testFile", "offset": $offset}')
+        .join(',');
+    String suggestionsString =
+        names.map((name) => '{"value": "$name", "kind": "VARIABLE"}').join(',');
+    _assertSingleLinkedEditGroupJson('''
+{
+  "length": $length,
+  "positions": [$positionsString],
+  "suggestions": [$suggestionsString]
+}''');
+  }
+
+  void _assertSingleLinkedEditGroupJson(String expectedJsonString) {
+    List<LinkedEditGroup> editGroups = refactoringChange.linkedEditGroups;
+    expect(editGroups, hasLength(1));
+    expect(editGroups.first.toJson(), JSON.decode(expectedJsonString));
+  }
+
   /**
-   * Checks that all conditions are OK and the result of applying the [Change]
-   * to [testUnit] is [expectedCode].
+   * Checks that all conditions are OK and the result of applying the
+   * [SourceChange] to [testUnit] is [expectedCode].
    */
   Future _assertSuccessfulRefactoring(String expectedCode) async {
     await assertRefactoringConditionsOK();
@@ -960,6 +1271,16 @@
   }
 
   /**
+   * Creates a new refactoring in [refactoring] at the offset of the given
+   * [search] pattern, and with the length `0`.
+   */
+  void _createRefactoringAtString(String search) {
+    int offset = findOffset(search);
+    int length = 0;
+    _createRefactoring(offset, length);
+  }
+
+  /**
    * Creates a new refactoring in [refactoring] for the selection range of the
    * given [search] pattern.
    */
@@ -974,4 +1295,14 @@
     int length = selectionSearch.length;
     _createRefactoring(offset, length);
   }
+
+  List<String> _getCoveringExpressions() {
+    List<String> subExpressions = <String>[];
+    for (int i = 0; i < refactoring.coveringExpressionOffsets.length; i++) {
+      int offset = refactoring.coveringExpressionOffsets[i];
+      int length = refactoring.coveringExpressionLengths[i];
+      subExpressions.add(testCode.substring(offset, offset + length));
+    }
+    return subExpressions;
+  }
 }
diff --git a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
index 9b6d46e..74d2ca8 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
@@ -7,8 +7,8 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index 720dc9a..4d96523 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -10,7 +10,7 @@
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 1453d46..0e38446 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -10,7 +10,9 @@
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:typed_mock/typed_mock.dart';
@@ -62,9 +64,7 @@
   }
 }
 
-class MockIndex extends TypedMock implements Index {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockIndex extends TypedMock implements Index {}
 
 @reflectiveTest
 class SearchEngineImplTest extends AbstractSingleUnitTest {
diff --git a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
index 2c1d252..9aa321b 100644
--- a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
+++ b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
@@ -49,7 +49,9 @@
       for (String path in inputFiles) {
         resProvider.newFile(path, '');
       }
-      return resProvider.getResource(inputFiles[0]).parent;
+      Folder projectFolder = resProvider.getResource(inputFiles[0]).parent;
+      resProvider.newFile(projectFolder.path + '/pubspec.lock', '');
+      return projectFolder;
     }
 
     int mockWriteFile(File cacheFile, String content) {
diff --git a/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart b/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart
index 43adc4e..4eb855f 100644
--- a/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart
+++ b/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart
@@ -4,8 +4,8 @@
 
 library analysis_server.test.src.utilities.change_builder_core_test;
 
-import 'package:analysis_server/plugin/edit/utilities/change_builder_core.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/edit/utilities/change_builder_core.dart';
 import 'package:analysis_server/src/utilities/change_builder_core.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
index 7c6442b..5db934d 100644
--- a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
+++ b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
@@ -4,8 +4,8 @@
 
 library analysis_server.test.src.utilities.change_builder_dart_test;
 
-import 'package:analysis_server/plugin/edit/utilities/change_builder_dart.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/edit/utilities/change_builder_dart.dart';
 import 'package:analysis_server/src/utilities/change_builder_dart.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/test/stress/replay/operation.dart b/pkg/analysis_server/test/stress/replay/operation.dart
new file mode 100644
index 0000000..835eb50
--- /dev/null
+++ b/pkg/analysis_server/test/stress/replay/operation.dart
@@ -0,0 +1,82 @@
+// 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.
+
+/**
+ * Operations to be performed during the simulation.
+ */
+library analysis_server.test.stress.replay.replay;
+
+import '../utilities/server.dart';
+
+/**
+ * An operation that will send an 'analysis.updateContent' request.
+ */
+class Analysis_UpdateContent extends ServerOperation {
+  /**
+   * The path of the file whose content is being updated.
+   */
+  final String filePath;
+
+  /**
+   * The overlay used to update the content.
+   */
+  final dynamic overlay;
+
+  /**
+   * Initialize an operation to send an 'analysis.updateContent' request with
+   * the given [filePath] and [overlay] as parameters.
+   */
+  Analysis_UpdateContent(this.filePath, this.overlay);
+
+  @override
+  void perform(Server server) {
+    server.sendAnalysisUpdateContent({filePath: overlay});
+//    if (overlay is ChangeContentOverlay) {
+//      List<SourceEdit> edits = (overlay as ChangeContentOverlay).edits;
+//      if (edits.length == 1) {
+//        SourceEdit edit = edits[0];
+//        if (edit.replacement.endsWith('.')) {
+//          int offset = edit.offset + edit.replacement.length - 1;
+//          server.sendCompletionGetSuggestions(filePath, offset);
+//        }
+//      }
+//    }
+  }
+}
+
+/**
+ * An operation that will send a 'completion.getSuggestions' request.
+ */
+class Completion_GetSuggestions extends ServerOperation {
+  /**
+   * The path of the file in which completions are being requested.
+   */
+  final String filePath;
+
+  /**
+   * The offset at which completions are being requested.
+   */
+  final int offset;
+
+  /**
+   * Initialize an operation to send a 'completion.getSuggestions' request with
+   * the given [filePath] and [offset] as parameters.
+   */
+  Completion_GetSuggestions(this.filePath, this.offset);
+
+  @override
+  void perform(Server server) {
+    server.sendCompletionGetSuggestions(filePath, offset);
+  }
+}
+
+/**
+ * An operation to be performed during the simulation.
+ */
+abstract class ServerOperation {
+  /**
+   * Perform this operation by communicating with the given [server].
+   */
+  void perform(Server server);
+}
diff --git a/pkg/analysis_server/test/stress/replay/replay.dart b/pkg/analysis_server/test/stress/replay/replay.dart
new file mode 100644
index 0000000..159944f
--- /dev/null
+++ b/pkg/analysis_server/test/stress/replay/replay.dart
@@ -0,0 +1,639 @@
+// 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.
+
+/**
+ * A stress test for the analysis server.
+ */
+library analysis_server.test.stress.replay.replay;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analyzer/src/generated/error.dart' as error;
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/glob.dart';
+import 'package:args/args.dart';
+import 'package:path/path.dart' as path;
+
+import '../utilities/git.dart';
+import '../utilities/server.dart';
+import 'operation.dart';
+
+/**
+ * Run the simulation based on the given command-line [arguments].
+ */
+Future main(List<String> arguments) async {
+  Driver driver = new Driver();
+  await driver.run(arguments);
+}
+
+/**
+ * The driver class that runs the simulation.
+ */
+class Driver {
+  /**
+   * The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications
+   * to a file should be represented by an add overlay, followed by zero or more
+   * change overlays, followed by a remove overlay.
+   */
+  static String CHANGE_OVERLAY_STYLE = 'change';
+
+  /**
+   * The name of the command-line flag that will print help text.
+   */
+  static String HELP_FLAG_NAME = 'help';
+
+  /**
+   * The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications
+   * to a file should be represented by an add overlay, followed by zero or more
+   * additional add overlays, followed by a remove overlay.
+   */
+  static String MULTIPLE_ADD_OVERLAY_STYLE = 'multipleAdd';
+
+  /**
+   * The name of the command-line option used to specify the style of
+   * interaction to use when making `analysis.updateContent` requests.
+   */
+  static String OVERLAY_STYLE_OPTION_NAME = 'overlay-style';
+
+  /**
+   * The name of the pubspec file.
+   */
+  static const String PUBSPEC_FILE_NAME = 'pubspec.yaml';
+
+  /**
+   * The name of the branch used to clean-up after making temporary changes.
+   */
+  static const String TEMP_BRANCH_NAME = 'temp';
+
+  /**
+   * The style of interaction to use for analysis.updateContent requests.
+   */
+  OverlayStyle overlayStyle;
+
+  /**
+   * The absolute path of the repository.
+   */
+  String repositoryPath;
+
+  /**
+   * The absolute paths to the analysis roots.
+   */
+  List<String> analysisRoots;
+
+  /**
+   * The git repository.
+   */
+  GitRepository repository;
+
+  /**
+   * The connection to the analysis server.
+   */
+  Server server = new Server();
+
+  /**
+   * A list of the glob patterns used to identify the files being analyzed by
+   * the server.
+   */
+  List<Glob> fileGlobs;
+
+  /**
+   * An object gathering statistics about the simulation.
+   */
+  Statistics statistics;
+
+  /**
+   * Initialize a newly created driver.
+   */
+  Driver() {
+    statistics = new Statistics(this);
+  }
+
+  /**
+   * Run the simulation based on the given command-line arguments ([args]).
+   */
+  Future run(List<String> args) async {
+    //
+    // Process the command-line arguments.
+    //
+    if (!_processCommandLine(args)) {
+      return null;
+    }
+    //
+    // Simulate interactions with the server.
+    //
+    await _runSimulation();
+    //
+    // Print out statistics gathered while performing the simulation.
+    //
+    statistics.print();
+    exit(0);
+    return null;
+  }
+
+  /**
+   * Create and return a parser that can be used to parse the command-line
+   * arguments.
+   */
+  ArgParser _createArgParser() {
+    ArgParser parser = new ArgParser();
+    parser.addFlag(HELP_FLAG_NAME,
+        abbr: 'h',
+        help: 'Print usage information',
+        defaultsTo: false,
+        negatable: false);
+
+    parser.addOption(OVERLAY_STYLE_OPTION_NAME,
+        help:
+            'The style of interaction to use for analysis.updateContent requests',
+        allowed: [CHANGE_OVERLAY_STYLE, MULTIPLE_ADD_OVERLAY_STYLE],
+        allowedHelp: {
+          CHANGE_OVERLAY_STYLE: '<add> <change>* <remove>',
+          MULTIPLE_ADD_OVERLAY_STYLE: '<add>+ <remove>'
+        },
+        defaultsTo: 'change');
+    return parser;
+  }
+
+  /**
+   * Add source edits to the given [fileEdit] based on the given [blobDiff].
+   */
+  void _createSourceEdits(FileEdit fileEdit, BlobDiff blobDiff) {
+    LineInfo info = fileEdit.lineInfo;
+    for (DiffHunk hunk in blobDiff.hunks) {
+      int srcStart = info.getOffsetOfLine(hunk.srcLine);
+      int srcEnd = info.getOffsetOfLine(hunk.srcLine + hunk.removeLines.length);
+      String addedText = _join(hunk.addLines);
+      //
+      // Create the source edits.
+      //
+      List<int> breakOffsets = _getBreakOffsets(addedText);
+      int breakCount = breakOffsets.length;
+      List<SourceEdit> sourceEdits = <SourceEdit>[];
+      if (breakCount == 0) {
+        sourceEdits
+            .add(new SourceEdit(srcStart, srcEnd - srcStart + 1, addedText));
+      } else {
+        int previousOffset = breakOffsets[0];
+        String string = addedText.substring(0, previousOffset);
+        sourceEdits
+            .add(new SourceEdit(srcStart, srcEnd - srcStart + 1, string));
+        String reconstruction = string;
+        for (int i = 1; i < breakCount; i++) {
+          int offset = breakOffsets[i];
+          string = addedText.substring(previousOffset, offset);
+          reconstruction += string;
+          sourceEdits.add(new SourceEdit(srcStart + previousOffset, 0, string));
+          previousOffset = offset;
+        }
+        string = addedText.substring(previousOffset);
+        reconstruction += string;
+        sourceEdits.add(new SourceEdit(srcStart + previousOffset, 0, string));
+        if (reconstruction != addedText) {
+          throw new AssertionError();
+        }
+      }
+      fileEdit.addSourceEdits(sourceEdits);
+    }
+  }
+
+  /**
+   * Return the absolute paths of all of the pubspec files in all of the
+   * analysis roots.
+   */
+  Iterable<String> _findPubspecsInAnalysisRoots() {
+    List<String> pubspecFiles = <String>[];
+    for (String directoryPath in analysisRoots) {
+      Directory directory = new Directory(directoryPath);
+      List<FileSystemEntity> children =
+          directory.listSync(recursive: true, followLinks: false);
+      for (FileSystemEntity child in children) {
+        String filePath = child.path;
+        if (path.basename(filePath) == PUBSPEC_FILE_NAME) {
+          pubspecFiles.add(filePath);
+        }
+      }
+    }
+    return pubspecFiles;
+  }
+
+  /**
+   * Return a list of offsets into the given [text] that represent good places
+   * to break the text when building edits.
+   */
+  List<int> _getBreakOffsets(String text) {
+    List<int> breakOffsets = <int>[];
+    Scanner scanner = new Scanner(null, new CharSequenceReader(text),
+        error.AnalysisErrorListener.NULL_LISTENER);
+    Token token = scanner.tokenize();
+    // TODO(brianwilkerson) Randomize. Sometimes add zero (0) as a break point.
+    while (token.type != TokenType.EOF) {
+      // TODO(brianwilkerson) Break inside comments?
+//      Token comment = token.precedingComments;
+      int offset = token.offset;
+      int length = token.length;
+      breakOffsets.add(offset);
+      if (token.type == TokenType.IDENTIFIER && length > 3) {
+        breakOffsets.add(offset + (length ~/ 2));
+      }
+      token = token.next;
+    }
+    return breakOffsets;
+  }
+
+  /**
+   * Join the given [lines] into a single string.
+   */
+  String _join(List<String> lines) {
+    StringBuffer buffer = new StringBuffer();
+    for (int i = 0; i < lines.length; i++) {
+      buffer.writeln(lines[i]);
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * Process the command-line [arguments]. Return `true` if the simulation
+   * should be run.
+   */
+  bool _processCommandLine(List<String> args) {
+    ArgParser parser = _createArgParser();
+    ArgResults results;
+    try {
+      results = parser.parse(args);
+    } catch (exception) {
+      _showUsage(parser);
+      return false;
+    }
+
+    if (results[HELP_FLAG_NAME]) {
+      _showUsage(parser);
+      return false;
+    }
+
+    String overlayStyleValue = results[OVERLAY_STYLE_OPTION_NAME];
+    if (overlayStyleValue == CHANGE_OVERLAY_STYLE) {
+      overlayStyle = OverlayStyle.change;
+    } else if (overlayStyleValue == MULTIPLE_ADD_OVERLAY_STYLE) {
+      overlayStyle = OverlayStyle.multipleAdd;
+    }
+
+    List<String> arguments = results.arguments;
+    if (arguments.length < 2) {
+      _showUsage(parser);
+      return false;
+    }
+    repositoryPath = path.normalize(arguments[0]);
+    repository = new GitRepository(repositoryPath);
+
+    analysisRoots = arguments
+        .sublist(1)
+        .map((String analysisRoot) => path.normalize(analysisRoot))
+        .toList();
+    for (String analysisRoot in analysisRoots) {
+      if (repositoryPath != analysisRoot &&
+          !path.isWithin(repositoryPath, analysisRoot)) {
+        _showUsage(parser,
+            'Analysis roots must be contained within the repository: $analysisRoot');
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Replay the changes in each commit.
+   */
+  Future _replayChanges() async {
+    //
+    // Get the revision history of the repo.
+    //
+    LinearCommitHistory history = repository.getCommitHistory();
+    statistics.commitCount = history.commitIds.length;
+    LinearCommitHistoryIterator iterator = history.iterator();
+    //
+    // Iterate over the history, applying changes.
+    //
+    bool firstCheckout = true;
+    ErrorMap expectedErrors = null;
+    Iterable<String> changedPubspecs;
+    while (iterator.moveNext()) {
+      //
+      // Checkout the commit on which the changes are based.
+      //
+      String commit = iterator.srcCommit;
+      repository.checkout(commit);
+      if (expectedErrors != null) {
+        ErrorMap actualErrors =
+            await server.computeErrorMap(server.analyzedDartFiles);
+        String difference = expectedErrors.expectErrorMap(actualErrors);
+        if (difference != null) {
+          stdout.write('Mismatched errors after commit ');
+          stdout.writeln(commit);
+          stdout.writeln();
+          stdout.writeln(difference);
+          return;
+        }
+      }
+      if (firstCheckout) {
+        changedPubspecs = _findPubspecsInAnalysisRoots();
+        server.sendAnalysisSetAnalysisRoots(analysisRoots, []);
+        firstCheckout = false;
+      } else {
+        server.removeAllOverlays();
+      }
+      expectedErrors = await server.computeErrorMap(server.analyzedDartFiles);
+      for (String filePath in changedPubspecs) {
+        _runPub(filePath);
+      }
+      //
+      // Apply the changes.
+      //
+      CommitDelta commitDelta = iterator.next();
+      commitDelta.filterDiffs(analysisRoots, fileGlobs);
+      if (commitDelta.hasDiffs) {
+        statistics.commitsWithChangeInRootCount++;
+        _replayDiff(commitDelta);
+      }
+      changedPubspecs = commitDelta.filesMatching(PUBSPEC_FILE_NAME);
+      stdout.write('.');
+    }
+    server.removeAllOverlays();
+    stdout.writeln();
+  }
+
+  /**
+   * Replay the changes between two commits, as represented by the given
+   * [commitDelta].
+   */
+  void _replayDiff(CommitDelta commitDelta) {
+    List<FileEdit> editList = <FileEdit>[];
+    for (DiffRecord record in commitDelta.diffRecords) {
+      FileEdit edit = new FileEdit(overlayStyle, record);
+      _createSourceEdits(edit, record.getBlobDiff());
+      editList.add(edit);
+    }
+    //
+    // TODO(brianwilkerson) Randomize.
+    // Randomly select operations from different files to simulate a user
+    // editing multiple files simultaneously.
+    //
+    for (FileEdit edit in editList) {
+      List<String> currentFile = <String>[edit.filePath];
+      server.sendAnalysisSetPriorityFiles(currentFile);
+      server.sendAnalysisSetSubscriptions({
+        AnalysisService.FOLDING: currentFile,
+        AnalysisService.HIGHLIGHTS: currentFile,
+        AnalysisService.IMPLEMENTED: currentFile,
+        AnalysisService.NAVIGATION: currentFile,
+        AnalysisService.OCCURRENCES: currentFile,
+        AnalysisService.OUTLINE: currentFile,
+        AnalysisService.OVERRIDES: currentFile
+      });
+      for (ServerOperation operation in edit.getOperations()) {
+        operation.perform(server);
+      }
+    }
+  }
+
+  /**
+   * Run `pub` on the pubspec with the given [filePath].
+   */
+  void _runPub(String filePath) {
+    String directoryPath = path.dirname(filePath);
+    if (new Directory(directoryPath).existsSync()) {
+      Process.runSync(
+          '/Users/brianwilkerson/Dev/dart/dart-sdk/bin/pub', ['get'],
+          workingDirectory: directoryPath);
+    }
+  }
+
+  /**
+   * Run the simulation by starting up a server and sending it requests.
+   */
+  Future _runSimulation() async {
+    Stopwatch stopwatch = new Stopwatch();
+    statistics.stopwatch = stopwatch;
+    stopwatch.start();
+    await server.start();
+    server.sendServerSetSubscriptions([ServerService.STATUS]);
+    server.sendAnalysisSetGeneralSubscriptions(
+        [GeneralAnalysisService.ANALYZED_FILES]);
+    // TODO(brianwilkerson) Get the list of glob patterns from the server after
+    // an API for getting them has been implemented.
+    fileGlobs = <Glob>[
+      new Glob(path.context.separator, '**.dart'),
+      new Glob(path.context.separator, '**.html'),
+      new Glob(path.context.separator, '**.htm'),
+      new Glob(path.context.separator, '**/.analysisOptions')
+    ];
+    try {
+      await _replayChanges();
+    } finally {
+      server.sendServerShutdown();
+      repository.checkout('master');
+    }
+    stopwatch.stop();
+  }
+
+  /**
+   * Display usage information, preceeded by the [errorMessage] if one is given.
+   */
+  void _showUsage(ArgParser parser, [String errorMessage = null]) {
+    if (errorMessage != null) {
+      stderr.writeln(errorMessage);
+      stderr.writeln();
+    }
+    stderr.writeln('''
+Usage: replay [options...] repositoryPath analysisRoot...
+
+Uses the commit history of the git repository at the given repository path to
+simulate the development of a code base while using the analysis server to
+analyze the code base.
+
+The repository path must be the absolute path of a directory containing a git
+repository.
+
+There must be at least one analysis root, and all of the analysis roots must be
+the absolute path of a directory contained within the repository directory. The
+analysis roots represent the portion of the repository that will be analyzed by
+the analysis server.
+
+OPTIONS:''');
+    stderr.writeln(parser.usage);
+  }
+}
+
+/**
+ * A representation of the edits to be applied to a single file.
+ */
+class FileEdit {
+  /**
+   * The style of interaction to use for analysis.updateContent requests.
+   */
+  OverlayStyle overlayStyle;
+
+  /**
+   * The absolute path of the file to be edited.
+   */
+  String filePath;
+
+  /**
+   * The content of the file before any edits have been applied.
+   */
+  String content;
+
+  /**
+   * The line info for the file before any edits have been applied.
+   */
+  LineInfo lineInfo;
+
+  /**
+   * The lists of source edits, one list for each hunk being edited.
+   */
+  List<List<SourceEdit>> editLists = <List<SourceEdit>>[];
+
+  /**
+   * The current content of the file. This field is only used if the overlay
+   * style is [OverlayStyle.multipleAdd].
+   */
+  String currentContent;
+
+  /**
+   * Initialize a collection of edits to be associated with the file at the
+   * given [filePath].
+   */
+  FileEdit(this.overlayStyle, DiffRecord record) {
+    filePath = record.srcPath;
+    if (record.isAddition) {
+      content = '';
+      lineInfo = new LineInfo(<int>[0]);
+    } else if (record.isCopy || record.isRename || record.isTypeChange) {
+      throw new ArgumentError('Unhandled change of type ${record.status}');
+    } else {
+      content = new File(filePath).readAsStringSync();
+      lineInfo = new LineInfo(StringUtilities.computeLineStarts(content));
+    }
+    currentContent = content;
+  }
+
+  /**
+   * Add a list of source edits that, taken together, transform a single hunk in
+   * the file.
+   */
+  void addSourceEdits(List<SourceEdit> sourceEdits) {
+    editLists.add(sourceEdits);
+  }
+
+  /**
+   * Return a list of operations to be sent to the server.
+   */
+  List<ServerOperation> getOperations() {
+    List<ServerOperation> operations = <ServerOperation>[];
+    void addUpdateContent(var overlay) {
+      operations.add(new Analysis_UpdateContent(filePath, overlay));
+    }
+
+    // TODO(brianwilkerson) Randomize.
+    // Make the order of edits random. Doing so will require updating the
+    // offsets of edits after the selected edit point.
+    addUpdateContent(new AddContentOverlay(content));
+    for (List<SourceEdit> editList in editLists.reversed) {
+      for (SourceEdit edit in editList.reversed) {
+        var overlay = null;
+        if (overlayStyle == OverlayStyle.change) {
+          overlay = new ChangeContentOverlay([edit]);
+        } else if (overlayStyle == OverlayStyle.multipleAdd) {
+          currentContent = edit.apply(currentContent);
+          overlay = new AddContentOverlay(currentContent);
+        } else {
+          throw new StateError(
+              'Failed to handle overlay style = $overlayStyle');
+        }
+        if (overlay != null) {
+          addUpdateContent(overlay);
+        }
+      }
+    }
+    addUpdateContent(new RemoveContentOverlay());
+    return operations;
+  }
+}
+
+/**
+ * The possible styles of interaction to use for analysis.updateContent requests.
+ */
+enum OverlayStyle { change, multipleAdd }
+
+/**
+ * A set of statistics related to the execution of the simulation.
+ */
+class Statistics {
+  /**
+   * The driver driving the simulation.
+   */
+  final Driver driver;
+
+  /**
+   * The stopwatch being used to time the simulation.
+   */
+  Stopwatch stopwatch;
+
+  /**
+   * The total number of commits in the repository.
+   */
+  int commitCount;
+
+  /**
+   * The number of commits in the repository that touched one of the files in
+   * one of the analysis roots.
+   */
+  int commitsWithChangeInRootCount = 0;
+
+  /**
+   * Initialize a newly created set of statistics.
+   */
+  Statistics(this.driver);
+
+  /**
+   * Print the statistics to [stdout].
+   */
+  void print() {
+    stdout.write('Replay commits in ');
+    stdout.writeln(driver.repositoryPath);
+    stdout.write('  replay took ');
+    stdout.writeln(_printTime(stopwatch.elapsedMilliseconds));
+    stdout.write('  analysis roots = ');
+    stdout.writeln(driver.analysisRoots);
+    stdout.write('  number of commits = ');
+    stdout.writeln(commitCount);
+    stdout.write('  number of commits with a change in an analysis root = ');
+    stdout.writeln(commitsWithChangeInRootCount);
+  }
+
+  /**
+   * Return a textual representation of the given duration, represented in
+   * [milliseconds].
+   */
+  String _printTime(int milliseconds) {
+    int seconds = milliseconds ~/ 1000;
+    milliseconds -= seconds * 1000;
+    int minutes = seconds ~/ 60;
+    seconds -= minutes * 60;
+    int hours = minutes ~/ 60;
+    minutes -= hours * 60;
+
+    if (hours > 0) {
+      return '$hours:$minutes:$seconds.$milliseconds';
+    } else if (minutes > 0) {
+      return '$minutes:$seconds.$milliseconds m';
+    } else if (seconds > 0) {
+      return '$seconds.$milliseconds s';
+    }
+    return '$milliseconds ms';
+  }
+}
diff --git a/pkg/analysis_server/test/stress/utilities/git.dart b/pkg/analysis_server/test/stress/utilities/git.dart
new file mode 100644
index 0000000..30e45f7
--- /dev/null
+++ b/pkg/analysis_server/test/stress/utilities/git.dart
@@ -0,0 +1,542 @@
+// 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 interacting with a git repository.
+ */
+library analysis_server.test.stress.utilities.git;
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:analyzer/src/util/glob.dart';
+import 'package:path/path.dart' as path;
+
+/**
+ * A representation of the differences between two blobs.
+ */
+class BlobDiff {
+  /**
+   * The regular expression used to identify the beginning of a hunk.
+   */
+  static final RegExp hunkHeaderRegExp =
+      new RegExp(r'@@ -([0-9]+)(?:,[0-9]+)? \+([0-9]+)(?:,[0-9]+)? @@');
+
+  /**
+   * A list of the hunks in the diff.
+   */
+  List<DiffHunk> hunks = <DiffHunk>[];
+
+  /**
+   * Initialize a newly created blob diff by parsing the result of the git diff
+   * command (the [input]).
+   *
+   * This is only intended to be invoked from [GitRepository.getBlobDiff].
+   */
+  BlobDiff._(List<String> input) {
+    _parseInput(input);
+  }
+
+  /**
+   * Parse the result of the git diff command (the [input]).
+   */
+  void _parseInput(List<String> input) {
+    for (String line in input) {
+      _parseLine(line);
+    }
+  }
+
+  /**
+   * Parse a single [line] from the result of the git diff command.
+   */
+  void _parseLine(String line) {
+    DiffHunk currentHunk = hunks.isEmpty ? null : hunks.last;
+    if (line.startsWith('@@')) {
+      Match match = hunkHeaderRegExp.matchAsPrefix(line);
+      int srcLine = int.parse(match.group(1));
+      int dstLine = int.parse(match.group(2));
+      hunks.add(new DiffHunk(srcLine, dstLine));
+    } else if (currentHunk != null && line.startsWith('+')) {
+      currentHunk.addLines.add(line.substring(1));
+    } else if (currentHunk != null && line.startsWith('-')) {
+      currentHunk.removeLines.add(line.substring(1));
+    }
+  }
+}
+
+/**
+ * A representation of the differences between two commits.
+ */
+class CommitDelta {
+  /**
+   * The length (in characters) of a SHA.
+   */
+  static final int SHA_LENGTH = 40;
+
+  /**
+   * The code-point for a colon (':').
+   */
+  static final int COLON = ':'.codeUnitAt(0);
+
+  /**
+   * The code-point for a nul character.
+   */
+  static final int NUL = 0;
+
+  /**
+   * The code-point for a tab.
+   */
+  static final int TAB = '\t'.codeUnitAt(0);
+
+  /**
+   * The repository from which the commits were taken.
+   */
+  final GitRepository repository;
+
+  /**
+   * The records of the files that were changed.
+   */
+  final List<DiffRecord> diffRecords = <DiffRecord>[];
+
+  /**
+   * Initialize a newly created representation of the differences between two
+   * commits. The differences are computed by parsing the result of a git diff
+   * command (the [diffResults]).
+   *
+   * This is only intended to be invoked from [GitRepository.getBlobDiff].
+   */
+  CommitDelta._(this.repository, String diffResults) {
+    _parseInput(diffResults);
+  }
+
+  /**
+   * Return `true` if there are differences.
+   */
+  bool get hasDiffs => diffRecords.isNotEmpty;
+
+  /**
+   * Return the absolute paths of all of the files in this commit whose name
+   * matches the given [fileName].
+   */
+  Iterable<String> filesMatching(String fileName) {
+    return diffRecords
+        .where((DiffRecord record) => record.isFor(fileName))
+        .map((DiffRecord record) => record.srcPath);
+  }
+
+  /**
+   * Remove any diffs for files that are either (a) outside the given
+   * [inclusionPaths], or (b) are files that do not match one of the given
+   * [globPatterns].
+   */
+  void filterDiffs(List<String> inclusionPaths, List<Glob> globPatterns) {
+    diffRecords.retainWhere((DiffRecord record) {
+      String filePath = record.srcPath ?? record.dstPath;
+      for (String inclusionPath in inclusionPaths) {
+        if (path.isWithin(inclusionPath, filePath)) {
+          for (Glob glob in globPatterns) {
+            if (glob.matches(filePath)) {
+              return true;
+            }
+          }
+        }
+      }
+      return false;
+    });
+  }
+
+  /**
+   * Return the index of the first nul character in the given [string] that is
+   * at or after the given [start] index.
+   */
+  int _findEnd(String string, int start) {
+    int length = string.length;
+    int end = start;
+    while (end < length && string.codeUnitAt(end) != NUL) {
+      end++;
+    }
+    return end;
+  }
+
+  /**
+   * Return the result of converting the given [relativePath] to an absolute
+   * path. The path is assumed to be relative to the root of the repository.
+   */
+  String _makeAbsolute(String relativePath) {
+    return path.join(repository.path, relativePath);
+  }
+
+  /**
+   * Parse all of the diff records in the given [input].
+   */
+  void _parseInput(String input) {
+    int length = input.length;
+    int start = 0;
+    while (start < length) {
+      start = _parseRecord(input, start);
+    }
+  }
+
+  /**
+   * Parse a single record from the given [input], assuming that the record
+   * starts at the given [startIndex].
+   *
+   * Each record is formatted as a sequence of fields. The fields are, from the
+   * left to the right:
+   *
+   * 1. a colon.
+   * 2. mode for "src"; 000000 if creation or unmerged.
+   * 3. a space.
+   * 4. mode for "dst"; 000000 if deletion or unmerged.
+   * 5. a space.
+   * 6. sha1 for "src"; 0{40} if creation or unmerged.
+   * 7. a space.
+   * 8. sha1 for "dst"; 0{40} if creation, unmerged or "look at work tree".
+   * 9. a space.
+   * 10. status, followed by optional "score" number.
+   * 11. a tab or a NUL when -z option is used.
+   * 12. path for "src"
+   * 13. a tab or a NUL when -z option is used; only exists for C or R.
+   * 14. path for "dst"; only exists for C or R.
+   * 15. an LF or a NUL when -z option is used, to terminate the record.
+   */
+  int _parseRecord(String input, int startIndex) {
+    // Skip the first five fields.
+    startIndex += 15;
+    // Parse field 6
+    String srcSha = input.substring(startIndex, startIndex + SHA_LENGTH);
+    startIndex += SHA_LENGTH + 1;
+    // Parse field 8
+    String dstSha = input.substring(startIndex, startIndex + SHA_LENGTH);
+    startIndex += SHA_LENGTH + 1;
+    // Parse field 10
+    int endIndex = _findEnd(input, startIndex);
+    String status = input.substring(startIndex, endIndex);
+    startIndex = endIndex + 1;
+    // Parse field 12
+    endIndex = _findEnd(input, startIndex);
+    String srcPath = _makeAbsolute(input.substring(startIndex, endIndex));
+    startIndex = endIndex + 1;
+    // Parse field 14
+    String dstPath = null;
+    if (status.startsWith('C') || status.startsWith('R')) {
+      endIndex = _findEnd(input, startIndex);
+      dstPath = _makeAbsolute(input.substring(startIndex, endIndex));
+    }
+    // Create the record.
+    diffRecords.add(
+        new DiffRecord(repository, srcSha, dstSha, status, srcPath, dstPath));
+    return endIndex + 1;
+  }
+}
+
+/**
+ * Representation of a single diff hunk.
+ */
+class DiffHunk {
+  /**
+   * The index of the first line that was changed in the src as returned by the
+   * diff command. The diff command numbers lines starting at 1, but it
+   * subtracts 1 from the line number if there are no lines on the source side
+   * of the hunk.
+   */
+  int diffSrcLine;
+
+  /**
+   * The index of the first line that was changed in the dst as returned by the
+   * diff command. The diff command numbers lines starting at 1, but it
+   * subtracts 1 from the line number if there are no lines on the destination
+   * side of the hunk.
+   */
+  int diffDstLine;
+
+  /**
+   * A list of the individual lines that were removed from the src.
+   */
+  List<String> removeLines = <String>[];
+
+  /**
+   * A list of the individual lines that were added to the dst.
+   */
+  List<String> addLines = <String>[];
+
+  /**
+   * Initialize a newly created hunk. The lines will be added after the object
+   * has been created.
+   */
+  DiffHunk(this.diffSrcLine, this.diffDstLine);
+
+  /**
+   * Return the index of the first line that was changed in the dst. Unlike the
+   * [diffDstLine] field, this getter adjusts the line number to be consistent
+   * whether or not there were any changed lines.
+   */
+  int get dstLine {
+    return addLines.isEmpty ? diffDstLine : diffDstLine - 1;
+  }
+
+  /**
+   * Return the index of the first line that was changed in the src. Unlike the
+   * [diffDstLine] field, this getter adjusts the line number to be consistent
+   * whether or not there were any changed lines.
+   */
+  int get srcLine {
+    return removeLines.isEmpty ? diffSrcLine : diffSrcLine - 1;
+  }
+}
+
+/**
+ * A representation of a single line (record) from a raw diff.
+ */
+class DiffRecord {
+  /**
+   * The repository containing the file(s) that were modified.
+   */
+  final GitRepository repository;
+
+  /**
+   * The SHA1 of the blob in the src.
+   */
+  final String srcBlob;
+
+  /**
+   * The SHA1 of the blob in the dst.
+   */
+  final String dstBlob;
+
+  /**
+   * The status of the change. Valid values are:
+   * * A: addition of a file
+   * * C: copy of a file into a new one
+   * * D: deletion of a file
+   * * M: modification of the contents or mode of a file
+   * * R: renaming of a file
+   * * T: change in the type of the file
+   * * U: file is unmerged (you must complete the merge before it can be committed)
+   * * X: "unknown" change type (most probably a bug, please report it)
+   *
+   * Status letters C and R are always followed by a score (denoting the
+   * percentage of similarity between the source and target of the move or
+   * copy), and are the only ones to be so.
+   */
+  final String status;
+
+  /**
+   * The path of the src.
+   */
+  final String srcPath;
+
+  /**
+   * The path of the dst if this was either a copy or a rename operation.
+   */
+  final String dstPath;
+
+  /**
+   * Initialize a newly created diff record.
+   */
+  DiffRecord(this.repository, this.srcBlob, this.dstBlob, this.status,
+      this.srcPath, this.dstPath);
+
+  /**
+   * Return `true` if this record represents a file that was added.
+   */
+  bool get isAddition => status == 'A';
+
+  /**
+   * Return `true` if this record represents a file that was copied.
+   */
+  bool get isCopy => status.startsWith('C');
+
+  /**
+   * Return `true` if this record represents a file that was deleted.
+   */
+  bool get isDeletion => status == 'D';
+
+  /**
+   * Return `true` if this record represents a file that was modified.
+   */
+  bool get isModification => status == 'M';
+
+  /**
+   * Return `true` if this record represents a file that was renamed.
+   */
+  bool get isRename => status.startsWith('R');
+
+  /**
+   * Return `true` if this record represents an entity whose type was changed
+   * (for example, from a file to a directory).
+   */
+  bool get isTypeChange => status == 'T';
+
+  /**
+   * Return a representation of the individual blobs within this diff.
+   */
+  BlobDiff getBlobDiff() => repository.getBlobDiff(srcBlob, dstBlob);
+
+  /**
+   * Return `true` if this diff applies to a file with the given name.
+   */
+  bool isFor(String fileName) =>
+      (srcPath != null && fileName == path.basename(srcPath)) ||
+          (dstPath != null && fileName == path.basename(dstPath));
+
+  @override
+  String toString() => srcPath ?? dstPath;
+}
+
+/**
+ * A representation of a git repository.
+ */
+class GitRepository {
+  /**
+   * The absolute path of the directory containing the repository.
+   */
+  final String path;
+
+  /**
+   * Initialize a newly created repository to represent the git repository at
+   * the given [path].
+   */
+  GitRepository(this.path);
+
+  /**
+   * Checkout the given [commit] from the repository. This is done by running
+   * the command `git checkout <sha>`.
+   */
+  void checkout(String commit) {
+    _run(['checkout', commit]);
+  }
+
+  /**
+   * Return details about the differences between the two blobs identified by
+   * the SHA1 of the [srcBlob] and the SHA1 of the [dstBlob]. This is done by
+   * running the command `git diff <blob> <blob>`.
+   */
+  BlobDiff getBlobDiff(String srcBlob, String dstBlob) {
+    ProcessResult result = _run(['diff', '-U0', srcBlob, dstBlob]);
+    List<String> diffResults = LineSplitter.split(result.stdout).toList();
+    return new BlobDiff._(diffResults);
+  }
+
+  /**
+   * Return details about the differences between the two commits identified by
+   * the [srcCommit] and [dstCommit]. This is done by running the command
+   * `git diff --raw --no-abbrev --no-renames -z <sha> <sha>`.
+   */
+  CommitDelta getCommitDiff(String srcCommit, String dstCommit) {
+    // Consider --find-renames instead of --no-renames if rename information is
+    // desired.
+    ProcessResult result = _run([
+      'diff',
+      '--raw',
+      '--no-abbrev',
+      '--no-renames',
+      '-z',
+      srcCommit,
+      dstCommit
+    ]);
+    return new CommitDelta._(this, result.stdout);
+  }
+
+  /**
+   * Return a representation of the history of this repository. This is done by
+   * running the command `git rev-list --first-parent HEAD`.
+   */
+  LinearCommitHistory getCommitHistory() {
+    ProcessResult result = _run(['rev-list', '--first-parent', 'HEAD']);
+    List<String> commitIds = LineSplitter.split(result.stdout).toList();
+    return new LinearCommitHistory(this, commitIds);
+  }
+
+  /**
+   * Synchronously run the given [executable] with the given [arguments]. Return
+   * the result of running the process.
+   */
+  ProcessResult _run(List<String> arguments) {
+    return Process.runSync('git', arguments,
+        stderrEncoding: UTF8, stdoutEncoding: UTF8, workingDirectory: path);
+  }
+}
+
+/**
+ * A representation of the history of a Git repository. This only represents a
+ * single linear path in the history graph.
+ */
+class LinearCommitHistory {
+  /**
+   * The repository whose history is being represented.
+   */
+  final GitRepository repository;
+
+  /**
+   * The id's (SHA's) of the commits in the repository, with the most recent
+   * commit being first and the oldest commit being last.
+   */
+  final List<String> commitIds;
+
+  /**
+   * Initialize a commit history for the given [repository] to have the given
+   * [commitIds].
+   */
+  LinearCommitHistory(this.repository, this.commitIds);
+
+  /**
+   * Return an iterator that can be used to iterate over this commit history.
+   */
+  LinearCommitHistoryIterator iterator() {
+    return new LinearCommitHistoryIterator(this);
+  }
+}
+
+/**
+ * An iterator over the history of a Git repository.
+ */
+class LinearCommitHistoryIterator {
+  /**
+   * The commit history being iterated over.
+   */
+  final LinearCommitHistory history;
+
+  /**
+   * The index of the current commit in the list of [commitIds].
+   */
+  int currentCommit;
+
+  /**
+   * Initialize a newly created iterator to iterate over the commits with the
+   * given [commitIds];
+   */
+  LinearCommitHistoryIterator(this.history) {
+    currentCommit = history.commitIds.length;
+  }
+
+  /**
+   * Return the SHA1 of the commit after the current commit (the 'dst' of the
+   * [next] diff).
+   */
+  String get dstCommit => history.commitIds[currentCommit - 1];
+
+  /**
+   * Return the SHA1 of the current commit (the 'src' of the [next] diff).
+   */
+  String get srcCommit => history.commitIds[currentCommit];
+
+  /**
+   * Advance to the next commit in the history. Return `true` if it is safe to
+   * ask for the [next] diff.
+   */
+  bool moveNext() {
+    if (currentCommit <= 1) {
+      return false;
+    }
+    currentCommit--;
+    return true;
+  }
+
+  /**
+   * Return the difference between the current commit and the commit that
+   * followed it.
+   */
+  CommitDelta next() => history.repository.getCommitDiff(srcCommit, dstCommit);
+}
diff --git a/pkg/analysis_server/test/stress/utilities/server.dart b/pkg/analysis_server/test/stress/utilities/server.dart
new file mode 100644
index 0000000..ee52fdd
--- /dev/null
+++ b/pkg/analysis_server/test/stress/utilities/server.dart
@@ -0,0 +1,289 @@
+// 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 interacting with an analysis server running in a separate
+ * process.
+ */
+library analysis_server.test.stress.utilities.server;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+
+import '../../integration/integration_test_methods.dart';
+import '../../integration/integration_tests.dart' as base;
+
+/**
+ * ???
+ */
+class ErrorMap {
+  /**
+   * A table mapping file paths to the errors associated with that file.
+   */
+  final Map<String, List<AnalysisError>> pathMap =
+      new HashMap<String, List<AnalysisError>>();
+
+  /**
+   * Initialize a newly created error map.
+   */
+  ErrorMap();
+
+  /**
+   * Initialize a newly created error map to contain the same mapping as the
+   * given [errorMap].
+   */
+  ErrorMap.from(ErrorMap errorMap) {
+    pathMap.addAll(errorMap.pathMap);
+  }
+
+  void operator []=(String filePath, List<AnalysisError> errors) {
+    pathMap[filePath] = errors;
+  }
+
+  /**
+   * Compare the this error map with the state captured in the given [errorMap].
+   * Throw an exception if the two maps do not agree.
+   */
+  String expectErrorMap(ErrorMap errorMap) {
+    StringBuffer buffer = new StringBuffer();
+    _ErrorComparator comparator = new _ErrorComparator(buffer);
+    comparator.compare(pathMap, errorMap.pathMap);
+    if (buffer.length > 0) {
+      return buffer.toString();
+    }
+    return null;
+  }
+}
+
+/**
+ * An interface for starting and communicating with an analysis server running
+ * in a separate process.
+ */
+class Server extends base.Server with IntegrationTestMixin {
+  /**
+   * A list containing the paths of files for which an overlay has been created.
+   */
+  List<String> filesWithOverlays = <String>[];
+
+  /**
+   * A mapping from the absolute paths of files to the most recent set of errors
+   * received for that file.
+   */
+  ErrorMap _errorMap = new ErrorMap();
+
+  /**
+   * Initialize a new analysis server. The analysis server is not running and
+   * must be started using [start].
+   */
+  Server() {
+    initializeInttestMixin();
+    onAnalysisErrors.listen(_recordErrors);
+  }
+
+  /**
+   * Return a list of the paths of files that are currently being analyzed.
+   */
+  List<String> get analyzedDartFiles {
+    // TODO(brianwilkerson) Implement this.
+    return <String>[];
+  }
+
+  /**
+   * Return a table mapping the absolute paths of files to the most recent set
+   * of errors received for that file. The content of the map will not change
+   * when new sets of errors are received.
+   */
+  ErrorMap get errorMap => new ErrorMap.from(_errorMap);
+
+  @override
+  base.Server get server => this;
+
+  /**
+   * Compute a mapping from each of the file paths in the given list of
+   * [filePaths] to the list of errors in the file at that path.
+   */
+  Future<ErrorMap> computeErrorMap(List<String> filePaths) async {
+    ErrorMap errorMap = new ErrorMap();
+    List<Future> futures = <Future>[];
+    for (String filePath in filePaths) {
+      futures.add(sendAnalysisGetErrors(filePath)
+          .then((AnalysisGetErrorsResult result) {
+        errorMap[filePath] = result.errors;
+      }));
+    }
+    await Future.wait(futures);
+    return errorMap;
+  }
+
+  /**
+   * Remove any existing overlays.
+   */
+  Future<AnalysisUpdateContentResult> removeAllOverlays() {
+    Map<String, dynamic> files = new HashMap<String, dynamic>();
+    for (String path in filesWithOverlays) {
+      files[path] = new RemoveContentOverlay();
+    }
+    return sendAnalysisUpdateContent(files);
+  }
+
+  @override
+  Future<AnalysisUpdateContentResult> sendAnalysisUpdateContent(
+      Map<String, dynamic> files) {
+    files.forEach((String path, dynamic overlay) {
+      if (overlay is AddContentOverlay) {
+        filesWithOverlays.add(path);
+      } else if (overlay is RemoveContentOverlay) {
+        filesWithOverlays.remove(path);
+      }
+    });
+    return super.sendAnalysisUpdateContent(files);
+  }
+
+  /**
+   * Record the errors in the given [params].
+   */
+  void _recordErrors(AnalysisErrorsParams params) {
+    _errorMap[params.file] = params.errors;
+  }
+}
+
+/**
+ * A utility class used to compare two sets of errors.
+ */
+class _ErrorComparator {
+  /**
+   * An empty list of analysis errors.
+   */
+  static final List<AnalysisError> NO_ERRORS = <AnalysisError>[];
+
+  /**
+   * The buffer to which an error description will be written if any of the
+   * files have different errors than are expected.
+   */
+  final StringBuffer buffer;
+
+  /**
+   * Initialize a newly created comparator to write to the given [buffer].
+   */
+  _ErrorComparator(this.buffer);
+
+  /**
+   * Compare the [actualErrorMap] and the [expectedErrorMap], writing a
+   * description to the [buffer] if they are not the same. The error maps are
+   * expected to be maps from absolute file paths to the list of actual or
+   * expected errors.
+   */
+  void compare(Map<String, List<AnalysisError>> actualErrorMap,
+      Map<String, List<AnalysisError>> expectedErrorMap) {
+    Set<String> allFiles = new HashSet();
+    allFiles.addAll(actualErrorMap.keys);
+    allFiles.addAll(expectedErrorMap.keys);
+    List<String> sortedFiles = allFiles.toList()..sort();
+    for (String filePath in sortedFiles) {
+      List<AnalysisError> actualErrors = actualErrorMap[filePath];
+      List<AnalysisError> expectedErrors = expectedErrorMap[filePath];
+      _compareLists(
+          filePath, actualErrors ?? NO_ERRORS, expectedErrors ?? NO_ERRORS);
+    }
+  }
+
+  /**
+   * Compare the [actualErrors] and [expectedErrors], writing a description to
+   * the [buffer] if they are not the same.
+   */
+  void _compareLists(String filePath, List<AnalysisError> actualErrors,
+      List<AnalysisError> expectedErrors) {
+    List<AnalysisError> remainingExpected =
+        new List<AnalysisError>.from(expectedErrors);
+    for (AnalysisError actualError in actualErrors) {
+      AnalysisError expectedError = _findError(remainingExpected, actualError);
+      if (expectedError == null) {
+        _writeReport(filePath, actualErrors, expectedErrors);
+        return;
+      }
+      remainingExpected.remove(expectedError);
+    }
+    if (remainingExpected.isNotEmpty) {
+      _writeReport(filePath, actualErrors, expectedErrors);
+    }
+  }
+
+  /**
+   * Return `true` if the [firstError] and the [secondError] are equivalent.
+   */
+  bool _equalErrors(AnalysisError firstError, AnalysisError secondError) =>
+      firstError.severity == secondError.severity &&
+      firstError.type == secondError.type &&
+      _equalLocations(firstError.location, secondError.location) &&
+      firstError.message == secondError.message;
+
+  /**
+   * Return `true` if the [firstLocation] and the [secondLocation] are
+   * equivalent.
+   */
+  bool _equalLocations(Location firstLocation, Location secondLocation) =>
+      firstLocation.file == secondLocation.file &&
+      firstLocation.offset == secondLocation.offset &&
+      firstLocation.length == secondLocation.length;
+
+  /**
+   * Search through the given list of [errors] for an error that is equal to the
+   * [targetError]. If one is found, return it, otherwise return `null`.
+   */
+  AnalysisError _findError(
+      List<AnalysisError> errors, AnalysisError targetError) {
+    for (AnalysisError error in errors) {
+      if (_equalErrors(error, targetError)) {
+        return error;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Write the given list of [errors], preceded by a header beginning with the
+   * given [prefix].
+   */
+  void _writeErrors(String prefix, List<AnalysisError> errors) {
+    buffer.write(prefix);
+    buffer.write(errors.length);
+    buffer.write(' errors:');
+    for (AnalysisError error in errors) {
+      buffer.writeln();
+      Location location = error.location;
+      int offset = location.offset;
+      buffer.write('    ');
+      buffer.write(location.file);
+      buffer.write(' (');
+      buffer.write(offset);
+      buffer.write('..');
+      buffer.write(offset + location.length);
+      buffer.write(') ');
+      buffer.write(error.severity);
+      buffer.write(', ');
+      buffer.write(error.type);
+      buffer.write(' : ');
+      buffer.write(error.message);
+    }
+  }
+
+  /**
+   * Write a report of the differences between the [actualErrors] and the
+   * [expectedErrors]. The errors are reported as being from the file at the
+   * given [filePath].
+   */
+  void _writeReport(String filePath, List<AnalysisError> actualErrors,
+      List<AnalysisError> expectedErrors) {
+    if (buffer.length > 0) {
+      buffer.writeln();
+      buffer.writeln();
+    }
+    buffer.writeln(filePath);
+    _writeErrors('  Expected ', expectedErrors);
+    buffer.writeln();
+    _writeErrors('  Found ', expectedErrors);
+  }
+}
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index a89913d..0a4a883 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.dart
@@ -10,6 +10,7 @@
 import 'context_manager_test.dart' as context_manager_test;
 import 'domain_analysis_test.dart' as domain_analysis_test;
 import 'domain_completion_test.dart' as domain_completion_test;
+import 'domain_diagnostic_test.dart' as domain_experimental_test;
 import 'domain_execution_test.dart' as domain_execution_test;
 import 'domain_server_test.dart' as domain_server_test;
 import 'edit/test_all.dart' as edit_all;
@@ -38,6 +39,7 @@
     domain_analysis_test.main();
     domain_completion_test.main();
     domain_execution_test.main();
+    domain_experimental_test.main();
     domain_server_test.main();
     edit_all.main();
     operation_test_all.main();
diff --git a/pkg/analysis_server/tool/spec/api.dart b/pkg/analysis_server/tool/spec/api.dart
index a558f17..b5443aa 100644
--- a/pkg/analysis_server/tool/spec/api.dart
+++ b/pkg/analysis_server/tool/spec/api.dart
@@ -22,8 +22,9 @@
   final Refactorings refactorings;
 
   Api(this.version, this.domains, this.types, this.refactorings,
-      dom.Element html)
-      : super(html);
+      dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -31,11 +32,17 @@
  */
 class ApiNode {
   /**
+   * A flag to indicate if this API is experimental.
+   */
+  final bool experimental;
+
+  /**
    * Html element representing this part of the API.
    */
   final dom.Element html;
 
-  ApiNode(this.html);
+  ApiNode(this.html, bool experimental)
+      : this.experimental = experimental ?? false;
 }
 
 /**
@@ -63,8 +70,9 @@
   final List<Request> requests;
   final List<Notification> notifications;
 
-  Domain(this.name, this.requests, this.notifications, dom.Element html)
-      : super(html);
+  Domain(this.name, this.requests, this.notifications, dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -195,8 +203,9 @@
    */
   final TypeObject params;
 
-  Notification(this.domainName, this.event, this.params, dom.Element html)
-      : super(html);
+  Notification(this.domainName, this.event, this.params, dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 
   /**
    * Get the name of the notification, including the domain prefix.
@@ -240,8 +249,9 @@
    */
   final TypeObject options;
 
-  Refactoring(this.kind, this.feedback, this.options, dom.Element html)
-      : super(html);
+  Refactoring(this.kind, this.feedback, this.options, dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -250,7 +260,8 @@
 class Refactorings extends ApiNode with IterableMixin<Refactoring> {
   final List<Refactoring> refactorings;
 
-  Refactorings(this.refactorings, dom.Element html) : super(html);
+  Refactorings(this.refactorings, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   @override
   Iterator<Refactoring> get iterator => refactorings.iterator;
@@ -283,8 +294,9 @@
   final TypeObject result;
 
   Request(
-      this.domainName, this.method, this.params, this.result, dom.Element html)
-      : super(html);
+      this.domainName, this.method, this.params, this.result, dom.Element html,
+      {bool experimental})
+      : super(html, experimental);
 
   /**
    * Get the name of the request, including the domain prefix.
@@ -329,7 +341,7 @@
  * Base class for all possible types.
  */
 abstract class TypeDecl extends ApiNode {
-  TypeDecl(dom.Element html) : super(html);
+  TypeDecl(dom.Element html, bool experimental) : super(html, experimental);
 
   accept(ApiVisitor visitor);
 }
@@ -341,7 +353,8 @@
   final String name;
   final TypeDecl type;
 
-  TypeDefinition(this.name, this.type, dom.Element html) : super(html);
+  TypeDefinition(this.name, this.type, dom.Element html, {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -351,7 +364,8 @@
 class TypeEnum extends TypeDecl {
   final List<TypeEnumValue> values;
 
-  TypeEnum(this.values, dom.Element html) : super(html);
+  TypeEnum(this.values, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeEnum(this);
 }
@@ -362,7 +376,8 @@
 class TypeEnumValue extends ApiNode {
   final String value;
 
-  TypeEnumValue(this.value, dom.Element html) : super(html);
+  TypeEnumValue(this.value, dom.Element html, {bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -371,7 +386,8 @@
 class TypeList extends TypeDecl {
   final TypeDecl itemType;
 
-  TypeList(this.itemType, dom.Element html) : super(html);
+  TypeList(this.itemType, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeList(this);
 }
@@ -392,7 +408,8 @@
    */
   final TypeDecl valueType;
 
-  TypeMap(this.keyType, this.valueType, dom.Element html) : super(html);
+  TypeMap(this.keyType, this.valueType, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeMap(this);
 }
@@ -403,7 +420,8 @@
 class TypeObject extends TypeDecl {
   final List<TypeObjectField> fields;
 
-  TypeObject(this.fields, dom.Element html) : super(html);
+  TypeObject(this.fields, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeObject(this);
 
@@ -434,8 +452,8 @@
   final Object value;
 
   TypeObjectField(this.name, this.type, dom.Element html,
-      {this.optional: false, this.value})
-      : super(html);
+      {this.optional: false, this.value, bool experimental})
+      : super(html, experimental);
 }
 
 /**
@@ -445,7 +463,8 @@
 class TypeReference extends TypeDecl {
   final String typeName;
 
-  TypeReference(this.typeName, dom.Element html) : super(html) {
+  TypeReference(this.typeName, dom.Element html, {bool experimental})
+      : super(html, experimental) {
     if (typeName.isEmpty) {
       throw new Exception('Empty type name');
     }
@@ -460,7 +479,8 @@
 class Types extends ApiNode with IterableMixin<TypeDefinition> {
   final Map<String, TypeDefinition> types;
 
-  Types(this.types, dom.Element html) : super(html);
+  Types(this.types, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   @override
   Iterator<TypeDefinition> get iterator => types.values.iterator;
@@ -483,7 +503,8 @@
    */
   final String field;
 
-  TypeUnion(this.choices, this.field, dom.Element html) : super(html);
+  TypeUnion(this.choices, this.field, dom.Element html, {bool experimental})
+      : super(html, experimental);
 
   accept(ApiVisitor visitor) => visitor.visitTypeUnion(this);
 }
diff --git a/pkg/analysis_server/tool/spec/check_all_test.dart b/pkg/analysis_server/tool/spec/check_all_test.dart
index f068f42..d43b320 100644
--- a/pkg/analysis_server/tool/spec/check_all_test.dart
+++ b/pkg/analysis_server/tool/spec/check_all_test.dart
@@ -6,9 +6,9 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:path/path.dart';
 
-import 'codegen_tools.dart';
 import 'generate_all.dart';
 
 /**
@@ -17,26 +17,6 @@
  */
 main() {
   String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  Directory.current = new Directory(dirname(script));
-  bool generateAllNeeded = false;
-  for (GeneratedContent generatedContent in allTargets) {
-    if (!generatedContent.check()) {
-      print(
-          '${generatedContent.outputFile.absolute} does not have expected contents.');
-      generateAllNeeded = true;
-    }
-  }
-  if (generateAllNeeded) {
-    print('Please regenerate using:');
-    String executable = Platform.executable;
-    String packageRoot = '';
-    if (Platform.packageRoot.isNotEmpty) {
-      packageRoot = ' --package-root=${Platform.packageRoot}';
-    }
-    String generateScript = join(dirname(script), 'generate_all.dart');
-    print('  $executable$packageRoot $generateScript');
-    exit(1);
-  } else {
-    print('All generated files up to date.');
-  }
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.checkAll(pkgPath, 'tool/spec/generate_all.dart', allTargets);
 }
diff --git a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
index 8b3c897..323c39c 100644
--- a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
+++ b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
@@ -7,21 +7,15 @@
  */
 library java.generator.server;
 
+import 'package:analyzer/src/codegen/tools.dart';
+
 import 'api.dart';
 import 'codegen_java.dart';
-import 'codegen_tools.dart';
 
 final GeneratedFile target = javaGeneratedFile(
-    'generated/java/AnalysisServer.java',
+    'tool/spec/generated/java/AnalysisServer.java',
     (Api api) => new CodegenAnalysisServer(api));
 
-/**
- * Translate spec_input.html into AnalysisServer.java.
- */
-main() {
-  target.generate();
-}
-
 class CodegenAnalysisServer extends CodegenJavaVisitor {
   CodegenAnalysisServer(Api api) : super(api);
 
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index b77f4ef..fc389a4 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -6,23 +6,16 @@
 
 import 'dart:convert';
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
 import 'codegen_dart.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'implied_types.dart';
 import 'to_html.dart';
 
 /**
- * Translate spec_input.html into protocol_matchers.dart.
- */
-main() {
-  target.generate();
-}
-
-/**
  * Special flags that need to be inserted into the declaration of the Element
  * class.
  */
@@ -35,9 +28,9 @@
   'deprecated': '0x20'
 };
 
-final GeneratedFile target =
-    new GeneratedFile('../../lib/plugin/protocol/generated_protocol.dart', () {
-  CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi());
+final GeneratedFile target = new GeneratedFile(
+    'lib/plugin/protocol/generated_protocol.dart', (String pkgPath) {
+  CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi(pkgPath));
   return visitor.collectCode(visitor.visitApi);
 });
 
diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
index bdc8910..3b5fde0 100644
--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
@@ -9,27 +9,21 @@
 
 import 'dart:convert';
 
+import 'package:analyzer/src/codegen/tools.dart';
+
 import 'api.dart';
 import 'codegen_dart.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'to_html.dart';
 
 final GeneratedFile target = new GeneratedFile(
-    '../../test/integration/integration_test_methods.dart', () {
+    'test/integration/integration_test_methods.dart', (String pkgPath) {
   CodegenInttestMethodsVisitor visitor =
-      new CodegenInttestMethodsVisitor(readApi());
+      new CodegenInttestMethodsVisitor(readApi(pkgPath));
   return visitor.collectCode(visitor.visitApi);
 });
 
 /**
- * Translate spec_input.html into protocol_matchers.dart.
- */
-main() {
-  target.generate();
-}
-
-/**
  * Visitor that generates the code for integration_test_methods.dart
  */
 class CodegenInttestMethodsVisitor extends DartCodegenVisitor
@@ -108,7 +102,8 @@
     writeln("import 'dart:async';");
     writeln();
     writeln("import 'package:analysis_server/plugin/protocol/protocol.dart';");
-    writeln("import 'package:analysis_server/src/protocol/protocol_internal.dart';");
+    writeln(
+        "import 'package:analysis_server/src/protocol/protocol_internal.dart';");
     writeln("import 'package:unittest/unittest.dart';");
     writeln();
     writeln("import 'integration_tests.dart';");
diff --git a/pkg/analysis_server/tool/spec/codegen_java.dart b/pkg/analysis_server/tool/spec/codegen_java.dart
index a06af6b..3b7a4d2 100644
--- a/pkg/analysis_server/tool/spec/codegen_java.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java.dart
@@ -7,10 +7,10 @@
  */
 library CodegenJava;
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'to_html.dart';
 
@@ -20,8 +20,8 @@
  */
 GeneratedFile javaGeneratedFile(
     String path, CodegenJavaVisitor createVisitor(Api api)) {
-  return new GeneratedFile(path, () {
-    CodegenJavaVisitor visitor = createVisitor(readApi());
+  return new GeneratedFile(path, (String pkgPath) {
+    CodegenJavaVisitor visitor = createVisitor(readApi(pkgPath));
     return visitor.collectCode(visitor.visitApi);
   });
 }
diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart
index 2dec54c..b752b2e 100644
--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart
@@ -7,69 +7,14 @@
  */
 library java.generator.types;
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
 import 'codegen_java.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'implied_types.dart';
 
-final String pathToGenTypes = 'generated/java/types/';
-
-final GeneratedDirectory targetDir = new GeneratedDirectory(pathToGenTypes, () {
-  Api api = readApi();
-  Map<String, ImpliedType> impliedTypes = computeImpliedTypes(api);
-  Map<String, FileContentsComputer> map =
-      new Map<String, FileContentsComputer>();
-  for (ImpliedType impliedType in impliedTypes.values) {
-    String typeNameInSpec = capitalize(impliedType.camelName);
-    bool isRefactoringFeedback = impliedType.kind == 'refactoringFeedback';
-    bool isRefactoringOption = impliedType.kind == 'refactoringOptions';
-    if (impliedType.kind == 'typeDefinition' ||
-        isRefactoringFeedback ||
-        isRefactoringOption) {
-      TypeDecl type = impliedType.type;
-      if (type is TypeObject || type is TypeEnum) {
-        // This is for situations such as 'Override' where the name in the spec
-        // doesn't match the java object that we generate:
-        String typeNameInJava = typeNameInSpec;
-        if (_typeRenames.containsKey(typeNameInSpec)) {
-          typeNameInJava = _typeRenames[typeNameInSpec];
-        }
-        map['${typeNameInJava}.java'] = () {
-          String superclassName = null;
-          if (isRefactoringFeedback) {
-            superclassName = 'RefactoringFeedback';
-          }
-          if (isRefactoringOption) {
-            superclassName = 'RefactoringOptions';
-          }
-          // configure accessors
-          bool generateGetters = true;
-          bool generateSetters = false;
-          if (isRefactoringOption ||
-              typeNameInSpec == 'Outline' ||
-              typeNameInSpec == 'RefactoringMethodParameter') {
-            generateSetters = true;
-          }
-          // create the visitor
-          CodegenJavaType visitor = new CodegenJavaType(api, typeNameInJava,
-              superclassName, generateGetters, generateSetters);
-          return visitor.collectCode(() {
-            dom.Element doc = type.html;
-            if (impliedType.apiNode is TypeDefinition) {
-              doc = (impliedType.apiNode as TypeDefinition).html;
-            }
-            visitor.emitType(type, doc);
-          });
-        };
-      }
-    }
-  }
-  return map;
-});
-
 /**
  * A map between the field names and values for the Element object such as:
  *
@@ -105,12 +50,62 @@
  */
 const Map<String, String> _typeRenames = const {'Override': 'OverrideMember',};
 
-/**
- * Translate spec_input.html into AnalysisServer.java.
- */
-main() {
-  targetDir.generate();
-}
+final String pathToGenTypes = 'tool/spec/generated/java/types';
+
+final GeneratedDirectory targetDir =
+    new GeneratedDirectory(pathToGenTypes, (String pkgPath) {
+  Api api = readApi(pkgPath);
+  Map<String, ImpliedType> impliedTypes = computeImpliedTypes(api);
+  Map<String, FileContentsComputer> map =
+      new Map<String, FileContentsComputer>();
+  for (ImpliedType impliedType in impliedTypes.values) {
+    String typeNameInSpec = capitalize(impliedType.camelName);
+    bool isRefactoringFeedback = impliedType.kind == 'refactoringFeedback';
+    bool isRefactoringOption = impliedType.kind == 'refactoringOptions';
+    if (impliedType.kind == 'typeDefinition' ||
+        isRefactoringFeedback ||
+        isRefactoringOption) {
+      TypeDecl type = impliedType.type;
+      if (type is TypeObject || type is TypeEnum) {
+        // This is for situations such as 'Override' where the name in the spec
+        // doesn't match the java object that we generate:
+        String typeNameInJava = typeNameInSpec;
+        if (_typeRenames.containsKey(typeNameInSpec)) {
+          typeNameInJava = _typeRenames[typeNameInSpec];
+        }
+        map['$typeNameInJava.java'] = (String pkgPath) {
+          String superclassName = null;
+          if (isRefactoringFeedback) {
+            superclassName = 'RefactoringFeedback';
+          }
+          if (isRefactoringOption) {
+            superclassName = 'RefactoringOptions';
+          }
+          // configure accessors
+          bool generateGetters = true;
+          bool generateSetters = false;
+          if (isRefactoringOption ||
+              typeNameInSpec == 'Outline' ||
+              typeNameInSpec == 'RefactoringMethodParameter') {
+            generateSetters = true;
+          }
+          // create the visitor
+          CodegenJavaType visitor = new CodegenJavaType(api, typeNameInJava,
+              superclassName, generateGetters, generateSetters);
+          return visitor.collectCode(() {
+            dom.Element doc = type.html;
+            if (impliedType.apiNode is TypeDefinition) {
+              doc = (impliedType.apiNode as TypeDefinition).html;
+            }
+            visitor.emitType(type, doc);
+          });
+        };
+      }
+    }
+  }
+  print(map.keys);
+  return map;
+});
 
 class CodegenJavaType extends CodegenJavaVisitor {
   final String className;
@@ -161,11 +156,11 @@
   String _getEqualsLogicForField(TypeObjectField field, String other) {
     String name = javaName(field.name);
     if (isPrimitive(field.type) && !field.optional) {
-      return '${other}.${name} == ${name}';
+      return '$other.$name == $name';
     } else if (isArray(field.type)) {
-      return 'Arrays.equals(other.${name}, ${name})';
+      return 'Arrays.equals(other.$name, $name)';
     } else {
-      return 'ObjectUtilities.equals(${other}.${name}, ${name})';
+      return 'ObjectUtilities.equals($other.$name, $name)';
     }
   }
 
@@ -176,7 +171,7 @@
   String _getToStringForField(TypeObjectField field) {
     String name = javaName(field.name);
     if (isArray(field.type) || isList(field.type)) {
-      return 'StringUtils.join(${name}, ", ")';
+      return 'StringUtils.join($name, ", ")';
     } else {
       return name;
     }
@@ -204,7 +199,7 @@
     //
     _extraFieldsOnElement.forEach((String name, String value) {
       publicField(javaName(name), () {
-        writeln('private static final int ${name} = ${value};');
+        writeln('private static final int $name = $value;');
       });
     });
 
@@ -216,8 +211,8 @@
     //
     _extraMethodsOnElement.forEach((String methodName, String fieldName) {
       publicMethod(methodName, () {
-        writeln('public boolean ${methodName}() {');
-        writeln('  return (flags & ${fieldName}) != 0;');
+        writeln('public boolean $methodName() {');
+        writeln('  return (flags & $fieldName) != 0;');
         writeln('}');
       });
     });
@@ -230,23 +225,23 @@
   void _writeOutJsonObjectAddStatement(TypeObjectField field) {
     String name = javaName(field.name);
     if (isDeclaredInSpec(field.type)) {
-      writeln('jsonObject.add("${name}", ${name}.toJson());');
+      writeln('jsonObject.add("$name", $name.toJson());');
     } else if (field.type is TypeList) {
       TypeDecl listItemType = (field.type as TypeList).itemType;
       String jsonArrayName = 'jsonArray${capitalize(name)}';
-      writeln('JsonArray ${jsonArrayName} = new JsonArray();');
-      writeln('for (${javaType(listItemType)} elt : ${name}) {');
+      writeln('JsonArray $jsonArrayName = new JsonArray();');
+      writeln('for (${javaType(listItemType)} elt : $name) {');
       indent(() {
         if (isDeclaredInSpec(listItemType)) {
-          writeln('${jsonArrayName}.add(elt.toJson());');
+          writeln('$jsonArrayName.add(elt.toJson());');
         } else {
-          writeln('${jsonArrayName}.add(new JsonPrimitive(elt));');
+          writeln('$jsonArrayName.add(new JsonPrimitive(elt));');
         }
       });
       writeln('}');
-      writeln('jsonObject.add("${name}", ${jsonArrayName});');
+      writeln('jsonObject.add("$name", $jsonArrayName);');
     } else {
-      writeln('jsonObject.addProperty("${name}", ${name});');
+      writeln('jsonObject.addProperty("$name", $name);');
     }
   }
 
@@ -256,7 +251,7 @@
       toHtmlVisitor.br();
       toHtmlVisitor.write('@coverage dart.server.generated.types');
     }));
-    makeClass('public class ${className}', () {
+    makeClass('public class $className', () {
       TypeEnum typeEnum = type as TypeEnum;
       List<TypeEnumValue> values = typeEnum.values;
       //
@@ -296,7 +291,7 @@
       toHtmlVisitor.write('@coverage dart.server.generated.types');
     }));
     writeln('@SuppressWarnings("unused")');
-    String header = 'public class ${className}';
+    String header = 'public class $className';
     if (superclassName != null) {
       header += ' extends $superclassName';
     }
@@ -309,7 +304,7 @@
       //
       publicField(javaName("EMPTY_ARRAY"), () {
         writeln(
-            'public static final ${className}[] EMPTY_ARRAY = new ${className}[0];');
+            'public static final $className[] EMPTY_ARRAY = new $className[0];');
       });
 
       //
@@ -317,7 +312,7 @@
       //
       publicField(javaName("EMPTY_LIST"), () {
         writeln(
-            'public static final List<${className}> EMPTY_LIST = Lists.newArrayList();');
+            'public static final List<$className> EMPTY_LIST = Lists.newArrayList();');
       });
 
       //
@@ -366,9 +361,9 @@
       //
       constructor(className, () {
         javadocComment(toHtmlVisitor.collectHtml(() {
-          toHtmlVisitor.write('Constructor for {@link ${className}}.');
+          toHtmlVisitor.write('Constructor for {@link $className}.');
         }));
-        write('public ${className}(');
+        write('public $className(');
         // write out parameters to constructor
         List<String> parameters = new List();
         if (className == 'Outline') {
@@ -486,7 +481,7 @@
       if (className != 'Outline') {
         publicMethod('fromJson', () {
           writeln(
-              'public static ${className} fromJson(JsonObject jsonObject) {');
+              'public static $className fromJson(JsonObject jsonObject) {');
           indent(() {
             for (TypeObjectField field in fields) {
               write('${javaFieldType(field)} ${javaName(field.name)} = ');
@@ -519,7 +514,7 @@
               }
               writeln(';');
             }
-            write('return new ${className}(');
+            write('return new $className(');
             List<String> parameters = new List();
             for (TypeObjectField field in fields) {
               if (!_isTypeFieldInUpdateContentUnionType(
@@ -573,13 +568,13 @@
           className != 'RefactoringOptions') {
         publicMethod('fromJsonArray', () {
           writeln(
-              'public static List<${className}> fromJsonArray(JsonArray jsonArray) {');
+              'public static List<$className> fromJsonArray(JsonArray jsonArray) {');
           indent(() {
             writeln('if (jsonArray == null) {');
             writeln('  return EMPTY_LIST;');
             writeln('}');
             writeln(
-                'ArrayList<${className}> list = new ArrayList<${className}>(jsonArray.size());');
+                'ArrayList<$className> list = new ArrayList<$className>(jsonArray.size());');
             writeln('Iterator<JsonElement> iterator = jsonArray.iterator();');
             writeln('while (iterator.hasNext()) {');
             writeln('  list.add(fromJson(iterator.next().getAsJsonObject()));');
@@ -629,9 +624,9 @@
         writeln('@Override');
         writeln('public boolean equals(Object obj) {');
         indent(() {
-          writeln('if (obj instanceof ${className}) {');
+          writeln('if (obj instanceof $className) {');
           indent(() {
-            writeln('${className} other = (${className}) obj;');
+            writeln('$className other = ($className) obj;');
             writeln('return');
             indent(() {
               List<String> equalsForField = new List<String>();
diff --git a/pkg/analysis_server/tool/spec/codegen_matchers.dart b/pkg/analysis_server/tool/spec/codegen_matchers.dart
index 5786493..be2f847 100644
--- a/pkg/analysis_server/tool/spec/codegen_matchers.dart
+++ b/pkg/analysis_server/tool/spec/codegen_matchers.dart
@@ -9,25 +9,19 @@
 
 import 'dart:convert';
 
+import 'package:analyzer/src/codegen/tools.dart';
+
 import 'api.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
 import 'implied_types.dart';
 import 'to_html.dart';
 
-final GeneratedFile target =
-    new GeneratedFile('../../test/integration/protocol_matchers.dart', () {
-  CodegenMatchersVisitor visitor = new CodegenMatchersVisitor(readApi());
+final GeneratedFile target = new GeneratedFile(
+    'test/integration/protocol_matchers.dart', (String pkgPath) {
+  CodegenMatchersVisitor visitor = new CodegenMatchersVisitor(readApi(pkgPath));
   return visitor.collectCode(visitor.visitApi);
 });
 
-/**
- * Translate spec_input.html into protocol_matchers.dart.
- */
-main() {
-  target.generate();
-}
-
 class CodegenMatchersVisitor extends HierarchicalApiVisitor with CodeGenerator {
   /**
    * Visitor used to produce doc comments.
diff --git a/pkg/analysis_server/tool/spec/codegen_tools.dart b/pkg/analysis_server/tool/spec/codegen_tools.dart
deleted file mode 100644
index f3fcb5d..0000000
--- a/pkg/analysis_server/tool/spec/codegen_tools.dart
+++ /dev/null
@@ -1,557 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Tools for code generation.
- */
-library codegen.tools;
-
-import 'dart:io';
-
-import 'package:html/dom.dart' as dom;
-import 'package:path/path.dart';
-
-import 'html_tools.dart';
-import 'text_formatter.dart';
-
-final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
-final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
-
-/**
- * Join the given strings using camelCase.  If [doCapitalize] is true, the first
- * part will be capitalized as well.
- */
-String camelJoin(List<String> parts, {bool doCapitalize: false}) {
-  List<String> upcasedParts = <String>[];
-  for (int i = 0; i < parts.length; i++) {
-    if (i == 0 && !doCapitalize) {
-      upcasedParts.add(parts[i]);
-    } else {
-      upcasedParts.add(capitalize(parts[i]));
-    }
-  }
-  return upcasedParts.join();
-}
-
-/**
- * Capitalize and return the passed String.
- */
-String capitalize(String string) {
-  return string[0].toUpperCase() + string.substring(1);
-}
-
-/**
- * Type of functions used to compute the contents of a set of generated files.
- */
-typedef Map<String, FileContentsComputer> DirectoryContentsComputer();
-
-/**
- * Type of functions used to compute the contents of a generated file.
- */
-typedef String FileContentsComputer();
-
-/**
- * Mixin class for generating code.
- */
-class CodeGenerator {
-  _CodeGeneratorState _state;
-
-  /**
-   * Settings that specialize code generation behavior for a given
-   * programming language.
-   */
-  CodeGeneratorSettings codeGeneratorSettings = new CodeGeneratorSettings();
-
-  /**
-   * Measure the width of the current indentation level.
-   */
-  int get indentWidth => _state.nextIndent.length;
-
-  /**
-   * Execute [callback], collecting any code that is output using [write]
-   * or [writeln], and return the result as a string.
-   */
-  String collectCode(void callback(), {bool removeTrailingNewLine: false}) {
-    _CodeGeneratorState oldState = _state;
-    try {
-      _state = new _CodeGeneratorState();
-      callback();
-      var text =
-          _state.buffer.toString().replaceAll(trailingSpacesInLineRegExp, '');
-      if (!removeTrailingNewLine) {
-        return text;
-      } else {
-        return text.replaceAll(trailingWhitespaceRegExp, '');
-      }
-    } finally {
-      _state = oldState;
-    }
-  }
-
-  /**
-   * Generate a doc comment based on the HTML in [docs].
-   *
-   * When generating java code, the output is compatible with Javadoc, which
-   * understands certain HTML constructs.
-   */
-  void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) {
-    if (containsOnlyWhitespace(docs)) return;
-    writeln(codeGeneratorSettings.docCommentStartMarker);
-    int width = codeGeneratorSettings.commentLineLength;
-    bool javadocStyle = codeGeneratorSettings.languageName == 'java';
-    indentBy(codeGeneratorSettings.docCommentLineLeader, () {
-      write(nodesToText(docs, width - _state.indent.length, javadocStyle,
-          removeTrailingNewLine: removeTrailingNewLine));
-    });
-    writeln(codeGeneratorSettings.docCommentEndMarker);
-  }
-
-  /**
-   * Execute [callback], indenting any code it outputs.
-   */
-  void indent(void callback()) {
-    indentSpecial(
-        codeGeneratorSettings.indent, codeGeneratorSettings.indent, callback);
-  }
-
-  /**
-   * Execute [callback], using [additionalIndent] to indent any code it outputs.
-   */
-  void indentBy(String additionalIndent, void callback()) =>
-      indentSpecial(additionalIndent, additionalIndent, callback);
-
-  /**
-   * Execute [callback], using [additionalIndent] to indent any code it outputs.
-   * The first line of output is indented by [firstAdditionalIndent] instead of
-   * [additionalIndent].
-   */
-  void indentSpecial(
-      String firstAdditionalIndent, String additionalIndent, void callback()) {
-    String oldNextIndent = _state.nextIndent;
-    String oldIndent = _state.indent;
-    try {
-      _state.nextIndent += firstAdditionalIndent;
-      _state.indent += additionalIndent;
-      callback();
-    } finally {
-      _state.nextIndent = oldNextIndent;
-      _state.indent = oldIndent;
-    }
-  }
-
-  void lineComment(List<dom.Node> docs) {
-    if (containsOnlyWhitespace(docs)) {
-      return;
-    }
-    write(codeGeneratorSettings.lineCommentLineLeader);
-    int width = codeGeneratorSettings.commentLineLength;
-    indentBy(codeGeneratorSettings.lineCommentLineLeader, () {
-      write(nodesToText(docs, width - _state.indent.length, false));
-    });
-  }
-
-  void outputHeader({bool javaStyle: false}) {
-    String header;
-    if (codeGeneratorSettings.languageName == 'java') {
-      header = '''
-/*
- * Copyright (c) 2014, the Dart project authors.
- *
- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- *
- * This file has been automatically generated.  Please do not edit it manually.
- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
- */''';
-    } else if (codeGeneratorSettings.languageName == 'python') {
-      header = '''
-# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-#
-# This file has been automatically generated.  Please do not edit it manually.
-# To regenerate the file, use the script
-# "pkg/analysis_server/tool/spec/generate_files".
-''';
-    } else {
-      header = '''
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// This file has been automatically generated.  Please do not edit it manually.
-// To regenerate the file, use the script
-// "pkg/analysis_server/tool/spec/generate_files".
-''';
-    }
-    writeln(header.trim());
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(Object obj) {
-    _state.write(obj.toString());
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    _state.write('$obj\n');
-  }
-}
-
-/**
- * Controls several settings of [CodeGenerator].
- *
- * The default settings are valid for generating Java and Dart code.
- */
-class CodeGeneratorSettings {
-  /**
-   * Name of the language being generated. Lowercase.
-   */
-  String languageName;
-
-  /**
-   * Marker used in line comments.
-   */
-  String lineCommentLineLeader;
-
-  /**
-   * Start marker for doc comments.
-   */
-  String docCommentStartMarker;
-
-  /**
-   * Line leader for body lines in doc comments.
-   */
-  String docCommentLineLeader;
-
-  /**
-   * End marker for doc comments.
-   */
-  String docCommentEndMarker;
-
-  /**
-   * Line length for doc comment lines.
-   */
-  int commentLineLength;
-
-  /**
-   * String used for indenting code.
-   */
-  String indent;
-
-  CodeGeneratorSettings(
-      {this.languageName: 'java',
-      this.lineCommentLineLeader: '// ',
-      this.docCommentStartMarker: '/**',
-      this.docCommentLineLeader: ' * ',
-      this.docCommentEndMarker: ' */',
-      this.commentLineLength: 99,
-      this.indent: '  '});
-}
-
-abstract class GeneratedContent {
-  FileSystemEntity get outputFile;
-  bool check();
-  void generate();
-}
-
-/**
- * Class representing a single output directory (either generated code or
- * generated HTML). No other content should exist in the directory.
- */
-class GeneratedDirectory extends GeneratedContent {
-  /**
-   * The path to the directory that will have the generated content.
-   */
-  final String outputDirPath;
-
-  /**
-   * Callback function that computes the directory contents.
-   */
-  final DirectoryContentsComputer directoryContentsComputer;
-
-  GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer);
-
-  /**
-   * Get a Directory object representing the output directory.
-   */
-  Directory get outputFile =>
-      new Directory(joinAll(posix.split(outputDirPath)));
-
-  /**
-   * Check whether the directory has the correct contents, and return true if it
-   * does.
-   */
-  @override
-  bool check() {
-    Map<String, FileContentsComputer> map = directoryContentsComputer();
-    try {
-      for (String file in map.keys) {
-        FileContentsComputer fileContentsComputer = map[file];
-        String expectedContents = fileContentsComputer();
-        File outputFile =
-            new File(joinAll(posix.split(posix.join(outputDirPath, file))));
-        String actualContents = outputFile.readAsStringSync();
-        // Normalize Windows line endings to Unix line endings so that the
-        // comparison doesn't fail on Windows.
-        actualContents = actualContents.replaceAll('\r\n', '\n');
-        if (expectedContents != actualContents) {
-          return false;
-        }
-      }
-      int nonHiddenFileCount = 0;
-      outputFile
-          .listSync(recursive: false, followLinks: false)
-          .forEach((FileSystemEntity fileSystemEntity) {
-        if (fileSystemEntity is File &&
-            !basename(fileSystemEntity.path).startsWith('.')) {
-          nonHiddenFileCount++;
-        }
-      });
-      if (nonHiddenFileCount != map.length) {
-        // The number of files generated doesn't match the number we expected to
-        // generate.
-        return false;
-      }
-    } catch (e) {
-      // There was a problem reading the file (most likely because it didn't
-      // exist).  Treat that the same as if the file doesn't have the expected
-      // contents.
-      return false;
-    }
-    return true;
-  }
-
-  /**
-   * Replace the directory with the correct contents.  [spec] is the "tool/spec"
-   * directory.  If [spec] is unspecified, it is assumed to be the directory
-   * containing Platform.executable.
-   */
-  @override
-  void generate() {
-    try {
-      // delete the contents of the directory (and the directory itself)
-      outputFile.deleteSync(recursive: true);
-    } catch (e) {
-      // Error caught while trying to delete the directory, this can happen if
-      // it didn't yet exist.
-    }
-    // re-create the empty directory
-    outputFile.createSync(recursive: true);
-
-    // generate all of the files in the directory
-    Map<String, FileContentsComputer> map = directoryContentsComputer();
-    map.forEach((String file, FileContentsComputer fileContentsComputer) {
-      File outputFile = new File(joinAll(posix.split(outputDirPath + file)));
-      outputFile.writeAsStringSync(fileContentsComputer());
-    });
-  }
-}
-
-/**
- * Class representing a single output file (either generated code or generated
- * HTML).
- */
-class GeneratedFile extends GeneratedContent {
-  /**
-   * The output file to which generated output should be written, relative to
-   * the "tool/spec" directory.  This filename uses the posix path separator
-   * ('/') regardless of the OS.
-   */
-  final String outputPath;
-
-  /**
-   * Callback function which computes the file.
-   */
-  final FileContentsComputer computeContents;
-
-  GeneratedFile(this.outputPath, this.computeContents);
-
-  /**
-   * Get a File object representing the output file.
-   */
-  File get outputFile => new File(joinAll(posix.split(outputPath)));
-
-  /**
-   * Check whether the file has the correct contents, and return true if it
-   * does.
-   */
-  @override
-  bool check() {
-    String expectedContents = computeContents();
-    try {
-      String actualContents = outputFile.readAsStringSync();
-      // Normalize Windows line endings to Unix line endings so that the
-      // comparison doesn't fail on Windows.
-      actualContents = actualContents.replaceAll('\r\n', '\n');
-      return expectedContents == actualContents;
-    } catch (e) {
-      // There was a problem reading the file (most likely because it didn't
-      // exist).  Treat that the same as if the file doesn't have the expected
-      // contents.
-      return false;
-    }
-  }
-
-  /**
-   * Replace the file with the correct contents.  [spec] is the "tool/spec"
-   * directory.  If [spec] is unspecified, it is assumed to be the directory
-   * containing Platform.executable.
-   */
-  void generate() {
-    outputFile.writeAsStringSync(computeContents());
-  }
-}
-
-/**
- * Mixin class for generating HTML representations of code that are suitable
- * for enclosing inside a <pre> element.
- */
-abstract class HtmlCodeGenerator {
-  _HtmlCodeGeneratorState _state;
-
-  /**
-   * Add the given [node] to the HTML output.
-   */
-  void add(dom.Node node) {
-    _state.add(node);
-  }
-
-  /**
-   * Add the given [nodes] to the HTML output.
-   */
-  void addAll(Iterable<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      _state.add(node);
-    }
-  }
-
-  /**
-   * Execute [callback], collecting any code that is output using [write],
-   * [writeln], [add], or [addAll], and return the result as a list of DOM
-   * nodes.
-   */
-  List<dom.Node> collectHtml(void callback()) {
-    _HtmlCodeGeneratorState oldState = _state;
-    try {
-      _state = new _HtmlCodeGeneratorState();
-      if (callback != null) {
-        callback();
-      }
-      return _state.buffer;
-    } finally {
-      _state = oldState;
-    }
-  }
-
-  /**
-   * Execute [callback], wrapping its output in an element with the given
-   * [name] and [attributes].
-   */
-  void element(String name, Map<String, String> attributes, [void callback()]) {
-    add(makeElement(name, attributes, collectHtml(callback)));
-  }
-
-  /**
-   * Execute [callback], indenting any code it outputs by two spaces.
-   */
-  void indent(void callback()) {
-    String oldIndent = _state.indent;
-    try {
-      _state.indent += '  ';
-      callback();
-    } finally {
-      _state.indent = oldIndent;
-    }
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(Object obj) {
-    _state.write(obj.toString());
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    _state.write('$obj\n');
-  }
-}
-
-/**
- * State used by [CodeGenerator].
- */
-class _CodeGeneratorState {
-  StringBuffer buffer = new StringBuffer();
-  String nextIndent = '';
-  String indent = '';
-  bool indentNeeded = true;
-
-  void write(String text) {
-    List<String> lines = text.split('\n');
-    for (int i = 0; i < lines.length; i++) {
-      if (i == lines.length - 1 && lines[i].isEmpty) {
-        break;
-      }
-      if (indentNeeded) {
-        buffer.write(nextIndent);
-        nextIndent = indent;
-      }
-      indentNeeded = false;
-      buffer.write(lines[i]);
-      if (i != lines.length - 1) {
-        buffer.writeln();
-        indentNeeded = true;
-      }
-    }
-  }
-}
-
-/**
- * State used by [HtmlCodeGenerator].
- */
-class _HtmlCodeGeneratorState {
-  List<dom.Node> buffer = <dom.Node>[];
-  String indent = '';
-  bool indentNeeded = true;
-
-  void add(dom.Node node) {
-    if (node is dom.Text) {
-      write(node.text);
-    } else {
-      buffer.add(node);
-    }
-  }
-
-  void write(String text) {
-    if (text.isEmpty) {
-      return;
-    }
-    if (indentNeeded) {
-      buffer.add(new dom.Text(indent));
-    }
-    List<String> lines = text.split('\n');
-    if (lines.last.isEmpty) {
-      lines.removeLast();
-      buffer.add(new dom.Text(lines.join('\n$indent') + '\n'));
-      indentNeeded = true;
-    } else {
-      buffer.add(new dom.Text(lines.join('\n$indent')));
-      indentNeeded = false;
-    }
-  }
-}
diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart
index 1ae9425..3840d86 100644
--- a/pkg/analysis_server/tool/spec/from_html.dart
+++ b/pkg/analysis_server/tool/spec/from_html.dart
@@ -9,11 +9,12 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/html.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:html/parser.dart' as parser;
+import 'package:path/path.dart';
 
 import 'api.dart';
-import 'html_tools.dart';
 
 const List<String> specialElements = const [
   'domain',
@@ -106,7 +107,7 @@
   for (String expectedAttribute in requiredAttributes) {
     if (!attributesFound.contains(expectedAttribute)) {
       throw new Exception(
-          '$context: ${element.localName} must contain attribute ${expectedAttribute}');
+          '$context: ${element.localName} must contain attribute $expectedAttribute');
     }
   }
 }
@@ -137,8 +138,10 @@
 Domain domainFromHtml(dom.Element html) {
   checkName(html, 'domain');
   String name = html.attributes['name'];
-  String context = name != null ? name : 'domain';
-  checkAttributes(html, ['name'], context);
+  String context = name ?? 'domain';
+  bool experimental = html.attributes['experimental'] == 'true';
+  checkAttributes(html, ['name'], context,
+      optionalAttributes: ['experimental']);
   List<Request> requests = <Request>[];
   List<Notification> notifications = <Notification>[];
   recurse(html, context, {
@@ -149,7 +152,8 @@
       notifications.add(notificationFromHtml(child, context));
     }
   });
-  return new Domain(name, requests, notifications, html);
+  return new Domain(name, requests, notifications, html,
+      experimental: experimental);
 }
 
 dom.Element getAncestor(dom.Element html, String name, String context) {
@@ -287,10 +291,11 @@
 }
 
 /**
- * Read the API description from the file 'spec_input.html'.
+ * Read the API description from the file 'spec_input.html'.  [pkgPath] is the
+ * path to the current package.
  */
-Api readApi() {
-  File htmlFile = new File('spec_input.html');
+Api readApi(String pkgPath) {
+  File htmlFile = new File(join(pkgPath, 'tool', 'spec', 'spec_input.html'));
   String htmlContents = htmlFile.readAsStringSync();
   dom.Document document = parser.parse(htmlContents);
   dom.Element htmlElement = document.children
@@ -418,9 +423,10 @@
   checkName(html, 'type');
   String name = html.attributes['name'];
   String context = name != null ? name : 'type';
-  checkAttributes(html, ['name'], context);
+  checkAttributes(html, ['name'], context, optionalAttributes: ['experimental']);
   TypeDecl type = processContentsAsType(html, context);
-  return new TypeDefinition(name, type, html);
+  bool experimental = html.attributes['experimental'] == 'true';
+  return new TypeDefinition(name, type, html, experimental: experimental);
 }
 
 /**
@@ -511,14 +517,15 @@
  * Create a [TypeObject] from an HTML description.
  */
 TypeObject typeObjectFromHtml(dom.Element html, String context) {
-  checkAttributes(html, [], context);
+  checkAttributes(html, [], context,  optionalAttributes: ['experimental']);
   List<TypeObjectField> fields = <TypeObjectField>[];
   recurse(html, context, {
     'field': (dom.Element child) {
       fields.add(typeObjectFieldFromHtml(child, context));
     }
   });
-  return new TypeObject(fields, html);
+  bool experimental = html.attributes['experimental'] == 'true';
+  return new TypeObject(fields, html, experimental: experimental);
 }
 
 /**
diff --git a/pkg/analysis_server/tool/spec/generate_all.dart b/pkg/analysis_server/tool/spec/generate_all.dart
index 00489bd..74d4307 100644
--- a/pkg/analysis_server/tool/spec/generate_all.dart
+++ b/pkg/analysis_server/tool/spec/generate_all.dart
@@ -6,6 +6,7 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:path/path.dart';
 
 import 'codegen_analysis_server.dart' as codegen_analysis_server;
@@ -13,10 +14,18 @@
 import 'codegen_inttest_methods.dart' as codegen_inttest_methods;
 import 'codegen_java_types.dart' as codegen_java_types;
 import 'codegen_matchers.dart' as codegen_matchers;
-import 'codegen_tools.dart';
 import 'to_html.dart' as to_html;
 
 /**
+ * Generate all targets
+ */
+main() {
+  String script = Platform.script.toFilePath(windows: Platform.isWindows);
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.generateAll(pkgPath, allTargets);
+}
+
+/**
  * Get a list of all generated targets.
  */
 List<GeneratedContent> get allTargets {
@@ -29,14 +38,3 @@
   targets.add(to_html.target);
   return targets;
 }
-
-/**
- * Generate all targets
- */
-main() {
-  String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  Directory.current = new Directory(dirname(script));
-  for (GeneratedContent generatedContent in allTargets) {
-    generatedContent.generate();
-  }
-}
diff --git a/pkg/analysis_server/tool/spec/generate_files b/pkg/analysis_server/tool/spec/generate_files
index 0c992fa..85092ea 100755
--- a/pkg/analysis_server/tool/spec/generate_files
+++ b/pkg/analysis_server/tool/spec/generate_files
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 83223c6..e465571 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
@@ -119,6 +119,20 @@
   public void analysis_getNavigation(String file, int offset, int length, GetNavigationConsumer consumer);
 
   /**
+   * {@code analysis.getReachableSources}
+   *
+   * Return the transitive closure of reachable sources for a given file.
+   *
+   * If a request is made for a file which does not exist, or which is not currently subject to
+   * analysis (e.g. because it is not associated with any analysis root specified to
+   * analysis.setAnalysisRoots), an error of type GET_REACHABLE_SOURCES_INVALID_FILE will be
+   * generated.
+   *
+   * @param file The file for which reachable source information is being requested.
+   */
+  public void analysis_getReachableSources(String file, GetReachableSourcesConsumer consumer);
+
+  /**
    * {@code analysis.reanalyze}
    *
    * Force the re-analysis of everything contained in the specified analysis roots. This will cause
@@ -273,6 +287,13 @@
   public void completion_getSuggestions(String file, int offset, GetSuggestionsConsumer consumer);
 
   /**
+   * {@code diagnostic.getDiagnostics}
+   *
+   * Return server diagnostics.
+   */
+  public void diagnostic_getDiagnostics(GetDiagnosticsConsumer consumer);
+
+  /**
    * {@code edit.format}
    *
    * Format the contents of a single file. The currently selected region of text is passed in so that
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
index 9d9c428..74249ca 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
index baf27c0..9020207 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
index 6a53f63..0837dac 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
index 6396fc2..e07df40 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
index d4ea8d7..db6fe76 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
index afdde92..6f99a38 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java
index 02bd9f6..407a650 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java
index d738660..1a0cb7f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java
index 469e3dc..e7b4062 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
index a69eee1..4cffa50 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
index 71f8761..3cebeab 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
new file mode 100644
index 0000000..ab4020c
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2015, the Dart project authors.
+ *
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * This file has been automatically generated.  Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Information about an analysis context.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class ContextData {
+
+  public static final ContextData[] EMPTY_ARRAY = new ContextData[0];
+
+  public static final List<ContextData> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The name of the context.
+   */
+  private final String name;
+
+  /**
+   * Explicitly analyzed files.
+   */
+  private final int explicitFileCount;
+
+  /**
+   * Implicitly analyzed files.
+   */
+  private final int implicitFileCount;
+
+  /**
+   * The number of work items in the queue.
+   */
+  private final int workItemQueueLength;
+
+  /**
+   * Exceptions associated with cache entries.
+   */
+  private final List<String> cacheEntryExceptions;
+
+  /**
+   * Constructor for {@link ContextData}.
+   */
+  public ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, List<String> cacheEntryExceptions) {
+    this.name = name;
+    this.explicitFileCount = explicitFileCount;
+    this.implicitFileCount = implicitFileCount;
+    this.workItemQueueLength = workItemQueueLength;
+    this.cacheEntryExceptions = cacheEntryExceptions;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof ContextData) {
+      ContextData other = (ContextData) obj;
+      return
+        ObjectUtilities.equals(other.name, name) &&
+        other.explicitFileCount == explicitFileCount &&
+        other.implicitFileCount == implicitFileCount &&
+        other.workItemQueueLength == workItemQueueLength &&
+        ObjectUtilities.equals(other.cacheEntryExceptions, cacheEntryExceptions);
+    }
+    return false;
+  }
+
+  public static ContextData fromJson(JsonObject jsonObject) {
+    String name = jsonObject.get("name").getAsString();
+    int explicitFileCount = jsonObject.get("explicitFileCount").getAsInt();
+    int implicitFileCount = jsonObject.get("implicitFileCount").getAsInt();
+    int workItemQueueLength = jsonObject.get("workItemQueueLength").getAsInt();
+    List<String> cacheEntryExceptions = JsonUtilities.decodeStringList(jsonObject.get("cacheEntryExceptions").getAsJsonArray());
+    return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, cacheEntryExceptions);
+  }
+
+  public static List<ContextData> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<ContextData> list = new ArrayList<ContextData>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * Exceptions associated with cache entries.
+   */
+  public List<String> getCacheEntryExceptions() {
+    return cacheEntryExceptions;
+  }
+
+  /**
+   * Explicitly analyzed files.
+   */
+  public int getExplicitFileCount() {
+    return explicitFileCount;
+  }
+
+  /**
+   * Implicitly analyzed files.
+   */
+  public int getImplicitFileCount() {
+    return implicitFileCount;
+  }
+
+  /**
+   * The name of the context.
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * The number of work items in the queue.
+   */
+  public int getWorkItemQueueLength() {
+    return workItemQueueLength;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(name);
+    builder.append(explicitFileCount);
+    builder.append(implicitFileCount);
+    builder.append(workItemQueueLength);
+    builder.append(cacheEntryExceptions);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("name", name);
+    jsonObject.addProperty("explicitFileCount", explicitFileCount);
+    jsonObject.addProperty("implicitFileCount", implicitFileCount);
+    jsonObject.addProperty("workItemQueueLength", workItemQueueLength);
+    JsonArray jsonArrayCacheEntryExceptions = new JsonArray();
+    for (String elt : cacheEntryExceptions) {
+      jsonArrayCacheEntryExceptions.add(new JsonPrimitive(elt));
+    }
+    jsonObject.add("cacheEntryExceptions", jsonArrayCacheEntryExceptions);
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("name=");
+    builder.append(name + ", ");
+    builder.append("explicitFileCount=");
+    builder.append(explicitFileCount + ", ");
+    builder.append("implicitFileCount=");
+    builder.append(implicitFileCount + ", ");
+    builder.append("workItemQueueLength=");
+    builder.append(workItemQueueLength + ", ");
+    builder.append("cacheEntryExceptions=");
+    builder.append(StringUtils.join(cacheEntryExceptions, ", "));
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Element.java b/pkg/analysis_server/tool/spec/generated/java/types/Element.java
index 51115ec..579ef3f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Element.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Element.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
index b84c921..0291a15 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
@@ -63,8 +63,14 @@
 
   public static final String TYPE_PARAMETER = "TYPE_PARAMETER";
 
+  /**
+   * Deprecated: support for tests was removed.
+   */
   public static final String UNIT_TEST_GROUP = "UNIT_TEST_GROUP";
 
+  /**
+   * Deprecated: support for tests was removed.
+   */
   public static final String UNIT_TEST_TEST = "UNIT_TEST_TEST";
 
   public static final String UNKNOWN = "UNKNOWN";
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java
index aee28ae..52f0c95 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java
index 3b3f1b8..407f368 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java
index 362368b..0e1b005 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java
index e00506d..8058954 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
@@ -96,8 +96,8 @@
   }
 
   public static ExtractLocalVariableFeedback fromJson(JsonObject jsonObject) {
-    int[] coveringExpressionOffsets = JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionOffsets").getAsJsonArray());
-    int[] coveringExpressionLengths = JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionLengths").getAsJsonArray());
+    int[] coveringExpressionOffsets = jsonObject.get("coveringExpressionOffsets") == null ? null : JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionOffsets").getAsJsonArray());
+    int[] coveringExpressionLengths = jsonObject.get("coveringExpressionLengths") == null ? null : JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionLengths").getAsJsonArray());
     List<String> names = JsonUtilities.decodeStringList(jsonObject.get("names").getAsJsonArray());
     int[] offsets = JsonUtilities.decodeIntArray(jsonObject.get("offsets").getAsJsonArray());
     int[] lengths = JsonUtilities.decodeIntArray(jsonObject.get("lengths").getAsJsonArray());
@@ -168,16 +168,20 @@
 
   public JsonObject toJson() {
     JsonObject jsonObject = new JsonObject();
-    JsonArray jsonArrayCoveringExpressionOffsets = new JsonArray();
-    for (int elt : coveringExpressionOffsets) {
-      jsonArrayCoveringExpressionOffsets.add(new JsonPrimitive(elt));
+    if (coveringExpressionOffsets != null) {
+      JsonArray jsonArrayCoveringExpressionOffsets = new JsonArray();
+      for (int elt : coveringExpressionOffsets) {
+        jsonArrayCoveringExpressionOffsets.add(new JsonPrimitive(elt));
+      }
+      jsonObject.add("coveringExpressionOffsets", jsonArrayCoveringExpressionOffsets);
     }
-    jsonObject.add("coveringExpressionOffsets", jsonArrayCoveringExpressionOffsets);
-    JsonArray jsonArrayCoveringExpressionLengths = new JsonArray();
-    for (int elt : coveringExpressionLengths) {
-      jsonArrayCoveringExpressionLengths.add(new JsonPrimitive(elt));
+    if (coveringExpressionLengths != null) {
+      JsonArray jsonArrayCoveringExpressionLengths = new JsonArray();
+      for (int elt : coveringExpressionLengths) {
+        jsonArrayCoveringExpressionLengths.add(new JsonPrimitive(elt));
+      }
+      jsonObject.add("coveringExpressionLengths", jsonArrayCoveringExpressionLengths);
     }
-    jsonObject.add("coveringExpressionLengths", jsonArrayCoveringExpressionLengths);
     JsonArray jsonArrayNames = new JsonArray();
     for (String elt : names) {
       jsonArrayNames.add(new JsonPrimitive(elt));
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java
index 4413dde..c0b9756 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java
index f6acccc..6bb32fe 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java
index d6b509e..1e71e43 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java
index d9ba7bb..8275310 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
index 4e72f1b..4a281de 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java
index 3e63a4e..ebad0e7 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java b/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java
index a1f0071..80975fa 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java
index 7a8e83c..ebbd410 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
index 9eace11..15d1373 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java b/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java
index c360b6a..79d233e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java
index dbe7096..5c08f6b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java
index 941d1a8..a18d6a4 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java
index 89c3bff..65e4a86 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java
index c6842dd..6d80cfa 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java
index 938c664..c13daa7 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java
index 7a495e8..b83f304 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java
index 4deb527..2537bc5 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java
index cdcdfa5..be193e0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Location.java b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
index d52b5f7..d9f8ae0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Location.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java
index d828d0d..4f04962 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java
index 8500056..80565a9 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java b/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java
index 217d091e..001a7a0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java b/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java
index 894fc0a..2f84e55 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Outline.java b/pkg/analysis_server/tool/spec/generated/java/types/Outline.java
index 7fd32a1..88eb41b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Outline.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Outline.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java b/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java
index 720722a..6054c55 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java b/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java
index 264185f..6f5936e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Position.java b/pkg/analysis_server/tool/spec/generated/java/types/Position.java
index 3eed81f..d9e3636 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Position.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Position.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java b/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java
index 27e2cfe..9d45a19 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java
index c619daf..d3cfa25 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java
index 9c8d0a8..b4eb166 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java
index 532ecfb..c3b20c2 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java
index 146617d..c71d8bb 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java
index 16c4392..67abd4b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java
index 3b8ec81..1b82e4a 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java
index 01ef16f..35c8296 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java
index b442848..c9e14a4 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
index cd31922..35dacff 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java
index 5ec34ce..18b80e0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java
index 598d83f..34c6b31 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
index 3730a03..346bf63 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
@@ -59,6 +59,12 @@
   public static final String GET_NAVIGATION_INVALID_FILE = "GET_NAVIGATION_INVALID_FILE";
 
   /**
+   * An "analysis.getReachableSources" request specified a FilePath which does not match a file
+   * currently subject to analysis.
+   */
+  public static final String GET_REACHABLE_SOURCES_INVALID_FILE = "GET_REACHABLE_SOURCES_INVALID_FILE";
+
+  /**
    * A path passed as an argument to a request (such as analysis.reanalyze) is required to be an
    * analysis root, but isn't.
    */
@@ -70,6 +76,11 @@
   public static final String INVALID_EXECUTION_CONTEXT = "INVALID_EXECUTION_CONTEXT";
 
   /**
+   * The format of the given file path is invalid, e.g. is not absolute and normalized.
+   */
+  public static final String INVALID_FILE_PATH_FORMAT = "INVALID_FILE_PATH_FORMAT";
+
+  /**
    * An "analysis.updateContent" request contained a ChangeContentOverlay object which can't be
    * applied, due to an edit having an offset or length that is out of range.
    */
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java b/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java
index 6f44743..299aba0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java b/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java
index ddbe0ef..e556272 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java b/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java
index 54fb1b3..6846e6e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java
index 45bf4eb..6842e2f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java
index 50b6306..1d54802 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java
index 5cfa8a1..18fab9b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java b/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java
index bfb0acc..b6420a2 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
diff --git a/pkg/analysis_server/tool/spec/html_tools.dart b/pkg/analysis_server/tool/spec/html_tools.dart
deleted file mode 100644
index d46419f..0000000
--- a/pkg/analysis_server/tool/spec/html_tools.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Tools for HTML manipulation.
- */
-library html.tools;
-
-import 'package:html/dom.dart' as dom;
-
-/**
- * Make a deep copy of the given HTML nodes.
- */
-List<dom.Node> cloneHtmlNodes(List<dom.Node> nodes) =>
-    nodes.map((dom.Node node) => node.clone(true)).toList();
-
-/**
- * Return true if the given iterable contains only whitespace text nodes.
- */
-bool containsOnlyWhitespace(Iterable<dom.Node> nodes) {
-  for (dom.Node node in nodes) {
-    if (!isWhitespaceNode(node)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-/**
- * Get the text contents of the element, ignoring all markup.
- */
-String innerText(dom.Element parent) {
-  StringBuffer buffer = new StringBuffer();
-  void recurse(dom.Element parent) {
-    for (dom.Node child in parent.nodes) {
-      if (child is dom.Text) {
-        buffer.write(child.text);
-      } else if (child is dom.Element) {
-        recurse(child);
-      }
-    }
-  }
-  recurse(parent);
-  return buffer.toString();
-}
-
-/**
- * Return true if the given node is a text node containing only whitespace, or
- * a comment.
- */
-bool isWhitespaceNode(dom.Node node) {
-  if (node is dom.Element) {
-    return false;
-  } else if (node is dom.Text) {
-    return node.text.trim().isEmpty;
-  }
-  // Treat all other types of nodes (e.g. comments) as whitespace.
-  return true;
-}
-
-/**
- * Create an HTML element with the given name, attributes, and child nodes.
- */
-dom.Element makeElement(
-    String name, Map<dynamic, String> attributes, List<dom.Node> children) {
-  dom.Element result = new dom.Element.tag(name);
-  result.attributes.addAll(attributes);
-  for (dom.Node child in children) {
-    result.append(child);
-  }
-  return result;
-}
-
-/**
- * Mixin class for generating HTML.
- */
-class HtmlGenerator {
-  List<dom.Node> _html;
-
-  /**
-   * Add the given [node] to the HTML output.
-   */
-  void add(dom.Node node) {
-    _html.add(node);
-  }
-
-  /**
-   * Add the given [nodes] to the HTML output.
-   */
-  void addAll(Iterable<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      add(node);
-    }
-  }
-
-  /**
-   * Execute [callback], collecting any code that is output using [write],
-   * [writeln], [add], [addAll] or [element], and return the result as a list
-   * of HTML nodes.
-   */
-  List<dom.Node> collectHtml(void callback()) {
-    List<dom.Node> oldHtml = _html;
-    try {
-      _html = <dom.Node>[];
-      if (callback != null) {
-        callback();
-      }
-      return _html;
-    } finally {
-      _html = oldHtml;
-    }
-  }
-
-  /**
-   * Execute [callback], wrapping its output in an element with the given
-   * [name] and [attributes].
-   */
-  void element(String name, Map<dynamic, String> attributes,
-      [void callback()]) {
-    add(makeElement(name, attributes, collectHtml(callback)));
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(String text) {
-    _html.add(new dom.Text(text));
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    write('$obj\n');
-  }
-}
diff --git a/pkg/analysis_server/tool/spec/implied_types.dart b/pkg/analysis_server/tool/spec/implied_types.dart
index 8f25296..21987fd 100644
--- a/pkg/analysis_server/tool/spec/implied_types.dart
+++ b/pkg/analysis_server/tool/spec/implied_types.dart
@@ -7,8 +7,9 @@
  */
 library html.tools;
 
+import 'package:analyzer/src/codegen/tools.dart';
+
 import 'api.dart';
-import 'codegen_tools.dart';
 
 Map<String, ImpliedType> computeImpliedTypes(Api api) {
   _ImpliedTypesVisitor visitor = new _ImpliedTypesVisitor(api);
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 8c349e3..c26da51 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -6,7 +6,7 @@
   </head>
   <body>
     <h1>Analysis Server API Specification</h1>
-    <h1 style="color:#999999">Version <version>1.12.0</version></h1>
+    <h1 style="color:#999999">Version <version>1.14.0</version></h1>
     <p>
       This document contains a specification of the API provided by the
       analysis server.  The API in this document is currently under
@@ -395,6 +395,42 @@
           </field>
         </result>
       </request>
+      <request method="getReachableSources">
+        <p>
+          Return the transitive closure of reachable sources for a given file.
+        </p>
+        <p>
+          If a request is made for a file which does not exist, or
+          which is not currently subject to analysis (e.g. because it
+          is not associated with any analysis root specified to
+          analysis.setAnalysisRoots), an error of type
+          <tt>GET_REACHABLE_SOURCES_INVALID_FILE</tt> will be generated.
+        </p>
+        <params>
+          <field name="file">
+            <ref>FilePath</ref>
+            <p>
+              The file for which reachable source information is being requested.
+            </p>
+          </field>
+        </params>
+        <result>
+          <field name="sources">
+            <map>
+              <key><ref>String</ref></key>
+              <value><list>><ref>String</ref></list></value>
+            </map>
+            <p>
+              A mapping from source URIs to directly reachable source URIs. For example,
+              a file "foo.dart" that imports "bar.dart" would have the corresponding mapping
+              { "file:///foo.dart" : ["file:///bar.dart"] }.  If "bar.dart" has further imports
+              (or exports) there will be a mapping from the URI "file:///bar.dart" to them.
+              To check if a specific URI is reachable from a given file, clients can check
+              for its presence in the resulting key set.
+            </p>
+          </field>
+        </result>
+      </request>
       <request method="getLibraryDependencies">
         <p>
           Return library dependency information for use in client-side indexing
@@ -1959,6 +1995,20 @@
         </params>
       </notification>
     </domain>
+    <domain name="diagnostic">
+      <p>
+        The diagnostic domain contains server diagnostics APIs.
+      </p>
+      <request method="getDiagnostics">
+        <p>Return server diagnostics.</p>
+        <result>
+          <field name="contexts">
+            <list><ref>ContextData</ref></list>
+            <p>The list of analysis contexts.</p>
+          </field>
+        </result>
+      </request>
+    </domain>
     <types>
       <h2 class="domain"><a name="types">Types</a></h2>
       <p>
@@ -2441,6 +2491,43 @@
           <value><code>PARAMETER</code></value>
         </enum>
       </type>
+      <type name="ContextData">
+        <p>
+          Information about an analysis context.
+        </p>
+        <object>
+          <field name="name">
+            <ref>String</ref>
+            <p>
+              The name of the context.
+            </p>
+          </field>
+          <field name="explicitFileCount">
+            <ref>int</ref>
+            <p>
+              Explicitly analyzed files.
+            </p>
+          </field>
+          <field name="implicitFileCount">
+            <ref>int</ref>
+            <p>
+              Implicitly analyzed files.
+            </p>
+          </field>
+          <field name="workItemQueueLength">
+            <ref>int</ref>
+            <p>
+              The number of work items in the queue.
+            </p>
+          </field>
+          <field name="cacheEntryExceptions">
+            <list><ref>String</ref></list>
+            <p>
+              Exceptions associated with cache entries.
+            </p>
+          </field>
+        </object>
+      </type>
       <type name="Element">
         <p>
           Information about an element (something that can be declared
@@ -2534,8 +2621,14 @@
           <value><code>SETTER</code></value>
           <value><code>TOP_LEVEL_VARIABLE</code></value>
           <value><code>TYPE_PARAMETER</code></value>
-          <value><code>UNIT_TEST_GROUP</code></value>
-          <value><code>UNIT_TEST_TEST</code></value>
+          <value>
+            <code>UNIT_TEST_GROUP</code>
+            <p><b><i>Deprecated</i></b>: support for tests was removed.</p>
+          </value>
+          <value>
+            <code>UNIT_TEST_TEST</code>
+            <p><b><i>Deprecated</i></b>: support for tests was removed.</p>
+          </value>
           <value><code>UNKNOWN</code></value>
         </enum>
       </type>
@@ -2596,7 +2689,12 @@
       <type name="FilePath">
         <ref>String</ref>
         <p>
-          The absolute path of a file.
+          The absolute, normalized path of a file.
+        </p>
+        <p>
+          If the format of a file path in a request is not valid, e.g. the
+          path is not absolute or is not normalized, then an error of type
+          <tt>INVALID_FILE_PATH_FORMAT</tt> will be generated.
         </p>
       </type>
       <type name="FoldingKind">
@@ -3588,6 +3686,14 @@
             </p>
           </value>
           <value>
+            <code>GET_REACHABLE_SOURCES_INVALID_FILE</code>
+            <p>
+              An "analysis.getReachableSources" request specified a FilePath
+              which does not match a file currently subject to
+              analysis.
+            </p>
+          </value>
+          <value>
             <code>INVALID_ANALYSIS_ROOT</code>
             <p>
               A path passed as an argument to a request (such as
@@ -3602,6 +3708,13 @@
             </p>
           </value>
           <value>
+            <code>INVALID_FILE_PATH_FORMAT</code>
+            <p>
+              The format of the given file path is invalid, e.g. is not
+              absolute and normalized.
+            </p>
+          </value>
+          <value>
             <code>INVALID_OVERLAY_CHANGE</code>
             <p>
               An "analysis.updateContent" request contained a
@@ -4035,14 +4148,14 @@
           complete expression.
         </p>
         <feedback>
-          <field name="coveringExpressionOffsets">
+          <field name="coveringExpressionOffsets" optional="true">
             <list><ref>int</ref></list>
             <p>
               The offsets of the expressions that cover the specified
               selection, from the down most to the up most.
             </p>
           </field>
-          <field name="coveringExpressionLengths">
+          <field name="coveringExpressionLengths" optional="true">
             <list><ref>int</ref></list>
             <p>
               The lengths of the expressions that cover the specified
diff --git a/pkg/analysis_server/tool/spec/text_formatter.dart b/pkg/analysis_server/tool/spec/text_formatter.dart
deleted file mode 100644
index a4eb82c..0000000
--- a/pkg/analysis_server/tool/spec/text_formatter.dart
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Code for converting HTML into text, for use in doc comments.
- */
-library text.formatter;
-
-import 'package:html/dom.dart' as dom;
-
-import 'codegen_tools.dart';
-
-final RegExp whitespace = new RegExp(r'\s');
-
-/**
- * Convert the HTML in [desc] into text, word wrapping at width [width].
- *
- * If [javadocStyle] is true, then the output is compatable with Javadoc,
- * which understands certain HTML constructs.
- */
-String nodesToText(List<dom.Node> desc, int width, bool javadocStyle,
-    {bool removeTrailingNewLine: false}) {
-  _TextFormatter formatter = new _TextFormatter(width, javadocStyle);
-  return formatter.collectCode(() {
-    formatter.addAll(desc);
-    formatter.lineBreak(false);
-  }, removeTrailingNewLine: removeTrailingNewLine);
-}
-
-/**
- * Engine that transforms HTML to text.  The input HTML is processed one
- * character at a time, gathering characters into words and words into lines.
- */
-class _TextFormatter extends CodeGenerator {
-  /**
-   * Word-wrapping width.
-   */
-  final int width;
-
-  /**
-   * The word currently being gathered.
-   */
-  String word = '';
-
-  /**
-   * The line currently being gathered.
-   */
-  String line = '';
-
-  /**
-   * True if a blank line should be inserted before the next word.
-   */
-  bool verticalSpaceNeeded = false;
-
-  /**
-   * True if no text has been output yet.  This suppresses blank lines.
-   */
-  bool atStart = true;
-
-  /**
-   * True if we are processing a <pre> element, thus whitespace should be
-   * preserved.
-   */
-  bool preserveSpaces = false;
-
-  /**
-   * True if the output should be Javadoc compatible.
-   */
-  final bool javadocStyle;
-
-  _TextFormatter(this.width, this.javadocStyle);
-
-  /**
-   * Process an HTML node.
-   */
-  void add(dom.Node node) {
-    if (node is dom.Text) {
-      for (String char in node.text.split('')) {
-        if (preserveSpaces) {
-          wordBreak();
-          write(escape(char));
-        } else if (whitespace.hasMatch(char)) {
-          wordBreak();
-        } else {
-          resolveVerticalSpace();
-          word += escape(char);
-        }
-      }
-    } else if (node is dom.Element) {
-      switch (node.localName) {
-        case 'br':
-          lineBreak(false);
-          break;
-        case 'dl':
-        case 'dt':
-        case 'h1':
-        case 'h2':
-        case 'h3':
-        case 'h4':
-        case 'p':
-          lineBreak(true);
-          addAll(node.nodes);
-          lineBreak(true);
-          break;
-        case 'div':
-          lineBreak(false);
-          if (node.classes.contains('hangingIndent')) {
-            resolveVerticalSpace();
-            indentSpecial('', '        ', () {
-              addAll(node.nodes);
-              lineBreak(false);
-            });
-          } else {
-            addAll(node.nodes);
-            lineBreak(false);
-          }
-          break;
-        case 'ul':
-          lineBreak(false);
-          addAll(node.nodes);
-          lineBreak(false);
-          break;
-        case 'li':
-          lineBreak(false);
-          resolveVerticalSpace();
-          indentSpecial('- ', '  ', () {
-            addAll(node.nodes);
-            lineBreak(false);
-          });
-          break;
-        case 'dd':
-          lineBreak(true);
-          indent(() {
-            addAll(node.nodes);
-            lineBreak(true);
-          });
-          break;
-        case 'pre':
-          lineBreak(false);
-          resolveVerticalSpace();
-          if (javadocStyle) {
-            writeln('<pre>');
-          }
-          bool oldPreserveSpaces = preserveSpaces;
-          try {
-            preserveSpaces = true;
-            addAll(node.nodes);
-          } finally {
-            preserveSpaces = oldPreserveSpaces;
-          }
-          writeln();
-          if (javadocStyle) {
-            writeln('</pre>');
-          }
-          lineBreak(false);
-          break;
-        case 'a':
-        case 'b':
-        case 'body':
-        case 'html':
-        case 'i':
-        case 'span':
-        case 'tt':
-          addAll(node.nodes);
-          break;
-        case 'head':
-          break;
-        default:
-          throw new Exception('Unexpected HTML element: ${node.localName}');
-      }
-    } else {
-      throw new Exception('Unexpected HTML: $node');
-    }
-  }
-
-  /**
-   * Process a list of HTML nodes.
-   */
-  void addAll(List<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      add(node);
-    }
-  }
-
-  /**
-   * Escape the given character for HTML.
-   */
-  String escape(String char) {
-    if (javadocStyle) {
-      switch (char) {
-        case '<':
-          return '&lt;';
-        case '>':
-          return '&gt;';
-        case '&':
-          return '&amp;';
-      }
-    }
-    return char;
-  }
-
-  /**
-   * Terminate the current word and/or line, if either is in progress.
-   */
-  void lineBreak(bool gap) {
-    wordBreak();
-    if (line.isNotEmpty) {
-      writeln(line);
-      line = '';
-    }
-    if (gap && !atStart) {
-      verticalSpaceNeeded = true;
-    }
-  }
-
-  /**
-   * Insert vertical space if necessary.
-   */
-  void resolveVerticalSpace() {
-    if (verticalSpaceNeeded) {
-      writeln();
-      verticalSpaceNeeded = false;
-    }
-  }
-
-  /**
-   * Terminate the current word, if a word is in progress.
-   */
-  void wordBreak() {
-    if (word.isNotEmpty) {
-      atStart = false;
-      if (line.isNotEmpty) {
-        if (indentWidth + line.length + 1 + word.length <= width) {
-          line += ' $word';
-        } else {
-          writeln(line);
-          line = word;
-        }
-      } else {
-        line = word;
-      }
-      word = '';
-    }
-  }
-}
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index 2164c9f..2ccf00e 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -11,12 +11,12 @@
 
 import 'dart:convert';
 
+import 'package:analyzer/src/codegen/html.dart';
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
-import 'codegen_tools.dart';
 import 'from_html.dart';
-import 'html_tools.dart';
 
 /**
  * Embedded stylesheet
@@ -81,8 +81,9 @@
 }
 '''.trim();
 
-final GeneratedFile target = new GeneratedFile('../../doc/api.html', () {
-  ToHtmlVisitor visitor = new ToHtmlVisitor(readApi());
+final GeneratedFile target =
+    new GeneratedFile('doc/api.html', (String pkgPath) {
+  ToHtmlVisitor visitor = new ToHtmlVisitor(readApi(pkgPath));
   dom.Document document = new dom.Document();
   document.append(new dom.DocumentType('html', null, null));
   for (dom.Node node in visitor.collectHtml(visitor.visitApi)) {
@@ -92,13 +93,6 @@
 });
 
 /**
- * Translate spec_input.html into api.html.
- */
-main() {
-  target.generate();
-}
-
-/**
  * Visitor that records the mapping from HTML elements to various kinds of API
  * nodes.
  */
@@ -204,6 +198,106 @@
     }
   }
 
+  void generateDomainIndex(Domain domain) {
+    h4(() {
+      write(domain.name);
+      write(' (');
+      link('domain_${domain.name}', () => write('\u2191'));
+      write(')');
+    });
+    if (domain.requests.length > 0) {
+      element('div', {'class': 'subindex'}, () {
+        generateRequestsIndex(domain.requests);
+        if (domain.notifications.length > 0) {
+          generateNotificationsIndex(domain.notifications);
+        }
+      });
+    } else if (domain.notifications.length > 0) {
+      element('div', {'class': 'subindex'}, () {
+        generateNotificationsIndex(domain.notifications);
+      });
+    }
+  }
+
+  void generateIndex() {
+    h3(() => write('Domains'));
+    for (var domain in api.domains) {
+      if (domain.experimental ||
+          (domain.requests.length == 0 && domain.notifications == 0)) {
+        continue;
+      }
+      generateDomainIndex(domain);
+    }
+
+    generateTypesIndex(definedTypes);
+    generateRefactoringsIndex(api.refactorings);
+  }
+
+  void generateNotificationsIndex(Iterable<Notification> notifications) {
+    h5(() => write("Notifications"));
+    element('div', {'class': 'subindex'}, () {
+      element('ul', {}, () {
+        for (var notification in notifications) {
+          element(
+              'li',
+              {},
+              () => link('notification_${notification.longEvent}',
+                  () => write(notification.event)));
+        }
+      });
+    });
+  }
+
+  void generateRefactoringsIndex(Iterable<Refactoring> refactorings) {
+    h3(() {
+      write("Refactorings");
+      write(' (');
+      link('refactorings', () => write('\u2191'));
+      write(')');
+    });
+    // TODO: Individual refactorings are not yet hyperlinked.
+    element('div', {'class': 'subindex'}, () {
+      element('ul', {}, () {
+        for (var refactoring in refactorings) {
+          element(
+              'li',
+              {},
+              () => link('refactoring_${refactoring.kind}',
+                  () => write(refactoring.kind)));
+        }
+      });
+    });
+  }
+
+  void generateRequestsIndex(Iterable<Request> requests) {
+    h5(() => write("Requests"));
+    element('ul', {}, () {
+      for (var request in requests) {
+        element(
+            'li',
+            {},
+            () => link(
+                'request_${request.longMethod}', () => write(request.method)));
+      }
+    });
+  }
+
+  void generateTypesIndex(Set<String> types) {
+    h3(() {
+      write("Types");
+      write(' (');
+      link('types', () => write('\u2191'));
+      write(')');
+    });
+    element('div', {'class': 'subindex'}, () {
+      element('ul', {}, () {
+        for (var type in types) {
+          element('li', {}, () => link('type_$type', () => write(type)));
+        }
+      });
+    });
+  }
+
   void javadocParams(TypeObject typeObject) {
     if (typeObject != null) {
       for (TypeObjectField field in typeObject.fields) {
@@ -294,7 +388,9 @@
 
   @override
   void visitApi() {
-    definedTypes = api.types.keys.toSet();
+    Iterable<TypeDefinition> apiTypes =
+        api.types.where((TypeDefinition td) => !td.experimental);
+    definedTypes = apiTypes.map((TypeDefinition td) => td.name).toSet();
 
     html(() {
       translateHtml(api.html);
@@ -303,6 +399,9 @@
 
   @override
   void visitDomain(Domain domain) {
+    if (domain.experimental) {
+      return;
+    }
     h2('domain', () {
       anchor('domain_${domain.name}', () {
         write('Domain: ${domain.name}');
@@ -394,6 +493,9 @@
 
   @override
   void visitTypeDefinition(TypeDefinition typeDefinition) {
+    if (typeDefinition.experimental) {
+      return;
+    }
     dt('typeDefinition', () {
       anchor('type_${typeDefinition.name}', () {
         write('${typeDefinition.name}: ');
@@ -493,103 +595,6 @@
       super.visitTypes(types);
     });
   }
-
-  void generateIndex() {
-    h3(() => write('Domains'));
-    for (var domain in api.domains) {
-      if (domain.requests.length == 0 && domain.notifications == 0) continue;
-      generateDomainIndex(domain);
-    }
-
-    generateTypesIndex(definedTypes);
-    generateRefactoringsIndex(api.refactorings);
-  }
-
-  void generateDomainIndex(Domain domain) {
-    h4(() {
-      write(domain.name);
-      write(' (');
-      link('domain_${domain.name}', () => write('\u2191'));
-      write(')');
-    });
-    if (domain.requests.length > 0) {
-      element('div', {'class': 'subindex'}, () {
-        generateRequestsIndex(domain.requests);
-        if (domain.notifications.length > 0) {
-          generateNotificationsIndex(domain.notifications);
-        }
-      });
-    } else if (domain.notifications.length > 0) {
-      element('div', {'class': 'subindex'}, () {
-        generateNotificationsIndex(domain.notifications);
-      });
-    }
-  }
-
-  void generateRequestsIndex(Iterable<Request> requests) {
-    h5(() => write("Requests"));
-    element('ul', {}, () {
-      for (var request in requests) {
-        element(
-            'li',
-            {},
-            () => link(
-                'request_${request.longMethod}', () => write(request.method)));
-      }
-    });
-  }
-
-  void generateNotificationsIndex(Iterable<Notification> notifications) {
-    h5(() => write("Notifications"));
-    element('div', {'class': 'subindex'}, () {
-      element('ul', {}, () {
-        for (var notification in notifications) {
-          element(
-              'li',
-              {},
-              () => link('notification_${notification.longEvent}',
-                  () => write(notification.event)));
-        }
-      });
-    });
-  }
-
-  void generateTypesIndex(Set<String> types) {
-    h3(() {
-      write("Types");
-      write(' (');
-      link('types', () => write('\u2191'));
-      write(')');
-    });
-    element('div', {'class': 'subindex'}, () {
-      element('ul', {}, () {
-        for (var type in types) {
-          element('li', {}, () => link('type_$type', () => write(type)));
-        }
-      });
-    });
-  }
-
-  void generateRefactoringsIndex(Iterable<Refactoring> refactorings) {
-    h3(() {
-      write("Refactorings");
-      write(' (');
-      link('refactorings', () => write('\u2191'));
-      write(')');
-    });
-    // TODO: Individual refactorings are not yet hyperlinked.
-    element('div', {'class': 'subindex'}, () {
-      element('ul', {}, () {
-        for (var refactoring in refactorings) {
-          element(
-              'li',
-              {},
-              () => link('refactoring_${refactoring.kind}',
-                  () => write(refactoring.kind)));
-        }
-      });
-    });
-  }
 }
 
 /**
diff --git a/pkg/analyzer/.analysis_options b/pkg/analyzer/.analysis_options
new file mode 100644
index 0000000..7b230dd
--- /dev/null
+++ b/pkg/analyzer/.analysis_options
@@ -0,0 +1,4 @@
+linter:
+  rules:
+    - unnecessary_brace_in_string_interp
+    - empty_constructor_bodies
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 4f4165d..d7e871c 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,29 @@
+## 0.27.1
+* Moved the public and private API's for the element model into their proper places.
+* Added back support for auto-processing of plugins.
+
+## 0.27.0
+* Support for DEP 37 (Assert with optional message).
+* Lexical support for DEP 40 (Interface libraries). This does not include any semantic checking to ensure that the
+  implementation libraries are compatible with the interface library.
+* Cleaned up the initialization of plugins. Clients are now required to initialize plugins, possibly using the utility
+  method AnalysisEngine.processRequiredPlugins().
+* Removed the old task model and code that supported it. None of the removed code was intended to be public API, but
+  might be in use anyway.
+* Removed previously deprecated API's (marked with the @deprecated annotation).
+
+## 0.26.4
+* Options processing API updated to accept untyped options maps (#25126).
+
+## 0.26.3
+* (Internal) Support for `_embedder.yaml` discovery and processing.
+
+## 0.26.2
+* Add code generation utilities for use in both analyzer and analysis server.
+
+## 0.26.1+17
+* (Internal) Introduced context configuration logic (`configureContext()` extracted from server).
+
 ## 0.26.1+16
 * (Internal) Options validation plugin API update.
 
@@ -79,7 +105,7 @@
 
 ## 0.25.2-alpha.0
 
-* Initial support for analyzing `dart:sdk` extensions from `.sdkext`. 
+* Initial support for analyzing `dart:sdk` extensions from `.sdkext`.
 
 ## 0.25.1
 
@@ -103,7 +129,7 @@
 ## 0.22.0
 
   New API:
-  
+
 * `Source.uri` added.
 
   Breaking changes:
diff --git a/pkg/analyzer/example/resolver_driver.dart b/pkg/analyzer/example/resolver_driver.dart
index 59e66e7..74ed79c 100755
--- a/pkg/analyzer/example/resolver_driver.dart
+++ b/pkg/analyzer/example/resolver_driver.dart
@@ -5,8 +5,8 @@
 
 import 'dart:io';
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index 83a72a1..d0fdc65 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -6,20 +6,19 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/error.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/string_source.dart';
 import 'package:path/path.dart' as pathos;
 
-import 'src/error.dart';
-import 'src/generated/ast.dart';
-import 'src/generated/error.dart';
-import 'src/generated/parser.dart';
-import 'src/generated/scanner.dart';
-import 'src/generated/source_io.dart';
-import 'src/string_source.dart';
-
-export 'src/error.dart';
-export 'src/generated/ast.dart';
-export 'src/generated/error.dart';
-export 'src/generated/utilities_dart.dart';
+export 'package:analyzer/src/error.dart';
+export 'package:analyzer/src/generated/ast.dart';
+export 'package:analyzer/src/generated/error.dart';
+export 'package:analyzer/src/generated/utilities_dart.dart';
 
 /// Parses a string of Dart code into an AST.
 ///
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
new file mode 100644
index 0000000..c9b345a
--- /dev/null
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -0,0 +1,1884 @@
+// 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 analyzer.dart.ast.visitor;
+
+import 'dart:collection';
+
+import 'package:analyzer/src/generated/ast.dart';
+
+/**
+ * An AST visitor that will recursively visit all of the nodes in an AST
+ * structure, similar to [GeneralizingAstVisitor]. This visitor uses a
+ * breadth-first ordering rather than the depth-first ordering of
+ * [GeneralizingAstVisitor].
+ *
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or explicitly invoke the more general visit method. Failure to
+ * do so will cause the visit methods for superclasses of the node to not be
+ * invoked and will cause the children of the visited node to not be visited.
+ *
+ * In addition, subclasses should <b>not</b> explicitly visit the children of a
+ * node, but should ensure that the method [visitNode] is used to visit the
+ * children (either directly or indirectly). Failure to do will break the order
+ * in which nodes are visited.
+ *
+ * Note that, unlike other visitors that begin to visit a structure of nodes by
+ * asking the root node in the structure to accept the visitor, this visitor
+ * requires that clients start the visit by invoking the method [visitAllNodes]
+ * defined on the visitor with the root node as the argument:
+ *
+ *     visitor.visitAllNodes(rootNode);
+ *
+ * Clients may extend or implement this class.
+ */
+class BreadthFirstVisitor<R> extends GeneralizingAstVisitor<R> {
+  /**
+   * A queue holding the nodes that have not yet been visited in the order in
+   * which they ought to be visited.
+   */
+  Queue<AstNode> _queue = new Queue<AstNode>();
+
+  /**
+   * A visitor, used to visit the children of the current node, that will add
+   * the nodes it visits to the [_queue].
+   */
+  _BreadthFirstChildVisitor _childVisitor;
+
+  /**
+   * Initialize a newly created visitor.
+   */
+  BreadthFirstVisitor() {
+    _childVisitor = new _BreadthFirstChildVisitor(this);
+  }
+
+  /**
+   * Visit all nodes in the tree starting at the given [root] node, in
+   * breadth-first order.
+   */
+  void visitAllNodes(AstNode root) {
+    _queue.add(root);
+    while (!_queue.isEmpty) {
+      AstNode next = _queue.removeFirst();
+      next.accept(this);
+    }
+  }
+
+  @override
+  R visitNode(AstNode node) {
+    node.visitChildren(_childVisitor);
+    return null;
+  }
+}
+
+/**
+ * An AST visitor that will recursively visit all of the nodes in an AST
+ * structure (like instances of the class [RecursiveAstVisitor]). In addition,
+ * when a node of a specific type is visited not only will the visit method for
+ * that specific type of node be invoked, but additional methods for the
+ * superclasses of that node will also be invoked. For example, using an
+ * instance of this class to visit a [Block] will cause the method [visitBlock]
+ * to be invoked but will also cause the methods [visitStatement] and
+ * [visitNode] to be subsequently invoked. This allows visitors to be written
+ * that visit all statements without needing to override the visit method for
+ * each of the specific subclasses of [Statement].
+ *
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or explicitly invoke the more general visit method. Failure to
+ * do so will cause the visit methods for superclasses of the node to not be
+ * invoked and will cause the children of the visited node to not be visited.
+ *
+ * Clients may extend or implement this class.
+ */
+class GeneralizingAstVisitor<R> implements AstVisitor<R> {
+  @override
+  R visitAdjacentStrings(AdjacentStrings node) => visitStringLiteral(node);
+
+  R visitAnnotatedNode(AnnotatedNode node) => visitNode(node);
+
+  @override
+  R visitAnnotation(Annotation node) => visitNode(node);
+
+  @override
+  R visitArgumentList(ArgumentList node) => visitNode(node);
+
+  @override
+  R visitAsExpression(AsExpression node) => visitExpression(node);
+
+  @override
+  R visitAssertStatement(AssertStatement node) => visitStatement(node);
+
+  @override
+  R visitAssignmentExpression(AssignmentExpression node) =>
+      visitExpression(node);
+
+  @override
+  R visitAwaitExpression(AwaitExpression node) => visitExpression(node);
+
+  @override
+  R visitBinaryExpression(BinaryExpression node) => visitExpression(node);
+
+  @override
+  R visitBlock(Block node) => visitStatement(node);
+
+  @override
+  R visitBlockFunctionBody(BlockFunctionBody node) => visitFunctionBody(node);
+
+  @override
+  R visitBooleanLiteral(BooleanLiteral node) => visitLiteral(node);
+
+  @override
+  R visitBreakStatement(BreakStatement node) => visitStatement(node);
+
+  @override
+  R visitCascadeExpression(CascadeExpression node) => visitExpression(node);
+
+  @override
+  R visitCatchClause(CatchClause node) => visitNode(node);
+
+  @override
+  R visitClassDeclaration(ClassDeclaration node) =>
+      visitNamedCompilationUnitMember(node);
+
+  R visitClassMember(ClassMember node) => visitDeclaration(node);
+
+  @override
+  R visitClassTypeAlias(ClassTypeAlias node) => visitTypeAlias(node);
+
+  R visitCombinator(Combinator node) => visitNode(node);
+
+  @override
+  R visitComment(Comment node) => visitNode(node);
+
+  @override
+  R visitCommentReference(CommentReference node) => visitNode(node);
+
+  @override
+  R visitCompilationUnit(CompilationUnit node) => visitNode(node);
+
+  R visitCompilationUnitMember(CompilationUnitMember node) =>
+      visitDeclaration(node);
+
+  @override
+  R visitConditionalExpression(ConditionalExpression node) =>
+      visitExpression(node);
+
+  @override
+  R visitConfiguration(Configuration node) => visitNode(node);
+
+  @override
+  R visitConstructorDeclaration(ConstructorDeclaration node) =>
+      visitClassMember(node);
+
+  @override
+  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) =>
+      visitConstructorInitializer(node);
+
+  R visitConstructorInitializer(ConstructorInitializer node) => visitNode(node);
+
+  @override
+  R visitConstructorName(ConstructorName node) => visitNode(node);
+
+  @override
+  R visitContinueStatement(ContinueStatement node) => visitStatement(node);
+
+  R visitDeclaration(Declaration node) => visitAnnotatedNode(node);
+
+  @override
+  R visitDeclaredIdentifier(DeclaredIdentifier node) => visitDeclaration(node);
+
+  @override
+  R visitDefaultFormalParameter(DefaultFormalParameter node) =>
+      visitFormalParameter(node);
+
+  R visitDirective(Directive node) => visitAnnotatedNode(node);
+
+  @override
+  R visitDoStatement(DoStatement node) => visitStatement(node);
+
+  @override
+  R visitDottedName(DottedName node) => visitNode(node);
+
+  @override
+  R visitDoubleLiteral(DoubleLiteral node) => visitLiteral(node);
+
+  @override
+  R visitEmptyFunctionBody(EmptyFunctionBody node) => visitFunctionBody(node);
+
+  @override
+  R visitEmptyStatement(EmptyStatement node) => visitStatement(node);
+
+  @override
+  R visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
+      visitDeclaration(node);
+
+  @override
+  R visitEnumDeclaration(EnumDeclaration node) =>
+      visitNamedCompilationUnitMember(node);
+
+  @override
+  R visitExportDirective(ExportDirective node) => visitNamespaceDirective(node);
+
+  R visitExpression(Expression node) => visitNode(node);
+
+  @override
+  R visitExpressionFunctionBody(ExpressionFunctionBody node) =>
+      visitFunctionBody(node);
+
+  @override
+  R visitExpressionStatement(ExpressionStatement node) => visitStatement(node);
+
+  @override
+  R visitExtendsClause(ExtendsClause node) => visitNode(node);
+
+  @override
+  R visitFieldDeclaration(FieldDeclaration node) => visitClassMember(node);
+
+  @override
+  R visitFieldFormalParameter(FieldFormalParameter node) =>
+      visitNormalFormalParameter(node);
+
+  @override
+  R visitForEachStatement(ForEachStatement node) => visitStatement(node);
+
+  R visitFormalParameter(FormalParameter node) => visitNode(node);
+
+  @override
+  R visitFormalParameterList(FormalParameterList node) => visitNode(node);
+
+  @override
+  R visitForStatement(ForStatement node) => visitStatement(node);
+
+  R visitFunctionBody(FunctionBody node) => visitNode(node);
+
+  @override
+  R visitFunctionDeclaration(FunctionDeclaration node) =>
+      visitNamedCompilationUnitMember(node);
+
+  @override
+  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) =>
+      visitStatement(node);
+
+  @override
+  R visitFunctionExpression(FunctionExpression node) => visitExpression(node);
+
+  @override
+  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) =>
+      visitExpression(node);
+
+  @override
+  R visitFunctionTypeAlias(FunctionTypeAlias node) => visitTypeAlias(node);
+
+  @override
+  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) =>
+      visitNormalFormalParameter(node);
+
+  @override
+  R visitHideCombinator(HideCombinator node) => visitCombinator(node);
+
+  R visitIdentifier(Identifier node) => visitExpression(node);
+
+  @override
+  R visitIfStatement(IfStatement node) => visitStatement(node);
+
+  @override
+  R visitImplementsClause(ImplementsClause node) => visitNode(node);
+
+  @override
+  R visitImportDirective(ImportDirective node) => visitNamespaceDirective(node);
+
+  @override
+  R visitIndexExpression(IndexExpression node) => visitExpression(node);
+
+  @override
+  R visitInstanceCreationExpression(InstanceCreationExpression node) =>
+      visitExpression(node);
+
+  @override
+  R visitIntegerLiteral(IntegerLiteral node) => visitLiteral(node);
+
+  R visitInterpolationElement(InterpolationElement node) => visitNode(node);
+
+  @override
+  R visitInterpolationExpression(InterpolationExpression node) =>
+      visitInterpolationElement(node);
+
+  @override
+  R visitInterpolationString(InterpolationString node) =>
+      visitInterpolationElement(node);
+
+  @override
+  R visitIsExpression(IsExpression node) => visitExpression(node);
+
+  @override
+  R visitLabel(Label node) => visitNode(node);
+
+  @override
+  R visitLabeledStatement(LabeledStatement node) => visitStatement(node);
+
+  @override
+  R visitLibraryDirective(LibraryDirective node) => visitDirective(node);
+
+  @override
+  R visitLibraryIdentifier(LibraryIdentifier node) => visitIdentifier(node);
+
+  @override
+  R visitListLiteral(ListLiteral node) => visitTypedLiteral(node);
+
+  R visitLiteral(Literal node) => visitExpression(node);
+
+  @override
+  R visitMapLiteral(MapLiteral node) => visitTypedLiteral(node);
+
+  @override
+  R visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
+
+  @override
+  R visitMethodDeclaration(MethodDeclaration node) => visitClassMember(node);
+
+  @override
+  R visitMethodInvocation(MethodInvocation node) => visitExpression(node);
+
+  R visitNamedCompilationUnitMember(NamedCompilationUnitMember node) =>
+      visitCompilationUnitMember(node);
+
+  @override
+  R visitNamedExpression(NamedExpression node) => visitExpression(node);
+
+  R visitNamespaceDirective(NamespaceDirective node) =>
+      visitUriBasedDirective(node);
+
+  @override
+  R visitNativeClause(NativeClause node) => visitNode(node);
+
+  @override
+  R visitNativeFunctionBody(NativeFunctionBody node) => visitFunctionBody(node);
+
+  R visitNode(AstNode node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  R visitNormalFormalParameter(NormalFormalParameter node) =>
+      visitFormalParameter(node);
+
+  @override
+  R visitNullLiteral(NullLiteral node) => visitLiteral(node);
+
+  @override
+  R visitParenthesizedExpression(ParenthesizedExpression node) =>
+      visitExpression(node);
+
+  @override
+  R visitPartDirective(PartDirective node) => visitUriBasedDirective(node);
+
+  @override
+  R visitPartOfDirective(PartOfDirective node) => visitDirective(node);
+
+  @override
+  R visitPostfixExpression(PostfixExpression node) => visitExpression(node);
+
+  @override
+  R visitPrefixedIdentifier(PrefixedIdentifier node) => visitIdentifier(node);
+
+  @override
+  R visitPrefixExpression(PrefixExpression node) => visitExpression(node);
+
+  @override
+  R visitPropertyAccess(PropertyAccess node) => visitExpression(node);
+
+  @override
+  R visitRedirectingConstructorInvocation(
+          RedirectingConstructorInvocation node) =>
+      visitConstructorInitializer(node);
+
+  @override
+  R visitRethrowExpression(RethrowExpression node) => visitExpression(node);
+
+  @override
+  R visitReturnStatement(ReturnStatement node) => visitStatement(node);
+
+  @override
+  R visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
+
+  @override
+  R visitShowCombinator(ShowCombinator node) => visitCombinator(node);
+
+  @override
+  R visitSimpleFormalParameter(SimpleFormalParameter node) =>
+      visitNormalFormalParameter(node);
+
+  @override
+  R visitSimpleIdentifier(SimpleIdentifier node) => visitIdentifier(node);
+
+  @override
+  R visitSimpleStringLiteral(SimpleStringLiteral node) =>
+      visitSingleStringLiteral(node);
+
+  R visitSingleStringLiteral(SingleStringLiteral node) =>
+      visitStringLiteral(node);
+
+  R visitStatement(Statement node) => visitNode(node);
+
+  @override
+  R visitStringInterpolation(StringInterpolation node) =>
+      visitSingleStringLiteral(node);
+
+  R visitStringLiteral(StringLiteral node) => visitLiteral(node);
+
+  @override
+  R visitSuperConstructorInvocation(SuperConstructorInvocation node) =>
+      visitConstructorInitializer(node);
+
+  @override
+  R visitSuperExpression(SuperExpression node) => visitExpression(node);
+
+  @override
+  R visitSwitchCase(SwitchCase node) => visitSwitchMember(node);
+
+  @override
+  R visitSwitchDefault(SwitchDefault node) => visitSwitchMember(node);
+
+  R visitSwitchMember(SwitchMember node) => visitNode(node);
+
+  @override
+  R visitSwitchStatement(SwitchStatement node) => visitStatement(node);
+
+  @override
+  R visitSymbolLiteral(SymbolLiteral node) => visitLiteral(node);
+
+  @override
+  R visitThisExpression(ThisExpression node) => visitExpression(node);
+
+  @override
+  R visitThrowExpression(ThrowExpression node) => visitExpression(node);
+
+  @override
+  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) =>
+      visitCompilationUnitMember(node);
+
+  @override
+  R visitTryStatement(TryStatement node) => visitStatement(node);
+
+  R visitTypeAlias(TypeAlias node) => visitNamedCompilationUnitMember(node);
+
+  @override
+  R visitTypeArgumentList(TypeArgumentList node) => visitNode(node);
+
+  R visitTypedLiteral(TypedLiteral node) => visitLiteral(node);
+
+  @override
+  R visitTypeName(TypeName node) => visitNode(node);
+
+  @override
+  R visitTypeParameter(TypeParameter node) => visitNode(node);
+
+  @override
+  R visitTypeParameterList(TypeParameterList node) => visitNode(node);
+
+  R visitUriBasedDirective(UriBasedDirective node) => visitDirective(node);
+
+  @override
+  R visitVariableDeclaration(VariableDeclaration node) =>
+      visitDeclaration(node);
+
+  @override
+  R visitVariableDeclarationList(VariableDeclarationList node) =>
+      visitNode(node);
+
+  @override
+  R visitVariableDeclarationStatement(VariableDeclarationStatement node) =>
+      visitStatement(node);
+
+  @override
+  R visitWhileStatement(WhileStatement node) => visitStatement(node);
+
+  @override
+  R visitWithClause(WithClause node) => visitNode(node);
+
+  @override
+  R visitYieldStatement(YieldStatement node) => visitStatement(node);
+}
+
+/**
+ * An AST visitor that will recursively visit all of the nodes in an AST
+ * structure. For example, using an instance of this class to visit a [Block]
+ * will also cause all of the statements in the block to be visited.
+ *
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or must explicitly ask the visited node to visit its children.
+ * Failure to do so will cause the children of the visited node to not be
+ * visited.
+ *
+ * Clients may extend or implement this class.
+ */
+class RecursiveAstVisitor<R> implements AstVisitor<R> {
+  @override
+  R visitAdjacentStrings(AdjacentStrings node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitAnnotation(Annotation node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitArgumentList(ArgumentList node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitAsExpression(AsExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitAssertStatement(AssertStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitAssignmentExpression(AssignmentExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitAwaitExpression(AwaitExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitBinaryExpression(BinaryExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitBlock(Block node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitBlockFunctionBody(BlockFunctionBody node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitBooleanLiteral(BooleanLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitBreakStatement(BreakStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitCascadeExpression(CascadeExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitCatchClause(CatchClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitClassDeclaration(ClassDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitClassTypeAlias(ClassTypeAlias node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitComment(Comment node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitCommentReference(CommentReference node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitCompilationUnit(CompilationUnit node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitConditionalExpression(ConditionalExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitConfiguration(Configuration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitConstructorDeclaration(ConstructorDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitConstructorName(ConstructorName node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitContinueStatement(ContinueStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitDeclaredIdentifier(DeclaredIdentifier node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitDefaultFormalParameter(DefaultFormalParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitDoStatement(DoStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitDottedName(DottedName node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitDoubleLiteral(DoubleLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitEmptyFunctionBody(EmptyFunctionBody node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitEmptyStatement(EmptyStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitEnumDeclaration(EnumDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitExportDirective(ExportDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitExpressionStatement(ExpressionStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitExtendsClause(ExtendsClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFieldDeclaration(FieldDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFieldFormalParameter(FieldFormalParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitForEachStatement(ForEachStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFormalParameterList(FormalParameterList node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitForStatement(ForStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionDeclaration(FunctionDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionExpression(FunctionExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionTypeAlias(FunctionTypeAlias node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitHideCombinator(HideCombinator node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitIfStatement(IfStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitImplementsClause(ImplementsClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitImportDirective(ImportDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitIndexExpression(IndexExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitInstanceCreationExpression(InstanceCreationExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitIntegerLiteral(IntegerLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitInterpolationExpression(InterpolationExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitInterpolationString(InterpolationString node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitIsExpression(IsExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLabel(Label node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLabeledStatement(LabeledStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLibraryDirective(LibraryDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLibraryIdentifier(LibraryIdentifier node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitListLiteral(ListLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitMapLiteral(MapLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitMapLiteralEntry(MapLiteralEntry node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitMethodDeclaration(MethodDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitMethodInvocation(MethodInvocation node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitNamedExpression(NamedExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitNativeClause(NativeClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitNativeFunctionBody(NativeFunctionBody node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitNullLiteral(NullLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitParenthesizedExpression(ParenthesizedExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPartDirective(PartDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPartOfDirective(PartOfDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPostfixExpression(PostfixExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPrefixedIdentifier(PrefixedIdentifier node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPrefixExpression(PrefixExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPropertyAccess(PropertyAccess node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitRethrowExpression(RethrowExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitReturnStatement(ReturnStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitScriptTag(ScriptTag node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitShowCombinator(ShowCombinator node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitSimpleFormalParameter(SimpleFormalParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitSimpleIdentifier(SimpleIdentifier node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitSimpleStringLiteral(SimpleStringLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitStringInterpolation(StringInterpolation node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitSuperExpression(SuperExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitSwitchCase(SwitchCase node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitSwitchDefault(SwitchDefault node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitSwitchStatement(SwitchStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitSymbolLiteral(SymbolLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitThisExpression(ThisExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitThrowExpression(ThrowExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTryStatement(TryStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTypeArgumentList(TypeArgumentList node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTypeName(TypeName node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTypeParameter(TypeParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTypeParameterList(TypeParameterList node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitVariableDeclaration(VariableDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitVariableDeclarationList(VariableDeclarationList node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitWhileStatement(WhileStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitWithClause(WithClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitYieldStatement(YieldStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+}
+
+/**
+ * An AST visitor that will do nothing when visiting an AST node. It is intended
+ * to be a superclass for classes that use the visitor pattern primarily as a
+ * dispatch mechanism (and hence don't need to recursively visit a whole
+ * structure) and that only need to visit a small number of node types.
+ *
+ * Clients may extend or implement this class.
+ */
+class SimpleAstVisitor<R> implements AstVisitor<R> {
+  @override
+  R visitAdjacentStrings(AdjacentStrings node) => null;
+
+  @override
+  R visitAnnotation(Annotation node) => null;
+
+  @override
+  R visitArgumentList(ArgumentList node) => null;
+
+  @override
+  R visitAsExpression(AsExpression node) => null;
+
+  @override
+  R visitAssertStatement(AssertStatement node) => null;
+
+  @override
+  R visitAssignmentExpression(AssignmentExpression node) => null;
+
+  @override
+  R visitAwaitExpression(AwaitExpression node) => null;
+
+  @override
+  R visitBinaryExpression(BinaryExpression node) => null;
+
+  @override
+  R visitBlock(Block node) => null;
+
+  @override
+  R visitBlockFunctionBody(BlockFunctionBody node) => null;
+
+  @override
+  R visitBooleanLiteral(BooleanLiteral node) => null;
+
+  @override
+  R visitBreakStatement(BreakStatement node) => null;
+
+  @override
+  R visitCascadeExpression(CascadeExpression node) => null;
+
+  @override
+  R visitCatchClause(CatchClause node) => null;
+
+  @override
+  R visitClassDeclaration(ClassDeclaration node) => null;
+
+  @override
+  R visitClassTypeAlias(ClassTypeAlias node) => null;
+
+  @override
+  R visitComment(Comment node) => null;
+
+  @override
+  R visitCommentReference(CommentReference node) => null;
+
+  @override
+  R visitCompilationUnit(CompilationUnit node) => null;
+
+  @override
+  R visitConditionalExpression(ConditionalExpression node) => null;
+
+  @override
+  R visitConfiguration(Configuration node) => null;
+
+  @override
+  R visitConstructorDeclaration(ConstructorDeclaration node) => null;
+
+  @override
+  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) => null;
+
+  @override
+  R visitConstructorName(ConstructorName node) => null;
+
+  @override
+  R visitContinueStatement(ContinueStatement node) => null;
+
+  @override
+  R visitDeclaredIdentifier(DeclaredIdentifier node) => null;
+
+  @override
+  R visitDefaultFormalParameter(DefaultFormalParameter node) => null;
+
+  @override
+  R visitDoStatement(DoStatement node) => null;
+
+  @override
+  R visitDottedName(DottedName node) => null;
+
+  @override
+  R visitDoubleLiteral(DoubleLiteral node) => null;
+
+  @override
+  R visitEmptyFunctionBody(EmptyFunctionBody node) => null;
+
+  @override
+  R visitEmptyStatement(EmptyStatement node) => null;
+
+  @override
+  R visitEnumConstantDeclaration(EnumConstantDeclaration node) => null;
+
+  @override
+  R visitEnumDeclaration(EnumDeclaration node) => null;
+
+  @override
+  R visitExportDirective(ExportDirective node) => null;
+
+  @override
+  R visitExpressionFunctionBody(ExpressionFunctionBody node) => null;
+
+  @override
+  R visitExpressionStatement(ExpressionStatement node) => null;
+
+  @override
+  R visitExtendsClause(ExtendsClause node) => null;
+
+  @override
+  R visitFieldDeclaration(FieldDeclaration node) => null;
+
+  @override
+  R visitFieldFormalParameter(FieldFormalParameter node) => null;
+
+  @override
+  R visitForEachStatement(ForEachStatement node) => null;
+
+  @override
+  R visitFormalParameterList(FormalParameterList node) => null;
+
+  @override
+  R visitForStatement(ForStatement node) => null;
+
+  @override
+  R visitFunctionDeclaration(FunctionDeclaration node) => null;
+
+  @override
+  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) =>
+      null;
+
+  @override
+  R visitFunctionExpression(FunctionExpression node) => null;
+
+  @override
+  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) =>
+      null;
+
+  @override
+  R visitFunctionTypeAlias(FunctionTypeAlias node) => null;
+
+  @override
+  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) =>
+      null;
+
+  @override
+  R visitHideCombinator(HideCombinator node) => null;
+
+  @override
+  R visitIfStatement(IfStatement node) => null;
+
+  @override
+  R visitImplementsClause(ImplementsClause node) => null;
+
+  @override
+  R visitImportDirective(ImportDirective node) => null;
+
+  @override
+  R visitIndexExpression(IndexExpression node) => null;
+
+  @override
+  R visitInstanceCreationExpression(InstanceCreationExpression node) => null;
+
+  @override
+  R visitIntegerLiteral(IntegerLiteral node) => null;
+
+  @override
+  R visitInterpolationExpression(InterpolationExpression node) => null;
+
+  @override
+  R visitInterpolationString(InterpolationString node) => null;
+
+  @override
+  R visitIsExpression(IsExpression node) => null;
+
+  @override
+  R visitLabel(Label node) => null;
+
+  @override
+  R visitLabeledStatement(LabeledStatement node) => null;
+
+  @override
+  R visitLibraryDirective(LibraryDirective node) => null;
+
+  @override
+  R visitLibraryIdentifier(LibraryIdentifier node) => null;
+
+  @override
+  R visitListLiteral(ListLiteral node) => null;
+
+  @override
+  R visitMapLiteral(MapLiteral node) => null;
+
+  @override
+  R visitMapLiteralEntry(MapLiteralEntry node) => null;
+
+  @override
+  R visitMethodDeclaration(MethodDeclaration node) => null;
+
+  @override
+  R visitMethodInvocation(MethodInvocation node) => null;
+
+  @override
+  R visitNamedExpression(NamedExpression node) => null;
+
+  @override
+  R visitNativeClause(NativeClause node) => null;
+
+  @override
+  R visitNativeFunctionBody(NativeFunctionBody node) => null;
+
+  @override
+  R visitNullLiteral(NullLiteral node) => null;
+
+  @override
+  R visitParenthesizedExpression(ParenthesizedExpression node) => null;
+
+  @override
+  R visitPartDirective(PartDirective node) => null;
+
+  @override
+  R visitPartOfDirective(PartOfDirective node) => null;
+
+  @override
+  R visitPostfixExpression(PostfixExpression node) => null;
+
+  @override
+  R visitPrefixedIdentifier(PrefixedIdentifier node) => null;
+
+  @override
+  R visitPrefixExpression(PrefixExpression node) => null;
+
+  @override
+  R visitPropertyAccess(PropertyAccess node) => null;
+
+  @override
+  R visitRedirectingConstructorInvocation(
+          RedirectingConstructorInvocation node) =>
+      null;
+
+  @override
+  R visitRethrowExpression(RethrowExpression node) => null;
+
+  @override
+  R visitReturnStatement(ReturnStatement node) => null;
+
+  @override
+  R visitScriptTag(ScriptTag node) => null;
+
+  @override
+  R visitShowCombinator(ShowCombinator node) => null;
+
+  @override
+  R visitSimpleFormalParameter(SimpleFormalParameter node) => null;
+
+  @override
+  R visitSimpleIdentifier(SimpleIdentifier node) => null;
+
+  @override
+  R visitSimpleStringLiteral(SimpleStringLiteral node) => null;
+
+  @override
+  R visitStringInterpolation(StringInterpolation node) => null;
+
+  @override
+  R visitSuperConstructorInvocation(SuperConstructorInvocation node) => null;
+
+  @override
+  R visitSuperExpression(SuperExpression node) => null;
+
+  @override
+  R visitSwitchCase(SwitchCase node) => null;
+
+  @override
+  R visitSwitchDefault(SwitchDefault node) => null;
+
+  @override
+  R visitSwitchStatement(SwitchStatement node) => null;
+
+  @override
+  R visitSymbolLiteral(SymbolLiteral node) => null;
+
+  @override
+  R visitThisExpression(ThisExpression node) => null;
+
+  @override
+  R visitThrowExpression(ThrowExpression node) => null;
+
+  @override
+  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) => null;
+
+  @override
+  R visitTryStatement(TryStatement node) => null;
+
+  @override
+  R visitTypeArgumentList(TypeArgumentList node) => null;
+
+  @override
+  R visitTypeName(TypeName node) => null;
+
+  @override
+  R visitTypeParameter(TypeParameter node) => null;
+
+  @override
+  R visitTypeParameterList(TypeParameterList node) => null;
+
+  @override
+  R visitVariableDeclaration(VariableDeclaration node) => null;
+
+  @override
+  R visitVariableDeclarationList(VariableDeclarationList node) => null;
+
+  @override
+  R visitVariableDeclarationStatement(VariableDeclarationStatement node) =>
+      null;
+
+  @override
+  R visitWhileStatement(WhileStatement node) => null;
+
+  @override
+  R visitWithClause(WithClause node) => null;
+
+  @override
+  R visitYieldStatement(YieldStatement node) => null;
+}
+
+/**
+ * An AST visitor that will recursively visit all of the nodes in an AST
+ * structure (like instances of the class [RecursiveAstVisitor]). In addition,
+ * every node will also be visited by using a single unified [visitNode] method.
+ *
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or explicitly invoke the more general [visitNode] method.
+ * Failure to do so will cause the children of the visited node to not be
+ * visited.
+ *
+ * Clients may extend or implement this class.
+ */
+class UnifyingAstVisitor<R> implements AstVisitor<R> {
+  @override
+  R visitAdjacentStrings(AdjacentStrings node) => visitNode(node);
+
+  @override
+  R visitAnnotation(Annotation node) => visitNode(node);
+
+  @override
+  R visitArgumentList(ArgumentList node) => visitNode(node);
+
+  @override
+  R visitAsExpression(AsExpression node) => visitNode(node);
+
+  @override
+  R visitAssertStatement(AssertStatement node) => visitNode(node);
+
+  @override
+  R visitAssignmentExpression(AssignmentExpression node) => visitNode(node);
+
+  @override
+  R visitAwaitExpression(AwaitExpression node) => visitNode(node);
+
+  @override
+  R visitBinaryExpression(BinaryExpression node) => visitNode(node);
+
+  @override
+  R visitBlock(Block node) => visitNode(node);
+
+  @override
+  R visitBlockFunctionBody(BlockFunctionBody node) => visitNode(node);
+
+  @override
+  R visitBooleanLiteral(BooleanLiteral node) => visitNode(node);
+
+  @override
+  R visitBreakStatement(BreakStatement node) => visitNode(node);
+
+  @override
+  R visitCascadeExpression(CascadeExpression node) => visitNode(node);
+
+  @override
+  R visitCatchClause(CatchClause node) => visitNode(node);
+
+  @override
+  R visitClassDeclaration(ClassDeclaration node) => visitNode(node);
+
+  @override
+  R visitClassTypeAlias(ClassTypeAlias node) => visitNode(node);
+
+  @override
+  R visitComment(Comment node) => visitNode(node);
+
+  @override
+  R visitCommentReference(CommentReference node) => visitNode(node);
+
+  @override
+  R visitCompilationUnit(CompilationUnit node) => visitNode(node);
+
+  @override
+  R visitConditionalExpression(ConditionalExpression node) => visitNode(node);
+
+  @override
+  R visitConfiguration(Configuration node) => visitNode(node);
+
+  @override
+  R visitConstructorDeclaration(ConstructorDeclaration node) => visitNode(node);
+
+  @override
+  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) =>
+      visitNode(node);
+
+  @override
+  R visitConstructorName(ConstructorName node) => visitNode(node);
+
+  @override
+  R visitContinueStatement(ContinueStatement node) => visitNode(node);
+
+  @override
+  R visitDeclaredIdentifier(DeclaredIdentifier node) => visitNode(node);
+
+  @override
+  R visitDefaultFormalParameter(DefaultFormalParameter node) => visitNode(node);
+
+  @override
+  R visitDoStatement(DoStatement node) => visitNode(node);
+
+  @override
+  R visitDottedName(DottedName node) => visitNode(node);
+
+  @override
+  R visitDoubleLiteral(DoubleLiteral node) => visitNode(node);
+
+  @override
+  R visitEmptyFunctionBody(EmptyFunctionBody node) => visitNode(node);
+
+  @override
+  R visitEmptyStatement(EmptyStatement node) => visitNode(node);
+
+  @override
+  R visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
+      visitNode(node);
+
+  @override
+  R visitEnumDeclaration(EnumDeclaration node) => visitNode(node);
+
+  @override
+  R visitExportDirective(ExportDirective node) => visitNode(node);
+
+  @override
+  R visitExpressionFunctionBody(ExpressionFunctionBody node) => visitNode(node);
+
+  @override
+  R visitExpressionStatement(ExpressionStatement node) => visitNode(node);
+
+  @override
+  R visitExtendsClause(ExtendsClause node) => visitNode(node);
+
+  @override
+  R visitFieldDeclaration(FieldDeclaration node) => visitNode(node);
+
+  @override
+  R visitFieldFormalParameter(FieldFormalParameter node) => visitNode(node);
+
+  @override
+  R visitForEachStatement(ForEachStatement node) => visitNode(node);
+
+  @override
+  R visitFormalParameterList(FormalParameterList node) => visitNode(node);
+
+  @override
+  R visitForStatement(ForStatement node) => visitNode(node);
+
+  @override
+  R visitFunctionDeclaration(FunctionDeclaration node) => visitNode(node);
+
+  @override
+  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) =>
+      visitNode(node);
+
+  @override
+  R visitFunctionExpression(FunctionExpression node) => visitNode(node);
+
+  @override
+  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) =>
+      visitNode(node);
+
+  @override
+  R visitFunctionTypeAlias(FunctionTypeAlias node) => visitNode(node);
+
+  @override
+  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) =>
+      visitNode(node);
+
+  @override
+  R visitHideCombinator(HideCombinator node) => visitNode(node);
+
+  @override
+  R visitIfStatement(IfStatement node) => visitNode(node);
+
+  @override
+  R visitImplementsClause(ImplementsClause node) => visitNode(node);
+
+  @override
+  R visitImportDirective(ImportDirective node) => visitNode(node);
+
+  @override
+  R visitIndexExpression(IndexExpression node) => visitNode(node);
+
+  @override
+  R visitInstanceCreationExpression(InstanceCreationExpression node) =>
+      visitNode(node);
+
+  @override
+  R visitIntegerLiteral(IntegerLiteral node) => visitNode(node);
+
+  @override
+  R visitInterpolationExpression(InterpolationExpression node) =>
+      visitNode(node);
+
+  @override
+  R visitInterpolationString(InterpolationString node) => visitNode(node);
+
+  @override
+  R visitIsExpression(IsExpression node) => visitNode(node);
+
+  @override
+  R visitLabel(Label node) => visitNode(node);
+
+  @override
+  R visitLabeledStatement(LabeledStatement node) => visitNode(node);
+
+  @override
+  R visitLibraryDirective(LibraryDirective node) => visitNode(node);
+
+  @override
+  R visitLibraryIdentifier(LibraryIdentifier node) => visitNode(node);
+
+  @override
+  R visitListLiteral(ListLiteral node) => visitNode(node);
+
+  @override
+  R visitMapLiteral(MapLiteral node) => visitNode(node);
+
+  @override
+  R visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
+
+  @override
+  R visitMethodDeclaration(MethodDeclaration node) => visitNode(node);
+
+  @override
+  R visitMethodInvocation(MethodInvocation node) => visitNode(node);
+
+  @override
+  R visitNamedExpression(NamedExpression node) => visitNode(node);
+
+  @override
+  R visitNativeClause(NativeClause node) => visitNode(node);
+
+  @override
+  R visitNativeFunctionBody(NativeFunctionBody node) => visitNode(node);
+
+  R visitNode(AstNode node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitNullLiteral(NullLiteral node) => visitNode(node);
+
+  @override
+  R visitParenthesizedExpression(ParenthesizedExpression node) =>
+      visitNode(node);
+
+  @override
+  R visitPartDirective(PartDirective node) => visitNode(node);
+
+  @override
+  R visitPartOfDirective(PartOfDirective node) => visitNode(node);
+
+  @override
+  R visitPostfixExpression(PostfixExpression node) => visitNode(node);
+
+  @override
+  R visitPrefixedIdentifier(PrefixedIdentifier node) => visitNode(node);
+
+  @override
+  R visitPrefixExpression(PrefixExpression node) => visitNode(node);
+
+  @override
+  R visitPropertyAccess(PropertyAccess node) => visitNode(node);
+
+  @override
+  R visitRedirectingConstructorInvocation(
+          RedirectingConstructorInvocation node) =>
+      visitNode(node);
+
+  @override
+  R visitRethrowExpression(RethrowExpression node) => visitNode(node);
+
+  @override
+  R visitReturnStatement(ReturnStatement node) => visitNode(node);
+
+  @override
+  R visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
+
+  @override
+  R visitShowCombinator(ShowCombinator node) => visitNode(node);
+
+  @override
+  R visitSimpleFormalParameter(SimpleFormalParameter node) => visitNode(node);
+
+  @override
+  R visitSimpleIdentifier(SimpleIdentifier node) => visitNode(node);
+
+  @override
+  R visitSimpleStringLiteral(SimpleStringLiteral node) => visitNode(node);
+
+  @override
+  R visitStringInterpolation(StringInterpolation node) => visitNode(node);
+
+  @override
+  R visitSuperConstructorInvocation(SuperConstructorInvocation node) =>
+      visitNode(node);
+
+  @override
+  R visitSuperExpression(SuperExpression node) => visitNode(node);
+
+  @override
+  R visitSwitchCase(SwitchCase node) => visitNode(node);
+
+  @override
+  R visitSwitchDefault(SwitchDefault node) => visitNode(node);
+
+  @override
+  R visitSwitchStatement(SwitchStatement node) => visitNode(node);
+
+  @override
+  R visitSymbolLiteral(SymbolLiteral node) => visitNode(node);
+
+  @override
+  R visitThisExpression(ThisExpression node) => visitNode(node);
+
+  @override
+  R visitThrowExpression(ThrowExpression node) => visitNode(node);
+
+  @override
+  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) =>
+      visitNode(node);
+
+  @override
+  R visitTryStatement(TryStatement node) => visitNode(node);
+
+  @override
+  R visitTypeArgumentList(TypeArgumentList node) => visitNode(node);
+
+  @override
+  R visitTypeName(TypeName node) => visitNode(node);
+
+  @override
+  R visitTypeParameter(TypeParameter node) => visitNode(node);
+
+  @override
+  R visitTypeParameterList(TypeParameterList node) => visitNode(node);
+
+  @override
+  R visitVariableDeclaration(VariableDeclaration node) => visitNode(node);
+
+  @override
+  R visitVariableDeclarationList(VariableDeclarationList node) =>
+      visitNode(node);
+
+  @override
+  R visitVariableDeclarationStatement(VariableDeclarationStatement node) =>
+      visitNode(node);
+
+  @override
+  R visitWhileStatement(WhileStatement node) => visitNode(node);
+
+  @override
+  R visitWithClause(WithClause node) => visitNode(node);
+
+  @override
+  R visitYieldStatement(YieldStatement node) => visitNode(node);
+}
+
+/**
+ * A helper class used to implement the correct order of visits for a
+ * [BreadthFirstVisitor].
+ */
+class _BreadthFirstChildVisitor extends UnifyingAstVisitor<Object> {
+  /**
+   * The [BreadthFirstVisitor] being helped by this visitor.
+   */
+  final BreadthFirstVisitor outerVisitor;
+
+  /**
+   * Initialize a newly created visitor to help the [outerVisitor].
+   */
+  _BreadthFirstChildVisitor(this.outerVisitor);
+
+  @override
+  Object visitNode(AstNode node) {
+    outerVisitor._queue.add(node);
+    return null;
+  }
+}
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
new file mode 100644
index 0000000..ab468ed
--- /dev/null
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -0,0 +1,2053 @@
+// 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 analyzer.dart.element.element;
+
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart' show DartObject;
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/model.dart' show AnalysisTarget;
+
+/**
+ * An element that represents a class.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ClassElement
+    implements TypeDefiningElement, TypeParameterizedElement {
+  /**
+   * An empty list of class elements.
+   */
+  static const List<ClassElement> EMPTY_LIST = const <ClassElement>[];
+
+  /**
+   * Return a list containing all of the accessors (getters and setters)
+   * declared in this class.
+   */
+  List<PropertyAccessorElement> get accessors;
+
+  /**
+   * Return a list containing all the supertypes defined for this class and its
+   * supertypes. This includes superclasses, mixins and interfaces.
+   */
+  List<InterfaceType> get allSupertypes;
+
+  /**
+   * Return a list containing all of the constructors declared in this class.
+   */
+  List<ConstructorElement> get constructors;
+
+  /**
+   * Return a list containing all of the fields declared in this class.
+   */
+  List<FieldElement> get fields;
+
+  /**
+   * Return `true` if this class or its superclass declares a non-final instance
+   * field.
+   */
+  bool get hasNonFinalField;
+
+  /**
+   * Return `true` if this class has reference to super (so, for example, cannot
+   * be used as a mixin).
+   */
+  bool get hasReferenceToSuper;
+
+  /**
+   * Return `true` if this class declares a static member.
+   */
+  bool get hasStaticMember;
+
+  /**
+   * Return a list containing all of the interfaces that are implemented by this
+   * class.
+   *
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
+   */
+  List<InterfaceType> get interfaces;
+
+  /**
+   * Return `true` if this class is abstract. A class is abstract if it has an
+   * explicit `abstract` modifier. Note, that this definition of <i>abstract</i>
+   * is different from <i>has unimplemented members</i>.
+   */
+  bool get isAbstract;
+
+  /**
+   * Return `true` if this class is defined by an enum declaration.
+   */
+  bool get isEnum;
+
+  /**
+   * Return `true` if this class is a mixin application.  A class is a mixin
+   * application if it was declared using the syntax "class A = B with C;".
+   */
+  bool get isMixinApplication;
+
+  /**
+   * Return `true` if this class [isProxy], or if it inherits the proxy
+   * annotation from a supertype.
+   */
+  bool get isOrInheritsProxy;
+
+  /**
+   * Return `true` if this element has an annotation of the form '@proxy'.
+   */
+  bool get isProxy;
+
+  /**
+   * Return `true` if this class can validly be used as a mixin when defining
+   * another class. The behavior of this method is defined by the Dart Language
+   * Specification in section 9:
+   * <blockquote>
+   * It is a compile-time error if a declared or derived mixin refers to super.
+   * It is a compile-time error if a declared or derived mixin explicitly
+   * declares a constructor. It is a compile-time error if a mixin is derived
+   * from a class whose superclass is not Object.
+   * </blockquote>
+   */
+  bool get isValidMixin;
+
+  /**
+   * Return a list containing all of the methods declared in this class.
+   */
+  List<MethodElement> get methods;
+
+  /**
+   * Return a list containing all of the mixins that are applied to the class
+   * being extended in order to derive the superclass of this class.
+   *
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
+   */
+  List<InterfaceType> get mixins;
+
+  /**
+   * Return the superclass of this class, or `null` if the class represents the
+   * class 'Object'. All other classes will have a non-`null` superclass. If the
+   * superclass was not explicitly declared then the implicit superclass
+   * 'Object' will be returned.
+   *
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
+   */
+  InterfaceType get supertype;
+
+  @override
+  InterfaceType get type;
+
+  /**
+   * Return the unnamed constructor declared in this class, or `null` if this
+   * class does not declare an unnamed constructor but does declare named
+   * constructors. The returned constructor will be synthetic if this class does
+   * not declare any constructors, in which case it will represent the default
+   * constructor for the class.
+   */
+  ConstructorElement get unnamedConstructor;
+
+  @override
+  NamedCompilationUnitMember computeNode();
+
+  /**
+   * Return the field (synthetic or explicit) defined in this class that has the
+   * given [name], or `null` if this class does not define a field with the
+   * given name.
+   */
+  FieldElement getField(String name);
+
+  /**
+   * Return the element representing the getter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a getter
+   * with the given name.
+   */
+  PropertyAccessorElement getGetter(String name);
+
+  /**
+   * Return the element representing the method with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a method
+   * with the given name.
+   */
+  MethodElement getMethod(String name);
+
+  /**
+   * Return the named constructor declared in this class with the given [name],
+   * or `null` if this class does not declare a named constructor with the given
+   * name.
+   */
+  ConstructorElement getNamedConstructor(String name);
+
+  /**
+   * Return the element representing the setter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a setter
+   * with the given name.
+   */
+  PropertyAccessorElement getSetter(String name);
+
+  /**
+   * Determine whether the given [constructor], which exists in the superclass
+   * of this class, is accessible to constructors in this class.
+   */
+  bool isSuperConstructorAccessible(ConstructorElement constructor);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in this class with respect to the given [library],
+   * ignoring abstract methods, or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section
+   * 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is: If <i>C</i> declares an instance method named <i>m</i>
+   * that is accessible to <i>L</i>, then that method is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up method <i>m</i> in <i>S</i> with
+   * respect to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  MethodElement lookUpConcreteMethod(String methodName, LibraryElement library);
+
+  /**
+   * Return the element representing the getter that results from looking up the
+   * given [getterName] in this class with respect to the given [library], or
+   * `null` if the look up fails. The behavior of this method is defined by the
+   * Dart Language Specification in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpGetter(
+      String getterName, LibraryElement library);
+
+  /**
+   * Return the element representing the getter that results from looking up the
+   * given [getterName] in the superclass of this class with respect to the
+   * given [library], ignoring abstract getters, or `null` if the look up fails.
+   * The behavior of this method is defined by the Dart Language Specification
+   * in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpInheritedConcreteGetter(
+      String getterName, LibraryElement library);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in the superclass of this class with respect to the
+   * given [library], ignoring abstract methods, or `null` if the look up fails.
+   * The behavior of this method is defined by the Dart Language Specification
+   * in section 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:  If <i>C</i> declares an instance method named
+   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+   * result of the lookup is the result of looking up method <i>m</i> in
+   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+   * failed.
+   * </blockquote>
+   */
+  MethodElement lookUpInheritedConcreteMethod(
+      String methodName, LibraryElement library);
+
+  /**
+   * Return the element representing the setter that results from looking up the
+   * given [setterName] in the superclass of this class with respect to the
+   * given [library], ignoring abstract setters, or `null` if the look up fails.
+   * The behavior of this method is defined by the Dart Language Specification
+   * in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:  If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpInheritedConcreteSetter(
+      String setterName, LibraryElement library);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in the superclass of this class with respect to the
+   * given [library], or `null` if the look up fails. The behavior of this
+   * method is defined by the Dart Language Specification in section 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:  If <i>C</i> declares an instance method named
+   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+   * result of the lookup is the result of looking up method <i>m</i> in
+   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+   * failed.
+   * </blockquote>
+   */
+  MethodElement lookUpInheritedMethod(
+      String methodName, LibraryElement library);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in this class with respect to the given [library], or
+   * `null` if the look up fails. The behavior of this method is defined by the
+   * Dart Language Specification in section 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:  If <i>C</i> declares an instance method named
+   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+   * result of the lookup is the result of looking up method <i>m</i> in
+   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+   * failed.
+   * </blockquote>
+   */
+  MethodElement lookUpMethod(String methodName, LibraryElement library);
+
+  /**
+   * Return the element representing the setter that results from looking up the
+   * given [setterName] in this class with respect to the given [library], or
+   * `null` if the look up fails. The behavior of this method is defined by the
+   * Dart Language Specification in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpSetter(
+      String setterName, LibraryElement library);
+}
+
+/**
+ * An element that is contained within a [ClassElement].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ClassMemberElement implements Element {
+  @override
+  ClassElement get enclosingElement;
+
+  /**
+   * Return `true` if this element is a static element. A static element is an
+   * element that is not associated with a particular instance, but rather with
+   * an entire library or class.
+   */
+  bool get isStatic;
+}
+
+/**
+ * An element representing a compilation unit.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class CompilationUnitElement implements Element, UriReferencedElement {
+  /**
+   * An empty list of compilation unit elements.
+   */
+  static const List<CompilationUnitElement> EMPTY_LIST =
+      const <CompilationUnitElement>[];
+
+  /**
+   * Return a list containing all of the top-level accessors (getters and
+   * setters) contained in this compilation unit.
+   */
+  List<PropertyAccessorElement> get accessors;
+
+  @override
+  LibraryElement get enclosingElement;
+
+  /**
+   * Return a list containing all of the enums contained in this compilation
+   * unit.
+   */
+  List<ClassElement> get enums;
+
+  /**
+   * Return a list containing all of the top-level functions contained in this
+   * compilation unit.
+   */
+  List<FunctionElement> get functions;
+
+  /**
+   * Return a list containing all of the function type aliases contained in this
+   * compilation unit.
+   */
+  List<FunctionTypeAliasElement> get functionTypeAliases;
+
+  /**
+   * Return `true` if this compilation unit defines a top-level function named
+   * `loadLibrary`.
+   */
+  bool get hasLoadLibraryFunction;
+
+  /**
+   * Return a list containing all of the top-level variables contained in this
+   * compilation unit.
+   */
+  List<TopLevelVariableElement> get topLevelVariables;
+
+  /**
+   * Return a list containing all of the classes contained in this compilation
+   * unit.
+   */
+  List<ClassElement> get types;
+
+  @override
+  CompilationUnit computeNode();
+
+  /**
+   * Return the element at the given [offset], maybe `null` if no such element.
+   */
+  Element getElementAt(int offset);
+
+  /**
+   * Return the enum defined in this compilation unit that has the given [name],
+   * or `null` if this compilation unit does not define an enum with the given
+   * name.
+   */
+  ClassElement getEnum(String name);
+
+  /**
+   * Return the class defined in this compilation unit that has the given
+   * [name], or `null` if this compilation unit does not define a class with the
+   * given name.
+   */
+  ClassElement getType(String name);
+}
+
+/**
+ * An element representing a constructor or a factory method defined within a
+ * class.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ConstructorElement
+    implements ClassMemberElement, ExecutableElement, ConstantEvaluationTarget {
+  /**
+   * An empty list of constructor elements.
+   */
+  static const List<ConstructorElement> EMPTY_LIST =
+      const <ConstructorElement>[];
+
+  /**
+   * Return `true` if this constructor is a const constructor.
+   */
+  bool get isConst;
+
+  /**
+   * Return `true` if this constructor can be used as a default constructor -
+   * unnamed and has no required parameters.
+   */
+  bool get isDefaultConstructor;
+
+  /**
+   * Return `true` if this constructor represents a factory constructor.
+   */
+  bool get isFactory;
+
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this constructor's name, or `null` if not named.
+   */
+  int get nameEnd;
+
+  /**
+   * Return the offset of the `.` before this constructor name, or `null` if
+   * not named.
+   */
+  int get periodOffset;
+
+  /**
+   * Return the constructor to which this constructor is redirecting, or `null`
+   * if this constructor does not redirect to another constructor or if the
+   * library containing this constructor has not yet been resolved.
+   */
+  ConstructorElement get redirectedConstructor;
+
+  @override
+  ConstructorDeclaration computeNode();
+}
+
+/**
+ * The base class for all of the elements in the element model. Generally
+ * speaking, the element model is a semantic model of the program that
+ * represents things that are declared with a name and hence can be referenced
+ * elsewhere in the code.
+ *
+ * There are two exceptions to the general case. First, there are elements in
+ * the element model that are created for the convenience of various kinds of
+ * analysis but that do not have any corresponding declaration within the source
+ * code. Such elements are marked as being <i>synthetic</i>. Examples of
+ * synthetic elements include
+ * * default constructors in classes that do not define any explicit
+ *   constructors,
+ * * getters and setters that are induced by explicit field declarations,
+ * * fields that are induced by explicit declarations of getters and setters,
+ *   and
+ * * functions representing the initialization expression for a variable.
+ *
+ * Second, there are elements in the element model that do not have a name.
+ * These correspond to unnamed functions and exist in order to more accurately
+ * represent the semantic structure of the program.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Element implements AnalysisTarget {
+  /**
+   * A comparator that can be used to sort elements by their name offset.
+   * Elements with a smaller offset will be sorted to be before elements with a
+   * larger name offset.
+   */
+  static final Comparator<Element> SORT_BY_OFFSET =
+      (Element firstElement, Element secondElement) =>
+          firstElement.nameOffset - secondElement.nameOffset;
+
+  /**
+   * Return the analysis context in which this element is defined.
+   */
+  AnalysisContext get context;
+
+  /**
+   * Return the display name of this element, or `null` if this element does not
+   * have a name.
+   *
+   * In most cases the name and the display name are the same. Differences
+   * though are cases such as setters where the name of some setter `set f(x)`
+   * is `f=`, instead of `f`.
+   */
+  String get displayName;
+
+  /**
+   * Return the source range of the documentation comment for this element,
+   * or `null` if this element does not or cannot have a documentation.
+   *
+   * Deprecated.  Use [documentationComment] instead.
+   */
+  @deprecated
+  SourceRange get docRange;
+
+  /**
+   * Return the content of the documentation comment (including delimiters) for
+   * this element, or `null` if this element does not or cannot have
+   * documentation.
+   */
+  String get documentationComment;
+
+  /**
+   * Return the element that either physically or logically encloses this
+   * element. This will be `null` if this element is a library because libraries
+   * are the top-level elements in the model.
+   */
+  Element get enclosingElement;
+
+  /**
+   * The unique integer identifier of this element.
+   */
+  int get id;
+
+  /**
+   * Return `true` if this element has an annotation of the form '@deprecated'
+   * or '@Deprecated('..')'.
+   */
+  bool get isDeprecated;
+
+  /**
+   * Return `true` if this element has an annotation of the form '@override'.
+   */
+  bool get isOverride;
+
+  /**
+   * Return `true` if this element is private. Private elements are visible only
+   * within the library in which they are declared.
+   */
+  bool get isPrivate;
+
+  /**
+   * Return `true` if this element is public. Public elements are visible within
+   * any library that imports the library in which they are declared.
+   */
+  bool get isPublic;
+
+  /**
+   * Return `true` if this element is synthetic. A synthetic element is an
+   * element that is not represented in the source code explicitly, but is
+   * implied by the source code, such as the default constructor for a class
+   * that does not explicitly define any constructors.
+   */
+  bool get isSynthetic;
+
+  /**
+   * Return the kind of element that this is.
+   */
+  ElementKind get kind;
+
+  /**
+   * Return the library that contains this element. This will be the element
+   * itself if it is a library element. This will be `null` if this element is
+   * an HTML file because HTML files are not contained in libraries.
+   */
+  LibraryElement get library;
+
+  /**
+   * Return an object representing the location of this element in the element
+   * model. The object can be used to locate this element at a later time.
+   */
+  ElementLocation get location;
+
+  /**
+   * Return a list containing all of the metadata associated with this element.
+   * The array will be empty if the element does not have any metadata or if the
+   * library containing this element has not yet been resolved.
+   */
+  List<ElementAnnotation> get metadata;
+
+  /**
+   * Return the name of this element, or `null` if this element does not have a
+   * name.
+   */
+  String get name;
+
+  /**
+   * Return the length of the name of this element in the file that contains the
+   * declaration of this element, or `0` if this element does not have a name.
+   */
+  int get nameLength;
+
+  /**
+   * Return the offset of the name of this element in the file that contains the
+   * declaration of this element, or `-1` if this element is synthetic, does not
+   * have a name, or otherwise does not have an offset.
+   */
+  int get nameOffset;
+
+  @override
+  Source get source;
+
+  /**
+   * Return the resolved [CompilationUnit] that declares this element, or `null`
+   * if this element is synthetic.
+   *
+   * This method is expensive, because resolved AST might have been already
+   * evicted from cache, so parsing and resolving will be performed.
+   */
+  CompilationUnit get unit;
+
+  /**
+   * Use the given [visitor] to visit this element. Return the value returned by
+   * the visitor as a result of visiting this element.
+   */
+  accept(ElementVisitor visitor);
+
+  /**
+   * Return the documentation comment for this element as it appears in the
+   * original source (complete with the beginning and ending delimiters), or
+   * `null` if this element does not have a documentation comment associated
+   * with it. This can be a long-running operation if the information needed to
+   * access the comment is not cached.
+   *
+   * Throws [AnalysisException] if the documentation comment could not be
+   * determined because the analysis could not be performed
+   *
+   * Deprecated.  Use [documentationComment] instead.
+   */
+  @deprecated
+  String computeDocumentationComment();
+
+  /**
+   * Return the resolved [AstNode] node that declares this element, or `null` if
+   * this element is synthetic or isn't contained in a compilation unit, such as
+   * a [LibraryElement].
+   *
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
+   *
+   * <b>Note:</b> This method cannot be used in an async environment.
+   */
+  AstNode computeNode();
+
+  /**
+   * Return the most immediate ancestor of this element for which the
+   * [predicate] returns `true`, or `null` if there is no such ancestor. Note
+   * that this element will never be returned.
+   */
+  Element getAncestor(Predicate<Element> predicate);
+
+  /**
+   * Return a display name for the given element that includes the path to the
+   * compilation unit in which the type is defined. If [shortName] is `null`
+   * then [getDisplayName] will be used as the name of this element. Otherwise
+   * the provided name will be used.
+   */
+  // TODO(brianwilkerson) Make the parameter optional.
+  String getExtendedDisplayName(String shortName);
+
+  /**
+   * Return `true` if this element, assuming that it is within scope, is
+   * accessible to code in the given [library]. This is defined by the Dart
+   * Language Specification in section 3.2:
+   * <blockquote>
+   * A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is
+   * declared in <i>L</i> or if <i>m</i> is public.
+   * </blockquote>
+   */
+  bool isAccessibleIn(LibraryElement library);
+
+  /**
+   * Use the given [visitor] to visit all of the children of this element. There
+   * is no guarantee of the order in which the children will be visited.
+   */
+  void visitChildren(ElementVisitor visitor);
+}
+
+/**
+ * A single annotation associated with an element.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ElementAnnotation {
+  /**
+   * An empty list of annotations.
+   */
+  static const List<ElementAnnotation> EMPTY_LIST = const <ElementAnnotation>[];
+
+  /**
+   * Return a representation of the value of this annotation.
+   *
+   * Return `null` if the value of this annotation could not be computed because
+   * of errors.
+   */
+  DartObject get constantValue;
+
+  /**
+   * Return the element representing the field, variable, or const constructor
+   * being used as an annotation.
+   */
+  Element get element;
+
+  /**
+   * Return `true` if this annotation marks the associated element as being
+   * deprecated.
+   */
+  bool get isDeprecated;
+
+  /**
+   * Return `true` if this annotation marks the associated method as being
+   * expected to override an inherited method.
+   */
+  bool get isOverride;
+
+  /**
+   * Return `true` if this annotation marks the associated class as implementing
+   * a proxy object.
+   */
+  bool get isProxy;
+}
+
+/**
+ * The enumeration `ElementKind` defines the various kinds of elements in the
+ * element model.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class ElementKind extends Enum<ElementKind> {
+  static const ElementKind CLASS = const ElementKind('CLASS', 0, "class");
+
+  static const ElementKind COMPILATION_UNIT =
+      const ElementKind('COMPILATION_UNIT', 1, "compilation unit");
+
+  static const ElementKind CONSTRUCTOR =
+      const ElementKind('CONSTRUCTOR', 2, "constructor");
+
+  static const ElementKind DYNAMIC =
+      const ElementKind('DYNAMIC', 3, "<dynamic>");
+
+  static const ElementKind ERROR = const ElementKind('ERROR', 4, "<error>");
+
+  static const ElementKind EXPORT =
+      const ElementKind('EXPORT', 5, "export directive");
+
+  static const ElementKind FIELD = const ElementKind('FIELD', 6, "field");
+
+  static const ElementKind FUNCTION =
+      const ElementKind('FUNCTION', 7, "function");
+
+  static const ElementKind GETTER = const ElementKind('GETTER', 8, "getter");
+
+  static const ElementKind IMPORT =
+      const ElementKind('IMPORT', 9, "import directive");
+
+  static const ElementKind LABEL = const ElementKind('LABEL', 10, "label");
+
+  static const ElementKind LIBRARY =
+      const ElementKind('LIBRARY', 11, "library");
+
+  static const ElementKind LOCAL_VARIABLE =
+      const ElementKind('LOCAL_VARIABLE', 12, "local variable");
+
+  static const ElementKind METHOD = const ElementKind('METHOD', 13, "method");
+
+  static const ElementKind NAME = const ElementKind('NAME', 14, "<name>");
+
+  static const ElementKind PARAMETER =
+      const ElementKind('PARAMETER', 15, "parameter");
+
+  static const ElementKind PREFIX =
+      const ElementKind('PREFIX', 16, "import prefix");
+
+  static const ElementKind SETTER = const ElementKind('SETTER', 17, "setter");
+
+  static const ElementKind TOP_LEVEL_VARIABLE =
+      const ElementKind('TOP_LEVEL_VARIABLE', 18, "top level variable");
+
+  static const ElementKind FUNCTION_TYPE_ALIAS =
+      const ElementKind('FUNCTION_TYPE_ALIAS', 19, "function type alias");
+
+  static const ElementKind TYPE_PARAMETER =
+      const ElementKind('TYPE_PARAMETER', 20, "type parameter");
+
+  static const ElementKind UNIVERSE =
+      const ElementKind('UNIVERSE', 21, "<universe>");
+
+  static const List<ElementKind> values = const [
+    CLASS,
+    COMPILATION_UNIT,
+    CONSTRUCTOR,
+    DYNAMIC,
+    ERROR,
+    EXPORT,
+    FIELD,
+    FUNCTION,
+    GETTER,
+    IMPORT,
+    LABEL,
+    LIBRARY,
+    LOCAL_VARIABLE,
+    METHOD,
+    NAME,
+    PARAMETER,
+    PREFIX,
+    SETTER,
+    TOP_LEVEL_VARIABLE,
+    FUNCTION_TYPE_ALIAS,
+    TYPE_PARAMETER,
+    UNIVERSE
+  ];
+
+  /**
+   * The name displayed in the UI for this kind of element.
+   */
+  final String displayName;
+
+  /**
+   * Initialize a newly created element kind to have the given [displayName].
+   */
+  const ElementKind(String name, int ordinal, this.displayName)
+      : super(name, ordinal);
+
+  /**
+   * Return the kind of the given [element], or [ERROR] if the element is
+   * `null`. This is a utility method that can reduce the need for null checks
+   * in other places.
+   */
+  static ElementKind of(Element element) {
+    if (element == null) {
+      return ERROR;
+    }
+    return element.kind;
+  }
+}
+
+/**
+ * The location of an element within the element model.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ElementLocation {
+  /**
+   * Return the path to the element whose location is represented by this
+   * object. Clients must not modify the returned array.
+   */
+  List<String> get components;
+
+  /**
+   * Return an encoded representation of this location that can be used to
+   * create a location that is equal to this location.
+   */
+  String get encoding;
+}
+
+/**
+ * An object that can be used to visit an element structure.
+ *
+ * Clients may implement this class.
+ */
+abstract class ElementVisitor<R> {
+  R visitClassElement(ClassElement element);
+
+  R visitCompilationUnitElement(CompilationUnitElement element);
+
+  R visitConstructorElement(ConstructorElement element);
+
+  R visitExportElement(ExportElement element);
+
+  R visitFieldElement(FieldElement element);
+
+  R visitFieldFormalParameterElement(FieldFormalParameterElement element);
+
+  R visitFunctionElement(FunctionElement element);
+
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element);
+
+  R visitImportElement(ImportElement element);
+
+  R visitLabelElement(LabelElement element);
+
+  R visitLibraryElement(LibraryElement element);
+
+  R visitLocalVariableElement(LocalVariableElement element);
+
+  R visitMethodElement(MethodElement element);
+
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element);
+
+  R visitParameterElement(ParameterElement element);
+
+  R visitPrefixElement(PrefixElement element);
+
+  R visitPropertyAccessorElement(PropertyAccessorElement element);
+
+  R visitTopLevelVariableElement(TopLevelVariableElement element);
+
+  R visitTypeParameterElement(TypeParameterElement element);
+}
+
+/**
+ * An element representing an executable object, including functions, methods,
+ * constructors, getters, and setters.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ExecutableElement implements FunctionTypedElement {
+  /**
+   * An empty list of executable elements.
+   */
+  static const List<ExecutableElement> EMPTY_LIST = const <ExecutableElement>[];
+
+  /**
+   * Return a list containing all of the functions defined within this
+   * executable element.
+   */
+  List<FunctionElement> get functions;
+
+  /**
+   * Return `true` if this executable element did not have an explicit return
+   * type specified for it in the original source. Note that if there was no
+   * explicit return type, and if the element model is fully populated, then
+   * the [returnType] will not be `null`.
+   */
+  bool get hasImplicitReturnType;
+
+  /**
+   * Return `true` if this executable element is abstract. Executable elements
+   * are abstract if they are not external and have no body.
+   */
+  bool get isAbstract;
+
+  /**
+   * Return `true` if this executable element has body marked as being
+   * asynchronous.
+   */
+  bool get isAsynchronous;
+
+  /**
+   * Return `true` if this executable element is external. Executable elements
+   * are external if they are explicitly marked as such using the 'external'
+   * keyword.
+   */
+  bool get isExternal;
+
+  /**
+   * Return `true` if this executable element has a body marked as being a
+   * generator.
+   */
+  bool get isGenerator;
+
+  /**
+   * Return `true` if this executable element is an operator. The test may be
+   * based on the name of the executable element, in which case the result will
+   * be correct when the name is legal.
+   */
+  bool get isOperator;
+
+  /**
+   * Return `true` if this element is a static element. A static element is an
+   * element that is not associated with a particular instance, but rather with
+   * an entire library or class.
+   */
+  bool get isStatic;
+
+  /**
+   * Return `true` if this executable element has a body marked as being
+   * synchronous.
+   */
+  bool get isSynchronous;
+
+  /**
+   * Return a list containing all of the labels defined within this executable
+   * element.
+   */
+  List<LabelElement> get labels;
+
+  /**
+   * Return a list containing all of the local variables defined within this
+   * executable element.
+   */
+  List<LocalVariableElement> get localVariables;
+}
+
+/**
+ * An export directive within a library.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ExportElement implements Element, UriReferencedElement {
+  /**
+   * An empty list of export elements.
+   */
+  static const List<ExportElement> EMPTY_LIST = const <ExportElement>[];
+
+  /**
+   * Return a list containing the combinators that were specified as part of the
+   * export directive in the order in which they were specified.
+   */
+  List<NamespaceCombinator> get combinators;
+
+  /**
+   * Return the library that is exported from this library by this export
+   * directive.
+   */
+  LibraryElement get exportedLibrary;
+}
+
+/**
+ * A field defined within a type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FieldElement
+    implements ClassMemberElement, PropertyInducingElement {
+  /**
+   * An empty list of field elements.
+   */
+  static const List<FieldElement> EMPTY_LIST = const <FieldElement>[];
+
+  /**
+   * Return {@code true} if this element is an enum constant.
+   */
+  bool get isEnumConstant;
+
+  @override
+  AstNode computeNode();
+}
+
+/**
+ * A field formal parameter defined within a constructor element.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FieldFormalParameterElement implements ParameterElement {
+  /**
+   * Return the field element associated with this field formal parameter, or
+   * `null` if the parameter references a field that doesn't exist.
+   */
+  FieldElement get field;
+}
+
+/**
+ * A (non-method) function. This can be either a top-level function, a local
+ * function, a closure, or the initialization expression for a field or
+ * variable.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionElement implements ExecutableElement, LocalElement {
+  /**
+   * An empty list of function elements.
+   */
+  static const List<FunctionElement> EMPTY_LIST = const <FunctionElement>[];
+
+  /**
+   * The name of the method that can be implemented by a class to allow its
+   * instances to be invoked as if they were a function.
+   */
+  static final String CALL_METHOD_NAME = "call";
+
+  /**
+   * The name of the synthetic function defined for libraries that are deferred.
+   */
+  static final String LOAD_LIBRARY_NAME = "loadLibrary";
+
+  /**
+   * The name of the function used as an entry point.
+   */
+  static const String MAIN_FUNCTION_NAME = "main";
+
+  /**
+   * The name of the method that will be invoked if an attempt is made to invoke
+   * an undefined method on an object.
+   */
+  static final String NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod";
+
+  /**
+   * Return `true` if the function is an entry point, i.e. a top-level function
+   * and has the name `main`.
+   */
+  bool get isEntryPoint;
+
+  @override
+  FunctionDeclaration computeNode();
+}
+
+/**
+ * A function type alias (`typedef`).
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionTypeAliasElement
+    implements FunctionTypedElement, TypeDefiningElement {
+  /**
+   * An empty array of type alias elements.
+   */
+  static List<FunctionTypeAliasElement> EMPTY_LIST =
+      new List<FunctionTypeAliasElement>(0);
+
+  /**
+   * Return the compilation unit in which this type alias is defined.
+   */
+  @override
+  CompilationUnitElement get enclosingElement;
+
+  @override
+  FunctionTypeAlias computeNode();
+}
+
+/**
+ * An element that has a [FunctionType] as its [type].
+ *
+ * This also provides convenient access to the parameters and return type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionTypedElement implements TypeParameterizedElement {
+  /**
+   * Return a list containing all of the parameters defined by this executable
+   * element.
+   */
+  List<ParameterElement> get parameters;
+
+  /**
+   * Return the return type defined by this element. If the element model is
+   * fully populated, then the [returnType] will not be `null`, even if no
+   * return type was explicitly specified.
+   */
+  DartType get returnType;
+
+  /**
+   * The type of this element, which will be a function type.
+   */
+  FunctionType get type;
+}
+
+/**
+ * A combinator that causes some of the names in a namespace to be hidden when
+ * being imported.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class HideElementCombinator implements NamespaceCombinator {
+  /**
+   * Return a list containing the names that are not to be made visible in the
+   * importing library even if they are defined in the imported library.
+   */
+  List<String> get hiddenNames;
+}
+
+/**
+ * A single import directive within a library.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ImportElement implements Element, UriReferencedElement {
+  /**
+   * An empty list of import elements.
+   */
+  static const List<ImportElement> EMPTY_LIST = const <ImportElement>[];
+
+  /**
+   * Return a list containing the combinators that were specified as part of the
+   * import directive in the order in which they were specified.
+   */
+  List<NamespaceCombinator> get combinators;
+
+  /**
+   * Return the library that is imported into this library by this import
+   * directive.
+   */
+  LibraryElement get importedLibrary;
+
+  /**
+   * Return `true` if this import is for a deferred library.
+   */
+  bool get isDeferred;
+
+  /**
+   * Return the prefix that was specified as part of the import directive, or
+   * `null` if there was no prefix specified.
+   */
+  PrefixElement get prefix;
+
+  /**
+   * Return the offset of the prefix of this import in the file that contains
+   * this import directive, or `-1` if this import is synthetic, does not have a
+   * prefix, or otherwise does not have an offset.
+   */
+  int get prefixOffset;
+}
+
+/**
+ * A label associated with a statement.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LabelElement implements Element {
+  /**
+   * An empty list of label elements.
+   */
+  static const List<LabelElement> EMPTY_LIST = const <LabelElement>[];
+
+  @override
+  ExecutableElement get enclosingElement;
+}
+
+/**
+ * A library.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LibraryElement implements Element {
+  /**
+   * An empty list of library elements.
+   */
+  static const List<LibraryElement> EMPTY_LIST = const <LibraryElement>[];
+
+  /**
+   * Return the compilation unit that defines this library.
+   */
+  CompilationUnitElement get definingCompilationUnit;
+
+  /**
+   * Return the entry point for this library, or `null` if this library does not
+   * have an entry point. The entry point is defined to be a zero argument
+   * top-level function whose name is `main`.
+   */
+  FunctionElement get entryPoint;
+
+  /**
+   * Return a list containing all of the libraries that are exported from this
+   * library.
+   */
+  List<LibraryElement> get exportedLibraries;
+
+  /**
+   * The export [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  Namespace get exportNamespace;
+
+  /**
+   * Return a list containing all of the exports defined in this library.
+   */
+  List<ExportElement> get exports;
+
+  /**
+   * Return `true` if the defining compilation unit of this library contains at
+   * least one import directive whose URI uses the "dart-ext" scheme.
+   */
+  bool get hasExtUri;
+
+  /**
+   * Return `true` if this library defines a top-level function named
+   * `loadLibrary`.
+   */
+  bool get hasLoadLibraryFunction;
+
+  /**
+   * Return an identifier that uniquely identifies this element among the
+   * children of this element's parent.
+   */
+  String get identifier;
+
+  /**
+   * Return a list containing all of the libraries that are imported into this
+   * library. This includes all of the libraries that are imported using a
+   * prefix (also available through the prefixes returned by [getPrefixes]) and
+   * those that are imported without a prefix.
+   */
+  List<LibraryElement> get importedLibraries;
+
+  /**
+   * Return a list containing all of the imports defined in this library.
+   */
+  List<ImportElement> get imports;
+
+  /**
+   * Return `true` if this library is an application that can be run in the
+   * browser.
+   */
+  bool get isBrowserApplication;
+
+  /**
+   * Return `true` if this library is the dart:core library.
+   */
+  bool get isDartCore;
+
+  /**
+   * Return `true` if this library is part of the SDK.
+   */
+  bool get isInSdk;
+
+  /**
+   * Return the element representing the synthetic function `loadLibrary` that
+   * is implicitly defined for this library if the library is imported using a
+   * deferred import.
+   */
+  FunctionElement get loadLibraryFunction;
+
+  /**
+   * Return a list containing all of the compilation units that are included in
+   * this library using a `part` directive. This does not include the defining
+   * compilation unit that contains the `part` directives.
+   */
+  List<CompilationUnitElement> get parts;
+
+  /**
+   * Return a list containing elements for each of the prefixes used to `import`
+   * libraries into this library. Each prefix can be used in more than one
+   * `import` directive.
+   */
+  List<PrefixElement> get prefixes;
+
+  /**
+   * The public [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  Namespace get publicNamespace;
+
+  /**
+   * Return a list containing all of the compilation units this library consists
+   * of. This includes the defining compilation unit and units included using
+   * the `part` directive.
+   */
+  List<CompilationUnitElement> get units;
+
+  /**
+   * Return a list containing all directly and indirectly imported libraries.
+   */
+  List<LibraryElement> get visibleLibraries;
+
+  /**
+   * Return a list containing all of the imports that share the given [prefix],
+   * or an empty array if there are no such imports.
+   */
+  List<ImportElement> getImportsWithPrefix(PrefixElement prefix);
+
+  /**
+   * Return the class defined in this library that has the given [name], or
+   * `null` if this library does not define a class with the given name.
+   */
+  ClassElement getType(String className);
+
+  /**
+   * Return `true` if this library is up to date with respect to the given
+   * [timeStamp]. If any transitively referenced Source is newer than the time
+   * stamp, this method returns false.
+   */
+  bool isUpToDate(int timeStamp);
+}
+
+/**
+ * An element that can be (but is not required to be) defined within a method
+ * or function (an [ExecutableElement]).
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LocalElement implements Element {
+  /**
+   * Return a source range that covers the approximate portion of the source in
+   * which the name of this element is visible, or `null` if there is no single
+   * range of characters within which the element name is visible.
+   *
+   * * For a local variable, this includes everything from the end of the
+   *   variable's initializer to the end of the block that encloses the variable
+   *   declaration.
+   * * For a parameter, this includes the body of the method or function that
+   *   declares the parameter.
+   * * For a local function, this includes everything from the beginning of the
+   *   function's body to the end of the block that encloses the function
+   *   declaration.
+   * * For top-level functions, `null` will be returned because they are
+   *   potentially visible in multiple sources.
+   */
+  SourceRange get visibleRange;
+}
+
+/**
+ * A local variable.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LocalVariableElement implements LocalElement, VariableElement {
+  /**
+   * An empty list of field elements.
+   */
+  static const List<LocalVariableElement> EMPTY_LIST =
+      const <LocalVariableElement>[];
+}
+
+/**
+ * An element that represents a method defined within a type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MethodElement implements ClassMemberElement, ExecutableElement {
+  /**
+   * An empty list of method elements.
+   */
+  static const List<MethodElement> EMPTY_LIST = const <MethodElement>[];
+
+  @override
+  MethodDeclaration computeNode();
+}
+
+/**
+ * The enumeration `Modifier` defines constants for all of the modifiers defined
+ * by the Dart language and for a few additional flags that are useful.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class Modifier extends Enum<Modifier> {
+  /**
+   * Indicates that the modifier 'abstract' was applied to the element.
+   */
+  static const Modifier ABSTRACT = const Modifier('ABSTRACT', 0);
+
+  /**
+   * Indicates that an executable element has a body marked as being
+   * asynchronous.
+   */
+  static const Modifier ASYNCHRONOUS = const Modifier('ASYNCHRONOUS', 1);
+
+  /**
+   * Indicates that the modifier 'const' was applied to the element.
+   */
+  static const Modifier CONST = const Modifier('CONST', 2);
+
+  /**
+   * Indicates that the import element represents a deferred library.
+   */
+  static const Modifier DEFERRED = const Modifier('DEFERRED', 3);
+
+  /**
+   * Indicates that a class element was defined by an enum declaration.
+   */
+  static const Modifier ENUM = const Modifier('ENUM', 4);
+
+  /**
+   * Indicates that a class element was defined by an enum declaration.
+   */
+  static const Modifier EXTERNAL = const Modifier('EXTERNAL', 5);
+
+  /**
+   * Indicates that the modifier 'factory' was applied to the element.
+   */
+  static const Modifier FACTORY = const Modifier('FACTORY', 6);
+
+  /**
+   * Indicates that the modifier 'final' was applied to the element.
+   */
+  static const Modifier FINAL = const Modifier('FINAL', 7);
+
+  /**
+   * Indicates that an executable element has a body marked as being a
+   * generator.
+   */
+  static const Modifier GENERATOR = const Modifier('GENERATOR', 8);
+
+  /**
+   * Indicates that the pseudo-modifier 'get' was applied to the element.
+   */
+  static const Modifier GETTER = const Modifier('GETTER', 9);
+
+  /**
+   * A flag used for libraries indicating that the defining compilation unit
+   * contains at least one import directive whose URI uses the "dart-ext"
+   * scheme.
+   */
+  static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 10);
+
+  /**
+   * Indicates that the associated element did not have an explicit type
+   * associated with it. If the element is an [ExecutableElement], then the
+   * type being referred to is the return type.
+   */
+  static const Modifier IMPLICIT_TYPE = const Modifier('IMPLICIT_TYPE', 11);
+
+  /**
+   * Indicates that a class can validly be used as a mixin.
+   */
+  static const Modifier MIXIN = const Modifier('MIXIN', 12);
+
+  /**
+   * Indicates that a class is a mixin application.
+   */
+  static const Modifier MIXIN_APPLICATION =
+      const Modifier('MIXIN_APPLICATION', 13);
+
+  /**
+   * Indicates that the value of a parameter or local variable might be mutated
+   * within the context.
+   */
+  static const Modifier POTENTIALLY_MUTATED_IN_CONTEXT =
+      const Modifier('POTENTIALLY_MUTATED_IN_CONTEXT', 14);
+
+  /**
+   * Indicates that the value of a parameter or local variable might be mutated
+   * within the scope.
+   */
+  static const Modifier POTENTIALLY_MUTATED_IN_SCOPE =
+      const Modifier('POTENTIALLY_MUTATED_IN_SCOPE', 15);
+
+  /**
+   * Indicates that a class contains an explicit reference to 'super'.
+   */
+  static const Modifier REFERENCES_SUPER =
+      const Modifier('REFERENCES_SUPER', 16);
+
+  /**
+   * Indicates that the pseudo-modifier 'set' was applied to the element.
+   */
+  static const Modifier SETTER = const Modifier('SETTER', 17);
+
+  /**
+   * Indicates that the modifier 'static' was applied to the element.
+   */
+  static const Modifier STATIC = const Modifier('STATIC', 18);
+
+  /**
+   * Indicates that the element does not appear in the source code but was
+   * implicitly created. For example, if a class does not define any
+   * constructors, an implicit zero-argument constructor will be created and it
+   * will be marked as being synthetic.
+   */
+  static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 19);
+
+  static const List<Modifier> values = const [
+    ABSTRACT,
+    ASYNCHRONOUS,
+    CONST,
+    DEFERRED,
+    ENUM,
+    EXTERNAL,
+    FACTORY,
+    FINAL,
+    GENERATOR,
+    GETTER,
+    HAS_EXT_URI,
+    IMPLICIT_TYPE,
+    MIXIN,
+    MIXIN_APPLICATION,
+    POTENTIALLY_MUTATED_IN_CONTEXT,
+    POTENTIALLY_MUTATED_IN_SCOPE,
+    REFERENCES_SUPER,
+    SETTER,
+    STATIC,
+    SYNTHETIC
+  ];
+
+  const Modifier(String name, int ordinal) : super(name, ordinal);
+}
+
+/**
+ * A pseudo-element that represents multiple elements defined within a single
+ * scope that have the same name. This situation is not allowed by the language,
+ * so objects implementing this interface always represent an error. As a
+ * result, most of the normal operations on elements do not make sense and will
+ * return useless results.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MultiplyDefinedElement implements Element {
+  /**
+   * Return a list containing all of the elements that were defined within the
+   * scope to have the same name.
+   */
+  List<Element> get conflictingElements;
+
+  /**
+   * Return the type of this element as the dynamic type.
+   */
+  DartType get type;
+}
+
+/**
+ * An [ExecutableElement], with the additional information of a list of
+ * [ExecutableElement]s from which this element was composed.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MultiplyInheritedExecutableElement implements ExecutableElement {
+  /**
+   * Return a list containing all of the executable elements defined within this
+   * executable element.
+   */
+  List<ExecutableElement> get inheritedElements;
+}
+
+/**
+ * An object that controls how namespaces are combined.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NamespaceCombinator {
+  /**
+   * An empty list of namespace combinators.
+   */
+  static const List<NamespaceCombinator> EMPTY_LIST =
+      const <NamespaceCombinator>[];
+}
+
+/**
+ * A parameter defined within an executable element.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ParameterElement
+    implements LocalElement, VariableElement, ConstantEvaluationTarget {
+  /**
+   * An empty list of parameter elements.
+   */
+  static const List<ParameterElement> EMPTY_LIST = const <ParameterElement>[];
+
+  /**
+   * Return the Dart code of the default value, or `null` if no default value.
+   */
+  String get defaultValueCode;
+
+  /**
+   * Return `true` if this parameter is an initializing formal parameter.
+   */
+  bool get isInitializingFormal;
+
+  /**
+   * Return the kind of this parameter.
+   */
+  ParameterKind get parameterKind;
+
+  /**
+   * Return a list containing all of the parameters defined by this parameter.
+   * A parameter will only define other parameters if it is a function typed
+   * parameter.
+   */
+  List<ParameterElement> get parameters;
+
+  /**
+   * Return a list containing all of the type parameters defined by this
+   * parameter. A parameter will only define other parameters if it is a
+   * function typed parameter.
+   */
+  List<TypeParameterElement> get typeParameters;
+
+  /**
+   * Append the type, name and possibly the default value of this parameter to
+   * the given [buffer].
+   */
+  void appendToWithoutDelimiters(StringBuffer buffer);
+
+  @override
+  FormalParameter computeNode();
+}
+
+/**
+ * A prefix used to import one or more libraries into another library.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PrefixElement implements Element {
+  /**
+   * An empty list of prefix elements.
+   */
+  static const List<PrefixElement> EMPTY_LIST = const <PrefixElement>[];
+
+  @override
+  LibraryElement get enclosingElement;
+
+  /**
+   * Return a list containing all of the libraries that are imported using this
+   * prefix.
+   */
+  List<LibraryElement> get importedLibraries;
+}
+
+/**
+ * A getter or a setter. Note that explicitly defined property accessors
+ * implicitly define a synthetic field. Symmetrically, synthetic accessors are
+ * implicitly created for explicitly defined fields. The following rules apply:
+ *
+ * * Every explicit field is represented by a non-synthetic [FieldElement].
+ * * Every explicit field induces a getter and possibly a setter, both of which
+ *   are represented by synthetic [PropertyAccessorElement]s.
+ * * Every explicit getter or setter is represented by a non-synthetic
+ *   [PropertyAccessorElement].
+ * * Every explicit getter or setter (or pair thereof if they have the same
+ *   name) induces a field that is represented by a synthetic [FieldElement].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PropertyAccessorElement implements ExecutableElement {
+  /**
+   * An empty list of property accessor elements.
+   */
+  static const List<PropertyAccessorElement> EMPTY_LIST =
+      const <PropertyAccessorElement>[];
+
+  /**
+   * Return the accessor representing the getter that corresponds to (has the
+   * same name as) this setter, or `null` if this accessor is not a setter or if
+   * there is no corresponding getter.
+   */
+  PropertyAccessorElement get correspondingGetter;
+
+  /**
+   * Return the accessor representing the setter that corresponds to (has the
+   * same name as) this getter, or `null` if this accessor is not a getter or if
+   * there is no corresponding setter.
+   */
+  PropertyAccessorElement get correspondingSetter;
+
+  /**
+   * Return `true` if this accessor represents a getter.
+   */
+  bool get isGetter;
+
+  /**
+   * Return `true` if this accessor represents a setter.
+   */
+  bool get isSetter;
+
+  /**
+   * Return the field or top-level variable associated with this accessor. If
+   * this accessor was explicitly defined (is not synthetic) then the variable
+   * associated with it will be synthetic.
+   */
+  PropertyInducingElement get variable;
+}
+
+/**
+ * A variable that has an associated getter and possibly a setter. Note that
+ * explicitly defined variables implicitly define a synthetic getter and that
+ * non-`final` explicitly defined variables implicitly define a synthetic
+ * setter. Symmetrically, synthetic fields are implicitly created for explicitly
+ * defined getters and setters. The following rules apply:
+ *
+ * * Every explicit variable is represented by a non-synthetic
+ *   [PropertyInducingElement].
+ * * Every explicit variable induces a getter and possibly a setter, both of
+ *   which are represented by synthetic [PropertyAccessorElement]s.
+ * * Every explicit getter or setter is represented by a non-synthetic
+ *   [PropertyAccessorElement].
+ * * Every explicit getter or setter (or pair thereof if they have the same
+ *   name) induces a variable that is represented by a synthetic
+ *   [PropertyInducingElement].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PropertyInducingElement implements VariableElement {
+  /**
+   * An empty list of elements.
+   */
+  static const List<PropertyInducingElement> EMPTY_LIST =
+      const <PropertyInducingElement>[];
+
+  /**
+   * Return the getter associated with this variable. If this variable was
+   * explicitly defined (is not synthetic) then the getter associated with it
+   * will be synthetic.
+   */
+  PropertyAccessorElement get getter;
+
+  /**
+   * Return the propagated type of this variable, or `null` if type propagation
+   * has not been performed, for example because the variable is not final.
+   */
+  DartType get propagatedType;
+
+  /**
+   * Return the setter associated with this variable, or `null` if the variable
+   * is effectively `final` and therefore does not have a setter associated with
+   * it. (This can happen either because the variable is explicitly defined as
+   * being `final` or because the variable is induced by an explicit getter that
+   * does not have a corresponding setter.) If this variable was explicitly
+   * defined (is not synthetic) then the setter associated with it will be
+   * synthetic.
+   */
+  PropertyAccessorElement get setter;
+}
+
+/**
+ * A combinator that cause some of the names in a namespace to be visible (and
+ * the rest hidden) when being imported.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ShowElementCombinator implements NamespaceCombinator {
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this node.
+   */
+  int get end;
+
+  /**
+   * Return the offset of the 'show' keyword of this element.
+   */
+  int get offset;
+
+  /**
+   * Return a list containing the names that are to be made visible in the
+   * importing library if they are defined in the imported library.
+   */
+  List<String> get shownNames;
+}
+
+/**
+ * A top-level variable.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TopLevelVariableElement implements PropertyInducingElement {
+  /**
+   * An empty list of top-level variable elements.
+   */
+  static const List<TopLevelVariableElement> EMPTY_LIST =
+      const <TopLevelVariableElement>[];
+
+  @override
+  VariableDeclaration computeNode();
+}
+
+/**
+ * An element that defines a type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeDefiningElement implements Element {
+  /**
+   * Return the type defined by this element.
+   */
+  DartType get type;
+}
+
+/**
+ * A type parameter.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeParameterElement implements TypeDefiningElement {
+  /**
+   * An empty list of type parameter elements.
+   */
+  static const List<TypeParameterElement> EMPTY_LIST =
+      const <TypeParameterElement>[];
+
+  /**
+   * Return the type representing the bound associated with this parameter, or
+   * `null` if this parameter does not have an explicit bound.
+   */
+  DartType get bound;
+
+  @override
+  TypeParameterType get type;
+}
+
+/**
+ * An element that has type parameters, such as a class or a typedef. This also
+ * includes functions and methods if support for generic methods is enabled.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeParameterizedElement implements Element {
+  /**
+   * Return a list containing all of the type parameters declared by this
+   * element directly. This does not include type parameters that are declared
+   * by any enclosing elements.
+   */
+  List<TypeParameterElement> get typeParameters;
+}
+
+/**
+ * A pseudo-elements that represents names that are undefined. This situation is
+ * not allowed by the language, so objects implementing this interface always
+ * represent an error. As a result, most of the normal operations on elements do
+ * not make sense and will return useless results.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class UndefinedElement implements Element {}
+
+/**
+ * An element included into a library using some URI.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class UriReferencedElement implements Element {
+  /**
+   * Return the URI that is used to include this element into the enclosing
+   * library, or `null` if this is the defining compilation unit of a library.
+   */
+  String get uri;
+
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this node's URI, or `-1` for synthetic import.
+   */
+  int get uriEnd;
+
+  /**
+   * Return the offset of the URI in the file, or `-1` if this element is
+   * synthetic.
+   */
+  int get uriOffset;
+}
+
+/**
+ * A variable. There are more specific subclasses for more specific kinds of
+ * variables.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class VariableElement implements Element, ConstantEvaluationTarget {
+  /**
+   * An empty list of variable elements.
+   */
+  static const List<VariableElement> EMPTY_LIST = const <VariableElement>[];
+
+  /**
+   * Return a representation of the value of this variable.
+   *
+   * Return `null` if either this variable was not declared with the 'const'
+   * modifier or if the value of this variable could not be computed because of
+   * errors.
+   */
+  DartObject get constantValue;
+
+  /**
+   * Return `true` if this variable element did not have an explicit type
+   * specified for it.
+   */
+  bool get hasImplicitType;
+
+  /**
+   * Return a synthetic function representing this variable's initializer, or
+   * `null` if this variable does not have an initializer. The function will
+   * have no parameters. The return type of the function will be the
+   * compile-time type of the initialization expression.
+   */
+  FunctionElement get initializer;
+
+  /**
+   * Return `true` if this variable was declared with the 'const' modifier.
+   */
+  bool get isConst;
+
+  /**
+   * Return `true` if this variable was declared with the 'final' modifier.
+   * Variables that are declared with the 'const' modifier will return `false`
+   * even though they are implicitly final.
+   */
+  bool get isFinal;
+
+  /**
+   * Return `true` if this variable is potentially mutated somewhere in a
+   * closure. This information is only available for local variables (including
+   * parameters) and only after the compilation unit containing the variable has
+   * been resolved.
+   */
+  bool get isPotentiallyMutatedInClosure;
+
+  /**
+   * Return `true` if this variable is potentially mutated somewhere in its
+   * scope. This information is only available for local variables (including
+   * parameters) and only after the compilation unit containing the variable has
+   * been resolved.
+   */
+  bool get isPotentiallyMutatedInScope;
+
+  /**
+   * Return `true` if this element is a static variable, as per section 8 of the
+   * Dart Language Specification:
+   *
+   * > A static variable is a variable that is not associated with a particular
+   * > instance, but rather with an entire library or class. Static variables
+   * > include library variables and class variables. Class variables are
+   * > variables whose declaration is immediately nested inside a class
+   * > declaration and includes the modifier static. A library variable is
+   * > implicitly static.
+   */
+  bool get isStatic;
+
+  /**
+   * Return the declared type of this variable, or `null` if the variable did
+   * not have a declared type (such as if it was declared using the keyword
+   * 'var').
+   */
+  DartType get type;
+}
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
new file mode 100644
index 0000000..548dc1d
--- /dev/null
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -0,0 +1,643 @@
+// 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 analyzer.dart.element.type;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart' show InterfaceTypeImpl;
+
+/**
+ * The type associated with elements in the element model.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DartType {
+  /**
+   * An empty list of types.
+   */
+  static const List<DartType> EMPTY_LIST = const <DartType>[];
+
+  /**
+   * Return the name of this type as it should appear when presented to users in
+   * contexts such as error messages.
+   */
+  String get displayName;
+
+  /**
+   * Return the element representing the declaration of this type, or `null` if
+   * the type has not, or cannot, be associated with an element. The former case
+   * will occur if the element model is not yet complete; the latter case will
+   * occur if this object represents an undefined type.
+   */
+  Element get element;
+
+  /**
+   * Return `true` if this type represents the bottom type.
+   */
+  bool get isBottom;
+
+  /**
+   * Return `true` if this type represents the type 'Function' defined in the
+   * dart:core library.
+   */
+  bool get isDartCoreFunction;
+
+  /**
+   * Return `true` if this type represents the type 'dynamic'.
+   */
+  bool get isDynamic;
+
+  /**
+   * Return `true` if this type represents the type 'Object'.
+   */
+  bool get isObject;
+
+  /**
+   * Return `true` if this type represents a typename that couldn't be resolved.
+   */
+  bool get isUndefined;
+
+  /**
+   * Return `true` if this type represents the type 'void'.
+   */
+  bool get isVoid;
+
+  /**
+   * Return the name of this type, or `null` if the type does not have a name,
+   * such as when the type represents the type of an unnamed function.
+   */
+  String get name;
+
+  /**
+   * Return `true` if this type is assignable to the given [type]. A type
+   * <i>T</i> may be assigned to a type <i>S</i>, written <i>T</i> &hArr;
+   * <i>S</i>, iff either <i>T</i> <: <i>S</i> or <i>S</i> <: <i>T</i>.
+   */
+  bool isAssignableTo(DartType type);
+
+  /**
+   * Return `true` if this type is more specific than the given [type].
+   */
+  bool isMoreSpecificThan(DartType type);
+
+  /**
+   * Return `true` if this type is a subtype of the given [type].
+   */
+  bool isSubtypeOf(DartType type);
+
+  /**
+   * Return `true` if this type is a supertype of the given [type]. A type
+   * <i>S</i> is a supertype of <i>T</i>, written <i>S</i> :> <i>T</i>, iff
+   * <i>T</i> is a subtype of <i>S</i>.
+   */
+  bool isSupertypeOf(DartType type);
+
+  /**
+   * Return the type resulting from substituting the given [argumentTypes] for
+   * the given [parameterTypes] in this type. The specification defines this
+   * operation in section 2:
+   * <blockquote>
+   * The notation <i>[x<sub>1</sub>, ..., x<sub>n</sub>/y<sub>1</sub>, ...,
+   * y<sub>n</sub>]E</i> denotes a copy of <i>E</i> in which all occurrences of
+   * <i>y<sub>i</sub>, 1 <= i <= n</i> have been replaced with
+   * <i>x<sub>i</sub></i>.
+   * </blockquote>
+   * Note that, contrary to the specification, this method will not create a
+   * copy of this type if no substitutions were required, but will return this
+   * type directly.
+   *
+   * Note too that the current implementation of this method is only guaranteed
+   * to work when the parameter types are type variables.
+   */
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes);
+}
+
+/**
+ * The type of a function, method, constructor, getter, or setter. Function
+ * types come in three variations:
+ *
+ * * The types of functions that only have required parameters. These have the
+ *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>.
+ * * The types of functions with optional positional parameters. These have the
+ *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
+ *   &hellip;, T<sub>n+k</sub>]) &rarr; T</i>.
+ * * The types of functions with named parameters. These have the general form
+ *   <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
+ *   T<sub>xk</sub> xk}) &rarr; T</i>.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionType implements ParameterizedType {
+  /**
+   * Deprecated: use [typeFormals].
+   */
+  @deprecated
+  List<TypeParameterElement> get boundTypeParameters;
+
+  /**
+   * The formal type parameters of this generic function.
+   * For example `<T> T -> T`.
+   *
+   * These are distinct from the [typeParameters] list, which contains type
+   * parameters from surrounding contexts, and thus are free type variables from
+   * the perspective of this function type.
+   */
+  List<TypeParameterElement> get typeFormals;
+
+  /**
+   * Return a map from the names of named parameters to the types of the named
+   * parameters of this type of function. The entries in the map will be
+   * iterated in the same order as the order in which the named parameters were
+   * defined. If there were no named parameters declared then the map will be
+   * empty.
+   */
+  Map<String, DartType> get namedParameterTypes;
+
+  /**
+   * Return a list containing the types of the normal parameters of this type of
+   * function. The parameter types are in the same order as they appear in the
+   * declaration of the function.
+   */
+  List<DartType> get normalParameterTypes;
+
+  /**
+   * Return a map from the names of optional (positional) parameters to the
+   * types of the optional parameters of this type of function. The entries in
+   * the map will be iterated in the same order as the order in which the
+   * optional parameters were defined. If there were no optional parameters
+   * declared then the map will be empty.
+   */
+  List<DartType> get optionalParameterTypes;
+
+  /**
+   * Return a list containing the parameters elements of this type of function.
+   * The parameter types are in the same order as they appear in the declaration
+   * of the function.
+   */
+  List<ParameterElement> get parameters;
+
+  /**
+   * Return the type of object returned by this type of function.
+   */
+  DartType get returnType;
+
+  /**
+   * Return the type resulting from instantiating (replacing) the given
+   * [argumentTypes] for this function's bound type parameters.
+   */
+  FunctionType instantiate(List<DartType> argumentTypes);
+
+  /**
+   * Return `true` if this type is a subtype of the given [type].
+   *
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i> is
+   * a subtype of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>)
+   * &rarr; S</i>, if all of the following conditions are met:
+   *
+   * * Either
+   *   * <i>S</i> is void, or
+   *   * <i>T &hArr; S</i>.
+   *
+   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
+   *   S<sub>i</sub></i>.
+   *
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
+   * [T<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>]) &rarr; T</i> is a subtype of
+   * the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
+   * [S<sub>n+1</sub>, &hellip;, S<sub>n+m</sub>]) &rarr; S</i>, if all of the
+   * following conditions are met:
+   *
+   * * Either
+   *   * <i>S</i> is void, or
+   *   * <i>T &hArr; S</i>.
+   *
+   * * <i>k</i> >= <i>m</i> and for all <i>i</i>, 1 <= <i>i</i> <= <i>n+m</i>,
+   *   <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.
+   *
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
+   * {T<sub>x1</sub> x1, &hellip;, T<sub>xk</sub> xk}) &rarr; T</i> is a subtype
+   * of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
+   * {S<sub>y1</sub> y1, &hellip;, S<sub>ym</sub> ym}) &rarr; S</i>, if all of
+   * the following conditions are met:
+   * * Either
+   *   * <i>S</i> is void,
+   *   * or <i>T &hArr; S</i>.
+   *
+   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
+   *   S<sub>i</sub></i>.
+   * * <i>k</i> >= <i>m</i> and <i>y<sub>i</sub></i> in <i>{x<sub>1</sub>,
+   *   &hellip;, x<sub>k</sub>}</i>, 1 <= <i>i</i> <= <i>m</i>.
+   * * For all <i>y<sub>i</sub></i> in <i>{y<sub>1</sub>, &hellip;,
+   *   y<sub>m</sub>}</i>, <i>y<sub>i</sub> = x<sub>j</sub> => Tj &hArr; Si</i>.
+   *
+   * In addition, the following subtype rules apply:
+   *
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, []) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>, {}) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {}) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>, []) &rarr; T.</i>
+   *
+   * All functions implement the class `Function`. However not all function
+   * types are a subtype of `Function`. If an interface type <i>I</i> includes a
+   * method named `call()`, and the type of `call()` is the function type
+   * <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
+   */
+  @override
+  bool isSubtypeOf(DartType type);
+
+  @override
+  FunctionType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes);
+
+  /**
+   * Return the type resulting from substituting the given [argumentTypes] for
+   * this type's parameters. This is fully equivalent to
+   * `substitute(argumentTypes, getTypeArguments())`.
+   */
+  @deprecated // use instantiate
+  FunctionType substitute3(List<DartType> argumentTypes);
+}
+
+/**
+ * The type introduced by either a class or an interface, or a reference to such
+ * a type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class InterfaceType implements ParameterizedType {
+  /**
+   * An empty list of types.
+   */
+  static const List<InterfaceType> EMPTY_LIST = const <InterfaceType>[];
+
+  /**
+   * Return a list containing all of the accessors (getters and setters)
+   * declared in this type.
+   */
+  List<PropertyAccessorElement> get accessors;
+
+  /**
+   * Return a list containing all of the constructors declared in this type.
+   */
+  List<ConstructorElement> get constructors;
+
+  @override
+  ClassElement get element;
+
+  /**
+   * Return a list containing all of the interfaces that are implemented by this
+   * interface. Note that this is <b>not</b>, in general, equivalent to getting
+   * the interfaces from this type's element because the types returned by this
+   * method will have had their type parameters replaced.
+   */
+  List<InterfaceType> get interfaces;
+
+  /**
+   * Return a list containing all of the methods declared in this type.
+   */
+  List<MethodElement> get methods;
+
+  /**
+   * Return a list containing all of the mixins that are applied to the class
+   * being extended in order to derive the superclass of this class. Note that
+   * this is <b>not</b>, in general, equivalent to getting the mixins from this
+   * type's element because the types returned by this method will have had
+   * their type parameters replaced.
+   */
+  List<InterfaceType> get mixins;
+
+  /**
+   * Return the type representing the superclass of this type, or null if this
+   * type represents the class 'Object'. Note that this is <b>not</b>, in
+   * general, equivalent to getting the superclass from this type's element
+   * because the type returned by this method will have had it's type parameters
+   * replaced.
+   */
+  InterfaceType get superclass;
+
+  /**
+   * Return the element representing the getter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a getter
+   * with the given name.
+   */
+  PropertyAccessorElement getGetter(String name);
+
+  /**
+   * Return the element representing the method with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a method
+   * with the given name.
+   */
+  MethodElement getMethod(String name);
+
+  /**
+   * Return the element representing the setter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a setter
+   * with the given name.
+   */
+  PropertyAccessorElement getSetter(String name);
+
+  /**
+   * Return `true` if this type is a direct supertype of the given [type]. The
+   * implicit interface of class <i>I</i> is a direct supertype of the implicit
+   * interface of class <i>J</i> iff:
+   *
+   * * <i>I</i> is Object, and <i>J</i> has no extends clause.
+   * * <i>I</i> is listed in the extends clause of <i>J</i>.
+   * * <i>I</i> is listed in the implements clause of <i>J</i>.
+   * * <i>I</i> is listed in the with clause of <i>J</i>.
+   * * <i>J</i> is a mixin application of the mixin of <i>I</i>.
+   */
+  bool isDirectSupertypeOf(InterfaceType type);
+
+  /**
+   * Return `true` if this type is more specific than the given [type]. An
+   * interface type <i>T</i> is more specific than an interface type <i>S</i>,
+   * written <i>T &laquo; S</i>, if one of the following conditions is met:
+   *
+   * * Reflexivity: <i>T</i> is <i>S</i>.
+   * * <i>T</i> is bottom.
+   * * <i>S</i> is dynamic.
+   * * Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
+   * * <i>T</i> is a type parameter and <i>S</i> is the upper bound of <i>T</i>.
+   * * Covariance: <i>T</i> is of the form <i>I&lt;T<sub>1</sub>, &hellip;,
+   *   T<sub>n</sub>&gt;</i> and S</i> is of the form <i>I&lt;S<sub>1</sub>,
+   *   &hellip;, S<sub>n</sub>&gt;</i> and <i>T<sub>i</sub> &laquo;
+   *   S<sub>i</sub></i>, <i>1 <= i <= n</i>.
+   * * Transitivity: <i>T &laquo; U</i> and <i>U &laquo; S</i>.
+   */
+  @override
+  bool isMoreSpecificThan(DartType type);
+
+  /**
+   * Return `true` if this type is a subtype of the given [type]. An interface
+   * type <i>T</i> is a subtype of an interface type <i>S</i>, written <i>T</i>
+   * <: <i>S</i>, iff <i>[bottom/dynamic]T</i> &laquo; <i>S</i> (<i>T</i> is
+   * more specific than <i>S</i>). If an interface type <i>I</i> includes a
+   * method named <i>call()</i>, and the type of <i>call()</i> is the function
+   * type <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
+   */
+  @override
+  bool isSubtypeOf(DartType type);
+
+  /**
+   * Return the element representing the constructor that results from looking
+   * up the constructor with the given [name] in this class with respect to the
+   * given [library], or `null` if the look up fails. The behavior of this
+   * method is defined by the Dart Language Specification in section 12.11.1:
+   * <blockquote>
+   * If <i>e</i> is of the form <b>new</b> <i>T.id()</i> then let <i>q<i> be the
+   * constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor <i>T<i>.
+   * Otherwise, if <i>q</i> is not defined or not accessible, a
+   * NoSuchMethodException is thrown.
+   * </blockquote>
+   */
+  ConstructorElement lookUpConstructor(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the getter that results from looking up the
+   * getter with the given [name] in this class with respect to the given
+   * [library], or `null` if the look up fails. The behavior of this method is
+   * defined by the Dart Language Specification in section 12.15.1:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpGetter(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the getter that results from looking up the
+   * getter with the given [name] in the superclass of this class with respect
+   * to the given [library], or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section
+   * 12.15.1:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpGetterInSuperclass(
+      String name, LibraryElement library);
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, and by default including [thisType]. If the search
+   * fails, this will then search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  PropertyAccessorElement lookUpInheritedGetter(String name,
+      {LibraryElement library, bool thisType: true});
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, starting from this type. If the search fails,
+   * search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  ExecutableElement lookUpInheritedGetterOrMethod(String name,
+      {LibraryElement library});
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, and by default including [thisType]. If the search
+   * fails, this will then search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  MethodElement lookUpInheritedMethod(String name,
+      {LibraryElement library, bool thisType: true});
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, and by default including [thisType]. If the search
+   * fails, this will then search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  PropertyAccessorElement lookUpInheritedSetter(String name,
+      {LibraryElement library, bool thisType: true});
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * method with the given [name] in this class with respect to the given
+   * [library], or `null` if the look up fails. The behavior of this method is
+   * defined by the Dart Language Specification in section 12.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:
+   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
+   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
+   *   <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
+   *   result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>
+   *   Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  MethodElement lookUpMethod(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * method with the given [name] in the superclass of this class with respect
+   * to the given [library], or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section
+   * 12.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:
+   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
+   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
+   * <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
+   * result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>.
+   * Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  MethodElement lookUpMethodInSuperclass(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the setter that results from looking up the
+   * setter with the given [name] in this class with respect to the given
+   * [library], or `null` if the look up fails. The behavior of this method is
+   * defined by the Dart Language Specification in section 12.16:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpSetter(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the setter that results from looking up the
+   * setter with the given [name] in the superclass of this class with respect
+   * to the given [library], or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section 12.16:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpSetterInSuperclass(
+      String name, LibraryElement library);
+
+  @override
+  InterfaceType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes);
+
+  /**
+   * Return the type resulting from substituting the given arguments for this
+   * type's parameters. This is fully equivalent to `substitute2(argumentTypes,
+   * getTypeArguments())`.
+   */
+  // TODO(jmesserly): introduce a new "instantiate" and deprecate this.
+  // The new "instantiate" should work similar to FunctionType.instantiate,
+  // which uses [typeFormals] to model type parameters that haven't been
+  // filled in yet. Those are kept separate from already-substituted type
+  // parameters or free variables from the enclosing scopes, which allows nested
+  // generics to work, such as a generic method in a generic class.
+  InterfaceType substitute4(List<DartType> argumentTypes);
+
+  /**
+   * Returns a "smart" version of the "least upper bound" of the given types.
+   *
+   * If these types have the same element and differ only in terms of the type
+   * arguments, attempts to find a compatible set of type arguments.
+   *
+   * Otherwise, returns the same result as [DartType.getLeastUpperBound].
+   */
+  // TODO(brianwilkerson) This needs to be deprecated and moved to TypeSystem.
+  static InterfaceType getSmartLeastUpperBound(
+          InterfaceType first, InterfaceType second) =>
+      InterfaceTypeImpl.getSmartLeastUpperBound(first, second);
+}
+
+/**
+ * A type that can track substituted type parameters, either for itself after
+ * instantiation, or from a surrounding context.
+ *
+ * For example, given a class `Foo<T>`, after instantiation with S for T, it
+ * will track the substitution `{S/T}`.
+ *
+ * This substitution will be propagated to its members. For example, say our
+ * `Foo<T>` class has a field `T bar;`. When we look up this field, we will get
+ * back a [FieldElement] that tracks the substituted type as `{S/T}T`, so when
+ * we ask for the field type we will get`S`.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ParameterizedType implements DartType {
+  /**
+   * Return a list containing the actual types of the type arguments. If this
+   * type's element does not have type parameters, then the array should be
+   * empty (although it is possible for type arguments to be erroneously
+   * declared). If the element has type parameters and the actual type does not
+   * explicitly include argument values, then the type "dynamic" will be
+   * automatically provided.
+   */
+  List<DartType> get typeArguments;
+
+  /**
+   * Return a list containing all of the type parameters declared for this type.
+   */
+  List<TypeParameterElement> get typeParameters;
+}
+
+/**
+ * The type introduced by a type parameter.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeParameterType implements DartType {
+  /**
+   * An empty list of type parameter types.
+   */
+  static const List<TypeParameterType> EMPTY_LIST = const <TypeParameterType>[];
+
+  @override
+  TypeParameterElement get element;
+}
diff --git a/pkg/analyzer/lib/dart/element/visitor.dart b/pkg/analyzer/lib/dart/element/visitor.dart
new file mode 100644
index 0000000..4a5f393
--- /dev/null
+++ b/pkg/analyzer/lib/dart/element/visitor.dart
@@ -0,0 +1,356 @@
+// 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 analyzer.dart.element.visitor;
+
+import 'package:analyzer/dart/element/element.dart';
+
+/**
+ * An element visitor that will recursively visit all of the elements in an
+ * element model (like instances of the class [RecursiveElementVisitor]). In
+ * addition, when an element of a specific type is visited not only will the
+ * visit method for that specific type of element be invoked, but additional
+ * methods for the supertypes of that element will also be invoked. For example,
+ * using an instance of this class to visit a [MethodElement] will cause the
+ * method [visitMethodElement] to be invoked but will also cause the methods
+ * [visitExecutableElement] and [visitElement] to be subsequently invoked. This
+ * allows visitors to be written that visit all executable elements without
+ * needing to override the visit method for each of the specific subclasses of
+ * [ExecutableElement].
+ *
+ * Note, however, that unlike many visitors, element visitors visit objects
+ * based on the interfaces implemented by those elements. Because interfaces
+ * form a graph structure rather than a tree structure the way classes do, and
+ * because it is generally undesirable for an object to be visited more than
+ * once, this class flattens the interface graph into a pseudo-tree. In
+ * particular, this class treats elements as if the element types were
+ * structured in the following way:
+ *
+ * <pre>
+ * Element
+ *   ClassElement
+ *   CompilationUnitElement
+ *   ExecutableElement
+ *       ConstructorElement
+ *       LocalElement
+ *           FunctionElement
+ *       MethodElement
+ *       PropertyAccessorElement
+ *   ExportElement
+ *   HtmlElement
+ *   ImportElement
+ *   LabelElement
+ *   LibraryElement
+ *   MultiplyDefinedElement
+ *   PrefixElement
+ *   TypeAliasElement
+ *   TypeParameterElement
+ *   UndefinedElement
+ *   VariableElement
+ *       PropertyInducingElement
+ *           FieldElement
+ *           TopLevelVariableElement
+ *       LocalElement
+ *           LocalVariableElement
+ *           ParameterElement
+ *               FieldFormalParameterElement
+ * </pre>
+ *
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or explicitly invoke the more general visit method. Failure to
+ * do so will cause the visit methods for superclasses of the element to not be
+ * invoked and will cause the children of the visited node to not be visited.
+ *
+ * Clients may extend or implement this class.
+ */
+class GeneralizingElementVisitor<R> implements ElementVisitor<R> {
+  @override
+  R visitClassElement(ClassElement element) => visitElement(element);
+
+  @override
+  R visitCompilationUnitElement(CompilationUnitElement element) =>
+      visitElement(element);
+
+  @override
+  R visitConstructorElement(ConstructorElement element) =>
+      visitExecutableElement(element);
+
+  R visitElement(Element element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  R visitExecutableElement(ExecutableElement element) => visitElement(element);
+
+  @override
+  R visitExportElement(ExportElement element) => visitElement(element);
+
+  @override
+  R visitFieldElement(FieldElement element) =>
+      visitPropertyInducingElement(element);
+
+  @override
+  R visitFieldFormalParameterElement(FieldFormalParameterElement element) =>
+      visitParameterElement(element);
+
+  @override
+  R visitFunctionElement(FunctionElement element) => visitLocalElement(element);
+
+  @override
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) =>
+      visitElement(element);
+
+  @override
+  R visitImportElement(ImportElement element) => visitElement(element);
+
+  @override
+  R visitLabelElement(LabelElement element) => visitElement(element);
+
+  @override
+  R visitLibraryElement(LibraryElement element) => visitElement(element);
+
+  R visitLocalElement(LocalElement element) {
+    if (element is LocalVariableElement) {
+      return visitVariableElement(element);
+    } else if (element is ParameterElement) {
+      return visitVariableElement(element);
+    } else if (element is FunctionElement) {
+      return visitExecutableElement(element);
+    }
+    return null;
+  }
+
+  @override
+  R visitLocalVariableElement(LocalVariableElement element) =>
+      visitLocalElement(element);
+
+  @override
+  R visitMethodElement(MethodElement element) =>
+      visitExecutableElement(element);
+
+  @override
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element) =>
+      visitElement(element);
+
+  @override
+  R visitParameterElement(ParameterElement element) =>
+      visitLocalElement(element);
+
+  @override
+  R visitPrefixElement(PrefixElement element) => visitElement(element);
+
+  @override
+  R visitPropertyAccessorElement(PropertyAccessorElement element) =>
+      visitExecutableElement(element);
+
+  R visitPropertyInducingElement(PropertyInducingElement element) =>
+      visitVariableElement(element);
+
+  @override
+  R visitTopLevelVariableElement(TopLevelVariableElement element) =>
+      visitPropertyInducingElement(element);
+
+  @override
+  R visitTypeParameterElement(TypeParameterElement element) =>
+      visitElement(element);
+
+  R visitVariableElement(VariableElement element) => visitElement(element);
+}
+
+/**
+ * A visitor that will recursively visit all of the element in an element model.
+ * For example, using an instance of this class to visit a
+ * [CompilationUnitElement] will also cause all of the types in the compilation
+ * unit to be visited.
+ *
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or must explicitly ask the visited element to visit its
+ * children. Failure to do so will cause the children of the visited element to
+ * not be visited.
+ *
+ * Clients may extend or implement this class.
+ */
+class RecursiveElementVisitor<R> implements ElementVisitor<R> {
+  @override
+  R visitClassElement(ClassElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitCompilationUnitElement(CompilationUnitElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitConstructorElement(ConstructorElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitExportElement(ExportElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFieldElement(FieldElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFieldFormalParameterElement(FieldFormalParameterElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionElement(FunctionElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitImportElement(ImportElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLabelElement(LabelElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLibraryElement(LibraryElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLocalVariableElement(LocalVariableElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitMethodElement(MethodElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitParameterElement(ParameterElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPrefixElement(PrefixElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPropertyAccessorElement(PropertyAccessorElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTopLevelVariableElement(TopLevelVariableElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTypeParameterElement(TypeParameterElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+}
+
+/**
+ * A visitor that will do nothing when visiting an element. It is intended to be
+ * a superclass for classes that use the visitor pattern primarily as a dispatch
+ * mechanism (and hence don't need to recursively visit a whole structure) and
+ * that only need to visit a small number of element types.
+ *
+ * Clients may extend or implement this class.
+ */
+class SimpleElementVisitor<R> implements ElementVisitor<R> {
+  @override
+  R visitClassElement(ClassElement element) => null;
+
+  @override
+  R visitCompilationUnitElement(CompilationUnitElement element) => null;
+
+  @override
+  R visitConstructorElement(ConstructorElement element) => null;
+
+  @override
+  R visitExportElement(ExportElement element) => null;
+
+  @override
+  R visitFieldElement(FieldElement element) => null;
+
+  @override
+  R visitFieldFormalParameterElement(FieldFormalParameterElement element) =>
+      null;
+
+  @override
+  R visitFunctionElement(FunctionElement element) => null;
+
+  @override
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null;
+
+  @override
+  R visitImportElement(ImportElement element) => null;
+
+  @override
+  R visitLabelElement(LabelElement element) => null;
+
+  @override
+  R visitLibraryElement(LibraryElement element) => null;
+
+  @override
+  R visitLocalVariableElement(LocalVariableElement element) => null;
+
+  @override
+  R visitMethodElement(MethodElement element) => null;
+
+  @override
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element) => null;
+
+  @override
+  R visitParameterElement(ParameterElement element) => null;
+
+  @override
+  R visitPrefixElement(PrefixElement element) => null;
+
+  @override
+  R visitPropertyAccessorElement(PropertyAccessorElement element) => null;
+
+  @override
+  R visitTopLevelVariableElement(TopLevelVariableElement element) => null;
+
+  @override
+  R visitTypeParameterElement(TypeParameterElement element) => null;
+}
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index 7d3ed95..05bd4e7 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -2,18 +2,19 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library file_system;
+library analyzer.file_system.file_system;
 
 import 'dart:async';
 
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
 /**
  * [File]s are leaf [Resource]s which contain data.
  */
-abstract class File extends Resource {
+abstract class File implements Resource {
   /**
    * Watch for changes to this file
    */
@@ -52,7 +53,7 @@
 /**
  * [Folder]s are [Resource]s which may contain files and/or other folders.
  */
-abstract class Folder extends Resource {
+abstract class Folder implements Resource {
   /**
    * Watch for changes to the files inside this folder (and in any nested
    * folders, including folders reachable via links).
@@ -134,6 +135,11 @@
  */
 abstract class ResourceProvider {
   /**
+   * Get the absolute path context used by this resource provider.
+   */
+  AbsolutePathContext get absolutePathContext;
+
+  /**
    * Get the path context used by this resource provider.
    */
   Context get pathContext;
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 058f9eb..dc676bb 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -2,19 +2,19 @@
 // for 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 memory_file_system;
+library analyzer.file_system.memory_file_system;
 
 import 'dart:async';
 import 'dart:collection';
 import 'dart:core' hide Resource;
 
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
-import 'file_system.dart';
-
 /**
  * An in-memory implementation of [ResourceProvider].
  * Use `/` as a path separator.
@@ -28,6 +28,9 @@
       new HashMap<String, List<StreamController<WatchEvent>>>();
   int nextStamp = 0;
 
+  final AbsolutePathContext absolutePathContext =
+      new AbsolutePathContext(false);
+
   @override
   Context get pathContext => posix;
 
@@ -44,7 +47,7 @@
 
   /**
    * Delete the folder with the given path
-   * and recurively delete nested files and folders.
+   * and recursively delete nested files and folders.
    */
   void deleteFolder(String path) {
     _checkFolderAtPath(path);
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 303d175..e7a83a4 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -2,19 +2,19 @@
 // for 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 physical_file_system;
+library analyzer.file_system.physical_file_system;
 
 import 'dart:async';
 import 'dart:core' hide Resource;
 import 'dart:io' as io;
 
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
-import 'file_system.dart';
-
 /**
  * A `dart:io` based implementation of [ResourceProvider].
  */
@@ -31,6 +31,9 @@
    */
   static final String SERVER_DIR = ".dartServer";
 
+  final AbsolutePathContext absolutePathContext =
+      new AbsolutePathContext(io.Platform.isWindows);
+
   PhysicalResourceProvider(String fileReadMode(String s)) {
     if (fileReadMode != null) {
       FileBasedSource.fileReadMode = fileReadMode;
@@ -111,7 +114,7 @@
   String readAsStringSync() {
     try {
       io.File file = _entry as io.File;
-      return file.readAsStringSync();
+      return FileBasedSource.fileReadMode(file.readAsStringSync());
     } on io.FileSystemException catch (exception) {
       throw new FileSystemException(exception.path, exception.message);
     }
@@ -129,12 +132,12 @@
 
   @override
   String canonicalizePath(String relPath) {
-    return normalize(join(_entry.absolute.path, relPath));
+    return normalize(join(path, relPath));
   }
 
   @override
   bool contains(String path) {
-    return isWithin(this.path, path);
+    return absolutePathContext.isWithin(this.path, path);
   }
 
   @override
@@ -188,6 +191,9 @@
 
   _PhysicalResource(this._entry);
 
+  AbsolutePathContext get absolutePathContext =>
+      PhysicalResourceProvider.INSTANCE.absolutePathContext;
+
   @override
   bool get exists => _entry.existsSync();
 
@@ -196,7 +202,7 @@
 
   @override
   Folder get parent {
-    String parentPath = dirname(path);
+    String parentPath = absolutePathContext.dirname(path);
     if (parentPath == path) {
       return null;
     }
@@ -207,7 +213,7 @@
   String get path => _entry.absolute.path;
 
   @override
-  String get shortName => basename(path);
+  String get shortName => absolutePathContext.basename(path);
 
   @override
   bool operator ==(other) {
diff --git a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
index ba23b68..fe36a9e 100644
--- a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
@@ -2,8 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library file_instrumentation;
+library analyzer.instrumentation.file_instrumentation;
 
+import 'dart:async';
 import 'dart:io';
 
 import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -30,8 +31,8 @@
   }
 
   @override
-  void shutdown() {
-    _sink.close();
+  Future shutdown() async {
+    await _sink.close();
     _sink = null;
   }
 }
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index 18772de..fe58cdb 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -2,8 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library instrumentation;
+library analyzer.instrumentation.instrumentation;
 
+import 'dart:async';
 import 'dart:convert';
 
 import 'package:analyzer/task/model.dart';
@@ -43,7 +44,7 @@
    * server. This method should be invoked exactly one time and no other methods
    * should be invoked on this instance after this method has been invoked.
    */
-  void shutdown();
+  Future shutdown();
 }
 
 /**
@@ -83,7 +84,7 @@
   int _subprocessCounter = 0;
 
   /**
-   * Initialize a newly created instrumentation service to comunicate with the
+   * Initialize a newly created instrumentation service to communicate with the
    * given [instrumentationServer].
    */
   InstrumentationService(this._instrumentationServer);
@@ -103,9 +104,7 @@
    * Log that the given analysis [task] is being performed in the given
    * [context].
    */
-  void logAnalysisTask(String context, dynamic task) {
-    // TODO(brianwilkerson) When the old task model is removed, change the
-    // parameter type to AnalysisTask.
+  void logAnalysisTask(String context, AnalysisTask task) {
     if (_instrumentationServer != null) {
       String description =
           (task is AnalysisTask) ? task.description : task.toString();
@@ -216,7 +215,7 @@
 
   /**
    * Log the result of executing a subprocess.  [subprocessId] should be the
-   * unique IDreturned by [logSubprocessStart].
+   * unique ID returned by [logSubprocessStart].
    */
   void logSubprocessResult(
       int subprocessId, int exitCode, String stdout, String stderr) {
@@ -290,9 +289,9 @@
    * server. This method should be invoked exactly one time and no other methods
    * should be invoked on this instance after this method has been invoked.
    */
-  void shutdown() {
+  Future shutdown() async {
     if (_instrumentationServer != null) {
-      _instrumentationServer.shutdown();
+      await _instrumentationServer.shutdown();
       _instrumentationServer = null;
     }
   }
@@ -373,9 +372,9 @@
   }
 
   @override
-  void shutdown() {
+  Future shutdown() async {
     for (InstrumentationServer server in _servers) {
-      server.shutdown();
+      await server.shutdown();
     }
   }
 }
diff --git a/pkg/analyzer/lib/plugin/options.dart b/pkg/analyzer/lib/plugin/options.dart
index cec20c2..725315e 100644
--- a/pkg/analyzer/lib/plugin/options.dart
+++ b/pkg/analyzer/lib/plugin/options.dart
@@ -69,7 +69,7 @@
   /// options have changed and to handle those changes appropriately. In
   /// addition to the [options] map, the associated analysis [context] is
   /// provided as well to allow for context-specific configuration.
-  void optionsProcessed(AnalysisContext context, Map<String, YamlNode> options);
+  void optionsProcessed(AnalysisContext context, Map<String, Object> options);
 }
 
 /// Validates options as defined in an analysis options file.
diff --git a/pkg/analyzer/lib/plugin/task.dart b/pkg/analyzer/lib/plugin/task.dart
index d3eb4cd..2a242de 100644
--- a/pkg/analyzer/lib/plugin/task.dart
+++ b/pkg/analyzer/lib/plugin/task.dart
@@ -8,7 +8,7 @@
  */
 library analyzer.plugin.task;
 
-import 'package:analyzer/src/generated/engine.dart' hide WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/plugin/engine_plugin.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:plugin/plugin.dart';
diff --git a/pkg/analyzer/lib/source/analysis_options_provider.dart b/pkg/analyzer/lib/source/analysis_options_provider.dart
index 29062a2..c53bbad 100644
--- a/pkg/analyzer/lib/source/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/source/analysis_options_provider.dart
@@ -2,10 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library source.analysis_options_provider;
+library analyzer.source.analysis_options_provider;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/yaml.dart';
 import 'package:source_span/source_span.dart';
 import 'package:yaml/yaml.dart';
 
@@ -33,7 +34,16 @@
     if (optionsSource == null) {
       return options;
     }
-    YamlNode doc = loadYamlNode(optionsSource);
+
+    YamlNode doc;
+    try {
+      doc = loadYamlNode(optionsSource);
+    } on YamlException catch (e) {
+      throw new OptionsFormatException(e.message, e.span);
+    } catch (e) {
+      throw new OptionsFormatException('Unable to parse YAML document.');
+    }
+
     // Empty options.
     if (doc is YamlScalar && doc.value == null) {
       return options;
@@ -44,19 +54,45 @@
           doc.span);
     }
     if (doc is YamlMap) {
-      doc.forEach((k, v) {
-        if (k is! String) {
+      (doc as YamlMap).nodes.forEach((k, v) {
+        var key;
+        if (k is YamlScalar) {
+          key = k.value;
+        }
+        if (key is! String) {
           throw new OptionsFormatException(
               'Bad options file format (expected String scope key, '
               'got ${k.runtimeType})',
               k != null ? k.span : doc.span);
         }
-        options[k] = v;
+        if (v != null && v is! YamlNode) {
+          throw new OptionsFormatException(
+              'Bad options file format (expected Node value, '
+                  'got ${v.runtimeType}: `${v.toString()}`)',
+              doc.span);
+        }
+        options[key] = v;
       });
     }
     return options;
   }
 
+  /// Merge the given options contents where the values in [defaults] may be
+  /// overridden by [overrides].
+  ///
+  /// Some notes about merge semantics:
+  ///
+  ///   * lists are merged (without duplicates).
+  ///   * lists of scalar values can be promoted to simple maps when merged with
+  ///     maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes
+  ///     {'opt1': true, 'opt2': true}.
+  ///   * maps are merged recursively.
+  ///   * if map values cannot be merged, the overriding value is taken.
+  ///
+  Map<String, YamlNode> merge(
+          Map<String, YamlNode> defaults, Map<String, YamlNode> overrides) =>
+      new Merger().merge(defaults, overrides);
+
   /// Read the contents of [file] as a string.
   /// Returns null if file does not exist.
   String _readAnalysisOptionsFile(File file) {
diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart
new file mode 100644
index 0000000..c82e4f3
--- /dev/null
+++ b/pkg/analyzer/lib/source/embedder.dart
@@ -0,0 +1,233 @@
+// 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.source.embedder;
+
+import 'dart:collection' show HashMap;
+import 'dart:core' hide Resource;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
+import 'package:path/path.dart' as pathos;
+import 'package:yaml/yaml.dart';
+
+/// Given a packageMap, check in each package's lib directory for the
+/// existence of an `_embedder.yaml` file. If the file contains a top level
+/// YamlMap, it will be added to the [embedderYamls] map.
+class EmbedderYamlLocator {
+  static const String EMBEDDER_FILE_NAME = '_embedder.yaml';
+
+  // Map from package's library directory to the parsed
+  // YamlMap.
+  final Map<Folder, YamlMap> embedderYamls = new HashMap<Folder, YamlMap>();
+
+  EmbedderYamlLocator(Map<String, List<Folder>> packageMap) {
+    if (packageMap != null) {
+      refresh(packageMap);
+    }
+  }
+
+  void refresh(Map<String, List<Folder>> packageMap) {
+    // Clear existing.
+    embedderYamls.clear();
+    if (packageMap == null) {
+      return;
+    }
+    packageMap.forEach(_processPackage);
+  }
+
+  /// Programatically add an _embedder.yaml mapping.
+  void addEmbedderYaml(Folder libDir, String embedderYaml) {
+    _processEmbedderYaml(libDir, embedderYaml);
+  }
+
+  /// Given a package [name] and a list of folders ([libDirs]),
+  /// add any found `_embedder.yaml` files.
+  void _processPackage(String name, List<Folder> libDirs) {
+    for (Folder libDir in libDirs) {
+      String embedderYaml = _readEmbedderYaml(libDir);
+      if (embedderYaml != null) {
+        _processEmbedderYaml(libDir, embedderYaml);
+      }
+    }
+  }
+
+  /// Given the yaml for an embedder ([embedderYaml]) and a folder
+  /// ([libDir]), setup the uri mapping.
+  void _processEmbedderYaml(Folder libDir, String embedderYaml) {
+    YamlNode yaml;
+    try {
+      yaml = loadYaml(embedderYaml);
+    } catch (_) {
+      // TODO(pquitslund): Notify developer that something is wrong with the
+      // _embedder.yaml file in libDir.
+      return;
+    }
+    if (yaml == null) {
+      // TODO(pquitslund): Notify developer that something is wrong with the
+      // _embedder.yaml file in libDir.
+      return;
+    }
+    if (yaml is! YamlMap) {
+      // TODO(pquitslund): Notify developer that something is wrong with the
+      // _embedder.yaml file in libDir.
+      return;
+    }
+    embedderYamls[libDir] = yaml;
+  }
+
+
+  /// Read the contents of [libDir]/[EMBEDDER_FILE_NAME] as a string.
+  /// Returns null if the file doesn't exist.
+  String _readEmbedderYaml(Folder libDir) {
+    File file = libDir.getChild(EMBEDDER_FILE_NAME);
+    try {
+      return file.readAsStringSync();
+    } on FileSystemException {
+      // File can't be read.
+      return null;
+    }
+  }
+}
+
+/// Given the [embedderYamls] from [EmbedderYamlLocator] check each one for the
+/// top level key 'embedder_libs'. Under the 'embedder_libs' key are key value
+/// pairs. Each key is a 'dart:' library uri and each value is a path
+/// (relative to the directory containing `_embedder.yaml`) to a dart script
+/// for the given library. For example:
+///
+/// embedder_libs:
+///   'dart:io': '../../sdk/io/io.dart'
+///
+/// If a key doesn't begin with `dart:` it is ignored.
+///
+class EmbedderUriResolver extends UriResolver {
+  static const String DART_COLON_PREFIX = 'dart:';
+
+  final Map<String, String> _urlMappings = <String, String>{};
+
+  /// Construct a [EmbedderUriResolver] from a package map
+  /// (see [PackageMapProvider]).
+  EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls) {
+    if (embedderYamls == null) {
+      return;
+    }
+    embedderYamls.forEach(_processEmbedderYaml);
+  }
+
+  void _processEmbedderYaml(Folder libDir, YamlMap map) {
+    YamlNode embedder_libs = map['embedder_libs'];
+    if (embedder_libs == null) {
+      return;
+    }
+    if (embedder_libs is! YamlMap) {
+      return;
+    }
+    (embedder_libs as YamlMap).forEach((k, v) =>
+        _processEmbedderLibs(k, v, libDir));
+  }
+
+  /// Install the mapping from [name] to [libDir]/[file].
+  void _processEmbedderLibs(String name, String file, Folder libDir) {
+    if (!name.startsWith(DART_COLON_PREFIX)) {
+      // SDK libraries must begin with 'dart:'.
+      // TODO(pquitslund): Notify developer that something is wrong with the
+      // _embedder.yaml file in libDir.
+      return;
+    }
+    String key = name;
+    String value = libDir.canonicalizePath(file);
+    _urlMappings[key] = value;
+  }
+
+  /// Number of embedder libraries.
+  int get length => _urlMappings.length;
+
+  /// Return the path mapping for [libName] or null if there is none.
+  String operator [](String libName) => _urlMappings[libName];
+
+  @override
+  Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
+    String libraryName = _libraryName(importUri);
+    String partPath = _partPath(importUri);
+    // Lookup library name in mappings.
+    String mapping = _urlMappings[libraryName];
+    if (mapping == null) {
+      // Not found.
+      return null;
+    }
+    // This mapping points to the main entry file of the dart: library.
+    Uri libraryEntry = new Uri.file(mapping);
+    if (!libraryEntry.isAbsolute) {
+      // We expect an absolute path.
+      return null;
+    }
+
+    if (partPath != null) {
+      return _resolvePart(libraryEntry, partPath, importUri);
+    } else {
+      return _resolveEntry(libraryEntry, importUri);
+    }
+  }
+
+  @override
+  Uri restoreAbsolute(Source source) {
+    String extensionName = _findExtensionNameFor(source.fullName);
+    if (extensionName != null) {
+      return Uri.parse(extensionName);
+    }
+    // TODO(johnmccutchan): Handle restoring parts.
+    return null;
+  }
+
+  /// Return the extension name for [fullName] or `null`.
+  String _findExtensionNameFor(String fullName) {
+    String result;
+    _urlMappings.forEach((extensionName, pathMapping) {
+      if (pathMapping == fullName) {
+        result = extensionName;
+      }
+    });
+    return result;
+  }
+
+  /// Return the library name of [importUri].
+  String _libraryName(Uri importUri) {
+    String uri = importUri.toString();
+    int index = uri.indexOf('/');
+    if (index >= 0) {
+      return uri.substring(0, index);
+    }
+    return uri;
+  }
+
+  /// Return the part path of [importUri].
+  String _partPath(Uri importUri) {
+    String uri = importUri.toString();
+    int index = uri.indexOf('/');
+    if (index >= 0) {
+      return uri.substring(index + 1);
+    }
+    return null;
+  }
+
+  /// Resolve an import of an sdk extension.
+  Source _resolveEntry(Uri libraryEntry, Uri importUri) {
+    // Library entry.
+    JavaFile javaFile = new JavaFile.fromUri(libraryEntry);
+    return new FileBasedSource(javaFile, importUri);
+  }
+
+  /// Resolve a 'part' statement inside an sdk extension.
+  Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
+    // Library part.
+    String directory = pathos.dirname(libraryEntry.path);
+    Uri partUri = new Uri.file(pathos.join(directory, partPath));
+    assert(partUri.isAbsolute);
+    JavaFile javaFile = new JavaFile.fromUri(partUri);
+    return new FileBasedSource(javaFile, importUri);
+  }
+}
diff --git a/pkg/analyzer/lib/source/error_processor.dart b/pkg/analyzer/lib/source/error_processor.dart
new file mode 100644
index 0000000..8e369aa
--- /dev/null
+++ b/pkg/analyzer/lib/source/error_processor.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.
+
+library analyzer.source.error_processor;
+
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:yaml/yaml.dart';
+
+/// Error processor configuration derived from analysis (or embedder) options.
+class ErrorConfig {
+  /// The processors in this config.
+  final List<ErrorProcessor> processors = <ErrorProcessor>[];
+
+  /// Create an error config for the given error code map.
+  /// For example:
+  ///     new ErrorConfig({'missing_return' : 'error'});
+  /// will create a processor config that turns `missing_return` hints into
+  /// errors.
+  ErrorConfig(Object codeMap) {
+    _processMap(codeMap);
+  }
+
+  void _process(String code, Object action) {
+    action = toLowerCase(action);
+    code = toUpperCase(code);
+    if (AnalyzerOptions.ignoreSynonyms.contains(action)) {
+      processors.add(new ErrorProcessor.ignore(code));
+    } else {
+      ErrorSeverity severity = _toSeverity(action);
+      if (severity != null) {
+        processors.add(new ErrorProcessor(code, severity));
+      }
+    }
+  }
+
+  void _processMap(Object codes) {
+    if (codes is YamlMap) {
+      // TODO(pq): stop traversing nodes and unify w/ standard map handling
+      codes.nodes.forEach((k, v) {
+        if (k is YamlScalar && v is YamlScalar) {
+          _process(k.value, v.value);
+        }
+      });
+    } else if (codes is Map) {
+      codes.forEach((k, v) {
+        if (k is String) {
+          _process(k, v);
+        }
+      });
+    }
+  }
+
+  ErrorSeverity _toSeverity(String severity) => severityMap[severity];
+}
+
+/// String identifiers mapped to associated severities.
+const Map<String, ErrorSeverity> severityMap = const {
+  'error': ErrorSeverity.ERROR,
+  'info': ErrorSeverity.INFO,
+  'warning': ErrorSeverity.WARNING
+};
+
+/// Process errors by filtering or changing associated [ErrorSeverity].
+class ErrorProcessor {
+  /// The code name of the associated error.
+  final String code;
+
+  /// The desired severity of the processed error.
+  ///
+  /// If `null`, this processor will "filter" the associated error code.
+  final ErrorSeverity severity;
+
+  /// Create an error processor that assigns errors with this [code] the
+  /// given [severity].
+  ///
+  /// If [severity] is `null`, matching errors will be filtered.
+  ErrorProcessor(this.code, [this.severity]);
+
+  /// Create an error processor that ignores the given error by [code].
+  factory ErrorProcessor.ignore(String code) => new ErrorProcessor(code);
+
+  /// Check if this processor applies to the given [error].
+  bool appliesTo(AnalysisError error) => code == error.errorCode.name;
+
+  /// Return an error processor associated with this [context] for the given
+  /// [error], or `null` if none is found.
+  static ErrorProcessor getProcessor(
+      AnalysisContext context, AnalysisError error) {
+    if (context == null) {
+      return null;
+    }
+    List<ErrorProcessor> processors =
+        context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+    return processors.firstWhere((ErrorProcessor p) => p.appliesTo(error),
+        orElse: () => null);
+  }
+}
diff --git a/pkg/analyzer/lib/source/package_map_provider.dart b/pkg/analyzer/lib/source/package_map_provider.dart
index 85b493d..b2eb8b6 100644
--- a/pkg/analyzer/lib/source/package_map_provider.dart
+++ b/pkg/analyzer/lib/source/package_map_provider.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library source.package_map_provider;
+library analyzer.source.package_map_provider;
 
 import 'package:analyzer/file_system/file_system.dart';
 
diff --git a/pkg/analyzer/lib/source/package_map_resolver.dart b/pkg/analyzer/lib/source/package_map_resolver.dart
index 0fa12ae..4325582 100644
--- a/pkg/analyzer/lib/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/source/package_map_resolver.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library source.package_map_resolver;
+library analyzer.source.package_map_resolver;
 
 import 'dart:core' hide Resource;
 
diff --git a/pkg/analyzer/lib/source/path_filter.dart b/pkg/analyzer/lib/source/path_filter.dart
index 40e81a6..f449610 100644
--- a/pkg/analyzer/lib/source/path_filter.dart
+++ b/pkg/analyzer/lib/source/path_filter.dart
@@ -2,12 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library source.path_filter;
+library analyzer.source.path_filter;
 
-import 'package:glob/glob.dart' as glob;
+import 'package:analyzer/src/util/glob.dart';
 import 'package:path/path.dart' as path;
 
-/// Filter paths against a set of [ignorePatterns] relative to a [root]
+/// Filter paths against a set of [_ignorePatterns] relative to a [root]
 /// directory. Paths outside of [root] are also ignored.
 class PathFilter {
   /// The path context to use when manipulating paths.
@@ -17,7 +17,7 @@
   final String root;
 
   /// List of ignore patterns that paths are tested against.
-  final List<glob.Glob> _ignorePatterns = new List<glob.Glob>();
+  final List<Glob> _ignorePatterns = new List<Glob>();
 
   /// Construct a new path filter rooted at [root] with [ignorePatterns].
   /// If [pathContext] is not specified, then the system path context is used.
@@ -39,11 +39,20 @@
     _ignorePatterns.clear();
     if (ignorePatterns != null) {
       for (var ignorePattern in ignorePatterns) {
-        _ignorePatterns.add(new glob.Glob(ignorePattern));
+        _ignorePatterns.add(new Glob(pathContext.separator, ignorePattern));
       }
     }
   }
 
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    for (Glob pattern in _ignorePatterns) {
+      sb.write('$pattern ');
+    }
+    sb.writeln('');
+    return sb.toString();
+  }
+
   /// Returns the absolute path of [path], relative to [root].
   String _canonicalize(String path) =>
       pathContext.normalize(pathContext.join(root, path));
@@ -54,7 +63,7 @@
   /// Returns true if [path] matches any ignore patterns.
   bool _match(String path) {
     path = _relative(path);
-    for (var glob in _ignorePatterns) {
+    for (Glob glob in _ignorePatterns) {
       if (glob.matches(path)) {
         return true;
       }
@@ -64,13 +73,4 @@
 
   /// Returns the relative portion of [path] from [root].
   String _relative(String path) => pathContext.relative(path, from: root);
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    for (var pattern in _ignorePatterns) {
-      sb.write('$pattern ');
-    }
-    sb.writeln('');
-    return sb.toString();
-  }
 }
diff --git a/pkg/analyzer/lib/source/pub_package_map_provider.dart b/pkg/analyzer/lib/source/pub_package_map_provider.dart
index 07fdba7..a7b2c42 100644
--- a/pkg/analyzer/lib/source/pub_package_map_provider.dart
+++ b/pkg/analyzer/lib/source/pub_package_map_provider.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library source.pub_package_map_provider;
+library analyzer.source.pub_package_map_provider;
 
 import 'dart:collection';
 import 'dart:convert';
@@ -59,6 +59,13 @@
 
   @override
   PackageMapInfo computePackageMap(Folder folder) {
+    // If the pubspec.lock file does not exist, no need to run anything.
+    {
+      String lockPath = getPubspecLockPath(folder);
+      if (!resourceProvider.getFile(lockPath).exists) {
+        return computePackageMapError(folder);
+      }
+    }
     // TODO(paulberry) make this asynchronous so that we can (a) do other
     // analysis while it's in progress, and (b) time out if it takes too long
     // to respond.
@@ -96,13 +103,18 @@
     // we'll know when to try running "pub list-package-dirs" again.
     // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when
     // an error occurs, so just assume there is one dependency, "pubspec.lock".
-    List<String> dependencies = <String>[
-      resourceProvider.pathContext.join(folder.path, PUBSPEC_LOCK_NAME)
-    ];
+    String lockPath = getPubspecLockPath(folder);
+    List<String> dependencies = <String>[lockPath];
     return new PackageMapInfo(null, dependencies.toSet());
   }
 
   /**
+   * Return the path to the `pubspec.lock` file in the given [folder].
+   */
+  String getPubspecLockPath(Folder folder) =>
+      resourceProvider.pathContext.join(folder.path, PUBSPEC_LOCK_NAME);
+
+  /**
    * Decode the JSON output from pub into a package map.  Paths in the
    * output are considered relative to [folder].
    */
diff --git a/pkg/analyzer/lib/source/sdk_ext.dart b/pkg/analyzer/lib/source/sdk_ext.dart
index 646a19f..fc7155a 100644
--- a/pkg/analyzer/lib/source/sdk_ext.dart
+++ b/pkg/analyzer/lib/source/sdk_ext.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library source.sdk_ext;
+library analyzer.source.sdk_ext;
 
 import 'dart:convert';
 import 'dart:core' hide Resource;
diff --git a/pkg/analyzer/lib/src/cancelable_future.dart b/pkg/analyzer/lib/src/cancelable_future.dart
index 733cac5..8ae070b 100644
--- a/pkg/analyzer/lib/src/cancelable_future.dart
+++ b/pkg/analyzer/lib/src/cancelable_future.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library cancelable_future;
+library analyzer.src.cancelable_future;
 
 import 'dart:async';
 
diff --git a/pkg/analyzer/lib/src/codegen/text_formatter.dart b/pkg/analyzer/lib/src/codegen/text_formatter.dart
index 28669e0..5274901 100644
--- a/pkg/analyzer/lib/src/codegen/text_formatter.dart
+++ b/pkg/analyzer/lib/src/codegen/text_formatter.dart
@@ -8,10 +8,9 @@
  */
 library analyzer.src.codegen.text_formatter;
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
-import 'tools.dart';
-
 final RegExp whitespace = new RegExp(r'\s');
 
 /**
diff --git a/pkg/analyzer/lib/src/codegen/tools.dart b/pkg/analyzer/lib/src/codegen/tools.dart
index 3b2115d..dd6ee41 100644
--- a/pkg/analyzer/lib/src/codegen/tools.dart
+++ b/pkg/analyzer/lib/src/codegen/tools.dart
@@ -9,14 +9,13 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/html.dart';
+import 'package:analyzer/src/codegen/text_formatter.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:path/path.dart';
 
-import 'html.dart';
-import 'text_formatter.dart';
-
-final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
 final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
+final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
 
 /**
  * Join the given strings using camelCase.  If [doCapitalize] is true, the first
@@ -43,13 +42,16 @@
 
 /**
  * Type of functions used to compute the contents of a set of generated files.
+ * [pkgPath] is the path to the current package.
  */
-typedef Map<String, FileContentsComputer> DirectoryContentsComputer();
+typedef Map<String, FileContentsComputer> DirectoryContentsComputer(
+    String pkgPath);
 
 /**
  * Type of functions used to compute the contents of a generated file.
+ * [pkgPath] is the path to the current package.
  */
-typedef String FileContentsComputer();
+typedef String FileContentsComputer(String pkgPath);
 
 /**
  * Mixin class for generating code.
@@ -97,14 +99,14 @@
    */
   void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) {
     if (containsOnlyWhitespace(docs)) return;
-    writeln(codeGeneratorSettings.docCommentStartMarker);
+    if (codeGeneratorSettings.docCommentStartMarker != null) writeln(codeGeneratorSettings.docCommentStartMarker);
     int width = codeGeneratorSettings.commentLineLength;
     bool javadocStyle = codeGeneratorSettings.languageName == 'java';
     indentBy(codeGeneratorSettings.docCommentLineLeader, () {
       write(nodesToText(docs, width - _state.indent.length, javadocStyle,
           removeTrailingNewLine: removeTrailingNewLine));
     });
-    writeln(codeGeneratorSettings.docCommentEndMarker);
+    if (codeGeneratorSettings.docCommentEndMarker != null) writeln(codeGeneratorSettings.docCommentEndMarker);
   }
 
   /**
@@ -156,7 +158,7 @@
     if (codeGeneratorSettings.languageName == 'java') {
       header = '''
 /*
- * Copyright (c) 2014, the Dart project authors.
+ * Copyright (c) 2015, the Dart project authors.
  *
  * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
  * in compliance with the License. You may obtain a copy of the License at
@@ -261,10 +263,75 @@
       this.indent: '  '});
 }
 
+/**
+ * Abstract base class representing behaviors common to generated files and
+ * generated directories.
+ */
 abstract class GeneratedContent {
-  FileSystemEntity get outputFile;
-  bool check();
-  void generate();
+  /**
+   * Check whether the [output] has the correct contents, and return true if it
+   * does.  [pkgPath] is the path to the current package.
+   */
+  bool check(String pkgPath);
+
+  /**
+   * Replace the [output] with the correct contents.  [pkgPath] is the path to
+   * the current package.
+   */
+  void generate(String pkgPath);
+
+  /**
+   * Get a [FileSystemEntity] representing the output file or directory.
+   * [pkgPath] is the path to the current package.
+   */
+  FileSystemEntity output(String pkgPath);
+
+  /**
+   * Check that all of the [targets] are up to date.  If they are not, print
+   * out a message instructing the user to regenerate them, and exit with a
+   * nonzero error code.
+   *
+   * [pkgPath] is the path to the current package.  [generatorRelPath] is the
+   * path to a .dart script the user may use to regenerate the targets.
+   *
+   * To avoid mistakes when run on Windows, [generatorRelPath] always uses
+   * POSIX directory separators.
+   */
+  static void checkAll(String pkgPath, String generatorRelPath,
+      Iterable<GeneratedContent> targets) {
+    bool generateNeeded = false;
+    for (GeneratedContent target in targets) {
+      if (!target.check(pkgPath)) {
+        print(
+            '${target.output(pkgPath).absolute} does not have expected contents.');
+        generateNeeded = true;
+      }
+    }
+    if (generateNeeded) {
+      print('Please regenerate using:');
+      String executable = Platform.executable;
+      String packageRoot = '';
+      if (Platform.packageRoot != null) {
+        packageRoot = ' --package-root=${Platform.packageRoot}';
+      }
+      String generateScript =
+          join(pkgPath, joinAll(posix.split(generatorRelPath)));
+      print('  $executable$packageRoot $generateScript');
+      exit(1);
+    } else {
+      print('All generated files up to date.');
+    }
+  }
+
+  /**
+   * Regenerate all of the [targets].  [pkgPath] is the path to the current
+   * package.
+   */
+  static void generateAll(String pkgPath, Iterable<GeneratedContent> targets) {
+    for (GeneratedContent target in targets) {
+      target.generate(pkgPath);
+    }
+  }
 }
 
 /**
@@ -284,25 +351,15 @@
 
   GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer);
 
-  /**
-   * Get a Directory object representing the output directory.
-   */
-  Directory get outputFile =>
-      new Directory(joinAll(posix.split(outputDirPath)));
-
-  /**
-   * Check whether the directory has the correct contents, and return true if it
-   * does.
-   */
   @override
-  bool check() {
-    Map<String, FileContentsComputer> map = directoryContentsComputer();
+  bool check(String pkgPath) {
+    Directory outputDirectory = output(pkgPath);
+    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
     try {
       for (String file in map.keys) {
         FileContentsComputer fileContentsComputer = map[file];
-        String expectedContents = fileContentsComputer();
-        File outputFile =
-            new File(joinAll(posix.split(posix.join(outputDirPath, file))));
+        String expectedContents = fileContentsComputer(pkgPath);
+        File outputFile = new File(posix.join(outputDirectory.path, file));
         String actualContents = outputFile.readAsStringSync();
         // Normalize Windows line endings to Unix line endings so that the
         // comparison doesn't fail on Windows.
@@ -312,7 +369,7 @@
         }
       }
       int nonHiddenFileCount = 0;
-      outputFile
+      outputDirectory
           .listSync(recursive: false, followLinks: false)
           .forEach((FileSystemEntity fileSystemEntity) {
         if (fileSystemEntity is File &&
@@ -334,30 +391,30 @@
     return true;
   }
 
-  /**
-   * Replace the directory with the correct contents.  [spec] is the "tool/spec"
-   * directory.  If [spec] is unspecified, it is assumed to be the directory
-   * containing Platform.executable.
-   */
   @override
-  void generate() {
+  void generate(String pkgPath) {
+    Directory outputDirectory = output(pkgPath);
     try {
       // delete the contents of the directory (and the directory itself)
-      outputFile.deleteSync(recursive: true);
+      outputDirectory.deleteSync(recursive: true);
     } catch (e) {
       // Error caught while trying to delete the directory, this can happen if
       // it didn't yet exist.
     }
     // re-create the empty directory
-    outputFile.createSync(recursive: true);
+    outputDirectory.createSync(recursive: true);
 
     // generate all of the files in the directory
-    Map<String, FileContentsComputer> map = directoryContentsComputer();
+    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
     map.forEach((String file, FileContentsComputer fileContentsComputer) {
-      File outputFile = new File(joinAll(posix.split(outputDirPath + file)));
-      outputFile.writeAsStringSync(fileContentsComputer());
+      File outputFile = new File(posix.join(outputDirectory.path, file));
+      outputFile.writeAsStringSync(fileContentsComputer(pkgPath));
     });
   }
+
+  @override
+  Directory output(String pkgPath) =>
+      new Directory(join(pkgPath, joinAll(posix.split(outputDirPath))));
 }
 
 /**
@@ -379,18 +436,10 @@
 
   GeneratedFile(this.outputPath, this.computeContents);
 
-  /**
-   * Get a File object representing the output file.
-   */
-  File get outputFile => new File(joinAll(posix.split(outputPath)));
-
-  /**
-   * Check whether the file has the correct contents, and return true if it
-   * does.
-   */
   @override
-  bool check() {
-    String expectedContents = computeContents();
+  bool check(String pkgPath) {
+    File outputFile = output(pkgPath);
+    String expectedContents = computeContents(pkgPath);
     try {
       String actualContents = outputFile.readAsStringSync();
       // Normalize Windows line endings to Unix line endings so that the
@@ -405,14 +454,14 @@
     }
   }
 
-  /**
-   * Replace the file with the correct contents.  [spec] is the "tool/spec"
-   * directory.  If [spec] is unspecified, it is assumed to be the directory
-   * containing Platform.executable.
-   */
-  void generate() {
-    outputFile.writeAsStringSync(computeContents());
+  @override
+  void generate(String pkgPath) {
+    output(pkgPath).writeAsStringSync(computeContents(pkgPath));
   }
+
+  @override
+  File output(String pkgPath) =>
+      new File(join(pkgPath, joinAll(posix.split(outputPath))));
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index a609421..afe0216 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -7,8 +7,7 @@
 import 'dart:async';
 import 'dart:collection';
 
-import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisEngine, CacheState, InternalAnalysisContext, RetentionPriority;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -41,9 +40,9 @@
   final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
       new ReentrantSynchronousStream<InvalidatedResult>();
 
-  final List<
-      ReentrantSynchronousStreamSubscription> onResultInvalidatedPartitionSubscriptions = <
-      ReentrantSynchronousStreamSubscription>[];
+  final List<ReentrantSynchronousStreamSubscription>
+      onResultInvalidatedPartitionSubscriptions =
+      <ReentrantSynchronousStreamSubscription>[];
 
   /**
    * Initialize a newly created cache to have the given [_partitions]. The
@@ -66,7 +65,7 @@
    */
   Iterable<Source> get sources {
     return _partitions
-        .map((CachePartition partition) => partition._sources)
+        .map((CachePartition partition) => partition.sources)
         .expand((Iterable<Source> sources) => sources);
   }
 
@@ -191,7 +190,7 @@
         <Map<AnalysisTarget, CacheEntry>>[];
     for (CachePartition partition in _partitions) {
       if (context == null || partition.context == context) {
-        maps.add(partition.map);
+        maps.add(partition.entryMap);
       }
     }
     return new MultipleMapIterator<AnalysisTarget, CacheEntry>(maps);
@@ -385,7 +384,7 @@
    * Return the value of the result represented by the given [descriptor], or
    * the default value for the result if this entry does not have a valid value.
    */
-  /*<V>*/ dynamic /*V*/ getValue(ResultDescriptor /*<V>*/ descriptor) {
+  dynamic /*=V*/ getValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor) {
     ResultData data = _resultMap[descriptor];
     if (data == null) {
       return descriptor.defaultValue;
@@ -483,11 +482,8 @@
    * Set the value of the result represented by the given [descriptor] to the
    * given [value].
    */
-  /*<V>*/ void setValue(
-      ResultDescriptor /*<V>*/ descriptor,
-      dynamic /*V*/
-      value,
-      List<TargetedResult> dependedOn) {
+  void setValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor,
+      dynamic /*=V*/ value, List<TargetedResult> dependedOn) {
 //    {
 //      String valueStr = '$value';
 //      if (valueStr.length > 20) {
@@ -495,7 +491,7 @@
 //      }
 //      valueStr = valueStr.replaceAll('\n', '\\n');
 //      print(
-//          'setValue $descriptor for $target value=$valueStr deps=$dependedOn');
+//          'setValue $descriptor for $target value=$valueStr $dependedOn=$dependedOn');
 //    }
     _validateStateChange(descriptor, CacheState.VALID);
     TargetedResult thisResult = new TargetedResult(target, descriptor);
@@ -509,14 +505,16 @@
   }
 
   /**
-   * Set the value of the result represented by the given [descriptor] to the
-   * given [value], keep its dependency, invalidate all the dependent result.
+   * If the result represented by the given [descriptor] is valid, set
+   * it to the given [value], keep its dependency, and if [invalidateDependent]
+   * invalidate all the dependent result.
    */
   void setValueIncremental(
       ResultDescriptor descriptor, dynamic value, bool invalidateDependent) {
     ResultData data = getResultData(descriptor);
-    data.state = CacheState.VALID;
-    data.value = value;
+    if (data.state == CacheState.VALID || data.state == CacheState.FLUSHED) {
+      data.value = value;
+    }
     if (invalidateDependent) {
       _invalidateDependentResults(nextInvalidateId++, data, null, 0);
     }
@@ -583,7 +581,7 @@
     _invalidateDependentResults(id, thisData, delta, level + 1);
     // If empty and not explicitly added, remove the entry altogether.
     if (_resultMap.isEmpty && !explicitlyAdded) {
-      _partition._targetMap.remove(target);
+      _partition.entryMap.remove(target);
       _partition._removeIfSource(target);
     }
     // Notify controller.
@@ -856,18 +854,18 @@
    * A table mapping the targets belonging to this partition to the information
    * known about those targets.
    */
-  HashMap<AnalysisTarget, CacheEntry> _targetMap =
+  final HashMap<AnalysisTarget, CacheEntry> entryMap =
       new HashMap<AnalysisTarget, CacheEntry>();
 
   /**
    * A set of the [Source] targets.
    */
-  final HashSet<Source> _sources = new HashSet<Source>();
+  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>>{};
+  final Map<String, List<Source>> pathToSource = <String, List<Source>>{};
 
   /**
    * Initialize a newly created cache partition, belonging to the given
@@ -876,35 +874,28 @@
   CachePartition(this.context);
 
   /**
-   * Return a table mapping the targets known to the context to the information
-   * known about the target.
-   *
-   * <b>Note:</b> This method is only visible for use by [AnalysisCache] and
-   * should not be used for any other purpose.
-   */
-  Map<AnalysisTarget, CacheEntry> get map => _targetMap;
-
-  /**
    * Notifies the partition that the client is going to stop using it.
    */
   void dispose() {
-    for (CacheEntry entry in _targetMap.values) {
+    for (CacheEntry entry in entryMap.values) {
       entry.dispose();
     }
-    _targetMap.clear();
+    entryMap.clear();
+    sources.clear();
+    pathToSource.clear();
   }
 
   /**
    * Return the entry associated with the given [target].
    */
-  CacheEntry get(AnalysisTarget target) => _targetMap[target];
+  CacheEntry get(AnalysisTarget target) => entryMap[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];
+    List<Source> sources = pathToSource[path];
     return sources != null ? sources : Source.EMPTY_LIST;
   }
 
@@ -918,7 +909,7 @@
    * cache entries.
    */
   MapIterator<AnalysisTarget, CacheEntry> iterator() =>
-      new SingleMapIterator<AnalysisTarget, CacheEntry>(_targetMap);
+      new SingleMapIterator<AnalysisTarget, CacheEntry>(entryMap);
 
   /**
    * Puts the given [entry] into the partition.
@@ -931,7 +922,7 @@
     }
     entry._partition = this;
     entry.fixExceptionState();
-    _targetMap[target] = entry;
+    entryMap[target] = entry;
     _addIfSource(target);
   }
 
@@ -944,7 +935,7 @@
     for (CacheFlushManager flushManager in _flushManagerMap.values) {
       flushManager.targetRemoved(target);
     }
-    CacheEntry entry = _targetMap.remove(target);
+    CacheEntry entry = entryMap.remove(target);
     if (entry != null) {
       entry._invalidateAll();
     }
@@ -983,16 +974,16 @@
   /**
    * Return the number of targets that are mapped to cache entries.
    */
-  int size() => _targetMap.length;
+  int size() => entryMap.length;
 
   /**
-   * If the given [target] is a [Source], adds it to [_sources].
+   * If the given [target] is a [Source], adds it to [sources].
    */
   void _addIfSource(AnalysisTarget target) {
     if (target is Source) {
-      _sources.add(target);
+      sources.add(target);
       String fullName = target.fullName;
-      _pathToSources.putIfAbsent(fullName, () => <Source>[]).add(target);
+      pathToSource.putIfAbsent(fullName, () => <Source>[]).add(target);
     }
   }
 
@@ -1022,17 +1013,17 @@
   }
 
   /**
-   * If the given [target] is a [Source], remove it from the list of [_sources].
+   * If the given [target] is a [Source], remove it from the list of [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);
+      sources.remove(target);
+      String path = target.fullName;
+      List<Source> pathSources = pathToSource[path];
+      if (pathSources != null) {
+        pathSources.remove(target);
+        if (pathSources.isEmpty) {
+          pathToSource.remove(path);
         }
       }
     }
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 4f2c08d..4714557 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -7,22 +7,17 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/task.dart';
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.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
-        AnalysisCache,
-        CachePartition,
-        SdkCachePartition,
-        UniversalCachePartition,
-        WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht show HtmlUnit;
 import 'package:analyzer/src/generated/incremental_resolver.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -81,6 +76,9 @@
    */
   AnalysisOptionsImpl _options = new AnalysisOptionsImpl();
 
+  /// The embedder yaml locator for this context.
+  EmbedderYamlLocator _embedderYamlLocator = new EmbedderYamlLocator(null);
+
   /**
    * A flag indicating whether this context is disposed.
    */
@@ -207,21 +205,6 @@
   CompilationUnit incrementalResolutionValidation_lastUnit;
 
   /**
-   * A factory to override how the [ResolverVisitor] is created.
-   */
-  ResolverVisitorFactory resolverVisitorFactory;
-
-  /**
-   * A factory to override how the [TypeResolverVisitor] is created.
-   */
-  TypeResolverVisitorFactory typeResolverVisitorFactory;
-
-  /**
-   * A factory to override how [LibraryResolver] is created.
-   */
-  LibraryResolverFactory libraryResolverFactory;
-
-  /**
    * Initialize a newly created analysis context.
    */
   AnalysisContextImpl() {
@@ -263,8 +246,14 @@
         (this._options.lint && !options.lint) ||
         this._options.preserveComments != options.preserveComments ||
         this._options.strongMode != options.strongMode ||
+        this._options.enableAssertMessage != options.enableAssertMessage ||
+        ((options is AnalysisOptionsImpl)
+            ? this._options.strongModeHints != options.strongModeHints
+            : false) ||
         this._options.enableStrictCallChecks !=
             options.enableStrictCallChecks ||
+        this._options.enableGenericMethods != options.enableGenericMethods ||
+        this._options.enableAsync != options.enableAsync ||
         this._options.enableSuperMixins != options.enableSuperMixins;
     int cacheSize = options.cacheSize;
     if (this._options.cacheSize != cacheSize) {
@@ -275,7 +264,10 @@
     this._options.generateImplicitErrors = options.generateImplicitErrors;
     this._options.generateSdkErrors = options.generateSdkErrors;
     this._options.dart2jsHint = options.dart2jsHint;
+    this._options.enableGenericMethods = options.enableGenericMethods;
+    this._options.enableAssertMessage = options.enableAssertMessage;
     this._options.enableStrictCallChecks = options.enableStrictCallChecks;
+    this._options.enableAsync = options.enableAsync;
     this._options.enableSuperMixins = options.enableSuperMixins;
     this._options.hint = options.hint;
     this._options.incremental = options.incremental;
@@ -284,6 +276,9 @@
     this._options.lint = options.lint;
     this._options.preserveComments = options.preserveComments;
     this._options.strongMode = options.strongMode;
+    if (options is AnalysisOptionsImpl) {
+      this._options.strongModeHints = options.strongModeHints;
+    }
     if (needsRecompute) {
       for (WorkManager workManager in workManagers) {
         workManager.onAnalysisOptionsChanged();
@@ -320,6 +315,9 @@
   DeclaredVariables get declaredVariables => _declaredVariables;
 
   @override
+  EmbedderYamlLocator get embedderYamlLocator => _embedderYamlLocator;
+
+  @override
   List<AnalysisTarget> get explicitTargets {
     List<AnalysisTarget> targets = <AnalysisTarget>[];
     MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
@@ -380,9 +378,8 @@
   /**
    * Make _pendingFutureSources available to unit tests.
    */
-  HashMap<AnalysisTarget,
-      List<PendingFuture>> get pendingFutureSources_forTesting =>
-      _pendingFutureTargets;
+  HashMap<AnalysisTarget, List<PendingFuture>>
+      get pendingFutureSources_forTesting => _pendingFutureTargets;
 
   @override
   List<Source> get prioritySources => _priorityOrder;
@@ -443,16 +440,6 @@
     return new List<Source>.from(sources);
   }
 
-  @override
-  AnalysisContextStatistics get statistics {
-    AnalysisContextStatisticsImpl statistics =
-        new AnalysisContextStatisticsImpl();
-    // TODO(brianwilkerson) Implement this.
-//    visitCacheItems(statistics._internalPutCacheItem);
-//    statistics.partitionData = _cache.partitionData;
-    return statistics;
-  }
-
   List<Source> get test_priorityOrder => _priorityOrder;
 
   @override
@@ -500,6 +487,33 @@
   }
 
   @override
+  bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) {
+    return PerformanceStatistics.summary.makeCurrentWhile(() {
+      AnalysisTarget target = entry.target;
+      // TYPE_PROVIDER
+      if (target is AnalysisContextTarget && result == TYPE_PROVIDER) {
+        DartSdk dartSdk = sourceFactory.dartSdk;
+        if (dartSdk != null) {
+          AnalysisContext sdkContext = dartSdk.context;
+          if (!identical(sdkContext, this) &&
+              sdkContext is InternalAnalysisContext) {
+            return sdkContext.aboutToComputeResult(entry, result);
+          }
+        }
+      }
+      // A result for a Source.
+      Source source = target.source;
+      if (source != null) {
+        InternalAnalysisContext context = _cache.getContextFor(source);
+        if (!identical(context, this)) {
+          return context.aboutToComputeResult(entry, result);
+        }
+      }
+      return false;
+    });
+  }
+
+  @override
   void addListener(AnalysisListener listener) {
     if (!_listeners.contains(listener)) {
       _listeners.add(listener);
@@ -520,15 +534,14 @@
   }
 
   @override
-  void applyChanges(ChangeSet changeSet) {
+  ApplyChangesStatus applyChanges(ChangeSet changeSet) {
     if (changeSet.isEmpty) {
-      return;
+      return new ApplyChangesStatus(false);
     }
     //
     // First, compute the list of sources that have been removed.
     //
-    List<Source> removedSources =
-        new List<Source>.from(changeSet.removedSources);
+    List<Source> removedSources = changeSet.removedSources.toList();
     for (SourceContainer container in changeSet.removedContainers) {
       _addSourcesInContainer(removedSources, container);
     }
@@ -538,13 +551,13 @@
     for (Source source in changeSet.addedSources) {
       _sourceAvailable(source);
     }
-    for (Source source in changeSet.changedSources) {
-      if (_contentCache.getContents(source) != null) {
-        // This source is overridden in the content cache, so the change will
-        // have no effect. Just ignore it to avoid wasting time doing
-        // re-analysis.
-        continue;
-      }
+    // Exclude sources that are overridden in the content cache, so the change
+    // will have no effect. Just ignore it to avoid wasting time doing
+    // re-analysis.
+    List<Source> changedSources = changeSet.changedSources
+        .where((s) => _contentCache.getContents(s) == null)
+        .toList();
+    for (Source source in changedSources) {
       _sourceChanged(source);
     }
     changeSet.changedContents.forEach((Source key, String value) {
@@ -563,28 +576,19 @@
     }
     for (WorkManager workManager in workManagers) {
       workManager.applyChange(
-          changeSet.addedSources, changeSet.changedSources, removedSources);
+          changeSet.addedSources, changedSources, removedSources);
     }
     _onSourcesChangedController.add(new SourcesChangedEvent(changeSet));
+    return new ApplyChangesStatus(changeSet.addedSources.isNotEmpty ||
+        changeSet.changedContents.isNotEmpty ||
+        changeSet.deletedSources.isNotEmpty ||
+        changedSources.isNotEmpty ||
+        removedSources.isNotEmpty);
   }
 
   @override
-  String computeDocumentationComment(Element element) {
-    if (element == null) {
-      return null;
-    }
-    Source source = element.source;
-    if (source == null) {
-      return null;
-    }
-    SourceRange docRange = element.docRange;
-    if (docRange == null) {
-      return null;
-    }
-    String code = getContents(source).data;
-    String comment = code.substring(docRange.offset, docRange.end);
-    return comment.replaceAll('\r\n', '\n');
-  }
+  String computeDocumentationComment(Element element) =>
+      element?.documentationComment;
 
   @override
   List<AnalysisError> computeErrors(Source source) {
@@ -600,14 +604,6 @@
       computeResult(source, EXPORTED_LIBRARIES);
 
   @override
-  @deprecated
-  HtmlElement computeHtmlElement(Source source) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   List<Source> computeImportedLibraries(Source source) =>
       computeResult(source, EXPLICITLY_IMPORTED_LIBRARIES);
 
@@ -632,26 +628,19 @@
   LineInfo computeLineInfo(Source source) => computeResult(source, LINE_INFO);
 
   @override
-  @deprecated
-  CompilationUnit computeResolvableCompilationUnit(Source source) {
-    return null;
-  }
-
-  @override
   CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync(
       Source unitSource, Source librarySource) {
     if (!AnalysisEngine.isDartFileName(unitSource.shortName) ||
         !AnalysisEngine.isDartFileName(librarySource.shortName)) {
       return new CancelableFuture.error(new AnalysisNotScheduledError());
     }
-    return new AnalysisFutureHelper<CompilationUnit>(
-        this,
-        new LibrarySpecificUnit(librarySource, unitSource),
-        RESOLVED_UNIT).computeAsync();
+    return new AnalysisFutureHelper<CompilationUnit>(this,
+            new LibrarySpecificUnit(librarySource, unitSource), RESOLVED_UNIT)
+        .computeAsync();
   }
 
   @override
-  Object /*V*/ computeResult(
+  Object /*=V*/ computeResult /*<V>*/ (
       AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) {
     // Make sure we are not trying to invoke the task model in a reentrant
     // fashion.
@@ -681,7 +670,7 @@
       return new AnalysisCache(<CachePartition>[_privatePartition]);
     }
     return new AnalysisCache(<CachePartition>[
-      AnalysisEngine.instance.partitionManager_new.forSdk(sdk),
+      AnalysisEngine.instance.partitionManager.forSdk(sdk),
       _privatePartition
     ]);
   }
@@ -765,7 +754,8 @@
   }
 
   @override
-  Object getConfigurationData(ResultDescriptor key) => _configurationData[key];
+  Object getConfigurationData(ResultDescriptor key) =>
+      _configurationData[key] ?? key?.defaultValue;
 
   @override
   TimestampedData<String> getContents(Source source) {
@@ -820,14 +810,6 @@
   }
 
   @override
-  @deprecated
-  HtmlElement getHtmlElement(Source source) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   List<Source> getHtmlFilesReferencing(Source source) {
     if (!AnalysisEngine.isDartFileName(source.shortName)) {
       return Source.EMPTY_LIST;
@@ -959,14 +941,6 @@
   }
 
   @override
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   Object getResult(AnalysisTarget target, ResultDescriptor result) {
     return _cache.getValue(target, result);
   }
@@ -1024,10 +998,14 @@
   }
 
   /**
-   * Invalidate analysis cache.
+   * Invalidate analysis cache and notify work managers that they have work
+   * to do.
    */
   void invalidateCachedResults() {
     _cache = createCacheFromSourceFactory(_sourceFactory);
+    for (WorkManager workManager in workManagers) {
+      workManager.onAnalysisOptionsChanged();
+    }
   }
 
   @override
@@ -1084,16 +1062,8 @@
   }
 
   @override
-  @deprecated // use parseHtmlDocument(source)
-  ht.HtmlUnit parseHtmlUnit(Source source) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   AnalysisResult performAnalysisTask() {
-    return PerformanceStatistics.performAnaysis.makeCurrentWhile(() {
+    return PerformanceStatistics.performAnalysis.makeCurrentWhile(() {
       _evaluatePendingFutures();
       bool done = !driver.performAnalysisTask();
       List<ChangeNotice> notices = _getChangeNotices(done);
@@ -1137,6 +1107,9 @@
       setValue(LIBRARY_ELEMENT3, library);
       setValue(LIBRARY_ELEMENT4, library);
       setValue(LIBRARY_ELEMENT5, library);
+      setValue(LIBRARY_ELEMENT6, library);
+      setValue(LIBRARY_ELEMENT7, library);
+      setValue(LIBRARY_ELEMENT8, library);
       setValue(LINE_INFO, new LineInfo(<int>[0]));
       setValue(PARSE_ERRORS, AnalysisError.NO_ERRORS);
       entry.setState(PARSED_UNIT, CacheState.FLUSHED);
@@ -1165,6 +1138,7 @@
       entry.setState(RESOLVED_UNIT8, CacheState.FLUSHED);
       entry.setState(RESOLVED_UNIT9, CacheState.FLUSHED);
       entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
+      entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
       // USED_IMPORTED_ELEMENTS
       // USED_LOCAL_ELEMENTS
       setValue(STRONG_MODE_ERRORS, AnalysisError.NO_ERRORS);
@@ -1198,14 +1172,6 @@
   }
 
   @override
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   void setChangedContents(Source source, String contents, int offset,
       int oldLength, int newLength) {
     if (_contentRangeChanged(source, contents, offset, oldLength, newLength)) {
@@ -1225,7 +1191,7 @@
   }
 
   @override
-  bool shouldErrorsBeAnalyzed(Source source, Object entry) {
+  bool shouldErrorsBeAnalyzed(Source source) {
     CacheEntry entry = analysisCache.get(source);
     if (source.isInSystemLibrary) {
       return _options.generateSdkErrors;
@@ -1250,6 +1216,7 @@
     entry.setState(RESOLVED_UNIT8, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT9, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
   }
 
@@ -1304,72 +1271,6 @@
     return changedSources.length > 0;
   }
 
-  @deprecated
-  @override
-  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state)) {
-    // TODO(brianwilkerson) Figure out where this is used and either remove it
-    // or adjust the call sites to use CacheEntry's.
-//    bool hintsEnabled = _options.hint;
-//    bool lintsEnabled = _options.lint;
-//    MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator();
-//    while (iterator.moveNext()) {
-//      Source source = iterator.key;
-//      cache.CacheEntry entry = iterator.value;
-//      for (DataDescriptor descriptor in entry.descriptors) {
-//        if (descriptor == DartEntry.SOURCE_KIND) {
-//          // The source kind is always valid, so the state isn't interesting.
-//          continue;
-//        } else if (descriptor == DartEntry.CONTAINING_LIBRARIES) {
-//          // The list of containing libraries is always valid, so the state
-//          // isn't interesting.
-//          continue;
-//        } else if (descriptor == DartEntry.PUBLIC_NAMESPACE) {
-//          // The public namespace isn't computed by performAnalysisTask()
-//          // and therefore isn't interesting.
-//          continue;
-//        } else if (descriptor == HtmlEntry.HINTS) {
-//          // We are not currently recording any hints related to HTML.
-//          continue;
-//        }
-//        callback(
-//            source, entry, descriptor, entry.getState(descriptor));
-//      }
-//      if (entry is DartEntry) {
-//        // get library-specific values
-//        List<Source> librarySources = getLibrariesContaining(source);
-//        for (Source librarySource in librarySources) {
-//          for (DataDescriptor descriptor in entry.libraryDescriptors) {
-//            if (descriptor == DartEntry.BUILT_ELEMENT ||
-//                descriptor == DartEntry.BUILT_UNIT) {
-//              // These values are not currently being computed, so their state
-//              // is not interesting.
-//              continue;
-//            } else if (!entry.explicitlyAdded &&
-//                !_generateImplicitErrors &&
-//                (descriptor == DartEntry.VERIFICATION_ERRORS ||
-//                    descriptor == DartEntry.HINTS ||
-//                    descriptor == DartEntry.LINTS)) {
-//              continue;
-//            } else if (source.isInSystemLibrary &&
-//                !_generateSdkErrors &&
-//                (descriptor == DartEntry.VERIFICATION_ERRORS ||
-//                    descriptor == DartEntry.HINTS ||
-//                    descriptor == DartEntry.LINTS)) {
-//              continue;
-//            } else if (!hintsEnabled && descriptor == DartEntry.HINTS) {
-//              continue;
-//            } else if (!lintsEnabled && descriptor == DartEntry.LINTS) {
-//              continue;
-//            }
-//            callback(librarySource, entry, descriptor,
-//                entry.getStateInLibrary(descriptor, librarySource));
-//          }
-//        }
-//      }
-//    }
-  }
-
   @override
   void visitContentCache(ContentCacheVisitor visitor) {
     _contentCache.accept(visitor);
@@ -1639,7 +1540,7 @@
         } else if (state == CacheState.ERROR) {
           return;
         }
-        if (shouldErrorsBeAnalyzed(source, unitEntry)) {
+        if (shouldErrorsBeAnalyzed(source)) {
           state = unitEntry.getState(VERIFY_ERRORS);
           if (state == CacheState.INVALID ||
               (isPriority && state == CacheState.FLUSHED)) {
@@ -1764,6 +1665,7 @@
     if (entry == null) {
       _createCacheEntry(source, true);
     } else {
+      entry.explicitlyAdded = true;
       entry.modificationTime = getModificationStamp(source);
       entry.setState(CONTENT, CacheState.INVALID);
     }
@@ -1919,7 +1821,6 @@
       PoorMansIncrementalResolver resolver = new PoorMansIncrementalResolver(
           typeProvider,
           unitSource,
-          null,
           sourceEntry,
           unitEntry,
           oldUnit,
@@ -2135,8 +2036,7 @@
       throw new IllegalArgumentException(
           "The source factory for an SDK analysis context must have a DartUriResolver");
     }
-    return new AnalysisCache(<CachePartition>[
-      AnalysisEngine.instance.partitionManager_new.forSdk(sdk)
-    ]);
+    return new AnalysisCache(
+        <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
new file mode 100644
index 0000000..f0435eb
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -0,0 +1,6272 @@
+// 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 analyzer.src.generated.ast;
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * An AST visitor that will clone any AST structure that it visits. The cloner
+ * will only clone the structure, it will not preserve any resolution results or
+ * properties associated with the nodes.
+ */
+class AstCloner implements AstVisitor<AstNode> {
+  /**
+   * A flag indicating whether tokens should be cloned while cloning an AST
+   * structure.
+   */
+  final bool cloneTokens;
+
+  /**
+   * Initialize a newly created AST cloner to optionally clone tokens while
+   * cloning AST nodes if [cloneTokens] is `true`.
+   */
+  AstCloner(
+      [this.cloneTokens =
+          false]); // TODO(brianwilkerson) Change this to be a named parameter.
+
+  /**
+   * Return a clone of the given [node].
+   */
+  AstNode cloneNode(AstNode node) {
+    if (node == null) {
+      return null;
+    }
+    return node.accept(this) as AstNode;
+  }
+
+  /**
+   * Return a list containing cloned versions of the nodes in the given list of
+   * [nodes].
+   */
+  List<AstNode> cloneNodeList(NodeList nodes) {
+    int count = nodes.length;
+    List clonedNodes = new List();
+    for (int i = 0; i < count; i++) {
+      clonedNodes.add((nodes[i]).accept(this) as AstNode);
+    }
+    return clonedNodes;
+  }
+
+  /**
+   * Clone the given [token] if tokens are supposed to be cloned.
+   */
+  Token cloneToken(Token token) {
+    if (cloneTokens) {
+      return (token == null ? null : token.copy());
+    } else {
+      return token;
+    }
+  }
+
+  /**
+   * Clone the given [tokens] if tokens are supposed to be cloned.
+   */
+  List<Token> cloneTokenList(List<Token> tokens) {
+    if (cloneTokens) {
+      return tokens.map((Token token) => token.copy()).toList();
+    }
+    return tokens;
+  }
+
+  @override
+  AdjacentStrings visitAdjacentStrings(AdjacentStrings node) =>
+      new AdjacentStrings(cloneNodeList(node.strings));
+
+  @override
+  Annotation visitAnnotation(Annotation node) => new Annotation(
+      cloneToken(node.atSign),
+      cloneNode(node.name),
+      cloneToken(node.period),
+      cloneNode(node.constructorName),
+      cloneNode(node.arguments));
+
+  @override
+  ArgumentList visitArgumentList(ArgumentList node) => new ArgumentList(
+      cloneToken(node.leftParenthesis),
+      cloneNodeList(node.arguments),
+      cloneToken(node.rightParenthesis));
+
+  @override
+  AsExpression visitAsExpression(AsExpression node) => new AsExpression(
+      cloneNode(node.expression),
+      cloneToken(node.asOperator),
+      cloneNode(node.type));
+
+  @override
+  AstNode visitAssertStatement(AssertStatement node) => new AssertStatement(
+      cloneToken(node.assertKeyword),
+      cloneToken(node.leftParenthesis),
+      cloneNode(node.condition),
+      cloneToken(node.comma),
+      cloneNode(node.message),
+      cloneToken(node.rightParenthesis),
+      cloneToken(node.semicolon));
+
+  @override
+  AssignmentExpression visitAssignmentExpression(AssignmentExpression node) =>
+      new AssignmentExpression(cloneNode(node.leftHandSide),
+          cloneToken(node.operator), cloneNode(node.rightHandSide));
+
+  @override
+  AwaitExpression visitAwaitExpression(AwaitExpression node) =>
+      new AwaitExpression(
+          cloneToken(node.awaitKeyword), cloneNode(node.expression));
+
+  @override
+  BinaryExpression visitBinaryExpression(BinaryExpression node) =>
+      new BinaryExpression(cloneNode(node.leftOperand),
+          cloneToken(node.operator), cloneNode(node.rightOperand));
+
+  @override
+  Block visitBlock(Block node) => new Block(cloneToken(node.leftBracket),
+      cloneNodeList(node.statements), cloneToken(node.rightBracket));
+
+  @override
+  BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) =>
+      new BlockFunctionBody(cloneToken(node.keyword), cloneToken(node.star),
+          cloneNode(node.block));
+
+  @override
+  BooleanLiteral visitBooleanLiteral(BooleanLiteral node) =>
+      new BooleanLiteral(cloneToken(node.literal), node.value);
+
+  @override
+  BreakStatement visitBreakStatement(BreakStatement node) => new BreakStatement(
+      cloneToken(node.breakKeyword),
+      cloneNode(node.label),
+      cloneToken(node.semicolon));
+
+  @override
+  CascadeExpression visitCascadeExpression(CascadeExpression node) =>
+      new CascadeExpression(
+          cloneNode(node.target), cloneNodeList(node.cascadeSections));
+
+  @override
+  CatchClause visitCatchClause(CatchClause node) => new CatchClause(
+      cloneToken(node.onKeyword),
+      cloneNode(node.exceptionType),
+      cloneToken(node.catchKeyword),
+      cloneToken(node.leftParenthesis),
+      cloneNode(node.exceptionParameter),
+      cloneToken(node.comma),
+      cloneNode(node.stackTraceParameter),
+      cloneToken(node.rightParenthesis),
+      cloneNode(node.body));
+
+  @override
+  ClassDeclaration visitClassDeclaration(ClassDeclaration node) {
+    ClassDeclaration copy = new ClassDeclaration(
+        cloneNode(node.documentationComment),
+        cloneNodeList(node.metadata),
+        cloneToken(node.abstractKeyword),
+        cloneToken(node.classKeyword),
+        cloneNode(node.name),
+        cloneNode(node.typeParameters),
+        cloneNode(node.extendsClause),
+        cloneNode(node.withClause),
+        cloneNode(node.implementsClause),
+        cloneToken(node.leftBracket),
+        cloneNodeList(node.members),
+        cloneToken(node.rightBracket));
+    copy.nativeClause = cloneNode(node.nativeClause);
+    return copy;
+  }
+
+  @override
+  ClassTypeAlias visitClassTypeAlias(ClassTypeAlias node) => new ClassTypeAlias(
+      cloneNode(node.documentationComment),
+      cloneNodeList(node.metadata),
+      cloneToken(node.typedefKeyword),
+      cloneNode(node.name),
+      cloneNode(node.typeParameters),
+      cloneToken(node.equals),
+      cloneToken(node.abstractKeyword),
+      cloneNode(node.superclass),
+      cloneNode(node.withClause),
+      cloneNode(node.implementsClause),
+      cloneToken(node.semicolon));
+
+  @override
+  Comment visitComment(Comment node) {
+    if (node.isDocumentation) {
+      return Comment.createDocumentationCommentWithReferences(
+          cloneTokenList(node.tokens), cloneNodeList(node.references));
+    } else if (node.isBlock) {
+      return Comment.createBlockComment(cloneTokenList(node.tokens));
+    }
+    return Comment.createEndOfLineComment(cloneTokenList(node.tokens));
+  }
+
+  @override
+  CommentReference visitCommentReference(CommentReference node) =>
+      new CommentReference(
+          cloneToken(node.newKeyword), cloneNode(node.identifier));
+
+  @override
+  CompilationUnit visitCompilationUnit(CompilationUnit node) {
+    CompilationUnit clone = new CompilationUnit(
+        cloneToken(node.beginToken),
+        cloneNode(node.scriptTag),
+        cloneNodeList(node.directives),
+        cloneNodeList(node.declarations),
+        cloneToken(node.endToken));
+    clone.lineInfo = node.lineInfo;
+    return clone;
+  }
+
+  @override
+  ConditionalExpression visitConditionalExpression(
+          ConditionalExpression node) =>
+      new ConditionalExpression(
+          cloneNode(node.condition),
+          cloneToken(node.question),
+          cloneNode(node.thenExpression),
+          cloneToken(node.colon),
+          cloneNode(node.elseExpression));
+
+  @override
+  Configuration visitConfiguration(Configuration node) => new Configuration(
+      cloneToken(node.ifKeyword),
+      cloneToken(node.leftParenthesis),
+      cloneNode(node.name),
+      cloneToken(node.equalToken),
+      cloneNode(node.value),
+      cloneToken(node.rightParenthesis),
+      cloneNode(node.libraryUri));
+
+  @override
+  ConstructorDeclaration visitConstructorDeclaration(
+          ConstructorDeclaration node) =>
+      new ConstructorDeclaration(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.externalKeyword),
+          cloneToken(node.constKeyword),
+          cloneToken(node.factoryKeyword),
+          cloneNode(node.returnType),
+          cloneToken(node.period),
+          cloneNode(node.name),
+          cloneNode(node.parameters),
+          cloneToken(node.separator),
+          cloneNodeList(node.initializers),
+          cloneNode(node.redirectedConstructor),
+          cloneNode(node.body));
+
+  @override
+  ConstructorFieldInitializer visitConstructorFieldInitializer(
+          ConstructorFieldInitializer node) =>
+      new ConstructorFieldInitializer(
+          cloneToken(node.thisKeyword),
+          cloneToken(node.period),
+          cloneNode(node.fieldName),
+          cloneToken(node.equals),
+          cloneNode(node.expression));
+
+  @override
+  ConstructorName visitConstructorName(ConstructorName node) =>
+      new ConstructorName(
+          cloneNode(node.type), cloneToken(node.period), cloneNode(node.name));
+
+  @override
+  ContinueStatement visitContinueStatement(ContinueStatement node) =>
+      new ContinueStatement(cloneToken(node.continueKeyword),
+          cloneNode(node.label), cloneToken(node.semicolon));
+
+  @override
+  DeclaredIdentifier visitDeclaredIdentifier(DeclaredIdentifier node) =>
+      new DeclaredIdentifier(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.keyword),
+          cloneNode(node.type),
+          cloneNode(node.identifier));
+
+  @override
+  DefaultFormalParameter visitDefaultFormalParameter(
+          DefaultFormalParameter node) =>
+      new DefaultFormalParameter(cloneNode(node.parameter), node.kind,
+          cloneToken(node.separator), cloneNode(node.defaultValue));
+
+  @override
+  DoStatement visitDoStatement(DoStatement node) => new DoStatement(
+      cloneToken(node.doKeyword),
+      cloneNode(node.body),
+      cloneToken(node.whileKeyword),
+      cloneToken(node.leftParenthesis),
+      cloneNode(node.condition),
+      cloneToken(node.rightParenthesis),
+      cloneToken(node.semicolon));
+
+  @override
+  DottedName visitDottedName(DottedName node) =>
+      new DottedName(cloneNodeList(node.components));
+
+  @override
+  DoubleLiteral visitDoubleLiteral(DoubleLiteral node) =>
+      new DoubleLiteral(cloneToken(node.literal), node.value);
+
+  @override
+  EmptyFunctionBody visitEmptyFunctionBody(EmptyFunctionBody node) =>
+      new EmptyFunctionBody(cloneToken(node.semicolon));
+
+  @override
+  EmptyStatement visitEmptyStatement(EmptyStatement node) =>
+      new EmptyStatement(cloneToken(node.semicolon));
+
+  @override
+  AstNode visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
+      new EnumConstantDeclaration(cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata), cloneNode(node.name));
+
+  @override
+  EnumDeclaration visitEnumDeclaration(EnumDeclaration node) =>
+      new EnumDeclaration(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.enumKeyword),
+          cloneNode(node.name),
+          cloneToken(node.leftBracket),
+          cloneNodeList(node.constants),
+          cloneToken(node.rightBracket));
+
+  @override
+  ExportDirective visitExportDirective(ExportDirective node) {
+    ExportDirective directive = new ExportDirective(
+        cloneNode(node.documentationComment),
+        cloneNodeList(node.metadata),
+        cloneToken(node.keyword),
+        cloneNode(node.uri),
+        cloneNodeList(node.configurations),
+        cloneNodeList(node.combinators),
+        cloneToken(node.semicolon));
+    directive.source = node.source;
+    directive.uriContent = node.uriContent;
+    return directive;
+  }
+
+  @override
+  ExpressionFunctionBody visitExpressionFunctionBody(
+          ExpressionFunctionBody node) =>
+      new ExpressionFunctionBody(
+          cloneToken(node.keyword),
+          cloneToken(node.functionDefinition),
+          cloneNode(node.expression),
+          cloneToken(node.semicolon));
+
+  @override
+  ExpressionStatement visitExpressionStatement(ExpressionStatement node) =>
+      new ExpressionStatement(
+          cloneNode(node.expression), cloneToken(node.semicolon));
+
+  @override
+  ExtendsClause visitExtendsClause(ExtendsClause node) => new ExtendsClause(
+      cloneToken(node.extendsKeyword), cloneNode(node.superclass));
+
+  @override
+  FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
+      new FieldDeclaration(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.staticKeyword),
+          cloneNode(node.fields),
+          cloneToken(node.semicolon));
+
+  @override
+  FieldFormalParameter visitFieldFormalParameter(FieldFormalParameter node) =>
+      new FieldFormalParameter(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.keyword),
+          cloneNode(node.type),
+          cloneToken(node.thisKeyword),
+          cloneToken(node.period),
+          cloneNode(node.identifier),
+          cloneNode(node.typeParameters),
+          cloneNode(node.parameters));
+
+  @override
+  ForEachStatement visitForEachStatement(ForEachStatement node) {
+    DeclaredIdentifier loopVariable = node.loopVariable;
+    if (loopVariable == null) {
+      return new ForEachStatement.withReference(
+          cloneToken(node.awaitKeyword),
+          cloneToken(node.forKeyword),
+          cloneToken(node.leftParenthesis),
+          cloneNode(node.identifier),
+          cloneToken(node.inKeyword),
+          cloneNode(node.iterable),
+          cloneToken(node.rightParenthesis),
+          cloneNode(node.body));
+    }
+    return new ForEachStatement.withDeclaration(
+        cloneToken(node.awaitKeyword),
+        cloneToken(node.forKeyword),
+        cloneToken(node.leftParenthesis),
+        cloneNode(loopVariable),
+        cloneToken(node.inKeyword),
+        cloneNode(node.iterable),
+        cloneToken(node.rightParenthesis),
+        cloneNode(node.body));
+  }
+
+  @override
+  FormalParameterList visitFormalParameterList(FormalParameterList node) =>
+      new FormalParameterList(
+          cloneToken(node.leftParenthesis),
+          cloneNodeList(node.parameters),
+          cloneToken(node.leftDelimiter),
+          cloneToken(node.rightDelimiter),
+          cloneToken(node.rightParenthesis));
+
+  @override
+  ForStatement visitForStatement(ForStatement node) => new ForStatement(
+      cloneToken(node.forKeyword),
+      cloneToken(node.leftParenthesis),
+      cloneNode(node.variables),
+      cloneNode(node.initialization),
+      cloneToken(node.leftSeparator),
+      cloneNode(node.condition),
+      cloneToken(node.rightSeparator),
+      cloneNodeList(node.updaters),
+      cloneToken(node.rightParenthesis),
+      cloneNode(node.body));
+
+  @override
+  FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) =>
+      new FunctionDeclaration(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.externalKeyword),
+          cloneNode(node.returnType),
+          cloneToken(node.propertyKeyword),
+          cloneNode(node.name),
+          cloneNode(node.functionExpression));
+
+  @override
+  FunctionDeclarationStatement visitFunctionDeclarationStatement(
+          FunctionDeclarationStatement node) =>
+      new FunctionDeclarationStatement(cloneNode(node.functionDeclaration));
+
+  @override
+  FunctionExpression visitFunctionExpression(FunctionExpression node) =>
+      new FunctionExpression(cloneNode(node.typeParameters),
+          cloneNode(node.parameters), cloneNode(node.body));
+
+  @override
+  FunctionExpressionInvocation visitFunctionExpressionInvocation(
+          FunctionExpressionInvocation node) =>
+      new FunctionExpressionInvocation(cloneNode(node.function),
+          cloneNode(node.typeArguments), cloneNode(node.argumentList));
+
+  @override
+  FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) =>
+      new FunctionTypeAlias(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.typedefKeyword),
+          cloneNode(node.returnType),
+          cloneNode(node.name),
+          cloneNode(node.typeParameters),
+          cloneNode(node.parameters),
+          cloneToken(node.semicolon));
+
+  @override
+  FunctionTypedFormalParameter visitFunctionTypedFormalParameter(
+          FunctionTypedFormalParameter node) =>
+      new FunctionTypedFormalParameter(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneNode(node.returnType),
+          cloneNode(node.identifier),
+          cloneNode(node.typeParameters),
+          cloneNode(node.parameters));
+
+  @override
+  HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
+      cloneToken(node.keyword), cloneNodeList(node.hiddenNames));
+
+  @override
+  IfStatement visitIfStatement(IfStatement node) => new IfStatement(
+      cloneToken(node.ifKeyword),
+      cloneToken(node.leftParenthesis),
+      cloneNode(node.condition),
+      cloneToken(node.rightParenthesis),
+      cloneNode(node.thenStatement),
+      cloneToken(node.elseKeyword),
+      cloneNode(node.elseStatement));
+
+  @override
+  ImplementsClause visitImplementsClause(ImplementsClause node) =>
+      new ImplementsClause(
+          cloneToken(node.implementsKeyword), cloneNodeList(node.interfaces));
+
+  @override
+  ImportDirective visitImportDirective(ImportDirective node) {
+    ImportDirective directive = new ImportDirective(
+        cloneNode(node.documentationComment),
+        cloneNodeList(node.metadata),
+        cloneToken(node.keyword),
+        cloneNode(node.uri),
+        cloneNodeList(node.configurations),
+        cloneToken(node.deferredKeyword),
+        cloneToken(node.asKeyword),
+        cloneNode(node.prefix),
+        cloneNodeList(node.combinators),
+        cloneToken(node.semicolon));
+    directive.source = node.source;
+    directive.uriContent = node.uriContent;
+    return directive;
+  }
+
+  @override
+  IndexExpression visitIndexExpression(IndexExpression node) {
+    Token period = node.period;
+    if (period == null) {
+      return new IndexExpression.forTarget(
+          cloneNode(node.target),
+          cloneToken(node.leftBracket),
+          cloneNode(node.index),
+          cloneToken(node.rightBracket));
+    } else {
+      return new IndexExpression.forCascade(
+          cloneToken(period),
+          cloneToken(node.leftBracket),
+          cloneNode(node.index),
+          cloneToken(node.rightBracket));
+    }
+  }
+
+  @override
+  InstanceCreationExpression visitInstanceCreationExpression(
+          InstanceCreationExpression node) =>
+      new InstanceCreationExpression(cloneToken(node.keyword),
+          cloneNode(node.constructorName), cloneNode(node.argumentList));
+
+  @override
+  IntegerLiteral visitIntegerLiteral(IntegerLiteral node) =>
+      new IntegerLiteral(cloneToken(node.literal), node.value);
+
+  @override
+  InterpolationExpression visitInterpolationExpression(
+          InterpolationExpression node) =>
+      new InterpolationExpression(cloneToken(node.leftBracket),
+          cloneNode(node.expression), cloneToken(node.rightBracket));
+
+  @override
+  InterpolationString visitInterpolationString(InterpolationString node) =>
+      new InterpolationString(cloneToken(node.contents), node.value);
+
+  @override
+  IsExpression visitIsExpression(IsExpression node) => new IsExpression(
+      cloneNode(node.expression),
+      cloneToken(node.isOperator),
+      cloneToken(node.notOperator),
+      cloneNode(node.type));
+
+  @override
+  Label visitLabel(Label node) =>
+      new Label(cloneNode(node.label), cloneToken(node.colon));
+
+  @override
+  LabeledStatement visitLabeledStatement(LabeledStatement node) =>
+      new LabeledStatement(
+          cloneNodeList(node.labels), cloneNode(node.statement));
+
+  @override
+  LibraryDirective visitLibraryDirective(LibraryDirective node) =>
+      new LibraryDirective(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.libraryKeyword),
+          cloneNode(node.name),
+          cloneToken(node.semicolon));
+
+  @override
+  LibraryIdentifier visitLibraryIdentifier(LibraryIdentifier node) =>
+      new LibraryIdentifier(cloneNodeList(node.components));
+
+  @override
+  ListLiteral visitListLiteral(ListLiteral node) => new ListLiteral(
+      cloneToken(node.constKeyword),
+      cloneNode(node.typeArguments),
+      cloneToken(node.leftBracket),
+      cloneNodeList(node.elements),
+      cloneToken(node.rightBracket));
+
+  @override
+  MapLiteral visitMapLiteral(MapLiteral node) => new MapLiteral(
+      cloneToken(node.constKeyword),
+      cloneNode(node.typeArguments),
+      cloneToken(node.leftBracket),
+      cloneNodeList(node.entries),
+      cloneToken(node.rightBracket));
+
+  @override
+  MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) =>
+      new MapLiteralEntry(cloneNode(node.key), cloneToken(node.separator),
+          cloneNode(node.value));
+
+  @override
+  MethodDeclaration visitMethodDeclaration(MethodDeclaration node) =>
+      new MethodDeclaration(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.externalKeyword),
+          cloneToken(node.modifierKeyword),
+          cloneNode(node.returnType),
+          cloneToken(node.propertyKeyword),
+          cloneToken(node.operatorKeyword),
+          cloneNode(node.name),
+          cloneNode(node.typeParameters),
+          cloneNode(node.parameters),
+          cloneNode(node.body));
+
+  @override
+  MethodInvocation visitMethodInvocation(MethodInvocation node) =>
+      new MethodInvocation(
+          cloneNode(node.target),
+          cloneToken(node.operator),
+          cloneNode(node.methodName),
+          cloneNode(node.typeArguments),
+          cloneNode(node.argumentList));
+
+  @override
+  NamedExpression visitNamedExpression(NamedExpression node) =>
+      new NamedExpression(cloneNode(node.name), cloneNode(node.expression));
+
+  @override
+  AstNode visitNativeClause(NativeClause node) =>
+      new NativeClause(cloneToken(node.nativeKeyword), cloneNode(node.name));
+
+  @override
+  NativeFunctionBody visitNativeFunctionBody(NativeFunctionBody node) =>
+      new NativeFunctionBody(cloneToken(node.nativeKeyword),
+          cloneNode(node.stringLiteral), cloneToken(node.semicolon));
+
+  @override
+  NullLiteral visitNullLiteral(NullLiteral node) =>
+      new NullLiteral(cloneToken(node.literal));
+
+  @override
+  ParenthesizedExpression visitParenthesizedExpression(
+          ParenthesizedExpression node) =>
+      new ParenthesizedExpression(cloneToken(node.leftParenthesis),
+          cloneNode(node.expression), cloneToken(node.rightParenthesis));
+
+  @override
+  PartDirective visitPartDirective(PartDirective node) {
+    PartDirective directive = new PartDirective(
+        cloneNode(node.documentationComment),
+        cloneNodeList(node.metadata),
+        cloneToken(node.partKeyword),
+        cloneNode(node.uri),
+        cloneToken(node.semicolon));
+    directive.source = node.source;
+    directive.uriContent = node.uriContent;
+    return directive;
+  }
+
+  @override
+  PartOfDirective visitPartOfDirective(PartOfDirective node) =>
+      new PartOfDirective(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.partKeyword),
+          cloneToken(node.ofKeyword),
+          cloneNode(node.libraryName),
+          cloneToken(node.semicolon));
+
+  @override
+  PostfixExpression visitPostfixExpression(PostfixExpression node) =>
+      new PostfixExpression(cloneNode(node.operand), cloneToken(node.operator));
+
+  @override
+  PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) =>
+      new PrefixedIdentifier(cloneNode(node.prefix), cloneToken(node.period),
+          cloneNode(node.identifier));
+
+  @override
+  PrefixExpression visitPrefixExpression(PrefixExpression node) =>
+      new PrefixExpression(cloneToken(node.operator), cloneNode(node.operand));
+
+  @override
+  PropertyAccess visitPropertyAccess(PropertyAccess node) => new PropertyAccess(
+      cloneNode(node.target),
+      cloneToken(node.operator),
+      cloneNode(node.propertyName));
+
+  @override
+  RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
+          RedirectingConstructorInvocation node) =>
+      new RedirectingConstructorInvocation(
+          cloneToken(node.thisKeyword),
+          cloneToken(node.period),
+          cloneNode(node.constructorName),
+          cloneNode(node.argumentList));
+
+  @override
+  RethrowExpression visitRethrowExpression(RethrowExpression node) =>
+      new RethrowExpression(cloneToken(node.rethrowKeyword));
+
+  @override
+  ReturnStatement visitReturnStatement(ReturnStatement node) =>
+      new ReturnStatement(cloneToken(node.returnKeyword),
+          cloneNode(node.expression), cloneToken(node.semicolon));
+
+  @override
+  ScriptTag visitScriptTag(ScriptTag node) =>
+      new ScriptTag(cloneToken(node.scriptTag));
+
+  @override
+  ShowCombinator visitShowCombinator(ShowCombinator node) => new ShowCombinator(
+      cloneToken(node.keyword), cloneNodeList(node.shownNames));
+
+  @override
+  SimpleFormalParameter visitSimpleFormalParameter(
+          SimpleFormalParameter node) =>
+      new SimpleFormalParameter(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.keyword),
+          cloneNode(node.type),
+          cloneNode(node.identifier));
+
+  @override
+  SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) =>
+      new SimpleIdentifier(cloneToken(node.token));
+
+  @override
+  SimpleStringLiteral visitSimpleStringLiteral(SimpleStringLiteral node) =>
+      new SimpleStringLiteral(cloneToken(node.literal), node.value);
+
+  @override
+  StringInterpolation visitStringInterpolation(StringInterpolation node) =>
+      new StringInterpolation(cloneNodeList(node.elements));
+
+  @override
+  SuperConstructorInvocation visitSuperConstructorInvocation(
+          SuperConstructorInvocation node) =>
+      new SuperConstructorInvocation(
+          cloneToken(node.superKeyword),
+          cloneToken(node.period),
+          cloneNode(node.constructorName),
+          cloneNode(node.argumentList));
+
+  @override
+  SuperExpression visitSuperExpression(SuperExpression node) =>
+      new SuperExpression(cloneToken(node.superKeyword));
+
+  @override
+  SwitchCase visitSwitchCase(SwitchCase node) => new SwitchCase(
+      cloneNodeList(node.labels),
+      cloneToken(node.keyword),
+      cloneNode(node.expression),
+      cloneToken(node.colon),
+      cloneNodeList(node.statements));
+
+  @override
+  SwitchDefault visitSwitchDefault(SwitchDefault node) => new SwitchDefault(
+      cloneNodeList(node.labels),
+      cloneToken(node.keyword),
+      cloneToken(node.colon),
+      cloneNodeList(node.statements));
+
+  @override
+  SwitchStatement visitSwitchStatement(SwitchStatement node) =>
+      new SwitchStatement(
+          cloneToken(node.switchKeyword),
+          cloneToken(node.leftParenthesis),
+          cloneNode(node.expression),
+          cloneToken(node.rightParenthesis),
+          cloneToken(node.leftBracket),
+          cloneNodeList(node.members),
+          cloneToken(node.rightBracket));
+
+  @override
+  SymbolLiteral visitSymbolLiteral(SymbolLiteral node) => new SymbolLiteral(
+      cloneToken(node.poundSign), cloneTokenList(node.components));
+
+  @override
+  ThisExpression visitThisExpression(ThisExpression node) =>
+      new ThisExpression(cloneToken(node.thisKeyword));
+
+  @override
+  ThrowExpression visitThrowExpression(ThrowExpression node) =>
+      new ThrowExpression(
+          cloneToken(node.throwKeyword), cloneNode(node.expression));
+
+  @override
+  TopLevelVariableDeclaration visitTopLevelVariableDeclaration(
+          TopLevelVariableDeclaration node) =>
+      new TopLevelVariableDeclaration(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneNode(node.variables),
+          cloneToken(node.semicolon));
+
+  @override
+  TryStatement visitTryStatement(TryStatement node) => new TryStatement(
+      cloneToken(node.tryKeyword),
+      cloneNode(node.body),
+      cloneNodeList(node.catchClauses),
+      cloneToken(node.finallyKeyword),
+      cloneNode(node.finallyBlock));
+
+  @override
+  TypeArgumentList visitTypeArgumentList(TypeArgumentList node) =>
+      new TypeArgumentList(cloneToken(node.leftBracket),
+          cloneNodeList(node.arguments), cloneToken(node.rightBracket));
+
+  @override
+  TypeName visitTypeName(TypeName node) =>
+      new TypeName(cloneNode(node.name), cloneNode(node.typeArguments));
+
+  @override
+  TypeParameter visitTypeParameter(TypeParameter node) => new TypeParameter(
+      cloneNode(node.documentationComment),
+      cloneNodeList(node.metadata),
+      cloneNode(node.name),
+      cloneToken(node.extendsKeyword),
+      cloneNode(node.bound));
+
+  @override
+  TypeParameterList visitTypeParameterList(TypeParameterList node) =>
+      new TypeParameterList(cloneToken(node.leftBracket),
+          cloneNodeList(node.typeParameters), cloneToken(node.rightBracket));
+
+  @override
+  VariableDeclaration visitVariableDeclaration(VariableDeclaration node) =>
+      new VariableDeclaration(cloneNode(node.name), cloneToken(node.equals),
+          cloneNode(node.initializer));
+
+  @override
+  VariableDeclarationList visitVariableDeclarationList(
+          VariableDeclarationList node) =>
+      new VariableDeclarationList(
+          cloneNode(node.documentationComment),
+          cloneNodeList(node.metadata),
+          cloneToken(node.keyword),
+          cloneNode(node.type),
+          cloneNodeList(node.variables));
+
+  @override
+  VariableDeclarationStatement visitVariableDeclarationStatement(
+          VariableDeclarationStatement node) =>
+      new VariableDeclarationStatement(
+          cloneNode(node.variables), cloneToken(node.semicolon));
+
+  @override
+  WhileStatement visitWhileStatement(WhileStatement node) => new WhileStatement(
+      cloneToken(node.whileKeyword),
+      cloneToken(node.leftParenthesis),
+      cloneNode(node.condition),
+      cloneToken(node.rightParenthesis),
+      cloneNode(node.body));
+
+  @override
+  WithClause visitWithClause(WithClause node) => new WithClause(
+      cloneToken(node.withKeyword), cloneNodeList(node.mixinTypes));
+
+  @override
+  YieldStatement visitYieldStatement(YieldStatement node) => new YieldStatement(
+      cloneToken(node.yieldKeyword),
+      cloneToken(node.star),
+      cloneNode(node.expression),
+      cloneToken(node.semicolon));
+
+  /**
+   * Return a clone of the given [node].
+   */
+  static AstNode clone(AstNode node) {
+    return node.accept(new AstCloner());
+  }
+}
+
+/**
+ * An AstVisitor that compares the structure of two AstNodes to see whether they
+ * are equal.
+ */
+class AstComparator implements AstVisitor<bool> {
+  /**
+   * The AST node with which the node being visited is to be compared. This is
+   * only valid at the beginning of each visit method (until [isEqualNodes] is
+   * invoked).
+   */
+  AstNode _other;
+
+  /**
+   * Return `true` if the [first] node and the [second] node have the same
+   * structure.
+   *
+   * *Note:* This method is only visible for testing purposes and should not be
+   * used by clients.
+   */
+  bool isEqualNodes(AstNode first, AstNode second) {
+    if (first == null) {
+      return second == null;
+    } else if (second == null) {
+      return false;
+    } else if (first.runtimeType != second.runtimeType) {
+      return false;
+    }
+    _other = second;
+    return first.accept(this);
+  }
+
+  /**
+   * Return `true` if the [first] token and the [second] token have the same
+   * structure.
+   *
+   * *Note:* This method is only visible for testing purposes and should not be
+   * used by clients.
+   */
+  bool isEqualTokens(Token first, Token second) {
+    if (first == null) {
+      return second == null;
+    } else if (second == null) {
+      return false;
+    } else if (identical(first, second)) {
+      return true;
+    }
+    return first.offset == second.offset &&
+        first.length == second.length &&
+        first.lexeme == second.lexeme;
+  }
+
+  @override
+  bool visitAdjacentStrings(AdjacentStrings node) {
+    AdjacentStrings other = _other as AdjacentStrings;
+    return _isEqualNodeLists(node.strings, other.strings);
+  }
+
+  @override
+  bool visitAnnotation(Annotation node) {
+    Annotation other = _other as Annotation;
+    return isEqualTokens(node.atSign, other.atSign) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualTokens(node.period, other.period) &&
+        isEqualNodes(node.constructorName, other.constructorName) &&
+        isEqualNodes(node.arguments, other.arguments);
+  }
+
+  @override
+  bool visitArgumentList(ArgumentList node) {
+    ArgumentList other = _other as ArgumentList;
+    return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        _isEqualNodeLists(node.arguments, other.arguments) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis);
+  }
+
+  @override
+  bool visitAsExpression(AsExpression node) {
+    AsExpression other = _other as AsExpression;
+    return isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.asOperator, other.asOperator) &&
+        isEqualNodes(node.type, other.type);
+  }
+
+  @override
+  bool visitAssertStatement(AssertStatement node) {
+    AssertStatement other = _other as AssertStatement;
+    return isEqualTokens(node.assertKeyword, other.assertKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.comma, other.comma) &&
+        isEqualNodes(node.message, other.message) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitAssignmentExpression(AssignmentExpression node) {
+    AssignmentExpression other = _other as AssignmentExpression;
+    return isEqualNodes(node.leftHandSide, other.leftHandSide) &&
+        isEqualTokens(node.operator, other.operator) &&
+        isEqualNodes(node.rightHandSide, other.rightHandSide);
+  }
+
+  @override
+  bool visitAwaitExpression(AwaitExpression node) {
+    AwaitExpression other = _other as AwaitExpression;
+    return isEqualTokens(node.awaitKeyword, other.awaitKeyword) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
+  bool visitBinaryExpression(BinaryExpression node) {
+    BinaryExpression other = _other as BinaryExpression;
+    return isEqualNodes(node.leftOperand, other.leftOperand) &&
+        isEqualTokens(node.operator, other.operator) &&
+        isEqualNodes(node.rightOperand, other.rightOperand);
+  }
+
+  @override
+  bool visitBlock(Block node) {
+    Block other = _other as Block;
+    return isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.statements, other.statements) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitBlockFunctionBody(BlockFunctionBody node) {
+    BlockFunctionBody other = _other as BlockFunctionBody;
+    return isEqualNodes(node.block, other.block);
+  }
+
+  @override
+  bool visitBooleanLiteral(BooleanLiteral node) {
+    BooleanLiteral other = _other as BooleanLiteral;
+    return isEqualTokens(node.literal, other.literal) &&
+        node.value == other.value;
+  }
+
+  @override
+  bool visitBreakStatement(BreakStatement node) {
+    BreakStatement other = _other as BreakStatement;
+    return isEqualTokens(node.breakKeyword, other.breakKeyword) &&
+        isEqualNodes(node.label, other.label) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitCascadeExpression(CascadeExpression node) {
+    CascadeExpression other = _other as CascadeExpression;
+    return isEqualNodes(node.target, other.target) &&
+        _isEqualNodeLists(node.cascadeSections, other.cascadeSections);
+  }
+
+  @override
+  bool visitCatchClause(CatchClause node) {
+    CatchClause other = _other as CatchClause;
+    return isEqualTokens(node.onKeyword, other.onKeyword) &&
+        isEqualNodes(node.exceptionType, other.exceptionType) &&
+        isEqualTokens(node.catchKeyword, other.catchKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.exceptionParameter, other.exceptionParameter) &&
+        isEqualTokens(node.comma, other.comma) &&
+        isEqualNodes(node.stackTraceParameter, other.stackTraceParameter) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
+  bool visitClassDeclaration(ClassDeclaration node) {
+    ClassDeclaration other = _other as ClassDeclaration;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.abstractKeyword, other.abstractKeyword) &&
+        isEqualTokens(node.classKeyword, other.classKeyword) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualNodes(node.typeParameters, other.typeParameters) &&
+        isEqualNodes(node.extendsClause, other.extendsClause) &&
+        isEqualNodes(node.withClause, other.withClause) &&
+        isEqualNodes(node.implementsClause, other.implementsClause) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.members, other.members) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitClassTypeAlias(ClassTypeAlias node) {
+    ClassTypeAlias other = _other as ClassTypeAlias;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.typedefKeyword, other.typedefKeyword) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualNodes(node.typeParameters, other.typeParameters) &&
+        isEqualTokens(node.equals, other.equals) &&
+        isEqualTokens(node.abstractKeyword, other.abstractKeyword) &&
+        isEqualNodes(node.superclass, other.superclass) &&
+        isEqualNodes(node.withClause, other.withClause) &&
+        isEqualNodes(node.implementsClause, other.implementsClause) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitComment(Comment node) {
+    Comment other = _other as Comment;
+    return _isEqualNodeLists(node.references, other.references);
+  }
+
+  @override
+  bool visitCommentReference(CommentReference node) {
+    CommentReference other = _other as CommentReference;
+    return isEqualTokens(node.newKeyword, other.newKeyword) &&
+        isEqualNodes(node.identifier, other.identifier);
+  }
+
+  @override
+  bool visitCompilationUnit(CompilationUnit node) {
+    CompilationUnit other = _other as CompilationUnit;
+    return isEqualTokens(node.beginToken, other.beginToken) &&
+        isEqualNodes(node.scriptTag, other.scriptTag) &&
+        _isEqualNodeLists(node.directives, other.directives) &&
+        _isEqualNodeLists(node.declarations, other.declarations) &&
+        isEqualTokens(node.endToken, other.endToken);
+  }
+
+  @override
+  bool visitConditionalExpression(ConditionalExpression node) {
+    ConditionalExpression other = _other as ConditionalExpression;
+    return isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.question, other.question) &&
+        isEqualNodes(node.thenExpression, other.thenExpression) &&
+        isEqualTokens(node.colon, other.colon) &&
+        isEqualNodes(node.elseExpression, other.elseExpression);
+  }
+
+  @override
+  bool visitConfiguration(Configuration node) {
+    Configuration other = _other as Configuration;
+    return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualTokens(node.equalToken, other.equalToken) &&
+        isEqualNodes(node.value, other.value) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.libraryUri, other.libraryUri);
+  }
+
+  @override
+  bool visitConstructorDeclaration(ConstructorDeclaration node) {
+    ConstructorDeclaration other = _other as ConstructorDeclaration;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.externalKeyword, other.externalKeyword) &&
+        isEqualTokens(node.constKeyword, other.constKeyword) &&
+        isEqualTokens(node.factoryKeyword, other.factoryKeyword) &&
+        isEqualNodes(node.returnType, other.returnType) &&
+        isEqualTokens(node.period, other.period) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualNodes(node.parameters, other.parameters) &&
+        isEqualTokens(node.separator, other.separator) &&
+        _isEqualNodeLists(node.initializers, other.initializers) &&
+        isEqualNodes(node.redirectedConstructor, other.redirectedConstructor) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
+  bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    ConstructorFieldInitializer other = _other as ConstructorFieldInitializer;
+    return isEqualTokens(node.thisKeyword, other.thisKeyword) &&
+        isEqualTokens(node.period, other.period) &&
+        isEqualNodes(node.fieldName, other.fieldName) &&
+        isEqualTokens(node.equals, other.equals) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
+  bool visitConstructorName(ConstructorName node) {
+    ConstructorName other = _other as ConstructorName;
+    return isEqualNodes(node.type, other.type) &&
+        isEqualTokens(node.period, other.period) &&
+        isEqualNodes(node.name, other.name);
+  }
+
+  @override
+  bool visitContinueStatement(ContinueStatement node) {
+    ContinueStatement other = _other as ContinueStatement;
+    return isEqualTokens(node.continueKeyword, other.continueKeyword) &&
+        isEqualNodes(node.label, other.label) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitDeclaredIdentifier(DeclaredIdentifier node) {
+    DeclaredIdentifier other = _other as DeclaredIdentifier;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.type, other.type) &&
+        isEqualNodes(node.identifier, other.identifier);
+  }
+
+  @override
+  bool visitDefaultFormalParameter(DefaultFormalParameter node) {
+    DefaultFormalParameter other = _other as DefaultFormalParameter;
+    return isEqualNodes(node.parameter, other.parameter) &&
+        node.kind == other.kind &&
+        isEqualTokens(node.separator, other.separator) &&
+        isEqualNodes(node.defaultValue, other.defaultValue);
+  }
+
+  @override
+  bool visitDoStatement(DoStatement node) {
+    DoStatement other = _other as DoStatement;
+    return isEqualTokens(node.doKeyword, other.doKeyword) &&
+        isEqualNodes(node.body, other.body) &&
+        isEqualTokens(node.whileKeyword, other.whileKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitDottedName(DottedName node) {
+    DottedName other = _other as DottedName;
+    return _isEqualNodeLists(node.components, other.components);
+  }
+
+  @override
+  bool visitDoubleLiteral(DoubleLiteral node) {
+    DoubleLiteral other = _other as DoubleLiteral;
+    return isEqualTokens(node.literal, other.literal) &&
+        node.value == other.value;
+  }
+
+  @override
+  bool visitEmptyFunctionBody(EmptyFunctionBody node) {
+    EmptyFunctionBody other = _other as EmptyFunctionBody;
+    return isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitEmptyStatement(EmptyStatement node) {
+    EmptyStatement other = _other as EmptyStatement;
+    return isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    EnumConstantDeclaration other = _other as EnumConstantDeclaration;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualNodes(node.name, other.name);
+  }
+
+  @override
+  bool visitEnumDeclaration(EnumDeclaration node) {
+    EnumDeclaration other = _other as EnumDeclaration;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.enumKeyword, other.enumKeyword) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.constants, other.constants) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitExportDirective(ExportDirective node) {
+    ExportDirective other = _other as ExportDirective;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.uri, other.uri) &&
+        _isEqualNodeLists(node.combinators, other.combinators) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    ExpressionFunctionBody other = _other as ExpressionFunctionBody;
+    return isEqualTokens(node.functionDefinition, other.functionDefinition) &&
+        isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitExpressionStatement(ExpressionStatement node) {
+    ExpressionStatement other = _other as ExpressionStatement;
+    return isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitExtendsClause(ExtendsClause node) {
+    ExtendsClause other = _other as ExtendsClause;
+    return isEqualTokens(node.extendsKeyword, other.extendsKeyword) &&
+        isEqualNodes(node.superclass, other.superclass);
+  }
+
+  @override
+  bool visitFieldDeclaration(FieldDeclaration node) {
+    FieldDeclaration other = _other as FieldDeclaration;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.staticKeyword, other.staticKeyword) &&
+        isEqualNodes(node.fields, other.fields) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitFieldFormalParameter(FieldFormalParameter node) {
+    FieldFormalParameter other = _other as FieldFormalParameter;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.type, other.type) &&
+        isEqualTokens(node.thisKeyword, other.thisKeyword) &&
+        isEqualTokens(node.period, other.period) &&
+        isEqualNodes(node.identifier, other.identifier);
+  }
+
+  @override
+  bool visitForEachStatement(ForEachStatement node) {
+    ForEachStatement other = _other as ForEachStatement;
+    return isEqualTokens(node.forKeyword, other.forKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.loopVariable, other.loopVariable) &&
+        isEqualTokens(node.inKeyword, other.inKeyword) &&
+        isEqualNodes(node.iterable, other.iterable) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
+  bool visitFormalParameterList(FormalParameterList node) {
+    FormalParameterList other = _other as FormalParameterList;
+    return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        _isEqualNodeLists(node.parameters, other.parameters) &&
+        isEqualTokens(node.leftDelimiter, other.leftDelimiter) &&
+        isEqualTokens(node.rightDelimiter, other.rightDelimiter) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis);
+  }
+
+  @override
+  bool visitForStatement(ForStatement node) {
+    ForStatement other = _other as ForStatement;
+    return isEqualTokens(node.forKeyword, other.forKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.variables, other.variables) &&
+        isEqualNodes(node.initialization, other.initialization) &&
+        isEqualTokens(node.leftSeparator, other.leftSeparator) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.rightSeparator, other.rightSeparator) &&
+        _isEqualNodeLists(node.updaters, other.updaters) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
+  bool visitFunctionDeclaration(FunctionDeclaration node) {
+    FunctionDeclaration other = _other as FunctionDeclaration;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.externalKeyword, other.externalKeyword) &&
+        isEqualNodes(node.returnType, other.returnType) &&
+        isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualNodes(node.functionExpression, other.functionExpression);
+  }
+
+  @override
+  bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    FunctionDeclarationStatement other = _other as FunctionDeclarationStatement;
+    return isEqualNodes(node.functionDeclaration, other.functionDeclaration);
+  }
+
+  @override
+  bool visitFunctionExpression(FunctionExpression node) {
+    FunctionExpression other = _other as FunctionExpression;
+    return isEqualNodes(node.parameters, other.parameters) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
+  bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    FunctionExpressionInvocation other = _other as FunctionExpressionInvocation;
+    return isEqualNodes(node.function, other.function) &&
+        isEqualNodes(node.argumentList, other.argumentList);
+  }
+
+  @override
+  bool visitFunctionTypeAlias(FunctionTypeAlias node) {
+    FunctionTypeAlias other = _other as FunctionTypeAlias;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.typedefKeyword, other.typedefKeyword) &&
+        isEqualNodes(node.returnType, other.returnType) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualNodes(node.typeParameters, other.typeParameters) &&
+        isEqualNodes(node.parameters, other.parameters) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    FunctionTypedFormalParameter other = _other as FunctionTypedFormalParameter;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualNodes(node.returnType, other.returnType) &&
+        isEqualNodes(node.identifier, other.identifier) &&
+        isEqualNodes(node.parameters, other.parameters);
+  }
+
+  @override
+  bool visitHideCombinator(HideCombinator node) {
+    HideCombinator other = _other as HideCombinator;
+    return isEqualTokens(node.keyword, other.keyword) &&
+        _isEqualNodeLists(node.hiddenNames, other.hiddenNames);
+  }
+
+  @override
+  bool visitIfStatement(IfStatement node) {
+    IfStatement other = _other as IfStatement;
+    return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.thenStatement, other.thenStatement) &&
+        isEqualTokens(node.elseKeyword, other.elseKeyword) &&
+        isEqualNodes(node.elseStatement, other.elseStatement);
+  }
+
+  @override
+  bool visitImplementsClause(ImplementsClause node) {
+    ImplementsClause other = _other as ImplementsClause;
+    return isEqualTokens(node.implementsKeyword, other.implementsKeyword) &&
+        _isEqualNodeLists(node.interfaces, other.interfaces);
+  }
+
+  @override
+  bool visitImportDirective(ImportDirective node) {
+    ImportDirective other = _other as ImportDirective;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.uri, other.uri) &&
+        isEqualTokens(node.deferredKeyword, other.deferredKeyword) &&
+        isEqualTokens(node.asKeyword, other.asKeyword) &&
+        isEqualNodes(node.prefix, other.prefix) &&
+        _isEqualNodeLists(node.combinators, other.combinators) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitIndexExpression(IndexExpression node) {
+    IndexExpression other = _other as IndexExpression;
+    return isEqualNodes(node.target, other.target) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        isEqualNodes(node.index, other.index) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitInstanceCreationExpression(InstanceCreationExpression node) {
+    InstanceCreationExpression other = _other as InstanceCreationExpression;
+    return isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.constructorName, other.constructorName) &&
+        isEqualNodes(node.argumentList, other.argumentList);
+  }
+
+  @override
+  bool visitIntegerLiteral(IntegerLiteral node) {
+    IntegerLiteral other = _other as IntegerLiteral;
+    return isEqualTokens(node.literal, other.literal) &&
+        (node.value == other.value);
+  }
+
+  @override
+  bool visitInterpolationExpression(InterpolationExpression node) {
+    InterpolationExpression other = _other as InterpolationExpression;
+    return isEqualTokens(node.leftBracket, other.leftBracket) &&
+        isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitInterpolationString(InterpolationString node) {
+    InterpolationString other = _other as InterpolationString;
+    return isEqualTokens(node.contents, other.contents) &&
+        node.value == other.value;
+  }
+
+  @override
+  bool visitIsExpression(IsExpression node) {
+    IsExpression other = _other as IsExpression;
+    return isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.isOperator, other.isOperator) &&
+        isEqualTokens(node.notOperator, other.notOperator) &&
+        isEqualNodes(node.type, other.type);
+  }
+
+  @override
+  bool visitLabel(Label node) {
+    Label other = _other as Label;
+    return isEqualNodes(node.label, other.label) &&
+        isEqualTokens(node.colon, other.colon);
+  }
+
+  @override
+  bool visitLabeledStatement(LabeledStatement node) {
+    LabeledStatement other = _other as LabeledStatement;
+    return _isEqualNodeLists(node.labels, other.labels) &&
+        isEqualNodes(node.statement, other.statement);
+  }
+
+  @override
+  bool visitLibraryDirective(LibraryDirective node) {
+    LibraryDirective other = _other as LibraryDirective;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.libraryKeyword, other.libraryKeyword) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitLibraryIdentifier(LibraryIdentifier node) {
+    LibraryIdentifier other = _other as LibraryIdentifier;
+    return _isEqualNodeLists(node.components, other.components);
+  }
+
+  @override
+  bool visitListLiteral(ListLiteral node) {
+    ListLiteral other = _other as ListLiteral;
+    return isEqualTokens(node.constKeyword, other.constKeyword) &&
+        isEqualNodes(node.typeArguments, other.typeArguments) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.elements, other.elements) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitMapLiteral(MapLiteral node) {
+    MapLiteral other = _other as MapLiteral;
+    return isEqualTokens(node.constKeyword, other.constKeyword) &&
+        isEqualNodes(node.typeArguments, other.typeArguments) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.entries, other.entries) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitMapLiteralEntry(MapLiteralEntry node) {
+    MapLiteralEntry other = _other as MapLiteralEntry;
+    return isEqualNodes(node.key, other.key) &&
+        isEqualTokens(node.separator, other.separator) &&
+        isEqualNodes(node.value, other.value);
+  }
+
+  @override
+  bool visitMethodDeclaration(MethodDeclaration node) {
+    MethodDeclaration other = _other as MethodDeclaration;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.externalKeyword, other.externalKeyword) &&
+        isEqualTokens(node.modifierKeyword, other.modifierKeyword) &&
+        isEqualNodes(node.returnType, other.returnType) &&
+        isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
+        isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualNodes(node.parameters, other.parameters) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
+  bool visitMethodInvocation(MethodInvocation node) {
+    MethodInvocation other = _other as MethodInvocation;
+    return isEqualNodes(node.target, other.target) &&
+        isEqualTokens(node.operator, other.operator) &&
+        isEqualNodes(node.methodName, other.methodName) &&
+        isEqualNodes(node.argumentList, other.argumentList);
+  }
+
+  @override
+  bool visitNamedExpression(NamedExpression node) {
+    NamedExpression other = _other as NamedExpression;
+    return isEqualNodes(node.name, other.name) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
+  bool visitNativeClause(NativeClause node) {
+    NativeClause other = _other as NativeClause;
+    return isEqualTokens(node.nativeKeyword, other.nativeKeyword) &&
+        isEqualNodes(node.name, other.name);
+  }
+
+  @override
+  bool visitNativeFunctionBody(NativeFunctionBody node) {
+    NativeFunctionBody other = _other as NativeFunctionBody;
+    return isEqualTokens(node.nativeKeyword, other.nativeKeyword) &&
+        isEqualNodes(node.stringLiteral, other.stringLiteral) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitNullLiteral(NullLiteral node) {
+    NullLiteral other = _other as NullLiteral;
+    return isEqualTokens(node.literal, other.literal);
+  }
+
+  @override
+  bool visitParenthesizedExpression(ParenthesizedExpression node) {
+    ParenthesizedExpression other = _other as ParenthesizedExpression;
+    return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis);
+  }
+
+  @override
+  bool visitPartDirective(PartDirective node) {
+    PartDirective other = _other as PartDirective;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.partKeyword, other.partKeyword) &&
+        isEqualNodes(node.uri, other.uri) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitPartOfDirective(PartOfDirective node) {
+    PartOfDirective other = _other as PartOfDirective;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.partKeyword, other.partKeyword) &&
+        isEqualTokens(node.ofKeyword, other.ofKeyword) &&
+        isEqualNodes(node.libraryName, other.libraryName) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitPostfixExpression(PostfixExpression node) {
+    PostfixExpression other = _other as PostfixExpression;
+    return isEqualNodes(node.operand, other.operand) &&
+        isEqualTokens(node.operator, other.operator);
+  }
+
+  @override
+  bool visitPrefixedIdentifier(PrefixedIdentifier node) {
+    PrefixedIdentifier other = _other as PrefixedIdentifier;
+    return isEqualNodes(node.prefix, other.prefix) &&
+        isEqualTokens(node.period, other.period) &&
+        isEqualNodes(node.identifier, other.identifier);
+  }
+
+  @override
+  bool visitPrefixExpression(PrefixExpression node) {
+    PrefixExpression other = _other as PrefixExpression;
+    return isEqualTokens(node.operator, other.operator) &&
+        isEqualNodes(node.operand, other.operand);
+  }
+
+  @override
+  bool visitPropertyAccess(PropertyAccess node) {
+    PropertyAccess other = _other as PropertyAccess;
+    return isEqualNodes(node.target, other.target) &&
+        isEqualTokens(node.operator, other.operator) &&
+        isEqualNodes(node.propertyName, other.propertyName);
+  }
+
+  @override
+  bool visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    RedirectingConstructorInvocation other =
+        _other as RedirectingConstructorInvocation;
+    return isEqualTokens(node.thisKeyword, other.thisKeyword) &&
+        isEqualTokens(node.period, other.period) &&
+        isEqualNodes(node.constructorName, other.constructorName) &&
+        isEqualNodes(node.argumentList, other.argumentList);
+  }
+
+  @override
+  bool visitRethrowExpression(RethrowExpression node) {
+    RethrowExpression other = _other as RethrowExpression;
+    return isEqualTokens(node.rethrowKeyword, other.rethrowKeyword);
+  }
+
+  @override
+  bool visitReturnStatement(ReturnStatement node) {
+    ReturnStatement other = _other as ReturnStatement;
+    return isEqualTokens(node.returnKeyword, other.returnKeyword) &&
+        isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitScriptTag(ScriptTag node) {
+    ScriptTag other = _other as ScriptTag;
+    return isEqualTokens(node.scriptTag, other.scriptTag);
+  }
+
+  @override
+  bool visitShowCombinator(ShowCombinator node) {
+    ShowCombinator other = _other as ShowCombinator;
+    return isEqualTokens(node.keyword, other.keyword) &&
+        _isEqualNodeLists(node.shownNames, other.shownNames);
+  }
+
+  @override
+  bool visitSimpleFormalParameter(SimpleFormalParameter node) {
+    SimpleFormalParameter other = _other as SimpleFormalParameter;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.type, other.type) &&
+        isEqualNodes(node.identifier, other.identifier);
+  }
+
+  @override
+  bool visitSimpleIdentifier(SimpleIdentifier node) {
+    SimpleIdentifier other = _other as SimpleIdentifier;
+    return isEqualTokens(node.token, other.token);
+  }
+
+  @override
+  bool visitSimpleStringLiteral(SimpleStringLiteral node) {
+    SimpleStringLiteral other = _other as SimpleStringLiteral;
+    return isEqualTokens(node.literal, other.literal) &&
+        (node.value == other.value);
+  }
+
+  @override
+  bool visitStringInterpolation(StringInterpolation node) {
+    StringInterpolation other = _other as StringInterpolation;
+    return _isEqualNodeLists(node.elements, other.elements);
+  }
+
+  @override
+  bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    SuperConstructorInvocation other = _other as SuperConstructorInvocation;
+    return isEqualTokens(node.superKeyword, other.superKeyword) &&
+        isEqualTokens(node.period, other.period) &&
+        isEqualNodes(node.constructorName, other.constructorName) &&
+        isEqualNodes(node.argumentList, other.argumentList);
+  }
+
+  @override
+  bool visitSuperExpression(SuperExpression node) {
+    SuperExpression other = _other as SuperExpression;
+    return isEqualTokens(node.superKeyword, other.superKeyword);
+  }
+
+  @override
+  bool visitSwitchCase(SwitchCase node) {
+    SwitchCase other = _other as SwitchCase;
+    return _isEqualNodeLists(node.labels, other.labels) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.colon, other.colon) &&
+        _isEqualNodeLists(node.statements, other.statements);
+  }
+
+  @override
+  bool visitSwitchDefault(SwitchDefault node) {
+    SwitchDefault other = _other as SwitchDefault;
+    return _isEqualNodeLists(node.labels, other.labels) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualTokens(node.colon, other.colon) &&
+        _isEqualNodeLists(node.statements, other.statements);
+  }
+
+  @override
+  bool visitSwitchStatement(SwitchStatement node) {
+    SwitchStatement other = _other as SwitchStatement;
+    return isEqualTokens(node.switchKeyword, other.switchKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.members, other.members) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitSymbolLiteral(SymbolLiteral node) {
+    SymbolLiteral other = _other as SymbolLiteral;
+    return isEqualTokens(node.poundSign, other.poundSign) &&
+        _isEqualTokenLists(node.components, other.components);
+  }
+
+  @override
+  bool visitThisExpression(ThisExpression node) {
+    ThisExpression other = _other as ThisExpression;
+    return isEqualTokens(node.thisKeyword, other.thisKeyword);
+  }
+
+  @override
+  bool visitThrowExpression(ThrowExpression node) {
+    ThrowExpression other = _other as ThrowExpression;
+    return isEqualTokens(node.throwKeyword, other.throwKeyword) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
+  bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    TopLevelVariableDeclaration other = _other as TopLevelVariableDeclaration;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualNodes(node.variables, other.variables) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitTryStatement(TryStatement node) {
+    TryStatement other = _other as TryStatement;
+    return isEqualTokens(node.tryKeyword, other.tryKeyword) &&
+        isEqualNodes(node.body, other.body) &&
+        _isEqualNodeLists(node.catchClauses, other.catchClauses) &&
+        isEqualTokens(node.finallyKeyword, other.finallyKeyword) &&
+        isEqualNodes(node.finallyBlock, other.finallyBlock);
+  }
+
+  @override
+  bool visitTypeArgumentList(TypeArgumentList node) {
+    TypeArgumentList other = _other as TypeArgumentList;
+    return isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.arguments, other.arguments) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitTypeName(TypeName node) {
+    TypeName other = _other as TypeName;
+    return isEqualNodes(node.name, other.name) &&
+        isEqualNodes(node.typeArguments, other.typeArguments);
+  }
+
+  @override
+  bool visitTypeParameter(TypeParameter node) {
+    TypeParameter other = _other as TypeParameter;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualTokens(node.extendsKeyword, other.extendsKeyword) &&
+        isEqualNodes(node.bound, other.bound);
+  }
+
+  @override
+  bool visitTypeParameterList(TypeParameterList node) {
+    TypeParameterList other = _other as TypeParameterList;
+    return isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.typeParameters, other.typeParameters) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
+  bool visitVariableDeclaration(VariableDeclaration node) {
+    VariableDeclaration other = _other as VariableDeclaration;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualTokens(node.equals, other.equals) &&
+        isEqualNodes(node.initializer, other.initializer);
+  }
+
+  @override
+  bool visitVariableDeclarationList(VariableDeclarationList node) {
+    VariableDeclarationList other = _other as VariableDeclarationList;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.type, other.type) &&
+        _isEqualNodeLists(node.variables, other.variables);
+  }
+
+  @override
+  bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    VariableDeclarationStatement other = _other as VariableDeclarationStatement;
+    return isEqualNodes(node.variables, other.variables) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
+  bool visitWhileStatement(WhileStatement node) {
+    WhileStatement other = _other as WhileStatement;
+    return isEqualTokens(node.whileKeyword, other.whileKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
+  bool visitWithClause(WithClause node) {
+    WithClause other = _other as WithClause;
+    return isEqualTokens(node.withKeyword, other.withKeyword) &&
+        _isEqualNodeLists(node.mixinTypes, other.mixinTypes);
+  }
+
+  @override
+  bool visitYieldStatement(YieldStatement node) {
+    YieldStatement other = _other as YieldStatement;
+    return isEqualTokens(node.yieldKeyword, other.yieldKeyword) &&
+        isEqualNodes(node.expression, other.expression) &&
+        isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  /**
+   * Return `true` if the [first] and [second] lists of AST nodes have the same
+   * size and corresponding elements are equal.
+   */
+  bool _isEqualNodeLists(NodeList first, NodeList second) {
+    if (first == null) {
+      return second == null;
+    } else if (second == null) {
+      return false;
+    }
+    int size = first.length;
+    if (second.length != size) {
+      return false;
+    }
+    for (int i = 0; i < size; i++) {
+      if (!isEqualNodes(first[i], second[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Return `true` if the [first] and [second] lists of tokens have the same
+   * length and corresponding elements are equal.
+   */
+  bool _isEqualTokenLists(List<Token> first, List<Token> second) {
+    int length = first.length;
+    if (second.length != length) {
+      return false;
+    }
+    for (int i = 0; i < length; i++) {
+      if (!isEqualTokens(first[i], second[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Return `true` if the [first] and [second] nodes are equal.
+   */
+  static bool equalNodes(AstNode first, AstNode second) {
+    AstComparator comparator = new AstComparator();
+    return comparator.isEqualNodes(first, second);
+  }
+}
+
+/**
+ * Instances of the class [ConstantEvaluator] evaluate constant expressions to
+ * produce their compile-time value.
+ *
+ * According to the Dart Language Specification:
+ *
+ * > A constant expression is one of the following:
+ * >
+ * > * A literal number.
+ * > * A literal boolean.
+ * > * A literal string where any interpolated expression is a compile-time
+ * >   constant that evaluates to a numeric, string or boolean value or to
+ * >   **null**.
+ * > * A literal symbol.
+ * > * **null**.
+ * > * A qualified reference to a static constant variable.
+ * > * An identifier expression that denotes a constant variable, class or type
+ * >   alias.
+ * > * A constant constructor invocation.
+ * > * A constant list literal.
+ * > * A constant map literal.
+ * > * A simple or qualified identifier denoting a top-level function or a
+ * >   static method.
+ * > * A parenthesized expression _(e)_ where _e_ is a constant expression.
+ * > * <span>
+ * >   An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i>
+ * >   where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * >   expressions and <i>identical()</i> is statically bound to the predefined
+ * >   dart function <i>identical()</i> discussed above.
+ * >   </span>
+ * > * <span>
+ * >   An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i>
+ * >   or <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and
+ * >   <i>e<sub>2</sub></i> are constant expressions that evaluate to a
+ * >   numeric, string or boolean value.
+ * >   </span>
+ * > * <span>
+ * >   An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp;
+ * >   e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where
+ * >   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * >   expressions that evaluate to a boolean value.
+ * >   </span>
+ * > * <span>
+ * >   An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^
+ * >   e<sub>2</sub></i>, <i>e<sub>1</sub> &amp; e<sub>2</sub></i>,
+ * >   <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;&gt;
+ * >   e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where
+ * >   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * >   expressions that evaluate to an integer value or to <b>null</b>.
+ * >   </span>
+ * > * <span>
+ * >   An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> +
+ * >   e<sub>2</sub></i>, <i>e<sub>1</sub> -e<sub>2</sub></i>,
+ * >   <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> /
+ * >   e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>,
+ * >   <i>e<sub>1</sub> &gt; e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;
+ * >   e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;= e<sub>2</sub></i>,
+ * >   <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</sub> %
+ * >   e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and
+ * >   <i>e<sub>2</sub></i> are constant expressions that evaluate to a numeric
+ * >   value or to <b>null</b>.
+ * >   </span>
+ * > * <span>
+ * >   An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> :
+ * >   e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and
+ * >   <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i>
+ * >   evaluates to a boolean value.
+ * >   </span>
+ *
+ * The values returned by instances of this class are therefore `null` and
+ * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and
+ * `DartObject`.
+ *
+ * In addition, this class defines several values that can be returned to
+ * indicate various conditions encountered during evaluation. These are
+ * documented with the static fields that define those values.
+ */
+class ConstantEvaluator extends GeneralizingAstVisitor<Object> {
+  /**
+   * The value returned for expressions (or non-expression nodes) that are not
+   * compile-time constant expressions.
+   */
+  static Object NOT_A_CONSTANT = new Object();
+
+  @override
+  Object visitAdjacentStrings(AdjacentStrings node) {
+    StringBuffer buffer = new StringBuffer();
+    for (StringLiteral string in node.strings) {
+      Object value = string.accept(this);
+      if (identical(value, NOT_A_CONSTANT)) {
+        return value;
+      }
+      buffer.write(value);
+    }
+    return buffer.toString();
+  }
+
+  @override
+  Object visitBinaryExpression(BinaryExpression node) {
+    Object leftOperand = node.leftOperand.accept(this);
+    if (identical(leftOperand, NOT_A_CONSTANT)) {
+      return leftOperand;
+    }
+    Object rightOperand = node.rightOperand.accept(this);
+    if (identical(rightOperand, NOT_A_CONSTANT)) {
+      return rightOperand;
+    }
+    while (true) {
+      if (node.operator.type == TokenType.AMPERSAND) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand & rightOperand;
+        }
+      } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
+        // boolean or {@code null}
+        if (leftOperand is bool && rightOperand is bool) {
+          return leftOperand && rightOperand;
+        }
+      } else if (node.operator.type == TokenType.BANG_EQ) {
+        // numeric, string, boolean, or {@code null}
+        if (leftOperand is bool && rightOperand is bool) {
+          return leftOperand != rightOperand;
+        } else if (leftOperand is num && rightOperand is num) {
+          return leftOperand != rightOperand;
+        } else if (leftOperand is String && rightOperand is String) {
+          return leftOperand != rightOperand;
+        }
+      } else if (node.operator.type == TokenType.BAR) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand | rightOperand;
+        }
+      } else if (node.operator.type == TokenType.BAR_BAR) {
+        // boolean or {@code null}
+        if (leftOperand is bool && rightOperand is bool) {
+          return leftOperand || rightOperand;
+        }
+      } else if (node.operator.type == TokenType.CARET) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand ^ rightOperand;
+        }
+      } else if (node.operator.type == TokenType.EQ_EQ) {
+        // numeric, string, boolean, or {@code null}
+        if (leftOperand is bool && rightOperand is bool) {
+          return leftOperand == rightOperand;
+        } else if (leftOperand is num && rightOperand is num) {
+          return leftOperand == rightOperand;
+        } else if (leftOperand is String && rightOperand is String) {
+          return leftOperand == rightOperand;
+        }
+      } else if (node.operator.type == TokenType.GT) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.compareTo(rightOperand) > 0;
+        }
+      } else if (node.operator.type == TokenType.GT_EQ) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.compareTo(rightOperand) >= 0;
+        }
+      } else if (node.operator.type == TokenType.GT_GT) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand >> rightOperand;
+        }
+      } else if (node.operator.type == TokenType.LT) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.compareTo(rightOperand) < 0;
+        }
+      } else if (node.operator.type == TokenType.LT_EQ) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.compareTo(rightOperand) <= 0;
+        }
+      } else if (node.operator.type == TokenType.LT_LT) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand << rightOperand;
+        }
+      } else if (node.operator.type == TokenType.MINUS) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand - rightOperand;
+        }
+      } else if (node.operator.type == TokenType.PERCENT) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.remainder(rightOperand);
+        }
+      } else if (node.operator.type == TokenType.PLUS) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand + rightOperand;
+        }
+      } else if (node.operator.type == TokenType.STAR) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand * rightOperand;
+        }
+      } else if (node.operator.type == TokenType.SLASH) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand / rightOperand;
+        }
+      } else if (node.operator.type == TokenType.TILDE_SLASH) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand ~/ rightOperand;
+        }
+      } else {}
+      break;
+    }
+    // TODO(brianwilkerson) This doesn't handle numeric conversions.
+    return visitExpression(node);
+  }
+
+  @override
+  Object visitBooleanLiteral(BooleanLiteral node) => node.value ? true : false;
+
+  @override
+  Object visitDoubleLiteral(DoubleLiteral node) => node.value;
+
+  @override
+  Object visitIntegerLiteral(IntegerLiteral node) => node.value;
+
+  @override
+  Object visitInterpolationExpression(InterpolationExpression node) {
+    Object value = node.expression.accept(this);
+    if (value == null || value is bool || value is String || value is num) {
+      return value;
+    }
+    return NOT_A_CONSTANT;
+  }
+
+  @override
+  Object visitInterpolationString(InterpolationString node) => node.value;
+
+  @override
+  Object visitListLiteral(ListLiteral node) {
+    List<Object> list = new List<Object>();
+    for (Expression element in node.elements) {
+      Object value = element.accept(this);
+      if (identical(value, NOT_A_CONSTANT)) {
+        return value;
+      }
+      list.add(value);
+    }
+    return list;
+  }
+
+  @override
+  Object visitMapLiteral(MapLiteral node) {
+    HashMap<String, Object> map = new HashMap<String, Object>();
+    for (MapLiteralEntry entry in node.entries) {
+      Object key = entry.key.accept(this);
+      Object value = entry.value.accept(this);
+      if (key is! String || identical(value, NOT_A_CONSTANT)) {
+        return NOT_A_CONSTANT;
+      }
+      map[(key as String)] = value;
+    }
+    return map;
+  }
+
+  @override
+  Object visitMethodInvocation(MethodInvocation node) => visitNode(node);
+
+  @override
+  Object visitNode(AstNode node) => NOT_A_CONSTANT;
+
+  @override
+  Object visitNullLiteral(NullLiteral node) => null;
+
+  @override
+  Object visitParenthesizedExpression(ParenthesizedExpression node) =>
+      node.expression.accept(this);
+
+  @override
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) =>
+      _getConstantValue(null);
+
+  @override
+  Object visitPrefixExpression(PrefixExpression node) {
+    Object operand = node.operand.accept(this);
+    if (identical(operand, NOT_A_CONSTANT)) {
+      return operand;
+    }
+    while (true) {
+      if (node.operator.type == TokenType.BANG) {
+        if (identical(operand, true)) {
+          return false;
+        } else if (identical(operand, false)) {
+          return true;
+        }
+      } else if (node.operator.type == TokenType.TILDE) {
+        if (operand is int) {
+          return ~operand;
+        }
+      } else if (node.operator.type == TokenType.MINUS) {
+        if (operand == null) {
+          return null;
+        } else if (operand is num) {
+          return -operand;
+        }
+      } else {}
+      break;
+    }
+    return NOT_A_CONSTANT;
+  }
+
+  @override
+  Object visitPropertyAccess(PropertyAccess node) => _getConstantValue(null);
+
+  @override
+  Object visitSimpleIdentifier(SimpleIdentifier node) =>
+      _getConstantValue(null);
+
+  @override
+  Object visitSimpleStringLiteral(SimpleStringLiteral node) => node.value;
+
+  @override
+  Object visitStringInterpolation(StringInterpolation node) {
+    StringBuffer buffer = new StringBuffer();
+    for (InterpolationElement element in node.elements) {
+      Object value = element.accept(this);
+      if (identical(value, NOT_A_CONSTANT)) {
+        return value;
+      }
+      buffer.write(value);
+    }
+    return buffer.toString();
+  }
+
+  @override
+  Object visitSymbolLiteral(SymbolLiteral node) {
+    // TODO(brianwilkerson) This isn't optimal because a Symbol is not a String.
+    StringBuffer buffer = new StringBuffer();
+    for (Token component in node.components) {
+      if (buffer.length > 0) {
+        buffer.writeCharCode(0x2E);
+      }
+      buffer.write(component.lexeme);
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * Return the constant value of the static constant represented by the given
+   * [element].
+   */
+  Object _getConstantValue(Element element) {
+    // TODO(brianwilkerson) Implement this
+    if (element is FieldElement) {
+      FieldElement field = element;
+      if (field.isStatic && field.isConst) {
+        //field.getConstantValue();
+      }
+      //    } else if (element instanceof VariableElement) {
+      //      VariableElement variable = (VariableElement) element;
+      //      if (variable.isStatic() && variable.isConst()) {
+      //        //variable.getConstantValue();
+      //      }
+    }
+    return NOT_A_CONSTANT;
+  }
+}
+
+/**
+ * A recursive AST visitor that is used to run over [Expression]s to determine
+ * whether the expression is composed by at least one deferred
+ * [PrefixedIdentifier].
+ *
+ * See [PrefixedIdentifier.isDeferred].
+ */
+class DeferredLibraryReferenceDetector extends RecursiveAstVisitor<Object> {
+  /**
+   * A flag indicating whether an identifier from a deferred library has been
+   * found.
+   */
+  bool _result = false;
+
+  /**
+   * Return `true` if the visitor found a [PrefixedIdentifier] that returned
+   * `true` to the [PrefixedIdentifier.isDeferred] query.
+   */
+  bool get result => _result;
+
+  @override
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    if (!_result) {
+      if (node.isDeferred) {
+        _result = true;
+      }
+    }
+    return null;
+  }
+}
+
+/**
+ * An object used to locate the [Element] associated with a given [AstNode].
+ */
+class ElementLocator {
+  /**
+   * Return the element associated with the given [node], or `null` if there is
+   * no element associated with the node.
+   */
+  static Element locate(AstNode node) {
+    if (node == null) {
+      return null;
+    }
+    ElementLocator_ElementMapper mapper = new ElementLocator_ElementMapper();
+    return node.accept(mapper);
+  }
+}
+
+/**
+ * Visitor that maps nodes to elements.
+ */
+class ElementLocator_ElementMapper extends GeneralizingAstVisitor<Element> {
+  @override
+  Element visitAnnotation(Annotation node) => node.element;
+
+  @override
+  Element visitAssignmentExpression(AssignmentExpression node) =>
+      node.bestElement;
+
+  @override
+  Element visitBinaryExpression(BinaryExpression node) => node.bestElement;
+
+  @override
+  Element visitClassDeclaration(ClassDeclaration node) => node.element;
+
+  @override
+  Element visitCompilationUnit(CompilationUnit node) => node.element;
+
+  @override
+  Element visitConstructorDeclaration(ConstructorDeclaration node) =>
+      node.element;
+
+  @override
+  Element visitFunctionDeclaration(FunctionDeclaration node) => node.element;
+
+  @override
+  Element visitIdentifier(Identifier node) {
+    AstNode parent = node.parent;
+    // Type name in Annotation
+    if (parent is Annotation) {
+      Annotation annotation = parent;
+      if (identical(annotation.name, node) &&
+          annotation.constructorName == null) {
+        return annotation.element;
+      }
+    }
+    // Extra work to map Constructor Declarations to their associated
+    // Constructor Elements
+    if (parent is ConstructorDeclaration) {
+      Identifier returnType = parent.returnType;
+      if (identical(returnType, node)) {
+        SimpleIdentifier name = parent.name;
+        if (name != null) {
+          return name.bestElement;
+        }
+        Element element = node.bestElement;
+        if (element is ClassElement) {
+          return element.unnamedConstructor;
+        }
+      }
+    }
+    if (parent is LibraryIdentifier) {
+      AstNode grandParent = parent.parent;
+      if (grandParent is PartOfDirective) {
+        Element element = grandParent.element;
+        if (element is LibraryElement) {
+          return element.definingCompilationUnit;
+        }
+      }
+    }
+    return node.bestElement;
+  }
+
+  @override
+  Element visitImportDirective(ImportDirective node) => node.element;
+
+  @override
+  Element visitIndexExpression(IndexExpression node) => node.bestElement;
+
+  @override
+  Element visitInstanceCreationExpression(InstanceCreationExpression node) =>
+      node.staticElement;
+
+  @override
+  Element visitLibraryDirective(LibraryDirective node) => node.element;
+
+  @override
+  Element visitMethodDeclaration(MethodDeclaration node) => node.element;
+
+  @override
+  Element visitMethodInvocation(MethodInvocation node) =>
+      node.methodName.bestElement;
+
+  @override
+  Element visitPartOfDirective(PartOfDirective node) => node.element;
+
+  @override
+  Element visitPostfixExpression(PostfixExpression node) => node.bestElement;
+
+  @override
+  Element visitPrefixedIdentifier(PrefixedIdentifier node) => node.bestElement;
+
+  @override
+  Element visitPrefixExpression(PrefixExpression node) => node.bestElement;
+
+  @override
+  Element visitStringLiteral(StringLiteral node) {
+    AstNode parent = node.parent;
+    if (parent is UriBasedDirective) {
+      return parent.uriElement;
+    }
+    return null;
+  }
+
+  @override
+  Element visitVariableDeclaration(VariableDeclaration node) => node.element;
+}
+
+/**
+ * An object that will clone any AST structure that it visits. The cloner will
+ * clone the structure, replacing the specified ASTNode with a new ASTNode,
+ * mapping the old token stream to a new token stream, and preserving resolution
+ * results.
+ */
+class IncrementalAstCloner implements AstVisitor<AstNode> {
+  /**
+   * The node to be replaced during the cloning process.
+   */
+  final AstNode _oldNode;
+
+  /**
+   * The replacement node used during the cloning process.
+   */
+  final AstNode _newNode;
+
+  /**
+   * A mapping of old tokens to new tokens used during the cloning process.
+   */
+  final TokenMap _tokenMap;
+
+  /**
+   * Construct a new instance that will replace the [oldNode] with the [newNode]
+   * in the process of cloning an existing AST structure. The [tokenMap] is a
+   * mapping of old tokens to new tokens.
+   */
+  IncrementalAstCloner(this._oldNode, this._newNode, this._tokenMap);
+
+  @override
+  AdjacentStrings visitAdjacentStrings(AdjacentStrings node) =>
+      new AdjacentStrings(_cloneNodeList(node.strings));
+
+  @override
+  Annotation visitAnnotation(Annotation node) {
+    Annotation copy = new Annotation(
+        _mapToken(node.atSign),
+        _cloneNode(node.name),
+        _mapToken(node.period),
+        _cloneNode(node.constructorName),
+        _cloneNode(node.arguments));
+    copy.element = node.element;
+    return copy;
+  }
+
+  @override
+  ArgumentList visitArgumentList(ArgumentList node) => new ArgumentList(
+      _mapToken(node.leftParenthesis),
+      _cloneNodeList(node.arguments),
+      _mapToken(node.rightParenthesis));
+
+  @override
+  AsExpression visitAsExpression(AsExpression node) {
+    AsExpression copy = new AsExpression(_cloneNode(node.expression),
+        _mapToken(node.asOperator), _cloneNode(node.type));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  AstNode visitAssertStatement(AssertStatement node) => new AssertStatement(
+      _mapToken(node.assertKeyword),
+      _mapToken(node.leftParenthesis),
+      _cloneNode(node.condition),
+      _mapToken(node.comma),
+      _cloneNode(node.message),
+      _mapToken(node.rightParenthesis),
+      _mapToken(node.semicolon));
+
+  @override
+  AssignmentExpression visitAssignmentExpression(AssignmentExpression node) {
+    AssignmentExpression copy = new AssignmentExpression(
+        _cloneNode(node.leftHandSide),
+        _mapToken(node.operator),
+        _cloneNode(node.rightHandSide));
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  AwaitExpression visitAwaitExpression(AwaitExpression node) =>
+      new AwaitExpression(
+          _mapToken(node.awaitKeyword), _cloneNode(node.expression));
+
+  @override
+  BinaryExpression visitBinaryExpression(BinaryExpression node) {
+    BinaryExpression copy = new BinaryExpression(_cloneNode(node.leftOperand),
+        _mapToken(node.operator), _cloneNode(node.rightOperand));
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  Block visitBlock(Block node) => new Block(_mapToken(node.leftBracket),
+      _cloneNodeList(node.statements), _mapToken(node.rightBracket));
+
+  @override
+  BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) =>
+      new BlockFunctionBody(_mapToken(node.keyword), _mapToken(node.star),
+          _cloneNode(node.block));
+
+  @override
+  BooleanLiteral visitBooleanLiteral(BooleanLiteral node) {
+    BooleanLiteral copy =
+        new BooleanLiteral(_mapToken(node.literal), node.value);
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  BreakStatement visitBreakStatement(BreakStatement node) => new BreakStatement(
+      _mapToken(node.breakKeyword),
+      _cloneNode(node.label),
+      _mapToken(node.semicolon));
+
+  @override
+  CascadeExpression visitCascadeExpression(CascadeExpression node) {
+    CascadeExpression copy = new CascadeExpression(
+        _cloneNode(node.target), _cloneNodeList(node.cascadeSections));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  CatchClause visitCatchClause(CatchClause node) => new CatchClause(
+      _mapToken(node.onKeyword),
+      _cloneNode(node.exceptionType),
+      _mapToken(node.catchKeyword),
+      _mapToken(node.leftParenthesis),
+      _cloneNode(node.exceptionParameter),
+      _mapToken(node.comma),
+      _cloneNode(node.stackTraceParameter),
+      _mapToken(node.rightParenthesis),
+      _cloneNode(node.body));
+
+  @override
+  ClassDeclaration visitClassDeclaration(ClassDeclaration node) {
+    ClassDeclaration copy = new ClassDeclaration(
+        _cloneNode(node.documentationComment),
+        _cloneNodeList(node.metadata),
+        _mapToken(node.abstractKeyword),
+        _mapToken(node.classKeyword),
+        _cloneNode(node.name),
+        _cloneNode(node.typeParameters),
+        _cloneNode(node.extendsClause),
+        _cloneNode(node.withClause),
+        _cloneNode(node.implementsClause),
+        _mapToken(node.leftBracket),
+        _cloneNodeList(node.members),
+        _mapToken(node.rightBracket));
+    copy.nativeClause = _cloneNode(node.nativeClause);
+    return copy;
+  }
+
+  @override
+  ClassTypeAlias visitClassTypeAlias(ClassTypeAlias node) => new ClassTypeAlias(
+      _cloneNode(node.documentationComment),
+      _cloneNodeList(node.metadata),
+      _mapToken(node.typedefKeyword),
+      _cloneNode(node.name),
+      _cloneNode(node.typeParameters),
+      _mapToken(node.equals),
+      _mapToken(node.abstractKeyword),
+      _cloneNode(node.superclass),
+      _cloneNode(node.withClause),
+      _cloneNode(node.implementsClause),
+      _mapToken(node.semicolon));
+
+  @override
+  Comment visitComment(Comment node) {
+    if (node.isDocumentation) {
+      return Comment.createDocumentationCommentWithReferences(
+          _mapTokens(node.tokens), _cloneNodeList(node.references));
+    } else if (node.isBlock) {
+      return Comment.createBlockComment(_mapTokens(node.tokens));
+    }
+    return Comment.createEndOfLineComment(_mapTokens(node.tokens));
+  }
+
+  @override
+  CommentReference visitCommentReference(CommentReference node) =>
+      new CommentReference(
+          _mapToken(node.newKeyword), _cloneNode(node.identifier));
+
+  @override
+  CompilationUnit visitCompilationUnit(CompilationUnit node) {
+    CompilationUnit copy = new CompilationUnit(
+        _mapToken(node.beginToken),
+        _cloneNode(node.scriptTag),
+        _cloneNodeList(node.directives),
+        _cloneNodeList(node.declarations),
+        _mapToken(node.endToken));
+    copy.lineInfo = node.lineInfo;
+    copy.element = node.element;
+    return copy;
+  }
+
+  @override
+  ConditionalExpression visitConditionalExpression(ConditionalExpression node) {
+    ConditionalExpression copy = new ConditionalExpression(
+        _cloneNode(node.condition),
+        _mapToken(node.question),
+        _cloneNode(node.thenExpression),
+        _mapToken(node.colon),
+        _cloneNode(node.elseExpression));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  Configuration visitConfiguration(Configuration node) => new Configuration(
+      _mapToken(node.ifKeyword),
+      _mapToken(node.leftParenthesis),
+      _cloneNode(node.name),
+      _mapToken(node.equalToken),
+      _cloneNode(node.value),
+      _mapToken(node.rightParenthesis),
+      _cloneNode(node.libraryUri));
+
+  @override
+  ConstructorDeclaration visitConstructorDeclaration(
+      ConstructorDeclaration node) {
+    ConstructorDeclaration copy = new ConstructorDeclaration(
+        _cloneNode(node.documentationComment),
+        _cloneNodeList(node.metadata),
+        _mapToken(node.externalKeyword),
+        _mapToken(node.constKeyword),
+        _mapToken(node.factoryKeyword),
+        _cloneNode(node.returnType),
+        _mapToken(node.period),
+        _cloneNode(node.name),
+        _cloneNode(node.parameters),
+        _mapToken(node.separator),
+        _cloneNodeList(node.initializers),
+        _cloneNode(node.redirectedConstructor),
+        _cloneNode(node.body));
+    copy.element = node.element;
+    return copy;
+  }
+
+  @override
+  ConstructorFieldInitializer visitConstructorFieldInitializer(
+          ConstructorFieldInitializer node) =>
+      new ConstructorFieldInitializer(
+          _mapToken(node.thisKeyword),
+          _mapToken(node.period),
+          _cloneNode(node.fieldName),
+          _mapToken(node.equals),
+          _cloneNode(node.expression));
+
+  @override
+  ConstructorName visitConstructorName(ConstructorName node) {
+    ConstructorName copy = new ConstructorName(
+        _cloneNode(node.type), _mapToken(node.period), _cloneNode(node.name));
+    copy.staticElement = node.staticElement;
+    return copy;
+  }
+
+  @override
+  ContinueStatement visitContinueStatement(ContinueStatement node) =>
+      new ContinueStatement(_mapToken(node.continueKeyword),
+          _cloneNode(node.label), _mapToken(node.semicolon));
+
+  @override
+  DeclaredIdentifier visitDeclaredIdentifier(DeclaredIdentifier node) =>
+      new DeclaredIdentifier(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _mapToken(node.keyword),
+          _cloneNode(node.type),
+          _cloneNode(node.identifier));
+
+  @override
+  DefaultFormalParameter visitDefaultFormalParameter(
+          DefaultFormalParameter node) =>
+      new DefaultFormalParameter(_cloneNode(node.parameter), node.kind,
+          _mapToken(node.separator), _cloneNode(node.defaultValue));
+
+  @override
+  DoStatement visitDoStatement(DoStatement node) => new DoStatement(
+      _mapToken(node.doKeyword),
+      _cloneNode(node.body),
+      _mapToken(node.whileKeyword),
+      _mapToken(node.leftParenthesis),
+      _cloneNode(node.condition),
+      _mapToken(node.rightParenthesis),
+      _mapToken(node.semicolon));
+
+  @override
+  DottedName visitDottedName(DottedName node) =>
+      new DottedName(_cloneNodeList(node.components));
+
+  @override
+  DoubleLiteral visitDoubleLiteral(DoubleLiteral node) {
+    DoubleLiteral copy = new DoubleLiteral(_mapToken(node.literal), node.value);
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  EmptyFunctionBody visitEmptyFunctionBody(EmptyFunctionBody node) =>
+      new EmptyFunctionBody(_mapToken(node.semicolon));
+
+  @override
+  EmptyStatement visitEmptyStatement(EmptyStatement node) =>
+      new EmptyStatement(_mapToken(node.semicolon));
+
+  @override
+  AstNode visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
+      new EnumConstantDeclaration(_cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata), _cloneNode(node.name));
+
+  @override
+  AstNode visitEnumDeclaration(EnumDeclaration node) => new EnumDeclaration(
+      _cloneNode(node.documentationComment),
+      _cloneNodeList(node.metadata),
+      _mapToken(node.enumKeyword),
+      _cloneNode(node.name),
+      _mapToken(node.leftBracket),
+      _cloneNodeList(node.constants),
+      _mapToken(node.rightBracket));
+
+  @override
+  ExportDirective visitExportDirective(ExportDirective node) {
+    ExportDirective copy = new ExportDirective(
+        _cloneNode(node.documentationComment),
+        _cloneNodeList(node.metadata),
+        _mapToken(node.keyword),
+        _cloneNode(node.uri),
+        _cloneNodeList(node.configurations),
+        _cloneNodeList(node.combinators),
+        _mapToken(node.semicolon));
+    copy.element = node.element;
+    return copy;
+  }
+
+  @override
+  ExpressionFunctionBody visitExpressionFunctionBody(
+          ExpressionFunctionBody node) =>
+      new ExpressionFunctionBody(
+          _mapToken(node.keyword),
+          _mapToken(node.functionDefinition),
+          _cloneNode(node.expression),
+          _mapToken(node.semicolon));
+
+  @override
+  ExpressionStatement visitExpressionStatement(ExpressionStatement node) =>
+      new ExpressionStatement(
+          _cloneNode(node.expression), _mapToken(node.semicolon));
+
+  @override
+  ExtendsClause visitExtendsClause(ExtendsClause node) => new ExtendsClause(
+      _mapToken(node.extendsKeyword), _cloneNode(node.superclass));
+
+  @override
+  FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
+      new FieldDeclaration(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _mapToken(node.staticKeyword),
+          _cloneNode(node.fields),
+          _mapToken(node.semicolon));
+
+  @override
+  FieldFormalParameter visitFieldFormalParameter(FieldFormalParameter node) =>
+      new FieldFormalParameter(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _mapToken(node.keyword),
+          _cloneNode(node.type),
+          _mapToken(node.thisKeyword),
+          _mapToken(node.period),
+          _cloneNode(node.identifier),
+          _cloneNode(node.typeParameters),
+          _cloneNode(node.parameters));
+
+  @override
+  ForEachStatement visitForEachStatement(ForEachStatement node) {
+    DeclaredIdentifier loopVariable = node.loopVariable;
+    if (loopVariable == null) {
+      return new ForEachStatement.withReference(
+          _mapToken(node.awaitKeyword),
+          _mapToken(node.forKeyword),
+          _mapToken(node.leftParenthesis),
+          _cloneNode(node.identifier),
+          _mapToken(node.inKeyword),
+          _cloneNode(node.iterable),
+          _mapToken(node.rightParenthesis),
+          _cloneNode(node.body));
+    }
+    return new ForEachStatement.withDeclaration(
+        _mapToken(node.awaitKeyword),
+        _mapToken(node.forKeyword),
+        _mapToken(node.leftParenthesis),
+        _cloneNode(loopVariable),
+        _mapToken(node.inKeyword),
+        _cloneNode(node.iterable),
+        _mapToken(node.rightParenthesis),
+        _cloneNode(node.body));
+  }
+
+  @override
+  FormalParameterList visitFormalParameterList(FormalParameterList node) =>
+      new FormalParameterList(
+          _mapToken(node.leftParenthesis),
+          _cloneNodeList(node.parameters),
+          _mapToken(node.leftDelimiter),
+          _mapToken(node.rightDelimiter),
+          _mapToken(node.rightParenthesis));
+
+  @override
+  ForStatement visitForStatement(ForStatement node) => new ForStatement(
+      _mapToken(node.forKeyword),
+      _mapToken(node.leftParenthesis),
+      _cloneNode(node.variables),
+      _cloneNode(node.initialization),
+      _mapToken(node.leftSeparator),
+      _cloneNode(node.condition),
+      _mapToken(node.rightSeparator),
+      _cloneNodeList(node.updaters),
+      _mapToken(node.rightParenthesis),
+      _cloneNode(node.body));
+
+  @override
+  FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) =>
+      new FunctionDeclaration(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _mapToken(node.externalKeyword),
+          _cloneNode(node.returnType),
+          _mapToken(node.propertyKeyword),
+          _cloneNode(node.name),
+          _cloneNode(node.functionExpression));
+
+  @override
+  FunctionDeclarationStatement visitFunctionDeclarationStatement(
+          FunctionDeclarationStatement node) =>
+      new FunctionDeclarationStatement(_cloneNode(node.functionDeclaration));
+
+  @override
+  FunctionExpression visitFunctionExpression(FunctionExpression node) {
+    FunctionExpression copy = new FunctionExpression(
+        _cloneNode(node.typeParameters),
+        _cloneNode(node.parameters),
+        _cloneNode(node.body));
+    copy.element = node.element;
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  FunctionExpressionInvocation visitFunctionExpressionInvocation(
+      FunctionExpressionInvocation node) {
+    FunctionExpressionInvocation copy = new FunctionExpressionInvocation(
+        _cloneNode(node.function),
+        _cloneNode(node.typeArguments),
+        _cloneNode(node.argumentList));
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) =>
+      new FunctionTypeAlias(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _mapToken(node.typedefKeyword),
+          _cloneNode(node.returnType),
+          _cloneNode(node.name),
+          _cloneNode(node.typeParameters),
+          _cloneNode(node.parameters),
+          _mapToken(node.semicolon));
+
+  @override
+  FunctionTypedFormalParameter visitFunctionTypedFormalParameter(
+          FunctionTypedFormalParameter node) =>
+      new FunctionTypedFormalParameter(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _cloneNode(node.returnType),
+          _cloneNode(node.identifier),
+          _cloneNode(node.typeParameters),
+          _cloneNode(node.parameters));
+
+  @override
+  HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
+      _mapToken(node.keyword), _cloneNodeList(node.hiddenNames));
+
+  @override
+  IfStatement visitIfStatement(IfStatement node) => new IfStatement(
+      _mapToken(node.ifKeyword),
+      _mapToken(node.leftParenthesis),
+      _cloneNode(node.condition),
+      _mapToken(node.rightParenthesis),
+      _cloneNode(node.thenStatement),
+      _mapToken(node.elseKeyword),
+      _cloneNode(node.elseStatement));
+
+  @override
+  ImplementsClause visitImplementsClause(ImplementsClause node) =>
+      new ImplementsClause(
+          _mapToken(node.implementsKeyword), _cloneNodeList(node.interfaces));
+
+  @override
+  ImportDirective visitImportDirective(ImportDirective node) =>
+      new ImportDirective(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _mapToken(node.keyword),
+          _cloneNode(node.uri),
+          _cloneNodeList(node.configurations),
+          _mapToken(node.deferredKeyword),
+          _mapToken(node.asKeyword),
+          _cloneNode(node.prefix),
+          _cloneNodeList(node.combinators),
+          _mapToken(node.semicolon));
+
+  @override
+  IndexExpression visitIndexExpression(IndexExpression node) {
+    Token period = _mapToken(node.period);
+    IndexExpression copy;
+    if (period == null) {
+      copy = new IndexExpression.forTarget(
+          _cloneNode(node.target),
+          _mapToken(node.leftBracket),
+          _cloneNode(node.index),
+          _mapToken(node.rightBracket));
+    } else {
+      copy = new IndexExpression.forCascade(period, _mapToken(node.leftBracket),
+          _cloneNode(node.index), _mapToken(node.rightBracket));
+    }
+    copy.auxiliaryElements = node.auxiliaryElements;
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  InstanceCreationExpression visitInstanceCreationExpression(
+      InstanceCreationExpression node) {
+    InstanceCreationExpression copy = new InstanceCreationExpression(
+        _mapToken(node.keyword),
+        _cloneNode(node.constructorName),
+        _cloneNode(node.argumentList));
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  IntegerLiteral visitIntegerLiteral(IntegerLiteral node) {
+    IntegerLiteral copy =
+        new IntegerLiteral(_mapToken(node.literal), node.value);
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  InterpolationExpression visitInterpolationExpression(
+          InterpolationExpression node) =>
+      new InterpolationExpression(_mapToken(node.leftBracket),
+          _cloneNode(node.expression), _mapToken(node.rightBracket));
+
+  @override
+  InterpolationString visitInterpolationString(InterpolationString node) =>
+      new InterpolationString(_mapToken(node.contents), node.value);
+
+  @override
+  IsExpression visitIsExpression(IsExpression node) {
+    IsExpression copy = new IsExpression(
+        _cloneNode(node.expression),
+        _mapToken(node.isOperator),
+        _mapToken(node.notOperator),
+        _cloneNode(node.type));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  Label visitLabel(Label node) =>
+      new Label(_cloneNode(node.label), _mapToken(node.colon));
+
+  @override
+  LabeledStatement visitLabeledStatement(LabeledStatement node) =>
+      new LabeledStatement(
+          _cloneNodeList(node.labels), _cloneNode(node.statement));
+
+  @override
+  LibraryDirective visitLibraryDirective(LibraryDirective node) =>
+      new LibraryDirective(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _mapToken(node.libraryKeyword),
+          _cloneNode(node.name),
+          _mapToken(node.semicolon));
+
+  @override
+  LibraryIdentifier visitLibraryIdentifier(LibraryIdentifier node) {
+    LibraryIdentifier copy =
+        new LibraryIdentifier(_cloneNodeList(node.components));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  ListLiteral visitListLiteral(ListLiteral node) {
+    ListLiteral copy = new ListLiteral(
+        _mapToken(node.constKeyword),
+        _cloneNode(node.typeArguments),
+        _mapToken(node.leftBracket),
+        _cloneNodeList(node.elements),
+        _mapToken(node.rightBracket));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  MapLiteral visitMapLiteral(MapLiteral node) {
+    MapLiteral copy = new MapLiteral(
+        _mapToken(node.constKeyword),
+        _cloneNode(node.typeArguments),
+        _mapToken(node.leftBracket),
+        _cloneNodeList(node.entries),
+        _mapToken(node.rightBracket));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) =>
+      new MapLiteralEntry(_cloneNode(node.key), _mapToken(node.separator),
+          _cloneNode(node.value));
+
+  @override
+  MethodDeclaration visitMethodDeclaration(MethodDeclaration node) =>
+      new MethodDeclaration(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _mapToken(node.externalKeyword),
+          _mapToken(node.modifierKeyword),
+          _cloneNode(node.returnType),
+          _mapToken(node.propertyKeyword),
+          _mapToken(node.operatorKeyword),
+          _cloneNode(node.name),
+          _cloneNode(node.typeParameters),
+          _cloneNode(node.parameters),
+          _cloneNode(node.body));
+
+  @override
+  MethodInvocation visitMethodInvocation(MethodInvocation node) {
+    MethodInvocation copy = new MethodInvocation(
+        _cloneNode(node.target),
+        _mapToken(node.operator),
+        _cloneNode(node.methodName),
+        _cloneNode(node.typeArguments),
+        _cloneNode(node.argumentList));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  NamedExpression visitNamedExpression(NamedExpression node) {
+    NamedExpression copy =
+        new NamedExpression(_cloneNode(node.name), _cloneNode(node.expression));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  AstNode visitNativeClause(NativeClause node) =>
+      new NativeClause(_mapToken(node.nativeKeyword), _cloneNode(node.name));
+
+  @override
+  NativeFunctionBody visitNativeFunctionBody(NativeFunctionBody node) =>
+      new NativeFunctionBody(_mapToken(node.nativeKeyword),
+          _cloneNode(node.stringLiteral), _mapToken(node.semicolon));
+
+  @override
+  NullLiteral visitNullLiteral(NullLiteral node) {
+    NullLiteral copy = new NullLiteral(_mapToken(node.literal));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  ParenthesizedExpression visitParenthesizedExpression(
+      ParenthesizedExpression node) {
+    ParenthesizedExpression copy = new ParenthesizedExpression(
+        _mapToken(node.leftParenthesis),
+        _cloneNode(node.expression),
+        _mapToken(node.rightParenthesis));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  PartDirective visitPartDirective(PartDirective node) {
+    PartDirective copy = new PartDirective(
+        _cloneNode(node.documentationComment),
+        _cloneNodeList(node.metadata),
+        _mapToken(node.partKeyword),
+        _cloneNode(node.uri),
+        _mapToken(node.semicolon));
+    copy.element = node.element;
+    return copy;
+  }
+
+  @override
+  PartOfDirective visitPartOfDirective(PartOfDirective node) {
+    PartOfDirective copy = new PartOfDirective(
+        _cloneNode(node.documentationComment),
+        _cloneNodeList(node.metadata),
+        _mapToken(node.partKeyword),
+        _mapToken(node.ofKeyword),
+        _cloneNode(node.libraryName),
+        _mapToken(node.semicolon));
+    copy.element = node.element;
+    return copy;
+  }
+
+  @override
+  PostfixExpression visitPostfixExpression(PostfixExpression node) {
+    PostfixExpression copy = new PostfixExpression(
+        _cloneNode(node.operand), _mapToken(node.operator));
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) {
+    PrefixedIdentifier copy = new PrefixedIdentifier(_cloneNode(node.prefix),
+        _mapToken(node.period), _cloneNode(node.identifier));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  PrefixExpression visitPrefixExpression(PrefixExpression node) {
+    PrefixExpression copy = new PrefixExpression(
+        _mapToken(node.operator), _cloneNode(node.operand));
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  PropertyAccess visitPropertyAccess(PropertyAccess node) {
+    PropertyAccess copy = new PropertyAccess(_cloneNode(node.target),
+        _mapToken(node.operator), _cloneNode(node.propertyName));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    RedirectingConstructorInvocation copy =
+        new RedirectingConstructorInvocation(
+            _mapToken(node.thisKeyword),
+            _mapToken(node.period),
+            _cloneNode(node.constructorName),
+            _cloneNode(node.argumentList));
+    copy.staticElement = node.staticElement;
+    return copy;
+  }
+
+  @override
+  RethrowExpression visitRethrowExpression(RethrowExpression node) {
+    RethrowExpression copy =
+        new RethrowExpression(_mapToken(node.rethrowKeyword));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  ReturnStatement visitReturnStatement(ReturnStatement node) =>
+      new ReturnStatement(_mapToken(node.returnKeyword),
+          _cloneNode(node.expression), _mapToken(node.semicolon));
+
+  @override
+  ScriptTag visitScriptTag(ScriptTag node) =>
+      new ScriptTag(_mapToken(node.scriptTag));
+
+  @override
+  ShowCombinator visitShowCombinator(ShowCombinator node) => new ShowCombinator(
+      _mapToken(node.keyword), _cloneNodeList(node.shownNames));
+
+  @override
+  SimpleFormalParameter visitSimpleFormalParameter(
+          SimpleFormalParameter node) =>
+      new SimpleFormalParameter(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _mapToken(node.keyword),
+          _cloneNode(node.type),
+          _cloneNode(node.identifier));
+
+  @override
+  SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
+    Token mappedToken = _mapToken(node.token);
+    if (mappedToken == null) {
+      // This only happens for SimpleIdentifiers created by the parser as part
+      // of scanning documentation comments (the tokens for those identifiers
+      // are not in the original token stream and hence do not get copied).
+      // This extra check can be removed if the scanner is changed to scan
+      // documentation comments for the parser.
+      mappedToken = node.token;
+    }
+    SimpleIdentifier copy = new SimpleIdentifier(mappedToken);
+    copy.auxiliaryElements = node.auxiliaryElements;
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  SimpleStringLiteral visitSimpleStringLiteral(SimpleStringLiteral node) {
+    SimpleStringLiteral copy =
+        new SimpleStringLiteral(_mapToken(node.literal), node.value);
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  StringInterpolation visitStringInterpolation(StringInterpolation node) {
+    StringInterpolation copy =
+        new StringInterpolation(_cloneNodeList(node.elements));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  SuperConstructorInvocation visitSuperConstructorInvocation(
+      SuperConstructorInvocation node) {
+    SuperConstructorInvocation copy = new SuperConstructorInvocation(
+        _mapToken(node.superKeyword),
+        _mapToken(node.period),
+        _cloneNode(node.constructorName),
+        _cloneNode(node.argumentList));
+    copy.staticElement = node.staticElement;
+    return copy;
+  }
+
+  @override
+  SuperExpression visitSuperExpression(SuperExpression node) {
+    SuperExpression copy = new SuperExpression(_mapToken(node.superKeyword));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  SwitchCase visitSwitchCase(SwitchCase node) => new SwitchCase(
+      _cloneNodeList(node.labels),
+      _mapToken(node.keyword),
+      _cloneNode(node.expression),
+      _mapToken(node.colon),
+      _cloneNodeList(node.statements));
+
+  @override
+  SwitchDefault visitSwitchDefault(SwitchDefault node) => new SwitchDefault(
+      _cloneNodeList(node.labels),
+      _mapToken(node.keyword),
+      _mapToken(node.colon),
+      _cloneNodeList(node.statements));
+
+  @override
+  SwitchStatement visitSwitchStatement(SwitchStatement node) =>
+      new SwitchStatement(
+          _mapToken(node.switchKeyword),
+          _mapToken(node.leftParenthesis),
+          _cloneNode(node.expression),
+          _mapToken(node.rightParenthesis),
+          _mapToken(node.leftBracket),
+          _cloneNodeList(node.members),
+          _mapToken(node.rightBracket));
+
+  @override
+  AstNode visitSymbolLiteral(SymbolLiteral node) {
+    SymbolLiteral copy = new SymbolLiteral(
+        _mapToken(node.poundSign), _mapTokens(node.components));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  ThisExpression visitThisExpression(ThisExpression node) {
+    ThisExpression copy = new ThisExpression(_mapToken(node.thisKeyword));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  ThrowExpression visitThrowExpression(ThrowExpression node) {
+    ThrowExpression copy = new ThrowExpression(
+        _mapToken(node.throwKeyword), _cloneNode(node.expression));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  TopLevelVariableDeclaration visitTopLevelVariableDeclaration(
+          TopLevelVariableDeclaration node) =>
+      new TopLevelVariableDeclaration(
+          _cloneNode(node.documentationComment),
+          _cloneNodeList(node.metadata),
+          _cloneNode(node.variables),
+          _mapToken(node.semicolon));
+
+  @override
+  TryStatement visitTryStatement(TryStatement node) => new TryStatement(
+      _mapToken(node.tryKeyword),
+      _cloneNode(node.body),
+      _cloneNodeList(node.catchClauses),
+      _mapToken(node.finallyKeyword),
+      _cloneNode(node.finallyBlock));
+
+  @override
+  TypeArgumentList visitTypeArgumentList(TypeArgumentList node) =>
+      new TypeArgumentList(_mapToken(node.leftBracket),
+          _cloneNodeList(node.arguments), _mapToken(node.rightBracket));
+
+  @override
+  TypeName visitTypeName(TypeName node) {
+    TypeName copy =
+        new TypeName(_cloneNode(node.name), _cloneNode(node.typeArguments));
+    copy.type = node.type;
+    return copy;
+  }
+
+  @override
+  TypeParameter visitTypeParameter(TypeParameter node) => new TypeParameter(
+      _cloneNode(node.documentationComment),
+      _cloneNodeList(node.metadata),
+      _cloneNode(node.name),
+      _mapToken(node.extendsKeyword),
+      _cloneNode(node.bound));
+
+  @override
+  TypeParameterList visitTypeParameterList(TypeParameterList node) =>
+      new TypeParameterList(_mapToken(node.leftBracket),
+          _cloneNodeList(node.typeParameters), _mapToken(node.rightBracket));
+
+  @override
+  VariableDeclaration visitVariableDeclaration(VariableDeclaration node) =>
+      new VariableDeclaration(_cloneNode(node.name), _mapToken(node.equals),
+          _cloneNode(node.initializer));
+
+  @override
+  VariableDeclarationList visitVariableDeclarationList(
+          VariableDeclarationList node) =>
+      new VariableDeclarationList(
+          null,
+          _cloneNodeList(node.metadata),
+          _mapToken(node.keyword),
+          _cloneNode(node.type),
+          _cloneNodeList(node.variables));
+
+  @override
+  VariableDeclarationStatement visitVariableDeclarationStatement(
+          VariableDeclarationStatement node) =>
+      new VariableDeclarationStatement(
+          _cloneNode(node.variables), _mapToken(node.semicolon));
+
+  @override
+  WhileStatement visitWhileStatement(WhileStatement node) => new WhileStatement(
+      _mapToken(node.whileKeyword),
+      _mapToken(node.leftParenthesis),
+      _cloneNode(node.condition),
+      _mapToken(node.rightParenthesis),
+      _cloneNode(node.body));
+
+  @override
+  WithClause visitWithClause(WithClause node) => new WithClause(
+      _mapToken(node.withKeyword), _cloneNodeList(node.mixinTypes));
+
+  @override
+  YieldStatement visitYieldStatement(YieldStatement node) => new YieldStatement(
+      _mapToken(node.yieldKeyword),
+      _mapToken(node.star),
+      _cloneNode(node.expression),
+      _mapToken(node.semicolon));
+
+  AstNode _cloneNode(AstNode node) {
+    if (node == null) {
+      return null;
+    }
+    if (identical(node, _oldNode)) {
+      return _newNode;
+    }
+    return node.accept(this) as AstNode;
+  }
+
+  List _cloneNodeList(NodeList nodes) {
+    List clonedNodes = new List();
+    for (AstNode node in nodes) {
+      clonedNodes.add(_cloneNode(node));
+    }
+    return clonedNodes;
+  }
+
+  Token _mapToken(Token oldToken) {
+    if (oldToken == null) {
+      return null;
+    }
+    return _tokenMap.get(oldToken);
+  }
+
+  List<Token> _mapTokens(List<Token> oldTokens) {
+    List<Token> newTokens = new List<Token>(oldTokens.length);
+    for (int index = 0; index < newTokens.length; index++) {
+      newTokens[index] = _mapToken(oldTokens[index]);
+    }
+    return newTokens;
+  }
+}
+
+/**
+ * An object used to locate the [AstNode] associated with a source range, given
+ * the AST structure built from the source. More specifically, they will return
+ * the [AstNode] with the shortest length whose source range completely
+ * encompasses the specified range.
+ */
+class NodeLocator extends UnifyingAstVisitor<Object> {
+  /**
+   * The start offset of the range used to identify the node.
+   */
+  int _startOffset = 0;
+
+  /**
+   * The end offset of the range used to identify the node.
+   */
+  int _endOffset = 0;
+
+  /**
+   * The element that was found that corresponds to the given source range, or
+   * `null` if there is no such element.
+   */
+  AstNode _foundNode;
+
+  /**
+   * Initialize a newly created locator to locate an [AstNode] by locating the
+   * node within an AST structure that corresponds to the given range of
+   * characters (between the [startOffset] and [endOffset] in the source.
+   */
+  NodeLocator(int startOffset, [int endOffset])
+      : this._startOffset = startOffset,
+        this._endOffset = endOffset == null ? startOffset : endOffset;
+
+  /**
+   * Return the node that was found that corresponds to the given source range
+   * or `null` if there is no such node.
+   */
+  AstNode get foundNode => _foundNode;
+
+  /**
+   * Search within the given AST [node] for an identifier representing an
+   * element in the specified source range. Return the element that was found,
+   * or `null` if no element was found.
+   */
+  AstNode searchWithin(AstNode node) {
+    if (node == null) {
+      return null;
+    }
+    try {
+      node.accept(this);
+    } on NodeLocator_NodeFoundException {
+      // A node with the right source position was found.
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Unable to locate element at offset ($_startOffset - $_endOffset)",
+          new CaughtException(exception, stackTrace));
+      return null;
+    }
+    return _foundNode;
+  }
+
+  @override
+  Object visitNode(AstNode node) {
+    Token beginToken = node.beginToken;
+    Token endToken = node.endToken;
+    // Don't include synthetic tokens.
+    while (endToken != beginToken) {
+      if (endToken.type == TokenType.EOF || !endToken.isSynthetic) {
+        break;
+      }
+      endToken = endToken.previous;
+    }
+    int end = endToken.end;
+    int start = node.offset;
+    if (end < _startOffset) {
+      return null;
+    }
+    if (start > _endOffset) {
+      return null;
+    }
+    try {
+      node.visitChildren(this);
+    } on NodeLocator_NodeFoundException {
+      rethrow;
+    } catch (exception, stackTrace) {
+      // Ignore the exception and proceed in order to visit the rest of the
+      // structure.
+      AnalysisEngine.instance.logger.logInformation(
+          "Exception caught while traversing an AST structure.",
+          new CaughtException(exception, stackTrace));
+    }
+    if (start <= _startOffset && _endOffset <= end) {
+      _foundNode = node;
+      throw new NodeLocator_NodeFoundException();
+    }
+    return null;
+  }
+}
+
+/**
+ * An object used to locate the [AstNode] associated with a source range.
+ * More specifically, they will return the deepest [AstNode] which completely
+ * encompasses the specified range.
+ */
+class NodeLocator2 extends UnifyingAstVisitor<Object> {
+  /**
+   * The inclusive start offset of the range used to identify the node.
+   */
+  int _startOffset = 0;
+
+  /**
+   * The inclusive end offset of the range used to identify the node.
+   */
+  int _endOffset = 0;
+
+  /**
+   * The found node or `null` if there is no such node.
+   */
+  AstNode _foundNode;
+
+  /**
+   * Initialize a newly created locator to locate the deepest [AstNode] for
+   * which `node.offset <= [startOffset]` and `[endOffset] < node.end`.
+   *
+   * If [endOffset] is not provided, then it is considered the same as the
+   * given [startOffset].
+   */
+  NodeLocator2(int startOffset, [int endOffset])
+      : this._startOffset = startOffset,
+        this._endOffset = endOffset == null ? startOffset : endOffset;
+
+  /**
+   * Search within the given AST [node] and return the node that was found,
+   * or `null` if no node was found.
+   */
+  AstNode searchWithin(AstNode node) {
+    if (node == null) {
+      return null;
+    }
+    try {
+      node.accept(this);
+    } on NodeLocator_NodeFoundException {} catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Unable to locate element at offset ($_startOffset - $_endOffset)",
+          new CaughtException(exception, stackTrace));
+      return null;
+    }
+    return _foundNode;
+  }
+
+  @override
+  Object visitNode(AstNode node) {
+    Token beginToken = node.beginToken;
+    Token endToken = node.endToken;
+    // Don't include synthetic tokens.
+    while (endToken != beginToken) {
+      if (endToken.type == TokenType.EOF || !endToken.isSynthetic) {
+        break;
+      }
+      endToken = endToken.previous;
+    }
+    int end = endToken.end;
+    int start = node.offset;
+    if (end <= _startOffset) {
+      return null;
+    }
+    if (start > _endOffset) {
+      return null;
+    }
+    try {
+      node.visitChildren(this);
+    } on NodeLocator_NodeFoundException {
+      rethrow;
+    } catch (exception, stackTrace) {
+      // Ignore the exception and proceed in order to visit the rest of the
+      // structure.
+      AnalysisEngine.instance.logger.logInformation(
+          "Exception caught while traversing an AST structure.",
+          new CaughtException(exception, stackTrace));
+    }
+    if (start <= _startOffset && _endOffset < end) {
+      _foundNode = node;
+      throw new NodeLocator_NodeFoundException();
+    }
+    return null;
+  }
+}
+
+/**
+ * An exception used by [NodeLocator] to cancel visiting after a node has been
+ * found.
+ */
+class NodeLocator_NodeFoundException extends RuntimeException {}
+
+/**
+ * An object that will replace one child node in an AST node with another node.
+ */
+class NodeReplacer implements AstVisitor<bool> {
+  /**
+   * The node being replaced.
+   */
+  final AstNode _oldNode;
+
+  /**
+   * The node that is replacing the old node.
+   */
+  final AstNode _newNode;
+
+  /**
+   * Initialize a newly created node locator to replace the [_oldNode] with the
+   * [_newNode].
+   */
+  NodeReplacer(this._oldNode, this._newNode);
+
+  @override
+  bool visitAdjacentStrings(AdjacentStrings node) {
+    if (_replaceInList(node.strings)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  bool visitAnnotatedNode(AnnotatedNode node) {
+    if (identical(node.documentationComment, _oldNode)) {
+      node.documentationComment = _newNode as Comment;
+      return true;
+    } else if (_replaceInList(node.metadata)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitAnnotation(Annotation node) {
+    if (identical(node.arguments, _oldNode)) {
+      node.arguments = _newNode as ArgumentList;
+      return true;
+    } else if (identical(node.constructorName, _oldNode)) {
+      node.constructorName = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.name, _oldNode)) {
+      node.name = _newNode as Identifier;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitArgumentList(ArgumentList node) {
+    if (_replaceInList(node.arguments)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitAsExpression(AsExpression node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    } else if (identical(node.type, _oldNode)) {
+      node.type = _newNode as TypeName;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitAssertStatement(AssertStatement node) {
+    if (identical(node.condition, _oldNode)) {
+      node.condition = _newNode as Expression;
+      return true;
+    }
+    if (identical(node.message, _oldNode)) {
+      node.message = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitAssignmentExpression(AssignmentExpression node) {
+    if (identical(node.leftHandSide, _oldNode)) {
+      node.leftHandSide = _newNode as Expression;
+      return true;
+    } else if (identical(node.rightHandSide, _oldNode)) {
+      node.rightHandSide = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitAwaitExpression(AwaitExpression node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitBinaryExpression(BinaryExpression node) {
+    if (identical(node.leftOperand, _oldNode)) {
+      node.leftOperand = _newNode as Expression;
+      return true;
+    } else if (identical(node.rightOperand, _oldNode)) {
+      node.rightOperand = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitBlock(Block node) {
+    if (_replaceInList(node.statements)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitBlockFunctionBody(BlockFunctionBody node) {
+    if (identical(node.block, _oldNode)) {
+      node.block = _newNode as Block;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitBooleanLiteral(BooleanLiteral node) => visitNode(node);
+
+  @override
+  bool visitBreakStatement(BreakStatement node) {
+    if (identical(node.label, _oldNode)) {
+      node.label = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitCascadeExpression(CascadeExpression node) {
+    if (identical(node.target, _oldNode)) {
+      node.target = _newNode as Expression;
+      return true;
+    } else if (_replaceInList(node.cascadeSections)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitCatchClause(CatchClause node) {
+    if (identical(node.exceptionType, _oldNode)) {
+      node.exceptionType = _newNode as TypeName;
+      return true;
+    } else if (identical(node.exceptionParameter, _oldNode)) {
+      node.exceptionParameter = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.stackTraceParameter, _oldNode)) {
+      node.stackTraceParameter = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitClassDeclaration(ClassDeclaration node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.typeParameters, _oldNode)) {
+      node.typeParameters = _newNode as TypeParameterList;
+      return true;
+    } else if (identical(node.extendsClause, _oldNode)) {
+      node.extendsClause = _newNode as ExtendsClause;
+      return true;
+    } else if (identical(node.withClause, _oldNode)) {
+      node.withClause = _newNode as WithClause;
+      return true;
+    } else if (identical(node.implementsClause, _oldNode)) {
+      node.implementsClause = _newNode as ImplementsClause;
+      return true;
+    } else if (identical(node.nativeClause, _oldNode)) {
+      node.nativeClause = _newNode as NativeClause;
+      return true;
+    } else if (_replaceInList(node.members)) {
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitClassTypeAlias(ClassTypeAlias node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.typeParameters, _oldNode)) {
+      node.typeParameters = _newNode as TypeParameterList;
+      return true;
+    } else if (identical(node.superclass, _oldNode)) {
+      node.superclass = _newNode as TypeName;
+      return true;
+    } else if (identical(node.withClause, _oldNode)) {
+      node.withClause = _newNode as WithClause;
+      return true;
+    } else if (identical(node.implementsClause, _oldNode)) {
+      node.implementsClause = _newNode as ImplementsClause;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitComment(Comment node) {
+    if (_replaceInList(node.references)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitCommentReference(CommentReference node) {
+    if (identical(node.identifier, _oldNode)) {
+      node.identifier = _newNode as Identifier;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitCompilationUnit(CompilationUnit node) {
+    if (identical(node.scriptTag, _oldNode)) {
+      node.scriptTag = _newNode as ScriptTag;
+      return true;
+    } else if (_replaceInList(node.directives)) {
+      return true;
+    } else if (_replaceInList(node.declarations)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitConditionalExpression(ConditionalExpression node) {
+    if (identical(node.condition, _oldNode)) {
+      node.condition = _newNode as Expression;
+      return true;
+    } else if (identical(node.thenExpression, _oldNode)) {
+      node.thenExpression = _newNode as Expression;
+      return true;
+    } else if (identical(node.elseExpression, _oldNode)) {
+      node.elseExpression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitConfiguration(Configuration node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as DottedName;
+      return true;
+    } else if (identical(node.value, _oldNode)) {
+      node.value = _newNode as StringLiteral;
+      return true;
+    } else if (identical(node.libraryUri, _oldNode)) {
+      node.libraryUri = _newNode as StringLiteral;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitConstructorDeclaration(ConstructorDeclaration node) {
+    if (identical(node.returnType, _oldNode)) {
+      node.returnType = _newNode as Identifier;
+      return true;
+    } else if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.parameters, _oldNode)) {
+      node.parameters = _newNode as FormalParameterList;
+      return true;
+    } else if (identical(node.redirectedConstructor, _oldNode)) {
+      node.redirectedConstructor = _newNode as ConstructorName;
+      return true;
+    } else if (identical(node.body, _oldNode)) {
+      node.body = _newNode as FunctionBody;
+      return true;
+    } else if (_replaceInList(node.initializers)) {
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    if (identical(node.fieldName, _oldNode)) {
+      node.fieldName = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitConstructorName(ConstructorName node) {
+    if (identical(node.type, _oldNode)) {
+      node.type = _newNode as TypeName;
+      return true;
+    } else if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitContinueStatement(ContinueStatement node) {
+    if (identical(node.label, _oldNode)) {
+      node.label = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitDeclaredIdentifier(DeclaredIdentifier node) {
+    if (identical(node.type, _oldNode)) {
+      node.type = _newNode as TypeName;
+      return true;
+    } else if (identical(node.identifier, _oldNode)) {
+      node.identifier = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitDefaultFormalParameter(DefaultFormalParameter node) {
+    if (identical(node.parameter, _oldNode)) {
+      node.parameter = _newNode as NormalFormalParameter;
+      return true;
+    } else if (identical(node.defaultValue, _oldNode)) {
+      node.defaultValue = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitDoStatement(DoStatement node) {
+    if (identical(node.body, _oldNode)) {
+      node.body = _newNode as Statement;
+      return true;
+    } else if (identical(node.condition, _oldNode)) {
+      node.condition = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitDottedName(DottedName node) {
+    if (_replaceInList(node.components)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitDoubleLiteral(DoubleLiteral node) => visitNode(node);
+
+  @override
+  bool visitEmptyFunctionBody(EmptyFunctionBody node) => visitNode(node);
+
+  @override
+  bool visitEmptyStatement(EmptyStatement node) => visitNode(node);
+
+  @override
+  bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitEnumDeclaration(EnumDeclaration node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    } else if (_replaceInList(node.constants)) {
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitExportDirective(ExportDirective node) =>
+      visitNamespaceDirective(node);
+
+  @override
+  bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitExpressionStatement(ExpressionStatement node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitExtendsClause(ExtendsClause node) {
+    if (identical(node.superclass, _oldNode)) {
+      node.superclass = _newNode as TypeName;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitFieldDeclaration(FieldDeclaration node) {
+    if (identical(node.fields, _oldNode)) {
+      node.fields = _newNode as VariableDeclarationList;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitFieldFormalParameter(FieldFormalParameter node) {
+    if (identical(node.type, _oldNode)) {
+      node.type = _newNode as TypeName;
+      return true;
+    } else if (identical(node.parameters, _oldNode)) {
+      node.parameters = _newNode as FormalParameterList;
+      return true;
+    }
+    return visitNormalFormalParameter(node);
+  }
+
+  @override
+  bool visitForEachStatement(ForEachStatement node) {
+    if (identical(node.loopVariable, _oldNode)) {
+      node.loopVariable = _newNode as DeclaredIdentifier;
+      return true;
+    } else if (identical(node.identifier, _oldNode)) {
+      node.identifier = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.iterable, _oldNode)) {
+      node.iterable = _newNode as Expression;
+      return true;
+    } else if (identical(node.body, _oldNode)) {
+      node.body = _newNode as Statement;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitFormalParameterList(FormalParameterList node) {
+    if (_replaceInList(node.parameters)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitForStatement(ForStatement node) {
+    if (identical(node.variables, _oldNode)) {
+      node.variables = _newNode as VariableDeclarationList;
+      return true;
+    } else if (identical(node.initialization, _oldNode)) {
+      node.initialization = _newNode as Expression;
+      return true;
+    } else if (identical(node.condition, _oldNode)) {
+      node.condition = _newNode as Expression;
+      return true;
+    } else if (identical(node.body, _oldNode)) {
+      node.body = _newNode as Statement;
+      return true;
+    } else if (_replaceInList(node.updaters)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitFunctionDeclaration(FunctionDeclaration node) {
+    if (identical(node.returnType, _oldNode)) {
+      node.returnType = _newNode as TypeName;
+      return true;
+    } else if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.functionExpression, _oldNode)) {
+      node.functionExpression = _newNode as FunctionExpression;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    if (identical(node.functionDeclaration, _oldNode)) {
+      node.functionDeclaration = _newNode as FunctionDeclaration;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitFunctionExpression(FunctionExpression node) {
+    if (identical(node.parameters, _oldNode)) {
+      node.parameters = _newNode as FormalParameterList;
+      return true;
+    } else if (identical(node.body, _oldNode)) {
+      node.body = _newNode as FunctionBody;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    if (identical(node.function, _oldNode)) {
+      node.function = _newNode as Expression;
+      return true;
+    } else if (identical(node.argumentList, _oldNode)) {
+      node.argumentList = _newNode as ArgumentList;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitFunctionTypeAlias(FunctionTypeAlias node) {
+    if (identical(node.returnType, _oldNode)) {
+      node.returnType = _newNode as TypeName;
+      return true;
+    } else if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.typeParameters, _oldNode)) {
+      node.typeParameters = _newNode as TypeParameterList;
+      return true;
+    } else if (identical(node.parameters, _oldNode)) {
+      node.parameters = _newNode as FormalParameterList;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    if (identical(node.returnType, _oldNode)) {
+      node.returnType = _newNode as TypeName;
+      return true;
+    } else if (identical(node.parameters, _oldNode)) {
+      node.parameters = _newNode as FormalParameterList;
+      return true;
+    }
+    return visitNormalFormalParameter(node);
+  }
+
+  @override
+  bool visitHideCombinator(HideCombinator node) {
+    if (_replaceInList(node.hiddenNames)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitIfStatement(IfStatement node) {
+    if (identical(node.condition, _oldNode)) {
+      node.condition = _newNode as Expression;
+      return true;
+    } else if (identical(node.thenStatement, _oldNode)) {
+      node.thenStatement = _newNode as Statement;
+      return true;
+    } else if (identical(node.elseStatement, _oldNode)) {
+      node.elseStatement = _newNode as Statement;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitImplementsClause(ImplementsClause node) {
+    if (_replaceInList(node.interfaces)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitImportDirective(ImportDirective node) {
+    if (identical(node.prefix, _oldNode)) {
+      node.prefix = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitNamespaceDirective(node);
+  }
+
+  @override
+  bool visitIndexExpression(IndexExpression node) {
+    if (identical(node.target, _oldNode)) {
+      node.target = _newNode as Expression;
+      return true;
+    } else if (identical(node.index, _oldNode)) {
+      node.index = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitInstanceCreationExpression(InstanceCreationExpression node) {
+    if (identical(node.constructorName, _oldNode)) {
+      node.constructorName = _newNode as ConstructorName;
+      return true;
+    } else if (identical(node.argumentList, _oldNode)) {
+      node.argumentList = _newNode as ArgumentList;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitIntegerLiteral(IntegerLiteral node) => visitNode(node);
+
+  @override
+  bool visitInterpolationExpression(InterpolationExpression node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitInterpolationString(InterpolationString node) => visitNode(node);
+
+  @override
+  bool visitIsExpression(IsExpression node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    } else if (identical(node.type, _oldNode)) {
+      node.type = _newNode as TypeName;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitLabel(Label node) {
+    if (identical(node.label, _oldNode)) {
+      node.label = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitLabeledStatement(LabeledStatement node) {
+    if (identical(node.statement, _oldNode)) {
+      node.statement = _newNode as Statement;
+      return true;
+    } else if (_replaceInList(node.labels)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitLibraryDirective(LibraryDirective node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as LibraryIdentifier;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitLibraryIdentifier(LibraryIdentifier node) {
+    if (_replaceInList(node.components)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitListLiteral(ListLiteral node) {
+    if (_replaceInList(node.elements)) {
+      return true;
+    }
+    return visitTypedLiteral(node);
+  }
+
+  @override
+  bool visitMapLiteral(MapLiteral node) {
+    if (_replaceInList(node.entries)) {
+      return true;
+    }
+    return visitTypedLiteral(node);
+  }
+
+  @override
+  bool visitMapLiteralEntry(MapLiteralEntry node) {
+    if (identical(node.key, _oldNode)) {
+      node.key = _newNode as Expression;
+      return true;
+    } else if (identical(node.value, _oldNode)) {
+      node.value = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitMethodDeclaration(MethodDeclaration node) {
+    if (identical(node.returnType, _oldNode)) {
+      node.returnType = _newNode as TypeName;
+      return true;
+    } else if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.parameters, _oldNode)) {
+      node.parameters = _newNode as FormalParameterList;
+      return true;
+    } else if (identical(node.body, _oldNode)) {
+      node.body = _newNode as FunctionBody;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitMethodInvocation(MethodInvocation node) {
+    if (identical(node.target, _oldNode)) {
+      node.target = _newNode as Expression;
+      return true;
+    } else if (identical(node.methodName, _oldNode)) {
+      node.methodName = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.argumentList, _oldNode)) {
+      node.argumentList = _newNode as ArgumentList;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitNamedExpression(NamedExpression node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as Label;
+      return true;
+    } else if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  bool visitNamespaceDirective(NamespaceDirective node) {
+    if (_replaceInList(node.combinators)) {
+      return true;
+    }
+    return visitUriBasedDirective(node);
+  }
+
+  @override
+  bool visitNativeClause(NativeClause node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as StringLiteral;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitNativeFunctionBody(NativeFunctionBody node) {
+    if (identical(node.stringLiteral, _oldNode)) {
+      node.stringLiteral = _newNode as StringLiteral;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  bool visitNode(AstNode node) {
+    throw new IllegalArgumentException(
+        "The old node is not a child of it's parent");
+  }
+
+  bool visitNormalFormalParameter(NormalFormalParameter node) {
+    if (identical(node.documentationComment, _oldNode)) {
+      node.documentationComment = _newNode as Comment;
+      return true;
+    } else if (identical(node.identifier, _oldNode)) {
+      node.identifier = _newNode as SimpleIdentifier;
+      return true;
+    } else if (_replaceInList(node.metadata)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitNullLiteral(NullLiteral node) => visitNode(node);
+
+  @override
+  bool visitParenthesizedExpression(ParenthesizedExpression node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitPartDirective(PartDirective node) => visitUriBasedDirective(node);
+
+  @override
+  bool visitPartOfDirective(PartOfDirective node) {
+    if (identical(node.libraryName, _oldNode)) {
+      node.libraryName = _newNode as LibraryIdentifier;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitPostfixExpression(PostfixExpression node) {
+    if (identical(node.operand, _oldNode)) {
+      node.operand = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitPrefixedIdentifier(PrefixedIdentifier node) {
+    if (identical(node.prefix, _oldNode)) {
+      node.prefix = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.identifier, _oldNode)) {
+      node.identifier = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitPrefixExpression(PrefixExpression node) {
+    if (identical(node.operand, _oldNode)) {
+      node.operand = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitPropertyAccess(PropertyAccess node) {
+    if (identical(node.target, _oldNode)) {
+      node.target = _newNode as Expression;
+      return true;
+    } else if (identical(node.propertyName, _oldNode)) {
+      node.propertyName = _newNode as SimpleIdentifier;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    if (identical(node.constructorName, _oldNode)) {
+      node.constructorName = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.argumentList, _oldNode)) {
+      node.argumentList = _newNode as ArgumentList;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitRethrowExpression(RethrowExpression node) => visitNode(node);
+
+  @override
+  bool visitReturnStatement(ReturnStatement node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
+
+  @override
+  bool visitShowCombinator(ShowCombinator node) {
+    if (_replaceInList(node.shownNames)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitSimpleFormalParameter(SimpleFormalParameter node) {
+    if (identical(node.type, _oldNode)) {
+      node.type = _newNode as TypeName;
+      return true;
+    }
+    return visitNormalFormalParameter(node);
+  }
+
+  @override
+  bool visitSimpleIdentifier(SimpleIdentifier node) => visitNode(node);
+
+  @override
+  bool visitSimpleStringLiteral(SimpleStringLiteral node) => visitNode(node);
+
+  @override
+  bool visitStringInterpolation(StringInterpolation node) {
+    if (_replaceInList(node.elements)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    if (identical(node.constructorName, _oldNode)) {
+      node.constructorName = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.argumentList, _oldNode)) {
+      node.argumentList = _newNode as ArgumentList;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitSuperExpression(SuperExpression node) => visitNode(node);
+
+  @override
+  bool visitSwitchCase(SwitchCase node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitSwitchMember(node);
+  }
+
+  @override
+  bool visitSwitchDefault(SwitchDefault node) => visitSwitchMember(node);
+
+  bool visitSwitchMember(SwitchMember node) {
+    if (_replaceInList(node.labels)) {
+      return true;
+    } else if (_replaceInList(node.statements)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitSwitchStatement(SwitchStatement node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    } else if (_replaceInList(node.members)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitSymbolLiteral(SymbolLiteral node) => visitNode(node);
+
+  @override
+  bool visitThisExpression(ThisExpression node) => visitNode(node);
+
+  @override
+  bool visitThrowExpression(ThrowExpression node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    if (identical(node.variables, _oldNode)) {
+      node.variables = _newNode as VariableDeclarationList;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitTryStatement(TryStatement node) {
+    if (identical(node.body, _oldNode)) {
+      node.body = _newNode as Block;
+      return true;
+    } else if (identical(node.finallyBlock, _oldNode)) {
+      node.finallyBlock = _newNode as Block;
+      return true;
+    } else if (_replaceInList(node.catchClauses)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitTypeArgumentList(TypeArgumentList node) {
+    if (_replaceInList(node.arguments)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  bool visitTypedLiteral(TypedLiteral node) {
+    if (identical(node.typeArguments, _oldNode)) {
+      node.typeArguments = _newNode as TypeArgumentList;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitTypeName(TypeName node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as Identifier;
+      return true;
+    } else if (identical(node.typeArguments, _oldNode)) {
+      node.typeArguments = _newNode as TypeArgumentList;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitTypeParameter(TypeParameter node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.bound, _oldNode)) {
+      node.bound = _newNode as TypeName;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitTypeParameterList(TypeParameterList node) {
+    if (_replaceInList(node.typeParameters)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  bool visitUriBasedDirective(UriBasedDirective node) {
+    if (identical(node.uri, _oldNode)) {
+      node.uri = _newNode as StringLiteral;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitVariableDeclaration(VariableDeclaration node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.initializer, _oldNode)) {
+      node.initializer = _newNode as Expression;
+      return true;
+    }
+    return visitAnnotatedNode(node);
+  }
+
+  @override
+  bool visitVariableDeclarationList(VariableDeclarationList node) {
+    if (identical(node.type, _oldNode)) {
+      node.type = _newNode as TypeName;
+      return true;
+    } else if (_replaceInList(node.variables)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    if (identical(node.variables, _oldNode)) {
+      node.variables = _newNode as VariableDeclarationList;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitWhileStatement(WhileStatement node) {
+    if (identical(node.condition, _oldNode)) {
+      node.condition = _newNode as Expression;
+      return true;
+    } else if (identical(node.body, _oldNode)) {
+      node.body = _newNode as Statement;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitWithClause(WithClause node) {
+    if (_replaceInList(node.mixinTypes)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitYieldStatement(YieldStatement node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  bool _replaceInList(NodeList list) {
+    int count = list.length;
+    for (int i = 0; i < count; i++) {
+      if (identical(_oldNode, list[i])) {
+        list[i] = _newNode;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Replace the [oldNode] with the [newNode] in the AST structure containing
+   * the old node. Return `true` if the replacement was successful.
+   *
+   * Throws an [IllegalArgumentException] if either node is `null`, if the old
+   * node does not have a parent node, or if the AST structure has been
+   * corrupted.
+   */
+  static bool replace(AstNode oldNode, AstNode newNode) {
+    if (oldNode == null || newNode == null) {
+      throw new IllegalArgumentException(
+          "The old and new nodes must be non-null");
+    } else if (identical(oldNode, newNode)) {
+      return true;
+    }
+    AstNode parent = oldNode.parent;
+    if (parent == null) {
+      throw new IllegalArgumentException(
+          "The old node is not a child of another node");
+    }
+    NodeReplacer replacer = new NodeReplacer(oldNode, newNode);
+    return parent.accept(replacer);
+  }
+}
+
+/**
+ * Traverse the AST from initial child node to successive parents, building a
+ * collection of local variable and parameter names visible to the initial child
+ * node. In case of name shadowing, the first name seen is the most specific one
+ * so names are not redefined.
+ *
+ * Completion test code coverage is 95%. The two basic blocks that are not
+ * executed cannot be executed. They are included for future reference.
+ */
+class ScopedNameFinder extends GeneralizingAstVisitor<Object> {
+  Declaration _declarationNode;
+
+  AstNode _immediateChild;
+
+  Map<String, SimpleIdentifier> _locals =
+      new HashMap<String, SimpleIdentifier>();
+
+  final int _position;
+
+  bool _referenceIsWithinLocalFunction = false;
+
+  ScopedNameFinder(this._position);
+
+  Declaration get declaration => _declarationNode;
+
+  Map<String, SimpleIdentifier> get locals => _locals;
+
+  @override
+  Object visitBlock(Block node) {
+    _checkStatements(node.statements);
+    return super.visitBlock(node);
+  }
+
+  @override
+  Object visitCatchClause(CatchClause node) {
+    _addToScope(node.exceptionParameter);
+    _addToScope(node.stackTraceParameter);
+    return super.visitCatchClause(node);
+  }
+
+  @override
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    if (!identical(_immediateChild, node.parameters)) {
+      _addParameters(node.parameters.parameters);
+    }
+    _declarationNode = node;
+    return null;
+  }
+
+  @override
+  Object visitFieldDeclaration(FieldDeclaration node) {
+    _declarationNode = node;
+    return null;
+  }
+
+  @override
+  Object visitForEachStatement(ForEachStatement node) {
+    DeclaredIdentifier loopVariable = node.loopVariable;
+    if (loopVariable != null) {
+      _addToScope(loopVariable.identifier);
+    }
+    return super.visitForEachStatement(node);
+  }
+
+  @override
+  Object visitForStatement(ForStatement node) {
+    if (!identical(_immediateChild, node.variables) && node.variables != null) {
+      _addVariables(node.variables.variables);
+    }
+    return super.visitForStatement(node);
+  }
+
+  @override
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    if (node.parent is! FunctionDeclarationStatement) {
+      _declarationNode = node;
+      return null;
+    }
+    return super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    _referenceIsWithinLocalFunction = true;
+    return super.visitFunctionDeclarationStatement(node);
+  }
+
+  @override
+  Object visitFunctionExpression(FunctionExpression node) {
+    if (node.parameters != null &&
+        !identical(_immediateChild, node.parameters)) {
+      _addParameters(node.parameters.parameters);
+    }
+    return super.visitFunctionExpression(node);
+  }
+
+  @override
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    _declarationNode = node;
+    if (node.parameters == null) {
+      return null;
+    }
+    if (!identical(_immediateChild, node.parameters)) {
+      _addParameters(node.parameters.parameters);
+    }
+    return null;
+  }
+
+  @override
+  Object visitNode(AstNode node) {
+    _immediateChild = node;
+    AstNode parent = node.parent;
+    if (parent != null) {
+      parent.accept(this);
+    }
+    return null;
+  }
+
+  @override
+  Object visitSwitchMember(SwitchMember node) {
+    _checkStatements(node.statements);
+    return super.visitSwitchMember(node);
+  }
+
+  @override
+  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    _declarationNode = node;
+    return null;
+  }
+
+  @override
+  Object visitTypeAlias(TypeAlias node) {
+    _declarationNode = node;
+    return null;
+  }
+
+  void _addParameters(NodeList<FormalParameter> vars) {
+    for (FormalParameter var2 in vars) {
+      _addToScope(var2.identifier);
+    }
+  }
+
+  void _addToScope(SimpleIdentifier identifier) {
+    if (identifier != null && _isInRange(identifier)) {
+      String name = identifier.name;
+      if (!_locals.containsKey(name)) {
+        _locals[name] = identifier;
+      }
+    }
+  }
+
+  void _addVariables(NodeList<VariableDeclaration> variables) {
+    for (VariableDeclaration variable in variables) {
+      _addToScope(variable.name);
+    }
+  }
+
+  /**
+   * Check the given list of [statements] for any that come before the immediate
+   * child and that define a name that would be visible to the immediate child.
+   */
+  void _checkStatements(List<Statement> statements) {
+    for (Statement statement in statements) {
+      if (identical(statement, _immediateChild)) {
+        return;
+      }
+      if (statement is VariableDeclarationStatement) {
+        _addVariables(statement.variables.variables);
+      } else if (statement is FunctionDeclarationStatement &&
+          !_referenceIsWithinLocalFunction) {
+        _addToScope(statement.functionDeclaration.name);
+      }
+    }
+  }
+
+  bool _isInRange(AstNode node) {
+    if (_position < 0) {
+      // if source position is not set then all nodes are in range
+      return true;
+      // not reached
+    }
+    return node.end < _position;
+  }
+}
+
+/**
+ * A visitor used to write a source representation of a visited AST node (and
+ * all of it's children) to a writer.
+ */
+class ToSourceVisitor implements AstVisitor<Object> {
+  /**
+   * The writer to which the source is to be written.
+   */
+  final PrintWriter _writer;
+
+  /**
+   * Initialize a newly created visitor to write source code representing the
+   * visited nodes to the given [writer].
+   */
+  ToSourceVisitor(this._writer);
+
+  @override
+  Object visitAdjacentStrings(AdjacentStrings node) {
+    _visitNodeListWithSeparator(node.strings, " ");
+    return null;
+  }
+
+  @override
+  Object visitAnnotation(Annotation node) {
+    _writer.print('@');
+    _visitNode(node.name);
+    _visitNodeWithPrefix(".", node.constructorName);
+    _visitNode(node.arguments);
+    return null;
+  }
+
+  @override
+  Object visitArgumentList(ArgumentList node) {
+    _writer.print('(');
+    _visitNodeListWithSeparator(node.arguments, ", ");
+    _writer.print(')');
+    return null;
+  }
+
+  @override
+  Object visitAsExpression(AsExpression node) {
+    _visitNode(node.expression);
+    _writer.print(" as ");
+    _visitNode(node.type);
+    return null;
+  }
+
+  @override
+  Object visitAssertStatement(AssertStatement node) {
+    _writer.print("assert (");
+    _visitNode(node.condition);
+    if (node.message != null) {
+      _writer.print(', ');
+      _visitNode(node.message);
+    }
+    _writer.print(");");
+    return null;
+  }
+
+  @override
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    _visitNode(node.leftHandSide);
+    _writer.print(' ');
+    _writer.print(node.operator.lexeme);
+    _writer.print(' ');
+    _visitNode(node.rightHandSide);
+    return null;
+  }
+
+  @override
+  Object visitAwaitExpression(AwaitExpression node) {
+    _writer.print("await ");
+    _visitNode(node.expression);
+    return null;
+  }
+
+  @override
+  Object visitBinaryExpression(BinaryExpression node) {
+    _visitNode(node.leftOperand);
+    _writer.print(' ');
+    _writer.print(node.operator.lexeme);
+    _writer.print(' ');
+    _visitNode(node.rightOperand);
+    return null;
+  }
+
+  @override
+  Object visitBlock(Block node) {
+    _writer.print('{');
+    _visitNodeListWithSeparator(node.statements, " ");
+    _writer.print('}');
+    return null;
+  }
+
+  @override
+  Object visitBlockFunctionBody(BlockFunctionBody node) {
+    Token keyword = node.keyword;
+    if (keyword != null) {
+      _writer.print(keyword.lexeme);
+      if (node.star != null) {
+        _writer.print('*');
+      }
+      _writer.print(' ');
+    }
+    _visitNode(node.block);
+    return null;
+  }
+
+  @override
+  Object visitBooleanLiteral(BooleanLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+
+  @override
+  Object visitBreakStatement(BreakStatement node) {
+    _writer.print("break");
+    _visitNodeWithPrefix(" ", node.label);
+    _writer.print(";");
+    return null;
+  }
+
+  @override
+  Object visitCascadeExpression(CascadeExpression node) {
+    _visitNode(node.target);
+    _visitNodeList(node.cascadeSections);
+    return null;
+  }
+
+  @override
+  Object visitCatchClause(CatchClause node) {
+    _visitNodeWithPrefix("on ", node.exceptionType);
+    if (node.catchKeyword != null) {
+      if (node.exceptionType != null) {
+        _writer.print(' ');
+      }
+      _writer.print("catch (");
+      _visitNode(node.exceptionParameter);
+      _visitNodeWithPrefix(", ", node.stackTraceParameter);
+      _writer.print(") ");
+    } else {
+      _writer.print(" ");
+    }
+    _visitNode(node.body);
+    return null;
+  }
+
+  @override
+  Object visitClassDeclaration(ClassDeclaration node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitTokenWithSuffix(node.abstractKeyword, " ");
+    _writer.print("class ");
+    _visitNode(node.name);
+    _visitNode(node.typeParameters);
+    _visitNodeWithPrefix(" ", node.extendsClause);
+    _visitNodeWithPrefix(" ", node.withClause);
+    _visitNodeWithPrefix(" ", node.implementsClause);
+    _writer.print(" {");
+    _visitNodeListWithSeparator(node.members, " ");
+    _writer.print("}");
+    return null;
+  }
+
+  @override
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    if (node.abstractKeyword != null) {
+      _writer.print("abstract ");
+    }
+    _writer.print("class ");
+    _visitNode(node.name);
+    _visitNode(node.typeParameters);
+    _writer.print(" = ");
+    _visitNode(node.superclass);
+    _visitNodeWithPrefix(" ", node.withClause);
+    _visitNodeWithPrefix(" ", node.implementsClause);
+    _writer.print(";");
+    return null;
+  }
+
+  @override
+  Object visitComment(Comment node) => null;
+
+  @override
+  Object visitCommentReference(CommentReference node) => null;
+
+  @override
+  Object visitCompilationUnit(CompilationUnit node) {
+    ScriptTag scriptTag = node.scriptTag;
+    NodeList<Directive> directives = node.directives;
+    _visitNode(scriptTag);
+    String prefix = scriptTag == null ? "" : " ";
+    _visitNodeListWithSeparatorAndPrefix(prefix, directives, " ");
+    prefix = scriptTag == null && directives.isEmpty ? "" : " ";
+    _visitNodeListWithSeparatorAndPrefix(prefix, node.declarations, " ");
+    return null;
+  }
+
+  @override
+  Object visitConditionalExpression(ConditionalExpression node) {
+    _visitNode(node.condition);
+    _writer.print(" ? ");
+    _visitNode(node.thenExpression);
+    _writer.print(" : ");
+    _visitNode(node.elseExpression);
+    return null;
+  }
+
+  @override
+  Object visitConfiguration(Configuration node) {
+    _writer.print('if (');
+    _visitNode(node.name);
+    _visitNodeWithPrefix(" == ", node.value);
+    _writer.print(') ');
+    _visitNode(node.libraryUri);
+    return null;
+  }
+
+  @override
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitTokenWithSuffix(node.externalKeyword, " ");
+    _visitTokenWithSuffix(node.constKeyword, " ");
+    _visitTokenWithSuffix(node.factoryKeyword, " ");
+    _visitNode(node.returnType);
+    _visitNodeWithPrefix(".", node.name);
+    _visitNode(node.parameters);
+    _visitNodeListWithSeparatorAndPrefix(" : ", node.initializers, ", ");
+    _visitNodeWithPrefix(" = ", node.redirectedConstructor);
+    _visitFunctionWithPrefix(" ", node.body);
+    return null;
+  }
+
+  @override
+  Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    _visitTokenWithSuffix(node.thisKeyword, ".");
+    _visitNode(node.fieldName);
+    _writer.print(" = ");
+    _visitNode(node.expression);
+    return null;
+  }
+
+  @override
+  Object visitConstructorName(ConstructorName node) {
+    _visitNode(node.type);
+    _visitNodeWithPrefix(".", node.name);
+    return null;
+  }
+
+  @override
+  Object visitContinueStatement(ContinueStatement node) {
+    _writer.print("continue");
+    _visitNodeWithPrefix(" ", node.label);
+    _writer.print(";");
+    return null;
+  }
+
+  @override
+  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitTokenWithSuffix(node.keyword, " ");
+    _visitNodeWithSuffix(node.type, " ");
+    _visitNode(node.identifier);
+    return null;
+  }
+
+  @override
+  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    _visitNode(node.parameter);
+    if (node.separator != null) {
+      _writer.print(" ");
+      _writer.print(node.separator.lexeme);
+      _visitNodeWithPrefix(" ", node.defaultValue);
+    }
+    return null;
+  }
+
+  @override
+  Object visitDoStatement(DoStatement node) {
+    _writer.print("do ");
+    _visitNode(node.body);
+    _writer.print(" while (");
+    _visitNode(node.condition);
+    _writer.print(");");
+    return null;
+  }
+
+  @override
+  Object visitDottedName(DottedName node) {
+    _visitNodeListWithSeparator(node.components, ".");
+    return null;
+  }
+
+  @override
+  Object visitDoubleLiteral(DoubleLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+
+  @override
+  Object visitEmptyFunctionBody(EmptyFunctionBody node) {
+    _writer.print(';');
+    return null;
+  }
+
+  @override
+  Object visitEmptyStatement(EmptyStatement node) {
+    _writer.print(';');
+    return null;
+  }
+
+  @override
+  Object visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitNode(node.name);
+    return null;
+  }
+
+  @override
+  Object visitEnumDeclaration(EnumDeclaration node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _writer.print("enum ");
+    _visitNode(node.name);
+    _writer.print(" {");
+    _visitNodeListWithSeparator(node.constants, ", ");
+    _writer.print("}");
+    return null;
+  }
+
+  @override
+  Object visitExportDirective(ExportDirective node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _writer.print("export ");
+    _visitNode(node.uri);
+    _visitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
+    _writer.print(';');
+    return null;
+  }
+
+  @override
+  Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    Token keyword = node.keyword;
+    if (keyword != null) {
+      _writer.print(keyword.lexeme);
+      _writer.print(' ');
+    }
+    _writer.print("=> ");
+    _visitNode(node.expression);
+    if (node.semicolon != null) {
+      _writer.print(';');
+    }
+    return null;
+  }
+
+  @override
+  Object visitExpressionStatement(ExpressionStatement node) {
+    _visitNode(node.expression);
+    _writer.print(';');
+    return null;
+  }
+
+  @override
+  Object visitExtendsClause(ExtendsClause node) {
+    _writer.print("extends ");
+    _visitNode(node.superclass);
+    return null;
+  }
+
+  @override
+  Object visitFieldDeclaration(FieldDeclaration node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitTokenWithSuffix(node.staticKeyword, " ");
+    _visitNode(node.fields);
+    _writer.print(";");
+    return null;
+  }
+
+  @override
+  Object visitFieldFormalParameter(FieldFormalParameter node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
+    _visitTokenWithSuffix(node.keyword, " ");
+    _visitNodeWithSuffix(node.type, " ");
+    _writer.print("this.");
+    _visitNode(node.identifier);
+    _visitNode(node.typeParameters);
+    _visitNode(node.parameters);
+    return null;
+  }
+
+  @override
+  Object visitForEachStatement(ForEachStatement node) {
+    DeclaredIdentifier loopVariable = node.loopVariable;
+    if (node.awaitKeyword != null) {
+      _writer.print("await ");
+    }
+    _writer.print("for (");
+    if (loopVariable == null) {
+      _visitNode(node.identifier);
+    } else {
+      _visitNode(loopVariable);
+    }
+    _writer.print(" in ");
+    _visitNode(node.iterable);
+    _writer.print(") ");
+    _visitNode(node.body);
+    return null;
+  }
+
+  @override
+  Object visitFormalParameterList(FormalParameterList node) {
+    String groupEnd = null;
+    _writer.print('(');
+    NodeList<FormalParameter> parameters = node.parameters;
+    int size = parameters.length;
+    for (int i = 0; i < size; i++) {
+      FormalParameter parameter = parameters[i];
+      if (i > 0) {
+        _writer.print(", ");
+      }
+      if (groupEnd == null && parameter is DefaultFormalParameter) {
+        if (parameter.kind == ParameterKind.NAMED) {
+          groupEnd = "}";
+          _writer.print('{');
+        } else {
+          groupEnd = "]";
+          _writer.print('[');
+        }
+      }
+      parameter.accept(this);
+    }
+    if (groupEnd != null) {
+      _writer.print(groupEnd);
+    }
+    _writer.print(')');
+    return null;
+  }
+
+  @override
+  Object visitForStatement(ForStatement node) {
+    Expression initialization = node.initialization;
+    _writer.print("for (");
+    if (initialization != null) {
+      _visitNode(initialization);
+    } else {
+      _visitNode(node.variables);
+    }
+    _writer.print(";");
+    _visitNodeWithPrefix(" ", node.condition);
+    _writer.print(";");
+    _visitNodeListWithSeparatorAndPrefix(" ", node.updaters, ", ");
+    _writer.print(") ");
+    _visitNode(node.body);
+    return null;
+  }
+
+  @override
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitTokenWithSuffix(node.externalKeyword, " ");
+    _visitNodeWithSuffix(node.returnType, " ");
+    _visitTokenWithSuffix(node.propertyKeyword, " ");
+    _visitNode(node.name);
+    _visitNode(node.functionExpression);
+    return null;
+  }
+
+  @override
+  Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    _visitNode(node.functionDeclaration);
+    return null;
+  }
+
+  @override
+  Object visitFunctionExpression(FunctionExpression node) {
+    _visitNode(node.typeParameters);
+    _visitNode(node.parameters);
+    if (node.body is! EmptyFunctionBody) {
+      _writer.print(' ');
+    }
+    _visitNode(node.body);
+    return null;
+  }
+
+  @override
+  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    _visitNode(node.function);
+    _visitNode(node.typeArguments);
+    _visitNode(node.argumentList);
+    return null;
+  }
+
+  @override
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _writer.print("typedef ");
+    _visitNodeWithSuffix(node.returnType, " ");
+    _visitNode(node.name);
+    _visitNode(node.typeParameters);
+    _visitNode(node.parameters);
+    _writer.print(";");
+    return null;
+  }
+
+  @override
+  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
+    _visitNodeWithSuffix(node.returnType, " ");
+    _visitNode(node.identifier);
+    _visitNode(node.typeParameters);
+    _visitNode(node.parameters);
+    return null;
+  }
+
+  @override
+  Object visitHideCombinator(HideCombinator node) {
+    _writer.print("hide ");
+    _visitNodeListWithSeparator(node.hiddenNames, ", ");
+    return null;
+  }
+
+  @override
+  Object visitIfStatement(IfStatement node) {
+    _writer.print("if (");
+    _visitNode(node.condition);
+    _writer.print(") ");
+    _visitNode(node.thenStatement);
+    _visitNodeWithPrefix(" else ", node.elseStatement);
+    return null;
+  }
+
+  @override
+  Object visitImplementsClause(ImplementsClause node) {
+    _writer.print("implements ");
+    _visitNodeListWithSeparator(node.interfaces, ", ");
+    return null;
+  }
+
+  @override
+  Object visitImportDirective(ImportDirective node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _writer.print("import ");
+    _visitNode(node.uri);
+    if (node.deferredKeyword != null) {
+      _writer.print(" deferred");
+    }
+    _visitNodeWithPrefix(" as ", node.prefix);
+    _visitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
+    _writer.print(';');
+    return null;
+  }
+
+  @override
+  Object visitIndexExpression(IndexExpression node) {
+    if (node.isCascaded) {
+      _writer.print("..");
+    } else {
+      _visitNode(node.target);
+    }
+    _writer.print('[');
+    _visitNode(node.index);
+    _writer.print(']');
+    return null;
+  }
+
+  @override
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    _visitTokenWithSuffix(node.keyword, " ");
+    _visitNode(node.constructorName);
+    _visitNode(node.argumentList);
+    return null;
+  }
+
+  @override
+  Object visitIntegerLiteral(IntegerLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+
+  @override
+  Object visitInterpolationExpression(InterpolationExpression node) {
+    if (node.rightBracket != null) {
+      _writer.print("\${");
+      _visitNode(node.expression);
+      _writer.print("}");
+    } else {
+      _writer.print("\$");
+      _visitNode(node.expression);
+    }
+    return null;
+  }
+
+  @override
+  Object visitInterpolationString(InterpolationString node) {
+    _writer.print(node.contents.lexeme);
+    return null;
+  }
+
+  @override
+  Object visitIsExpression(IsExpression node) {
+    _visitNode(node.expression);
+    if (node.notOperator == null) {
+      _writer.print(" is ");
+    } else {
+      _writer.print(" is! ");
+    }
+    _visitNode(node.type);
+    return null;
+  }
+
+  @override
+  Object visitLabel(Label node) {
+    _visitNode(node.label);
+    _writer.print(":");
+    return null;
+  }
+
+  @override
+  Object visitLabeledStatement(LabeledStatement node) {
+    _visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
+    _visitNode(node.statement);
+    return null;
+  }
+
+  @override
+  Object visitLibraryDirective(LibraryDirective node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _writer.print("library ");
+    _visitNode(node.name);
+    _writer.print(';');
+    return null;
+  }
+
+  @override
+  Object visitLibraryIdentifier(LibraryIdentifier node) {
+    _writer.print(node.name);
+    return null;
+  }
+
+  @override
+  Object visitListLiteral(ListLiteral node) {
+    if (node.constKeyword != null) {
+      _writer.print(node.constKeyword.lexeme);
+      _writer.print(' ');
+    }
+    _visitNodeWithSuffix(node.typeArguments, " ");
+    _writer.print("[");
+    _visitNodeListWithSeparator(node.elements, ", ");
+    _writer.print("]");
+    return null;
+  }
+
+  @override
+  Object visitMapLiteral(MapLiteral node) {
+    if (node.constKeyword != null) {
+      _writer.print(node.constKeyword.lexeme);
+      _writer.print(' ');
+    }
+    _visitNodeWithSuffix(node.typeArguments, " ");
+    _writer.print("{");
+    _visitNodeListWithSeparator(node.entries, ", ");
+    _writer.print("}");
+    return null;
+  }
+
+  @override
+  Object visitMapLiteralEntry(MapLiteralEntry node) {
+    _visitNode(node.key);
+    _writer.print(" : ");
+    _visitNode(node.value);
+    return null;
+  }
+
+  @override
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitTokenWithSuffix(node.externalKeyword, " ");
+    _visitTokenWithSuffix(node.modifierKeyword, " ");
+    _visitNodeWithSuffix(node.returnType, " ");
+    _visitTokenWithSuffix(node.propertyKeyword, " ");
+    _visitTokenWithSuffix(node.operatorKeyword, " ");
+    _visitNode(node.name);
+    if (!node.isGetter) {
+      _visitNode(node.typeParameters);
+      _visitNode(node.parameters);
+    }
+    _visitFunctionWithPrefix(" ", node.body);
+    return null;
+  }
+
+  @override
+  Object visitMethodInvocation(MethodInvocation node) {
+    if (node.isCascaded) {
+      _writer.print("..");
+    } else {
+      if (node.target != null) {
+        node.target.accept(this);
+        _writer.print(node.operator.lexeme);
+      }
+    }
+    _visitNode(node.methodName);
+    _visitNode(node.typeArguments);
+    _visitNode(node.argumentList);
+    return null;
+  }
+
+  @override
+  Object visitNamedExpression(NamedExpression node) {
+    _visitNode(node.name);
+    _visitNodeWithPrefix(" ", node.expression);
+    return null;
+  }
+
+  @override
+  Object visitNativeClause(NativeClause node) {
+    _writer.print("native ");
+    _visitNode(node.name);
+    return null;
+  }
+
+  @override
+  Object visitNativeFunctionBody(NativeFunctionBody node) {
+    _writer.print("native ");
+    _visitNode(node.stringLiteral);
+    _writer.print(';');
+    return null;
+  }
+
+  @override
+  Object visitNullLiteral(NullLiteral node) {
+    _writer.print("null");
+    return null;
+  }
+
+  @override
+  Object visitParenthesizedExpression(ParenthesizedExpression node) {
+    _writer.print('(');
+    _visitNode(node.expression);
+    _writer.print(')');
+    return null;
+  }
+
+  @override
+  Object visitPartDirective(PartDirective node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _writer.print("part ");
+    _visitNode(node.uri);
+    _writer.print(';');
+    return null;
+  }
+
+  @override
+  Object visitPartOfDirective(PartOfDirective node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _writer.print("part of ");
+    _visitNode(node.libraryName);
+    _writer.print(';');
+    return null;
+  }
+
+  @override
+  Object visitPostfixExpression(PostfixExpression node) {
+    _visitNode(node.operand);
+    _writer.print(node.operator.lexeme);
+    return null;
+  }
+
+  @override
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    _visitNode(node.prefix);
+    _writer.print('.');
+    _visitNode(node.identifier);
+    return null;
+  }
+
+  @override
+  Object visitPrefixExpression(PrefixExpression node) {
+    _writer.print(node.operator.lexeme);
+    _visitNode(node.operand);
+    return null;
+  }
+
+  @override
+  Object visitPropertyAccess(PropertyAccess node) {
+    if (node.isCascaded) {
+      _writer.print("..");
+    } else {
+      _visitNode(node.target);
+      _writer.print(node.operator.lexeme);
+    }
+    _visitNode(node.propertyName);
+    return null;
+  }
+
+  @override
+  Object visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    _writer.print("this");
+    _visitNodeWithPrefix(".", node.constructorName);
+    _visitNode(node.argumentList);
+    return null;
+  }
+
+  @override
+  Object visitRethrowExpression(RethrowExpression node) {
+    _writer.print("rethrow");
+    return null;
+  }
+
+  @override
+  Object visitReturnStatement(ReturnStatement node) {
+    Expression expression = node.expression;
+    if (expression == null) {
+      _writer.print("return;");
+    } else {
+      _writer.print("return ");
+      expression.accept(this);
+      _writer.print(";");
+    }
+    return null;
+  }
+
+  @override
+  Object visitScriptTag(ScriptTag node) {
+    _writer.print(node.scriptTag.lexeme);
+    return null;
+  }
+
+  @override
+  Object visitShowCombinator(ShowCombinator node) {
+    _writer.print("show ");
+    _visitNodeListWithSeparator(node.shownNames, ", ");
+    return null;
+  }
+
+  @override
+  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
+    _visitTokenWithSuffix(node.keyword, " ");
+    _visitNodeWithSuffix(node.type, " ");
+    _visitNode(node.identifier);
+    return null;
+  }
+
+  @override
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    _writer.print(node.token.lexeme);
+    return null;
+  }
+
+  @override
+  Object visitSimpleStringLiteral(SimpleStringLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+
+  @override
+  Object visitStringInterpolation(StringInterpolation node) {
+    _visitNodeList(node.elements);
+    return null;
+  }
+
+  @override
+  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    _writer.print("super");
+    _visitNodeWithPrefix(".", node.constructorName);
+    _visitNode(node.argumentList);
+    return null;
+  }
+
+  @override
+  Object visitSuperExpression(SuperExpression node) {
+    _writer.print("super");
+    return null;
+  }
+
+  @override
+  Object visitSwitchCase(SwitchCase node) {
+    _visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
+    _writer.print("case ");
+    _visitNode(node.expression);
+    _writer.print(": ");
+    _visitNodeListWithSeparator(node.statements, " ");
+    return null;
+  }
+
+  @override
+  Object visitSwitchDefault(SwitchDefault node) {
+    _visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
+    _writer.print("default: ");
+    _visitNodeListWithSeparator(node.statements, " ");
+    return null;
+  }
+
+  @override
+  Object visitSwitchStatement(SwitchStatement node) {
+    _writer.print("switch (");
+    _visitNode(node.expression);
+    _writer.print(") {");
+    _visitNodeListWithSeparator(node.members, " ");
+    _writer.print("}");
+    return null;
+  }
+
+  @override
+  Object visitSymbolLiteral(SymbolLiteral node) {
+    _writer.print("#");
+    List<Token> components = node.components;
+    for (int i = 0; i < components.length; i++) {
+      if (i > 0) {
+        _writer.print(".");
+      }
+      _writer.print(components[i].lexeme);
+    }
+    return null;
+  }
+
+  @override
+  Object visitThisExpression(ThisExpression node) {
+    _writer.print("this");
+    return null;
+  }
+
+  @override
+  Object visitThrowExpression(ThrowExpression node) {
+    _writer.print("throw ");
+    _visitNode(node.expression);
+    return null;
+  }
+
+  @override
+  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    _visitNodeWithSuffix(node.variables, ";");
+    return null;
+  }
+
+  @override
+  Object visitTryStatement(TryStatement node) {
+    _writer.print("try ");
+    _visitNode(node.body);
+    _visitNodeListWithSeparatorAndPrefix(" ", node.catchClauses, " ");
+    _visitNodeWithPrefix(" finally ", node.finallyBlock);
+    return null;
+  }
+
+  @override
+  Object visitTypeArgumentList(TypeArgumentList node) {
+    _writer.print('<');
+    _visitNodeListWithSeparator(node.arguments, ", ");
+    _writer.print('>');
+    return null;
+  }
+
+  @override
+  Object visitTypeName(TypeName node) {
+    _visitNode(node.name);
+    _visitNode(node.typeArguments);
+    return null;
+  }
+
+  @override
+  Object visitTypeParameter(TypeParameter node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitNode(node.name);
+    _visitNodeWithPrefix(" extends ", node.bound);
+    return null;
+  }
+
+  @override
+  Object visitTypeParameterList(TypeParameterList node) {
+    _writer.print('<');
+    _visitNodeListWithSeparator(node.typeParameters, ", ");
+    _writer.print('>');
+    return null;
+  }
+
+  @override
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitNode(node.name);
+    _visitNodeWithPrefix(" = ", node.initializer);
+    return null;
+  }
+
+  @override
+  Object visitVariableDeclarationList(VariableDeclarationList node) {
+    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
+    _visitTokenWithSuffix(node.keyword, " ");
+    _visitNodeWithSuffix(node.type, " ");
+    _visitNodeListWithSeparator(node.variables, ", ");
+    return null;
+  }
+
+  @override
+  Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    _visitNode(node.variables);
+    _writer.print(";");
+    return null;
+  }
+
+  @override
+  Object visitWhileStatement(WhileStatement node) {
+    _writer.print("while (");
+    _visitNode(node.condition);
+    _writer.print(") ");
+    _visitNode(node.body);
+    return null;
+  }
+
+  @override
+  Object visitWithClause(WithClause node) {
+    _writer.print("with ");
+    _visitNodeListWithSeparator(node.mixinTypes, ", ");
+    return null;
+  }
+
+  @override
+  Object visitYieldStatement(YieldStatement node) {
+    if (node.star != null) {
+      _writer.print("yield* ");
+    } else {
+      _writer.print("yield ");
+    }
+    _visitNode(node.expression);
+    _writer.print(";");
+    return null;
+  }
+
+  /**
+   * Visit the given function [body], printing the [prefix] before if the body
+   * is not empty.
+   */
+  void _visitFunctionWithPrefix(String prefix, FunctionBody body) {
+    if (body is! EmptyFunctionBody) {
+      _writer.print(prefix);
+    }
+    _visitNode(body);
+  }
+
+  /**
+   * Safely visit the given [node].
+   */
+  void _visitNode(AstNode node) {
+    if (node != null) {
+      node.accept(this);
+    }
+  }
+
+  /**
+   * Print a list of [nodes] without any separation.
+   */
+  void _visitNodeList(NodeList<AstNode> nodes) {
+    _visitNodeListWithSeparator(nodes, "");
+  }
+
+  /**
+   * Print a list of [nodes], separated by the given [separator].
+   */
+  void _visitNodeListWithSeparator(NodeList<AstNode> nodes, String separator) {
+    if (nodes != null) {
+      int size = nodes.length;
+      for (int i = 0; i < size; i++) {
+        if (i > 0) {
+          _writer.print(separator);
+        }
+        nodes[i].accept(this);
+      }
+    }
+  }
+
+  /**
+   * Print a list of [nodes], prefixed by the given [prefix] if the list is not
+   * empty, and separated by the given [separator].
+   */
+  void _visitNodeListWithSeparatorAndPrefix(
+      String prefix, NodeList<AstNode> nodes, String separator) {
+    if (nodes != null) {
+      int size = nodes.length;
+      if (size > 0) {
+        _writer.print(prefix);
+        for (int i = 0; i < size; i++) {
+          if (i > 0) {
+            _writer.print(separator);
+          }
+          nodes[i].accept(this);
+        }
+      }
+    }
+  }
+
+  /**
+   * Print a list of [nodes], separated by the given [separator], followed by
+   * the given [suffix] if the list is not empty.
+   */
+  void _visitNodeListWithSeparatorAndSuffix(
+      NodeList<AstNode> nodes, String separator, String suffix) {
+    if (nodes != null) {
+      int size = nodes.length;
+      if (size > 0) {
+        for (int i = 0; i < size; i++) {
+          if (i > 0) {
+            _writer.print(separator);
+          }
+          nodes[i].accept(this);
+        }
+        _writer.print(suffix);
+      }
+    }
+  }
+
+  /**
+   * Safely visit the given [node], printing the [prefix] before the node if it
+   * is non-`null`.
+   */
+  void _visitNodeWithPrefix(String prefix, AstNode node) {
+    if (node != null) {
+      _writer.print(prefix);
+      node.accept(this);
+    }
+  }
+
+  /**
+   * Safely visit the given [node], printing the [suffix] after the node if it
+   * is non-`null`.
+   */
+  void _visitNodeWithSuffix(AstNode node, String suffix) {
+    if (node != null) {
+      node.accept(this);
+      _writer.print(suffix);
+    }
+  }
+
+  /**
+   * Safely visit the given [token], printing the [suffix] after the token if it
+   * is non-`null`.
+   */
+  void _visitTokenWithSuffix(Token token, String suffix) {
+    if (token != null) {
+      _writer.print(token.lexeme);
+      _writer.print(suffix);
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
new file mode 100644
index 0000000..71030e7
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -0,0 +1,4596 @@
+// 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 analyzer.src.dart.element.element;
+
+import 'dart:collection';
+import 'dart:math' show min;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart'
+    show DartObject, EvaluationResultImpl;
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, AnalysisEngine, AnalysisException;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' show Keyword;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+
+/**
+ * For AST nodes that could be in both the getter and setter contexts
+ * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
+ * elements are stored in the AST node, in an [AuxiliaryElements]. Because
+ * resolved elements are either statically resolved or resolved using propagated
+ * type information, this class is a wrapper for a pair of [ExecutableElement]s,
+ * not just a single [ExecutableElement].
+ */
+class AuxiliaryElements {
+  /**
+   * The element based on propagated type information, or `null` if the AST
+   * structure has not been resolved or if the node could not be resolved.
+   */
+  final ExecutableElement propagatedElement;
+
+  /**
+   * The element based on static type information, or `null` if the AST
+   * structure has not been resolved or if the node could not be resolved.
+   */
+  final ExecutableElement staticElement;
+
+  /**
+   * Initialize a newly created pair to have both the [staticElement] and the
+   * [propagatedElement].
+   */
+  AuxiliaryElements(this.staticElement, this.propagatedElement);
+}
+
+/**
+ * A concrete implementation of a [ClassElement].
+ */
+class ClassElementImpl extends ElementImpl implements ClassElement {
+  /**
+   * A list containing all of the accessors (getters and setters) contained in
+   * this class.
+   */
+  List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
+
+  /**
+   * For classes which are not mixin applications, a list containing all of the
+   * constructors contained in this class, or `null` if the list of
+   * constructors has not yet been built.
+   *
+   * For classes which are mixin applications, the list of constructors is
+   * computed on the fly by the [constructors] getter, and this field is
+   * `null`.
+   */
+  List<ConstructorElement> _constructors;
+
+  /**
+   * A list containing all of the fields contained in this class.
+   */
+  List<FieldElement> _fields = FieldElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the mixins that are applied to the class being
+   * extended in order to derive the superclass of this class.
+   */
+  List<InterfaceType> mixins = InterfaceType.EMPTY_LIST;
+
+  /**
+   * A list containing all of the interfaces that are implemented by this class.
+   */
+  List<InterfaceType> interfaces = InterfaceType.EMPTY_LIST;
+
+  /**
+   * A list containing all of the methods contained in this class.
+   */
+  List<MethodElement> _methods = MethodElement.EMPTY_LIST;
+
+  /**
+   * The superclass of the class, or `null` if the class does not have an
+   * explicit superclass.
+   */
+  InterfaceType supertype;
+
+  /**
+   * The type defined by the class.
+   */
+  InterfaceType type;
+
+  /**
+   * A list containing all of the type parameters defined for this class.
+   */
+  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+
+  /**
+   * The [SourceRange] of the `with` clause, `null` if there is no one.
+   */
+  SourceRange withClauseRange;
+
+  /**
+   * A flag indicating whether the types associated with the instance members of
+   * this class have been inferred.
+   */
+  bool hasBeenInferred = false;
+
+  /**
+   * Initialize a newly created class element to have the given [name] at the
+   * given [offset] in the file that contains the declaration of this element.
+   */
+  ClassElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created class element to have the given [name].
+   */
+  ClassElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this class is abstract.
+   */
+  void set abstract(bool isAbstract) {
+    setModifier(Modifier.ABSTRACT, isAbstract);
+  }
+
+  @override
+  List<PropertyAccessorElement> get accessors => _accessors;
+
+  /**
+   * Set the accessors contained in this class to the given [accessors].
+   */
+  void set accessors(List<PropertyAccessorElement> accessors) {
+    for (PropertyAccessorElement accessor in accessors) {
+      (accessor as PropertyAccessorElementImpl).enclosingElement = this;
+    }
+    this._accessors = accessors;
+  }
+
+  @override
+  List<InterfaceType> get allSupertypes {
+    List<InterfaceType> list = new List<InterfaceType>();
+    _collectAllSupertypes(list);
+    return list;
+  }
+
+  @override
+  List<ConstructorElement> get constructors {
+    if (!isMixinApplication) {
+      assert(_constructors != null);
+      return _constructors == null
+          ? ConstructorElement.EMPTY_LIST
+          : _constructors;
+    }
+
+    return _computeMixinAppConstructors();
+  }
+
+  /**
+   * Set the constructors contained in this class to the given [constructors].
+   *
+   * Should only be used for class elements that are not mixin applications.
+   */
+  void set constructors(List<ConstructorElement> constructors) {
+    assert(!isMixinApplication);
+    for (ConstructorElement constructor in constructors) {
+      (constructor as ConstructorElementImpl).enclosingElement = this;
+    }
+    this._constructors = constructors;
+  }
+
+  /**
+   * Return `true` if [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] should
+   * be reported for this class.
+   */
+  bool get doesMixinLackConstructors {
+    if (!isMixinApplication && mixins.isEmpty) {
+      // This class is not a mixin application and it doesn't have a "with"
+      // clause, so CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS is
+      // inapplicable.
+      return false;
+    }
+    if (supertype == null) {
+      // Should never happen, since Object is the only class that has no
+      // supertype, and it should have been caught by the test above.
+      assert(false);
+      return false;
+    }
+    // Find the nearest class in the supertype chain that is not a mixin
+    // application.
+    ClassElement nearestNonMixinClass = supertype.element;
+    if (nearestNonMixinClass.isMixinApplication) {
+      // Use a list to keep track of the classes we've seen, so that we won't
+      // go into an infinite loop in the event of a non-trivial loop in the
+      // class hierarchy.
+      List<ClassElementImpl> classesSeen = <ClassElementImpl>[this];
+      while (nearestNonMixinClass.isMixinApplication) {
+        if (classesSeen.contains(nearestNonMixinClass)) {
+          // Loop in the class hierarchy (which is reported elsewhere).  Don't
+          // confuse the user with further errors.
+          return false;
+        }
+        classesSeen.add(nearestNonMixinClass);
+        if (nearestNonMixinClass.supertype == null) {
+          // Should never happen, since Object is the only class that has no
+          // supertype, and it is not a mixin application.
+          assert(false);
+          return false;
+        }
+        nearestNonMixinClass = nearestNonMixinClass.supertype.element;
+      }
+    }
+    return !nearestNonMixinClass.constructors.any(isSuperConstructorAccessible);
+  }
+
+  /**
+   * Set whether this class is defined by an enum declaration.
+   */
+  void set enum2(bool isEnum) {
+    setModifier(Modifier.ENUM, isEnum);
+  }
+
+  @override
+  List<FieldElement> get fields => _fields;
+
+  /**
+   * Set the fields contained in this class to the given [fields].
+   */
+  void set fields(List<FieldElement> fields) {
+    for (FieldElement field in fields) {
+      (field as FieldElementImpl).enclosingElement = this;
+    }
+    this._fields = fields;
+  }
+
+  @override
+  bool get hasNonFinalField {
+    List<ClassElement> classesToVisit = new List<ClassElement>();
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    classesToVisit.add(this);
+    while (!classesToVisit.isEmpty) {
+      ClassElement currentElement = classesToVisit.removeAt(0);
+      if (visitedClasses.add(currentElement)) {
+        // check fields
+        for (FieldElement field in currentElement.fields) {
+          if (!field.isFinal &&
+              !field.isConst &&
+              !field.isStatic &&
+              !field.isSynthetic) {
+            return true;
+          }
+        }
+        // check mixins
+        for (InterfaceType mixinType in currentElement.mixins) {
+          ClassElement mixinElement = mixinType.element;
+          classesToVisit.add(mixinElement);
+        }
+        // check super
+        InterfaceType supertype = currentElement.supertype;
+        if (supertype != null) {
+          ClassElement superElement = supertype.element;
+          if (superElement != null) {
+            classesToVisit.add(superElement);
+          }
+        }
+      }
+    }
+    // not found
+    return false;
+  }
+
+  @override
+  bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
+
+  /**
+   * Set whether this class references 'super'.
+   */
+  void set hasReferenceToSuper(bool isReferencedSuper) {
+    setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
+  }
+
+  @override
+  bool get hasStaticMember {
+    for (MethodElement method in _methods) {
+      if (method.isStatic) {
+        return true;
+      }
+    }
+    for (PropertyAccessorElement accessor in _accessors) {
+      if (accessor.isStatic) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
+
+  @override
+  bool get isEnum => hasModifier(Modifier.ENUM);
+
+  @override
+  bool get isMixinApplication => hasModifier(Modifier.MIXIN_APPLICATION);
+
+  @override
+  bool get isOrInheritsProxy =>
+      _safeIsOrInheritsProxy(this, new HashSet<ClassElement>());
+
+  @override
+  bool get isProxy {
+    for (ElementAnnotation annotation in metadata) {
+      if (annotation.isProxy) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isValidMixin => hasModifier(Modifier.MIXIN);
+
+  @override
+  ElementKind get kind => ElementKind.CLASS;
+
+  @override
+  List<MethodElement> get methods => _methods;
+
+  /**
+   * Set the methods contained in this class to the given [methods].
+   */
+  void set methods(List<MethodElement> methods) {
+    for (MethodElement method in methods) {
+      (method as MethodElementImpl).enclosingElement = this;
+    }
+    this._methods = methods;
+  }
+
+  /**
+   * Set whether this class is a mixin application.
+   */
+  void set mixinApplication(bool isMixinApplication) {
+    setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters defined for this class to the given
+   * [typeParameters].
+   */
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement typeParameter in typeParameters) {
+      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
+  }
+
+  @override
+  ConstructorElement get unnamedConstructor {
+    for (ConstructorElement element in constructors) {
+      String name = element.displayName;
+      if (name == null || name.isEmpty) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Set whether this class is a valid mixin.
+   */
+  void set validMixin(bool isValidMixin) {
+    setModifier(Modifier.MIXIN, isValidMixin);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitClassElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (isAbstract) {
+      buffer.write('abstract ');
+    }
+    if (isEnum) {
+      buffer.write('enum ');
+    } else {
+      buffer.write('class ');
+    }
+    String name = displayName;
+    if (name == null) {
+      buffer.write("{unnamed class}");
+    } else {
+      buffer.write(name);
+    }
+    int variableCount = _typeParameters.length;
+    if (variableCount > 0) {
+      buffer.write("<");
+      for (int i = 0; i < variableCount; i++) {
+        if (i > 0) {
+          buffer.write(", ");
+        }
+        (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
+      }
+      buffer.write(">");
+    }
+    if (supertype != null && !supertype.isObject) {
+      buffer.write(' extends ');
+      buffer.write(supertype.displayName);
+    }
+    if (mixins.isNotEmpty) {
+      buffer.write(' with ');
+      buffer.write(mixins.map((t) => t.displayName).join(', '));
+    }
+    if (interfaces.isNotEmpty) {
+      buffer.write(' implements ');
+      buffer.write(interfaces.map((t) => t.displayName).join(', '));
+    }
+  }
+
+  @override
+  NamedCompilationUnitMember computeNode() {
+    if (isEnum) {
+      return getNodeMatching((node) => node is EnumDeclaration);
+    } else {
+      return getNodeMatching(
+          (node) => node is ClassDeclaration || node is ClassTypeAlias);
+    }
+  }
+
+  @override
+  ElementImpl getChild(String identifier) {
+    //
+    // The casts in this method are safe because the set methods would have
+    // thrown a CCE if any of the elements in the arrays were not of the
+    // expected types.
+    //
+    for (PropertyAccessorElement accessor in _accessors) {
+      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
+        return accessor as PropertyAccessorElementImpl;
+      }
+    }
+    for (ConstructorElement constructor in _constructors) {
+      if ((constructor as ConstructorElementImpl).identifier == identifier) {
+        return constructor as ConstructorElementImpl;
+      }
+    }
+    for (FieldElement field in _fields) {
+      if ((field as FieldElementImpl).identifier == identifier) {
+        return field as FieldElementImpl;
+      }
+    }
+    for (MethodElement method in _methods) {
+      if ((method as MethodElementImpl).identifier == identifier) {
+        return method as MethodElementImpl;
+      }
+    }
+    for (TypeParameterElement typeParameter in _typeParameters) {
+      if ((typeParameter as TypeParameterElementImpl).identifier ==
+          identifier) {
+        return typeParameter as TypeParameterElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  FieldElement getField(String name) {
+    for (FieldElement fieldElement in _fields) {
+      if (name == fieldElement.name) {
+        return fieldElement;
+      }
+    }
+    return null;
+  }
+
+  @override
+  PropertyAccessorElement getGetter(String getterName) {
+    for (PropertyAccessorElement accessor in _accessors) {
+      if (accessor.isGetter && accessor.name == getterName) {
+        return accessor;
+      }
+    }
+    return null;
+  }
+
+  @override
+  MethodElement getMethod(String methodName) {
+    for (MethodElement method in _methods) {
+      if (method.name == methodName) {
+        return method;
+      }
+    }
+    return null;
+  }
+
+  @override
+  ConstructorElement getNamedConstructor(String name) {
+    for (ConstructorElement element in constructors) {
+      String elementName = element.name;
+      if (elementName != null && elementName == name) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  @override
+  PropertyAccessorElement getSetter(String setterName) {
+    // TODO (jwren) revisit- should we append '=' here or require clients to
+    // include it?
+    // Do we need the check for isSetter below?
+    if (!StringUtilities.endsWithChar(setterName, 0x3D)) {
+      setterName += '=';
+    }
+    for (PropertyAccessorElement accessor in _accessors) {
+      if (accessor.isSetter && accessor.name == setterName) {
+        return accessor;
+      }
+    }
+    return null;
+  }
+
+  @override
+  bool isSuperConstructorAccessible(ConstructorElement constructor) {
+    // If this class has no mixins, then all superclass constructors are
+    // accessible.
+    if (mixins.isEmpty) {
+      return true;
+    }
+    // Otherwise only constructors that lack optional parameters are
+    // accessible (see dartbug.com/19576).
+    for (ParameterElement parameter in constructor.parameters) {
+      if (parameter.parameterKind != ParameterKind.REQUIRED) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  MethodElement lookUpConcreteMethod(
+          String methodName, LibraryElement library) =>
+      _internalLookUpConcreteMethod(methodName, library, true);
+
+  @override
+  PropertyAccessorElement lookUpGetter(
+          String getterName, LibraryElement library) =>
+      _internalLookUpGetter(getterName, library, true);
+
+  @override
+  PropertyAccessorElement lookUpInheritedConcreteGetter(
+          String getterName, LibraryElement library) =>
+      _internalLookUpConcreteGetter(getterName, library, false);
+
+  @override
+  MethodElement lookUpInheritedConcreteMethod(
+          String methodName, LibraryElement library) =>
+      _internalLookUpConcreteMethod(methodName, library, false);
+
+  @override
+  PropertyAccessorElement lookUpInheritedConcreteSetter(
+          String setterName, LibraryElement library) =>
+      _internalLookUpConcreteSetter(setterName, library, false);
+
+  @override
+  MethodElement lookUpInheritedMethod(
+          String methodName, LibraryElement library) =>
+      _internalLookUpMethod(methodName, library, false);
+
+  @override
+  MethodElement lookUpMethod(String methodName, LibraryElement library) =>
+      _internalLookUpMethod(methodName, library, true);
+
+  @override
+  PropertyAccessorElement lookUpSetter(
+          String setterName, LibraryElement library) =>
+      _internalLookUpSetter(setterName, library, true);
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_accessors, visitor);
+    safelyVisitChildren(_constructors, visitor);
+    safelyVisitChildren(_fields, visitor);
+    safelyVisitChildren(_methods, visitor);
+    safelyVisitChildren(_typeParameters, visitor);
+  }
+
+  void _collectAllSupertypes(List<InterfaceType> supertypes) {
+    List<InterfaceType> typesToVisit = new List<InterfaceType>();
+    List<ClassElement> visitedClasses = new List<ClassElement>();
+    typesToVisit.add(this.type);
+    while (!typesToVisit.isEmpty) {
+      InterfaceType currentType = typesToVisit.removeAt(0);
+      ClassElement currentElement = currentType.element;
+      if (!visitedClasses.contains(currentElement)) {
+        visitedClasses.add(currentElement);
+        if (!identical(currentType, this.type)) {
+          supertypes.add(currentType);
+        }
+        InterfaceType supertype = currentType.superclass;
+        if (supertype != null) {
+          typesToVisit.add(supertype);
+        }
+        for (InterfaceType type in currentElement.interfaces) {
+          typesToVisit.add(type);
+        }
+        for (InterfaceType type in currentElement.mixins) {
+          ClassElement element = type.element;
+          if (!visitedClasses.contains(element)) {
+            supertypes.add(type);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Compute a list of constructors for this class, which is a mixin
+   * application.  If specified, [visitedClasses] is a list of the other mixin
+   * application classes which have been visited on the way to reaching this
+   * one (this is used to detect circularities).
+   */
+  List<ConstructorElement> _computeMixinAppConstructors(
+      [List<ClassElementImpl> visitedClasses = null]) {
+    // First get the list of constructors of the superclass which need to be
+    // forwarded to this class.
+    Iterable<ConstructorElement> constructorsToForward;
+    if (supertype == null) {
+      // Shouldn't ever happen, since the only class with no supertype is
+      // Object, and it isn't a mixin application.  But for safety's sake just
+      // assume an empty list.
+      assert(false);
+      constructorsToForward = <ConstructorElement>[];
+    } else if (!supertype.element.isMixinApplication) {
+      List<ConstructorElement> superclassConstructors =
+          supertype.element.constructors;
+      // Filter out any constructors with optional parameters (see
+      // dartbug.com/15101).
+      constructorsToForward =
+          superclassConstructors.where(isSuperConstructorAccessible);
+    } else {
+      if (visitedClasses == null) {
+        visitedClasses = <ClassElementImpl>[this];
+      } else {
+        if (visitedClasses.contains(this)) {
+          // Loop in the class hierarchy.  Don't try to forward any
+          // constructors.
+          return <ConstructorElement>[];
+        }
+        visitedClasses.add(this);
+      }
+      try {
+        ClassElementImpl superclass = supertype.element;
+        constructorsToForward =
+            superclass._computeMixinAppConstructors(visitedClasses);
+      } finally {
+        visitedClasses.removeLast();
+      }
+    }
+
+    // Figure out the type parameter substitution we need to perform in order
+    // to produce constructors for this class.  We want to be robust in the
+    // face of errors, so drop any extra type arguments and fill in any missing
+    // ones with `dynamic`.
+    List<DartType> parameterTypes =
+        TypeParameterTypeImpl.getTypes(supertype.typeParameters);
+    List<DartType> argumentTypes = new List<DartType>.filled(
+        parameterTypes.length, DynamicTypeImpl.instance);
+    for (int i = 0; i < supertype.typeArguments.length; i++) {
+      if (i >= argumentTypes.length) {
+        break;
+      }
+      argumentTypes[i] = supertype.typeArguments[i];
+    }
+
+    // Now create an implicit constructor for every constructor found above,
+    // substituting type parameters as appropriate.
+    return constructorsToForward
+        .map((ConstructorElement superclassConstructor) {
+      ConstructorElementImpl implicitConstructor =
+          new ConstructorElementImpl(superclassConstructor.name, -1);
+      implicitConstructor.synthetic = true;
+      implicitConstructor.redirectedConstructor = superclassConstructor;
+      implicitConstructor.const2 = superclassConstructor.isConst;
+      implicitConstructor.returnType = type;
+      List<ParameterElement> superParameters = superclassConstructor.parameters;
+      int count = superParameters.length;
+      if (count > 0) {
+        List<ParameterElement> implicitParameters =
+            new List<ParameterElement>(count);
+        for (int i = 0; i < count; i++) {
+          ParameterElement superParameter = superParameters[i];
+          ParameterElementImpl implicitParameter =
+              new ParameterElementImpl(superParameter.name, -1);
+          implicitParameter.const3 = superParameter.isConst;
+          implicitParameter.final2 = superParameter.isFinal;
+          implicitParameter.parameterKind = superParameter.parameterKind;
+          implicitParameter.synthetic = true;
+          implicitParameter.type =
+              superParameter.type.substitute2(argumentTypes, parameterTypes);
+          implicitParameters[i] = implicitParameter;
+        }
+        implicitConstructor.parameters = implicitParameters;
+      }
+      implicitConstructor.enclosingElement = this;
+      implicitConstructor.type = new FunctionTypeImpl(implicitConstructor);
+      return implicitConstructor;
+    }).toList();
+  }
+
+  PropertyAccessorElement _internalLookUpConcreteGetter(
+      String getterName, LibraryElement library, bool includeThisClass) {
+    PropertyAccessorElement getter =
+        _internalLookUpGetter(getterName, library, includeThisClass);
+    while (getter != null && getter.isAbstract) {
+      Element definingClass = getter.enclosingElement;
+      if (definingClass is! ClassElementImpl) {
+        return null;
+      }
+      getter = (definingClass as ClassElementImpl)
+          ._internalLookUpGetter(getterName, library, false);
+    }
+    return getter;
+  }
+
+  MethodElement _internalLookUpConcreteMethod(
+      String methodName, LibraryElement library, bool includeThisClass) {
+    MethodElement method =
+        _internalLookUpMethod(methodName, library, includeThisClass);
+    while (method != null && method.isAbstract) {
+      ClassElement definingClass = method.enclosingElement;
+      if (definingClass == null) {
+        return null;
+      }
+      method = definingClass.lookUpInheritedMethod(methodName, library);
+    }
+    return method;
+  }
+
+  PropertyAccessorElement _internalLookUpConcreteSetter(
+      String setterName, LibraryElement library, bool includeThisClass) {
+    PropertyAccessorElement setter =
+        _internalLookUpSetter(setterName, library, includeThisClass);
+    while (setter != null && setter.isAbstract) {
+      Element definingClass = setter.enclosingElement;
+      if (definingClass is! ClassElementImpl) {
+        return null;
+      }
+      setter = (definingClass as ClassElementImpl)
+          ._internalLookUpSetter(setterName, library, false);
+    }
+    return setter;
+  }
+
+  PropertyAccessorElement _internalLookUpGetter(
+      String getterName, LibraryElement library, bool includeThisClass) {
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    ClassElement currentElement = this;
+    if (includeThisClass) {
+      PropertyAccessorElement element = currentElement.getGetter(getterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    while (currentElement != null && visitedClasses.add(currentElement)) {
+      for (InterfaceType mixin in currentElement.mixins.reversed) {
+        ClassElement mixinElement = mixin.element;
+        if (mixinElement != null) {
+          PropertyAccessorElement element = mixinElement.getGetter(getterName);
+          if (element != null && element.isAccessibleIn(library)) {
+            return element;
+          }
+        }
+      }
+      InterfaceType supertype = currentElement.supertype;
+      if (supertype == null) {
+        return null;
+      }
+      currentElement = supertype.element;
+      PropertyAccessorElement element = currentElement.getGetter(getterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  MethodElement _internalLookUpMethod(
+      String methodName, LibraryElement library, bool includeThisClass) {
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    ClassElement currentElement = this;
+    if (includeThisClass) {
+      MethodElement element = currentElement.getMethod(methodName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    while (currentElement != null && visitedClasses.add(currentElement)) {
+      for (InterfaceType mixin in currentElement.mixins.reversed) {
+        ClassElement mixinElement = mixin.element;
+        if (mixinElement != null) {
+          MethodElement element = mixinElement.getMethod(methodName);
+          if (element != null && element.isAccessibleIn(library)) {
+            return element;
+          }
+        }
+      }
+      InterfaceType supertype = currentElement.supertype;
+      if (supertype == null) {
+        return null;
+      }
+      currentElement = supertype.element;
+      MethodElement element = currentElement.getMethod(methodName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  PropertyAccessorElement _internalLookUpSetter(
+      String setterName, LibraryElement library, bool includeThisClass) {
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    ClassElement currentElement = this;
+    if (includeThisClass) {
+      PropertyAccessorElement element = currentElement.getSetter(setterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    while (currentElement != null && visitedClasses.add(currentElement)) {
+      for (InterfaceType mixin in currentElement.mixins.reversed) {
+        ClassElement mixinElement = mixin.element;
+        if (mixinElement != null) {
+          PropertyAccessorElement element = mixinElement.getSetter(setterName);
+          if (element != null && element.isAccessibleIn(library)) {
+            return element;
+          }
+        }
+      }
+      InterfaceType supertype = currentElement.supertype;
+      if (supertype == null) {
+        return null;
+      }
+      currentElement = supertype.element;
+      PropertyAccessorElement element = currentElement.getSetter(setterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  bool _safeIsOrInheritsProxy(
+      ClassElement classElt, HashSet<ClassElement> visitedClassElts) {
+    if (visitedClassElts.contains(classElt)) {
+      return false;
+    }
+    visitedClassElts.add(classElt);
+    if (classElt.isProxy) {
+      return true;
+    } else if (classElt.supertype != null &&
+        _safeIsOrInheritsProxy(classElt.supertype.element, visitedClassElts)) {
+      return true;
+    }
+    List<InterfaceType> supertypes = classElt.interfaces;
+    for (int i = 0; i < supertypes.length; i++) {
+      if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
+        return true;
+      }
+    }
+    supertypes = classElt.mixins;
+    for (int i = 0; i < supertypes.length; i++) {
+      if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * A concrete implementation of a [CompilationUnitElement].
+ */
+class CompilationUnitElementImpl extends UriReferencedElementImpl
+    implements CompilationUnitElement {
+  /**
+   * The source that corresponds to this compilation unit.
+   */
+  Source source;
+
+  /**
+   * The source of the library containing this compilation unit.
+   *
+   * This is the same as the source of the containing [LibraryElement],
+   * except that it does not require the containing [LibraryElement] to be
+   * computed.
+   */
+  Source librarySource;
+
+  /**
+   * A list containing all of the top-level accessors (getters and setters)
+   * contained in this compilation unit.
+   */
+  List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the enums contained in this compilation unit.
+   */
+  List<ClassElement> _enums = ClassElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the top-level functions contained in this
+   * compilation unit.
+   */
+  List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the function type aliases contained in this
+   * compilation unit.
+   */
+  List<FunctionTypeAliasElement> _typeAliases =
+      FunctionTypeAliasElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the types contained in this compilation unit.
+   */
+  List<ClassElement> _types = ClassElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the variables contained in this compilation unit.
+   */
+  List<TopLevelVariableElement> _variables = TopLevelVariableElement.EMPTY_LIST;
+
+  /**
+   * A map from offsets to elements of this unit at these offsets.
+   */
+  final Map<int, Element> _offsetToElementMap = new HashMap<int, Element>();
+
+  /**
+   * Initialize a newly created compilation unit element to have the given
+   * [name].
+   */
+  CompilationUnitElementImpl(String name) : super(name, -1);
+
+  @override
+  List<PropertyAccessorElement> get accessors => _accessors;
+
+  /**
+   * Set the top-level accessors (getters and setters) contained in this
+   * compilation unit to the given [accessors].
+   */
+  void set accessors(List<PropertyAccessorElement> accessors) {
+    for (PropertyAccessorElement accessor in accessors) {
+      (accessor as PropertyAccessorElementImpl).enclosingElement = this;
+    }
+    this._accessors = accessors;
+  }
+
+  @override
+  LibraryElement get enclosingElement =>
+      super.enclosingElement as LibraryElement;
+
+  @override
+  List<ClassElement> get enums => _enums;
+
+  /**
+   * Set the enums contained in this compilation unit to the given [enums].
+   */
+  void set enums(List<ClassElement> enums) {
+    for (ClassElement enumDeclaration in enums) {
+      (enumDeclaration as ClassElementImpl).enclosingElement = this;
+    }
+    this._enums = enums;
+  }
+
+  @override
+  List<FunctionElement> get functions => _functions;
+
+  /**
+   * Set the top-level functions contained in this compilation unit to the given
+   * [functions].
+   */
+  void set functions(List<FunctionElement> functions) {
+    for (FunctionElement function in functions) {
+      (function as FunctionElementImpl).enclosingElement = this;
+    }
+    this._functions = functions;
+  }
+
+  @override
+  List<FunctionTypeAliasElement> get functionTypeAliases => _typeAliases;
+
+  @override
+  int get hashCode => source.hashCode;
+
+  @override
+  bool get hasLoadLibraryFunction {
+    for (int i = 0; i < _functions.length; i++) {
+      if (_functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  String get identifier => source.encoding;
+
+  @override
+  ElementKind get kind => ElementKind.COMPILATION_UNIT;
+
+  @override
+  List<TopLevelVariableElement> get topLevelVariables => _variables;
+
+  /**
+   * Set the top-level variables contained in this compilation unit to the given
+   * [variables].
+   */
+  void set topLevelVariables(List<TopLevelVariableElement> variables) {
+    for (TopLevelVariableElement field in variables) {
+      (field as TopLevelVariableElementImpl).enclosingElement = this;
+    }
+    this._variables = variables;
+  }
+
+  /**
+   * Set the function type aliases contained in this compilation unit to the
+   * given [typeAliases].
+   */
+  void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
+    for (FunctionTypeAliasElement typeAlias in typeAliases) {
+      (typeAlias as FunctionTypeAliasElementImpl).enclosingElement = this;
+    }
+    this._typeAliases = typeAliases;
+  }
+
+  @override
+  List<ClassElement> get types => _types;
+
+  /**
+   * Set the types contained in this compilation unit to the given [types].
+   */
+  void set types(List<ClassElement> types) {
+    for (ClassElement type in types) {
+      (type as ClassElementImpl).enclosingElement = this;
+    }
+    this._types = types;
+  }
+
+  @override
+  bool operator ==(Object object) =>
+      object is CompilationUnitElementImpl && source == object.source;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this);
+
+  /**
+   * This method is invoked after this unit was incrementally resolved.
+   */
+  void afterIncrementalResolution() {
+    _offsetToElementMap.clear();
+  }
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (source == null) {
+      buffer.write("{compilation unit}");
+    } else {
+      buffer.write(source.fullName);
+    }
+  }
+
+  @override
+  CompilationUnit computeNode() => unit;
+
+  @override
+  ElementImpl getChild(String identifier) {
+    //
+    // The casts in this method are safe because the set methods would have
+    // thrown a CCE if any of the elements in the arrays were not of the
+    // expected types.
+    //
+    for (PropertyAccessorElement accessor in _accessors) {
+      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
+        return accessor as PropertyAccessorElementImpl;
+      }
+    }
+    for (VariableElement variable in _variables) {
+      if ((variable as VariableElementImpl).identifier == identifier) {
+        return variable as VariableElementImpl;
+      }
+    }
+    for (ExecutableElement function in _functions) {
+      if ((function as ExecutableElementImpl).identifier == identifier) {
+        return function as ExecutableElementImpl;
+      }
+    }
+    for (FunctionTypeAliasElement typeAlias in _typeAliases) {
+      if ((typeAlias as FunctionTypeAliasElementImpl).identifier ==
+          identifier) {
+        return typeAlias as FunctionTypeAliasElementImpl;
+      }
+    }
+    for (ClassElement type in _types) {
+      if ((type as ClassElementImpl).identifier == identifier) {
+        return type as ClassElementImpl;
+      }
+    }
+    for (ClassElement type in _enums) {
+      if ((type as ClassElementImpl).identifier == identifier) {
+        return type as ClassElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  Element getElementAt(int offset) {
+    if (_offsetToElementMap.isEmpty) {
+      accept(new _BuildOffsetToElementMap(_offsetToElementMap));
+    }
+    return _offsetToElementMap[offset];
+  }
+
+  @override
+  ClassElement getEnum(String enumName) {
+    for (ClassElement enumDeclaration in _enums) {
+      if (enumDeclaration.name == enumName) {
+        return enumDeclaration;
+      }
+    }
+    return null;
+  }
+
+  @override
+  ClassElement getType(String className) {
+    for (ClassElement type in _types) {
+      if (type.name == className) {
+        return type;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Replace the given [from] top-level variable with [to] in this compilation unit.
+   */
+  void replaceTopLevelVariable(
+      TopLevelVariableElement from, TopLevelVariableElement to) {
+    int index = _variables.indexOf(from);
+    _variables[index] = to;
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_accessors, visitor);
+    safelyVisitChildren(_enums, visitor);
+    safelyVisitChildren(_functions, visitor);
+    safelyVisitChildren(_typeAliases, visitor);
+    safelyVisitChildren(_types, visitor);
+    safelyVisitChildren(_variables, visitor);
+  }
+}
+
+/**
+ * A [FieldElement] for a 'const' or 'final' field that has an initializer.
+ *
+ * TODO(paulberry): we should rename this class to reflect the fact that it's
+ * used for both const and final fields.  However, we shouldn't do so until
+ * we've created an API for reading the values of constants; until that API is
+ * available, clients are likely to read constant values by casting to
+ * ConstFieldElementImpl, so it would be a breaking change to rename this
+ * class.
+ */
+class ConstFieldElementImpl extends FieldElementImpl with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created synthetic field element to have the given
+   * [name] and [offset].
+   */
+  ConstFieldElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created field element to have the given [name].
+   */
+  ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+}
+
+/**
+ * A [LocalVariableElement] for a local 'const' variable that has an
+ * initializer.
+ */
+class ConstLocalVariableElementImpl extends LocalVariableElementImpl
+    with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created local variable element to have the given [name]
+   * and [offset].
+   */
+  ConstLocalVariableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created local variable element to have the given [name].
+   */
+  ConstLocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+}
+
+/**
+ * A concrete implementation of a [ConstructorElement].
+ */
+class ConstructorElementImpl extends ExecutableElementImpl
+    implements ConstructorElement {
+  /**
+   * The constructor to which this constructor is redirecting.
+   */
+  ConstructorElement redirectedConstructor;
+
+  /**
+   * The initializers for this constructor (used for evaluating constant
+   * instance creation expressions).
+   */
+  List<ConstructorInitializer> constantInitializers;
+
+  /**
+   * The offset of the `.` before this constructor name or `null` if not named.
+   */
+  int periodOffset;
+
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this constructor's name, or `null` if not named.
+   */
+  int nameEnd;
+
+  /**
+   * True if this constructor has been found by constant evaluation to be free
+   * of redirect cycles, and is thus safe to evaluate.
+   */
+  bool isCycleFree = false;
+
+  /**
+   * Initialize a newly created constructor element to have the given [name] and
+   * [offset].
+   */
+  ConstructorElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created constructor element to have the given [name].
+   */
+  ConstructorElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this constructor represents a 'const' constructor.
+   */
+  void set const2(bool isConst) {
+    setModifier(Modifier.CONST, isConst);
+  }
+
+  @override
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+
+  /**
+   * Set whether this constructor represents a factory method.
+   */
+  void set factory(bool isFactory) {
+    setModifier(Modifier.FACTORY, isFactory);
+  }
+
+  @override
+  bool get isConst => hasModifier(Modifier.CONST);
+
+  @override
+  bool get isDefaultConstructor {
+    // unnamed
+    String name = this.name;
+    if (name != null && name.length != 0) {
+      return false;
+    }
+    // no required parameters
+    for (ParameterElement parameter in parameters) {
+      if (parameter.parameterKind == ParameterKind.REQUIRED) {
+        return false;
+      }
+    }
+    // OK, can be used as default constructor
+    return true;
+  }
+
+  @override
+  bool get isFactory => hasModifier(Modifier.FACTORY);
+
+  @override
+  bool get isStatic => false;
+
+  @override
+  ElementKind get kind => ElementKind.CONSTRUCTOR;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (enclosingElement == null) {
+      String message;
+      String name = displayName;
+      if (name != null && !name.isEmpty) {
+        message =
+            'Found constructor element named $name with no enclosing element';
+      } else {
+        message = 'Found unnamed constructor element with no enclosing element';
+      }
+      AnalysisEngine.instance.logger.logError(message);
+      buffer.write('<unknown class>');
+    } else {
+      buffer.write(enclosingElement.displayName);
+    }
+    String name = displayName;
+    if (name != null && !name.isEmpty) {
+      buffer.write(".");
+      buffer.write(name);
+    }
+    super.appendTo(buffer);
+  }
+
+  @override
+  ConstructorDeclaration computeNode() =>
+      getNodeMatching((node) => node is ConstructorDeclaration);
+}
+
+/**
+ * A [TopLevelVariableElement] for a top-level 'const' variable that has an
+ * initializer.
+ */
+class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl
+    with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created top-level variable element to have the given
+   * [name].
+   */
+  ConstTopLevelVariableElementImpl(Identifier name) : super.forNode(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+}
+
+/**
+ * Mixin used by elements that represent constant variables and have
+ * initializers.
+ *
+ * Note that in correct Dart code, all constant variables must have
+ * initializers.  However, analyzer also needs to handle incorrect Dart code,
+ * in which case there might be some constant variables that lack initializers.
+ * This interface is only used for constant variables that have initializers.
+ *
+ * This class is not intended to be part of the public API for analyzer.
+ */
+abstract class ConstVariableElement {
+  /**
+   * If this element represents a constant variable, and it has an initializer,
+   * a copy of the initializer for the constant.  Otherwise `null`.
+   *
+   * Note that in correct Dart code, all constant variables must have
+   * initializers.  However, analyzer also needs to handle incorrect Dart code,
+   * in which case there might be some constant variables that lack
+   * initializers.
+   */
+  Expression constantInitializer;
+}
+
+/**
+ * A [FieldFormalParameterElementImpl] for parameters that have an initializer.
+ */
+class DefaultFieldFormalParameterElementImpl
+    extends FieldFormalParameterElementImpl with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created parameter element to have the given [name].
+   */
+  DefaultFieldFormalParameterElementImpl(Identifier name) : super(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+}
+
+/**
+ * A [ParameterElement] for parameters that have an initializer.
+ */
+class DefaultParameterElementImpl extends ParameterElementImpl
+    with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created parameter element to have the given [name].
+   */
+  DefaultParameterElementImpl(Identifier name) : super.forNode(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+
+  @override
+  DefaultFormalParameter computeNode() =>
+      getNodeMatching((node) => node is DefaultFormalParameter);
+}
+
+/**
+ * The synthetic element representing the declaration of the type `dynamic`.
+ */
+class DynamicElementImpl extends ElementImpl implements TypeDefiningElement {
+  /**
+   * Return the unique instance of this class.
+   */
+  static DynamicElementImpl get instance =>
+      DynamicTypeImpl.instance.element as DynamicElementImpl;
+
+  @override
+  DynamicTypeImpl type;
+
+  /**
+   * Initialize a newly created instance of this class. Instances of this class
+   * should <b>not</b> be created except as part of creating the type associated
+   * with this element. The single instance of this class should be accessed
+   * through the method [getInstance].
+   */
+  DynamicElementImpl() : super(Keyword.DYNAMIC.syntax, -1) {
+    setModifier(Modifier.SYNTHETIC, true);
+  }
+
+  @override
+  ElementKind get kind => ElementKind.DYNAMIC;
+
+  @override
+  accept(ElementVisitor visitor) => null;
+}
+
+/**
+ * A concrete implementation of an [ElementAnnotation].
+ */
+class ElementAnnotationImpl implements ElementAnnotation {
+  /**
+   * The name of the class used to mark an element as being deprecated.
+   */
+  static String _DEPRECATED_CLASS_NAME = "Deprecated";
+
+  /**
+   * The name of the top-level variable used to mark an element as being
+   * deprecated.
+   */
+  static String _DEPRECATED_VARIABLE_NAME = "deprecated";
+
+  /**
+   * The name of the top-level variable used to mark a method as being expected
+   * to override an inherited method.
+   */
+  static String _OVERRIDE_VARIABLE_NAME = "override";
+
+  /**
+   * The name of the top-level variable used to mark a class as implementing a
+   * proxy object.
+   */
+  static String PROXY_VARIABLE_NAME = "proxy";
+
+  /**
+   * The element representing the field, variable, or constructor being used as
+   * an annotation.
+   */
+  final Element element;
+
+  /**
+   * The result of evaluating this annotation as a compile-time constant
+   * expression, or `null` if the compilation unit containing the variable has
+   * not been resolved.
+   */
+  EvaluationResultImpl evaluationResult;
+
+  /**
+   * Initialize a newly created annotation. The given [element] is the element
+   * representing the field, variable, or constructor being used as an
+   * annotation.
+   */
+  ElementAnnotationImpl(this.element);
+
+  @override
+  DartObject get constantValue => evaluationResult.value;
+
+  @override
+  bool get isDeprecated {
+    if (element != null) {
+      LibraryElement library = element.library;
+      if (library != null && library.isDartCore) {
+        if (element is ConstructorElement) {
+          ConstructorElement constructorElement = element as ConstructorElement;
+          if (constructorElement.enclosingElement.name ==
+              _DEPRECATED_CLASS_NAME) {
+            return true;
+          }
+        } else if (element is PropertyAccessorElement &&
+            element.name == _DEPRECATED_VARIABLE_NAME) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isOverride {
+    if (element != null) {
+      LibraryElement library = element.library;
+      if (library != null && library.isDartCore) {
+        if (element is PropertyAccessorElement &&
+            element.name == _OVERRIDE_VARIABLE_NAME) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isProxy {
+    if (element != null) {
+      LibraryElement library = element.library;
+      if (library != null && library.isDartCore) {
+        if (element is PropertyAccessorElement &&
+            element.name == PROXY_VARIABLE_NAME) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @override
+  String toString() => '@$element';
+}
+
+/**
+ * A base class for concrete implementations of an [Element].
+ */
+abstract class ElementImpl implements Element {
+  /**
+   * An Unicode right arrow.
+   */
+  static final String RIGHT_ARROW = " \u2192 ";
+
+  static int _NEXT_ID = 0;
+
+  final int id = _NEXT_ID++;
+
+  /**
+   * The enclosing element of this element, or `null` if this element is at the
+   * root of the element structure.
+   */
+  ElementImpl _enclosingElement;
+
+  /**
+   * The name of this element.
+   */
+  String _name;
+
+  /**
+   * The offset of the name of this element in the file that contains the
+   * declaration of this element.
+   */
+  int _nameOffset = 0;
+
+  /**
+   * A bit-encoded form of the modifiers associated with this element.
+   */
+  int _modifiers = 0;
+
+  /**
+   * A list containing all of the metadata associated with this element.
+   */
+  List<ElementAnnotation> metadata = ElementAnnotation.EMPTY_LIST;
+
+  /**
+   * A cached copy of the calculated hashCode for this element.
+   */
+  int _cachedHashCode;
+
+  /**
+   * A cached copy of the calculated location for this element.
+   */
+  ElementLocation _cachedLocation;
+
+  /**
+   * The documentation comment for this element.
+   */
+  String _docComment;
+
+  /**
+   * The offset to the beginning of the documentation comment,
+   * or `null` if this element does not have a documentation comment.
+   */
+  int _docRangeOffset;
+
+  /**
+   * The length of the documentation comment range for this element.
+   */
+  int _docRangeLength;
+
+  /**
+   * Initialize a newly created element to have the given [name] at the given
+   * [_nameOffset].
+   */
+  ElementImpl(String name, this._nameOffset) {
+    this._name = StringUtilities.intern(name);
+  }
+
+  /**
+   * Initialize a newly created element to have the given [name].
+   */
+  ElementImpl.forNode(Identifier name)
+      : this(name == null ? "" : name.name, name == null ? -1 : name.offset);
+
+  @override
+  AnalysisContext get context {
+    if (_enclosingElement == null) {
+      return null;
+    }
+    return _enclosingElement.context;
+  }
+
+  @override
+  String get displayName => _name;
+
+  @override
+  SourceRange get docRange {
+    if (_docRangeOffset != null && _docRangeLength != null) {
+      return new SourceRange(_docRangeOffset, _docRangeLength);
+    }
+    return null;
+  }
+
+  @override
+  String get documentationComment => _docComment;
+
+  /**
+   * The documentation comment source for this element.
+   */
+  void set documentationComment(String doc) {
+    _docComment = doc?.replaceAll('\r\n', '\n');
+  }
+
+  @override
+  Element get enclosingElement => _enclosingElement;
+
+  /**
+   * Set the enclosing element of this element to the given [element].
+   */
+  void set enclosingElement(Element element) {
+    _enclosingElement = element as ElementImpl;
+    _cachedLocation = null;
+    _cachedHashCode = null;
+  }
+
+  @override
+  int get hashCode {
+    // TODO: We might want to re-visit this optimization in the future.
+    // We cache the hash code value as this is a very frequently called method.
+    if (_cachedHashCode == null) {
+      int hashIdentifier = identifier.hashCode;
+      Element enclosing = enclosingElement;
+      if (enclosing != null) {
+        _cachedHashCode = hashIdentifier + enclosing.hashCode;
+      } else {
+        _cachedHashCode = hashIdentifier;
+      }
+    }
+    return _cachedHashCode;
+  }
+
+  /**
+   * Return an identifier that uniquely identifies this element among the
+   * children of this element's parent.
+   */
+  String get identifier => name;
+
+  @override
+  bool get isDeprecated {
+    for (ElementAnnotation annotation in metadata) {
+      if (annotation.isDeprecated) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isOverride {
+    for (ElementAnnotation annotation in metadata) {
+      if (annotation.isOverride) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isPrivate {
+    String name = displayName;
+    if (name == null) {
+      return true;
+    }
+    return Identifier.isPrivateName(name);
+  }
+
+  @override
+  bool get isPublic => !isPrivate;
+
+  @override
+  bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
+
+  @override
+  LibraryElement get library =>
+      getAncestor((element) => element is LibraryElement);
+
+  @override
+  ElementLocation get location {
+    if (_cachedLocation == null) {
+      if (library == null) {
+        return new ElementLocationImpl.con1(this);
+      }
+      _cachedLocation = new ElementLocationImpl.con1(this);
+    }
+    return _cachedLocation;
+  }
+
+  @override
+  String get name => _name;
+
+  void set name(String name) {
+    this._name = name;
+    _cachedLocation = null;
+    _cachedHashCode = null;
+  }
+
+  @override
+  int get nameLength => displayName != null ? displayName.length : 0;
+
+  @override
+  int get nameOffset => _nameOffset;
+
+  /**
+   * Sets the offset of the name of this element in the file that contains the
+   * declaration of this element.
+   */
+  void set nameOffset(int offset) {
+    _nameOffset = offset;
+    _cachedHashCode = null;
+    _cachedLocation = null;
+  }
+
+  @override
+  Source get source {
+    if (_enclosingElement == null) {
+      return null;
+    }
+    return _enclosingElement.source;
+  }
+
+  /**
+   * Set whether this element is synthetic.
+   */
+  void set synthetic(bool isSynthetic) {
+    setModifier(Modifier.SYNTHETIC, isSynthetic);
+  }
+
+  @override
+  CompilationUnit get unit => context.resolveCompilationUnit(source, library);
+
+  @override
+  bool operator ==(Object object) {
+    if (identical(this, object)) {
+      return true;
+    }
+    return object is Element &&
+        object.kind == kind &&
+        object.location == location;
+  }
+
+  /**
+   * Append a textual representation of this element to the given [buffer].
+   */
+  void appendTo(StringBuffer buffer) {
+    if (_name == null) {
+      buffer.write("<unnamed ");
+      buffer.write(runtimeType.toString());
+      buffer.write(">");
+    } else {
+      buffer.write(_name);
+    }
+  }
+
+  @override
+  String computeDocumentationComment() => documentationComment;
+
+  @override
+  AstNode computeNode() => getNodeMatching((node) => node is AstNode);
+
+  /**
+   * Set this element as the enclosing element for given [element].
+   */
+  void encloseElement(ElementImpl element) {
+    element.enclosingElement = this;
+  }
+
+  @override
+  Element getAncestor(Predicate<Element> predicate) {
+    Element ancestor = _enclosingElement;
+    while (ancestor != null && !predicate(ancestor)) {
+      ancestor = ancestor.enclosingElement;
+    }
+    return ancestor;
+  }
+
+  /**
+   * Return the child of this element that is uniquely identified by the given
+   * [identifier], or `null` if there is no such child.
+   */
+  ElementImpl getChild(String identifier) => null;
+
+  @override
+  String getExtendedDisplayName(String shortName) {
+    if (shortName == null) {
+      shortName = displayName;
+    }
+    Source source = this.source;
+    if (source != null) {
+      return "$shortName (${source.fullName})";
+    }
+    return shortName;
+  }
+
+  /**
+   * Return the resolved [AstNode] of the given type enclosing [getNameOffset].
+   */
+  AstNode getNodeMatching(Predicate<AstNode> predicate) {
+    CompilationUnit unit = this.unit;
+    if (unit == null) {
+      return null;
+    }
+    int offset = nameOffset;
+    AstNode node = new NodeLocator(offset).searchWithin(unit);
+    if (node == null) {
+      return null;
+    }
+    return node.getAncestor(predicate);
+  }
+
+  /**
+   * Return `true` if this element has the given [modifier] associated with it.
+   */
+  bool hasModifier(Modifier modifier) =>
+      BooleanArray.getEnum(_modifiers, modifier);
+
+  @override
+  bool isAccessibleIn(LibraryElement library) {
+    if (Identifier.isPrivateName(_name)) {
+      return library == this.library;
+    }
+    return true;
+  }
+
+  /**
+   * If the given [child] is not `null`, use the given [visitor] to visit it.
+   */
+  void safelyVisitChild(Element child, ElementVisitor visitor) {
+    if (child != null) {
+      child.accept(visitor);
+    }
+  }
+
+  /**
+   * Use the given [visitor] to visit all of the [children] in the given array.
+   */
+  void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
+    if (children != null) {
+      for (Element child in children) {
+        child.accept(visitor);
+      }
+    }
+  }
+
+  /**
+   * Set the documentation comment source range for this element.
+   */
+  void setDocRange(int offset, int length) {
+    _docRangeOffset = offset;
+    _docRangeLength = length;
+  }
+
+  /**
+   * Set whether the given [modifier] is associated with this element to
+   * correspond to the given [value].
+   */
+  void setModifier(Modifier modifier, bool value) {
+    _modifiers = BooleanArray.setEnum(_modifiers, modifier, value);
+  }
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    appendTo(buffer);
+    return buffer.toString();
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // There are no children to visit
+  }
+}
+
+/**
+ * A concrete implementation of an [ElementLocation].
+ */
+class ElementLocationImpl implements ElementLocation {
+  /**
+   * The character used to separate components in the encoded form.
+   */
+  static int _SEPARATOR_CHAR = 0x3B;
+
+  /**
+   * The path to the element whose location is represented by this object.
+   */
+  List<String> _components;
+
+  /**
+   * The object managing [indexKeyId] and [indexLocationId].
+   */
+  Object indexOwner;
+
+  /**
+   * A cached id of this location in index.
+   */
+  int indexKeyId;
+
+  /**
+   * A cached id of this location in index.
+   */
+  int indexLocationId;
+
+  /**
+   * Initialize a newly created location to represent the given [element].
+   */
+  ElementLocationImpl.con1(Element element) {
+    List<String> components = new List<String>();
+    Element ancestor = element;
+    while (ancestor != null) {
+      components.insert(0, (ancestor as ElementImpl).identifier);
+      ancestor = ancestor.enclosingElement;
+    }
+    this._components = components;
+  }
+
+  /**
+   * Initialize a newly created location from the given [encoding].
+   */
+  ElementLocationImpl.con2(String encoding) {
+    this._components = _decode(encoding);
+  }
+
+  /**
+   * Initialize a newly created location from the given [components].
+   */
+  ElementLocationImpl.con3(List<String> components) {
+    this._components = components;
+  }
+
+  @override
+  List<String> get components => _components;
+
+  @override
+  String get encoding {
+    StringBuffer buffer = new StringBuffer();
+    int length = _components.length;
+    for (int i = 0; i < length; i++) {
+      if (i > 0) {
+        buffer.writeCharCode(_SEPARATOR_CHAR);
+      }
+      _encode(buffer, _components[i]);
+    }
+    return buffer.toString();
+  }
+
+  @override
+  int get hashCode {
+    int result = 1;
+    for (int i = 0; i < _components.length; i++) {
+      String component = _components[i];
+      result = 31 * result + component.hashCode;
+    }
+    return result;
+  }
+
+  @override
+  bool operator ==(Object object) {
+    if (identical(this, object)) {
+      return true;
+    }
+    if (object is! ElementLocationImpl) {
+      return false;
+    }
+    ElementLocationImpl location = object as ElementLocationImpl;
+    List<String> otherComponents = location._components;
+    int length = _components.length;
+    if (otherComponents.length != length) {
+      return false;
+    }
+    for (int i = 0; i < length; i++) {
+      if (_components[i] != otherComponents[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  String toString() => encoding;
+
+  /**
+   * Decode the [encoding] of a location into a list of components and return
+   * the components.
+   */
+  List<String> _decode(String encoding) {
+    List<String> components = new List<String>();
+    StringBuffer buffer = new StringBuffer();
+    int index = 0;
+    int length = encoding.length;
+    while (index < length) {
+      int currentChar = encoding.codeUnitAt(index);
+      if (currentChar == _SEPARATOR_CHAR) {
+        if (index + 1 < length &&
+            encoding.codeUnitAt(index + 1) == _SEPARATOR_CHAR) {
+          buffer.writeCharCode(_SEPARATOR_CHAR);
+          index += 2;
+        } else {
+          components.add(buffer.toString());
+          buffer = new StringBuffer();
+          index++;
+        }
+      } else {
+        buffer.writeCharCode(currentChar);
+        index++;
+      }
+    }
+    components.add(buffer.toString());
+    return components;
+  }
+
+  /**
+   * Append an encoded form of the given [component] to the given [buffer].
+   */
+  void _encode(StringBuffer buffer, String component) {
+    int length = component.length;
+    for (int i = 0; i < length; i++) {
+      int currentChar = component.codeUnitAt(i);
+      if (currentChar == _SEPARATOR_CHAR) {
+        buffer.writeCharCode(_SEPARATOR_CHAR);
+      }
+      buffer.writeCharCode(currentChar);
+    }
+  }
+}
+
+/**
+ * A base class for concrete implementations of an [ExecutableElement].
+ */
+abstract class ExecutableElementImpl extends ElementImpl
+    implements ExecutableElement {
+  /**
+   * A list containing all of the functions defined within this executable
+   * element.
+   */
+  List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the labels defined within this executable element.
+   */
+  List<LabelElement> _labels = LabelElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the local variables defined within this executable
+   * element.
+   */
+  List<LocalVariableElement> _localVariables = LocalVariableElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the parameters defined by this executable element.
+   */
+  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the type parameters defined for this executable
+   * element.
+   */
+  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+
+  /**
+   * The return type defined by this executable element.
+   */
+  DartType returnType;
+
+  /**
+   * The type of function defined by this executable element.
+   */
+  FunctionType type;
+
+  /**
+   * Initialize a newly created executable element to have the given [name] and
+   * [offset].
+   */
+  ExecutableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created executable element to have the given [name].
+   */
+  ExecutableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this executable element's body is asynchronous.
+   */
+  void set asynchronous(bool isAsynchronous) {
+    setModifier(Modifier.ASYNCHRONOUS, isAsynchronous);
+  }
+
+  /**
+   * Set whether this executable element is external.
+   */
+  void set external(bool isExternal) {
+    setModifier(Modifier.EXTERNAL, isExternal);
+  }
+
+  @override
+  List<FunctionElement> get functions => _functions;
+
+  /**
+   * Set the functions defined within this executable element to the given
+   * [functions].
+   */
+  void set functions(List<FunctionElement> functions) {
+    for (FunctionElement function in functions) {
+      (function as FunctionElementImpl).enclosingElement = this;
+    }
+    this._functions = functions;
+  }
+
+  /**
+   * Set whether this method's body is a generator.
+   */
+  void set generator(bool isGenerator) {
+    setModifier(Modifier.GENERATOR, isGenerator);
+  }
+
+  @override
+  bool get hasImplicitReturnType => hasModifier(Modifier.IMPLICIT_TYPE);
+
+  /**
+   * Set whether this executable element has an implicit return type.
+   */
+  void set hasImplicitReturnType(bool hasImplicitReturnType) {
+    setModifier(Modifier.IMPLICIT_TYPE, hasImplicitReturnType);
+  }
+
+  @override
+  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
+
+  @override
+  bool get isAsynchronous => hasModifier(Modifier.ASYNCHRONOUS);
+
+  @override
+  bool get isExternal => hasModifier(Modifier.EXTERNAL);
+
+  @override
+  bool get isGenerator => hasModifier(Modifier.GENERATOR);
+
+  @override
+  bool get isOperator => false;
+
+  @override
+  bool get isSynchronous => !hasModifier(Modifier.ASYNCHRONOUS);
+
+  @override
+  List<LabelElement> get labels => _labels;
+
+  /**
+   * Set the labels defined within this executable element to the given
+   * [labels].
+   */
+  void set labels(List<LabelElement> labels) {
+    for (LabelElement label in labels) {
+      (label as LabelElementImpl).enclosingElement = this;
+    }
+    this._labels = labels;
+  }
+
+  @override
+  List<LocalVariableElement> get localVariables => _localVariables;
+
+  /**
+   * Set the local variables defined within this executable element to the given
+   * [variables].
+   */
+  void set localVariables(List<LocalVariableElement> variables) {
+    for (LocalVariableElement variable in variables) {
+      (variable as LocalVariableElementImpl).enclosingElement = this;
+    }
+    this._localVariables = variables;
+  }
+
+  @override
+  List<ParameterElement> get parameters => _parameters;
+
+  /**
+   * Set the parameters defined by this executable element to the given
+   * [parameters].
+   */
+  void set parameters(List<ParameterElement> parameters) {
+    for (ParameterElement parameter in parameters) {
+      (parameter as ParameterElementImpl).enclosingElement = this;
+    }
+    this._parameters = parameters;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters defined by this executable element to the given
+   * [typeParameters].
+   */
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement parameter in typeParameters) {
+      (parameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
+  }
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (this.kind != ElementKind.GETTER) {
+      int typeParameterCount = _typeParameters.length;
+      if (typeParameterCount > 0) {
+        buffer.write('<');
+        for (int i = 0; i < typeParameterCount; i++) {
+          if (i > 0) {
+            buffer.write(", ");
+          }
+          (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
+        }
+        buffer.write('>');
+      }
+      buffer.write("(");
+      String closing = null;
+      ParameterKind kind = ParameterKind.REQUIRED;
+      int parameterCount = _parameters.length;
+      for (int i = 0; i < parameterCount; i++) {
+        if (i > 0) {
+          buffer.write(", ");
+        }
+        ParameterElementImpl parameter = _parameters[i] as ParameterElementImpl;
+        ParameterKind parameterKind = parameter.parameterKind;
+        if (parameterKind != kind) {
+          if (closing != null) {
+            buffer.write(closing);
+          }
+          if (parameterKind == ParameterKind.POSITIONAL) {
+            buffer.write("[");
+            closing = "]";
+          } else if (parameterKind == ParameterKind.NAMED) {
+            buffer.write("{");
+            closing = "}";
+          } else {
+            closing = null;
+          }
+        }
+        kind = parameterKind;
+        parameter.appendToWithoutDelimiters(buffer);
+      }
+      if (closing != null) {
+        buffer.write(closing);
+      }
+      buffer.write(")");
+    }
+    if (type != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(type.returnType);
+    }
+  }
+
+  @override
+  ElementImpl getChild(String identifier) {
+    for (ExecutableElement function in _functions) {
+      if ((function as ExecutableElementImpl).identifier == identifier) {
+        return function as ExecutableElementImpl;
+      }
+    }
+    for (LabelElement label in _labels) {
+      if ((label as LabelElementImpl).identifier == identifier) {
+        return label as LabelElementImpl;
+      }
+    }
+    for (VariableElement variable in _localVariables) {
+      if ((variable as VariableElementImpl).identifier == identifier) {
+        return variable as VariableElementImpl;
+      }
+    }
+    for (ParameterElement parameter in _parameters) {
+      if ((parameter as ParameterElementImpl).identifier == identifier) {
+        return parameter as ParameterElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_functions, visitor);
+    safelyVisitChildren(_labels, visitor);
+    safelyVisitChildren(_localVariables, visitor);
+    safelyVisitChildren(_parameters, visitor);
+  }
+}
+
+/**
+ * A concrete implementation of an [ExportElement].
+ */
+class ExportElementImpl extends UriReferencedElementImpl
+    implements ExportElement {
+  /**
+   * The library that is exported from this library by this export directive.
+   */
+  LibraryElement exportedLibrary;
+
+  /**
+   * The combinators that were specified as part of the export directive in the
+   * order in which they were specified.
+   */
+  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
+
+  /**
+   * Initialize a newly created export element at the given [offset].
+   */
+  ExportElementImpl(int offset) : super(null, offset);
+
+  @override
+  String get identifier => exportedLibrary.name;
+
+  @override
+  ElementKind get kind => ElementKind.EXPORT;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitExportElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write("export ");
+    (exportedLibrary as LibraryElementImpl).appendTo(buffer);
+  }
+}
+
+/**
+ * A concrete implementation of a [FieldElement].
+ */
+class FieldElementImpl extends PropertyInducingElementImpl
+    implements FieldElement {
+  /**
+   * Initialize a newly created synthetic field element to have the given [name]
+   * at the given [offset].
+   */
+  FieldElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created field element to have the given [name].
+   */
+  FieldElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+
+  @override
+  bool get isEnumConstant =>
+      enclosingElement != null ? enclosingElement.isEnum : false;
+
+  @override
+  ElementKind get kind => ElementKind.FIELD;
+
+  /**
+   * Set whether this field is static.
+   */
+  void set static(bool isStatic) {
+    setModifier(Modifier.STATIC, isStatic);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
+
+  @override
+  AstNode computeNode() {
+    if (isEnumConstant) {
+      return getNodeMatching((node) => node is EnumConstantDeclaration);
+    } else {
+      return getNodeMatching((node) => node is VariableDeclaration);
+    }
+  }
+}
+
+/**
+ * A [ParameterElementImpl] that has the additional information of the
+ * [FieldElement] associated with the parameter.
+ */
+class FieldFormalParameterElementImpl extends ParameterElementImpl
+    implements FieldFormalParameterElement {
+  /**
+   * The field associated with this field formal parameter.
+   */
+  FieldElement field;
+
+  /**
+   * Initialize a newly created parameter element to have the given [name].
+   */
+  FieldFormalParameterElementImpl(Identifier name) : super.forNode(name);
+
+  @override
+  bool get isInitializingFormal => true;
+
+  @override
+  accept(ElementVisitor visitor) =>
+      visitor.visitFieldFormalParameterElement(this);
+}
+
+/**
+ * A concrete implementation of a [FunctionElement].
+ */
+class FunctionElementImpl extends ExecutableElementImpl
+    implements FunctionElement {
+  /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+
+  /**
+   * The length of the visible range for this element, or `-1` if this element
+   * does not have a visible range.
+   */
+  int _visibleRangeLength = -1;
+
+  /**
+   * Initialize a newly created function element to have the given [name] and
+   * [offset].
+   */
+  FunctionElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created function element to have the given [name].
+   */
+  FunctionElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Initialize a newly created function element to have no name and the given
+   * [offset]. This is used for function expressions, that have no name.
+   */
+  FunctionElementImpl.forOffset(int nameOffset) : super("", nameOffset);
+
+  @override
+  String get identifier {
+    String identifier = super.identifier;
+    if (!isStatic) {
+      identifier += "@$nameOffset";
+    }
+    return identifier;
+  }
+
+  @override
+  bool get isEntryPoint {
+    return isStatic && displayName == FunctionElement.MAIN_FUNCTION_NAME;
+  }
+
+  @override
+  bool get isStatic => enclosingElement is CompilationUnitElement;
+
+  @override
+  ElementKind get kind => ElementKind.FUNCTION;
+
+  @override
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    String name = displayName;
+    if (name != null) {
+      buffer.write(name);
+    }
+    super.appendTo(buffer);
+  }
+
+  @override
+  FunctionDeclaration computeNode() =>
+      getNodeMatching((node) => node is FunctionDeclaration);
+
+  /**
+   * Set the visible range for this element to the range starting at the given
+   * [offset] with the given [length].
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+
+  /**
+   * Set the parameters defined by this type alias to the given [parameters]
+   * without becoming the parent of the parameters. This should only be used by
+   * the [TypeResolverVisitor] when creating a synthetic type alias.
+   */
+  void shareParameters(List<ParameterElement> parameters) {
+    this._parameters = parameters;
+  }
+
+  /**
+   * Set the type parameters defined by this type alias to the given
+   * [parameters] without becoming the parent of the parameters. This should
+   * only be used by the [TypeResolverVisitor] when creating a synthetic type
+   * alias.
+   */
+  void shareTypeParameters(List<TypeParameterElement> typeParameters) {
+    this._typeParameters = typeParameters;
+  }
+}
+
+/**
+ * A concrete implementation of a [FunctionTypeAliasElement].
+ */
+class FunctionTypeAliasElementImpl extends ElementImpl
+    implements FunctionTypeAliasElement {
+  /**
+   * A list containing all of the parameters defined by this type alias.
+   */
+  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
+
+  /**
+   * The return type defined by this type alias.
+   */
+  DartType returnType;
+
+  /**
+   * The type of function defined by this type alias.
+   */
+  FunctionType type;
+
+  /**
+   * A list containing all of the type parameters defined for this type.
+   */
+  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+
+  /**
+   * Initialize a newly created type alias element to have the given name.
+   *
+   * [name] the name of this element
+   * [nameOffset] the offset of the name of this element in the file that
+   *    contains the declaration of this element
+   */
+  FunctionTypeAliasElementImpl(String name, int nameOffset)
+      : super(name, nameOffset);
+
+  /**
+   * Initialize a newly created type alias element to have the given [name].
+   */
+  FunctionTypeAliasElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  CompilationUnitElement get enclosingElement =>
+      super.enclosingElement as CompilationUnitElement;
+
+  @override
+  ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
+
+  @override
+  List<ParameterElement> get parameters => _parameters;
+
+  /**
+   * Set the parameters defined by this type alias to the given [parameters].
+   */
+  void set parameters(List<ParameterElement> parameters) {
+    if (parameters != null) {
+      for (ParameterElement parameter in parameters) {
+        (parameter as ParameterElementImpl).enclosingElement = this;
+      }
+    }
+    this._parameters = parameters;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters defined for this type to the given
+   * [typeParameters].
+   */
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement typeParameter in typeParameters) {
+      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFunctionTypeAliasElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write("typedef ");
+    buffer.write(displayName);
+    int typeParameterCount = _typeParameters.length;
+    if (typeParameterCount > 0) {
+      buffer.write("<");
+      for (int i = 0; i < typeParameterCount; i++) {
+        if (i > 0) {
+          buffer.write(", ");
+        }
+        (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
+      }
+      buffer.write(">");
+    }
+    buffer.write("(");
+    int parameterCount = _parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      (_parameters[i] as ParameterElementImpl).appendTo(buffer);
+    }
+    buffer.write(")");
+    if (type != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(type.returnType);
+    } else if (returnType != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(returnType);
+    }
+  }
+
+  @override
+  FunctionTypeAlias computeNode() =>
+      getNodeMatching((node) => node is FunctionTypeAlias);
+
+  @override
+  ElementImpl getChild(String identifier) {
+    for (VariableElement parameter in _parameters) {
+      if ((parameter as VariableElementImpl).identifier == identifier) {
+        return parameter as VariableElementImpl;
+      }
+    }
+    for (TypeParameterElement typeParameter in _typeParameters) {
+      if ((typeParameter as TypeParameterElementImpl).identifier ==
+          identifier) {
+        return typeParameter as TypeParameterElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_parameters, visitor);
+    safelyVisitChildren(_typeParameters, visitor);
+  }
+}
+
+/**
+ * A concrete implementation of a [HideElementCombinator].
+ */
+class HideElementCombinatorImpl implements HideElementCombinator {
+  /**
+   * The names that are not to be made visible in the importing library even if
+   * they are defined in the imported library.
+   */
+  List<String> hiddenNames = StringUtilities.EMPTY_ARRAY;
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write("show ");
+    int count = hiddenNames.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      buffer.write(hiddenNames[i]);
+    }
+    return buffer.toString();
+  }
+}
+
+/**
+ * A concrete implementation of an [ImportElement].
+ */
+class ImportElementImpl extends UriReferencedElementImpl
+    implements ImportElement {
+  /**
+   * The offset of the prefix of this import in the file that contains the this
+   * import directive, or `-1` if this import is synthetic.
+   */
+  int prefixOffset = 0;
+
+  /**
+   * The library that is imported into this library by this import directive.
+   */
+  LibraryElement importedLibrary;
+
+  /**
+   * The combinators that were specified as part of the import directive in the
+   * order in which they were specified.
+   */
+  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
+
+  /**
+   * The prefix that was specified as part of the import directive, or `null` if
+   * there was no prefix specified.
+   */
+  PrefixElement prefix;
+
+  /**
+   * Initialize a newly created import element at the given [offset].
+   * The offset may be `-1` if the import is synthetic.
+   */
+  ImportElementImpl(int offset) : super(null, offset);
+
+  /**
+   * Set whether this import is for a deferred library.
+   */
+  void set deferred(bool isDeferred) {
+    setModifier(Modifier.DEFERRED, isDeferred);
+  }
+
+  @override
+  String get identifier => "${importedLibrary.identifier}@$nameOffset";
+
+  @override
+  bool get isDeferred => hasModifier(Modifier.DEFERRED);
+
+  @override
+  ElementKind get kind => ElementKind.IMPORT;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitImportElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write("import ");
+    (importedLibrary as LibraryElementImpl).appendTo(buffer);
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(prefix, visitor);
+  }
+}
+
+/**
+ * A concrete implementation of a [LabelElement].
+ */
+class LabelElementImpl extends ElementImpl implements LabelElement {
+  /**
+   * A flag indicating whether this label is associated with a `switch`
+   * statement.
+   */
+  // TODO(brianwilkerson) Make this a modifier.
+  final bool _onSwitchStatement;
+
+  /**
+   * A flag indicating whether this label is associated with a `switch` member
+   * (`case` or `default`).
+   */
+  // TODO(brianwilkerson) Make this a modifier.
+  final bool _onSwitchMember;
+
+  /**
+   * Initialize a newly created label element to have the given [name].
+   * [onSwitchStatement] should be `true` if this label is associated with a
+   * `switch` statement and [onSwitchMember] should be `true` if this label is
+   * associated with a `switch` member.
+   */
+  LabelElementImpl(
+      Identifier name, this._onSwitchStatement, this._onSwitchMember)
+      : super.forNode(name);
+
+  @override
+  ExecutableElement get enclosingElement =>
+      super.enclosingElement as ExecutableElement;
+
+  /**
+   * Return `true` if this label is associated with a `switch` member (`case` or
+   * `default`).
+   */
+  bool get isOnSwitchMember => _onSwitchMember;
+
+  /**
+   * Return `true` if this label is associated with a `switch` statement.
+   */
+  bool get isOnSwitchStatement => _onSwitchStatement;
+
+  @override
+  ElementKind get kind => ElementKind.LABEL;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitLabelElement(this);
+}
+
+/**
+ * A concrete implementation of a [LibraryElement].
+ */
+class LibraryElementImpl extends ElementImpl implements LibraryElement {
+  /**
+   * The analysis context in which this library is defined.
+   */
+  final AnalysisContext context;
+
+  /**
+   * The compilation unit that defines this library.
+   */
+  CompilationUnitElement _definingCompilationUnit;
+
+  /**
+   * The entry point for this library, or `null` if this library does not have
+   * an entry point.
+   */
+  FunctionElement entryPoint;
+
+  /**
+   * A list containing specifications of all of the imports defined in this
+   * library.
+   */
+  List<ImportElement> _imports = ImportElement.EMPTY_LIST;
+
+  /**
+   * A list containing specifications of all of the exports defined in this
+   * library.
+   */
+  List<ExportElement> _exports = ExportElement.EMPTY_LIST;
+
+  /**
+   * A list containing the strongly connected component in the import/export
+   * graph in which the current library resides.  Computed on demand, null
+   * if not present.  If _libraryCycle is set, then the _libraryCycle field
+   * for all libraries reachable from this library in the import/export graph
+   * is also set.
+   */
+  List<LibraryElement> _libraryCycle = null;
+
+  /**
+   * A list containing all of the compilation units that are included in this
+   * library using a `part` directive.
+   */
+  List<CompilationUnitElement> _parts = CompilationUnitElement.EMPTY_LIST;
+
+  /**
+   * The element representing the synthetic function `loadLibrary` that is
+   * defined for this library, or `null` if the element has not yet been created.
+   */
+  FunctionElement _loadLibraryFunction;
+
+  @override
+  final int nameLength;
+
+  /**
+   * The export [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  @override
+  Namespace exportNamespace;
+
+  /**
+   * The public [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  @override
+  Namespace publicNamespace;
+
+  /**
+   * Initialize a newly created library element in the given [context] to have
+   * the given [name] and [offset].
+   */
+  LibraryElementImpl(this.context, String name, int offset, this.nameLength)
+      : super(name, offset);
+
+  /**
+   * Initialize a newly created library element in the given [context] to have
+   * the given [name].
+   */
+  LibraryElementImpl.forNode(this.context, LibraryIdentifier name)
+      : super.forNode(name),
+        nameLength = name != null ? name.length : 0;
+
+  @override
+  CompilationUnitElement get definingCompilationUnit =>
+      _definingCompilationUnit;
+
+  /**
+   * Set the compilation unit that defines this library to the given compilation
+   * [unit].
+   */
+  void set definingCompilationUnit(CompilationUnitElement unit) {
+    assert((unit as CompilationUnitElementImpl).librarySource == unit.source);
+    (unit as CompilationUnitElementImpl).enclosingElement = this;
+    this._definingCompilationUnit = unit;
+  }
+
+  @override
+  List<LibraryElement> get exportedLibraries {
+    HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
+    for (ExportElement element in _exports) {
+      LibraryElement library = element.exportedLibrary;
+      if (library != null) {
+        libraries.add(library);
+      }
+    }
+    return new List.from(libraries);
+  }
+
+  @override
+  List<ExportElement> get exports => _exports;
+
+  /**
+   * Set the specifications of all of the exports defined in this library to the
+   * given list of [exports].
+   */
+  void set exports(List<ExportElement> exports) {
+    for (ExportElement exportElement in exports) {
+      (exportElement as ExportElementImpl).enclosingElement = this;
+    }
+    this._exports = exports;
+  }
+
+  @override
+  bool get hasExtUri => hasModifier(Modifier.HAS_EXT_URI);
+
+  /**
+   * Set whether this library has an import of a "dart-ext" URI.
+   */
+  void set hasExtUri(bool hasExtUri) {
+    setModifier(Modifier.HAS_EXT_URI, hasExtUri);
+  }
+
+  @override
+  int get hashCode => _definingCompilationUnit.hashCode;
+
+  @override
+  bool get hasLoadLibraryFunction {
+    if (_definingCompilationUnit.hasLoadLibraryFunction) {
+      return true;
+    }
+    for (int i = 0; i < _parts.length; i++) {
+      if (_parts[i].hasLoadLibraryFunction) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  String get identifier => _definingCompilationUnit.source.encoding;
+
+  @override
+  List<LibraryElement> get importedLibraries {
+    HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
+    for (ImportElement element in _imports) {
+      LibraryElement library = element.importedLibrary;
+      if (library != null) {
+        libraries.add(library);
+      }
+    }
+    return new List.from(libraries);
+  }
+
+  @override
+  List<ImportElement> get imports => _imports;
+
+  /**
+   * Set the specifications of all of the imports defined in this library to the
+   * given list of [imports].
+   */
+  void set imports(List<ImportElement> imports) {
+    for (ImportElement importElement in imports) {
+      (importElement as ImportElementImpl).enclosingElement = this;
+      PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
+      if (prefix != null) {
+        prefix.enclosingElement = this;
+      }
+    }
+    this._imports = imports;
+  }
+
+  @override
+  bool get isBrowserApplication =>
+      entryPoint != null && isOrImportsBrowserLibrary;
+
+  @override
+  bool get isDartCore => name == "dart.core";
+
+  @override
+  bool get isInSdk =>
+      StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x74, 0x2E);
+
+  /**
+   * Return `true` if the receiver directly or indirectly imports the
+   * 'dart:html' libraries.
+   */
+  bool get isOrImportsBrowserLibrary {
+    List<LibraryElement> visited = new List<LibraryElement>();
+    Source htmlLibSource = context.sourceFactory.forUri(DartSdk.DART_HTML);
+    visited.add(this);
+    for (int index = 0; index < visited.length; index++) {
+      LibraryElement library = visited[index];
+      Source source = library.definingCompilationUnit.source;
+      if (source == htmlLibSource) {
+        return true;
+      }
+      for (LibraryElement importedLibrary in library.importedLibraries) {
+        if (!visited.contains(importedLibrary)) {
+          visited.add(importedLibrary);
+        }
+      }
+      for (LibraryElement exportedLibrary in library.exportedLibraries) {
+        if (!visited.contains(exportedLibrary)) {
+          visited.add(exportedLibrary);
+        }
+      }
+    }
+    return false;
+  }
+
+  @override
+  ElementKind get kind => ElementKind.LIBRARY;
+
+  @override
+  LibraryElement get library => this;
+
+  List<LibraryElement> get libraryCycle {
+    if (_libraryCycle != null) {
+      return _libraryCycle;
+    }
+
+    // Global counter for this run of the algorithm
+    int counter = 0;
+    // The discovery times of each library
+    Map<LibraryElementImpl, int> indices = {};
+    // The set of scc candidates
+    Set<LibraryElementImpl> active = new Set();
+    // The stack of discovered elements
+    List<LibraryElementImpl> stack = [];
+    // For a given library that has not yet been processed by this run of the
+    // algorithm, compute the strongly connected components.
+    int scc(LibraryElementImpl library) {
+      int index = counter++;
+      int root = index;
+      indices[library] = index;
+      active.add(library);
+      stack.add(library);
+      void recurse(LibraryElementImpl child) {
+        if (!indices.containsKey(child)) {
+          // We haven't visited this child yet, so recurse on the child,
+          // returning the lowest numbered node reachable from the child.  If
+          // the child can reach a root which is lower numbered than anything
+          // we've reached so far, update the root.
+          root = min(root, scc(child));
+        } else if (active.contains(child)) {
+          // The child has been visited, but has not yet been placed into a
+          // component.  If the child is higher than anything we've seen so far
+          // update the root appropriately.
+          root = min(root, indices[child]);
+        }
+      }
+      // Recurse on all of the children in the import/export graph, filtering
+      // out those for which library cycles have already been computed.
+      library.exportedLibraries
+          .where((l) => l._libraryCycle == null)
+          .forEach(recurse);
+      library.importedLibraries
+          .where((l) => l._libraryCycle == null)
+          .forEach(recurse);
+
+      if (root == index) {
+        // This is the root of a strongly connected component.
+        // Pop the elements, and share the component across all
+        // of the elements.
+        List<LibraryElement> component = <LibraryElement>[];
+        LibraryElementImpl cur = null;
+        do {
+          cur = stack.removeLast();
+          active.remove(cur);
+          component.add(cur);
+          cur._libraryCycle = component;
+        } while (cur != library);
+      }
+      return root;
+    }
+    scc(library);
+    return _libraryCycle;
+  }
+
+  @override
+  FunctionElement get loadLibraryFunction {
+    assert(_loadLibraryFunction != null);
+    return _loadLibraryFunction;
+  }
+
+  @override
+  List<CompilationUnitElement> get parts => _parts;
+
+  /**
+   * Set the compilation units that are included in this library using a `part`
+   * directive to the given list of [parts].
+   */
+  void set parts(List<CompilationUnitElement> parts) {
+    for (CompilationUnitElement compilationUnit in parts) {
+      assert((compilationUnit as CompilationUnitElementImpl).librarySource ==
+          source);
+      (compilationUnit as CompilationUnitElementImpl).enclosingElement = this;
+    }
+    this._parts = parts;
+  }
+
+  @override
+  List<PrefixElement> get prefixes {
+    HashSet<PrefixElement> prefixes = new HashSet<PrefixElement>();
+    for (ImportElement element in _imports) {
+      PrefixElement prefix = element.prefix;
+      if (prefix != null) {
+        prefixes.add(prefix);
+      }
+    }
+    return new List.from(prefixes);
+  }
+
+  @override
+  Source get source {
+    if (_definingCompilationUnit == null) {
+      return null;
+    }
+    return _definingCompilationUnit.source;
+  }
+
+  @override
+  List<CompilationUnitElement> get units {
+    List<CompilationUnitElement> units = new List<CompilationUnitElement>();
+    units.add(_definingCompilationUnit);
+    units.addAll(_parts);
+    return units;
+  }
+
+  @override
+  List<LibraryElement> get visibleLibraries {
+    Set<LibraryElement> visibleLibraries = new Set();
+    _addVisibleLibraries(visibleLibraries, false);
+    return new List.from(visibleLibraries);
+  }
+
+  @override
+  bool operator ==(Object object) =>
+      object is LibraryElementImpl &&
+      _definingCompilationUnit == object.definingCompilationUnit;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
+
+  /**
+   * Create the [FunctionElement] to be returned by [loadLibraryFunction],
+   * using types provided by [typeProvider].
+   */
+  void createLoadLibraryFunction(TypeProvider typeProvider) {
+    FunctionElementImpl function =
+        new FunctionElementImpl(FunctionElement.LOAD_LIBRARY_NAME, -1);
+    function.synthetic = true;
+    function.enclosingElement = this;
+    function.returnType = typeProvider.futureDynamicType;
+    function.type = new FunctionTypeImpl(function);
+    _loadLibraryFunction = function;
+  }
+
+  @override
+  ElementImpl getChild(String identifier) {
+    if ((_definingCompilationUnit as CompilationUnitElementImpl).identifier ==
+        identifier) {
+      return _definingCompilationUnit as CompilationUnitElementImpl;
+    }
+    for (CompilationUnitElement part in _parts) {
+      if ((part as CompilationUnitElementImpl).identifier == identifier) {
+        return part as CompilationUnitElementImpl;
+      }
+    }
+    for (ImportElement importElement in _imports) {
+      if ((importElement as ImportElementImpl).identifier == identifier) {
+        return importElement as ImportElementImpl;
+      }
+    }
+    for (ExportElement exportElement in _exports) {
+      if ((exportElement as ExportElementImpl).identifier == identifier) {
+        return exportElement as ExportElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) {
+    int count = _imports.length;
+    List<ImportElement> importList = new List<ImportElement>();
+    for (int i = 0; i < count; i++) {
+      if (identical(_imports[i].prefix, prefixElement)) {
+        importList.add(_imports[i]);
+      }
+    }
+    return importList;
+  }
+
+  @override
+  ClassElement getType(String className) {
+    ClassElement type = _definingCompilationUnit.getType(className);
+    if (type != null) {
+      return type;
+    }
+    for (CompilationUnitElement part in _parts) {
+      type = part.getType(className);
+      if (type != null) {
+        return type;
+      }
+    }
+    return null;
+  }
+
+  /** Given an update to this library which may have added or deleted edges
+   * in the import/export graph originating from this node only, remove any
+   * cached library cycles in the element model which may have been invalidated.
+   */
+  void invalidateLibraryCycles() {
+    if (_libraryCycle == null) {
+      // We have already invalidated this node, or we have never computed
+      // library cycle information for it.  In the former case, we're done. In
+      // the latter case, this node cannot be reachable from any node for which
+      // we have computed library cycle information.  Therefore, any edges added
+      // or deleted in the update causing this invalidation can only be edges to
+      // nodes which either have no library cycle information (and hence do not
+      // need invalidation), or which do not reach this node by any path.
+      // In either case, no further invalidation is needed.
+      return;
+    }
+    // If we have pre-computed library cycle information, then we must
+    // invalidate the information both on this element, and on certain
+    // other elements.  Edges originating at this node may have been
+    // added or deleted.  A deleted edge that points outside of this cycle
+    // cannot change the cycle information for anything outside of this cycle,
+    // and so it is sufficient to delete the cached library information on this
+    // cycle.  An added edge which points to another node within the cycle
+    // only invalidates the cycle.  An added edge which points to a node earlier
+    // in the topological sort of cycles induces no invalidation (since there
+    // are by definition no back edges from earlier cycles in the topological
+    // order, and hence no possible cycle can have been introduced.  The only
+    // remaining case is that we have added an edge to a node which is later
+    // in the topological sort of cycles.  This can induce cycles, since it
+    // represents a new back edge.  It would be sufficient to invalidate the
+    // cycle information for all nodes that are between the target and the
+    // node in the topological order.  For simplicity, we simply invalidate
+    // all nodes which are reachable from the the source node.
+    // Note that in the invalidation phase, we do not cut off when we encounter
+    // a node with no library cycle information, since we do not know whether
+    // we are in the case where invalidation has already been performed, or we
+    // are in the case where library cycles have simply never been computed from
+    // a newly reachable node.
+    Set<LibraryElementImpl> active = new HashSet();
+    void invalidate(LibraryElementImpl library) {
+      if (!active.add(library)) return;
+      if (library._libraryCycle != null) {
+        library._libraryCycle.forEach(invalidate);
+        library._libraryCycle = null;
+      }
+      library.exportedLibraries.forEach(invalidate);
+      library.importedLibraries.forEach(invalidate);
+    }
+    invalidate(this);
+  }
+
+  @override
+  bool isUpToDate(int timeStamp) {
+    Set<LibraryElement> visitedLibraries = new Set();
+    return _safeIsUpToDate(this, timeStamp, visitedLibraries);
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_definingCompilationUnit, visitor);
+    safelyVisitChildren(_exports, visitor);
+    safelyVisitChildren(_imports, visitor);
+    safelyVisitChildren(_parts, visitor);
+  }
+
+  /**
+   * Recursively fills set of visible libraries for
+   * [getVisibleElementsLibraries].
+   */
+  void _addVisibleLibraries(
+      Set<LibraryElement> visibleLibraries, bool includeExports) {
+    // maybe already processed
+    if (!visibleLibraries.add(this)) {
+      return;
+    }
+    // add imported libraries
+    for (ImportElement importElement in _imports) {
+      LibraryElement importedLibrary = importElement.importedLibrary;
+      if (importedLibrary != null) {
+        (importedLibrary as LibraryElementImpl)
+            ._addVisibleLibraries(visibleLibraries, true);
+      }
+    }
+    // add exported libraries
+    if (includeExports) {
+      for (ExportElement exportElement in _exports) {
+        LibraryElement exportedLibrary = exportElement.exportedLibrary;
+        if (exportedLibrary != null) {
+          (exportedLibrary as LibraryElementImpl)
+              ._addVisibleLibraries(visibleLibraries, true);
+        }
+      }
+    }
+  }
+
+  /**
+   * Return `true` if the given [library] is up to date with respect to the
+   * given [timeStamp]. The set of [visitedLibraries] is used to prevent
+   * infinite recursion in the case of mutually dependent libraries.
+   */
+  static bool _safeIsUpToDate(LibraryElement library, int timeStamp,
+      Set<LibraryElement> visitedLibraries) {
+    if (!visitedLibraries.contains(library)) {
+      visitedLibraries.add(library);
+      AnalysisContext context = library.context;
+      // Check the defining compilation unit.
+      if (timeStamp <
+          context
+              .getModificationStamp(library.definingCompilationUnit.source)) {
+        return false;
+      }
+      // Check the parted compilation units.
+      for (CompilationUnitElement element in library.parts) {
+        if (timeStamp < context.getModificationStamp(element.source)) {
+          return false;
+        }
+      }
+      // Check the imported libraries.
+      for (LibraryElement importedLibrary in library.importedLibraries) {
+        if (!_safeIsUpToDate(importedLibrary, timeStamp, visitedLibraries)) {
+          return false;
+        }
+      }
+      // Check the exported libraries.
+      for (LibraryElement exportedLibrary in library.exportedLibraries) {
+        if (!_safeIsUpToDate(exportedLibrary, timeStamp, visitedLibraries)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+}
+
+/**
+ * A concrete implementation of a [LocalVariableElement].
+ */
+class LocalVariableElementImpl extends VariableElementImpl
+    implements LocalVariableElement {
+  /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+
+  /**
+   * The length of the visible range for this element, or `-1` if this element
+   * does not have a visible range.
+   */
+  int _visibleRangeLength = -1;
+
+  /**
+   * Initialize a newly created method element to have the given [name] and
+   * [offset].
+   */
+  LocalVariableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created local variable element to have the given [name].
+   */
+  LocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  String get identifier {
+    int enclosingOffset =
+        enclosingElement != null ? enclosingElement.nameOffset : 0;
+    int delta = nameOffset - enclosingOffset;
+    return '${super.identifier}@$delta';
+  }
+
+  @override
+  bool get isPotentiallyMutatedInClosure =>
+      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
+
+  @override
+  bool get isPotentiallyMutatedInScope =>
+      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
+
+  @override
+  ElementKind get kind => ElementKind.LOCAL_VARIABLE;
+
+  @override
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitLocalVariableElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(type);
+    buffer.write(" ");
+    buffer.write(displayName);
+  }
+
+  @override
+  VariableDeclaration computeNode() =>
+      getNodeMatching((node) => node is VariableDeclaration);
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in closure.
+   */
+  void markPotentiallyMutatedInClosure() {
+    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
+  }
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in its scope.
+   */
+  void markPotentiallyMutatedInScope() {
+    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
+  }
+
+  /**
+   * Set the visible range for this element to the range starting at the given
+   * [offset] with the given [length].
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+}
+
+/**
+ * A concrete implementation of a [MethodElement].
+ */
+class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
+  /**
+   * Initialize a newly created method element to have the given [name] at the
+   * given [offset].
+   */
+  MethodElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created method element to have the given [name].
+   */
+  MethodElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this method is abstract.
+   */
+  void set abstract(bool isAbstract) {
+    setModifier(Modifier.ABSTRACT, isAbstract);
+  }
+
+  @override
+  String get displayName {
+    String displayName = super.displayName;
+    if ("unary-" == displayName) {
+      return "-";
+    }
+    return displayName;
+  }
+
+  @override
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+
+  @override
+  bool get isOperator {
+    String name = displayName;
+    if (name.isEmpty) {
+      return false;
+    }
+    int first = name.codeUnitAt(0);
+    return !((0x61 <= first && first <= 0x7A) ||
+        (0x41 <= first && first <= 0x5A) ||
+        first == 0x5F ||
+        first == 0x24);
+  }
+
+  @override
+  bool get isStatic => hasModifier(Modifier.STATIC);
+
+  @override
+  ElementKind get kind => ElementKind.METHOD;
+
+  @override
+  String get name {
+    String name = super.name;
+    if (isOperator && name == "-") {
+      if (parameters.length == 0) {
+        return "unary-";
+      }
+    }
+    return super.name;
+  }
+
+  /**
+   * Set whether this method is static.
+   */
+  void set static(bool isStatic) {
+    setModifier(Modifier.STATIC, isStatic);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(displayName);
+    super.appendTo(buffer);
+  }
+
+  @override
+  MethodDeclaration computeNode() =>
+      getNodeMatching((node) => node is MethodDeclaration);
+}
+
+/**
+ * A concrete implementation of a [MultiplyDefinedElement].
+ */
+class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
+  /**
+   * The unique integer identifier of this element.
+   */
+  final int id = ElementImpl._NEXT_ID++;
+
+  /**
+   * The analysis context in which the multiply defined elements are defined.
+   */
+  final AnalysisContext context;
+
+  /**
+   * The name of the conflicting elements.
+   */
+  String _name;
+
+  /**
+   * A list containing all of the elements that conflict.
+   */
+  final List<Element> conflictingElements;
+
+  /**
+   * Initialize a newly created element in the given [context] to represent a
+   * list of [conflictingElements].
+   */
+  MultiplyDefinedElementImpl(this.context, this.conflictingElements) {
+    _name = conflictingElements[0].name;
+  }
+
+  @override
+  String get displayName => _name;
+
+  @override
+  SourceRange get docRange => null;
+
+  @override
+  String get documentationComment => null;
+
+  @override
+  Element get enclosingElement => null;
+
+  @override
+  bool get isDeprecated => false;
+
+  @override
+  bool get isOverride => false;
+
+  @override
+  bool get isPrivate {
+    String name = displayName;
+    if (name == null) {
+      return false;
+    }
+    return Identifier.isPrivateName(name);
+  }
+
+  @override
+  bool get isPublic => !isPrivate;
+
+  @override
+  bool get isSynthetic => true;
+
+  @override
+  ElementKind get kind => ElementKind.ERROR;
+
+  @override
+  LibraryElement get library => null;
+
+  @override
+  ElementLocation get location => null;
+
+  @override
+  List<ElementAnnotation> get metadata => ElementAnnotation.EMPTY_LIST;
+
+  @override
+  String get name => _name;
+
+  @override
+  int get nameLength => displayName != null ? displayName.length : 0;
+
+  @override
+  int get nameOffset => -1;
+
+  @override
+  Source get source => null;
+
+  @override
+  DartType get type => DynamicTypeImpl.instance;
+
+  @override
+  CompilationUnit get unit => null;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitMultiplyDefinedElement(this);
+
+  @override
+  String computeDocumentationComment() => null;
+
+  @override
+  AstNode computeNode() => null;
+
+  @override
+  Element getAncestor(Predicate<Element> predicate) => null;
+
+  @override
+  String getExtendedDisplayName(String shortName) {
+    if (shortName != null) {
+      return shortName;
+    }
+    return displayName;
+  }
+
+  @override
+  bool isAccessibleIn(LibraryElement library) {
+    for (Element element in conflictingElements) {
+      if (element.isAccessibleIn(library)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write("[");
+    int count = conflictingElements.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      (conflictingElements[i] as ElementImpl).appendTo(buffer);
+    }
+    buffer.write("]");
+    return buffer.toString();
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // There are no children to visit
+  }
+
+  /**
+   * Return an element in the given [context] that represents the fact that the
+   * [firstElement] and [secondElement] conflict. (If the elements are the same,
+   * then one of the two will be returned directly.)
+   */
+  static Element fromElements(
+      AnalysisContext context, Element firstElement, Element secondElement) {
+    List<Element> conflictingElements =
+        _computeConflictingElements(firstElement, secondElement);
+    int length = conflictingElements.length;
+    if (length == 0) {
+      return null;
+    } else if (length == 1) {
+      return conflictingElements[0];
+    }
+    return new MultiplyDefinedElementImpl(context, conflictingElements);
+  }
+
+  /**
+   * Add the given [element] to the list of [elements]. If the element is a
+   * multiply-defined element, add all of the conflicting elements that it
+   * represents.
+   */
+  static void _add(HashSet<Element> elements, Element element) {
+    if (element is MultiplyDefinedElementImpl) {
+      for (Element conflictingElement in element.conflictingElements) {
+        elements.add(conflictingElement);
+      }
+    } else {
+      elements.add(element);
+    }
+  }
+
+  /**
+   * Use the given elements to construct a list of conflicting elements. If
+   * either the [firstElement] or [secondElement] are multiply-defined elements
+   * then the conflicting elements they represent will be included in the array.
+   * Otherwise, the element itself will be included.
+   */
+  static List<Element> _computeConflictingElements(
+      Element firstElement, Element secondElement) {
+    HashSet<Element> elements = new HashSet<Element>();
+    _add(elements, firstElement);
+    _add(elements, secondElement);
+    return new List.from(elements);
+  }
+}
+
+/**
+ * A [MethodElementImpl], with the additional information of a list of
+ * [ExecutableElement]s from which this element was composed.
+ */
+class MultiplyInheritedMethodElementImpl extends MethodElementImpl
+    implements MultiplyInheritedExecutableElement {
+  /**
+   * A list the array of executable elements that were used to compose this
+   * element.
+   */
+  List<ExecutableElement> _elements = MethodElement.EMPTY_LIST;
+
+  MultiplyInheritedMethodElementImpl(Identifier name) : super.forNode(name) {
+    synthetic = true;
+  }
+
+  @override
+  List<ExecutableElement> get inheritedElements => _elements;
+
+  void set inheritedElements(List<ExecutableElement> elements) {
+    this._elements = elements;
+  }
+}
+
+/**
+ * A [PropertyAccessorElementImpl], with the additional information of a list of
+ * [ExecutableElement]s from which this element was composed.
+ */
+class MultiplyInheritedPropertyAccessorElementImpl
+    extends PropertyAccessorElementImpl
+    implements MultiplyInheritedExecutableElement {
+  /**
+   * A list the array of executable elements that were used to compose this
+   * element.
+   */
+  List<ExecutableElement> _elements = PropertyAccessorElement.EMPTY_LIST;
+
+  MultiplyInheritedPropertyAccessorElementImpl(Identifier name)
+      : super.forNode(name) {
+    synthetic = true;
+  }
+
+  @override
+  List<ExecutableElement> get inheritedElements => _elements;
+
+  void set inheritedElements(List<ExecutableElement> elements) {
+    this._elements = elements;
+  }
+}
+
+/**
+ * A concrete implementation of a [ParameterElement].
+ */
+class ParameterElementImpl extends VariableElementImpl
+    with ParameterElementMixin
+    implements ParameterElement {
+  /**
+   * A list containing all of the parameters defined by this parameter element.
+   * There will only be parameters if this parameter is a function typed
+   * parameter.
+   */
+  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the type parameters defined for this parameter
+   * element. There will only be parameters if this parameter is a function
+   * typed parameter.
+   */
+  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+
+  /**
+   * The kind of this parameter.
+   */
+  ParameterKind parameterKind;
+
+  /**
+   * The Dart code of the default value.
+   */
+  String _defaultValueCode;
+
+  /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+
+  /**
+   * The length of the visible range for this element, or `-1` if this element
+   * does not have a visible range.
+   */
+  int _visibleRangeLength = -1;
+
+  /**
+   * Initialize a newly created parameter element to have the given [name] and
+   * [offset].
+   */
+  ParameterElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  /**
+   * Initialize a newly created parameter element to have the given [name].
+   */
+  ParameterElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  String get defaultValueCode => _defaultValueCode;
+
+  /**
+   * Set Dart code of the default value.
+   */
+  void set defaultValueCode(String defaultValueCode) {
+    this._defaultValueCode = StringUtilities.intern(defaultValueCode);
+  }
+
+  @override
+  bool get isInitializingFormal => false;
+
+  @override
+  bool get isPotentiallyMutatedInClosure =>
+      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
+
+  @override
+  bool get isPotentiallyMutatedInScope =>
+      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
+
+  @override
+  ElementKind get kind => ElementKind.PARAMETER;
+
+  @override
+  List<ParameterElement> get parameters => _parameters;
+
+  /**
+   * Set the parameters defined by this executable element to the given
+   * [parameters].
+   */
+  void set parameters(List<ParameterElement> parameters) {
+    for (ParameterElement parameter in parameters) {
+      (parameter as ParameterElementImpl).enclosingElement = this;
+    }
+    this._parameters = parameters;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters defined by this parameter element to the given
+   * [typeParameters].
+   */
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement parameter in typeParameters) {
+      (parameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
+  }
+
+  @override
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    String left = "";
+    String right = "";
+    while (true) {
+      if (parameterKind == ParameterKind.NAMED) {
+        left = "{";
+        right = "}";
+      } else if (parameterKind == ParameterKind.POSITIONAL) {
+        left = "[";
+        right = "]";
+      } else if (parameterKind == ParameterKind.REQUIRED) {}
+      break;
+    }
+    buffer.write(left);
+    appendToWithoutDelimiters(buffer);
+    buffer.write(right);
+  }
+
+  @override
+  FormalParameter computeNode() =>
+      getNodeMatching((node) => node is FormalParameter);
+
+  @override
+  ElementImpl getChild(String identifier) {
+    for (ParameterElement parameter in _parameters) {
+      if ((parameter as ParameterElementImpl).identifier == identifier) {
+        return parameter as ParameterElementImpl;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in closure.
+   */
+  void markPotentiallyMutatedInClosure() {
+    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
+  }
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in its scope.
+   */
+  void markPotentiallyMutatedInScope() {
+    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
+  }
+
+  /**
+   * Set the visible range for this element to the range starting at the given
+   * [offset] with the given [length].
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_parameters, visitor);
+  }
+}
+
+/**
+ * A mixin that provides a common implementation for methods defined in
+ * [ParameterElement].
+ */
+abstract class ParameterElementMixin implements ParameterElement {
+  @override
+  void appendToWithoutDelimiters(StringBuffer buffer) {
+    buffer.write(type);
+    buffer.write(" ");
+    buffer.write(displayName);
+    if (defaultValueCode != null) {
+      if (parameterKind == ParameterKind.NAMED) {
+        buffer.write(": ");
+      }
+      if (parameterKind == ParameterKind.POSITIONAL) {
+        buffer.write(" = ");
+      }
+      buffer.write(defaultValueCode);
+    }
+  }
+}
+
+/**
+ * A concrete implementation of a [PrefixElement].
+ */
+class PrefixElementImpl extends ElementImpl implements PrefixElement {
+  /**
+   * A list containing all of the libraries that are imported using this prefix.
+   */
+  List<LibraryElement> _importedLibraries = LibraryElement.EMPTY_LIST;
+
+  /**
+   * Initialize a newly created method element to have the given [name] and
+   * [offset].
+   */
+  PrefixElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  /**
+   * Initialize a newly created prefix element to have the given [name].
+   */
+  PrefixElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  LibraryElement get enclosingElement =>
+      super.enclosingElement as LibraryElement;
+
+  @override
+  String get identifier => "_${super.identifier}";
+
+  @override
+  List<LibraryElement> get importedLibraries => _importedLibraries;
+
+  /**
+   * Set the libraries that are imported using this prefix to the given
+   * [libraries].
+   */
+  void set importedLibraries(List<LibraryElement> libraries) {
+    for (LibraryElement library in libraries) {
+      (library as LibraryElementImpl).enclosingElement = this;
+    }
+    _importedLibraries = libraries;
+  }
+
+  @override
+  ElementKind get kind => ElementKind.PREFIX;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitPrefixElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write("as ");
+    super.appendTo(buffer);
+  }
+}
+
+/**
+ * A concrete implementation of a [PropertyAccessorElement].
+ */
+class PropertyAccessorElementImpl extends ExecutableElementImpl
+    implements PropertyAccessorElement {
+  /**
+   * The variable associated with this accessor.
+   */
+  PropertyInducingElement variable;
+
+  /**
+   * Initialize a newly created property accessor element to have the given
+   * [name] and [offset].
+   */
+  PropertyAccessorElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created property accessor element to have the given
+   * [name].
+   */
+  PropertyAccessorElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Initialize a newly created synthetic property accessor element to be
+   * associated with the given [variable].
+   */
+  PropertyAccessorElementImpl.forVariable(PropertyInducingElementImpl variable)
+      : super(variable.name, variable.nameOffset) {
+    this.variable = variable;
+    static = variable.isStatic;
+    synthetic = true;
+  }
+
+  /**
+   * Set whether this accessor is abstract.
+   */
+  void set abstract(bool isAbstract) {
+    setModifier(Modifier.ABSTRACT, isAbstract);
+  }
+
+  @override
+  PropertyAccessorElement get correspondingGetter {
+    if (isGetter || variable == null) {
+      return null;
+    }
+    return variable.getter;
+  }
+
+  @override
+  PropertyAccessorElement get correspondingSetter {
+    if (isSetter || variable == null) {
+      return null;
+    }
+    return variable.setter;
+  }
+
+  /**
+   * Set whether this accessor is a getter.
+   */
+  void set getter(bool isGetter) {
+    setModifier(Modifier.GETTER, isGetter);
+  }
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash2(super.hashCode, isGetter ? 1 : 2);
+
+  @override
+  String get identifier {
+    String name = displayName;
+    String suffix = isGetter ? "?" : "=";
+    return "$name$suffix";
+  }
+
+  @override
+  bool get isGetter => hasModifier(Modifier.GETTER);
+
+  @override
+  bool get isSetter => hasModifier(Modifier.SETTER);
+
+  @override
+  bool get isStatic => hasModifier(Modifier.STATIC);
+
+  @override
+  ElementKind get kind {
+    if (isGetter) {
+      return ElementKind.GETTER;
+    }
+    return ElementKind.SETTER;
+  }
+
+  @override
+  String get name {
+    if (isSetter) {
+      return "${super.name}=";
+    }
+    return super.name;
+  }
+
+  /**
+   * Set whether this accessor is a setter.
+   */
+  void set setter(bool isSetter) {
+    setModifier(Modifier.SETTER, isSetter);
+  }
+
+  /**
+   * Set whether this accessor is static.
+   */
+  void set static(bool isStatic) {
+    setModifier(Modifier.STATIC, isStatic);
+  }
+
+  @override
+  bool operator ==(Object object) =>
+      super == object &&
+      isGetter == (object as PropertyAccessorElement).isGetter;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(isGetter ? "get " : "set ");
+    buffer.write(variable.displayName);
+    super.appendTo(buffer);
+  }
+
+  @override
+  AstNode computeNode() {
+    if (isSynthetic) {
+      return null;
+    }
+    if (enclosingElement is ClassElement) {
+      return getNodeMatching((node) => node is MethodDeclaration);
+    }
+    if (enclosingElement is CompilationUnitElement) {
+      return getNodeMatching((node) => node is FunctionDeclaration);
+    }
+    return null;
+  }
+}
+
+/**
+ * A concrete implementation of a [PropertyInducingElement].
+ */
+abstract class PropertyInducingElementImpl extends VariableElementImpl
+    implements PropertyInducingElement {
+  /**
+   * The getter associated with this element.
+   */
+  PropertyAccessorElement getter;
+
+  /**
+   * The setter associated with this element, or `null` if the element is
+   * effectively `final` and therefore does not have a setter associated with
+   * it.
+   */
+  PropertyAccessorElement setter;
+
+  /**
+   * The propagated type of this variable, or `null` if type propagation has not
+   * been performed.
+   */
+  DartType propagatedType;
+
+  /**
+   * Initialize a newly created synthetic element to have the given [name] and
+   * [offset].
+   */
+  PropertyInducingElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created element to have the given [name].
+   */
+  PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
+}
+
+/**
+ * A concrete implementation of a [ShowElementCombinator].
+ */
+class ShowElementCombinatorImpl implements ShowElementCombinator {
+  /**
+   * The names that are to be made visible in the importing library if they are
+   * defined in the imported library.
+   */
+  List<String> shownNames = StringUtilities.EMPTY_ARRAY;
+
+  /**
+   * The offset of the character immediately following the last character of
+   * this node.
+   */
+  int end = -1;
+
+  /**
+   * The offset of the 'show' keyword of this element.
+   */
+  int offset = 0;
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write("show ");
+    int count = shownNames.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      buffer.write(shownNames[i]);
+    }
+    return buffer.toString();
+  }
+}
+
+/**
+ * A concrete implementation of a [TopLevelVariableElement].
+ */
+class TopLevelVariableElementImpl extends PropertyInducingElementImpl
+    implements TopLevelVariableElement {
+  /**
+   * Initialize a newly created synthetic top-level variable element to have the
+   * given [name] and [offset].
+   */
+  TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created top-level variable element to have the given
+   * [name].
+   */
+  TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  bool get isStatic => true;
+
+  @override
+  ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
+
+  @override
+  VariableDeclaration computeNode() =>
+      getNodeMatching((node) => node is VariableDeclaration);
+}
+
+/**
+ * A concrete implementation of a [TypeParameterElement].
+ */
+class TypeParameterElementImpl extends ElementImpl
+    implements TypeParameterElement {
+  /**
+   * The type defined by this type parameter.
+   */
+  TypeParameterType type;
+
+  /**
+   * The type representing the bound associated with this parameter, or `null`
+   * if this parameter does not have an explicit bound.
+   */
+  DartType bound;
+
+  /**
+   * Initialize a newly created method element to have the given [name] and
+   * [offset].
+   */
+  TypeParameterElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created type parameter element to have the given [name].
+   */
+  TypeParameterElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  ElementKind get kind => ElementKind.TYPE_PARAMETER;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitTypeParameterElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(displayName);
+    if (bound != null) {
+      buffer.write(" extends ");
+      buffer.write(bound);
+    }
+  }
+}
+
+/**
+ * A concrete implementation of a [UriReferencedElement].
+ */
+abstract class UriReferencedElementImpl extends ElementImpl
+    implements UriReferencedElement {
+  /**
+   * The offset of the URI in the file, may be `-1` if synthetic.
+   */
+  int uriOffset = -1;
+
+  /**
+   * The offset of the character immediately following the last character of
+   * this node's URI, may be `-1` if synthetic.
+   */
+  int uriEnd = -1;
+
+  /**
+   * The URI that is specified by this directive.
+   */
+  String uri;
+
+  /**
+   * Initialize a newly created import element to have the given [name] and
+   * [offset]. The offset may be `-1` if the element is synthetic.
+   */
+  UriReferencedElementImpl(String name, int offset) : super(name, offset);
+}
+
+/**
+ * A concrete implementation of a [VariableElement].
+ */
+abstract class VariableElementImpl extends ElementImpl
+    implements VariableElement {
+  /**
+   * The declared type of this variable.
+   */
+  DartType type;
+
+  /**
+   * A synthetic function representing this variable's initializer, or `null` if
+   * this variable does not have an initializer.
+   */
+  FunctionElement _initializer;
+
+  /**
+   * Initialize a newly created variable element to have the given [name] and
+   * [offset].
+   */
+  VariableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created variable element to have the given [name].
+   */
+  VariableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this variable is const.
+   */
+  void set const3(bool isConst) {
+    setModifier(Modifier.CONST, isConst);
+  }
+
+  /**
+   * If this element represents a constant variable, and it has an initializer,
+   * a copy of the initializer for the constant.  Otherwise `null`.
+   *
+   * Note that in correct Dart code, all constant variables must have
+   * initializers.  However, analyzer also needs to handle incorrect Dart code,
+   * in which case there might be some constant variables that lack
+   * initializers.
+   */
+  Expression get constantInitializer => null;
+
+  @override
+  DartObject get constantValue => null;
+
+  /**
+   * Return the result of evaluating this variable's initializer as a
+   * compile-time constant expression, or `null` if this variable is not a
+   * 'const' variable, if it does not have an initializer, or if the compilation
+   * unit containing the variable has not been resolved.
+   */
+  EvaluationResultImpl get evaluationResult => null;
+
+  /**
+   * Set the result of evaluating this variable's initializer as a compile-time
+   * constant expression to the given [result].
+   */
+  void set evaluationResult(EvaluationResultImpl result) {
+    throw new IllegalStateException(
+        "Invalid attempt to set a compile-time constant result");
+  }
+
+  /**
+   * Set whether this variable is final.
+   */
+  void set final2(bool isFinal) {
+    setModifier(Modifier.FINAL, isFinal);
+  }
+
+  @override
+  bool get hasImplicitType => hasModifier(Modifier.IMPLICIT_TYPE);
+
+  /**
+   * Set whether this variable element has an implicit type.
+   */
+  void set hasImplicitType(bool hasImplicitType) {
+    setModifier(Modifier.IMPLICIT_TYPE, hasImplicitType);
+  }
+
+  @override
+  FunctionElement get initializer => _initializer;
+
+  /**
+   * Set the function representing this variable's initializer to the given
+   * [function].
+   */
+  void set initializer(FunctionElement function) {
+    if (function != null) {
+      (function as FunctionElementImpl).enclosingElement = this;
+    }
+    this._initializer = function;
+  }
+
+  @override
+  bool get isConst => hasModifier(Modifier.CONST);
+
+  @override
+  bool get isFinal => hasModifier(Modifier.FINAL);
+
+  @override
+  bool get isPotentiallyMutatedInClosure => false;
+
+  @override
+  bool get isPotentiallyMutatedInScope => false;
+
+  @override
+  bool get isStatic => hasModifier(Modifier.STATIC);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(type);
+    buffer.write(" ");
+    buffer.write(displayName);
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_initializer, visitor);
+  }
+}
+
+/**
+ * A visitor that visit all the elements recursively and fill the given [map].
+ */
+class _BuildOffsetToElementMap extends GeneralizingElementVisitor {
+  final Map<int, Element> map;
+
+  _BuildOffsetToElementMap(this.map);
+
+  @override
+  void visitElement(Element element) {
+    int offset = element.nameOffset;
+    if (offset != -1) {
+      map[offset] = element;
+    }
+    super.visitElement(element);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
new file mode 100644
index 0000000..75dcee6
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -0,0 +1,968 @@
+// 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 analyzer.src.dart.element.member;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart'
+    show DartObject, EvaluationResultImpl;
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, AnalysisEngine, AnalysisException;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * A constructor element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+class ConstructorMember extends ExecutableMember implements ConstructorElement {
+  /**
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType]. If [type] is passed, it
+   * represents the full type of the member, and will take precedence over
+   * the [definingType].
+   */
+  ConstructorMember(ConstructorElement baseElement, InterfaceType definingType,
+      [FunctionType type])
+      : super(baseElement, definingType, type);
+
+  @override
+  ConstructorElement get baseElement => super.baseElement as ConstructorElement;
+
+  @override
+  InterfaceType get definingType => super.definingType as InterfaceType;
+
+  @override
+  ClassElement get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  bool get isConst => baseElement.isConst;
+
+  @override
+  bool get isDefaultConstructor => baseElement.isDefaultConstructor;
+
+  @override
+  bool get isFactory => baseElement.isFactory;
+
+  @override
+  int get nameEnd => baseElement.nameEnd;
+
+  @override
+  int get periodOffset => baseElement.periodOffset;
+
+  @override
+  ConstructorElement get redirectedConstructor =>
+      from(baseElement.redirectedConstructor, definingType);
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
+
+  @override
+  ConstructorDeclaration computeNode() => baseElement.computeNode();
+
+  @override
+  String toString() {
+    ConstructorElement baseElement = this.baseElement;
+    List<ParameterElement> parameters = this.parameters;
+    FunctionType type = this.type;
+    StringBuffer buffer = new StringBuffer();
+    buffer.write(baseElement.enclosingElement.displayName);
+    String name = displayName;
+    if (name != null && !name.isEmpty) {
+      buffer.write(".");
+      buffer.write(name);
+    }
+    buffer.write("(");
+    int parameterCount = parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      buffer.write(parameters[i]);
+    }
+    buffer.write(")");
+    if (type != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(type.returnType);
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * If the given [constructor]'s type is different when any type parameters
+   * from the defining type's declaration are replaced with the actual type
+   * arguments from the [definingType], create a constructor member representing
+   * the given constructor. Return the member that was created, or the original
+   * constructor if no member was created.
+   */
+  static ConstructorElement from(
+      ConstructorElement constructor, InterfaceType definingType) {
+    if (constructor == null || definingType.typeArguments.length == 0) {
+      return constructor;
+    }
+    FunctionType baseType = constructor.type;
+    if (baseType == null) {
+      // TODO(brianwilkerson) We need to understand when this can happen.
+      return constructor;
+    }
+    List<DartType> argumentTypes = definingType.typeArguments;
+    List<DartType> parameterTypes = definingType.element.type.typeArguments;
+    FunctionType substitutedType =
+        baseType.substitute2(argumentTypes, parameterTypes);
+    if (baseType == substitutedType) {
+      return constructor;
+    }
+    return new ConstructorMember(constructor, definingType, substitutedType);
+  }
+}
+
+/**
+ * An executable element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+abstract class ExecutableMember extends Member implements ExecutableElement {
+  @override
+  final FunctionType type;
+
+  /**
+   * Initialize a newly created element to represent a callable element (like a
+   * method or function or property), based on the [baseElement], defined by the
+   * [definingType]. If [type] is passed, it represents the full type of the
+   * member, and will take precedence over the [definingType].
+   */
+  ExecutableMember(ExecutableElement baseElement, InterfaceType definingType,
+      [FunctionType type])
+      : type = type ??
+            baseElement.type.substitute2(definingType.typeArguments,
+                TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
+        super(baseElement, definingType);
+
+  @override
+  ExecutableElement get baseElement => super.baseElement as ExecutableElement;
+
+  @override
+  List<FunctionElement> get functions {
+    //
+    // Elements within this element should have type parameters substituted,
+    // just like this element.
+    //
+    throw new UnsupportedOperationException();
+//    return getBaseElement().getFunctions();
+  }
+
+  @override
+  bool get hasImplicitReturnType => baseElement.hasImplicitReturnType;
+
+  @override
+  bool get isAbstract => baseElement.isAbstract;
+
+  @override
+  bool get isAsynchronous => baseElement.isAsynchronous;
+
+  @override
+  bool get isExternal => baseElement.isExternal;
+
+  @override
+  bool get isGenerator => baseElement.isGenerator;
+
+  @override
+  bool get isOperator => baseElement.isOperator;
+
+  @override
+  bool get isStatic => baseElement.isStatic;
+
+  @override
+  bool get isSynchronous => baseElement.isSynchronous;
+
+  @override
+  List<LabelElement> get labels => baseElement.labels;
+
+  @override
+  List<LocalVariableElement> get localVariables {
+    //
+    // Elements within this element should have type parameters substituted,
+    // just like this element.
+    //
+    throw new UnsupportedOperationException();
+//    return getBaseElement().getLocalVariables();
+  }
+
+  @override
+  List<ParameterElement> get parameters => type.parameters;
+
+  @override
+  DartType get returnType => type.returnType;
+
+  @override
+  List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // TODO(brianwilkerson) We need to finish implementing the accessors used
+    // below so that we can safely invoke them.
+    super.visitChildren(visitor);
+    safelyVisitChildren(baseElement.functions, visitor);
+    safelyVisitChildren(labels, visitor);
+    safelyVisitChildren(baseElement.localVariables, visitor);
+    safelyVisitChildren(parameters, visitor);
+  }
+}
+
+/**
+ * A parameter element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+class FieldFormalParameterMember extends ParameterMember
+    implements FieldFormalParameterElement {
+  /**
+   * Initialize a newly created element to represent a field formal parameter,
+   * based on the [baseElement], defined by the [definingType]. If [type]
+   * is passed it will be used as the substituted type for this member.
+   */
+  FieldFormalParameterMember(
+      FieldFormalParameterElement baseElement, ParameterizedType definingType,
+      [DartType type])
+      : super(baseElement, definingType, type);
+
+  @override
+  FieldElement get field {
+    FieldElement field = (baseElement as FieldFormalParameterElement).field;
+    if (field is FieldElement) {
+      return FieldMember.from(
+          field, substituteFor(field.enclosingElement.type));
+    }
+    return field;
+  }
+
+  @override
+  accept(ElementVisitor visitor) =>
+      visitor.visitFieldFormalParameterElement(this);
+}
+
+/**
+ * A field element defined in a parameterized type where the values of the type
+ * parameters are known.
+ */
+class FieldMember extends VariableMember implements FieldElement {
+  /**
+   * Initialize a newly created element to represent a field, based on the
+   * [baseElement], defined by the [definingType].
+   */
+  FieldMember(FieldElement baseElement, InterfaceType definingType)
+      : super(baseElement, definingType);
+
+  @override
+  FieldElement get baseElement => super.baseElement as FieldElement;
+
+  @override
+  ClassElement get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  PropertyAccessorElement get getter =>
+      PropertyAccessorMember.from(baseElement.getter, definingType);
+
+  @override
+  bool get isEnumConstant => baseElement.isEnumConstant;
+
+  @override
+  DartType get propagatedType => substituteFor(baseElement.propagatedType);
+
+  @override
+  PropertyAccessorElement get setter =>
+      PropertyAccessorMember.from(baseElement.setter, definingType);
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
+
+  @override
+  VariableDeclaration computeNode() => baseElement.computeNode();
+
+  @override
+  String toString() => '$type $displayName';
+
+  /**
+   * If the given [field]'s type is different when any type parameters from the
+   * defining type's declaration are replaced with the actual type arguments
+   * from the [definingType], create a field member representing the given
+   * field. Return the member that was created, or the base field if no member
+   * was created.
+   */
+  static FieldElement from(FieldElement field, ParameterizedType definingType) {
+    if (!_isChangedByTypeSubstitution(field, definingType)) {
+      return field;
+    }
+    // TODO(brianwilkerson) Consider caching the substituted type in the
+    // instance. It would use more memory but speed up some operations.
+    // We need to see how often the type is being re-computed.
+    return new FieldMember(field, definingType);
+  }
+
+  /**
+   * Determine whether the given [field]'s type is changed when type parameters
+   * from the [definingType]'s declaration are replaced with the actual type
+   * arguments from the defining type.
+   */
+  static bool _isChangedByTypeSubstitution(
+      FieldElement field, ParameterizedType definingType) {
+    List<DartType> argumentTypes = definingType.typeArguments;
+    if (field != null && argumentTypes.length != 0) {
+      DartType baseType = field.type;
+      List<DartType> parameterTypes =
+          TypeParameterTypeImpl.getTypes(definingType.typeParameters);
+      if (baseType != null) {
+        DartType substitutedType =
+            baseType.substitute2(argumentTypes, parameterTypes);
+        if (baseType != substitutedType) {
+          return true;
+        }
+      }
+      // If the field has a propagated type, then we need to check whether the
+      // propagated type needs substitution.
+      DartType basePropagatedType = field.propagatedType;
+      if (basePropagatedType != null) {
+        DartType substitutedPropagatedType =
+            basePropagatedType.substitute2(argumentTypes, parameterTypes);
+        if (basePropagatedType != substitutedPropagatedType) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * Deprecated: this type is no longer used. Use
+ * [MethodInvocation.staticInvokeType] to get the instantiated type of a generic
+ * method invocation.
+ *
+ * An element of a generic function, where the type parameters are known.
+ */
+// TODO(jmesserly): the term "function member" is a bit weird, but it allows
+// a certain consistency.
+@deprecated
+class FunctionMember extends ExecutableMember implements FunctionElement {
+  /**
+   * Initialize a newly created element to represent a function, based on the
+   * [baseElement], with the corresponding function [type].
+   */
+  @deprecated
+  FunctionMember(FunctionElement baseElement, [DartType type])
+      : super(baseElement, null, type);
+
+  @override
+  FunctionElement get baseElement => super.baseElement as FunctionElement;
+
+  @override
+  Element get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  bool get isEntryPoint => baseElement.isEntryPoint;
+
+  @override
+  SourceRange get visibleRange => baseElement.visibleRange;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
+
+  @override
+  FunctionDeclaration computeNode() => baseElement.computeNode();
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write(baseElement.displayName);
+    (type as FunctionTypeImpl).appendTo(buffer);
+    return buffer.toString();
+  }
+
+  /**
+   * If the given [method]'s type is different when any type parameters from the
+   * defining type's declaration are replaced with the actual type arguments
+   * from the [definingType], create a method member representing the given
+   * method. Return the member that was created, or the base method if no member
+   * was created.
+   */
+  static MethodElement from(
+      MethodElement method, ParameterizedType definingType) {
+    if (method == null || definingType.typeArguments.length == 0) {
+      return method;
+    }
+    FunctionType baseType = method.type;
+    List<DartType> argumentTypes = definingType.typeArguments;
+    List<DartType> parameterTypes =
+        TypeParameterTypeImpl.getTypes(definingType.typeParameters);
+    FunctionType substitutedType =
+        baseType.substitute2(argumentTypes, parameterTypes);
+    if (baseType == substitutedType) {
+      return method;
+    }
+    return new MethodMember(method, definingType, substitutedType);
+  }
+}
+
+/**
+ * An element defined in a parameterized type where the values of the type
+ * parameters are known.
+ */
+abstract class Member implements Element {
+  /**
+   * The element on which the parameterized element was created.
+   */
+  final Element _baseElement;
+
+  /**
+   * The type in which the element is defined.
+   */
+  final ParameterizedType _definingType;
+
+  /**
+   * Initialize a newly created element to represent a member, based on the
+   * [baseElement], defined by the [definingType].
+   */
+  Member(this._baseElement, this._definingType);
+
+  /**
+   * Return the element on which the parameterized element was created.
+   */
+  Element get baseElement => _baseElement;
+
+  @override
+  AnalysisContext get context => _baseElement.context;
+
+  /**
+   * Return the type in which the element is defined.
+   */
+  ParameterizedType get definingType => _definingType;
+
+  @override
+  String get displayName => _baseElement.displayName;
+
+  @deprecated
+  @override
+  SourceRange get docRange => _baseElement.docRange;
+
+  @override
+  String get documentationComment => _baseElement.documentationComment;
+
+  int get id => _baseElement.id;
+
+  @override
+  bool get isDeprecated => _baseElement.isDeprecated;
+
+  @override
+  bool get isOverride => _baseElement.isOverride;
+
+  @override
+  bool get isPrivate => _baseElement.isPrivate;
+
+  @override
+  bool get isPublic => _baseElement.isPublic;
+
+  @override
+  bool get isSynthetic => _baseElement.isSynthetic;
+
+  @override
+  ElementKind get kind => _baseElement.kind;
+
+  @override
+  LibraryElement get library => _baseElement.library;
+
+  @override
+  ElementLocation get location => _baseElement.location;
+
+  @override
+  List<ElementAnnotation> get metadata => _baseElement.metadata;
+
+  @override
+  String get name => _baseElement.name;
+
+  @override
+  int get nameLength => _baseElement.nameLength;
+
+  @override
+  int get nameOffset => _baseElement.nameOffset;
+
+  @override
+  Source get source => _baseElement.source;
+
+  @override
+  CompilationUnit get unit => _baseElement.unit;
+
+  @override
+  String computeDocumentationComment() => documentationComment;
+
+  @override
+  AstNode computeNode() => _baseElement.computeNode();
+
+  @override
+  Element getAncestor(Predicate<Element> predicate) =>
+      baseElement.getAncestor(predicate);
+
+  @override
+  String getExtendedDisplayName(String shortName) =>
+      _baseElement.getExtendedDisplayName(shortName);
+
+  @override
+  bool isAccessibleIn(LibraryElement library) =>
+      _baseElement.isAccessibleIn(library);
+
+  /**
+   * If the given [child] is not `null`, use the given [visitor] to visit it.
+   */
+  void safelyVisitChild(Element child, ElementVisitor visitor) {
+    // TODO(brianwilkerson) Make this private
+    if (child != null) {
+      child.accept(visitor);
+    }
+  }
+
+  /**
+   * Use the given [visitor] to visit all of the [children].
+   */
+  void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
+    // TODO(brianwilkerson) Make this private
+    if (children != null) {
+      for (Element child in children) {
+        child.accept(visitor);
+      }
+    }
+  }
+
+  /**
+   * Return the type that results from replacing the type parameters in the
+   * given [type] with the type arguments associated with this member.
+   */
+  DartType substituteFor(DartType type) {
+    if (type == null) {
+      return null;
+    }
+    List<DartType> argumentTypes = _definingType.typeArguments;
+    List<DartType> parameterTypes =
+        TypeParameterTypeImpl.getTypes(_definingType.typeParameters);
+    return type.substitute2(argumentTypes, parameterTypes);
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // There are no children to visit
+  }
+}
+
+/**
+ * A method element defined in a parameterized type where the values of the type
+ * parameters are known.
+ */
+class MethodMember extends ExecutableMember implements MethodElement {
+  /**
+   * Initialize a newly created element to represent a method, based on the
+   * [baseElement], defined by the [definingType]. If [type] is passed, it
+   * represents the full type of the member, and will take precedence over
+   * the [definingType].
+   */
+  MethodMember(MethodElement baseElement, InterfaceType definingType,
+      [DartType type])
+      : super(baseElement, definingType, type);
+
+  @override
+  MethodElement get baseElement => super.baseElement as MethodElement;
+
+  @override
+  ClassElement get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
+
+  @override
+  MethodDeclaration computeNode() => baseElement.computeNode();
+
+  @override
+  String toString() {
+    MethodElement baseElement = this.baseElement;
+    List<ParameterElement> parameters = this.parameters;
+    FunctionType type = this.type;
+    StringBuffer buffer = new StringBuffer();
+    buffer.write(baseElement.enclosingElement.displayName);
+    buffer.write(".");
+    buffer.write(baseElement.displayName);
+    buffer.write("(");
+    int parameterCount = parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      buffer.write(parameters[i]);
+    }
+    buffer.write(")");
+    if (type != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(type.returnType);
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * If the given [method]'s type is different when any type parameters from the
+   * defining type's declaration are replaced with the actual type arguments
+   * from the [definingType], create a method member representing the given
+   * method. Return the member that was created, or the base method if no member
+   * was created.
+   */
+  static MethodElement from(MethodElement method, InterfaceType definingType) {
+    if (method == null || definingType.typeArguments.length == 0) {
+      return method;
+    }
+    FunctionType baseType = method.type;
+    List<DartType> argumentTypes = definingType.typeArguments;
+    List<DartType> parameterTypes = definingType.element.type.typeArguments;
+    FunctionType substitutedType =
+        baseType.substitute2(argumentTypes, parameterTypes);
+    if (baseType == substitutedType) {
+      return method;
+    }
+    return new MethodMember(method, definingType, substitutedType);
+  }
+}
+
+/**
+ * A parameter element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+class ParameterMember extends VariableMember
+    with ParameterElementMixin
+    implements ParameterElement {
+  /**
+   * Initialize a newly created element to represent a parameter, based on the
+   * [baseElement], defined by the [definingType]. If [type] is passed it will
+   * represent the already substituted type.
+   */
+  ParameterMember(ParameterElement baseElement, ParameterizedType definingType,
+      [DartType type])
+      : super._(baseElement, definingType, type);
+
+  @override
+  ParameterElement get baseElement => super.baseElement as ParameterElement;
+
+  @override
+  String get defaultValueCode => baseElement.defaultValueCode;
+
+  @override
+  Element get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  int get hashCode => baseElement.hashCode;
+
+  @override
+  bool get isInitializingFormal => baseElement.isInitializingFormal;
+
+  @override
+  ParameterKind get parameterKind => baseElement.parameterKind;
+
+  @override
+  List<ParameterElement> get parameters {
+    DartType type = this.type;
+    if (type is FunctionType) {
+      return type.parameters;
+    }
+    return ParameterElement.EMPTY_LIST;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
+
+  @override
+  SourceRange get visibleRange => baseElement.visibleRange;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
+
+  @override
+  FormalParameter computeNode() => baseElement.computeNode();
+
+  @override
+  Element getAncestor(Predicate<Element> predicate) {
+    Element element = baseElement.getAncestor(predicate);
+    ParameterizedType definingType = this.definingType;
+    if (definingType is InterfaceType) {
+      InterfaceType definingInterfaceType = definingType;
+      if (element is ConstructorElement) {
+        return ConstructorMember.from(element, definingInterfaceType);
+      } else if (element is MethodElement) {
+        return MethodMember.from(element, definingInterfaceType);
+      } else if (element is PropertyAccessorElement) {
+        return PropertyAccessorMember.from(element, definingInterfaceType);
+      }
+    }
+    return element;
+  }
+
+  @override
+  String toString() {
+    ParameterElement baseElement = this.baseElement;
+    String left = "";
+    String right = "";
+    while (true) {
+      if (baseElement.parameterKind == ParameterKind.NAMED) {
+        left = "{";
+        right = "}";
+      } else if (baseElement.parameterKind == ParameterKind.POSITIONAL) {
+        left = "[";
+        right = "]";
+      } else if (baseElement.parameterKind == ParameterKind.REQUIRED) {}
+      break;
+    }
+    return '$left$type ${baseElement.displayName}$right';
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(parameters, visitor);
+  }
+
+  /**
+   * If the given [parameter]'s type is different when any type parameters from
+   * the defining type's declaration are replaced with the actual type
+   * arguments from the [definingType], create a parameter member representing
+   * the given parameter. Return the member that was created, or the base
+   * parameter if no member was created.
+   */
+  static ParameterElement from(
+      ParameterElement parameter, ParameterizedType definingType) {
+    if (parameter == null || definingType.typeArguments.length == 0) {
+      return parameter;
+    }
+    // Check if parameter type depends on defining type type arguments.
+    // It is possible that we did not resolve field formal parameter yet,
+    // so skip this check for it.
+    if (parameter is FieldFormalParameterElement) {
+      return new FieldFormalParameterMember(parameter, definingType);
+    } else {
+      DartType baseType = parameter.type;
+      List<DartType> argumentTypes = definingType.typeArguments;
+      List<DartType> parameterTypes =
+          TypeParameterTypeImpl.getTypes(definingType.typeParameters);
+      DartType substitutedType =
+          baseType.substitute2(argumentTypes, parameterTypes);
+      if (baseType == substitutedType) {
+        return parameter;
+      }
+      return new ParameterMember(parameter, definingType, substitutedType);
+    }
+  }
+}
+
+/**
+ * A property accessor element defined in a parameterized type where the values
+ * of the type parameters are known.
+ */
+class PropertyAccessorMember extends ExecutableMember
+    implements PropertyAccessorElement {
+  /**
+   * Initialize a newly created element to represent a property, based on the
+   * [baseElement], defined by the [definingType].
+   */
+  PropertyAccessorMember(
+      PropertyAccessorElement baseElement, InterfaceType definingType)
+      : super(baseElement, definingType);
+
+  @override
+  PropertyAccessorElement get baseElement =>
+      super.baseElement as PropertyAccessorElement;
+
+  @override
+  PropertyAccessorElement get correspondingGetter =>
+      from(baseElement.correspondingGetter, definingType);
+
+  @override
+  PropertyAccessorElement get correspondingSetter =>
+      from(baseElement.correspondingSetter, definingType);
+
+  @override
+  InterfaceType get definingType => super.definingType as InterfaceType;
+
+  @override
+  Element get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  bool get isGetter => baseElement.isGetter;
+
+  @override
+  bool get isSetter => baseElement.isSetter;
+
+  @override
+  PropertyInducingElement get variable {
+    PropertyInducingElement variable = baseElement.variable;
+    if (variable is FieldElement) {
+      return FieldMember.from(variable, definingType);
+    }
+    return variable;
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
+
+  @override
+  String toString() {
+    PropertyAccessorElement baseElement = this.baseElement;
+    List<ParameterElement> parameters = this.parameters;
+    FunctionType type = this.type;
+    StringBuffer builder = new StringBuffer();
+    if (isGetter) {
+      builder.write("get ");
+    } else {
+      builder.write("set ");
+    }
+    builder.write(baseElement.enclosingElement.displayName);
+    builder.write(".");
+    builder.write(baseElement.displayName);
+    builder.write("(");
+    int parameterCount = parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        builder.write(", ");
+      }
+      builder.write(parameters[i]);
+    }
+    builder.write(")");
+    if (type != null) {
+      builder.write(ElementImpl.RIGHT_ARROW);
+      builder.write(type.returnType);
+    }
+    return builder.toString();
+  }
+
+  /**
+   * If the given [accessor]'s type is different when any type parameters from
+   * the defining type's declaration are replaced with the actual type
+   * arguments from the [definingType], create an accessor member representing
+   * the given accessor. Return the member that was created, or the base
+   * accessor if no member was created.
+   */
+  static PropertyAccessorElement from(
+      PropertyAccessorElement accessor, InterfaceType definingType) {
+    if (!_isChangedByTypeSubstitution(accessor, definingType)) {
+      return accessor;
+    }
+    // TODO(brianwilkerson) Consider caching the substituted type in the
+    // instance. It would use more memory but speed up some operations.
+    // We need to see how often the type is being re-computed.
+    return new PropertyAccessorMember(accessor, definingType);
+  }
+
+  /**
+   * Determine whether the given property [accessor]'s type is changed when type
+   * parameters from the defining type's declaration are replaced with the
+   * actual type arguments from the [definingType].
+   */
+  static bool _isChangedByTypeSubstitution(
+      PropertyAccessorElement accessor, InterfaceType definingType) {
+    List<DartType> argumentTypes = definingType.typeArguments;
+    if (accessor != null && argumentTypes.length != 0) {
+      FunctionType baseType = accessor.type;
+      if (baseType == null) {
+        AnalysisEngine.instance.logger.logInformation(
+            'Type of $accessor is null in PropertyAccessorMember._isChangedByTypeSubstitution');
+        return false;
+      }
+      List<DartType> parameterTypes = definingType.element.type.typeArguments;
+      FunctionType substitutedType =
+          baseType.substitute2(argumentTypes, parameterTypes);
+      if (baseType != substitutedType) {
+        return true;
+      }
+      // If this property accessor is based on a field, that field might have a
+      // propagated type. In which case we need to check whether the propagated
+      // type of the field needs substitution.
+      PropertyInducingElement field = accessor.variable;
+      if (!field.isSynthetic) {
+        DartType baseFieldType = field.propagatedType;
+        if (baseFieldType != null) {
+          DartType substitutedFieldType =
+              baseFieldType.substitute2(argumentTypes, parameterTypes);
+          if (baseFieldType != substitutedFieldType) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * A variable element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+abstract class VariableMember extends Member implements VariableElement {
+  @override
+  final DartType type;
+
+  /**
+   * Initialize a newly created element to represent a variable, based on the
+   * [baseElement], defined by the [definingType].
+   */
+  VariableMember(VariableElement baseElement, ParameterizedType definingType,
+      [DartType type])
+      : type = type ??
+            baseElement.type.substitute2(definingType.typeArguments,
+                TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
+        super(baseElement, definingType);
+
+  // TODO(jmesserly): this is temporary to allow the ParameterMember subclass.
+  // Apparently mixins don't work with optional params.
+  VariableMember._(VariableElement baseElement, ParameterizedType definingType,
+      DartType type)
+      : this(baseElement, definingType, type);
+
+  @override
+  VariableElement get baseElement => super.baseElement as VariableElement;
+
+  @override
+  DartObject get constantValue => baseElement.constantValue;
+
+  @override
+  bool get hasImplicitType => baseElement.hasImplicitType;
+
+  @override
+  FunctionElement get initializer {
+    //
+    // Elements within this element should have type parameters substituted,
+    // just like this element.
+    //
+    throw new UnsupportedOperationException();
+    //    return getBaseElement().getInitializer();
+  }
+
+  @override
+  bool get isConst => baseElement.isConst;
+
+  @override
+  bool get isFinal => baseElement.isFinal;
+
+  @override
+  bool get isPotentiallyMutatedInClosure =>
+      baseElement.isPotentiallyMutatedInClosure;
+
+  @override
+  bool get isPotentiallyMutatedInScope =>
+      baseElement.isPotentiallyMutatedInScope;
+
+  @override
+  bool get isStatic => baseElement.isStatic;
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // TODO(brianwilkerson) We need to finish implementing the accessors used
+    // below so that we can safely invoke them.
+    super.visitChildren(visitor);
+    safelyVisitChild(baseElement.initializer, visitor);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
new file mode 100644
index 0000000..b804339
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -0,0 +1,2395 @@
+// 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 analyzer.src.dart.element.type;
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, AnalysisEngine, AnalysisException;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/scanner.dart' show Keyword;
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * A [Type] that represents the type 'bottom'.
+ */
+class BottomTypeImpl extends TypeImpl {
+  /**
+   * The unique instance of this class.
+   */
+  static BottomTypeImpl _INSTANCE = new BottomTypeImpl._();
+
+  /**
+   * Return the unique instance of this class.
+   */
+  static BottomTypeImpl get instance => _INSTANCE;
+
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  BottomTypeImpl._() : super(null, "<bottom>");
+
+  @override
+  int get hashCode => 0;
+
+  @override
+  bool get isBottom => true;
+
+  @override
+  bool operator ==(Object object) => identical(object, this);
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+          [bool withDynamic = false, Set<Element> visitedElements]) =>
+      true;
+
+  @override
+  bool isSubtypeOf(DartType type) => true;
+
+  @override
+  bool isSupertypeOf(DartType type) => false;
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  BottomTypeImpl substitute2(
+          List<DartType> argumentTypes, List<DartType> parameterTypes,
+          [List<FunctionTypeAliasElement> prune]) =>
+      this;
+}
+
+/**
+ * Type created internally if a circular reference is ever detected.  Behaves
+ * like `dynamic`, except that when converted to a string it is displayed as
+ * `...`.
+ */
+class CircularTypeImpl extends DynamicTypeImpl {
+  CircularTypeImpl() : super._circular();
+
+  @override
+  int get hashCode => 1;
+
+  @override
+  bool operator ==(Object object) => object is CircularTypeImpl;
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write('...');
+  }
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+}
+
+/**
+ * The [Type] representing the type `dynamic`.
+ */
+class DynamicTypeImpl extends TypeImpl {
+  /**
+   * The unique instance of this class.
+   */
+  static DynamicTypeImpl _INSTANCE = new DynamicTypeImpl._();
+
+  /**
+   * Return the unique instance of this class.
+   */
+  static DynamicTypeImpl get instance => _INSTANCE;
+
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  DynamicTypeImpl._()
+      : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) {
+    (element as DynamicElementImpl).type = this;
+  }
+
+  /**
+   * Constructor used by [CircularTypeImpl].
+   */
+  DynamicTypeImpl._circular()
+      : super(_INSTANCE.element, Keyword.DYNAMIC.syntax);
+
+  @override
+  int get hashCode => 1;
+
+  @override
+  bool get isDynamic => true;
+
+  @override
+  bool operator ==(Object object) => identical(object, this);
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    // T is S
+    if (identical(this, type)) {
+      return true;
+    }
+    // else
+    return withDynamic;
+  }
+
+  @override
+  bool isSubtypeOf(DartType type) => true;
+
+  @override
+  bool isSupertypeOf(DartType type) => true;
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    int length = parameterTypes.length;
+    for (int i = 0; i < length; i++) {
+      if (parameterTypes[i] == this) {
+        return argumentTypes[i];
+      }
+    }
+    return this;
+  }
+}
+
+/**
+ * The type of a function, method, constructor, getter, or setter.
+ */
+class FunctionTypeImpl extends TypeImpl implements FunctionType {
+  /**
+   * The list of [typeArguments].
+   */
+  List<DartType> _typeArguments;
+
+  /**
+   * The list of [typeParameters], if it has been computed already.  Otherwise
+   * `null`.
+   */
+  List<TypeParameterElement> _typeParameters;
+
+  /**
+   * True if this type is the result of instantiating type parameters (and thus
+   * any type parameters bound by the typedef should be considered part of
+   * [typeParameters] rather than [typeFormals]).
+   */
+  final bool _isInstantiated;
+
+  /**
+   * The set of typedefs which should not be expanded when exploring this type,
+   * to avoid creating infinite types in response to self-referential typedefs.
+   */
+  final List<FunctionTypeAliasElement> prunedTypedefs;
+
+  /**
+   * Initialize a newly created function type to be declared by the given
+   * [element], and also initialize [typeArguments] to match the
+   * [typeParameters], which permits later substitution.
+   */
+  FunctionTypeImpl(ExecutableElement element,
+      [List<FunctionTypeAliasElement> prunedTypedefs])
+      : this._(element, null, prunedTypedefs, null, false);
+
+  /**
+   * Initialize a newly created function type to be declared by the given
+   * [element], with the given [name] and [typeArguments].
+   */
+  FunctionTypeImpl.elementWithNameAndArgs(Element element, String name,
+      List<DartType> typeArguments, bool isInstantiated)
+      : this._(element, name, null, typeArguments, isInstantiated);
+
+  /**
+   * Initialize a newly created function type to be declared by the given
+   * [element].
+   */
+  FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
+      [List<FunctionTypeAliasElement> prunedTypedefs])
+      : this._(element, element?.name, prunedTypedefs, null, false);
+
+  /**
+   * Private constructor.
+   */
+  FunctionTypeImpl._(TypeParameterizedElement element, String name,
+      this.prunedTypedefs, this._typeArguments, this._isInstantiated)
+      : super(element, name);
+
+  /**
+   * Return the base parameter elements of this function element.
+   */
+  List<ParameterElement> get baseParameters => element.parameters;
+
+  /**
+   * Return the return type defined by this function's element.
+   */
+  DartType get baseReturnType => element.returnType;
+
+  @deprecated
+  @override
+  List<TypeParameterElement> get boundTypeParameters => typeFormals;
+
+  @override
+  List<TypeParameterElement> get typeFormals {
+    if (_isInstantiated) {
+      return TypeParameterElement.EMPTY_LIST;
+    } else {
+      return element?.typeParameters ?? TypeParameterElement.EMPTY_LIST;
+    }
+  }
+
+  @override
+  String get displayName {
+    String name = this.name;
+    if (name == null || name.length == 0) {
+      // Function types have an empty name when they are defined implicitly by
+      // either a closure or as part of a parameter declaration.
+      List<DartType> normalParameterTypes = this.normalParameterTypes;
+      List<DartType> optionalParameterTypes = this.optionalParameterTypes;
+      Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
+      DartType returnType = this.returnType;
+      StringBuffer buffer = new StringBuffer();
+      buffer.write("(");
+      bool needsComma = false;
+      if (normalParameterTypes.length > 0) {
+        for (DartType type in normalParameterTypes) {
+          if (needsComma) {
+            buffer.write(", ");
+          } else {
+            needsComma = true;
+          }
+          buffer.write(type.displayName);
+        }
+      }
+      if (optionalParameterTypes.length > 0) {
+        if (needsComma) {
+          buffer.write(", ");
+          needsComma = false;
+        }
+        buffer.write("[");
+        for (DartType type in optionalParameterTypes) {
+          if (needsComma) {
+            buffer.write(", ");
+          } else {
+            needsComma = true;
+          }
+          buffer.write(type.displayName);
+        }
+        buffer.write("]");
+        needsComma = true;
+      }
+      if (namedParameterTypes.length > 0) {
+        if (needsComma) {
+          buffer.write(", ");
+          needsComma = false;
+        }
+        buffer.write("{");
+        namedParameterTypes.forEach((String name, DartType type) {
+          if (needsComma) {
+            buffer.write(", ");
+          } else {
+            needsComma = true;
+          }
+          buffer.write(name);
+          buffer.write(": ");
+          buffer.write(type.displayName);
+        });
+        buffer.write("}");
+        needsComma = true;
+      }
+      buffer.write(")");
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      if (returnType == null) {
+        buffer.write("null");
+      } else {
+        buffer.write(returnType.displayName);
+      }
+      name = buffer.toString();
+    }
+    return name;
+  }
+
+  @override
+  FunctionTypedElement get element => super.element;
+
+  @override
+  int get hashCode {
+    if (element == null) {
+      return 0;
+    }
+    // Reference the arrays of parameters
+    List<DartType> normalParameterTypes = this.normalParameterTypes;
+    List<DartType> optionalParameterTypes = this.optionalParameterTypes;
+    Iterable<DartType> namedParameterTypes = this.namedParameterTypes.values;
+    // Generate the hashCode
+    int code = (returnType as TypeImpl).hashCode;
+    for (int i = 0; i < normalParameterTypes.length; i++) {
+      code = (code << 1) + (normalParameterTypes[i] as TypeImpl).hashCode;
+    }
+    for (int i = 0; i < optionalParameterTypes.length; i++) {
+      code = (code << 1) + (optionalParameterTypes[i] as TypeImpl).hashCode;
+    }
+    for (DartType type in namedParameterTypes) {
+      code = (code << 1) + (type as TypeImpl).hashCode;
+    }
+    return code;
+  }
+
+  /**
+   * Return `true` if this type is the result of instantiating type parameters.
+   */
+  bool get isInstantiated => _isInstantiated;
+
+  @override
+  Map<String, DartType> get namedParameterTypes {
+    LinkedHashMap<String, DartType> namedParameterTypes =
+        new LinkedHashMap<String, DartType>();
+    List<ParameterElement> parameters = baseParameters;
+    if (parameters.length == 0) {
+      return namedParameterTypes;
+    }
+    List<DartType> typeParameters =
+        TypeParameterTypeImpl.getTypes(this.typeParameters);
+    for (ParameterElement parameter in parameters) {
+      if (parameter.parameterKind == ParameterKind.NAMED) {
+        DartType type = parameter.type;
+        if (typeArguments.length != 0 &&
+            typeArguments.length == typeParameters.length) {
+          type = (type as TypeImpl)
+              .substitute2(typeArguments, typeParameters, newPrune);
+        } else {
+          type = (type as TypeImpl).pruned(newPrune);
+        }
+        namedParameterTypes[parameter.name] = type;
+      }
+    }
+    return namedParameterTypes;
+  }
+
+  /**
+   * Determine the new set of typedefs which should be pruned when expanding
+   * this function type.
+   */
+  List<FunctionTypeAliasElement> get newPrune {
+    Element element = this.element;
+    if (element is FunctionTypeAliasElement && !element.isSynthetic) {
+      // This typedef should be pruned, along with anything that was previously
+      // pruned.
+      if (prunedTypedefs == null) {
+        return <FunctionTypeAliasElement>[element];
+      } else {
+        return new List<FunctionTypeAliasElement>.from(prunedTypedefs)
+          ..add(element);
+      }
+    } else {
+      // This is not a typedef, so nothing additional needs to be pruned.
+      return prunedTypedefs;
+    }
+  }
+
+  @override
+  List<DartType> get normalParameterTypes {
+    List<ParameterElement> parameters = baseParameters;
+    if (parameters.length == 0) {
+      return DartType.EMPTY_LIST;
+    }
+    List<DartType> typeParameters =
+        TypeParameterTypeImpl.getTypes(this.typeParameters);
+    List<DartType> types = new List<DartType>();
+    for (ParameterElement parameter in parameters) {
+      if (parameter.parameterKind == ParameterKind.REQUIRED) {
+        DartType type = parameter.type;
+        if (typeArguments.length != 0 &&
+            typeArguments.length == typeParameters.length) {
+          type = (type as TypeImpl)
+              .substitute2(typeArguments, typeParameters, newPrune);
+        } else {
+          type = (type as TypeImpl).pruned(newPrune);
+        }
+        types.add(type);
+      }
+    }
+    return types;
+  }
+
+  @override
+  List<DartType> get optionalParameterTypes {
+    List<ParameterElement> parameters = baseParameters;
+    if (parameters.length == 0) {
+      return DartType.EMPTY_LIST;
+    }
+    List<DartType> typeParameters =
+        TypeParameterTypeImpl.getTypes(this.typeParameters);
+    List<DartType> types = new List<DartType>();
+    for (ParameterElement parameter in parameters) {
+      if (parameter.parameterKind == ParameterKind.POSITIONAL) {
+        DartType type = parameter.type;
+        if (typeArguments.length != 0 &&
+            typeArguments.length == typeParameters.length) {
+          type = (type as TypeImpl)
+              .substitute2(typeArguments, typeParameters, newPrune);
+        } else {
+          type = (type as TypeImpl).pruned(newPrune);
+        }
+        types.add(type);
+      }
+    }
+    return types;
+  }
+
+  @override
+  List<ParameterElement> get parameters {
+    List<ParameterElement> baseParameters = this.baseParameters;
+    // no parameters, quick return
+    int parameterCount = baseParameters.length;
+    if (parameterCount == 0) {
+      return baseParameters;
+    }
+    // create specialized parameters
+    List<ParameterElement> specializedParameters =
+        new List<ParameterElement>(parameterCount);
+    for (int i = 0; i < parameterCount; i++) {
+      specializedParameters[i] = ParameterMember.from(baseParameters[i], this);
+    }
+    return specializedParameters;
+  }
+
+  @override
+  DartType get returnType {
+    DartType baseReturnType = this.baseReturnType;
+    if (baseReturnType == null) {
+      // TODO(brianwilkerson) This is a patch. The return type should never be
+      // null and we need to understand why it is and fix it.
+      return DynamicTypeImpl.instance;
+    }
+    // If there are no arguments to substitute, or if the arguments size doesn't
+    // match the parameter size, return the base return type.
+    if (typeArguments.length == 0 ||
+        typeArguments.length != typeParameters.length) {
+      return (baseReturnType as TypeImpl).pruned(newPrune);
+    }
+    return (baseReturnType as TypeImpl).substitute2(typeArguments,
+        TypeParameterTypeImpl.getTypes(typeParameters), newPrune);
+  }
+
+  /**
+   * A list containing the actual types of the type arguments.
+   */
+  List<DartType> get typeArguments {
+    if (_typeArguments == null) {
+      // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can
+      // make it generic, which will allow it to return List<DartType> instead
+      // of List<TypeParameterType>.
+      if (typeParameters.isEmpty) {
+        _typeArguments = DartType.EMPTY_LIST;
+      } else {
+        _typeArguments = new List<DartType>.from(
+            typeParameters.map((t) => t.type),
+            growable: false);
+      }
+    }
+    return _typeArguments;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters {
+    if (_typeParameters == null) {
+      // Combine the generic type variables from all enclosing contexts, except
+      // for this generic function's type variables. Those variables are
+      // tracked in [boundTypeParameters].
+      _typeParameters = <TypeParameterElement>[];
+      Element e = element?.enclosingElement;
+      while (e != null) {
+        if (e is TypeParameterizedElement) {
+          _typeParameters.addAll(e.typeParameters);
+        }
+        e = e.enclosingElement;
+      }
+      if (_isInstantiated) {
+        // Once the type has been instantiated, type parameters defined at the
+        // site of the declaration of the method are no longer considered part
+        // [boundTypeParameters]; they are part of [typeParameters].
+        List<TypeParameterElement> parametersToAdd = element?.typeParameters;
+        if (parametersToAdd != null) {
+          _typeParameters.addAll(parametersToAdd);
+        }
+      }
+    }
+    return _typeParameters;
+  }
+
+  @override
+  bool operator ==(Object object) {
+    if (object is! FunctionTypeImpl) {
+      return false;
+    }
+    FunctionTypeImpl otherType = object as FunctionTypeImpl;
+    if (typeFormals.length != otherType.typeFormals.length) {
+      return false;
+    }
+    // `<T>T -> T` should be equal to `<U>U -> U`
+    // To test this, we instantiate both types with the same (unique) type
+    // variables, and see if the result is equal.
+    if (typeFormals.isNotEmpty) {
+      List<DartType> instantiateTypeArgs = new List<DartType>();
+      List<DartType> variablesThis = new List<DartType>();
+      List<DartType> variablesOther = new List<DartType>();
+      for (int i = 0; i < typeFormals.length; i++) {
+        TypeParameterElement pThis = typeFormals[i];
+        TypeParameterElement pOther = otherType.typeFormals[i];
+        TypeParameterTypeImpl pFresh = new TypeParameterTypeImpl(
+            new TypeParameterElementImpl(pThis.name, -1));
+        instantiateTypeArgs.add(pFresh);
+        variablesThis.add(pThis.type);
+        variablesOther.add(pOther.type);
+        // Check that the bounds are equal after equating the previous
+        // bound variables.
+        if (pThis.bound?.substitute2(instantiateTypeArgs, variablesThis) !=
+            pOther.bound?.substitute2(instantiateTypeArgs, variablesOther)) {
+          return false;
+        }
+      }
+      // After instantiation, they will no longer have typeFormals,
+      // so we will continue below.
+      return this.instantiate(instantiateTypeArgs) ==
+          otherType.instantiate(instantiateTypeArgs);
+    }
+
+    return returnType == otherType.returnType &&
+        TypeImpl.equalArrays(
+            normalParameterTypes, otherType.normalParameterTypes) &&
+        TypeImpl.equalArrays(
+            optionalParameterTypes, otherType.optionalParameterTypes) &&
+        _equals(namedParameterTypes, otherType.namedParameterTypes);
+  }
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (typeFormals.isNotEmpty) {
+      // To print a type with type variables, first make sure we have unique
+      // variable names to print.
+      Set<TypeParameterType> freeVariables = new HashSet<TypeParameterType>();
+      _freeVariablesInFunctionType(this, freeVariables);
+
+      Set<String> namesToAvoid = new HashSet<String>();
+      for (DartType arg in freeVariables) {
+        if (arg is TypeParameterType) {
+          namesToAvoid.add(arg.displayName);
+        }
+      }
+
+      List<DartType> instantiateTypeArgs = new List<DartType>();
+      List<DartType> variables = new List<DartType>();
+      buffer.write("<");
+      for (TypeParameterElement e in typeFormals) {
+        if (e != typeFormals[0]) {
+          buffer.write(",");
+        }
+        String name = e.name;
+        int counter = 0;
+        while (!namesToAvoid.add(name)) {
+          // Unicode subscript-zero is U+2080, zero is U+0030. Other digits
+          // are sequential from there. Thus +0x2050 will get us the subscript.
+          String subscript = new String.fromCharCodes(
+              counter.toString().codeUnits.map((n) => n + 0x2050));
+
+          name = e.name + subscript;
+          counter++;
+        }
+        TypeParameterTypeImpl t =
+            new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1));
+        t.appendTo(buffer);
+        instantiateTypeArgs.add(t);
+        variables.add(e.type);
+        if (e.bound != null) {
+          buffer.write(" extends ");
+          TypeImpl renamed =
+              e.bound.substitute2(instantiateTypeArgs, variables);
+          renamed.appendTo(buffer);
+        }
+      }
+      buffer.write(">");
+
+      // Instantiate it and print the resulting type. After instantiation, it
+      // will no longer have typeFormals, so we will continue below.
+      this.instantiate(instantiateTypeArgs).appendTo(buffer);
+      return;
+    }
+
+    List<DartType> normalParameterTypes = this.normalParameterTypes;
+    List<DartType> optionalParameterTypes = this.optionalParameterTypes;
+    Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
+    DartType returnType = this.returnType;
+    buffer.write("(");
+    bool needsComma = false;
+    if (normalParameterTypes.isNotEmpty) {
+      for (DartType type in normalParameterTypes) {
+        if (needsComma) {
+          buffer.write(", ");
+        } else {
+          needsComma = true;
+        }
+        (type as TypeImpl).appendTo(buffer);
+      }
+    }
+    if (optionalParameterTypes.isNotEmpty) {
+      if (needsComma) {
+        buffer.write(", ");
+        needsComma = false;
+      }
+      buffer.write("[");
+      for (DartType type in optionalParameterTypes) {
+        if (needsComma) {
+          buffer.write(", ");
+        } else {
+          needsComma = true;
+        }
+        (type as TypeImpl).appendTo(buffer);
+      }
+      buffer.write("]");
+      needsComma = true;
+    }
+    if (namedParameterTypes.isNotEmpty) {
+      if (needsComma) {
+        buffer.write(", ");
+        needsComma = false;
+      }
+      buffer.write("{");
+      namedParameterTypes.forEach((String name, DartType type) {
+        if (needsComma) {
+          buffer.write(", ");
+        } else {
+          needsComma = true;
+        }
+        buffer.write(name);
+        buffer.write(": ");
+        (type as TypeImpl).appendTo(buffer);
+      });
+      buffer.write("}");
+      needsComma = true;
+    }
+    buffer.write(")");
+    buffer.write(ElementImpl.RIGHT_ARROW);
+    if (returnType == null) {
+      buffer.write("null");
+    } else {
+      (returnType as TypeImpl).appendTo(buffer);
+    }
+  }
+
+  @override
+  FunctionTypeImpl instantiate(List<DartType> argumentTypes) {
+    if (argumentTypes.length != typeFormals.length) {
+      throw new IllegalArgumentException(
+          "argumentTypes.length (${argumentTypes.length}) != "
+          "typeFormals.length (${typeFormals.length})");
+    }
+    if (argumentTypes.isEmpty) {
+      return this;
+    }
+
+    // Given:
+    //     {U/T} <S> T -> S
+    // Where {U/T} represents the typeArguments (U) and typeParameters (T) list,
+    // and <S> represents the typeFormals.
+    //
+    // Now instantiate([V]), and the result should be:
+    //     {U/T, V/S} T -> S.
+    List<DartType> newTypeArgs = typeArguments.toList();
+    newTypeArgs.addAll(argumentTypes);
+
+    return new FunctionTypeImpl._(
+        element, name, prunedTypedefs, newTypeArgs, true);
+  }
+
+  @override
+  bool isAssignableTo(DartType type) {
+    // A function type T may be assigned to a function type S, written T <=> S,
+    // iff T <: S.
+    return isSubtypeOf(type);
+  }
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    // Note: visitedElements is only used for breaking recursion in the type
+    // hierarchy; we don't use it when recursing into the function type.
+
+    // trivial base cases
+    if (type == null) {
+      return false;
+    } else if (identical(this, type) ||
+        type.isDynamic ||
+        type.isDartCoreFunction ||
+        type.isObject) {
+      return true;
+    } else if (type is! FunctionType) {
+      return false;
+    } else if (this == type) {
+      return true;
+    }
+    FunctionType t = this;
+    FunctionType s = type as FunctionType;
+    List<DartType> tTypes = t.normalParameterTypes;
+    List<DartType> tOpTypes = t.optionalParameterTypes;
+    List<DartType> sTypes = s.normalParameterTypes;
+    List<DartType> sOpTypes = s.optionalParameterTypes;
+    // If one function has positional and the other has named parameters,
+    // return false.
+    if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
+        (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
+      return false;
+    }
+    // named parameters case
+    if (t.namedParameterTypes.length > 0) {
+      // check that the number of required parameters are equal, and check that
+      // every t_i is more specific than every s_i
+      if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
+        return false;
+      } else if (t.normalParameterTypes.length > 0) {
+        for (int i = 0; i < tTypes.length; i++) {
+          if (!(tTypes[i] as TypeImpl)
+              .isMoreSpecificThan(sTypes[i], withDynamic)) {
+            return false;
+          }
+        }
+      }
+      Map<String, DartType> namedTypesT = t.namedParameterTypes;
+      Map<String, DartType> namedTypesS = s.namedParameterTypes;
+      // if k >= m is false, return false: the passed function type has more
+      // named parameter types than this
+      if (namedTypesT.length < namedTypesS.length) {
+        return false;
+      }
+      // Loop through each element in S verifying that T has a matching
+      // parameter name and that the corresponding type is more specific then
+      // the type in S.
+      for (String keyS in namedTypesS.keys) {
+        DartType typeT = namedTypesT[keyS];
+        if (typeT == null) {
+          return false;
+        }
+        if (!(typeT as TypeImpl)
+            .isMoreSpecificThan(namedTypesS[keyS], withDynamic)) {
+          return false;
+        }
+      }
+    } else if (s.namedParameterTypes.length > 0) {
+      return false;
+    } else {
+      // positional parameter case
+      int tArgLength = tTypes.length + tOpTypes.length;
+      int sArgLength = sTypes.length + sOpTypes.length;
+      // Check that the total number of parameters in t is greater than or equal
+      // to the number of parameters in s and that the number of required
+      // parameters in s is greater than or equal to the number of required
+      // parameters in t.
+      if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
+        return false;
+      }
+      if (tOpTypes.length == 0 && sOpTypes.length == 0) {
+        // No positional arguments, don't copy contents to new array
+        for (int i = 0; i < sTypes.length; i++) {
+          if (!(tTypes[i] as TypeImpl)
+              .isMoreSpecificThan(sTypes[i], withDynamic)) {
+            return false;
+          }
+        }
+      } else {
+        // Else, we do have positional parameters, copy required and positional
+        // parameter types into arrays to do the compare (for loop below).
+        List<DartType> tAllTypes = new List<DartType>(sArgLength);
+        for (int i = 0; i < tTypes.length; i++) {
+          tAllTypes[i] = tTypes[i];
+        }
+        for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
+          tAllTypes[i] = tOpTypes[j];
+        }
+        List<DartType> sAllTypes = new List<DartType>(sArgLength);
+        for (int i = 0; i < sTypes.length; i++) {
+          sAllTypes[i] = sTypes[i];
+        }
+        for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
+          sAllTypes[i] = sOpTypes[j];
+        }
+        for (int i = 0; i < sAllTypes.length; i++) {
+          if (!(tAllTypes[i] as TypeImpl)
+              .isMoreSpecificThan(sAllTypes[i], withDynamic)) {
+            return false;
+          }
+        }
+      }
+    }
+    DartType tRetType = t.returnType;
+    DartType sRetType = s.returnType;
+    return sRetType.isVoid ||
+        (tRetType as TypeImpl).isMoreSpecificThan(sRetType, withDynamic);
+  }
+
+  @override
+  bool isSubtypeOf(DartType type) {
+    // trivial base cases
+    if (type == null) {
+      return false;
+    } else if (identical(this, type) ||
+        type.isDynamic ||
+        type.isDartCoreFunction ||
+        type.isObject) {
+      return true;
+    } else if (type is! FunctionType) {
+      return false;
+    } else if (this == type) {
+      return true;
+    }
+    FunctionType t = this;
+    FunctionType s = type as FunctionType;
+    List<DartType> tTypes = t.normalParameterTypes;
+    List<DartType> tOpTypes = t.optionalParameterTypes;
+    List<DartType> sTypes = s.normalParameterTypes;
+    List<DartType> sOpTypes = s.optionalParameterTypes;
+    // If one function has positional and the other has named parameters,
+    // return false.
+    if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
+        (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
+      return false;
+    }
+    // named parameters case
+    if (t.namedParameterTypes.length > 0) {
+      // check that the number of required parameters are equal,
+      // and check that every t_i is assignable to every s_i
+      if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
+        return false;
+      } else if (t.normalParameterTypes.length > 0) {
+        for (int i = 0; i < tTypes.length; i++) {
+          if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
+            return false;
+          }
+        }
+      }
+      Map<String, DartType> namedTypesT = t.namedParameterTypes;
+      Map<String, DartType> namedTypesS = s.namedParameterTypes;
+      // if k >= m is false, return false: the passed function type has more
+      // named parameter types than this
+      if (namedTypesT.length < namedTypesS.length) {
+        return false;
+      }
+      // Loop through each element in S verifying that T has a matching
+      // parameter name and that the corresponding type is assignable to the
+      // type in S.
+      for (String keyS in namedTypesS.keys) {
+        DartType typeT = namedTypesT[keyS];
+        if (typeT == null) {
+          return false;
+        }
+        if (!(typeT as TypeImpl).isAssignableTo(namedTypesS[keyS])) {
+          return false;
+        }
+      }
+    } else if (s.namedParameterTypes.length > 0) {
+      return false;
+    } else {
+      // positional parameter case
+      int tArgLength = tTypes.length + tOpTypes.length;
+      int sArgLength = sTypes.length + sOpTypes.length;
+      // Check that the total number of parameters in t is greater than or
+      // equal to the number of parameters in s and that the number of
+      // required parameters in s is greater than or equal to the number of
+      // required parameters in t.
+      if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
+        return false;
+      }
+      if (tOpTypes.length == 0 && sOpTypes.length == 0) {
+        // No positional arguments, don't copy contents to new array
+        for (int i = 0; i < sTypes.length; i++) {
+          if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
+            return false;
+          }
+        }
+      } else {
+        // Else, we do have positional parameters, copy required and
+        // positional parameter types into arrays to do the compare (for loop
+        // below).
+        List<DartType> tAllTypes = new List<DartType>(sArgLength);
+        for (int i = 0; i < tTypes.length; i++) {
+          tAllTypes[i] = tTypes[i];
+        }
+        for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
+          tAllTypes[i] = tOpTypes[j];
+        }
+        List<DartType> sAllTypes = new List<DartType>(sArgLength);
+        for (int i = 0; i < sTypes.length; i++) {
+          sAllTypes[i] = sTypes[i];
+        }
+        for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
+          sAllTypes[i] = sOpTypes[j];
+        }
+        for (int i = 0; i < sAllTypes.length; i++) {
+          if (!(tAllTypes[i] as TypeImpl).isAssignableTo(sAllTypes[i])) {
+            return false;
+          }
+        }
+      }
+    }
+    DartType tRetType = t.returnType;
+    DartType sRetType = s.returnType;
+    return sRetType.isVoid || (tRetType as TypeImpl).isAssignableTo(sRetType);
+  }
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) {
+    if (prune == null) {
+      return this;
+    } else if (prune.contains(element)) {
+      // Circularity found.  Prune the type declaration.
+      return new CircularTypeImpl();
+    } else {
+      // There should never be a reason to prune a type that has already been
+      // pruned, since pruning is only done when expanding a function type
+      // alias, and function type aliases are always expanded by starting with
+      // base types.
+      assert(this.prunedTypedefs == null);
+      List<DartType> typeArgs = typeArguments
+          .map((TypeImpl t) => t.pruned(prune))
+          .toList(growable: false);
+      return new FunctionTypeImpl._(
+          element, name, prune, typeArgs, _isInstantiated);
+    }
+  }
+
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    // Pruned types should only ever result from performing type variable
+    // substitution, and it doesn't make sense to substitute again after
+    // substituting once.
+    assert(this.prunedTypedefs == null);
+    if (argumentTypes.length != parameterTypes.length) {
+      throw new IllegalArgumentException(
+          "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
+    }
+    Element element = this.element;
+    if (prune != null && prune.contains(element)) {
+      // Circularity found.  Prune the type declaration.
+      return new CircularTypeImpl();
+    }
+    if (argumentTypes.length == 0) {
+      return this.pruned(prune);
+    }
+    List<DartType> typeArgs =
+        TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes);
+    return new FunctionTypeImpl._(
+        element, name, prune, typeArgs, _isInstantiated);
+  }
+
+  @override
+  FunctionTypeImpl substitute3(List<DartType> argumentTypes) =>
+      substitute2(argumentTypes, typeArguments);
+
+  void _freeVariablesInFunctionType(
+      FunctionType type, Set<TypeParameterType> free) {
+    // Make some fresh variables to avoid capture.
+    List<DartType> typeArgs = DartType.EMPTY_LIST;
+    if (type.typeFormals.isNotEmpty) {
+      typeArgs = new List<DartType>.from(type.typeFormals.map((e) =>
+          new TypeParameterTypeImpl(new TypeParameterElementImpl(e.name, -1))));
+
+      type = type.instantiate(typeArgs);
+    }
+
+    for (ParameterElement p in type.parameters) {
+      _freeVariablesInType(p.type, free);
+    }
+    _freeVariablesInType(type.returnType, free);
+
+    // Remove all of our bound variables.
+    free.removeAll(typeArgs);
+  }
+
+  void _freeVariablesInInterfaceType(
+      InterfaceType type, Set<TypeParameterType> free) {
+    for (DartType typeArg in type.typeArguments) {
+      _freeVariablesInType(typeArg, free);
+    }
+  }
+
+  void _freeVariablesInType(DartType type, Set<TypeParameterType> free) {
+    if (type is TypeParameterType) {
+      free.add(type);
+    } else if (type is FunctionType) {
+      _freeVariablesInFunctionType(type, free);
+    } else if (type is InterfaceType) {
+      _freeVariablesInInterfaceType(type, free);
+    }
+  }
+
+  /**
+   * Compute the least upper bound of types [f] and [g], both of which are
+   * known to be function types.
+   *
+   * In the event that f and g have different numbers of required parameters,
+   * `null` is returned, in which case the least upper bound is the interface
+   * type `Function`.
+   */
+  static FunctionType computeLeastUpperBound(FunctionType f, FunctionType g) {
+    // TODO(paulberry): implement this.
+    return null;
+  }
+
+  /**
+   * Return `true` if all of the name/type pairs in the first map ([firstTypes])
+   * are equal to the corresponding name/type pairs in the second map
+   * ([secondTypes]). The maps are expected to iterate over their entries in the
+   * same order in which those entries were added to the map.
+   */
+  static bool _equals(
+      Map<String, DartType> firstTypes, Map<String, DartType> secondTypes) {
+    if (secondTypes.length != firstTypes.length) {
+      return false;
+    }
+    Iterator<String> firstKeys = firstTypes.keys.iterator;
+    Iterator<String> secondKeys = secondTypes.keys.iterator;
+    while (firstKeys.moveNext() && secondKeys.moveNext()) {
+      String firstKey = firstKeys.current;
+      String secondKey = secondKeys.current;
+      TypeImpl firstType = firstTypes[firstKey];
+      TypeImpl secondType = secondTypes[secondKey];
+      if (firstKey != secondKey || firstType != secondType) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+/**
+ * A concrete implementation of an [InterfaceType].
+ */
+class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
+  /**
+   * A list containing the actual types of the type arguments.
+   */
+  List<DartType> typeArguments = DartType.EMPTY_LIST;
+
+  /**
+   * The set of typedefs which should not be expanded when exploring this type,
+   * to avoid creating infinite types in response to self-referential typedefs.
+   */
+  final List<FunctionTypeAliasElement> prunedTypedefs;
+
+  /**
+   * Initialize a newly created type to be declared by the given [element].
+   */
+  InterfaceTypeImpl(ClassElement element, [this.prunedTypedefs])
+      : super(element, element.displayName);
+
+  /**
+   * Initialize a newly created type to be declared by the given [element],
+   * with the given [name] and [typeArguents].
+   */
+  InterfaceTypeImpl.elementWithNameAndArgs(
+      ClassElement element, String name, List<DartType> typeArguments)
+      : prunedTypedefs = null,
+        super(element, name) {
+    this.typeArguments = typeArguments;
+  }
+
+  /**
+   * Initialize a newly created type to have the given [name]. This constructor
+   * should only be used in cases where there is no declaration of the type.
+   */
+  InterfaceTypeImpl.named(String name)
+      : prunedTypedefs = null,
+        super(null, name);
+
+  /**
+   * Private constructor.
+   */
+  InterfaceTypeImpl._(Element element, String name, this.prunedTypedefs)
+      : super(element, name);
+
+  @override
+  List<PropertyAccessorElement> get accessors {
+    List<PropertyAccessorElement> accessors = element.accessors;
+    List<PropertyAccessorElement> members =
+        new List<PropertyAccessorElement>(accessors.length);
+    for (int i = 0; i < accessors.length; i++) {
+      members[i] = PropertyAccessorMember.from(accessors[i], this);
+    }
+    return members;
+  }
+
+  @override
+  List<ConstructorElement> get constructors {
+    List<ConstructorElement> constructors = element.constructors;
+    List<ConstructorElement> members =
+        new List<ConstructorElement>(constructors.length);
+    for (int i = 0; i < constructors.length; i++) {
+      members[i] = ConstructorMember.from(constructors[i], this);
+    }
+    return members;
+  }
+
+  @override
+  String get displayName {
+    String name = this.name;
+    List<DartType> typeArguments = this.typeArguments;
+    bool allDynamic = true;
+    for (DartType type in typeArguments) {
+      if (type != null && !type.isDynamic) {
+        allDynamic = false;
+        break;
+      }
+    }
+    // If there is at least one non-dynamic type, then list them out
+    if (!allDynamic) {
+      StringBuffer buffer = new StringBuffer();
+      buffer.write(name);
+      buffer.write("<");
+      for (int i = 0; i < typeArguments.length; i++) {
+        if (i != 0) {
+          buffer.write(", ");
+        }
+        DartType typeArg = typeArguments[i];
+        buffer.write(typeArg.displayName);
+      }
+      buffer.write(">");
+      name = buffer.toString();
+    }
+    return name;
+  }
+
+  @override
+  ClassElement get element => super.element as ClassElement;
+
+  @override
+  int get hashCode {
+    ClassElement element = this.element;
+    if (element == null) {
+      return 0;
+    }
+    return element.hashCode;
+  }
+
+  @override
+  List<InterfaceType> get interfaces {
+    ClassElement classElement = element;
+    List<InterfaceType> interfaces = classElement.interfaces;
+    List<TypeParameterElement> typeParameters = classElement.typeParameters;
+    List<DartType> parameterTypes = classElement.type.typeArguments;
+    if (typeParameters.length == 0) {
+      return interfaces;
+    }
+    int count = interfaces.length;
+    List<InterfaceType> typedInterfaces = new List<InterfaceType>(count);
+    for (int i = 0; i < count; i++) {
+      typedInterfaces[i] =
+          interfaces[i].substitute2(typeArguments, parameterTypes);
+    }
+    return typedInterfaces;
+  }
+
+  @override
+  bool get isDartCoreFunction {
+    ClassElement element = this.element;
+    if (element == null) {
+      return false;
+    }
+    return element.name == "Function" && element.library.isDartCore;
+  }
+
+  @override
+  bool get isObject => element.supertype == null;
+
+  @override
+  List<MethodElement> get methods {
+    List<MethodElement> methods = element.methods;
+    List<MethodElement> members = new List<MethodElement>(methods.length);
+    for (int i = 0; i < methods.length; i++) {
+      members[i] = MethodMember.from(methods[i], this);
+    }
+    return members;
+  }
+
+  @override
+  List<InterfaceType> get mixins {
+    ClassElement classElement = element;
+    List<InterfaceType> mixins = classElement.mixins;
+    List<TypeParameterElement> typeParameters = classElement.typeParameters;
+    List<DartType> parameterTypes = classElement.type.typeArguments;
+    if (typeParameters.length == 0) {
+      return mixins;
+    }
+    int count = mixins.length;
+    List<InterfaceType> typedMixins = new List<InterfaceType>(count);
+    for (int i = 0; i < count; i++) {
+      typedMixins[i] = mixins[i].substitute2(typeArguments, parameterTypes);
+    }
+    return typedMixins;
+  }
+
+  @override
+  InterfaceType get superclass {
+    ClassElement classElement = element;
+    InterfaceType supertype = classElement.supertype;
+    if (supertype == null) {
+      return null;
+    }
+    List<DartType> typeParameters = classElement.type.typeArguments;
+    if (typeArguments.length == 0 ||
+        typeArguments.length != typeParameters.length) {
+      return supertype;
+    }
+    return supertype.substitute2(typeArguments, typeParameters);
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => element.typeParameters;
+
+  @override
+  bool operator ==(Object object) {
+    if (identical(object, this)) {
+      return true;
+    }
+    if (object is! InterfaceTypeImpl) {
+      return false;
+    }
+    InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
+    return (element == otherType.element) &&
+        TypeImpl.equalArrays(typeArguments, otherType.typeArguments);
+  }
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(name);
+    int argumentCount = typeArguments.length;
+    if (argumentCount > 0) {
+      buffer.write("<");
+      for (int i = 0; i < argumentCount; i++) {
+        if (i > 0) {
+          buffer.write(", ");
+        }
+        (typeArguments[i] as TypeImpl).appendTo(buffer);
+      }
+      buffer.write(">");
+    }
+  }
+
+  @override
+  PropertyAccessorElement getGetter(String getterName) =>
+      PropertyAccessorMember.from(element.getGetter(getterName), this);
+
+  @override
+  MethodElement getMethod(String methodName) =>
+      MethodMember.from(element.getMethod(methodName), this);
+
+  @override
+  PropertyAccessorElement getSetter(String setterName) =>
+      PropertyAccessorMember.from(element.getSetter(setterName), this);
+
+  @override
+  bool isDirectSupertypeOf(InterfaceType type) {
+    InterfaceType i = this;
+    InterfaceType j = type;
+    ClassElement jElement = j.element;
+    InterfaceType supertype = jElement.supertype;
+    //
+    // If J has no direct supertype then it is Object, and Object has no direct
+    // supertypes.
+    //
+    if (supertype == null) {
+      return false;
+    }
+    //
+    // I is listed in the extends clause of J.
+    //
+    List<DartType> jArgs = j.typeArguments;
+    List<DartType> jVars = jElement.type.typeArguments;
+    supertype = supertype.substitute2(jArgs, jVars);
+    if (supertype == i) {
+      return true;
+    }
+    //
+    // I is listed in the implements clause of J.
+    //
+    for (InterfaceType interfaceType in jElement.interfaces) {
+      interfaceType = interfaceType.substitute2(jArgs, jVars);
+      if (interfaceType == i) {
+        return true;
+      }
+    }
+    //
+    // I is listed in the with clause of J.
+    //
+    for (InterfaceType mixinType in jElement.mixins) {
+      mixinType = mixinType.substitute2(jArgs, jVars);
+      if (mixinType == i) {
+        return true;
+      }
+    }
+    //
+    // J is a mixin application of the mixin of I.
+    //
+    // TODO(brianwilkerson) Determine whether this needs to be implemented or
+    // whether it is covered by the case above.
+    return false;
+  }
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    //
+    // S is dynamic.
+    // The test to determine whether S is dynamic is done here because dynamic
+    // is not an instance of InterfaceType.
+    //
+    if (type.isDynamic) {
+      return true;
+    }
+    //
+    // A type T is more specific than a type S, written T << S,
+    // if one of the following conditions is met:
+    //
+    // Reflexivity: T is S.
+    //
+    if (this == type) {
+      return true;
+    }
+    if (type is InterfaceType) {
+      //
+      // T is bottom. (This case is handled by the class BottomTypeImpl.)
+      //
+      // Direct supertype: S is a direct supertype of T.
+      //
+      if (type.isDirectSupertypeOf(this)) {
+        return true;
+      }
+      //
+      // Covariance: T is of the form I<T1, ..., Tn> and S is of the form
+      // I<S1, ..., Sn> and Ti << Si, 1 <= i <= n.
+      //
+      ClassElement tElement = this.element;
+      ClassElement sElement = type.element;
+      if (tElement == sElement) {
+        List<DartType> tArguments = typeArguments;
+        List<DartType> sArguments = type.typeArguments;
+        if (tArguments.length != sArguments.length) {
+          return false;
+        }
+        for (int i = 0; i < tArguments.length; i++) {
+          if (!(tArguments[i] as TypeImpl)
+              .isMoreSpecificThan(sArguments[i], withDynamic)) {
+            return false;
+          }
+        }
+        return true;
+      }
+    }
+    //
+    // Transitivity: T << U and U << S.
+    //
+    // First check for infinite loops
+    if (element == null) {
+      return false;
+    }
+    if (visitedElements == null) {
+      visitedElements = new HashSet<ClassElement>();
+    } else if (visitedElements.contains(element)) {
+      return false;
+    }
+    visitedElements.add(element);
+    try {
+      // Iterate over all of the types U that are more specific than T because
+      // they are direct supertypes of T and return true if any of them are more
+      // specific than S.
+      InterfaceTypeImpl supertype = superclass;
+      if (supertype != null &&
+          supertype.isMoreSpecificThan(type, withDynamic, visitedElements)) {
+        return true;
+      }
+      for (InterfaceType interfaceType in interfaces) {
+        if ((interfaceType as InterfaceTypeImpl)
+            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
+          return true;
+        }
+      }
+      for (InterfaceType mixinType in mixins) {
+        if ((mixinType as InterfaceTypeImpl)
+            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
+          return true;
+        }
+      }
+      // If a type I includes an instance method named `call`, and the type of
+      // `call` is the function type F, then I is considered to be more specific
+      // than F.
+      MethodElement callMethod = getMethod('call');
+      if (callMethod != null && !callMethod.isStatic) {
+        FunctionTypeImpl callType = callMethod.type;
+        if (callType.isMoreSpecificThan(type, withDynamic, visitedElements)) {
+          return true;
+        }
+      }
+      return false;
+    } finally {
+      visitedElements.remove(element);
+    }
+  }
+
+  @override
+  ConstructorElement lookUpConstructor(
+      String constructorName, LibraryElement library) {
+    // prepare base ConstructorElement
+    ConstructorElement constructorElement;
+    if (constructorName == null) {
+      constructorElement = element.unnamedConstructor;
+    } else {
+      constructorElement = element.getNamedConstructor(constructorName);
+    }
+    // not found or not accessible
+    if (constructorElement == null ||
+        !constructorElement.isAccessibleIn(library)) {
+      return null;
+    }
+    // return member
+    return ConstructorMember.from(constructorElement, this);
+  }
+
+  @override
+  PropertyAccessorElement lookUpGetter(
+      String getterName, LibraryElement library) {
+    PropertyAccessorElement element = getGetter(getterName);
+    if (element != null && element.isAccessibleIn(library)) {
+      return element;
+    }
+    return lookUpGetterInSuperclass(getterName, library);
+  }
+
+  @override
+  PropertyAccessorElement lookUpGetterInSuperclass(
+      String getterName, LibraryElement library) {
+    for (InterfaceType mixin in mixins.reversed) {
+      PropertyAccessorElement element = mixin.getGetter(getterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    InterfaceType supertype = superclass;
+    ClassElement supertypeElement =
+        supertype == null ? null : supertype.element;
+    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
+      visitedClasses.add(supertypeElement);
+      PropertyAccessorElement element = supertype.getGetter(getterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+      for (InterfaceType mixin in supertype.mixins.reversed) {
+        element = mixin.getGetter(getterName);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+      supertype = supertype.superclass;
+      supertypeElement = supertype == null ? null : supertype.element;
+    }
+    return null;
+  }
+
+  @override
+  PropertyAccessorElement lookUpInheritedGetter(String name,
+      {LibraryElement library, bool thisType: true}) {
+    PropertyAccessorElement result;
+    if (thisType) {
+      result = lookUpGetter(name, library);
+    } else {
+      result = lookUpGetterInSuperclass(name, library);
+    }
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(this, false, library,
+        new HashSet<ClassElement>(), (InterfaceType t) => t.getGetter(name));
+  }
+
+  @override
+  ExecutableElement lookUpInheritedGetterOrMethod(String name,
+      {LibraryElement library}) {
+    ExecutableElement result =
+        lookUpGetter(name, library) ?? lookUpMethod(name, library);
+
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(
+        this,
+        false,
+        library,
+        new HashSet<ClassElement>(),
+        (InterfaceType t) => t.getGetter(name) ?? t.getMethod(name));
+  }
+
+  @override
+  MethodElement lookUpInheritedMethod(String name,
+      {LibraryElement library, bool thisType: true}) {
+    MethodElement result;
+    if (thisType) {
+      result = lookUpMethod(name, library);
+    } else {
+      result = lookUpMethodInSuperclass(name, library);
+    }
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(this, false, library,
+        new HashSet<ClassElement>(), (InterfaceType t) => t.getMethod(name));
+  }
+
+  @override
+  PropertyAccessorElement lookUpInheritedSetter(String name,
+      {LibraryElement library, bool thisType: true}) {
+    PropertyAccessorElement result;
+    if (thisType) {
+      result = lookUpSetter(name, library);
+    } else {
+      result = lookUpSetterInSuperclass(name, library);
+    }
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(this, false, library,
+        new HashSet<ClassElement>(), (t) => t.getSetter(name));
+  }
+
+  @override
+  MethodElement lookUpMethod(String methodName, LibraryElement library) {
+    MethodElement element = getMethod(methodName);
+    if (element != null && element.isAccessibleIn(library)) {
+      return element;
+    }
+    return lookUpMethodInSuperclass(methodName, library);
+  }
+
+  @override
+  MethodElement lookUpMethodInSuperclass(
+      String methodName, LibraryElement library) {
+    for (InterfaceType mixin in mixins.reversed) {
+      MethodElement element = mixin.getMethod(methodName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    InterfaceType supertype = superclass;
+    ClassElement supertypeElement =
+        supertype == null ? null : supertype.element;
+    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
+      visitedClasses.add(supertypeElement);
+      MethodElement element = supertype.getMethod(methodName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+      for (InterfaceType mixin in supertype.mixins.reversed) {
+        element = mixin.getMethod(methodName);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+      supertype = supertype.superclass;
+      supertypeElement = supertype == null ? null : supertype.element;
+    }
+    return null;
+  }
+
+  @override
+  PropertyAccessorElement lookUpSetter(
+      String setterName, LibraryElement library) {
+    PropertyAccessorElement element = getSetter(setterName);
+    if (element != null && element.isAccessibleIn(library)) {
+      return element;
+    }
+    return lookUpSetterInSuperclass(setterName, library);
+  }
+
+  @override
+  PropertyAccessorElement lookUpSetterInSuperclass(
+      String setterName, LibraryElement library) {
+    for (InterfaceType mixin in mixins.reversed) {
+      PropertyAccessorElement element = mixin.getSetter(setterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    InterfaceType supertype = superclass;
+    ClassElement supertypeElement =
+        supertype == null ? null : supertype.element;
+    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
+      visitedClasses.add(supertypeElement);
+      PropertyAccessorElement element = supertype.getSetter(setterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+      for (InterfaceType mixin in supertype.mixins.reversed) {
+        element = mixin.getSetter(setterName);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+      supertype = supertype.superclass;
+      supertypeElement = supertype == null ? null : supertype.element;
+    }
+    return null;
+  }
+
+  @override
+  InterfaceTypeImpl pruned(List<FunctionTypeAliasElement> prune) {
+    if (prune == null) {
+      return this;
+    } else {
+      // There should never be a reason to prune a type that has already been
+      // pruned, since pruning is only done when expanding a function type
+      // alias, and function type aliases are always expanded by starting with
+      // base types.
+      assert(this.prunedTypedefs == null);
+      InterfaceTypeImpl result = new InterfaceTypeImpl._(element, name, prune);
+      result.typeArguments =
+          typeArguments.map((TypeImpl t) => t.pruned(prune)).toList();
+      return result;
+    }
+  }
+
+  @override
+  InterfaceTypeImpl substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    if (argumentTypes.length != parameterTypes.length) {
+      throw new IllegalArgumentException(
+          "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
+    }
+    if (argumentTypes.length == 0 || typeArguments.length == 0) {
+      return this.pruned(prune);
+    }
+    List<DartType> newTypeArguments = TypeImpl.substitute(
+        typeArguments, argumentTypes, parameterTypes, prune);
+    if (JavaArrays.equals(newTypeArguments, typeArguments)) {
+      return this;
+    }
+    InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune);
+    newType.typeArguments = newTypeArguments;
+    return newType;
+  }
+
+  @override
+  InterfaceTypeImpl substitute4(List<DartType> argumentTypes) =>
+      substitute2(argumentTypes, typeArguments);
+
+  /**
+   * Compute the least upper bound of types [i] and [j], both of which are
+   * known to be interface types.
+   *
+   * In the event that the algorithm fails (which might occur due to a bug in
+   * the analyzer), `null` is returned.
+   */
+  static InterfaceType computeLeastUpperBound(
+      InterfaceType i, InterfaceType j) {
+    // compute set of supertypes
+    Set<InterfaceType> si = computeSuperinterfaceSet(i);
+    Set<InterfaceType> sj = computeSuperinterfaceSet(j);
+    // union si with i and sj with j
+    si.add(i);
+    sj.add(j);
+    // compute intersection, reference as set 's'
+    List<InterfaceType> s = _intersection(si, sj);
+    // for each element in Set s, compute the largest inheritance path to Object
+    List<int> depths = new List<int>.filled(s.length, 0);
+    int maxDepth = 0;
+    for (int n = 0; n < s.length; n++) {
+      depths[n] = computeLongestInheritancePathToObject(s[n]);
+      if (depths[n] > maxDepth) {
+        maxDepth = depths[n];
+      }
+    }
+    // ensure that the currently computed maxDepth is unique,
+    // otherwise, decrement and test for uniqueness again
+    for (; maxDepth >= 0; maxDepth--) {
+      int indexOfLeastUpperBound = -1;
+      int numberOfTypesAtMaxDepth = 0;
+      for (int m = 0; m < depths.length; m++) {
+        if (depths[m] == maxDepth) {
+          numberOfTypesAtMaxDepth++;
+          indexOfLeastUpperBound = m;
+        }
+      }
+      if (numberOfTypesAtMaxDepth == 1) {
+        return s[indexOfLeastUpperBound];
+      }
+    }
+    // Should be impossible--there should always be exactly one type with the
+    // maximum depth.
+    assert(false);
+    return null;
+  }
+
+  /**
+   * Return the length of the longest inheritance path from the given [type] to
+   * Object.
+   *
+   * See [computeLeastUpperBound].
+   */
+  static int computeLongestInheritancePathToObject(InterfaceType type) =>
+      _computeLongestInheritancePathToObject(
+          type, 0, new HashSet<ClassElement>());
+
+  /**
+   * Returns the set of all superinterfaces of the given [type].
+   *
+   * See [computeLeastUpperBound].
+   */
+  static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) =>
+      _computeSuperinterfaceSet(type, new HashSet<InterfaceType>());
+
+  /**
+   * Returns a "smart" version of the "least upper bound" of the given types.
+   *
+   * If these types have the same element and differ only in terms of the type
+   * arguments, attempts to find a compatible set of type arguments.
+   *
+   * Otherwise, calls [DartType.getLeastUpperBound].
+   */
+  static InterfaceType getSmartLeastUpperBound(
+      InterfaceType first, InterfaceType second) {
+    // TODO(paulberry): this needs to be deprecated and replaced with a method
+    // in [TypeSystem], since it relies on the deprecated functionality of
+    // [DartType.getLeastUpperBound].
+    if (first.element == second.element) {
+      return _leastUpperBound(first, second);
+    }
+    AnalysisContext context = first.element.context;
+    return context.typeSystem
+        .getLeastUpperBound(context.typeProvider, first, second);
+  }
+
+  /**
+   * Return the length of the longest inheritance path from a subtype of the
+   * given [type] to Object, where the given [depth] is the length of the
+   * longest path from the subtype to this type. The set of [visitedTypes] is
+   * used to prevent infinite recursion in the case of a cyclic type structure.
+   *
+   * See [computeLongestInheritancePathToObject], and [computeLeastUpperBound].
+   */
+  static int _computeLongestInheritancePathToObject(
+      InterfaceType type, int depth, HashSet<ClassElement> visitedTypes) {
+    ClassElement classElement = type.element;
+    // Object case
+    if (classElement.supertype == null || visitedTypes.contains(classElement)) {
+      return depth;
+    }
+    int longestPath = 1;
+    try {
+      visitedTypes.add(classElement);
+      List<InterfaceType> superinterfaces = classElement.interfaces;
+      int pathLength;
+      if (superinterfaces.length > 0) {
+        // loop through each of the superinterfaces recursively calling this
+        // method and keeping track of the longest path to return
+        for (InterfaceType superinterface in superinterfaces) {
+          pathLength = _computeLongestInheritancePathToObject(
+              superinterface, depth + 1, visitedTypes);
+          if (pathLength > longestPath) {
+            longestPath = pathLength;
+          }
+        }
+      }
+      // finally, perform this same check on the super type
+      // TODO(brianwilkerson) Does this also need to add in the number of mixin
+      // classes?
+      InterfaceType supertype = classElement.supertype;
+      pathLength = _computeLongestInheritancePathToObject(
+          supertype, depth + 1, visitedTypes);
+      if (pathLength > longestPath) {
+        longestPath = pathLength;
+      }
+    } finally {
+      visitedTypes.remove(classElement);
+    }
+    return longestPath;
+  }
+
+  /**
+   * Add all of the superinterfaces of the given [type] to the given [set].
+   * Return the [set] as a convenience.
+   *
+   * See [computeSuperinterfaceSet], and [computeLeastUpperBound].
+   */
+  static Set<InterfaceType> _computeSuperinterfaceSet(
+      InterfaceType type, HashSet<InterfaceType> set) {
+    Element element = type.element;
+    if (element != null) {
+      List<InterfaceType> superinterfaces = type.interfaces;
+      for (InterfaceType superinterface in superinterfaces) {
+        if (set.add(superinterface)) {
+          _computeSuperinterfaceSet(superinterface, set);
+        }
+      }
+      InterfaceType supertype = type.superclass;
+      if (supertype != null) {
+        if (set.add(supertype)) {
+          _computeSuperinterfaceSet(supertype, set);
+        }
+      }
+    }
+    return set;
+  }
+
+  /**
+   * Return the intersection of the [first] and [second] sets of types, where
+   * intersection is based on the equality of the types themselves.
+   */
+  static List<InterfaceType> _intersection(
+      Set<InterfaceType> first, Set<InterfaceType> second) {
+    Set<InterfaceType> result = new HashSet<InterfaceType>.from(first);
+    result.retainAll(second);
+    return new List.from(result);
+  }
+
+  /**
+   * Return the "least upper bound" of the given types under the assumption that
+   * the types have the same element and differ only in terms of the type
+   * arguments.
+   *
+   * The resulting type is composed by comparing the corresponding type
+   * arguments, keeping those that are the same, and using 'dynamic' for those
+   * that are different.
+   */
+  static InterfaceType _leastUpperBound(
+      InterfaceType firstType, InterfaceType secondType) {
+    ClassElement firstElement = firstType.element;
+    ClassElement secondElement = secondType.element;
+    if (firstElement != secondElement) {
+      throw new IllegalArgumentException('The same elements expected, but '
+          '$firstElement and $secondElement are given.');
+    }
+    if (firstType == secondType) {
+      return firstType;
+    }
+    List<DartType> firstArguments = firstType.typeArguments;
+    List<DartType> secondArguments = secondType.typeArguments;
+    int argumentCount = firstArguments.length;
+    if (argumentCount == 0) {
+      return firstType;
+    }
+    List<DartType> lubArguments = new List<DartType>(argumentCount);
+    for (int i = 0; i < argumentCount; i++) {
+      //
+      // Ideally we would take the least upper bound of the two argument types,
+      // but this can cause an infinite recursion (such as when finding the
+      // least upper bound of String and num).
+      //
+      if (firstArguments[i] == secondArguments[i]) {
+        lubArguments[i] = firstArguments[i];
+      }
+      if (lubArguments[i] == null) {
+        lubArguments[i] = DynamicTypeImpl.instance;
+      }
+    }
+    InterfaceTypeImpl lub = new InterfaceTypeImpl(firstElement);
+    lub.typeArguments = lubArguments;
+    return lub;
+  }
+
+  /**
+   * Look up the getter with the given [name] in the interfaces
+   * implemented by the given [targetType], either directly or indirectly.
+   * Return the element representing the getter that was found, or `null` if
+   * there is no getter with the given name. The flag [includeTargetType] should
+   * be `true` if the search should include the target type. The
+   * [visitedInterfaces] is a set containing all of the interfaces that have
+   * been examined, used to prevent infinite recursion and to optimize the
+   * search.
+   */
+  static ExecutableElement _lookUpMemberInInterfaces(
+      InterfaceType targetType,
+      bool includeTargetType,
+      LibraryElement library,
+      HashSet<ClassElement> visitedInterfaces,
+      ExecutableElement getMember(InterfaceType type)) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
+    // specification (titled "Inheritance and Overriding" under "Interfaces")
+    // describes a much more complex scheme for finding the inherited member.
+    // We need to follow that scheme. The code below should cover the 80% case.
+    ClassElement targetClass = targetType.element;
+    if (!visitedInterfaces.add(targetClass)) {
+      return null;
+    }
+    if (includeTargetType) {
+      ExecutableElement member = getMember(targetType);
+      if (member != null && member.isAccessibleIn(library)) {
+        return member;
+      }
+    }
+    for (InterfaceType interfaceType in targetType.interfaces) {
+      ExecutableElement member = _lookUpMemberInInterfaces(
+          interfaceType, true, library, visitedInterfaces, getMember);
+      if (member != null) {
+        return member;
+      }
+    }
+    for (InterfaceType mixinType in targetType.mixins.reversed) {
+      ExecutableElement member = _lookUpMemberInInterfaces(
+          mixinType, true, library, visitedInterfaces, getMember);
+      if (member != null) {
+        return member;
+      }
+    }
+    InterfaceType superclass = targetType.superclass;
+    if (superclass == null) {
+      return null;
+    }
+    return _lookUpMemberInInterfaces(
+        superclass, true, library, visitedInterfaces, getMember);
+  }
+}
+
+/**
+ * The abstract class `TypeImpl` implements the behavior common to objects
+ * representing the declared type of elements in the element model.
+ */
+abstract class TypeImpl implements DartType {
+  /**
+   * The element representing the declaration of this type, or `null` if the
+   * type has not, or cannot, be associated with an element.
+   */
+  final Element _element;
+
+  /**
+   * The name of this type, or `null` if the type does not have a name.
+   */
+  final String name;
+
+  /**
+   * Initialize a newly created type to be declared by the given [element] and
+   * to have the given [name].
+   */
+  TypeImpl(this._element, this.name);
+
+  @override
+  String get displayName => name;
+
+  @override
+  Element get element => _element;
+
+  @override
+  bool get isBottom => false;
+
+  @override
+  bool get isDartCoreFunction => false;
+
+  @override
+  bool get isDynamic => false;
+
+  @override
+  bool get isObject => false;
+
+  @override
+  bool get isUndefined => false;
+
+  @override
+  bool get isVoid => false;
+
+  /**
+   * Append a textual representation of this type to the given [buffer]. The set
+   * of [visitedTypes] is used to prevent infinite recursion.
+   */
+  void appendTo(StringBuffer buffer) {
+    if (name == null) {
+      buffer.write("<unnamed type>");
+    } else {
+      buffer.write(name);
+    }
+  }
+
+  /**
+   * Return `true` if this type is assignable to the given [type] (written in
+   * the spec as "T <=> S", where T=[this] and S=[type]).
+   *
+   * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
+   * function type aliases that have been expanded so far in the process of
+   * reaching [this] and [type], respectively.  These are used to avoid
+   * infinite regress when analyzing invalid code; since the language spec
+   * forbids a typedef from referring to itself directly or indirectly, we can
+   * use these as sets of function type aliases that don't need to be expanded.
+   */
+  @override
+  bool isAssignableTo(DartType type) {
+    // An interface type T may be assigned to a type S, written T <=> S, iff
+    // either T <: S or S <: T.
+    return isSubtypeOf(type) || (type as TypeImpl).isSubtypeOf(this);
+  }
+
+  /**
+   * Return `true` if this type is more specific than the given [type] (written
+   * in the spec as "T << S", where T=[this] and S=[type]).
+   *
+   * If [withDynamic] is `true`, then "dynamic" should be considered as a
+   * subtype of any type (as though "dynamic" had been replaced with bottom).
+   *
+   * The set [visitedElements], if given, is the set of classes and type
+   * parameters that have been visited so far while examining the class
+   * hierarchy of [this].  This is used to avoid infinite regress when
+   * analyzing invalid code; since the language spec forbids loops in the class
+   * hierarchy, we can use this as a set of classes that don't need to be
+   * examined when walking the class hierarchy.
+   */
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]);
+
+  /**
+   * Return `true` if this type is a subtype of the given [type] (written in
+   * the spec as "T <: S", where T=[this] and S=[type]).
+   *
+   * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
+   * function type aliases that have been expanded so far in the process of
+   * reaching [this] and [type], respectively.  These are used to avoid
+   * infinite regress when analyzing invalid code; since the language spec
+   * forbids a typedef from referring to itself directly or indirectly, we can
+   * use these as sets of function type aliases that don't need to be expanded.
+   */
+  @override
+  bool isSubtypeOf(DartType type) {
+    // For non-function types, T <: S iff [_|_/dynamic]T << S.
+    return isMoreSpecificThan(type, true);
+  }
+
+  @override
+  bool isSupertypeOf(DartType type) => type.isSubtypeOf(this);
+
+  /**
+   * Create a new [TypeImpl] that is identical to [this] except that when
+   * visiting type parameters, function parameter types, and function return
+   * types, function types listed in [prune] will not be expanded.  This is
+   * used to avoid creating infinite types in the presence of circular
+   * typedefs.
+   *
+   * If [prune] is null, then [this] is returned unchanged.
+   *
+   * Only legal to call on a [TypeImpl] that is not already subject to pruning.
+   */
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune);
+
+  /**
+   * Return the type resulting from substituting the given [argumentTypes] for
+   * the given [parameterTypes] in this type.
+   *
+   * In all classes derived from [TypeImpl], a new optional argument
+   * [prune] is added.  If specified, it is a list of function typdefs
+   * which should not be expanded.  This is used to avoid creating infinite
+   * types in response to self-referential typedefs.
+   */
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]);
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    appendTo(buffer);
+    return buffer.toString();
+  }
+
+  /**
+   * Return `true` if corresponding elements of the [first] and [second] lists
+   * of type arguments are all equal.
+   */
+  static bool equalArrays(List<DartType> first, List<DartType> second) {
+    if (first.length != second.length) {
+      return false;
+    }
+    for (int i = 0; i < first.length; i++) {
+      if (first[i] == null) {
+        AnalysisEngine.instance.logger
+            .logInformation('Found null type argument in TypeImpl.equalArrays');
+        return second[i] == null;
+      } else if (second[i] == null) {
+        AnalysisEngine.instance.logger
+            .logInformation('Found null type argument in TypeImpl.equalArrays');
+        return false;
+      }
+      if (first[i] != second[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Return a list containing the results of using the given [argumentTypes] and
+   * [parameterTypes] to perform a substitution on all of the given [types].
+   *
+   * If [prune] is specified, it is a list of function typdefs which should not
+   * be expanded.  This is used to avoid creating infinite types in response to
+   * self-referential typedefs.
+   */
+  static List<DartType> substitute(List<DartType> types,
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    int length = types.length;
+    if (length == 0) {
+      return types;
+    }
+    List<DartType> newTypes = new List<DartType>(length);
+    for (int i = 0; i < length; i++) {
+      newTypes[i] = (types[i] as TypeImpl)
+          .substitute2(argumentTypes, parameterTypes, prune);
+    }
+    return newTypes;
+  }
+}
+
+/**
+ * A concrete implementation of a [TypeParameterType].
+ */
+class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
+  /**
+   * Initialize a newly created type parameter type to be declared by the given
+   * [element] and to have the given name.
+   */
+  TypeParameterTypeImpl(TypeParameterElement element)
+      : super(element, element.name);
+
+  @override
+  TypeParameterElement get element => super.element as TypeParameterElement;
+
+  @override
+  int get hashCode => element.hashCode;
+
+  @override
+  bool operator ==(Object object) =>
+      object is TypeParameterTypeImpl && (element == object.element);
+
+  @override
+  bool isMoreSpecificThan(DartType s,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    //
+    // A type T is more specific than a type S, written T << S,
+    // if one of the following conditions is met:
+    //
+    // Reflexivity: T is S.
+    //
+    if (this == s) {
+      return true;
+    }
+    // S is dynamic.
+    //
+    if (s.isDynamic) {
+      return true;
+    }
+    //
+    // T is a type parameter and S is the upper bound of T.
+    //
+    TypeImpl bound = element.bound;
+    if (s == bound) {
+      return true;
+    }
+    //
+    // T is a type parameter and S is Object.
+    //
+    if (s.isObject) {
+      return true;
+    }
+    // We need upper bound to continue.
+    if (bound == null) {
+      return false;
+    }
+    //
+    // Transitivity: T << U and U << S.
+    //
+    // First check for infinite loops
+    if (element == null) {
+      return false;
+    }
+    if (visitedElements == null) {
+      visitedElements = new HashSet<Element>();
+    } else if (visitedElements.contains(element)) {
+      return false;
+    }
+    visitedElements.add(element);
+    try {
+      return bound.isMoreSpecificThan(s, withDynamic, visitedElements);
+    } finally {
+      visitedElements.remove(element);
+    }
+  }
+
+  @override
+  bool isSubtypeOf(DartType type) => isMoreSpecificThan(type, true);
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    int length = parameterTypes.length;
+    for (int i = 0; i < length; i++) {
+      if (parameterTypes[i] == this) {
+        return argumentTypes[i];
+      }
+    }
+    return this;
+  }
+
+  /**
+   * Return a list containing the type parameter types defined by the given
+   * array of type parameter elements ([typeParameters]).
+   */
+  static List<TypeParameterType> getTypes(
+      List<TypeParameterElement> typeParameters) {
+    int count = typeParameters.length;
+    if (count == 0) {
+      return TypeParameterType.EMPTY_LIST;
+    }
+    List<TypeParameterType> types = new List<TypeParameterType>(count);
+    for (int i = 0; i < count; i++) {
+      types[i] = typeParameters[i].type;
+    }
+    return types;
+  }
+}
+
+/**
+ * The unique instance of the class `UndefinedTypeImpl` implements the type of
+ * type names that couldn't be resolved.
+ *
+ * This class behaves like DynamicTypeImpl in almost every respect, to reduce
+ * cascading errors.
+ */
+class UndefinedTypeImpl extends TypeImpl {
+  /**
+   * The unique instance of this class.
+   */
+  static UndefinedTypeImpl _INSTANCE = new UndefinedTypeImpl._();
+
+  /**
+   * Return the unique instance of this class.
+   */
+  static UndefinedTypeImpl get instance => _INSTANCE;
+
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  UndefinedTypeImpl._()
+      : super(DynamicElementImpl.instance, Keyword.DYNAMIC.syntax);
+
+  @override
+  int get hashCode => 1;
+
+  @override
+  bool get isDynamic => true;
+
+  @override
+  bool get isUndefined => true;
+
+  @override
+  bool operator ==(Object object) => identical(object, this);
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    // T is S
+    if (identical(this, type)) {
+      return true;
+    }
+    // else
+    return withDynamic;
+  }
+
+  @override
+  bool isSubtypeOf(DartType type) => true;
+
+  @override
+  bool isSupertypeOf(DartType type) => true;
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    int length = parameterTypes.length;
+    for (int i = 0; i < length; i++) {
+      if (parameterTypes[i] == this) {
+        return argumentTypes[i];
+      }
+    }
+    return this;
+  }
+}
+
+/**
+ * The type `void`.
+ */
+abstract class VoidType implements DartType {
+  @override
+  VoidType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes);
+}
+
+/**
+ * A concrete implementation of a [VoidType].
+ */
+class VoidTypeImpl extends TypeImpl implements VoidType {
+  /**
+   * The unique instance of this class.
+   */
+  static VoidTypeImpl _INSTANCE = new VoidTypeImpl();
+
+  /**
+   * Return the unique instance of this class.
+   */
+  static VoidTypeImpl get instance => _INSTANCE;
+
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  VoidTypeImpl() : super(null, Keyword.VOID.syntax);
+
+  @override
+  int get hashCode => 2;
+
+  @override
+  bool get isVoid => true;
+
+  @override
+  bool operator ==(Object object) => identical(object, this);
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+          [bool withDynamic = false, Set<Element> visitedElements]) =>
+      isSubtypeOf(type);
+
+  @override
+  bool isSubtypeOf(DartType type) {
+    // The only subtype relations that pertain to void are therefore:
+    // void <: void (by reflexivity)
+    // bottom <: void (as bottom is a subtype of all types).
+    // void <: dynamic (as dynamic is a supertype of all types)
+    return identical(type, this) || type.isDynamic;
+  }
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  VoidTypeImpl substitute2(
+          List<DartType> argumentTypes, List<DartType> parameterTypes,
+          [List<FunctionTypeAliasElement> prune]) =>
+      this;
+}
diff --git a/pkg/analyzer/lib/src/error.dart b/pkg/analyzer/lib/src/error.dart
index 60f5cf0..35ffb7c 100644
--- a/pkg/analyzer/lib/src/error.dart
+++ b/pkg/analyzer/lib/src/error.dart
@@ -1,11 +1,11 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-library error;
+library analyzer.src.error;
 
 import 'dart:collection';
 
-import 'generated/error.dart';
+import 'package:analyzer/src/generated/error.dart';
 
 /// The maximum line length when printing extracted source code when converting
 /// an [AnalyzerError] to a string.
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index 03cb8f1..3daca75 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -2,19 +2,25 @@
 // for 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 engine.ast;
+library analyzer.src.generated.ast;
 
 import 'dart:collection';
 
-import 'element.dart';
-import 'engine.dart' show AnalysisEngine;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart';
-import 'scanner.dart';
-import 'source.dart' show LineInfo, Source;
-import 'utilities_collection.dart' show TokenMap;
-import 'utilities_dart.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+export 'package:analyzer/dart/ast/visitor.dart';
+export 'package:analyzer/src/dart/ast/utilities.dart';
 
 /**
  * Two or more string literals that are implicitly concatenated because of being
@@ -140,15 +146,6 @@
   NodeList<Annotation> get metadata => _metadata;
 
   /**
-   * Set the metadata associated with this node to the given [metadata].
-   */
-  @deprecated // Directly modify the list returned by "this.metadata"
-  void set metadata(List<Annotation> metadata) {
-    _metadata.clear();
-    _metadata.addAll(metadata);
-  }
-
-  /**
    * Return a list containing the comment and annotations associated with this
    * node, sorted in lexical order.
    */
@@ -465,37 +462,6 @@
   @override
   accept(AstVisitor visitor) => visitor.visitArgumentList(this);
 
-  /**
-   * If
-   * * the given [expression] is a child of this list,
-   * * the AST structure has been resolved,
-   * * the function being invoked is known based on propagated type information,
-   *   and
-   * * the expression corresponds to one of the parameters of the function being
-   *   invoked,
-   * then return the parameter element representing the parameter to which the
-   * value of the given expression will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement getPropagatedParameterElementFor(Expression expression) {
-    return _getPropagatedParameterElementFor(expression);
-  }
-
-  /**
-   * If
-   * * the given [expression] is a child of this list,
-   * * the AST structure has been resolved,
-   * * the function being invoked is known based on static type information, and
-   * * the expression corresponds to one of the parameters of the function being
-   *   invoked,
-   * then return the parameter element representing the parameter to which the
-   * value of the given expression will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.staticParameterElement"
-  ParameterElement getStaticParameterElementFor(Expression expression) {
-    return _getStaticParameterElementFor(expression);
-  }
-
   @override
   void visitChildren(AstVisitor visitor) {
     _arguments.accept(visitor);
@@ -656,6 +622,17 @@
   Expression _condition;
 
   /**
+   * The comma, if a message expression was supplied.  Otherwise `null`.
+   */
+  Token comma;
+
+  /**
+   * The message to report if the assertion fails.  `null` if no message was
+   * supplied.
+   */
+  Expression _message;
+
+  /**
    * The right parenthesis.
    */
   Token rightParenthesis;
@@ -668,9 +645,16 @@
   /**
    * Initialize a newly created assert statement.
    */
-  AssertStatement(this.assertKeyword, this.leftParenthesis,
-      Expression condition, this.rightParenthesis, this.semicolon) {
+  AssertStatement(
+      this.assertKeyword,
+      this.leftParenthesis,
+      Expression condition,
+      this.comma,
+      Expression message,
+      this.rightParenthesis,
+      this.semicolon) {
     _condition = _becomeParentOf(condition);
+    _message = _becomeParentOf(message);
   }
 
   @override
@@ -681,6 +665,8 @@
     ..add(assertKeyword)
     ..add(leftParenthesis)
     ..add(_condition)
+    ..add(comma)
+    ..add(_message)
     ..add(rightParenthesis)
     ..add(semicolon);
 
@@ -701,17 +687,16 @@
   Token get endToken => semicolon;
 
   /**
-   * Return the token representing the 'assert' keyword.
+   * Return the message to report if the assertion fails.
    */
-  @deprecated // Use "this.assertKeyword"
-  Token get keyword => assertKeyword;
+  Expression get message => _message;
 
   /**
-   * Set the token representing the 'assert' keyword to the given [token].
+   * Set the message to report if the assertion fails to the given
+   * [expression].
    */
-  @deprecated // Use "this.assertKeyword"
-  set keyword(Token token) {
-    assertKeyword = token;
+  void set message(Expression expression) {
+    _message = _becomeParentOf(expression);
   }
 
   @override
@@ -720,6 +705,7 @@
   @override
   void visitChildren(AstVisitor visitor) {
     _safelyVisitChild(_condition, visitor);
+    _safelyVisitChild(message, visitor);
   }
 }
 
@@ -828,17 +814,6 @@
   int get precedence => 1;
 
   /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the right operand
-   * will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForRightHandSide {
-    return _propagatedParameterElementForRightHandSide;
-  }
-
-  /**
    * Return the expression used to compute the right hand side.
    */
   Expression get rightHandSide => _rightHandSide;
@@ -853,17 +828,6 @@
 
   /**
    * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the right operand will be
-   * bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.staticParameterElement"
-  ParameterElement get staticParameterElementForRightHandSide {
-    return _staticParameterElementForRightHandSide;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
    * known based on propagated type information, then return the parameter
    * element representing the parameter to which the value of the right operand
    * will be bound. Otherwise, return `null`.
@@ -945,1935 +909,12 @@
 }
 
 /**
- * An AST visitor that will clone any AST structure that it visits. The cloner
- * will only clone the structure, it will not preserve any resolution results or
- * properties associated with the nodes.
- */
-class AstCloner implements AstVisitor<AstNode> {
-  /**
-   * A flag indicating whether tokens should be cloned while cloning an AST
-   * structure.
-   */
-  final bool cloneTokens;
-
-  /**
-   * Initialize a newly created AST cloner to optionally clone tokens while
-   * cloning AST nodes if [cloneTokens] is `true`.
-   */
-  AstCloner(
-      [this.cloneTokens =
-          false]); // TODO(brianwilkerson) Change this to be a named parameter.
-
-  /**
-   * Return a clone of the given [node].
-   */
-  AstNode cloneNode(AstNode node) {
-    if (node == null) {
-      return null;
-    }
-    return node.accept(this) as AstNode;
-  }
-
-  /**
-   * Return a list containing cloned versions of the nodes in the given list of
-   * [nodes].
-   */
-  List<AstNode> cloneNodeList(NodeList nodes) {
-    int count = nodes.length;
-    List clonedNodes = new List();
-    for (int i = 0; i < count; i++) {
-      clonedNodes.add((nodes[i]).accept(this) as AstNode);
-    }
-    return clonedNodes;
-  }
-
-  /**
-   * Clone the given [token] if tokens are supposed to be cloned.
-   */
-  Token cloneToken(Token token) {
-    if (cloneTokens) {
-      return (token == null ? null : token.copy());
-    } else {
-      return token;
-    }
-  }
-
-  /**
-   * Clone the given [tokens] if tokens are supposed to be cloned.
-   */
-  List<Token> cloneTokenList(List<Token> tokens) {
-    if (cloneTokens) {
-      return tokens.map((Token token) => token.copy()).toList();
-    }
-    return tokens;
-  }
-
-  @override
-  AdjacentStrings visitAdjacentStrings(AdjacentStrings node) =>
-      new AdjacentStrings(cloneNodeList(node.strings));
-
-  @override
-  Annotation visitAnnotation(Annotation node) => new Annotation(
-      cloneToken(node.atSign),
-      cloneNode(node.name),
-      cloneToken(node.period),
-      cloneNode(node.constructorName),
-      cloneNode(node.arguments));
-
-  @override
-  ArgumentList visitArgumentList(ArgumentList node) => new ArgumentList(
-      cloneToken(node.leftParenthesis),
-      cloneNodeList(node.arguments),
-      cloneToken(node.rightParenthesis));
-
-  @override
-  AsExpression visitAsExpression(AsExpression node) => new AsExpression(
-      cloneNode(node.expression),
-      cloneToken(node.asOperator),
-      cloneNode(node.type));
-
-  @override
-  AstNode visitAssertStatement(AssertStatement node) => new AssertStatement(
-      cloneToken(node.assertKeyword),
-      cloneToken(node.leftParenthesis),
-      cloneNode(node.condition),
-      cloneToken(node.rightParenthesis),
-      cloneToken(node.semicolon));
-
-  @override
-  AssignmentExpression visitAssignmentExpression(AssignmentExpression node) =>
-      new AssignmentExpression(cloneNode(node.leftHandSide),
-          cloneToken(node.operator), cloneNode(node.rightHandSide));
-
-  @override
-  AwaitExpression visitAwaitExpression(AwaitExpression node) =>
-      new AwaitExpression(
-          cloneToken(node.awaitKeyword), cloneNode(node.expression));
-
-  @override
-  BinaryExpression visitBinaryExpression(BinaryExpression node) =>
-      new BinaryExpression(cloneNode(node.leftOperand),
-          cloneToken(node.operator), cloneNode(node.rightOperand));
-
-  @override
-  Block visitBlock(Block node) => new Block(cloneToken(node.leftBracket),
-      cloneNodeList(node.statements), cloneToken(node.rightBracket));
-
-  @override
-  BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) =>
-      new BlockFunctionBody(cloneToken(node.keyword), cloneToken(node.star),
-          cloneNode(node.block));
-
-  @override
-  BooleanLiteral visitBooleanLiteral(BooleanLiteral node) =>
-      new BooleanLiteral(cloneToken(node.literal), node.value);
-
-  @override
-  BreakStatement visitBreakStatement(BreakStatement node) => new BreakStatement(
-      cloneToken(node.breakKeyword),
-      cloneNode(node.label),
-      cloneToken(node.semicolon));
-
-  @override
-  CascadeExpression visitCascadeExpression(CascadeExpression node) =>
-      new CascadeExpression(
-          cloneNode(node.target), cloneNodeList(node.cascadeSections));
-
-  @override
-  CatchClause visitCatchClause(CatchClause node) => new CatchClause(
-      cloneToken(node.onKeyword),
-      cloneNode(node.exceptionType),
-      cloneToken(node.catchKeyword),
-      cloneToken(node.leftParenthesis),
-      cloneNode(node.exceptionParameter),
-      cloneToken(node.comma),
-      cloneNode(node.stackTraceParameter),
-      cloneToken(node.rightParenthesis),
-      cloneNode(node.body));
-
-  @override
-  ClassDeclaration visitClassDeclaration(ClassDeclaration node) {
-    ClassDeclaration copy = new ClassDeclaration(
-        cloneNode(node.documentationComment),
-        cloneNodeList(node.metadata),
-        cloneToken(node.abstractKeyword),
-        cloneToken(node.classKeyword),
-        cloneNode(node.name),
-        cloneNode(node.typeParameters),
-        cloneNode(node.extendsClause),
-        cloneNode(node.withClause),
-        cloneNode(node.implementsClause),
-        cloneToken(node.leftBracket),
-        cloneNodeList(node.members),
-        cloneToken(node.rightBracket));
-    copy.nativeClause = cloneNode(node.nativeClause);
-    return copy;
-  }
-
-  @override
-  ClassTypeAlias visitClassTypeAlias(ClassTypeAlias node) => new ClassTypeAlias(
-      cloneNode(node.documentationComment),
-      cloneNodeList(node.metadata),
-      cloneToken(node.typedefKeyword),
-      cloneNode(node.name),
-      cloneNode(node.typeParameters),
-      cloneToken(node.equals),
-      cloneToken(node.abstractKeyword),
-      cloneNode(node.superclass),
-      cloneNode(node.withClause),
-      cloneNode(node.implementsClause),
-      cloneToken(node.semicolon));
-
-  @override
-  Comment visitComment(Comment node) {
-    if (node.isDocumentation) {
-      return Comment.createDocumentationCommentWithReferences(
-          cloneTokenList(node.tokens), cloneNodeList(node.references));
-    } else if (node.isBlock) {
-      return Comment.createBlockComment(cloneTokenList(node.tokens));
-    }
-    return Comment.createEndOfLineComment(cloneTokenList(node.tokens));
-  }
-
-  @override
-  CommentReference visitCommentReference(CommentReference node) =>
-      new CommentReference(
-          cloneToken(node.newKeyword), cloneNode(node.identifier));
-
-  @override
-  CompilationUnit visitCompilationUnit(CompilationUnit node) {
-    CompilationUnit clone = new CompilationUnit(
-        cloneToken(node.beginToken),
-        cloneNode(node.scriptTag),
-        cloneNodeList(node.directives),
-        cloneNodeList(node.declarations),
-        cloneToken(node.endToken));
-    clone.lineInfo = node.lineInfo;
-    return clone;
-  }
-
-  @override
-  ConditionalExpression visitConditionalExpression(
-          ConditionalExpression node) =>
-      new ConditionalExpression(
-          cloneNode(node.condition),
-          cloneToken(node.question),
-          cloneNode(node.thenExpression),
-          cloneToken(node.colon),
-          cloneNode(node.elseExpression));
-
-  @override
-  ConstructorDeclaration visitConstructorDeclaration(
-          ConstructorDeclaration node) =>
-      new ConstructorDeclaration(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.externalKeyword),
-          cloneToken(node.constKeyword),
-          cloneToken(node.factoryKeyword),
-          cloneNode(node.returnType),
-          cloneToken(node.period),
-          cloneNode(node.name),
-          cloneNode(node.parameters),
-          cloneToken(node.separator),
-          cloneNodeList(node.initializers),
-          cloneNode(node.redirectedConstructor),
-          cloneNode(node.body));
-
-  @override
-  ConstructorFieldInitializer visitConstructorFieldInitializer(
-          ConstructorFieldInitializer node) =>
-      new ConstructorFieldInitializer(
-          cloneToken(node.thisKeyword),
-          cloneToken(node.period),
-          cloneNode(node.fieldName),
-          cloneToken(node.equals),
-          cloneNode(node.expression));
-
-  @override
-  ConstructorName visitConstructorName(ConstructorName node) =>
-      new ConstructorName(
-          cloneNode(node.type), cloneToken(node.period), cloneNode(node.name));
-
-  @override
-  ContinueStatement visitContinueStatement(ContinueStatement node) =>
-      new ContinueStatement(cloneToken(node.continueKeyword),
-          cloneNode(node.label), cloneToken(node.semicolon));
-
-  @override
-  DeclaredIdentifier visitDeclaredIdentifier(DeclaredIdentifier node) =>
-      new DeclaredIdentifier(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.keyword),
-          cloneNode(node.type),
-          cloneNode(node.identifier));
-
-  @override
-  DefaultFormalParameter visitDefaultFormalParameter(
-          DefaultFormalParameter node) =>
-      new DefaultFormalParameter(cloneNode(node.parameter), node.kind,
-          cloneToken(node.separator), cloneNode(node.defaultValue));
-
-  @override
-  DoStatement visitDoStatement(DoStatement node) => new DoStatement(
-      cloneToken(node.doKeyword),
-      cloneNode(node.body),
-      cloneToken(node.whileKeyword),
-      cloneToken(node.leftParenthesis),
-      cloneNode(node.condition),
-      cloneToken(node.rightParenthesis),
-      cloneToken(node.semicolon));
-
-  @override
-  DoubleLiteral visitDoubleLiteral(DoubleLiteral node) =>
-      new DoubleLiteral(cloneToken(node.literal), node.value);
-
-  @override
-  EmptyFunctionBody visitEmptyFunctionBody(EmptyFunctionBody node) =>
-      new EmptyFunctionBody(cloneToken(node.semicolon));
-
-  @override
-  EmptyStatement visitEmptyStatement(EmptyStatement node) =>
-      new EmptyStatement(cloneToken(node.semicolon));
-
-  @override
-  AstNode visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
-      new EnumConstantDeclaration(cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata), cloneNode(node.name));
-
-  @override
-  EnumDeclaration visitEnumDeclaration(EnumDeclaration node) =>
-      new EnumDeclaration(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.enumKeyword),
-          cloneNode(node.name),
-          cloneToken(node.leftBracket),
-          cloneNodeList(node.constants),
-          cloneToken(node.rightBracket));
-
-  @override
-  ExportDirective visitExportDirective(ExportDirective node) {
-    ExportDirective directive = new ExportDirective(
-        cloneNode(node.documentationComment),
-        cloneNodeList(node.metadata),
-        cloneToken(node.keyword),
-        cloneNode(node.uri),
-        cloneNodeList(node.combinators),
-        cloneToken(node.semicolon));
-    directive.source = node.source;
-    directive.uriContent = node.uriContent;
-    return directive;
-  }
-
-  @override
-  ExpressionFunctionBody visitExpressionFunctionBody(
-          ExpressionFunctionBody node) =>
-      new ExpressionFunctionBody(
-          cloneToken(node.keyword),
-          cloneToken(node.functionDefinition),
-          cloneNode(node.expression),
-          cloneToken(node.semicolon));
-
-  @override
-  ExpressionStatement visitExpressionStatement(ExpressionStatement node) =>
-      new ExpressionStatement(
-          cloneNode(node.expression), cloneToken(node.semicolon));
-
-  @override
-  ExtendsClause visitExtendsClause(ExtendsClause node) => new ExtendsClause(
-      cloneToken(node.extendsKeyword), cloneNode(node.superclass));
-
-  @override
-  FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
-      new FieldDeclaration(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.staticKeyword),
-          cloneNode(node.fields),
-          cloneToken(node.semicolon));
-
-  @override
-  FieldFormalParameter visitFieldFormalParameter(FieldFormalParameter node) =>
-      new FieldFormalParameter(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.keyword),
-          cloneNode(node.type),
-          cloneToken(node.thisKeyword),
-          cloneToken(node.period),
-          cloneNode(node.identifier),
-          cloneNode(node.typeParameters),
-          cloneNode(node.parameters));
-
-  @override
-  ForEachStatement visitForEachStatement(ForEachStatement node) {
-    DeclaredIdentifier loopVariable = node.loopVariable;
-    if (loopVariable == null) {
-      return new ForEachStatement.withReference(
-          cloneToken(node.awaitKeyword),
-          cloneToken(node.forKeyword),
-          cloneToken(node.leftParenthesis),
-          cloneNode(node.identifier),
-          cloneToken(node.inKeyword),
-          cloneNode(node.iterable),
-          cloneToken(node.rightParenthesis),
-          cloneNode(node.body));
-    }
-    return new ForEachStatement.withDeclaration(
-        cloneToken(node.awaitKeyword),
-        cloneToken(node.forKeyword),
-        cloneToken(node.leftParenthesis),
-        cloneNode(loopVariable),
-        cloneToken(node.inKeyword),
-        cloneNode(node.iterable),
-        cloneToken(node.rightParenthesis),
-        cloneNode(node.body));
-  }
-
-  @override
-  FormalParameterList visitFormalParameterList(FormalParameterList node) =>
-      new FormalParameterList(
-          cloneToken(node.leftParenthesis),
-          cloneNodeList(node.parameters),
-          cloneToken(node.leftDelimiter),
-          cloneToken(node.rightDelimiter),
-          cloneToken(node.rightParenthesis));
-
-  @override
-  ForStatement visitForStatement(ForStatement node) => new ForStatement(
-      cloneToken(node.forKeyword),
-      cloneToken(node.leftParenthesis),
-      cloneNode(node.variables),
-      cloneNode(node.initialization),
-      cloneToken(node.leftSeparator),
-      cloneNode(node.condition),
-      cloneToken(node.rightSeparator),
-      cloneNodeList(node.updaters),
-      cloneToken(node.rightParenthesis),
-      cloneNode(node.body));
-
-  @override
-  FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) =>
-      new FunctionDeclaration(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.externalKeyword),
-          cloneNode(node.returnType),
-          cloneToken(node.propertyKeyword),
-          cloneNode(node.name),
-          cloneNode(node.functionExpression));
-
-  @override
-  FunctionDeclarationStatement visitFunctionDeclarationStatement(
-          FunctionDeclarationStatement node) =>
-      new FunctionDeclarationStatement(cloneNode(node.functionDeclaration));
-
-  @override
-  FunctionExpression visitFunctionExpression(FunctionExpression node) =>
-      new FunctionExpression(cloneNode(node.typeParameters),
-          cloneNode(node.parameters), cloneNode(node.body));
-
-  @override
-  FunctionExpressionInvocation visitFunctionExpressionInvocation(
-          FunctionExpressionInvocation node) =>
-      new FunctionExpressionInvocation(cloneNode(node.function),
-          cloneNode(node.typeArguments), cloneNode(node.argumentList));
-
-  @override
-  FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) =>
-      new FunctionTypeAlias(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.typedefKeyword),
-          cloneNode(node.returnType),
-          cloneNode(node.name),
-          cloneNode(node.typeParameters),
-          cloneNode(node.parameters),
-          cloneToken(node.semicolon));
-
-  @override
-  FunctionTypedFormalParameter visitFunctionTypedFormalParameter(
-          FunctionTypedFormalParameter node) =>
-      new FunctionTypedFormalParameter(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneNode(node.returnType),
-          cloneNode(node.identifier),
-          cloneNode(node.typeParameters),
-          cloneNode(node.parameters));
-
-  @override
-  HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
-      cloneToken(node.keyword), cloneNodeList(node.hiddenNames));
-
-  @override
-  IfStatement visitIfStatement(IfStatement node) => new IfStatement(
-      cloneToken(node.ifKeyword),
-      cloneToken(node.leftParenthesis),
-      cloneNode(node.condition),
-      cloneToken(node.rightParenthesis),
-      cloneNode(node.thenStatement),
-      cloneToken(node.elseKeyword),
-      cloneNode(node.elseStatement));
-
-  @override
-  ImplementsClause visitImplementsClause(ImplementsClause node) =>
-      new ImplementsClause(
-          cloneToken(node.implementsKeyword), cloneNodeList(node.interfaces));
-
-  @override
-  ImportDirective visitImportDirective(ImportDirective node) {
-    ImportDirective directive = new ImportDirective(
-        cloneNode(node.documentationComment),
-        cloneNodeList(node.metadata),
-        cloneToken(node.keyword),
-        cloneNode(node.uri),
-        cloneToken(node.deferredKeyword),
-        cloneToken(node.asKeyword),
-        cloneNode(node.prefix),
-        cloneNodeList(node.combinators),
-        cloneToken(node.semicolon));
-    directive.source = node.source;
-    directive.uriContent = node.uriContent;
-    return directive;
-  }
-
-  @override
-  IndexExpression visitIndexExpression(IndexExpression node) {
-    Token period = node.period;
-    if (period == null) {
-      return new IndexExpression.forTarget(
-          cloneNode(node.target),
-          cloneToken(node.leftBracket),
-          cloneNode(node.index),
-          cloneToken(node.rightBracket));
-    } else {
-      return new IndexExpression.forCascade(
-          cloneToken(period),
-          cloneToken(node.leftBracket),
-          cloneNode(node.index),
-          cloneToken(node.rightBracket));
-    }
-  }
-
-  @override
-  InstanceCreationExpression visitInstanceCreationExpression(
-          InstanceCreationExpression node) =>
-      new InstanceCreationExpression(cloneToken(node.keyword),
-          cloneNode(node.constructorName), cloneNode(node.argumentList));
-
-  @override
-  IntegerLiteral visitIntegerLiteral(IntegerLiteral node) =>
-      new IntegerLiteral(cloneToken(node.literal), node.value);
-
-  @override
-  InterpolationExpression visitInterpolationExpression(
-          InterpolationExpression node) =>
-      new InterpolationExpression(cloneToken(node.leftBracket),
-          cloneNode(node.expression), cloneToken(node.rightBracket));
-
-  @override
-  InterpolationString visitInterpolationString(InterpolationString node) =>
-      new InterpolationString(cloneToken(node.contents), node.value);
-
-  @override
-  IsExpression visitIsExpression(IsExpression node) => new IsExpression(
-      cloneNode(node.expression),
-      cloneToken(node.isOperator),
-      cloneToken(node.notOperator),
-      cloneNode(node.type));
-
-  @override
-  Label visitLabel(Label node) =>
-      new Label(cloneNode(node.label), cloneToken(node.colon));
-
-  @override
-  LabeledStatement visitLabeledStatement(LabeledStatement node) =>
-      new LabeledStatement(
-          cloneNodeList(node.labels), cloneNode(node.statement));
-
-  @override
-  LibraryDirective visitLibraryDirective(LibraryDirective node) =>
-      new LibraryDirective(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.libraryKeyword),
-          cloneNode(node.name),
-          cloneToken(node.semicolon));
-
-  @override
-  LibraryIdentifier visitLibraryIdentifier(LibraryIdentifier node) =>
-      new LibraryIdentifier(cloneNodeList(node.components));
-
-  @override
-  ListLiteral visitListLiteral(ListLiteral node) => new ListLiteral(
-      cloneToken(node.constKeyword),
-      cloneNode(node.typeArguments),
-      cloneToken(node.leftBracket),
-      cloneNodeList(node.elements),
-      cloneToken(node.rightBracket));
-
-  @override
-  MapLiteral visitMapLiteral(MapLiteral node) => new MapLiteral(
-      cloneToken(node.constKeyword),
-      cloneNode(node.typeArguments),
-      cloneToken(node.leftBracket),
-      cloneNodeList(node.entries),
-      cloneToken(node.rightBracket));
-
-  @override
-  MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) =>
-      new MapLiteralEntry(cloneNode(node.key), cloneToken(node.separator),
-          cloneNode(node.value));
-
-  @override
-  MethodDeclaration visitMethodDeclaration(MethodDeclaration node) =>
-      new MethodDeclaration(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.externalKeyword),
-          cloneToken(node.modifierKeyword),
-          cloneNode(node.returnType),
-          cloneToken(node.propertyKeyword),
-          cloneToken(node.operatorKeyword),
-          cloneNode(node.name),
-          cloneNode(node.typeParameters),
-          cloneNode(node.parameters),
-          cloneNode(node.body));
-
-  @override
-  MethodInvocation visitMethodInvocation(MethodInvocation node) =>
-      new MethodInvocation(
-          cloneNode(node.target),
-          cloneToken(node.operator),
-          cloneNode(node.methodName),
-          cloneNode(node.typeArguments),
-          cloneNode(node.argumentList));
-
-  @override
-  NamedExpression visitNamedExpression(NamedExpression node) =>
-      new NamedExpression(cloneNode(node.name), cloneNode(node.expression));
-
-  @override
-  AstNode visitNativeClause(NativeClause node) =>
-      new NativeClause(cloneToken(node.nativeKeyword), cloneNode(node.name));
-
-  @override
-  NativeFunctionBody visitNativeFunctionBody(NativeFunctionBody node) =>
-      new NativeFunctionBody(cloneToken(node.nativeKeyword),
-          cloneNode(node.stringLiteral), cloneToken(node.semicolon));
-
-  @override
-  NullLiteral visitNullLiteral(NullLiteral node) =>
-      new NullLiteral(cloneToken(node.literal));
-
-  @override
-  ParenthesizedExpression visitParenthesizedExpression(
-          ParenthesizedExpression node) =>
-      new ParenthesizedExpression(cloneToken(node.leftParenthesis),
-          cloneNode(node.expression), cloneToken(node.rightParenthesis));
-
-  @override
-  PartDirective visitPartDirective(PartDirective node) {
-    PartDirective directive = new PartDirective(
-        cloneNode(node.documentationComment),
-        cloneNodeList(node.metadata),
-        cloneToken(node.partKeyword),
-        cloneNode(node.uri),
-        cloneToken(node.semicolon));
-    directive.source = node.source;
-    directive.uriContent = node.uriContent;
-    return directive;
-  }
-
-  @override
-  PartOfDirective visitPartOfDirective(PartOfDirective node) =>
-      new PartOfDirective(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.partKeyword),
-          cloneToken(node.ofKeyword),
-          cloneNode(node.libraryName),
-          cloneToken(node.semicolon));
-
-  @override
-  PostfixExpression visitPostfixExpression(PostfixExpression node) =>
-      new PostfixExpression(cloneNode(node.operand), cloneToken(node.operator));
-
-  @override
-  PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) =>
-      new PrefixedIdentifier(cloneNode(node.prefix), cloneToken(node.period),
-          cloneNode(node.identifier));
-
-  @override
-  PrefixExpression visitPrefixExpression(PrefixExpression node) =>
-      new PrefixExpression(cloneToken(node.operator), cloneNode(node.operand));
-
-  @override
-  PropertyAccess visitPropertyAccess(PropertyAccess node) => new PropertyAccess(
-      cloneNode(node.target),
-      cloneToken(node.operator),
-      cloneNode(node.propertyName));
-
-  @override
-  RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
-          RedirectingConstructorInvocation node) =>
-      new RedirectingConstructorInvocation(
-          cloneToken(node.thisKeyword),
-          cloneToken(node.period),
-          cloneNode(node.constructorName),
-          cloneNode(node.argumentList));
-
-  @override
-  RethrowExpression visitRethrowExpression(RethrowExpression node) =>
-      new RethrowExpression(cloneToken(node.rethrowKeyword));
-
-  @override
-  ReturnStatement visitReturnStatement(ReturnStatement node) =>
-      new ReturnStatement(cloneToken(node.returnKeyword),
-          cloneNode(node.expression), cloneToken(node.semicolon));
-
-  @override
-  ScriptTag visitScriptTag(ScriptTag node) =>
-      new ScriptTag(cloneToken(node.scriptTag));
-
-  @override
-  ShowCombinator visitShowCombinator(ShowCombinator node) => new ShowCombinator(
-      cloneToken(node.keyword), cloneNodeList(node.shownNames));
-
-  @override
-  SimpleFormalParameter visitSimpleFormalParameter(
-          SimpleFormalParameter node) =>
-      new SimpleFormalParameter(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.keyword),
-          cloneNode(node.type),
-          cloneNode(node.identifier));
-
-  @override
-  SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) =>
-      new SimpleIdentifier(cloneToken(node.token));
-
-  @override
-  SimpleStringLiteral visitSimpleStringLiteral(SimpleStringLiteral node) =>
-      new SimpleStringLiteral(cloneToken(node.literal), node.value);
-
-  @override
-  StringInterpolation visitStringInterpolation(StringInterpolation node) =>
-      new StringInterpolation(cloneNodeList(node.elements));
-
-  @override
-  SuperConstructorInvocation visitSuperConstructorInvocation(
-          SuperConstructorInvocation node) =>
-      new SuperConstructorInvocation(
-          cloneToken(node.superKeyword),
-          cloneToken(node.period),
-          cloneNode(node.constructorName),
-          cloneNode(node.argumentList));
-
-  @override
-  SuperExpression visitSuperExpression(SuperExpression node) =>
-      new SuperExpression(cloneToken(node.superKeyword));
-
-  @override
-  SwitchCase visitSwitchCase(SwitchCase node) => new SwitchCase(
-      cloneNodeList(node.labels),
-      cloneToken(node.keyword),
-      cloneNode(node.expression),
-      cloneToken(node.colon),
-      cloneNodeList(node.statements));
-
-  @override
-  SwitchDefault visitSwitchDefault(SwitchDefault node) => new SwitchDefault(
-      cloneNodeList(node.labels),
-      cloneToken(node.keyword),
-      cloneToken(node.colon),
-      cloneNodeList(node.statements));
-
-  @override
-  SwitchStatement visitSwitchStatement(SwitchStatement node) =>
-      new SwitchStatement(
-          cloneToken(node.switchKeyword),
-          cloneToken(node.leftParenthesis),
-          cloneNode(node.expression),
-          cloneToken(node.rightParenthesis),
-          cloneToken(node.leftBracket),
-          cloneNodeList(node.members),
-          cloneToken(node.rightBracket));
-
-  @override
-  SymbolLiteral visitSymbolLiteral(SymbolLiteral node) => new SymbolLiteral(
-      cloneToken(node.poundSign), cloneTokenList(node.components));
-
-  @override
-  ThisExpression visitThisExpression(ThisExpression node) =>
-      new ThisExpression(cloneToken(node.thisKeyword));
-
-  @override
-  ThrowExpression visitThrowExpression(ThrowExpression node) =>
-      new ThrowExpression(
-          cloneToken(node.throwKeyword), cloneNode(node.expression));
-
-  @override
-  TopLevelVariableDeclaration visitTopLevelVariableDeclaration(
-          TopLevelVariableDeclaration node) =>
-      new TopLevelVariableDeclaration(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneNode(node.variables),
-          cloneToken(node.semicolon));
-
-  @override
-  TryStatement visitTryStatement(TryStatement node) => new TryStatement(
-      cloneToken(node.tryKeyword),
-      cloneNode(node.body),
-      cloneNodeList(node.catchClauses),
-      cloneToken(node.finallyKeyword),
-      cloneNode(node.finallyBlock));
-
-  @override
-  TypeArgumentList visitTypeArgumentList(TypeArgumentList node) =>
-      new TypeArgumentList(cloneToken(node.leftBracket),
-          cloneNodeList(node.arguments), cloneToken(node.rightBracket));
-
-  @override
-  TypeName visitTypeName(TypeName node) =>
-      new TypeName(cloneNode(node.name), cloneNode(node.typeArguments));
-
-  @override
-  TypeParameter visitTypeParameter(TypeParameter node) => new TypeParameter(
-      cloneNode(node.documentationComment),
-      cloneNodeList(node.metadata),
-      cloneNode(node.name),
-      cloneToken(node.extendsKeyword),
-      cloneNode(node.bound));
-
-  @override
-  TypeParameterList visitTypeParameterList(TypeParameterList node) =>
-      new TypeParameterList(cloneToken(node.leftBracket),
-          cloneNodeList(node.typeParameters), cloneToken(node.rightBracket));
-
-  @override
-  VariableDeclaration visitVariableDeclaration(VariableDeclaration node) =>
-      new VariableDeclaration(cloneNode(node.name), cloneToken(node.equals),
-          cloneNode(node.initializer));
-
-  @override
-  VariableDeclarationList visitVariableDeclarationList(
-          VariableDeclarationList node) =>
-      new VariableDeclarationList(
-          cloneNode(node.documentationComment),
-          cloneNodeList(node.metadata),
-          cloneToken(node.keyword),
-          cloneNode(node.type),
-          cloneNodeList(node.variables));
-
-  @override
-  VariableDeclarationStatement visitVariableDeclarationStatement(
-          VariableDeclarationStatement node) =>
-      new VariableDeclarationStatement(
-          cloneNode(node.variables), cloneToken(node.semicolon));
-
-  @override
-  WhileStatement visitWhileStatement(WhileStatement node) => new WhileStatement(
-      cloneToken(node.whileKeyword),
-      cloneToken(node.leftParenthesis),
-      cloneNode(node.condition),
-      cloneToken(node.rightParenthesis),
-      cloneNode(node.body));
-
-  @override
-  WithClause visitWithClause(WithClause node) => new WithClause(
-      cloneToken(node.withKeyword), cloneNodeList(node.mixinTypes));
-
-  @override
-  YieldStatement visitYieldStatement(YieldStatement node) => new YieldStatement(
-      cloneToken(node.yieldKeyword),
-      cloneToken(node.star),
-      cloneNode(node.expression),
-      cloneToken(node.semicolon));
-
-  /**
-   * Return a clone of the given [node].
-   */
-  static AstNode clone(AstNode node) {
-    return node.accept(new AstCloner());
-  }
-}
-
-/**
- * An AstVisitor that compares the structure of two AstNodes to see whether they
- * are equal.
- */
-class AstComparator implements AstVisitor<bool> {
-  /**
-   * The AST node with which the node being visited is to be compared. This is
-   * only valid at the beginning of each visit method (until [isEqualNodes] is
-   * invoked).
-   */
-  AstNode _other;
-
-  /**
-   * Return `true` if the [first] node and the [second] node have the same
-   * structure.
-   *
-   * *Note:* This method is only visible for testing purposes and should not be
-   * used by clients.
-   */
-  bool isEqualNodes(AstNode first, AstNode second) {
-    if (first == null) {
-      return second == null;
-    } else if (second == null) {
-      return false;
-    } else if (first.runtimeType != second.runtimeType) {
-      return false;
-    }
-    _other = second;
-    return first.accept(this);
-  }
-
-  /**
-   * Return `true` if the [first] token and the [second] token have the same
-   * structure.
-   *
-   * *Note:* This method is only visible for testing purposes and should not be
-   * used by clients.
-   */
-  bool isEqualTokens(Token first, Token second) {
-    if (first == null) {
-      return second == null;
-    } else if (second == null) {
-      return false;
-    } else if (identical(first, second)) {
-      return true;
-    }
-    return first.offset == second.offset &&
-        first.length == second.length &&
-        first.lexeme == second.lexeme;
-  }
-
-  @override
-  bool visitAdjacentStrings(AdjacentStrings node) {
-    AdjacentStrings other = _other as AdjacentStrings;
-    return _isEqualNodeLists(node.strings, other.strings);
-  }
-
-  @override
-  bool visitAnnotation(Annotation node) {
-    Annotation other = _other as Annotation;
-    return isEqualTokens(node.atSign, other.atSign) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualTokens(node.period, other.period) &&
-        isEqualNodes(node.constructorName, other.constructorName) &&
-        isEqualNodes(node.arguments, other.arguments);
-  }
-
-  @override
-  bool visitArgumentList(ArgumentList node) {
-    ArgumentList other = _other as ArgumentList;
-    return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        _isEqualNodeLists(node.arguments, other.arguments) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis);
-  }
-
-  @override
-  bool visitAsExpression(AsExpression node) {
-    AsExpression other = _other as AsExpression;
-    return isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.asOperator, other.asOperator) &&
-        isEqualNodes(node.type, other.type);
-  }
-
-  @override
-  bool visitAssertStatement(AssertStatement node) {
-    AssertStatement other = _other as AssertStatement;
-    return isEqualTokens(node.assertKeyword, other.assertKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.condition, other.condition) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitAssignmentExpression(AssignmentExpression node) {
-    AssignmentExpression other = _other as AssignmentExpression;
-    return isEqualNodes(node.leftHandSide, other.leftHandSide) &&
-        isEqualTokens(node.operator, other.operator) &&
-        isEqualNodes(node.rightHandSide, other.rightHandSide);
-  }
-
-  @override
-  bool visitAwaitExpression(AwaitExpression node) {
-    AwaitExpression other = _other as AwaitExpression;
-    return isEqualTokens(node.awaitKeyword, other.awaitKeyword) &&
-        isEqualNodes(node.expression, other.expression);
-  }
-
-  @override
-  bool visitBinaryExpression(BinaryExpression node) {
-    BinaryExpression other = _other as BinaryExpression;
-    return isEqualNodes(node.leftOperand, other.leftOperand) &&
-        isEqualTokens(node.operator, other.operator) &&
-        isEqualNodes(node.rightOperand, other.rightOperand);
-  }
-
-  @override
-  bool visitBlock(Block node) {
-    Block other = _other as Block;
-    return isEqualTokens(node.leftBracket, other.leftBracket) &&
-        _isEqualNodeLists(node.statements, other.statements) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitBlockFunctionBody(BlockFunctionBody node) {
-    BlockFunctionBody other = _other as BlockFunctionBody;
-    return isEqualNodes(node.block, other.block);
-  }
-
-  @override
-  bool visitBooleanLiteral(BooleanLiteral node) {
-    BooleanLiteral other = _other as BooleanLiteral;
-    return isEqualTokens(node.literal, other.literal) &&
-        node.value == other.value;
-  }
-
-  @override
-  bool visitBreakStatement(BreakStatement node) {
-    BreakStatement other = _other as BreakStatement;
-    return isEqualTokens(node.breakKeyword, other.breakKeyword) &&
-        isEqualNodes(node.label, other.label) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitCascadeExpression(CascadeExpression node) {
-    CascadeExpression other = _other as CascadeExpression;
-    return isEqualNodes(node.target, other.target) &&
-        _isEqualNodeLists(node.cascadeSections, other.cascadeSections);
-  }
-
-  @override
-  bool visitCatchClause(CatchClause node) {
-    CatchClause other = _other as CatchClause;
-    return isEqualTokens(node.onKeyword, other.onKeyword) &&
-        isEqualNodes(node.exceptionType, other.exceptionType) &&
-        isEqualTokens(node.catchKeyword, other.catchKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.exceptionParameter, other.exceptionParameter) &&
-        isEqualTokens(node.comma, other.comma) &&
-        isEqualNodes(node.stackTraceParameter, other.stackTraceParameter) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualNodes(node.body, other.body);
-  }
-
-  @override
-  bool visitClassDeclaration(ClassDeclaration node) {
-    ClassDeclaration other = _other as ClassDeclaration;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.abstractKeyword, other.abstractKeyword) &&
-        isEqualTokens(node.classKeyword, other.classKeyword) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualNodes(node.typeParameters, other.typeParameters) &&
-        isEqualNodes(node.extendsClause, other.extendsClause) &&
-        isEqualNodes(node.withClause, other.withClause) &&
-        isEqualNodes(node.implementsClause, other.implementsClause) &&
-        isEqualTokens(node.leftBracket, other.leftBracket) &&
-        _isEqualNodeLists(node.members, other.members) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitClassTypeAlias(ClassTypeAlias node) {
-    ClassTypeAlias other = _other as ClassTypeAlias;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.typedefKeyword, other.typedefKeyword) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualNodes(node.typeParameters, other.typeParameters) &&
-        isEqualTokens(node.equals, other.equals) &&
-        isEqualTokens(node.abstractKeyword, other.abstractKeyword) &&
-        isEqualNodes(node.superclass, other.superclass) &&
-        isEqualNodes(node.withClause, other.withClause) &&
-        isEqualNodes(node.implementsClause, other.implementsClause) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitComment(Comment node) {
-    Comment other = _other as Comment;
-    return _isEqualNodeLists(node.references, other.references);
-  }
-
-  @override
-  bool visitCommentReference(CommentReference node) {
-    CommentReference other = _other as CommentReference;
-    return isEqualTokens(node.newKeyword, other.newKeyword) &&
-        isEqualNodes(node.identifier, other.identifier);
-  }
-
-  @override
-  bool visitCompilationUnit(CompilationUnit node) {
-    CompilationUnit other = _other as CompilationUnit;
-    return isEqualTokens(node.beginToken, other.beginToken) &&
-        isEqualNodes(node.scriptTag, other.scriptTag) &&
-        _isEqualNodeLists(node.directives, other.directives) &&
-        _isEqualNodeLists(node.declarations, other.declarations) &&
-        isEqualTokens(node.endToken, other.endToken);
-  }
-
-  @override
-  bool visitConditionalExpression(ConditionalExpression node) {
-    ConditionalExpression other = _other as ConditionalExpression;
-    return isEqualNodes(node.condition, other.condition) &&
-        isEqualTokens(node.question, other.question) &&
-        isEqualNodes(node.thenExpression, other.thenExpression) &&
-        isEqualTokens(node.colon, other.colon) &&
-        isEqualNodes(node.elseExpression, other.elseExpression);
-  }
-
-  @override
-  bool visitConstructorDeclaration(ConstructorDeclaration node) {
-    ConstructorDeclaration other = _other as ConstructorDeclaration;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.externalKeyword, other.externalKeyword) &&
-        isEqualTokens(node.constKeyword, other.constKeyword) &&
-        isEqualTokens(node.factoryKeyword, other.factoryKeyword) &&
-        isEqualNodes(node.returnType, other.returnType) &&
-        isEqualTokens(node.period, other.period) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualNodes(node.parameters, other.parameters) &&
-        isEqualTokens(node.separator, other.separator) &&
-        _isEqualNodeLists(node.initializers, other.initializers) &&
-        isEqualNodes(node.redirectedConstructor, other.redirectedConstructor) &&
-        isEqualNodes(node.body, other.body);
-  }
-
-  @override
-  bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    ConstructorFieldInitializer other = _other as ConstructorFieldInitializer;
-    return isEqualTokens(node.thisKeyword, other.thisKeyword) &&
-        isEqualTokens(node.period, other.period) &&
-        isEqualNodes(node.fieldName, other.fieldName) &&
-        isEqualTokens(node.equals, other.equals) &&
-        isEqualNodes(node.expression, other.expression);
-  }
-
-  @override
-  bool visitConstructorName(ConstructorName node) {
-    ConstructorName other = _other as ConstructorName;
-    return isEqualNodes(node.type, other.type) &&
-        isEqualTokens(node.period, other.period) &&
-        isEqualNodes(node.name, other.name);
-  }
-
-  @override
-  bool visitContinueStatement(ContinueStatement node) {
-    ContinueStatement other = _other as ContinueStatement;
-    return isEqualTokens(node.continueKeyword, other.continueKeyword) &&
-        isEqualNodes(node.label, other.label) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitDeclaredIdentifier(DeclaredIdentifier node) {
-    DeclaredIdentifier other = _other as DeclaredIdentifier;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.keyword, other.keyword) &&
-        isEqualNodes(node.type, other.type) &&
-        isEqualNodes(node.identifier, other.identifier);
-  }
-
-  @override
-  bool visitDefaultFormalParameter(DefaultFormalParameter node) {
-    DefaultFormalParameter other = _other as DefaultFormalParameter;
-    return isEqualNodes(node.parameter, other.parameter) &&
-        node.kind == other.kind &&
-        isEqualTokens(node.separator, other.separator) &&
-        isEqualNodes(node.defaultValue, other.defaultValue);
-  }
-
-  @override
-  bool visitDoStatement(DoStatement node) {
-    DoStatement other = _other as DoStatement;
-    return isEqualTokens(node.doKeyword, other.doKeyword) &&
-        isEqualNodes(node.body, other.body) &&
-        isEqualTokens(node.whileKeyword, other.whileKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.condition, other.condition) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitDoubleLiteral(DoubleLiteral node) {
-    DoubleLiteral other = _other as DoubleLiteral;
-    return isEqualTokens(node.literal, other.literal) &&
-        node.value == other.value;
-  }
-
-  @override
-  bool visitEmptyFunctionBody(EmptyFunctionBody node) {
-    EmptyFunctionBody other = _other as EmptyFunctionBody;
-    return isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitEmptyStatement(EmptyStatement node) {
-    EmptyStatement other = _other as EmptyStatement;
-    return isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    EnumConstantDeclaration other = _other as EnumConstantDeclaration;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualNodes(node.name, other.name);
-  }
-
-  @override
-  bool visitEnumDeclaration(EnumDeclaration node) {
-    EnumDeclaration other = _other as EnumDeclaration;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.enumKeyword, other.enumKeyword) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualTokens(node.leftBracket, other.leftBracket) &&
-        _isEqualNodeLists(node.constants, other.constants) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitExportDirective(ExportDirective node) {
-    ExportDirective other = _other as ExportDirective;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.keyword, other.keyword) &&
-        isEqualNodes(node.uri, other.uri) &&
-        _isEqualNodeLists(node.combinators, other.combinators) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    ExpressionFunctionBody other = _other as ExpressionFunctionBody;
-    return isEqualTokens(node.functionDefinition, other.functionDefinition) &&
-        isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitExpressionStatement(ExpressionStatement node) {
-    ExpressionStatement other = _other as ExpressionStatement;
-    return isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitExtendsClause(ExtendsClause node) {
-    ExtendsClause other = _other as ExtendsClause;
-    return isEqualTokens(node.extendsKeyword, other.extendsKeyword) &&
-        isEqualNodes(node.superclass, other.superclass);
-  }
-
-  @override
-  bool visitFieldDeclaration(FieldDeclaration node) {
-    FieldDeclaration other = _other as FieldDeclaration;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.staticKeyword, other.staticKeyword) &&
-        isEqualNodes(node.fields, other.fields) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitFieldFormalParameter(FieldFormalParameter node) {
-    FieldFormalParameter other = _other as FieldFormalParameter;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.keyword, other.keyword) &&
-        isEqualNodes(node.type, other.type) &&
-        isEqualTokens(node.thisKeyword, other.thisKeyword) &&
-        isEqualTokens(node.period, other.period) &&
-        isEqualNodes(node.identifier, other.identifier);
-  }
-
-  @override
-  bool visitForEachStatement(ForEachStatement node) {
-    ForEachStatement other = _other as ForEachStatement;
-    return isEqualTokens(node.forKeyword, other.forKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.loopVariable, other.loopVariable) &&
-        isEqualTokens(node.inKeyword, other.inKeyword) &&
-        isEqualNodes(node.iterable, other.iterable) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualNodes(node.body, other.body);
-  }
-
-  @override
-  bool visitFormalParameterList(FormalParameterList node) {
-    FormalParameterList other = _other as FormalParameterList;
-    return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        _isEqualNodeLists(node.parameters, other.parameters) &&
-        isEqualTokens(node.leftDelimiter, other.leftDelimiter) &&
-        isEqualTokens(node.rightDelimiter, other.rightDelimiter) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis);
-  }
-
-  @override
-  bool visitForStatement(ForStatement node) {
-    ForStatement other = _other as ForStatement;
-    return isEqualTokens(node.forKeyword, other.forKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.variables, other.variables) &&
-        isEqualNodes(node.initialization, other.initialization) &&
-        isEqualTokens(node.leftSeparator, other.leftSeparator) &&
-        isEqualNodes(node.condition, other.condition) &&
-        isEqualTokens(node.rightSeparator, other.rightSeparator) &&
-        _isEqualNodeLists(node.updaters, other.updaters) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualNodes(node.body, other.body);
-  }
-
-  @override
-  bool visitFunctionDeclaration(FunctionDeclaration node) {
-    FunctionDeclaration other = _other as FunctionDeclaration;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.externalKeyword, other.externalKeyword) &&
-        isEqualNodes(node.returnType, other.returnType) &&
-        isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualNodes(node.functionExpression, other.functionExpression);
-  }
-
-  @override
-  bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
-    FunctionDeclarationStatement other = _other as FunctionDeclarationStatement;
-    return isEqualNodes(node.functionDeclaration, other.functionDeclaration);
-  }
-
-  @override
-  bool visitFunctionExpression(FunctionExpression node) {
-    FunctionExpression other = _other as FunctionExpression;
-    return isEqualNodes(node.parameters, other.parameters) &&
-        isEqualNodes(node.body, other.body);
-  }
-
-  @override
-  bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    FunctionExpressionInvocation other = _other as FunctionExpressionInvocation;
-    return isEqualNodes(node.function, other.function) &&
-        isEqualNodes(node.argumentList, other.argumentList);
-  }
-
-  @override
-  bool visitFunctionTypeAlias(FunctionTypeAlias node) {
-    FunctionTypeAlias other = _other as FunctionTypeAlias;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.typedefKeyword, other.typedefKeyword) &&
-        isEqualNodes(node.returnType, other.returnType) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualNodes(node.typeParameters, other.typeParameters) &&
-        isEqualNodes(node.parameters, other.parameters) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    FunctionTypedFormalParameter other = _other as FunctionTypedFormalParameter;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualNodes(node.returnType, other.returnType) &&
-        isEqualNodes(node.identifier, other.identifier) &&
-        isEqualNodes(node.parameters, other.parameters);
-  }
-
-  @override
-  bool visitHideCombinator(HideCombinator node) {
-    HideCombinator other = _other as HideCombinator;
-    return isEqualTokens(node.keyword, other.keyword) &&
-        _isEqualNodeLists(node.hiddenNames, other.hiddenNames);
-  }
-
-  @override
-  bool visitIfStatement(IfStatement node) {
-    IfStatement other = _other as IfStatement;
-    return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.condition, other.condition) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualNodes(node.thenStatement, other.thenStatement) &&
-        isEqualTokens(node.elseKeyword, other.elseKeyword) &&
-        isEqualNodes(node.elseStatement, other.elseStatement);
-  }
-
-  @override
-  bool visitImplementsClause(ImplementsClause node) {
-    ImplementsClause other = _other as ImplementsClause;
-    return isEqualTokens(node.implementsKeyword, other.implementsKeyword) &&
-        _isEqualNodeLists(node.interfaces, other.interfaces);
-  }
-
-  @override
-  bool visitImportDirective(ImportDirective node) {
-    ImportDirective other = _other as ImportDirective;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.keyword, other.keyword) &&
-        isEqualNodes(node.uri, other.uri) &&
-        isEqualTokens(node.deferredKeyword, other.deferredKeyword) &&
-        isEqualTokens(node.asKeyword, other.asKeyword) &&
-        isEqualNodes(node.prefix, other.prefix) &&
-        _isEqualNodeLists(node.combinators, other.combinators) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitIndexExpression(IndexExpression node) {
-    IndexExpression other = _other as IndexExpression;
-    return isEqualNodes(node.target, other.target) &&
-        isEqualTokens(node.leftBracket, other.leftBracket) &&
-        isEqualNodes(node.index, other.index) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitInstanceCreationExpression(InstanceCreationExpression node) {
-    InstanceCreationExpression other = _other as InstanceCreationExpression;
-    return isEqualTokens(node.keyword, other.keyword) &&
-        isEqualNodes(node.constructorName, other.constructorName) &&
-        isEqualNodes(node.argumentList, other.argumentList);
-  }
-
-  @override
-  bool visitIntegerLiteral(IntegerLiteral node) {
-    IntegerLiteral other = _other as IntegerLiteral;
-    return isEqualTokens(node.literal, other.literal) &&
-        (node.value == other.value);
-  }
-
-  @override
-  bool visitInterpolationExpression(InterpolationExpression node) {
-    InterpolationExpression other = _other as InterpolationExpression;
-    return isEqualTokens(node.leftBracket, other.leftBracket) &&
-        isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitInterpolationString(InterpolationString node) {
-    InterpolationString other = _other as InterpolationString;
-    return isEqualTokens(node.contents, other.contents) &&
-        node.value == other.value;
-  }
-
-  @override
-  bool visitIsExpression(IsExpression node) {
-    IsExpression other = _other as IsExpression;
-    return isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.isOperator, other.isOperator) &&
-        isEqualTokens(node.notOperator, other.notOperator) &&
-        isEqualNodes(node.type, other.type);
-  }
-
-  @override
-  bool visitLabel(Label node) {
-    Label other = _other as Label;
-    return isEqualNodes(node.label, other.label) &&
-        isEqualTokens(node.colon, other.colon);
-  }
-
-  @override
-  bool visitLabeledStatement(LabeledStatement node) {
-    LabeledStatement other = _other as LabeledStatement;
-    return _isEqualNodeLists(node.labels, other.labels) &&
-        isEqualNodes(node.statement, other.statement);
-  }
-
-  @override
-  bool visitLibraryDirective(LibraryDirective node) {
-    LibraryDirective other = _other as LibraryDirective;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.libraryKeyword, other.libraryKeyword) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitLibraryIdentifier(LibraryIdentifier node) {
-    LibraryIdentifier other = _other as LibraryIdentifier;
-    return _isEqualNodeLists(node.components, other.components);
-  }
-
-  @override
-  bool visitListLiteral(ListLiteral node) {
-    ListLiteral other = _other as ListLiteral;
-    return isEqualTokens(node.constKeyword, other.constKeyword) &&
-        isEqualNodes(node.typeArguments, other.typeArguments) &&
-        isEqualTokens(node.leftBracket, other.leftBracket) &&
-        _isEqualNodeLists(node.elements, other.elements) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitMapLiteral(MapLiteral node) {
-    MapLiteral other = _other as MapLiteral;
-    return isEqualTokens(node.constKeyword, other.constKeyword) &&
-        isEqualNodes(node.typeArguments, other.typeArguments) &&
-        isEqualTokens(node.leftBracket, other.leftBracket) &&
-        _isEqualNodeLists(node.entries, other.entries) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitMapLiteralEntry(MapLiteralEntry node) {
-    MapLiteralEntry other = _other as MapLiteralEntry;
-    return isEqualNodes(node.key, other.key) &&
-        isEqualTokens(node.separator, other.separator) &&
-        isEqualNodes(node.value, other.value);
-  }
-
-  @override
-  bool visitMethodDeclaration(MethodDeclaration node) {
-    MethodDeclaration other = _other as MethodDeclaration;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.externalKeyword, other.externalKeyword) &&
-        isEqualTokens(node.modifierKeyword, other.modifierKeyword) &&
-        isEqualNodes(node.returnType, other.returnType) &&
-        isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
-        isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualNodes(node.parameters, other.parameters) &&
-        isEqualNodes(node.body, other.body);
-  }
-
-  @override
-  bool visitMethodInvocation(MethodInvocation node) {
-    MethodInvocation other = _other as MethodInvocation;
-    return isEqualNodes(node.target, other.target) &&
-        isEqualTokens(node.operator, other.operator) &&
-        isEqualNodes(node.methodName, other.methodName) &&
-        isEqualNodes(node.argumentList, other.argumentList);
-  }
-
-  @override
-  bool visitNamedExpression(NamedExpression node) {
-    NamedExpression other = _other as NamedExpression;
-    return isEqualNodes(node.name, other.name) &&
-        isEqualNodes(node.expression, other.expression);
-  }
-
-  @override
-  bool visitNativeClause(NativeClause node) {
-    NativeClause other = _other as NativeClause;
-    return isEqualTokens(node.nativeKeyword, other.nativeKeyword) &&
-        isEqualNodes(node.name, other.name);
-  }
-
-  @override
-  bool visitNativeFunctionBody(NativeFunctionBody node) {
-    NativeFunctionBody other = _other as NativeFunctionBody;
-    return isEqualTokens(node.nativeKeyword, other.nativeKeyword) &&
-        isEqualNodes(node.stringLiteral, other.stringLiteral) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitNullLiteral(NullLiteral node) {
-    NullLiteral other = _other as NullLiteral;
-    return isEqualTokens(node.literal, other.literal);
-  }
-
-  @override
-  bool visitParenthesizedExpression(ParenthesizedExpression node) {
-    ParenthesizedExpression other = _other as ParenthesizedExpression;
-    return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis);
-  }
-
-  @override
-  bool visitPartDirective(PartDirective node) {
-    PartDirective other = _other as PartDirective;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.partKeyword, other.partKeyword) &&
-        isEqualNodes(node.uri, other.uri) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitPartOfDirective(PartOfDirective node) {
-    PartOfDirective other = _other as PartOfDirective;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.partKeyword, other.partKeyword) &&
-        isEqualTokens(node.ofKeyword, other.ofKeyword) &&
-        isEqualNodes(node.libraryName, other.libraryName) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitPostfixExpression(PostfixExpression node) {
-    PostfixExpression other = _other as PostfixExpression;
-    return isEqualNodes(node.operand, other.operand) &&
-        isEqualTokens(node.operator, other.operator);
-  }
-
-  @override
-  bool visitPrefixedIdentifier(PrefixedIdentifier node) {
-    PrefixedIdentifier other = _other as PrefixedIdentifier;
-    return isEqualNodes(node.prefix, other.prefix) &&
-        isEqualTokens(node.period, other.period) &&
-        isEqualNodes(node.identifier, other.identifier);
-  }
-
-  @override
-  bool visitPrefixExpression(PrefixExpression node) {
-    PrefixExpression other = _other as PrefixExpression;
-    return isEqualTokens(node.operator, other.operator) &&
-        isEqualNodes(node.operand, other.operand);
-  }
-
-  @override
-  bool visitPropertyAccess(PropertyAccess node) {
-    PropertyAccess other = _other as PropertyAccess;
-    return isEqualNodes(node.target, other.target) &&
-        isEqualTokens(node.operator, other.operator) &&
-        isEqualNodes(node.propertyName, other.propertyName);
-  }
-
-  @override
-  bool visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    RedirectingConstructorInvocation other =
-        _other as RedirectingConstructorInvocation;
-    return isEqualTokens(node.thisKeyword, other.thisKeyword) &&
-        isEqualTokens(node.period, other.period) &&
-        isEqualNodes(node.constructorName, other.constructorName) &&
-        isEqualNodes(node.argumentList, other.argumentList);
-  }
-
-  @override
-  bool visitRethrowExpression(RethrowExpression node) {
-    RethrowExpression other = _other as RethrowExpression;
-    return isEqualTokens(node.rethrowKeyword, other.rethrowKeyword);
-  }
-
-  @override
-  bool visitReturnStatement(ReturnStatement node) {
-    ReturnStatement other = _other as ReturnStatement;
-    return isEqualTokens(node.returnKeyword, other.returnKeyword) &&
-        isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitScriptTag(ScriptTag node) {
-    ScriptTag other = _other as ScriptTag;
-    return isEqualTokens(node.scriptTag, other.scriptTag);
-  }
-
-  @override
-  bool visitShowCombinator(ShowCombinator node) {
-    ShowCombinator other = _other as ShowCombinator;
-    return isEqualTokens(node.keyword, other.keyword) &&
-        _isEqualNodeLists(node.shownNames, other.shownNames);
-  }
-
-  @override
-  bool visitSimpleFormalParameter(SimpleFormalParameter node) {
-    SimpleFormalParameter other = _other as SimpleFormalParameter;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.keyword, other.keyword) &&
-        isEqualNodes(node.type, other.type) &&
-        isEqualNodes(node.identifier, other.identifier);
-  }
-
-  @override
-  bool visitSimpleIdentifier(SimpleIdentifier node) {
-    SimpleIdentifier other = _other as SimpleIdentifier;
-    return isEqualTokens(node.token, other.token);
-  }
-
-  @override
-  bool visitSimpleStringLiteral(SimpleStringLiteral node) {
-    SimpleStringLiteral other = _other as SimpleStringLiteral;
-    return isEqualTokens(node.literal, other.literal) &&
-        (node.value == other.value);
-  }
-
-  @override
-  bool visitStringInterpolation(StringInterpolation node) {
-    StringInterpolation other = _other as StringInterpolation;
-    return _isEqualNodeLists(node.elements, other.elements);
-  }
-
-  @override
-  bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    SuperConstructorInvocation other = _other as SuperConstructorInvocation;
-    return isEqualTokens(node.superKeyword, other.superKeyword) &&
-        isEqualTokens(node.period, other.period) &&
-        isEqualNodes(node.constructorName, other.constructorName) &&
-        isEqualNodes(node.argumentList, other.argumentList);
-  }
-
-  @override
-  bool visitSuperExpression(SuperExpression node) {
-    SuperExpression other = _other as SuperExpression;
-    return isEqualTokens(node.superKeyword, other.superKeyword);
-  }
-
-  @override
-  bool visitSwitchCase(SwitchCase node) {
-    SwitchCase other = _other as SwitchCase;
-    return _isEqualNodeLists(node.labels, other.labels) &&
-        isEqualTokens(node.keyword, other.keyword) &&
-        isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.colon, other.colon) &&
-        _isEqualNodeLists(node.statements, other.statements);
-  }
-
-  @override
-  bool visitSwitchDefault(SwitchDefault node) {
-    SwitchDefault other = _other as SwitchDefault;
-    return _isEqualNodeLists(node.labels, other.labels) &&
-        isEqualTokens(node.keyword, other.keyword) &&
-        isEqualTokens(node.colon, other.colon) &&
-        _isEqualNodeLists(node.statements, other.statements);
-  }
-
-  @override
-  bool visitSwitchStatement(SwitchStatement node) {
-    SwitchStatement other = _other as SwitchStatement;
-    return isEqualTokens(node.switchKeyword, other.switchKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualTokens(node.leftBracket, other.leftBracket) &&
-        _isEqualNodeLists(node.members, other.members) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitSymbolLiteral(SymbolLiteral node) {
-    SymbolLiteral other = _other as SymbolLiteral;
-    return isEqualTokens(node.poundSign, other.poundSign) &&
-        _isEqualTokenLists(node.components, other.components);
-  }
-
-  @override
-  bool visitThisExpression(ThisExpression node) {
-    ThisExpression other = _other as ThisExpression;
-    return isEqualTokens(node.thisKeyword, other.thisKeyword);
-  }
-
-  @override
-  bool visitThrowExpression(ThrowExpression node) {
-    ThrowExpression other = _other as ThrowExpression;
-    return isEqualTokens(node.throwKeyword, other.throwKeyword) &&
-        isEqualNodes(node.expression, other.expression);
-  }
-
-  @override
-  bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    TopLevelVariableDeclaration other = _other as TopLevelVariableDeclaration;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualNodes(node.variables, other.variables) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitTryStatement(TryStatement node) {
-    TryStatement other = _other as TryStatement;
-    return isEqualTokens(node.tryKeyword, other.tryKeyword) &&
-        isEqualNodes(node.body, other.body) &&
-        _isEqualNodeLists(node.catchClauses, other.catchClauses) &&
-        isEqualTokens(node.finallyKeyword, other.finallyKeyword) &&
-        isEqualNodes(node.finallyBlock, other.finallyBlock);
-  }
-
-  @override
-  bool visitTypeArgumentList(TypeArgumentList node) {
-    TypeArgumentList other = _other as TypeArgumentList;
-    return isEqualTokens(node.leftBracket, other.leftBracket) &&
-        _isEqualNodeLists(node.arguments, other.arguments) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitTypeName(TypeName node) {
-    TypeName other = _other as TypeName;
-    return isEqualNodes(node.name, other.name) &&
-        isEqualNodes(node.typeArguments, other.typeArguments);
-  }
-
-  @override
-  bool visitTypeParameter(TypeParameter node) {
-    TypeParameter other = _other as TypeParameter;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualTokens(node.extendsKeyword, other.extendsKeyword) &&
-        isEqualNodes(node.bound, other.bound);
-  }
-
-  @override
-  bool visitTypeParameterList(TypeParameterList node) {
-    TypeParameterList other = _other as TypeParameterList;
-    return isEqualTokens(node.leftBracket, other.leftBracket) &&
-        _isEqualNodeLists(node.typeParameters, other.typeParameters) &&
-        isEqualTokens(node.rightBracket, other.rightBracket);
-  }
-
-  @override
-  bool visitVariableDeclaration(VariableDeclaration node) {
-    VariableDeclaration other = _other as VariableDeclaration;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualNodes(node.name, other.name) &&
-        isEqualTokens(node.equals, other.equals) &&
-        isEqualNodes(node.initializer, other.initializer);
-  }
-
-  @override
-  bool visitVariableDeclarationList(VariableDeclarationList node) {
-    VariableDeclarationList other = _other as VariableDeclarationList;
-    return isEqualNodes(
-            node.documentationComment, other.documentationComment) &&
-        _isEqualNodeLists(node.metadata, other.metadata) &&
-        isEqualTokens(node.keyword, other.keyword) &&
-        isEqualNodes(node.type, other.type) &&
-        _isEqualNodeLists(node.variables, other.variables);
-  }
-
-  @override
-  bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    VariableDeclarationStatement other = _other as VariableDeclarationStatement;
-    return isEqualNodes(node.variables, other.variables) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  @override
-  bool visitWhileStatement(WhileStatement node) {
-    WhileStatement other = _other as WhileStatement;
-    return isEqualTokens(node.whileKeyword, other.whileKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.condition, other.condition) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualNodes(node.body, other.body);
-  }
-
-  @override
-  bool visitWithClause(WithClause node) {
-    WithClause other = _other as WithClause;
-    return isEqualTokens(node.withKeyword, other.withKeyword) &&
-        _isEqualNodeLists(node.mixinTypes, other.mixinTypes);
-  }
-
-  @override
-  bool visitYieldStatement(YieldStatement node) {
-    YieldStatement other = _other as YieldStatement;
-    return isEqualTokens(node.yieldKeyword, other.yieldKeyword) &&
-        isEqualNodes(node.expression, other.expression) &&
-        isEqualTokens(node.semicolon, other.semicolon);
-  }
-
-  /**
-   * Return `true` if the [first] and [second] lists of AST nodes have the same
-   * size and corresponding elements are equal.
-   */
-  bool _isEqualNodeLists(NodeList first, NodeList second) {
-    if (first == null) {
-      return second == null;
-    } else if (second == null) {
-      return false;
-    }
-    int size = first.length;
-    if (second.length != size) {
-      return false;
-    }
-    for (int i = 0; i < size; i++) {
-      if (!isEqualNodes(first[i], second[i])) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Return `true` if the [first] and [second] lists of tokens have the same
-   * length and corresponding elements are equal.
-   */
-  bool _isEqualTokenLists(List<Token> first, List<Token> second) {
-    int length = first.length;
-    if (second.length != length) {
-      return false;
-    }
-    for (int i = 0; i < length; i++) {
-      if (!isEqualTokens(first[i], second[i])) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Return `true` if the [first] and [second] nodes are equal.
-   */
-  static bool equalNodes(AstNode first, AstNode second) {
-    AstComparator comparator = new AstComparator();
-    return comparator.isEqualNodes(first, second);
-  }
-}
-
-/**
  * A node in the AST structure for a Dart program.
  */
 abstract class AstNode {
   /**
    * An empty list of AST nodes.
    */
-  @deprecated // Use "AstNode.EMPTY_LIST"
-  static const List<AstNode> EMPTY_ARRAY = EMPTY_LIST;
-
-  /**
-   * An empty list of AST nodes.
-   */
   static const List<AstNode> EMPTY_LIST = const <AstNode>[];
 
   /**
@@ -2883,8 +924,8 @@
    * the same offset, and a positive value if the offset of the first node is
    * greater than the offset of the second node.
    */
-  static Comparator<AstNode> LEXICAL_ORDER = (AstNode first, AstNode second) =>
-      first.offset - second.offset;
+  static Comparator<AstNode> LEXICAL_ORDER =
+      (AstNode first, AstNode second) => first.offset - second.offset;
 
   /**
    * The parent of the node, or `null` if the node is the root of an AST
@@ -2966,14 +1007,6 @@
   AstNode get parent => _parent;
 
   /**
-   * Set the parent of this node to the [newParent].
-   */
-  @deprecated // Never intended for public use.
-  void set parent(AstNode newParent) {
-    _parent = newParent;
-  }
-
-  /**
    * Return the node at the root of this node's AST structure. Note that this
    * method's performance is linear with respect to the depth of the node in the
    * AST structure (O(depth)).
@@ -2992,15 +1025,7 @@
    * Use the given [visitor] to visit this node. Return the value returned by
    * the visitor as a result of visiting this node.
    */
-  /* <E> E */ accept(AstVisitor /*<E>*/ visitor);
-
-  /**
-   * Make this node the parent of the given [child] node. Return the child node.
-   */
-  @deprecated // Never intended for public use.
-  AstNode becomeParentOf(AstNode child) {
-    return _becomeParentOf(child);
-  }
+  dynamic /*=E*/ accept /*<E>*/ (AstVisitor /*<E>*/ visitor);
 
   /**
    * Return the most immediate ancestor of this node for which the [predicate]
@@ -3028,16 +1053,6 @@
   }
 
   /**
-   * If the given [child] is not `null`, use the given [visitor] to visit it.
-   */
-  @deprecated // Never intended for public use.
-  void safelyVisitChild(AstNode child, AstVisitor visitor) {
-    if (child != null) {
-      child.accept(visitor);
-    }
-  }
-
-  /**
    * Set the value of the property with the given [name] to the given [value].
    * If the value is `null`, the property will effectively be removed.
    */
@@ -3141,6 +1156,8 @@
 
   R visitConditionalExpression(ConditionalExpression node);
 
+  R visitConfiguration(Configuration node);
+
   R visitConstructorDeclaration(ConstructorDeclaration node);
 
   R visitConstructorFieldInitializer(ConstructorFieldInitializer node);
@@ -3155,6 +1172,8 @@
 
   R visitDoStatement(DoStatement node);
 
+  R visitDottedName(DottedName node);
+
   R visitDoubleLiteral(DoubleLiteral node);
 
   R visitEmptyFunctionBody(EmptyFunctionBody node);
@@ -3466,17 +1485,6 @@
   int get precedence => operator.type.precedence;
 
   /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the right operand
-   * will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForRightOperand {
-    return _propagatedParameterElementForRightOperand;
-  }
-
-  /**
    * Return the expression used to compute the right operand.
    */
   Expression get rightOperand => _rightOperand;
@@ -3491,17 +1499,6 @@
 
   /**
    * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the right operand will be
-   * bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.staticParameterElement"
-  ParameterElement get staticParameterElementForRightOperand {
-    return _staticParameterElementForRightOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
    * known based on propagated type information, then return the parameter
    * element representing the parameter to which the value of the right operand
    * will be bound. Otherwise, return `null`.
@@ -3722,61 +1719,6 @@
 }
 
 /**
- * An AST visitor that will recursively visit all of the nodes in an AST
- * structure, similar to [GeneralizingAstVisitor]. This visitor uses a
- * breadth-first ordering rather than the depth-first ordering of
- * [GeneralizingAstVisitor].
- *
- * Subclasses that override a visit method must either invoke the overridden
- * visit method or explicitly invoke the more general visit method. Failure to
- * do so will cause the visit methods for superclasses of the node to not be
- * invoked and will cause the children of the visited node to not be visited.
- *
- * In addition, subclasses should <b>not</b> explicitly visit the children of a
- * node, but should ensure that the method [visitNode] is used to visit the
- * children (either directly or indirectly). Failure to do will break the order
- * in which nodes are visited.
- */
-class BreadthFirstVisitor<R> extends GeneralizingAstVisitor<R> {
-  /**
-   * A queue holding the nodes that have not yet been visited in the order in
-   * which they ought to be visited.
-   */
-  Queue<AstNode> _queue = new Queue<AstNode>();
-
-  /**
-   * A visitor, used to visit the children of the current node, that will add
-   * the nodes it visits to the [_queue].
-   */
-  GeneralizingAstVisitor<Object> _childVisitor;
-
-  /**
-   * Initialize a newly created visitor.
-   */
-  BreadthFirstVisitor() {
-    _childVisitor = new GeneralizingAstVisitor_BreadthFirstVisitor(this);
-  }
-
-  /**
-   * Visit all nodes in the tree starting at the given [root] node, in
-   * breadth-first order.
-   */
-  void visitAllNodes(AstNode root) {
-    _queue.add(root);
-    while (!_queue.isEmpty) {
-      AstNode next = _queue.removeFirst();
-      next.accept(this);
-    }
-  }
-
-  @override
-  R visitNode(AstNode node) {
-    node.visitChildren(_childVisitor);
-    return null;
-  }
-}
-
-/**
  * A break statement.
  *
  * > breakStatement ::=
@@ -3828,20 +1770,6 @@
   Token get endToken => semicolon;
 
   /**
-   * Return the token representing the 'break' keyword.
-   */
-  @deprecated // Use "this.breakKeyword"
-  Token get keyword => breakKeyword;
-
-  /**
-   * Set the token representing the 'break' keyword to the given [token].
-   */
-  @deprecated // Use "this.breakKeyword"
-  void set keyword(Token token) {
-    breakKeyword = token;
-  }
-
-  /**
    * Return the label associated with the statement, or `null` if there is no
    * label.
    */
@@ -5115,370 +3043,82 @@
   }
 }
 
-/// Instances of the class [ConstantEvaluator] evaluate constant expressions to
-/// produce their compile-time value.
-///
-/// According to the Dart Language Specification:
-///
-/// > A constant expression is one of the following:
-/// >
-/// > * A literal number.
-/// > * A literal boolean.
-/// > * A literal string where any interpolated expression is a compile-time
-/// >   constant that evaluates to a numeric, string or boolean value or to
-/// >   **null**.
-/// > * A literal symbol.
-/// > * **null**.
-/// > * A qualified reference to a static constant variable.
-/// > * An identifier expression that denotes a constant variable, class or type
-/// >   alias.
-/// > * A constant constructor invocation.
-/// > * A constant list literal.
-/// > * A constant map literal.
-/// > * A simple or qualified identifier denoting a top-level function or a
-/// >   static method.
-/// > * A parenthesized expression _(e)_ where _e_ is a constant expression.
-/// > * <span>
-/// >   An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i>
-/// >   where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
-/// >   expressions and <i>identical()</i> is statically bound to the predefined
-/// >   dart function <i>identical()</i> discussed above.
-/// >   </span>
-/// > * <span>
-/// >   An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i>
-/// >   or <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and
-/// >   <i>e<sub>2</sub></i> are constant expressions that evaluate to a
-/// >   numeric, string or boolean value.
-/// >   </span>
-/// > * <span>
-/// >   An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp;
-/// >   e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where
-/// >   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
-/// >   expressions that evaluate to a boolean value.
-/// >   </span>
-/// > * <span>
-/// >   An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^
-/// >   e<sub>2</sub></i>, <i>e<sub>1</sub> &amp; e<sub>2</sub></i>,
-/// >   <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;&gt;
-/// >   e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where
-/// >   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
-/// >   expressions that evaluate to an integer value or to <b>null</b>.
-/// >   </span>
-/// > * <span>
-/// >   An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> +
-/// >   e<sub>2</sub></i>, <i>e<sub>1</sub> -e<sub>2</sub></i>,
-/// >   <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> /
-/// >   e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>,
-/// >   <i>e<sub>1</sub> &gt; e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;
-/// >   e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;= e<sub>2</sub></i>,
-/// >   <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</sub> %
-/// >   e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and
-/// >   <i>e<sub>2</sub></i> are constant expressions that evaluate to a numeric
-/// >   value or to <b>null</b>.
-/// >   </span>
-/// > * <span>
-/// >   An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> :
-/// >   e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and
-/// >   <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i>
-/// >   evaluates to a boolean value.
-/// >   </span>
-///
-/// The values returned by instances of this class are therefore `null` and
-/// instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and
-/// `DartObject`.
-///
-/// In addition, this class defines several values that can be returned to
-/// indicate various conditions encountered during evaluation. These are
-/// documented with the static fields that define those values.
-class ConstantEvaluator extends GeneralizingAstVisitor<Object> {
-  /**
-   * The value returned for expressions (or non-expression nodes) that are not
-   * compile-time constant expressions.
-   */
-  static Object NOT_A_CONSTANT = new Object();
+/**
+ * A configuration in either an import or export directive.
+ *
+ *     configuration ::=
+ *         'if' '(' test ')' uri
+ *
+ *     test ::=
+ *         dottedName ('==' stringLiteral)?
+ *
+ *     dottedName ::=
+ *         identifier ('.' identifier)*
+ */
+class Configuration extends AstNode {
+  Token ifKeyword;
+  Token leftParenthesis;
+  DottedName _name;
+  Token equalToken;
+  StringLiteral _value;
+  Token rightParenthesis;
+  StringLiteral _libraryUri;
 
-  @override
-  Object visitAdjacentStrings(AdjacentStrings node) {
-    StringBuffer buffer = new StringBuffer();
-    for (StringLiteral string in node.strings) {
-      Object value = string.accept(this);
-      if (identical(value, NOT_A_CONSTANT)) {
-        return value;
-      }
-      buffer.write(value);
-    }
-    return buffer.toString();
+  Configuration(
+      this.ifKeyword,
+      this.leftParenthesis,
+      DottedName name,
+      this.equalToken,
+      StringLiteral value,
+      this.rightParenthesis,
+      StringLiteral libraryUri) {
+    _name = _becomeParentOf(name);
+    _value = _becomeParentOf(value);
+    _libraryUri = _becomeParentOf(libraryUri);
   }
 
   @override
-  Object visitBinaryExpression(BinaryExpression node) {
-    Object leftOperand = node.leftOperand.accept(this);
-    if (identical(leftOperand, NOT_A_CONSTANT)) {
-      return leftOperand;
-    }
-    Object rightOperand = node.rightOperand.accept(this);
-    if (identical(rightOperand, NOT_A_CONSTANT)) {
-      return rightOperand;
-    }
-    while (true) {
-      if (node.operator.type == TokenType.AMPERSAND) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand & rightOperand;
-        }
-      } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
-        // boolean or {@code null}
-        if (leftOperand is bool && rightOperand is bool) {
-          return leftOperand && rightOperand;
-        }
-      } else if (node.operator.type == TokenType.BANG_EQ) {
-        // numeric, string, boolean, or {@code null}
-        if (leftOperand is bool && rightOperand is bool) {
-          return leftOperand != rightOperand;
-        } else if (leftOperand is num && rightOperand is num) {
-          return leftOperand != rightOperand;
-        } else if (leftOperand is String && rightOperand is String) {
-          return leftOperand != rightOperand;
-        }
-      } else if (node.operator.type == TokenType.BAR) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand | rightOperand;
-        }
-      } else if (node.operator.type == TokenType.BAR_BAR) {
-        // boolean or {@code null}
-        if (leftOperand is bool && rightOperand is bool) {
-          return leftOperand || rightOperand;
-        }
-      } else if (node.operator.type == TokenType.CARET) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand ^ rightOperand;
-        }
-      } else if (node.operator.type == TokenType.EQ_EQ) {
-        // numeric, string, boolean, or {@code null}
-        if (leftOperand is bool && rightOperand is bool) {
-          return leftOperand == rightOperand;
-        } else if (leftOperand is num && rightOperand is num) {
-          return leftOperand == rightOperand;
-        } else if (leftOperand is String && rightOperand is String) {
-          return leftOperand == rightOperand;
-        }
-      } else if (node.operator.type == TokenType.GT) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.compareTo(rightOperand) > 0;
-        }
-      } else if (node.operator.type == TokenType.GT_EQ) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.compareTo(rightOperand) >= 0;
-        }
-      } else if (node.operator.type == TokenType.GT_GT) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand >> rightOperand;
-        }
-      } else if (node.operator.type == TokenType.LT) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.compareTo(rightOperand) < 0;
-        }
-      } else if (node.operator.type == TokenType.LT_EQ) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.compareTo(rightOperand) <= 0;
-        }
-      } else if (node.operator.type == TokenType.LT_LT) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand << rightOperand;
-        }
-      } else if (node.operator.type == TokenType.MINUS) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand - rightOperand;
-        }
-      } else if (node.operator.type == TokenType.PERCENT) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.remainder(rightOperand);
-        }
-      } else if (node.operator.type == TokenType.PLUS) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand + rightOperand;
-        }
-      } else if (node.operator.type == TokenType.STAR) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand * rightOperand;
-        }
-      } else if (node.operator.type == TokenType.SLASH) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand / rightOperand;
-        }
-      } else if (node.operator.type == TokenType.TILDE_SLASH) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand ~/ rightOperand;
-        }
-      } else {}
-      break;
-    }
-    // TODO(brianwilkerson) This doesn't handle numeric conversions.
-    return visitExpression(node);
+  Token get beginToken => ifKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(ifKeyword)
+    ..add(leftParenthesis)
+    ..add(_name)
+    ..add(equalToken)
+    ..add(_value)
+    ..add(rightParenthesis)
+    ..add(_libraryUri);
+
+  @override
+  Token get endToken => _libraryUri.endToken;
+
+  StringLiteral get libraryUri => _libraryUri;
+
+  void set libraryUri(StringLiteral libraryUri) {
+    _libraryUri = _becomeParentOf(libraryUri);
+  }
+
+  DottedName get name => _name;
+
+  void set name(DottedName name) {
+    _name = _becomeParentOf(name);
+  }
+
+  StringLiteral get value => _value;
+
+  void set value(StringLiteral value) {
+    _value = _becomeParentOf(value);
   }
 
   @override
-  Object visitBooleanLiteral(BooleanLiteral node) => node.value ? true : false;
+  accept(AstVisitor visitor) => visitor.visitConfiguration(this);
 
   @override
-  Object visitDoubleLiteral(DoubleLiteral node) => node.value;
-
-  @override
-  Object visitIntegerLiteral(IntegerLiteral node) => node.value;
-
-  @override
-  Object visitInterpolationExpression(InterpolationExpression node) {
-    Object value = node.expression.accept(this);
-    if (value == null || value is bool || value is String || value is num) {
-      return value;
-    }
-    return NOT_A_CONSTANT;
-  }
-
-  @override
-  Object visitInterpolationString(InterpolationString node) => node.value;
-
-  @override
-  Object visitListLiteral(ListLiteral node) {
-    List<Object> list = new List<Object>();
-    for (Expression element in node.elements) {
-      Object value = element.accept(this);
-      if (identical(value, NOT_A_CONSTANT)) {
-        return value;
-      }
-      list.add(value);
-    }
-    return list;
-  }
-
-  @override
-  Object visitMapLiteral(MapLiteral node) {
-    HashMap<String, Object> map = new HashMap<String, Object>();
-    for (MapLiteralEntry entry in node.entries) {
-      Object key = entry.key.accept(this);
-      Object value = entry.value.accept(this);
-      if (key is! String || identical(value, NOT_A_CONSTANT)) {
-        return NOT_A_CONSTANT;
-      }
-      map[(key as String)] = value;
-    }
-    return map;
-  }
-
-  @override
-  Object visitMethodInvocation(MethodInvocation node) => visitNode(node);
-
-  @override
-  Object visitNode(AstNode node) => NOT_A_CONSTANT;
-
-  @override
-  Object visitNullLiteral(NullLiteral node) => null;
-
-  @override
-  Object visitParenthesizedExpression(ParenthesizedExpression node) =>
-      node.expression.accept(this);
-
-  @override
-  Object visitPrefixedIdentifier(PrefixedIdentifier node) =>
-      _getConstantValue(null);
-
-  @override
-  Object visitPrefixExpression(PrefixExpression node) {
-    Object operand = node.operand.accept(this);
-    if (identical(operand, NOT_A_CONSTANT)) {
-      return operand;
-    }
-    while (true) {
-      if (node.operator.type == TokenType.BANG) {
-        if (identical(operand, true)) {
-          return false;
-        } else if (identical(operand, false)) {
-          return true;
-        }
-      } else if (node.operator.type == TokenType.TILDE) {
-        if (operand is int) {
-          return ~operand;
-        }
-      } else if (node.operator.type == TokenType.MINUS) {
-        if (operand == null) {
-          return null;
-        } else if (operand is num) {
-          return -operand;
-        }
-      } else {}
-      break;
-    }
-    return NOT_A_CONSTANT;
-  }
-
-  @override
-  Object visitPropertyAccess(PropertyAccess node) => _getConstantValue(null);
-
-  @override
-  Object visitSimpleIdentifier(SimpleIdentifier node) =>
-      _getConstantValue(null);
-
-  @override
-  Object visitSimpleStringLiteral(SimpleStringLiteral node) => node.value;
-
-  @override
-  Object visitStringInterpolation(StringInterpolation node) {
-    StringBuffer buffer = new StringBuffer();
-    for (InterpolationElement element in node.elements) {
-      Object value = element.accept(this);
-      if (identical(value, NOT_A_CONSTANT)) {
-        return value;
-      }
-      buffer.write(value);
-    }
-    return buffer.toString();
-  }
-
-  @override
-  Object visitSymbolLiteral(SymbolLiteral node) {
-    // TODO(brianwilkerson) This isn't optimal because a Symbol is not a String.
-    StringBuffer buffer = new StringBuffer();
-    for (Token component in node.components) {
-      if (buffer.length > 0) {
-        buffer.writeCharCode(0x2E);
-      }
-      buffer.write(component.lexeme);
-    }
-    return buffer.toString();
-  }
-
-  /**
-   * Return the constant value of the static constant represented by the given
-   * [element].
-   */
-  Object _getConstantValue(Element element) {
-    // TODO(brianwilkerson) Implement this
-    if (element is FieldElement) {
-      FieldElement field = element;
-      if (field.isStatic && field.isConst) {
-        //field.getConstantValue();
-      }
-      //    } else if (element instanceof VariableElement) {
-      //      VariableElement variable = (VariableElement) element;
-      //      if (variable.isStatic() && variable.isConst()) {
-      //        //variable.getConstantValue();
-      //      }
-    }
-    return NOT_A_CONSTANT;
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_value, visitor);
+    _safelyVisitChild(_libraryUri, visitor);
   }
 }
 
@@ -5824,21 +3464,6 @@
     _fieldName = _becomeParentOf(identifier);
   }
 
-  /**
-   * Return the token for the 'this' keyword, or `null` if there is no 'this'
-   * keyword.
-   */
-  @deprecated // Use "this.thisKeyword"
-  Token get keyword => thisKeyword;
-
-  /**
-   * Set the token for the 'this' keyword to the given [token].
-   */
-  @deprecated // Use "this.thisKeyword"
-  set keyword(Token token) {
-    thisKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitConstructorFieldInitializer(this);
 
@@ -5855,6 +3480,7 @@
  * > constructorInitializer ::=
  * >     [SuperConstructorInvocation]
  * >   | [ConstructorFieldInitializer]
+ * >   | [RedirectingConstructorInvocation]
  */
 abstract class ConstructorInitializer extends AstNode {}
 
@@ -6000,21 +3626,6 @@
   Token get endToken => semicolon;
 
   /**
-   * Return the token for the 'continue' keyword, or `null` if there is no
-   * 'continue' keyword.
-   */
-  @deprecated // Use "this.continueKeyword"
-  Token get keyword => continueKeyword;
-
-  /**
-   * Set the token for the 'continue' keyword to the given [token].
-   */
-  @deprecated // Use "this.continueKeyword"
-  set keyword(Token token) {
-    continueKeyword = token;
-  }
-
-  /**
    * Return the label associated with the statement, or `null` if there is no
    * label.
    */
@@ -6134,7 +3745,8 @@
   /**
    * Return `true` if this variable was declared with the 'const' modifier.
    */
-  bool get isConst => (keyword is KeywordToken) &&
+  bool get isConst =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   /**
@@ -6142,7 +3754,8 @@
    * Variables that are declared with the 'const' modifier will return `false`
    * even though they are implicitly final.
    */
-  bool get isFinal => (keyword is KeywordToken) &&
+  bool get isFinal =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.FINAL;
 
   /**
@@ -6278,37 +3891,6 @@
 }
 
 /**
- * A recursive AST visitor that is used to run over [Expression]s to determine
- * whether the expression is composed by at least one deferred
- * [PrefixedIdentifier].
- *
- * See [PrefixedIdentifier.isDeferred].
- */
-class DeferredLibraryReferenceDetector extends RecursiveAstVisitor<Object> {
-  /**
-   * A flag indicating whether an identifier from a deferred library has been
-   * found.
-   */
-  bool _result = false;
-
-  /**
-   * Return `true` if the visitor found a [PrefixedIdentifier] that returned
-   * `true` to the [PrefixedIdentifier.isDeferred] query.
-   */
-  bool get result => _result;
-
-  @override
-  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
-    if (!_result) {
-      if (node.isDeferred) {
-        _result = true;
-      }
-    }
-    return null;
-  }
-}
-
-/**
  * A node that represents a directive.
  *
  * > directive ::=
@@ -6449,6 +4031,49 @@
 }
 
 /**
+ * A dotted name, used in a configuration within an import or export directive.
+ *
+ * > dottedName ::=
+ * >     [SimpleIdentifier] ('.' [SimpleIdentifier])*
+ */
+class DottedName extends AstNode {
+  /**
+   * The components of the identifier.
+   */
+  NodeList<SimpleIdentifier> _components;
+
+  /**
+   * Initialize a newly created dotted name.
+   */
+  DottedName(List<SimpleIdentifier> components) {
+    _components = new NodeList<SimpleIdentifier>(this, components);
+  }
+
+  @override
+  Token get beginToken => _components.beginToken;
+
+  @override
+  // TODO(paulberry): add "." tokens.
+  Iterable get childEntities => new ChildEntities()..addAll(_components);
+
+  /**
+   * Return the components of the identifier.
+   */
+  NodeList<SimpleIdentifier> get components => _components;
+
+  @override
+  Token get endToken => _components.endToken;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitDottedName(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _components.accept(visitor);
+  }
+}
+
+/**
  * A floating point literal expression.
  *
  * > doubleLiteral ::=
@@ -6493,134 +4118,6 @@
 }
 
 /**
- * An object used to locate the [Element] associated with a given [AstNode].
- */
-class ElementLocator {
-  /**
-   * Return the element associated with the given [node], or `null` if there is
-   * no element associated with the node.
-   */
-  static Element locate(AstNode node) {
-    if (node == null) {
-      return null;
-    }
-    ElementLocator_ElementMapper mapper = new ElementLocator_ElementMapper();
-    return node.accept(mapper);
-  }
-}
-
-/**
- * Visitor that maps nodes to elements.
- */
-class ElementLocator_ElementMapper extends GeneralizingAstVisitor<Element> {
-  @override
-  Element visitAnnotation(Annotation node) => node.element;
-
-  @override
-  Element visitAssignmentExpression(AssignmentExpression node) =>
-      node.bestElement;
-
-  @override
-  Element visitBinaryExpression(BinaryExpression node) => node.bestElement;
-
-  @override
-  Element visitClassDeclaration(ClassDeclaration node) => node.element;
-
-  @override
-  Element visitCompilationUnit(CompilationUnit node) => node.element;
-
-  @override
-  Element visitConstructorDeclaration(ConstructorDeclaration node) =>
-      node.element;
-
-  @override
-  Element visitFunctionDeclaration(FunctionDeclaration node) => node.element;
-
-  @override
-  Element visitIdentifier(Identifier node) {
-    AstNode parent = node.parent;
-    // Type name in Annotation
-    if (parent is Annotation) {
-      Annotation annotation = parent;
-      if (identical(annotation.name, node) &&
-          annotation.constructorName == null) {
-        return annotation.element;
-      }
-    }
-    // Extra work to map Constructor Declarations to their associated
-    // Constructor Elements
-    if (parent is ConstructorDeclaration) {
-      ConstructorDeclaration decl = parent;
-      Identifier returnType = decl.returnType;
-      if (identical(returnType, node)) {
-        SimpleIdentifier name = decl.name;
-        if (name != null) {
-          return name.bestElement;
-        }
-        Element element = node.bestElement;
-        if (element is ClassElement) {
-          return element.unnamedConstructor;
-        }
-      }
-    }
-    if (parent is LibraryIdentifier) {
-      AstNode grandParent = parent.parent;
-      if (grandParent is PartOfDirective) {
-        Element element = grandParent.element;
-        if (element is LibraryElement) {
-          return element.definingCompilationUnit;
-        }
-      }
-    }
-    return node.bestElement;
-  }
-
-  @override
-  Element visitImportDirective(ImportDirective node) => node.element;
-
-  @override
-  Element visitIndexExpression(IndexExpression node) => node.bestElement;
-
-  @override
-  Element visitInstanceCreationExpression(InstanceCreationExpression node) =>
-      node.staticElement;
-
-  @override
-  Element visitLibraryDirective(LibraryDirective node) => node.element;
-
-  @override
-  Element visitMethodDeclaration(MethodDeclaration node) => node.element;
-
-  @override
-  Element visitMethodInvocation(MethodInvocation node) =>
-      node.methodName.bestElement;
-
-  @override
-  Element visitPartOfDirective(PartOfDirective node) => node.element;
-
-  @override
-  Element visitPostfixExpression(PostfixExpression node) => node.bestElement;
-
-  @override
-  Element visitPrefixedIdentifier(PrefixedIdentifier node) => node.bestElement;
-
-  @override
-  Element visitPrefixExpression(PrefixExpression node) => node.bestElement;
-
-  @override
-  Element visitStringLiteral(StringLiteral node) {
-    AstNode parent = node.parent;
-    if (parent is UriBasedDirective) {
-      return parent.uriElement;
-    }
-    return null;
-  }
-
-  @override
-  Element visitVariableDeclaration(VariableDeclaration node) => node.element;
-}
-
-/**
  * An empty function body, which can only appear in constructors or abstract
  * methods.
  *
@@ -6817,21 +4314,6 @@
   @override
   Token get firstTokenAfterCommentAndMetadata => enumKeyword;
 
-  /**
-   * Return the token for the 'enum' keyword, or `null` if there is no
-   * 'enum' keyword.
-   */
-  @deprecated // Use "this.enumKeyword"
-  Token get keyword => enumKeyword;
-
-  /**
-   * Set the token for the 'enum' keyword to the given [token].
-   */
-  @deprecated // Use "this.enumKeyword"
-  set keyword(Token token) {
-    enumKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitEnumDeclaration(this);
 
@@ -6867,9 +4349,16 @@
    * corresponding attribute. The list of [combinators] can be `null` if there
    * are no combinators.
    */
-  ExportDirective(Comment comment, List<Annotation> metadata, Token keyword,
-      StringLiteral libraryUri, List<Combinator> combinators, Token semicolon)
-      : super(comment, metadata, keyword, libraryUri, combinators, semicolon);
+  ExportDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      List<Combinator> combinators,
+      Token semicolon)
+      : super(comment, metadata, keyword, libraryUri, configurations,
+            combinators, semicolon);
 
   @override
   Iterable get childEntities => super._childEntities
@@ -6910,12 +4399,6 @@
   /**
    * An empty list of expressions.
    */
-  @deprecated // Use "Expression.EMPTY_LIST"
-  static const List<Expression> EMPTY_ARRAY = EMPTY_LIST;
-
-  /**
-   * An empty list of expressions.
-   */
   static const List<Expression> EMPTY_LIST = const <Expression>[];
 
   /**
@@ -7238,20 +4721,6 @@
   Token get endToken => _superclass.endToken;
 
   /**
-   * Return the token for the 'extends' keyword.
-   */
-  @deprecated // Use "this.extendsKeyword"
-  Token get keyword => extendsKeyword;
-
-  /**
-   * Set the token for the 'extends' keyword to the given [token].
-   */
-  @deprecated // Use "this.extendsKeyword"
-  set keyword(Token token) {
-    extendsKeyword = token;
-  }
-
-  /**
    * Return the name of the class that is being extended.
    */
   TypeName get superclass => _superclass;
@@ -7447,11 +4916,13 @@
   }
 
   @override
-  bool get isConst => (keyword is KeywordToken) &&
+  bool get isConst =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   @override
-  bool get isFinal => (keyword is KeywordToken) &&
+  bool get isFinal =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.FINAL;
 
   /**
@@ -7469,20 +4940,6 @@
   }
 
   /**
-   * Return the token representing the 'this' keyword.
-   */
-  @deprecated // Use "this.thisKeyword"
-  Token get thisToken => thisKeyword;
-
-  /**
-   * Set the token representing the 'this' keyword to the given [token].
-   */
-  @deprecated // Use "this.thisKeyword"
-  set thisToken(Token token) {
-    thisKeyword = token;
-  }
-
-  /**
    * Return the name of the declared type of the parameter, or `null` if the
    * parameter does not have a declared type. Note that if this is a
    * function-typed field formal parameter this is the return type of the
@@ -7580,44 +5037,6 @@
   Statement _body;
 
   /**
-   * Initialize a newly created for-each statement. The [awaitKeyword] can be
-   * `null` if this is not an asynchronous for loop.
-   */
-  @deprecated // Use new ForEachStatement.withDeclaration(...)
-  ForEachStatement.con1(
-      this.awaitKeyword,
-      this.forKeyword,
-      this.leftParenthesis,
-      DeclaredIdentifier loopVariable,
-      this.inKeyword,
-      Expression iterator,
-      this.rightParenthesis,
-      Statement body) {
-    _loopVariable = _becomeParentOf(loopVariable);
-    _iterable = _becomeParentOf(iterator);
-    _body = _becomeParentOf(body);
-  }
-
-  /**
-   * Initialize a newly created for-each statement. The [awaitKeyword] can be
-   * `null` if this is not an asynchronous for loop.
-   */
-  @deprecated // Use new ForEachStatement.withReference(...)
-  ForEachStatement.con2(
-      this.awaitKeyword,
-      this.forKeyword,
-      this.leftParenthesis,
-      SimpleIdentifier identifier,
-      this.inKeyword,
-      Expression iterator,
-      this.rightParenthesis,
-      Statement body) {
-    _identifier = _becomeParentOf(identifier);
-    _iterable = _becomeParentOf(iterator);
-    _body = _becomeParentOf(body);
-  }
-
-  /**
    * Initialize a newly created for-each statement whose loop control variable
    * is declared internally (in the for-loop part). The [awaitKeyword] can be
    * `null` if this is not an asynchronous for loop.
@@ -7712,12 +5131,6 @@
   }
 
   /**
-   * Return the expression evaluated to produce the iterator.
-   */
-  @deprecated // Use "this.iterable"
-  Expression get iterator => iterable;
-
-  /**
    * Return the declaration of the loop variable, or `null` if the loop variable
    * is a simple identifier.
    */
@@ -8223,13 +5636,15 @@
   /**
    * Return `true` if this function declares a getter.
    */
-  bool get isGetter => propertyKeyword != null &&
+  bool get isGetter =>
+      propertyKeyword != null &&
       (propertyKeyword as KeywordToken).keyword == Keyword.GET;
 
   /**
    * Return `true` if this function declares a setter.
    */
-  bool get isSetter => propertyKeyword != null &&
+  bool get isSetter =>
+      propertyKeyword != null &&
       (propertyKeyword as KeywordToken).keyword == Keyword.SET;
 
   /**
@@ -8432,7 +5847,7 @@
  * [MethodInvocation] nodes. Invocations of getters and setters are represented
  * by either [PrefixedIdentifier] or [PropertyAccess] nodes.
  *
- * > functionExpressionInvoction ::=
+ * > functionExpressionInvocation ::=
  * >     [Expression] [TypeArgumentList]? [ArgumentList]
  */
 class FunctionExpressionInvocation extends Expression {
@@ -8460,6 +5875,16 @@
   ExecutableElement staticElement;
 
   /**
+   * The function type of the method invocation, or `null` if the AST
+   * structure has not been resolved, or if the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType staticInvokeType;
+
+  /**
    * The element associated with the function being invoked based on propagated
    * type information, or `null` if the AST structure has not been resolved or
    * the function could not be resolved.
@@ -8467,6 +5892,11 @@
   ExecutableElement propagatedElement;
 
   /**
+   * Like [staticInvokeType], but reflects propagated type information.
+   */
+  DartType propagatedInvokeType;
+
+  /**
    * Initialize a newly created function expression invocation.
    */
   FunctionExpressionInvocation(Expression function,
@@ -8788,441 +6218,6 @@
 }
 
 /**
- * An AST visitor that will recursively visit all of the nodes in an AST
- * structure (like instances of the class [RecursiveAstVisitor]). In addition,
- * when a node of a specific type is visited not only will the visit method for
- * that specific type of node be invoked, but additional methods for the
- * superclasses of that node will also be invoked. For example, using an
- * instance of this class to visit a [Block] will cause the method [visitBlock]
- * to be invoked but will also cause the methods [visitStatement] and
- * [visitNode] to be subsequently invoked. This allows visitors to be written
- * that visit all statements without needing to override the visit method for
- * each of the specific subclasses of [Statement].
- *
- * Subclasses that override a visit method must either invoke the overridden
- * visit method or explicitly invoke the more general visit method. Failure to
- * do so will cause the visit methods for superclasses of the node to not be
- * invoked and will cause the children of the visited node to not be visited.
- */
-class GeneralizingAstVisitor<R> implements AstVisitor<R> {
-  @override
-  R visitAdjacentStrings(AdjacentStrings node) => visitStringLiteral(node);
-
-  R visitAnnotatedNode(AnnotatedNode node) => visitNode(node);
-
-  @override
-  R visitAnnotation(Annotation node) => visitNode(node);
-
-  @override
-  R visitArgumentList(ArgumentList node) => visitNode(node);
-
-  @override
-  R visitAsExpression(AsExpression node) => visitExpression(node);
-
-  @override
-  R visitAssertStatement(AssertStatement node) => visitStatement(node);
-
-  @override
-  R visitAssignmentExpression(AssignmentExpression node) =>
-      visitExpression(node);
-
-  @override
-  R visitAwaitExpression(AwaitExpression node) => visitExpression(node);
-
-  @override
-  R visitBinaryExpression(BinaryExpression node) => visitExpression(node);
-
-  @override
-  R visitBlock(Block node) => visitStatement(node);
-
-  @override
-  R visitBlockFunctionBody(BlockFunctionBody node) => visitFunctionBody(node);
-
-  @override
-  R visitBooleanLiteral(BooleanLiteral node) => visitLiteral(node);
-
-  @override
-  R visitBreakStatement(BreakStatement node) => visitStatement(node);
-
-  @override
-  R visitCascadeExpression(CascadeExpression node) => visitExpression(node);
-
-  @override
-  R visitCatchClause(CatchClause node) => visitNode(node);
-
-  @override
-  R visitClassDeclaration(ClassDeclaration node) =>
-      visitNamedCompilationUnitMember(node);
-
-  R visitClassMember(ClassMember node) => visitDeclaration(node);
-
-  @override
-  R visitClassTypeAlias(ClassTypeAlias node) => visitTypeAlias(node);
-
-  R visitCombinator(Combinator node) => visitNode(node);
-
-  @override
-  R visitComment(Comment node) => visitNode(node);
-
-  @override
-  R visitCommentReference(CommentReference node) => visitNode(node);
-
-  @override
-  R visitCompilationUnit(CompilationUnit node) => visitNode(node);
-
-  R visitCompilationUnitMember(CompilationUnitMember node) =>
-      visitDeclaration(node);
-
-  @override
-  R visitConditionalExpression(ConditionalExpression node) =>
-      visitExpression(node);
-
-  @override
-  R visitConstructorDeclaration(ConstructorDeclaration node) =>
-      visitClassMember(node);
-
-  @override
-  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) =>
-      visitConstructorInitializer(node);
-
-  R visitConstructorInitializer(ConstructorInitializer node) => visitNode(node);
-
-  @override
-  R visitConstructorName(ConstructorName node) => visitNode(node);
-
-  @override
-  R visitContinueStatement(ContinueStatement node) => visitStatement(node);
-
-  R visitDeclaration(Declaration node) => visitAnnotatedNode(node);
-
-  @override
-  R visitDeclaredIdentifier(DeclaredIdentifier node) => visitDeclaration(node);
-
-  @override
-  R visitDefaultFormalParameter(DefaultFormalParameter node) =>
-      visitFormalParameter(node);
-
-  R visitDirective(Directive node) => visitAnnotatedNode(node);
-
-  @override
-  R visitDoStatement(DoStatement node) => visitStatement(node);
-
-  @override
-  R visitDoubleLiteral(DoubleLiteral node) => visitLiteral(node);
-
-  @override
-  R visitEmptyFunctionBody(EmptyFunctionBody node) => visitFunctionBody(node);
-
-  @override
-  R visitEmptyStatement(EmptyStatement node) => visitStatement(node);
-
-  @override
-  R visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
-      visitDeclaration(node);
-
-  @override
-  R visitEnumDeclaration(EnumDeclaration node) =>
-      visitNamedCompilationUnitMember(node);
-
-  @override
-  R visitExportDirective(ExportDirective node) => visitNamespaceDirective(node);
-
-  R visitExpression(Expression node) => visitNode(node);
-
-  @override
-  R visitExpressionFunctionBody(ExpressionFunctionBody node) =>
-      visitFunctionBody(node);
-
-  @override
-  R visitExpressionStatement(ExpressionStatement node) => visitStatement(node);
-
-  @override
-  R visitExtendsClause(ExtendsClause node) => visitNode(node);
-
-  @override
-  R visitFieldDeclaration(FieldDeclaration node) => visitClassMember(node);
-
-  @override
-  R visitFieldFormalParameter(FieldFormalParameter node) =>
-      visitNormalFormalParameter(node);
-
-  @override
-  R visitForEachStatement(ForEachStatement node) => visitStatement(node);
-
-  R visitFormalParameter(FormalParameter node) => visitNode(node);
-
-  @override
-  R visitFormalParameterList(FormalParameterList node) => visitNode(node);
-
-  @override
-  R visitForStatement(ForStatement node) => visitStatement(node);
-
-  R visitFunctionBody(FunctionBody node) => visitNode(node);
-
-  @override
-  R visitFunctionDeclaration(FunctionDeclaration node) =>
-      visitNamedCompilationUnitMember(node);
-
-  @override
-  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) =>
-      visitStatement(node);
-
-  @override
-  R visitFunctionExpression(FunctionExpression node) => visitExpression(node);
-
-  @override
-  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) =>
-      visitExpression(node);
-
-  @override
-  R visitFunctionTypeAlias(FunctionTypeAlias node) => visitTypeAlias(node);
-
-  @override
-  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) =>
-      visitNormalFormalParameter(node);
-
-  @override
-  R visitHideCombinator(HideCombinator node) => visitCombinator(node);
-
-  R visitIdentifier(Identifier node) => visitExpression(node);
-
-  @override
-  R visitIfStatement(IfStatement node) => visitStatement(node);
-
-  @override
-  R visitImplementsClause(ImplementsClause node) => visitNode(node);
-
-  @override
-  R visitImportDirective(ImportDirective node) => visitNamespaceDirective(node);
-
-  @override
-  R visitIndexExpression(IndexExpression node) => visitExpression(node);
-
-  @override
-  R visitInstanceCreationExpression(InstanceCreationExpression node) =>
-      visitExpression(node);
-
-  @override
-  R visitIntegerLiteral(IntegerLiteral node) => visitLiteral(node);
-
-  R visitInterpolationElement(InterpolationElement node) => visitNode(node);
-
-  @override
-  R visitInterpolationExpression(InterpolationExpression node) =>
-      visitInterpolationElement(node);
-
-  @override
-  R visitInterpolationString(InterpolationString node) =>
-      visitInterpolationElement(node);
-
-  @override
-  R visitIsExpression(IsExpression node) => visitExpression(node);
-
-  @override
-  R visitLabel(Label node) => visitNode(node);
-
-  @override
-  R visitLabeledStatement(LabeledStatement node) => visitStatement(node);
-
-  @override
-  R visitLibraryDirective(LibraryDirective node) => visitDirective(node);
-
-  @override
-  R visitLibraryIdentifier(LibraryIdentifier node) => visitIdentifier(node);
-
-  @override
-  R visitListLiteral(ListLiteral node) => visitTypedLiteral(node);
-
-  R visitLiteral(Literal node) => visitExpression(node);
-
-  @override
-  R visitMapLiteral(MapLiteral node) => visitTypedLiteral(node);
-
-  @override
-  R visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
-
-  @override
-  R visitMethodDeclaration(MethodDeclaration node) => visitClassMember(node);
-
-  @override
-  R visitMethodInvocation(MethodInvocation node) => visitExpression(node);
-
-  R visitNamedCompilationUnitMember(NamedCompilationUnitMember node) =>
-      visitCompilationUnitMember(node);
-
-  @override
-  R visitNamedExpression(NamedExpression node) => visitExpression(node);
-
-  R visitNamespaceDirective(NamespaceDirective node) =>
-      visitUriBasedDirective(node);
-
-  @override
-  R visitNativeClause(NativeClause node) => visitNode(node);
-
-  @override
-  R visitNativeFunctionBody(NativeFunctionBody node) => visitFunctionBody(node);
-
-  R visitNode(AstNode node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  R visitNormalFormalParameter(NormalFormalParameter node) =>
-      visitFormalParameter(node);
-
-  @override
-  R visitNullLiteral(NullLiteral node) => visitLiteral(node);
-
-  @override
-  R visitParenthesizedExpression(ParenthesizedExpression node) =>
-      visitExpression(node);
-
-  @override
-  R visitPartDirective(PartDirective node) => visitUriBasedDirective(node);
-
-  @override
-  R visitPartOfDirective(PartOfDirective node) => visitDirective(node);
-
-  @override
-  R visitPostfixExpression(PostfixExpression node) => visitExpression(node);
-
-  @override
-  R visitPrefixedIdentifier(PrefixedIdentifier node) => visitIdentifier(node);
-
-  @override
-  R visitPrefixExpression(PrefixExpression node) => visitExpression(node);
-
-  @override
-  R visitPropertyAccess(PropertyAccess node) => visitExpression(node);
-
-  @override
-  R visitRedirectingConstructorInvocation(
-          RedirectingConstructorInvocation node) =>
-      visitConstructorInitializer(node);
-
-  @override
-  R visitRethrowExpression(RethrowExpression node) => visitExpression(node);
-
-  @override
-  R visitReturnStatement(ReturnStatement node) => visitStatement(node);
-
-  @override
-  R visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
-
-  @override
-  R visitShowCombinator(ShowCombinator node) => visitCombinator(node);
-
-  @override
-  R visitSimpleFormalParameter(SimpleFormalParameter node) =>
-      visitNormalFormalParameter(node);
-
-  @override
-  R visitSimpleIdentifier(SimpleIdentifier node) => visitIdentifier(node);
-
-  @override
-  R visitSimpleStringLiteral(SimpleStringLiteral node) =>
-      visitSingleStringLiteral(node);
-
-  R visitSingleStringLiteral(SingleStringLiteral node) =>
-      visitStringLiteral(node);
-
-  R visitStatement(Statement node) => visitNode(node);
-
-  @override
-  R visitStringInterpolation(StringInterpolation node) =>
-      visitSingleStringLiteral(node);
-
-  R visitStringLiteral(StringLiteral node) => visitLiteral(node);
-
-  @override
-  R visitSuperConstructorInvocation(SuperConstructorInvocation node) =>
-      visitConstructorInitializer(node);
-
-  @override
-  R visitSuperExpression(SuperExpression node) => visitExpression(node);
-
-  @override
-  R visitSwitchCase(SwitchCase node) => visitSwitchMember(node);
-
-  @override
-  R visitSwitchDefault(SwitchDefault node) => visitSwitchMember(node);
-
-  R visitSwitchMember(SwitchMember node) => visitNode(node);
-
-  @override
-  R visitSwitchStatement(SwitchStatement node) => visitStatement(node);
-
-  @override
-  R visitSymbolLiteral(SymbolLiteral node) => visitLiteral(node);
-
-  @override
-  R visitThisExpression(ThisExpression node) => visitExpression(node);
-
-  @override
-  R visitThrowExpression(ThrowExpression node) => visitExpression(node);
-
-  @override
-  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) =>
-      visitCompilationUnitMember(node);
-
-  @override
-  R visitTryStatement(TryStatement node) => visitStatement(node);
-
-  R visitTypeAlias(TypeAlias node) => visitNamedCompilationUnitMember(node);
-
-  @override
-  R visitTypeArgumentList(TypeArgumentList node) => visitNode(node);
-
-  R visitTypedLiteral(TypedLiteral node) => visitLiteral(node);
-
-  @override
-  R visitTypeName(TypeName node) => visitNode(node);
-
-  @override
-  R visitTypeParameter(TypeParameter node) => visitNode(node);
-
-  @override
-  R visitTypeParameterList(TypeParameterList node) => visitNode(node);
-
-  R visitUriBasedDirective(UriBasedDirective node) => visitDirective(node);
-
-  @override
-  R visitVariableDeclaration(VariableDeclaration node) =>
-      visitDeclaration(node);
-
-  @override
-  R visitVariableDeclarationList(VariableDeclarationList node) =>
-      visitNode(node);
-
-  @override
-  R visitVariableDeclarationStatement(VariableDeclarationStatement node) =>
-      visitStatement(node);
-
-  @override
-  R visitWhileStatement(WhileStatement node) => visitStatement(node);
-
-  @override
-  R visitWithClause(WithClause node) => visitNode(node);
-
-  @override
-  R visitYieldStatement(YieldStatement node) => visitStatement(node);
-}
-
-class GeneralizingAstVisitor_BreadthFirstVisitor
-    extends GeneralizingAstVisitor<Object> {
-  final BreadthFirstVisitor BreadthFirstVisitor_this;
-
-  GeneralizingAstVisitor_BreadthFirstVisitor(this.BreadthFirstVisitor_this)
-      : super();
-
-  @override
-  Object visitNode(AstNode node) {
-    BreadthFirstVisitor_this._queue.add(node);
-    return null;
-  }
-}
-
-/**
  * A combinator that restricts the names being imported to those that are not in
  * a given list.
  *
@@ -9490,20 +6485,6 @@
    */
   NodeList<TypeName> get interfaces => _interfaces;
 
-  /**
-   * Return the token representing the 'implements' keyword.
-   */
-  @deprecated // Use "this.implementsKeyword"
-  Token get keyword => implementsKeyword;
-
-  /**
-   * Set the token representing the 'implements' keyword to the given [token].
-   */
-  @deprecated // Use "this.implementsKeyword"
-  set keyword(Token token) {
-    implementsKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitImplementsClause(this);
 
@@ -9646,30 +6627,17 @@
       List<Annotation> metadata,
       Token keyword,
       StringLiteral libraryUri,
+      List<Configuration> configurations,
       this.deferredKeyword,
       this.asKeyword,
       SimpleIdentifier prefix,
       List<Combinator> combinators,
       Token semicolon)
-      : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
+      : super(comment, metadata, keyword, libraryUri, configurations,
+            combinators, semicolon) {
     _prefix = _becomeParentOf(prefix);
   }
 
-  /**
-   * The token representing the 'as' token, or `null` if the imported names are
-   * not prefixed.
-   */
-  @deprecated // Use "this.asKeyword"
-  Token get asToken => asKeyword;
-
-  /**
-   * The token representing the 'as' token to the given token.
-   */
-  @deprecated // Use "this.asKeyword"
-  set asToken(Token token) {
-    asKeyword = token;
-  }
-
   @override
   Iterable get childEntities => super._childEntities
     ..add(_uri)
@@ -9679,21 +6647,6 @@
     ..addAll(combinators)
     ..add(semicolon);
 
-  /**
-   * Return the token representing the 'deferred' token, or `null` if the
-   * imported is not deferred.
-   */
-  @deprecated // Use "this.deferredKeyword"
-  Token get deferredToken => deferredKeyword;
-
-  /**
-   * Set the token representing the 'deferred' token to the given token.
-   */
-  @deprecated // Use "this.deferredKeyword"
-  set deferredToken(Token token) {
-    deferredKeyword = token;
-  }
-
   @override
   ImportElement get element => super.element as ImportElement;
 
@@ -9731,1047 +6684,6 @@
 }
 
 /**
- * An object that will clone any AST structure that it visits. The cloner will
- * clone the structure, replacing the specified ASTNode with a new ASTNode,
- * mapping the old token stream to a new token stream, and preserving resolution
- * results.
- */
-class IncrementalAstCloner implements AstVisitor<AstNode> {
-  /**
-   * The node to be replaced during the cloning process.
-   */
-  final AstNode _oldNode;
-
-  /**
-   * The replacement node used during the cloning process.
-   */
-  final AstNode _newNode;
-
-  /**
-   * A mapping of old tokens to new tokens used during the cloning process.
-   */
-  final TokenMap _tokenMap;
-
-  /**
-   * Construct a new instance that will replace the [oldNode] with the [newNode]
-   * in the process of cloning an existing AST structure. The [tokenMap] is a
-   * mapping of old tokens to new tokens.
-   */
-  IncrementalAstCloner(this._oldNode, this._newNode, this._tokenMap);
-
-  @override
-  AdjacentStrings visitAdjacentStrings(AdjacentStrings node) =>
-      new AdjacentStrings(_cloneNodeList(node.strings));
-
-  @override
-  Annotation visitAnnotation(Annotation node) {
-    Annotation copy = new Annotation(
-        _mapToken(node.atSign),
-        _cloneNode(node.name),
-        _mapToken(node.period),
-        _cloneNode(node.constructorName),
-        _cloneNode(node.arguments));
-    copy.element = node.element;
-    return copy;
-  }
-
-  @override
-  ArgumentList visitArgumentList(ArgumentList node) => new ArgumentList(
-      _mapToken(node.leftParenthesis),
-      _cloneNodeList(node.arguments),
-      _mapToken(node.rightParenthesis));
-
-  @override
-  AsExpression visitAsExpression(AsExpression node) {
-    AsExpression copy = new AsExpression(_cloneNode(node.expression),
-        _mapToken(node.asOperator), _cloneNode(node.type));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  AstNode visitAssertStatement(AssertStatement node) => new AssertStatement(
-      _mapToken(node.assertKeyword),
-      _mapToken(node.leftParenthesis),
-      _cloneNode(node.condition),
-      _mapToken(node.rightParenthesis),
-      _mapToken(node.semicolon));
-
-  @override
-  AssignmentExpression visitAssignmentExpression(AssignmentExpression node) {
-    AssignmentExpression copy = new AssignmentExpression(
-        _cloneNode(node.leftHandSide),
-        _mapToken(node.operator),
-        _cloneNode(node.rightHandSide));
-    copy.propagatedElement = node.propagatedElement;
-    copy.propagatedType = node.propagatedType;
-    copy.staticElement = node.staticElement;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  AwaitExpression visitAwaitExpression(AwaitExpression node) =>
-      new AwaitExpression(
-          _mapToken(node.awaitKeyword), _cloneNode(node.expression));
-
-  @override
-  BinaryExpression visitBinaryExpression(BinaryExpression node) {
-    BinaryExpression copy = new BinaryExpression(_cloneNode(node.leftOperand),
-        _mapToken(node.operator), _cloneNode(node.rightOperand));
-    copy.propagatedElement = node.propagatedElement;
-    copy.propagatedType = node.propagatedType;
-    copy.staticElement = node.staticElement;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  Block visitBlock(Block node) => new Block(_mapToken(node.leftBracket),
-      _cloneNodeList(node.statements), _mapToken(node.rightBracket));
-
-  @override
-  BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) =>
-      new BlockFunctionBody(_mapToken(node.keyword), _mapToken(node.star),
-          _cloneNode(node.block));
-
-  @override
-  BooleanLiteral visitBooleanLiteral(BooleanLiteral node) {
-    BooleanLiteral copy =
-        new BooleanLiteral(_mapToken(node.literal), node.value);
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  BreakStatement visitBreakStatement(BreakStatement node) => new BreakStatement(
-      _mapToken(node.breakKeyword),
-      _cloneNode(node.label),
-      _mapToken(node.semicolon));
-
-  @override
-  CascadeExpression visitCascadeExpression(CascadeExpression node) {
-    CascadeExpression copy = new CascadeExpression(
-        _cloneNode(node.target), _cloneNodeList(node.cascadeSections));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  CatchClause visitCatchClause(CatchClause node) => new CatchClause(
-      _mapToken(node.onKeyword),
-      _cloneNode(node.exceptionType),
-      _mapToken(node.catchKeyword),
-      _mapToken(node.leftParenthesis),
-      _cloneNode(node.exceptionParameter),
-      _mapToken(node.comma),
-      _cloneNode(node.stackTraceParameter),
-      _mapToken(node.rightParenthesis),
-      _cloneNode(node.body));
-
-  @override
-  ClassDeclaration visitClassDeclaration(ClassDeclaration node) {
-    ClassDeclaration copy = new ClassDeclaration(
-        _cloneNode(node.documentationComment),
-        _cloneNodeList(node.metadata),
-        _mapToken(node.abstractKeyword),
-        _mapToken(node.classKeyword),
-        _cloneNode(node.name),
-        _cloneNode(node.typeParameters),
-        _cloneNode(node.extendsClause),
-        _cloneNode(node.withClause),
-        _cloneNode(node.implementsClause),
-        _mapToken(node.leftBracket),
-        _cloneNodeList(node.members),
-        _mapToken(node.rightBracket));
-    copy.nativeClause = _cloneNode(node.nativeClause);
-    return copy;
-  }
-
-  @override
-  ClassTypeAlias visitClassTypeAlias(ClassTypeAlias node) => new ClassTypeAlias(
-      _cloneNode(node.documentationComment),
-      _cloneNodeList(node.metadata),
-      _mapToken(node.typedefKeyword),
-      _cloneNode(node.name),
-      _cloneNode(node.typeParameters),
-      _mapToken(node.equals),
-      _mapToken(node.abstractKeyword),
-      _cloneNode(node.superclass),
-      _cloneNode(node.withClause),
-      _cloneNode(node.implementsClause),
-      _mapToken(node.semicolon));
-
-  @override
-  Comment visitComment(Comment node) {
-    if (node.isDocumentation) {
-      return Comment.createDocumentationCommentWithReferences(
-          _mapTokens(node.tokens), _cloneNodeList(node.references));
-    } else if (node.isBlock) {
-      return Comment.createBlockComment(_mapTokens(node.tokens));
-    }
-    return Comment.createEndOfLineComment(_mapTokens(node.tokens));
-  }
-
-  @override
-  CommentReference visitCommentReference(CommentReference node) =>
-      new CommentReference(
-          _mapToken(node.newKeyword), _cloneNode(node.identifier));
-
-  @override
-  CompilationUnit visitCompilationUnit(CompilationUnit node) {
-    CompilationUnit copy = new CompilationUnit(
-        _mapToken(node.beginToken),
-        _cloneNode(node.scriptTag),
-        _cloneNodeList(node.directives),
-        _cloneNodeList(node.declarations),
-        _mapToken(node.endToken));
-    copy.lineInfo = node.lineInfo;
-    copy.element = node.element;
-    return copy;
-  }
-
-  @override
-  ConditionalExpression visitConditionalExpression(ConditionalExpression node) {
-    ConditionalExpression copy = new ConditionalExpression(
-        _cloneNode(node.condition),
-        _mapToken(node.question),
-        _cloneNode(node.thenExpression),
-        _mapToken(node.colon),
-        _cloneNode(node.elseExpression));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  ConstructorDeclaration visitConstructorDeclaration(
-      ConstructorDeclaration node) {
-    ConstructorDeclaration copy = new ConstructorDeclaration(
-        _cloneNode(node.documentationComment),
-        _cloneNodeList(node.metadata),
-        _mapToken(node.externalKeyword),
-        _mapToken(node.constKeyword),
-        _mapToken(node.factoryKeyword),
-        _cloneNode(node.returnType),
-        _mapToken(node.period),
-        _cloneNode(node.name),
-        _cloneNode(node.parameters),
-        _mapToken(node.separator),
-        _cloneNodeList(node.initializers),
-        _cloneNode(node.redirectedConstructor),
-        _cloneNode(node.body));
-    copy.element = node.element;
-    return copy;
-  }
-
-  @override
-  ConstructorFieldInitializer visitConstructorFieldInitializer(
-          ConstructorFieldInitializer node) =>
-      new ConstructorFieldInitializer(
-          _mapToken(node.thisKeyword),
-          _mapToken(node.period),
-          _cloneNode(node.fieldName),
-          _mapToken(node.equals),
-          _cloneNode(node.expression));
-
-  @override
-  ConstructorName visitConstructorName(ConstructorName node) {
-    ConstructorName copy = new ConstructorName(
-        _cloneNode(node.type), _mapToken(node.period), _cloneNode(node.name));
-    copy.staticElement = node.staticElement;
-    return copy;
-  }
-
-  @override
-  ContinueStatement visitContinueStatement(ContinueStatement node) =>
-      new ContinueStatement(_mapToken(node.continueKeyword),
-          _cloneNode(node.label), _mapToken(node.semicolon));
-
-  @override
-  DeclaredIdentifier visitDeclaredIdentifier(DeclaredIdentifier node) =>
-      new DeclaredIdentifier(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _mapToken(node.keyword),
-          _cloneNode(node.type),
-          _cloneNode(node.identifier));
-
-  @override
-  DefaultFormalParameter visitDefaultFormalParameter(
-          DefaultFormalParameter node) =>
-      new DefaultFormalParameter(_cloneNode(node.parameter), node.kind,
-          _mapToken(node.separator), _cloneNode(node.defaultValue));
-
-  @override
-  DoStatement visitDoStatement(DoStatement node) => new DoStatement(
-      _mapToken(node.doKeyword),
-      _cloneNode(node.body),
-      _mapToken(node.whileKeyword),
-      _mapToken(node.leftParenthesis),
-      _cloneNode(node.condition),
-      _mapToken(node.rightParenthesis),
-      _mapToken(node.semicolon));
-
-  @override
-  DoubleLiteral visitDoubleLiteral(DoubleLiteral node) {
-    DoubleLiteral copy = new DoubleLiteral(_mapToken(node.literal), node.value);
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  EmptyFunctionBody visitEmptyFunctionBody(EmptyFunctionBody node) =>
-      new EmptyFunctionBody(_mapToken(node.semicolon));
-
-  @override
-  EmptyStatement visitEmptyStatement(EmptyStatement node) =>
-      new EmptyStatement(_mapToken(node.semicolon));
-
-  @override
-  AstNode visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
-      new EnumConstantDeclaration(_cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata), _cloneNode(node.name));
-
-  @override
-  AstNode visitEnumDeclaration(EnumDeclaration node) => new EnumDeclaration(
-      _cloneNode(node.documentationComment),
-      _cloneNodeList(node.metadata),
-      _mapToken(node.enumKeyword),
-      _cloneNode(node.name),
-      _mapToken(node.leftBracket),
-      _cloneNodeList(node.constants),
-      _mapToken(node.rightBracket));
-
-  @override
-  ExportDirective visitExportDirective(ExportDirective node) {
-    ExportDirective copy = new ExportDirective(
-        _cloneNode(node.documentationComment),
-        _cloneNodeList(node.metadata),
-        _mapToken(node.keyword),
-        _cloneNode(node.uri),
-        _cloneNodeList(node.combinators),
-        _mapToken(node.semicolon));
-    copy.element = node.element;
-    return copy;
-  }
-
-  @override
-  ExpressionFunctionBody visitExpressionFunctionBody(
-          ExpressionFunctionBody node) =>
-      new ExpressionFunctionBody(
-          _mapToken(node.keyword),
-          _mapToken(node.functionDefinition),
-          _cloneNode(node.expression),
-          _mapToken(node.semicolon));
-
-  @override
-  ExpressionStatement visitExpressionStatement(ExpressionStatement node) =>
-      new ExpressionStatement(
-          _cloneNode(node.expression), _mapToken(node.semicolon));
-
-  @override
-  ExtendsClause visitExtendsClause(ExtendsClause node) => new ExtendsClause(
-      _mapToken(node.extendsKeyword), _cloneNode(node.superclass));
-
-  @override
-  FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
-      new FieldDeclaration(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _mapToken(node.staticKeyword),
-          _cloneNode(node.fields),
-          _mapToken(node.semicolon));
-
-  @override
-  FieldFormalParameter visitFieldFormalParameter(FieldFormalParameter node) =>
-      new FieldFormalParameter(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _mapToken(node.keyword),
-          _cloneNode(node.type),
-          _mapToken(node.thisKeyword),
-          _mapToken(node.period),
-          _cloneNode(node.identifier),
-          _cloneNode(node.typeParameters),
-          _cloneNode(node.parameters));
-
-  @override
-  ForEachStatement visitForEachStatement(ForEachStatement node) {
-    DeclaredIdentifier loopVariable = node.loopVariable;
-    if (loopVariable == null) {
-      return new ForEachStatement.withReference(
-          _mapToken(node.awaitKeyword),
-          _mapToken(node.forKeyword),
-          _mapToken(node.leftParenthesis),
-          _cloneNode(node.identifier),
-          _mapToken(node.inKeyword),
-          _cloneNode(node.iterable),
-          _mapToken(node.rightParenthesis),
-          _cloneNode(node.body));
-    }
-    return new ForEachStatement.withDeclaration(
-        _mapToken(node.awaitKeyword),
-        _mapToken(node.forKeyword),
-        _mapToken(node.leftParenthesis),
-        _cloneNode(loopVariable),
-        _mapToken(node.inKeyword),
-        _cloneNode(node.iterable),
-        _mapToken(node.rightParenthesis),
-        _cloneNode(node.body));
-  }
-
-  @override
-  FormalParameterList visitFormalParameterList(FormalParameterList node) =>
-      new FormalParameterList(
-          _mapToken(node.leftParenthesis),
-          _cloneNodeList(node.parameters),
-          _mapToken(node.leftDelimiter),
-          _mapToken(node.rightDelimiter),
-          _mapToken(node.rightParenthesis));
-
-  @override
-  ForStatement visitForStatement(ForStatement node) => new ForStatement(
-      _mapToken(node.forKeyword),
-      _mapToken(node.leftParenthesis),
-      _cloneNode(node.variables),
-      _cloneNode(node.initialization),
-      _mapToken(node.leftSeparator),
-      _cloneNode(node.condition),
-      _mapToken(node.rightSeparator),
-      _cloneNodeList(node.updaters),
-      _mapToken(node.rightParenthesis),
-      _cloneNode(node.body));
-
-  @override
-  FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) =>
-      new FunctionDeclaration(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _mapToken(node.externalKeyword),
-          _cloneNode(node.returnType),
-          _mapToken(node.propertyKeyword),
-          _cloneNode(node.name),
-          _cloneNode(node.functionExpression));
-
-  @override
-  FunctionDeclarationStatement visitFunctionDeclarationStatement(
-          FunctionDeclarationStatement node) =>
-      new FunctionDeclarationStatement(_cloneNode(node.functionDeclaration));
-
-  @override
-  FunctionExpression visitFunctionExpression(FunctionExpression node) {
-    FunctionExpression copy = new FunctionExpression(
-        _cloneNode(node.typeParameters),
-        _cloneNode(node.parameters),
-        _cloneNode(node.body));
-    copy.element = node.element;
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  FunctionExpressionInvocation visitFunctionExpressionInvocation(
-      FunctionExpressionInvocation node) {
-    FunctionExpressionInvocation copy = new FunctionExpressionInvocation(
-        _cloneNode(node.function),
-        _cloneNode(node.typeArguments),
-        _cloneNode(node.argumentList));
-    copy.propagatedElement = node.propagatedElement;
-    copy.propagatedType = node.propagatedType;
-    copy.staticElement = node.staticElement;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) =>
-      new FunctionTypeAlias(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _mapToken(node.typedefKeyword),
-          _cloneNode(node.returnType),
-          _cloneNode(node.name),
-          _cloneNode(node.typeParameters),
-          _cloneNode(node.parameters),
-          _mapToken(node.semicolon));
-
-  @override
-  FunctionTypedFormalParameter visitFunctionTypedFormalParameter(
-          FunctionTypedFormalParameter node) =>
-      new FunctionTypedFormalParameter(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _cloneNode(node.returnType),
-          _cloneNode(node.identifier),
-          _cloneNode(node.typeParameters),
-          _cloneNode(node.parameters));
-
-  @override
-  HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
-      _mapToken(node.keyword), _cloneNodeList(node.hiddenNames));
-
-  @override
-  IfStatement visitIfStatement(IfStatement node) => new IfStatement(
-      _mapToken(node.ifKeyword),
-      _mapToken(node.leftParenthesis),
-      _cloneNode(node.condition),
-      _mapToken(node.rightParenthesis),
-      _cloneNode(node.thenStatement),
-      _mapToken(node.elseKeyword),
-      _cloneNode(node.elseStatement));
-
-  @override
-  ImplementsClause visitImplementsClause(ImplementsClause node) =>
-      new ImplementsClause(
-          _mapToken(node.implementsKeyword), _cloneNodeList(node.interfaces));
-
-  @override
-  ImportDirective visitImportDirective(ImportDirective node) =>
-      new ImportDirective(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _mapToken(node.keyword),
-          _cloneNode(node.uri),
-          _mapToken(node.deferredKeyword),
-          _mapToken(node.asKeyword),
-          _cloneNode(node.prefix),
-          _cloneNodeList(node.combinators),
-          _mapToken(node.semicolon));
-
-  @override
-  IndexExpression visitIndexExpression(IndexExpression node) {
-    Token period = _mapToken(node.period);
-    IndexExpression copy;
-    if (period == null) {
-      copy = new IndexExpression.forTarget(
-          _cloneNode(node.target),
-          _mapToken(node.leftBracket),
-          _cloneNode(node.index),
-          _mapToken(node.rightBracket));
-    } else {
-      copy = new IndexExpression.forCascade(period, _mapToken(node.leftBracket),
-          _cloneNode(node.index), _mapToken(node.rightBracket));
-    }
-    copy.auxiliaryElements = node.auxiliaryElements;
-    copy.propagatedElement = node.propagatedElement;
-    copy.propagatedType = node.propagatedType;
-    copy.staticElement = node.staticElement;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  InstanceCreationExpression visitInstanceCreationExpression(
-      InstanceCreationExpression node) {
-    InstanceCreationExpression copy = new InstanceCreationExpression(
-        _mapToken(node.keyword),
-        _cloneNode(node.constructorName),
-        _cloneNode(node.argumentList));
-    copy.propagatedType = node.propagatedType;
-    copy.staticElement = node.staticElement;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  IntegerLiteral visitIntegerLiteral(IntegerLiteral node) {
-    IntegerLiteral copy =
-        new IntegerLiteral(_mapToken(node.literal), node.value);
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  InterpolationExpression visitInterpolationExpression(
-          InterpolationExpression node) =>
-      new InterpolationExpression(_mapToken(node.leftBracket),
-          _cloneNode(node.expression), _mapToken(node.rightBracket));
-
-  @override
-  InterpolationString visitInterpolationString(InterpolationString node) =>
-      new InterpolationString(_mapToken(node.contents), node.value);
-
-  @override
-  IsExpression visitIsExpression(IsExpression node) {
-    IsExpression copy = new IsExpression(
-        _cloneNode(node.expression),
-        _mapToken(node.isOperator),
-        _mapToken(node.notOperator),
-        _cloneNode(node.type));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  Label visitLabel(Label node) =>
-      new Label(_cloneNode(node.label), _mapToken(node.colon));
-
-  @override
-  LabeledStatement visitLabeledStatement(LabeledStatement node) =>
-      new LabeledStatement(
-          _cloneNodeList(node.labels), _cloneNode(node.statement));
-
-  @override
-  LibraryDirective visitLibraryDirective(LibraryDirective node) =>
-      new LibraryDirective(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _mapToken(node.libraryKeyword),
-          _cloneNode(node.name),
-          _mapToken(node.semicolon));
-
-  @override
-  LibraryIdentifier visitLibraryIdentifier(LibraryIdentifier node) {
-    LibraryIdentifier copy =
-        new LibraryIdentifier(_cloneNodeList(node.components));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  ListLiteral visitListLiteral(ListLiteral node) {
-    ListLiteral copy = new ListLiteral(
-        _mapToken(node.constKeyword),
-        _cloneNode(node.typeArguments),
-        _mapToken(node.leftBracket),
-        _cloneNodeList(node.elements),
-        _mapToken(node.rightBracket));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  MapLiteral visitMapLiteral(MapLiteral node) {
-    MapLiteral copy = new MapLiteral(
-        _mapToken(node.constKeyword),
-        _cloneNode(node.typeArguments),
-        _mapToken(node.leftBracket),
-        _cloneNodeList(node.entries),
-        _mapToken(node.rightBracket));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) =>
-      new MapLiteralEntry(_cloneNode(node.key), _mapToken(node.separator),
-          _cloneNode(node.value));
-
-  @override
-  MethodDeclaration visitMethodDeclaration(MethodDeclaration node) =>
-      new MethodDeclaration(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _mapToken(node.externalKeyword),
-          _mapToken(node.modifierKeyword),
-          _cloneNode(node.returnType),
-          _mapToken(node.propertyKeyword),
-          _mapToken(node.operatorKeyword),
-          _cloneNode(node.name),
-          _cloneNode(node._typeParameters),
-          _cloneNode(node.parameters),
-          _cloneNode(node.body));
-
-  @override
-  MethodInvocation visitMethodInvocation(MethodInvocation node) {
-    MethodInvocation copy = new MethodInvocation(
-        _cloneNode(node.target),
-        _mapToken(node.operator),
-        _cloneNode(node.methodName),
-        _cloneNode(node.typeArguments),
-        _cloneNode(node.argumentList));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  NamedExpression visitNamedExpression(NamedExpression node) {
-    NamedExpression copy =
-        new NamedExpression(_cloneNode(node.name), _cloneNode(node.expression));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  AstNode visitNativeClause(NativeClause node) =>
-      new NativeClause(_mapToken(node.nativeKeyword), _cloneNode(node.name));
-
-  @override
-  NativeFunctionBody visitNativeFunctionBody(NativeFunctionBody node) =>
-      new NativeFunctionBody(_mapToken(node.nativeKeyword),
-          _cloneNode(node.stringLiteral), _mapToken(node.semicolon));
-
-  @override
-  NullLiteral visitNullLiteral(NullLiteral node) {
-    NullLiteral copy = new NullLiteral(_mapToken(node.literal));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  ParenthesizedExpression visitParenthesizedExpression(
-      ParenthesizedExpression node) {
-    ParenthesizedExpression copy = new ParenthesizedExpression(
-        _mapToken(node.leftParenthesis),
-        _cloneNode(node.expression),
-        _mapToken(node.rightParenthesis));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  PartDirective visitPartDirective(PartDirective node) {
-    PartDirective copy = new PartDirective(
-        _cloneNode(node.documentationComment),
-        _cloneNodeList(node.metadata),
-        _mapToken(node.partKeyword),
-        _cloneNode(node.uri),
-        _mapToken(node.semicolon));
-    copy.element = node.element;
-    return copy;
-  }
-
-  @override
-  PartOfDirective visitPartOfDirective(PartOfDirective node) {
-    PartOfDirective copy = new PartOfDirective(
-        _cloneNode(node.documentationComment),
-        _cloneNodeList(node.metadata),
-        _mapToken(node.partKeyword),
-        _mapToken(node.ofKeyword),
-        _cloneNode(node.libraryName),
-        _mapToken(node.semicolon));
-    copy.element = node.element;
-    return copy;
-  }
-
-  @override
-  PostfixExpression visitPostfixExpression(PostfixExpression node) {
-    PostfixExpression copy = new PostfixExpression(
-        _cloneNode(node.operand), _mapToken(node.operator));
-    copy.propagatedElement = node.propagatedElement;
-    copy.propagatedType = node.propagatedType;
-    copy.staticElement = node.staticElement;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) {
-    PrefixedIdentifier copy = new PrefixedIdentifier(_cloneNode(node.prefix),
-        _mapToken(node.period), _cloneNode(node.identifier));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  PrefixExpression visitPrefixExpression(PrefixExpression node) {
-    PrefixExpression copy = new PrefixExpression(
-        _mapToken(node.operator), _cloneNode(node.operand));
-    copy.propagatedElement = node.propagatedElement;
-    copy.propagatedType = node.propagatedType;
-    copy.staticElement = node.staticElement;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  PropertyAccess visitPropertyAccess(PropertyAccess node) {
-    PropertyAccess copy = new PropertyAccess(_cloneNode(node.target),
-        _mapToken(node.operator), _cloneNode(node.propertyName));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    RedirectingConstructorInvocation copy =
-        new RedirectingConstructorInvocation(
-            _mapToken(node.thisKeyword),
-            _mapToken(node.period),
-            _cloneNode(node.constructorName),
-            _cloneNode(node.argumentList));
-    copy.staticElement = node.staticElement;
-    return copy;
-  }
-
-  @override
-  RethrowExpression visitRethrowExpression(RethrowExpression node) {
-    RethrowExpression copy =
-        new RethrowExpression(_mapToken(node.rethrowKeyword));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  ReturnStatement visitReturnStatement(ReturnStatement node) =>
-      new ReturnStatement(_mapToken(node.returnKeyword),
-          _cloneNode(node.expression), _mapToken(node.semicolon));
-
-  @override
-  ScriptTag visitScriptTag(ScriptTag node) =>
-      new ScriptTag(_mapToken(node.scriptTag));
-
-  @override
-  ShowCombinator visitShowCombinator(ShowCombinator node) => new ShowCombinator(
-      _mapToken(node.keyword), _cloneNodeList(node.shownNames));
-
-  @override
-  SimpleFormalParameter visitSimpleFormalParameter(
-          SimpleFormalParameter node) =>
-      new SimpleFormalParameter(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _mapToken(node.keyword),
-          _cloneNode(node.type),
-          _cloneNode(node.identifier));
-
-  @override
-  SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
-    Token mappedToken = _mapToken(node.token);
-    if (mappedToken == null) {
-      // This only happens for SimpleIdentifiers created by the parser as part
-      // of scanning documentation comments (the tokens for those identifiers
-      // are not in the original token stream and hence do not get copied).
-      // This extra check can be removed if the scanner is changed to scan
-      // documentation comments for the parser.
-      mappedToken = node.token;
-    }
-    SimpleIdentifier copy = new SimpleIdentifier(mappedToken);
-    copy.auxiliaryElements = node.auxiliaryElements;
-    copy.propagatedElement = node.propagatedElement;
-    copy.propagatedType = node.propagatedType;
-    copy.staticElement = node.staticElement;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  SimpleStringLiteral visitSimpleStringLiteral(SimpleStringLiteral node) {
-    SimpleStringLiteral copy =
-        new SimpleStringLiteral(_mapToken(node.literal), node.value);
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  StringInterpolation visitStringInterpolation(StringInterpolation node) {
-    StringInterpolation copy =
-        new StringInterpolation(_cloneNodeList(node.elements));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  SuperConstructorInvocation visitSuperConstructorInvocation(
-      SuperConstructorInvocation node) {
-    SuperConstructorInvocation copy = new SuperConstructorInvocation(
-        _mapToken(node.superKeyword),
-        _mapToken(node.period),
-        _cloneNode(node.constructorName),
-        _cloneNode(node.argumentList));
-    copy.staticElement = node.staticElement;
-    return copy;
-  }
-
-  @override
-  SuperExpression visitSuperExpression(SuperExpression node) {
-    SuperExpression copy = new SuperExpression(_mapToken(node.superKeyword));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  SwitchCase visitSwitchCase(SwitchCase node) => new SwitchCase(
-      _cloneNodeList(node.labels),
-      _mapToken(node.keyword),
-      _cloneNode(node.expression),
-      _mapToken(node.colon),
-      _cloneNodeList(node.statements));
-
-  @override
-  SwitchDefault visitSwitchDefault(SwitchDefault node) => new SwitchDefault(
-      _cloneNodeList(node.labels),
-      _mapToken(node.keyword),
-      _mapToken(node.colon),
-      _cloneNodeList(node.statements));
-
-  @override
-  SwitchStatement visitSwitchStatement(SwitchStatement node) =>
-      new SwitchStatement(
-          _mapToken(node.switchKeyword),
-          _mapToken(node.leftParenthesis),
-          _cloneNode(node.expression),
-          _mapToken(node.rightParenthesis),
-          _mapToken(node.leftBracket),
-          _cloneNodeList(node.members),
-          _mapToken(node.rightBracket));
-
-  @override
-  AstNode visitSymbolLiteral(SymbolLiteral node) {
-    SymbolLiteral copy = new SymbolLiteral(
-        _mapToken(node.poundSign), _mapTokens(node.components));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  ThisExpression visitThisExpression(ThisExpression node) {
-    ThisExpression copy = new ThisExpression(_mapToken(node.thisKeyword));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  ThrowExpression visitThrowExpression(ThrowExpression node) {
-    ThrowExpression copy = new ThrowExpression(
-        _mapToken(node.throwKeyword), _cloneNode(node.expression));
-    copy.propagatedType = node.propagatedType;
-    copy.staticType = node.staticType;
-    return copy;
-  }
-
-  @override
-  TopLevelVariableDeclaration visitTopLevelVariableDeclaration(
-          TopLevelVariableDeclaration node) =>
-      new TopLevelVariableDeclaration(
-          _cloneNode(node.documentationComment),
-          _cloneNodeList(node.metadata),
-          _cloneNode(node.variables),
-          _mapToken(node.semicolon));
-
-  @override
-  TryStatement visitTryStatement(TryStatement node) => new TryStatement(
-      _mapToken(node.tryKeyword),
-      _cloneNode(node.body),
-      _cloneNodeList(node.catchClauses),
-      _mapToken(node.finallyKeyword),
-      _cloneNode(node.finallyBlock));
-
-  @override
-  TypeArgumentList visitTypeArgumentList(TypeArgumentList node) =>
-      new TypeArgumentList(_mapToken(node.leftBracket),
-          _cloneNodeList(node.arguments), _mapToken(node.rightBracket));
-
-  @override
-  TypeName visitTypeName(TypeName node) {
-    TypeName copy =
-        new TypeName(_cloneNode(node.name), _cloneNode(node.typeArguments));
-    copy.type = node.type;
-    return copy;
-  }
-
-  @override
-  TypeParameter visitTypeParameter(TypeParameter node) => new TypeParameter(
-      _cloneNode(node.documentationComment),
-      _cloneNodeList(node.metadata),
-      _cloneNode(node.name),
-      _mapToken(node.extendsKeyword),
-      _cloneNode(node.bound));
-
-  @override
-  TypeParameterList visitTypeParameterList(TypeParameterList node) =>
-      new TypeParameterList(_mapToken(node.leftBracket),
-          _cloneNodeList(node.typeParameters), _mapToken(node.rightBracket));
-
-  @override
-  VariableDeclaration visitVariableDeclaration(VariableDeclaration node) =>
-      new VariableDeclaration(_cloneNode(node.name), _mapToken(node.equals),
-          _cloneNode(node.initializer));
-
-  @override
-  VariableDeclarationList visitVariableDeclarationList(
-          VariableDeclarationList node) =>
-      new VariableDeclarationList(
-          null,
-          _cloneNodeList(node.metadata),
-          _mapToken(node.keyword),
-          _cloneNode(node.type),
-          _cloneNodeList(node.variables));
-
-  @override
-  VariableDeclarationStatement visitVariableDeclarationStatement(
-          VariableDeclarationStatement node) =>
-      new VariableDeclarationStatement(
-          _cloneNode(node.variables), _mapToken(node.semicolon));
-
-  @override
-  WhileStatement visitWhileStatement(WhileStatement node) => new WhileStatement(
-      _mapToken(node.whileKeyword),
-      _mapToken(node.leftParenthesis),
-      _cloneNode(node.condition),
-      _mapToken(node.rightParenthesis),
-      _cloneNode(node.body));
-
-  @override
-  WithClause visitWithClause(WithClause node) => new WithClause(
-      _mapToken(node.withKeyword), _cloneNodeList(node.mixinTypes));
-
-  @override
-  YieldStatement visitYieldStatement(YieldStatement node) => new YieldStatement(
-      _mapToken(node.yieldKeyword),
-      _mapToken(node.star),
-      _cloneNode(node.expression),
-      _mapToken(node.semicolon));
-
-  AstNode _cloneNode(AstNode node) {
-    if (node == null) {
-      return null;
-    }
-    if (identical(node, _oldNode)) {
-      return _newNode;
-    }
-    return node.accept(this) as AstNode;
-  }
-
-  List _cloneNodeList(NodeList nodes) {
-    List clonedNodes = new List();
-    for (AstNode node in nodes) {
-      clonedNodes.add(_cloneNode(node));
-    }
-    return clonedNodes;
-  }
-
-  Token _mapToken(Token oldToken) {
-    if (oldToken == null) {
-      return null;
-    }
-    return _tokenMap.get(oldToken);
-  }
-
-  List<Token> _mapTokens(List<Token> oldTokens) {
-    List<Token> newTokens = new List<Token>(oldTokens.length);
-    for (int index = 0; index < newTokens.length; index++) {
-      newTokens[index] = _mapToken(oldTokens[index]);
-    }
-    return newTokens;
-  }
-}
-
-/**
  * An index expression.
  *
  * > indexExpression ::=
@@ -10904,17 +6816,6 @@
   int get precedence => 15;
 
   /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the index
-   * expression will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForIndex {
-    return _propagatedParameterElementForIndex;
-  }
-
-  /**
    * Return the expression used to compute the object being indexed. If this
    * index expression is not part of a cascade expression, then this is the same
    * as [target]. If this index expression is part of a cascade expression, then
@@ -10935,17 +6836,6 @@
   }
 
   /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the index expression will
-   * be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get staticParameterElementForIndex {
-    return _staticParameterElementForIndex;
-  }
-
-  /**
    * Return the expression used to compute the object being indexed, or `null`
    * if this index expression is part of a cascade expression.
    *
@@ -11129,7 +7019,8 @@
    * Return `true` if this creation expression is used to invoke a constant
    * constructor.
    */
-  bool get isConst => keyword is KeywordToken &&
+  bool get isConst =>
+      keyword is KeywordToken &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   @override
@@ -11150,14 +7041,14 @@
  *
  * > integerLiteral ::=
  * >     decimalIntegerLiteral
- * >   | hexidecimalIntegerLiteral
+ * >   | hexadecimalIntegerLiteral
  * >
  * > decimalIntegerLiteral ::=
  * >     decimalDigit+
  * >
- * > hexidecimalIntegerLiteral ::=
- * >     '0x' hexidecimalDigit+
- * >   | '0X' hexidecimalDigit+
+ * > hexadecimalIntegerLiteral ::=
+ * >     '0x' hexadecimalDigit+
+ * >   | '0X' hexadecimalDigit+
  */
 class IntegerLiteral extends Literal {
   /**
@@ -11593,20 +7484,6 @@
   Token get keyword => libraryKeyword;
 
   /**
-   * Return the token representing the 'library' token.
-   */
-  @deprecated // Use "this.libraryKeyword"
-  Token get libraryToken => libraryKeyword;
-
-  /**
-   * Set the token representing the 'library' token to the given [token].
-   */
-  @deprecated // Use "this.libraryKeyword"
-  set libraryToken(Token token) {
-    libraryKeyword = token;
-  }
-
-  /**
    * Return the name of the library being defined.
    */
   LibraryIdentifier get name => _name;
@@ -12095,7 +7972,8 @@
   /**
    * Return `true` if this method declares a getter.
    */
-  bool get isGetter => propertyKeyword != null &&
+  bool get isGetter =>
+      propertyKeyword != null &&
       (propertyKeyword as KeywordToken).keyword == Keyword.GET;
 
   /**
@@ -12106,13 +7984,15 @@
   /**
    * Return `true` if this method declares a setter.
    */
-  bool get isSetter => propertyKeyword != null &&
+  bool get isSetter =>
+      propertyKeyword != null &&
       (propertyKeyword as KeywordToken).keyword == Keyword.SET;
 
   /**
    * Return `true` if this method is declared to be a static method.
    */
-  bool get isStatic => modifierKeyword != null &&
+  bool get isStatic =>
+      modifierKeyword != null &&
       (modifierKeyword as KeywordToken).keyword == Keyword.STATIC;
 
   /**
@@ -12188,7 +8068,7 @@
  * [FunctionExpressionInvocation] nodes. Invocations of getters and setters are
  * represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.
  *
- * > methodInvoction ::=
+ * > methodInvocation ::=
  * >     ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
  */
 class MethodInvocation extends Expression {
@@ -12223,6 +8103,21 @@
   ArgumentList _argumentList;
 
   /**
+   * The function type of the method invocation, or `null` if the AST
+   * structure has not been resolved, or if the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType staticInvokeType;
+
+  /**
+   * Like [staticInvokeType], but reflects propagated type information.
+   */
+  DartType propagatedInvokeType;
+
+  /**
    * Initialize a newly created method invocation. The [target] and [operator]
    * can be `null` if there is no target.
    */
@@ -12290,26 +8185,6 @@
     _methodName = _becomeParentOf(identifier);
   }
 
-  /**
-   * The operator that separates the target from the method name, or `null`
-   * if there is no target. In an ordinary method invocation this will be a
-   * period ('.'). In a cascade section this will be the cascade operator
-   * ('..').
-   */
-  @deprecated // Use this.operator
-  Token get period => operator;
-
-  /**
-   * The operator that separates the target from the method name, or `null`
-   * if there is no target. In an ordinary method invocation this will be a
-   * period ('.'). In a cascade section this will be the cascade operator
-   * ('..').
-   */
-  @deprecated // Use this.operator
-  void set period(Token value) {
-    operator = value;
-  }
-
   @override
   int get precedence => 15;
 
@@ -12511,6 +8386,12 @@
   Token keyword;
 
   /**
+   * The configurations used to control which library will actually be loaded at
+   * run-time.
+   */
+  NodeList<Configuration> _configurations;
+
+  /**
    * The combinators used to control which names are imported or exported.
    */
   NodeList<Combinator> _combinators;
@@ -12526,9 +8407,16 @@
    * corresponding attribute. The list of [combinators] can be `null` if there
    * are no combinators.
    */
-  NamespaceDirective(Comment comment, List<Annotation> metadata, this.keyword,
-      StringLiteral libraryUri, List<Combinator> combinators, this.semicolon)
+  NamespaceDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      this.keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      List<Combinator> combinators,
+      this.semicolon)
       : super(comment, metadata, libraryUri) {
+    _configurations = new NodeList<Configuration>(this, configurations);
     _combinators = new NodeList<Combinator>(this, combinators);
   }
 
@@ -12537,6 +8425,12 @@
    */
   NodeList<Combinator> get combinators => _combinators;
 
+  /**
+   * Return the configurations used to control which library will actually be
+   * loaded at run-time.
+   */
+  NodeList<Configuration> get configurations => _configurations;
+
   @override
   Token get endToken => semicolon;
 
@@ -12582,20 +8476,6 @@
   Token get endToken => _name.endToken;
 
   /**
-   * Get the token representing the 'native' keyword.
-   */
-  @deprecated // Use "this.nativeKeyword"
-  Token get keyword => nativeKeyword;
-
-  /**
-   * Set the token representing the 'native' keyword to the given [token].
-   */
-  @deprecated // Use "this.nativeKeyword"
-  set keyword(Token token) {
-    nativeKeyword = token;
-  }
-
-  /**
    * Return the name of the native object that implements the class.
    */
   StringLiteral get name => _name;
@@ -12663,22 +8543,6 @@
   Token get endToken => semicolon;
 
   /**
-   * Return the token representing 'native' that marks the start of the function
-   * body.
-   */
-  @deprecated // Use "this.nativeKeyword"
-  Token get nativeToken => nativeKeyword;
-
-  /**
-   * Set the token representing 'native' that marks the start of the function
-   * body to the given [token].
-   */
-  @deprecated // Use "this.nativeKeyword"
-  set nativeToken(Token token) {
-    nativeKeyword = token;
-  }
-
-  /**
    * Return the string literal representing the string after the 'native' token.
    */
   StringLiteral get stringLiteral => _stringLiteral;
@@ -12749,7 +8613,8 @@
   int get length => _elements.length;
 
   @deprecated // Never intended for public use.
-  void set length(int value) {
+  @override
+  void set length(int newLength) {
     throw new UnsupportedError("Cannot resize NodeList.");
   }
 
@@ -12823,1298 +8688,6 @@
     _elements.removeAt(index);
     return removedNode;
   }
-
-  /**
-   * Create an empty list with the given [owner].
-   */
-  @deprecated // Use "new NodeList<E>(owner)"
-  static NodeList create(AstNode owner) => new NodeList(owner);
-}
-
-/**
- * An object used to locate the [AstNode] associated with a source range, given
- * the AST structure built from the source. More specifically, they will return
- * the [AstNode] with the shortest length whose source range completely
- * encompasses the specified range.
- */
-class NodeLocator extends UnifyingAstVisitor<Object> {
-  /**
-   * The start offset of the range used to identify the node.
-   */
-  int _startOffset = 0;
-
-  /**
-   * The end offset of the range used to identify the node.
-   */
-  int _endOffset = 0;
-
-  /**
-   * The element that was found that corresponds to the given source range, or
-   * `null` if there is no such element.
-   */
-  AstNode _foundNode;
-
-  /**
-   * Initialize a newly created locator to locate an [AstNode] by locating the
-   * node within an AST structure that corresponds to the given range of
-   * characters (between the [startOffset] and [endOffset] in the source.
-   */
-  NodeLocator(int startOffset, [int endOffset])
-      : this._startOffset = startOffset,
-        this._endOffset = endOffset == null ? startOffset : endOffset;
-
-  /**
-   * Initialize a newly created locator to locate an [AstNode] by locating the
-   * node within an AST structure that corresponds to the given [offset] in the
-   * source.
-   */
-  @deprecated // Use new NodeLocator(offset)
-  NodeLocator.con1(int offset) : this(offset);
-
-  /**
-   * Initialize a newly created locator to locate an [AstNode] by locating the
-   * node within an AST structure that corresponds to the given range of
-   * characters (between the [startOffset] and [endOffset] in the source.
-   */
-  @deprecated // Use new NodeLocator(startOffset, endOffset)
-  NodeLocator.con2(this._startOffset, this._endOffset);
-
-  /**
-   * Return the node that was found that corresponds to the given source range
-   * or `null` if there is no such node.
-   */
-  AstNode get foundNode => _foundNode;
-
-  /**
-   * Search within the given AST [node] for an identifier representing an
-   * element in the specified source range. Return the element that was found,
-   * or `null` if no element was found.
-   */
-  AstNode searchWithin(AstNode node) {
-    if (node == null) {
-      return null;
-    }
-    try {
-      node.accept(this);
-    } on NodeLocator_NodeFoundException {
-      // A node with the right source position was found.
-    } catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Unable to locate element at offset ($_startOffset - $_endOffset)",
-          new CaughtException(exception, stackTrace));
-      return null;
-    }
-    return _foundNode;
-  }
-
-  @override
-  Object visitNode(AstNode node) {
-    Token beginToken = node.beginToken;
-    Token endToken = node.endToken;
-    // Don't include synthetic tokens.
-    while (endToken != beginToken) {
-      if (endToken.type == TokenType.EOF || !endToken.isSynthetic) {
-        break;
-      }
-      endToken = endToken.previous;
-    }
-    int end = endToken.end;
-    int start = node.offset;
-    if (end < _startOffset) {
-      return null;
-    }
-    if (start > _endOffset) {
-      return null;
-    }
-    try {
-      node.visitChildren(this);
-    } on NodeLocator_NodeFoundException {
-      rethrow;
-    } catch (exception, stackTrace) {
-      // Ignore the exception and proceed in order to visit the rest of the
-      // structure.
-      AnalysisEngine.instance.logger.logInformation(
-          "Exception caught while traversing an AST structure.",
-          new CaughtException(exception, stackTrace));
-    }
-    if (start <= _startOffset && _endOffset <= end) {
-      _foundNode = node;
-      throw new NodeLocator_NodeFoundException();
-    }
-    return null;
-  }
-}
-
-/**
- * An exception used by [NodeLocator] to cancel visiting after a node has been
- * found.
- */
-class NodeLocator_NodeFoundException extends RuntimeException {}
-
-/**
- * An object that will replace one child node in an AST node with another node.
- */
-class NodeReplacer implements AstVisitor<bool> {
-  /**
-   * The node being replaced.
-   */
-  final AstNode _oldNode;
-
-  /**
-   * The node that is replacing the old node.
-   */
-  final AstNode _newNode;
-
-  /**
-   * Initialize a newly created node locator to replace the [_oldNode] with the
-   * [_newNode].
-   */
-  NodeReplacer(this._oldNode, this._newNode);
-
-  @override
-  bool visitAdjacentStrings(AdjacentStrings node) {
-    if (_replaceInList(node.strings)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  bool visitAnnotatedNode(AnnotatedNode node) {
-    if (identical(node.documentationComment, _oldNode)) {
-      node.documentationComment = _newNode as Comment;
-      return true;
-    } else if (_replaceInList(node.metadata)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitAnnotation(Annotation node) {
-    if (identical(node.arguments, _oldNode)) {
-      node.arguments = _newNode as ArgumentList;
-      return true;
-    } else if (identical(node.constructorName, _oldNode)) {
-      node.constructorName = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.name, _oldNode)) {
-      node.name = _newNode as Identifier;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitArgumentList(ArgumentList node) {
-    if (_replaceInList(node.arguments)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitAsExpression(AsExpression node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    } else if (identical(node.type, _oldNode)) {
-      node.type = _newNode as TypeName;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitAssertStatement(AssertStatement node) {
-    if (identical(node.condition, _oldNode)) {
-      node.condition = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitAssignmentExpression(AssignmentExpression node) {
-    if (identical(node.leftHandSide, _oldNode)) {
-      node.leftHandSide = _newNode as Expression;
-      return true;
-    } else if (identical(node.rightHandSide, _oldNode)) {
-      node.rightHandSide = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitAwaitExpression(AwaitExpression node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitBinaryExpression(BinaryExpression node) {
-    if (identical(node.leftOperand, _oldNode)) {
-      node.leftOperand = _newNode as Expression;
-      return true;
-    } else if (identical(node.rightOperand, _oldNode)) {
-      node.rightOperand = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitBlock(Block node) {
-    if (_replaceInList(node.statements)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitBlockFunctionBody(BlockFunctionBody node) {
-    if (identical(node.block, _oldNode)) {
-      node.block = _newNode as Block;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitBooleanLiteral(BooleanLiteral node) => visitNode(node);
-
-  @override
-  bool visitBreakStatement(BreakStatement node) {
-    if (identical(node.label, _oldNode)) {
-      node.label = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitCascadeExpression(CascadeExpression node) {
-    if (identical(node.target, _oldNode)) {
-      node.target = _newNode as Expression;
-      return true;
-    } else if (_replaceInList(node.cascadeSections)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitCatchClause(CatchClause node) {
-    if (identical(node.exceptionType, _oldNode)) {
-      node.exceptionType = _newNode as TypeName;
-      return true;
-    } else if (identical(node.exceptionParameter, _oldNode)) {
-      node.exceptionParameter = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.stackTraceParameter, _oldNode)) {
-      node.stackTraceParameter = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitClassDeclaration(ClassDeclaration node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.typeParameters, _oldNode)) {
-      node.typeParameters = _newNode as TypeParameterList;
-      return true;
-    } else if (identical(node.extendsClause, _oldNode)) {
-      node.extendsClause = _newNode as ExtendsClause;
-      return true;
-    } else if (identical(node.withClause, _oldNode)) {
-      node.withClause = _newNode as WithClause;
-      return true;
-    } else if (identical(node.implementsClause, _oldNode)) {
-      node.implementsClause = _newNode as ImplementsClause;
-      return true;
-    } else if (identical(node.nativeClause, _oldNode)) {
-      node.nativeClause = _newNode as NativeClause;
-      return true;
-    } else if (_replaceInList(node.members)) {
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitClassTypeAlias(ClassTypeAlias node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.typeParameters, _oldNode)) {
-      node.typeParameters = _newNode as TypeParameterList;
-      return true;
-    } else if (identical(node.superclass, _oldNode)) {
-      node.superclass = _newNode as TypeName;
-      return true;
-    } else if (identical(node.withClause, _oldNode)) {
-      node.withClause = _newNode as WithClause;
-      return true;
-    } else if (identical(node.implementsClause, _oldNode)) {
-      node.implementsClause = _newNode as ImplementsClause;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitComment(Comment node) {
-    if (_replaceInList(node.references)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitCommentReference(CommentReference node) {
-    if (identical(node.identifier, _oldNode)) {
-      node.identifier = _newNode as Identifier;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitCompilationUnit(CompilationUnit node) {
-    if (identical(node.scriptTag, _oldNode)) {
-      node.scriptTag = _newNode as ScriptTag;
-      return true;
-    } else if (_replaceInList(node.directives)) {
-      return true;
-    } else if (_replaceInList(node.declarations)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitConditionalExpression(ConditionalExpression node) {
-    if (identical(node.condition, _oldNode)) {
-      node.condition = _newNode as Expression;
-      return true;
-    } else if (identical(node.thenExpression, _oldNode)) {
-      node.thenExpression = _newNode as Expression;
-      return true;
-    } else if (identical(node.elseExpression, _oldNode)) {
-      node.elseExpression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitConstructorDeclaration(ConstructorDeclaration node) {
-    if (identical(node.returnType, _oldNode)) {
-      node.returnType = _newNode as Identifier;
-      return true;
-    } else if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.parameters, _oldNode)) {
-      node.parameters = _newNode as FormalParameterList;
-      return true;
-    } else if (identical(node.redirectedConstructor, _oldNode)) {
-      node.redirectedConstructor = _newNode as ConstructorName;
-      return true;
-    } else if (identical(node.body, _oldNode)) {
-      node.body = _newNode as FunctionBody;
-      return true;
-    } else if (_replaceInList(node.initializers)) {
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    if (identical(node.fieldName, _oldNode)) {
-      node.fieldName = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitConstructorName(ConstructorName node) {
-    if (identical(node.type, _oldNode)) {
-      node.type = _newNode as TypeName;
-      return true;
-    } else if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitContinueStatement(ContinueStatement node) {
-    if (identical(node.label, _oldNode)) {
-      node.label = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitDeclaredIdentifier(DeclaredIdentifier node) {
-    if (identical(node.type, _oldNode)) {
-      node.type = _newNode as TypeName;
-      return true;
-    } else if (identical(node.identifier, _oldNode)) {
-      node.identifier = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitDefaultFormalParameter(DefaultFormalParameter node) {
-    if (identical(node.parameter, _oldNode)) {
-      node.parameter = _newNode as NormalFormalParameter;
-      return true;
-    } else if (identical(node.defaultValue, _oldNode)) {
-      node.defaultValue = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitDoStatement(DoStatement node) {
-    if (identical(node.body, _oldNode)) {
-      node.body = _newNode as Statement;
-      return true;
-    } else if (identical(node.condition, _oldNode)) {
-      node.condition = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitDoubleLiteral(DoubleLiteral node) => visitNode(node);
-
-  @override
-  bool visitEmptyFunctionBody(EmptyFunctionBody node) => visitNode(node);
-
-  @override
-  bool visitEmptyStatement(EmptyStatement node) => visitNode(node);
-
-  @override
-  bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitEnumDeclaration(EnumDeclaration node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    } else if (_replaceInList(node.constants)) {
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitExportDirective(ExportDirective node) =>
-      visitNamespaceDirective(node);
-
-  @override
-  bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitExpressionStatement(ExpressionStatement node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitExtendsClause(ExtendsClause node) {
-    if (identical(node.superclass, _oldNode)) {
-      node.superclass = _newNode as TypeName;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitFieldDeclaration(FieldDeclaration node) {
-    if (identical(node.fields, _oldNode)) {
-      node.fields = _newNode as VariableDeclarationList;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitFieldFormalParameter(FieldFormalParameter node) {
-    if (identical(node.type, _oldNode)) {
-      node.type = _newNode as TypeName;
-      return true;
-    } else if (identical(node.parameters, _oldNode)) {
-      node.parameters = _newNode as FormalParameterList;
-      return true;
-    }
-    return visitNormalFormalParameter(node);
-  }
-
-  @override
-  bool visitForEachStatement(ForEachStatement node) {
-    if (identical(node.loopVariable, _oldNode)) {
-      node.loopVariable = _newNode as DeclaredIdentifier;
-      return true;
-    } else if (identical(node.identifier, _oldNode)) {
-      node.identifier = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.iterable, _oldNode)) {
-      node.iterable = _newNode as Expression;
-      return true;
-    } else if (identical(node.body, _oldNode)) {
-      node.body = _newNode as Statement;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitFormalParameterList(FormalParameterList node) {
-    if (_replaceInList(node.parameters)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitForStatement(ForStatement node) {
-    if (identical(node.variables, _oldNode)) {
-      node.variables = _newNode as VariableDeclarationList;
-      return true;
-    } else if (identical(node.initialization, _oldNode)) {
-      node.initialization = _newNode as Expression;
-      return true;
-    } else if (identical(node.condition, _oldNode)) {
-      node.condition = _newNode as Expression;
-      return true;
-    } else if (identical(node.body, _oldNode)) {
-      node.body = _newNode as Statement;
-      return true;
-    } else if (_replaceInList(node.updaters)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitFunctionDeclaration(FunctionDeclaration node) {
-    if (identical(node.returnType, _oldNode)) {
-      node.returnType = _newNode as TypeName;
-      return true;
-    } else if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.functionExpression, _oldNode)) {
-      node.functionExpression = _newNode as FunctionExpression;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
-    if (identical(node.functionDeclaration, _oldNode)) {
-      node.functionDeclaration = _newNode as FunctionDeclaration;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitFunctionExpression(FunctionExpression node) {
-    if (identical(node.parameters, _oldNode)) {
-      node.parameters = _newNode as FormalParameterList;
-      return true;
-    } else if (identical(node.body, _oldNode)) {
-      node.body = _newNode as FunctionBody;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    if (identical(node.function, _oldNode)) {
-      node.function = _newNode as Expression;
-      return true;
-    } else if (identical(node.argumentList, _oldNode)) {
-      node.argumentList = _newNode as ArgumentList;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitFunctionTypeAlias(FunctionTypeAlias node) {
-    if (identical(node.returnType, _oldNode)) {
-      node.returnType = _newNode as TypeName;
-      return true;
-    } else if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.typeParameters, _oldNode)) {
-      node.typeParameters = _newNode as TypeParameterList;
-      return true;
-    } else if (identical(node.parameters, _oldNode)) {
-      node.parameters = _newNode as FormalParameterList;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    if (identical(node.returnType, _oldNode)) {
-      node.returnType = _newNode as TypeName;
-      return true;
-    } else if (identical(node.parameters, _oldNode)) {
-      node.parameters = _newNode as FormalParameterList;
-      return true;
-    }
-    return visitNormalFormalParameter(node);
-  }
-
-  @override
-  bool visitHideCombinator(HideCombinator node) {
-    if (_replaceInList(node.hiddenNames)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitIfStatement(IfStatement node) {
-    if (identical(node.condition, _oldNode)) {
-      node.condition = _newNode as Expression;
-      return true;
-    } else if (identical(node.thenStatement, _oldNode)) {
-      node.thenStatement = _newNode as Statement;
-      return true;
-    } else if (identical(node.elseStatement, _oldNode)) {
-      node.elseStatement = _newNode as Statement;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitImplementsClause(ImplementsClause node) {
-    if (_replaceInList(node.interfaces)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitImportDirective(ImportDirective node) {
-    if (identical(node.prefix, _oldNode)) {
-      node.prefix = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitNamespaceDirective(node);
-  }
-
-  @override
-  bool visitIndexExpression(IndexExpression node) {
-    if (identical(node.target, _oldNode)) {
-      node.target = _newNode as Expression;
-      return true;
-    } else if (identical(node.index, _oldNode)) {
-      node.index = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitInstanceCreationExpression(InstanceCreationExpression node) {
-    if (identical(node.constructorName, _oldNode)) {
-      node.constructorName = _newNode as ConstructorName;
-      return true;
-    } else if (identical(node.argumentList, _oldNode)) {
-      node.argumentList = _newNode as ArgumentList;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitIntegerLiteral(IntegerLiteral node) => visitNode(node);
-
-  @override
-  bool visitInterpolationExpression(InterpolationExpression node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitInterpolationString(InterpolationString node) => visitNode(node);
-
-  @override
-  bool visitIsExpression(IsExpression node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    } else if (identical(node.type, _oldNode)) {
-      node.type = _newNode as TypeName;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitLabel(Label node) {
-    if (identical(node.label, _oldNode)) {
-      node.label = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitLabeledStatement(LabeledStatement node) {
-    if (identical(node.statement, _oldNode)) {
-      node.statement = _newNode as Statement;
-      return true;
-    } else if (_replaceInList(node.labels)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitLibraryDirective(LibraryDirective node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as LibraryIdentifier;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitLibraryIdentifier(LibraryIdentifier node) {
-    if (_replaceInList(node.components)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitListLiteral(ListLiteral node) {
-    if (_replaceInList(node.elements)) {
-      return true;
-    }
-    return visitTypedLiteral(node);
-  }
-
-  @override
-  bool visitMapLiteral(MapLiteral node) {
-    if (_replaceInList(node.entries)) {
-      return true;
-    }
-    return visitTypedLiteral(node);
-  }
-
-  @override
-  bool visitMapLiteralEntry(MapLiteralEntry node) {
-    if (identical(node.key, _oldNode)) {
-      node.key = _newNode as Expression;
-      return true;
-    } else if (identical(node.value, _oldNode)) {
-      node.value = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitMethodDeclaration(MethodDeclaration node) {
-    if (identical(node.returnType, _oldNode)) {
-      node.returnType = _newNode as TypeName;
-      return true;
-    } else if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.parameters, _oldNode)) {
-      node.parameters = _newNode as FormalParameterList;
-      return true;
-    } else if (identical(node.body, _oldNode)) {
-      node.body = _newNode as FunctionBody;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitMethodInvocation(MethodInvocation node) {
-    if (identical(node.target, _oldNode)) {
-      node.target = _newNode as Expression;
-      return true;
-    } else if (identical(node.methodName, _oldNode)) {
-      node.methodName = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.argumentList, _oldNode)) {
-      node.argumentList = _newNode as ArgumentList;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitNamedExpression(NamedExpression node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as Label;
-      return true;
-    } else if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  bool visitNamespaceDirective(NamespaceDirective node) {
-    if (_replaceInList(node.combinators)) {
-      return true;
-    }
-    return visitUriBasedDirective(node);
-  }
-
-  @override
-  bool visitNativeClause(NativeClause node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as StringLiteral;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitNativeFunctionBody(NativeFunctionBody node) {
-    if (identical(node.stringLiteral, _oldNode)) {
-      node.stringLiteral = _newNode as StringLiteral;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  bool visitNode(AstNode node) {
-    throw new IllegalArgumentException(
-        "The old node is not a child of it's parent");
-  }
-
-  bool visitNormalFormalParameter(NormalFormalParameter node) {
-    if (identical(node.documentationComment, _oldNode)) {
-      node.documentationComment = _newNode as Comment;
-      return true;
-    } else if (identical(node.identifier, _oldNode)) {
-      node.identifier = _newNode as SimpleIdentifier;
-      return true;
-    } else if (_replaceInList(node.metadata)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitNullLiteral(NullLiteral node) => visitNode(node);
-
-  @override
-  bool visitParenthesizedExpression(ParenthesizedExpression node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitPartDirective(PartDirective node) => visitUriBasedDirective(node);
-
-  @override
-  bool visitPartOfDirective(PartOfDirective node) {
-    if (identical(node.libraryName, _oldNode)) {
-      node.libraryName = _newNode as LibraryIdentifier;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitPostfixExpression(PostfixExpression node) {
-    if (identical(node.operand, _oldNode)) {
-      node.operand = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitPrefixedIdentifier(PrefixedIdentifier node) {
-    if (identical(node.prefix, _oldNode)) {
-      node.prefix = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.identifier, _oldNode)) {
-      node.identifier = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitPrefixExpression(PrefixExpression node) {
-    if (identical(node.operand, _oldNode)) {
-      node.operand = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitPropertyAccess(PropertyAccess node) {
-    if (identical(node.target, _oldNode)) {
-      node.target = _newNode as Expression;
-      return true;
-    } else if (identical(node.propertyName, _oldNode)) {
-      node.propertyName = _newNode as SimpleIdentifier;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    if (identical(node.constructorName, _oldNode)) {
-      node.constructorName = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.argumentList, _oldNode)) {
-      node.argumentList = _newNode as ArgumentList;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitRethrowExpression(RethrowExpression node) => visitNode(node);
-
-  @override
-  bool visitReturnStatement(ReturnStatement node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
-
-  @override
-  bool visitShowCombinator(ShowCombinator node) {
-    if (_replaceInList(node.shownNames)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitSimpleFormalParameter(SimpleFormalParameter node) {
-    if (identical(node.type, _oldNode)) {
-      node.type = _newNode as TypeName;
-      return true;
-    }
-    return visitNormalFormalParameter(node);
-  }
-
-  @override
-  bool visitSimpleIdentifier(SimpleIdentifier node) => visitNode(node);
-
-  @override
-  bool visitSimpleStringLiteral(SimpleStringLiteral node) => visitNode(node);
-
-  @override
-  bool visitStringInterpolation(StringInterpolation node) {
-    if (_replaceInList(node.elements)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    if (identical(node.constructorName, _oldNode)) {
-      node.constructorName = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.argumentList, _oldNode)) {
-      node.argumentList = _newNode as ArgumentList;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitSuperExpression(SuperExpression node) => visitNode(node);
-
-  @override
-  bool visitSwitchCase(SwitchCase node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitSwitchMember(node);
-  }
-
-  @override
-  bool visitSwitchDefault(SwitchDefault node) => visitSwitchMember(node);
-
-  bool visitSwitchMember(SwitchMember node) {
-    if (_replaceInList(node.labels)) {
-      return true;
-    } else if (_replaceInList(node.statements)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitSwitchStatement(SwitchStatement node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    } else if (_replaceInList(node.members)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitSymbolLiteral(SymbolLiteral node) => visitNode(node);
-
-  @override
-  bool visitThisExpression(ThisExpression node) => visitNode(node);
-
-  @override
-  bool visitThrowExpression(ThrowExpression node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    if (identical(node.variables, _oldNode)) {
-      node.variables = _newNode as VariableDeclarationList;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitTryStatement(TryStatement node) {
-    if (identical(node.body, _oldNode)) {
-      node.body = _newNode as Block;
-      return true;
-    } else if (identical(node.finallyBlock, _oldNode)) {
-      node.finallyBlock = _newNode as Block;
-      return true;
-    } else if (_replaceInList(node.catchClauses)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitTypeArgumentList(TypeArgumentList node) {
-    if (_replaceInList(node.arguments)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  bool visitTypedLiteral(TypedLiteral node) {
-    if (identical(node.typeArguments, _oldNode)) {
-      node.typeArguments = _newNode as TypeArgumentList;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitTypeName(TypeName node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as Identifier;
-      return true;
-    } else if (identical(node.typeArguments, _oldNode)) {
-      node.typeArguments = _newNode as TypeArgumentList;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitTypeParameter(TypeParameter node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.bound, _oldNode)) {
-      node.bound = _newNode as TypeName;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitTypeParameterList(TypeParameterList node) {
-    if (_replaceInList(node.typeParameters)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  bool visitUriBasedDirective(UriBasedDirective node) {
-    if (identical(node.uri, _oldNode)) {
-      node.uri = _newNode as StringLiteral;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitVariableDeclaration(VariableDeclaration node) {
-    if (identical(node.name, _oldNode)) {
-      node.name = _newNode as SimpleIdentifier;
-      return true;
-    } else if (identical(node.initializer, _oldNode)) {
-      node.initializer = _newNode as Expression;
-      return true;
-    }
-    return visitAnnotatedNode(node);
-  }
-
-  @override
-  bool visitVariableDeclarationList(VariableDeclarationList node) {
-    if (identical(node.type, _oldNode)) {
-      node.type = _newNode as TypeName;
-      return true;
-    } else if (_replaceInList(node.variables)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    if (identical(node.variables, _oldNode)) {
-      node.variables = _newNode as VariableDeclarationList;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitWhileStatement(WhileStatement node) {
-    if (identical(node.condition, _oldNode)) {
-      node.condition = _newNode as Expression;
-      return true;
-    } else if (identical(node.body, _oldNode)) {
-      node.body = _newNode as Statement;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitWithClause(WithClause node) {
-    if (_replaceInList(node.mixinTypes)) {
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitYieldStatement(YieldStatement node) {
-    if (identical(node.expression, _oldNode)) {
-      node.expression = _newNode as Expression;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  bool _replaceInList(NodeList list) {
-    int count = list.length;
-    for (int i = 0; i < count; i++) {
-      if (identical(_oldNode, list[i])) {
-        list[i] = _newNode;
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Replace the [oldNode] with the [newNode] in the AST structure containing
-   * the old node. Return `true` if the replacement was successful.
-   *
-   * Throws an [IllegalArgumentException] if either node is `null`, if the old
-   * node does not have a parent node, or if the AST structure has been
-   * corrupted.
-   */
-  static bool replace(AstNode oldNode, AstNode newNode) {
-    if (oldNode == null || newNode == null) {
-      throw new IllegalArgumentException(
-          "The old and new nodes must be non-null");
-    } else if (identical(oldNode, newNode)) {
-      return true;
-    }
-    AstNode parent = oldNode.parent;
-    if (parent == null) {
-      throw new IllegalArgumentException(
-          "The old node is not a child of another node");
-    }
-    NodeReplacer replacer = new NodeReplacer(oldNode, newNode);
-    return parent.accept(replacer);
-  }
 }
 
 /**
@@ -14389,20 +8962,6 @@
   @override
   Token get keyword => partKeyword;
 
-  /**
-   * Return the token representing the 'part' token.
-   */
-  @deprecated // Use "this.partKeyword"
-  Token get partToken => partKeyword;
-
-  /**
-   * Set the token representing the 'part' token to the given [token].
-   */
-  @deprecated // Use "this.partKeyword"
-  set partToken(Token token) {
-    partKeyword = token;
-  }
-
   @override
   CompilationUnitElement get uriElement => element as CompilationUnitElement;
 
@@ -14478,34 +9037,6 @@
     _libraryName = _becomeParentOf(libraryName);
   }
 
-  /**
-   * Return the token representing the 'of' token.
-   */
-  @deprecated // Use "this.ofKeyword"
-  Token get ofToken => ofKeyword;
-
-  /**
-   * Set the token representing the 'of' token to the given [token].
-   */
-  @deprecated // Use "this.ofKeyword"
-  set ofToken(Token token) {
-    ofKeyword = token;
-  }
-
-  /**
-   * Return the token representing the 'part' token.
-   */
-  @deprecated // Use "this.partKeyword"
-  Token get partToken => partKeyword;
-
-  /**
-   * Set the token representing the 'part' token to the given [token].
-   */
-  @deprecated // Use "this.partKeyword"
-  set partToken(Token token) {
-    partKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitPartOfDirective(this);
 
@@ -14602,28 +9133,6 @@
    * element representing the parameter to which the value of the operand will
    * be bound. Otherwise, return `null`.
    */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForOperand {
-    return _propagatedParameterElementForOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the operand will be bound.
-   * Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get staticParameterElementForOperand {
-    return _staticParameterElementForOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the operand will
-   * be bound. Otherwise, return `null`.
-   */
   ParameterElement get _propagatedParameterElementForOperand {
     if (propagatedElement == null) {
       return null;
@@ -14875,28 +9384,6 @@
    * element representing the parameter to which the value of the operand will
    * be bound. Otherwise, return `null`.
    */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForOperand {
-    return _propagatedParameterElementForOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the operand will be bound.
-   * Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get staticParameterElementForOperand {
-    return _staticParameterElementForOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the operand will
-   * be bound. Otherwise, return `null`.
-   */
   ParameterElement get _propagatedParameterElementForOperand {
     if (propagatedElement == null) {
       return null;
@@ -15058,655 +9545,6 @@
 }
 
 /**
- * An AST visitor that will recursively visit all of the nodes in an AST
- * structure. For example, using an instance of this class to visit a [Block]
- * will also cause all of the statements in the block to be visited.
- *
- * Subclasses that override a visit method must either invoke the overridden
- * visit method or must explicitly ask the visited node to visit its children.
- * Failure to do so will cause the children of the visited node to not be
- * visited.
- */
-class RecursiveAstVisitor<R> implements AstVisitor<R> {
-  @override
-  R visitAdjacentStrings(AdjacentStrings node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitAnnotation(Annotation node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitArgumentList(ArgumentList node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitAsExpression(AsExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitAssertStatement(AssertStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitAssignmentExpression(AssignmentExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitAwaitExpression(AwaitExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitBinaryExpression(BinaryExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitBlock(Block node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitBlockFunctionBody(BlockFunctionBody node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitBooleanLiteral(BooleanLiteral node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitBreakStatement(BreakStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitCascadeExpression(CascadeExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitCatchClause(CatchClause node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitClassDeclaration(ClassDeclaration node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitClassTypeAlias(ClassTypeAlias node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitComment(Comment node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitCommentReference(CommentReference node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitCompilationUnit(CompilationUnit node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitConditionalExpression(ConditionalExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitConstructorDeclaration(ConstructorDeclaration node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitConstructorName(ConstructorName node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitContinueStatement(ContinueStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitDeclaredIdentifier(DeclaredIdentifier node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitDefaultFormalParameter(DefaultFormalParameter node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitDoStatement(DoStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitDoubleLiteral(DoubleLiteral node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitEmptyFunctionBody(EmptyFunctionBody node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitEmptyStatement(EmptyStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitEnumDeclaration(EnumDeclaration node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitExportDirective(ExportDirective node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitExpressionStatement(ExpressionStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitExtendsClause(ExtendsClause node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFieldDeclaration(FieldDeclaration node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFieldFormalParameter(FieldFormalParameter node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitForEachStatement(ForEachStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFormalParameterList(FormalParameterList node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitForStatement(ForStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionDeclaration(FunctionDeclaration node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionExpression(FunctionExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionTypeAlias(FunctionTypeAlias node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitHideCombinator(HideCombinator node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitIfStatement(IfStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitImplementsClause(ImplementsClause node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitImportDirective(ImportDirective node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitIndexExpression(IndexExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitInstanceCreationExpression(InstanceCreationExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitIntegerLiteral(IntegerLiteral node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitInterpolationExpression(InterpolationExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitInterpolationString(InterpolationString node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitIsExpression(IsExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLabel(Label node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLabeledStatement(LabeledStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLibraryDirective(LibraryDirective node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLibraryIdentifier(LibraryIdentifier node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitListLiteral(ListLiteral node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitMapLiteral(MapLiteral node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitMapLiteralEntry(MapLiteralEntry node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitMethodDeclaration(MethodDeclaration node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitMethodInvocation(MethodInvocation node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitNamedExpression(NamedExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitNativeClause(NativeClause node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitNativeFunctionBody(NativeFunctionBody node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitNullLiteral(NullLiteral node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitParenthesizedExpression(ParenthesizedExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPartDirective(PartDirective node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPartOfDirective(PartOfDirective node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPostfixExpression(PostfixExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPrefixedIdentifier(PrefixedIdentifier node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPrefixExpression(PrefixExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPropertyAccess(PropertyAccess node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitRethrowExpression(RethrowExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitReturnStatement(ReturnStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitScriptTag(ScriptTag node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitShowCombinator(ShowCombinator node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitSimpleFormalParameter(SimpleFormalParameter node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitSimpleIdentifier(SimpleIdentifier node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitSimpleStringLiteral(SimpleStringLiteral node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitStringInterpolation(StringInterpolation node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitSuperExpression(SuperExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitSwitchCase(SwitchCase node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitSwitchDefault(SwitchDefault node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitSwitchStatement(SwitchStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitSymbolLiteral(SymbolLiteral node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitThisExpression(ThisExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitThrowExpression(ThrowExpression node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTryStatement(TryStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTypeArgumentList(TypeArgumentList node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTypeName(TypeName node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTypeParameter(TypeParameter node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTypeParameterList(TypeParameterList node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitVariableDeclaration(VariableDeclaration node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitVariableDeclarationList(VariableDeclarationList node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitWhileStatement(WhileStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitWithClause(WithClause node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitYieldStatement(YieldStatement node) {
-    node.visitChildren(this);
-    return null;
-  }
-}
-
-/**
  * The invocation of a constructor in the same class from within a constructor's
  * initialization list.
  *
@@ -15793,20 +9631,6 @@
   @override
   Token get endToken => _argumentList.endToken;
 
-  /**
-   * Return the token for the 'this' keyword.
-   */
-  @deprecated // Use "this.thisKeyword"
-  Token get keyword => thisKeyword;
-
-  /**
-   * Set the token for the 'this' keyword to the given [token].
-   */
-  @deprecated // Use "this.thisKeyword"
-  set keyword(Token token) {
-    thisKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) =>
       visitor.visitRedirectingConstructorInvocation(this);
@@ -15844,20 +9668,6 @@
   @override
   Token get endToken => rethrowKeyword;
 
-  /**
-   * Return the token representing the 'rethrow' keyword.
-   */
-  @deprecated // Use "this.rethrowKeyword"
-  Token get keyword => rethrowKeyword;
-
-  /**
-   * Set the token representing the 'rethrow' keyword to the given [token].
-   */
-  @deprecated // Use "this.rethrowKeyword"
-  set keyword(Token token) {
-    rethrowKeyword = token;
-  }
-
   @override
   int get precedence => 0;
 
@@ -15925,20 +9735,6 @@
     _expression = _becomeParentOf(expression);
   }
 
-  /**
-   * Return the token representing the 'return' keyword.
-   */
-  @deprecated // Use "this.returnKeyword"
-  Token get keyword => returnKeyword;
-
-  /**
-   * Set the token representing the 'return' keyword to the given [token].
-   */
-  @deprecated // Use "this.returnKeyword"
-  set keyword(Token token) {
-    returnKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitReturnStatement(this);
 
@@ -15949,191 +9745,6 @@
 }
 
 /**
- * Traverse the AST from initial child node to successive parents, building a
- * collection of local variable and parameter names visible to the initial child
- * node. In case of name shadowing, the first name seen is the most specific one
- * so names are not redefined.
- *
- * Completion test code coverage is 95%. The two basic blocks that are not
- * executed cannot be executed. They are included for future reference.
- */
-class ScopedNameFinder extends GeneralizingAstVisitor<Object> {
-  Declaration _declarationNode;
-
-  AstNode _immediateChild;
-
-  Map<String, SimpleIdentifier> _locals =
-      new HashMap<String, SimpleIdentifier>();
-
-  final int _position;
-
-  bool _referenceIsWithinLocalFunction = false;
-
-  ScopedNameFinder(this._position);
-
-  Declaration get declaration => _declarationNode;
-
-  Map<String, SimpleIdentifier> get locals => _locals;
-
-  @override
-  Object visitBlock(Block node) {
-    _checkStatements(node.statements);
-    return super.visitBlock(node);
-  }
-
-  @override
-  Object visitCatchClause(CatchClause node) {
-    _addToScope(node.exceptionParameter);
-    _addToScope(node.stackTraceParameter);
-    return super.visitCatchClause(node);
-  }
-
-  @override
-  Object visitConstructorDeclaration(ConstructorDeclaration node) {
-    if (!identical(_immediateChild, node.parameters)) {
-      _addParameters(node.parameters.parameters);
-    }
-    _declarationNode = node;
-    return null;
-  }
-
-  @override
-  Object visitFieldDeclaration(FieldDeclaration node) {
-    _declarationNode = node;
-    return null;
-  }
-
-  @override
-  Object visitForEachStatement(ForEachStatement node) {
-    DeclaredIdentifier loopVariable = node.loopVariable;
-    if (loopVariable != null) {
-      _addToScope(loopVariable.identifier);
-    }
-    return super.visitForEachStatement(node);
-  }
-
-  @override
-  Object visitForStatement(ForStatement node) {
-    if (!identical(_immediateChild, node.variables) && node.variables != null) {
-      _addVariables(node.variables.variables);
-    }
-    return super.visitForStatement(node);
-  }
-
-  @override
-  Object visitFunctionDeclaration(FunctionDeclaration node) {
-    if (node.parent is! FunctionDeclarationStatement) {
-      _declarationNode = node;
-      return null;
-    }
-    return super.visitFunctionDeclaration(node);
-  }
-
-  @override
-  Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
-    _referenceIsWithinLocalFunction = true;
-    return super.visitFunctionDeclarationStatement(node);
-  }
-
-  @override
-  Object visitFunctionExpression(FunctionExpression node) {
-    if (node.parameters != null &&
-        !identical(_immediateChild, node.parameters)) {
-      _addParameters(node.parameters.parameters);
-    }
-    return super.visitFunctionExpression(node);
-  }
-
-  @override
-  Object visitMethodDeclaration(MethodDeclaration node) {
-    _declarationNode = node;
-    if (node.parameters == null) {
-      return null;
-    }
-    if (!identical(_immediateChild, node.parameters)) {
-      _addParameters(node.parameters.parameters);
-    }
-    return null;
-  }
-
-  @override
-  Object visitNode(AstNode node) {
-    _immediateChild = node;
-    AstNode parent = node.parent;
-    if (parent != null) {
-      parent.accept(this);
-    }
-    return null;
-  }
-
-  @override
-  Object visitSwitchMember(SwitchMember node) {
-    _checkStatements(node.statements);
-    return super.visitSwitchMember(node);
-  }
-
-  @override
-  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    _declarationNode = node;
-    return null;
-  }
-
-  @override
-  Object visitTypeAlias(TypeAlias node) {
-    _declarationNode = node;
-    return null;
-  }
-
-  void _addParameters(NodeList<FormalParameter> vars) {
-    for (FormalParameter var2 in vars) {
-      _addToScope(var2.identifier);
-    }
-  }
-
-  void _addToScope(SimpleIdentifier identifier) {
-    if (identifier != null && _isInRange(identifier)) {
-      String name = identifier.name;
-      if (!_locals.containsKey(name)) {
-        _locals[name] = identifier;
-      }
-    }
-  }
-
-  void _addVariables(NodeList<VariableDeclaration> variables) {
-    for (VariableDeclaration variable in variables) {
-      _addToScope(variable.name);
-    }
-  }
-
-  /**
-   * Check the given list of [statements] for any that come before the immediate
-   * child and that define a name that would be visible to the immediate child.
-   */
-  void _checkStatements(List<Statement> statements) {
-    for (Statement statement in statements) {
-      if (identical(statement, _immediateChild)) {
-        return;
-      }
-      if (statement is VariableDeclarationStatement) {
-        _addVariables(statement.variables.variables);
-      } else if (statement is FunctionDeclarationStatement &&
-          !_referenceIsWithinLocalFunction) {
-        _addToScope(statement.functionDeclaration.name);
-      }
-    }
-  }
-
-  bool _isInRange(AstNode node) {
-    if (_position < 0) {
-      // if source position is not set then all nodes are in range
-      return true;
-      // not reached
-    }
-    return node.end < _position;
-  }
-}
-
-/**
  * A script tag that can optionally occur at the beginning of a compilation unit.
  *
  * > scriptTag ::=
@@ -16213,338 +9824,6 @@
 }
 
 /**
- * An AST visitor that will do nothing when visiting an AST node. It is intended
- * to be a superclass for classes that use the visitor pattern primarily as a
- * dispatch mechanism (and hence don't need to recursively visit a whole
- * structure) and that only need to visit a small number of node types.
- */
-class SimpleAstVisitor<R> implements AstVisitor<R> {
-  @override
-  R visitAdjacentStrings(AdjacentStrings node) => null;
-
-  @override
-  R visitAnnotation(Annotation node) => null;
-
-  @override
-  R visitArgumentList(ArgumentList node) => null;
-
-  @override
-  R visitAsExpression(AsExpression node) => null;
-
-  @override
-  R visitAssertStatement(AssertStatement node) => null;
-
-  @override
-  R visitAssignmentExpression(AssignmentExpression node) => null;
-
-  @override
-  R visitAwaitExpression(AwaitExpression node) => null;
-
-  @override
-  R visitBinaryExpression(BinaryExpression node) => null;
-
-  @override
-  R visitBlock(Block node) => null;
-
-  @override
-  R visitBlockFunctionBody(BlockFunctionBody node) => null;
-
-  @override
-  R visitBooleanLiteral(BooleanLiteral node) => null;
-
-  @override
-  R visitBreakStatement(BreakStatement node) => null;
-
-  @override
-  R visitCascadeExpression(CascadeExpression node) => null;
-
-  @override
-  R visitCatchClause(CatchClause node) => null;
-
-  @override
-  R visitClassDeclaration(ClassDeclaration node) => null;
-
-  @override
-  R visitClassTypeAlias(ClassTypeAlias node) => null;
-
-  @override
-  R visitComment(Comment node) => null;
-
-  @override
-  R visitCommentReference(CommentReference node) => null;
-
-  @override
-  R visitCompilationUnit(CompilationUnit node) => null;
-
-  @override
-  R visitConditionalExpression(ConditionalExpression node) => null;
-
-  @override
-  R visitConstructorDeclaration(ConstructorDeclaration node) => null;
-
-  @override
-  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) => null;
-
-  @override
-  R visitConstructorName(ConstructorName node) => null;
-
-  @override
-  R visitContinueStatement(ContinueStatement node) => null;
-
-  @override
-  R visitDeclaredIdentifier(DeclaredIdentifier node) => null;
-
-  @override
-  R visitDefaultFormalParameter(DefaultFormalParameter node) => null;
-
-  @override
-  R visitDoStatement(DoStatement node) => null;
-
-  @override
-  R visitDoubleLiteral(DoubleLiteral node) => null;
-
-  @override
-  R visitEmptyFunctionBody(EmptyFunctionBody node) => null;
-
-  @override
-  R visitEmptyStatement(EmptyStatement node) => null;
-
-  @override
-  R visitEnumConstantDeclaration(EnumConstantDeclaration node) => null;
-
-  @override
-  R visitEnumDeclaration(EnumDeclaration node) => null;
-
-  @override
-  R visitExportDirective(ExportDirective node) => null;
-
-  @override
-  R visitExpressionFunctionBody(ExpressionFunctionBody node) => null;
-
-  @override
-  R visitExpressionStatement(ExpressionStatement node) => null;
-
-  @override
-  R visitExtendsClause(ExtendsClause node) => null;
-
-  @override
-  R visitFieldDeclaration(FieldDeclaration node) => null;
-
-  @override
-  R visitFieldFormalParameter(FieldFormalParameter node) => null;
-
-  @override
-  R visitForEachStatement(ForEachStatement node) => null;
-
-  @override
-  R visitFormalParameterList(FormalParameterList node) => null;
-
-  @override
-  R visitForStatement(ForStatement node) => null;
-
-  @override
-  R visitFunctionDeclaration(FunctionDeclaration node) => null;
-
-  @override
-  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) =>
-      null;
-
-  @override
-  R visitFunctionExpression(FunctionExpression node) => null;
-
-  @override
-  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) =>
-      null;
-
-  @override
-  R visitFunctionTypeAlias(FunctionTypeAlias node) => null;
-
-  @override
-  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) =>
-      null;
-
-  @override
-  R visitHideCombinator(HideCombinator node) => null;
-
-  @override
-  R visitIfStatement(IfStatement node) => null;
-
-  @override
-  R visitImplementsClause(ImplementsClause node) => null;
-
-  @override
-  R visitImportDirective(ImportDirective node) => null;
-
-  @override
-  R visitIndexExpression(IndexExpression node) => null;
-
-  @override
-  R visitInstanceCreationExpression(InstanceCreationExpression node) => null;
-
-  @override
-  R visitIntegerLiteral(IntegerLiteral node) => null;
-
-  @override
-  R visitInterpolationExpression(InterpolationExpression node) => null;
-
-  @override
-  R visitInterpolationString(InterpolationString node) => null;
-
-  @override
-  R visitIsExpression(IsExpression node) => null;
-
-  @override
-  R visitLabel(Label node) => null;
-
-  @override
-  R visitLabeledStatement(LabeledStatement node) => null;
-
-  @override
-  R visitLibraryDirective(LibraryDirective node) => null;
-
-  @override
-  R visitLibraryIdentifier(LibraryIdentifier node) => null;
-
-  @override
-  R visitListLiteral(ListLiteral node) => null;
-
-  @override
-  R visitMapLiteral(MapLiteral node) => null;
-
-  @override
-  R visitMapLiteralEntry(MapLiteralEntry node) => null;
-
-  @override
-  R visitMethodDeclaration(MethodDeclaration node) => null;
-
-  @override
-  R visitMethodInvocation(MethodInvocation node) => null;
-
-  @override
-  R visitNamedExpression(NamedExpression node) => null;
-
-  @override
-  R visitNativeClause(NativeClause node) => null;
-
-  @override
-  R visitNativeFunctionBody(NativeFunctionBody node) => null;
-
-  @override
-  R visitNullLiteral(NullLiteral node) => null;
-
-  @override
-  R visitParenthesizedExpression(ParenthesizedExpression node) => null;
-
-  @override
-  R visitPartDirective(PartDirective node) => null;
-
-  @override
-  R visitPartOfDirective(PartOfDirective node) => null;
-
-  @override
-  R visitPostfixExpression(PostfixExpression node) => null;
-
-  @override
-  R visitPrefixedIdentifier(PrefixedIdentifier node) => null;
-
-  @override
-  R visitPrefixExpression(PrefixExpression node) => null;
-
-  @override
-  R visitPropertyAccess(PropertyAccess node) => null;
-
-  @override
-  R visitRedirectingConstructorInvocation(
-          RedirectingConstructorInvocation node) =>
-      null;
-
-  @override
-  R visitRethrowExpression(RethrowExpression node) => null;
-
-  @override
-  R visitReturnStatement(ReturnStatement node) => null;
-
-  @override
-  R visitScriptTag(ScriptTag node) => null;
-
-  @override
-  R visitShowCombinator(ShowCombinator node) => null;
-
-  @override
-  R visitSimpleFormalParameter(SimpleFormalParameter node) => null;
-
-  @override
-  R visitSimpleIdentifier(SimpleIdentifier node) => null;
-
-  @override
-  R visitSimpleStringLiteral(SimpleStringLiteral node) => null;
-
-  @override
-  R visitStringInterpolation(StringInterpolation node) => null;
-
-  @override
-  R visitSuperConstructorInvocation(SuperConstructorInvocation node) => null;
-
-  @override
-  R visitSuperExpression(SuperExpression node) => null;
-
-  @override
-  R visitSwitchCase(SwitchCase node) => null;
-
-  @override
-  R visitSwitchDefault(SwitchDefault node) => null;
-
-  @override
-  R visitSwitchStatement(SwitchStatement node) => null;
-
-  @override
-  R visitSymbolLiteral(SymbolLiteral node) => null;
-
-  @override
-  R visitThisExpression(ThisExpression node) => null;
-
-  @override
-  R visitThrowExpression(ThrowExpression node) => null;
-
-  @override
-  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) => null;
-
-  @override
-  R visitTryStatement(TryStatement node) => null;
-
-  @override
-  R visitTypeArgumentList(TypeArgumentList node) => null;
-
-  @override
-  R visitTypeName(TypeName node) => null;
-
-  @override
-  R visitTypeParameter(TypeParameter node) => null;
-
-  @override
-  R visitTypeParameterList(TypeParameterList node) => null;
-
-  @override
-  R visitVariableDeclaration(VariableDeclaration node) => null;
-
-  @override
-  R visitVariableDeclarationList(VariableDeclarationList node) => null;
-
-  @override
-  R visitVariableDeclarationStatement(VariableDeclarationStatement node) =>
-      null;
-
-  @override
-  R visitWhileStatement(WhileStatement node) => null;
-
-  @override
-  R visitWithClause(WithClause node) => null;
-
-  @override
-  R visitYieldStatement(YieldStatement node) => null;
-}
-
-/**
  * A simple formal parameter.
  *
  * > simpleFormalParameter ::=
@@ -16596,11 +9875,13 @@
   Token get endToken => identifier.endToken;
 
   @override
-  bool get isConst => (keyword is KeywordToken) &&
+  bool get isConst =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   @override
-  bool get isFinal => (keyword is KeywordToken) &&
+  bool get isFinal =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.FINAL;
 
   /**
@@ -16973,12 +10254,6 @@
   String _value;
 
   /**
-   * The toolkit specific element associated with this literal, or `null`.
-   */
-  @deprecated // No replacement
-  Element toolkitElement;
-
-  /**
    * Initialize a newly created simple string literal.
    */
   SimpleStringLiteral(this.literal, String value) {
@@ -17072,8 +10347,8 @@
   bool get isRaw;
 
   /**
-   * Return `true` if this string literal uses single qoutes (' or ''').
-   * Return `false` if this string literal uses double qoutes (" or """).
+   * Return `true` if this string literal uses single quotes (' or ''').
+   * Return `false` if this string literal uses double quotes (" or """).
    */
   bool get isSingleQuoted;
 }
@@ -17303,14 +10578,6 @@
    * [IllegalArgumentException] if the string is not a constant string without
    * any string interpolation.
    */
-  @deprecated // Use "this.stringValue"
-  void appendStringValue(StringBuffer buffer) => _appendStringValue(buffer);
-
-  /**
-   * Append the value of this string literal to the given [buffer]. Throw an
-   * [IllegalArgumentException] if the string is not a constant string without
-   * any string interpolation.
-   */
   void _appendStringValue(StringBuffer buffer);
 }
 
@@ -17402,20 +10669,6 @@
   @override
   Token get endToken => _argumentList.endToken;
 
-  /**
-   * Return the token for the 'super' keyword.
-   */
-  @deprecated // Use "this.superKeyword"
-  Token get keyword => superKeyword;
-
-  /**
-   * Set the token for the 'super' keyword to the given [token].
-   */
-  @deprecated // Use "this.superKeyword"
-  set keyword(Token token) {
-    superKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitSuperConstructorInvocation(this);
 
@@ -17452,20 +10705,6 @@
   @override
   Token get endToken => superKeyword;
 
-  /**
-   * Return the token for the 'super' keyword.
-   */
-  @deprecated // Use "this.superKeyword"
-  Token get keyword => superKeyword;
-
-  /**
-   * Set the token for the 'super' keyword to the given [token].
-   */
-  @deprecated // Use "this.superKeyword"
-  set keyword(Token token) {
-    superKeyword = token;
-  }
-
   @override
   int get precedence => 16;
 
@@ -17720,20 +10959,6 @@
   }
 
   /**
-   * Return the token representing the 'switch' keyword.
-   */
-  @deprecated // Use "this.switchKeyword"
-  Token get keyword => switchKeyword;
-
-  /**
-   * Set the token representing the 'switch' keyword to the given [token].
-   */
-  @deprecated // Use "this.switchKeyword"
-  set keyword(Token token) {
-    switchKeyword = token;
-  }
-
-  /**
    * Return the switch members that can be selected by the expression.
    */
   NodeList<SwitchMember> get members => _members;
@@ -17817,20 +11042,6 @@
   @override
   Token get endToken => thisKeyword;
 
-  /**
-   * Return the token representing the 'this' keyword.
-   */
-  @deprecated // Use "this.thisKeyword"
-  Token get keyword => thisKeyword;
-
-  /**
-   * Set the token representing the 'this' keyword to the given [token].
-   */
-  @deprecated // Use "this.thisKeyword"
-  set keyword(Token token) {
-    thisKeyword = token;
-  }
-
   @override
   int get precedence => 16;
 
@@ -17895,20 +11106,6 @@
     _expression = _becomeParentOf(expression);
   }
 
-  /**
-   * Return the token representing the 'throw' keyword.
-   */
-  @deprecated // Use "this.throwKeyword"
-  Token get keyword => throwKeyword;
-
-  /**
-   * Set the token representing the 'throw' keyword to the given [token].
-   */
-  @deprecated // Use "this.throwKeyword"
-  set keyword(Token token) {
-    throwKeyword = token;
-  }
-
   @override
   int get precedence => 0;
 
@@ -17987,1129 +11184,6 @@
 }
 
 /**
- * A visitor used to write a source representation of a visited AST node (and
- * all of it's children) to a writer.
- */
-class ToSourceVisitor implements AstVisitor<Object> {
-  /**
-   * The writer to which the source is to be written.
-   */
-  final PrintWriter _writer;
-
-  /**
-   * Initialize a newly created visitor to write source code representing the
-   * visited nodes to the given [writer].
-   */
-  ToSourceVisitor(this._writer);
-
-  @override
-  Object visitAdjacentStrings(AdjacentStrings node) {
-    _visitNodeListWithSeparator(node.strings, " ");
-    return null;
-  }
-
-  @override
-  Object visitAnnotation(Annotation node) {
-    _writer.print('@');
-    _visitNode(node.name);
-    _visitNodeWithPrefix(".", node.constructorName);
-    _visitNode(node.arguments);
-    return null;
-  }
-
-  @override
-  Object visitArgumentList(ArgumentList node) {
-    _writer.print('(');
-    _visitNodeListWithSeparator(node.arguments, ", ");
-    _writer.print(')');
-    return null;
-  }
-
-  @override
-  Object visitAsExpression(AsExpression node) {
-    _visitNode(node.expression);
-    _writer.print(" as ");
-    _visitNode(node.type);
-    return null;
-  }
-
-  @override
-  Object visitAssertStatement(AssertStatement node) {
-    _writer.print("assert (");
-    _visitNode(node.condition);
-    _writer.print(");");
-    return null;
-  }
-
-  @override
-  Object visitAssignmentExpression(AssignmentExpression node) {
-    _visitNode(node.leftHandSide);
-    _writer.print(' ');
-    _writer.print(node.operator.lexeme);
-    _writer.print(' ');
-    _visitNode(node.rightHandSide);
-    return null;
-  }
-
-  @override
-  Object visitAwaitExpression(AwaitExpression node) {
-    _writer.print("await ");
-    _visitNode(node.expression);
-    return null;
-  }
-
-  @override
-  Object visitBinaryExpression(BinaryExpression node) {
-    _visitNode(node.leftOperand);
-    _writer.print(' ');
-    _writer.print(node.operator.lexeme);
-    _writer.print(' ');
-    _visitNode(node.rightOperand);
-    return null;
-  }
-
-  @override
-  Object visitBlock(Block node) {
-    _writer.print('{');
-    _visitNodeListWithSeparator(node.statements, " ");
-    _writer.print('}');
-    return null;
-  }
-
-  @override
-  Object visitBlockFunctionBody(BlockFunctionBody node) {
-    Token keyword = node.keyword;
-    if (keyword != null) {
-      _writer.print(keyword.lexeme);
-      if (node.star != null) {
-        _writer.print('*');
-      }
-      _writer.print(' ');
-    }
-    _visitNode(node.block);
-    return null;
-  }
-
-  @override
-  Object visitBooleanLiteral(BooleanLiteral node) {
-    _writer.print(node.literal.lexeme);
-    return null;
-  }
-
-  @override
-  Object visitBreakStatement(BreakStatement node) {
-    _writer.print("break");
-    _visitNodeWithPrefix(" ", node.label);
-    _writer.print(";");
-    return null;
-  }
-
-  @override
-  Object visitCascadeExpression(CascadeExpression node) {
-    _visitNode(node.target);
-    _visitNodeList(node.cascadeSections);
-    return null;
-  }
-
-  @override
-  Object visitCatchClause(CatchClause node) {
-    _visitNodeWithPrefix("on ", node.exceptionType);
-    if (node.catchKeyword != null) {
-      if (node.exceptionType != null) {
-        _writer.print(' ');
-      }
-      _writer.print("catch (");
-      _visitNode(node.exceptionParameter);
-      _visitNodeWithPrefix(", ", node.stackTraceParameter);
-      _writer.print(") ");
-    } else {
-      _writer.print(" ");
-    }
-    _visitNode(node.body);
-    return null;
-  }
-
-  @override
-  Object visitClassDeclaration(ClassDeclaration node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitTokenWithSuffix(node.abstractKeyword, " ");
-    _writer.print("class ");
-    _visitNode(node.name);
-    _visitNode(node.typeParameters);
-    _visitNodeWithPrefix(" ", node.extendsClause);
-    _visitNodeWithPrefix(" ", node.withClause);
-    _visitNodeWithPrefix(" ", node.implementsClause);
-    _writer.print(" {");
-    _visitNodeListWithSeparator(node.members, " ");
-    _writer.print("}");
-    return null;
-  }
-
-  @override
-  Object visitClassTypeAlias(ClassTypeAlias node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    if (node.abstractKeyword != null) {
-      _writer.print("abstract ");
-    }
-    _writer.print("class ");
-    _visitNode(node.name);
-    _visitNode(node.typeParameters);
-    _writer.print(" = ");
-    _visitNode(node.superclass);
-    _visitNodeWithPrefix(" ", node.withClause);
-    _visitNodeWithPrefix(" ", node.implementsClause);
-    _writer.print(";");
-    return null;
-  }
-
-  @override
-  Object visitComment(Comment node) => null;
-
-  @override
-  Object visitCommentReference(CommentReference node) => null;
-
-  @override
-  Object visitCompilationUnit(CompilationUnit node) {
-    ScriptTag scriptTag = node.scriptTag;
-    NodeList<Directive> directives = node.directives;
-    _visitNode(scriptTag);
-    String prefix = scriptTag == null ? "" : " ";
-    _visitNodeListWithSeparatorAndPrefix(prefix, directives, " ");
-    prefix = scriptTag == null && directives.isEmpty ? "" : " ";
-    _visitNodeListWithSeparatorAndPrefix(prefix, node.declarations, " ");
-    return null;
-  }
-
-  @override
-  Object visitConditionalExpression(ConditionalExpression node) {
-    _visitNode(node.condition);
-    _writer.print(" ? ");
-    _visitNode(node.thenExpression);
-    _writer.print(" : ");
-    _visitNode(node.elseExpression);
-    return null;
-  }
-
-  @override
-  Object visitConstructorDeclaration(ConstructorDeclaration node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitTokenWithSuffix(node.externalKeyword, " ");
-    _visitTokenWithSuffix(node.constKeyword, " ");
-    _visitTokenWithSuffix(node.factoryKeyword, " ");
-    _visitNode(node.returnType);
-    _visitNodeWithPrefix(".", node.name);
-    _visitNode(node.parameters);
-    _visitNodeListWithSeparatorAndPrefix(" : ", node.initializers, ", ");
-    _visitNodeWithPrefix(" = ", node.redirectedConstructor);
-    _visitFunctionWithPrefix(" ", node.body);
-    return null;
-  }
-
-  @override
-  Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    _visitTokenWithSuffix(node.thisKeyword, ".");
-    _visitNode(node.fieldName);
-    _writer.print(" = ");
-    _visitNode(node.expression);
-    return null;
-  }
-
-  @override
-  Object visitConstructorName(ConstructorName node) {
-    _visitNode(node.type);
-    _visitNodeWithPrefix(".", node.name);
-    return null;
-  }
-
-  @override
-  Object visitContinueStatement(ContinueStatement node) {
-    _writer.print("continue");
-    _visitNodeWithPrefix(" ", node.label);
-    _writer.print(";");
-    return null;
-  }
-
-  @override
-  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitTokenWithSuffix(node.keyword, " ");
-    _visitNodeWithSuffix(node.type, " ");
-    _visitNode(node.identifier);
-    return null;
-  }
-
-  @override
-  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
-    _visitNode(node.parameter);
-    if (node.separator != null) {
-      _writer.print(" ");
-      _writer.print(node.separator.lexeme);
-      _visitNodeWithPrefix(" ", node.defaultValue);
-    }
-    return null;
-  }
-
-  @override
-  Object visitDoStatement(DoStatement node) {
-    _writer.print("do ");
-    _visitNode(node.body);
-    _writer.print(" while (");
-    _visitNode(node.condition);
-    _writer.print(");");
-    return null;
-  }
-
-  @override
-  Object visitDoubleLiteral(DoubleLiteral node) {
-    _writer.print(node.literal.lexeme);
-    return null;
-  }
-
-  @override
-  Object visitEmptyFunctionBody(EmptyFunctionBody node) {
-    _writer.print(';');
-    return null;
-  }
-
-  @override
-  Object visitEmptyStatement(EmptyStatement node) {
-    _writer.print(';');
-    return null;
-  }
-
-  @override
-  Object visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitNode(node.name);
-    return null;
-  }
-
-  @override
-  Object visitEnumDeclaration(EnumDeclaration node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _writer.print("enum ");
-    _visitNode(node.name);
-    _writer.print(" {");
-    _visitNodeListWithSeparator(node.constants, ", ");
-    _writer.print("}");
-    return null;
-  }
-
-  @override
-  Object visitExportDirective(ExportDirective node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _writer.print("export ");
-    _visitNode(node.uri);
-    _visitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
-    _writer.print(';');
-    return null;
-  }
-
-  @override
-  Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    Token keyword = node.keyword;
-    if (keyword != null) {
-      _writer.print(keyword.lexeme);
-      _writer.print(' ');
-    }
-    _writer.print("=> ");
-    _visitNode(node.expression);
-    if (node.semicolon != null) {
-      _writer.print(';');
-    }
-    return null;
-  }
-
-  @override
-  Object visitExpressionStatement(ExpressionStatement node) {
-    _visitNode(node.expression);
-    _writer.print(';');
-    return null;
-  }
-
-  @override
-  Object visitExtendsClause(ExtendsClause node) {
-    _writer.print("extends ");
-    _visitNode(node.superclass);
-    return null;
-  }
-
-  @override
-  Object visitFieldDeclaration(FieldDeclaration node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitTokenWithSuffix(node.staticKeyword, " ");
-    _visitNode(node.fields);
-    _writer.print(";");
-    return null;
-  }
-
-  @override
-  Object visitFieldFormalParameter(FieldFormalParameter node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
-    _visitTokenWithSuffix(node.keyword, " ");
-    _visitNodeWithSuffix(node.type, " ");
-    _writer.print("this.");
-    _visitNode(node.identifier);
-    _visitNode(node.typeParameters);
-    _visitNode(node.parameters);
-    return null;
-  }
-
-  @override
-  Object visitForEachStatement(ForEachStatement node) {
-    DeclaredIdentifier loopVariable = node.loopVariable;
-    if (node.awaitKeyword != null) {
-      _writer.print("await ");
-    }
-    _writer.print("for (");
-    if (loopVariable == null) {
-      _visitNode(node.identifier);
-    } else {
-      _visitNode(loopVariable);
-    }
-    _writer.print(" in ");
-    _visitNode(node.iterable);
-    _writer.print(") ");
-    _visitNode(node.body);
-    return null;
-  }
-
-  @override
-  Object visitFormalParameterList(FormalParameterList node) {
-    String groupEnd = null;
-    _writer.print('(');
-    NodeList<FormalParameter> parameters = node.parameters;
-    int size = parameters.length;
-    for (int i = 0; i < size; i++) {
-      FormalParameter parameter = parameters[i];
-      if (i > 0) {
-        _writer.print(", ");
-      }
-      if (groupEnd == null && parameter is DefaultFormalParameter) {
-        if (parameter.kind == ParameterKind.NAMED) {
-          groupEnd = "}";
-          _writer.print('{');
-        } else {
-          groupEnd = "]";
-          _writer.print('[');
-        }
-      }
-      parameter.accept(this);
-    }
-    if (groupEnd != null) {
-      _writer.print(groupEnd);
-    }
-    _writer.print(')');
-    return null;
-  }
-
-  @override
-  Object visitForStatement(ForStatement node) {
-    Expression initialization = node.initialization;
-    _writer.print("for (");
-    if (initialization != null) {
-      _visitNode(initialization);
-    } else {
-      _visitNode(node.variables);
-    }
-    _writer.print(";");
-    _visitNodeWithPrefix(" ", node.condition);
-    _writer.print(";");
-    _visitNodeListWithSeparatorAndPrefix(" ", node.updaters, ", ");
-    _writer.print(") ");
-    _visitNode(node.body);
-    return null;
-  }
-
-  @override
-  Object visitFunctionDeclaration(FunctionDeclaration node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitTokenWithSuffix(node.externalKeyword, " ");
-    _visitNodeWithSuffix(node.returnType, " ");
-    _visitTokenWithSuffix(node.propertyKeyword, " ");
-    _visitNode(node.name);
-    _visitNode(node.functionExpression);
-    return null;
-  }
-
-  @override
-  Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
-    _visitNode(node.functionDeclaration);
-    return null;
-  }
-
-  @override
-  Object visitFunctionExpression(FunctionExpression node) {
-    _visitNode(node.typeParameters);
-    _visitNode(node.parameters);
-    if (node.body is! EmptyFunctionBody) {
-      _writer.print(' ');
-    }
-    _visitNode(node.body);
-    return null;
-  }
-
-  @override
-  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    _visitNode(node.function);
-    _visitNode(node.typeArguments);
-    _visitNode(node.argumentList);
-    return null;
-  }
-
-  @override
-  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _writer.print("typedef ");
-    _visitNodeWithSuffix(node.returnType, " ");
-    _visitNode(node.name);
-    _visitNode(node.typeParameters);
-    _visitNode(node.parameters);
-    _writer.print(";");
-    return null;
-  }
-
-  @override
-  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
-    _visitNodeWithSuffix(node.returnType, " ");
-    _visitNode(node.identifier);
-    _visitNode(node.typeParameters);
-    _visitNode(node.parameters);
-    return null;
-  }
-
-  @override
-  Object visitHideCombinator(HideCombinator node) {
-    _writer.print("hide ");
-    _visitNodeListWithSeparator(node.hiddenNames, ", ");
-    return null;
-  }
-
-  @override
-  Object visitIfStatement(IfStatement node) {
-    _writer.print("if (");
-    _visitNode(node.condition);
-    _writer.print(") ");
-    _visitNode(node.thenStatement);
-    _visitNodeWithPrefix(" else ", node.elseStatement);
-    return null;
-  }
-
-  @override
-  Object visitImplementsClause(ImplementsClause node) {
-    _writer.print("implements ");
-    _visitNodeListWithSeparator(node.interfaces, ", ");
-    return null;
-  }
-
-  @override
-  Object visitImportDirective(ImportDirective node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _writer.print("import ");
-    _visitNode(node.uri);
-    if (node.deferredKeyword != null) {
-      _writer.print(" deferred");
-    }
-    _visitNodeWithPrefix(" as ", node.prefix);
-    _visitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
-    _writer.print(';');
-    return null;
-  }
-
-  @override
-  Object visitIndexExpression(IndexExpression node) {
-    if (node.isCascaded) {
-      _writer.print("..");
-    } else {
-      _visitNode(node.target);
-    }
-    _writer.print('[');
-    _visitNode(node.index);
-    _writer.print(']');
-    return null;
-  }
-
-  @override
-  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
-    _visitTokenWithSuffix(node.keyword, " ");
-    _visitNode(node.constructorName);
-    _visitNode(node.argumentList);
-    return null;
-  }
-
-  @override
-  Object visitIntegerLiteral(IntegerLiteral node) {
-    _writer.print(node.literal.lexeme);
-    return null;
-  }
-
-  @override
-  Object visitInterpolationExpression(InterpolationExpression node) {
-    if (node.rightBracket != null) {
-      _writer.print("\${");
-      _visitNode(node.expression);
-      _writer.print("}");
-    } else {
-      _writer.print("\$");
-      _visitNode(node.expression);
-    }
-    return null;
-  }
-
-  @override
-  Object visitInterpolationString(InterpolationString node) {
-    _writer.print(node.contents.lexeme);
-    return null;
-  }
-
-  @override
-  Object visitIsExpression(IsExpression node) {
-    _visitNode(node.expression);
-    if (node.notOperator == null) {
-      _writer.print(" is ");
-    } else {
-      _writer.print(" is! ");
-    }
-    _visitNode(node.type);
-    return null;
-  }
-
-  @override
-  Object visitLabel(Label node) {
-    _visitNode(node.label);
-    _writer.print(":");
-    return null;
-  }
-
-  @override
-  Object visitLabeledStatement(LabeledStatement node) {
-    _visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
-    _visitNode(node.statement);
-    return null;
-  }
-
-  @override
-  Object visitLibraryDirective(LibraryDirective node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _writer.print("library ");
-    _visitNode(node.name);
-    _writer.print(';');
-    return null;
-  }
-
-  @override
-  Object visitLibraryIdentifier(LibraryIdentifier node) {
-    _writer.print(node.name);
-    return null;
-  }
-
-  @override
-  Object visitListLiteral(ListLiteral node) {
-    if (node.constKeyword != null) {
-      _writer.print(node.constKeyword.lexeme);
-      _writer.print(' ');
-    }
-    _visitNodeWithSuffix(node.typeArguments, " ");
-    _writer.print("[");
-    _visitNodeListWithSeparator(node.elements, ", ");
-    _writer.print("]");
-    return null;
-  }
-
-  @override
-  Object visitMapLiteral(MapLiteral node) {
-    if (node.constKeyword != null) {
-      _writer.print(node.constKeyword.lexeme);
-      _writer.print(' ');
-    }
-    _visitNodeWithSuffix(node.typeArguments, " ");
-    _writer.print("{");
-    _visitNodeListWithSeparator(node.entries, ", ");
-    _writer.print("}");
-    return null;
-  }
-
-  @override
-  Object visitMapLiteralEntry(MapLiteralEntry node) {
-    _visitNode(node.key);
-    _writer.print(" : ");
-    _visitNode(node.value);
-    return null;
-  }
-
-  @override
-  Object visitMethodDeclaration(MethodDeclaration node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitTokenWithSuffix(node.externalKeyword, " ");
-    _visitTokenWithSuffix(node.modifierKeyword, " ");
-    _visitNodeWithSuffix(node.returnType, " ");
-    _visitTokenWithSuffix(node.propertyKeyword, " ");
-    _visitTokenWithSuffix(node.operatorKeyword, " ");
-    _visitNode(node.name);
-    if (!node.isGetter) {
-      _visitNode(node.typeParameters);
-      _visitNode(node.parameters);
-    }
-    _visitFunctionWithPrefix(" ", node.body);
-    return null;
-  }
-
-  @override
-  Object visitMethodInvocation(MethodInvocation node) {
-    if (node.isCascaded) {
-      _writer.print("..");
-    } else {
-      if (node.target != null) {
-        node.target.accept(this);
-        _writer.print(node.operator.lexeme);
-      }
-    }
-    _visitNode(node.methodName);
-    _visitNode(node.typeArguments);
-    _visitNode(node.argumentList);
-    return null;
-  }
-
-  @override
-  Object visitNamedExpression(NamedExpression node) {
-    _visitNode(node.name);
-    _visitNodeWithPrefix(" ", node.expression);
-    return null;
-  }
-
-  @override
-  Object visitNativeClause(NativeClause node) {
-    _writer.print("native ");
-    _visitNode(node.name);
-    return null;
-  }
-
-  @override
-  Object visitNativeFunctionBody(NativeFunctionBody node) {
-    _writer.print("native ");
-    _visitNode(node.stringLiteral);
-    _writer.print(';');
-    return null;
-  }
-
-  @override
-  Object visitNullLiteral(NullLiteral node) {
-    _writer.print("null");
-    return null;
-  }
-
-  @override
-  Object visitParenthesizedExpression(ParenthesizedExpression node) {
-    _writer.print('(');
-    _visitNode(node.expression);
-    _writer.print(')');
-    return null;
-  }
-
-  @override
-  Object visitPartDirective(PartDirective node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _writer.print("part ");
-    _visitNode(node.uri);
-    _writer.print(';');
-    return null;
-  }
-
-  @override
-  Object visitPartOfDirective(PartOfDirective node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _writer.print("part of ");
-    _visitNode(node.libraryName);
-    _writer.print(';');
-    return null;
-  }
-
-  @override
-  Object visitPostfixExpression(PostfixExpression node) {
-    _visitNode(node.operand);
-    _writer.print(node.operator.lexeme);
-    return null;
-  }
-
-  @override
-  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
-    _visitNode(node.prefix);
-    _writer.print('.');
-    _visitNode(node.identifier);
-    return null;
-  }
-
-  @override
-  Object visitPrefixExpression(PrefixExpression node) {
-    _writer.print(node.operator.lexeme);
-    _visitNode(node.operand);
-    return null;
-  }
-
-  @override
-  Object visitPropertyAccess(PropertyAccess node) {
-    if (node.isCascaded) {
-      _writer.print("..");
-    } else {
-      _visitNode(node.target);
-      _writer.print(node.operator.lexeme);
-    }
-    _visitNode(node.propertyName);
-    return null;
-  }
-
-  @override
-  Object visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    _writer.print("this");
-    _visitNodeWithPrefix(".", node.constructorName);
-    _visitNode(node.argumentList);
-    return null;
-  }
-
-  @override
-  Object visitRethrowExpression(RethrowExpression node) {
-    _writer.print("rethrow");
-    return null;
-  }
-
-  @override
-  Object visitReturnStatement(ReturnStatement node) {
-    Expression expression = node.expression;
-    if (expression == null) {
-      _writer.print("return;");
-    } else {
-      _writer.print("return ");
-      expression.accept(this);
-      _writer.print(";");
-    }
-    return null;
-  }
-
-  @override
-  Object visitScriptTag(ScriptTag node) {
-    _writer.print(node.scriptTag.lexeme);
-    return null;
-  }
-
-  @override
-  Object visitShowCombinator(ShowCombinator node) {
-    _writer.print("show ");
-    _visitNodeListWithSeparator(node.shownNames, ", ");
-    return null;
-  }
-
-  @override
-  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
-    _visitTokenWithSuffix(node.keyword, " ");
-    _visitNodeWithSuffix(node.type, " ");
-    _visitNode(node.identifier);
-    return null;
-  }
-
-  @override
-  Object visitSimpleIdentifier(SimpleIdentifier node) {
-    _writer.print(node.token.lexeme);
-    return null;
-  }
-
-  @override
-  Object visitSimpleStringLiteral(SimpleStringLiteral node) {
-    _writer.print(node.literal.lexeme);
-    return null;
-  }
-
-  @override
-  Object visitStringInterpolation(StringInterpolation node) {
-    _visitNodeList(node.elements);
-    return null;
-  }
-
-  @override
-  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    _writer.print("super");
-    _visitNodeWithPrefix(".", node.constructorName);
-    _visitNode(node.argumentList);
-    return null;
-  }
-
-  @override
-  Object visitSuperExpression(SuperExpression node) {
-    _writer.print("super");
-    return null;
-  }
-
-  @override
-  Object visitSwitchCase(SwitchCase node) {
-    _visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
-    _writer.print("case ");
-    _visitNode(node.expression);
-    _writer.print(": ");
-    _visitNodeListWithSeparator(node.statements, " ");
-    return null;
-  }
-
-  @override
-  Object visitSwitchDefault(SwitchDefault node) {
-    _visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
-    _writer.print("default: ");
-    _visitNodeListWithSeparator(node.statements, " ");
-    return null;
-  }
-
-  @override
-  Object visitSwitchStatement(SwitchStatement node) {
-    _writer.print("switch (");
-    _visitNode(node.expression);
-    _writer.print(") {");
-    _visitNodeListWithSeparator(node.members, " ");
-    _writer.print("}");
-    return null;
-  }
-
-  @override
-  Object visitSymbolLiteral(SymbolLiteral node) {
-    _writer.print("#");
-    List<Token> components = node.components;
-    for (int i = 0; i < components.length; i++) {
-      if (i > 0) {
-        _writer.print(".");
-      }
-      _writer.print(components[i].lexeme);
-    }
-    return null;
-  }
-
-  @override
-  Object visitThisExpression(ThisExpression node) {
-    _writer.print("this");
-    return null;
-  }
-
-  @override
-  Object visitThrowExpression(ThrowExpression node) {
-    _writer.print("throw ");
-    _visitNode(node.expression);
-    return null;
-  }
-
-  @override
-  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    _visitNodeWithSuffix(node.variables, ";");
-    return null;
-  }
-
-  @override
-  Object visitTryStatement(TryStatement node) {
-    _writer.print("try ");
-    _visitNode(node.body);
-    _visitNodeListWithSeparatorAndPrefix(" ", node.catchClauses, " ");
-    _visitNodeWithPrefix(" finally ", node.finallyBlock);
-    return null;
-  }
-
-  @override
-  Object visitTypeArgumentList(TypeArgumentList node) {
-    _writer.print('<');
-    _visitNodeListWithSeparator(node.arguments, ", ");
-    _writer.print('>');
-    return null;
-  }
-
-  @override
-  Object visitTypeName(TypeName node) {
-    _visitNode(node.name);
-    _visitNode(node.typeArguments);
-    return null;
-  }
-
-  @override
-  Object visitTypeParameter(TypeParameter node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitNode(node.name);
-    _visitNodeWithPrefix(" extends ", node.bound);
-    return null;
-  }
-
-  @override
-  Object visitTypeParameterList(TypeParameterList node) {
-    _writer.print('<');
-    _visitNodeListWithSeparator(node.typeParameters, ", ");
-    _writer.print('>');
-    return null;
-  }
-
-  @override
-  Object visitVariableDeclaration(VariableDeclaration node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitNode(node.name);
-    _visitNodeWithPrefix(" = ", node.initializer);
-    return null;
-  }
-
-  @override
-  Object visitVariableDeclarationList(VariableDeclarationList node) {
-    _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
-    _visitTokenWithSuffix(node.keyword, " ");
-    _visitNodeWithSuffix(node.type, " ");
-    _visitNodeListWithSeparator(node.variables, ", ");
-    return null;
-  }
-
-  @override
-  Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    _visitNode(node.variables);
-    _writer.print(";");
-    return null;
-  }
-
-  @override
-  Object visitWhileStatement(WhileStatement node) {
-    _writer.print("while (");
-    _visitNode(node.condition);
-    _writer.print(") ");
-    _visitNode(node.body);
-    return null;
-  }
-
-  @override
-  Object visitWithClause(WithClause node) {
-    _writer.print("with ");
-    _visitNodeListWithSeparator(node.mixinTypes, ", ");
-    return null;
-  }
-
-  @override
-  Object visitYieldStatement(YieldStatement node) {
-    if (node.star != null) {
-      _writer.print("yield* ");
-    } else {
-      _writer.print("yield ");
-    }
-    _visitNode(node.expression);
-    _writer.print(";");
-    return null;
-  }
-
-  /**
-   * Visit the given function [body], printing the [prefix] before if the body
-   * is not empty.
-   */
-  void _visitFunctionWithPrefix(String prefix, FunctionBody body) {
-    if (body is! EmptyFunctionBody) {
-      _writer.print(prefix);
-    }
-    _visitNode(body);
-  }
-
-  /**
-   * Safely visit the given [node].
-   */
-  void _visitNode(AstNode node) {
-    if (node != null) {
-      node.accept(this);
-    }
-  }
-
-  /**
-   * Print a list of [nodes] without any separation.
-   */
-  void _visitNodeList(NodeList<AstNode> nodes) {
-    _visitNodeListWithSeparator(nodes, "");
-  }
-
-  /**
-   * Print a list of [nodes], separated by the given [separator].
-   */
-  void _visitNodeListWithSeparator(NodeList<AstNode> nodes, String separator) {
-    if (nodes != null) {
-      int size = nodes.length;
-      for (int i = 0; i < size; i++) {
-        if (i > 0) {
-          _writer.print(separator);
-        }
-        nodes[i].accept(this);
-      }
-    }
-  }
-
-  /**
-   * Print a list of [nodes], prefixed by the given [prefix] if the list is not
-   * empty, and separated by the given [separator].
-   */
-  void _visitNodeListWithSeparatorAndPrefix(
-      String prefix, NodeList<AstNode> nodes, String separator) {
-    if (nodes != null) {
-      int size = nodes.length;
-      if (size > 0) {
-        _writer.print(prefix);
-        for (int i = 0; i < size; i++) {
-          if (i > 0) {
-            _writer.print(separator);
-          }
-          nodes[i].accept(this);
-        }
-      }
-    }
-  }
-
-  /**
-   * Print a list of [nodes], separated by the given [separator], followed by
-   * the given [suffix] if the list is not empty.
-   */
-  void _visitNodeListWithSeparatorAndSuffix(
-      NodeList<AstNode> nodes, String separator, String suffix) {
-    if (nodes != null) {
-      int size = nodes.length;
-      if (size > 0) {
-        for (int i = 0; i < size; i++) {
-          if (i > 0) {
-            _writer.print(separator);
-          }
-          nodes[i].accept(this);
-        }
-        _writer.print(suffix);
-      }
-    }
-  }
-
-  /**
-   * Safely visit the given [node], printing the [prefix] before the node if it
-   * is non-`null`.
-   */
-  void _visitNodeWithPrefix(String prefix, AstNode node) {
-    if (node != null) {
-      _writer.print(prefix);
-      node.accept(this);
-    }
-  }
-
-  /**
-   * Safely visit the given [node], printing the [suffix] after the node if it
-   * is non-`null`.
-   */
-  void _visitNodeWithSuffix(AstNode node, String suffix) {
-    if (node != null) {
-      node.accept(this);
-      _writer.print(suffix);
-    }
-  }
-
-  /**
-   * Safely visit the given [token], printing the [suffix] after the token if it
-   * is non-`null`.
-   */
-  void _visitTokenWithSuffix(Token token, String suffix) {
-    if (token != null) {
-      _writer.print(token.lexeme);
-      _writer.print(suffix);
-    }
-  }
-}
-
-/**
  * A try statement.
  *
  * > tryStatement ::=
@@ -19257,20 +11331,6 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata => typedefKeyword;
-
-  /**
-   * Return the token representing the 'typedef' keyword.
-   */
-  @deprecated // Use "this.typedefKeyword"
-  Token get keyword => typedefKeyword;
-
-  /**
-   * Set the token representing the 'typedef' keyword to the given [token].
-   */
-  @deprecated // Use "this.typedefKeyword"
-  set keyword(Token token) {
-    typedefKeyword = token;
-  }
 }
 
 /**
@@ -19553,21 +11613,6 @@
   Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
 
   /**
-   * Return the token representing the 'extends' keyword, or `null` if there is
-   * no explicit upper bound.
-   */
-  @deprecated // Use "this.extendsKeyword"
-  Token get keyword => extendsKeyword;
-
-  /**
-   * Set the token representing the 'extends' keyword to the given [token].
-   */
-  @deprecated // Use "this.extendsKeyword"
-  set keyword(Token token) {
-    extendsKeyword = token;
-  }
-
-  /**
    * Return the name of the type parameter.
    */
   SimpleIdentifier get name => _name;
@@ -19647,355 +11692,6 @@
 }
 
 /**
- * An AST visitor that will recursively visit all of the nodes in an AST
- * structure (like instances of the class [RecursiveAstVisitor]). In addition,
- * every node will also be visited by using a single unified [visitNode] method.
- *
- * Subclasses that override a visit method must either invoke the overridden
- * visit method or explicitly invoke the more general [visitNode] method.
- * Failure to do so will cause the children of the visited node to not be
- * visited.
- */
-class UnifyingAstVisitor<R> implements AstVisitor<R> {
-  @override
-  R visitAdjacentStrings(AdjacentStrings node) => visitNode(node);
-
-  @override
-  R visitAnnotation(Annotation node) => visitNode(node);
-
-  @override
-  R visitArgumentList(ArgumentList node) => visitNode(node);
-
-  @override
-  R visitAsExpression(AsExpression node) => visitNode(node);
-
-  @override
-  R visitAssertStatement(AssertStatement node) => visitNode(node);
-
-  @override
-  R visitAssignmentExpression(AssignmentExpression node) => visitNode(node);
-
-  @override
-  R visitAwaitExpression(AwaitExpression node) => visitNode(node);
-
-  @override
-  R visitBinaryExpression(BinaryExpression node) => visitNode(node);
-
-  @override
-  R visitBlock(Block node) => visitNode(node);
-
-  @override
-  R visitBlockFunctionBody(BlockFunctionBody node) => visitNode(node);
-
-  @override
-  R visitBooleanLiteral(BooleanLiteral node) => visitNode(node);
-
-  @override
-  R visitBreakStatement(BreakStatement node) => visitNode(node);
-
-  @override
-  R visitCascadeExpression(CascadeExpression node) => visitNode(node);
-
-  @override
-  R visitCatchClause(CatchClause node) => visitNode(node);
-
-  @override
-  R visitClassDeclaration(ClassDeclaration node) => visitNode(node);
-
-  @override
-  R visitClassTypeAlias(ClassTypeAlias node) => visitNode(node);
-
-  @override
-  R visitComment(Comment node) => visitNode(node);
-
-  @override
-  R visitCommentReference(CommentReference node) => visitNode(node);
-
-  @override
-  R visitCompilationUnit(CompilationUnit node) => visitNode(node);
-
-  @override
-  R visitConditionalExpression(ConditionalExpression node) => visitNode(node);
-
-  @override
-  R visitConstructorDeclaration(ConstructorDeclaration node) => visitNode(node);
-
-  @override
-  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) =>
-      visitNode(node);
-
-  @override
-  R visitConstructorName(ConstructorName node) => visitNode(node);
-
-  @override
-  R visitContinueStatement(ContinueStatement node) => visitNode(node);
-
-  @override
-  R visitDeclaredIdentifier(DeclaredIdentifier node) => visitNode(node);
-
-  @override
-  R visitDefaultFormalParameter(DefaultFormalParameter node) => visitNode(node);
-
-  @override
-  R visitDoStatement(DoStatement node) => visitNode(node);
-
-  @override
-  R visitDoubleLiteral(DoubleLiteral node) => visitNode(node);
-
-  @override
-  R visitEmptyFunctionBody(EmptyFunctionBody node) => visitNode(node);
-
-  @override
-  R visitEmptyStatement(EmptyStatement node) => visitNode(node);
-
-  @override
-  R visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
-      visitNode(node);
-
-  @override
-  R visitEnumDeclaration(EnumDeclaration node) => visitNode(node);
-
-  @override
-  R visitExportDirective(ExportDirective node) => visitNode(node);
-
-  @override
-  R visitExpressionFunctionBody(ExpressionFunctionBody node) => visitNode(node);
-
-  @override
-  R visitExpressionStatement(ExpressionStatement node) => visitNode(node);
-
-  @override
-  R visitExtendsClause(ExtendsClause node) => visitNode(node);
-
-  @override
-  R visitFieldDeclaration(FieldDeclaration node) => visitNode(node);
-
-  @override
-  R visitFieldFormalParameter(FieldFormalParameter node) => visitNode(node);
-
-  @override
-  R visitForEachStatement(ForEachStatement node) => visitNode(node);
-
-  @override
-  R visitFormalParameterList(FormalParameterList node) => visitNode(node);
-
-  @override
-  R visitForStatement(ForStatement node) => visitNode(node);
-
-  @override
-  R visitFunctionDeclaration(FunctionDeclaration node) => visitNode(node);
-
-  @override
-  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) =>
-      visitNode(node);
-
-  @override
-  R visitFunctionExpression(FunctionExpression node) => visitNode(node);
-
-  @override
-  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) =>
-      visitNode(node);
-
-  @override
-  R visitFunctionTypeAlias(FunctionTypeAlias node) => visitNode(node);
-
-  @override
-  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) =>
-      visitNode(node);
-
-  @override
-  R visitHideCombinator(HideCombinator node) => visitNode(node);
-
-  @override
-  R visitIfStatement(IfStatement node) => visitNode(node);
-
-  @override
-  R visitImplementsClause(ImplementsClause node) => visitNode(node);
-
-  @override
-  R visitImportDirective(ImportDirective node) => visitNode(node);
-
-  @override
-  R visitIndexExpression(IndexExpression node) => visitNode(node);
-
-  @override
-  R visitInstanceCreationExpression(InstanceCreationExpression node) =>
-      visitNode(node);
-
-  @override
-  R visitIntegerLiteral(IntegerLiteral node) => visitNode(node);
-
-  @override
-  R visitInterpolationExpression(InterpolationExpression node) =>
-      visitNode(node);
-
-  @override
-  R visitInterpolationString(InterpolationString node) => visitNode(node);
-
-  @override
-  R visitIsExpression(IsExpression node) => visitNode(node);
-
-  @override
-  R visitLabel(Label node) => visitNode(node);
-
-  @override
-  R visitLabeledStatement(LabeledStatement node) => visitNode(node);
-
-  @override
-  R visitLibraryDirective(LibraryDirective node) => visitNode(node);
-
-  @override
-  R visitLibraryIdentifier(LibraryIdentifier node) => visitNode(node);
-
-  @override
-  R visitListLiteral(ListLiteral node) => visitNode(node);
-
-  @override
-  R visitMapLiteral(MapLiteral node) => visitNode(node);
-
-  @override
-  R visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
-
-  @override
-  R visitMethodDeclaration(MethodDeclaration node) => visitNode(node);
-
-  @override
-  R visitMethodInvocation(MethodInvocation node) => visitNode(node);
-
-  @override
-  R visitNamedExpression(NamedExpression node) => visitNode(node);
-
-  @override
-  R visitNativeClause(NativeClause node) => visitNode(node);
-
-  @override
-  R visitNativeFunctionBody(NativeFunctionBody node) => visitNode(node);
-
-  R visitNode(AstNode node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitNullLiteral(NullLiteral node) => visitNode(node);
-
-  @override
-  R visitParenthesizedExpression(ParenthesizedExpression node) =>
-      visitNode(node);
-
-  @override
-  R visitPartDirective(PartDirective node) => visitNode(node);
-
-  @override
-  R visitPartOfDirective(PartOfDirective node) => visitNode(node);
-
-  @override
-  R visitPostfixExpression(PostfixExpression node) => visitNode(node);
-
-  @override
-  R visitPrefixedIdentifier(PrefixedIdentifier node) => visitNode(node);
-
-  @override
-  R visitPrefixExpression(PrefixExpression node) => visitNode(node);
-
-  @override
-  R visitPropertyAccess(PropertyAccess node) => visitNode(node);
-
-  @override
-  R visitRedirectingConstructorInvocation(
-          RedirectingConstructorInvocation node) =>
-      visitNode(node);
-
-  @override
-  R visitRethrowExpression(RethrowExpression node) => visitNode(node);
-
-  @override
-  R visitReturnStatement(ReturnStatement node) => visitNode(node);
-
-  @override
-  R visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
-
-  @override
-  R visitShowCombinator(ShowCombinator node) => visitNode(node);
-
-  @override
-  R visitSimpleFormalParameter(SimpleFormalParameter node) => visitNode(node);
-
-  @override
-  R visitSimpleIdentifier(SimpleIdentifier node) => visitNode(node);
-
-  @override
-  R visitSimpleStringLiteral(SimpleStringLiteral node) => visitNode(node);
-
-  @override
-  R visitStringInterpolation(StringInterpolation node) => visitNode(node);
-
-  @override
-  R visitSuperConstructorInvocation(SuperConstructorInvocation node) =>
-      visitNode(node);
-
-  @override
-  R visitSuperExpression(SuperExpression node) => visitNode(node);
-
-  @override
-  R visitSwitchCase(SwitchCase node) => visitNode(node);
-
-  @override
-  R visitSwitchDefault(SwitchDefault node) => visitNode(node);
-
-  @override
-  R visitSwitchStatement(SwitchStatement node) => visitNode(node);
-
-  @override
-  R visitSymbolLiteral(SymbolLiteral node) => visitNode(node);
-
-  @override
-  R visitThisExpression(ThisExpression node) => visitNode(node);
-
-  @override
-  R visitThrowExpression(ThrowExpression node) => visitNode(node);
-
-  @override
-  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) =>
-      visitNode(node);
-
-  @override
-  R visitTryStatement(TryStatement node) => visitNode(node);
-
-  @override
-  R visitTypeArgumentList(TypeArgumentList node) => visitNode(node);
-
-  @override
-  R visitTypeName(TypeName node) => visitNode(node);
-
-  @override
-  R visitTypeParameter(TypeParameter node) => visitNode(node);
-
-  @override
-  R visitTypeParameterList(TypeParameterList node) => visitNode(node);
-
-  @override
-  R visitVariableDeclaration(VariableDeclaration node) => visitNode(node);
-
-  @override
-  R visitVariableDeclarationList(VariableDeclarationList node) =>
-      visitNode(node);
-
-  @override
-  R visitVariableDeclarationStatement(VariableDeclarationStatement node) =>
-      visitNode(node);
-
-  @override
-  R visitWhileStatement(WhileStatement node) => visitNode(node);
-
-  @override
-  R visitWithClause(WithClause node) => visitNode(node);
-
-  @override
-  R visitYieldStatement(YieldStatement node) => visitNode(node);
-}
-
-/**
  * A directive that references a URI.
  *
  * > uriBasedDirective ::=
@@ -20161,7 +11857,7 @@
 
   /**
    * This overridden implementation of getDocumentationComment() looks in the
-   * grandparent node for dartdoc comments if no documentation is specifically
+   * grandparent node for Dartdoc comments if no documentation is specifically
    * available on the node.
    */
   @override
@@ -20314,7 +12010,8 @@
    * Return `true` if the variables in this list were declared with the 'const'
    * modifier.
    */
-  bool get isConst => keyword is KeywordToken &&
+  bool get isConst =>
+      keyword is KeywordToken &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   /**
@@ -20323,7 +12020,8 @@
    * `false` even though they are implicitly final. (In other words, this is a
    * syntactic check rather than a semantic check.)
    */
-  bool get isFinal => keyword is KeywordToken &&
+  bool get isFinal =>
+      keyword is KeywordToken &&
       (keyword as KeywordToken).keyword == Keyword.FINAL;
 
   /**
@@ -20493,20 +12191,6 @@
   @override
   Token get endToken => _body.endToken;
 
-  /**
-   * Return the token representing the 'while' keyword.
-   */
-  @deprecated // Use "this.whileKeyword"
-  Token get keyword => whileKeyword;
-
-  /**
-   * Set the token representing the 'while' keyword to the given [token].
-   */
-  @deprecated // Use "this.whileKeyword"
-  set keyword(Token token) {
-    whileKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitWhileStatement(this);
 
@@ -20554,14 +12238,6 @@
   Token get endToken => _mixinTypes.endToken;
 
   /**
-   * Set the token representing the 'with' keyword to the given [token].
-   */
-  @deprecated // Use "this.withKeyword"
-  void set mixinKeyword(Token token) {
-    this.withKeyword = token;
-  }
-
-  /**
    * Return the names of the mixins that were specified.
    */
   NodeList<TypeName> get mixinTypes => _mixinTypes;
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index aca4af5..a561978 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -2,25 +2,30 @@
 // for 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 engine.constant;
+library analyzer.src.generated.constant;
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisEngine, RecordingErrorListener;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
+import 'package:analyzer/src/generated/source.dart' show Source;
+import 'package:analyzer/src/generated/type_system.dart'
+    show TypeSystem, TypeSystemImpl;
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/task/dart.dart';
 
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart' show AnalysisEngine, RecordingErrorListener;
-import 'error.dart';
-import 'java_core.dart';
-import 'resolver.dart' show TypeProvider, TypeSystem, TypeSystemImpl;
-import 'scanner.dart' show Token, TokenType;
-import 'source.dart' show Source;
-import 'utilities_collection.dart';
-import 'utilities_dart.dart' show ParameterKind;
-
 /**
  * Callback used by [ReferenceFinder] to report that a dependency was found.
  */
@@ -56,9 +61,6 @@
   BoolState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : (value ? 2 : 3);
 
   @override
@@ -187,6 +189,13 @@
     invocation.staticElement = node.staticElement;
     return invocation;
   }
+
+  @override
+  TypeName visitTypeName(TypeName node) {
+    TypeName typeName = super.visitTypeName(node);
+    typeName.type = node.type;
+    return typeName;
+  }
 }
 
 /**
@@ -703,16 +712,24 @@
           field is ConstFieldElementImpl) {
         validator.beforeGetFieldEvaluationResult(field);
         EvaluationResultImpl evaluationResult = field.evaluationResult;
+        // It is possible that the evaluation result is null.
+        // This happens for example when we have duplicate fields.
+        // class Test {final x = 1; final x = 2; const Test();}
+        if (evaluationResult == null) {
+          continue;
+        }
+        // Match the value and the type.
         DartType fieldType =
             FieldMember.from(field, constructor.returnType).type;
         DartObjectImpl fieldValue = evaluationResult.value;
         if (fieldValue != null && !runtimeTypeMatch(fieldValue, fieldType)) {
           errorReporter.reportErrorForNode(
-              CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+              CheckedModeCompileTimeErrorCode
+                  .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
               node,
               [fieldValue.type, field.name, fieldType]);
         }
-        fieldMap[field.name] = evaluationResult.value;
+        fieldMap[field.name] = fieldValue;
       }
     }
     // Now evaluate the constructor declaration.
@@ -756,7 +773,8 @@
       if (argumentValue != null) {
         if (!runtimeTypeMatch(argumentValue, parameter.type)) {
           errorReporter.reportErrorForNode(
-              CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+              CheckedModeCompileTimeErrorCode
+                  .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
               errorTarget,
               [argumentValue.type, parameter.type]);
         }
@@ -770,7 +788,8 @@
               // the field.
               if (!runtimeTypeMatch(argumentValue, fieldType)) {
                 errorReporter.reportErrorForNode(
-                    CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+                    CheckedModeCompileTimeErrorCode
+                        .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
                     errorTarget,
                     [argumentValue.type, fieldType]);
               }
@@ -812,7 +831,8 @@
             PropertyInducingElement field = getter.variable;
             if (!runtimeTypeMatch(evaluationResult, field.type)) {
               errorReporter.reportErrorForNode(
-                  CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+                  CheckedModeCompileTimeErrorCode
+                      .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
                   node,
                   [evaluationResult.type, fieldName, field.type]);
             }
@@ -986,7 +1006,8 @@
    * Determine whether the given string is a valid name for a public symbol
    * (i.e. whether it is allowed for a call to the Symbol constructor).
    */
-  static bool isValidPublicSymbol(String name) => name.isEmpty ||
+  static bool isValidPublicSymbol(String name) =>
+      name.isEmpty ||
       name == "void" ||
       new JavaPatternMatcher(_PUBLIC_SYMBOL_PATTERN, name).matches();
 
@@ -1209,6 +1230,59 @@
 
 /**
  * A visitor used to traverse the AST structures of all of the compilation units
+ * being resolved and build the full set of dependencies for all constant
+ * expressions.
+ */
+class ConstantExpressionsDependenciesFinder extends RecursiveAstVisitor {
+  /**
+   * The constants whose values need to be computed.
+   */
+  HashSet<ConstantEvaluationTarget> dependencies =
+      new HashSet<ConstantEvaluationTarget>();
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    if (node.isConst) {
+      _find(node);
+    } else {
+      super.visitInstanceCreationExpression(node);
+    }
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    if (node.constKeyword != null) {
+      _find(node);
+    } else {
+      super.visitListLiteral(node);
+    }
+  }
+
+  @override
+  void visitMapLiteral(MapLiteral node) {
+    if (node.constKeyword != null) {
+      _find(node);
+    } else {
+      super.visitMapLiteral(node);
+    }
+  }
+
+  @override
+  void visitSwitchCase(SwitchCase node) {
+    _find(node.expression);
+    node.statements.accept(this);
+  }
+
+  void _find(Expression node) {
+    if (node != null) {
+      ReferenceFinder referenceFinder = new ReferenceFinder(dependencies.add);
+      node.accept(referenceFinder);
+    }
+  }
+}
+
+/**
+ * A visitor used to traverse the AST structures of all of the compilation units
  * being resolved and build tables of the constant variables, constant
  * constructors, constant constructor invocations, and annotations found in
  * those compilation units.
@@ -1270,6 +1344,16 @@
   }
 
   @override
+  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    super.visitDefaultFormalParameter(node);
+    Expression defaultValue = node.defaultValue;
+    if (defaultValue != null && node.element != null) {
+      constantsToCompute.add(node.element);
+    }
+    return null;
+  }
+
+  @override
   Object visitVariableDeclaration(VariableDeclaration node) {
     super.visitVariableDeclaration(node);
     Expression initializer = node.initializer;
@@ -1964,33 +2048,6 @@
  */
 abstract class DartObject {
   /**
-   * Return the boolean value of this object, or `null` if either the value of
-   * this object is not known or this object is not of type 'bool'.
-   *
-   * Deprecated. Use [toBoolValue].
-   */
-  @deprecated
-  bool get boolValue;
-
-  /**
-   * Return the floating point value of this object, or `null` if either the
-   * value of this object is not known or this object is not of type 'double'.
-   *
-   * Deprecated. Use [toDoubleValue].
-   */
-  @deprecated
-  double get doubleValue;
-
-  /**
-   * Return `true` if this object's value can be represented exactly.
-   *
-   * Deprecated. The semantics of this method were not clear. One semantic is
-   * covered by [hasKnownValue].
-   */
-  @deprecated
-  bool get hasExactValue;
-
-  /**
    * Return `true` if the value of the object being represented is known.
    *
    * This method will return `false` if
@@ -2009,45 +2066,11 @@
   bool get hasKnownValue;
 
   /**
-   * Return the integer value of this object, or `null` if either the value of
-   * this object is not known or this object is not of type 'int'.
-   *
-   * Deprecated. Use [toIntValue].
-   */
-  @deprecated
-  int get intValue;
-
-  /**
-   * Return `true` if this object represents the value 'false'.
-   *
-   * Deprecated. Use `object.toBoolValue() == false`.
-   */
-  @deprecated
-  bool get isFalse;
-
-  /**
    * Return `true` if the object being represented represents the value 'null'.
    */
   bool get isNull;
 
   /**
-   * Return `true` if this object represents the value 'true'.
-   *
-   * Deprecated. Use `object.toBoolValue() == true`.
-   */
-  @deprecated
-  bool get isTrue;
-
-  /**
-   * Return the string value of this object, or `null` if either the value of
-   * this object is not known or this object is not of type 'String'.
-   *
-   * Deprecated. Use [toStringValue].
-   */
-  @deprecated
-  String get stringValue;
-
-  /**
    * Return a representation of the type of the object being represented.
    *
    * For values resulting from the invocation of a 'const' constructor, this
@@ -2072,16 +2095,6 @@
   ParameterizedType get type;
 
   /**
-   * Return this object's value if it can be represented exactly, or `null` if
-   * either the value cannot be represented exactly or if the value is `null`.
-   * Clients should use `hasExactValue` to distinguish between these two cases.
-   *
-   * Deprecated. Use one of the `isXValue()` methods.
-   */
-  @deprecated
-  Object get value;
-
-  /**
    * Return a representation of the value of the field with the given [name].
    *
    * Return `null` if either the object being represented does not have a field
@@ -2161,7 +2174,7 @@
    * * this object is not of type 'Type', or
    * * the value of the object being represented is `null`.
    */
-  ParameterizedType toTypeValue();
+  DartType toTypeValue();
 }
 
 /**
@@ -2558,30 +2571,14 @@
     return new DartObjectImpl(type, GenericState.UNKNOWN_VALUE);
   }
 
-  @deprecated
-  @override
-  bool get boolValue => toBoolValue();
-
-  @deprecated
-  @override
-  double get doubleValue => toDoubleValue();
-
   HashMap<String, DartObjectImpl> get fields => _state.fields;
 
-  @deprecated
-  @override
-  bool get hasExactValue => _state.hasExactValue;
-
   @override
   int get hashCode => JenkinsSmiHash.hash2(type.hashCode, _state.hashCode);
 
   @override
   bool get hasKnownValue => !_state.isUnknown;
 
-  @deprecated
-  @override
-  int get intValue => toIntValue();
-
   /**
    * Return `true` if this object represents an object whose type is 'bool'.
    */
@@ -2593,18 +2590,9 @@
    */
   bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
 
-  @deprecated
-  @override
-  bool get isFalse => toBoolValue() == false;
-
   @override
   bool get isNull => _state is NullState;
 
-  @deprecated
-  @override
-  bool get isTrue =>
-      _state is BoolState && identical((_state as BoolState).value, true);
-
   /**
    * Return `true` if this object represents an unknown value.
    */
@@ -2616,14 +2604,6 @@
    */
   bool get isUserDefinedObject => _state is GenericState;
 
-  @deprecated
-  @override
-  String get stringValue => toStringValue();
-
-  @deprecated
-  @override
-  Object get value => _state.value;
-
   @override
   bool operator ==(Object object) {
     if (object is! DartObjectImpl) {
@@ -3122,13 +3102,10 @@
   }
 
   @override
-  ParameterizedType toTypeValue() {
+  DartType toTypeValue() {
     if (_state is TypeState) {
-      Element element = (_state as TypeState).value;
-      if (element is ClassElement) {
-        return element.type;
-      }
-      if (element is FunctionElement) {
+      Element element = (_state as TypeState)._element;
+      if (element is TypeDefiningElement) {
         return element.type;
       }
     }
@@ -3232,9 +3209,6 @@
   DoubleState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
@@ -3809,14 +3783,6 @@
     this._errors = errors == null ? <AnalysisError>[] : errors;
   }
 
-  @deprecated // Use new EvaluationResultImpl(value)
-  EvaluationResultImpl.con1(this.value) {
-    this._errors = new List<AnalysisError>(0);
-  }
-
-  @deprecated // Use new EvaluationResultImpl(value, errors)
-  EvaluationResultImpl.con2(this.value, List<AnalysisError> this._errors);
-
   List<AnalysisError> get errors => _errors;
 
   bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) {
@@ -4013,11 +3979,6 @@
   HashMap<String, DartObjectImpl> get fields => null;
 
   /**
-   * Return `true` if this object's value can be represented exactly.
-   */
-  bool get hasExactValue => false;
-
-  /**
    * Return `true` if this object represents an object whose type is 'bool'.
    */
   bool get isBool => false;
@@ -4039,13 +4000,6 @@
   String get typeName;
 
   /**
-   * Return this object's value if it can be represented exactly, or `null` if
-   * either the value cannot be represented exactly or if the value is `null`.
-   * Clients should use [hasExactValue] to distinguish between these two cases.
-   */
-  Object get value => null;
-
-  /**
    * Return the result of invoking the '+' operator on this object with the
    * [rightOperand].
    *
@@ -4440,9 +4394,6 @@
   IntState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
@@ -4899,17 +4850,6 @@
   ListState(this._elements);
 
   @override
-  bool get hasExactValue {
-    int count = _elements.length;
-    for (int i = 0; i < count; i++) {
-      if (!_elements[i].hasExactValue) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @override
   int get hashCode {
     int value = 0;
     int count = _elements.length;
@@ -4923,20 +4863,6 @@
   String get typeName => "List";
 
   @override
-  List<Object> get value {
-    int count = _elements.length;
-    List<Object> result = new List<Object>(count);
-    for (int i = 0; i < count; i++) {
-      DartObjectImpl element = _elements[i];
-      if (!element.hasExactValue) {
-        return null;
-      }
-      result[i] = element.value;
-    }
-    return result;
-  }
-
-  @override
   bool operator ==(Object object) {
     if (object is! ListState) {
       return false;
@@ -5007,16 +4933,6 @@
   MapState(this._entries);
 
   @override
-  bool get hasExactValue {
-    for (DartObjectImpl key in _entries.keys) {
-      if (!key.hasExactValue || !_entries[key].hasExactValue) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @override
   int get hashCode {
     int value = 0;
     for (DartObjectImpl key in _entries.keys.toSet()) {
@@ -5029,19 +4945,6 @@
   String get typeName => "Map";
 
   @override
-  Map<Object, Object> get value {
-    HashMap<Object, Object> result = new HashMap<Object, Object>();
-    for (DartObjectImpl key in _entries.keys) {
-      DartObjectImpl value = _entries[key];
-      if (!key.hasExactValue || !value.hasExactValue) {
-        return null;
-      }
-      result[key.value] = value.value;
-    }
-    return result;
-  }
-
-  @override
   bool operator ==(Object object) {
     if (object is! MapState) {
       return false;
@@ -5111,9 +5014,6 @@
   static NullState NULL_STATE = new NullState();
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => 0;
 
   @override
@@ -5370,9 +5270,6 @@
   StringState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
@@ -5458,9 +5355,6 @@
   SymbolState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
@@ -5526,9 +5420,6 @@
   String get typeName => "Type";
 
   @override
-  Element get value => _element;
-
-  @override
   bool operator ==(Object object) =>
       object is TypeState && (_element == object._element);
 
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 7085b8d..968d797 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -2,10975 +2,22 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.element;
-
-import 'dart:collection';
-import 'dart:math' show min;
-
-import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/model.dart'
-    show AnalysisTarget, ConstantEvaluationTarget;
-
-import 'ast.dart';
-import 'constant.dart' show DartObject, EvaluationResultImpl;
-import 'engine.dart' show AnalysisContext, AnalysisEngine, AnalysisException;
-import 'html.dart' show XmlAttributeNode, XmlTagNode;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'resolver.dart';
-import 'scanner.dart' show Keyword;
-import 'sdk.dart' show DartSdk;
-import 'source.dart';
-import 'utilities_collection.dart';
-import 'utilities_dart.dart';
-
 /**
- * For AST nodes that could be in both the getter and setter contexts
- * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
- * elements are stored in the AST node, in an [AuxiliaryElements]. Because
- * resolved elements are either statically resolved or resolved using propagated
- * type information, this class is a wrapper for a pair of [ExecutableElement]s,
- * not just a single [ExecutableElement].
- */
-class AuxiliaryElements {
-  /**
-   * The element based on propagated type information, or `null` if the AST
-   * structure has not been resolved or if the node could not be resolved.
-   */
-  final ExecutableElement propagatedElement;
-
-  /**
-   * The element based on static type information, or `null` if the AST
-   * structure has not been resolved or if the node could not be resolved.
-   */
-  final ExecutableElement staticElement;
-
-  /**
-   * Initialize a newly created pair to have both the [staticElement] and the
-   * [propagatedElement].
-   */
-  AuxiliaryElements(this.staticElement, this.propagatedElement);
-}
-
-/**
- * A [Type] that represents the type 'bottom'.
- */
-class BottomTypeImpl extends TypeImpl {
-  /**
-   * The unique instance of this class.
-   */
-  static BottomTypeImpl _INSTANCE = new BottomTypeImpl._();
-
-  /**
-   * Return the unique instance of this class.
-   */
-  static BottomTypeImpl get instance => _INSTANCE;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  BottomTypeImpl._() : super(null, "<bottom>");
-
-  @override
-  int get hashCode => 0;
-
-  @override
-  bool get isBottom => true;
-
-  @override
-  bool operator ==(Object object) => identical(object, this);
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-          [bool withDynamic = false, Set<Element> visitedElements]) =>
-      true;
-
-  @override
-  bool isSubtypeOf(DartType type) => true;
-
-  @override
-  bool isSupertypeOf(DartType type) => false;
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  BottomTypeImpl substitute2(
-          List<DartType> argumentTypes, List<DartType> parameterTypes,
-          [List<FunctionTypeAliasElement> prune]) =>
-      this;
-}
-
-/**
- * Type created internally if a circular reference is ever detected.  Behaves
- * like `dynamic`, except that when converted to a string it is displayed as
- * `...`.
- */
-class CircularTypeImpl extends DynamicTypeImpl {
-  CircularTypeImpl() : super._circular();
-
-  @override
-  int get hashCode => 1;
-
-  @override
-  bool operator ==(Object object) => object is CircularTypeImpl;
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write('...');
-  }
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-}
-
-/**
- * An element that represents a class.
- */
-abstract class ClassElement implements TypeDefiningElement {
-  /**
-   * An empty list of class elements.
-   */
-  static const List<ClassElement> EMPTY_LIST = const <ClassElement>[];
-
-  /**
-   * Return a list containing all of the accessors (getters and setters)
-   * declared in this class.
-   */
-  List<PropertyAccessorElement> get accessors;
-
-  /**
-   * Return a list containing all the supertypes defined for this class and its
-   * supertypes. This includes superclasses, mixins and interfaces.
-   */
-  List<InterfaceType> get allSupertypes;
-
-  /**
-   * Return a list containing all of the constructors declared in this class.
-   */
-  List<ConstructorElement> get constructors;
-
-  /**
-   * Return a list containing all of the fields declared in this class.
-   */
-  List<FieldElement> get fields;
-
-  /**
-   * Return `true` if this class or its superclass declares a non-final instance
-   * field.
-   */
-  bool get hasNonFinalField;
-
-  /**
-   * Return `true` if this class has reference to super (so, for example, cannot
-   * be used as a mixin).
-   */
-  bool get hasReferenceToSuper;
-
-  /**
-   * Return `true` if this class declares a static member.
-   */
-  bool get hasStaticMember;
-
-  /**
-   * Return a list containing all of the interfaces that are implemented by this
-   * class.
-   *
-   * <b>Note:</b> Because the element model represents the state of the code, it
-   * is possible for it to be semantically invalid. In particular, it is not
-   * safe to assume that the inheritance structure of a class does not contain a
-   * cycle. Clients that traverse the inheritance structure must explicitly
-   * guard against infinite loops.
-   */
-  List<InterfaceType> get interfaces;
-
-  /**
-   * Return `true` if this class is abstract. A class is abstract if it has an
-   * explicit `abstract` modifier. Note, that this definition of <i>abstract</i>
-   * is different from <i>has unimplemented members</i>.
-   */
-  bool get isAbstract;
-
-  /**
-   * Return `true` if this class is defined by an enum declaration.
-   */
-  bool get isEnum;
-
-  /**
-   * Return `true` if this class is a mixin application.  A class is a mixin
-   * application if it was declared using the syntax "class A = B with C;".
-   */
-  bool get isMixinApplication;
-
-  /**
-   * Return `true` if this class [isProxy], or if it inherits the proxy
-   * annotation from a supertype.
-   */
-  bool get isOrInheritsProxy;
-
-  /**
-   * Return `true` if this element has an annotation of the form '@proxy'.
-   */
-  bool get isProxy;
-
-  /**
-   * Return `true` if this class is a mixin application.  Deprecated--please
-   * use [isMixinApplication] instead.
-   */
-  @deprecated
-  bool get isTypedef;
-
-  /**
-   * Return `true` if this class can validly be used as a mixin when defining
-   * another class. The behavior of this method is defined by the Dart Language
-   * Specification in section 9:
-   * <blockquote>
-   * It is a compile-time error if a declared or derived mixin refers to super.
-   * It is a compile-time error if a declared or derived mixin explicitly
-   * declares a constructor. It is a compile-time error if a mixin is derived
-   * from a class whose superclass is not Object.
-   * </blockquote>
-   */
-  bool get isValidMixin;
-
-  /**
-   * Return a list containing all of the methods declared in this class.
-   */
-  List<MethodElement> get methods;
-
-  /**
-   * Return a list containing all of the mixins that are applied to the class
-   * being extended in order to derive the superclass of this class.
-   *
-   * <b>Note:</b> Because the element model represents the state of the code, it
-   * is possible for it to be semantically invalid. In particular, it is not
-   * safe to assume that the inheritance structure of a class does not contain a
-   * cycle. Clients that traverse the inheritance structure must explicitly
-   * guard against infinite loops.
-   */
-  List<InterfaceType> get mixins;
-
-  /**
-   * Return the superclass of this class, or `null` if the class represents the
-   * class 'Object'. All other classes will have a non-`null` superclass. If the
-   * superclass was not explicitly declared then the implicit superclass
-   * 'Object' will be returned.
-   *
-   * <b>Note:</b> Because the element model represents the state of the code, it
-   * is possible for it to be semantically invalid. In particular, it is not
-   * safe to assume that the inheritance structure of a class does not contain a
-   * cycle. Clients that traverse the inheritance structure must explicitly
-   * guard against infinite loops.
-   */
-  InterfaceType get supertype;
-
-  @override
-  InterfaceType get type;
-
-  /**
-   * Return a list containing all of the type parameters declared for this
-   * class.
-   */
-  List<TypeParameterElement> get typeParameters;
-
-  /**
-   * Return the unnamed constructor declared in this class, or `null` if this
-   * class does not declare an unnamed constructor but does declare named
-   * constructors. The returned constructor will be synthetic if this class does
-   * not declare any constructors, in which case it will represent the default
-   * constructor for the class.
-   */
-  ConstructorElement get unnamedConstructor;
-
-  /**
-   * Return the resolved [ClassDeclaration] or [EnumDeclaration] node that
-   * declares this [ClassElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  NamedCompilationUnitMember computeNode();
-
-  /**
-   * Return the field (synthetic or explicit) defined in this class that has the
-   * given [name], or `null` if this class does not define a field with the
-   * given name.
-   */
-  FieldElement getField(String name);
-
-  /**
-   * Return the element representing the getter with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a getter
-   * with the given name.
-   */
-  PropertyAccessorElement getGetter(String name);
-
-  /**
-   * Return the element representing the method with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a method
-   * with the given name.
-   */
-  MethodElement getMethod(String name);
-
-  /**
-   * Return the named constructor declared in this class with the given [name],
-   * or `null` if this class does not declare a named constructor with the given
-   * name.
-   */
-  ConstructorElement getNamedConstructor(String name);
-
-  /**
-   * Return the element representing the setter with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a setter
-   * with the given name.
-   */
-  PropertyAccessorElement getSetter(String name);
-
-  /**
-   * Determine whether the given [constructor], which exists in the superclass
-   * of this class, is accessible to constructors in this class.
-   */
-  bool isSuperConstructorAccessible(ConstructorElement constructor);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * given [methodName] in this class with respect to the given [library],
-   * ignoring abstract methods, or `null` if the look up fails. The behavior of
-   * this method is defined by the Dart Language Specification in section
-   * 16.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is: If <i>C</i> declares an instance method named <i>m</i>
-   * that is accessible to <i>L</i>, then that method is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up method <i>m</i> in <i>S</i> with
-   * respect to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  MethodElement lookUpConcreteMethod(String methodName, LibraryElement library);
-
-  /**
-   * Return the element representing the getter that results from looking up the
-   * given [getterName] in this class with respect to the given [library], or
-   * `null` if the look up fails. The behavior of this method is defined by the
-   * Dart Language Specification in section 16.15.2:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
-   * instance getter (respectively setter) named <i>m</i> that is accessible to
-   * <i>L</i>, then that getter (respectively setter) is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up getter (respectively setter)
-   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-   * lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpGetter(
-      String getterName, LibraryElement library);
-
-  /**
-   * Return the element representing the getter that results from looking up the
-   * given [getterName] in the superclass of this class with respect to the
-   * given [library], ignoring abstract getters, or `null` if the look up fails.
-   * The behavior of this method is defined by the Dart Language Specification
-   * in section 16.15.2:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
-   * instance getter (respectively setter) named <i>m</i> that is accessible to
-   * <i>L</i>, then that getter (respectively setter) is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up getter (respectively setter)
-   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-   * lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpInheritedConcreteGetter(
-      String getterName, LibraryElement library);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * given [methodName] in the superclass of this class with respect to the
-   * given [library], ignoring abstract methods, or `null` if the look up fails.
-   * The behavior of this method is defined by the Dart Language Specification
-   * in section 16.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:  If <i>C</i> declares an instance method named
-   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
-   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
-   * result of the lookup is the result of looking up method <i>m</i> in
-   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
-   * failed.
-   * </blockquote>
-   */
-  MethodElement lookUpInheritedConcreteMethod(
-      String methodName, LibraryElement library);
-
-  /**
-   * Return the element representing the setter that results from looking up the
-   * given [setterName] in the superclass of this class with respect to the
-   * given [library], ignoring abstract setters, or `null` if the look up fails.
-   * The behavior of this method is defined by the Dart Language Specification
-   * in section 16.15.2:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:  If <i>C</i> declares an
-   * instance getter (respectively setter) named <i>m</i> that is accessible to
-   * <i>L</i>, then that getter (respectively setter) is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up getter (respectively setter)
-   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-   * lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpInheritedConcreteSetter(
-      String setterName, LibraryElement library);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * given [methodName] in the superclass of this class with respect to the
-   * given [library], or `null` if the look up fails. The behavior of this
-   * method is defined by the Dart Language Specification in section 16.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:  If <i>C</i> declares an instance method named
-   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
-   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
-   * result of the lookup is the result of looking up method <i>m</i> in
-   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
-   * failed.
-   * </blockquote>
-   */
-  MethodElement lookUpInheritedMethod(
-      String methodName, LibraryElement library);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * given [methodName] in this class with respect to the given [library], or
-   * `null` if the look up fails. The behavior of this method is defined by the
-   * Dart Language Specification in section 16.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:  If <i>C</i> declares an instance method named
-   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
-   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
-   * result of the lookup is the result of looking up method <i>m</i> in
-   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
-   * failed.
-   * </blockquote>
-   */
-  MethodElement lookUpMethod(String methodName, LibraryElement library);
-
-  /**
-   * Return the element representing the setter that results from looking up the
-   * given [setterName] in this class with respect to the given [library], or
-   * `null` if the look up fails. The behavior of this method is defined by the
-   * Dart Language Specification in section 16.15.2:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
-   * instance getter (respectively setter) named <i>m</i> that is accessible to
-   * <i>L</i>, then that getter (respectively setter) is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up getter (respectively setter)
-   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-   * lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpSetter(
-      String setterName, LibraryElement library);
-}
-
-/**
- * A concrete implementation of a [ClassElement].
- */
-class ClassElementImpl extends ElementImpl implements ClassElement {
-  /**
-   * An empty list of class elements.
-   */
-  @deprecated // Use ClassElement.EMPTY_LIST
-  static const List<ClassElement> EMPTY_ARRAY = const <ClassElement>[];
-
-  /**
-   * A list containing all of the accessors (getters and setters) contained in
-   * this class.
-   */
-  List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
-
-  /**
-   * For classes which are not mixin applications, a list containing all of the
-   * constructors contained in this class, or `null` if the list of
-   * constructors has not yet been built.
-   *
-   * For classes which are mixin applications, the list of constructors is
-   * computed on the fly by the [constructors] getter, and this field is
-   * `null`.
-   */
-  List<ConstructorElement> _constructors;
-
-  /**
-   * A list containing all of the fields contained in this class.
-   */
-  List<FieldElement> _fields = FieldElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the mixins that are applied to the class being
-   * extended in order to derive the superclass of this class.
-   */
-  List<InterfaceType> mixins = InterfaceType.EMPTY_LIST;
-
-  /**
-   * A list containing all of the interfaces that are implemented by this class.
-   */
-  List<InterfaceType> interfaces = InterfaceType.EMPTY_LIST;
-
-  /**
-   * A list containing all of the methods contained in this class.
-   */
-  List<MethodElement> _methods = MethodElement.EMPTY_LIST;
-
-  /**
-   * The superclass of the class, or `null` if the class does not have an
-   * explicit superclass.
-   */
-  InterfaceType supertype;
-
-  /**
-   * The type defined by the class.
-   */
-  InterfaceType type;
-
-  /**
-   * A list containing all of the type parameters defined for this class.
-   */
-  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
-  /**
-   * The [SourceRange] of the `with` clause, `null` if there is no one.
-   */
-  SourceRange withClauseRange;
-
-  /**
-   * A flag indicating whether the types associated with the instance members of
-   * this class have been inferred.
-   */
-  bool hasBeenInferred = false;
-
-  /**
-   * Initialize a newly created class element to have the given [name] at the
-   * given [offset] in the file that contains the declaration of this element.
-   */
-  ClassElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created class element to have the given [name].
-   */
-  ClassElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this class is abstract.
-   */
-  void set abstract(bool isAbstract) {
-    setModifier(Modifier.ABSTRACT, isAbstract);
-  }
-
-  @override
-  List<PropertyAccessorElement> get accessors => _accessors;
-
-  /**
-   * Set the accessors contained in this class to the given [accessors].
-   */
-  void set accessors(List<PropertyAccessorElement> accessors) {
-    for (PropertyAccessorElement accessor in accessors) {
-      (accessor as PropertyAccessorElementImpl).enclosingElement = this;
-    }
-    this._accessors = accessors;
-  }
-
-  @override
-  List<InterfaceType> get allSupertypes {
-    List<InterfaceType> list = new List<InterfaceType>();
-    _collectAllSupertypes(list);
-    return list;
-  }
-
-  @override
-  List<ConstructorElement> get constructors {
-    if (!isMixinApplication) {
-      assert(_constructors != null);
-      return _constructors == null
-          ? ConstructorElement.EMPTY_LIST
-          : _constructors;
-    }
-
-    return _computeMixinAppConstructors();
-  }
-
-  /**
-   * Set the constructors contained in this class to the given [constructors].
-   *
-   * Should only be used for class elements that are not mixin applications.
-   */
-  void set constructors(List<ConstructorElement> constructors) {
-    assert(!isMixinApplication);
-    for (ConstructorElement constructor in constructors) {
-      (constructor as ConstructorElementImpl).enclosingElement = this;
-    }
-    this._constructors = constructors;
-  }
-
-  /**
-   * Return `true` if [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] should
-   * be reported for this class.
-   */
-  bool get doesMixinLackConstructors {
-    if (!isMixinApplication && mixins.isEmpty) {
-      // This class is not a mixin application and it doesn't have a "with"
-      // clause, so CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS is
-      // inapplicable.
-      return false;
-    }
-    if (supertype == null) {
-      // Should never happen, since Object is the only class that has no
-      // supertype, and it should have been caught by the test above.
-      assert(false);
-      return false;
-    }
-    // Find the nearest class in the supertype chain that is not a mixin
-    // application.
-    ClassElement nearestNonMixinClass = supertype.element;
-    if (nearestNonMixinClass.isMixinApplication) {
-      // Use a list to keep track of the classes we've seen, so that we won't
-      // go into an infinite loop in the event of a non-trivial loop in the
-      // class hierarchy.
-      List<ClassElementImpl> classesSeen = <ClassElementImpl>[this];
-      while (nearestNonMixinClass.isMixinApplication) {
-        if (classesSeen.contains(nearestNonMixinClass)) {
-          // Loop in the class hierarchy (which is reported elsewhere).  Don't
-          // confuse the user with further errors.
-          return false;
-        }
-        classesSeen.add(nearestNonMixinClass);
-        if (nearestNonMixinClass.supertype == null) {
-          // Should never happen, since Object is the only class that has no
-          // supertype, and it is not a mixin application.
-          assert(false);
-          return false;
-        }
-        nearestNonMixinClass = nearestNonMixinClass.supertype.element;
-      }
-    }
-    return !nearestNonMixinClass.constructors.any(isSuperConstructorAccessible);
-  }
-
-  /**
-   * Set whether this class is defined by an enum declaration.
-   */
-  void set enum2(bool isEnum) {
-    setModifier(Modifier.ENUM, isEnum);
-  }
-
-  @override
-  List<FieldElement> get fields => _fields;
-
-  /**
-   * Set the fields contained in this class to the given [fields].
-   */
-  void set fields(List<FieldElement> fields) {
-    for (FieldElement field in fields) {
-      (field as FieldElementImpl).enclosingElement = this;
-    }
-    this._fields = fields;
-  }
-
-  @override
-  bool get hasNonFinalField {
-    List<ClassElement> classesToVisit = new List<ClassElement>();
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    classesToVisit.add(this);
-    while (!classesToVisit.isEmpty) {
-      ClassElement currentElement = classesToVisit.removeAt(0);
-      if (visitedClasses.add(currentElement)) {
-        // check fields
-        for (FieldElement field in currentElement.fields) {
-          if (!field.isFinal &&
-              !field.isConst &&
-              !field.isStatic &&
-              !field.isSynthetic) {
-            return true;
-          }
-        }
-        // check mixins
-        for (InterfaceType mixinType in currentElement.mixins) {
-          ClassElement mixinElement = mixinType.element;
-          classesToVisit.add(mixinElement);
-        }
-        // check super
-        InterfaceType supertype = currentElement.supertype;
-        if (supertype != null) {
-          ClassElement superElement = supertype.element;
-          if (superElement != null) {
-            classesToVisit.add(superElement);
-          }
-        }
-      }
-    }
-    // not found
-    return false;
-  }
-
-  @override
-  bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
-
-  /**
-   * Set whether this class references 'super'.
-   */
-  void set hasReferenceToSuper(bool isReferencedSuper) {
-    setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
-  }
-
-  @override
-  bool get hasStaticMember {
-    for (MethodElement method in _methods) {
-      if (method.isStatic) {
-        return true;
-      }
-    }
-    for (PropertyAccessorElement accessor in _accessors) {
-      if (accessor.isStatic) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
-
-  @override
-  bool get isEnum => hasModifier(Modifier.ENUM);
-
-  @override
-  bool get isMixinApplication => hasModifier(Modifier.MIXIN_APPLICATION);
-
-  @override
-  bool get isOrInheritsProxy =>
-      _safeIsOrInheritsProxy(this, new HashSet<ClassElement>());
-
-  @override
-  bool get isProxy {
-    for (ElementAnnotation annotation in metadata) {
-      if (annotation.isProxy) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  @deprecated
-  bool get isTypedef => isMixinApplication;
-
-  @override
-  bool get isValidMixin => hasModifier(Modifier.MIXIN);
-
-  @override
-  ElementKind get kind => ElementKind.CLASS;
-
-  @override
-  List<MethodElement> get methods => _methods;
-
-  /**
-   * Set the methods contained in this class to the given [methods].
-   */
-  void set methods(List<MethodElement> methods) {
-    for (MethodElement method in methods) {
-      (method as MethodElementImpl).enclosingElement = this;
-    }
-    this._methods = methods;
-  }
-
-  /**
-   * Set whether this class is a mixin application.
-   */
-  void set mixinApplication(bool isMixinApplication) {
-    setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters defined for this class to the given
-   * [typeParameters].
-   */
-  void set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement typeParameter in typeParameters) {
-      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    this._typeParameters = typeParameters;
-  }
-
-  @override
-  ConstructorElement get unnamedConstructor {
-    for (ConstructorElement element in constructors) {
-      String name = element.displayName;
-      if (name == null || name.isEmpty) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Set whether this class is a valid mixin.
-   */
-  void set validMixin(bool isValidMixin) {
-    setModifier(Modifier.MIXIN, isValidMixin);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitClassElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    String name = displayName;
-    if (name == null) {
-      buffer.write("{unnamed class}");
-    } else {
-      buffer.write(name);
-    }
-    int variableCount = _typeParameters.length;
-    if (variableCount > 0) {
-      buffer.write("<");
-      for (int i = 0; i < variableCount; i++) {
-        if (i > 0) {
-          buffer.write(", ");
-        }
-        (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
-      }
-      buffer.write(">");
-    }
-  }
-
-  @override
-  NamedCompilationUnitMember computeNode() {
-    if (isEnum) {
-      return getNodeMatching((node) => node is EnumDeclaration);
-    } else {
-      return getNodeMatching(
-          (node) => node is ClassDeclaration || node is ClassTypeAlias);
-    }
-  }
-
-  @override
-  ElementImpl getChild(String identifier) {
-    //
-    // The casts in this method are safe because the set methods would have
-    // thrown a CCE if any of the elements in the arrays were not of the
-    // expected types.
-    //
-    for (PropertyAccessorElement accessor in _accessors) {
-      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
-        return accessor as PropertyAccessorElementImpl;
-      }
-    }
-    for (ConstructorElement constructor in _constructors) {
-      if ((constructor as ConstructorElementImpl).identifier == identifier) {
-        return constructor as ConstructorElementImpl;
-      }
-    }
-    for (FieldElement field in _fields) {
-      if ((field as FieldElementImpl).identifier == identifier) {
-        return field as FieldElementImpl;
-      }
-    }
-    for (MethodElement method in _methods) {
-      if ((method as MethodElementImpl).identifier == identifier) {
-        return method as MethodElementImpl;
-      }
-    }
-    for (TypeParameterElement typeParameter in _typeParameters) {
-      if ((typeParameter as TypeParameterElementImpl).identifier ==
-          identifier) {
-        return typeParameter as TypeParameterElementImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
-  FieldElement getField(String name) {
-    for (FieldElement fieldElement in _fields) {
-      if (name == fieldElement.name) {
-        return fieldElement;
-      }
-    }
-    return null;
-  }
-
-  @override
-  PropertyAccessorElement getGetter(String getterName) {
-    for (PropertyAccessorElement accessor in _accessors) {
-      if (accessor.isGetter && accessor.name == getterName) {
-        return accessor;
-      }
-    }
-    return null;
-  }
-
-  @override
-  MethodElement getMethod(String methodName) {
-    for (MethodElement method in _methods) {
-      if (method.name == methodName) {
-        return method;
-      }
-    }
-    return null;
-  }
-
-  @override
-  ConstructorElement getNamedConstructor(String name) {
-    for (ConstructorElement element in constructors) {
-      String elementName = element.name;
-      if (elementName != null && elementName == name) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  @override
-  PropertyAccessorElement getSetter(String setterName) {
-    // TODO (jwren) revisit- should we append '=' here or require clients to
-    // include it?
-    // Do we need the check for isSetter below?
-    if (!StringUtilities.endsWithChar(setterName, 0x3D)) {
-      setterName += '=';
-    }
-    for (PropertyAccessorElement accessor in _accessors) {
-      if (accessor.isSetter && accessor.name == setterName) {
-        return accessor;
-      }
-    }
-    return null;
-  }
-
-  @override
-  bool isSuperConstructorAccessible(ConstructorElement constructor) {
-    // If this class has no mixins, then all superclass constructors are
-    // accessible.
-    if (mixins.isEmpty) {
-      return true;
-    }
-    // Otherwise only constructors that lack optional parameters are
-    // accessible (see dartbug.com/19576).
-    for (ParameterElement parameter in constructor.parameters) {
-      if (parameter.parameterKind != ParameterKind.REQUIRED) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @override
-  MethodElement lookUpConcreteMethod(
-          String methodName, LibraryElement library) =>
-      _internalLookUpConcreteMethod(methodName, library, true);
-
-  @override
-  PropertyAccessorElement lookUpGetter(
-          String getterName, LibraryElement library) =>
-      _internalLookUpGetter(getterName, library, true);
-
-  @override
-  PropertyAccessorElement lookUpInheritedConcreteGetter(
-          String getterName, LibraryElement library) =>
-      _internalLookUpConcreteGetter(getterName, library, false);
-
-  @override
-  MethodElement lookUpInheritedConcreteMethod(
-          String methodName, LibraryElement library) =>
-      _internalLookUpConcreteMethod(methodName, library, false);
-
-  @override
-  PropertyAccessorElement lookUpInheritedConcreteSetter(
-          String setterName, LibraryElement library) =>
-      _internalLookUpConcreteSetter(setterName, library, false);
-
-  @override
-  MethodElement lookUpInheritedMethod(
-          String methodName, LibraryElement library) =>
-      _internalLookUpMethod(methodName, library, false);
-
-  @override
-  MethodElement lookUpMethod(String methodName, LibraryElement library) =>
-      _internalLookUpMethod(methodName, library, true);
-
-  @override
-  PropertyAccessorElement lookUpSetter(
-          String setterName, LibraryElement library) =>
-      _internalLookUpSetter(setterName, library, true);
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_accessors, visitor);
-    safelyVisitChildren(_constructors, visitor);
-    safelyVisitChildren(_fields, visitor);
-    safelyVisitChildren(_methods, visitor);
-    safelyVisitChildren(_typeParameters, visitor);
-  }
-
-  void _collectAllSupertypes(List<InterfaceType> supertypes) {
-    List<InterfaceType> typesToVisit = new List<InterfaceType>();
-    List<ClassElement> visitedClasses = new List<ClassElement>();
-    typesToVisit.add(this.type);
-    while (!typesToVisit.isEmpty) {
-      InterfaceType currentType = typesToVisit.removeAt(0);
-      ClassElement currentElement = currentType.element;
-      if (!visitedClasses.contains(currentElement)) {
-        visitedClasses.add(currentElement);
-        if (!identical(currentType, this.type)) {
-          supertypes.add(currentType);
-        }
-        InterfaceType supertype = currentType.superclass;
-        if (supertype != null) {
-          typesToVisit.add(supertype);
-        }
-        for (InterfaceType type in currentElement.interfaces) {
-          typesToVisit.add(type);
-        }
-        for (InterfaceType type in currentElement.mixins) {
-          ClassElement element = type.element;
-          if (!visitedClasses.contains(element)) {
-            supertypes.add(type);
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Compute a list of constructors for this class, which is a mixin
-   * application.  If specified, [visitedClasses] is a list of the other mixin
-   * application classes which have been visited on the way to reaching this
-   * one (this is used to detect circularities).
-   */
-  List<ConstructorElement> _computeMixinAppConstructors(
-      [List<ClassElementImpl> visitedClasses = null]) {
-    // First get the list of constructors of the superclass which need to be
-    // forwarded to this class.
-    Iterable<ConstructorElement> constructorsToForward;
-    if (supertype == null) {
-      // Shouldn't ever happen, since the only class with no supertype is
-      // Object, and it isn't a mixin application.  But for safety's sake just
-      // assume an empty list.
-      assert(false);
-      constructorsToForward = <ConstructorElement>[];
-    } else if (!supertype.element.isMixinApplication) {
-      List<ConstructorElement> superclassConstructors =
-          supertype.element.constructors;
-      // Filter out any constructors with optional parameters (see
-      // dartbug.com/15101).
-      constructorsToForward =
-          superclassConstructors.where(isSuperConstructorAccessible);
-    } else {
-      if (visitedClasses == null) {
-        visitedClasses = <ClassElementImpl>[this];
-      } else {
-        if (visitedClasses.contains(this)) {
-          // Loop in the class hierarchy.  Don't try to forward any
-          // constructors.
-          return <ConstructorElement>[];
-        }
-        visitedClasses.add(this);
-      }
-      try {
-        ClassElementImpl superclass = supertype.element;
-        constructorsToForward =
-            superclass._computeMixinAppConstructors(visitedClasses);
-      } finally {
-        visitedClasses.removeLast();
-      }
-    }
-
-    // Figure out the type parameter substitution we need to perform in order
-    // to produce constructors for this class.  We want to be robust in the
-    // face of errors, so drop any extra type arguments and fill in any missing
-    // ones with `dynamic`.
-    List<DartType> parameterTypes =
-        TypeParameterTypeImpl.getTypes(supertype.typeParameters);
-    List<DartType> argumentTypes = new List<DartType>.filled(
-        parameterTypes.length, DynamicTypeImpl.instance);
-    for (int i = 0; i < supertype.typeArguments.length; i++) {
-      if (i >= argumentTypes.length) {
-        break;
-      }
-      argumentTypes[i] = supertype.typeArguments[i];
-    }
-
-    // Now create an implicit constructor for every constructor found above,
-    // substituting type parameters as appropriate.
-    return constructorsToForward
-        .map((ConstructorElement superclassConstructor) {
-      ConstructorElementImpl implicitConstructor =
-          new ConstructorElementImpl(superclassConstructor.name, -1);
-      implicitConstructor.synthetic = true;
-      implicitConstructor.redirectedConstructor = superclassConstructor;
-      implicitConstructor.const2 = superclassConstructor.isConst;
-      implicitConstructor.returnType = type;
-      List<ParameterElement> superParameters = superclassConstructor.parameters;
-      int count = superParameters.length;
-      if (count > 0) {
-        List<ParameterElement> implicitParameters =
-            new List<ParameterElement>(count);
-        for (int i = 0; i < count; i++) {
-          ParameterElement superParameter = superParameters[i];
-          ParameterElementImpl implicitParameter =
-              new ParameterElementImpl(superParameter.name, -1);
-          implicitParameter.const3 = superParameter.isConst;
-          implicitParameter.final2 = superParameter.isFinal;
-          implicitParameter.parameterKind = superParameter.parameterKind;
-          implicitParameter.synthetic = true;
-          implicitParameter.type =
-              superParameter.type.substitute2(argumentTypes, parameterTypes);
-          implicitParameters[i] = implicitParameter;
-        }
-        implicitConstructor.parameters = implicitParameters;
-      }
-      FunctionTypeImpl constructorType =
-          new FunctionTypeImpl(implicitConstructor);
-      constructorType.typeArguments = type.typeArguments;
-      implicitConstructor.type = constructorType;
-      implicitConstructor.enclosingElement = this;
-      return implicitConstructor;
-    }).toList();
-  }
-
-  PropertyAccessorElement _internalLookUpConcreteGetter(
-      String getterName, LibraryElement library, bool includeThisClass) {
-    PropertyAccessorElement getter =
-        _internalLookUpGetter(getterName, library, includeThisClass);
-    while (getter != null && getter.isAbstract) {
-      Element definingClass = getter.enclosingElement;
-      if (definingClass is! ClassElementImpl) {
-        return null;
-      }
-      getter = (definingClass as ClassElementImpl)
-          ._internalLookUpGetter(getterName, library, false);
-    }
-    return getter;
-  }
-
-  MethodElement _internalLookUpConcreteMethod(
-      String methodName, LibraryElement library, bool includeThisClass) {
-    MethodElement method =
-        _internalLookUpMethod(methodName, library, includeThisClass);
-    while (method != null && method.isAbstract) {
-      ClassElement definingClass = method.enclosingElement;
-      if (definingClass == null) {
-        return null;
-      }
-      method = definingClass.lookUpInheritedMethod(methodName, library);
-    }
-    return method;
-  }
-
-  PropertyAccessorElement _internalLookUpConcreteSetter(
-      String setterName, LibraryElement library, bool includeThisClass) {
-    PropertyAccessorElement setter =
-        _internalLookUpSetter(setterName, library, includeThisClass);
-    while (setter != null && setter.isAbstract) {
-      Element definingClass = setter.enclosingElement;
-      if (definingClass is! ClassElementImpl) {
-        return null;
-      }
-      setter = (definingClass as ClassElementImpl)
-          ._internalLookUpSetter(setterName, library, false);
-    }
-    return setter;
-  }
-
-  PropertyAccessorElement _internalLookUpGetter(
-      String getterName, LibraryElement library, bool includeThisClass) {
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    ClassElement currentElement = this;
-    if (includeThisClass) {
-      PropertyAccessorElement element = currentElement.getGetter(getterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    while (currentElement != null && visitedClasses.add(currentElement)) {
-      for (InterfaceType mixin in currentElement.mixins.reversed) {
-        ClassElement mixinElement = mixin.element;
-        if (mixinElement != null) {
-          PropertyAccessorElement element = mixinElement.getGetter(getterName);
-          if (element != null && element.isAccessibleIn(library)) {
-            return element;
-          }
-        }
-      }
-      InterfaceType supertype = currentElement.supertype;
-      if (supertype == null) {
-        return null;
-      }
-      currentElement = supertype.element;
-      PropertyAccessorElement element = currentElement.getGetter(getterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  MethodElement _internalLookUpMethod(
-      String methodName, LibraryElement library, bool includeThisClass) {
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    ClassElement currentElement = this;
-    if (includeThisClass) {
-      MethodElement element = currentElement.getMethod(methodName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    while (currentElement != null && visitedClasses.add(currentElement)) {
-      for (InterfaceType mixin in currentElement.mixins.reversed) {
-        ClassElement mixinElement = mixin.element;
-        if (mixinElement != null) {
-          MethodElement element = mixinElement.getMethod(methodName);
-          if (element != null && element.isAccessibleIn(library)) {
-            return element;
-          }
-        }
-      }
-      InterfaceType supertype = currentElement.supertype;
-      if (supertype == null) {
-        return null;
-      }
-      currentElement = supertype.element;
-      MethodElement element = currentElement.getMethod(methodName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  PropertyAccessorElement _internalLookUpSetter(
-      String setterName, LibraryElement library, bool includeThisClass) {
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    ClassElement currentElement = this;
-    if (includeThisClass) {
-      PropertyAccessorElement element = currentElement.getSetter(setterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    while (currentElement != null && visitedClasses.add(currentElement)) {
-      for (InterfaceType mixin in currentElement.mixins.reversed) {
-        ClassElement mixinElement = mixin.element;
-        if (mixinElement != null) {
-          PropertyAccessorElement element = mixinElement.getSetter(setterName);
-          if (element != null && element.isAccessibleIn(library)) {
-            return element;
-          }
-        }
-      }
-      InterfaceType supertype = currentElement.supertype;
-      if (supertype == null) {
-        return null;
-      }
-      currentElement = supertype.element;
-      PropertyAccessorElement element = currentElement.getSetter(setterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  bool _safeIsOrInheritsProxy(
-      ClassElement classElt, HashSet<ClassElement> visitedClassElts) {
-    if (visitedClassElts.contains(classElt)) {
-      return false;
-    }
-    visitedClassElts.add(classElt);
-    if (classElt.isProxy) {
-      return true;
-    } else if (classElt.supertype != null &&
-        _safeIsOrInheritsProxy(classElt.supertype.element, visitedClassElts)) {
-      return true;
-    }
-    List<InterfaceType> supertypes = classElt.interfaces;
-    for (int i = 0; i < supertypes.length; i++) {
-      if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
-        return true;
-      }
-    }
-    supertypes = classElt.mixins;
-    for (int i = 0; i < supertypes.length; i++) {
-      if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-/**
- * An element that is contained within a [ClassElement].
- */
-abstract class ClassMemberElement implements Element {
-  /**
-   * Return the type in which this member is defined.
-   */
-  @override
-  ClassElement get enclosingElement;
-
-  /**
-   * Return `true` if this element is a static element. A static element is an
-   * element that is not associated with a particular instance, but rather with
-   * an entire library or class.
-   */
-  bool get isStatic;
-}
-
-/**
- * An element representing a compilation unit.
- */
-abstract class CompilationUnitElement implements Element, UriReferencedElement {
-  /**
-   * An empty list of compilation unit elements.
-   */
-  static const List<CompilationUnitElement> EMPTY_LIST =
-      const <CompilationUnitElement>[];
-
-  /**
-   * Return a list containing all of the top-level accessors (getters and
-   * setters) contained in this compilation unit.
-   */
-  List<PropertyAccessorElement> get accessors;
-
-  /**
-   * Return the library in which this compilation unit is defined.
-   */
-  @override
-  LibraryElement get enclosingElement;
-
-  /**
-   * Return a list containing all of the enums contained in this compilation
-   * unit.
-   */
-  List<ClassElement> get enums;
-
-  /**
-   * Return a list containing all of the top-level functions contained in this
-   * compilation unit.
-   */
-  List<FunctionElement> get functions;
-
-  /**
-   * Return a list containing all of the function type aliases contained in this
-   * compilation unit.
-   */
-  List<FunctionTypeAliasElement> get functionTypeAliases;
-
-  /**
-   * Return `true` if this compilation unit defines a top-level function named
-   * `loadLibrary`.
-   */
-  bool get hasLoadLibraryFunction;
-
-  /**
-   * Return a list containing all of the top-level variables contained in this
-   * compilation unit.
-   */
-  List<TopLevelVariableElement> get topLevelVariables;
-
-  /**
-   * Return a list containing all of the classes contained in this compilation
-   * unit.
-   */
-  List<ClassElement> get types;
-
-  /**
-   * Return the resolved [CompilationUnit] node that declares this element.
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  CompilationUnit computeNode();
-
-  /**
-   * Return the element at the given [offset], maybe `null` if no such element.
-   */
-  Element getElementAt(int offset);
-
-  /**
-   * Return the enum defined in this compilation unit that has the given [name],
-   * or `null` if this compilation unit does not define an enum with the given
-   * name.
-   */
-  ClassElement getEnum(String name);
-
-  /**
-   * Return the class defined in this compilation unit that has the given
-   * [name], or `null` if this compilation unit does not define a class with the
-   * given name.
-   */
-  ClassElement getType(String name);
-}
-
-/**
- * A concrete implementation of a [CompilationUnitElement].
- */
-class CompilationUnitElementImpl extends UriReferencedElementImpl
-    implements CompilationUnitElement {
-  /**
-   * An empty list of compilation unit elements.
-   */
-  @deprecated // Use CompilationUnitElement.EMPTY_LIST
-  static const List<CompilationUnitElement> EMPTY_ARRAY =
-      const <CompilationUnitElement>[];
-
-  /**
-   * The source that corresponds to this compilation unit.
-   */
-  Source source;
-
-  /**
-   * The source of the library containing this compilation unit.
-   *
-   * This is the same as the source of the containing [LibraryElement],
-   * except that it does not require the containing [LibraryElement] to be
-   * computed.
-   */
-  Source librarySource;
-
-  /**
-   * A list containing all of the top-level accessors (getters and setters)
-   * contained in this compilation unit.
-   */
-  List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the enums contained in this compilation unit.
-   */
-  List<ClassElement> _enums = ClassElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the top-level functions contained in this
-   * compilation unit.
-   */
-  List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the function type aliases contained in this
-   * compilation unit.
-   */
-  List<FunctionTypeAliasElement> _typeAliases =
-      FunctionTypeAliasElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the types contained in this compilation unit.
-   */
-  List<ClassElement> _types = ClassElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the variables contained in this compilation unit.
-   */
-  List<TopLevelVariableElement> _variables = TopLevelVariableElement.EMPTY_LIST;
-
-  /**
-   * A map from offsets to elements of this unit at these offsets.
-   */
-  final Map<int, Element> _offsetToElementMap = new HashMap<int, Element>();
-
-  /**
-   * Initialize a newly created compilation unit element to have the given
-   * [name].
-   */
-  CompilationUnitElementImpl(String name) : super(name, -1);
-
-  @override
-  List<PropertyAccessorElement> get accessors => _accessors;
-
-  /**
-   * Set the top-level accessors (getters and setters) contained in this
-   * compilation unit to the given [accessors].
-   */
-  void set accessors(List<PropertyAccessorElement> accessors) {
-    for (PropertyAccessorElement accessor in accessors) {
-      (accessor as PropertyAccessorElementImpl).enclosingElement = this;
-    }
-    this._accessors = accessors;
-  }
-
-  @override
-  LibraryElement get enclosingElement =>
-      super.enclosingElement as LibraryElement;
-
-  @override
-  List<ClassElement> get enums => _enums;
-
-  /**
-   * Set the enums contained in this compilation unit to the given [enums].
-   */
-  void set enums(List<ClassElement> enums) {
-    for (ClassElement enumDeclaration in enums) {
-      (enumDeclaration as ClassElementImpl).enclosingElement = this;
-    }
-    this._enums = enums;
-  }
-
-  @override
-  List<FunctionElement> get functions => _functions;
-
-  /**
-   * Set the top-level functions contained in this compilation unit to the given
-   * [functions].
-   */
-  void set functions(List<FunctionElement> functions) {
-    for (FunctionElement function in functions) {
-      (function as FunctionElementImpl).enclosingElement = this;
-    }
-    this._functions = functions;
-  }
-
-  @override
-  List<FunctionTypeAliasElement> get functionTypeAliases => _typeAliases;
-
-  @override
-  int get hashCode => source.hashCode;
-
-  @override
-  bool get hasLoadLibraryFunction {
-    for (int i = 0; i < _functions.length; i++) {
-      if (_functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  String get identifier => source.encoding;
-
-  @override
-  ElementKind get kind => ElementKind.COMPILATION_UNIT;
-
-  @override
-  List<TopLevelVariableElement> get topLevelVariables => _variables;
-
-  /**
-   * Set the top-level variables contained in this compilation unit to the given
-   * [variables].
-   */
-  void set topLevelVariables(List<TopLevelVariableElement> variables) {
-    for (TopLevelVariableElement field in variables) {
-      (field as TopLevelVariableElementImpl).enclosingElement = this;
-    }
-    this._variables = variables;
-  }
-
-  /**
-   * Set the function type aliases contained in this compilation unit to the
-   * given [typeAliases].
-   */
-  void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
-    for (FunctionTypeAliasElement typeAlias in typeAliases) {
-      (typeAlias as FunctionTypeAliasElementImpl).enclosingElement = this;
-    }
-    this._typeAliases = typeAliases;
-  }
-
-  @override
-  List<ClassElement> get types => _types;
-
-  /**
-   * Set the types contained in this compilation unit to the given [types].
-   */
-  void set types(List<ClassElement> types) {
-    for (ClassElement type in types) {
-      (type as ClassElementImpl).enclosingElement = this;
-    }
-    this._types = types;
-  }
-
-  @override
-  bool operator ==(Object object) =>
-      object is CompilationUnitElementImpl && source == object.source;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this);
-
-  /**
-   * This method is invoked after this unit was incrementally resolved.
-   */
-  void afterIncrementalResolution() {
-    _offsetToElementMap.clear();
-  }
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    if (source == null) {
-      buffer.write("{compilation unit}");
-    } else {
-      buffer.write(source.fullName);
-    }
-  }
-
-  @override
-  CompilationUnit computeNode() => unit;
-
-  @override
-  ElementImpl getChild(String identifier) {
-    //
-    // The casts in this method are safe because the set methods would have
-    // thrown a CCE if any of the elements in the arrays were not of the
-    // expected types.
-    //
-    for (PropertyAccessorElement accessor in _accessors) {
-      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
-        return accessor as PropertyAccessorElementImpl;
-      }
-    }
-    for (VariableElement variable in _variables) {
-      if ((variable as VariableElementImpl).identifier == identifier) {
-        return variable as VariableElementImpl;
-      }
-    }
-    for (ExecutableElement function in _functions) {
-      if ((function as ExecutableElementImpl).identifier == identifier) {
-        return function as ExecutableElementImpl;
-      }
-    }
-    for (FunctionTypeAliasElement typeAlias in _typeAliases) {
-      if ((typeAlias as FunctionTypeAliasElementImpl).identifier ==
-          identifier) {
-        return typeAlias as FunctionTypeAliasElementImpl;
-      }
-    }
-    for (ClassElement type in _types) {
-      if ((type as ClassElementImpl).identifier == identifier) {
-        return type as ClassElementImpl;
-      }
-    }
-    for (ClassElement type in _enums) {
-      if ((type as ClassElementImpl).identifier == identifier) {
-        return type as ClassElementImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
-  Element getElementAt(int offset) {
-    if (_offsetToElementMap.isEmpty) {
-      accept(new _BuildOffsetToElementMap(_offsetToElementMap));
-    }
-    return _offsetToElementMap[offset];
-  }
-
-  @override
-  ClassElement getEnum(String enumName) {
-    for (ClassElement enumDeclaration in _enums) {
-      if (enumDeclaration.name == enumName) {
-        return enumDeclaration;
-      }
-    }
-    return null;
-  }
-
-  @override
-  ClassElement getType(String className) {
-    for (ClassElement type in _types) {
-      if (type.name == className) {
-        return type;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Replace the given [from] top-level variable with [to] in this compilation unit.
-   */
-  void replaceTopLevelVariable(
-      TopLevelVariableElement from, TopLevelVariableElement to) {
-    int index = _variables.indexOf(from);
-    _variables[index] = to;
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_accessors, visitor);
-    safelyVisitChildren(_enums, visitor);
-    safelyVisitChildren(_functions, visitor);
-    safelyVisitChildren(_typeAliases, visitor);
-    safelyVisitChildren(_types, visitor);
-    safelyVisitChildren(_variables, visitor);
-  }
-}
-
-/**
- * A [FieldElement] for a 'const' or 'final' field that has an initializer.
+ * This library is deprecated. Please convert all references to this library to
+ * reference one of the following public libraries:
+ * * package:analyzer/dart/element/element.dart
+ * * package:analyzer/dart/element/type.dart
+ * * package:analyzer/dart/element/visitor.dart
  *
- * TODO(paulberry): we should rename this class to reflect the fact that it's
- * used for both const and final fields.  However, we shouldn't do so until
- * we've created an API for reading the values of constants; until that API is
- * available, clients are likely to read constant values by casting to
- * ConstFieldElementImpl, so it would be a breaking change to rename this
- * class.
+ * If your code is using API's not available in these public libraries, please
+ * contact the analyzer team to either find an alternate API or have the API you
+ * depend on added to the public API.
  */
-class ConstFieldElementImpl extends FieldElementImpl with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
+library analyzer.src.generated.element;
 
-  /**
-   * Initialize a newly created synthetic field element to have the given
-   * [name] and [offset].
-   */
-  ConstFieldElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created field element to have the given [name].
-   */
-  @deprecated // Use new ConstFieldElementImpl.forNode(name)
-  ConstFieldElementImpl.con1(Identifier name) : super.forNode(name);
-
-  /**
-   * Initialize a newly created synthetic field element to have the given
-   * [name] and [offset].
-   */
-  @deprecated // Use new ConstFieldElementImpl(name, offset)
-  ConstFieldElementImpl.con2(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created field element to have the given [name].
-   */
-  ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-}
-
-/**
- * A [LocalVariableElement] for a local 'const' variable that has an
- * initializer.
- */
-class ConstLocalVariableElementImpl extends LocalVariableElementImpl
-    with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created local variable element to have the given [name]
-   * and [offset].
-   */
-  ConstLocalVariableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created local variable element to have the given [name].
-   */
-  ConstLocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-}
-
-/**
- * An element representing a constructor or a factory method defined within a
- * class.
- */
-abstract class ConstructorElement
-    implements ClassMemberElement, ExecutableElement, ConstantEvaluationTarget {
-  /**
-   * An empty list of constructor elements.
-   */
-  static const List<ConstructorElement> EMPTY_LIST =
-      const <ConstructorElement>[];
-
-  /**
-   * Return `true` if this constructor is a const constructor.
-   */
-  bool get isConst;
-
-  /**
-   * Return `true` if this constructor can be used as a default constructor -
-   * unnamed and has no required parameters.
-   */
-  bool get isDefaultConstructor;
-
-  /**
-   * Return `true` if this constructor represents a factory constructor.
-   */
-  bool get isFactory;
-
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this constructor's name, or `null` if not named.
-   */
-  int get nameEnd;
-
-  /**
-   * Return the offset of the `.` before this constructor name, or `null` if
-   * not named.
-   */
-  int get periodOffset;
-
-  /**
-   * Return the constructor to which this constructor is redirecting, or `null`
-   * if this constructor does not redirect to another constructor or if the
-   * library containing this constructor has not yet been resolved.
-   */
-  ConstructorElement get redirectedConstructor;
-
-  /**
-   * Return the resolved [ConstructorDeclaration] node that declares this
-   * [ConstructorElement] .
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  ConstructorDeclaration computeNode();
-}
-
-/**
- * A concrete implementation of a [ConstructorElement].
- */
-class ConstructorElementImpl extends ExecutableElementImpl
-    implements ConstructorElement {
-  /**
-   * An empty list of constructor elements.
-   */
-  @deprecated // Use ConstructorElement.EMPTY_LIST
-  static const List<ConstructorElement> EMPTY_ARRAY =
-      const <ConstructorElement>[];
-
-  /**
-   * The constructor to which this constructor is redirecting.
-   */
-  ConstructorElement redirectedConstructor;
-
-  /**
-   * The initializers for this constructor (used for evaluating constant
-   * instance creation expressions).
-   */
-  List<ConstructorInitializer> constantInitializers;
-
-  /**
-   * The offset of the `.` before this constructor name or `null` if not named.
-   */
-  int periodOffset;
-
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this constructor's name, or `null` if not named.
-   */
-  int nameEnd;
-
-  /**
-   * True if this constructor has been found by constant evaluation to be free
-   * of redirect cycles, and is thus safe to evaluate.
-   */
-  bool isCycleFree = false;
-
-  /**
-   * Initialize a newly created constructor element to have the given [name] and
-   * [offset].
-   */
-  ConstructorElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created constructor element to have the given [name].
-   */
-  ConstructorElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this constructor represents a 'const' constructor.
-   */
-  void set const2(bool isConst) {
-    setModifier(Modifier.CONST, isConst);
-  }
-
-  @override
-  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
-
-  /**
-   * Set whether this constructor represents a factory method.
-   */
-  void set factory(bool isFactory) {
-    setModifier(Modifier.FACTORY, isFactory);
-  }
-
-  @override
-  bool get isConst => hasModifier(Modifier.CONST);
-
-  @override
-  bool get isDefaultConstructor {
-    // unnamed
-    String name = this.name;
-    if (name != null && name.length != 0) {
-      return false;
-    }
-    // no required parameters
-    for (ParameterElement parameter in parameters) {
-      if (parameter.parameterKind == ParameterKind.REQUIRED) {
-        return false;
-      }
-    }
-    // OK, can be used as default constructor
-    return true;
-  }
-
-  @override
-  bool get isFactory => hasModifier(Modifier.FACTORY);
-
-  @override
-  bool get isStatic => false;
-
-  @override
-  ElementKind get kind => ElementKind.CONSTRUCTOR;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    if (enclosingElement == null) {
-      String message;
-      String name = displayName;
-      if (name != null && !name.isEmpty) {
-        message =
-            'Found constructor element named $name with no enclosing element';
-      } else {
-        message = 'Found unnamed constructor element with no enclosing element';
-      }
-      AnalysisEngine.instance.logger.logError(message);
-      buffer.write('<unknown class>');
-    } else {
-      buffer.write(enclosingElement.displayName);
-    }
-    String name = displayName;
-    if (name != null && !name.isEmpty) {
-      buffer.write(".");
-      buffer.write(name);
-    }
-    super.appendTo(buffer);
-  }
-
-  @override
-  ConstructorDeclaration computeNode() =>
-      getNodeMatching((node) => node is ConstructorDeclaration);
-}
-
-/**
- * A constructor element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-class ConstructorMember extends ExecutableMember implements ConstructorElement {
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  ConstructorMember(ConstructorElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  ConstructorElement get baseElement => super.baseElement as ConstructorElement;
-
-  @override
-  InterfaceType get definingType => super.definingType as InterfaceType;
-
-  @override
-  ClassElement get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  bool get isConst => baseElement.isConst;
-
-  @override
-  bool get isDefaultConstructor => baseElement.isDefaultConstructor;
-
-  @override
-  bool get isFactory => baseElement.isFactory;
-
-  @override
-  int get nameEnd => baseElement.nameEnd;
-
-  @override
-  int get periodOffset => baseElement.periodOffset;
-
-  @override
-  ConstructorElement get redirectedConstructor =>
-      from(baseElement.redirectedConstructor, definingType);
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
-
-  @override
-  ConstructorDeclaration computeNode() => baseElement.computeNode();
-
-  @override
-  String toString() {
-    ConstructorElement baseElement = this.baseElement;
-    List<ParameterElement> parameters = this.parameters;
-    FunctionType type = this.type;
-    StringBuffer buffer = new StringBuffer();
-    buffer.write(baseElement.enclosingElement.displayName);
-    String name = displayName;
-    if (name != null && !name.isEmpty) {
-      buffer.write(".");
-      buffer.write(name);
-    }
-    buffer.write("(");
-    int parameterCount = parameters.length;
-    for (int i = 0; i < parameterCount; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      buffer.write(parameters[i]);
-    }
-    buffer.write(")");
-    if (type != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(type.returnType);
-    }
-    return buffer.toString();
-  }
-
-  /**
-   * If the given [constructor]'s type is different when any type parameters
-   * from the defining type's declaration are replaced with the actual type
-   * arguments from the [definingType], create a constructor member representing
-   * the given constructor. Return the member that was created, or the original
-   * constructor if no member was created.
-   */
-  static ConstructorElement from(
-      ConstructorElement constructor, InterfaceType definingType) {
-    if (constructor == null || definingType.typeArguments.length == 0) {
-      return constructor;
-    }
-    FunctionType baseType = constructor.type;
-    if (baseType == null) {
-      // TODO(brianwilkerson) We need to understand when this can happen.
-      return constructor;
-    }
-    List<DartType> argumentTypes = definingType.typeArguments;
-    List<DartType> parameterTypes = definingType.element.type.typeArguments;
-    FunctionType substitutedType =
-        baseType.substitute2(argumentTypes, parameterTypes);
-    if (baseType == substitutedType) {
-      return constructor;
-    }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    return new ConstructorMember(constructor, definingType);
-  }
-}
-
-/**
- * A [TopLevelVariableElement] for a top-level 'const' variable that has an
- * initializer.
- */
-class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl
-    with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created top-level variable element to have the given
-   * [name].
-   */
-  ConstTopLevelVariableElementImpl(Identifier name) : super.forNode(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-}
-
-/**
- * Mixin used by elements that represent constant variables and have
- * initializers.
- *
- * Note that in correct Dart code, all constant variables must have
- * initializers.  However, analyzer also needs to handle incorrect Dart code,
- * in which case there might be some constant variables that lack initializers.
- * This interface is only used for constant variables that have initializers.
- *
- * This class is not intended to be part of the public API for analyzer.
- */
-abstract class ConstVariableElement {
-  /**
-   * If this element represents a constant variable, and it has an initializer,
-   * a copy of the initializer for the constant.  Otherwise `null`.
-   *
-   * Note that in correct Dart code, all constant variables must have
-   * initializers.  However, analyzer also needs to handle incorrect Dart code,
-   * in which case there might be some constant variables that lack
-   * initializers.
-   */
-  Expression constantInitializer;
-}
-
-/**
- * The type associated with elements in the element model.
- */
-abstract class DartType {
-  /**
-   * An empty list of types.
-   */
-  static const List<DartType> EMPTY_LIST = const <DartType>[];
-
-  /**
-   * Return the name of this type as it should appear when presented to users in
-   * contexts such as error messages.
-   */
-  String get displayName;
-
-  /**
-   * Return the element representing the declaration of this type, or `null` if
-   * the type has not, or cannot, be associated with an element. The former case
-   * will occur if the element model is not yet complete; the latter case will
-   * occur if this object represents an undefined type.
-   */
-  Element get element;
-
-  /**
-   * Return `true` if this type represents the bottom type.
-   */
-  bool get isBottom;
-
-  /**
-   * Return `true` if this type represents the type 'Function' defined in the
-   * dart:core library.
-   */
-  bool get isDartCoreFunction;
-
-  /**
-   * Return `true` if this type represents the type 'dynamic'.
-   */
-  bool get isDynamic;
-
-  /**
-   * Return `true` if this type represents the type 'Object'.
-   */
-  bool get isObject;
-
-  /**
-   * Return `true` if this type represents a typename that couldn't be resolved.
-   */
-  bool get isUndefined;
-
-  /**
-   * Return `true` if this type represents the type 'void'.
-   */
-  bool get isVoid;
-
-  /**
-   * Return the name of this type, or `null` if the type does not have a name,
-   * such as when the type represents the type of an unnamed function.
-   */
-  String get name;
-
-  /**
-   * Return the least upper bound of this type and the given [type], or `null`
-   * if there is no least upper bound.
-   *
-   * Deprecated, since it is impossible to implement the correct algorithm
-   * without access to a [TypeProvider].  Please use
-   * [TypeSystem.getLeastUpperBound] instead.
-   */
-  @deprecated
-  DartType getLeastUpperBound(DartType type);
-
-  /**
-   * Return `true` if this type is assignable to the given [type]. A type
-   * <i>T</i> may be assigned to a type <i>S</i>, written <i>T</i> &hArr;
-   * <i>S</i>, iff either <i>T</i> <: <i>S</i> or <i>S</i> <: <i>T</i>.
-   */
-  bool isAssignableTo(DartType type);
-
-  /**
-   * Return `true` if this type is more specific than the given [type].
-   */
-  bool isMoreSpecificThan(DartType type);
-
-  /**
-   * Return `true` if this type is a subtype of the given [type].
-   */
-  bool isSubtypeOf(DartType type);
-
-  /**
-   * Return `true` if this type is a supertype of the given [type]. A type
-   * <i>S</i> is a supertype of <i>T</i>, written <i>S</i> :> <i>T</i>, iff
-   * <i>T</i> is a subtype of <i>S</i>.
-   */
-  bool isSupertypeOf(DartType type);
-
-  /**
-   * Return the type resulting from substituting the given [argumentTypes] for
-   * the given [parameterTypes] in this type. The specification defines this
-   * operation in section 2:
-   * <blockquote>
-   * The notation <i>[x<sub>1</sub>, ..., x<sub>n</sub>/y<sub>1</sub>, ...,
-   * y<sub>n</sub>]E</i> denotes a copy of <i>E</i> in which all occurrences of
-   * <i>y<sub>i</sub>, 1 <= i <= n</i> have been replaced with
-   * <i>x<sub>i</sub></i>.
-   * </blockquote>
-   * Note that, contrary to the specification, this method will not create a
-   * copy of this type if no substitutions were required, but will return this
-   * type directly.
-   *
-   * Note too that the current implementation of this method is only guaranteed
-   * to work when the parameter types are type variables.
-   */
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes);
-}
-
-/**
- * A [FieldFormalParameterElementImpl] for parameters that have an initializer.
- */
-class DefaultFieldFormalParameterElementImpl
-    extends FieldFormalParameterElementImpl with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created parameter element to have the given [name].
-   */
-  DefaultFieldFormalParameterElementImpl(Identifier name) : super(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-}
-
-/**
- * A [ParameterElement] for parameters that have an initializer.
- */
-class DefaultParameterElementImpl extends ParameterElementImpl
-    with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created parameter element to have the given [name].
-   */
-  DefaultParameterElementImpl(Identifier name) : super.forNode(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-
-  @override
-  DefaultFormalParameter computeNode() =>
-      getNodeMatching((node) => node is DefaultFormalParameter);
-}
-
-/**
- * The synthetic element representing the declaration of the type `dynamic`.
- */
-class DynamicElementImpl extends ElementImpl implements TypeDefiningElement {
-  /**
-   * Return the unique instance of this class.
-   */
-  static DynamicElementImpl get instance =>
-      DynamicTypeImpl.instance.element as DynamicElementImpl;
-
-  @override
-  DynamicTypeImpl type;
-
-  /**
-   * Initialize a newly created instance of this class. Instances of this class
-   * should <b>not</b> be created except as part of creating the type associated
-   * with this element. The single instance of this class should be accessed
-   * through the method [getInstance].
-   */
-  DynamicElementImpl() : super(Keyword.DYNAMIC.syntax, -1) {
-    setModifier(Modifier.SYNTHETIC, true);
-  }
-
-  @override
-  ElementKind get kind => ElementKind.DYNAMIC;
-
-  @override
-  accept(ElementVisitor visitor) => null;
-}
-
-/**
- * The [Type] representing the type `dynamic`.
- */
-class DynamicTypeImpl extends TypeImpl {
-  /**
-   * The unique instance of this class.
-   */
-  static DynamicTypeImpl _INSTANCE = new DynamicTypeImpl._();
-
-  /**
-   * Return the unique instance of this class.
-   */
-  static DynamicTypeImpl get instance => _INSTANCE;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  DynamicTypeImpl._()
-      : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) {
-    (element as DynamicElementImpl).type = this;
-  }
-
-  /**
-   * Constructor used by [CircularTypeImpl].
-   */
-  DynamicTypeImpl._circular()
-      : super(_INSTANCE.element, Keyword.DYNAMIC.syntax);
-
-  @override
-  int get hashCode => 1;
-
-  @override
-  bool get isDynamic => true;
-
-  @override
-  bool operator ==(Object object) => identical(object, this);
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    // T is S
-    if (identical(this, type)) {
-      return true;
-    }
-    // else
-    return withDynamic;
-  }
-
-  @override
-  bool isSubtypeOf(DartType type) => true;
-
-  @override
-  bool isSupertypeOf(DartType type) => true;
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    int length = parameterTypes.length;
-    for (int i = 0; i < length; i++) {
-      if (parameterTypes[i] == this) {
-        return argumentTypes[i];
-      }
-    }
-    return this;
-  }
-}
-
-/**
- * The base class for all of the elements in the element model. Generally
- * speaking, the element model is a semantic model of the program that
- * represents things that are declared with a name and hence can be referenced
- * elsewhere in the code.
- *
- * There are two exceptions to the general case. First, there are elements in
- * the element model that are created for the convenience of various kinds of
- * analysis but that do not have any corresponding declaration within the source
- * code. Such elements are marked as being <i>synthetic</i>. Examples of
- * synthetic elements include
- * * default constructors in classes that do not define any explicit
- *   constructors,
- * * getters and setters that are induced by explicit field declarations,
- * * fields that are induced by explicit declarations of getters and setters,
- *   and
- * * functions representing the initialization expression for a variable.
- *
- * Second, there are elements in the element model that do not have a name.
- * These correspond to unnamed functions and exist in order to more accurately
- * represent the semantic structure of the program.
- */
-abstract class Element implements AnalysisTarget {
-  /**
-   * An Unicode right arrow.
-   */
-  static final String RIGHT_ARROW = " \u2192 ";
-
-  /**
-   * A comparator that can be used to sort elements by their name offset.
-   * Elements with a smaller offset will be sorted to be before elements with a
-   * larger name offset.
-   */
-  static final Comparator<Element> SORT_BY_OFFSET = (Element firstElement,
-          Element secondElement) =>
-      firstElement.nameOffset - secondElement.nameOffset;
-
-  /**
-   * Return the analysis context in which this element is defined.
-   */
-  AnalysisContext get context;
-
-  /**
-   * Return the display name of this element, or `null` if this element does not
-   * have a name.
-   *
-   * In most cases the name and the display name are the same. Differences
-   * though are cases such as setters where the name of some setter `set f(x)`
-   * is `f=`, instead of `f`.
-   */
-  String get displayName;
-
-  /**
-   * Return the source range of the documentation comment for this element,
-   * or `null` if this element does not or cannot have a documentation.
-   */
-  SourceRange get docRange;
-
-  /**
-   * Return the element that either physically or logically encloses this
-   * element. This will be `null` if this element is a library because libraries
-   * are the top-level elements in the model.
-   */
-  Element get enclosingElement;
-
-  /**
-   * The unique integer identifier of this element.
-   */
-  int get id;
-
-  /**
-   * Return `true` if this element has an annotation of the form '@deprecated'
-   * or '@Deprecated('..')'.
-   */
-  bool get isDeprecated;
-
-  /**
-   * Return `true` if this element has an annotation of the form '@override'.
-   */
-  bool get isOverride;
-
-  /**
-   * Return `true` if this element is private. Private elements are visible only
-   * within the library in which they are declared.
-   */
-  bool get isPrivate;
-
-  /**
-   * Return `true` if this element is public. Public elements are visible within
-   * any library that imports the library in which they are declared.
-   */
-  bool get isPublic;
-
-  /**
-   * Return `true` if this element is synthetic. A synthetic element is an
-   * element that is not represented in the source code explicitly, but is
-   * implied by the source code, such as the default constructor for a class
-   * that does not explicitly define any constructors.
-   */
-  bool get isSynthetic;
-
-  /**
-   * Return the kind of element that this is.
-   */
-  ElementKind get kind;
-
-  /**
-   * Return the library that contains this element. This will be the element
-   * itself if it is a library element. This will be `null` if this element is
-   * an HTML file because HTML files are not contained in libraries.
-   */
-  LibraryElement get library;
-
-  /**
-   * Return an object representing the location of this element in the element
-   * model. The object can be used to locate this element at a later time.
-   */
-  ElementLocation get location;
-
-  /**
-   * Return a list containing all of the metadata associated with this element.
-   * The array will be empty if the element does not have any metadata or if the
-   * library containing this element has not yet been resolved.
-   */
-  List<ElementAnnotation> get metadata;
-
-  /**
-   * Return the name of this element, or `null` if this element does not have a
-   * name.
-   */
-  String get name;
-
-  /**
-   * Return the length of the name of this element in the file that contains the
-   * declaration of this element, or `0` if this element does not have a name.
-   */
-  int get nameLength;
-
-  /**
-   * Return the offset of the name of this element in the file that contains the
-   * declaration of this element, or `-1` if this element is synthetic, does not
-   * have a name, or otherwise does not have an offset.
-   */
-  int get nameOffset;
-
-  /**
-   * **DEPRECATED** Use `computeNode()` instead.
-   *
-   * Return the resolved [AstNode] node that declares this element, or `null` if
-   * this element is synthetic or isn't contained in a compilation unit, such as
-   * a [LibraryElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  @deprecated
-  AstNode get node;
-
-  /**
-   * Return the source that contains this element, or `null` if this element is
-   * not contained in a source.
-   */
-  Source get source;
-
-  /**
-   * Return the resolved [CompilationUnit] that declares this element, or `null`
-   * if this element is synthetic.
-   *
-   * This method is expensive, because resolved AST might have been already
-   * evicted from cache, so parsing and resolving will be performed.
-   */
-  CompilationUnit get unit;
-
-  /**
-   * Use the given [visitor] to visit this element. Return the value returned by
-   * the visitor as a result of visiting this element.
-   */
-  accept(ElementVisitor visitor);
-
-  /**
-   * Return the documentation comment for this element as it appears in the
-   * original source (complete with the beginning and ending delimiters), or
-   * `null` if this element does not have a documentation comment associated
-   * with it. This can be a long-running operation if the information needed to
-   * access the comment is not cached.
-   *
-   * Throws [AnalysisException] if the documentation comment could not be
-   * determined because the analysis could not be performed
-   */
-  String computeDocumentationComment();
-
-  /**
-   * Return the resolved [AstNode] node that declares this element, or `null` if
-   * this element is synthetic or isn't contained in a compilation unit, such as
-   * a [LibraryElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  AstNode computeNode();
-
-  /**
-   * Return the most immediate ancestor of this element for which the
-   * [predicate] returns `true`, or `null` if there is no such ancestor. Note
-   * that this element will never be returned.
-   */
-  Element getAncestor(Predicate<Element> predicate);
-
-  /**
-   * Return a display name for the given element that includes the path to the
-   * compilation unit in which the type is defined. If [shortName] is `null`
-   * then [getDisplayName] will be used as the name of this element. Otherwise
-   * the provided name will be used.
-   */
-  // TODO(brianwilkerson) Make the parameter optional.
-  String getExtendedDisplayName(String shortName);
-
-  /**
-   * Return `true` if this element, assuming that it is within scope, is
-   * accessible to code in the given [library]. This is defined by the Dart
-   * Language Specification in section 3.2:
-   * <blockquote>
-   * A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is
-   * declared in <i>L</i> or if <i>m</i> is public.
-   * </blockquote>
-   */
-  bool isAccessibleIn(LibraryElement library);
-
-  /**
-   * Use the given [visitor] to visit all of the children of this element. There
-   * is no guarantee of the order in which the children will be visited.
-   */
-  void visitChildren(ElementVisitor visitor);
-}
-
-/**
- * A single annotation associated with an element.
- */
-abstract class ElementAnnotation {
-  /**
-   * An empty list of annotations.
-   */
-  static const List<ElementAnnotation> EMPTY_LIST = const <ElementAnnotation>[];
-
-  /**
-   * Return a representation of the value of this annotation.
-   *
-   * Return `null` if the value of this annotation could not be computed because
-   * of errors.
-   */
-  DartObject get constantValue;
-
-  /**
-   * Return the element representing the field, variable, or const constructor
-   * being used as an annotation.
-   */
-  Element get element;
-
-  /**
-   * Return `true` if this annotation marks the associated element as being
-   * deprecated.
-   */
-  bool get isDeprecated;
-
-  /**
-   * Return `true` if this annotation marks the associated method as being
-   * expected to override an inherited method.
-   */
-  bool get isOverride;
-
-  /**
-   * Return `true` if this annotation marks the associated class as implementing
-   * a proxy object.
-   */
-  bool get isProxy;
-}
-
-/**
- * A concrete implementation of an [ElementAnnotation].
- */
-class ElementAnnotationImpl implements ElementAnnotation {
-  /**
-   * An empty list of annotations.
-   */
-  @deprecated // Use ElementAnnotation.EMPTY_LIST
-  static const List<ElementAnnotationImpl> EMPTY_ARRAY =
-      const <ElementAnnotationImpl>[];
-
-  /**
-   * The name of the class used to mark an element as being deprecated.
-   */
-  static String _DEPRECATED_CLASS_NAME = "Deprecated";
-
-  /**
-   * The name of the top-level variable used to mark an element as being
-   * deprecated.
-   */
-  static String _DEPRECATED_VARIABLE_NAME = "deprecated";
-
-  /**
-   * The name of the top-level variable used to mark a method as being expected
-   * to override an inherited method.
-   */
-  static String _OVERRIDE_VARIABLE_NAME = "override";
-
-  /**
-   * The name of the top-level variable used to mark a class as implementing a
-   * proxy object.
-   */
-  static String PROXY_VARIABLE_NAME = "proxy";
-
-  /**
-   * The element representing the field, variable, or constructor being used as
-   * an annotation.
-   */
-  final Element element;
-
-  /**
-   * The result of evaluating this annotation as a compile-time constant
-   * expression, or `null` if the compilation unit containing the variable has
-   * not been resolved.
-   */
-  EvaluationResultImpl evaluationResult;
-
-  /**
-   * Initialize a newly created annotation. The given [element] is the element
-   * representing the field, variable, or constructor being used as an
-   * annotation.
-   */
-  ElementAnnotationImpl(this.element);
-
-  @override
-  DartObject get constantValue => evaluationResult.value;
-
-  @override
-  bool get isDeprecated {
-    if (element != null) {
-      LibraryElement library = element.library;
-      if (library != null && library.isDartCore) {
-        if (element is ConstructorElement) {
-          ConstructorElement constructorElement = element as ConstructorElement;
-          if (constructorElement.enclosingElement.name ==
-              _DEPRECATED_CLASS_NAME) {
-            return true;
-          }
-        } else if (element is PropertyAccessorElement &&
-            element.name == _DEPRECATED_VARIABLE_NAME) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isOverride {
-    if (element != null) {
-      LibraryElement library = element.library;
-      if (library != null && library.isDartCore) {
-        if (element is PropertyAccessorElement &&
-            element.name == _OVERRIDE_VARIABLE_NAME) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isProxy {
-    if (element != null) {
-      LibraryElement library = element.library;
-      if (library != null && library.isDartCore) {
-        if (element is PropertyAccessorElement &&
-            element.name == PROXY_VARIABLE_NAME) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  @override
-  String toString() => '@$element';
-}
-
-/**
- * A base class for concrete implementations of an [Element].
- */
-abstract class ElementImpl implements Element {
-  static int _NEXT_ID = 0;
-
-  final int id = _NEXT_ID++;
-
-  /**
-   * The enclosing element of this element, or `null` if this element is at the
-   * root of the element structure.
-   */
-  ElementImpl _enclosingElement;
-
-  /**
-   * The name of this element.
-   */
-  String _name;
-
-  /**
-   * The offset of the name of this element in the file that contains the
-   * declaration of this element.
-   */
-  int _nameOffset = 0;
-
-  /**
-   * A bit-encoded form of the modifiers associated with this element.
-   */
-  int _modifiers = 0;
-
-  /**
-   * A list containing all of the metadata associated with this element.
-   */
-  List<ElementAnnotation> metadata = ElementAnnotation.EMPTY_LIST;
-
-  /**
-   * A cached copy of the calculated hashCode for this element.
-   */
-  int _cachedHashCode;
-
-  /**
-   * A cached copy of the calculated location for this element.
-   */
-  ElementLocation _cachedLocation;
-
-  /**
-   * The offset to the beginning of the documentation comment,
-   * or `null` if this element does not have a documentation comment.
-   */
-  int _docRangeOffset;
-
-  /**
-   * The length of the documentation comment range for this element.
-   */
-  int _docRangeLength;
-
-  /**
-   * Initialize a newly created element to have the given [name] at the given
-   * [_nameOffset].
-   */
-  ElementImpl(String name, this._nameOffset) {
-    this._name = StringUtilities.intern(name);
-  }
-
-  /**
-   * Initialize a newly created element to have the given [name].
-   */
-  ElementImpl.forNode(Identifier name)
-      : this(name == null ? "" : name.name, name == null ? -1 : name.offset);
-
-  @override
-  AnalysisContext get context {
-    if (_enclosingElement == null) {
-      return null;
-    }
-    return _enclosingElement.context;
-  }
-
-  @override
-  String get displayName => _name;
-
-  @override
-  SourceRange get docRange {
-    if (_docRangeOffset != null && _docRangeLength != null) {
-      return new SourceRange(_docRangeOffset, _docRangeLength);
-    }
-    return null;
-  }
-
-  @override
-  Element get enclosingElement => _enclosingElement;
-
-  /**
-   * Set the enclosing element of this element to the given [element].
-   */
-  void set enclosingElement(Element element) {
-    _enclosingElement = element as ElementImpl;
-    _cachedLocation = null;
-    _cachedHashCode = null;
-  }
-
-  @override
-  int get hashCode {
-    // TODO: We might want to re-visit this optimization in the future.
-    // We cache the hash code value as this is a very frequently called method.
-    if (_cachedHashCode == null) {
-      int hashIdentifier = identifier.hashCode;
-      Element enclosing = enclosingElement;
-      if (enclosing != null) {
-        _cachedHashCode = hashIdentifier + enclosing.hashCode;
-      } else {
-        _cachedHashCode = hashIdentifier;
-      }
-    }
-    return _cachedHashCode;
-  }
-
-  /**
-   * Return an identifier that uniquely identifies this element among the
-   * children of this element's parent.
-   */
-  String get identifier => name;
-
-  @override
-  bool get isDeprecated {
-    for (ElementAnnotation annotation in metadata) {
-      if (annotation.isDeprecated) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isOverride {
-    for (ElementAnnotation annotation in metadata) {
-      if (annotation.isOverride) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isPrivate {
-    String name = displayName;
-    if (name == null) {
-      return true;
-    }
-    return Identifier.isPrivateName(name);
-  }
-
-  @override
-  bool get isPublic => !isPrivate;
-
-  @override
-  bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
-
-  @override
-  LibraryElement get library =>
-      getAncestor((element) => element is LibraryElement);
-
-  @override
-  ElementLocation get location {
-    if (_cachedLocation == null) {
-      _cachedLocation = new ElementLocationImpl.con1(this);
-    }
-    return _cachedLocation;
-  }
-
-  @override
-  String get name => _name;
-
-  void set name(String name) {
-    this._name = name;
-    _cachedLocation = null;
-    _cachedHashCode = null;
-  }
-
-  @override
-  int get nameLength => displayName != null ? displayName.length : 0;
-
-  @override
-  int get nameOffset => _nameOffset;
-
-  /**
-   * Sets the offset of the name of this element in the file that contains the
-   * declaration of this element.
-   */
-  void set nameOffset(int offset) {
-    _nameOffset = offset;
-    _cachedHashCode = null;
-    _cachedLocation = null;
-  }
-
-  @deprecated
-  @override
-  AstNode get node => computeNode();
-
-  @override
-  Source get source {
-    if (_enclosingElement == null) {
-      return null;
-    }
-    return _enclosingElement.source;
-  }
-
-  /**
-   * Set whether this element is synthetic.
-   */
-  void set synthetic(bool isSynthetic) {
-    setModifier(Modifier.SYNTHETIC, isSynthetic);
-  }
-
-  @override
-  CompilationUnit get unit => context.resolveCompilationUnit(source, library);
-
-  @override
-  bool operator ==(Object object) {
-    if (identical(this, object)) {
-      return true;
-    }
-    if (object == null || hashCode != object.hashCode) {
-      return false;
-    }
-    return object.runtimeType == runtimeType &&
-        (object as Element).location == location;
-  }
-
-  /**
-   * Append a textual representation of this element to the given [buffer].
-   */
-  void appendTo(StringBuffer buffer) {
-    if (_name == null) {
-      buffer.write("<unnamed ");
-      buffer.write(runtimeType.toString());
-      buffer.write(">");
-    } else {
-      buffer.write(_name);
-    }
-  }
-
-  @override
-  String computeDocumentationComment() {
-    AnalysisContext context = this.context;
-    if (context == null) {
-      return null;
-    }
-    return context.computeDocumentationComment(this);
-  }
-
-  @override
-  AstNode computeNode() => getNodeMatching((node) => node is AstNode);
-
-  /**
-   * Set this element as the enclosing element for given [element].
-   */
-  void encloseElement(ElementImpl element) {
-    element.enclosingElement = this;
-  }
-
-  @override
-  Element getAncestor(Predicate<Element> predicate) {
-    Element ancestor = _enclosingElement;
-    while (ancestor != null && !predicate(ancestor)) {
-      ancestor = ancestor.enclosingElement;
-    }
-    return ancestor;
-  }
-
-  /**
-   * Return the child of this element that is uniquely identified by the given
-   * [identifier], or `null` if there is no such child.
-   */
-  ElementImpl getChild(String identifier) => null;
-
-  @override
-  String getExtendedDisplayName(String shortName) {
-    if (shortName == null) {
-      shortName = displayName;
-    }
-    Source source = this.source;
-    if (source != null) {
-      return "$shortName (${source.fullName})";
-    }
-    return shortName;
-  }
-
-  /**
-   * Return the resolved [AstNode] of the given type enclosing [getNameOffset].
-   */
-  AstNode getNodeMatching(Predicate<AstNode> predicate) {
-    CompilationUnit unit = this.unit;
-    if (unit == null) {
-      return null;
-    }
-    int offset = nameOffset;
-    AstNode node = new NodeLocator(offset).searchWithin(unit);
-    if (node == null) {
-      return null;
-    }
-    return node.getAncestor(predicate);
-  }
-
-  /**
-   * Return `true` if this element has the given [modifier] associated with it.
-   */
-  bool hasModifier(Modifier modifier) =>
-      BooleanArray.getEnum(_modifiers, modifier);
-
-  @override
-  bool isAccessibleIn(LibraryElement library) {
-    if (Identifier.isPrivateName(_name)) {
-      return library == this.library;
-    }
-    return true;
-  }
-
-  /**
-   * If the given [child] is not `null`, use the given [visitor] to visit it.
-   */
-  void safelyVisitChild(Element child, ElementVisitor visitor) {
-    if (child != null) {
-      child.accept(visitor);
-    }
-  }
-
-  /**
-   * Use the given [visitor] to visit all of the [children] in the given array.
-   */
-  void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
-    if (children != null) {
-      for (Element child in children) {
-        child.accept(visitor);
-      }
-    }
-  }
-
-  /**
-   * Set the documentation comment source range for this element.
-   */
-  void setDocRange(int offset, int length) {
-    _docRangeOffset = offset;
-    _docRangeLength = length;
-  }
-
-  /**
-   * Set whether the given [modifier] is associated with this element to
-   * correspond to the given [value].
-   */
-  void setModifier(Modifier modifier, bool value) {
-    _modifiers = BooleanArray.setEnum(_modifiers, modifier, value);
-  }
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    appendTo(buffer);
-    return buffer.toString();
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // There are no children to visit
-  }
-}
-
-/**
- * The enumeration `ElementKind` defines the various kinds of elements in the
- * element model.
- */
-class ElementKind extends Enum<ElementKind> {
-  static const ElementKind CLASS = const ElementKind('CLASS', 0, "class");
-
-  static const ElementKind COMPILATION_UNIT =
-      const ElementKind('COMPILATION_UNIT', 1, "compilation unit");
-
-  static const ElementKind CONSTRUCTOR =
-      const ElementKind('CONSTRUCTOR', 2, "constructor");
-
-  static const ElementKind DYNAMIC =
-      const ElementKind('DYNAMIC', 3, "<dynamic>");
-
-  static const ElementKind EMBEDDED_HTML_SCRIPT =
-      const ElementKind('EMBEDDED_HTML_SCRIPT', 4, "embedded html script");
-
-  static const ElementKind ERROR = const ElementKind('ERROR', 5, "<error>");
-
-  static const ElementKind EXPORT =
-      const ElementKind('EXPORT', 6, "export directive");
-
-  static const ElementKind EXTERNAL_HTML_SCRIPT =
-      const ElementKind('EXTERNAL_HTML_SCRIPT', 7, "external html script");
-
-  static const ElementKind FIELD = const ElementKind('FIELD', 8, "field");
-
-  static const ElementKind FUNCTION =
-      const ElementKind('FUNCTION', 9, "function");
-
-  static const ElementKind GETTER = const ElementKind('GETTER', 10, "getter");
-
-  static const ElementKind HTML = const ElementKind('HTML', 11, "html");
-
-  static const ElementKind IMPORT =
-      const ElementKind('IMPORT', 12, "import directive");
-
-  static const ElementKind LABEL = const ElementKind('LABEL', 13, "label");
-
-  static const ElementKind LIBRARY =
-      const ElementKind('LIBRARY', 14, "library");
-
-  static const ElementKind LOCAL_VARIABLE =
-      const ElementKind('LOCAL_VARIABLE', 15, "local variable");
-
-  static const ElementKind METHOD = const ElementKind('METHOD', 16, "method");
-
-  static const ElementKind NAME = const ElementKind('NAME', 17, "<name>");
-
-  static const ElementKind PARAMETER =
-      const ElementKind('PARAMETER', 18, "parameter");
-
-  static const ElementKind PREFIX =
-      const ElementKind('PREFIX', 19, "import prefix");
-
-  static const ElementKind SETTER = const ElementKind('SETTER', 20, "setter");
-
-  static const ElementKind TOP_LEVEL_VARIABLE =
-      const ElementKind('TOP_LEVEL_VARIABLE', 21, "top level variable");
-
-  static const ElementKind FUNCTION_TYPE_ALIAS =
-      const ElementKind('FUNCTION_TYPE_ALIAS', 22, "function type alias");
-
-  static const ElementKind TYPE_PARAMETER =
-      const ElementKind('TYPE_PARAMETER', 23, "type parameter");
-
-  static const ElementKind UNIVERSE =
-      const ElementKind('UNIVERSE', 24, "<universe>");
-
-  static const List<ElementKind> values = const [
-    CLASS,
-    COMPILATION_UNIT,
-    CONSTRUCTOR,
-    DYNAMIC,
-    EMBEDDED_HTML_SCRIPT,
-    ERROR,
-    EXPORT,
-    EXTERNAL_HTML_SCRIPT,
-    FIELD,
-    FUNCTION,
-    GETTER,
-    HTML,
-    IMPORT,
-    LABEL,
-    LIBRARY,
-    LOCAL_VARIABLE,
-    METHOD,
-    NAME,
-    PARAMETER,
-    PREFIX,
-    SETTER,
-    TOP_LEVEL_VARIABLE,
-    FUNCTION_TYPE_ALIAS,
-    TYPE_PARAMETER,
-    UNIVERSE
-  ];
-
-  /**
-   * The name displayed in the UI for this kind of element.
-   */
-  final String displayName;
-
-  /**
-   * Initialize a newly created element kind to have the given [displayName].
-   */
-  const ElementKind(String name, int ordinal, this.displayName)
-      : super(name, ordinal);
-
-  /**
-   * Return the kind of the given [element], or [ERROR] if the element is
-   * `null`. This is a utility method that can reduce the need for null checks
-   * in other places.
-   */
-  static ElementKind of(Element element) {
-    if (element == null) {
-      return ERROR;
-    }
-    return element.kind;
-  }
-}
-
-/**
- * The location of an element within the element model.
- */
-abstract class ElementLocation {
-  /**
-   * Return the path to the element whose location is represented by this
-   * object. Clients must not modify the returned array.
-   */
-  List<String> get components;
-
-  /**
-   * Return an encoded representation of this location that can be used to
-   * create a location that is equal to this location.
-   */
-  String get encoding;
-}
-
-/**
- * A concrete implementation of an [ElementLocation].
- */
-class ElementLocationImpl implements ElementLocation {
-  /**
-   * The character used to separate components in the encoded form.
-   */
-  static int _SEPARATOR_CHAR = 0x3B;
-
-  /**
-   * The path to the element whose location is represented by this object.
-   */
-  List<String> _components;
-
-  /**
-   * The object managing [indexKeyId] and [indexLocationId].
-   */
-  Object indexOwner;
-
-  /**
-   * A cached id of this location in index.
-   */
-  int indexKeyId;
-
-  /**
-   * A cached id of this location in index.
-   */
-  int indexLocationId;
-
-  /**
-   * Initialize a newly created location to represent the given [element].
-   */
-  ElementLocationImpl.con1(Element element) {
-    List<String> components = new List<String>();
-    Element ancestor = element;
-    while (ancestor != null) {
-      components.insert(0, (ancestor as ElementImpl).identifier);
-      ancestor = ancestor.enclosingElement;
-    }
-    this._components = components;
-  }
-
-  /**
-   * Initialize a newly created location from the given [encoding].
-   */
-  ElementLocationImpl.con2(String encoding) {
-    this._components = _decode(encoding);
-  }
-
-  /**
-   * Initialize a newly created location from the given [components].
-   */
-  ElementLocationImpl.con3(List<String> components) {
-    this._components = components;
-  }
-
-  @override
-  List<String> get components => _components;
-
-  @override
-  String get encoding {
-    StringBuffer buffer = new StringBuffer();
-    int length = _components.length;
-    for (int i = 0; i < length; i++) {
-      if (i > 0) {
-        buffer.writeCharCode(_SEPARATOR_CHAR);
-      }
-      _encode(buffer, _components[i]);
-    }
-    return buffer.toString();
-  }
-
-  @override
-  int get hashCode {
-    int result = 1;
-    for (int i = 0; i < _components.length; i++) {
-      String component = _components[i];
-      result = 31 * result + component.hashCode;
-    }
-    return result;
-  }
-
-  @override
-  bool operator ==(Object object) {
-    if (identical(this, object)) {
-      return true;
-    }
-    if (object is! ElementLocationImpl) {
-      return false;
-    }
-    ElementLocationImpl location = object as ElementLocationImpl;
-    List<String> otherComponents = location._components;
-    int length = _components.length;
-    if (otherComponents.length != length) {
-      return false;
-    }
-    for (int i = 0; i < length; i++) {
-      if (_components[i] != otherComponents[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @override
-  String toString() => encoding;
-
-  /**
-   * Decode the [encoding] of a location into a list of components and return
-   * the components.
-   */
-  List<String> _decode(String encoding) {
-    List<String> components = new List<String>();
-    StringBuffer buffer = new StringBuffer();
-    int index = 0;
-    int length = encoding.length;
-    while (index < length) {
-      int currentChar = encoding.codeUnitAt(index);
-      if (currentChar == _SEPARATOR_CHAR) {
-        if (index + 1 < length &&
-            encoding.codeUnitAt(index + 1) == _SEPARATOR_CHAR) {
-          buffer.writeCharCode(_SEPARATOR_CHAR);
-          index += 2;
-        } else {
-          components.add(buffer.toString());
-          buffer = new StringBuffer();
-          index++;
-        }
-      } else {
-        buffer.writeCharCode(currentChar);
-        index++;
-      }
-    }
-    components.add(buffer.toString());
-    return components;
-  }
-
-  /**
-   * Append an encoded form of the given [component] to the given [buffer].
-   */
-  void _encode(StringBuffer buffer, String component) {
-    int length = component.length;
-    for (int i = 0; i < length; i++) {
-      int currentChar = component.codeUnitAt(i);
-      if (currentChar == _SEPARATOR_CHAR) {
-        buffer.writeCharCode(_SEPARATOR_CHAR);
-      }
-      buffer.writeCharCode(currentChar);
-    }
-  }
-}
-
-/**
- * An object that can be used to visit an element structure.
- */
-abstract class ElementVisitor<R> {
-  R visitClassElement(ClassElement element);
-
-  R visitCompilationUnitElement(CompilationUnitElement element);
-
-  R visitConstructorElement(ConstructorElement element);
-
-  @deprecated
-  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element);
-
-  R visitExportElement(ExportElement element);
-
-  @deprecated
-  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element);
-
-  R visitFieldElement(FieldElement element);
-
-  R visitFieldFormalParameterElement(FieldFormalParameterElement element);
-
-  R visitFunctionElement(FunctionElement element);
-
-  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element);
-
-  @deprecated
-  R visitHtmlElement(HtmlElement element);
-
-  R visitImportElement(ImportElement element);
-
-  R visitLabelElement(LabelElement element);
-
-  R visitLibraryElement(LibraryElement element);
-
-  R visitLocalVariableElement(LocalVariableElement element);
-
-  R visitMethodElement(MethodElement element);
-
-  R visitMultiplyDefinedElement(MultiplyDefinedElement element);
-
-  R visitParameterElement(ParameterElement element);
-
-  R visitPrefixElement(PrefixElement element);
-
-  R visitPropertyAccessorElement(PropertyAccessorElement element);
-
-  R visitTopLevelVariableElement(TopLevelVariableElement element);
-
-  R visitTypeParameterElement(TypeParameterElement element);
-}
-
-/**
- * A script tag in an HTML file having content that defines a Dart library.
- */
-@deprecated
-abstract class EmbeddedHtmlScriptElement implements HtmlScriptElement {
-  /**
-   * Return the library element defined by the content of the script tag.
-   */
-  LibraryElement get scriptLibrary;
-}
-
-/**
- * A concrete implementation of an [EmbeddedHtmlScriptElement].
- */
-@deprecated
-class EmbeddedHtmlScriptElementImpl extends HtmlScriptElementImpl
-    implements EmbeddedHtmlScriptElement {
-  /**
-   * The library defined by the script tag's content.
-   */
-  LibraryElement _scriptLibrary;
-
-  /**
-   * Initialize a newly created script element to represent the given [node].
-   */
-  EmbeddedHtmlScriptElementImpl(XmlTagNode node) : super(node);
-
-  @override
-  ElementKind get kind => ElementKind.EMBEDDED_HTML_SCRIPT;
-
-  @override
-  LibraryElement get scriptLibrary => _scriptLibrary;
-
-  /**
-   * Set the script library defined by the script tag's content to the given
-   * [library].
-   */
-  void set scriptLibrary(LibraryElementImpl library) {
-    library.enclosingElement = this;
-    _scriptLibrary = library;
-  }
-
-  @override
-  accept(ElementVisitor visitor) =>
-      visitor.visitEmbeddedHtmlScriptElement(this);
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    safelyVisitChild(_scriptLibrary, visitor);
-  }
-}
-
-/**
- * An element representing an executable object, including functions, methods,
- * constructors, getters, and setters.
- */
-abstract class ExecutableElement implements Element {
-  /**
-   * An empty list of executable elements.
-   */
-  static const List<ExecutableElement> EMPTY_LIST = const <ExecutableElement>[];
-
-  /**
-   * Return a list containing all of the functions defined within this
-   * executable element.
-   */
-  List<FunctionElement> get functions;
-
-  /**
-   * Return `true` if this executable element did not have an explicit return
-   * type specified for it in the original source. Note that if there was no
-   * explicit return type, and if the element model is fully populated, then
-   * the [returnType] will not be `null`.
-   */
-  bool get hasImplicitReturnType;
-
-  /**
-   * Return `true` if this executable element is abstract. Executable elements
-   * are abstract if they are not external and have no body.
-   */
-  bool get isAbstract;
-
-  /**
-   * Return `true` if this executable element has body marked as being
-   * asynchronous.
-   */
-  bool get isAsynchronous;
-
-  /**
-   * Return `true` if this executable element is external. Executable elements
-   * are external if they are explicitly marked as such using the 'external'
-   * keyword.
-   */
-  bool get isExternal;
-
-  /**
-   * Return `true` if this executable element has a body marked as being a
-   * generator.
-   */
-  bool get isGenerator;
-
-  /**
-   * Return `true` if this executable element is an operator. The test may be
-   * based on the name of the executable element, in which case the result will
-   * be correct when the name is legal.
-   */
-  bool get isOperator;
-
-  /**
-   * Return `true` if this element is a static element. A static element is an
-   * element that is not associated with a particular instance, but rather with
-   * an entire library or class.
-   */
-  bool get isStatic;
-
-  /**
-   * Return `true` if this executable element has a body marked as being
-   * synchronous.
-   */
-  bool get isSynchronous;
-
-  /**
-   * Return a list containing all of the labels defined within this executable
-   * element.
-   */
-  List<LabelElement> get labels;
-
-  /**
-   * Return a list containing all of the local variables defined within this
-   * executable element.
-   */
-  List<LocalVariableElement> get localVariables;
-
-  /**
-   * Return a list containing all of the parameters defined by this executable
-   * element.
-   */
-  List<ParameterElement> get parameters;
-
-  /**
-   * Return the return type defined by this executable element. If the element
-   * model is fully populated, then the [returnType] will not be `null`, even
-   * if no return type was explicitly specified.
-   */
-  DartType get returnType;
-
-  /**
-   * Return the type of function defined by this executable element.
-   */
-  FunctionType get type;
-
-  /**
-   * Return a list containing all of the type parameters defined for this
-   * executable element.
-   */
-  List<TypeParameterElement> get typeParameters;
-}
-
-/**
- * A base class for concrete implementations of an [ExecutableElement].
- */
-abstract class ExecutableElementImpl extends ElementImpl
-    implements ExecutableElement {
-  /**
-   * An empty list of executable elements.
-   */
-  @deprecated // Use ExecutableElement.EMPTY_LIST
-  static const List<ExecutableElement> EMPTY_ARRAY =
-      const <ExecutableElement>[];
-
-  /**
-   * A list containing all of the functions defined within this executable
-   * element.
-   */
-  List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the labels defined within this executable element.
-   */
-  List<LabelElement> _labels = LabelElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the local variables defined within this executable
-   * element.
-   */
-  List<LocalVariableElement> _localVariables = LocalVariableElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the parameters defined by this executable element.
-   */
-  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the type parameters defined for this executable
-   * element.
-   */
-  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
-  /**
-   * The return type defined by this executable element.
-   */
-  DartType returnType;
-
-  /**
-   * The type of function defined by this executable element.
-   */
-  FunctionType type;
-
-  /**
-   * Initialize a newly created executable element to have the given [name] and
-   * [offset].
-   */
-  ExecutableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created executable element to have the given [name].
-   */
-  ExecutableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this executable element's body is asynchronous.
-   */
-  void set asynchronous(bool isAsynchronous) {
-    setModifier(Modifier.ASYNCHRONOUS, isAsynchronous);
-  }
-
-  /**
-   * Set whether this executable element is external.
-   */
-  void set external(bool isExternal) {
-    setModifier(Modifier.EXTERNAL, isExternal);
-  }
-
-  @override
-  List<FunctionElement> get functions => _functions;
-
-  /**
-   * Set the functions defined within this executable element to the given
-   * [functions].
-   */
-  void set functions(List<FunctionElement> functions) {
-    for (FunctionElement function in functions) {
-      (function as FunctionElementImpl).enclosingElement = this;
-    }
-    this._functions = functions;
-  }
-
-  /**
-   * Set whether this method's body is a generator.
-   */
-  void set generator(bool isGenerator) {
-    setModifier(Modifier.GENERATOR, isGenerator);
-  }
-
-  @override
-  bool get hasImplicitReturnType => hasModifier(Modifier.IMPLICIT_TYPE);
-
-  /**
-   * Set whether this executable element has an implicit return type.
-   */
-  void set hasImplicitReturnType(bool hasImplicitReturnType) {
-    setModifier(Modifier.IMPLICIT_TYPE, hasImplicitReturnType);
-  }
-
-  @override
-  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
-
-  @override
-  bool get isAsynchronous => hasModifier(Modifier.ASYNCHRONOUS);
-
-  @override
-  bool get isExternal => hasModifier(Modifier.EXTERNAL);
-
-  @override
-  bool get isGenerator => hasModifier(Modifier.GENERATOR);
-
-  @override
-  bool get isOperator => false;
-
-  @override
-  bool get isSynchronous => !hasModifier(Modifier.ASYNCHRONOUS);
-
-  @override
-  List<LabelElement> get labels => _labels;
-
-  /**
-   * Set the labels defined within this executable element to the given
-   * [labels].
-   */
-  void set labels(List<LabelElement> labels) {
-    for (LabelElement label in labels) {
-      (label as LabelElementImpl).enclosingElement = this;
-    }
-    this._labels = labels;
-  }
-
-  @override
-  List<LocalVariableElement> get localVariables => _localVariables;
-
-  /**
-   * Set the local variables defined within this executable element to the given
-   * [variables].
-   */
-  void set localVariables(List<LocalVariableElement> variables) {
-    for (LocalVariableElement variable in variables) {
-      (variable as LocalVariableElementImpl).enclosingElement = this;
-    }
-    this._localVariables = variables;
-  }
-
-  @override
-  List<ParameterElement> get parameters => _parameters;
-
-  /**
-   * Set the parameters defined by this executable element to the given
-   * [parameters].
-   */
-  void set parameters(List<ParameterElement> parameters) {
-    for (ParameterElement parameter in parameters) {
-      (parameter as ParameterElementImpl).enclosingElement = this;
-    }
-    this._parameters = parameters;
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters defined by this executable element to the given
-   * [typeParameters].
-   */
-  void set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement parameter in typeParameters) {
-      (parameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    this._typeParameters = typeParameters;
-  }
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    if (this.kind != ElementKind.GETTER) {
-      int typeParameterCount = _typeParameters.length;
-      if (typeParameterCount > 0) {
-        buffer.write('<');
-        for (int i = 0; i < typeParameterCount; i++) {
-          if (i > 0) {
-            buffer.write(", ");
-          }
-          (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
-        }
-        buffer.write('>');
-      }
-      buffer.write("(");
-      String closing = null;
-      ParameterKind kind = ParameterKind.REQUIRED;
-      int parameterCount = _parameters.length;
-      for (int i = 0; i < parameterCount; i++) {
-        if (i > 0) {
-          buffer.write(", ");
-        }
-        ParameterElementImpl parameter = _parameters[i] as ParameterElementImpl;
-        ParameterKind parameterKind = parameter.parameterKind;
-        if (parameterKind != kind) {
-          if (closing != null) {
-            buffer.write(closing);
-          }
-          if (parameterKind == ParameterKind.POSITIONAL) {
-            buffer.write("[");
-            closing = "]";
-          } else if (parameterKind == ParameterKind.NAMED) {
-            buffer.write("{");
-            closing = "}";
-          } else {
-            closing = null;
-          }
-        }
-        kind = parameterKind;
-        parameter.appendToWithoutDelimiters(buffer);
-      }
-      if (closing != null) {
-        buffer.write(closing);
-      }
-      buffer.write(")");
-    }
-    if (type != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(type.returnType);
-    }
-  }
-
-  @override
-  ElementImpl getChild(String identifier) {
-    for (ExecutableElement function in _functions) {
-      if ((function as ExecutableElementImpl).identifier == identifier) {
-        return function as ExecutableElementImpl;
-      }
-    }
-    for (LabelElement label in _labels) {
-      if ((label as LabelElementImpl).identifier == identifier) {
-        return label as LabelElementImpl;
-      }
-    }
-    for (VariableElement variable in _localVariables) {
-      if ((variable as VariableElementImpl).identifier == identifier) {
-        return variable as VariableElementImpl;
-      }
-    }
-    for (ParameterElement parameter in _parameters) {
-      if ((parameter as ParameterElementImpl).identifier == identifier) {
-        return parameter as ParameterElementImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_functions, visitor);
-    safelyVisitChildren(_labels, visitor);
-    safelyVisitChildren(_localVariables, visitor);
-    safelyVisitChildren(_parameters, visitor);
-  }
-}
-
-/**
- * An executable element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-abstract class ExecutableMember extends Member implements ExecutableElement {
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  ExecutableMember(ExecutableElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  ExecutableElement get baseElement => super.baseElement as ExecutableElement;
-
-  @override
-  List<FunctionElement> get functions {
-    //
-    // Elements within this element should have type parameters substituted,
-    // just like this element.
-    //
-    throw new UnsupportedOperationException();
-//    return getBaseElement().getFunctions();
-  }
-
-  @override
-  bool get hasImplicitReturnType => baseElement.hasImplicitReturnType;
-
-  @override
-  bool get isAbstract => baseElement.isAbstract;
-
-  @override
-  bool get isAsynchronous => baseElement.isAsynchronous;
-
-  @override
-  bool get isExternal => baseElement.isExternal;
-
-  @override
-  bool get isGenerator => baseElement.isGenerator;
-
-  @override
-  bool get isOperator => baseElement.isOperator;
-
-  @override
-  bool get isStatic => baseElement.isStatic;
-
-  @override
-  bool get isSynchronous => baseElement.isSynchronous;
-
-  @override
-  List<LabelElement> get labels => baseElement.labels;
-
-  @override
-  List<LocalVariableElement> get localVariables {
-    //
-    // Elements within this element should have type parameters substituted,
-    // just like this element.
-    //
-    throw new UnsupportedOperationException();
-//    return getBaseElement().getLocalVariables();
-  }
-
-  @override
-  List<ParameterElement> get parameters {
-    List<ParameterElement> baseParameters = baseElement.parameters;
-    int parameterCount = baseParameters.length;
-    if (parameterCount == 0) {
-      return baseParameters;
-    }
-    List<ParameterElement> parameterizedParameters =
-        new List<ParameterElement>(parameterCount);
-    for (int i = 0; i < parameterCount; i++) {
-      parameterizedParameters[i] =
-          ParameterMember.from(baseParameters[i], definingType);
-    }
-    return parameterizedParameters;
-  }
-
-  @override
-  DartType get returnType => substituteFor(baseElement.returnType);
-
-  @override
-  FunctionType get type => substituteFor(baseElement.type);
-
-  @override
-  List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // TODO(brianwilkerson) We need to finish implementing the accessors used
-    // below so that we can safely invoke them.
-    super.visitChildren(visitor);
-    safelyVisitChildren(baseElement.functions, visitor);
-    safelyVisitChildren(labels, visitor);
-    safelyVisitChildren(baseElement.localVariables, visitor);
-    safelyVisitChildren(parameters, visitor);
-  }
-}
-
-/**
- * An export directive within a library.
- */
-abstract class ExportElement implements Element, UriReferencedElement {
-  /**
-   * An empty list of export elements.
-   */
-  @deprecated // Use ExportElement.EMPTY_LIST
-  static const List<ExportElement> EMPTY_ARRAY = const <ExportElement>[];
-
-  /**
-   * An empty list of export elements.
-   */
-  static const List<ExportElement> EMPTY_LIST = const <ExportElement>[];
-
-  /**
-   * Return a list containing the combinators that were specified as part of the
-   * export directive in the order in which they were specified.
-   */
-  List<NamespaceCombinator> get combinators;
-
-  /**
-   * Return the library that is exported from this library by this export
-   * directive.
-   */
-  LibraryElement get exportedLibrary;
-}
-
-/**
- * A concrete implementation of an [ExportElement].
- */
-class ExportElementImpl extends UriReferencedElementImpl
-    implements ExportElement {
-  /**
-   * The library that is exported from this library by this export directive.
-   */
-  LibraryElement exportedLibrary;
-
-  /**
-   * The combinators that were specified as part of the export directive in the
-   * order in which they were specified.
-   */
-  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
-
-  /**
-   * Initialize a newly created export element at the given [offset].
-   */
-  ExportElementImpl(int offset) : super(null, offset);
-
-  @override
-  String get identifier => exportedLibrary.name;
-
-  @override
-  ElementKind get kind => ElementKind.EXPORT;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitExportElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write("export ");
-    (exportedLibrary as LibraryElementImpl).appendTo(buffer);
-  }
-}
-
-/**
- * A script tag in an HTML file having a `source` attribute that references a
- * Dart library source file.
- */
-@deprecated
-abstract class ExternalHtmlScriptElement implements HtmlScriptElement {
-  /**
-   * Return the source referenced by this element, or `null` if this element
-   * does not reference a Dart library source file.
-   */
-  Source get scriptSource;
-}
-
-/**
- * A concrete implementation of an [ExternalHtmlScriptElement].
- */
-@deprecated
-class ExternalHtmlScriptElementImpl extends HtmlScriptElementImpl
-    implements ExternalHtmlScriptElement {
-  /**
-   * The source specified in the `source` attribute or `null` if unspecified.
-   */
-  Source scriptSource;
-
-  /**
-   * Initialize a newly created script element to correspond to the given
-   * [node].
-   */
-  ExternalHtmlScriptElementImpl(XmlTagNode node) : super(node);
-
-  @override
-  ElementKind get kind => ElementKind.EXTERNAL_HTML_SCRIPT;
-
-  @override
-  accept(ElementVisitor visitor) =>
-      visitor.visitExternalHtmlScriptElement(this);
-}
-
-/**
- * A field defined within a type.
- */
-abstract class FieldElement
-    implements ClassMemberElement, PropertyInducingElement {
-  /**
-   * An empty list of field elements.
-   */
-  static const List<FieldElement> EMPTY_LIST = const <FieldElement>[];
-
-  /**
-   * Return {@code true} if this element is an enum constant.
-   */
-  bool get isEnumConstant;
-
-  /**
-   * Return the resolved [VariableDeclaration] or [EnumConstantDeclaration]
-   * node that declares this [FieldElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  AstNode computeNode();
-}
-
-/**
- * A concrete implementation of a [FieldElement].
- */
-class FieldElementImpl extends PropertyInducingElementImpl
-    implements FieldElement {
-  /**
-   * An empty list of field elements.
-   */
-  @deprecated // Use FieldElement.EMPTY_LIST
-  static const List<FieldElement> EMPTY_ARRAY = const <FieldElement>[];
-
-  /**
-   * Initialize a newly created synthetic field element to have the given [name]
-   * at the given [offset].
-   */
-  FieldElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created field element to have the given [name].
-   */
-  FieldElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
-
-  @override
-  bool get isEnumConstant =>
-      enclosingElement != null ? enclosingElement.isEnum : false;
-
-  @override
-  ElementKind get kind => ElementKind.FIELD;
-
-  /**
-   * Set whether this field is static.
-   */
-  void set static(bool isStatic) {
-    setModifier(Modifier.STATIC, isStatic);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
-
-  @override
-  AstNode computeNode() {
-    if (isEnumConstant) {
-      return getNodeMatching((node) => node is EnumConstantDeclaration);
-    } else {
-      return getNodeMatching((node) => node is VariableDeclaration);
-    }
-  }
-}
-
-/**
- * A field formal parameter defined within a constructor element.
- */
-abstract class FieldFormalParameterElement implements ParameterElement {
-  /**
-   * Return the field element associated with this field formal parameter, or
-   * `null` if the parameter references a field that doesn't exist.
-   */
-  FieldElement get field;
-}
-
-/**
- * A [ParameterElementImpl] that has the additional information of the
- * [FieldElement] associated with the parameter.
- */
-class FieldFormalParameterElementImpl extends ParameterElementImpl
-    implements FieldFormalParameterElement {
-  /**
-   * The field associated with this field formal parameter.
-   */
-  FieldElement field;
-
-  /**
-   * Initialize a newly created parameter element to have the given [name].
-   */
-  FieldFormalParameterElementImpl(Identifier name) : super.forNode(name);
-
-  @override
-  bool get isInitializingFormal => true;
-
-  @override
-  accept(ElementVisitor visitor) =>
-      visitor.visitFieldFormalParameterElement(this);
-}
-
-/**
- * A parameter element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-class FieldFormalParameterMember extends ParameterMember
-    implements FieldFormalParameterElement {
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  FieldFormalParameterMember(
-      FieldFormalParameterElement baseElement, ParameterizedType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  FieldElement get field {
-    FieldElement field = (baseElement as FieldFormalParameterElement).field;
-    if (field is FieldElement) {
-      return FieldMember.from(field, definingType);
-    }
-    return field;
-  }
-
-  @override
-  accept(ElementVisitor visitor) =>
-      visitor.visitFieldFormalParameterElement(this);
-}
-
-/**
- * A field element defined in a parameterized type where the values of the type
- * parameters are known.
- */
-class FieldMember extends VariableMember implements FieldElement {
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  FieldMember(FieldElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  FieldElement get baseElement => super.baseElement as FieldElement;
-
-  @override
-  InterfaceType get definingType => super.definingType as InterfaceType;
-
-  @override
-  ClassElement get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  PropertyAccessorElement get getter =>
-      PropertyAccessorMember.from(baseElement.getter, definingType);
-
-  @override
-  bool get isEnumConstant => baseElement.isEnumConstant;
-
-  @override
-  DartType get propagatedType => substituteFor(baseElement.propagatedType);
-
-  @override
-  PropertyAccessorElement get setter =>
-      PropertyAccessorMember.from(baseElement.setter, definingType);
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
-
-  @override
-  VariableDeclaration computeNode() => baseElement.computeNode();
-
-  @override
-  String toString() => '$type $displayName';
-
-  /**
-   * If the given [field]'s type is different when any type parameters from the
-   * defining type's declaration are replaced with the actual type arguments
-   * from the [definingType], create a field member representing the given
-   * field. Return the member that was created, or the base field if no member
-   * was created.
-   */
-  static FieldElement from(FieldElement field, InterfaceType definingType) {
-    if (!_isChangedByTypeSubstitution(field, definingType)) {
-      return field;
-    }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    return new FieldMember(field, definingType);
-  }
-
-  /**
-   * Determine whether the given [field]'s type is changed when type parameters
-   * from the [definingType]'s declaration are replaced with the actual type
-   * arguments from the defining type.
-   */
-  static bool _isChangedByTypeSubstitution(
-      FieldElement field, InterfaceType definingType) {
-    List<DartType> argumentTypes = definingType.typeArguments;
-    if (field != null && argumentTypes.length != 0) {
-      DartType baseType = field.type;
-      List<DartType> parameterTypes = definingType.element.type.typeArguments;
-      if (baseType != null) {
-        DartType substitutedType =
-            baseType.substitute2(argumentTypes, parameterTypes);
-        if (baseType != substitutedType) {
-          return true;
-        }
-      }
-      // If the field has a propagated type, then we need to check whether the
-      // propagated type needs substitution.
-      DartType basePropagatedType = field.propagatedType;
-      if (basePropagatedType != null) {
-        DartType substitutedPropagatedType =
-            basePropagatedType.substitute2(argumentTypes, parameterTypes);
-        if (basePropagatedType != substitutedPropagatedType) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-}
-
-/**
- * A (non-method) function. This can be either a top-level function, a local
- * function, a closure, or the initialization expression for a field or
- * variable.
- */
-abstract class FunctionElement implements ExecutableElement, LocalElement {
-  /**
-   * An empty list of function elements.
-   */
-  static const List<FunctionElement> EMPTY_LIST = const <FunctionElement>[];
-
-  /**
-   * The name of the method that can be implemented by a class to allow its
-   * instances to be invoked as if they were a function.
-   */
-  static final String CALL_METHOD_NAME = "call";
-
-  /**
-   * The name of the synthetic function defined for libraries that are deferred.
-   */
-  static final String LOAD_LIBRARY_NAME = "loadLibrary";
-
-  /**
-   * The name of the function used as an entry point.
-   */
-  static const String MAIN_FUNCTION_NAME = "main";
-
-  /**
-   * The name of the method that will be invoked if an attempt is made to invoke
-   * an undefined method on an object.
-   */
-  static final String NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod";
-
-  /**
-   * Return `true` if the function is an entry point, i.e. a top-level function
-   * and has the name `main`.
-   */
-  bool get isEntryPoint;
-
-  /**
-   * Return the resolved function declaration node that declares this element.
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  FunctionDeclaration computeNode();
-}
-
-/**
- * A concrete implementation of a [FunctionElement].
- */
-class FunctionElementImpl extends ExecutableElementImpl
-    implements FunctionElement {
-  /**
-   * An empty list of function elements.
-   */
-  @deprecated // Use FunctionElement.EMPTY_LIST
-  static const List<FunctionElement> EMPTY_ARRAY = const <FunctionElement>[];
-
-  /**
-   * The offset to the beginning of the visible range for this element.
-   */
-  int _visibleRangeOffset = 0;
-
-  /**
-   * The length of the visible range for this element, or `-1` if this element
-   * does not have a visible range.
-   */
-  int _visibleRangeLength = -1;
-
-  /**
-   * Initialize a newly created function element to have the given [name] and
-   * [offset].
-   */
-  FunctionElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created function element to have the given [name].
-   */
-  FunctionElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Initialize a newly created function element to have no name and the given
-   * [offset]. This is used for function expressions, that have no name.
-   */
-  FunctionElementImpl.forOffset(int nameOffset) : super("", nameOffset);
-
-  @override
-  String get identifier {
-    String identifier = super.identifier;
-    if (!isStatic) {
-      identifier += "@$nameOffset";
-    }
-    return identifier;
-  }
-
-  @override
-  bool get isEntryPoint {
-    return isStatic && displayName == FunctionElement.MAIN_FUNCTION_NAME;
-  }
-
-  @override
-  bool get isStatic => enclosingElement is CompilationUnitElement;
-
-  @override
-  ElementKind get kind => ElementKind.FUNCTION;
-
-  @override
-  SourceRange get visibleRange {
-    if (_visibleRangeLength < 0) {
-      return null;
-    }
-    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    String name = displayName;
-    if (name != null) {
-      buffer.write(name);
-    }
-    super.appendTo(buffer);
-  }
-
-  @override
-  FunctionDeclaration computeNode() =>
-      getNodeMatching((node) => node is FunctionDeclaration);
-
-  /**
-   * Set the visible range for this element to the range starting at the given
-   * [offset] with the given [length].
-   */
-  void setVisibleRange(int offset, int length) {
-    _visibleRangeOffset = offset;
-    _visibleRangeLength = length;
-  }
-}
-
-/**
- * The type of a function, method, constructor, getter, or setter. Function
- * types come in three variations:
- *
- * * The types of functions that only have required parameters. These have the
- *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>.
- * * The types of functions with optional positional parameters. These have the
- *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
- *   &hellip;, T<sub>n+k</sub>]) &rarr; T</i>.
- * * The types of functions with named parameters. These have the general form
- *   <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
- *   T<sub>xk</sub> xk}) &rarr; T</i>.
- */
-abstract class FunctionType implements ParameterizedType {
-  /**
-   * Return a map from the names of named parameters to the types of the named
-   * parameters of this type of function. The entries in the map will be
-   * iterated in the same order as the order in which the named parameters were
-   * defined. If there were no named parameters declared then the map will be
-   * empty.
-   */
-  Map<String, DartType> get namedParameterTypes;
-
-  /**
-   * Return a list containing the types of the normal parameters of this type of
-   * function. The parameter types are in the same order as they appear in the
-   * declaration of the function.
-   */
-  List<DartType> get normalParameterTypes;
-
-  /**
-   * Return a map from the names of optional (positional) parameters to the
-   * types of the optional parameters of this type of function. The entries in
-   * the map will be iterated in the same order as the order in which the
-   * optional parameters were defined. If there were no optional parameters
-   * declared then the map will be empty.
-   */
-  List<DartType> get optionalParameterTypes;
-
-  /**
-   * Return a list containing the parameters elements of this type of function.
-   * The parameter types are in the same order as they appear in the declaration
-   * of the function.
-   */
-  List<ParameterElement> get parameters;
-
-  /**
-   * Return the type of object returned by this type of function.
-   */
-  DartType get returnType;
-
-  /**
-   * Return `true` if this type is a subtype of the given [type].
-   *
-   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i> is
-   * a subtype of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>)
-   * &rarr; S</i>, if all of the following conditions are met:
-   *
-   * * Either
-   *   * <i>S</i> is void, or
-   *   * <i>T &hArr; S</i>.
-   *
-   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
-   *   S<sub>i</sub></i>.
-   *
-   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
-   * [T<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>]) &rarr; T</i> is a subtype of
-   * the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
-   * [S<sub>n+1</sub>, &hellip;, S<sub>n+m</sub>]) &rarr; S</i>, if all of the
-   * following conditions are met:
-   *
-   * * Either
-   *   * <i>S</i> is void, or
-   *   * <i>T &hArr; S</i>.
-   *
-   * * <i>k</i> >= <i>m</i> and for all <i>i</i>, 1 <= <i>i</i> <= <i>n+m</i>,
-   *   <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.
-   *
-   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
-   * {T<sub>x1</sub> x1, &hellip;, T<sub>xk</sub> xk}) &rarr; T</i> is a subtype
-   * of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
-   * {S<sub>y1</sub> y1, &hellip;, S<sub>ym</sub> ym}) &rarr; S</i>, if all of
-   * the following conditions are met:
-   * * Either
-   *   * <i>S</i> is void,
-   *   * or <i>T &hArr; S</i>.
-   *
-   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
-   *   S<sub>i</sub></i>.
-   * * <i>k</i> >= <i>m</i> and <i>y<sub>i</sub></i> in <i>{x<sub>1</sub>,
-   *   &hellip;, x<sub>k</sub>}</i>, 1 <= <i>i</i> <= <i>m</i>.
-   * * For all <i>y<sub>i</sub></i> in <i>{y<sub>1</sub>, &hellip;,
-   *   y<sub>m</sub>}</i>, <i>y<sub>i</sub> = x<sub>j</sub> => Tj &hArr; Si</i>.
-   *
-   * In addition, the following subtype rules apply:
-   *
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, []) &rarr; T <: (T<sub>1</sub>,
-   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
-   * &hellip;, T<sub>n</sub>, {}) &rarr; T.</i><br>
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {}) &rarr; T <: (T<sub>1</sub>,
-   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
-   * &hellip;, T<sub>n</sub>, []) &rarr; T.</i>
-   *
-   * All functions implement the class `Function`. However not all function
-   * types are a subtype of `Function`. If an interface type <i>I</i> includes a
-   * method named `call()`, and the type of `call()` is the function type
-   * <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
-   */
-  @override
-  bool isSubtypeOf(DartType type);
-
-  @override
-  FunctionType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes);
-
-  /**
-   * Return the type resulting from substituting the given [argumentTypes] for
-   * this type's parameters. This is fully equivalent to
-   * `substitute(argumentTypes, getTypeArguments())`.
-   */
-  FunctionType substitute3(List<DartType> argumentTypes);
-}
-
-/**
- * A function type alias (`typedef`).
- */
-abstract class FunctionTypeAliasElement implements TypeDefiningElement {
-  /**
-   * An empty array of type alias elements.
-   */
-  static List<FunctionTypeAliasElement> EMPTY_LIST =
-      new List<FunctionTypeAliasElement>(0);
-
-  /**
-   * Return the compilation unit in which this type alias is defined.
-   */
-  @override
-  CompilationUnitElement get enclosingElement;
-
-  /**
-   * Return a list containing all of the parameters defined by this type alias.
-   */
-  List<ParameterElement> get parameters;
-
-  /**
-   * Return the return type defined by this type alias.
-   */
-  DartType get returnType;
-
-  @override
-  FunctionType get type;
-
-  /**
-   * Return a list containing all of the type parameters defined for this type.
-   */
-  List<TypeParameterElement> get typeParameters;
-
-  /**
-   * Return the resolved function type alias node that declares this element.
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  FunctionTypeAlias computeNode();
-}
-
-/**
- * A concrete implementation of a [FunctionTypeAliasElement].
- */
-class FunctionTypeAliasElementImpl extends ElementImpl
-    implements FunctionTypeAliasElement {
-  /**
-   * An empty array of type alias elements.
-   */
-  @deprecated // Use FunctionTypeAliasElement.EMPTY_LIST
-  static List<FunctionTypeAliasElement> EMPTY_ARRAY =
-      new List<FunctionTypeAliasElement>(0);
-
-  /**
-   * A list containing all of the parameters defined by this type alias.
-   */
-  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
-
-  /**
-   * The return type defined by this type alias.
-   */
-  DartType returnType;
-
-  /**
-   * The type of function defined by this type alias.
-   */
-  FunctionType type;
-
-  /**
-   * A list containing all of the type parameters defined for this type.
-   */
-  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
-  /**
-   * Initialize a newly created type alias element to have the given name.
-   *
-   * [name] the name of this element
-   * [nameOffset] the offset of the name of this element in the file that
-   *    contains the declaration of this element
-   */
-  FunctionTypeAliasElementImpl(String name, int nameOffset)
-      : super(name, nameOffset);
-
-  /**
-   * Initialize a newly created type alias element to have the given [name].
-   */
-  FunctionTypeAliasElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  CompilationUnitElement get enclosingElement =>
-      super.enclosingElement as CompilationUnitElement;
-
-  @override
-  ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
-
-  @override
-  List<ParameterElement> get parameters => _parameters;
-
-  /**
-   * Set the parameters defined by this type alias to the given [parameters].
-   */
-  void set parameters(List<ParameterElement> parameters) {
-    if (parameters != null) {
-      for (ParameterElement parameter in parameters) {
-        (parameter as ParameterElementImpl).enclosingElement = this;
-      }
-    }
-    this._parameters = parameters;
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters defined for this type to the given
-   * [typeParameters].
-   */
-  void set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement typeParameter in typeParameters) {
-      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    this._typeParameters = typeParameters;
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitFunctionTypeAliasElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write("typedef ");
-    buffer.write(displayName);
-    int typeParameterCount = _typeParameters.length;
-    if (typeParameterCount > 0) {
-      buffer.write("<");
-      for (int i = 0; i < typeParameterCount; i++) {
-        if (i > 0) {
-          buffer.write(", ");
-        }
-        (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
-      }
-      buffer.write(">");
-    }
-    buffer.write("(");
-    int parameterCount = _parameters.length;
-    for (int i = 0; i < parameterCount; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      (_parameters[i] as ParameterElementImpl).appendTo(buffer);
-    }
-    buffer.write(")");
-    if (type != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(type.returnType);
-    } else if (returnType != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(returnType);
-    }
-  }
-
-  @override
-  FunctionTypeAlias computeNode() =>
-      getNodeMatching((node) => node is FunctionTypeAlias);
-
-  @override
-  ElementImpl getChild(String identifier) {
-    for (VariableElement parameter in _parameters) {
-      if ((parameter as VariableElementImpl).identifier == identifier) {
-        return parameter as VariableElementImpl;
-      }
-    }
-    for (TypeParameterElement typeParameter in _typeParameters) {
-      if ((typeParameter as TypeParameterElementImpl).identifier ==
-          identifier) {
-        return typeParameter as TypeParameterElementImpl;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Set the parameters defined by this type alias to the given [parameters]
-   * without becoming the parent of the parameters. This should only be used by
-   * the [TypeResolverVisitor] when creating a synthetic type alias.
-   */
-  void shareParameters(List<ParameterElement> parameters) {
-    this._parameters = parameters;
-  }
-
-  /**
-   * Set the type parameters defined for this type to the given [typeParameters]
-   * without becoming the parent of the parameters. This should only be used by
-   * the [TypeResolverVisitor] when creating a synthetic type alias.
-   */
-  void shareTypeParameters(List<TypeParameterElement> typeParameters) {
-    this._typeParameters = typeParameters;
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_parameters, visitor);
-    safelyVisitChildren(_typeParameters, visitor);
-  }
-}
-
-/**
- * The type of a function, method, constructor, getter, or setter.
- */
-class FunctionTypeImpl extends TypeImpl implements FunctionType {
-  /**
-   * A list containing the actual types of the type arguments.
-   */
-  List<DartType> typeArguments = DartType.EMPTY_LIST;
-
-  /**
-   * The set of typedefs which should not be expanded when exploring this type,
-   * to avoid creating infinite types in response to self-referential typedefs.
-   */
-  final List<FunctionTypeAliasElement> prunedTypedefs;
-
-  /**
-   * Initialize a newly created function type to be declared by the given
-   * [element].
-   */
-  FunctionTypeImpl(ExecutableElement element, [this.prunedTypedefs])
-      : super(element, null);
-
-  /**
-   * Initialize a newly created function type to be declared by the given
-   * [element].
-   */
-  @deprecated // Use new FunctionTypeImpl(element)
-  FunctionTypeImpl.con1(ExecutableElement element)
-      : prunedTypedefs = null,
-        super(element, null);
-
-  /**
-   * Initialize a newly created function type to be declared by the given
-   * [element].
-   */
-  @deprecated // Use new FunctionTypeImpl.forTypedef(element)
-  FunctionTypeImpl.con2(FunctionTypeAliasElement element)
-      : prunedTypedefs = null,
-        super(element, element == null ? null : element.name);
-
-  /**
-   * Initialize a newly created function type to be declared by the given
-   * [element].
-   */
-  FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
-      [this.prunedTypedefs])
-      : super(element, element == null ? null : element.name);
-
-  /**
-   * Private constructor.
-   */
-  FunctionTypeImpl._(Element element, String name, this.prunedTypedefs)
-      : super(element, name);
-
-  /**
-   * Return the base parameter elements of this function element.
-   */
-  List<ParameterElement> get baseParameters {
-    Element element = this.element;
-    if (element is ExecutableElement) {
-      return element.parameters;
-    } else {
-      return (element as FunctionTypeAliasElement).parameters;
-    }
-  }
-
-  /**
-   * Return the return type defined by this function's element.
-   */
-  DartType get baseReturnType {
-    Element element = this.element;
-    if (element is ExecutableElement) {
-      return element.returnType;
-    } else {
-      return (element as FunctionTypeAliasElement).returnType;
-    }
-  }
-
-  @override
-  String get displayName {
-    String name = this.name;
-    if (name == null || name.length == 0) {
-      // Function types have an empty name when they are defined implicitly by
-      // either a closure or as part of a parameter declaration.
-      List<DartType> normalParameterTypes = this.normalParameterTypes;
-      List<DartType> optionalParameterTypes = this.optionalParameterTypes;
-      Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
-      DartType returnType = this.returnType;
-      StringBuffer buffer = new StringBuffer();
-      buffer.write("(");
-      bool needsComma = false;
-      if (normalParameterTypes.length > 0) {
-        for (DartType type in normalParameterTypes) {
-          if (needsComma) {
-            buffer.write(", ");
-          } else {
-            needsComma = true;
-          }
-          buffer.write(type.displayName);
-        }
-      }
-      if (optionalParameterTypes.length > 0) {
-        if (needsComma) {
-          buffer.write(", ");
-          needsComma = false;
-        }
-        buffer.write("[");
-        for (DartType type in optionalParameterTypes) {
-          if (needsComma) {
-            buffer.write(", ");
-          } else {
-            needsComma = true;
-          }
-          buffer.write(type.displayName);
-        }
-        buffer.write("]");
-        needsComma = true;
-      }
-      if (namedParameterTypes.length > 0) {
-        if (needsComma) {
-          buffer.write(", ");
-          needsComma = false;
-        }
-        buffer.write("{");
-        namedParameterTypes.forEach((String name, DartType type) {
-          if (needsComma) {
-            buffer.write(", ");
-          } else {
-            needsComma = true;
-          }
-          buffer.write(name);
-          buffer.write(": ");
-          buffer.write(type.displayName);
-        });
-        buffer.write("}");
-        needsComma = true;
-      }
-      buffer.write(")");
-      buffer.write(Element.RIGHT_ARROW);
-      if (returnType == null) {
-        buffer.write("null");
-      } else {
-        buffer.write(returnType.displayName);
-      }
-      name = buffer.toString();
-    }
-    return name;
-  }
-
-  @override
-  int get hashCode {
-    if (element == null) {
-      return 0;
-    }
-    // Reference the arrays of parameters
-    List<DartType> normalParameterTypes = this.normalParameterTypes;
-    List<DartType> optionalParameterTypes = this.optionalParameterTypes;
-    Iterable<DartType> namedParameterTypes = this.namedParameterTypes.values;
-    // Generate the hashCode
-    int code = (returnType as TypeImpl).hashCode;
-    for (int i = 0; i < normalParameterTypes.length; i++) {
-      code = (code << 1) + (normalParameterTypes[i] as TypeImpl).hashCode;
-    }
-    for (int i = 0; i < optionalParameterTypes.length; i++) {
-      code = (code << 1) + (optionalParameterTypes[i] as TypeImpl).hashCode;
-    }
-    for (DartType type in namedParameterTypes) {
-      code = (code << 1) + (type as TypeImpl).hashCode;
-    }
-    return code;
-  }
-
-  @override
-  Map<String, DartType> get namedParameterTypes {
-    LinkedHashMap<String, DartType> namedParameterTypes =
-        new LinkedHashMap<String, DartType>();
-    List<ParameterElement> parameters = baseParameters;
-    if (parameters.length == 0) {
-      return namedParameterTypes;
-    }
-    List<DartType> typeParameters =
-        TypeParameterTypeImpl.getTypes(this.typeParameters);
-    for (ParameterElement parameter in parameters) {
-      if (parameter.parameterKind == ParameterKind.NAMED) {
-        DartType type = parameter.type;
-        if (typeArguments.length != 0 &&
-            typeArguments.length == typeParameters.length) {
-          type = (type as TypeImpl)
-              .substitute2(typeArguments, typeParameters, newPrune);
-        } else {
-          type = (type as TypeImpl).pruned(newPrune);
-        }
-        namedParameterTypes[parameter.name] = type;
-      }
-    }
-    return namedParameterTypes;
-  }
-
-  /**
-   * Determine the new set of typedefs which should be pruned when expanding
-   * this function type.
-   */
-  List<FunctionTypeAliasElement> get newPrune {
-    Element element = this.element;
-    if (element is FunctionTypeAliasElement && !element.isSynthetic) {
-      // This typedef should be pruned, along with anything that was previously
-      // pruned.
-      if (prunedTypedefs == null) {
-        return <FunctionTypeAliasElement>[element];
-      } else {
-        return new List<FunctionTypeAliasElement>.from(prunedTypedefs)
-          ..add(element);
-      }
-    } else {
-      // This is not a typedef, so nothing additional needs to be pruned.
-      return prunedTypedefs;
-    }
-  }
-
-  @override
-  List<DartType> get normalParameterTypes {
-    List<ParameterElement> parameters = baseParameters;
-    if (parameters.length == 0) {
-      return DartType.EMPTY_LIST;
-    }
-    List<DartType> typeParameters =
-        TypeParameterTypeImpl.getTypes(this.typeParameters);
-    List<DartType> types = new List<DartType>();
-    for (ParameterElement parameter in parameters) {
-      if (parameter.parameterKind == ParameterKind.REQUIRED) {
-        DartType type = parameter.type;
-        if (typeArguments.length != 0 &&
-            typeArguments.length == typeParameters.length) {
-          type = (type as TypeImpl)
-              .substitute2(typeArguments, typeParameters, newPrune);
-        } else {
-          type = (type as TypeImpl).pruned(newPrune);
-        }
-        types.add(type);
-      }
-    }
-    return types;
-  }
-
-  @override
-  List<DartType> get optionalParameterTypes {
-    List<ParameterElement> parameters = baseParameters;
-    if (parameters.length == 0) {
-      return DartType.EMPTY_LIST;
-    }
-    List<DartType> typeParameters =
-        TypeParameterTypeImpl.getTypes(this.typeParameters);
-    List<DartType> types = new List<DartType>();
-    for (ParameterElement parameter in parameters) {
-      if (parameter.parameterKind == ParameterKind.POSITIONAL) {
-        DartType type = parameter.type;
-        if (typeArguments.length != 0 &&
-            typeArguments.length == typeParameters.length) {
-          type = (type as TypeImpl)
-              .substitute2(typeArguments, typeParameters, newPrune);
-        } else {
-          type = (type as TypeImpl).pruned(newPrune);
-        }
-        types.add(type);
-      }
-    }
-    return types;
-  }
-
-  @override
-  List<ParameterElement> get parameters {
-    List<ParameterElement> baseParameters = this.baseParameters;
-    // no parameters, quick return
-    int parameterCount = baseParameters.length;
-    if (parameterCount == 0) {
-      return baseParameters;
-    }
-    // create specialized parameters
-    List<ParameterElement> specializedParameters =
-        new List<ParameterElement>(parameterCount);
-    for (int i = 0; i < parameterCount; i++) {
-      specializedParameters[i] = ParameterMember.from(baseParameters[i], this);
-    }
-    return specializedParameters;
-  }
-
-  @override
-  DartType get returnType {
-    DartType baseReturnType = this.baseReturnType;
-    if (baseReturnType == null) {
-      // TODO(brianwilkerson) This is a patch. The return type should never be
-      // null and we need to understand why it is and fix it.
-      return DynamicTypeImpl.instance;
-    }
-    // If there are no arguments to substitute, or if the arguments size doesn't
-    // match the parameter size, return the base return type.
-    if (typeArguments.length == 0 ||
-        typeArguments.length != typeParameters.length) {
-      return (baseReturnType as TypeImpl).pruned(newPrune);
-    }
-    return (baseReturnType as TypeImpl).substitute2(typeArguments,
-        TypeParameterTypeImpl.getTypes(typeParameters), newPrune);
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters {
-    Element element = this.element;
-    if (element is FunctionTypeAliasElement) {
-      return element.typeParameters;
-    }
-    ClassElement definingClass =
-        element.getAncestor((element) => element is ClassElement);
-    if (definingClass != null) {
-      return definingClass.typeParameters;
-    }
-    return TypeParameterElement.EMPTY_LIST;
-  }
-
-  @override
-  bool operator ==(Object object) {
-    if (object is! FunctionTypeImpl) {
-      return false;
-    }
-    FunctionTypeImpl otherType = object as FunctionTypeImpl;
-    return returnType == otherType.returnType &&
-        TypeImpl.equalArrays(
-            normalParameterTypes, otherType.normalParameterTypes) &&
-        TypeImpl.equalArrays(
-            optionalParameterTypes, otherType.optionalParameterTypes) &&
-        _equals(namedParameterTypes, otherType.namedParameterTypes);
-  }
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    List<DartType> normalParameterTypes = this.normalParameterTypes;
-    List<DartType> optionalParameterTypes = this.optionalParameterTypes;
-    Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
-    DartType returnType = this.returnType;
-    buffer.write("(");
-    bool needsComma = false;
-    if (normalParameterTypes.length > 0) {
-      for (DartType type in normalParameterTypes) {
-        if (needsComma) {
-          buffer.write(", ");
-        } else {
-          needsComma = true;
-        }
-        (type as TypeImpl).appendTo(buffer);
-      }
-    }
-    if (optionalParameterTypes.length > 0) {
-      if (needsComma) {
-        buffer.write(", ");
-        needsComma = false;
-      }
-      buffer.write("[");
-      for (DartType type in optionalParameterTypes) {
-        if (needsComma) {
-          buffer.write(", ");
-        } else {
-          needsComma = true;
-        }
-        (type as TypeImpl).appendTo(buffer);
-      }
-      buffer.write("]");
-      needsComma = true;
-    }
-    if (namedParameterTypes.length > 0) {
-      if (needsComma) {
-        buffer.write(", ");
-        needsComma = false;
-      }
-      buffer.write("{");
-      namedParameterTypes.forEach((String name, DartType type) {
-        if (needsComma) {
-          buffer.write(", ");
-        } else {
-          needsComma = true;
-        }
-        buffer.write(name);
-        buffer.write(": ");
-        (type as TypeImpl).appendTo(buffer);
-      });
-      buffer.write("}");
-      needsComma = true;
-    }
-    buffer.write(")");
-    buffer.write(Element.RIGHT_ARROW);
-    if (returnType == null) {
-      buffer.write("null");
-    } else {
-      (returnType as TypeImpl).appendTo(buffer);
-    }
-  }
-
-  @override
-  bool isAssignableTo(DartType type) {
-    // A function type T may be assigned to a function type S, written T <=> S,
-    // iff T <: S.
-    return isSubtypeOf(type);
-  }
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    // Note: visitedElements is only used for breaking recursion in the type
-    // hierarchy; we don't use it when recursing into the function type.
-
-    // trivial base cases
-    if (type == null) {
-      return false;
-    } else if (identical(this, type) ||
-        type.isDynamic ||
-        type.isDartCoreFunction ||
-        type.isObject) {
-      return true;
-    } else if (type is! FunctionType) {
-      return false;
-    } else if (this == type) {
-      return true;
-    }
-    FunctionType t = this;
-    FunctionType s = type as FunctionType;
-    List<DartType> tTypes = t.normalParameterTypes;
-    List<DartType> tOpTypes = t.optionalParameterTypes;
-    List<DartType> sTypes = s.normalParameterTypes;
-    List<DartType> sOpTypes = s.optionalParameterTypes;
-    // If one function has positional and the other has named parameters,
-    // return false.
-    if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
-        (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
-      return false;
-    }
-    // named parameters case
-    if (t.namedParameterTypes.length > 0) {
-      // check that the number of required parameters are equal, and check that
-      // every t_i is more specific than every s_i
-      if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
-        return false;
-      } else if (t.normalParameterTypes.length > 0) {
-        for (int i = 0; i < tTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl)
-              .isMoreSpecificThan(sTypes[i], withDynamic)) {
-            return false;
-          }
-        }
-      }
-      Map<String, DartType> namedTypesT = t.namedParameterTypes;
-      Map<String, DartType> namedTypesS = s.namedParameterTypes;
-      // if k >= m is false, return false: the passed function type has more
-      // named parameter types than this
-      if (namedTypesT.length < namedTypesS.length) {
-        return false;
-      }
-      // Loop through each element in S verifying that T has a matching
-      // parameter name and that the corresponding type is more specific then
-      // the type in S.
-      for (String keyS in namedTypesS.keys) {
-        DartType typeT = namedTypesT[keyS];
-        if (typeT == null) {
-          return false;
-        }
-        if (!(typeT as TypeImpl)
-            .isMoreSpecificThan(namedTypesS[keyS], withDynamic)) {
-          return false;
-        }
-      }
-    } else if (s.namedParameterTypes.length > 0) {
-      return false;
-    } else {
-      // positional parameter case
-      int tArgLength = tTypes.length + tOpTypes.length;
-      int sArgLength = sTypes.length + sOpTypes.length;
-      // Check that the total number of parameters in t is greater than or equal
-      // to the number of parameters in s and that the number of required
-      // parameters in s is greater than or equal to the number of required
-      // parameters in t.
-      if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
-        return false;
-      }
-      if (tOpTypes.length == 0 && sOpTypes.length == 0) {
-        // No positional arguments, don't copy contents to new array
-        for (int i = 0; i < sTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl)
-              .isMoreSpecificThan(sTypes[i], withDynamic)) {
-            return false;
-          }
-        }
-      } else {
-        // Else, we do have positional parameters, copy required and positional
-        // parameter types into arrays to do the compare (for loop below).
-        List<DartType> tAllTypes = new List<DartType>(sArgLength);
-        for (int i = 0; i < tTypes.length; i++) {
-          tAllTypes[i] = tTypes[i];
-        }
-        for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
-          tAllTypes[i] = tOpTypes[j];
-        }
-        List<DartType> sAllTypes = new List<DartType>(sArgLength);
-        for (int i = 0; i < sTypes.length; i++) {
-          sAllTypes[i] = sTypes[i];
-        }
-        for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
-          sAllTypes[i] = sOpTypes[j];
-        }
-        for (int i = 0; i < sAllTypes.length; i++) {
-          if (!(tAllTypes[i] as TypeImpl)
-              .isMoreSpecificThan(sAllTypes[i], withDynamic)) {
-            return false;
-          }
-        }
-      }
-    }
-    DartType tRetType = t.returnType;
-    DartType sRetType = s.returnType;
-    return sRetType.isVoid ||
-        (tRetType as TypeImpl).isMoreSpecificThan(sRetType, withDynamic);
-  }
-
-  @override
-  bool isSubtypeOf(DartType type) {
-    // trivial base cases
-    if (type == null) {
-      return false;
-    } else if (identical(this, type) ||
-        type.isDynamic ||
-        type.isDartCoreFunction ||
-        type.isObject) {
-      return true;
-    } else if (type is! FunctionType) {
-      return false;
-    } else if (this == type) {
-      return true;
-    }
-    FunctionType t = this;
-    FunctionType s = type as FunctionType;
-    List<DartType> tTypes = t.normalParameterTypes;
-    List<DartType> tOpTypes = t.optionalParameterTypes;
-    List<DartType> sTypes = s.normalParameterTypes;
-    List<DartType> sOpTypes = s.optionalParameterTypes;
-    // If one function has positional and the other has named parameters,
-    // return false.
-    if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
-        (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
-      return false;
-    }
-    // named parameters case
-    if (t.namedParameterTypes.length > 0) {
-      // check that the number of required parameters are equal,
-      // and check that every t_i is assignable to every s_i
-      if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
-        return false;
-      } else if (t.normalParameterTypes.length > 0) {
-        for (int i = 0; i < tTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
-            return false;
-          }
-        }
-      }
-      Map<String, DartType> namedTypesT = t.namedParameterTypes;
-      Map<String, DartType> namedTypesS = s.namedParameterTypes;
-      // if k >= m is false, return false: the passed function type has more
-      // named parameter types than this
-      if (namedTypesT.length < namedTypesS.length) {
-        return false;
-      }
-      // Loop through each element in S verifying that T has a matching
-      // parameter name and that the corresponding type is assignable to the
-      // type in S.
-      for (String keyS in namedTypesS.keys) {
-        DartType typeT = namedTypesT[keyS];
-        if (typeT == null) {
-          return false;
-        }
-        if (!(typeT as TypeImpl).isAssignableTo(namedTypesS[keyS])) {
-          return false;
-        }
-      }
-    } else if (s.namedParameterTypes.length > 0) {
-      return false;
-    } else {
-      // positional parameter case
-      int tArgLength = tTypes.length + tOpTypes.length;
-      int sArgLength = sTypes.length + sOpTypes.length;
-      // Check that the total number of parameters in t is greater than or
-      // equal to the number of parameters in s and that the number of
-      // required parameters in s is greater than or equal to the number of
-      // required parameters in t.
-      if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
-        return false;
-      }
-      if (tOpTypes.length == 0 && sOpTypes.length == 0) {
-        // No positional arguments, don't copy contents to new array
-        for (int i = 0; i < sTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
-            return false;
-          }
-        }
-      } else {
-        // Else, we do have positional parameters, copy required and
-        // positional parameter types into arrays to do the compare (for loop
-        // below).
-        List<DartType> tAllTypes = new List<DartType>(sArgLength);
-        for (int i = 0; i < tTypes.length; i++) {
-          tAllTypes[i] = tTypes[i];
-        }
-        for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
-          tAllTypes[i] = tOpTypes[j];
-        }
-        List<DartType> sAllTypes = new List<DartType>(sArgLength);
-        for (int i = 0; i < sTypes.length; i++) {
-          sAllTypes[i] = sTypes[i];
-        }
-        for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
-          sAllTypes[i] = sOpTypes[j];
-        }
-        for (int i = 0; i < sAllTypes.length; i++) {
-          if (!(tAllTypes[i] as TypeImpl).isAssignableTo(sAllTypes[i])) {
-            return false;
-          }
-        }
-      }
-    }
-    DartType tRetType = t.returnType;
-    DartType sRetType = s.returnType;
-    return sRetType.isVoid || (tRetType as TypeImpl).isAssignableTo(sRetType);
-  }
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) {
-    if (prune == null) {
-      return this;
-    } else if (prune.contains(element)) {
-      // Circularity found.  Prune the type declaration.
-      return new CircularTypeImpl();
-    } else {
-      // There should never be a reason to prune a type that has already been
-      // pruned, since pruning is only done when expanding a function type
-      // alias, and function type aliases are always expanded by starting with
-      // base types.
-      assert(this.prunedTypedefs == null);
-      FunctionTypeImpl result = new FunctionTypeImpl._(element, name, prune);
-      result.typeArguments =
-          typeArguments.map((TypeImpl t) => t.pruned(prune)).toList();
-      return result;
-    }
-  }
-
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    // Pruned types should only ever result from peforming type variable
-    // substitution, and it doesn't make sense to substitute again after
-    // substituting once.
-    assert(this.prunedTypedefs == null);
-    if (argumentTypes.length != parameterTypes.length) {
-      throw new IllegalArgumentException(
-          "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
-    }
-    Element element = this.element;
-    if (prune != null && prune.contains(element)) {
-      // Circularity found.  Prune the type declaration.
-      return new CircularTypeImpl();
-    }
-    if (argumentTypes.length == 0) {
-      return this.pruned(prune);
-    }
-    FunctionTypeImpl newType = (element is ExecutableElement)
-        ? new FunctionTypeImpl(element, prune)
-        : new FunctionTypeImpl.forTypedef(
-            element as FunctionTypeAliasElement, prune);
-    newType.typeArguments =
-        TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes);
-    return newType;
-  }
-
-  @override
-  FunctionTypeImpl substitute3(List<DartType> argumentTypes) =>
-      substitute2(argumentTypes, typeArguments);
-
-  /**
-   * Compute the least upper bound of types [f] and [g], both of which are
-   * known to be function types.
-   *
-   * In the event that f and g have different numbers of required parameters,
-   * `null` is returned, in which case the least upper bound is the interface
-   * type `Function`.
-   */
-  static FunctionType computeLeastUpperBound(FunctionType f, FunctionType g) {
-    // TODO(paulberry): implement this.
-    return null;
-  }
-
-  /**
-   * Return `true` if all of the name/type pairs in the first map ([firstTypes])
-   * are equal to the corresponding name/type pairs in the second map
-   * ([secondTypes]). The maps are expected to iterate over their entries in the
-   * same order in which those entries were added to the map.
-   */
-  static bool _equals(
-      Map<String, DartType> firstTypes, Map<String, DartType> secondTypes) {
-    if (secondTypes.length != firstTypes.length) {
-      return false;
-    }
-    Iterator<String> firstKeys = firstTypes.keys.iterator;
-    Iterator<String> secondKeys = secondTypes.keys.iterator;
-    while (firstKeys.moveNext() && secondKeys.moveNext()) {
-      String firstKey = firstKeys.current;
-      String secondKey = secondKeys.current;
-      TypeImpl firstType = firstTypes[firstKey];
-      TypeImpl secondType = secondTypes[secondKey];
-      if (firstKey != secondKey || firstType != secondType) {
-        return false;
-      }
-    }
-    return true;
-  }
-}
-
-/**
- * An element visitor that will recursively visit all of the elements in an
- * element model (like instances of the class [RecursiveElementVisitor]). In
- * addition, when an element of a specific type is visited not only will the
- * visit method for that specific type of element be invoked, but additional
- * methods for the supertypes of that element will also be invoked. For example,
- * using an instance of this class to visit a [MethodElement] will cause the
- * method [visitMethodElement] to be invoked but will also cause the methods
- * [visitExecutableElement] and [visitElement] to be subsequently invoked. This
- * allows visitors to be written that visit all executable elements without
- * needing to override the visit method for each of the specific subclasses of
- * [ExecutableElement].
- *
- * Note, however, that unlike many visitors, element visitors visit objects
- * based on the interfaces implemented by those elements. Because interfaces
- * form a graph structure rather than a tree structure the way classes do, and
- * because it is generally undesirable for an object to be visited more than
- * once, this class flattens the interface graph into a pseudo-tree. In
- * particular, this class treats elements as if the element types were
- * structured in the following way:
- *
- * <pre>
- * Element
- *   ClassElement
- *   CompilationUnitElement
- *   ExecutableElement
- *       ConstructorElement
- *       LocalElement
- *           FunctionElement
- *       MethodElement
- *       PropertyAccessorElement
- *   ExportElement
- *   HtmlElement
- *   ImportElement
- *   LabelElement
- *   LibraryElement
- *   MultiplyDefinedElement
- *   PrefixElement
- *   TypeAliasElement
- *   TypeParameterElement
- *   UndefinedElement
- *   VariableElement
- *       PropertyInducingElement
- *           FieldElement
- *           TopLevelVariableElement
- *       LocalElement
- *           LocalVariableElement
- *           ParameterElement
- *               FieldFormalParameterElement
- * </pre>
- *
- * Subclasses that override a visit method must either invoke the overridden
- * visit method or explicitly invoke the more general visit method. Failure to
- * do so will cause the visit methods for superclasses of the element to not be
- * invoked and will cause the children of the visited node to not be visited.
- */
-class GeneralizingElementVisitor<R> implements ElementVisitor<R> {
-  @override
-  R visitClassElement(ClassElement element) => visitElement(element);
-
-  @override
-  R visitCompilationUnitElement(CompilationUnitElement element) =>
-      visitElement(element);
-
-  @override
-  R visitConstructorElement(ConstructorElement element) =>
-      visitExecutableElement(element);
-
-  R visitElement(Element element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  @deprecated
-  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) =>
-      visitHtmlScriptElement(element);
-
-  R visitExecutableElement(ExecutableElement element) => visitElement(element);
-
-  @override
-  R visitExportElement(ExportElement element) => visitElement(element);
-
-  @override
-  @deprecated
-  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) =>
-      visitHtmlScriptElement(element);
-
-  @override
-  R visitFieldElement(FieldElement element) =>
-      visitPropertyInducingElement(element);
-
-  @override
-  R visitFieldFormalParameterElement(FieldFormalParameterElement element) =>
-      visitParameterElement(element);
-
-  @override
-  R visitFunctionElement(FunctionElement element) => visitLocalElement(element);
-
-  @override
-  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) =>
-      visitElement(element);
-
-  @override
-  @deprecated
-  R visitHtmlElement(HtmlElement element) => visitElement(element);
-
-  @deprecated
-  R visitHtmlScriptElement(HtmlScriptElement element) => visitElement(element);
-
-  @override
-  R visitImportElement(ImportElement element) => visitElement(element);
-
-  @override
-  R visitLabelElement(LabelElement element) => visitElement(element);
-
-  @override
-  R visitLibraryElement(LibraryElement element) => visitElement(element);
-
-  R visitLocalElement(LocalElement element) {
-    if (element is LocalVariableElement) {
-      return visitVariableElement(element);
-    } else if (element is ParameterElement) {
-      return visitVariableElement(element);
-    } else if (element is FunctionElement) {
-      return visitExecutableElement(element);
-    }
-    return null;
-  }
-
-  @override
-  R visitLocalVariableElement(LocalVariableElement element) =>
-      visitLocalElement(element);
-
-  @override
-  R visitMethodElement(MethodElement element) =>
-      visitExecutableElement(element);
-
-  @override
-  R visitMultiplyDefinedElement(MultiplyDefinedElement element) =>
-      visitElement(element);
-
-  @override
-  R visitParameterElement(ParameterElement element) =>
-      visitLocalElement(element);
-
-  @override
-  R visitPrefixElement(PrefixElement element) => visitElement(element);
-
-  @override
-  R visitPropertyAccessorElement(PropertyAccessorElement element) =>
-      visitExecutableElement(element);
-
-  R visitPropertyInducingElement(PropertyInducingElement element) =>
-      visitVariableElement(element);
-
-  @override
-  R visitTopLevelVariableElement(TopLevelVariableElement element) =>
-      visitPropertyInducingElement(element);
-
-  @override
-  R visitTypeParameterElement(TypeParameterElement element) =>
-      visitElement(element);
-
-  R visitVariableElement(VariableElement element) => visitElement(element);
-}
-
-/**
- * A combinator that causes some of the names in a namespace to be hidden when
- * being imported.
- */
-abstract class HideElementCombinator implements NamespaceCombinator {
-  /**
-   * Return a list containing the names that are not to be made visible in the
-   * importing library even if they are defined in the imported library.
-   */
-  List<String> get hiddenNames;
-}
-
-/**
- * A concrete implementation of a [HideElementCombinator].
- */
-class HideElementCombinatorImpl implements HideElementCombinator {
-  /**
-   * The names that are not to be made visible in the importing library even if
-   * they are defined in the imported library.
-   */
-  List<String> hiddenNames = StringUtilities.EMPTY_ARRAY;
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("show ");
-    int count = hiddenNames.length;
-    for (int i = 0; i < count; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      buffer.write(hiddenNames[i]);
-    }
-    return buffer.toString();
-  }
-}
-
-/**
- * An HTML file.
- */
-@deprecated
-abstract class HtmlElement implements Element {
-  /**
-   * An empty list of HTML file elements.
-   */
-  static const List<HtmlElement> EMPTY_LIST = const <HtmlElement>[];
-
-  /**
-   * Return a list containing all of the script elements contained in the HTML
-   * file. This includes scripts with libraries that are defined by the content
-   * of a script tag as well as libraries that are referenced in the `source`
-   * attribute of a script tag.
-   */
-  List<HtmlScriptElement> get scripts;
-}
-
-/**
- * A concrete implementation of an [HtmlElement].
- */
-@deprecated
-class HtmlElementImpl extends ElementImpl implements HtmlElement {
-  /**
-   * An empty list of HTML file elements.
-   */
-  @deprecated // Use HtmlElement.EMPTY_LIST
-  static const List<HtmlElement> EMPTY_ARRAY = const <HtmlElement>[];
-
-  /**
-   * The analysis context in which this library is defined.
-   */
-  final AnalysisContext context;
-
-  /**
-   * The scripts contained in or referenced from script tags in the HTML file.
-   */
-  List<HtmlScriptElement> _scripts = HtmlScriptElement.EMPTY_LIST;
-
-  /**
-   * The source that corresponds to this HTML file.
-   */
-  Source source;
-
-  /**
-   * Initialize a newly created HTML element in the given [context] to have the
-   * given [name].
-   */
-  HtmlElementImpl(this.context, String name) : super(name, -1);
-
-  @override
-  int get hashCode => source.hashCode;
-
-  @override
-  String get identifier => source.encoding;
-
-  @override
-  ElementKind get kind => ElementKind.HTML;
-
-  @override
-  List<HtmlScriptElement> get scripts => _scripts;
-
-  /**
-   * Set the scripts contained in the HTML file to the given [scripts].
-   */
-  void set scripts(List<HtmlScriptElement> scripts) {
-    if (scripts.length == 0) {
-      this._scripts = HtmlScriptElement.EMPTY_LIST;
-      return;
-    }
-    for (HtmlScriptElement script in scripts) {
-      (script as HtmlScriptElementImpl).enclosingElement = this;
-    }
-    this._scripts = scripts;
-  }
-
-  @override
-  bool operator ==(Object object) {
-    if (identical(object, this)) {
-      return true;
-    }
-    return object is HtmlElementImpl && source == object.source;
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitHtmlElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    if (source == null) {
-      buffer.write("{HTML file}");
-    } else {
-      buffer.write(source.fullName);
-    }
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_scripts, visitor);
-  }
-}
-
-/**
- * A script tag in an HTML file.
- *
- * See [EmbeddedHtmlScriptElement], and [ExternalHtmlScriptElement].
- */
-@deprecated
-abstract class HtmlScriptElement implements Element {
-  /**
-   * An empty list of HTML script elements.
-   */
-  static const List<HtmlScriptElement> EMPTY_LIST = const <HtmlScriptElement>[];
-}
-
-/**
- * A concrete implementation of an [HtmlScriptElement].
- */
-@deprecated
-abstract class HtmlScriptElementImpl extends ElementImpl
-    implements HtmlScriptElement {
-  /**
-   * An empty list of HTML script elements.
-   */
-  @deprecated // Use HtmlScriptElement.EMPTY_LIST
-  static const List<HtmlScriptElement> EMPTY_ARRAY =
-      const <HtmlScriptElement>[];
-
-  /**
-   * Initialize a newly created script element corresponding to the given
-   * [node].
-   */
-  HtmlScriptElementImpl(XmlTagNode node)
-      : super(node.tag, node.tagToken.offset);
-}
-
-/**
- * A single import directive within a library.
- */
-abstract class ImportElement implements Element, UriReferencedElement {
-  /**
-   * An empty list of import elements.
-   */
-  @deprecated // Use ImportElement.EMPTY_LIST
-  static const List<ImportElement> EMPTY_ARRAY = const <ImportElement>[];
-
-  /**
-   * An empty list of import elements.
-   */
-  static const List<ImportElement> EMPTY_LIST = const <ImportElement>[];
-
-  /**
-   * Return a list containing the combinators that were specified as part of the
-   * import directive in the order in which they were specified.
-   */
-  List<NamespaceCombinator> get combinators;
-
-  /**
-   * Return the library that is imported into this library by this import
-   * directive.
-   */
-  LibraryElement get importedLibrary;
-
-  /**
-   * Return `true` if this import is for a deferred library.
-   */
-  bool get isDeferred;
-
-  /**
-   * Return the prefix that was specified as part of the import directive, or
-   * `null` if there was no prefix specified.
-   */
-  PrefixElement get prefix;
-
-  /**
-   * Return the offset of the prefix of this import in the file that contains
-   * this import directive, or `-1` if this import is synthetic, does not have a
-   * prefix, or otherwise does not have an offset.
-   */
-  int get prefixOffset;
-}
-
-/**
- * A concrete implementation of an [ImportElement].
- */
-class ImportElementImpl extends UriReferencedElementImpl
-    implements ImportElement {
-  /**
-   * The offset of the prefix of this import in the file that contains the this
-   * import directive, or `-1` if this import is synthetic.
-   */
-  int prefixOffset = 0;
-
-  /**
-   * The library that is imported into this library by this import directive.
-   */
-  LibraryElement importedLibrary;
-
-  /**
-   * The combinators that were specified as part of the import directive in the
-   * order in which they were specified.
-   */
-  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
-
-  /**
-   * The prefix that was specified as part of the import directive, or `null` if
-   * there was no prefix specified.
-   */
-  PrefixElement prefix;
-
-  /**
-   * Initialize a newly created import element at the given [offset].
-   * The offset may be `-1` if the import is synthetic.
-   */
-  ImportElementImpl(int offset) : super(null, offset);
-
-  /**
-   * Set whether this import is for a deferred library.
-   */
-  void set deferred(bool isDeferred) {
-    setModifier(Modifier.DEFERRED, isDeferred);
-  }
-
-  @override
-  String get identifier =>
-      "${(importedLibrary as LibraryElementImpl).identifier}@$nameOffset";
-
-  @override
-  bool get isDeferred => hasModifier(Modifier.DEFERRED);
-
-  @override
-  ElementKind get kind => ElementKind.IMPORT;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitImportElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write("import ");
-    (importedLibrary as LibraryElementImpl).appendTo(buffer);
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(prefix, visitor);
-  }
-}
-
-/**
- * The type introduced by either a class or an interface, or a reference to such
- * a type.
- */
-abstract class InterfaceType implements ParameterizedType {
-  /**
-   * An empty list of types.
-   */
-  @deprecated // Use InterfaceType.EMPTY_LIST
-  static const List<InterfaceType> EMPTY_ARRAY = const <InterfaceType>[];
-
-  /**
-   * An empty list of types.
-   */
-  static const List<InterfaceType> EMPTY_LIST = const <InterfaceType>[];
-
-  /**
-   * Return a list containing all of the accessors (getters and setters)
-   * declared in this type.
-   */
-  List<PropertyAccessorElement> get accessors;
-
-  /**
-   * Return a list containing all of the constructors declared in this type.
-   */
-  List<ConstructorElement> get constructors;
-
-  @override
-  ClassElement get element;
-
-  /**
-   * Return a list containing all of the interfaces that are implemented by this
-   * interface. Note that this is <b>not</b>, in general, equivalent to getting
-   * the interfaces from this type's element because the types returned by this
-   * method will have had their type parameters replaced.
-   */
-  List<InterfaceType> get interfaces;
-
-  /**
-   * Return a list containing all of the methods declared in this type.
-   */
-  List<MethodElement> get methods;
-
-  /**
-   * Return a list containing all of the mixins that are applied to the class
-   * being extended in order to derive the superclass of this class. Note that
-   * this is <b>not</b>, in general, equivalent to getting the mixins from this
-   * type's element because the types returned by this method will have had
-   * their type parameters replaced.
-   */
-  List<InterfaceType> get mixins;
-
-  /**
-   * Return the type representing the superclass of this type, or null if this
-   * type represents the class 'Object'. Note that this is <b>not</b>, in
-   * general, equivalent to getting the superclass from this type's element
-   * because the type returned by this method will have had it's type parameters
-   * replaced.
-   */
-  InterfaceType get superclass;
-
-  /**
-   * Return the element representing the getter with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a getter
-   * with the given name.
-   */
-  PropertyAccessorElement getGetter(String name);
-
-  /**
-   * Return the least upper bound of this type and the given [type], or `null`
-   * if there is no least upper bound.
-   *
-   * Given two interfaces <i>I</i> and <i>J</i>, let <i>S<sub>I</sub></i> be the
-   * set of superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of
-   * superinterfaces of <i>J</i> and let <i>S = (I &cup; S<sub>I</sub>) &cap;
-   * (J &cup; S<sub>J</sub>)</i>. Furthermore, we define <i>S<sub>n</sub> =
-   * {T | T &isin; S &and; depth(T) = n}</i> for any finite <i>n</i>, where
-   * <i>depth(T)</i> is the number of steps in the longest inheritance path from
-   * <i>T</i> to <i>Object</i>. Let <i>q</i> be the largest number such that
-   * <i>S<sub>q</sub></i> has cardinality one. The least upper bound of <i>I</i>
-   * and <i>J</i> is the sole element of <i>S<sub>q</sub></i>.
-   */
-  @override
-  @deprecated
-  DartType getLeastUpperBound(DartType type);
-
-  /**
-   * Return the element representing the method with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a method
-   * with the given name.
-   */
-  MethodElement getMethod(String name);
-
-  /**
-   * Return the element representing the setter with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a setter
-   * with the given name.
-   */
-  PropertyAccessorElement getSetter(String name);
-
-  /**
-   * Return `true` if this type is a direct supertype of the given [type]. The
-   * implicit interface of class <i>I</i> is a direct supertype of the implicit
-   * interface of class <i>J</i> iff:
-   *
-   * * <i>I</i> is Object, and <i>J</i> has no extends clause.
-   * * <i>I</i> is listed in the extends clause of <i>J</i>.
-   * * <i>I</i> is listed in the implements clause of <i>J</i>.
-   * * <i>I</i> is listed in the with clause of <i>J</i>.
-   * * <i>J</i> is a mixin application of the mixin of <i>I</i>.
-   */
-  bool isDirectSupertypeOf(InterfaceType type);
-
-  /**
-   * Return `true` if this type is more specific than the given [type]. An
-   * interface type <i>T</i> is more specific than an interface type <i>S</i>,
-   * written <i>T &laquo; S</i>, if one of the following conditions is met:
-   *
-   * * Reflexivity: <i>T</i> is <i>S</i>.
-   * * <i>T</i> is bottom.
-   * * <i>S</i> is dynamic.
-   * * Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
-   * * <i>T</i> is a type parameter and <i>S</i> is the upper bound of <i>T</i>.
-   * * Covariance: <i>T</i> is of the form <i>I&lt;T<sub>1</sub>, &hellip;,
-   *   T<sub>n</sub>&gt;</i> and S</i> is of the form <i>I&lt;S<sub>1</sub>,
-   *   &hellip;, S<sub>n</sub>&gt;</i> and <i>T<sub>i</sub> &laquo;
-   *   S<sub>i</sub></i>, <i>1 <= i <= n</i>.
-   * * Transitivity: <i>T &laquo; U</i> and <i>U &laquo; S</i>.
-   */
-  @override
-  bool isMoreSpecificThan(DartType type);
-
-  /**
-   * Return `true` if this type is a subtype of the given [type]. An interface
-   * type <i>T</i> is a subtype of an interface type <i>S</i>, written <i>T</i>
-   * <: <i>S</i>, iff <i>[bottom/dynamic]T</i> &laquo; <i>S</i> (<i>T</i> is
-   * more specific than <i>S</i>). If an interface type <i>I</i> includes a
-   * method named <i>call()</i>, and the type of <i>call()</i> is the function
-   * type <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
-   */
-  @override
-  bool isSubtypeOf(DartType type);
-
-  /**
-   * Return the element representing the constructor that results from looking
-   * up the constructor with the given [name] in this class with respect to the
-   * given [library], or `null` if the look up fails. The behavior of this
-   * method is defined by the Dart Language Specification in section 12.11.1:
-   * <blockquote>
-   * If <i>e</i> is of the form <b>new</b> <i>T.id()</i> then let <i>q<i> be the
-   * constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor <i>T<i>.
-   * Otherwise, if <i>q</i> is not defined or not accessible, a
-   * NoSuchMethodException is thrown.
-   * </blockquote>
-   */
-  ConstructorElement lookUpConstructor(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the getter that results from looking up the
-   * getter with the given [name] in this class with respect to the given
-   * [library], or `null` if the look up fails. The behavior of this method is
-   * defined by the Dart Language Specification in section 12.15.1:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named
-   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
-   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
-   *   superclass <i>S</i>, then the result of the lookup is the result of
-   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
-   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpGetter(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the getter that results from looking up the
-   * getter with the given [name] in the superclass of this class with respect
-   * to the given [library], or `null` if the look up fails. The behavior of
-   * this method is defined by the Dart Language Specification in section
-   * 12.15.1:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named
-   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
-   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
-   *   superclass <i>S</i>, then the result of the lookup is the result of
-   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
-   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpGetterInSuperclass(
-      String name, LibraryElement library);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * method with the given [name] in this class with respect to the given
-   * [library], or `null` if the look up fails. The behavior of this method is
-   * defined by the Dart Language Specification in section 12.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
-   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
-   *   <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
-   *   result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>
-   *   Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  MethodElement lookUpMethod(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * method with the given [name] in the superclass of this class with respect
-   * to the given [library], or `null` if the look up fails. The behavior of
-   * this method is defined by the Dart Language Specification in section
-   * 12.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
-   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
-   * <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
-   * result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  MethodElement lookUpMethodInSuperclass(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the setter that results from looking up the
-   * setter with the given [name] in this class with respect to the given
-   * [library], or `null` if the look up fails. The behavior of this method is
-   * defined by the Dart Language Specification in section 12.16:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named
-   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
-   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
-   *   superclass <i>S</i>, then the result of the lookup is the result of
-   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
-   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpSetter(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the setter that results from looking up the
-   * setter with the given [name] in the superclass of this class with respect
-   * to the given [library], or `null` if the look up fails. The behavior of
-   * this method is defined by the Dart Language Specification in section 12.16:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named
-   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
-   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
-   *   superclass <i>S</i>, then the result of the lookup is the result of
-   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
-   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpSetterInSuperclass(
-      String name, LibraryElement library);
-
-  @override
-  InterfaceType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes);
-
-  /**
-   * Return the type resulting from substituting the given arguments for this
-   * type's parameters. This is fully equivalent to `substitute2(argumentTypes,
-   * getTypeArguments())`.
-   */
-  InterfaceType substitute4(List<DartType> argumentTypes);
-
-  /**
-   * Returns a "smart" version of the "least upper bound" of the given types.
-   *
-   * If these types have the same element and differ only in terms of the type
-   * arguments, attempts to find a compatible set of type arguments.
-   *
-   * Otherwise, calls [DartType.getLeastUpperBound].
-   */
-  static InterfaceType getSmartLeastUpperBound(
-      InterfaceType first, InterfaceType second) {
-    // TODO(paulberry): this needs to be deprecated and replaced with a method
-    // in [TypeSystem], since it relies on the deprecated functionality of
-    // [DartType.getLeastUpperBound].
-    if (first.element == second.element) {
-      return _leastUpperBound(first, second);
-    }
-    return first.getLeastUpperBound(second);
-  }
-
-  /**
-   * Return the "least upper bound" of the given types under the assumption that
-   * the types have the same element and differ only in terms of the type
-   * arguments.
-   *
-   * The resulting type is composed by comparing the corresponding type
-   * arguments, keeping those that are the same, and using 'dynamic' for those
-   * that are different.
-   */
-  static InterfaceType _leastUpperBound(
-      InterfaceType firstType, InterfaceType secondType) {
-    ClassElement firstElement = firstType.element;
-    ClassElement secondElement = secondType.element;
-    if (firstElement != secondElement) {
-      throw new IllegalArgumentException('The same elements expected, but '
-          '$firstElement and $secondElement are given.');
-    }
-    if (firstType == secondType) {
-      return firstType;
-    }
-    List<DartType> firstArguments = firstType.typeArguments;
-    List<DartType> secondArguments = secondType.typeArguments;
-    int argumentCount = firstArguments.length;
-    if (argumentCount == 0) {
-      return firstType;
-    }
-    List<DartType> lubArguments = new List<DartType>(argumentCount);
-    for (int i = 0; i < argumentCount; i++) {
-      //
-      // Ideally we would take the least upper bound of the two argument types,
-      // but this can cause an infinite recursion (such as when finding the
-      // least upper bound of String and num).
-      //
-      if (firstArguments[i] == secondArguments[i]) {
-        lubArguments[i] = firstArguments[i];
-      }
-      if (lubArguments[i] == null) {
-        lubArguments[i] = DynamicTypeImpl.instance;
-      }
-    }
-    InterfaceTypeImpl lub = new InterfaceTypeImpl(firstElement);
-    lub.typeArguments = lubArguments;
-    return lub;
-  }
-}
-
-/**
- * A concrete implementation of an [InterfaceType].
- */
-class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
-  /**
-   * A list containing the actual types of the type arguments.
-   */
-  List<DartType> typeArguments = DartType.EMPTY_LIST;
-
-  /**
-   * The set of typedefs which should not be expanded when exploring this type,
-   * to avoid creating infinite types in response to self-referential typedefs.
-   */
-  final List<FunctionTypeAliasElement> prunedTypedefs;
-
-  /**
-   * Initialize a newly created type to be declared by the given [element].
-   */
-  InterfaceTypeImpl(ClassElement element, [this.prunedTypedefs])
-      : super(element, element.displayName);
-
-  /**
-   * Initialize a newly created type to be declared by the given [element].
-   */
-  @deprecated // Use new InterfaceTypeImpl(element)
-  InterfaceTypeImpl.con1(ClassElement element)
-      : prunedTypedefs = null,
-        super(element, element.displayName);
-
-  /**
-   * Initialize a newly created type to have the given [name]. This constructor
-   * should only be used in cases where there is no declaration of the type.
-   */
-  @deprecated // Use new InterfaceTypeImpl.named(name)
-  InterfaceTypeImpl.con2(String name)
-      : prunedTypedefs = null,
-        super(null, name);
-
-  /**
-   * Initialize a newly created type to have the given [name]. This constructor
-   * should only be used in cases where there is no declaration of the type.
-   */
-  InterfaceTypeImpl.named(String name)
-      : prunedTypedefs = null,
-        super(null, name);
-
-  /**
-   * Private constructor.
-   */
-  InterfaceTypeImpl._(Element element, String name, this.prunedTypedefs)
-      : super(element, name);
-
-  @override
-  List<PropertyAccessorElement> get accessors {
-    List<PropertyAccessorElement> accessors = element.accessors;
-    List<PropertyAccessorElement> members =
-        new List<PropertyAccessorElement>(accessors.length);
-    for (int i = 0; i < accessors.length; i++) {
-      members[i] = PropertyAccessorMember.from(accessors[i], this);
-    }
-    return members;
-  }
-
-  @override
-  List<ConstructorElement> get constructors {
-    List<ConstructorElement> constructors = element.constructors;
-    List<ConstructorElement> members =
-        new List<ConstructorElement>(constructors.length);
-    for (int i = 0; i < constructors.length; i++) {
-      members[i] = ConstructorMember.from(constructors[i], this);
-    }
-    return members;
-  }
-
-  @override
-  String get displayName {
-    String name = this.name;
-    List<DartType> typeArguments = this.typeArguments;
-    bool allDynamic = true;
-    for (DartType type in typeArguments) {
-      if (type != null && !type.isDynamic) {
-        allDynamic = false;
-        break;
-      }
-    }
-    // If there is at least one non-dynamic type, then list them out
-    if (!allDynamic) {
-      StringBuffer buffer = new StringBuffer();
-      buffer.write(name);
-      buffer.write("<");
-      for (int i = 0; i < typeArguments.length; i++) {
-        if (i != 0) {
-          buffer.write(", ");
-        }
-        DartType typeArg = typeArguments[i];
-        buffer.write(typeArg.displayName);
-      }
-      buffer.write(">");
-      name = buffer.toString();
-    }
-    return name;
-  }
-
-  @override
-  ClassElement get element => super.element as ClassElement;
-
-  @override
-  int get hashCode {
-    ClassElement element = this.element;
-    if (element == null) {
-      return 0;
-    }
-    return element.hashCode;
-  }
-
-  @override
-  List<InterfaceType> get interfaces {
-    ClassElement classElement = element;
-    List<InterfaceType> interfaces = classElement.interfaces;
-    List<TypeParameterElement> typeParameters = classElement.typeParameters;
-    List<DartType> parameterTypes = classElement.type.typeArguments;
-    if (typeParameters.length == 0) {
-      return interfaces;
-    }
-    int count = interfaces.length;
-    List<InterfaceType> typedInterfaces = new List<InterfaceType>(count);
-    for (int i = 0; i < count; i++) {
-      typedInterfaces[i] =
-          interfaces[i].substitute2(typeArguments, parameterTypes);
-    }
-    return typedInterfaces;
-  }
-
-  @override
-  bool get isDartCoreFunction {
-    ClassElement element = this.element;
-    if (element == null) {
-      return false;
-    }
-    return element.name == "Function" && element.library.isDartCore;
-  }
-
-  @override
-  bool get isObject => element.supertype == null;
-
-  @override
-  List<MethodElement> get methods {
-    List<MethodElement> methods = element.methods;
-    List<MethodElement> members = new List<MethodElement>(methods.length);
-    for (int i = 0; i < methods.length; i++) {
-      members[i] = MethodMember.from(methods[i], this);
-    }
-    return members;
-  }
-
-  @override
-  List<InterfaceType> get mixins {
-    ClassElement classElement = element;
-    List<InterfaceType> mixins = classElement.mixins;
-    List<TypeParameterElement> typeParameters = classElement.typeParameters;
-    List<DartType> parameterTypes = classElement.type.typeArguments;
-    if (typeParameters.length == 0) {
-      return mixins;
-    }
-    int count = mixins.length;
-    List<InterfaceType> typedMixins = new List<InterfaceType>(count);
-    for (int i = 0; i < count; i++) {
-      typedMixins[i] = mixins[i].substitute2(typeArguments, parameterTypes);
-    }
-    return typedMixins;
-  }
-
-  @override
-  InterfaceType get superclass {
-    ClassElement classElement = element;
-    InterfaceType supertype = classElement.supertype;
-    if (supertype == null) {
-      return null;
-    }
-    List<DartType> typeParameters = classElement.type.typeArguments;
-    if (typeArguments.length == 0 ||
-        typeArguments.length != typeParameters.length) {
-      return supertype;
-    }
-    return supertype.substitute2(typeArguments, typeParameters);
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => element.typeParameters;
-
-  @override
-  bool operator ==(Object object) {
-    if (identical(object, this)) {
-      return true;
-    }
-    if (object is! InterfaceTypeImpl) {
-      return false;
-    }
-    InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
-    return (element == otherType.element) &&
-        TypeImpl.equalArrays(typeArguments, otherType.typeArguments);
-  }
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(name);
-    int argumentCount = typeArguments.length;
-    if (argumentCount > 0) {
-      buffer.write("<");
-      for (int i = 0; i < argumentCount; i++) {
-        if (i > 0) {
-          buffer.write(", ");
-        }
-        (typeArguments[i] as TypeImpl).appendTo(buffer);
-      }
-      buffer.write(">");
-    }
-  }
-
-  @override
-  PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember
-      .from((element as ClassElementImpl).getGetter(getterName), this);
-
-  @override
-  @deprecated
-  DartType getLeastUpperBound(DartType type) {
-    // quick check for self
-    if (identical(type, this)) {
-      return this;
-    }
-    // dynamic
-    DartType dynamicType = DynamicTypeImpl.instance;
-    if (identical(this, dynamicType) || identical(type, dynamicType)) {
-      return dynamicType;
-    }
-    // TODO (jwren) opportunity here for a better, faster algorithm if this
-    // turns out to be a bottle-neck
-    if (type is! InterfaceType) {
-      return null;
-    }
-    return computeLeastUpperBound(this, type);
-  }
-
-  @override
-  MethodElement getMethod(String methodName) => MethodMember.from(
-      (element as ClassElementImpl).getMethod(methodName), this);
-
-  @override
-  PropertyAccessorElement getSetter(String setterName) => PropertyAccessorMember
-      .from((element as ClassElementImpl).getSetter(setterName), this);
-
-  @override
-  bool isDirectSupertypeOf(InterfaceType type) {
-    InterfaceType i = this;
-    InterfaceType j = type;
-    ClassElement jElement = j.element;
-    InterfaceType supertype = jElement.supertype;
-    //
-    // If J has no direct supertype then it is Object, and Object has no direct
-    // supertypes.
-    //
-    if (supertype == null) {
-      return false;
-    }
-    //
-    // I is listed in the extends clause of J.
-    //
-    List<DartType> jArgs = j.typeArguments;
-    List<DartType> jVars = jElement.type.typeArguments;
-    supertype = supertype.substitute2(jArgs, jVars);
-    if (supertype == i) {
-      return true;
-    }
-    //
-    // I is listed in the implements clause of J.
-    //
-    for (InterfaceType interfaceType in jElement.interfaces) {
-      interfaceType = interfaceType.substitute2(jArgs, jVars);
-      if (interfaceType == i) {
-        return true;
-      }
-    }
-    //
-    // I is listed in the with clause of J.
-    //
-    for (InterfaceType mixinType in jElement.mixins) {
-      mixinType = mixinType.substitute2(jArgs, jVars);
-      if (mixinType == i) {
-        return true;
-      }
-    }
-    //
-    // J is a mixin application of the mixin of I.
-    //
-    // TODO(brianwilkerson) Determine whether this needs to be implemented or
-    // whether it is covered by the case above.
-    return false;
-  }
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    //
-    // S is dynamic.
-    // The test to determine whether S is dynamic is done here because dynamic
-    // is not an instance of InterfaceType.
-    //
-    if (type.isDynamic) {
-      return true;
-    }
-    //
-    // A type T is more specific than a type S, written T << S,
-    // if one of the following conditions is met:
-    //
-    // Reflexivity: T is S.
-    //
-    if (this == type) {
-      return true;
-    }
-    if (type is InterfaceType) {
-      //
-      // T is bottom. (This case is handled by the class BottomTypeImpl.)
-      //
-      // Direct supertype: S is a direct supertype of T.
-      //
-      if (type.isDirectSupertypeOf(this)) {
-        return true;
-      }
-      //
-      // Covariance: T is of the form I<T1, ..., Tn> and S is of the form
-      // I<S1, ..., Sn> and Ti << Si, 1 <= i <= n.
-      //
-      ClassElement tElement = this.element;
-      ClassElement sElement = type.element;
-      if (tElement == sElement) {
-        List<DartType> tArguments = typeArguments;
-        List<DartType> sArguments = type.typeArguments;
-        if (tArguments.length != sArguments.length) {
-          return false;
-        }
-        for (int i = 0; i < tArguments.length; i++) {
-          if (!(tArguments[i] as TypeImpl)
-              .isMoreSpecificThan(sArguments[i], withDynamic)) {
-            return false;
-          }
-        }
-        return true;
-      }
-    }
-    //
-    // Transitivity: T << U and U << S.
-    //
-    // First check for infinite loops
-    if (element == null) {
-      return false;
-    }
-    if (visitedElements == null) {
-      visitedElements = new HashSet<ClassElement>();
-    } else if (visitedElements.contains(element)) {
-      return false;
-    }
-    visitedElements.add(element);
-    try {
-      // Iterate over all of the types U that are more specific than T because
-      // they are direct supertypes of T and return true if any of them are more
-      // specific than S.
-      InterfaceTypeImpl supertype = superclass;
-      if (supertype != null &&
-          supertype.isMoreSpecificThan(type, withDynamic, visitedElements)) {
-        return true;
-      }
-      for (InterfaceType interfaceType in interfaces) {
-        if ((interfaceType as InterfaceTypeImpl)
-            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
-          return true;
-        }
-      }
-      for (InterfaceType mixinType in mixins) {
-        if ((mixinType as InterfaceTypeImpl)
-            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
-          return true;
-        }
-      }
-      // If a type I includes an instance method named `call`, and the type of
-      // `call` is the function type F, then I is considered to be more specific
-      // than F.
-      MethodElement callMethod = getMethod('call');
-      if (callMethod != null && !callMethod.isStatic) {
-        FunctionTypeImpl callType = callMethod.type;
-        if (callType.isMoreSpecificThan(type, withDynamic, visitedElements)) {
-          return true;
-        }
-      }
-      return false;
-    } finally {
-      visitedElements.remove(element);
-    }
-  }
-
-  @override
-  ConstructorElement lookUpConstructor(
-      String constructorName, LibraryElement library) {
-    // prepare base ConstructorElement
-    ConstructorElement constructorElement;
-    if (constructorName == null) {
-      constructorElement = element.unnamedConstructor;
-    } else {
-      constructorElement = element.getNamedConstructor(constructorName);
-    }
-    // not found or not accessible
-    if (constructorElement == null ||
-        !constructorElement.isAccessibleIn(library)) {
-      return null;
-    }
-    // return member
-    return ConstructorMember.from(constructorElement, this);
-  }
-
-  @override
-  PropertyAccessorElement lookUpGetter(
-      String getterName, LibraryElement library) {
-    PropertyAccessorElement element = getGetter(getterName);
-    if (element != null && element.isAccessibleIn(library)) {
-      return element;
-    }
-    return lookUpGetterInSuperclass(getterName, library);
-  }
-
-  @override
-  PropertyAccessorElement lookUpGetterInSuperclass(
-      String getterName, LibraryElement library) {
-    for (InterfaceType mixin in mixins.reversed) {
-      PropertyAccessorElement element = mixin.getGetter(getterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    InterfaceType supertype = superclass;
-    ClassElement supertypeElement =
-        supertype == null ? null : supertype.element;
-    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
-      visitedClasses.add(supertypeElement);
-      PropertyAccessorElement element = supertype.getGetter(getterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-      for (InterfaceType mixin in supertype.mixins.reversed) {
-        element = mixin.getGetter(getterName);
-        if (element != null && element.isAccessibleIn(library)) {
-          return element;
-        }
-      }
-      supertype = supertype.superclass;
-      supertypeElement = supertype == null ? null : supertype.element;
-    }
-    return null;
-  }
-
-  @override
-  MethodElement lookUpMethod(String methodName, LibraryElement library) {
-    MethodElement element = getMethod(methodName);
-    if (element != null && element.isAccessibleIn(library)) {
-      return element;
-    }
-    return lookUpMethodInSuperclass(methodName, library);
-  }
-
-  @override
-  MethodElement lookUpMethodInSuperclass(
-      String methodName, LibraryElement library) {
-    for (InterfaceType mixin in mixins.reversed) {
-      MethodElement element = mixin.getMethod(methodName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    InterfaceType supertype = superclass;
-    ClassElement supertypeElement =
-        supertype == null ? null : supertype.element;
-    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
-      visitedClasses.add(supertypeElement);
-      MethodElement element = supertype.getMethod(methodName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-      for (InterfaceType mixin in supertype.mixins.reversed) {
-        element = mixin.getMethod(methodName);
-        if (element != null && element.isAccessibleIn(library)) {
-          return element;
-        }
-      }
-      supertype = supertype.superclass;
-      supertypeElement = supertype == null ? null : supertype.element;
-    }
-    return null;
-  }
-
-  @override
-  PropertyAccessorElement lookUpSetter(
-      String setterName, LibraryElement library) {
-    PropertyAccessorElement element = getSetter(setterName);
-    if (element != null && element.isAccessibleIn(library)) {
-      return element;
-    }
-    return lookUpSetterInSuperclass(setterName, library);
-  }
-
-  @override
-  PropertyAccessorElement lookUpSetterInSuperclass(
-      String setterName, LibraryElement library) {
-    for (InterfaceType mixin in mixins.reversed) {
-      PropertyAccessorElement element = mixin.getSetter(setterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    InterfaceType supertype = superclass;
-    ClassElement supertypeElement =
-        supertype == null ? null : supertype.element;
-    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
-      visitedClasses.add(supertypeElement);
-      PropertyAccessorElement element = supertype.getSetter(setterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-      for (InterfaceType mixin in supertype.mixins.reversed) {
-        element = mixin.getSetter(setterName);
-        if (element != null && element.isAccessibleIn(library)) {
-          return element;
-        }
-      }
-      supertype = supertype.superclass;
-      supertypeElement = supertype == null ? null : supertype.element;
-    }
-    return null;
-  }
-
-  @override
-  InterfaceTypeImpl pruned(List<FunctionTypeAliasElement> prune) {
-    if (prune == null) {
-      return this;
-    } else {
-      // There should never be a reason to prune a type that has already been
-      // pruned, since pruning is only done when expanding a function type
-      // alias, and function type aliases are always expanded by starting with
-      // base types.
-      assert(this.prunedTypedefs == null);
-      InterfaceTypeImpl result = new InterfaceTypeImpl._(element, name, prune);
-      result.typeArguments =
-          typeArguments.map((TypeImpl t) => t.pruned(prune)).toList();
-      return result;
-    }
-  }
-
-  @override
-  InterfaceTypeImpl substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    // Pruned types should only ever result from performing type variable
-    // substitution, and it doesn't make sense to substitute again after
-    // substituting once.
-    assert(this.prunedTypedefs == null);
-    if (argumentTypes.length != parameterTypes.length) {
-      throw new IllegalArgumentException(
-          "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
-    }
-    if (argumentTypes.length == 0 || typeArguments.length == 0) {
-      return this.pruned(prune);
-    }
-    List<DartType> newTypeArguments = TypeImpl.substitute(
-        typeArguments, argumentTypes, parameterTypes, prune);
-    if (JavaArrays.equals(newTypeArguments, typeArguments)) {
-      return this;
-    }
-    InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune);
-    newType.typeArguments = newTypeArguments;
-    return newType;
-  }
-
-  @override
-  InterfaceTypeImpl substitute4(List<DartType> argumentTypes) =>
-      substitute2(argumentTypes, typeArguments);
-
-  /**
-   * Compute the least upper bound of types [i] and [j], both of which are
-   * known to be interface types.
-   *
-   * In the event that the algorithm fails (which might occur due to a bug in
-   * the analyzer), `null` is returned.
-   */
-  static InterfaceType computeLeastUpperBound(
-      InterfaceType i, InterfaceType j) {
-    // compute set of supertypes
-    Set<InterfaceType> si = computeSuperinterfaceSet(i);
-    Set<InterfaceType> sj = computeSuperinterfaceSet(j);
-    // union si with i and sj with j
-    si.add(i);
-    sj.add(j);
-    // compute intersection, reference as set 's'
-    List<InterfaceType> s = _intersection(si, sj);
-    // for each element in Set s, compute the largest inheritance path to Object
-    List<int> depths = new List<int>.filled(s.length, 0);
-    int maxDepth = 0;
-    for (int n = 0; n < s.length; n++) {
-      depths[n] = computeLongestInheritancePathToObject(s[n]);
-      if (depths[n] > maxDepth) {
-        maxDepth = depths[n];
-      }
-    }
-    // ensure that the currently computed maxDepth is unique,
-    // otherwise, decrement and test for uniqueness again
-    for (; maxDepth >= 0; maxDepth--) {
-      int indexOfLeastUpperBound = -1;
-      int numberOfTypesAtMaxDepth = 0;
-      for (int m = 0; m < depths.length; m++) {
-        if (depths[m] == maxDepth) {
-          numberOfTypesAtMaxDepth++;
-          indexOfLeastUpperBound = m;
-        }
-      }
-      if (numberOfTypesAtMaxDepth == 1) {
-        return s[indexOfLeastUpperBound];
-      }
-    }
-    // Should be impossible--there should always be exactly one type with the
-    // maximum depth.
-    assert(false);
-    return null;
-  }
-
-  /**
-   * Return the length of the longest inheritance path from the given [type] to
-   * Object.
-   *
-   * See [computeLeastUpperBound].
-   */
-  static int computeLongestInheritancePathToObject(InterfaceType type) =>
-      _computeLongestInheritancePathToObject(
-          type, 0, new HashSet<ClassElement>());
-
-  /**
-   * Returns the set of all superinterfaces of the given [type].
-   *
-   * See [computeLeastUpperBound].
-   */
-  static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) =>
-      _computeSuperinterfaceSet(type, new HashSet<InterfaceType>());
-
-  /**
-   * Return the length of the longest inheritance path from a subtype of the
-   * given [type] to Object, where the given [depth] is the length of the
-   * longest path from the subtype to this type. The set of [visitedTypes] is
-   * used to prevent infinite recursion in the case of a cyclic type structure.
-   *
-   * See [computeLongestInheritancePathToObject], and [computeLeastUpperBound].
-   */
-  static int _computeLongestInheritancePathToObject(
-      InterfaceType type, int depth, HashSet<ClassElement> visitedTypes) {
-    ClassElement classElement = type.element;
-    // Object case
-    if (classElement.supertype == null || visitedTypes.contains(classElement)) {
-      return depth;
-    }
-    int longestPath = 1;
-    try {
-      visitedTypes.add(classElement);
-      List<InterfaceType> superinterfaces = classElement.interfaces;
-      int pathLength;
-      if (superinterfaces.length > 0) {
-        // loop through each of the superinterfaces recursively calling this
-        // method and keeping track of the longest path to return
-        for (InterfaceType superinterface in superinterfaces) {
-          pathLength = _computeLongestInheritancePathToObject(
-              superinterface, depth + 1, visitedTypes);
-          if (pathLength > longestPath) {
-            longestPath = pathLength;
-          }
-        }
-      }
-      // finally, perform this same check on the super type
-      // TODO(brianwilkerson) Does this also need to add in the number of mixin
-      // classes?
-      InterfaceType supertype = classElement.supertype;
-      pathLength = _computeLongestInheritancePathToObject(
-          supertype, depth + 1, visitedTypes);
-      if (pathLength > longestPath) {
-        longestPath = pathLength;
-      }
-    } finally {
-      visitedTypes.remove(classElement);
-    }
-    return longestPath;
-  }
-
-  /**
-   * Add all of the superinterfaces of the given [type] to the given [set].
-   * Return the [set] as a convenience.
-   *
-   * See [computeSuperinterfaceSet], and [computeLeastUpperBound].
-   */
-  static Set<InterfaceType> _computeSuperinterfaceSet(
-      InterfaceType type, HashSet<InterfaceType> set) {
-    Element element = type.element;
-    if (element != null) {
-      List<InterfaceType> superinterfaces = type.interfaces;
-      for (InterfaceType superinterface in superinterfaces) {
-        if (set.add(superinterface)) {
-          _computeSuperinterfaceSet(superinterface, set);
-        }
-      }
-      InterfaceType supertype = type.superclass;
-      if (supertype != null) {
-        if (set.add(supertype)) {
-          _computeSuperinterfaceSet(supertype, set);
-        }
-      }
-    }
-    return set;
-  }
-
-  /**
-   * Return the intersection of the [first] and [second] sets of types, where
-   * intersection is based on the equality of the types themselves.
-   */
-  static List<InterfaceType> _intersection(
-      Set<InterfaceType> first, Set<InterfaceType> second) {
-    Set<InterfaceType> result = new HashSet<InterfaceType>.from(first);
-    result.retainAll(second);
-    return new List.from(result);
-  }
-}
-
-/**
- * A label associated with a statement.
- */
-abstract class LabelElement implements Element {
-  /**
-   * An empty list of label elements.
-   */
-  static const List<LabelElement> EMPTY_LIST = const <LabelElement>[];
-
-  /**
-   * Return the executable element in which this label is defined.
-   */
-  @override
-  ExecutableElement get enclosingElement;
-}
-
-/**
- * A concrete implementation of a [LabelElement].
- */
-class LabelElementImpl extends ElementImpl implements LabelElement {
-  /**
-   * An empty list of label elements.
-   */
-  @deprecated // Use LabelElement.EMPTY_LIST
-  static const List<LabelElement> EMPTY_ARRAY = const <LabelElement>[];
-
-  /**
-   * A flag indicating whether this label is associated with a `switch`
-   * statement.
-   */
-  // TODO(brianwilkerson) Make this a modifier.
-  final bool _onSwitchStatement;
-
-  /**
-   * A flag indicating whether this label is associated with a `switch` member
-   * (`case` or `default`).
-   */
-  // TODO(brianwilkerson) Make this a modifier.
-  final bool _onSwitchMember;
-
-  /**
-   * Initialize a newly created label element to have the given [name].
-   * [onSwitchStatement] should be `true` if this label is associated with a
-   * `switch` statement and [onSwitchMember] should be `true` if this label is
-   * associated with a `switch` member.
-   */
-  LabelElementImpl(
-      Identifier name, this._onSwitchStatement, this._onSwitchMember)
-      : super.forNode(name);
-
-  @override
-  ExecutableElement get enclosingElement =>
-      super.enclosingElement as ExecutableElement;
-
-  /**
-   * Return `true` if this label is associated with a `switch` member (`case` or
-   * `default`).
-   */
-  bool get isOnSwitchMember => _onSwitchMember;
-
-  /**
-   * Return `true` if this label is associated with a `switch` statement.
-   */
-  bool get isOnSwitchStatement => _onSwitchStatement;
-
-  @override
-  ElementKind get kind => ElementKind.LABEL;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitLabelElement(this);
-}
-
-/**
- * A library.
- */
-abstract class LibraryElement implements Element {
-  /**
-   * An empty list of library elements.
-   */
-  static const List<LibraryElement> EMPTY_LIST = const <LibraryElement>[];
-
-  /**
-   * Return the compilation unit that defines this library.
-   */
-  CompilationUnitElement get definingCompilationUnit;
-
-  /**
-   * Return the entry point for this library, or `null` if this library does not
-   * have an entry point. The entry point is defined to be a zero argument
-   * top-level function whose name is `main`.
-   */
-  FunctionElement get entryPoint;
-
-  /**
-   * Return a list containing all of the libraries that are exported from this
-   * library.
-   */
-  List<LibraryElement> get exportedLibraries;
-
-  /**
-   * The export [Namespace] of this library, `null` if it has not been
-   * computed yet.
-   */
-  Namespace get exportNamespace;
-
-  /**
-   * Return a list containing all of the exports defined in this library.
-   */
-  List<ExportElement> get exports;
-
-  /**
-   * Return `true` if the defining compilation unit of this library contains at
-   * least one import directive whose URI uses the "dart-ext" scheme.
-   */
-  bool get hasExtUri;
-
-  /**
-   * Return `true` if this library defines a top-level function named
-   * `loadLibrary`.
-   */
-  bool get hasLoadLibraryFunction;
-
-  /**
-   * Return a list containing all of the libraries that are imported into this
-   * library. This includes all of the libraries that are imported using a
-   * prefix (also available through the prefixes returned by [getPrefixes]) and
-   * those that are imported without a prefix.
-   */
-  List<LibraryElement> get importedLibraries;
-
-  /**
-   * Return a list containing all of the imports defined in this library.
-   */
-  List<ImportElement> get imports;
-
-  /**
-   * Return `true` if this library is an application that can be run in the
-   * browser.
-   */
-  bool get isBrowserApplication;
-
-  /**
-   * Return `true` if this library is the dart:core library.
-   */
-  bool get isDartCore;
-
-  /**
-   * Return `true` if this library is part of the SDK.
-   */
-  bool get isInSdk;
-
-  /**
-   * Return the element representing the synthetic function `loadLibrary` that
-   * is implicitly defined for this library if the library is imported using a
-   * deferred import.
-   */
-  FunctionElement get loadLibraryFunction;
-
-  /**
-   * Return a list containing all of the compilation units that are included in
-   * this library using a `part` directive. This does not include the defining
-   * compilation unit that contains the `part` directives.
-   */
-  List<CompilationUnitElement> get parts;
-
-  /**
-   * Return a list containing elements for each of the prefixes used to `import`
-   * libraries into this library. Each prefix can be used in more than one
-   * `import` directive.
-   */
-  List<PrefixElement> get prefixes;
-
-  /**
-   * The public [Namespace] of this library, `null` if it has not been
-   * computed yet.
-   */
-  Namespace get publicNamespace;
-
-  /**
-   * Return a list containing all of the compilation units this library consists
-   * of. This includes the defining compilation unit and units included using
-   * the `part` directive.
-   */
-  List<CompilationUnitElement> get units;
-
-  /**
-   * Return a list containing all directly and indirectly imported libraries.
-   */
-  List<LibraryElement> get visibleLibraries;
-
-  /**
-   * Return a list containing all of the imports that share the given [prefix],
-   * or an empty array if there are no such imports.
-   */
-  List<ImportElement> getImportsWithPrefix(PrefixElement prefix);
-
-  /**
-   * Return the class defined in this library that has the given [name], or
-   * `null` if this library does not define a class with the given name.
-   */
-  ClassElement getType(String className);
-
-  /**
-   * Return `true` if this library is up to date with respect to the given
-   * [timeStamp]. If any transitively referenced Source is newer than the time
-   * stamp, this method returns false.
-   */
-  bool isUpToDate(int timeStamp);
-}
-
-/**
- * A concrete implementation of a [LibraryElement].
- */
-class LibraryElementImpl extends ElementImpl implements LibraryElement {
-  /**
-   * An empty list of library elements.
-   */
-  @deprecated // Use LibraryElement.EMPTY_LIST
-  static const List<LibraryElement> EMPTY_ARRAY = const <LibraryElement>[];
-
-  /**
-   * The analysis context in which this library is defined.
-   */
-  final AnalysisContext context;
-
-  /**
-   * The compilation unit that defines this library.
-   */
-  CompilationUnitElement _definingCompilationUnit;
-
-  /**
-   * The entry point for this library, or `null` if this library does not have
-   * an entry point.
-   */
-  FunctionElement entryPoint;
-
-  /**
-   * A list containing specifications of all of the imports defined in this
-   * library.
-   */
-  List<ImportElement> _imports = ImportElement.EMPTY_LIST;
-
-  /**
-   * A list containing specifications of all of the exports defined in this
-   * library.
-   */
-  List<ExportElement> _exports = ExportElement.EMPTY_LIST;
-
-  /**
-   * A list containing the strongly connected component in the import/export
-   * graph in which the current library resides.  Computed on demand, null
-   * if not present.  If _libraryCycle is set, then the _libraryCycle field
-   * for all libraries reachable from this library in the import/export graph
-   * is also set.
-   */
-  List<LibraryElement> _libraryCycle = null;
-
-  /**
-   * A list containing all of the compilation units that are included in this
-   * library using a `part` directive.
-   */
-  List<CompilationUnitElement> _parts = CompilationUnitElement.EMPTY_LIST;
-
-  /**
-   * The element representing the synthetic function `loadLibrary` that is
-   * defined for this library, or `null` if the element has not yet been created.
-   */
-  FunctionElement _loadLibraryFunction;
-
-  @override
-  final int nameLength;
-
-  /**
-   * The export [Namespace] of this library, `null` if it has not been
-   * computed yet.
-   */
-  @override
-  Namespace exportNamespace;
-
-  /**
-   * The public [Namespace] of this library, `null` if it has not been
-   * computed yet.
-   */
-  @override
-  Namespace publicNamespace;
-
-  /**
-   * Initialize a newly created library element in the given [context] to have
-   * the given [name] and [offset].
-   */
-  LibraryElementImpl(this.context, String name, int offset, this.nameLength)
-      : super(name, offset);
-
-  /**
-   * Initialize a newly created library element in the given [context] to have
-   * the given [name].
-   */
-  LibraryElementImpl.forNode(this.context, LibraryIdentifier name)
-      : super.forNode(name),
-        nameLength = name != null ? name.length : 0;
-
-  @override
-  CompilationUnitElement get definingCompilationUnit =>
-      _definingCompilationUnit;
-
-  /**
-   * Set the compilation unit that defines this library to the given compilation
-   * [unit].
-   */
-  void set definingCompilationUnit(CompilationUnitElement unit) {
-    assert((unit as CompilationUnitElementImpl).librarySource == unit.source);
-    (unit as CompilationUnitElementImpl).enclosingElement = this;
-    this._definingCompilationUnit = unit;
-  }
-
-  @override
-  List<LibraryElement> get exportedLibraries {
-    HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
-    for (ExportElement element in _exports) {
-      LibraryElement library = element.exportedLibrary;
-      if (library != null) {
-        libraries.add(library);
-      }
-    }
-    return new List.from(libraries);
-  }
-
-  @override
-  List<ExportElement> get exports => _exports;
-
-  /**
-   * Set the specifications of all of the exports defined in this library to the
-   * given list of [exports].
-   */
-  void set exports(List<ExportElement> exports) {
-    for (ExportElement exportElement in exports) {
-      (exportElement as ExportElementImpl).enclosingElement = this;
-    }
-    this._exports = exports;
-  }
-
-  @override
-  bool get hasExtUri => hasModifier(Modifier.HAS_EXT_URI);
-
-  /**
-   * Set whether this library has an import of a "dart-ext" URI.
-   */
-  void set hasExtUri(bool hasExtUri) {
-    setModifier(Modifier.HAS_EXT_URI, hasExtUri);
-  }
-
-  @override
-  int get hashCode => _definingCompilationUnit.hashCode;
-
-  @override
-  bool get hasLoadLibraryFunction {
-    if (_definingCompilationUnit.hasLoadLibraryFunction) {
-      return true;
-    }
-    for (int i = 0; i < _parts.length; i++) {
-      if (_parts[i].hasLoadLibraryFunction) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  String get identifier => _definingCompilationUnit.source.encoding;
-
-  @override
-  List<LibraryElement> get importedLibraries {
-    HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
-    for (ImportElement element in _imports) {
-      LibraryElement library = element.importedLibrary;
-      if (library != null) {
-        libraries.add(library);
-      }
-    }
-    return new List.from(libraries);
-  }
-
-  @override
-  List<ImportElement> get imports => _imports;
-
-  /**
-   * Set the specifications of all of the imports defined in this library to the
-   * given list of [imports].
-   */
-  void set imports(List<ImportElement> imports) {
-    for (ImportElement importElement in imports) {
-      (importElement as ImportElementImpl).enclosingElement = this;
-      PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
-      if (prefix != null) {
-        prefix.enclosingElement = this;
-      }
-    }
-    this._imports = imports;
-  }
-
-  /** Given an update to this library which may have added or deleted edges
-   * in the import/export graph originating from this node only, remove any
-   * cached library cycles in the element model which may have been invalidated.
-   */
-  void invalidateLibraryCycles() {
-    if (_libraryCycle == null) {
-      // We have already invalidated this node, or we have never computed
-      // library cycle information for it.  In the former case, we're done. In
-      // the latter case, this node cannot be reachable from any node for which
-      // we have computed library cycle information.  Therefore, any edges added
-      // or deleted in the update causing this invalidation can only be edges to
-      // nodes which either have no library cycle information (and hence do not
-      // need invalidation), or which do not reach this node by any path.
-      // In either case, no further invalidation is needed.
-      return;
-    }
-    // If we have pre-computed library cycle information, then we must
-    // invalidate the information both on this element, and on certain
-    // other elements.  Edges originating at this node may have been
-    // added or deleted.  A deleted edge that points outside of this cycle
-    // cannot change the cycle information for anything outside of this cycle,
-    // and so it is sufficient to delete the cached library information on this
-    // cycle.  An added edge which points to another node within the cycle
-    // only invalidates the cycle.  An added edge which points to a node earlier
-    // in the topological sort of cycles induces no invalidation (since there
-    // are by definition no back edges from earlier cycles in the topological
-    // order, and hence no possible cycle can have been introduced.  The only
-    // remaining case is that we have added an edge to a node which is later
-    // in the topological sort of cycles.  This can induce cycles, since it
-    // represents a new back edge.  It would be sufficient to invalidate the
-    // cycle information for all nodes that are between the target and the
-    // node in the topological order.  For simplicity, we simply invalidate
-    // all nodes which are reachable from the the source node.
-    // Note that in the invalidation phase, we do not cut off when we encounter
-    // a node with no library cycle information, since we do not know whether
-    // we are in the case where invalidation has already been performed, or we
-    // are in the case where library cycles have simply never been computed from
-    // a newly reachable node.
-    Set<LibraryElementImpl> active = new HashSet();
-    void invalidate(LibraryElementImpl library) {
-      if (!active.add(library)) return;
-      if (library._libraryCycle != null) {
-        library._libraryCycle.forEach(invalidate);
-        library._libraryCycle = null;
-      }
-      library.exportedLibraries.forEach(invalidate);
-      library.importedLibraries.forEach(invalidate);
-    }
-    invalidate(this);
-  }
-
-  @override
-  bool get isBrowserApplication =>
-      entryPoint != null && isOrImportsBrowserLibrary;
-
-  @override
-  bool get isDartCore => name == "dart.core";
-
-  @override
-  bool get isInSdk =>
-      StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x74, 0x2E);
-
-  /**
-   * Return `true` if the receiver directly or indirectly imports the
-   * 'dart:html' libraries.
-   */
-  bool get isOrImportsBrowserLibrary {
-    List<LibraryElement> visited = new List<LibraryElement>();
-    Source htmlLibSource = context.sourceFactory.forUri(DartSdk.DART_HTML);
-    visited.add(this);
-    for (int index = 0; index < visited.length; index++) {
-      LibraryElement library = visited[index];
-      Source source = library.definingCompilationUnit.source;
-      if (source == htmlLibSource) {
-        return true;
-      }
-      for (LibraryElement importedLibrary in library.importedLibraries) {
-        if (!visited.contains(importedLibrary)) {
-          visited.add(importedLibrary);
-        }
-      }
-      for (LibraryElement exportedLibrary in library.exportedLibraries) {
-        if (!visited.contains(exportedLibrary)) {
-          visited.add(exportedLibrary);
-        }
-      }
-    }
-    return false;
-  }
-
-  @override
-  ElementKind get kind => ElementKind.LIBRARY;
-
-  @override
-  LibraryElement get library => this;
-
-  List<LibraryElement> get libraryCycle {
-    if (_libraryCycle != null) {
-      return _libraryCycle;
-    }
-
-    // Global counter for this run of the algorithm
-    int counter = 0;
-    // The discovery times of each library
-    Map<LibraryElementImpl, int> indices = {};
-    // The set of scc candidates
-    Set<LibraryElementImpl> active = new Set();
-    // The stack of discovered elements
-    List<LibraryElementImpl> stack = [];
-    // For a given library that has not yet been processed by this run of the
-    // algorithm, compute the strongly connected components.
-    int scc(LibraryElementImpl library) {
-      int index = counter++;
-      int root = index;
-      indices[library] = index;
-      active.add(library);
-      stack.add(library);
-      void recurse(LibraryElementImpl child) {
-        if (!indices.containsKey(child)) {
-          // We haven't visited this child yet, so recurse on the child,
-          // returning the lowest numbered node reachable from the child.  If
-          // the child can reach a root which is lower numbered than anything
-          // we've reached so far, update the root.
-          root = min(root, scc(child));
-        } else if (active.contains(child)) {
-          // The child has been visited, but has not yet been placed into a
-          // component.  If the child is higher than anything we've seen so far
-          // update the root appropriately.
-          root = min(root, indices[child]);
-        }
-      }
-      // Recurse on all of the children in the import/export graph, filtering
-      // out those for which library cycles have already been computed.
-      library.exportedLibraries
-          .where((l) => l._libraryCycle == null)
-          .forEach(recurse);
-      library.importedLibraries
-          .where((l) => l._libraryCycle == null)
-          .forEach(recurse);
-
-      if (root == index) {
-        // This is the root of a strongly connected component.
-        // Pop the elements, and share the component across all
-        // of the elements.
-        List<LibraryElement> component = <LibraryElement>[];
-        LibraryElementImpl cur = null;
-        do {
-          cur = stack.removeLast();
-          active.remove(cur);
-          component.add(cur);
-          cur._libraryCycle = component;
-        } while (cur != library);
-      }
-      return root;
-    }
-    scc(library);
-    return _libraryCycle;
-  }
-
-  @override
-  FunctionElement get loadLibraryFunction {
-    assert(_loadLibraryFunction != null);
-    return _loadLibraryFunction;
-  }
-
-  @override
-  List<CompilationUnitElement> get parts => _parts;
-
-  /**
-   * Set the compilation units that are included in this library using a `part`
-   * directive to the given list of [parts].
-   */
-  void set parts(List<CompilationUnitElement> parts) {
-    for (CompilationUnitElement compilationUnit in parts) {
-      assert((compilationUnit as CompilationUnitElementImpl).librarySource ==
-          source);
-      (compilationUnit as CompilationUnitElementImpl).enclosingElement = this;
-    }
-    this._parts = parts;
-  }
-
-  @override
-  List<PrefixElement> get prefixes {
-    HashSet<PrefixElement> prefixes = new HashSet<PrefixElement>();
-    for (ImportElement element in _imports) {
-      PrefixElement prefix = element.prefix;
-      if (prefix != null) {
-        prefixes.add(prefix);
-      }
-    }
-    return new List.from(prefixes);
-  }
-
-  @override
-  Source get source {
-    if (_definingCompilationUnit == null) {
-      return null;
-    }
-    return _definingCompilationUnit.source;
-  }
-
-  @override
-  List<CompilationUnitElement> get units {
-    List<CompilationUnitElement> units = new List<CompilationUnitElement>();
-    units.add(_definingCompilationUnit);
-    units.addAll(_parts);
-    return units;
-  }
-
-  @override
-  List<LibraryElement> get visibleLibraries {
-    Set<LibraryElement> visibleLibraries = new Set();
-    _addVisibleLibraries(visibleLibraries, false);
-    return new List.from(visibleLibraries);
-  }
-
-  @override
-  bool operator ==(Object object) => object is LibraryElementImpl &&
-      _definingCompilationUnit == object.definingCompilationUnit;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
-
-  /**
-   * Create the [FunctionElement] to be returned by [loadLibraryFunction],
-   * using types provided by [typeProvider].
-   */
-  void createLoadLibraryFunction(TypeProvider typeProvider) {
-    FunctionElementImpl function =
-        new FunctionElementImpl(FunctionElement.LOAD_LIBRARY_NAME, -1);
-    function.synthetic = true;
-    function.enclosingElement = this;
-    function.returnType = typeProvider.futureDynamicType;
-    function.type = new FunctionTypeImpl(function);
-    _loadLibraryFunction = function;
-  }
-
-  @override
-  ElementImpl getChild(String identifier) {
-    if ((_definingCompilationUnit as CompilationUnitElementImpl).identifier ==
-        identifier) {
-      return _definingCompilationUnit as CompilationUnitElementImpl;
-    }
-    for (CompilationUnitElement part in _parts) {
-      if ((part as CompilationUnitElementImpl).identifier == identifier) {
-        return part as CompilationUnitElementImpl;
-      }
-    }
-    for (ImportElement importElement in _imports) {
-      if ((importElement as ImportElementImpl).identifier == identifier) {
-        return importElement as ImportElementImpl;
-      }
-    }
-    for (ExportElement exportElement in _exports) {
-      if ((exportElement as ExportElementImpl).identifier == identifier) {
-        return exportElement as ExportElementImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
-  List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) {
-    int count = _imports.length;
-    List<ImportElement> importList = new List<ImportElement>();
-    for (int i = 0; i < count; i++) {
-      if (identical(_imports[i].prefix, prefixElement)) {
-        importList.add(_imports[i]);
-      }
-    }
-    return importList;
-  }
-
-  @override
-  ClassElement getType(String className) {
-    ClassElement type = _definingCompilationUnit.getType(className);
-    if (type != null) {
-      return type;
-    }
-    for (CompilationUnitElement part in _parts) {
-      type = part.getType(className);
-      if (type != null) {
-        return type;
-      }
-    }
-    return null;
-  }
-
-  @override
-  bool isUpToDate(int timeStamp) {
-    Set<LibraryElement> visitedLibraries = new Set();
-    return _safeIsUpToDate(this, timeStamp, visitedLibraries);
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(_definingCompilationUnit, visitor);
-    safelyVisitChildren(_exports, visitor);
-    safelyVisitChildren(_imports, visitor);
-    safelyVisitChildren(_parts, visitor);
-  }
-
-  /**
-   * Recursively fills set of visible libraries for
-   * [getVisibleElementsLibraries].
-   */
-  void _addVisibleLibraries(
-      Set<LibraryElement> visibleLibraries, bool includeExports) {
-    // maybe already processed
-    if (!visibleLibraries.add(this)) {
-      return;
-    }
-    // add imported libraries
-    for (ImportElement importElement in _imports) {
-      LibraryElement importedLibrary = importElement.importedLibrary;
-      if (importedLibrary != null) {
-        (importedLibrary as LibraryElementImpl)
-            ._addVisibleLibraries(visibleLibraries, true);
-      }
-    }
-    // add exported libraries
-    if (includeExports) {
-      for (ExportElement exportElement in _exports) {
-        LibraryElement exportedLibrary = exportElement.exportedLibrary;
-        if (exportedLibrary != null) {
-          (exportedLibrary as LibraryElementImpl)
-              ._addVisibleLibraries(visibleLibraries, true);
-        }
-      }
-    }
-  }
-
-  /**
-   * Return `true` if the given [library] is up to date with respect to the
-   * given [timeStamp]. The set of [visitedLibraries] is used to prevent
-   * infinite recusion in the case of mutually dependent libraries.
-   */
-  static bool _safeIsUpToDate(LibraryElement library, int timeStamp,
-      Set<LibraryElement> visitedLibraries) {
-    if (!visitedLibraries.contains(library)) {
-      visitedLibraries.add(library);
-      AnalysisContext context = library.context;
-      // Check the defining compilation unit.
-      if (timeStamp <
-          context
-              .getModificationStamp(library.definingCompilationUnit.source)) {
-        return false;
-      }
-      // Check the parted compilation units.
-      for (CompilationUnitElement element in library.parts) {
-        if (timeStamp < context.getModificationStamp(element.source)) {
-          return false;
-        }
-      }
-      // Check the imported libraries.
-      for (LibraryElement importedLibrary in library.importedLibraries) {
-        if (!_safeIsUpToDate(importedLibrary, timeStamp, visitedLibraries)) {
-          return false;
-        }
-      }
-      // Check the exported libraries.
-      for (LibraryElement exportedLibrary in library.exportedLibraries) {
-        if (!_safeIsUpToDate(exportedLibrary, timeStamp, visitedLibraries)) {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-}
-
-/**
- * An element that can be (but are not required to be) defined within a method
- * or function (an [ExecutableElement]).
- */
-abstract class LocalElement implements Element {
-  /**
-   * Return a source range that covers the approximate portion of the source in
-   * which the name of this element is visible, or `null` if there is no single
-   * range of characters within which the element name is visible.
-   *
-   * * For a local variable, this includes everything from the end of the
-   *   variable's initializer to the end of the block that encloses the variable
-   *   declaration.
-   * * For a parameter, this includes the body of the method or function that
-   *   declares the parameter.
-   * * For a local function, this includes everything from the beginning of the
-   *   function's body to the end of the block that encloses the function
-   *   declaration.
-   * * For top-level functions, `null` will be returned because they are
-   *   potentially visible in multiple sources.
-   */
-  SourceRange get visibleRange;
-}
-
-/**
- * A local variable.
- */
-abstract class LocalVariableElement implements LocalElement, VariableElement {
-  /**
-   * An empty list of field elements.
-   */
-  static const List<LocalVariableElement> EMPTY_LIST =
-      const <LocalVariableElement>[];
-
-  /**
-   * Return the resolved [VariableDeclaration] node that declares this
-   * [LocalVariableElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  VariableDeclaration computeNode();
-}
-
-/**
- * A concrete implementation of a [LocalVariableElement].
- */
-class LocalVariableElementImpl extends VariableElementImpl
-    implements LocalVariableElement {
-  /**
-   * An empty list of field elements.
-   */
-  @deprecated // Use LocalVariableElement.EMPTY_LIST
-  static const List<LocalVariableElement> EMPTY_ARRAY =
-      const <LocalVariableElement>[];
-
-  /**
-   * The offset to the beginning of the visible range for this element.
-   */
-  int _visibleRangeOffset = 0;
-
-  /**
-   * The length of the visible range for this element, or `-1` if this element
-   * does not have a visible range.
-   */
-  int _visibleRangeLength = -1;
-
-  /**
-   * Initialize a newly created method element to have the given [name] and
-   * [offset].
-   */
-  LocalVariableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created local variable element to have the given [name].
-   */
-  LocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  String get identifier {
-    int enclosingOffset =
-        enclosingElement != null ? enclosingElement.nameOffset : 0;
-    int delta = nameOffset - enclosingOffset;
-    return '${super.identifier}@$delta';
-  }
-
-  @override
-  bool get isPotentiallyMutatedInClosure =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
-
-  @override
-  bool get isPotentiallyMutatedInScope =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
-
-  @override
-  ElementKind get kind => ElementKind.LOCAL_VARIABLE;
-
-  @override
-  SourceRange get visibleRange {
-    if (_visibleRangeLength < 0) {
-      return null;
-    }
-    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitLocalVariableElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(type);
-    buffer.write(" ");
-    buffer.write(displayName);
-  }
-
-  @override
-  VariableDeclaration computeNode() =>
-      getNodeMatching((node) => node is VariableDeclaration);
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in closure.
-   */
-  void markPotentiallyMutatedInClosure() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
-  }
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in its scope.
-   */
-  void markPotentiallyMutatedInScope() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
-  }
-
-  /**
-   * Set the visible range for this element to the range starting at the given
-   * [offset] with the given [length].
-   */
-  void setVisibleRange(int offset, int length) {
-    _visibleRangeOffset = offset;
-    _visibleRangeLength = length;
-  }
-}
-
-/**
- * An element defined in a parameterized type where the values of the type
- * parameters are known.
- */
-abstract class Member implements Element {
-  /**
-   * The element on which the parameterized element was created.
-   */
-  final Element _baseElement;
-
-  /**
-   * The type in which the element is defined.
-   */
-  final ParameterizedType _definingType;
-
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  Member(this._baseElement, this._definingType);
-
-  /**
-   * Return the element on which the parameterized element was created.
-   */
-  Element get baseElement => _baseElement;
-
-  @override
-  AnalysisContext get context => _baseElement.context;
-
-  /**
-   * Return the type in which the element is defined.
-   */
-  ParameterizedType get definingType => _definingType;
-
-  @override
-  String get displayName => _baseElement.displayName;
-
-  @override
-  SourceRange get docRange => _baseElement.docRange;
-
-  int get id => _baseElement.id;
-
-  @override
-  bool get isDeprecated => _baseElement.isDeprecated;
-
-  @override
-  bool get isOverride => _baseElement.isOverride;
-
-  @override
-  bool get isPrivate => _baseElement.isPrivate;
-
-  @override
-  bool get isPublic => _baseElement.isPublic;
-
-  @override
-  bool get isSynthetic => _baseElement.isSynthetic;
-
-  @override
-  ElementKind get kind => _baseElement.kind;
-
-  @override
-  LibraryElement get library => _baseElement.library;
-
-  @override
-  ElementLocation get location => _baseElement.location;
-
-  @override
-  List<ElementAnnotation> get metadata => _baseElement.metadata;
-
-  @override
-  String get name => _baseElement.name;
-
-  @override
-  int get nameLength => _baseElement.nameLength;
-
-  @override
-  int get nameOffset => _baseElement.nameOffset;
-
-  @deprecated
-  @override
-  AstNode get node => computeNode();
-
-  @override
-  Source get source => _baseElement.source;
-
-  @override
-  CompilationUnit get unit => _baseElement.unit;
-
-  @override
-  String computeDocumentationComment() =>
-      _baseElement.computeDocumentationComment();
-
-  @override
-  AstNode computeNode() => _baseElement.computeNode();
-
-  @override
-  Element getAncestor(Predicate<Element> predicate) =>
-      baseElement.getAncestor(predicate);
-
-  @override
-  String getExtendedDisplayName(String shortName) =>
-      _baseElement.getExtendedDisplayName(shortName);
-
-  @override
-  bool isAccessibleIn(LibraryElement library) =>
-      _baseElement.isAccessibleIn(library);
-
-  /**
-   * If the given [child] is not `null`, use the given [visitor] to visit it.
-   */
-  void safelyVisitChild(Element child, ElementVisitor visitor) {
-    // TODO(brianwilkerson) Make this private
-    if (child != null) {
-      child.accept(visitor);
-    }
-  }
-
-  /**
-   * Use the given [visitor] to visit all of the [children].
-   */
-  void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
-    // TODO(brianwilkerson) Make this private
-    if (children != null) {
-      for (Element child in children) {
-        child.accept(visitor);
-      }
-    }
-  }
-
-  /**
-   * Return the type that results from replacing the type parameters in the
-   * given [type] with the type arguments associated with this member.
-   */
-  DartType substituteFor(DartType type) {
-    if (type == null) {
-      return null;
-    }
-    List<DartType> argumentTypes = _definingType.typeArguments;
-    List<DartType> parameterTypes =
-        TypeParameterTypeImpl.getTypes(_definingType.typeParameters);
-    return type.substitute2(argumentTypes, parameterTypes);
-  }
-
-  /**
-   * Return the list of types that results from replacing the type parameters in
-   * the given [types] with the type arguments associated with this member.
-   */
-  List<InterfaceType> substituteFor2(List<InterfaceType> types) {
-    int count = types.length;
-    List<InterfaceType> substitutedTypes = new List<InterfaceType>(count);
-    for (int i = 0; i < count; i++) {
-      substitutedTypes[i] = substituteFor(types[i]);
-    }
-    return substitutedTypes;
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // There are no children to visit
-  }
-}
-
-/**
- * An element that represents a method defined within a type.
- */
-abstract class MethodElement implements ClassMemberElement, ExecutableElement {
-  /**
-   * An empty list of method elements.
-   */
-  static const List<MethodElement> EMPTY_LIST = const <MethodElement>[];
-
-  /**
-   * Return the resolved [MethodDeclaration] node that declares this
-   * [MethodElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  MethodDeclaration computeNode();
-}
-
-/**
- * A concrete implementation of a [MethodElement].
- */
-class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
-  /**
-   * An empty list of method elements.
-   */
-  @deprecated // Use MethodElement.EMPTY_LIST
-  static const List<MethodElement> EMPTY_ARRAY = const <MethodElement>[];
-
-  /**
-   * Initialize a newly created method element to have the given [name] at the
-   * given [offset].
-   */
-  MethodElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created method element to have the given [name].
-   */
-  MethodElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this method is abstract.
-   */
-  void set abstract(bool isAbstract) {
-    setModifier(Modifier.ABSTRACT, isAbstract);
-  }
-
-  @override
-  String get displayName {
-    String displayName = super.displayName;
-    if ("unary-" == displayName) {
-      return "-";
-    }
-    return displayName;
-  }
-
-  @override
-  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
-
-  @override
-  bool get isOperator {
-    String name = displayName;
-    if (name.isEmpty) {
-      return false;
-    }
-    int first = name.codeUnitAt(0);
-    return !((0x61 <= first && first <= 0x7A) ||
-        (0x41 <= first && first <= 0x5A) ||
-        first == 0x5F ||
-        first == 0x24);
-  }
-
-  @override
-  bool get isStatic => hasModifier(Modifier.STATIC);
-
-  @override
-  ElementKind get kind => ElementKind.METHOD;
-
-  @override
-  String get name {
-    String name = super.name;
-    if (isOperator && name == "-") {
-      if (parameters.length == 0) {
-        return "unary-";
-      }
-    }
-    return super.name;
-  }
-
-  /**
-   * Set whether this method is static.
-   */
-  void set static(bool isStatic) {
-    setModifier(Modifier.STATIC, isStatic);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(displayName);
-    super.appendTo(buffer);
-  }
-
-  @override
-  MethodDeclaration computeNode() =>
-      getNodeMatching((node) => node is MethodDeclaration);
-}
-
-/**
- * A method element defined in a parameterized type where the values of the type
- * parameters are known.
- */
-class MethodMember extends ExecutableMember implements MethodElement {
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  MethodMember(MethodElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  MethodElement get baseElement => super.baseElement as MethodElement;
-
-  @override
-  ClassElement get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
-
-  @override
-  MethodDeclaration computeNode() => baseElement.computeNode();
-
-  @override
-  String toString() {
-    MethodElement baseElement = this.baseElement;
-    List<ParameterElement> parameters = this.parameters;
-    FunctionType type = this.type;
-    StringBuffer buffer = new StringBuffer();
-    buffer.write(baseElement.enclosingElement.displayName);
-    buffer.write(".");
-    buffer.write(baseElement.displayName);
-    buffer.write("(");
-    int parameterCount = parameters.length;
-    for (int i = 0; i < parameterCount; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      buffer.write(parameters[i]);
-    }
-    buffer.write(")");
-    if (type != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(type.returnType);
-    }
-    return buffer.toString();
-  }
-
-  /**
-   * If the given [method]'s type is different when any type parameters from the
-   * defining type's declaration are replaced with the actual type arguments
-   * from the [definingType], create a method member representing the given
-   * method. Return the member that was created, or the base method if no member
-   * was created.
-   */
-  static MethodElement from(MethodElement method, InterfaceType definingType) {
-    if (method == null || definingType.typeArguments.length == 0) {
-      return method;
-    }
-    FunctionType baseType = method.type;
-    List<DartType> argumentTypes = definingType.typeArguments;
-    List<DartType> parameterTypes = definingType.element.type.typeArguments;
-    FunctionType substitutedType =
-        baseType.substitute2(argumentTypes, parameterTypes);
-    if (baseType == substitutedType) {
-      return method;
-    }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    return new MethodMember(method, definingType);
-  }
-}
-
-/**
- * The enumeration `Modifier` defines constants for all of the modifiers defined
- * by the Dart language and for a few additional flags that are useful.
- */
-class Modifier extends Enum<Modifier> {
-  /**
-   * Indicates that the modifier 'abstract' was applied to the element.
-   */
-  static const Modifier ABSTRACT = const Modifier('ABSTRACT', 0);
-
-  /**
-   * Indicates that an executable element has a body marked as being
-   * asynchronous.
-   */
-  static const Modifier ASYNCHRONOUS = const Modifier('ASYNCHRONOUS', 1);
-
-  /**
-   * Indicates that the modifier 'const' was applied to the element.
-   */
-  static const Modifier CONST = const Modifier('CONST', 2);
-
-  /**
-   * Indicates that the import element represents a deferred library.
-   */
-  static const Modifier DEFERRED = const Modifier('DEFERRED', 3);
-
-  /**
-   * Indicates that a class element was defined by an enum declaration.
-   */
-  static const Modifier ENUM = const Modifier('ENUM', 4);
-
-  /**
-   * Indicates that a class element was defined by an enum declaration.
-   */
-  static const Modifier EXTERNAL = const Modifier('EXTERNAL', 5);
-
-  /**
-   * Indicates that the modifier 'factory' was applied to the element.
-   */
-  static const Modifier FACTORY = const Modifier('FACTORY', 6);
-
-  /**
-   * Indicates that the modifier 'final' was applied to the element.
-   */
-  static const Modifier FINAL = const Modifier('FINAL', 7);
-
-  /**
-   * Indicates that an executable element has a body marked as being a
-   * generator.
-   */
-  static const Modifier GENERATOR = const Modifier('GENERATOR', 8);
-
-  /**
-   * Indicates that the pseudo-modifier 'get' was applied to the element.
-   */
-  static const Modifier GETTER = const Modifier('GETTER', 9);
-
-  /**
-   * A flag used for libraries indicating that the defining compilation unit
-   * contains at least one import directive whose URI uses the "dart-ext"
-   * scheme.
-   */
-  static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 10);
-
-  /**
-   * Indicates that the associated element did not have an explicit type
-   * associated with it. If the element is an [ExecutableElement], then the
-   * type being referred to is the return type.
-   */
-  static const Modifier IMPLICIT_TYPE = const Modifier('IMPLICIT_TYPE', 11);
-
-  /**
-   * Indicates that a class can validly be used as a mixin.
-   */
-  static const Modifier MIXIN = const Modifier('MIXIN', 12);
-
-  /**
-   * Indicates that a class is a mixin application.
-   */
-  static const Modifier MIXIN_APPLICATION =
-      const Modifier('MIXIN_APPLICATION', 13);
-
-  /**
-   * Indicates that the value of a parameter or local variable might be mutated
-   * within the context.
-   */
-  static const Modifier POTENTIALLY_MUTATED_IN_CONTEXT =
-      const Modifier('POTENTIALLY_MUTATED_IN_CONTEXT', 14);
-
-  /**
-   * Indicates that the value of a parameter or local variable might be mutated
-   * within the scope.
-   */
-  static const Modifier POTENTIALLY_MUTATED_IN_SCOPE =
-      const Modifier('POTENTIALLY_MUTATED_IN_SCOPE', 15);
-
-  /**
-   * Indicates that a class contains an explicit reference to 'super'.
-   */
-  static const Modifier REFERENCES_SUPER =
-      const Modifier('REFERENCES_SUPER', 16);
-
-  /**
-   * Indicates that the pseudo-modifier 'set' was applied to the element.
-   */
-  static const Modifier SETTER = const Modifier('SETTER', 17);
-
-  /**
-   * Indicates that the modifier 'static' was applied to the element.
-   */
-  static const Modifier STATIC = const Modifier('STATIC', 18);
-
-  /**
-   * Indicates that the element does not appear in the source code but was
-   * implicitly created. For example, if a class does not define any
-   * constructors, an implicit zero-argument constructor will be created and it
-   * will be marked as being synthetic.
-   */
-  static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 19);
-
-  static const List<Modifier> values = const [
-    ABSTRACT,
-    ASYNCHRONOUS,
-    CONST,
-    DEFERRED,
-    ENUM,
-    EXTERNAL,
-    FACTORY,
-    FINAL,
-    GENERATOR,
-    GETTER,
-    HAS_EXT_URI,
-    IMPLICIT_TYPE,
-    MIXIN,
-    MIXIN_APPLICATION,
-    POTENTIALLY_MUTATED_IN_CONTEXT,
-    POTENTIALLY_MUTATED_IN_SCOPE,
-    REFERENCES_SUPER,
-    SETTER,
-    STATIC,
-    SYNTHETIC
-  ];
-
-  const Modifier(String name, int ordinal) : super(name, ordinal);
-}
-
-/**
- * A pseudo-element that represents multiple elements defined within a single
- * scope that have the same name. This situation is not allowed by the language,
- * so objects implementing this interface always represent an error. As a
- * result, most of the normal operations on elements do not make sense and will
- * return useless results.
- */
-abstract class MultiplyDefinedElement implements Element {
-  /**
-   * Return a list containing all of the elements that were defined within the
-   * scope to have the same name.
-   */
-  List<Element> get conflictingElements;
-
-  /**
-   * Return the type of this element as the dynamic type.
-   */
-  DartType get type;
-}
-
-/**
- * A concrete implementation of a [MultiplyDefinedElement].
- */
-class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
-  /**
-   * The unique integer identifier of this element.
-   */
-  final int id = ElementImpl._NEXT_ID++;
-
-  /**
-   * The analysis context in which the multiply defined elements are defined.
-   */
-  final AnalysisContext context;
-
-  /**
-   * The name of the conflicting elements.
-   */
-  String _name;
-
-  /**
-   * A list containing all of the elements that conflict.
-   */
-  final List<Element> conflictingElements;
-
-  /**
-   * Initialize a newly created element in the given [context] to represent a
-   * list of [conflictingElements].
-   */
-  MultiplyDefinedElementImpl(this.context, this.conflictingElements) {
-    _name = conflictingElements[0].name;
-  }
-
-  @override
-  String get displayName => _name;
-
-  @override
-  SourceRange get docRange => null;
-
-  @override
-  Element get enclosingElement => null;
-
-  @override
-  bool get isDeprecated => false;
-
-  @override
-  bool get isOverride => false;
-
-  @override
-  bool get isPrivate {
-    String name = displayName;
-    if (name == null) {
-      return false;
-    }
-    return Identifier.isPrivateName(name);
-  }
-
-  @override
-  bool get isPublic => !isPrivate;
-
-  @override
-  bool get isSynthetic => true;
-
-  @override
-  ElementKind get kind => ElementKind.ERROR;
-
-  @override
-  LibraryElement get library => null;
-
-  @override
-  ElementLocation get location => null;
-
-  @override
-  List<ElementAnnotation> get metadata => ElementAnnotation.EMPTY_LIST;
-
-  @override
-  String get name => _name;
-
-  @override
-  int get nameLength => displayName != null ? displayName.length : 0;
-
-  @override
-  int get nameOffset => -1;
-
-  @deprecated
-  @override
-  AstNode get node => null;
-
-  @override
-  Source get source => null;
-
-  @override
-  DartType get type => DynamicTypeImpl.instance;
-
-  @override
-  CompilationUnit get unit => null;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitMultiplyDefinedElement(this);
-
-  @override
-  String computeDocumentationComment() => null;
-
-  @override
-  AstNode computeNode() => null;
-
-  @override
-  Element getAncestor(Predicate<Element> predicate) => null;
-
-  @override
-  String getExtendedDisplayName(String shortName) {
-    if (shortName != null) {
-      return shortName;
-    }
-    return displayName;
-  }
-
-  @override
-  bool isAccessibleIn(LibraryElement library) {
-    for (Element element in conflictingElements) {
-      if (element.isAccessibleIn(library)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("[");
-    int count = conflictingElements.length;
-    for (int i = 0; i < count; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      (conflictingElements[i] as ElementImpl).appendTo(buffer);
-    }
-    buffer.write("]");
-    return buffer.toString();
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // There are no children to visit
-  }
-
-  /**
-   * Return an element in the given [context] that represents the fact that the
-   * [firstElement] and [secondElement] conflict. (If the elements are the same,
-   * then one of the two will be returned directly.)
-   */
-  static Element fromElements(
-      AnalysisContext context, Element firstElement, Element secondElement) {
-    List<Element> conflictingElements =
-        _computeConflictingElements(firstElement, secondElement);
-    int length = conflictingElements.length;
-    if (length == 0) {
-      return null;
-    } else if (length == 1) {
-      return conflictingElements[0];
-    }
-    return new MultiplyDefinedElementImpl(context, conflictingElements);
-  }
-
-  /**
-   * Add the given [element] to the list of [elements]. If the element is a
-   * multiply-defined element, add all of the conflicting elements that it
-   * represents.
-   */
-  static void _add(HashSet<Element> elements, Element element) {
-    if (element is MultiplyDefinedElementImpl) {
-      for (Element conflictingElement in element.conflictingElements) {
-        elements.add(conflictingElement);
-      }
-    } else {
-      elements.add(element);
-    }
-  }
-
-  /**
-   * Use the given elements to construct a list of conflicting elements. If
-   * either the [firstElement] or [secondElement] are multiply-defined elements
-   * then the conflicting elements they represent will be included in the array.
-   * Otherwise, the element itself will be included.
-   */
-  static List<Element> _computeConflictingElements(
-      Element firstElement, Element secondElement) {
-    HashSet<Element> elements = new HashSet<Element>();
-    _add(elements, firstElement);
-    _add(elements, secondElement);
-    return new List.from(elements);
-  }
-}
-
-/**
- * An [ExecutableElement], with the additional information of a list of
- * [ExecutableElement]s from which this element was composed.
- */
-abstract class MultiplyInheritedExecutableElement implements ExecutableElement {
-  /**
-   * Return a list containing all of the executable elements defined within this
-   * executable element.
-   */
-  List<ExecutableElement> get inheritedElements;
-}
-
-/**
- * A [MethodElementImpl], with the additional information of a list of
- * [ExecutableElement]s from which this element was composed.
- */
-class MultiplyInheritedMethodElementImpl extends MethodElementImpl
-    implements MultiplyInheritedExecutableElement {
-  /**
-   * A list the array of executable elements that were used to compose this
-   * element.
-   */
-  List<ExecutableElement> _elements = MethodElement.EMPTY_LIST;
-
-  MultiplyInheritedMethodElementImpl(Identifier name) : super.forNode(name) {
-    synthetic = true;
-  }
-
-  @override
-  List<ExecutableElement> get inheritedElements => _elements;
-
-  void set inheritedElements(List<ExecutableElement> elements) {
-    this._elements = elements;
-  }
-}
-
-/**
- * A [PropertyAccessorElementImpl], with the additional information of a list of
- * [ExecutableElement]s from which this element was composed.
- */
-class MultiplyInheritedPropertyAccessorElementImpl
-    extends PropertyAccessorElementImpl
-    implements MultiplyInheritedExecutableElement {
-  /**
-   * A list the array of executable elements that were used to compose this
-   * element.
-   */
-  List<ExecutableElement> _elements = PropertyAccessorElement.EMPTY_LIST;
-
-  MultiplyInheritedPropertyAccessorElementImpl(Identifier name)
-      : super.forNode(name) {
-    synthetic = true;
-  }
-
-  @override
-  List<ExecutableElement> get inheritedElements => _elements;
-
-  void set inheritedElements(List<ExecutableElement> elements) {
-    this._elements = elements;
-  }
-}
-
-/**
- * An object that controls how namespaces are combined.
- */
-abstract class NamespaceCombinator {
-  /**
-   * An empty list of namespace combinators.
-   */
-  @deprecated // Use NamespaceCombinator.EMPTY_LIST
-  static const List<NamespaceCombinator> EMPTY_ARRAY =
-      const <NamespaceCombinator>[];
-
-  /**
-   * An empty list of namespace combinators.
-   */
-  static const List<NamespaceCombinator> EMPTY_LIST =
-      const <NamespaceCombinator>[];
-}
-
-/**
- * A parameter defined within an executable element.
- */
-abstract class ParameterElement
-    implements LocalElement, VariableElement, ConstantEvaluationTarget {
-  /**
-   * An empty list of parameter elements.
-   */
-  static const List<ParameterElement> EMPTY_LIST = const <ParameterElement>[];
-
-  /**
-   * Return the Dart code of the default value, or `null` if no default value.
-   */
-  String get defaultValueCode;
-
-  /**
-   * Return `true` if this parameter is an initializing formal parameter.
-   */
-  bool get isInitializingFormal;
-
-  /**
-   * Return the kind of this parameter.
-   */
-  ParameterKind get parameterKind;
-
-  /**
-   * Return a list containing all of the parameters defined by this parameter.
-   * A parameter will only define other parameters if it is a function typed
-   * parameter.
-   */
-  List<ParameterElement> get parameters;
-
-  /**
-   * Return a list containing all of the type parameters defined by this
-   * parameter. A parameter will only define other parameters if it is a
-   * function typed parameter.
-   */
-  List<TypeParameterElement> get typeParameters;
-
-  /**
-   * Append the type, name and possibly the default value of this parameter to
-   * the given [buffer].
-   */
-  void appendToWithoutDelimiters(StringBuffer buffer);
-
-  @override
-  FormalParameter computeNode();
-}
-
-/**
- * A concrete implementation of a [ParameterElement].
- */
-class ParameterElementImpl extends VariableElementImpl
-    with ParameterElementMixin
-    implements ParameterElement {
-  /**
-   * An empty list of parameter elements.
-   */
-  @deprecated // Use ParameterElement.EMPTY_LIST
-  static const List<ParameterElement> EMPTY_ARRAY = const <ParameterElement>[];
-
-  /**
-   * A list containing all of the parameters defined by this parameter element.
-   * There will only be parameters if this parameter is a function typed
-   * parameter.
-   */
-  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the type parameters defined for this parameter
-   * element. There will only be parameters if this parameter is a function
-   * typed parameter.
-   */
-  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
-  /**
-   * The kind of this parameter.
-   */
-  ParameterKind parameterKind;
-
-  /**
-   * The Dart code of the default value.
-   */
-  String _defaultValueCode;
-
-  /**
-   * The offset to the beginning of the visible range for this element.
-   */
-  int _visibleRangeOffset = 0;
-
-  /**
-   * The length of the visible range for this element, or `-1` if this element
-   * does not have a visible range.
-   */
-  int _visibleRangeLength = -1;
-
-  /**
-   * Initialize a newly created parameter element to have the given [name] and
-   * [offset].
-   */
-  ParameterElementImpl(String name, int nameOffset) : super(name, nameOffset);
-
-  /**
-   * Initialize a newly created parameter element to have the given [name].
-   */
-  ParameterElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  String get defaultValueCode => _defaultValueCode;
-
-  /**
-   * Set Dart code of the default value.
-   */
-  void set defaultValueCode(String defaultValueCode) {
-    this._defaultValueCode = StringUtilities.intern(defaultValueCode);
-  }
-
-  @override
-  bool get isInitializingFormal => false;
-
-  @override
-  bool get isPotentiallyMutatedInClosure =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
-
-  @override
-  bool get isPotentiallyMutatedInScope =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
-
-  @override
-  ElementKind get kind => ElementKind.PARAMETER;
-
-  @override
-  List<ParameterElement> get parameters => _parameters;
-
-  /**
-   * Set the parameters defined by this executable element to the given
-   * [parameters].
-   */
-  void set parameters(List<ParameterElement> parameters) {
-    for (ParameterElement parameter in parameters) {
-      (parameter as ParameterElementImpl).enclosingElement = this;
-    }
-    this._parameters = parameters;
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters defined by this parameter element to the given
-   * [typeParameters].
-   */
-  void set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement parameter in typeParameters) {
-      (parameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    this._typeParameters = typeParameters;
-  }
-
-  @override
-  SourceRange get visibleRange {
-    if (_visibleRangeLength < 0) {
-      return null;
-    }
-    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    String left = "";
-    String right = "";
-    while (true) {
-      if (parameterKind == ParameterKind.NAMED) {
-        left = "{";
-        right = "}";
-      } else if (parameterKind == ParameterKind.POSITIONAL) {
-        left = "[";
-        right = "]";
-      } else if (parameterKind == ParameterKind.REQUIRED) {}
-      break;
-    }
-    buffer.write(left);
-    appendToWithoutDelimiters(buffer);
-    buffer.write(right);
-  }
-
-  @override
-  FormalParameter computeNode() =>
-      getNodeMatching((node) => node is FormalParameter);
-
-  @override
-  ElementImpl getChild(String identifier) {
-    for (ParameterElement parameter in _parameters) {
-      if ((parameter as ParameterElementImpl).identifier == identifier) {
-        return parameter as ParameterElementImpl;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in closure.
-   */
-  void markPotentiallyMutatedInClosure() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
-  }
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in its scope.
-   */
-  void markPotentiallyMutatedInScope() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
-  }
-
-  /**
-   * Set the visible range for this element to the range starting at the given
-   * [offset] with the given [length].
-   */
-  void setVisibleRange(int offset, int length) {
-    _visibleRangeOffset = offset;
-    _visibleRangeLength = length;
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_parameters, visitor);
-  }
-}
-
-/**
- * A mixin that provides a common implementation for methods defined in
- * [ParameterElement].
- */
-abstract class ParameterElementMixin implements ParameterElement {
-  @override
-  void appendToWithoutDelimiters(StringBuffer buffer) {
-    buffer.write(type);
-    buffer.write(" ");
-    buffer.write(displayName);
-    if (defaultValueCode != null) {
-      if (parameterKind == ParameterKind.NAMED) {
-        buffer.write(": ");
-      }
-      if (parameterKind == ParameterKind.POSITIONAL) {
-        buffer.write(" = ");
-      }
-      buffer.write(defaultValueCode);
-    }
-  }
-}
-
-/**
- * A type with type parameters, such as a class or function type alias.
- */
-abstract class ParameterizedType implements DartType {
-  /**
-   * Return a list containing the actual types of the type arguments. If this
-   * type's element does not have type parameters, then the array should be
-   * empty (although it is possible for type arguments to be erroneously
-   * declared). If the element has type parameters and the actual type does not
-   * explicitly include argument values, then the type "dynamic" will be
-   * automatically provided.
-   */
-  List<DartType> get typeArguments;
-
-  /**
-   * Return a list containing all of the type parameters declared for this type.
-   */
-  List<TypeParameterElement> get typeParameters;
-}
-
-/**
- * A parameter element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-class ParameterMember extends VariableMember
-    with ParameterElementMixin
-    implements ParameterElement {
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  ParameterMember(ParameterElement baseElement, ParameterizedType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  ParameterElement get baseElement => super.baseElement as ParameterElement;
-
-  @override
-  String get defaultValueCode => baseElement.defaultValueCode;
-
-  @override
-  Element get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  bool get isInitializingFormal => baseElement.isInitializingFormal;
-
-  @override
-  ParameterKind get parameterKind => baseElement.parameterKind;
-
-  @override
-  List<ParameterElement> get parameters {
-    List<ParameterElement> baseParameters = baseElement.parameters;
-    int parameterCount = baseParameters.length;
-    if (parameterCount == 0) {
-      return baseParameters;
-    }
-    List<ParameterElement> parameterizedParameters =
-        new List<ParameterElement>(parameterCount);
-    for (int i = 0; i < parameterCount; i++) {
-      parameterizedParameters[i] =
-          ParameterMember.from(baseParameters[i], definingType);
-    }
-    return parameterizedParameters;
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
-
-  @override
-  SourceRange get visibleRange => baseElement.visibleRange;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
-
-  @override
-  FormalParameter computeNode() => baseElement.computeNode();
-
-  @override
-  Element getAncestor(Predicate<Element> predicate) {
-    Element element = baseElement.getAncestor(predicate);
-    ParameterizedType definingType = this.definingType;
-    if (definingType is InterfaceType) {
-      InterfaceType definingInterfaceType = definingType;
-      if (element is ConstructorElement) {
-        return ConstructorMember.from(element, definingInterfaceType);
-      } else if (element is MethodElement) {
-        return MethodMember.from(element, definingInterfaceType);
-      } else if (element is PropertyAccessorElement) {
-        return PropertyAccessorMember.from(element, definingInterfaceType);
-      }
-    }
-    return element;
-  }
-
-  @override
-  String toString() {
-    ParameterElement baseElement = this.baseElement;
-    String left = "";
-    String right = "";
-    while (true) {
-      if (baseElement.parameterKind == ParameterKind.NAMED) {
-        left = "{";
-        right = "}";
-      } else if (baseElement.parameterKind == ParameterKind.POSITIONAL) {
-        left = "[";
-        right = "]";
-      } else if (baseElement.parameterKind == ParameterKind.REQUIRED) {}
-      break;
-    }
-    return '$left$type ${baseElement.displayName}$right';
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(parameters, visitor);
-  }
-
-  /**
-   * If the given [parameter]'s type is different when any type parameters from
-   * the defining type's declaration are replaced with the actual type
-   * arguments from the [definingType], create a parameter member representing
-   * the given parameter. Return the member that was created, or the base
-   * parameter if no member was created.
-   */
-  static ParameterElement from(
-      ParameterElement parameter, ParameterizedType definingType) {
-    if (parameter == null || definingType.typeArguments.length == 0) {
-      return parameter;
-    }
-    // Check if parameter type depends on defining type type arguments.
-    // It is possible that we did not resolve field formal parameter yet,
-    // so skip this check for it.
-    bool isFieldFormal = parameter is FieldFormalParameterElement;
-    if (!isFieldFormal) {
-      DartType baseType = parameter.type;
-      List<DartType> argumentTypes = definingType.typeArguments;
-      List<DartType> parameterTypes =
-          TypeParameterTypeImpl.getTypes(definingType.typeParameters);
-      DartType substitutedType =
-          baseType.substitute2(argumentTypes, parameterTypes);
-      if (baseType == substitutedType) {
-        return parameter;
-      }
-    }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    if (isFieldFormal) {
-      return new FieldFormalParameterMember(
-          parameter as FieldFormalParameterElement, definingType);
-    }
-    return new ParameterMember(parameter, definingType);
-  }
-}
-
-/**
- * A prefix used to import one or more libraries into another library.
- */
-abstract class PrefixElement implements Element {
-  /**
-   * An empty list of prefix elements.
-   */
-  static const List<PrefixElement> EMPTY_LIST = const <PrefixElement>[];
-
-  /**
-   * Return the library into which other libraries are imported using this
-   * prefix.
-   */
-  @override
-  LibraryElement get enclosingElement;
-
-  /**
-   * Return a list containing all of the libraries that are imported using this
-   * prefix.
-   */
-  List<LibraryElement> get importedLibraries;
-}
-
-/**
- * A concrete implementation of a [PrefixElement].
- */
-class PrefixElementImpl extends ElementImpl implements PrefixElement {
-  /**
-   * An empty list of prefix elements.
-   */
-  @deprecated // Use PrefixElement.EMPTY_LIST
-  static const List<PrefixElement> EMPTY_ARRAY = const <PrefixElement>[];
-
-  /**
-   * A list containing all of the libraries that are imported using this prefix.
-   */
-  List<LibraryElement> _importedLibraries = LibraryElement.EMPTY_LIST;
-
-  /**
-   * Initialize a newly created method element to have the given [name] and
-   * [offset].
-   */
-  PrefixElementImpl(String name, int nameOffset) : super(name, nameOffset);
-
-  /**
-   * Initialize a newly created prefix element to have the given [name].
-   */
-  PrefixElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  LibraryElement get enclosingElement =>
-      super.enclosingElement as LibraryElement;
-
-  @override
-  String get identifier => "_${super.identifier}";
-
-  @override
-  List<LibraryElement> get importedLibraries => _importedLibraries;
-
-  /**
-   * Set the libraries that are imported using this prefix to the given
-   * [libraries].
-   */
-  void set importedLibraries(List<LibraryElement> libraries) {
-    for (LibraryElement library in libraries) {
-      (library as LibraryElementImpl).enclosingElement = this;
-    }
-    _importedLibraries = libraries;
-  }
-
-  @override
-  ElementKind get kind => ElementKind.PREFIX;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitPrefixElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write("as ");
-    super.appendTo(buffer);
-  }
-}
-
-/**
- * A getter or a setter. Note that explicitly defined property accessors
- * implicitly define a synthetic field. Symmetrically, synthetic accessors are
- * implicitly created for explicitly defined fields. The following rules apply:
- *
- * * Every explicit field is represented by a non-synthetic [FieldElement].
- * * Every explicit field induces a getter and possibly a setter, both of which
- *   are represented by synthetic [PropertyAccessorElement]s.
- * * Every explicit getter or setter is represented by a non-synthetic
- *   [PropertyAccessorElement].
- * * Every explicit getter or setter (or pair thereof if they have the same
- *   name) induces a field that is represented by a synthetic [FieldElement].
- */
-abstract class PropertyAccessorElement implements ExecutableElement {
-  /**
-   * An empty list of property accessor elements.
-   */
-  static const List<PropertyAccessorElement> EMPTY_LIST =
-      const <PropertyAccessorElement>[];
-
-  /**
-   * Return the accessor representing the getter that corresponds to (has the
-   * same name as) this setter, or `null` if this accessor is not a setter or if
-   * there is no corresponding getter.
-   */
-  PropertyAccessorElement get correspondingGetter;
-
-  /**
-   * Return the accessor representing the setter that corresponds to (has the
-   * same name as) this getter, or `null` if this accessor is not a getter or if
-   * there is no corresponding setter.
-   */
-  PropertyAccessorElement get correspondingSetter;
-
-  /**
-   * Return `true` if this accessor represents a getter.
-   */
-  bool get isGetter;
-
-  /**
-   * Return `true` if this accessor represents a setter.
-   */
-  bool get isSetter;
-
-  /**
-   * Return the field or top-level variable associated with this accessor. If
-   * this accessor was explicitly defined (is not synthetic) then the variable
-   * associated with it will be synthetic.
-   */
-  PropertyInducingElement get variable;
-}
-
-/**
- * A concrete implementation of a [PropertyAccessorElement].
- */
-class PropertyAccessorElementImpl extends ExecutableElementImpl
-    implements PropertyAccessorElement {
-  /**
-   * An empty list of property accessor elements.
-   */
-  @deprecated // Use PropertyAccessorElement.EMPTY_LIST
-  static const List<PropertyAccessorElement> EMPTY_ARRAY =
-      const <PropertyAccessorElement>[];
-
-  /**
-   * The variable associated with this accessor.
-   */
-  PropertyInducingElement variable;
-
-  /**
-   * Initialize a newly created property accessor element to have the given
-   * [name].
-   */
-  PropertyAccessorElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Initialize a newly created synthetic property accessor element to be
-   * associated with the given [variable].
-   */
-  PropertyAccessorElementImpl.forVariable(PropertyInducingElementImpl variable)
-      : super(variable.name, variable.nameOffset) {
-    this.variable = variable;
-    static = variable.isStatic;
-    synthetic = true;
-  }
-
-  /**
-   * Set whether this accessor is abstract.
-   */
-  void set abstract(bool isAbstract) {
-    setModifier(Modifier.ABSTRACT, isAbstract);
-  }
-
-  @override
-  PropertyAccessorElement get correspondingGetter {
-    if (isGetter || variable == null) {
-      return null;
-    }
-    return variable.getter;
-  }
-
-  @override
-  PropertyAccessorElement get correspondingSetter {
-    if (isSetter || variable == null) {
-      return null;
-    }
-    return variable.setter;
-  }
-
-  /**
-   * Set whether this accessor is a getter.
-   */
-  void set getter(bool isGetter) {
-    setModifier(Modifier.GETTER, isGetter);
-  }
-
-  @override
-  int get hashCode => JenkinsSmiHash.hash2(super.hashCode, isGetter ? 1 : 2);
-
-  @override
-  String get identifier {
-    String name = displayName;
-    String suffix = isGetter ? "?" : "=";
-    return "$name$suffix";
-  }
-
-  @override
-  bool get isGetter => hasModifier(Modifier.GETTER);
-
-  @override
-  bool get isSetter => hasModifier(Modifier.SETTER);
-
-  @override
-  bool get isStatic => hasModifier(Modifier.STATIC);
-
-  @override
-  ElementKind get kind {
-    if (isGetter) {
-      return ElementKind.GETTER;
-    }
-    return ElementKind.SETTER;
-  }
-
-  @override
-  String get name {
-    if (isSetter) {
-      return "${super.name}=";
-    }
-    return super.name;
-  }
-
-  /**
-   * Set whether this accessor is a setter.
-   */
-  void set setter(bool isSetter) {
-    setModifier(Modifier.SETTER, isSetter);
-  }
-
-  /**
-   * Set whether this accessor is static.
-   */
-  void set static(bool isStatic) {
-    setModifier(Modifier.STATIC, isStatic);
-  }
-
-  @override
-  bool operator ==(Object object) => super == object &&
-      isGetter == (object as PropertyAccessorElement).isGetter;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(isGetter ? "get " : "set ");
-    buffer.write(variable.displayName);
-    super.appendTo(buffer);
-  }
-
-  @override
-  AstNode computeNode() {
-    if (isSynthetic) {
-      return null;
-    }
-    if (enclosingElement is ClassElement) {
-      return getNodeMatching((node) => node is MethodDeclaration);
-    }
-    if (enclosingElement is CompilationUnitElement) {
-      return getNodeMatching((node) => node is FunctionDeclaration);
-    }
-    return null;
-  }
-}
-
-/**
- * A property accessor element defined in a parameterized type where the values
- * of the type parameters are known.
- */
-class PropertyAccessorMember extends ExecutableMember
-    implements PropertyAccessorElement {
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  PropertyAccessorMember(
-      PropertyAccessorElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  PropertyAccessorElement get baseElement =>
-      super.baseElement as PropertyAccessorElement;
-
-  @override
-  PropertyAccessorElement get correspondingGetter =>
-      from(baseElement.correspondingGetter, definingType);
-
-  @override
-  PropertyAccessorElement get correspondingSetter =>
-      from(baseElement.correspondingSetter, definingType);
-
-  @override
-  InterfaceType get definingType => super.definingType as InterfaceType;
-
-  @override
-  Element get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  bool get isGetter => baseElement.isGetter;
-
-  @override
-  bool get isSetter => baseElement.isSetter;
-
-  @override
-  PropertyInducingElement get variable {
-    PropertyInducingElement variable = baseElement.variable;
-    if (variable is FieldElement) {
-      return FieldMember.from(variable, definingType);
-    }
-    return variable;
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
-
-  @override
-  String toString() {
-    PropertyAccessorElement baseElement = this.baseElement;
-    List<ParameterElement> parameters = this.parameters;
-    FunctionType type = this.type;
-    StringBuffer builder = new StringBuffer();
-    if (isGetter) {
-      builder.write("get ");
-    } else {
-      builder.write("set ");
-    }
-    builder.write(baseElement.enclosingElement.displayName);
-    builder.write(".");
-    builder.write(baseElement.displayName);
-    builder.write("(");
-    int parameterCount = parameters.length;
-    for (int i = 0; i < parameterCount; i++) {
-      if (i > 0) {
-        builder.write(", ");
-      }
-      builder.write(parameters[i]);
-    }
-    builder.write(")");
-    if (type != null) {
-      builder.write(Element.RIGHT_ARROW);
-      builder.write(type.returnType);
-    }
-    return builder.toString();
-  }
-
-  /**
-   * If the given [accessor]'s type is different when any type parameters from
-   * the defining type's declaration are replaced with the actual type
-   * arguments from the [definingType], create an accessor member representing
-   * the given accessor. Return the member that was created, or the base
-   * accessor if no member was created.
-   */
-  static PropertyAccessorElement from(
-      PropertyAccessorElement accessor, InterfaceType definingType) {
-    if (!_isChangedByTypeSubstitution(accessor, definingType)) {
-      return accessor;
-    }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    return new PropertyAccessorMember(accessor, definingType);
-  }
-
-  /**
-   * Determine whether the given property [accessor]'s type is changed when type
-   * parameters from the defining type's declaration are replaced with the
-   * actual type arguments from the [definingType].
-   */
-  static bool _isChangedByTypeSubstitution(
-      PropertyAccessorElement accessor, InterfaceType definingType) {
-    List<DartType> argumentTypes = definingType.typeArguments;
-    if (accessor != null && argumentTypes.length != 0) {
-      FunctionType baseType = accessor.type;
-      if (baseType == null) {
-        AnalysisEngine.instance.logger.logInformation(
-            'Type of $accessor is null in PropertyAccessorMember._isChangedByTypeSubstitution');
-        return false;
-      }
-      List<DartType> parameterTypes = definingType.element.type.typeArguments;
-      FunctionType substitutedType =
-          baseType.substitute2(argumentTypes, parameterTypes);
-      if (baseType != substitutedType) {
-        return true;
-      }
-      // If this property accessor is based on a field, that field might have a
-      // propagated type. In which case we need to check whether the propagated
-      // type of the field needs substitution.
-      PropertyInducingElement field = accessor.variable;
-      if (!field.isSynthetic) {
-        DartType baseFieldType = field.propagatedType;
-        if (baseFieldType != null) {
-          DartType substitutedFieldType =
-              baseFieldType.substitute2(argumentTypes, parameterTypes);
-          if (baseFieldType != substitutedFieldType) {
-            return true;
-          }
-        }
-      }
-    }
-    return false;
-  }
-}
-
-/**
- * A variable that has an associated getter and possibly a setter. Note that
- * explicitly defined variables implicitly define a synthetic getter and that
- * non-`final` explicitly defined variables implicitly define a synthetic
- * setter. Symmetrically, synthetic fields are implicitly created for explicitly
- * defined getters and setters. The following rules apply:
- *
- * * Every explicit variable is represented by a non-synthetic
- *   [PropertyInducingElement].
- * * Every explicit variable induces a getter and possibly a setter, both of
- *   which are represented by synthetic [PropertyAccessorElement]s.
- * * Every explicit getter or setter is represented by a non-synthetic
- *   [PropertyAccessorElement].
- * * Every explicit getter or setter (or pair thereof if they have the same
- *   name) induces a variable that is represented by a synthetic
- *   [PropertyInducingElement].
- */
-abstract class PropertyInducingElement implements VariableElement {
-  /**
-   * An empty list of elements.
-   */
-  static const List<PropertyInducingElement> EMPTY_LIST =
-      const <PropertyInducingElement>[];
-
-  /**
-   * Return the getter associated with this variable. If this variable was
-   * explicitly defined (is not synthetic) then the getter associated with it
-   * will be synthetic.
-   */
-  PropertyAccessorElement get getter;
-
-  /**
-   * Return the propagated type of this variable, or `null` if type propagation
-   * has not been performed, for example because the variable is not final.
-   */
-  DartType get propagatedType;
-
-  /**
-   * Return the setter associated with this variable, or `null` if the variable
-   * is effectively `final` and therefore does not have a setter associated with
-   * it. (This can happen either because the variable is explicitly defined as
-   * being `final` or because the variable is induced by an explicit getter that
-   * does not have a corresponding setter.) If this variable was explicitly
-   * defined (is not synthetic) then the setter associated with it will be
-   * synthetic.
-   */
-  PropertyAccessorElement get setter;
-}
-
-/**
- * A concrete implementation of a [PropertyInducingElement].
- */
-abstract class PropertyInducingElementImpl extends VariableElementImpl
-    implements PropertyInducingElement {
-  /**
-   * An empty list of elements.
-   */
-  @deprecated // Use PropertyInducingElement.EMPTY_LIST
-  static const List<PropertyInducingElement> EMPTY_ARRAY =
-      const <PropertyInducingElement>[];
-
-  /**
-   * The getter associated with this element.
-   */
-  PropertyAccessorElement getter;
-
-  /**
-   * The setter associated with this element, or `null` if the element is
-   * effectively `final` and therefore does not have a setter associated with
-   * it.
-   */
-  PropertyAccessorElement setter;
-
-  /**
-   * The propagated type of this variable, or `null` if type propagation has not
-   * been performed.
-   */
-  DartType propagatedType;
-
-  /**
-   * Initialize a newly created synthetic element to have the given [name] and
-   * [offset].
-   */
-  PropertyInducingElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created element to have the given [name].
-   */
-  PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
-}
-
-/**
- * A visitor that will recursively visit all of the element in an element model.
- * For example, using an instance of this class to visit a
- * [CompilationUnitElement] will also cause all of the types in the compilation
- * unit to be visited.
- *
- * Subclasses that override a visit method must either invoke the overridden
- * visit method or must explicitly ask the visited element to visit its
- * children. Failure to do so will cause the children of the visited element to
- * not be visited.
- */
-class RecursiveElementVisitor<R> implements ElementVisitor<R> {
-  @override
-  R visitClassElement(ClassElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitCompilationUnitElement(CompilationUnitElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitConstructorElement(ConstructorElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  @deprecated
-  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitExportElement(ExportElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  @deprecated
-  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFieldElement(FieldElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFieldFormalParameterElement(FieldFormalParameterElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionElement(FunctionElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  @deprecated
-  R visitHtmlElement(HtmlElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitImportElement(ImportElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLabelElement(LabelElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLibraryElement(LibraryElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLocalVariableElement(LocalVariableElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitMethodElement(MethodElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitMultiplyDefinedElement(MultiplyDefinedElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitParameterElement(ParameterElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPrefixElement(PrefixElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPropertyAccessorElement(PropertyAccessorElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTopLevelVariableElement(TopLevelVariableElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTypeParameterElement(TypeParameterElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-}
-
-/**
- * A combinator that cause some of the names in a namespace to be visible (and
- * the rest hidden) when being imported.
- */
-abstract class ShowElementCombinator implements NamespaceCombinator {
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this node.
-   */
-  int get end;
-
-  /**
-   * Return the offset of the 'show' keyword of this element.
-   */
-  int get offset;
-
-  /**
-   * Return a list containing the names that are to be made visible in the
-   * importing library if they are defined in the imported library.
-   */
-  List<String> get shownNames;
-}
-
-/**
- * A concrete implementation of a [ShowElementCombinator].
- */
-class ShowElementCombinatorImpl implements ShowElementCombinator {
-  /**
-   * The names that are to be made visible in the importing library if they are
-   * defined in the imported library.
-   */
-  List<String> shownNames = StringUtilities.EMPTY_ARRAY;
-
-  /**
-   * The offset of the character immediately following the last character of
-   * this node.
-   */
-  int end = -1;
-
-  /**
-   * The offset of the 'show' keyword of this element.
-   */
-  int offset = 0;
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("show ");
-    int count = shownNames.length;
-    for (int i = 0; i < count; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      buffer.write(shownNames[i]);
-    }
-    return buffer.toString();
-  }
-}
-
-/**
- * A visitor that will do nothing when visiting an element. It is intended to be
- * a superclass for classes that use the visitor pattern primarily as a dispatch
- * mechanism (and hence don't need to recursively visit a whole structure) and
- * that only need to visit a small number of element types.
- */
-class SimpleElementVisitor<R> implements ElementVisitor<R> {
-  @override
-  R visitClassElement(ClassElement element) => null;
-
-  @override
-  R visitCompilationUnitElement(CompilationUnitElement element) => null;
-
-  @override
-  R visitConstructorElement(ConstructorElement element) => null;
-
-  @override
-  @deprecated
-  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) => null;
-
-  @override
-  R visitExportElement(ExportElement element) => null;
-
-  @override
-  @deprecated
-  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) => null;
-
-  @override
-  R visitFieldElement(FieldElement element) => null;
-
-  @override
-  R visitFieldFormalParameterElement(FieldFormalParameterElement element) =>
-      null;
-
-  @override
-  R visitFunctionElement(FunctionElement element) => null;
-
-  @override
-  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null;
-
-  @override
-  @deprecated
-  R visitHtmlElement(HtmlElement element) => null;
-
-  @override
-  R visitImportElement(ImportElement element) => null;
-
-  @override
-  R visitLabelElement(LabelElement element) => null;
-
-  @override
-  R visitLibraryElement(LibraryElement element) => null;
-
-  @override
-  R visitLocalVariableElement(LocalVariableElement element) => null;
-
-  @override
-  R visitMethodElement(MethodElement element) => null;
-
-  @override
-  R visitMultiplyDefinedElement(MultiplyDefinedElement element) => null;
-
-  @override
-  R visitParameterElement(ParameterElement element) => null;
-
-  @override
-  R visitPrefixElement(PrefixElement element) => null;
-
-  @override
-  R visitPropertyAccessorElement(PropertyAccessorElement element) => null;
-
-  @override
-  R visitTopLevelVariableElement(TopLevelVariableElement element) => null;
-
-  @override
-  R visitTypeParameterElement(TypeParameterElement element) => null;
-}
-
-/**
- * A top-level variable.
- */
-abstract class TopLevelVariableElement implements PropertyInducingElement {
-  /**
-   * An empty list of top-level variable elements.
-   */
-  static const List<TopLevelVariableElement> EMPTY_LIST =
-      const <TopLevelVariableElement>[];
-
-  @override
-  VariableDeclaration computeNode();
-}
-
-/**
- * A concrete implementation of a [TopLevelVariableElement].
- */
-class TopLevelVariableElementImpl extends PropertyInducingElementImpl
-    implements TopLevelVariableElement {
-  /**
-   * An empty list of top-level variable elements.
-   */
-  @deprecated // Use TopLevelVariableElement.EMPTY_LIST
-  static const List<TopLevelVariableElement> EMPTY_ARRAY =
-      const <TopLevelVariableElement>[];
-
-  /**
-   * Initialize a newly created synthetic top-level variable element to have the
-   * given [name] and [offset].
-   */
-  TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created top-level variable element to have the given
-   * [name].
-   */
-  TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  bool get isStatic => true;
-
-  @override
-  ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
-
-  @override
-  VariableDeclaration computeNode() =>
-      getNodeMatching((node) => node is VariableDeclaration);
-}
-
-/**
- * An element that defines a type.
- */
-abstract class TypeDefiningElement implements Element {
-  /**
-   * Return the type defined by this element.
-   */
-  DartType get type;
-}
-
-/**
- * The abstract class `TypeImpl` implements the behavior common to objects
- * representing the declared type of elements in the element model.
- */
-abstract class TypeImpl implements DartType {
-  /**
-   * An empty list of types.
-   */
-  @deprecated // Use DartType.EMPTY_LIST
-  static const List<DartType> EMPTY_ARRAY = const <DartType>[];
-
-  /**
-   * The element representing the declaration of this type, or `null` if the
-   * type has not, or cannot, be associated with an element.
-   */
-  final Element _element;
-
-  /**
-   * The name of this type, or `null` if the type does not have a name.
-   */
-  final String name;
-
-  /**
-   * Initialize a newly created type to be declared by the given [element] and
-   * to have the given [name].
-   */
-  TypeImpl(this._element, this.name);
-
-  @override
-  String get displayName => name;
-
-  @override
-  Element get element => _element;
-
-  @override
-  bool get isBottom => false;
-
-  @override
-  bool get isDartCoreFunction => false;
-
-  @override
-  bool get isDynamic => false;
-
-  @override
-  bool get isObject => false;
-
-  @override
-  bool get isUndefined => false;
-
-  @override
-  bool get isVoid => false;
-
-  /**
-   * Append a textual representation of this type to the given [buffer]. The set
-   * of [visitedTypes] is used to prevent infinite recusion.
-   */
-  void appendTo(StringBuffer buffer) {
-    if (name == null) {
-      buffer.write("<unnamed type>");
-    } else {
-      buffer.write(name);
-    }
-  }
-
-  @override
-  DartType getLeastUpperBound(DartType type) => null;
-
-  /**
-   * Return `true` if this type is assignable to the given [type] (written in
-   * the spec as "T <=> S", where T=[this] and S=[type]).
-   *
-   * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
-   * function type aliases that have been expanded so far in the process of
-   * reaching [this] and [type], respectively.  These are used to avoid
-   * infinite regress when analyzing invalid code; since the language spec
-   * forbids a typedef from referring to itself directly or indirectly, we can
-   * use these as sets of function type aliases that don't need to be expanded.
-   */
-  @override
-  bool isAssignableTo(DartType type) {
-    // An interface type T may be assigned to a type S, written T <=> S, iff
-    // either T <: S or S <: T.
-    return isSubtypeOf(type) || (type as TypeImpl).isSubtypeOf(this);
-  }
-
-  /**
-   * Return `true` if this type is more specific than the given [type] (written
-   * in the spec as "T << S", where T=[this] and S=[type]).
-   *
-   * If [withDynamic] is `true`, then "dynamic" should be considered as a
-   * subtype of any type (as though "dynamic" had been replaced with bottom).
-   *
-   * The set [visitedElements], if given, is the set of classes and type
-   * parameters that have been visited so far while examining the class
-   * hierarchy of [this].  This is used to avoid infinite regress when
-   * analyzing invalid code; since the language spec forbids loops in the class
-   * hierarchy, we can use this as a set of classes that don't need to be
-   * examined when walking the class hierarchy.
-   */
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]);
-
-  /**
-   * Return `true` if this type is a subtype of the given [type] (written in
-   * the spec as "T <: S", where T=[this] and S=[type]).
-   *
-   * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
-   * function type aliases that have been expanded so far in the process of
-   * reaching [this] and [type], respectively.  These are used to avoid
-   * infinite regress when analyzing invalid code; since the language spec
-   * forbids a typedef from referring to itself directly or indirectly, we can
-   * use these as sets of function type aliases that don't need to be expanded.
-   */
-  @override
-  bool isSubtypeOf(DartType type) {
-    // For non-function types, T <: S iff [_|_/dynamic]T << S.
-    return isMoreSpecificThan(type, true);
-  }
-
-  @override
-  bool isSupertypeOf(DartType type) => type.isSubtypeOf(this);
-
-  /**
-   * Create a new [TypeImpl] that is identical to [this] except that when
-   * visiting type parameters, function parameter types, and function return
-   * types, function types listed in [prune] will not be expanded.  This is
-   * used to avoid creating infinite types in the presence of circular
-   * typedefs.
-   *
-   * If [prune] is null, then [this] is returned unchanged.
-   *
-   * Only legal to call on a [TypeImpl] that is not already subject to pruning.
-   */
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune);
-
-  /**
-   * Return the type resulting from substituting the given [argumentTypes] for
-   * the given [parameterTypes] in this type.
-   *
-   * In all classes derived from [TypeImpl], a new optional argument
-   * [prune] is added.  If specified, it is a list of function typdefs
-   * which should not be expanded.  This is used to avoid creating infinite
-   * types in response to self-referential typedefs.
-   */
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]);
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    appendTo(buffer);
-    return buffer.toString();
-  }
-
-  /**
-   * Return `true` if corresponding elements of the [first] and [second] lists
-   * of type arguments are all equal.
-   */
-  static bool equalArrays(List<DartType> first, List<DartType> second) {
-    if (first.length != second.length) {
-      return false;
-    }
-    for (int i = 0; i < first.length; i++) {
-      if (first[i] == null) {
-        AnalysisEngine.instance.logger
-            .logInformation('Found null type argument in TypeImpl.equalArrays');
-        return second[i] == null;
-      } else if (second[i] == null) {
-        AnalysisEngine.instance.logger
-            .logInformation('Found null type argument in TypeImpl.equalArrays');
-        return false;
-      }
-      if (first[i] != second[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Return a list containing the results of using the given [argumentTypes] and
-   * [parameterTypes] to perform a substitution on all of the given [types].
-   *
-   * If [prune] is specified, it is a list of function typdefs which should not
-   * be expanded.  This is used to avoid creating infinite types in response to
-   * self-referential typedefs.
-   */
-  static List<DartType> substitute(List<DartType> types,
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    int length = types.length;
-    if (length == 0) {
-      return types;
-    }
-    List<DartType> newTypes = new List<DartType>(length);
-    for (int i = 0; i < length; i++) {
-      newTypes[i] = (types[i] as TypeImpl)
-          .substitute2(argumentTypes, parameterTypes, prune);
-    }
-    return newTypes;
-  }
-}
-
-/**
- * A type parameter.
- */
-abstract class TypeParameterElement implements TypeDefiningElement {
-  /**
-   * An empty list of type parameter elements.
-   */
-  static const List<TypeParameterElement> EMPTY_LIST =
-      const <TypeParameterElement>[];
-
-  /**
-   * Return the type representing the bound associated with this parameter, or
-   * `null` if this parameter does not have an explicit bound.
-   */
-  DartType get bound;
-
-  /**
-   * Return the type defined by this type parameter.
-   */
-  TypeParameterType get type;
-}
-
-/**
- * A concrete implementation of a [TypeParameterElement].
- */
-class TypeParameterElementImpl extends ElementImpl
-    implements TypeParameterElement {
-  /**
-   * An empty list of type parameter elements.
-   */
-  @deprecated // Use TypeParameterElement.EMPTY_LIST
-  static const List<TypeParameterElement> EMPTY_ARRAY =
-      const <TypeParameterElement>[];
-
-  /**
-   * The type defined by this type parameter.
-   */
-  TypeParameterType type;
-
-  /**
-   * The type representing the bound associated with this parameter, or `null`
-   * if this parameter does not have an explicit bound.
-   */
-  DartType bound;
-
-  /**
-   * Initialize a newly created method element to have the given [name] and
-   * [offset].
-   */
-  TypeParameterElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created type parameter element to have the given [name].
-   */
-  TypeParameterElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  ElementKind get kind => ElementKind.TYPE_PARAMETER;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitTypeParameterElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(displayName);
-    if (bound != null) {
-      buffer.write(" extends ");
-      buffer.write(bound);
-    }
-  }
-}
-
-/**
- * The type introduced by a type parameter.
- */
-abstract class TypeParameterType implements DartType {
-  /**
-   * An empty list of type parameter types.
-   */
-  static const List<TypeParameterType> EMPTY_LIST = const <TypeParameterType>[];
-
-  @override
-  TypeParameterElement get element;
-}
-
-/**
- * A concrete implementation of a [TypeParameterType].
- */
-class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
-  /**
-   * An empty list of type parameter types.
-   */
-  @deprecated // Use TypeParameterType.EMPTY_LIST
-  static const List<TypeParameterType> EMPTY_ARRAY =
-      const <TypeParameterType>[];
-
-  /**
-   * Initialize a newly created type parameter type to be declared by the given
-   * [element] and to have the given name.
-   */
-  TypeParameterTypeImpl(TypeParameterElement element)
-      : super(element, element.name);
-
-  @override
-  TypeParameterElement get element => super.element as TypeParameterElement;
-
-  @override
-  int get hashCode => element.hashCode;
-
-  @override
-  bool operator ==(Object object) =>
-      object is TypeParameterTypeImpl && (element == object.element);
-
-  @override
-  bool isMoreSpecificThan(DartType s,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    //
-    // A type T is more specific than a type S, written T << S,
-    // if one of the following conditions is met:
-    //
-    // Reflexivity: T is S.
-    //
-    if (this == s) {
-      return true;
-    }
-    // S is dynamic.
-    //
-    if (s.isDynamic) {
-      return true;
-    }
-    //
-    // T is a type parameter and S is the upper bound of T.
-    //
-    TypeImpl bound = element.bound;
-    if (s == bound) {
-      return true;
-    }
-    //
-    // T is a type parameter and S is Object.
-    //
-    if (s.isObject) {
-      return true;
-    }
-    // We need upper bound to continue.
-    if (bound == null) {
-      return false;
-    }
-    //
-    // Transitivity: T << U and U << S.
-    //
-    // First check for infinite loops
-    if (element == null) {
-      return false;
-    }
-    if (visitedElements == null) {
-      visitedElements = new HashSet<Element>();
-    } else if (visitedElements.contains(element)) {
-      return false;
-    }
-    visitedElements.add(element);
-    try {
-      return bound.isMoreSpecificThan(s, withDynamic, visitedElements);
-    } finally {
-      visitedElements.remove(element);
-    }
-  }
-
-  @override
-  bool isSubtypeOf(DartType type) => isMoreSpecificThan(type, true);
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    int length = parameterTypes.length;
-    for (int i = 0; i < length; i++) {
-      if (parameterTypes[i] == this) {
-        return argumentTypes[i];
-      }
-    }
-    return this;
-  }
-
-  /**
-   * Return a list containing the type parameter types defined by the given
-   * array of type parameter elements ([typeParameters]).
-   */
-  static List<TypeParameterType> getTypes(
-      List<TypeParameterElement> typeParameters) {
-    int count = typeParameters.length;
-    if (count == 0) {
-      return TypeParameterType.EMPTY_LIST;
-    }
-    List<TypeParameterType> types = new List<TypeParameterType>(count);
-    for (int i = 0; i < count; i++) {
-      types[i] = typeParameters[i].type;
-    }
-    return types;
-  }
-}
-
-/**
- * A pseudo-elements that represents names that are undefined. This situation is
- * not allowed by the language, so objects implementing this interface always
- * represent an error. As a result, most of the normal operations on elements do
- * not make sense and will return useless results.
- */
-abstract class UndefinedElement implements Element {}
-
-/**
- * The unique instance of the class `UndefinedTypeImpl` implements the type of
- * typenames that couldn't be resolved.
- *
- * This class behaves like DynamicTypeImpl in almost every respect, to reduce
- * cascading errors.
- */
-class UndefinedTypeImpl extends TypeImpl {
-  /**
-   * The unique instance of this class.
-   */
-  static UndefinedTypeImpl _INSTANCE = new UndefinedTypeImpl._();
-
-  /**
-   * Return the unique instance of this class.
-   */
-  static UndefinedTypeImpl get instance => _INSTANCE;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  UndefinedTypeImpl._()
-      : super(DynamicElementImpl.instance, Keyword.DYNAMIC.syntax);
-
-  @override
-  int get hashCode => 1;
-
-  @override
-  bool get isDynamic => true;
-
-  @override
-  bool get isUndefined => true;
-
-  @override
-  bool operator ==(Object object) => identical(object, this);
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    // T is S
-    if (identical(this, type)) {
-      return true;
-    }
-    // else
-    return withDynamic;
-  }
-
-  @override
-  bool isSubtypeOf(DartType type) => true;
-
-  @override
-  bool isSupertypeOf(DartType type) => true;
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    int length = parameterTypes.length;
-    for (int i = 0; i < length; i++) {
-      if (parameterTypes[i] == this) {
-        return argumentTypes[i];
-      }
-    }
-    return this;
-  }
-}
-
-/**
- * An element included into a library using some URI.
- */
-abstract class UriReferencedElement implements Element {
-  /**
-   * Return the URI that is used to include this element into the enclosing
-   * library, or `null` if this is the defining compilation unit of a library.
-   */
-  String get uri;
-
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this node's URI, or `-1` for synthetic import.
-   */
-  int get uriEnd;
-
-  /**
-   * Return the offset of the URI in the file, or `-1` if this element is
-   * synthetic.
-   */
-  int get uriOffset;
-}
-
-/**
- * A concrete implementation of a [UriReferencedElement].
- */
-abstract class UriReferencedElementImpl extends ElementImpl
-    implements UriReferencedElement {
-  /**
-   * The offset of the URI in the file, may be `-1` if synthetic.
-   */
-  int uriOffset = -1;
-
-  /**
-   * The offset of the character immediately following the last character of
-   * this node's URI, may be `-1` if synthetic.
-   */
-  int uriEnd = -1;
-
-  /**
-   * The URI that is specified by this directive.
-   */
-  String uri;
-
-  /**
-   * Initialize a newly created import element to heve the given [name] and
-   * [offset]. The offset may be `-1` if the element is synthetic.
-   */
-  UriReferencedElementImpl(String name, int offset) : super(name, offset);
-}
-
-/**
- * A variable. There are concrete subclasses for different kinds of variables.
- */
-abstract class VariableElement implements Element, ConstantEvaluationTarget {
-  /**
-   * An empty list of variable elements.
-   */
-  static const List<VariableElement> EMPTY_LIST = const <VariableElement>[];
-
-  /**
-   * Return a representation of the value of this variable.
-   *
-   * Return `null` if either this variable was not declared with the 'const'
-   * modifier or if the value of this variable could not be computed because of
-   * errors.
-   */
-  DartObject get constantValue;
-
-  /**
-   * Return `true` if this variable element did not have an explicit type
-   * specified for it.
-   */
-  bool get hasImplicitType;
-
-  /**
-   * Return a synthetic function representing this variable's initializer, or
-   * `null` if this variable does not have an initializer. The function will
-   * have no parameters. The return type of the function will be the
-   * compile-time type of the initialization expression.
-   */
-  FunctionElement get initializer;
-
-  /**
-   * Return `true` if this variable was declared with the 'const' modifier.
-   */
-  bool get isConst;
-
-  /**
-   * Return `true` if this variable was declared with the 'final' modifier.
-   * Variables that are declared with the 'const' modifier will return `false`
-   * even though they are implicitly final.
-   */
-  bool get isFinal;
-
-  /**
-   * Return `true` if this variable is potentially mutated somewhere in a
-   * closure. This information is only available for local variables (including
-   * parameters) and only after the compilation unit containing the variable has
-   * been resolved.
-   */
-  bool get isPotentiallyMutatedInClosure;
-
-  /**
-   * Return `true` if this variable is potentially mutated somewhere in its
-   * scope. This information is only available for local variables (including
-   * parameters) and only after the compilation unit containing the variable has
-   * been resolved.
-   */
-  bool get isPotentiallyMutatedInScope;
-
-  /**
-   * Return `true` if this element is a static variable, as per section 8 of the
-   * Dart Language Specification:
-   *
-   * > A static variable is a variable that is not associated with a particular
-   * > instance, but rather with an entire library or class. Static variables
-   * > include library variables and class variables. Class variables are
-   * > variables whose declaration is immediately nested inside a class
-   * > declaration and includes the modifier static. A library variable is
-   * > implicitly static.
-   */
-  bool get isStatic;
-
-  /**
-   * Return the declared type of this variable, or `null` if the variable did
-   * not have a declared type (such as if it was declared using the keyword
-   * 'var').
-   */
-  DartType get type;
-}
-
-/**
- * A concrete implementation of a [VariableElement].
- */
-abstract class VariableElementImpl extends ElementImpl
-    implements VariableElement {
-  /**
-   * An empty list of variable elements.
-   */
-  @deprecated // Use VariableElement.EMPTY_LIST
-  static const List<VariableElement> EMPTY_ARRAY = const <VariableElement>[];
-
-  /**
-   * The declared type of this variable.
-   */
-  DartType type;
-
-  /**
-   * A synthetic function representing this variable's initializer, or `null` if
-   * this variable does not have an initializer.
-   */
-  FunctionElement _initializer;
-
-  /**
-   * Initialize a newly created variable element to have the given [name] and
-   * [offset].
-   */
-  VariableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created variable element to have the given [name].
-   */
-  VariableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this variable is const.
-   */
-  void set const3(bool isConst) {
-    setModifier(Modifier.CONST, isConst);
-  }
-
-  @override
-  DartObject get constantValue => null;
-
-  /**
-   * If this element represents a constant variable, and it has an initializer,
-   * a copy of the initializer for the constant.  Otherwise `null`.
-   *
-   * Note that in correct Dart code, all constant variables must have
-   * initializers.  However, analyzer also needs to handle incorrect Dart code,
-   * in which case there might be some constant variables that lack
-   * initializers.
-   */
-  Expression get constantInitializer => null;
-
-  /**
-   * Return the result of evaluating this variable's initializer as a
-   * compile-time constant expression, or `null` if this variable is not a
-   * 'const' variable, if it does not have an initializer, or if the compilation
-   * unit containing the variable has not been resolved.
-   */
-  EvaluationResultImpl get evaluationResult => null;
-
-  /**
-   * Set the result of evaluating this variable's initializer as a compile-time
-   * constant expression to the given [result].
-   */
-  void set evaluationResult(EvaluationResultImpl result) {
-    throw new IllegalStateException(
-        "Invalid attempt to set a compile-time constant result");
-  }
-
-  /**
-   * Set whether this variable is final.
-   */
-  void set final2(bool isFinal) {
-    setModifier(Modifier.FINAL, isFinal);
-  }
-
-  @override
-  bool get hasImplicitType => hasModifier(Modifier.IMPLICIT_TYPE);
-
-  /**
-   * Set whether this variable element has an implicit type.
-   */
-  void set hasImplicitType(bool hasImplicitType) {
-    setModifier(Modifier.IMPLICIT_TYPE, hasImplicitType);
-  }
-
-  @override
-  FunctionElement get initializer => _initializer;
-
-  /**
-   * Set the function representing this variable's initializer to the given
-   * [function].
-   */
-  void set initializer(FunctionElement function) {
-    if (function != null) {
-      (function as FunctionElementImpl).enclosingElement = this;
-    }
-    this._initializer = function;
-  }
-
-  @override
-  bool get isConst => hasModifier(Modifier.CONST);
-
-  @override
-  bool get isFinal => hasModifier(Modifier.FINAL);
-
-  @override
-  bool get isPotentiallyMutatedInClosure => false;
-
-  @override
-  bool get isPotentiallyMutatedInScope => false;
-
-  @override
-  bool get isStatic => hasModifier(Modifier.STATIC);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(type);
-    buffer.write(" ");
-    buffer.write(displayName);
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(_initializer, visitor);
-  }
-}
-
-/**
- * A variable element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-abstract class VariableMember extends Member implements VariableElement {
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  VariableMember(VariableElement baseElement, ParameterizedType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  VariableElement get baseElement => super.baseElement as VariableElement;
-
-  @override
-  DartObject get constantValue => baseElement.constantValue;
-
-  @override
-  bool get hasImplicitType => baseElement.hasImplicitType;
-
-  @override
-  FunctionElement get initializer {
-    //
-    // Elements within this element should have type parameters substituted,
-    // just like this element.
-    //
-    throw new UnsupportedOperationException();
-    //    return getBaseElement().getInitializer();
-  }
-
-  @override
-  bool get isConst => baseElement.isConst;
-
-  @override
-  bool get isFinal => baseElement.isFinal;
-
-  @override
-  bool get isPotentiallyMutatedInClosure =>
-      baseElement.isPotentiallyMutatedInClosure;
-
-  @override
-  bool get isPotentiallyMutatedInScope =>
-      baseElement.isPotentiallyMutatedInScope;
-
-  @override
-  bool get isStatic => baseElement.isStatic;
-
-  @override
-  DartType get type => substituteFor(baseElement.type);
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // TODO(brianwilkerson) We need to finish implementing the accessors used
-    // below so that we can safely invoke them.
-    super.visitChildren(visitor);
-    safelyVisitChild(baseElement.initializer, visitor);
-  }
-}
-
-/**
- * The type `void`.
- */
-abstract class VoidType implements DartType {
-  @override
-  VoidType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes);
-}
-
-/**
- * A concrete implementation of a [VoidType].
- */
-class VoidTypeImpl extends TypeImpl implements VoidType {
-  /**
-   * The unique instance of this class.
-   */
-  static VoidTypeImpl _INSTANCE = new VoidTypeImpl();
-
-  /**
-   * Return the unique instance of this class.
-   */
-  static VoidTypeImpl get instance => _INSTANCE;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  VoidTypeImpl() : super(null, Keyword.VOID.syntax);
-
-  @override
-  int get hashCode => 2;
-
-  @override
-  bool get isVoid => true;
-
-  @override
-  bool operator ==(Object object) => identical(object, this);
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-          [bool withDynamic = false, Set<Element> visitedElements]) =>
-      isSubtypeOf(type);
-
-  @override
-  bool isSubtypeOf(DartType type) {
-    // The only subtype relations that pertain to void are therefore:
-    // void <: void (by reflexivity)
-    // bottom <: void (as bottom is a subtype of all types).
-    // void <: dynamic (as dynamic is a supertype of all types)
-    return identical(type, this) || type.isDynamic;
-  }
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  VoidTypeImpl substitute2(
-          List<DartType> argumentTypes, List<DartType> parameterTypes,
-          [List<FunctionTypeAliasElement> prune]) =>
-      this;
-}
-
-/**
- * A visitor that visit all the elements recursively and fill the given [map].
- */
-class _BuildOffsetToElementMap extends GeneralizingElementVisitor {
-  final Map<int, Element> map;
-
-  _BuildOffsetToElementMap(this.map);
-
-  @override
-  void visitElement(Element element) {
-    int offset = element.nameOffset;
-    if (offset != -1) {
-      map[offset] = element;
-    }
-    super.visitElement(element);
-  }
-}
+export 'package:analyzer/dart/element/element.dart';
+export 'package:analyzer/dart/element/type.dart';
+export 'package:analyzer/dart/element/visitor.dart';
+export 'package:analyzer/src/dart/element/element.dart';
+export 'package:analyzer/src/dart/element/member.dart';
+export 'package:analyzer/src/dart/element/type.dart';
diff --git a/pkg/analyzer/lib/src/generated/element_handle.dart b/pkg/analyzer/lib/src/generated/element_handle.dart
index f496602..0a29cfb 100644
--- a/pkg/analyzer/lib/src/generated/element_handle.dart
+++ b/pkg/analyzer/lib/src/generated/element_handle.dart
@@ -2,13 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.element_handle;
+library analyzer.src.generated.element_handle;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -23,7 +24,9 @@
    *
    * @param element the element being represented
    */
-  ClassElementHandle(ClassElement element) : super(element);
+  ClassElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   List<PropertyAccessorElement> get accessors => actualElement.accessors;
@@ -68,10 +71,6 @@
   bool get isProxy => actualElement.isProxy;
 
   @override
-  @deprecated
-  bool get isTypedef => actualElement.isMixinApplication;
-
-  @override
   bool get isValidMixin => actualElement.isValidMixin;
 
   @override
@@ -169,7 +168,9 @@
    *
    * @param element the element being represented
    */
-  CompilationUnitElementHandle(CompilationUnitElement element) : super(element);
+  CompilationUnitElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   List<PropertyAccessorElement> get accessors => actualElement.accessors;
@@ -243,7 +244,9 @@
    *
    * @param element the element being represented
    */
-  ConstructorElementHandle(ConstructorElement element) : super(element);
+  ConstructorElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ConstructorElement get actualElement =>
@@ -289,32 +292,29 @@
   final int id = 0;
 
   /**
-   * The context in which the element is defined.
+   * The [ElementResynthesizer] which will be used to resynthesize elements on
+   * demand.
    */
-  AnalysisContext _context;
+  final ElementResynthesizer _resynthesizer;
 
   /**
    * The location of this element, used to reconstitute the element if it has been garbage
    * collected.
    */
-  ElementLocation _location;
+  final ElementLocation _location;
 
   /**
    * A reference to the element being referenced by this handle, or `null` if the element has
    * been garbage collected.
    */
-  WeakReference<Element> _elementReference;
+  Element _elementReference;
 
   /**
-   * Initialize a newly created element handle to represent the given element.
-   *
-   * @param element the element being represented
+   * Initialize a newly created element handle to represent the element at the
+   * given [_location].  [_resynthesizer] will be used to resynthesize the
+   * element when needed.
    */
-  ElementHandle(Element element) {
-    _context = element.context;
-    _location = element.location;
-    _elementReference = new WeakReference<Element>(element);
-  }
+  ElementHandle(this._resynthesizer, this._location);
 
   /**
    * Return the element being represented by this handle, reconstituting the element if the
@@ -323,24 +323,26 @@
    * @return the element being represented by this handle
    */
   Element get actualElement {
-    Element element = _elementReference.get();
-    if (element == null) {
-      element = _context.getElement(_location);
-      _elementReference = new WeakReference<Element>(element);
+    if (_elementReference == null) {
+      _elementReference = _resynthesizer.getElement(_location);
     }
-    return element;
+    return _elementReference;
   }
 
   @override
-  AnalysisContext get context => _context;
+  AnalysisContext get context => _resynthesizer.context;
 
   @override
   String get displayName => actualElement.displayName;
 
+  @deprecated
   @override
   SourceRange get docRange => actualElement.docRange;
 
   @override
+  String get documentationComment => actualElement.documentationComment;
+
+  @override
   Element get enclosingElement => actualElement.enclosingElement;
 
   @override
@@ -380,10 +382,6 @@
   @override
   int get nameOffset => actualElement.nameOffset;
 
-  @deprecated
-  @override
-  AstNode get node => computeNode();
-
   @override
   Source get source => actualElement.source;
 
@@ -398,8 +396,7 @@
   accept(ElementVisitor visitor) => actualElement.accept(visitor);
 
   @override
-  String computeDocumentationComment() =>
-      actualElement.computeDocumentationComment();
+  String computeDocumentationComment() => documentationComment;
 
   @override
   AstNode computeNode() => actualElement.computeNode();
@@ -420,82 +417,19 @@
   void visitChildren(ElementVisitor visitor) {
     actualElement.visitChildren(visitor);
   }
+}
 
-  /**
-   * Return a handle on the given element. If the element is already a handle, then it will be
-   * returned directly, otherwise a handle of the appropriate class will be constructed.
-   *
-   * @param element the element for which a handle is to be constructed
-   * @return a handle on the given element
-   */
-  static Element forElement(Element element) {
-    if (element is ElementHandle) {
-      return element;
-    }
-    while (true) {
-      if (element.kind == ElementKind.CLASS) {
-        return new ClassElementHandle(element as ClassElement);
-      } else if (element.kind == ElementKind.COMPILATION_UNIT) {
-        return new CompilationUnitElementHandle(
-            element as CompilationUnitElement);
-      } else if (element.kind == ElementKind.CONSTRUCTOR) {
-        return new ConstructorElementHandle(element as ConstructorElement);
-      } else if (element.kind == ElementKind.EXPORT) {
-        return new ExportElementHandle(element as ExportElement);
-      } else if (element.kind == ElementKind.FIELD) {
-        return new FieldElementHandle(element as FieldElement);
-      } else if (element.kind == ElementKind.FUNCTION) {
-        return new FunctionElementHandle(element as FunctionElement);
-      } else if (element.kind == ElementKind.GETTER) {
-        return new PropertyAccessorElementHandle(
-            element as PropertyAccessorElement);
-      } else if (element.kind == ElementKind.IMPORT) {
-        return new ImportElementHandle(element as ImportElement);
-      } else if (element.kind == ElementKind.LABEL) {
-        return new LabelElementHandle(element as LabelElement);
-      } else if (element.kind == ElementKind.LIBRARY) {
-        return new LibraryElementHandle(element as LibraryElement);
-      } else if (element.kind == ElementKind.LOCAL_VARIABLE) {
-        return new LocalVariableElementHandle(element as LocalVariableElement);
-      } else if (element.kind == ElementKind.METHOD) {
-        return new MethodElementHandle(element as MethodElement);
-      } else if (element.kind == ElementKind.PARAMETER) {
-        return new ParameterElementHandle(element as ParameterElement);
-      } else if (element.kind == ElementKind.PREFIX) {
-        return new PrefixElementHandle(element as PrefixElement);
-      } else if (element.kind == ElementKind.SETTER) {
-        return new PropertyAccessorElementHandle(
-            element as PropertyAccessorElement);
-      } else if (element.kind == ElementKind.TOP_LEVEL_VARIABLE) {
-        return new TopLevelVariableElementHandle(
-            element as TopLevelVariableElement);
-      } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
-        return new FunctionTypeAliasElementHandle(
-            element as FunctionTypeAliasElement);
-      } else if (element.kind == ElementKind.TYPE_PARAMETER) {
-        return new TypeParameterElementHandle(element as TypeParameterElement);
-      } else {
-        throw new UnsupportedOperationException();
-      }
-      break;
-    }
-  }
+/**
+ * Interface which allows an [Element] handle to be resynthesized based on an
+ * [ElementLocation].  The concrete classes implementing element handles use
+ * this interface to retrieve the underlying elements when queried.
+ */
+abstract class ElementResynthesizer {
+  final AnalysisContext context;
 
-  /**
-   * Return an array of the same size as the given array where each element of the returned array is
-   * a handle for the corresponding element of the given array.
-   *
-   * @param elements the elements for which handles are to be created
-   * @return an array of handles to the given elements
-   */
-  static List<Element> forElements(List<Element> elements) {
-    int length = elements.length;
-    List<Element> handles = new List<Element>.from(elements);
-    for (int i = 0; i < length; i++) {
-      handles[i] = forElement(elements[i]);
-    }
-    return handles;
-  }
+  ElementResynthesizer(this.context);
+
+  Element getElement(ElementLocation location);
 }
 
 /**
@@ -509,7 +443,9 @@
    *
    * @param element the element being represented
    */
-  ExecutableElementHandle(ExecutableElement element) : super(element);
+  ExecutableElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ExecutableElement get actualElement =>
@@ -571,7 +507,9 @@
    *
    * @param element the element being represented
    */
-  ExportElementHandle(ExportElement element) : super(element);
+  ExportElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ExportElement get actualElement => super.actualElement as ExportElement;
@@ -605,7 +543,9 @@
    *
    * @param element the element being represented
    */
-  FieldElementHandle(FieldElement element) : super(element);
+  FieldElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   FieldElement get actualElement => super.actualElement as FieldElement;
@@ -634,7 +574,9 @@
    *
    * @param element the element being represented
    */
-  FunctionElementHandle(FunctionElement element) : super(element);
+  FunctionElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   FunctionElement get actualElement => super.actualElement as FunctionElement;
@@ -663,8 +605,9 @@
    *
    * @param element the element being represented
    */
-  FunctionTypeAliasElementHandle(FunctionTypeAliasElement element)
-      : super(element);
+  FunctionTypeAliasElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   FunctionTypeAliasElement get actualElement =>
@@ -703,7 +646,9 @@
    *
    * @param element the element being represented
    */
-  ImportElementHandle(ImportElement element) : super(element);
+  ImportElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ImportElement get actualElement => super.actualElement as ImportElement;
@@ -745,7 +690,9 @@
    *
    * @param element the element being represented
    */
-  LabelElementHandle(LabelElement element) : super(element);
+  LabelElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ExecutableElement get enclosingElement =>
@@ -765,7 +712,9 @@
    *
    * @param element the element being represented
    */
-  LibraryElementHandle(LibraryElement element) : super(element);
+  LibraryElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   LibraryElement get actualElement => super.actualElement as LibraryElement;
@@ -793,6 +742,9 @@
   bool get hasLoadLibraryFunction => actualElement.hasLoadLibraryFunction;
 
   @override
+  String get identifier => location.components.last;
+
+  @override
   List<LibraryElement> get importedLibraries => actualElement.importedLibraries;
 
   @override
@@ -850,7 +802,9 @@
    *
    * @param element the element being represented
    */
-  LocalVariableElementHandle(LocalVariableElement element) : super(element);
+  LocalVariableElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   LocalVariableElement get actualElement =>
@@ -876,7 +830,9 @@
    *
    * @param element the element being represented
    */
-  MethodElementHandle(MethodElement element) : super(element);
+  MethodElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   MethodElement get actualElement => super.actualElement as MethodElement;
@@ -906,7 +862,9 @@
    *
    * @param element the element being represented
    */
-  ParameterElementHandle(ParameterElement element) : super(element);
+  ParameterElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ParameterElement get actualElement => super.actualElement as ParameterElement;
@@ -942,7 +900,9 @@
    *
    * @param element the element being represented
    */
-  PrefixElementHandle(PrefixElement element) : super(element);
+  PrefixElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   PrefixElement get actualElement => super.actualElement as PrefixElement;
@@ -969,8 +929,9 @@
    *
    * @param element the element being represented
    */
-  PropertyAccessorElementHandle(PropertyAccessorElement element)
-      : super(element);
+  PropertyAccessorElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   PropertyAccessorElement get actualElement =>
@@ -1014,8 +975,9 @@
    *
    * @param element the element being represented
    */
-  PropertyInducingElementHandle(PropertyInducingElement element)
-      : super(element);
+  PropertyInducingElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   PropertyInducingElement get actualElement =>
@@ -1042,8 +1004,9 @@
    *
    * @param element the element being represented
    */
-  TopLevelVariableElementHandle(TopLevelVariableElement element)
-      : super(element);
+  TopLevelVariableElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
@@ -1060,7 +1023,9 @@
    *
    * @param element the element being represented
    */
-  TypeParameterElementHandle(TypeParameterElement element) : super(element);
+  TypeParameterElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   TypeParameterElement get actualElement =>
@@ -1087,7 +1052,9 @@
    *
    * @param element the element being represented
    */
-  VariableElementHandle(VariableElement element) : super(element);
+  VariableElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   VariableElement get actualElement => super.actualElement as VariableElement;
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index ffe623b..368da2a 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -2,17 +2,19 @@
 // for 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 engine.resolver.element_resolver;
+library analyzer.src.generated.element_resolver;
 
 import 'dart:collection';
 
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart';
-import 'error.dart';
-import 'resolver.dart';
-import 'scanner.dart' as sc;
-import 'utilities_dart.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' as sc;
 
 /**
  * An object used by instances of [ResolverVisitor] to resolve references within
@@ -102,7 +104,7 @@
   /**
    * The type representing the type 'type'.
    */
-  DartType _typeType;
+  InterfaceType _typeType;
 
   /**
    * A utility class for the resolver to answer the question of "what are my
@@ -259,8 +261,8 @@
       if (element == null) {
 //        resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, prefix, prefix.getName());
       } else {
+        prefix.staticElement = element;
         if (element is PrefixElement) {
-          prefix.staticElement = element;
           // TODO(brianwilkerson) Report this error?
           element = _resolver.nameScope.lookup(identifier, _definingLibrary);
           name.staticElement = element;
@@ -275,7 +277,6 @@
         } else if (library != _definingLibrary) {
           // TODO(brianwilkerson) Report this error.
         }
-        name.staticElement = element;
         if (node.newKeyword == null) {
           if (element is ClassElement) {
             Element memberElement =
@@ -425,17 +426,26 @@
 
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    // TODO(brianwilkerson) Can we ever resolve the function being invoked?
-    Expression expression = node.function;
-    if (expression is FunctionExpression) {
-      FunctionExpression functionExpression = expression;
-      ExecutableElement functionElement = functionExpression.element;
-      ArgumentList argumentList = node.argumentList;
-      List<ParameterElement> parameters =
-          _resolveArgumentsToFunction(false, argumentList, functionElement);
-      if (parameters != null) {
-        argumentList.correspondingStaticParameters = parameters;
-      }
+    Expression function = node.function;
+    DartType staticInvokeType =
+        _resolveGenericMethod(function.staticType, node.typeArguments, node);
+    DartType propagatedInvokeType = _resolveGenericMethod(
+        function.propagatedType, node.typeArguments, node);
+
+    node.staticInvokeType = staticInvokeType;
+    node.propagatedInvokeType =
+        _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
+
+    List<ParameterElement> parameters =
+        _computeCorrespondingParameters(node.argumentList, staticInvokeType);
+    if (parameters != null) {
+      node.argumentList.correspondingStaticParameters = parameters;
+    }
+
+    parameters = _computeCorrespondingParameters(
+        node.argumentList, propagatedInvokeType);
+    if (parameters != null) {
+      node.argumentList.correspondingPropagatedParameters = parameters;
     }
     return null;
   }
@@ -594,8 +604,6 @@
     }
     Element staticElement;
     Element propagatedElement;
-    DartType staticType = null;
-    DartType propagatedType = null;
     if (target == null) {
       staticElement = _resolveInvokedElement(methodName);
       propagatedElement = null;
@@ -611,8 +619,6 @@
       methodName.staticElement = importedLibrary.loadLibraryFunction;
       return null;
     } else {
-      staticType = _getStaticType(target);
-      propagatedType = _getPropagatedType(target);
       //
       // If this method invocation is of the form 'C.m' where 'C' is a class,
       // then we don't call resolveInvokedElement(...) which walks up the class
@@ -622,33 +628,61 @@
       bool isConditional = node.operator.type == sc.TokenType.QUESTION_PERIOD;
       ClassElementImpl typeReference = getTypeReference(target);
       if (typeReference != null) {
-        staticElement =
-            propagatedElement = _resolveElement(typeReference, methodName);
+        if (node.isCascaded) {
+          typeReference = _typeType.element;
+        }
+        staticElement = _resolveElement(typeReference, methodName);
       } else {
+        DartType staticType = _getStaticType(target);
+        DartType propagatedType = _getPropagatedType(target);
         staticElement = _resolveInvokedElementWithTarget(
             target, staticType, methodName, isConditional);
-        propagatedElement = _resolveInvokedElementWithTarget(
-            target, propagatedType, methodName, isConditional);
+        // If we have propagated type information use it (since it should
+        // not be redundant with the staticType).  Otherwise, don't produce
+        // a propagatedElement which duplicates the staticElement.
+        if (propagatedType is InterfaceType) {
+          propagatedElement = _resolveInvokedElementWithTarget(
+              target, propagatedType, methodName, isConditional);
+        }
       }
     }
+
     staticElement = _convertSetterToGetter(staticElement);
     propagatedElement = _convertSetterToGetter(propagatedElement);
+
+    DartType staticInvokeType = _computeMethodInvokeType(node, staticElement);
+    DartType propagatedInvokeType =
+        _computeMethodInvokeType(node, propagatedElement);
+
     //
     // Record the results.
     //
     methodName.staticElement = staticElement;
     methodName.propagatedElement = propagatedElement;
+
+    node.staticInvokeType = staticInvokeType;
+    //
+    // Store the propagated invoke type if it's more specific than the static
+    // type.
+    //
+    // We still need to record the propagated parameter elements however,
+    // as they are used in propagatedType downwards inference of lambda
+    // parameters. So we don't want to clear the propagatedInvokeType variable.
+    //
+    node.propagatedInvokeType =
+        _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
+
     ArgumentList argumentList = node.argumentList;
-    if (staticElement != null) {
+    if (staticInvokeType != null) {
       List<ParameterElement> parameters =
-          _computeCorrespondingParameters(argumentList, staticElement);
+          _computeCorrespondingParameters(argumentList, staticInvokeType);
       if (parameters != null) {
         argumentList.correspondingStaticParameters = parameters;
       }
     }
-    if (propagatedElement != null) {
+    if (propagatedInvokeType != null) {
       List<ParameterElement> parameters =
-          _computeCorrespondingParameters(argumentList, propagatedElement);
+          _computeCorrespondingParameters(argumentList, propagatedInvokeType);
       if (parameters != null) {
         argumentList.correspondingPropagatedParameters = parameters;
       }
@@ -729,6 +763,21 @@
 //          resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
           return null;
         }
+        if (!node.isCascaded) {
+          ClassElementImpl typeReference = getTypeReference(target);
+          if (typeReference != null) {
+            ConstructorElement constructor =
+                typeReference.getNamedConstructor(methodName.name);
+            if (constructor != null) {
+              _recordUndefinedNode(
+                  typeReference,
+                  StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR,
+                  methodName,
+                  [methodName.name, typeReference.name]);
+              return null;
+            }
+          }
+        }
         targetTypeName = targetType == null ? null : targetType.displayName;
         ErrorCode proxyErrorCode = (generatedWithTypePropagation
             ? HintCode.UNDEFINED_METHOD
@@ -866,7 +915,7 @@
     // Otherwise, the prefix is really an expression that happens to be a simple
     // identifier and this is really equivalent to a property access node.
     //
-    _resolvePropertyAccess(prefix, identifier);
+    _resolvePropertyAccess(prefix, identifier, false);
     return null;
   }
 
@@ -922,7 +971,7 @@
       return null;
     }
     SimpleIdentifier propertyName = node.propertyName;
-    _resolvePropertyAccess(target, propertyName);
+    _resolvePropertyAccess(target, propertyName, node.isCascaded);
     return null;
   }
 
@@ -979,6 +1028,10 @@
     if (node.inDeclarationContext()) {
       return null;
     }
+    if (node.staticElement is LocalVariableElement ||
+        node.staticElement is ParameterElement) {
+      return null;
+    }
     AstNode parent = node.parent;
     if (parent is FieldFormalParameter) {
       return null;
@@ -1269,48 +1322,44 @@
    * arguments, or `null` if no correspondence could be computed.
    */
   List<ParameterElement> _computeCorrespondingParameters(
-      ArgumentList argumentList, Element element) {
-    if (element is PropertyAccessorElement) {
-      //
-      // This is an invocation of the call method defined on the value returned
-      // by the getter.
-      //
-      FunctionType getterType = element.type;
-      if (getterType != null) {
-        DartType getterReturnType = getterType.returnType;
-        if (getterReturnType is InterfaceType) {
-          MethodElement callMethod = getterReturnType.lookUpMethod(
-              FunctionElement.CALL_METHOD_NAME, _definingLibrary);
-          if (callMethod != null) {
-            return _resolveArgumentsToFunction(false, argumentList, callMethod);
-          }
-        } else if (getterReturnType is FunctionType) {
-          List<ParameterElement> parameters = getterReturnType.parameters;
-          return _resolveArgumentsToParameters(false, argumentList, parameters);
-        }
+      ArgumentList argumentList, DartType type) {
+    if (type is InterfaceType) {
+      MethodElement callMethod =
+          type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
+      if (callMethod != null) {
+        return _resolveArgumentsToFunction(false, argumentList, callMethod);
       }
-    } else if (element is ExecutableElement) {
-      return _resolveArgumentsToFunction(false, argumentList, element);
-    } else if (element is VariableElement) {
-      VariableElement variable = element;
-      DartType type = _promoteManager.getStaticType(variable);
-      if (type is FunctionType) {
-        FunctionType functionType = type;
-        List<ParameterElement> parameters = functionType.parameters;
-        return _resolveArgumentsToParameters(false, argumentList, parameters);
-      } else if (type is InterfaceType) {
-        // "call" invocation
-        MethodElement callMethod = type.lookUpMethod(
-            FunctionElement.CALL_METHOD_NAME, _definingLibrary);
-        if (callMethod != null) {
-          List<ParameterElement> parameters = callMethod.parameters;
-          return _resolveArgumentsToParameters(false, argumentList, parameters);
-        }
-      }
+    } else if (type is FunctionType) {
+      return _resolveArgumentsToParameters(
+          false, argumentList, type.parameters);
     }
     return null;
   }
 
+  DartType _computeMethodInvokeType(MethodInvocation node, Element element) {
+    if (element == null) {
+      // TODO(jmesserly): should we return `dynamic` in this case?
+      // Otherwise we have to guard against `null` every time we use
+      // `staticInvokeType`.
+      // If we do return `dynamic` we need to be careful that this doesn't
+      // adversely affect propagatedType code path. But it shouldn't because
+      // we'll discard `dynamic` anyway (see _propagatedInvokeTypeIfBetter).
+      return null;
+    }
+
+    DartType invokeType;
+    if (element is PropertyAccessorElement) {
+      invokeType = element.returnType;
+    } else if (element is ExecutableElement) {
+      invokeType = element.type;
+    } else if (element is VariableElement) {
+      invokeType = _promoteManager.getStaticType(element);
+    }
+
+    return _resolveGenericMethod(
+        invokeType, node.typeArguments, node.methodName);
+  }
+
   /**
    * If the given [element] is a setter, return the getter associated with it.
    * Otherwise, return the element unchanged.
@@ -1573,76 +1622,13 @@
       Expression target, DartType type, String getterName) {
     type = _resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      PropertyAccessorElement accessor;
-      if (target is SuperExpression) {
-        accessor = interfaceType.lookUpGetterInSuperclass(
-            getterName, _definingLibrary);
-      } else {
-        accessor = interfaceType.lookUpGetter(getterName, _definingLibrary);
-      }
-      if (accessor != null) {
-        return accessor;
-      }
-      return _lookUpGetterInInterfaces(
-          interfaceType, false, getterName, new HashSet<ClassElement>());
+      return type.lookUpInheritedGetter(getterName,
+          library: _definingLibrary, thisType: target is! SuperExpression);
     }
     return null;
   }
 
   /**
-   * Look up the getter with the given [getterName] in the interfaces
-   * implemented by the given [targetType], either directly or indirectly.
-   * Return the element representing the getter that was found, or `null` if
-   * there is no getter with the given name. The flag [includeTargetType] should
-   * be `true` if the search should include the target type. The
-   * [visitedInterfaces] is a set containing all of the interfaces that have
-   * been examined, used to prevent infinite recursion and to optimize the
-   * search.
-   */
-  PropertyAccessorElement _lookUpGetterInInterfaces(
-      InterfaceType targetType,
-      bool includeTargetType,
-      String getterName,
-      HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
-    // specification (titled "Inheritance and Overriding" under "Interfaces")
-    // describes a much more complex scheme for finding the inherited member.
-    // We need to follow that scheme. The code below should cover the 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      PropertyAccessorElement getter = targetType.getGetter(getterName);
-      if (getter != null && getter.isAccessibleIn(_definingLibrary)) {
-        return getter;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      PropertyAccessorElement getter = _lookUpGetterInInterfaces(
-          interfaceType, true, getterName, visitedInterfaces);
-      if (getter != null) {
-        return getter;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins.reversed) {
-      PropertyAccessorElement getter = _lookUpGetterInInterfaces(
-          mixinType, true, getterName, visitedInterfaces);
-      if (getter != null) {
-        return getter;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpGetterInInterfaces(
-        superclass, true, getterName, visitedInterfaces);
-  }
-
-  /**
    * Look up the method or getter with the given [memberName] in the given
    * [type]. Return the element representing the method or getter that was
    * found, or `null` if there is no method or getter with the given name.
@@ -1650,79 +1636,13 @@
   ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) {
     type = _resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      ExecutableElement member =
-          interfaceType.lookUpMethod(memberName, _definingLibrary);
-      if (member != null) {
-        return member;
-      }
-      member = interfaceType.lookUpGetter(memberName, _definingLibrary);
-      if (member != null) {
-        return member;
-      }
-      return _lookUpGetterOrMethodInInterfaces(
-          interfaceType, false, memberName, new HashSet<ClassElement>());
+      return type.lookUpInheritedGetterOrMethod(memberName,
+          library: _definingLibrary);
     }
     return null;
   }
 
   /**
-   * Look up the method or getter with the given [memberName] in the interfaces
-   * implemented by the given [targetType], either directly or indirectly.
-   * Return the element representing the method or getter that was found, or
-   * `null` if there is no method or getter with the given name. The flag
-   * [includeTargetType] should be `true` if the search should include the
-   * target type. The [visitedInterfaces] is a set containing all of the
-   * interfaces that have been examined, used to prevent infinite recursion and
-   * to optimize the search.
-   */
-  ExecutableElement _lookUpGetterOrMethodInInterfaces(
-      InterfaceType targetType,
-      bool includeTargetType,
-      String memberName,
-      HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
-    // specification (titled "Inheritance and Overriding" under "Interfaces")
-    // describes a much more complex scheme for finding the inherited member.
-    // We need to follow that scheme. The code below should cover the 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      ExecutableElement member = targetType.getMethod(memberName);
-      if (member != null) {
-        return member;
-      }
-      member = targetType.getGetter(memberName);
-      if (member != null) {
-        return member;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      ExecutableElement member = _lookUpGetterOrMethodInInterfaces(
-          interfaceType, true, memberName, visitedInterfaces);
-      if (member != null) {
-        return member;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins.reversed) {
-      ExecutableElement member = _lookUpGetterOrMethodInInterfaces(
-          mixinType, true, memberName, visitedInterfaces);
-      if (member != null) {
-        return member;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpGetterOrMethodInInterfaces(
-        superclass, true, memberName, visitedInterfaces);
-  }
-
-  /**
    * Look up the method with the given [methodName] in the given [type]. Return
    * the element representing the method that was found, or `null` if there is
    * no method with the given name. The [target] is the target of the
@@ -1732,76 +1652,13 @@
       Expression target, DartType type, String methodName) {
     type = _resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      MethodElement method;
-      if (target is SuperExpression) {
-        method = interfaceType.lookUpMethodInSuperclass(
-            methodName, _definingLibrary);
-      } else {
-        method = interfaceType.lookUpMethod(methodName, _definingLibrary);
-      }
-      if (method != null) {
-        return method;
-      }
-      return _lookUpMethodInInterfaces(
-          interfaceType, false, methodName, new HashSet<ClassElement>());
+      return type.lookUpInheritedMethod(methodName,
+          library: _definingLibrary, thisType: target is! SuperExpression);
     }
     return null;
   }
 
   /**
-   * Look up the method with the given [methodName] in the interfaces
-   * implemented by the given [targetType], either directly or indirectly.
-   * Return the element representing the method that was found, or `null` if
-   * there is no method with the given name. The flag [includeTargetType] should
-   * be `true` if the search should include the target type. The
-   * [visitedInterfaces] is a set containing all of the interfaces that have
-   * been examined, used to prevent infinite recursion and to optimize the
-   * search.
-   */
-  MethodElement _lookUpMethodInInterfaces(
-      InterfaceType targetType,
-      bool includeTargetType,
-      String methodName,
-      HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
-    // specification (titled "Inheritance and Overriding" under "Interfaces")
-    // describes a much more complex scheme for finding the inherited member.
-    // We need to follow that scheme. The code below should cover the 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      MethodElement method = targetType.getMethod(methodName);
-      if (method != null && method.isAccessibleIn(_definingLibrary)) {
-        return method;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      MethodElement method = _lookUpMethodInInterfaces(
-          interfaceType, true, methodName, visitedInterfaces);
-      if (method != null) {
-        return method;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins.reversed) {
-      MethodElement method = _lookUpMethodInInterfaces(
-          mixinType, true, methodName, visitedInterfaces);
-      if (method != null) {
-        return method;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpMethodInInterfaces(
-        superclass, true, methodName, visitedInterfaces);
-  }
-
-  /**
    * Look up the setter with the given [setterName] in the given [type]. Return
    * the element representing the setter that was found, or `null` if there is
    * no setter with the given name. The [target] is the target of the
@@ -1811,77 +1668,13 @@
       Expression target, DartType type, String setterName) {
     type = _resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      PropertyAccessorElement accessor;
-      if (target is SuperExpression) {
-        accessor = interfaceType.lookUpSetterInSuperclass(
-            setterName, _definingLibrary);
-      } else {
-        accessor = interfaceType.lookUpSetter(setterName, _definingLibrary);
-      }
-      if (accessor != null) {
-        return accessor;
-      }
-      return _lookUpSetterInInterfaces(
-          interfaceType, false, setterName, new HashSet<ClassElement>());
+      return type.lookUpInheritedSetter(setterName,
+          library: _definingLibrary, thisType: target is! SuperExpression);
     }
     return null;
   }
 
   /**
-   * Look up the setter with the given [setterName] in the interfaces
-   * implemented by the given [targetType], either directly or indirectly.
-   * Return the element representing the setter that was found, or `null` if
-   * there is no setter with the given name. The [targetType] is the type in
-   * which the setter might be defined. The flag [includeTargetType] should be
-   * `true` if the search should include the target type. The
-   * [visitedInterfaces] is a set containing all of the interfaces that have
-   * been examined, used to prevent infinite recursion and to optimize the
-   * search.
-   */
-  PropertyAccessorElement _lookUpSetterInInterfaces(
-      InterfaceType targetType,
-      bool includeTargetType,
-      String setterName,
-      HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
-    // specification (titled "Inheritance and Overriding" under "Interfaces")
-    // describes a much more complex scheme for finding the inherited member.
-    // We need to follow that scheme. The code below should cover the 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      PropertyAccessorElement setter = targetType.getSetter(setterName);
-      if (setter != null && setter.isAccessibleIn(_definingLibrary)) {
-        return setter;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      PropertyAccessorElement setter = _lookUpSetterInInterfaces(
-          interfaceType, true, setterName, visitedInterfaces);
-      if (setter != null) {
-        return setter;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins.reversed) {
-      PropertyAccessorElement setter = _lookUpSetterInInterfaces(
-          mixinType, true, setterName, visitedInterfaces);
-      if (setter != null) {
-        return setter;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpSetterInInterfaces(
-        superclass, true, setterName, visitedInterfaces);
-  }
-
-  /**
    * Given some class [element], this method uses [_subtypeManager] to find the
    * set of all subtypes; the subtypes are then searched for a member (method,
    * getter, or setter), that has the given [memberName]. The flag [asMethod]
@@ -1947,6 +1740,24 @@
   }
 
   /**
+   * Determines if the [propagatedType] of the invoke is better (more specific)
+   * than the [staticType]. If so it will be returned, otherwise returns null.
+   */
+  // TODO(jmesserly): can we refactor Resolver.recordPropagatedTypeIfBetter to
+  // get some code sharing? Right now, this method is to support
+  // `staticInvokeType` and `propagatedInvokeType`, and the one in Resolver is
+  // for `staticType` and `propagatedType` on Expression.
+  DartType _propagatedInvokeTypeIfBetter(
+      DartType propagatedType, DartType staticType) {
+    if (propagatedType != null &&
+        (staticType == null || propagatedType.isMoreSpecificThan(staticType))) {
+      return propagatedType;
+    } else {
+      return null;
+    }
+  }
+
+  /**
    * Record that the given [node] is undefined, causing an error to be reported
    * if appropriate. The [declaringElement] is the element inside which no
    * declaration was found. If this element is a proxy, no error will be
@@ -2122,6 +1933,13 @@
       _resolver.reportErrorForNode(
           CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
     }
+    // no arguments
+    if (annotation.arguments != null) {
+      _resolver.reportErrorForNode(
+          CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS,
+          annotation.name,
+          [annotation.name]);
+    }
     // OK
     return;
   }
@@ -2130,102 +1948,35 @@
    * Given an [argumentList] and the [executableElement] that will be invoked
    * using those argument, compute the list of parameters that correspond to the
    * list of arguments. An error will be reported if any of the arguments cannot
-   * be matched to a parameter. The flag [reportError] should be `true` if a
+   * be matched to a parameter. The flag [reportAsError] should be `true` if a
    * compile-time error should be reported; or `false` if a compile-time warning
    * should be reported. Return the parameters that correspond to the arguments,
    * or `null` if no correspondence could be computed.
    */
-  List<ParameterElement> _resolveArgumentsToFunction(bool reportError,
+  List<ParameterElement> _resolveArgumentsToFunction(bool reportAsError,
       ArgumentList argumentList, ExecutableElement executableElement) {
     if (executableElement == null) {
       return null;
     }
     List<ParameterElement> parameters = executableElement.parameters;
-    return _resolveArgumentsToParameters(reportError, argumentList, parameters);
+    return _resolveArgumentsToParameters(
+        reportAsError, argumentList, parameters);
   }
 
   /**
    * Given an [argumentList] and the [parameters] related to the element that
    * will be invoked using those arguments, compute the list of parameters that
    * correspond to the list of arguments. An error will be reported if any of
-   * the arguments cannot be matched to a parameter. The flag [reportError]
+   * the arguments cannot be matched to a parameter. The flag [reportAsError]
    * should be `true` if a compile-time error should be reported; or `false` if
    * a compile-time warning should be reported. Return the parameters that
    * correspond to the arguments.
    */
-  List<ParameterElement> _resolveArgumentsToParameters(bool reportError,
+  List<ParameterElement> _resolveArgumentsToParameters(bool reportAsError,
       ArgumentList argumentList, List<ParameterElement> parameters) {
-    List<ParameterElement> requiredParameters = new List<ParameterElement>();
-    List<ParameterElement> positionalParameters = new List<ParameterElement>();
-    HashMap<String, ParameterElement> namedParameters =
-        new HashMap<String, ParameterElement>();
-    for (ParameterElement parameter in parameters) {
-      ParameterKind kind = parameter.parameterKind;
-      if (kind == ParameterKind.REQUIRED) {
-        requiredParameters.add(parameter);
-      } else if (kind == ParameterKind.POSITIONAL) {
-        positionalParameters.add(parameter);
-      } else {
-        namedParameters[parameter.name] = parameter;
-      }
-    }
-    List<ParameterElement> unnamedParameters =
-        new List<ParameterElement>.from(requiredParameters);
-    unnamedParameters.addAll(positionalParameters);
-    int unnamedParameterCount = unnamedParameters.length;
-    int unnamedIndex = 0;
-    NodeList<Expression> arguments = argumentList.arguments;
-    int argumentCount = arguments.length;
-    List<ParameterElement> resolvedParameters =
-        new List<ParameterElement>(argumentCount);
-    int positionalArgumentCount = 0;
-    HashSet<String> usedNames = new HashSet<String>();
-    bool noBlankArguments = true;
-    for (int i = 0; i < argumentCount; i++) {
-      Expression argument = arguments[i];
-      if (argument is NamedExpression) {
-        SimpleIdentifier nameNode = argument.name.label;
-        String name = nameNode.name;
-        ParameterElement element = namedParameters[name];
-        if (element == null) {
-          ErrorCode errorCode = (reportError
-              ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER
-              : StaticWarningCode.UNDEFINED_NAMED_PARAMETER);
-          _resolver.reportErrorForNode(errorCode, nameNode, [name]);
-        } else {
-          resolvedParameters[i] = element;
-          nameNode.staticElement = element;
-        }
-        if (!usedNames.add(name)) {
-          _resolver.reportErrorForNode(
-              CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
-        }
-      } else {
-        if (argument is SimpleIdentifier && argument.name.isEmpty) {
-          noBlankArguments = false;
-        }
-        positionalArgumentCount++;
-        if (unnamedIndex < unnamedParameterCount) {
-          resolvedParameters[i] = unnamedParameters[unnamedIndex++];
-        }
-      }
-    }
-    if (positionalArgumentCount < requiredParameters.length &&
-        noBlankArguments) {
-      ErrorCode errorCode = (reportError
-          ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS
-          : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
-      _resolver.reportErrorForNode(errorCode, argumentList,
-          [requiredParameters.length, positionalArgumentCount]);
-    } else if (positionalArgumentCount > unnamedParameterCount &&
-        noBlankArguments) {
-      ErrorCode errorCode = (reportError
-          ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS
-          : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
-      _resolver.reportErrorForNode(errorCode, argumentList,
-          [unnamedParameterCount, positionalArgumentCount]);
-    }
-    return resolvedParameters;
+    return ResolverVisitor.resolveArgumentsToParameters(
+        argumentList, parameters, _resolver.reportErrorForNode,
+        reportAsError: reportAsError);
   }
 
   void _resolveBinaryExpression(BinaryExpression node, String methodName) {
@@ -2311,7 +2062,7 @@
    * given [propertyName], return the element that represents the property.
    */
   Element _resolveElement(
-      ClassElementImpl classElement, SimpleIdentifier propertyName) {
+      ClassElement classElement, SimpleIdentifier propertyName) {
     String name = propertyName.name;
     Element element = null;
     if (propertyName.inSetterContext()) {
@@ -2330,6 +2081,36 @@
   }
 
   /**
+   * Check for a generic method & apply type arguments if any were passed.
+   */
+  DartType _resolveGenericMethod(
+      DartType invokeType, TypeArgumentList typeArguments, AstNode node) {
+    // TODO(jmesserly): support generic "call" methods on InterfaceType.
+    if (invokeType is FunctionType) {
+      FunctionType type = invokeType;
+      List<TypeParameterElement> parameters = type.typeFormals;
+
+      NodeList<TypeName> arguments = typeArguments?.arguments;
+      if (arguments != null && arguments.length != parameters.length) {
+        // Wrong number of type arguments. Ignore them
+        arguments = null;
+        _resolver.reportErrorForNode(
+            StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+            node,
+            [type, parameters.length, arguments?.length ?? 0]);
+      }
+      if (parameters.isNotEmpty) {
+        if (arguments == null) {
+          invokeType = _resolver.typeSystem.instantiateToBounds(type);
+        } else {
+          invokeType = type.instantiate(arguments.map((n) => n.type).toList());
+        }
+      }
+    }
+    return invokeType;
+  }
+
+  /**
    * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the
    * element being invoked. If the returned element is a method, then the method
    * will be invoked. If the returned element is a getter, the getter will be
@@ -2439,7 +2220,7 @@
   }
 
   void _resolvePropertyAccess(
-      Expression target, SimpleIdentifier propertyName) {
+      Expression target, SimpleIdentifier propertyName, bool isCascaded) {
     DartType staticType = _getStaticType(target);
     DartType propagatedType = _getPropagatedType(target);
     Element staticElement = null;
@@ -2452,6 +2233,9 @@
     //
     ClassElementImpl typeReference = getTypeReference(target);
     if (typeReference != null) {
+      if (isCascaded) {
+        typeReference = _typeType.element;
+      }
       // TODO(brianwilkerson) Why are we setting the propagated element here?
       // It looks wrong.
       staticElement =
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 5822a61..4f8d664 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -2,49 +2,36 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine;
+library analyzer.src.generated.engine;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:math' as math;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
-import 'package:analyzer/src/context/cache.dart' as cache;
-import 'package:analyzer/src/context/context.dart' as newContext;
-import 'package:analyzer/src/generated/incremental_resolution_validator.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/plugin/command_line_plugin.dart';
 import 'package:analyzer/src/plugin/engine_plugin.dart';
 import 'package:analyzer/src/plugin/options_plugin.dart';
-import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/task/manager.dart';
 import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/model.dart' as newContext;
 import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart' show Document;
 import 'package:path/path.dart' as pathos;
 import 'package:plugin/manager.dart';
 import 'package:plugin/plugin.dart';
 
-import '../../instrumentation/instrumentation.dart';
-import 'ast.dart';
-import 'constant.dart';
-import 'element.dart';
-import 'error.dart';
-import 'error_verifier.dart';
-import 'html.dart' as ht;
-import 'incremental_resolver.dart'
-    show IncrementalResolver, PoorMansIncrementalResolver;
-import 'incremental_scanner.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser, IncrementalParser;
-import 'resolver.dart';
-import 'scanner.dart';
-import 'sdk.dart' show DartSdk;
-import 'source.dart';
-import 'utilities_collection.dart';
-import 'utilities_general.dart';
-
 /**
  * Used by [AnalysisOptions] to allow function bodies to be analyzed in some
  * sources but not others.
@@ -52,226 +39,6 @@
 typedef bool AnalyzeFunctionBodiesPredicate(Source source);
 
 /**
- * Type of callback functions used by PendingFuture.  Functions of this type
- * should perform a computation based on the data in [sourceEntry] and return
- * it.  If the computation can't be performed yet because more analysis is
- * needed, null should be returned.
- *
- * The function may also throw an exception, in which case the corresponding
- * future will be completed with failure.
- *
- * Since this function is called while the state of analysis is being updated,
- * it should be free of side effects so that it doesn't cause reentrant
- * changes to the analysis state.
- */
-typedef T PendingFutureComputer<T>(SourceEntry sourceEntry);
-
-/**
- * An LRU cache of information related to analysis.
- */
-class AnalysisCache {
-  /**
-   * A flag used to control whether trace information should be produced when
-   * the content of the cache is modified.
-   */
-  static bool _TRACE_CHANGES = false;
-
-  /**
-   * A list containing the partitions of which this cache is comprised.
-   */
-  final List<CachePartition> _partitions;
-
-  /**
-   * Initialize a newly created cache to have the given [_partitions]. The
-   * partitions will be searched in the order in which they appear in the list,
-   * so the most specific partition (usually an [SdkCachePartition]) should be
-   * first and the most general (usually a [UniversalCachePartition]) last.
-   */
-  AnalysisCache(this._partitions);
-
-  /**
-   * Return the number of entries in this cache that have an AST associated with
-   * them.
-   */
-  int get astSize => _partitions[_partitions.length - 1].astSize;
-
-  /**
-   * Return information about each of the partitions in this cache.
-   */
-  List<AnalysisContextStatistics_PartitionData> get partitionData {
-    int count = _partitions.length;
-    List<AnalysisContextStatistics_PartitionData> data =
-        new List<AnalysisContextStatistics_PartitionData>(count);
-    for (int i = 0; i < count; i++) {
-      CachePartition partition = _partitions[i];
-      data[i] = new AnalysisContextStatisticsImpl_PartitionDataImpl(
-          partition.astSize, partition.map.length);
-    }
-    return data;
-  }
-
-  /**
-   * Record that the AST associated with the given [source] was just read from
-   * the cache.
-   */
-  void accessedAst(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        _partitions[i].accessedAst(source);
-        return;
-      }
-    }
-  }
-
-  /**
-   * Return the entry associated with the given [source].
-   */
-  SourceEntry get(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        return _partitions[i].get(source);
-      }
-    }
-    //
-    // We should never get to this point because the last partition should
-    // always be a universal partition, except in the case of the SDK context,
-    // in which case the source should always be part of the SDK.
-    //
-    return null;
-  }
-
-  /**
-   * Return context that owns the given [source].
-   */
-  InternalAnalysisContext getContextFor(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        return _partitions[i].context;
-      }
-    }
-    //
-    // We should never get to this point because the last partition should
-    // always be a universal partition, except in the case of the SDK context,
-    // in which case the source should always be part of the SDK.
-    //
-    AnalysisEngine.instance.logger.logInformation(
-        "Could not find context for ${source.fullName}",
-        new CaughtException(new AnalysisException(), null));
-    return null;
-  }
-
-  /**
-   * Return an iterator returning all of the map entries mapping sources to
-   * cache entries.
-   */
-  MapIterator<Source, SourceEntry> iterator() {
-    int count = _partitions.length;
-    List<Map<Source, SourceEntry>> maps =
-        new List<Map<Source, SourceEntry>>(count);
-    for (int i = 0; i < count; i++) {
-      maps[i] = _partitions[i].map;
-    }
-    return new MultipleMapIterator<Source, SourceEntry>(maps);
-  }
-
-  /**
-   * Associate the given [entry] with the given [source].
-   */
-  void put(Source source, SourceEntry entry) {
-    entry.fixExceptionState();
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        if (_TRACE_CHANGES) {
-          try {
-            SourceEntry oldEntry = _partitions[i].get(source);
-            if (oldEntry == null) {
-              AnalysisEngine.instance.logger.logInformation(
-                  "Added a cache entry for '${source.fullName}'.");
-            } else {
-              AnalysisEngine.instance.logger.logInformation(
-                  "Modified the cache entry for ${source.fullName}'. Diff = ${entry.getDiff(oldEntry)}");
-            }
-          } catch (exception) {
-            // Ignored
-            JavaSystem.currentTimeMillis();
-          }
-        }
-        _partitions[i].put(source, entry);
-        return;
-      }
-    }
-  }
-
-  /**
-   * Remove all information related to the given [source] from this cache.
-   * Return the entry associated with the source, or `null` if there was cache
-   * entry for the source.
-   */
-  SourceEntry remove(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        if (_TRACE_CHANGES) {
-          try {
-            AnalysisEngine.instance.logger.logInformation(
-                "Removed the cache entry for ${source.fullName}'.");
-          } catch (exception) {
-            // Ignored
-            JavaSystem.currentTimeMillis();
-          }
-        }
-        return _partitions[i].remove(source);
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Record that the AST associated with the given [source] was just removed
-   * from the cache.
-   */
-  void removedAst(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        _partitions[i].removedAst(source);
-        return;
-      }
-    }
-  }
-
-  /**
-   * Return the number of sources that are mapped to cache entries.
-   */
-  int size() {
-    int size = 0;
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      size += _partitions[i].size();
-    }
-    return size;
-  }
-
-  /**
-   * Record that the AST associated with the given [source] was just stored to
-   * the cache.
-   */
-  void storedAst(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        _partitions[i].storedAst(source);
-        return;
-      }
-    }
-  }
-}
-
-/**
  * A context in which a single analysis can be performed and incrementally
  * maintained. The context includes such information as the version of the SDK
  * being analyzed against as well as the package-root used to resolve 'package:'
@@ -452,7 +219,7 @@
    * analysis results that have been invalidated by these changes will be
    * removed.
    */
-  void applyChanges(ChangeSet changeSet);
+  ApplyChangesStatus applyChanges(ChangeSet changeSet);
 
   /**
    * Return the documentation comment for the given [element] as it appears in
@@ -485,24 +252,6 @@
   List<AnalysisError> computeErrors(Source source);
 
   /**
-   * Return the element model corresponding to the HTML file defined by the
-   * given [source]. If the element model does not yet exist it will be created.
-   * The process of creating an element model for an HTML file can be
-   * long-running, depending on the size of the file and the number of libraries
-   * that are defined in it (via script tags) that also need to have a model
-   * built for them.
-   *
-   * Throws AnalysisException if the element model could not be determined
-   * because the analysis could not be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * See [getHtmlElement].
-   */
-  @deprecated
-  HtmlElement computeHtmlElement(Source source);
-
-  /**
    * Return the kind of the given [source], computing it's kind if it is not
    * already known. Return [SourceKind.UNKNOWN] if the source is not contained
    * in this context.
@@ -563,7 +312,7 @@
    * Perform work until the given [result] has been computed for the given
    * [target]. Return the computed value.
    */
-  Object /*V*/ computeResult(
+  Object /*=V*/ computeResult /*<V>*/ (
       AnalysisTarget target, ResultDescriptor /*<V>*/ result);
 
   /**
@@ -591,8 +340,8 @@
       Source unitSource, Source librarySource);
 
   /**
-   * Return configuration data associated with the given key or `null` if no
-   * state has been associated with the given [key].
+   * Return configuration data associated with the given key or the [key]'s
+   * default value if no state has been associated.
    *
    * See [setConfigurationData].
    */
@@ -628,17 +377,6 @@
   AnalysisErrorInfo getErrors(Source source);
 
   /**
-   * Return the element model corresponding to the HTML file defined by the
-   * given [source], or `null` if the source does not represent an HTML file,
-   * the element representing the file has not yet been created, or the analysis
-   * of the HTML file failed for some reason.
-   *
-   * See [computeHtmlElement].
-   */
-  @deprecated
-  HtmlElement getHtmlElement(Source source);
-
-  /**
    * Return the sources for the HTML files that reference the compilation unit
    * with the given [source]. If the source does not represent a Dart source or
    * is not known to this context, the returned list will be empty. The contents
@@ -731,21 +469,12 @@
       Source unitSource, Source librarySource);
 
   /**
-   * Return the fully resolved HTML unit defined by the given [htmlSource], or
-   * `null` if the resolved unit is not already computed.
-   *
-   * See [resolveHtmlUnit].
-   */
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource);
-
-  /**
    * Return the value of the given [result] for the given [target].
    *
    * If the corresponding [target] does not exist, or the [result] is not
    * computed yet, then the default value is returned.
    */
-  Object /*V*/ getResult(
+  Object /*=V*/ getResult /*<V>*/ (
       AnalysisTarget target, ResultDescriptor /*<V>*/ result);
 
   /**
@@ -810,18 +539,6 @@
   Document parseHtmlDocument(Source source);
 
   /**
-   * Parse a single HTML [source] to produce an AST structure. The resulting
-   * HTML AST structure may or may not be resolved, and may have a slightly
-   * different structure depending upon whether it is resolved.
-   *
-   * Throws an [AnalysisException] if the analysis could not be performed
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  @deprecated // use parseHtmlDocument(source)
-  ht.HtmlUnit parseHtmlUnit(Source source);
-
-  /**
    * Perform the next unit of work required to keep the analysis results
    * up-to-date and return information about the consequent changes to the
    * analysis results. This method can be long running.
@@ -876,17 +593,6 @@
       Source unitSource, Source librarySource);
 
   /**
-   * Parse and resolve a single [htmlSource] within the given context to produce
-   * a fully resolved AST.
-   *
-   * Throws an [AnalysisException] if the analysis could not be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource);
-
-  /**
    * Set the contents of the given [source] to the given [contents] and mark the
    * source as having changed. The additional [offset] and [length] information
    * is used by the context to determine what reanalysis is necessary.
@@ -919,4867 +625,6 @@
 }
 
 /**
- * An [AnalysisContext].
- */
-class AnalysisContextImpl implements InternalAnalysisContext {
-  /**
-   * The difference between the maximum cache size and the maximum priority
-   * order size. The priority list must be capped so that it is less than the
-   * cache size. Failure to do so can result in an infinite loop in
-   * performAnalysisTask() because re-caching one AST structure can cause
-   * another priority source's AST structure to be flushed.
-   */
-  static int _PRIORITY_ORDER_SIZE_DELTA = 4;
-
-  /**
-   * A flag indicating whether trace output should be produced as analysis tasks
-   * are performed. Used for debugging.
-   */
-  static bool _TRACE_PERFORM_TASK = false;
-
-  /**
-   * 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.
-   */
-  String name;
-
-  /**
-   * Configuration data associated with this context.
-   */
-  final HashMap<ResultDescriptor, Object> _configurationData =
-      new HashMap<ResultDescriptor, Object>();
-
-  /**
-   * The set of analysis options controlling the behavior of this context.
-   */
-  AnalysisOptionsImpl _options = new AnalysisOptionsImpl();
-
-  /**
-   * A flag indicating whether errors related to implicitly analyzed sources
-   * should be generated and reported.
-   */
-  bool _generateImplicitErrors = true;
-
-  /**
-   * A flag indicating whether errors related to sources in the SDK should be
-   * generated and reported.
-   */
-  bool _generateSdkErrors = true;
-
-  /**
-   * A flag indicating whether this context is disposed.
-   */
-  bool _disposed = false;
-
-  /**
-   * A cache of content used to override the default content of a source.
-   */
-  ContentCache _contentCache = new ContentCache();
-
-  /**
-   * The source factory used to create the sources that can be analyzed in this
-   * context.
-   */
-  SourceFactory _sourceFactory;
-
-  /**
-   * The set of declared variables used when computing constant values.
-   */
-  DeclaredVariables _declaredVariables = new DeclaredVariables();
-
-  /**
-   * A source representing the core library.
-   */
-  Source _coreLibrarySource;
-
-  /**
-   * A source representing the async library.
-   */
-  Source _asyncLibrarySource;
-
-  /**
-   * The partition that contains analysis results that are not shared with other
-   * contexts.
-   */
-  CachePartition _privatePartition;
-
-  /**
-   * A table mapping the sources known to the context to the information known
-   * about the source.
-   */
-  AnalysisCache _cache;
-
-  /**
-   * A list containing sources for which data should not be flushed.
-   */
-  List<Source> _priorityOrder = Source.EMPTY_LIST;
-
-  /**
-   * A map from all sources for which there are futures pending to a list of
-   * the corresponding PendingFuture objects.  These sources will be analyzed
-   * in the same way as priority sources, except with higher priority.
-   *
-   * TODO(paulberry): since the size of this map is not constrained (as it is
-   * for _priorityOrder), we run the risk of creating an analysis loop if
-   * re-caching one AST structure causes the AST structure for another source
-   * with pending futures to be flushed.  However, this is unlikely to happen
-   * in practice since sources are removed from this hash set as soon as their
-   * futures have completed.
-   */
-  HashMap<Source, List<PendingFuture>> _pendingFutureSources =
-      new HashMap<Source, List<PendingFuture>>();
-
-  /**
-   * A list containing sources whose AST structure is needed in order to resolve
-   * the next library to be resolved.
-   */
-  HashSet<Source> _neededForResolution = null;
-
-  /**
-   * A table mapping sources to the change notices that are waiting to be
-   * returned related to that source.
-   */
-  HashMap<Source, ChangeNoticeImpl> _pendingNotices =
-      new HashMap<Source, ChangeNoticeImpl>();
-
-  /**
-   * The object used to record the results of performing an analysis task.
-   */
-  AnalysisContextImpl_AnalysisTaskResultRecorder _resultRecorder;
-
-  /**
-   * Cached information used in incremental analysis or `null` if none.
-   */
-  IncrementalAnalysisCache _incrementalAnalysisCache;
-
-  /**
-   * The [TypeProvider] for this context, `null` if not yet created.
-   */
-  TypeProvider _typeProvider;
-
-  /**
-   * The [TypeSystem] for this context, `null` if not yet created.
-   */
-  TypeSystem _typeSystem;
-
-  /**
-   * The object used to manage the list of sources that need to be analyzed.
-   */
-  WorkManager _workManager = new WorkManager();
-
-  /**
-   * The [Stopwatch] of the current "perform tasks cycle".
-   */
-  Stopwatch _performAnalysisTaskStopwatch;
-
-  /**
-   * The controller for sending [SourcesChangedEvent]s.
-   */
-  StreamController<SourcesChangedEvent> _onSourcesChangedController;
-
-  /**
-   * A subscription for a stream of events indicating when files are (and are
-   * not) being implicitly analyzed.
-   */
-  StreamController<ImplicitAnalysisEvent> _implicitAnalysisEventsController;
-
-  /**
-   * The listeners that are to be notified when various analysis results are
-   * produced in this context.
-   */
-  List<AnalysisListener> _listeners = new List<AnalysisListener>();
-
-  /**
-   * The most recently incrementally resolved source, or `null` when it was
-   * already validated, or the most recent change was not incrementally resolved.
-   */
-  Source incrementalResolutionValidation_lastUnitSource;
-
-  /**
-   * The most recently incrementally resolved library source, or `null` when it
-   * was already validated, or the most recent change was not incrementally
-   * resolved.
-   */
-  Source incrementalResolutionValidation_lastLibrarySource;
-
-  /**
-   * The result of incremental resolution result of
-   * [incrementalResolutionValidation_lastSource].
-   */
-  CompilationUnit incrementalResolutionValidation_lastUnit;
-
-  /**
-   * A factory to override how the [ResolverVisitor] is created.
-   */
-  ResolverVisitorFactory resolverVisitorFactory;
-
-  /**
-   * A factory to override how the [TypeResolverVisitor] is created.
-   */
-  TypeResolverVisitorFactory typeResolverVisitorFactory;
-
-  /**
-   * A factory to override how [LibraryResolver] is created.
-   */
-  LibraryResolverFactory libraryResolverFactory;
-
-  /**
-   * Initialize a newly created analysis context.
-   */
-  AnalysisContextImpl() {
-    _resultRecorder = new AnalysisContextImpl_AnalysisTaskResultRecorder(this);
-    _privatePartition = new UniversalCachePartition(
-        this,
-        AnalysisOptionsImpl.DEFAULT_CACHE_SIZE,
-        new AnalysisContextImpl_ContextRetentionPolicy(this));
-    _cache = createCacheFromSourceFactory(null);
-    _onSourcesChangedController =
-        new StreamController<SourcesChangedEvent>.broadcast();
-    _implicitAnalysisEventsController =
-        new StreamController<ImplicitAnalysisEvent>.broadcast();
-  }
-
-  @override
-  AnalysisCache get analysisCache => _cache;
-
-  @override
-  AnalysisOptions get analysisOptions => _options;
-
-  @override
-  void set analysisOptions(AnalysisOptions options) {
-    bool needsRecompute = this._options.analyzeFunctionBodiesPredicate !=
-            options.analyzeFunctionBodiesPredicate ||
-        this._options.generateImplicitErrors !=
-            options.generateImplicitErrors ||
-        this._options.generateSdkErrors != options.generateSdkErrors ||
-        this._options.dart2jsHint != options.dart2jsHint ||
-        (this._options.hint && !options.hint) ||
-        this._options.preserveComments != options.preserveComments ||
-        this._options.strongMode != options.strongMode ||
-        this._options.enableStrictCallChecks !=
-            options.enableStrictCallChecks ||
-        this._options.enableSuperMixins != options.enableSuperMixins;
-    int cacheSize = options.cacheSize;
-    if (this._options.cacheSize != cacheSize) {
-      this._options.cacheSize = cacheSize;
-      //cache.setMaxCacheSize(cacheSize);
-      _privatePartition.maxCacheSize = cacheSize;
-      //
-      // Cap the size of the priority list to being less than the cache size.
-      // Failure to do so can result in an infinite loop in
-      // performAnalysisTask() because re-caching one AST structure
-      // can cause another priority source's AST structure to be flushed.
-      //
-      // TODO(brianwilkerson) Remove this constraint when the new task model is
-      // implemented.
-      //
-      int maxPriorityOrderSize = cacheSize - _PRIORITY_ORDER_SIZE_DELTA;
-      if (_priorityOrder.length > maxPriorityOrderSize) {
-        _priorityOrder = _priorityOrder.sublist(0, maxPriorityOrderSize);
-      }
-    }
-    this._options.analyzeFunctionBodiesPredicate =
-        options.analyzeFunctionBodiesPredicate;
-    this._options.generateImplicitErrors = options.generateImplicitErrors;
-    this._options.generateSdkErrors = options.generateSdkErrors;
-    this._options.dart2jsHint = options.dart2jsHint;
-    this._options.enableStrictCallChecks = options.enableStrictCallChecks;
-    this._options.enableSuperMixins = options.enableSuperMixins;
-    this._options.hint = options.hint;
-    this._options.incremental = options.incremental;
-    this._options.incrementalApi = options.incrementalApi;
-    this._options.incrementalValidation = options.incrementalValidation;
-    this._options.lint = options.lint;
-    this._options.preserveComments = options.preserveComments;
-    this._options.strongMode = options.strongMode;
-    _generateImplicitErrors = options.generateImplicitErrors;
-    _generateSdkErrors = options.generateSdkErrors;
-    if (needsRecompute) {
-      _invalidateAllLocalResolutionInformation(false);
-    }
-  }
-
-  @override
-  void set analysisPriorityOrder(List<Source> sources) {
-    if (sources == null || sources.isEmpty) {
-      _priorityOrder = Source.EMPTY_LIST;
-    } else {
-      while (sources.remove(null)) {
-        // Nothing else to do.
-      }
-      if (sources.isEmpty) {
-        _priorityOrder = Source.EMPTY_LIST;
-      }
-      //
-      // Cap the size of the priority list to being less than the cache size.
-      // Failure to do so can result in an infinite loop in
-      // performAnalysisTask() because re-caching one AST structure
-      // can cause another priority source's AST structure to be flushed.
-      //
-      int count = math.min(
-          sources.length, _options.cacheSize - _PRIORITY_ORDER_SIZE_DELTA);
-      _priorityOrder = new List<Source>(count);
-      for (int i = 0; i < count; i++) {
-        _priorityOrder[i] = sources[i];
-      }
-      // Ensure entries for every priority source.
-      for (var source in _priorityOrder) {
-        SourceEntry entry = _getReadableSourceEntry(source);
-        if (entry == null) {
-          _createSourceEntry(source, false);
-        }
-      }
-    }
-  }
-
-  @override
-  set contentCache(ContentCache value) {
-    _contentCache = value;
-  }
-
-  @override
-  DeclaredVariables get declaredVariables => _declaredVariables;
-
-  @override
-  List<AnalysisTarget> get explicitTargets {
-    List<AnalysisTarget> targets = <AnalysisTarget>[];
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      if (iterator.value.explicitlyAdded) {
-        targets.add(iterator.key);
-      }
-    }
-    return targets;
-  }
-
-  @override
-  List<Source> get htmlSources => _getSources(SourceKind.HTML);
-
-  @override
-  Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents =>
-      _implicitAnalysisEventsController.stream;
-
-  @override
-  bool get isDisposed => _disposed;
-
-  @override
-  List<Source> get launchableClientLibrarySources {
-    // TODO(brianwilkerson) This needs to filter out libraries that do not
-    // reference dart:html, either directly or indirectly.
-    List<Source> sources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
-//          DartEntry dartEntry = (DartEntry) sourceEntry;
-//          if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && dartEntry.getValue(DartEntry.IS_CLIENT)) {
-        sources.add(source);
-//          }
-      }
-    }
-    return sources;
-  }
-
-  @override
-  List<Source> get launchableServerLibrarySources {
-    // TODO(brianwilkerson) This needs to filter out libraries that reference
-    // dart:html, either directly or indirectly.
-    List<Source> sources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
-//          DartEntry dartEntry = (DartEntry) sourceEntry;
-//          if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && !dartEntry.getValue(DartEntry.IS_CLIENT)) {
-        sources.add(source);
-//          }
-      }
-    }
-    return sources;
-  }
-
-  @override
-  List<Source> get librarySources => _getSources(SourceKind.LIBRARY);
-
-  /**
-   * Look through the cache for a task that needs to be performed. Return the
-   * task that was found, or `null` if there is no more work to be done.
-   */
-  AnalysisTask get nextAnalysisTask {
-    bool hintsEnabled = _options.hint;
-    bool lintsEnabled = _options.lint;
-    bool hasBlockedTask = false;
-    //
-    // Look for incremental analysis
-    //
-    if (_incrementalAnalysisCache != null &&
-        _incrementalAnalysisCache.hasWork) {
-      AnalysisTask task =
-          new IncrementalAnalysisTask(this, _incrementalAnalysisCache);
-      _incrementalAnalysisCache = null;
-      return task;
-    }
-    //
-    // Look for a source that needs to be analyzed because it has futures
-    // pending.
-    //
-    if (_pendingFutureSources.isNotEmpty) {
-      List<Source> sourcesToRemove = <Source>[];
-      AnalysisTask task;
-      for (Source source in _pendingFutureSources.keys) {
-        SourceEntry sourceEntry = _cache.get(source);
-        List<PendingFuture> pendingFutures = _pendingFutureSources[source];
-        for (int i = 0; i < pendingFutures.length;) {
-          if (pendingFutures[i].evaluate(sourceEntry)) {
-            pendingFutures.removeAt(i);
-          } else {
-            i++;
-          }
-        }
-        if (pendingFutures.isEmpty) {
-          sourcesToRemove.add(source);
-          continue;
-        }
-        AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource(
-            source, sourceEntry, true, hintsEnabled, lintsEnabled);
-        task = taskData.task;
-        if (task != null) {
-          break;
-        } else if (taskData.isBlocked) {
-          hasBlockedTask = true;
-        } else {
-          // There is no more work to do for this task, so forcibly complete
-          // all its pending futures.
-          for (PendingFuture pendingFuture in pendingFutures) {
-            pendingFuture.forciblyComplete();
-          }
-          sourcesToRemove.add(source);
-        }
-      }
-      for (Source source in sourcesToRemove) {
-        _pendingFutureSources.remove(source);
-      }
-      if (task != null) {
-        return task;
-      }
-    }
-    //
-    // Look for a priority source that needs to be analyzed.
-    //
-    int priorityCount = _priorityOrder.length;
-    for (int i = 0; i < priorityCount; i++) {
-      Source source = _priorityOrder[i];
-      AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource(
-          source, _cache.get(source), true, hintsEnabled, lintsEnabled);
-      AnalysisTask task = taskData.task;
-      if (task != null) {
-        return task;
-      } else if (taskData.isBlocked) {
-        hasBlockedTask = true;
-      }
-    }
-    if (_neededForResolution != null) {
-      List<Source> sourcesToRemove = new List<Source>();
-      for (Source source in _neededForResolution) {
-        SourceEntry sourceEntry = _cache.get(source);
-        if (sourceEntry is DartEntry) {
-          DartEntry dartEntry = sourceEntry;
-          if (!dartEntry.hasResolvableCompilationUnit) {
-            if (dartEntry.getState(DartEntry.PARSED_UNIT) == CacheState.ERROR) {
-              sourcesToRemove.add(source);
-            } else {
-              AnalysisContextImpl_TaskData taskData =
-                  _createParseDartTask(source, dartEntry);
-              AnalysisTask task = taskData.task;
-              if (task != null) {
-                return task;
-              } else if (taskData.isBlocked) {
-                hasBlockedTask = true;
-              }
-            }
-          }
-        }
-      }
-      int count = sourcesToRemove.length;
-      for (int i = 0; i < count; i++) {
-        _neededForResolution.remove(sourcesToRemove[i]);
-      }
-    }
-    //
-    // Look for a non-priority source that needs to be analyzed.
-    //
-    List<Source> sourcesToRemove = new List<Source>();
-    WorkManager_WorkIterator sources = _workManager.iterator();
-    try {
-      while (sources.hasNext) {
-        Source source = sources.next();
-        AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource(
-            source, _cache.get(source), false, hintsEnabled, lintsEnabled);
-        AnalysisTask task = taskData.task;
-        if (task != null) {
-          return task;
-        } else if (taskData.isBlocked) {
-          hasBlockedTask = true;
-        } else {
-          sourcesToRemove.add(source);
-        }
-      }
-    } finally {
-      int count = sourcesToRemove.length;
-      for (int i = 0; i < count; i++) {
-        _workManager.remove(sourcesToRemove[i]);
-      }
-    }
-    if (hasBlockedTask) {
-      // All of the analysis work is blocked waiting for an asynchronous task
-      // to complete.
-      return WaitForAsyncTask.instance;
-    }
-    return null;
-  }
-
-  @override
-  Stream<SourcesChangedEvent> get onSourcesChanged =>
-      _onSourcesChangedController.stream;
-
-  /**
-   * Make _pendingFutureSources available to unit tests.
-   */
-  HashMap<Source, List<PendingFuture>> get pendingFutureSources_forTesting =>
-      _pendingFutureSources;
-
-  @override
-  List<Source> get prioritySources => _priorityOrder;
-
-  @override
-  List<AnalysisTarget> get priorityTargets => prioritySources;
-
-  @override
-  CachePartition get privateAnalysisCachePartition => _privatePartition;
-
-  @override
-  SourceFactory get sourceFactory => _sourceFactory;
-
-  @override
-  void set sourceFactory(SourceFactory factory) {
-    if (identical(_sourceFactory, factory)) {
-      return;
-    } else if (factory.context != null) {
-      throw new IllegalStateException(
-          "Source factories cannot be shared between contexts");
-    }
-    if (_sourceFactory != null) {
-      _sourceFactory.context = null;
-    }
-    factory.context = this;
-    _sourceFactory = factory;
-    _coreLibrarySource = _sourceFactory.forUri(DartSdk.DART_CORE);
-    _asyncLibrarySource = _sourceFactory.forUri(DartSdk.DART_ASYNC);
-    _cache = createCacheFromSourceFactory(factory);
-    _invalidateAllLocalResolutionInformation(true);
-  }
-
-  @override
-  List<Source> get sources {
-    List<Source> sources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      sources.add(iterator.key);
-    }
-    return sources;
-  }
-
-  /**
-   * Return a list of the sources that would be processed by
-   * [performAnalysisTask]. This method duplicates, and must therefore be kept
-   * in sync with, [getNextAnalysisTask]. This method is intended to be used for
-   * testing purposes only.
-   */
-  List<Source> get sourcesNeedingProcessing {
-    HashSet<Source> sources = new HashSet<Source>();
-    bool hintsEnabled = _options.hint;
-    bool lintsEnabled = _options.lint;
-
-    //
-    // Look for priority sources that need to be analyzed.
-    //
-    for (Source source in _priorityOrder) {
-      _getSourcesNeedingProcessing(source, _cache.get(source), true,
-          hintsEnabled, lintsEnabled, sources);
-    }
-    //
-    // Look for non-priority sources that need to be analyzed.
-    //
-    WorkManager_WorkIterator iterator = _workManager.iterator();
-    while (iterator.hasNext) {
-      Source source = iterator.next();
-      _getSourcesNeedingProcessing(source, _cache.get(source), false,
-          hintsEnabled, lintsEnabled, sources);
-    }
-    return new List<Source>.from(sources);
-  }
-
-  @override
-  AnalysisContextStatistics get statistics {
-    AnalysisContextStatisticsImpl statistics =
-        new AnalysisContextStatisticsImpl();
-    visitCacheItems(statistics._internalPutCacheItem);
-    statistics.partitionData = _cache.partitionData;
-    return statistics;
-  }
-
-  IncrementalAnalysisCache get test_incrementalAnalysisCache {
-    return _incrementalAnalysisCache;
-  }
-
-  set test_incrementalAnalysisCache(IncrementalAnalysisCache value) {
-    _incrementalAnalysisCache = value;
-  }
-
-  List<Source> get test_priorityOrder => _priorityOrder;
-
-  @override
-  TypeProvider get typeProvider {
-    if (_typeProvider != null) {
-      return _typeProvider;
-    }
-    Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
-    if (coreSource == null) {
-      throw new AnalysisException("Could not create a source for dart:core");
-    }
-    LibraryElement coreElement = computeLibraryElement(coreSource);
-    if (coreElement == null) {
-      throw new AnalysisException("Could not create an element for dart:core");
-    }
-    Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
-    if (asyncSource == null) {
-      throw new AnalysisException("Could not create a source for dart:async");
-    }
-    LibraryElement asyncElement = computeLibraryElement(asyncSource);
-    if (asyncElement == null) {
-      throw new AnalysisException("Could not create an element for dart:async");
-    }
-    _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
-    return _typeProvider;
-  }
-
-  /**
-   * Sets the [TypeProvider] for this context.
-   */
-  void set typeProvider(TypeProvider typeProvider) {
-    _typeProvider = typeProvider;
-  }
-
-  @override
-  TypeSystem get typeSystem {
-    if (_typeSystem == null) {
-      _typeSystem = TypeSystem.create(this);
-    }
-    return _typeSystem;
-  }
-
-  @override
-  List<newContext.WorkManager> get workManagers {
-    throw new NotImplementedException('In not task-based AnalysisContext.');
-  }
-
-  @override
-  void addListener(AnalysisListener listener) {
-    if (!_listeners.contains(listener)) {
-      _listeners.add(listener);
-    }
-  }
-
-  @override
-  void applyAnalysisDelta(AnalysisDelta delta) {
-    ChangeSet changeSet = new ChangeSet();
-    delta.analysisLevels.forEach((Source source, AnalysisLevel level) {
-      if (level == AnalysisLevel.NONE) {
-        changeSet.removedSource(source);
-      } else {
-        changeSet.addedSource(source);
-      }
-    });
-    applyChanges(changeSet);
-  }
-
-  @override
-  void applyChanges(ChangeSet changeSet) {
-    if (changeSet.isEmpty) {
-      return;
-    }
-    //
-    // First, compute the list of sources that have been removed.
-    //
-    List<Source> removedSources =
-        new List<Source>.from(changeSet.removedSources);
-    for (SourceContainer container in changeSet.removedContainers) {
-      _addSourcesInContainer(removedSources, container);
-    }
-    //
-    // Then determine which cached results are no longer valid.
-    //
-    for (Source source in changeSet.addedSources) {
-      _sourceAvailable(source);
-    }
-    for (Source source in changeSet.changedSources) {
-      if (_contentCache.getContents(source) != null) {
-        // This source is overridden in the content cache, so the change will
-        // have no effect. Just ignore it to avoid wasting time doing
-        // re-analysis.
-        continue;
-      }
-      _sourceChanged(source);
-    }
-    changeSet.changedContents.forEach((Source key, String value) {
-      _contentsChanged(key, value, false);
-    });
-    changeSet.changedRanges
-        .forEach((Source source, ChangeSet_ContentChange change) {
-      _contentRangeChanged(source, change.contents, change.offset,
-          change.oldLength, change.newLength);
-    });
-    for (Source source in changeSet.deletedSources) {
-      _sourceDeleted(source);
-    }
-    for (Source source in removedSources) {
-      _sourceRemoved(source);
-    }
-    _onSourcesChangedController.add(new SourcesChangedEvent(changeSet));
-  }
-
-  @override
-  String computeDocumentationComment(Element element) {
-    if (element == null) {
-      return null;
-    }
-    Source source = element.source;
-    if (source == null) {
-      return null;
-    }
-    SourceRange docRange = element.docRange;
-    if (docRange == null) {
-      return null;
-    }
-    String code = getContents(source).data;
-    String comment = code.substring(docRange.offset, docRange.end);
-    return comment.replaceAll('\r\n', '\n');
-  }
-
-  @override
-  List<AnalysisError> computeErrors(Source source) {
-    bool enableHints = _options.hint;
-    bool enableLints = _options.lint;
-
-    SourceEntry sourceEntry = _getReadableSourceEntry(source);
-    if (sourceEntry is DartEntry) {
-      List<AnalysisError> errors = new List<AnalysisError>();
-      try {
-        DartEntry dartEntry = sourceEntry;
-        ListUtilities.addAll(
-            errors, _getDartScanData(source, dartEntry, DartEntry.SCAN_ERRORS));
-        dartEntry = _getReadableDartEntry(source);
-        ListUtilities.addAll(errors,
-            _getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
-        dartEntry = _getReadableDartEntry(source);
-        if (dartEntry.getValue(DartEntry.SOURCE_KIND) == SourceKind.LIBRARY) {
-          ListUtilities.addAll(
-              errors,
-              _getDartResolutionData(
-                  source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
-          dartEntry = _getReadableDartEntry(source);
-          ListUtilities.addAll(
-              errors,
-              _getDartVerificationData(
-                  source, source, dartEntry, DartEntry.VERIFICATION_ERRORS));
-          if (enableHints) {
-            dartEntry = _getReadableDartEntry(source);
-            ListUtilities.addAll(errors,
-                _getDartHintData(source, source, dartEntry, DartEntry.HINTS));
-          }
-          if (enableLints) {
-            dartEntry = _getReadableDartEntry(source);
-            ListUtilities.addAll(errors,
-                _getDartLintData(source, source, dartEntry, DartEntry.LINTS));
-          }
-        } else {
-          List<Source> libraries = getLibrariesContaining(source);
-          for (Source librarySource in libraries) {
-            ListUtilities.addAll(
-                errors,
-                _getDartResolutionData(source, librarySource, dartEntry,
-                    DartEntry.RESOLUTION_ERRORS));
-            dartEntry = _getReadableDartEntry(source);
-            ListUtilities.addAll(
-                errors,
-                _getDartVerificationData(source, librarySource, dartEntry,
-                    DartEntry.VERIFICATION_ERRORS));
-            if (enableHints) {
-              dartEntry = _getReadableDartEntry(source);
-              ListUtilities.addAll(
-                  errors,
-                  _getDartHintData(
-                      source, librarySource, dartEntry, DartEntry.HINTS));
-            }
-            if (enableLints) {
-              dartEntry = _getReadableDartEntry(source);
-              ListUtilities.addAll(
-                  errors,
-                  _getDartLintData(
-                      source, librarySource, dartEntry, DartEntry.LINTS));
-            }
-          }
-        }
-      } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logInformation(
-            "Could not compute errors",
-            new CaughtException(exception, stackTrace));
-      }
-      if (errors.isEmpty) {
-        return AnalysisError.NO_ERRORS;
-      }
-      return errors;
-    } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      try {
-        return _getHtmlResolutionData2(
-            source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
-      } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logInformation(
-            "Could not compute errors",
-            new CaughtException(exception, stackTrace));
-      }
-    }
-    return AnalysisError.NO_ERRORS;
-  }
-
-  @override
-  List<Source> computeExportedLibraries(Source source) => _getDartParseData2(
-      source, DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_LIST);
-
-  @override
-  @deprecated
-  HtmlElement computeHtmlElement(Source source) =>
-      _getHtmlResolutionData(source, HtmlEntry.ELEMENT, null);
-
-  @override
-  List<Source> computeImportedLibraries(Source source) => _getDartParseData2(
-      source, DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_LIST);
-
-  @override
-  SourceKind computeKindOf(Source source) {
-    SourceEntry sourceEntry = _getReadableSourceEntry(source);
-    if (sourceEntry == null) {
-      return SourceKind.UNKNOWN;
-    } else if (sourceEntry is DartEntry) {
-      try {
-        return _getDartParseData(source, sourceEntry, DartEntry.SOURCE_KIND);
-      } on AnalysisException {
-        return SourceKind.UNKNOWN;
-      }
-    }
-    return sourceEntry.kind;
-  }
-
-  @override
-  LibraryElement computeLibraryElement(Source source) =>
-      _getDartResolutionData2(source, source, DartEntry.ELEMENT, null);
-
-  @override
-  LineInfo computeLineInfo(Source source) {
-    SourceEntry sourceEntry = _getReadableSourceEntry(source);
-    try {
-      if (sourceEntry is HtmlEntry) {
-        return _getHtmlParseData(source, SourceEntry.LINE_INFO, null);
-      } else if (sourceEntry is DartEntry) {
-        return _getDartScanData2(source, SourceEntry.LINE_INFO, null);
-      }
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute ${SourceEntry.LINE_INFO}",
-          new CaughtException(exception, stackTrace));
-    }
-    return null;
-  }
-
-  @override
-  CompilationUnit computeResolvableCompilationUnit(Source source) {
-    DartEntry dartEntry = _getReadableDartEntry(source);
-    if (dartEntry == null) {
-      throw new AnalysisException(
-          "computeResolvableCompilationUnit for non-Dart: ${source.fullName}");
-    }
-    dartEntry = _cacheDartParseData(source, dartEntry, DartEntry.PARSED_UNIT);
-    CompilationUnit unit = dartEntry.resolvableCompilationUnit;
-    if (unit == null) {
-      throw new AnalysisException(
-          "Internal error: computeResolvableCompilationUnit could not parse ${source.fullName}",
-          new CaughtException(dartEntry.exception, null));
-    }
-    return unit;
-  }
-
-  @override
-  CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync(
-      Source unitSource, Source librarySource) {
-    return new _AnalysisFutureHelper<CompilationUnit>(this)
-        .computeAsync(unitSource, (SourceEntry sourceEntry) {
-      if (sourceEntry is DartEntry) {
-        if (sourceEntry.getStateInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource) ==
-            CacheState.ERROR) {
-          throw sourceEntry.exception;
-        }
-        return sourceEntry.getValueInLibrary(
-            DartEntry.RESOLVED_UNIT, librarySource);
-      }
-      throw new AnalysisNotScheduledError();
-    });
-  }
-
-  @override
-  Object computeResult(AnalysisTarget target, ResultDescriptor result) {
-    return result.defaultValue;
-  }
-
-  /**
-   * Create an analysis cache based on the given source [factory].
-   */
-  AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
-    if (factory == null) {
-      return new AnalysisCache(<CachePartition>[_privatePartition]);
-    }
-    DartSdk sdk = factory.dartSdk;
-    if (sdk == null) {
-      return new AnalysisCache(<CachePartition>[_privatePartition]);
-    }
-    return new AnalysisCache(<CachePartition>[
-      AnalysisEngine.instance.partitionManager.forSdk(sdk),
-      _privatePartition
-    ]);
-  }
-
-  @override
-  void dispose() {
-    _disposed = true;
-    for (List<PendingFuture> pendingFutures in _pendingFutureSources.values) {
-      for (PendingFuture pendingFuture in pendingFutures) {
-        pendingFuture.forciblyComplete();
-      }
-    }
-    _pendingFutureSources.clear();
-  }
-
-  @override
-  List<CompilationUnit> ensureResolvedDartUnits(Source unitSource) {
-    SourceEntry sourceEntry = _cache.get(unitSource);
-    if (sourceEntry is! DartEntry) {
-      return null;
-    }
-    DartEntry dartEntry = sourceEntry;
-    // Check every library.
-    List<CompilationUnit> units = <CompilationUnit>[];
-    List<Source> containingLibraries = dartEntry.containingLibraries;
-    for (Source librarySource in containingLibraries) {
-      CompilationUnit unit =
-          dartEntry.getValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource);
-      if (unit == null) {
-        units = null;
-        break;
-      }
-      units.add(unit);
-    }
-    // Invalidate the flushed RESOLVED_UNIT to force it eventually.
-    if (units == null) {
-      bool shouldBeScheduled = false;
-      for (Source librarySource in containingLibraries) {
-        if (dartEntry.getStateInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource) ==
-            CacheState.FLUSHED) {
-          dartEntry.setStateInLibrary(
-              DartEntry.RESOLVED_UNIT, librarySource, CacheState.INVALID);
-          shouldBeScheduled = true;
-        }
-      }
-      if (shouldBeScheduled) {
-        _workManager.add(unitSource, SourcePriority.UNKNOWN);
-      }
-      // We cannot provide resolved units right now,
-      // but the future analysis will.
-      return null;
-    }
-    // done
-    return units;
-  }
-
-  @override
-  bool exists(Source source) {
-    if (source == null) {
-      return false;
-    }
-    if (_contentCache.getContents(source) != null) {
-      return true;
-    }
-    return source.exists();
-  }
-
-  @override
-  cache.CacheEntry getCacheEntry(AnalysisTarget target) {
-    return null;
-  }
-
-  @override
-  CompilationUnitElement getCompilationUnitElement(
-      Source unitSource, Source librarySource) {
-    LibraryElement libraryElement = getLibraryElement(librarySource);
-    if (libraryElement != null) {
-      // try defining unit
-      CompilationUnitElement definingUnit =
-          libraryElement.definingCompilationUnit;
-      if (definingUnit.source == unitSource) {
-        return definingUnit;
-      }
-      // try parts
-      for (CompilationUnitElement partUnit in libraryElement.parts) {
-        if (partUnit.source == unitSource) {
-          return partUnit;
-        }
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object getConfigurationData(ResultDescriptor key) => _configurationData[key];
-
-  @override
-  TimestampedData<String> getContents(Source source) {
-    String contents = _contentCache.getContents(source);
-    if (contents != null) {
-      return new TimestampedData<String>(
-          _contentCache.getModificationStamp(source), contents);
-    }
-    return source.contents;
-  }
-
-  @override
-  InternalAnalysisContext getContextFor(Source source) {
-    InternalAnalysisContext context = _cache.getContextFor(source);
-    return context == null ? this : context;
-  }
-
-  @override
-  Element getElement(ElementLocation location) {
-    // TODO(brianwilkerson) This should not be a "get" method.
-    try {
-      List<String> components = location.components;
-      Source source = _computeSourceFromEncoding(components[0]);
-      String sourceName = source.shortName;
-      if (AnalysisEngine.isDartFileName(sourceName)) {
-        ElementImpl element = computeLibraryElement(source) as ElementImpl;
-        for (int i = 1; i < components.length; i++) {
-          if (element == null) {
-            return null;
-          }
-          element = element.getChild(components[i]);
-        }
-        return element;
-      }
-      if (AnalysisEngine.isHtmlFileName(sourceName)) {
-        return computeHtmlElement(source);
-      }
-    } catch (exception) {
-      // If the location cannot be decoded for some reason then the underlying
-      // cause should have been logged already and we can fall though to return
-      // null.
-    }
-    return null;
-  }
-
-  @override
-  AnalysisErrorInfo getErrors(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      return new AnalysisErrorInfoImpl(
-          dartEntry.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO));
-    } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      return new AnalysisErrorInfoImpl(
-          htmlEntry.allErrors, htmlEntry.getValue(SourceEntry.LINE_INFO));
-    }
-    return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
-  }
-
-  @override
-  @deprecated
-  HtmlElement getHtmlElement(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry is HtmlEntry) {
-      return sourceEntry.getValue(HtmlEntry.ELEMENT);
-    }
-    return null;
-  }
-
-  @override
-  List<Source> getHtmlFilesReferencing(Source source) {
-    SourceKind sourceKind = getKindOf(source);
-    if (sourceKind == null) {
-      return Source.EMPTY_LIST;
-    }
-    List<Source> htmlSources = new List<Source>();
-    while (true) {
-      if (sourceKind == SourceKind.PART) {
-        List<Source> librarySources = getLibrariesContaining(source);
-        MapIterator<Source, SourceEntry> partIterator = _cache.iterator();
-        while (partIterator.moveNext()) {
-          SourceEntry sourceEntry = partIterator.value;
-          if (sourceEntry.kind == SourceKind.HTML) {
-            List<Source> referencedLibraries = (sourceEntry as HtmlEntry)
-                .getValue(HtmlEntry.REFERENCED_LIBRARIES);
-            if (_containsAny(referencedLibraries, librarySources)) {
-              htmlSources.add(partIterator.key);
-            }
-          }
-        }
-      } else {
-        MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-        while (iterator.moveNext()) {
-          SourceEntry sourceEntry = iterator.value;
-          if (sourceEntry.kind == SourceKind.HTML) {
-            List<Source> referencedLibraries = (sourceEntry as HtmlEntry)
-                .getValue(HtmlEntry.REFERENCED_LIBRARIES);
-            if (_contains(referencedLibraries, source)) {
-              htmlSources.add(iterator.key);
-            }
-          }
-        }
-      }
-      break;
-    }
-    if (htmlSources.isEmpty) {
-      return Source.EMPTY_LIST;
-    }
-    return htmlSources;
-  }
-
-  @override
-  SourceKind getKindOf(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry == null) {
-      return SourceKind.UNKNOWN;
-    }
-    return sourceEntry.kind;
-  }
-
-  @override
-  List<Source> getLibrariesContaining(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry is DartEntry) {
-      return sourceEntry.containingLibraries;
-    }
-    return Source.EMPTY_LIST;
-  }
-
-  @override
-  List<Source> getLibrariesDependingOn(Source librarySource) {
-    List<Source> dependentLibraries = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      SourceEntry sourceEntry = iterator.value;
-      if (sourceEntry.kind == SourceKind.LIBRARY) {
-        if (_contains(
-            (sourceEntry as DartEntry).getValue(DartEntry.EXPORTED_LIBRARIES),
-            librarySource)) {
-          dependentLibraries.add(iterator.key);
-        }
-        if (_contains(
-            (sourceEntry as DartEntry).getValue(DartEntry.IMPORTED_LIBRARIES),
-            librarySource)) {
-          dependentLibraries.add(iterator.key);
-        }
-      }
-    }
-    if (dependentLibraries.isEmpty) {
-      return Source.EMPTY_LIST;
-    }
-    return dependentLibraries;
-  }
-
-  @override
-  List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(htmlSource);
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      return htmlEntry.getValue(HtmlEntry.REFERENCED_LIBRARIES);
-    }
-    return Source.EMPTY_LIST;
-  }
-
-  @override
-  LibraryElement getLibraryElement(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry is DartEntry) {
-      return sourceEntry.getValue(DartEntry.ELEMENT);
-    }
-    return null;
-  }
-
-  @override
-  LineInfo getLineInfo(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry != null) {
-      return sourceEntry.getValue(SourceEntry.LINE_INFO);
-    }
-    return null;
-  }
-
-  @override
-  int getModificationStamp(Source source) {
-    int stamp = _contentCache.getModificationStamp(source);
-    if (stamp != null) {
-      return stamp;
-    }
-    return source.modificationStamp;
-  }
-
-  @override
-  ChangeNoticeImpl getNotice(Source source) {
-    ChangeNoticeImpl notice = _pendingNotices[source];
-    if (notice == null) {
-      notice = new ChangeNoticeImpl(source);
-      _pendingNotices[source] = notice;
-    }
-    return notice;
-  }
-
-  @override
-  Namespace getPublicNamespace(LibraryElement library) {
-    // TODO(brianwilkerson) Rename this to not start with 'get'.
-    // Note that this is not part of the API of the interface.
-    Source source = library.definingCompilationUnit.source;
-    DartEntry dartEntry = _getReadableDartEntry(source);
-    if (dartEntry == null) {
-      return null;
-    }
-    Namespace namespace = null;
-    if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
-      namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
-    }
-    if (namespace == null) {
-      NamespaceBuilder builder = new NamespaceBuilder();
-      namespace = builder.createPublicNamespaceForLibrary(library);
-      if (dartEntry == null) {
-        AnalysisEngine.instance.logger.logError(
-            "Could not compute the public namespace for ${library.source.fullName}",
-            new CaughtException(
-                new AnalysisException(
-                    "A Dart file became a non-Dart file: ${source.fullName}"),
-                null));
-        return null;
-      }
-      if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
-        dartEntry.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
-      }
-    }
-    return namespace;
-  }
-
-  /**
-   * Return the cache entry associated with the given [source], or `null` if
-   * there is no entry associated with the source.
-   */
-  SourceEntry getReadableSourceEntryOrNull(Source source) => _cache.get(source);
-
-  @override
-  CompilationUnit getResolvedCompilationUnit(
-      Source unitSource, LibraryElement library) {
-    if (library == null) {
-      return null;
-    }
-    return getResolvedCompilationUnit2(unitSource, library.source);
-  }
-
-  @override
-  CompilationUnit getResolvedCompilationUnit2(
-      Source unitSource, Source librarySource) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(unitSource);
-    if (sourceEntry is DartEntry) {
-      return sourceEntry.getValueInLibrary(
-          DartEntry.RESOLVED_UNIT, librarySource);
-    }
-    return null;
-  }
-
-  @override
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(htmlSource);
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      return htmlEntry.getValue(HtmlEntry.RESOLVED_UNIT);
-    }
-    return null;
-  }
-
-  @override
-  Object getResult(AnalysisTarget target, ResultDescriptor result) {
-    return result.defaultValue;
-  }
-
-  @override
-  List<Source> getSourcesWithFullName(String path) {
-    List<Source> sources = <Source>[];
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      if (iterator.key.fullName == path) {
-        sources.add(iterator.key);
-      }
-    }
-    return sources;
-  }
-
-  @override
-  bool handleContentsChanged(
-      Source source, String originalContents, String newContents, bool notify) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      return false;
-    }
-    bool changed = newContents != originalContents;
-    if (newContents != null) {
-      if (changed) {
-        _incrementalAnalysisCache =
-            IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
-        if (!analysisOptions.incremental ||
-            !_tryPoorMansIncrementalResolution(source, newContents)) {
-          _sourceChanged(source);
-        }
-        sourceEntry.modificationTime =
-            _contentCache.getModificationStamp(source);
-        sourceEntry.setValue(SourceEntry.CONTENT, newContents);
-      } else {
-        sourceEntry.modificationTime =
-            _contentCache.getModificationStamp(source);
-      }
-    } else if (originalContents != null) {
-      _incrementalAnalysisCache =
-          IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
-      // We are removing the overlay for the file, check if the file's
-      // contents is the same as it was in the overlay.
-      try {
-        TimestampedData<String> fileContents = getContents(source);
-        newContents = fileContents.data;
-        sourceEntry.modificationTime = fileContents.modificationTime;
-        if (newContents == originalContents) {
-          sourceEntry.setValue(SourceEntry.CONTENT, newContents);
-          changed = false;
-        }
-      } catch (e) {}
-      // If not the same content (e.g. the file is being closed without save),
-      // then force analysis.
-      if (changed) {
-        if (!analysisOptions.incremental ||
-            !_tryPoorMansIncrementalResolution(source, newContents)) {
-          _sourceChanged(source);
-        }
-      }
-    }
-    if (notify && changed) {
-      _onSourcesChangedController
-          .add(new SourcesChangedEvent.changedContent(source, newContents));
-    }
-    return changed;
-  }
-
-  @override
-  void invalidateLibraryHints(Source librarySource) {
-    SourceEntry sourceEntry = _cache.get(librarySource);
-    if (sourceEntry is! DartEntry) {
-      return;
-    }
-    DartEntry dartEntry = sourceEntry;
-    // Prepare sources to invalidate hints in.
-    List<Source> sources = <Source>[librarySource];
-    sources.addAll(dartEntry.getValue(DartEntry.INCLUDED_PARTS));
-    // Invalidate hints and lints.
-    for (Source source in sources) {
-      DartEntry dartEntry = _cache.get(source);
-      if (dartEntry.getStateInLibrary(DartEntry.HINTS, librarySource) ==
-          CacheState.VALID) {
-        dartEntry.setStateInLibrary(
-            DartEntry.HINTS, librarySource, CacheState.INVALID);
-      }
-      if (dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource) ==
-          CacheState.VALID) {
-        dartEntry.setStateInLibrary(
-            DartEntry.LINTS, librarySource, CacheState.INVALID);
-      }
-    }
-  }
-
-  @override
-  bool isClientLibrary(Source librarySource) {
-    SourceEntry sourceEntry = _getReadableSourceEntry(librarySource);
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      return dartEntry.getValue(DartEntry.IS_CLIENT) &&
-          dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
-    }
-    return false;
-  }
-
-  @override
-  bool isServerLibrary(Source librarySource) {
-    SourceEntry sourceEntry = _getReadableSourceEntry(librarySource);
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      return !dartEntry.getValue(DartEntry.IS_CLIENT) &&
-          dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
-    }
-    return false;
-  }
-
-  @override
-  Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
-    throw new NotImplementedException('In not task-based AnalysisContext.');
-  }
-
-  @override
-  CompilationUnit parseCompilationUnit(Source source) =>
-      _getDartParseData2(source, DartEntry.PARSED_UNIT, null);
-
-  @override
-  Document parseHtmlDocument(Source source) {
-    return null;
-  }
-
-  @override
-  @deprecated
-  ht.HtmlUnit parseHtmlUnit(Source source) =>
-      _getHtmlParseData(source, HtmlEntry.PARSED_UNIT, null);
-
-  @override
-  AnalysisResult performAnalysisTask() {
-    if (_TRACE_PERFORM_TASK) {
-      print("----------------------------------------");
-    }
-    return PerformanceStatistics.performAnaysis.makeCurrentWhile(() {
-      int getStart = JavaSystem.currentTimeMillis();
-      AnalysisTask task = PerformanceStatistics.nextTask
-          .makeCurrentWhile(() => nextAnalysisTask);
-      int getEnd = JavaSystem.currentTimeMillis();
-      if (task == null) {
-        _validateLastIncrementalResolutionResult();
-        if (_performAnalysisTaskStopwatch != null) {
-          AnalysisEngine.instance.instrumentationService.logPerformance(
-              AnalysisPerformanceKind.FULL,
-              _performAnalysisTaskStopwatch,
-              'context_id=$_id');
-          _performAnalysisTaskStopwatch = null;
-        }
-        return new AnalysisResult(
-            _getChangeNotices(true), getEnd - getStart, null, -1);
-      }
-      if (_performAnalysisTaskStopwatch == null) {
-        _performAnalysisTaskStopwatch = new Stopwatch()..start();
-      }
-      String taskDescription = task.toString();
-      _notifyAboutToPerformTask(taskDescription);
-      if (_TRACE_PERFORM_TASK) {
-        print(taskDescription);
-      }
-      int performStart = JavaSystem.currentTimeMillis();
-      try {
-        task.perform(_resultRecorder);
-      } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logInformation(
-            "Could not perform analysis task: $taskDescription",
-            new CaughtException(exception, stackTrace));
-      } on AnalysisException catch (exception, stackTrace) {
-        if (exception.cause is! JavaIOException) {
-          AnalysisEngine.instance.logger.logError(
-              "Internal error while performing the task: $task",
-              new CaughtException(exception, stackTrace));
-        }
-      }
-      int performEnd = JavaSystem.currentTimeMillis();
-      List<ChangeNotice> notices = _getChangeNotices(false);
-      int noticeCount = notices.length;
-      for (int i = 0; i < noticeCount; i++) {
-        ChangeNotice notice = notices[i];
-        Source source = notice.source;
-        // TODO(brianwilkerson) Figure out whether the compilation unit is
-        // always resolved, or whether we need to decide whether to invoke the
-        // "parsed" or "resolved" method. This might be better done when
-        // recording task results in order to reduce the chance of errors.
-//        if (notice.getCompilationUnit() != null) {
-//          notifyResolvedDart(source, notice.getCompilationUnit());
-//        } else if (notice.getHtmlUnit() != null) {
-//          notifyResolvedHtml(source, notice.getHtmlUnit());
-//        }
-        _notifyErrors(source, notice.errors, notice.lineInfo);
-      }
-      return new AnalysisResult(notices, getEnd - getStart,
-          task.runtimeType.toString(), performEnd - performStart);
-    });
-  }
-
-  @override
-  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
-    Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
-    elementMap.forEach((Source librarySource, LibraryElement library) {
-      //
-      // Cache the element in the library's info.
-      //
-      DartEntry dartEntry = _getReadableDartEntry(librarySource);
-      if (dartEntry != null) {
-        _recordElementData(dartEntry, library, library.source, htmlSource);
-        dartEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
-        dartEntry.setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
-        // DartEntry.ELEMENT - set in recordElementData
-        dartEntry.setValue(DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_LIST);
-        dartEntry.setValue(DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_LIST);
-        dartEntry.setValue(DartEntry.INCLUDED_PARTS, Source.EMPTY_LIST);
-        // DartEntry.IS_CLIENT - set in recordElementData
-        // DartEntry.IS_LAUNCHABLE - set in recordElementData
-        dartEntry.setValue(DartEntry.PARSE_ERRORS, AnalysisError.NO_ERRORS);
-        dartEntry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-        dartEntry.setState(DartEntry.PUBLIC_NAMESPACE, CacheState.FLUSHED);
-        dartEntry.setValue(DartEntry.SCAN_ERRORS, AnalysisError.NO_ERRORS);
-        dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
-        dartEntry.setState(DartEntry.TOKEN_STREAM, CacheState.FLUSHED);
-        dartEntry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource,
-            AnalysisError.NO_ERRORS);
-        dartEntry.setStateInLibrary(
-            DartEntry.RESOLVED_UNIT, librarySource, CacheState.FLUSHED);
-        dartEntry.setValueInLibrary(DartEntry.VERIFICATION_ERRORS,
-            librarySource, AnalysisError.NO_ERRORS);
-        dartEntry.setValueInLibrary(
-            DartEntry.HINTS, librarySource, AnalysisError.NO_ERRORS);
-        dartEntry.setValueInLibrary(
-            DartEntry.LINTS, librarySource, AnalysisError.NO_ERRORS);
-      }
-    });
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry recordResolveDartLibraryCycleTaskResults(
-      ResolveDartLibraryCycleTask task) {
-    LibraryResolver2 resolver = task.libraryResolver;
-    CaughtException thrownException = task.exception;
-    Source unitSource = task.unitSource;
-    DartEntry unitEntry = _getReadableDartEntry(unitSource);
-    if (resolver != null) {
-      //
-      // The resolver should only be null if an exception was thrown before (or
-      // while) it was being created.
-      //
-      List<ResolvableLibrary> resolvedLibraries = resolver.resolvedLibraries;
-      if (resolvedLibraries == null) {
-        //
-        // The resolved libraries should only be null if an exception was thrown
-        // during resolution.
-        //
-        if (thrownException == null) {
-          var message = "In recordResolveDartLibraryCycleTaskResults, "
-              "resolvedLibraries was null and there was no thrown exception";
-          unitEntry.recordResolutionError(
-              new CaughtException(new AnalysisException(message), null));
-        } else {
-          unitEntry.recordResolutionError(thrownException);
-        }
-        _removeFromCache(unitSource);
-        if (thrownException != null) {
-          throw new AnalysisException('<rethrow>', thrownException);
-        }
-        return unitEntry;
-      }
-      Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
-      RecordingErrorListener errorListener = resolver.errorListener;
-      for (ResolvableLibrary library in resolvedLibraries) {
-        Source librarySource = library.librarySource;
-        for (Source source in library.compilationUnitSources) {
-          CompilationUnit unit = library.getAST(source);
-          List<AnalysisError> errors = errorListener.getErrorsForSource(source);
-          LineInfo lineInfo = getLineInfo(source);
-          DartEntry dartEntry = _cache.get(source);
-          if (thrownException == null) {
-            dartEntry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-            dartEntry.setValueInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource, unit);
-            dartEntry.setValueInLibrary(
-                DartEntry.RESOLUTION_ERRORS, librarySource, errors);
-            if (source == librarySource) {
-              _recordElementData(
-                  dartEntry, library.libraryElement, librarySource, htmlSource);
-            }
-            _cache.storedAst(source);
-          } else {
-            dartEntry.recordResolutionErrorInLibrary(
-                librarySource, thrownException);
-          }
-          if (source != librarySource) {
-            _workManager.add(source, SourcePriority.PRIORITY_PART);
-          }
-          ChangeNoticeImpl notice = getNotice(source);
-          notice.resolvedDartUnit = unit;
-          notice.setErrors(dartEntry.allErrors, lineInfo);
-        }
-      }
-    }
-    if (thrownException != null) {
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    return unitEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
-    LibraryResolver resolver = task.libraryResolver;
-    CaughtException thrownException = task.exception;
-    Source unitSource = task.unitSource;
-    DartEntry unitEntry = _getReadableDartEntry(unitSource);
-    if (resolver != null) {
-      //
-      // The resolver should only be null if an exception was thrown before (or
-      // while) it was being created.
-      //
-      Set<Library> resolvedLibraries = resolver.resolvedLibraries;
-      if (resolvedLibraries == null) {
-        //
-        // The resolved libraries should only be null if an exception was thrown
-        // during resolution.
-        //
-        if (thrownException == null) {
-          String message = "In recordResolveDartLibraryTaskResults, "
-              "resolvedLibraries was null and there was no thrown exception";
-          unitEntry.recordResolutionError(
-              new CaughtException(new AnalysisException(message), null));
-        } else {
-          unitEntry.recordResolutionError(thrownException);
-        }
-        _removeFromCache(unitSource);
-        if (thrownException != null) {
-          throw new AnalysisException('<rethrow>', thrownException);
-        }
-        return unitEntry;
-      }
-      Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
-      RecordingErrorListener errorListener = resolver.errorListener;
-      for (Library library in resolvedLibraries) {
-        Source librarySource = library.librarySource;
-        for (Source source in library.compilationUnitSources) {
-          CompilationUnit unit = library.getAST(source);
-          List<AnalysisError> errors = errorListener.getErrorsForSource(source);
-          LineInfo lineInfo = getLineInfo(source);
-          DartEntry dartEntry = _cache.get(source);
-          if (thrownException == null) {
-            dartEntry.setValue(SourceEntry.LINE_INFO, lineInfo);
-            dartEntry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-            dartEntry.setValueInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource, unit);
-            dartEntry.setValueInLibrary(
-                DartEntry.RESOLUTION_ERRORS, librarySource, errors);
-            if (source == librarySource) {
-              _recordElementData(
-                  dartEntry, library.libraryElement, librarySource, htmlSource);
-            }
-            _cache.storedAst(source);
-          } else {
-            dartEntry.recordResolutionErrorInLibrary(
-                librarySource, thrownException);
-            _removeFromCache(source);
-          }
-          if (source != librarySource) {
-            _workManager.add(source, SourcePriority.PRIORITY_PART);
-          }
-          ChangeNoticeImpl notice = getNotice(source);
-          notice.resolvedDartUnit = unit;
-          notice.setErrors(dartEntry.allErrors, lineInfo);
-        }
-      }
-    }
-    if (thrownException != null) {
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    return unitEntry;
-  }
-
-  @override
-  void removeListener(AnalysisListener listener) {
-    _listeners.remove(listener);
-  }
-
-  @override
-  CompilationUnit resolveCompilationUnit(
-      Source unitSource, LibraryElement library) {
-    if (library == null) {
-      return null;
-    }
-    return resolveCompilationUnit2(unitSource, library.source);
-  }
-
-  @override
-  CompilationUnit resolveCompilationUnit2(
-          Source unitSource, Source librarySource) =>
-      _getDartResolutionData2(
-          unitSource, librarySource, DartEntry.RESOLVED_UNIT, null);
-
-  @override
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
-    computeHtmlElement(htmlSource);
-    return parseHtmlUnit(htmlSource);
-  }
-
-  @override
-  void setChangedContents(Source source, String contents, int offset,
-      int oldLength, int newLength) {
-    if (_contentRangeChanged(source, contents, offset, oldLength, newLength)) {
-      _onSourcesChangedController.add(new SourcesChangedEvent.changedRange(
-          source, contents, offset, oldLength, newLength));
-    }
-  }
-
-  @override
-  void setConfigurationData(ResultDescriptor key, Object data) {
-    _configurationData[key] = data;
-  }
-
-  @override
-  void setContents(Source source, String contents) {
-    _contentsChanged(source, contents, true);
-  }
-
-  @override
-  bool shouldErrorsBeAnalyzed(Source source, Object entry) {
-    DartEntry dartEntry = entry;
-    if (source.isInSystemLibrary) {
-      return _generateSdkErrors;
-    } else if (!dartEntry.explicitlyAdded) {
-      return _generateImplicitErrors;
-    } else {
-      return true;
-    }
-  }
-
-  @override
-  void test_flushAstStructures(Source source) {
-    DartEntry dartEntry = getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-  }
-
-  @override
-  bool validateCacheConsistency() {
-    int consistencyCheckStart = JavaSystem.nanoTime();
-    List<Source> changedSources = new List<Source>();
-    List<Source> missingSources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      int sourceTime = getModificationStamp(source);
-      if (sourceTime != sourceEntry.modificationTime) {
-        changedSources.add(source);
-      }
-      if (sourceEntry.exception != null) {
-        if (!exists(source)) {
-          missingSources.add(source);
-        }
-      }
-    }
-    int count = changedSources.length;
-    for (int i = 0; i < count; i++) {
-      _sourceChanged(changedSources[i]);
-    }
-    int removalCount = 0;
-    for (Source source in missingSources) {
-      if (getLibrariesContaining(source).isEmpty &&
-          getLibrariesDependingOn(source).isEmpty) {
-        _removeFromCache(source);
-        removalCount++;
-      }
-    }
-    int consistencyCheckEnd = JavaSystem.nanoTime();
-    if (changedSources.length > 0 || missingSources.length > 0) {
-      StringBuffer buffer = new StringBuffer();
-      buffer.write("Consistency check took ");
-      buffer.write((consistencyCheckEnd - consistencyCheckStart) / 1000000.0);
-      buffer.writeln(" ms and found");
-      buffer.write("  ");
-      buffer.write(changedSources.length);
-      buffer.writeln(" inconsistent entries");
-      buffer.write("  ");
-      buffer.write(missingSources.length);
-      buffer.write(" missing sources (");
-      buffer.write(removalCount);
-      buffer.writeln(" removed");
-      for (Source source in missingSources) {
-        buffer.write("    ");
-        buffer.writeln(source.fullName);
-      }
-      _logInformation(buffer.toString());
-    }
-    return changedSources.length > 0;
-  }
-
-  @deprecated
-  @override
-  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state)) {
-    bool hintsEnabled = _options.hint;
-    bool lintsEnabled = _options.lint;
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      for (DataDescriptor descriptor in sourceEntry.descriptors) {
-        if (descriptor == DartEntry.SOURCE_KIND) {
-          // The source kind is always valid, so the state isn't interesting.
-          continue;
-        } else if (descriptor == DartEntry.CONTAINING_LIBRARIES) {
-          // The list of containing libraries is always valid, so the state
-          // isn't interesting.
-          continue;
-        } else if (descriptor == DartEntry.PUBLIC_NAMESPACE) {
-          // The public namespace isn't computed by performAnalysisTask()
-          // and therefore isn't interesting.
-          continue;
-        } else if (descriptor == HtmlEntry.HINTS) {
-          // We are not currently recording any hints related to HTML.
-          continue;
-        }
-        callback(
-            source, sourceEntry, descriptor, sourceEntry.getState(descriptor));
-      }
-      if (sourceEntry is DartEntry) {
-        // get library-specific values
-        List<Source> librarySources = getLibrariesContaining(source);
-        for (Source librarySource in librarySources) {
-          for (DataDescriptor descriptor in sourceEntry.libraryDescriptors) {
-            if (descriptor == DartEntry.BUILT_ELEMENT ||
-                descriptor == DartEntry.BUILT_UNIT) {
-              // These values are not currently being computed, so their state
-              // is not interesting.
-              continue;
-            } else if (!sourceEntry.explicitlyAdded &&
-                !_generateImplicitErrors &&
-                (descriptor == DartEntry.VERIFICATION_ERRORS ||
-                    descriptor == DartEntry.HINTS ||
-                    descriptor == DartEntry.LINTS)) {
-              continue;
-            } else if (source.isInSystemLibrary &&
-                !_generateSdkErrors &&
-                (descriptor == DartEntry.VERIFICATION_ERRORS ||
-                    descriptor == DartEntry.HINTS ||
-                    descriptor == DartEntry.LINTS)) {
-              continue;
-            } else if (!hintsEnabled && descriptor == DartEntry.HINTS) {
-              continue;
-            } else if (!lintsEnabled && descriptor == DartEntry.LINTS) {
-              continue;
-            }
-            callback(librarySource, sourceEntry, descriptor,
-                sourceEntry.getStateInLibrary(descriptor, librarySource));
-          }
-        }
-      }
-    }
-  }
-
-  @override
-  void visitContentCache(ContentCacheVisitor visitor) {
-    _contentCache.accept(visitor);
-  }
-
-  /**
-   * Record that we have accessed the AST structure associated with the given
-   * [source]. At the moment, there is no differentiation between the parsed and
-   * resolved forms of the AST.
-   */
-  void _accessedAst(Source source) {
-    _cache.accessedAst(source);
-  }
-
-  /**
-   * Add all of the sources contained in the given source [container] to the
-   * given list of [sources].
-   */
-  void _addSourcesInContainer(List<Source> sources, SourceContainer container) {
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      if (container.contains(source)) {
-        sources.add(source);
-      }
-    }
-  }
-
-  /**
-   * Given the [unitSource] of a Dart file and the [librarySource] of the
-   * library that contains it, return a cache entry in which the state of the
-   * data represented by the given [descriptor] is either [CacheState.VALID] or
-   * [CacheState.ERROR]. This method assumes that the data can be produced by
-   * generating hints for the library if the data is not already cached. The
-   * [dartEntry] is the cache entry associated with the Dart file.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be parsed.
-   */
-  DartEntry _cacheDartHintData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information.
-      // Unless the modification date of the source continues to change,
-      // this loop will eventually terminate.
-      //
-      DartEntry libraryEntry = _getReadableDartEntry(librarySource);
-      libraryEntry = _cacheDartResolutionData(
-          librarySource, librarySource, libraryEntry, DartEntry.ELEMENT);
-      LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-      CompilationUnitElement definingUnit =
-          libraryElement.definingCompilationUnit;
-      List<CompilationUnitElement> parts = libraryElement.parts;
-      List<TimestampedData<CompilationUnit>> units =
-          new List<TimestampedData<CompilationUnit>>(parts.length + 1);
-      units[0] = _getResolvedUnit(definingUnit, librarySource);
-      if (units[0] == null) {
-        Source source = definingUnit.source;
-        units[0] = new TimestampedData<CompilationUnit>(
-            getModificationStamp(source),
-            resolveCompilationUnit(source, libraryElement));
-      }
-      for (int i = 0; i < parts.length; i++) {
-        units[i + 1] = _getResolvedUnit(parts[i], librarySource);
-        if (units[i + 1] == null) {
-          Source source = parts[i].source;
-          units[i + 1] = new TimestampedData<CompilationUnit>(
-              getModificationStamp(source),
-              resolveCompilationUnit(source, libraryElement));
-        }
-      }
-      dartEntry = new GenerateDartHintsTask(
-              this, units, getLibraryElement(librarySource))
-          .perform(_resultRecorder) as DartEntry;
-      state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return a
-   * cache entry in which the state of the data represented by the given
-   * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
-   * assumes that the data can be produced by generating lints for the library
-   * if the data is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartLintData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information.
-      // Unless the modification date of the source continues to change,
-      // this loop will eventually terminate.
-      //
-      DartEntry libraryEntry = _getReadableDartEntry(librarySource);
-      libraryEntry = _cacheDartResolutionData(
-          librarySource, librarySource, libraryEntry, DartEntry.ELEMENT);
-      LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-      CompilationUnitElement definingUnit =
-          libraryElement.definingCompilationUnit;
-      List<CompilationUnitElement> parts = libraryElement.parts;
-      List<TimestampedData<CompilationUnit>> units =
-          new List<TimestampedData<CompilationUnit>>(parts.length + 1);
-      units[0] = _getResolvedUnit(definingUnit, librarySource);
-      if (units[0] == null) {
-        Source source = definingUnit.source;
-        units[0] = new TimestampedData<CompilationUnit>(
-            getModificationStamp(source),
-            resolveCompilationUnit(source, libraryElement));
-      }
-      for (int i = 0; i < parts.length; i++) {
-        units[i + 1] = _getResolvedUnit(parts[i], librarySource);
-        if (units[i + 1] == null) {
-          Source source = parts[i].source;
-          units[i + 1] = new TimestampedData<CompilationUnit>(
-              getModificationStamp(source),
-              resolveCompilationUnit(source, libraryElement));
-        }
-      }
-      //TODO(pquitslund): revisit if we need all units or whether one will do
-      dartEntry = new GenerateDartLintsTask(
-              this, units, getLibraryElement(librarySource))
-          .perform(_resultRecorder) as DartEntry;
-      state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file, return a cache entry in which the state of
-   * the data represented by the given descriptor is either [CacheState.VALID]
-   * or [CacheState.ERROR]. This method assumes that the data can be produced by
-   * parsing the source if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartParseData(
-      Source source, DartEntry dartEntry, DataDescriptor descriptor) {
-    if (identical(descriptor, DartEntry.PARSED_UNIT)) {
-      if (dartEntry.hasResolvableCompilationUnit) {
-        return dartEntry;
-      }
-    }
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getState(descriptor);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      dartEntry = _cacheDartScanData(source, dartEntry, DartEntry.TOKEN_STREAM);
-      dartEntry = new ParseDartTask(
-              this,
-              source,
-              dartEntry.getValue(DartEntry.TOKEN_STREAM),
-              dartEntry.getValue(SourceEntry.LINE_INFO))
-          .perform(_resultRecorder) as DartEntry;
-      state = dartEntry.getState(descriptor);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return a
-   * cache entry in which the state of the data represented by the given
-   * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
-   * assumes that the data can be produced by resolving the source in the
-   * context of the library if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartResolutionData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = (identical(descriptor, DartEntry.ELEMENT))
-        ? dartEntry.getState(descriptor)
-        : dartEntry.getStateInLibrary(descriptor, librarySource);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      // TODO(brianwilkerson) As an optimization, if we already have the
-      // element model for the library we can use ResolveDartUnitTask to produce
-      // the resolved AST structure much faster.
-      dartEntry = new ResolveDartLibraryTask(this, unitSource, librarySource)
-          .perform(_resultRecorder) as DartEntry;
-      state = (identical(descriptor, DartEntry.ELEMENT))
-          ? dartEntry.getState(descriptor)
-          : dartEntry.getStateInLibrary(descriptor, librarySource);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file, return a cache entry in which the state of
-   * the data represented by the given descriptor is either [CacheState.VALID]
-   * or [CacheState.ERROR]. This method assumes that the data can be produced by
-   * scanning the source if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartScanData(
-      Source source, DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getState(descriptor);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      try {
-        if (dartEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
-          dartEntry = new GetContentTask(this, source).perform(_resultRecorder)
-              as DartEntry;
-        }
-        dartEntry = new ScanDartTask(
-                this, source, dartEntry.getValue(SourceEntry.CONTENT))
-            .perform(_resultRecorder) as DartEntry;
-      } on AnalysisException catch (exception) {
-        throw exception;
-      } catch (exception, stackTrace) {
-        throw new AnalysisException(
-            "Exception", new CaughtException(exception, stackTrace));
-      }
-      state = dartEntry.getState(descriptor);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return a
-   * cache entry in which the state of the data represented by the given
-   * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
-   * assumes that the data can be produced by verifying the source in the given
-   * library if the data is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartVerificationData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      LibraryElement library = computeLibraryElement(librarySource);
-      CompilationUnit unit = resolveCompilationUnit(unitSource, library);
-      if (unit == null) {
-        throw new AnalysisException(
-            "Could not resolve compilation unit ${unitSource.fullName} in ${librarySource.fullName}");
-      }
-      dartEntry = new GenerateDartErrorsTask(this, unitSource, unit, library)
-          .perform(_resultRecorder) as DartEntry;
-      state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for an HTML file, return a cache entry in which all of the
-   * data represented by the state of the given descriptors is either
-   * [CacheState.VALID] or [CacheState.ERROR]. This method assumes that the data
-   * can be produced by parsing the source if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  HtmlEntry _cacheHtmlParseData(
-      Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
-    if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
-      ht.HtmlUnit unit = htmlEntry.anyParsedUnit;
-      if (unit != null) {
-        return htmlEntry;
-      }
-    }
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = htmlEntry.getState(descriptor);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      try {
-        if (htmlEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
-          htmlEntry = new GetContentTask(this, source).perform(_resultRecorder)
-              as HtmlEntry;
-        }
-        htmlEntry = new ParseHtmlTask(
-                this, source, htmlEntry.getValue(SourceEntry.CONTENT))
-            .perform(_resultRecorder) as HtmlEntry;
-      } on AnalysisException catch (exception) {
-        throw exception;
-      } catch (exception, stackTrace) {
-        throw new AnalysisException(
-            "Exception", new CaughtException(exception, stackTrace));
-      }
-      state = htmlEntry.getState(descriptor);
-    }
-    return htmlEntry;
-  }
-
-  /**
-   * Given a source for an HTML file, return a cache entry in which the state of
-   * the data represented by the given descriptor is either [CacheState.VALID]
-   * or [CacheState.ERROR]. This method assumes that the data can be produced by
-   * resolving the source if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  HtmlEntry _cacheHtmlResolutionData(
-      Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = htmlEntry.getState(descriptor);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      htmlEntry = _cacheHtmlParseData(source, htmlEntry, HtmlEntry.PARSED_UNIT);
-      htmlEntry = new ResolveHtmlTask(this, source, htmlEntry.modificationTime,
-              htmlEntry.getValue(HtmlEntry.PARSED_UNIT))
-          .perform(_resultRecorder) as HtmlEntry;
-      state = htmlEntry.getState(descriptor);
-    }
-    return htmlEntry;
-  }
-
-  /**
-   * Remove the given [pendingFuture] from [_pendingFutureSources], since the
-   * client has indicated its computation is not needed anymore.
-   */
-  void _cancelFuture(PendingFuture pendingFuture) {
-    List<PendingFuture> pendingFutures =
-        _pendingFutureSources[pendingFuture.source];
-    if (pendingFutures != null) {
-      pendingFutures.remove(pendingFuture);
-      if (pendingFutures.isEmpty) {
-        _pendingFutureSources.remove(pendingFuture.source);
-      }
-    }
-  }
-
-  /**
-   * Compute the transitive closure of all libraries that depend on the given
-   * [library] by adding such libraries to the given collection of
-   * [librariesToInvalidate].
-   */
-  void _computeAllLibrariesDependingOn(
-      Source library, HashSet<Source> librariesToInvalidate) {
-    if (librariesToInvalidate.add(library)) {
-      for (Source dependentLibrary in getLibrariesDependingOn(library)) {
-        _computeAllLibrariesDependingOn(
-            dependentLibrary, librariesToInvalidate);
-      }
-    }
-  }
-
-  /**
-   * Return the priority that should be used when the source associated with
-   * the given [dartEntry] is added to the work manager.
-   */
-  SourcePriority _computePriority(DartEntry dartEntry) {
-    SourceKind kind = dartEntry.kind;
-    if (kind == SourceKind.LIBRARY) {
-      return SourcePriority.LIBRARY;
-    } else if (kind == SourceKind.PART) {
-      return SourcePriority.NORMAL_PART;
-    }
-    return SourcePriority.UNKNOWN;
-  }
-
-  /**
-   * Given the encoded form of a source ([encoding]), use the source factory to
-   * reconstitute the original source.
-   */
-  Source _computeSourceFromEncoding(String encoding) =>
-      _sourceFactory.fromEncoding(encoding);
-
-  /**
-   * Return `true` if the given list of [sources] contains the given
-   * [targetSource].
-   */
-  bool _contains(List<Source> sources, Source targetSource) {
-    for (Source source in sources) {
-      if (source == targetSource) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if the given list of [sources] contains any of the given
-   * [targetSources].
-   */
-  bool _containsAny(List<Source> sources, List<Source> targetSources) {
-    for (Source targetSource in targetSources) {
-      if (_contains(sources, targetSource)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Set the contents of the given [source] to the given [contents] and mark the
-   * source as having changed. The additional [offset], [oldLength] and
-   * [newLength] information is used by the context to determine what reanalysis
-   * is necessary. The method [setChangedContents] triggers a source changed
-   * event where as this method does not.
-   */
-  bool _contentRangeChanged(Source source, String contents, int offset,
-      int oldLength, int newLength) {
-    bool changed = false;
-    String originalContents = _contentCache.setContents(source, contents);
-    if (contents != null) {
-      if (contents != originalContents) {
-        if (_options.incremental) {
-          _incrementalAnalysisCache = IncrementalAnalysisCache.update(
-              _incrementalAnalysisCache,
-              source,
-              originalContents,
-              contents,
-              offset,
-              oldLength,
-              newLength,
-              _getReadableSourceEntry(source));
-        }
-        _sourceChanged(source);
-        changed = true;
-        SourceEntry sourceEntry = _cache.get(source);
-        if (sourceEntry != null) {
-          sourceEntry.modificationTime =
-              _contentCache.getModificationStamp(source);
-          sourceEntry.setValue(SourceEntry.CONTENT, contents);
-        }
-      }
-    } else if (originalContents != null) {
-      _incrementalAnalysisCache =
-          IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
-      _sourceChanged(source);
-      changed = true;
-    }
-    return changed;
-  }
-
-  /**
-   * Set the contents of the given [source] to the given [contents] and mark the
-   * source as having changed. This has the effect of overriding the default
-   * contents of the source. If the contents are `null` the override is removed
-   * so that the default contents will be returned. If [notify] is true, a
-   * source changed event is triggered.
-   */
-  void _contentsChanged(Source source, String contents, bool notify) {
-    String originalContents = _contentCache.setContents(source, contents);
-    handleContentsChanged(source, originalContents, contents, notify);
-  }
-
-  /**
-   * Create a [GenerateDartErrorsTask] for the given [unitSource], marking the
-   * verification errors as being in-process. The compilation unit and the
-   * library can be the same if the compilation unit is the defining compilation
-   * unit of the library.
-   */
-  AnalysisContextImpl_TaskData _createGenerateDartErrorsTask(Source unitSource,
-      DartEntry unitEntry, Source librarySource, DartEntry libraryEntry) {
-    if (unitEntry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource) !=
-            CacheState.VALID ||
-        libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) {
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    CompilationUnit unit =
-        unitEntry.getValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource);
-    if (unit == null) {
-      CaughtException exception = new CaughtException(
-          new AnalysisException(
-              "Entry has VALID state for RESOLVED_UNIT but null value for ${unitSource.fullName} in ${librarySource.fullName}"),
-          null);
-      AnalysisEngine.instance.logger
-          .logInformation(exception.toString(), exception);
-      unitEntry.recordResolutionError(exception);
-      return new AnalysisContextImpl_TaskData(null, false);
-    }
-    LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-    return new AnalysisContextImpl_TaskData(
-        new GenerateDartErrorsTask(this, unitSource, unit, libraryElement),
-        false);
-  }
-
-  /**
-   * Create a [GenerateDartHintsTask] for the given [source], marking the hints
-   * as being in-process.
-   */
-  AnalysisContextImpl_TaskData _createGenerateDartHintsTask(Source source,
-      DartEntry dartEntry, Source librarySource, DartEntry libraryEntry) {
-    if (libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) {
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-    CompilationUnitElement definingUnit =
-        libraryElement.definingCompilationUnit;
-    List<CompilationUnitElement> parts = libraryElement.parts;
-    List<TimestampedData<CompilationUnit>> units =
-        new List<TimestampedData<CompilationUnit>>(parts.length + 1);
-    units[0] = _getResolvedUnit(definingUnit, librarySource);
-    if (units[0] == null) {
-      // TODO(brianwilkerson) We should return a ResolveDartUnitTask
-      // (unless there are multiple ASTs that need to be resolved).
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    for (int i = 0; i < parts.length; i++) {
-      units[i + 1] = _getResolvedUnit(parts[i], librarySource);
-      if (units[i + 1] == null) {
-        // TODO(brianwilkerson) We should return a ResolveDartUnitTask
-        // (unless there are multiple ASTs that need to be resolved).
-        return _createResolveDartLibraryTask(librarySource, libraryEntry);
-      }
-    }
-    return new AnalysisContextImpl_TaskData(
-        new GenerateDartHintsTask(this, units, libraryElement), false);
-  }
-
-  /**
-   * Create a [GenerateDartLintsTask] for the given [source], marking the lints
-   * as being in-process.
-   */
-  AnalysisContextImpl_TaskData _createGenerateDartLintsTask(Source source,
-      DartEntry dartEntry, Source librarySource, DartEntry libraryEntry) {
-    if (libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) {
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-    CompilationUnitElement definingUnit =
-        libraryElement.definingCompilationUnit;
-    List<CompilationUnitElement> parts = libraryElement.parts;
-    List<TimestampedData<CompilationUnit>> units =
-        new List<TimestampedData<CompilationUnit>>(parts.length + 1);
-    units[0] = _getResolvedUnit(definingUnit, librarySource);
-    if (units[0] == null) {
-      // TODO(brianwilkerson) We should return a ResolveDartUnitTask
-      // (unless there are multiple ASTs that need to be resolved).
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    for (int i = 0; i < parts.length; i++) {
-      units[i + 1] = _getResolvedUnit(parts[i], librarySource);
-      if (units[i + 1] == null) {
-        // TODO(brianwilkerson) We should return a ResolveDartUnitTask
-        // (unless there are multiple ASTs that need to be resolved).
-        return _createResolveDartLibraryTask(librarySource, libraryEntry);
-      }
-    }
-    //TODO(pquitslund): revisit if we need all units or whether one will do
-    return new AnalysisContextImpl_TaskData(
-        new GenerateDartLintsTask(this, units, libraryElement), false);
-  }
-
-  /**
-   * Create a [GetContentTask] for the given [source], marking the content as
-   * being in-process.
-   */
-  AnalysisContextImpl_TaskData _createGetContentTask(
-      Source source, SourceEntry sourceEntry) {
-    return new AnalysisContextImpl_TaskData(
-        new GetContentTask(this, source), false);
-  }
-
-  /**
-   * Create a [ParseDartTask] for the given [source].
-   */
-  AnalysisContextImpl_TaskData _createParseDartTask(
-      Source source, DartEntry dartEntry) {
-    if (dartEntry.getState(DartEntry.TOKEN_STREAM) != CacheState.VALID ||
-        dartEntry.getState(SourceEntry.LINE_INFO) != CacheState.VALID) {
-      return _createScanDartTask(source, dartEntry);
-    }
-    Token tokenStream = dartEntry.getValue(DartEntry.TOKEN_STREAM);
-    dartEntry.setState(DartEntry.TOKEN_STREAM, CacheState.FLUSHED);
-    return new AnalysisContextImpl_TaskData(
-        new ParseDartTask(this, source, tokenStream,
-            dartEntry.getValue(SourceEntry.LINE_INFO)),
-        false);
-  }
-
-  /**
-   * Create a [ParseHtmlTask] for the given [source].
-   */
-  AnalysisContextImpl_TaskData _createParseHtmlTask(
-      Source source, HtmlEntry htmlEntry) {
-    if (htmlEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
-      return _createGetContentTask(source, htmlEntry);
-    }
-    String content = htmlEntry.getValue(SourceEntry.CONTENT);
-    htmlEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
-    return new AnalysisContextImpl_TaskData(
-        new ParseHtmlTask(this, source, content), false);
-  }
-
-  /**
-   * Create a [ResolveDartLibraryTask] for the given [source], marking ? as
-   * being in-process.
-   */
-  AnalysisContextImpl_TaskData _createResolveDartLibraryTask(
-      Source source, DartEntry dartEntry) {
-    try {
-      AnalysisContextImpl_CycleBuilder builder =
-          new AnalysisContextImpl_CycleBuilder(this);
-      PerformanceStatistics.cycles.makeCurrentWhile(() {
-        builder.computeCycleContaining(source);
-      });
-      AnalysisContextImpl_TaskData taskData = builder.taskData;
-      if (taskData != null) {
-        return taskData;
-      }
-      return new AnalysisContextImpl_TaskData(
-          new ResolveDartLibraryCycleTask(
-              this, source, source, builder.librariesInCycle),
-          false);
-    } on AnalysisException catch (exception, stackTrace) {
-      dartEntry
-          .recordResolutionError(new CaughtException(exception, stackTrace));
-      AnalysisEngine.instance.logger.logError(
-          "Internal error trying to create a ResolveDartLibraryTask",
-          new CaughtException(exception, stackTrace));
-    }
-    return new AnalysisContextImpl_TaskData(null, false);
-  }
-
-  /**
-   * Create a [ResolveHtmlTask] for the given [source], marking the resolved
-   * unit as being in-process.
-   */
-  AnalysisContextImpl_TaskData _createResolveHtmlTask(
-      Source source, HtmlEntry htmlEntry) {
-    if (htmlEntry.getState(HtmlEntry.PARSED_UNIT) != CacheState.VALID) {
-      return _createParseHtmlTask(source, htmlEntry);
-    }
-    return new AnalysisContextImpl_TaskData(
-        new ResolveHtmlTask(this, source, htmlEntry.modificationTime,
-            htmlEntry.getValue(HtmlEntry.PARSED_UNIT)),
-        false);
-  }
-
-  /**
-   * Create a [ScanDartTask] for the given [source], marking the scan errors as
-   * being in-process.
-   */
-  AnalysisContextImpl_TaskData _createScanDartTask(
-      Source source, DartEntry dartEntry) {
-    if (dartEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
-      return _createGetContentTask(source, dartEntry);
-    }
-    String content = dartEntry.getValue(SourceEntry.CONTENT);
-    dartEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
-    return new AnalysisContextImpl_TaskData(
-        new ScanDartTask(this, source, content), false);
-  }
-
-  /**
-   * Create a source entry for the given [source]. Return the source entry that
-   * was created, or `null` if the source should not be tracked by this context.
-   */
-  SourceEntry _createSourceEntry(Source source, bool explicitlyAdded) {
-    String name = source.shortName;
-    if (AnalysisEngine.isHtmlFileName(name)) {
-      HtmlEntry htmlEntry = new HtmlEntry();
-      htmlEntry.modificationTime = getModificationStamp(source);
-      htmlEntry.explicitlyAdded = explicitlyAdded;
-      _cache.put(source, htmlEntry);
-      if (!explicitlyAdded) {
-        _implicitAnalysisEventsController
-            .add(new ImplicitAnalysisEvent(source, true));
-      }
-      return htmlEntry;
-    } else {
-      DartEntry dartEntry = new DartEntry();
-      dartEntry.modificationTime = getModificationStamp(source);
-      dartEntry.explicitlyAdded = explicitlyAdded;
-      _cache.put(source, dartEntry);
-      if (!explicitlyAdded) {
-        _implicitAnalysisEventsController
-            .add(new ImplicitAnalysisEvent(source, true));
-      }
-      return dartEntry;
-    }
-  }
-
-  /**
-   * Return a list containing all of the change notices that are waiting to be
-   * returned. If there are no notices, then return either `null` or an empty
-   * list, depending on the value of [nullIfEmpty].
-   */
-  List<ChangeNotice> _getChangeNotices(bool nullIfEmpty) {
-    if (_pendingNotices.isEmpty) {
-      if (nullIfEmpty) {
-        return null;
-      }
-      return ChangeNoticeImpl.EMPTY_LIST;
-    }
-    List<ChangeNotice> notices = new List.from(_pendingNotices.values);
-    _pendingNotices.clear();
-    return notices;
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source. This method assumes that the data can be produced by generating
-   * hints for the library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartHintData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry =
-        _cacheDartHintData(unitSource, librarySource, dartEntry, descriptor);
-    if (identical(descriptor, DartEntry.ELEMENT)) {
-      return dartEntry.getValue(descriptor);
-    }
-    return dartEntry.getValueInLibrary(descriptor, librarySource);
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source. This method assumes that the data can be produced by generating
-   * lints for the library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartLintData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry =
-        _cacheDartLintData(unitSource, librarySource, dartEntry, descriptor);
-    if (identical(descriptor, DartEntry.ELEMENT)) {
-      return dartEntry.getValue(descriptor);
-    }
-    return dartEntry.getValueInLibrary(descriptor, librarySource);
-  }
-
-  /**
-   * Given a source for a Dart file, return the data represented by the given
-   * descriptor that is associated with that source. This method assumes that
-   * the data can be produced by parsing the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be parsed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartParseData(
-      Source source, DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry = _cacheDartParseData(source, dartEntry, descriptor);
-    if (identical(descriptor, DartEntry.PARSED_UNIT)) {
-      _accessedAst(source);
-      return dartEntry.anyParsedCompilationUnit;
-    }
-    return dartEntry.getValue(descriptor);
-  }
-
-  /**
-   * Given a source for a Dart file, return the data represented by the given
-   * descriptor that is associated with that source, or the given default value
-   * if the source is not a Dart file. This method assumes that the data can be
-   * produced by parsing the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be parsed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartParseData2(
-      Source source, DataDescriptor descriptor, Object defaultValue) {
-    DartEntry dartEntry = _getReadableDartEntry(source);
-    if (dartEntry == null) {
-      return defaultValue;
-    }
-    try {
-      return _getDartParseData(source, dartEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute $descriptor",
-          new CaughtException(exception, stackTrace));
-      return defaultValue;
-    }
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source. This method assumes that the data can be produced by resolving the
-   * source in the context of the library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartResolutionData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry = _cacheDartResolutionData(
-        unitSource, librarySource, dartEntry, descriptor);
-    if (identical(descriptor, DartEntry.ELEMENT)) {
-      return dartEntry.getValue(descriptor);
-    } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
-      _accessedAst(unitSource);
-    }
-    return dartEntry.getValueInLibrary(descriptor, librarySource);
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source, or the given default value if the source is not a Dart file. This
-   * method assumes that the data can be produced by resolving the source in the
-   * context of the library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartResolutionData2(Source unitSource, Source librarySource,
-      DataDescriptor descriptor, Object defaultValue) {
-    DartEntry dartEntry = _getReadableDartEntry(unitSource);
-    if (dartEntry == null) {
-      return defaultValue;
-    }
-    try {
-      return _getDartResolutionData(
-          unitSource, librarySource, dartEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute $descriptor",
-          new CaughtException(exception, stackTrace));
-      return defaultValue;
-    }
-  }
-
-  /**
-   * Given a source for a Dart file, return the data represented by the given
-   * descriptor that is associated with that source. This method assumes that
-   * the data can be produced by scanning the source if it is not already
-   * cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be scanned.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartScanData(
-      Source source, DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry = _cacheDartScanData(source, dartEntry, descriptor);
-    return dartEntry.getValue(descriptor);
-  }
-
-  /**
-   * Given a source for a Dart file, return the data represented by the given
-   * descriptor that is associated with that source, or the given default value
-   * if the source is not a Dart file. This method assumes that the data can be
-   * produced by scanning the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be scanned.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartScanData2(
-      Source source, DataDescriptor descriptor, Object defaultValue) {
-    DartEntry dartEntry = _getReadableDartEntry(source);
-    if (dartEntry == null) {
-      return defaultValue;
-    }
-    try {
-      return _getDartScanData(source, dartEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute $descriptor",
-          new CaughtException(exception, stackTrace));
-      return defaultValue;
-    }
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source. This method assumes that the data can be produced by verifying the
-   * source within the given library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartVerificationData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry = _cacheDartVerificationData(
-        unitSource, librarySource, dartEntry, descriptor);
-    return dartEntry.getValueInLibrary(descriptor, librarySource);
-  }
-
-  /**
-   * Given a source for an HTML file, return the data represented by the given
-   * descriptor that is associated with that source, or the given default value
-   * if the source is not an HTML file. This method assumes that the data can be
-   * produced by parsing the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be parsed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getHtmlParseData(
-      Source source, DataDescriptor descriptor, Object defaultValue) {
-    HtmlEntry htmlEntry = _getReadableHtmlEntry(source);
-    if (htmlEntry == null) {
-      return defaultValue;
-    }
-    htmlEntry = _cacheHtmlParseData(source, htmlEntry, descriptor);
-    if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
-      _accessedAst(source);
-      return htmlEntry.anyParsedUnit;
-    }
-    return htmlEntry.getValue(descriptor);
-  }
-
-  /**
-   * Given a source for an HTML file, return the data represented by the given
-   * descriptor that is associated with that source, or the given default value
-   * if the source is not an HTML file. This method assumes that the data can be
-   * produced by resolving the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getHtmlResolutionData(
-      Source source, DataDescriptor descriptor, Object defaultValue) {
-    HtmlEntry htmlEntry = _getReadableHtmlEntry(source);
-    if (htmlEntry == null) {
-      return defaultValue;
-    }
-    try {
-      return _getHtmlResolutionData2(source, htmlEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute $descriptor",
-          new CaughtException(exception, stackTrace));
-      return defaultValue;
-    }
-  }
-
-  /**
-   * Given a source for an HTML file, return the data represented by the given
-   * descriptor that is associated with that source. This method assumes that
-   * the data can be produced by resolving the source if it is not already
-   * cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getHtmlResolutionData2(
-      Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
-    htmlEntry = _cacheHtmlResolutionData(source, htmlEntry, descriptor);
-    if (identical(descriptor, HtmlEntry.RESOLVED_UNIT)) {
-      _accessedAst(source);
-    }
-    return htmlEntry.getValue(descriptor);
-  }
-
-  /**
-   * Look at the given [source] to see whether a task needs to be performed
-   * related to it. Return the task that should be performed, or `null` if there
-   * is no more work to be done for the source.
-   */
-  AnalysisContextImpl_TaskData _getNextAnalysisTaskForSource(
-      Source source,
-      SourceEntry sourceEntry,
-      bool isPriority,
-      bool hintsEnabled,
-      bool lintsEnabled) {
-    // Refuse to generate tasks for html based files that are above 1500 KB
-    if (_isTooBigHtmlSourceEntry(source, sourceEntry)) {
-      // TODO (jwren) we still need to report an error of some kind back to the
-      // client.
-      return new AnalysisContextImpl_TaskData(null, false);
-    }
-    if (sourceEntry == null) {
-      return new AnalysisContextImpl_TaskData(null, false);
-    }
-    CacheState contentState = sourceEntry.getState(SourceEntry.CONTENT);
-    if (contentState == CacheState.INVALID) {
-      return _createGetContentTask(source, sourceEntry);
-    } else if (contentState == CacheState.IN_PROCESS) {
-      // We are already in the process of getting the content.
-      // There's nothing else we can do with this source until that's complete.
-      return new AnalysisContextImpl_TaskData(null, true);
-    } else if (contentState == CacheState.ERROR) {
-      // We have done all of the analysis we can for this source because we
-      // cannot get its content.
-      return new AnalysisContextImpl_TaskData(null, false);
-    }
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS);
-      if (scanErrorsState == CacheState.INVALID ||
-          (isPriority && scanErrorsState == CacheState.FLUSHED)) {
-        return _createScanDartTask(source, dartEntry);
-      }
-      CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
-      if (parseErrorsState == CacheState.INVALID ||
-          (isPriority && parseErrorsState == CacheState.FLUSHED)) {
-        return _createParseDartTask(source, dartEntry);
-      }
-      if (isPriority && parseErrorsState != CacheState.ERROR) {
-        if (!dartEntry.hasResolvableCompilationUnit) {
-          return _createParseDartTask(source, dartEntry);
-        }
-      }
-      SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
-      if (kind == SourceKind.UNKNOWN) {
-        return _createParseDartTask(source, dartEntry);
-      } else if (kind == SourceKind.LIBRARY) {
-        CacheState elementState = dartEntry.getState(DartEntry.ELEMENT);
-        if (elementState == CacheState.INVALID) {
-          return _createResolveDartLibraryTask(source, dartEntry);
-        }
-      }
-      List<Source> librariesContaining = dartEntry.containingLibraries;
-      for (Source librarySource in librariesContaining) {
-        SourceEntry librarySourceEntry = _cache.get(librarySource);
-        if (librarySourceEntry is DartEntry) {
-          DartEntry libraryEntry = librarySourceEntry;
-          CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
-          if (elementState == CacheState.INVALID ||
-              (isPriority && elementState == CacheState.FLUSHED)) {
-//            return createResolveDartLibraryTask(librarySource, (DartEntry) libraryEntry);
-            return new AnalysisContextImpl_TaskData(
-                new ResolveDartLibraryTask(this, source, librarySource), false);
-          }
-          CacheState resolvedUnitState = dartEntry.getStateInLibrary(
-              DartEntry.RESOLVED_UNIT, librarySource);
-          if (resolvedUnitState == CacheState.INVALID ||
-              (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
-            //
-            // The commented out lines below are an optimization that doesn't
-            // quite work yet. The problem is that if the source was not
-            // resolved because it wasn't part of any library, then there won't
-            // be any elements in the element model that we can use to resolve
-            // it.
-            //
-//            LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-//            if (libraryElement != null) {
-//              return new ResolveDartUnitTask(this, source, libraryElement);
-//            }
-            // Possibly replace with:
-//             return createResolveDartLibraryTask(librarySource, (DartEntry) libraryEntry);
-            return new AnalysisContextImpl_TaskData(
-                new ResolveDartLibraryTask(this, source, librarySource), false);
-          }
-          if (shouldErrorsBeAnalyzed(source, dartEntry)) {
-            CacheState verificationErrorsState = dartEntry.getStateInLibrary(
-                DartEntry.VERIFICATION_ERRORS, librarySource);
-            if (verificationErrorsState == CacheState.INVALID ||
-                (isPriority && verificationErrorsState == CacheState.FLUSHED)) {
-              return _createGenerateDartErrorsTask(
-                  source, dartEntry, librarySource, libraryEntry);
-            }
-            if (hintsEnabled) {
-              CacheState hintsState =
-                  dartEntry.getStateInLibrary(DartEntry.HINTS, librarySource);
-              if (hintsState == CacheState.INVALID ||
-                  (isPriority && hintsState == CacheState.FLUSHED)) {
-                return _createGenerateDartHintsTask(
-                    source, dartEntry, librarySource, libraryEntry);
-              }
-            }
-            if (lintsEnabled) {
-              CacheState lintsState =
-                  dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource);
-              if (lintsState == CacheState.INVALID ||
-                  (isPriority && lintsState == CacheState.FLUSHED)) {
-                return _createGenerateDartLintsTask(
-                    source, dartEntry, librarySource, libraryEntry);
-              }
-            }
-          }
-        }
-      }
-    } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      CacheState parseErrorsState = htmlEntry.getState(HtmlEntry.PARSE_ERRORS);
-      if (parseErrorsState == CacheState.INVALID ||
-          (isPriority && parseErrorsState == CacheState.FLUSHED)) {
-        return _createParseHtmlTask(source, htmlEntry);
-      }
-      if (isPriority && parseErrorsState != CacheState.ERROR) {
-        ht.HtmlUnit parsedUnit = htmlEntry.anyParsedUnit;
-        if (parsedUnit == null) {
-          return _createParseHtmlTask(source, htmlEntry);
-        }
-      }
-      CacheState resolvedUnitState =
-          htmlEntry.getState(HtmlEntry.RESOLVED_UNIT);
-      if (resolvedUnitState == CacheState.INVALID ||
-          (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
-        return _createResolveHtmlTask(source, htmlEntry);
-      }
-    }
-    return new AnalysisContextImpl_TaskData(null, false);
-  }
-
-  /**
-   * Return the cache entry associated with the given [source], or `null` if the
-   * source is not a Dart file.
-   *
-   * @param source the source for which a cache entry is being sought
-   * @return the source cache entry associated with the given source
-   */
-  DartEntry _getReadableDartEntry(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      sourceEntry = _createSourceEntry(source, false);
-    }
-    if (sourceEntry is DartEntry) {
-      return sourceEntry;
-    }
-    return null;
-  }
-
-  /**
-   * Return the cache entry associated with the given [source], or `null` if the
-   * source is not an HTML file.
-   */
-  HtmlEntry _getReadableHtmlEntry(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      sourceEntry = _createSourceEntry(source, false);
-    }
-    if (sourceEntry is HtmlEntry) {
-      return sourceEntry;
-    }
-    return null;
-  }
-
-  /**
-   * Return the cache entry associated with the given [source], creating it if
-   * necessary.
-   */
-  SourceEntry _getReadableSourceEntry(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      sourceEntry = _createSourceEntry(source, false);
-    }
-    return sourceEntry;
-  }
-
-  /**
-   * Return a resolved compilation unit corresponding to the given [element] in
-   * the library defined by the given [librarySource], or `null` if the
-   * information is not cached.
-   */
-  TimestampedData<CompilationUnit> _getResolvedUnit(
-      CompilationUnitElement element, Source librarySource) {
-    SourceEntry sourceEntry = _cache.get(element.source);
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      if (dartEntry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource) ==
-          CacheState.VALID) {
-        return new TimestampedData<CompilationUnit>(
-            dartEntry.modificationTime,
-            dartEntry.getValueInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource));
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return a list containing all of the sources known to this context that have
-   * the given [kind].
-   */
-  List<Source> _getSources(SourceKind kind) {
-    List<Source> sources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      if (iterator.value.kind == kind) {
-        sources.add(iterator.key);
-      }
-    }
-    return sources;
-  }
-
-  /**
-   * Look at the given [source] to see whether a task needs to be performed
-   * related to it. If so, add the source to the set of sources that need to be
-   * processed. This method duplicates, and must therefore be kept in sync with,
-   * [_getNextAnalysisTaskForSource]. This method is intended to be used for
-   * testing purposes only.
-   */
-  void _getSourcesNeedingProcessing(
-      Source source,
-      SourceEntry sourceEntry,
-      bool isPriority,
-      bool hintsEnabled,
-      bool lintsEnabled,
-      HashSet<Source> sources) {
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS);
-      if (scanErrorsState == CacheState.INVALID ||
-          (isPriority && scanErrorsState == CacheState.FLUSHED)) {
-        sources.add(source);
-        return;
-      }
-      CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
-      if (parseErrorsState == CacheState.INVALID ||
-          (isPriority && parseErrorsState == CacheState.FLUSHED)) {
-        sources.add(source);
-        return;
-      }
-      if (isPriority) {
-        if (!dartEntry.hasResolvableCompilationUnit) {
-          sources.add(source);
-          return;
-        }
-      }
-      for (Source librarySource in getLibrariesContaining(source)) {
-        SourceEntry libraryEntry = _cache.get(librarySource);
-        if (libraryEntry is DartEntry) {
-          CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
-          if (elementState == CacheState.INVALID ||
-              (isPriority && elementState == CacheState.FLUSHED)) {
-            sources.add(source);
-            return;
-          }
-          CacheState resolvedUnitState = dartEntry.getStateInLibrary(
-              DartEntry.RESOLVED_UNIT, librarySource);
-          if (resolvedUnitState == CacheState.INVALID ||
-              (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
-            LibraryElement libraryElement =
-                libraryEntry.getValue(DartEntry.ELEMENT);
-            if (libraryElement != null) {
-              sources.add(source);
-              return;
-            }
-          }
-          if (shouldErrorsBeAnalyzed(source, dartEntry)) {
-            CacheState verificationErrorsState = dartEntry.getStateInLibrary(
-                DartEntry.VERIFICATION_ERRORS, librarySource);
-            if (verificationErrorsState == CacheState.INVALID ||
-                (isPriority && verificationErrorsState == CacheState.FLUSHED)) {
-              LibraryElement libraryElement =
-                  libraryEntry.getValue(DartEntry.ELEMENT);
-              if (libraryElement != null) {
-                sources.add(source);
-                return;
-              }
-            }
-            if (hintsEnabled) {
-              CacheState hintsState =
-                  dartEntry.getStateInLibrary(DartEntry.HINTS, librarySource);
-              if (hintsState == CacheState.INVALID ||
-                  (isPriority && hintsState == CacheState.FLUSHED)) {
-                LibraryElement libraryElement =
-                    libraryEntry.getValue(DartEntry.ELEMENT);
-                if (libraryElement != null) {
-                  sources.add(source);
-                  return;
-                }
-              }
-            }
-            if (lintsEnabled) {
-              CacheState lintsState =
-                  dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource);
-              if (lintsState == CacheState.INVALID ||
-                  (isPriority && lintsState == CacheState.FLUSHED)) {
-                LibraryElement libraryElement =
-                    libraryEntry.getValue(DartEntry.ELEMENT);
-                if (libraryElement != null) {
-                  sources.add(source);
-                  return;
-                }
-              }
-            }
-          }
-        }
-      }
-    } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
-      if (parsedUnitState == CacheState.INVALID ||
-          (isPriority && parsedUnitState == CacheState.FLUSHED)) {
-        sources.add(source);
-        return;
-      }
-      CacheState resolvedUnitState =
-          htmlEntry.getState(HtmlEntry.RESOLVED_UNIT);
-      if (resolvedUnitState == CacheState.INVALID ||
-          (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
-        sources.add(source);
-        return;
-      }
-    }
-  }
-
-  /**
-   * Invalidate all of the resolution results computed by this context. The flag
-   * [invalidateUris] should be `true` if the cached results of converting URIs
-   * to source files should also be invalidated.
-   */
-  void _invalidateAllLocalResolutionInformation(bool invalidateUris) {
-    HashMap<Source, List<Source>> oldPartMap =
-        new HashMap<Source, List<Source>>();
-    MapIterator<Source, SourceEntry> iterator = _privatePartition.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      if (sourceEntry is HtmlEntry) {
-        HtmlEntry htmlEntry = sourceEntry;
-        htmlEntry.invalidateAllResolutionInformation(invalidateUris);
-        iterator.value = htmlEntry;
-        _workManager.add(source, SourcePriority.HTML);
-      } else if (sourceEntry is DartEntry) {
-        DartEntry dartEntry = sourceEntry;
-        oldPartMap[source] = dartEntry.getValue(DartEntry.INCLUDED_PARTS);
-        dartEntry.invalidateAllResolutionInformation(invalidateUris);
-        iterator.value = dartEntry;
-        _workManager.add(source, _computePriority(dartEntry));
-      }
-    }
-    _removeFromPartsUsingMap(oldPartMap);
-  }
-
-  /**
-   * In response to a change to at least one of the compilation units in the
-   * library defined by the given [librarySource], invalidate any results that
-   * are dependent on the result of resolving that library.
-   *
-   * <b>Note:</b> Any cache entries that were accessed before this method was
-   * invoked must be re-accessed after this method returns.
-   */
-  void _invalidateLibraryResolution(Source librarySource) {
-    // TODO(brianwilkerson) This could be optimized. There's no need to flush
-    // all of these entries if the public namespace hasn't changed, which will
-    // be a fairly common case. The question is whether we can afford the time
-    // to compute the namespace to look for differences.
-    DartEntry libraryEntry = _getReadableDartEntry(librarySource);
-    if (libraryEntry != null) {
-      List<Source> includedParts =
-          libraryEntry.getValue(DartEntry.INCLUDED_PARTS);
-      libraryEntry.invalidateAllResolutionInformation(false);
-      _workManager.add(librarySource, SourcePriority.LIBRARY);
-      for (Source partSource in includedParts) {
-        SourceEntry partEntry = _cache.get(partSource);
-        if (partEntry is DartEntry) {
-          partEntry.invalidateAllResolutionInformation(false);
-        }
-      }
-    }
-  }
-
-  /**
-   * Return `true` if the given [library] is, or depends on, 'dart:html'. The
-   * [visitedLibraries] is a collection of the libraries that have been visited,
-   * used to prevent infinite recursion.
-   */
-  bool _isClient(LibraryElement library, Source htmlSource,
-      HashSet<LibraryElement> visitedLibraries) {
-    if (visitedLibraries.contains(library)) {
-      return false;
-    }
-    if (library.source == htmlSource) {
-      return true;
-    }
-    visitedLibraries.add(library);
-    for (LibraryElement imported in library.importedLibraries) {
-      if (_isClient(imported, htmlSource, visitedLibraries)) {
-        return true;
-      }
-    }
-    for (LibraryElement exported in library.exportedLibraries) {
-      if (_isClient(exported, htmlSource, visitedLibraries)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool _isTooBigHtmlSourceEntry(Source source, SourceEntry sourceEntry) =>
-      false;
-
-//  /**
-//   * Notify all of the analysis listeners that the given source is no longer included in the set of
-//   * sources that are being analyzed.
-//   *
-//   * @param source the source that is no longer being analyzed
-//   */
-//  void _notifyExcludedSource(Source source) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].excludedSource(this, source);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given source is now included in the set of
-//   * sources that are being analyzed.
-//   *
-//   * @param source the source that is now being analyzed
-//   */
-//  void _notifyIncludedSource(Source source) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].includedSource(this, source);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given Dart source was parsed.
-//   *
-//   * @param source the source that was parsed
-//   * @param unit the result of parsing the source
-//   */
-//  void _notifyParsedDart(Source source, CompilationUnit unit) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].parsedDart(this, source, unit);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given HTML source was parsed.
-//   *
-//   * @param source the source that was parsed
-//   * @param unit the result of parsing the source
-//   */
-//  void _notifyParsedHtml(Source source, ht.HtmlUnit unit) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].parsedHtml(this, source, unit);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given Dart source was resolved.
-//   *
-//   * @param source the source that was resolved
-//   * @param unit the result of resolving the source
-//   */
-//  void _notifyResolvedDart(Source source, CompilationUnit unit) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].resolvedDart(this, source, unit);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given HTML source was resolved.
-//   *
-//   * @param source the source that was resolved
-//   * @param unit the result of resolving the source
-//   */
-//  void _notifyResolvedHtml(Source source, ht.HtmlUnit unit) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].resolvedHtml(this, source, unit);
-//    }
-//  }
-
-  /**
-   * Log the given debugging [message].
-   */
-  void _logInformation(String message) {
-    AnalysisEngine.instance.logger.logInformation(message);
-  }
-
-  /**
-   * Notify all of the analysis listeners that a task is about to be performed.
-   */
-  void _notifyAboutToPerformTask(String taskDescription) {
-    int count = _listeners.length;
-    for (int i = 0; i < count; i++) {
-      _listeners[i].aboutToPerformTask(this, taskDescription);
-    }
-  }
-
-  /**
-   * Notify all of the analysis listeners that the errors associated with the
-   * given [source] has been updated to the given [errors].
-   */
-  void _notifyErrors(
-      Source source, List<AnalysisError> errors, LineInfo lineInfo) {
-    int count = _listeners.length;
-    for (int i = 0; i < count; i++) {
-      _listeners[i].computedErrors(this, source, errors, lineInfo);
-    }
-  }
-
-  /**
-   * 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;
-    }
-  }
-
-  /**
-   * Given a [dartEntry] and a [library] element, record the library element and
-   * other information gleaned from the element in the cache entry.
-   */
-  void _recordElementData(DartEntry dartEntry, LibraryElement library,
-      Source librarySource, Source htmlSource) {
-    dartEntry.setValue(DartEntry.ELEMENT, library);
-    dartEntry.setValue(DartEntry.IS_LAUNCHABLE, library.entryPoint != null);
-    dartEntry.setValue(DartEntry.IS_CLIENT,
-        _isClient(library, htmlSource, new HashSet<LibraryElement>()));
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordGenerateDartErrorsTask(GenerateDartErrorsTask task) {
-    Source source = task.source;
-    DartEntry dartEntry = _cache.get(source);
-    Source librarySource = task.libraryElement.source;
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      dartEntry.recordVerificationErrorInLibrary(
-          librarySource, thrownException);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    dartEntry.setValueInLibrary(
-        DartEntry.VERIFICATION_ERRORS, librarySource, task.errors);
-    ChangeNoticeImpl notice = getNotice(source);
-    LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
-    notice.setErrors(dartEntry.allErrors, lineInfo);
-    return dartEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordGenerateDartHintsTask(GenerateDartHintsTask task) {
-    Source librarySource = task.libraryElement.source;
-    CaughtException thrownException = task.exception;
-    DartEntry libraryEntry = null;
-    HashMap<Source, List<AnalysisError>> hintMap = task.hintMap;
-    if (hintMap == null) {
-      // We don't have any information about which sources to mark as invalid
-      // other than the library source.
-      DartEntry libraryEntry = _cache.get(librarySource);
-      if (thrownException == null) {
-        String message = "GenerateDartHintsTask returned a null hint map "
-            "without throwing an exception: ${librarySource.fullName}";
-        thrownException =
-            new CaughtException(new AnalysisException(message), null);
-      }
-      libraryEntry.recordHintErrorInLibrary(librarySource, thrownException);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    hintMap.forEach((Source unitSource, List<AnalysisError> hints) {
-      DartEntry dartEntry = _cache.get(unitSource);
-      if (unitSource == librarySource) {
-        libraryEntry = dartEntry;
-      }
-      if (thrownException == null) {
-        dartEntry.setValueInLibrary(DartEntry.HINTS, librarySource, hints);
-        ChangeNoticeImpl notice = getNotice(unitSource);
-        LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
-        notice.setErrors(dartEntry.allErrors, lineInfo);
-      } else {
-        dartEntry.recordHintErrorInLibrary(librarySource, thrownException);
-      }
-    });
-    if (thrownException != null) {
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    return libraryEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordGenerateDartLintsTask(GenerateDartLintsTask task) {
-    Source librarySource = task.libraryElement.source;
-    CaughtException thrownException = task.exception;
-    DartEntry libraryEntry = null;
-    HashMap<Source, List<AnalysisError>> lintMap = task.lintMap;
-    if (lintMap == null) {
-      // We don't have any information about which sources to mark as invalid
-      // other than the library source.
-      DartEntry libraryEntry = _cache.get(librarySource);
-      if (thrownException == null) {
-        String message = "GenerateDartLintsTask returned a null lint map "
-            "without throwing an exception: ${librarySource.fullName}";
-        thrownException =
-            new CaughtException(new AnalysisException(message), null);
-      }
-      libraryEntry.recordLintErrorInLibrary(librarySource, thrownException);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    lintMap.forEach((Source unitSource, List<AnalysisError> lints) {
-      DartEntry dartEntry = _cache.get(unitSource);
-      if (unitSource == librarySource) {
-        libraryEntry = dartEntry;
-      }
-      if (thrownException == null) {
-        dartEntry.setValueInLibrary(DartEntry.LINTS, librarySource, lints);
-        ChangeNoticeImpl notice = getNotice(unitSource);
-        LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
-        notice.setErrors(dartEntry.allErrors, lineInfo);
-      } else {
-        dartEntry.recordLintErrorInLibrary(librarySource, thrownException);
-      }
-    });
-    if (thrownException != null) {
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    return libraryEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  SourceEntry _recordGetContentsTask(GetContentTask task) {
-    if (!task.isComplete) {
-      return null;
-    }
-    Source source = task.source;
-    SourceEntry sourceEntry = _cache.get(source);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      sourceEntry.recordContentError(thrownException);
-      {
-        sourceEntry.setValue(SourceEntry.CONTENT_ERRORS, task.errors);
-        ChangeNoticeImpl notice = getNotice(source);
-        notice.setErrors(sourceEntry.allErrors, null);
-      }
-      _workManager.remove(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    sourceEntry.modificationTime = task.modificationTime;
-    sourceEntry.setValue(SourceEntry.CONTENT, task.content);
-    return sourceEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordIncrementalAnalysisTaskResults(
-      IncrementalAnalysisTask task) {
-    CompilationUnit unit = task.compilationUnit;
-    if (unit != null) {
-      ChangeNoticeImpl notice = getNotice(task.source);
-      notice.resolvedDartUnit = unit;
-      _incrementalAnalysisCache =
-          IncrementalAnalysisCache.cacheResult(task.cache, unit);
-    }
-    return null;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordParseDartTaskResults(ParseDartTask task) {
-    Source source = task.source;
-    DartEntry dartEntry = _cache.get(source);
-    _removeFromParts(source, dartEntry);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      _removeFromParts(source, dartEntry);
-      dartEntry.recordParseError(thrownException);
-      _cache.removedAst(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    if (task.hasNonPartOfDirective) {
-      dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
-      dartEntry.containingLibrary = source;
-      _workManager.add(source, SourcePriority.LIBRARY);
-    } else if (task.hasPartOfDirective) {
-      dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
-      dartEntry.removeContainingLibrary(source);
-      _workManager.add(source, SourcePriority.NORMAL_PART);
-    } else {
-      // The file contains no directives.
-      List<Source> containingLibraries = dartEntry.containingLibraries;
-      if (containingLibraries.length > 1 ||
-          (containingLibraries.length == 1 &&
-              containingLibraries[0] != source)) {
-        dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
-        dartEntry.removeContainingLibrary(source);
-        _workManager.add(source, SourcePriority.NORMAL_PART);
-      } else {
-        dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
-        dartEntry.containingLibrary = source;
-        _workManager.add(source, SourcePriority.LIBRARY);
-      }
-    }
-    List<Source> newParts = task.includedSources;
-    for (int i = 0; i < newParts.length; i++) {
-      Source partSource = newParts[i];
-      DartEntry partEntry = _getReadableDartEntry(partSource);
-      if (partEntry != null && !identical(partEntry, dartEntry)) {
-        // TODO(brianwilkerson) Change the kind of the "part" if it was marked
-        // as a library and it has no directives.
-        partEntry.addContainingLibrary(source);
-      }
-    }
-    dartEntry.setValue(DartEntry.PARSED_UNIT, task.compilationUnit);
-    dartEntry.setValue(DartEntry.PARSE_ERRORS, task.errors);
-    dartEntry.setValue(DartEntry.EXPORTED_LIBRARIES, task.exportedSources);
-    dartEntry.setValue(DartEntry.IMPORTED_LIBRARIES, task.importedSources);
-    dartEntry.setValue(DartEntry.INCLUDED_PARTS, newParts);
-    _cache.storedAst(source);
-    ChangeNoticeImpl notice = getNotice(source);
-    if (notice.resolvedDartUnit == null) {
-      notice.parsedDartUnit = task.compilationUnit;
-    }
-    notice.setErrors(dartEntry.allErrors, task.lineInfo);
-    // Verify that the incrementally parsed and resolved unit in the incremental
-    // cache is structurally equivalent to the fully parsed unit
-    _incrementalAnalysisCache = IncrementalAnalysisCache.verifyStructure(
-        _incrementalAnalysisCache, source, task.compilationUnit);
-    return dartEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  HtmlEntry _recordParseHtmlTaskResults(ParseHtmlTask task) {
-    Source source = task.source;
-    HtmlEntry htmlEntry = _cache.get(source);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      htmlEntry.recordParseError(thrownException);
-      _cache.removedAst(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    LineInfo lineInfo = task.lineInfo;
-    htmlEntry.setValue(SourceEntry.LINE_INFO, lineInfo);
-    htmlEntry.setValue(HtmlEntry.PARSED_UNIT, task.htmlUnit);
-    htmlEntry.setValue(HtmlEntry.PARSE_ERRORS, task.errors);
-    htmlEntry.setValue(
-        HtmlEntry.REFERENCED_LIBRARIES, task.referencedLibraries);
-    _cache.storedAst(source);
-    ChangeNoticeImpl notice = getNotice(source);
-    notice.setErrors(htmlEntry.allErrors, lineInfo);
-    return htmlEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
-    Source unitSource = task.source;
-    DartEntry dartEntry = _cache.get(unitSource);
-    Source librarySource = task.librarySource;
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      dartEntry.recordResolutionErrorInLibrary(librarySource, thrownException);
-      _cache.removedAst(unitSource);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    dartEntry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, librarySource, task.resolvedUnit);
-    _cache.storedAst(unitSource);
-    return dartEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  HtmlEntry _recordResolveHtmlTaskResults(ResolveHtmlTask task) {
-    Source source = task.source;
-    HtmlEntry htmlEntry = _cache.get(source);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      htmlEntry.recordResolutionError(thrownException);
-      _cache.removedAst(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    htmlEntry.setState(HtmlEntry.PARSED_UNIT, CacheState.FLUSHED);
-    htmlEntry.setValue(HtmlEntry.RESOLVED_UNIT, task.resolvedUnit);
-    htmlEntry.setValue(HtmlEntry.ELEMENT, task.element);
-    htmlEntry.setValue(HtmlEntry.RESOLUTION_ERRORS, task.resolutionErrors);
-    _cache.storedAst(source);
-    ChangeNoticeImpl notice = getNotice(source);
-    notice.resolvedHtmlUnit = task.resolvedUnit;
-    LineInfo lineInfo = htmlEntry.getValue(SourceEntry.LINE_INFO);
-    notice.setErrors(htmlEntry.allErrors, lineInfo);
-    return htmlEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordScanDartTaskResults(ScanDartTask task) {
-    Source source = task.source;
-    DartEntry dartEntry = _cache.get(source);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      _removeFromParts(source, dartEntry);
-      dartEntry.recordScanError(thrownException);
-      _cache.removedAst(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    LineInfo lineInfo = task.lineInfo;
-    dartEntry.setValue(SourceEntry.LINE_INFO, lineInfo);
-    dartEntry.setValue(DartEntry.TOKEN_STREAM, task.tokenStream);
-    dartEntry.setValue(DartEntry.SCAN_ERRORS, task.errors);
-    _cache.storedAst(source);
-    ChangeNoticeImpl notice = getNotice(source);
-    notice.setErrors(dartEntry.allErrors, lineInfo);
-    return dartEntry;
-  }
-
-  void _removeFromCache(Source source) {
-    SourceEntry entry = _cache.remove(source);
-    if (entry != null && !entry.explicitlyAdded) {
-      _implicitAnalysisEventsController
-          .add(new ImplicitAnalysisEvent(source, false));
-    }
-  }
-
-  /**
-   * Remove the given [librarySource] from the list of containing libraries for
-   * all of the parts referenced by the given [dartEntry].
-   */
-  void _removeFromParts(Source librarySource, DartEntry dartEntry) {
-    List<Source> oldParts = dartEntry.getValue(DartEntry.INCLUDED_PARTS);
-    for (int i = 0; i < oldParts.length; i++) {
-      Source partSource = oldParts[i];
-      DartEntry partEntry = _getReadableDartEntry(partSource);
-      if (partEntry != null && !identical(partEntry, dartEntry)) {
-        partEntry.removeContainingLibrary(librarySource);
-        if (partEntry.containingLibraries.length == 0 && !exists(partSource)) {
-          _removeFromCache(partSource);
-        }
-      }
-    }
-  }
-
-  /**
-   * Remove the given libraries that are keys in the given map from the list of
-   * containing libraries for each of the parts in the corresponding value.
-   */
-  void _removeFromPartsUsingMap(HashMap<Source, List<Source>> oldPartMap) {
-    oldPartMap.forEach((Source librarySource, List<Source> oldParts) {
-      for (int i = 0; i < oldParts.length; i++) {
-        Source partSource = oldParts[i];
-        if (partSource != librarySource) {
-          DartEntry partEntry = _getReadableDartEntry(partSource);
-          if (partEntry != null) {
-            partEntry.removeContainingLibrary(librarySource);
-            if (partEntry.containingLibraries.length == 0 &&
-                !exists(partSource)) {
-              _removeFromCache(partSource);
-            }
-          }
-        }
-      }
-    });
-  }
-
-  /**
-   * Remove the given [source] from the priority order if it is in the list.
-   */
-  void _removeFromPriorityOrder(Source source) {
-    int count = _priorityOrder.length;
-    List<Source> newOrder = new List<Source>();
-    for (int i = 0; i < count; i++) {
-      if (_priorityOrder[i] != source) {
-        newOrder.add(_priorityOrder[i]);
-      }
-    }
-    if (newOrder.length < count) {
-      analysisPriorityOrder = newOrder;
-    }
-  }
-
-  /**
-   * Create an entry for the newly added [source] and invalidate any sources
-   * that referenced the source before it existed.
-   */
-  void _sourceAvailable(Source source) {
-    // TODO(brianwilkerson) This method needs to check whether the source was
-    // previously being implicitly analyzed. If so, the cache entry needs to be
-    // update to reflect the new status and an event needs to be generated to
-    // inform clients that it is no longer being implicitly analyzed.
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      sourceEntry = _createSourceEntry(source, true);
-    } else {
-      _propagateInvalidation(source, sourceEntry);
-      sourceEntry = _cache.get(source);
-    }
-    if (sourceEntry is HtmlEntry) {
-      _workManager.add(source, SourcePriority.HTML);
-    } else if (sourceEntry is DartEntry) {
-      _workManager.add(source, _computePriority(sourceEntry));
-    }
-  }
-
-  /**
-   * Invalidate the [source] that was changed and any sources that referenced
-   * the source before it existed.
-   */
-  void _sourceChanged(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    // If the source is removed, we don't care about it.
-    if (sourceEntry == null) {
-      return;
-    }
-    // Check if the content of the source is the same as it was the last time.
-    String sourceContent = sourceEntry.getValue(SourceEntry.CONTENT);
-    if (sourceContent != null) {
-      sourceEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
-      try {
-        TimestampedData<String> fileContents = getContents(source);
-        if (fileContents.data == sourceContent) {
-          return;
-        }
-      } catch (e) {}
-    }
-    // We have to invalidate the cache.
-    _propagateInvalidation(source, sourceEntry);
-  }
-
-  /**
-   * Record that the give [source] has been deleted.
-   */
-  void _sourceDeleted(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      htmlEntry.recordContentError(new CaughtException(
-          new AnalysisException("This source was marked as being deleted"),
-          null));
-    } else if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      HashSet<Source> libraries = new HashSet<Source>();
-      for (Source librarySource in getLibrariesContaining(source)) {
-        libraries.add(librarySource);
-        for (Source dependentLibrary
-            in getLibrariesDependingOn(librarySource)) {
-          libraries.add(dependentLibrary);
-        }
-      }
-      for (Source librarySource in libraries) {
-        _invalidateLibraryResolution(librarySource);
-      }
-      dartEntry.recordContentError(new CaughtException(
-          new AnalysisException("This source was marked as being deleted"),
-          null));
-    }
-    _workManager.remove(source);
-    _removeFromPriorityOrder(source);
-  }
-
-  /**
-   * Record that the given [source] has been removed.
-   */
-  void _sourceRemoved(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry is HtmlEntry) {} else if (sourceEntry is DartEntry) {
-      HashSet<Source> libraries = new HashSet<Source>();
-      for (Source librarySource in getLibrariesContaining(source)) {
-        libraries.add(librarySource);
-        for (Source dependentLibrary
-            in getLibrariesDependingOn(librarySource)) {
-          libraries.add(dependentLibrary);
-        }
-      }
-      for (Source librarySource in libraries) {
-        _invalidateLibraryResolution(librarySource);
-      }
-    }
-    _removeFromCache(source);
-    _workManager.remove(source);
-    _removeFromPriorityOrder(source);
-  }
-
-  /**
-   * TODO(scheglov) A hackish, limited incremental resolution implementation.
-   */
-  bool _tryPoorMansIncrementalResolution(Source unitSource, String newCode) {
-    return PerformanceStatistics.incrementalAnalysis.makeCurrentWhile(() {
-      incrementalResolutionValidation_lastUnitSource = null;
-      incrementalResolutionValidation_lastLibrarySource = null;
-      incrementalResolutionValidation_lastUnit = null;
-      // prepare the entry
-      DartEntry dartEntry = _cache.get(unitSource);
-      if (dartEntry == 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,
-          getReadableSourceEntryOrNull(unitSource),
-          null,
-          null,
-          oldUnit,
-          analysisOptions.incrementalApi);
-      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(dartEntry.allErrors, lineInfo);
-      }
-      // OK
-      return true;
-    });
-  }
-
-  void _validateLastIncrementalResolutionResult() {
-    if (incrementalResolutionValidation_lastUnitSource == null ||
-        incrementalResolutionValidation_lastLibrarySource == null ||
-        incrementalResolutionValidation_lastUnit == null) {
-      return;
-    }
-    CompilationUnit fullUnit = getResolvedCompilationUnit2(
-        incrementalResolutionValidation_lastUnitSource,
-        incrementalResolutionValidation_lastLibrarySource);
-    if (fullUnit != null) {
-      try {
-        assertSameResolution(
-            incrementalResolutionValidation_lastUnit, fullUnit);
-      } on IncrementalResolutionMismatch catch (mismatch, stack) {
-        String failure = mismatch.message;
-        String message =
-            'Incremental resolution mismatch:\n$failure\nat\n$stack';
-        AnalysisEngine.instance.logger.logError(message);
-      }
-    }
-    incrementalResolutionValidation_lastUnitSource = null;
-    incrementalResolutionValidation_lastLibrarySource = null;
-    incrementalResolutionValidation_lastUnit = null;
-  }
-}
-
-/**
- * An object used by an analysis context to record the results of a task.
- */
-class AnalysisContextImpl_AnalysisTaskResultRecorder
-    implements AnalysisTaskVisitor<SourceEntry> {
-  final AnalysisContextImpl AnalysisContextImpl_this;
-
-  AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
-
-  @override
-  DartEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) =>
-      AnalysisContextImpl_this._recordGenerateDartErrorsTask(task);
-
-  @override
-  DartEntry visitGenerateDartHintsTask(GenerateDartHintsTask task) =>
-      AnalysisContextImpl_this._recordGenerateDartHintsTask(task);
-
-  @override
-  DartEntry visitGenerateDartLintsTask(GenerateDartLintsTask task) =>
-      AnalysisContextImpl_this._recordGenerateDartLintsTask(task);
-
-  @override
-  SourceEntry visitGetContentTask(GetContentTask task) =>
-      AnalysisContextImpl_this._recordGetContentsTask(task);
-
-  @override
-  DartEntry visitIncrementalAnalysisTask(IncrementalAnalysisTask task) =>
-      AnalysisContextImpl_this._recordIncrementalAnalysisTaskResults(task);
-
-  @override
-  DartEntry visitParseDartTask(ParseDartTask task) =>
-      AnalysisContextImpl_this._recordParseDartTaskResults(task);
-
-  @override
-  HtmlEntry visitParseHtmlTask(ParseHtmlTask task) =>
-      AnalysisContextImpl_this._recordParseHtmlTaskResults(task);
-
-  @override
-  DartEntry visitResolveDartLibraryCycleTask(
-          ResolveDartLibraryCycleTask task) =>
-      AnalysisContextImpl_this.recordResolveDartLibraryCycleTaskResults(task);
-
-  @override
-  DartEntry visitResolveDartLibraryTask(ResolveDartLibraryTask task) =>
-      AnalysisContextImpl_this.recordResolveDartLibraryTaskResults(task);
-
-  @override
-  DartEntry visitResolveDartUnitTask(ResolveDartUnitTask task) =>
-      AnalysisContextImpl_this._recordResolveDartUnitTaskResults(task);
-
-  @override
-  HtmlEntry visitResolveHtmlTask(ResolveHtmlTask task) =>
-      AnalysisContextImpl_this._recordResolveHtmlTaskResults(task);
-
-  @override
-  DartEntry visitScanDartTask(ScanDartTask task) =>
-      AnalysisContextImpl_this._recordScanDartTaskResults(task);
-}
-
-class AnalysisContextImpl_ContextRetentionPolicy
-    implements CacheRetentionPolicy {
-  final AnalysisContextImpl AnalysisContextImpl_this;
-
-  AnalysisContextImpl_ContextRetentionPolicy(this.AnalysisContextImpl_this);
-
-  @override
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) {
-    int priorityCount = AnalysisContextImpl_this._priorityOrder.length;
-    for (int i = 0; i < priorityCount; i++) {
-      if (source == AnalysisContextImpl_this._priorityOrder[i]) {
-        return RetentionPriority.HIGH;
-      }
-    }
-    if (AnalysisContextImpl_this._neededForResolution != null &&
-        AnalysisContextImpl_this._neededForResolution.contains(source)) {
-      return RetentionPriority.HIGH;
-    }
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      if (_astIsNeeded(dartEntry)) {
-        return RetentionPriority.MEDIUM;
-      }
-    }
-    return RetentionPriority.LOW;
-  }
-
-  bool _astIsNeeded(DartEntry dartEntry) =>
-      dartEntry.hasInvalidData(DartEntry.HINTS) ||
-          dartEntry.hasInvalidData(DartEntry.LINTS) ||
-          dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) ||
-          dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS);
-}
-
-/**
- * An object used to construct a list of the libraries that must be resolved
- * together in order to resolve any one of the libraries.
- */
-class AnalysisContextImpl_CycleBuilder {
-  final AnalysisContextImpl AnalysisContextImpl_this;
-
-  /**
-   * A table mapping the sources of the defining compilation units of libraries
-   * to the representation of the library that has the information needed to
-   * resolve the library.
-   */
-  HashMap<Source, ResolvableLibrary> _libraryMap =
-      new HashMap<Source, ResolvableLibrary>();
-
-  /**
-   * The dependency graph used to compute the libraries in the cycle.
-   */
-  DirectedGraph<ResolvableLibrary> _dependencyGraph;
-
-  /**
-   * A list containing the libraries that are ready to be resolved.
-   */
-  List<ResolvableLibrary> _librariesInCycle;
-
-  /**
-   * The analysis task that needs to be performed before the cycle of libraries
-   * can be resolved, or `null` if the libraries are ready to be resolved.
-   */
-  AnalysisContextImpl_TaskData _taskData;
-
-  /**
-   * Initialize a newly created cycle builder.
-   */
-  AnalysisContextImpl_CycleBuilder(this.AnalysisContextImpl_this) : super();
-
-  /**
-   * Return a list containing the libraries that are ready to be resolved
-   * (assuming that [getTaskData] returns `null`).
-   */
-  List<ResolvableLibrary> get librariesInCycle => _librariesInCycle;
-
-  /**
-   * Return a representation of an analysis task that needs to be performed
-   * before the cycle of libraries can be resolved, or `null` if the libraries
-   * are ready to be resolved.
-   */
-  AnalysisContextImpl_TaskData get taskData => _taskData;
-
-  /**
-   * Compute a list of the libraries that need to be resolved together in orde
-   *  to resolve the given [librarySource].
-   */
-  void computeCycleContaining(Source librarySource) {
-    //
-    // Create the object representing the library being resolved.
-    //
-    ResolvableLibrary targetLibrary = _createLibrary(librarySource);
-    //
-    // Compute the set of libraries that need to be resolved together.
-    //
-    _dependencyGraph = new DirectedGraph<ResolvableLibrary>();
-    _computeLibraryDependencies(targetLibrary);
-    if (_taskData != null) {
-      return;
-    }
-    _librariesInCycle = _dependencyGraph.findCycleContaining(targetLibrary);
-    //
-    // Ensure that all of the data needed to resolve them has been computed.
-    //
-    _ensureImportsAndExports();
-    if (_taskData != null) {
-      // At least one imported library needs to be resolved before the target
-      // library.
-      AnalysisTask task = _taskData.task;
-      if (task is ResolveDartLibraryTask) {
-        AnalysisContextImpl_this._workManager
-            .addFirst(task.librarySource, SourcePriority.LIBRARY);
-      }
-      return;
-    }
-    _computePartsInCycle(librarySource);
-    if (_taskData != null) {
-      // At least one part needs to be parsed.
-      return;
-    }
-    // All of the AST's necessary to perform a resolution of the library cycle
-    // have been gathered, so it is no longer necessary to retain them in the
-    // cache.
-    AnalysisContextImpl_this._neededForResolution = null;
-  }
-
-  bool _addDependency(ResolvableLibrary dependant, Source dependency,
-      List<ResolvableLibrary> dependencyList) {
-    if (dependant.librarySource == dependency) {
-      // Don't add a dependency of a library on itself; there's no point.
-      return true;
-    }
-    ResolvableLibrary importedLibrary = _libraryMap[dependency];
-    if (importedLibrary == null) {
-      importedLibrary = _createLibraryOrNull(dependency);
-      if (importedLibrary != null) {
-        _computeLibraryDependencies(importedLibrary);
-        if (_taskData != null) {
-          return false;
-        }
-      }
-    }
-    if (importedLibrary != null) {
-      if (dependencyList != null) {
-        dependencyList.add(importedLibrary);
-      }
-      _dependencyGraph.addEdge(dependant, importedLibrary);
-    }
-    return true;
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given [library],
-   * creating instances of the class [Library] to represent them, and record the
-   * references in the library objects.
-   *
-   * Throws an [AnalysisException] if some portion of the library graph could
-   * not be traversed.
-   */
-  void _computeLibraryDependencies(ResolvableLibrary library) {
-    Source librarySource = library.librarySource;
-    DartEntry dartEntry =
-        AnalysisContextImpl_this._getReadableDartEntry(librarySource);
-    List<Source> importedSources =
-        _getSources(librarySource, dartEntry, DartEntry.IMPORTED_LIBRARIES);
-    if (_taskData != null) {
-      return;
-    }
-    List<Source> exportedSources =
-        _getSources(librarySource, dartEntry, DartEntry.EXPORTED_LIBRARIES);
-    if (_taskData != null) {
-      return;
-    }
-    _computeLibraryDependenciesFromDirectives(
-        library, importedSources, exportedSources);
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given [library],
-   * creating instances of the class [Library] to represent them, and record the
-   * references in the library objects. The [importedSources] is a list
-   * containing the sources that are imported into the given library. The
-   * [exportedSources] is a list containing the sources that are exported from
-   * the given library.
-   */
-  void _computeLibraryDependenciesFromDirectives(ResolvableLibrary library,
-      List<Source> importedSources, List<Source> exportedSources) {
-    int importCount = importedSources.length;
-    List<ResolvableLibrary> importedLibraries = new List<ResolvableLibrary>();
-    bool explicitlyImportsCore = false;
-    bool importsAsync = false;
-    for (int i = 0; i < importCount; i++) {
-      Source importedSource = importedSources[i];
-      if (importedSource == AnalysisContextImpl_this._coreLibrarySource) {
-        explicitlyImportsCore = true;
-      } else if (importedSource ==
-          AnalysisContextImpl_this._asyncLibrarySource) {
-        importsAsync = true;
-      }
-      if (!_addDependency(library, importedSource, importedLibraries)) {
-        return;
-      }
-    }
-    library.explicitlyImportsCore = explicitlyImportsCore;
-    if (!explicitlyImportsCore) {
-      if (!_addDependency(library, AnalysisContextImpl_this._coreLibrarySource,
-          importedLibraries)) {
-        return;
-      }
-    }
-    if (!importsAsync) {
-      // Add a dependency on async to ensure that the Future element will be
-      // built before we generate errors and warnings for async methods.  Also
-      // include it in importedLibraries, so that it will be picked up by
-      // LibraryResolver2._buildLibraryMap().
-      // TODO(paulberry): this is a bit of a hack, since the async library
-      // isn't actually being imported.  Also, it's not clear whether it should
-      // be necessary: in theory, dart:core already (indirectly) imports
-      // dart:async, so if core has been built, async should have been built
-      // too.  However, removing this code causes unit test failures.
-      if (!_addDependency(library, AnalysisContextImpl_this._asyncLibrarySource,
-          importedLibraries)) {
-        return;
-      }
-    }
-    library.importedLibraries = importedLibraries;
-    int exportCount = exportedSources.length;
-    if (exportCount > 0) {
-      List<ResolvableLibrary> exportedLibraries = new List<ResolvableLibrary>();
-      for (int i = 0; i < exportCount; i++) {
-        Source exportedSource = exportedSources[i];
-        if (!_addDependency(library, exportedSource, exportedLibraries)) {
-          return;
-        }
-      }
-      library.exportedLibraries = exportedLibraries;
-    }
-  }
-
-  /**
-   * Gather the resolvable AST structures for each of the compilation units in
-   * each of the libraries in the cycle. This is done in two phases: first we
-   * ensure that we have cached an AST structure for each compilation unit, then
-   * we gather them. We split the work this way because getting the AST
-   * structures can change the state of the cache in such a way that we would
-   * have more work to do if any compilation unit didn't have a resolvable AST
-   * structure.
-   */
-  void _computePartsInCycle(Source librarySource) {
-    int count = _librariesInCycle.length;
-    List<CycleBuilder_LibraryPair> libraryData =
-        new List<CycleBuilder_LibraryPair>();
-    for (int i = 0; i < count; i++) {
-      ResolvableLibrary library = _librariesInCycle[i];
-      libraryData.add(new CycleBuilder_LibraryPair(
-          library, _ensurePartsInLibrary(library)));
-    }
-    AnalysisContextImpl_this._neededForResolution = _gatherSources(libraryData);
-    if (AnalysisContextImpl._TRACE_PERFORM_TASK) {
-      print(
-          "  preserve resolution data for ${AnalysisContextImpl_this._neededForResolution.length} sources while resolving ${librarySource.fullName}");
-    }
-    if (_taskData != null) {
-      return;
-    }
-    for (int i = 0; i < count; i++) {
-      _computePartsInLibrary(libraryData[i]);
-    }
-  }
-
-  /**
-   * Gather the resolvable compilation units for each of the compilation units
-   * in the library represented by the [libraryPair].
-   */
-  void _computePartsInLibrary(CycleBuilder_LibraryPair libraryPair) {
-    ResolvableLibrary library = libraryPair.library;
-    List<CycleBuilder_SourceEntryPair> entryPairs = libraryPair.entryPairs;
-    int count = entryPairs.length;
-    List<ResolvableCompilationUnit> units =
-        new List<ResolvableCompilationUnit>(count);
-    for (int i = 0; i < count; i++) {
-      CycleBuilder_SourceEntryPair entryPair = entryPairs[i];
-      Source source = entryPair.source;
-      DartEntry dartEntry = entryPair.entry;
-      units[i] = new ResolvableCompilationUnit(
-          source, dartEntry.resolvableCompilationUnit);
-    }
-    library.resolvableCompilationUnits = units;
-  }
-
-  /**
-   * Create an object to represent the information about the library defined by
-   * the compilation unit with the given [librarySource].
-   */
-  ResolvableLibrary _createLibrary(Source librarySource) {
-    ResolvableLibrary library = new ResolvableLibrary(librarySource);
-    SourceEntry sourceEntry =
-        AnalysisContextImpl_this._cache.get(librarySource);
-    if (sourceEntry is DartEntry) {
-      LibraryElementImpl libraryElement =
-          sourceEntry.getValue(DartEntry.ELEMENT) as LibraryElementImpl;
-      if (libraryElement != null) {
-        library.libraryElement = libraryElement;
-      }
-    }
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Create an object to represent the information about the library defined by
-   * the compilation unit with the given [librarySource].
-   */
-  ResolvableLibrary _createLibraryOrNull(Source librarySource) {
-    ResolvableLibrary library = new ResolvableLibrary(librarySource);
-    SourceEntry sourceEntry =
-        AnalysisContextImpl_this._cache.get(librarySource);
-    if (sourceEntry is DartEntry) {
-      LibraryElementImpl libraryElement =
-          sourceEntry.getValue(DartEntry.ELEMENT) as LibraryElementImpl;
-      if (libraryElement != null) {
-        library.libraryElement = libraryElement;
-      }
-    }
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Ensure that the given [library] has an element model built for it. If
-   * another task needs to be executed first in order to build the element
-   * model, that task is placed in [taskData].
-   */
-  void _ensureElementModel(ResolvableLibrary library) {
-    Source librarySource = library.librarySource;
-    DartEntry libraryEntry =
-        AnalysisContextImpl_this._getReadableDartEntry(librarySource);
-    if (libraryEntry != null &&
-        libraryEntry.getState(DartEntry.PARSED_UNIT) != CacheState.ERROR) {
-      AnalysisContextImpl_this._workManager
-          .addFirst(librarySource, SourcePriority.LIBRARY);
-      if (_taskData == null) {
-        _taskData = AnalysisContextImpl_this._createResolveDartLibraryTask(
-            librarySource, libraryEntry);
-      }
-    }
-  }
-
-  /**
-   * Ensure that all of the libraries that are exported by the given [library]
-   * (but are not themselves in the cycle) have element models built for them.
-   * If another task needs to be executed first in order to build the element
-   * model, that task is placed in [taskData].
-   */
-  void _ensureExports(
-      ResolvableLibrary library, HashSet<Source> visitedLibraries) {
-    List<ResolvableLibrary> dependencies = library.exports;
-    int dependencyCount = dependencies.length;
-    for (int i = 0; i < dependencyCount; i++) {
-      ResolvableLibrary dependency = dependencies[i];
-      if (!_librariesInCycle.contains(dependency) &&
-          visitedLibraries.add(dependency.librarySource)) {
-        if (dependency.libraryElement == null) {
-          _ensureElementModel(dependency);
-        } else {
-          _ensureExports(dependency, visitedLibraries);
-        }
-        if (_taskData != null) {
-          return;
-        }
-      }
-    }
-  }
-
-  /**
-   * Ensure that all of the libraries that are exported by the given [library]
-   * (but are not themselves in the cycle) have element models built for them.
-   * If another task needs to be executed first in order to build the element
-   * model, that task is placed in [taskData].
-   */
-  void _ensureImports(ResolvableLibrary library) {
-    List<ResolvableLibrary> dependencies = library.imports;
-    int dependencyCount = dependencies.length;
-    for (int i = 0; i < dependencyCount; i++) {
-      ResolvableLibrary dependency = dependencies[i];
-      if (!_librariesInCycle.contains(dependency) &&
-          dependency.libraryElement == null) {
-        _ensureElementModel(dependency);
-        if (_taskData != null) {
-          return;
-        }
-      }
-    }
-  }
-
-  /**
-   * Ensure that all of the libraries that are either imported or exported by
-   * libraries in the cycle (but are not themselves in the cycle) have element
-   * models built for them.
-   */
-  void _ensureImportsAndExports() {
-    HashSet<Source> visitedLibraries = new HashSet<Source>();
-    int libraryCount = _librariesInCycle.length;
-    for (int i = 0; i < libraryCount; i++) {
-      ResolvableLibrary library = _librariesInCycle[i];
-      _ensureImports(library);
-      if (_taskData != null) {
-        return;
-      }
-      _ensureExports(library, visitedLibraries);
-      if (_taskData != null) {
-        return;
-      }
-    }
-  }
-
-  /**
-   * Ensure that there is a resolvable compilation unit available for all of the
-   * compilation units in the given [library].
-   */
-  List<CycleBuilder_SourceEntryPair> _ensurePartsInLibrary(
-      ResolvableLibrary library) {
-    List<CycleBuilder_SourceEntryPair> pairs =
-        new List<CycleBuilder_SourceEntryPair>();
-    Source librarySource = library.librarySource;
-    DartEntry libraryEntry =
-        AnalysisContextImpl_this._getReadableDartEntry(librarySource);
-    if (libraryEntry == null) {
-      throw new AnalysisException(
-          "Cannot find entry for ${librarySource.fullName}");
-    } else if (libraryEntry.getState(DartEntry.PARSED_UNIT) ==
-        CacheState.ERROR) {
-      String message =
-          "Cannot compute parsed unit for ${librarySource.fullName}";
-      CaughtException exception = libraryEntry.exception;
-      if (exception == null) {
-        throw new AnalysisException(message);
-      }
-      throw new AnalysisException(
-          message, new CaughtException(exception, null));
-    }
-    _ensureResolvableCompilationUnit(librarySource, libraryEntry);
-    pairs.add(new CycleBuilder_SourceEntryPair(librarySource, libraryEntry));
-    List<Source> partSources =
-        _getSources(librarySource, libraryEntry, DartEntry.INCLUDED_PARTS);
-    int count = partSources.length;
-    for (int i = 0; i < count; i++) {
-      Source partSource = partSources[i];
-      DartEntry partEntry =
-          AnalysisContextImpl_this._getReadableDartEntry(partSource);
-      if (partEntry != null &&
-          partEntry.getState(DartEntry.PARSED_UNIT) != CacheState.ERROR) {
-        _ensureResolvableCompilationUnit(partSource, partEntry);
-        pairs.add(new CycleBuilder_SourceEntryPair(partSource, partEntry));
-      }
-    }
-    return pairs;
-  }
-
-  /**
-   * Ensure that there is a resolvable compilation unit available for the given
-   * [source].
-   */
-  void _ensureResolvableCompilationUnit(Source source, DartEntry dartEntry) {
-    // The entry will be null if the source represents a non-Dart file.
-    if (dartEntry != null && !dartEntry.hasResolvableCompilationUnit) {
-      if (_taskData == null) {
-        _taskData =
-            AnalysisContextImpl_this._createParseDartTask(source, dartEntry);
-      }
-    }
-  }
-
-  HashSet<Source> _gatherSources(List<CycleBuilder_LibraryPair> libraryData) {
-    int libraryCount = libraryData.length;
-    HashSet<Source> sources = new HashSet<Source>();
-    for (int i = 0; i < libraryCount; i++) {
-      List<CycleBuilder_SourceEntryPair> entryPairs = libraryData[i].entryPairs;
-      int entryCount = entryPairs.length;
-      for (int j = 0; j < entryCount; j++) {
-        sources.add(entryPairs[j].source);
-      }
-    }
-    return sources;
-  }
-
-  /**
-   * Return the sources described by the given [descriptor].
-   */
-  List<Source> _getSources(Source source, DartEntry dartEntry,
-      DataDescriptor<List<Source>> descriptor) {
-    if (dartEntry == null) {
-      return Source.EMPTY_LIST;
-    }
-    CacheState exportState = dartEntry.getState(descriptor);
-    if (exportState == CacheState.ERROR) {
-      return Source.EMPTY_LIST;
-    } else if (exportState != CacheState.VALID) {
-      if (_taskData == null) {
-        _taskData =
-            AnalysisContextImpl_this._createParseDartTask(source, dartEntry);
-      }
-      return Source.EMPTY_LIST;
-    }
-    return dartEntry.getValue(descriptor);
-  }
-}
-
-/**
- * Information about the next task to be performed. Each data has an implicit
- * associated source: the source that might need to be analyzed. There are
- * essentially three states that can be represented:
- *
- * * If [getTask] returns a non-`null` value, then that is the task that should
- *   be executed to further analyze the associated source.
- * * Otherwise, if [isBlocked] returns `true`, then there is no work that can be
- *   done, but analysis for the associated source is not complete.
- * * Otherwise, [getDependentSource] should return a source that needs to be
- *   analyzed before the analysis of the associated source can be completed.
- */
-class AnalysisContextImpl_TaskData {
-  /**
-   * The task that is to be performed.
-   */
-  final AnalysisTask task;
-
-  /**
-   * A flag indicating whether the associated source is blocked waiting for its
-   * contents to be loaded.
-   */
-  final bool _blocked;
-
-  /**
-   * Initialize a newly created data holder.
-   */
-  AnalysisContextImpl_TaskData(this.task, this._blocked);
-
-  /**
-   * Return `true` if the associated source is blocked waiting for its contents
-   * to be loaded.
-   */
-  bool get isBlocked => _blocked;
-
-  @override
-  String toString() {
-    if (task == null) {
-      return "blocked: $_blocked";
-    }
-    return task.toString();
-  }
-}
-
-/**
- * Statistics and information about a single [AnalysisContext].
- */
-abstract class AnalysisContextStatistics {
-  /**
-   * Return the statistics for each kind of cached data.
-   */
-  List<AnalysisContextStatistics_CacheRow> get cacheRows;
-
-  /**
-   * Return the exceptions that caused some entries to have a state of
-   * [CacheState.ERROR].
-   */
-  List<CaughtException> get exceptions;
-
-  /**
-   * Return information about each of the partitions in the cache.
-   */
-  List<AnalysisContextStatistics_PartitionData> get partitionData;
-
-  /**
-   * Return a list containing all of the sources in the cache.
-   */
-  List<Source> get sources;
-}
-
-/**
- * Information about single piece of data in the cache.
- */
-abstract class AnalysisContextStatistics_CacheRow {
-  /**
-   * List of possible states which can be queried.
-   */
-  static const List<CacheState> STATES = const <CacheState>[
-    CacheState.ERROR,
-    CacheState.FLUSHED,
-    CacheState.IN_PROCESS,
-    CacheState.INVALID,
-    CacheState.VALID
-  ];
-
-  /**
-   * Return the number of entries whose state is [CacheState.ERROR].
-   */
-  int get errorCount;
-
-  /**
-   * Return the number of entries whose state is [CacheState.FLUSHED].
-   */
-  int get flushedCount;
-
-  /**
-   * Return the number of entries whose state is [CacheState.IN_PROCESS].
-   */
-  int get inProcessCount;
-
-  /**
-   * Return the number of entries whose state is [CacheState.INVALID].
-   */
-  int get invalidCount;
-
-  /**
-   * Return the name of the data represented by this object.
-   */
-  String get name;
-
-  /**
-   * Return the number of entries whose state is [CacheState.VALID].
-   */
-  int get validCount;
-
-  /**
-   * Return the number of entries whose state is [state].
-   */
-  int getCount(CacheState state);
-}
-
-/**
- * Information about a single partition in the cache.
- */
-abstract class AnalysisContextStatistics_PartitionData {
-  /**
-   * Return the number of entries in the partition that have an AST structure in
-   * one state or another.
-   */
-  int get astCount;
-
-  /**
-   * Return the total number of entries in the partition.
-   */
-  int get totalCount;
-}
-
-/**
- * Implementation of the [AnalysisContextStatistics].
- */
-class AnalysisContextStatisticsImpl implements AnalysisContextStatistics {
-  Map<String, AnalysisContextStatistics_CacheRow> _dataMap =
-      new HashMap<String, AnalysisContextStatistics_CacheRow>();
-
-  List<Source> _sources = new List<Source>();
-
-  HashSet<CaughtException> _exceptions = new HashSet<CaughtException>();
-
-  List<AnalysisContextStatistics_PartitionData> _partitionData;
-
-  @override
-  List<AnalysisContextStatistics_CacheRow> get cacheRows =>
-      _dataMap.values.toList();
-
-  @override
-  List<CaughtException> get exceptions => new List.from(_exceptions);
-
-  @override
-  List<AnalysisContextStatistics_PartitionData> get partitionData =>
-      _partitionData;
-
-  /**
-   * Set the partition data returned by this object to the given data.
-   */
-  void set partitionData(List<AnalysisContextStatistics_PartitionData> data) {
-    _partitionData = data;
-  }
-
-  @override
-  List<Source> get sources => _sources;
-
-  void addSource(Source source) {
-    _sources.add(source);
-  }
-
-  void _internalPutCacheItem(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state) {
-    String rowName = rowDesc.toString();
-    AnalysisContextStatisticsImpl_CacheRowImpl row =
-        _dataMap[rowName] as AnalysisContextStatisticsImpl_CacheRowImpl;
-    if (row == null) {
-      row = new AnalysisContextStatisticsImpl_CacheRowImpl(rowName);
-      _dataMap[rowName] = row;
-    }
-    row._incState(state);
-    if (state == CacheState.ERROR) {
-      CaughtException exception = dartEntry.exception;
-      if (exception != null) {
-        _exceptions.add(exception);
-      }
-    }
-  }
-}
-
-class AnalysisContextStatisticsImpl_CacheRowImpl
-    implements AnalysisContextStatistics_CacheRow {
-  final String name;
-
-  Map<CacheState, int> _counts = <CacheState, int>{};
-
-  AnalysisContextStatisticsImpl_CacheRowImpl(this.name);
-
-  @override
-  int get errorCount => getCount(CacheState.ERROR);
-
-  @override
-  int get flushedCount => getCount(CacheState.FLUSHED);
-
-  @override
-  int get hashCode => name.hashCode;
-
-  @override
-  int get inProcessCount => getCount(CacheState.IN_PROCESS);
-
-  @override
-  int get invalidCount => getCount(CacheState.INVALID);
-
-  @override
-  int get validCount => getCount(CacheState.VALID);
-
-  @override
-  bool operator ==(Object obj) =>
-      obj is AnalysisContextStatisticsImpl_CacheRowImpl && obj.name == name;
-
-  @override
-  int getCount(CacheState state) {
-    int count = _counts[state];
-    if (count != null) {
-      return count;
-    } else {
-      return 0;
-    }
-  }
-
-  void _incState(CacheState state) {
-    if (_counts[state] == null) {
-      _counts[state] = 1;
-    } else {
-      _counts[state]++;
-    }
-  }
-}
-
-class AnalysisContextStatisticsImpl_PartitionDataImpl
-    implements AnalysisContextStatistics_PartitionData {
-  final int astCount;
-
-  final int totalCount;
-
-  AnalysisContextStatisticsImpl_PartitionDataImpl(
-      this.astCount, this.totalCount);
-}
-
-/**
  * A representation of changes to the types of analysis that should be
  * performed.
  */
@@ -5830,7 +675,7 @@
   }
 
   /**
-   * Appendto the given [buffer] all sources with the given analysis [level],
+   * Append to the given [buffer] all sources with the given analysis [level],
    * prefixed with a label and a separator if [needsSeparator] is `true`.
    */
   bool _appendSources(
@@ -5917,39 +762,17 @@
       InstrumentationService.NULL_SERVICE;
 
   /**
-   * The list of supported plugins for processing by clients.
-   */
-  List<Plugin> _supportedPlugins;
-
-  /**
    * The partition manager being used to manage the shared partitions.
    */
   final PartitionManager partitionManager = new PartitionManager();
 
   /**
-   * The partition manager being used to manage the shared partitions.
-   */
-  final newContext.PartitionManager partitionManager_new =
-      new newContext.PartitionManager();
-
-  /**
-   * A flag indicating whether the (new) task model should be used to perform
-   * analysis.
-   */
-  bool useTaskModel = true;
-
-  /**
    * A flag indicating whether the task model should attempt to limit
    * invalidation after a change.
    */
   bool limitInvalidationInTaskModel = false;
 
   /**
-   * The plugins that are defined outside the `analyzer` package.
-   */
-  List<Plugin> _userDefinedPlugins = <Plugin>[];
-
-  /**
    * The task manager used to manage the tasks used to analyze code.
    */
   TaskManager _taskManager;
@@ -5989,26 +812,20 @@
   }
 
   /**
-   * Return the list of supported plugins for processing by clients.
+   * Return the list of plugins that clients are required to process, either by
+   * creating an [ExtensionManager] or by using the method
+   * [processRequiredPlugins].
    */
-  List<Plugin> get supportedPlugins {
-    if (_supportedPlugins == null) {
-      _supportedPlugins = <Plugin>[
-        enginePlugin,
-        commandLinePlugin,
-        optionsPlugin
-      ];
-      _supportedPlugins.addAll(_userDefinedPlugins);
-    }
-    return _supportedPlugins;
-  }
+  List<Plugin> get requiredPlugins => <Plugin>[enginePlugin];
 
   /**
    * Return the task manager used to manage the tasks used to analyze code.
    */
   TaskManager get taskManager {
     if (_taskManager == null) {
-      new ExtensionManager().processPlugins(supportedPlugins);
+      if (enginePlugin.taskExtensionPoint == null) {
+        processRequiredPlugins();
+      }
       _taskManager = new TaskManager();
       _taskManager.addTaskDescriptors(enginePlugin.taskDescriptors);
       // TODO(brianwilkerson) Create a way to associate different results with
@@ -6019,18 +836,6 @@
   }
 
   /**
-   * Set plugins that are defined outside the `analyzer` package.
-   */
-  void set userDefinedPlugins(List<Plugin> plugins) {
-    if (plugins == null) {
-      plugins = <Plugin>[];
-    }
-    _userDefinedPlugins = plugins;
-    _supportedPlugins = null;
-    _taskManager = null;
-  }
-
-  /**
    * Clear any caches holding on to analysis results so that a full re-analysis
    * will be performed the next time an analysis context is created.
    */
@@ -6042,13 +847,20 @@
    * Create and return a new context in which analysis can be performed.
    */
   AnalysisContext createAnalysisContext() {
-    if (useTaskModel) {
-      return new newContext.AnalysisContextImpl();
-    }
     return new AnalysisContextImpl();
   }
 
   /**
+   * A utility method that clients can use to process all of the required
+   * plugins. This method can only be used by clients that do not need to
+   * process any other plugins.
+   */
+  void processRequiredPlugins() {
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(requiredPlugins);
+  }
+
+  /**
    * Return `true` if the given [fileName] is an analysis options file.
    */
   static bool isAnalysisOptionsFileName(String fileName,
@@ -6192,22 +1004,10 @@
   void parsedDart(AnalysisContext context, Source source, CompilationUnit unit);
 
   /**
-   * Reports that the given HTML [source] was parsed in the given [context].
-   */
-  @deprecated
-  void parsedHtml(AnalysisContext context, Source source, ht.HtmlUnit unit);
-
-  /**
    * Reports that the given Dart [source] was resolved in the given [context].
    */
   void resolvedDart(
       AnalysisContext context, Source source, CompilationUnit unit);
-
-  /**
-   * Reports that the given HTML [source] was resolved in the given [context].
-   */
-  @deprecated
-  void resolvedHtml(AnalysisContext context, Source source, ht.HtmlUnit unit);
 }
 
 /**
@@ -6225,18 +1025,6 @@
  */
 abstract class AnalysisOptions {
   /**
-   * If analysis is to parse and analyze all function bodies, return `true`.
-   * If analysis is to skip all function bodies, return `false`.  If analysis
-   * is to parse and analyze function bodies in some sources and not in others,
-   * throw an exception.
-   *
-   * This getter is deprecated; consider using [analyzeFunctionBodiesPredicate]
-   * instead.
-   */
-  @deprecated // Use this.analyzeFunctionBodiesPredicate
-  bool get analyzeFunctionBodies;
-
-  /**
    * Function that returns `true` if analysis is to parse and analyze function
    * bodies for a given source.
    */
@@ -6254,22 +1042,19 @@
   bool get dart2jsHint;
 
   /**
-   * Return `true` if analysis is to include the new async support.
+   * Return `true` to enable custom assert messages (DEP 37).
    */
-  @deprecated // Always true
+  bool get enableAssertMessage;
+
+  /**
+   * Return `true` to if analysis is to enable async support.
+   */
   bool get enableAsync;
 
   /**
-   * Return `true` if analysis is to include the new deferred loading support.
+   * Return `true` to enable interface libraries (DEP 40).
    */
-  @deprecated // Always true
-  bool get enableDeferredLoading;
-
-  /**
-   * Return `true` if analysis is to include the new enum support.
-   */
-  @deprecated // Always true
-  bool get enableEnum;
+  bool get enableConditionalDirectives;
 
   /**
    * Return `true` to enable generic methods (DEP 22).
@@ -6277,12 +1062,6 @@
   bool get enableGenericMethods => null;
 
   /**
-   * Return `true` to enable null-aware operators (DEP 9).
-   */
-  @deprecated // Always true
-  bool get enableNullAwareOperators;
-
-  /**
    * Return `true` to strictly follow the specification when generating
    * warnings on "call" methods (fixes dartbug.com/21938).
    */
@@ -6356,18 +1135,6 @@
   static const int DEFAULT_CACHE_SIZE = 64;
 
   /**
-   * The default value for enabling deferred loading.
-   */
-  @deprecated
-  static bool DEFAULT_ENABLE_DEFERRED_LOADING = true;
-
-  /**
-   * The default value for enabling enum support.
-   */
-  @deprecated
-  static bool DEFAULT_ENABLE_ENUM = true;
-
-  /**
    * A predicate indicating whether analysis is to parse and analyze function
    * bodies.
    */
@@ -6387,6 +1154,22 @@
   bool dart2jsHint = false;
 
   /**
+   * A flag indicating whether custom assert messages are to be supported (DEP
+   * 37).
+   */
+  bool enableAssertMessage = false;
+
+  /**
+   * A flag indicating whether analysis is to enable async support.
+   */
+  bool enableAsync = true;
+
+  /**
+   * A flag indicating whether interface libraries are to be supported (DEP 40).
+   */
+  bool enableConditionalDirectives = false;
+
+  /**
    * A flag indicating whether generic methods are to be supported (DEP 22).
    */
   bool enableGenericMethods = false;
@@ -6454,6 +1237,14 @@
   bool strongMode = false;
 
   /**
+   * A flag indicating whether strong-mode inference hints should be
+   * used.  This flag is not exposed in the interface, and should be
+   * replaced by something more general.
+   */
+  // TODO(leafp): replace this with something more general
+  bool strongModeHints = false;
+
+  /**
    * Initialize a newly created set of analysis options to have their default
    * values.
    */
@@ -6463,33 +1254,14 @@
    * Initialize a newly created set of analysis options to have the same values
    * as those in the given set of analysis [options].
    */
-  @deprecated // Use new AnalysisOptionsImpl.from(options)
-  AnalysisOptionsImpl.con1(AnalysisOptions options) {
-    analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
-    cacheSize = options.cacheSize;
-    dart2jsHint = options.dart2jsHint;
-    enableStrictCallChecks = options.enableStrictCallChecks;
-    enableSuperMixins = options.enableSuperMixins;
-    generateImplicitErrors = options.generateImplicitErrors;
-    generateSdkErrors = options.generateSdkErrors;
-    hint = options.hint;
-    incremental = options.incremental;
-    incrementalApi = options.incrementalApi;
-    incrementalValidation = options.incrementalValidation;
-    lint = options.lint;
-    preserveComments = options.preserveComments;
-    strongMode = options.strongMode;
-  }
-
-  /**
-   * Initialize a newly created set of analysis options to have the same values
-   * as those in the given set of analysis [options].
-   */
   AnalysisOptionsImpl.from(AnalysisOptions options) {
     analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
     cacheSize = options.cacheSize;
     dart2jsHint = options.dart2jsHint;
+    enableAssertMessage = options.enableAssertMessage;
+    enableAsync = options.enableAsync;
     enableStrictCallChecks = options.enableStrictCallChecks;
+    enableGenericMethods = options.enableGenericMethods;
     enableSuperMixins = options.enableSuperMixins;
     generateImplicitErrors = options.generateImplicitErrors;
     generateSdkErrors = options.generateSdkErrors;
@@ -6500,6 +1272,9 @@
     lint = options.lint;
     preserveComments = options.preserveComments;
     strongMode = options.strongMode;
+    if (options is AnalysisOptionsImpl) {
+      strongModeHints = options.strongModeHints;
+    }
   }
 
   bool get analyzeFunctionBodies {
@@ -6532,42 +1307,6 @@
     _analyzeFunctionBodiesPredicate = value;
   }
 
-  @deprecated
-  @override
-  bool get enableAsync => true;
-
-  @deprecated
-  void set enableAsync(bool enable) {
-    // Async support cannot be disabled
-  }
-
-  @deprecated
-  @override
-  bool get enableDeferredLoading => true;
-
-  @deprecated
-  void set enableDeferredLoading(bool enable) {
-    // Deferred loading support cannot be disabled
-  }
-
-  @deprecated
-  @override
-  bool get enableEnum => true;
-
-  @deprecated
-  void set enableEnum(bool enable) {
-    // Enum support cannot be disabled
-  }
-
-  @deprecated
-  @override
-  bool get enableNullAwareOperators => true;
-
-  @deprecated
-  void set enableNullAwareOperators(bool enable) {
-    // Null-aware operator support cannot be disabled
-  }
-
   /**
    * Predicate used for [analyzeFunctionBodiesPredicate] when
    * [analyzeFunctionBodies] is set to `true`.
@@ -6632,427 +1371,15 @@
 }
 
 /**
- * An analysis task.
+ * The result of applying a [ChangeSet] to a [AnalysisContext].
  */
-abstract class AnalysisTask {
+class ApplyChangesStatus {
   /**
-   * The context in which the task is to be performed.
+   * Is `true` if the given [ChangeSet] caused any changes in the context.
    */
-  final InternalAnalysisContext context;
+  final bool hasChanges;
 
-  /**
-   * The exception that was thrown while performing this task, or `null` if the
-   * task completed successfully.
-   */
-  CaughtException _thrownException;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given
-   * [context].
-   */
-  AnalysisTask(this.context);
-
-  /**
-   * Return the exception that was thrown while performing this task, or `null`
-   * if the task completed successfully.
-   */
-  CaughtException get exception => _thrownException;
-
-  /**
-   * Return a textual description of this task.
-   */
-  String get taskDescription;
-
-  /**
-   * Use the given [visitor] to visit this task. Throws an [AnalysisException]
-   * if the visitor throws the exception.
-   */
-  accept(AnalysisTaskVisitor visitor);
-
-  /**
-   * Perform this analysis task, protected by an exception handler. Throws an
-   * [AnalysisException] if an exception occurs while performing the task.
-   */
-  void internalPerform();
-
-  /**
-   * Perform this analysis task and use the given [visitor] to visit this task
-   * after it has completed. Throws an [AnalysisException] if the visitor throws
-   * the exception.
-   */
-  Object perform(AnalysisTaskVisitor visitor) {
-    try {
-      _safelyPerform();
-    } on AnalysisException catch (exception, stackTrace) {
-      _thrownException = new CaughtException(exception, stackTrace);
-      AnalysisEngine.instance.logger.logInformation(
-          "Task failed: $taskDescription",
-          new CaughtException(exception, stackTrace));
-    }
-    return PerformanceStatistics.analysisTaskVisitor
-        .makeCurrentWhile(() => accept(visitor));
-  }
-
-  @override
-  String toString() => taskDescription;
-
-  /**
-   * Perform this analysis task, ensuring that all exceptions are wrapped in an
-   * [AnalysisException]. Throws an [AnalysisException] if any exception occurs
-   * while performing the task
-   */
-  void _safelyPerform() {
-    try {
-      String contextName = context.name;
-      if (contextName == null) {
-        contextName = 'unnamed';
-      }
-      AnalysisEngine.instance.instrumentationService
-          .logAnalysisTask(contextName, taskDescription);
-      internalPerform();
-    } on AnalysisException {
-      rethrow;
-    } catch (exception, stackTrace) {
-      throw new AnalysisException(
-          exception.toString(), new CaughtException(exception, stackTrace));
-    }
-  }
-}
-
-/**
- * An object used to visit tasks. While tasks are not structured in any
- * interesting way, this class provides the ability to dispatch to an
- * appropriate method.
- */
-abstract class AnalysisTaskVisitor<E> {
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitGenerateDartErrorsTask(GenerateDartErrorsTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitGenerateDartHintsTask(GenerateDartHintsTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitGenerateDartLintsTask(GenerateDartLintsTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitGetContentTask(GetContentTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitIncrementalAnalysisTask(
-      IncrementalAnalysisTask incrementalAnalysisTask);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitParseDartTask(ParseDartTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitParseHtmlTask(ParseHtmlTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitResolveDartLibraryCycleTask(ResolveDartLibraryCycleTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitResolveDartLibraryTask(ResolveDartLibraryTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitResolveDartUnitTask(ResolveDartUnitTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitResolveHtmlTask(ResolveHtmlTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitScanDartTask(ScanDartTask task);
-}
-
-/**
- * A `CachedResult` is a single analysis result that is stored in a
- * [SourceEntry].
- */
-class CachedResult<E> {
-  /**
-   * The state of the cached value.
-   */
-  CacheState state;
-
-  /**
-   * The value being cached, or `null` if there is no value (for example, when
-   * the [state] is [CacheState.INVALID].
-   */
-  E value;
-
-  /**
-   * Initialize a newly created result holder to represent the value of data
-   * described by the given [descriptor].
-   */
-  CachedResult(DataDescriptor descriptor) {
-    state = CacheState.INVALID;
-    value = descriptor.defaultValue;
-  }
-}
-
-/**
- * A single partition in an LRU cache of information related to analysis.
- */
-abstract class CachePartition {
-  /**
-   * The context that owns this partition. Multiple contexts can reference a
-   * partition, but only one context can own it.
-   */
-  final InternalAnalysisContext context;
-
-  /**
-   * The maximum number of sources for which AST structures should be kept in
-   * the cache.
-   */
-  int _maxCacheSize = 0;
-
-  /**
-   * The policy used to determine which pieces of data to remove from the cache.
-   */
-  final CacheRetentionPolicy _retentionPolicy;
-
-  /**
-   * A table mapping the sources belonging to this partition to the information
-   * known about those sources.
-   */
-  HashMap<Source, SourceEntry> _sourceMap = new HashMap<Source, SourceEntry>();
-
-  /**
-   * A list containing the most recently accessed sources with the most recently
-   * used at the end of the list. When more sources are added than the maximum
-   * allowed then the least recently used source will be removed and will have
-   * it's cached AST structure flushed.
-   */
-  List<Source> _recentlyUsed;
-
-  /**
-   * Initialize a newly created cache to maintain at most [maxCacheSize] AST
-   * structures in the cache. The cache is owned by the give [context], and the
-   * [retentionPolicy] will be used to determine which pieces of data to remove
-   * from the cache.
-   */
-  CachePartition(this.context, this._maxCacheSize, this._retentionPolicy) {
-    _recentlyUsed = new List<Source>();
-  }
-
-  /**
-   * Return the number of entries in this partition that have an AST associated
-   * with them.
-   */
-  int get astSize {
-    int astSize = 0;
-    int count = _recentlyUsed.length;
-    for (int i = 0; i < count; i++) {
-      Source source = _recentlyUsed[i];
-      SourceEntry sourceEntry = _sourceMap[source];
-      if (sourceEntry is DartEntry) {
-        if (sourceEntry.anyParsedCompilationUnit != null) {
-          astSize++;
-        }
-      } else if (sourceEntry is HtmlEntry) {
-        if (sourceEntry.anyParsedUnit != null) {
-          astSize++;
-        }
-      }
-    }
-    return astSize;
-  }
-
-  /**
-   * Return a table mapping the sources known to the context to the information
-   * known about the source.
-   *
-   * <b>Note:</b> This method is only visible for use by [AnalysisCache] and
-   * should not be used for any other purpose.
-   */
-  Map<Source, SourceEntry> get map => _sourceMap;
-
-  /**
-   * Set the maximum size of the cache to the given [size].
-   */
-  void set maxCacheSize(int size) {
-    _maxCacheSize = size;
-    while (_recentlyUsed.length > _maxCacheSize) {
-      if (!_flushAstFromCache()) {
-        break;
-      }
-    }
-  }
-
-  /**
-   * Record that the AST associated with the given source was just read from the
-   * cache.
-   */
-  void accessedAst(Source source) {
-    if (_recentlyUsed.remove(source)) {
-      _recentlyUsed.add(source);
-      return;
-    }
-    while (_recentlyUsed.length >= _maxCacheSize) {
-      if (!_flushAstFromCache()) {
-        break;
-      }
-    }
-    _recentlyUsed.add(source);
-  }
-
-  /**
-   * Return `true` if the given [source] is contained in this partition.
-   */
-  bool contains(Source source);
-
-  /**
-   * Return the entry associated with the given [source].
-   */
-  SourceEntry get(Source source) => _sourceMap[source];
-
-  /**
-   * Return an iterator returning all of the map entries mapping sources to
-   * cache entries.
-   */
-  MapIterator<Source, SourceEntry> iterator() =>
-      new SingleMapIterator<Source, SourceEntry>(_sourceMap);
-
-  /**
-   * Associate the given [entry] with the given [source].
-   */
-  void put(Source source, SourceEntry entry) {
-    entry.fixExceptionState();
-    _sourceMap[source] = entry;
-  }
-
-  /**
-   * Remove all information related to the given [source] from this partition.
-   * Return the entry associated with the source, or `null` if there was cache
-   * entry for the source.
-   */
-  SourceEntry remove(Source source) {
-    _recentlyUsed.remove(source);
-    return _sourceMap.remove(source);
-  }
-
-  /**
-   * Record that the AST associated with the given [source] was just removed
-   * from the cache.
-   */
-  void removedAst(Source source) {
-    _recentlyUsed.remove(source);
-  }
-
-  /**
-   * Return the number of sources that are mapped to cache entries.
-   */
-  int size() => _sourceMap.length;
-
-  /**
-   * Record that the AST associated with the given [source] was just stored to
-   * the cache.
-   */
-  void storedAst(Source source) {
-    if (_recentlyUsed.contains(source)) {
-      return;
-    }
-    while (_recentlyUsed.length >= _maxCacheSize) {
-      if (!_flushAstFromCache()) {
-        break;
-      }
-    }
-    _recentlyUsed.add(source);
-  }
-
-  /**
-   * Attempt to flush one AST structure from the cache. Return `true` if a
-   * structure was flushed.
-   */
-  bool _flushAstFromCache() {
-    Source removedSource = _removeAstToFlush();
-    if (removedSource == null) {
-      return false;
-    }
-    SourceEntry sourceEntry = _sourceMap[removedSource];
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      htmlEntry.flushAstStructures();
-    } else if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      dartEntry.flushAstStructures();
-    }
-    return true;
-  }
-
-  /**
-   * Remove and return one source from the list of recently used sources whose
-   * AST structure can be flushed from the cache. The source that will be
-   * returned will be the source that has been unreferenced for the longest
-   * period of time but that is not a priority for analysis.
-   */
-  Source _removeAstToFlush() {
-    int sourceToRemove = -1;
-    for (int i = 0; i < _recentlyUsed.length; i++) {
-      Source source = _recentlyUsed[i];
-      RetentionPriority priority =
-          _retentionPolicy.getAstPriority(source, _sourceMap[source]);
-      if (priority == RetentionPriority.LOW) {
-        return _recentlyUsed.removeAt(i);
-      } else if (priority == RetentionPriority.MEDIUM && sourceToRemove < 0) {
-        sourceToRemove = i;
-      }
-    }
-    if (sourceToRemove < 0) {
-      // This happens if the retention policy returns a priority of HIGH for all
-      // of the sources that have been recently used. This is the case, for
-      // example, when the list of priority sources is bigger than the current
-      // cache size.
-      return null;
-    }
-    return _recentlyUsed.removeAt(sourceToRemove);
-  }
-}
-
-/**
- * An object used to determine how important it is for data to be retained in
- * the analysis cache.
- */
-abstract class CacheRetentionPolicy {
-  /**
-   * Return the priority of retaining the AST structure for the given [source].
-   */
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry);
+  ApplyChangesStatus(this.hasChanges);
 }
 
 /**
@@ -7140,13 +1467,6 @@
   CompilationUnit get resolvedDartUnit;
 
   /**
-   * The fully resolved HTML AST that changed as a result of the analysis, or
-   * `null` if the AST was not changed.
-   */
-  @deprecated
-  ht.HtmlUnit get resolvedHtmlUnit;
-
-  /**
    * Return the source for which the result is being reported.
    */
   Source get source;
@@ -7179,13 +1499,6 @@
   CompilationUnit resolvedDartUnit;
 
   /**
-   * The fully resolved HTML AST that changed as a result of the analysis, or
-   * `null` if the AST was not changed.
-   */
-  @deprecated
-  ht.HtmlUnit resolvedHtmlUnit;
-
-  /**
    * The errors that changed as a result of the analysis, or `null` if errors
    * were not changed.
    */
@@ -7287,7 +1600,8 @@
   /**
    * Return `true` if this change set does not contain any changes.
    */
-  bool get isEmpty => addedSources.isEmpty &&
+  bool get isEmpty =>
+      addedSources.isEmpty &&
       changedSources.isEmpty &&
       _changedContent.isEmpty &&
       changedRanges.isEmpty &&
@@ -7466,7 +1780,7 @@
   /**
    * Initialize a newly created change object to represent a change to the
    * content of a source. The [contents] is the new contents of the source. The
-   * [offse] ist the offset into the current contents. The [oldLength] is the
+   * [offset] is the offset into the current contents. The [oldLength] is the
    * number of characters in the original contents that were replaced. The
    * [newLength] is the number of characters in the replacement text.
    */
@@ -7505,1564 +1819,6 @@
 }
 
 /**
- * A pair containing a library and a list of the (source, entry) pairs for
- * compilation units in the library.
- */
-class CycleBuilder_LibraryPair {
-  /**
-   * The library containing the compilation units.
-   */
-  ResolvableLibrary library;
-
-  /**
-   * The (source, entry) pairs representing the compilation units in the
-   * library.
-   */
-  List<CycleBuilder_SourceEntryPair> entryPairs;
-
-  /**
-   * Initialize a newly created pair from the given [library] and [entryPairs].
-   */
-  CycleBuilder_LibraryPair(this.library, this.entryPairs);
-}
-
-/**
- * A pair containing a source and the cache entry associated with that source.
- * They are used to reduce the number of times an entry must be looked up in the
- * cache.
- */
-class CycleBuilder_SourceEntryPair {
-  /**
-   * The source associated with the entry.
-   */
-  Source source;
-
-  /**
-   * The entry associated with the source.
-   */
-  DartEntry entry;
-
-  /**
-   * Initialize a newly created pair from the given [source] and [entry].
-   */
-  CycleBuilder_SourceEntryPair(this.source, this.entry);
-}
-
-/**
- * The information cached by an analysis context about an individual Dart file.
- */
-class DartEntry extends SourceEntry {
-  /**
-   * The data descriptor representing the element model representing a single
-   * compilation unit. This model is incomplete and should not be used except as
-   * input to another task.
-   */
-  static final DataDescriptor<List<AnalysisError>> BUILT_ELEMENT =
-      new DataDescriptor<List<AnalysisError>>("DartEntry.BUILT_ELEMENT");
-
-  /**
-   * The data descriptor representing the AST structure after the element model
-   * has been built (and declarations are resolved) but before other resolution
-   * has been performed.
-   */
-  static final DataDescriptor<CompilationUnit> BUILT_UNIT =
-      new DataDescriptor<CompilationUnit>("DartEntry.BUILT_UNIT");
-
-  /**
-   * The data descriptor representing the list of libraries that contain this
-   * compilation unit.
-   */
-  static final DataDescriptor<List<Source>> CONTAINING_LIBRARIES =
-      new DataDescriptor<List<Source>>(
-          "DartEntry.CONTAINING_LIBRARIES", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the library element for the library. This
-   * data is only available for Dart files that are the defining compilation
-   * unit of a library.
-   */
-  static final DataDescriptor<LibraryElement> ELEMENT =
-      new DataDescriptor<LibraryElement>("DartEntry.ELEMENT");
-
-  /**
-   * The data descriptor representing the list of exported libraries. This data
-   * is only available for Dart files that are the defining compilation unit of
-   * a library.
-   */
-  static final DataDescriptor<List<Source>> EXPORTED_LIBRARIES =
-      new DataDescriptor<List<Source>>(
-          "DartEntry.EXPORTED_LIBRARIES", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the hints resulting from auditing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> HINTS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.HINTS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the list of imported libraries. This data
-   * is only available for Dart files that are the defining compilation unit of
-   * a library.
-   */
-  static final DataDescriptor<List<Source>> IMPORTED_LIBRARIES =
-      new DataDescriptor<List<Source>>(
-          "DartEntry.IMPORTED_LIBRARIES", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the list of included parts. This data is
-   * only available for Dart files that are the defining compilation unit of a
-   * library.
-   */
-  static final DataDescriptor<List<Source>> INCLUDED_PARTS =
-      new DataDescriptor<List<Source>>(
-          "DartEntry.INCLUDED_PARTS", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the client flag. This data is only
-   * available for Dart files that are the defining compilation unit of a
-   * library.
-   */
-  static final DataDescriptor<bool> IS_CLIENT =
-      new DataDescriptor<bool>("DartEntry.IS_CLIENT", false);
-
-  /**
-   * The data descriptor representing the launchable flag. This data is only
-   * available for Dart files that are the defining compilation unit of a
-   * library.
-   */
-  static final DataDescriptor<bool> IS_LAUNCHABLE =
-      new DataDescriptor<bool>("DartEntry.IS_LAUNCHABLE", false);
-
-  /**
-   * The data descriptor representing lint warnings resulting from auditing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> LINTS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.LINTS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the errors resulting from parsing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> PARSE_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.PARSE_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the parsed AST structure.
-   */
-  static final DataDescriptor<CompilationUnit> PARSED_UNIT =
-      new DataDescriptor<CompilationUnit>("DartEntry.PARSED_UNIT");
-
-  /**
-   * The data descriptor representing the public namespace of the library. This
-   * data is only available for Dart files that are the defining compilation
-   * unit of a library.
-   */
-  static final DataDescriptor<Namespace> PUBLIC_NAMESPACE =
-      new DataDescriptor<Namespace>("DartEntry.PUBLIC_NAMESPACE");
-
-  /**
-   * The data descriptor representing the errors resulting from resolving the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.RESOLUTION_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the resolved AST structure.
-   */
-  static final DataDescriptor<CompilationUnit> RESOLVED_UNIT =
-      new DataDescriptor<CompilationUnit>("DartEntry.RESOLVED_UNIT");
-
-  /**
-   * The data descriptor representing the errors resulting from scanning the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> SCAN_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.SCAN_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the source kind.
-   */
-  static final DataDescriptor<SourceKind> SOURCE_KIND =
-      new DataDescriptor<SourceKind>(
-          "DartEntry.SOURCE_KIND", SourceKind.UNKNOWN);
-
-  /**
-   * The data descriptor representing the token stream.
-   */
-  static final DataDescriptor<Token> TOKEN_STREAM =
-      new DataDescriptor<Token>("DartEntry.TOKEN_STREAM");
-
-  /**
-   * The data descriptor representing the errors resulting from verifying the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> VERIFICATION_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.VERIFICATION_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The list of libraries that contain this compilation unit. The list will be
-   * empty if there are no known libraries that contain this compilation unit.
-   */
-  List<Source> _containingLibraries = new List<Source>();
-
-  /**
-   * The information known as a result of resolving this compilation unit as
-   * part of the library that contains this unit. This field will never be
-   * `null`.
-   */
-  ResolutionState _resolutionState = new ResolutionState();
-
-  /**
-   * Return all of the errors associated with the compilation unit that are
-   * currently cached.
-   */
-  List<AnalysisError> get allErrors {
-    List<AnalysisError> errors = new List<AnalysisError>();
-    errors.addAll(super.allErrors);
-    errors.addAll(getValue(SCAN_ERRORS));
-    errors.addAll(getValue(PARSE_ERRORS));
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      errors.addAll(state.getValue(RESOLUTION_ERRORS));
-      errors.addAll(state.getValue(VERIFICATION_ERRORS));
-      errors.addAll(state.getValue(HINTS));
-      errors.addAll(state.getValue(LINTS));
-      state = state._nextState;
-    }
-    if (errors.length == 0) {
-      return AnalysisError.NO_ERRORS;
-    }
-    return errors;
-  }
-
-  /**
-   * Return a valid parsed compilation unit, either an unresolved AST structure
-   * or the result of resolving the AST structure in the context of some
-   * library, or `null` if there is no parsed compilation unit available.
-   */
-  CompilationUnit get anyParsedCompilationUnit {
-    if (getState(PARSED_UNIT) == CacheState.VALID) {
-      return getValue(PARSED_UNIT);
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (state.getState(BUILT_UNIT) == CacheState.VALID) {
-        return state.getValue(BUILT_UNIT);
-      }
-      state = state._nextState;
-    }
-
-    return anyResolvedCompilationUnit;
-  }
-
-  /**
-   * Return the result of resolving the compilation unit as part of any library,
-   * or `null` if there is no cached resolved compilation unit.
-   */
-  CompilationUnit get anyResolvedCompilationUnit {
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-        return state.getValue(RESOLVED_UNIT);
-      }
-      state = state._nextState;
-    }
-    return null;
-  }
-
-  /**
-   * The libraries that are known to contain this part.
-   */
-  List<Source> get containingLibraries => _containingLibraries;
-
-  /**
-   * Set the list of libraries that contain this compilation unit to contain
-   * only the given [librarySource]. This method should only be invoked on
-   * entries that represent a library.
-   */
-  void set containingLibrary(Source librarySource) {
-    _containingLibraries.clear();
-    _containingLibraries.add(librarySource);
-  }
-
-  @override
-  List<DataDescriptor> get descriptors {
-    List<DataDescriptor> result = super.descriptors;
-    result.addAll(<DataDescriptor>[
-      DartEntry.SOURCE_KIND,
-      DartEntry.CONTAINING_LIBRARIES,
-      DartEntry.PARSE_ERRORS,
-      DartEntry.PARSED_UNIT,
-      DartEntry.SCAN_ERRORS,
-      DartEntry.SOURCE_KIND,
-      DartEntry.TOKEN_STREAM
-    ]);
-    SourceKind kind = getValue(DartEntry.SOURCE_KIND);
-    if (kind == SourceKind.LIBRARY) {
-      result.addAll(<DataDescriptor>[
-        DartEntry.ELEMENT,
-        DartEntry.EXPORTED_LIBRARIES,
-        DartEntry.IMPORTED_LIBRARIES,
-        DartEntry.INCLUDED_PARTS,
-        DartEntry.IS_CLIENT,
-        DartEntry.IS_LAUNCHABLE,
-        DartEntry.PUBLIC_NAMESPACE
-      ]);
-    }
-    return result;
-  }
-
-  /**
-   * Return `true` if this entry has an AST structure that can be resolved, even
-   * if it needs to be copied. Returning `true` implies that the method
-   * [resolvableCompilationUnit] will return a non-`null` result.
-   */
-  bool get hasResolvableCompilationUnit {
-    if (getState(PARSED_UNIT) == CacheState.VALID) {
-      return true;
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (state.getState(BUILT_UNIT) == CacheState.VALID ||
-          state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-        return true;
-      }
-      state = state._nextState;
-    }
-
-    return false;
-  }
-
-  @override
-  SourceKind get kind => getValue(SOURCE_KIND);
-
-  /**
-   * The library sources containing the receiver's source.
-   */
-  List<Source> get librariesContaining {
-    ResolutionState state = _resolutionState;
-    List<Source> result = new List<Source>();
-    while (state != null) {
-      if (state._librarySource != null) {
-        result.add(state._librarySource);
-      }
-      state = state._nextState;
-    }
-    return result;
-  }
-
-  /**
-   * Get a list of all the library-dependent descriptors for which values may
-   * be stored in this SourceEntry.
-   */
-  List<DataDescriptor> get libraryDescriptors {
-    return <DataDescriptor>[
-      DartEntry.BUILT_ELEMENT,
-      DartEntry.BUILT_UNIT,
-      DartEntry.RESOLUTION_ERRORS,
-      DartEntry.RESOLVED_UNIT,
-      DartEntry.VERIFICATION_ERRORS,
-      DartEntry.HINTS,
-      DartEntry.LINTS
-    ];
-  }
-
-  /**
-   * A compilation unit that has not been accessed by any other client and can
-   * therefore safely be modified by the reconciler, or `null` if the source has
-   * not been parsed.
-   */
-  CompilationUnit get resolvableCompilationUnit {
-    if (getState(PARSED_UNIT) == CacheState.VALID) {
-      CompilationUnit unit = getValue(PARSED_UNIT);
-      setState(PARSED_UNIT, CacheState.FLUSHED);
-      return unit;
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (state.getState(BUILT_UNIT) == CacheState.VALID) {
-        // TODO(brianwilkerson) We're cloning the structure to remove any
-        // previous resolution data, but I'm not sure that's necessary.
-        return state.getValue(BUILT_UNIT).accept(new AstCloner());
-      }
-      if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-        return state.getValue(RESOLVED_UNIT).accept(new AstCloner());
-      }
-      state = state._nextState;
-    }
-    return null;
-  }
-
-  /**
-   * Add the given [librarySource] to the list of libraries that contain this
-   * part. This method should only be invoked on entries that represent a part.
-   */
-  void addContainingLibrary(Source librarySource) {
-    _containingLibraries.add(librarySource);
-  }
-
-  /**
-   * Flush any AST structures being maintained by this entry.
-   */
-  void flushAstStructures() {
-    _flush(TOKEN_STREAM);
-    _flush(PARSED_UNIT);
-    _resolutionState.flushAstStructures();
-  }
-
-  /**
-   * Return the state of the data represented by the given [descriptor] in the
-   * context of the given [librarySource].
-   */
-  CacheState getStateInLibrary(
-      DataDescriptor descriptor, Source librarySource) {
-    if (!_isValidLibraryDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (librarySource == state._librarySource) {
-        return state.getState(descriptor);
-      }
-      state = state._nextState;
-    }
-    return CacheState.INVALID;
-  }
-
-  /**
-   * Return the value of the data represented by the given [descriptor] in the
-   * context of the given [librarySource], or `null` if the data represented by
-   * the descriptor is not in the cache.
-   */
-  Object getValueInLibrary(DataDescriptor descriptor, Source librarySource) {
-    if (!_isValidLibraryDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (librarySource == state._librarySource) {
-        return state.getValue(descriptor);
-      }
-      state = state._nextState;
-    }
-    return descriptor.defaultValue;
-  }
-
-  /**
-   * Return `true` if the data represented by the given [descriptor] is marked
-   * as being invalid. If the descriptor represents library-specific data then
-   * this method will return `true` if the data associated with any library it
-   * marked as invalid.
-   */
-  bool hasInvalidData(DataDescriptor descriptor) {
-    if (_isValidDescriptor(descriptor)) {
-      return getState(descriptor) == CacheState.INVALID;
-    } else if (_isValidLibraryDescriptor(descriptor)) {
-      ResolutionState state = _resolutionState;
-      while (state != null) {
-        if (state.getState(descriptor) == CacheState.INVALID) {
-          return true;
-        }
-        state = state._nextState;
-      }
-    }
-    return false;
-  }
-
-  @override
-  void invalidateAllInformation() {
-    super.invalidateAllInformation();
-    setState(SCAN_ERRORS, CacheState.INVALID);
-    setState(TOKEN_STREAM, CacheState.INVALID);
-    setState(SOURCE_KIND, CacheState.INVALID);
-    setState(PARSE_ERRORS, CacheState.INVALID);
-    setState(PARSED_UNIT, CacheState.INVALID);
-    _discardCachedResolutionInformation(true);
-  }
-
-  /**
-   * Invalidate all of the resolution information associated with the
-   * compilation unit. The flag [invalidateUris] should be `true` if the cached
-   * results of converting URIs to source files should also be invalidated.
-   */
-  void invalidateAllResolutionInformation(bool invalidateUris) {
-    if (getState(PARSED_UNIT) == CacheState.FLUSHED) {
-      ResolutionState state = _resolutionState;
-      while (state != null) {
-        if (state.getState(BUILT_UNIT) == CacheState.VALID) {
-          CompilationUnit unit = state.getValue(BUILT_UNIT);
-          setValue(PARSED_UNIT, unit.accept(new AstCloner()));
-          break;
-        } else if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-          CompilationUnit unit = state.getValue(RESOLVED_UNIT);
-          setValue(PARSED_UNIT, unit.accept(new AstCloner()));
-          break;
-        }
-        state = state._nextState;
-      }
-    }
-    _discardCachedResolutionInformation(invalidateUris);
-  }
-
-  /**
-   * Invalidate all of the parse and resolution information associated with
-   * this source.
-   */
-  void invalidateParseInformation() {
-    setState(SOURCE_KIND, CacheState.INVALID);
-    setState(PARSE_ERRORS, CacheState.INVALID);
-    setState(PARSED_UNIT, CacheState.INVALID);
-    _containingLibraries.clear();
-    _discardCachedResolutionInformation(true);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to build the element
-   * model for the source represented by this entry in the context of the given
-   * [library]. This will set the state of all resolution-based information as
-   * being in error, but will not change the state of any parse results.
-   */
-  void recordBuildElementErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    setStateInLibrary(BUILT_ELEMENT, librarySource, CacheState.ERROR);
-    setStateInLibrary(BUILT_UNIT, librarySource, CacheState.ERROR);
-    recordResolutionErrorInLibrary(librarySource, exception);
-  }
-
-  @override
-  void recordContentError(CaughtException exception) {
-    super.recordContentError(exception);
-    recordScanError(exception);
-  }
-
-  /**
-   * Record that an error occurred while attempting to generate hints for the
-   * source represented by this entry. This will set the state of all
-   * verification information as being in error. The [librarySource] is the
-   * source of the library in which hints were being generated. The [exception]
-   * is the exception that shows where the error occurred.
-   */
-  void recordHintErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    this.exception = exception;
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
-    state.recordHintError();
-  }
-
-  /**
-   * Record that an error occurred while attempting to generate lints for the
-   * source represented by this entry. This will set the state of all
-   * verification information as being in error. The [librarySource] is the
-   * source of the library in which lints were being generated. The [exception]
-   * is the exception that shows where the error occurred.
-   */
-  void recordLintErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    this.exception = exception;
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
-    state.recordLintError();
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to scan or parse the
-   * entry represented by this entry. This will set the state of all information,
-   * including any resolution-based information, as being in error.
-   */
-  void recordParseError(CaughtException exception) {
-    setState(SOURCE_KIND, CacheState.ERROR);
-    setState(PARSE_ERRORS, CacheState.ERROR);
-    setState(PARSED_UNIT, CacheState.ERROR);
-    setState(EXPORTED_LIBRARIES, CacheState.ERROR);
-    setState(IMPORTED_LIBRARIES, CacheState.ERROR);
-    setState(INCLUDED_PARTS, CacheState.ERROR);
-    recordResolutionError(exception);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to resolve the source
-   * represented by this entry. This will set the state of all resolution-based
-   * information as being in error, but will not change the state of any parse
-   * results.
-   */
-  void recordResolutionError(CaughtException exception) {
-    this.exception = exception;
-    setState(ELEMENT, CacheState.ERROR);
-    setState(IS_CLIENT, CacheState.ERROR);
-    setState(IS_LAUNCHABLE, CacheState.ERROR);
-    setState(PUBLIC_NAMESPACE, CacheState.ERROR);
-    _resolutionState.recordResolutionErrorsInAllLibraries();
-  }
-
-  /**
-   * Record that an error occurred while attempting to resolve the source
-   * represented by this entry. This will set the state of all resolution-based
-   * information as being in error, but will not change the state of any parse
-   * results. The [librarySource] is the source of the library in which
-   * resolution was being performed. The [exception] is the exception that shows
-   * where the error occurred.
-   */
-  void recordResolutionErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    this.exception = exception;
-    setState(ELEMENT, CacheState.ERROR);
-    setState(IS_CLIENT, CacheState.ERROR);
-    setState(IS_LAUNCHABLE, CacheState.ERROR);
-    setState(PUBLIC_NAMESPACE, CacheState.ERROR);
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
-    state.recordResolutionError();
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to scan or parse the
-   * entry represented by this entry. This will set the state of all
-   * information, including any resolution-based information, as being in error.
-   */
-  @override
-  void recordScanError(CaughtException exception) {
-    super.recordScanError(exception);
-    setState(SCAN_ERRORS, CacheState.ERROR);
-    setState(TOKEN_STREAM, CacheState.ERROR);
-    recordParseError(exception);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to generate errors and
-   * warnings for the source represented by this entry. This will set the state
-   * of all verification information as being in error. The [librarySource] is
-   * the source of the library in which verification was being performed. The
-   * [exception] is the exception that shows where the error occurred.
-   */
-  void recordVerificationErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    this.exception = exception;
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
-    state.recordVerificationError();
-  }
-
-  /**
-   * Remove the given [library] from the list of libraries that contain this
-   * part. This method should only be invoked on entries that represent a part.
-   */
-  void removeContainingLibrary(Source library) {
-    _containingLibraries.remove(library);
-  }
-
-  /**
-   * Remove any resolution information associated with this compilation unit
-   * being part of the given [library], presumably because it is no longer part
-   * of the library.
-   */
-  void removeResolution(Source library) {
-    if (library != null) {
-      if (library == _resolutionState._librarySource) {
-        if (_resolutionState._nextState == null) {
-          _resolutionState.invalidateAllResolutionInformation();
-        } else {
-          _resolutionState = _resolutionState._nextState;
-        }
-      } else {
-        ResolutionState priorState = _resolutionState;
-        ResolutionState state = _resolutionState._nextState;
-        while (state != null) {
-          if (library == state._librarySource) {
-            priorState._nextState = state._nextState;
-            break;
-          }
-          priorState = state;
-          state = state._nextState;
-        }
-      }
-    }
-  }
-
-  /**
-   * Set the state of the data represented by the given [descriptor] in the
-   * context of the given [library] to the given [state].
-   */
-  void setStateInLibrary(
-      DataDescriptor descriptor, Source library, CacheState state) {
-    if (!_isValidLibraryDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    ResolutionState resolutionState = _getOrCreateResolutionState(library);
-    resolutionState.setState(descriptor, state);
-  }
-
-  /**
-   * Set the value of the data represented by the given [descriptor] in the
-   * context of the given [library] to the given [value], and set the state of
-   * that data to [CacheState.VALID].
-   */
-  void setValueInLibrary(
-      DataDescriptor descriptor, Source library, Object value) {
-    if (!_isValidLibraryDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    ResolutionState state = _getOrCreateResolutionState(library);
-    state.setValue(descriptor, value);
-  }
-
-  /**
-   * Invalidate all of the resolution information associated with the
-   * compilation unit. The flag [invalidateUris] should be `true` if the cached
-   * results of converting URIs to source files should also be invalidated.
-   */
-  void _discardCachedResolutionInformation(bool invalidateUris) {
-    setState(ELEMENT, CacheState.INVALID);
-    setState(IS_CLIENT, CacheState.INVALID);
-    setState(IS_LAUNCHABLE, CacheState.INVALID);
-    setState(PUBLIC_NAMESPACE, CacheState.INVALID);
-    _resolutionState.invalidateAllResolutionInformation();
-    if (invalidateUris) {
-      setState(EXPORTED_LIBRARIES, CacheState.INVALID);
-      setState(IMPORTED_LIBRARIES, CacheState.INVALID);
-      setState(INCLUDED_PARTS, CacheState.INVALID);
-    }
-  }
-
-  /**
-   * Return a resolution state for the specified [library], creating one as
-   * necessary.
-   */
-  ResolutionState _getOrCreateResolutionState(Source library) {
-    ResolutionState state = _resolutionState;
-    if (state._librarySource == null) {
-      state._librarySource = library;
-      return state;
-    }
-    while (state._librarySource != library) {
-      if (state._nextState == null) {
-        ResolutionState newState = new ResolutionState();
-        newState._librarySource = library;
-        state._nextState = newState;
-        return newState;
-      }
-      state = state._nextState;
-    }
-    return state;
-  }
-
-  @override
-  bool _isValidDescriptor(DataDescriptor descriptor) {
-    return descriptor == CONTAINING_LIBRARIES ||
-        descriptor == ELEMENT ||
-        descriptor == EXPORTED_LIBRARIES ||
-        descriptor == IMPORTED_LIBRARIES ||
-        descriptor == INCLUDED_PARTS ||
-        descriptor == IS_CLIENT ||
-        descriptor == IS_LAUNCHABLE ||
-        descriptor == PARSED_UNIT ||
-        descriptor == PARSE_ERRORS ||
-        descriptor == PUBLIC_NAMESPACE ||
-        descriptor == SCAN_ERRORS ||
-        descriptor == SOURCE_KIND ||
-        descriptor == TOKEN_STREAM ||
-        super._isValidDescriptor(descriptor);
-  }
-
-  /**
-   * Return `true` if the [descriptor] is valid for this entry when the data is
-   * relative to a library.
-   */
-  bool _isValidLibraryDescriptor(DataDescriptor descriptor) {
-    return descriptor == BUILT_ELEMENT ||
-        descriptor == BUILT_UNIT ||
-        descriptor == HINTS ||
-        descriptor == LINTS ||
-        descriptor == RESOLUTION_ERRORS ||
-        descriptor == RESOLVED_UNIT ||
-        descriptor == VERIFICATION_ERRORS;
-  }
-
-  @override
-  bool _writeDiffOn(StringBuffer buffer, SourceEntry oldEntry) {
-    bool needsSeparator = super._writeDiffOn(buffer, oldEntry);
-    if (oldEntry is! DartEntry) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("entry type changed; was ");
-      buffer.write(oldEntry.runtimeType.toString());
-      return true;
-    }
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "tokenStream",
-        DartEntry.TOKEN_STREAM, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "scanErrors", DartEntry.SCAN_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "sourceKind", DartEntry.SOURCE_KIND, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "parsedUnit", DartEntry.PARSED_UNIT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "parseErrors",
-        DartEntry.PARSE_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "importedLibraries", DartEntry.IMPORTED_LIBRARIES, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "exportedLibraries", DartEntry.EXPORTED_LIBRARIES, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "includedParts",
-        DartEntry.INCLUDED_PARTS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "element", DartEntry.ELEMENT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "publicNamespace", DartEntry.PUBLIC_NAMESPACE, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "clientServer", DartEntry.IS_CLIENT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "launchable",
-        DartEntry.IS_LAUNCHABLE, oldEntry);
-    // TODO(brianwilkerson) Add better support for containingLibraries.
-    // It would be nice to be able to report on size-preserving changes.
-    int oldLibraryCount = (oldEntry as DartEntry)._containingLibraries.length;
-    int libraryCount = _containingLibraries.length;
-    if (oldLibraryCount != libraryCount) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("containingLibraryCount = ");
-      buffer.write(oldLibraryCount);
-      buffer.write(" -> ");
-      buffer.write(libraryCount);
-      needsSeparator = true;
-    }
-    //
-    // Report change to the per-library state.
-    //
-    HashMap<Source, ResolutionState> oldStateMap =
-        new HashMap<Source, ResolutionState>();
-    ResolutionState state = (oldEntry as DartEntry)._resolutionState;
-    while (state != null) {
-      Source librarySource = state._librarySource;
-      if (librarySource != null) {
-        oldStateMap[librarySource] = state;
-      }
-      state = state._nextState;
-    }
-    state = _resolutionState;
-    while (state != null) {
-      Source librarySource = state._librarySource;
-      if (librarySource != null) {
-        ResolutionState oldState = oldStateMap.remove(librarySource);
-        if (oldState == null) {
-          if (needsSeparator) {
-            buffer.write("; ");
-          }
-          buffer.write("added resolution for ");
-          buffer.write(librarySource.fullName);
-          needsSeparator = true;
-        } else {
-          needsSeparator = oldState._writeDiffOn(
-              buffer, needsSeparator, oldEntry as DartEntry);
-        }
-      }
-      state = state._nextState;
-    }
-    for (Source librarySource in oldStateMap.keys.toSet()) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("removed resolution for ");
-      buffer.write(librarySource.fullName);
-      needsSeparator = true;
-    }
-    return needsSeparator;
-  }
-
-  @override
-  void _writeOn(StringBuffer buffer) {
-    buffer.write("Dart: ");
-    super._writeOn(buffer);
-    _writeStateOn(buffer, "tokenStream", TOKEN_STREAM);
-    _writeStateOn(buffer, "scanErrors", SCAN_ERRORS);
-    _writeStateOn(buffer, "sourceKind", SOURCE_KIND);
-    _writeStateOn(buffer, "parsedUnit", PARSED_UNIT);
-    _writeStateOn(buffer, "parseErrors", PARSE_ERRORS);
-    _writeStateOn(buffer, "exportedLibraries", EXPORTED_LIBRARIES);
-    _writeStateOn(buffer, "importedLibraries", IMPORTED_LIBRARIES);
-    _writeStateOn(buffer, "includedParts", INCLUDED_PARTS);
-    _writeStateOn(buffer, "element", ELEMENT);
-    _writeStateOn(buffer, "publicNamespace", PUBLIC_NAMESPACE);
-    _writeStateOn(buffer, "clientServer", IS_CLIENT);
-    _writeStateOn(buffer, "launchable", IS_LAUNCHABLE);
-    _resolutionState._writeOn(buffer);
-  }
-}
-
-/**
- * An immutable constant representing data that can be stored in the cache.
- */
-class DataDescriptor<E> {
-  /**
-   * The next artificial hash code.
-   */
-  static int _NEXT_HASH_CODE = 0;
-
-  /**
-   * The artifitial hash code for this object.
-   */
-  final int _hashCode = _NEXT_HASH_CODE++;
-
-  /**
-   * The name of the descriptor, used for debugging purposes.
-   */
-  final String _name;
-
-  /**
-   * The default value used when the data does not exist.
-   */
-  final E defaultValue;
-
-  /**
-   * Initialize a newly created descriptor to have the given [name] and
-   * [defaultValue].
-   */
-  DataDescriptor(this._name, [this.defaultValue = null]);
-
-  @override
-  int get hashCode => _hashCode;
-
-  @override
-  String toString() => _name;
-}
-
-/**
- * A retention policy that will keep AST's in the cache if there is analysis
- * information that needs to be computed for a source, where the computation is
- * dependent on having the AST.
- */
-class DefaultRetentionPolicy implements CacheRetentionPolicy {
-  /**
-   * An instance of this class that can be shared.
-   */
-  static DefaultRetentionPolicy POLICY = new DefaultRetentionPolicy();
-
-  /**
-   * Return `true` if there is analysis information in the given [dartEntry]
-   * that needs to be computed, where the computation is dependent on having the
-   * AST.
-   */
-  bool astIsNeeded(DartEntry dartEntry) =>
-      dartEntry.hasInvalidData(DartEntry.HINTS) ||
-          dartEntry.hasInvalidData(DartEntry.LINTS) ||
-          dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) ||
-          dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS);
-
-  @override
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) {
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      if (astIsNeeded(dartEntry)) {
-        return RetentionPriority.MEDIUM;
-      }
-    }
-    return RetentionPriority.LOW;
-  }
-}
-
-/**
- * Instances of the class `GenerateDartErrorsTask` generate errors and warnings for a single
- * Dart source.
- */
-class GenerateDartErrorsTask extends AnalysisTask {
-  /**
-   * The source for which errors and warnings are to be produced.
-   */
-  final Source source;
-
-  /**
-   * The compilation unit used to resolve the dependencies.
-   */
-  final CompilationUnit _unit;
-
-  /**
-   * The element model for the library containing the source.
-   */
-  final LibraryElement libraryElement;
-
-  /**
-   * The errors that were generated for the source.
-   */
-  List<AnalysisError> _errors;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source for which errors and warnings are to be produced
-   * @param unit the compilation unit used to resolve the dependencies
-   * @param libraryElement the element model for the library containing the source
-   */
-  GenerateDartErrorsTask(InternalAnalysisContext context, this.source,
-      this._unit, this.libraryElement)
-      : super(context);
-
-  /**
-   * Return the errors that were generated for the source.
-   *
-   * @return the errors that were generated for the source
-   */
-  List<AnalysisError> get errors => _errors;
-
-  @override
-  String get taskDescription =>
-      "generate errors and warnings for ${source.fullName}";
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitGenerateDartErrorsTask(this);
-
-  @override
-  void internalPerform() {
-    PerformanceStatistics.errors.makeCurrentWhile(() {
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
-      TypeProvider typeProvider = context.typeProvider;
-      //
-      // Validate the directives
-      //
-      validateDirectives(context, source, _unit, errorListener);
-      //
-      // Use the ConstantVerifier to verify the use of constants.
-      // This needs to happen before using the ErrorVerifier because some error
-      // codes need the computed constant values.
-      //
-      // TODO(paulberry): as a temporary workaround for issue 21572,
-      // ConstantVerifier is being run right after ConstantValueComputer, so we
-      // don't need to run it here.  Once issue 21572 is fixed, re-enable the
-      // call to ConstantVerifier.
-//      ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, libraryElement, typeProvider);
-//      _unit.accept(constantVerifier);
-      //
-      // Use the ErrorVerifier to compute the rest of the errors.
-      //
-      ErrorVerifier errorVerifier = new ErrorVerifier(
-          errorReporter,
-          libraryElement,
-          typeProvider,
-          new InheritanceManager(libraryElement),
-          context.analysisOptions.enableSuperMixins);
-      _unit.accept(errorVerifier);
-      _errors = errorListener.getErrorsForSource(source);
-    });
-  }
-
-  /**
-   * Check each directive in the given compilation unit to see if the referenced source exists and
-   * report an error if it does not.
-   *
-   * @param context the context in which the library exists
-   * @param librarySource the source representing the library containing the directives
-   * @param unit the compilation unit containing the directives to be validated
-   * @param errorListener the error listener to which errors should be reported
-   */
-  static void validateDirectives(AnalysisContext context, Source librarySource,
-      CompilationUnit unit, AnalysisErrorListener errorListener) {
-    for (Directive directive in unit.directives) {
-      if (directive is UriBasedDirective) {
-        validateReferencedSource(
-            context, librarySource, directive, errorListener);
-      }
-    }
-  }
-
-  /**
-   * Check the given directive to see if the referenced source exists and report an error if it does
-   * not.
-   *
-   * @param context the context in which the library exists
-   * @param librarySource the source representing the library containing the directive
-   * @param directive the directive to be verified
-   * @param errorListener the error listener to which errors should be reported
-   */
-  static void validateReferencedSource(
-      AnalysisContext context,
-      Source librarySource,
-      UriBasedDirective directive,
-      AnalysisErrorListener errorListener) {
-    Source source = directive.source;
-    if (source != null) {
-      if (context.exists(source)) {
-        return;
-      }
-    } else {
-      // Don't report errors already reported by ParseDartTask.resolveDirective
-      if (directive.validate() != null) {
-        return;
-      }
-    }
-    StringLiteral uriLiteral = directive.uri;
-    errorListener.onError(new AnalysisError(
-        librarySource,
-        uriLiteral.offset,
-        uriLiteral.length,
-        CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-        [directive.uriContent]));
-  }
-}
-
-/**
- * Instances of the class `GenerateDartHintsTask` generate hints for a single Dart library.
- */
-class GenerateDartHintsTask extends AnalysisTask {
-  /**
-   * The compilation units that comprise the library, with the defining compilation unit appearing
-   * first in the list.
-   */
-  final List<TimestampedData<CompilationUnit>> _units;
-
-  /**
-   * The element model for the library being analyzed.
-   */
-  final LibraryElement libraryElement;
-
-  /**
-   * A table mapping the sources that were analyzed to the hints that were
-   * generated for the sources.
-   */
-  HashMap<Source, List<AnalysisError>> _hintMap;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param units the compilation units that comprise the library, with the defining compilation
-   *          unit appearing first in the list
-   * @param libraryElement the element model for the library being analyzed
-   */
-  GenerateDartHintsTask(
-      InternalAnalysisContext context, this._units, this.libraryElement)
-      : super(context);
-
-  /**
-   * Return a table mapping the sources that were analyzed to the hints that were generated for the
-   * sources, or `null` if the task has not been performed or if the analysis did not complete
-   * normally.
-   *
-   * @return a table mapping the sources that were analyzed to the hints that were generated for the
-   *         sources
-   */
-  HashMap<Source, List<AnalysisError>> get hintMap => _hintMap;
-
-  @override
-  String get taskDescription {
-    Source librarySource = libraryElement.source;
-    if (librarySource == null) {
-      return "generate Dart hints for library without source";
-    }
-    return "generate Dart hints for ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitGenerateDartHintsTask(this);
-
-  @override
-  void internalPerform() {
-    //
-    // Gather the compilation units.
-    //
-    int unitCount = _units.length;
-    List<CompilationUnit> compilationUnits =
-        new List<CompilationUnit>(unitCount);
-    for (int i = 0; i < unitCount; i++) {
-      compilationUnits[i] = _units[i].data;
-    }
-    //
-    // Analyze all of the units.
-    //
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-    HintGenerator hintGenerator =
-        new HintGenerator(compilationUnits, context, errorListener);
-    hintGenerator.generateForLibrary();
-    //
-    // Store the results.
-    //
-    _hintMap = new HashMap<Source, List<AnalysisError>>();
-    for (int i = 0; i < unitCount; i++) {
-      Source source = _units[i].data.element.source;
-      _hintMap[source] = errorListener.getErrorsForSource(source);
-    }
-  }
-}
-
-/// Generates lint feedback for a single Dart library.
-class GenerateDartLintsTask extends AnalysisTask {
-  ///The compilation units that comprise the library, with the defining
-  ///compilation unit appearing first in the list.
-  final List<TimestampedData<CompilationUnit>> _units;
-
-  /// The element model for the library being analyzed.
-  final LibraryElement libraryElement;
-
-  /// A mapping of analyzed sources to their associated lint warnings.
-  /// May be [null] if the task has not been performed or if analysis did not
-  /// complete normally.
-  HashMap<Source, List<AnalysisError>> lintMap;
-
-  /// Initialize a newly created task to perform lint checking over these
-  /// [_units] belonging to this [libraryElement] within the given [context].
-  GenerateDartLintsTask(context, this._units, this.libraryElement)
-      : super(context);
-
-  @override
-  String get taskDescription {
-    Source librarySource = libraryElement.source;
-    return (librarySource == null)
-        ? "generate Dart lints for library without source"
-        : "generate Dart lints for ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitGenerateDartLintsTask(this);
-
-  @override
-  void internalPerform() {
-    Iterable<CompilationUnit> compilationUnits =
-        _units.map((TimestampedData<CompilationUnit> unit) => unit.data);
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-    LintGenerator lintGenerator =
-        new LintGenerator(compilationUnits, errorListener);
-    lintGenerator.generate();
-
-    lintMap = new HashMap<Source, List<AnalysisError>>();
-    compilationUnits.forEach((CompilationUnit unit) {
-      Source source = unit.element.source;
-      lintMap[source] = errorListener.getErrorsForSource(source);
-    });
-  }
-}
-
-/**
- * Instances of the class `GetContentTask` get the contents of a source.
- */
-class GetContentTask extends AnalysisTask {
-  /**
-   * The source to be read.
-   */
-  final Source source;
-
-  /**
-   * A flag indicating whether this task is complete.
-   */
-  bool _complete = false;
-
-  /**
-   * The contents of the source.
-   */
-  String _content;
-
-  /**
-   * The errors that were produced by getting the source content.
-   */
-  final List<AnalysisError> errors = <AnalysisError>[];
-
-  /**
-   * The time at which the contents of the source were last modified.
-   */
-  int _modificationTime = -1;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param contentData the time-stamped contents of the source
-   */
-  GetContentTask(InternalAnalysisContext context, this.source)
-      : super(context) {
-    if (source == null) {
-      throw new IllegalArgumentException("Cannot get contents of null source");
-    }
-  }
-
-  /**
-   * Return the contents of the source, or `null` if the task has not completed or if there
-   * was an exception while getting the contents.
-   *
-   * @return the contents of the source
-   */
-  String get content => _content;
-
-  /**
-   * Return `true` if this task is complete. Unlike most tasks, this task is allowed to be
-   * visited more than once in order to support asynchronous IO. If the task is not complete when it
-   * is visited synchronously as part of the [AnalysisTask.perform]
-   * method, it will be visited again, using the same visitor, when the IO operation has been
-   * performed.
-   *
-   * @return `true` if this task is complete
-   */
-  bool get isComplete => _complete;
-
-  /**
-   * Return the time at which the contents of the source that was parsed were last modified, or a
-   * negative value if the task has not yet been performed or if an exception occurred.
-   *
-   * @return the time at which the contents of the source that was parsed were last modified
-   */
-  int get modificationTime => _modificationTime;
-
-  @override
-  String get taskDescription => "get contents of ${source.fullName}";
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitGetContentTask(this);
-
-  @override
-  void internalPerform() {
-    _complete = true;
-    try {
-      TimestampedData<String> data = context.getContents(source);
-      _content = data.data;
-      _modificationTime = data.modificationTime;
-      AnalysisEngine.instance.instrumentationService
-          .logFileRead(source.fullName, _modificationTime, _content);
-    } catch (exception, stackTrace) {
-      if (source.exists()) {
-        errors.add(new AnalysisError(
-            source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [exception]));
-      }
-      throw new AnalysisException("Could not get contents of $source",
-          new CaughtException(exception, stackTrace));
-    }
-  }
-}
-
-/**
- * The information cached by an analysis context about an individual HTML file.
- */
-class HtmlEntry extends SourceEntry {
-  /**
-   * The data descriptor representing the HTML element.
-   */
-  static final DataDescriptor<HtmlElement> ELEMENT =
-      new DataDescriptor<HtmlElement>("HtmlEntry.ELEMENT");
-
-  /**
-   * The data descriptor representing the hints resulting from auditing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> HINTS =
-      new DataDescriptor<List<AnalysisError>>(
-          "HtmlEntry.HINTS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the errors resulting from parsing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> PARSE_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "HtmlEntry.PARSE_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the parsed AST structure.
-   */
-  static final DataDescriptor<ht.HtmlUnit> PARSED_UNIT =
-      new DataDescriptor<ht.HtmlUnit>("HtmlEntry.PARSED_UNIT");
-
-  /**
-   * The data descriptor representing the resolved AST structure.
-   */
-  static final DataDescriptor<ht.HtmlUnit> RESOLVED_UNIT =
-      new DataDescriptor<ht.HtmlUnit>("HtmlEntry.RESOLVED_UNIT");
-
-  /**
-   * The data descriptor representing the list of referenced libraries.
-   */
-  static final DataDescriptor<List<Source>> REFERENCED_LIBRARIES =
-      new DataDescriptor<List<Source>>(
-          "HtmlEntry.REFERENCED_LIBRARIES", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the errors resulting from resolving the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "HtmlEntry.RESOLUTION_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * Return all of the errors associated with the HTML file that are currently
-   * cached.
-   */
-  List<AnalysisError> get allErrors {
-    List<AnalysisError> errors = new List<AnalysisError>();
-    errors.addAll(super.allErrors);
-    errors.addAll(getValue(PARSE_ERRORS));
-    errors.addAll(getValue(RESOLUTION_ERRORS));
-    errors.addAll(getValue(HINTS));
-    if (errors.length == 0) {
-      return AnalysisError.NO_ERRORS;
-    }
-    return errors;
-  }
-
-  /**
-   * Return a valid parsed unit, either an unresolved AST structure or the
-   * result of resolving the AST structure, or `null` if there is no parsed unit
-   * available.
-   */
-  ht.HtmlUnit get anyParsedUnit {
-    if (getState(PARSED_UNIT) == CacheState.VALID) {
-      return getValue(PARSED_UNIT);
-    }
-    if (getState(RESOLVED_UNIT) == CacheState.VALID) {
-      return getValue(RESOLVED_UNIT);
-    }
-    return null;
-  }
-
-  @override
-  List<DataDescriptor> get descriptors {
-    List<DataDescriptor> result = super.descriptors;
-    result.addAll([
-      HtmlEntry.ELEMENT,
-      HtmlEntry.PARSE_ERRORS,
-      HtmlEntry.PARSED_UNIT,
-      HtmlEntry.RESOLUTION_ERRORS,
-      HtmlEntry.RESOLVED_UNIT,
-      HtmlEntry.HINTS
-    ]);
-    return result;
-  }
-
-  @override
-  SourceKind get kind => SourceKind.HTML;
-
-  /**
-   * Flush any AST structures being maintained by this entry.
-   */
-  void flushAstStructures() {
-    _flush(PARSED_UNIT);
-    _flush(RESOLVED_UNIT);
-  }
-
-  @override
-  void invalidateAllInformation() {
-    super.invalidateAllInformation();
-    setState(PARSE_ERRORS, CacheState.INVALID);
-    setState(PARSED_UNIT, CacheState.INVALID);
-    setState(RESOLVED_UNIT, CacheState.INVALID);
-    invalidateAllResolutionInformation(true);
-  }
-
-  /**
-   * Invalidate all of the resolution information associated with the HTML file.
-   * If [invalidateUris] is `true`, the cached results of converting URIs to
-   * source files should also be invalidated.
-   */
-  void invalidateAllResolutionInformation(bool invalidateUris) {
-    setState(RESOLVED_UNIT, CacheState.INVALID);
-    setState(ELEMENT, CacheState.INVALID);
-    setState(RESOLUTION_ERRORS, CacheState.INVALID);
-    setState(HINTS, CacheState.INVALID);
-    if (invalidateUris) {
-      setState(REFERENCED_LIBRARIES, CacheState.INVALID);
-    }
-  }
-
-  /**
-   * Invalidate all of the parse and resolution information associated with
-   * this source.
-   */
-  void invalidateParseInformation() {
-    setState(PARSE_ERRORS, CacheState.INVALID);
-    setState(PARSED_UNIT, CacheState.INVALID);
-    invalidateAllResolutionInformation(true);
-  }
-
-  @override
-  void recordContentError(CaughtException exception) {
-    super.recordContentError(exception);
-    recordParseError(exception);
-  }
-
-  /**
-   * Record that an [exception] was encountered while attempting to parse the
-   * source associated with this entry.
-   */
-  void recordParseError(CaughtException exception) {
-    // If the scanning and parsing of HTML are separated,
-    // the following line can be removed.
-    recordScanError(exception);
-    setState(PARSE_ERRORS, CacheState.ERROR);
-    setState(PARSED_UNIT, CacheState.ERROR);
-    setState(REFERENCED_LIBRARIES, CacheState.ERROR);
-    recordResolutionError(exception);
-  }
-
-  /**
-   * Record that an [exception] was encountered while attempting to resolve the
-   * source associated with this entry.
-   */
-  void recordResolutionError(CaughtException exception) {
-    this.exception = exception;
-    setState(RESOLVED_UNIT, CacheState.ERROR);
-    setState(ELEMENT, CacheState.ERROR);
-    setState(RESOLUTION_ERRORS, CacheState.ERROR);
-    setState(HINTS, CacheState.ERROR);
-  }
-
-  @override
-  bool _isValidDescriptor(DataDescriptor descriptor) {
-    return descriptor == ELEMENT ||
-        descriptor == HINTS ||
-        descriptor == PARSED_UNIT ||
-        descriptor == PARSE_ERRORS ||
-        descriptor == REFERENCED_LIBRARIES ||
-        descriptor == RESOLUTION_ERRORS ||
-        descriptor == RESOLVED_UNIT ||
-        super._isValidDescriptor(descriptor);
-  }
-
-  @override
-  bool _writeDiffOn(StringBuffer buffer, SourceEntry oldEntry) {
-    bool needsSeparator = super._writeDiffOn(buffer, oldEntry);
-    if (oldEntry is! HtmlEntry) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("entry type changed; was ");
-      buffer.write(oldEntry.runtimeType);
-      return true;
-    }
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "parseErrors",
-        HtmlEntry.PARSE_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "parsedUnit", HtmlEntry.PARSED_UNIT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "resolvedUnit",
-        HtmlEntry.RESOLVED_UNIT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "resolutionErrors", HtmlEntry.RESOLUTION_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "referencedLibraries", HtmlEntry.REFERENCED_LIBRARIES, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "element", HtmlEntry.ELEMENT, oldEntry);
-    return needsSeparator;
-  }
-
-  @override
-  void _writeOn(StringBuffer buffer) {
-    buffer.write("Html: ");
-    super._writeOn(buffer);
-    _writeStateOn(buffer, "parseErrors", PARSE_ERRORS);
-    _writeStateOn(buffer, "parsedUnit", PARSED_UNIT);
-    _writeStateOn(buffer, "resolvedUnit", RESOLVED_UNIT);
-    _writeStateOn(buffer, "resolutionErrors", RESOLUTION_ERRORS);
-    _writeStateOn(buffer, "referencedLibraries", REFERENCED_LIBRARIES);
-    _writeStateOn(buffer, "element", ELEMENT);
-  }
-}
-
-/**
  * An event indicating when a source either starts or stops being implicitly
  * analyzed.
  */
@@ -9089,296 +1845,6 @@
 }
 
 /**
- * Instances of the class `IncrementalAnalysisCache` hold information used to perform
- * incremental analysis.
- *
- * See [AnalysisContextImpl.setChangedContents].
- */
-class IncrementalAnalysisCache {
-  final Source librarySource;
-
-  final Source source;
-
-  final String oldContents;
-
-  final CompilationUnit resolvedUnit;
-
-  String _newContents;
-
-  int _offset = 0;
-
-  int _oldLength = 0;
-
-  int _newLength = 0;
-
-  IncrementalAnalysisCache(
-      this.librarySource,
-      this.source,
-      this.resolvedUnit,
-      this.oldContents,
-      this._newContents,
-      this._offset,
-      this._oldLength,
-      this._newLength);
-
-  /**
-   * Determine if the cache contains source changes that need to be analyzed
-   *
-   * @return `true` if the cache contains changes to be analyzed, else `false`
-   */
-  bool get hasWork => _oldLength > 0 || _newLength > 0;
-
-  /**
-   * Return the current contents for the receiver's source.
-   *
-   * @return the contents (not `null`)
-   */
-  String get newContents => _newContents;
-
-  /**
-   * Return the number of characters in the replacement text.
-   *
-   * @return the replacement length (zero or greater)
-   */
-  int get newLength => _newLength;
-
-  /**
-   * Return the character position of the first changed character.
-   *
-   * @return the offset (zero or greater)
-   */
-  int get offset => _offset;
-
-  /**
-   * Return the number of characters that were replaced.
-   *
-   * @return the replaced length (zero or greater)
-   */
-  int get oldLength => _oldLength;
-
-  /**
-   * Determine if the incremental analysis result can be cached for the next incremental analysis.
-   *
-   * @param cache the prior incremental analysis cache
-   * @param unit the incrementally updated compilation unit
-   * @return the cache used for incremental analysis or `null` if incremental analysis results
-   *         cannot be cached for the next incremental analysis
-   */
-  static IncrementalAnalysisCache cacheResult(
-      IncrementalAnalysisCache cache, CompilationUnit unit) {
-    if (cache != null && unit != null) {
-      return new IncrementalAnalysisCache(cache.librarySource, cache.source,
-          unit, cache._newContents, cache._newContents, 0, 0, 0);
-    }
-    return null;
-  }
-
-  /**
-   * Determine if the cache should be cleared.
-   *
-   * @param cache the prior cache or `null` if none
-   * @param source the source being updated (not `null`)
-   * @return the cache used for incremental analysis or `null` if incremental analysis cannot
-   *         be performed
-   */
-  static IncrementalAnalysisCache clear(
-      IncrementalAnalysisCache cache, Source source) {
-    if (cache == null || cache.source == source) {
-      return null;
-    }
-    return cache;
-  }
-
-  /**
-   * Determine if incremental analysis can be performed from the given information.
-   *
-   * @param cache the prior cache or `null` if none
-   * @param source the source being updated (not `null`)
-   * @param oldContents the original source contents prior to this update (may be `null`)
-   * @param newContents the new contents after this incremental change (not `null`)
-   * @param offset the offset at which the change occurred
-   * @param oldLength the length of the text being replaced
-   * @param newLength the length of the replacement text
-   * @param sourceEntry the cached entry for the given source or `null` if none
-   * @return the cache used for incremental analysis or `null` if incremental analysis cannot
-   *         be performed
-   */
-  static IncrementalAnalysisCache update(
-      IncrementalAnalysisCache cache,
-      Source source,
-      String oldContents,
-      String newContents,
-      int offset,
-      int oldLength,
-      int newLength,
-      SourceEntry sourceEntry) {
-    // Determine the cache resolved unit
-    Source librarySource = null;
-    CompilationUnit unit = null;
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      List<Source> librarySources = dartEntry.librariesContaining;
-      if (librarySources.length == 1) {
-        librarySource = librarySources[0];
-        if (librarySource != null) {
-          unit = dartEntry.getValueInLibrary(
-              DartEntry.RESOLVED_UNIT, librarySource);
-        }
-      }
-    }
-    // Create a new cache if there is not an existing cache or the source is
-    // different or a new resolved compilation unit is available.
-    if (cache == null || cache.source != source || unit != null) {
-      if (unit == null) {
-        return null;
-      }
-      if (oldContents == null) {
-        if (oldLength != 0) {
-          return null;
-        }
-        oldContents =
-            "${newContents.substring(0, offset)}${newContents.substring(offset + newLength)}";
-      }
-      return new IncrementalAnalysisCache(librarySource, source, unit,
-          oldContents, newContents, offset, oldLength, newLength);
-    }
-    // Update the existing cache if the change is contiguous
-    if (cache._oldLength == 0 && cache._newLength == 0) {
-      cache._offset = offset;
-      cache._oldLength = oldLength;
-      cache._newLength = newLength;
-    } else {
-      if (cache._offset > offset || offset > cache._offset + cache._newLength) {
-        return null;
-      }
-      cache._newLength += newLength - oldLength;
-    }
-    cache._newContents = newContents;
-    return cache;
-  }
-
-  /**
-   * Verify that the incrementally parsed and resolved unit in the incremental cache is structurally
-   * equivalent to the fully parsed unit.
-   *
-   * @param cache the prior cache or `null` if none
-   * @param source the source of the compilation unit that was parsed (not `null`)
-   * @param unit the compilation unit that was just parsed
-   * @return the cache used for incremental analysis or `null` if incremental analysis results
-   *         cannot be cached for the next incremental analysis
-   */
-  static IncrementalAnalysisCache verifyStructure(
-      IncrementalAnalysisCache cache, Source source, CompilationUnit unit) {
-    if (cache != null && unit != null && cache.source == source) {
-      if (!AstComparator.equalNodes(cache.resolvedUnit, unit)) {
-        return null;
-      }
-    }
-    return cache;
-  }
-}
-
-/**
- * Instances of the class `IncrementalAnalysisTask` incrementally update existing analysis.
- */
-class IncrementalAnalysisTask extends AnalysisTask {
-  /**
-   * The information used to perform incremental analysis.
-   */
-  final IncrementalAnalysisCache cache;
-
-  /**
-   * The compilation unit that was produced by incrementally updating the existing unit.
-   */
-  CompilationUnit _updatedUnit;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param cache the incremental analysis cache used to perform the analysis
-   */
-  IncrementalAnalysisTask(InternalAnalysisContext context, this.cache)
-      : super(context);
-
-  /**
-   * Return the compilation unit that was produced by incrementally updating the existing
-   * compilation unit, or `null` if the task has not yet been performed, could not be
-   * performed, or if an exception occurred.
-   *
-   * @return the compilation unit
-   */
-  CompilationUnit get compilationUnit => _updatedUnit;
-
-  /**
-   * Return the source that is to be incrementally analyzed.
-   *
-   * @return the source
-   */
-  Source get source => cache != null ? cache.source : null;
-
-  @override
-  String get taskDescription =>
-      "incremental analysis ${cache != null ? cache.source : "null"}";
-
-  /**
-   * Return the type provider used for incremental resolution.
-   *
-   * @return the type provider (or `null` if an exception occurs)
-   */
-  TypeProvider get typeProvider {
-    try {
-      return context.typeProvider;
-    } on AnalysisException {
-      return null;
-    }
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitIncrementalAnalysisTask(this);
-
-  @override
-  void internalPerform() {
-    if (cache == null) {
-      return;
-    }
-    // Only handle small changes
-    if (cache.oldLength > 0 || cache.newLength > 30) {
-      return;
-    }
-    // Produce an updated token stream
-    CharacterReader reader = new CharSequenceReader(cache.newContents);
-    BooleanErrorListener errorListener = new BooleanErrorListener();
-    IncrementalScanner scanner = new IncrementalScanner(
-        cache.source, reader, errorListener, context.analysisOptions);
-    scanner.rescan(cache.resolvedUnit.beginToken, cache.offset, cache.oldLength,
-        cache.newLength);
-    if (errorListener.errorReported) {
-      return;
-    }
-    // Produce an updated AST
-    IncrementalParser parser = new IncrementalParser(
-        cache.source, scanner.tokenMap, AnalysisErrorListener.NULL_LISTENER);
-    _updatedUnit = parser.reparse(cache.resolvedUnit, scanner.leftToken,
-        scanner.rightToken, cache.offset, cache.offset + cache.oldLength);
-    // Update the resolution
-    TypeProvider typeProvider = this.typeProvider;
-    if (_updatedUnit != null && typeProvider != null) {
-      CompilationUnitElement element = _updatedUnit.element;
-      if (element != null) {
-        LibraryElement library = element.library;
-        if (library != null) {
-          IncrementalResolver resolver = new IncrementalResolver(null, null,
-              null, element, cache.offset, cache.oldLength, cache.newLength);
-          resolver.resolve(parser.updatedNode);
-        }
-      }
-    }
-  }
-}
-
-/**
  * Additional behavior for an analysis context that is required by internal
  * users of the context.
  */
@@ -9386,10 +1852,8 @@
   /**
    * A table mapping the sources known to the context to the information known
    * about the source.
-   *
-   * TODO(scheglov) add the type, once we have only one cache.
    */
-  dynamic get analysisCache;
+  AnalysisCache get analysisCache;
 
   /**
    * Allow the client to supply its own content cache.  This will take the
@@ -9398,17 +1862,15 @@
    */
   set contentCache(ContentCache value);
 
+  /// Get the [EmbedderYamlLocator] for this context.
+  EmbedderYamlLocator get embedderYamlLocator;
+
   /**
    * Return a list of the explicit targets being analyzed by this context.
    */
   List<AnalysisTarget> get explicitTargets;
 
   /**
-   * A factory to override how [LibraryResolver] is created.
-   */
-  LibraryResolverFactory get libraryResolverFactory;
-
-  /**
    * Return a list containing all of the sources that have been marked as
    * priority sources. Clients must not modify the returned list.
    */
@@ -9422,20 +1884,8 @@
   /**
    * The partition that contains analysis results that are not shared with other
    * contexts.
-   *
-   * TODO(scheglov) add the type, once we have only one cache.
    */
-  dynamic get privateAnalysisCachePartition;
-
-  /**
-   * A factory to override how [ResolverVisitor] is created.
-   */
-  ResolverVisitorFactory get resolverVisitorFactory;
-
-  /**
-   * Returns a statistics about this context.
-   */
-  AnalysisContextStatistics get statistics;
+  CachePartition get privateAnalysisCachePartition;
 
   /**
    * Sets the [TypeProvider] for this context.
@@ -9443,14 +1893,21 @@
   void set typeProvider(TypeProvider typeProvider);
 
   /**
-   * A factory to override how [TypeResolverVisitor] is created.
-   */
-  TypeResolverVisitorFactory get typeResolverVisitorFactory;
-
-  /**
    * A list of all [WorkManager]s used by this context.
    */
-  List<newContext.WorkManager> get workManagers;
+  List<WorkManager> get workManagers;
+
+  /**
+   * This method is invoked when the state of the [result] of the [entry] is
+   * [CacheState.INVALID], so it is about to be computed.
+   *
+   * If the context knows how to provide the value, it sets the value into
+   * the [entry] with all required dependencies, and returns `true`.
+   *
+   * Otherwise, it returns `false` to indicate that the result should be
+   * computed as usually.
+   */
+  bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result);
 
   /**
    * Return a list containing the sources of the libraries that are exported by
@@ -9475,17 +1932,6 @@
   List<Source> computeImportedLibraries(Source source);
 
   /**
-   * Return an AST structure corresponding to the given [source], but ensure
-   * that the structure has not already been resolved and will not be resolved
-   * by any other threads or in any other library.
-   *
-   * Throws an [AnalysisException] if the analysis could not be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment
-   */
-  CompilationUnit computeResolvableCompilationUnit(Source source);
-
-  /**
    * Return all the resolved [CompilationUnit]s for the given [source] if not
    * flushed, otherwise return `null` and ensures that the [CompilationUnit]s
    * will be eventually returned to the client from [performAnalysisTask].
@@ -9495,7 +1941,7 @@
   /**
    * Return the cache entry associated with the given [target].
    */
-  cache.CacheEntry getCacheEntry(AnalysisTarget target);
+  CacheEntry getCacheEntry(AnalysisTarget target);
 
   /**
    * Return context that owns the given [source].
@@ -9542,12 +1988,8 @@
 
   /**
    * 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);
+  bool shouldErrorsBeAnalyzed(Source source);
 
   /**
    * For testing only: flush all representations of the AST (both resolved and
@@ -9556,13 +1998,6 @@
   void test_flushAstStructures(Source source);
 
   /**
-   * Call the given callback function for eache cache item in the context.
-   */
-  @deprecated
-  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state));
-
-  /**
    * Visit all entries of the content cache.
    */
   void visitContentCache(ContentCacheVisitor visitor);
@@ -9589,25 +2024,11 @@
   void logError(String message, [CaughtException exception]);
 
   /**
-   * Log the given [exception] as one representing an error. The [message] is an
-   * explanation of why the error occurred or what it means.
-   */
-  @deprecated // Use logError(message, exception)
-  void logError2(String message, Object exception);
-
-  /**
    * Log the given informational message. The [message] is expected to be an
    * explanation of why the error occurred or what it means. The [exception] is
    * expected to be the reason for the error.
    */
   void logInformation(String message, [CaughtException exception]);
-
-  /**
-   * Log the given [exception] as one representing an informational message. The
-   * [message] is an explanation of why the error occurred or what it means.
-   */
-  @deprecated // Use logInformation(message, exception)
-  void logInformation2(String message, Object exception);
 }
 
 /**
@@ -9618,13 +2039,7 @@
   void logError(String message, [CaughtException exception]) {}
 
   @override
-  void logError2(String message, Object exception) {}
-
-  @override
   void logInformation(String message, [CaughtException exception]) {}
-
-  @override
-  void logInformation2(String message, Object exception) {}
 }
 
 /**
@@ -9655,547 +2070,6 @@
 }
 
 /**
- * Instances of the class `ParseDartTask` parse a specific source as a Dart file.
- */
-class ParseDartTask extends AnalysisTask {
-  /**
-   * The source to be parsed.
-   */
-  final Source source;
-
-  /**
-   * The head of the token stream used for parsing.
-   */
-  final Token _tokenStream;
-
-  /**
-   * The line information associated with the source.
-   */
-  final LineInfo lineInfo;
-
-  /**
-   * The compilation unit that was produced by parsing the source.
-   */
-  CompilationUnit _unit;
-
-  /**
-   * A flag indicating whether the source contains a 'part of' directive.
-   */
-  bool _containsPartOfDirective = false;
-
-  /**
-   * A flag indicating whether the source contains any directive other than a 'part of' directive.
-   */
-  bool _containsNonPartOfDirective = false;
-
-  /**
-   * A set containing the sources referenced by 'export' directives.
-   */
-  HashSet<Source> _exportedSources = new HashSet<Source>();
-
-  /**
-   * A set containing the sources referenced by 'import' directives.
-   */
-  HashSet<Source> _importedSources = new HashSet<Source>();
-
-  /**
-   * A set containing the sources referenced by 'part' directives.
-   */
-  HashSet<Source> _includedSources = new HashSet<Source>();
-
-  /**
-   * The errors that were produced by scanning and parsing the source.
-   */
-  List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param tokenStream the head of the token stream used for parsing
-   * @param lineInfo the line information associated with the source
-   */
-  ParseDartTask(InternalAnalysisContext context, this.source, this._tokenStream,
-      this.lineInfo)
-      : super(context);
-
-  /**
-   * Return the compilation unit that was produced by parsing the source, or `null` if the
-   * task has not yet been performed or if an exception occurred.
-   *
-   * @return the compilation unit that was produced by parsing the source
-   */
-  CompilationUnit get compilationUnit => _unit;
-
-  /**
-   * Return the errors that were produced by scanning and parsing the source, or an empty list if
-   * the task has not yet been performed or if an exception occurred.
-   *
-   * @return the errors that were produced by scanning and parsing the source
-   */
-  List<AnalysisError> get errors => _errors;
-
-  /**
-   * Return a list containing the sources referenced by 'export' directives, or an empty list if
-   * the task has not yet been performed or if an exception occurred.
-   *
-   * @return an list containing the sources referenced by 'export' directives
-   */
-  List<Source> get exportedSources => _toArray(_exportedSources);
-
-  /**
-   * Return `true` if the source contains any directive other than a 'part of' directive, or
-   * `false` if the task has not yet been performed or if an exception occurred.
-   *
-   * @return `true` if the source contains any directive other than a 'part of' directive
-   */
-  bool get hasNonPartOfDirective => _containsNonPartOfDirective;
-
-  /**
-   * Return `true` if the source contains a 'part of' directive, or `false` if the task
-   * has not yet been performed or if an exception occurred.
-   *
-   * @return `true` if the source contains a 'part of' directive
-   */
-  bool get hasPartOfDirective => _containsPartOfDirective;
-
-  /**
-   * Return a list containing the sources referenced by 'import' directives, or an empty list if
-   * the task has not yet been performed or if an exception occurred.
-   *
-   * @return a list containing the sources referenced by 'import' directives
-   */
-  List<Source> get importedSources => _toArray(_importedSources);
-
-  /**
-   * Return a list containing the sources referenced by 'part' directives, or an empty list if
-   * the task has not yet been performed or if an exception occurred.
-   *
-   * @return a list containing the sources referenced by 'part' directives
-   */
-  List<Source> get includedSources => _toArray(_includedSources);
-
-  @override
-  String get taskDescription {
-    if (source == null) {
-      return "parse as dart null source";
-    }
-    return "parse as dart ${source.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitParseDartTask(this);
-
-  @override
-  void internalPerform() {
-    //
-    // Then parse the token stream.
-    //
-    PerformanceStatistics.parse.makeCurrentWhile(() {
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      Parser parser = new Parser(source, errorListener);
-      AnalysisOptions options = context.analysisOptions;
-      parser.parseFunctionBodies =
-          options.analyzeFunctionBodiesPredicate(source);
-      parser.parseGenericMethods = options.enableGenericMethods;
-      _unit = parser.parseCompilationUnit(_tokenStream);
-      _unit.lineInfo = lineInfo;
-      AnalysisContext analysisContext = context;
-      for (Directive directive in _unit.directives) {
-        if (directive is PartOfDirective) {
-          _containsPartOfDirective = true;
-        } else {
-          _containsNonPartOfDirective = true;
-          if (directive is UriBasedDirective) {
-            Source referencedSource = resolveDirective(
-                analysisContext, source, directive, errorListener);
-            if (referencedSource != null) {
-              if (directive is ExportDirective) {
-                _exportedSources.add(referencedSource);
-              } else if (directive is ImportDirective) {
-                _importedSources.add(referencedSource);
-              } else if (directive is PartDirective) {
-                if (referencedSource != source) {
-                  _includedSources.add(referencedSource);
-                }
-              } else {
-                throw new AnalysisException(
-                    "$runtimeType failed to handle a ${directive.runtimeType}");
-              }
-            }
-          }
-        }
-      }
-      _errors = errorListener.getErrorsForSource(source);
-    });
-  }
-
-  /**
-   * Efficiently convert the given set of [sources] to a list.
-   */
-  List<Source> _toArray(HashSet<Source> sources) {
-    int size = sources.length;
-    if (size == 0) {
-      return Source.EMPTY_LIST;
-    }
-    return new List.from(sources);
-  }
-
-  /**
-   * Return the result of resolving the URI of the given URI-based directive against the URI of the
-   * given library, or `null` if the URI is not valid.
-   *
-   * @param context the context in which the resolution is to be performed
-   * @param librarySource the source representing the library containing the directive
-   * @param directive the directive which URI should be resolved
-   * @param errorListener the error listener to which errors should be reported
-   * @return the result of resolving the URI against the URI of the library
-   */
-  static Source resolveDirective(AnalysisContext context, Source librarySource,
-      UriBasedDirective directive, AnalysisErrorListener errorListener) {
-    StringLiteral uriLiteral = directive.uri;
-    String uriContent = uriLiteral.stringValue;
-    if (uriContent != null) {
-      uriContent = uriContent.trim();
-      directive.uriContent = uriContent;
-    }
-    UriValidationCode code = directive.validate();
-    if (code == null) {
-      String encodedUriContent = Uri.encodeFull(uriContent);
-      try {
-        Source source =
-            context.sourceFactory.resolveUri(librarySource, encodedUriContent);
-        directive.source = source;
-        return source;
-      } on JavaIOException {
-        code = UriValidationCode.INVALID_URI;
-      }
-    }
-    if (code == UriValidationCode.URI_WITH_DART_EXT_SCHEME) {
-      return null;
-    }
-    if (code == UriValidationCode.URI_WITH_INTERPOLATION) {
-      errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
-          uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION));
-      return null;
-    }
-    if (code == UriValidationCode.INVALID_URI) {
-      errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
-          uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
-      return null;
-    }
-    throw new RuntimeException(
-        message: "Failed to handle validation code: $code");
-  }
-}
-
-/**
- * Instances of the class `ParseHtmlTask` parse a specific source as an HTML file.
- */
-class ParseHtmlTask extends AnalysisTask {
-  /**
-   * The name of the 'src' attribute in a HTML tag.
-   */
-  static String _ATTRIBUTE_SRC = "src";
-
-  /**
-   * The name of the 'script' tag in an HTML file.
-   */
-  static String _TAG_SCRIPT = "script";
-
-  /**
-   * The source to be parsed.
-   */
-  final Source source;
-
-  /**
-   * The contents of the source.
-   */
-  final String _content;
-
-  /**
-   * The line information that was produced.
-   */
-  LineInfo _lineInfo;
-
-  /**
-   * The HTML unit that was produced by parsing the source.
-   */
-  ht.HtmlUnit _unit;
-
-  /**
-   * The errors that were produced by scanning and parsing the source.
-   */
-  List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
-
-  /**
-   * A list containing the sources of the libraries that are referenced within the HTML.
-   */
-  List<Source> _referencedLibraries = Source.EMPTY_LIST;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param content the contents of the source
-   */
-  ParseHtmlTask(InternalAnalysisContext context, this.source, this._content)
-      : super(context);
-
-  /**
-   * Return the errors that were produced by scanning and parsing the source, or `null` if the
-   * task has not yet been performed or if an exception occurred.
-   *
-   * @return the errors that were produced by scanning and parsing the source
-   */
-  List<AnalysisError> get errors => _errors;
-
-  /**
-   * Return the HTML unit that was produced by parsing the source.
-   *
-   * @return the HTML unit that was produced by parsing the source
-   */
-  ht.HtmlUnit get htmlUnit => _unit;
-
-  /**
-   * Return the sources of libraries that are referenced in the specified HTML file.
-   *
-   * @return the sources of libraries that are referenced in the HTML file
-   */
-  List<Source> get librarySources {
-    List<Source> libraries = new List<Source>();
-    _unit.accept(new ParseHtmlTask_getLibrarySources(this, libraries));
-    if (libraries.isEmpty) {
-      return Source.EMPTY_LIST;
-    }
-    return libraries;
-  }
-
-  /**
-   * Return the line information that was produced, or `null` if the task has not yet been
-   * performed or if an exception occurred.
-   *
-   * @return the line information that was produced
-   */
-  LineInfo get lineInfo => _lineInfo;
-
-  /**
-   * Return a list containing the sources of the libraries that are referenced within the HTML.
-   *
-   * @return the sources of the libraries that are referenced within the HTML
-   */
-  List<Source> get referencedLibraries => _referencedLibraries;
-
-  @override
-  String get taskDescription {
-    if (source == null) {
-      return "parse as html null source";
-    }
-    return "parse as html ${source.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitParseHtmlTask(this);
-
-  @override
-  void internalPerform() {
-    try {
-      ht.AbstractScanner scanner = new ht.StringScanner(source, _content);
-      scanner.passThroughElements = <String>[_TAG_SCRIPT];
-      ht.Token token = scanner.tokenize();
-      _lineInfo = new LineInfo(scanner.lineStarts);
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      _unit = new ht.HtmlParser(source, errorListener, context.analysisOptions)
-          .parse(token, _lineInfo);
-      _unit.accept(new RecursiveXmlVisitor_ParseHtmlTask_internalPerform(
-          this, errorListener));
-      _errors = errorListener.getErrorsForSource(source);
-      _referencedLibraries = librarySources;
-    } catch (exception, stackTrace) {
-      throw new AnalysisException(
-          "Exception", new CaughtException(exception, stackTrace));
-    }
-  }
-
-  /**
-   * Resolves directives in the given [CompilationUnit].
-   */
-  void _resolveScriptDirectives(
-      CompilationUnit script, AnalysisErrorListener errorListener) {
-    if (script == null) {
-      return;
-    }
-    AnalysisContext analysisContext = context;
-    for (Directive directive in script.directives) {
-      if (directive is UriBasedDirective) {
-        ParseDartTask.resolveDirective(
-            analysisContext, source, directive, errorListener);
-      }
-    }
-  }
-}
-
-class ParseHtmlTask_getLibrarySources extends ht.RecursiveXmlVisitor<Object> {
-  final ParseHtmlTask _task;
-
-  List<Source> libraries;
-
-  ParseHtmlTask_getLibrarySources(this._task, this.libraries) : super();
-
-  @override
-  Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    ht.XmlAttributeNode scriptAttribute = null;
-    for (ht.XmlAttributeNode attribute in node.attributes) {
-      if (javaStringEqualsIgnoreCase(
-          attribute.name, ParseHtmlTask._ATTRIBUTE_SRC)) {
-        scriptAttribute = attribute;
-      }
-    }
-    if (scriptAttribute != null) {
-      try {
-        Uri uri = Uri.parse(scriptAttribute.text);
-        String fileName = uri.path;
-        Source librarySource =
-            _task.context.sourceFactory.resolveUri(_task.source, fileName);
-        if (_task.context.exists(librarySource)) {
-          libraries.add(librarySource);
-        }
-      } on FormatException {
-        // ignored - invalid URI reported during resolution phase
-      }
-    }
-    return super.visitHtmlScriptTagNode(node);
-  }
-}
-
-/**
- * An object that manages the partitions that can be shared between analysis
- * contexts.
- */
-class PartitionManager {
-  /**
-   * The default cache size for a Dart SDK partition.
-   */
-  static int _DEFAULT_SDK_CACHE_SIZE = 256;
-
-  /**
-   * A table mapping SDK's to the partitions used for those SDK's.
-   */
-  HashMap<DartSdk, SdkCachePartition> _sdkPartitions =
-      new HashMap<DartSdk, SdkCachePartition>();
-
-  /**
-   * Clear any cached data being maintained by this manager.
-   */
-  void clearCache() {
-    _sdkPartitions.clear();
-  }
-
-  /**
-   * Return the partition being used for the given [sdk], creating the partition
-   * if necessary.
-   */
-  SdkCachePartition forSdk(DartSdk sdk) {
-    // Call sdk.context now, because when it creates a new
-    // InternalAnalysisContext instance, it calls forSdk() again, so creates an
-    // SdkCachePartition instance.
-    // So, if we initialize context after "partition == null", we end up
-    // with two SdkCachePartition instances.
-    InternalAnalysisContext sdkContext = sdk.context;
-    // Check cache for an existing partition.
-    SdkCachePartition partition = _sdkPartitions[sdk];
-    if (partition == null) {
-      partition = new SdkCachePartition(sdkContext, _DEFAULT_SDK_CACHE_SIZE);
-      _sdkPartitions[sdk] = partition;
-    }
-    return partition;
-  }
-}
-
-/**
- * Representation of a pending computation which is based on the results of
- * analysis that may or may not have been completed.
- */
-class PendingFuture<T> {
-  /**
-   * The context in which this computation runs.
-   */
-  final AnalysisContextImpl _context;
-
-  /**
-   * The source used by this computation to compute its value.
-   */
-  final Source source;
-
-  /**
-   * The function which implements the computation.
-   */
-  final PendingFutureComputer<T> _computeValue;
-
-  /**
-   * The completer that should be completed once the computation has succeeded.
-   */
-  CancelableCompleter<T> _completer;
-
-  PendingFuture(this._context, this.source, this._computeValue) {
-    _completer = new CancelableCompleter<T>(_onCancel);
-  }
-
-  /**
-   * Retrieve the future which will be completed when this object is
-   * successfully evaluated.
-   */
-  CancelableFuture<T> get future => _completer.future;
-
-  /**
-   * Execute [_computeValue], passing it the given [sourceEntry], and complete
-   * the pending future if it's appropriate to do so.  If the pending future is
-   * completed by this call, true is returned; otherwise false is returned.
-   *
-   * Once this function has returned true, it should not be called again.
-   *
-   * Other than completing the future, this method is free of side effects.
-   * Note that any code the client has attached to the future will be executed
-   * in a microtask, so there is no danger of side effects occurring due to
-   * client callbacks.
-   */
-  bool evaluate(SourceEntry sourceEntry) {
-    assert(!_completer.isCompleted);
-    try {
-      T result = _computeValue(sourceEntry);
-      if (result == null) {
-        return false;
-      } else {
-        _completer.complete(result);
-        return true;
-      }
-    } catch (exception, stackTrace) {
-      _completer.completeError(exception, stackTrace);
-      return true;
-    }
-  }
-
-  /**
-   * No further analysis updates are expected which affect this future, so
-   * complete it with an AnalysisNotScheduledError in order to avoid
-   * deadlocking the client.
-   */
-  void forciblyComplete() {
-    try {
-      throw new AnalysisNotScheduledError();
-    } catch (exception, stackTrace) {
-      _completer.completeError(exception, stackTrace);
-    }
-  }
-
-  void _onCancel() {
-    _context._cancelFuture(this);
-  }
-}
-
-/**
  * Container with global [AnalysisContext] performance statistics.
  */
 class PerformanceStatistics {
@@ -10242,7 +2116,7 @@
   /**
    * The [PerformanceTag] for time spent in other phases of analysis.
    */
-  static PerformanceTag performAnaysis = new PerformanceTag('performAnaysis');
+  static PerformanceTag performAnalysis = new PerformanceTag('performAnalysis');
 
   /**
    * The [PerformanceTag] for time spent in the analysis task visitor after
@@ -10263,6 +2137,11 @@
    */
   static PerformanceTag incrementalAnalysis =
       new PerformanceTag('incrementalAnalysis');
+
+  /**
+   * The [PerformanceTag] for time spent in summaries support.
+   */
+  static PerformanceTag summary = new PerformanceTag('summary');
 }
 
 /**
@@ -10325,44 +2204,6 @@
   }
 }
 
-class RecursiveXmlVisitor_ParseHtmlTask_internalPerform
-    extends ht.RecursiveXmlVisitor<Object> {
-  final ParseHtmlTask ParseHtmlTask_this;
-
-  RecordingErrorListener errorListener;
-
-  RecursiveXmlVisitor_ParseHtmlTask_internalPerform(
-      this.ParseHtmlTask_this, this.errorListener)
-      : super();
-
-  @override
-  Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    ParseHtmlTask_this._resolveScriptDirectives(node.script, errorListener);
-    return null;
-  }
-}
-
-class RecursiveXmlVisitor_ResolveHtmlTask_internalPerform
-    extends ht.RecursiveXmlVisitor<Object> {
-  final ResolveHtmlTask ResolveHtmlTask_this;
-
-  RecordingErrorListener errorListener;
-
-  RecursiveXmlVisitor_ResolveHtmlTask_internalPerform(
-      this.ResolveHtmlTask_this, this.errorListener)
-      : super();
-
-  @override
-  Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    CompilationUnit script = node.script;
-    if (script != null) {
-      GenerateDartErrorsTask.validateDirectives(ResolveHtmlTask_this.context,
-          ResolveHtmlTask_this.source, script, errorListener);
-    }
-    return null;
-  }
-}
-
 /**
  * An visitor that removes any resolution information from an AST structure when
  * used to visit that structure.
@@ -10512,1257 +2353,6 @@
 }
 
 /**
- * The information produced by resolving a compilation unit as part of a
- * specific library.
- */
-class ResolutionState {
-  /**
-   * The next resolution state or `null` if none.
-   */
-  ResolutionState _nextState;
-
-  /**
-   * The source for the defining compilation unit of the library that contains
-   * this unit. If this unit is the defining compilation unit for it's library,
-   * then this will be the source for this unit.
-   */
-  Source _librarySource;
-
-  /**
-   * A table mapping descriptors to the cached results for those descriptors.
-   * If there is no entry for a given descriptor then the state is implicitly
-   * [CacheState.INVALID] and the value is implicitly the default value.
-   */
-  Map<DataDescriptor, CachedResult> resultMap =
-      new HashMap<DataDescriptor, CachedResult>();
-
-  /**
-   * Flush any AST structures being maintained by this state.
-   */
-  void flushAstStructures() {
-    _flush(DartEntry.BUILT_UNIT);
-    _flush(DartEntry.RESOLVED_UNIT);
-    if (_nextState != null) {
-      _nextState.flushAstStructures();
-    }
-  }
-
-  /**
-   * Return the state of the data represented by the given [descriptor].
-   */
-  CacheState getState(DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    if (result == null) {
-      return CacheState.INVALID;
-    }
-    return result.state;
-  }
-
-  /**
-   * Return the value of the data represented by the given [descriptor], or
-   * `null` if the data represented by the descriptor is not valid.
-   */
-  /*<V>*/ dynamic /*V*/ getValue(DataDescriptor /*<V>*/ descriptor) {
-    CachedResult result = resultMap[descriptor];
-    if (result == null) {
-      return descriptor.defaultValue;
-    }
-    return result.value;
-  }
-
-  /**
-   * Return `true` if the state of any data value is [CacheState.ERROR].
-   */
-  bool hasErrorState() {
-    for (CachedResult result in resultMap.values) {
-      if (result.state == CacheState.ERROR) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Invalidate all of the resolution information associated with the compilation unit.
-   */
-  void invalidateAllResolutionInformation() {
-    _nextState = null;
-    _librarySource = null;
-    setState(DartEntry.BUILT_UNIT, CacheState.INVALID);
-    setState(DartEntry.BUILT_ELEMENT, CacheState.INVALID);
-    setState(DartEntry.HINTS, CacheState.INVALID);
-    setState(DartEntry.LINTS, CacheState.INVALID);
-    setState(DartEntry.RESOLVED_UNIT, CacheState.INVALID);
-    setState(DartEntry.RESOLUTION_ERRORS, CacheState.INVALID);
-    setState(DartEntry.VERIFICATION_ERRORS, CacheState.INVALID);
-  }
-
-  /**
-   * Record that an exception occurred while attempting to build the element
-   * model for the source associated with this state.
-   */
-  void recordBuildElementError() {
-    setState(DartEntry.BUILT_UNIT, CacheState.ERROR);
-    setState(DartEntry.BUILT_ELEMENT, CacheState.ERROR);
-    recordResolutionError();
-  }
-
-  /**
-   * Record that an exception occurred while attempting to generate hints for
-   * the source associated with this entry. This will set the state of all
-   * verification information as being in error.
-   */
-  void recordHintError() {
-    setState(DartEntry.HINTS, CacheState.ERROR);
-  }
-
-  /**
-   * Record that an exception occurred while attempting to generate lints for
-   * the source associated with this entry. This will set the state of all
-   * verification information as being in error.
-   */
-  void recordLintError() {
-    setState(DartEntry.LINTS, CacheState.ERROR);
-  }
-
-  /**
-   * Record that an exception occurred while attempting to resolve the source
-   * associated with this state.
-   */
-  void recordResolutionError() {
-    setState(DartEntry.RESOLVED_UNIT, CacheState.ERROR);
-    setState(DartEntry.RESOLUTION_ERRORS, CacheState.ERROR);
-    recordVerificationError();
-  }
-
-  /**
-   * Record that an exception occurred while attempting to scan or parse the
-   * source associated with this entry. This will set the state of all
-   * resolution-based information as being in error.
-   */
-  void recordResolutionErrorsInAllLibraries() {
-    recordBuildElementError();
-    if (_nextState != null) {
-      _nextState.recordResolutionErrorsInAllLibraries();
-    }
-  }
-
-  /**
-   * Record that an exception occurred while attempting to generate errors and
-   * warnings for the source associated with this entry. This will set the state
-   * of all verification information as being in error.
-   */
-  void recordVerificationError() {
-    setState(DartEntry.VERIFICATION_ERRORS, CacheState.ERROR);
-    recordHintError();
-  }
-
-  /**
-   * Set the state of the data represented by the given [descriptor] to the
-   * given [state].
-   */
-  void setState(DataDescriptor descriptor, CacheState state) {
-    if (state == CacheState.VALID) {
-      throw new ArgumentError("use setValue() to set the state to VALID");
-    }
-    if (state == CacheState.INVALID) {
-      resultMap.remove(descriptor);
-    } else {
-      CachedResult result =
-          resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
-      result.state = state;
-      if (state != CacheState.IN_PROCESS) {
-        //
-        // If the state is in-process, we can leave the current value in the
-        // cache for any 'get' methods to access.
-        //
-        result.value = descriptor.defaultValue;
-      }
-    }
-  }
-
-  /**
-   * Set the value of the data represented by the given [descriptor] to the
-   * given [value].
-   */
-  void setValue(DataDescriptor /*<V>*/ descriptor, dynamic /*V*/ value) {
-    CachedResult result =
-        resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
-    SourceEntry.countTransition(descriptor, result);
-    result.state = CacheState.VALID;
-    result.value = value == null ? descriptor.defaultValue : value;
-  }
-
-  /**
-   * Flush the value of the data described by the [descriptor].
-   */
-  void _flush(DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    if (result != null && result.state == CacheState.VALID) {
-      result.state = CacheState.FLUSHED;
-      result.value = descriptor.defaultValue;
-    }
-  }
-
-  /**
-   * Write a textual representation of the difference between the old entry and
-   * this entry to the given string [buffer]. A separator will be written before
-   * the first difference if [needsSeparator] is `true`. The [oldEntry] is the
-   * entry that was replaced by this entry. Return `true` is a separator is
-   * needed before writing any subsequent differences.
-   */
-  bool _writeDiffOn(
-      StringBuffer buffer, bool needsSeparator, DartEntry oldEntry) {
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "resolvedUnit",
-        DartEntry.RESOLVED_UNIT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "resolutionErrors", DartEntry.RESOLUTION_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "verificationErrors", DartEntry.VERIFICATION_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "hints", DartEntry.HINTS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "lints", DartEntry.LINTS, oldEntry);
-    return needsSeparator;
-  }
-
-  /**
-   * Write a textual representation of this state to the given [buffer]. The
-   * result will only be used for debugging purposes.
-   */
-  void _writeOn(StringBuffer buffer) {
-    if (_librarySource != null) {
-      _writeStateOn(buffer, "builtElement", DartEntry.BUILT_ELEMENT);
-      _writeStateOn(buffer, "builtUnit", DartEntry.BUILT_UNIT);
-      _writeStateOn(buffer, "resolvedUnit", DartEntry.RESOLVED_UNIT);
-      _writeStateOn(buffer, "resolutionErrors", DartEntry.RESOLUTION_ERRORS);
-      _writeStateOn(
-          buffer, "verificationErrors", DartEntry.VERIFICATION_ERRORS);
-      _writeStateOn(buffer, "hints", DartEntry.HINTS);
-      _writeStateOn(buffer, "lints", DartEntry.LINTS);
-      if (_nextState != null) {
-        _nextState._writeOn(buffer);
-      }
-    }
-  }
-
-  /**
-   * Write a textual representation of the difference between the state of the
-   * value described by the given [descriptor] between the [oldEntry] and this
-   * entry to the given [buffer]. Return `true` if some difference was written.
-   */
-  bool _writeStateDiffOn(StringBuffer buffer, bool needsSeparator, String label,
-      DataDescriptor descriptor, SourceEntry oldEntry) {
-    CacheState oldState = oldEntry.getState(descriptor);
-    CacheState newState = getState(descriptor);
-    if (oldState != newState) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write(label);
-      buffer.write(" = ");
-      buffer.write(oldState);
-      buffer.write(" -> ");
-      buffer.write(newState);
-      return true;
-    }
-    return needsSeparator;
-  }
-
-  /**
-   * Write a textual representation of the state of the value described by the
-   * given [descriptor] to the given bugger, prefixed by the given [label] to
-   * the given [buffer].
-   */
-  void _writeStateOn(
-      StringBuffer buffer, String label, DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    buffer.write("; ");
-    buffer.write(label);
-    buffer.write(" = ");
-    buffer.write(result == null ? CacheState.INVALID : result.state);
-  }
-}
-
-/**
- * A compilation unit that is not referenced by any other objects. It is used by
- * the [LibraryResolver] to resolve a library.
- */
-class ResolvableCompilationUnit {
-  /**
-   * The source of the compilation unit.
-   */
-  final Source source;
-
-  /**
-   * The compilation unit.
-   */
-  final CompilationUnit compilationUnit;
-
-  /**
-   * Initialize a newly created holder to hold the given [source] and
-   * [compilationUnit].
-   */
-  ResolvableCompilationUnit(this.source, this.compilationUnit);
-}
-
-/**
- * Instances of the class `ResolveDartLibraryTask` resolve a specific Dart library.
- */
-class ResolveDartLibraryCycleTask extends AnalysisTask {
-  /**
-   * The source representing the file whose compilation unit is to be returned. TODO(brianwilkerson)
-   * This should probably be removed, but is being left in for now to ease the transition.
-   */
-  final Source unitSource;
-
-  /**
-   * The source representing the library to be resolved.
-   */
-  final Source librarySource;
-
-  /**
-   * The libraries that are part of the cycle containing the library to be resolved.
-   */
-  final List<ResolvableLibrary> _librariesInCycle;
-
-  /**
-   * The library resolver holding information about the libraries that were resolved.
-   */
-  LibraryResolver2 _resolver;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param unitSource the source representing the file whose compilation unit is to be returned
-   * @param librarySource the source representing the library to be resolved
-   * @param librariesInCycle the libraries that are part of the cycle containing the library to be
-   *          resolved
-   */
-  ResolveDartLibraryCycleTask(InternalAnalysisContext context, this.unitSource,
-      this.librarySource, this._librariesInCycle)
-      : super(context);
-
-  /**
-   * Return the library resolver holding information about the libraries that were resolved.
-   *
-   * @return the library resolver holding information about the libraries that were resolved
-   */
-  LibraryResolver2 get libraryResolver => _resolver;
-
-  @override
-  String get taskDescription {
-    if (librarySource == null) {
-      return "resolve library null source";
-    }
-    return "resolve library ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitResolveDartLibraryCycleTask(this);
-
-  @override
-  void internalPerform() {
-    _resolver = new LibraryResolver2(context);
-    _resolver.resolveLibrary(librarySource, _librariesInCycle);
-  }
-}
-
-/**
- * Instances of the class `ResolveDartLibraryTask` resolve a specific Dart library.
- */
-class ResolveDartLibraryTask extends AnalysisTask {
-  /**
-   * The source representing the file whose compilation unit is to be returned.
-   */
-  final Source unitSource;
-
-  /**
-   * The source representing the library to be resolved.
-   */
-  final Source librarySource;
-
-  /**
-   * The library resolver holding information about the libraries that were resolved.
-   */
-  LibraryResolver _resolver;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param unitSource the source representing the file whose compilation unit is to be returned
-   * @param librarySource the source representing the library to be resolved
-   */
-  ResolveDartLibraryTask(
-      InternalAnalysisContext context, this.unitSource, this.librarySource)
-      : super(context);
-
-  /**
-   * Return the library resolver holding information about the libraries that were resolved.
-   *
-   * @return the library resolver holding information about the libraries that were resolved
-   */
-  LibraryResolver get libraryResolver => _resolver;
-
-  @override
-  String get taskDescription {
-    if (librarySource == null) {
-      return "resolve library null source";
-    }
-    return "resolve library ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitResolveDartLibraryTask(this);
-
-  @override
-  void internalPerform() {
-    LibraryResolverFactory resolverFactory = context.libraryResolverFactory;
-    _resolver = resolverFactory == null
-        ? new LibraryResolver(context)
-        : resolverFactory(context);
-    _resolver.resolveLibrary(librarySource, true);
-  }
-}
-
-/**
- * Instances of the class `ResolveDartUnitTask` resolve a single Dart file based on a existing
- * element model.
- */
-class ResolveDartUnitTask extends AnalysisTask {
-  /**
-   * The source that is to be resolved.
-   */
-  final Source source;
-
-  /**
-   * The element model for the library containing the source.
-   */
-  final LibraryElement _libraryElement;
-
-  /**
-   * The compilation unit that was resolved by this task.
-   */
-  CompilationUnit _resolvedUnit;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param libraryElement the element model for the library containing the source
-   */
-  ResolveDartUnitTask(
-      InternalAnalysisContext context, this.source, this._libraryElement)
-      : super(context);
-
-  /**
-   * Return the source for the library containing the source that is to be resolved.
-   *
-   * @return the source for the library containing the source that is to be resolved
-   */
-  Source get librarySource => _libraryElement.source;
-
-  /**
-   * Return the compilation unit that was resolved by this task.
-   *
-   * @return the compilation unit that was resolved by this task
-   */
-  CompilationUnit get resolvedUnit => _resolvedUnit;
-
-  @override
-  String get taskDescription {
-    Source librarySource = _libraryElement.source;
-    if (librarySource == null) {
-      return "resolve unit null source";
-    }
-    return "resolve unit ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitResolveDartUnitTask(this);
-
-  @override
-  void internalPerform() {
-    TypeProvider typeProvider = _libraryElement.context.typeProvider;
-    CompilationUnit unit = context.computeResolvableCompilationUnit(source);
-    if (unit == null) {
-      throw new AnalysisException(
-          "Internal error: computeResolvableCompilationUnit returned a value without a parsed Dart unit");
-    }
-    //
-    // Resolve names in declarations.
-    //
-    new DeclarationResolver().resolve(unit, _find(_libraryElement, source));
-    //
-    // Resolve the type names.
-    //
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-    TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor(
-        _libraryElement, source, typeProvider, errorListener);
-    unit.accept(typeResolverVisitor);
-    //
-    // Resolve the rest of the structure
-    //
-    InheritanceManager inheritanceManager =
-        new InheritanceManager(_libraryElement);
-    ResolverVisitor resolverVisitor = new ResolverVisitor(
-        _libraryElement, source, typeProvider, errorListener,
-        inheritanceManager: inheritanceManager);
-    unit.accept(resolverVisitor);
-    //
-    // Perform additional error checking.
-    //
-    PerformanceStatistics.errors.makeCurrentWhile(() {
-      ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
-      ErrorVerifier errorVerifier = new ErrorVerifier(
-          errorReporter,
-          _libraryElement,
-          typeProvider,
-          inheritanceManager,
-          context.analysisOptions.enableSuperMixins);
-      unit.accept(errorVerifier);
-      // TODO(paulberry): as a temporary workaround for issue 21572,
-      // ConstantVerifier is being run right after ConstantValueComputer, so we
-      // don't need to run it here.  Once issue 21572 is fixed, re-enable the
-      // call to ConstantVerifier.
-//       ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, _libraryElement, typeProvider);
-//       unit.accept(constantVerifier);
-    });
-    //
-    // Capture the results.
-    //
-    _resolvedUnit = unit;
-  }
-
-  /**
-   * Search the compilation units that are part of the given library and return the element
-   * representing the compilation unit with the given source. Return `null` if there is no
-   * such compilation unit.
-   *
-   * @param libraryElement the element representing the library being searched through
-   * @param unitSource the source for the compilation unit whose element is to be returned
-   * @return the element representing the compilation unit
-   */
-  CompilationUnitElement _find(
-      LibraryElement libraryElement, Source unitSource) {
-    CompilationUnitElement element = libraryElement.definingCompilationUnit;
-    if (element.source == unitSource) {
-      return element;
-    }
-    for (CompilationUnitElement partElement in libraryElement.parts) {
-      if (partElement.source == unitSource) {
-        return partElement;
-      }
-    }
-    return null;
-  }
-}
-
-/**
- * Instances of the class `ResolveHtmlTask` resolve a specific source as an HTML file.
- */
-class ResolveHtmlTask extends AnalysisTask {
-  /**
-   * The source to be resolved.
-   */
-  final Source source;
-
-  /**
-   * The time at which the contents of the source were last modified.
-   */
-  final int modificationTime;
-
-  /**
-   * The HTML unit to be resolved.
-   */
-  final ht.HtmlUnit _unit;
-
-  /**
-   * The [HtmlUnit] that was resolved by this task.
-   */
-  ht.HtmlUnit _resolvedUnit;
-
-  /**
-   * The element produced by resolving the source.
-   */
-  HtmlElement _element = null;
-
-  /**
-   * The resolution errors that were discovered while resolving the source.
-   */
-  List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be resolved
-   * @param modificationTime the time at which the contents of the source were last modified
-   * @param unit the HTML unit to be resolved
-   */
-  ResolveHtmlTask(InternalAnalysisContext context, this.source,
-      this.modificationTime, this._unit)
-      : super(context);
-
-  HtmlElement get element => _element;
-
-  List<AnalysisError> get resolutionErrors => _resolutionErrors;
-
-  /**
-   * Return the [HtmlUnit] that was resolved by this task.
-   *
-   * @return the [HtmlUnit] that was resolved by this task
-   */
-  ht.HtmlUnit get resolvedUnit => _resolvedUnit;
-
-  @override
-  String get taskDescription {
-    if (source == null) {
-      return "resolve as html null source";
-    }
-    return "resolve as html ${source.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitResolveHtmlTask(this);
-
-  @override
-  void internalPerform() {
-    //
-    // Build the standard HTML element.
-    //
-    HtmlUnitBuilder builder = new HtmlUnitBuilder(context);
-    _element = builder.buildHtmlElement(source, _unit);
-    RecordingErrorListener errorListener = builder.errorListener;
-    //
-    // Validate the directives
-    //
-    _unit.accept(new RecursiveXmlVisitor_ResolveHtmlTask_internalPerform(
-        this, errorListener));
-    //
-    // Record all resolution errors.
-    //
-    _resolutionErrors = errorListener.getErrorsForSource(source);
-    //
-    // Remember the resolved unit.
-    //
-    _resolvedUnit = _unit;
-  }
-}
-
-/**
- * The priority of data in the cache in terms of the desirability of retaining
- * some specified data about a specified source.
- */
-class RetentionPriority extends Enum<RetentionPriority> {
-  /**
-   * A priority indicating that a given piece of data can be removed from the
-   * cache without reservation.
-   */
-  static const RetentionPriority LOW = const RetentionPriority('LOW', 0);
-
-  /**
-   * A priority indicating that a given piece of data should not be removed from
-   * the cache unless there are no sources for which the corresponding data has
-   * a lower priority. Currently used for data that is needed in order to finish
-   * some outstanding analysis task.
-   */
-  static const RetentionPriority MEDIUM = const RetentionPriority('MEDIUM', 1);
-
-  /**
-   * A priority indicating that a given piece of data should not be removed from
-   * the cache. Currently used for data related to a priority source.
-   */
-  static const RetentionPriority HIGH = const RetentionPriority('HIGH', 2);
-
-  static const List<RetentionPriority> values = const [LOW, MEDIUM, HIGH];
-
-  const RetentionPriority(String name, int ordinal) : super(name, ordinal);
-}
-
-/**
- * Instances of the class `ScanDartTask` scan a specific source as a Dart file.
- */
-class ScanDartTask extends AnalysisTask {
-  /**
-   * The source to be scanned.
-   */
-  final Source source;
-
-  /**
-   * The contents of the source.
-   */
-  final String _content;
-
-  /**
-   * The token stream that was produced by scanning the source.
-   */
-  Token _tokenStream;
-
-  /**
-   * The line information that was produced.
-   */
-  LineInfo _lineInfo;
-
-  /**
-   * The errors that were produced by scanning the source.
-   */
-  List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param content the contents of the source
-   */
-  ScanDartTask(InternalAnalysisContext context, this.source, this._content)
-      : super(context);
-
-  /**
-   * Return the errors that were produced by scanning the source, or `null` if the task has
-   * not yet been performed or if an exception occurred.
-   *
-   * @return the errors that were produced by scanning the source
-   */
-  List<AnalysisError> get errors => _errors;
-
-  /**
-   * Return the line information that was produced, or `null` if the task has not yet been
-   * performed or if an exception occurred.
-   *
-   * @return the line information that was produced
-   */
-  LineInfo get lineInfo => _lineInfo;
-
-  @override
-  String get taskDescription {
-    if (source == null) {
-      return "scan as dart null source";
-    }
-    return "scan as dart ${source.fullName}";
-  }
-
-  /**
-   * Return the token stream that was produced by scanning the source, or `null` if the task
-   * has not yet been performed or if an exception occurred.
-   *
-   * @return the token stream that was produced by scanning the source
-   */
-  Token get tokenStream => _tokenStream;
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitScanDartTask(this);
-
-  @override
-  void internalPerform() {
-    PerformanceStatistics.scan.makeCurrentWhile(() {
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      try {
-        Scanner scanner = new Scanner(
-            source, new CharSequenceReader(_content), errorListener);
-        scanner.preserveComments = context.analysisOptions.preserveComments;
-        _tokenStream = scanner.tokenize();
-        _lineInfo = new LineInfo(scanner.lineStarts);
-        _errors = errorListener.getErrorsForSource(source);
-      } catch (exception, stackTrace) {
-        throw new AnalysisException(
-            "Exception", new CaughtException(exception, stackTrace));
-      }
-    });
-  }
-}
-
-/**
- * An [AnalysisContext] that only contains sources for a Dart SDK.
- */
-class SdkAnalysisContext extends AnalysisContextImpl {
-  @override
-  AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
-    if (factory == null) {
-      return super.createCacheFromSourceFactory(factory);
-    }
-    DartSdk sdk = factory.dartSdk;
-    if (sdk == null) {
-      throw new IllegalArgumentException(
-          "The source factory for an SDK analysis context must have a DartUriResolver");
-    }
-    return new AnalysisCache(
-        <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
-  }
-}
-
-/**
- * A cache partition that contains all of the sources in the SDK.
- */
-class SdkCachePartition extends CachePartition {
-  /**
-   * Initialize a newly created partition. The [context] is the context that
-   * owns this partition. The [maxCacheSize] is the maximum number of sources
-   * for which AST structures should be kept in the cache.
-   */
-  SdkCachePartition(InternalAnalysisContext context, int maxCacheSize)
-      : super(context, maxCacheSize, DefaultRetentionPolicy.POLICY);
-
-  @override
-  bool contains(Source source) => source.isInSystemLibrary;
-}
-
-/**
- * The information cached by an analysis context about an individual source, no
- * matter what kind of source it is.
- */
-abstract class SourceEntry {
-  /**
-   * The data descriptor representing the contents of the source.
-   */
-  static final DataDescriptor<String> CONTENT =
-      new DataDescriptor<String>("SourceEntry.CONTENT");
-
-  /**
-   * The data descriptor representing the errors resulting from reading the
-   * source content.
-   */
-  static final DataDescriptor<List<AnalysisError>> CONTENT_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "SourceEntry.CONTENT_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the line information.
-   */
-  static final DataDescriptor<LineInfo> LINE_INFO =
-      new DataDescriptor<LineInfo>("SourceEntry.LINE_INFO");
-
-  /**
-   * The index of the flag indicating whether the source was explicitly added to
-   * the context or whether the source was implicitly added because it was
-   * referenced by another source.
-   */
-  static int _EXPLICITLY_ADDED_FLAG = 0;
-
-  /**
-   * A table mapping data descriptors to a count of the number of times a value
-   * was set when in a given state.
-   */
-  static final Map<DataDescriptor, Map<CacheState, int>> transitionMap =
-      new HashMap<DataDescriptor, Map<CacheState, int>>();
-
-  /**
-   * The most recent time at which the state of the source matched the state
-   * represented by this entry.
-   */
-  int modificationTime = 0;
-
-  /**
-   * The exception that caused one or more values to have a state of
-   * [CacheState.ERROR].
-   */
-  CaughtException exception;
-
-  /**
-   * A bit-encoding of boolean flags associated with this element.
-   */
-  int _flags = 0;
-
-  /**
-   * A table mapping data descriptors to the cached results for those
-   * descriptors.
-   */
-  Map<DataDescriptor, CachedResult> resultMap =
-      new HashMap<DataDescriptor, CachedResult>();
-
-  /**
-   * Return all of the errors associated with this entry.
-   */
-  List<AnalysisError> get allErrors {
-    return getValue(CONTENT_ERRORS);
-  }
-
-  /**
-   * Get a list of all the library-independent descriptors for which values may
-   * be stored in this SourceEntry.
-   */
-  List<DataDescriptor> get descriptors {
-    return <DataDescriptor>[CONTENT, CONTENT_ERRORS, LINE_INFO];
-  }
-
-  /**
-   * Return `true` if the source was explicitly added to the context or `false`
-   * if the source was implicitly added because it was referenced by another
-   * source.
-   */
-  bool get explicitlyAdded => _getFlag(_EXPLICITLY_ADDED_FLAG);
-
-  /**
-   * Set whether the source was explicitly added to the context to match the
-   * [explicitlyAdded] flag.
-   */
-  void set explicitlyAdded(bool explicitlyAdded) {
-    _setFlag(_EXPLICITLY_ADDED_FLAG, explicitlyAdded);
-  }
-
-  /**
-   * Return the kind of the source, or `null` if the kind is not currently
-   * cached.
-   */
-  SourceKind get kind;
-
-  /**
-   * Fix the state of the [exception] to match the current state of the entry.
-   */
-  void fixExceptionState() {
-    if (hasErrorState()) {
-      if (exception == null) {
-        //
-        // This code should never be reached, but is a fail-safe in case an
-        // exception is not recorded when it should be.
-        //
-        String message = "State set to ERROR without setting an exception";
-        exception = new CaughtException(new AnalysisException(message), null);
-      }
-    } else {
-      exception = null;
-    }
-  }
-
-  /**
-   * Return a textual representation of the difference between the [oldEntry]
-   * and this entry. The difference is represented as a sequence of fields whose
-   * value would change if the old entry were converted into the new entry.
-   */
-  String getDiff(SourceEntry oldEntry) {
-    StringBuffer buffer = new StringBuffer();
-    _writeDiffOn(buffer, oldEntry);
-    return buffer.toString();
-  }
-
-  /**
-   * Return the state of the data represented by the given [descriptor].
-   */
-  CacheState getState(DataDescriptor descriptor) {
-    if (!_isValidDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    CachedResult result = resultMap[descriptor];
-    if (result == null) {
-      return CacheState.INVALID;
-    }
-    return result.state;
-  }
-
-  /**
-   * Return the value of the data represented by the given [descriptor], or
-   * `null` if the data represented by the descriptor is not valid.
-   */
-  /*<V>*/ dynamic /*V*/ getValue(DataDescriptor /*<V>*/ descriptor) {
-    if (!_isValidDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    CachedResult result = resultMap[descriptor];
-    if (result == null) {
-      return descriptor.defaultValue;
-    }
-    return result.value;
-  }
-
-  /**
-   * Return `true` if the state of any data value is [CacheState.ERROR].
-   */
-  bool hasErrorState() {
-    for (CachedResult result in resultMap.values) {
-      if (result.state == CacheState.ERROR) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Invalidate all of the information associated with this source.
-   */
-  void invalidateAllInformation() {
-    setState(CONTENT, CacheState.INVALID);
-    setState(CONTENT_ERRORS, CacheState.INVALID);
-    setState(LINE_INFO, CacheState.INVALID);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to get the contents of
-   * the source represented by this entry. This will set the state of all
-   * information, including any resolution-based information, as being in error.
-   */
-  void recordContentError(CaughtException exception) {
-    setState(CONTENT, CacheState.ERROR);
-    recordScanError(exception);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to scan or parse the
-   * entry represented by this entry. This will set the state of all
-   * information, including any resolution-based information, as being in error.
-   */
-  void recordScanError(CaughtException exception) {
-    this.exception = exception;
-    setState(LINE_INFO, CacheState.ERROR);
-  }
-
-  /**
-   * Set the state of the data represented by the given [descriptor] to the
-   * given [state].
-   */
-  void setState(DataDescriptor descriptor, CacheState state) {
-    if (!_isValidDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    if (state == CacheState.VALID) {
-      throw new ArgumentError("use setValue() to set the state to VALID");
-    }
-    _validateStateChange(descriptor, state);
-    if (state == CacheState.INVALID) {
-      resultMap.remove(descriptor);
-    } else {
-      CachedResult result =
-          resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
-      result.state = state;
-      if (state != CacheState.IN_PROCESS) {
-        //
-        // If the state is in-process, we can leave the current value in the
-        // cache for any 'get' methods to access.
-        //
-        result.value = descriptor.defaultValue;
-      }
-    }
-  }
-
-  /**
-   * Set the value of the data represented by the given [descriptor] to the
-   * given [value].
-   */
-  void setValue(DataDescriptor /*<V>*/ descriptor, dynamic /*V*/ value) {
-    if (!_isValidDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    _validateStateChange(descriptor, CacheState.VALID);
-    CachedResult result =
-        resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
-    countTransition(descriptor, result);
-    result.state = CacheState.VALID;
-    result.value = value == null ? descriptor.defaultValue : value;
-  }
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    _writeOn(buffer);
-    return buffer.toString();
-  }
-
-  /**
-   * Flush the value of the data described by the [descriptor].
-   */
-  void _flush(DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    if (result != null && result.state == CacheState.VALID) {
-      _validateStateChange(descriptor, CacheState.FLUSHED);
-      result.state = CacheState.FLUSHED;
-      result.value = descriptor.defaultValue;
-    }
-  }
-
-  /**
-   * Return the value of the flag with the given [index].
-   */
-  bool _getFlag(int index) => BooleanArray.get(_flags, index);
-
-  /**
-   * Return `true` if the [descriptor] is valid for this entry.
-   */
-  bool _isValidDescriptor(DataDescriptor descriptor) {
-    return descriptor == CONTENT ||
-        descriptor == CONTENT_ERRORS ||
-        descriptor == LINE_INFO;
-  }
-
-  /**
-   * Set the value of the flag with the given [index] to the given [value].
-   */
-  void _setFlag(int index, bool value) {
-    _flags = BooleanArray.set(_flags, index, value);
-  }
-
-  /**
-   * If the state of the value described by the given [descriptor] is changing
-   * from ERROR to anything else, capture the information. This is an attempt to
-   * discover the underlying cause of a long-standing bug.
-   */
-  void _validateStateChange(DataDescriptor descriptor, CacheState newState) {
-    // TODO(brianwilkerson) Decide whether we still want to capture this data.
-//    if (descriptor != CONTENT) {
-//      return;
-//    }
-//    CachedResult result = resultMap[CONTENT];
-//    if (result != null && result.state == CacheState.ERROR) {
-//      String message =
-//          "contentState changing from ${result.state} to $newState";
-//      InstrumentationBuilder builder =
-//          Instrumentation.builder2("SourceEntry-validateStateChange");
-//      builder.data3("message", message);
-//      //builder.data("source", source.getFullName());
-//      builder.record(new CaughtException(new AnalysisException(message), null));
-//      builder.log();
-//    }
-  }
-
-  /**
-   * Write a textual representation of the difference between the [oldEntry] and
-   * this entry to the given string [buffer]. Return `true` if some difference
-   * was written.
-   */
-  bool _writeDiffOn(StringBuffer buffer, SourceEntry oldEntry) {
-    bool needsSeparator = false;
-    CaughtException oldException = oldEntry.exception;
-    if (!identical(oldException, exception)) {
-      buffer.write("exception = ");
-      buffer.write(oldException.runtimeType);
-      buffer.write(" -> ");
-      buffer.write(exception.runtimeType);
-      needsSeparator = true;
-    }
-    int oldModificationTime = oldEntry.modificationTime;
-    if (oldModificationTime != modificationTime) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("time = ");
-      buffer.write(oldModificationTime);
-      buffer.write(" -> ");
-      buffer.write(modificationTime);
-      needsSeparator = true;
-    }
-    needsSeparator =
-        _writeStateDiffOn(buffer, needsSeparator, "content", CONTENT, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "contentErrors", CONTENT_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "lineInfo", LINE_INFO, oldEntry);
-    return needsSeparator;
-  }
-
-  /**
-   * Write a textual representation of this entry to the given [buffer]. The
-   * result should only be used for debugging purposes.
-   */
-  void _writeOn(StringBuffer buffer) {
-    buffer.write("time = ");
-    buffer.write(modificationTime);
-    _writeStateOn(buffer, "content", CONTENT);
-    _writeStateOn(buffer, "contentErrors", CONTENT_ERRORS);
-    _writeStateOn(buffer, "lineInfo", LINE_INFO);
-  }
-
-  /**
-   * Write a textual representation of the difference between the state of the
-   * value described by the given [descriptor] between the [oldEntry] and this
-   * entry to the given [buffer]. Return `true` if some difference was written.
-   */
-  bool _writeStateDiffOn(StringBuffer buffer, bool needsSeparator, String label,
-      DataDescriptor descriptor, SourceEntry oldEntry) {
-    CacheState oldState = oldEntry.getState(descriptor);
-    CacheState newState = getState(descriptor);
-    if (oldState != newState) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write(label);
-      buffer.write(" = ");
-      buffer.write(oldState);
-      buffer.write(" -> ");
-      buffer.write(newState);
-      return true;
-    }
-    return needsSeparator;
-  }
-
-  /**
-   * Write a textual representation of the state of the value described by the
-   * given [descriptor] to the given bugger, prefixed by the given [label] to
-   * the given [buffer].
-   */
-  void _writeStateOn(
-      StringBuffer buffer, String label, DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    buffer.write("; ");
-    buffer.write(label);
-    buffer.write(" = ");
-    buffer.write(result == null ? CacheState.INVALID : result.state);
-  }
-
-  /**
-   * Increment the count of the number of times that data represented by the
-   * given [descriptor] was transitioned from the current state (as found in the
-   * given [result] to a valid state.
-   */
-  static void countTransition(DataDescriptor descriptor, CachedResult result) {
-    Map<CacheState, int> countMap = transitionMap.putIfAbsent(
-        descriptor, () => new HashMap<CacheState, int>());
-    int count = countMap[result.state];
-    countMap[result.state] = count == null ? 1 : count + 1;
-  }
-}
-
-/**
- * The priority levels used to return sources in an optimal order. A smaller
- * ordinal value equates to a higher priority.
- */
-class SourcePriority extends Enum<SourcePriority> {
-  /**
-   * Used for a Dart source that is known to be a part contained in a library
-   * that was recently resolved. These parts are given a higher priority because
-   * there is a high probability that their AST structure is still in the cache
-   * and therefore would not need to be re-created.
-   */
-  static const SourcePriority PRIORITY_PART =
-      const SourcePriority('PRIORITY_PART', 0);
-
-  /**
-   * Used for a Dart source that is known to be a library.
-   */
-  static const SourcePriority LIBRARY = const SourcePriority('LIBRARY', 1);
-
-  /**
-   * Used for a Dart source whose kind is unknown.
-   */
-  static const SourcePriority UNKNOWN = const SourcePriority('UNKNOWN', 2);
-
-  /**
-   * Used for a Dart source that is known to be a part but whose library has not
-   * yet been resolved.
-   */
-  static const SourcePriority NORMAL_PART =
-      const SourcePriority('NORMAL_PART', 3);
-
-  /**
-   * Used for an HTML source.
-   */
-  static const SourcePriority HTML = const SourcePriority('HTML', 4);
-
-  static const List<SourcePriority> values = const [
-    PRIORITY_PART,
-    LIBRARY,
-    UNKNOWN,
-    NORMAL_PART,
-    HTML
-  ];
-
-  const SourcePriority(String name, int ordinal) : super(name, ordinal);
-}
-
-/**
  * [SourcesChangedEvent] indicates which sources have been added, removed,
  * or whose contents have changed.
  */
@@ -11817,8 +2407,8 @@
    */
   bool get wereSourcesRemovedOrDeleted =>
       _changeSet.removedSources.length > 0 ||
-          _changeSet.removedContainers.length > 0 ||
-          _changeSet.deletedSources.length > 0;
+      _changeSet.removedContainers.length > 0 ||
+      _changeSet.deletedSources.length > 0;
 }
 
 /**
@@ -11841,280 +2431,3 @@
    */
   TimestampedData(this.modificationTime, this.data);
 }
-
-/**
- * A cache partition that contains all sources not contained in other
- * partitions.
- */
-class UniversalCachePartition extends CachePartition {
-  /**
-   * Initialize a newly created partition. The [context] is the context that
-   * owns this partition. The [maxCacheSize] is the maximum number of sources
-   * for which AST structures should be kept in the cache. The [retentionPolicy]
-   * is the policy used to determine which pieces of data to remove from the
-   * cache.
-   */
-  UniversalCachePartition(InternalAnalysisContext context, int maxCacheSize,
-      CacheRetentionPolicy retentionPolicy)
-      : super(context, maxCacheSize, retentionPolicy);
-
-  @override
-  bool contains(Source source) => true;
-}
-
-/**
- * The unique instances of the class `WaitForAsyncTask` represents a state in which there is
- * no analysis work that can be done until some asynchronous task (such as IO) has completed, but
- * where analysis is not yet complete.
- */
-class WaitForAsyncTask extends AnalysisTask {
-  /**
-   * The unique instance of this class.
-   */
-  static WaitForAsyncTask _UniqueInstance = new WaitForAsyncTask();
-
-  /**
-   * Return the unique instance of this class.
-   *
-   * @return the unique instance of this class
-   */
-  static WaitForAsyncTask get instance => _UniqueInstance;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  WaitForAsyncTask() : super(null);
-
-  @override
-  String get taskDescription => "Waiting for async analysis";
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => null;
-
-  @override
-  void internalPerform() {
-    // There is no work to be done.
-  }
-}
-
-/**
- * An object that manages a list of sources that need to have analysis work
- * performed on them.
- */
-class WorkManager {
-  /**
-   * A list containing the various queues is priority order.
-   */
-  List<List<Source>> _workQueues;
-
-  /**
-   * Initialize a newly created manager to have no work queued up.
-   */
-  WorkManager() {
-    int queueCount = SourcePriority.values.length;
-    _workQueues = new List<List<Source>>(queueCount);
-    for (int i = 0; i < queueCount; i++) {
-      _workQueues[i] = new List<Source>();
-    }
-  }
-
-  /**
-   * Record that the given [source] needs to be analyzed. The [priority] level
-   * is used to control when the source will be analyzed with respect to other
-   * sources. If the source was previously added then it's priority is updated.
-   * If it was previously added with the same priority then it's position in the
-   * queue is unchanged.
-   */
-  void add(Source source, SourcePriority priority) {
-    int queueCount = _workQueues.length;
-    int ordinal = priority.ordinal;
-    for (int i = 0; i < queueCount; i++) {
-      List<Source> queue = _workQueues[i];
-      if (i == ordinal) {
-        if (!queue.contains(source)) {
-          queue.add(source);
-        }
-      } else {
-        queue.remove(source);
-      }
-    }
-  }
-
-  /**
-   * Record that the given [source] needs to be analyzed. The [priority] level
-   * is used to control when the source will be analyzed with respect to other
-   * sources. If the source was previously added then it's priority is updated.
-   * In either case, it will be analyzed before other sources of the same
-   * priority.
-   */
-  void addFirst(Source source, SourcePriority priority) {
-    int queueCount = _workQueues.length;
-    int ordinal = priority.ordinal;
-    for (int i = 0; i < queueCount; i++) {
-      List<Source> queue = _workQueues[i];
-      if (i == ordinal) {
-        queue.remove(source);
-        queue.insert(0, source);
-      } else {
-        queue.remove(source);
-      }
-    }
-  }
-
-  /**
-   * Return an iterator that can be used to access the sources to be analyzed in
-   * the order in which they should be analyzed.
-   *
-   * <b>Note:</b> As with other iterators, no sources can be added or removed
-   * from this work manager while the iterator is being used. Unlike some
-   * implementations, however, the iterator will not detect when this
-   * requirement has been violated; it might work correctly, it might return the
-   * wrong source, or it might throw an exception.
-   */
-  WorkManager_WorkIterator iterator() => new WorkManager_WorkIterator(this);
-
-  /**
-   * Record that the given source is fully analyzed.
-   */
-  void remove(Source source) {
-    int queueCount = _workQueues.length;
-    for (int i = 0; i < queueCount; i++) {
-      _workQueues[i].remove(source);
-    }
-  }
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    List<SourcePriority> priorities = SourcePriority.values;
-    bool needsSeparator = false;
-    int queueCount = _workQueues.length;
-    for (int i = 0; i < queueCount; i++) {
-      List<Source> queue = _workQueues[i];
-      if (!queue.isEmpty) {
-        if (needsSeparator) {
-          buffer.write("; ");
-        }
-        buffer.write(priorities[i]);
-        buffer.write(": ");
-        int queueSize = queue.length;
-        for (int j = 0; j < queueSize; j++) {
-          if (j > 0) {
-            buffer.write(", ");
-          }
-          buffer.write(queue[j].fullName);
-        }
-        needsSeparator = true;
-      }
-    }
-    return buffer.toString();
-  }
-}
-
-/**
- * An iterator that returns the sources in a work manager in the order in which
- * they are to be analyzed.
- */
-class WorkManager_WorkIterator {
-  final WorkManager _manager;
-
-  /**
-   * The index of the work queue through which we are currently iterating.
-   */
-  int _queueIndex = 0;
-
-  /**
-   * The index of the next element of the work queue to be returned.
-   */
-  int _index = -1;
-
-  /**
-   * Initialize a newly created iterator to be ready to return the first element
-   * in the iteration.
-   */
-  WorkManager_WorkIterator(this._manager) {
-    _advance();
-  }
-
-  /**
-   * Return `true` if there is another [Source] available for processing.
-   */
-  bool get hasNext => _queueIndex < _manager._workQueues.length;
-
-  /**
-   * Return the next [Source] available for processing and advance so that the
-   * returned source will not be returned again.
-   */
-  Source next() {
-    if (!hasNext) {
-      throw new NoSuchElementException();
-    }
-    Source source = _manager._workQueues[_queueIndex][_index];
-    _advance();
-    return source;
-  }
-
-  /**
-   * Increment the [index] and [queueIndex] so that they are either indicating
-   * the next source to be returned or are indicating that there are no more
-   * sources to be returned.
-   */
-  void _advance() {
-    _index++;
-    if (_index >= _manager._workQueues[_queueIndex].length) {
-      _index = 0;
-      _queueIndex++;
-      while (_queueIndex < _manager._workQueues.length &&
-          _manager._workQueues[_queueIndex].isEmpty) {
-        _queueIndex++;
-      }
-    }
-  }
-}
-
-/**
- * A helper class used to create futures for AnalysisContextImpl. Using a helper
- * class allows us to preserve the generic parameter T.
- */
-class _AnalysisFutureHelper<T> {
-  final AnalysisContextImpl _context;
-
-  _AnalysisFutureHelper(this._context);
-
-  /**
-   * Return a future that will be completed with the result of calling
-   * [computeValue].  If [computeValue] returns non-null, the future will be
-   * completed immediately with the resulting value.  If it returns null, then
-   * it will be re-executed in the future, after the next time the cached
-   * information for [source] has changed.  If [computeValue] throws an
-   * exception, the future will fail with that exception.
-   *
-   * If the [computeValue] still returns null after there is no further
-   * analysis to be done for [source], then the future will be completed with
-   * the error AnalysisNotScheduledError.
-   *
-   * Since [computeValue] will be called while the state of analysis is being
-   * updated, it should be free of side effects so that it doesn't cause
-   * reentrant changes to the analysis state.
-   */
-  CancelableFuture<T> computeAsync(
-      Source source, T computeValue(SourceEntry sourceEntry)) {
-    if (_context.isDisposed) {
-      // No further analysis is expected, so return a future that completes
-      // immediately with AnalysisNotScheduledError.
-      return new CancelableFuture.error(new AnalysisNotScheduledError());
-    }
-    SourceEntry sourceEntry = _context.getReadableSourceEntryOrNull(source);
-    if (sourceEntry == null) {
-      return new CancelableFuture.error(new AnalysisNotScheduledError());
-    }
-    PendingFuture pendingFuture =
-        new PendingFuture<T>(_context, source, computeValue);
-    if (!pendingFuture.evaluate(sourceEntry)) {
-      _context._pendingFutureSources
-          .putIfAbsent(source, () => <PendingFuture>[])
-          .add(pendingFuture);
-    }
-    return pendingFuture.future;
-  }
-}
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index af45572..aa43a7e 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -2,17 +2,29 @@
 // for 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 engine.error;
+library analyzer.src.generated.error;
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/generated/ast.dart' show AstNode;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
+import 'package:analyzer/src/generated/scanner.dart'
+    show ScannerErrorCode, Token;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/model.dart';
+import 'package:analyzer/task/model.dart';
 import 'package:source_span/source_span.dart';
 
-import 'ast.dart' show AstNode;
-import 'element.dart';
-import 'java_core.dart';
-import 'scanner.dart' show Token;
-import 'source.dart';
+/**
+ * The descriptor used to associate error processors with analysis contexts in
+ * configuration data.
+ */
+final ListResultDescriptor<List<ErrorProcessor>> CONFIGURED_ERROR_PROCESSORS =
+    new ListResultDescriptorImpl('configured.errors', const <ErrorProcessor>[]);
 
 /**
  * An error discovered during the analysis of some Dart code.
@@ -29,9 +41,9 @@
    * A [Comparator] that sorts by the name of the file that the [AnalysisError]
    * was found.
    */
-  static Comparator<AnalysisError> FILE_COMPARATOR = (AnalysisError o1,
-          AnalysisError o2) =>
-      o1.source.shortName.compareTo(o2.source.shortName);
+  static Comparator<AnalysisError> FILE_COMPARATOR =
+      (AnalysisError o1, AnalysisError o2) =>
+          o1.source.shortName.compareTo(o2.source.shortName);
 
   /**
    * A [Comparator] that sorts error codes first by their severity (errors
@@ -107,27 +119,6 @@
   }
 
   /**
-   * Initialize a newly created analysis error for the specified [source]. The
-   * error will have the given [errorCode] and the list of [arguments] will be
-   * used to complete the message. The error has no location information.
-   */
-  @deprecated // Use new AnalysisError(source, 0, 0, errorCode, arguments)
-  AnalysisError.con1(Source source, ErrorCode errorCode,
-      [List<Object> arguments])
-      : this(source, 0, 0, errorCode, arguments);
-
-  /**
-   * Initialize a newly created analysis error for the specified [source] at the
-   * given [offset] with the given [length]. The error will have the given
-   * [errorCode] and the list of [arguments] will be used to complete the
-   * message.
-   */
-  @deprecated // Use new AnalysisError(source, offset, length, errorCode, arguments)
-  AnalysisError.con2(Source source, int offset, int length, ErrorCode errorCode,
-      [List<Object> arguments])
-      : this(source, offset, length, errorCode, arguments);
-
-  /**
    * Return the template used to create the correction to be displayed for this
    * error, or `null` if there is no correction information for this error. The
    * correction should indicate how the user can fix the error.
@@ -261,28 +252,6 @@
       [List<Object> arguments])
       : super(source, offset, length, errorCode, arguments);
 
-  /**
-   * Initialize a newly created analysis error for the specified [source]. The
-   * error will have the given [errorCode] and the list of [arguments] will be
-   * used to complete the message. The error has no location information.
-   */
-  @deprecated // Use new AnalysisErrorWithProperties(source, 0, 0, errorCode, arguments)
-  AnalysisErrorWithProperties.con1(Source source, ErrorCode errorCode,
-      [List<Object> arguments])
-      : this(source, 0, 0, errorCode, arguments);
-
-  /**
-   * Initialize a newly created analysis error for the specified [source] at the
-   * given [offset] with the given [length]. The error will have the given
-   * [errorCode] and the list of [arguments] will be used to complete the
-   * message.
-   */
-  @deprecated // Use new AnalysisErrorWithProperties(source, offset, length, errorCode, arguments)
-  AnalysisErrorWithProperties.con2(
-      Source source, int offset, int length, ErrorCode errorCode,
-      [List<Object> arguments])
-      : this(source, offset, length, errorCode, arguments);
-
   @override
   Object getProperty(ErrorProperty property) => _propertyMap[property];
 
@@ -334,15 +303,53 @@
 class AnalysisOptionsWarningCode extends ErrorCode {
   /**
    * An error code indicating that a plugin is being configured with an
-   * unsupported option.
+   * unsupported option and legal options are provided.
    *
    * Parameters:
    * 0: the plugin name
    * 1: the unsupported option key
+   * 2: legal values
    */
-  static const AnalysisOptionsWarningCode UNSUPPORTED_OPTION =
-      const AnalysisOptionsWarningCode('UNSUPPORTED_OPTION_ERROR',
-          "The option '{1}' is not supported by {0}");
+  static const AnalysisOptionsWarningCode UNSUPPORTED_OPTION_WITH_LEGAL_VALUES =
+      const AnalysisOptionsWarningCode('UNSUPPORTED_OPTION_WITH_LEGAL_VALUES',
+          "The option '{1}' is not supported by {0}, supported values are {2}");
+
+  /**
+   * An error code indicating that a plugin is being configured with an
+   * unsupported option where there is just one legal value.
+   *
+   * Parameters:
+   * 0: the plugin name
+   * 1: the unsupported option key
+   * 2: the legal value
+   */
+  static const AnalysisOptionsWarningCode UNSUPPORTED_OPTION_WITH_LEGAL_VALUE =
+      const AnalysisOptionsWarningCode('UNSUPPORTED_OPTION_WITH_LEGAL_VALUE',
+          "The option '{1}' is not supported by {0}, did you mean {2}?");
+
+  /**
+   * An error code indicating that an option entry is being configured with an
+   * unsupported value.
+   *
+   * Parameters:
+   * 0: the option name
+   * 1: the unsupported value
+   * 2: legal values
+   */
+  static const AnalysisOptionsWarningCode UNSUPPORTED_VALUE =
+      const AnalysisOptionsWarningCode('UNSUPPORTED_VALUE',
+          "The value '{1}' is not supported by {0}, legal values are {2}");
+
+  /**
+   * An error code indicating that an unrecognized error code is being used to
+   * specify an error filter.
+   *
+   * Parameters:
+   * 0: the unrecognized error code
+   */
+  static const AnalysisOptionsWarningCode UNRECOGNIZED_ERROR_CODE =
+      const AnalysisOptionsWarningCode(
+          'UNRECOGNIZED_ERROR_CODE', "'{0}' is not a recognized error code");
 
   /**
    * Initialize a newly created warning code to have the given [name].
@@ -399,7 +406,8 @@
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant
    * object results in an uncaught exception being thrown.
    */
-  static const CheckedModeCompileTimeErrorCode CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH =
+  static const CheckedModeCompileTimeErrorCode
+      CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH =
       const CheckedModeCompileTimeErrorCode(
           'CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH',
           "The object type '{0}' cannot be assigned to the field '{1}', which has type '{2}'");
@@ -408,7 +416,8 @@
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant
    * object results in an uncaught exception being thrown.
    */
-  static const CheckedModeCompileTimeErrorCode CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH =
+  static const CheckedModeCompileTimeErrorCode
+      CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH =
       const CheckedModeCompileTimeErrorCode(
           'CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH',
           "The object type '{0}' cannot be assigned to a parameter of type '{1}'");
@@ -425,7 +434,8 @@
    * 0: the name of the type of the initializer expression
    * 1: the name of the type of the field
    */
-  static const CheckedModeCompileTimeErrorCode CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE =
+  static const CheckedModeCompileTimeErrorCode
+      CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE =
       const CheckedModeCompileTimeErrorCode(
           'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
           "The initializer type '{0}' cannot be assigned to the field type '{1}'");
@@ -443,8 +453,9 @@
    * warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>,
    * 1 &lt;= j &lt;= m</i>.
    */
-  static const CheckedModeCompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE =
-      const CheckedModeCompileTimeErrorCode('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE',
+  static const CheckedModeCompileTimeErrorCode
+      LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = const CheckedModeCompileTimeErrorCode(
+          'LIST_ELEMENT_TYPE_NOT_ASSIGNABLE',
           "The element type '{0}' cannot be assigned to the list type '{1}'");
 
   /**
@@ -542,6 +553,26 @@
           "The name '{0}' is defined in the libraries '{1}' and '{2}'");
 
   /**
+   * 15 Metadata: The constant expression given in an annotation is type checked
+   * and evaluated in the scope surrounding the declaration being annotated.
+   *
+   * 12.11.2 Const: It is a compile-time error if <i>T</i> is not a class
+   * accessible in the current scope, optionally followed by type arguments.
+   *
+   * 12.11.2 Const: If <i>e</i> is of the form <i>const T.id(a<sub>1</sub>,
+   * &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, &hellip;
+   * x<sub>n+k</sub>: a<sub>n+k</sub>)</i> it is a compile-time error if
+   * <i>T</i> is not a class accessible in the current scope, optionally
+   * followed by type arguments.
+   *
+   * Parameters:
+   * 0: the name of the non-type element
+   */
+  static const CompileTimeErrorCode ANNOTATION_WITH_NON_CLASS =
+      const CompileTimeErrorCode(
+          'ANNOTATION_WITH_NON_CLASS', "The name '{0}' is not a class");
+
+  /**
    * 12.33 Argument Definition Test: It is a compile time error if <i>v</i> does
    * not denote a formal parameter.
    *
@@ -691,7 +722,8 @@
    * constructor is declared by a class C if any instance variable declared in C
    * is initialized with an expression that is not a constant expression.
    */
-  static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST =
+  static const CompileTimeErrorCode
+      CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST =
       const CompileTimeErrorCode(
           'CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST',
           "Can't define the 'const' constructor because the field '{0}' is initialized with a non-constant value");
@@ -759,7 +791,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used to initialized a 'const' variable");
@@ -777,7 +810,8 @@
    * map literal is an instance of a class that implements the operator
    * <i>==</i> unless the key is a string or integer.
    */
-  static const CompileTimeErrorCode CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS =
+  static const CompileTimeErrorCode
+      CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS =
       const CompileTimeErrorCode(
           'CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS',
           "The constant map entry key expression type '{0}' cannot override the == operator");
@@ -953,7 +987,8 @@
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> explicitly
    * specifies a default value for an optional parameter.
    */
-  static const CompileTimeErrorCode DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR =
+  static const CompileTimeErrorCode
+      DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR =
       const CompileTimeErrorCode(
           'DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR',
           "Default values aren't allowed in factory constructors that redirect to another constructor");
@@ -1103,6 +1138,15 @@
           "This class cannot extend the deferred class '{0}'");
 
   /**
+   * DEP 37 extends the syntax for assert() to allow a second "message"
+   * argument.  We issue this error if the user tries to supply a "message"
+   * argument but the DEP is not enabled.
+   */
+  static const CompileTimeErrorCode EXTRA_ARGUMENT_TO_ASSERT =
+      const CompileTimeErrorCode('EXTRA_ARGUMENT_TO_ASSERT',
+          "Assertions only accept a single argument");
+
+  /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
    * h</i> or if <i>m &gt; n</i>.
    *
@@ -1132,7 +1176,8 @@
    * initializer for a variable that is initialized by means of an initializing
    * formal of <i>k</i>.
    */
-  static const CompileTimeErrorCode FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER =
+  static const CompileTimeErrorCode
+      FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER =
       const CompileTimeErrorCode(
           'FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER',
           "Fields cannot be initialized in both the parameter list and the initializers");
@@ -1742,8 +1787,9 @@
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting,
    * in which case its only action is to invoke another generative constructor.
    */
-  static const CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS =
-      const CompileTimeErrorCode('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS',
+  static const CompileTimeErrorCode
+      MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = const CompileTimeErrorCode(
+          'MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS',
           "Constructor may have at most one 'this' redirection");
 
   /**
@@ -1830,7 +1876,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as a case expression");
@@ -1850,7 +1897,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as a default parameter value");
@@ -1870,7 +1918,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as values in a 'const' list");
@@ -1909,8 +1958,9 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY =
-      const CompileTimeErrorCode('NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY',
+  static const CompileTimeErrorCode
+      NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY = const CompileTimeErrorCode(
+          'NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as values in a 'const' map");
 
   /**
@@ -1943,7 +1993,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as constant initializers");
@@ -2086,7 +2137,8 @@
    * Parameters:
    * 0: the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS =
+  static const CompileTimeErrorCode
+      RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS =
       const CompileTimeErrorCode(
           'RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS',
           "'{0}' cannot extend itself");
@@ -2104,7 +2156,8 @@
    * Parameters:
    * 0: the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS =
+  static const CompileTimeErrorCode
+      RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS =
       const CompileTimeErrorCode(
           'RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS',
           "'{0}' cannot implement itself");
@@ -2122,7 +2175,8 @@
    * Parameters:
    * 0: the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH =
+  static const CompileTimeErrorCode
+      RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH =
       const CompileTimeErrorCode(
           'RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH',
           "'{0}' cannot use itself as a mixin");
@@ -2165,7 +2219,8 @@
    * <i>redirecting</i>, in which case its only action is to invoke another
    * generative constructor.
    */
-  static const CompileTimeErrorCode REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR =
+  static const CompileTimeErrorCode
+      REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR =
       const CompileTimeErrorCode(
           'REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR',
           "Generative constructor cannot redirect to a factory constructor");
@@ -2296,8 +2351,9 @@
    * class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT =
-      const CompileTimeErrorCode('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
+  static const CompileTimeErrorCode
+      UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = const CompileTimeErrorCode(
+          'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
           "The class '{0}' does not have a default generative constructor");
 
   /**
@@ -2375,7 +2431,8 @@
    * Parameters:
    * 0: the number of parameters found in the operator declaration
    */
-  static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS =
+  static const CompileTimeErrorCode
+      WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS =
       const CompileTimeErrorCode(
           'WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS',
           "Operator '-' should declare 0 or 1 parameter, but {0} found");
@@ -2421,62 +2478,6 @@
 }
 
 /**
- * An error listener that can be enabled or disabled while executing a function.
- */
-class DisablableErrorListener implements AnalysisErrorListener {
-  /**
-   * The listener to which errors will be reported if this listener is enabled.
-   */
-  final AnalysisErrorListener baseListener;
-
-  /**
-   * A flag indicating whether this listener is currently enabled.
-   */
-  bool enabled = true;
-
-  /**
-   * Initialize a newly created listener to report errors to the given
-   * [baseListener].
-   */
-  DisablableErrorListener(this.baseListener);
-
-  /**
-   * Disable the processing of errors while evaluating the given [function].
-   * Return the value returned by the function.
-   */
-  dynamic disableWhile(dynamic function()) {
-    bool wasEnabled = enabled;
-    try {
-      enabled = false;
-      return function();
-    } finally {
-      enabled = wasEnabled;
-    }
-  }
-
-  /**
-   * Disable the processing of errors while evaluating the given [function].
-   * Return the value returned by the function.
-   */
-  dynamic enableWhile(dynamic function()) {
-    bool wasEnabled = enabled;
-    try {
-      enabled = true;
-      return function();
-    } finally {
-      enabled = wasEnabled;
-    }
-  }
-
-  @override
-  void onError(AnalysisError error) {
-    if (enabled) {
-      baseListener.onError(error);
-    }
-  }
-}
-
-/**
  * An error code associated with an [AnalysisError].
  *
  * Generally, we want to provide messages that consist of three sentences. From
@@ -2489,6 +2490,539 @@
  */
 abstract class ErrorCode {
   /**
+   * Engine error code values.
+   */
+  static const List<ErrorCode> values = const [
+    //
+    // Manually generated.  FWIW, this get's you most of the way there:
+    //
+    // > grep 'static const .*Code' (error.dart|parser|scanner.dart)
+    //     | awk '{print $3"."$4","}'
+    //
+    // error.dart:
+    //
+    AnalysisOptionsErrorCode.PARSE_ERROR,
+    AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE,
+    AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
+    CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+    CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+    CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+    CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+    CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+    CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+    CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
+    CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
+    CompileTimeErrorCode.AMBIGUOUS_EXPORT,
+    CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS,
+    CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER,
+    CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT,
+    CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT,
+    CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE,
+    CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME,
+    CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME,
+    CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME,
+    CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
+    CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION,
+    CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD,
+    CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER,
+    CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD,
+    CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD,
+    CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS,
+    CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
+    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
+    CompileTimeErrorCode.CONST_DEFERRED_CLASS,
+    CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
+    CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
+    CompileTimeErrorCode
+        .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.CONST_INSTANCE_FIELD,
+    CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
+    CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+    CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
+    CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING,
+    CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
+    CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
+    CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+    CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE,
+    CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS,
+    CompileTimeErrorCode.CONST_WITH_NON_CONST,
+    CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT,
+    CompileTimeErrorCode.CONST_WITH_NON_TYPE,
+    CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
+    CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR,
+    CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
+    CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
+    CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
+    CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
+    CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
+    CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
+    CompileTimeErrorCode.DUPLICATE_DEFINITION,
+    CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE,
+    CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT,
+    CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY,
+    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+    CompileTimeErrorCode.EXTENDS_ENUM,
+    CompileTimeErrorCode.EXTENDS_NON_CLASS,
+    CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
+    CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS,
+    CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS,
+    CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
+    CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
+    CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES,
+    CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
+    CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
+    CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
+    CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
+    CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS,
+    CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
+    CompileTimeErrorCode.IMPLEMENTS_DYNAMIC,
+    CompileTimeErrorCode.IMPLEMENTS_ENUM,
+    CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
+    CompileTimeErrorCode.IMPLEMENTS_REPEATED,
+    CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
+    CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
+    CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
+    CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
+    CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
+    CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
+    CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
+    CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
+    CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
+    CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY,
+    CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC,
+    CompileTimeErrorCode.INSTANTIATE_ENUM,
+    CompileTimeErrorCode.INVALID_ANNOTATION,
+    CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.INVALID_IDENTIFIER_IN_ASYNC,
+    CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR,
+    CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
+    CompileTimeErrorCode.INVALID_CONSTANT,
+    CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME,
+    CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS,
+    CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS,
+    CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST,
+    CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP,
+    CompileTimeErrorCode.INVALID_URI,
+    CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
+    CompileTimeErrorCode.LABEL_UNDEFINED,
+    CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME,
+    CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
+    CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL,
+    CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL,
+    CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
+    CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
+    CompileTimeErrorCode.MIXIN_DEFERRED_CLASS,
+    CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
+    CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT,
+    CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS,
+    CompileTimeErrorCode.MIXIN_OF_ENUM,
+    CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
+    CompileTimeErrorCode.MIXIN_REFERENCES_SUPER,
+    CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS,
+    CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
+    CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS,
+    CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS,
+    CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
+    CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
+    CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
+    CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION,
+    CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE,
+    CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT,
+    CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_MAP_KEY,
+    CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE,
+    CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR,
+    CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
+    CompileTimeErrorCode
+        .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
+    CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
+    CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS,
+    CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR,
+    CompileTimeErrorCode.PART_OF_NON_PART,
+    CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER,
+    CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+    CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER,
+    CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+    CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT,
+    CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+    CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+    CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS,
+    CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS,
+    CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH,
+    CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR,
+    CompileTimeErrorCode.REDIRECT_TO_NON_CLASS,
+    CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR,
+    CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
+    CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
+    CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION,
+    CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH,
+    CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR,
+    CompileTimeErrorCode.RETURN_IN_GENERATOR,
+    CompileTimeErrorCode.SHARED_DEFERRED_PREFIX,
+    CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT,
+    CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
+    CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
+    CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+    CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+    CompileTimeErrorCode.UNDEFINED_CLASS,
+    CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER,
+    CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
+    CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER,
+    CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+    CompileTimeErrorCode.URI_WITH_INTERPOLATION,
+    CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR,
+    CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS,
+    CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
+    CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR,
+    CompileTimeErrorCode.YIELD_IN_NON_GENERATOR,
+    HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+    HintCode.DEAD_CODE,
+    HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
+    HintCode.DEAD_CODE_ON_CATCH_SUBTYPE,
+    HintCode.DEPRECATED_MEMBER_USE,
+    HintCode.DUPLICATE_IMPORT,
+    HintCode.DIVISION_OPTIMIZATION,
+    HintCode.IS_DOUBLE,
+    HintCode.IS_INT,
+    HintCode.IS_NOT_DOUBLE,
+    HintCode.IS_NOT_INT,
+    HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
+    HintCode.INVALID_ASSIGNMENT,
+    HintCode.MISSING_RETURN,
+    HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER,
+    HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD,
+    HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER,
+    HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
+    HintCode.TYPE_CHECK_IS_NOT_NULL,
+    HintCode.TYPE_CHECK_IS_NULL,
+    HintCode.UNDEFINED_GETTER,
+    HintCode.UNDEFINED_METHOD,
+    HintCode.UNDEFINED_OPERATOR,
+    HintCode.UNDEFINED_SETTER,
+    HintCode.UNNECESSARY_CAST,
+    HintCode.UNNECESSARY_TYPE_CHECK_FALSE,
+    HintCode.UNNECESSARY_TYPE_CHECK_TRUE,
+    HintCode.UNUSED_ELEMENT,
+    HintCode.UNUSED_FIELD,
+    HintCode.UNUSED_IMPORT,
+    HintCode.UNUSED_CATCH_CLAUSE,
+    HintCode.UNUSED_CATCH_STACK,
+    HintCode.UNUSED_LOCAL_VARIABLE,
+    HintCode.USE_OF_VOID_RESULT,
+    HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE,
+    HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE,
+    HintCode.NULL_AWARE_IN_CONDITION,
+    HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT,
+    HtmlErrorCode.PARSE_ERROR,
+    HtmlWarningCode.INVALID_URI,
+    HtmlWarningCode.URI_DOES_NOT_EXIST,
+    StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS,
+    StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS,
+    StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE,
+    StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
+    StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE,
+    StaticTypeWarningCode.INACCESSIBLE_SETTER,
+    StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
+    StaticTypeWarningCode.INVALID_ASSIGNMENT,
+    StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
+    StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
+    StaticTypeWarningCode.NON_BOOL_CONDITION,
+    StaticTypeWarningCode.NON_BOOL_EXPRESSION,
+    StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION,
+    StaticTypeWarningCode.NON_BOOL_OPERAND,
+    StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
+    StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+    StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+    StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
+    StaticTypeWarningCode.UNDEFINED_ENUM_CONSTANT,
+    StaticTypeWarningCode.UNDEFINED_FUNCTION,
+    StaticTypeWarningCode.UNDEFINED_GETTER,
+    StaticTypeWarningCode.UNDEFINED_METHOD,
+    StaticTypeWarningCode.UNDEFINED_OPERATOR,
+    StaticTypeWarningCode.UNDEFINED_SETTER,
+    StaticTypeWarningCode.UNDEFINED_SUPER_GETTER,
+    StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
+    StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
+    StaticTypeWarningCode.UNDEFINED_SUPER_SETTER,
+    StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
+    StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+    StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
+    StaticWarningCode.AMBIGUOUS_IMPORT,
+    StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+    StaticWarningCode.ASSIGNMENT_TO_CONST,
+    StaticWarningCode.ASSIGNMENT_TO_FINAL,
+    StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
+    StaticWarningCode.ASSIGNMENT_TO_FUNCTION,
+    StaticWarningCode.ASSIGNMENT_TO_METHOD,
+    StaticWarningCode.ASSIGNMENT_TO_TYPE,
+    StaticWarningCode.CASE_BLOCK_NOT_TERMINATED,
+    StaticWarningCode.CAST_TO_NON_TYPE,
+    StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER,
+    StaticWarningCode.CONFLICTING_DART_IMPORT,
+    StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER,
+    StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER,
+    StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2,
+    StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER,
+    StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER,
+    StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER,
+    StaticWarningCode.CONST_WITH_ABSTRACT_CLASS,
+    StaticWarningCode.EQUAL_KEYS_IN_MAP,
+    StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED,
+    StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS,
+    StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
+    StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
+    StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
+    StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE,
+    StaticWarningCode.FINAL_NOT_INITIALIZED,
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1,
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2,
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS,
+    StaticWarningCode.FUNCTION_WITHOUT_CALL,
+    StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED,
+    StaticWarningCode.IMPORT_OF_NON_LIBRARY,
+    StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+    StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
+    StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS,
+    StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
+    StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
+    StaticWarningCode.INVALID_OVERRIDE_NAMED,
+    StaticWarningCode.INVALID_OVERRIDE_POSITIONAL,
+    StaticWarningCode.INVALID_OVERRIDE_REQUIRED,
+    StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE,
+    StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+    StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+    StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+    StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
+    StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,
+    StaticWarningCode.MIXED_RETURN_TYPES,
+    StaticWarningCode.NEW_WITH_ABSTRACT_CLASS,
+    StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS,
+    StaticWarningCode.NEW_WITH_NON_TYPE,
+    StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR,
+    StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE,
+    StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO,
+    StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE,
+    StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR,
+    StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+    StaticWarningCode.NOT_A_TYPE,
+    StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
+    StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
+    StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE,
+    StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE,
+    StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR,
+    StaticWarningCode.REDIRECT_TO_NON_CLASS,
+    StaticWarningCode.RETURN_WITHOUT_VALUE,
+    StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
+    StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
+    StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS,
+    StaticWarningCode.TYPE_TEST_WITH_NON_TYPE,
+    StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME,
+    StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC,
+    StaticWarningCode.UNDEFINED_CLASS,
+    StaticWarningCode.UNDEFINED_CLASS_BOOLEAN,
+    StaticWarningCode.UNDEFINED_GETTER,
+    StaticWarningCode.UNDEFINED_IDENTIFIER,
+    StaticWarningCode.UNDEFINED_NAMED_PARAMETER,
+    StaticWarningCode.UNDEFINED_SETTER,
+    StaticWarningCode.UNDEFINED_STATIC_METHOD_OR_GETTER,
+    StaticWarningCode.UNDEFINED_SUPER_GETTER,
+    StaticWarningCode.UNDEFINED_SUPER_SETTER,
+    StaticWarningCode.VOID_RETURN_FOR_GETTER,
+    TodoCode.TODO,
+
+    //
+    // parser.dart:
+    //
+    ParserErrorCode.ABSTRACT_CLASS_MEMBER,
+    ParserErrorCode.ABSTRACT_ENUM,
+    ParserErrorCode.ABSTRACT_STATIC_METHOD,
+    ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION,
+    ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE,
+    ParserErrorCode.ABSTRACT_TYPEDEF,
+    ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT,
+    ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT,
+    ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE,
+    ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW,
+    ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW,
+    ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
+    ParserErrorCode.BREAK_OUTSIDE_OF_LOOP,
+    ParserErrorCode.CLASS_IN_CLASS,
+    ParserErrorCode.COLON_IN_PLACE_OF_IN,
+    ParserErrorCode.CONST_AND_FINAL,
+    ParserErrorCode.CONST_AND_VAR,
+    ParserErrorCode.CONST_CLASS,
+    ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY,
+    ParserErrorCode.CONST_ENUM,
+    ParserErrorCode.CONST_FACTORY,
+    ParserErrorCode.CONST_METHOD,
+    ParserErrorCode.CONST_TYPEDEF,
+    ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE,
+    ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP,
+    ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE,
+    ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS,
+    ParserErrorCode.DIRECTIVE_AFTER_DECLARATION,
+    ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT,
+    ParserErrorCode.DUPLICATED_MODIFIER,
+    ParserErrorCode.EMPTY_ENUM_BODY,
+    ParserErrorCode.ENUM_IN_CLASS,
+    ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND,
+    ParserErrorCode.EXPECTED_CASE_OR_DEFAULT,
+    ParserErrorCode.EXPECTED_CLASS_MEMBER,
+    ParserErrorCode.EXPECTED_EXECUTABLE,
+    ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL,
+    ParserErrorCode.EXPECTED_STRING_LITERAL,
+    ParserErrorCode.EXPECTED_TOKEN,
+    ParserErrorCode.EXPECTED_TYPE_NAME,
+    ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE,
+    ParserErrorCode.EXTERNAL_AFTER_CONST,
+    ParserErrorCode.EXTERNAL_AFTER_FACTORY,
+    ParserErrorCode.EXTERNAL_AFTER_STATIC,
+    ParserErrorCode.EXTERNAL_CLASS,
+    ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY,
+    ParserErrorCode.EXTERNAL_ENUM,
+    ParserErrorCode.EXTERNAL_FIELD,
+    ParserErrorCode.EXTERNAL_GETTER_WITH_BODY,
+    ParserErrorCode.EXTERNAL_METHOD_WITH_BODY,
+    ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY,
+    ParserErrorCode.EXTERNAL_SETTER_WITH_BODY,
+    ParserErrorCode.EXTERNAL_TYPEDEF,
+    ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION,
+    ParserErrorCode.FACTORY_WITH_INITIALIZERS,
+    ParserErrorCode.FACTORY_WITHOUT_BODY,
+    ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
+    ParserErrorCode.FINAL_AND_VAR,
+    ParserErrorCode.FINAL_CLASS,
+    ParserErrorCode.FINAL_CONSTRUCTOR,
+    ParserErrorCode.FINAL_ENUM,
+    ParserErrorCode.FINAL_METHOD,
+    ParserErrorCode.FINAL_TYPEDEF,
+    ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR,
+    ParserErrorCode.GETTER_IN_FUNCTION,
+    ParserErrorCode.GETTER_WITH_PARAMETERS,
+    ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE,
+    ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS,
+    ParserErrorCode.IMPLEMENTS_BEFORE_WITH,
+    ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE,
+    ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH,
+    ParserErrorCode.INVALID_AWAIT_IN_FOR,
+    ParserErrorCode.INVALID_CODE_POINT,
+    ParserErrorCode.INVALID_COMMENT_REFERENCE,
+    ParserErrorCode.INVALID_HEX_ESCAPE,
+    ParserErrorCode.INVALID_OPERATOR,
+    ParserErrorCode.INVALID_OPERATOR_FOR_SUPER,
+    ParserErrorCode.INVALID_STAR_AFTER_ASYNC,
+    ParserErrorCode.INVALID_SYNC,
+    ParserErrorCode.INVALID_UNICODE_ESCAPE,
+    ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST,
+    ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER,
+    ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR,
+    ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER,
+    ParserErrorCode.MISSING_CATCH_OR_FINALLY,
+    ParserErrorCode.MISSING_CLASS_BODY,
+    ParserErrorCode.MISSING_CLOSING_PARENTHESIS,
+    ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
+    ParserErrorCode.MISSING_ENUM_BODY,
+    ParserErrorCode.MISSING_EXPRESSION_IN_INITIALIZER,
+    ParserErrorCode.MISSING_EXPRESSION_IN_THROW,
+    ParserErrorCode.MISSING_FUNCTION_BODY,
+    ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+    ParserErrorCode.MISSING_METHOD_PARAMETERS,
+    ParserErrorCode.MISSING_GET,
+    ParserErrorCode.MISSING_IDENTIFIER,
+    ParserErrorCode.MISSING_INITIALIZER,
+    ParserErrorCode.MISSING_KEYWORD_OPERATOR,
+    ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE,
+    ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE,
+    ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT,
+    ParserErrorCode.MISSING_STAR_AFTER_SYNC,
+    ParserErrorCode.MISSING_STATEMENT,
+    ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP,
+    ParserErrorCode.MISSING_TYPEDEF_PARAMETERS,
+    ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH,
+    ParserErrorCode.MIXED_PARAMETER_GROUPS,
+    ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES,
+    ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES,
+    ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES,
+    ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS,
+    ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES,
+    ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS,
+    ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH,
+    ParserErrorCode.MULTIPLE_WITH_CLAUSES,
+    ParserErrorCode.NAMED_FUNCTION_EXPRESSION,
+    ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP,
+    ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE,
+    ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE,
+    ParserErrorCode.NON_CONSTRUCTOR_FACTORY,
+    ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME,
+    ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART,
+    ParserErrorCode.NON_STRING_LITERAL_AS_URI,
+    ParserErrorCode.NON_USER_DEFINABLE_OPERATOR,
+    ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS,
+    ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT,
+    ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP,
+    ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR,
+    ParserErrorCode.SETTER_IN_FUNCTION,
+    ParserErrorCode.STATIC_AFTER_CONST,
+    ParserErrorCode.STATIC_AFTER_FINAL,
+    ParserErrorCode.STATIC_AFTER_VAR,
+    ParserErrorCode.STATIC_CONSTRUCTOR,
+    ParserErrorCode.STATIC_GETTER_WITHOUT_BODY,
+    ParserErrorCode.STATIC_OPERATOR,
+    ParserErrorCode.STATIC_SETTER_WITHOUT_BODY,
+    ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION,
+    ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE,
+    ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES,
+    ParserErrorCode.TOP_LEVEL_OPERATOR,
+    ParserErrorCode.TYPEDEF_IN_CLASS,
+    ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
+    ParserErrorCode.UNEXPECTED_TOKEN,
+    ParserErrorCode.WITH_BEFORE_EXTENDS,
+    ParserErrorCode.WITH_WITHOUT_EXTENDS,
+    ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER,
+    ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER,
+    ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
+    ParserErrorCode.VAR_AND_TYPE,
+    ParserErrorCode.VAR_AS_TYPE_NAME,
+    ParserErrorCode.VAR_CLASS,
+    ParserErrorCode.VAR_ENUM,
+    ParserErrorCode.VAR_RETURN_TYPE,
+    ParserErrorCode.VAR_TYPEDEF,
+    ParserErrorCode.VOID_PARAMETER,
+    ParserErrorCode.VOID_VARIABLE,
+
+    //
+    // scanner.dart:
+    //
+    ScannerErrorCode.ILLEGAL_CHARACTER,
+    ScannerErrorCode.MISSING_DIGIT,
+    ScannerErrorCode.MISSING_HEX_DIGIT,
+    ScannerErrorCode.MISSING_QUOTE,
+    ScannerErrorCode.UNABLE_GET_CONTENT,
+    ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT,
+    ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+  ];
+
+  /**
    * An empty list of error codes.
    */
   static const List<ErrorCode> EMPTY_LIST = const <ErrorCode>[];
@@ -2916,6 +3450,15 @@
       "The argument type '{0}' cannot be assigned to the parameter type '{1}'");
 
   /**
+   * When the target expression uses '?.' operator, it can be `null`, so all the
+   * subsequent invocations should also use '?.' operator.
+   */
+  static const HintCode CAN_BE_NULL_AFTER_NULL_AWARE = const HintCode(
+      'CAN_BE_NULL_AFTER_NULL_AWARE',
+      "The expression uses '?.', so can be 'null'",
+      "Replace the '.' with a '?.' in the invocation");
+
+  /**
    * Dead code is code that is never reached, this can happen for instance if a
    * statement follows a return statement.
    */
@@ -3023,6 +3566,15 @@
       "Either add a return statement or change the return type to 'void'");
 
   /**
+   * A condition in a control flow statement could evaluate to `null` because it
+   * uses the null-aware '?.' operator.
+   */
+  static const HintCode NULL_AWARE_IN_CONDITION = const HintCode(
+      'NULL_AWARE_IN_CONDITION',
+      "The value of the '?.' operator can be 'null', which is not appropriate in a condition",
+      "Replace the '?.' with a '.', testing the left-hand side for null if necessary");
+
+  /**
    * A getter with the override annotation does not override an existing getter.
    */
   static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = const HintCode(
@@ -3124,6 +3676,12 @@
       const HintCode('UNNECESSARY_CAST', "Unnecessary cast");
 
   /**
+   * Unnecessary `noSuchMethod` declaration.
+   */
+  static const HintCode UNNECESSARY_NO_SUCH_METHOD = const HintCode(
+      'UNNECESSARY_NO_SUCH_METHOD', "Unnecessary 'noSuchMethod' declaration");
+
+  /**
    * Unnecessary type checks, the result is always true.
    */
   static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = const HintCode(
@@ -3668,6 +4226,21 @@
           "The method '{0}' is not defined for the class '{1}'");
 
   /**
+   * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>.
+   * It is a static type warning if <i>T</i> does not have an accessible
+   * instance member named <i>m</i>.
+   *
+   * Parameters:
+   * 0: the name of the method that is undefined
+   * 1: the resolved type name that the method lookup is happening on
+   */
+  static const StaticTypeWarningCode UNDEFINED_METHOD_WITH_CONSTRUCTOR =
+      const StaticTypeWarningCode(
+          'UNDEFINED_METHOD_WITH_CONSTRUCTOR',
+          "The method '{0}' is not defined for the class '{1}', but a constructor with that name is defined",
+          "Add 'new' or 'const' to invoke the constuctor, or change the method name.");
+
+  /**
    * 12.18 Assignment: Evaluation of an assignment of the form
    * <i>e<sub>1</sub></i>[<i>e<sub>2</sub></i>] = <i>e<sub>3</sub></i> is
    * equivalent to the evaluation of the expression (a, i, e){a.[]=(i, e);
@@ -3780,7 +4353,8 @@
    * when we are able to find the name defined in a supertype. It exists to
    * provide a more informative error message.
    */
-  static const StaticTypeWarningCode UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER =
+  static const StaticTypeWarningCode
+      UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER =
       const StaticTypeWarningCode(
           'UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER',
           "Static members from supertypes must be qualified by the name of the defining type");
@@ -4005,7 +4579,8 @@
    * Parameters:
    * 0: the name of the super class declaring a static member
    */
-  static const StaticWarningCode CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER =
+  static const StaticWarningCode
+      CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER =
       const StaticWarningCode(
           'CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER',
           "Superclass '{0}' declares static member with the same name");
@@ -4034,7 +4609,8 @@
    * Parameters:
    * 0: the name of the super class declaring a static member
    */
-  static const StaticWarningCode CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER =
+  static const StaticWarningCode
+      CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER =
       const StaticWarningCode(
           'CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER',
           "Superclass '{0}' declares static member with the same name");
@@ -4104,7 +4680,8 @@
    * been initialized at its point of declaration is also initialized in a
    * constructor.
    */
-  static const StaticWarningCode FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION =
+  static const StaticWarningCode
+      FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION =
       const StaticWarningCode(
           'FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION',
           "Values cannot be set in the constructor if they are final, and have already been set");
@@ -4117,7 +4694,8 @@
    * Parameters:
    * 0: the name of the field in question
    */
-  static const StaticWarningCode FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR =
+  static const StaticWarningCode
+      FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR =
       const StaticWarningCode(
           'FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR',
           "'{0}' is final and was given a value when it was declared, so it cannot be set to a new value");
@@ -4264,7 +4842,8 @@
    * getters none of the <i>m<sub>i</sub></i> are inherited, and a static
    * warning is issued.
    */
-  static const StaticWarningCode INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD =
+  static const StaticWarningCode
+      INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD =
       const StaticWarningCode(
           'INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD',
           "'{0}' is inherited as a getter and also a method");
@@ -4278,7 +4857,8 @@
    * 0: the name of the member with the name conflict
    * 1: the name of the enclosing class that has the static member
    */
-  static const StaticWarningCode INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC =
+  static const StaticWarningCode
+      INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC =
       const StaticWarningCode(
           'INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC',
           "'{0}' collides with a static member in the superclass '{1}'");
@@ -4316,6 +4896,34 @@
           "The parameter type '{0}' is not assignable to '{1}' as required by the method it is overriding from '{2}'");
 
   /**
+   * Generic Method DEP: number of type parameters must match.
+   * <https://github.com/leafpetersen/dep-generic-methods/blob/master/proposal.md#function-subtyping>
+   *
+   * Parameters:
+   * 0: the number of type parameters in the method
+   * 1: the number of type parameters in the overridden method
+   * 2: the name of the class where the overridden method is declared
+   */
+  static const StaticWarningCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS =
+      const StaticWarningCode('INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS',
+          "The method has {0} type parameters, but it is overriding a method with {1} type parameters from '{2}'");
+
+  /**
+   * Generic Method DEP: bounds of type parameters must be compatible.
+   * <https://github.com/leafpetersen/dep-generic-methods/blob/master/proposal.md#function-subtyping>
+   *
+   * Parameters:
+   * 0: the type parameter name
+   * 1: the type parameter bound
+   * 2: the overridden type parameter name
+   * 3: the overridden type parameter bound
+   * 4: the name of the class where the overridden method is declared
+   */
+  static const StaticWarningCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND =
+      const StaticWarningCode('INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND',
+          "The type parameter '{0}' extends '{1}', but that is stricter than '{2}' extends '{3}' in the overridden method from '{4}'");
+
+  /**
    * 7.1 Instance Methods: It is a static warning if an instance method
    * <i>m1</i> overrides an instance method <i>m2</i> and the type of <i>m1</i>
    * is not a subtype of the type of <i>m2</i>.
@@ -4370,8 +4978,9 @@
    * <i>p</i> and the signature of <i>m1</i> specifies a different default value
    * for <i>p</i>.
    */
-  static const StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED =
-      const StaticWarningCode('INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED',
+  static const StaticWarningCode
+      INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED = const StaticWarningCode(
+          'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED',
           "Parameters cannot override default values, this method overrides '{0}.{1}' where '{2}' has a different value");
 
   /**
@@ -4381,7 +4990,8 @@
    * <i>p</i> and the signature of <i>m1</i> specifies a different default value
    * for <i>p</i>.
    */
-  static const StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL =
+  static const StaticWarningCode
+      INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL =
       const StaticWarningCode(
           'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL',
           "Parameters cannot override default values, this method overrides '{0}.{1}' where this positional parameter has a different value");
@@ -4393,11 +5003,12 @@
    *
    * Parameters:
    * 0: the number of named parameters in the overridden member
-   * 1: the name of the class from the overridden method
+   * 1: the signature of the overridden member
+   * 2: the name of the class from the overridden method
    */
   static const StaticWarningCode INVALID_OVERRIDE_NAMED = const StaticWarningCode(
       'INVALID_OVERRIDE_NAMED',
-      "Missing the named parameter '{0}' to match the overridden method from '{1}'");
+      "Missing the named parameter '{0}' to match the overridden method from '{1}' from '{2}'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -4406,11 +5017,12 @@
    *
    * Parameters:
    * 0: the number of positional parameters in the overridden member
-   * 1: the name of the class from the overridden method
+   * 1: the signature of the overridden member
+   * 2: the name of the class from the overridden method
    */
   static const StaticWarningCode INVALID_OVERRIDE_POSITIONAL =
       const StaticWarningCode('INVALID_OVERRIDE_POSITIONAL',
-          "Must have at least {0} parameters to match the overridden method from '{1}'");
+          "Must have at least {0} parameters to match the overridden method '{1}' from '{2}'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -4419,11 +5031,12 @@
    *
    * Parameters:
    * 0: the number of required parameters in the overridden member
-   * 1: the name of the class from the overridden method
+   * 1: the signature of the overridden member
+   * 2: the name of the class from the overridden method
    */
   static const StaticWarningCode INVALID_OVERRIDE_REQUIRED =
       const StaticWarningCode('INVALID_OVERRIDE_REQUIRED',
-          "Must have {0} required parameters or less to match the overridden method from '{1}'");
+          "Must have {0} required parameters or less to match the overridden method '{1}' from '{2}'");
 
   /**
    * 7.3 Setters: It is a static warning if a setter <i>m1</i> overrides a
@@ -4511,7 +5124,8 @@
    * with argument type <i>T</i> and a getter named <i>v</i> with return type
    * <i>S</i>, and <i>T</i> may not be assigned to <i>S</i>.
    */
-  static const StaticWarningCode MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE =
+  static const StaticWarningCode
+      MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE =
       const StaticWarningCode(
           'MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE',
           "The parameter type for setter '{0}' is '{1}' which is not assignable to its getter (of type '{2}'), from superclass '{3}'");
@@ -4613,7 +5227,8 @@
    * 3: the name of the fourth member
    * 4: the number of additional missing members that aren't listed
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS =
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS =
       const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS',
           "Missing concrete implementation of {0}, {1}, {2}, {3} and {4} more");
@@ -4638,7 +5253,8 @@
    * 2: the name of the third member
    * 3: the name of the fourth member
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR =
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR =
       const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR',
           "Missing concrete implementation of {0}, {1}, {2} and {3}");
@@ -4660,8 +5276,9 @@
    * Parameters:
    * 0: the name of the member
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE =
-      const StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = const StaticWarningCode(
+          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
           "Missing concrete implementation of {0}");
 
   /**
@@ -4683,7 +5300,8 @@
    * 1: the name of the second member
    * 2: the name of the third member
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE =
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE =
       const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE',
           "Missing concrete implementation of {0}, {1} and {2}");
@@ -4706,8 +5324,9 @@
    * 0: the name of the first member
    * 1: the name of the second member
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO =
-      const StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = const StaticWarningCode(
+          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
           "Missing concrete implementation of {0} and {1}");
 
   /**
@@ -4896,7 +5515,7 @@
    */
   static const StaticWarningCode TYPE_PARAMETER_REFERENCED_BY_STATIC =
       const StaticWarningCode('TYPE_PARAMETER_REFERENCED_BY_STATIC',
-          "Static members cannot reference type parameters");
+          "Static members cannot reference type parameters of the class");
 
   /**
    * 12.16.3 Static Invocation: A static method invocation <i>i</i> has the form
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index ec9559a..d644fcd 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2,24 +2,29 @@
 // for 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 engine.resolver.error_verifier;
+library analyzer.src.generated.error_verifier;
 
 import 'dart:collection';
 import "dart:math" as math;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element_resolver.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/parser.dart'
+    show Parser, ParserErrorCode;
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' as sc;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary;
 import 'package:analyzer/src/generated/static_type_analyzer.dart';
-
-import 'ast.dart';
-import 'constant.dart';
-import 'element.dart';
-import 'element_resolver.dart';
-import 'error.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser, ParserErrorCode;
-import 'resolver.dart';
-import 'scanner.dart' as sc;
-import 'sdk.dart' show DartSdk, SdkLibrary;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
  * A visitor used to traverse an AST structure looking for additional errors and
@@ -266,10 +271,21 @@
   final bool enableSuperMixins;
 
   /**
+   * If `true`, asserts are allowed to take a second argument representing the
+   * assertion failure message (see DEP 37).
+   */
+  final bool enableAssertMessage;
+
+  /**
    * Initialize a newly created error verifier.
    */
-  ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider,
-      this._inheritanceManager, this.enableSuperMixins) {
+  ErrorVerifier(
+      this._errorReporter,
+      this._currentLibrary,
+      this._typeProvider,
+      this._inheritanceManager,
+      this.enableSuperMixins,
+      this.enableAssertMessage) {
     this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
     this._hasExtUri = _currentLibrary.hasExtUri;
     _isEnclosingConstructorConst = false;
@@ -306,6 +322,7 @@
   @override
   Object visitAssertStatement(AssertStatement node) {
     _checkForNonBoolExpression(node);
+    _checkAssertMessage(node);
     return super.visitAssertStatement(node);
   }
 
@@ -1117,6 +1134,19 @@
   }
 
   /**
+   * If the given assert [statement] specifies a message, verify that support
+   * for assertions with messages is enabled.
+   */
+  void _checkAssertMessage(AssertStatement statement) {
+    Expression expression = statement.message;
+    if (expression != null && !enableAssertMessage) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.EXTRA_ARGUMENT_TO_ASSERT, expression);
+      return;
+    }
+  }
+
+  /**
    * Verify that the given list of [typeArguments] contains exactly two
    * elements.
    *
@@ -1176,7 +1206,8 @@
         } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
           if (fieldElement.isFinal || fieldElement.isConst) {
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
+                StaticWarningCode
+                    .FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
                 formalParameter.identifier,
                 [fieldElement.displayName]);
             foundError = true;
@@ -1211,13 +1242,15 @@
           } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
             if (fieldElement.isFinal || fieldElement.isConst) {
               _errorReporter.reportErrorForNode(
-                  StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
+                  StaticWarningCode
+                      .FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
                   fieldName);
               foundError = true;
             }
           } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) {
             _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
+                CompileTimeErrorCode
+                    .FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
                 fieldName);
             foundError = true;
           } else if (state == INIT_STATE.INIT_IN_INITIALIZERS) {
@@ -1316,12 +1349,77 @@
     FunctionType overridingFT = executableElement.type;
     FunctionType overriddenFT = overriddenExecutable.type;
     InterfaceType enclosingType = _enclosingClass.type;
-    overriddenFT = _inheritanceManager
-        .substituteTypeArgumentsInMemberFromInheritance(
+    overriddenFT =
+        _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(
             overriddenFT, executableElementName, enclosingType);
     if (overridingFT == null || overriddenFT == null) {
       return false;
     }
+
+    // Handle generic function type parameters.
+    // TODO(jmesserly): this duplicates some code in isSubtypeOf and most of
+    // _isGenericFunctionSubtypeOf. Ideally, we'd let TypeSystem produce
+    // an error message once it's ready to "return false".
+    if (!overridingFT.typeFormals.isEmpty) {
+      if (overriddenFT.typeFormals.isEmpty) {
+        overriddenFT = _typeSystem.instantiateToBounds(overriddenFT);
+      } else {
+        List<TypeParameterElement> params1 = overridingFT.typeFormals;
+        List<TypeParameterElement> params2 = overriddenFT.typeFormals;
+        int count = params1.length;
+        if (params2.length != count) {
+          _errorReporter.reportErrorForNode(
+              StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS,
+              errorNameTarget, [
+            count,
+            params2.length,
+            overriddenExecutable.enclosingElement.displayName
+          ]);
+          return true;
+        }
+        // We build up a substitution matching up the type parameters
+        // from the two types, {variablesFresh/variables1} and
+        // {variablesFresh/variables2}
+        List<DartType> variables1 = new List<DartType>();
+        List<DartType> variables2 = new List<DartType>();
+        List<DartType> variablesFresh = new List<DartType>();
+        for (int i = 0; i < count; i++) {
+          TypeParameterElement p1 = params1[i];
+          TypeParameterElement p2 = params2[i];
+          TypeParameterElementImpl pFresh =
+              new TypeParameterElementImpl(p1.name, -1);
+
+          DartType variable1 = p1.type;
+          DartType variable2 = p2.type;
+          DartType variableFresh = new TypeParameterTypeImpl(pFresh);
+
+          variables1.add(variable1);
+          variables2.add(variable2);
+          variablesFresh.add(variableFresh);
+          DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
+          DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
+          bound1 = bound1.substitute2(variablesFresh, variables1);
+          bound2 = bound2.substitute2(variablesFresh, variables2);
+          pFresh.bound = bound2;
+          if (!_typeSystem.isSubtypeOf(bound2, bound1)) {
+            _errorReporter.reportErrorForNode(
+                StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND,
+                errorNameTarget, [
+              p1.displayName,
+              p1.bound,
+              p2.displayName,
+              p2.bound,
+              overriddenExecutable.enclosingElement.displayName
+            ]);
+            return true;
+          }
+        }
+        // Proceed with the rest of the checks, using instantiated types.
+        overridingFT = overridingFT.instantiate(variablesFresh);
+        overriddenFT = overriddenFT.instantiate(variablesFresh);
+      }
+    }
+
     DartType overridingFTReturnType = overridingFT.returnType;
     DartType overriddenFTReturnType = overriddenFT.returnType;
     List<DartType> overridingNormalPT = overridingFT.normalParameterTypes;
@@ -1336,6 +1434,7 @@
       _errorReporter.reportErrorForNode(
           StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
         overriddenNormalPT.length,
+        overriddenExecutable,
         overriddenExecutable.enclosingElement.displayName
       ]);
       return true;
@@ -1345,6 +1444,7 @@
       _errorReporter.reportErrorForNode(
           StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
         overriddenPositionalPT.length + overriddenNormalPT.length,
+        overriddenExecutable,
         overriddenExecutable.enclosingElement.displayName
       ]);
       return true;
@@ -1358,6 +1458,7 @@
         _errorReporter.reportErrorForNode(
             StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [
           overriddenParamName,
+          overriddenExecutable,
           overriddenExecutable.enclosingElement.displayName
         ]);
         return true;
@@ -1373,10 +1474,10 @@
               : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE,
           errorNameTarget,
           [
-        overridingFTReturnType,
-        overriddenFTReturnType,
-        overriddenExecutable.enclosingElement.displayName
-      ]);
+            overridingFTReturnType,
+            overriddenFTReturnType,
+            overriddenExecutable.enclosingElement.displayName
+          ]);
       return true;
     }
     // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
@@ -1393,10 +1494,10 @@
                 : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE,
             parameterLocations[parameterIndex],
             [
-          overridingNormalPT[i],
-          overriddenNormalPT[i],
-          overriddenExecutable.enclosingElement.displayName
-        ]);
+              overridingNormalPT[i],
+              overriddenNormalPT[i],
+              overriddenExecutable.enclosingElement.displayName
+            ]);
         return true;
       }
       parameterIndex++;
@@ -1512,12 +1613,14 @@
               }
               if (!result.equalValues(_typeProvider, overriddenResult)) {
                 _errorReporter.reportErrorForNode(
-                    StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
-                    formalParameters[i], [
-                  overriddenExecutable.enclosingElement.displayName,
-                  overriddenExecutable.displayName,
-                  parameterName
-                ]);
+                    StaticWarningCode
+                        .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
+                    formalParameters[i],
+                    [
+                      overriddenExecutable.enclosingElement.displayName,
+                      overriddenExecutable.displayName,
+                      parameterName
+                    ]);
                 foundError = true;
               }
             }
@@ -1549,11 +1652,13 @@
           }
           if (!result.equalValues(_typeProvider, overriddenResult)) {
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
-                formalParameters[i], [
-              overriddenExecutable.enclosingElement.displayName,
-              overriddenExecutable.displayName
-            ]);
+                StaticWarningCode
+                    .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
+                formalParameters[i],
+                [
+                  overriddenExecutable.enclosingElement.displayName,
+                  overriddenExecutable.displayName
+                ]);
             foundError = true;
           }
         }
@@ -2066,8 +2171,8 @@
       SimpleIdentifier identifier, ErrorCode errorCode) {
     sc.Token token = identifier.token;
     if (token.type == sc.TokenType.KEYWORD) {
-      _errorReporter.reportErrorForNode(
-          errorCode, identifier, [identifier.name]);
+      _errorReporter
+          .reportErrorForNode(errorCode, identifier, [identifier.name]);
       return true;
     }
     return false;
@@ -3168,8 +3273,8 @@
       return false;
     }
     if (typeName.isDeferred) {
-      _errorReporter.reportErrorForNode(
-          errorCode, typeName, [typeName.name.name]);
+      _errorReporter
+          .reportErrorForNode(errorCode, typeName, [typeName.name.name]);
       return true;
     }
     return false;
@@ -3264,7 +3369,8 @@
       // TODO(paulberry): this error should be based on the actual type of the
       // constant, not the static type.  See dartbug.com/21119.
       _errorReporter.reportTypeErrorForNode(
-          CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+          CheckedModeCompileTimeErrorCode
+              .CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
           expression,
           [staticType, fieldType]);
     }
@@ -3706,7 +3812,8 @@
           // instance vs. static
           if (fieldElt.isStatic) {
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
+                StaticWarningCode
+                    .INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
                 errorNameTarget,
                 [executableElementName, fieldElt.enclosingElement.displayName]);
             return true;
@@ -3727,11 +3834,13 @@
           // instance vs. static
           if (methodElement.isStatic) {
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
-                errorNameTarget, [
-              executableElementName,
-              methodElement.enclosingElement.displayName
-            ]);
+                StaticWarningCode
+                    .INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
+                errorNameTarget,
+                [
+                  executableElementName,
+                  methodElement.enclosingElement.displayName
+                ]);
             return true;
           }
         }
@@ -4233,8 +4342,8 @@
   void _checkForMixinHasNoConstructors(AstNode node) {
     if ((_enclosingClass as ClassElementImpl).doesMixinLackConstructors) {
       ErrorCode errorCode = CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS;
-      _errorReporter.reportErrorForNode(
-          errorCode, node, [_enclosingClass.supertype]);
+      _errorReporter
+          .reportErrorForNode(errorCode, node, [_enclosingClass.supertype]);
     }
   }
 
@@ -4563,14 +4672,16 @@
       ]);
     } else {
       analysisError = _errorReporter.newErrorWithProperties(
-          StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS,
-          classNameNode, [
-        stringMembersArray[0],
-        stringMembersArray[1],
-        stringMembersArray[2],
-        stringMembersArray[3],
-        stringMembersArray.length - 4
-      ]);
+          StaticWarningCode
+              .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS,
+          classNameNode,
+          [
+            stringMembersArray[0],
+            stringMembersArray[1],
+            stringMembersArray[2],
+            stringMembersArray[3],
+            stringMembersArray.length - 4
+          ]);
     }
     analysisError.setProperty(
         ErrorProperty.UNIMPLEMENTED_METHODS, missingOverridesArray);
@@ -4854,7 +4965,8 @@
         if (parameter is DefaultFormalParameter &&
             parameter.defaultValue != null) {
           _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
+              CompileTimeErrorCode
+                  .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
               parameter.identifier);
           errorReported = true;
         }
@@ -4886,7 +4998,8 @@
           } else {
             if (redirectingElement.isFactory) {
               _errorReporter.reportErrorForNode(
-                  CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
+                  CompileTimeErrorCode
+                      .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
                   initializer);
             }
           }
@@ -5058,6 +5171,10 @@
    */
   bool _checkForStaticAccessToInstanceMember(
       ClassElement typeReference, SimpleIdentifier name) {
+    // OK, in comment
+    if (_isInComment) {
+      return false;
+    }
     // OK, target is not a type
     if (typeReference == null) {
       return false;
@@ -5210,9 +5327,14 @@
     if (_isInStaticMethod || _isInStaticVariableDeclaration) {
       DartType type = name.type;
       if (type is TypeParameterType) {
-        _errorReporter.reportErrorForNode(
-            StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name);
-        return true;
+        // The class's type parameters are not in scope for static methods.
+        // However all other type parameters are legal (e.g. the static method's
+        // type parameters, or a local function's type parameters).
+        if (type.element.enclosingElement is ClassElement) {
+          _errorReporter.reportErrorForNode(
+              StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name);
+          return true;
+        }
       }
     }
     return false;
@@ -5663,15 +5785,18 @@
   ErrorCode _getBaseCaseErrorCode(ClassElement element) {
     InterfaceType supertype = element.supertype;
     if (supertype != null && _enclosingClass == supertype.element) {
-      return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS;
+      return CompileTimeErrorCode
+          .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS;
     }
     List<InterfaceType> mixins = element.mixins;
     for (int i = 0; i < mixins.length; i++) {
       if (_enclosingClass == mixins[i].element) {
-        return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH;
+        return CompileTimeErrorCode
+            .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH;
       }
     }
-    return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS;
+    return CompileTimeErrorCode
+        .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS;
   }
 
   /**
@@ -5781,7 +5906,8 @@
   bool _hasTypedefSelfReference(Element element) {
     Set<Element> checked = new HashSet<Element>();
     List<Element> toCheck = new List<Element>();
-    GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisitor =
+    GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference
+        elementVisitor =
         new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(
             toCheck);
     toCheck.add(element);
@@ -5933,7 +6059,8 @@
     return false;
   }
 
-  bool _isUserDefinedObject(EvaluationResultImpl result) => result == null ||
+  bool _isUserDefinedObject(EvaluationResultImpl result) =>
+      result == null ||
       (result.value != null && result.value.isUserDefinedObject);
 
   /**
@@ -6046,6 +6173,12 @@
   }
 
   @override
+  Object visitFunctionElement(FunctionElement element) {
+    _addTypeToCheck(element.returnType);
+    return super.visitFunctionElement(element);
+  }
+
+  @override
   Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
     _addTypeToCheck(element.returnType);
     return super.visitFunctionTypeAliasElement(element);
diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
deleted file mode 100644
index c0012c5..0000000
--- a/pkg/analyzer/lib/src/generated/html.dart
+++ /dev/null
@@ -1,1905 +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 engine.html;
-
-import 'dart:collection';
-
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart' show AnalysisOptions, AnalysisEngine;
-import 'error.dart' show AnalysisErrorListener;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser;
-import 'scanner.dart' as sc show Scanner, SubSequenceReader, Token;
-import 'source.dart';
-
-/**
- * The abstract class `AbstractScanner` implements a scanner for HTML code. Subclasses are
- * required to implement the interface used to access the characters being scanned.
- */
-abstract class AbstractScanner {
-  static List<String> _NO_PASS_THROUGH_ELEMENTS = <String>[];
-
-  /**
-   * The source being scanned.
-   */
-  final Source source;
-
-  /**
-   * The token pointing to the head of the linked list of tokens.
-   */
-  Token _tokens;
-
-  /**
-   * The last token that was scanned.
-   */
-  Token _tail;
-
-  /**
-   * A list containing the offsets of the first character of each line in the source code.
-   */
-  List<int> _lineStarts = new List<int>();
-
-  /**
-   * An array of element tags for which the content between tags should be consider a single token.
-   */
-  List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS;
-
-  /**
-   * Initialize a newly created scanner.
-   *
-   * @param source the source being scanned
-   */
-  AbstractScanner(this.source) {
-    _tokens = new Token.con1(TokenType.EOF, -1);
-    _tokens.setNext(_tokens);
-    _tail = _tokens;
-    recordStartOfLine();
-  }
-
-  /**
-   * Return an array containing the offsets of the first character of each line in the source code.
-   *
-   * @return an array containing the offsets of the first character of each line in the source code
-   */
-  List<int> get lineStarts => _lineStarts;
-
-  /**
-   * Return the current offset relative to the beginning of the file. Return the initial offset if
-   * the scanner has not yet scanned the source code, and one (1) past the end of the source code if
-   * the source code has been scanned.
-   *
-   * @return the current offset of the scanner in the source
-   */
-  int get offset;
-
-  /**
-   * Set array of element tags for which the content between tags should be consider a single token.
-   */
-  void set passThroughElements(List<String> passThroughElements) {
-    this._passThroughElements = passThroughElements != null
-        ? passThroughElements
-        : _NO_PASS_THROUGH_ELEMENTS;
-  }
-
-  /**
-   * Advance the current position and return the character at the new current position.
-   *
-   * @return the character at the new current position
-   */
-  int advance();
-
-  /**
-   * Return the substring of the source code between the start offset and the modified current
-   * position. The current position is modified by adding the end delta.
-   *
-   * @param start the offset to the beginning of the string, relative to the start of the file
-   * @param endDelta the number of character after the current location to be included in the
-   *          string, or the number of characters before the current location to be excluded if the
-   *          offset is negative
-   * @return the specified substring of the source code
-   */
-  String getString(int start, int endDelta);
-
-  /**
-   * Return the character at the current position without changing the current position.
-   *
-   * @return the character at the current position
-   */
-  int peek();
-
-  /**
-   * Record the fact that we are at the beginning of a new line in the source.
-   */
-  void recordStartOfLine() {
-    _lineStarts.add(offset);
-  }
-
-  /**
-   * Scan the source code to produce a list of tokens representing the source.
-   *
-   * @return the first token in the list of tokens that were produced
-   */
-  Token tokenize() {
-    _scan();
-    _appendEofToken();
-    return _firstToken();
-  }
-
-  void _appendEofToken() {
-    Token eofToken = new Token.con1(TokenType.EOF, offset);
-    // The EOF token points to itself so that there is always infinite
-    // look-ahead.
-    eofToken.setNext(eofToken);
-    _tail = _tail.setNext(eofToken);
-  }
-
-  Token _emit(Token token) {
-    _tail.setNext(token);
-    _tail = token;
-    return token;
-  }
-
-  Token _emitWithOffset(TokenType type, int start) =>
-      _emit(new Token.con1(type, start));
-
-  Token _emitWithOffsetAndLength(TokenType type, int start, int count) =>
-      _emit(new Token.con2(type, start, getString(start, count)));
-
-  Token _firstToken() => _tokens.next;
-
-  int _recordStartOfLineAndAdvance(int c) {
-    if (c == 0xD) {
-      c = advance();
-      if (c == 0xA) {
-        c = advance();
-      }
-      recordStartOfLine();
-    } else if (c == 0xA) {
-      c = advance();
-      recordStartOfLine();
-    } else {
-      c = advance();
-    }
-    return c;
-  }
-
-  void _scan() {
-    bool inBrackets = false;
-    String endPassThrough = null;
-    int c = advance();
-    while (c >= 0) {
-      int start = offset;
-      if (c == 0x3C) {
-        c = advance();
-        if (c == 0x21) {
-          c = advance();
-          if (c == 0x2D && peek() == 0x2D) {
-            // handle a comment
-            c = advance();
-            int dashCount = 1;
-            while (c >= 0) {
-              if (c == 0x2D) {
-                dashCount++;
-              } else if (c == 0x3E && dashCount >= 2) {
-                c = advance();
-                break;
-              } else {
-                dashCount = 0;
-              }
-              c = _recordStartOfLineAndAdvance(c);
-            }
-            _emitWithOffsetAndLength(TokenType.COMMENT, start, -1);
-            // Capture <!--> and <!---> as tokens but report an error
-            if (_tail.length < 7) {
-              // TODO (danrubel): Report invalid HTML comment
-            }
-          } else {
-            // handle a declaration
-            while (c >= 0) {
-              if (c == 0x3E) {
-                c = advance();
-                break;
-              }
-              c = _recordStartOfLineAndAdvance(c);
-            }
-            _emitWithOffsetAndLength(TokenType.DECLARATION, start, -1);
-            if (!StringUtilities.endsWithChar(_tail.lexeme, 0x3E)) {
-              // TODO (danrubel): Report missing '>' in directive
-            }
-          }
-        } else if (c == 0x3F) {
-          // handle a directive
-          while (c >= 0) {
-            if (c == 0x3F) {
-              c = advance();
-              if (c == 0x3E) {
-                c = advance();
-                break;
-              }
-            } else {
-              c = _recordStartOfLineAndAdvance(c);
-            }
-          }
-          _emitWithOffsetAndLength(TokenType.DIRECTIVE, start, -1);
-          if (_tail.length < 4) {
-            // TODO (danrubel): Report invalid directive
-          }
-        } else if (c == 0x2F) {
-          _emitWithOffset(TokenType.LT_SLASH, start);
-          inBrackets = true;
-          c = advance();
-        } else {
-          inBrackets = true;
-          _emitWithOffset(TokenType.LT, start);
-          // ignore whitespace in braces
-          while (Character.isWhitespace(c)) {
-            c = _recordStartOfLineAndAdvance(c);
-          }
-          // get tag
-          if (Character.isLetterOrDigit(c)) {
-            int tagStart = offset;
-            c = advance();
-            while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
-              c = advance();
-            }
-            _emitWithOffsetAndLength(TokenType.TAG, tagStart, -1);
-            // check tag against passThrough elements
-            String tag = _tail.lexeme;
-            for (String str in _passThroughElements) {
-              if (str == tag) {
-                endPassThrough = "</$str>";
-                break;
-              }
-            }
-          }
-        }
-      } else if (c == 0x3E) {
-        _emitWithOffset(TokenType.GT, start);
-        inBrackets = false;
-        c = advance();
-        // if passThrough != null, read until we match it
-        if (endPassThrough != null) {
-          bool endFound = false;
-          int len = endPassThrough.length;
-          int firstC = endPassThrough.codeUnitAt(0);
-          int index = 0;
-          int nextC = firstC;
-          while (c >= 0) {
-            if (c == nextC) {
-              index++;
-              if (index == len) {
-                endFound = true;
-                break;
-              }
-              nextC = endPassThrough.codeUnitAt(index);
-            } else if (c == firstC) {
-              index = 1;
-              nextC = endPassThrough.codeUnitAt(1);
-            } else {
-              index = 0;
-              nextC = firstC;
-            }
-            c = _recordStartOfLineAndAdvance(c);
-          }
-          if (start + 1 < offset) {
-            if (endFound) {
-              _emitWithOffsetAndLength(TokenType.TEXT, start + 1, -len);
-              _emitWithOffset(TokenType.LT_SLASH, offset - len + 1);
-              _emitWithOffsetAndLength(TokenType.TAG, offset - len + 3, -1);
-            } else {
-              _emitWithOffsetAndLength(TokenType.TEXT, start + 1, -1);
-            }
-          }
-          endPassThrough = null;
-        }
-      } else if (c == 0x2F && peek() == 0x3E) {
-        advance();
-        _emitWithOffset(TokenType.SLASH_GT, start);
-        inBrackets = false;
-        c = advance();
-      } else if (!inBrackets) {
-        c = _recordStartOfLineAndAdvance(c);
-        while (c != 0x3C && c >= 0) {
-          c = _recordStartOfLineAndAdvance(c);
-        }
-        _emitWithOffsetAndLength(TokenType.TEXT, start, -1);
-      } else if (c == 0x22 || c == 0x27) {
-        // read a string
-        int endQuote = c;
-        c = advance();
-        while (c >= 0) {
-          if (c == endQuote) {
-            c = advance();
-            break;
-          }
-          c = _recordStartOfLineAndAdvance(c);
-        }
-        _emitWithOffsetAndLength(TokenType.STRING, start, -1);
-      } else if (c == 0x3D) {
-        // a non-char token
-        _emitWithOffset(TokenType.EQ, start);
-        c = advance();
-      } else if (Character.isWhitespace(c)) {
-        // ignore whitespace in braces
-        do {
-          c = _recordStartOfLineAndAdvance(c);
-        } while (Character.isWhitespace(c));
-      } else if (Character.isLetterOrDigit(c)) {
-        c = advance();
-        while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
-          c = advance();
-        }
-        _emitWithOffsetAndLength(TokenType.TAG, start, -1);
-      } else {
-        // a non-char token
-        _emitWithOffsetAndLength(TokenType.TEXT, start, 0);
-        c = advance();
-      }
-    }
-  }
-}
-
-/**
- * Instances of the class `HtmlParser` are used to parse tokens into a AST structure comprised
- * of [XmlNode]s.
- */
-class HtmlParser extends XmlParser {
-  static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\"";
-
-  static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'";
-
-  static String _SCRIPT = "script";
-
-  static String _TYPE = "type";
-
-  /**
-   * A set containing the names of tags that do not have a closing tag.
-   */
-  static Set<String> SELF_CLOSING = new HashSet<String>.from(<String>[
-    "area",
-    "base",
-    "basefont",
-    "br",
-    "col",
-    "frame",
-    "hr",
-    "img",
-    "input",
-    "link",
-    "meta",
-    "param",
-    "!"
-  ]);
-
-  /**
-   * The line information associated with the source being parsed.
-   */
-  LineInfo _lineInfo;
-
-  /**
-   * The error listener to which errors will be reported.
-   */
-  final AnalysisErrorListener _errorListener;
-
-  final AnalysisOptions _options;
-
-  /**
-   * Construct a parser for the specified source.
-   *
-   * [source] is the source being parsed.  [_errorListener] is the error
-   * listener to which errors will be reported.  [_options] is the analysis
-   * options which should be used for parsing.
-   */
-  HtmlParser(Source source, this._errorListener, this._options) : super(source);
-
-  @override
-  XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
-      new XmlAttributeNode(name, equals, value);
-
-  @override
-  XmlTagNode createTagNode(
-      Token nodeStart,
-      Token tag,
-      List<XmlAttributeNode> attributes,
-      Token attributeEnd,
-      List<XmlTagNode> tagNodes,
-      Token contentEnd,
-      Token closingTag,
-      Token nodeEnd) {
-    if (_isScriptNode(tag, attributes, tagNodes)) {
-      HtmlScriptTagNode tagNode = new HtmlScriptTagNode(nodeStart, tag,
-          attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
-      String contents = tagNode.content;
-      int contentOffset = attributeEnd.end;
-      LineInfo_Location location = _lineInfo.getLocation(contentOffset);
-      sc.Scanner scanner = new sc.Scanner(source,
-          new sc.SubSequenceReader(contents, contentOffset), _errorListener);
-      scanner.setSourceStart(location.lineNumber, location.columnNumber);
-      sc.Token firstToken = scanner.tokenize();
-      Parser parser = new Parser(source, _errorListener);
-      CompilationUnit unit = parser.parseCompilationUnit(firstToken);
-      unit.lineInfo = _lineInfo;
-      tagNode.script = unit;
-      return tagNode;
-    }
-    return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
-        contentEnd, closingTag, nodeEnd);
-  }
-
-  @override
-  bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
-
-  /**
-   * Parse the given tokens.
-   *
-   * @param token the first token in the stream of tokens to be parsed
-   * @param lineInfo the line information created by the scanner
-   * @return the parse result (not `null`)
-   */
-  HtmlUnit parse(Token token, LineInfo lineInfo) {
-    this._lineInfo = lineInfo;
-    List<XmlTagNode> tagNodes = parseTopTagNodes(token);
-    return new HtmlUnit(token, tagNodes, currentToken);
-  }
-
-  /**
-   * Determine if the specified node is a Dart script.
-   *
-   * @param node the node to be tested (not `null`)
-   * @return `true` if the node is a Dart script
-   */
-  bool _isScriptNode(
-      Token tag, List<XmlAttributeNode> attributes, List<XmlTagNode> tagNodes) {
-    if (tagNodes.length != 0 || tag.lexeme != _SCRIPT) {
-      return false;
-    }
-    for (XmlAttributeNode attribute in attributes) {
-      if (attribute.name == _TYPE) {
-        Token valueToken = attribute.valueToken;
-        if (valueToken != null) {
-          String value = valueToken.lexeme;
-          if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES ||
-              value == _APPLICATION_DART_IN_SINGLE_QUOTES) {
-            return true;
-          }
-        }
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Given the contents of an embedded expression that occurs at the given offset, parse it as a
-   * Dart expression. The contents should not include the expression's delimiters.
-   *
-   * @param source the source that contains that given token
-   * @param token the token to start parsing from
-   * @return the Dart expression that was parsed
-   */
-  static Expression parseEmbeddedExpression(
-      Source source, sc.Token token, AnalysisErrorListener errorListener) {
-    Parser parser = new Parser(source, errorListener);
-    return parser.parseExpression(token);
-  }
-
-  /**
-   * Given the contents of an embedded expression that occurs at the given offset, scans it as a
-   * Dart code.
-   *
-   * @param source the source of that contains the given contents
-   * @param contents the contents to scan
-   * @param contentOffset the offset of the contents in the larger file
-   * @return the first Dart token
-   */
-  static sc.Token scanDartSource(Source source, LineInfo lineInfo,
-      String contents, int contentOffset, AnalysisErrorListener errorListener) {
-    LineInfo_Location location = lineInfo.getLocation(contentOffset);
-    sc.Scanner scanner = new sc.Scanner(source,
-        new sc.SubSequenceReader(contents, contentOffset), errorListener);
-    scanner.setSourceStart(location.lineNumber, location.columnNumber);
-    return scanner.tokenize();
-  }
-}
-
-/**
- * Instances of the class `HtmlScriptTagNode` represent a script tag within an HTML file that
- * references a Dart script.
- */
-@deprecated
-class HtmlScriptTagNode extends XmlTagNode {
-  /**
-   * The AST structure representing the Dart code within this tag.
-   */
-  CompilationUnit _script;
-
-  /**
-   * The element representing this script.
-   */
-  HtmlScriptElement scriptElement;
-
-  /**
-   * Initialize a newly created node to represent a script tag within an HTML file that references a
-   * Dart script.
-   *
-   * @param nodeStart the token marking the beginning of the tag
-   * @param tag the name of the tag
-   * @param attributes the attributes in the tag
-   * @param attributeEnd the token terminating the region where attributes can be
-   * @param tagNodes the children of the tag
-   * @param contentEnd the token that starts the closing tag
-   * @param closingTag the name of the tag that occurs in the closing tag
-   * @param nodeEnd the last token in the tag
-   */
-  HtmlScriptTagNode(
-      Token nodeStart,
-      Token tag,
-      List<XmlAttributeNode> attributes,
-      Token attributeEnd,
-      List<XmlTagNode> tagNodes,
-      Token contentEnd,
-      Token closingTag,
-      Token nodeEnd)
-      : super(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd,
-            closingTag, nodeEnd);
-
-  /**
-   * Return the AST structure representing the Dart code within this tag, or `null` if this
-   * tag references an external script.
-   *
-   * @return the AST structure representing the Dart code within this tag
-   */
-  CompilationUnit get script => _script;
-
-  /**
-   * Set the AST structure representing the Dart code within this tag to the given compilation unit.
-   *
-   * @param unit the AST structure representing the Dart code within this tag
-   */
-  void set script(CompilationUnit unit) {
-    _script = unit;
-  }
-
-  @override
-  accept(XmlVisitor visitor) => visitor.visitHtmlScriptTagNode(this);
-}
-
-/**
- * Instances of the class `HtmlUnit` represent the contents of an HTML file.
- */
-@deprecated
-class HtmlUnit extends XmlNode {
-  /**
-   * The first token in the token stream that was parsed to form this HTML unit.
-   */
-  final Token beginToken;
-
-  /**
-   * The last token in the token stream that was parsed to form this compilation unit. This token
-   * should always have a type of [TokenType.EOF].
-   */
-  final Token endToken;
-
-  /**
-   * The tag nodes contained in the receiver (not `null`, contains no `null`s).
-   */
-  List<XmlTagNode> _tagNodes;
-
-  /**
-   * Construct a new instance representing the content of an HTML file.
-   *
-   * @param beginToken the first token in the file (not `null`)
-   * @param tagNodes child tag nodes of the receiver (not `null`, contains no `null`s)
-   * @param endToken the last token in the token stream which should be of type
-   *          [TokenType.EOF]
-   */
-  HtmlUnit(this.beginToken, List<XmlTagNode> tagNodes, this.endToken) {
-    this._tagNodes = becomeParentOfAll(tagNodes);
-  }
-
-  /**
-   * Return the element associated with this HTML unit.
-   *
-   * @return the element or `null` if the receiver is not resolved
-   */
-  @override
-  HtmlElement get element => super.element as HtmlElement;
-
-  @override
-  void set element(Element element) {
-    if (element != null && element is! HtmlElement) {
-      throw new IllegalArgumentException(
-          "HtmlElement expected, but ${element.runtimeType} given");
-    }
-    super.element = element;
-  }
-
-  /**
-   * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
-   * to edit the AST structure.
-   *
-   * @return the children (not `null`, contains no `null`s)
-   */
-  List<XmlTagNode> get tagNodes => _tagNodes;
-
-  @override
-  accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
-
-  @override
-  void visitChildren(XmlVisitor visitor) {
-    for (XmlTagNode node in _tagNodes) {
-      node.accept(visitor);
-    }
-  }
-}
-
-/**
- * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that will recursively
- * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
- * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and
- * [XmlTagNode]s to be visited.
- *
- * Subclasses that override a visit method must either invoke the overridden visit method or must
- * explicitly ask the visited node to visit its children. Failure to do so will cause the children
- * of the visited node to not be visited.
- */
-class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
-  @override
-  R visitHtmlScriptTagNode(HtmlScriptTagNode node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitHtmlUnit(HtmlUnit node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitXmlAttributeNode(XmlAttributeNode node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitXmlTagNode(XmlTagNode node) {
-    node.visitChildren(this);
-    return null;
-  }
-}
-
-/**
- * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will do nothing
- * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
- * pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a whole
- * structure) and that only need to visit a small number of node types.
- */
-class SimpleXmlVisitor<R> implements XmlVisitor<R> {
-  @override
-  R visitHtmlScriptTagNode(HtmlScriptTagNode node) => null;
-
-  @override
-  R visitHtmlUnit(HtmlUnit htmlUnit) => null;
-
-  @override
-  R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
-
-  @override
-  R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
-}
-
-/**
- * Instances of the class `StringScanner` implement a scanner that reads from a string. The
- * scanning logic is in the superclass.
- */
-class StringScanner extends AbstractScanner {
-  /**
-   * The string from which characters will be read.
-   */
-  final String _string;
-
-  /**
-   * The number of characters in the string.
-   */
-  int _stringLength = 0;
-
-  /**
-   * The index, relative to the string, of the last character that was read.
-   */
-  int _charOffset = 0;
-
-  /**
-   * Initialize a newly created scanner to scan the characters in the given string.
-   *
-   * @param source the source being scanned
-   * @param string the string from which characters will be read
-   */
-  StringScanner(Source source, this._string) : super(source) {
-    this._stringLength = _string.length;
-    this._charOffset = -1;
-  }
-
-  @override
-  int get offset => _charOffset;
-
-  void set offset(int offset) {
-    _charOffset = offset;
-  }
-
-  @override
-  int advance() {
-    if (++_charOffset < _stringLength) {
-      return _string.codeUnitAt(_charOffset);
-    }
-    _charOffset = _stringLength;
-    return -1;
-  }
-
-  @override
-  String getString(int start, int endDelta) =>
-      _string.substring(start, _charOffset + 1 + endDelta).toString();
-
-  @override
-  int peek() {
-    if (_charOffset + 1 < _stringLength) {
-      return _string.codeUnitAt(_charOffset + 1);
-    }
-    return -1;
-  }
-}
-
-/**
- * Instances of the class `Token` represent a token that was scanned from the input. Each
- * token knows which token follows it, acting as the head of a linked list of tokens.
- */
-class Token {
-  /**
-   * The offset from the beginning of the file to the first character in the token.
-   */
-  final int offset;
-
-  /**
-   * The previous token in the token stream.
-   */
-  Token previous;
-
-  /**
-   * The next token in the token stream.
-   */
-  Token _next;
-
-  /**
-   * The type of the token.
-   */
-  final TokenType type;
-
-  /**
-   * The lexeme represented by this token.
-   */
-  String _value;
-
-  /**
-   * Initialize a newly created token.
-   *
-   * @param type the token type (not `null`)
-   * @param offset the offset from the beginning of the file to the first character in the token
-   */
-  Token.con1(TokenType type, int offset) : this.con2(type, offset, type.lexeme);
-
-  /**
-   * Initialize a newly created token.
-   *
-   * @param type the token type (not `null`)
-   * @param offset the offset from the beginning of the file to the first character in the token
-   * @param value the lexeme represented by this token (not `null`)
-   */
-  Token.con2(this.type, this.offset, String value) {
-    this._value = StringUtilities.intern(value);
-  }
-
-  /**
-   * Return the offset from the beginning of the file to the character after last character of the
-   * token.
-   *
-   * @return the offset from the beginning of the file to the first character after last character
-   *         of the token
-   */
-  int get end => offset + length;
-
-  /**
-   * Return `true` if this token is a synthetic token. A synthetic token is a token that was
-   * introduced by the parser in order to recover from an error in the code. Synthetic tokens always
-   * have a length of zero (`0`).
-   *
-   * @return `true` if this token is a synthetic token
-   */
-  bool get isSynthetic => length == 0;
-
-  /**
-   * Return the number of characters in the node's source range.
-   *
-   * @return the number of characters in the node's source range
-   */
-  int get length => lexeme.length;
-
-  /**
-   * Return the lexeme that represents this token.
-   *
-   * @return the lexeme (not `null`)
-   */
-  String get lexeme => _value;
-
-  /**
-   * Return the next token in the token stream.
-   *
-   * @return the next token in the token stream
-   */
-  Token get next => _next;
-
-  /**
-   * Set the next token in the token stream to the given token. This has the side-effect of setting
-   * this token to be the previous token for the given token.
-   *
-   * @param token the next token in the token stream
-   * @return the token that was passed in
-   */
-  Token setNext(Token token) {
-    _next = token;
-    token.previous = this;
-    return token;
-  }
-
-  @override
-  String toString() => lexeme;
-}
-
-/**
- * The enumeration `TokenType` defines the types of tokens that can be returned by the
- * scanner.
- */
-class TokenType extends Enum<TokenType> {
-  /**
-   * The type of the token that marks the end of the input.
-   */
-  static const TokenType EOF = const TokenType_EOF('EOF', 0, "");
-
-  static const TokenType EQ = const TokenType('EQ', 1, "=");
-
-  static const TokenType GT = const TokenType('GT', 2, ">");
-
-  static const TokenType LT_SLASH = const TokenType('LT_SLASH', 3, "</");
-
-  static const TokenType LT = const TokenType('LT', 4, "<");
-
-  static const TokenType SLASH_GT = const TokenType('SLASH_GT', 5, "/>");
-
-  static const TokenType COMMENT = const TokenType('COMMENT', 6, null);
-
-  static const TokenType DECLARATION = const TokenType('DECLARATION', 7, null);
-
-  static const TokenType DIRECTIVE = const TokenType('DIRECTIVE', 8, null);
-
-  static const TokenType STRING = const TokenType('STRING', 9, null);
-
-  static const TokenType TAG = const TokenType('TAG', 10, null);
-
-  static const TokenType TEXT = const TokenType('TEXT', 11, null);
-
-  static const List<TokenType> values = const [
-    EOF,
-    EQ,
-    GT,
-    LT_SLASH,
-    LT,
-    SLASH_GT,
-    COMMENT,
-    DECLARATION,
-    DIRECTIVE,
-    STRING,
-    TAG,
-    TEXT
-  ];
-
-  /**
-   * The lexeme that defines this type of token, or `null` if there is more than one possible
-   * lexeme for this type of token.
-   */
-  final String lexeme;
-
-  const TokenType(String name, int ordinal, this.lexeme) : super(name, ordinal);
-}
-
-class TokenType_EOF extends TokenType {
-  const TokenType_EOF(String name, int ordinal, String arg0)
-      : super(name, ordinal, arg0);
-
-  @override
-  String toString() => "-eof-";
-}
-
-/**
- * Instances of the class `ToSourceVisitor` write a source representation of a visited XML
- * node (and all of it's children) to a writer.
- */
-class ToSourceVisitor implements XmlVisitor<Object> {
-  /**
-   * The writer to which the source is to be written.
-   */
-  final PrintWriter _writer;
-
-  /**
-   * Initialize a newly created visitor to write source code representing the visited nodes to the
-   * given writer.
-   *
-   * @param writer the writer to which the source is to be written
-   */
-  ToSourceVisitor(this._writer);
-
-  @override
-  Object visitHtmlScriptTagNode(HtmlScriptTagNode node) =>
-      visitXmlTagNode(node);
-
-  @override
-  Object visitHtmlUnit(HtmlUnit node) {
-    for (XmlTagNode child in node.tagNodes) {
-      _visit(child);
-    }
-    return null;
-  }
-
-  @override
-  Object visitXmlAttributeNode(XmlAttributeNode node) {
-    String name = node.name;
-    Token value = node.valueToken;
-    if (name.length == 0) {
-      _writer.print("__");
-    } else {
-      _writer.print(name);
-    }
-    _writer.print("=");
-    if (value == null) {
-      _writer.print("__");
-    } else {
-      _writer.print(value.lexeme);
-    }
-    return null;
-  }
-
-  @override
-  Object visitXmlTagNode(XmlTagNode node) {
-    _writer.print("<");
-    String tagName = node.tag;
-    _writer.print(tagName);
-    for (XmlAttributeNode attribute in node.attributes) {
-      _writer.print(" ");
-      _visit(attribute);
-    }
-    _writer.print(node.attributeEnd.lexeme);
-    if (node.closingTag != null) {
-      for (XmlTagNode child in node.tagNodes) {
-        _visit(child);
-      }
-      _writer.print("</");
-      _writer.print(tagName);
-      _writer.print(">");
-    }
-    return null;
-  }
-
-  /**
-   * Safely visit the given node.
-   *
-   * @param node the node to be visited
-   */
-  void _visit(XmlNode node) {
-    if (node != null) {
-      node.accept(this);
-    }
-  }
-}
-
-/**
- * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTagNode].
- */
-class XmlAttributeNode extends XmlNode {
-  /**
-   * An empty list of XML attribute nodes.
-   */
-  static const List<XmlAttributeNode> EMPTY_LIST = const <XmlAttributeNode>[];
-
-  final Token _name;
-
-  final Token equals;
-
-  final Token _value;
-
-  List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY;
-
-  /**
-   * Construct a new instance representing an XML attribute.
-   *
-   * @param name the name token (not `null`). This may be a zero length token if the attribute
-   *          is badly formed.
-   * @param equals the equals sign or `null` if none
-   * @param value the value token (not `null`)
-   */
-  XmlAttributeNode(this._name, this.equals, this._value);
-
-  @override
-  Token get beginToken => _name;
-
-  @override
-  Token get endToken => _value;
-
-  /**
-   * Answer the attribute name. This may be a zero length string if the attribute is badly formed.
-   *
-   * @return the name (not `null`)
-   */
-  String get name => _name.lexeme;
-
-  /**
-   * Answer the attribute name token. This may be a zero length token if the attribute is badly
-   * formed.
-   *
-   * @return the name token (not `null`)
-   */
-  Token get nameToken => _name;
-
-  /**
-   * Answer the lexeme for the value token without the leading and trailing quotes.
-   *
-   * @return the text or `null` if the value is not specified
-   */
-  String get text {
-    if (_value == null) {
-      return null;
-    }
-    //TODO (danrubel): replace HTML character encodings with the actual
-    // characters
-    String text = _value.lexeme;
-    int len = text.length;
-    if (len > 0) {
-      if (text.codeUnitAt(0) == 0x22) {
-        if (len > 1 && text.codeUnitAt(len - 1) == 0x22) {
-          return text.substring(1, len - 1);
-        } else {
-          return text.substring(1);
-        }
-      } else if (text.codeUnitAt(0) == 0x27) {
-        if (len > 1 && text.codeUnitAt(len - 1) == 0x27) {
-          return text.substring(1, len - 1);
-        } else {
-          return text.substring(1);
-        }
-      }
-    }
-    return text;
-  }
-
-  /**
-   * Answer the offset of the value after the leading quote.
-   *
-   * @return the offset of the value, or `-1` if the value is not specified
-   */
-  int get textOffset {
-    if (_value == null) {
-      return -1;
-    }
-    String text = _value.lexeme;
-    if (StringUtilities.startsWithChar(text, 0x22) ||
-        StringUtilities.startsWithChar(text, 0x27)) {
-      return _value.offset + 1;
-    }
-    return _value.offset;
-  }
-
-  /**
-   * Answer the attribute value token. A properly formed value will start and end with matching
-   * quote characters, but the value returned may not be properly formed.
-   *
-   * @return the value token or `null` if this represents a badly formed attribute
-   */
-  Token get valueToken => _value;
-
-  @override
-  accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
-
-  @override
-  void visitChildren(XmlVisitor visitor) {
-    // no children to visit
-  }
-}
-
-/**
- * Instances of the class `XmlExpression` represent an abstract expression embedded into
- * [XmlNode].
- */
-abstract class XmlExpression {
-  /**
-   * An empty list of expressions.
-   */
-  static const List<XmlExpression> EMPTY_ARRAY = const <XmlExpression>[];
-
-  /**
-   * Return the offset of the character immediately following the last character of this
-   * expression's source range. This is equivalent to `getOffset() + getLength()`.
-   *
-   * @return the offset of the character just past the expression's source range
-   */
-  int get end;
-
-  /**
-   * Return the number of characters in the expression's source range.
-   */
-  int get length;
-
-  /**
-   * Return the offset of the first character in the expression's source range.
-   */
-  int get offset;
-
-  /**
-   * Check if the given offset belongs to the expression's source range.
-   */
-  bool contains(int offset) => this.offset <= offset && offset < end;
-
-  /**
-   * Return the [Reference] at the given offset.
-   *
-   * @param offset the offset from the beginning of the file
-   * @return the [Reference] at the given offset, maybe `null`
-   */
-  XmlExpression_Reference getReference(int offset);
-}
-
-/**
- * The reference to the [Element].
- */
-class XmlExpression_Reference {
-  Element element;
-
-  int offset = 0;
-
-  int length = 0;
-
-  XmlExpression_Reference(this.element, this.offset, this.length);
-}
-
-/**
- * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes.
- */
-abstract class XmlNode {
-  /**
-   * The parent of the node, or `null` if the node is the root of an AST structure.
-   */
-  XmlNode _parent;
-
-  /**
-   * The element associated with this node or `null` if the receiver is not resolved.
-   */
-  Element _element;
-
-  /**
-   * Return the first token included in this node's source range.
-   *
-   * @return the first token or `null` if none
-   */
-  Token get beginToken;
-
-  /**
-   * Return the element associated with this node.
-   *
-   * @return the element or `null` if the receiver is not resolved
-   */
-  Element get element => _element;
-
-  /**
-   * Set the element associated with this node.
-   *
-   * @param element the element
-   */
-  void set element(Element element) {
-    this._element = element;
-  }
-
-  /**
-   * Return the offset of the character immediately following the last character of this node's
-   * source range. This is equivalent to `node.getOffset() + node.getLength()`. For an html
-   * unit this will be equal to the length of the unit's source.
-   *
-   * @return the offset of the character just past the node's source range
-   */
-  int get end => offset + length;
-
-  /**
-   * Return the last token included in this node's source range.
-   *
-   * @return the last token or `null` if none
-   */
-  Token get endToken;
-
-  /**
-   * Return the number of characters in the node's source range.
-   *
-   * @return the number of characters in the node's source range
-   */
-  int get length {
-    Token beginToken = this.beginToken;
-    Token endToken = this.endToken;
-    if (beginToken == null || endToken == null) {
-      return -1;
-    }
-    return endToken.offset + endToken.length - beginToken.offset;
-  }
-
-  /**
-   * Return the offset from the beginning of the file to the first character in the node's source
-   * range.
-   *
-   * @return the offset from the beginning of the file to the first character in the node's source
-   *         range
-   */
-  int get offset {
-    Token beginToken = this.beginToken;
-    if (beginToken == null) {
-      return -1;
-    }
-    return this.beginToken.offset;
-  }
-
-  /**
-   * Return this node's parent node, or `null` if this node is the root of an AST structure.
-   *
-   * Note that the relationship between an AST node and its parent node may change over the lifetime
-   * of a node.
-   *
-   * @return the parent of this node, or `null` if none
-   */
-  XmlNode get parent => _parent;
-
-  /**
-   * Set the parent of this node to the given node.
-   *
-   * @param newParent the node that is to be made the parent of this node
-   */
-  void set parent(XmlNode newParent) {
-    XmlNode current = newParent;
-    while (current != null) {
-      if (identical(current, this)) {
-        AnalysisEngine.instance.logger.logError(
-            "Circular structure while setting an XML node's parent",
-            new CaughtException(
-                new ArgumentError(_buildRecursiveStructureMessage(newParent)),
-                null));
-        return;
-      }
-      current = current.parent;
-    }
-    _parent = newParent;
-  }
-
-  /**
-   * Use the given visitor to visit this node.
-   *
-   * @param visitor the visitor that will visit this node
-   * @return the value returned by the visitor as a result of visiting this node
-   */
-  accept(XmlVisitor visitor);
-
-  /**
-   * Make this node the parent of the given child node.
-   *
-   * @param child the node that will become a child of this node
-   * @return the node that was made a child of this node
-   */
-  XmlNode becomeParentOf(XmlNode child) {
-    if (child != null) {
-      XmlNode node = child;
-      node.parent = this;
-    }
-    return child;
-  }
-
-  /**
-   * Make this node the parent of the given child nodes.
-   *
-   * @param children the nodes that will become the children of this node
-   * @param ifEmpty the (empty) nodes to return if "children" is empty
-   * @return the nodes that were made children of this node
-   */
-  List becomeParentOfAll(List children, {List ifEmpty}) {
-    if (children == null || children.isEmpty) {
-      if (ifEmpty != null) {
-        return ifEmpty;
-      }
-    }
-    if (children != null) {
-      children.forEach((XmlNode node) {
-        node.parent = this;
-      });
-    }
-    return children;
-  }
-
-  @override
-  String toString() {
-    PrintStringWriter writer = new PrintStringWriter();
-    accept(new ToSourceVisitor(writer));
-    return writer.toString();
-  }
-
-  /**
-   * Use the given visitor to visit all of the children of this node. The children will be visited
-   * in source order.
-   *
-   * @param visitor the visitor that will be used to visit the children of this node
-   */
-  void visitChildren(XmlVisitor visitor);
-
-  /**
-   * This method exists for debugging purposes only.
-   */
-  void _appendIdentifier(StringBuffer buffer, XmlNode node) {
-    if (node is XmlTagNode) {
-      buffer.write(node.tag);
-    } else if (node is XmlAttributeNode) {
-      buffer.write(node.name);
-    } else {
-      buffer.write("htmlUnit");
-    }
-  }
-
-  /**
-   * This method exists for debugging purposes only.
-   */
-  String _buildRecursiveStructureMessage(XmlNode newParent) {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("Attempt to create recursive structure: ");
-    XmlNode current = newParent;
-    while (current != null) {
-      if (!identical(current, newParent)) {
-        buffer.write(" -> ");
-      }
-      if (identical(current, this)) {
-        buffer.writeCharCode(0x2A);
-        _appendIdentifier(buffer, current);
-        buffer.writeCharCode(0x2A);
-      } else {
-        _appendIdentifier(buffer, current);
-      }
-      current = current.parent;
-    }
-    return buffer.toString();
-  }
-}
-
-/**
- * Instances of the class `XmlParser` are used to parse tokens into a AST structure comprised
- * of [XmlNode]s.
- */
-class XmlParser {
-  /**
-   * The source being parsed.
-   */
-  final Source source;
-
-  /**
-   * The next token to be parsed.
-   */
-  Token _currentToken;
-
-  /**
-   * Construct a parser for the specified source.
-   *
-   * @param source the source being parsed
-   */
-  XmlParser(this.source);
-
-  /**
-   * Answer the current token.
-   *
-   * @return the current token
-   */
-  Token get currentToken => _currentToken;
-
-  /**
-   * Create a node representing an attribute.
-   *
-   * @param name the name of the attribute
-   * @param equals the equals sign, or `null` if there is no value
-   * @param value the value of the attribute
-   * @return the node that was created
-   */
-  XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
-      new XmlAttributeNode(name, equals, value);
-
-  /**
-   * Create a node representing a tag.
-   *
-   * @param nodeStart the token marking the beginning of the tag
-   * @param tag the name of the tag
-   * @param attributes the attributes in the tag
-   * @param attributeEnd the token terminating the region where attributes can be
-   * @param tagNodes the children of the tag
-   * @param contentEnd the token that starts the closing tag
-   * @param closingTag the name of the tag that occurs in the closing tag
-   * @param nodeEnd the last token in the tag
-   * @return the node that was created
-   */
-  XmlTagNode createTagNode(
-          Token nodeStart,
-          Token tag,
-          List<XmlAttributeNode> attributes,
-          Token attributeEnd,
-          List<XmlTagNode> tagNodes,
-          Token contentEnd,
-          Token closingTag,
-          Token nodeEnd) =>
-      new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
-          contentEnd, closingTag, nodeEnd);
-
-  /**
-   * Answer `true` if the specified tag is self closing and thus should never have content or
-   * child tag nodes.
-   *
-   * @param tag the tag (not `null`)
-   * @return `true` if self closing
-   */
-  bool isSelfClosing(Token tag) => false;
-
-  /**
-   * Parse the entire token stream and in the process, advance the current token to the end of the
-   * token stream.
-   *
-   * @return the list of tag nodes found (not `null`, contains no `null`)
-   */
-  List<XmlTagNode> parseTopTagNodes(Token firstToken) {
-    _currentToken = firstToken;
-    List<XmlTagNode> tagNodes = new List<XmlTagNode>();
-    TokenType type = _currentToken.type;
-    while (type != TokenType.EOF) {
-      if (type == TokenType.LT) {
-        tagNodes.add(_parseTagNode());
-      } else if (type == TokenType.DECLARATION ||
-          type == TokenType.DIRECTIVE ||
-          type == TokenType.COMMENT) {
-        // ignored tokens
-        _currentToken = _currentToken.next;
-      } else {
-        _reportUnexpectedToken();
-        _currentToken = _currentToken.next;
-      }
-      type = _currentToken.type;
-    }
-    return tagNodes;
-  }
-
-  /**
-   * Insert a synthetic token of the specified type before the current token
-   *
-   * @param type the type of token to be inserted (not `null`)
-   * @return the synthetic token that was inserted (not `null`)
-   */
-  Token _insertSyntheticToken(TokenType type) {
-    Token token = new Token.con2(type, _currentToken.offset, "");
-    _currentToken.previous.setNext(token);
-    token.setNext(_currentToken);
-    return token;
-  }
-
-  /**
-   * Parse the token stream for an attribute. This method advances the current token over the
-   * attribute, but should not be called if the [currentToken] is not [TokenType.TAG].
-   *
-   * @return the attribute (not `null`)
-   */
-  XmlAttributeNode _parseAttribute() {
-    // Assume the current token is a tag
-    Token name = _currentToken;
-    _currentToken = _currentToken.next;
-    // Equals sign
-    Token equals;
-    if (_currentToken.type == TokenType.EQ) {
-      equals = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      equals = _insertSyntheticToken(TokenType.EQ);
-    }
-    // String value
-    Token value;
-    if (_currentToken.type == TokenType.STRING) {
-      value = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      value = _insertSyntheticToken(TokenType.STRING);
-    }
-    return createAttributeNode(name, equals, value);
-  }
-
-  /**
-   * Parse the stream for a sequence of attributes. This method advances the current token to the
-   * next [TokenType.GT], [TokenType.SLASH_GT], or [TokenType.EOF].
-   *
-   * @return a collection of zero or more attributes (not `null`, contains no `null`s)
-   */
-  List<XmlAttributeNode> _parseAttributes() {
-    TokenType type = _currentToken.type;
-    if (type == TokenType.GT ||
-        type == TokenType.SLASH_GT ||
-        type == TokenType.EOF) {
-      return XmlTagNode.NO_ATTRIBUTES;
-    }
-    List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
-    while (type != TokenType.GT &&
-        type != TokenType.SLASH_GT &&
-        type != TokenType.EOF) {
-      if (type == TokenType.TAG) {
-        attributes.add(_parseAttribute());
-      } else {
-        _reportUnexpectedToken();
-        _currentToken = _currentToken.next;
-      }
-      type = _currentToken.type;
-    }
-    return attributes;
-  }
-
-  /**
-   * Parse the stream for a sequence of tag nodes existing within a parent tag node. This method
-   * advances the current token to the next [TokenType.LT_SLASH] or [TokenType.EOF].
-   *
-   * @return a list of nodes (not `null`, contains no `null`s)
-   */
-  List<XmlTagNode> _parseChildTagNodes() {
-    TokenType type = _currentToken.type;
-    if (type == TokenType.LT_SLASH || type == TokenType.EOF) {
-      return XmlTagNode.NO_TAG_NODES;
-    }
-    List<XmlTagNode> nodes = new List<XmlTagNode>();
-    while (type != TokenType.LT_SLASH && type != TokenType.EOF) {
-      if (type == TokenType.LT) {
-        nodes.add(_parseTagNode());
-      } else if (type == TokenType.COMMENT) {
-        // ignored token
-        _currentToken = _currentToken.next;
-      } else {
-        _reportUnexpectedToken();
-        _currentToken = _currentToken.next;
-      }
-      type = _currentToken.type;
-    }
-    return nodes;
-  }
-
-  /**
-   * Parse the token stream for the next tag node. This method advances current token over the
-   * parsed tag node, but should only be called if the current token is [TokenType.LT]
-   *
-   * @return the tag node or `null` if none found
-   */
-  XmlTagNode _parseTagNode() {
-    // Assume that the current node is a tag node start TokenType.LT
-    Token nodeStart = _currentToken;
-    _currentToken = _currentToken.next;
-    // Get the tag or create a synthetic tag and report an error
-    Token tag;
-    if (_currentToken.type == TokenType.TAG) {
-      tag = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      tag = _insertSyntheticToken(TokenType.TAG);
-    }
-    // Parse the attributes
-    List<XmlAttributeNode> attributes = _parseAttributes();
-    // Token ending attribute list
-    Token attributeEnd;
-    if (_currentToken.type == TokenType.GT ||
-        _currentToken.type == TokenType.SLASH_GT) {
-      attributeEnd = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      attributeEnd = _insertSyntheticToken(TokenType.SLASH_GT);
-    }
-    // If the node has no children, then return the node
-    if (attributeEnd.type == TokenType.SLASH_GT || isSelfClosing(tag)) {
-      return createTagNode(nodeStart, tag, attributes, attributeEnd,
-          XmlTagNode.NO_TAG_NODES, _currentToken, null, attributeEnd);
-    }
-    // Parse the child tag nodes
-    List<XmlTagNode> tagNodes = _parseChildTagNodes();
-    // Token ending child tag nodes
-    Token contentEnd;
-    if (_currentToken.type == TokenType.LT_SLASH) {
-      contentEnd = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      // TODO (danrubel): handle self closing HTML elements by inserting
-      // synthetic tokens but not reporting an error
-      _reportUnexpectedToken();
-      contentEnd = _insertSyntheticToken(TokenType.LT_SLASH);
-    }
-    // Closing tag
-    Token closingTag;
-    if (_currentToken.type == TokenType.TAG) {
-      closingTag = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      closingTag = _insertSyntheticToken(TokenType.TAG);
-    }
-    // Token ending node
-    Token nodeEnd;
-    if (_currentToken.type == TokenType.GT) {
-      nodeEnd = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      nodeEnd = _insertSyntheticToken(TokenType.GT);
-    }
-    return createTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
-        contentEnd, closingTag, nodeEnd);
-  }
-
-  /**
-   * Report the current token as unexpected
-   */
-  void _reportUnexpectedToken() {
-    // TODO (danrubel): report unexpected token
-  }
-}
-
-/**
- * Instances of `XmlTagNode` represent XML or HTML elements such as `` and
- * `<body foo="bar"> ... </body>`.
- */
-class XmlTagNode extends XmlNode {
-  /**
-   * Constant representing empty list of attributes.
-   */
-  static List<XmlAttributeNode> NO_ATTRIBUTES =
-      new UnmodifiableListView(new List<XmlAttributeNode>());
-
-  /**
-   * Constant representing empty list of tag nodes.
-   */
-  static List<XmlTagNode> NO_TAG_NODES =
-      new UnmodifiableListView(new List<XmlTagNode>());
-
-  /**
-   * The starting [TokenType.LT] token (not `null`).
-   */
-  final Token nodeStart;
-
-  /**
-   * The [TokenType.TAG] token after the starting '&lt;' (not `null`).
-   */
-  final Token _tag;
-
-  /**
-   * The attributes contained by the receiver (not `null`, contains no `null`s).
-   */
-  List<XmlAttributeNode> _attributes;
-
-  /**
-   * The [TokenType.GT] or [TokenType.SLASH_GT] token after the attributes (not
-   * `null`). The token may be the same token as [nodeEnd] if there are no child
-   * [tagNodes].
-   */
-  final Token attributeEnd;
-
-  /**
-   * The tag nodes contained in the receiver (not `null`, contains no `null`s).
-   */
-  List<XmlTagNode> _tagNodes;
-
-  /**
-   * The token (not `null`) after the content, which may be
-   * * (1) [TokenType.LT_SLASH] for nodes with open and close tags, or
-   * * (2) the [TokenType.LT] nodeStart of the next sibling node if this node is self
-   * closing or the attributeEnd is [TokenType.SLASH_GT], or
-   * * (3) [TokenType.EOF] if the node does not have a closing tag and is the last node in
-   * the stream [TokenType.LT_SLASH] token after the content, or `null` if there is no
-   * content and the attributes ended with [TokenType.SLASH_GT].
-   */
-  final Token contentEnd;
-
-  /**
-   * The closing [TokenType.TAG] after the child elements or `null` if there is no
-   * content and the attributes ended with [TokenType.SLASH_GT]
-   */
-  final Token closingTag;
-
-  /**
-   * The ending [TokenType.GT] or [TokenType.SLASH_GT] token (not `null`).
-   */
-  final Token nodeEnd;
-
-  /**
-   * The expressions that are embedded in the tag's content.
-   */
-  List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY;
-
-  /**
-   * Construct a new instance representing an XML or HTML element
-   *
-   * @param nodeStart the starting [TokenType.LT] token (not `null`)
-   * @param tag the [TokenType.TAG] token after the starting '&lt;' (not `null`).
-   * @param attributes the attributes associated with this element or [NO_ATTRIBUTES] (not
-   *          `null`, contains no `null`s)
-   * @param attributeEnd The [TokenType.GT] or [TokenType.SLASH_GT] token after the
-   *          attributes (not `null`). The token may be the same token as [nodeEnd] if
-   *          there are no child [tagNodes].
-   * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `null`,
-   *          contains no `null`s)
-   * @param contentEnd the token (not `null`) after the content, which may be
-   *          * (1) [TokenType.LT_SLASH] for nodes with open and close tags, or
-   *          * (2) the [TokenType.LT] nodeStart of the next sibling node if this node is
-   *          self closing or the attributeEnd is [TokenType.SLASH_GT], or
-   *          * (3) [TokenType.EOF] if the node does not have a closing tag and is the last
-   *          node in the stream [TokenType.LT_SLASH] token after the content, or `null`
-   *          if there is no content and the attributes ended with [TokenType.SLASH_GT].
-   * @param closingTag the closing [TokenType.TAG] after the child elements or `null` if
-   *          there is no content and the attributes ended with [TokenType.SLASH_GT]
-   * @param nodeEnd the ending [TokenType.GT] or [TokenType.SLASH_GT] token (not
-   *          `null`)
-   */
-  XmlTagNode(
-      this.nodeStart,
-      this._tag,
-      List<XmlAttributeNode> attributes,
-      this.attributeEnd,
-      List<XmlTagNode> tagNodes,
-      this.contentEnd,
-      this.closingTag,
-      this.nodeEnd) {
-    this._attributes = becomeParentOfAll(attributes, ifEmpty: NO_ATTRIBUTES);
-    this._tagNodes = becomeParentOfAll(tagNodes, ifEmpty: NO_TAG_NODES);
-  }
-
-  /**
-   * Answer the receiver's attributes. Callers should not manipulate the returned list to edit the
-   * AST structure.
-   *
-   * @return the attributes (not `null`, contains no `null`s)
-   */
-  List<XmlAttributeNode> get attributes => _attributes;
-
-  @override
-  Token get beginToken => nodeStart;
-
-  /**
-   * Return a string representing the content contained in the receiver. This
-   * includes the textual representation of any child tag nodes ([getTagNodes]).
-   * Whitespace between '&lt;', '&lt;/', and '>', '/>' is discarded, but all
-   * other whitespace is preserved.
-   */
-  String get content {
-    Token token = attributeEnd.next;
-    if (identical(token, contentEnd)) {
-      return "";
-    }
-    // TODO(danrubel) Handle CDATA and replace HTML character encodings with
-    // the actual characters.
-    String content = token.lexeme;
-    token = token.next;
-    if (identical(token, contentEnd)) {
-      return content;
-    }
-    StringBuffer buffer = new StringBuffer();
-    buffer.write(content);
-    while (!identical(token, contentEnd)) {
-      buffer.write(token.lexeme);
-      token = token.next;
-    }
-    return buffer.toString();
-  }
-
-  @override
-  Token get endToken {
-    if (nodeEnd != null) {
-      return nodeEnd;
-    }
-    if (closingTag != null) {
-      return closingTag;
-    }
-    if (contentEnd != null) {
-      return contentEnd;
-    }
-    if (!_tagNodes.isEmpty) {
-      return _tagNodes[_tagNodes.length - 1].endToken;
-    }
-    if (attributeEnd != null) {
-      return attributeEnd;
-    }
-    if (!_attributes.isEmpty) {
-      return _attributes[_attributes.length - 1].endToken;
-    }
-    return _tag;
-  }
-
-  /**
-   * Answer the tag name after the starting '&lt;'.
-   *
-   * @return the tag name (not `null`)
-   */
-  String get tag => _tag.lexeme;
-
-  /**
-   * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
-   * to edit the AST structure.
-   *
-   * @return the children (not `null`, contains no `null`s)
-   */
-  List<XmlTagNode> get tagNodes => _tagNodes;
-
-  /**
-   * Answer the [TokenType.TAG] token after the starting '&lt;'.
-   *
-   * @return the token (not `null`)
-   */
-  Token get tagToken => _tag;
-
-  @override
-  accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this);
-
-  /**
-   * Answer the attribute with the specified name.
-   *
-   * @param name the attribute name
-   * @return the attribute or `null` if no matching attribute is found
-   */
-  XmlAttributeNode getAttribute(String name) {
-    for (XmlAttributeNode attribute in _attributes) {
-      if (attribute.name == name) {
-        return attribute;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Find the attribute with the given name (see [getAttribute] and answer the lexeme
-   * for the attribute's value token without the leading and trailing quotes (see
-   * [XmlAttributeNode.getText]).
-   *
-   * @param name the attribute name
-   * @return the attribute text or `null` if no matching attribute is found
-   */
-  String getAttributeText(String name) {
-    XmlAttributeNode attribute = getAttribute(name);
-    return attribute != null ? attribute.text : null;
-  }
-
-  @override
-  void visitChildren(XmlVisitor visitor) {
-    for (XmlAttributeNode node in _attributes) {
-      node.accept(visitor);
-    }
-    for (XmlTagNode node in _tagNodes) {
-      node.accept(visitor);
-    }
-  }
-}
-
-/**
- * The interface `XmlVisitor` defines the behavior of objects that can be used to visit an
- * [XmlNode] structure.
- */
-abstract class XmlVisitor<R> {
-  R visitHtmlScriptTagNode(HtmlScriptTagNode node);
-
-  R visitHtmlUnit(HtmlUnit htmlUnit);
-
-  R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
-
-  R visitXmlTagNode(XmlTagNode xmlTagNode);
-}
diff --git a/pkg/analyzer/lib/src/generated/incremental_logger.dart b/pkg/analyzer/lib/src/generated/incremental_logger.dart
index 8abc6fe..d942aba 100644
--- a/pkg/analyzer/lib/src/generated/incremental_logger.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_logger.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_logger;
+library analyzer.src.generated.incremental_logger;
 
 /**
  * The shared instance of [Logger] used by several incremental resolution
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
index bab107e..36d8784 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
@@ -2,10 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_resolution_validator;
+library analyzer.src.generated.incremental_resolution_validator;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 /**
  * Validates that the [actual] and the [expected] units have the same structure
@@ -63,6 +66,7 @@
   visitAssertStatement(AssertStatement node) {
     AssertStatement other = this.other;
     _visitNode(node.condition, other.condition);
+    _visitNode(node.message, other.message);
   }
 
   @override
@@ -185,6 +189,14 @@
   }
 
   @override
+  visitConfiguration(Configuration node) {
+    Configuration other = this.other;
+    _visitNode(node.name, other.name);
+    _visitNode(node.value, other.value);
+    _visitNode(node.libraryUri, other.libraryUri);
+  }
+
+  @override
   visitConstructorDeclaration(ConstructorDeclaration node) {
     ConstructorDeclaration other = this.other;
     _visitDeclaration(node, other);
@@ -238,6 +250,12 @@
   }
 
   @override
+  visitDottedName(DottedName node) {
+    DottedName other = this.other;
+    _visitList(node.components, other.components);
+  }
+
+  @override
   visitDoubleLiteral(DoubleLiteral node) {
     DoubleLiteral other = this.other;
     _visitExpression(node, other);
@@ -828,6 +846,11 @@
     if (a.nameOffset != b.nameOffset) {
       _fail('Expected: ${b.nameOffset}\n  Actual: ${a.nameOffset}');
     }
+    if (a is LocalElement && b is LocalElement) {
+      if (a.visibleRange != b.visibleRange) {
+        _fail('Expected: ${b.visibleRange}\nActual: ${a.visibleRange}');
+      }
+    }
   }
 
   void _verifyType(DartType a, DartType b) {
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index c15f247..b67b905 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -2,41 +2,33 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_resolver;
+library analyzer.src.generated.incremental_resolver;
 
 import 'dart:collection';
 import 'dart:math' as math;
 
-import 'package:analyzer/src/context/cache.dart'
-    show CacheEntry, Delta, DeltaResult;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/error_verifier.dart';
+import 'package:analyzer/src/generated/incremental_logger.dart'
+    show logger, LoggingTimer;
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart' show CONTENT, LINE_INFO;
-import 'package:analyzer/task/model.dart'
-    show AnalysisTarget, ResultDescriptor, TargetedResult, TaskDescriptor;
-
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart'
-    show
-        AnalysisContext,
-        AnalysisOptions,
-        CacheState,
-        DartEntry,
-        DataDescriptor,
-        InternalAnalysisContext,
-        RecordingErrorListener,
-        SourceEntry;
-import 'error.dart';
-import 'error_verifier.dart';
-import 'incremental_logger.dart' show logger, LoggingTimer;
-import 'java_engine.dart';
-import 'parser.dart';
-import 'resolver.dart';
-import 'scanner.dart';
-import 'source.dart';
-import 'utilities_dart.dart';
+import 'package:analyzer/task/model.dart';
 
 /**
  * If `true`, an attempt to resolve API-changing modifications is made.
@@ -56,7 +48,7 @@
  */
 class DeclarationMatcher extends RecursiveAstVisitor {
   /**
-   * The libary containing the AST nodes being visited.
+   * The library containing the AST nodes being visited.
    */
   LibraryElement _enclosingLibrary;
 
@@ -173,6 +165,8 @@
         _assertEquals(constructor.parameters.length, 0);
       }
     }
+    // matches, set the element
+    node.name.staticElement = element;
   }
 
   @override
@@ -363,11 +357,12 @@
       if (newElement != null) {
         _addedElements.add(newElement);
         if (newElement is MethodElement) {
-          List<MethodElement> methods = _enclosingClass.methods;
+          List<MethodElement> methods = _enclosingClass.methods.toList();
           methods.add(newElement);
           _enclosingClass.methods = methods;
         } else {
-          List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
+          List<PropertyAccessorElement> accessors =
+              _enclosingClass.accessors.toList();
           accessors.add(newElement);
           _enclosingClass.accessors = accessors;
         }
@@ -904,12 +899,14 @@
         isByTask(ComputeConstantDependenciesTask.DESCRIPTOR) ||
         isByTask(ComputeConstantValueTask.DESCRIPTOR) ||
         isByTask(ComputeLibraryCycleTask.DESCRIPTOR) ||
+        isByTask(ComputePropagableVariableDependenciesTask.DESCRIPTOR) ||
         isByTask(DartErrorsTask.DESCRIPTOR) ||
         isByTask(ReadyLibraryElement2Task.DESCRIPTOR) ||
         isByTask(ReadyLibraryElement5Task.DESCRIPTOR) ||
+        isByTask(ReadyLibraryElement6Task.DESCRIPTOR) ||
         isByTask(ReadyResolvedUnitTask.DESCRIPTOR) ||
-        isByTask(ReadyResolvedUnit9Task.DESCRIPTOR) ||
         isByTask(ReadyResolvedUnit10Task.DESCRIPTOR) ||
+        isByTask(ReadyResolvedUnit11Task.DESCRIPTOR) ||
         isByTask(EvaluateUnitConstantsTask.DESCRIPTOR) ||
         isByTask(GenerateHintsTask.DESCRIPTOR) ||
         isByTask(InferInstanceMembersInUnitTask.DESCRIPTOR) ||
@@ -918,9 +915,14 @@
         isByTask(LibraryUnitErrorsTask.DESCRIPTOR) ||
         isByTask(ParseDartTask.DESCRIPTOR) ||
         isByTask(PartiallyResolveUnitReferencesTask.DESCRIPTOR) ||
+        isByTask(PropagateVariableTypesInLibraryClosureTask.DESCRIPTOR) ||
+        isByTask(PropagateVariableTypesInLibraryTask.DESCRIPTOR) ||
+        isByTask(PropagateVariableTypesInUnitTask.DESCRIPTOR) ||
+        isByTask(PropagateVariableTypeTask.DESCRIPTOR) ||
         isByTask(ScanDartTask.DESCRIPTOR) ||
         isByTask(ResolveInstanceFieldsInUnitTask.DESCRIPTOR) ||
         isByTask(ResolveLibraryReferencesTask.DESCRIPTOR) ||
+        isByTask(ResolveLibraryTask.DESCRIPTOR) ||
         isByTask(ResolveLibraryTypeNamesTask.DESCRIPTOR) ||
         isByTask(ResolveUnitTask.DESCRIPTOR) ||
         isByTask(ResolveUnitTypeNamesTask.DESCRIPTOR) ||
@@ -965,11 +967,6 @@
   LibraryElementImpl _definingLibrary;
 
   /**
-   * The [DartEntry] corresponding to the source being resolved.
-   */
-  DartEntry oldEntry;
-
-  /**
    * The [CacheEntry] corresponding to the source being resolved.
    */
   CacheEntry newSourceEntry;
@@ -1025,7 +1022,6 @@
    * given source in the given library.
    */
   IncrementalResolver(
-      this.oldEntry,
       this.newSourceEntry,
       this.newUnitEntry,
       this._definingUnit,
@@ -1128,7 +1124,8 @@
    *
    * [node] - the node being tested.
    */
-  bool _canBeResolved(AstNode node) => node is ClassDeclaration ||
+  bool _canBeResolved(AstNode node) =>
+      node is ClassDeclaration ||
       node is ClassTypeAlias ||
       node is CompilationUnit ||
       node is ConstructorDeclaration ||
@@ -1237,14 +1234,6 @@
   }
 
   void _shiftEntryErrors() {
-    if (oldEntry != null) {
-      _shiftEntryErrors_OLD();
-    } else {
-      _shiftEntryErrors_NEW();
-    }
-  }
-
-  void _shiftEntryErrors_NEW() {
     _shiftErrors_NEW(HINTS);
     _shiftErrors_NEW(LINTS);
     _shiftErrors_NEW(LIBRARY_UNIT_ERRORS);
@@ -1255,13 +1244,6 @@
     _shiftErrors_NEW(VERIFY_ERRORS);
   }
 
-  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) {
       if (_alreadyShiftedErrors.add(error)) {
@@ -1278,12 +1260,6 @@
     _shiftErrors(errors);
   }
 
-  void _shiftErrors_OLD(DataDescriptor<List<AnalysisError>> descriptor) {
-    List<AnalysisError> errors =
-        oldEntry.getValueInLibrary(descriptor, _librarySource);
-    _shiftErrors(errors);
-  }
-
   void _updateCache() {
     if (newSourceEntry != null) {
       LoggingTimer timer = logger.startTimer();
@@ -1301,7 +1277,7 @@
     LoggingTimer timer = logger.startTimer();
     try {
       _definingUnit
-          .accept(new _ElementNameOffsetUpdater(_updateOffset, _updateDelta));
+          .accept(new _ElementOffsetUpdater(_updateOffset, _updateDelta));
       _definingUnit.afterIncrementalResolution();
     } finally {
       timer.stop('update element offsets');
@@ -1309,14 +1285,6 @@
   }
 
   void _updateEntry() {
-    if (oldEntry != null) {
-      _updateEntry_OLD();
-    } else {
-      _updateEntry_NEW();
-    }
-  }
-
-  void _updateEntry_NEW() {
     _updateErrors_NEW(RESOLVE_TYPE_NAMES_ERRORS, []);
     _updateErrors_NEW(RESOLVE_UNIT_ERRORS, _resolveErrors);
     _updateErrors_NEW(VARIABLE_REFERENCE_ERRORS, []);
@@ -1329,11 +1297,6 @@
     newUnitEntry.setState(LINTS, CacheState.INVALID);
   }
 
-  void _updateEntry_OLD() {
-    _updateErrors_OLD(DartEntry.RESOLUTION_ERRORS, _resolveErrors);
-    _updateErrors_OLD(DartEntry.VERIFICATION_ERRORS, _verifyErrors);
-  }
-
   List<AnalysisError> _updateErrors(
       List<AnalysisError> oldErrors, List<AnalysisError> newErrors) {
     List<AnalysisError> errors = new List<AnalysisError>();
@@ -1365,14 +1328,6 @@
     newUnitEntry.setValueIncremental(descriptor, errors, true);
   }
 
-  void _updateErrors_OLD(DataDescriptor<List<AnalysisError>> descriptor,
-      List<AnalysisError> newErrors) {
-    List<AnalysisError> oldErrors =
-        oldEntry.getValueInLibrary(descriptor, _librarySource);
-    List<AnalysisError> errors = _updateErrors(oldErrors, newErrors);
-    oldEntry.setValueInLibrary(descriptor, _librarySource, errors);
-  }
-
   void _verify(AstNode node) {
     LoggingTimer timer = logger.startTimer();
     try {
@@ -1383,7 +1338,8 @@
           _definingLibrary,
           _typeProvider,
           new InheritanceManager(_definingLibrary),
-          _context.analysisOptions.enableSuperMixins);
+          _context.analysisOptions.enableSuperMixins,
+          _context.analysisOptions.enableAssertMessage);
       if (_resolutionContext.enclosingClassDeclaration != null) {
         errorVerifier.visitClassDeclarationIncrementally(
             _resolutionContext.enclosingClassDeclaration);
@@ -1401,19 +1357,14 @@
   final Source _unitSource;
 
   /**
-   * The [DartEntry] corresponding to the source being resolved.
-   */
-  DartEntry _oldEntry;
-
-  /**
    * The [CacheEntry] corresponding to the source being resolved.
    */
-  CacheEntry _newSourceEntry;
+  CacheEntry _sourceEntry;
 
   /**
    * The [CacheEntry] corresponding to the [LibrarySpecificUnit] being resolved.
    */
-  CacheEntry _newUnitEntry;
+  CacheEntry _unitEntry;
 
   final CompilationUnit _oldUnit;
   CompilationUnitElement _unitElement;
@@ -1430,9 +1381,8 @@
   PoorMansIncrementalResolver(
       this._typeProvider,
       this._unitSource,
-      this._oldEntry,
-      this._newSourceEntry,
-      this._newUnitEntry,
+      this._sourceEntry,
+      this._unitEntry,
       this._oldUnit,
       bool resolveApiChanges) {
     _resolveApiChanges = resolveApiChanges;
@@ -1491,9 +1441,8 @@
             _shiftTokens(firstPair.oldToken);
             {
               IncrementalResolver incrementalResolver = new IncrementalResolver(
-                  _oldEntry,
-                  _newSourceEntry,
-                  _newUnitEntry,
+                  _sourceEntry,
+                  _unitEntry,
                   _unitElement,
                   _updateOffset,
                   _updateEndOld,
@@ -1588,9 +1537,8 @@
         }
         // perform incremental resolution
         IncrementalResolver incrementalResolver = new IncrementalResolver(
-            _oldEntry,
-            _newSourceEntry,
-            _newUnitEntry,
+            _sourceEntry,
+            _unitEntry,
             _unitElement,
             _updateOffset,
             _updateEndOld,
@@ -1659,9 +1607,8 @@
     NodeReplacer.replace(oldComment, newComment);
     // update elements
     IncrementalResolver incrementalResolver = new IncrementalResolver(
-        _oldEntry,
-        _newSourceEntry,
-        _newUnitEntry,
+        _sourceEntry,
+        _unitEntry,
         _unitElement,
         _updateOffset,
         _updateEndOld,
@@ -1725,26 +1672,12 @@
   }
 
   void _updateEntry() {
-    if (_oldEntry != null) {
-      _updateEntry_OLD();
-    } else {
-      _updateEntry_NEW();
-    }
-  }
-
-  void _updateEntry_NEW() {
     // scan results
-    _newSourceEntry.setValueIncremental(SCAN_ERRORS, _newScanErrors, true);
-    _newSourceEntry.setValueIncremental(LINE_INFO, _newLineInfo, false);
+    _sourceEntry.setValueIncremental(SCAN_ERRORS, _newScanErrors, true);
+    _sourceEntry.setValueIncremental(LINE_INFO, _newLineInfo, false);
     // parse results
-    _newSourceEntry.setValueIncremental(PARSE_ERRORS, _newParseErrors, true);
-    _newSourceEntry.setValueIncremental(PARSED_UNIT, _oldUnit, false);
-  }
-
-  void _updateEntry_OLD() {
-    _oldEntry.setValue(SourceEntry.LINE_INFO, _newLineInfo);
-    _oldEntry.setValue(DartEntry.SCAN_ERRORS, _newScanErrors);
-    _oldEntry.setValue(DartEntry.PARSE_ERRORS, _newParseErrors);
+    _sourceEntry.setValueIncremental(PARSE_ERRORS, _newParseErrors, true);
+    _sourceEntry.setValueIncremental(PARSED_UNIT, _oldUnit, false);
   }
 
   /**
@@ -2062,18 +1995,34 @@
  */
 class _DeclarationMismatchException {}
 
-class _ElementNameOffsetUpdater extends GeneralizingElementVisitor {
+class _ElementOffsetUpdater extends GeneralizingElementVisitor {
   final int updateOffset;
   final int updateDelta;
 
-  _ElementNameOffsetUpdater(this.updateOffset, this.updateDelta);
+  _ElementOffsetUpdater(this.updateOffset, this.updateDelta);
 
   @override
   visitElement(Element element) {
+    // name offset
     int nameOffset = element.nameOffset;
     if (nameOffset > updateOffset) {
       (element as ElementImpl).nameOffset = nameOffset + updateDelta;
     }
+    // visible range
+    if (element is LocalElement) {
+      SourceRange visibleRange = element.visibleRange;
+      if (visibleRange != null && visibleRange.offset > updateOffset) {
+        int newOffset = visibleRange.offset + updateDelta;
+        int length = visibleRange.length;
+        if (element is FunctionElementImpl) {
+          element.setVisibleRange(newOffset, length);
+        } else if (element is LocalVariableElementImpl) {
+          element.setVisibleRange(newOffset, length);
+        } else if (element is ParameterElementImpl) {
+          element.setVisibleRange(newOffset, length);
+        }
+      }
+    }
     super.visitElement(element);
   }
 }
diff --git a/pkg/analyzer/lib/src/generated/incremental_scanner.dart b/pkg/analyzer/lib/src/generated/incremental_scanner.dart
index a2e4daf..6f4abee 100644
--- a/pkg/analyzer/lib/src/generated/incremental_scanner.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_scanner.dart
@@ -2,16 +2,15 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_scanner;
+library analyzer.src.generated.incremental_scanner;
 
 import "dart:math" as math;
 
 import 'package:analyzer/src/generated/engine.dart';
-
-import 'error.dart';
-import 'scanner.dart';
-import 'source.dart';
-import 'utilities_collection.dart' show TokenMap;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
 
 /**
  * An `IncrementalScanner` is a scanner that scans a subset of a string and
diff --git a/pkg/analyzer/lib/src/generated/interner.dart b/pkg/analyzer/lib/src/generated/interner.dart
index 9ff047b..9741f28 100644
--- a/pkg/analyzer/lib/src/generated/interner.dart
+++ b/pkg/analyzer/lib/src/generated/interner.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library interner;
+library analyzer.src.generated.interner;
 
 import 'dart:collection';
 
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index 8c96357..acd2337 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -1,4 +1,8 @@
-library java.core;
+// 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 analyzer.src.generated.java_core;
 
 const int LONG_MAX_VALUE = 0x7fffffffffffffff;
 
@@ -295,14 +299,6 @@
 }
 
 class JavaSystem {
-  @deprecated
-  static void arraycopy(
-      List src, int srcPos, List dest, int destPos, int length) {
-    for (int i = 0; i < length; i++) {
-      dest[destPos + i] = src[srcPos + i];
-    }
-  }
-
   static int currentTimeMillis() {
     return (new DateTime.now()).millisecondsSinceEpoch;
   }
diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
index d0fb62b..be2020f 100644
--- a/pkg/analyzer/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine.dart
@@ -1,7 +1,11 @@
-library java.engine;
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
 
-import 'interner.dart';
-import 'java_core.dart';
+library analyzer.src.generated.java_engine;
+
+import 'package:analyzer/src/generated/interner.dart';
+import 'package:analyzer/src/generated/java_core.dart';
 
 /**
  * A predicate is a one-argument function that returns a boolean value.
@@ -97,7 +101,9 @@
       }
     } else {
       buffer.writeln(exception.toString());
-      buffer.writeln(stackTrace.toString());
+      if (stackTrace != null) {
+        buffer.writeln(stackTrace.toString());
+      }
     }
   }
 }
@@ -121,6 +127,33 @@
 
   static Interner INTERNER = new NullInterner();
 
+  /**
+   * Compute line starts for the given [content].
+   * Lines end with `\r`, `\n` or `\r\n`.
+   */
+  static List<int> computeLineStarts(String content) {
+    List<int> lineStarts = <int>[0];
+    int length = content.length;
+    int unit;
+    for (int index = 0; index < length; index++) {
+      unit = content.codeUnitAt(index);
+      // Special-case \r\n.
+      if (unit == 0x0D /* \r */) {
+        // Peek ahead to detect a following \n.
+        if ((index + 1 < length) && content.codeUnitAt(index + 1) == 0x0A) {
+          // Line start will get registered at next index at the \n.
+        } else {
+          lineStarts.add(index + 1);
+        }
+      }
+      // \n
+      if (unit == 0x0A) {
+        lineStarts.add(index + 1);
+      }
+    }
+    return lineStarts;
+  }
+
   static endsWith3(String str, int c1, int c2, int c3) {
     var length = str.length;
     return length >= 3 &&
diff --git a/pkg/analyzer/lib/src/generated/java_engine_io.dart b/pkg/analyzer/lib/src/generated/java_engine_io.dart
index 749695a..aa7023d 100644
--- a/pkg/analyzer/lib/src/generated/java_engine_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine_io.dart
@@ -1,16 +1,21 @@
-library java.engine.io;
+// 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 analyzer.src.generated.java_engine_io;
 
 import "dart:io";
-import "java_io.dart";
 
-class OSUtilities {
-  static String LINE_SEPARATOR = isWindows() ? '\r\n' : '\n';
-  static bool isWindows() => Platform.operatingSystem == 'windows';
-  static bool isMac() => Platform.operatingSystem == 'macos';
-}
+import "package:analyzer/src/generated/java_io.dart";
 
 class FileUtilities2 {
   static JavaFile createFile(String path) {
     return new JavaFile(path).getAbsoluteFile();
   }
 }
+
+class OSUtilities {
+  static String LINE_SEPARATOR = isWindows() ? '\r\n' : '\n';
+  static bool isMac() => Platform.operatingSystem == 'macos';
+  static bool isWindows() => Platform.operatingSystem == 'windows';
+}
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
index 000746f..dc054d0 100644
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_io.dart
@@ -1,11 +1,14 @@
-library java.io;
+// 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 analyzer.src.generated.java_io;
 
 import "dart:io";
 
+import 'package:analyzer/src/generated/java_core.dart' show JavaIOException;
 import 'package:path/path.dart' as path;
 
-import 'java_core.dart' show JavaIOException;
-
 class JavaFile {
   static path.Context pathContext = path.context;
   static final String separator = Platform.pathSeparator;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 76f9dc7..de0306f 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2,20 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.parser;
+library analyzer.src.generated.parser;
 
 import 'dart:collection';
 import "dart:math" as math;
 
-import 'ast.dart';
-import 'engine.dart' show AnalysisEngine, AnalysisOptionsImpl;
-import 'error.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'scanner.dart';
-import 'source.dart';
-import 'utilities_collection.dart' show TokenMap;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisEngine, AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 Map<String, MethodTrampoline> methodTable_Parser = <String, MethodTrampoline>{
   'parseCompilationUnit_1': new MethodTrampoline(
@@ -196,6 +197,8 @@
       1, (Parser target, arg0) => target._parseCommentReferences(arg0)),
   'parseCompilationUnitMember_1': new MethodTrampoline(
       1, (Parser target, arg0) => target._parseCompilationUnitMember(arg0)),
+  'parseConfiguration_0':
+      new MethodTrampoline(0, (Parser target) => target._parseConfiguration()),
   'parseConstExpression_0': new MethodTrampoline(
       0, (Parser target) => target._parseConstExpression()),
   'parseConstructor_8': new MethodTrampoline(
@@ -214,6 +217,8 @@
       0, (Parser target) => target._parseDocumentationComment()),
   'parseDoStatement_0':
       new MethodTrampoline(0, (Parser target) => target._parseDoStatement()),
+  'parseDottedName_0':
+      new MethodTrampoline(0, (Parser target) => target._parseDottedName()),
   'parseEmptyStatement_0':
       new MethodTrampoline(0, (Parser target) => target._parseEmptyStatement()),
   'parseEnumConstantDeclaration_0': new MethodTrampoline(
@@ -574,6 +579,9 @@
     if (identical(_oldNode, node.condition)) {
       return _parser.parseExpression2();
     }
+    if (identical(_oldNode, node.message)) {
+      return _parser.parseExpression2();
+    }
     return _notAChild(node);
   }
 
@@ -745,6 +753,18 @@
   }
 
   @override
+  AstNode visitConfiguration(Configuration node) {
+    if (identical(_oldNode, node.name)) {
+      throw new InsufficientContextException();
+    } else if (identical(_oldNode, node.value)) {
+      return _parser.parseStringLiteral();
+    } else if (identical(_oldNode, node.libraryUri)) {
+      return _parser.parseStringLiteral();
+    }
+    return _notAChild(node);
+  }
+
+  @override
   AstNode visitConstructorDeclaration(ConstructorDeclaration node) {
     if (identical(_oldNode, node.documentationComment)) {
       throw new InsufficientContextException();
@@ -829,6 +849,14 @@
   }
 
   @override
+  AstNode visitDottedName(DottedName node) {
+    if (node.components.contains(_oldNode)) {
+      throw new InsufficientContextException();
+    }
+    return _notAChild(node);
+  }
+
+  @override
   AstNode visitDoubleLiteral(DoubleLiteral node) => _notAChild(node);
 
   @override
@@ -2080,6 +2108,11 @@
   int _errorListenerLock = 0;
 
   /**
+   * A flag indicating whether the parser is to parse the async support.
+   */
+  bool _parseAsync = true;
+
+  /**
    * A flag indicating whether parser is to parse function bodies.
    */
   bool _parseFunctionBodies = true;
@@ -2118,11 +2151,23 @@
   bool _inInitializer = false;
 
   /**
+   * A flag indicating whether the parser is to parse conditional directives
+   * syntax.
+   */
+  bool parseConditionalDirectives = false;
+
+  /**
    * A flag indicating whether the parser is to parse generic method syntax.
    */
   bool parseGenericMethods = false;
 
   /**
+   * A flag indicating whether to parse generic method comments, of the form
+   * `/*=T*/` and `/*<T>*/`.
+   */
+  bool parseGenericMethodComments = false;
+
+  /**
    * Initialize a newly created parser to parse the content of the given
    * [_source] and to report any errors that are found to the given
    * [_errorListener].
@@ -2150,25 +2195,8 @@
   /**
    * Set whether the parser is to parse the async support.
    */
-  @deprecated
   void set parseAsync(bool parseAsync) {
-    // Async support cannot be disabled
-  }
-
-  /**
-   * Set whether the parser is to parse deferred libraries.
-   */
-  @deprecated
-  void set parseDeferredLibraries(bool parseDeferredLibraries) {
-    // Deferred libraries support cannot be disabled
-  }
-
-  /**
-   * Set whether the parser is to parse enum declarations.
-   */
-  @deprecated
-  void set parseEnum(bool parseEnum) {
-    // Enum support cannot be disabled
+    this._parseAsync = parseAsync;
   }
 
   /**
@@ -2514,7 +2542,9 @@
           parseSimpleIdentifier(),
           parseFormalParameterList());
     } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+      TypeName returnType = _parseOptionalTypeNameComment();
       SimpleIdentifier methodName = parseSimpleIdentifier();
+      TypeParameterList typeParameters = _parseGenericCommentTypeParameters();
       FormalParameterList parameters = parseFormalParameterList();
       if (_matches(TokenType.COLON) ||
           modifiers.factoryKeyword != null ||
@@ -2535,9 +2565,9 @@
           commentAndMetadata,
           modifiers.externalKeyword,
           modifiers.staticKeyword,
-          null,
+          returnType,
           methodName,
-          null,
+          typeParameters,
           parameters);
     } else if (_peek()
         .matchesAny([TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
@@ -2617,6 +2647,7 @@
       }
     } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
       SimpleIdentifier methodName = parseSimpleIdentifier();
+      TypeParameterList typeParameters = _parseGenericCommentTypeParameters();
       FormalParameterList parameters = parseFormalParameterList();
       if (methodName.name == className) {
         _reportErrorForNode(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type);
@@ -2638,7 +2669,7 @@
           modifiers.staticKeyword,
           type,
           methodName,
-          null,
+          typeParameters,
           parameters);
     } else if (parseGenericMethods && _tokenMatches(_peek(), TokenType.LT)) {
       return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
@@ -3135,10 +3166,7 @@
    *         typeParameters? formalParameterList functionExpressionBody
    */
   FunctionExpression parseFunctionExpression() {
-    TypeParameterList typeParameters = null;
-    if (parseGenericMethods && _matches(TokenType.LT)) {
-      typeParameters = parseTypeParameterList();
-    }
+    TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
     FormalParameterList parameters = parseFormalParameterList();
     _validateFormalParameterList(parameters);
     FunctionBody body =
@@ -3265,10 +3293,7 @@
       period = _expect(TokenType.PERIOD);
     }
     SimpleIdentifier identifier = parseSimpleIdentifier();
-    TypeParameterList typeParameters = null;
-    if (parseGenericMethods && _matches(TokenType.LT)) {
-      typeParameters = parseTypeParameterList();
-    }
+    TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
     if (_matches(TokenType.OPEN_PAREN)) {
       FormalParameterList parameters = parseFormalParameterList();
       if (thisKeyword == null) {
@@ -3476,21 +3501,13 @@
    *         qualified typeArguments?
    */
   TypeName parseTypeName() {
-    Identifier typeName;
-    if (_matchesKeyword(Keyword.VAR)) {
-      _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME);
-      typeName = new SimpleIdentifier(getAndAdvance());
-    } else if (_matchesIdentifier()) {
-      typeName = parsePrefixedIdentifier();
-    } else {
-      typeName = _createSyntheticIdentifier();
-      _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME);
-    }
-    TypeArgumentList typeArguments = null;
-    if (_matches(TokenType.LT)) {
-      typeArguments = parseTypeArgumentList();
-    }
-    return new TypeName(typeName, typeArguments);
+    TypeName realType = _parseTypeName();
+    // If this is followed by a generic method type comment, allow the comment
+    // type to replace the real type name.
+    // TODO(jmesserly): this feels like a big hammer. Can we restrict it to
+    // only work inside generic methods?
+    TypeName typeComment = _parseOptionalTypeNameComment();
+    return typeComment ?? realType;
   }
 
   /**
@@ -3862,6 +3879,16 @@
         index = 3;
       }
     }
+    if (StringUtilities.startsWith4(comment, index, 0x20, 0x20, 0x20, 0x20)) {
+      int end = index + 4;
+      while (end < length &&
+          comment.codeUnitAt(end) != 0xD &&
+          comment.codeUnitAt(end) != 0xA) {
+        end = end + 1;
+      }
+      ranges.add(<int>[index, end]);
+      index = end;
+    }
     while (index < length) {
       int currentChar = comment.codeUnitAt(index);
       if (currentChar == 0xD || currentChar == 0xA) {
@@ -3909,6 +3936,46 @@
     return null;
   }
 
+  bool _injectGenericComment(TokenType type, int prefixLen) {
+    if (parseGenericMethodComments) {
+      CommentToken t = _currentToken.precedingComments;
+      for (; t != null; t = t.next) {
+        if (t.type == type) {
+          String comment = t.lexeme.substring(prefixLen, t.lexeme.length - 2);
+          Token list = _scanGenericMethodComment(comment, t.offset + prefixLen);
+          if (list != null) {
+            // Insert the tokens into the stream.
+            _injectTokenList(list);
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Matches a generic comment type substitution and injects it into the token
+   * stream. Returns true if a match was injected, otherwise false.
+   *
+   * These comments are of the form `/*=T*/`, in other words, a [TypeName]
+   * inside a slash-star comment, preceded by equals sign.
+   */
+  bool _injectGenericCommentTypeAssign() {
+    return _injectGenericComment(TokenType.GENERIC_METHOD_TYPE_ASSIGN, 3);
+  }
+
+  /**
+   * Matches a generic comment type parameters and injects them into the token
+   * stream. Returns true if a match was injected, otherwise false.
+   *
+   * These comments are of the form `/*<K, V>*/`, in other words, a
+   * [TypeParameterList] or [TypeArgumentList] inside a slash-star comment.
+   */
+  bool _injectGenericCommentTypeList() {
+    return _injectGenericComment(TokenType.GENERIC_METHOD_TYPE_LIST, 2);
+  }
+
   /**
    * Inject the given [token] into the token stream immediately before the
    * current token.
@@ -3920,6 +3987,19 @@
     return token;
   }
 
+  void _injectTokenList(Token firstToken) {
+    // Scanner creates a cyclic EOF token.
+    Token lastToken = firstToken;
+    while (lastToken.next.type != TokenType.EOF) {
+      lastToken = lastToken.next;
+    }
+    // Inject these new tokens into the stream.
+    Token previous = _currentToken.previous;
+    lastToken.setNext(_currentToken);
+    previous.setNext(firstToken);
+    _currentToken = firstToken;
+  }
+
   /**
    * Return `true` if the current token appears to be the beginning of a
    * function declaration.
@@ -3994,7 +4074,8 @@
   /**
    * Return `true` if the given [character] is a valid hexadecimal digit.
    */
-  bool _isHexDigit(int character) => (0x30 <= character && character <= 0x39) ||
+  bool _isHexDigit(int character) =>
+      (0x30 <= character && character <= 0x39) ||
       (0x41 <= character && character <= 0x46) ||
       (0x61 <= character && character <= 0x66);
 
@@ -4150,6 +4231,14 @@
     return _tokenMatches(token, TokenType.OPEN_PAREN);
   }
 
+  bool _isPeekGenericTypeParametersAndOpenParen() {
+    if (!parseGenericMethods) {
+      return false;
+    }
+    Token token = _skipTypeArgumentList(_peek());
+    return token != null && _tokenMatches(token, TokenType.OPEN_PAREN);
+  }
+
   /**
    * Return `true` if the current token appears to be the beginning of a switch
    * member.
@@ -4268,7 +4357,7 @@
    */
   bool _matchesString(String identifier) =>
       _currentToken.type == TokenType.IDENTIFIER &&
-          _currentToken.lexeme == identifier;
+      _currentToken.lexeme == identifier;
 
   /**
    * If the current token has the given [type], then advance to the next token
@@ -4330,10 +4419,16 @@
       _reportErrorForNode(
           ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW, expression);
     }
+    Token comma;
+    Expression message;
+    if (_matches(TokenType.COMMA)) {
+      comma = getAndAdvance();
+      message = parseExpression2();
+    }
     Token rightParen = _expect(TokenType.CLOSE_PAREN);
     Token semicolon = _expect(TokenType.SEMICOLON);
     return new AssertStatement(
-        keyword, leftParen, expression, rightParen, semicolon);
+        keyword, leftParen, expression, comma, message, rightParen, semicolon);
   }
 
   /**
@@ -4361,10 +4456,7 @@
     bool isOptional = primaryAllowed || expression is SimpleIdentifier;
     while (true) {
       while (_isLikelyParameterList()) {
-        TypeArgumentList typeArguments = null;
-        if (_matches(TokenType.LT)) {
-          typeArguments = parseTypeArgumentList();
-        }
+        TypeArgumentList typeArguments = _parseOptionalTypeArguments();
         ArgumentList argumentList = parseArgumentList();
         if (expression is SimpleIdentifier) {
           expression = new MethodInvocation(null, null,
@@ -4573,10 +4665,7 @@
         (expression != null && functionName == null));
     if (_isLikelyParameterList()) {
       while (_isLikelyParameterList()) {
-        TypeArgumentList typeArguments = null;
-        if (_matches(TokenType.LT)) {
-          typeArguments = parseTypeArgumentList();
-        }
+        TypeArgumentList typeArguments = _parseOptionalTypeArguments();
         if (functionName != null) {
           expression = new MethodInvocation(expression, period, functionName,
               typeArguments, parseArgumentList());
@@ -4604,10 +4693,7 @@
         expression = selector;
         progress = true;
         while (_isLikelyParameterList()) {
-          TypeArgumentList typeArguments = null;
-          if (_matches(TokenType.LT)) {
-            typeArguments = parseTypeArgumentList();
-          }
+          TypeArgumentList typeArguments = _parseOptionalTypeArguments();
           if (expression is PropertyAccess) {
             PropertyAccess propertyAccess = expression as PropertyAccess;
             expression = new MethodInvocation(
@@ -4987,6 +5073,7 @@
     List<CommentReference> references = new List<CommentReference>();
     for (DocumentationCommentToken token in tokens) {
       String comment = token.lexeme;
+      comment = _removeCodeBlocksGitHub(comment);
       int length = comment.length;
       List<List<int>> codeBlockRanges = _getCodeBlockRanges(comment);
       int leftIndex = comment.indexOf('[');
@@ -5087,7 +5174,8 @@
           _peek().matchesAny([
             TokenType.OPEN_PAREN,
             TokenType.OPEN_CURLY_BRACKET,
-            TokenType.FUNCTION
+            TokenType.FUNCTION,
+            TokenType.LT
           ])) {
         _validateModifiersForTopLevelFunction(modifiers);
         return _parseFunctionDeclaration(
@@ -5148,10 +5236,14 @@
       }
       _reportErrorForToken(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken);
       return null;
-    } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
-      _validateModifiersForTopLevelFunction(modifiers);
+    } else if (_isPeekGenericTypeParametersAndOpenParen()) {
       return _parseFunctionDeclaration(
           commentAndMetadata, modifiers.externalKeyword, null);
+    } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+      TypeName returnType = _parseOptionalTypeNameComment();
+      _validateModifiersForTopLevelFunction(modifiers);
+      return _parseFunctionDeclaration(
+          commentAndMetadata, modifiers.externalKeyword, returnType);
     } else if (_peek()
         .matchesAny([TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
       if (modifiers.constKeyword == null &&
@@ -5206,7 +5298,8 @@
     if (_peek().matchesAny([
       TokenType.OPEN_PAREN,
       TokenType.FUNCTION,
-      TokenType.OPEN_CURLY_BRACKET
+      TokenType.OPEN_CURLY_BRACKET,
+      TokenType.LT
     ])) {
       _validateModifiersForTopLevelFunction(modifiers);
       return _parseFunctionDeclaration(
@@ -5221,6 +5314,52 @@
   }
 
   /**
+   * Parse a configuration in either an import or export directive.
+   *
+   *     configuration ::=
+   *         'if' '(' test ')' uri
+   *
+   *     test ::=
+   *         dottedName ('==' stringLiteral)?
+   *
+   *     dottedName ::=
+   *         identifier ('.' identifier)*
+   */
+  Configuration _parseConfiguration() {
+    Token ifKeyword = _expectKeyword(Keyword.IF);
+    Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
+    DottedName name = _parseDottedName();
+    Token equalToken = null;
+    StringLiteral value = null;
+    if (_matches(TokenType.EQ_EQ)) {
+      equalToken = getAndAdvance();
+      value = parseStringLiteral();
+      if (value is StringInterpolation) {
+        _reportErrorForNode(
+            ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION, value);
+      }
+    }
+    Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
+    StringLiteral libraryUri = _parseUri();
+    return new Configuration(ifKeyword, leftParenthesis, name, equalToken,
+        value, rightParenthesis, libraryUri);
+  }
+
+  /**
+   * Parse a list of configurations. If conditional directives are not
+   * supported, return an empty list without attempting to parse anything.
+   */
+  List<Configuration> _parseConfigurations() {
+    List<Configuration> configurations = <Configuration>[];
+    if (parseConditionalDirectives) {
+      while (_matchesKeyword(Keyword.IF)) {
+        configurations.add(_parseConfiguration());
+      }
+    }
+    return configurations;
+  }
+
+  /**
    * Parse a const expression. Return the const expression that was parsed.
    *
    *     constExpression ::=
@@ -5536,6 +5675,22 @@
   }
 
   /**
+   * Parse a dotted name. Return the dotted name that was parsed.
+   *
+   *     dottedName ::=
+   *         identifier ('.' identifier)*
+   */
+  DottedName _parseDottedName() {
+    List<SimpleIdentifier> components = new List<SimpleIdentifier>();
+    components.add(parseSimpleIdentifier());
+    while (_matches(TokenType.PERIOD)) {
+      _advance();
+      components.add(parseSimpleIdentifier());
+    }
+    return new DottedName(components);
+  }
+
+  /**
    * Parse an empty statement. Return the empty statement that was parsed.
    *
    *     emptyStatement ::=
@@ -5642,11 +5797,12 @@
    * associated with the directive. Return the export directive that was parsed.
    *
    *     exportDirective ::=
-   *         metadata 'export' stringLiteral combinator*';'
+   *         metadata 'export' stringLiteral configuration* combinator*';'
    */
   ExportDirective _parseExportDirective(CommentAndMetadata commentAndMetadata) {
     Token exportKeyword = _expectKeyword(Keyword.EXPORT);
     StringLiteral libraryUri = _parseUri();
+    List<Configuration> configurations = _parseConfigurations();
     List<Combinator> combinators = _parseCombinators();
     Token semicolon = _expectSemicolon();
     return new ExportDirective(
@@ -5654,6 +5810,7 @@
         commentAndMetadata.metadata,
         exportKeyword,
         libraryUri,
+        configurations,
         combinators,
         semicolon);
   }
@@ -5691,16 +5848,27 @@
       keyword = getAndAdvance();
       if (_isTypedIdentifier(_currentToken)) {
         type = parseTypeName();
+      } else {
+        // Support `final/*=T*/ x;`
+        type = _parseOptionalTypeNameComment();
       }
     } else if (_matchesKeyword(Keyword.VAR)) {
       keyword = getAndAdvance();
-    } else {
-      if (_isTypedIdentifier(_currentToken)) {
-        type = parseReturnType();
-      } else if (!optional) {
-        _reportErrorForCurrentToken(
-            ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE);
+      // Support `var/*=T*/ x;`
+      type = _parseOptionalTypeNameComment();
+      if (type != null) {
+        // Clear the keyword to prevent an error.
+        keyword = null;
       }
+    } else if (_isTypedIdentifier(_currentToken)) {
+      type = parseReturnType();
+    } else if (!optional) {
+      _reportErrorForCurrentToken(
+          ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE);
+    } else {
+      // Support parameters such as `(/*=K*/ key, /*=V*/ value)`
+      // This is not supported if the type is required.
+      type = _parseOptionalTypeNameComment();
     }
     return new FinalConstVarOrType(keyword, type);
   }
@@ -5931,6 +6099,9 @@
       Token star = null;
       if (_matchesString(ASYNC)) {
         keyword = getAndAdvance();
+        if (!_parseAsync) {
+          _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
+        }
         if (_matches(TokenType.STAR)) {
           star = getAndAdvance();
           _inGenerator = true;
@@ -5938,6 +6109,9 @@
         _inAsync = true;
       } else if (_matchesString(SYNC)) {
         keyword = getAndAdvance();
+        if (!_parseAsync) {
+          _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
+        }
         if (_matches(TokenType.STAR)) {
           star = getAndAdvance();
           _inGenerator = true;
@@ -6025,10 +6199,7 @@
       keyword = getAndAdvance();
     }
     SimpleIdentifier name = parseSimpleIdentifier();
-    TypeParameterList typeParameters = null;
-    if (parseGenericMethods && _matches(TokenType.LT)) {
-      typeParameters = parseTypeParameterList();
-    }
+    TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
     FormalParameterList parameters = null;
     if (!isGetter) {
       if (_matches(TokenType.OPEN_PAREN)) {
@@ -6182,6 +6353,37 @@
   }
 
   /**
+   * Parses generic type parameters from a comment.
+   *
+   * Normally this is handled by [_parseGenericMethodTypeParameters], but if the
+   * code already handles the normal generic type parameters, the comment
+   * matcher can be called directly. For example, we may have already tried
+   * matching `<` (less than sign) in a method declaration, and be currently
+   * on the `(` (open paren) because we didn't find it. In that case, this
+   * function will parse the preceding comment such as `/*<T, R>*/`.
+   */
+  TypeParameterList _parseGenericCommentTypeParameters() {
+    if (_injectGenericCommentTypeList()) {
+      return parseTypeParameterList();
+    }
+    return null;
+  }
+
+  /**
+   * Parse the generic method or function's type parameters.
+   *
+   * For backwards compatibility this can optionally use comments.
+   * See [parseGenericMethodComments].
+   */
+  TypeParameterList _parseGenericMethodTypeParameters() {
+    if (parseGenericMethods && _matches(TokenType.LT) ||
+        _injectGenericCommentTypeList()) {
+      return parseTypeParameterList();
+    }
+    return null;
+  }
+
+  /**
    * Parse a getter. The [commentAndMetadata] is the documentation comment and
    * metadata to be associated with the declaration. The externalKeyword] is the
    * 'external' token. The staticKeyword] is the static keyword, or `null` if
@@ -6270,11 +6472,12 @@
    * associated with the directive. Return the import directive that was parsed.
    *
    *     importDirective ::=
-   *         metadata 'import' stringLiteral (deferred)? ('as' identifier)? combinator*';'
+   *         metadata 'import' stringLiteral configuration* (deferred)? ('as' identifier)? combinator*';'
    */
   ImportDirective _parseImportDirective(CommentAndMetadata commentAndMetadata) {
     Token importKeyword = _expectKeyword(Keyword.IMPORT);
     StringLiteral libraryUri = _parseUri();
+    List<Configuration> configurations = _parseConfigurations();
     Token deferredToken = null;
     Token asToken = null;
     SimpleIdentifier prefix = null;
@@ -6310,6 +6513,7 @@
         commentAndMetadata.metadata,
         importKeyword,
         libraryUri,
+        configurations,
         deferredToken,
         asToken,
         prefix,
@@ -6473,10 +6677,7 @@
    *       | mapLiteral
    */
   TypedLiteral _parseListOrMapLiteral(Token modifier) {
-    TypeArgumentList typeArguments = null;
-    if (_matches(TokenType.LT)) {
-      typeArguments = parseTypeArgumentList();
-    }
+    TypeArgumentList typeArguments = _parseOptionalTypeArguments();
     if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
       return _parseMapLiteral(modifier, typeArguments);
     } else if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
@@ -6610,10 +6811,7 @@
       Token staticKeyword,
       TypeName returnType) {
     SimpleIdentifier methodName = parseSimpleIdentifier();
-    TypeParameterList typeParameters = null;
-    if (parseGenericMethods && _matches(TokenType.LT)) {
-      typeParameters = parseTypeParameterList();
-    }
+    TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
     FormalParameterList parameters;
     if (!_matches(TokenType.OPEN_PAREN) &&
         (_matches(TokenType.OPEN_CURLY_BRACKET) ||
@@ -7010,7 +7208,10 @@
    * advancing. Return the return type that was parsed.
    */
   TypeName _parseOptionalReturnType() {
-    if (_matchesKeyword(Keyword.VOID)) {
+    TypeName typeComment = _parseOptionalTypeNameComment();
+    if (typeComment != null) {
+      return typeComment;
+    } else if (_matchesKeyword(Keyword.VOID)) {
       return parseReturnType();
     } else if (_matchesIdentifier() &&
         !_matchesKeyword(Keyword.GET) &&
@@ -7030,6 +7231,24 @@
   }
 
   /**
+   * Parse a [TypeArgumentList] if present, otherwise return null.
+   * This also supports the comment form, if enabled: `/*<T>*/`
+   */
+  TypeArgumentList _parseOptionalTypeArguments() {
+    if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) {
+      return parseTypeArgumentList();
+    }
+    return null;
+  }
+
+  TypeName _parseOptionalTypeNameComment() {
+    if (_injectGenericCommentTypeAssign()) {
+      return _parseTypeName();
+    }
+    return null;
+  }
+
+  /**
    * Parse a part or part-of directive. The [commentAndMetadata] is the metadata
    * to be associated with the directive. Return the part or part-of directive
    * that was parsed.
@@ -7081,10 +7300,7 @@
         (parseGenericMethods && _matches(TokenType.LT))) {
       do {
         if (_isLikelyParameterList()) {
-          TypeArgumentList typeArguments = null;
-          if (_matches(TokenType.LT)) {
-            typeArguments = parseTypeArgumentList();
-          }
+          TypeArgumentList typeArguments = _parseOptionalTypeArguments();
           ArgumentList argumentList = parseArgumentList();
           if (operand is PropertyAccess) {
             PropertyAccess access = operand as PropertyAccess;
@@ -7741,6 +7957,21 @@
     return _parseFunctionTypeAlias(commentAndMetadata, keyword);
   }
 
+  TypeName _parseTypeName() {
+    Identifier typeName;
+    if (_matchesKeyword(Keyword.VAR)) {
+      _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME);
+      typeName = new SimpleIdentifier(getAndAdvance());
+    } else if (_matchesIdentifier()) {
+      typeName = parsePrefixedIdentifier();
+    } else {
+      typeName = _createSyntheticIdentifier();
+      _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME);
+    }
+    TypeArgumentList typeArguments = _parseOptionalTypeArguments();
+    return new TypeName(typeName, typeArguments);
+  }
+
   /**
    * Parse a unary expression. Return the unary expression that was parsed.
    *
@@ -7819,7 +8050,8 @@
    * was parsed.
    */
   StringLiteral _parseUri() {
-    bool iskeywordAfterUri(Token token) => token.lexeme == Keyword.AS.syntax ||
+    bool iskeywordAfterUri(Token token) =>
+        token.lexeme == Keyword.AS.syntax ||
         token.lexeme == _HIDE ||
         token.lexeme == _SHOW;
     if (!_matches(TokenType.STRING) &&
@@ -8041,6 +8273,25 @@
     return token;
   }
 
+  String _removeCodeBlocksGitHub(String comment) {
+    int index = 0;
+    while (true) {
+      int beginIndex = comment.indexOf('`', index);
+      if (beginIndex == -1) {
+        break;
+      }
+      int endIndex = comment.indexOf('`', beginIndex + 1);
+      if (endIndex == -1) {
+        break;
+      }
+      comment = comment.substring(0, beginIndex + 1) +
+          ' ' * (endIndex - beginIndex - 1) +
+          comment.substring(endIndex);
+      index = endIndex + 1;
+    }
+    return comment;
+  }
+
   /**
    * Report the given [error].
    */
@@ -8084,6 +8335,22 @@
   }
 
   /**
+   * Scans the generic method comment, and returns the tokens, otherwise
+   * returns null.
+   */
+  Token _scanGenericMethodComment(String code, int offset) {
+    BooleanErrorListener listener = new BooleanErrorListener();
+    Scanner scanner =
+        new Scanner(null, new SubSequenceReader(code, offset), listener);
+    scanner.setSourceStart(1, 1);
+    Token firstToken = scanner.tokenize();
+    if (listener.errorReported) {
+      return null;
+    }
+    return firstToken;
+  }
+
+  /**
    * Skips a block with all containing blocks.
    */
   void _skipBlock() {
@@ -8420,7 +8687,8 @@
    */
   Token _skipTypeArgumentList(Token startToken) {
     Token token = startToken;
-    if (!_tokenMatches(token, TokenType.LT)) {
+    if (!_tokenMatches(token, TokenType.LT) &&
+        !_injectGenericCommentTypeList()) {
       return null;
     }
     token = _skipTypeName(token.next);
@@ -8535,21 +8803,21 @@
    */
   bool _tokenMatchesIdentifier(Token token) =>
       _tokenMatches(token, TokenType.IDENTIFIER) ||
-          _tokenMatchesPseudoKeyword(token);
+      _tokenMatchesPseudoKeyword(token);
 
   /**
    * Return `true` if the given [token] matches the given [keyword].
    */
   bool _tokenMatchesKeyword(Token token, Keyword keyword) =>
       token.type == TokenType.KEYWORD &&
-          (token as KeywordToken).keyword == keyword;
+      (token as KeywordToken).keyword == keyword;
 
   /**
    * Return `true` if the given [token] matches a pseudo keyword.
    */
   bool _tokenMatchesPseudoKeyword(Token token) =>
       _tokenMatches(token, TokenType.KEYWORD) &&
-          (token as KeywordToken).keyword.isPseudoKeyword;
+      (token as KeywordToken).keyword.isPseudoKeyword;
 
   /**
    * Return `true` if the given [token] matches the given [identifier].
@@ -9110,6 +9378,13 @@
       const ParserErrorCode('ASYNC_KEYWORD_USED_AS_IDENTIFIER',
           "The keywords 'async', 'await', and 'yield' may not be used as identifiers in an asynchronous or generator function.");
 
+  /**
+   * Some environments, such as Fletch, do not support async.
+   */
+  static const CompileTimeErrorCode ASYNC_NOT_SUPPORTED =
+      const CompileTimeErrorCode('ASYNC_NOT_SUPPORTED',
+          "Async and sync are not supported in this environment.");
+
   static const ParserErrorCode BREAK_OUTSIDE_OF_LOOP = const ParserErrorCode(
       'BREAK_OUTSIDE_OF_LOOP',
       "A break statement cannot be used outside of a loop or switch statement");
@@ -9345,6 +9620,10 @@
       'INVALID_HEX_ESCAPE',
       "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
 
+  static const ParserErrorCode INVALID_LITERAL_IN_CONFIGURATION =
+      const ParserErrorCode('INVALID_LITERAL_IN_CONFIGURATION',
+          "The literal in a configuration cannot contain interpolation");
+
   static const ParserErrorCode INVALID_OPERATOR = const ParserErrorCode(
       'INVALID_OPERATOR', "The string '{0}' is not a valid operator");
 
@@ -9738,6 +10017,8 @@
         _isEqualTokens(node.assertKeyword, toNode.assertKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
         _isEqualNodes(node.condition, toNode.condition),
+        _isEqualTokens(node.comma, toNode.comma),
+        _isEqualNodes(node.message, toNode.message),
         _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
         _isEqualTokens(node.semicolon, toNode.semicolon));
   }
@@ -9933,6 +10214,22 @@
   }
 
   @override
+  bool visitConfiguration(Configuration node) {
+    Configuration toNode = this._toNode as Configuration;
+    if (_and(
+        _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
+        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+        _isEqualNodes(node.name, toNode.name),
+        _isEqualTokens(node.equalToken, toNode.equalToken),
+        _isEqualNodes(node.value, toNode.value),
+        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+        _isEqualNodes(node.libraryUri, toNode.libraryUri))) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
   bool visitConstructorDeclaration(ConstructorDeclaration node) {
     ConstructorDeclaration toNode = this._toNode as ConstructorDeclaration;
     if (_and(
@@ -10028,6 +10325,12 @@
   }
 
   @override
+  bool visitDottedName(DottedName node) {
+    DottedName toNode = this._toNode as DottedName;
+    return _isEqualNodeLists(node.components, toNode.components);
+  }
+
+  @override
   bool visitDoubleLiteral(DoubleLiteral node) {
     DoubleLiteral toNode = this._toNode as DoubleLiteral;
     if (_and(_isEqualTokens(node.literal, toNode.literal),
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 40a2162..0d856c8 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2,51 +2,33 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.resolver;
+library analyzer.src.generated.resolver;
 
 import 'dart:collection';
 
-import 'ast.dart';
-import 'constant.dart';
-import 'element.dart';
-import 'element_resolver.dart';
-import 'engine.dart';
-import 'error.dart';
-import 'error_verifier.dart';
-import 'html.dart' as ht;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'scanner.dart' as sc;
-import 'sdk.dart' show DartSdk, SdkLibrary;
-import 'source.dart';
-import 'static_type_analyzer.dart';
-import 'utilities_dart.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/error_verifier.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/static_type_analyzer.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/strong/info.dart'
+    show InferredType, StaticInfo;
 
-/**
- * Callback signature used by ImplicitConstructorBuilder to register
- * computations to be performed, and their dependencies.  A call to this
- * callback indicates that [computation] may be used to compute implicit
- * constructors for [classElement], but that the computation may not be invoked
- * until after implicit constructors have been built for [superclassElement].
- */
-typedef void ImplicitConstructorBuilderCallback(ClassElement classElement,
-    ClassElement superclassElement, void computation());
-
-typedef LibraryResolver LibraryResolverFactory(AnalysisContext context);
-
-typedef ResolverVisitor ResolverVisitorFactory(
-    Library library, Source source, TypeProvider typeProvider);
-
-typedef StaticTypeAnalyzer StaticTypeAnalyzerFactory(ResolverVisitor visitor);
-
-typedef TypeResolverVisitor TypeResolverVisitorFactory(
-    Library library, Source source, TypeProvider typeProvider);
-
-typedef void VoidFunction();
-
-typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
-
-typedef bool _SubtypeChecker<T>(T t1, T t2);
+export 'package:analyzer/src/generated/type_system.dart';
 
 /**
  * Instances of the class `BestPracticesVerifier` traverse an AST structure looking for
@@ -104,9 +86,15 @@
   }
 
   @override
+  Object visitAssertStatement(AssertStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitAssertStatement(node);
+  }
+
+  @override
   Object visitAssignmentExpression(AssignmentExpression node) {
-    sc.TokenType operatorType = node.operator.type;
-    if (operatorType == sc.TokenType.EQ) {
+    TokenType operatorType = node.operator.type;
+    if (operatorType == TokenType.EQ) {
       _checkForUseOfVoidResult(node.rightHandSide);
       _checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
     } else {
@@ -136,18 +124,42 @@
   }
 
   @override
+  Object visitConditionalExpression(ConditionalExpression node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitConditionalExpression(node);
+  }
+
+  @override
+  Object visitDoStatement(DoStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitDoStatement(node);
+  }
+
+  @override
   Object visitExportDirective(ExportDirective node) {
     _checkForDeprecatedMemberUse(node.uriElement, node);
     return super.visitExportDirective(node);
   }
 
   @override
+  Object visitForStatement(ForStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitForStatement(node);
+  }
+
+  @override
   Object visitFunctionDeclaration(FunctionDeclaration node) {
     _checkForMissingReturn(node.returnType, node.functionExpression.body);
     return super.visitFunctionDeclaration(node);
   }
 
   @override
+  Object visitIfStatement(IfStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitIfStatement(node);
+  }
+
+  @override
   Object visitImportDirective(ImportDirective node) {
     _checkForDeprecatedMemberUse(node.uriElement, node);
     ImportElement importElement = node.element;
@@ -182,10 +194,17 @@
     // This was determined to not be a good hint, see: dartbug.com/16029
     //checkForOverridingPrivateMember(node);
     _checkForMissingReturn(node.returnType, node.body);
+    _checkForUnnecessaryNoSuchMethod(node);
     return super.visitMethodDeclaration(node);
   }
 
   @override
+  Object visitMethodInvocation(MethodInvocation node) {
+    _checkForCanBeNullAfterNullAware(node.realTarget, node.operator);
+    return super.visitMethodInvocation(node);
+  }
+
+  @override
   Object visitPostfixExpression(PostfixExpression node) {
     _checkForDeprecatedMemberUse(node.bestElement, node);
     return super.visitPostfixExpression(node);
@@ -198,6 +217,12 @@
   }
 
   @override
+  Object visitPropertyAccess(PropertyAccess node) {
+    _checkForCanBeNullAfterNullAware(node.realTarget, node.operator);
+    return super.visitPropertyAccess(node);
+  }
+
+  @override
   Object visitRedirectingConstructorInvocation(
       RedirectingConstructorInvocation node) {
     _checkForDeprecatedMemberUse(node.staticElement, node);
@@ -223,6 +248,12 @@
     return super.visitVariableDeclaration(node);
   }
 
+  @override
+  Object visitWhileStatement(WhileStatement node) {
+    _checkForPossibleNullCondition(node.condition);
+    return super.visitWhileStatement(node);
+  }
+
   /**
    * Check for the passed is expression for the unnecessary type check hint codes as well as null
    * checks expressed using an is expression.
@@ -243,7 +274,7 @@
     }
     String rhsNameStr = typeName.name.name;
     // if x is dynamic
-    if (rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax) {
+    if (rhsType.isDynamic && rhsNameStr == Keyword.DYNAMIC.syntax) {
       if (node.notOperator == null) {
         // the is case
         _errorReporter.reportErrorForNode(
@@ -415,6 +446,29 @@
   }
 
   /**
+   * Produce a hint if the given [target] could have a value of `null`.
+   */
+  void _checkForCanBeNullAfterNullAware(Expression target, Token operator) {
+    if (operator?.type == TokenType.QUESTION_PERIOD) {
+      return;
+    }
+    while (target is ParenthesizedExpression) {
+      target = (target as ParenthesizedExpression).expression;
+    }
+    if (target is MethodInvocation) {
+      if (target.operator?.type == TokenType.QUESTION_PERIOD) {
+        _errorReporter.reportErrorForNode(
+            HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, target);
+      }
+    } else if (target is PropertyAccess) {
+      if (target.operator.type == TokenType.QUESTION_PERIOD) {
+        _errorReporter.reportErrorForNode(
+            HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, target);
+      }
+    }
+  }
+
+  /**
    * Given some [Element], look at the associated metadata and report the use of the member if
    * it is declared as deprecated.
    *
@@ -480,7 +534,7 @@
    */
   bool _checkForDivisionOptimizationHint(BinaryExpression node) {
     // Return if the operator is not '/'
-    if (node.operator.type != sc.TokenType.SLASH) {
+    if (node.operator.type != TokenType.SLASH) {
       return false;
     }
     // Return if the '/' operator is not defined in core, or if we don't know
@@ -619,33 +673,65 @@
   }
 
   /**
-   * Check for the passed class declaration for the
-   * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
-   *
-   * @param node the class declaration to check
-   * @return `true` if and only if a hint code is generated on the passed node
-   * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
+   * Produce a hint if the given [condition] could have a value of `null`.
    */
-//  bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
-//    ClassElement classElement = node.element;
-//    if (classElement == null) {
-//      return false;
-//    }
-//    MethodElement equalsOperatorMethodElement =
-//        classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
-//    if (equalsOperatorMethodElement != null) {
-//      PropertyAccessorElement hashCodeElement =
-//          classElement.getGetter(_HASHCODE_GETTER_NAME);
-//      if (hashCodeElement == null) {
-//        _errorReporter.reportErrorForNode(
-//            HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
-//            node.name,
-//            [classElement.displayName]);
-//        return true;
-//      }
-//    }
-//    return false;
-//  }
+  void _checkForPossibleNullCondition(Expression condition) {
+    while (condition is ParenthesizedExpression) {
+      condition = (condition as ParenthesizedExpression).expression;
+    }
+    if (condition is BinaryExpression) {
+      _checkForPossibleNullConditionInBinaryExpression(condition);
+    } else if (condition is PrefixExpression) {
+      _checkForPossibleNullConditionInPrefixExpression(condition);
+    } else {
+      _checkForPossibleNullConditionInSimpleExpression(condition);
+    }
+  }
+
+  /**
+   * Produce a hint if any of the parts of the given binary [condition] could
+   * have a value of `null`.
+   */
+  void _checkForPossibleNullConditionInBinaryExpression(
+      BinaryExpression condition) {
+    Token operator = condition.operator;
+    if (operator != null &&
+        (operator.type == TokenType.AMPERSAND_AMPERSAND ||
+            operator.type == TokenType.BAR_BAR)) {
+      _checkForPossibleNullCondition(condition.leftOperand);
+      _checkForPossibleNullCondition(condition.rightOperand);
+    }
+  }
+
+  /**
+   * Produce a hint if the operand of the given prefix [condition] could
+   * have a value of `null`.
+   */
+  void _checkForPossibleNullConditionInPrefixExpression(
+      PrefixExpression condition) {
+    if (condition.operator?.type == TokenType.BANG) {
+      _checkForPossibleNullCondition(condition.operand);
+    }
+  }
+
+  /**
+   * Produce a hint if the given [condition] could have a value of `null`.
+   */
+  void _checkForPossibleNullConditionInSimpleExpression(Expression condition) {
+    if (condition is MethodInvocation) {
+      Token operator = condition.operator;
+      if (operator != null && operator.type == TokenType.QUESTION_PERIOD) {
+        _errorReporter.reportErrorForNode(
+            HintCode.NULL_AWARE_IN_CONDITION, condition);
+      }
+    } else if (condition is PropertyAccess) {
+      Token operator = condition.operator;
+      if (operator != null && operator.type == TokenType.QUESTION_PERIOD) {
+        _errorReporter.reportErrorForNode(
+            HintCode.NULL_AWARE_IN_CONDITION, condition);
+      }
+    }
+  }
 
   /**
    * Check for the passed as expression for the [HintCode.UNNECESSARY_CAST] hint code.
@@ -697,6 +783,83 @@
   }
 
   /**
+   * Check for the passed class declaration for the
+   * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
+   *
+   * @param node the class declaration to check
+   * @return `true` if and only if a hint code is generated on the passed node
+   * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
+   */
+//  bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
+//    ClassElement classElement = node.element;
+//    if (classElement == null) {
+//      return false;
+//    }
+//    MethodElement equalsOperatorMethodElement =
+//        classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
+//    if (equalsOperatorMethodElement != null) {
+//      PropertyAccessorElement hashCodeElement =
+//          classElement.getGetter(_HASHCODE_GETTER_NAME);
+//      if (hashCodeElement == null) {
+//        _errorReporter.reportErrorForNode(
+//            HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
+//            node.name,
+//            [classElement.displayName]);
+//        return true;
+//      }
+//    }
+//    return false;
+//  }
+
+  /**
+   * Generate a hint for `noSuchMethod` methods that do nothing except of
+   * calling another `noSuchMethod` that is not defined by `Object`.
+   *
+   * @return `true` if and only if a hint code is generated on the passed node
+   * See [HintCode.UNNECESSARY_NO_SUCH_METHOD].
+   */
+  bool _checkForUnnecessaryNoSuchMethod(MethodDeclaration node) {
+    if (node.name.name != FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+      return false;
+    }
+    bool isNonObjectNoSuchMethodInvocation(Expression invocation) {
+      if (invocation is MethodInvocation &&
+          invocation.target is SuperExpression &&
+          invocation.argumentList.arguments.length == 1) {
+        SimpleIdentifier name = invocation.methodName;
+        if (name.name == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+          Element methodElement = name.staticElement;
+          Element classElement = methodElement?.enclosingElement;
+          return methodElement is MethodElement &&
+              classElement is ClassElement &&
+              !classElement.type.isObject;
+        }
+      }
+      return false;
+    }
+    FunctionBody body = node.body;
+    if (body is ExpressionFunctionBody) {
+      if (isNonObjectNoSuchMethodInvocation(body.expression)) {
+        _errorReporter.reportErrorForNode(
+            HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
+        return true;
+      }
+    } else if (body is BlockFunctionBody) {
+      List<Statement> statements = body.block.statements;
+      if (statements.length == 1) {
+        Statement returnStatement = statements.first;
+        if (returnStatement is ReturnStatement &&
+            isNonObjectNoSuchMethodInvocation(returnStatement.expression)) {
+          _errorReporter.reportErrorForNode(
+              HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
    * Check for situations where the result of a method or function is used, when it returns 'void'.
    *
    * TODO(jwren) Many other situations of use could be covered. We currently cover the cases var x =
@@ -976,8 +1139,10 @@
         result =
             _validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT);
         if (result != null) {
-          _reportErrorIfFromDeferredLibrary(element,
-              CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY);
+          _reportErrorIfFromDeferredLibrary(
+              element,
+              CompileTimeErrorCode
+                  .NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY);
         }
       }
     }
@@ -1000,8 +1165,10 @@
         DartObjectImpl valueResult = _validate(
             valueExpression, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE);
         if (valueResult != null) {
-          _reportErrorIfFromDeferredLibrary(valueExpression,
-              CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY);
+          _reportErrorIfFromDeferredLibrary(
+              valueExpression,
+              CompileTimeErrorCode
+                  .NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY);
         }
         if (keyResult != null) {
           _reportErrorIfFromDeferredLibrary(key,
@@ -1014,7 +1181,8 @@
           DartType type = keyResult.type;
           if (_implementsEqualsWhenNotAllowed(type)) {
             _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
+                CompileTimeErrorCode
+                    .CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
                 key,
                 [type.displayName]);
           }
@@ -1071,8 +1239,10 @@
         DartObjectImpl caseResult = _validate(
             expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION);
         if (caseResult != null) {
-          _reportErrorIfFromDeferredLibrary(expression,
-              CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY);
+          _reportErrorIfFromDeferredLibrary(
+              expression,
+              CompileTimeErrorCode
+                  .NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY);
           DartObject value = caseResult;
           if (firstType == null) {
             firstType = value.type;
@@ -1112,8 +1282,10 @@
       }
       _reportErrors(result.errors,
           CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
-      _reportErrorIfFromDeferredLibrary(initializer,
-          CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY);
+      _reportErrorIfFromDeferredLibrary(
+          initializer,
+          CompileTimeErrorCode
+              .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY);
     }
     return null;
   }
@@ -1206,10 +1378,14 @@
           identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM) ||
           identical(dataErrorCode,
               CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT) ||
-          identical(dataErrorCode,
-              CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH) ||
-          identical(dataErrorCode,
-              CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH) ||
+          identical(
+              dataErrorCode,
+              CheckedModeCompileTimeErrorCode
+                  .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH) ||
+          identical(
+              dataErrorCode,
+              CheckedModeCompileTimeErrorCode
+                  .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH) ||
           identical(dataErrorCode,
               CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH)) {
         _errorReporter.reportError(data);
@@ -1306,8 +1482,10 @@
           result = _validate(
               defaultValue, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE);
           if (result != null) {
-            _reportErrorIfFromDeferredLibrary(defaultValue,
-                CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY);
+            _reportErrorIfFromDeferredLibrary(
+                defaultValue,
+                CompileTimeErrorCode
+                    .NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY);
           }
         }
         VariableElementImpl element = parameter.element as VariableElementImpl;
@@ -1347,7 +1525,8 @@
                   subErrorReporter));
               if (result == null) {
                 _errorReporter.reportErrorForNode(
-                    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
+                    CompileTimeErrorCode
+                        .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
                     errorSite,
                     [variableDeclaration.name.name]);
               }
@@ -1377,8 +1556,10 @@
     _reportErrors(errorListener.errors,
         CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER);
     if (result != null) {
-      _reportErrorIfFromDeferredLibrary(expression,
-          CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY);
+      _reportErrorIfFromDeferredLibrary(
+          expression,
+          CompileTimeErrorCode
+              .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY);
     }
   }
 
@@ -1513,9 +1694,9 @@
 
   @override
   Object visitBinaryExpression(BinaryExpression node) {
-    sc.Token operator = node.operator;
-    bool isAmpAmp = operator.type == sc.TokenType.AMPERSAND_AMPERSAND;
-    bool isBarBar = operator.type == sc.TokenType.BAR_BAR;
+    Token operator = node.operator;
+    bool isAmpAmp = operator.type == TokenType.AMPERSAND_AMPERSAND;
+    bool isBarBar = operator.type == TokenType.BAR_BAR;
     if (isAmpAmp || isBarBar) {
       Expression lhsCondition = node.leftOperand;
       if (!_isDebugConstant(lhsCondition)) {
@@ -2010,7 +2191,7 @@
     ExecutableElement outerExecutable = _enclosingExecutable;
     try {
       SimpleIdentifier functionName = node.name;
-      sc.Token property = node.propertyKeyword;
+      Token property = node.propertyKeyword;
       if (property == null) {
         if (_enclosingExecutable != null) {
           _enclosingExecutable =
@@ -2020,13 +2201,18 @@
               _findIdentifier(_enclosingUnit.functions, functionName);
         }
       } else {
-        PropertyAccessorElement accessor =
-            _findIdentifier(_enclosingUnit.accessors, functionName);
-        if ((property as sc.KeywordToken).keyword == sc.Keyword.SET) {
-          accessor = accessor.variable.setter;
-          functionName.staticElement = accessor;
+        if (_enclosingExecutable != null) {
+          _enclosingExecutable =
+              _findIdentifier(_enclosingExecutable.functions, functionName);
+        } else {
+          PropertyAccessorElement accessor =
+              _findIdentifier(_enclosingUnit.accessors, functionName);
+          if ((property as KeywordToken).keyword == Keyword.SET) {
+            accessor = accessor.variable.setter;
+            functionName.staticElement = accessor;
+          }
+          _enclosingExecutable = accessor;
         }
-        _enclosingExecutable = accessor;
       }
       node.functionExpression.element = _enclosingExecutable;
       return super.visitFunctionDeclaration(node);
@@ -2115,7 +2301,7 @@
   Object visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement outerExecutable = _enclosingExecutable;
     try {
-      sc.Token property = node.propertyKeyword;
+      Token property = node.propertyKeyword;
       SimpleIdentifier methodName = node.name;
       String nameOfMethod = methodName.name;
       if (property == null) {
@@ -2125,7 +2311,7 @@
       } else {
         PropertyAccessorElement accessor =
             _findIdentifier(_enclosingClass.accessors, methodName);
-        if ((property as sc.KeywordToken).keyword == sc.Keyword.SET) {
+        if ((property as KeywordToken).keyword == Keyword.SET) {
           accessor = accessor.variable.setter;
           methodName.staticElement = accessor;
         }
@@ -2191,10 +2377,18 @@
   @override
   Object visitTypeParameter(TypeParameter node) {
     SimpleIdentifier parameterName = node.name;
-    if (_enclosingClass != null) {
-      _findIdentifier(_enclosingClass.typeParameters, parameterName);
-    } else if (_enclosingAlias != null) {
-      _findIdentifier(_enclosingAlias.typeParameters, parameterName);
+
+    Element element;
+    if (_enclosingExecutable != null) {
+      element =
+          _findIdentifier(_enclosingExecutable.typeParameters, parameterName);
+    }
+    if (element == null) {
+      if (_enclosingClass != null) {
+        _findIdentifier(_enclosingClass.typeParameters, parameterName);
+      } else if (_enclosingAlias != null) {
+        _findIdentifier(_enclosingAlias.typeParameters, parameterName);
+      }
     }
     return super.visitTypeParameter(node);
   }
@@ -2421,11 +2615,12 @@
   bool _isValidMixin = false;
 
   /**
-   * A collection holding the function types defined in a class that need to have their type
-   * arguments set to the types of the type parameters for the class, or `null` if we are not
-   * currently processing nodes within a class.
+   * A collection holding the elements defined in a class that need to have
+   * their function type fixed to take into account type parameters of the
+   * enclosing class, or `null` if we are not currently processing nodes within
+   * a class.
    */
-  List<FunctionTypeImpl> _functionTypesToFix = null;
+  List<ExecutableElementImpl> _functionTypesToFix = null;
 
   /**
    * A table mapping field names to field elements for the fields defined in the current class, or
@@ -2482,7 +2677,7 @@
   Object visitClassDeclaration(ClassDeclaration node) {
     ElementHolder holder = new ElementHolder();
     _isValidMixin = true;
-    _functionTypesToFix = new List<FunctionTypeImpl>();
+    _functionTypesToFix = new List<ExecutableElementImpl>();
     //
     // Process field declarations before constructors and methods so that field
     // formal parameters can be correctly resolved to their fields.
@@ -2508,24 +2703,22 @@
     InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
     interfaceType.typeArguments = typeArguments;
     element.type = interfaceType;
-    List<ConstructorElement> constructors = holder.constructors;
-    if (constructors.length == 0) {
-      //
-      // Create the default constructor.
-      //
-      constructors = _createDefaultConstructors(interfaceType);
-    }
-    _setDocRange(element, node);
+    element.typeParameters = typeParameters;
+    _setDoc(element, node);
     element.abstract = node.isAbstract;
     element.accessors = holder.accessors;
+    List<ConstructorElement> constructors = holder.constructors;
+    if (constructors.isEmpty) {
+      constructors = _createDefaultConstructors(element);
+    }
     element.constructors = constructors;
     element.fields = holder.fields;
     element.methods = holder.methods;
-    element.typeParameters = typeParameters;
     element.validMixin = _isValidMixin;
-    int functionTypeCount = _functionTypesToFix.length;
-    for (int i = 0; i < functionTypeCount; i++) {
-      _functionTypesToFix[i].typeArguments = typeArguments;
+    // Function types must be initialized after the enclosing element has been
+    // set, for them to pick up the type parameters.
+    for (ExecutableElementImpl e in _functionTypesToFix) {
+      e.type = new FunctionTypeImpl(e);
     }
     _functionTypesToFix = null;
     _currentHolder.addType(element);
@@ -2551,7 +2744,6 @@
   @override
   Object visitClassTypeAlias(ClassTypeAlias node) {
     ElementHolder holder = new ElementHolder();
-    _functionTypesToFix = new List<FunctionTypeImpl>();
     _visitChildren(holder, node);
     SimpleIdentifier className = node.name;
     ClassElementImpl element = new ClassElementImpl.forNode(className);
@@ -2563,11 +2755,7 @@
     InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
     interfaceType.typeArguments = typeArguments;
     element.type = interfaceType;
-    // set default constructor
-    for (FunctionTypeImpl functionType in _functionTypesToFix) {
-      functionType.typeArguments = typeArguments;
-    }
-    _functionTypesToFix = null;
+    _setDoc(element, node);
     _currentHolder.addType(element);
     className.staticElement = element;
     holder.validate();
@@ -2589,7 +2777,7 @@
     SimpleIdentifier constructorName = node.name;
     ConstructorElementImpl element =
         new ConstructorElementImpl.forNode(constructorName);
-    _setDocRange(element, node);
+    _setDoc(element, node);
     if (node.externalKeyword != null) {
       element.external = true;
     }
@@ -2694,7 +2882,7 @@
     SimpleIdentifier enumName = node.name;
     ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName);
     enumElement.enum2 = true;
-    _setDocRange(enumElement, node);
+    _setDoc(enumElement, node);
     InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement);
     enumElement.type = enumType;
     // The equivalent code for enums in the spec shows a single constructor,
@@ -2762,12 +2950,12 @@
         _inFunction = wasInFunction;
       }
       FunctionBody body = expression.body;
-      sc.Token property = node.propertyKeyword;
+      Token property = node.propertyKeyword;
       if (property == null || _inFunction) {
         SimpleIdentifier functionName = node.name;
         FunctionElementImpl element =
             new FunctionElementImpl.forNode(functionName);
-        _setDocRange(element, node);
+        _setDoc(element, node);
         if (node.externalKeyword != null) {
           element.external = true;
         }
@@ -2814,7 +3002,7 @@
         if (node.isGetter) {
           PropertyAccessorElementImpl getter =
               new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDocRange(getter, node);
+          _setDoc(getter, node);
           if (node.externalKeyword != null) {
             getter.external = true;
           }
@@ -2840,7 +3028,7 @@
         } else {
           PropertyAccessorElementImpl setter =
               new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDocRange(setter, node);
+          _setDoc(setter, node);
           if (node.externalKeyword != null) {
             setter.external = true;
           }
@@ -2857,6 +3045,9 @@
           setter.variable = variable;
           setter.setter = true;
           setter.static = true;
+          if (node.returnType == null) {
+            setter.hasImplicitReturnType = true;
+          }
           variable.setter = setter;
           variable.final2 = false;
           _currentHolder.addAccessor(setter);
@@ -2906,11 +3097,11 @@
         element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
       }
     }
-    FunctionTypeImpl type = new FunctionTypeImpl(element);
     if (_functionTypesToFix != null) {
-      _functionTypesToFix.add(type);
+      _functionTypesToFix.add(element);
+    } else {
+      element.type = new FunctionTypeImpl(element);
     }
-    element.type = type;
     element.hasImplicitReturnType = true;
     _currentHolder.addFunction(element);
     node.element = element;
@@ -2927,12 +3118,11 @@
     List<TypeParameterElement> typeParameters = holder.typeParameters;
     FunctionTypeAliasElementImpl element =
         new FunctionTypeAliasElementImpl.forNode(aliasName);
-    _setDocRange(element, node);
+    _setDoc(element, node);
     element.parameters = parameters;
     element.typeParameters = typeParameters;
-    FunctionTypeImpl type = new FunctionTypeImpl.forTypedef(element);
-    type.typeArguments = _createTypeParameterTypes(typeParameters);
-    element.type = type;
+    _createTypeParameterTypes(typeParameters);
+    element.type = new FunctionTypeImpl.forTypedef(element);
     _currentHolder.addTypeAlias(element);
     aliasName.staticElement = element;
     holder.validate();
@@ -2988,18 +3178,18 @@
         _inFunction = wasInFunction;
       }
       bool isStatic = node.isStatic;
-      sc.Token property = node.propertyKeyword;
+      Token property = node.propertyKeyword;
       FunctionBody body = node.body;
       if (property == null) {
         SimpleIdentifier methodName = node.name;
         String nameOfMethod = methodName.name;
-        if (nameOfMethod == sc.TokenType.MINUS.lexeme &&
+        if (nameOfMethod == TokenType.MINUS.lexeme &&
             node.parameters.parameters.length == 0) {
           nameOfMethod = "unary-";
         }
         MethodElementImpl element =
             new MethodElementImpl(nameOfMethod, methodName.offset);
-        _setDocRange(element, node);
+        _setDoc(element, node);
         element.abstract = node.isAbstract;
         if (node.externalKeyword != null) {
           element.external = true;
@@ -3036,7 +3226,7 @@
         if (node.isGetter) {
           PropertyAccessorElementImpl getter =
               new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDocRange(getter, node);
+          _setDoc(getter, node);
           if (node.externalKeyword != null) {
             getter.external = true;
           }
@@ -3062,7 +3252,7 @@
         } else {
           PropertyAccessorElementImpl setter =
               new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDocRange(setter, node);
+          _setDoc(setter, node);
           if (node.externalKeyword != null) {
             setter.external = true;
           }
@@ -3080,6 +3270,9 @@
           setter.abstract = node.isAbstract;
           setter.setter = true;
           setter.static = isStatic;
+          if (node.returnType == null) {
+            setter.hasImplicitReturnType = true;
+          }
           field.setter = setter;
           field.final2 = false;
           _currentHolder.addAccessor(setter);
@@ -3200,7 +3393,7 @@
       }
       element = field;
       if (node.parent.parent is FieldDeclaration) {
-        _setDocRange(element, node.parent.parent);
+        _setDoc(element, node.parent.parent);
       }
       if ((node.parent as VariableDeclarationList).type == null) {
         field.hasImplicitType = true;
@@ -3235,7 +3428,7 @@
       }
       element = variable;
       if (node.parent.parent is TopLevelVariableDeclaration) {
-        _setDocRange(element, node.parent.parent);
+        _setDoc(element, node.parent.parent);
       }
       if ((node.parent as VariableDeclarationList).type == null) {
         variable.hasImplicitType = true;
@@ -3314,14 +3507,13 @@
    * @return the [ConstructorElement]s array with the single default constructor element
    */
   List<ConstructorElement> _createDefaultConstructors(
-      InterfaceTypeImpl interfaceType) {
+      ClassElementImpl definingClass) {
     ConstructorElementImpl constructor =
         new ConstructorElementImpl.forNode(null);
     constructor.synthetic = true;
-    constructor.returnType = interfaceType;
-    FunctionTypeImpl type = new FunctionTypeImpl(constructor);
-    _functionTypesToFix.add(type);
-    constructor.type = type;
+    constructor.returnType = definingClass.type;
+    constructor.enclosingElement = definingClass;
+    constructor.type = new FunctionTypeImpl(constructor);
     return <ConstructorElement>[constructor];
   }
 
@@ -3370,12 +3562,14 @@
   }
 
   /**
-   * If the given [node] has a documentation comment, remember its range
-   * into the given [element].
+   * If the given [node] has a documentation comment, remember its content
+   * and range into the given [element].
    */
-  void _setDocRange(ElementImpl element, AnnotatedNode node) {
+  void _setDoc(ElementImpl element, AnnotatedNode node) {
     Comment comment = node.documentationComment;
     if (comment != null && comment.isDocumentation) {
+      element.documentationComment =
+          comment.tokens.map((Token t) => t.lexeme).join('\n');
       element.setDocRange(comment.offset, comment.length);
     }
   }
@@ -3995,11 +4189,11 @@
     if (_nodeExits(leftHandSide)) {
       return true;
     }
-    if (node.operator.type == sc.TokenType.QUESTION_QUESTION_EQ) {
+    if (node.operator.type == TokenType.QUESTION_QUESTION_EQ) {
       return false;
     }
     if (leftHandSide is PropertyAccess &&
-        leftHandSide.operator.type == sc.TokenType.QUESTION_PERIOD) {
+        leftHandSide.operator.type == TokenType.QUESTION_PERIOD) {
       return false;
     }
     return _nodeExits(node.rightHandSide);
@@ -4013,13 +4207,13 @@
   bool visitBinaryExpression(BinaryExpression node) {
     Expression lhsExpression = node.leftOperand;
     Expression rhsExpression = node.rightOperand;
-    sc.TokenType operatorType = node.operator.type;
+    TokenType operatorType = node.operator.type;
     // If the operator is ||, then only consider the RHS of the binary
     // expression if the left hand side is the false literal.
     // TODO(jwren) Do we want to take constant expressions into account,
     // evaluate if(false) {} differently than if(<condition>), when <condition>
     // evaluates to a constant false value?
-    if (operatorType == sc.TokenType.BAR_BAR) {
+    if (operatorType == TokenType.BAR_BAR) {
       if (lhsExpression is BooleanLiteral) {
         BooleanLiteral booleanLiteral = lhsExpression;
         if (!booleanLiteral.value) {
@@ -4030,7 +4224,7 @@
     }
     // If the operator is &&, then only consider the RHS of the binary
     // expression if the left hand side is the true literal.
-    if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) {
+    if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
       if (lhsExpression is BooleanLiteral) {
         BooleanLiteral booleanLiteral = lhsExpression;
         if (booleanLiteral.value) {
@@ -4041,7 +4235,7 @@
     }
     // If the operator is ??, then don't consider the RHS of the binary
     // expression.
-    if (operatorType == sc.TokenType.QUESTION_QUESTION) {
+    if (operatorType == TokenType.QUESTION_QUESTION) {
       return _nodeExits(lhsExpression);
     }
     return _nodeExits(lhsExpression) || _nodeExits(rhsExpression);
@@ -4242,7 +4436,7 @@
       if (target.accept(this)) {
         return true;
       }
-      if (node.operator.type == sc.TokenType.QUESTION_PERIOD) {
+      if (node.operator.type == TokenType.QUESTION_PERIOD) {
         return false;
       }
     }
@@ -4764,7 +4958,10 @@
           return;
         }
         if (parent2 is VariableDeclarationList) {
-          return;
+          // If it's a field's type, it still counts as used.
+          if (parent2.parent is! FieldDeclaration) {
+            return;
+          }
         }
       }
     }
@@ -4824,7 +5021,7 @@
     _usedImportedElementsVisitor =
         new GatherUsedImportedElementsVisitor(_library);
     _enableDart2JSHints = _context.analysisOptions.dart2jsHint;
-    _manager = new InheritanceManager(_compilationUnits[0].element.library);
+    _manager = new InheritanceManager(_library);
     _usedLocalElementsVisitor = new GatherUsedLocalElementsVisitor(_library);
   }
 
@@ -4877,438 +5074,6 @@
 }
 
 /**
- * Instances of the class {@code HtmlTagInfo} record information about the tags used in an HTML
- * file.
- */
-class HtmlTagInfo {
-  /**
-   * An array containing all of the tags used in the HTML file.
-   */
-  List<String> allTags;
-
-  /**
-   * A table mapping the id's defined in the HTML file to an array containing the names of tags with
-   * that identifier.
-   */
-  HashMap<String, String> idToTagMap;
-
-  /**
-   * A table mapping the classes defined in the HTML file to an array containing the names of tags
-   * with that class.
-   */
-  HashMap<String, List<String>> classToTagsMap;
-
-  /**
-   * Initialize a newly created information holder to hold the given information about the tags in
-   * an HTML file.
-   *
-   * @param allTags an array containing all of the tags used in the HTML file
-   * @param idToTagMap a table mapping the id's defined in the HTML file to an array containing the
-   *          names of tags with that identifier
-   * @param classToTagsMap a table mapping the classes defined in the HTML file to an array
-   *          containing the names of tags with that class
-   */
-  HtmlTagInfo(this.allTags, this.idToTagMap, this.classToTagsMap);
-
-  /**
-   * Return an array containing the tags that have the given class, or {@code null} if there are no
-   * such tags.
-   *
-   * @return an array containing the tags that have the given class
-   */
-  List<String> getTagsWithClass(String identifier) {
-    return classToTagsMap[identifier];
-  }
-
-  /**
-   * Return the tag that has the given identifier, or {@code null} if there is no such tag (the
-   * identifier is not defined).
-   *
-   * @return the tag that has the given identifier
-   */
-  String getTagWithId(String identifier) {
-    return idToTagMap[identifier];
-  }
-}
-
-/**
- * Instances of the class {@code HtmlTagInfoBuilder} gather information about the tags used in one
- * or more HTML structures.
- */
-class HtmlTagInfoBuilder implements ht.XmlVisitor {
-  /**
-   * The name of the 'id' attribute.
-   */
-  static final String ID_ATTRIBUTE = "id";
-
-  /**
-   * The name of the 'class' attribute.
-   */
-  static final String ID_CLASS = "class";
-
-  /**
-   * A set containing all of the tag names used in the HTML.
-   */
-  HashSet<String> tagSet = new HashSet<String>();
-
-  /**
-   * A table mapping the id's that are defined to the tag name with that id.
-   */
-  HashMap<String, String> idMap = new HashMap<String, String>();
-
-  /**
-   * A table mapping the classes that are defined to a set of the tag names with that class.
-   */
-  HashMap<String, HashSet<String>> classMap =
-      new HashMap<String, HashSet<String>>();
-
-  /**
-   * Initialize a newly created HTML tag info builder.
-   */
-  HtmlTagInfoBuilder();
-
-  /**
-   * Create a tag information holder holding all of the information gathered about the tags in the
-   * HTML structures that were visited.
-   *
-   * @return the information gathered about the tags in the visited HTML structures
-   */
-  HtmlTagInfo getTagInfo() {
-    List<String> allTags = tagSet.toList();
-    HashMap<String, List<String>> classToTagsMap =
-        new HashMap<String, List<String>>();
-    classMap.forEach((String key, Set<String> tags) {
-      classToTagsMap[key] = tags.toList();
-    });
-    return new HtmlTagInfo(allTags, idMap, classToTagsMap);
-  }
-
-  @override
-  visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    visitXmlTagNode(node);
-  }
-
-  @override
-  visitHtmlUnit(ht.HtmlUnit node) {
-    node.visitChildren(this);
-  }
-
-  @override
-  visitXmlAttributeNode(ht.XmlAttributeNode node) {}
-
-  @override
-  visitXmlTagNode(ht.XmlTagNode node) {
-    node.visitChildren(this);
-    String tagName = node.tag;
-    tagSet.add(tagName);
-    for (ht.XmlAttributeNode attribute in node.attributes) {
-      String attributeName = attribute.name;
-      if (attributeName == ID_ATTRIBUTE) {
-        String attributeValue = attribute.text;
-        if (attributeValue != null) {
-          String tag = idMap[attributeValue];
-          if (tag == null) {
-            idMap[attributeValue] = tagName;
-          } else {
-//            reportError(HtmlWarningCode.MULTIPLY_DEFINED_ID, valueToken);
-          }
-        }
-      } else if (attributeName == ID_CLASS) {
-        String attributeValue = attribute.text;
-        if (attributeValue != null) {
-          HashSet<String> tagList = classMap[attributeValue];
-          if (tagList == null) {
-            tagList = new HashSet<String>();
-            classMap[attributeValue] = tagList;
-          } else {
-//            reportError(HtmlWarningCode.MULTIPLY_DEFINED_ID, valueToken);
-          }
-          tagList.add(tagName);
-        }
-      }
-    }
-  }
-
-//  /**
-//   * Report an error with the given error code at the given location. Use the given arguments to
-//   * compose the error message.
-//   *
-//   * @param errorCode the error code of the error to be reported
-//   * @param offset the offset of the first character to be highlighted
-//   * @param length the number of characters to be highlighted
-//   * @param arguments the arguments used to compose the error message
-//   */
-//  private void reportError(ErrorCode errorCode, Token token, Object... arguments) {
-//    errorListener.onError(new AnalysisError(
-//        htmlElement.getSource(),
-//        token.getOffset(),
-//        token.getLength(),
-//        errorCode,
-//        arguments));
-//  }
-//
-//  /**
-//   * Report an error with the given error code at the given location. Use the given arguments to
-//   * compose the error message.
-//   *
-//   * @param errorCode the error code of the error to be reported
-//   * @param offset the offset of the first character to be highlighted
-//   * @param length the number of characters to be highlighted
-//   * @param arguments the arguments used to compose the error message
-//   */
-//  private void reportError(ErrorCode errorCode, int offset, int length, Object... arguments) {
-//    errorListener.onError(new AnalysisError(
-//        htmlElement.getSource(),
-//        offset,
-//        length,
-//        errorCode,
-//        arguments));
-//  }
-}
-
-/**
- * Instances of the class `HtmlUnitBuilder` build an element model for a single HTML unit.
- */
-class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
-  static String _SRC = "src";
-
-  /**
-   * The analysis context in which the element model will be built.
-   */
-  final InternalAnalysisContext _context;
-
-  /**
-   * The error listener to which errors will be reported.
-   */
-  RecordingErrorListener _errorListener;
-
-  /**
-   * The HTML element being built.
-   */
-  HtmlElementImpl _htmlElement;
-
-  /**
-   * The elements in the path from the HTML unit to the current tag node.
-   */
-  List<ht.XmlTagNode> _parentNodes;
-
-  /**
-   * The script elements being built.
-   */
-  List<HtmlScriptElement> _scripts;
-
-  /**
-   * A set of the libraries that were resolved while resolving the HTML unit.
-   */
-  Set<Library> _resolvedLibraries = new HashSet<Library>();
-
-  /**
-   * Initialize a newly created HTML unit builder.
-   *
-   * @param context the analysis context in which the element model will be built
-   */
-  HtmlUnitBuilder(this._context) {
-    this._errorListener = new RecordingErrorListener();
-  }
-
-  /**
-   * Return the listener to which analysis errors will be reported.
-   *
-   * @return the listener to which analysis errors will be reported
-   */
-  RecordingErrorListener get errorListener => _errorListener;
-
-  /**
-   * Return an array containing information about all of the libraries that were resolved.
-   *
-   * @return an array containing the libraries that were resolved
-   */
-  Set<Library> get resolvedLibraries => _resolvedLibraries;
-
-  /**
-   * Build the HTML element for the given source.
-   *
-   * @param source the source describing the compilation unit
-   * @param unit the AST structure representing the HTML
-   * @throws AnalysisException if the analysis could not be performed
-   */
-  HtmlElementImpl buildHtmlElement(Source source, ht.HtmlUnit unit) {
-    HtmlElementImpl result = new HtmlElementImpl(_context, source.shortName);
-    result.source = source;
-    _htmlElement = result;
-    unit.accept(this);
-    _htmlElement = null;
-    unit.element = result;
-    return result;
-  }
-
-  @override
-  Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    if (_parentNodes.contains(node)) {
-      return _reportCircularity(node);
-    }
-    _parentNodes.add(node);
-    try {
-      Source htmlSource = _htmlElement.source;
-      ht.XmlAttributeNode scriptAttribute = _getScriptSourcePath(node);
-      String scriptSourcePath =
-          scriptAttribute == null ? null : scriptAttribute.text;
-      if (node.attributeEnd.type == ht.TokenType.GT &&
-          scriptSourcePath == null) {
-        EmbeddedHtmlScriptElementImpl script =
-            new EmbeddedHtmlScriptElementImpl(node);
-        try {
-          LibraryResolver resolver = new LibraryResolver(_context);
-          LibraryElementImpl library =
-              resolver.resolveEmbeddedLibrary(htmlSource, node.script, true);
-          script.scriptLibrary = library;
-          _resolvedLibraries.addAll(resolver.resolvedLibraries);
-          _errorListener.addAll(resolver.errorListener);
-        } on AnalysisException catch (exception, stackTrace) {
-          //TODO (danrubel): Handle or forward the exception
-          AnalysisEngine.instance.logger.logError(
-              "Could not resolve script tag",
-              new CaughtException(exception, stackTrace));
-        }
-        node.scriptElement = script;
-        _scripts.add(script);
-      } else {
-        ExternalHtmlScriptElementImpl script =
-            new ExternalHtmlScriptElementImpl(node);
-        if (scriptSourcePath != null) {
-          try {
-            scriptSourcePath = Uri.encodeFull(scriptSourcePath);
-            // Force an exception to be thrown if the URI is invalid so that we
-            // can report the problem.
-            parseUriWithException(scriptSourcePath);
-            Source scriptSource =
-                _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
-            script.scriptSource = scriptSource;
-            if (!_context.exists(scriptSource)) {
-              _reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST,
-                  scriptAttribute, [scriptSourcePath]);
-            }
-          } on URISyntaxException {
-            _reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute,
-                [scriptSourcePath]);
-          }
-        }
-        node.scriptElement = script;
-        _scripts.add(script);
-      }
-    } finally {
-      _parentNodes.remove(node);
-    }
-    return null;
-  }
-
-  @override
-  Object visitHtmlUnit(ht.HtmlUnit node) {
-    _parentNodes = new List<ht.XmlTagNode>();
-    _scripts = new List<HtmlScriptElement>();
-    try {
-      node.visitChildren(this);
-      _htmlElement.scripts = new List.from(_scripts);
-    } finally {
-      _scripts = null;
-      _parentNodes = null;
-    }
-    return null;
-  }
-
-  @override
-  Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null;
-
-  @override
-  Object visitXmlTagNode(ht.XmlTagNode node) {
-    if (_parentNodes.contains(node)) {
-      return _reportCircularity(node);
-    }
-    _parentNodes.add(node);
-    try {
-      node.visitChildren(this);
-    } finally {
-      _parentNodes.remove(node);
-    }
-    return null;
-  }
-
-  /**
-   * Return the first source attribute for the given tag node, or `null` if it does not exist.
-   *
-   * @param node the node containing attributes
-   * @return the source attribute contained in the given tag
-   */
-  ht.XmlAttributeNode _getScriptSourcePath(ht.XmlTagNode node) {
-    for (ht.XmlAttributeNode attribute in node.attributes) {
-      if (attribute.name == _SRC) {
-        return attribute;
-      }
-    }
-    return null;
-  }
-
-  Object _reportCircularity(ht.XmlTagNode node) {
-    //
-    // This should not be possible, but we have an error report that suggests
-    // that it happened at least once. This code will guard against infinite
-    // recursion and might help us identify the cause of the issue.
-    //
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("Found circularity in XML nodes: ");
-    bool first = true;
-    for (ht.XmlTagNode pathNode in _parentNodes) {
-      if (first) {
-        first = false;
-      } else {
-        buffer.write(", ");
-      }
-      String tagName = pathNode.tag;
-      if (identical(pathNode, node)) {
-        buffer.write("*");
-        buffer.write(tagName);
-        buffer.write("*");
-      } else {
-        buffer.write(tagName);
-      }
-    }
-    AnalysisEngine.instance.logger.logError(buffer.toString());
-    return null;
-  }
-
-  /**
-   * Report an error with the given error code at the given location. Use the given arguments to
-   * compose the error message.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param offset the offset of the first character to be highlighted
-   * @param length the number of characters to be highlighted
-   * @param arguments the arguments used to compose the error message
-   */
-  void _reportErrorForOffset(
-      ErrorCode errorCode, int offset, int length, List<Object> arguments) {
-    _errorListener.onError(new AnalysisError(
-        _htmlElement.source, offset, length, errorCode, arguments));
-  }
-
-  /**
-   * Report an error with the given error code at the location of the value of the given attribute.
-   * Use the given arguments to compose the error message.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param offset the offset of the first character to be highlighted
-   * @param length the number of characters to be highlighted
-   * @param arguments the arguments used to compose the error message
-   */
-  void _reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute,
-      List<Object> arguments) {
-    int offset = attribute.valueToken.offset + 1;
-    int length = attribute.valueToken.length - 2;
-    _reportErrorForOffset(errorCode, offset, length, arguments);
-  }
-}
-
-/**
  * Instances of the class `ImplicitLabelScope` represent the scope statements
  * that can be the target of unlabeled break and continue statements.
  */
@@ -5628,6 +5393,234 @@
 }
 
 /**
+ * Maintains and manages contextual type information used for
+ * inferring types.
+ */
+class InferenceContext {
+  // TODO(leafp): Consider replacing these node properties with a
+  // hash table help in an instance of this class.
+  static const String _typeProperty =
+      'analyzer.src.generated.InferenceContext.contextType';
+
+  /**
+   * The error listener on which to record inference information.
+   */
+  final AnalysisErrorListener _errorListener;
+
+  /**
+   * If true, emit hints when types are inferred
+   */
+  final bool _inferenceHints;
+
+  /**
+   * Type provider, needed for type matching.
+   */
+  final TypeProvider _typeProvider;
+
+  /**
+   * The type system in use.
+   */
+  final TypeSystem _typeSystem;
+
+  /**
+   * A stack of return types for all of the enclosing
+   * functions and methods.
+   */
+  // TODO(leafp) Handle the implicit union type for Futures
+  // https://github.com/dart-lang/sdk/issues/25322
+  List<DartType> _returnStack = <DartType>[];
+
+  InferenceContext._(this._errorListener, TypeProvider typeProvider,
+      this._typeSystem, this._inferenceHints)
+      : _typeProvider = typeProvider;
+
+  /**
+   * Get the return type of the current enclosing function, if any.
+   *
+   * The type returned for a function is the type that is expected
+   * to be used in a return or yield context.  For ordinary functions
+   * this is the same as the return type of the function.  For async
+   * functions returning Future<T> and for generator functions
+   * returning Stream<T> or Iterable<T>, this is T.
+   */
+  DartType get returnContext =>
+      _returnStack.isNotEmpty ? _returnStack.last : null;
+
+  /**
+   * Match type [t1] against type [t2] as follows.
+   * If `t1 = I<dynamic, ..., dynamic>`, then look for a supertype
+   * of t1 of the form `K<S0, ..., Sm>` where `t2 = K<S0', ..., Sm'>`
+   * If the supertype exists, use the constraints `S0 <: S0', ... Sm <: Sm'`
+   * to derive a concrete instantation for I of the form `<T0, ..., Tn>`,
+   * such that `I<T0, .., Tn> <: t2`
+   */
+  List<DartType> matchTypes(DartType t1, DartType t2) =>
+      (t1 is InterfaceType && t2 is InterfaceType) ? _matchTypes(t1, t2) : null;
+
+  /**
+   * Pop a return type off of the return stack.
+   */
+  void popReturnContext() {
+    assert(_returnStack.isNotEmpty);
+    if (_returnStack.isNotEmpty) {
+      _returnStack.removeLast();
+    }
+  }
+
+  /**
+   * Push a [returnType] onto the return stack.
+   */
+  void pushReturnContext(DartType returnType) {
+    _returnStack.add(returnType);
+  }
+
+  /**
+   * Place an info node into the error stream indicating that a
+   * [type] has been inferred as the type of [node].
+   */
+  void recordInference(Expression node, DartType type) {
+    StaticInfo info = InferredType.create(_typeSystem, node, type);
+    if (!_inferenceHints || info == null) {
+      return;
+    }
+    AnalysisError error = info.toAnalysisError();
+    _errorListener.onError(error);
+  }
+
+  List<DartType> _matchTypes(InterfaceType t1, InterfaceType t2) {
+    if (t1 == t2) {
+      return t2.typeArguments;
+    }
+    List<DartType> tArgs1 = t1.typeArguments;
+    List<DartType> tArgs2 = t2.typeArguments;
+    // If t1 isn't a raw type, bail out
+    if (tArgs1 != null && tArgs1.any((t) => !t.isDynamic)) {
+      return null;
+    }
+
+    // This is our inferred type argument list.  We start at all dynamic,
+    // and fill in with inferred types when we reach a match.
+    List<DartType> actuals =
+        new List<DartType>.filled(tArgs1.length, _typeProvider.dynamicType);
+
+    // When we find the supertype of t1 with the same
+    // classname as t2 (see below), we have the following:
+    // If t1 is an instantiation of a class T1<X0, ..., Xn>
+    // and t2 is an instantiation of a class T2<Y0, ...., Ym>
+    // of the form t2 = T2<S0, ..., Sm>
+    // then we want to choose instantiations for the Xi
+    // T0, ..., Tn such that T1<T0, ..., Tn> <: t2 .
+    // To find this, we simply instantate T1 with
+    // X0, ..., Xn, and then find its superclass
+    // T2<T0', ..., Tn'>.  We then solve the constraint
+    // set T0' <: S0, ..., Tn' <: Sn for the Xi.
+    // Currently, we only handle constraints where
+    // the Ti' is one of the Xi'.  If there are multiple
+    // constraints on some Xi, we choose the lower of the
+    // two (if it exists).
+    bool permute(List<DartType> permutedArgs) {
+      if (permutedArgs == null) {
+        return false;
+      }
+      List<TypeParameterElement> ps = t1.typeParameters;
+      List<DartType> ts = ps.map((p) => p.type).toList();
+      for (int i = 0; i < permutedArgs.length; i++) {
+        DartType tVar = permutedArgs[i];
+        DartType tActual = tArgs2[i];
+        int index = ts.indexOf(tVar);
+        if (index >= 0 && _typeSystem.isSubtypeOf(tActual, actuals[index])) {
+          actuals[index] = tActual;
+        }
+      }
+      return actuals.any((x) => !x.isDynamic);
+    }
+
+    // Look for the first supertype of t1 with the same class name as t2.
+    bool match(InterfaceType t1, Set<Element> visited) {
+      if (t1.element == t2.element) {
+        return permute(t1.typeArguments);
+      }
+
+      if (t1 == _typeProvider.objectType) {
+        return false;
+      }
+
+      Element element = t1.element;
+      if (visited == null) {
+        visited = new HashSet<Element>();
+      }
+      if (element == null || !visited.add(element)) {
+        return false;
+      }
+      try {
+        if (match(t1.superclass, visited)) {
+          return true;
+        }
+
+        for (final parent in t1.mixins) {
+          if (match(parent, visited)) {
+            return true;
+          }
+        }
+
+        for (final parent in t1.interfaces) {
+          if (match(parent, visited)) {
+            return true;
+          }
+        }
+      } finally {
+        visited.remove(element);
+      }
+      return false;
+    }
+
+    // We have that t1 = T1<dynamic, ..., dynamic>.
+    // To match t1 against t2, we use the uninstantiated version
+    // of t1, essentially treating it as an instantiation with
+    // fresh variables, and solve for the variables.
+    // t1.element.type will be of the form T1<X0, ..., Xn>
+    if (!match(t1.element.type, null)) {
+      return null;
+    }
+    DartType newT1 = t1.element.type.substitute4(actuals);
+    // If we found a solution, return it.
+    if (_typeSystem.isSubtypeOf(newT1, t2)) {
+      return actuals;
+    }
+    return null;
+  }
+
+  /**
+   * Clear the type information assocated with [node].
+   */
+  static void clearType(AstNode node) {
+    node?.setProperty(_typeProperty, null);
+  }
+
+  /**
+   * Look for contextual type information attached to [node].  Returns
+   * the type if found, otherwise null.
+   */
+  static DartType getType(AstNode node) => node?.getProperty(_typeProperty);
+
+  /**
+   * Attach contextual type information [type] to [node] for use during
+   * inference.
+   */
+  static void setType(AstNode node, DartType type) {
+    node?.setProperty(_typeProperty, type);
+  }
+
+  /**
+   * Attach contextual type information [type] to [node] for use during
+   * inference.
+   */
+  static void setTypeFromNode(AstNode innerNode, AstNode outerNode) {
+    setType(innerNode, getType(outerNode));
+  }
+}
+
+/**
  * Instances of the class `InheritanceManager` manage the knowledge of where class members
  * (methods, getters & setters) are inherited from.
  */
@@ -5725,8 +5718,9 @@
     if (memberName == null || memberName.isEmpty) {
       return null;
     }
-    ExecutableElement executable = _computeClassChainLookupMap(
-        classElt, new HashSet<ClassElement>()).get(memberName);
+    ExecutableElement executable =
+        _computeClassChainLookupMap(classElt, new HashSet<ClassElement>())
+            .get(memberName);
     if (executable == null) {
       return _computeInterfaceLookupMap(classElt, new HashSet<ClassElement>())
           .get(memberName);
@@ -5753,28 +5747,6 @@
   }
 
   /**
-   * Given some [InterfaceType] and some member name, this returns the
-   * [FunctionType] of the [ExecutableElement] that the
-   * class either declares itself, or inherits, that has the member name, if no member is inherited
-   * `null` is returned. The returned [FunctionType] has all type
-   * parameters substituted with corresponding type arguments from the given [InterfaceType].
-   *
-   * @param interfaceType the interface type to query
-   * @param memberName the name of the executable element to find and return
-   * @return the member's function type, or `null` if no such member exists
-   */
-  FunctionType lookupMemberType(
-      InterfaceType interfaceType, String memberName) {
-    ExecutableElement iteratorMember =
-        lookupMember(interfaceType.element, memberName);
-    if (iteratorMember == null) {
-      return null;
-    }
-    return substituteTypeArgumentsInMemberFromInheritance(
-        iteratorMember.type, memberName, interfaceType);
-  }
-
-  /**
    * Determine the set of methods which is overridden by the given class member. If no member is
    * inherited, an empty list is returned. If one of the inherited members is a
    * [MultiplyInheritedExecutableElement], then it is expanded into its constituent inherited
@@ -5822,6 +5794,9 @@
    * @param definingType the type that is overriding the member
    * @return the passed function type with any parameterized types substituted
    */
+  // TODO(jmesserly): investigate why this is needed in ErrorVerifier's override
+  // checking. There seems to be some rare cases where we get partially
+  // substituted type arguments, and the function types don't compare equally.
   FunctionType substituteTypeArgumentsInMemberFromInheritance(
       FunctionType baseFunctionType,
       String memberName,
@@ -6400,8 +6375,9 @@
               // Tests: test_getMapOfMembersInheritedFromInterfaces_
               // union_multipleSubtypes_*
               //
-              List<ExecutableElement> elementArrayToMerge = new List<
-                  ExecutableElement>(subtypesOfAllOtherTypesIndexes.length);
+              List<ExecutableElement> elementArrayToMerge =
+                  new List<ExecutableElement>(
+                      subtypesOfAllOtherTypesIndexes.length);
               for (int i = 0; i < elementArrayToMerge.length; i++) {
                 elementArrayToMerge[i] =
                     elements[subtypesOfAllOtherTypesIndexes[i]];
@@ -6416,7 +6392,8 @@
               classElt,
               classElt.nameOffset,
               classElt.nameLength,
-              StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+              StaticWarningCode
+                  .INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
               [key]);
         }
       }
@@ -6563,8 +6540,8 @@
       int numOfPositionalParameters,
       List<String> namedParameters) {
     DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
-    SimpleIdentifier nameIdentifier = new SimpleIdentifier(
-        new sc.StringToken(sc.TokenType.IDENTIFIER, name, 0));
+    SimpleIdentifier nameIdentifier =
+        new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, 0));
     ExecutableElementImpl executable;
     if (elementArrayToMerge[0] is MethodElement) {
       MultiplyInheritedMethodElementImpl unionedMethod =
@@ -6653,7 +6630,7 @@
   static int _getNumOfPositionalParameters(
           ExecutableElement executableElement) =>
       _getNumOfParameters(executableElement, ParameterKind.REQUIRED) +
-          _getNumOfParameters(executableElement, ParameterKind.POSITIONAL);
+      _getNumOfParameters(executableElement, ParameterKind.POSITIONAL);
 
   /**
    * Given some [ExecutableElement] return the number of required parameters.
@@ -6753,652 +6730,6 @@
 }
 
 /**
- * Instances of the class `Library` represent the data about a single library during the
- * resolution of some (possibly different) library. They are not intended to be used except during
- * the resolution process.
- */
-class Library {
-  /**
-   * An empty list that can be used to initialize lists of libraries.
-   */
-  static const List<Library> _EMPTY_ARRAY = const <Library>[];
-
-  /**
-   * The prefix of a URI using the dart-ext scheme to reference a native code library.
-   */
-  static String _DART_EXT_SCHEME = "dart-ext:";
-
-  /**
-   * The analysis context in which this library is being analyzed.
-   */
-  final InternalAnalysisContext _analysisContext;
-
-  /**
-   * The inheritance manager which is used for this member lookups in this library.
-   */
-  InheritanceManager _inheritanceManager;
-
-  /**
-   * The listener to which analysis errors will be reported.
-   */
-  final AnalysisErrorListener errorListener;
-
-  /**
-   * The source specifying the defining compilation unit of this library.
-   */
-  final Source librarySource;
-
-  /**
-   * The library element representing this library.
-   */
-  LibraryElementImpl _libraryElement;
-
-  /**
-   * A list containing all of the libraries that are imported into this library.
-   */
-  List<Library> _importedLibraries = _EMPTY_ARRAY;
-
-  /**
-   * A table mapping URI-based directive to the actual URI value.
-   */
-  HashMap<UriBasedDirective, String> _directiveUris =
-      new HashMap<UriBasedDirective, String>();
-
-  /**
-   * A flag indicating whether this library explicitly imports core.
-   */
-  bool explicitlyImportsCore = false;
-
-  /**
-   * A list containing all of the libraries that are exported from this library.
-   */
-  List<Library> _exportedLibraries = _EMPTY_ARRAY;
-
-  /**
-   * A table mapping the sources for the compilation units in this library to their corresponding
-   * AST structures.
-   */
-  HashMap<Source, CompilationUnit> _astMap =
-      new HashMap<Source, CompilationUnit>();
-
-  /**
-   * The library scope used when resolving elements within this library's compilation units.
-   */
-  LibraryScope _libraryScope;
-
-  /**
-   * Initialize a newly created data holder that can maintain the data associated with a library.
-   *
-   * @param analysisContext the analysis context in which this library is being analyzed
-   * @param errorListener the listener to which analysis errors will be reported
-   * @param librarySource the source specifying the defining compilation unit of this library
-   */
-  Library(this._analysisContext, this.errorListener, this.librarySource) {
-    this._libraryElement =
-        _analysisContext.getLibraryElement(librarySource) as LibraryElementImpl;
-  }
-
-  /**
-   * Return an array of the [CompilationUnit]s that make up the library. The first unit is
-   * always the defining unit.
-   *
-   * @return an array of the [CompilationUnit]s that make up the library. The first unit is
-   *         always the defining unit
-   */
-  List<CompilationUnit> get compilationUnits {
-    List<CompilationUnit> unitArrayList = new List<CompilationUnit>();
-    unitArrayList.add(definingCompilationUnit);
-    for (Source source in _astMap.keys.toSet()) {
-      if (librarySource != source) {
-        unitArrayList.add(getAST(source));
-      }
-    }
-    return unitArrayList;
-  }
-
-  /**
-   * Return a collection containing the sources for the compilation units in this library, including
-   * the defining compilation unit.
-   *
-   * @return the sources for the compilation units in this library
-   */
-  Set<Source> get compilationUnitSources => _astMap.keys.toSet();
-
-  /**
-   * Return the AST structure associated with the defining compilation unit for this library.
-   *
-   * @return the AST structure associated with the defining compilation unit for this library
-   * @throws AnalysisException if an AST structure could not be created for the defining compilation
-   *           unit
-   */
-  CompilationUnit get definingCompilationUnit => getAST(librarySource);
-
-  /**
-   * Set the libraries that are exported by this library to be those in the given array.
-   *
-   * @param exportedLibraries the libraries that are exported by this library
-   */
-  void set exportedLibraries(List<Library> exportedLibraries) {
-    this._exportedLibraries = exportedLibraries;
-  }
-
-  /**
-   * Return an array containing the libraries that are exported from this library.
-   *
-   * @return an array containing the libraries that are exported from this library
-   */
-  List<Library> get exports => _exportedLibraries;
-
-  /**
-   * Set the libraries that are imported into this library to be those in the given array.
-   *
-   * @param importedLibraries the libraries that are imported into this library
-   */
-  void set importedLibraries(List<Library> importedLibraries) {
-    this._importedLibraries = importedLibraries;
-  }
-
-  /**
-   * Return an array containing the libraries that are imported into this library.
-   *
-   * @return an array containing the libraries that are imported into this library
-   */
-  List<Library> get imports => _importedLibraries;
-
-  /**
-   * Return an array containing the libraries that are either imported or exported from this
-   * library.
-   *
-   * @return the libraries that are either imported or exported from this library
-   */
-  List<Library> get importsAndExports {
-    HashSet<Library> libraries = new HashSet<Library>();
-    for (Library library in _importedLibraries) {
-      libraries.add(library);
-    }
-    for (Library library in _exportedLibraries) {
-      libraries.add(library);
-    }
-    return new List.from(libraries);
-  }
-
-  /**
-   * Return the inheritance manager for this library.
-   *
-   * @return the inheritance manager for this library
-   */
-  InheritanceManager get inheritanceManager {
-    if (_inheritanceManager == null) {
-      return _inheritanceManager = new InheritanceManager(_libraryElement);
-    }
-    return _inheritanceManager;
-  }
-
-  /**
-   * Return the library element representing this library, creating it if necessary.
-   *
-   * @return the library element representing this library
-   */
-  LibraryElementImpl get libraryElement {
-    if (_libraryElement == null) {
-      try {
-        _libraryElement = _analysisContext.computeLibraryElement(librarySource)
-            as LibraryElementImpl;
-      } on AnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logError(
-            "Could not compute library element for ${librarySource.fullName}",
-            new CaughtException(exception, stackTrace));
-      }
-    }
-    return _libraryElement;
-  }
-
-  /**
-   * Set the library element representing this library to the given library element.
-   *
-   * @param libraryElement the library element representing this library
-   */
-  void set libraryElement(LibraryElementImpl libraryElement) {
-    this._libraryElement = libraryElement;
-    if (_inheritanceManager != null) {
-      _inheritanceManager.libraryElement = libraryElement;
-    }
-  }
-
-  /**
-   * Return the library scope used when resolving elements within this library's compilation units.
-   *
-   * @return the library scope used when resolving elements within this library's compilation units
-   */
-  LibraryScope get libraryScope {
-    if (_libraryScope == null) {
-      _libraryScope = new LibraryScope(_libraryElement, errorListener);
-    }
-    return _libraryScope;
-  }
-
-  /**
-   * Return the AST structure associated with the given source.
-   *
-   * @param source the source representing the compilation unit whose AST is to be returned
-   * @return the AST structure associated with the given source
-   * @throws AnalysisException if an AST structure could not be created for the compilation unit
-   */
-  CompilationUnit getAST(Source source) {
-    CompilationUnit unit = _astMap[source];
-    if (unit == null) {
-      unit = _analysisContext.computeResolvableCompilationUnit(source);
-      _astMap[source] = unit;
-    }
-    return unit;
-  }
-
-  /**
-   * Return the result of resolving the URI of the given URI-based directive against the URI of the
-   * library, or `null` if the URI is not valid. If the URI is not valid, report the error.
-   *
-   * @param directive the directive which URI should be resolved
-   * @return the result of resolving the URI against the URI of the library
-   */
-  Source getSource(UriBasedDirective directive) {
-    StringLiteral uriLiteral = directive.uri;
-    if (uriLiteral is StringInterpolation) {
-      errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
-          uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION));
-      return null;
-    }
-    String uriContent = uriLiteral.stringValue.trim();
-    _directiveUris[directive] = uriContent;
-    uriContent = Uri.encodeFull(uriContent);
-    if (directive is ImportDirective &&
-        uriContent.startsWith(_DART_EXT_SCHEME)) {
-      _libraryElement.hasExtUri = true;
-      return null;
-    }
-    try {
-      parseUriWithException(uriContent);
-      Source source =
-          _analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
-      if (!_analysisContext.exists(source)) {
-        errorListener.onError(new AnalysisError(
-            librarySource,
-            uriLiteral.offset,
-            uriLiteral.length,
-            CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-            [uriContent]));
-      }
-      return source;
-    } on URISyntaxException {
-      errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
-          uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
-    }
-    return null;
-  }
-
-  /**
-   * Returns the URI value of the given directive.
-   */
-  String getUri(UriBasedDirective directive) => _directiveUris[directive];
-
-  /**
-   * Set the AST structure associated with the defining compilation unit for this library to the
-   * given AST structure.
-   *
-   * @param unit the AST structure associated with the defining compilation unit for this library
-   */
-  void setDefiningCompilationUnit(CompilationUnit unit) {
-    _astMap[librarySource] = unit;
-  }
-
-  @override
-  String toString() => librarySource.shortName;
-}
-
-/**
- * Instances of the class `LibraryElementBuilder` build an element model for a single library.
- */
-class LibraryElementBuilder {
-  /**
-   * The analysis context in which the element model will be built.
-   */
-  final InternalAnalysisContext _analysisContext;
-
-  /**
-   * The listener to which errors will be reported.
-   */
-  final AnalysisErrorListener _errorListener;
-
-  /**
-   * Initialize a newly created library element builder.
-   *
-   * @param analysisContext the analysis context in which the element model will be built
-   * @param errorListener the listener to which errors will be reported
-   */
-  LibraryElementBuilder(this._analysisContext, this._errorListener);
-
-  /**
-   * Build the library element for the given library.
-   *
-   * @param library the library for which an element model is to be built
-   * @return the library element that was built
-   * @throws AnalysisException if the analysis could not be performed
-   */
-  LibraryElementImpl buildLibrary(Library library) {
-    CompilationUnitBuilder builder = new CompilationUnitBuilder();
-    Source librarySource = library.librarySource;
-    CompilationUnit definingCompilationUnit = library.definingCompilationUnit;
-    CompilationUnitElementImpl definingCompilationUnitElement = builder
-        .buildCompilationUnit(
-            librarySource, definingCompilationUnit, librarySource);
-    NodeList<Directive> directives = definingCompilationUnit.directives;
-    LibraryDirective libraryDirective = null;
-    LibraryIdentifier libraryNameNode = null;
-    bool hasPartDirective = false;
-    FunctionElement entryPoint =
-        _findEntryPoint(definingCompilationUnitElement);
-    List<Directive> directivesToResolve = new List<Directive>();
-    List<CompilationUnitElementImpl> sourcedCompilationUnits =
-        new List<CompilationUnitElementImpl>();
-    for (Directive directive in directives) {
-      //
-      // We do not build the elements representing the import and export
-      // directives at this point. That is not done until we get to
-      // LibraryResolver.buildDirectiveModels() because we need the
-      // LibraryElements for the referenced libraries, which might not exist at
-      // this point (due to the possibility of circular references).
-      //
-      if (directive is LibraryDirective) {
-        if (libraryNameNode == null) {
-          libraryDirective = directive;
-          libraryNameNode = directive.name;
-          directivesToResolve.add(directive);
-        }
-      } else if (directive is PartDirective) {
-        PartDirective partDirective = directive;
-        StringLiteral partUri = partDirective.uri;
-        Source partSource = partDirective.source;
-        if (_analysisContext.exists(partSource)) {
-          hasPartDirective = true;
-          CompilationUnit partUnit = library.getAST(partSource);
-          CompilationUnitElementImpl part =
-              builder.buildCompilationUnit(partSource, partUnit, librarySource);
-          part.uriOffset = partUri.offset;
-          part.uriEnd = partUri.end;
-          part.uri = partDirective.uriContent;
-          //
-          // Validate that the part contains a part-of directive with the same
-          // name as the library.
-          //
-          String partLibraryName =
-              _getPartLibraryName(partSource, partUnit, directivesToResolve);
-          if (partLibraryName == null) {
-            _errorListener.onError(new AnalysisError(
-                librarySource,
-                partUri.offset,
-                partUri.length,
-                CompileTimeErrorCode.PART_OF_NON_PART,
-                [partUri.toSource()]));
-          } else if (libraryNameNode == null) {
-            // TODO(brianwilkerson) Collect the names declared by the part.
-            // If they are all the same then we can use that name as the
-            // inferred name of the library and present it in a quick-fix.
-            // partLibraryNames.add(partLibraryName);
-          } else if (libraryNameNode.name != partLibraryName) {
-            _errorListener.onError(new AnalysisError(
-                librarySource,
-                partUri.offset,
-                partUri.length,
-                StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
-                [libraryNameNode.name, partLibraryName]));
-          }
-          if (entryPoint == null) {
-            entryPoint = _findEntryPoint(part);
-          }
-          directive.element = part;
-          sourcedCompilationUnits.add(part);
-        }
-      }
-    }
-    if (hasPartDirective && libraryNameNode == null) {
-      _errorListener.onError(new AnalysisError(librarySource, 0, 0,
-          ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART));
-    }
-    //
-    // Create and populate the library element.
-    //
-    LibraryElementImpl libraryElement = new LibraryElementImpl.forNode(
-        _analysisContext.getContextFor(librarySource), libraryNameNode);
-    _setDocRange(libraryElement, libraryDirective);
-    libraryElement.definingCompilationUnit = definingCompilationUnitElement;
-    if (entryPoint != null) {
-      libraryElement.entryPoint = entryPoint;
-    }
-    int sourcedUnitCount = sourcedCompilationUnits.length;
-    libraryElement.parts = sourcedCompilationUnits;
-    for (Directive directive in directivesToResolve) {
-      directive.element = libraryElement;
-    }
-    library.libraryElement = libraryElement;
-    if (sourcedUnitCount > 0) {
-      _patchTopLevelAccessors(libraryElement);
-    }
-    return libraryElement;
-  }
-
-  /**
-   * Build the library element for the given library.  The resulting element is
-   * stored in the [ResolvableLibrary] structure.
-   *
-   * @param library the library for which an element model is to be built
-   * @throws AnalysisException if the analysis could not be performed
-   */
-  void buildLibrary2(ResolvableLibrary library) {
-    CompilationUnitBuilder builder = new CompilationUnitBuilder();
-    Source librarySource = library.librarySource;
-    CompilationUnit definingCompilationUnit = library.definingCompilationUnit;
-    CompilationUnitElementImpl definingCompilationUnitElement = builder
-        .buildCompilationUnit(
-            librarySource, definingCompilationUnit, librarySource);
-    NodeList<Directive> directives = definingCompilationUnit.directives;
-    LibraryDirective libraryDirective = null;
-    LibraryIdentifier libraryNameNode = null;
-    bool hasPartDirective = false;
-    FunctionElement entryPoint =
-        _findEntryPoint(definingCompilationUnitElement);
-    List<Directive> directivesToResolve = new List<Directive>();
-    List<CompilationUnitElementImpl> sourcedCompilationUnits =
-        new List<CompilationUnitElementImpl>();
-    for (Directive directive in directives) {
-      //
-      // We do not build the elements representing the import and export
-      // directives at this point. That is not done until we get to
-      // LibraryResolver.buildDirectiveModels() because we need the
-      // LibraryElements for the referenced libraries, which might not exist at
-      // this point (due to the possibility of circular references).
-      //
-      if (directive is LibraryDirective) {
-        if (libraryNameNode == null) {
-          libraryDirective = directive;
-          libraryNameNode = directive.name;
-          directivesToResolve.add(directive);
-        }
-      } else if (directive is PartDirective) {
-        PartDirective partDirective = directive;
-        StringLiteral partUri = partDirective.uri;
-        Source partSource = partDirective.source;
-        if (_analysisContext.exists(partSource)) {
-          hasPartDirective = true;
-          CompilationUnit partUnit = library.getAST(partSource);
-          if (partUnit != null) {
-            CompilationUnitElementImpl part = builder.buildCompilationUnit(
-                partSource, partUnit, librarySource);
-            part.uriOffset = partUri.offset;
-            part.uriEnd = partUri.end;
-            part.uri = partDirective.uriContent;
-            //
-            // Validate that the part contains a part-of directive with the same
-            // name as the library.
-            //
-            String partLibraryName =
-                _getPartLibraryName(partSource, partUnit, directivesToResolve);
-            if (partLibraryName == null) {
-              _errorListener.onError(new AnalysisError(
-                  librarySource,
-                  partUri.offset,
-                  partUri.length,
-                  CompileTimeErrorCode.PART_OF_NON_PART,
-                  [partUri.toSource()]));
-            } else if (libraryNameNode == null) {
-              // TODO(brianwilkerson) Collect the names declared by the part.
-              // If they are all the same then we can use that name as the
-              // inferred name of the library and present it in a quick-fix.
-              // partLibraryNames.add(partLibraryName);
-            } else if (libraryNameNode.name != partLibraryName) {
-              _errorListener.onError(new AnalysisError(
-                  librarySource,
-                  partUri.offset,
-                  partUri.length,
-                  StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
-                  [libraryNameNode.name, partLibraryName]));
-            }
-            if (entryPoint == null) {
-              entryPoint = _findEntryPoint(part);
-            }
-            directive.element = part;
-            sourcedCompilationUnits.add(part);
-          }
-        }
-      }
-    }
-    if (hasPartDirective && libraryNameNode == null) {
-      _errorListener.onError(new AnalysisError(librarySource, 0, 0,
-          ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART));
-    }
-    //
-    // Create and populate the library element.
-    //
-    LibraryElementImpl libraryElement = new LibraryElementImpl.forNode(
-        _analysisContext.getContextFor(librarySource), libraryNameNode);
-    _setDocRange(libraryElement, libraryDirective);
-    libraryElement.definingCompilationUnit = definingCompilationUnitElement;
-    if (entryPoint != null) {
-      libraryElement.entryPoint = entryPoint;
-    }
-    int sourcedUnitCount = sourcedCompilationUnits.length;
-    libraryElement.parts = sourcedCompilationUnits;
-    for (Directive directive in directivesToResolve) {
-      directive.element = libraryElement;
-    }
-    library.libraryElement = libraryElement;
-    if (sourcedUnitCount > 0) {
-      _patchTopLevelAccessors(libraryElement);
-    }
-  }
-
-  /**
-   * Add all of the non-synthetic getters and setters defined in the given compilation unit that
-   * have no corresponding accessor to one of the given collections.
-   *
-   * @param getters the map to which getters are to be added
-   * @param setters the list to which setters are to be added
-   * @param unit the compilation unit defining the accessors that are potentially being added
-   */
-  void _collectAccessors(HashMap<String, PropertyAccessorElement> getters,
-      List<PropertyAccessorElement> setters, CompilationUnitElement unit) {
-    for (PropertyAccessorElement accessor in unit.accessors) {
-      if (accessor.isGetter) {
-        if (!accessor.isSynthetic && accessor.correspondingSetter == null) {
-          getters[accessor.displayName] = accessor;
-        }
-      } else {
-        if (!accessor.isSynthetic && accessor.correspondingGetter == null) {
-          setters.add(accessor);
-        }
-      }
-    }
-  }
-
-  /**
-   * Search the top-level functions defined in the given compilation unit for the entry point.
-   *
-   * @param element the compilation unit to be searched
-   * @return the entry point that was found, or `null` if the compilation unit does not define
-   *         an entry point
-   */
-  FunctionElement _findEntryPoint(CompilationUnitElementImpl element) {
-    for (FunctionElement function in element.functions) {
-      if (function.isEntryPoint) {
-        return function;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return the name of the library that the given part is declared to be a part of, or `null`
-   * if the part does not contain a part-of directive.
-   *
-   * @param partSource the source representing the part
-   * @param partUnit the AST structure of the part
-   * @param directivesToResolve a list of directives that should be resolved to the library being
-   *          built
-   * @return the name of the library that the given part is declared to be a part of
-   */
-  String _getPartLibraryName(Source partSource, CompilationUnit partUnit,
-      List<Directive> directivesToResolve) {
-    for (Directive directive in partUnit.directives) {
-      if (directive is PartOfDirective) {
-        directivesToResolve.add(directive);
-        LibraryIdentifier libraryName = directive.libraryName;
-        if (libraryName != null) {
-          return libraryName.name;
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Look through all of the compilation units defined for the given library, looking for getters
-   * and setters that are defined in different compilation units but that have the same names. If
-   * any are found, make sure that they have the same variable element.
-   *
-   * @param libraryElement the library defining the compilation units to be processed
-   */
-  void _patchTopLevelAccessors(LibraryElementImpl libraryElement) {
-    HashMap<String, PropertyAccessorElement> getters =
-        new HashMap<String, PropertyAccessorElement>();
-    List<PropertyAccessorElement> setters = new List<PropertyAccessorElement>();
-    _collectAccessors(getters, setters, libraryElement.definingCompilationUnit);
-    for (CompilationUnitElement unit in libraryElement.parts) {
-      _collectAccessors(getters, setters, unit);
-    }
-    for (PropertyAccessorElement setter in setters) {
-      PropertyAccessorElement getter = getters[setter.displayName];
-      if (getter != null) {
-        PropertyInducingElementImpl variable =
-            getter.variable as PropertyInducingElementImpl;
-        variable.setter = setter;
-        (setter as PropertyAccessorElementImpl).variable = variable;
-      }
-    }
-  }
-
-  /**
-   * If the given [node] has a documentation comment, remember its range
-   * into the given [element].
-   */
-  void _setDocRange(ElementImpl element, LibraryDirective node) {
-    if (node != null) {
-      Comment comment = node.documentationComment;
-      if (comment != null && comment.isDocumentation) {
-        element.setDocRange(comment.offset, comment.length);
-      }
-    }
-  }
-}
-
-/**
  * Instances of the class `LibraryImportScope` represent the scope containing all of the names
  * available from imported libraries.
  */
@@ -7610,1374 +6941,11 @@
  * Instances of the class `LibraryResolver` are used to resolve one or more mutually dependent
  * libraries within a single context.
  */
-class LibraryResolver {
-  /**
-   * The analysis context in which the libraries are being analyzed.
-   */
-  final InternalAnalysisContext analysisContext;
-
-  /**
-   * The listener to which analysis errors will be reported, this error listener is either
-   * references [recordingErrorListener], or it unions the passed
-   * [AnalysisErrorListener] with the [recordingErrorListener].
-   */
-  RecordingErrorListener _errorListener;
-
-  /**
-   * A source object representing the core library (dart:core).
-   */
-  Source _coreLibrarySource;
-
-  /**
-   * A Source object representing the async library (dart:async).
-   */
-  Source _asyncLibrarySource;
-
-  /**
-   * The object representing the core library.
-   */
-  Library _coreLibrary;
-
-  /**
-   * The object representing the async library.
-   */
-  Library _asyncLibrary;
-
-  /**
-   * The object used to access the types from the core library.
-   */
-  TypeProvider _typeProvider;
-
-  /**
-   * The type system in use for the library
-   */
-  TypeSystem _typeSystem;
-
-  /**
-   * A table mapping library sources to the information being maintained for those libraries.
-   */
-  HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>();
-
-  /**
-   * A collection containing the libraries that are being resolved together.
-   */
-  Set<Library> _librariesInCycles;
-
-  /**
-   * Initialize a newly created library resolver to resolve libraries within the given context.
-   *
-   * @param analysisContext the analysis context in which the library is being analyzed
-   */
-  LibraryResolver(this.analysisContext) {
-    this._errorListener = new RecordingErrorListener();
-    _coreLibrarySource =
-        analysisContext.sourceFactory.forUri(DartSdk.DART_CORE);
-    _asyncLibrarySource =
-        analysisContext.sourceFactory.forUri(DartSdk.DART_ASYNC);
-  }
-
-  /**
-   * Return the listener to which analysis errors will be reported.
-   *
-   * @return the listener to which analysis errors will be reported
-   */
-  RecordingErrorListener get errorListener => _errorListener;
-
-  /**
-   * Return an array containing information about all of the libraries that were resolved.
-   *
-   * @return an array containing the libraries that were resolved
-   */
-  Set<Library> get resolvedLibraries => _librariesInCycles;
-
-  /**
-   * The object used to access the types from the core library.
-   */
-  TypeProvider get typeProvider => _typeProvider;
-
-  /**
-   * The type system in use.
-   */
-  TypeSystem get typeSystem => _typeSystem;
-
-  /**
-   * Create an object to represent the information about the library defined by the compilation unit
-   * with the given source.
-   *
-   * @param librarySource the source of the library's defining compilation unit
-   * @return the library object that was created
-   * @throws AnalysisException if the library source is not valid
-   */
-  Library createLibrary(Source librarySource) {
-    Library library =
-        new Library(analysisContext, _errorListener, librarySource);
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Resolve the library specified by the given source in the given context. The library is assumed
-   * to be embedded in the given source.
-   *
-   * @param librarySource the source specifying the defining compilation unit of the library to be
-   *          resolved
-   * @param unit the compilation unit representing the embedded library
-   * @param fullAnalysis `true` if a full analysis should be performed
-   * @return the element representing the resolved library
-   * @throws AnalysisException if the library could not be resolved for some reason
-   */
-  LibraryElement resolveEmbeddedLibrary(
-      Source librarySource, CompilationUnit unit, bool fullAnalysis) {
-    //
-    // Create the objects representing the library being resolved and the core
-    // library.
-    //
-    Library targetLibrary = _createLibraryWithUnit(librarySource, unit);
-    _coreLibrary = _libraryMap[_coreLibrarySource];
-    if (_coreLibrary == null) {
-      // This will only happen if the library being analyzed is the core
-      // library.
-      _coreLibrary = createLibrary(_coreLibrarySource);
-      if (_coreLibrary == null) {
-        LibraryResolver2.missingCoreLibrary(
-            analysisContext, _coreLibrarySource);
-      }
-    }
-    _asyncLibrary = _libraryMap[_asyncLibrarySource];
-    if (_asyncLibrary == null) {
-      // This will only happen if the library being analyzed is the async
-      // library.
-      _asyncLibrary = createLibrary(_asyncLibrarySource);
-      if (_asyncLibrary == null) {
-        LibraryResolver2.missingAsyncLibrary(
-            analysisContext, _asyncLibrarySource);
-      }
-    }
-    //
-    // Compute the set of libraries that need to be resolved together.
-    //
-    _computeEmbeddedLibraryDependencies(targetLibrary, unit);
-    _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
-    //
-    // Build the element models representing the libraries being resolved.
-    // This is done in three steps:
-    //
-    // 1. Build the basic element models without making any connections
-    //    between elements other than the basic parent/child relationships.
-    //    This includes building the elements representing the libraries.
-    // 2. Build the elements for the import and export directives. This
-    //    requires that we have the elements built for the referenced
-    //    libraries, but because of the possibility of circular references
-    //    needs to happen after all of the library elements have been created.
-    // 3. Build the rest of the type model by connecting superclasses, mixins,
-    //    and interfaces. This requires that we be able to compute the names
-    //    visible in the libraries being resolved, which in turn requires that
-    //    we have resolved the import directives.
-    //
-    _buildElementModels();
-    LibraryElement coreElement = _coreLibrary.libraryElement;
-    if (coreElement == null) {
-      throw new AnalysisException("Could not resolve dart:core");
-    }
-    LibraryElement asyncElement = _asyncLibrary.libraryElement;
-    if (asyncElement == null) {
-      throw new AnalysisException("Could not resolve dart:async");
-    }
-    _buildDirectiveModels();
-    _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
-    _typeSystem = TypeSystem.create(analysisContext);
-    _buildTypeHierarchies();
-    //
-    // Perform resolution and type analysis.
-    //
-    // TODO(brianwilkerson) Decide whether we want to resolve all of the
-    // libraries or whether we want to only resolve the target library.
-    // The advantage to resolving everything is that we have already done part
-    // of the work so we'll avoid duplicated effort. The disadvantage of
-    // resolving everything is that we might do extra work that we don't
-    // really care about. Another possibility is to add a parameter to this
-    // method and punt the decision to the clients.
-    //
-    //if (analyzeAll) {
-    resolveReferencesAndTypes();
-    //} else {
-    //  resolveReferencesAndTypes(targetLibrary);
-    //}
-    _performConstantEvaluation();
-    return targetLibrary.libraryElement;
-  }
-
-  /**
-   * Resolve the library specified by the given source in the given context.
-   *
-   * Note that because Dart allows circular imports between libraries, it is possible that more than
-   * one library will need to be resolved. In such cases the error listener can receive errors from
-   * multiple libraries.
-   *
-   * @param librarySource the source specifying the defining compilation unit of the library to be
-   *          resolved
-   * @param fullAnalysis `true` if a full analysis should be performed
-   * @return the element representing the resolved library
-   * @throws AnalysisException if the library could not be resolved for some reason
-   */
-  LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) {
-    //
-    // Create the object representing the library being resolved and compute
-    // the dependency relationship.  Note that all libraries depend implicitly
-    // on core, and we inject an ersatz dependency on async, so once this is
-    // done the core and async library elements will have been created.
-    //
-    Library targetLibrary = createLibrary(librarySource);
-    _computeLibraryDependencies(targetLibrary);
-    _coreLibrary = _libraryMap[_coreLibrarySource];
-    _asyncLibrary = _libraryMap[_asyncLibrarySource];
-    //
-    // Compute the set of libraries that need to be resolved together.
-    //
-    _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
-    //
-    // Build the element models representing the libraries being resolved.
-    // This is done in three steps:
-    //
-    // 1. Build the basic element models without making any connections
-    //    between elements other than the basic parent/child relationships.
-    //    This includes building the elements representing the libraries, but
-    //    excludes members defined in enums.
-    // 2. Build the elements for the import and export directives. This
-    //    requires that we have the elements built for the referenced
-    //    libraries, but because of the possibility of circular references
-    //    needs to happen after all of the library elements have been created.
-    // 3. Build the members in enum declarations.
-    // 4. Build the rest of the type model by connecting superclasses, mixins,
-    //    and interfaces. This requires that we be able to compute the names
-    //    visible in the libraries being resolved, which in turn requires that
-    //    we have resolved the import directives.
-    //
-    _buildElementModels();
-    LibraryElement coreElement = _coreLibrary.libraryElement;
-    if (coreElement == null) {
-      throw new AnalysisException("Could not resolve dart:core");
-    }
-    LibraryElement asyncElement = _asyncLibrary.libraryElement;
-    if (asyncElement == null) {
-      throw new AnalysisException("Could not resolve dart:async");
-    }
-    _buildDirectiveModels();
-    _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
-    _typeSystem = TypeSystem.create(analysisContext);
-    _buildEnumMembers();
-    _buildTypeHierarchies();
-    //
-    // Perform resolution and type analysis.
-    //
-    // TODO(brianwilkerson) Decide whether we want to resolve all of the
-    // libraries or whether we want to only resolve the target library. The
-    // advantage to resolving everything is that we have already done part of
-    // the work so we'll avoid duplicated effort. The disadvantage of
-    // resolving everything is that we might do extra work that we don't
-    // really care about. Another possibility is to add a parameter to this
-    // method and punt the decision to the clients.
-    //
-    //if (analyzeAll) {
-    resolveReferencesAndTypes();
-    //} else {
-    //  resolveReferencesAndTypes(targetLibrary);
-    //}
-    _performConstantEvaluation();
-    return targetLibrary.libraryElement;
-  }
-
-  /**
-   * Resolve the identifiers and perform type analysis in the libraries in the current cycle.
-   *
-   * @throws AnalysisException if any of the identifiers could not be resolved or if any of the
-   *           libraries could not have their types analyzed
-   */
-  void resolveReferencesAndTypes() {
-    for (Library library in _librariesInCycles) {
-      _resolveReferencesAndTypesInLibrary(library);
-    }
-  }
-
-  /**
-   * Add a dependency to the given map from the referencing library to the referenced library.
-   *
-   * @param dependencyMap the map to which the dependency is to be added
-   * @param referencingLibrary the library that references the referenced library
-   * @param referencedLibrary the library referenced by the referencing library
-   */
-  void _addDependencyToMap(HashMap<Library, List<Library>> dependencyMap,
-      Library referencingLibrary, Library referencedLibrary) {
-    List<Library> dependentLibraries = dependencyMap[referencedLibrary];
-    if (dependentLibraries == null) {
-      dependentLibraries = new List<Library>();
-      dependencyMap[referencedLibrary] = dependentLibraries;
-    }
-    dependentLibraries.add(referencingLibrary);
-  }
-
-  /**
-   * Given a library that is part of a cycle that includes the root library, add to the given set of
-   * libraries all of the libraries reachable from the root library that are also included in the
-   * cycle.
-   *
-   * @param library the library to be added to the collection of libraries in cycles
-   * @param librariesInCycle a collection of the libraries that are in the cycle
-   * @param dependencyMap a table mapping libraries to the collection of libraries from which those
-   *          libraries are referenced
-   */
-  void _addLibrariesInCycle(Library library, Set<Library> librariesInCycle,
-      HashMap<Library, List<Library>> dependencyMap) {
-    if (librariesInCycle.add(library)) {
-      List<Library> dependentLibraries = dependencyMap[library];
-      if (dependentLibraries != null) {
-        for (Library dependentLibrary in dependentLibraries) {
-          _addLibrariesInCycle(
-              dependentLibrary, librariesInCycle, dependencyMap);
-        }
-      }
-    }
-  }
-
-  /**
-   * Add the given library, and all libraries reachable from it that have not already been visited,
-   * to the given dependency map.
-   *
-   * @param library the library currently being added to the dependency map
-   * @param dependencyMap the dependency map being computed
-   * @param visitedLibraries the libraries that have already been visited, used to prevent infinite
-   *          recursion
-   */
-  void _addToDependencyMap(
-      Library library,
-      HashMap<Library, List<Library>> dependencyMap,
-      Set<Library> visitedLibraries) {
-    if (visitedLibraries.add(library)) {
-      bool asyncFound = false;
-      for (Library referencedLibrary in library.importsAndExports) {
-        _addDependencyToMap(dependencyMap, library, referencedLibrary);
-        _addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries);
-        if (identical(referencedLibrary, _asyncLibrary)) {
-          asyncFound = true;
-        }
-      }
-      if (!library.explicitlyImportsCore && !identical(library, _coreLibrary)) {
-        _addDependencyToMap(dependencyMap, library, _coreLibrary);
-      }
-      if (!asyncFound && !identical(library, _asyncLibrary)) {
-        _addDependencyToMap(dependencyMap, library, _asyncLibrary);
-        _addToDependencyMap(_asyncLibrary, dependencyMap, visitedLibraries);
-      }
-    }
-  }
-
-  /**
-   * Build the element model representing the combinators declared by the given directive.
-   *
-   * @param directive the directive that declares the combinators
-   * @return an array containing the import combinators that were built
-   */
-  List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) {
-    List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
-    for (Combinator combinator in directive.combinators) {
-      if (combinator is HideCombinator) {
-        HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
-        hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
-        combinators.add(hide);
-      } else {
-        ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
-        show.offset = combinator.offset;
-        show.end = combinator.end;
-        show.shownNames =
-            _getIdentifiers((combinator as ShowCombinator).shownNames);
-        combinators.add(show);
-      }
-    }
-    return combinators;
-  }
-
-  /**
-   * Every library now has a corresponding [LibraryElement], so it is now possible to resolve
-   * the import and export directives.
-   *
-   * @throws AnalysisException if the defining compilation unit for any of the libraries could not
-   *           be accessed
-   */
-  void _buildDirectiveModels() {
-    for (Library library in _librariesInCycles) {
-      HashMap<String, PrefixElementImpl> nameToPrefixMap =
-          new HashMap<String, PrefixElementImpl>();
-      List<ImportElement> imports = new List<ImportElement>();
-      List<ExportElement> exports = new List<ExportElement>();
-      for (Directive directive in library.definingCompilationUnit.directives) {
-        if (directive is ImportDirective) {
-          ImportDirective importDirective = directive;
-          String uriContent = importDirective.uriContent;
-          if (DartUriResolver.isDartExtUri(uriContent)) {
-            library.libraryElement.hasExtUri = true;
-          }
-          Source importedSource = importDirective.source;
-          if (importedSource != null) {
-            // The imported source will be null if the URI in the import
-            // directive was invalid.
-            Library importedLibrary = _libraryMap[importedSource];
-            if (importedLibrary != null) {
-              ImportElementImpl importElement =
-                  new ImportElementImpl(directive.offset);
-              StringLiteral uriLiteral = importDirective.uri;
-              importElement.uriOffset = uriLiteral.offset;
-              importElement.uriEnd = uriLiteral.end;
-              importElement.uri = uriContent;
-              importElement.deferred = importDirective.deferredKeyword != null;
-              importElement.combinators = _buildCombinators(importDirective);
-              LibraryElement importedLibraryElement =
-                  importedLibrary.libraryElement;
-              if (importedLibraryElement != null) {
-                importElement.importedLibrary = importedLibraryElement;
-              }
-              SimpleIdentifier prefixNode = directive.prefix;
-              if (prefixNode != null) {
-                importElement.prefixOffset = prefixNode.offset;
-                String prefixName = prefixNode.name;
-                PrefixElementImpl prefix = nameToPrefixMap[prefixName];
-                if (prefix == null) {
-                  prefix = new PrefixElementImpl.forNode(prefixNode);
-                  nameToPrefixMap[prefixName] = prefix;
-                }
-                importElement.prefix = prefix;
-                prefixNode.staticElement = prefix;
-              }
-              directive.element = importElement;
-              imports.add(importElement);
-              if (analysisContext.computeKindOf(importedSource) !=
-                  SourceKind.LIBRARY) {
-                ErrorCode errorCode = (importElement.isDeferred
-                    ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
-                    : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
-                _errorListener.onError(new AnalysisError(
-                    library.librarySource,
-                    uriLiteral.offset,
-                    uriLiteral.length,
-                    errorCode,
-                    [uriLiteral.toSource()]));
-              }
-            }
-          }
-        } else if (directive is ExportDirective) {
-          ExportDirective exportDirective = directive;
-          Source exportedSource = exportDirective.source;
-          if (exportedSource != null) {
-            // The exported source will be null if the URI in the export
-            // directive was invalid.
-            Library exportedLibrary = _libraryMap[exportedSource];
-            if (exportedLibrary != null) {
-              ExportElementImpl exportElement =
-                  new ExportElementImpl(directive.offset);
-              StringLiteral uriLiteral = exportDirective.uri;
-              exportElement.uriOffset = uriLiteral.offset;
-              exportElement.uriEnd = uriLiteral.end;
-              exportElement.uri = exportDirective.uriContent;
-              exportElement.combinators = _buildCombinators(exportDirective);
-              LibraryElement exportedLibraryElement =
-                  exportedLibrary.libraryElement;
-              if (exportedLibraryElement != null) {
-                exportElement.exportedLibrary = exportedLibraryElement;
-              }
-              directive.element = exportElement;
-              exports.add(exportElement);
-              if (analysisContext.computeKindOf(exportedSource) !=
-                  SourceKind.LIBRARY) {
-                _errorListener.onError(new AnalysisError(
-                    library.librarySource,
-                    uriLiteral.offset,
-                    uriLiteral.length,
-                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
-                    [uriLiteral.toSource()]));
-              }
-            }
-          }
-        }
-      }
-      Source librarySource = library.librarySource;
-      if (!library.explicitlyImportsCore &&
-          _coreLibrarySource != librarySource) {
-        ImportElementImpl importElement = new ImportElementImpl(-1);
-        importElement.importedLibrary = _coreLibrary.libraryElement;
-        importElement.synthetic = true;
-        imports.add(importElement);
-      }
-      LibraryElementImpl libraryElement = library.libraryElement;
-      libraryElement.imports = imports;
-      libraryElement.exports = exports;
-      if (libraryElement.entryPoint == null) {
-        Namespace namespace = new NamespaceBuilder()
-            .createExportNamespaceForLibrary(libraryElement);
-        Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME);
-        if (element is FunctionElement) {
-          libraryElement.entryPoint = element;
-        }
-      }
-    }
-  }
-
-  /**
-   * Build element models for all of the libraries in the current cycle.
-   *
-   * @throws AnalysisException if any of the element models cannot be built
-   */
-  void _buildElementModels() {
-    for (Library library in _librariesInCycles) {
-      LibraryElementBuilder builder =
-          new LibraryElementBuilder(analysisContext, errorListener);
-      LibraryElementImpl libraryElement = builder.buildLibrary(library);
-      library.libraryElement = libraryElement;
-    }
-  }
-
-  /**
-   * Build the members in enum declarations. This cannot be done while building the rest of the
-   * element model because it depends on being able to access core types, which cannot happen until
-   * the rest of the element model has been built (when resolving the core library).
-   *
-   * @throws AnalysisException if any of the enum members could not be built
-   */
-  void _buildEnumMembers() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (Library library in _librariesInCycles) {
-        for (Source source in library.compilationUnitSources) {
-          EnumMemberBuilder builder = new EnumMemberBuilder(_typeProvider);
-          library.getAST(source).accept(builder);
-        }
-      }
-    });
-  }
-
-  /**
-   * Resolve the type hierarchy across all of the types declared in the libraries in the current
-   * cycle.
-   *
-   * @throws AnalysisException if any of the type hierarchies could not be resolved
-   */
-  void _buildTypeHierarchies() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (Library library in _librariesInCycles) {
-        for (Source source in library.compilationUnitSources) {
-          TypeResolverVisitorFactory typeResolverVisitorFactory =
-              analysisContext.typeResolverVisitorFactory;
-          TypeResolverVisitor visitor = (typeResolverVisitorFactory == null)
-              ? new TypeResolverVisitor(library.libraryElement, source,
-                  _typeProvider, library.errorListener,
-                  nameScope: library.libraryScope)
-              : typeResolverVisitorFactory(library, source, _typeProvider);
-          library.getAST(source).accept(visitor);
-        }
-        library.libraryElement.createLoadLibraryFunction(_typeProvider);
-      }
-    });
-  }
-
-  /**
-   * Compute a dependency map of libraries reachable from the given library. A dependency map is a
-   * table that maps individual libraries to a list of the libraries that either import or export
-   * those libraries.
-   *
-   * This map is used to compute all of the libraries involved in a cycle that include the root
-   * library. Given that we only add libraries that are reachable from the root library, when we
-   * work backward we are guaranteed to only get libraries in the cycle.
-   *
-   * @param library the library currently being added to the dependency map
-   */
-  HashMap<Library, List<Library>> _computeDependencyMap(Library library) {
-    HashMap<Library, List<Library>> dependencyMap =
-        new HashMap<Library, List<Library>>();
-    _addToDependencyMap(library, dependencyMap, new HashSet<Library>());
-    return dependencyMap;
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given library, creating instances of the
-   * class [Library] to represent them, and record the references in the library objects.
-   *
-   * @param library the library to be processed to find libraries that have not yet been traversed
-   * @throws AnalysisException if some portion of the library graph could not be traversed
-   */
-  void _computeEmbeddedLibraryDependencies(
-      Library library, CompilationUnit unit) {
-    Source librarySource = library.librarySource;
-    HashSet<Source> exportedSources = new HashSet<Source>();
-    HashSet<Source> importedSources = new HashSet<Source>();
-    for (Directive directive in unit.directives) {
-      if (directive is ExportDirective) {
-        Source exportSource = _resolveSource(librarySource, directive);
-        if (exportSource != null) {
-          exportedSources.add(exportSource);
-        }
-      } else if (directive is ImportDirective) {
-        Source importSource = _resolveSource(librarySource, directive);
-        if (importSource != null) {
-          importedSources.add(importSource);
-        }
-      }
-    }
-    _computeLibraryDependenciesFromDirectives(library,
-        new List.from(importedSources), new List.from(exportedSources));
-  }
-
-  /**
-   * Return a collection containing all of the libraries reachable from the given library that are
-   * contained in a cycle that includes the given library.
-   *
-   * @param library the library that must be included in any cycles whose members are to be returned
-   * @return all of the libraries referenced by the given library that have a circular reference
-   *         back to the given library
-   */
-  Set<Library> _computeLibrariesInCycles(Library library) {
-    HashMap<Library, List<Library>> dependencyMap =
-        _computeDependencyMap(library);
-    Set<Library> librariesInCycle = new HashSet<Library>();
-    _addLibrariesInCycle(library, librariesInCycle, dependencyMap);
-    return librariesInCycle;
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given library, creating instances of the
-   * class [Library] to represent them, and record the references in the library objects.
-   *
-   * @param library the library to be processed to find libraries that have not yet been traversed
-   * @throws AnalysisException if some portion of the library graph could not be traversed
-   */
-  void _computeLibraryDependencies(Library library) {
-    Source librarySource = library.librarySource;
-    _computeLibraryDependenciesFromDirectives(
-        library,
-        analysisContext.computeImportedLibraries(librarySource),
-        analysisContext.computeExportedLibraries(librarySource));
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given library, creating instances of the
-   * class [Library] to represent them, and record the references in the library objects.
-   *
-   * @param library the library to be processed to find libraries that have not yet been traversed
-   * @param importedSources an array containing the sources that are imported into the given library
-   * @param exportedSources an array containing the sources that are exported from the given library
-   * @throws AnalysisException if some portion of the library graph could not be traversed
-   */
-  void _computeLibraryDependenciesFromDirectives(Library library,
-      List<Source> importedSources, List<Source> exportedSources) {
-    List<Library> importedLibraries = new List<Library>();
-    bool explicitlyImportsCore = false;
-    bool importsAsync = false;
-    for (Source importedSource in importedSources) {
-      if (importedSource == _coreLibrarySource) {
-        explicitlyImportsCore = true;
-      }
-      if (importedSource == _asyncLibrarySource) {
-        importsAsync = true;
-      }
-      Library importedLibrary = _libraryMap[importedSource];
-      if (importedLibrary == null) {
-        importedLibrary = _createLibraryOrNull(importedSource);
-        if (importedLibrary != null) {
-          _computeLibraryDependencies(importedLibrary);
-        }
-      }
-      if (importedLibrary != null) {
-        importedLibraries.add(importedLibrary);
-      }
-    }
-    library.importedLibraries = importedLibraries;
-    List<Library> exportedLibraries = new List<Library>();
-    for (Source exportedSource in exportedSources) {
-      Library exportedLibrary = _libraryMap[exportedSource];
-      if (exportedLibrary == null) {
-        exportedLibrary = _createLibraryOrNull(exportedSource);
-        if (exportedLibrary != null) {
-          _computeLibraryDependencies(exportedLibrary);
-        }
-      }
-      if (exportedLibrary != null) {
-        exportedLibraries.add(exportedLibrary);
-      }
-    }
-    library.exportedLibraries = exportedLibraries;
-    library.explicitlyImportsCore = explicitlyImportsCore;
-    if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) {
-      Library importedLibrary = _libraryMap[_coreLibrarySource];
-      if (importedLibrary == null) {
-        importedLibrary = _createLibraryOrNull(_coreLibrarySource);
-        if (importedLibrary != null) {
-          _computeLibraryDependencies(importedLibrary);
-        }
-      }
-    }
-    if (!importsAsync && _asyncLibrarySource != library.librarySource) {
-      Library importedLibrary = _libraryMap[_asyncLibrarySource];
-      if (importedLibrary == null) {
-        importedLibrary = _createLibraryOrNull(_asyncLibrarySource);
-        if (importedLibrary != null) {
-          _computeLibraryDependencies(importedLibrary);
-        }
-      }
-    }
-  }
-
-  /**
-   * Create an object to represent the information about the library defined by the compilation unit
-   * with the given source. Return the library object that was created, or `null` if the
-   * source is not valid.
-   *
-   * @param librarySource the source of the library's defining compilation unit
-   * @return the library object that was created
-   */
-  Library _createLibraryOrNull(Source librarySource) {
-    if (!analysisContext.exists(librarySource)) {
-      return null;
-    }
-    Library library =
-        new Library(analysisContext, _errorListener, librarySource);
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Create an object to represent the information about the library defined by the compilation unit
-   * with the given source.
-   *
-   * @param librarySource the source of the library's defining compilation unit
-   * @param unit the compilation unit that defines the library
-   * @return the library object that was created
-   * @throws AnalysisException if the library source is not valid
-   */
-  Library _createLibraryWithUnit(Source librarySource, CompilationUnit unit) {
-    Library library =
-        new Library(analysisContext, _errorListener, librarySource);
-    library.setDefiningCompilationUnit(unit);
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Return an array containing the lexical identifiers associated with the nodes in the given list.
-   *
-   * @param names the AST nodes representing the identifiers
-   * @return the lexical identifiers associated with the nodes in the list
-   */
-  List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) {
-    int count = names.length;
-    List<String> identifiers = new List<String>(count);
-    for (int i = 0; i < count; i++) {
-      identifiers[i] = names[i].name;
-    }
-    return identifiers;
-  }
-
-  /**
-   * Compute a value for all of the constants in the libraries being analyzed.
-   */
-  void _performConstantEvaluation() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      ConstantValueComputer computer = new ConstantValueComputer(
-          analysisContext,
-          _typeProvider,
-          analysisContext.declaredVariables,
-          null,
-          _typeSystem);
-      for (Library library in _librariesInCycles) {
-        for (Source source in library.compilationUnitSources) {
-          try {
-            CompilationUnit unit = library.getAST(source);
-            if (unit != null) {
-              computer.add(unit, source, library.librarySource);
-            }
-          } on AnalysisException catch (exception, stackTrace) {
-            AnalysisEngine.instance.logger.logError(
-                "Internal Error: Could not access AST for ${source.fullName} during constant evaluation",
-                new CaughtException(exception, stackTrace));
-          }
-        }
-      }
-      computer.computeValues();
-      // As a temporary workaround for issue 21572, run ConstantVerifier now.
-      // TODO(paulberry): remove this workaround once issue 21572 is fixed.
-      for (Library library in _librariesInCycles) {
-        for (Source source in library.compilationUnitSources) {
-          try {
-            CompilationUnit unit = library.getAST(source);
-            ErrorReporter errorReporter =
-                new ErrorReporter(_errorListener, source);
-            ConstantVerifier constantVerifier = new ConstantVerifier(
-                errorReporter,
-                library.libraryElement,
-                _typeProvider,
-                analysisContext.declaredVariables);
-            unit.accept(constantVerifier);
-          } on AnalysisException catch (exception, stackTrace) {
-            AnalysisEngine.instance.logger.logError(
-                "Internal Error: Could not access AST for ${source.fullName} "
-                "during constant verification",
-                new CaughtException(exception, stackTrace));
-          }
-        }
-      }
-    });
-  }
-
-  /**
-   * Resolve the identifiers and perform type analysis in the given library.
-   *
-   * @param library the library to be resolved
-   * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
-   *           the library cannot be analyzed
-   */
-  void _resolveReferencesAndTypesInLibrary(Library library) {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (Source source in library.compilationUnitSources) {
-        CompilationUnit ast = library.getAST(source);
-        ast.accept(new VariableResolverVisitor(library.libraryElement, source,
-            _typeProvider, library.errorListener,
-            nameScope: library.libraryScope));
-        ResolverVisitorFactory visitorFactory =
-            analysisContext.resolverVisitorFactory;
-        ResolverVisitor visitor = visitorFactory != null
-            ? visitorFactory(library, source, _typeProvider)
-            : new ResolverVisitor(library.libraryElement, source, _typeProvider,
-                library.errorListener,
-                nameScope: library.libraryScope,
-                inheritanceManager: library.inheritanceManager);
-        ast.accept(visitor);
-      }
-    });
-  }
-
-  /**
-   * Return the result of resolving the URI of the given URI-based directive against the URI of the
-   * given library, or `null` if the URI is not valid.
-   *
-   * @param librarySource the source representing the library containing the directive
-   * @param directive the directive which URI should be resolved
-   * @return the result of resolving the URI against the URI of the library
-   */
-  Source _resolveSource(Source librarySource, UriBasedDirective directive) {
-    StringLiteral uriLiteral = directive.uri;
-    if (uriLiteral is StringInterpolation) {
-      return null;
-    }
-    String uriContent = uriLiteral.stringValue.trim();
-    if (uriContent == null || uriContent.isEmpty) {
-      return null;
-    }
-    uriContent = Uri.encodeFull(uriContent);
-    return analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
-  }
-}
 
 /**
  * Instances of the class `LibraryResolver` are used to resolve one or more mutually dependent
  * libraries within a single context.
  */
-class LibraryResolver2 {
-  /**
-   * The analysis context in which the libraries are being analyzed.
-   */
-  final InternalAnalysisContext analysisContext;
-
-  /**
-   * The listener to which analysis errors will be reported, this error listener is either
-   * references [recordingErrorListener], or it unions the passed
-   * [AnalysisErrorListener] with the [recordingErrorListener].
-   */
-  RecordingErrorListener _errorListener;
-
-  /**
-   * A source object representing the core library (dart:core).
-   */
-  Source _coreLibrarySource;
-
-  /**
-   * A source object representing the async library (dart:async).
-   */
-  Source _asyncLibrarySource;
-
-  /**
-   * The object representing the core library.
-   */
-  ResolvableLibrary _coreLibrary;
-
-  /**
-   * The object representing the async library.
-   */
-  ResolvableLibrary _asyncLibrary;
-
-  /**
-   * The object used to access the types from the core library.
-   */
-  TypeProvider _typeProvider;
-
-  /**
-   * The type system in use for the library
-   */
-  TypeSystem _typeSystem;
-
-  /**
-   * A table mapping library sources to the information being maintained for those libraries.
-   */
-  HashMap<Source, ResolvableLibrary> _libraryMap =
-      new HashMap<Source, ResolvableLibrary>();
-
-  /**
-   * A collection containing the libraries that are being resolved together.
-   */
-  List<ResolvableLibrary> _librariesInCycle;
-
-  /**
-   * Initialize a newly created library resolver to resolve libraries within the given context.
-   *
-   * @param analysisContext the analysis context in which the library is being analyzed
-   */
-  LibraryResolver2(this.analysisContext) {
-    this._errorListener = new RecordingErrorListener();
-    _coreLibrarySource =
-        analysisContext.sourceFactory.forUri(DartSdk.DART_CORE);
-    _asyncLibrarySource =
-        analysisContext.sourceFactory.forUri(DartSdk.DART_ASYNC);
-  }
-
-  /**
-   * Return the listener to which analysis errors will be reported.
-   *
-   * @return the listener to which analysis errors will be reported
-   */
-  RecordingErrorListener get errorListener => _errorListener;
-
-  /**
-   * Return an array containing information about all of the libraries that were resolved.
-   *
-   * @return an array containing the libraries that were resolved
-   */
-  List<ResolvableLibrary> get resolvedLibraries => _librariesInCycle;
-
-  /**
-   * Resolve the library specified by the given source in the given context.
-   *
-   * Note that because Dart allows circular imports between libraries, it is possible that more than
-   * one library will need to be resolved. In such cases the error listener can receive errors from
-   * multiple libraries.
-   *
-   * @param librarySource the source specifying the defining compilation unit of the library to be
-   *          resolved
-   * @param fullAnalysis `true` if a full analysis should be performed
-   * @return the element representing the resolved library
-   * @throws AnalysisException if the library could not be resolved for some reason
-   */
-  LibraryElement resolveLibrary(
-      Source librarySource, List<ResolvableLibrary> librariesInCycle) {
-    //
-    // Build the map of libraries that are known.
-    //
-    this._librariesInCycle = librariesInCycle;
-    _libraryMap = _buildLibraryMap();
-    ResolvableLibrary targetLibrary = _libraryMap[librarySource];
-    _coreLibrary = _libraryMap[_coreLibrarySource];
-    _asyncLibrary = _libraryMap[_asyncLibrarySource];
-    //
-    // Build the element models representing the libraries being resolved.
-    // This is done in three steps:
-    //
-    // 1. Build the basic element models without making any connections
-    //    between elements other than the basic parent/child relationships.
-    //    This includes building the elements representing the libraries, but
-    //    excludes members defined in enums.
-    // 2. Build the elements for the import and export directives. This
-    //    requires that we have the elements built for the referenced
-    //    libraries, but because of the possibility of circular references
-    //    needs to happen after all of the library elements have been created.
-    // 3. Build the members in enum declarations.
-    // 4. Build the rest of the type model by connecting superclasses, mixins,
-    //    and interfaces. This requires that we be able to compute the names
-    //    visible in the libraries being resolved, which in turn requires that
-    //    we have resolved the import directives.
-    //
-    _buildElementModels();
-    LibraryElement coreElement = _coreLibrary.libraryElement;
-    if (coreElement == null) {
-      missingCoreLibrary(analysisContext, _coreLibrarySource);
-    }
-    LibraryElement asyncElement = _asyncLibrary.libraryElement;
-    if (asyncElement == null) {
-      missingAsyncLibrary(analysisContext, _asyncLibrarySource);
-    }
-    _buildDirectiveModels();
-    _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
-    _typeSystem = TypeSystem.create(analysisContext);
-    _buildEnumMembers();
-    _buildTypeHierarchies();
-    //
-    // Perform resolution and type analysis.
-    //
-    // TODO(brianwilkerson) Decide whether we want to resolve all of the
-    // libraries or whether we want to only resolve the target library. The
-    // advantage to resolving everything is that we have already done part of
-    // the work so we'll avoid duplicated effort. The disadvantage of
-    // resolving everything is that we might do extra work that we don't
-    // really care about. Another possibility is to add a parameter to this
-    // method and punt the decision to the clients.
-    //
-    //if (analyzeAll) {
-    _resolveReferencesAndTypes();
-    //} else {
-    //  resolveReferencesAndTypes(targetLibrary);
-    //}
-    _performConstantEvaluation();
-    return targetLibrary.libraryElement;
-  }
-
-  /**
-   * Build the element model representing the combinators declared by the given directive.
-   *
-   * @param directive the directive that declares the combinators
-   * @return an array containing the import combinators that were built
-   */
-  List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) {
-    List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
-    for (Combinator combinator in directive.combinators) {
-      if (combinator is HideCombinator) {
-        HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
-        hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
-        combinators.add(hide);
-      } else {
-        ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
-        show.offset = combinator.offset;
-        show.end = combinator.end;
-        show.shownNames =
-            _getIdentifiers((combinator as ShowCombinator).shownNames);
-        combinators.add(show);
-      }
-    }
-    return combinators;
-  }
-
-  /**
-   * Every library now has a corresponding [LibraryElement], so it is now possible to resolve
-   * the import and export directives.
-   *
-   * @throws AnalysisException if the defining compilation unit for any of the libraries could not
-   *           be accessed
-   */
-  void _buildDirectiveModels() {
-    for (ResolvableLibrary library in _librariesInCycle) {
-      HashMap<String, PrefixElementImpl> nameToPrefixMap =
-          new HashMap<String, PrefixElementImpl>();
-      List<ImportElement> imports = new List<ImportElement>();
-      List<ExportElement> exports = new List<ExportElement>();
-      for (Directive directive in library.definingCompilationUnit.directives) {
-        if (directive is ImportDirective) {
-          ImportDirective importDirective = directive;
-          String uriContent = importDirective.uriContent;
-          if (DartUriResolver.isDartExtUri(uriContent)) {
-            library.libraryElement.hasExtUri = true;
-          }
-          Source importedSource = importDirective.source;
-          if (importedSource != null &&
-              analysisContext.exists(importedSource)) {
-            // The imported source will be null if the URI in the import
-            // directive was invalid.
-            ResolvableLibrary importedLibrary = _libraryMap[importedSource];
-            if (importedLibrary != null) {
-              ImportElementImpl importElement =
-                  new ImportElementImpl(directive.offset);
-              StringLiteral uriLiteral = importDirective.uri;
-              if (uriLiteral != null) {
-                importElement.uriOffset = uriLiteral.offset;
-                importElement.uriEnd = uriLiteral.end;
-              }
-              importElement.uri = uriContent;
-              importElement.deferred = importDirective.deferredKeyword != null;
-              importElement.combinators = _buildCombinators(importDirective);
-              LibraryElement importedLibraryElement =
-                  importedLibrary.libraryElement;
-              if (importedLibraryElement != null) {
-                importElement.importedLibrary = importedLibraryElement;
-              }
-              SimpleIdentifier prefixNode = directive.prefix;
-              if (prefixNode != null) {
-                importElement.prefixOffset = prefixNode.offset;
-                String prefixName = prefixNode.name;
-                PrefixElementImpl prefix = nameToPrefixMap[prefixName];
-                if (prefix == null) {
-                  prefix = new PrefixElementImpl.forNode(prefixNode);
-                  nameToPrefixMap[prefixName] = prefix;
-                }
-                importElement.prefix = prefix;
-                prefixNode.staticElement = prefix;
-              }
-              directive.element = importElement;
-              imports.add(importElement);
-              if (analysisContext.computeKindOf(importedSource) !=
-                  SourceKind.LIBRARY) {
-                ErrorCode errorCode = (importElement.isDeferred
-                    ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
-                    : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
-                _errorListener.onError(new AnalysisError(
-                    library.librarySource,
-                    uriLiteral.offset,
-                    uriLiteral.length,
-                    errorCode,
-                    [uriLiteral.toSource()]));
-              }
-            }
-          }
-        } else if (directive is ExportDirective) {
-          ExportDirective exportDirective = directive;
-          Source exportedSource = exportDirective.source;
-          if (exportedSource != null &&
-              analysisContext.exists(exportedSource)) {
-            // The exported source will be null if the URI in the export
-            // directive was invalid.
-            ResolvableLibrary exportedLibrary = _libraryMap[exportedSource];
-            if (exportedLibrary != null) {
-              ExportElementImpl exportElement =
-                  new ExportElementImpl(directive.offset);
-              StringLiteral uriLiteral = exportDirective.uri;
-              if (uriLiteral != null) {
-                exportElement.uriOffset = uriLiteral.offset;
-                exportElement.uriEnd = uriLiteral.end;
-              }
-              exportElement.uri = exportDirective.uriContent;
-              exportElement.combinators = _buildCombinators(exportDirective);
-              LibraryElement exportedLibraryElement =
-                  exportedLibrary.libraryElement;
-              if (exportedLibraryElement != null) {
-                exportElement.exportedLibrary = exportedLibraryElement;
-              }
-              directive.element = exportElement;
-              exports.add(exportElement);
-              if (analysisContext.computeKindOf(exportedSource) !=
-                  SourceKind.LIBRARY) {
-                _errorListener.onError(new AnalysisError(
-                    library.librarySource,
-                    uriLiteral.offset,
-                    uriLiteral.length,
-                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
-                    [uriLiteral.toSource()]));
-              }
-            }
-          }
-        }
-      }
-      Source librarySource = library.librarySource;
-      if (!library.explicitlyImportsCore &&
-          _coreLibrarySource != librarySource) {
-        ImportElementImpl importElement = new ImportElementImpl(-1);
-        importElement.importedLibrary = _coreLibrary.libraryElement;
-        importElement.synthetic = true;
-        imports.add(importElement);
-      }
-      LibraryElementImpl libraryElement = library.libraryElement;
-      libraryElement.imports = imports;
-      libraryElement.exports = exports;
-      if (libraryElement.entryPoint == null) {
-        Namespace namespace = new NamespaceBuilder()
-            .createExportNamespaceForLibrary(libraryElement);
-        Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME);
-        if (element is FunctionElement) {
-          libraryElement.entryPoint = element;
-        }
-      }
-    }
-  }
-
-  /**
-   * Build element models for all of the libraries in the current cycle.
-   *
-   * @throws AnalysisException if any of the element models cannot be built
-   */
-  void _buildElementModels() {
-    for (ResolvableLibrary library in _librariesInCycle) {
-      LibraryElementBuilder builder =
-          new LibraryElementBuilder(analysisContext, errorListener);
-      builder.buildLibrary2(library);
-    }
-  }
-
-  /**
-   * Build the members in enum declarations. This cannot be done while building the rest of the
-   * element model because it depends on being able to access core types, which cannot happen until
-   * the rest of the element model has been built (when resolving the core library).
-   *
-   * @throws AnalysisException if any of the enum members could not be built
-   */
-  void _buildEnumMembers() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (ResolvableLibrary library in _librariesInCycle) {
-        for (Source source in library.compilationUnitSources) {
-          EnumMemberBuilder builder = new EnumMemberBuilder(_typeProvider);
-          library.getAST(source).accept(builder);
-        }
-      }
-    });
-  }
-
-  HashMap<Source, ResolvableLibrary> _buildLibraryMap() {
-    HashMap<Source, ResolvableLibrary> libraryMap =
-        new HashMap<Source, ResolvableLibrary>();
-    int libraryCount = _librariesInCycle.length;
-    for (int i = 0; i < libraryCount; i++) {
-      ResolvableLibrary library = _librariesInCycle[i];
-      library.errorListener = _errorListener;
-      libraryMap[library.librarySource] = library;
-      List<ResolvableLibrary> dependencies = library.importsAndExports;
-      int dependencyCount = dependencies.length;
-      for (int j = 0; j < dependencyCount; j++) {
-        ResolvableLibrary dependency = dependencies[j];
-        //dependency.setErrorListener(errorListener);
-        libraryMap[dependency.librarySource] = dependency;
-      }
-    }
-    return libraryMap;
-  }
-
-  /**
-   * Resolve the type hierarchy across all of the types declared in the libraries in the current
-   * cycle.
-   *
-   * @throws AnalysisException if any of the type hierarchies could not be resolved
-   */
-  void _buildTypeHierarchies() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (ResolvableLibrary library in _librariesInCycle) {
-        for (ResolvableCompilationUnit unit
-            in library.resolvableCompilationUnits) {
-          Source source = unit.source;
-          CompilationUnit ast = unit.compilationUnit;
-          TypeResolverVisitor visitor = new TypeResolverVisitor(
-              library.libraryElement,
-              source,
-              _typeProvider,
-              library.libraryScope.errorListener,
-              nameScope: library.libraryScope);
-          ast.accept(visitor);
-        }
-        library.libraryElement.createLoadLibraryFunction(_typeProvider);
-      }
-    });
-  }
-
-  /**
-   * Return an array containing the lexical identifiers associated with the nodes in the given list.
-   *
-   * @param names the AST nodes representing the identifiers
-   * @return the lexical identifiers associated with the nodes in the list
-   */
-  List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) {
-    int count = names.length;
-    List<String> identifiers = new List<String>(count);
-    for (int i = 0; i < count; i++) {
-      identifiers[i] = names[i].name;
-    }
-    return identifiers;
-  }
-
-  /**
-   * Compute a value for all of the constants in the libraries being analyzed.
-   */
-  void _performConstantEvaluation() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      ConstantValueComputer computer = new ConstantValueComputer(
-          analysisContext,
-          _typeProvider,
-          analysisContext.declaredVariables,
-          null,
-          _typeSystem);
-      for (ResolvableLibrary library in _librariesInCycle) {
-        for (ResolvableCompilationUnit unit
-            in library.resolvableCompilationUnits) {
-          CompilationUnit ast = unit.compilationUnit;
-          if (ast != null) {
-            computer.add(ast, unit.source, library.librarySource);
-          }
-        }
-      }
-      computer.computeValues();
-      // As a temporary workaround for issue 21572, run ConstantVerifier now.
-      // TODO(paulberry): remove this workaround once issue 21572 is fixed.
-      for (ResolvableLibrary library in _librariesInCycle) {
-        for (ResolvableCompilationUnit unit
-            in library.resolvableCompilationUnits) {
-          CompilationUnit ast = unit.compilationUnit;
-          ErrorReporter errorReporter =
-              new ErrorReporter(_errorListener, unit.source);
-          ConstantVerifier constantVerifier = new ConstantVerifier(
-              errorReporter,
-              library.libraryElement,
-              _typeProvider,
-              analysisContext.declaredVariables);
-          ast.accept(constantVerifier);
-        }
-      }
-    });
-  }
-
-  /**
-   * Resolve the identifiers and perform type analysis in the libraries in the current cycle.
-   *
-   * @throws AnalysisException if any of the identifiers could not be resolved or if any of the
-   *           libraries could not have their types analyzed
-   */
-  void _resolveReferencesAndTypes() {
-    for (ResolvableLibrary library in _librariesInCycle) {
-      _resolveReferencesAndTypesInLibrary(library);
-    }
-  }
-
-  /**
-   * Resolve the identifiers and perform type analysis in the given library.
-   *
-   * @param library the library to be resolved
-   * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
-   *           the library cannot be analyzed
-   */
-  void _resolveReferencesAndTypesInLibrary(ResolvableLibrary library) {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (ResolvableCompilationUnit unit
-          in library.resolvableCompilationUnits) {
-        Source source = unit.source;
-        CompilationUnit ast = unit.compilationUnit;
-        ast.accept(new VariableResolverVisitor(library.libraryElement, source,
-            _typeProvider, library.libraryScope.errorListener,
-            nameScope: library.libraryScope));
-        ResolverVisitor visitor = new ResolverVisitor(library.libraryElement,
-            source, _typeProvider, library._libraryScope.errorListener,
-            nameScope: library._libraryScope,
-            inheritanceManager: library.inheritanceManager);
-        ast.accept(visitor);
-      }
-    });
-  }
-
-  /**
-   * Report that the async library could not be resolved in the given
-   * [analysisContext] and throw an exception.  [asyncLibrarySource] is the source
-   * representing the async library.
-   */
-  static void missingAsyncLibrary(
-      AnalysisContext analysisContext, Source asyncLibrarySource) {
-    throw new AnalysisException("Could not resolve dart:async");
-  }
-
-  /**
-   * Report that the core library could not be resolved in the given analysis context and throw an
-   * exception.
-   *
-   * @param analysisContext the analysis context in which the failure occurred
-   * @param coreLibrarySource the source representing the core library
-   * @throws AnalysisException always
-   */
-  static void missingCoreLibrary(
-      AnalysisContext analysisContext, Source coreLibrarySource) {
-    throw new AnalysisException("Could not resolve dart:core");
-  }
-}
 
 /**
  * Instances of the class `LibraryScope` implement a scope containing all of the names defined
@@ -9090,29 +7058,6 @@
   }
 
   /**
-   * This constructor takes an initial capacity of the map.
-   *
-   * @param initialCapacity the initial capacity
-   */
-  @deprecated // Use new MemberMap(initialCapacity)
-  MemberMap.con1(int initialCapacity) {
-    _initArrays(initialCapacity);
-  }
-
-  /**
-   * Copy constructor.
-   */
-  @deprecated // Use new MemberMap.from(memberMap)
-  MemberMap.con2(MemberMap memberMap) {
-    _initArrays(memberMap._size + 5);
-    for (int i = 0; i < memberMap._size; i++) {
-      _keys[i] = memberMap._keys[i];
-      _values[i] = memberMap._values[i];
-    }
-    _size = memberMap._size;
-  }
-
-  /**
    * Initialize a newly created member map to contain the same members as the
    * given [memberMap].
    */
@@ -9617,25 +7562,18 @@
  */
 class PartialResolverVisitor extends ResolverVisitor {
   /**
-   * A flag indicating whether the resolver is being run in strong mode.
-   */
-  final bool strongMode;
-
-  /**
    * The static variables and fields that have an initializer. These are the
    * variables that need to be re-resolved after static variables have their
    * types inferred. A subset of these variables are those whose types should
-   * be inferred. The list will be empty unless the resolver is being run in
-   * strong mode.
+   * be inferred.
    */
-  final List<VariableElement> variablesAndFields = <VariableElement>[];
+  final List<VariableElement> staticVariables = <VariableElement>[];
 
   /**
-   * A flag indicating whether we should discard errors while resolving the
-   * initializer for variable declarations. We do this for top-level variables
-   * and fields because their initializer will be re-resolved at a later time.
+   * The static and instance variables and fields that have an initializer.
+   * These are the variables whose types might be propagated.
    */
-  bool discardErrorsInInitializer = false;
+  final List<VariableElement> propagableVariables = <VariableElement>[];
 
   /**
    * Initialize a newly created visitor to resolve the nodes in an AST node.
@@ -9656,12 +7594,9 @@
    */
   PartialResolverVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
-      {Scope nameScope,
-      InheritanceManager inheritanceManager,
-      StaticTypeAnalyzerFactory typeAnalyzerFactory})
-      : strongMode = definingLibrary.context.analysisOptions.strongMode,
-        super(definingLibrary, source, typeProvider,
-            new DisablableErrorListener(errorListener));
+      {Scope nameScope})
+      : super(definingLibrary, source, typeProvider, errorListener,
+            nameScope: nameScope);
 
   @override
   Object visitBlockFunctionBody(BlockFunctionBody node) {
@@ -9681,44 +7616,37 @@
 
   @override
   Object visitFieldDeclaration(FieldDeclaration node) {
-    if (strongMode && node.isStatic) {
-      _addVariables(node.fields.variables);
-      bool wasDiscarding = discardErrorsInInitializer;
-      discardErrorsInInitializer = true;
-      try {
-        return super.visitFieldDeclaration(node);
-      } finally {
-        discardErrorsInInitializer = wasDiscarding;
-      }
+    _addPropagableVariables(node.fields.variables);
+    if (node.isStatic) {
+      _addStaticVariables(node.fields.variables);
     }
     return super.visitFieldDeclaration(node);
   }
 
   @override
   Object visitNode(AstNode node) {
-    if (discardErrorsInInitializer) {
-      AstNode parent = node.parent;
-      if (parent is VariableDeclaration && parent.initializer == node) {
-        DisablableErrorListener listener = errorListener;
-        return listener.disableWhile(() => super.visitNode(node));
-      }
-    }
     return super.visitNode(node);
   }
 
   @override
   Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    if (strongMode) {
-      _addVariables(node.variables.variables);
-      bool wasDiscarding = discardErrorsInInitializer;
-      discardErrorsInInitializer = true;
-      try {
-        return super.visitTopLevelVariableDeclaration(node);
-      } finally {
-        discardErrorsInInitializer = wasDiscarding;
+    _addPropagableVariables(node.variables.variables);
+    _addStaticVariables(node.variables.variables);
+    return super.visitTopLevelVariableDeclaration(node);
+  }
+
+  /**
+   * Add all of the [variables] with initializers to [propagableVariables].
+   */
+  void _addPropagableVariables(List<VariableDeclaration> variables) {
+    for (VariableDeclaration variable in variables) {
+      if (variable.initializer != null) {
+        VariableElement element = variable.element;
+        if (element.isConst || element.isFinal) {
+          propagableVariables.add(element);
+        }
       }
     }
-    return super.visitTopLevelVariableDeclaration(node);
   }
 
   /**
@@ -9728,10 +7656,10 @@
    * potentially need to be re-resolved after inference because they might
    * refer to a field whose type was inferred.
    */
-  void _addVariables(NodeList<VariableDeclaration> variables) {
+  void _addStaticVariables(List<VariableDeclaration> variables) {
     for (VariableDeclaration variable in variables) {
       if (variable.initializer != null) {
-        variablesAndFields.add(variable.element);
+        staticVariables.add(variable.element);
       }
     }
   }
@@ -9970,273 +7898,6 @@
 }
 
 /**
- * A `ResolvableLibrary` represents a single library during the resolution of
- * some (possibly different) library. They are not intended to be used except
- * during the resolution process.
- */
-class ResolvableLibrary {
-  /**
-   * An empty array that can be used to initialize lists of libraries.
-   */
-  static List<ResolvableLibrary> _EMPTY_ARRAY = new List<ResolvableLibrary>(0);
-
-  /**
-   * The next artificial hash code.
-   */
-  static int _NEXT_HASH_CODE = 0;
-
-  /**
-   * The artifitial hash code for this object.
-   */
-  final int _hashCode = _nextHashCode();
-
-  /**
-   * The source specifying the defining compilation unit of this library.
-   */
-  final Source librarySource;
-
-  /**
-   * A list containing all of the libraries that are imported into this library.
-   */
-  List<ResolvableLibrary> _importedLibraries = _EMPTY_ARRAY;
-
-  /**
-   * A flag indicating whether this library explicitly imports core.
-   */
-  bool explicitlyImportsCore = false;
-
-  /**
-   * An array containing all of the libraries that are exported from this library.
-   */
-  List<ResolvableLibrary> _exportedLibraries = _EMPTY_ARRAY;
-
-  /**
-   * An array containing the compilation units that comprise this library. The
-   * defining compilation unit is always first.
-   */
-  List<ResolvableCompilationUnit> _compilationUnits;
-
-  /**
-   * The library element representing this library.
-   */
-  LibraryElementImpl _libraryElement;
-
-  /**
-   * The listener to which analysis errors will be reported.
-   */
-  AnalysisErrorListener _errorListener;
-
-  /**
-   * The inheritance manager which is used for member lookups in this library.
-   */
-  InheritanceManager _inheritanceManager;
-
-  /**
-   * The library scope used when resolving elements within this library's compilation units.
-   */
-  LibraryScope _libraryScope;
-
-  /**
-   * Initialize a newly created data holder that can maintain the data associated with a library.
-   *
-   * @param librarySource the source specifying the defining compilation unit of this library
-   * @param errorListener the listener to which analysis errors will be reported
-   */
-  ResolvableLibrary(this.librarySource);
-
-  /**
-   * Return an array of the [CompilationUnit]s that make up the library. The first unit is
-   * always the defining unit.
-   *
-   * @return an array of the [CompilationUnit]s that make up the library. The first unit is
-   *         always the defining unit
-   */
-  List<CompilationUnit> get compilationUnits {
-    int count = _compilationUnits.length;
-    List<CompilationUnit> units = new List<CompilationUnit>(count);
-    for (int i = 0; i < count; i++) {
-      units[i] = _compilationUnits[i].compilationUnit;
-    }
-    return units;
-  }
-
-  /**
-   * Return an array containing the sources for the compilation units in this library, including the
-   * defining compilation unit.
-   *
-   * @return the sources for the compilation units in this library
-   */
-  List<Source> get compilationUnitSources {
-    int count = _compilationUnits.length;
-    List<Source> sources = new List<Source>(count);
-    for (int i = 0; i < count; i++) {
-      sources[i] = _compilationUnits[i].source;
-    }
-    return sources;
-  }
-
-  /**
-   * Return the AST structure associated with the defining compilation unit for this library.
-   *
-   * @return the AST structure associated with the defining compilation unit for this library
-   * @throws AnalysisException if an AST structure could not be created for the defining compilation
-   *           unit
-   */
-  CompilationUnit get definingCompilationUnit =>
-      _compilationUnits[0].compilationUnit;
-
-  /**
-   * Set the listener to which analysis errors will be reported to be the given listener.
-   *
-   * @param errorListener the listener to which analysis errors will be reported
-   */
-  void set errorListener(AnalysisErrorListener errorListener) {
-    this._errorListener = errorListener;
-  }
-
-  /**
-   * Set the libraries that are exported by this library to be those in the given array.
-   *
-   * @param exportedLibraries the libraries that are exported by this library
-   */
-  void set exportedLibraries(List<ResolvableLibrary> exportedLibraries) {
-    this._exportedLibraries = exportedLibraries;
-  }
-
-  /**
-   * Return an array containing the libraries that are exported from this library.
-   *
-   * @return an array containing the libraries that are exported from this library
-   */
-  List<ResolvableLibrary> get exports => _exportedLibraries;
-
-  @override
-  int get hashCode => _hashCode;
-
-  /**
-   * Set the libraries that are imported into this library to be those in the given array.
-   *
-   * @param importedLibraries the libraries that are imported into this library
-   */
-  void set importedLibraries(List<ResolvableLibrary> importedLibraries) {
-    this._importedLibraries = importedLibraries;
-  }
-
-  /**
-   * Return an array containing the libraries that are imported into this library.
-   *
-   * @return an array containing the libraries that are imported into this library
-   */
-  List<ResolvableLibrary> get imports => _importedLibraries;
-
-  /**
-   * Return an array containing the libraries that are either imported or exported from this
-   * library.
-   *
-   * @return the libraries that are either imported or exported from this library
-   */
-  List<ResolvableLibrary> get importsAndExports {
-    HashSet<ResolvableLibrary> libraries = new HashSet<ResolvableLibrary>();
-    for (ResolvableLibrary library in _importedLibraries) {
-      libraries.add(library);
-    }
-    for (ResolvableLibrary library in _exportedLibraries) {
-      libraries.add(library);
-    }
-    return new List.from(libraries);
-  }
-
-  /**
-   * Return the inheritance manager for this library.
-   *
-   * @return the inheritance manager for this library
-   */
-  InheritanceManager get inheritanceManager {
-    if (_inheritanceManager == null) {
-      return _inheritanceManager = new InheritanceManager(_libraryElement);
-    }
-    return _inheritanceManager;
-  }
-
-  /**
-   * Return the library element representing this library, creating it if necessary.
-   *
-   * @return the library element representing this library
-   */
-  LibraryElementImpl get libraryElement => _libraryElement;
-
-  /**
-   * Set the library element representing this library to the given library element.
-   *
-   * @param libraryElement the library element representing this library
-   */
-  void set libraryElement(LibraryElementImpl libraryElement) {
-    this._libraryElement = libraryElement;
-    if (_inheritanceManager != null) {
-      _inheritanceManager.libraryElement = libraryElement;
-    }
-  }
-
-  /**
-   * Return the library scope used when resolving elements within this library's compilation units.
-   *
-   * @return the library scope used when resolving elements within this library's compilation units
-   */
-  LibraryScope get libraryScope {
-    if (_libraryScope == null) {
-      _libraryScope = new LibraryScope(_libraryElement, _errorListener);
-    }
-    return _libraryScope;
-  }
-
-  /**
-   * Return an array containing the compilation units that comprise this library. The defining
-   * compilation unit is always first.
-   *
-   * @return the compilation units that comprise this library
-   */
-  List<ResolvableCompilationUnit> get resolvableCompilationUnits =>
-      _compilationUnits;
-
-  /**
-   * Set the compilation unit in this library to the given compilation units. The defining
-   * compilation unit must be the first element of the array.
-   *
-   * @param units the compilation units in this library
-   */
-  void set resolvableCompilationUnits(List<ResolvableCompilationUnit> units) {
-    _compilationUnits = units;
-  }
-
-  /**
-   * Return the AST structure associated with the given source, or `null` if the source does
-   * not represent a compilation unit that is included in this library.
-   *
-   * @param source the source representing the compilation unit whose AST is to be returned
-   * @return the AST structure associated with the given source
-   * @throws AnalysisException if an AST structure could not be created for the compilation unit
-   */
-  CompilationUnit getAST(Source source) {
-    int count = _compilationUnits.length;
-    for (int i = 0; i < count; i++) {
-      if (_compilationUnits[i].source == source) {
-        return _compilationUnits[i].compilationUnit;
-      }
-    }
-    return null;
-  }
-
-  @override
-  String toString() => librarySource.shortName;
-
-  static int _nextHashCode() {
-    int next = (_NEXT_HASH_CODE + 1) & 0xFFFFFF;
-    _NEXT_HASH_CODE = next;
-    return next;
-  }
-}
-
-/**
  * The enumeration `ResolverErrorCode` defines the error codes used for errors
  * detected by the resolver. The convention for this class is for the name of
  * the error code to indicate the problem that caused the error to be generated
@@ -10278,11 +7939,6 @@
  */
 class ResolverVisitor extends ScopedVisitor {
   /**
-   * The manager for the inheritance mappings.
-   */
-  InheritanceManager _inheritanceManager;
-
-  /**
    * The object used to resolve the element associated with the current node.
    */
   ElementResolver elementResolver;
@@ -10293,8 +7949,8 @@
   StaticTypeAnalyzer typeAnalyzer;
 
   /*
-  * The type system in use during resolution.
-  */
+   * The type system in use during resolution.
+   */
   TypeSystem typeSystem;
 
   /**
@@ -10321,11 +7977,7 @@
    */
   ExecutableElement _enclosingFunction = null;
 
-  /**
-   * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that
-   * cannot be resolved where we visited it, because it should be resolved in the scope of the body.
-   */
-  Comment _commentBeforeFunction = null;
+  InferenceContext inferenceContext = null;
 
   /**
    * The object keeping track of which elements have had their types overridden.
@@ -10366,45 +8018,22 @@
    */
   ResolverVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
-      {Scope nameScope,
-      InheritanceManager inheritanceManager,
-      StaticTypeAnalyzerFactory typeAnalyzerFactory})
+      {Scope nameScope})
       : super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope) {
-    if (inheritanceManager == null) {
-      this._inheritanceManager = new InheritanceManager(definingLibrary);
-    } else {
-      this._inheritanceManager = inheritanceManager;
-    }
     this.elementResolver = new ElementResolver(this);
     this.typeSystem = definingLibrary.context.typeSystem;
-    if (typeAnalyzerFactory == null) {
-      this.typeAnalyzer = new StaticTypeAnalyzer(this);
-    } else {
-      this.typeAnalyzer = typeAnalyzerFactory(this);
+    bool strongModeHints = false;
+    AnalysisOptions options = definingLibrary.context.analysisOptions;
+    if (options is AnalysisOptionsImpl) {
+      strongModeHints = options.strongModeHints;
     }
+    this.inferenceContext = new InferenceContext._(
+        errorListener, typeProvider, typeSystem, strongModeHints);
+    this.typeAnalyzer = new StaticTypeAnalyzer(this);
   }
 
   /**
-   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
-   *
-   * @param library the library containing the compilation unit being resolved
-   * @param source the source representing the compilation unit being visited
-   * @param typeProvider the object used to access the types from the core library
-   *
-   * Deprecated.  Please use unnamed constructor instead.
-   */
-  @deprecated
-  ResolverVisitor.con1(
-      Library library, Source source, TypeProvider typeProvider,
-      {StaticTypeAnalyzerFactory typeAnalyzerFactory})
-      : this(
-            library.libraryElement, source, typeProvider, library.errorListener,
-            nameScope: library.libraryScope,
-            inheritanceManager: library.inheritanceManager,
-            typeAnalyzerFactory: typeAnalyzerFactory);
-
-  /**
    * Return the element representing the function containing the current node, or `null` if
    * the current node is not contained in a function.
    *
@@ -10508,7 +8137,6 @@
       if (element is ExecutableElement) {
         _enclosingFunction = element;
       }
-      _commentBeforeFunction = declaration.documentationComment;
     }
     _overrideManager.enterScope();
   }
@@ -10643,6 +8271,15 @@
     expression.propagatedType = type;
   }
 
+  /**
+   * Visit the given [comment] if it is not `null`.
+   */
+  void safelyVisitComment(Comment comment) {
+    if (comment != null) {
+      super.visitComment(comment);
+    }
+  }
+
   @override
   Object visitAnnotation(Annotation node) {
     AstNode parent = node.parent;
@@ -10650,11 +8287,65 @@
         identical(parent, _enclosingFunctionTypeAlias)) {
       return null;
     }
-    return super.visitAnnotation(node);
+    safelyVisit(node.name);
+    safelyVisit(node.constructorName);
+    Element element = node.element;
+    if (element is ExecutableElement) {
+      InferenceContext.setType(node.arguments, element.type);
+    }
+    safelyVisit(node.arguments);
+    node.accept(elementResolver);
+    node.accept(typeAnalyzer);
+    return null;
+  }
+
+  @override
+  Object visitArgumentList(ArgumentList node) {
+    DartType callerType = InferenceContext.getType(node);
+    if (callerType is FunctionType) {
+      Map<String, DartType> namedParameterTypes =
+          callerType.namedParameterTypes;
+      List<DartType> normalParameterTypes = callerType.normalParameterTypes;
+      List<DartType> optionalParameterTypes = callerType.optionalParameterTypes;
+      int normalCount = normalParameterTypes.length;
+      int optionalCount = optionalParameterTypes.length;
+
+      NodeList<Expression> arguments = node.arguments;
+      Iterable<Expression> positional =
+          arguments.takeWhile((l) => l is! NamedExpression);
+      Iterable<Expression> required = positional.take(normalCount);
+      Iterable<Expression> optional =
+          positional.skip(normalCount).take(optionalCount);
+      Iterable<Expression> named =
+          arguments.skipWhile((l) => l is! NamedExpression);
+
+      //TODO(leafp): Consider using the parameter elements here instead.
+      //TODO(leafp): Make sure that the parameter elements are getting
+      // setup correctly with inference.
+      int index = 0;
+      for (Expression argument in required) {
+        InferenceContext.setType(argument, normalParameterTypes[index++]);
+      }
+      index = 0;
+      for (Expression argument in optional) {
+        InferenceContext.setType(argument, optionalParameterTypes[index++]);
+      }
+
+      for (Expression argument in named) {
+        if (argument is NamedExpression) {
+          DartType type = namedParameterTypes[argument.name.label.name];
+          if (type != null) {
+            InferenceContext.setType(argument, type);
+          }
+        }
+      }
+    }
+    return super.visitArgumentList(node);
   }
 
   @override
   Object visitAsExpression(AsExpression node) {
+    InferenceContext.setType(node.expression, node.type.type);
     super.visitAsExpression(node);
     // Since an as-statement doesn't actually change the type, we don't
     // let it affect the propagated type when it would result in a loss
@@ -10671,11 +8362,40 @@
   }
 
   @override
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    safelyVisit(node.leftHandSide);
+    TokenType operator = node.operator.type;
+    if (operator == TokenType.EQ ||
+        operator == TokenType.QUESTION_QUESTION_EQ) {
+      InferenceContext.setType(
+          node.rightHandSide, node.leftHandSide.staticType);
+    }
+    safelyVisit(node.rightHandSide);
+    node.accept(elementResolver);
+    node.accept(typeAnalyzer);
+    return null;
+  }
+
+  @override
+  Object visitAwaitExpression(AwaitExpression node) {
+    // TODO(leafp): Handle the implicit union type here
+    // https://github.com/dart-lang/sdk/issues/25322
+    DartType contextType = StaticTypeAnalyzer.flattenFutures(
+        typeProvider, InferenceContext.getType(node));
+    if (contextType != null) {
+      InterfaceType futureT =
+          typeProvider.futureType.substitute4([contextType]);
+      InferenceContext.setType(node.expression, futureT);
+    }
+    return super.visitAwaitExpression(node);
+  }
+
+  @override
   Object visitBinaryExpression(BinaryExpression node) {
-    sc.TokenType operatorType = node.operator.type;
+    TokenType operatorType = node.operator.type;
     Expression leftOperand = node.leftOperand;
     Expression rightOperand = node.rightOperand;
-    if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) {
+    if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
       safelyVisit(leftOperand);
       if (rightOperand != null) {
         _overrideManager.enterScope();
@@ -10698,7 +8418,7 @@
           _overrideManager.exitScope();
         }
       }
-    } else if (operatorType == sc.TokenType.BAR_BAR) {
+    } else if (operatorType == TokenType.BAR_BAR) {
       safelyVisit(leftOperand);
       if (rightOperand != null) {
         _overrideManager.enterScope();
@@ -10710,6 +8430,12 @@
         }
       }
     } else {
+      // TODO(leafp): Do downwards inference using the declared type
+      // of the binary operator for other cases.
+      if (operatorType == TokenType.QUESTION_QUESTION) {
+        InferenceContext.setTypeFromNode(leftOperand, node);
+        InferenceContext.setTypeFromNode(rightOperand, node);
+      }
       safelyVisit(leftOperand);
       safelyVisit(rightOperand);
     }
@@ -10720,12 +8446,13 @@
 
   @override
   Object visitBlockFunctionBody(BlockFunctionBody node) {
-    safelyVisit(_commentBeforeFunction);
     _overrideManager.enterScope();
     try {
+      inferenceContext.pushReturnContext(InferenceContext.getType(node));
       super.visitBlockFunctionBody(node);
     } finally {
       _overrideManager.exitScope();
+      inferenceContext.popReturnContext();
     }
     return null;
   }
@@ -10742,6 +8469,12 @@
   }
 
   @override
+  Object visitCascadeExpression(CascadeExpression node) {
+    InferenceContext.setTypeFromNode(node.target, node);
+    return super.visitCascadeExpression(node);
+  }
+
+  @override
   Object visitClassDeclaration(ClassDeclaration node) {
     //
     // Resolve the metadata in the library scope.
@@ -10792,16 +8525,14 @@
 
   @override
   Object visitComment(Comment node) {
-    if (node.parent is FunctionDeclaration ||
-        node.parent is ConstructorDeclaration ||
-        node.parent is MethodDeclaration) {
-      if (!identical(node, _commentBeforeFunction)) {
-        _commentBeforeFunction = node;
-        return null;
-      }
+    AstNode parent = node.parent;
+    if (parent is FunctionDeclaration ||
+        parent is FunctionTypeAlias ||
+        parent is ConstructorDeclaration ||
+        parent is MethodDeclaration) {
+      return null;
     }
     super.visitComment(node);
-    _commentBeforeFunction = null;
     return null;
   }
 
@@ -10874,6 +8605,7 @@
           _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
               thenExpression);
           // Visit "then" expression.
+          InferenceContext.setTypeFromNode(thenExpression, node);
           thenExpression.accept(this);
         } finally {
           _promoteManager.exitScope();
@@ -10887,6 +8619,7 @@
       _overrideManager.enterScope();
       try {
         _propagateFalseState(condition);
+        InferenceContext.setTypeFromNode(elseExpression, node);
         elseExpression.accept(this);
       } finally {
         _overrideManager.exitScope();
@@ -10911,6 +8644,8 @@
     ExecutableElement outerFunction = _enclosingFunction;
     try {
       _enclosingFunction = node.element;
+      FunctionType type = _enclosingFunction.type;
+      InferenceContext.setType(node.body, type.returnType);
       super.visitConstructorDeclaration(node);
     } finally {
       _enclosingFunction = outerFunction;
@@ -10922,11 +8657,19 @@
   }
 
   @override
+  void visitConstructorDeclarationInScope(ConstructorDeclaration node) {
+    super.visitConstructorDeclarationInScope(node);
+    safelyVisitComment(node.documentationComment);
+  }
+
+  @override
   Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     //
     // We visit the expression, but do not visit the field name because it needs
     // to be visited in the context of the constructor field initializer node.
     //
+    FieldElement fieldElement = enclosingClass.getField(node.fieldName.name);
+    InferenceContext.setType(node.expression, fieldElement?.type);
     safelyVisit(node.expression);
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
@@ -10958,22 +8701,17 @@
 
   @override
   Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    InferenceContext.setType(node.defaultValue, node.parameter.element?.type);
     super.visitDefaultFormalParameter(node);
     ParameterElement element = node.element;
     if (element.initializer != null && node.defaultValue != null) {
       (element.initializer as FunctionElementImpl).returnType =
           node.defaultValue.staticType;
     }
-    FormalParameterList parent = node.parent;
-    AstNode grandparent = parent.parent;
-    if (grandparent is ConstructorDeclaration &&
-        grandparent.constKeyword != null) {
-      // For const constructors, we need to clone the ASTs for default formal
-      // parameters, so that we can use them during constant evaluation.
-      ParameterElement element = node.element;
-      (element as ConstVariableElement).constantInitializer =
-          new ConstantAstCloner().cloneNode(node.defaultValue);
-    }
+    // Clone the ASTs for default formal parameters, so that we can use them
+    // during constant evaluation.
+    (element as ConstVariableElement).constantInitializer =
+        new ConstantAstCloner().cloneNode(node.defaultValue);
     return null;
   }
 
@@ -10992,7 +8730,6 @@
 
   @override
   Object visitEmptyFunctionBody(EmptyFunctionBody node) {
-    safelyVisit(_commentBeforeFunction);
     if (resolveOnlyCommentInFunctionBody) {
       return null;
     }
@@ -11030,12 +8767,12 @@
 
   @override
   Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    safelyVisit(_commentBeforeFunction);
     if (resolveOnlyCommentInFunctionBody) {
       return null;
     }
     _overrideManager.enterScope();
     try {
+      InferenceContext.setTypeFromNode(node.expression, node);
       super.visitExpressionFunctionBody(node);
     } finally {
       _overrideManager.exitScope();
@@ -11075,9 +8812,16 @@
     // cannot be in scope while visiting the iterator.
     //
     Expression iterable = node.iterable;
-    safelyVisit(iterable);
     DeclaredIdentifier loopVariable = node.loopVariable;
     SimpleIdentifier identifier = node.identifier;
+    if (loopVariable?.type?.type != null) {
+      InterfaceType targetType = (node.awaitKeyword == null)
+          ? typeProvider.iterableType
+          : typeProvider.streamType;
+      InferenceContext.setType(
+          iterable, targetType.substitute4([loopVariable.type.type]));
+    }
+    safelyVisit(iterable);
     safelyVisit(loopVariable);
     safelyVisit(identifier);
     Statement body = node.body;
@@ -11150,6 +8894,8 @@
     try {
       SimpleIdentifier functionName = node.name;
       _enclosingFunction = functionName.staticElement as ExecutableElement;
+      InferenceContext.setType(
+          node.functionExpression, _enclosingFunction.type);
       super.visitFunctionDeclaration(node);
     } finally {
       _enclosingFunction = outerFunction;
@@ -11158,12 +8904,27 @@
   }
 
   @override
+  void visitFunctionDeclarationInScope(FunctionDeclaration node) {
+    super.visitFunctionDeclarationInScope(node);
+    safelyVisitComment(node.documentationComment);
+  }
+
+  @override
   Object visitFunctionExpression(FunctionExpression node) {
     ExecutableElement outerFunction = _enclosingFunction;
     try {
       _enclosingFunction = node.element;
       _overrideManager.enterScope();
       try {
+        DartType functionType = InferenceContext.getType(node);
+        if (functionType is FunctionType) {
+          _inferFormalParameterList(node.parameters, functionType);
+          DartType returnType = _computeReturnOrYieldType(
+              functionType.returnType,
+              _enclosingFunction.isGenerator,
+              _enclosingFunction.isAsynchronous);
+          InferenceContext.setType(node.body, returnType);
+        }
         super.visitFunctionExpression(node);
       } finally {
         _overrideManager.exitScope();
@@ -11179,6 +8940,7 @@
     safelyVisit(node.function);
     node.accept(elementResolver);
     _inferFunctionExpressionsParametersTypes(node.argumentList);
+    InferenceContext.setType(node.argumentList, node.function.staticType);
     safelyVisit(node.argumentList);
     node.accept(typeAnalyzer);
     return null;
@@ -11201,6 +8963,12 @@
   }
 
   @override
+  void visitFunctionTypeAliasInScope(FunctionTypeAlias node) {
+    super.visitFunctionTypeAliasInScope(node);
+    safelyVisitComment(node.documentationComment);
+  }
+
+  @override
   Object visitHideCombinator(HideCombinator node) => null;
 
   @override
@@ -11266,16 +9034,105 @@
   }
 
   @override
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    TypeName classTypeName = node.constructorName.type;
+    if (classTypeName.typeArguments == null) {
+      DartType contextType = InferenceContext.getType(node);
+      if (contextType is InterfaceType &&
+          contextType.typeArguments != null &&
+          contextType.typeArguments.length > 0) {
+        List<DartType> targs =
+            inferenceContext.matchTypes(classTypeName.type, contextType);
+        if (targs != null && targs.any((t) => !t.isDynamic)) {
+          ClassElement classElement = classTypeName.type.element;
+          InterfaceType rawType = classElement.type;
+          InterfaceType fullType =
+              rawType.substitute2(targs, rawType.typeArguments);
+          // The element resolver uses the type on the constructor name, so
+          // infer it first
+          typeAnalyzer.inferConstructorName(node.constructorName, fullType);
+        }
+      }
+    }
+    safelyVisit(node.constructorName);
+    FunctionType constructorType = node.constructorName.staticElement?.type;
+    if (constructorType != null) {
+      InferenceContext.setType(node.argumentList, constructorType);
+    }
+    safelyVisit(node.argumentList);
+    node.accept(elementResolver);
+    node.accept(typeAnalyzer);
+    return null;
+  }
+
+  @override
   Object visitLabel(Label node) => null;
 
   @override
   Object visitLibraryIdentifier(LibraryIdentifier node) => null;
 
   @override
+  Object visitListLiteral(ListLiteral node) {
+    DartType contextType = InferenceContext.getType(node);
+    List<DartType> targs = null;
+    if (node.typeArguments != null) {
+      targs = node.typeArguments.arguments.map((t) => t.type).toList();
+    } else if (contextType is InterfaceType) {
+      InterfaceType listD =
+          typeProvider.listType.substitute4([typeProvider.dynamicType]);
+      targs = inferenceContext.matchTypes(listD, contextType);
+    }
+    if (targs != null && targs.length == 1 && !targs[0].isDynamic) {
+      DartType eType = targs[0];
+      InterfaceType listT = typeProvider.listType.substitute4([eType]);
+      for (Expression child in node.elements) {
+        InferenceContext.setType(child, eType);
+      }
+      InferenceContext.setType(node, listT);
+    } else {
+      InferenceContext.clearType(node);
+    }
+    super.visitListLiteral(node);
+    return null;
+  }
+
+  @override
+  Object visitMapLiteral(MapLiteral node) {
+    DartType contextType = InferenceContext.getType(node);
+    List<DartType> targs = null;
+    if (node.typeArguments != null) {
+      targs = node.typeArguments.arguments.map((t) => t.type).toList();
+    } else if (contextType is InterfaceType) {
+      InterfaceType mapD = typeProvider.mapType
+          .substitute4([typeProvider.dynamicType, typeProvider.dynamicType]);
+      targs = inferenceContext.matchTypes(mapD, contextType);
+    }
+    if (targs != null && targs.length == 2 && targs.any((t) => !t.isDynamic)) {
+      DartType kType = targs[0];
+      DartType vType = targs[1];
+      InterfaceType mapT = typeProvider.mapType.substitute4([kType, vType]);
+      for (MapLiteralEntry entry in node.entries) {
+        InferenceContext.setType(entry.key, kType);
+        InferenceContext.setType(entry.value, vType);
+      }
+      InferenceContext.setType(node, mapT);
+    } else {
+      InferenceContext.clearType(node);
+    }
+    super.visitMapLiteral(node);
+    return null;
+  }
+
+  @override
   Object visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
     try {
       _enclosingFunction = node.element;
+      DartType returnType = _computeReturnOrYieldType(
+          _enclosingFunction.type?.returnType,
+          _enclosingFunction.isGenerator,
+          _enclosingFunction.isAsynchronous);
+      InferenceContext.setType(node.body, returnType);
       super.visitMethodDeclaration(node);
     } finally {
       _enclosingFunction = outerFunction;
@@ -11284,19 +9141,135 @@
   }
 
   @override
+  void visitMethodDeclarationInScope(MethodDeclaration node) {
+    super.visitMethodDeclarationInScope(node);
+    safelyVisitComment(node.documentationComment);
+  }
+
+  @override
   Object visitMethodInvocation(MethodInvocation node) {
     //
     // We visit the target and argument list, but do not visit the method name
     // because it needs to be visited in the context of the invocation.
     //
     safelyVisit(node.target);
+    safelyVisit(node.typeArguments);
     node.accept(elementResolver);
     _inferFunctionExpressionsParametersTypes(node.argumentList);
+    DartType contextType = node.staticInvokeType;
+    if (contextType is FunctionType) {
+      InferenceContext.setType(node.argumentList, contextType);
+    }
     safelyVisit(node.argumentList);
     node.accept(typeAnalyzer);
     return null;
   }
 
+  /**
+   * Given an [argumentList] and the [parameters] related to the element that
+   * will be invoked using those arguments, compute the list of parameters that
+   * correspond to the list of arguments.
+   *
+   * An error will be reported to [onError] if any of the arguments cannot be
+   * matched to a parameter. onError can be null to ignore the error.
+   *
+   * The flag [reportAsError] should be `true` if a compile-time error should be
+   * reported; or `false` if a compile-time warning should be reported
+   *
+   * Returns the parameters that correspond to the arguments.
+   */
+  static List<ParameterElement> resolveArgumentsToParameters(
+      ArgumentList argumentList,
+      List<ParameterElement> parameters,
+      void onError(ErrorCode errorCode, AstNode node, [List<Object> arguments]),
+      {bool reportAsError: false}) {
+    List<ParameterElement> requiredParameters = new List<ParameterElement>();
+    List<ParameterElement> positionalParameters = new List<ParameterElement>();
+    HashMap<String, ParameterElement> namedParameters =
+        new HashMap<String, ParameterElement>();
+    for (ParameterElement parameter in parameters) {
+      ParameterKind kind = parameter.parameterKind;
+      if (kind == ParameterKind.REQUIRED) {
+        requiredParameters.add(parameter);
+      } else if (kind == ParameterKind.POSITIONAL) {
+        positionalParameters.add(parameter);
+      } else {
+        namedParameters[parameter.name] = parameter;
+      }
+    }
+    List<ParameterElement> unnamedParameters =
+        new List<ParameterElement>.from(requiredParameters);
+    unnamedParameters.addAll(positionalParameters);
+    int unnamedParameterCount = unnamedParameters.length;
+    int unnamedIndex = 0;
+    NodeList<Expression> arguments = argumentList.arguments;
+    int argumentCount = arguments.length;
+    List<ParameterElement> resolvedParameters =
+        new List<ParameterElement>(argumentCount);
+    int positionalArgumentCount = 0;
+    HashSet<String> usedNames = new HashSet<String>();
+    bool noBlankArguments = true;
+    for (int i = 0; i < argumentCount; i++) {
+      Expression argument = arguments[i];
+      if (argument is NamedExpression) {
+        SimpleIdentifier nameNode = argument.name.label;
+        String name = nameNode.name;
+        ParameterElement element = namedParameters[name];
+        if (element == null) {
+          ErrorCode errorCode = (reportAsError
+              ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER
+              : StaticWarningCode.UNDEFINED_NAMED_PARAMETER);
+          if (onError != null) {
+            onError(errorCode, nameNode, [name]);
+          }
+        } else {
+          resolvedParameters[i] = element;
+          nameNode.staticElement = element;
+        }
+        if (!usedNames.add(name)) {
+          if (onError != null) {
+            onError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode,
+                [name]);
+          }
+        }
+      } else {
+        if (argument is SimpleIdentifier && argument.name.isEmpty) {
+          noBlankArguments = false;
+        }
+        positionalArgumentCount++;
+        if (unnamedIndex < unnamedParameterCount) {
+          resolvedParameters[i] = unnamedParameters[unnamedIndex++];
+        }
+      }
+    }
+    if (positionalArgumentCount < requiredParameters.length &&
+        noBlankArguments) {
+      ErrorCode errorCode = (reportAsError
+          ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS
+          : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
+      if (onError != null) {
+        onError(errorCode, argumentList,
+            [requiredParameters.length, positionalArgumentCount]);
+      }
+    } else if (positionalArgumentCount > unnamedParameterCount &&
+        noBlankArguments) {
+      ErrorCode errorCode = (reportAsError
+          ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS
+          : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
+      if (onError != null) {
+        onError(errorCode, argumentList,
+            [unnamedParameterCount, positionalArgumentCount]);
+      }
+    }
+    return resolvedParameters;
+  }
+
+  @override
+  Object visitNamedExpression(NamedExpression node) {
+    InferenceContext.setType(node.expression, InferenceContext.getType(node));
+    return super.visitNamedExpression(node);
+  }
+
   @override
   Object visitNode(AstNode node) {
     node.visitChildren(this);
@@ -11306,6 +9279,12 @@
   }
 
   @override
+  Object visitParenthesizedExpression(ParenthesizedExpression node) {
+    InferenceContext.setType(node.expression, InferenceContext.getType(node));
+    return super.visitParenthesizedExpression(node);
+  }
+
+  @override
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
     //
     // We visit the prefix, but do not visit the identifier because it needs to
@@ -11337,6 +9316,7 @@
     // because it needs to be visited in the context of the constructor
     // invocation.
     //
+    InferenceContext.setType(node.argumentList, node.staticElement?.type);
     safelyVisit(node.argumentList);
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
@@ -11344,6 +9324,12 @@
   }
 
   @override
+  Object visitReturnStatement(ReturnStatement node) {
+    InferenceContext.setType(node.expression, inferenceContext.returnContext);
+    return super.visitReturnStatement(node);
+  }
+
+  @override
   Object visitShowCombinator(ShowCombinator node) => null;
 
   @override
@@ -11353,6 +9339,7 @@
     // because it needs to be visited in the context of the constructor
     // invocation.
     //
+    InferenceContext.setType(node.argumentList, node.staticElement?.type);
     safelyVisit(node.argumentList);
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
@@ -11400,6 +9387,7 @@
 
   @override
   Object visitVariableDeclaration(VariableDeclaration node) {
+    InferenceContext.setType(node.initializer, InferenceContext.getType(node));
     super.visitVariableDeclaration(node);
     VariableElement element = node.element;
     if (element.initializer != null && node.initializer != null) {
@@ -11421,6 +9409,13 @@
     return null;
   }
 
+  @override visitVariableDeclarationList(VariableDeclarationList node) {
+    for (VariableDeclaration decl in node.variables) {
+      InferenceContext.setType(decl, node.type?.type);
+    }
+    super.visitVariableDeclarationList(node);
+  }
+
   @override
   Object visitWhileStatement(WhileStatement node) {
     // Note: since we don't call the base class, we have to maintain
@@ -11450,6 +9445,29 @@
     return null;
   }
 
+  @override
+  Object visitYieldStatement(YieldStatement node) {
+    DartType returnType = inferenceContext.returnContext;
+    if (returnType != null && _enclosingFunction != null) {
+      // If we're not in a generator ([a]sync*, then we shouldn't have a yield.
+      // so don't infer
+      if (_enclosingFunction.isGenerator) {
+        // If this just a yield, then we just pass on the element type
+        DartType type = returnType;
+        if (node.star != null) {
+          // If this is a yield*, then we wrap the element return type
+          // If it's synchronous, we expect Iterable<T>, otherwise Stream<T>
+          InterfaceType wrapperType = _enclosingFunction.isSynchronous
+              ? typeProvider.iterableType
+              : typeProvider.streamType;
+          type = wrapperType.substitute4(<DartType>[type]);
+        }
+        InferenceContext.setType(node.expression, type);
+      }
+    }
+    return super.visitYieldStatement(node);
+  }
+
   /**
    * Checks each promoted variable in the current scope for compliance with the following
    * specification statement:
@@ -11483,6 +9501,34 @@
   }
 
   /**
+   * Given the declared return type of a function, compute the type of the
+   * values which should be returned or yielded as appropriate.  If a type
+   * cannot be computed from the declared return type, return null.
+   */
+  DartType _computeReturnOrYieldType(
+      DartType declaredType, bool isGenerator, bool isAsynchronous) {
+    // Ordinary functions just return their declared types.
+    if (!isGenerator && !isAsynchronous) {
+      return declaredType;
+    }
+    if (isGenerator) {
+      if (declaredType is! InterfaceType) {
+        return null;
+      }
+      // If it's synchronous, we expect Iterable<T>, otherwise Stream<T>
+      InterfaceType rawType = isAsynchronous
+          ? typeProvider.streamDynamicType
+          : typeProvider.iterableDynamicType;
+      // Match the types to instantiate the type arguments if possible
+      List<DartType> typeArgs =
+          inferenceContext.matchTypes(rawType, declaredType);
+      return (typeArgs?.length == 1) ? typeArgs[0] : null;
+    }
+    // Must be asynchronous to reach here, so strip off any layers of Future
+    return StaticTypeAnalyzer.flattenFutures(typeProvider, declaredType);
+  }
+
+  /**
    * The given expression is the expression used to compute the iterator for a
    * for-each statement. Attempt to compute the type of objects that will be
    * assigned to the loop variable and return that type. Return `null` if the
@@ -11493,8 +9539,8 @@
     DartType expressionType = iteratorExpression.bestType;
     if (expressionType is InterfaceType) {
       InterfaceType interfaceType = expressionType;
-      FunctionType iteratorFunction =
-          _inheritanceManager.lookupMemberType(interfaceType, "iterator");
+      PropertyAccessorElement iteratorFunction =
+          interfaceType.lookUpInheritedGetter("iterator");
       if (iteratorFunction == null) {
         // TODO(brianwilkerson) Should we report this error?
         return null;
@@ -11502,8 +9548,8 @@
       DartType iteratorType = iteratorFunction.returnType;
       if (iteratorType is InterfaceType) {
         InterfaceType iteratorInterfaceType = iteratorType;
-        FunctionType currentFunction = _inheritanceManager.lookupMemberType(
-            iteratorInterfaceType, "current");
+        PropertyAccessorElement currentFunction =
+            iteratorInterfaceType.lookUpInheritedGetter("current");
         if (currentFunction == null) {
           // TODO(brianwilkerson) Should we report this error?
           return null;
@@ -11516,16 +9562,15 @@
 
   /**
    * The given expression is the expression used to compute the stream for an
-   * asyncronous for-each statement. Attempt to compute the type of objects that
-   * will be assigned to the loop variable and return that type. Return `null`
-   * if the type could not be determined. The [streamExpression] is the
-   * expression that will return the stream being iterated over.
+   * asynchronous for-each statement. Attempt to compute the type of objects
+   * that will be assigned to the loop variable and return that type.
+   * Return `null` if the type could not be determined. The [streamExpression]
+   * is the expression that will return the stream being iterated over.
    */
   DartType _getStreamElementType(Expression streamExpression) {
     DartType streamType = streamExpression.bestType;
     if (streamType is InterfaceType) {
-      FunctionType listenFunction =
-          _inheritanceManager.lookupMemberType(streamType, "listen");
+      MethodElement listenFunction = streamType.lookUpInheritedMethod("listen");
       if (listenFunction == null) {
         return null;
       }
@@ -11536,22 +9581,23 @@
       DartType onDataType = listenParameters[0].type;
       if (onDataType is FunctionType) {
         List<ParameterElement> onDataParameters = onDataType.parameters;
-        if (onDataParameters == null || onDataParameters.length < 1) {
+        if (onDataParameters == null || onDataParameters.isEmpty) {
           return null;
         }
-        DartType eventType = onDataParameters[0].type;
-        // TODO(paulberry): checking that typeParameters.isNotEmpty is a
-        // band-aid fix for dartbug.com/24191.  Figure out what the correct
-        // logic should be.
-        if (streamType.typeParameters.isNotEmpty &&
-            eventType.element == streamType.typeParameters[0]) {
-          return streamType.typeArguments[0];
-        }
+        return onDataParameters[0].type;
       }
     }
     return null;
   }
 
+  void _inferFormalParameterList(FormalParameterList node, DartType type) {
+    if (typeAnalyzer.inferFormalParameterList(node, type)) {
+      // TODO(leafp): This gets dropped on the floor if we're in the field
+      // inference task.  We should probably keep these infos.
+      inferenceContext.recordInference(node.parent, type);
+    }
+  }
+
   /**
    * If given "mayBeClosure" is [FunctionExpression] without explicit parameters types and its
    * required type is [FunctionType], then infer parameters types from [FunctionType].
@@ -11756,7 +9802,7 @@
   void _promoteTypes(Expression condition) {
     if (condition is BinaryExpression) {
       BinaryExpression binary = condition;
-      if (binary.operator.type == sc.TokenType.AMPERSAND_AMPERSAND) {
+      if (binary.operator.type == TokenType.AMPERSAND_AMPERSAND) {
         Expression left = binary.leftOperand;
         Expression right = binary.rightOperand;
         _promoteTypes(left);
@@ -11782,7 +9828,7 @@
   void _propagateFalseState(Expression condition) {
     if (condition is BinaryExpression) {
       BinaryExpression binary = condition;
-      if (binary.operator.type == sc.TokenType.BAR_BAR) {
+      if (binary.operator.type == TokenType.BAR_BAR) {
         _propagateFalseState(binary.leftOperand);
         _propagateFalseState(binary.rightOperand);
       }
@@ -11796,7 +9842,7 @@
       }
     } else if (condition is PrefixExpression) {
       PrefixExpression prefix = condition;
-      if (prefix.operator.type == sc.TokenType.BANG) {
+      if (prefix.operator.type == TokenType.BANG) {
         _propagateTrueState(prefix.operand);
       }
     } else if (condition is ParenthesizedExpression) {
@@ -11823,7 +9869,7 @@
   void _propagateTrueState(Expression condition) {
     if (condition is BinaryExpression) {
       BinaryExpression binary = condition;
-      if (binary.operator.type == sc.TokenType.AMPERSAND_AMPERSAND) {
+      if (binary.operator.type == TokenType.AMPERSAND_AMPERSAND) {
         _propagateTrueState(binary.leftOperand);
         _propagateTrueState(binary.rightOperand);
       }
@@ -11837,7 +9883,7 @@
       }
     } else if (condition is PrefixExpression) {
       PrefixExpression prefix = condition;
-      if (prefix.operator.type == sc.TokenType.BANG) {
+      if (prefix.operator.type == TokenType.BANG) {
         _propagateFalseState(prefix.operand);
       }
     } else if (condition is ParenthesizedExpression) {
@@ -12173,7 +10219,7 @@
    * @param token the token specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportErrorForToken(ErrorCode errorCode, sc.Token token,
+  void reportErrorForToken(ErrorCode errorCode, Token token,
       [List<Object> arguments]) {
     errorListener.onError(new AnalysisError(
         source, token.offset, token.length, errorCode, arguments));
@@ -12315,13 +10361,17 @@
       } else {
         nameScope = new FunctionScope(nameScope, constructorElement);
       }
-      super.visitConstructorDeclaration(node);
+      visitConstructorDeclarationInScope(node);
     } finally {
       nameScope = outerScope;
     }
     return null;
   }
 
+  void visitConstructorDeclarationInScope(ConstructorDeclaration node) {
+    super.visitConstructorDeclaration(node);
+  }
+
   @override
   Object visitDeclaredIdentifier(DeclaredIdentifier node) {
     VariableElement element = node.element;
@@ -12473,13 +10523,17 @@
       } else {
         nameScope = new FunctionScope(nameScope, functionElement);
       }
-      super.visitFunctionDeclaration(node);
+      visitFunctionDeclarationInScope(node);
     } finally {
       nameScope = outerScope;
     }
     return null;
   }
 
+  void visitFunctionDeclarationInScope(FunctionDeclaration node) {
+    super.visitFunctionDeclaration(node);
+  }
+
   @override
   Object visitFunctionExpression(FunctionExpression node) {
     if (node.parent is FunctionDeclaration) {
@@ -12522,13 +10576,17 @@
     Scope outerScope = nameScope;
     try {
       nameScope = new FunctionTypeScope(nameScope, node.element);
-      super.visitFunctionTypeAlias(node);
+      visitFunctionTypeAliasInScope(node);
     } finally {
       nameScope = outerScope;
     }
     return null;
   }
 
+  void visitFunctionTypeAliasInScope(FunctionTypeAlias node) {
+    super.visitFunctionTypeAlias(node);
+  }
+
   @override
   Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
     Scope outerScope = nameScope;
@@ -12583,13 +10641,17 @@
       } else {
         nameScope = new FunctionScope(nameScope, methodElement);
       }
-      super.visitMethodDeclaration(node);
+      visitMethodDeclarationInScope(node);
     } finally {
       nameScope = outerScope;
     }
     return null;
   }
 
+  void visitMethodDeclarationInScope(MethodDeclaration node) {
+    super.visitMethodDeclaration(node);
+  }
+
   /**
    * Visit the given statement after it's scope has been created. This is used by ResolverVisitor to
    * correctly visit the 'then' and 'else' statements of an 'if' statement.
@@ -12728,310 +10790,6 @@
 }
 
 /**
- * Implementation of [TypeSystem] using the strong mode rules.
- * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md
- */
-class StrongTypeSystemImpl implements TypeSystem {
-  final _specTypeSystem = new TypeSystemImpl();
-
-  StrongTypeSystemImpl();
-
-  @override
-  DartType getLeastUpperBound(
-      TypeProvider typeProvider, DartType type1, DartType type2) {
-    // TODO(leafp): Implement a strong mode version of this.
-    return _specTypeSystem.getLeastUpperBound(typeProvider, type1, type2);
-  }
-
-  // TODO(leafp): Document the rules in play here
-  @override
-  bool isAssignableTo(DartType fromType, DartType toType) {
-    // An actual subtype
-    if (isSubtypeOf(fromType, toType)) {
-      return true;
-    }
-
-    // Don't allow implicit downcasts between function types
-    // and call method objects, as these will almost always fail.
-    if ((fromType is FunctionType && _getCallMethodType(toType) != null) ||
-        (toType is FunctionType && _getCallMethodType(fromType) != null)) {
-      return false;
-    }
-
-    // If the subtype relation goes the other way, allow the implicit downcast.
-    // TODO(leafp): Emit warnings and hints for these in some way.
-    // TODO(leafp): Consider adding a flag to disable these?  Or just rely on
-    //   --warnings-as-errors?
-    if (isSubtypeOf(toType, fromType) ||
-        _specTypeSystem.isAssignableTo(toType, fromType)) {
-      // TODO(leafp): error if type is known to be exact (literal,
-      //  instance creation).
-      // TODO(leafp): Warn on composite downcast.
-      // TODO(leafp): hint on object/dynamic downcast.
-      // TODO(leafp): Consider allowing assignment casts.
-      return true;
-    }
-
-    return false;
-  }
-
-  @override
-  bool isSubtypeOf(DartType leftType, DartType rightType) {
-    return _isSubtypeOf(leftType, rightType, null);
-  }
-
-  FunctionType _getCallMethodType(DartType t) {
-    if (t is InterfaceType) {
-      ClassElement element = t.element;
-      InheritanceManager manager = new InheritanceManager(element.library);
-      FunctionType callType = manager.lookupMemberType(t, "call");
-      return callType;
-    }
-    return null;
-  }
-
-  // Given a type t, if t is an interface type with a call method
-  // defined, return the function type for the call method, otherwise
-  // return null.
-  _GuardedSubtypeChecker<DartType> _guard(
-      _GuardedSubtypeChecker<DartType> check) {
-    return (DartType t1, DartType t2, Set<Element> visited) {
-      Element element = t1.element;
-      if (visited == null) {
-        visited = new HashSet<Element>();
-      }
-      if (element == null || !visited.add(element)) {
-        return false;
-      }
-      try {
-        return check(t1, t2, visited);
-      } finally {
-        visited.remove(element);
-      }
-    };
-  }
-
-  bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
-    return (t.isDynamic && dynamicIsBottom) || t.isBottom;
-  }
-
-  // Guard against loops in the class hierarchy
-  /**
-   * Check that [f1] is a subtype of [f2].
-   * [fuzzyArrows] indicates whether or not the f1 and f2 should be
-   * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated
-   * as bottom).
-   */
-  bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
-      {bool fuzzyArrows: true}) {
-    final r1s = f1.normalParameterTypes;
-    final o1s = f1.optionalParameterTypes;
-    final n1s = f1.namedParameterTypes;
-    final r2s = f2.normalParameterTypes;
-    final o2s = f2.optionalParameterTypes;
-    final n2s = f2.namedParameterTypes;
-    final ret1 = f1.returnType;
-    final ret2 = f2.returnType;
-
-    // A -> B <: C -> D if C <: A and
-    // either D is void or B <: D
-    if (!ret2.isVoid && !isSubtypeOf(ret1, ret2)) {
-      return false;
-    }
-
-    // Reject if one has named and the other has optional
-    if (n1s.length > 0 && o2s.length > 0) {
-      return false;
-    }
-    if (n2s.length > 0 && o1s.length > 0) {
-      return false;
-    }
-
-    // Rebind _isSubtypeOf for convenience
-    _SubtypeChecker<DartType> parameterSubtype = (DartType t1, DartType t2) =>
-        _isSubtypeOf(t1, t2, null, dynamicIsBottom: fuzzyArrows);
-
-    // f2 has named parameters
-    if (n2s.length > 0) {
-      // Check that every named parameter in f2 has a match in f1
-      for (String k2 in n2s.keys) {
-        if (!n1s.containsKey(k2)) {
-          return false;
-        }
-        if (!parameterSubtype(n2s[k2], n1s[k2])) {
-          return false;
-        }
-      }
-    }
-    // If we get here, we either have no named parameters,
-    // or else the named parameters match and we have no optional
-    // parameters
-
-    // If f1 has more required parameters, reject
-    if (r1s.length > r2s.length) {
-      return false;
-    }
-
-    // If f2 has more required + optional parameters, reject
-    if (r2s.length + o2s.length > r1s.length + o1s.length) {
-      return false;
-    }
-
-    // The parameter lists must look like the following at this point
-    // where rrr is a region of required, and ooo is a region of optionals.
-    // f1: rrr ooo ooo ooo
-    // f2: rrr rrr ooo
-    int rr = r1s.length; // required in both
-    int or = r2s.length - r1s.length; // optional in f1, required in f2
-    int oo = o2s.length; // optional in both
-
-    for (int i = 0; i < rr; ++i) {
-      if (!parameterSubtype(r2s[i], r1s[i])) {
-        return false;
-      }
-    }
-    for (int i = 0, j = rr; i < or; ++i, ++j) {
-      if (!parameterSubtype(r2s[j], o1s[i])) {
-        return false;
-      }
-    }
-    for (int i = or, j = 0; i < oo; ++i, ++j) {
-      if (!parameterSubtype(o2s[j], o1s[i])) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  bool _isInterfaceSubtypeOf(
-      InterfaceType i1, InterfaceType i2, Set<Element> visited) {
-    // Guard recursive calls
-    _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype =
-        _guard(_isInterfaceSubtypeOf);
-
-    if (i1 == i2) {
-      return true;
-    }
-
-    if (i1.element == i2.element) {
-      List<DartType> tArgs1 = i1.typeArguments;
-      List<DartType> tArgs2 = i2.typeArguments;
-
-      assert(tArgs1.length == tArgs2.length);
-
-      for (int i = 0; i < tArgs1.length; i++) {
-        DartType t1 = tArgs1[i];
-        DartType t2 = tArgs2[i];
-        if (!isSubtypeOf(t1, t2)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    if (i2.isDartCoreFunction && i1.element.getMethod("call") != null) {
-      return true;
-    }
-
-    if (i1.isObject) {
-      return false;
-    }
-
-    if (guardedInterfaceSubtype(i1.superclass, i2, visited)) {
-      return true;
-    }
-
-    for (final parent in i1.interfaces) {
-      if (guardedInterfaceSubtype(parent, i2, visited)) {
-        return true;
-      }
-    }
-
-    for (final parent in i1.mixins) {
-      if (guardedInterfaceSubtype(parent, i2, visited)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  bool _isSubtypeOf(DartType t1, DartType t2, Set<Element> visited,
-      {bool dynamicIsBottom: false}) {
-    // Guard recursive calls
-    _GuardedSubtypeChecker<DartType> guardedSubtype = _guard(_isSubtypeOf);
-
-    if (t1 == t2) {
-      return true;
-    }
-
-    // The types are void, dynamic, bottom, interface types, function types
-    // and type parameters.  We proceed by eliminating these different classes
-    // from consideration.
-
-    // Trivially true.
-    if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
-        _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
-      return true;
-    }
-
-    // Trivially false.
-    if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
-        _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
-      return false;
-    }
-
-    // S <: T where S is a type variable
-    //  T is not dynamic or object (handled above)
-    //  S != T (handled above)
-    //  So only true if bound of S is S' and
-    //  S' <: T
-    if (t1 is TypeParameterType) {
-      DartType bound = t1.element.bound;
-      if (bound == null) return false;
-      return guardedSubtype(bound, t2, visited);
-    }
-
-    if (t2 is TypeParameterType) {
-      return false;
-    }
-
-    if (t1.isVoid || t2.isVoid) {
-      return false;
-    }
-
-    // We've eliminated void, dynamic, bottom, and type parameters.  The only
-    // cases are the combinations of interface type and function type.
-
-    // A function type can only subtype an interface type if
-    // the interface type is Function
-    if (t1 is FunctionType && t2 is InterfaceType) {
-      return t2.isDartCoreFunction;
-    }
-
-    // An interface type can only subtype a function type if
-    // the interface type declares a call method with a type
-    // which is a super type of the function type.
-    if (t1 is InterfaceType && t2 is FunctionType) {
-      var callType = _getCallMethodType(t1);
-      return (callType != null) && _isFunctionSubtypeOf(callType, t2);
-    }
-
-    // Two interface types
-    if (t1 is InterfaceType && t2 is InterfaceType) {
-      return _isInterfaceSubtypeOf(t1, t2, visited);
-    }
-
-    return _isFunctionSubtypeOf(t1 as FunctionType, t2 as FunctionType);
-  }
-
-  // TODO(leafp): Document the rules in play here
-  bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
-    return (t.isDynamic && !dynamicIsBottom) || t.isObject;
-  }
-}
-
-/**
  * Instances of this class manage the knowledge of what the set of subtypes are for a given type.
  */
 class SubtypeManager {
@@ -13220,12 +10978,12 @@
    *
    * @param token the head of the list of tokens being searched
    */
-  void _gatherTodoComments(sc.Token token) {
-    while (token != null && token.type != sc.TokenType.EOF) {
-      sc.Token commentToken = token.precedingComments;
+  void _gatherTodoComments(Token token) {
+    while (token != null && token.type != TokenType.EOF) {
+      Token commentToken = token.precedingComments;
       while (commentToken != null) {
-        if (commentToken.type == sc.TokenType.SINGLE_LINE_COMMENT ||
-            commentToken.type == sc.TokenType.MULTI_LINE_COMMENT) {
+        if (commentToken.type == TokenType.SINGLE_LINE_COMMENT ||
+            commentToken.type == TokenType.MULTI_LINE_COMMENT) {
           _scrapeTodoComment(commentToken);
         }
         commentToken = commentToken.next;
@@ -13239,7 +10997,7 @@
    *
    * @param commentToken the comment token to analyze
    */
-  void _scrapeTodoComment(sc.Token commentToken) {
+  void _scrapeTodoComment(Token commentToken) {
     JavaPatternMatcher matcher =
         new JavaPatternMatcher(TodoCode.TODO_REGEX, commentToken.lexeme);
     if (matcher.find()) {
@@ -14098,6 +11856,11 @@
   bool _hasReferenceToSuper = false;
 
   /**
+   * True if we're analyzing in strong mode.
+   */
+  bool _strongMode;
+
+  /**
    * Initialize a newly created visitor to resolve the nodes in an AST node.
    *
    * [definingLibrary] is the element for the library containing the node being
@@ -14119,6 +11882,7 @@
             nameScope: nameScope) {
     _dynamicType = typeProvider.dynamicType;
     _undefinedType = typeProvider.undefinedType;
+    _strongMode = definingLibrary.context.analysisOptions.strongMode;
   }
 
   @override
@@ -14196,6 +11960,8 @@
     super.visitClassDeclaration(node);
     ClassElementImpl classElement = _getClassElement(node.name);
     if (classElement != null) {
+      // Clear this flag, as we just invalidated any inferred member types.
+      classElement.hasBeenInferred = false;
       classElement.hasReferenceToSuper = _hasReferenceToSuper;
     }
     return null;
@@ -14288,9 +12054,7 @@
     } else {
       ClassElement definingClass = element.enclosingElement as ClassElement;
       element.returnType = definingClass.type;
-      FunctionTypeImpl type = new FunctionTypeImpl(element);
-      type.typeArguments = definingClass.type.typeArguments;
-      element.type = type;
+      element.type = new FunctionTypeImpl(element);
     }
     return null;
   }
@@ -14358,13 +12122,8 @@
           new CaughtException(new AnalysisException(), null));
     }
     element.returnType = _computeReturnType(node.returnType);
-    FunctionTypeImpl type = new FunctionTypeImpl(element);
-    ClassElement definingClass =
-        element.getAncestor((element) => element is ClassElement);
-    if (definingClass != null) {
-      type.typeArguments = definingClass.type.typeArguments;
-    }
-    element.type = type;
+    element.type = new FunctionTypeImpl(element);
+    _inferSetterReturnType(element);
     return null;
   }
 
@@ -14412,21 +12171,16 @@
           new CaughtException(new AnalysisException(), null));
     }
     element.returnType = _computeReturnType(node.returnType);
-    FunctionTypeImpl type = new FunctionTypeImpl(element);
-    ClassElement definingClass =
-        element.getAncestor((element) => element is ClassElement);
-    if (definingClass != null) {
-      type.typeArguments = definingClass.type.typeArguments;
-    }
-    element.type = type;
+    element.type = new FunctionTypeImpl(element);
+    _inferSetterReturnType(element);
     if (element is PropertyAccessorElement) {
       PropertyAccessorElement accessor = element as PropertyAccessorElement;
       PropertyInducingElementImpl variable =
           accessor.variable as PropertyInducingElementImpl;
       if (accessor.isGetter) {
-        variable.type = type.baseReturnType;
+        variable.type = element.returnType;
       } else if (variable.type == null) {
-        List<ParameterElement> parameters = type.baseParameters;
+        List<ParameterElement> parameters = element.parameters;
         if (parameters != null && parameters.length > 0) {
           variable.type = parameters[0].type;
         }
@@ -14595,10 +12349,10 @@
       } else if ((redirectingConstructorKind =
               _getRedirectingConstructorKind(node)) !=
           null) {
-        ErrorCode errorCode = (redirectingConstructorKind ==
-                RedirectingConstructorKind.CONST
-            ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
-            : StaticWarningCode.REDIRECT_TO_NON_CLASS);
+        ErrorCode errorCode =
+            (redirectingConstructorKind == RedirectingConstructorKind.CONST
+                ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
+                : StaticWarningCode.REDIRECT_TO_NON_CLASS);
         reportErrorForNode(errorCode, typeName, [typeName.name]);
       } else if (_isTypeNameInTypeArgumentList(node)) {
         reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
@@ -14655,10 +12409,10 @@
       } else if ((redirectingConstructorKind =
               _getRedirectingConstructorKind(node)) !=
           null) {
-        ErrorCode errorCode = (redirectingConstructorKind ==
-                RedirectingConstructorKind.CONST
-            ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
-            : StaticWarningCode.REDIRECT_TO_NON_CLASS);
+        ErrorCode errorCode =
+            (redirectingConstructorKind == RedirectingConstructorKind.CONST
+                ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
+                : StaticWarningCode.REDIRECT_TO_NON_CLASS);
         reportErrorForNode(errorCode, typeName, [typeName.name]);
       } else if (_isTypeNameInTypeArgumentList(node)) {
         reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
@@ -14686,7 +12440,7 @@
     if (argumentList != null) {
       NodeList<TypeName> arguments = argumentList.arguments;
       int argumentCount = arguments.length;
-      List<DartType> parameters = _getTypeArguments(type);
+      List<DartType> parameters = _getTypeParameters(type);
       int parameterCount = parameters.length;
       List<DartType> typeArguments = new List<DartType>(parameterCount);
       if (argumentCount == parameterCount) {
@@ -14705,21 +12459,13 @@
           typeArguments[i] = _dynamicType;
         }
       }
-      if (type is InterfaceTypeImpl) {
-        InterfaceTypeImpl interfaceType = type as InterfaceTypeImpl;
-        type = interfaceType.substitute4(typeArguments);
-      } else if (type is FunctionTypeImpl) {
-        FunctionTypeImpl functionType = type as FunctionTypeImpl;
-        type = functionType.substitute3(typeArguments);
-      } else {
-        // TODO(brianwilkerson) Report this internal error.
-      }
+      type = _instantiateType(type, typeArguments);
     } else {
       //
       // Check for the case where there are no type arguments given for a
       // parameterized type.
       //
-      List<DartType> parameters = _getTypeArguments(type);
+      List<DartType> parameters = _getTypeParameters(type);
       int parameterCount = parameters.length;
       if (parameterCount > 0) {
         DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
@@ -14727,7 +12473,7 @@
         for (int i = 0; i < parameterCount; i++) {
           arguments[i] = dynamicType;
         }
-        type = type.substitute2(arguments, parameters);
+        type = _instantiateType(type, arguments);
       }
     }
     typeName.staticType = type;
@@ -14767,13 +12513,7 @@
         PropertyAccessorElementImpl getter =
             variableElement.getter as PropertyAccessorElementImpl;
         getter.returnType = declaredType;
-        FunctionTypeImpl getterType = new FunctionTypeImpl(getter);
-        ClassElement definingClass =
-            element.getAncestor((element) => element is ClassElement);
-        if (definingClass != null) {
-          getterType.typeArguments = definingClass.type.typeArguments;
-        }
-        getter.type = getterType;
+        getter.type = new FunctionTypeImpl(getter);
         PropertyAccessorElementImpl setter =
             variableElement.setter as PropertyAccessorElementImpl;
         if (setter != null) {
@@ -14782,11 +12522,7 @@
             (parameters[0] as ParameterElementImpl).type = declaredType;
           }
           setter.returnType = VoidTypeImpl.instance;
-          FunctionTypeImpl setterType = new FunctionTypeImpl(setter);
-          if (definingClass != null) {
-            setterType.typeArguments = definingClass.type.typeArguments;
-          }
-          setter.type = setterType;
+          setter.type = new FunctionTypeImpl(setter);
         }
       }
     } else {
@@ -14922,11 +12658,11 @@
    * @param type the type whole type arguments are to be returned
    * @return the type arguments associated with the given type
    */
-  List<DartType> _getTypeArguments(DartType type) {
+  List<DartType> _getTypeParameters(DartType type) {
     if (type is InterfaceType) {
       return type.typeArguments;
     } else if (type is FunctionType) {
-      return type.typeArguments;
+      return TypeParameterTypeImpl.getTypes(type.typeFormals);
     }
     return DartType.EMPTY_LIST;
   }
@@ -14966,6 +12702,35 @@
   }
 
   /**
+   * In strong mode we infer "void" as the setter return type (as void is the
+   * only legal return type for a setter). This allows us to give better
+   * errors later if an invalid type is returned.
+   */
+  void _inferSetterReturnType(ExecutableElementImpl element) {
+    if (_strongMode &&
+        element is PropertyAccessorElementImpl &&
+        element.isSetter &&
+        element.hasImplicitReturnType) {
+      element.returnType = VoidTypeImpl.instance;
+    }
+  }
+
+  DartType _instantiateType(DartType type, List<DartType> typeArguments) {
+    // TODO(jmesserly): this should use TypeSystem.instantiateToBounds,
+    // from calling methods when they know they're just trying to fill in
+    // "dynamic" for the case of missing type arguments.
+
+    if (type is InterfaceTypeImpl) {
+      return type.substitute4(typeArguments);
+    } else if (type is FunctionTypeImpl) {
+      return type.instantiate(typeArguments);
+    } else {
+      // TODO(brianwilkerson) Report this internal error.
+      return type;
+    }
+  }
+
+  /**
    * Checks if the given type name is used as the type in an as expression.
    *
    * @param typeName the type name to analyzer
@@ -15135,7 +12900,7 @@
     // If the type is not an InterfaceType, then visitTypeName() sets the type
     // to be a DynamicTypeImpl
     Identifier name = typeName.name;
-    if (name.name == sc.Keyword.DYNAMIC.syntax) {
+    if (name.name == Keyword.DYNAMIC.syntax) {
       reportErrorForNode(dynamicTypeError, name, [name.name]);
     } else {
       reportErrorForNode(nonTypeError, name, [name.name]);
@@ -15196,46 +12961,22 @@
   void _setFunctionTypedParameterType(ParameterElementImpl element,
       TypeName returnType, FormalParameterList parameterList) {
     List<ParameterElement> parameters = _getElements(parameterList);
-    FunctionTypeAliasElementImpl aliasElement =
-        new FunctionTypeAliasElementImpl.forNode(null);
-    aliasElement.synthetic = true;
-    aliasElement.shareParameters(parameters);
-    aliasElement.returnType = _computeReturnType(returnType);
-    // FunctionTypeAliasElementImpl assumes the enclosing element is a
-    // CompilationUnitElement (because non-synthetic function types can only be
-    // declared at top level), so to avoid breaking things, go find the
-    // compilation unit element.
-    aliasElement.enclosingElement =
-        element.getAncestor((element) => element is CompilationUnitElement);
-    FunctionTypeImpl type = new FunctionTypeImpl.forTypedef(aliasElement);
-    ClassElement definingClass =
-        element.getAncestor((element) => element is ClassElement);
-    if (definingClass != null) {
-      aliasElement.shareTypeParameters(definingClass.typeParameters);
-      type.typeArguments = definingClass.type.typeArguments;
-    } else {
-      FunctionTypeAliasElement alias =
-          element.getAncestor((element) => element is FunctionTypeAliasElement);
-      while (alias != null && alias.isSynthetic) {
-        alias =
-            alias.getAncestor((element) => element is FunctionTypeAliasElement);
-      }
-      if (alias != null) {
-        aliasElement.typeParameters = alias.typeParameters;
-        type.typeArguments = alias.type.typeArguments;
-      } else {
-        type.typeArguments = DartType.EMPTY_LIST;
-      }
-    }
-    element.type = type;
+    FunctionElementImpl functionElement = new FunctionElementImpl.forNode(null);
+    functionElement.synthetic = true;
+    functionElement.shareParameters(parameters);
+    functionElement.returnType = _computeReturnType(returnType);
+    functionElement.enclosingElement = element;
+    functionElement.shareTypeParameters(element.typeParameters);
+    element.type = new FunctionTypeImpl(functionElement);
+    functionElement.type = element.type;
   }
 
   /**
    * @return `true` if the name of the given [TypeName] is an built-in identifier.
    */
   static bool _isBuiltInIdentifier(TypeName node) {
-    sc.Token token = node.name.beginToken;
-    return token.type == sc.TokenType.KEYWORD;
+    Token token = node.name.beginToken;
+    return token.type == TokenType.KEYWORD;
   }
 
   /**
@@ -15257,139 +12998,6 @@
 }
 
 /**
- * The interface `TypeSystem` defines the behavior of an object representing
- * the type system.  This provides a common location to put methods that act on
- * types but may need access to more global data structures, and it paves the
- * way for a possible future where we may wish to make the type system
- * pluggable.
- */
-abstract class TypeSystem {
-  /**
-   * Compute the least upper bound of two types.
-   */
-  DartType getLeastUpperBound(
-      TypeProvider typeProvider, DartType type1, DartType type2);
-
-  /**
-   * Return `true` if the [leftType] is assignable to the [rightType] (that is,
-   * if leftType <==> rightType).
-   */
-  bool isAssignableTo(DartType leftType, DartType rightType);
-
-  /**
-   * Return `true` if the [leftType] is a subtype of the [rightType] (that is,
-   * if leftType <: rightType).
-   */
-  bool isSubtypeOf(DartType leftType, DartType rightType);
-
-  /**
-   * Create either a strong mode or regular type system based on context.
-   */
-  static TypeSystem create(AnalysisContext context) {
-    return (context.analysisOptions.strongMode)
-        ? new StrongTypeSystemImpl()
-        : new TypeSystemImpl();
-  }
-}
-
-/**
- * Implementation of [TypeSystem] using the rules in the Dart specification.
- */
-class TypeSystemImpl implements TypeSystem {
-  TypeSystemImpl();
-
-  @override
-  DartType getLeastUpperBound(
-      TypeProvider typeProvider, DartType type1, DartType type2) {
-    // The least upper bound relation is reflexive.
-    if (identical(type1, type2)) {
-      return type1;
-    }
-    // The least upper bound of dynamic and any type T is dynamic.
-    if (type1.isDynamic) {
-      return type1;
-    }
-    if (type2.isDynamic) {
-      return type2;
-    }
-    // The least upper bound of void and any type T != dynamic is void.
-    if (type1.isVoid) {
-      return type1;
-    }
-    if (type2.isVoid) {
-      return type2;
-    }
-    // The least upper bound of bottom and any type T is T.
-    if (type1.isBottom) {
-      return type2;
-    }
-    if (type2.isBottom) {
-      return type1;
-    }
-    // Let U be a type variable with upper bound B.  The least upper bound of U
-    // and a type T is the least upper bound of B and T.
-    while (type1 is TypeParameterType) {
-      // TODO(paulberry): is this correct in the complex of F-bounded
-      // polymorphism?
-      DartType bound = (type1 as TypeParameterType).element.bound;
-      if (bound == null) {
-        bound = typeProvider.objectType;
-      }
-      type1 = bound;
-    }
-    while (type2 is TypeParameterType) {
-      // TODO(paulberry): is this correct in the context of F-bounded
-      // polymorphism?
-      DartType bound = (type2 as TypeParameterType).element.bound;
-      if (bound == null) {
-        bound = typeProvider.objectType;
-      }
-      type2 = bound;
-    }
-    // The least upper bound of a function type and an interface type T is the
-    // least upper bound of Function and T.
-    if (type1 is FunctionType && type2 is InterfaceType) {
-      type1 = typeProvider.functionType;
-    }
-    if (type2 is FunctionType && type1 is InterfaceType) {
-      type2 = typeProvider.functionType;
-    }
-
-    // At this point type1 and type2 should both either be interface types or
-    // function types.
-    if (type1 is InterfaceType && type2 is InterfaceType) {
-      InterfaceType result =
-          InterfaceTypeImpl.computeLeastUpperBound(type1, type2);
-      if (result == null) {
-        return typeProvider.dynamicType;
-      }
-      return result;
-    } else if (type1 is FunctionType && type2 is FunctionType) {
-      FunctionType result =
-          FunctionTypeImpl.computeLeastUpperBound(type1, type2);
-      if (result == null) {
-        return typeProvider.functionType;
-      }
-      return result;
-    } else {
-      // Should never happen.  As a defensive measure, return the dynamic type.
-      assert(false);
-      return typeProvider.dynamicType;
-    }
-  }
-
-  @override
-  bool isAssignableTo(DartType leftType, DartType rightType) {
-    return leftType.isAssignableTo(rightType);
-  }
-
-  @override
-  bool isSubtypeOf(DartType leftType, DartType rightType) {
-    return leftType.isSubtypeOf(rightType);
-  }
-}
-
-/**
  * Instances of the class [UnusedLocalElementsVerifier] traverse an element
  * structure looking for cases of [HintCode.UNUSED_ELEMENT],
  * [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc.
@@ -15664,22 +13272,6 @@
       : super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope);
 
-  /**
-   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
-   *
-   * @param library the library containing the compilation unit being resolved
-   * @param source the source representing the compilation unit being visited
-   * @param typeProvider the object used to access the types from the core library
-   *
-   * Deprecated.  Please use unnamed constructor instead.
-   */
-  @deprecated
-  VariableResolverVisitor.con1(
-      Library library, Source source, TypeProvider typeProvider)
-      : this(
-            library.libraryElement, source, typeProvider, library.errorListener,
-            nameScope: library.libraryScope);
-
   @override
   Object visitExportDirective(ExportDirective node) => null;
 
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index 0a9fa2a..49ea3ba 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -2,13 +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.
 
-library engine.scanner;
+library analyzer.src.generated.scanner;
 
 import 'dart:collection';
 
-import 'error.dart';
-import 'java_engine.dart';
-import 'source.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
 
 /**
  * The opening half of a grouping pair of tokens. This is used for curly
@@ -723,6 +723,12 @@
   bool _hasUnmatchedGroups = false;
 
   /**
+   * A flag indicating whether to parse generic method comments, of the form
+   * `/*=T*/` and `/*<T>*/`.
+   */
+  bool scanGenericMethodComments = false;
+
+  /**
    * Initialize a newly created scanner to scan characters from the given
    * [source]. The given character [_reader] will be used to read the characters
    * in the source. The given [_errorListener] will be informed of any errors
@@ -1012,16 +1018,20 @@
   }
 
   void _appendCommentToken(TokenType type, String value) {
-    // Ignore comment tokens if client specified that it doesn't need them.
-    if (!_preserveComments) {
+    CommentToken token = null;
+    TokenType genericComment = _matchGenericMethodCommentType(value);
+    if (genericComment != null) {
+      token = new CommentToken(genericComment, value, _tokenStart);
+    } else if (!_preserveComments) {
+      // Ignore comment tokens if client specified that it doesn't need them.
       return;
-    }
-    // OK, remember comment tokens.
-    CommentToken token;
-    if (_isDocumentationComment(value)) {
-      token = new DocumentationCommentToken(type, value, _tokenStart);
     } else {
-      token = new CommentToken(type, value, _tokenStart);
+      // OK, remember comment tokens.
+      if (_isDocumentationComment(value)) {
+        token = new DocumentationCommentToken(type, value, _tokenStart);
+      } else {
+        token = new CommentToken(type, value, _tokenStart);
+      }
     }
     if (_firstComment == null) {
       _firstComment = token;
@@ -1152,6 +1162,27 @@
   }
 
   /**
+   * Checks if [value] is the start of a generic method type annotation comment.
+   *
+   * This can either be of the form `/*<T>*/` or `/*=T*/`. The token type is
+   * returned, or null if it was not a generic method comment.
+   */
+  TokenType _matchGenericMethodCommentType(String value) {
+    if (scanGenericMethodComments) {
+      // Match /*< and >*/
+      if (StringUtilities.startsWith3(value, 0, 0x2F, 0x2A, 0x3C) &&
+          StringUtilities.endsWith3(value, 0x3E, 0x2A, 0x2F)) {
+        return TokenType.GENERIC_METHOD_TYPE_LIST;
+      }
+      // Match /*=
+      if (StringUtilities.startsWith3(value, 0, 0x2F, 0x2A, 0x3D)) {
+        return TokenType.GENERIC_METHOD_TYPE_ASSIGN;
+      }
+    }
+    return null;
+  }
+
+  /**
    * Report an error at the current offset. The [errorCode] is the error code
    * indicating the nature of the error. The [arguments] are any arguments
    * needed to complete the error message
@@ -2057,9 +2088,9 @@
    * comments can be reached by following the token stream using [next] until
    * `null` is returned.
    *
-   * For example, if the original contents were "/* one */ /* two */ id", then
-   * the first preceding comment token will have a lexeme of "/* one */" and
-   * the next comment token will have a lexeme of "/* two */".
+   * For example, if the original contents were `/* one */ /* two */ id`, then
+   * the first preceding comment token will have a lexeme of `/* one */` and
+   * the next comment token will have a lexeme of `/* two */`.
    */
   CommentToken get precedingComments => null;
 
@@ -2501,6 +2532,12 @@
   static const TokenType PERIOD_PERIOD_PERIOD =
       const TokenType('PERIOD_PERIOD_PERIOD', TokenClass.NO_CLASS, "...");
 
+  static const TokenType GENERIC_METHOD_TYPE_LIST =
+      const TokenType('GENERIC_METHOD_TYPE_LIST');
+
+  static const TokenType GENERIC_METHOD_TYPE_ASSIGN =
+      const TokenType('GENERIC_METHOD_TYPE_ASSIGN');
+
   /**
    * The class of the token.
    */
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index c4f034f..4c756e2 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -2,13 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.sdk;
+library analyzer.src.generated.sdk;
 
 import 'dart:collection';
 
-import 'ast.dart';
-import 'engine.dart' show AnalysisContext;
-import 'source.dart' show ContentCache, Source, UriKind;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/source.dart'
+    show ContentCache, Source, UriKind;
 
 /**
  * A Dart SDK installed in a specified location.
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index b155b9a..863a3d4 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -2,23 +2,26 @@
 // for 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 engine.sdk.io;
+library analyzer.src.generated.sdk_io;
 
+import 'dart:collection';
 import 'dart:io';
 
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
-
-import 'ast.dart';
-import 'engine.dart';
-import 'error.dart';
-import 'java_core.dart';
-import 'java_engine_io.dart';
-import 'java_io.dart';
-import 'parser.dart';
-import 'scanner.dart';
-import 'sdk.dart';
-import 'source_io.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/summary/format.dart' show SdkBundle;
+import 'package:analyzer/src/summary/summary_sdk.dart';
+import 'package:path/path.dart' as pathos;
 
 /**
  * A Dart SDK installed in a specified directory. Typical Dart SDK layout is
@@ -199,6 +202,11 @@
   JavaFile _sdkDirectory;
 
   /**
+   * The directory within the SDK directory that contains the libraries.
+   */
+  JavaFile _libraryDirectory;
+
+  /**
    * The revision number of this SDK, or `"0"` if the revision number cannot be
    * discovered.
    */
@@ -230,6 +238,11 @@
   LibraryMap _libraryMap;
 
   /**
+   * The mapping from Dart URI's to the corresponding sources.
+   */
+  Map<String, Source> _uriToSourceMap = new HashMap<String, Source>();
+
+  /**
    * Initialize a newly created SDK to represent the Dart SDK installed in the
    * [sdkDirectory]. The flag [useDart2jsPaths] is `true` if the dart2js path
    * should be used when it is available
@@ -242,8 +255,9 @@
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      if (AnalysisEngine.instance.useTaskModel) {
-        _analysisContext = new newContext.SdkAnalysisContext();
+      SdkBundle sdkBundle = _getSummarySdkBundle();
+      if (sdkBundle != null) {
+        _analysisContext = new SummarySdkAnalysisContext(sdkBundle);
       } else {
         _analysisContext = new SdkAnalysisContext();
       }
@@ -330,8 +344,13 @@
   /**
    * Return the directory within the SDK directory that contains the libraries.
    */
-  JavaFile get libraryDirectory =>
-      new JavaFile.relative(_sdkDirectory, _LIB_DIRECTORY_NAME);
+  JavaFile get libraryDirectory {
+    if (_libraryDirectory == null) {
+      _libraryDirectory =
+          new JavaFile.relative(_sdkDirectory, _LIB_DIRECTORY_NAME);
+    }
+    return _libraryDirectory;
+  }
 
   /**
    * Return the file containing the Pub executable, or `null` if it does not exist.
@@ -511,6 +530,35 @@
 
   @override
   Source mapDartUri(String dartUri) {
+    Source source = _uriToSourceMap[dartUri];
+    if (source == null) {
+      source = _mapDartUri(dartUri);
+      _uriToSourceMap[dartUri] = source;
+    }
+    return source;
+  }
+
+  /**
+   * Return the [SdkBundle] for this SDK, if it exists, or `null` otherwise.
+   */
+  SdkBundle _getSummarySdkBundle() {
+    String rootPath = directory.getAbsolutePath();
+    String path = pathos.join(rootPath, 'lib', '_internal', 'analysis_summary');
+    try {
+      File file = new File(path);
+      if (file.existsSync()) {
+        List<int> bytes = file.readAsBytesSync();
+        return new SdkBundle.fromBuffer(bytes);
+      }
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logError(
+          'Failed to load SDK analysis summary from $path',
+          new CaughtException(exception, stackTrace));
+    }
+    return null;
+  }
+
+  FileBasedSource _mapDartUri(String dartUri) {
     String libraryName;
     String relativePath;
     int index = dartUri.indexOf('/');
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 1a47516..950f36e0 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.source;
+library analyzer.src.generated.source;
 
 import 'dart:collection';
 import "dart:math" as math;
@@ -10,18 +10,17 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
 import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
 import 'package:analyzer/task/model.dart';
 import 'package:package_config/packages.dart';
 import 'package:path/path.dart' as pathos;
 
-import 'engine.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'java_io.dart' show JavaFile;
-import 'sdk.dart' show DartSdk;
-import 'source_io.dart' show FileBasedSource;
-
 /**
  * A function that is used to visit [ContentCache] entries.
  */
@@ -247,6 +246,17 @@
 
     return new LineInfo_Location(min + 1, offset - _lineStarts[min] + 1);
   }
+
+  /**
+   * Return the offset of the first character on the line with the given
+   * [lineNumber].
+   */
+  int getOffsetOfLine(int lineNumber) {
+    if (lineNumber < 0 || lineNumber >= _lineStarts.length) {
+      throw new ArgumentError('Invalid line number: $lineNumber');
+    }
+    return _lineStarts[lineNumber];
+  }
 }
 
 /**
@@ -400,12 +410,6 @@
   /**
    * An empty list of sources.
    */
-  @deprecated // Use Source.EMPTY_LIST
-  static const List<Source> EMPTY_ARRAY = EMPTY_LIST;
-
-  /**
-   * An empty list of sources.
-   */
   static const List<Source> EMPTY_LIST = const <Source>[];
 
   /**
@@ -657,6 +661,17 @@
   }
 
   /**
+   * Return a source factory that will resolve URI's in the same way that this
+   * source factory does.
+   */
+  SourceFactory clone() {
+    SourceFactory factory =
+        new SourceFactory(_resolvers, _packages, _resourceProvider);
+    factory.localSourcePredicate = _localSourcePredicate;
+    return factory;
+  }
+
+  /**
    * Return a source object representing the given absolute URI, or `null` if the URI is not a
    * valid URI or if it is not an absolute URI.
    *
@@ -723,14 +738,11 @@
   bool isLocalSource(Source source) => _localSourcePredicate.isLocal(source);
 
   /**
-   * Return a source object representing the URI that results from resolving the given (possibly
-   * relative) contained URI against the URI associated with an existing source object, whether or
-   * not the resulting source exists, or `null` if either the contained URI is invalid or if
-   * it cannot be resolved against the source object's URI.
-   *
-   * @param containingSource the source containing the given URI
-   * @param containedUri the (possibly relative) URI to be resolved against the containing source
-   * @return the source representing the contained URI
+   * Return a source representing the URI that results from resolving the given
+   * (possibly relative) [containedUri] against the URI associated with the
+   * [containingSource], whether or not the resulting source exists, or `null`
+   * if either the [containedUri] is invalid or if it cannot be resolved against
+   * the [containingSource]'s URI.
    */
   Source resolveUri(Source containingSource, String containedUri) {
     if (containedUri == null || containedUri.isEmpty) {
@@ -740,10 +752,12 @@
       // Force the creation of an escaped URI to deal with spaces, etc.
       return _internalResolveUri(
           containingSource, parseUriWithException(containedUri));
+    } on URISyntaxException {
+      return null;
     } catch (exception, stackTrace) {
       String containingFullName =
           containingSource != null ? containingSource.fullName : '<null>';
-      AnalysisEngine.instance.logger.logError(
+      AnalysisEngine.instance.logger.logInformation(
           "Could not resolve URI ($containedUri) relative to source ($containingFullName)",
           new CaughtException(exception, stackTrace));
       return null;
@@ -820,8 +834,13 @@
 
     // Check .packages and update target and actual URIs as appropriate.
     if (_packages != null && containedUri.scheme == 'package') {
-      Uri packageUri =
-          _packages.resolve(containedUri, notFound: (Uri packageUri) => null);
+      Uri packageUri = null;
+      try {
+        packageUri =
+            _packages.resolve(containedUri, notFound: (Uri packageUri) => null);
+      } on ArgumentError {
+        // Fall through to try resolvers.
+      }
 
       if (packageUri != null) {
         // Ensure scheme is set.
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 0c5d9e8..4847d9a 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -2,17 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.source.io;
+library analyzer.src.generated.source_io;
 
 import 'dart:collection';
 
-import 'engine.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'java_io.dart';
-import 'source.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 
-export 'source.dart';
+export 'package:analyzer/src/generated/source.dart';
 
 /**
  * Instances of the class [DirectoryBasedSourceContainer] represent a source container that
@@ -136,27 +136,6 @@
             '${uri == null ? file.toURI() : uri}@${file.getPath()}',
             () => _idTable.length);
 
-  /**
-   * Initialize a newly created source object.
-   *
-   * @param file the file represented by this source
-   */
-  @deprecated // Use new FileBasedSource(file)
-  FileBasedSource.con1(JavaFile file) : this(file);
-
-  /**
-   * Initialize a newly created source object.
-   *
-   * @param file the file represented by this source
-   * @param uri the URI from which this source was originally derived
-   */
-  @deprecated // Use new FileBasedSource(file, uri)
-  FileBasedSource.con2(Uri uri, JavaFile file)
-      : uri = uri,
-        file = file,
-        id = _idTable.putIfAbsent(
-            '$uri@${file.getPath()}', () => _idTable.length);
-
   @override
   TimestampedData<String> get contents {
     return PerformanceStatistics.io.makeCurrentWhile(() {
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 3f8c0ef..28f42f7 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -2,17 +2,20 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.resolver.static_type_analyzer;
+library analyzer.src.generated.static_type_analyzer;
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
-
-import 'ast.dart';
-import 'element.dart';
-import 'java_engine.dart';
-import 'resolver.dart';
-import 'scanner.dart' as sc;
+import 'package:analyzer/src/generated/scanner.dart' as sc;
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
  * Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
@@ -93,6 +96,83 @@
   }
 
   /**
+   * Given a constructor name [node] and a type [type], record an inferred type
+   * for the constructor if in strong mode. This is used to fill in any
+   * inferred type parameters found by the resolver.
+   */
+  void inferConstructorName(ConstructorName node, InterfaceType type) {
+    if (_strongMode) {
+      node.type.type = type;
+      _resolver.inferenceContext.recordInference(node.parent, type);
+    }
+    return;
+  }
+
+  /**
+   * Given a formal parameter list and a function type use the function type
+   * to infer types for any of the parameters which have implicit (missing)
+   * types.  Only infers types in strong mode.  Returns true if inference
+   * has occurred.
+   */
+  bool inferFormalParameterList(
+      FormalParameterList node, DartType functionType) {
+    bool inferred = false;
+    if (_strongMode && node != null && functionType is FunctionType) {
+      void inferType(ParameterElementImpl p, DartType inferredType) {
+        // Check that there is no declared type, and that we have not already
+        // inferred a type in some fashion.
+        if (p.hasImplicitType &&
+            (p.type == null || p.type.isDynamic) &&
+            !inferredType.isDynamic) {
+          p.type = inferredType;
+          inferred = true;
+        }
+      }
+
+      List<ParameterElement> parameters = node.parameterElements;
+
+      {
+        List<DartType> normalParameterTypes = functionType.normalParameterTypes;
+        int normalCount = normalParameterTypes.length;
+        Iterable<ParameterElement> required = parameters
+            .where((p) => p.parameterKind == ParameterKind.REQUIRED)
+            .take(normalCount);
+        int index = 0;
+        for (ParameterElementImpl p in required) {
+          inferType(p, normalParameterTypes[index++]);
+        }
+      }
+
+      {
+        List<DartType> optionalParameterTypes =
+            functionType.optionalParameterTypes;
+        int optionalCount = optionalParameterTypes.length;
+        Iterable<ParameterElement> optional = parameters
+            .where((p) => p.parameterKind == ParameterKind.POSITIONAL)
+            .take(optionalCount);
+        int index = 0;
+        for (ParameterElementImpl p in optional) {
+          inferType(p, optionalParameterTypes[index++]);
+        }
+      }
+
+      {
+        Map<String, DartType> namedParameterTypes =
+            functionType.namedParameterTypes;
+        Iterable<ParameterElement> named =
+            parameters.where((p) => p.parameterKind == ParameterKind.NAMED);
+        for (ParameterElementImpl p in named) {
+          if (!namedParameterTypes.containsKey(p.name)) {
+            continue;
+          }
+          inferType(p, namedParameterTypes[p.name]);
+        }
+      }
+    }
+    return inferred;
+  }
+
+  /**
    * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
    * `String`.</blockquote>
    */
@@ -250,7 +330,7 @@
   @override
   Object visitBinaryExpression(BinaryExpression node) {
     if (node.operator.type == TokenType.QUESTION_QUESTION) {
-      // Evaluation of an if-null expresion e of the form e1 ?? e2 is
+      // Evaluation of an if-null expression e of the form e1 ?? e2 is
       // equivalent to the evaluation of the expression
       // ((x) => x == null ? e2 : x)(e1).  The static type of e is the least
       // upper bound of the static type of e1 and the static type of e2.
@@ -333,9 +413,11 @@
     FunctionExpression function = node.functionExpression;
     ExecutableElementImpl functionElement =
         node.element as ExecutableElementImpl;
-    functionElement.returnType =
-        _computeStaticReturnTypeOfFunctionDeclaration(node);
     if (node.parent is FunctionDeclarationStatement) {
+      // TypeResolverVisitor sets the return type for top-level functions, so
+      // we only need to handle local functions.
+      functionElement.returnType =
+          _computeStaticReturnTypeOfFunctionDeclaration(node);
       _recordPropagatedTypeOfFunction(functionElement, function.body);
     }
     _recordStaticType(function, functionElement.type);
@@ -381,8 +463,19 @@
     }
     ExecutableElementImpl functionElement =
         node.element as ExecutableElementImpl;
-    functionElement.returnType =
-        _computeStaticReturnTypeOfFunctionExpression(node);
+    DartType computedType = _computeStaticReturnTypeOfFunctionExpression(node);
+    if (_strongMode) {
+      DartType functionType = InferenceContext.getType(node);
+      if (functionType is FunctionType) {
+        DartType returnType = functionType.returnType;
+        if ((computedType.isDynamic || computedType.isBottom) &&
+            !(returnType.isDynamic || returnType.isBottom)) {
+          computedType = returnType;
+          _resolver.inferenceContext.recordInference(node, functionType);
+        }
+      }
+    }
+    functionElement.returnType = computedType;
     _recordPropagatedTypeOfFunction(functionElement, node.body);
     _recordStaticType(node, node.element.type);
     return null;
@@ -402,15 +495,9 @@
    */
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    DartType functionStaticType = _getStaticType(node.function);
-    DartType staticType;
-    if (functionStaticType is FunctionType) {
-      staticType = functionStaticType.returnType;
-    } else {
-      staticType = _dynamicType;
-    }
+    DartType staticType = _computeInvokeReturnType(node.staticInvokeType);
     _recordStaticType(node, staticType);
-    DartType functionPropagatedType = node.function.propagatedType;
+    DartType functionPropagatedType = node.propagatedInvokeType;
     if (functionPropagatedType is FunctionType) {
       DartType propagatedType = functionPropagatedType.returnType;
       _resolver.recordPropagatedTypeIfBetter(node, propagatedType);
@@ -522,6 +609,15 @@
           staticType = argumentType;
         }
       }
+    } else {
+      DartType contextType = InferenceContext.getType(node);
+      if (_strongMode &&
+          contextType is InterfaceType &&
+          contextType.typeArguments.length == 1 &&
+          contextType.element == _typeProvider.listType.element) {
+        staticType = contextType.typeArguments[0];
+        _resolver.inferenceContext.recordInference(node, contextType);
+      }
     }
     _recordStaticType(
         node, _typeProvider.listType.substitute4(<DartType>[staticType]));
@@ -559,6 +655,16 @@
           staticValueType = entryValueType;
         }
       }
+    } else {
+      DartType contextType = InferenceContext.getType(node);
+      if (_strongMode &&
+          contextType is InterfaceType &&
+          contextType.typeArguments.length == 2 &&
+          contextType.element == _typeProvider.mapType.element) {
+        staticKeyType = contextType.typeArguments[0] ?? staticKeyType;
+        staticValueType = contextType.typeArguments[1] ?? staticValueType;
+        _resolver.inferenceContext.recordInference(node, contextType);
+      }
     }
     _recordStaticType(
         node,
@@ -616,7 +722,7 @@
       _resolver.recordPropagatedTypeIfBetter(methodNameNode, propagatedType);
     }
     // Record static return type of the static element.
-    DartType staticStaticType = _computeStaticReturnType(staticMethodElement);
+    DartType staticStaticType = _computeInvokeReturnType(node.staticInvokeType);
     _recordStaticType(node, staticStaticType);
     // Record propagated return type of the static element.
     DartType staticPropagatedType =
@@ -626,12 +732,6 @@
     bool needPropagatedType = true;
     String methodName = methodNameNode.name;
     if (_strongMode) {
-      // TODO(leafp): Revisit this.  It's here to associate a type with the
-      // method name, which is important to the DDC backend (but apparently
-      // no-one else).  Not sure that there's a problem having this here, but
-      // it's a little ad hoc.
-      visitSimpleIdentifier(methodNameNode);
-
       _inferMethodInvocation(node);
     }
     if (methodName == "then") {
@@ -1036,7 +1136,6 @@
     if (propagatedElement is MethodElement) {
       propagatedType = propagatedElement.type;
     } else if (propagatedElement is PropertyAccessorElement) {
-      Expression realTarget = node.realTarget;
       propagatedType = _getTypeOfProperty(propagatedElement);
     } else {
       // TODO(brianwilkerson) Report this internal error.
@@ -1329,38 +1428,28 @@
       //
       FunctionType propertyType = element.type;
       if (propertyType != null) {
-        DartType returnType = propertyType.returnType;
-        if (returnType.isDartCoreFunction) {
-          return _dynamicType;
-        } else if (returnType is InterfaceType) {
-          MethodElement callMethod = returnType.lookUpMethod(
-              FunctionElement.CALL_METHOD_NAME, _resolver.definingLibrary);
-          if (callMethod != null) {
-            return callMethod.type.returnType;
-          }
-        } else if (returnType is FunctionType) {
-          DartType innerReturnType = returnType.returnType;
-          if (innerReturnType != null) {
-            return innerReturnType;
-          }
-        }
-        if (returnType != null) {
-          return returnType;
-        }
+        return _computeInvokeReturnType(propertyType.returnType);
       }
     } else if (element is ExecutableElement) {
-      FunctionType type = element.type;
-      if (type != null) {
-        // TODO(brianwilkerson) Figure out the conditions under which the type
-        // is null.
-        return type.returnType;
-      }
+      return _computeInvokeReturnType(element.type);
     } else if (element is VariableElement) {
-      VariableElement variable = element;
-      DartType variableType = _promoteManager.getStaticType(variable);
-      if (variableType is FunctionType) {
-        return variableType.returnType;
-      }
+      DartType variableType = _promoteManager.getStaticType(element);
+      return _computeInvokeReturnType(variableType);
+    }
+    return _dynamicType;
+  }
+
+  /**
+   * Compute the return type of the method or function represented by the given
+   * type that is being invoked.
+   */
+  DartType _computeInvokeReturnType(DartType type) {
+    if (type is InterfaceType) {
+      MethodElement callMethod = type.lookUpMethod(
+          FunctionElement.CALL_METHOD_NAME, _resolver.definingLibrary);
+      return callMethod?.type?.returnType ?? _dynamicType;
+    } else if (type is FunctionType) {
+      return type.returnType ?? _dynamicType;
     }
     return _dynamicType;
   }
@@ -1680,6 +1769,25 @@
   }
 
   /**
+   * Given a local variable declaration and its initializer, attempt to infer
+   * a type for the local variable declaration based on the initializer.
+   * Inference is only done if an explicit type is not present, and if
+   * inferring a type improves the type.
+   */
+  void _inferLocalVariableType(
+      VariableDeclaration node, Expression initializer) {
+    if (initializer != null &&
+        (node.parent as VariableDeclarationList).type == null &&
+        (node.element is LocalVariableElementImpl) &&
+        (initializer.staticType != null) &&
+        (!initializer.staticType.isBottom)) {
+      LocalVariableElementImpl element = node.element;
+      element.type = initializer.staticType;
+      node.name.staticType = initializer.staticType;
+    }
+  }
+
+  /**
    * Given a method invocation [node], attempt to infer a better
    * type for the result.
    */
@@ -1690,17 +1798,47 @@
   }
 
   /**
-   * Given a method invocation [node], attempt to infer a better
-   * type for the result using an ad-hoc list of psuedo-generic methods.
+   * Given a generic method invocation [node], attempt to infer the method's
+   * type variables, using the actual types of the arguments.
    */
   bool _inferMethodInvocationGeneric(MethodInvocation node) {
-    DartType inferredType = _matchGeneric(node);
-    // TODO(vsm): If the inferred type is not a subtype,
-    // should we use a GLB instead?
-    if (inferredType != null &&
-        _typeSystem.isSubtypeOf(inferredType, node.staticType)) {
-      _recordStaticType(node, inferredType);
-      return true;
+    Element element = node.methodName.staticElement;
+    DartType invokeType = node.staticInvokeType;
+
+    TypeSystem ts = _typeSystem;
+    if (node.typeArguments == null &&
+        element is ExecutableElement &&
+        ts is StrongTypeSystemImpl) {
+      FunctionType fnType = element.type;
+      if (fnType.typeFormals.isNotEmpty &&
+          ts.instantiateToBounds(fnType) == invokeType) {
+        // Get the parameters that correspond to the uninstantiated generic.
+        List<ParameterElement> genericParameters =
+            ResolverVisitor.resolveArgumentsToParameters(
+                node.argumentList, fnType.parameters, null);
+
+        int length = genericParameters.length;
+        List<DartType> argTypes = new List<DartType>(length);
+        List<DartType> paramTypes = new List<DartType>(length);
+        for (int i = 0; i < length; i++) {
+          argTypes[i] = node.argumentList.arguments[i].staticType;
+          paramTypes[i] = genericParameters[i].type;
+        }
+
+        FunctionType inferred = ts.inferCallFromArguments(
+            _typeProvider, fnType, paramTypes, argTypes);
+
+        if (inferred != fnType) {
+          // Fix up the parameter elements based on inferred method.
+          List<ParameterElement> inferredParameters =
+              ResolverVisitor.resolveArgumentsToParameters(
+                  node.argumentList, inferred.parameters, null);
+          node.argumentList.correspondingStaticParameters = inferredParameters;
+          node.staticInvokeType = inferred;
+          _recordStaticType(node, inferred.returnType);
+          return true;
+        }
+      }
     }
     return false;
   }
@@ -1759,7 +1897,7 @@
         inferredType.parameters.isEmpty &&
         node.argumentList.arguments.isEmpty &&
         _typeProvider.nonSubtypableTypes.contains(inferredType.returnType)) {
-      _recordStaticType(node.methodName, inferredType);
+      node.staticInvokeType = inferredType;
       _recordStaticType(node, inferredType.returnType);
       return true;
     }
@@ -1767,25 +1905,6 @@
   }
 
   /**
-   * Given a local variable declaration and its initializer, attempt to infer
-   * a type for the local variable declaration based on the initializer.
-   * Inference is only done if an explicit type is not present, and if
-   * inferring a type improves the type.
-   */
-  void _inferLocalVariableType(
-      VariableDeclaration node, Expression initializer) {
-    if (initializer != null &&
-        (node.parent as VariableDeclarationList).type == null &&
-        (node.element is LocalVariableElementImpl) &&
-        (initializer.staticType != null) &&
-        (!initializer.staticType.isBottom)) {
-      LocalVariableElementImpl element = node.element;
-      element.type = initializer.staticType;
-      node.name.staticType = initializer.staticType;
-    }
-  }
-
-  /**
    * Given a property access [node] with static type [nodeType],
    * and [id] is the property name being accessed, infer a type for the
    * access itself and its constituent components if the access is to one of the
@@ -1822,7 +1941,8 @@
    * Return `true` if the given [Type] is the `Future` form the 'dart:async'
    * library.
    */
-  bool _isAsyncFutureType(DartType type) => type is InterfaceType &&
+  bool _isAsyncFutureType(DartType type) =>
+      type is InterfaceType &&
       type.name == "Future" &&
       _isAsyncLibrary(type.element.library);
 
@@ -1863,91 +1983,6 @@
   }
 
   /**
-   * Return a more specialized type for a method invocation based on
-   * an ad-hoc list of pseudo-generic methods.
-   */
-  DartType _matchGeneric(MethodInvocation node) {
-    Element e = node.methodName.staticElement;
-
-    if (e == null || e.name == null) {
-      return null;
-    }
-
-    List<DartType> arguments =
-        node.argumentList.arguments.map((arg) => arg.staticType).toList();
-
-    bool matchInvocation(DartType t, int c) {
-      return (node.realTarget != null) &&
-          node.realTarget.staticType.isSubtypeOf(t) &&
-          arguments.length == c;
-    }
-
-    switch (e.name) {
-      case 'max':
-      case 'min':
-        if (e.library.source.uri.toString() == 'dart:math' &&
-            arguments.length == 2) {
-          DartType tx = arguments[0];
-          DartType ty = arguments[1];
-          if (tx == ty &&
-              (tx == _typeProvider.intType || tx == _typeProvider.doubleType)) {
-            return tx;
-          }
-        }
-        return null;
-      case 'wait':
-        if (matchInvocation(_typeProvider.futureType, 1)) {
-          DartType tx = arguments[0];
-          // Iterable<Future<T>> -> Future<List<T>>
-          DartType futureType =
-              _findIteratedType(tx, _typeProvider.iterableType);
-          if (futureType.element != _typeProvider.futureType.element) {
-            return null;
-          }
-          List<DartType> typeArguments =
-              (futureType as InterfaceType).typeArguments;
-          if (typeArguments.length != 1) {
-            return null;
-          }
-          DartType baseType = typeArguments[0];
-          if (baseType.isDynamic) {
-            return null;
-          }
-          return _typeProvider.futureType.substitute4([
-            _typeProvider.listType.substitute4([baseType])
-          ]);
-        }
-        return null;
-      case 'map':
-        if (matchInvocation(_typeProvider.iterableDynamicType, 1)) {
-          DartType tx = arguments[0];
-          return (tx is FunctionType)
-              ? _typeProvider.iterableType.substitute4([tx.returnType])
-              : null;
-        }
-        return null;
-      case 'fold':
-        if (matchInvocation(_typeProvider.iterableDynamicType, 2)) {
-          DartType tx = arguments[0];
-          DartType ty = arguments[1];
-          // TODO(vsm): LUB?
-          return (ty is FunctionType && tx == ty.returnType) ? tx : null;
-        }
-        return null;
-      case 'then':
-        if (matchInvocation(_typeProvider.futureDynamicType, 1)) {
-          DartType tx = arguments[0];
-          return (tx is FunctionType)
-              ? _typeProvider.futureType.substitute4([tx.returnType])
-              : null;
-        }
-        return null;
-      default:
-        return null;
-    }
-  }
-
-  /**
    * Record that the propagated type of the given node is the given type.
    *
    * @param expression the node whose type is to be recorded
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
index bb758b3..c6892c2 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.testing.ast_factory;
+library analyzer.src.generated.testing.ast_factory;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -46,11 +46,14 @@
       new AsExpression(
           expression, TokenFactory.tokenFromKeyword(Keyword.AS), type);
 
-  static AssertStatement assertStatement(Expression condition) =>
+  static AssertStatement assertStatement(Expression condition,
+          [Expression message]) =>
       new AssertStatement(
           TokenFactory.tokenFromKeyword(Keyword.ASSERT),
           TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
           condition,
+          message == null ? null : TokenFactory.tokenFromType(TokenType.COMMA),
+          message,
           TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
           TokenFactory.tokenFromType(TokenType.SEMICOLON));
 
@@ -431,6 +434,7 @@
           metadata,
           TokenFactory.tokenFromKeyword(Keyword.EXPORT),
           string2(uri),
+          null,
           combinators,
           TokenFactory.tokenFromType(TokenType.SEMICOLON));
 
@@ -657,6 +661,7 @@
           metadata,
           TokenFactory.tokenFromKeyword(Keyword.IMPORT),
           string2(uri),
+          null,
           !isDeferred ? null : TokenFactory.tokenFromKeyword(Keyword.DEFERRED),
           prefix == null ? null : TokenFactory.tokenFromKeyword(Keyword.AS),
           prefix == null ? null : identifier3(prefix),
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 736fa0d..0dc3c7b 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -2,13 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.testing.element_factory;
+library analyzer.src.generated.testing.element_factory;
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.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';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -42,25 +45,17 @@
       String typeName, InterfaceType superclassType,
       [List<String> parameterNames]) {
     ClassElementImpl element = new ClassElementImpl(typeName, 0);
+    element.constructors = const <ConstructorElement>[];
     element.supertype = superclassType;
     InterfaceTypeImpl type = new InterfaceTypeImpl(element);
     element.type = type;
     if (parameterNames != null) {
       int count = parameterNames.length;
       if (count > 0) {
-        List<TypeParameterElementImpl> typeParameters =
-            new List<TypeParameterElementImpl>(count);
-        List<TypeParameterTypeImpl> typeParameterTypes =
-            new List<TypeParameterTypeImpl>(count);
-        for (int i = 0; i < count; i++) {
-          TypeParameterElementImpl typeParameter =
-              typeParameterElement(parameterNames[i]);
-          typeParameters[i] = typeParameter;
-          typeParameterTypes[i] = new TypeParameterTypeImpl(typeParameter);
-          typeParameter.type = typeParameterTypes[i];
-        }
-        element.typeParameters = typeParameters;
-        type.typeArguments = typeParameterTypes;
+        element.typeParameters = typeParameters(parameterNames);
+        type.typeArguments = new List<DartType>.from(
+            element.typeParameters.map((p) => p.type),
+            growable: false);
       }
     }
     return element;
@@ -120,8 +115,8 @@
       constructor.parameters = <ParameterElement>[];
     }
     constructor.returnType = type;
-    FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
-    constructor.type = constructorType;
+    constructor.enclosingElement = definingClass;
+    constructor.type = new FunctionTypeImpl(constructor);
     return constructor;
   }
 
@@ -204,7 +199,9 @@
 
   static FieldElementImpl fieldElement(
       String name, bool isStatic, bool isFinal, bool isConst, DartType type) {
-    FieldElementImpl field = new FieldElementImpl(name, 0);
+    FieldElementImpl field = isConst
+        ? new ConstFieldElementImpl(name, 0)
+        : new FieldElementImpl(name, 0);
     field.const3 = isConst;
     field.final2 = isFinal;
     field.static = isStatic;
@@ -242,12 +239,12 @@
       functionElement4(functionName, null, null, null, null);
 
   static FunctionElementImpl functionElement2(
-          String functionName, ClassElement returnElement) =>
+          String functionName, TypeDefiningElement returnElement) =>
       functionElement3(functionName, returnElement, null, null);
 
   static FunctionElementImpl functionElement3(
       String functionName,
-      ClassElement returnElement,
+      TypeDefiningElement returnElement,
       List<TypeDefiningElement> normalParameters,
       List<TypeDefiningElement> optionalParameters) {
     // We don't create parameter elements because we don't have parameter names
@@ -406,8 +403,10 @@
     field.static = isStatic;
     field.synthetic = true;
     field.type = type;
+    field.final2 = true;
     PropertyAccessorElementImpl getter =
         new PropertyAccessorElementImpl.forVariable(field);
+    getter.synthetic = false;
     getter.getter = true;
     getter.variable = field;
     getter.returnType = type;
@@ -417,15 +416,6 @@
     return getter;
   }
 
-  @deprecated
-  static HtmlElementImpl htmlUnit(AnalysisContext context, String fileName) {
-    Source source =
-        new NonExistingSource(fileName, toUri(fileName), UriKind.FILE_URI);
-    HtmlElementImpl unit = new HtmlElementImpl(context, fileName);
-    unit.source = source;
-    return unit;
-  }
-
   static ImportElementImpl importFor(
       LibraryElement importedLibrary, PrefixElement prefix,
       [List<NamespaceCombinator> combinators =
@@ -476,16 +466,15 @@
   }
 
   static MethodElementImpl methodElementWithParameters(
+      ClassElement enclosingElement,
       String methodName,
-      List<DartType> typeArguments,
       DartType returnType,
       List<ParameterElement> parameters) {
     MethodElementImpl method = new MethodElementImpl(methodName, 0);
+    method.enclosingElement = enclosingElement;
     method.parameters = parameters;
     method.returnType = returnType;
-    FunctionTypeImpl methodType = new FunctionTypeImpl(method);
-    methodType.typeArguments = typeArguments;
-    method.type = methodType;
+    method.type = new FunctionTypeImpl(method);
     return method;
   }
 
@@ -578,7 +567,8 @@
     }
     variable.const3 = isConst;
     variable.final2 = isFinal;
-    variable.synthetic = true;
+    variable.synthetic = false;
+    variable.type = type;
     PropertyAccessorElementImpl getter =
         new PropertyAccessorElementImpl.forVariable(variable);
     getter.getter = true;
@@ -610,4 +600,25 @@
     element.type = new TypeParameterTypeImpl(element);
     return element;
   }
+
+  static List<TypeParameterElement> typeParameters(List<String> names) {
+    int count = names.length;
+    if (count == 0) {
+      return TypeParameterElement.EMPTY_LIST;
+    }
+    List<TypeParameterElementImpl> typeParameters =
+        new List<TypeParameterElementImpl>(count);
+    for (int i = 0; i < count; i++) {
+      typeParameters[i] = typeParameterWithType(names[i]);
+    }
+    return typeParameters;
+  }
+
+  static TypeParameterElementImpl typeParameterWithType(String name,
+      [DartType bound]) {
+    TypeParameterElementImpl typeParameter = typeParameterElement(name);
+    typeParameter.type = new TypeParameterTypeImpl(typeParameter);
+    typeParameter.bound = bound;
+    return typeParameter;
+  }
 }
diff --git a/pkg/analyzer/lib/src/generated/testing/html_factory.dart b/pkg/analyzer/lib/src/generated/testing/html_factory.dart
deleted file mode 100644
index a9ac412..0000000
--- a/pkg/analyzer/lib/src/generated/testing/html_factory.dart
+++ /dev/null
@@ -1,63 +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 engine.testing.html_factory;
-
-import 'package:analyzer/src/generated/html.dart';
-
-/**
- * Utility methods to create HTML nodes.
- */
-@deprecated
-class HtmlFactory {
-  static XmlAttributeNode attribute(String name, String value) {
-    Token nameToken = stringToken(name);
-    Token equalsToken = new Token.con1(TokenType.EQ, 0);
-    Token valueToken = stringToken(value);
-    return new XmlAttributeNode(nameToken, equalsToken, valueToken);
-  }
-
-  static Token gtToken() {
-    return new Token.con1(TokenType.GT, 0);
-  }
-
-  static Token ltsToken() {
-    return new Token.con1(TokenType.LT_SLASH, 0);
-  }
-
-  static Token ltToken() {
-    return new Token.con1(TokenType.LT, 0);
-  }
-
-  static HtmlScriptTagNode scriptTag(
-      [List<XmlAttributeNode> attributes = XmlAttributeNode.EMPTY_LIST]) {
-    return new HtmlScriptTagNode(ltToken(), stringToken("script"), attributes,
-        sgtToken(), null, null, null, null);
-  }
-
-  static HtmlScriptTagNode scriptTagWithContent(String contents,
-      [List<XmlAttributeNode> attributes = XmlAttributeNode.EMPTY_LIST]) {
-    Token attributeEnd = gtToken();
-    Token contentToken = stringToken(contents);
-    attributeEnd.setNext(contentToken);
-    Token contentEnd = ltsToken();
-    contentToken.setNext(contentEnd);
-    return new HtmlScriptTagNode(ltToken(), stringToken("script"), attributes,
-        attributeEnd, null, contentEnd, stringToken("script"), gtToken());
-  }
-
-  static Token sgtToken() {
-    return new Token.con1(TokenType.SLASH_GT, 0);
-  }
-
-  static Token stringToken(String value) {
-    return new Token.con2(TokenType.STRING, 0, value);
-  }
-
-  static XmlTagNode tagNode(String name,
-      [List<XmlAttributeNode> attributes = XmlAttributeNode.EMPTY_LIST]) {
-    return new XmlTagNode(ltToken(), stringToken(name), attributes, sgtToken(),
-        null, null, null, null);
-  }
-}
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index 5b5204a..5f1a49b 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -2,12 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.testing.test_type_provider;
+library analyzer.src.generated.testing.test_type_provider;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.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/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 
@@ -208,7 +212,11 @@
   @override
   InterfaceType get functionType {
     if (_functionType == null) {
-      _functionType = ElementFactory.classElement2("Function").type;
+      ClassElementImpl functionClass = ElementFactory.classElement2("Function");
+      functionClass.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(functionClass, null, false)
+      ];
+      _functionType = functionClass.type;
     }
     return _functionType;
   }
@@ -265,7 +273,10 @@
             "iterator", false, iteratorType.substitute4(<DartType>[eType])),
         ElementFactory.getterElement("last", false, eType)
       ]);
-      iterableElement.constructors = ConstructorElement.EMPTY_LIST;
+      iterableElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(iterableElement, null, true)
+          ..isCycleFree = true
+      ];
       _propagateTypeArguments(iterableElement);
     }
     return _iterableType;
@@ -280,7 +291,9 @@
       _setAccessors(iteratorElement, <PropertyAccessorElement>[
         ElementFactory.getterElement("current", false, eType)
       ]);
-      iteratorElement.constructors = ConstructorElement.EMPTY_LIST;
+      iteratorElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(iteratorElement, null, false)
+      ];
       _propagateTypeArguments(iteratorElement);
     }
     return _iteratorType;
@@ -329,7 +342,11 @@
         ElementFactory.methodElement(
             "[]=", VoidTypeImpl.instance, [kType, vType])
       ];
-      mapElement.constructors = ConstructorElement.EMPTY_LIST;
+      mapElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(mapElement, null, false)
+          ..external = true
+          ..factory = true
+      ];
       _propagateTypeArguments(mapElement);
     }
     return _mapType;
@@ -357,7 +374,10 @@
   InterfaceType get nullType {
     if (_nullType == null) {
       ClassElementImpl nullElement = ElementFactory.classElement2("Null");
-      nullElement.constructors = ConstructorElement.EMPTY_LIST;
+      nullElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(
+            nullElement, '_uninstantiatable', false)..factory = true
+      ];
       _nullType = nullElement.type;
     }
     return _nullType;
@@ -396,7 +416,12 @@
   @override
   InterfaceType get stackTraceType {
     if (_stackTraceType == null) {
-      _stackTraceType = ElementFactory.classElement2("StackTrace").type;
+      ClassElementImpl stackTraceElement =
+          ElementFactory.classElement2("StackTrace");
+      stackTraceElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(stackTraceElement, null, false)
+      ];
+      _stackTraceType = stackTraceElement.type;
     }
     return _stackTraceType;
   }
@@ -463,7 +488,12 @@
   @override
   InterfaceType get typeType {
     if (_typeType == null) {
-      _typeType = ElementFactory.classElement2("Type").type;
+      ClassElementImpl typeClass = ElementFactory.classElement2("Type");
+      typeClass.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(typeClass, null, false)
+          ..synthetic = true
+      ];
+      _typeType = typeClass.type;
     }
     return _typeType;
   }
@@ -554,12 +584,22 @@
     ];
     fromEnvironment.factory = true;
     fromEnvironment.isCycleFree = true;
-    numElement.constructors = ConstructorElement.EMPTY_LIST;
+    numElement.constructors = <ConstructorElement>[
+      ElementFactory.constructorElement(numElement, null, false)
+        ..synthetic = true
+    ];
     intElement.constructors = <ConstructorElement>[fromEnvironment];
-    doubleElement.constructors = ConstructorElement.EMPTY_LIST;
+    doubleElement.constructors = <ConstructorElement>[
+      ElementFactory.constructorElement(doubleElement, null, false)
+        ..synthetic = true
+    ];
+    ConstFieldElementImpl varINFINITY =
+        ElementFactory.fieldElement("INFINITY", true, false, true, _doubleType);
+    varINFINITY.constantInitializer = AstFactory.binaryExpression(
+        AstFactory.integer(1), TokenType.SLASH, AstFactory.integer(0));
     List<FieldElement> fields = <FieldElement>[
       ElementFactory.fieldElement("NAN", true, false, true, _doubleType),
-      ElementFactory.fieldElement("INFINITY", true, false, true, _doubleType),
+      varINFINITY,
       ElementFactory.fieldElement(
           "NEGATIVE_INFINITY", true, false, true, _doubleType),
       ElementFactory.fieldElement(
@@ -598,19 +638,15 @@
    * defined for the class.
    */
   void _propagateTypeArguments(ClassElementImpl classElement) {
-    List<DartType> typeArguments =
-        TypeParameterTypeImpl.getTypes(classElement.typeParameters);
     for (PropertyAccessorElement accessor in classElement.accessors) {
-      FunctionTypeImpl functionType = accessor.type as FunctionTypeImpl;
-      functionType.typeArguments = typeArguments;
+      (accessor as ExecutableElementImpl).type = new FunctionTypeImpl(accessor);
     }
     for (MethodElement method in classElement.methods) {
-      FunctionTypeImpl functionType = method.type as FunctionTypeImpl;
-      functionType.typeArguments = typeArguments;
+      (method as ExecutableElementImpl).type = new FunctionTypeImpl(method);
     }
     for (ConstructorElement constructor in classElement.constructors) {
-      FunctionTypeImpl functionType = constructor.type as FunctionTypeImpl;
-      functionType.typeArguments = typeArguments;
+      (constructor as ExecutableElementImpl).type =
+          new FunctionTypeImpl(constructor);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/generated/testing/token_factory.dart b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
index 1b9a828..a293842 100644
--- a/pkg/analyzer/lib/src/generated/testing/token_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.testing.token_factory;
+library analyzer.src.generated.testing.token_factory;
 
 import 'package:analyzer/src/generated/scanner.dart';
 
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
new file mode 100644
index 0000000..911dfa9
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -0,0 +1,867 @@
+// 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.generated.type_system;
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+
+typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
+typedef bool _SubtypeChecker<T>(T t1, T t2);
+
+/**
+ * Implementation of [TypeSystem] using the strong mode rules.
+ * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md
+ */
+class StrongTypeSystemImpl implements TypeSystem {
+  final _specTypeSystem = new TypeSystemImpl();
+
+  StrongTypeSystemImpl();
+
+  bool anyParameterType(FunctionType ft, bool predicate(DartType t)) {
+    return ft.parameters.any((p) => predicate(p.type));
+  }
+
+  /**
+   * Given a type t, if t is an interface type with a call method
+   * defined, return the function type for the call method, otherwise
+   * return null.
+   */
+  FunctionType getCallMethodType(DartType t) {
+    if (t is InterfaceType) {
+      return t.lookUpInheritedMethod("call")?.type;
+    }
+    return null;
+  }
+
+  @override
+  DartType getLeastUpperBound(
+      TypeProvider typeProvider, DartType type1, DartType type2) {
+    // TODO(leafp): Implement a strong mode version of this.
+    return _specTypeSystem.getLeastUpperBound(typeProvider, type1, type2);
+  }
+
+  /// Given a function type with generic type parameters, infer the type
+  /// parameters from the actual argument types, and return it. If we can't.
+  /// returns the original function type.
+  ///
+  /// Concretely, given a function type with parameter types P0, P1, ... Pn,
+  /// result type R, and generic type parameters T0, T1, ... Tm, use the
+  /// argument types A0, A1, ... An to solve for the type parameters.
+  ///
+  /// For each parameter Pi, we want to ensure that Ai <: Pi. We can do this by
+  /// running the subtype algorithm, and when we reach a type parameter Pj,
+  /// recording the lower or upper bound it must satisfy. At the end, all
+  /// constraints can be combined to determine the type.
+  ///
+  /// As a simplification, we do not actually store all constraints on each type
+  /// parameter Pj. Instead we track Uj and Lj where U is the upper bound and
+  /// L is the lower bound of that type parameter.
+  FunctionType inferCallFromArguments(
+      TypeProvider typeProvider,
+      FunctionTypeImpl fnType,
+      List<DartType> correspondingParameterTypes,
+      List<DartType> argumentTypes) {
+    if (fnType.typeFormals.isEmpty) {
+      return fnType;
+    }
+
+    List<TypeParameterType> fnTypeParams =
+        TypeParameterTypeImpl.getTypes(fnType.typeFormals);
+
+    // Create a TypeSystem that will allow certain type parameters to be
+    // inferred. It will optimistically assume these type parameters can be
+    // subtypes (or supertypes) as necessary, and track the constraints that
+    // are implied by this.
+    var inferringTypeSystem =
+        new _StrongInferenceTypeSystem(typeProvider, fnTypeParams);
+
+    for (int i = 0; i < argumentTypes.length; i++) {
+      // Try to pass each argument to each parameter, recording any type
+      // parameter bounds that were implied by this assignment.
+      inferringTypeSystem.isSubtypeOf(
+          argumentTypes[i], correspondingParameterTypes[i]);
+    }
+
+    var inferredTypes = new List<DartType>.from(fnTypeParams, growable: false);
+    for (int i = 0; i < fnTypeParams.length; i++) {
+      TypeParameterType typeParam = fnTypeParams[i];
+      _TypeParameterBound bound = inferringTypeSystem._bounds[typeParam];
+
+      // Now we've computed lower and upper bounds for each type parameter.
+      //
+      // To decide on which type to assign, we look at the return type and see
+      // if the type parameter occurs in covariant or contravariant positions.
+      //
+      // If the type is "passed in" at all, or if our lower bound was bottom,
+      // we choose the upper bound as being the most useful.
+      //
+      // Otherwise we choose the more precise lower bound.
+      _TypeParameterVariance variance =
+          new _TypeParameterVariance.from(typeParam, fnType.returnType);
+
+      inferredTypes[i] =
+          variance.passedIn || bound.lower.isBottom ? bound.upper : bound.lower;
+
+      // Assumption: if the current type parameter has an "extends" clause
+      // that refers to another type variable we are inferring, it will appear
+      // before us or in this list position. For example:
+      //
+      //     <TFrom, TTo extends TFrom>
+      //
+      // We may infer TTo is TFrom. In that case, we already know what TFrom
+      // is inferred as, so we can substitute it now. This also handles more
+      // complex cases such as:
+      //
+      //     <TFrom, TTo extends Iterable<TFrom>>
+      //
+      // Or if the type parameter's bound depends on itself such as:
+      //
+      //     <T extends Clonable<T>>
+      inferredTypes[i] =
+          inferredTypes[i].substitute2(inferredTypes, fnTypeParams);
+
+      // See if this actually worked.
+      // If not, fall back to the known upper bound (if any) or `dynamic`.
+      if (inferredTypes[i].isBottom ||
+          !isSubtypeOf(inferredTypes[i],
+              bound.upper.substitute2(inferredTypes, fnTypeParams)) ||
+          !isSubtypeOf(bound.lower.substitute2(inferredTypes, fnTypeParams),
+              inferredTypes[i])) {
+        inferredTypes[i] = DynamicTypeImpl.instance;
+        if (typeParam.element.bound != null) {
+          inferredTypes[i] =
+              typeParam.element.bound.substitute2(inferredTypes, fnTypeParams);
+        }
+      }
+    }
+
+    // Return the instantiated type.
+    return fnType.instantiate(inferredTypes);
+  }
+
+  /**
+   * Given a [FunctionType] [function], of the form
+   * <T0 extends B0, ... Tn extends Bn>.F (where Bi is implicitly
+   * dynamic if absent, and F is a non-generic function type)
+   * compute {I0/T0, ..., In/Tn}F
+   * where I_(i+1) = {I0/T0, ..., Ii/Ti, dynamic/T_(i+1)}B_(i+1).
+   * That is, we instantiate the generic with its bounds, replacing
+   * each Ti in Bi with dynamic to get Ii, and then replacing Ti with
+   * Ii in all of the remaining bounds.
+   */
+  DartType instantiateToBounds(FunctionType function) {
+    int count = function.typeFormals.length;
+    if (count == 0) {
+      return function;
+    }
+    // We build up a substitution replacing bound parameters with
+    // their instantiated bounds, {substituted/variables}
+    List<DartType> substituted = new List<DartType>();
+    List<DartType> variables = new List<DartType>();
+    for (int i = 0; i < count; i++) {
+      TypeParameterElement param = function.typeFormals[i];
+      DartType bound = param.bound ?? DynamicTypeImpl.instance;
+      DartType variable = param.type;
+      // For each Ti extends Bi, first compute Ii by replacing
+      // Ti in Bi with dynamic (simultaneously replacing all
+      // of the previous Tj (j < i) with their instantiated bounds.
+      substituted.add(DynamicTypeImpl.instance);
+      variables.add(variable);
+      // Now update the substitution to replace Ti with Ii instead
+      // of dynamic in subsequent rounds.
+      substituted[i] = bound.substitute2(substituted, variables);
+    }
+    return function.instantiate(substituted);
+  }
+
+  @override
+  bool isAssignableTo(DartType fromType, DartType toType) {
+    // TODO(leafp): Document the rules in play here
+
+    // An actual subtype
+    if (isSubtypeOf(fromType, toType)) {
+      return true;
+    }
+
+    // Don't allow implicit downcasts between function types
+    // and call method objects, as these will almost always fail.
+    if ((fromType is FunctionType && getCallMethodType(toType) != null) ||
+        (toType is FunctionType && getCallMethodType(fromType) != null)) {
+      return false;
+    }
+
+    // If the subtype relation goes the other way, allow the implicit downcast.
+    // TODO(leafp): Emit warnings and hints for these in some way.
+    // TODO(leafp): Consider adding a flag to disable these?  Or just rely on
+    //   --warnings-as-errors?
+    if (isSubtypeOf(toType, fromType) ||
+        _specTypeSystem.isAssignableTo(toType, fromType)) {
+      // TODO(leafp): error if type is known to be exact (literal,
+      //  instance creation).
+      // TODO(leafp): Warn on composite downcast.
+      // TODO(leafp): hint on object/dynamic downcast.
+      // TODO(leafp): Consider allowing assignment casts.
+      return true;
+    }
+
+    return false;
+  }
+
+  bool isGroundType(DartType t) {
+    // TODO(leafp): Revisit this.
+    if (t is TypeParameterType) return false;
+    if (_isTop(t)) return true;
+
+    if (t is FunctionType) {
+      if (!_isTop(t.returnType) ||
+          anyParameterType(t, (pt) => !_isBottom(pt, dynamicIsBottom: true))) {
+        return false;
+      } else {
+        return true;
+      }
+    }
+
+    if (t is InterfaceType) {
+      var typeArguments = t.typeArguments;
+      for (var typeArgument in typeArguments) {
+        if (!_isTop(typeArgument)) return false;
+      }
+      return true;
+    }
+
+    // We should not see any other type aside from malformed code.
+    return false;
+  }
+
+  @override
+  bool isSubtypeOf(DartType leftType, DartType rightType) {
+    return _isSubtypeOf(leftType, rightType, null);
+  }
+
+  /**
+   * Guard against loops in the class hierarchy
+   */
+  _GuardedSubtypeChecker<DartType> _guard(
+      _GuardedSubtypeChecker<DartType> check) {
+    return (DartType t1, DartType t2, Set<Element> visited) {
+      Element element = t1.element;
+      if (visited == null) {
+        visited = new HashSet<Element>();
+      }
+      if (element == null || !visited.add(element)) {
+        return false;
+      }
+      try {
+        return check(t1, t2, visited);
+      } finally {
+        visited.remove(element);
+      }
+    };
+  }
+
+  /// If [t1] or [t2] is a type parameter we are inferring, update its bound.
+  /// Returns `true` if we could possibly find a compatible type,
+  /// otherwise `false`.
+  bool _inferTypeParameterSubtypeOf(
+      DartType t1, DartType t2, Set<Element> visited) {
+    return false;
+  }
+
+  bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
+    return (t.isDynamic && dynamicIsBottom) || t.isBottom;
+  }
+
+  /**
+   * Check that [f1] is a subtype of [f2].
+   * [fuzzyArrows] indicates whether or not the f1 and f2 should be
+   * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated
+   * as bottom).
+   */
+  bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
+      {bool fuzzyArrows: true}) {
+    if (!f1.typeFormals.isEmpty) {
+      if (f2.typeFormals.isEmpty) {
+        f1 = instantiateToBounds(f1);
+        return _isFunctionSubtypeOf(f1, f2);
+      } else {
+        return _isGenericFunctionSubtypeOf(f1, f2, fuzzyArrows: fuzzyArrows);
+      }
+    }
+    final List<DartType> r1s = f1.normalParameterTypes;
+    final List<DartType> r2s = f2.normalParameterTypes;
+    final List<DartType> o1s = f1.optionalParameterTypes;
+    final List<DartType> o2s = f2.optionalParameterTypes;
+    final Map<String, DartType> n1s = f1.namedParameterTypes;
+    final Map<String, DartType> n2s = f2.namedParameterTypes;
+    final DartType ret1 = f1.returnType;
+    final DartType ret2 = f2.returnType;
+
+    // A -> B <: C -> D if C <: A and
+    // either D is void or B <: D
+    if (!ret2.isVoid && !isSubtypeOf(ret1, ret2)) {
+      return false;
+    }
+
+    // Reject if one has named and the other has optional
+    if (n1s.length > 0 && o2s.length > 0) {
+      return false;
+    }
+    if (n2s.length > 0 && o1s.length > 0) {
+      return false;
+    }
+
+    // Rebind _isSubtypeOf for convenience
+    _SubtypeChecker<DartType> parameterSubtype = (DartType t1, DartType t2) =>
+        _isSubtypeOf(t1, t2, null, dynamicIsBottom: fuzzyArrows);
+
+    // f2 has named parameters
+    if (n2s.length > 0) {
+      // Check that every named parameter in f2 has a match in f1
+      for (String k2 in n2s.keys) {
+        if (!n1s.containsKey(k2)) {
+          return false;
+        }
+        if (!parameterSubtype(n2s[k2], n1s[k2])) {
+          return false;
+        }
+      }
+    }
+    // If we get here, we either have no named parameters,
+    // or else the named parameters match and we have no optional
+    // parameters
+
+    // If f1 has more required parameters, reject
+    if (r1s.length > r2s.length) {
+      return false;
+    }
+
+    // If f2 has more required + optional parameters, reject
+    if (r2s.length + o2s.length > r1s.length + o1s.length) {
+      return false;
+    }
+
+    // The parameter lists must look like the following at this point
+    // where rrr is a region of required, and ooo is a region of optionals.
+    // f1: rrr ooo ooo ooo
+    // f2: rrr rrr ooo
+    int rr = r1s.length; // required in both
+    int or = r2s.length - r1s.length; // optional in f1, required in f2
+    int oo = o2s.length; // optional in both
+
+    for (int i = 0; i < rr; ++i) {
+      if (!parameterSubtype(r2s[i], r1s[i])) {
+        return false;
+      }
+    }
+    for (int i = 0, j = rr; i < or; ++i, ++j) {
+      if (!parameterSubtype(r2s[j], o1s[i])) {
+        return false;
+      }
+    }
+    for (int i = or, j = 0; i < oo; ++i, ++j) {
+      if (!parameterSubtype(o2s[j], o1s[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Check that [f1] is a subtype of [f2] where f1 and f2 are known
+   * to be generic function types (both have type parameters)
+   * [fuzzyArrows] indicates whether or not the f1 and f2 should be
+   * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated
+   * as bottom).
+   */
+  bool _isGenericFunctionSubtypeOf(FunctionType f1, FunctionType f2,
+      {bool fuzzyArrows: true}) {
+    List<TypeParameterElement> params1 = f1.typeFormals;
+    List<TypeParameterElement> params2 = f2.typeFormals;
+    int count = params1.length;
+    if (params2.length != count) {
+      return false;
+    }
+    // We build up a substitution matching up the type parameters
+    // from the two types, {variablesFresh/variables1} and
+    // {variablesFresh/variables2}
+    List<DartType> variables1 = new List<DartType>();
+    List<DartType> variables2 = new List<DartType>();
+    List<DartType> variablesFresh = new List<DartType>();
+    for (int i = 0; i < count; i++) {
+      TypeParameterElement p1 = params1[i];
+      TypeParameterElement p2 = params2[i];
+      TypeParameterElementImpl pFresh =
+          new TypeParameterElementImpl(p2.name, -1);
+
+      DartType variable1 = p1.type;
+      DartType variable2 = p2.type;
+      DartType variableFresh = new TypeParameterTypeImpl(pFresh);
+
+      variables1.add(variable1);
+      variables2.add(variable2);
+      variablesFresh.add(variableFresh);
+      DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
+      DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
+      bound1 = bound1.substitute2(variablesFresh, variables1);
+      bound2 = bound2.substitute2(variablesFresh, variables2);
+      pFresh.bound = bound2;
+      if (!isSubtypeOf(bound2, bound1)) {
+        return false;
+      }
+    }
+    return _isFunctionSubtypeOf(
+        f1.instantiate(variablesFresh), f2.instantiate(variablesFresh),
+        fuzzyArrows: fuzzyArrows);
+  }
+
+  bool _isInterfaceSubtypeOf(
+      InterfaceType i1, InterfaceType i2, Set<Element> visited) {
+    // Guard recursive calls
+    _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype =
+        _guard(_isInterfaceSubtypeOf);
+
+    if (i1 == i2) {
+      return true;
+    }
+
+    if (i1.element == i2.element) {
+      List<DartType> tArgs1 = i1.typeArguments;
+      List<DartType> tArgs2 = i2.typeArguments;
+
+      assert(tArgs1.length == tArgs2.length);
+
+      for (int i = 0; i < tArgs1.length; i++) {
+        DartType t1 = tArgs1[i];
+        DartType t2 = tArgs2[i];
+        if (!isSubtypeOf(t1, t2)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    if (i2.isDartCoreFunction && i1.element.getMethod("call") != null) {
+      return true;
+    }
+
+    if (i1.isObject) {
+      return false;
+    }
+
+    if (guardedInterfaceSubtype(i1.superclass, i2, visited)) {
+      return true;
+    }
+
+    for (final parent in i1.interfaces) {
+      if (guardedInterfaceSubtype(parent, i2, visited)) {
+        return true;
+      }
+    }
+
+    for (final parent in i1.mixins) {
+      if (guardedInterfaceSubtype(parent, i2, visited)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  bool _isSubtypeOf(DartType t1, DartType t2, Set<Element> visited,
+      {bool dynamicIsBottom: false}) {
+    // Guard recursive calls
+    _GuardedSubtypeChecker<DartType> guardedSubtype = _guard(_isSubtypeOf);
+    _GuardedSubtypeChecker<DartType> guardedInferTypeParameter =
+        _guard(_inferTypeParameterSubtypeOf);
+
+    if (t1 == t2) {
+      return true;
+    }
+
+    // The types are void, dynamic, bottom, interface types, function types
+    // and type parameters.  We proceed by eliminating these different classes
+    // from consideration.
+
+    // Trivially true.
+    if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
+        _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
+      return true;
+    }
+
+    // Trivially false.
+    if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
+        _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
+      return guardedInferTypeParameter(t1, t2, visited);
+    }
+
+    // S <: T where S is a type variable
+    //  T is not dynamic or object (handled above)
+    //  S != T (handled above)
+    //  So only true if bound of S is S' and
+    //  S' <: T
+    if (t1 is TypeParameterType) {
+      if (guardedInferTypeParameter(t1, t2, visited)) {
+        return true;
+      }
+      DartType bound = t1.element.bound;
+      return bound == null ? false : guardedSubtype(bound, t2, visited);
+    }
+
+    if (t2 is TypeParameterType) {
+      return guardedInferTypeParameter(t1, t2, visited);
+    }
+
+    if (t1.isVoid || t2.isVoid) {
+      return false;
+    }
+
+    // We've eliminated void, dynamic, bottom, and type parameters.  The only
+    // cases are the combinations of interface type and function type.
+
+    // A function type can only subtype an interface type if
+    // the interface type is Function
+    if (t1 is FunctionType && t2 is InterfaceType) {
+      return t2.isDartCoreFunction;
+    }
+
+    // An interface type can only subtype a function type if
+    // the interface type declares a call method with a type
+    // which is a super type of the function type.
+    if (t1 is InterfaceType && t2 is FunctionType) {
+      var callType = getCallMethodType(t1);
+      return (callType != null) && _isFunctionSubtypeOf(callType, t2);
+    }
+
+    // Two interface types
+    if (t1 is InterfaceType && t2 is InterfaceType) {
+      return _isInterfaceSubtypeOf(t1, t2, visited);
+    }
+
+    return _isFunctionSubtypeOf(t1 as FunctionType, t2 as FunctionType);
+  }
+
+  // TODO(leafp): Document the rules in play here
+  bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
+    return (t.isDynamic && !dynamicIsBottom) || t.isObject;
+  }
+}
+
+/**
+ * The interface `TypeSystem` defines the behavior of an object representing
+ * the type system.  This provides a common location to put methods that act on
+ * types but may need access to more global data structures, and it paves the
+ * way for a possible future where we may wish to make the type system
+ * pluggable.
+ */
+abstract class TypeSystem {
+  /**
+   * Compute the least upper bound of two types.
+   */
+  DartType getLeastUpperBound(
+      TypeProvider typeProvider, DartType type1, DartType type2);
+
+  /**
+   * Given a [function] type, instantiate it with its bounds.
+   *
+   * The behavior of this method depends on the type system, for example, in
+   * classic Dart `dynamic` will be used for all type arguments, whereas
+   * strong mode prefers the actual bound type if it was specified.
+   */
+  FunctionType instantiateToBounds(FunctionType function);
+
+  /**
+   * Return `true` if the [leftType] is assignable to the [rightType] (that is,
+   * if leftType <==> rightType).
+   */
+  bool isAssignableTo(DartType leftType, DartType rightType);
+
+  /**
+   * Return `true` if the [leftType] is a subtype of the [rightType] (that is,
+   * if leftType <: rightType).
+   */
+  bool isSubtypeOf(DartType leftType, DartType rightType);
+
+  /**
+   * Create either a strong mode or regular type system based on context.
+   */
+  static TypeSystem create(AnalysisContext context) {
+    return (context.analysisOptions.strongMode)
+        ? new StrongTypeSystemImpl()
+        : new TypeSystemImpl();
+  }
+}
+
+/**
+ * Implementation of [TypeSystem] using the rules in the Dart specification.
+ */
+class TypeSystemImpl implements TypeSystem {
+  TypeSystemImpl();
+
+  @override
+  DartType getLeastUpperBound(
+      TypeProvider typeProvider, DartType type1, DartType type2) {
+    // The least upper bound relation is reflexive.
+    if (identical(type1, type2)) {
+      return type1;
+    }
+    // The least upper bound of dynamic and any type T is dynamic.
+    if (type1.isDynamic) {
+      return type1;
+    }
+    if (type2.isDynamic) {
+      return type2;
+    }
+    // The least upper bound of void and any type T != dynamic is void.
+    if (type1.isVoid) {
+      return type1;
+    }
+    if (type2.isVoid) {
+      return type2;
+    }
+    // The least upper bound of bottom and any type T is T.
+    if (type1.isBottom) {
+      return type2;
+    }
+    if (type2.isBottom) {
+      return type1;
+    }
+    // Let U be a type variable with upper bound B.  The least upper bound of U
+    // and a type T is the least upper bound of B and T.
+    while (type1 is TypeParameterType) {
+      // TODO(paulberry): is this correct in the complex of F-bounded
+      // polymorphism?
+      DartType bound = (type1 as TypeParameterType).element.bound;
+      if (bound == null) {
+        bound = typeProvider.objectType;
+      }
+      type1 = bound;
+    }
+    while (type2 is TypeParameterType) {
+      // TODO(paulberry): is this correct in the context of F-bounded
+      // polymorphism?
+      DartType bound = (type2 as TypeParameterType).element.bound;
+      if (bound == null) {
+        bound = typeProvider.objectType;
+      }
+      type2 = bound;
+    }
+    // The least upper bound of a function type and an interface type T is the
+    // least upper bound of Function and T.
+    if (type1 is FunctionType && type2 is InterfaceType) {
+      type1 = typeProvider.functionType;
+    }
+    if (type2 is FunctionType && type1 is InterfaceType) {
+      type2 = typeProvider.functionType;
+    }
+
+    // At this point type1 and type2 should both either be interface types or
+    // function types.
+    if (type1 is InterfaceType && type2 is InterfaceType) {
+      InterfaceType result =
+          InterfaceTypeImpl.computeLeastUpperBound(type1, type2);
+      if (result == null) {
+        return typeProvider.dynamicType;
+      }
+      return result;
+    } else if (type1 is FunctionType && type2 is FunctionType) {
+      FunctionType result =
+          FunctionTypeImpl.computeLeastUpperBound(type1, type2);
+      if (result == null) {
+        return typeProvider.functionType;
+      }
+      return result;
+    } else {
+      // Should never happen.  As a defensive measure, return the dynamic type.
+      assert(false);
+      return typeProvider.dynamicType;
+    }
+  }
+
+  /**
+   * Instantiate the function type using `dynamic` for all generic parameters.
+   */
+  FunctionType instantiateToBounds(FunctionType function) {
+    int count = function.typeFormals.length;
+    if (count == 0) {
+      return function;
+    }
+    return function.instantiate(
+        new List<DartType>.filled(count, DynamicTypeImpl.instance));
+  }
+
+  @override
+  bool isAssignableTo(DartType leftType, DartType rightType) {
+    return leftType.isAssignableTo(rightType);
+  }
+
+  @override
+  bool isSubtypeOf(DartType leftType, DartType rightType) {
+    return leftType.isSubtypeOf(rightType);
+  }
+}
+
+/// Tracks upper and lower type bounds for a set of type parameters.
+class _StrongInferenceTypeSystem extends StrongTypeSystemImpl {
+  final TypeProvider _typeProvider;
+  final Map<TypeParameterType, _TypeParameterBound> _bounds;
+
+  _StrongInferenceTypeSystem(
+      this._typeProvider, Iterable<TypeParameterType> typeParams)
+      : _bounds = new Map.fromIterable(typeParams, value: (t) {
+          _TypeParameterBound bound = new _TypeParameterBound();
+          if (t.element.bound != null) bound.upper = t.element.bound;
+          return bound;
+        });
+
+  @override
+  bool _inferTypeParameterSubtypeOf(
+      DartType t1, DartType t2, Set<Element> visited) {
+    if (t1 is TypeParameterType) {
+      _TypeParameterBound bound = _bounds[t1];
+      if (bound != null) {
+        _GuardedSubtypeChecker<DartType> guardedSubtype = _guard(_isSubtypeOf);
+
+        DartType newUpper = t2;
+        if (guardedSubtype(bound.upper, newUpper, visited)) {
+          // upper bound already covers this. Nothing to do.
+        } else if (guardedSubtype(newUpper, bound.upper, visited)) {
+          // update to the new, more precise upper bound.
+          bound.upper = newUpper;
+        } else {
+          // Failed to find an upper bound. Use bottom to signal no solution.
+          bound.upper = BottomTypeImpl.instance;
+        }
+        // Optimistically assume we will be able to satisfy the constraint.
+        return true;
+      }
+    }
+    if (t2 is TypeParameterType) {
+      _TypeParameterBound bound = _bounds[t2];
+      if (bound != null) {
+        bound.lower = getLeastUpperBound(_typeProvider, bound.lower, t1);
+        // Optimistically assume we will be able to satisfy the constraint.
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/// An [upper] and [lower] bound for a type variable.
+class _TypeParameterBound {
+  /// The upper bound of the type parameter. In other words, T <: upperBound.
+  ///
+  /// In Dart this can be written as `<T extends UpperBoundType>`.
+  ///
+  /// In inference, this can happen as a result of parameters of function type.
+  /// For example, consider a signature like:
+  ///
+  ///     T reduce<T>(List<T> values, T f(T x, T y));
+  ///
+  /// and a call to it like:
+  ///
+  ///     reduce(values, (num x, num y) => ...);
+  ///
+  /// From the function expression's parameters, we conclude `T <: num`. We may
+  /// still be able to conclude a different [lower] based on `values` or
+  /// the type of the elided `=> ...` body. For example:
+  ///
+  ///      reduce(['x'], (num x, num y) => 'hi');
+  ///
+  /// Here the [lower] will be `String` and the upper bound will be `num`,
+  /// which cannot be satisfied, so this is ill typed.
+  DartType upper = DynamicTypeImpl.instance;
+
+  /// The lower bound of the type parameter. In other words, lowerBound <: T.
+  ///
+  /// This kind of constraint cannot be expressed in Dart, but it applies when
+  /// we're doing inference. For example, consider a signature like:
+  ///
+  ///     T pickAtRandom<T>(T x, T y);
+  ///
+  /// and a call to it like:
+  ///
+  ///     pickAtRandom(1, 2.0)
+  ///
+  /// when we see the first parameter is an `int`, we know that `int <: T`.
+  /// When we see `double` this implies `double <: T`.
+  /// Combining these constraints results in a lower bound of `num`.
+  ///
+  /// In general, we choose the lower bound as our inferred type, so we can
+  /// offer the most constrained (strongest) result type.
+  DartType lower = BottomTypeImpl.instance;
+}
+
+/// Records what positions a type parameter is used in.
+class _TypeParameterVariance {
+  /// The type parameter is a value passed out. It must satisfy T <: S,
+  /// where T is the type parameter and S is what it's assigned to.
+  ///
+  /// For example, this could be the return type, or a parameter to a parameter:
+  ///
+  ///     TOut method<TOut>(void f(TOut t));
+  bool passedOut = false;
+
+  /// The type parameter is a value passed in. It must satisfy S <: T,
+  /// where T is the type parameter and S is what's being assigned to it.
+  ///
+  /// For example, this could be a parameter type, or the parameter of the
+  /// return value:
+  ///
+  ///     typedef void Func<T>(T t);
+  ///     Func<TIn> method<TIn>(TIn t);
+  bool passedIn = false;
+
+  _TypeParameterVariance.from(TypeParameterType typeParam, DartType type) {
+    _visitType(typeParam, type, false);
+  }
+
+  void _visitFunctionType(
+      TypeParameterType typeParam, FunctionType type, bool paramIn) {
+    for (ParameterElement p in type.parameters) {
+      // If a lambda L is passed in to a function F, the the parameters are
+      // "passed out" of F into L. Thus we invert the "passedIn" state.
+      _visitType(typeParam, p.type, !paramIn);
+    }
+    // If a lambda L is passed in to a function F, and we call L, the result of
+    // L is then "passed in" to F. So we keep the "passedIn" state.
+    _visitType(typeParam, type.returnType, paramIn);
+  }
+
+  void _visitInterfaceType(
+      TypeParameterType typeParam, InterfaceType type, bool paramIn) {
+    // Currently in "strong mode" generic type parameters are covariant.
+    //
+    // This means we treat them as "out" type parameters similar to the result
+    // of a function, and thus they follow the same rules.
+    //
+    // For example, we pass in Iterable<T> as a parameter. Then we iterate over
+    // it. The "T" is essentially an input. So it keeps the same state.
+    // Similarly, if we return an Iterable<T> it's equivalent to returning a T.
+    for (DartType typeArg in type.typeArguments) {
+      _visitType(typeParam, typeArg, paramIn);
+    }
+  }
+
+  void _visitType(TypeParameterType typeParam, DartType type, bool paramIn) {
+    if (type == typeParam) {
+      if (paramIn) {
+        passedIn = true;
+      } else {
+        passedOut = true;
+      }
+    } else if (type is FunctionType) {
+      _visitFunctionType(typeParam, type, paramIn);
+    } else if (type is InterfaceType) {
+      _visitInterfaceType(typeParam, type, paramIn);
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index 0d2afe8..6a71b97 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -2,13 +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.
 
-library engine.utilities.collection;
+library analyzer.src.generated.utilities_collection;
 
-import "dart:math" as math;
 import 'dart:collection';
+import "dart:math" as math;
 
-import 'java_core.dart';
-import 'scanner.dart' show Token;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/scanner.dart' show Token;
 
 /**
  * The class `BooleanArray` defines methods for operating on integers as if they were arrays
diff --git a/pkg/analyzer/lib/src/generated/utilities_dart.dart b/pkg/analyzer/lib/src/generated/utilities_dart.dart
index 882d182..5fe5e72 100644
--- a/pkg/analyzer/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_dart.dart
@@ -2,9 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.dart;
+library analyzer.src.generated.utilities_dart;
 
-import 'java_core.dart';
+import 'package:analyzer/src/generated/java_core.dart';
 
 /**
  * Check whether [uri1] starts with (or 'is prefixed by') [uri2] by checking
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index d000b54..1adc883 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -2,12 +2,36 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.general;
+library analyzer.src.generated.utilities_general;
 
 import 'dart:collection';
 import 'dart:developer' show UserTag;
 
 /**
+ * Test if the given [value] is `false` or the string "false" (case-insensitive).
+ */
+bool isFalse(Object value) =>
+    value is bool ? !value : toLowerCase(value) == 'false';
+
+/**
+ * Test if the given [value] is `true` or the string "true" (case-insensitive).
+ */
+bool isTrue(Object value) =>
+    value is bool ? value : toLowerCase(value) == 'true';
+
+/**
+ * Safely convert this [value] to lower case, returning `null` if [value] is
+ * null.
+ */
+String toLowerCase(Object value) => value?.toString()?.toLowerCase();
+
+/**
+ * Safely convert this [value] to upper case, returning `null` if [value] is
+ * null.
+ */
+String toUpperCase(Object value) => value?.toString()?.toUpperCase();
+
+/**
  * Jenkins hash function, optimized for small integers.
  * Borrowed from sdk/lib/math/jenkins_smi_hash.dart.
  */
diff --git a/pkg/analyzer/lib/src/generated/visitors.dart b/pkg/analyzer/lib/src/generated/visitors.dart
index 59e644f..46e2a41 100644
--- a/pkg/analyzer/lib/src/generated/visitors.dart
+++ b/pkg/analyzer/lib/src/generated/visitors.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.ast.visitors;
+library analyzer.src.generated.visitors;
 
 import 'package:analyzer/src/generated/ast.dart';
 
@@ -153,6 +153,13 @@
   }
 
   @override
+  T visitConfiguration(Configuration node) {
+    _delegates.forEach((delegate) => delegate.visitConfiguration(node));
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   T visitConstructorDeclaration(ConstructorDeclaration node) {
     _delegates
         .forEach((delegate) => delegate.visitConstructorDeclaration(node));
@@ -205,6 +212,13 @@
   }
 
   @override
+  T visitDottedName(DottedName node) {
+    _delegates.forEach((delegate) => delegate.visitDottedName(node));
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   T visitDoubleLiteral(DoubleLiteral node) {
     _delegates.forEach((delegate) => delegate.visitDoubleLiteral(node));
     node.visitChildren(this);
@@ -291,15 +305,15 @@
   }
 
   @override
-  T visitForStatement(ForStatement node) {
-    _delegates.forEach((delegate) => delegate.visitForStatement(node));
+  T visitFormalParameterList(FormalParameterList node) {
+    _delegates.forEach((delegate) => delegate.visitFormalParameterList(node));
     node.visitChildren(this);
     return null;
   }
 
   @override
-  T visitFormalParameterList(FormalParameterList node) {
-    _delegates.forEach((delegate) => delegate.visitFormalParameterList(node));
+  T visitForStatement(ForStatement node) {
+    _delegates.forEach((delegate) => delegate.visitForStatement(node));
     node.visitChildren(this);
     return null;
   }
@@ -542,15 +556,15 @@
   }
 
   @override
-  T visitPrefixExpression(PrefixExpression node) {
-    _delegates.forEach((delegate) => delegate.visitPrefixExpression(node));
+  T visitPrefixedIdentifier(PrefixedIdentifier node) {
+    _delegates.forEach((delegate) => delegate.visitPrefixedIdentifier(node));
     node.visitChildren(this);
     return null;
   }
 
   @override
-  T visitPrefixedIdentifier(PrefixedIdentifier node) {
-    _delegates.forEach((delegate) => delegate.visitPrefixedIdentifier(node));
+  T visitPrefixExpression(PrefixExpression node) {
+    _delegates.forEach((delegate) => delegate.visitPrefixExpression(node));
     node.visitChildren(this);
     return null;
   }
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index a067dcc..07b0def 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -197,6 +197,8 @@
     registerExtension(
         taskId, ComputeInferableStaticVariableDependenciesTask.DESCRIPTOR);
     registerExtension(taskId, ComputeLibraryCycleTask.DESCRIPTOR);
+    registerExtension(
+        taskId, ComputePropagableVariableDependenciesTask.DESCRIPTOR);
     registerExtension(taskId, ContainingLibrariesTask.DESCRIPTOR);
     registerExtension(taskId, DartErrorsTask.DESCRIPTOR);
     registerExtension(taskId, EvaluateUnitConstantsTask.DESCRIPTOR);
@@ -211,13 +213,20 @@
     registerExtension(taskId, LibraryUnitErrorsTask.DESCRIPTOR);
     registerExtension(taskId, ParseDartTask.DESCRIPTOR);
     registerExtension(taskId, PartiallyResolveUnitReferencesTask.DESCRIPTOR);
+    registerExtension(
+        taskId, PropagateVariableTypesInLibraryClosureTask.DESCRIPTOR);
+    registerExtension(taskId, PropagateVariableTypesInLibraryTask.DESCRIPTOR);
+    registerExtension(taskId, PropagateVariableTypesInUnitTask.DESCRIPTOR);
+    registerExtension(taskId, PropagateVariableTypeTask.DESCRIPTOR);
     registerExtension(taskId, ReadyLibraryElement2Task.DESCRIPTOR);
     registerExtension(taskId, ReadyLibraryElement5Task.DESCRIPTOR);
+    registerExtension(taskId, ReadyLibraryElement6Task.DESCRIPTOR);
     registerExtension(taskId, ReadyResolvedUnitTask.DESCRIPTOR);
-    registerExtension(taskId, ReadyResolvedUnit9Task.DESCRIPTOR);
     registerExtension(taskId, ReadyResolvedUnit10Task.DESCRIPTOR);
+    registerExtension(taskId, ReadyResolvedUnit11Task.DESCRIPTOR);
     registerExtension(taskId, ResolveInstanceFieldsInUnitTask.DESCRIPTOR);
     registerExtension(taskId, ResolveLibraryReferencesTask.DESCRIPTOR);
+    registerExtension(taskId, ResolveLibraryTask.DESCRIPTOR);
     registerExtension(taskId, ResolveLibraryTypeNamesTask.DESCRIPTOR);
     registerExtension(taskId, ResolveUnitTask.DESCRIPTOR);
     registerExtension(taskId, ResolveUnitTypeNamesTask.DESCRIPTOR);
diff --git a/pkg/analyzer/lib/src/plugin/options_plugin.dart b/pkg/analyzer/lib/src/plugin/options_plugin.dart
index 6e0ebd6..6fba649 100644
--- a/pkg/analyzer/lib/src/plugin/options_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/options_plugin.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.src.plugin.options;
+library analyzer.src.plugin.options_plugin;
 
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/plugin/task.dart';
diff --git a/pkg/analyzer/lib/src/plugin/plugin_configuration.dart b/pkg/analyzer/lib/src/plugin/plugin_configuration.dart
index 9365a3c..222e376 100644
--- a/pkg/analyzer/lib/src/plugin/plugin_configuration.dart
+++ b/pkg/analyzer/lib/src/plugin/plugin_configuration.dart
@@ -84,10 +84,11 @@
   PluginConfig(this.plugins);
 
   /// Create a plugin configuration from an options map.
-  factory PluginConfig.fromOptions(Map<String, YamlNode> options) {
+  factory PluginConfig.fromOptions(Map<String, Object> options) {
     List<PluginInfo> plugins = [];
     var analyzerOptions = options[_analyzerOptionScope];
     if (analyzerOptions != null) {
+      //TODO(pq): handle "raw" maps (https://github.com/dart-lang/sdk/issues/25126)
       if (analyzerOptions is YamlMap) {
         var pluginConfig = analyzerOptions[_pluginOptionScope];
         if (pluginConfig is YamlMap) {
@@ -143,7 +144,7 @@
 
   @override
   void optionsProcessed(
-      AnalysisContext context, Map<String, YamlNode> options) {
+      AnalysisContext context, Map<String, Object> options) {
     _config = new PluginConfig.fromOptions(options);
   }
 }
diff --git a/pkg/analyzer/lib/src/services/lint.dart b/pkg/analyzer/lib/src/services/lint.dart
index a6b55cc..91d72a2 100644
--- a/pkg/analyzer/lib/src/services/lint.dart
+++ b/pkg/analyzer/lib/src/services/lint.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library lint;
+library analyzer.src.services.lint;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/lib/src/string_source.dart b/pkg/analyzer/lib/src/string_source.dart
index 5ffb332..0c99e69 100644
--- a/pkg/analyzer/lib/src/string_source.dart
+++ b/pkg/analyzer/lib/src/string_source.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.string_source;
+library analyzer.src.string_source;
 
-import 'generated/engine.dart' show TimestampedData;
-import 'generated/source.dart';
+import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
+import 'package:analyzer/src/generated/source.dart';
 
 /// An implementation of [Source] that's based on an in-memory Dart string.
 class StringSource extends Source {
diff --git a/pkg/analyzer/lib/src/summary/base.dart b/pkg/analyzer/lib/src/summary/base.dart
new file mode 100644
index 0000000..a04476b
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/base.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Base functionality which code generated summary classes are built upon.
+ */
+library analyzer.src.summary.base;
+
+/**
+ * Instances of this class represent data that has been read from a summary.
+ */
+abstract class SummaryClass {
+  /**
+   * Translate the data in this class into a map whose keys are the names of
+   * fields and whose values are the data stored in those fields.
+   *
+   * Intended for testing and debugging only.
+   */
+  Map<String, Object> toMap();
+}
diff --git a/pkg/analyzer/lib/src/summary/flat_buffers.dart b/pkg/analyzer/lib/src/summary/flat_buffers.dart
new file mode 100644
index 0000000..3c7de13
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/flat_buffers.dart
@@ -0,0 +1,631 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.summary.flat_buffers;
+
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:math';
+import 'dart:typed_data';
+
+/**
+ * The reader of booleans.
+ */
+class BoolReader extends Reader<bool> {
+  const BoolReader() : super();
+
+  @override
+  int get size => 1;
+
+  @override
+  bool read(BufferPointer bp) => bp._getInt8() != 0;
+}
+
+/**
+ * A pointer to some data.
+ */
+class BufferPointer {
+  final ByteData _buffer;
+  final int _offset;
+
+  factory BufferPointer.fromBytes(List<int> byteList, [int offset = 0]) {
+    Uint8List uint8List = _asUint8List(byteList);
+    ByteData buf = new ByteData.view(uint8List.buffer);
+    return new BufferPointer._(buf, uint8List.offsetInBytes + offset);
+  }
+
+  BufferPointer._(this._buffer, this._offset);
+
+  BufferPointer derefObject() {
+    int uOffset = _getUint32();
+    return _advance(uOffset);
+  }
+
+  @override
+  String toString() => _offset.toString();
+
+  BufferPointer _advance(int delta) {
+    return new BufferPointer._(_buffer, _offset + delta);
+  }
+
+  int _getInt32([int delta = 0]) =>
+      _buffer.getInt32(_offset + delta, Endianness.LITTLE_ENDIAN);
+
+  int _getInt8([int delta = 0]) => _buffer.getInt8(_offset + delta);
+
+  int _getUint16([int delta = 0]) =>
+      _buffer.getUint16(_offset + delta, Endianness.LITTLE_ENDIAN);
+
+  int _getUint32([int delta = 0]) =>
+      _buffer.getUint32(_offset + delta, Endianness.LITTLE_ENDIAN);
+
+  /**
+   * If the [byteList] is already a [Uint8List] return it.
+   * Otherwise return a [Uint8List] copy of the [byteList].
+   */
+  static Uint8List _asUint8List(List<int> byteList) {
+    if (byteList is Uint8List) {
+      return byteList;
+    } else {
+      return new Uint8List.fromList(byteList);
+    }
+  }
+}
+
+/**
+ * Class that helps building flat buffers.
+ */
+class Builder {
+  final int initialSize;
+
+  /**
+   * The list of existing VTable(s).
+   */
+  final List<_VTable> _vTables = <_VTable>[];
+
+  ByteData _buf;
+
+  /**
+   * The maximum alignment that has been seen so far.  If [_buf] has to be
+   * reallocated in the future (to insert room at its start for more bytes) the
+   * reallocation will need to be a multiple of this many bytes.
+   */
+  int _maxAlign;
+
+  /**
+   * The number of bytes that have been written to the buffer so far.  The
+   * most recently written byte is this many bytes from the end of [_buf].
+   */
+  int _tail;
+
+  /**
+   * The location of the end of the current table, measured in bytes from the
+   * end of [_buf], or `null` if a table is not currently being built.
+   */
+  int _currentTableEndTail;
+
+  _VTable _currentVTable;
+
+  Builder({this.initialSize: 1024}) {
+    reset();
+  }
+
+  /**
+   * Add the [field] with the given boolean [value].  The field is not added if
+   * the [value] is equal to [def].  Booleans are stored as 8-bit fields with
+   * `0` for `false` and `1` for `true`.
+   */
+  void addBool(int field, bool value, [bool def]) {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+    if (value != null && value != def) {
+      int size = 1;
+      _prepare(size, 1);
+      _trackField(field);
+      _buf.setInt8(_buf.lengthInBytes - _tail, value ? 1 : 0);
+    }
+  }
+
+  /**
+   * Add the [field] with the given 32-bit signed integer [value].  The field is
+   * not added if the [value] is equal to [def].
+   */
+  void addInt32(int field, int value, [int def]) {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+    if (value != null && value != def) {
+      int size = 4;
+      _prepare(size, 1);
+      _trackField(field);
+      _setInt32AtTail(_buf, _tail, value);
+    }
+  }
+
+  /**
+   * Add the [field] with the given 8-bit signed integer [value].  The field is
+   * not added if the [value] is equal to [def].
+   */
+  void addInt8(int field, int value, [int def]) {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+    if (value != null && value != def) {
+      int size = 1;
+      _prepare(size, 1);
+      _trackField(field);
+      _buf.setInt8(_buf.lengthInBytes - _tail, value);
+    }
+  }
+
+  /**
+   * Add the [field] referencing an object with the given [offset].
+   */
+  void addOffset(int field, Offset offset) {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+    if (offset != null) {
+      _prepare(4, 1);
+      _trackField(field);
+      _setUint32AtTail(_buf, _tail, _tail - offset._tail);
+    }
+  }
+
+  /**
+   * End the current table and return its offset.
+   */
+  Offset endTable() {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before ending it.');
+    }
+    // Prepare the size of the current table.
+    _currentVTable.tableSize = _tail - _currentTableEndTail;
+    // Prepare for writing the VTable.
+    _prepare(4, 1);
+    int tableTail = _tail;
+    // Prepare the VTable to use for the current table.
+    int vTableTail;
+    {
+      _currentVTable.computeFieldOffsets(tableTail);
+      // Try to find an existing compatible VTable.
+      for (_VTable vTable in _vTables) {
+        if (_currentVTable.canUseExistingVTable(vTable)) {
+          vTableTail = vTable.tail;
+        }
+      }
+      // Write a new VTable.
+      if (vTableTail == null) {
+        _prepare(2, _currentVTable.numOfUint16);
+        vTableTail = _tail;
+        _currentVTable.tail = vTableTail;
+        _currentVTable.output(_buf, _buf.lengthInBytes - _tail);
+        _vTables.add(_currentVTable);
+      }
+    }
+    // Set the VTable offset.
+    _setInt32AtTail(_buf, tableTail, vTableTail - tableTail);
+    // Done with this table.
+    _currentVTable = null;
+    return new Offset(tableTail);
+  }
+
+  /**
+   * Finish off the creation of the buffer.  The given [offset] is used as the
+   * root object offset, and usually references directly or indirectly every
+   * written object.
+   */
+  Uint8List finish(Offset offset) {
+    _prepare(max(4, _maxAlign), 1);
+    int alignedTail = _tail + ((-_tail) % _maxAlign);
+    _setUint32AtTail(_buf, alignedTail, alignedTail - offset._tail);
+    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
+  }
+
+  /**
+   * This is a low-level method, it should not be invoked by clients.
+   */
+  Uint8List lowFinish() {
+    int alignedTail = _tail + ((-_tail) % _maxAlign);
+    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
+  }
+
+  /**
+   * This is a low-level method, it should not be invoked by clients.
+   */
+  void lowReset() {
+    _buf = new ByteData(initialSize);
+    _maxAlign = 1;
+    _tail = 0;
+  }
+
+  /**
+   * This is a low-level method, it should not be invoked by clients.
+   */
+  void lowWriteUint32(int value) {
+    _prepare(4, 1);
+    _setUint32AtTail(_buf, _tail, value);
+  }
+
+  /**
+   * This is a low-level method, it should not be invoked by clients.
+   */
+  void lowWriteUint8(int value) {
+    _prepare(1, 1);
+    _buf.setUint8(_buf.lengthInBytes - _tail, value);
+  }
+
+  /**
+   * Reset the builder and make it ready for filling a new buffer.
+   */
+  void reset() {
+    _buf = new ByteData(initialSize);
+    _maxAlign = 1;
+    _tail = 0;
+    _currentVTable = null;
+  }
+
+  /**
+   * Start a new table.  Must be finished with [endTable] invocation.
+   */
+  void startTable() {
+    if (_currentVTable != null) {
+      throw new StateError('Inline tables are not supported.');
+    }
+    _currentVTable = new _VTable();
+    _currentTableEndTail = _tail;
+  }
+
+  /**
+   * Write the given list of [values].
+   */
+  Offset writeList(List<Offset> values) {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+    _prepare(4, 1 + values.length);
+    Offset result = new Offset(_tail);
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= 4;
+    for (Offset value in values) {
+      _setUint32AtTail(_buf, tail, tail - value._tail);
+      tail -= 4;
+    }
+    return result;
+  }
+
+  /**
+   * Write the given list of signed 32-bit integer [values].
+   */
+  Offset writeListInt32(List<int> values) {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+    _prepare(4, 1 + values.length);
+    Offset result = new Offset(_tail);
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= 4;
+    for (int value in values) {
+      _setInt32AtTail(_buf, tail, value);
+      tail -= 4;
+    }
+    return result;
+  }
+
+  /**
+   * Write the given string [value] and return its [Offset], or `null` if
+   * the [value] is equal to [def].
+   */
+  Offset<String> writeString(String value, [String def]) {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+    if (value != def) {
+      // TODO(scheglov) optimize for ASCII strings
+      List<int> bytes = UTF8.encode(value);
+      int length = bytes.length;
+      _prepare(4, 1, additionalBytes: length);
+      Offset<String> result = new Offset(_tail);
+      _setUint32AtTail(_buf, _tail, length);
+      int offset = _buf.lengthInBytes - _tail + 4;
+      for (int i = 0; i < length; i++) {
+        _buf.setUint8(offset++, bytes[i]);
+      }
+      return result;
+    }
+    return null;
+  }
+
+  /**
+   * Prepare for writing the given [count] of scalars of the given [size].
+   * Additionally allocate the specified [additionalBytes]. Update the current
+   * tail pointer to point at the allocated space.
+   */
+  void _prepare(int size, int count, {int additionalBytes: 0}) {
+    // Update the alignment.
+    if (_maxAlign < size) {
+      _maxAlign = size;
+    }
+    // Prepare amount of required space.
+    int dataSize = size * count + additionalBytes;
+    int alignDelta = (-(_tail + dataSize)) % size;
+    int bufSize = alignDelta + dataSize;
+    // Ensure that we have the required amount of space.
+    {
+      int oldCapacity = _buf.lengthInBytes;
+      if (_tail + bufSize > oldCapacity) {
+        int desiredNewCapacity = (oldCapacity + bufSize) * 2;
+        int deltaCapacity = desiredNewCapacity - oldCapacity;
+        deltaCapacity += (-deltaCapacity) % _maxAlign;
+        int newCapacity = oldCapacity + deltaCapacity;
+        ByteData newBuf = new ByteData(newCapacity);
+        newBuf.buffer
+            .asUint8List()
+            .setAll(deltaCapacity, _buf.buffer.asUint8List());
+        _buf = newBuf;
+      }
+    }
+    // Update the tail pointer.
+    _tail += bufSize;
+  }
+
+  /**
+   * Record the offset of the given [field].
+   */
+  void _trackField(int field) {
+    _currentVTable.addField(field, _tail);
+  }
+
+  static void _setInt32AtTail(ByteData _buf, int tail, int x) {
+    _buf.setInt32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+  }
+
+  static void _setUint32AtTail(ByteData _buf, int tail, int x) {
+    _buf.setUint32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+  }
+}
+
+/**
+ * The reader of 32-bit signed integers.
+ */
+class Int32Reader extends Reader<int> {
+  const Int32Reader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  int read(BufferPointer bp) => bp._getInt32();
+}
+
+/**
+ * The reader of 8-bit signed integers.
+ */
+class Int8Reader extends Reader<int> {
+  const Int8Reader() : super();
+
+  @override
+  int get size => 1;
+
+  @override
+  int read(BufferPointer bp) => bp._getInt8();
+}
+
+/**
+ * The reader of lists of objects.
+ *
+ * The returned unmodifiable lists lazily read objects on access.
+ */
+class ListReader<E> extends Reader<List<E>> {
+  final Reader<E> _elementReader;
+
+  const ListReader(this._elementReader);
+
+  @override
+  int get size => 4;
+
+  @override
+  List<E> read(BufferPointer bp) =>
+      new _FbList<E>(_elementReader, bp.derefObject());
+}
+
+/**
+ * The offset from the end of the buffer to a serialized object of the type [T].
+ */
+class Offset<T> {
+  final int _tail;
+
+  Offset(this._tail);
+}
+
+/**
+ * Object that can read a value at a [BufferPointer].
+ */
+abstract class Reader<T> {
+  const Reader();
+
+  /**
+   * The size of the value in bytes.
+   */
+  int get size;
+
+  /**
+   * Read the value at the given pointer.
+   */
+  T read(BufferPointer bp);
+
+  /**
+   * Read the value of the given [field] in the given [object].
+   */
+  T vTableGet(BufferPointer object, int field, [T defaultValue]) {
+    int vTableSOffset = object._getInt32();
+    BufferPointer vTable = object._advance(-vTableSOffset);
+    int vTableSize = vTable._getUint16();
+    int vTableFieldOffset = (1 + 1 + field) * 2;
+    if (vTableFieldOffset < vTableSize) {
+      int fieldOffsetInObject = vTable._getUint16(vTableFieldOffset);
+      if (fieldOffsetInObject != 0) {
+        BufferPointer fieldPointer = object._advance(fieldOffsetInObject);
+        return read(fieldPointer);
+      }
+    }
+    return defaultValue;
+  }
+}
+
+/**
+ * The reader of string values.
+ */
+class StringReader extends Reader<String> {
+  const StringReader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  String read(BufferPointer ref) {
+    BufferPointer object = ref.derefObject();
+    int length = object._getUint32();
+    return UTF8
+        .decode(ref._buffer.buffer.asUint8List(object._offset + 4, length));
+  }
+}
+
+/**
+ * An abstract reader for tables.
+ */
+abstract class TableReader<T> extends Reader<T> {
+  const TableReader();
+
+  @override
+  int get size => 4;
+
+  /**
+   * Return the object at [bp].
+   */
+  T createObject(BufferPointer bp);
+
+  @override
+  T read(BufferPointer bp) {
+    bp = bp.derefObject();
+    return createObject(bp);
+  }
+}
+
+class _FbList<E> extends Object with ListMixin<E> implements List<E> {
+  final Reader<E> elementReader;
+  final BufferPointer bp;
+
+  int _length;
+  List<E> _items;
+
+  _FbList(this.elementReader, this.bp);
+
+  @override
+  int get length {
+    _length ??= bp._getUint32();
+    return _length;
+  }
+
+  @override
+  void set length(int i) =>
+      throw new StateError('Attempt to modify immutable list');
+
+  @override
+  E operator [](int i) {
+    _items ??= new List<E>(length);
+    E item = _items[i];
+    if (item == null) {
+      BufferPointer ref = bp._advance(4 + elementReader.size * i);
+      item = elementReader.read(ref);
+      _items[i] = item;
+    }
+    return item;
+  }
+
+  @override
+  void operator []=(int i, E e) =>
+      throw new StateError('Attempt to modify immutable list');
+}
+
+/**
+ * Class that describes the structure of a table.
+ */
+class _VTable {
+  final List<int> fieldTails = <int>[];
+  final List<int> fieldOffsets = <int>[];
+
+  /**
+   * The size of the table that uses this VTable.
+   */
+  int tableSize;
+
+  /**
+   * The tail of this VTable.  It is used to share the same VTable between
+   * multiple tables of identical structure.
+   */
+  int tail;
+
+  int get numOfUint16 => 1 + 1 + fieldTails.length;
+
+  void addField(int field, int offset) {
+    while (fieldTails.length <= field) {
+      fieldTails.add(null);
+    }
+    fieldTails[field] = offset;
+  }
+
+  /**
+   * Return `true` if the [existing] VTable can be used instead of this.
+   */
+  bool canUseExistingVTable(_VTable existing) {
+    assert(tail == null);
+    assert(existing.tail != null);
+    if (tableSize == existing.tableSize &&
+        fieldOffsets.length == existing.fieldOffsets.length) {
+      for (int i = 0; i < fieldOffsets.length; i++) {
+        if (fieldOffsets[i] != existing.fieldOffsets[i]) {
+          return false;
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Fill the [fieldOffsets] field.
+   */
+  void computeFieldOffsets(int tableTail) {
+    assert(fieldOffsets.isEmpty);
+    for (int fieldTail in fieldTails) {
+      int fieldOffset = fieldTail == null ? 0 : tableTail - fieldTail;
+      fieldOffsets.add(fieldOffset);
+    }
+  }
+
+  /**
+   * Outputs this VTable to [buf], which is is expected to be aligned to 16-bit
+   * and have at least [numOfUint16] 16-bit words available.
+   */
+  void output(ByteData buf, int bufOffset) {
+    // VTable size.
+    buf.setUint16(bufOffset, numOfUint16 * 2, Endianness.LITTLE_ENDIAN);
+    bufOffset += 2;
+    // Table size.
+    buf.setUint16(bufOffset, tableSize, Endianness.LITTLE_ENDIAN);
+    bufOffset += 2;
+    // Field offsets.
+    for (int fieldOffset in fieldOffsets) {
+      buf.setUint16(bufOffset, fieldOffset, Endianness.LITTLE_ENDIAN);
+      bufOffset += 2;
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
new file mode 100644
index 0000000..97f9db6
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -0,0 +1,4672 @@
+// 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 file has been automatically generated.  Please do not edit it manually.
+// To regenerate the file, use the script "pkg/analyzer/tool/generate_files".
+
+library analyzer.src.summary.format;
+
+import 'base.dart' as base;
+import 'flat_buffers.dart' as fb;
+
+/**
+ * Enum used to indicate the kind of entity referred to by a
+ * [PrelinkedReference].
+ */
+enum PrelinkedReferenceKind {
+  classOrEnum,
+  typedef,
+  other,
+  prefix,
+  unresolved,
+}
+
+/**
+ * Enum used to indicate the kind of an executable.
+ */
+enum UnlinkedExecutableKind {
+  functionOrMethod,
+  getter,
+  setter,
+  constructor,
+}
+
+/**
+ * Enum used to indicate the kind of a parameter.
+ */
+enum UnlinkedParamKind {
+  required,
+  positional,
+  named,
+}
+
+class PrelinkedDependencyBuilder {
+  bool _finished = false;
+
+  String _uri;
+  List<String> _parts;
+
+  PrelinkedDependencyBuilder();
+
+  /**
+   * The relative URI of the dependent library.  This URI is relative to the
+   * importing library, even if there are intervening `export` declarations.
+   * So, for example, if `a.dart` imports `b/c.dart` and `b/c.dart` exports
+   * `d/e.dart`, the URI listed for `a.dart`'s dependency on `e.dart` will be
+   * `b/d/e.dart`.
+   */
+  void set uri(String _value) {
+    assert(!_finished);
+    _uri = _value;
+  }
+
+  /**
+   * URI for the compilation units listed in the library's `part` declarations.
+   * These URIs are relative to the importing library.
+   */
+  void set parts(List<String> _value) {
+    assert(!_finished);
+    _parts = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_uri;
+    fb.Offset offset_parts;
+    if (_uri != null) {
+      offset_uri = fbBuilder.writeString(_uri);
+    }
+    if (!(_parts == null || _parts.isEmpty)) {
+      offset_parts = fbBuilder.writeList(_parts.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_uri != null) {
+      fbBuilder.addOffset(0, offset_uri);
+    }
+    if (offset_parts != null) {
+      fbBuilder.addOffset(1, offset_parts);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+PrelinkedDependencyBuilder encodePrelinkedDependency({String uri, List<String> parts}) {
+  PrelinkedDependencyBuilder builder = new PrelinkedDependencyBuilder();
+  builder.uri = uri;
+  builder.parts = parts;
+  return builder;
+}
+
+/**
+ * Information about a dependency that exists between one library and another
+ * due to an "import" declaration.
+ */
+abstract class PrelinkedDependency extends base.SummaryClass {
+
+  /**
+   * The relative URI of the dependent library.  This URI is relative to the
+   * importing library, even if there are intervening `export` declarations.
+   * So, for example, if `a.dart` imports `b/c.dart` and `b/c.dart` exports
+   * `d/e.dart`, the URI listed for `a.dart`'s dependency on `e.dart` will be
+   * `b/d/e.dart`.
+   */
+  String get uri;
+
+  /**
+   * URI for the compilation units listed in the library's `part` declarations.
+   * These URIs are relative to the importing library.
+   */
+  List<String> get parts;
+}
+
+class _PrelinkedDependencyReader extends fb.TableReader<_PrelinkedDependencyImpl> {
+  const _PrelinkedDependencyReader();
+
+  @override
+  _PrelinkedDependencyImpl createObject(fb.BufferPointer bp) => new _PrelinkedDependencyImpl(bp);
+}
+
+class _PrelinkedDependencyImpl implements PrelinkedDependency {
+  final fb.BufferPointer _bp;
+
+  _PrelinkedDependencyImpl(this._bp);
+
+  String _uri;
+  List<String> _parts;
+
+  @override
+  Map<String, Object> toMap() => {
+    "uri": uri,
+    "parts": parts,
+  };
+
+  @override
+  String get uri {
+    _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _uri;
+  }
+
+  @override
+  List<String> get parts {
+    _parts ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
+    return _parts;
+  }
+}
+
+class PrelinkedLibraryBuilder {
+  bool _finished = false;
+
+  List<PrelinkedUnitBuilder> _units;
+  List<PrelinkedDependencyBuilder> _dependencies;
+  List<int> _importDependencies;
+
+  PrelinkedLibraryBuilder();
+
+  /**
+   * The pre-linked summary of all the compilation units constituting the
+   * library.  The summary of the defining compilation unit is listed first,
+   * followed by the summary of each part, in the order of the `part`
+   * declarations in the defining compilation unit.
+   */
+  void set units(List<PrelinkedUnitBuilder> _value) {
+    assert(!_finished);
+    _units = _value;
+  }
+
+  /**
+   * The libraries that this library depends on (either via an explicit import
+   * statement or via the implicit dependencies on `dart:core` and
+   * `dart:async`).  The first element of this array is a pseudo-dependency
+   * representing the library itself (it is also used for "dynamic").
+   *
+   * TODO(paulberry): consider removing this entirely and just using
+   * [UnlinkedLibrary.imports].
+   */
+  void set dependencies(List<PrelinkedDependencyBuilder> _value) {
+    assert(!_finished);
+    _dependencies = _value;
+  }
+
+  /**
+   * For each import in [UnlinkedUnit.imports], an index into [dependencies]
+   * of the library being imported.
+   *
+   * TODO(paulberry): if [dependencies] is removed, this can be removed as
+   * well, since there will effectively be a one-to-one mapping.
+   */
+  void set importDependencies(List<int> _value) {
+    assert(!_finished);
+    _importDependencies = _value;
+  }
+
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = new fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder));
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_units;
+    fb.Offset offset_dependencies;
+    fb.Offset offset_importDependencies;
+    if (!(_units == null || _units.isEmpty)) {
+      offset_units = fbBuilder.writeList(_units.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_dependencies == null || _dependencies.isEmpty)) {
+      offset_dependencies = fbBuilder.writeList(_dependencies.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_importDependencies == null || _importDependencies.isEmpty)) {
+      offset_importDependencies = fbBuilder.writeListInt32(_importDependencies);
+    }
+    fbBuilder.startTable();
+    if (offset_units != null) {
+      fbBuilder.addOffset(0, offset_units);
+    }
+    if (offset_dependencies != null) {
+      fbBuilder.addOffset(1, offset_dependencies);
+    }
+    if (offset_importDependencies != null) {
+      fbBuilder.addOffset(2, offset_importDependencies);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+PrelinkedLibraryBuilder encodePrelinkedLibrary({List<PrelinkedUnitBuilder> units, List<PrelinkedDependencyBuilder> dependencies, List<int> importDependencies}) {
+  PrelinkedLibraryBuilder builder = new PrelinkedLibraryBuilder();
+  builder.units = units;
+  builder.dependencies = dependencies;
+  builder.importDependencies = importDependencies;
+  return builder;
+}
+
+/**
+ * Pre-linked summary of a library.
+ */
+abstract class PrelinkedLibrary extends base.SummaryClass {
+  factory PrelinkedLibrary.fromBuffer(List<int> buffer) {
+    fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
+    return const _PrelinkedLibraryReader().read(rootRef);
+  }
+
+  /**
+   * The pre-linked summary of all the compilation units constituting the
+   * library.  The summary of the defining compilation unit is listed first,
+   * followed by the summary of each part, in the order of the `part`
+   * declarations in the defining compilation unit.
+   */
+  List<PrelinkedUnit> get units;
+
+  /**
+   * The libraries that this library depends on (either via an explicit import
+   * statement or via the implicit dependencies on `dart:core` and
+   * `dart:async`).  The first element of this array is a pseudo-dependency
+   * representing the library itself (it is also used for "dynamic").
+   *
+   * TODO(paulberry): consider removing this entirely and just using
+   * [UnlinkedLibrary.imports].
+   */
+  List<PrelinkedDependency> get dependencies;
+
+  /**
+   * For each import in [UnlinkedUnit.imports], an index into [dependencies]
+   * of the library being imported.
+   *
+   * TODO(paulberry): if [dependencies] is removed, this can be removed as
+   * well, since there will effectively be a one-to-one mapping.
+   */
+  List<int> get importDependencies;
+}
+
+class _PrelinkedLibraryReader extends fb.TableReader<_PrelinkedLibraryImpl> {
+  const _PrelinkedLibraryReader();
+
+  @override
+  _PrelinkedLibraryImpl createObject(fb.BufferPointer bp) => new _PrelinkedLibraryImpl(bp);
+}
+
+class _PrelinkedLibraryImpl implements PrelinkedLibrary {
+  final fb.BufferPointer _bp;
+
+  _PrelinkedLibraryImpl(this._bp);
+
+  List<PrelinkedUnit> _units;
+  List<PrelinkedDependency> _dependencies;
+  List<int> _importDependencies;
+
+  @override
+  Map<String, Object> toMap() => {
+    "units": units,
+    "dependencies": dependencies,
+    "importDependencies": importDependencies,
+  };
+
+  @override
+  List<PrelinkedUnit> get units {
+    _units ??= const fb.ListReader<PrelinkedUnit>(const _PrelinkedUnitReader()).vTableGet(_bp, 0, const <PrelinkedUnit>[]);
+    return _units;
+  }
+
+  @override
+  List<PrelinkedDependency> get dependencies {
+    _dependencies ??= const fb.ListReader<PrelinkedDependency>(const _PrelinkedDependencyReader()).vTableGet(_bp, 1, const <PrelinkedDependency>[]);
+    return _dependencies;
+  }
+
+  @override
+  List<int> get importDependencies {
+    _importDependencies ??= const fb.ListReader<int>(const fb.Int32Reader()).vTableGet(_bp, 2, const <int>[]);
+    return _importDependencies;
+  }
+}
+
+class PrelinkedReferenceBuilder {
+  bool _finished = false;
+
+  int _dependency;
+  PrelinkedReferenceKind _kind;
+  int _unit;
+  int _numTypeParameters;
+
+  PrelinkedReferenceBuilder();
+
+  /**
+   * Index into [PrelinkedLibrary.dependencies] indicating which imported library
+   * declares the entity being referred to.
+   */
+  void set dependency(int _value) {
+    assert(!_finished);
+    _dependency = _value;
+  }
+
+  /**
+   * The kind of the entity being referred to.  For the pseudo-type `dynamic`,
+   * the kind is [PrelinkedReferenceKind.classOrEnum].
+   */
+  void set kind(PrelinkedReferenceKind _value) {
+    assert(!_finished);
+    _kind = _value;
+  }
+
+  /**
+   * Integer index indicating which unit in the imported library contains the
+   * definition of the entity.  As with indices into [PrelinkedLibrary.units],
+   * zero represents the defining compilation unit, and nonzero values
+   * represent parts in the order of the corresponding `part` declarations.
+   */
+  void set unit(int _value) {
+    assert(!_finished);
+    _unit = _value;
+  }
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  void set numTypeParameters(int _value) {
+    assert(!_finished);
+    _numTypeParameters = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fbBuilder.startTable();
+    if (_dependency != null && _dependency != 0) {
+      fbBuilder.addInt32(0, _dependency);
+    }
+    if (_kind != null && _kind != PrelinkedReferenceKind.classOrEnum) {
+      fbBuilder.addInt32(1, _kind.index);
+    }
+    if (_unit != null && _unit != 0) {
+      fbBuilder.addInt32(2, _unit);
+    }
+    if (_numTypeParameters != null && _numTypeParameters != 0) {
+      fbBuilder.addInt32(3, _numTypeParameters);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+PrelinkedReferenceBuilder encodePrelinkedReference({int dependency, PrelinkedReferenceKind kind, int unit, int numTypeParameters}) {
+  PrelinkedReferenceBuilder builder = new PrelinkedReferenceBuilder();
+  builder.dependency = dependency;
+  builder.kind = kind;
+  builder.unit = unit;
+  builder.numTypeParameters = numTypeParameters;
+  return builder;
+}
+
+/**
+ * Information about the resolution of an [UnlinkedReference].
+ */
+abstract class PrelinkedReference extends base.SummaryClass {
+
+  /**
+   * Index into [PrelinkedLibrary.dependencies] indicating which imported library
+   * declares the entity being referred to.
+   */
+  int get dependency;
+
+  /**
+   * The kind of the entity being referred to.  For the pseudo-type `dynamic`,
+   * the kind is [PrelinkedReferenceKind.classOrEnum].
+   */
+  PrelinkedReferenceKind get kind;
+
+  /**
+   * Integer index indicating which unit in the imported library contains the
+   * definition of the entity.  As with indices into [PrelinkedLibrary.units],
+   * zero represents the defining compilation unit, and nonzero values
+   * represent parts in the order of the corresponding `part` declarations.
+   */
+  int get unit;
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  int get numTypeParameters;
+}
+
+class _PrelinkedReferenceReader extends fb.TableReader<_PrelinkedReferenceImpl> {
+  const _PrelinkedReferenceReader();
+
+  @override
+  _PrelinkedReferenceImpl createObject(fb.BufferPointer bp) => new _PrelinkedReferenceImpl(bp);
+}
+
+class _PrelinkedReferenceImpl implements PrelinkedReference {
+  final fb.BufferPointer _bp;
+
+  _PrelinkedReferenceImpl(this._bp);
+
+  int _dependency;
+  PrelinkedReferenceKind _kind;
+  int _unit;
+  int _numTypeParameters;
+
+  @override
+  Map<String, Object> toMap() => {
+    "dependency": dependency,
+    "kind": kind,
+    "unit": unit,
+    "numTypeParameters": numTypeParameters,
+  };
+
+  @override
+  int get dependency {
+    _dependency ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    return _dependency;
+  }
+
+  @override
+  PrelinkedReferenceKind get kind {
+    _kind ??= PrelinkedReferenceKind.values[const fb.Int32Reader().vTableGet(_bp, 1, 0)];
+    return _kind;
+  }
+
+  @override
+  int get unit {
+    _unit ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _unit;
+  }
+
+  @override
+  int get numTypeParameters {
+    _numTypeParameters ??= const fb.Int32Reader().vTableGet(_bp, 3, 0);
+    return _numTypeParameters;
+  }
+}
+
+class PrelinkedUnitBuilder {
+  bool _finished = false;
+
+  List<PrelinkedReferenceBuilder> _references;
+
+  PrelinkedUnitBuilder();
+
+  /**
+   * For each reference in [UnlinkedUnit.references], information about how
+   * that reference is resolved.
+   */
+  void set references(List<PrelinkedReferenceBuilder> _value) {
+    assert(!_finished);
+    _references = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_references;
+    if (!(_references == null || _references.isEmpty)) {
+      offset_references = fbBuilder.writeList(_references.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_references != null) {
+      fbBuilder.addOffset(0, offset_references);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+PrelinkedUnitBuilder encodePrelinkedUnit({List<PrelinkedReferenceBuilder> references}) {
+  PrelinkedUnitBuilder builder = new PrelinkedUnitBuilder();
+  builder.references = references;
+  return builder;
+}
+
+/**
+ * Pre-linked summary of a compilation unit.
+ */
+abstract class PrelinkedUnit extends base.SummaryClass {
+
+  /**
+   * For each reference in [UnlinkedUnit.references], information about how
+   * that reference is resolved.
+   */
+  List<PrelinkedReference> get references;
+}
+
+class _PrelinkedUnitReader extends fb.TableReader<_PrelinkedUnitImpl> {
+  const _PrelinkedUnitReader();
+
+  @override
+  _PrelinkedUnitImpl createObject(fb.BufferPointer bp) => new _PrelinkedUnitImpl(bp);
+}
+
+class _PrelinkedUnitImpl implements PrelinkedUnit {
+  final fb.BufferPointer _bp;
+
+  _PrelinkedUnitImpl(this._bp);
+
+  List<PrelinkedReference> _references;
+
+  @override
+  Map<String, Object> toMap() => {
+    "references": references,
+  };
+
+  @override
+  List<PrelinkedReference> get references {
+    _references ??= const fb.ListReader<PrelinkedReference>(const _PrelinkedReferenceReader()).vTableGet(_bp, 0, const <PrelinkedReference>[]);
+    return _references;
+  }
+}
+
+class SdkBundleBuilder {
+  bool _finished = false;
+
+  List<String> _prelinkedLibraryUris;
+  List<PrelinkedLibraryBuilder> _prelinkedLibraries;
+  List<String> _unlinkedUnitUris;
+  List<UnlinkedUnitBuilder> _unlinkedUnits;
+
+  SdkBundleBuilder();
+
+  /**
+   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
+   */
+  void set prelinkedLibraryUris(List<String> _value) {
+    assert(!_finished);
+    _prelinkedLibraryUris = _value;
+  }
+
+  /**
+   * Pre-linked libraries.
+   */
+  void set prelinkedLibraries(List<PrelinkedLibraryBuilder> _value) {
+    assert(!_finished);
+    _prelinkedLibraries = _value;
+  }
+
+  /**
+   * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
+   */
+  void set unlinkedUnitUris(List<String> _value) {
+    assert(!_finished);
+    _unlinkedUnitUris = _value;
+  }
+
+  /**
+   * Unlinked information for the compilation units constituting the SDK.
+   */
+  void set unlinkedUnits(List<UnlinkedUnitBuilder> _value) {
+    assert(!_finished);
+    _unlinkedUnits = _value;
+  }
+
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = new fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder));
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_prelinkedLibraryUris;
+    fb.Offset offset_prelinkedLibraries;
+    fb.Offset offset_unlinkedUnitUris;
+    fb.Offset offset_unlinkedUnits;
+    if (!(_prelinkedLibraryUris == null || _prelinkedLibraryUris.isEmpty)) {
+      offset_prelinkedLibraryUris = fbBuilder.writeList(_prelinkedLibraryUris.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (!(_prelinkedLibraries == null || _prelinkedLibraries.isEmpty)) {
+      offset_prelinkedLibraries = fbBuilder.writeList(_prelinkedLibraries.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_unlinkedUnitUris == null || _unlinkedUnitUris.isEmpty)) {
+      offset_unlinkedUnitUris = fbBuilder.writeList(_unlinkedUnitUris.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (!(_unlinkedUnits == null || _unlinkedUnits.isEmpty)) {
+      offset_unlinkedUnits = fbBuilder.writeList(_unlinkedUnits.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_prelinkedLibraryUris != null) {
+      fbBuilder.addOffset(0, offset_prelinkedLibraryUris);
+    }
+    if (offset_prelinkedLibraries != null) {
+      fbBuilder.addOffset(1, offset_prelinkedLibraries);
+    }
+    if (offset_unlinkedUnitUris != null) {
+      fbBuilder.addOffset(2, offset_unlinkedUnitUris);
+    }
+    if (offset_unlinkedUnits != null) {
+      fbBuilder.addOffset(3, offset_unlinkedUnits);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+SdkBundleBuilder encodeSdkBundle({List<String> prelinkedLibraryUris, List<PrelinkedLibraryBuilder> prelinkedLibraries, List<String> unlinkedUnitUris, List<UnlinkedUnitBuilder> unlinkedUnits}) {
+  SdkBundleBuilder builder = new SdkBundleBuilder();
+  builder.prelinkedLibraryUris = prelinkedLibraryUris;
+  builder.prelinkedLibraries = prelinkedLibraries;
+  builder.unlinkedUnitUris = unlinkedUnitUris;
+  builder.unlinkedUnits = unlinkedUnits;
+  return builder;
+}
+
+/**
+ * Information about SDK.
+ */
+abstract class SdkBundle extends base.SummaryClass {
+  factory SdkBundle.fromBuffer(List<int> buffer) {
+    fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
+    return const _SdkBundleReader().read(rootRef);
+  }
+
+  /**
+   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
+   */
+  List<String> get prelinkedLibraryUris;
+
+  /**
+   * Pre-linked libraries.
+   */
+  List<PrelinkedLibrary> get prelinkedLibraries;
+
+  /**
+   * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
+   */
+  List<String> get unlinkedUnitUris;
+
+  /**
+   * Unlinked information for the compilation units constituting the SDK.
+   */
+  List<UnlinkedUnit> get unlinkedUnits;
+}
+
+class _SdkBundleReader extends fb.TableReader<_SdkBundleImpl> {
+  const _SdkBundleReader();
+
+  @override
+  _SdkBundleImpl createObject(fb.BufferPointer bp) => new _SdkBundleImpl(bp);
+}
+
+class _SdkBundleImpl implements SdkBundle {
+  final fb.BufferPointer _bp;
+
+  _SdkBundleImpl(this._bp);
+
+  List<String> _prelinkedLibraryUris;
+  List<PrelinkedLibrary> _prelinkedLibraries;
+  List<String> _unlinkedUnitUris;
+  List<UnlinkedUnit> _unlinkedUnits;
+
+  @override
+  Map<String, Object> toMap() => {
+    "prelinkedLibraryUris": prelinkedLibraryUris,
+    "prelinkedLibraries": prelinkedLibraries,
+    "unlinkedUnitUris": unlinkedUnitUris,
+    "unlinkedUnits": unlinkedUnits,
+  };
+
+  @override
+  List<String> get prelinkedLibraryUris {
+    _prelinkedLibraryUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 0, const <String>[]);
+    return _prelinkedLibraryUris;
+  }
+
+  @override
+  List<PrelinkedLibrary> get prelinkedLibraries {
+    _prelinkedLibraries ??= const fb.ListReader<PrelinkedLibrary>(const _PrelinkedLibraryReader()).vTableGet(_bp, 1, const <PrelinkedLibrary>[]);
+    return _prelinkedLibraries;
+  }
+
+  @override
+  List<String> get unlinkedUnitUris {
+    _unlinkedUnitUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 2, const <String>[]);
+    return _unlinkedUnitUris;
+  }
+
+  @override
+  List<UnlinkedUnit> get unlinkedUnits {
+    _unlinkedUnits ??= const fb.ListReader<UnlinkedUnit>(const _UnlinkedUnitReader()).vTableGet(_bp, 3, const <UnlinkedUnit>[]);
+    return _unlinkedUnits;
+  }
+}
+
+class UnlinkedClassBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  List<UnlinkedTypeParamBuilder> _typeParameters;
+  UnlinkedTypeRefBuilder _supertype;
+  List<UnlinkedTypeRefBuilder> _mixins;
+  List<UnlinkedTypeRefBuilder> _interfaces;
+  List<UnlinkedVariableBuilder> _fields;
+  List<UnlinkedExecutableBuilder> _executables;
+  bool _isAbstract;
+  bool _isMixinApplication;
+  bool _hasNoSupertype;
+
+  UnlinkedClassBuilder();
+
+  /**
+   * Name of the class.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Offset of the class name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the class, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
+  }
+
+  /**
+   * Type parameters of the class, if any.
+   */
+  void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
+    assert(!_finished);
+    _typeParameters = _value;
+  }
+
+  /**
+   * Supertype of the class, or `null` if either (a) the class doesn't
+   * explicitly declare a supertype (and hence has supertype `Object`), or (b)
+   * the class *is* `Object` (and hence has no supertype).
+   */
+  void set supertype(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
+    _supertype = _value;
+  }
+
+  /**
+   * Mixins appearing in a `with` clause, if any.
+   */
+  void set mixins(List<UnlinkedTypeRefBuilder> _value) {
+    assert(!_finished);
+    _mixins = _value;
+  }
+
+  /**
+   * Interfaces appearing in an `implements` clause, if any.
+   */
+  void set interfaces(List<UnlinkedTypeRefBuilder> _value) {
+    assert(!_finished);
+    _interfaces = _value;
+  }
+
+  /**
+   * Field declarations contained in the class.
+   */
+  void set fields(List<UnlinkedVariableBuilder> _value) {
+    assert(!_finished);
+    _fields = _value;
+  }
+
+  /**
+   * Executable objects (methods, getters, and setters) contained in the class.
+   */
+  void set executables(List<UnlinkedExecutableBuilder> _value) {
+    assert(!_finished);
+    _executables = _value;
+  }
+
+  /**
+   * Indicates whether the class is declared with the `abstract` keyword.
+   */
+  void set isAbstract(bool _value) {
+    assert(!_finished);
+    _isAbstract = _value;
+  }
+
+  /**
+   * Indicates whether the class is declared using mixin application syntax.
+   */
+  void set isMixinApplication(bool _value) {
+    assert(!_finished);
+    _isMixinApplication = _value;
+  }
+
+  /**
+   * Indicates whether this class is the core "Object" class (and hence has no
+   * supertype)
+   */
+  void set hasNoSupertype(bool _value) {
+    assert(!_finished);
+    _hasNoSupertype = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_typeParameters;
+    fb.Offset offset_supertype;
+    fb.Offset offset_mixins;
+    fb.Offset offset_interfaces;
+    fb.Offset offset_fields;
+    fb.Offset offset_executables;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (!(_typeParameters == null || _typeParameters.isEmpty)) {
+      offset_typeParameters = fbBuilder.writeList(_typeParameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (_supertype != null) {
+      offset_supertype = _supertype.finish(fbBuilder);
+    }
+    if (!(_mixins == null || _mixins.isEmpty)) {
+      offset_mixins = fbBuilder.writeList(_mixins.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_interfaces == null || _interfaces.isEmpty)) {
+      offset_interfaces = fbBuilder.writeList(_interfaces.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_fields == null || _fields.isEmpty)) {
+      offset_fields = fbBuilder.writeList(_fields.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_executables == null || _executables.isEmpty)) {
+      offset_executables = fbBuilder.writeList(_executables.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_typeParameters != null) {
+      fbBuilder.addOffset(3, offset_typeParameters);
+    }
+    if (offset_supertype != null) {
+      fbBuilder.addOffset(4, offset_supertype);
+    }
+    if (offset_mixins != null) {
+      fbBuilder.addOffset(5, offset_mixins);
+    }
+    if (offset_interfaces != null) {
+      fbBuilder.addOffset(6, offset_interfaces);
+    }
+    if (offset_fields != null) {
+      fbBuilder.addOffset(7, offset_fields);
+    }
+    if (offset_executables != null) {
+      fbBuilder.addOffset(8, offset_executables);
+    }
+    if (_isAbstract == true) {
+      fbBuilder.addBool(9, true);
+    }
+    if (_isMixinApplication == true) {
+      fbBuilder.addBool(10, true);
+    }
+    if (_hasNoSupertype == true) {
+      fbBuilder.addBool(11, true);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedClassBuilder encodeUnlinkedClass({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder supertype, List<UnlinkedTypeRefBuilder> mixins, List<UnlinkedTypeRefBuilder> interfaces, List<UnlinkedVariableBuilder> fields, List<UnlinkedExecutableBuilder> executables, bool isAbstract, bool isMixinApplication, bool hasNoSupertype}) {
+  UnlinkedClassBuilder builder = new UnlinkedClassBuilder();
+  builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
+  builder.typeParameters = typeParameters;
+  builder.supertype = supertype;
+  builder.mixins = mixins;
+  builder.interfaces = interfaces;
+  builder.fields = fields;
+  builder.executables = executables;
+  builder.isAbstract = isAbstract;
+  builder.isMixinApplication = isMixinApplication;
+  builder.hasNoSupertype = hasNoSupertype;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a class declaration.
+ */
+abstract class UnlinkedClass extends base.SummaryClass {
+
+  /**
+   * Name of the class.
+   */
+  String get name;
+
+  /**
+   * Offset of the class name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the class, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Type parameters of the class, if any.
+   */
+  List<UnlinkedTypeParam> get typeParameters;
+
+  /**
+   * Supertype of the class, or `null` if either (a) the class doesn't
+   * explicitly declare a supertype (and hence has supertype `Object`), or (b)
+   * the class *is* `Object` (and hence has no supertype).
+   */
+  UnlinkedTypeRef get supertype;
+
+  /**
+   * Mixins appearing in a `with` clause, if any.
+   */
+  List<UnlinkedTypeRef> get mixins;
+
+  /**
+   * Interfaces appearing in an `implements` clause, if any.
+   */
+  List<UnlinkedTypeRef> get interfaces;
+
+  /**
+   * Field declarations contained in the class.
+   */
+  List<UnlinkedVariable> get fields;
+
+  /**
+   * Executable objects (methods, getters, and setters) contained in the class.
+   */
+  List<UnlinkedExecutable> get executables;
+
+  /**
+   * Indicates whether the class is declared with the `abstract` keyword.
+   */
+  bool get isAbstract;
+
+  /**
+   * Indicates whether the class is declared using mixin application syntax.
+   */
+  bool get isMixinApplication;
+
+  /**
+   * Indicates whether this class is the core "Object" class (and hence has no
+   * supertype)
+   */
+  bool get hasNoSupertype;
+}
+
+class _UnlinkedClassReader extends fb.TableReader<_UnlinkedClassImpl> {
+  const _UnlinkedClassReader();
+
+  @override
+  _UnlinkedClassImpl createObject(fb.BufferPointer bp) => new _UnlinkedClassImpl(bp);
+}
+
+class _UnlinkedClassImpl implements UnlinkedClass {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedClassImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  List<UnlinkedTypeParam> _typeParameters;
+  UnlinkedTypeRef _supertype;
+  List<UnlinkedTypeRef> _mixins;
+  List<UnlinkedTypeRef> _interfaces;
+  List<UnlinkedVariable> _fields;
+  List<UnlinkedExecutable> _executables;
+  bool _isAbstract;
+  bool _isMixinApplication;
+  bool _hasNoSupertype;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "typeParameters": typeParameters,
+    "supertype": supertype,
+    "mixins": mixins,
+    "interfaces": interfaces,
+    "fields": fields,
+    "executables": executables,
+    "isAbstract": isAbstract,
+    "isMixinApplication": isMixinApplication,
+    "hasNoSupertype": hasNoSupertype,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  List<UnlinkedTypeParam> get typeParameters {
+    _typeParameters ??= const fb.ListReader<UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bp, 3, const <UnlinkedTypeParam>[]);
+    return _typeParameters;
+  }
+
+  @override
+  UnlinkedTypeRef get supertype {
+    _supertype ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 4, null);
+    return _supertype;
+  }
+
+  @override
+  List<UnlinkedTypeRef> get mixins {
+    _mixins ??= const fb.ListReader<UnlinkedTypeRef>(const _UnlinkedTypeRefReader()).vTableGet(_bp, 5, const <UnlinkedTypeRef>[]);
+    return _mixins;
+  }
+
+  @override
+  List<UnlinkedTypeRef> get interfaces {
+    _interfaces ??= const fb.ListReader<UnlinkedTypeRef>(const _UnlinkedTypeRefReader()).vTableGet(_bp, 6, const <UnlinkedTypeRef>[]);
+    return _interfaces;
+  }
+
+  @override
+  List<UnlinkedVariable> get fields {
+    _fields ??= const fb.ListReader<UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bp, 7, const <UnlinkedVariable>[]);
+    return _fields;
+  }
+
+  @override
+  List<UnlinkedExecutable> get executables {
+    _executables ??= const fb.ListReader<UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bp, 8, const <UnlinkedExecutable>[]);
+    return _executables;
+  }
+
+  @override
+  bool get isAbstract {
+    _isAbstract ??= const fb.BoolReader().vTableGet(_bp, 9, false);
+    return _isAbstract;
+  }
+
+  @override
+  bool get isMixinApplication {
+    _isMixinApplication ??= const fb.BoolReader().vTableGet(_bp, 10, false);
+    return _isMixinApplication;
+  }
+
+  @override
+  bool get hasNoSupertype {
+    _hasNoSupertype ??= const fb.BoolReader().vTableGet(_bp, 11, false);
+    return _hasNoSupertype;
+  }
+}
+
+class UnlinkedCombinatorBuilder {
+  bool _finished = false;
+
+  List<String> _shows;
+  List<String> _hides;
+
+  UnlinkedCombinatorBuilder();
+
+  /**
+   * List of names which are shown.  Empty if this is a `hide` combinator.
+   */
+  void set shows(List<String> _value) {
+    assert(!_finished);
+    _shows = _value;
+  }
+
+  /**
+   * List of names which are hidden.  Empty if this is a `show` combinator.
+   */
+  void set hides(List<String> _value) {
+    assert(!_finished);
+    _hides = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_shows;
+    fb.Offset offset_hides;
+    if (!(_shows == null || _shows.isEmpty)) {
+      offset_shows = fbBuilder.writeList(_shows.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (!(_hides == null || _hides.isEmpty)) {
+      offset_hides = fbBuilder.writeList(_hides.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_shows != null) {
+      fbBuilder.addOffset(0, offset_shows);
+    }
+    if (offset_hides != null) {
+      fbBuilder.addOffset(1, offset_hides);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedCombinatorBuilder encodeUnlinkedCombinator({List<String> shows, List<String> hides}) {
+  UnlinkedCombinatorBuilder builder = new UnlinkedCombinatorBuilder();
+  builder.shows = shows;
+  builder.hides = hides;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a `show` or `hide` combinator in an
+ * import or export declaration.
+ */
+abstract class UnlinkedCombinator extends base.SummaryClass {
+
+  /**
+   * List of names which are shown.  Empty if this is a `hide` combinator.
+   */
+  List<String> get shows;
+
+  /**
+   * List of names which are hidden.  Empty if this is a `show` combinator.
+   */
+  List<String> get hides;
+}
+
+class _UnlinkedCombinatorReader extends fb.TableReader<_UnlinkedCombinatorImpl> {
+  const _UnlinkedCombinatorReader();
+
+  @override
+  _UnlinkedCombinatorImpl createObject(fb.BufferPointer bp) => new _UnlinkedCombinatorImpl(bp);
+}
+
+class _UnlinkedCombinatorImpl implements UnlinkedCombinator {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedCombinatorImpl(this._bp);
+
+  List<String> _shows;
+  List<String> _hides;
+
+  @override
+  Map<String, Object> toMap() => {
+    "shows": shows,
+    "hides": hides,
+  };
+
+  @override
+  List<String> get shows {
+    _shows ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 0, const <String>[]);
+    return _shows;
+  }
+
+  @override
+  List<String> get hides {
+    _hides ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
+    return _hides;
+  }
+}
+
+class UnlinkedDocumentationCommentBuilder {
+  bool _finished = false;
+
+  String _text;
+  int _offset;
+  int _length;
+
+  UnlinkedDocumentationCommentBuilder();
+
+  /**
+   * Text of the documentation comment, with '\r\n' replaced by '\n'.
+   *
+   * References appearing within the doc comment in square brackets are not
+   * specially encoded.
+   */
+  void set text(String _value) {
+    assert(!_finished);
+    _text = _value;
+  }
+
+  /**
+   * Offset of the beginning of the documentation comment relative to the
+   * beginning of the file.
+   */
+  void set offset(int _value) {
+    assert(!_finished);
+    _offset = _value;
+  }
+
+  /**
+   * Length of the documentation comment (prior to replacing '\r\n' with '\n').
+   */
+  void set length(int _value) {
+    assert(!_finished);
+    _length = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_text;
+    if (_text != null) {
+      offset_text = fbBuilder.writeString(_text);
+    }
+    fbBuilder.startTable();
+    if (offset_text != null) {
+      fbBuilder.addOffset(0, offset_text);
+    }
+    if (_offset != null && _offset != 0) {
+      fbBuilder.addInt32(1, _offset);
+    }
+    if (_length != null && _length != 0) {
+      fbBuilder.addInt32(2, _length);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedDocumentationCommentBuilder encodeUnlinkedDocumentationComment({String text, int offset, int length}) {
+  UnlinkedDocumentationCommentBuilder builder = new UnlinkedDocumentationCommentBuilder();
+  builder.text = text;
+  builder.offset = offset;
+  builder.length = length;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a documentation comment.
+ */
+abstract class UnlinkedDocumentationComment extends base.SummaryClass {
+
+  /**
+   * Text of the documentation comment, with '\r\n' replaced by '\n'.
+   *
+   * References appearing within the doc comment in square brackets are not
+   * specially encoded.
+   */
+  String get text;
+
+  /**
+   * Offset of the beginning of the documentation comment relative to the
+   * beginning of the file.
+   */
+  int get offset;
+
+  /**
+   * Length of the documentation comment (prior to replacing '\r\n' with '\n').
+   */
+  int get length;
+}
+
+class _UnlinkedDocumentationCommentReader extends fb.TableReader<_UnlinkedDocumentationCommentImpl> {
+  const _UnlinkedDocumentationCommentReader();
+
+  @override
+  _UnlinkedDocumentationCommentImpl createObject(fb.BufferPointer bp) => new _UnlinkedDocumentationCommentImpl(bp);
+}
+
+class _UnlinkedDocumentationCommentImpl implements UnlinkedDocumentationComment {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedDocumentationCommentImpl(this._bp);
+
+  String _text;
+  int _offset;
+  int _length;
+
+  @override
+  Map<String, Object> toMap() => {
+    "text": text,
+    "offset": offset,
+    "length": length,
+  };
+
+  @override
+  String get text {
+    _text ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _text;
+  }
+
+  @override
+  int get offset {
+    _offset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _offset;
+  }
+
+  @override
+  int get length {
+    _length ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _length;
+  }
+}
+
+class UnlinkedEnumBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  List<UnlinkedEnumValueBuilder> _values;
+
+  UnlinkedEnumBuilder();
+
+  /**
+   * Name of the enum type.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Offset of the enum name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the enum, or `null` if there is no documentation
+   * comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
+  }
+
+  /**
+   * Values listed in the enum declaration, in declaration order.
+   */
+  void set values(List<UnlinkedEnumValueBuilder> _value) {
+    assert(!_finished);
+    _values = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_values;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (!(_values == null || _values.isEmpty)) {
+      offset_values = fbBuilder.writeList(_values.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_values != null) {
+      fbBuilder.addOffset(3, offset_values);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedEnumBuilder encodeUnlinkedEnum({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedEnumValueBuilder> values}) {
+  UnlinkedEnumBuilder builder = new UnlinkedEnumBuilder();
+  builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
+  builder.values = values;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about an enum declaration.
+ */
+abstract class UnlinkedEnum extends base.SummaryClass {
+
+  /**
+   * Name of the enum type.
+   */
+  String get name;
+
+  /**
+   * Offset of the enum name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the enum, or `null` if there is no documentation
+   * comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Values listed in the enum declaration, in declaration order.
+   */
+  List<UnlinkedEnumValue> get values;
+}
+
+class _UnlinkedEnumReader extends fb.TableReader<_UnlinkedEnumImpl> {
+  const _UnlinkedEnumReader();
+
+  @override
+  _UnlinkedEnumImpl createObject(fb.BufferPointer bp) => new _UnlinkedEnumImpl(bp);
+}
+
+class _UnlinkedEnumImpl implements UnlinkedEnum {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedEnumImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  List<UnlinkedEnumValue> _values;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "values": values,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  List<UnlinkedEnumValue> get values {
+    _values ??= const fb.ListReader<UnlinkedEnumValue>(const _UnlinkedEnumValueReader()).vTableGet(_bp, 3, const <UnlinkedEnumValue>[]);
+    return _values;
+  }
+}
+
+class UnlinkedEnumValueBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+
+  UnlinkedEnumValueBuilder();
+
+  /**
+   * Name of the enumerated value.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Offset of the enum value name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the enum value, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedEnumValueBuilder encodeUnlinkedEnumValue({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment}) {
+  UnlinkedEnumValueBuilder builder = new UnlinkedEnumValueBuilder();
+  builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a single enumerated value in an enum
+ * declaration.
+ */
+abstract class UnlinkedEnumValue extends base.SummaryClass {
+
+  /**
+   * Name of the enumerated value.
+   */
+  String get name;
+
+  /**
+   * Offset of the enum value name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the enum value, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+}
+
+class _UnlinkedEnumValueReader extends fb.TableReader<_UnlinkedEnumValueImpl> {
+  const _UnlinkedEnumValueReader();
+
+  @override
+  _UnlinkedEnumValueImpl createObject(fb.BufferPointer bp) => new _UnlinkedEnumValueImpl(bp);
+}
+
+class _UnlinkedEnumValueImpl implements UnlinkedEnumValue {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedEnumValueImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+}
+
+class UnlinkedExecutableBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  List<UnlinkedTypeParamBuilder> _typeParameters;
+  UnlinkedTypeRefBuilder _returnType;
+  List<UnlinkedParamBuilder> _parameters;
+  UnlinkedExecutableKind _kind;
+  bool _isAbstract;
+  bool _isStatic;
+  bool _isConst;
+  bool _isFactory;
+  bool _hasImplicitReturnType;
+  bool _isExternal;
+
+  UnlinkedExecutableBuilder();
+
+  /**
+   * Name of the executable.  For setters, this includes the trailing "=".  For
+   * named constructors, this excludes the class name and excludes the ".".
+   * For unnamed constructors, this is the empty string.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Offset of the executable name relative to the beginning of the file.  For
+   * named constructors, this excludes the class name and excludes the ".".
+   * For unnamed constructors, this is the offset of the class name (i.e. the
+   * offset of the second "C" in "class C { C(); }").
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the executable, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
+  }
+
+  /**
+   * Type parameters of the executable, if any.  Empty if support for generic
+   * method syntax is disabled.
+   */
+  void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
+    assert(!_finished);
+    _typeParameters = _value;
+  }
+
+  /**
+   * Declared return type of the executable.  Absent if the return type is
+   * `void` or the executable is a constructor.  Note that when strong mode is
+   * enabled, the actual return type may be different due to type inference.
+   */
+  void set returnType(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
+    _returnType = _value;
+  }
+
+  /**
+   * Parameters of the executable, if any.  Note that getters have no
+   * parameters (hence this will be the empty list), and setters have a single
+   * parameter.
+   */
+  void set parameters(List<UnlinkedParamBuilder> _value) {
+    assert(!_finished);
+    _parameters = _value;
+  }
+
+  /**
+   * The kind of the executable (function/method, getter, setter, or
+   * constructor).
+   */
+  void set kind(UnlinkedExecutableKind _value) {
+    assert(!_finished);
+    _kind = _value;
+  }
+
+  /**
+   * Indicates whether the executable is declared using the `abstract` keyword.
+   */
+  void set isAbstract(bool _value) {
+    assert(!_finished);
+    _isAbstract = _value;
+  }
+
+  /**
+   * Indicates whether the executable is declared using the `static` keyword.
+   *
+   * Note that for top level executables, this flag is false, since they are
+   * not declared using the `static` keyword (even though they are considered
+   * static for semantic purposes).
+   */
+  void set isStatic(bool _value) {
+    assert(!_finished);
+    _isStatic = _value;
+  }
+
+  /**
+   * Indicates whether the executable is declared using the `const` keyword.
+   */
+  void set isConst(bool _value) {
+    assert(!_finished);
+    _isConst = _value;
+  }
+
+  /**
+   * Indicates whether the executable is declared using the `factory` keyword.
+   */
+  void set isFactory(bool _value) {
+    assert(!_finished);
+    _isFactory = _value;
+  }
+
+  /**
+   * Indicates whether the executable lacks an explicit return type
+   * declaration.  False for constructors and setters.
+   */
+  void set hasImplicitReturnType(bool _value) {
+    assert(!_finished);
+    _hasImplicitReturnType = _value;
+  }
+
+  /**
+   * Indicates whether the executable is declared using the `external` keyword.
+   */
+  void set isExternal(bool _value) {
+    assert(!_finished);
+    _isExternal = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_typeParameters;
+    fb.Offset offset_returnType;
+    fb.Offset offset_parameters;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (!(_typeParameters == null || _typeParameters.isEmpty)) {
+      offset_typeParameters = fbBuilder.writeList(_typeParameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (_returnType != null) {
+      offset_returnType = _returnType.finish(fbBuilder);
+    }
+    if (!(_parameters == null || _parameters.isEmpty)) {
+      offset_parameters = fbBuilder.writeList(_parameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_typeParameters != null) {
+      fbBuilder.addOffset(3, offset_typeParameters);
+    }
+    if (offset_returnType != null) {
+      fbBuilder.addOffset(4, offset_returnType);
+    }
+    if (offset_parameters != null) {
+      fbBuilder.addOffset(5, offset_parameters);
+    }
+    if (_kind != null && _kind != UnlinkedExecutableKind.functionOrMethod) {
+      fbBuilder.addInt32(6, _kind.index);
+    }
+    if (_isAbstract == true) {
+      fbBuilder.addBool(7, true);
+    }
+    if (_isStatic == true) {
+      fbBuilder.addBool(8, true);
+    }
+    if (_isConst == true) {
+      fbBuilder.addBool(9, true);
+    }
+    if (_isFactory == true) {
+      fbBuilder.addBool(10, true);
+    }
+    if (_hasImplicitReturnType == true) {
+      fbBuilder.addBool(11, true);
+    }
+    if (_isExternal == true) {
+      fbBuilder.addBool(12, true);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedExecutableBuilder encodeUnlinkedExecutable({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters, UnlinkedExecutableKind kind, bool isAbstract, bool isStatic, bool isConst, bool isFactory, bool hasImplicitReturnType, bool isExternal}) {
+  UnlinkedExecutableBuilder builder = new UnlinkedExecutableBuilder();
+  builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
+  builder.typeParameters = typeParameters;
+  builder.returnType = returnType;
+  builder.parameters = parameters;
+  builder.kind = kind;
+  builder.isAbstract = isAbstract;
+  builder.isStatic = isStatic;
+  builder.isConst = isConst;
+  builder.isFactory = isFactory;
+  builder.hasImplicitReturnType = hasImplicitReturnType;
+  builder.isExternal = isExternal;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a function, method, getter, or setter
+ * declaration.
+ */
+abstract class UnlinkedExecutable extends base.SummaryClass {
+
+  /**
+   * Name of the executable.  For setters, this includes the trailing "=".  For
+   * named constructors, this excludes the class name and excludes the ".".
+   * For unnamed constructors, this is the empty string.
+   */
+  String get name;
+
+  /**
+   * Offset of the executable name relative to the beginning of the file.  For
+   * named constructors, this excludes the class name and excludes the ".".
+   * For unnamed constructors, this is the offset of the class name (i.e. the
+   * offset of the second "C" in "class C { C(); }").
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the executable, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Type parameters of the executable, if any.  Empty if support for generic
+   * method syntax is disabled.
+   */
+  List<UnlinkedTypeParam> get typeParameters;
+
+  /**
+   * Declared return type of the executable.  Absent if the return type is
+   * `void` or the executable is a constructor.  Note that when strong mode is
+   * enabled, the actual return type may be different due to type inference.
+   */
+  UnlinkedTypeRef get returnType;
+
+  /**
+   * Parameters of the executable, if any.  Note that getters have no
+   * parameters (hence this will be the empty list), and setters have a single
+   * parameter.
+   */
+  List<UnlinkedParam> get parameters;
+
+  /**
+   * The kind of the executable (function/method, getter, setter, or
+   * constructor).
+   */
+  UnlinkedExecutableKind get kind;
+
+  /**
+   * Indicates whether the executable is declared using the `abstract` keyword.
+   */
+  bool get isAbstract;
+
+  /**
+   * Indicates whether the executable is declared using the `static` keyword.
+   *
+   * Note that for top level executables, this flag is false, since they are
+   * not declared using the `static` keyword (even though they are considered
+   * static for semantic purposes).
+   */
+  bool get isStatic;
+
+  /**
+   * Indicates whether the executable is declared using the `const` keyword.
+   */
+  bool get isConst;
+
+  /**
+   * Indicates whether the executable is declared using the `factory` keyword.
+   */
+  bool get isFactory;
+
+  /**
+   * Indicates whether the executable lacks an explicit return type
+   * declaration.  False for constructors and setters.
+   */
+  bool get hasImplicitReturnType;
+
+  /**
+   * Indicates whether the executable is declared using the `external` keyword.
+   */
+  bool get isExternal;
+}
+
+class _UnlinkedExecutableReader extends fb.TableReader<_UnlinkedExecutableImpl> {
+  const _UnlinkedExecutableReader();
+
+  @override
+  _UnlinkedExecutableImpl createObject(fb.BufferPointer bp) => new _UnlinkedExecutableImpl(bp);
+}
+
+class _UnlinkedExecutableImpl implements UnlinkedExecutable {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedExecutableImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  List<UnlinkedTypeParam> _typeParameters;
+  UnlinkedTypeRef _returnType;
+  List<UnlinkedParam> _parameters;
+  UnlinkedExecutableKind _kind;
+  bool _isAbstract;
+  bool _isStatic;
+  bool _isConst;
+  bool _isFactory;
+  bool _hasImplicitReturnType;
+  bool _isExternal;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "typeParameters": typeParameters,
+    "returnType": returnType,
+    "parameters": parameters,
+    "kind": kind,
+    "isAbstract": isAbstract,
+    "isStatic": isStatic,
+    "isConst": isConst,
+    "isFactory": isFactory,
+    "hasImplicitReturnType": hasImplicitReturnType,
+    "isExternal": isExternal,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  List<UnlinkedTypeParam> get typeParameters {
+    _typeParameters ??= const fb.ListReader<UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bp, 3, const <UnlinkedTypeParam>[]);
+    return _typeParameters;
+  }
+
+  @override
+  UnlinkedTypeRef get returnType {
+    _returnType ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 4, null);
+    return _returnType;
+  }
+
+  @override
+  List<UnlinkedParam> get parameters {
+    _parameters ??= const fb.ListReader<UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 5, const <UnlinkedParam>[]);
+    return _parameters;
+  }
+
+  @override
+  UnlinkedExecutableKind get kind {
+    _kind ??= UnlinkedExecutableKind.values[const fb.Int32Reader().vTableGet(_bp, 6, 0)];
+    return _kind;
+  }
+
+  @override
+  bool get isAbstract {
+    _isAbstract ??= const fb.BoolReader().vTableGet(_bp, 7, false);
+    return _isAbstract;
+  }
+
+  @override
+  bool get isStatic {
+    _isStatic ??= const fb.BoolReader().vTableGet(_bp, 8, false);
+    return _isStatic;
+  }
+
+  @override
+  bool get isConst {
+    _isConst ??= const fb.BoolReader().vTableGet(_bp, 9, false);
+    return _isConst;
+  }
+
+  @override
+  bool get isFactory {
+    _isFactory ??= const fb.BoolReader().vTableGet(_bp, 10, false);
+    return _isFactory;
+  }
+
+  @override
+  bool get hasImplicitReturnType {
+    _hasImplicitReturnType ??= const fb.BoolReader().vTableGet(_bp, 11, false);
+    return _hasImplicitReturnType;
+  }
+
+  @override
+  bool get isExternal {
+    _isExternal ??= const fb.BoolReader().vTableGet(_bp, 12, false);
+    return _isExternal;
+  }
+}
+
+class UnlinkedExportNonPublicBuilder {
+  bool _finished = false;
+
+  int _offset;
+  int _uriOffset;
+  int _uriEnd;
+
+  UnlinkedExportNonPublicBuilder();
+
+  /**
+   * Offset of the "export" keyword.
+   */
+  void set offset(int _value) {
+    assert(!_finished);
+    _offset = _value;
+  }
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  void set uriOffset(int _value) {
+    assert(!_finished);
+    _uriOffset = _value;
+  }
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  void set uriEnd(int _value) {
+    assert(!_finished);
+    _uriEnd = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fbBuilder.startTable();
+    if (_offset != null && _offset != 0) {
+      fbBuilder.addInt32(0, _offset);
+    }
+    if (_uriOffset != null && _uriOffset != 0) {
+      fbBuilder.addInt32(1, _uriOffset);
+    }
+    if (_uriEnd != null && _uriEnd != 0) {
+      fbBuilder.addInt32(2, _uriEnd);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedExportNonPublicBuilder encodeUnlinkedExportNonPublic({int offset, int uriOffset, int uriEnd}) {
+  UnlinkedExportNonPublicBuilder builder = new UnlinkedExportNonPublicBuilder();
+  builder.offset = offset;
+  builder.uriOffset = uriOffset;
+  builder.uriEnd = uriEnd;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about an export declaration (stored outside
+ * [UnlinkedPublicNamespace]).
+ */
+abstract class UnlinkedExportNonPublic extends base.SummaryClass {
+
+  /**
+   * Offset of the "export" keyword.
+   */
+  int get offset;
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  int get uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  int get uriEnd;
+}
+
+class _UnlinkedExportNonPublicReader extends fb.TableReader<_UnlinkedExportNonPublicImpl> {
+  const _UnlinkedExportNonPublicReader();
+
+  @override
+  _UnlinkedExportNonPublicImpl createObject(fb.BufferPointer bp) => new _UnlinkedExportNonPublicImpl(bp);
+}
+
+class _UnlinkedExportNonPublicImpl implements UnlinkedExportNonPublic {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedExportNonPublicImpl(this._bp);
+
+  int _offset;
+  int _uriOffset;
+  int _uriEnd;
+
+  @override
+  Map<String, Object> toMap() => {
+    "offset": offset,
+    "uriOffset": uriOffset,
+    "uriEnd": uriEnd,
+  };
+
+  @override
+  int get offset {
+    _offset ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    return _offset;
+  }
+
+  @override
+  int get uriOffset {
+    _uriOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _uriOffset;
+  }
+
+  @override
+  int get uriEnd {
+    _uriEnd ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _uriEnd;
+  }
+}
+
+class UnlinkedExportPublicBuilder {
+  bool _finished = false;
+
+  String _uri;
+  List<UnlinkedCombinatorBuilder> _combinators;
+
+  UnlinkedExportPublicBuilder();
+
+  /**
+   * URI used in the source code to reference the exported library.
+   */
+  void set uri(String _value) {
+    assert(!_finished);
+    _uri = _value;
+  }
+
+  /**
+   * Combinators contained in this import declaration.
+   */
+  void set combinators(List<UnlinkedCombinatorBuilder> _value) {
+    assert(!_finished);
+    _combinators = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_uri;
+    fb.Offset offset_combinators;
+    if (_uri != null) {
+      offset_uri = fbBuilder.writeString(_uri);
+    }
+    if (!(_combinators == null || _combinators.isEmpty)) {
+      offset_combinators = fbBuilder.writeList(_combinators.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_uri != null) {
+      fbBuilder.addOffset(0, offset_uri);
+    }
+    if (offset_combinators != null) {
+      fbBuilder.addOffset(1, offset_combinators);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedExportPublicBuilder encodeUnlinkedExportPublic({String uri, List<UnlinkedCombinatorBuilder> combinators}) {
+  UnlinkedExportPublicBuilder builder = new UnlinkedExportPublicBuilder();
+  builder.uri = uri;
+  builder.combinators = combinators;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about an export declaration (stored inside
+ * [UnlinkedPublicNamespace]).
+ */
+abstract class UnlinkedExportPublic extends base.SummaryClass {
+
+  /**
+   * URI used in the source code to reference the exported library.
+   */
+  String get uri;
+
+  /**
+   * Combinators contained in this import declaration.
+   */
+  List<UnlinkedCombinator> get combinators;
+}
+
+class _UnlinkedExportPublicReader extends fb.TableReader<_UnlinkedExportPublicImpl> {
+  const _UnlinkedExportPublicReader();
+
+  @override
+  _UnlinkedExportPublicImpl createObject(fb.BufferPointer bp) => new _UnlinkedExportPublicImpl(bp);
+}
+
+class _UnlinkedExportPublicImpl implements UnlinkedExportPublic {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedExportPublicImpl(this._bp);
+
+  String _uri;
+  List<UnlinkedCombinator> _combinators;
+
+  @override
+  Map<String, Object> toMap() => {
+    "uri": uri,
+    "combinators": combinators,
+  };
+
+  @override
+  String get uri {
+    _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _uri;
+  }
+
+  @override
+  List<UnlinkedCombinator> get combinators {
+    _combinators ??= const fb.ListReader<UnlinkedCombinator>(const _UnlinkedCombinatorReader()).vTableGet(_bp, 1, const <UnlinkedCombinator>[]);
+    return _combinators;
+  }
+}
+
+class UnlinkedImportBuilder {
+  bool _finished = false;
+
+  String _uri;
+  int _offset;
+  int _prefixReference;
+  List<UnlinkedCombinatorBuilder> _combinators;
+  bool _isDeferred;
+  bool _isImplicit;
+  int _uriOffset;
+  int _uriEnd;
+  int _prefixOffset;
+
+  UnlinkedImportBuilder();
+
+  /**
+   * URI used in the source code to reference the imported library.
+   */
+  void set uri(String _value) {
+    assert(!_finished);
+    _uri = _value;
+  }
+
+  /**
+   * If [isImplicit] is false, offset of the "import" keyword.  If [isImplicit]
+   * is true, zero.
+   */
+  void set offset(int _value) {
+    assert(!_finished);
+    _offset = _value;
+  }
+
+  /**
+   * Index into [UnlinkedUnit.references] of the prefix declared by this
+   * import declaration, or zero if this import declaration declares no prefix.
+   *
+   * Note that multiple imports can declare the same prefix.
+   */
+  void set prefixReference(int _value) {
+    assert(!_finished);
+    _prefixReference = _value;
+  }
+
+  /**
+   * Combinators contained in this import declaration.
+   */
+  void set combinators(List<UnlinkedCombinatorBuilder> _value) {
+    assert(!_finished);
+    _combinators = _value;
+  }
+
+  /**
+   * Indicates whether the import declaration uses the `deferred` keyword.
+   */
+  void set isDeferred(bool _value) {
+    assert(!_finished);
+    _isDeferred = _value;
+  }
+
+  /**
+   * Indicates whether the import declaration is implicit.
+   */
+  void set isImplicit(bool _value) {
+    assert(!_finished);
+    _isImplicit = _value;
+  }
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.  If [isImplicit] is true, zero.
+   */
+  void set uriOffset(int _value) {
+    assert(!_finished);
+    _uriOffset = _value;
+  }
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.  If [isImplicit] is true, zero.
+   */
+  void set uriEnd(int _value) {
+    assert(!_finished);
+    _uriEnd = _value;
+  }
+
+  /**
+   * Offset of the prefix name relative to the beginning of the file, or zero
+   * if there is no prefix.
+   */
+  void set prefixOffset(int _value) {
+    assert(!_finished);
+    _prefixOffset = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_uri;
+    fb.Offset offset_combinators;
+    if (_uri != null) {
+      offset_uri = fbBuilder.writeString(_uri);
+    }
+    if (!(_combinators == null || _combinators.isEmpty)) {
+      offset_combinators = fbBuilder.writeList(_combinators.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_uri != null) {
+      fbBuilder.addOffset(0, offset_uri);
+    }
+    if (_offset != null && _offset != 0) {
+      fbBuilder.addInt32(1, _offset);
+    }
+    if (_prefixReference != null && _prefixReference != 0) {
+      fbBuilder.addInt32(2, _prefixReference);
+    }
+    if (offset_combinators != null) {
+      fbBuilder.addOffset(3, offset_combinators);
+    }
+    if (_isDeferred == true) {
+      fbBuilder.addBool(4, true);
+    }
+    if (_isImplicit == true) {
+      fbBuilder.addBool(5, true);
+    }
+    if (_uriOffset != null && _uriOffset != 0) {
+      fbBuilder.addInt32(6, _uriOffset);
+    }
+    if (_uriEnd != null && _uriEnd != 0) {
+      fbBuilder.addInt32(7, _uriEnd);
+    }
+    if (_prefixOffset != null && _prefixOffset != 0) {
+      fbBuilder.addInt32(8, _prefixOffset);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedImportBuilder encodeUnlinkedImport({String uri, int offset, int prefixReference, List<UnlinkedCombinatorBuilder> combinators, bool isDeferred, bool isImplicit, int uriOffset, int uriEnd, int prefixOffset}) {
+  UnlinkedImportBuilder builder = new UnlinkedImportBuilder();
+  builder.uri = uri;
+  builder.offset = offset;
+  builder.prefixReference = prefixReference;
+  builder.combinators = combinators;
+  builder.isDeferred = isDeferred;
+  builder.isImplicit = isImplicit;
+  builder.uriOffset = uriOffset;
+  builder.uriEnd = uriEnd;
+  builder.prefixOffset = prefixOffset;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about an import declaration.
+ */
+abstract class UnlinkedImport extends base.SummaryClass {
+
+  /**
+   * URI used in the source code to reference the imported library.
+   */
+  String get uri;
+
+  /**
+   * If [isImplicit] is false, offset of the "import" keyword.  If [isImplicit]
+   * is true, zero.
+   */
+  int get offset;
+
+  /**
+   * Index into [UnlinkedUnit.references] of the prefix declared by this
+   * import declaration, or zero if this import declaration declares no prefix.
+   *
+   * Note that multiple imports can declare the same prefix.
+   */
+  int get prefixReference;
+
+  /**
+   * Combinators contained in this import declaration.
+   */
+  List<UnlinkedCombinator> get combinators;
+
+  /**
+   * Indicates whether the import declaration uses the `deferred` keyword.
+   */
+  bool get isDeferred;
+
+  /**
+   * Indicates whether the import declaration is implicit.
+   */
+  bool get isImplicit;
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.  If [isImplicit] is true, zero.
+   */
+  int get uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.  If [isImplicit] is true, zero.
+   */
+  int get uriEnd;
+
+  /**
+   * Offset of the prefix name relative to the beginning of the file, or zero
+   * if there is no prefix.
+   */
+  int get prefixOffset;
+}
+
+class _UnlinkedImportReader extends fb.TableReader<_UnlinkedImportImpl> {
+  const _UnlinkedImportReader();
+
+  @override
+  _UnlinkedImportImpl createObject(fb.BufferPointer bp) => new _UnlinkedImportImpl(bp);
+}
+
+class _UnlinkedImportImpl implements UnlinkedImport {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedImportImpl(this._bp);
+
+  String _uri;
+  int _offset;
+  int _prefixReference;
+  List<UnlinkedCombinator> _combinators;
+  bool _isDeferred;
+  bool _isImplicit;
+  int _uriOffset;
+  int _uriEnd;
+  int _prefixOffset;
+
+  @override
+  Map<String, Object> toMap() => {
+    "uri": uri,
+    "offset": offset,
+    "prefixReference": prefixReference,
+    "combinators": combinators,
+    "isDeferred": isDeferred,
+    "isImplicit": isImplicit,
+    "uriOffset": uriOffset,
+    "uriEnd": uriEnd,
+    "prefixOffset": prefixOffset,
+  };
+
+  @override
+  String get uri {
+    _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _uri;
+  }
+
+  @override
+  int get offset {
+    _offset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _offset;
+  }
+
+  @override
+  int get prefixReference {
+    _prefixReference ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _prefixReference;
+  }
+
+  @override
+  List<UnlinkedCombinator> get combinators {
+    _combinators ??= const fb.ListReader<UnlinkedCombinator>(const _UnlinkedCombinatorReader()).vTableGet(_bp, 3, const <UnlinkedCombinator>[]);
+    return _combinators;
+  }
+
+  @override
+  bool get isDeferred {
+    _isDeferred ??= const fb.BoolReader().vTableGet(_bp, 4, false);
+    return _isDeferred;
+  }
+
+  @override
+  bool get isImplicit {
+    _isImplicit ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    return _isImplicit;
+  }
+
+  @override
+  int get uriOffset {
+    _uriOffset ??= const fb.Int32Reader().vTableGet(_bp, 6, 0);
+    return _uriOffset;
+  }
+
+  @override
+  int get uriEnd {
+    _uriEnd ??= const fb.Int32Reader().vTableGet(_bp, 7, 0);
+    return _uriEnd;
+  }
+
+  @override
+  int get prefixOffset {
+    _prefixOffset ??= const fb.Int32Reader().vTableGet(_bp, 8, 0);
+    return _prefixOffset;
+  }
+}
+
+class UnlinkedParamBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _nameOffset;
+  UnlinkedTypeRefBuilder _type;
+  List<UnlinkedParamBuilder> _parameters;
+  UnlinkedParamKind _kind;
+  bool _isFunctionTyped;
+  bool _isInitializingFormal;
+  bool _hasImplicitType;
+
+  UnlinkedParamBuilder();
+
+  /**
+   * Name of the parameter.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Offset of the parameter name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * If [isFunctionTyped] is `true`, the declared return type.  If
+   * [isFunctionTyped] is `false`, the declared type.  Absent if
+   * [isFunctionTyped] is `true` and the declared return type is `void`.  Note
+   * that when strong mode is enabled, the actual type may be different due to
+   * type inference.
+   */
+  void set type(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
+    _type = _value;
+  }
+
+  /**
+   * If [isFunctionTyped] is `true`, the parameters of the function type.
+   */
+  void set parameters(List<UnlinkedParamBuilder> _value) {
+    assert(!_finished);
+    _parameters = _value;
+  }
+
+  /**
+   * Kind of the parameter.
+   */
+  void set kind(UnlinkedParamKind _value) {
+    assert(!_finished);
+    _kind = _value;
+  }
+
+  /**
+   * Indicates whether this is a function-typed parameter.
+   */
+  void set isFunctionTyped(bool _value) {
+    assert(!_finished);
+    _isFunctionTyped = _value;
+  }
+
+  /**
+   * Indicates whether this is an initializing formal parameter (i.e. it is
+   * declared using `this.` syntax).
+   */
+  void set isInitializingFormal(bool _value) {
+    assert(!_finished);
+    _isInitializingFormal = _value;
+  }
+
+  /**
+   * Indicates whether this parameter lacks an explicit type declaration.
+   * Always false for a function-typed parameter.
+   */
+  void set hasImplicitType(bool _value) {
+    assert(!_finished);
+    _hasImplicitType = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    fb.Offset offset_type;
+    fb.Offset offset_parameters;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_type != null) {
+      offset_type = _type.finish(fbBuilder);
+    }
+    if (!(_parameters == null || _parameters.isEmpty)) {
+      offset_parameters = fbBuilder.writeList(_parameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_type != null) {
+      fbBuilder.addOffset(2, offset_type);
+    }
+    if (offset_parameters != null) {
+      fbBuilder.addOffset(3, offset_parameters);
+    }
+    if (_kind != null && _kind != UnlinkedParamKind.required) {
+      fbBuilder.addInt32(4, _kind.index);
+    }
+    if (_isFunctionTyped == true) {
+      fbBuilder.addBool(5, true);
+    }
+    if (_isInitializingFormal == true) {
+      fbBuilder.addBool(6, true);
+    }
+    if (_hasImplicitType == true) {
+      fbBuilder.addBool(7, true);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedParamBuilder encodeUnlinkedParam({String name, int nameOffset, UnlinkedTypeRefBuilder type, List<UnlinkedParamBuilder> parameters, UnlinkedParamKind kind, bool isFunctionTyped, bool isInitializingFormal, bool hasImplicitType}) {
+  UnlinkedParamBuilder builder = new UnlinkedParamBuilder();
+  builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.type = type;
+  builder.parameters = parameters;
+  builder.kind = kind;
+  builder.isFunctionTyped = isFunctionTyped;
+  builder.isInitializingFormal = isInitializingFormal;
+  builder.hasImplicitType = hasImplicitType;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a function parameter.
+ */
+abstract class UnlinkedParam extends base.SummaryClass {
+
+  /**
+   * Name of the parameter.
+   */
+  String get name;
+
+  /**
+   * Offset of the parameter name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * If [isFunctionTyped] is `true`, the declared return type.  If
+   * [isFunctionTyped] is `false`, the declared type.  Absent if
+   * [isFunctionTyped] is `true` and the declared return type is `void`.  Note
+   * that when strong mode is enabled, the actual type may be different due to
+   * type inference.
+   */
+  UnlinkedTypeRef get type;
+
+  /**
+   * If [isFunctionTyped] is `true`, the parameters of the function type.
+   */
+  List<UnlinkedParam> get parameters;
+
+  /**
+   * Kind of the parameter.
+   */
+  UnlinkedParamKind get kind;
+
+  /**
+   * Indicates whether this is a function-typed parameter.
+   */
+  bool get isFunctionTyped;
+
+  /**
+   * Indicates whether this is an initializing formal parameter (i.e. it is
+   * declared using `this.` syntax).
+   */
+  bool get isInitializingFormal;
+
+  /**
+   * Indicates whether this parameter lacks an explicit type declaration.
+   * Always false for a function-typed parameter.
+   */
+  bool get hasImplicitType;
+}
+
+class _UnlinkedParamReader extends fb.TableReader<_UnlinkedParamImpl> {
+  const _UnlinkedParamReader();
+
+  @override
+  _UnlinkedParamImpl createObject(fb.BufferPointer bp) => new _UnlinkedParamImpl(bp);
+}
+
+class _UnlinkedParamImpl implements UnlinkedParam {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedParamImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedTypeRef _type;
+  List<UnlinkedParam> _parameters;
+  UnlinkedParamKind _kind;
+  bool _isFunctionTyped;
+  bool _isInitializingFormal;
+  bool _hasImplicitType;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "type": type,
+    "parameters": parameters,
+    "kind": kind,
+    "isFunctionTyped": isFunctionTyped,
+    "isInitializingFormal": isInitializingFormal,
+    "hasImplicitType": hasImplicitType,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedTypeRef get type {
+    _type ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 2, null);
+    return _type;
+  }
+
+  @override
+  List<UnlinkedParam> get parameters {
+    _parameters ??= const fb.ListReader<UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 3, const <UnlinkedParam>[]);
+    return _parameters;
+  }
+
+  @override
+  UnlinkedParamKind get kind {
+    _kind ??= UnlinkedParamKind.values[const fb.Int32Reader().vTableGet(_bp, 4, 0)];
+    return _kind;
+  }
+
+  @override
+  bool get isFunctionTyped {
+    _isFunctionTyped ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    return _isFunctionTyped;
+  }
+
+  @override
+  bool get isInitializingFormal {
+    _isInitializingFormal ??= const fb.BoolReader().vTableGet(_bp, 6, false);
+    return _isInitializingFormal;
+  }
+
+  @override
+  bool get hasImplicitType {
+    _hasImplicitType ??= const fb.BoolReader().vTableGet(_bp, 7, false);
+    return _hasImplicitType;
+  }
+}
+
+class UnlinkedPartBuilder {
+  bool _finished = false;
+
+  int _uriOffset;
+  int _uriEnd;
+
+  UnlinkedPartBuilder();
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  void set uriOffset(int _value) {
+    assert(!_finished);
+    _uriOffset = _value;
+  }
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  void set uriEnd(int _value) {
+    assert(!_finished);
+    _uriEnd = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fbBuilder.startTable();
+    if (_uriOffset != null && _uriOffset != 0) {
+      fbBuilder.addInt32(0, _uriOffset);
+    }
+    if (_uriEnd != null && _uriEnd != 0) {
+      fbBuilder.addInt32(1, _uriEnd);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedPartBuilder encodeUnlinkedPart({int uriOffset, int uriEnd}) {
+  UnlinkedPartBuilder builder = new UnlinkedPartBuilder();
+  builder.uriOffset = uriOffset;
+  builder.uriEnd = uriEnd;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a part declaration.
+ */
+abstract class UnlinkedPart extends base.SummaryClass {
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  int get uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  int get uriEnd;
+}
+
+class _UnlinkedPartReader extends fb.TableReader<_UnlinkedPartImpl> {
+  const _UnlinkedPartReader();
+
+  @override
+  _UnlinkedPartImpl createObject(fb.BufferPointer bp) => new _UnlinkedPartImpl(bp);
+}
+
+class _UnlinkedPartImpl implements UnlinkedPart {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedPartImpl(this._bp);
+
+  int _uriOffset;
+  int _uriEnd;
+
+  @override
+  Map<String, Object> toMap() => {
+    "uriOffset": uriOffset,
+    "uriEnd": uriEnd,
+  };
+
+  @override
+  int get uriOffset {
+    _uriOffset ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    return _uriOffset;
+  }
+
+  @override
+  int get uriEnd {
+    _uriEnd ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _uriEnd;
+  }
+}
+
+class UnlinkedPublicNameBuilder {
+  bool _finished = false;
+
+  String _name;
+  PrelinkedReferenceKind _kind;
+  int _numTypeParameters;
+
+  UnlinkedPublicNameBuilder();
+
+  /**
+   * The name itself.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * The kind of object referred to by the name.
+   */
+  void set kind(PrelinkedReferenceKind _value) {
+    assert(!_finished);
+    _kind = _value;
+  }
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  void set numTypeParameters(int _value) {
+    assert(!_finished);
+    _numTypeParameters = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_kind != null && _kind != PrelinkedReferenceKind.classOrEnum) {
+      fbBuilder.addInt32(1, _kind.index);
+    }
+    if (_numTypeParameters != null && _numTypeParameters != 0) {
+      fbBuilder.addInt32(2, _numTypeParameters);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedPublicNameBuilder encodeUnlinkedPublicName({String name, PrelinkedReferenceKind kind, int numTypeParameters}) {
+  UnlinkedPublicNameBuilder builder = new UnlinkedPublicNameBuilder();
+  builder.name = name;
+  builder.kind = kind;
+  builder.numTypeParameters = numTypeParameters;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a specific name contributed by a
+ * compilation unit to a library's public namespace.
+ *
+ * TODO(paulberry): add a count of generic parameters, so that resynthesis
+ * doesn't have to peek into the library to obtain this info.
+ *
+ * TODO(paulberry): for classes, add info about static members and
+ * constructors, since this will be needed to prelink info about constants.
+ *
+ * TODO(paulberry): some of this information is redundant with information
+ * elsewhere in the summary.  Consider reducing the redundancy to reduce
+ * summary size.
+ */
+abstract class UnlinkedPublicName extends base.SummaryClass {
+
+  /**
+   * The name itself.
+   */
+  String get name;
+
+  /**
+   * The kind of object referred to by the name.
+   */
+  PrelinkedReferenceKind get kind;
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  int get numTypeParameters;
+}
+
+class _UnlinkedPublicNameReader extends fb.TableReader<_UnlinkedPublicNameImpl> {
+  const _UnlinkedPublicNameReader();
+
+  @override
+  _UnlinkedPublicNameImpl createObject(fb.BufferPointer bp) => new _UnlinkedPublicNameImpl(bp);
+}
+
+class _UnlinkedPublicNameImpl implements UnlinkedPublicName {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedPublicNameImpl(this._bp);
+
+  String _name;
+  PrelinkedReferenceKind _kind;
+  int _numTypeParameters;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "kind": kind,
+    "numTypeParameters": numTypeParameters,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  PrelinkedReferenceKind get kind {
+    _kind ??= PrelinkedReferenceKind.values[const fb.Int32Reader().vTableGet(_bp, 1, 0)];
+    return _kind;
+  }
+
+  @override
+  int get numTypeParameters {
+    _numTypeParameters ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _numTypeParameters;
+  }
+}
+
+class UnlinkedPublicNamespaceBuilder {
+  bool _finished = false;
+
+  List<UnlinkedPublicNameBuilder> _names;
+  List<UnlinkedExportPublicBuilder> _exports;
+  List<String> _parts;
+
+  UnlinkedPublicNamespaceBuilder();
+
+  /**
+   * Public names defined in the compilation unit.
+   *
+   * TODO(paulberry): consider sorting these names to reduce unnecessary
+   * relinking.
+   */
+  void set names(List<UnlinkedPublicNameBuilder> _value) {
+    assert(!_finished);
+    _names = _value;
+  }
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  void set exports(List<UnlinkedExportPublicBuilder> _value) {
+    assert(!_finished);
+    _exports = _value;
+  }
+
+  /**
+   * URIs referenced by part declarations in the compilation unit.
+   */
+  void set parts(List<String> _value) {
+    assert(!_finished);
+    _parts = _value;
+  }
+
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = new fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder));
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_names;
+    fb.Offset offset_exports;
+    fb.Offset offset_parts;
+    if (!(_names == null || _names.isEmpty)) {
+      offset_names = fbBuilder.writeList(_names.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_exports == null || _exports.isEmpty)) {
+      offset_exports = fbBuilder.writeList(_exports.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_parts == null || _parts.isEmpty)) {
+      offset_parts = fbBuilder.writeList(_parts.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_names != null) {
+      fbBuilder.addOffset(0, offset_names);
+    }
+    if (offset_exports != null) {
+      fbBuilder.addOffset(1, offset_exports);
+    }
+    if (offset_parts != null) {
+      fbBuilder.addOffset(2, offset_parts);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedPublicNamespaceBuilder encodeUnlinkedPublicNamespace({List<UnlinkedPublicNameBuilder> names, List<UnlinkedExportPublicBuilder> exports, List<String> parts}) {
+  UnlinkedPublicNamespaceBuilder builder = new UnlinkedPublicNamespaceBuilder();
+  builder.names = names;
+  builder.exports = exports;
+  builder.parts = parts;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about what a compilation unit contributes to a
+ * library's public namespace.  This is the subset of [UnlinkedUnit] that is
+ * required from dependent libraries in order to perform prelinking.
+ */
+abstract class UnlinkedPublicNamespace extends base.SummaryClass {
+  factory UnlinkedPublicNamespace.fromBuffer(List<int> buffer) {
+    fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
+    return const _UnlinkedPublicNamespaceReader().read(rootRef);
+  }
+
+  /**
+   * Public names defined in the compilation unit.
+   *
+   * TODO(paulberry): consider sorting these names to reduce unnecessary
+   * relinking.
+   */
+  List<UnlinkedPublicName> get names;
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  List<UnlinkedExportPublic> get exports;
+
+  /**
+   * URIs referenced by part declarations in the compilation unit.
+   */
+  List<String> get parts;
+}
+
+class _UnlinkedPublicNamespaceReader extends fb.TableReader<_UnlinkedPublicNamespaceImpl> {
+  const _UnlinkedPublicNamespaceReader();
+
+  @override
+  _UnlinkedPublicNamespaceImpl createObject(fb.BufferPointer bp) => new _UnlinkedPublicNamespaceImpl(bp);
+}
+
+class _UnlinkedPublicNamespaceImpl implements UnlinkedPublicNamespace {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedPublicNamespaceImpl(this._bp);
+
+  List<UnlinkedPublicName> _names;
+  List<UnlinkedExportPublic> _exports;
+  List<String> _parts;
+
+  @override
+  Map<String, Object> toMap() => {
+    "names": names,
+    "exports": exports,
+    "parts": parts,
+  };
+
+  @override
+  List<UnlinkedPublicName> get names {
+    _names ??= const fb.ListReader<UnlinkedPublicName>(const _UnlinkedPublicNameReader()).vTableGet(_bp, 0, const <UnlinkedPublicName>[]);
+    return _names;
+  }
+
+  @override
+  List<UnlinkedExportPublic> get exports {
+    _exports ??= const fb.ListReader<UnlinkedExportPublic>(const _UnlinkedExportPublicReader()).vTableGet(_bp, 1, const <UnlinkedExportPublic>[]);
+    return _exports;
+  }
+
+  @override
+  List<String> get parts {
+    _parts ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 2, const <String>[]);
+    return _parts;
+  }
+}
+
+class UnlinkedReferenceBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _prefixReference;
+
+  UnlinkedReferenceBuilder();
+
+  /**
+   * Name of the entity being referred to.  The empty string refers to the
+   * pseudo-type `dynamic`.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Prefix used to refer to the entity, or zero if no prefix is used.  This is
+   * an index into [UnlinkedUnit.references].
+   *
+   * Prefix references must always point backward; that is, for all i, if
+   * UnlinkedUnit.references[i].prefixReference != 0, then
+   * UnlinkedUnit.references[i].prefixReference < i.
+   */
+  void set prefixReference(int _value) {
+    assert(!_finished);
+    _prefixReference = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_prefixReference != null && _prefixReference != 0) {
+      fbBuilder.addInt32(1, _prefixReference);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedReferenceBuilder encodeUnlinkedReference({String name, int prefixReference}) {
+  UnlinkedReferenceBuilder builder = new UnlinkedReferenceBuilder();
+  builder.name = name;
+  builder.prefixReference = prefixReference;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a name referred to in one library that
+ * might be defined in another.
+ */
+abstract class UnlinkedReference extends base.SummaryClass {
+
+  /**
+   * Name of the entity being referred to.  The empty string refers to the
+   * pseudo-type `dynamic`.
+   */
+  String get name;
+
+  /**
+   * Prefix used to refer to the entity, or zero if no prefix is used.  This is
+   * an index into [UnlinkedUnit.references].
+   *
+   * Prefix references must always point backward; that is, for all i, if
+   * UnlinkedUnit.references[i].prefixReference != 0, then
+   * UnlinkedUnit.references[i].prefixReference < i.
+   */
+  int get prefixReference;
+}
+
+class _UnlinkedReferenceReader extends fb.TableReader<_UnlinkedReferenceImpl> {
+  const _UnlinkedReferenceReader();
+
+  @override
+  _UnlinkedReferenceImpl createObject(fb.BufferPointer bp) => new _UnlinkedReferenceImpl(bp);
+}
+
+class _UnlinkedReferenceImpl implements UnlinkedReference {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedReferenceImpl(this._bp);
+
+  String _name;
+  int _prefixReference;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "prefixReference": prefixReference,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get prefixReference {
+    _prefixReference ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _prefixReference;
+  }
+}
+
+class UnlinkedTypedefBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  List<UnlinkedTypeParamBuilder> _typeParameters;
+  UnlinkedTypeRefBuilder _returnType;
+  List<UnlinkedParamBuilder> _parameters;
+
+  UnlinkedTypedefBuilder();
+
+  /**
+   * Name of the typedef.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Offset of the typedef name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the typedef, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
+  }
+
+  /**
+   * Type parameters of the typedef, if any.
+   */
+  void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
+    assert(!_finished);
+    _typeParameters = _value;
+  }
+
+  /**
+   * Return type of the typedef.  Absent if the return type is `void`.
+   */
+  void set returnType(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
+    _returnType = _value;
+  }
+
+  /**
+   * Parameters of the executable, if any.
+   */
+  void set parameters(List<UnlinkedParamBuilder> _value) {
+    assert(!_finished);
+    _parameters = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_typeParameters;
+    fb.Offset offset_returnType;
+    fb.Offset offset_parameters;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (!(_typeParameters == null || _typeParameters.isEmpty)) {
+      offset_typeParameters = fbBuilder.writeList(_typeParameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (_returnType != null) {
+      offset_returnType = _returnType.finish(fbBuilder);
+    }
+    if (!(_parameters == null || _parameters.isEmpty)) {
+      offset_parameters = fbBuilder.writeList(_parameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_typeParameters != null) {
+      fbBuilder.addOffset(3, offset_typeParameters);
+    }
+    if (offset_returnType != null) {
+      fbBuilder.addOffset(4, offset_returnType);
+    }
+    if (offset_parameters != null) {
+      fbBuilder.addOffset(5, offset_parameters);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedTypedefBuilder encodeUnlinkedTypedef({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters}) {
+  UnlinkedTypedefBuilder builder = new UnlinkedTypedefBuilder();
+  builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
+  builder.typeParameters = typeParameters;
+  builder.returnType = returnType;
+  builder.parameters = parameters;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a typedef declaration.
+ */
+abstract class UnlinkedTypedef extends base.SummaryClass {
+
+  /**
+   * Name of the typedef.
+   */
+  String get name;
+
+  /**
+   * Offset of the typedef name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the typedef, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Type parameters of the typedef, if any.
+   */
+  List<UnlinkedTypeParam> get typeParameters;
+
+  /**
+   * Return type of the typedef.  Absent if the return type is `void`.
+   */
+  UnlinkedTypeRef get returnType;
+
+  /**
+   * Parameters of the executable, if any.
+   */
+  List<UnlinkedParam> get parameters;
+}
+
+class _UnlinkedTypedefReader extends fb.TableReader<_UnlinkedTypedefImpl> {
+  const _UnlinkedTypedefReader();
+
+  @override
+  _UnlinkedTypedefImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypedefImpl(bp);
+}
+
+class _UnlinkedTypedefImpl implements UnlinkedTypedef {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedTypedefImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  List<UnlinkedTypeParam> _typeParameters;
+  UnlinkedTypeRef _returnType;
+  List<UnlinkedParam> _parameters;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "typeParameters": typeParameters,
+    "returnType": returnType,
+    "parameters": parameters,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  List<UnlinkedTypeParam> get typeParameters {
+    _typeParameters ??= const fb.ListReader<UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bp, 3, const <UnlinkedTypeParam>[]);
+    return _typeParameters;
+  }
+
+  @override
+  UnlinkedTypeRef get returnType {
+    _returnType ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 4, null);
+    return _returnType;
+  }
+
+  @override
+  List<UnlinkedParam> get parameters {
+    _parameters ??= const fb.ListReader<UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 5, const <UnlinkedParam>[]);
+    return _parameters;
+  }
+}
+
+class UnlinkedTypeParamBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _nameOffset;
+  UnlinkedTypeRefBuilder _bound;
+
+  UnlinkedTypeParamBuilder();
+
+  /**
+   * Name of the type parameter.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Offset of the type parameter name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Bound of the type parameter, if a bound is explicitly declared.  Otherwise
+   * null.
+   */
+  void set bound(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
+    _bound = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    fb.Offset offset_bound;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_bound != null) {
+      offset_bound = _bound.finish(fbBuilder);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_bound != null) {
+      fbBuilder.addOffset(2, offset_bound);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedTypeParamBuilder encodeUnlinkedTypeParam({String name, int nameOffset, UnlinkedTypeRefBuilder bound}) {
+  UnlinkedTypeParamBuilder builder = new UnlinkedTypeParamBuilder();
+  builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.bound = bound;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a type parameter declaration.
+ */
+abstract class UnlinkedTypeParam extends base.SummaryClass {
+
+  /**
+   * Name of the type parameter.
+   */
+  String get name;
+
+  /**
+   * Offset of the type parameter name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Bound of the type parameter, if a bound is explicitly declared.  Otherwise
+   * null.
+   */
+  UnlinkedTypeRef get bound;
+}
+
+class _UnlinkedTypeParamReader extends fb.TableReader<_UnlinkedTypeParamImpl> {
+  const _UnlinkedTypeParamReader();
+
+  @override
+  _UnlinkedTypeParamImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypeParamImpl(bp);
+}
+
+class _UnlinkedTypeParamImpl implements UnlinkedTypeParam {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedTypeParamImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedTypeRef _bound;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "bound": bound,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedTypeRef get bound {
+    _bound ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 2, null);
+    return _bound;
+  }
+}
+
+class UnlinkedTypeRefBuilder {
+  bool _finished = false;
+
+  int _reference;
+  int _paramReference;
+  List<UnlinkedTypeRefBuilder> _typeArguments;
+
+  UnlinkedTypeRefBuilder();
+
+  /**
+   * Index into [UnlinkedUnit.references] for the type being referred to, or
+   * zero if this is a reference to a type parameter.
+   *
+   * Note that since zero is also a valid index into
+   * [UnlinkedUnit.references], we cannot distinguish between references to
+   * type parameters and references to types by checking [reference] against
+   * zero.  To distinguish between references to type parameters and references
+   * to types, check whether [paramReference] is zero.
+   */
+  void set reference(int _value) {
+    assert(!_finished);
+    _reference = _value;
+  }
+
+  /**
+   * If this is a reference to a type parameter, one-based index into the list
+   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
+   * Bruijn index conventions; that is, innermost parameters come first, and
+   * if a class or method has multiple parameters, they are indexed from right
+   * to left.  So for instance, if the enclosing declaration is
+   *
+   *     class C<T,U> {
+   *       m<V,W> {
+   *         ...
+   *       }
+   *     }
+   *
+   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
+   * respectively.
+   *
+   * If the type being referred to is not a type parameter, [paramReference] is
+   * zero.
+   */
+  void set paramReference(int _value) {
+    assert(!_finished);
+    _paramReference = _value;
+  }
+
+  /**
+   * If this is an instantiation of a generic type, the type arguments used to
+   * instantiate it.  Trailing type arguments of type `dynamic` are omitted.
+   */
+  void set typeArguments(List<UnlinkedTypeRefBuilder> _value) {
+    assert(!_finished);
+    _typeArguments = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_typeArguments;
+    if (!(_typeArguments == null || _typeArguments.isEmpty)) {
+      offset_typeArguments = fbBuilder.writeList(_typeArguments.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (_reference != null && _reference != 0) {
+      fbBuilder.addInt32(0, _reference);
+    }
+    if (_paramReference != null && _paramReference != 0) {
+      fbBuilder.addInt32(1, _paramReference);
+    }
+    if (offset_typeArguments != null) {
+      fbBuilder.addOffset(2, offset_typeArguments);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedTypeRefBuilder encodeUnlinkedTypeRef({int reference, int paramReference, List<UnlinkedTypeRefBuilder> typeArguments}) {
+  UnlinkedTypeRefBuilder builder = new UnlinkedTypeRefBuilder();
+  builder.reference = reference;
+  builder.paramReference = paramReference;
+  builder.typeArguments = typeArguments;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a reference to a type.
+ */
+abstract class UnlinkedTypeRef extends base.SummaryClass {
+
+  /**
+   * Index into [UnlinkedUnit.references] for the type being referred to, or
+   * zero if this is a reference to a type parameter.
+   *
+   * Note that since zero is also a valid index into
+   * [UnlinkedUnit.references], we cannot distinguish between references to
+   * type parameters and references to types by checking [reference] against
+   * zero.  To distinguish between references to type parameters and references
+   * to types, check whether [paramReference] is zero.
+   */
+  int get reference;
+
+  /**
+   * If this is a reference to a type parameter, one-based index into the list
+   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
+   * Bruijn index conventions; that is, innermost parameters come first, and
+   * if a class or method has multiple parameters, they are indexed from right
+   * to left.  So for instance, if the enclosing declaration is
+   *
+   *     class C<T,U> {
+   *       m<V,W> {
+   *         ...
+   *       }
+   *     }
+   *
+   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
+   * respectively.
+   *
+   * If the type being referred to is not a type parameter, [paramReference] is
+   * zero.
+   */
+  int get paramReference;
+
+  /**
+   * If this is an instantiation of a generic type, the type arguments used to
+   * instantiate it.  Trailing type arguments of type `dynamic` are omitted.
+   */
+  List<UnlinkedTypeRef> get typeArguments;
+}
+
+class _UnlinkedTypeRefReader extends fb.TableReader<_UnlinkedTypeRefImpl> {
+  const _UnlinkedTypeRefReader();
+
+  @override
+  _UnlinkedTypeRefImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypeRefImpl(bp);
+}
+
+class _UnlinkedTypeRefImpl implements UnlinkedTypeRef {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedTypeRefImpl(this._bp);
+
+  int _reference;
+  int _paramReference;
+  List<UnlinkedTypeRef> _typeArguments;
+
+  @override
+  Map<String, Object> toMap() => {
+    "reference": reference,
+    "paramReference": paramReference,
+    "typeArguments": typeArguments,
+  };
+
+  @override
+  int get reference {
+    _reference ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    return _reference;
+  }
+
+  @override
+  int get paramReference {
+    _paramReference ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _paramReference;
+  }
+
+  @override
+  List<UnlinkedTypeRef> get typeArguments {
+    _typeArguments ??= const fb.ListReader<UnlinkedTypeRef>(const _UnlinkedTypeRefReader()).vTableGet(_bp, 2, const <UnlinkedTypeRef>[]);
+    return _typeArguments;
+  }
+}
+
+class UnlinkedUnitBuilder {
+  bool _finished = false;
+
+  String _libraryName;
+  int _libraryNameOffset;
+  int _libraryNameLength;
+  UnlinkedDocumentationCommentBuilder _libraryDocumentationComment;
+  UnlinkedPublicNamespaceBuilder _publicNamespace;
+  List<UnlinkedReferenceBuilder> _references;
+  List<UnlinkedClassBuilder> _classes;
+  List<UnlinkedEnumBuilder> _enums;
+  List<UnlinkedExecutableBuilder> _executables;
+  List<UnlinkedExportNonPublicBuilder> _exports;
+  List<UnlinkedImportBuilder> _imports;
+  List<UnlinkedPartBuilder> _parts;
+  List<UnlinkedTypedefBuilder> _typedefs;
+  List<UnlinkedVariableBuilder> _variables;
+
+  UnlinkedUnitBuilder();
+
+  /**
+   * Name of the library (from a "library" declaration, if present).
+   */
+  void set libraryName(String _value) {
+    assert(!_finished);
+    _libraryName = _value;
+  }
+
+  /**
+   * Offset of the library name relative to the beginning of the file (or 0 if
+   * the library has no name).
+   */
+  void set libraryNameOffset(int _value) {
+    assert(!_finished);
+    _libraryNameOffset = _value;
+  }
+
+  /**
+   * Length of the library name as it appears in the source code (or 0 if the
+   * library has no name).
+   */
+  void set libraryNameLength(int _value) {
+    assert(!_finished);
+    _libraryNameLength = _value;
+  }
+
+  /**
+   * Documentation comment for the library, or `null` if there is no
+   * documentation comment.
+   */
+  void set libraryDocumentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _libraryDocumentationComment = _value;
+  }
+
+  /**
+   * Unlinked public namespace of this compilation unit.
+   */
+  void set publicNamespace(UnlinkedPublicNamespaceBuilder _value) {
+    assert(!_finished);
+    _publicNamespace = _value;
+  }
+
+  /**
+   * Top level and prefixed names referred to by this compilation unit.  The
+   * zeroth element of this array is always populated and always represents a
+   * reference to the pseudo-type "dynamic".
+   */
+  void set references(List<UnlinkedReferenceBuilder> _value) {
+    assert(!_finished);
+    _references = _value;
+  }
+
+  /**
+   * Classes declared in the compilation unit.
+   */
+  void set classes(List<UnlinkedClassBuilder> _value) {
+    assert(!_finished);
+    _classes = _value;
+  }
+
+  /**
+   * Enums declared in the compilation unit.
+   */
+  void set enums(List<UnlinkedEnumBuilder> _value) {
+    assert(!_finished);
+    _enums = _value;
+  }
+
+  /**
+   * Top level executable objects (functions, getters, and setters) declared in
+   * the compilation unit.
+   */
+  void set executables(List<UnlinkedExecutableBuilder> _value) {
+    assert(!_finished);
+    _executables = _value;
+  }
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  void set exports(List<UnlinkedExportNonPublicBuilder> _value) {
+    assert(!_finished);
+    _exports = _value;
+  }
+
+  /**
+   * Import declarations in the compilation unit.
+   */
+  void set imports(List<UnlinkedImportBuilder> _value) {
+    assert(!_finished);
+    _imports = _value;
+  }
+
+  /**
+   * Part declarations in the compilation unit.
+   */
+  void set parts(List<UnlinkedPartBuilder> _value) {
+    assert(!_finished);
+    _parts = _value;
+  }
+
+  /**
+   * Typedefs declared in the compilation unit.
+   */
+  void set typedefs(List<UnlinkedTypedefBuilder> _value) {
+    assert(!_finished);
+    _typedefs = _value;
+  }
+
+  /**
+   * Top level variables declared in the compilation unit.
+   */
+  void set variables(List<UnlinkedVariableBuilder> _value) {
+    assert(!_finished);
+    _variables = _value;
+  }
+
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = new fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder));
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_libraryName;
+    fb.Offset offset_libraryDocumentationComment;
+    fb.Offset offset_publicNamespace;
+    fb.Offset offset_references;
+    fb.Offset offset_classes;
+    fb.Offset offset_enums;
+    fb.Offset offset_executables;
+    fb.Offset offset_exports;
+    fb.Offset offset_imports;
+    fb.Offset offset_parts;
+    fb.Offset offset_typedefs;
+    fb.Offset offset_variables;
+    if (_libraryName != null) {
+      offset_libraryName = fbBuilder.writeString(_libraryName);
+    }
+    if (_libraryDocumentationComment != null) {
+      offset_libraryDocumentationComment = _libraryDocumentationComment.finish(fbBuilder);
+    }
+    if (_publicNamespace != null) {
+      offset_publicNamespace = _publicNamespace.finish(fbBuilder);
+    }
+    if (!(_references == null || _references.isEmpty)) {
+      offset_references = fbBuilder.writeList(_references.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_classes == null || _classes.isEmpty)) {
+      offset_classes = fbBuilder.writeList(_classes.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_enums == null || _enums.isEmpty)) {
+      offset_enums = fbBuilder.writeList(_enums.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_executables == null || _executables.isEmpty)) {
+      offset_executables = fbBuilder.writeList(_executables.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_exports == null || _exports.isEmpty)) {
+      offset_exports = fbBuilder.writeList(_exports.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_imports == null || _imports.isEmpty)) {
+      offset_imports = fbBuilder.writeList(_imports.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_parts == null || _parts.isEmpty)) {
+      offset_parts = fbBuilder.writeList(_parts.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_typedefs == null || _typedefs.isEmpty)) {
+      offset_typedefs = fbBuilder.writeList(_typedefs.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_variables == null || _variables.isEmpty)) {
+      offset_variables = fbBuilder.writeList(_variables.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_libraryName != null) {
+      fbBuilder.addOffset(0, offset_libraryName);
+    }
+    if (_libraryNameOffset != null && _libraryNameOffset != 0) {
+      fbBuilder.addInt32(1, _libraryNameOffset);
+    }
+    if (_libraryNameLength != null && _libraryNameLength != 0) {
+      fbBuilder.addInt32(2, _libraryNameLength);
+    }
+    if (offset_libraryDocumentationComment != null) {
+      fbBuilder.addOffset(3, offset_libraryDocumentationComment);
+    }
+    if (offset_publicNamespace != null) {
+      fbBuilder.addOffset(4, offset_publicNamespace);
+    }
+    if (offset_references != null) {
+      fbBuilder.addOffset(5, offset_references);
+    }
+    if (offset_classes != null) {
+      fbBuilder.addOffset(6, offset_classes);
+    }
+    if (offset_enums != null) {
+      fbBuilder.addOffset(7, offset_enums);
+    }
+    if (offset_executables != null) {
+      fbBuilder.addOffset(8, offset_executables);
+    }
+    if (offset_exports != null) {
+      fbBuilder.addOffset(9, offset_exports);
+    }
+    if (offset_imports != null) {
+      fbBuilder.addOffset(10, offset_imports);
+    }
+    if (offset_parts != null) {
+      fbBuilder.addOffset(11, offset_parts);
+    }
+    if (offset_typedefs != null) {
+      fbBuilder.addOffset(12, offset_typedefs);
+    }
+    if (offset_variables != null) {
+      fbBuilder.addOffset(13, offset_variables);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedUnitBuilder encodeUnlinkedUnit({String libraryName, int libraryNameOffset, int libraryNameLength, UnlinkedDocumentationCommentBuilder libraryDocumentationComment, UnlinkedPublicNamespaceBuilder publicNamespace, List<UnlinkedReferenceBuilder> references, List<UnlinkedClassBuilder> classes, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportNonPublicBuilder> exports, List<UnlinkedImportBuilder> imports, List<UnlinkedPartBuilder> parts, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables}) {
+  UnlinkedUnitBuilder builder = new UnlinkedUnitBuilder();
+  builder.libraryName = libraryName;
+  builder.libraryNameOffset = libraryNameOffset;
+  builder.libraryNameLength = libraryNameLength;
+  builder.libraryDocumentationComment = libraryDocumentationComment;
+  builder.publicNamespace = publicNamespace;
+  builder.references = references;
+  builder.classes = classes;
+  builder.enums = enums;
+  builder.executables = executables;
+  builder.exports = exports;
+  builder.imports = imports;
+  builder.parts = parts;
+  builder.typedefs = typedefs;
+  builder.variables = variables;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a compilation unit ("part file").
+ */
+abstract class UnlinkedUnit extends base.SummaryClass {
+  factory UnlinkedUnit.fromBuffer(List<int> buffer) {
+    fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
+    return const _UnlinkedUnitReader().read(rootRef);
+  }
+
+  /**
+   * Name of the library (from a "library" declaration, if present).
+   */
+  String get libraryName;
+
+  /**
+   * Offset of the library name relative to the beginning of the file (or 0 if
+   * the library has no name).
+   */
+  int get libraryNameOffset;
+
+  /**
+   * Length of the library name as it appears in the source code (or 0 if the
+   * library has no name).
+   */
+  int get libraryNameLength;
+
+  /**
+   * Documentation comment for the library, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get libraryDocumentationComment;
+
+  /**
+   * Unlinked public namespace of this compilation unit.
+   */
+  UnlinkedPublicNamespace get publicNamespace;
+
+  /**
+   * Top level and prefixed names referred to by this compilation unit.  The
+   * zeroth element of this array is always populated and always represents a
+   * reference to the pseudo-type "dynamic".
+   */
+  List<UnlinkedReference> get references;
+
+  /**
+   * Classes declared in the compilation unit.
+   */
+  List<UnlinkedClass> get classes;
+
+  /**
+   * Enums declared in the compilation unit.
+   */
+  List<UnlinkedEnum> get enums;
+
+  /**
+   * Top level executable objects (functions, getters, and setters) declared in
+   * the compilation unit.
+   */
+  List<UnlinkedExecutable> get executables;
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  List<UnlinkedExportNonPublic> get exports;
+
+  /**
+   * Import declarations in the compilation unit.
+   */
+  List<UnlinkedImport> get imports;
+
+  /**
+   * Part declarations in the compilation unit.
+   */
+  List<UnlinkedPart> get parts;
+
+  /**
+   * Typedefs declared in the compilation unit.
+   */
+  List<UnlinkedTypedef> get typedefs;
+
+  /**
+   * Top level variables declared in the compilation unit.
+   */
+  List<UnlinkedVariable> get variables;
+}
+
+class _UnlinkedUnitReader extends fb.TableReader<_UnlinkedUnitImpl> {
+  const _UnlinkedUnitReader();
+
+  @override
+  _UnlinkedUnitImpl createObject(fb.BufferPointer bp) => new _UnlinkedUnitImpl(bp);
+}
+
+class _UnlinkedUnitImpl implements UnlinkedUnit {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedUnitImpl(this._bp);
+
+  String _libraryName;
+  int _libraryNameOffset;
+  int _libraryNameLength;
+  UnlinkedDocumentationComment _libraryDocumentationComment;
+  UnlinkedPublicNamespace _publicNamespace;
+  List<UnlinkedReference> _references;
+  List<UnlinkedClass> _classes;
+  List<UnlinkedEnum> _enums;
+  List<UnlinkedExecutable> _executables;
+  List<UnlinkedExportNonPublic> _exports;
+  List<UnlinkedImport> _imports;
+  List<UnlinkedPart> _parts;
+  List<UnlinkedTypedef> _typedefs;
+  List<UnlinkedVariable> _variables;
+
+  @override
+  Map<String, Object> toMap() => {
+    "libraryName": libraryName,
+    "libraryNameOffset": libraryNameOffset,
+    "libraryNameLength": libraryNameLength,
+    "libraryDocumentationComment": libraryDocumentationComment,
+    "publicNamespace": publicNamespace,
+    "references": references,
+    "classes": classes,
+    "enums": enums,
+    "executables": executables,
+    "exports": exports,
+    "imports": imports,
+    "parts": parts,
+    "typedefs": typedefs,
+    "variables": variables,
+  };
+
+  @override
+  String get libraryName {
+    _libraryName ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _libraryName;
+  }
+
+  @override
+  int get libraryNameOffset {
+    _libraryNameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _libraryNameOffset;
+  }
+
+  @override
+  int get libraryNameLength {
+    _libraryNameLength ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    return _libraryNameLength;
+  }
+
+  @override
+  UnlinkedDocumentationComment get libraryDocumentationComment {
+    _libraryDocumentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 3, null);
+    return _libraryDocumentationComment;
+  }
+
+  @override
+  UnlinkedPublicNamespace get publicNamespace {
+    _publicNamespace ??= const _UnlinkedPublicNamespaceReader().vTableGet(_bp, 4, null);
+    return _publicNamespace;
+  }
+
+  @override
+  List<UnlinkedReference> get references {
+    _references ??= const fb.ListReader<UnlinkedReference>(const _UnlinkedReferenceReader()).vTableGet(_bp, 5, const <UnlinkedReference>[]);
+    return _references;
+  }
+
+  @override
+  List<UnlinkedClass> get classes {
+    _classes ??= const fb.ListReader<UnlinkedClass>(const _UnlinkedClassReader()).vTableGet(_bp, 6, const <UnlinkedClass>[]);
+    return _classes;
+  }
+
+  @override
+  List<UnlinkedEnum> get enums {
+    _enums ??= const fb.ListReader<UnlinkedEnum>(const _UnlinkedEnumReader()).vTableGet(_bp, 7, const <UnlinkedEnum>[]);
+    return _enums;
+  }
+
+  @override
+  List<UnlinkedExecutable> get executables {
+    _executables ??= const fb.ListReader<UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bp, 8, const <UnlinkedExecutable>[]);
+    return _executables;
+  }
+
+  @override
+  List<UnlinkedExportNonPublic> get exports {
+    _exports ??= const fb.ListReader<UnlinkedExportNonPublic>(const _UnlinkedExportNonPublicReader()).vTableGet(_bp, 9, const <UnlinkedExportNonPublic>[]);
+    return _exports;
+  }
+
+  @override
+  List<UnlinkedImport> get imports {
+    _imports ??= const fb.ListReader<UnlinkedImport>(const _UnlinkedImportReader()).vTableGet(_bp, 10, const <UnlinkedImport>[]);
+    return _imports;
+  }
+
+  @override
+  List<UnlinkedPart> get parts {
+    _parts ??= const fb.ListReader<UnlinkedPart>(const _UnlinkedPartReader()).vTableGet(_bp, 11, const <UnlinkedPart>[]);
+    return _parts;
+  }
+
+  @override
+  List<UnlinkedTypedef> get typedefs {
+    _typedefs ??= const fb.ListReader<UnlinkedTypedef>(const _UnlinkedTypedefReader()).vTableGet(_bp, 12, const <UnlinkedTypedef>[]);
+    return _typedefs;
+  }
+
+  @override
+  List<UnlinkedVariable> get variables {
+    _variables ??= const fb.ListReader<UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bp, 13, const <UnlinkedVariable>[]);
+    return _variables;
+  }
+}
+
+class UnlinkedVariableBuilder {
+  bool _finished = false;
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  UnlinkedTypeRefBuilder _type;
+  bool _isStatic;
+  bool _isFinal;
+  bool _isConst;
+  bool _hasImplicitType;
+
+  UnlinkedVariableBuilder();
+
+  /**
+   * Name of the variable.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  /**
+   * Offset of the variable name relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    _nameOffset = _value;
+  }
+
+  /**
+   * Documentation comment for the variable, or `null` if there is no
+   * documentation comment.
+   */
+  void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
+    assert(!_finished);
+    _documentationComment = _value;
+  }
+
+  /**
+   * Declared type of the variable.  Note that when strong mode is enabled, the
+   * actual type of the variable may be different due to type inference.
+   */
+  void set type(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
+    _type = _value;
+  }
+
+  /**
+   * Indicates whether the variable is declared using the `static` keyword.
+   *
+   * Note that for top level variables, this flag is false, since they are not
+   * declared using the `static` keyword (even though they are considered
+   * static for semantic purposes).
+   */
+  void set isStatic(bool _value) {
+    assert(!_finished);
+    _isStatic = _value;
+  }
+
+  /**
+   * Indicates whether the variable is declared using the `final` keyword.
+   */
+  void set isFinal(bool _value) {
+    assert(!_finished);
+    _isFinal = _value;
+  }
+
+  /**
+   * Indicates whether the variable is declared using the `const` keyword.
+   */
+  void set isConst(bool _value) {
+    assert(!_finished);
+    _isConst = _value;
+  }
+
+  /**
+   * Indicates whether this variable lacks an explicit type declaration.
+   */
+  void set hasImplicitType(bool _value) {
+    assert(!_finished);
+    _hasImplicitType = _value;
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_type;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (_type != null) {
+      offset_type = _type.finish(fbBuilder);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addInt32(1, _nameOffset);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(2, offset_documentationComment);
+    }
+    if (offset_type != null) {
+      fbBuilder.addOffset(3, offset_type);
+    }
+    if (_isStatic == true) {
+      fbBuilder.addBool(4, true);
+    }
+    if (_isFinal == true) {
+      fbBuilder.addBool(5, true);
+    }
+    if (_isConst == true) {
+      fbBuilder.addBool(6, true);
+    }
+    if (_hasImplicitType == true) {
+      fbBuilder.addBool(7, true);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+UnlinkedVariableBuilder encodeUnlinkedVariable({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, UnlinkedTypeRefBuilder type, bool isStatic, bool isFinal, bool isConst, bool hasImplicitType}) {
+  UnlinkedVariableBuilder builder = new UnlinkedVariableBuilder();
+  builder.name = name;
+  builder.nameOffset = nameOffset;
+  builder.documentationComment = documentationComment;
+  builder.type = type;
+  builder.isStatic = isStatic;
+  builder.isFinal = isFinal;
+  builder.isConst = isConst;
+  builder.hasImplicitType = hasImplicitType;
+  return builder;
+}
+
+/**
+ * Unlinked summary information about a top level variable, local variable, or
+ * a field.
+ */
+abstract class UnlinkedVariable extends base.SummaryClass {
+
+  /**
+   * Name of the variable.
+   */
+  String get name;
+
+  /**
+   * Offset of the variable name relative to the beginning of the file.
+   */
+  int get nameOffset;
+
+  /**
+   * Documentation comment for the variable, or `null` if there is no
+   * documentation comment.
+   */
+  UnlinkedDocumentationComment get documentationComment;
+
+  /**
+   * Declared type of the variable.  Note that when strong mode is enabled, the
+   * actual type of the variable may be different due to type inference.
+   */
+  UnlinkedTypeRef get type;
+
+  /**
+   * Indicates whether the variable is declared using the `static` keyword.
+   *
+   * Note that for top level variables, this flag is false, since they are not
+   * declared using the `static` keyword (even though they are considered
+   * static for semantic purposes).
+   */
+  bool get isStatic;
+
+  /**
+   * Indicates whether the variable is declared using the `final` keyword.
+   */
+  bool get isFinal;
+
+  /**
+   * Indicates whether the variable is declared using the `const` keyword.
+   */
+  bool get isConst;
+
+  /**
+   * Indicates whether this variable lacks an explicit type declaration.
+   */
+  bool get hasImplicitType;
+}
+
+class _UnlinkedVariableReader extends fb.TableReader<_UnlinkedVariableImpl> {
+  const _UnlinkedVariableReader();
+
+  @override
+  _UnlinkedVariableImpl createObject(fb.BufferPointer bp) => new _UnlinkedVariableImpl(bp);
+}
+
+class _UnlinkedVariableImpl implements UnlinkedVariable {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedVariableImpl(this._bp);
+
+  String _name;
+  int _nameOffset;
+  UnlinkedDocumentationComment _documentationComment;
+  UnlinkedTypeRef _type;
+  bool _isStatic;
+  bool _isFinal;
+  bool _isConst;
+  bool _hasImplicitType;
+
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "type": type,
+    "isStatic": isStatic,
+    "isFinal": isFinal,
+    "isConst": isConst,
+    "hasImplicitType": hasImplicitType,
+  };
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    return _documentationComment;
+  }
+
+  @override
+  UnlinkedTypeRef get type {
+    _type ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 3, null);
+    return _type;
+  }
+
+  @override
+  bool get isStatic {
+    _isStatic ??= const fb.BoolReader().vTableGet(_bp, 4, false);
+    return _isStatic;
+  }
+
+  @override
+  bool get isFinal {
+    _isFinal ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    return _isFinal;
+  }
+
+  @override
+  bool get isConst {
+    _isConst ??= const fb.BoolReader().vTableGet(_bp, 6, false);
+    return _isConst;
+  }
+
+  @override
+  bool get hasImplicitType {
+    _hasImplicitType ??= const fb.BoolReader().vTableGet(_bp, 7, false);
+    return _hasImplicitType;
+  }
+}
+
diff --git a/pkg/analyzer/lib/src/summary/name_filter.dart b/pkg/analyzer/lib/src/summary/name_filter.dart
new file mode 100644
index 0000000..7b130ec
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/name_filter.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/summary/format.dart';
+
+/**
+ * A [NameFilter] represents the set of filtering rules implied by zero or more
+ * combinators in an `export` or `import` statement.
+ */
+class NameFilter {
+  /**
+   * A [NameFilter] representing no filtering at all (i.e. no combinators).
+   */
+  static final NameFilter identity =
+      new NameFilter._(hiddenNames: new Set<String>());
+
+  /**
+   * If this [NameFilter] accepts a finite number of names and hides all
+   * others, the (possibly empty) set of names it accepts.  Otherwise `null`.
+   */
+  final Set<String> shownNames;
+
+  /**
+   * If [shownNames] is `null`, the (possibly empty) set of names not accepted
+   * by this filter (all other names are accepted).  If [shownNames] is not
+   * `null`, then [hiddenNames] will be `null`.
+   */
+  final Set<String> hiddenNames;
+
+  /**
+   * Create a [NameFilter] based on the given [combinator].
+   */
+  factory NameFilter.forNamespaceCombinator(NamespaceCombinator combinator) {
+    if (combinator is ShowElementCombinator) {
+      return new NameFilter._(shownNames: combinator.shownNames.toSet());
+    } else if (combinator is HideElementCombinator) {
+      return new NameFilter._(hiddenNames: combinator.hiddenNames.toSet());
+    } else {
+      throw new StateError(
+          'Unexpected combinator type ${combinator.runtimeType}');
+    }
+  }
+
+  /**
+   * Create a [NameFilter] based on the given (possibly empty) sequence of
+   * [combinators].
+   */
+  factory NameFilter.forNamespaceCombinators(
+      List<NamespaceCombinator> combinators) {
+    NameFilter result = identity;
+    for (NamespaceCombinator combinator in combinators) {
+      result = result.merge(new NameFilter.forNamespaceCombinator(combinator));
+    }
+    return result;
+  }
+
+  /**
+   * Create a [NameFilter] based on the given [combinator].
+   */
+  factory NameFilter.forUnlinkedCombinator(UnlinkedCombinator combinator) {
+    if (combinator.shows.isNotEmpty) {
+      return new NameFilter._(shownNames: combinator.shows.toSet());
+    } else {
+      return new NameFilter._(hiddenNames: combinator.hides.toSet());
+    }
+  }
+
+  /**
+   * Create a [NameFilter] based on the given (possibly empty) sequence of
+   * [combinators].
+   */
+  factory NameFilter.forUnlinkedCombinators(
+      List<UnlinkedCombinator> combinators) {
+    NameFilter result = identity;
+    for (UnlinkedCombinator combinator in combinators) {
+      result = result.merge(new NameFilter.forUnlinkedCombinator(combinator));
+    }
+    return result;
+  }
+
+  const NameFilter._({this.shownNames, this.hiddenNames});
+
+  /**
+   * Determine if the given [name] is accepted by this [NameFilter].
+   */
+  bool accepts(String name) {
+    if (name.endsWith('=')) {
+      name = name.substring(0, name.length - 1);
+    }
+    if (shownNames != null) {
+      return shownNames.contains(name);
+    } else {
+      return !hiddenNames.contains(name);
+    }
+  }
+
+  /**
+   * Produce a new [NameFilter] by combining this [NameFilter] with another
+   * one.  The new [NameFilter] will only accept names that would be accepted
+   * by both input filters.
+   */
+  NameFilter merge(NameFilter other) {
+    if (shownNames != null) {
+      if (other.shownNames != null) {
+        return new NameFilter._(
+            shownNames: shownNames.intersection(other.shownNames));
+      } else {
+        return new NameFilter._(
+            shownNames: shownNames.difference(other.hiddenNames));
+      }
+    } else {
+      if (other.shownNames != null) {
+        return new NameFilter._(
+            shownNames: other.shownNames.difference(hiddenNames));
+      } else {
+        return new NameFilter._(
+            hiddenNames: hiddenNames.union(other.hiddenNames));
+      }
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
new file mode 100644
index 0000000..ad4834f
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/prelink.dart
@@ -0,0 +1,418 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/name_filter.dart';
+
+/**
+ * Create a [PrelinkedLibraryBuilder] corresponding to the given
+ * [definingUnit], which should be the defining compilation unit for a library.
+ * Compilation units referenced by the defining compilation unit via `part`
+ * declarations will be retrieved using [getPart].  Public namespaces for
+ * libraries referenced by the defining compilation unit via `import`
+ * declarations (and files reachable from them via `part` and `export`
+ * declarations) will be retrieved using [getImport].
+ */
+PrelinkedLibraryBuilder prelink(UnlinkedUnit definingUnit,
+    GetPartCallback getPart, GetImportCallback getImport) {
+  return new _Prelinker(definingUnit, getPart, getImport).prelink();
+}
+
+/**
+ * Type of the callback used by the prelinker to obtain public namespace
+ * information about libraries imported by the library to be prelinked (and
+ * the transitive closure of parts and exports reachable from those libraries).
+ * [relativeUri] should be interpreted relative to the defining compilation
+ * unit of the library being prelinked.
+ *
+ * If no file exists at the given uri, `null` should be returned.
+ */
+typedef UnlinkedPublicNamespace GetImportCallback(String relativeUri);
+
+/**
+ * Type of the callback used by the prelinker to obtain unlinked summaries of
+ * part files of the library to be prelinked.  [relaviteUri] should be
+ * interpreted relative to the defining compilation unit of the library being
+ * prelinked.
+ *
+ * If no file exists at the given uri, `null` should be returned.
+ */
+typedef UnlinkedUnit GetPartCallback(String relativeUri);
+
+/**
+ * A [_Meaning] stores all the information necessary to find the declaration
+ * referred to by a name in a namespace.
+ */
+class _Meaning {
+  /**
+   * Which unit in the dependent library contains the declared entity.
+   */
+  final int unit;
+
+  /**
+   * The kind of entity being referred to.
+   */
+  final PrelinkedReferenceKind kind;
+
+  /**
+   * Which of the dependencies of the library being prelinked contains the
+   * declared entity.
+   */
+  final int dependency;
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  final int numTypeParameters;
+
+  _Meaning(this.unit, this.kind, this.dependency, this.numTypeParameters);
+
+  /**
+   * Encode this [_Meaning] as a [PrelinkedReference].
+   */
+  PrelinkedReferenceBuilder encode() {
+    return encodePrelinkedReference(
+        unit: unit,
+        kind: kind,
+        dependency: dependency,
+        numTypeParameters: numTypeParameters);
+  }
+}
+
+/**
+ * A [_Meaning] representing a prefix introduced by an import directive.
+ */
+class _PrefixMeaning extends _Meaning {
+  final Map<String, _Meaning> namespace = <String, _Meaning>{};
+
+  _PrefixMeaning() : super(0, PrelinkedReferenceKind.prefix, 0, 0);
+}
+
+/**
+ * Helper class containing temporary data structures needed to prelink a single
+ * library.
+ *
+ * Note: throughout this class, a `null` value for a relative URI represents
+ * the defining compilation unit of the library being prelinked.
+ */
+class _Prelinker {
+  final UnlinkedUnit definingUnit;
+  final GetPartCallback getPart;
+  final GetImportCallback getImport;
+
+  /**
+   * Cache of values returned by [getImport].
+   */
+  final Map<String, UnlinkedPublicNamespace> importCache =
+      <String, UnlinkedPublicNamespace>{};
+
+  /**
+   * Cache of values returned by [getPart].
+   */
+  final Map<String, UnlinkedUnit> partCache = <String, UnlinkedUnit>{};
+
+  /**
+   * Names defined inside the library being prelinked.
+   */
+  final Map<String, _Meaning> privateNamespace = <String, _Meaning>{
+    '': new _Meaning(0, PrelinkedReferenceKind.classOrEnum, 0, 0)
+  };
+
+  /**
+   * List of dependencies of the library being prelinked.  This will be output
+   * to [PrelinkedLibrary.dependencies].
+   */
+  final List<PrelinkedDependencyBuilder> dependencies =
+      <PrelinkedDependencyBuilder>[encodePrelinkedDependency()];
+
+  /**
+   * Map from the relative URI of a dependent library to the index of the
+   * corresponding entry in [dependencies].
+   */
+  final Map<String, int> uriToDependency = <String, int>{null: 0};
+
+  /**
+   * List of public namespaces corresponding to each entry in [dependencies].
+   */
+  final List<Map<String, _Meaning>> dependencyToPublicNamespace =
+      <Map<String, _Meaning>>[null];
+
+  _Prelinker(this.definingUnit, this.getPart, this.getImport) {
+    partCache[null] = definingUnit;
+    importCache[null] = definingUnit.publicNamespace;
+  }
+
+  /**
+   * Compute the public namespace for the library whose URI is reachable from
+   * [definingUnit] via [relativeUri], by aggregating together public namespace
+   * information from all of its parts.
+   */
+  Map<String, _Meaning> aggregatePublicNamespace(String relativeUri) {
+    if (uriToDependency.containsKey(relativeUri)) {
+      return dependencyToPublicNamespace[uriToDependency[relativeUri]];
+    }
+    assert(dependencies.length == dependencyToPublicNamespace.length);
+    int dependency = dependencies.length;
+    uriToDependency[relativeUri] = dependency;
+    List<String> unitUris = getUnitUris(relativeUri);
+    PrelinkedDependencyBuilder prelinkedDependency =
+        encodePrelinkedDependency(uri: relativeUri, parts: unitUris.sublist(1));
+    dependencies.add(prelinkedDependency);
+
+    Map<String, _Meaning> aggregated = <String, _Meaning>{};
+
+    for (int unitNum = 0; unitNum < unitUris.length; unitNum++) {
+      String unitUri = unitUris[unitNum];
+      UnlinkedPublicNamespace importedNamespace = getImportCached(unitUri);
+      if (importedNamespace == null) {
+        continue;
+      }
+      for (UnlinkedPublicName name in importedNamespace.names) {
+        aggregated.putIfAbsent(
+            name.name,
+            () => new _Meaning(
+                unitNum, name.kind, dependency, name.numTypeParameters));
+      }
+    }
+
+    dependencyToPublicNamespace.add(aggregated);
+    return aggregated;
+  }
+
+  /**
+   * Compute the export namespace for the library whose URI is reachable from
+   * [definingUnit] via [relativeUri], by aggregating together public namespace
+   * information from the library and the transitive closure of its exports.
+   */
+  Map<String, _Meaning> computeExportNamespace(String relativeUri) {
+    Map<String, _Meaning> exportNamespace =
+        aggregatePublicNamespace(relativeUri);
+    void chaseExports(
+        NameFilter filter, String relativeUri, Set<String> seenUris) {
+      if (seenUris.add(relativeUri)) {
+        UnlinkedPublicNamespace exportedNamespace =
+            getImportCached(relativeUri);
+        if (exportedNamespace != null) {
+          for (UnlinkedExportPublic export in exportedNamespace.exports) {
+            String exportUri = resolveUri(relativeUri, export.uri);
+            aggregatePublicNamespace(exportUri)
+                .forEach((String name, _Meaning meaning) {
+              if (filter.accepts(name) && !exportNamespace.containsKey(name)) {
+                exportNamespace[name] = meaning;
+              }
+            });
+            chaseExports(
+                filter.merge(
+                    new NameFilter.forUnlinkedCombinators(export.combinators)),
+                exportUri,
+                seenUris);
+          }
+        }
+        seenUris.remove(relativeUri);
+      }
+    }
+    chaseExports(NameFilter.identity, relativeUri, new Set<String>());
+    return exportNamespace;
+  }
+
+  /**
+   * Extract all the names defined in [unit] (which is the [unitNum]th unit in
+   * the library being prelinked) and store them in [privateNamespace].
+   * Excludes names introduced by `import` statements.
+   */
+  void extractPrivateNames(UnlinkedUnit unit, int unitNum) {
+    for (UnlinkedClass cls in unit.classes) {
+      privateNamespace.putIfAbsent(
+          cls.name,
+          () => new _Meaning(unitNum, PrelinkedReferenceKind.classOrEnum, 0,
+              cls.typeParameters.length));
+    }
+    for (UnlinkedEnum enm in unit.enums) {
+      privateNamespace.putIfAbsent(
+          enm.name,
+          () =>
+              new _Meaning(unitNum, PrelinkedReferenceKind.classOrEnum, 0, 0));
+    }
+    for (UnlinkedExecutable executable in unit.executables) {
+      privateNamespace.putIfAbsent(
+          executable.name,
+          () => new _Meaning(unitNum, PrelinkedReferenceKind.other, 0,
+              executable.typeParameters.length));
+    }
+    for (UnlinkedTypedef typedef in unit.typedefs) {
+      privateNamespace.putIfAbsent(
+          typedef.name,
+          () => new _Meaning(unitNum, PrelinkedReferenceKind.typedef, 0,
+              typedef.typeParameters.length));
+    }
+    for (UnlinkedVariable variable in unit.variables) {
+      privateNamespace.putIfAbsent(variable.name,
+          () => new _Meaning(unitNum, PrelinkedReferenceKind.other, 0, 0));
+    }
+  }
+
+  /**
+   * Filter the export namespace for the library whose URI is reachable from
+   * [definingUnit] via [relativeUri], retaining only those names accepted by
+   * [combinators], and store the resulting names in [result].  Names that
+   * already exist in [result] are not overwritten.
+   */
+  void filterExportNamespace(String relativeUri,
+      List<UnlinkedCombinator> combinators, Map<String, _Meaning> result) {
+    Map<String, _Meaning> exportNamespace = computeExportNamespace(relativeUri);
+    NameFilter filter = new NameFilter.forUnlinkedCombinators(combinators);
+    exportNamespace.forEach((String name, _Meaning meaning) {
+      if (filter.accepts(name) && !result.containsKey(name)) {
+        result[name] = meaning;
+      }
+    });
+  }
+
+  /**
+   * Wrapper around [getImport] that caches the return value in [importCache].
+   */
+  UnlinkedPublicNamespace getImportCached(String relativeUri) {
+    return importCache.putIfAbsent(relativeUri, () => getImport(relativeUri));
+  }
+
+  /**
+   * Wrapper around [getPart] that caches the return value in [partCache] and
+   * updates [importCache] appropriately.
+   */
+  UnlinkedUnit getPartCached(String relativeUri) {
+    return partCache.putIfAbsent(relativeUri, () {
+      UnlinkedUnit unit = getPart(relativeUri);
+      importCache[relativeUri] = unit?.publicNamespace;
+      return unit;
+    });
+  }
+
+  /**
+   * Compute the set of relative URIs of all the compilation units in the
+   * library whose URI is reachable from [definingUnit] via [relativeUri].
+   */
+  List<String> getUnitUris(String relativeUri) {
+    List<String> result = <String>[relativeUri];
+    UnlinkedPublicNamespace publicNamespace = getImportCached(relativeUri);
+    if (publicNamespace != null) {
+      result.addAll(publicNamespace.parts
+          .map((String uri) => resolveUri(relativeUri, uri)));
+    }
+    return result;
+  }
+
+  /**
+   * Process a single `import` declaration in the library being prelinked.  The
+   * return value is the index of the imported library in [dependencies].
+   */
+  int handleImport(UnlinkedImport import) {
+    String uri = import.isImplicit ? 'dart:core' : import.uri;
+    Map<String, _Meaning> targetNamespace = null;
+    if (import.prefixReference != 0) {
+      // The name introduced by an import declaration can't have a prefix of
+      // its own.
+      assert(
+          definingUnit.references[import.prefixReference].prefixReference == 0);
+      String prefix = definingUnit.references[import.prefixReference].name;
+      _Meaning prefixMeaning = privateNamespace[prefix];
+      if (prefixMeaning is _PrefixMeaning) {
+        targetNamespace = prefixMeaning.namespace;
+      }
+    } else {
+      targetNamespace = privateNamespace;
+    }
+    filterExportNamespace(uri, import.combinators, targetNamespace);
+    return uriToDependency[uri];
+  }
+
+  /**
+   * Produce a [PrelinkedUnit] for the given [unit], by resolving every one of
+   * its references.
+   */
+  PrelinkedUnitBuilder linkUnit(UnlinkedUnit unit) {
+    if (unit == null) {
+      return encodePrelinkedUnit();
+    }
+    Map<int, Map<String, _Meaning>> prefixNamespaces =
+        <int, Map<String, _Meaning>>{};
+    List<PrelinkedReferenceBuilder> references = <PrelinkedReferenceBuilder>[];
+    for (int i = 0; i < unit.references.length; i++) {
+      UnlinkedReference reference = unit.references[i];
+      Map<String, _Meaning> namespace;
+      if (reference.prefixReference != 0) {
+        // Prefix references must always point backward.
+        assert(reference.prefixReference < i);
+        namespace = prefixNamespaces[reference.prefixReference];
+        // Prefix references must always point to proper prefixes.
+        assert(namespace != null);
+      } else {
+        namespace = privateNamespace;
+      }
+      _Meaning meaning = namespace[reference.name];
+      if (meaning != null) {
+        if (meaning is _PrefixMeaning) {
+          prefixNamespaces[i] = meaning.namespace;
+        }
+        references.add(meaning.encode());
+      } else {
+        references.add(
+            encodePrelinkedReference(kind: PrelinkedReferenceKind.unresolved));
+      }
+    }
+    return encodePrelinkedUnit(references: references);
+  }
+
+  /**
+   * Form the [PrelinkedLibrary] for the [definingUnit] that was passed to the
+   * constructor.
+   */
+  PrelinkedLibraryBuilder prelink() {
+    // Gather up the unlinked summaries for all the compilation units in the
+    // library.
+    List<UnlinkedUnit> units = getUnitUris(null).map(getPartCached).toList();
+
+    // Create the private namespace for the library by gathering all the names
+    // defined in its compilation units.
+    for (int unitNum = 0; unitNum < units.length; unitNum++) {
+      UnlinkedUnit unit = units[unitNum];
+      if (unit != null) {
+        extractPrivateNames(unit, unitNum);
+      }
+    }
+
+    // Fill in prefixes defined in import declarations.
+    for (UnlinkedImport import in units[0].imports) {
+      if (import.prefixReference != 0) {
+        privateNamespace.putIfAbsent(
+            units[0].references[import.prefixReference].name,
+            () => new _PrefixMeaning());
+      }
+    }
+
+    // Fill in imported names.
+    List<int> importDependencies =
+        definingUnit.imports.map(handleImport).toList();
+
+    // Link each compilation unit.
+    List<PrelinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList();
+
+    return encodePrelinkedLibrary(
+        units: linkedUnits,
+        dependencies: dependencies,
+        importDependencies: importDependencies);
+  }
+
+  /**
+   * Resolve [relativeUri] relative to [sourceUri].  Works correctly if
+   * [sourceUri] is also relative.
+   */
+  String resolveUri(String sourceUri, String relativeUri) {
+    if (sourceUri == null) {
+      return relativeUri;
+    } else {
+      return Uri.parse(sourceUri).resolve(relativeUri).toString();
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
new file mode 100644
index 0000000..e8751b0
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -0,0 +1,111 @@
+// 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.summary.public_namespace_visitor;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/summary/format.dart';
+
+/**
+ * Compute the public namespace portion of the summary for the given [unit],
+ * which is presumed to be an unresolved AST.
+ */
+UnlinkedPublicNamespaceBuilder computePublicNamespace(CompilationUnit unit) {
+  _PublicNamespaceVisitor visitor = new _PublicNamespaceVisitor();
+  unit.accept(visitor);
+  return encodeUnlinkedPublicNamespace(
+      names: visitor.names, exports: visitor.exports, parts: visitor.parts);
+}
+
+class _CombinatorEncoder extends SimpleAstVisitor<UnlinkedCombinatorBuilder> {
+  _CombinatorEncoder();
+
+  List<String> encodeNames(NodeList<SimpleIdentifier> names) =>
+      names.map((SimpleIdentifier id) => id.name).toList();
+
+  @override
+  UnlinkedCombinatorBuilder visitHideCombinator(HideCombinator node) {
+    return encodeUnlinkedCombinator(hides: encodeNames(node.hiddenNames));
+  }
+
+  @override
+  UnlinkedCombinatorBuilder visitShowCombinator(ShowCombinator node) {
+    return encodeUnlinkedCombinator(shows: encodeNames(node.shownNames));
+  }
+}
+
+class _PublicNamespaceVisitor extends RecursiveAstVisitor {
+  final List<UnlinkedPublicNameBuilder> names = <UnlinkedPublicNameBuilder>[];
+  final List<UnlinkedExportPublicBuilder> exports =
+      <UnlinkedExportPublicBuilder>[];
+  final List<String> parts = <String>[];
+
+  _PublicNamespaceVisitor();
+
+  void addNameIfPublic(
+      String name, PrelinkedReferenceKind kind, int numTypeParameters) {
+    if (isPublic(name)) {
+      names.add(encodeUnlinkedPublicName(
+          name: name, kind: kind, numTypeParameters: numTypeParameters));
+    }
+  }
+
+  bool isPublic(String name) => !name.startsWith('_');
+
+  @override
+  visitClassDeclaration(ClassDeclaration node) {
+    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum,
+        node.typeParameters?.typeParameters?.length ?? 0);
+  }
+
+  @override
+  visitClassTypeAlias(ClassTypeAlias node) {
+    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum,
+        node.typeParameters?.typeParameters?.length ?? 0);
+  }
+
+  @override
+  visitEnumDeclaration(EnumDeclaration node) {
+    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum, 0);
+  }
+
+  @override
+  visitExportDirective(ExportDirective node) {
+    exports.add(encodeUnlinkedExportPublic(
+        uri: node.uri.stringValue,
+        combinators: node.combinators
+            .map((Combinator c) => c.accept(new _CombinatorEncoder()))
+            .toList()));
+  }
+
+  @override
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    String name = node.name.name;
+    if (node.isSetter) {
+      name += '=';
+    }
+    addNameIfPublic(name, PrelinkedReferenceKind.other,
+        node.functionExpression.typeParameters?.typeParameters?.length ?? 0);
+  }
+
+  @override
+  visitFunctionTypeAlias(FunctionTypeAlias node) {
+    addNameIfPublic(node.name.name, PrelinkedReferenceKind.typedef,
+        node.typeParameters?.typeParameters?.length ?? 0);
+  }
+
+  @override
+  visitPartDirective(PartDirective node) {
+    parts.add(node.uri.stringValue);
+  }
+
+  @override
+  visitVariableDeclaration(VariableDeclaration node) {
+    String name = node.name.name;
+    addNameIfPublic(name, PrelinkedReferenceKind.other, 0);
+    if (!node.isFinal && !node.isConst) {
+      addNameIfPublic('$name=', PrelinkedReferenceKind.other, 0);
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
new file mode 100644
index 0000000..23b103c
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -0,0 +1,1006 @@
+// 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 summary_resynthesizer;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/element_handle.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/summary/format.dart';
+
+/**
+ * Callback used by [SummaryResynthesizer] to obtain the prelinked summary for
+ * a given URI.
+ */
+typedef PrelinkedLibrary GetPrelinkedSummaryCallback(String uri);
+
+/**
+ * Callback used by [SummaryResynthesizer] to obtain the unlinked summary for a
+ * given URI.
+ */
+typedef UnlinkedUnit GetUnlinkedSummaryCallback(String uri);
+
+/**
+ * Implementation of [ElementResynthesizer] used when resynthesizing an element
+ * model from summaries.
+ */
+class SummaryResynthesizer extends ElementResynthesizer {
+  /**
+   * Callback used to obtain the prelinked summary for a given URI.
+   */
+  final GetPrelinkedSummaryCallback getPrelinkedSummary;
+
+  /**
+   * Callback used to obtain the unlinked summary for a given URI.
+   */
+  final GetUnlinkedSummaryCallback getUnlinkedSummary;
+
+  /**
+   * Source factory used to convert URIs to [Source] objects.
+   */
+  final SourceFactory sourceFactory;
+
+  /**
+   * Cache of [Source] objects that have already been converted from URIs.
+   */
+  final Map<String, Source> _sources = <String, Source>{};
+
+  /**
+   * The [TypeProvider] used to obtain core types (such as Object, int, List,
+   * and dynamic) during resynthesis.
+   */
+  final TypeProvider typeProvider;
+
+  /**
+   * Map of top level elements resynthesized from summaries.  The three map
+   * keys are the first three elements of the element's location (the library
+   * URI, the compilation unit URI, and the name of the top level declaration).
+   */
+  final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements =
+      <String, Map<String, Map<String, Element>>>{};
+
+  /**
+   * Map of libraries which have been resynthesized from summaries.  The map
+   * key is the library URI.
+   */
+  final Map<String, LibraryElement> _resynthesizedLibraries =
+      <String, LibraryElement>{};
+
+  SummaryResynthesizer(AnalysisContext context, this.typeProvider,
+      this.getPrelinkedSummary, this.getUnlinkedSummary, this.sourceFactory)
+      : super(context);
+
+  /**
+   * Number of libraries that have been resynthesized so far.
+   */
+  int get resynthesisCount => _resynthesizedLibraries.length;
+
+  @override
+  Element getElement(ElementLocation location) {
+    if (location.components.length == 1) {
+      return getLibraryElement(location.components[0]);
+    } else if (location.components.length == 3) {
+      String uri = location.components[0];
+      Map<String, Map<String, Element>> libraryMap =
+          _resynthesizedElements[uri];
+      if (libraryMap == null) {
+        getLibraryElement(uri);
+        libraryMap = _resynthesizedElements[uri];
+        assert(libraryMap != null);
+      }
+      Map<String, Element> compilationUnitElements =
+          libraryMap[location.components[1]];
+      if (compilationUnitElements != null) {
+        Element element = compilationUnitElements[location.components[2]];
+        if (element != null) {
+          return element;
+        }
+      }
+      throw new Exception('Element not found in summary: $location');
+    } else {
+      throw new UnimplementedError(location.toString());
+    }
+  }
+
+  /**
+   * Get the [LibraryElement] for the given [uri], resynthesizing it if it
+   * hasn't been resynthesized already.
+   */
+  LibraryElement getLibraryElement(String uri) {
+    return _resynthesizedLibraries.putIfAbsent(uri, () {
+      PrelinkedLibrary serializedLibrary = getPrelinkedSummary(uri);
+      List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[
+        getUnlinkedSummary(uri)
+      ];
+      Source librarySource = _getSource(uri);
+      for (String part in serializedUnits[0].publicNamespace.parts) {
+        Source partSource = sourceFactory.resolveUri(librarySource, part);
+        String partAbsUri = partSource.uri.toString();
+        serializedUnits.add(getUnlinkedSummary(partAbsUri));
+      }
+      _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer(
+          this, serializedLibrary, serializedUnits, librarySource);
+      LibraryElement library = libraryResynthesizer.buildLibrary();
+      _resynthesizedElements[uri] = libraryResynthesizer.resummarizedElements;
+      return library;
+    });
+  }
+
+  /**
+   * Get the [Source] object for the given [uri].
+   */
+  Source _getSource(String uri) {
+    return _sources.putIfAbsent(uri, () => sourceFactory.forUri(uri));
+  }
+}
+
+/**
+ * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the
+ * elements in a single library from that library's summary.
+ */
+class _LibraryResynthesizer {
+  /**
+   * The [SummaryResynthesizer] which is being used to obtain summaries.
+   */
+  final SummaryResynthesizer summaryResynthesizer;
+
+  /**
+   * Prelinked summary of the library to be resynthesized.
+   */
+  final PrelinkedLibrary prelinkedLibrary;
+
+  /**
+   * Unlinked compilation units constituting the library to be resynthesized.
+   */
+  final List<UnlinkedUnit> unlinkedUnits;
+
+  /**
+   * [Source] object for the library to be resynthesized.
+   */
+  final Source librarySource;
+
+  /**
+   * Indicates whether [librarySource] is the `dart:core` library.
+   */
+  bool isCoreLibrary;
+
+  /**
+   * Classes which should have their supertype set to "object" once
+   * resynthesis is complete.  Only used if [isCoreLibrary] is `true`.
+   */
+  List<ClassElementImpl> delayedObjectSubclasses = <ClassElementImpl>[];
+
+  /**
+   * [ElementHolder] into which resynthesized elements should be placed.  This
+   * object is recreated afresh for each unit in the library, and is used to
+   * populate the [CompilationUnitElement].
+   */
+  ElementHolder unitHolder;
+
+  /**
+   * The [PrelinkedUnit] from which elements are currently being resynthesized.
+   */
+  PrelinkedUnit prelinkedUnit;
+
+  /**
+   * The [UnlinkedUnit] from which elements are currently being resynthesized.
+   */
+  UnlinkedUnit unlinkedUnit;
+
+  /**
+   * Map of top level elements that have been resynthesized so far.  The first
+   * key is the URI of the compilation unit; the second is the name of the top
+   * level element.
+   */
+  final Map<String, Map<String, Element>> resummarizedElements =
+      <String, Map<String, Element>>{};
+
+  /**
+   * Type parameters for the generic class, typedef, or executable currently
+   * being resynthesized, if any.  If multiple entities with type parameters
+   * are nested (e.g. a generic executable inside a generic class), this is the
+   * concatenation of all type parameters from all declarations currently in
+   * force, with the outermost declaration appearing first.  If there are no
+   * type parameters, or we are not currently resynthesizing a class, typedef,
+   * or executable, then this is an empty list.
+   */
+  List<TypeParameterElement> currentTypeParameters = <TypeParameterElement>[];
+
+  _LibraryResynthesizer(this.summaryResynthesizer, this.prelinkedLibrary,
+      this.unlinkedUnits, this.librarySource) {
+    isCoreLibrary = librarySource.uri.toString() == 'dart:core';
+  }
+
+  /**
+   * Return a list of type arguments corresponding to [currentTypeParameters].
+   */
+  List<TypeParameterType> get currentTypeArguments => currentTypeParameters
+      ?.map((TypeParameterElement param) => param.type)
+      ?.toList();
+
+  /**
+   * Resynthesize a [ClassElement] and place it in [unitHolder].
+   */
+  void buildClass(UnlinkedClass serializedClass) {
+    try {
+      currentTypeParameters =
+          serializedClass.typeParameters.map(buildTypeParameter).toList();
+      for (int i = 0; i < serializedClass.typeParameters.length; i++) {
+        finishTypeParameter(
+            serializedClass.typeParameters[i], currentTypeParameters[i]);
+      }
+      ClassElementImpl classElement = new ClassElementImpl(
+          serializedClass.name, serializedClass.nameOffset);
+      classElement.mixinApplication = serializedClass.isMixinApplication;
+      InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement);
+      if (serializedClass.supertype != null) {
+        classElement.supertype = buildType(serializedClass.supertype);
+      } else if (!serializedClass.hasNoSupertype) {
+        if (isCoreLibrary) {
+          delayedObjectSubclasses.add(classElement);
+        } else {
+          classElement.supertype = summaryResynthesizer.typeProvider.objectType;
+        }
+      }
+      classElement.interfaces =
+          serializedClass.interfaces.map(buildType).toList();
+      classElement.mixins = serializedClass.mixins.map(buildType).toList();
+      classElement.typeParameters = currentTypeParameters;
+      ElementHolder memberHolder = new ElementHolder();
+      bool constructorFound = false;
+      for (UnlinkedExecutable serializedExecutable
+          in serializedClass.executables) {
+        switch (serializedExecutable.kind) {
+          case UnlinkedExecutableKind.constructor:
+            constructorFound = true;
+            buildConstructor(
+                serializedExecutable, memberHolder, correspondingType);
+            break;
+          case UnlinkedExecutableKind.functionOrMethod:
+          case UnlinkedExecutableKind.getter:
+          case UnlinkedExecutableKind.setter:
+            buildExecutable(serializedExecutable, memberHolder);
+            break;
+        }
+      }
+      for (UnlinkedVariable serializedVariable in serializedClass.fields) {
+        buildVariable(serializedVariable, memberHolder);
+      }
+      if (!serializedClass.isMixinApplication) {
+        if (!constructorFound) {
+          // Synthesize implicit constructors.
+          ConstructorElementImpl constructor =
+              new ConstructorElementImpl('', -1);
+          constructor.synthetic = true;
+          constructor.returnType = correspondingType;
+          constructor.type = new FunctionTypeImpl.elementWithNameAndArgs(
+              constructor, null, currentTypeArguments, false);
+          memberHolder.addConstructor(constructor);
+        }
+        classElement.constructors = memberHolder.constructors;
+      }
+      classElement.accessors = memberHolder.accessors;
+      classElement.fields = memberHolder.fields;
+      classElement.methods = memberHolder.methods;
+      correspondingType.typeArguments = currentTypeArguments;
+      classElement.type = correspondingType;
+      buildDocumentation(classElement, serializedClass.documentationComment);
+      unitHolder.addType(classElement);
+    } finally {
+      currentTypeParameters = <TypeParameterElement>[];
+    }
+  }
+
+  /**
+   * Resynthesize a [NamespaceCombinator].
+   */
+  NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) {
+    if (serializedCombinator.shows.isNotEmpty) {
+      ShowElementCombinatorImpl combinator = new ShowElementCombinatorImpl();
+      // Note: we call toList() so that we don't retain a reference to the
+      // deserialized data structure.
+      combinator.shownNames = serializedCombinator.shows.toList();
+      return combinator;
+    } else {
+      HideElementCombinatorImpl combinator = new HideElementCombinatorImpl();
+      // Note: we call toList() so that we don't retain a reference to the
+      // deserialized data structure.
+      combinator.hiddenNames = serializedCombinator.hides.toList();
+      return combinator;
+    }
+  }
+
+  /**
+   * Resynthesize a [ConstructorElement] and place it in the given [holder].
+   * [classType] is the type of the class for which this element is a
+   * constructor.
+   */
+  void buildConstructor(UnlinkedExecutable serializedExecutable,
+      ElementHolder holder, InterfaceType classType) {
+    assert(serializedExecutable.kind == UnlinkedExecutableKind.constructor);
+    ConstructorElementImpl constructorElement = new ConstructorElementImpl(
+        serializedExecutable.name, serializedExecutable.nameOffset);
+    constructorElement.returnType = classType;
+    buildExecutableCommonParts(constructorElement, serializedExecutable);
+    constructorElement.factory = serializedExecutable.isFactory;
+    constructorElement.const2 = serializedExecutable.isConst;
+    holder.addConstructor(constructorElement);
+  }
+
+  /**
+   * Build the documentation for the given [element].  Does nothing if
+   * [serializedDocumentationComment] is `null`.
+   */
+  void buildDocumentation(ElementImpl element,
+      UnlinkedDocumentationComment serializedDocumentationComment) {
+    if (serializedDocumentationComment != null) {
+      element.documentationComment = serializedDocumentationComment.text;
+      element.setDocRange(serializedDocumentationComment.offset,
+          serializedDocumentationComment.length);
+    }
+  }
+
+  /**
+   * Resynthesize the [ClassElement] corresponding to an enum, along with the
+   * associated fields and implicit accessors.
+   */
+  void buildEnum(UnlinkedEnum serializedEnum) {
+    assert(!isCoreLibrary);
+    // TODO(paulberry): add offset support (for this element type and others)
+    ClassElementImpl classElement =
+        new ClassElementImpl(serializedEnum.name, serializedEnum.nameOffset);
+    classElement.enum2 = true;
+    InterfaceType enumType = new InterfaceTypeImpl(classElement);
+    classElement.type = enumType;
+    classElement.supertype = summaryResynthesizer.typeProvider.objectType;
+    buildDocumentation(classElement, serializedEnum.documentationComment);
+    ElementHolder memberHolder = new ElementHolder();
+    FieldElementImpl indexField = new FieldElementImpl('index', -1);
+    indexField.final2 = true;
+    indexField.synthetic = true;
+    indexField.type = summaryResynthesizer.typeProvider.intType;
+    memberHolder.addField(indexField);
+    buildImplicitAccessors(indexField, memberHolder);
+    FieldElementImpl valuesField = new ConstFieldElementImpl('values', -1);
+    valuesField.synthetic = true;
+    valuesField.const3 = true;
+    valuesField.static = true;
+    valuesField.type = summaryResynthesizer.typeProvider.listType
+        .substitute4(<DartType>[enumType]);
+    memberHolder.addField(valuesField);
+    buildImplicitAccessors(valuesField, memberHolder);
+    for (UnlinkedEnumValue serializedEnumValue in serializedEnum.values) {
+      ConstFieldElementImpl valueField = new ConstFieldElementImpl(
+          serializedEnumValue.name, serializedEnumValue.nameOffset);
+      valueField.const3 = true;
+      valueField.static = true;
+      valueField.type = enumType;
+      memberHolder.addField(valueField);
+      buildImplicitAccessors(valueField, memberHolder);
+    }
+    classElement.fields = memberHolder.fields;
+    classElement.accessors = memberHolder.accessors;
+    classElement.constructors = <ConstructorElement>[];
+    unitHolder.addEnum(classElement);
+  }
+
+  /**
+   * Resynthesize an [ExecutableElement] and place it in the given [holder].
+   */
+  void buildExecutable(UnlinkedExecutable serializedExecutable,
+      [ElementHolder holder]) {
+    bool isTopLevel = holder == null;
+    if (holder == null) {
+      holder = unitHolder;
+    }
+    UnlinkedExecutableKind kind = serializedExecutable.kind;
+    String name = serializedExecutable.name;
+    if (kind == UnlinkedExecutableKind.setter) {
+      assert(name.endsWith('='));
+      name = name.substring(0, name.length - 1);
+    }
+    switch (kind) {
+      case UnlinkedExecutableKind.functionOrMethod:
+        if (isTopLevel) {
+          FunctionElementImpl executableElement =
+              new FunctionElementImpl(name, serializedExecutable.nameOffset);
+          buildExecutableCommonParts(executableElement, serializedExecutable);
+          holder.addFunction(executableElement);
+        } else {
+          MethodElementImpl executableElement =
+              new MethodElementImpl(name, serializedExecutable.nameOffset);
+          buildExecutableCommonParts(executableElement, serializedExecutable);
+          executableElement.static = serializedExecutable.isStatic;
+          holder.addMethod(executableElement);
+        }
+        break;
+      case UnlinkedExecutableKind.getter:
+      case UnlinkedExecutableKind.setter:
+        PropertyAccessorElementImpl executableElement =
+            new PropertyAccessorElementImpl(
+                name, serializedExecutable.nameOffset);
+        if (isTopLevel) {
+          executableElement.static = true;
+        } else {
+          executableElement.static = serializedExecutable.isStatic;
+        }
+        buildExecutableCommonParts(executableElement, serializedExecutable);
+        DartType type;
+        if (kind == UnlinkedExecutableKind.getter) {
+          executableElement.getter = true;
+          type = executableElement.returnType;
+        } else {
+          executableElement.setter = true;
+          type = executableElement.parameters[0].type;
+        }
+        holder.addAccessor(executableElement);
+        // TODO(paulberry): consider removing implicit variables from the
+        // element model; the spec doesn't call for them, and they cause
+        // trouble when getters/setters exist in different parts.
+        PropertyInducingElementImpl implicitVariable;
+        if (isTopLevel) {
+          implicitVariable = buildImplicitTopLevelVariable(name, kind, holder);
+        } else {
+          FieldElementImpl field = buildImplicitField(name, type, kind, holder);
+          field.static = serializedExecutable.isStatic;
+          implicitVariable = field;
+        }
+        executableElement.variable = implicitVariable;
+        if (kind == UnlinkedExecutableKind.getter) {
+          implicitVariable.getter = executableElement;
+        } else {
+          implicitVariable.setter = executableElement;
+        }
+        // TODO(paulberry): do the right thing when getter and setter are in
+        // different units.
+        break;
+      default:
+        // The only other executable type is a constructor, and that is handled
+        // separately (in [buildConstructor].  So this code should be
+        // unreachable.
+        assert(false);
+    }
+  }
+
+  /**
+   * Handle the parts of an executable element that are common to constructors,
+   * functions, methods, getters, and setters.
+   */
+  void buildExecutableCommonParts(ExecutableElementImpl executableElement,
+      UnlinkedExecutable serializedExecutable) {
+    List<TypeParameterType> oldTypeArguments = currentTypeArguments;
+    int oldTypeParametersLength = currentTypeParameters.length;
+    if (serializedExecutable.typeParameters.isNotEmpty) {
+      executableElement.typeParameters =
+          serializedExecutable.typeParameters.map(buildTypeParameter).toList();
+      currentTypeParameters.addAll(executableElement.typeParameters);
+    }
+    executableElement.parameters =
+        serializedExecutable.parameters.map(buildParameter).toList();
+    if (serializedExecutable.returnType != null) {
+      executableElement.returnType = buildType(serializedExecutable.returnType);
+    } else if (serializedExecutable.kind ==
+        UnlinkedExecutableKind.constructor) {
+      // Return type was set by the caller.
+    } else {
+      executableElement.returnType = VoidTypeImpl.instance;
+    }
+    executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
+        executableElement, null, oldTypeArguments, false);
+    executableElement.hasImplicitReturnType =
+        serializedExecutable.hasImplicitReturnType;
+    executableElement.external = serializedExecutable.isExternal;
+    currentTypeParameters.removeRange(
+        oldTypeParametersLength, currentTypeParameters.length);
+    buildDocumentation(
+        executableElement, serializedExecutable.documentationComment);
+  }
+
+  /**
+   * Resynthesize an [ExportElement],
+   */
+  ExportElement buildExport(UnlinkedExportPublic serializedExportPublic,
+      UnlinkedExportNonPublic serializedExportNonPublic) {
+    ExportElementImpl exportElement =
+        new ExportElementImpl(serializedExportNonPublic.offset);
+    String exportedLibraryUri = summaryResynthesizer.sourceFactory
+        .resolveUri(librarySource, serializedExportPublic.uri)
+        .uri
+        .toString();
+    exportElement.exportedLibrary = new LibraryElementHandle(
+        summaryResynthesizer,
+        new ElementLocationImpl.con3(<String>[exportedLibraryUri]));
+    exportElement.uri = serializedExportPublic.uri;
+    exportElement.combinators =
+        serializedExportPublic.combinators.map(buildCombinator).toList();
+    exportElement.uriOffset = serializedExportNonPublic.uriOffset;
+    exportElement.uriEnd = serializedExportNonPublic.uriEnd;
+    return exportElement;
+  }
+
+  /**
+   * Resynthesize a [FieldElement].
+   */
+  FieldElement buildField(UnlinkedVariable serializedField) {
+    FieldElementImpl fieldElement =
+        new FieldElementImpl(serializedField.name, -1);
+    fieldElement.type = buildType(serializedField.type);
+    fieldElement.const3 = serializedField.isConst;
+    return fieldElement;
+  }
+
+  /**
+   * Build the implicit getter and setter associated with [element], and place
+   * them in [holder].
+   */
+  void buildImplicitAccessors(
+      PropertyInducingElementImpl element, ElementHolder holder) {
+    String name = element.name;
+    DartType type = element.type;
+    PropertyAccessorElementImpl getter =
+        new PropertyAccessorElementImpl(name, element.nameOffset);
+    getter.getter = true;
+    getter.static = element.isStatic;
+    getter.synthetic = true;
+    getter.returnType = type;
+    getter.type = new FunctionTypeImpl(getter);
+    getter.variable = element;
+    getter.hasImplicitReturnType = element.hasImplicitType;
+    holder.addAccessor(getter);
+    element.getter = getter;
+    if (!(element.isConst || element.isFinal)) {
+      PropertyAccessorElementImpl setter =
+          new PropertyAccessorElementImpl(name, element.nameOffset);
+      setter.setter = true;
+      setter.static = element.isStatic;
+      setter.synthetic = true;
+      setter.parameters = <ParameterElement>[
+        new ParameterElementImpl('_$name', element.nameOffset)
+          ..synthetic = true
+          ..type = type
+          ..parameterKind = ParameterKind.REQUIRED
+      ];
+      setter.returnType = VoidTypeImpl.instance;
+      setter.type = new FunctionTypeImpl(setter);
+      setter.variable = element;
+      holder.addAccessor(setter);
+      element.setter = setter;
+    }
+  }
+
+  /**
+   * Build the implicit field associated with a getter or setter, and place it
+   * in [holder].
+   */
+  FieldElementImpl buildImplicitField(String name, DartType type,
+      UnlinkedExecutableKind kind, ElementHolder holder) {
+    FieldElementImpl field = holder.getField(name);
+    if (field == null) {
+      field = new FieldElementImpl(name, -1);
+      field.synthetic = true;
+      field.final2 = kind == UnlinkedExecutableKind.getter;
+      field.type = type;
+      holder.addField(field);
+      return field;
+    } else {
+      // TODO(paulberry): what if the getter and setter have a type mismatch?
+      field.final2 = false;
+      return field;
+    }
+  }
+
+  /**
+   * Build the implicit top level variable associated with a getter or setter,
+   * and place it in [holder].
+   */
+  PropertyInducingElementImpl buildImplicitTopLevelVariable(
+      String name, UnlinkedExecutableKind kind, ElementHolder holder) {
+    TopLevelVariableElementImpl variable = holder.getTopLevelVariable(name);
+    if (variable == null) {
+      variable = new TopLevelVariableElementImpl(name, -1);
+      variable.synthetic = true;
+      variable.final2 = kind == UnlinkedExecutableKind.getter;
+      holder.addTopLevelVariable(variable);
+      return variable;
+    } else {
+      // TODO(paulberry): what if the getter and setter have a type mismatch?
+      variable.final2 = false;
+      return variable;
+    }
+  }
+
+  /**
+   * Resynthesize an [ImportElement].
+   */
+  ImportElement buildImport(UnlinkedImport serializedImport, int dependency) {
+    bool isSynthetic = serializedImport.isImplicit;
+    // TODO(paulberry): it seems problematic for the offset to be 0 for
+    // non-synthetic imports, since it is used to disambiguate location.
+    ImportElementImpl importElement =
+        new ImportElementImpl(isSynthetic ? -1 : serializedImport.offset);
+    String absoluteUri = summaryResynthesizer.sourceFactory
+        .resolveUri(
+            librarySource, prelinkedLibrary.dependencies[dependency].uri)
+        .uri
+        .toString();
+    importElement.importedLibrary = new LibraryElementHandle(
+        summaryResynthesizer,
+        new ElementLocationImpl.con3(<String>[absoluteUri]));
+    if (isSynthetic) {
+      importElement.synthetic = true;
+    } else {
+      importElement.uri = serializedImport.uri;
+      importElement.uriOffset = serializedImport.uriOffset;
+      importElement.uriEnd = serializedImport.uriEnd;
+    }
+    if (serializedImport.prefixReference != 0) {
+      UnlinkedReference serializedPrefix =
+          unlinkedUnits[0].references[serializedImport.prefixReference];
+      importElement.prefix = new PrefixElementImpl(
+          serializedPrefix.name, serializedImport.prefixOffset);
+    }
+    importElement.combinators =
+        serializedImport.combinators.map(buildCombinator).toList();
+    return importElement;
+  }
+
+  /**
+   * Main entry point.  Resynthesize the [LibraryElement] and return it.
+   */
+  LibraryElement buildLibrary() {
+    bool hasName = unlinkedUnits[0].libraryName.isNotEmpty;
+    LibraryElementImpl libraryElement = new LibraryElementImpl(
+        summaryResynthesizer.context,
+        unlinkedUnits[0].libraryName,
+        hasName ? unlinkedUnits[0].libraryNameOffset : -1,
+        unlinkedUnits[0].libraryNameLength);
+    buildDocumentation(
+        libraryElement, unlinkedUnits[0].libraryDocumentationComment);
+    CompilationUnitElementImpl definingCompilationUnit =
+        new CompilationUnitElementImpl(librarySource.shortName);
+    libraryElement.definingCompilationUnit = definingCompilationUnit;
+    definingCompilationUnit.source = librarySource;
+    definingCompilationUnit.librarySource = librarySource;
+    List<CompilationUnitElement> parts = <CompilationUnitElement>[];
+    UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0];
+    assert(unlinkedDefiningUnit.publicNamespace.parts.length + 1 ==
+        prelinkedLibrary.units.length);
+    for (int i = 1; i < prelinkedLibrary.units.length; i++) {
+      CompilationUnitElementImpl part = buildPart(
+          unlinkedDefiningUnit.publicNamespace.parts[i - 1],
+          unlinkedDefiningUnit.parts[i - 1],
+          unlinkedUnits[i]);
+      parts.add(part);
+    }
+    libraryElement.parts = parts;
+    List<ImportElement> imports = <ImportElement>[];
+    for (int i = 0; i < unlinkedDefiningUnit.imports.length; i++) {
+      imports.add(buildImport(unlinkedDefiningUnit.imports[i],
+          prelinkedLibrary.importDependencies[i]));
+    }
+    libraryElement.imports = imports;
+    List<ExportElement> exports = <ExportElement>[];
+    assert(unlinkedDefiningUnit.exports.length ==
+        unlinkedDefiningUnit.publicNamespace.exports.length);
+    for (int i = 0; i < unlinkedDefiningUnit.exports.length; i++) {
+      exports.add(buildExport(unlinkedDefiningUnit.publicNamespace.exports[i],
+          unlinkedDefiningUnit.exports[i]));
+    }
+    libraryElement.exports = exports;
+    populateUnit(definingCompilationUnit, 0);
+    for (int i = 0; i < parts.length; i++) {
+      populateUnit(parts[i], i + 1);
+    }
+    if (isCoreLibrary) {
+      ClassElement objectElement = libraryElement.getType('Object');
+      assert(objectElement != null);
+      for (ClassElementImpl classElement in delayedObjectSubclasses) {
+        classElement.supertype = objectElement.type;
+      }
+    }
+    // Compute namespaces.
+    libraryElement.publicNamespace =
+        new NamespaceBuilder().createPublicNamespaceForLibrary(libraryElement);
+    // TODO(paulberry): compute the export namespace from prelinked data, so
+    // that exported libraries won't be unnecessarily resynthesized.
+    libraryElement.exportNamespace =
+        new NamespaceBuilder().createExportNamespaceForLibrary(libraryElement);
+    // Find the entry point.
+    libraryElement.entryPoint =
+        libraryElement.exportNamespace.definedNames.values.firstWhere(
+            (element) => element is FunctionElement && element.isEntryPoint,
+            orElse: () => null);
+    // Done.
+    return libraryElement;
+  }
+
+  /**
+   * Resynthesize a [ParameterElement].
+   */
+  ParameterElement buildParameter(UnlinkedParam serializedParameter) {
+    ParameterElementImpl parameterElement = new ParameterElementImpl(
+        serializedParameter.name, serializedParameter.nameOffset);
+    if (serializedParameter.isFunctionTyped) {
+      FunctionElementImpl parameterTypeElement =
+          new FunctionElementImpl('', -1);
+      parameterTypeElement.synthetic = true;
+      parameterElement.parameters =
+          serializedParameter.parameters.map(buildParameter).toList();
+      parameterTypeElement.enclosingElement = parameterElement;
+      parameterTypeElement.shareParameters(parameterElement.parameters);
+      if (serializedParameter.type != null) {
+        parameterTypeElement.returnType = buildType(serializedParameter.type);
+      } else {
+        parameterTypeElement.returnType = VoidTypeImpl.instance;
+      }
+      parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
+          parameterTypeElement, null, currentTypeArguments, false);
+    } else {
+      parameterElement.type = buildType(serializedParameter.type);
+      parameterElement.hasImplicitType = serializedParameter.hasImplicitType;
+    }
+    switch (serializedParameter.kind) {
+      case UnlinkedParamKind.named:
+        parameterElement.parameterKind = ParameterKind.NAMED;
+        break;
+      case UnlinkedParamKind.positional:
+        parameterElement.parameterKind = ParameterKind.POSITIONAL;
+        break;
+      case UnlinkedParamKind.required:
+        parameterElement.parameterKind = ParameterKind.REQUIRED;
+        break;
+    }
+    return parameterElement;
+  }
+
+  /**
+   * Create, but do not populate, the [CompilationUnitElement] for a part other
+   * than the defining compilation unit.
+   */
+  CompilationUnitElementImpl buildPart(
+      String uri, UnlinkedPart partDecl, UnlinkedUnit serializedPart) {
+    Source unitSource =
+        summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
+    CompilationUnitElementImpl partUnit =
+        new CompilationUnitElementImpl(unitSource.shortName);
+    partUnit.uriOffset = partDecl.uriOffset;
+    partUnit.uriEnd = partDecl.uriEnd;
+    partUnit.source = unitSource;
+    partUnit.librarySource = librarySource;
+    partUnit.uri = uri;
+    return partUnit;
+  }
+
+  /**
+   * Build a [DartType] object based on an [UnlinkedTypeRef].  This [DartType]
+   * may refer to elements in other libraries than the library being
+   * deserialized, so handles are used to avoid having to deserialize other
+   * libraries in the process.
+   */
+  DartType buildType(UnlinkedTypeRef type) {
+    if (type.paramReference != 0) {
+      // TODO(paulberry): make this work for generic methods.
+      return currentTypeParameters[
+              currentTypeParameters.length - type.paramReference]
+          .type;
+    } else {
+      // TODO(paulberry): handle references to things other than classes (note:
+      // this should only occur in the case of erroneous code).
+      // TODO(paulberry): test reference to something inside a part.
+      // TODO(paulberry): test reference to something inside a part of the
+      // current lib.
+      UnlinkedReference reference = unlinkedUnit.references[type.reference];
+      PrelinkedReference referenceResolution =
+          prelinkedUnit.references[type.reference];
+      String referencedLibraryUri;
+      String partUri;
+      if (referenceResolution.dependency != 0) {
+        PrelinkedDependency dependency =
+            prelinkedLibrary.dependencies[referenceResolution.dependency];
+        Source referencedLibrarySource = summaryResynthesizer.sourceFactory
+            .resolveUri(librarySource, dependency.uri);
+        referencedLibraryUri = referencedLibrarySource.uri.toString();
+        // TODO(paulberry): consider changing Location format so that this is
+        // not necessary (2nd string in location should just be the unit
+        // number).
+        if (referenceResolution.unit != 0) {
+          UnlinkedUnit referencedLibraryDefiningUnit =
+              summaryResynthesizer.getUnlinkedSummary(referencedLibraryUri);
+          String uri = referencedLibraryDefiningUnit.publicNamespace.parts[
+              referenceResolution.unit - 1];
+          Source partSource = summaryResynthesizer.sourceFactory
+              .resolveUri(referencedLibrarySource, uri);
+          partUri = partSource.uri.toString();
+        } else {
+          partUri = referencedLibraryUri;
+        }
+      } else if (referenceResolution.kind ==
+          PrelinkedReferenceKind.unresolved) {
+        return summaryResynthesizer.typeProvider.undefinedType;
+      } else if (reference.name.isEmpty) {
+        return summaryResynthesizer.typeProvider.dynamicType;
+      } else {
+        referencedLibraryUri = librarySource.uri.toString();
+        if (referenceResolution.unit != 0) {
+          String uri = unlinkedUnits[0].publicNamespace.parts[
+              referenceResolution.unit - 1];
+          Source partSource =
+              summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
+          partUri = partSource.uri.toString();
+        } else {
+          partUri = referencedLibraryUri;
+        }
+      }
+      ElementLocationImpl location = new ElementLocationImpl.con3(
+          <String>[referencedLibraryUri, partUri, reference.name]);
+      List<DartType> typeArguments = const <DartType>[];
+      if (referenceResolution.numTypeParameters != 0) {
+        typeArguments = <DartType>[];
+        for (int i = 0; i < referenceResolution.numTypeParameters; i++) {
+          if (i < type.typeArguments.length) {
+            typeArguments.add(buildType(type.typeArguments[i]));
+          } else {
+            typeArguments.add(summaryResynthesizer.typeProvider.dynamicType);
+          }
+        }
+      }
+      switch (referenceResolution.kind) {
+        case PrelinkedReferenceKind.classOrEnum:
+          return new InterfaceTypeImpl.elementWithNameAndArgs(
+              new ClassElementHandle(summaryResynthesizer, location),
+              reference.name,
+              typeArguments);
+        case PrelinkedReferenceKind.typedef:
+          return new FunctionTypeImpl.elementWithNameAndArgs(
+              new FunctionTypeAliasElementHandle(
+                  summaryResynthesizer, location),
+              reference.name,
+              typeArguments,
+              typeArguments.isNotEmpty);
+        default:
+          // TODO(paulberry): figure out how to handle this case (which should
+          // only occur in the event of erroneous code).
+          throw new UnimplementedError();
+      }
+    }
+  }
+
+  /**
+   * Resynthesize a [FunctionTypeAliasElement] and place it in the
+   * [unitHolder].
+   */
+  void buildTypedef(UnlinkedTypedef serializedTypedef) {
+    try {
+      currentTypeParameters =
+          serializedTypedef.typeParameters.map(buildTypeParameter).toList();
+      for (int i = 0; i < serializedTypedef.typeParameters.length; i++) {
+        finishTypeParameter(
+            serializedTypedef.typeParameters[i], currentTypeParameters[i]);
+      }
+      FunctionTypeAliasElementImpl functionTypeAliasElement =
+          new FunctionTypeAliasElementImpl(
+              serializedTypedef.name, serializedTypedef.nameOffset);
+      functionTypeAliasElement.parameters =
+          serializedTypedef.parameters.map(buildParameter).toList();
+      if (serializedTypedef.returnType != null) {
+        functionTypeAliasElement.returnType =
+            buildType(serializedTypedef.returnType);
+      } else {
+        functionTypeAliasElement.returnType = VoidTypeImpl.instance;
+      }
+      functionTypeAliasElement.type =
+          new FunctionTypeImpl.forTypedef(functionTypeAliasElement);
+      functionTypeAliasElement.typeParameters = currentTypeParameters;
+      buildDocumentation(
+          functionTypeAliasElement, serializedTypedef.documentationComment);
+      unitHolder.addTypeAlias(functionTypeAliasElement);
+    } finally {
+      currentTypeParameters = <TypeParameterElement>[];
+    }
+  }
+
+  /**
+   * Resynthesize a [TypeParameterElement], handling all parts of its except
+   * its bound.
+   *
+   * The bound is deferred until later since it may refer to other type
+   * parameters that have not been resynthesized yet.  To handle the bound,
+   * call [finishTypeParameter].
+   */
+  TypeParameterElement buildTypeParameter(
+      UnlinkedTypeParam serializedTypeParameter) {
+    TypeParameterElementImpl typeParameterElement =
+        new TypeParameterElementImpl(
+            serializedTypeParameter.name, serializedTypeParameter.nameOffset);
+    typeParameterElement.type = new TypeParameterTypeImpl(typeParameterElement);
+    return typeParameterElement;
+  }
+
+  /**
+   * Resynthesize a [TopLevelVariableElement] or [FieldElement].
+   */
+  void buildVariable(UnlinkedVariable serializedVariable,
+      [ElementHolder holder]) {
+    if (holder == null) {
+      TopLevelVariableElementImpl element = new TopLevelVariableElementImpl(
+          serializedVariable.name, serializedVariable.nameOffset);
+      buildVariableCommonParts(element, serializedVariable);
+      unitHolder.addTopLevelVariable(element);
+      buildImplicitAccessors(element, unitHolder);
+    } else {
+      FieldElementImpl element = new FieldElementImpl(
+          serializedVariable.name, serializedVariable.nameOffset);
+      buildVariableCommonParts(element, serializedVariable);
+      element.static = serializedVariable.isStatic;
+      holder.addField(element);
+      buildImplicitAccessors(element, holder);
+    }
+  }
+
+  /**
+   * Handle the parts that are common to top level variables and fields.
+   */
+  void buildVariableCommonParts(PropertyInducingElementImpl element,
+      UnlinkedVariable serializedVariable) {
+    element.type = buildType(serializedVariable.type);
+    element.const3 = serializedVariable.isConst;
+    element.hasImplicitType = serializedVariable.hasImplicitType;
+    buildDocumentation(element, serializedVariable.documentationComment);
+  }
+
+  /**
+   * Finish creating a [TypeParameterElement] by deserializing its bound.
+   */
+  void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter,
+      TypeParameterElementImpl typeParameterElement) {
+    if (serializedTypeParameter.bound != null) {
+      typeParameterElement.bound = buildType(serializedTypeParameter.bound);
+    }
+  }
+
+  /**
+   * Populate a [CompilationUnitElement] by deserializing all the elements
+   * contained in it.
+   */
+  void populateUnit(CompilationUnitElementImpl unit, int unitNum) {
+    prelinkedUnit = prelinkedLibrary.units[unitNum];
+    unlinkedUnit = unlinkedUnits[unitNum];
+    unitHolder = new ElementHolder();
+    unlinkedUnit.classes.forEach(buildClass);
+    unlinkedUnit.enums.forEach(buildEnum);
+    unlinkedUnit.executables.forEach(buildExecutable);
+    unlinkedUnit.typedefs.forEach(buildTypedef);
+    unlinkedUnit.variables.forEach(buildVariable);
+    String absoluteUri = unit.source.uri.toString();
+    unit.accessors = unitHolder.accessors;
+    unit.enums = unitHolder.enums;
+    unit.functions = unitHolder.functions;
+    List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases;
+    for (FunctionTypeAliasElementImpl typeAlias in typeAliases) {
+      if (typeAlias.isSynthetic) {
+        typeAlias.enclosingElement = unit;
+      }
+    }
+    unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList();
+    unit.types = unitHolder.types;
+    unit.topLevelVariables = unitHolder.topLevelVariables;
+    Map<String, Element> elementMap = <String, Element>{};
+    for (ClassElement cls in unit.types) {
+      elementMap[cls.name] = cls;
+    }
+    for (ClassElement cls in unit.enums) {
+      elementMap[cls.name] = cls;
+    }
+    for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) {
+      elementMap[typeAlias.name] = typeAlias;
+    }
+    resummarizedElements[absoluteUri] = elementMap;
+    unitHolder = null;
+    prelinkedUnit = null;
+    unlinkedUnit = null;
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
new file mode 100644
index 0000000..0eac910
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -0,0 +1,740 @@
+// 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 serialization.elements;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/name_filter.dart';
+
+/**
+ * Serialize all the elements in [lib] to a summary using [ctx] as the context
+ * for building the summary, and using [typeProvider] to find built-in types.
+ */
+LibrarySerializationResult serializeLibrary(
+    LibraryElement lib, TypeProvider typeProvider) {
+  var serializer = new _LibrarySerializer(lib, typeProvider);
+  PrelinkedLibraryBuilder prelinked = serializer.serializeLibrary();
+  return new LibrarySerializationResult(
+      prelinked, serializer.unlinkedUnits, serializer.unitUris);
+}
+
+/**
+ * Data structure holding the result of serializing a [LibraryElement].
+ */
+class LibrarySerializationResult {
+  /**
+   * Pre-linked information the given library.
+   */
+  final PrelinkedLibraryBuilder prelinked;
+
+  /**
+   * Unlinked information for the compilation units constituting the library.
+   * The zeroth entry in the list is the defining compilation unit; the
+   * remaining entries are the parts, in the order listed in the defining
+   * compilation unit's part declarations.
+   */
+  final List<UnlinkedUnitBuilder> unlinkedUnits;
+
+  /**
+   * Absolute URI of each compilation unit appearing in the library.
+   */
+  final List<String> unitUris;
+
+  LibrarySerializationResult(this.prelinked, this.unlinkedUnits, this.unitUris);
+}
+
+/**
+ * Instances of this class keep track of intermediate state during
+ * serialization of a single library.`
+ */
+class _LibrarySerializer {
+  /**
+   * The library to be serialized.
+   */
+  final LibraryElement libraryElement;
+
+  /**
+   * The type provider.  This is used to locate the library for `dart:core`.
+   */
+  final TypeProvider typeProvider;
+
+  /**
+   * List of objects which should be written to [PrelinkedLibrary.units].
+   */
+  final List<PrelinkedUnitBuilder> prelinkedUnits = <PrelinkedUnitBuilder>[];
+
+  /**
+   * List of unlinked units corresponding to the pre-linked units in
+   * [prelinkedUnits],
+   */
+  final List<UnlinkedUnitBuilder> unlinkedUnits = <UnlinkedUnitBuilder>[];
+
+  /**
+   * List of absolute URIs of the compilation units in the library.
+   */
+  final List<String> unitUris = <String>[];
+
+  /**
+   * Map from [LibraryElement] to the index of the entry in the "dependency
+   * table" that refers to it.
+   */
+  final Map<LibraryElement, int> dependencyMap = <LibraryElement, int>{};
+
+  /**
+   * The "dependency table".  This is the list of objects which should be
+   * written to [PrelinkedLibrary.dependencies].
+   */
+  final List<PrelinkedDependencyBuilder> dependencies =
+      <PrelinkedDependencyBuilder>[];
+
+  /**
+   * The prelinked portion of the "imports table".  This is the list of ints
+   * which should be written to [PrelinkedLibrary.imports].
+   */
+  final List<int> prelinkedImports = <int>[];
+
+  /**
+   * Map from [Element] to the index of the entry in the "references table"
+   * that refers to it.
+   */
+  final Map<Element, int> referenceMap = <Element, int>{};
+
+  /**
+   * The unlinked portion of the "references table".  This is the list of
+   * objects which should be written to [UnlinkedUnit.references].
+   */
+  List<UnlinkedReferenceBuilder> unlinkedReferences;
+
+  /**
+   * The prelinked portion of the "references table".  This is the list of
+   * objects which should be written to [PrelinkedUnit.references].
+   */
+  List<PrelinkedReferenceBuilder> prelinkedReferences;
+
+  //final Map<String, int> prefixIndices = <String, int>{};
+
+  /**
+   * Index into the "references table" representing an unresolved reference, if
+   * such an index exists.  `null` if no such entry has been made in the
+   * references table yet.
+   */
+  int unresolvedReferenceIndex = null;
+
+  /**
+   * Set of libraries which have been seen so far while visiting the transitive
+   * closure of exports.
+   */
+  final Set<LibraryElement> librariesAddedToTransitiveExportClosure =
+      new Set<LibraryElement>();
+
+  /**
+   * Map from imported element to the prefix which may be used to refer to that
+   * element; elements for which no prefix is needed are absent from this map.
+   */
+  final Map<Element, PrefixElement> prefixMap = <Element, PrefixElement>{};
+
+  _LibrarySerializer(this.libraryElement, this.typeProvider) {
+    dependencies.add(encodePrelinkedDependency());
+    dependencyMap[libraryElement] = 0;
+  }
+
+  /**
+   * Retrieve the library element for `dart:core`.
+   */
+  LibraryElement get coreLibrary => typeProvider.objectType.element.library;
+
+  /**
+   * Add all classes, enums, typedefs, executables, and top level variables
+   * from the given compilation unit [element] to the library summary.
+   * [unitNum] indicates the ordinal position of this compilation unit in the
+   * library.
+   */
+  void addCompilationUnitElements(CompilationUnitElement element, int unitNum) {
+    UnlinkedUnitBuilder b = new UnlinkedUnitBuilder();
+    referenceMap.clear();
+    unlinkedReferences = <UnlinkedReferenceBuilder>[encodeUnlinkedReference()];
+    prelinkedReferences = <PrelinkedReferenceBuilder>[
+      encodePrelinkedReference(kind: PrelinkedReferenceKind.classOrEnum)
+    ];
+    List<UnlinkedPublicNameBuilder> names = <UnlinkedPublicNameBuilder>[];
+    for (PropertyAccessorElement accessor in element.accessors) {
+      if (accessor.isPublic) {
+        names.add(encodeUnlinkedPublicName(
+            kind: PrelinkedReferenceKind.other,
+            name: accessor.name,
+            numTypeParameters: accessor.typeParameters.length));
+      }
+    }
+    for (ClassElement cls in element.types) {
+      if (cls.isPublic) {
+        names.add(encodeUnlinkedPublicName(
+            kind: PrelinkedReferenceKind.classOrEnum,
+            name: cls.name,
+            numTypeParameters: cls.typeParameters.length));
+      }
+    }
+    for (ClassElement enm in element.enums) {
+      if (enm.isPublic) {
+        names.add(encodeUnlinkedPublicName(
+            kind: PrelinkedReferenceKind.classOrEnum, name: enm.name));
+      }
+    }
+    for (FunctionElement function in element.functions) {
+      if (function.isPublic) {
+        names.add(encodeUnlinkedPublicName(
+            kind: PrelinkedReferenceKind.other,
+            name: function.name,
+            numTypeParameters: function.typeParameters.length));
+      }
+    }
+    for (FunctionTypeAliasElement typedef in element.functionTypeAliases) {
+      if (typedef.isPublic) {
+        names.add(encodeUnlinkedPublicName(
+            kind: PrelinkedReferenceKind.typedef,
+            name: typedef.name,
+            numTypeParameters: typedef.typeParameters.length));
+      }
+    }
+    if (unitNum == 0) {
+      if (libraryElement.name.isNotEmpty) {
+        b.libraryName = libraryElement.name;
+        b.libraryNameOffset = libraryElement.nameOffset;
+        b.libraryNameLength = libraryElement.nameLength;
+        b.libraryDocumentationComment = serializeDocumentation(libraryElement);
+      }
+      b.publicNamespace = encodeUnlinkedPublicNamespace(
+          exports: libraryElement.exports.map(serializeExportPublic).toList(),
+          parts: libraryElement.parts
+              .map((CompilationUnitElement e) => e.uri)
+              .toList(),
+          names: names);
+      b.exports = libraryElement.exports.map(serializeExportNonPublic).toList();
+      b.imports = libraryElement.imports.map(serializeImport).toList();
+      b.parts = libraryElement.parts
+          .map((CompilationUnitElement e) =>
+              encodeUnlinkedPart(uriOffset: e.uriOffset, uriEnd: e.uriEnd))
+          .toList();
+    } else {
+      // TODO(paulberry): we need to figure out a way to record library, part,
+      // import, and export declarations that appear in non-defining
+      // compilation units (even though such declarations are prohibited by the
+      // language), so that if the user makes code changes that cause a
+      // non-defining compilation unit to become a defining compilation unit,
+      // we can create a correct summary by simply re-linking.
+      b.publicNamespace = encodeUnlinkedPublicNamespace(names: names);
+    }
+    b.classes = element.types.map(serializeClass).toList();
+    b.enums = element.enums.map(serializeEnum).toList();
+    b.typedefs = element.functionTypeAliases.map(serializeTypedef).toList();
+    List<UnlinkedExecutableBuilder> executables =
+        element.functions.map(serializeExecutable).toList();
+    for (PropertyAccessorElement accessor in element.accessors) {
+      if (!accessor.isSynthetic) {
+        executables.add(serializeExecutable(accessor));
+      }
+    }
+    b.executables = executables;
+    List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
+    for (PropertyAccessorElement accessor in element.accessors) {
+      if (accessor.isSynthetic && accessor.isGetter) {
+        PropertyInducingElement variable = accessor.variable;
+        if (variable != null) {
+          assert(!variable.isSynthetic);
+          variables.add(serializeVariable(variable));
+        }
+      }
+    }
+    b.variables = variables;
+    b.references = unlinkedReferences;
+    unlinkedUnits.add(b);
+    prelinkedUnits.add(encodePrelinkedUnit(references: prelinkedReferences));
+    unitUris.add(element.source.uri.toString());
+    unlinkedReferences = null;
+    prelinkedReferences = null;
+  }
+
+  /**
+   * Add [exportedLibrary] (and the transitive closure of all libraries it
+   * exports) to the dependency table ([PrelinkedLibrary.dependencies]).
+   */
+  void addTransitiveExportClosure(LibraryElement exportedLibrary) {
+    if (librariesAddedToTransitiveExportClosure.add(exportedLibrary)) {
+      serializeDependency(exportedLibrary);
+      for (LibraryElement transitiveExport
+          in exportedLibrary.exportedLibraries) {
+        addTransitiveExportClosure(transitiveExport);
+      }
+    }
+  }
+
+  /**
+   * Fill in [prefixMap] using information from [libraryElement.imports].
+   */
+  void computePrefixMap() {
+    for (ImportElement import in libraryElement.imports) {
+      if (import.prefix == null) {
+        continue;
+      }
+      import.importedLibrary.exportNamespace.definedNames
+          .forEach((String name, Element e) {
+        if (new NameFilter.forNamespaceCombinators(import.combinators)
+            .accepts(name)) {
+          prefixMap[e] = import.prefix;
+        }
+      });
+    }
+  }
+
+  /**
+   * Compute the appropriate De Bruijn index to represent the given type
+   * parameter [type].
+   */
+  int findTypeParameterIndex(TypeParameterType type, Element context) {
+    int index = 0;
+    while (context != null) {
+      List<TypeParameterElement> typeParameters;
+      if (context is ClassElement) {
+        typeParameters = context.typeParameters;
+      } else if (context is FunctionTypeAliasElement) {
+        typeParameters = context.typeParameters;
+      } else if (context is ExecutableElement) {
+        typeParameters = context.typeParameters;
+      }
+      if (typeParameters != null) {
+        for (int i = 0; i < typeParameters.length; i++) {
+          TypeParameterElement param = typeParameters[i];
+          if (param == type.element) {
+            return index + typeParameters.length - i;
+          }
+        }
+        index += typeParameters.length;
+      }
+      context = context.enclosingElement;
+    }
+    throw new StateError('Unbound type parameter $type');
+  }
+
+  /**
+   * Serialize the given [classElement], creating an [UnlinkedClass].
+   */
+  UnlinkedClassBuilder serializeClass(ClassElement classElement) {
+    UnlinkedClassBuilder b = new UnlinkedClassBuilder();
+    b.name = classElement.name;
+    b.nameOffset = classElement.nameOffset;
+    b.typeParameters =
+        classElement.typeParameters.map(serializeTypeParam).toList();
+    if (classElement.supertype == null) {
+      b.hasNoSupertype = true;
+    } else if (!classElement.supertype.isObject) {
+      b.supertype = serializeTypeRef(classElement.supertype, classElement);
+    }
+    b.mixins = classElement.mixins
+        .map((InterfaceType t) => serializeTypeRef(t, classElement))
+        .toList();
+    b.interfaces = classElement.interfaces
+        .map((InterfaceType t) => serializeTypeRef(t, classElement))
+        .toList();
+    List<UnlinkedVariableBuilder> fields = <UnlinkedVariableBuilder>[];
+    List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
+    for (ConstructorElement executable in classElement.constructors) {
+      if (!executable.isSynthetic) {
+        executables.add(serializeExecutable(executable));
+      }
+    }
+    for (MethodElement executable in classElement.methods) {
+      executables.add(serializeExecutable(executable));
+    }
+    for (PropertyAccessorElement accessor in classElement.accessors) {
+      if (!accessor.isSynthetic) {
+        executables.add(serializeExecutable(accessor));
+      } else if (accessor.isGetter) {
+        PropertyInducingElement field = accessor.variable;
+        if (field != null && !field.isSynthetic) {
+          fields.add(serializeVariable(field));
+        }
+      }
+    }
+    b.fields = fields;
+    b.executables = executables;
+    b.isAbstract = classElement.isAbstract;
+    b.isMixinApplication = classElement.isMixinApplication;
+    b.documentationComment = serializeDocumentation(classElement);
+    return b;
+  }
+
+  /**
+   * Serialize the given [combinator] into an [UnlinkedCombinator].
+   */
+  UnlinkedCombinatorBuilder serializeCombinator(
+      NamespaceCombinator combinator) {
+    UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder();
+    if (combinator is ShowElementCombinator) {
+      b.shows = combinator.shownNames;
+    } else if (combinator is HideElementCombinator) {
+      b.hides = combinator.hiddenNames;
+    }
+    return b;
+  }
+
+  /**
+   * Return the index of the entry in the dependency table
+   * ([PrelinkedLibrary.dependencies]) for the given [dependentLibrary].  A new
+   * entry is added to the table if necessary to satisfy the request.
+   */
+  int serializeDependency(LibraryElement dependentLibrary) {
+    return dependencyMap.putIfAbsent(dependentLibrary, () {
+      int index = dependencies.length;
+      List<String> parts = dependentLibrary.parts
+          .map((CompilationUnitElement e) => e.source.uri.toString())
+          .toList();
+      dependencies.add(encodePrelinkedDependency(
+          uri: dependentLibrary.source.uri.toString(), parts: parts));
+      return index;
+    });
+  }
+
+  /**
+   * Serialize documentation from the given [element], creating an
+   * [UnlinkedDocumentationComment].
+   *
+   * If [element] has no documentation, `null` is returned.
+   */
+  UnlinkedDocumentationCommentBuilder serializeDocumentation(Element element) {
+    if (element.documentationComment == null) {
+      return null;
+    }
+    return encodeUnlinkedDocumentationComment(
+        text: element.documentationComment,
+        offset: element.docRange.offset,
+        length: element.docRange.length);
+  }
+
+  /**
+   * Return the index of the entry in the references table
+   * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references])
+   * representing the pseudo-type `dynamic`.
+   */
+  int serializeDynamicReference() => 0;
+
+  /**
+   * Serialize the given [enumElement], creating an [UnlinkedEnum].
+   */
+  UnlinkedEnumBuilder serializeEnum(ClassElement enumElement) {
+    UnlinkedEnumBuilder b = new UnlinkedEnumBuilder();
+    b.name = enumElement.name;
+    b.nameOffset = enumElement.nameOffset;
+    List<UnlinkedEnumValueBuilder> values = <UnlinkedEnumValueBuilder>[];
+    for (FieldElement field in enumElement.fields) {
+      if (field.isConst && field.type.element == enumElement) {
+        values.add(encodeUnlinkedEnumValue(
+            name: field.name,
+            nameOffset: field.nameOffset,
+            documentationComment: serializeDocumentation(field)));
+      }
+    }
+    b.values = values;
+    b.documentationComment = serializeDocumentation(enumElement);
+    return b;
+  }
+
+  /**
+   * Serialize the given [executableElement], creating an [UnlinkedExecutable].
+   */
+  UnlinkedExecutableBuilder serializeExecutable(
+      ExecutableElement executableElement) {
+    UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
+    b.name = executableElement.name;
+    b.nameOffset = executableElement.nameOffset;
+    if (executableElement is! ConstructorElement &&
+        !executableElement.type.returnType.isVoid) {
+      b.returnType = serializeTypeRef(
+          executableElement.type.returnType, executableElement);
+    }
+    b.typeParameters =
+        executableElement.typeParameters.map(serializeTypeParam).toList();
+    b.parameters =
+        executableElement.type.parameters.map(serializeParam).toList();
+    if (executableElement is PropertyAccessorElement) {
+      if (executableElement.isGetter) {
+        b.kind = UnlinkedExecutableKind.getter;
+      } else {
+        b.kind = UnlinkedExecutableKind.setter;
+      }
+    } else if (executableElement is ConstructorElement) {
+      b.kind = UnlinkedExecutableKind.constructor;
+      b.isConst = executableElement.isConst;
+      b.isFactory = executableElement.isFactory;
+    } else {
+      b.kind = UnlinkedExecutableKind.functionOrMethod;
+    }
+    b.isAbstract = executableElement.isAbstract;
+    b.isStatic = executableElement.isStatic &&
+        executableElement.enclosingElement is ClassElement;
+    b.hasImplicitReturnType = executableElement.hasImplicitReturnType;
+    b.isExternal = executableElement.isExternal;
+    b.documentationComment = serializeDocumentation(executableElement);
+    return b;
+  }
+
+  /**
+   * Serialize the given [exportElement] into an [UnlinkedExportNonPublic].
+   */
+  UnlinkedExportNonPublicBuilder serializeExportNonPublic(
+      ExportElement exportElement) {
+    UnlinkedExportNonPublicBuilder b = new UnlinkedExportNonPublicBuilder();
+    b.offset = exportElement.nameOffset;
+    b.uriOffset = exportElement.uriOffset;
+    b.uriEnd = exportElement.uriEnd;
+    return b;
+  }
+
+  /**
+   * Serialize the given [exportElement] into an [UnlinkedExportPublic].
+   */
+  UnlinkedExportPublicBuilder serializeExportPublic(
+      ExportElement exportElement) {
+    UnlinkedExportPublicBuilder b = new UnlinkedExportPublicBuilder();
+    b.uri = exportElement.uri;
+    b.combinators = exportElement.combinators.map(serializeCombinator).toList();
+    return b;
+  }
+
+  /**
+   * Serialize the given [importElement] yielding an [UnlinkedImportBuilder].
+   * Also, add pre-linked information about it to the [prelinkedImports] list.
+   */
+  UnlinkedImportBuilder serializeImport(ImportElement importElement) {
+    UnlinkedImportBuilder b = new UnlinkedImportBuilder();
+    b.isDeferred = importElement.isDeferred;
+    b.offset = importElement.nameOffset;
+    b.combinators = importElement.combinators.map(serializeCombinator).toList();
+    if (importElement.prefix != null) {
+      b.prefixReference = serializePrefix(importElement.prefix);
+      b.prefixOffset = importElement.prefix.nameOffset;
+    }
+    if (importElement.isSynthetic) {
+      b.isImplicit = true;
+    } else {
+      b.uri = importElement.uri;
+      b.uriOffset = importElement.uriOffset;
+      b.uriEnd = importElement.uriEnd;
+    }
+    addTransitiveExportClosure(importElement.importedLibrary);
+    prelinkedImports.add(serializeDependency(importElement.importedLibrary));
+    return b;
+  }
+
+  /**
+   * Serialize the whole library element into a [PrelinkedLibrary].  Should be
+   * called exactly once for each instance of [_LibrarySerializer].
+   *
+   * The unlinked compilation units are stored in [unlinkedUnits], and their
+   * absolute URIs are stored in [unitUris].
+   */
+  PrelinkedLibraryBuilder serializeLibrary() {
+    computePrefixMap();
+    PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder();
+    addCompilationUnitElements(libraryElement.definingCompilationUnit, 0);
+    for (int i = 0; i < libraryElement.parts.length; i++) {
+      addCompilationUnitElements(libraryElement.parts[i], i + 1);
+    }
+    pb.units = prelinkedUnits;
+    pb.dependencies = dependencies;
+    pb.importDependencies = prelinkedImports;
+    return pb;
+  }
+
+  /**
+   * Serialize the given [parameter] into an [UnlinkedParam].
+   */
+  UnlinkedParamBuilder serializeParam(ParameterElement parameter,
+      [Element context]) {
+    context ??= parameter;
+    UnlinkedParamBuilder b = new UnlinkedParamBuilder();
+    b.name = parameter.name;
+    b.nameOffset = parameter.nameOffset;
+    switch (parameter.parameterKind) {
+      case ParameterKind.REQUIRED:
+        b.kind = UnlinkedParamKind.required;
+        break;
+      case ParameterKind.POSITIONAL:
+        b.kind = UnlinkedParamKind.positional;
+        break;
+      case ParameterKind.NAMED:
+        b.kind = UnlinkedParamKind.named;
+        break;
+    }
+    b.isInitializingFormal = parameter.isInitializingFormal;
+    DartType type = parameter.type;
+    if (type is FunctionType) {
+      b.isFunctionTyped = true;
+      if (!type.returnType.isVoid) {
+        b.type = serializeTypeRef(type.returnType, parameter);
+      }
+      b.parameters = type.parameters
+          .map((parameter) => serializeParam(parameter, context))
+          .toList();
+    } else {
+      b.type = serializeTypeRef(type, context);
+      b.hasImplicitType = parameter.hasImplicitType;
+    }
+    return b;
+  }
+
+  /**
+   * Serialize the given [prefix] into an index into the references table.
+   */
+  int serializePrefix(PrefixElement element) {
+    return referenceMap.putIfAbsent(element, () {
+      assert(unlinkedReferences.length == prelinkedReferences.length);
+      int index = unlinkedReferences.length;
+      unlinkedReferences.add(encodeUnlinkedReference(name: element.name));
+      prelinkedReferences
+          .add(encodePrelinkedReference(kind: PrelinkedReferenceKind.prefix));
+      return index;
+    });
+  }
+
+  /**
+   * Serialize the given [typedefElement], creating an [UnlinkedTypedef].
+   */
+  UnlinkedTypedefBuilder serializeTypedef(
+      FunctionTypeAliasElement typedefElement) {
+    UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder();
+    b.name = typedefElement.name;
+    b.nameOffset = typedefElement.nameOffset;
+    b.typeParameters =
+        typedefElement.typeParameters.map(serializeTypeParam).toList();
+    if (!typedefElement.returnType.isVoid) {
+      b.returnType =
+          serializeTypeRef(typedefElement.returnType, typedefElement);
+    }
+    b.parameters = typedefElement.parameters.map(serializeParam).toList();
+    b.documentationComment = serializeDocumentation(typedefElement);
+    return b;
+  }
+
+  /**
+   * Serialize the given [typeParameter] into an [UnlinkedTypeParam].
+   */
+  UnlinkedTypeParamBuilder serializeTypeParam(
+      TypeParameterElement typeParameter) {
+    UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder();
+    b.name = typeParameter.name;
+    b.nameOffset = typeParameter.nameOffset;
+    if (typeParameter.bound != null) {
+      b.bound = serializeTypeRef(typeParameter.bound, typeParameter);
+    }
+    return b;
+  }
+
+  /**
+   * Serialize the given [type] into an [UnlinkedTypeRef].
+   */
+  UnlinkedTypeRefBuilder serializeTypeRef(DartType type, Element context) {
+    UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder();
+    if (type is TypeParameterType) {
+      b.paramReference = findTypeParameterIndex(type, context);
+    } else {
+      Element element = type.element;
+      LibraryElement dependentLibrary = element.library;
+      if (dependentLibrary == null) {
+        assert(type.isDynamic);
+        if (type is UndefinedTypeImpl) {
+          b.reference = serializeUnresolvedReference();
+        } else {
+          b.reference = serializeDynamicReference();
+        }
+      } else {
+        b.reference = referenceMap.putIfAbsent(element, () {
+          assert(unlinkedReferences.length == prelinkedReferences.length);
+          CompilationUnitElement unitElement =
+              element.getAncestor((Element e) => e is CompilationUnitElement);
+          int unit = dependentLibrary.units.indexOf(unitElement);
+          assert(unit != -1);
+          int numTypeParameters = 0;
+          if (element is TypeParameterizedElement) {
+            numTypeParameters = element.typeParameters.length;
+          }
+          // Figure out a prefix that may be used to refer to the given type.
+          // TODO(paulberry): to avoid subtle relinking inconsistencies we
+          // should use the actual prefix from the AST (a given type may be
+          // reachable via multiple prefixes), but sadly, this information is
+          // not recorded in the element model.
+          int prefixReference = 0;
+          PrefixElement prefix = prefixMap[element];
+          if (prefix != null) {
+            prefixReference = serializePrefix(prefix);
+          }
+          int index = unlinkedReferences.length;
+          unlinkedReferences.add(encodeUnlinkedReference(
+              name: element.name, prefixReference: prefixReference));
+          prelinkedReferences.add(encodePrelinkedReference(
+              dependency: serializeDependency(dependentLibrary),
+              kind: element is FunctionTypeAliasElement
+                  ? PrelinkedReferenceKind.typedef
+                  : PrelinkedReferenceKind.classOrEnum,
+              unit: unit,
+              numTypeParameters: numTypeParameters));
+          return index;
+        });
+      }
+      List<DartType> typeArguments;
+      if (type is InterfaceType) {
+        typeArguments = type.typeArguments;
+      } else if (type is FunctionType) {
+        typeArguments = type.typeArguments;
+      }
+      if (typeArguments != null &&
+          typeArguments.any((DartType argument) => !argument.isDynamic)) {
+        b.typeArguments = typeArguments
+            .map((DartType t) => serializeTypeRef(t, context))
+            .toList();
+      }
+    }
+    return b;
+  }
+
+  /**
+   * Return the index of the entry in the references table
+   * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references]) used for
+   * unresolved references.  A new entry is added to the table if necessary to
+   * satisfy the request.
+   */
+  int serializeUnresolvedReference() {
+    // TODO(paulberry): in order for relinking to work, we need to record the
+    // name and prefix of the unresolved symbol.  This is not (yet) encoded in
+    // the element model.  For the moment we use a name that can't possibly
+    // ever exist.
+    if (unresolvedReferenceIndex == null) {
+      assert(unlinkedReferences.length == prelinkedReferences.length);
+      unresolvedReferenceIndex = unlinkedReferences.length;
+      unlinkedReferences.add(encodeUnlinkedReference(name: '*unresolved*'));
+      prelinkedReferences.add(
+          encodePrelinkedReference(kind: PrelinkedReferenceKind.unresolved));
+    }
+    return unresolvedReferenceIndex;
+  }
+
+  /**
+   * Serialize the given [variable], creating an [UnlinkedVariable].
+   */
+  UnlinkedVariableBuilder serializeVariable(PropertyInducingElement variable) {
+    UnlinkedVariableBuilder b = new UnlinkedVariableBuilder();
+    b.name = variable.name;
+    b.nameOffset = variable.nameOffset;
+    b.type = serializeTypeRef(variable.type, variable);
+    b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement;
+    b.isFinal = variable.isFinal;
+    b.isConst = variable.isConst;
+    b.hasImplicitType = variable.hasImplicitType;
+    b.documentationComment = serializeDocumentation(variable);
+    return b;
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
new file mode 100644
index 0000000..4d9b9fe
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -0,0 +1,362 @@
+// 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.summary.summary_sdk;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/context/cache.dart' show CacheEntry;
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart' show Source, SourceKind;
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:analyzer/src/task/dart.dart'
+    show
+        LIBRARY_ELEMENT1,
+        LIBRARY_ELEMENT2,
+        LIBRARY_ELEMENT3,
+        LIBRARY_ELEMENT4,
+        LIBRARY_ELEMENT5,
+        LIBRARY_ELEMENT6,
+        LIBRARY_ELEMENT7,
+        LIBRARY_ELEMENT8,
+        READY_LIBRARY_ELEMENT2,
+        READY_LIBRARY_ELEMENT5,
+        READY_LIBRARY_ELEMENT6,
+        TYPE_PROVIDER;
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart'
+    show AnalysisTarget, ResultDescriptor, TargetedResult;
+
+/**
+ * An [SdkAnalysisContext] for Dart SDK with a summary [SdkBundle].
+ */
+class SummarySdkAnalysisContext extends SdkAnalysisContext {
+  final SdkBundle bundle;
+  final SummaryTypeProvider typeProvider = new SummaryTypeProvider();
+
+  SummaryResynthesizer resynthesizer;
+
+  SummarySdkAnalysisContext(this.bundle);
+
+  @override
+  bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) {
+    if (resynthesizer == null) {
+      resynthesizer = new SummaryResynthesizer(this, typeProvider,
+          _getPrelinkedSummary, _getUnlinkedSummary, sourceFactory);
+      _buildCoreLibrary();
+      _buildAsyncLibrary();
+    }
+    if (result == TYPE_PROVIDER) {
+      entry.setValue(result, typeProvider, TargetedResult.EMPTY_LIST);
+      return true;
+    }
+    AnalysisTarget target = entry.target;
+//    print('SummarySdkAnalysisContext: $result of $target');
+    if (target is Source && target.isInSystemLibrary) {
+      if (result == LIBRARY_ELEMENT1 ||
+          result == LIBRARY_ELEMENT2 ||
+          result == LIBRARY_ELEMENT3 ||
+          result == LIBRARY_ELEMENT4 ||
+          result == LIBRARY_ELEMENT5 ||
+          result == LIBRARY_ELEMENT6 ||
+          result == LIBRARY_ELEMENT7 ||
+          result == LIBRARY_ELEMENT8 ||
+          result == LIBRARY_ELEMENT) {
+        // TODO(scheglov) try to find a way to avoid listing every result
+        // e.g. "result.whenComplete == LIBRARY_ELEMENT"
+        String uri = target.uri.toString();
+        LibraryElement libraryElement = resynthesizer.getLibraryElement(uri);
+        entry.setValue(result, libraryElement, TargetedResult.EMPTY_LIST);
+        return true;
+      } else if (result == READY_LIBRARY_ELEMENT2 ||
+          result == READY_LIBRARY_ELEMENT5 ||
+          result == READY_LIBRARY_ELEMENT6) {
+        entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+        return true;
+      } else if (result == SOURCE_KIND) {
+        String uri = target.uri.toString();
+        if (bundle.prelinkedLibraryUris.contains(uri)) {
+          entry.setValue(result, SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+        if (bundle.unlinkedUnitUris.contains(uri)) {
+          entry.setValue(result, SourceKind.PART, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+        return false;
+      } else {
+//        throw new UnimplementedError('$result of $target');
+      }
+    }
+    return false;
+  }
+
+  void _buildAsyncLibrary() {
+    LibraryElement library = resynthesizer.getLibraryElement('dart:async');
+    typeProvider.initializeAsync(library);
+  }
+
+  void _buildCoreLibrary() {
+    LibraryElement library = resynthesizer.getLibraryElement('dart:core');
+    typeProvider.initializeCore(library);
+  }
+
+  PrelinkedLibrary _getPrelinkedSummary(String uri) {
+    for (int i = 0; i < bundle.prelinkedLibraryUris.length; i++) {
+      if (bundle.prelinkedLibraryUris[i] == uri) {
+        return bundle.prelinkedLibraries[i];
+      }
+    }
+    throw new StateError('Unable to find prelinked summary for $uri');
+  }
+
+  UnlinkedUnit _getUnlinkedSummary(String uri) {
+    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
+      if (bundle.unlinkedUnitUris[i] == uri) {
+        return bundle.unlinkedUnits[i];
+      }
+    }
+    throw new StateError('Unable to find unlinked summary for $uri');
+  }
+}
+
+/**
+ * Implementation of [TypeProvider] which can be initialized separately with
+ * `dart:core` and `dart:async` libraries.
+ */
+class SummaryTypeProvider implements TypeProvider {
+  bool _isCoreInitialized = false;
+  bool _isAsyncInitialized = false;
+
+  InterfaceType _boolType;
+  InterfaceType _deprecatedType;
+  InterfaceType _doubleType;
+  InterfaceType _functionType;
+  InterfaceType _futureDynamicType;
+  InterfaceType _futureNullType;
+  InterfaceType _futureType;
+  InterfaceType _intType;
+  InterfaceType _iterableDynamicType;
+  InterfaceType _iterableType;
+  InterfaceType _listType;
+  InterfaceType _mapType;
+  DartObjectImpl _nullObject;
+  InterfaceType _nullType;
+  InterfaceType _numType;
+  InterfaceType _objectType;
+  InterfaceType _stackTraceType;
+  InterfaceType _streamDynamicType;
+  InterfaceType _streamType;
+  InterfaceType _stringType;
+  InterfaceType _symbolType;
+  InterfaceType _typeType;
+
+  @override
+  InterfaceType get boolType {
+    assert(_isCoreInitialized);
+    return _boolType;
+  }
+
+  @override
+  DartType get bottomType => BottomTypeImpl.instance;
+
+  @override
+  InterfaceType get deprecatedType {
+    assert(_isCoreInitialized);
+    return _deprecatedType;
+  }
+
+  @override
+  InterfaceType get doubleType {
+    assert(_isCoreInitialized);
+    return _doubleType;
+  }
+
+  @override
+  DartType get dynamicType => DynamicTypeImpl.instance;
+
+  @override
+  InterfaceType get functionType {
+    assert(_isCoreInitialized);
+    return _functionType;
+  }
+
+  @override
+  InterfaceType get futureDynamicType {
+    assert(_isAsyncInitialized);
+    return _futureDynamicType;
+  }
+
+  @override
+  InterfaceType get futureNullType {
+    assert(_isAsyncInitialized);
+    return _futureNullType;
+  }
+
+  @override
+  InterfaceType get futureType {
+    assert(_isAsyncInitialized);
+    return _futureType;
+  }
+
+  @override
+  InterfaceType get intType {
+    assert(_isCoreInitialized);
+    return _intType;
+  }
+
+  @override
+  InterfaceType get iterableDynamicType {
+    assert(_isCoreInitialized);
+    return _iterableDynamicType;
+  }
+
+  @override
+  InterfaceType get iterableType {
+    assert(_isCoreInitialized);
+    return _iterableType;
+  }
+
+  @override
+  InterfaceType get listType {
+    assert(_isCoreInitialized);
+    return _listType;
+  }
+
+  @override
+  InterfaceType get mapType {
+    assert(_isCoreInitialized);
+    return _mapType;
+  }
+
+  @override
+  List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[
+        nullType,
+        numType,
+        intType,
+        doubleType,
+        boolType,
+        stringType
+      ];
+
+  @override
+  DartObjectImpl get nullObject {
+    if (_nullObject == null) {
+      _nullObject = new DartObjectImpl(nullType, NullState.NULL_STATE);
+    }
+    return _nullObject;
+  }
+
+  @override
+  InterfaceType get nullType {
+    assert(_isCoreInitialized);
+    return _nullType;
+  }
+
+  @override
+  InterfaceType get numType {
+    assert(_isCoreInitialized);
+    return _numType;
+  }
+
+  @override
+  InterfaceType get objectType {
+    assert(_isCoreInitialized);
+    return _objectType;
+  }
+
+  @override
+  InterfaceType get stackTraceType {
+    assert(_isCoreInitialized);
+    return _stackTraceType;
+  }
+
+  @override
+  InterfaceType get streamDynamicType {
+    assert(_isAsyncInitialized);
+    return _streamDynamicType;
+  }
+
+  @override
+  InterfaceType get streamType {
+    assert(_isAsyncInitialized);
+    return _streamType;
+  }
+
+  @override
+  InterfaceType get stringType {
+    assert(_isCoreInitialized);
+    return _stringType;
+  }
+
+  @override
+  InterfaceType get symbolType {
+    assert(_isCoreInitialized);
+    return _symbolType;
+  }
+
+  @override
+  InterfaceType get typeType {
+    assert(_isCoreInitialized);
+    return _typeType;
+  }
+
+  @override
+  DartType get undefinedType => UndefinedTypeImpl.instance;
+
+  /**
+   * Initialize the `dart:async` types provided by this type provider.
+   */
+  void initializeAsync(LibraryElement library) {
+    assert(_isCoreInitialized);
+    assert(!_isAsyncInitialized);
+    _isAsyncInitialized = true;
+    _futureType = _getType(library, "Future");
+    _streamType = _getType(library, "Stream");
+    _futureDynamicType = _futureType.substitute4(<DartType>[dynamicType]);
+    _futureNullType = _futureType.substitute4(<DartType>[_nullType]);
+    _streamDynamicType = _streamType.substitute4(<DartType>[dynamicType]);
+  }
+
+  /**
+   * Initialize the `dart:core` types provided by this type provider.
+   */
+  void initializeCore(LibraryElement library) {
+    assert(!_isCoreInitialized);
+    assert(!_isAsyncInitialized);
+    _isCoreInitialized = true;
+    _boolType = _getType(library, "bool");
+    _deprecatedType = _getType(library, "Deprecated");
+    _doubleType = _getType(library, "double");
+    _functionType = _getType(library, "Function");
+    _intType = _getType(library, "int");
+    _iterableType = _getType(library, "Iterable");
+    _listType = _getType(library, "List");
+    _mapType = _getType(library, "Map");
+    _nullType = _getType(library, "Null");
+    _numType = _getType(library, "num");
+    _objectType = _getType(library, "Object");
+    _stackTraceType = _getType(library, "StackTrace");
+    _stringType = _getType(library, "String");
+    _symbolType = _getType(library, "Symbol");
+    _typeType = _getType(library, "Type");
+    _iterableDynamicType = _iterableType.substitute4(<DartType>[dynamicType]);
+  }
+
+  /**
+   * Return the type with the given [name] from the given [library], or
+   * throw a [StateError] if there is no class with the given name.
+   */
+  InterfaceType _getType(LibraryElement library, String name) {
+    Element element = library.getType(name);
+    if (element == null) {
+      throw new StateError("No definition of type $name");
+    }
+    return (element as ClassElement).type;
+  }
+}
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 9eca05f..df4e7ac 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -6,12 +6,13 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.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 AnalysisCache, AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/error_verifier.dart';
 import 'package:analyzer/src/generated/incremental_resolver.dart';
@@ -30,7 +31,6 @@
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
-import 'package:analyzer/src/task/strong/rules.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart';
@@ -80,12 +80,12 @@
  * A list of the [ConstantEvaluationTarget]s defined in a unit.  This includes
  * constants defined at top level, statically inside classes, and local to
  * functions, as well as constant constructors, annotations, and default values
- * of parameters to constant constructors.
+ * of parameters.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
-final ListResultDescriptor<
-        ConstantEvaluationTarget> COMPILATION_UNIT_CONSTANTS =
+final ListResultDescriptor<ConstantEvaluationTarget>
+    COMPILATION_UNIT_CONSTANTS =
     new ListResultDescriptor<ConstantEvaluationTarget>(
         'COMPILATION_UNIT_CONSTANTS', null,
         cachingPolicy: ELEMENT_CACHING_POLICY);
@@ -113,6 +113,18 @@
         'CONSTANT_DEPENDENCIES', const <ConstantEvaluationTarget>[]);
 
 /**
+ * The list of [ConstantEvaluationTarget]s on which constant expressions of a
+ * unit depend.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ListResultDescriptor<ConstantEvaluationTarget>
+    CONSTANT_EXPRESSIONS_DEPENDENCIES =
+    new ListResultDescriptor<ConstantEvaluationTarget>(
+        'CONSTANT_EXPRESSIONS_DEPENDENCIES',
+        const <ConstantEvaluationTarget>[]);
+
+/**
  * A [ConstantEvaluationTarget] that has been successfully constant-evaluated.
  *
  * TODO(paulberry): is ELEMENT_CACHING_POLICY the correct caching policy?
@@ -133,6 +145,114 @@
     new ListResultDescriptor<Source>('CONTAINING_LIBRARIES', Source.EMPTY_LIST);
 
 /**
+ * The flag specifying that [RESOLVED_UNIT] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT1] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT1 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT1', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT10] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT10 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT10', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT11] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT11 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT11', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT2] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT2 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT2', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT3] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT3 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT3', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT4] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT4 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT4', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT5] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT5 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT5', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT6] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT6 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT6', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT7] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT7 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT7', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT8] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT8 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT8', false);
+
+/**
+ * The flag specifying that [RESOLVED_UNIT9] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT9 =
+    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT9', false);
+
+/**
  * The sources representing the export closure of a library.
  * The [Source]s include only library sources, not their units.
  *
@@ -159,8 +279,8 @@
  * The result is only available for [VariableElement]s, and only when strong
  * mode is enabled.
  */
-final ListResultDescriptor<
-        VariableElement> INFERABLE_STATIC_VARIABLE_DEPENDENCIES =
+final ListResultDescriptor<VariableElement>
+    INFERABLE_STATIC_VARIABLE_DEPENDENCIES =
     new ListResultDescriptor<VariableElement>(
         'INFERABLE_STATIC_VARIABLE_DEPENDENCIES', null);
 
@@ -286,6 +406,39 @@
         cachingPolicy: ELEMENT_CACHING_POLICY);
 
 /**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * [LIBRARY_ELEMENT5] plus propagated types for propagable variables.
+ *
+ * The result is only available for [Source]s representing a library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT6 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT6', null,
+        cachingPolicy: ELEMENT_CACHING_POLICY);
+
+/**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * [LIBRARY_ELEMENT6] for the library and its import/export closure.
+ *
+ * The result is only available for [Source]s representing a library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT7 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT7', null,
+        cachingPolicy: ELEMENT_CACHING_POLICY);
+
+/**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * The same as a [LIBRARY_ELEMENT7].
+ *
+ * The result is only available for [Source]s representing a library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT8 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT8', null,
+        cachingPolicy: ELEMENT_CACHING_POLICY);
+
+/**
  * The flag specifying whether all analysis errors are computed in a specific
  * library.
  *
@@ -338,6 +491,36 @@
         'PARSE_ERRORS', AnalysisError.NO_ERRORS);
 
 /**
+ * A list of the [VariableElement]s whose type should be known to propagate
+ * the type of another variable (the target).
+ *
+ * The result is only available for [VariableElement]s.
+ */
+final ListResultDescriptor<VariableElement> PROPAGABLE_VARIABLE_DEPENDENCIES =
+    new ListResultDescriptor<VariableElement>(
+        'PROPAGABLE_VARIABLE_DEPENDENCIES', null);
+
+/**
+ * A list of the [VariableElement]s defined in a unit whose type might be
+ * propagated. This includes variables defined at the library level as well as
+ * static and instance members inside classes.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ListResultDescriptor<VariableElement> PROPAGABLE_VARIABLES_IN_UNIT =
+    new ListResultDescriptor<VariableElement>(
+        'PROPAGABLE_VARIABLES_IN_UNIT', null);
+
+/**
+ * An propagable variable ([VariableElement]) whose type has been propagated.
+ *
+ * The result is only available for [VariableElement]s.
+ */
+final ResultDescriptor<VariableElement> PROPAGATED_VARIABLE =
+    new ResultDescriptor<VariableElement>('PROPAGATED_VARIABLE', null,
+        cachingPolicy: ELEMENT_CACHING_POLICY);
+
+/**
  * The flag specifying that [LIBRARY_ELEMENT2] is ready for a library and its
  * import/export closure.
  *
@@ -356,8 +539,17 @@
     new ResultDescriptor<bool>('READY_LIBRARY_ELEMENT5', false);
 
 /**
+ * The flag specifying that [LIBRARY_ELEMENT6] is ready for a library and its
+ * import/export closure.
+ *
+ * The result is only available for [Source]s representing a library.
+ */
+final ResultDescriptor<bool> READY_LIBRARY_ELEMENT6 =
+    new ResultDescriptor<bool>('READY_LIBRARY_ELEMENT6', false);
+
+/**
  * The flag specifying that [RESOLVED_UNIT] is ready for all of the units of a
- * library and its import/export closure.
+ * library.
  *
  * The result is only available for [Source]s representing a library.
  */
@@ -374,13 +566,13 @@
     new ResultDescriptor<bool>('READY_RESOLVED_UNIT10', false);
 
 /**
- * The flag specifying that [RESOLVED_UNIT9] is ready for all of the units of a
+ * The flag specifying that [RESOLVED_UNIT11] is ready for all of the units of a
  * library and its import/export closure.
  *
  * The result is only available for [Source]s representing a library.
  */
-final ResultDescriptor<bool> READY_RESOLVED_UNIT9 =
-    new ResultDescriptor<bool>('READY_RESOLVED_UNIT9', false);
+final ResultDescriptor<bool> READY_RESOLVED_UNIT11 =
+    new ResultDescriptor<bool>('READY_RESOLVED_UNIT11', false);
 
 /**
  * The names (resolved and not) referenced by a unit.
@@ -427,7 +619,7 @@
 
 /**
  * The resolved [CompilationUnit] associated with a compilation unit, with
- * constants resolved.
+ * constants not yet resolved.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -436,6 +628,16 @@
         cachingPolicy: AST_CACHING_POLICY);
 
 /**
+ * The resolved [CompilationUnit] associated with a compilation unit, with
+ * constants resolved.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT11 =
+    new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT11', null,
+        cachingPolicy: AST_CACHING_POLICY);
+
+/**
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * Tasks that use this value as an input can assume that the [SimpleIdentifier]s
@@ -493,7 +695,8 @@
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT5], tasks that use this value
- * as an input can assume that the types of static variables have been inferred.
+ * as an input can assume that the types of final variables have been
+ * propagated.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -505,8 +708,7 @@
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT6], tasks that use this value
- * as an input can assume that the initializers of instance variables have been
- * re-resolved.
+ * as an input can assume that the types of static variables have been inferred.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -515,9 +717,11 @@
         cachingPolicy: AST_CACHING_POLICY);
 
 /**
- * The resolved [CompilationUnit] associated with a compilation unit in which
- * the types of class members have been inferred in addition to everything that
- * is true of a [RESOLVED_UNIT7].
+ * The partially resolved [CompilationUnit] associated with a compilation unit.
+ *
+ * In addition to what is true of a [RESOLVED_UNIT7], tasks that use this value
+ * as an input can assume that the initializers of instance variables have been
+ * re-resolved.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -526,8 +730,9 @@
         cachingPolicy: AST_CACHING_POLICY);
 
 /**
- * The resolved [CompilationUnit] associated with a compilation unit, with
- * constants not yet resolved.
+ * The resolved [CompilationUnit] associated with a compilation unit in which
+ * the types of class members have been inferred in addition to everything that
+ * is true of a [RESOLVED_UNIT8].
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -603,10 +808,20 @@
         'VERIFY_ERRORS', AnalysisError.NO_ERRORS);
 
 /**
+ * Return a list of unique errors for the [Source] of the given [target].
+ */
+List<AnalysisError> getTargetSourceErrors(
+    RecordingErrorListener listener, AnalysisTarget target) {
+  Source source = target.source;
+  List<AnalysisError> errors = listener.getErrorsForSource(source);
+  return getUniqueErrors(errors);
+}
+
+/**
  * Return a list of errors containing the errors from the given [errors] list
  * but with duplications removed.
  */
-List<AnalysisError> removeDuplicateErrors(List<AnalysisError> errors) {
+List<AnalysisError> getUniqueErrors(List<AnalysisError> errors) {
   if (errors.isEmpty) {
     return errors;
   }
@@ -631,6 +846,7 @@
       buildInputs, <ResultDescriptor>[
     COMPILATION_UNIT_CONSTANTS,
     COMPILATION_UNIT_ELEMENT,
+    CREATED_RESOLVED_UNIT1,
     RESOLVED_UNIT1
   ]);
 
@@ -674,14 +890,16 @@
     ConstantFinder constantFinder =
         new ConstantFinder(context, source, librarySpecificUnit.library);
     unit.accept(constantFinder);
-    List<ConstantEvaluationTarget> constants = new List<
-        ConstantEvaluationTarget>.from(constantFinder.constantsToCompute);
+    List<ConstantEvaluationTarget> constants =
+        new List<ConstantEvaluationTarget>.from(
+            constantFinder.constantsToCompute);
     //
     // Record outputs.
     //
     outputs[COMPILATION_UNIT_CONSTANTS] = constants;
     outputs[COMPILATION_UNIT_ELEMENT] = element;
     outputs[RESOLVED_UNIT1] = unit;
+    outputs[CREATED_RESOLVED_UNIT1] = true;
   }
 
   /**
@@ -812,7 +1030,7 @@
             importElement.deferred = importDirective.deferredKeyword != null;
             importElement.combinators = _buildCombinators(importDirective);
             importElement.importedLibrary = importedLibrary;
-            _setDocRange(importElement, importDirective);
+            _setDoc(importElement, importDirective);
             SimpleIdentifier prefixNode = directive.prefix;
             if (prefixNode != null) {
               importElement.prefixOffset = prefixNode.offset;
@@ -854,7 +1072,7 @@
             exportElement.uri = exportDirective.uriContent;
             exportElement.combinators = _buildCombinators(exportDirective);
             exportElement.exportedLibrary = exportedLibrary;
-            _setDocRange(exportElement, exportDirective);
+            _setDoc(exportElement, exportDirective);
             directive.element = exportElement;
             exports.add(exportElement);
             if (exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
@@ -895,12 +1113,14 @@
   }
 
   /**
-   * If the given [node] has a documentation comment, remember its range
-   * into the given [element].
+   * If the given [node] has a documentation comment, remember its content
+   * and range into the given [element].
    */
-  void _setDocRange(ElementImpl element, AnnotatedNode node) {
+  void _setDoc(ElementImpl element, AnnotatedNode node) {
     Comment comment = node.documentationComment;
     if (comment != null && comment.isDocumentation) {
+      element.documentationComment =
+          comment.tokens.map((Token t) => t.lexeme).join('\n');
       element.setDocRange(comment.offset, comment.length);
     }
   }
@@ -989,7 +1209,7 @@
       'BuildEnumMemberElementsTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[RESOLVED_UNIT2]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT2, RESOLVED_UNIT2]);
 
   BuildEnumMemberElementsTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -1010,6 +1230,7 @@
     //
     EnumMemberBuilder builder = new EnumMemberBuilder(typeProvider);
     unit.accept(builder);
+    outputs[CREATED_RESOLVED_UNIT2] = true;
     outputs[RESOLVED_UNIT2] = unit;
   }
 
@@ -1271,7 +1492,7 @@
       _patchTopLevelAccessors(libraryElement);
     }
     if (libraryDirective != null) {
-      _setDocRange(libraryElement, libraryDirective);
+      _setDoc(libraryElement, libraryDirective);
     }
     //
     // Record outputs.
@@ -1359,12 +1580,14 @@
   }
 
   /**
-   * If the given [node] has a documentation comment, remember its range
-   * into the given [element].
+   * If the given [node] has a documentation comment, remember its content
+   * and range into the given [element].
    */
-  void _setDocRange(ElementImpl element, AnnotatedNode node) {
+  void _setDoc(ElementImpl element, AnnotatedNode node) {
     Comment comment = node.documentationComment;
     if (comment != null && comment.isDocumentation) {
+      element.documentationComment =
+          comment.tokens.map((Token t) => t.lexeme).join('\n');
       element.setDocRange(comment.offset, comment.length);
     }
   }
@@ -1638,7 +1861,7 @@
           'Cannot build inputs for a ${target.runtimeType}');
     }
     return <String, TaskInput>{
-      'resolvedUnit': RESOLVED_UNIT9
+      'resolvedUnit': RESOLVED_UNIT10
           .of(new LibrarySpecificUnit(librarySource, target.source)),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
     };
@@ -1752,7 +1975,7 @@
  * static variable whose type should be inferred.
  */
 class ComputeInferableStaticVariableDependenciesTask
-    extends ConstantEvaluationAnalysisTask {
+    extends InferStaticVariableTask {
   /**
    * The name of the [RESOLVED_UNIT5] input.
    */
@@ -1776,19 +1999,11 @@
     //
     // Prepare inputs.
     //
-    VariableElement variable = target;
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
     //
     // Compute dependencies.
     //
-    NodeLocator locator = new NodeLocator(variable.nameOffset);
-    AstNode node = locator.searchWithin(unit);
-    VariableDeclaration declaration =
-        node.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration);
-    if (declaration == null || declaration.name != node) {
-      throw new AnalysisException(
-          "NodeLocator failed to find a variable's declaration");
-    }
+    VariableDeclaration declaration = getDeclaration(unit);
     VariableGatherer gatherer = new VariableGatherer(_isInferableStatic);
     declaration.initializer.accept(gatherer);
     //
@@ -1801,7 +2016,8 @@
    * Return `true` if the given [variable] is a static variable whose type
    * should be inferred.
    */
-  bool _isInferableStatic(VariableElement variable) => variable.isStatic &&
+  bool _isInferableStatic(VariableElement variable) =>
+      variable.isStatic &&
       variable.hasImplicitType &&
       variable.initializer != null;
 
@@ -1940,6 +2156,85 @@
 }
 
 /**
+ * A task that computes the [PROPAGABLE_VARIABLE_DEPENDENCIES] for a variable.
+ */
+class ComputePropagableVariableDependenciesTask
+    extends InferStaticVariableTask {
+  /**
+   * The name of the [RESOLVED_UNIT5] input.
+   */
+  static const String UNIT_INPUT = 'UNIT_INPUT';
+
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ComputePropagableVariableDependenciesTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[PROPAGABLE_VARIABLE_DEPENDENCIES]);
+
+  ComputePropagableVariableDependenciesTask(
+      InternalAnalysisContext context, VariableElement variable)
+      : super(context, variable);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    //
+    // Prepare inputs.
+    //
+    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+    //
+    // Compute dependencies.
+    //
+    VariableDeclaration declaration = getDeclaration(unit);
+    VariableGatherer gatherer = new VariableGatherer(_isPropagable);
+    declaration.initializer.accept(gatherer);
+    //
+    // Record outputs.
+    //
+    outputs[PROPAGABLE_VARIABLE_DEPENDENCIES] = gatherer.results.toList();
+  }
+
+  /**
+   * Return `true` if the given [variable] is a variable whose type can be
+   * propagated.
+   */
+  bool _isPropagable(VariableElement variable) =>
+      variable is PropertyInducingElement &&
+      (variable.isConst || variable.isFinal) &&
+      variable.hasImplicitType &&
+      variable.initializer != null;
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    if (target is VariableElement) {
+      CompilationUnitElementImpl unit = target
+          .getAncestor((Element element) => element is CompilationUnitElement);
+      return <String, TaskInput>{
+        UNIT_INPUT: RESOLVED_UNIT5
+            .of(new LibrarySpecificUnit(unit.librarySource, unit.source))
+      };
+    }
+    throw new AnalysisException(
+        'Cannot build inputs for a ${target.runtimeType}');
+  }
+
+  /**
+   * Create a [ComputePropagableVariableDependenciesTask] based on the
+   * given [target] in the given [context].
+   */
+  static ComputePropagableVariableDependenciesTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ComputePropagableVariableDependenciesTask(context, target);
+  }
+}
+
+/**
  * A base class for analysis tasks whose target is expected to be a
  * [ConstantEvaluationTarget].
  */
@@ -2194,11 +2489,11 @@
 }
 
 /**
- * A task that builds [RESOLVED_UNIT10] for a unit.
+ * A task that builds [RESOLVED_UNIT11] for a unit.
  */
 class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT9] input.
+   * The name of the [RESOLVED_UNIT10] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -2214,7 +2509,7 @@
       'EvaluateUnitConstantsTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[RESOLVED_UNIT10]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT11, RESOLVED_UNIT11]);
 
   EvaluateUnitConstantsTask(AnalysisContext context, LibrarySpecificUnit target)
       : super(context, target);
@@ -2227,7 +2522,8 @@
     // No actual work needs to be performed; the task manager will ensure that
     // all constants are evaluated before this method is called.
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
-    outputs[RESOLVED_UNIT10] = unit;
+    outputs[RESOLVED_UNIT11] = unit;
+    outputs[CREATED_RESOLVED_UNIT11] = true;
   }
 
   /**
@@ -2238,10 +2534,12 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      'libraryElement': LIBRARY_ELEMENT.of(unit.library),
-      UNIT_INPUT: RESOLVED_UNIT9.of(unit),
+      'libraryElement': LIBRARY_ELEMENT8.of(unit.library),
+      UNIT_INPUT: RESOLVED_UNIT10.of(unit),
       CONSTANT_VALUES:
-          COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE)
+          COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE),
+      'constantExpressionsDependencies':
+          CONSTANT_EXPRESSIONS_DEPENDENCIES.of(unit).toListOf(CONSTANT_VALUE)
     };
   }
 
@@ -2363,7 +2661,7 @@
  */
 class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT9] input.
+   * The name of the [RESOLVED_UNIT10] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -2407,7 +2705,7 @@
    */
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
-    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT9.of(unit)};
+    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT10.of(unit)};
   }
 
   /**
@@ -2425,7 +2723,7 @@
  */
 class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT9] input.
+   * The name of the [RESOLVED_UNIT10] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -2469,7 +2767,7 @@
    */
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
-    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT9.of(unit)};
+    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT10.of(unit)};
   }
 
   /**
@@ -2487,7 +2785,7 @@
  */
 class GenerateHintsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT9] input.
+   * The name of the [RESOLVED_UNIT10] input.
    */
   static const String RESOLVED_UNIT_INPUT = 'RESOLVED_UNIT';
 
@@ -2693,7 +2991,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the input whose value is the [RESOLVED_UNIT6] for the
+   * The name of the input whose value is the [RESOLVED_UNIT7] for the
    * compilation unit.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2705,7 +3003,7 @@
       'InferInstanceMembersInUnitTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[RESOLVED_UNIT8]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT9, RESOLVED_UNIT9]);
 
   /**
    * Initialize a newly created task to build a library element for the given
@@ -2736,7 +3034,8 @@
     //
     // Record outputs.
     //
-    outputs[RESOLVED_UNIT8] = unit;
+    outputs[RESOLVED_UNIT9] = unit;
+    outputs[CREATED_RESOLVED_UNIT9] = true;
   }
 
   /**
@@ -2747,7 +3046,7 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      UNIT_INPUT: RESOLVED_UNIT7.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT8.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
@@ -2755,12 +3054,12 @@
       // Require that field re-resolution be complete for all units in the
       // current library cycle.
       'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
-          (CompilationUnitElementImpl unit) => RESOLVED_UNIT7
+          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT8
               .of(new LibrarySpecificUnit(unit.librarySource, unit.source))),
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
-          (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
               .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
     };
   }
@@ -2790,13 +3089,13 @@
    */
   VariableDeclaration getDeclaration(CompilationUnit unit) {
     VariableElement variable = target;
-    NodeLocator locator = new NodeLocator(variable.nameOffset);
-    AstNode node = locator.searchWithin(unit);
+    AstNode node = new NodeLocator2(variable.nameOffset).searchWithin(unit);
     VariableDeclaration declaration =
         node.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration);
     if (declaration == null || declaration.name != node) {
       throw new AnalysisException(
-          "Failed to find the declaration of the variable ${variable.displayName} in ${variable.source}");
+          "Failed to find the declaration of the variable "
+          "${variable.displayName} in ${variable.source}");
     }
     return declaration;
   }
@@ -2808,7 +3107,7 @@
  */
 class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the input whose value is the [RESOLVED_UNIT5] for the
+   * The name of the input whose value is the [RESOLVED_UNIT6] for the
    * compilation unit.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2826,7 +3125,7 @@
       'InferStaticVariableTypesInUnitTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[RESOLVED_UNIT6]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT7, RESOLVED_UNIT7]);
 
   /**
    * Initialize a newly created task to build a library element for the given
@@ -2850,7 +3149,8 @@
     // because the work has implicitly been done by virtue of the task model
     // preparing all of the inputs.
     //
-    outputs[RESOLVED_UNIT6] = unit;
+    outputs[RESOLVED_UNIT7] = unit;
+    outputs[CREATED_RESOLVED_UNIT7] = true;
   }
 
   /**
@@ -2864,7 +3164,7 @@
       INFERRED_VARIABLES_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
           .of(unit)
           .toListOf(INFERRED_STATIC_VARIABLE),
-      UNIT_INPUT: RESOLVED_UNIT5.of(unit)
+      UNIT_INPUT: RESOLVED_UNIT6.of(unit)
     };
   }
 
@@ -2895,7 +3195,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the [RESOLVED_UNIT5] input.
+   * The name of the [RESOLVED_UNIT6] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -2993,14 +3293,14 @@
           .of(variable)
           .toListOf(INFERRED_STATIC_VARIABLE),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      UNIT_INPUT: RESOLVED_UNIT5.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT6.of(unit),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
 
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
-          (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
               .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
     };
   }
@@ -3048,7 +3348,8 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     Source source = target;
     return <String, TaskInput>{
-      'allErrors': UNITS.of(source).toListOf(DART_ERRORS)
+      'allErrors': UNITS.of(source).toListOf(DART_ERRORS),
+      'libraryElement': LIBRARY_ELEMENT.of(source)
     };
   }
 
@@ -3249,8 +3550,10 @@
     RecordingErrorListener errorListener = new RecordingErrorListener();
     Parser parser = new Parser(source, errorListener);
     AnalysisOptions options = context.analysisOptions;
+    parser.parseAsync = options.enableAsync;
     parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source);
     parser.parseGenericMethods = options.enableGenericMethods;
+    parser.parseGenericMethodComments = options.strongMode;
     CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
     unit.lineInfo = lineInfo;
 
@@ -3306,8 +3609,7 @@
     List<Source> exportedSources = exportedSourceSet.toList();
     List<Source> importedSources = importedSourceSet.toList();
     List<Source> includedSources = includedSourceSet.toList();
-    List<AnalysisError> parseErrors =
-        removeDuplicateErrors(errorListener.errors);
+    List<AnalysisError> parseErrors = getUniqueErrors(errorListener.errors);
     List<Source> unitSources = <Source>[source]..addAll(includedSourceSet);
     List<LibrarySpecificUnit> librarySpecificUnits =
         unitSources.map((s) => new LibrarySpecificUnit(source, s)).toList();
@@ -3325,13 +3627,13 @@
   /**
    * Return a map from the names of the inputs of this kind of task to the task
    * input descriptors describing those inputs for a task with the given
-   * [source].
+   * [target].
    */
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     return <String, TaskInput>{
       LINE_INFO_INPUT_NAME: LINE_INFO.of(target),
       MODIFICATION_TIME_INPUT_NAME: MODIFICATION_TIME.of(target),
-      TOKEN_STREAM_INPUT_NAME: TOKEN_STREAM.of(target)
+      TOKEN_STREAM_INPUT_NAME: TOKEN_STREAM.of(target, flushOnAccess: true)
     };
   }
 
@@ -3409,8 +3711,12 @@
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
       'PartiallyResolveUnitReferencesTask',
       createTask,
-      buildInputs,
-      <ResultDescriptor>[INFERABLE_STATIC_VARIABLES_IN_UNIT, RESOLVED_UNIT5]);
+      buildInputs, <ResultDescriptor>[
+    INFERABLE_STATIC_VARIABLES_IN_UNIT,
+    PROPAGABLE_VARIABLES_IN_UNIT,
+    CREATED_RESOLVED_UNIT5,
+    RESOLVED_UNIT5
+  ]);
 
   PartiallyResolveUnitReferencesTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -3431,22 +3737,20 @@
     //
     // Resolve references and record outputs.
     //
+    PartialResolverVisitor visitor = new PartialResolverVisitor(libraryElement,
+        unitElement.source, typeProvider, AnalysisErrorListener.NULL_LISTENER);
+    unit.accept(visitor);
+    //
+    // Record outputs.
+    //
     if (context.analysisOptions.strongMode) {
-      InheritanceManager inheritanceManager =
-          new InheritanceManager(libraryElement);
-      PartialResolverVisitor visitor = new PartialResolverVisitor(
-          libraryElement,
-          unitElement.source,
-          typeProvider,
-          AnalysisErrorListener.NULL_LISTENER,
-          inheritanceManager: inheritanceManager);
-      unit.accept(visitor);
-
-      outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.variablesAndFields;
+      outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.staticVariables;
     } else {
-      outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = [];
+      outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = VariableElement.EMPTY_LIST;
     }
+    outputs[PROPAGABLE_VARIABLES_IN_UNIT] = visitor.propagableVariables;
     outputs[RESOLVED_UNIT5] = unit;
+    outputs[CREATED_RESOLVED_UNIT5] = true;
   }
 
   /**
@@ -3467,7 +3771,7 @@
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
-          (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
               .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
     };
   }
@@ -3483,6 +3787,286 @@
 }
 
 /**
+ * An artificial task that does nothing except to force propagated types for
+ * all propagable variables in the import/export closure a library.
+ */
+class PropagateVariableTypesInLibraryClosureTask
+    extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [LIBRARY_ELEMENT6] input.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'PropagateVariableTypesInLibraryClosureTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT7]);
+
+  PropagateVariableTypesInLibraryClosureTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+    outputs[LIBRARY_ELEMENT7] = library;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    Source source = target;
+    return <String, TaskInput>{
+      'readyForClosure': READY_LIBRARY_ELEMENT6.of(source),
+      LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
+    };
+  }
+
+  /**
+   * Create a [PropagateVariableTypesInLibraryClosureTask] based on the given
+   * [target] in the given [context].
+   */
+  static PropagateVariableTypesInLibraryClosureTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new PropagateVariableTypesInLibraryClosureTask(context, target);
+  }
+}
+
+/**
+ * An artificial task that does nothing except to force propagated types for
+ * all propagable variables in the defining and part units of a library.
+ */
+class PropagateVariableTypesInLibraryTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [LIBRARY_ELEMENT5] input.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'PropagateVariableTypesInLibraryTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT6]);
+
+  PropagateVariableTypesInLibraryTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+    outputs[LIBRARY_ELEMENT6] = library;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    Source source = target;
+    return <String, TaskInput>{
+      'propagatedVariableTypesInUnits':
+          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT6),
+      LIBRARY_INPUT: LIBRARY_ELEMENT5.of(source),
+    };
+  }
+
+  /**
+   * Create a [PropagateVariableTypesInLibraryTask] based on the given [target]
+   * in the given [context].
+   */
+  static PropagateVariableTypesInLibraryTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new PropagateVariableTypesInLibraryTask(context, target);
+  }
+}
+
+/**
+ * A task that ensures that all of the propagable variables in a compilation
+ * unit have had their type propagated.
+ */
+class PropagateVariableTypesInUnitTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the input whose value is the [RESOLVED_UNIT5] for the
+   * compilation unit.
+   */
+  static const String UNIT_INPUT = 'UNIT_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'PropagateVariableTypesInUnitTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT6, RESOLVED_UNIT6]);
+
+  PropagateVariableTypesInUnitTask(
+      InternalAnalysisContext context, LibrarySpecificUnit unit)
+      : super(context, unit);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    //
+    // Prepare inputs.
+    //
+    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+    //
+    // Record outputs. There is no additional work to be done at this time
+    // because the work has implicitly been done by virtue of the task model
+    // preparing all of the inputs.
+    //
+    outputs[RESOLVED_UNIT6] = unit;
+    outputs[CREATED_RESOLVED_UNIT6] = true;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the given
+   * [target].
+   */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    LibrarySpecificUnit unit = target;
+    return <String, TaskInput>{
+      'variables':
+          PROPAGABLE_VARIABLES_IN_UNIT.of(unit).toListOf(PROPAGATED_VARIABLE),
+      UNIT_INPUT: RESOLVED_UNIT5.of(unit)
+    };
+  }
+
+  /**
+   * Create a [PropagateVariableTypesInUnitTask] based on the given [target]
+   * in the given [context].
+   */
+  static PropagateVariableTypesInUnitTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new PropagateVariableTypesInUnitTask(context, target);
+  }
+}
+
+/**
+ * A task that computes the propagated type of an propagable variable and
+ * stores it in the element model.
+ */
+class PropagateVariableTypeTask extends InferStaticVariableTask {
+  /**
+   * The name of the [TYPE_PROVIDER] input.
+   */
+  static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
+
+  /**
+   * The name of the [RESOLVED_UNIT5] input.
+   */
+  static const String UNIT_INPUT = 'UNIT_INPUT';
+
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'PropagateVariableTypeTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[PROPAGATED_VARIABLE]);
+
+  PropagateVariableTypeTask(
+      InternalAnalysisContext context, VariableElement variable)
+      : super(context, variable);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  bool get handlesDependencyCycles => true;
+
+  @override
+  void internalPerform() {
+    //
+    // Prepare inputs.
+    //
+    PropertyInducingElementImpl variable = target;
+    TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
+    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+
+    // If we're not in a dependency cycle, and we have no type annotation,
+    // re-resolve the right hand side and do propagation.
+    if (dependencyCycle == null && variable.hasImplicitType) {
+      VariableDeclaration declaration = getDeclaration(unit);
+      //
+      // Re-resolve the variable's initializer with the propagated types of
+      // other variables.
+      //
+      Expression initializer = declaration.initializer;
+      ResolutionContext resolutionContext = ResolutionContextBuilder.contextFor(
+          initializer, AnalysisErrorListener.NULL_LISTENER);
+      ResolverVisitor visitor = new ResolverVisitor(variable.library,
+          variable.source, typeProvider, AnalysisErrorListener.NULL_LISTENER,
+          nameScope: resolutionContext.scope);
+      if (resolutionContext.enclosingClassDeclaration != null) {
+        visitor.prepareToResolveMembersInClass(
+            resolutionContext.enclosingClassDeclaration);
+      }
+      visitor.initForIncrementalResolution();
+      initializer.accept(visitor);
+      //
+      // Record the type of the variable.
+      //
+      DartType newType = initializer.bestType;
+      if (newType != null && !newType.isBottom && !newType.isDynamic) {
+        variable.propagatedType = newType;
+      }
+    }
+    //
+    // Record outputs.
+    //
+    outputs[PROPAGATED_VARIABLE] = variable;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the given
+   * [target].
+   */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    VariableElement variable = target;
+    LibrarySpecificUnit unit =
+        new LibrarySpecificUnit(variable.library.source, variable.source);
+    return <String, TaskInput>{
+      'dependencies': PROPAGABLE_VARIABLE_DEPENDENCIES
+          .of(variable)
+          .toListOf(PROPAGATED_VARIABLE),
+      TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
+      UNIT_INPUT: RESOLVED_UNIT5.of(unit),
+    };
+  }
+
+  /**
+   * Create a [PropagateVariableTypeTask] based on the given [target] in the
+   * given [context].
+   */
+  static PropagateVariableTypeTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new PropagateVariableTypeTask(context, target);
+  }
+}
+
+/**
  * The helper for building the public [Namespace] of a [LibraryElement].
  */
 class PublicNamespaceBuilder {
@@ -3608,6 +4192,49 @@
 }
 
 /**
+ * A task that ensures that [LIBRARY_ELEMENT6] is ready for the target library
+ * source and its import/export closure.
+ */
+class ReadyLibraryElement6Task extends SourceBasedAnalysisTask {
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ReadyLibraryElement6Task',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[READY_LIBRARY_ELEMENT6]);
+
+  ReadyLibraryElement6Task(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  bool get handlesDependencyCycles => true;
+
+  @override
+  void internalPerform() {
+    outputs[READY_LIBRARY_ELEMENT6] = true;
+  }
+
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    Source source = target;
+    return <String, TaskInput>{
+      'thisLibraryElementReady': LIBRARY_ELEMENT6.of(source),
+      'directlyImportedLibrariesReady':
+          IMPORTED_LIBRARIES.of(source).toListOf(READY_LIBRARY_ELEMENT6),
+      'directlyExportedLibrariesReady':
+          EXPORTED_LIBRARIES.of(source).toListOf(READY_LIBRARY_ELEMENT6),
+    };
+  }
+
+  static ReadyLibraryElement6Task createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ReadyLibraryElement6Task(context, target);
+  }
+}
+
+/**
  * A task that ensures that [RESOLVED_UNIT10] is ready for every unit of the
  * target library source and its import/export closure.
  */
@@ -3652,17 +4279,18 @@
 }
 
 /**
- * A task that ensures that [RESOLVED_UNIT9] is ready for every unit of the
+ * A task that ensures that [RESOLVED_UNIT11] is ready for every unit of the
  * target library source and its import/export closure.
  */
-class ReadyResolvedUnit9Task extends SourceBasedAnalysisTask {
+class ReadyResolvedUnit11Task extends SourceBasedAnalysisTask {
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'ReadyResolvedUnit9Task',
+      'ReadyResolvedUnit11Task',
       createTask,
       buildInputs,
-      <ResultDescriptor>[READY_RESOLVED_UNIT9]);
+      <ResultDescriptor>[READY_RESOLVED_UNIT11]);
 
-  ReadyResolvedUnit9Task(InternalAnalysisContext context, AnalysisTarget target)
+  ReadyResolvedUnit11Task(
+      InternalAnalysisContext context, AnalysisTarget target)
       : super(context, target);
 
   @override
@@ -3673,24 +4301,24 @@
 
   @override
   void internalPerform() {
-    outputs[READY_RESOLVED_UNIT9] = true;
+    outputs[READY_RESOLVED_UNIT11] = true;
   }
 
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     Source source = target;
     return <String, TaskInput>{
       'thisLibraryUnitsReady':
-          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT9),
+          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT11),
       'directlyImportedLibrariesReady':
-          IMPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT9),
+          IMPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT11),
       'directlyExportedLibrariesReady':
-          EXPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT9),
+          EXPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT11),
     };
   }
 
-  static ReadyResolvedUnit9Task createTask(
+  static ReadyResolvedUnit11Task createTask(
       AnalysisContext context, AnalysisTarget target) {
-    return new ReadyResolvedUnit9Task(context, target);
+    return new ReadyResolvedUnit11Task(context, target);
   }
 }
 
@@ -3724,10 +4352,6 @@
     return <String, TaskInput>{
       'thisLibraryUnitsReady':
           LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT),
-      'directlyImportedLibrariesReady':
-          IMPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT),
-      'directlyExportedLibrariesReady':
-          EXPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT),
     };
   }
 
@@ -3851,7 +4475,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the input whose value is the [RESOLVED_UNIT6] for the
+   * The name of the input whose value is the [RESOLVED_UNIT7] for the
    * compilation unit.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3863,7 +4487,7 @@
       'ResolveInstanceFieldsInUnitTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[RESOLVED_UNIT7]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT8, RESOLVED_UNIT8]);
 
   /**
    * Initialize a newly created task to build a library element for the given
@@ -3898,20 +4522,18 @@
       // the size of the enclosing class, and hence incrementally resolving each
       // field was quadratic.  We may wish to revisit this if we can resolve
       // this performance issue.
-      InheritanceManager inheritanceManager =
-          new InheritanceManager(libraryElement);
       PartialResolverVisitor visitor = new PartialResolverVisitor(
           libraryElement,
           unitElement.source,
           typeProvider,
-          AnalysisErrorListener.NULL_LISTENER,
-          inheritanceManager: inheritanceManager);
+          AnalysisErrorListener.NULL_LISTENER);
       unit.accept(visitor);
     }
     //
     // Record outputs.
     //
-    outputs[RESOLVED_UNIT7] = unit;
+    outputs[RESOLVED_UNIT8] = unit;
+    outputs[CREATED_RESOLVED_UNIT8] = true;
   }
 
   /**
@@ -3922,7 +4544,7 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      UNIT_INPUT: RESOLVED_UNIT6.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT7.of(unit),
       LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
       // In strong mode, add additional dependencies to enforce inference
@@ -3931,12 +4553,12 @@
       // Require that static variable inference  be complete for all units in
       // the current library cycle.
       'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
-          (CompilationUnitElementImpl unit) => RESOLVED_UNIT6
+          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT7
               .of(new LibrarySpecificUnit(unit.librarySource, unit.source))),
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
-          (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
               .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
     };
   }
@@ -3952,17 +4574,17 @@
 }
 
 /**
- * A task that finishes resolution by requesting [RESOLVED_UNIT9] for every
- * unit in the libraries closure and produces [LIBRARY_ELEMENT].
+ * A task that finishes resolution by requesting [RESOLVED_UNIT10] for every
+ * unit in the libraries closure and produces [LIBRARY_ELEMENT8].
  */
 class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [LIBRARY_ELEMENT5] input.
+   * The name of the [LIBRARY_ELEMENT7] input.
    */
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
   /**
-   * The name of the list of [RESOLVED_UNIT9] input.
+   * The name of the list of [RESOLVED_UNIT10] input.
    */
   static const String UNITS_INPUT = 'UNITS_INPUT';
 
@@ -3973,7 +4595,7 @@
       'ResolveLibraryReferencesTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[LIBRARY_ELEMENT, REFERENCED_NAMES]);
+      <ResultDescriptor>[LIBRARY_ELEMENT8, REFERENCED_NAMES]);
 
   ResolveLibraryReferencesTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -3997,7 +4619,7 @@
     //
     // Record outputs.
     //
-    outputs[LIBRARY_ELEMENT] = library;
+    outputs[LIBRARY_ELEMENT8] = library;
     outputs[REFERENCED_NAMES] = referencedNames;
   }
 
@@ -4009,9 +4631,8 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     Source source = target;
     return <String, TaskInput>{
-      LIBRARY_INPUT: LIBRARY_ELEMENT5.of(source),
-      UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT9),
-      'thisLibraryClosureIsReady': READY_RESOLVED_UNIT9.of(source),
+      LIBRARY_INPUT: LIBRARY_ELEMENT7.of(source),
+      UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT10),
     };
   }
 
@@ -4026,6 +4647,71 @@
 }
 
 /**
+ * A task that finishes resolution by requesting [RESOLVED_UNIT11] for every
+ * unit in the libraries closure and produces [LIBRARY_ELEMENT].
+ */
+class ResolveLibraryTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [LIBRARY_ELEMENT8] input.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The name of the list of [RESOLVED_UNIT11] input.
+   */
+  static const String UNITS_INPUT = 'UNITS_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ResolveLibraryTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT]);
+
+  ResolveLibraryTask(InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    //
+    // Prepare inputs.
+    //
+    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+    //
+    // Record outputs.
+    //
+    outputs[LIBRARY_ELEMENT] = library;
+  }
+
+/**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the
+ * given [target].
+ */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    Source source = target;
+    return <String, TaskInput>{
+      LIBRARY_INPUT: LIBRARY_ELEMENT8.of(source),
+      'thisLibraryClosureIsReady': READY_RESOLVED_UNIT.of(source),
+    };
+  }
+
+/**
+ * Create a [ResolveLibraryTask] based on the given [target] in the given
+ * [context].
+ */
+  static ResolveLibraryTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ResolveLibraryTask(context, target);
+  }
+}
+
+/**
  * An artificial task that does nothing except to force type names resolution
  * for the defining and part units of a library.
  */
@@ -4104,7 +4790,7 @@
  */
 class ResolveUnitTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the input whose value is the defining [LIBRARY_ELEMENT5].
+   * The name of the input whose value is the defining [LIBRARY_ELEMENT7].
    */
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
@@ -4114,15 +4800,17 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the [RESOLVED_UNIT8] input.
+   * The name of the [RESOLVED_UNIT9] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'ResolveUnitTask',
-      createTask,
-      buildInputs,
-      <ResultDescriptor>[RESOLVE_UNIT_ERRORS, RESOLVED_UNIT9]);
+      'ResolveUnitTask', createTask, buildInputs, <ResultDescriptor>[
+    CONSTANT_EXPRESSIONS_DEPENDENCIES,
+    RESOLVE_UNIT_ERRORS,
+    CREATED_RESOLVED_UNIT10,
+    RESOLVED_UNIT10
+  ]);
 
   ResolveUnitTask(
       InternalAnalysisContext context, LibrarySpecificUnit compilationUnit)
@@ -4136,6 +4824,7 @@
     //
     // Prepare inputs.
     //
+    LibrarySpecificUnit target = this.target;
     LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT);
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
     TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
@@ -4148,14 +4837,26 @@
         libraryElement, unitElement.source, typeProvider, errorListener);
     unit.accept(visitor);
     //
+    // Compute constant expressions' dependencies.
+    //
+    List<ConstantEvaluationTarget> constExprDependencies;
+    {
+      ConstantExpressionsDependenciesFinder finder =
+          new ConstantExpressionsDependenciesFinder();
+      unit.accept(finder);
+      constExprDependencies = finder.dependencies.toList();
+    }
+    //
     // Record outputs.
     //
     // TODO(brianwilkerson) This task modifies the element model (by copying the
     // AST's for constructor initializers into it) but does not produce an
     // updated version of the element model.
     //
-    outputs[RESOLVE_UNIT_ERRORS] = errorListener.errors;
-    outputs[RESOLVED_UNIT9] = unit;
+    outputs[CONSTANT_EXPRESSIONS_DEPENDENCIES] = constExprDependencies;
+    outputs[RESOLVE_UNIT_ERRORS] = getTargetSourceErrors(errorListener, target);
+    outputs[RESOLVED_UNIT10] = unit;
+    outputs[CREATED_RESOLVED_UNIT10] = true;
   }
 
   /**
@@ -4166,16 +4867,16 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library),
+      LIBRARY_INPUT: LIBRARY_ELEMENT7.of(unit.library),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      UNIT_INPUT: RESOLVED_UNIT8.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT9.of(unit),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
 
       // Require that inference be complete for all units in the
       // current library cycle.
       'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
-          (CompilationUnitElementImpl unit) => RESOLVED_UNIT8
+          (CompilationUnitElementImpl unit) => CREATED_RESOLVED_UNIT9
               .of(new LibrarySpecificUnit(unit.librarySource, unit.source)))
     };
   }
@@ -4213,10 +4914,11 @@
    * The task descriptor describing this kind of task.
    */
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'ResolveUnitTypeNamesTask',
-      createTask,
-      buildInputs,
-      <ResultDescriptor>[RESOLVE_TYPE_NAMES_ERRORS, RESOLVED_UNIT3]);
+      'ResolveUnitTypeNamesTask', createTask, buildInputs, <ResultDescriptor>[
+    RESOLVE_TYPE_NAMES_ERRORS,
+    CREATED_RESOLVED_UNIT3,
+    RESOLVED_UNIT3
+  ]);
 
   ResolveUnitTypeNamesTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -4245,8 +4947,9 @@
     // Record outputs.
     //
     outputs[RESOLVE_TYPE_NAMES_ERRORS] =
-        removeDuplicateErrors(errorListener.errors);
+        getTargetSourceErrors(errorListener, target);
     outputs[RESOLVED_UNIT3] = unit;
+    outputs[CREATED_RESOLVED_UNIT3] = true;
   }
 
   /**
@@ -4303,8 +5006,11 @@
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
       'ResolveVariableReferencesTask',
       createTask,
-      buildInputs,
-      <ResultDescriptor>[RESOLVED_UNIT4, VARIABLE_REFERENCE_ERRORS]);
+      buildInputs, <ResultDescriptor>[
+    CREATED_RESOLVED_UNIT4,
+    RESOLVED_UNIT4,
+    VARIABLE_REFERENCE_ERRORS
+  ]);
 
   ResolveVariableReferencesTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -4335,8 +5041,9 @@
     // Record outputs.
     //
     outputs[RESOLVED_UNIT4] = unit;
+    outputs[CREATED_RESOLVED_UNIT4] = true;
     outputs[VARIABLE_REFERENCE_ERRORS] =
-        removeDuplicateErrors(errorListener.errors);
+        getTargetSourceErrors(errorListener, target);
   }
 
   /**
@@ -4429,20 +5136,22 @@
           errorListener);
       scanner.setSourceStart(fragment.line, fragment.column);
       scanner.preserveComments = context.analysisOptions.preserveComments;
+      scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
 
       outputs[TOKEN_STREAM] = scanner.tokenize();
       outputs[LINE_INFO] = new LineInfo(scanner.lineStarts);
-      outputs[SCAN_ERRORS] = removeDuplicateErrors(errorListener.errors);
+      outputs[SCAN_ERRORS] = getUniqueErrors(errorListener.errors);
     } else if (target is Source) {
       String content = getRequiredInput(CONTENT_INPUT_NAME);
 
       Scanner scanner =
           new Scanner(source, new CharSequenceReader(content), errorListener);
       scanner.preserveComments = context.analysisOptions.preserveComments;
+      scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
 
       outputs[TOKEN_STREAM] = scanner.tokenize();
       outputs[LINE_INFO] = new LineInfo(scanner.lineStarts);
-      outputs[SCAN_ERRORS] = removeDuplicateErrors(errorListener.errors);
+      outputs[SCAN_ERRORS] = getUniqueErrors(errorListener.errors);
     } else {
       throw new AnalysisException(
           'Cannot scan Dart code from a ${target.runtimeType}');
@@ -4482,7 +5191,7 @@
  */
 class StrongModeVerifyUnitTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT10] input.
+   * The name of the [RESOLVED_UNIT11] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -4495,10 +5204,11 @@
    * The task descriptor describing this kind of task.
    */
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'StrongModeVerifyUnitTask',
-      createTask,
-      buildInputs,
-      <ResultDescriptor>[STRONG_MODE_ERRORS, RESOLVED_UNIT]);
+      'StrongModeVerifyUnitTask', createTask, buildInputs, <ResultDescriptor>[
+    STRONG_MODE_ERRORS,
+    CREATED_RESOLVED_UNIT,
+    RESOLVED_UNIT
+  ]);
 
   StrongModeVerifyUnitTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -4516,13 +5226,14 @@
     TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
     if (context.analysisOptions.strongMode) {
-      unit.accept(new CodeChecker(new TypeRules(typeProvider), errorListener));
+      unit.accept(new CodeChecker(
+          typeProvider, new StrongTypeSystemImpl(), errorListener));
     }
-
     //
     // Record outputs.
     //
-    outputs[STRONG_MODE_ERRORS] = removeDuplicateErrors(errorListener.errors);
+    outputs[STRONG_MODE_ERRORS] = getUniqueErrors(errorListener.errors);
+    outputs[CREATED_RESOLVED_UNIT] = true;
     outputs[RESOLVED_UNIT] = unit;
   }
 
@@ -4534,9 +5245,8 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      UNIT_INPUT: RESOLVED_UNIT10.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT11.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      'thisLibraryClosureIsReady': READY_RESOLVED_UNIT10.of(unit.library),
     };
   }
 
@@ -4611,13 +5321,14 @@
         libraryElement,
         typeProvider,
         new InheritanceManager(libraryElement),
-        context.analysisOptions.enableSuperMixins);
+        context.analysisOptions.enableSuperMixins,
+        context.analysisOptions.enableAssertMessage);
     unit.accept(errorVerifier);
 
     //
     // Record outputs.
     //
-    outputs[VERIFY_ERRORS] = removeDuplicateErrors(errorListener.errors);
+    outputs[VERIFY_ERRORS] = getUniqueErrors(errorListener.errors);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 793d9ce..a586b3b 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -474,7 +474,7 @@
   }
 
   bool _shouldErrorsBeComputed(Source source) =>
-      context.shouldErrorsBeAnalyzed(source, null);
+      context.shouldErrorsBeAnalyzed(source);
 
   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 c6abda8..db9cd1d 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -8,8 +8,7 @@
 import 'dart:collection';
 
 import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisTask, AnalysisContextImpl, WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
@@ -47,8 +46,8 @@
   /**
    * The map of [ComputedResult] controllers.
    */
-  final Map<ResultDescriptor,
-          StreamController<ComputedResult>> resultComputedControllers =
+  final Map<ResultDescriptor, StreamController<ComputedResult>>
+      resultComputedControllers =
       <ResultDescriptor, StreamController<ComputedResult>>{};
 
   /**
@@ -168,7 +167,8 @@
     }
     TaskDescriptor taskDescriptor = taskManager.findTask(target, result);
     try {
-      WorkItem workItem = new WorkItem(context, target, taskDescriptor, result);
+      WorkItem workItem =
+          new WorkItem(context, target, taskDescriptor, result, 0, null);
       return new WorkOrder(taskManager, workItem);
     } catch (exception, stackTrace) {
       throw new AnalysisException(
@@ -504,7 +504,7 @@
 }
 
 /**
- * Object used by CycleAwareDependencyWalker to report a single strongly
+ * Object used by [CycleAwareDependencyWalker] to report a single strongly
  * connected component of nodes.
  */
 class StronglyConnectedComponent<Node> {
@@ -530,21 +530,6 @@
  */
 class WorkItem {
   /**
-   * A table mapping the names of analysis tasks to the number of times each
-   * kind of task has been performed.
-   */
-  static final Map<TaskDescriptor, int> countMap =
-      new HashMap<TaskDescriptor, int>();
-
-  /**
-   * A table mapping the names of analysis tasks to stopwatches used to compute
-   * how much time was spent between creating an item and creating (for
-   * performing) of each kind of task
-   */
-  static final Map<TaskDescriptor, Stopwatch> stopwatchMap =
-      new HashMap<TaskDescriptor, Stopwatch>();
-
-  /**
    * The context in which the task will be performed.
    */
   final InternalAnalysisContext context;
@@ -565,9 +550,14 @@
   final ResultDescriptor spawningResult;
 
   /**
-   * The current inputs computing stopwatch.
+   * The level of this item in its [WorkOrder].
    */
-  Stopwatch stopwatch;
+  final int level;
+
+  /**
+   * The work order that this item is part of, may be `null`.
+   */
+  WorkOrder workOrder;
 
   /**
    * An iterator used to iterate over the descriptors of the inputs to the task,
@@ -607,11 +597,13 @@
    * Initialize a newly created work item to compute the inputs for the task
    * described by the given descriptor.
    */
-  WorkItem(this.context, this.target, this.descriptor, this.spawningResult) {
+  WorkItem(this.context, this.target, this.descriptor, this.spawningResult,
+      this.level, this.workOrder) {
     AnalysisTarget actualTarget =
         identical(target, AnalysisContextTarget.request)
             ? new AnalysisContextTarget(context)
             : target;
+//    print('${'\t' * level}$spawningResult of $actualTarget');
     Map<String, TaskInput> inputDescriptors =
         descriptor.createTaskInputs(actualTarget);
     builder = new TopLevelTaskInputBuilder(inputDescriptors);
@@ -619,19 +611,6 @@
       builder = null;
     }
     inputs = new HashMap<String, dynamic>();
-    // Update performance counters.
-    {
-      stopwatch = stopwatchMap[descriptor];
-      if (stopwatch == null) {
-        stopwatch = new Stopwatch();
-        stopwatchMap[descriptor] = stopwatch;
-      }
-      stopwatch.start();
-    }
-    {
-      int count = countMap[descriptor];
-      countMap[descriptor] = count == null ? 1 : count + 1;
-    }
   }
 
   @override
@@ -651,7 +630,6 @@
    * Build the task represented by this work item.
    */
   AnalysisTask buildTask() {
-    stopwatch.stop();
     if (builder != null) {
       throw new StateError("some inputs have not been computed");
     }
@@ -680,6 +658,25 @@
     while (builder != null) {
       AnalysisTarget inputTarget = builder.currentTarget;
       ResultDescriptor inputResult = builder.currentResult;
+
+      // TODO(scheglov) record information to debug
+      // https://github.com/dart-lang/sdk/issues/24939
+      if (inputTarget == null || inputResult == null) {
+        try {
+          String message =
+              'Invalid input descriptor ($inputTarget, $inputResult) for $this';
+          if (workOrder != null) {
+            message += '\nPath:\n' + workOrder.workItems.join('|\n');
+          }
+          throw new AnalysisException(message);
+        } catch (exception, stackTrace) {
+          this.exception = new CaughtException(exception, stackTrace);
+          AnalysisEngine.instance.logger
+              .logError('Task failed: $this', this.exception);
+        }
+        return null;
+      }
+
       inputTargetedResults.add(new TargetedResult(inputTarget, inputResult));
       CacheEntry inputEntry = context.getCacheEntry(inputTarget);
       CacheState inputState = inputEntry.getState(inputResult);
@@ -705,13 +702,19 @@
         //
         throw new UnimplementedError();
       } else if (inputState != CacheState.VALID) {
-        try {
-          TaskDescriptor descriptor =
-              taskManager.findTask(inputTarget, inputResult);
-          return new WorkItem(context, inputTarget, descriptor, inputResult);
-        } on AnalysisException catch (exception, stackTrace) {
-          this.exception = new CaughtException(exception, stackTrace);
-          return null;
+        if (context.aboutToComputeResult(inputEntry, inputResult)) {
+          inputState = CacheState.VALID;
+          builder.currentValue = inputEntry.getValue(inputResult);
+        } else {
+          try {
+            TaskDescriptor descriptor =
+                taskManager.findTask(inputTarget, inputResult);
+            return new WorkItem(context, inputTarget, descriptor, inputResult,
+                level + 1, workOrder);
+          } on AnalysisException catch (exception, stackTrace) {
+            this.exception = new CaughtException(exception, stackTrace);
+            return null;
+          }
         }
       } else {
         builder.currentValue = inputEntry.getValue(inputResult);
@@ -756,7 +759,9 @@
    * the given work item.
    */
   WorkOrder(TaskManager taskManager, WorkItem item)
-      : _dependencyWalker = new _WorkOrderDependencyWalker(taskManager, item);
+      : _dependencyWalker = new _WorkOrderDependencyWalker(taskManager, item) {
+    item.workOrder = this;
+  }
 
   @override
   WorkItem get current {
diff --git a/pkg/analyzer/lib/src/task/general.dart b/pkg/analyzer/lib/src/task/general.dart
index 72f80fd..38d67df 100644
--- a/pkg/analyzer/lib/src/task/general.dart
+++ b/pkg/analyzer/lib/src/task/general.dart
@@ -4,7 +4,7 @@
 
 library analyzer.src.task.general;
 
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index b603f1f..b6a771a 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -7,7 +7,7 @@
 import 'dart:collection';
 
 import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -313,7 +313,8 @@
       ];
       outputs[LINE_INFO] = new LineInfo(<int>[0]);
     } else {
-      HtmlParser parser = new HtmlParser(content, generateSpans: true);
+      HtmlParser parser = new HtmlParser(content,
+          generateSpans: true, lowercaseAttrName: false);
       parser.compatMode = 'quirks';
       Document document = parser.parse();
       //
@@ -360,12 +361,7 @@
    * Compute [LineInfo] for the given [content].
    */
   static LineInfo _computeLineInfo(String content) {
-    List<int> lineStarts = <int>[0];
-    for (int index = 0; index < content.length; index++) {
-      if (content.codeUnitAt(index) == 0x0A) {
-        lineStarts.add(index + 1);
-      }
-    }
+    List<int> lineStarts = StringUtilities.computeLineStarts(content);
     return new LineInfo(lineStarts);
   }
 }
diff --git a/pkg/analyzer/lib/src/task/incremental_element_builder.dart b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
index d6a0c14..07550c5 100644
--- a/pkg/analyzer/lib/src/task/incremental_element_builder.dart
+++ b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
@@ -6,8 +6,10 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -222,8 +224,9 @@
           }
         }
       }
-    } else if (node is PartDirective || node is PartOfDirective) {
-    } else if (node is Directive && node.element != null) {
+    } else if (node is PartDirective || node is PartOfDirective) {} else if (node
+        is Directive &&
+        node.element != null) {
       elements.add(node.element);
     } else if (node is Declaration && node.element != null) {
       Element element = node.element;
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index 2236ca0..1134a58 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -89,26 +89,28 @@
  */
 abstract class ListTaskInputMixin<E> implements ListTaskInput<E> {
   @override
-  ListTaskInput /*<V>*/ toFlattenListOf(
+  ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
       ListResultDescriptor /*<V>*/ subListResult) {
-    return new ListToFlattenListTaskInput<E, dynamic /*V*/ >(
+    return new ListToFlattenListTaskInput<E, dynamic /*=V*/ >(
         this, subListResult.of as dynamic);
   }
 
-  ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper) {
-    return new ListToListTaskInput<E, dynamic /*V*/ >(this, mapper);
+  ListTaskInput /*<V>*/ toList /*<V>*/ (
+      UnaryFunction<E, dynamic /*<=V>*/ > mapper) {
+    return new ListToListTaskInput<E, dynamic /*=V*/ >(this, mapper);
   }
 
-  ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) {
+  ListTaskInput /*<V>*/ toListOf /*<V>*/ (
+      ResultDescriptor /*<V>*/ valueResult) {
     return (this as ListTaskInput<AnalysisTarget>).toList(valueResult.of);
   }
 
-  MapTaskInput<E, dynamic /*V*/ > toMap(
-      UnaryFunction<E, dynamic /*<V>*/ > mapper) {
-    return new ListToMapTaskInput<E, dynamic /*V*/ >(this, mapper);
+  MapTaskInput<E, dynamic /*=V*/ > toMap /*<V>*/ (
+      UnaryFunction<E, dynamic /*<=V>*/ > mapper) {
+    return new ListToMapTaskInput<E, dynamic /*=V*/ >(this, mapper);
   }
 
-  MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
+  MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
       ResultDescriptor /*<V>*/ valueResult) {
     return (this as ListTaskInputImpl<AnalysisTarget>).toMap(valueResult.of);
   }
@@ -277,11 +279,10 @@
  * A mixin-ready implementation of [MapTaskInput].
  */
 abstract class MapTaskInputMixin<K, V> implements MapTaskInput<K, V> {
-  TaskInput<List /*<E>*/ > toFlattenList(
-      BinaryFunction<K, dynamic /*element of V*/, dynamic /*<E>*/ > mapper) {
+  TaskInput<List /*<E>*/ > toFlattenList /*<E>*/ (
+      BinaryFunction<K, dynamic /*element of V*/, dynamic /*<=E>*/ > mapper) {
     return new MapToFlattenListTaskInput<K, dynamic /*element of V*/,
-        dynamic /*E*/ >(
-        this as MapTaskInput<K, List /*<element of V>*/ >, mapper);
+        dynamic /*=E*/ >(this as MapTaskInput<K, List /*<element of V>*/ >, mapper);
   }
 }
 
@@ -440,22 +441,23 @@
       new ObjectToListTaskInputBuilder<E>(this);
 
   @override
-  ListTaskInput /*<V>*/ toFlattenListOf(
+  ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
       ListResultDescriptor /*<V>*/ subListResult) {
-    return new ListToFlattenListTaskInput<E, dynamic /*V*/ >(
+    return new ListToFlattenListTaskInput<E, dynamic /*=V*/ >(
         this, subListResult.of as dynamic);
   }
 
   @override
-  ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) {
-    return new ListToListTaskInput<E, dynamic /*V*/ >(
+  ListTaskInput /*<V>*/ toListOf /*<V>*/ (
+      ResultDescriptor /*<V>*/ valueResult) {
+    return new ListToListTaskInput<E, dynamic /*=V*/ >(
         this, valueResult.of as dynamic);
   }
 
   @override
-  MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
+  MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
       ResultDescriptor /*<V>*/ valueResult) {
-    return new ListToMapTaskInput<AnalysisTarget, dynamic /*V*/ >(
+    return new ListToMapTaskInput<AnalysisTarget, dynamic /*=V*/ >(
         this as dynamic, valueResult.of);
   }
 }
@@ -694,7 +696,7 @@
 
 abstract class TaskInputImpl<V> implements TaskInput<V> {
   @override
-  ListTaskInput /*<E>*/ mappedToList(List /*<E>*/ mapper(V value)) {
+  ListTaskInput /*<E>*/ mappedToList /*<E>*/ (List /*<E>*/ mapper(V value)) {
     return new ObjectToListTaskInput(this, mapper);
   }
 }
diff --git a/pkg/analyzer/lib/src/task/model.dart b/pkg/analyzer/lib/src/task/model.dart
index 50c05ee..8eaa838 100644
--- a/pkg/analyzer/lib/src/task/model.dart
+++ b/pkg/analyzer/lib/src/task/model.dart
@@ -4,7 +4,7 @@
 
 library analyzer.src.task.model;
 
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/task/model.dart';
 
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 9f22f7f..6775408 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -4,12 +4,18 @@
 
 library analyzer.src.task.options;
 
+import 'dart:collection';
+
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/task/general.dart';
+import 'package:analyzer/src/task/strong/info.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:source_span/source_span.dart';
@@ -22,10 +28,65 @@
     new ListResultDescriptor<AnalysisError>(
         'ANALYSIS_OPTIONS_ERRORS', AnalysisError.NO_ERRORS);
 
-/// Validates `analyzer` top-level options.
-class AnalyzerOptionsValidator extends TopLevelOptionValidator {
+final _OptionsProcessor _processor = new _OptionsProcessor();
+
+/// Configure this [context] based on configuration details specified in
+/// the given [options].  If [options] is `null`, default values are applied.
+void configureContextOptions(
+        AnalysisContext context, Map<String, Object> options) =>
+    _processor.configure(context, options);
+
+/// `analyzer` analysis options constants.
+class AnalyzerOptions {
+  static const String analyzer = 'analyzer';
+  static const String enableAsync = 'enableAsync';
+  static const String enableGenericMethods = 'enableGenericMethods';
+  static const String enableSuperMixins = 'enableSuperMixins';
+  static const String errors = 'errors';
+  static const String exclude = 'exclude';
+  static const String language = 'language';
+  static const String plugins = 'plugins';
+  static const String strong_mode = 'strong-mode';
+
+  /// Ways to say `ignore`.
+  static const List<String> ignoreSynonyms = const ['ignore', 'false'];
+
+  /// Valid error `severity`s.
+  static final List<String> severities =
+      new List.unmodifiable(severityMap.keys);
+
+  /// Ways to say `include`.
+  static const List<String> includeSynonyms = const ['include', 'true'];
+
+  /// Ways to say `true` or `false`.
+  static const List<String> trueOrFalse = const ['true', 'false'];
+
+  /// Supported top-level `analyzer` options.
+  static const List<String> topLevel = const [
+    errors,
+    exclude,
+    language,
+    plugins,
+    strong_mode
+  ];
+
+  /// Supported `analyzer` language configuration options.
+  static const List<String> languageOptions = const [
+    enableAsync,
+    enableGenericMethods,
+    enableSuperMixins
+  ];
+}
+
+/// Validates `analyzer` options.
+class AnalyzerOptionsValidator extends CompositeValidator {
   AnalyzerOptionsValidator()
-      : super('analyzer', const ['exclude', 'plugins', 'strong-mode']);
+      : super([
+          new TopLevelAnalyzerOptionsValidator(),
+          new StrongModeOptionValueValidator(),
+          new ErrorFilterOptionValidator(),
+          new LanguageOptionValidator()
+        ]);
 }
 
 /// Convenience class for composing validators.
@@ -38,6 +99,99 @@
       validators.forEach((v) => v.validate(reporter, options));
 }
 
+/// Builds error reports with value proposals.
+class ErrorBuilder {
+  String proposal;
+  AnalysisOptionsWarningCode code;
+
+  /// Create a builder for the given [supportedOptions].
+  ErrorBuilder(List<String> supportedOptions) {
+    assert(supportedOptions != null && !supportedOptions.isEmpty);
+    if (supportedOptions.length > 1) {
+      proposal = StringUtilities.printListOfQuotedNames(supportedOptions);
+      code = pluralProposalCode;
+    } else {
+      proposal = "'${supportedOptions.join()}'";
+      code = singularProposalCode;
+    }
+  }
+  AnalysisOptionsWarningCode get pluralProposalCode =>
+      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
+
+  AnalysisOptionsWarningCode get singularProposalCode =>
+      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
+
+  /// Report an unsupported [node] value, defined in the given [scopeName].
+  void reportError(ErrorReporter reporter, String scopeName, YamlNode node) {
+    reporter
+        .reportErrorForSpan(code, node.span, [scopeName, node.value, proposal]);
+  }
+}
+
+/// Validates `analyzer` error filter options.
+class ErrorFilterOptionValidator extends OptionsValidator {
+  /// Legal values.
+  static final List<String> legalValues =
+      new List.from(AnalyzerOptions.ignoreSynonyms)
+        ..addAll(AnalyzerOptions.includeSynonyms)
+        ..addAll(AnalyzerOptions.severities);
+
+  /// Pretty String listing legal values.
+  static final String legalValueString =
+      StringUtilities.printListOfQuotedNames(legalValues);
+
+  /// Lazily populated set of error codes (hashed for speedy lookup).
+  static HashSet<String> _errorCodes;
+
+  /// Legal error code names.
+  static Set<String> get errorCodes {
+    if (_errorCodes == null) {
+      _errorCodes = new HashSet<String>();
+      // Engine codes.
+      _errorCodes.addAll(ErrorCode.values.map((ErrorCode code) => code.name));
+      // Strong-mode codes.
+      _errorCodes.addAll(StaticInfo.names);
+    }
+    return _errorCodes;
+  }
+
+  @override
+  void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! YamlMap) {
+      return;
+    }
+
+    var filters = analyzer[AnalyzerOptions.errors];
+    if (filters is YamlMap) {
+      String value;
+      filters.nodes.forEach((k, v) {
+        if (k is YamlScalar) {
+          value = toUpperCase(k.value);
+          if (!errorCodes.contains(value)) {
+            reporter.reportErrorForSpan(
+                AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
+                k.span,
+                [k.value?.toString()]);
+          }
+        }
+        if (v is YamlScalar) {
+          value = toLowerCase(v.value);
+          if (!legalValues.contains(value)) {
+            reporter.reportErrorForSpan(
+                AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
+                v.span, [
+              AnalyzerOptions.errors,
+              v.value?.toString(),
+              legalValueString
+            ]);
+          }
+        }
+      });
+    }
+  }
+}
+
 /// A task that generates errors for an `.analysis_options` file.
 class GenerateOptionsErrorsTask extends SourceBasedAnalysisTask {
   /// The name of the input whose value is the content of the file.
@@ -81,7 +235,7 @@
     // Record outputs.
     //
     outputs[ANALYSIS_OPTIONS_ERRORS] = errors;
-    outputs[LINE_INFO] = _computeLineInfo(content);
+    outputs[LINE_INFO] = computeLineInfo(content);
   }
 
   List<AnalysisError> _validate(Map<String, YamlNode> options) =>
@@ -93,20 +247,52 @@
   static Map<String, TaskInput> buildInputs(Source source) =>
       <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)};
 
+  /// Compute [LineInfo] for the given [content].
+  static LineInfo computeLineInfo(String content) {
+    List<int> lineStarts = StringUtilities.computeLineStarts(content);
+    return new LineInfo(lineStarts);
+  }
+
   /// Create a task based on the given [target] in the given [context].
   static GenerateOptionsErrorsTask createTask(
           AnalysisContext context, AnalysisTarget target) =>
       new GenerateOptionsErrorsTask(context, target);
+}
 
-  /// Compute [LineInfo] for the given [content].
-  static LineInfo _computeLineInfo(String content) {
-    List<int> lineStarts = <int>[0];
-    for (int index = 0; index < content.length; index++) {
-      if (content.codeUnitAt(index) == 0x0A) {
-        lineStarts.add(index + 1);
-      }
+/// Validates `analyzer` language configuration options.
+class LanguageOptionValidator extends OptionsValidator {
+  ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.languageOptions);
+  ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
+
+  @override
+  void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! YamlMap) {
+      return;
     }
-    return new LineInfo(lineStarts);
+
+    var language = analyzer[AnalyzerOptions.language];
+    if (language is YamlMap) {
+      language.nodes.forEach((k, v) {
+        String key, value;
+        bool validKey = false;
+        if (k is YamlScalar) {
+          key = k.value?.toString();
+          if (!AnalyzerOptions.languageOptions.contains(key)) {
+            builder.reportError(reporter, AnalyzerOptions.language, k);
+          } else {
+            // If we have a valid key, go on and check the value.
+            validKey = true;
+          }
+        }
+        if (validKey && v is YamlScalar) {
+          value = toLowerCase(v.value);
+          if (!AnalyzerOptions.trueOrFalse.contains(value)) {
+            trueOrFalseBuilder.reportError(reporter, key, v);
+          }
+        }
+      });
+    }
   }
 }
 
@@ -137,14 +323,55 @@
   }
 }
 
+/// Validates `analyzer` strong-mode value configuration options.
+class StrongModeOptionValueValidator extends OptionsValidator {
+  ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
+
+  @override
+  void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! YamlMap) {
+      return;
+    }
+
+    var v = analyzer.nodes[AnalyzerOptions.strong_mode];
+    if (v is YamlScalar) {
+      var value = toLowerCase(v.value);
+      if (!AnalyzerOptions.trueOrFalse.contains(value)) {
+        trueOrFalseBuilder.reportError(
+            reporter, AnalyzerOptions.strong_mode, v);
+      }
+    }
+  }
+}
+
+/// Validates `analyzer` top-level options.
+class TopLevelAnalyzerOptionsValidator extends TopLevelOptionValidator {
+  TopLevelAnalyzerOptionsValidator()
+      : super(AnalyzerOptions.analyzer, AnalyzerOptions.topLevel);
+}
+
 /// Validates top-level options. For example,
 ///     plugin:
 ///       top-level-option: true
 class TopLevelOptionValidator extends OptionsValidator {
   final String pluginName;
   final List<String> supportedOptions;
+  String _valueProposal;
+  AnalysisOptionsWarningCode _warningCode;
+  TopLevelOptionValidator(this.pluginName, this.supportedOptions) {
+    assert(supportedOptions != null && !supportedOptions.isEmpty);
+    if (supportedOptions.length > 1) {
+      _valueProposal = StringUtilities.printListOfQuotedNames(supportedOptions);
+      _warningCode =
+          AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
+    } else {
+      _valueProposal = "'${supportedOptions.join()}'";
+      _warningCode =
+          AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
+    }
+  }
 
-  TopLevelOptionValidator(this.pluginName, this.supportedOptions);
   @override
   void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
     YamlNode node = options[pluginName];
@@ -153,9 +380,7 @@
         if (k is YamlScalar) {
           if (!supportedOptions.contains(k.value)) {
             reporter.reportErrorForSpan(
-                AnalysisOptionsWarningCode.UNSUPPORTED_OPTION,
-                k.span,
-                [pluginName, k.value]);
+                _warningCode, k.span, [pluginName, k.value, _valueProposal]);
           }
         }
         //TODO(pq): consider an error if the node is not a Scalar.
@@ -163,3 +388,97 @@
     }
   }
 }
+
+/// An error-builder that knows about `true` and `false` legal values.
+class TrueOrFalseValueErrorBuilder extends ErrorBuilder {
+  TrueOrFalseValueErrorBuilder() : super(AnalyzerOptions.trueOrFalse);
+  @override
+  AnalysisOptionsWarningCode get pluralProposalCode =>
+      AnalysisOptionsWarningCode.UNSUPPORTED_VALUE;
+}
+
+class _OptionsProcessor {
+  static final Map<String, Object> defaults = {'analyzer': {}};
+
+  /// Configure [context] based on the given [options] (which can be `null`
+  /// to restore [defaults]).
+  void configure(AnalysisContext context, Map<String, Object> options) {
+    if (options == null) {
+      options = defaults;
+    }
+
+    var analyzer = options[AnalyzerOptions.analyzer];
+    if (analyzer is! Map) {
+      return;
+    }
+
+    // Set strong mode (default is false).
+    var strongMode = analyzer[AnalyzerOptions.strong_mode];
+    setStrongMode(context, strongMode);
+
+    // Set filters.
+    var filters = analyzer[AnalyzerOptions.errors];
+    setProcessors(context, filters);
+
+    // Process language options.
+    var language = analyzer[AnalyzerOptions.language];
+    setLanguageOptions(context, language);
+  }
+
+  void setLanguageOption(
+      AnalysisContext context, Object feature, Object value) {
+    if (feature == AnalyzerOptions.enableAsync) {
+      if (isFalse(value)) {
+        AnalysisOptionsImpl options =
+            new AnalysisOptionsImpl.from(context.analysisOptions);
+        options.enableAsync = false;
+        context.analysisOptions = options;
+      }
+    }
+    if (feature == AnalyzerOptions.enableSuperMixins) {
+      if (isTrue(value)) {
+        AnalysisOptionsImpl options =
+            new AnalysisOptionsImpl.from(context.analysisOptions);
+        options.enableSuperMixins = true;
+        context.analysisOptions = options;
+      }
+    }
+    if (feature == AnalyzerOptions.enableGenericMethods) {
+      if (isTrue(value)) {
+        AnalysisOptionsImpl options =
+            new AnalysisOptionsImpl.from(context.analysisOptions);
+        options.enableGenericMethods = true;
+        context.analysisOptions = options;
+      }
+    }
+  }
+
+  void setLanguageOptions(AnalysisContext context, Object configs) {
+    if (configs is YamlMap) {
+      configs.nodes.forEach((k, v) {
+        if (k is YamlScalar && v is YamlScalar) {
+          String feature = k.value?.toString();
+          setLanguageOption(context, feature, v.value);
+        }
+      });
+    } else if (configs is Map) {
+      configs.forEach((k, v) => setLanguageOption(context, k, v));
+    }
+  }
+
+  void setProcessors(AnalysisContext context, Object codes) {
+    ErrorConfig config = new ErrorConfig(codes);
+    context.setConfigurationData(
+        CONFIGURED_ERROR_PROCESSORS, config.processors);
+  }
+
+  void setStrongMode(AnalysisContext context, Object strongMode) {
+    bool strong = strongMode is bool ? strongMode : false;
+    if (context.analysisOptions.strongMode != strong) {
+      AnalysisOptionsImpl options =
+          new AnalysisOptionsImpl.from(context.analysisOptions);
+      options.strongMode = strong;
+      context.analysisOptions = options;
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 9cfefe8..29857b0 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -7,22 +7,933 @@
 library analyzer.src.task.strong.checker;
 
 import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
+import 'package:analyzer/src/generated/type_system.dart';
 
 import 'info.dart';
-import 'rules.dart';
+
+DartType _elementType(Element e) {
+  if (e == null) {
+    // Malformed code - just return dynamic.
+    return DynamicTypeImpl.instance;
+  }
+  return (e as dynamic).type;
+}
+
+PropertyInducingElement _getMemberField(
+    InterfaceType type, PropertyAccessorElement member) {
+  String memberName = member.name;
+  PropertyInducingElement field;
+  if (member.isGetter) {
+    // The subclass member is an explicit getter or a field
+    // - lookup the getter on the superclass.
+    var getter = type.getGetter(memberName);
+    if (getter == null || getter.isStatic) return null;
+    field = getter.variable;
+  } else if (!member.isSynthetic) {
+    // The subclass member is an explicit setter
+    // - lookup the setter on the superclass.
+    // Note: an implicit (synthetic) setter would have already been flagged on
+    // the getter above.
+    var setter = type.getSetter(memberName);
+    if (setter == null || setter.isStatic) return null;
+    field = setter.variable;
+  } else {
+    return null;
+  }
+  if (field.isSynthetic) return null;
+  return field;
+}
+
+// Return the field on type corresponding to member, or null if none
+// exists or the "field" is actually a getter/setter.
+/// Looks up the declaration that matches [member] in [type] and returns it's
+/// declared type.
+FunctionType _getMemberType(InterfaceType type, ExecutableElement member) =>
+    _memberTypeGetter(member)(type);
+
+_MemberTypeGetter _memberTypeGetter(ExecutableElement member) {
+  String memberName = member.name;
+  final isGetter = member is PropertyAccessorElement && member.isGetter;
+  final isSetter = member is PropertyAccessorElement && member.isSetter;
+
+  FunctionType f(InterfaceType type) {
+    ExecutableElement baseMethod;
+
+    if (member.isPrivate) {
+      var subtypeLibrary = member.library;
+      var baseLibrary = type.element.library;
+      if (baseLibrary != subtypeLibrary) {
+        return null;
+      }
+    }
+
+    try {
+      if (isGetter) {
+        assert(!isSetter);
+        // Look for getter or field.
+        baseMethod = type.getGetter(memberName);
+      } else if (isSetter) {
+        baseMethod = type.getSetter(memberName);
+      } else {
+        baseMethod = type.getMethod(memberName);
+      }
+    } catch (e) {
+      // TODO(sigmund): remove this try-catch block (see issue #48).
+    }
+    if (baseMethod == null || baseMethod.isStatic) return null;
+    return baseMethod.type;
+  }
+  return f;
+}
+
+typedef FunctionType _MemberTypeGetter(InterfaceType type);
+
+/// Checks the body of functions and properties.
+class CodeChecker extends RecursiveAstVisitor {
+  final StrongTypeSystemImpl rules;
+  final TypeProvider typeProvider;
+  final AnalysisErrorListener reporter;
+  final _OverrideChecker _overrideChecker;
+  final bool _hints;
+
+  bool _failure = false;
+  CodeChecker(this.typeProvider, StrongTypeSystemImpl rules,
+      AnalysisErrorListener reporter,
+      {bool hints: false})
+      : rules = rules,
+        reporter = reporter,
+        _hints = hints,
+        _overrideChecker = new _OverrideChecker(rules, reporter);
+
+  bool get failure => _failure || _overrideChecker._failure;
+
+  void checkArgument(Expression arg, DartType expectedType) {
+    // Preserve named argument structure, so their immediate parent is the
+    // method invocation.
+    if (arg is NamedExpression) {
+      arg = (arg as NamedExpression).expression;
+    }
+    checkAssignment(arg, expectedType);
+  }
+
+  void checkArgumentList(ArgumentList node, FunctionType type) {
+    NodeList<Expression> list = node.arguments;
+    int len = list.length;
+    for (int i = 0; i < len; ++i) {
+      Expression arg = list[i];
+      ParameterElement element = arg.staticParameterElement;
+      if (element == null) {
+        if (type.parameters.length < len) {
+          // We found an argument mismatch, the analyzer will report this too,
+          // so no need to insert an error for this here.
+          continue;
+        }
+        element = type.parameters[i];
+        // TODO(vsm): When can this happen?
+        assert(element != null);
+      }
+      DartType expectedType = _elementType(element);
+      if (expectedType == null) expectedType = DynamicTypeImpl.instance;
+      checkArgument(arg, expectedType);
+    }
+  }
+
+  void checkAssignment(Expression expr, DartType type) {
+    if (expr is ParenthesizedExpression) {
+      checkAssignment(expr.expression, type);
+    } else {
+      _recordMessage(_checkAssignment(expr, type));
+    }
+  }
+
+  /// Analyzer checks boolean conversions, but we need to check too, because
+  /// it uses the default assignability rules that allow `dynamic` and `Object`
+  /// to be assigned to bool with no message.
+  void checkBoolean(Expression expr) =>
+      checkAssignment(expr, typeProvider.boolType);
+
+  void checkFunctionApplication(
+      Expression node, Expression f, ArgumentList list) {
+    if (_isDynamicCall(f)) {
+      // If f is Function and this is a method invocation, we should have
+      // gotten an analyzer error, so no need to issue another error.
+      _recordDynamicInvoke(node, f);
+    } else {
+      checkArgumentList(list, _getTypeAsCaller(f));
+    }
+  }
+
+  DartType getType(TypeName name) {
+    return (name == null) ? DynamicTypeImpl.instance : name.type;
+  }
+
+  void reset() {
+    _failure = false;
+    _overrideChecker._failure = false;
+  }
+
+  @override
+  void visitAsExpression(AsExpression node) {
+    // We could do the same check as the IsExpression below, but that is
+    // potentially too conservative.  Instead, at runtime, we must fail hard
+    // if the Dart as and the DDC as would return different values.
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    var token = node.operator;
+    if (token.type == TokenType.EQ ||
+        token.type == TokenType.QUESTION_QUESTION_EQ) {
+      DartType staticType = _getStaticType(node.leftHandSide);
+      checkAssignment(node.rightHandSide, staticType);
+    } else {
+      _checkCompoundAssignment(node);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    var op = node.operator;
+    if (op.isUserDefinableOperator) {
+      if (_isDynamicTarget(node.leftOperand)) {
+        // Dynamic invocation
+        // TODO(vsm): Move this logic to the resolver?
+        if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) {
+          _recordDynamicInvoke(node, node.leftOperand);
+        }
+      } else {
+        var element = node.staticElement;
+        // Method invocation.
+        if (element is MethodElement) {
+          var type = element.type;
+          // Analyzer should enforce number of parameter types, but check in
+          // case we have erroneous input.
+          if (type.normalParameterTypes.isNotEmpty) {
+            checkArgument(node.rightOperand, type.normalParameterTypes[0]);
+          }
+        } else {
+          // TODO(vsm): Assert that the analyzer found an error here?
+        }
+      }
+    } else {
+      // Non-method operator.
+      switch (op.type) {
+        case TokenType.AMPERSAND_AMPERSAND:
+        case TokenType.BAR_BAR:
+          checkBoolean(node.leftOperand);
+          checkBoolean(node.rightOperand);
+          break;
+        case TokenType.BANG_EQ:
+          break;
+        case TokenType.QUESTION_QUESTION:
+          break;
+        default:
+          assert(false);
+      }
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    _overrideChecker.check(node);
+    super.visitClassDeclaration(node);
+  }
+
+  @override
+  void visitComment(Comment node) {
+    // skip, no need to do typechecking inside comments (they may contain
+    // comment references which would require resolution).
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    checkBoolean(node.condition);
+    node.visitChildren(this);
+  }
+
+  /// Check constructor declaration to ensure correct super call placement.
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    node.visitChildren(this);
+
+    final init = node.initializers;
+    for (int i = 0, last = init.length - 1; i < last; i++) {
+      final node = init[i];
+      if (node is SuperConstructorInvocation) {
+        _recordMessage(new InvalidSuperInvocation(node));
+      }
+    }
+  }
+
+  // Check invocations
+  @override
+  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    var field = node.fieldName;
+    var element = field.staticElement;
+    DartType staticType = _elementType(element);
+    checkAssignment(node.expression, staticType);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    // Check that defaults have the proper subtype.
+    var parameter = node.parameter;
+    var parameterType = _elementType(parameter.element);
+    assert(parameterType != null);
+    var defaultValue = node.defaultValue;
+    if (defaultValue != null) {
+      checkAssignment(defaultValue, parameterType);
+    }
+
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    checkBoolean(node.condition);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    _checkReturnOrYield(node.expression, node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    var element = node.element;
+    var typeName = node.type;
+    if (typeName != null) {
+      var type = _elementType(element);
+      var fieldElement =
+          node.identifier.staticElement as FieldFormalParameterElement;
+      var fieldType = _elementType(fieldElement.field);
+      if (!rules.isSubtypeOf(type, fieldType)) {
+        var staticInfo =
+            new InvalidParameterDeclaration(rules, node, fieldType);
+        _recordMessage(staticInfo);
+      }
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitForEachStatement(ForEachStatement node) {
+    // Check that the expression is an Iterable.
+    var expr = node.iterable;
+    var iterableType = node.awaitKeyword != null
+        ? typeProvider.streamType
+        : typeProvider.iterableType;
+    var loopVariable = node.identifier != null
+        ? node.identifier
+        : node.loopVariable?.identifier;
+    if (loopVariable != null) {
+      var iteratorType = loopVariable.staticType;
+      var checkedType = iterableType.substitute4([iteratorType]);
+      checkAssignment(expr, checkedType);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    if (node.condition != null) {
+      checkBoolean(node.condition);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    checkFunctionApplication(node, node.function, node.argumentList);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitIfStatement(IfStatement node) {
+    checkBoolean(node.condition);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    var target = node.realTarget;
+    if (_isDynamicTarget(target)) {
+      _recordDynamicInvoke(node, target);
+    } else {
+      var element = node.staticElement;
+      if (element is MethodElement) {
+        var type = element.type;
+        // Analyzer should enforce number of parameter types, but check in
+        // case we have erroneous input.
+        if (type.normalParameterTypes.isNotEmpty) {
+          checkArgument(node.index, type.normalParameterTypes[0]);
+        }
+      } else {
+        // TODO(vsm): Assert that the analyzer found an error here?
+      }
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    var arguments = node.argumentList;
+    var element = node.staticElement;
+    if (element != null) {
+      var type = _elementType(node.staticElement);
+      checkArgumentList(arguments, type);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitIsExpression(IsExpression node) {
+    _checkRuntimeTypeCheck(node, node.type);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    var type = DynamicTypeImpl.instance;
+    if (node.typeArguments != null) {
+      var targs = node.typeArguments.arguments;
+      if (targs.length > 0) type = targs[0].type;
+    } else if (node.staticType is InterfaceType) {
+      InterfaceType listT = node.staticType;
+      var targs = listT.typeArguments;
+      if (targs != null && targs.length > 0) type = targs[0];
+    }
+    var elements = node.elements;
+    for (int i = 0; i < elements.length; i++) {
+      checkArgument(elements[i], type);
+    }
+    super.visitListLiteral(node);
+  }
+
+  @override
+  void visitMapLiteral(MapLiteral node) {
+    var ktype = DynamicTypeImpl.instance;
+    var vtype = DynamicTypeImpl.instance;
+    if (node.typeArguments != null) {
+      var targs = node.typeArguments.arguments;
+      if (targs.length > 0) ktype = targs[0].type;
+      if (targs.length > 1) vtype = targs[1].type;
+    } else if (node.staticType is InterfaceType) {
+      InterfaceType mapT = node.staticType;
+      var targs = mapT.typeArguments;
+      if (targs != null) {
+        if (targs.length > 0) ktype = targs[0];
+        if (targs.length > 1) vtype = targs[1];
+      }
+    }
+    var entries = node.entries;
+    for (int i = 0; i < entries.length; i++) {
+      var entry = entries[i];
+      checkArgument(entry.key, ktype);
+      checkArgument(entry.value, vtype);
+    }
+    super.visitMapLiteral(node);
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    var target = node.realTarget;
+    if (_isDynamicTarget(target) && !_isObjectMethod(node, node.methodName)) {
+      _recordDynamicInvoke(node, target);
+
+      // Mark the tear-off as being dynamic, too. This lets us distinguish
+      // cases like:
+      //
+      //     dynamic d;
+      //     d.someMethod(...); // the whole method call must be a dynamic send.
+      //
+      // ... from case like:
+      //
+      //     SomeType s;
+      //     s.someDynamicField(...); // static get, followed by dynamic call.
+      //
+      // The first case is handled here, the second case is handled below when
+      // we call [checkFunctionApplication].
+      DynamicInvoke.set(node.methodName, true);
+    } else {
+      checkFunctionApplication(node, node.methodName, node.argumentList);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPostfixExpression(PostfixExpression node) {
+    _checkUnary(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    _checkFieldAccess(node, node.prefix, node.identifier);
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    if (node.operator.type == TokenType.BANG) {
+      checkBoolean(node.operand);
+    } else {
+      _checkUnary(node);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    _checkFieldAccess(node, node.realTarget, node.propertyName);
+  }
+
+  @override
+  void visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    var type = node.staticElement?.type;
+    // TODO(leafp): There's a TODO in visitRedirectingConstructorInvocation
+    // in the element_resolver to handle the case that the element is null
+    // and emit an error.  In the meantime, just be defensive here.
+    if (type != null) {
+      checkArgumentList(node.argumentList, type);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    _checkReturnOrYield(node.expression, node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    var element = node.staticElement;
+    if (element != null) {
+      var type = node.staticElement.type;
+      checkArgumentList(node.argumentList, type);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    // SwitchStatement defines a boolean conversion to check the result of the
+    // case value == the switch value, but in dev_compiler we require a boolean
+    // return type from an overridden == operator (because Object.==), so
+    // checking in SwitchStatement shouldn't be necessary.
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    TypeName type = node.type;
+    if (type == null) {
+      // No checks are needed when the type is var. Although internally the
+      // typing rules may have inferred a more precise type for the variable
+      // based on the initializer.
+    } else {
+      var dartType = getType(type);
+      for (VariableDeclaration variable in node.variables) {
+        var initializer = variable.initializer;
+        if (initializer != null) {
+          checkAssignment(initializer, dartType);
+        }
+      }
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    checkBoolean(node.condition);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitYieldStatement(YieldStatement node) {
+    _checkReturnOrYield(node.expression, node, yieldStar: node.star != null);
+    node.visitChildren(this);
+  }
+
+  StaticInfo _checkAssignment(Expression expr, DartType toT) {
+    final fromT = expr.staticType ?? DynamicTypeImpl.instance;
+    final Coercion c = _coerceTo(fromT, toT);
+    if (c is Identity) return null;
+    if (c is CoercionError) return new StaticTypeError(rules, expr, toT);
+    var reason = null;
+
+    var errors = <String>[];
+
+    var ok = _inferExpression(expr, toT, errors);
+    if (ok) return InferredType.create(rules, expr, toT);
+    reason = (errors.isNotEmpty) ? errors.first : null;
+
+    if (c is Cast) return DownCast.create(rules, expr, c, reason: reason);
+    assert(false);
+    return null;
+  }
+
+  void _checkCompoundAssignment(AssignmentExpression expr) {
+    var op = expr.operator.type;
+    assert(op.isAssignmentOperator && op != TokenType.EQ);
+    var methodElement = expr.staticElement;
+    if (methodElement == null) {
+      // Dynamic invocation
+      _recordDynamicInvoke(expr, expr.leftHandSide);
+    } else {
+      // Sanity check the operator
+      assert(methodElement.isOperator);
+      var functionType = methodElement.type;
+      var paramTypes = functionType.normalParameterTypes;
+      assert(paramTypes.length == 1);
+      assert(functionType.namedParameterTypes.isEmpty);
+      assert(functionType.optionalParameterTypes.isEmpty);
+
+      // Check the lhs type
+      var staticInfo;
+      var rhsType = _getStaticType(expr.rightHandSide);
+      var lhsType = _getStaticType(expr.leftHandSide);
+      var returnType = _specializedBinaryReturnType(
+          op, lhsType, rhsType, functionType.returnType);
+
+      if (!rules.isSubtypeOf(returnType, lhsType)) {
+        final numType = typeProvider.numType;
+        // Try to fix up the numerical case if possible.
+        if (rules.isSubtypeOf(lhsType, numType) &&
+            rules.isSubtypeOf(lhsType, rhsType)) {
+          // This is also slightly different from spec, but allows us to keep
+          // compound operators in the int += num and num += dynamic cases.
+          staticInfo = DownCast.create(
+              rules, expr.rightHandSide, Coercion.cast(rhsType, lhsType));
+          rhsType = lhsType;
+        } else {
+          // Static type error
+          staticInfo = new StaticTypeError(rules, expr, lhsType);
+        }
+        _recordMessage(staticInfo);
+      }
+
+      // Check the rhs type
+      if (staticInfo is! CoercionInfo) {
+        var paramType = paramTypes.first;
+        staticInfo = _checkAssignment(expr.rightHandSide, paramType);
+        _recordMessage(staticInfo);
+      }
+    }
+  }
+
+  void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) {
+    if ((_isDynamicTarget(target) || field.staticElement == null) &&
+        !_isObjectProperty(target, field)) {
+      _recordDynamicInvoke(node, target);
+    }
+    node.visitChildren(this);
+  }
+
+  void _checkReturnOrYield(Expression expression, AstNode node,
+      {bool yieldStar: false}) {
+    var body = node.getAncestor((n) => n is FunctionBody);
+    var type = _getExpectedReturnType(body, yieldStar: yieldStar);
+    if (type == null) {
+      // We have a type mismatch: the async/async*/sync* modifier does
+      // not match the return or yield type.  We should have already gotten an
+      // analyzer error in this case.
+      return;
+    }
+    InterfaceType futureType = typeProvider.futureType;
+    DartType actualType = expression?.staticType;
+    if (body.isAsynchronous &&
+        !body.isGenerator &&
+        actualType is InterfaceType &&
+        actualType.element == futureType.element) {
+      type = futureType.substitute4([type]);
+    }
+    // TODO(vsm): Enforce void or dynamic (to void?) when expression is null.
+    if (expression != null) checkAssignment(expression, type);
+  }
+
+  void _checkRuntimeTypeCheck(AstNode node, TypeName typeName) {
+    var type = getType(typeName);
+    if (!rules.isGroundType(type)) {
+      _recordMessage(new NonGroundTypeCheckInfo(node, type));
+    }
+  }
+
+  void _checkUnary(/*PrefixExpression|PostfixExpression*/ node) {
+    var op = node.operator;
+    if (op.isUserDefinableOperator ||
+        op.type == TokenType.PLUS_PLUS ||
+        op.type == TokenType.MINUS_MINUS) {
+      if (_isDynamicTarget(node.operand)) {
+        _recordDynamicInvoke(node, node.operand);
+      }
+      // For ++ and --, even if it is not dynamic, we still need to check
+      // that the user defined method accepts an `int` as the RHS.
+      // We assume Analyzer has done this already.
+    }
+  }
+
+  Coercion _coerceTo(DartType fromT, DartType toT) {
+    // We can use anything as void
+    if (toT.isVoid) return Coercion.identity(toT);
+
+    // fromT <: toT, no coercion needed
+    if (rules.isSubtypeOf(fromT, toT)) return Coercion.identity(toT);
+
+    // TODO(vsm): We can get rid of the second clause if we disallow
+    // all sideways casts - see TODO below.
+    // -------
+    // Note: a function type is never assignable to a class per the Dart
+    // spec - even if it has a compatible call method.  We disallow as
+    // well for consistency.
+    if ((fromT is FunctionType && rules.getCallMethodType(toT) != null) ||
+        (toT is FunctionType && rules.getCallMethodType(fromT) != null)) {
+      return Coercion.error();
+    }
+
+    // Downcast if toT <: fromT
+    if (rules.isSubtypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
+
+    // TODO(vsm): Once we have generic methods, we should delete this
+    // workaround.  These sideways casts are always ones we warn about
+    // - i.e., we think they are likely to fail at runtime.
+    // -------
+    // Downcast if toT <===> fromT
+    // The intention here is to allow casts that are sideways in the restricted
+    // type system, but allowed in the regular dart type system, since these
+    // are likely to succeed.  The canonical example is List<dynamic> and
+    // Iterable<T> for some concrete T (e.g. Object).  These are unrelated
+    // in the restricted system, but List<dynamic> <: Iterable<T> in dart.
+    if (fromT.isAssignableTo(toT)) {
+      return Coercion.cast(fromT, toT);
+    }
+
+    return Coercion.error();
+  }
+
+  // Produce a coercion which coerces something of type fromT
+  // to something of type toT.
+  // Returns the error coercion if the types cannot be coerced
+  // according to our current criteria.
+  /// Gets the expected return type of the given function [body], either from
+  /// a normal return/yield, or from a yield*.
+  DartType _getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) {
+    FunctionType functionType;
+    var parent = body.parent;
+    if (parent is Declaration) {
+      functionType = _elementType(parent.element);
+    } else {
+      assert(parent is FunctionExpression);
+      functionType = parent.staticType ?? DynamicTypeImpl.instance;
+    }
+
+    var type = functionType.returnType;
+
+    InterfaceType expectedType = null;
+    if (body.isAsynchronous) {
+      if (body.isGenerator) {
+        // Stream<T> -> T
+        expectedType = typeProvider.streamType;
+      } else {
+        // Future<T> -> T
+        // TODO(vsm): Revisit with issue #228.
+        expectedType = typeProvider.futureType;
+      }
+    } else {
+      if (body.isGenerator) {
+        // Iterable<T> -> T
+        expectedType = typeProvider.iterableType;
+      } else {
+        // T -> T
+        return type;
+      }
+    }
+    if (yieldStar) {
+      if (type.isDynamic) {
+        // Ensure it's at least a Stream / Iterable.
+        return expectedType.substitute4([typeProvider.dynamicType]);
+      } else {
+        // Analyzer will provide a separate error if expected type
+        // is not compatible with type.
+        return type;
+      }
+    }
+    if (type.isDynamic) {
+      return type;
+    } else if (type is InterfaceType && type.element == expectedType.element) {
+      return type.typeArguments[0];
+    } else {
+      // Malformed type - fallback on analyzer error.
+      return null;
+    }
+  }
+
+  DartType _getStaticType(Expression expr) {
+    return expr.staticType ?? DynamicTypeImpl.instance;
+  }
+
+  /// Given an expression, return its type assuming it is
+  /// in the caller position of a call (that is, accounting
+  /// for the possibility of a call method).  Returns null
+  /// if expression is not statically callable.
+  FunctionType _getTypeAsCaller(Expression node) {
+    DartType t = node.staticType;
+    if (node is SimpleIdentifier) {
+      Expression parent = node.parent;
+      if (parent is MethodInvocation) {
+        t = parent.staticInvokeType;
+      }
+    }
+    if (t is InterfaceType) {
+      return rules.getCallMethodType(t);
+    }
+    if (t is FunctionType) return t;
+    return null;
+  }
+
+  /// Checks if we can perform downwards inference on [e] tp get type [t].
+  /// If it is not possible, this will add a message to [errors].
+  bool _inferExpression(Expression e, DartType t, List<String> errors) {
+    DartType staticType = e.staticType ?? DynamicTypeImpl.instance;
+    if (rules.isSubtypeOf(staticType, t)) {
+      return true;
+    }
+    errors.add("$e cannot be typed as $t");
+    return false;
+  }
+
+  /// Returns `true` if the expression is a dynamic function call or method
+  /// invocation.
+  bool _isDynamicCall(Expression call) {
+    var ft = _getTypeAsCaller(call);
+    // TODO(leafp): This will currently return true if t is Function
+    // This is probably the most correct thing to do for now, since
+    // this code is also used by the back end.  Maybe revisit at some
+    // point?
+    if (ft == null) return true;
+    // Dynamic as the parameter type is treated as bottom.  A function with
+    // a dynamic parameter type requires a dynamic call in general.
+    // However, as an optimization, if we have an original definition, we know
+    // dynamic is reified as Object - in this case a regular call is fine.
+    if (call is SimpleIdentifier) {
+      var element = call.staticElement;
+      if (element is FunctionElement || element is MethodElement) {
+        // An original declaration.
+        return false;
+      }
+    }
+
+    return rules.anyParameterType(ft, (pt) => pt.isDynamic);
+  }
+
+  /// Returns `true` if the target expression is dynamic.
+  bool _isDynamicTarget(Expression node) {
+    if (node == null) return false;
+
+    if (_isLibraryPrefix(node)) return false;
+
+    // Null type happens when we have unknown identifiers, like a dart: import
+    // that doesn't resolve.
+    var type = node.staticType;
+    return type == null || type.isDynamic;
+  }
+
+  bool _isLibraryPrefix(Expression node) =>
+      node is SimpleIdentifier && node.staticElement is PrefixElement;
+
+  bool _isObjectGetter(Expression target, SimpleIdentifier id) {
+    PropertyAccessorElement element =
+        typeProvider.objectType.element.getGetter(id.name);
+    return (element != null && !element.isStatic);
+  }
+
+  bool _isObjectMethod(Expression target, SimpleIdentifier id) {
+    MethodElement element = typeProvider.objectType.element.getMethod(id.name);
+    return (element != null && !element.isStatic);
+  }
+
+  bool _isObjectProperty(Expression target, SimpleIdentifier id) {
+    return _isObjectGetter(target, id) || _isObjectMethod(target, id);
+  }
+
+  void _recordDynamicInvoke(AstNode node, AstNode target) {
+    if (_hints) {
+      reporter.onError(new DynamicInvoke(rules, node).toAnalysisError());
+    }
+    // TODO(jmesserly): we may eventually want to record if the whole operation
+    // (node) was dynamic, rather than the target, but this is an easier fit
+    // with what we used to do.
+    DynamicInvoke.set(target, true);
+  }
+
+  void _recordMessage(StaticInfo info) {
+    if (info == null) return;
+    var error = info.toAnalysisError();
+    var severity = error.errorCode.errorSeverity;
+    if (severity == ErrorSeverity.ERROR) _failure = true;
+    if (severity != ErrorSeverity.INFO || _hints) {
+      reporter.onError(error);
+    }
+
+    if (info is CoercionInfo) {
+      // TODO(jmesserly): if we're run again on the same AST, we'll produce the
+      // same annotations. This should be harmless. This might go away once
+      // CodeChecker is integrated better with analyzer, as it will know that
+      // checking has already been performed.
+      // assert(CoercionInfo.get(info.node) == null);
+      CoercionInfo.set(info.node, info);
+    }
+  }
+
+  DartType _specializedBinaryReturnType(
+      TokenType op, DartType t1, DartType t2, DartType normalReturnType) {
+    // This special cases binary return types as per 16.26 and 16.27 of the
+    // Dart language spec.
+    switch (op) {
+      case TokenType.PLUS:
+      case TokenType.MINUS:
+      case TokenType.STAR:
+      case TokenType.TILDE_SLASH:
+      case TokenType.PERCENT:
+      case TokenType.PLUS_EQ:
+      case TokenType.MINUS_EQ:
+      case TokenType.STAR_EQ:
+      case TokenType.TILDE_SLASH_EQ:
+      case TokenType.PERCENT_EQ:
+        if (t1 == typeProvider.intType && t2 == typeProvider.intType) return t1;
+        if (t1 == typeProvider.doubleType && t2 == typeProvider.doubleType)
+          return t1;
+        // This particular combo is not spelled out in the spec, but all
+        // implementations and analyzer seem to follow this.
+        if (t1 == typeProvider.doubleType && t2 == typeProvider.intType)
+          return t1;
+    }
+    return normalReturnType;
+  }
+}
 
 /// Checks for overriding declarations of fields and methods. This is used to
 /// check overrides between classes and superclasses, interfaces, and mixin
 /// applications.
 class _OverrideChecker {
   bool _failure = false;
-  final TypeRules _rules;
+  final StrongTypeSystemImpl rules;
   final AnalysisErrorListener _reporter;
 
-  _OverrideChecker(this._rules, this._reporter);
+  _OverrideChecker(this.rules, this._reporter);
 
   void check(ClassDeclaration node) {
     if (node.element.type.isObject) return;
@@ -31,67 +942,6 @@
     _checkAllInterfaceOverrides(node);
   }
 
-  /// Check overrides from mixin applications themselves. For example, in:
-  ///
-  ///      A extends B with E, F
-  ///
-  ///  we check:
-  ///
-  ///      B & E against B (equivalently how E overrides B)
-  ///      B & E & F against B & E (equivalently how F overrides both B and E)
-  void _checkMixinApplicationOverrides(ClassDeclaration node) {
-    var type = node.element.type;
-    var parent = type.superclass;
-    var mixins = type.mixins;
-
-    // Check overrides from applying mixins
-    for (int i = 0; i < mixins.length; i++) {
-      var seen = new Set<String>();
-      var current = mixins[i];
-      var errorLocation = node.withClause.mixinTypes[i];
-      for (int j = i - 1; j >= 0; j--) {
-        _checkIndividualOverridesFromType(
-            current, mixins[j], errorLocation, seen);
-      }
-      _checkIndividualOverridesFromType(current, parent, errorLocation, seen);
-    }
-  }
-
-  /// Check overrides between a class and its superclasses and mixins. For
-  /// example, in:
-  ///
-  ///      A extends B with E, F
-  ///
-  /// we check A against B, B super classes, E, and F.
-  ///
-  /// Internally we avoid reporting errors twice and we visit classes bottom up
-  /// to ensure we report the most immediate invalid override first. For
-  /// example, in the following code we'll report that `Test` has an invalid
-  /// override with respect to `Parent` (as opposed to an invalid override with
-  /// respect to `Grandparent`):
-  ///
-  ///     class Grandparent {
-  ///         m(A a) {}
-  ///     }
-  ///     class Parent extends Grandparent {
-  ///         m(A a) {}
-  ///     }
-  ///     class Test extends Parent {
-  ///         m(B a) {} // invalid override
-  ///     }
-  void _checkSuperOverrides(ClassDeclaration node) {
-    var seen = new Set<String>();
-    var current = node.element.type;
-    var visited = new Set<InterfaceType>();
-    do {
-      visited.add(current);
-      current.mixins.reversed
-          .forEach((m) => _checkIndividualOverridesFromClass(node, m, seen));
-      _checkIndividualOverridesFromClass(node, current.superclass, seen);
-      current = current.superclass;
-    } while (!current.isObject && !visited.contains(current));
-  }
-
   /// Checks that implementations correctly override all reachable interfaces.
   /// In particular, we need to check these overrides for the definitions in
   /// the class itself and each its superclasses. If a superclass is not
@@ -143,6 +993,72 @@
         includeParents: false);
   }
 
+  /// Check that individual methods and fields in [subType] correctly override
+  /// the declarations in [baseType].
+  ///
+  /// The [errorLocation] node indicates where errors are reported, see
+  /// [_checkSingleOverride] for more details.
+  _checkIndividualOverridesFromClass(ClassDeclaration node,
+      InterfaceType baseType, Set<String> seen, bool isSubclass) {
+    for (var member in node.members) {
+      if (member is ConstructorDeclaration) continue;
+      if (member is FieldDeclaration) {
+        if (member.isStatic) continue;
+        for (var variable in member.fields.variables) {
+          var element = variable.element as PropertyInducingElement;
+          var name = element.name;
+          if (seen.contains(name)) continue;
+          var getter = element.getter;
+          var setter = element.setter;
+          bool found = _checkSingleOverride(
+              getter, baseType, variable, member, isSubclass);
+          if (!variable.isFinal &&
+              !variable.isConst &&
+              _checkSingleOverride(
+                  setter, baseType, variable, member, isSubclass)) {
+            found = true;
+          }
+          if (found) seen.add(name);
+        }
+      } else {
+        if ((member as MethodDeclaration).isStatic) continue;
+        var method = (member as MethodDeclaration).element;
+        if (seen.contains(method.name)) continue;
+        if (_checkSingleOverride(
+            method, baseType, member, member, isSubclass)) {
+          seen.add(method.name);
+        }
+      }
+    }
+  }
+
+  /// Check that individual methods and fields in [subType] correctly override
+  /// the declarations in [baseType].
+  ///
+  /// The [errorLocation] node indicates where errors are reported, see
+  /// [_checkSingleOverride] for more details.
+  ///
+  /// The set [seen] is used to avoid reporting overrides more than once. It
+  /// is used when invoking this function multiple times when checking several
+  /// types in a class hierarchy. Errors are reported only the first time an
+  /// invalid override involving a specific member is encountered.
+  _checkIndividualOverridesFromType(
+      InterfaceType subType,
+      InterfaceType baseType,
+      AstNode errorLocation,
+      Set<String> seen,
+      bool isSubclass) {
+    void checkHelper(ExecutableElement e) {
+      if (e.isStatic) return;
+      if (seen.contains(e.name)) return;
+      if (_checkSingleOverride(e, baseType, null, errorLocation, isSubclass)) {
+        seen.add(e.name);
+      }
+    }
+    subType.methods.forEach(checkHelper);
+    subType.accessors.forEach(checkHelper);
+  }
+
   /// Checks that [cls] and its super classes (including mixins) correctly
   /// overrides each interface in [interfaces]. If [includeParents] is false,
   /// then mixins are still checked, but the base type and it's transitive
@@ -171,10 +1087,10 @@
     // Check direct overrides on [type]
     for (var interfaceType in interfaces) {
       if (node != null) {
-        _checkIndividualOverridesFromClass(node, interfaceType, seen);
+        _checkIndividualOverridesFromClass(node, interfaceType, seen, false);
       } else {
         _checkIndividualOverridesFromType(
-            type, interfaceType, errorLocation, seen);
+            type, interfaceType, errorLocation, seen, false);
       }
     }
 
@@ -186,7 +1102,7 @@
         // We copy [seen] so we can report separately if more than one mixin or
         // the base class have an invalid override.
         _checkIndividualOverridesFromType(
-            type.mixins[i], interfaceType, loc, new Set.from(seen));
+            type.mixins[i], interfaceType, loc, new Set.from(seen), false);
       }
     }
 
@@ -202,62 +1118,30 @@
     }
   }
 
-  /// Check that individual methods and fields in [subType] correctly override
-  /// the declarations in [baseType].
+  /// Check overrides from mixin applications themselves. For example, in:
   ///
-  /// The [errorLocation] node indicates where errors are reported, see
-  /// [_checkSingleOverride] for more details.
+  ///      A extends B with E, F
   ///
-  /// The set [seen] is used to avoid reporting overrides more than once. It
-  /// is used when invoking this function multiple times when checking several
-  /// types in a class hierarchy. Errors are reported only the first time an
-  /// invalid override involving a specific member is encountered.
-  _checkIndividualOverridesFromType(InterfaceType subType,
-      InterfaceType baseType, AstNode errorLocation, Set<String> seen) {
-    void checkHelper(ExecutableElement e) {
-      if (e.isStatic) return;
-      if (seen.contains(e.name)) return;
-      if (_checkSingleOverride(e, baseType, null, errorLocation)) {
-        seen.add(e.name);
-      }
-    }
-    subType.methods.forEach(checkHelper);
-    subType.accessors.forEach(checkHelper);
-  }
+  ///  we check:
+  ///
+  ///      B & E against B (equivalently how E overrides B)
+  ///      B & E & F against B & E (equivalently how F overrides both B and E)
+  void _checkMixinApplicationOverrides(ClassDeclaration node) {
+    var type = node.element.type;
+    var parent = type.superclass;
+    var mixins = type.mixins;
 
-  /// Check that individual methods and fields in [subType] correctly override
-  /// the declarations in [baseType].
-  ///
-  /// The [errorLocation] node indicates where errors are reported, see
-  /// [_checkSingleOverride] for more details.
-  _checkIndividualOverridesFromClass(
-      ClassDeclaration node, InterfaceType baseType, Set<String> seen) {
-    for (var member in node.members) {
-      if (member is ConstructorDeclaration) continue;
-      if (member is FieldDeclaration) {
-        if (member.isStatic) continue;
-        for (var variable in member.fields.variables) {
-          var element = variable.element as PropertyInducingElement;
-          var name = element.name;
-          if (seen.contains(name)) continue;
-          var getter = element.getter;
-          var setter = element.setter;
-          bool found = _checkSingleOverride(getter, baseType, variable, member);
-          if (!variable.isFinal &&
-              !variable.isConst &&
-              _checkSingleOverride(setter, baseType, variable, member)) {
-            found = true;
-          }
-          if (found) seen.add(name);
-        }
-      } else {
-        if ((member as MethodDeclaration).isStatic) continue;
-        var method = (member as MethodDeclaration).element;
-        if (seen.contains(method.name)) continue;
-        if (_checkSingleOverride(method, baseType, member, member)) {
-          seen.add(method.name);
-        }
+    // Check overrides from applying mixins
+    for (int i = 0; i < mixins.length; i++) {
+      var seen = new Set<String>();
+      var current = mixins[i];
+      var errorLocation = node.withClause.mixinTypes[i];
+      for (int j = i - 1; j >= 0; j--) {
+        _checkIndividualOverridesFromType(
+            current, mixins[j], errorLocation, seen, true);
       }
+      _checkIndividualOverridesFromType(
+          current, parent, errorLocation, seen, true);
     }
   }
 
@@ -288,16 +1172,25 @@
   /// the AST node that defines [element]. This is used to determine whether the
   /// type of the element could be inferred from the types in the super classes.
   bool _checkSingleOverride(ExecutableElement element, InterfaceType type,
-      AstNode node, AstNode errorLocation) {
+      AstNode node, AstNode errorLocation, bool isSubclass) {
     assert(!element.isStatic);
 
-    FunctionType subType = _rules.elementType(element);
+    FunctionType subType = _elementType(element);
     // TODO(vsm): Test for generic
     FunctionType baseType = _getMemberType(type, element);
-
     if (baseType == null) return false;
-    if (!_rules.isAssignable(subType, baseType)) {
-      // See whether non-assignable cases fit one of our common patterns:
+
+    if (isSubclass && element is PropertyAccessorElement) {
+      // Disallow any overriding if the base class defines this member
+      // as a field.  We effectively treat fields as final / non-virtual.
+      PropertyInducingElement field = _getMemberField(type, element);
+      if (field != null) {
+        _recordMessage(new InvalidFieldOverride(
+            errorLocation, element, type, subType, baseType));
+      }
+    }
+    if (!rules.isSubtypeOf(subType, baseType)) {
+      // See whether non-subtype cases fit one of our common patterns:
       //
       // Common pattern 1: Inferable return type (on getters and methods)
       //   class A {
@@ -314,6 +1207,41 @@
     return true;
   }
 
+  /// Check overrides between a class and its superclasses and mixins. For
+  /// example, in:
+  ///
+  ///      A extends B with E, F
+  ///
+  /// we check A against B, B super classes, E, and F.
+  ///
+  /// Internally we avoid reporting errors twice and we visit classes bottom up
+  /// to ensure we report the most immediate invalid override first. For
+  /// example, in the following code we'll report that `Test` has an invalid
+  /// override with respect to `Parent` (as opposed to an invalid override with
+  /// respect to `Grandparent`):
+  ///
+  ///     class Grandparent {
+  ///         m(A a) {}
+  ///     }
+  ///     class Parent extends Grandparent {
+  ///         m(A a) {}
+  ///     }
+  ///     class Test extends Parent {
+  ///         m(B a) {} // invalid override
+  ///     }
+  void _checkSuperOverrides(ClassDeclaration node) {
+    var seen = new Set<String>();
+    var current = node.element.type;
+    var visited = new Set<InterfaceType>();
+    do {
+      visited.add(current);
+      current.mixins.reversed.forEach(
+          (m) => _checkIndividualOverridesFromClass(node, m, seen, true));
+      _checkIndividualOverridesFromClass(node, current.superclass, seen, true);
+      current = current.superclass;
+    } while (!current.isObject && !visited.contains(current));
+  }
+
   void _recordMessage(StaticInfo info) {
     if (info == null) return;
     var error = info.toAnalysisError();
@@ -321,665 +1249,3 @@
     _reporter.onError(error);
   }
 }
-
-/// Checks the body of functions and properties.
-class CodeChecker extends RecursiveAstVisitor {
-  final TypeRules rules;
-  final AnalysisErrorListener reporter;
-  final _OverrideChecker _overrideChecker;
-  final bool _hints;
-
-  bool _failure = false;
-  bool get failure => _failure || _overrideChecker._failure;
-
-  void reset() {
-    _failure = false;
-    _overrideChecker._failure = false;
-  }
-
-  CodeChecker(TypeRules rules, AnalysisErrorListener reporter,
-      {bool hints: false})
-      : rules = rules,
-        reporter = reporter,
-        _hints = hints,
-        _overrideChecker = new _OverrideChecker(rules, reporter);
-
-  @override
-  void visitComment(Comment node) {
-    // skip, no need to do typechecking inside comments (they may contain
-    // comment references which would require resolution).
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    _overrideChecker.check(node);
-    super.visitClassDeclaration(node);
-  }
-
-  @override
-  void visitAssignmentExpression(AssignmentExpression node) {
-    var token = node.operator;
-    if (token.type != TokenType.EQ) {
-      _checkCompoundAssignment(node);
-    } else {
-      DartType staticType = _getStaticType(node.leftHandSide);
-      checkAssignment(node.rightHandSide, staticType);
-    }
-    node.visitChildren(this);
-  }
-
-  /// Check constructor declaration to ensure correct super call placement.
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    node.visitChildren(this);
-
-    final init = node.initializers;
-    for (int i = 0, last = init.length - 1; i < last; i++) {
-      final node = init[i];
-      if (node is SuperConstructorInvocation) {
-        _recordMessage(new InvalidSuperInvocation(node));
-      }
-    }
-  }
-
-  @override
-  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    var field = node.fieldName;
-    var element = field.staticElement;
-    DartType staticType = rules.elementType(element);
-    checkAssignment(node.expression, staticType);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitForEachStatement(ForEachStatement node) {
-    // Check that the expression is an Iterable.
-    var expr = node.iterable;
-    var iterableType = node.awaitKeyword != null
-        ? rules.provider.streamType
-        : rules.provider.iterableType;
-    var loopVariable = node.identifier != null
-        ? node.identifier
-        : node.loopVariable?.identifier;
-    if (loopVariable != null) {
-      var iteratorType = loopVariable.staticType;
-      var checkedType = iterableType.substitute4([iteratorType]);
-      checkAssignment(expr, checkedType);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    if (node.condition != null) {
-      checkBoolean(node.condition);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitIfStatement(IfStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    // SwitchStatement defines a boolean conversion to check the result of the
-    // case value == the switch value, but in dev_compiler we require a boolean
-    // return type from an overridden == operator (because Object.==), so
-    // checking in SwitchStatement shouldn't be necessary.
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitListLiteral(ListLiteral node) {
-    var type = rules.provider.dynamicType;
-    if (node.typeArguments != null) {
-      var targs = node.typeArguments.arguments;
-      if (targs.length > 0) type = targs[0].type;
-    }
-    var elements = node.elements;
-    for (int i = 0; i < elements.length; i++) {
-      checkArgument(elements[i], type);
-    }
-    super.visitListLiteral(node);
-  }
-
-  @override
-  void visitMapLiteral(MapLiteral node) {
-    var ktype = rules.provider.dynamicType;
-    var vtype = rules.provider.dynamicType;
-    if (node.typeArguments != null) {
-      var targs = node.typeArguments.arguments;
-      if (targs.length > 0) ktype = targs[0].type;
-      if (targs.length > 1) vtype = targs[1].type;
-    }
-    var entries = node.entries;
-    for (int i = 0; i < entries.length; i++) {
-      var entry = entries[i];
-      checkArgument(entry.key, ktype);
-      checkArgument(entry.value, vtype);
-    }
-    super.visitMapLiteral(node);
-  }
-
-  // Check invocations
-  void checkArgumentList(ArgumentList node, FunctionType type) {
-    NodeList<Expression> list = node.arguments;
-    int len = list.length;
-    for (int i = 0; i < len; ++i) {
-      Expression arg = list[i];
-      ParameterElement element = arg.staticParameterElement;
-      if (element == null) {
-        if (type.parameters.length < len) {
-          // We found an argument mismatch, the analyzer will report this too,
-          // so no need to insert an error for this here.
-          continue;
-        }
-        element = type.parameters[i];
-        // TODO(vsm): When can this happen?
-        assert(element != null);
-      }
-      DartType expectedType = rules.elementType(element);
-      if (expectedType == null) expectedType = rules.provider.dynamicType;
-      checkArgument(arg, expectedType);
-    }
-  }
-
-  void checkArgument(Expression arg, DartType expectedType) {
-    // Preserve named argument structure, so their immediate parent is the
-    // method invocation.
-    if (arg is NamedExpression) {
-      arg = (arg as NamedExpression).expression;
-    }
-    checkAssignment(arg, expectedType);
-  }
-
-  void checkFunctionApplication(
-      Expression node, Expression f, ArgumentList list) {
-    if (rules.isDynamicCall(f)) {
-      // If f is Function and this is a method invocation, we should have
-      // gotten an analyzer error, so no need to issue another error.
-      _recordDynamicInvoke(node, f);
-    } else {
-      checkArgumentList(list, rules.getTypeAsCaller(f));
-    }
-  }
-
-  @override
-  visitMethodInvocation(MethodInvocation node) {
-    var target = node.realTarget;
-    if (rules.isDynamicTarget(target) &&
-        !_isObjectMethod(node, node.methodName)) {
-      _recordDynamicInvoke(node, target);
-
-      // Mark the tear-off as being dynamic, too. This lets us distinguish
-      // cases like:
-      //
-      //     dynamic d;
-      //     d.someMethod(...); // the whole method call must be a dynamic send.
-      //
-      // ... from case like:
-      //
-      //     SomeType s;
-      //     s.someDynamicField(...); // static get, followed by dynamic call.
-      //
-      // The first case is handled here, the second case is handled below when
-      // we call [checkFunctionApplication].
-      DynamicInvoke.set(node.methodName, true);
-    } else {
-      checkFunctionApplication(node, node.methodName, node.argumentList);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    checkFunctionApplication(node, node.function, node.argumentList);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    var type = node.staticElement.type;
-    checkArgumentList(node.argumentList, type);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    var element = node.staticElement;
-    if (element != null) {
-      var type = node.staticElement.type;
-      checkArgumentList(node.argumentList, type);
-    }
-    node.visitChildren(this);
-  }
-
-  void _checkReturnOrYield(Expression expression, AstNode node,
-      {bool yieldStar: false}) {
-    var body = node.getAncestor((n) => n is FunctionBody);
-    var type = rules.getExpectedReturnType(body, yieldStar: yieldStar);
-    if (type == null) {
-      // We have a type mismatch: the async/async*/sync* modifier does
-      // not match the return or yield type.  We should have already gotten an
-      // analyzer error in this case.
-      return;
-    }
-    // TODO(vsm): Enforce void or dynamic (to void?) when expression is null.
-    if (expression != null) checkAssignment(expression, type);
-  }
-
-  @override
-  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    _checkReturnOrYield(node.expression, node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitReturnStatement(ReturnStatement node) {
-    _checkReturnOrYield(node.expression, node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitYieldStatement(YieldStatement node) {
-    _checkReturnOrYield(node.expression, node, yieldStar: node.star != null);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitPropertyAccess(PropertyAccess node) {
-    var target = node.realTarget;
-    if (rules.isDynamicTarget(target) &&
-        !_isObjectProperty(target, node.propertyName)) {
-      _recordDynamicInvoke(node, target);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitPrefixedIdentifier(PrefixedIdentifier node) {
-    final target = node.prefix;
-    if (rules.isDynamicTarget(target) &&
-        !_isObjectProperty(target, node.identifier)) {
-      _recordDynamicInvoke(node, target);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    // Check that defaults have the proper subtype.
-    var parameter = node.parameter;
-    var parameterType = rules.elementType(parameter.element);
-    assert(parameterType != null);
-    var defaultValue = node.defaultValue;
-    if (defaultValue != null) {
-      checkAssignment(defaultValue, parameterType);
-    }
-
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitFieldFormalParameter(FieldFormalParameter node) {
-    var element = node.element;
-    var typeName = node.type;
-    if (typeName != null) {
-      var type = rules.elementType(element);
-      var fieldElement =
-          node.identifier.staticElement as FieldFormalParameterElement;
-      var fieldType = rules.elementType(fieldElement.field);
-      if (!rules.isSubTypeOf(type, fieldType)) {
-        var staticInfo =
-            new InvalidParameterDeclaration(rules, node, fieldType);
-        _recordMessage(staticInfo);
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    var arguments = node.argumentList;
-    var element = node.staticElement;
-    if (element != null) {
-      var type = rules.elementType(node.staticElement);
-      checkArgumentList(arguments, type);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    TypeName type = node.type;
-    if (type == null) {
-      // No checks are needed when the type is var. Although internally the
-      // typing rules may have inferred a more precise type for the variable
-      // based on the initializer.
-    } else {
-      var dartType = getType(type);
-      for (VariableDeclaration variable in node.variables) {
-        var initializer = variable.initializer;
-        if (initializer != null) {
-          checkAssignment(initializer, dartType);
-        }
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  void _checkRuntimeTypeCheck(AstNode node, TypeName typeName) {
-    var type = getType(typeName);
-    if (!rules.isGroundType(type)) {
-      _recordMessage(new NonGroundTypeCheckInfo(node, type));
-    }
-  }
-
-  @override
-  void visitAsExpression(AsExpression node) {
-    // We could do the same check as the IsExpression below, but that is
-    // potentially too conservative.  Instead, at runtime, we must fail hard
-    // if the Dart as and the DDC as would return different values.
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitIsExpression(IsExpression node) {
-    _checkRuntimeTypeCheck(node, node.type);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitPrefixExpression(PrefixExpression node) {
-    if (node.operator.type == TokenType.BANG) {
-      checkBoolean(node.operand);
-    } else {
-      _checkUnary(node);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitPostfixExpression(PostfixExpression node) {
-    _checkUnary(node);
-    node.visitChildren(this);
-  }
-
-  void _checkUnary(/*PrefixExpression|PostfixExpression*/ node) {
-    var op = node.operator;
-    if (op.isUserDefinableOperator ||
-        op.type == TokenType.PLUS_PLUS ||
-        op.type == TokenType.MINUS_MINUS) {
-      if (rules.isDynamicTarget(node.operand)) {
-        _recordDynamicInvoke(node, node.operand);
-      }
-      // For ++ and --, even if it is not dynamic, we still need to check
-      // that the user defined method accepts an `int` as the RHS.
-      // We assume Analyzer has done this already.
-    }
-  }
-
-  @override
-  void visitBinaryExpression(BinaryExpression node) {
-    var op = node.operator;
-    if (op.isUserDefinableOperator) {
-      if (rules.isDynamicTarget(node.leftOperand)) {
-        // Dynamic invocation
-        // TODO(vsm): Move this logic to the resolver?
-        if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) {
-          _recordDynamicInvoke(node, node.leftOperand);
-        }
-      } else {
-        var element = node.staticElement;
-        // Method invocation.
-        if (element is MethodElement) {
-          var type = element.type;
-          // Analyzer should enforce number of parameter types, but check in
-          // case we have erroneous input.
-          if (type.normalParameterTypes.isNotEmpty) {
-            checkArgument(node.rightOperand, type.normalParameterTypes[0]);
-          }
-        } else {
-          // TODO(vsm): Assert that the analyzer found an error here?
-        }
-      }
-    } else {
-      // Non-method operator.
-      switch (op.type) {
-        case TokenType.AMPERSAND_AMPERSAND:
-        case TokenType.BAR_BAR:
-          checkBoolean(node.leftOperand);
-          checkBoolean(node.rightOperand);
-          break;
-        case TokenType.BANG_EQ:
-          break;
-        case TokenType.QUESTION_QUESTION:
-          break;
-        default:
-          assert(false);
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitConditionalExpression(ConditionalExpression node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitIndexExpression(IndexExpression node) {
-    var target = node.realTarget;
-    if (rules.isDynamicTarget(target)) {
-      _recordDynamicInvoke(node, target);
-    } else {
-      var element = node.staticElement;
-      if (element is MethodElement) {
-        var type = element.type;
-        // Analyzer should enforce number of parameter types, but check in
-        // case we have erroneous input.
-        if (type.normalParameterTypes.isNotEmpty) {
-          checkArgument(node.index, type.normalParameterTypes[0]);
-        }
-      } else {
-        // TODO(vsm): Assert that the analyzer found an error here?
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  DartType getType(TypeName name) {
-    return (name == null) ? rules.provider.dynamicType : name.type;
-  }
-
-  /// Analyzer checks boolean conversions, but we need to check too, because
-  /// it uses the default assignability rules that allow `dynamic` and `Object`
-  /// to be assigned to bool with no message.
-  void checkBoolean(Expression expr) =>
-      checkAssignment(expr, rules.provider.boolType);
-
-  void checkAssignment(Expression expr, DartType type) {
-    if (expr is ParenthesizedExpression) {
-      checkAssignment(expr.expression, type);
-    } else {
-      _recordMessage(rules.checkAssignment(expr, type));
-    }
-  }
-
-  DartType _specializedBinaryReturnType(
-      TokenType op, DartType t1, DartType t2, DartType normalReturnType) {
-    // This special cases binary return types as per 16.26 and 16.27 of the
-    // Dart language spec.
-    switch (op) {
-      case TokenType.PLUS:
-      case TokenType.MINUS:
-      case TokenType.STAR:
-      case TokenType.TILDE_SLASH:
-      case TokenType.PERCENT:
-      case TokenType.PLUS_EQ:
-      case TokenType.MINUS_EQ:
-      case TokenType.STAR_EQ:
-      case TokenType.TILDE_SLASH_EQ:
-      case TokenType.PERCENT_EQ:
-        if (t1 == rules.provider.intType &&
-            t2 == rules.provider.intType) return t1;
-        if (t1 == rules.provider.doubleType &&
-            t2 == rules.provider.doubleType) return t1;
-        // This particular combo is not spelled out in the spec, but all
-        // implementations and analyzer seem to follow this.
-        if (t1 == rules.provider.doubleType &&
-            t2 == rules.provider.intType) return t1;
-    }
-    return normalReturnType;
-  }
-
-  void _checkCompoundAssignment(AssignmentExpression expr) {
-    var op = expr.operator.type;
-    assert(op.isAssignmentOperator && op != TokenType.EQ);
-    var methodElement = expr.staticElement;
-    if (methodElement == null) {
-      // Dynamic invocation
-      _recordDynamicInvoke(expr, expr.leftHandSide);
-    } else {
-      // Sanity check the operator
-      assert(methodElement.isOperator);
-      var functionType = methodElement.type;
-      var paramTypes = functionType.normalParameterTypes;
-      assert(paramTypes.length == 1);
-      assert(functionType.namedParameterTypes.isEmpty);
-      assert(functionType.optionalParameterTypes.isEmpty);
-
-      // Check the lhs type
-      var staticInfo;
-      var rhsType = _getStaticType(expr.rightHandSide);
-      var lhsType = _getStaticType(expr.leftHandSide);
-      var returnType = _specializedBinaryReturnType(
-          op, lhsType, rhsType, functionType.returnType);
-
-      if (!rules.isSubTypeOf(returnType, lhsType)) {
-        final numType = rules.provider.numType;
-        // Try to fix up the numerical case if possible.
-        if (rules.isSubTypeOf(lhsType, numType) &&
-            rules.isSubTypeOf(lhsType, rhsType)) {
-          // This is also slightly different from spec, but allows us to keep
-          // compound operators in the int += num and num += dynamic cases.
-          staticInfo = DownCast.create(
-              rules, expr.rightHandSide, Coercion.cast(rhsType, lhsType));
-          rhsType = lhsType;
-        } else {
-          // Static type error
-          staticInfo = new StaticTypeError(rules, expr, lhsType);
-        }
-        _recordMessage(staticInfo);
-      }
-
-      // Check the rhs type
-      if (staticInfo is! CoercionInfo) {
-        var paramType = paramTypes.first;
-        staticInfo = rules.checkAssignment(expr.rightHandSide, paramType);
-        _recordMessage(staticInfo);
-      }
-    }
-  }
-
-  bool _isObjectGetter(Expression target, SimpleIdentifier id) {
-    PropertyAccessorElement element =
-        rules.provider.objectType.element.getGetter(id.name);
-    return (element != null && !element.isStatic);
-  }
-
-  bool _isObjectMethod(Expression target, SimpleIdentifier id) {
-    MethodElement element =
-        rules.provider.objectType.element.getMethod(id.name);
-    return (element != null && !element.isStatic);
-  }
-
-  bool _isObjectProperty(Expression target, SimpleIdentifier id) {
-    return _isObjectGetter(target, id) || _isObjectMethod(target, id);
-  }
-
-  DartType _getStaticType(Expression expr) {
-    return expr.staticType ?? rules.provider.dynamicType;
-  }
-
-  void _recordDynamicInvoke(AstNode node, AstNode target) {
-    if (_hints) {
-      reporter.onError(new DynamicInvoke(rules, node).toAnalysisError());
-    }
-    // TODO(jmesserly): we may eventually want to record if the whole operation
-    // (node) was dynamic, rather than the target, but this is an easier fit
-    // with what we used to do.
-    DynamicInvoke.set(target, true);
-  }
-
-  void _recordMessage(StaticInfo info) {
-    if (info == null) return;
-    var error = info.toAnalysisError();
-
-    var severity = error.errorCode.errorSeverity;
-    if (severity == ErrorSeverity.ERROR) _failure = true;
-    if (severity != ErrorSeverity.INFO || _hints) {
-      reporter.onError(error);
-    }
-
-    if (info is CoercionInfo) {
-      // TODO(jmesserly): if we're run again on the same AST, we'll produce the
-      // same annotations. This should be harmless. This might go away once
-      // CodeChecker is integrated better with analyzer, as it will know that
-      // checking has already been performed.
-      // assert(CoercionInfo.get(info.node) == null);
-      CoercionInfo.set(info.node, info);
-    }
-  }
-}
-
-/// Looks up the declaration that matches [member] in [type] and returns it's
-/// declared type.
-FunctionType _getMemberType(InterfaceType type, ExecutableElement member) =>
-    _memberTypeGetter(member)(type);
-
-typedef FunctionType _MemberTypeGetter(InterfaceType type);
-
-_MemberTypeGetter _memberTypeGetter(ExecutableElement member) {
-  String memberName = member.name;
-  final isGetter = member is PropertyAccessorElement && member.isGetter;
-  final isSetter = member is PropertyAccessorElement && member.isSetter;
-
-  FunctionType f(InterfaceType type) {
-    ExecutableElement baseMethod;
-    try {
-      if (isGetter) {
-        assert(!isSetter);
-        // Look for getter or field.
-        baseMethod = type.getGetter(memberName);
-      } else if (isSetter) {
-        baseMethod = type.getSetter(memberName);
-      } else {
-        baseMethod = type.getMethod(memberName);
-      }
-    } catch (e) {
-      // TODO(sigmund): remove this try-catch block (see issue #48).
-    }
-    if (baseMethod == null || baseMethod.isStatic) return null;
-    return baseMethod.type;
-  }
-  ;
-  return f;
-}
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index 1aa42b2..cf4f822 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -8,11 +8,31 @@
 // refactored to fit into analyzer.
 library analyzer.src.task.strong.info;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 
-import 'rules.dart';
+// A down cast due to a variable declaration to a ground type.  E.g.,
+//   T x = expr;
+// where T is ground.  We exclude non-ground types as these behave differently
+// compared to standard Dart.
+class AssignmentCast extends DownCast {
+  AssignmentCast(TypeSystem rules, Expression expression, Cast cast)
+      : super._internal(rules, expression, cast);
+
+  @override
+  String get name => 'STRONG_MODE_ASSIGNMENT_CAST';
+
+  toErrorCode() => new HintCode(name, message);
+}
+
+// Coercion which casts one type to another
+class Cast extends Coercion {
+  Cast(DartType fromType, DartType toType) : super(fromType, toType);
+}
 
 // The abstract type of coercions mapping one type to another.
 // This class also exposes static builder functions which
@@ -22,18 +42,8 @@
   final DartType toType;
   Coercion(this.fromType, this.toType);
   static Coercion cast(DartType fromT, DartType toT) => new Cast(fromT, toT);
-  static Coercion identity(DartType type) => new Identity(type);
   static Coercion error() => new CoercionError();
-}
-
-// Coercion which casts one type to another
-class Cast extends Coercion {
-  Cast(DartType fromType, DartType toType) : super(fromType, toType);
-}
-
-// The identity coercion
-class Identity extends Coercion {
-  Identity(DartType fromType) : super(fromType, fromType);
+  static Coercion identity(DartType type) => new Identity(type);
 }
 
 // The error coercion.  This coercion signals that a coercion
@@ -43,50 +53,23 @@
   CoercionError() : super(null, null);
 }
 
-// TODO(jmesserly): this could use some refactoring. These are essentially
-// like ErrorCodes in analyzer, but we're including some details in our message.
-// Analyzer instead has template strings, and replaces '{0}' with the first
-// argument.
-abstract class StaticInfo {
-  /// AST Node this info is attached to.
-  AstNode get node;
-
-  // TODO(jmesserly): review the usage of error codes. We probably want our own,
-  // as well as some DDC specific [ErrorType]s.
-  ErrorCode toErrorCode();
-
-  // TODO(jmesserly): what convention to use here?
-  String get name => 'dev_compiler.$runtimeType';
-
-  List<Object> get arguments => [node];
-
-  AnalysisError toAnalysisError() {
-    int begin = node is AnnotatedNode
-        ? (node as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset
-        : node.offset;
-    int length = node.end - begin;
-    var source = (node.root as CompilationUnit).element.source;
-    return new AnalysisError(source, begin, length, toErrorCode(), arguments);
-  }
-}
-
 /// Implicitly injected expression conversion.
 abstract class CoercionInfo extends StaticInfo {
-  final TypeRules rules;
+  static const String _propertyName = 'dev_compiler.src.info.CoercionInfo';
+
+  final TypeSystem rules;
 
   final Expression node;
 
-  DartType get convertedType;
-
   CoercionInfo(this.rules, this.node);
 
-  DartType get baseType => rules.getStaticType(node);
-  DartType get staticType => convertedType;
+  DartType get baseType => node.staticType ?? DynamicTypeImpl.instance;
+  DartType get convertedType;
 
   String get message;
-  toErrorCode() => new HintCode(name, message);
+  DartType get staticType => convertedType;
 
-  static const String _propertyName = 'dev_compiler.src.info.CoercionInfo';
+  toErrorCode() => new HintCode(name, message);
 
   /// Gets the coercion info associated with this node.
   static CoercionInfo get(AstNode node) => node.getProperty(_propertyName);
@@ -102,7 +85,7 @@
 abstract class DownCast extends CoercionInfo {
   Cast _cast;
 
-  DownCast._internal(TypeRules rules, Expression expression, this._cast)
+  DownCast._internal(TypeSystem rules, Expression expression, this._cast)
       : super(rules, expression) {
     assert(_cast.toType != baseType &&
         _cast.fromType == baseType &&
@@ -112,16 +95,17 @@
             baseType.isAssignableTo(_cast.toType)));
   }
 
+  @override List<Object> get arguments => [node, baseType, convertedType];
+
   Cast get cast => _cast;
 
   DartType get convertedType => _cast.toType;
-
-  @override List<Object> get arguments => [node, baseType, convertedType];
   @override String get message => '{0} ({1}) will need runtime check '
       'to cast to type {2}';
 
   // Factory to create correct DownCast variant.
-  static StaticInfo create(TypeRules rules, Expression expression, Cast cast,
+  static StaticInfo create(
+      StrongTypeSystemImpl rules, Expression expression, Cast cast,
       {String reason}) {
     final fromT = cast.fromType;
     final toT = cast.toType;
@@ -156,7 +140,7 @@
 
     // TODO(vsm): Change this to an assert when we have generic methods and
     // fix TypeRules._coerceTo to disallow implicit sideways casts.
-    if (!rules.isSubTypeOf(toT, fromT)) {
+    if (!rules.isSubtypeOf(toT, fromT)) {
       assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT));
       return new DownCastComposite(rules, expression, cast);
     }
@@ -195,133 +179,56 @@
 }
 
 //
-// Standard down casts.  These casts are implicitly injected by the compiler.
-//
-
-// A down cast from dynamic to T.
-class DynamicCast extends DownCast {
-  DynamicCast(TypeRules rules, Expression expression, Cast cast)
-      : super._internal(rules, expression, cast);
-
-  toErrorCode() => new HintCode(name, message);
-}
-
-// A down cast due to a variable declaration to a ground type.  E.g.,
-//   T x = expr;
-// where T is ground.  We exclude non-ground types as these behave differently
-// compared to standard Dart.
-class AssignmentCast extends DownCast {
-  AssignmentCast(TypeRules rules, Expression expression, Cast cast)
-      : super._internal(rules, expression, cast);
-
-  toErrorCode() => new HintCode(name, message);
-}
-
-//
-// Temporary "casts" of allocation sites - literals, constructor invocations,
-// and closures.  These should be handled by contextual inference.  In most
-// cases, inference will be sufficient, though in some it may unmask an actual
-// error: e.g.,
-//   List<int> l = [1, 2, 3]; // Inference succeeds
-//   List<String> l = [1, 2, 3]; // Inference reveals static type error
-// We're marking all as warnings for now.
-//
-// TODO(vsm,leafp): Remove this.
-class UninferredClosure extends DownCast {
-  UninferredClosure(TypeRules rules, FunctionExpression expression, Cast cast)
-      : super._internal(rules, expression, cast);
-
-  toErrorCode() => new StaticTypeWarningCode(name, message);
-}
-
-//
 // Implicit down casts.  These are only injected by the compiler by flag.
 //
-
 // A down cast to a non-ground type.  These behave differently from standard
 // Dart and may be more likely to fail at runtime.
 class DownCastComposite extends DownCast {
-  DownCastComposite(TypeRules rules, Expression expression, Cast cast)
+  DownCastComposite(TypeSystem rules, Expression expression, Cast cast)
       : super._internal(rules, expression, cast);
 
+  @override
+  String get name => 'STRONG_MODE_DOWN_CAST_COMPOSITE';
+
   toErrorCode() => new StaticTypeWarningCode(name, message);
 }
 
 // A down cast to a non-ground type.  These behave differently from standard
 // Dart and may be more likely to fail at runtime.
 class DownCastImplicit extends DownCast {
-  DownCastImplicit(TypeRules rules, Expression expression, Cast cast)
+  DownCastImplicit(TypeSystem rules, Expression expression, Cast cast)
       : super._internal(rules, expression, cast);
 
-  toErrorCode() => new HintCode(name, message);
-}
-
-// An inferred type for the wrapped expression, which may need to be
-// reified into the term
-abstract class InferredTypeBase extends CoercionInfo {
-  final DartType _type;
-
-  InferredTypeBase._internal(TypeRules rules, Expression expression, this._type)
-      : super(rules, expression);
-
-  DartType get type => _type;
-  DartType get convertedType => type;
-  @override String get message => '{0} has inferred type {1}';
-  @override List get arguments => [node, type];
+  @override
+  String get name => 'STRONG_MODE_DOWN_CAST_IMPLICIT';
 
   toErrorCode() => new HintCode(name, message);
 }
 
-// Standard / unspecialized inferred type
-class InferredType extends InferredTypeBase {
-  InferredType(TypeRules rules, Expression expression, DartType type)
-      : super._internal(rules, expression, type);
+// A down cast from dynamic to T.
+class DynamicCast extends DownCast {
+  DynamicCast(TypeSystem rules, Expression expression, Cast cast)
+      : super._internal(rules, expression, cast);
 
-  // Factory to create correct InferredType variant.
-  static InferredTypeBase create(
-      TypeRules rules, Expression expression, DartType type) {
-    // Specialized inference:
-    if (expression is Literal) {
-      return new InferredTypeLiteral(rules, expression, type);
-    }
-    if (expression is InstanceCreationExpression) {
-      return new InferredTypeAllocation(rules, expression, type);
-    }
-    if (expression is FunctionExpression) {
-      return new InferredTypeClosure(rules, expression, type);
-    }
-    return new InferredType(rules, expression, type);
-  }
-}
+  @override
+  String get name => 'STRONG_MODE_DYNAMIC_CAST';
 
-// An infered type for a literal expression.
-class InferredTypeLiteral extends InferredTypeBase {
-  InferredTypeLiteral(TypeRules rules, Expression expression, DartType type)
-      : super._internal(rules, expression, type);
-}
-
-// An inferred type for a non-literal allocation site.
-class InferredTypeAllocation extends InferredTypeBase {
-  InferredTypeAllocation(TypeRules rules, Expression expression, DartType type)
-      : super._internal(rules, expression, type);
-}
-
-// An inferred type for a closure expression
-class InferredTypeClosure extends InferredTypeBase {
-  InferredTypeClosure(TypeRules rules, Expression expression, DartType type)
-      : super._internal(rules, expression, type);
+  toErrorCode() => new HintCode(name, message);
 }
 
 class DynamicInvoke extends CoercionInfo {
-  DynamicInvoke(TypeRules rules, Expression expression)
-      : super(rules, expression);
-
-  DartType get convertedType => rules.provider.dynamicType;
-  String get message => '{0} requires dynamic invoke';
-  toErrorCode() => new HintCode(name, message);
-
   static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke';
 
+  DynamicInvoke(TypeSystem rules, Expression expression)
+      : super(rules, expression);
+  DartType get convertedType => DynamicTypeImpl.instance;
+  String get message => '{0} requires dynamic invoke';
+
+  @override
+  String get name => 'STRONG_MODE_DYNAMIC_INVOKE';
+
+  toErrorCode() => new HintCode(name, message);
+
   /// Whether this [node] is the target of a dynamic operation.
   static bool get(AstNode node) {
     var value = node.getProperty(_propertyName);
@@ -337,69 +244,105 @@
   }
 }
 
-abstract class StaticError extends StaticInfo {
-  final AstNode node;
-
-  StaticError(this.node);
-
-  String get message;
-
-  toErrorCode() => new CompileTimeErrorCode(name, message);
+// The identity coercion
+class Identity extends Coercion {
+  Identity(DartType fromType) : super(fromType, fromType);
 }
 
-class StaticTypeError extends StaticError {
-  final DartType baseType;
-  final DartType expectedType;
-  String reason = null;
+// Standard / unspecialized inferred type
+class InferredType extends InferredTypeBase {
+  InferredType(TypeSystem rules, Expression expression, DartType type)
+      : super._internal(rules, expression, type);
 
-  StaticTypeError(TypeRules rules, Expression expression, this.expectedType,
-      {this.reason})
-      : baseType = rules.getStaticType(expression),
-        super(expression);
+  @override
+  String get name => 'STRONG_MODE_INFERRED_TYPE';
 
-  @override List<Object> get arguments => [node, baseType, expectedType];
-  @override String get message =>
-      'Type check failed: {0} ({1}) is not of type {2}' +
-          ((reason == null) ? '' : ' because $reason');
-}
-
-class InvalidVariableDeclaration extends StaticError {
-  final DartType expectedType;
-
-  InvalidVariableDeclaration(
-      TypeRules rules, AstNode declaration, this.expectedType)
-      : super(declaration);
-
-  @override List<Object> get arguments => [expectedType];
-  @override String get message => 'Type check failed: null is not of type {0}';
-}
-
-class InvalidParameterDeclaration extends StaticError {
-  final DartType expectedType;
-
-  InvalidParameterDeclaration(
-      TypeRules rules, FormalParameter declaration, this.expectedType)
-      : super(declaration);
-
-  @override List<Object> get arguments => [node, expectedType];
-  @override String get message => 'Type check failed: {0} is not of type {1}';
-}
-
-class NonGroundTypeCheckInfo extends StaticInfo {
-  final DartType type;
-  final AstNode node;
-
-  NonGroundTypeCheckInfo(this.node, this.type) {
-    assert(node is IsExpression || node is AsExpression);
+  // Factory to create correct InferredType variant.
+  static InferredTypeBase create(
+      TypeSystem rules, Expression expression, DartType type) {
+    // Specialized inference:
+    if (expression is Literal) {
+      return new InferredTypeLiteral(rules, expression, type);
+    }
+    if (expression is InstanceCreationExpression) {
+      return new InferredTypeAllocation(rules, expression, type);
+    }
+    if (expression is FunctionExpression) {
+      return new InferredTypeClosure(rules, expression, type);
+    }
+    return new InferredType(rules, expression, type);
   }
+}
 
-  @override List<Object> get arguments => [type];
-  String get message =>
-      "Runtime check on non-ground type {0} may throw StrongModeError";
+// An inferred type for a non-literal allocation site.
+class InferredTypeAllocation extends InferredTypeBase {
+  InferredTypeAllocation(TypeSystem rules, Expression expression, DartType type)
+      : super._internal(rules, expression, type);
+
+  @override
+  String get name => 'STRONG_MODE_INFERRED_TYPE_ALLOCATION';
+}
+
+// An inferred type for the wrapped expression, which may need to be
+// reified into the term
+abstract class InferredTypeBase extends CoercionInfo {
+  final DartType _type;
+
+  InferredTypeBase._internal(
+      TypeSystem rules, Expression expression, this._type)
+      : super(rules, expression);
+
+  @override List get arguments => [node, type];
+  DartType get convertedType => type;
+  @override String get message => '{0} has inferred type {1}';
+  DartType get type => _type;
 
   toErrorCode() => new HintCode(name, message);
 }
 
+// An inferred type for a closure expression
+class InferredTypeClosure extends InferredTypeBase {
+  InferredTypeClosure(TypeSystem rules, Expression expression, DartType type)
+      : super._internal(rules, expression, type);
+
+  @override
+  String get name => 'STRONG_MODE_INFERRED_TYPE_CLOSURE';
+}
+
+// An inferred type for a literal expression.
+class InferredTypeLiteral extends InferredTypeBase {
+  InferredTypeLiteral(TypeSystem rules, Expression expression, DartType type)
+      : super._internal(rules, expression, type);
+
+  @override
+  String get name => 'STRONG_MODE_INFERRED_TYPE_LITERAL';
+}
+
+class InvalidFieldOverride extends InvalidOverride {
+  InvalidFieldOverride(AstNode node, ExecutableElement element,
+      InterfaceType base, DartType subType, DartType baseType)
+      : super(node, element, base, subType, baseType);
+
+  String get message => 'Field declaration {3}.{1} cannot be '
+      'overridden in {0}.';
+
+  @override
+  String get name => 'STRONG_MODE_INVALID_FIELD_OVERRIDE';
+}
+
+// Invalid override due to incompatible type.  I.e., the overridden signature
+// is not compatible with the original.
+class InvalidMethodOverride extends InvalidOverride {
+  InvalidMethodOverride(AstNode node, ExecutableElement element,
+      InterfaceType base, FunctionType subType, FunctionType baseType)
+      : super(node, element, base, subType, baseType);
+
+  String get message => _messageHelper('Invalid override');
+
+  @override
+  String get name => 'STRONG_MODE_INVALID_METHOD_OVERRIDE';
+}
+
 // Invalid override of an instance member of a class.
 abstract class InvalidOverride extends StaticError {
   /// Member declaration with the invalid override.
@@ -427,11 +370,11 @@
         fromMixin = node.parent is WithClause,
         super(node);
 
-  ClassElement get parent => element.enclosingElement;
-
   @override List<Object> get arguments =>
       [parent.name, element.name, subType, base, baseType];
 
+  ClassElement get parent => element.enclosingElement;
+
   String _messageHelper(String errorName) {
     var lcErrorName = errorName.toLowerCase();
     var intro = fromBaseClass
@@ -442,14 +385,17 @@
   }
 }
 
-// Invalid override due to incompatible type.  I.e., the overridden signature
-// is not compatible with the original.
-class InvalidMethodOverride extends InvalidOverride {
-  InvalidMethodOverride(AstNode node, ExecutableElement element,
-      InterfaceType base, FunctionType subType, FunctionType baseType)
-      : super(node, element, base, subType, baseType);
+class InvalidParameterDeclaration extends StaticError {
+  final DartType expectedType;
 
-  String get message => _messageHelper('Invalid override');
+  InvalidParameterDeclaration(
+      TypeSystem rules, FormalParameter declaration, this.expectedType)
+      : super(declaration);
+
+  @override List<Object> get arguments => [node, expectedType];
+  @override String get message => 'Type check failed: {0} is not of type {1}';
+  @override
+  String get name => 'STRONG_MODE_INVALID_PARAMETER_DECLARATION';
 }
 
 /// Dart constructors have one weird quirk, illustrated with this example:
@@ -486,4 +432,140 @@
 
   @override String get message => "super call must be last in an initializer "
       "list (see http://goo.gl/q1T4BB): {0}";
+
+  @override
+  String get name => 'STRONG_MODE_INVALID_SUPER_INVOCATION';
+}
+
+class InvalidVariableDeclaration extends StaticError {
+  final DartType expectedType;
+
+  InvalidVariableDeclaration(
+      TypeSystem rules, AstNode declaration, this.expectedType)
+      : super(declaration);
+
+  @override List<Object> get arguments => [expectedType];
+  @override String get message => 'Type check failed: null is not of type {0}';
+
+  @override
+  String get name => 'STRONG_MODE_INVALID_VARIABLE_DECLARATION';
+}
+
+class NonGroundTypeCheckInfo extends StaticInfo {
+  final DartType type;
+  final AstNode node;
+
+  NonGroundTypeCheckInfo(this.node, this.type) {
+    assert(node is IsExpression || node is AsExpression);
+  }
+
+  @override List<Object> get arguments => [type];
+  String get message =>
+      "Runtime check on non-ground type {0} may throw StrongModeError";
+
+  @override
+  String get name => 'STRONG_MODE_NON_GROUND_TYPE_CHECK_INFO';
+
+  toErrorCode() => new HintCode(name, message);
+}
+
+abstract class StaticError extends StaticInfo {
+  final AstNode node;
+
+  StaticError(this.node);
+
+  String get message;
+
+  toErrorCode() => new CompileTimeErrorCode(name, message);
+}
+
+// TODO(jmesserly): this could use some refactoring. These are essentially
+// like ErrorCodes in analyzer, but we're including some details in our message.
+// Analyzer instead has template strings, and replaces '{0}' with the first
+// argument.
+abstract class StaticInfo {
+  /// Strong-mode error code names.
+  ///
+  /// Used for error code configuration validation in `.analysis_options`.
+  static const List<String> names = const [
+    //
+    // Manually populated.
+    //
+    'STRONG_MODE_ASSIGNMENT_CAST',
+    'STRONG_MODE_DOWN_CAST_COMPOSITE',
+    'STRONG_MODE_DOWN_CAST_IMPLICIT',
+    'STRONG_MODE_DYNAMIC_CAST',
+    'STRONG_MODE_DYNAMIC_INVOKE',
+    'STRONG_MODE_INFERRED_TYPE',
+    'STRONG_MODE_INFERRED_TYPE_ALLOCATION',
+    'STRONG_MODE_INFERRED_TYPE_CLOSURE',
+    'STRONG_MODE_INFERRED_TYPE_LITERAL',
+    'STRONG_MODE_INVALID_FIELD_OVERRIDE',
+    'STRONG_MODE_INVALID_METHOD_OVERRIDE',
+    'STRONG_MODE_INVALID_PARAMETER_DECLARATION',
+    'STRONG_MODE_INVALID_SUPER_INVOCATION',
+    'STRONG_MODE_INVALID_VARIABLE_DECLARATION',
+    'STRONG_MODE_NON_GROUND_TYPE_CHECK_INFO',
+    'STRONG_MODE_STATIC_TYPE_ERROR',
+    'STRONG_MODE_UNINFERRED_CLOSURE',
+  ];
+
+  List<Object> get arguments => [node];
+
+  String get name;
+
+  /// AST Node this info is attached to.
+  AstNode get node;
+
+  AnalysisError toAnalysisError() {
+    int begin = node is AnnotatedNode
+        ? (node as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset
+        : node.offset;
+    int length = node.end - begin;
+    var source = (node.root as CompilationUnit).element.source;
+    return new AnalysisError(source, begin, length, toErrorCode(), arguments);
+  }
+
+  // TODO(jmesserly): review the usage of error codes. We probably want our own,
+  // as well as some DDC specific [ErrorType]s.
+  ErrorCode toErrorCode();
+}
+
+class StaticTypeError extends StaticError {
+  final DartType baseType;
+  final DartType expectedType;
+  String reason = null;
+
+  StaticTypeError(TypeSystem rules, Expression expression, this.expectedType,
+      {this.reason})
+      : baseType = expression.staticType ?? DynamicTypeImpl.instance,
+        super(expression);
+
+  @override List<Object> get arguments => [node, baseType, expectedType];
+  @override String get message =>
+      'Type check failed: {0} ({1}) is not of type {2}' +
+      ((reason == null) ? '' : ' because $reason');
+
+  @override
+  String get name => 'STRONG_MODE_STATIC_TYPE_ERROR';
+}
+
+//
+// Temporary "casts" of allocation sites - literals, constructor invocations,
+// and closures.  These should be handled by contextual inference.  In most
+// cases, inference will be sufficient, though in some it may unmask an actual
+// error: e.g.,
+//   List<int> l = [1, 2, 3]; // Inference succeeds
+//   List<String> l = [1, 2, 3]; // Inference reveals static type error
+// We're marking all as warnings for now.
+//
+// TODO(vsm,leafp): Remove this.
+class UninferredClosure extends DownCast {
+  UninferredClosure(TypeSystem rules, FunctionExpression expression, Cast cast)
+      : super._internal(rules, expression, cast);
+
+  @override
+  String get name => 'STRONG_MODE_UNINFERRED_CLOSURE';
+
+  toErrorCode() => new StaticTypeWarningCode(name, message);
 }
diff --git a/pkg/analyzer/lib/src/task/strong/rules.dart b/pkg/analyzer/lib/src/task/strong/rules.dart
deleted file mode 100644
index 3cd6db2..0000000
--- a/pkg/analyzer/lib/src/task/strong/rules.dart
+++ /dev/null
@@ -1,774 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// TODO(jmesserly): this was ported from package:dev_compiler, and needs to be
-// refactored to fit into analyzer.
-library analyzer.src.task.strong.rules;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-
-import 'info.dart';
-
-// TODO(jmesserly): this entire file needs to be removed in favor of TypeSystem.
-
-final _objectMap = new Expando('providerToObjectMap');
-Map<String, DartType> getObjectMemberMap(TypeProvider typeProvider) {
-  var map = _objectMap[typeProvider] as Map<String, DartType>;
-  if (map == null) {
-    map = <String, DartType>{};
-    _objectMap[typeProvider] = map;
-    var objectType = typeProvider.objectType;
-    var element = objectType.element;
-    // Only record methods (including getters) with no parameters.  As parameters are contravariant wrt
-    // type, using Object's version may be too strict.
-    // Add instance methods.
-    element.methods.where((method) => !method.isStatic).forEach((method) {
-      map[method.name] = method.type;
-    });
-    // Add getters.
-    element.accessors
-        .where((member) => !member.isStatic && member.isGetter)
-        .forEach((member) {
-      map[member.name] = member.type.returnType;
-    });
-  }
-  return map;
-}
-
-class TypeRules {
-  final TypeProvider provider;
-
-  /// Map of fields / properties / methods on Object.
-  final Map<String, DartType> objectMembers;
-
-  DownwardsInference inferrer;
-
-  TypeRules(TypeProvider provider)
-      : provider = provider,
-        objectMembers = getObjectMemberMap(provider) {
-    inferrer = new DownwardsInference(this);
-  }
-
-  /// Given a type t, if t is an interface type with a call method
-  /// defined, return the function type for the call method, otherwise
-  /// return null.
-  FunctionType getCallMethodType(DartType t) {
-    if (t is InterfaceType) {
-      ClassElement element = t.element;
-      InheritanceManager manager = new InheritanceManager(element.library);
-      FunctionType callType = manager.lookupMemberType(t, "call");
-      return callType;
-    }
-    return null;
-  }
-
-  /// Given an expression, return its type assuming it is
-  /// in the caller position of a call (that is, accounting
-  /// for the possibility of a call method).  Returns null
-  /// if expression is not statically callable.
-  FunctionType getTypeAsCaller(Expression applicand) {
-    var t = getStaticType(applicand);
-    if (t is InterfaceType) {
-      return getCallMethodType(t);
-    }
-    if (t is FunctionType) return t;
-    return null;
-  }
-
-  /// Gets the expected return type of the given function [body], either from
-  /// a normal return/yield, or from a yield*.
-  DartType getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) {
-    FunctionType functionType;
-    var parent = body.parent;
-    if (parent is Declaration) {
-      functionType = elementType(parent.element);
-    } else {
-      assert(parent is FunctionExpression);
-      functionType = getStaticType(parent);
-    }
-
-    var type = functionType.returnType;
-
-    InterfaceType expectedType = null;
-    if (body.isAsynchronous) {
-      if (body.isGenerator) {
-        // Stream<T> -> T
-        expectedType = provider.streamType;
-      } else {
-        // Future<T> -> T
-        // TODO(vsm): Revisit with issue #228.
-        expectedType = provider.futureType;
-      }
-    } else {
-      if (body.isGenerator) {
-        // Iterable<T> -> T
-        expectedType = provider.iterableType;
-      } else {
-        // T -> T
-        return type;
-      }
-    }
-    if (yieldStar) {
-      if (type.isDynamic) {
-        // Ensure it's at least a Stream / Iterable.
-        return expectedType.substitute4([provider.dynamicType]);
-      } else {
-        // Analyzer will provide a separate error if expected type
-        // is not compatible with type.
-        return type;
-      }
-    }
-    if (type.isDynamic) {
-      return type;
-    } else if (type is InterfaceType && type.element == expectedType.element) {
-      return type.typeArguments[0];
-    } else {
-      // Malformed type - fallback on analyzer error.
-      return null;
-    }
-  }
-
-  DartType getStaticType(Expression expr) {
-    return expr.staticType ?? provider.dynamicType;
-  }
-
-  bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
-    if (t.isDynamic && dynamicIsBottom) return true;
-    // TODO(vsm): We need direct support for non-nullability in DartType.
-    // This should check on "true/nonnullable" Bottom
-    if (t.isBottom) return true;
-    return false;
-  }
-
-  bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
-    if (t.isDynamic && !dynamicIsBottom) return true;
-    if (t.isObject) return true;
-    return false;
-  }
-
-  bool _anyParameterType(FunctionType ft, bool predicate(DartType t)) {
-    return ft.normalParameterTypes.any(predicate) ||
-        ft.optionalParameterTypes.any(predicate) ||
-        ft.namedParameterTypes.values.any(predicate);
-  }
-
-  // TODO(leafp): Revisit this.
-  bool isGroundType(DartType t) {
-    if (t is TypeParameterType) return false;
-    if (_isTop(t)) return true;
-
-    if (t is FunctionType) {
-      if (!_isTop(t.returnType) ||
-          _anyParameterType(t, (pt) => !_isBottom(pt, dynamicIsBottom: true))) {
-        return false;
-      } else {
-        return true;
-      }
-    }
-
-    if (t is InterfaceType) {
-      var typeArguments = t.typeArguments;
-      for (var typeArgument in typeArguments) {
-        if (!_isTop(typeArgument)) return false;
-      }
-      return true;
-    }
-
-    // We should not see any other type aside from malformed code.
-    return false;
-  }
-
-  /// Check that f1 is a subtype of f2. [ignoreReturn] is used in the DDC
-  /// checker to determine whether f1 would be a subtype of f2 if the return
-  /// type of f1 is set to match f2's return type.
-  // [fuzzyArrows] indicates whether or not the f1 and f2 should be
-  // treated as fuzzy arrow types (and hence dynamic parameters to f2 treated as
-  // bottom).
-  bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2,
-      {bool fuzzyArrows: true, bool ignoreReturn: false}) {
-    final r1s = f1.normalParameterTypes;
-    final o1s = f1.optionalParameterTypes;
-    final n1s = f1.namedParameterTypes;
-    final r2s = f2.normalParameterTypes;
-    final o2s = f2.optionalParameterTypes;
-    final n2s = f2.namedParameterTypes;
-    final ret1 = ignoreReturn ? f2.returnType : f1.returnType;
-    final ret2 = f2.returnType;
-
-    // A -> B <: C -> D if C <: A and
-    // either D is void or B <: D
-    if (!ret2.isVoid && !isSubTypeOf(ret1, ret2)) return false;
-
-    // Reject if one has named and the other has optional
-    if (n1s.length > 0 && o2s.length > 0) return false;
-    if (n2s.length > 0 && o1s.length > 0) return false;
-
-    // f2 has named parameters
-    if (n2s.length > 0) {
-      // Check that every named parameter in f2 has a match in f1
-      for (String k2 in n2s.keys) {
-        if (!n1s.containsKey(k2)) return false;
-        if (!isSubTypeOf(n2s[k2], n1s[k2],
-            dynamicIsBottom: fuzzyArrows)) return false;
-      }
-    }
-    // If we get here, we either have no named parameters,
-    // or else the named parameters match and we have no optional
-    // parameters
-
-    // If f1 has more required parameters, reject
-    if (r1s.length > r2s.length) return false;
-
-    // If f2 has more required + optional parameters, reject
-    if (r2s.length + o2s.length > r1s.length + o1s.length) return false;
-
-    // The parameter lists must look like the following at this point
-    // where rrr is a region of required, and ooo is a region of optionals.
-    // f1: rrr ooo ooo ooo
-    // f2: rrr rrr ooo
-    int rr = r1s.length; // required in both
-    int or = r2s.length - r1s.length; // optional in f1, required in f2
-    int oo = o2s.length; // optional in both
-
-    for (int i = 0; i < rr; ++i) {
-      if (!isSubTypeOf(r2s[i], r1s[i],
-          dynamicIsBottom: fuzzyArrows)) return false;
-    }
-    for (int i = 0, j = rr; i < or; ++i, ++j) {
-      if (!isSubTypeOf(r2s[j], o1s[i],
-          dynamicIsBottom: fuzzyArrows)) return false;
-    }
-    for (int i = or, j = 0; i < oo; ++i, ++j) {
-      if (!isSubTypeOf(o2s[j], o1s[i],
-          dynamicIsBottom: fuzzyArrows)) return false;
-    }
-    return true;
-  }
-
-  bool _isInterfaceSubTypeOf(InterfaceType i1, InterfaceType i2) {
-    if (i1 == i2) return true;
-
-    if (i1.element == i2.element) {
-      List<DartType> tArgs1 = i1.typeArguments;
-      List<DartType> tArgs2 = i2.typeArguments;
-
-      // TODO(leafp): Verify that this is always true
-      // Do raw types get filled in?
-      assert(tArgs1.length == tArgs2.length);
-
-      for (int i = 0; i < tArgs1.length; i++) {
-        DartType t1 = tArgs1[i];
-        DartType t2 = tArgs2[i];
-        if (!isSubTypeOf(t1, t2)) return false;
-      }
-      return true;
-    }
-
-    if (i2.isDartCoreFunction) {
-      if (i1.element.getMethod("call") != null) return true;
-    }
-
-    if (i1 == provider.objectType) return false;
-
-    if (_isInterfaceSubTypeOf(i1.superclass, i2)) return true;
-
-    for (final parent in i1.interfaces) {
-      if (_isInterfaceSubTypeOf(parent, i2)) return true;
-    }
-
-    for (final parent in i1.mixins) {
-      if (_isInterfaceSubTypeOf(parent, i2)) return true;
-    }
-
-    return false;
-  }
-
-  bool isSubTypeOf(DartType t1, DartType t2, {bool dynamicIsBottom: false}) {
-    if (t1 == t2) return true;
-
-    // Trivially true.
-    if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
-        _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
-      return true;
-    }
-
-    // Trivially false.
-    if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
-        _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
-      return false;
-    }
-
-    // The null type is a subtype of any nullable type, which is all Dart types.
-    // TODO(vsm): Note, t1.isBottom still allows for null confusingly.
-    // _isBottom(t1) does not necessarily imply t1.isBottom if there are
-    // nonnullable types in the system.
-    if (t1.isBottom) {
-      return true;
-    }
-
-    // S <: T where S is a type variable
-    //  T is not dynamic or object (handled above)
-    //  S != T (handled above)
-    //  So only true if bound of S is S' and
-    //  S' <: T
-    if (t1 is TypeParameterType) {
-      DartType bound = t1.element.bound;
-      if (bound == null) return false;
-      return isSubTypeOf(bound, t2);
-    }
-
-    if (t2 is TypeParameterType) {
-      return false;
-    }
-
-    if (t2.isDartCoreFunction) {
-      if (t1 is FunctionType) return true;
-      if (t1.element is ClassElement) {
-        if ((t1.element as ClassElement).getMethod("call") != null) return true;
-      }
-    }
-
-    // "Traditional" name-based subtype check.
-    if (t1 is InterfaceType && t2 is InterfaceType) {
-      return _isInterfaceSubTypeOf(t1, t2);
-    }
-
-    if (t1 is! FunctionType && t2 is! FunctionType) return false;
-
-    if (t1 is InterfaceType && t2 is FunctionType) {
-      var callType = getCallMethodType(t1);
-      if (callType == null) return false;
-      return isFunctionSubTypeOf(callType, t2);
-    }
-
-    if (t1 is FunctionType && t2 is InterfaceType) {
-      return false;
-    }
-
-    // Functions
-    // Note: it appears under the hood all Dart functions map to a class /
-    // hidden type that:
-    //  (a) subtypes Object (an internal _FunctionImpl in the VM)
-    //  (b) implements Function
-    //  (c) provides standard Object members (hashCode, toString)
-    //  (d) contains private members (corresponding to _FunctionImpl?)
-    //  (e) provides a call method to handle the actual function invocation
-    //
-    // The standard Dart subtyping rules are structural in nature.  I.e.,
-    // bivariant on arguments and return type.
-    //
-    // The below tries for a more traditional subtyping rule:
-    // - covariant on return type
-    // - contravariant on parameters
-    // - 'sensible' (?) rules on optional and/or named params
-    // but doesn't properly mix with class subtyping.  I suspect Java 8 lambdas
-    // essentially map to dynamic (and rely on invokedynamic) due to similar
-    // issues.
-    return isFunctionSubTypeOf(t1 as FunctionType, t2 as FunctionType);
-  }
-
-  bool isAssignable(DartType t1, DartType t2) {
-    return isSubTypeOf(t1, t2);
-  }
-
-  // Produce a coercion which coerces something of type fromT
-  // to something of type toT.
-  // Returns the error coercion if the types cannot be coerced
-  // according to our current criteria.
-  Coercion _coerceTo(DartType fromT, DartType toT) {
-    // We can use anything as void
-    if (toT.isVoid) return Coercion.identity(toT);
-
-    // fromT <: toT, no coercion needed
-    if (isSubTypeOf(fromT, toT)) return Coercion.identity(toT);
-
-    // TODO(vsm): We can get rid of the second clause if we disallow
-    // all sideways casts - see TODO below.
-    // -------
-    // Note: a function type is never assignable to a class per the Dart
-    // spec - even if it has a compatible call method.  We disallow as
-    // well for consistency.
-    if ((fromT is FunctionType && getCallMethodType(toT) != null) ||
-        (toT is FunctionType && getCallMethodType(fromT) != null)) {
-      return Coercion.error();
-    }
-
-    // Downcast if toT <: fromT
-    if (isSubTypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
-
-    // TODO(vsm): Once we have generic methods, we should delete this
-    // workaround.  These sideways casts are always ones we warn about
-    // - i.e., we think they are likely to fail at runtime.
-    // -------
-    // Downcast if toT <===> fromT
-    // The intention here is to allow casts that are sideways in the restricted
-    // type system, but allowed in the regular dart type system, since these
-    // are likely to succeed.  The canonical example is List<dynamic> and
-    // Iterable<T> for some concrete T (e.g. Object).  These are unrelated
-    // in the restricted system, but List<dynamic> <: Iterable<T> in dart.
-    if (fromT.isAssignableTo(toT)) {
-      return Coercion.cast(fromT, toT);
-    }
-
-    return Coercion.error();
-  }
-
-  StaticInfo checkAssignment(Expression expr, DartType toT) {
-    final fromT = getStaticType(expr);
-    final Coercion c = _coerceTo(fromT, toT);
-    if (c is Identity) return null;
-    if (c is CoercionError) return new StaticTypeError(this, expr, toT);
-    var reason = null;
-
-    var errors = <String>[];
-    var ok = inferrer.inferExpression(expr, toT, errors);
-    if (ok) return InferredType.create(this, expr, toT);
-    reason = (errors.isNotEmpty) ? errors.first : null;
-
-    if (c is Cast) return DownCast.create(this, expr, c, reason: reason);
-    assert(false);
-    return null;
-  }
-
-  DartType elementType(Element e) {
-    if (e == null) {
-      // Malformed code - just return dynamic.
-      return provider.dynamicType;
-    }
-    return (e as dynamic).type;
-  }
-
-  bool _isLibraryPrefix(Expression node) =>
-      node is SimpleIdentifier && node.staticElement is PrefixElement;
-
-  /// Returns `true` if the target expression is dynamic.
-  bool isDynamicTarget(Expression node) {
-    if (node == null) return false;
-
-    if (_isLibraryPrefix(node)) return false;
-
-    // Null type happens when we have unknown identifiers, like a dart: import
-    // that doesn't resolve.
-    var type = node.staticType;
-    return type == null || type.isDynamic;
-  }
-
-  /// Returns `true` if the expression is a dynamic function call or method
-  /// invocation.
-  bool isDynamicCall(Expression call) {
-    var ft = getTypeAsCaller(call);
-    // TODO(leafp): This will currently return true if t is Function
-    // This is probably the most correct thing to do for now, since
-    // this code is also used by the back end.  Maybe revisit at some
-    // point?
-    if (ft == null) return true;
-    // Dynamic as the parameter type is treated as bottom.  A function with
-    // a dynamic parameter type requires a dynamic call in general.
-    // However, as an optimization, if we have an original definition, we know
-    // dynamic is reified as Object - in this case a regular call is fine.
-    if (call is SimpleIdentifier) {
-      var element = call.staticElement;
-      if (element is FunctionElement || element is MethodElement) {
-        // An original declaration.
-        return false;
-      }
-    }
-
-    return _anyParameterType(ft, (pt) => pt.isDynamic);
-  }
-}
-
-class DownwardsInference {
-  final TypeRules rules;
-
-  DownwardsInference(this.rules);
-
-  /// Called for each list literal which gets inferred
-  void annotateListLiteral(ListLiteral e, List<DartType> targs) {}
-
-  /// Called for each map literal which gets inferred
-  void annotateMapLiteral(MapLiteral e, List<DartType> targs) {}
-
-  /// Called for each new/const which gets inferred
-  void annotateInstanceCreationExpression(
-      InstanceCreationExpression e, List<DartType> targs) {}
-
-  /// Called for cast from dynamic required for inference to succeed
-  void annotateCastFromDynamic(Expression e, DartType t) {}
-
-  /// Called for each function expression return type inferred
-  void annotateFunctionExpression(FunctionExpression e, DartType returnType) {}
-
-  /// Downward inference
-  bool inferExpression(Expression e, DartType t, List<String> errors) {
-    // Don't cast top level expressions, only sub-expressions
-    return _inferExpression(e, t, errors, cast: false);
-  }
-
-  /// Downward inference
-  bool _inferExpression(Expression e, DartType t, List<String> errors,
-      {cast: true}) {
-    if (e is ConditionalExpression) {
-      return _inferConditionalExpression(e, t, errors);
-    }
-    if (e is ParenthesizedExpression) {
-      return _inferParenthesizedExpression(e, t, errors);
-    }
-    if (rules.isSubTypeOf(rules.getStaticType(e), t)) return true;
-    if (cast && rules.getStaticType(e).isDynamic) {
-      annotateCastFromDynamic(e, t);
-      return true;
-    }
-    if (e is FunctionExpression) return _inferFunctionExpression(e, t, errors);
-    if (e is ListLiteral) return _inferListLiteral(e, t, errors);
-    if (e is MapLiteral) return _inferMapLiteral(e, t, errors);
-    if (e is NamedExpression) return _inferNamedExpression(e, t, errors);
-    if (e is InstanceCreationExpression) {
-      return _inferInstanceCreationExpression(e, t, errors);
-    }
-    errors.add("$e cannot be typed as $t");
-    return false;
-  }
-
-  /// If t1 = I<dynamic, ..., dynamic>, then look for a supertype
-  /// of t1 of the form K<S0, ..., Sm> where t2 = K<S0', ..., Sm'>
-  /// If the supertype exists, use the constraints S0 <: S0', ... Sm <: Sm'
-  /// to derive a concrete instantation for I of the form <T0, ..., Tn>,
-  /// such that I<T0, .., Tn> <: t2
-  List<DartType> _matchTypes(InterfaceType t1, InterfaceType t2) {
-    if (t1 == t2) return t2.typeArguments;
-    var tArgs1 = t1.typeArguments;
-    var tArgs2 = t2.typeArguments;
-    // If t1 isn't a raw type, bail out
-    if (tArgs1 != null && tArgs1.any((t) => !t.isDynamic)) return null;
-
-    // This is our inferred type argument list.  We start at all dynamic,
-    // and fill in with inferred types when we reach a match.
-    var actuals =
-        new List<DartType>.filled(tArgs1.length, rules.provider.dynamicType);
-
-    // When we find the supertype of t1 with the same
-    // classname as t2 (see below), we have the following:
-    // If t1 is an instantiation of a class T1<X0, ..., Xn>
-    // and t2 is an instantiation of a class T2<Y0, ...., Ym>
-    // of the form t2 = T2<S0, ..., Sm>
-    // then we want to choose instantiations for the Xi
-    // T0, ..., Tn such that T1<T0, ..., Tn> <: t2 .
-    // To find this, we simply instantate T1 with
-    // X0, ..., Xn, and then find its superclass
-    // T2<T0', ..., Tn'>.  We then solve the constraint
-    // set T0' <: S0, ..., Tn' <: Sn for the Xi.
-    // Currently, we only handle constraints where
-    // the Ti' is one of the Xi'.  If there are multiple
-    // constraints on some Xi, we choose the lower of the
-    // two (if it exists).
-    bool permute(List<DartType> permutedArgs) {
-      if (permutedArgs == null) return false;
-      var ps = t1.typeParameters;
-      var ts = ps.map((p) => p.type).toList();
-      for (int i = 0; i < permutedArgs.length; i++) {
-        var tVar = permutedArgs[i];
-        var tActual = tArgs2[i];
-        var index = ts.indexOf(tVar);
-        if (index >= 0 && rules.isSubTypeOf(tActual, actuals[index])) {
-          actuals[index] = tActual;
-        }
-      }
-      return actuals.any((x) => !x.isDynamic);
-    }
-
-    // Look for the first supertype of t1 with the same class name as t2.
-    bool match(InterfaceType t1) {
-      if (t1.element == t2.element) {
-        return permute(t1.typeArguments);
-      }
-
-      if (t1 == rules.provider.objectType) return false;
-
-      if (match(t1.superclass)) return true;
-
-      for (final parent in t1.interfaces) {
-        if (match(parent)) return true;
-      }
-
-      for (final parent in t1.mixins) {
-        if (match(parent)) return true;
-      }
-      return false;
-    }
-
-    // We have that t1 = T1<dynamic, ..., dynamic>.
-    // To match t1 against t2, we use the uninstantiated version
-    // of t1, essentially treating it as an instantiation with
-    // fresh variables, and solve for the variables.
-    // t1.element.type will be of the form T1<X0, ..., Xn>
-    if (!match(t1.element.type)) return null;
-    var newT1 = t1.element.type.substitute4(actuals);
-    // If we found a solution, return it.
-    if (rules.isSubTypeOf(newT1, t2)) return actuals;
-    return null;
-  }
-
-  /// These assume that e is not already a subtype of t
-
-  bool _inferConditionalExpression(
-      ConditionalExpression e, DartType t, errors) {
-    return _inferExpression(e.thenExpression, t, errors) &&
-        _inferExpression(e.elseExpression, t, errors);
-  }
-
-  bool _inferParenthesizedExpression(
-      ParenthesizedExpression e, DartType t, errors) {
-    return _inferExpression(e.expression, t, errors);
-  }
-
-  bool _inferInstanceCreationExpression(
-      InstanceCreationExpression e, DartType t, errors) {
-    var arguments = e.argumentList.arguments;
-    var rawType = rules.getStaticType(e);
-    // rawType is the instantiated type of the instance
-    if (rawType is! InterfaceType) return false;
-    var type = (rawType as InterfaceType);
-    if (type.typeParameters == null ||
-        type.typeParameters.length == 0) return false;
-    if (e.constructorName.type == null) return false;
-    // classTypeName is the type name of the class being instantiated
-    var classTypeName = e.constructorName.type;
-    // Check that we were not passed any type arguments
-    if (classTypeName.typeArguments != null) return false;
-    // Infer type arguments
-    if (t is! InterfaceType) return false;
-    var targs = _matchTypes(type, t);
-    if (targs == null) return false;
-    if (e.staticElement == null) return false;
-    var constructorElement = e.staticElement;
-    // From the constructor element get:
-    //  the instantiated type of the constructor, then
-    //     the uninstantiated element for the constructor, then
-    //        the uninstantiated type for the constructor
-    var rawConstructorElement =
-        constructorElement.type.element as ConstructorElement;
-    var baseType = rawConstructorElement.type;
-    if (baseType == null) return false;
-    // From the interface type (instantiated), get:
-    //  the uninstantiated element, then
-    //    the uninstantiated type, then
-    //      the type arguments (aka the type parameters)
-    var tparams = type.element.type.typeArguments;
-    // Take the uninstantiated constructor type, and replace the type
-    // parameters with the inferred arguments.
-    var fType = baseType.substitute2(targs, tparams);
-    {
-      var rTypes = fType.normalParameterTypes;
-      var oTypes = fType.optionalParameterTypes;
-      var pTypes = new List.from(rTypes)..addAll(oTypes);
-      var pArgs = arguments.where((x) => x is! NamedExpression);
-      var pi = 0;
-      for (var arg in pArgs) {
-        if (pi >= pTypes.length) return false;
-        var argType = pTypes[pi];
-        if (!_inferExpression(arg, argType, errors)) return false;
-        pi++;
-      }
-      var nTypes = fType.namedParameterTypes;
-      for (var arg0 in arguments) {
-        if (arg0 is! NamedExpression) continue;
-        var arg = arg0 as NamedExpression;
-        SimpleIdentifier nameNode = arg.name.label;
-        String name = nameNode.name;
-        var argType = nTypes[name];
-        if (argType == null) return false;
-        if (!_inferExpression(arg, argType, errors)) return false;
-      }
-    }
-    annotateInstanceCreationExpression(e, targs);
-    return true;
-  }
-
-  bool _inferNamedExpression(NamedExpression e, DartType t, errors) {
-    return _inferExpression(e.expression, t, errors);
-  }
-
-  bool _inferFunctionExpression(FunctionExpression e, DartType t, errors) {
-    if (t is! FunctionType) return false;
-    var fType = t as FunctionType;
-    var eType = e.staticType as FunctionType;
-    if (eType is! FunctionType) return false;
-
-    // We have a function literal, so we can treat the arrow type
-    // as non-fuzzy.  Since we're not improving on parameter types
-    // currently, if this check fails then we cannot succeed, so
-    // bail out.  Otherwise, we never need to check the parameter types
-    // again.
-    if (!rules.isFunctionSubTypeOf(eType, fType,
-        fuzzyArrows: false, ignoreReturn: true)) return false;
-
-    // This only entered inference because of fuzzy typing.
-    // The function type is already specific enough, we can just
-    // succeed and treat it as a successful inference
-    if (rules.isSubTypeOf(eType.returnType, fType.returnType)) return true;
-
-    // Fuzzy typing again, handle the void case (not caught by the previous)
-    if (fType.returnType.isVoid) return true;
-
-    if (e.body is! ExpressionFunctionBody) return false;
-    var body = (e.body as ExpressionFunctionBody).expression;
-    if (!_inferExpression(body, fType.returnType, errors)) return false;
-
-    // TODO(leafp): Try narrowing the argument types if possible
-    // to get better code in the function body.  This requires checking
-    // that the body is well-typed at the more specific type.
-
-    // At this point, we know that the parameter types are in the appropriate subtype
-    // relation, and we have checked that we can type the body at the appropriate return
-    // type, so we can are done.
-    annotateFunctionExpression(e, fType.returnType);
-    return true;
-  }
-
-  bool _inferListLiteral(ListLiteral e, DartType t, errors) {
-    var dyn = rules.provider.dynamicType;
-    var listT = rules.provider.listType.substitute4([dyn]);
-    // List <: t (using dart rules) must be true
-    if (!listT.isSubtypeOf(t)) return false;
-    // The list literal must have no type arguments
-    if (e.typeArguments != null) return false;
-    if (t is! InterfaceType) return false;
-    var targs = _matchTypes(listT, t);
-    if (targs == null) return false;
-    assert(targs.length == 1);
-    var etype = targs[0];
-    assert(!etype.isDynamic);
-    var elements = e.elements;
-    var b = elements.every((e) => _inferExpression(e, etype, errors));
-    if (b) annotateListLiteral(e, targs);
-    return b;
-  }
-
-  bool _inferMapLiteral(MapLiteral e, DartType t, errors) {
-    var dyn = rules.provider.dynamicType;
-    var mapT = rules.provider.mapType.substitute4([dyn, dyn]);
-    // Map <: t (using dart rules) must be true
-    if (!mapT.isSubtypeOf(t)) return false;
-    // The map literal must have no type arguments
-    if (e.typeArguments != null) return false;
-    if (t is! InterfaceType) return false;
-    var targs = _matchTypes(mapT, t);
-    if (targs == null) return false;
-    assert(targs.length == 2);
-    var kType = targs[0];
-    var vType = targs[1];
-    assert(!(kType.isDynamic && vType.isDynamic));
-    var entries = e.entries;
-    bool inferEntry(MapLiteralEntry entry) {
-      return _inferExpression(entry.key, kType, errors) &&
-          _inferExpression(entry.value, vType, errors);
-    }
-    var b = entries.every(inferEntry);
-    if (b) annotateMapLiteral(e, targs);
-    return b;
-  }
-}
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index ea3559d..46b84e0 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -6,9 +6,14 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/resolver.dart'
+    show TypeProvider, InheritanceManager;
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
@@ -25,11 +30,11 @@
       //
       // Update the type of the setter to reflect the new parameter type.
       //
+      // TODO(jmesserly): why is this necessary? The function type should always
+      // delegate to the orginal element.
       FunctionType functionType = element.type;
       if (functionType is FunctionTypeImpl) {
-        element.type =
-            new FunctionTypeImpl(element, functionType.prunedTypedefs)
-              ..typeArguments = functionType.typeArguments;
+        element.type = new FunctionTypeImpl(element);
       } else {
         assert(false);
       }
@@ -51,11 +56,12 @@
     // Update the return type of the element, which is stored in two places:
     // directly in the element and indirectly in the type of the element.
     //
+    // TODO(jmesserly): why is this necessary? The function type should always
+    // delegate to the orginal element.
     element.returnType = type;
     FunctionType functionType = element.type;
     if (functionType is FunctionTypeImpl) {
-      element.type = new FunctionTypeImpl(element, functionType.prunedTypedefs)
-        ..typeArguments = functionType.typeArguments;
+      element.type = new FunctionTypeImpl(element);
     } else {
       assert(false);
     }
@@ -134,6 +140,14 @@
   }
 
   /**
+   * Return `true` if the list of [elements] contains only methods.
+   */
+  bool _allSameElementKind(
+      ExecutableElement element, List<ExecutableElement> elements) {
+    return elements.every((e) => e.kind == element.kind);
+  }
+
+  /**
    * Compute the best type for the [parameter] at the given [index] that must be
    * compatible with the types of the corresponding parameters of the given
    * [overriddenMethods].
@@ -210,7 +224,7 @@
       matchingParameter = methodParameters.lastWhere(
           (ParameterElement methodParameter) =>
               methodParameter.parameterKind == ParameterKind.NAMED &&
-                  methodParameter.name == parameter.name,
+              methodParameter.name == parameter.name,
           orElse: () => null);
     } else {
       //
@@ -275,51 +289,10 @@
     }
   }
 
-  /**
-   * If the given [fieldElement] represents a non-synthetic instance field for
-   * which no type was provided, infer the type of the field.
-   */
-  void _inferField(FieldElement fieldElement) {
-    if (!fieldElement.isSynthetic &&
-        !fieldElement.isStatic &&
-        fieldElement.hasImplicitType) {
-      //
-      // First look for overridden getters with the same name as the field.
-      //
-      List<ExecutableElement> overriddenGetters = inheritanceManager
-          .lookupOverrides(fieldElement.enclosingElement, fieldElement.name);
-      DartType newType = null;
-      if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) {
-        newType = _computeReturnType(overriddenGetters);
-        List<ExecutableElement> overriddenSetters = inheritanceManager
-            .lookupOverrides(
-                fieldElement.enclosingElement, fieldElement.name + '=');
-        if (!_isCompatible(newType, overriddenSetters)) {
-          newType = null;
-        }
-      }
-      //
-      // If there is no overridden getter or if the overridden getter's type is
-      // dynamic, then we can infer the type from the initialization expression
-      // without breaking subtype rules. We could potentially infer a consistent
-      // return type even if the overridden getter's type was not dynamic, but
-      // choose not to for simplicity. The field is required to be final to
-      // prevent choosing a type that is inconsistent with assignments we cannot
-      // analyze.
-      //
-      if (newType == null || newType.isDynamic) {
-        if (fieldElement.initializer != null &&
-            (fieldElement.isFinal || overriddenGetters.isEmpty)) {
-          newType = fieldElement.initializer.returnType;
-        }
-      }
-      if (newType == null || newType.isBottom) {
-        newType = typeProvider.dynamicType;
-      }
-      (fieldElement as FieldElementImpl).type = newType;
-      setReturnType(fieldElement.getter, newType);
-      if (!fieldElement.isFinal && !fieldElement.isConst) {
-        setParameterType(fieldElement.setter, newType);
+  void _inferConstructorFieldFormals(ConstructorElement element) {
+    for (ParameterElement p in element.parameters) {
+      if (p is FieldFormalParameterElement) {
+        _inferFieldFormalParameter(p);
       }
     }
   }
@@ -374,29 +347,58 @@
   }
 
   /**
-   * If the given [element] is a non-synthetic getter or setter, update its
-   * synthetic variable's type to match the getter's return type, or if no
-   * corresponding getter exists, use the setter's parameter type.
-   *
-   * In general, the type of the synthetic variable should not be used, because
-   * getters and setters are independent methods. But this logic matches what
-   * `TypeResolverVisitor.visitMethodDeclaration` would fill in there.
+   * If the given [fieldElement] represents a non-synthetic instance field for
+   * which no type was provided, infer the type of the field.
    */
-  void _updateSyntheticVariableType(PropertyAccessorElement element) {
-    assert(!element.isSynthetic);
-    PropertyAccessorElement getter = element;
-    if (element.isSetter) {
-      // See if we can find any getter.
-      getter = element.correspondingGetter;
+  void _inferField(FieldElement fieldElement) {
+    if (!fieldElement.isSynthetic &&
+        !fieldElement.isStatic &&
+        fieldElement.hasImplicitType) {
+      //
+      // First look for overridden getters with the same name as the field.
+      //
+      List<ExecutableElement> overriddenGetters = inheritanceManager
+          .lookupOverrides(fieldElement.enclosingElement, fieldElement.name);
+      DartType newType = null;
+      if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) {
+        newType = _computeReturnType(overriddenGetters);
+        List<ExecutableElement> overriddenSetters =
+            inheritanceManager.lookupOverrides(
+                fieldElement.enclosingElement, fieldElement.name + '=');
+        if (!_isCompatible(newType, overriddenSetters)) {
+          newType = null;
+        }
+      }
+      //
+      // If there is no overridden getter or if the overridden getter's type is
+      // dynamic, then we can infer the type from the initialization expression
+      // without breaking subtype rules. We could potentially infer a consistent
+      // return type even if the overridden getter's type was not dynamic, but
+      // choose not to for simplicity. The field is required to be final to
+      // prevent choosing a type that is inconsistent with assignments we cannot
+      // analyze.
+      //
+      if (newType == null || newType.isDynamic) {
+        if (fieldElement.initializer != null &&
+            (fieldElement.isFinal || overriddenGetters.isEmpty)) {
+          newType = fieldElement.initializer.returnType;
+        }
+      }
+      if (newType == null || newType.isBottom) {
+        newType = typeProvider.dynamicType;
+      }
+      (fieldElement as FieldElementImpl).type = newType;
+      setReturnType(fieldElement.getter, newType);
+      if (!fieldElement.isFinal && !fieldElement.isConst) {
+        setParameterType(fieldElement.setter, newType);
+      }
     }
-    DartType newType;
-    if (getter != null) {
-      newType = getter.returnType;
-    } else if (element.isSetter && element.parameters.isNotEmpty) {
-      newType = element.parameters[0].type;
-    }
-    if (newType != null) {
-      (element.variable as VariableElementImpl).type = newType;
+  }
+
+  void _inferFieldFormalParameter(FieldFormalParameterElement element) {
+    FieldElement field = element.field;
+    if (field != null && element.hasImplicitType) {
+      (element as FieldFormalParameterElementImpl).type = field.type;
     }
   }
 
@@ -440,25 +442,29 @@
   }
 
   /**
-   * Return `true` if the list of [elements] contains only methods.
+   * If the given [element] is a non-synthetic getter or setter, update its
+   * synthetic variable's type to match the getter's return type, or if no
+   * corresponding getter exists, use the setter's parameter type.
+   *
+   * In general, the type of the synthetic variable should not be used, because
+   * getters and setters are independent methods. But this logic matches what
+   * `TypeResolverVisitor.visitMethodDeclaration` would fill in there.
    */
-  bool _allSameElementKind(
-      ExecutableElement element, List<ExecutableElement> elements) {
-    return elements.every((e) => e.kind == element.kind);
-  }
-
-  void _inferConstructorFieldFormals(ConstructorElement element) {
-    for (ParameterElement p in element.parameters) {
-      if (p is FieldFormalParameterElement) {
-        _inferFieldFormalParameter(p);
-      }
+  void _updateSyntheticVariableType(PropertyAccessorElement element) {
+    assert(!element.isSynthetic);
+    PropertyAccessorElement getter = element;
+    if (element.isSetter) {
+      // See if we can find any getter.
+      getter = element.correspondingGetter;
     }
-  }
-
-  void _inferFieldFormalParameter(FieldFormalParameterElement element) {
-    FieldElement field = element.field;
-    if (field != null && element.hasImplicitType) {
-      (element as FieldFormalParameterElementImpl).type = field.type;
+    DartType newType;
+    if (getter != null) {
+      newType = getter.returnType;
+    } else if (element.isSetter && element.parameters.isNotEmpty) {
+      newType = element.parameters[0].type;
+    }
+    if (newType != null) {
+      (element.variable as VariableElementImpl).type = newType;
     }
   }
 }
diff --git a/pkg/analyzer/lib/src/util/absolute_path.dart b/pkg/analyzer/lib/src/util/absolute_path.dart
new file mode 100644
index 0000000..28f5732
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/absolute_path.dart
@@ -0,0 +1,170 @@
+// 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.util.absolute_path;
+
+/// The class for manipulating absolute, normalized paths.
+class AbsolutePathContext {
+  static const int _COLON = 0x3A;
+  static const int _LOWER_A = 0x61;
+  static const int _LOWER_Z = 0x7A;
+  static const int _UPPER_A = 0x41;
+  static const int _UPPER_Z = 0x5A;
+
+  final bool _isWindows;
+  String separator;
+  int _separatorChar;
+  String _singlePeriodComponent;
+  String _doublePeriodComponent;
+  String _singlePeriodEnding;
+  String _doublePeriodEnding;
+
+  AbsolutePathContext(this._isWindows) {
+    separator = _isWindows ? r'\' : '/';
+    _separatorChar = separator.codeUnitAt(0);
+    _singlePeriodComponent = separator + '.' + separator;
+    _doublePeriodComponent = separator + '..' + separator;
+    _singlePeriodEnding = separator + '.';
+    _doublePeriodEnding = separator + '..';
+  }
+
+  /// Append the given relative [suffix] to the given absolute [parent].
+  ///
+  ///     context.append('/path/to', 'foo'); // -> '/path/to/foo'
+  ///
+  /// The given [suffix] cannot be an absolute path or use `..`.
+  String append(String parent, String suffix) {
+    return '$parent$separator$suffix';
+  }
+
+  /// Return the part of the absolute [path] after the last separator on the
+  /// context's platform.
+  ///
+  ///     context.basename('/path/to/foo.dart'); // -> 'foo.dart'
+  ///     context.basename('/path/to');          // -> 'to'
+  ///     context.basename('/path');             // -> 'path'
+  ///     context.basename('/');                 // -> ''
+  String basename(String path) {
+    int index = path.lastIndexOf(separator);
+    return path.substring(index + 1);
+  }
+
+  /// Return the part of the absolute [path] before the last separator.
+  ///
+  ///     context.dirname('/path/to/foo.dart'); // -> '/path/to'
+  ///     context.dirname('/path/to');          // -> '/path'
+  ///     context.dirname(r'/path');            // -> '/'
+  ///     context.dirname(r'/');                // -> '/'
+  ///     context.dirname(r'C:\path');          // -> 'C:\'
+  ///     context.dirname(r'C:\');              // -> 'C:\'
+  String dirname(String path) {
+    int firstIndex = path.indexOf(separator);
+    int lastIndex = path.lastIndexOf(separator);
+    return lastIndex == firstIndex
+        ? path.substring(0, firstIndex + 1)
+        : path.substring(0, lastIndex);
+  }
+
+  /// Return `true` if the given [path] is valid.
+  ///
+  ///     context.isNormalized('/foo/bar');        // -> true
+  ///     context.isNormalized('/foo/bar/../baz'); // -> false
+  bool isValid(String path) {
+    return _isAbsolute(path) && _isNormalized(path);
+  }
+
+  /// Return `true` if [child] is a path beneath [parent], and `false`
+  /// otherwise. Both the [child] and [parent] paths must be absolute paths.
+  ///
+  ///     context.isWithin('/root/path', '/root/path/a'); // -> true
+  ///     context.isWithin('/root/path', '/root/other');  // -> false
+  ///     context.isWithin('/root/path', '/root/path');   // -> false
+  bool isWithin(String parent, String child) {
+    int parentLength = parent.length;
+    int childLength = child.length;
+    if (parentLength >= childLength) {
+      return false;
+    }
+    if (child.codeUnitAt(parentLength) != _separatorChar) {
+      return false;
+    }
+    return _startsWithUnsafe(child, parent);
+  }
+
+  /// Split [path] into its components using [separator].
+  ///
+  ///     context.split('/path/to/foo'); // -> ['', 'path', 'to', 'foo']
+  List<String> split(String path) {
+    return path.split(separator);
+  }
+
+  /// If the given [child] is within the given [parent], then return the
+  /// relative path from [parent] to [child]. Otherwise return `null`. Both
+  /// the [child] and [parent] paths must be absolute paths.
+  ///
+  ///     context.relative('/root/path', '/root/path/a/b.dart'); // -> 'a/b.dart'
+  ///     context.relative('/root/path', '/root/other.dart');    // -> null
+  String suffix(String parent, String child) {
+    String parentPrefix = parent + separator;
+    if (child.startsWith(parentPrefix)) {
+      return child.substring(parentPrefix.length);
+    }
+    return null;
+  }
+
+  /// Return `true` if the given [path] is absolute.
+  ///
+  ///     _isAbsolute('/foo/bar');   // -> true
+  ///     _isAbsolute('/');          // -> true
+  ///     _isAbsolute('foo/bar');    // -> false
+  ///     _isAbsolute('C:\foo\bar'); // -> true
+  ///     _isAbsolute('C:\');        // -> true
+  ///     _isAbsolute('foo\bar');    // -> false
+  bool _isAbsolute(String path) {
+    if (_isWindows) {
+      return path.length >= 3 &&
+          _isAlphabetic(path.codeUnitAt(0)) &&
+          path.codeUnitAt(1) == _COLON &&
+          path.codeUnitAt(2) == _separatorChar;
+    } else {
+      return path.isNotEmpty && path.codeUnitAt(0) == _separatorChar;
+    }
+  }
+
+  /// Return `true` if the given absolute [path] is normalized.
+  ///
+  ///     _isNormalized('/foo/bar');        // -> true
+  ///     _isNormalized('/foo/..bar');      // -> true
+  ///     _isNormalized('/foo/bar..');      // -> true
+  ///     _isNormalized('/');               // -> true
+  ///     _isNormalized('/foo/bar/../baz'); // -> false
+  ///     _isNormalized('/foo/bar/..');     // -> false
+  bool _isNormalized(String path) {
+    return !path.contains(_singlePeriodComponent) &&
+        !path.contains(_doublePeriodComponent) &&
+        !path.endsWith(_singlePeriodEnding) &&
+        !path.endsWith(_doublePeriodEnding);
+  }
+
+  /// Returns whether [char] is the code for an ASCII letter (uppercase or
+  /// lowercase).
+  static bool _isAlphabetic(int char) {
+    return char >= _UPPER_A && char <= _UPPER_Z ||
+        char >= _LOWER_A && char <= _LOWER_Z;
+  }
+
+  /// Return `true` if [str] starts with the given [prefix].
+  ///
+  /// The check is done from the end of [prefix], because absolute paths
+  /// usually have the same prefix, e.g. the user's home directory.
+  static bool _startsWithUnsafe(String str, String prefix) {
+    int len = prefix.length;
+    for (int i = len - 1; i >= 0; i--) {
+      if (str.codeUnitAt(i) != prefix.codeUnitAt(i)) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
diff --git a/pkg/analyzer/lib/src/util/asserts.dart b/pkg/analyzer/lib/src/util/asserts.dart
index a53e7e6..402f3bc 100644
--- a/pkg/analyzer/lib/src/util/asserts.dart
+++ b/pkg/analyzer/lib/src/util/asserts.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.asserts;
+library analyzer.src.util.asserts;
 
 /**
  * Ensures that the given [value] is not null.
diff --git a/pkg/analyzer/lib/src/util/glob.dart b/pkg/analyzer/lib/src/util/glob.dart
new file mode 100644
index 0000000..ab86b4f
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/glob.dart
@@ -0,0 +1,117 @@
+// 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.util.glob;
+
+/**
+ * A pattern that matches against filesystem path-like strings with wildcards.
+ *
+ * The pattern matches strings as follows:
+ *   * The pattern must use `/` as the path separator.
+ *   * The whole string must match, not a substring.
+ *   * Any non wildcard is matched as a literal.
+ *   * '*' matches one or more characters except '/'.
+ *   * '?' matches exactly one character except '/'.
+ *   * '**' matches one or more characters including '/'.
+ */
+class Glob {
+  /**
+   * The special characters are: \ ^ $ . | + [ ] ( ) { }
+   * as defined here: http://ecma-international.org/ecma-262/5.1/#sec-15.10
+   */
+  static final RegExp _specialChars =
+      new RegExp(r'([\\\^\$\.\|\+\[\]\(\)\{\}])');
+
+  /**
+   * The path separator used to separate components in file paths.
+   */
+  final String _separator;
+
+  /**
+   * The pattern string.
+   */
+  final String _pattern;
+
+  String _suffix;
+  RegExp _regex;
+
+  Glob(this._separator, this._pattern) {
+    if (_hasJustPrefix(_pattern, '**/*')) {
+      _suffix = _pattern.substring(4).toLowerCase();
+    } else if (_hasJustPrefix(_pattern, '**')) {
+      _suffix = _pattern.substring(2).toLowerCase();
+    } else {
+      _regex = _regexpFromGlobPattern(_pattern);
+    }
+  }
+
+  @override
+  int get hashCode => _pattern.hashCode;
+
+  bool operator ==(other) => other is Glob && _pattern == other._pattern;
+
+  /**
+   * Return `true` if the given [path] matches this glob.
+   * The given [path] must use the same [_separator] as the glob.
+   */
+  bool matches(String path) {
+    String posixPath = _toPosixPath(path);
+    if (_suffix != null) {
+      return posixPath.toLowerCase().endsWith(_suffix);
+    }
+    return _regex.matchAsPrefix(posixPath) != null;
+  }
+
+  @override
+  String toString() => _pattern;
+
+  /**
+   * Return the Posix version of the given [path].
+   */
+  String _toPosixPath(String path) {
+    if (_separator == '/') {
+      return path;
+    }
+    return path.replaceAll(_separator, '/');
+  }
+
+  /**
+   * Return `true` if the [pattern] start with the given [prefix] and does
+   * not have `*` or `?` characters after the [prefix].
+   */
+  static bool _hasJustPrefix(String pattern, String prefix) {
+    if (pattern.startsWith(prefix)) {
+      int prefixLength = prefix.length;
+      return pattern.indexOf('*', prefixLength) == -1 &&
+          pattern.indexOf('?', prefixLength) == -1;
+    }
+    return false;
+  }
+
+  static RegExp _regexpFromGlobPattern(String pattern) {
+    StringBuffer sb = new StringBuffer();
+    sb.write('^');
+    List<String> chars = pattern.split('');
+    for (int i = 0; i < chars.length; i++) {
+      String c = chars[i];
+      if (_specialChars.hasMatch(c)) {
+        sb.write(r'\');
+        sb.write(c);
+      } else if (c == '*') {
+        if (i + 1 < chars.length && chars[i + 1] == '*') {
+          sb.write('.*');
+          i++;
+        } else {
+          sb.write('[^/]*');
+        }
+      } else if (c == '?') {
+        sb.write('[^/]');
+      } else {
+        sb.write(c);
+      }
+    }
+    sb.write(r'$');
+    return new RegExp(sb.toString(), caseSensitive: false);
+  }
+}
diff --git a/pkg/analyzer/lib/src/util/lru_map.dart b/pkg/analyzer/lib/src/util/lru_map.dart
index 38ef8ff..716f7ab 100644
--- a/pkg/analyzer/lib/src/util/lru_map.dart
+++ b/pkg/analyzer/lib/src/util/lru_map.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.lru_cache;
+library analyzer.src.util.lru_cache;
 
 import 'dart:collection';
 
diff --git a/pkg/analyzer/lib/src/util/utilities_timing.dart b/pkg/analyzer/lib/src/util/utilities_timing.dart
index 7b8e122..ebc42b7 100644
--- a/pkg/analyzer/lib/src/util/utilities_timing.dart
+++ b/pkg/analyzer/lib/src/util/utilities_timing.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.timing;
+library analyzer.src.util.utilities_timing;
 
 /**
  * A `CountedStopwatch` is a [Stopwatch] that counts the number of times the
diff --git a/pkg/analyzer/lib/src/util/yaml.dart b/pkg/analyzer/lib/src/util/yaml.dart
new file mode 100644
index 0000000..4f71bd7
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/yaml.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.util.yaml;
+
+import 'dart:collection';
+
+/// Merges two maps (of yaml) with simple override semantics, suitable for
+/// merging two maps where one map defines default values that are added to
+/// (and possibly overriden) by an overriding map.
+class Merger {
+  /// Merges a default [o1] with an overriding object [o2].
+  ///
+  ///   * lists are merged (without duplicates).
+  ///   * lists of scalar values can be promoted to simple maps when merged with
+  ///     maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes
+  ///     {'opt1': true, 'opt2': true}.
+  ///   * maps are merged recursively.
+  ///   * if map values cannot be merged, the overriding value is taken.
+  ///
+  Object merge(Object o1, Object o2) {
+    // Handle promotion first.
+    if (o1 is List && isMapToBools(o2)) {
+      o1 = new Map.fromIterable(o1, key: (item) => item, value: (item) => true);
+    } else if (isMapToBools(o1) && o2 is List) {
+      o2 = new Map.fromIterable(o2, key: (item) => item, value: (item) => true);
+    }
+
+    if (o1 is Map && o2 is Map) {
+      return mergeMap(o1, o2);
+    }
+    if (o1 is List && o2 is List) {
+      return mergeList(o1, o2);
+    }
+    // Default to override.
+    return o2;
+  }
+
+  /// Merge lists, avoiding duplicates.
+  List mergeList(List l1, List l2) =>
+      new List()..addAll(l1)..addAll(l2.where((item) => !l1.contains(item)));
+
+  /// Merge maps (recursively).
+  Map mergeMap(Map m1, Map m2) {
+    Map merged = new HashMap()..addAll(m1);
+    m2.forEach((k, v) {
+      merged[k] = merge(merged[k], v);
+    });
+    return merged;
+  }
+
+  static bool isMapToBools(Object o) =>
+      o is Map && o.values.every((v) => v is bool);
+}
diff --git a/pkg/analyzer/lib/task/dart.dart b/pkg/analyzer/lib/task/dart.dart
index 45fcb56..27258c3 100644
--- a/pkg/analyzer/lib/task/dart.dart
+++ b/pkg/analyzer/lib/task/dart.dart
@@ -4,8 +4,8 @@
 
 library analyzer.task.dart;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
index af67453..c320659 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -211,7 +211,7 @@
     } on AnalysisException catch (exception, stackTrace) {
       caughtException = new CaughtException(exception, stackTrace);
       AnalysisEngine.instance.logger
-          .logError("Task failed: ${description}", caughtException);
+          .logError("Task failed: $description", caughtException);
     }
   }
 
@@ -337,8 +337,8 @@
    * values associated with this result will remain in the cache.
    */
   factory ListResultDescriptor(String name, List<E> defaultValue,
-      {ResultCachingPolicy<List<E>> cachingPolicy}) = ListResultDescriptorImpl<
-      E>;
+          {ResultCachingPolicy<List<E>> cachingPolicy}) =
+      ListResultDescriptorImpl<E>;
 
   @override
   ListTaskInput<E> of(AnalysisTarget target, {bool flushOnAccess: false});
@@ -350,40 +350,41 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class ListTaskInput<E> extends TaskInput<List<E>> {
+abstract class ListTaskInput<E> implements TaskInput<List<E>> {
   /**
    * Return a task input that can be used to compute a flatten list whose
    * elements are combined [subListResult]'s associated with those elements.
    */
-  ListTaskInput /*<V>*/ toFlattenListOf(
+  ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
       ListResultDescriptor /*<V>*/ subListResult);
 
   /**
    * Return a task input that can be used to compute a list whose elements are
    * the result of passing the elements of this input to the [mapper] function.
    */
-  ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper);
+  ListTaskInput /*<V>*/ toList /*<V>*/ (
+      UnaryFunction<E, dynamic /*<=V>*/ > mapper);
 
   /**
    * Return a task input that can be used to compute a list whose elements are
    * [valueResult]'s associated with those elements.
    */
-  ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult);
+  ListTaskInput /*<V>*/ toListOf /*<V>*/ (ResultDescriptor /*<V>*/ valueResult);
 
   /**
    * Return a task input that can be used to compute a map whose keys are the
    * elements of this input and whose values are the result of passing the
    * corresponding key to the [mapper] function.
    */
-  MapTaskInput<E, dynamic /*V*/ > toMap(
-      UnaryFunction<E, dynamic /*<V>*/ > mapper);
+  MapTaskInput<E, dynamic /*=V*/ > toMap /*<V>*/ (
+      UnaryFunction<E, dynamic /*=V*/ > mapper);
 
   /**
    * Return a task input that can be used to compute a map whose keys are the
    * elements of this input and whose values are the [valueResult]'s associated
    * with those elements.
    */
-  MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
+  MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
       ResultDescriptor /*<V>*/ valueResult);
 }
 
@@ -392,15 +393,15 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class MapTaskInput<K, V> extends TaskInput<Map<K, V>> {
+abstract class MapTaskInput<K, V> implements TaskInput<Map<K, V>> {
   /**
    * [V] must be a [List].
    * Return a task input that can be used to compute a list whose elements are
    * the result of passing keys [K] and the corresponding elements of [V] to
    * the [mapper] function.
    */
-  TaskInput<List /*<E>*/ > toFlattenList(
-      BinaryFunction<K, dynamic /*element of V*/, dynamic /*<E>*/ > mapper);
+  TaskInput<List /*<E>*/ > toFlattenList /*<E>*/ (
+      BinaryFunction<K, dynamic /*element of V*/, dynamic /*=E*/ > mapper);
 }
 
 /**
@@ -570,7 +571,7 @@
    * Return a task input that can be used to compute a list whose elements are
    * the result of passing the result of this input to the [mapper] function.
    */
-  ListTaskInput /*<E>*/ mappedToList(List /*<E>*/ mapper(V value));
+  ListTaskInput /*<E>*/ mappedToList /*<E>*/ (List /*<E>*/ mapper(V value));
 }
 
 /**
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index d30df1f..607b92c 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.26.1+16
+version: 0.27.1+2
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/cancelable_future_test.dart b/pkg/analyzer/test/cancelable_future_test.dart
index b28c0f9..24c84ae 100644
--- a/pkg/analyzer/test/cancelable_future_test.dart
+++ b/pkg/analyzer/test/cancelable_future_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.cancelable_future;
+library analyzer.test.cancelable_future_test;
 
 import 'dart:async';
 
diff --git a/pkg/analyzer/test/dart/element/element_test.dart b/pkg/analyzer/test/dart/element/element_test.dart
new file mode 100644
index 0000000..ba6d5d1
--- /dev/null
+++ b/pkg/analyzer/test/dart/element/element_test.dart
@@ -0,0 +1,30 @@
+// 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 analyzer.test.dart.element.element_test;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../generated/test_support.dart';
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(ElementKindTest);
+}
+
+@reflectiveTest
+class ElementKindTest extends EngineTestCase {
+  void test_of_nonNull() {
+    expect(ElementKind.of(ElementFactory.classElement2("A")),
+        same(ElementKind.CLASS));
+  }
+
+  void test_of_null() {
+    expect(ElementKind.of(null), same(ElementKind.ERROR));
+  }
+}
diff --git a/pkg/analyzer/test/dart/element/test_all.dart b/pkg/analyzer/test/dart/element/test_all.dart
new file mode 100644
index 0000000..392c06a
--- /dev/null
+++ b/pkg/analyzer/test/dart/element/test_all.dart
@@ -0,0 +1,18 @@
+// 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 analyzer.test.generated.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../utils.dart';
+import 'element_test.dart' as element;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('generated tests', () {
+    element.main();
+  });
+}
diff --git a/pkg/analyzer/test/dart/test_all.dart b/pkg/analyzer/test/dart/test_all.dart
new file mode 100644
index 0000000..669b706
--- /dev/null
+++ b/pkg/analyzer/test/dart/test_all.dart
@@ -0,0 +1,18 @@
+// 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 analyzer.test.generated.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../utils.dart';
+import 'element/test_all.dart' as element;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('dart tests', () {
+    element.main();
+  });
+}
diff --git a/pkg/analyzer/test/enum_test.dart b/pkg/analyzer/test/enum_test.dart
index 706737f..625cf40 100644
--- a/pkg/analyzer/test/enum_test.dart
+++ b/pkg/analyzer/test/enum_test.dart
@@ -2,14 +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.
 
-library test.enums;
+library analyzer.test.enum_test;
 
 import 'dart:mirrors';
 
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as html;
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -69,12 +68,6 @@
       ..check_explicit_values();
   }
 
-  void test_html_TokenType() {
-    new EnumTester<html.TokenType>()
-      ..check_getters()
-      ..check_explicit_values();
-  }
-
   void test_INIT_STATE() {
     new EnumTester<INIT_STATE>()
       ..check_getters()
@@ -99,24 +92,12 @@
       ..check_explicit_values();
   }
 
-  void test_RetentionPriority() {
-    new EnumTester<RetentionPriority>()
-      ..check_getters()
-      ..check_explicit_values();
-  }
-
   void test_SourceKind() {
     new EnumTester<SourceKind>()
       ..check_getters()
       ..check_explicit_values();
   }
 
-  void test_SourcePriority() {
-    new EnumTester<SourcePriority>()
-      ..check_getters()
-      ..check_explicit_values();
-  }
-
   void test_UriKind() {
     new EnumTester<UriKind>()
       ..check_getters()
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index d0d3e55..d00d2d4 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.memory_file_system;
+library analyzer.test.file_system.memory_file_system_test;
 
 import 'dart:async';
 import 'dart:core' hide Resource;
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
index 87d976a..850bbcf 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.physical_file_system;
+library analyzer.test.file_system.physical_resource_provider_test;
 
 import 'dart:async';
 import 'dart:core' hide Resource;
@@ -301,7 +301,7 @@
           // See https://github.com/dart-lang/sdk/issues/23762
           // Not sure why this breaks under Windows, but testing to see whether
           // we are running Windows causes the type to change. For now we print
-          // the type out of curriosity.
+          // the type out of curiosity.
           print(
               'PhysicalResourceProviderTest:test_watchFile_delete received an event with type = ${changesReceived[0].type}');
         } else {
@@ -378,8 +378,8 @@
   }
 
   test_watchFolder_modifyFile_inSubDir() {
-    var subdirPath = join(tempPath, 'foo');
-    new io.Directory(subdirPath).createSync();
+    var fooPath = join(tempPath, 'foo');
+    new io.Directory(fooPath).createSync();
     var path = join(tempPath, 'bar');
     var file = new io.File(path);
     file.writeAsStringSync('contents 1');
@@ -410,7 +410,7 @@
       File file = PhysicalResourceProvider.INSTANCE.getResource(path);
       var changesReceived = <WatchEvent>[];
       var subscription = file.changes.listen(changesReceived.add);
-      // Delay running the rest of the test to allow file.changes propogate.
+      // Delay running the rest of the test to allow file.changes propagate.
       return _delayed(() => test(changesReceived)).whenComplete(() {
         subscription.cancel();
       });
diff --git a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
index 8d91d24..53247c1 100644
--- a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
+++ b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.resource_uri_resolver;
+library analyzer.test.file_system.resource_uri_resolver_test;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/file_system/test_all.dart b/pkg/analyzer/test/file_system/test_all.dart
index 303df09..1714c0b 100644
--- a/pkg/analyzer/test/file_system/test_all.dart
+++ b/pkg/analyzer/test/file_system/test_all.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.file_system;
+library analyzer.test.file_system.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index dc07ef9..f8ca1dc 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -2,17 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.all_the_rest_test;
+library analyzer.test.generated.all_the_rest_test;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht;
 import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -23,7 +23,6 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/testing/html_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -62,388 +61,9 @@
   runReflectiveTests(ExitDetectorTest2);
   runReflectiveTests(FileBasedSourceTest);
   runReflectiveTests(FileUriResolverTest);
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(HtmlParserTest);
-    runReflectiveTests(HtmlTagInfoBuilderTest);
-    runReflectiveTests(HtmlUnitBuilderTest);
-    runReflectiveTests(HtmlWarningCodeTest);
-  }
   runReflectiveTests(ReferenceFinderTest);
   runReflectiveTests(SDKLibrariesReaderTest);
-  runReflectiveTests(ToSourceVisitorTest);
   runReflectiveTests(UriKindTest);
-  runReflectiveTests(StringScannerTest);
-}
-
-abstract class AbstractScannerTest {
-  ht.AbstractScanner newScanner(String input);
-
-  void test_tokenize_attribute() {
-    _tokenize("<html bob=\"one two\">", <Object>[
-      ht.TokenType.LT,
-      "html",
-      "bob",
-      ht.TokenType.EQ,
-      "\"one two\"",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_comment() {
-    _tokenize("<!-- foo -->", <Object>["<!-- foo -->"]);
-  }
-
-  void test_tokenize_comment_incomplete() {
-    _tokenize("<!-- foo", <Object>["<!-- foo"]);
-  }
-
-  void test_tokenize_comment_with_gt() {
-    _tokenize("<!-- foo > -> -->", <Object>["<!-- foo > -> -->"]);
-  }
-
-  void test_tokenize_declaration() {
-    _tokenize("<! foo ><html>",
-        <Object>["<! foo >", ht.TokenType.LT, "html", ht.TokenType.GT]);
-  }
-
-  void test_tokenize_declaration_malformed() {
-    _tokenize("<! foo /><html>",
-        <Object>["<! foo />", ht.TokenType.LT, "html", ht.TokenType.GT]);
-  }
-
-  void test_tokenize_directive_incomplete() {
-    _tokenize2("<? \nfoo", <Object>["<? \nfoo"], <int>[0, 4]);
-  }
-
-  void test_tokenize_directive_xml() {
-    _tokenize("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>",
-        <Object>["<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"]);
-  }
-
-  void test_tokenize_directives_incomplete_with_newline() {
-    _tokenize2("<! \nfoo", <Object>["<! \nfoo"], <int>[0, 4]);
-  }
-
-  void test_tokenize_empty() {
-    _tokenize("", <Object>[]);
-  }
-
-  void test_tokenize_lt() {
-    _tokenize("<", <Object>[ht.TokenType.LT]);
-  }
-
-  void test_tokenize_script_embedded_tags() {
-    _tokenize("<script> <p></p></script>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      ht.TokenType.GT,
-      " <p></p>",
-      ht.TokenType.LT_SLASH,
-      "script",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_script_embedded_tags2() {
-    _tokenize("<script> <p></p><</script>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      ht.TokenType.GT,
-      " <p></p><",
-      ht.TokenType.LT_SLASH,
-      "script",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_script_embedded_tags3() {
-    _tokenize("<script> <p></p></</script>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      ht.TokenType.GT,
-      " <p></p></",
-      ht.TokenType.LT_SLASH,
-      "script",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_script_partial() {
-    _tokenize("<script> <p> ",
-        <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> "]);
-  }
-
-  void test_tokenize_script_partial2() {
-    _tokenize("<script> <p> <",
-        <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> <"]);
-  }
-
-  void test_tokenize_script_partial3() {
-    _tokenize("<script> <p> </",
-        <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> </"]);
-  }
-
-  void test_tokenize_script_ref() {
-    _tokenize("<script source='some.dart'/> <p>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      "source",
-      ht.TokenType.EQ,
-      "'some.dart'",
-      ht.TokenType.SLASH_GT,
-      " ",
-      ht.TokenType.LT,
-      "p",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_script_with_newline() {
-    _tokenize2("<script> <p>\n </script>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      ht.TokenType.GT,
-      " <p>\n ",
-      ht.TokenType.LT_SLASH,
-      "script",
-      ht.TokenType.GT
-    ], <int>[
-      0,
-      13
-    ]);
-  }
-
-  void test_tokenize_spaces_and_newlines() {
-    ht.Token token = _tokenize2(
-        " < html \n bob = 'joe\n' >\n <\np > one \r\n two <!-- \rfoo --> </ p > </ html > ",
-        <Object>[
-      " ",
-      ht.TokenType.LT,
-      "html",
-      "bob",
-      ht.TokenType.EQ,
-      "'joe\n'",
-      ht.TokenType.GT,
-      "\n ",
-      ht.TokenType.LT,
-      "p",
-      ht.TokenType.GT,
-      " one \r\n two ",
-      "<!-- \rfoo -->",
-      " ",
-      ht.TokenType.LT_SLASH,
-      "p",
-      ht.TokenType.GT,
-      " ",
-      ht.TokenType.LT_SLASH,
-      "html",
-      ht.TokenType.GT,
-      " "
-    ],
-        <int>[
-      0,
-      9,
-      21,
-      25,
-      28,
-      38,
-      49
-    ]);
-    token = token.next;
-    expect(token.offset, 1);
-    token = token.next;
-    expect(token.offset, 3);
-    token = token.next;
-    expect(token.offset, 10);
-  }
-
-  void test_tokenize_string() {
-    _tokenize("<p bob=\"foo\">", <Object>[
-      ht.TokenType.LT,
-      "p",
-      "bob",
-      ht.TokenType.EQ,
-      "\"foo\"",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_string_partial() {
-    _tokenize("<p bob=\"foo",
-        <Object>[ht.TokenType.LT, "p", "bob", ht.TokenType.EQ, "\"foo"]);
-  }
-
-  void test_tokenize_string_single_quote() {
-    _tokenize("<p bob='foo'>", <Object>[
-      ht.TokenType.LT,
-      "p",
-      "bob",
-      ht.TokenType.EQ,
-      "'foo'",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_string_single_quote_partial() {
-    _tokenize("<p bob='foo",
-        <Object>[ht.TokenType.LT, "p", "bob", ht.TokenType.EQ, "'foo"]);
-  }
-
-  void test_tokenize_tag_begin_end() {
-    _tokenize("<html></html>", <Object>[
-      ht.TokenType.LT,
-      "html",
-      ht.TokenType.GT,
-      ht.TokenType.LT_SLASH,
-      "html",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_tag_begin_only() {
-    ht.Token token =
-        _tokenize("<html>", <Object>[ht.TokenType.LT, "html", ht.TokenType.GT]);
-    token = token.next;
-    expect(token.offset, 1);
-  }
-
-  void test_tokenize_tag_incomplete_with_special_characters() {
-    _tokenize("<br-a_b", <Object>[ht.TokenType.LT, "br-a_b"]);
-  }
-
-  void test_tokenize_tag_self_contained() {
-    _tokenize("<br/>", <Object>[ht.TokenType.LT, "br", ht.TokenType.SLASH_GT]);
-  }
-
-  void test_tokenize_tags_wellformed() {
-    _tokenize("<html><p>one two</p></html>", <Object>[
-      ht.TokenType.LT,
-      "html",
-      ht.TokenType.GT,
-      ht.TokenType.LT,
-      "p",
-      ht.TokenType.GT,
-      "one two",
-      ht.TokenType.LT_SLASH,
-      "p",
-      ht.TokenType.GT,
-      ht.TokenType.LT_SLASH,
-      "html",
-      ht.TokenType.GT
-    ]);
-  }
-
-  /**
-   * Given an object representing an expected token, answer the expected token type.
-   *
-   * @param count the token count for error reporting
-   * @param expected the object representing an expected token
-   * @return the expected token type
-   */
-  ht.TokenType _getExpectedTokenType(int count, Object expected) {
-    if (expected is ht.TokenType) {
-      return expected;
-    }
-    if (expected is String) {
-      String lexeme = expected;
-      if (lexeme.startsWith("\"") || lexeme.startsWith("'")) {
-        return ht.TokenType.STRING;
-      }
-      if (lexeme.startsWith("<!--")) {
-        return ht.TokenType.COMMENT;
-      }
-      if (lexeme.startsWith("<!")) {
-        return ht.TokenType.DECLARATION;
-      }
-      if (lexeme.startsWith("<?")) {
-        return ht.TokenType.DIRECTIVE;
-      }
-      if (_isTag(lexeme)) {
-        return ht.TokenType.TAG;
-      }
-      return ht.TokenType.TEXT;
-    }
-    fail(
-        "Unknown expected token $count: ${expected != null ? expected.runtimeType : "null"}");
-    return null;
-  }
-
-  bool _isTag(String lexeme) {
-    if (lexeme.length == 0 || !Character.isLetter(lexeme.codeUnitAt(0))) {
-      return false;
-    }
-    for (int index = 1; index < lexeme.length; index++) {
-      int ch = lexeme.codeUnitAt(index);
-      if (!Character.isLetterOrDigit(ch) && ch != 0x2D && ch != 0x5F) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  ht.Token _tokenize(String input, List<Object> expectedTokens) =>
-      _tokenize2(input, expectedTokens, <int>[0]);
-  ht.Token _tokenize2(
-      String input, List<Object> expectedTokens, List<int> expectedLineStarts) {
-    ht.AbstractScanner scanner = newScanner(input);
-    scanner.passThroughElements = <String>["script"];
-    int count = 0;
-    ht.Token firstToken = scanner.tokenize();
-    ht.Token token = firstToken;
-    ht.Token previousToken = token.previous;
-    expect(previousToken.type == ht.TokenType.EOF, isTrue);
-    expect(previousToken.previous, same(previousToken));
-    expect(previousToken.offset, -1);
-    expect(previousToken.next, same(token));
-    expect(token.offset, 0);
-    while (token.type != ht.TokenType.EOF) {
-      if (count == expectedTokens.length) {
-        fail("too many parsed tokens");
-      }
-      Object expected = expectedTokens[count];
-      ht.TokenType expectedTokenType = _getExpectedTokenType(count, expected);
-      expect(token.type, same(expectedTokenType), reason: "token $count");
-      if (expectedTokenType.lexeme != null) {
-        expect(token.lexeme, expectedTokenType.lexeme, reason: "token $count");
-      } else {
-        expect(token.lexeme, expected, reason: "token $count");
-      }
-      count++;
-      previousToken = token;
-      token = token.next;
-      expect(token.previous, same(previousToken));
-    }
-    expect(token.next, same(token));
-    expect(token.offset, input.length);
-    if (count != expectedTokens.length) {
-      expect(false, isTrue, reason: "not enough parsed tokens");
-    }
-    List<int> lineStarts = scanner.lineStarts;
-    bool success = expectedLineStarts.length == lineStarts.length;
-    if (success) {
-      for (int i = 0; i < lineStarts.length; i++) {
-        if (expectedLineStarts[i] != lineStarts[i]) {
-          success = false;
-          break;
-        }
-      }
-    }
-    if (!success) {
-      StringBuffer buffer = new StringBuffer();
-      buffer.write("Expected line starts ");
-      for (int start in expectedLineStarts) {
-        buffer.write(start);
-        buffer.write(", ");
-      }
-      buffer.write(" but found ");
-      for (int start in lineStarts) {
-        buffer.write(start);
-        buffer.write(", ");
-      }
-      fail(buffer.toString());
-    }
-    return firstToken;
-  }
 }
 
 /**
@@ -877,14 +497,13 @@
 }
 
 @reflectiveTest
-class ConstantFinderTest extends EngineTestCase {
+class ConstantFinderTest {
   AstNode _node;
   TypeProvider _typeProvider;
   AnalysisContext _context;
   Source _source;
 
   void setUp() {
-    super.setUp();
     _typeProvider = new TestTypeProvider();
     _context = new TestAnalysisContext_ConstantFinderTest();
     _source = new TestSource();
@@ -1258,23 +877,27 @@
   void test_computeValues_cycle() {
     TestLogger logger = new TestLogger();
     AnalysisEngine.instance.logger = logger;
-    Source librarySource = addSource(r'''
-const int a = c;
-const int b = a;
-const int c = b;''');
-    LibraryElement libraryElement = resolve2(librarySource);
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit(librarySource, libraryElement);
-    analysisContext.computeErrors(librarySource);
-    expect(unit, isNotNull);
-    ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, librarySource, librarySource);
-    computer.computeValues();
-    NodeList<CompilationUnitMember> members = unit.declarations;
-    expect(members, hasLength(3));
-    _validate(false, (members[0] as TopLevelVariableDeclaration).variables);
-    _validate(false, (members[1] as TopLevelVariableDeclaration).variables);
-    _validate(false, (members[2] as TopLevelVariableDeclaration).variables);
+    try {
+      Source librarySource = addSource(r'''
+  const int a = c;
+  const int b = a;
+  const int c = b;''');
+      LibraryElement libraryElement = resolve2(librarySource);
+      CompilationUnit unit =
+          analysisContext.resolveCompilationUnit(librarySource, libraryElement);
+      analysisContext.computeErrors(librarySource);
+      expect(unit, isNotNull);
+      ConstantValueComputer computer = _makeConstantValueComputer();
+      computer.add(unit, librarySource, librarySource);
+      computer.computeValues();
+      NodeList<CompilationUnitMember> members = unit.declarations;
+      expect(members, hasLength(3));
+      _validate(false, (members[0] as TopLevelVariableDeclaration).variables);
+      _validate(false, (members[1] as TopLevelVariableDeclaration).variables);
+      _validate(false, (members[2] as TopLevelVariableDeclaration).variables);
+    } finally {
+      AnalysisEngine.instance.logger = Logger.NULL;
+    }
   }
 
   void test_computeValues_dependentVariables() {
@@ -2039,7 +1662,7 @@
     expect(evaluationResult.value, isNotNull);
     DartObjectImpl value = evaluationResult.value;
     expect(value.type, typeProvider.symbolType);
-    expect(value.value, "a");
+    expect(value.toSymbolValue(), "a");
   }
 
   void test_instanceCreationExpression_withSupertypeParams_explicit() {
@@ -2150,7 +1773,7 @@
         (voidSymbol.element as VariableElementImpl).evaluationResult;
     DartObjectImpl value = voidSymbolResult.value;
     expect(value.type, typeProvider.symbolType);
-    expect(value.value, "void");
+    expect(value.toSymbolValue(), "void");
   }
 
   Map<String, DartObjectImpl> _assertFieldType(
@@ -2221,7 +1844,7 @@
     expect(result.value, isNotNull);
     DartObjectImpl value = result.value;
     expect(value.type, typeProvider.stringType);
-    return value.stringValue;
+    return value.toStringValue();
   }
 
   void _assertValidUnknown(EvaluationResultImpl result) {
@@ -2483,8 +2106,7 @@
 ''');
     DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
     expect(result.type, typeProvider.typeType);
-    ClassElement element = result.value;
-    expect(element.name, 'C');
+    expect(result.toTypeValue().name, 'C');
   }
 
   void test_visitSimpleIdentifier_dynamic() {
@@ -2493,7 +2115,7 @@
 ''');
     DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
     expect(result.type, typeProvider.typeType);
-    expect(result.value, typeProvider.dynamicType.element);
+    expect(result.toTypeValue(), typeProvider.dynamicType);
   }
 
   void test_visitSimpleIdentifier_inEnvironment() {
@@ -2932,51 +2554,51 @@
   }
 
   void test_getValue_bool_false() {
-    expect(_boolValue(false).value, false);
+    expect(_boolValue(false).toBoolValue(), false);
   }
 
   void test_getValue_bool_true() {
-    expect(_boolValue(true).value, true);
+    expect(_boolValue(true).toBoolValue(), true);
   }
 
   void test_getValue_bool_unknown() {
-    expect(_boolValue(null).value, isNull);
+    expect(_boolValue(null).toBoolValue(), isNull);
   }
 
   void test_getValue_double_known() {
     double value = 2.3;
-    expect(_doubleValue(value).value, value);
+    expect(_doubleValue(value).toDoubleValue(), value);
   }
 
   void test_getValue_double_unknown() {
-    expect(_doubleValue(null).value, isNull);
+    expect(_doubleValue(null).toDoubleValue(), isNull);
   }
 
   void test_getValue_int_known() {
     int value = 23;
-    expect(_intValue(value).value, value);
+    expect(_intValue(value).toIntValue(), value);
   }
 
   void test_getValue_int_unknown() {
-    expect(_intValue(null).value, isNull);
+    expect(_intValue(null).toIntValue(), isNull);
   }
 
   void test_getValue_list_empty() {
-    Object result = _listValue().value;
+    Object result = _listValue().toListValue();
     _assertInstanceOfObjectArray(result);
     List<Object> array = result as List<Object>;
     expect(array, hasLength(0));
   }
 
   void test_getValue_list_valid() {
-    Object result = _listValue([_intValue(23)]).value;
+    Object result = _listValue([_intValue(23)]).toListValue();
     _assertInstanceOfObjectArray(result);
     List<Object> array = result as List<Object>;
     expect(array, hasLength(1));
   }
 
   void test_getValue_map_empty() {
-    Object result = _mapValue().value;
+    Object result = _mapValue().toMapValue();
     EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
     Map map = result as Map;
     expect(map, hasLength(0));
@@ -2984,23 +2606,23 @@
 
   void test_getValue_map_valid() {
     Object result =
-        _mapValue([_stringValue("key"), _stringValue("value")]).value;
+        _mapValue([_stringValue("key"), _stringValue("value")]).toMapValue();
     EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
     Map map = result as Map;
     expect(map, hasLength(1));
   }
 
   void test_getValue_null() {
-    expect(_nullValue().value, isNull);
+    expect(_nullValue().isNull, isTrue);
   }
 
   void test_getValue_string_known() {
     String value = "twenty-three";
-    expect(_stringValue(value).value, value);
+    expect(_stringValue(value).toStringValue(), value);
   }
 
   void test_getValue_string_unknown() {
-    expect(_stringValue(null).value, isNull);
+    expect(_stringValue(null).toStringValue(), isNull);
   }
 
   void test_greaterThan_knownDouble_knownDouble_false() {
@@ -5706,7 +5328,7 @@
     PropertyAccessorElement accessor = accessors[0];
     expect(accessor, isNotNull);
     _assertHasDocRange(accessor, 50, 7);
-    expect(accessor.hasImplicitReturnType, isFalse);
+    expect(accessor.hasImplicitReturnType, isTrue);
     expect(accessor.name, "$functionName=");
     expect(declaration.element, same(accessor));
     expect(declaration.functionExpression.element, same(accessor));
@@ -6133,7 +5755,7 @@
     PropertyAccessorElement setter = field.setter;
     expect(setter, isNotNull);
     _assertHasDocRange(setter, 50, 7);
-    expect(setter.hasImplicitReturnType, isFalse);
+    expect(setter.hasImplicitReturnType, isTrue);
     expect(setter.isAbstract, isFalse);
     expect(setter.isExternal, isFalse);
     expect(setter.isSetter, isTrue);
@@ -6171,7 +5793,7 @@
     expect(field.getter, isNull);
     PropertyAccessorElement setter = field.setter;
     expect(setter, isNotNull);
-    expect(setter.hasImplicitReturnType, isFalse);
+    expect(setter.hasImplicitReturnType, isTrue);
     expect(setter.isAbstract, isTrue);
     expect(setter.isExternal, isFalse);
     expect(setter.isSetter, isTrue);
@@ -6210,7 +5832,7 @@
     expect(field.getter, isNull);
     PropertyAccessorElement setter = field.setter;
     expect(setter, isNotNull);
-    expect(setter.hasImplicitReturnType, isFalse);
+    expect(setter.hasImplicitReturnType, isTrue);
     expect(setter.isAbstract, isFalse);
     expect(setter.isExternal, isTrue);
     expect(setter.isSetter, isTrue);
@@ -6727,7 +6349,8 @@
 
   void _assertHasDocRange(
       Element element, int expectedOffset, int expectedLength) {
-    SourceRange docRange = element.docRange;
+    // Cast to dynamic here to avoid a hint about @deprecated docRange.
+    SourceRange docRange = (element as dynamic).docRange;
     expect(docRange, isNotNull);
     expect(docRange.offset, expectedOffset);
     expect(docRange.length, expectedLength);
@@ -7350,7 +6973,9 @@
     SourceSpan span = new SourceFile(src).span(offset, offset + length);
 
     reporter.reportErrorForSpan(
-        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION, span, ['test', 'zap']);
+        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE,
+        span,
+        ['test', 'zip', 'zap']);
     expect(listener.errors, hasLength(1));
     expect(listener.errors.first.offset, offset);
     expect(listener.errors.first.length, length);
@@ -8400,473 +8025,6 @@
   }
 }
 
-@reflectiveTest
-class HtmlParserTest extends EngineTestCase {
-  /**
-   * The name of the 'script' tag in an HTML file.
-   */
-  static String _TAG_SCRIPT = "script";
-  void fail_parse_scriptWithComment() {
-    String scriptBody = r'''
-      /**
-       *     <editable-label bind-value="dartAsignableValue">
-       *     </editable-label>
-       */
-      class Foo {}''';
-    ht.HtmlUnit htmlUnit = parse("""
-<html>
-  <body>
-    <script type='application/dart'>
-$scriptBody
-    </script>
-  </body>
-</html>""");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t4("body", [
-          _t("script", _a(["type", "'application/dart'"]), scriptBody)
-        ])
-      ])
-    ]);
-  }
-
-  ht.HtmlUnit parse(String contents) {
-//    TestSource source =
-//        new TestSource.con1(FileUtilities2.createFile("/test.dart"), contents);
-    ht.AbstractScanner scanner = new ht.StringScanner(null, contents);
-    scanner.passThroughElements = <String>[_TAG_SCRIPT];
-    ht.Token token = scanner.tokenize();
-    LineInfo lineInfo = new LineInfo(scanner.lineStarts);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    ht.HtmlUnit unit =
-        new ht.HtmlParser(null, errorListener, options).parse(token, lineInfo);
-    errorListener.assertNoErrors();
-    return unit;
-  }
-
-  void test_parse_attribute() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "\"sdfsdf\""]), "")
-      ])
-    ]);
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.attributes[0].text, "sdfsdf");
-  }
-
-  void test_parse_attribute_EOF() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "\"sdfsdf\""]), "")
-      ])
-    ]);
-  }
-
-  void test_parse_attribute_EOF_missing_quote() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsd");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "\"sdfsd"]), "")
-      ])
-    ]);
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.attributes[0].text, "sdfsd");
-  }
-
-  void test_parse_attribute_extra_quote() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"\"></body></html>");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "\"sdfsdf\""]), "")
-      ])
-    ]);
-  }
-
-  void test_parse_attribute_single_quote() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo='sdfsdf'></body></html>");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "'sdfsdf'"]), "")
-      ])
-    ]);
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.attributes[0].text, "sdfsdf");
-  }
-
-  void test_parse_comment_embedded() {
-    ht.HtmlUnit htmlUnit = parse("<html <!-- comment -->></html>");
-    _validate(htmlUnit, [_t3("html", "")]);
-  }
-
-  void test_parse_comment_first() {
-    ht.HtmlUnit htmlUnit = parse("<!-- comment --><html></html>");
-    _validate(htmlUnit, [_t3("html", "")]);
-  }
-
-  void test_parse_comment_in_content() {
-    ht.HtmlUnit htmlUnit = parse("<html><!-- comment --></html>");
-    _validate(htmlUnit, [_t3("html", "<!-- comment -->")]);
-  }
-
-  void test_parse_content() {
-    ht.HtmlUnit htmlUnit = parse("<html>\n<p a=\"b\">blat \n </p>\n</html>");
-    // ht.XmlTagNode.getContent() does not include whitespace
-    // between '<' and '>' at this time
-    _validate(htmlUnit, [
-      _t3("html", "\n<pa=\"b\">blat \n </p>\n", [
-        _t("p", _a(["a", "\"b\""]), "blat \n ")
-      ])
-    ]);
-  }
-
-  void test_parse_content_none() {
-    ht.HtmlUnit htmlUnit = parse("<html><p/>blat<p/></html>");
-    _validate(htmlUnit, [
-      _t3("html", "<p/>blat<p/>", [_t3("p", ""), _t3("p", "")])
-    ]);
-  }
-
-  void test_parse_declaration() {
-    ht.HtmlUnit htmlUnit = parse("<!DOCTYPE html>\n\n<html><p></p></html>");
-    _validate(htmlUnit, [
-      _t4("html", [_t3("p", "")])
-    ]);
-  }
-
-  void test_parse_directive() {
-    ht.HtmlUnit htmlUnit = parse("<?xml ?>\n\n<html><p></p></html>");
-    _validate(htmlUnit, [
-      _t4("html", [_t3("p", "")])
-    ]);
-  }
-
-  void test_parse_getAttribute() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.getAttribute("foo").text, "sdfsdf");
-    expect(bodyNode.getAttribute("bar"), null);
-    expect(bodyNode.getAttribute(null), null);
-  }
-
-  void test_parse_getAttributeText() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.getAttributeText("foo"), "sdfsdf");
-    expect(bodyNode.getAttributeText("bar"), null);
-    expect(bodyNode.getAttributeText(null), null);
-  }
-
-  void test_parse_headers() {
-    String code = r'''
-<html>
-  <body>
-    <h2>000</h2>
-    <div>
-      111
-    </div>
-  </body>
-</html>''';
-    ht.HtmlUnit htmlUnit = parse(code);
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t4("body", [_t3("h2", "000"), _t4("div")])
-      ])
-    ]);
-  }
-
-  void test_parse_script() {
-    ht.HtmlUnit htmlUnit =
-        parse("<html><script >here is <p> some</script></html>");
-    _validate(htmlUnit, [
-      _t4("html", [_t3("script", "here is <p> some")])
-    ]);
-  }
-
-  void test_parse_self_closing() {
-    ht.HtmlUnit htmlUnit = parse("<html>foo<br>bar</html>");
-    _validate(htmlUnit, [
-      _t3("html", "foo<br>bar", [_t3("br", "")])
-    ]);
-  }
-
-  void test_parse_self_closing_declaration() {
-    ht.HtmlUnit htmlUnit = parse("<!DOCTYPE html><html>foo</html>");
-    _validate(htmlUnit, [_t3("html", "foo")]);
-  }
-
-  XmlValidator_Attributes _a(List<String> keyValuePairs) =>
-      new XmlValidator_Attributes(keyValuePairs);
-  XmlValidator_Tag _t(
-          String tag, XmlValidator_Attributes attributes, String content,
-          [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
-      new XmlValidator_Tag(tag, attributes, content, children);
-  XmlValidator_Tag _t3(String tag, String content,
-          [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
-      new XmlValidator_Tag(
-          tag, new XmlValidator_Attributes(), content, children);
-  XmlValidator_Tag _t4(String tag,
-          [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
-      new XmlValidator_Tag(tag, new XmlValidator_Attributes(), null, children);
-  void _validate(ht.HtmlUnit htmlUnit, List<XmlValidator_Tag> expectedTags) {
-    XmlValidator validator = new XmlValidator();
-    validator.expectTags(expectedTags);
-    htmlUnit.accept(validator);
-    validator.assertValid();
-  }
-}
-
-@reflectiveTest
-class HtmlTagInfoBuilderTest extends HtmlParserTest {
-  void test_builder() {
-    HtmlTagInfoBuilder builder = new HtmlTagInfoBuilder();
-    ht.HtmlUnit unit = parse(r'''
-<html>
-  <body>
-    <div id="x"></div>
-    <p class='c'></p>
-    <div class='c'></div>
-  </body>
-</html>''');
-    unit.accept(builder);
-    HtmlTagInfo info = builder.getTagInfo();
-    expect(info, isNotNull);
-    List<String> allTags = info.allTags;
-    expect(allTags, hasLength(4));
-    expect(info.getTagWithId("x"), "div");
-    List<String> tagsWithClass = info.getTagsWithClass("c");
-    expect(tagsWithClass, hasLength(2));
-  }
-}
-
-@reflectiveTest
-class HtmlUnitBuilderTest extends EngineTestCase {
-  InternalAnalysisContext _context;
-  @override
-  void setUp() {
-    _context = AnalysisContextFactory.contextWithCore();
-  }
-
-  @override
-  void tearDown() {
-    _context = null;
-    super.tearDown();
-  }
-
-  void test_embedded_script() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart">foo=2;</script>
-</html>''');
-    _validate(element, [
-      _s(_l([_v("foo")]))
-    ]);
-  }
-
-  void test_embedded_script_no_content() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart"></script>
-</html>''');
-    _validate(element, [_s(_l())]);
-  }
-
-  void test_external_script() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart" src="other.dart"/>
-</html>''');
-    _validate(element, [_s2("other.dart")]);
-  }
-
-  void test_external_script_no_source() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart"/>
-</html>''');
-    _validate(element, [_s2(null)]);
-  }
-
-  void test_external_script_with_content() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart" src="other.dart">blat=2;</script>
-</html>''');
-    _validate(element, [_s2("other.dart")]);
-  }
-
-  void test_no_scripts() {
-    HtmlElementImpl element = _build(r'''
-<!DOCTYPE html>
-<html><p></p></html>''');
-    _validate(element, []);
-  }
-
-  void test_two_dart_scripts() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart">bar=2;</script>
-<script type="application/dart" src="other.dart"/>
-<script src="dart.js"/>
-</html>''');
-    _validate(element, [
-      _s(_l([_v("bar")])),
-      _s2("other.dart")
-    ]);
-  }
-
-  HtmlElementImpl _build(String contents) {
-    TestSource source = new TestSource(
-        FileUtilities2.createFile("/test.html").getAbsolutePath(), contents);
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    HtmlUnitBuilder builder = new HtmlUnitBuilder(_context);
-    return builder.buildHtmlElement(source, _context.parseHtmlUnit(source));
-  }
-
-  HtmlUnitBuilderTest_ExpectedLibrary _l(
-          [List<HtmlUnitBuilderTest_ExpectedVariable> expectedVariables =
-              HtmlUnitBuilderTest_ExpectedVariable.EMPTY_LIST]) =>
-      new HtmlUnitBuilderTest_ExpectedLibrary(this, expectedVariables);
-  _ExpectedScript _s(HtmlUnitBuilderTest_ExpectedLibrary expectedLibrary) =>
-      new _ExpectedScript.con1(expectedLibrary);
-  _ExpectedScript _s2(String scriptSourcePath) =>
-      new _ExpectedScript.con2(scriptSourcePath);
-  HtmlUnitBuilderTest_ExpectedVariable _v(String varName) =>
-      new HtmlUnitBuilderTest_ExpectedVariable(varName);
-  void _validate(
-      HtmlElementImpl element, List<_ExpectedScript> expectedScripts) {
-    expect(element.context, same(_context));
-    List<HtmlScriptElement> scripts = element.scripts;
-    expect(scripts, isNotNull);
-    expect(scripts, hasLength(expectedScripts.length));
-    for (int scriptIndex = 0; scriptIndex < scripts.length; scriptIndex++) {
-      expectedScripts[scriptIndex]._validate(scriptIndex, scripts[scriptIndex]);
-    }
-  }
-}
-
-class HtmlUnitBuilderTest_ExpectedLibrary {
-  final HtmlUnitBuilderTest HtmlUnitBuilderTest_this;
-  final List<HtmlUnitBuilderTest_ExpectedVariable> _expectedVariables;
-  HtmlUnitBuilderTest_ExpectedLibrary(this.HtmlUnitBuilderTest_this,
-      [this._expectedVariables =
-          HtmlUnitBuilderTest_ExpectedVariable.EMPTY_LIST]);
-  void _validate(int scriptIndex, EmbeddedHtmlScriptElementImpl script) {
-    LibraryElement library = script.scriptLibrary;
-    expect(library, isNotNull, reason: "script $scriptIndex");
-    expect(script.context, same(HtmlUnitBuilderTest_this._context),
-        reason: "script $scriptIndex");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull, reason: "script $scriptIndex");
-    List<TopLevelVariableElement> variables = unit.topLevelVariables;
-    expect(variables, hasLength(_expectedVariables.length));
-    for (int index = 0; index < variables.length; index++) {
-      _expectedVariables[index].validate(scriptIndex, variables[index]);
-    }
-    expect(library.enclosingElement, same(script),
-        reason: "script $scriptIndex");
-  }
-}
-
-class HtmlUnitBuilderTest_ExpectedVariable {
-  static const List<HtmlUnitBuilderTest_ExpectedVariable> EMPTY_LIST =
-      const <HtmlUnitBuilderTest_ExpectedVariable>[];
-  final String _expectedName;
-  HtmlUnitBuilderTest_ExpectedVariable(this._expectedName);
-  void validate(int scriptIndex, TopLevelVariableElement variable) {
-    expect(variable, isNotNull, reason: "script $scriptIndex");
-    expect(variable.name, _expectedName, reason: "script $scriptIndex");
-  }
-}
-
-/**
- * Instances of the class `HtmlWarningCodeTest` test the generation of HTML warning codes.
- */
-@reflectiveTest
-class HtmlWarningCodeTest extends EngineTestCase {
-  /**
-   * The analysis context used to resolve the HTML files.
-   */
-  InternalAnalysisContext _context;
-
-  /**
-   * The contents of the 'test.html' file.
-   */
-  String _contents;
-
-  /**
-   * The list of reported errors.
-   */
-  List<AnalysisError> _errors;
-  @override
-  void setUp() {
-    _context = AnalysisContextFactory.contextWithCore();
-  }
-
-  @override
-  void tearDown() {
-    _context = null;
-    _contents = null;
-    _errors = null;
-    super.tearDown();
-  }
-
-  void test_invalidUri() {
-    _verify(
-        r'''
-<html>
-<script type='application/dart' src='ht:'/>
-</html>''',
-        [HtmlWarningCode.INVALID_URI]);
-    _assertErrorLocation2(_errors[0], "ht:");
-  }
-
-  void test_uriDoesNotExist() {
-    _verify(
-        r'''
-<html>
-<script type='application/dart' src='other.dart'/>
-</html>''',
-        [HtmlWarningCode.URI_DOES_NOT_EXIST]);
-    _assertErrorLocation2(_errors[0], "other.dart");
-  }
-
-  void _assertErrorLocation(
-      AnalysisError error, int expectedOffset, int expectedLength) {
-    expect(error.offset, expectedOffset, reason: error.toString());
-    expect(error.length, expectedLength, reason: error.toString());
-  }
-
-  void _assertErrorLocation2(AnalysisError error, String expectedString) {
-    _assertErrorLocation(
-        error, _contents.indexOf(expectedString), expectedString.length);
-  }
-
-  void _verify(String contents, List<ErrorCode> expectedErrorCodes) {
-    this._contents = contents;
-    TestSource source = new TestSource(
-        FileUtilities2.createFile("/test.html").getAbsolutePath(), contents);
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    HtmlUnitBuilder builder = new HtmlUnitBuilder(_context);
-    builder.buildHtmlElement(source, _context.parseHtmlUnit(source));
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    errorListener.addAll2(builder.errorListener);
-    errorListener.assertErrorsWithCodes(expectedErrorCodes);
-    _errors = errorListener.errors;
-  }
-}
-
 /**
  * Instances of the class `MockDartSdk` implement a [DartSdk].
  */
@@ -8894,11 +8052,11 @@
 }
 
 @reflectiveTest
-class ReferenceFinderTest extends EngineTestCase {
+class ReferenceFinderTest {
   DirectedGraph<ConstantEvaluationTarget> _referenceGraph;
   VariableElement _head;
   Element _tail;
-  @override
+
   void setUp() {
     _referenceGraph = new DirectedGraph<ConstantEvaluationTarget>();
     _head = ElementFactory.topLevelVariableElement2("v1");
@@ -9060,14 +8218,6 @@
   }
 }
 
-@reflectiveTest
-class StringScannerTest extends AbstractScannerTest {
-  @override
-  ht.AbstractScanner newScanner(String input) {
-    return new ht.StringScanner(null, input);
-  }
-}
-
 class TestAnalysisContext_ConstantFinderTest extends TestAnalysisContext {
   bool invoked = false;
   TestAnalysisContext_ConstantFinderTest();
@@ -9078,61 +8228,6 @@
   }
 }
 
-/**
- * Instances of the class `ToSourceVisitorTest`
- */
-@reflectiveTest
-class ToSourceVisitorTest extends EngineTestCase {
-  void fail_visitHtmlScriptTagNode_attributes_content() {
-    _assertSource(
-        "<script type='application/dart'>f() {}</script>",
-        HtmlFactory.scriptTagWithContent(
-            "f() {}", [HtmlFactory.attribute("type", "'application/dart'")]));
-  }
-
-  void fail_visitHtmlScriptTagNode_noAttributes_content() {
-    _assertSource(
-        "<script>f() {}</script>", HtmlFactory.scriptTagWithContent("f() {}"));
-  }
-
-  void test_visitHtmlScriptTagNode_attributes_noContent() {
-    _assertSource(
-        "<script type='application/dart'/>",
-        HtmlFactory
-            .scriptTag([HtmlFactory.attribute("type", "'application/dart'")]));
-  }
-
-  void test_visitHtmlScriptTagNode_noAttributes_noContent() {
-    _assertSource("<script/>", HtmlFactory.scriptTag());
-  }
-
-  void test_visitHtmlUnit_empty() {
-    _assertSource("", new ht.HtmlUnit(null, new List<ht.XmlTagNode>(), null));
-  }
-
-  void test_visitHtmlUnit_nonEmpty() {
-    _assertSource(
-        "<html/>", new ht.HtmlUnit(null, [HtmlFactory.tagNode("html")], null));
-  }
-
-  void test_visitXmlAttributeNode() {
-    _assertSource("x=y", HtmlFactory.attribute("x", "y"));
-  }
-
-  /**
-   * Assert that a `ToSourceVisitor` will produce the expected source when visiting the given
-   * node.
-   *
-   * @param expectedSource the source string that the visitor is expected to produce
-   * @param node the AST node being visited to produce the actual source
-   */
-  void _assertSource(String expectedSource, ht.XmlNode node) {
-    PrintStringWriter writer = new PrintStringWriter();
-    node.accept(new ht.ToSourceVisitor(writer));
-    expect(writer.toString(), expectedSource);
-  }
-}
-
 @reflectiveTest
 class UriKindTest {
   void test_fromEncoding() {
@@ -9148,285 +8243,3 @@
     expect(UriKind.PACKAGE_URI.encoding, 0x70);
   }
 }
-
-/**
- * Instances of `XmlValidator` traverse an [XmlNode] structure and validate the node
- * hierarchy.
- */
-class XmlValidator extends ht.RecursiveXmlVisitor<Object> {
-  /**
-   * A list containing the errors found while traversing the AST structure.
-   */
-  List<String> _errors = new List<String>();
-  /**
-   * The tags to expect when visiting or `null` if tags should not be checked.
-   */
-  List<XmlValidator_Tag> _expectedTagsInOrderVisited;
-  /**
-   * The current index into the [expectedTagsInOrderVisited] array.
-   */
-  int _expectedTagsIndex = 0;
-  /**
-   * The key/value pairs to expect when visiting or `null` if attributes should not be
-   * checked.
-   */
-  List<String> _expectedAttributeKeyValuePairs;
-  /**
-   * The current index into the [expectedAttributeKeyValuePairs].
-   */
-  int _expectedAttributeIndex = 0;
-  /**
-   * Assert that no errors were found while traversing any of the AST structures that have been
-   * visited.
-   */
-  void assertValid() {
-    while (_expectedTagsIndex < _expectedTagsInOrderVisited.length) {
-      String expectedTag =
-          _expectedTagsInOrderVisited[_expectedTagsIndex++]._tag;
-      _errors.add("Expected to visit node with tag: $expectedTag");
-    }
-    if (!_errors.isEmpty) {
-      StringBuffer buffer = new StringBuffer();
-      buffer.write("Invalid XML structure:");
-      for (String message in _errors) {
-        buffer.writeln();
-        buffer.write("   ");
-        buffer.write(message);
-      }
-      fail(buffer.toString());
-    }
-  }
-
-  /**
-   * Set the tags to be expected when visiting
-   *
-   * @param expectedTags the expected tags
-   */
-  void expectTags(List<XmlValidator_Tag> expectedTags) {
-    // Flatten the hierarchy into expected order in which the tags are visited
-    List<XmlValidator_Tag> expected = new List<XmlValidator_Tag>();
-    _expectTags(expected, expectedTags);
-    this._expectedTagsInOrderVisited = expected;
-  }
-
-  @override
-  Object visitHtmlUnit(ht.HtmlUnit node) {
-    if (node.parent != null) {
-      _errors.add("HtmlUnit should not have a parent");
-    }
-    if (node.endToken.type != ht.TokenType.EOF) {
-      _errors.add("HtmlUnit end token should be of type EOF");
-    }
-    _validateNode(node);
-    return super.visitHtmlUnit(node);
-  }
-
-  @override
-  Object visitXmlAttributeNode(ht.XmlAttributeNode actual) {
-    if (actual.parent is! ht.XmlTagNode) {
-      _errors.add(
-          "Expected ${actual.runtimeType} to have parent of type XmlTagNode");
-    }
-    String actualName = actual.name;
-    String actualValue = actual.valueToken.lexeme;
-    if (_expectedAttributeIndex < _expectedAttributeKeyValuePairs.length) {
-      String expectedName =
-          _expectedAttributeKeyValuePairs[_expectedAttributeIndex];
-      if (expectedName != actualName) {
-        _errors.add(
-            "Expected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} to have name: $expectedName but found: $actualName");
-      }
-      String expectedValue =
-          _expectedAttributeKeyValuePairs[_expectedAttributeIndex + 1];
-      if (expectedValue != actualValue) {
-        _errors.add(
-            "Expected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} to have value: $expectedValue but found: $actualValue");
-      }
-    } else {
-      _errors.add(
-          "Unexpected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} name: $actualName value: $actualValue");
-    }
-    _expectedAttributeIndex += 2;
-    _validateNode(actual);
-    return super.visitXmlAttributeNode(actual);
-  }
-
-  @override
-  Object visitXmlTagNode(ht.XmlTagNode actual) {
-    if (!(actual.parent is ht.HtmlUnit || actual.parent is ht.XmlTagNode)) {
-      _errors.add(
-          "Expected ${actual.runtimeType} to have parent of type HtmlUnit or XmlTagNode");
-    }
-    if (_expectedTagsInOrderVisited != null) {
-      String actualTag = actual.tag;
-      if (_expectedTagsIndex < _expectedTagsInOrderVisited.length) {
-        XmlValidator_Tag expected =
-            _expectedTagsInOrderVisited[_expectedTagsIndex];
-        if (expected._tag != actualTag) {
-          _errors.add(
-              "Expected $_expectedTagsIndex tag: ${expected._tag} but found: $actualTag");
-        }
-        _expectedAttributeKeyValuePairs = expected._attributes._keyValuePairs;
-        int expectedAttributeCount =
-            _expectedAttributeKeyValuePairs.length ~/ 2;
-        int actualAttributeCount = actual.attributes.length;
-        if (expectedAttributeCount != actualAttributeCount) {
-          _errors.add(
-              "Expected $_expectedTagsIndex tag: ${expected._tag} to have $expectedAttributeCount attributes but found $actualAttributeCount");
-        }
-        _expectedAttributeIndex = 0;
-        _expectedTagsIndex++;
-        expect(actual.attributeEnd, isNotNull);
-        expect(actual.contentEnd, isNotNull);
-        int count = 0;
-        ht.Token token = actual.attributeEnd.next;
-        ht.Token lastToken = actual.contentEnd;
-        while (!identical(token, lastToken)) {
-          token = token.next;
-          if (++count > 1000) {
-            fail(
-                "Expected $_expectedTagsIndex tag: ${expected._tag} to have a sequence of tokens from getAttributeEnd() to getContentEnd()");
-            break;
-          }
-        }
-        if (actual.attributeEnd.type == ht.TokenType.GT) {
-          if (ht.HtmlParser.SELF_CLOSING.contains(actual.tag)) {
-            expect(actual.closingTag, isNull);
-          } else {
-            expect(actual.closingTag, isNotNull);
-          }
-        } else if (actual.attributeEnd.type == ht.TokenType.SLASH_GT) {
-          expect(actual.closingTag, isNull);
-        } else {
-          fail("Unexpected attribute end token: ${actual.attributeEnd.lexeme}");
-        }
-        if (expected._content != null && expected._content != actual.content) {
-          _errors.add(
-              "Expected $_expectedTagsIndex tag: ${expected._tag} to have content '${expected._content}' but found '${actual.content}'");
-        }
-        if (expected._children.length != actual.tagNodes.length) {
-          _errors.add(
-              "Expected $_expectedTagsIndex tag: ${expected._tag} to have ${expected._children.length} children but found ${actual.tagNodes.length}");
-        } else {
-          for (int index = 0; index < expected._children.length; index++) {
-            String expectedChildTag = expected._children[index]._tag;
-            String actualChildTag = actual.tagNodes[index].tag;
-            if (expectedChildTag != actualChildTag) {
-              _errors.add(
-                  "Expected $_expectedTagsIndex tag: ${expected._tag} child $index to have tag: $expectedChildTag but found: $actualChildTag");
-            }
-          }
-        }
-      } else {
-        _errors.add("Visited unexpected tag: $actualTag");
-      }
-    }
-    _validateNode(actual);
-    return super.visitXmlTagNode(actual);
-  }
-
-  /**
-   * Append the specified tags to the array in depth first order
-   *
-   * @param expected the array to which the tags are added (not `null`)
-   * @param expectedTags the expected tags to be added (not `null`, contains no `null`s)
-   */
-  void _expectTags(
-      List<XmlValidator_Tag> expected, List<XmlValidator_Tag> expectedTags) {
-    for (XmlValidator_Tag tag in expectedTags) {
-      expected.add(tag);
-      _expectTags(expected, tag._children);
-    }
-  }
-
-  void _validateNode(ht.XmlNode node) {
-    if (node.beginToken == null) {
-      _errors.add("No begin token for ${node.runtimeType}");
-    }
-    if (node.endToken == null) {
-      _errors.add("No end token for ${node.runtimeType}");
-    }
-    int nodeStart = node.offset;
-    int nodeLength = node.length;
-    if (nodeStart < 0 || nodeLength < 0) {
-      _errors.add("No source info for ${node.runtimeType}");
-    }
-    ht.XmlNode parent = node.parent;
-    if (parent != null) {
-      int nodeEnd = nodeStart + nodeLength;
-      int parentStart = parent.offset;
-      int parentEnd = parentStart + parent.length;
-      if (nodeStart < parentStart) {
-        _errors.add(
-            "Invalid source start ($nodeStart) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
-      }
-      if (nodeEnd > parentEnd) {
-        _errors.add(
-            "Invalid source end ($nodeEnd) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
-      }
-    }
-  }
-}
-
-class XmlValidator_Attributes {
-  final List<String> _keyValuePairs;
-  XmlValidator_Attributes([this._keyValuePairs = StringUtilities.EMPTY_ARRAY]);
-}
-
-class XmlValidator_Tag {
-  static const List<XmlValidator_Tag> EMPTY_LIST = const <XmlValidator_Tag>[];
-  final String _tag;
-  final XmlValidator_Attributes _attributes;
-  final String _content;
-  final List<XmlValidator_Tag> _children;
-  XmlValidator_Tag(this._tag, this._attributes, this._content,
-      [this._children = EMPTY_LIST]);
-}
-
-class _ExpectedScript {
-  String _expectedExternalScriptName;
-  HtmlUnitBuilderTest_ExpectedLibrary _expectedLibrary;
-  _ExpectedScript.con1(HtmlUnitBuilderTest_ExpectedLibrary expectedLibrary) {
-    this._expectedExternalScriptName = null;
-    this._expectedLibrary = expectedLibrary;
-  }
-  _ExpectedScript.con2(String expectedExternalScriptPath) {
-    this._expectedExternalScriptName = expectedExternalScriptPath;
-    this._expectedLibrary = null;
-  }
-  void _validate(int scriptIndex, HtmlScriptElement script) {
-    if (_expectedLibrary != null) {
-      _validateEmbedded(scriptIndex, script);
-    } else {
-      _validateExternal(scriptIndex, script);
-    }
-  }
-
-  void _validateEmbedded(int scriptIndex, HtmlScriptElement script) {
-    if (script is! EmbeddedHtmlScriptElementImpl) {
-      fail(
-          "Expected script $scriptIndex to be embedded, but found ${script != null ? script.runtimeType : "null"}");
-    }
-    EmbeddedHtmlScriptElementImpl embeddedScript =
-        script as EmbeddedHtmlScriptElementImpl;
-    _expectedLibrary._validate(scriptIndex, embeddedScript);
-  }
-
-  void _validateExternal(int scriptIndex, HtmlScriptElement script) {
-    if (script is! ExternalHtmlScriptElementImpl) {
-      fail(
-          "Expected script $scriptIndex to be external with src=$_expectedExternalScriptName but found ${script != null ? script.runtimeType : "null"}");
-    }
-    ExternalHtmlScriptElementImpl externalScript =
-        script as ExternalHtmlScriptElementImpl;
-    Source scriptSource = externalScript.scriptSource;
-    if (_expectedExternalScriptName == null) {
-      expect(scriptSource, isNull, reason: "script $scriptIndex");
-    } else {
-      expect(scriptSource, isNotNull, reason: "script $scriptIndex");
-      String actualExternalScriptName = scriptSource.shortName;
-      expect(actualExternalScriptName, _expectedExternalScriptName,
-          reason: "script $scriptIndex");
-    }
-  }
-}
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index e25c253..bff9b8b 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.ast_test;
+library analyzer.test.generated.ast_test;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -29,6 +29,7 @@
   runReflectiveTests(IndexExpressionTest);
   runReflectiveTests(NodeListTest);
   runReflectiveTests(NodeLocatorTest);
+  runReflectiveTests(NodeLocator2Test);
   runReflectiveTests(SimpleIdentifierTest);
   runReflectiveTests(SimpleStringLiteralTest);
   runReflectiveTests(StringInterpolationTest);
@@ -945,6 +946,50 @@
 }
 
 @reflectiveTest
+class NodeLocator2Test extends ParserTestCase {
+  void test_onlyStartOffset() {
+    String code = ' int vv; ';
+    //             012345678
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit(code);
+    TopLevelVariableDeclaration declaration = unit.declarations[0];
+    VariableDeclarationList variableList = declaration.variables;
+    Identifier typeName = variableList.type.name;
+    SimpleIdentifier varName = variableList.variables[0].name;
+    expect(new NodeLocator2(0).searchWithin(unit), same(unit));
+    expect(new NodeLocator2(1).searchWithin(unit), same(typeName));
+    expect(new NodeLocator2(2).searchWithin(unit), same(typeName));
+    expect(new NodeLocator2(3).searchWithin(unit), same(typeName));
+    expect(new NodeLocator2(4).searchWithin(unit), same(variableList));
+    expect(new NodeLocator2(5).searchWithin(unit), same(varName));
+    expect(new NodeLocator2(6).searchWithin(unit), same(varName));
+    expect(new NodeLocator2(7).searchWithin(unit), same(declaration));
+    expect(new NodeLocator2(8).searchWithin(unit), same(unit));
+    expect(new NodeLocator2(9).searchWithin(unit), isNull);
+    expect(new NodeLocator2(100).searchWithin(unit), isNull);
+  }
+
+  void test_startEndOffset() {
+    String code = ' int vv; ';
+    //             012345678
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit(code);
+    TopLevelVariableDeclaration declaration = unit.declarations[0];
+    VariableDeclarationList variableList = declaration.variables;
+    Identifier typeName = variableList.type.name;
+    SimpleIdentifier varName = variableList.variables[0].name;
+    expect(new NodeLocator2(-1, 2).searchWithin(unit), isNull);
+    expect(new NodeLocator2(0, 2).searchWithin(unit), same(unit));
+    expect(new NodeLocator2(1, 2).searchWithin(unit), same(typeName));
+    expect(new NodeLocator2(1, 3).searchWithin(unit), same(typeName));
+    expect(new NodeLocator2(1, 4).searchWithin(unit), same(variableList));
+    expect(new NodeLocator2(5, 6).searchWithin(unit), same(varName));
+    expect(new NodeLocator2(5, 7).searchWithin(unit), same(declaration));
+    expect(new NodeLocator2(5, 8).searchWithin(unit), same(unit));
+    expect(new NodeLocator2(5, 100).searchWithin(unit), isNull);
+    expect(new NodeLocator2(100, 200).searchWithin(unit), isNull);
+  }
+}
+
+@reflectiveTest
 class NodeLocatorTest extends ParserTestCase {
   void test_range() {
     CompilationUnit unit =
@@ -1688,6 +1733,13 @@
         "assert (a);", AstFactory.assertStatement(AstFactory.identifier3("a")));
   }
 
+  void test_visitAssertStatement_withMessage() {
+    _assertSource(
+        "assert (a, b);",
+        AstFactory.assertStatement(
+            AstFactory.identifier3("a"), AstFactory.identifier3('b')));
+  }
+
   void test_visitAssignmentExpression() {
     _assertSource(
         "a = b",
@@ -2290,6 +2342,13 @@
     _assertSource("continue;", AstFactory.continueStatement());
   }
 
+  void test_visitDefaultFormalParameter_annotation() {
+    DefaultFormalParameter parameter = AstFactory.positionalFormalParameter(
+        AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0));
+    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+    _assertSource('@A p = 0', parameter);
+  }
+
   void test_visitDefaultFormalParameter_named_noValue() {
     _assertSource(
         "p",
@@ -2318,13 +2377,6 @@
             AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0)));
   }
 
-  void test_visitDefaultFormalParameter_annotation() {
-    DefaultFormalParameter parameter = AstFactory.positionalFormalParameter(
-        AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0));
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
-    _assertSource('@A p = 0', parameter);
-  }
-
   void test_visitDoStatement() {
     _assertSource(
         "do {} while (c);",
@@ -2423,6 +2475,12 @@
     _assertSource("@deprecated var a;", declaration);
   }
 
+  void test_visitFieldFormalParameter_annotation() {
+    FieldFormalParameter parameter = AstFactory.fieldFormalParameter2('f');
+    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+    _assertSource('@A this.f', parameter);
+  }
+
   void test_visitFieldFormalParameter_functionTyped() {
     _assertSource(
         "A this.a(b)",
@@ -2467,12 +2525,6 @@
         AstFactory.fieldFormalParameter(null, AstFactory.typeName4("A"), "a"));
   }
 
-  void test_visitFieldFormalParameter_annotation() {
-    FieldFormalParameter parameter = AstFactory.fieldFormalParameter2('f');
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
-    _assertSource('@A this.f', parameter);
-  }
-
   void test_visitForEachStatement_declared() {
     _assertSource(
         "for (var a in b) {}",
@@ -2907,16 +2959,17 @@
     _assertSource("@deprecated typedef A F();", declaration);
   }
 
-  void test_visitFunctionTypedFormalParameter_noType() {
-    _assertSource("f()", AstFactory.functionTypedFormalParameter(null, "f"));
-  }
-
   void test_visitFunctionTypedFormalParameter_annotation() {
-    FunctionTypedFormalParameter parameter = AstFactory.functionTypedFormalParameter(null, "f");
+    FunctionTypedFormalParameter parameter =
+        AstFactory.functionTypedFormalParameter(null, "f");
     parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
     _assertSource('@A f()', parameter);
   }
 
+  void test_visitFunctionTypedFormalParameter_noType() {
+    _assertSource("f()", AstFactory.functionTypedFormalParameter(null, "f"));
+  }
+
   void test_visitFunctionTypedFormalParameter_type() {
     _assertSource(
         "T f()",
@@ -3524,6 +3577,12 @@
     _assertSource(scriptTag, AstFactory.scriptTag(scriptTag));
   }
 
+  void test_visitSimpleFormalParameter_annotation() {
+    SimpleFormalParameter parameter = AstFactory.simpleFormalParameter3('x');
+    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+    _assertSource('@A x', parameter);
+  }
+
   void test_visitSimpleFormalParameter_keyword() {
     _assertSource("var a", AstFactory.simpleFormalParameter(Keyword.VAR, "a"));
   }
@@ -3540,12 +3599,6 @@
         AstFactory.simpleFormalParameter4(AstFactory.typeName4("A"), "a"));
   }
 
-  void test_visitSimpleFormalParameter_annotation() {
-    SimpleFormalParameter parameter = AstFactory.simpleFormalParameter3('x');
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
-    _assertSource('@A x', parameter);
-  }
-
   void test_visitSimpleIdentifier() {
     _assertSource("a", AstFactory.identifier3("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 743399e..5f2abf5 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.compile_time_error_code_test;
+library analyzer.test.generated.compile_time_error_code_test;
 
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
@@ -222,6 +222,59 @@
     verify([source]);
   }
 
+  void test_annotationWithNotClass() {
+    Source source = addSource('''
+class Property {
+  final int value;
+  const Property(this.value);
+}
+
+const Property property = const Property(42);
+
+@property(123)
+main() {
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS]);
+    verify([source]);
+  }
+
+  void test_annotationWithNotClass_prefixed() {
+    addNamedSource(
+        "/annotations.dart",
+        r'''
+class Property {
+  final int value;
+  const Property(this.value);
+}
+
+const Property property = const Property(42);
+''');
+    Source source = addSource('''
+import 'annotations.dart' as pref;
+@pref.property(123)
+main() {
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS]);
+    verify([source]);
+  }
+
+  void test_assertWithExtraArgument() {
+    // TODO(paulberry): once DEP 37 is turned on by default, this test should
+    // be removed.
+    Source source = addSource('''
+f(bool x) {
+  assert(x, 'foo');
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTRA_ARGUMENT_TO_ASSERT]);
+    verify([source]);
+  }
+
   void test_async_used_as_identifier_in_annotation() {
     Source source = addSource('''
 const int async = 0;
@@ -1595,9 +1648,28 @@
 class A {}''');
     computeLibrarySourceErrors(librarySource);
     assertErrors(sourceB, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertNoErrors(librarySource);
     verify([librarySource, sourceA, sourceB]);
   }
 
+  void test_duplicateDefinition_inPart() {
+    Source librarySource = addNamedSource(
+        "/lib.dart",
+        r'''
+library test;
+part 'a.dart';
+class A {}''');
+    Source sourceA = addNamedSource(
+        "/a.dart",
+        r'''
+part of test;
+class A {}''');
+    computeLibrarySourceErrors(librarySource);
+    assertErrors(sourceA, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertNoErrors(librarySource);
+    verify([librarySource, sourceA]);
+  }
+
   void test_duplicateDefinition_catch() {
     Source source = addSource(r'''
 main() {
@@ -1896,8 +1968,7 @@
     Source source = addSource("class A extends double {}");
     computeLibrarySourceErrors(source);
     assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
-      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS
     ]);
     verify([source]);
   }
@@ -1926,8 +1997,7 @@
     Source source = addSource("class A extends num {}");
     computeLibrarySourceErrors(source);
     assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
-      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS
     ]);
     verify([source]);
   }
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
new file mode 100644
index 0000000..3dfae2b
--- /dev/null
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -0,0 +1,157 @@
+// 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 engine.declaration_resolver_test;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'resolver_test.dart';
+import 'test_support.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(DeclarationResolverTest);
+  runReflectiveTests(StrongModeDeclarationResolverTest);
+}
+
+CompilationUnit _cloneResolveUnit(CompilationUnit unit) {
+  CompilationUnit clonedUnit = AstCloner.clone(unit);
+  new DeclarationResolver().resolve(clonedUnit, unit.element);
+  return clonedUnit;
+}
+
+SimpleIdentifier _findSimpleIdentifier(
+    AstNode root, String code, String search) {
+  return EngineTestCase.findNode(
+      root, code, search, (n) => n is SimpleIdentifier);
+}
+
+@reflectiveTest
+class DeclarationResolverTest extends ResolverTestCase {
+  @override
+  void setUp() {
+    super.setUp();
+  }
+
+  void test_functionDeclaration_getter() {
+    String code = r'''
+int get zzz => 42;
+''';
+    CompilationUnit unit = resolveSource(code);
+    PropertyAccessorElement getterElement =
+        _findSimpleIdentifier(unit, code, 'zzz =>').staticElement;
+    expect(getterElement.isGetter, isTrue);
+    // re-resolve
+    CompilationUnit unit2 = _cloneResolveUnit(unit);
+    SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz =>');
+    expect(getterName.staticElement, same(getterElement));
+  }
+
+  void test_functionDeclaration_setter() {
+    String code = r'''
+void set zzz(_) {}
+''';
+    CompilationUnit unit = resolveSource(code);
+    PropertyAccessorElement setterElement =
+        _findSimpleIdentifier(unit, code, 'zzz(_)').staticElement;
+    expect(setterElement.isSetter, isTrue);
+    // re-resolve
+    CompilationUnit unit2 = _cloneResolveUnit(unit);
+    SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz(_)');
+    expect(getterName.staticElement, same(setterElement));
+  }
+
+  void test_invalid_functionDeclaration_getter_inFunction() {
+    String code = r'''
+main() {
+  int get zzz => 42;
+}
+''';
+    CompilationUnit unit = resolveSource(code);
+    FunctionElement getterElement =
+        _findSimpleIdentifier(unit, code, 'zzz =>').staticElement;
+    // re-resolve
+    CompilationUnit unit2 = _cloneResolveUnit(unit);
+    SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz =>');
+    expect(getterName.staticElement, same(getterElement));
+  }
+
+  void test_invalid_functionDeclaration_setter_inFunction() {
+    String code = r'''
+main() {
+  set zzz(x) {}
+}
+''';
+    CompilationUnit unit = resolveSource(code);
+    FunctionElement setterElement =
+        _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement;
+    // re-resolve
+    CompilationUnit unit2 = _cloneResolveUnit(unit);
+    SimpleIdentifier setterName = _findSimpleIdentifier(unit2, code, 'zzz(x)');
+    expect(setterName.staticElement, same(setterElement));
+  }
+}
+
+/**
+ * Strong mode DeclarationResolver tests
+ */
+@reflectiveTest
+class StrongModeDeclarationResolverTest extends ResolverTestCase {
+  @override
+  void setUp() {
+    resetWithOptions(new AnalysisOptionsImpl()..strongMode = true);
+  }
+
+  void test_genericFunction_typeParameter() {
+    String code = r'''
+/*=T*/ max/*<T>*/(/*=T*/ x, /*=T*/ y) => null;
+''';
+    CompilationUnit unit = resolveSource(code);
+    FunctionDeclaration node = _findSimpleIdentifier(unit, code, 'max').parent;
+    TypeParameter t = node.functionExpression.typeParameters.typeParameters[0];
+
+    FunctionElement element = node.name.staticElement;
+    TypeParameterElement tElement = element.typeParameters[0];
+    expect(tElement, isNotNull);
+    expect(element.typeParameters.toString(), "[T]");
+    expect(element.type.toString(), "<T>(T, T) → T");
+    expect(t.element, same(tElement));
+
+    // re-resolve
+    CompilationUnit unit2 = _cloneResolveUnit(unit);
+    node = _findSimpleIdentifier(unit2, code, 'max').parent;
+    t = node.functionExpression.typeParameters.typeParameters[0];
+    expect(t.element, same(tElement));
+  }
+
+  void test_genericMethod_typeParameter() {
+    String code = r'''
+class C {
+  /*=T*/ max/*<T>*/(/*=T*/ x, /*=T*/ y) => null;
+}
+''';
+    CompilationUnit unit = resolveSource(code);
+    MethodDeclaration node = _findSimpleIdentifier(unit, code, 'max').parent;
+    TypeParameter t = node.typeParameters.typeParameters[0];
+
+    MethodElement element = node.name.staticElement;
+    TypeParameterElement tElement = element.typeParameters[0];
+    expect(tElement, isNotNull);
+    expect(element.typeParameters.toString(), "[T]");
+    expect(element.type.toString(), "<T>(T, T) → T");
+    expect(t.element, same(tElement));
+
+    // re-resolve
+    CompilationUnit unit2 = _cloneResolveUnit(unit);
+    node = _findSimpleIdentifier(unit2, code, 'max').parent;
+    t = node.typeParameters.typeParameters[0];
+    expect(t.element, same(tElement));
+  }
+}
diff --git a/pkg/analyzer/test/generated/element_test.dart b/pkg/analyzer/test/generated/element_test.dart
deleted file mode 100644
index 14485e2..0000000
--- a/pkg/analyzer/test/generated/element_test.dart
+++ /dev/null
@@ -1,4285 +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 engine.element_test;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisContext, AnalysisOptionsImpl;
-import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
-import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/testing/test_type_provider.dart';
-import 'package:unittest/unittest.dart';
-
-import '../reflective_tests.dart';
-import '../utils.dart';
-import 'resolver_test.dart' show TestTypeProvider, AnalysisContextHelper;
-import 'test_support.dart';
-
-main() {
-  initializeTestEnvironment();
-  runReflectiveTests(ElementKindTest);
-  runReflectiveTests(FieldElementImplTest);
-  runReflectiveTests(FunctionTypeImplTest);
-  runReflectiveTests(InterfaceTypeImplTest);
-  runReflectiveTests(TypeParameterTypeImplTest);
-  runReflectiveTests(VoidTypeImplTest);
-  runReflectiveTests(ClassElementImplTest);
-  runReflectiveTests(CompilationUnitElementImplTest);
-  runReflectiveTests(ElementLocationImplTest);
-  runReflectiveTests(ElementImplTest);
-  runReflectiveTests(HtmlElementImplTest);
-  runReflectiveTests(LibraryElementImplTest);
-  runReflectiveTests(MethodElementImplTest);
-  runReflectiveTests(MultiplyDefinedElementImplTest);
-  runReflectiveTests(ParameterElementImplTest);
-}
-
-@reflectiveTest
-class ClassElementImplTest extends EngineTestCase {
-  void test_computeNode_ClassDeclaration() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource(
-        "/test.dart",
-        r'''
-class A {}
-@deprecated class B {}
-enum C {C1, C2, C3}
-@deprecated enum D {D1, D2, D3}''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // A
-    {
-      ClassElement elementA = unitElement.getType("A");
-      expect(elementA.isDeprecated, isFalse);
-      expect(elementA.isEnum, isFalse);
-      ClassDeclaration nodeA = elementA.computeNode();
-      expect(nodeA, isNotNull);
-      expect(nodeA.name.name, "A");
-      expect(nodeA.element, same(elementA));
-    }
-    // B
-    {
-      ClassElement elementB = unitElement.getType("B");
-      expect(elementB.isDeprecated, isTrue);
-      expect(elementB.isEnum, isFalse);
-      ClassDeclaration nodeB = elementB.computeNode();
-      expect(nodeB, isNotNull);
-      expect(nodeB.name.name, "B");
-      expect(nodeB.element, same(elementB));
-    }
-    // C
-    {
-      ClassElement elementC = unitElement.getEnum("C");
-      expect(elementC.isDeprecated, isFalse);
-      expect(elementC.isEnum, isTrue);
-      EnumDeclaration nodeC = elementC.computeNode();
-      expect(nodeC, isNotNull);
-      expect(nodeC.name.name, "C");
-      expect(nodeC.element, same(elementC));
-    }
-    // D
-    {
-      ClassElement elementD = unitElement.getEnum("D");
-      expect(elementD.isDeprecated, isTrue);
-      expect(elementD.isEnum, isTrue);
-      EnumDeclaration nodeC = elementD.computeNode();
-      expect(nodeC, isNotNull);
-      expect(nodeC.name.name, "D");
-      expect(nodeC.element, same(elementD));
-    }
-  }
-
-  void test_computeNode_ClassTypeAlias() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource(
-        "/test.dart",
-        r'''
-abstract class A<K, V> = Object with MapMixin<K, V>;
-''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // A
-    {
-      ClassElement elementA = unitElement.getType("A");
-      ClassTypeAlias nodeA = elementA.computeNode();
-      expect(nodeA, isNotNull);
-      expect(nodeA.name.name, "A");
-      expect(nodeA.element, same(elementA));
-    }
-  }
-
-  void test_getAllSupertypes_interface() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl elementC = ElementFactory.classElement2("C");
-    InterfaceType typeObject = classA.supertype;
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = elementC.type;
-    elementC.interfaces = <InterfaceType>[typeB];
-    List<InterfaceType> supers = elementC.allSupertypes;
-    List<InterfaceType> types = new List<InterfaceType>();
-    types.addAll(supers);
-    expect(types.contains(typeA), isTrue);
-    expect(types.contains(typeB), isTrue);
-    expect(types.contains(typeObject), isTrue);
-    expect(types.contains(typeC), isFalse);
-  }
-
-  void test_getAllSupertypes_mixins() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeObject = classA.supertype;
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classC.mixins = <InterfaceType>[typeB];
-    List<InterfaceType> supers = classC.allSupertypes;
-    List<InterfaceType> types = new List<InterfaceType>();
-    types.addAll(supers);
-    expect(types.contains(typeA), isFalse);
-    expect(types.contains(typeB), isTrue);
-    expect(types.contains(typeObject), isTrue);
-    expect(types.contains(typeC), isFalse);
-  }
-
-  void test_getAllSupertypes_recursive() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    List<InterfaceType> supers = classB.allSupertypes;
-    expect(supers, hasLength(1));
-  }
-
-  void test_getField() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String fieldName = "f";
-    FieldElementImpl field =
-        ElementFactory.fieldElement(fieldName, false, false, false, null);
-    classA.fields = <FieldElement>[field];
-    expect(classA.getField(fieldName), same(field));
-    expect(field.isEnumConstant, false);
-    // no such field
-    expect(classA.getField("noSuchField"), same(null));
-  }
-
-  void test_getMethod_declared() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[method];
-    expect(classA.getMethod(methodName), same(method));
-  }
-
-  void test_getMethod_undeclared() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[method];
-    expect(classA.getMethod("${methodName}x"), isNull);
-  }
-
-  void test_hasNonFinalField_false_const() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.fields = <FieldElement>[
-      ElementFactory.fieldElement("f", false, false, true, classA.type)
-    ];
-    expect(classA.hasNonFinalField, isFalse);
-  }
-
-  void test_hasNonFinalField_false_final() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.fields = <FieldElement>[
-      ElementFactory.fieldElement("f", false, true, false, classA.type)
-    ];
-    expect(classA.hasNonFinalField, isFalse);
-  }
-
-  void test_hasNonFinalField_false_recursive() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    expect(classA.hasNonFinalField, isFalse);
-  }
-
-  void test_hasNonFinalField_true_immediate() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.fields = <FieldElement>[
-      ElementFactory.fieldElement("f", false, false, false, classA.type)
-    ];
-    expect(classA.hasNonFinalField, isTrue);
-  }
-
-  void test_hasNonFinalField_true_inherited() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.fields = <FieldElement>[
-      ElementFactory.fieldElement("f", false, false, false, classA.type)
-    ];
-    expect(classB.hasNonFinalField, isTrue);
-  }
-
-  void test_hasStaticMember_false_empty() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    // no members
-    expect(classA.hasStaticMember, isFalse);
-  }
-
-  void test_hasStaticMember_false_instanceMethod() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    MethodElement method = ElementFactory.methodElement("foo", null);
-    classA.methods = <MethodElement>[method];
-    expect(classA.hasStaticMember, isFalse);
-  }
-
-  void test_hasStaticMember_instanceGetter() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    PropertyAccessorElement getter =
-        ElementFactory.getterElement("foo", false, null);
-    classA.accessors = <PropertyAccessorElement>[getter];
-    expect(classA.hasStaticMember, isFalse);
-  }
-
-  void test_hasStaticMember_true_getter() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    PropertyAccessorElementImpl getter =
-        ElementFactory.getterElement("foo", false, null);
-    classA.accessors = <PropertyAccessorElement>[getter];
-    // "foo" is static
-    getter.static = true;
-    expect(classA.hasStaticMember, isTrue);
-  }
-
-  void test_hasStaticMember_true_method() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    MethodElementImpl method = ElementFactory.methodElement("foo", null);
-    classA.methods = <MethodElement>[method];
-    // "foo" is static
-    method.static = true;
-    expect(classA.hasStaticMember, isTrue);
-  }
-
-  void test_hasStaticMember_true_setter() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    PropertyAccessorElementImpl setter =
-        ElementFactory.setterElement("foo", false, null);
-    classA.accessors = <PropertyAccessorElement>[setter];
-    // "foo" is static
-    setter.static = true;
-    expect(classA.hasStaticMember, isTrue);
-  }
-
-  void test_isEnum() {
-    String firstConst = "A";
-    String secondConst = "B";
-    ClassElementImpl enumE = ElementFactory.enumElement(
-        new TestTypeProvider(), "E", [firstConst, secondConst]);
-
-    // E is an enum
-    expect(enumE.isEnum, true);
-
-    // A and B are static members
-    expect(enumE.getField(firstConst).isEnumConstant, true);
-    expect(enumE.getField(secondConst).isEnumConstant, true);
-  }
-
-  void test_lookUpConcreteMethod_declared() {
-    // class A {
-    //   m() {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpConcreteMethod(methodName, library), same(method));
-  }
-
-  void test_lookUpConcreteMethod_declaredAbstract() {
-    // class A {
-    //   m();
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElementImpl method = ElementFactory.methodElement(methodName, null);
-    method.abstract = true;
-    classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpConcreteMethod(methodName, library), isNull);
-  }
-
-  void test_lookUpConcreteMethod_declaredAbstractAndInherited() {
-    // class A {
-    //   m() {}
-    // }
-    // class B extends A {
-    //   m();
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    MethodElementImpl method = ElementFactory.methodElement(methodName, null);
-    method.abstract = true;
-    classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpConcreteMethod(methodName, library),
-        same(inheritedMethod));
-  }
-
-  void test_lookUpConcreteMethod_declaredAndInherited() {
-    // class A {
-    //   m() {}
-    // }
-    // class B extends A {
-    //   m() {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpConcreteMethod(methodName, library), same(method));
-  }
-
-  void test_lookUpConcreteMethod_declaredAndInheritedAbstract() {
-    // abstract class A {
-    //   m();
-    // }
-    // class B extends A {
-    //   m() {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.abstract = true;
-    String methodName = "m";
-    MethodElementImpl inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    inheritedMethod.abstract = true;
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpConcreteMethod(methodName, library), same(method));
-  }
-
-  void test_lookUpConcreteMethod_inherited() {
-    // class A {
-    //   m() {}
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpConcreteMethod(methodName, library),
-        same(inheritedMethod));
-  }
-
-  void test_lookUpConcreteMethod_undeclared() {
-    // class A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpConcreteMethod("m", library), isNull);
-  }
-
-  void test_lookUpGetter_declared() {
-    // class A {
-    //   get g {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String getterName = "g";
-    PropertyAccessorElement getter =
-        ElementFactory.getterElement(getterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[getter];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpGetter(getterName, library), same(getter));
-  }
-
-  void test_lookUpGetter_inherited() {
-    // class A {
-    //   get g {}
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String getterName = "g";
-    PropertyAccessorElement getter =
-        ElementFactory.getterElement(getterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[getter];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpGetter(getterName, library), same(getter));
-  }
-
-  void test_lookUpGetter_undeclared() {
-    // class A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpGetter("g", library), isNull);
-  }
-
-  void test_lookUpGetter_undeclared_recursive() {
-    // class A extends B {
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classA.lookUpGetter("g", library), isNull);
-  }
-
-  void test_lookUpInheritedConcreteGetter_declared() {
-    // class A {
-    //   get g {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String getterName = "g";
-    PropertyAccessorElement getter =
-        ElementFactory.getterElement(getterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[getter];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpInheritedConcreteGetter(getterName, library), isNull);
-  }
-
-  void test_lookUpInheritedConcreteGetter_inherited() {
-    // class A {
-    //   get g {}
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String getterName = "g";
-    PropertyAccessorElement inheritedGetter =
-        ElementFactory.getterElement(getterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[inheritedGetter];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpInheritedConcreteGetter(getterName, library),
-        same(inheritedGetter));
-  }
-
-  void test_lookUpInheritedConcreteGetter_undeclared() {
-    // class A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
-  }
-
-  void test_lookUpInheritedConcreteGetter_undeclared_recursive() {
-    // class A extends B {
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
-  }
-
-  void test_lookUpInheritedConcreteMethod_declared() {
-    // class A {
-    //   m() {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpInheritedConcreteMethod(methodName, library), isNull);
-  }
-
-  void test_lookUpInheritedConcreteMethod_declaredAbstractAndInherited() {
-    // class A {
-    //   m() {}
-    // }
-    // class B extends A {
-    //   m();
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    MethodElementImpl method = ElementFactory.methodElement(methodName, null);
-    method.abstract = true;
-    classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpInheritedConcreteMethod(methodName, library),
-        same(inheritedMethod));
-  }
-
-  void test_lookUpInheritedConcreteMethod_declaredAndInherited() {
-    // class A {
-    //   m() {}
-    // }
-    // class B extends A {
-    //   m() {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpInheritedConcreteMethod(methodName, library),
-        same(inheritedMethod));
-  }
-
-  void test_lookUpInheritedConcreteMethod_declaredAndInheritedAbstract() {
-    // abstract class A {
-    //   m();
-    // }
-    // class B extends A {
-    //   m() {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.abstract = true;
-    String methodName = "m";
-    MethodElementImpl inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    inheritedMethod.abstract = true;
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpInheritedConcreteMethod(methodName, library), isNull);
-  }
-
-  void test_lookUpInheritedConcreteMethod_declaredAndInheritedWithAbstractBetween() {
-    // class A {
-    //   m() {}
-    // }
-    // class B extends A {
-    //   m();
-    // }
-    // class C extends B {
-    //   m() {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    MethodElementImpl abstractMethod =
-        ElementFactory.methodElement(methodName, null);
-    abstractMethod.abstract = true;
-    classB.methods = <MethodElement>[abstractMethod];
-    ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
-    MethodElementImpl method = ElementFactory.methodElement(methodName, null);
-    classC.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB, classC];
-    expect(classC.lookUpInheritedConcreteMethod(methodName, library),
-        same(inheritedMethod));
-  }
-
-  void test_lookUpInheritedConcreteMethod_inherited() {
-    // class A {
-    //   m() {}
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpInheritedConcreteMethod(methodName, library),
-        same(inheritedMethod));
-  }
-
-  void test_lookUpInheritedConcreteMethod_undeclared() {
-    // class A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpInheritedConcreteMethod("m", library), isNull);
-  }
-
-  void test_lookUpInheritedConcreteSetter_declared() {
-    // class A {
-    //   set g(x) {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String setterName = "s";
-    PropertyAccessorElement setter =
-        ElementFactory.setterElement(setterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[setter];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpInheritedConcreteSetter(setterName, library), isNull);
-  }
-
-  void test_lookUpInheritedConcreteSetter_inherited() {
-    // class A {
-    //   set g(x) {}
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String setterName = "s";
-    PropertyAccessorElement setter =
-        ElementFactory.setterElement(setterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[setter];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpInheritedConcreteSetter(setterName, library),
-        same(setter));
-  }
-
-  void test_lookUpInheritedConcreteSetter_undeclared() {
-    // class A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
-  }
-
-  void test_lookUpInheritedConcreteSetter_undeclared_recursive() {
-    // class A extends B {
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
-  }
-
-  void test_lookUpInheritedMethod_declared() {
-    // class A {
-    //   m() {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpInheritedMethod(methodName, library), isNull);
-  }
-
-  void test_lookUpInheritedMethod_declaredAndInherited() {
-    // class A {
-    //   m() {}
-    // }
-    // class B extends A {
-    //   m() {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpInheritedMethod(methodName, library),
-        same(inheritedMethod));
-  }
-
-  void test_lookUpInheritedMethod_inherited() {
-    // class A {
-    //   m() {}
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement inheritedMethod =
-        ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[inheritedMethod];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpInheritedMethod(methodName, library),
-        same(inheritedMethod));
-  }
-
-  void test_lookUpInheritedMethod_undeclared() {
-    // class A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpInheritedMethod("m", library), isNull);
-  }
-
-  void test_lookUpMethod_declared() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpMethod(methodName, library), same(method));
-  }
-
-  void test_lookUpMethod_inherited() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElement method = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[method];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpMethod(methodName, library), same(method));
-  }
-
-  void test_lookUpMethod_undeclared() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpMethod("m", library), isNull);
-  }
-
-  void test_lookUpMethod_undeclared_recursive() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classA.lookUpMethod("m", library), isNull);
-  }
-
-  void test_lookUpSetter_declared() {
-    // class A {
-    //   set g(x) {}
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String setterName = "s";
-    PropertyAccessorElement setter =
-        ElementFactory.setterElement(setterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[setter];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpSetter(setterName, library), same(setter));
-  }
-
-  void test_lookUpSetter_inherited() {
-    // class A {
-    //   set g(x) {}
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String setterName = "s";
-    PropertyAccessorElement setter =
-        ElementFactory.setterElement(setterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[setter];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classB.lookUpSetter(setterName, library), same(setter));
-  }
-
-  void test_lookUpSetter_undeclared() {
-    // class A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA];
-    expect(classA.lookUpSetter("s", library), isNull);
-  }
-
-  void test_lookUpSetter_undeclared_recursive() {
-    // class A extends B {
-    // }
-    // class B extends A {
-    // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classA, classB];
-    expect(classA.lookUpSetter("s", library), isNull);
-  }
-}
-
-@reflectiveTest
-class CompilationUnitElementImplTest extends EngineTestCase {
-  void test_getElementAt() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    String code = r'''
-class A {
-  int field;
-}
-main() {
-  int localVar = 42;
-}
-''';
-    Source libSource = contextHelper.addSource("/my_lib.dart", code);
-    // prepare library/unit elements
-    LibraryElement libraryElement = context.computeLibraryElement(libSource);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // A
-    ClassElement elementA;
-    {
-      int offset = code.indexOf('A {');
-      elementA = unitElement.getElementAt(offset);
-      expect(elementA, isNotNull);
-      expect(elementA.enclosingElement, unitElement);
-      expect(elementA.name, 'A');
-    }
-    // A.field
-    {
-      int offset = code.indexOf('field;');
-      FieldElement element = unitElement.getElementAt(offset);
-      expect(element, isNotNull);
-      expect(element.enclosingElement, elementA);
-      expect(element.name, 'field');
-    }
-    // main
-    FunctionElement mainElement;
-    {
-      int offset = code.indexOf('main() {');
-      mainElement = unitElement.getElementAt(offset);
-      expect(mainElement, isNotNull);
-      expect(mainElement.enclosingElement, unitElement);
-      expect(mainElement.name, 'main');
-    }
-    // main.localVar
-    {
-      int offset = code.indexOf('localVar');
-      LocalVariableElement element = unitElement.getElementAt(offset);
-      expect(element, isNotNull);
-      expect(element.enclosingElement, mainElement);
-      expect(element.name, 'localVar');
-    }
-    // null
-    expect(unitElement.getElementAt(1000), isNull);
-  }
-
-  void test_getElementAt_multipleUnitsInLibrary() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source libSource = contextHelper.addSource(
-        "/my_lib.dart",
-        r'''
-library my_lib;
-part 'unit_a.dart';
-part 'unit_b.dart';
-''');
-    Source unitSourceA =
-        contextHelper.addSource("/unit_a.dart", 'part of my_lib;class A {}');
-    Source unitSourceB =
-        contextHelper.addSource("/unit_b.dart", 'part of my_lib;class B {}');
-    int offset = 'part of my_lib;class A {}'.indexOf('A {}');
-    // prepare library/unit elements
-    context.computeLibraryElement(libSource);
-    CompilationUnitElement unitElementA =
-        context.getCompilationUnitElement(unitSourceA, libSource);
-    CompilationUnitElement unitElementB =
-        context.getCompilationUnitElement(unitSourceB, libSource);
-    // A
-    {
-      ClassElement element = unitElementA.getElementAt(offset);
-      expect(element, isNotNull);
-      expect(element.enclosingElement, unitElementA);
-      expect(element.name, 'A');
-    }
-    // B
-    {
-      ClassElement element = unitElementB.getElementAt(offset);
-      expect(element, isNotNull);
-      expect(element.enclosingElement, unitElementB);
-      expect(element.name, 'B');
-    }
-  }
-
-  void test_getEnum_declared() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    CompilationUnitElementImpl unit =
-        ElementFactory.compilationUnit("/lib.dart");
-    String enumName = "E";
-    ClassElement enumElement =
-        ElementFactory.enumElement(typeProvider, enumName);
-    unit.enums = <ClassElement>[enumElement];
-    expect(unit.getEnum(enumName), same(enumElement));
-  }
-
-  void test_getEnum_undeclared() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    CompilationUnitElementImpl unit =
-        ElementFactory.compilationUnit("/lib.dart");
-    String enumName = "E";
-    ClassElement enumElement =
-        ElementFactory.enumElement(typeProvider, enumName);
-    unit.enums = <ClassElement>[enumElement];
-    expect(unit.getEnum("${enumName}x"), isNull);
-  }
-
-  void test_getType_declared() {
-    CompilationUnitElementImpl unit =
-        ElementFactory.compilationUnit("/lib.dart");
-    String className = "C";
-    ClassElement classElement = ElementFactory.classElement2(className);
-    unit.types = <ClassElement>[classElement];
-    expect(unit.getType(className), same(classElement));
-  }
-
-  void test_getType_undeclared() {
-    CompilationUnitElementImpl unit =
-        ElementFactory.compilationUnit("/lib.dart");
-    String className = "C";
-    ClassElement classElement = ElementFactory.classElement2(className);
-    unit.types = <ClassElement>[classElement];
-    expect(unit.getType("${className}x"), isNull);
-  }
-}
-
-@reflectiveTest
-class ElementImplTest extends EngineTestCase {
-  void test_equals() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElementImpl classElement = ElementFactory.classElement2("C");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classElement];
-    FieldElement field = ElementFactory.fieldElement(
-        "next", false, false, false, classElement.type);
-    classElement.fields = <FieldElement>[field];
-    expect(field == field, isTrue);
-    expect(field == field.getter, isFalse);
-    expect(field == field.setter, isFalse);
-    expect(field.getter == field.setter, isFalse);
-  }
-
-  void test_isAccessibleIn_private_differentLibrary() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
-    ClassElement classElement = ElementFactory.classElement2("_C");
-    (library1.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classElement];
-    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
-    expect(classElement.isAccessibleIn(library2), isFalse);
-  }
-
-  void test_isAccessibleIn_private_sameLibrary() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElement classElement = ElementFactory.classElement2("_C");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classElement];
-    expect(classElement.isAccessibleIn(library), isTrue);
-  }
-
-  void test_isAccessibleIn_public_differentLibrary() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
-    ClassElement classElement = ElementFactory.classElement2("C");
-    (library1.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classElement];
-    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
-    expect(classElement.isAccessibleIn(library2), isTrue);
-  }
-
-  void test_isAccessibleIn_public_sameLibrary() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    ClassElement classElement = ElementFactory.classElement2("C");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
-        <ClassElement>[classElement];
-    expect(classElement.isAccessibleIn(library), isTrue);
-  }
-
-  void test_isPrivate_false() {
-    Element element = ElementFactory.classElement2("C");
-    expect(element.isPrivate, isFalse);
-  }
-
-  void test_isPrivate_null() {
-    Element element = ElementFactory.classElement2(null);
-    expect(element.isPrivate, isTrue);
-  }
-
-  void test_isPrivate_true() {
-    Element element = ElementFactory.classElement2("_C");
-    expect(element.isPrivate, isTrue);
-  }
-
-  void test_isPublic_false() {
-    Element element = ElementFactory.classElement2("_C");
-    expect(element.isPublic, isFalse);
-  }
-
-  void test_isPublic_null() {
-    Element element = ElementFactory.classElement2(null);
-    expect(element.isPublic, isFalse);
-  }
-
-  void test_isPublic_true() {
-    Element element = ElementFactory.classElement2("C");
-    expect(element.isPublic, isTrue);
-  }
-
-  void test_SORT_BY_OFFSET() {
-    ClassElementImpl classElementA = ElementFactory.classElement2("A");
-    classElementA.nameOffset = 1;
-    ClassElementImpl classElementB = ElementFactory.classElement2("B");
-    classElementB.nameOffset = 2;
-    expect(Element.SORT_BY_OFFSET(classElementA, classElementA), 0);
-    expect(Element.SORT_BY_OFFSET(classElementA, classElementB) < 0, isTrue);
-    expect(Element.SORT_BY_OFFSET(classElementB, classElementA) > 0, isTrue);
-  }
-}
-
-@reflectiveTest
-class ElementKindTest extends EngineTestCase {
-  void test_of_nonNull() {
-    expect(ElementKind.of(ElementFactory.classElement2("A")),
-        same(ElementKind.CLASS));
-  }
-
-  void test_of_null() {
-    expect(ElementKind.of(null), same(ElementKind.ERROR));
-  }
-}
-
-@reflectiveTest
-class ElementLocationImplTest extends EngineTestCase {
-  void test_create_encoding() {
-    String encoding = "a;b;c";
-    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
-    expect(location.encoding, encoding);
-  }
-
-  /**
-   * For example unnamed constructor.
-   */
-  void test_create_encoding_emptyLast() {
-    String encoding = "a;b;c;";
-    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
-    expect(location.encoding, encoding);
-  }
-
-  void test_equals_equal() {
-    String encoding = "a;b;c";
-    ElementLocationImpl first = new ElementLocationImpl.con2(encoding);
-    ElementLocationImpl second = new ElementLocationImpl.con2(encoding);
-    expect(first == second, isTrue);
-  }
-
-  void test_equals_notEqual_differentLengths() {
-    ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
-    ElementLocationImpl second = new ElementLocationImpl.con2("a;b;c;d");
-    expect(first == second, isFalse);
-  }
-
-  void test_equals_notEqual_notLocation() {
-    ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
-    expect(first == "a;b;d", isFalse);
-  }
-
-  void test_equals_notEqual_sameLengths() {
-    ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
-    ElementLocationImpl second = new ElementLocationImpl.con2("a;b;d");
-    expect(first == second, isFalse);
-  }
-
-  void test_getComponents() {
-    String encoding = "a;b;c";
-    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
-    List<String> components = location.components;
-    expect(components, hasLength(3));
-    expect(components[0], "a");
-    expect(components[1], "b");
-    expect(components[2], "c");
-  }
-
-  void test_getEncoding() {
-    String encoding = "a;b;c;;d";
-    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
-    expect(location.encoding, encoding);
-  }
-
-  void test_hashCode_equal() {
-    String encoding = "a;b;c";
-    ElementLocationImpl first = new ElementLocationImpl.con2(encoding);
-    ElementLocationImpl second = new ElementLocationImpl.con2(encoding);
-    expect(first.hashCode == second.hashCode, isTrue);
-  }
-}
-
-@reflectiveTest
-class FieldElementImplTest extends EngineTestCase {
-  void test_computeNode() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource(
-        "/test.dart",
-        r'''
-class A {
-  int a;
-}
-enum B {B1, B2, B3}''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // A
-    {
-      FieldElement elementA = unitElement.getType("A").getField('a');
-      VariableDeclaration nodeA = elementA.computeNode();
-      expect(nodeA, isNotNull);
-      expect(nodeA.name.name, "a");
-      expect(nodeA.element, same(elementA));
-    }
-    // B
-    {
-      FieldElement elementB = unitElement.getEnum("B").getField('B2');
-      EnumConstantDeclaration nodeB = elementB.computeNode();
-      expect(nodeB, isNotNull);
-      expect(nodeB.name.name, "B2");
-      expect(nodeB.element, same(elementB));
-    }
-  }
-}
-
-@reflectiveTest
-class FunctionTypeImplTest extends EngineTestCase {
-  void test_creation() {
-    expect(
-        new FunctionTypeImpl(
-            new FunctionElementImpl.forNode(AstFactory.identifier3("f"))),
-        isNotNull);
-  }
-
-  void test_equality_recursive() {
-    FunctionTypeAliasElementImpl s =
-        ElementFactory.functionTypeAliasElement('s');
-    FunctionTypeAliasElementImpl t =
-        ElementFactory.functionTypeAliasElement('t');
-    FunctionTypeAliasElementImpl u =
-        ElementFactory.functionTypeAliasElement('u');
-    FunctionTypeAliasElementImpl v =
-        ElementFactory.functionTypeAliasElement('v');
-    s.returnType = t.type;
-    t.returnType = s.type;
-    u.returnType = v.type;
-    v.returnType = u.type;
-    // We don't care whether the types compare equal or not.  We just need the
-    // computation to terminate.
-    expect(s.type == u.type, new isInstanceOf<bool>());
-  }
-
-  void test_getElement() {
-    FunctionElementImpl typeElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
-    FunctionTypeImpl type = new FunctionTypeImpl(typeElement);
-    expect(type.element, typeElement);
-  }
-
-  void test_getNamedParameterTypes() {
-    FunctionTypeImpl type = new FunctionTypeImpl(
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
-    Map<String, DartType> types = type.namedParameterTypes;
-    expect(types, hasLength(0));
-  }
-
-  void test_getNormalParameterTypes() {
-    FunctionTypeImpl type = new FunctionTypeImpl(
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
-    List<DartType> types = type.normalParameterTypes;
-    expect(types, hasLength(0));
-  }
-
-  void test_getReturnType() {
-    DartType expectedReturnType = VoidTypeImpl.instance;
-    FunctionElementImpl functionElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
-    functionElement.returnType = expectedReturnType;
-    FunctionTypeImpl type = new FunctionTypeImpl(functionElement);
-    DartType returnType = type.returnType;
-    expect(returnType, expectedReturnType);
-  }
-
-  void test_getTypeArguments() {
-    FunctionTypeImpl type = new FunctionTypeImpl(
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
-    List<DartType> types = type.typeArguments;
-    expect(types, hasLength(0));
-  }
-
-  void test_hashCode_element() {
-    FunctionTypeImpl type = new FunctionTypeImpl(
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
-    type.hashCode;
-  }
-
-  void test_hashCode_noElement() {
-    FunctionTypeImpl type = new FunctionTypeImpl(null);
-    type.hashCode;
-  }
-
-  void test_hashCode_recursive() {
-    FunctionTypeAliasElementImpl s =
-        ElementFactory.functionTypeAliasElement('s');
-    FunctionTypeAliasElementImpl t =
-        ElementFactory.functionTypeAliasElement('t');
-    s.returnType = t.type;
-    t.returnType = s.type;
-    // We don't care what the hash code is.  We just need its computation to
-    // terminate.
-    expect(t.type.hashCode, new isInstanceOf<int>());
-  }
-
-  void test_isAssignableTo_normalAndPositionalArgs() {
-    // ([a]) -> void <: (a) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    FunctionType t =
-        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
-    FunctionType s =
-        ElementFactory.functionElement5("s", <ClassElement>[a]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-    expect(s.isSubtypeOf(t), isFalse);
-    // assignable iff subtype
-    expect(t.isAssignableTo(s), isTrue);
-    expect(s.isAssignableTo(t), isFalse);
-  }
-
-  void test_isSubtypeOf_baseCase_classFunction() {
-    // () -> void <: Function
-    ClassElementImpl functionElement = ElementFactory.classElement2("Function");
-    InterfaceTypeImpl functionType =
-        new _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction(
-            functionElement);
-    FunctionType f = ElementFactory.functionElement("f").type;
-    expect(f.isSubtypeOf(functionType), isTrue);
-  }
-
-  void test_isSubtypeOf_baseCase_notFunctionType() {
-    // class C
-    // ! () -> void <: C
-    FunctionType f = ElementFactory.functionElement("f").type;
-    InterfaceType t = ElementFactory.classElement2("C").type;
-    expect(f.isSubtypeOf(t), isFalse);
-  }
-
-  void test_isSubtypeOf_baseCase_null() {
-    // ! () -> void <: null
-    FunctionType f = ElementFactory.functionElement("f").type;
-    expect(f.isSubtypeOf(null), isFalse);
-  }
-
-  void test_isSubtypeOf_baseCase_self() {
-    // () -> void <: () -> void
-    FunctionType f = ElementFactory.functionElement("f").type;
-    expect(f.isSubtypeOf(f), isTrue);
-  }
-
-  void test_isSubtypeOf_namedParameters_isAssignable() {
-    // B extends A
-    // ({name: A}) -> void <: ({name: B}) -> void
-    // ({name: B}) -> void <: ({name: A}) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t = ElementFactory.functionElement4(
-        "t", null, null, <String>["name"], <ClassElement>[a]).type;
-    FunctionType s = ElementFactory.functionElement4(
-        "s", null, null, <String>["name"], <ClassElement>[b]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-    expect(s.isSubtypeOf(t), isTrue);
-  }
-
-  void test_isSubtypeOf_namedParameters_isNotAssignable() {
-    // ! ({name: A}) -> void <: ({name: B}) -> void
-    FunctionType t = ElementFactory.functionElement4(
-        "t",
-        null,
-        null,
-        <String>["name"],
-        <ClassElement>[ElementFactory.classElement2("A")]).type;
-    FunctionType s = ElementFactory.functionElement4(
-        "s",
-        null,
-        null,
-        <String>["name"],
-        <ClassElement>[ElementFactory.classElement2("B")]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-  }
-
-  void test_isSubtypeOf_namedParameters_namesDifferent() {
-    // B extends A
-    // void t({A name}) {}
-    // void s({A diff}) {}
-    // ! t <: s
-    // ! s <: t
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t = ElementFactory.functionElement4(
-        "t", null, null, <String>["name"], <ClassElement>[a]).type;
-    FunctionType s = ElementFactory.functionElement4(
-        "s", null, null, <String>["diff"], <ClassElement>[b]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-    expect(s.isSubtypeOf(t), isFalse);
-  }
-
-  void test_isSubtypeOf_namedParameters_orderOfParams() {
-    // B extends A
-    // ({A: A, B: B}) -> void <: ({B: B, A: A}) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t = ElementFactory.functionElement4(
-        "t", null, null, <String>["A", "B"], <ClassElement>[a, b]).type;
-    FunctionType s = ElementFactory.functionElement4(
-        "s", null, null, <String>["B", "A"], <ClassElement>[b, a]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-  }
-
-  void test_isSubtypeOf_namedParameters_orderOfParams2() {
-    // B extends A
-    // ! ({B: B}) -> void <: ({B: B, A: A}) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t = ElementFactory.functionElement4(
-        "t", null, null, <String>["B"], <ClassElement>[b]).type;
-    FunctionType s = ElementFactory.functionElement4(
-        "s", null, null, <String>["B", "A"], <ClassElement>[b, a]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-  }
-
-  void test_isSubtypeOf_namedParameters_orderOfParams3() {
-    // B extends A
-    // ({A: A, B: B}) -> void <: ({A: A}) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t = ElementFactory.functionElement4(
-        "t", null, null, <String>["A", "B"], <ClassElement>[a, b]).type;
-    FunctionType s = ElementFactory.functionElement4(
-        "s", null, null, <String>["B"], <ClassElement>[b]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-  }
-
-  void test_isSubtypeOf_namedParameters_sHasMoreParams() {
-    // B extends A
-    // ! ({name: A}) -> void <: ({name: B, name2: B}) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t = ElementFactory.functionElement4(
-        "t", null, null, <String>["name"], <ClassElement>[a]).type;
-    FunctionType s = ElementFactory.functionElement4(
-        "s", null, null, <String>["name", "name2"], <ClassElement>[b, b]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-  }
-
-  void test_isSubtypeOf_namedParameters_tHasMoreParams() {
-    // B extends A
-    // ({name: A, name2: A}) -> void <: ({name: B}) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t = ElementFactory.functionElement4(
-        "t", null, null, <String>["name", "name2"], <ClassElement>[a, a]).type;
-    FunctionType s = ElementFactory.functionElement4(
-        "s", null, null, <String>["name"], <ClassElement>[b]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-  }
-
-  void test_isSubtypeOf_normalAndPositionalArgs_1() {
-    // ([a]) -> void <: (a) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    FunctionType t =
-        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
-    FunctionType s =
-        ElementFactory.functionElement5("s", <ClassElement>[a]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-    expect(s.isSubtypeOf(t), isFalse);
-  }
-
-  void test_isSubtypeOf_normalAndPositionalArgs_2() {
-    // (a, [a]) -> void <: (a) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    FunctionType t = ElementFactory
-        .functionElement6("t", <ClassElement>[a], <ClassElement>[a]).type;
-    FunctionType s =
-        ElementFactory.functionElement5("s", <ClassElement>[a]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-    expect(s.isSubtypeOf(t), isFalse);
-  }
-
-  void test_isSubtypeOf_normalAndPositionalArgs_3() {
-    // ([a]) -> void <: () -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    FunctionType t =
-        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
-    FunctionType s = ElementFactory.functionElement("s").type;
-    expect(t.isSubtypeOf(s), isTrue);
-    expect(s.isSubtypeOf(t), isFalse);
-  }
-
-  void test_isSubtypeOf_normalAndPositionalArgs_4() {
-    // (a, b, [c, d, e]) -> void <: (a, b, c, [d]) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement2("B");
-    ClassElement c = ElementFactory.classElement2("C");
-    ClassElement d = ElementFactory.classElement2("D");
-    ClassElement e = ElementFactory.classElement2("E");
-    FunctionType t = ElementFactory.functionElement6(
-        "t", <ClassElement>[a, b], <ClassElement>[c, d, e]).type;
-    FunctionType s = ElementFactory
-        .functionElement6("s", <ClassElement>[a, b, c], <ClassElement>[d]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-    expect(s.isSubtypeOf(t), isFalse);
-  }
-
-  void test_isSubtypeOf_normalParameters_isAssignable() {
-    // B extends A
-    // (a) -> void <: (b) -> void
-    // (b) -> void <: (a) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t =
-        ElementFactory.functionElement5("t", <ClassElement>[a]).type;
-    FunctionType s =
-        ElementFactory.functionElement5("s", <ClassElement>[b]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-    expect(s.isSubtypeOf(t), isTrue);
-  }
-
-  void test_isSubtypeOf_normalParameters_isNotAssignable() {
-    // ! (a) -> void <: (b) -> void
-    FunctionType t = ElementFactory.functionElement5(
-        "t", <ClassElement>[ElementFactory.classElement2("A")]).type;
-    FunctionType s = ElementFactory.functionElement5(
-        "s", <ClassElement>[ElementFactory.classElement2("B")]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-  }
-
-  void test_isSubtypeOf_normalParameters_sHasMoreParams() {
-    // B extends A
-    // ! (a) -> void <: (b, b) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t =
-        ElementFactory.functionElement5("t", <ClassElement>[a]).type;
-    FunctionType s =
-        ElementFactory.functionElement5("s", <ClassElement>[b, b]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-  }
-
-  void test_isSubtypeOf_normalParameters_tHasMoreParams() {
-    // B extends A
-    // ! (a, a) -> void <: (a) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t =
-        ElementFactory.functionElement5("t", <ClassElement>[a, a]).type;
-    FunctionType s =
-        ElementFactory.functionElement5("s", <ClassElement>[b]).type;
-    // note, this is a different assertion from the other "tHasMoreParams"
-    // tests, this is intentional as it is a difference of the "normal
-    // parameters"
-    expect(t.isSubtypeOf(s), isFalse);
-  }
-
-  void test_isSubtypeOf_Object() {
-    // () -> void <: Object
-    FunctionType f = ElementFactory.functionElement("f").type;
-    InterfaceType t = ElementFactory.object.type;
-    expect(f.isSubtypeOf(t), isTrue);
-  }
-
-  void test_isSubtypeOf_positionalParameters_isAssignable() {
-    // B extends A
-    // ([a]) -> void <: ([b]) -> void
-    // ([b]) -> void <: ([a]) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t =
-        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
-    FunctionType s =
-        ElementFactory.functionElement6("s", null, <ClassElement>[b]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-    expect(s.isSubtypeOf(t), isTrue);
-  }
-
-  void test_isSubtypeOf_positionalParameters_isNotAssignable() {
-    // ! ([a]) -> void <: ([b]) -> void
-    FunctionType t = ElementFactory.functionElement6(
-        "t", null, <ClassElement>[ElementFactory.classElement2("A")]).type;
-    FunctionType s = ElementFactory.functionElement6(
-        "s", null, <ClassElement>[ElementFactory.classElement2("B")]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-  }
-
-  void test_isSubtypeOf_positionalParameters_sHasMoreParams() {
-    // B extends A
-    // ! ([a]) -> void <: ([b, b]) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t =
-        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
-    FunctionType s =
-        ElementFactory.functionElement6("s", null, <ClassElement>[b, b]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-  }
-
-  void test_isSubtypeOf_positionalParameters_tHasMoreParams() {
-    // B extends A
-    // ([a, a]) -> void <: ([b]) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t =
-        ElementFactory.functionElement6("t", null, <ClassElement>[a, a]).type;
-    FunctionType s =
-        ElementFactory.functionElement6("s", null, <ClassElement>[b]).type;
-    expect(t.isSubtypeOf(s), isTrue);
-  }
-
-  void test_isSubtypeOf_returnType_sIsVoid() {
-    // () -> void <: void
-    FunctionType t = ElementFactory.functionElement("t").type;
-    FunctionType s = ElementFactory.functionElement("s").type;
-    // function s has the implicit return type of void, we assert it here
-    expect(VoidTypeImpl.instance == s.returnType, isTrue);
-    expect(t.isSubtypeOf(s), isTrue);
-  }
-
-  void test_isSubtypeOf_returnType_tAssignableToS() {
-    // B extends A
-    // () -> A <: () -> B
-    // () -> B <: () -> A
-    ClassElement a = ElementFactory.classElement2("A");
-    ClassElement b = ElementFactory.classElement("B", a.type);
-    FunctionType t = ElementFactory.functionElement2("t", a).type;
-    FunctionType s = ElementFactory.functionElement2("s", b).type;
-    expect(t.isSubtypeOf(s), isTrue);
-    expect(s.isSubtypeOf(t), isTrue);
-  }
-
-  void test_isSubtypeOf_returnType_tNotAssignableToS() {
-    // ! () -> A <: () -> B
-    FunctionType t = ElementFactory
-        .functionElement2("t", ElementFactory.classElement2("A"))
-        .type;
-    FunctionType s = ElementFactory
-        .functionElement2("s", ElementFactory.classElement2("B"))
-        .type;
-    expect(t.isSubtypeOf(s), isFalse);
-  }
-
-  void test_isSubtypeOf_typeParameters_matchesBounds() {
-    TestTypeProvider provider = new TestTypeProvider();
-    InterfaceType boolType = provider.boolType;
-    InterfaceType stringType = provider.stringType;
-    TypeParameterElementImpl parameterB =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("B"));
-    parameterB.bound = boolType;
-    TypeParameterTypeImpl typeB = new TypeParameterTypeImpl(parameterB);
-    TypeParameterElementImpl parameterS =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("S"));
-    parameterS.bound = stringType;
-    TypeParameterTypeImpl typeS = new TypeParameterTypeImpl(parameterS);
-    FunctionElementImpl functionAliasElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("func"));
-    functionAliasElement.parameters = <ParameterElement>[
-      ElementFactory.requiredParameter2("a", typeB),
-      ElementFactory.positionalParameter2("b", typeS)
-    ];
-    functionAliasElement.returnType = stringType;
-    FunctionTypeImpl functionAliasType =
-        new FunctionTypeImpl(functionAliasElement);
-    functionAliasElement.type = functionAliasType;
-    FunctionElementImpl functionElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
-    functionElement.parameters = <ParameterElement>[
-      ElementFactory.requiredParameter2("c", boolType),
-      ElementFactory.positionalParameter2("d", stringType)
-    ];
-    functionElement.returnType = provider.dynamicType;
-    FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
-    functionElement.type = functionType;
-    expect(functionType.isAssignableTo(functionAliasType), isTrue);
-  }
-
-  void test_isSubtypeOf_wrongFunctionType_normal_named() {
-    // ! (a) -> void <: ({name: A}) -> void
-    // ! ({name: A}) -> void <: (a) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    FunctionType t =
-        ElementFactory.functionElement5("t", <ClassElement>[a]).type;
-    FunctionType s = ElementFactory
-        .functionElement7("s", null, <String>["name"], <ClassElement>[a]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-    expect(s.isSubtypeOf(t), isFalse);
-  }
-
-  void test_isSubtypeOf_wrongFunctionType_optional_named() {
-    // ! ([a]) -> void <: ({name: A}) -> void
-    // ! ({name: A}) -> void <: ([a]) -> void
-    ClassElement a = ElementFactory.classElement2("A");
-    FunctionType t =
-        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
-    FunctionType s = ElementFactory
-        .functionElement7("s", null, <String>["name"], <ClassElement>[a]).type;
-    expect(t.isSubtypeOf(s), isFalse);
-    expect(s.isSubtypeOf(t), isFalse);
-  }
-
-  void test_namedParameterTypes_pruned_no_type_arguments() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeAliasElementImpl g =
-        ElementFactory.functionTypeAliasElement('g');
-    f.parameters = [ElementFactory.namedParameter2('x', g.type)];
-    FunctionTypeImpl paramType = f.type.namedParameterTypes['x'];
-    expect(paramType.prunedTypedefs, hasLength(1));
-    expect(paramType.prunedTypedefs[0], same(f));
-  }
-
-  void test_namedParameterTypes_pruned_with_type_arguments() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeAliasElementImpl g =
-        ElementFactory.functionTypeAliasElement('g');
-    f.typeParameters = [ElementFactory.typeParameterElement('T')];
-    f.parameters = [ElementFactory.namedParameter2('x', g.type)];
-    FunctionTypeImpl paramType = f.type.namedParameterTypes['x'];
-    expect(paramType.prunedTypedefs, hasLength(1));
-    expect(paramType.prunedTypedefs[0], same(f));
-  }
-
-  void test_newPrune_no_previous_prune() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeImpl type = f.type;
-    List<FunctionTypeAliasElement> pruneList = type.newPrune;
-    expect(pruneList, hasLength(1));
-    expect(pruneList[0], same(f));
-  }
-
-  void test_newPrune_non_typedef() {
-    // No pruning needs to be done for function types that aren't associated
-    // with typedefs because those types can't be directly referred to by the
-    // user (and hence can't participate in circularities).
-    FunctionElementImpl f = ElementFactory.functionElement('f');
-    FunctionTypeImpl type = f.type;
-    expect(type.newPrune, isNull);
-  }
-
-  void test_newPrune_synthetic_typedef() {
-    // No pruning needs to be done for function types that are associated with
-    // synthetic typedefs because those types are only created for
-    // function-typed formal parameters, which can't be directly referred to by
-    // the user (and hence can't participate in circularities).
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    f.synthetic = true;
-    FunctionTypeImpl type = f.type;
-    expect(type.newPrune, isNull);
-  }
-
-  void test_newPrune_with_previous_prune() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeAliasElementImpl g =
-        ElementFactory.functionTypeAliasElement('g');
-    FunctionTypeImpl type = f.type;
-    FunctionTypeImpl prunedType = type.pruned([g]);
-    List<FunctionTypeAliasElement> pruneList = prunedType.newPrune;
-    expect(pruneList, hasLength(2));
-    expect(pruneList, contains(f));
-    expect(pruneList, contains(g));
-  }
-
-  void test_normalParameterTypes_pruned_no_type_arguments() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeAliasElementImpl g =
-        ElementFactory.functionTypeAliasElement('g');
-    f.parameters = [ElementFactory.requiredParameter2('x', g.type)];
-    FunctionTypeImpl paramType = f.type.normalParameterTypes[0];
-    expect(paramType.prunedTypedefs, hasLength(1));
-    expect(paramType.prunedTypedefs[0], same(f));
-  }
-
-  void test_normalParameterTypes_pruned_with_type_arguments() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeAliasElementImpl g =
-        ElementFactory.functionTypeAliasElement('g');
-    f.typeParameters = [ElementFactory.typeParameterElement('T')];
-    f.parameters = [ElementFactory.requiredParameter2('x', g.type)];
-    FunctionTypeImpl paramType = f.type.normalParameterTypes[0];
-    expect(paramType.prunedTypedefs, hasLength(1));
-    expect(paramType.prunedTypedefs[0], same(f));
-  }
-
-  void test_optionalParameterTypes_pruned_no_type_arguments() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeAliasElementImpl g =
-        ElementFactory.functionTypeAliasElement('g');
-    f.parameters = [ElementFactory.positionalParameter2('x', g.type)];
-    FunctionTypeImpl paramType = f.type.optionalParameterTypes[0];
-    expect(paramType.prunedTypedefs, hasLength(1));
-    expect(paramType.prunedTypedefs[0], same(f));
-  }
-
-  void test_optionalParameterTypes_pruned_with_type_arguments() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeAliasElementImpl g =
-        ElementFactory.functionTypeAliasElement('g');
-    f.typeParameters = [ElementFactory.typeParameterElement('T')];
-    f.parameters = [ElementFactory.positionalParameter2('x', g.type)];
-    FunctionTypeImpl paramType = f.type.optionalParameterTypes[0];
-    expect(paramType.prunedTypedefs, hasLength(1));
-    expect(paramType.prunedTypedefs[0], same(f));
-  }
-
-  void test_returnType_pruned_no_type_arguments() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeAliasElementImpl g =
-        ElementFactory.functionTypeAliasElement('g');
-    f.returnType = g.type;
-    FunctionTypeImpl paramType = f.type.returnType;
-    expect(paramType.prunedTypedefs, hasLength(1));
-    expect(paramType.prunedTypedefs[0], same(f));
-  }
-
-  void test_returnType_pruned_with_type_arguments() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    FunctionTypeAliasElementImpl g =
-        ElementFactory.functionTypeAliasElement('g');
-    f.typeParameters = [ElementFactory.typeParameterElement('T')];
-    f.returnType = g.type;
-    FunctionTypeImpl paramType = f.type.returnType;
-    expect(paramType.prunedTypedefs, hasLength(1));
-    expect(paramType.prunedTypedefs[0], same(f));
-  }
-
-  void test_setTypeArguments() {
-    ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
-    MethodElementImpl methodElement =
-        new MethodElementImpl.forNode(AstFactory.identifier3("m"));
-    enclosingClass.methods = <MethodElement>[methodElement];
-    FunctionTypeImpl type = new FunctionTypeImpl(methodElement);
-    DartType expectedType = enclosingClass.typeParameters[0].type;
-    type.typeArguments = <DartType>[expectedType];
-    List<DartType> arguments = type.typeArguments;
-    expect(arguments, hasLength(1));
-    expect(arguments[0], expectedType);
-  }
-
-  void test_substitute2_equal() {
-    ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
-    TypeParameterType parameterType = definingClass.typeParameters[0].type;
-    MethodElementImpl functionElement =
-        new MethodElementImpl.forNode(AstFactory.identifier3("m"));
-    String namedParameterName = "c";
-    functionElement.parameters = <ParameterElement>[
-      ElementFactory.requiredParameter2("a", parameterType),
-      ElementFactory.positionalParameter2("b", parameterType),
-      ElementFactory.namedParameter2(namedParameterName, parameterType)
-    ];
-    functionElement.returnType = parameterType;
-    definingClass.methods = <MethodElement>[functionElement];
-    FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
-    functionType.typeArguments = <DartType>[parameterType];
-    InterfaceTypeImpl argumentType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("D")));
-    FunctionType result = functionType.substitute2(
-        <DartType>[argumentType], <DartType>[parameterType]);
-    expect(result.returnType, argumentType);
-    List<DartType> normalParameters = result.normalParameterTypes;
-    expect(normalParameters, hasLength(1));
-    expect(normalParameters[0], argumentType);
-    List<DartType> optionalParameters = result.optionalParameterTypes;
-    expect(optionalParameters, hasLength(1));
-    expect(optionalParameters[0], argumentType);
-    Map<String, DartType> namedParameters = result.namedParameterTypes;
-    expect(namedParameters, hasLength(1));
-    expect(namedParameters[namedParameterName], argumentType);
-  }
-
-  void test_substitute2_notEqual() {
-    DartType returnType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("R")));
-    DartType normalParameterType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("A")));
-    DartType optionalParameterType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("B")));
-    DartType namedParameterType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("C")));
-    FunctionElementImpl functionElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
-    String namedParameterName = "c";
-    functionElement.parameters = <ParameterElement>[
-      ElementFactory.requiredParameter2("a", normalParameterType),
-      ElementFactory.positionalParameter2("b", optionalParameterType),
-      ElementFactory.namedParameter2(namedParameterName, namedParameterType)
-    ];
-    functionElement.returnType = returnType;
-    FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
-    InterfaceTypeImpl argumentType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("D")));
-    TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
-    FunctionType result = functionType.substitute2(
-        <DartType>[argumentType], <DartType>[parameterType]);
-    expect(result.returnType, returnType);
-    List<DartType> normalParameters = result.normalParameterTypes;
-    expect(normalParameters, hasLength(1));
-    expect(normalParameters[0], normalParameterType);
-    List<DartType> optionalParameters = result.optionalParameterTypes;
-    expect(optionalParameters, hasLength(1));
-    expect(optionalParameters[0], optionalParameterType);
-    Map<String, DartType> namedParameters = result.namedParameterTypes;
-    expect(namedParameters, hasLength(1));
-    expect(namedParameters[namedParameterName], namedParameterType);
-  }
-
-  void test_toString_recursive() {
-    FunctionTypeAliasElementImpl t =
-        ElementFactory.functionTypeAliasElement("t");
-    FunctionTypeAliasElementImpl s =
-        ElementFactory.functionTypeAliasElement("s");
-    t.returnType = s.type;
-    s.returnType = t.type;
-    expect(t.type.toString(), '() \u2192 () \u2192 ...');
-  }
-
-  void test_toString_recursive_via_interface_type() {
-    FunctionTypeAliasElementImpl f =
-        ElementFactory.functionTypeAliasElement('f');
-    ClassElementImpl c = ElementFactory.classElement2('C', ['T']);
-    f.returnType = c.type.substitute4([f.type]);
-    expect(f.type.toString(), '() \u2192 C<...>');
-  }
-}
-
-@reflectiveTest
-class HtmlElementImplTest extends EngineTestCase {
-  void test_equals_differentSource() {
-    AnalysisContext context = createAnalysisContext();
-    HtmlElementImpl elementA = ElementFactory.htmlUnit(context, "indexA.html");
-    HtmlElementImpl elementB = ElementFactory.htmlUnit(context, "indexB.html");
-    expect(elementA == elementB, isFalse);
-  }
-
-  void test_equals_null() {
-    AnalysisContext context = createAnalysisContext();
-    HtmlElementImpl element = ElementFactory.htmlUnit(context, "index.html");
-    expect(element == null, isFalse);
-  }
-
-  void test_equals_sameSource() {
-    AnalysisContext context = createAnalysisContext();
-    HtmlElementImpl elementA = ElementFactory.htmlUnit(context, "index.html");
-    HtmlElementImpl elementB = ElementFactory.htmlUnit(context, "index.html");
-    expect(elementA == elementB, isTrue);
-  }
-
-  void test_equals_self() {
-    AnalysisContext context = createAnalysisContext();
-    HtmlElementImpl element = ElementFactory.htmlUnit(context, "index.html");
-    expect(element == element, isTrue);
-  }
-}
-
-@reflectiveTest
-class InterfaceTypeImplTest extends EngineTestCase {
-  /**
-   * The type provider used to access the types.
-   */
-  TestTypeProvider _typeProvider;
-
-  @override
-  void setUp() {
-    _typeProvider = new TestTypeProvider();
-  }
-
-  void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
-    //
-    //   Object
-    //     |
-    //     A
-    //    / \
-    //   B   C
-    //   |   |
-    //   |   D
-    //    \ /
-    //     E
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    ClassElementImpl classD = ElementFactory.classElement2("D");
-    ClassElementImpl classE = ElementFactory.classElement2("E");
-    classB.interfaces = <InterfaceType>[classA.type];
-    classC.interfaces = <InterfaceType>[classA.type];
-    classD.interfaces = <InterfaceType>[classC.type];
-    classE.interfaces = <InterfaceType>[classB.type, classD.type];
-    // assertion: even though the longest path to Object for typeB is 2, and
-    // typeE implements typeB, the longest path for typeE is 4 since it also
-    // implements typeD
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
-        2);
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type),
-        4);
-  }
-
-  void test_computeLongestInheritancePathToObject_multipleSuperclassPaths() {
-    //
-    //   Object
-    //     |
-    //     A
-    //    / \
-    //   B   C
-    //   |   |
-    //   |   D
-    //    \ /
-    //     E
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElement classC = ElementFactory.classElement("C", classA.type);
-    ClassElement classD = ElementFactory.classElement("D", classC.type);
-    ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
-    classE.interfaces = <InterfaceType>[classD.type];
-    // assertion: even though the longest path to Object for typeB is 2, and
-    // typeE extends typeB, the longest path for typeE is 4 since it also
-    // implements typeD
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
-        2);
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type),
-        4);
-  }
-
-  void test_computeLongestInheritancePathToObject_object() {
-    //
-    //   Object
-    //     |
-    //     A
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType object = classA.supertype;
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(object), 0);
-  }
-
-  void test_computeLongestInheritancePathToObject_recursion() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type),
-        2);
-  }
-
-  void test_computeLongestInheritancePathToObject_singleInterfacePath() {
-    //
-    //   Object
-    //     |
-    //     A
-    //     |
-    //     B
-    //     |
-    //     C
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    classB.interfaces = <InterfaceType>[classA.type];
-    classC.interfaces = <InterfaceType>[classB.type];
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type),
-        1);
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
-        2);
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classC.type),
-        3);
-  }
-
-  void test_computeLongestInheritancePathToObject_singleSuperclassPath() {
-    //
-    //   Object
-    //     |
-    //     A
-    //     |
-    //     B
-    //     |
-    //     C
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElement classC = ElementFactory.classElement("C", classB.type);
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type),
-        1);
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
-        2);
-    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classC.type),
-        3);
-  }
-
-  void test_computeSuperinterfaceSet_genericInterfacePath() {
-    //
-    //  A
-    //  | implements
-    //  B<T>
-    //  | implements
-    //  C<T>
-    //
-    //  D
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B", ["T"]);
-    ClassElementImpl classC = ElementFactory.classElement2("C", ["T"]);
-    ClassElement classD = ElementFactory.classElement2("D");
-    InterfaceType typeA = classA.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    InterfaceTypeImpl typeBT = new InterfaceTypeImpl(classB);
-    DartType typeT = classC.type.typeArguments[0];
-    typeBT.typeArguments = <DartType>[typeT];
-    classC.interfaces = <InterfaceType>[typeBT];
-    // A
-    Set<InterfaceType> superinterfacesOfA =
-        InterfaceTypeImpl.computeSuperinterfaceSet(typeA);
-    expect(superinterfacesOfA, hasLength(1));
-    InterfaceType typeObject = ElementFactory.object.type;
-    expect(superinterfacesOfA.contains(typeObject), isTrue);
-    // B<D>
-    InterfaceTypeImpl typeBD = new InterfaceTypeImpl(classB);
-    typeBD.typeArguments = <DartType>[classD.type];
-    Set<InterfaceType> superinterfacesOfBD =
-        InterfaceTypeImpl.computeSuperinterfaceSet(typeBD);
-    expect(superinterfacesOfBD, hasLength(2));
-    expect(superinterfacesOfBD.contains(typeObject), isTrue);
-    expect(superinterfacesOfBD.contains(typeA), isTrue);
-    // C<D>
-    InterfaceTypeImpl typeCD = new InterfaceTypeImpl(classC);
-    typeCD.typeArguments = <DartType>[classD.type];
-    Set<InterfaceType> superinterfacesOfCD =
-        InterfaceTypeImpl.computeSuperinterfaceSet(typeCD);
-    expect(superinterfacesOfCD, hasLength(3));
-    expect(superinterfacesOfCD.contains(typeObject), isTrue);
-    expect(superinterfacesOfCD.contains(typeA), isTrue);
-    expect(superinterfacesOfCD.contains(typeBD), isTrue);
-  }
-
-  void test_computeSuperinterfaceSet_genericSuperclassPath() {
-    //
-    //  A
-    //  |
-    //  B<T>
-    //  |
-    //  C<T>
-    //
-    //  D
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    ClassElement classB = ElementFactory.classElement("B", typeA, ["T"]);
-    ClassElementImpl classC = ElementFactory.classElement2("C", ["T"]);
-    InterfaceTypeImpl typeBT = new InterfaceTypeImpl(classB);
-    DartType typeT = classC.type.typeArguments[0];
-    typeBT.typeArguments = <DartType>[typeT];
-    classC.supertype = typeBT;
-    ClassElement classD = ElementFactory.classElement2("D");
-    // A
-    Set<InterfaceType> superinterfacesOfA =
-        InterfaceTypeImpl.computeSuperinterfaceSet(typeA);
-    expect(superinterfacesOfA, hasLength(1));
-    InterfaceType typeObject = ElementFactory.object.type;
-    expect(superinterfacesOfA.contains(typeObject), isTrue);
-    // B<D>
-    InterfaceTypeImpl typeBD = new InterfaceTypeImpl(classB);
-    typeBD.typeArguments = <DartType>[classD.type];
-    Set<InterfaceType> superinterfacesOfBD =
-        InterfaceTypeImpl.computeSuperinterfaceSet(typeBD);
-    expect(superinterfacesOfBD, hasLength(2));
-    expect(superinterfacesOfBD.contains(typeObject), isTrue);
-    expect(superinterfacesOfBD.contains(typeA), isTrue);
-    // C<D>
-    InterfaceTypeImpl typeCD = new InterfaceTypeImpl(classC);
-    typeCD.typeArguments = <DartType>[classD.type];
-    Set<InterfaceType> superinterfacesOfCD =
-        InterfaceTypeImpl.computeSuperinterfaceSet(typeCD);
-    expect(superinterfacesOfCD, hasLength(3));
-    expect(superinterfacesOfCD.contains(typeObject), isTrue);
-    expect(superinterfacesOfCD.contains(typeA), isTrue);
-    expect(superinterfacesOfCD.contains(typeBD), isTrue);
-  }
-
-  void test_computeSuperinterfaceSet_multipleInterfacePaths() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    ClassElementImpl classD = ElementFactory.classElement2("D");
-    ClassElementImpl classE = ElementFactory.classElement2("E");
-    classB.interfaces = <InterfaceType>[classA.type];
-    classC.interfaces = <InterfaceType>[classA.type];
-    classD.interfaces = <InterfaceType>[classC.type];
-    classE.interfaces = <InterfaceType>[classB.type, classD.type];
-    // D
-    Set<InterfaceType> superinterfacesOfD =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classD.type);
-    expect(superinterfacesOfD, hasLength(3));
-    expect(superinterfacesOfD.contains(ElementFactory.object.type), isTrue);
-    expect(superinterfacesOfD.contains(classA.type), isTrue);
-    expect(superinterfacesOfD.contains(classC.type), isTrue);
-    // E
-    Set<InterfaceType> superinterfacesOfE =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classE.type);
-    expect(superinterfacesOfE, hasLength(5));
-    expect(superinterfacesOfE.contains(ElementFactory.object.type), isTrue);
-    expect(superinterfacesOfE.contains(classA.type), isTrue);
-    expect(superinterfacesOfE.contains(classB.type), isTrue);
-    expect(superinterfacesOfE.contains(classC.type), isTrue);
-    expect(superinterfacesOfE.contains(classD.type), isTrue);
-  }
-
-  void test_computeSuperinterfaceSet_multipleSuperclassPaths() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElement classC = ElementFactory.classElement("C", classA.type);
-    ClassElement classD = ElementFactory.classElement("D", classC.type);
-    ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
-    classE.interfaces = <InterfaceType>[classD.type];
-    // D
-    Set<InterfaceType> superinterfacesOfD =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classD.type);
-    expect(superinterfacesOfD, hasLength(3));
-    expect(superinterfacesOfD.contains(ElementFactory.object.type), isTrue);
-    expect(superinterfacesOfD.contains(classA.type), isTrue);
-    expect(superinterfacesOfD.contains(classC.type), isTrue);
-    // E
-    Set<InterfaceType> superinterfacesOfE =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classE.type);
-    expect(superinterfacesOfE, hasLength(5));
-    expect(superinterfacesOfE.contains(ElementFactory.object.type), isTrue);
-    expect(superinterfacesOfE.contains(classA.type), isTrue);
-    expect(superinterfacesOfE.contains(classB.type), isTrue);
-    expect(superinterfacesOfE.contains(classC.type), isTrue);
-    expect(superinterfacesOfE.contains(classD.type), isTrue);
-  }
-
-  void test_computeSuperinterfaceSet_recursion() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    Set<InterfaceType> superinterfacesOfB =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
-    expect(superinterfacesOfB, hasLength(2));
-  }
-
-  void test_computeSuperinterfaceSet_singleInterfacePath() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    classB.interfaces = <InterfaceType>[classA.type];
-    classC.interfaces = <InterfaceType>[classB.type];
-    // A
-    Set<InterfaceType> superinterfacesOfA =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classA.type);
-    expect(superinterfacesOfA, hasLength(1));
-    expect(superinterfacesOfA.contains(ElementFactory.object.type), isTrue);
-    // B
-    Set<InterfaceType> superinterfacesOfB =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
-    expect(superinterfacesOfB, hasLength(2));
-    expect(superinterfacesOfB.contains(ElementFactory.object.type), isTrue);
-    expect(superinterfacesOfB.contains(classA.type), isTrue);
-    // C
-    Set<InterfaceType> superinterfacesOfC =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classC.type);
-    expect(superinterfacesOfC, hasLength(3));
-    expect(superinterfacesOfC.contains(ElementFactory.object.type), isTrue);
-    expect(superinterfacesOfC.contains(classA.type), isTrue);
-    expect(superinterfacesOfC.contains(classB.type), isTrue);
-  }
-
-  void test_computeSuperinterfaceSet_singleSuperclassPath() {
-    //
-    //  A
-    //  |
-    //  B
-    //  |
-    //  C
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElement classC = ElementFactory.classElement("C", classB.type);
-    // A
-    Set<InterfaceType> superinterfacesOfA =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classA.type);
-    expect(superinterfacesOfA, hasLength(1));
-    expect(superinterfacesOfA.contains(ElementFactory.object.type), isTrue);
-    // B
-    Set<InterfaceType> superinterfacesOfB =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
-    expect(superinterfacesOfB, hasLength(2));
-    expect(superinterfacesOfB.contains(ElementFactory.object.type), isTrue);
-    expect(superinterfacesOfB.contains(classA.type), isTrue);
-    // C
-    Set<InterfaceType> superinterfacesOfC =
-        InterfaceTypeImpl.computeSuperinterfaceSet(classC.type);
-    expect(superinterfacesOfC, hasLength(3));
-    expect(superinterfacesOfC.contains(ElementFactory.object.type), isTrue);
-    expect(superinterfacesOfC.contains(classA.type), isTrue);
-    expect(superinterfacesOfC.contains(classB.type), isTrue);
-  }
-
-  void test_creation() {
-    expect(new InterfaceTypeImpl(ElementFactory.classElement2("A")), isNotNull);
-  }
-
-  void test_getAccessors() {
-    ClassElementImpl typeElement = ElementFactory.classElement2("A");
-    PropertyAccessorElement getterG =
-        ElementFactory.getterElement("g", false, null);
-    PropertyAccessorElement getterH =
-        ElementFactory.getterElement("h", false, null);
-    typeElement.accessors = <PropertyAccessorElement>[getterG, getterH];
-    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
-    expect(type.accessors.length, 2);
-  }
-
-  void test_getAccessors_empty() {
-    ClassElementImpl typeElement = ElementFactory.classElement2("A");
-    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
-    expect(type.accessors.length, 0);
-  }
-
-  void test_getConstructors() {
-    ClassElementImpl typeElement = ElementFactory.classElement2("A");
-    ConstructorElementImpl constructorOne =
-        ElementFactory.constructorElement(typeElement, 'one', false);
-    ConstructorElementImpl constructorTwo =
-        ElementFactory.constructorElement(typeElement, 'two', false);
-    typeElement.constructors = <ConstructorElement>[
-      constructorOne,
-      constructorTwo
-    ];
-    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
-    expect(type.constructors, hasLength(2));
-  }
-
-  void test_getConstructors_empty() {
-    ClassElementImpl typeElement = ElementFactory.classElement2("A");
-    typeElement.constructors = ConstructorElement.EMPTY_LIST;
-    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
-    expect(type.constructors, isEmpty);
-  }
-
-  void test_getElement() {
-    ClassElementImpl typeElement = ElementFactory.classElement2("A");
-    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
-    expect(type.element, typeElement);
-  }
-
-  void test_getGetter_implemented() {
-    //
-    // class A { g {} }
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String getterName = "g";
-    PropertyAccessorElement getterG =
-        ElementFactory.getterElement(getterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[getterG];
-    InterfaceType typeA = classA.type;
-    expect(typeA.getGetter(getterName), same(getterG));
-  }
-
-  void test_getGetter_parameterized() {
-    //
-    // class A<E> { E get g {} }
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
-    DartType typeE = classA.type.typeArguments[0];
-    String getterName = "g";
-    PropertyAccessorElement getterG =
-        ElementFactory.getterElement(getterName, false, typeE);
-    classA.accessors = <PropertyAccessorElement>[getterG];
-    (getterG.type as FunctionTypeImpl).typeArguments =
-        classA.type.typeArguments;
-    //
-    // A<I>
-    //
-    InterfaceType typeI = ElementFactory.classElement2("I").type;
-    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
-    typeAI.typeArguments = <DartType>[typeI];
-    PropertyAccessorElement getter = typeAI.getGetter(getterName);
-    expect(getter, isNotNull);
-    FunctionType getterType = getter.type;
-    expect(getterType.returnType, same(typeI));
-  }
-
-  void test_getGetter_unimplemented() {
-    //
-    // class A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    expect(typeA.getGetter("g"), isNull);
-  }
-
-  void test_getInterfaces_nonParameterized() {
-    //
-    // class C implements A, B
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    InterfaceType typeB = classB.type;
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    classC.interfaces = <InterfaceType>[typeA, typeB];
-    List<InterfaceType> interfaces = classC.type.interfaces;
-    expect(interfaces, hasLength(2));
-    if (identical(interfaces[0], typeA)) {
-      expect(interfaces[1], same(typeB));
-    } else {
-      expect(interfaces[0], same(typeB));
-      expect(interfaces[1], same(typeA));
-    }
-  }
-
-  void test_getInterfaces_parameterized() {
-    //
-    // class A<E>
-    // class B<F> implements A<F>
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
-    ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
-    InterfaceType typeB = classB.type;
-    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
-    typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
-    classB.interfaces = <InterfaceType>[typeAF];
-    //
-    // B<I>
-    //
-    InterfaceType typeI = ElementFactory.classElement2("I").type;
-    InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
-    typeBI.typeArguments = <DartType>[typeI];
-    List<InterfaceType> interfaces = typeBI.interfaces;
-    expect(interfaces, hasLength(1));
-    InterfaceType result = interfaces[0];
-    expect(result.element, same(classA));
-    expect(result.typeArguments[0], same(typeI));
-  }
-
-  void test_getLeastUpperBound_directInterfaceCase() {
-    //
-    // class A
-    // class B implements A
-    // class C implements B
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    classC.interfaces = <InterfaceType>[typeB];
-    expect(typeB.getLeastUpperBound(typeC), typeB);
-    expect(typeC.getLeastUpperBound(typeB), typeB);
-  }
-
-  void test_getLeastUpperBound_directSubclassCase() {
-    //
-    // class A
-    // class B extends A
-    // class C extends B
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    expect(typeB.getLeastUpperBound(typeC), typeB);
-    expect(typeC.getLeastUpperBound(typeB), typeB);
-  }
-
-  void test_getLeastUpperBound_functionType() {
-    DartType interfaceType = ElementFactory.classElement2("A").type;
-    FunctionTypeImpl functionType = new FunctionTypeImpl(
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
-    expect(interfaceType.getLeastUpperBound(functionType), isNull);
-  }
-
-  void test_getLeastUpperBound_mixinCase() {
-    //
-    // class A
-    // class B extends A
-    // class C extends A
-    // class D extends B with M, N, O, P
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElement classC = ElementFactory.classElement("C", classA.type);
-    ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    InterfaceType typeD = classD.type;
-    classD.mixins = <InterfaceType>[
-      ElementFactory.classElement2("M").type,
-      ElementFactory.classElement2("N").type,
-      ElementFactory.classElement2("O").type,
-      ElementFactory.classElement2("P").type
-    ];
-    expect(typeD.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeD), typeA);
-  }
-
-  void test_getLeastUpperBound_null() {
-    DartType interfaceType = ElementFactory.classElement2("A").type;
-    expect(interfaceType.getLeastUpperBound(null), isNull);
-  }
-
-  void test_getLeastUpperBound_object() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    DartType typeObject = typeA.element.supertype;
-    // assert that object does not have a super type
-    expect((typeObject.element as ClassElement).supertype, isNull);
-    // assert that both A and B have the same super type of Object
-    expect(typeB.element.supertype, typeObject);
-    // finally, assert that the only least upper bound of A and B is Object
-    expect(typeA.getLeastUpperBound(typeB), typeObject);
-  }
-
-  void test_getLeastUpperBound_self() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    expect(typeA.getLeastUpperBound(typeA), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperclass1() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    expect(typeB.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperclass2() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
-    ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeD = classD.type;
-    expect(typeB.getLeastUpperBound(typeD), typeA);
-    expect(typeD.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperclass3() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
-    ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    InterfaceType typeD = classD.type;
-    expect(typeC.getLeastUpperBound(typeD), typeB);
-    expect(typeD.getLeastUpperBound(typeC), typeB);
-  }
-
-  void test_getLeastUpperBound_sharedSuperclass4() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classA2 = ElementFactory.classElement2("A2");
-    ClassElement classA3 = ElementFactory.classElement2("A3");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeA2 = classA2.type;
-    InterfaceType typeA3 = classA3.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classB.interfaces = <InterfaceType>[typeA2];
-    classC.interfaces = <InterfaceType>[typeA3];
-    expect(typeB.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperinterface1() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    classC.interfaces = <InterfaceType>[typeA];
-    expect(typeB.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperinterface2() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    ClassElementImpl classD = ElementFactory.classElement2("D");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    InterfaceType typeD = classD.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    classC.interfaces = <InterfaceType>[typeA];
-    classD.interfaces = <InterfaceType>[typeC];
-    expect(typeB.getLeastUpperBound(typeD), typeA);
-    expect(typeD.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperinterface3() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    ClassElementImpl classD = ElementFactory.classElement2("D");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    InterfaceType typeD = classD.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    classC.interfaces = <InterfaceType>[typeB];
-    classD.interfaces = <InterfaceType>[typeB];
-    expect(typeC.getLeastUpperBound(typeD), typeB);
-    expect(typeD.getLeastUpperBound(typeC), typeB);
-  }
-
-  void test_getLeastUpperBound_sharedSuperinterface4() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classA2 = ElementFactory.classElement2("A2");
-    ClassElement classA3 = ElementFactory.classElement2("A3");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeA2 = classA2.type;
-    InterfaceType typeA3 = classA3.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classB.interfaces = <InterfaceType>[typeA, typeA2];
-    classC.interfaces = <InterfaceType>[typeA, typeA3];
-    expect(typeB.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_twoComparables() {
-    InterfaceType string = _typeProvider.stringType;
-    InterfaceType num = _typeProvider.numType;
-    expect(string.getLeastUpperBound(num), _typeProvider.objectType);
-  }
-
-  void test_getLeastUpperBound_typeParameters_different() {
-    //
-    // class List<int>
-    // class List<double>
-    //
-    InterfaceType listType = _typeProvider.listType;
-    InterfaceType intType = _typeProvider.intType;
-    InterfaceType doubleType = _typeProvider.doubleType;
-    InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
-    InterfaceType listOfDoubleType =
-        listType.substitute4(<DartType>[doubleType]);
-    expect(listOfIntType.getLeastUpperBound(listOfDoubleType),
-        _typeProvider.objectType);
-  }
-
-  void test_getLeastUpperBound_typeParameters_same() {
-    //
-    // List<int>
-    // List<int>
-    //
-    InterfaceType listType = _typeProvider.listType;
-    InterfaceType intType = _typeProvider.intType;
-    InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
-    expect(listOfIntType.getLeastUpperBound(listOfIntType), listOfIntType);
-  }
-
-  void test_getMethod_implemented() {
-    //
-    // class A { m() {} }
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[methodM];
-    InterfaceType typeA = classA.type;
-    expect(typeA.getMethod(methodName), same(methodM));
-  }
-
-  void test_getMethod_parameterized() {
-    //
-    // class A<E> { E m(E p) {} }
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
-    DartType typeE = classA.type.typeArguments[0];
-    String methodName = "m";
-    MethodElementImpl methodM =
-        ElementFactory.methodElement(methodName, typeE, [typeE]);
-    classA.methods = <MethodElement>[methodM];
-    (methodM.type as FunctionTypeImpl).typeArguments =
-        classA.type.typeArguments;
-    //
-    // A<I>
-    //
-    InterfaceType typeI = ElementFactory.classElement2("I").type;
-    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
-    typeAI.typeArguments = <DartType>[typeI];
-    MethodElement method = typeAI.getMethod(methodName);
-    expect(method, isNotNull);
-    FunctionType methodType = method.type;
-    expect(methodType.returnType, same(typeI));
-    List<DartType> parameterTypes = methodType.normalParameterTypes;
-    expect(parameterTypes, hasLength(1));
-    expect(parameterTypes[0], same(typeI));
-  }
-
-  void test_getMethod_unimplemented() {
-    //
-    // class A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    expect(typeA.getMethod("m"), isNull);
-  }
-
-  void test_getMethods() {
-    ClassElementImpl typeElement = ElementFactory.classElement2("A");
-    MethodElementImpl methodOne = ElementFactory.methodElement("one", null);
-    MethodElementImpl methodTwo = ElementFactory.methodElement("two", null);
-    typeElement.methods = <MethodElement>[methodOne, methodTwo];
-    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
-    expect(type.methods.length, 2);
-  }
-
-  void test_getMethods_empty() {
-    ClassElementImpl typeElement = ElementFactory.classElement2("A");
-    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
-    expect(type.methods.length, 0);
-  }
-
-  void test_getMixins_nonParameterized() {
-    //
-    // class C extends Object with A, B
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    InterfaceType typeB = classB.type;
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    classC.mixins = <InterfaceType>[typeA, typeB];
-    List<InterfaceType> interfaces = classC.type.mixins;
-    expect(interfaces, hasLength(2));
-    if (identical(interfaces[0], typeA)) {
-      expect(interfaces[1], same(typeB));
-    } else {
-      expect(interfaces[0], same(typeB));
-      expect(interfaces[1], same(typeA));
-    }
-  }
-
-  void test_getMixins_parameterized() {
-    //
-    // class A<E>
-    // class B<F> extends Object with A<F>
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
-    ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
-    InterfaceType typeB = classB.type;
-    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
-    typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
-    classB.mixins = <InterfaceType>[typeAF];
-    //
-    // B<I>
-    //
-    InterfaceType typeI = ElementFactory.classElement2("I").type;
-    InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
-    typeBI.typeArguments = <DartType>[typeI];
-    List<InterfaceType> interfaces = typeBI.mixins;
-    expect(interfaces, hasLength(1));
-    InterfaceType result = interfaces[0];
-    expect(result.element, same(classA));
-    expect(result.typeArguments[0], same(typeI));
-  }
-
-  void test_getSetter_implemented() {
-    //
-    // class A { s() {} }
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String setterName = "s";
-    PropertyAccessorElement setterS =
-        ElementFactory.setterElement(setterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[setterS];
-    InterfaceType typeA = classA.type;
-    expect(typeA.getSetter(setterName), same(setterS));
-  }
-
-  void test_getSetter_parameterized() {
-    //
-    // class A<E> { set s(E p) {} }
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
-    DartType typeE = classA.type.typeArguments[0];
-    String setterName = "s";
-    PropertyAccessorElement setterS =
-        ElementFactory.setterElement(setterName, false, typeE);
-    classA.accessors = <PropertyAccessorElement>[setterS];
-    (setterS.type as FunctionTypeImpl).typeArguments =
-        classA.type.typeArguments;
-    //
-    // A<I>
-    //
-    InterfaceType typeI = ElementFactory.classElement2("I").type;
-    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
-    typeAI.typeArguments = <DartType>[typeI];
-    PropertyAccessorElement setter = typeAI.getSetter(setterName);
-    expect(setter, isNotNull);
-    FunctionType setterType = setter.type;
-    List<DartType> parameterTypes = setterType.normalParameterTypes;
-    expect(parameterTypes, hasLength(1));
-    expect(parameterTypes[0], same(typeI));
-  }
-
-  void test_getSetter_unimplemented() {
-    //
-    // class A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    expect(typeA.getSetter("s"), isNull);
-  }
-
-  void test_getSuperclass_nonParameterized() {
-    //
-    // class B extends A
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    ClassElementImpl classB = ElementFactory.classElement("B", typeA);
-    InterfaceType typeB = classB.type;
-    expect(typeB.superclass, same(typeA));
-  }
-
-  void test_getSuperclass_parameterized() {
-    //
-    // class A<E>
-    // class B<F> extends A<F>
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
-    ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
-    InterfaceType typeB = classB.type;
-    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
-    typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
-    classB.supertype = typeAF;
-    //
-    // B<I>
-    //
-    InterfaceType typeI = ElementFactory.classElement2("I").type;
-    InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
-    typeBI.typeArguments = <DartType>[typeI];
-    InterfaceType superclass = typeBI.superclass;
-    expect(superclass.element, same(classA));
-    expect(superclass.typeArguments[0], same(typeI));
-  }
-
-  void test_getTypeArguments_empty() {
-    InterfaceType type = ElementFactory.classElement2("A").type;
-    expect(type.typeArguments, hasLength(0));
-  }
-
-  void test_hashCode() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    expect(0 == typeA.hashCode, isFalse);
-  }
-
-  void test_isAssignableTo_typeVariables() {
-    //
-    // class A<E> {}
-    // class B<F, G> {
-    //   A<F> af;
-    //   f (A<G> ag) {
-    //     af = ag;
-    //   }
-    // }
-    //
-    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
-    ClassElement classB = ElementFactory.classElement2("B", ["F", "G"]);
-    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
-    typeAF.typeArguments = <DartType>[classB.typeParameters[0].type];
-    InterfaceTypeImpl typeAG = new InterfaceTypeImpl(classA);
-    typeAG.typeArguments = <DartType>[classB.typeParameters[1].type];
-    expect(typeAG.isAssignableTo(typeAF), isFalse);
-  }
-
-  void test_isAssignableTo_void() {
-    InterfaceTypeImpl intType = _typeProvider.intType;
-    expect(VoidTypeImpl.instance.isAssignableTo(intType), isFalse);
-  }
-
-  void test_isDirectSupertypeOf_extends() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    expect(typeA.isDirectSupertypeOf(typeB), isTrue);
-  }
-
-  void test_isDirectSupertypeOf_false() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement2("B");
-    ClassElement classC = ElementFactory.classElement("C", classB.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    expect(typeA.isDirectSupertypeOf(typeC), isFalse);
-  }
-
-  void test_isDirectSupertypeOf_implements() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    expect(typeA.isDirectSupertypeOf(typeB), isTrue);
-  }
-
-  void test_isDirectSupertypeOf_with() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    classB.mixins = <InterfaceType>[typeA];
-    expect(typeA.isDirectSupertypeOf(typeB), isTrue);
-  }
-
-  void test_isMoreSpecificThan_bottom() {
-    DartType type = ElementFactory.classElement2("A").type;
-    expect(BottomTypeImpl.instance.isMoreSpecificThan(type), isTrue);
-  }
-
-  void test_isMoreSpecificThan_covariance() {
-    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
-    ClassElement classI = ElementFactory.classElement2("I");
-    ClassElement classJ = ElementFactory.classElement("J", classI.type);
-    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
-    InterfaceTypeImpl typeAJ = new InterfaceTypeImpl(classA);
-    typeAI.typeArguments = <DartType>[classI.type];
-    typeAJ.typeArguments = <DartType>[classJ.type];
-    expect(typeAJ.isMoreSpecificThan(typeAI), isTrue);
-    expect(typeAI.isMoreSpecificThan(typeAJ), isFalse);
-  }
-
-  void test_isMoreSpecificThan_directSupertype() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    expect(typeB.isMoreSpecificThan(typeA), isTrue);
-    // the opposite test tests a different branch in isMoreSpecificThan()
-    expect(typeA.isMoreSpecificThan(typeB), isFalse);
-  }
-
-  void test_isMoreSpecificThan_dynamic() {
-    InterfaceType type = ElementFactory.classElement2("A").type;
-    expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
-  }
-
-  void test_isMoreSpecificThan_generic() {
-    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
-    ClassElement classB = ElementFactory.classElement2("B");
-    DartType dynamicType = DynamicTypeImpl.instance;
-    InterfaceType typeAOfDynamic =
-        classA.type.substitute4(<DartType>[dynamicType]);
-    InterfaceType typeAOfB = classA.type.substitute4(<DartType>[classB.type]);
-    expect(typeAOfDynamic.isMoreSpecificThan(typeAOfB), isFalse);
-    expect(typeAOfB.isMoreSpecificThan(typeAOfDynamic), isTrue);
-  }
-
-  void test_isMoreSpecificThan_self() {
-    InterfaceType type = ElementFactory.classElement2("A").type;
-    expect(type.isMoreSpecificThan(type), isTrue);
-  }
-
-  void test_isMoreSpecificThan_transitive_interface() {
-    //
-    //  class A {}
-    //  class B extends A {}
-    //  class C implements B {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    classC.interfaces = <InterfaceType>[classB.type];
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    expect(typeC.isMoreSpecificThan(typeA), isTrue);
-  }
-
-  void test_isMoreSpecificThan_transitive_mixin() {
-    //
-    //  class A {}
-    //  class B extends A {}
-    //  class C with B {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    classC.mixins = <InterfaceType>[classB.type];
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    expect(typeC.isMoreSpecificThan(typeA), isTrue);
-  }
-
-  void test_isMoreSpecificThan_transitive_recursive() {
-    //
-    //  class A extends B {}
-    //  class B extends A {}
-    //  class C {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    classA.supertype = classB.type;
-    expect(typeA.isMoreSpecificThan(typeC), isFalse);
-  }
-
-  void test_isMoreSpecificThan_transitive_superclass() {
-    //
-    //  class A {}
-    //  class B extends A {}
-    //  class C extends B {}
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElement classC = ElementFactory.classElement("C", classB.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    expect(typeC.isMoreSpecificThan(typeA), isTrue);
-  }
-
-  void test_isMoreSpecificThan_typeParameterType() {
-    //
-    // class A<E> {}
-    //
-    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
-    InterfaceType typeA = classA.type;
-    TypeParameterType parameterType = classA.typeParameters[0].type;
-    DartType objectType = _typeProvider.objectType;
-    expect(parameterType.isMoreSpecificThan(objectType), isTrue);
-    expect(parameterType.isMoreSpecificThan(typeA), isFalse);
-  }
-
-  void test_isMoreSpecificThan_typeParameterType_withBound() {
-    //
-    // class A {}
-    // class B<E extends A> {}
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    TypeParameterElementImpl parameterEA =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
-    TypeParameterType parameterAEType = new TypeParameterTypeImpl(parameterEA);
-    parameterEA.bound = typeA;
-    parameterEA.type = parameterAEType;
-    classB.typeParameters = <TypeParameterElementImpl>[parameterEA];
-    expect(parameterAEType.isMoreSpecificThan(typeA), isTrue);
-  }
-
-  void test_isSubtypeOf_directSubtype() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    expect(typeB.isSubtypeOf(typeA), isTrue);
-    expect(typeA.isSubtypeOf(typeB), isFalse);
-  }
-
-  void test_isSubtypeOf_dynamic() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    DartType dynamicType = DynamicTypeImpl.instance;
-    expect(dynamicType.isSubtypeOf(typeA), isTrue);
-    expect(typeA.isSubtypeOf(dynamicType), isTrue);
-  }
-
-  void test_isSubtypeOf_function() {
-    //
-    // void f(String s) {}
-    // class A {
-    //   void call(String s) {}
-    // }
-    //
-    InterfaceType stringType = _typeProvider.stringType;
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.methods = <MethodElement>[
-      ElementFactory.methodElement("call", VoidTypeImpl.instance, [stringType])
-    ];
-    FunctionType functionType = ElementFactory
-        .functionElement5("f", <ClassElement>[stringType.element]).type;
-    expect(classA.type.isSubtypeOf(functionType), isTrue);
-  }
-
-  void test_isSubtypeOf_generic() {
-    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
-    ClassElement classB = ElementFactory.classElement2("B");
-    DartType dynamicType = DynamicTypeImpl.instance;
-    InterfaceType typeAOfDynamic =
-        classA.type.substitute4(<DartType>[dynamicType]);
-    InterfaceType typeAOfB = classA.type.substitute4(<DartType>[classB.type]);
-    expect(typeAOfDynamic.isSubtypeOf(typeAOfB), isTrue);
-    expect(typeAOfB.isSubtypeOf(typeAOfDynamic), isTrue);
-  }
-
-  void test_isSubtypeOf_interface() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeObject = classA.supertype;
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classC.interfaces = <InterfaceType>[typeB];
-    expect(typeC.isSubtypeOf(typeB), isTrue);
-    expect(typeC.isSubtypeOf(typeObject), isTrue);
-    expect(typeC.isSubtypeOf(typeA), isTrue);
-    expect(typeA.isSubtypeOf(typeC), isFalse);
-  }
-
-  void test_isSubtypeOf_mixins() {
-    //
-    // class A {}
-    // class B extends A {}
-    // class C with B {}
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeObject = classA.supertype;
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classC.mixins = <InterfaceType>[typeB];
-    expect(typeC.isSubtypeOf(typeB), isTrue);
-    expect(typeC.isSubtypeOf(typeObject), isTrue);
-    expect(typeC.isSubtypeOf(typeA), isTrue);
-    expect(typeA.isSubtypeOf(typeC), isFalse);
-  }
-
-  void test_isSubtypeOf_object() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeObject = classA.supertype;
-    expect(typeA.isSubtypeOf(typeObject), isTrue);
-    expect(typeObject.isSubtypeOf(typeA), isFalse);
-  }
-
-  void test_isSubtypeOf_self() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    expect(typeA.isSubtypeOf(typeA), isTrue);
-  }
-
-  void test_isSubtypeOf_transitive_recursive() {
-    //
-    //  class A extends B {}
-    //  class B extends A {}
-    //  class C {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    classA.supertype = classB.type;
-    expect(typeA.isSubtypeOf(typeC), isFalse);
-  }
-
-  void test_isSubtypeOf_transitive_superclass() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElement classC = ElementFactory.classElement("C", classB.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    expect(typeC.isSubtypeOf(typeA), isTrue);
-    expect(typeA.isSubtypeOf(typeC), isFalse);
-  }
-
-  void test_isSubtypeOf_typeArguments() {
-    DartType dynamicType = DynamicTypeImpl.instance;
-    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
-    ClassElement classI = ElementFactory.classElement2("I");
-    ClassElement classJ = ElementFactory.classElement("J", classI.type);
-    ClassElement classK = ElementFactory.classElement2("K");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeA_dynamic = typeA.substitute4(<DartType>[dynamicType]);
-    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
-    InterfaceTypeImpl typeAJ = new InterfaceTypeImpl(classA);
-    InterfaceTypeImpl typeAK = new InterfaceTypeImpl(classA);
-    typeAI.typeArguments = <DartType>[classI.type];
-    typeAJ.typeArguments = <DartType>[classJ.type];
-    typeAK.typeArguments = <DartType>[classK.type];
-    // A<J> <: A<I> since J <: I
-    expect(typeAJ.isSubtypeOf(typeAI), isTrue);
-    expect(typeAI.isSubtypeOf(typeAJ), isFalse);
-    // A<I> <: A<I> since I <: I
-    expect(typeAI.isSubtypeOf(typeAI), isTrue);
-    // A <: A<I> and A <: A<J>
-    expect(typeA_dynamic.isSubtypeOf(typeAI), isTrue);
-    expect(typeA_dynamic.isSubtypeOf(typeAJ), isTrue);
-    // A<I> <: A and A<J> <: A
-    expect(typeAI.isSubtypeOf(typeA_dynamic), isTrue);
-    expect(typeAJ.isSubtypeOf(typeA_dynamic), isTrue);
-    // A<I> !<: A<K> and A<K> !<: A<I>
-    expect(typeAI.isSubtypeOf(typeAK), isFalse);
-    expect(typeAK.isSubtypeOf(typeAI), isFalse);
-  }
-
-  void test_isSubtypeOf_typeParameter() {
-    //
-    // class A<E> {}
-    //
-    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
-    InterfaceType typeA = classA.type;
-    TypeParameterType parameterType = classA.typeParameters[0].type;
-    expect(typeA.isSubtypeOf(parameterType), isFalse);
-  }
-
-  void test_isSupertypeOf_directSupertype() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    expect(typeB.isSupertypeOf(typeA), isFalse);
-    expect(typeA.isSupertypeOf(typeB), isTrue);
-  }
-
-  void test_isSupertypeOf_dynamic() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    DartType dynamicType = DynamicTypeImpl.instance;
-    expect(dynamicType.isSupertypeOf(typeA), isTrue);
-    expect(typeA.isSupertypeOf(dynamicType), isTrue);
-  }
-
-  void test_isSupertypeOf_indirectSupertype() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElement classC = ElementFactory.classElement("C", classB.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    expect(typeC.isSupertypeOf(typeA), isFalse);
-    expect(typeA.isSupertypeOf(typeC), isTrue);
-  }
-
-  void test_isSupertypeOf_interface() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeObject = classA.supertype;
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classC.interfaces = <InterfaceType>[typeB];
-    expect(typeB.isSupertypeOf(typeC), isTrue);
-    expect(typeObject.isSupertypeOf(typeC), isTrue);
-    expect(typeA.isSupertypeOf(typeC), isTrue);
-    expect(typeC.isSupertypeOf(typeA), isFalse);
-  }
-
-  void test_isSupertypeOf_mixins() {
-    //
-    // class A {}
-    // class B extends A {}
-    // class C with B {}
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeObject = classA.supertype;
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classC.mixins = <InterfaceType>[typeB];
-    expect(typeB.isSupertypeOf(typeC), isTrue);
-    expect(typeObject.isSupertypeOf(typeC), isTrue);
-    expect(typeA.isSupertypeOf(typeC), isTrue);
-    expect(typeC.isSupertypeOf(typeA), isFalse);
-  }
-
-  void test_isSupertypeOf_object() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeObject = classA.supertype;
-    expect(typeA.isSupertypeOf(typeObject), isFalse);
-    expect(typeObject.isSupertypeOf(typeA), isTrue);
-  }
-
-  void test_isSupertypeOf_self() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    expect(typeA.isSupertypeOf(typeA), isTrue);
-  }
-
-  void test_lookUpGetter_implemented() {
-    //
-    // class A { g {} }
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String getterName = "g";
-    PropertyAccessorElement getterG =
-        ElementFactory.getterElement(getterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[getterG];
-    InterfaceType typeA = classA.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
-    expect(typeA.lookUpGetter(getterName, library), same(getterG));
-  }
-
-  void test_lookUpGetter_inherited() {
-    //
-    // class A { g {} }
-    // class B extends A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String getterName = "g";
-    PropertyAccessorElement getterG =
-        ElementFactory.getterElement(getterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[getterG];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    InterfaceType typeB = classB.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
-    expect(typeB.lookUpGetter(getterName, library), same(getterG));
-  }
-
-  void test_lookUpGetter_mixin_shadowing() {
-    //
-    // class B {}
-    // class M1 { get g {} }
-    // class M2 { get g {} }
-    // class C extends B with M1, M2 {}
-    //
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String getterName = 'g';
-    ClassElementImpl classB = ElementFactory.classElement2('B');
-    ClassElementImpl classM1 = ElementFactory.classElement2('M1');
-    PropertyAccessorElementImpl getterM1g = ElementFactory.getterElement(
-        getterName, false, typeProvider.dynamicType);
-    classM1.accessors = <PropertyAccessorElement>[getterM1g];
-    ClassElementImpl classM2 = ElementFactory.classElement2('M2');
-    PropertyAccessorElementImpl getterM2g = ElementFactory.getterElement(
-        getterName, false, typeProvider.dynamicType);
-    classM2.accessors = <PropertyAccessorElement>[getterM2g];
-    ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
-    classC.mixins = <InterfaceType>[classM1.type, classM2.type];
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElementImpl unit = library.definingCompilationUnit;
-    unit.types = <ClassElement>[classB, classM1, classM2, classC];
-    expect(classC.type.lookUpGetter(getterName, library), getterM2g);
-  }
-
-  void test_lookUpGetter_recursive() {
-    //
-    // class A extends B {}
-    // class B extends A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    ClassElementImpl classB = ElementFactory.classElement("B", typeA);
-    classA.supertype = classB.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
-    expect(typeA.lookUpGetter("g", library), isNull);
-  }
-
-  void test_lookUpGetter_unimplemented() {
-    //
-    // class A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
-    expect(typeA.lookUpGetter("g", library), isNull);
-  }
-
-  void test_lookUpMethod_implemented() {
-    //
-    // class A { m() {} }
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[methodM];
-    InterfaceType typeA = classA.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
-    expect(typeA.lookUpMethod(methodName, library), same(methodM));
-  }
-
-  void test_lookUpMethod_inherited() {
-    //
-    // class A { m() {} }
-    // class B extends A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String methodName = "m";
-    MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
-    classA.methods = <MethodElement>[methodM];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    InterfaceType typeB = classB.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
-    expect(typeB.lookUpMethod(methodName, library), same(methodM));
-  }
-
-  void test_lookUpMethod_mixin_shadowing() {
-    //
-    // class B {}
-    // class M1 { m() {} }
-    // class M2 { m() {} }
-    // class C extends B with M1, M2 {}
-    //
-    String methodName = 'm';
-    ClassElementImpl classB = ElementFactory.classElement2('B');
-    ClassElementImpl classM1 = ElementFactory.classElement2('M1');
-    MethodElementImpl methodM1m =
-        ElementFactory.methodElement(methodName, null);
-    classM1.methods = <MethodElement>[methodM1m];
-    ClassElementImpl classM2 = ElementFactory.classElement2('M2');
-    MethodElementImpl methodM2m =
-        ElementFactory.methodElement(methodName, null);
-    classM2.methods = <MethodElement>[methodM2m];
-    ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
-    classC.mixins = <InterfaceType>[classM1.type, classM2.type];
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElementImpl unit = library.definingCompilationUnit;
-    unit.types = <ClassElement>[classB, classM1, classM2, classC];
-    expect(classC.type.lookUpMethod(methodName, library), methodM2m);
-  }
-
-  void test_lookUpMethod_parameterized() {
-    //
-    // class A<E> { E m(E p) {} }
-    // class B<F> extends A<F> {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
-    DartType typeE = classA.type.typeArguments[0];
-    String methodName = "m";
-    MethodElementImpl methodM =
-        ElementFactory.methodElement(methodName, typeE, [typeE]);
-    classA.methods = <MethodElement>[methodM];
-    (methodM.type as FunctionTypeImpl).typeArguments =
-        classA.type.typeArguments;
-    ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
-    InterfaceType typeB = classB.type;
-    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
-    typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
-    classB.supertype = typeAF;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
-    //
-    // B<I>
-    //
-    InterfaceType typeI = ElementFactory.classElement2("I").type;
-    InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
-    typeBI.typeArguments = <DartType>[typeI];
-    MethodElement method = typeBI.lookUpMethod(methodName, library);
-    expect(method, isNotNull);
-    FunctionType methodType = method.type;
-    expect(methodType.returnType, same(typeI));
-    List<DartType> parameterTypes = methodType.normalParameterTypes;
-    expect(parameterTypes, hasLength(1));
-    expect(parameterTypes[0], same(typeI));
-  }
-
-  void test_lookUpMethod_recursive() {
-    //
-    // class A extends B {}
-    // class B extends A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    ClassElementImpl classB = ElementFactory.classElement("B", typeA);
-    classA.supertype = classB.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
-    expect(typeA.lookUpMethod("m", library), isNull);
-  }
-
-  void test_lookUpMethod_unimplemented() {
-    //
-    // class A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
-    expect(typeA.lookUpMethod("m", library), isNull);
-  }
-
-  void test_lookUpSetter_implemented() {
-    //
-    // class A { s(x) {} }
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String setterName = "s";
-    PropertyAccessorElement setterS =
-        ElementFactory.setterElement(setterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[setterS];
-    InterfaceType typeA = classA.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
-    expect(typeA.lookUpSetter(setterName, library), same(setterS));
-  }
-
-  void test_lookUpSetter_inherited() {
-    //
-    // class A { s(x) {} }
-    // class B extends A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    String setterName = "g";
-    PropertyAccessorElement setterS =
-        ElementFactory.setterElement(setterName, false, null);
-    classA.accessors = <PropertyAccessorElement>[setterS];
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    InterfaceType typeB = classB.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
-    expect(typeB.lookUpSetter(setterName, library), same(setterS));
-  }
-
-  void test_lookUpSetter_mixin_shadowing() {
-    //
-    // class B {}
-    // class M1 { set s() {} }
-    // class M2 { set s() {} }
-    // class C extends B with M1, M2 {}
-    //
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String setterName = 's';
-    ClassElementImpl classB = ElementFactory.classElement2('B');
-    ClassElementImpl classM1 = ElementFactory.classElement2('M1');
-    PropertyAccessorElementImpl setterM1g = ElementFactory.setterElement(
-        setterName, false, typeProvider.dynamicType);
-    classM1.accessors = <PropertyAccessorElement>[setterM1g];
-    ClassElementImpl classM2 = ElementFactory.classElement2('M2');
-    PropertyAccessorElementImpl setterM2g = ElementFactory.getterElement(
-        setterName, false, typeProvider.dynamicType);
-    classM2.accessors = <PropertyAccessorElement>[setterM2g];
-    ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
-    classC.mixins = <InterfaceType>[classM1.type, classM2.type];
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElementImpl unit = library.definingCompilationUnit;
-    unit.types = <ClassElement>[classB, classM1, classM2, classC];
-    expect(classC.type.lookUpGetter(setterName, library), setterM2g);
-  }
-
-  void test_lookUpSetter_recursive() {
-    //
-    // class A extends B {}
-    // class B extends A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    ClassElementImpl classB = ElementFactory.classElement("B", typeA);
-    classA.supertype = classB.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
-    expect(typeA.lookUpSetter("s", library), isNull);
-  }
-
-  void test_lookUpSetter_unimplemented() {
-    //
-    // class A {}
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
-    expect(typeA.lookUpSetter("s", library), isNull);
-  }
-
-  void test_setTypeArguments() {
-    InterfaceTypeImpl type =
-        ElementFactory.classElement2("A").type as InterfaceTypeImpl;
-    List<DartType> typeArguments = <DartType>[
-      ElementFactory.classElement2("B").type,
-      ElementFactory.classElement2("C").type
-    ];
-    type.typeArguments = typeArguments;
-    expect(type.typeArguments, typeArguments);
-  }
-
-  void test_substitute_equal() {
-    ClassElement classAE = ElementFactory.classElement2("A", ["E"]);
-    InterfaceType typeAE = classAE.type;
-    InterfaceType argumentType = ElementFactory.classElement2("B").type;
-    List<DartType> args = [argumentType];
-    List<DartType> params = [classAE.typeParameters[0].type];
-    InterfaceType typeAESubbed = typeAE.substitute2(args, params);
-    expect(typeAESubbed.element, classAE);
-    List<DartType> resultArguments = typeAESubbed.typeArguments;
-    expect(resultArguments, hasLength(1));
-    expect(resultArguments[0], argumentType);
-  }
-
-  void test_substitute_exception() {
-    try {
-      ClassElementImpl classA = ElementFactory.classElement2("A");
-      InterfaceTypeImpl type = new InterfaceTypeImpl(classA);
-      InterfaceType argumentType = ElementFactory.classElement2("B").type;
-      type.substitute2(<DartType>[argumentType], <DartType>[]);
-      fail(
-          "Expected to encounter exception, argument and parameter type array lengths not equal.");
-    } catch (e) {
-      // Expected result
-    }
-  }
-
-  void test_substitute_notEqual() {
-    // The [test_substitute_equals] above has a slightly higher level
-    // implementation.
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    TypeParameterElementImpl parameterElement =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
-    InterfaceTypeImpl type = new InterfaceTypeImpl(classA);
-    TypeParameterTypeImpl parameter =
-        new TypeParameterTypeImpl(parameterElement);
-    type.typeArguments = <DartType>[parameter];
-    InterfaceType argumentType = ElementFactory.classElement2("B").type;
-    TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("F")));
-    InterfaceType result =
-        type.substitute2(<DartType>[argumentType], <DartType>[parameterType]);
-    expect(result.element, classA);
-    List<DartType> resultArguments = result.typeArguments;
-    expect(resultArguments, hasLength(1));
-    expect(resultArguments[0], parameter);
-  }
-}
-
-@reflectiveTest
-class LibraryElementImplTest extends EngineTestCase {
-  void test_creation() {
-    expect(
-        new LibraryElementImpl.forNode(
-            createAnalysisContext(), AstFactory.libraryIdentifier2(["l"])),
-        isNotNull);
-  }
-
-  void test_getImportedLibraries() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library1 = ElementFactory.library(context, "l1");
-    LibraryElementImpl library2 = ElementFactory.library(context, "l2");
-    LibraryElementImpl library3 = ElementFactory.library(context, "l3");
-    LibraryElementImpl library4 = ElementFactory.library(context, "l4");
-    PrefixElement prefixA =
-        new PrefixElementImpl.forNode(AstFactory.identifier3("a"));
-    PrefixElement prefixB =
-        new PrefixElementImpl.forNode(AstFactory.identifier3("b"));
-    List<ImportElementImpl> imports = [
-      ElementFactory.importFor(library2, null),
-      ElementFactory.importFor(library2, prefixB),
-      ElementFactory.importFor(library3, null),
-      ElementFactory.importFor(library3, prefixA),
-      ElementFactory.importFor(library3, prefixB),
-      ElementFactory.importFor(library4, prefixA)
-    ];
-    library1.imports = imports;
-    List<LibraryElement> libraries = library1.importedLibraries;
-    expect(libraries,
-        unorderedEquals(<LibraryElement>[library2, library3, library4]));
-  }
-
-  void test_getPrefixes() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library = ElementFactory.library(context, "l1");
-    PrefixElement prefixA =
-        new PrefixElementImpl.forNode(AstFactory.identifier3("a"));
-    PrefixElement prefixB =
-        new PrefixElementImpl.forNode(AstFactory.identifier3("b"));
-    List<ImportElementImpl> imports = [
-      ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
-      ElementFactory.importFor(ElementFactory.library(context, "l3"), null),
-      ElementFactory.importFor(ElementFactory.library(context, "l4"), prefixA),
-      ElementFactory.importFor(ElementFactory.library(context, "l5"), prefixA),
-      ElementFactory.importFor(ElementFactory.library(context, "l6"), prefixB)
-    ];
-    library.imports = imports;
-    List<PrefixElement> prefixes = library.prefixes;
-    expect(prefixes, hasLength(2));
-    if (identical(prefixA, prefixes[0])) {
-      expect(prefixes[1], same(prefixB));
-    } else {
-      expect(prefixes[0], same(prefixB));
-      expect(prefixes[1], same(prefixA));
-    }
-  }
-
-  void test_getUnits() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library = ElementFactory.library(context, "test");
-    CompilationUnitElement unitLib = library.definingCompilationUnit;
-    CompilationUnitElementImpl unitA =
-        ElementFactory.compilationUnit("unit_a.dart", unitLib.source);
-    CompilationUnitElementImpl unitB =
-        ElementFactory.compilationUnit("unit_b.dart", unitLib.source);
-    library.parts = <CompilationUnitElement>[unitA, unitB];
-    expect(library.units,
-        unorderedEquals(<CompilationUnitElement>[unitLib, unitA, unitB]));
-  }
-
-  void test_getVisibleLibraries_cycle() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library = ElementFactory.library(context, "app");
-    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
-    libraryA.imports = <ImportElementImpl>[
-      ElementFactory.importFor(library, null)
-    ];
-    library.imports = <ImportElementImpl>[
-      ElementFactory.importFor(libraryA, null)
-    ];
-    List<LibraryElement> libraries = library.visibleLibraries;
-    expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA]));
-  }
-
-  void test_getVisibleLibraries_directExports() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library = ElementFactory.library(context, "app");
-    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
-    library.exports = <ExportElementImpl>[ElementFactory.exportFor(libraryA)];
-    List<LibraryElement> libraries = library.visibleLibraries;
-    expect(libraries, unorderedEquals(<LibraryElement>[library]));
-  }
-
-  void test_getVisibleLibraries_directImports() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library = ElementFactory.library(context, "app");
-    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
-    library.imports = <ImportElementImpl>[
-      ElementFactory.importFor(libraryA, null)
-    ];
-    List<LibraryElement> libraries = library.visibleLibraries;
-    expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA]));
-  }
-
-  void test_getVisibleLibraries_indirectExports() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library = ElementFactory.library(context, "app");
-    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
-    LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
-    libraryA.exports = <ExportElementImpl>[ElementFactory.exportFor(libraryAA)];
-    library.imports = <ImportElementImpl>[
-      ElementFactory.importFor(libraryA, null)
-    ];
-    List<LibraryElement> libraries = library.visibleLibraries;
-    expect(libraries,
-        unorderedEquals(<LibraryElement>[library, libraryA, libraryAA]));
-  }
-
-  void test_getVisibleLibraries_indirectImports() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library = ElementFactory.library(context, "app");
-    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
-    LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
-    LibraryElementImpl libraryB = ElementFactory.library(context, "B");
-    libraryA.imports = <ImportElementImpl>[
-      ElementFactory.importFor(libraryAA, null)
-    ];
-    library.imports = <ImportElementImpl>[
-      ElementFactory.importFor(libraryA, null),
-      ElementFactory.importFor(libraryB, null)
-    ];
-    List<LibraryElement> libraries = library.visibleLibraries;
-    expect(
-        libraries,
-        unorderedEquals(
-            <LibraryElement>[library, libraryA, libraryAA, libraryB]));
-  }
-
-  void test_getVisibleLibraries_noImports() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library = ElementFactory.library(context, "app");
-    expect(
-        library.visibleLibraries, unorderedEquals(<LibraryElement>[library]));
-  }
-
-  void test_isUpToDate() {
-    AnalysisContext context = createAnalysisContext();
-    context.sourceFactory = new SourceFactory([]);
-    LibraryElement library = ElementFactory.library(context, "foo");
-    context.setContents(library.definingCompilationUnit.source, "sdfsdff");
-    // Assert that we are not up to date if the target has an old time stamp.
-    expect(library.isUpToDate(0), isFalse);
-    // Assert that we are up to date with a target modification time in the
-    // future.
-    expect(library.isUpToDate(JavaSystem.currentTimeMillis() + 1000), isTrue);
-  }
-
-  void test_setImports() {
-    AnalysisContext context = createAnalysisContext();
-    LibraryElementImpl library = new LibraryElementImpl.forNode(
-        context, AstFactory.libraryIdentifier2(["l1"]));
-    List<ImportElementImpl> expectedImports = [
-      ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
-      ElementFactory.importFor(ElementFactory.library(context, "l3"), null)
-    ];
-    library.imports = expectedImports;
-    List<ImportElement> actualImports = library.imports;
-    expect(actualImports, hasLength(expectedImports.length));
-    for (int i = 0; i < actualImports.length; i++) {
-      expect(actualImports[i], same(expectedImports[i]));
-    }
-  }
-}
-
-@reflectiveTest
-class MethodElementImplTest extends EngineTestCase {
-  void test_computeNode() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource(
-        "/test.dart",
-        r'''
-abstract class A {
-  String m1() => null;
-  m2();
-}
-''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // m1
-    {
-      MethodElement m1Element = unitElement.getType("A").getMethod('m1');
-      MethodDeclaration m1Node = m1Element.computeNode();
-      expect(m1Node, isNotNull);
-      expect(m1Node.name.name, "m1");
-      expect(m1Node.element, same(m1Element));
-    }
-    // m2
-    {
-      MethodElement m2Element = unitElement.getType("A").getMethod('m2');
-      MethodDeclaration m2Node = m2Element.computeNode();
-      expect(m2Node, isNotNull);
-      expect(m2Node.name.name, "m2");
-      expect(m2Node.element, same(m2Element));
-    }
-  }
-
-  void test_computeNode_withoutFunctionBody() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.analyzeFunctionBodies = false;
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper(options);
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource(
-        "/test.dart",
-        r'''
-abstract class A {
-  String m1() => null;
-  m2();
-}
-''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // m1
-    {
-      MethodElement m1Element = unitElement.getType("A").getMethod('m1');
-      MethodDeclaration m1Node = m1Element.computeNode();
-      expect(m1Node, isNotNull);
-      expect(m1Node.name.name, "m1");
-      expect(m1Node.element, same(m1Element));
-    }
-    // m2
-    {
-      MethodElement m2Element = unitElement.getType("A").getMethod('m2');
-      MethodDeclaration m2Node = m2Element.computeNode();
-      expect(m2Node, isNotNull);
-      expect(m2Node.name.name, "m2");
-      expect(m2Node.element, same(m2Element));
-    }
-  }
-}
-
-@reflectiveTest
-class MultiplyDefinedElementImplTest extends EngineTestCase {
-  void test_fromElements_conflicting() {
-    Element firstElement = ElementFactory.localVariableElement2("xx");
-    Element secondElement = ElementFactory.localVariableElement2("yy");
-    Element result = MultiplyDefinedElementImpl.fromElements(
-        null, firstElement, secondElement);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is MultiplyDefinedElement, MultiplyDefinedElement, result);
-    List<Element> elements =
-        (result as MultiplyDefinedElement).conflictingElements;
-    expect(elements, hasLength(2));
-    for (int i = 0; i < elements.length; i++) {
-      EngineTestCase.assertInstanceOf((obj) => obj is LocalVariableElement,
-          LocalVariableElement, elements[i]);
-    }
-  }
-
-  void test_fromElements_multiple() {
-    Element firstElement = ElementFactory.localVariableElement2("xx");
-    Element secondElement = ElementFactory.localVariableElement2("yy");
-    Element thirdElement = ElementFactory.localVariableElement2("zz");
-    Element result = MultiplyDefinedElementImpl.fromElements(
-        null,
-        MultiplyDefinedElementImpl.fromElements(
-            null, firstElement, secondElement),
-        thirdElement);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is MultiplyDefinedElement, MultiplyDefinedElement, result);
-    List<Element> elements =
-        (result as MultiplyDefinedElement).conflictingElements;
-    expect(elements, hasLength(3));
-    for (int i = 0; i < elements.length; i++) {
-      EngineTestCase.assertInstanceOf((obj) => obj is LocalVariableElement,
-          LocalVariableElement, elements[i]);
-    }
-  }
-
-  void test_fromElements_nonConflicting() {
-    Element element = ElementFactory.localVariableElement2("xx");
-    expect(MultiplyDefinedElementImpl.fromElements(null, element, element),
-        same(element));
-  }
-}
-
-@reflectiveTest
-class ParameterElementImplTest extends EngineTestCase {
-  void test_computeNode_DefaultFormalParameter() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource(
-        "/test.dart",
-        r'''
-main([int p = 42]) {
-}''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // p
-    {
-      ParameterElement element = unitElement.functions[0].parameters[0];
-      DefaultFormalParameter node = element.computeNode();
-      expect(node, isNotNull);
-      expect(node.identifier.name, 'p');
-      expect(node.element, same(element));
-    }
-  }
-
-  void test_computeNode_FieldFormalParameter() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource(
-        "/test.dart",
-        r'''
-class A {
-  int p;
-  A(this.p) {
-  }
-}''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // p
-    {
-      ClassElement classA = unitElement.types[0];
-      ConstructorElement constructorA = classA.constructors[0];
-      FieldFormalParameterElement element = constructorA.parameters[0];
-      FieldFormalParameter node = element.computeNode();
-      expect(node, isNotNull);
-      expect(node.identifier.name, 'p');
-      expect(node.element, same(element));
-    }
-  }
-
-  void test_computeNode_FunctionTypedFormalParameter() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource(
-        "/test.dart",
-        r'''
-main(p(int a, int b)) {
-}''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // p
-    {
-      ParameterElement element = unitElement.functions[0].parameters[0];
-      FunctionTypedFormalParameter node = element.computeNode();
-      expect(node, isNotNull);
-      expect(node.identifier.name, 'p');
-      expect(node.element, same(element));
-    }
-  }
-
-  void test_computeNode_SimpleFormalParameter() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource(
-        "/test.dart",
-        r'''
-main(int p) {
-}''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // p
-    {
-      ParameterElement element = unitElement.functions[0].parameters[0];
-      SimpleFormalParameter node = element.computeNode();
-      expect(node, isNotNull);
-      expect(node.identifier.name, 'p');
-      expect(node.element, same(element));
-    }
-  }
-}
-
-@reflectiveTest
-class TypeParameterTypeImplTest extends EngineTestCase {
-  void test_creation() {
-    expect(
-        new TypeParameterTypeImpl(
-            new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"))),
-        isNotNull);
-  }
-
-  void test_getElement() {
-    TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
-    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
-    expect(type.element, element);
-  }
-
-  void test_isMoreSpecificThan_typeArguments_dynamic() {
-    TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
-    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
-    // E << dynamic
-    expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
-  }
-
-  void test_isMoreSpecificThan_typeArguments_object() {
-    TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
-    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
-    // E << Object
-    expect(type.isMoreSpecificThan(ElementFactory.object.type), isTrue);
-  }
-
-  void test_isMoreSpecificThan_typeArguments_resursive() {
-    ClassElementImpl classS = ElementFactory.classElement2("A");
-    TypeParameterElementImpl typeParameterU =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("U"));
-    TypeParameterTypeImpl typeParameterTypeU =
-        new TypeParameterTypeImpl(typeParameterU);
-    TypeParameterElementImpl typeParameterT =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
-    TypeParameterTypeImpl typeParameterTypeT =
-        new TypeParameterTypeImpl(typeParameterT);
-    typeParameterT.bound = typeParameterTypeU;
-    typeParameterU.bound = typeParameterTypeU;
-    // <T extends U> and <U extends T>
-    // T << S
-    expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isFalse);
-  }
-
-  void test_isMoreSpecificThan_typeArguments_self() {
-    TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
-    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
-    // E << E
-    expect(type.isMoreSpecificThan(type), isTrue);
-  }
-
-  void test_isMoreSpecificThan_typeArguments_transitivity_interfaceTypes() {
-    //  class A {}
-    //  class B extends A {}
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    TypeParameterElementImpl typeParameterT =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
-    typeParameterT.bound = typeB;
-    TypeParameterTypeImpl typeParameterTypeT =
-        new TypeParameterTypeImpl(typeParameterT);
-    // <T extends B>
-    // T << A
-    expect(typeParameterTypeT.isMoreSpecificThan(typeA), isTrue);
-  }
-
-  void test_isMoreSpecificThan_typeArguments_transitivity_typeParameters() {
-    ClassElementImpl classS = ElementFactory.classElement2("A");
-    TypeParameterElementImpl typeParameterU =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("U"));
-    typeParameterU.bound = classS.type;
-    TypeParameterTypeImpl typeParameterTypeU =
-        new TypeParameterTypeImpl(typeParameterU);
-    TypeParameterElementImpl typeParameterT =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
-    typeParameterT.bound = typeParameterTypeU;
-    TypeParameterTypeImpl typeParameterTypeT =
-        new TypeParameterTypeImpl(typeParameterT);
-    // <T extends U> and <U extends S>
-    // T << S
-    expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue);
-  }
-
-  void test_isMoreSpecificThan_typeArguments_upperBound() {
-    ClassElementImpl classS = ElementFactory.classElement2("A");
-    TypeParameterElementImpl typeParameterT =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
-    typeParameterT.bound = classS.type;
-    TypeParameterTypeImpl typeParameterTypeT =
-        new TypeParameterTypeImpl(typeParameterT);
-    // <T extends S>
-    // T << S
-    expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue);
-  }
-
-  void test_substitute_equal() {
-    TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
-    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
-    InterfaceTypeImpl argument = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("A")));
-    TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(element);
-    expect(type.substitute2(<DartType>[argument], <DartType>[parameter]),
-        same(argument));
-  }
-
-  void test_substitute_notEqual() {
-    TypeParameterTypeImpl type = new TypeParameterTypeImpl(
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
-    InterfaceTypeImpl argument = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("A")));
-    TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("F")));
-    expect(type.substitute2(<DartType>[argument], <DartType>[parameter]),
-        same(type));
-  }
-}
-
-@reflectiveTest
-class VoidTypeImplTest extends EngineTestCase {
-  /**
-   * Reference {code VoidTypeImpl.getInstance()}.
-   */
-  DartType _voidType = VoidTypeImpl.instance;
-
-  void test_isMoreSpecificThan_void_A() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    expect(_voidType.isMoreSpecificThan(classA.type), isFalse);
-  }
-
-  void test_isMoreSpecificThan_void_dynamic() {
-    expect(_voidType.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
-  }
-
-  void test_isMoreSpecificThan_void_void() {
-    expect(_voidType.isMoreSpecificThan(_voidType), isTrue);
-  }
-
-  void test_isSubtypeOf_void_A() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    expect(_voidType.isSubtypeOf(classA.type), isFalse);
-  }
-
-  void test_isSubtypeOf_void_dynamic() {
-    expect(_voidType.isSubtypeOf(DynamicTypeImpl.instance), isTrue);
-  }
-
-  void test_isSubtypeOf_void_void() {
-    expect(_voidType.isSubtypeOf(_voidType), isTrue);
-  }
-
-  void test_isVoid() {
-    expect(_voidType.isVoid, isTrue);
-  }
-}
-
-class _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction
-    extends InterfaceTypeImpl {
-  _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction(ClassElement arg0)
-      : super(arg0);
-
-  @override
-  bool get isDartCoreFunction => true;
-}
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 7224060..e2b20b3 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -2,2474 +2,32 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.engine_test;
+library analyzer.test.generated.engine_test;
 
 import 'dart:async';
-import 'dart:collection';
 
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/cancelable_future.dart';
-import 'package:analyzer/src/context/cache.dart' show CacheEntry;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/source/embedder.dart';
+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';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht;
 import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
-import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
-import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/utilities_collection.dart';
-import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/task/model.dart' as newContext;
+import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart' show Document;
-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';
 
 import '../reflective_tests.dart';
 import '../utils.dart';
-import 'all_the_rest_test.dart';
-import 'resolver_test.dart';
-import 'test_support.dart';
 
 main() {
   initializeTestEnvironment();
-  // Tests for the classes used in both old and new analysis implementations.
   runReflectiveTests(SourcesChangedEventTest);
-  // Tests for the classes used in the old analysis implementation.
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(AnalysisCacheTest);
-    runReflectiveTests(AnalysisContextImplTest);
-    runReflectiveTests(AnalysisTaskTest);
-    runReflectiveTests(AnalysisOptionsImplTest);
-    runReflectiveTests(DartEntryTest);
-    runReflectiveTests(GenerateDartErrorsTaskTest);
-    runReflectiveTests(GenerateDartHintsTaskTest);
-    runReflectiveTests(GenerateDartLintsTaskTest);
-    runReflectiveTests(GetContentTaskTest);
-    runReflectiveTests(HtmlEntryTest);
-    runReflectiveTests(IncrementalAnalysisCacheTest);
-    runReflectiveTests(IncrementalAnalysisTaskTest);
-    runReflectiveTests(LintGeneratorTest);
-    runReflectiveTests(ParseDartTaskTest);
-    runReflectiveTests(ParseHtmlTaskTest);
-    runReflectiveTests(PartitionManagerTest);
-    runReflectiveTests(ResolveDartLibraryTaskTest);
-    runReflectiveTests(ResolveDartUnitTaskTest);
-    runReflectiveTests(ResolveHtmlTaskTest);
-    runReflectiveTests(ScanDartTaskTest);
-    runReflectiveTests(SdkCachePartitionTest);
-    runReflectiveTests(UniversalCachePartitionTest);
-    runReflectiveTests(WorkManagerTest);
-  }
-}
-
-@reflectiveTest
-class AnalysisCacheTest extends EngineTestCase {
-  void test_creation() {
-    expect(new AnalysisCache(new List<CachePartition>(0)), isNotNull);
-  }
-
-  void test_get() {
-    AnalysisCache cache = new AnalysisCache(new List<CachePartition>(0));
-    TestSource source = new TestSource();
-    expect(cache.get(source), isNull);
-  }
-
-  void test_iterator() {
-    CachePartition partition =
-        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    cache.put(source, entry);
-    MapIterator<Source, SourceEntry> iterator = cache.iterator();
-    expect(iterator.moveNext(), isTrue);
-    expect(iterator.key, same(source));
-    expect(iterator.value, same(entry));
-    expect(iterator.moveNext(), isFalse);
-  }
-
-  /**
-   * Verify that if multiple Source objects refer to the same file via
-   * different URIs, they are treated as separate entries in the cache.
-   */
-  void test_lookup_distinguishes_uris() {
-    CachePartition partition =
-        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    JavaFile file = new JavaFile('baz.dart');
-    Source source1 = new FileBasedSource(file);
-    Source source2 =
-        new FileBasedSource(file, Uri.parse('package:foo/baz.dart'));
-    Source source3 =
-        new FileBasedSource(file, Uri.parse('package:bar/baz.dart'));
-    DartEntry entry1 = new DartEntry();
-    DartEntry entry2 = new DartEntry();
-    DartEntry entry3 = new DartEntry();
-    cache.put(source1, entry1);
-    cache.put(source2, entry2);
-    cache.put(source3, entry3);
-    expect(cache.get(source1), same(entry1));
-    expect(cache.get(source2), same(entry2));
-    expect(cache.get(source3), same(entry3));
-  }
-
-  void test_put_noFlush() {
-    CachePartition partition =
-        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    cache.put(source, entry);
-    expect(cache.get(source), same(entry));
-  }
-
-  void test_setMaxCacheSize() {
-    CachePartition partition = new UniversalCachePartition(
-        null, 8, new _AnalysisCacheTest_test_setMaxCacheSize());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    int size = 6;
-    for (int i = 0; i < size; i++) {
-      Source source = new TestSource("/test$i.dart");
-      DartEntry entry = new DartEntry();
-      entry.setValue(DartEntry.PARSED_UNIT, null);
-      cache.put(source, entry);
-      cache.accessedAst(source);
-    }
-    _assertNonFlushedCount(size, cache);
-    int newSize = size - 2;
-    partition.maxCacheSize = newSize;
-    _assertNonFlushedCount(newSize, cache);
-  }
-
-  void test_size() {
-    CachePartition partition =
-        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    int size = 4;
-    for (int i = 0; i < size; i++) {
-      Source source = new TestSource("/test$i.dart");
-      cache.put(source, new DartEntry());
-      cache.accessedAst(source);
-    }
-    expect(cache.size(), size);
-  }
-
-  void _assertNonFlushedCount(int expectedCount, AnalysisCache cache) {
-    int nonFlushedCount = 0;
-    MapIterator<Source, SourceEntry> iterator = cache.iterator();
-    while (iterator.moveNext()) {
-      if (iterator.value.getState(DartEntry.PARSED_UNIT) !=
-          CacheState.FLUSHED) {
-        nonFlushedCount++;
-      }
-    }
-    expect(nonFlushedCount, expectedCount);
-  }
-}
-
-@reflectiveTest
-class AnalysisContextImplTest extends EngineTestCase {
-  /**
-   * An analysis context whose source factory is [sourceFactory].
-   */
-  AnalysisContextImpl _context;
-
-  /**
-   * The source factory associated with the analysis [context].
-   */
-  SourceFactory _sourceFactory;
-
-  void fail_performAnalysisTask_importedLibraryDelete_html() {
-    Source htmlSource = _addSource(
-        "/page.html",
-        r'''
-<html><body><script type="application/dart">
-  import 'libB.dart';
-  main() {print('hello dart');}
-</script></body></html>''');
-    Source libBSource = _addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
-        reason: "htmlUnit resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 1");
-    expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(htmlSource)),
-        isTrue,
-        reason: "htmlSource doesn't have errors");
-    // remove libB.dart content and analyze
-    _context.setContents(libBSource, null);
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
-        reason: "htmlUnit resolved 1");
-    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
-    expect(_hasAnalysisErrorWithErrorSeverity(errors), isTrue,
-        reason: "htmlSource has an error");
-  }
-
-  void fail_recordLibraryElements() {
-    fail("Implement this");
-  }
-
-  @override
-  void setUp() {
-    _context = new AnalysisContextImpl();
-    _sourceFactory = new SourceFactory([
-      new DartUriResolver(DirectoryBasedDartSdk.defaultSdk),
-      new FileUriResolver()
-    ]);
-    _context.sourceFactory = _sourceFactory;
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(_context.analysisOptions);
-    options.cacheSize = 256;
-    _context.analysisOptions = options;
-  }
-
-  @override
-  void tearDown() {
-    _context = null;
-    _sourceFactory = null;
-    super.tearDown();
-  }
-
-  Future test_applyChanges_add() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  Future test_applyChanges_change() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet1 = new ChangeSet();
-    changeSet1.addedSource(source);
-    _context.applyChanges(changeSet1);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    Source source2 =
-        new FileBasedSource(FileUtilities2.createFile("/test2.dart"));
-    ChangeSet changeSet2 = new ChangeSet();
-    changeSet2.addedSource(source2);
-    changeSet2.changedSource(source);
-    _context.applyChanges(changeSet2);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  Future test_applyChanges_change_content() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet1 = new ChangeSet();
-    changeSet1.addedSource(source);
-    _context.applyChanges(changeSet1);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    Source source2 =
-        new FileBasedSource(FileUtilities2.createFile("/test2.dart"));
-    ChangeSet changeSet2 = new ChangeSet();
-    changeSet2.addedSource(source2);
-    changeSet2.changedContent(source, 'library test;');
-    _context.applyChanges(changeSet2);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_applyChanges_change_flush_element() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source librarySource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-int a = 0;''');
-    expect(_context.computeLibraryElement(librarySource), isNotNull);
-    _context.setContents(
-        librarySource,
-        r'''
-library lib;
-int aa = 0;''');
-    expect(_context.getLibraryElement(librarySource), isNull);
-  }
-
-  Future test_applyChanges_change_multiple() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String libraryContents1 = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = _addSource("/lib.dart", libraryContents1);
-    String partContents1 = r'''
-part of lib;
-int b = a;''';
-    Source partSource = _addSource("/part.dart", partContents1);
-    _context.computeLibraryElement(librarySource);
-    String libraryContents2 = r'''
-library lib;
-part 'part.dart';
-int aa = 0;''';
-    _context.setContents(librarySource, libraryContents2);
-    String partContents2 = r'''
-part of lib;
-int b = aa;''';
-    _context.setContents(partSource, partContents2);
-    _context.computeLibraryElement(librarySource);
-    CompilationUnit libraryUnit =
-        _context.resolveCompilationUnit2(librarySource, librarySource);
-    CompilationUnit partUnit =
-        _context.resolveCompilationUnit2(partSource, librarySource);
-    TopLevelVariableDeclaration declaration =
-        libraryUnit.declarations[0] as TopLevelVariableDeclaration;
-    Element declarationElement = declaration.variables.variables[0].element;
-    TopLevelVariableDeclaration use =
-        partUnit.declarations[0] as TopLevelVariableDeclaration;
-    Element useElement = (use.variables.variables[0].initializer
-        as SimpleIdentifier).staticElement;
-    expect((useElement as PropertyAccessorElement).variable,
-        same(declarationElement));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  Future test_applyChanges_change_range() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet1 = new ChangeSet();
-    changeSet1.addedSource(source);
-    _context.applyChanges(changeSet1);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    Source source2 =
-        new FileBasedSource(FileUtilities2.createFile("/test2.dart"));
-    ChangeSet changeSet2 = new ChangeSet();
-    changeSet2.addedSource(source2);
-    changeSet2.changedRange(source, 'library test;', 0, 0, 13);
-    _context.applyChanges(changeSet2);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_applyChanges_empty() {
-    _context.applyChanges(new ChangeSet());
-    expect(_context.performAnalysisTask().changeNotices, isNull);
-  }
-
-  void test_applyChanges_overriddenSource() {
-    // Note: addSource adds the source to the contentCache.
-    Source source = _addSource("/test.dart", "library test;");
-    _context.computeErrors(source);
-    while (!_context.sourcesNeedingProcessing.isEmpty) {
-      _context.performAnalysisTask();
-    }
-    // Adding the source as a changedSource should have no effect since
-    // it is already overridden in the content cache.
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.changedSource(source);
-    _context.applyChanges(changeSet);
-    expect(_context.sourcesNeedingProcessing, hasLength(0));
-  }
-
-  Future test_applyChanges_remove() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String libAContents = r'''
-library libA;
-import 'libB.dart';''';
-    Source libA = _addSource("/libA.dart", libAContents);
-    String libBContents = "library libB;";
-    Source libB = _addSource("/libB.dart", libBContents);
-    LibraryElement libAElement = _context.computeLibraryElement(libA);
-    List<LibraryElement> importedLibraries = libAElement.importedLibraries;
-    expect(importedLibraries, hasLength(2));
-    _context.computeErrors(libA);
-    _context.computeErrors(libB);
-    expect(_context.sourcesNeedingProcessing, hasLength(0));
-    _context.setContents(libB, null);
-    _removeSource(libB);
-    List<Source> sources = _context.sourcesNeedingProcessing;
-    expect(sources, hasLength(1));
-    expect(sources[0], same(libA));
-    libAElement = _context.computeLibraryElement(libA);
-    importedLibraries = libAElement.importedLibraries;
-    expect(importedLibraries, hasLength(1));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [libA]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [libB]);
-      listener.assertEvent(changedSources: [libB]);
-      listener.assertEvent(wereSourcesRemovedOrDeleted: true);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  /**
-   * IDEA uses the following scenario:
-   * 1. Add overlay.
-   * 2. Change overlay.
-   * 3. If the contents of the document buffer is the same as the contents
-   *    of the file, remove overlay.
-   * So, we need to try to use incremental resolution for removing overlays too.
-   */
-  void test_applyChanges_remove_incremental() {
-    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-    Source source = resourceProvider
-        .newFile(
-            '/test.dart',
-            r'''
-main() {
-  print(1);
-}
-''')
-        .createSource();
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _context.analysisOptions = new AnalysisOptionsImpl()..incremental = true;
-    _context.applyChanges(new ChangeSet()..addedSource(source));
-    // remember compilation unit
-    _analyzeAll_assertFinished();
-    CompilationUnit unit = _context.getResolvedCompilationUnit2(source, source);
-    // add overlay
-    _context.setContents(
-        source,
-        r'''
-main() {
-  print(12);
-}
-''');
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedCompilationUnit2(source, source), unit);
-    // remove overlay
-    _context.setContents(source, null);
-    _context.validateCacheConsistency();
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedCompilationUnit2(source, source), unit);
-  }
-
-  Future test_applyChanges_removeContainer() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String libAContents = r'''
-library libA;
-import 'libB.dart';''';
-    Source libA = _addSource("/libA.dart", libAContents);
-    String libBContents = "library libB;";
-    Source libB = _addSource("/libB.dart", libBContents);
-    _context.computeLibraryElement(libA);
-    _context.computeErrors(libA);
-    _context.computeErrors(libB);
-    expect(_context.sourcesNeedingProcessing, hasLength(0));
-    ChangeSet changeSet = new ChangeSet();
-    SourceContainer removedContainer =
-        new _AnalysisContextImplTest_test_applyChanges_removeContainer(libB);
-    changeSet.removedContainer(removedContainer);
-    _context.applyChanges(changeSet);
-    List<Source> sources = _context.sourcesNeedingProcessing;
-    expect(sources, hasLength(1));
-    expect(sources[0], same(libA));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [libA]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [libB]);
-      listener.assertEvent(wereSourcesRemovedOrDeleted: true);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_computeDocumentationComment_block() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    String comment = "/** Comment */";
-    Source source = _addSource(
-        "/test.dart",
-        """
-$comment
-class A {}""");
-    LibraryElement libraryElement = _context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    expect(_context.computeDocumentationComment(classElement), comment);
-  }
-
-  void test_computeDocumentationComment_none() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.dart", "class A {}");
-    LibraryElement libraryElement = _context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    expect(_context.computeDocumentationComment(classElement), isNull);
-  }
-
-  void test_computeDocumentationComment_null() {
-    expect(_context.computeDocumentationComment(null), isNull);
-  }
-
-  void test_computeDocumentationComment_singleLine_multiple_EOL_n() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    String comment = "/// line 1\n/// line 2\n/// line 3\n";
-    Source source = _addSource("/test.dart", "${comment}class A {}");
-    LibraryElement libraryElement = _context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    String actual = _context.computeDocumentationComment(classElement);
-    expect(actual, "/// line 1\n/// line 2\n/// line 3");
-  }
-
-  void test_computeDocumentationComment_singleLine_multiple_EOL_rn() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    String comment = "/// line 1\r\n/// line 2\r\n/// line 3\r\n";
-    Source source = _addSource("/test.dart", "${comment}class A {}");
-    LibraryElement libraryElement = _context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    String actual = _context.computeDocumentationComment(classElement);
-    expect(actual, "/// line 1\n/// line 2\n/// line 3");
-  }
-
-  void test_computeErrors_dart_none() {
-    Source source = _addSource("/lib.dart", "library lib;");
-    List<AnalysisError> errors = _context.computeErrors(source);
-    expect(errors, hasLength(0));
-  }
-
-  void test_computeErrors_dart_part() {
-    Source librarySource =
-        _addSource("/lib.dart", "library lib; part 'part.dart';");
-    Source partSource = _addSource("/part.dart", "part of 'lib';");
-    _context.parseCompilationUnit(librarySource);
-    List<AnalysisError> errors = _context.computeErrors(partSource);
-    expect(errors, isNotNull);
-    expect(errors.length > 0, isTrue);
-  }
-
-  void test_computeErrors_dart_some() {
-    Source source = _addSource("/lib.dart", "library 'lib';");
-    List<AnalysisError> errors = _context.computeErrors(source);
-    expect(errors, isNotNull);
-    expect(errors.length > 0, isTrue);
-  }
-
-  void test_computeErrors_html_none() {
-    Source source = _addSource("/test.html", "<html></html>");
-    List<AnalysisError> errors = _context.computeErrors(source);
-    expect(errors, hasLength(0));
-  }
-
-  void test_computeExportedLibraries_none() {
-    Source source = _addSource("/test.dart", "library test;");
-    expect(_context.computeExportedLibraries(source), hasLength(0));
-  }
-
-  void test_computeExportedLibraries_some() {
-    //    addSource("/lib1.dart", "library lib1;");
-    //    addSource("/lib2.dart", "library lib2;");
-    Source source = _addSource(
-        "/test.dart", "library test; export 'lib1.dart'; export 'lib2.dart';");
-    expect(_context.computeExportedLibraries(source), hasLength(2));
-  }
-
-  void test_computeHtmlElement_nonHtml() {
-    Source source = _addSource("/test.dart", "library test;");
-    expect(_context.computeHtmlElement(source), isNull);
-  }
-
-  void test_computeHtmlElement_valid() {
-    Source source = _addSource("/test.html", "<html></html>");
-    HtmlElement element = _context.computeHtmlElement(source);
-    expect(element, isNotNull);
-    expect(_context.computeHtmlElement(source), same(element));
-  }
-
-  void test_computeImportedLibraries_none() {
-    Source source = _addSource("/test.dart", "library test;");
-    expect(_context.computeImportedLibraries(source), hasLength(0));
-  }
-
-  void test_computeImportedLibraries_some() {
-    //    addSource("/lib1.dart", "library lib1;");
-    //    addSource("/lib2.dart", "library lib2;");
-    Source source = _addSource(
-        "/test.dart", "library test; import 'lib1.dart'; import 'lib2.dart';");
-    expect(_context.computeImportedLibraries(source), hasLength(2));
-  }
-
-  void test_computeKindOf_html() {
-    Source source = _addSource("/test.html", "");
-    expect(_context.computeKindOf(source), same(SourceKind.HTML));
-  }
-
-  void test_computeKindOf_library() {
-    Source source = _addSource("/test.dart", "library lib;");
-    expect(_context.computeKindOf(source), same(SourceKind.LIBRARY));
-  }
-
-  void test_computeKindOf_libraryAndPart() {
-    Source source = _addSource("/test.dart", "library lib; part of lib;");
-    expect(_context.computeKindOf(source), same(SourceKind.LIBRARY));
-  }
-
-  void test_computeKindOf_part() {
-    Source source = _addSource("/test.dart", "part of lib;");
-    expect(_context.computeKindOf(source), same(SourceKind.PART));
-  }
-
-  void test_computeLibraryElement() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.dart", "library lib;");
-    LibraryElement element = _context.computeLibraryElement(source);
-    expect(element, isNotNull);
-  }
-
-  void test_computeLineInfo_dart() {
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-library lib;
-
-main() {}''');
-    LineInfo info = _context.computeLineInfo(source);
-    expect(info, isNotNull);
-  }
-
-  void test_computeLineInfo_html() {
-    Source source = _addSource(
-        "/test.html",
-        r'''
-<html>
-  <body>
-    <h1>A</h1>
-  </body>
-</html>''');
-    LineInfo info = _context.computeLineInfo(source);
-    expect(info, isNotNull);
-  }
-
-  void test_computeResolvableCompilationUnit_dart_exception() {
-    TestSource source = _addSourceWithException("/test.dart");
-    try {
-      _context.computeResolvableCompilationUnit(source);
-      fail("Expected AnalysisException");
-    } on AnalysisException {
-      // Expected
-    }
-  }
-
-  void test_computeResolvableCompilationUnit_html_exception() {
-    Source source = _addSource("/lib.html", "<html></html>");
-    try {
-      _context.computeResolvableCompilationUnit(source);
-      fail("Expected AnalysisException");
-    } on AnalysisException {
-      // Expected
-    }
-  }
-
-  void test_computeResolvableCompilationUnit_valid() {
-    Source source = _addSource("/lib.dart", "library lib;");
-    CompilationUnit parsedUnit = _context.parseCompilationUnit(source);
-    expect(parsedUnit, isNotNull);
-    CompilationUnit resolvedUnit =
-        _context.computeResolvableCompilationUnit(source);
-    expect(resolvedUnit, isNotNull);
-    expect(resolvedUnit, same(parsedUnit));
-  }
-
-  Future test_computeResolvedCompilationUnitAsync() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-    bool completed = false;
-    _context
-        .computeResolvedCompilationUnitAsync(source, source)
-        .then((CompilationUnit unit) {
-      expect(unit, isNotNull);
-      completed = true;
-    });
-    return pumpEventQueue().then((_) {
-      expect(completed, isFalse);
-      _performPendingAnalysisTasks();
-    }).then((_) => pumpEventQueue()).then((_) {
-      expect(completed, isTrue);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_afterDispose() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-    // Dispose of the context.
-    _context.dispose();
-    // Any attempt to start an asynchronous computation should return a future
-    // which completes with error.
-    CancelableFuture<CompilationUnit> future =
-        _context.computeResolvedCompilationUnitAsync(source, source);
-    bool completed = false;
-    future.then((CompilationUnit unit) {
-      fail('Future should have completed with error');
-    }, onError: (error) {
-      expect(error, new isInstanceOf<AnalysisNotScheduledError>());
-      completed = true;
-    });
-    return pumpEventQueue().then((_) {
-      expect(completed, isTrue);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_cancel() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-    CancelableFuture<CompilationUnit> future =
-        _context.computeResolvedCompilationUnitAsync(source, source);
-    bool completed = false;
-    future.then((CompilationUnit unit) {
-      fail('Future should have been canceled');
-    }, onError: (error) {
-      expect(error, new isInstanceOf<FutureCanceledError>());
-      completed = true;
-    });
-    expect(completed, isFalse);
-    expect(_context.pendingFutureSources_forTesting, isNotEmpty);
-    future.cancel();
-    expect(_context.pendingFutureSources_forTesting, isEmpty);
-    return pumpEventQueue().then((_) {
-      expect(completed, isTrue);
-      expect(_context.pendingFutureSources_forTesting, isEmpty);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_dispose() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-    CancelableFuture<CompilationUnit> future =
-        _context.computeResolvedCompilationUnitAsync(source, source);
-    bool completed = false;
-    future.then((CompilationUnit unit) {
-      fail('Future should have completed with error');
-    }, onError: (error) {
-      expect(error, new isInstanceOf<AnalysisNotScheduledError>());
-      completed = true;
-    });
-    expect(completed, isFalse);
-    expect(_context.pendingFutureSources_forTesting, isNotEmpty);
-    // Disposing of the context should cause all pending futures to complete
-    // with AnalysisNotScheduled, so that no clients are left hanging.
-    _context.dispose();
-    expect(_context.pendingFutureSources_forTesting, isEmpty);
-    return pumpEventQueue().then((_) {
-      expect(completed, isTrue);
-      expect(_context.pendingFutureSources_forTesting, isEmpty);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_unrelatedLibrary() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source librarySource = _addSource("/lib.dart", "library lib;");
-    Source partSource = _addSource("/part.dart", "part of foo;");
-    bool completed = false;
-    _context
-        .computeResolvedCompilationUnitAsync(partSource, librarySource)
-        .then((_) {
-      fail('Expected resolution to fail');
-    }, onError: (e) {
-      expect(e, new isInstanceOf<AnalysisNotScheduledError>());
-      completed = true;
-    });
-    return pumpEventQueue().then((_) {
-      expect(completed, isFalse);
-      _performPendingAnalysisTasks();
-    }).then((_) => pumpEventQueue()).then((_) {
-      expect(completed, isTrue);
-    });
-  }
-
-  void test_configurationData() {
-    var key = new newContext.ResultDescriptor('test_key', '');
-    var testData = ['test', 'data'];
-    _context.setConfigurationData(key, testData);
-    expect(_context.getConfigurationData(key), testData);
-    var unusedKey = new newContext.ResultDescriptor('unused_key', '');
-    expect(_context.getConfigurationData(unusedKey), null);
-  }
-
-  void test_dispose() {
-    expect(_context.isDisposed, isFalse);
-    _context.dispose();
-    expect(_context.isDisposed, isTrue);
-  }
-
-  void test_exists_false() {
-    TestSource source = new TestSource();
-    source.exists2 = false;
-    expect(_context.exists(source), isFalse);
-  }
-
-  void test_exists_null() {
-    expect(_context.exists(null), isFalse);
-  }
-
-  void test_exists_overridden() {
-    Source source = new TestSource();
-    _context.setContents(source, "");
-    expect(_context.exists(source), isTrue);
-  }
-
-  void test_exists_true() {
-    expect(_context.exists(new AnalysisContextImplTest_Source_exists_true()),
-        isTrue);
-  }
-
-  void test_getAnalysisOptions() {
-    expect(_context.analysisOptions, isNotNull);
-  }
-
-  void test_getContents_fromSource() {
-    String content = "library lib;";
-    TimestampedData<String> contents =
-        _context.getContents(new TestSource('/test.dart', content));
-    expect(contents.data.toString(), content);
-  }
-
-  void test_getContents_overridden() {
-    String content = "library lib;";
-    Source source = new TestSource();
-    _context.setContents(source, content);
-    TimestampedData<String> contents = _context.getContents(source);
-    expect(contents.data.toString(), content);
-  }
-
-  void test_getContents_unoverridden() {
-    String content = "library lib;";
-    Source source = new TestSource('/test.dart', content);
-    _context.setContents(source, "part of lib;");
-    _context.setContents(source, null);
-    TimestampedData<String> contents = _context.getContents(source);
-    expect(contents.data.toString(), content);
-  }
-
-  void test_getDeclaredVariables() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    expect(_context.declaredVariables, isNotNull);
-  }
-
-  void test_getElement() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    LibraryElement core =
-        _context.computeLibraryElement(_sourceFactory.forUri("dart:core"));
-    expect(core, isNotNull);
-    ClassElement classObject =
-        _findClass(core.definingCompilationUnit, "Object");
-    expect(classObject, isNotNull);
-    ElementLocation location = classObject.location;
-    Element element = _context.getElement(location);
-    expect(element, same(classObject));
-  }
-
-  void test_getElement_constructor_named() {
-    Source source = _addSource(
-        "/lib.dart",
-        r'''
-class A {
-  A.named() {}
-}''');
-    _analyzeAll_assertFinished();
-    LibraryElement library = _context.computeLibraryElement(source);
-    ClassElement classA = _findClass(library.definingCompilationUnit, "A");
-    ConstructorElement constructor = classA.constructors[0];
-    ElementLocation location = constructor.location;
-    Element element = _context.getElement(location);
-    expect(element, same(constructor));
-  }
-
-  void test_getElement_constructor_unnamed() {
-    Source source = _addSource(
-        "/lib.dart",
-        r'''
-class A {
-  A() {}
-}''');
-    _analyzeAll_assertFinished();
-    LibraryElement library = _context.computeLibraryElement(source);
-    ClassElement classA = _findClass(library.definingCompilationUnit, "A");
-    ConstructorElement constructor = classA.constructors[0];
-    ElementLocation location = constructor.location;
-    Element element = _context.getElement(location);
-    expect(element, same(constructor));
-  }
-
-  void test_getElement_enum() {
-    Source source = _addSource('/test.dart', 'enum MyEnum {A, B, C}');
-    _analyzeAll_assertFinished();
-    LibraryElement library = _context.computeLibraryElement(source);
-    ClassElement myEnum = library.definingCompilationUnit.getEnum('MyEnum');
-    ElementLocation location = myEnum.location;
-    Element element = _context.getElement(location);
-    expect(element, same(myEnum));
-  }
-
-  void test_getErrors_dart_none() {
-    Source source = _addSource("/lib.dart", "library lib;");
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-    _context.computeErrors(source);
-    errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-  }
-
-  void test_getErrors_dart_some() {
-    Source source = _addSource("/lib.dart", "library 'lib';");
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-    _context.computeErrors(source);
-    errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(1));
-  }
-
-  void test_getErrors_html_none() {
-    Source source = _addSource("/test.html", "<html></html>");
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-    _context.computeErrors(source);
-    errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-  }
-
-  void test_getErrors_html_some() {
-    Source source = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-</head></html>''');
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-    _context.computeErrors(source);
-    errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(1));
-  }
-
-  void test_getHtmlElement_dart() {
-    Source source = _addSource("/test.dart", "");
-    expect(_context.getHtmlElement(source), isNull);
-    expect(_context.computeHtmlElement(source), isNull);
-    expect(_context.getHtmlElement(source), isNull);
-  }
-
-  void test_getHtmlElement_html() {
-    Source source = _addSource("/test.html", "<html></html>");
-    HtmlElement element = _context.getHtmlElement(source);
-    expect(element, isNull);
-    _context.computeHtmlElement(source);
-    element = _context.getHtmlElement(source);
-    expect(element, isNotNull);
-  }
-
-  void test_getHtmlFilesReferencing_html() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource = _addSource("/test.dart", "library lib;");
-    Source secondHtmlSource = _addSource("/test.html", "<html></html>");
-    _context.computeLibraryElement(librarySource);
-    List<Source> result = _context.getHtmlFilesReferencing(secondHtmlSource);
-    expect(result, hasLength(0));
-    _context.parseHtmlUnit(htmlSource);
-    result = _context.getHtmlFilesReferencing(secondHtmlSource);
-    expect(result, hasLength(0));
-  }
-
-  void test_getHtmlFilesReferencing_library() {
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource = _addSource("/test.dart", "library lib;");
-    List<Source> result = _context.getHtmlFilesReferencing(librarySource);
-    expect(result, hasLength(0));
-    _context.parseHtmlUnit(htmlSource);
-    result = _context.getHtmlFilesReferencing(librarySource);
-    expect(result, hasLength(1));
-    expect(result[0], htmlSource);
-  }
-
-  void test_getHtmlFilesReferencing_part() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource =
-        _addSource("/test.dart", "library lib; part 'part.dart';");
-    Source partSource = _addSource("/part.dart", "part of lib;");
-    _context.computeLibraryElement(librarySource);
-    List<Source> result = _context.getHtmlFilesReferencing(partSource);
-    expect(result, hasLength(0));
-    _context.parseHtmlUnit(htmlSource);
-    result = _context.getHtmlFilesReferencing(partSource);
-    expect(result, hasLength(1));
-    expect(result[0], htmlSource);
-  }
-
-  void test_getHtmlSources() {
-    List<Source> sources = _context.htmlSources;
-    expect(sources, hasLength(0));
-    Source source = _addSource("/test.html", "");
-    _context.computeKindOf(source);
-    sources = _context.htmlSources;
-    expect(sources, hasLength(1));
-    expect(sources[0], source);
-  }
-
-  void test_getKindOf_html() {
-    Source source = _addSource("/test.html", "");
-    expect(_context.getKindOf(source), same(SourceKind.HTML));
-  }
-
-  void test_getKindOf_library() {
-    Source source = _addSource("/test.dart", "library lib;");
-    expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
-    _context.computeKindOf(source);
-    expect(_context.getKindOf(source), same(SourceKind.LIBRARY));
-  }
-
-  void test_getKindOf_part() {
-    Source source = _addSource("/test.dart", "part of lib;");
-    expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
-    _context.computeKindOf(source);
-    expect(_context.getKindOf(source), same(SourceKind.PART));
-  }
-
-  void test_getKindOf_unknown() {
-    Source source = _addSource("/test.css", "");
-    expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
-  }
-
-  void test_getLaunchableClientLibrarySources() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    List<Source> sources = _context.launchableClientLibrarySources;
-    expect(sources, hasLength(0));
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-import 'dart:html';
-main() {}''');
-    _context.computeLibraryElement(source);
-    sources = _context.launchableClientLibrarySources;
-    expect(sources, hasLength(1));
-  }
-
-  void test_getLaunchableServerLibrarySources() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    List<Source> sources = _context.launchableServerLibrarySources;
-    expect(sources, hasLength(0));
-    Source source = _addSource("/test.dart", "main() {}");
-    _context.computeLibraryElement(source);
-    sources = _context.launchableServerLibrarySources;
-    expect(sources, hasLength(1));
-  }
-
-  void test_getLibrariesContaining() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source librarySource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'part.dart';''');
-    Source partSource = _addSource("/part.dart", "part of lib;");
-    _context.computeLibraryElement(librarySource);
-    List<Source> result = _context.getLibrariesContaining(librarySource);
-    expect(result, hasLength(1));
-    expect(result[0], librarySource);
-    result = _context.getLibrariesContaining(partSource);
-    expect(result, hasLength(1));
-    expect(result[0], librarySource);
-  }
-
-  void test_getLibrariesDependingOn() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source libASource = _addSource("/libA.dart", "library libA;");
-    _addSource("/libB.dart", "library libB;");
-    Source lib1Source = _addSource(
-        "/lib1.dart",
-        r'''
-library lib1;
-import 'libA.dart';
-export 'libB.dart';''');
-    Source lib2Source = _addSource(
-        "/lib2.dart",
-        r'''
-library lib2;
-import 'libB.dart';
-export 'libA.dart';''');
-    _context.computeLibraryElement(lib1Source);
-    _context.computeLibraryElement(lib2Source);
-    List<Source> result = _context.getLibrariesDependingOn(libASource);
-    expect(result, unorderedEquals([lib1Source, lib2Source]));
-  }
-
-  void test_getLibrariesReferencedFromHtml() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource = _addSource("/test.dart", "library lib;");
-    _context.computeLibraryElement(librarySource);
-    _context.parseHtmlUnit(htmlSource);
-    List<Source> result = _context.getLibrariesReferencedFromHtml(htmlSource);
-    expect(result, hasLength(1));
-    expect(result[0], librarySource);
-  }
-
-  void test_getLibrariesReferencedFromHtml_no() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    _addSource("/test.dart", "library lib;");
-    _context.parseHtmlUnit(htmlSource);
-    List<Source> result = _context.getLibrariesReferencedFromHtml(htmlSource);
-    expect(result, hasLength(0));
-  }
-
-  void test_getLibraryElement() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.dart", "library lib;");
-    LibraryElement element = _context.getLibraryElement(source);
-    expect(element, isNull);
-    _context.computeLibraryElement(source);
-    element = _context.getLibraryElement(source);
-    expect(element, isNotNull);
-  }
-
-  void test_getLibrarySources() {
-    List<Source> sources = _context.librarySources;
-    int originalLength = sources.length;
-    Source source = _addSource("/test.dart", "library lib;");
-    _context.computeKindOf(source);
-    sources = _context.librarySources;
-    expect(sources, hasLength(originalLength + 1));
-    for (Source returnedSource in sources) {
-      if (returnedSource == source) {
-        return;
-      }
-    }
-    fail("The added source was not in the list of library sources");
-  }
-
-  void test_getLineInfo() {
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-library lib;
-
-main() {}''');
-    LineInfo info = _context.getLineInfo(source);
-    expect(info, isNull);
-    _context.parseCompilationUnit(source);
-    info = _context.getLineInfo(source);
-    expect(info, isNotNull);
-  }
-
-  void test_getModificationStamp_fromSource() {
-    int stamp = 42;
-    expect(
-        _context.getModificationStamp(
-            new AnalysisContextImplTest_Source_getModificationStamp_fromSource(
-                stamp)),
-        stamp);
-  }
-
-  void test_getModificationStamp_overridden() {
-    int stamp = 42;
-    Source source =
-        new AnalysisContextImplTest_Source_getModificationStamp_overridden(
-            stamp);
-    _context.setContents(source, "");
-    expect(stamp != _context.getModificationStamp(source), isTrue);
-  }
-
-  void test_getPublicNamespace_element() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.dart", "class A {}");
-    LibraryElement library = _context.computeLibraryElement(source);
-    Namespace namespace = _context.getPublicNamespace(library);
-    expect(namespace, isNotNull);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is ClassElement, ClassElement, namespace.get("A"));
-  }
-
-  void test_getResolvedCompilationUnit_library() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library libb;");
-    LibraryElement library = _context.computeLibraryElement(source);
-    expect(_context.getResolvedCompilationUnit(source, library), isNotNull);
-    _context.setContents(source, "library lib;");
-    expect(_context.getResolvedCompilationUnit(source, library), isNull);
-  }
-
-  void test_getResolvedCompilationUnit_library_null() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    expect(_context.getResolvedCompilationUnit(source, null), isNull);
-  }
-
-  void test_getResolvedCompilationUnit_source_dart() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    expect(_context.getResolvedCompilationUnit2(source, source), isNull);
-    _context.resolveCompilationUnit2(source, source);
-    expect(_context.getResolvedCompilationUnit2(source, source), isNotNull);
-  }
-
-  void test_getResolvedCompilationUnit_source_html() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.getResolvedCompilationUnit2(source, source), isNull);
-    expect(_context.resolveCompilationUnit2(source, source), isNull);
-    expect(_context.getResolvedCompilationUnit2(source, source), isNull);
-  }
-
-  void test_getResolvedHtmlUnit() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.getResolvedHtmlUnit(source), isNull);
-    _context.resolveHtmlUnit(source);
-    expect(_context.getResolvedHtmlUnit(source), isNotNull);
-  }
-
-  void test_getSourceFactory() {
-    expect(_context.sourceFactory, same(_sourceFactory));
-  }
-
-  void test_getSourcesWithFullName() {
-    String filePath = '/foo/lib/file.dart';
-    List<Source> expected = <Source>[];
-    ChangeSet changeSet = new ChangeSet();
-
-    TestSourceWithUri source1 =
-        new TestSourceWithUri(filePath, Uri.parse('file://$filePath'));
-    expected.add(source1);
-    changeSet.addedSource(source1);
-
-    TestSourceWithUri source2 =
-        new TestSourceWithUri(filePath, Uri.parse('package:foo/file.dart'));
-    expected.add(source2);
-    changeSet.addedSource(source2);
-
-    _context.applyChanges(changeSet);
-    expect(
-        _context.getSourcesWithFullName(filePath), unorderedEquals(expected));
-  }
-
-  void test_getStatistics() {
-    AnalysisContextStatistics statistics = _context.statistics;
-    expect(statistics, isNotNull);
-    // The following lines are fragile.
-    // The values depend on the number of libraries in the SDK.
-//    assertLength(0, statistics.getCacheRows());
-//    assertLength(0, statistics.getExceptions());
-//    assertLength(0, statistics.getSources());
-  }
-
-  Future test_implicitAnalysisEvents_added() async {
-    AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
-    _context.implicitAnalysisEvents.listen(listener.onData);
-    //
-    // Create a file that references an file that is not explicitly being
-    // analyzed and fully analyze it. Ensure that the listener is told about
-    // the implicitly analyzed file.
-    //
-    Source sourceA = _addSource('/a.dart', "library a; import 'b.dart';");
-    Source sourceB = _createSource('/b.dart', "library b;");
-    _context.computeErrors(sourceA);
-    await pumpEventQueue();
-    listener.expectAnalyzed(sourceB);
-  }
-
-  void test_isClientLibrary_dart() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-import 'dart:html';
-
-main() {}''');
-    expect(_context.isClientLibrary(source), isFalse);
-    expect(_context.isServerLibrary(source), isFalse);
-    _context.computeLibraryElement(source);
-    expect(_context.isClientLibrary(source), isTrue);
-    expect(_context.isServerLibrary(source), isFalse);
-  }
-
-  void test_isClientLibrary_html() {
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.isClientLibrary(source), isFalse);
-  }
-
-  void test_isServerLibrary_dart() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-library lib;
-
-main() {}''');
-    expect(_context.isClientLibrary(source), isFalse);
-    expect(_context.isServerLibrary(source), isFalse);
-    _context.computeLibraryElement(source);
-    expect(_context.isClientLibrary(source), isFalse);
-    expect(_context.isServerLibrary(source), isTrue);
-  }
-
-  void test_isServerLibrary_html() {
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.isServerLibrary(source), isFalse);
-  }
-
-  void test_parseCompilationUnit_errors() {
-    Source source = _addSource("/lib.dart", "library {");
-    CompilationUnit compilationUnit = _context.parseCompilationUnit(source);
-    expect(compilationUnit, isNotNull);
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, isNotNull);
-    expect(errors.length > 0, isTrue);
-  }
-
-  void test_parseCompilationUnit_exception() {
-    Source source = _addSourceWithException("/test.dart");
-    try {
-      _context.parseCompilationUnit(source);
-      fail("Expected AnalysisException");
-    } on AnalysisException {
-      // Expected
-    }
-  }
-
-  void test_parseCompilationUnit_html() {
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.parseCompilationUnit(source), isNull);
-  }
-
-  void test_parseCompilationUnit_noErrors() {
-    Source source = _addSource("/lib.dart", "library lib;");
-    CompilationUnit compilationUnit = _context.parseCompilationUnit(source);
-    expect(compilationUnit, isNotNull);
-    expect(_context.getErrors(source).errors, hasLength(0));
-  }
-
-  void test_parseCompilationUnit_nonExistentSource() {
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    try {
-      _context.parseCompilationUnit(source);
-      fail("Expected AnalysisException because file does not exist");
-    } on AnalysisException {
-      // Expected result
-    }
-  }
-
-  void test_parseHtmlUnit_noErrors() {
-    Source source = _addSource("/lib.html", "<html></html>");
-    ht.HtmlUnit unit = _context.parseHtmlUnit(source);
-    expect(unit, isNotNull);
-  }
-
-  void test_parseHtmlUnit_resolveDirectives() {
-    Source libSource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-class ClassA {}''');
-    Source source = _addSource(
-        "/lib.html",
-        r'''
-<html>
-<head>
-  <script type='application/dart'>
-    import 'lib.dart';
-    ClassA v = null;
-  </script>
-</head>
-<body>
-</body>
-</html>''');
-    ht.HtmlUnit unit = _context.parseHtmlUnit(source);
-    // import directive should be resolved
-    ht.XmlTagNode htmlNode = unit.tagNodes[0];
-    ht.XmlTagNode headNode = htmlNode.tagNodes[0];
-    ht.HtmlScriptTagNode scriptNode = headNode.tagNodes[0];
-    CompilationUnit script = scriptNode.script;
-    ImportDirective importNode = script.directives[0] as ImportDirective;
-    expect(importNode.uriContent, isNotNull);
-    expect(importNode.source, libSource);
-  }
-
-  void test_performAnalysisTask_addPart() {
-    Source libSource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'part.dart';''');
-    // run all tasks without part
-    _analyzeAll_assertFinished();
-    // add part and run all tasks
-    Source partSource = _addSource(
-        "/part.dart",
-        r'''
-part of lib;
-''');
-    _analyzeAll_assertFinished();
-    // "libSource" should be here
-    List<Source> librariesWithPart =
-        _context.getLibrariesContaining(partSource);
-    expect(librariesWithPart, unorderedEquals([libSource]));
-  }
-
-  void test_performAnalysisTask_changeLibraryContents() {
-    Source libSource =
-        _addSource("/test.dart", "library lib; part 'test-part.dart';");
-    Source partSource = _addSource("/test-part.dart", "part of lib;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze #1
-    _context.setContents(libSource, "library lib;");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part resolved 2");
-    // update and analyze #2
-    _context.setContents(libSource, "library lib; part 'test-part.dart';");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 3");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 3");
-  }
-
-  void test_performAnalysisTask_changeLibraryThenPartContents() {
-    Source libSource =
-        _addSource("/test.dart", "library lib; part 'test-part.dart';");
-    Source partSource = _addSource("/test-part.dart", "part of lib;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze #1
-    _context.setContents(libSource, "library lib;");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part resolved 2");
-    // update and analyze #2
-    _context.setContents(partSource, "part of lib; // 1");
-    // Assert that changing the part's content does not effect the library
-    // now that it is no longer part of that library
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library changed 3");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 3");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part resolved 3");
-  }
-
-  void test_performAnalysisTask_changePartContents_makeItAPart() {
-    Source libSource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'part.dart';
-void f(x) {}''');
-    Source partSource = _addSource("/part.dart", "void g() { f(null); }");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze
-    _context.setContents(
-        partSource,
-        r'''
-part of lib;
-void g() { f(null); }''');
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 2");
-    expect(_context.getErrors(libSource).errors, hasLength(0));
-    expect(_context.getErrors(partSource).errors, hasLength(0));
-  }
-
-  /**
-   * https://code.google.com/p/dart/issues/detail?id=12424
-   */
-  void test_performAnalysisTask_changePartContents_makeItNotPart() {
-    Source libSource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'part.dart';
-void f(x) {}''');
-    Source partSource = _addSource(
-        "/part.dart",
-        r'''
-part of lib;
-void g() { f(null); }''');
-    _analyzeAll_assertFinished();
-    expect(_context.getErrors(libSource).errors, hasLength(0));
-    expect(_context.getErrors(partSource).errors, hasLength(0));
-    // Remove 'part' directive, which should make "f(null)" an error.
-    _context.setContents(
-        partSource,
-        r'''
-//part of lib;
-void g() { f(null); }''');
-    _analyzeAll_assertFinished();
-    expect(_context.getErrors(libSource).errors.length != 0, isTrue);
-  }
-
-  void test_performAnalysisTask_changePartContents_noSemanticChanges() {
-    Source libSource =
-        _addSource("/test.dart", "library lib; part 'test-part.dart';");
-    Source partSource = _addSource("/test-part.dart", "part of lib;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze #1
-    _context.setContents(partSource, "part of lib; // 1");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 2");
-    // update and analyze #2
-    _context.setContents(partSource, "part of lib; // 12");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 3");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 3");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 3");
-  }
-
-  void test_performAnalysisTask_getContentException_dart() {
-    // add source that throw an exception on "get content"
-    Source source = new _Source_getContent_throwException('test.dart');
-    {
-      ChangeSet changeSet = new ChangeSet();
-      changeSet.addedSource(source);
-      _context.applyChanges(changeSet);
-    }
-    // prepare errors
-    _analyzeAll_assertFinished();
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    // validate errors
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.source, same(source));
-    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
-  }
-
-  void test_performAnalysisTask_getContentException_html() {
-    // add source that throw an exception on "get content"
-    Source source = new _Source_getContent_throwException('test.html');
-    {
-      ChangeSet changeSet = new ChangeSet();
-      changeSet.addedSource(source);
-      _context.applyChanges(changeSet);
-    }
-    // prepare errors
-    _analyzeAll_assertFinished();
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    // validate errors
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.source, same(source));
-    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
-  }
-
-  void test_performAnalysisTask_importedLibraryAdd() {
-    Source libASource =
-        _addSource("/libA.dart", "library libA; import 'libB.dart';");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 1");
-    expect(_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
-        isTrue,
-        reason: "libA has an error");
-    // add libB.dart and analyze
-    Source libBSource = _addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 2");
-    expect(
-        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 2");
-    expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
-        isTrue,
-        reason: "libA doesn't have errors");
-  }
-
-  void test_performAnalysisTask_importedLibraryAdd_html() {
-    Source htmlSource = _addSource(
-        "/page.html",
-        r'''
-<html><body><script type="application/dart">
-  import '/libB.dart';
-  main() {print('hello dart');}
-</script></body></html>''');
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
-        reason: "htmlUnit resolved 1");
-    expect(_hasAnalysisErrorWithErrorSeverity(_context.getErrors(htmlSource)),
-        isTrue,
-        reason: "htmlSource has an error");
-    // add libB.dart and analyze
-    Source libBSource = _addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
-        reason: "htmlUnit resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 2");
-    // TODO (danrubel) commented out to fix red bots
-//    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
-//    expect(
-//        !_hasAnalysisErrorWithErrorSeverity(errors),
-//        isTrue,
-//        reason: "htmlSource doesn't have errors");
-  }
-
-  void test_performAnalysisTask_importedLibraryDelete() {
-    Source libASource =
-        _addSource("/libA.dart", "library libA; import 'libB.dart';");
-    Source libBSource = _addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 1");
-    expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
-        isTrue,
-        reason: "libA doesn't have errors");
-    // remove libB.dart content and analyze
-    _context.setContents(libBSource, null);
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 2");
-    expect(_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
-        isTrue,
-        reason: "libA has an error");
-  }
-
-  void test_performAnalysisTask_IOException() {
-    TestSource source = _addSourceWithException2("/test.dart", "library test;");
-    int oldTimestamp = _context.getModificationStamp(source);
-    source.generateExceptionOnRead = false;
-    _analyzeAll_assertFinished();
-    expect(source.readCount, 1);
-    source.generateExceptionOnRead = true;
-    do {
-      _changeSource(source, "");
-      // Ensure that the timestamp differs,
-      // so that analysis engine notices the change
-    } while (oldTimestamp == _context.getModificationStamp(source));
-    _analyzeAll_assertFinished();
-    expect(source.readCount, 2);
-  }
-
-  void test_performAnalysisTask_missingPart() {
-    Source source =
-        _addSource("/test.dart", "library lib; part 'no-such-file.dart';");
-    _analyzeAll_assertFinished();
-    expect(_context.getLibraryElement(source), isNotNull,
-        reason: "performAnalysisTask failed to compute an element model");
-  }
-
-  void test_performAnalysisTask_modifiedAfterParse() {
-    // TODO(scheglov) no threads in Dart
-//    Source source = _addSource("/test.dart", "library lib;");
-//    int initialTime = _context.getModificationStamp(source);
-//    List<Source> sources = new List<Source>();
-//    sources.add(source);
-//    _context.analysisPriorityOrder = sources;
-//    _context.parseCompilationUnit(source);
-//    while (initialTime == JavaSystem.currentTimeMillis()) {
-//      Thread.sleep(1);
-//      // Force the modification time to be different.
-//    }
-//    _context.setContents(source, "library test;");
-//    JUnitTestCase.assertTrue(initialTime != _context.getModificationStamp(source));
-//    _analyzeAll_assertFinished();
-//    JUnitTestCase.assertNotNullMsg("performAnalysisTask failed to compute an element model", _context.getLibraryElement(source));
-  }
-
-  void test_resolveCompilationUnit_import_relative() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    Source sourceA =
-        _addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
-    _addSource("/libB.dart", "library libB; class B{}");
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit2(sourceA, sourceA);
-    LibraryElement library = compilationUnit.element.library;
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-    List<LibraryElement> visibleLibraries = library.visibleLibraries;
-    assertNamedElements(visibleLibraries, ["dart.core", "libA", "libB"]);
-  }
-
-  void test_resolveCompilationUnit_import_relative_cyclic() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    Source sourceA =
-        _addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
-    _addSource("/libB.dart", "library libB; import 'libA.dart'; class B{}");
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit2(sourceA, sourceA);
-    LibraryElement library = compilationUnit.element.library;
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-    List<LibraryElement> visibleLibraries = library.visibleLibraries;
-    assertNamedElements(visibleLibraries, ["dart.core", "libA", "libB"]);
-  }
-
-  void test_resolveCompilationUnit_library() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    LibraryElement library = _context.computeLibraryElement(source);
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit(source, library);
-    expect(compilationUnit, isNotNull);
-    expect(compilationUnit.element, isNotNull);
-  }
-
-  void test_resolveCompilationUnit_source() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit2(source, source);
-    expect(compilationUnit, isNotNull);
-  }
-
-  void test_resolveCompilationUnit_sourceChangeDuringResolution() {
-    _context = new _AnalysisContext_sourceChangeDuringResolution();
-    AnalysisContextFactory.initContextWithCore(_context);
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit2(source, source);
-    expect(compilationUnit, isNotNull);
-    expect(_context.getLineInfo(source), isNotNull);
-  }
-
-  void test_resolveHtmlUnit() {
-    Source source = _addSource("/lib.html", "<html></html>");
-    ht.HtmlUnit unit = _context.resolveHtmlUnit(source);
-    expect(unit, isNotNull);
-  }
-
-  void test_setAnalysisOptions() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.cacheSize = 42;
-    options.dart2jsHint = false;
-    options.hint = false;
-    _context.analysisOptions = options;
-    AnalysisOptions result = _context.analysisOptions;
-    expect(result.cacheSize, options.cacheSize);
-    expect(result.dart2jsHint, options.dart2jsHint);
-    expect(result.hint, options.hint);
-  }
-
-  void test_setAnalysisOptions_reduceAnalysisPriorityOrder() {
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(_context.analysisOptions);
-    List<Source> sources = new List<Source>();
-    for (int index = 0; index < options.cacheSize; index++) {
-      sources.add(_addSource("/lib.dart$index", ""));
-    }
-    _context.analysisPriorityOrder = sources;
-    int oldPriorityOrderSize = _getPriorityOrder(_context).length;
-    options.cacheSize = options.cacheSize - 10;
-    _context.analysisOptions = options;
-    expect(oldPriorityOrderSize > _getPriorityOrder(_context).length, isTrue);
-  }
-
-  void test_setAnalysisPriorityOrder_empty() {
-    _context.analysisPriorityOrder = new List<Source>();
-  }
-
-  void test_setAnalysisPriorityOrder_lessThanCacheSize() {
-    AnalysisOptions options = _context.analysisOptions;
-    List<Source> sources = new List<Source>();
-    for (int index = 0; index < options.cacheSize; index++) {
-      sources.add(_addSource("/lib.dart$index", ""));
-    }
-    _context.analysisPriorityOrder = sources;
-    expect(options.cacheSize > _getPriorityOrder(_context).length, isTrue);
-  }
-
-  void test_setAnalysisPriorityOrder_nonEmpty() {
-    List<Source> sources = new List<Source>();
-    sources.add(_addSource("/lib.dart", "library lib;"));
-    _context.analysisPriorityOrder = sources;
-  }
-
-  Future test_setChangedContents_libraryWithPart() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.incremental = true;
-    _context = AnalysisContextFactory.oldContextWithCoreAndOptions(options);
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String oldCode = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = _addSource("/lib.dart", oldCode);
-    String partContents = r'''
-part of lib;
-int b = a;''';
-    Source partSource = _addSource("/part.dart", partContents);
-    LibraryElement element = _context.computeLibraryElement(librarySource);
-    CompilationUnit unit =
-        _context.getResolvedCompilationUnit(librarySource, element);
-    expect(unit, isNotNull);
-    int offset = oldCode.indexOf("int a") + 4;
-    String newCode = r'''
-library lib;
-part 'part.dart';
-int ya = 0;''';
-    expect(_getIncrementalAnalysisCache(_context), isNull);
-    _context.setChangedContents(librarySource, newCode, offset, 0, 1);
-    expect(_context.getContents(librarySource).data, newCode);
-    IncrementalAnalysisCache incrementalCache =
-        _getIncrementalAnalysisCache(_context);
-    expect(incrementalCache.librarySource, librarySource);
-    expect(incrementalCache.resolvedUnit, same(unit));
-    expect(_context.getResolvedCompilationUnit2(partSource, librarySource),
-        isNull);
-    expect(incrementalCache.newContents, newCode);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_setChangedContents_notResolved() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(_context.analysisOptions);
-    options.incremental = true;
-    _context.analysisOptions = options;
-    _sourceFactory = _context.sourceFactory;
-    String oldCode = r'''
-library lib;
-int a = 0;''';
-    Source librarySource = _addSource("/lib.dart", oldCode);
-    int offset = oldCode.indexOf("int a") + 4;
-    String newCode = r'''
-library lib;
-int ya = 0;''';
-    _context.setChangedContents(librarySource, newCode, offset, 0, 1);
-    expect(_context.getContents(librarySource).data, newCode);
-    expect(_getIncrementalAnalysisCache(_context), isNull);
-  }
-
-  Future test_setContents_libraryWithPart() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String libraryContents1 = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = _addSource("/lib.dart", libraryContents1);
-    String partContents1 = r'''
-part of lib;
-int b = a;''';
-    Source partSource = _addSource("/part.dart", partContents1);
-    _context.computeLibraryElement(librarySource);
-    IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
-        librarySource, librarySource, null, null, null, 0, 0, 0);
-    _setIncrementalAnalysisCache(_context, incrementalCache);
-    expect(_getIncrementalAnalysisCache(_context), same(incrementalCache));
-    String libraryContents2 = r'''
-library lib;
-part 'part.dart';
-int aa = 0;''';
-    _context.setContents(librarySource, libraryContents2);
-    expect(_context.getResolvedCompilationUnit2(partSource, librarySource),
-        isNull);
-    expect(_getIncrementalAnalysisCache(_context), isNull);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_setContents_null() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source librarySource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-int a = 0;''');
-    _context.computeLibraryElement(librarySource);
-    IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
-        librarySource, librarySource, null, null, null, 0, 0, 0);
-    _setIncrementalAnalysisCache(_context, incrementalCache);
-    expect(_getIncrementalAnalysisCache(_context), same(incrementalCache));
-    _context.setContents(librarySource, null);
-    expect(_context.getResolvedCompilationUnit2(librarySource, librarySource),
-        isNull);
-    expect(_getIncrementalAnalysisCache(_context), isNull);
-  }
-
-  void test_setContents_unchanged_consistentModificationTime() {
-    String contents = "// foo";
-    Source source = _addSource("/test.dart", contents);
-    // do all, no tasks
-    _analyzeAll_assertFinished();
-    {
-      AnalysisResult result = _context.performAnalysisTask();
-      expect(result.changeNotices, isNull);
-    }
-    // set the same contents, still no tasks
-    _context.setContents(source, contents);
-    {
-      AnalysisResult result = _context.performAnalysisTask();
-      expect(result.changeNotices, isNull);
-    }
-  }
-
-  void test_setSourceFactory() {
-    expect(_context.sourceFactory, _sourceFactory);
-    SourceFactory factory = new SourceFactory([]);
-    _context.sourceFactory = factory;
-    expect(_context.sourceFactory, factory);
-  }
-
-  void test_unreadableSource() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source test1 = _addSource(
-        "/test1.dart",
-        r'''
-import 'test2.dart';
-library test1;''');
-    Source test2 = _addSource(
-        "/test2.dart",
-        r'''
-import 'test1.dart';
-import 'test3.dart';
-library test2;''');
-    Source test3 = _addSourceWithException("/test3.dart");
-    _analyzeAll_assertFinished();
-    // test1 and test2 should have been successfully analyzed
-    // despite the fact that test3 couldn't be read.
-    expect(_context.computeLibraryElement(test1), isNotNull);
-    expect(_context.computeLibraryElement(test2), isNotNull);
-    expect(_context.computeLibraryElement(test3), isNull);
-  }
-
-  void test_updateAnalysis() {
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    AnalysisDelta delta = new AnalysisDelta();
-    delta.setAnalysisLevel(source, AnalysisLevel.ALL);
-    _context.applyAnalysisDelta(delta);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    delta = new AnalysisDelta();
-    delta.setAnalysisLevel(source, AnalysisLevel.NONE);
-    _context.applyAnalysisDelta(delta);
-    expect(_context.sourcesNeedingProcessing.contains(source), isFalse);
-  }
-
-  void xtest_performAnalysisTask_stress() {
-    int maxCacheSize = 4;
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(_context.analysisOptions);
-    options.cacheSize = maxCacheSize;
-    _context.analysisOptions = options;
-    int sourceCount = maxCacheSize + 2;
-    List<Source> sources = new List<Source>();
-    ChangeSet changeSet = new ChangeSet();
-    for (int i = 0; i < sourceCount; i++) {
-      Source source = _addSource("/lib$i.dart", "library lib$i;");
-      sources.add(source);
-      changeSet.addedSource(source);
-    }
-    _context.applyChanges(changeSet);
-    _context.analysisPriorityOrder = sources;
-    for (int i = 0; i < 1000; i++) {
-      List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
-      if (notice == null) {
-        //System.out.println("test_performAnalysisTask_stress: " + i);
-        break;
-      }
-    }
-    List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
-    if (notice != null) {
-      fail(
-          "performAnalysisTask failed to terminate after analyzing all sources");
-    }
-  }
-
-  Source _addSource(String fileName, String contents) {
-    Source source = new FileBasedSource(FileUtilities2.createFile(fileName));
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    _context.setContents(source, contents);
-    return source;
-  }
-
-  TestSource _addSourceWithException(String fileName) {
-    return _addSourceWithException2(fileName, "");
-  }
-
-  TestSource _addSourceWithException2(String fileName, String contents) {
-    TestSource source = new TestSource(fileName, contents);
-    source.generateExceptionOnRead = true;
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    return source;
-  }
-
-  /**
-   * Perform analysis tasks up to 512 times and asserts that that was enough.
-   */
-  void _analyzeAll_assertFinished() {
-    _analyzeAll_assertFinished2(512);
-  }
-
-  /**
-   * Perform analysis tasks up to the given number of times and asserts that that was enough.
-   *
-   * @param maxIterations the maximum number of tasks to perform
-   */
-  void _analyzeAll_assertFinished2(int maxIterations) {
-    for (int i = 0; i < maxIterations; i++) {
-      List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
-      if (notice == null) {
-        return;
-      }
-    }
-    fail("performAnalysisTask failed to terminate after analyzing all sources");
-  }
-
-  void _changeSource(TestSource source, String contents) {
-    source.setContents(contents);
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.changedSource(source);
-    _context.applyChanges(changeSet);
-  }
-
-  Source _createSource(String fileName, String contents) {
-    Source source = new FileBasedSource(FileUtilities2.createFile(fileName));
-    _context.setContents(source, contents);
-    return source;
-  }
-
-  /**
-   * Search the given compilation unit for a class with the given name. Return the class with the
-   * given name, or `null` if the class cannot be found.
-   *
-   * @param unit the compilation unit being searched
-   * @param className the name of the class being searched for
-   * @return the class with the given name
-   */
-  ClassElement _findClass(CompilationUnitElement unit, String className) {
-    for (ClassElement classElement in unit.types) {
-      if (classElement.displayName == className) {
-        return classElement;
-      }
-    }
-    return null;
-  }
-
-  IncrementalAnalysisCache _getIncrementalAnalysisCache(
-      AnalysisContextImpl context2) {
-    return context2.test_incrementalAnalysisCache;
-  }
-
-  List<Source> _getPriorityOrder(AnalysisContextImpl context2) {
-    return context2.test_priorityOrder;
-  }
-
-  void _performPendingAnalysisTasks([int maxTasks = 20]) {
-    for (int i = 0; _context.performAnalysisTask().hasMoreWork; i++) {
-      if (i > maxTasks) {
-        fail('Analysis did not terminate.');
-      }
-    }
-  }
-
-  void _removeSource(Source source) {
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.removedSource(source);
-    _context.applyChanges(changeSet);
-  }
-
-  void _setIncrementalAnalysisCache(
-      AnalysisContextImpl context, IncrementalAnalysisCache incrementalCache) {
-    context.test_incrementalAnalysisCache = incrementalCache;
-  }
-
-  /**
-   * Returns `true` if there is an [AnalysisError] with [ErrorSeverity.ERROR] in
-   * the given [AnalysisErrorInfo].
-   */
-  static bool _hasAnalysisErrorWithErrorSeverity(AnalysisErrorInfo errorInfo) {
-    List<AnalysisError> errors = errorInfo.errors;
-    for (AnalysisError analysisError in errors) {
-      if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-class AnalysisContextImplTest_Source_exists_true extends TestSource {
-  @override
-  bool exists() => true;
-}
-
-class AnalysisContextImplTest_Source_getModificationStamp_fromSource
-    extends TestSource {
-  int stamp;
-  AnalysisContextImplTest_Source_getModificationStamp_fromSource(this.stamp);
-  @override
-  int get modificationStamp => stamp;
-}
-
-class AnalysisContextImplTest_Source_getModificationStamp_overridden
-    extends TestSource {
-  int stamp;
-  AnalysisContextImplTest_Source_getModificationStamp_overridden(this.stamp);
-  @override
-  int get modificationStamp => stamp;
-}
-
-@reflectiveTest
-class AnalysisOptionsImplTest extends EngineTestCase {
-  void test_AnalysisOptionsImpl_copy() {
-    bool booleanValue = true;
-    for (int i = 0; i < 2; i++, booleanValue = !booleanValue) {
-      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-      options.analyzeFunctionBodies = booleanValue;
-      options.cacheSize = i;
-      options.dart2jsHint = booleanValue;
-      options.enableStrictCallChecks = booleanValue;
-      options.enableSuperMixins = booleanValue;
-      options.generateImplicitErrors = booleanValue;
-      options.generateSdkErrors = booleanValue;
-      options.hint = booleanValue;
-      options.incremental = booleanValue;
-      options.preserveComments = booleanValue;
-      options.strongMode = booleanValue;
-      AnalysisOptionsImpl copy = new AnalysisOptionsImpl.from(options);
-      expect(copy.analyzeFunctionBodies, options.analyzeFunctionBodies);
-      expect(copy.cacheSize, options.cacheSize);
-      expect(copy.dart2jsHint, options.dart2jsHint);
-      expect(copy.enableStrictCallChecks, options.enableStrictCallChecks);
-      expect(copy.enableSuperMixins, options.enableSuperMixins);
-      expect(copy.generateImplicitErrors, options.generateImplicitErrors);
-      expect(copy.generateSdkErrors, options.generateSdkErrors);
-      expect(copy.hint, options.hint);
-      expect(copy.incremental, options.incremental);
-      expect(copy.preserveComments, options.preserveComments);
-      expect(copy.strongMode, options.strongMode);
-    }
-  }
-
-  void test_analyzeFunctionBodies() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.analyzeFunctionBodies;
-    options.analyzeFunctionBodies = value;
-    expect(options.analyzeFunctionBodies, value);
-  }
-
-  void test_cacheSize() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    expect(options.cacheSize, AnalysisOptionsImpl.DEFAULT_CACHE_SIZE);
-    int value = options.cacheSize + 1;
-    options.cacheSize = value;
-    expect(options.cacheSize, value);
-  }
-
-  void test_dart2jsHint() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.dart2jsHint;
-    options.dart2jsHint = value;
-    expect(options.dart2jsHint, value);
-  }
-
-  void test_enableSuperMixins() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.enableSuperMixins;
-    options.enableSuperMixins = value;
-    expect(options.enableSuperMixins, value);
-  }
-
-  void test_generateImplicitErrors() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.generateImplicitErrors;
-    options.generateImplicitErrors = value;
-    expect(options.generateImplicitErrors, value);
-  }
-
-  void test_generateSdkErrors() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.generateSdkErrors;
-    options.generateSdkErrors = value;
-    expect(options.generateSdkErrors, value);
-  }
-
-  void test_hint() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.hint;
-    options.hint = value;
-    expect(options.hint, value);
-  }
-
-  void test_incremental() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.incremental;
-    options.incremental = value;
-    expect(options.incremental, value);
-  }
-
-  void test_preserveComments() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.preserveComments;
-    options.preserveComments = value;
-    expect(options.preserveComments, value);
-  }
-
-  void test_strongMode() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.strongMode;
-    options.strongMode = value;
-    expect(options.strongMode, value);
-  }
-}
-
-class AnalysisTask_test_perform_exception extends AnalysisTask {
-  AnalysisTask_test_perform_exception(InternalAnalysisContext arg0)
-      : super(arg0);
-  @override
-  String get taskDescription => null;
-  @override
-  accept(AnalysisTaskVisitor visitor) {
-    expect(exception, isNotNull);
-    return null;
-  }
-
-  @override
-  void internalPerform() {
-    throw new AnalysisException("Forced exception");
-  }
-}
-
-@reflectiveTest
-class AnalysisTaskTest extends EngineTestCase {
-  void test_perform_exception() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTask task = new AnalysisTask_test_perform_exception(context);
-    task.perform(new TestTaskVisitor<Object>());
-  }
 }
 
 /**
@@ -2514,2277 +72,7 @@
   }
 }
 
-class CompilationUnitMock extends TypedMock implements CompilationUnit {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-@reflectiveTest
-class DartEntryTest extends EngineTestCase {
-  void test_allErrors() {
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
-    expect(entry.allErrors, hasLength(0));
-    entry.setValue(SourceEntry.CONTENT_ERRORS, <AnalysisError>[
-      new AnalysisError(source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT,
-          ['exception details'])
-    ]);
-    entry.setValue(DartEntry.SCAN_ERRORS, <AnalysisError>[
-      new AnalysisError(
-          source, 0, 0, ScannerErrorCode.UNTERMINATED_STRING_LITERAL)
-    ]);
-    entry.setValue(DartEntry.PARSE_ERRORS, <AnalysisError>[
-      new AnalysisError(source, 0, 0, ParserErrorCode.ABSTRACT_CLASS_MEMBER)
-    ]);
-    entry.setValueInLibrary(
-        DartEntry.RESOLUTION_ERRORS, source, <AnalysisError>[
-      new AnalysisError(
-          source, 0, 0, CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION)
-    ]);
-    entry.setValueInLibrary(
-        DartEntry.VERIFICATION_ERRORS, source, <AnalysisError>[
-      new AnalysisError(
-          source, 0, 0, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)
-    ]);
-    entry.setValueInLibrary(DartEntry.HINTS, source,
-        <AnalysisError>[new AnalysisError(source, 0, 0, HintCode.DEAD_CODE)]);
-    expect(entry.allErrors, hasLength(6));
-  }
-
-  void test_creation() {
-    Source librarySource = new TestSource();
-    DartEntry entry = new DartEntry();
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES),
-        same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-  }
-
-  void test_getResolvableCompilationUnit_none() {
-    DartEntry entry = new DartEntry();
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_getResolvableCompilationUnit_parsed_accessed() {
-    Source librarySource = new TestSource("/lib.dart");
-    String importUri = "/f1.dart";
-    Source importSource = new TestSource(importUri);
-    ImportDirective importDirective =
-        AstFactory.importDirective3(importUri, null);
-    importDirective.source = importSource;
-    importDirective.uriContent = importUri;
-    String exportUri = "/f2.dart";
-    Source exportSource = new TestSource(exportUri);
-    ExportDirective exportDirective = AstFactory.exportDirective2(exportUri);
-    exportDirective.source = exportSource;
-    exportDirective.uriContent = exportUri;
-    String partUri = "/f3.dart";
-    Source partSource = new TestSource(partUri);
-    PartDirective partDirective = AstFactory.partDirective2(partUri);
-    partDirective.source = partSource;
-    partDirective.uriContent = partUri;
-    CompilationUnit unit = AstFactory
-        .compilationUnit3([importDirective, exportDirective, partDirective]);
-    DartEntry entry = new DartEntry();
-    entry.setValue(DartEntry.PARSED_UNIT, unit);
-    entry.getValue(DartEntry.PARSED_UNIT);
-    CompilationUnit result = entry.resolvableCompilationUnit;
-    expect(result, same(unit));
-    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
-    result = entry.resolvableCompilationUnit;
-    expect(result, isNot(same(unit)));
-    NodeList<Directive> directives = result.directives;
-    ImportDirective resultImportDirective = directives[0] as ImportDirective;
-    expect(resultImportDirective.uriContent, importUri);
-    expect(resultImportDirective.source, same(importSource));
-    ExportDirective resultExportDirective = directives[1] as ExportDirective;
-    expect(resultExportDirective.uriContent, exportUri);
-    expect(resultExportDirective.source, same(exportSource));
-    PartDirective resultPartDirective = directives[2] as PartDirective;
-    expect(resultPartDirective.uriContent, partUri);
-    expect(resultPartDirective.source, same(partSource));
-  }
-
-  void test_getResolvableCompilationUnit_parsed_notAccessed() {
-    CompilationUnit unit = AstFactory.compilationUnit();
-    DartEntry entry = new DartEntry();
-    entry.setValue(DartEntry.PARSED_UNIT, unit);
-    expect(entry.resolvableCompilationUnit, same(unit));
-  }
-
-  void test_getResolvableCompilationUnit_resolved() {
-    String importUri = "f1.dart";
-    Source importSource = new TestSource(importUri);
-    ImportDirective importDirective =
-        AstFactory.importDirective3(importUri, null);
-    importDirective.source = importSource;
-    importDirective.uriContent = importUri;
-    String exportUri = "f2.dart";
-    Source exportSource = new TestSource(exportUri);
-    ExportDirective exportDirective = AstFactory.exportDirective2(exportUri);
-    exportDirective.source = exportSource;
-    exportDirective.uriContent = exportUri;
-    String partUri = "f3.dart";
-    Source partSource = new TestSource(partUri);
-    PartDirective partDirective = AstFactory.partDirective2(partUri);
-    partDirective.source = partSource;
-    partDirective.uriContent = partUri;
-    CompilationUnit unit = AstFactory
-        .compilationUnit3([importDirective, exportDirective, partDirective]);
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, new TestSource("lib.dart"), unit);
-    CompilationUnit result = entry.resolvableCompilationUnit;
-    expect(result, isNot(same(unit)));
-    NodeList<Directive> directives = result.directives;
-    ImportDirective resultImportDirective = directives[0] as ImportDirective;
-    expect(resultImportDirective.uriContent, importUri);
-    expect(resultImportDirective.source, same(importSource));
-    ExportDirective resultExportDirective = directives[1] as ExportDirective;
-    expect(resultExportDirective.uriContent, exportUri);
-    expect(resultExportDirective.source, same(exportSource));
-    PartDirective resultPartDirective = directives[2] as PartDirective;
-    expect(resultPartDirective.uriContent, partUri);
-    expect(resultPartDirective.source, same(partSource));
-  }
-
-  void test_getState_invalid_resolutionErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getState(DartEntry.RESOLUTION_ERRORS);
-      fail("Expected ArgumentError for RESOLUTION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getState_invalid_verificationErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getState(DartEntry.VERIFICATION_ERRORS);
-      fail("Expected ArgumentError for VERIFICATION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getStateInLibrary_invalid_element() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getStateInLibrary(DartEntry.ELEMENT, new TestSource());
-      fail("Expected ArgumentError for ELEMENT");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getValue_containingLibraries() {
-    Source testSource = new TestSource();
-    DartEntry entry = new DartEntry();
-    List<Source> value = entry.containingLibraries;
-    expect(value, hasLength(0));
-    entry.addContainingLibrary(testSource);
-    value = entry.containingLibraries;
-    expect(value, hasLength(1));
-    expect(value[0], testSource);
-    entry.removeContainingLibrary(testSource);
-    value = entry.containingLibraries;
-    expect(value, hasLength(0));
-  }
-
-  void test_getValue_invalid_resolutionErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getValue(DartEntry.RESOLUTION_ERRORS);
-      fail("Expected ArgumentError for RESOLUTION_ERRORS");
-    } on ArgumentError {}
-  }
-
-  void test_getValue_invalid_verificationErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getValue(DartEntry.VERIFICATION_ERRORS);
-      fail("Expected ArgumentError for VERIFICATION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getValueInLibrary_invalid_element() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getValueInLibrary(DartEntry.ELEMENT, new TestSource());
-      fail("Expected ArgumentError for ELEMENT");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getValueInLibrary_invalid_resolutionErrors_multiple() {
-    Source source1 = new TestSource();
-    Source source2 = new TestSource();
-    Source source3 = new TestSource();
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
-    try {
-      entry.getValueInLibrary(DartEntry.ELEMENT, source3);
-      fail("Expected ArgumentError for ELEMENT");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_hasInvalidData_false() {
-    DartEntry entry = new DartEntry();
-    entry.recordScanError(new CaughtException(new AnalysisException(), null));
-    expect(entry.hasInvalidData(DartEntry.ELEMENT), isFalse);
-    expect(entry.hasInvalidData(DartEntry.EXPORTED_LIBRARIES), isFalse);
-    expect(entry.hasInvalidData(DartEntry.HINTS), isFalse);
-    expect(entry.hasInvalidData(DartEntry.IMPORTED_LIBRARIES), isFalse);
-    expect(entry.hasInvalidData(DartEntry.INCLUDED_PARTS), isFalse);
-    expect(entry.hasInvalidData(DartEntry.IS_CLIENT), isFalse);
-    expect(entry.hasInvalidData(DartEntry.IS_LAUNCHABLE), isFalse);
-    expect(entry.hasInvalidData(SourceEntry.LINE_INFO), isFalse);
-    expect(entry.hasInvalidData(DartEntry.PARSE_ERRORS), isFalse);
-    expect(entry.hasInvalidData(DartEntry.PARSED_UNIT), isFalse);
-    expect(entry.hasInvalidData(DartEntry.PUBLIC_NAMESPACE), isFalse);
-    expect(entry.hasInvalidData(DartEntry.SOURCE_KIND), isFalse);
-    expect(entry.hasInvalidData(DartEntry.RESOLUTION_ERRORS), isFalse);
-    expect(entry.hasInvalidData(DartEntry.RESOLVED_UNIT), isFalse);
-    expect(entry.hasInvalidData(DartEntry.VERIFICATION_ERRORS), isFalse);
-  }
-
-  void test_hasInvalidData_true() {
-    DartEntry entry = new DartEntry();
-    expect(entry.hasInvalidData(DartEntry.ELEMENT), isTrue);
-    expect(entry.hasInvalidData(DartEntry.EXPORTED_LIBRARIES), isTrue);
-    expect(entry.hasInvalidData(DartEntry.HINTS), isTrue);
-    expect(entry.hasInvalidData(DartEntry.IMPORTED_LIBRARIES), isTrue);
-    expect(entry.hasInvalidData(DartEntry.INCLUDED_PARTS), isTrue);
-    expect(entry.hasInvalidData(DartEntry.IS_CLIENT), isTrue);
-    expect(entry.hasInvalidData(DartEntry.IS_LAUNCHABLE), isTrue);
-    expect(entry.hasInvalidData(SourceEntry.LINE_INFO), isTrue);
-    expect(entry.hasInvalidData(DartEntry.PARSE_ERRORS), isTrue);
-    expect(entry.hasInvalidData(DartEntry.PARSED_UNIT), isTrue);
-    expect(entry.hasInvalidData(DartEntry.PUBLIC_NAMESPACE), isTrue);
-    expect(entry.hasInvalidData(DartEntry.SOURCE_KIND), isTrue);
-    expect(entry.hasInvalidData(DartEntry.RESOLUTION_ERRORS), isTrue);
-    expect(entry.hasInvalidData(DartEntry.RESOLVED_UNIT), isTrue);
-    expect(entry.hasInvalidData(DartEntry.VERIFICATION_ERRORS), isTrue);
-  }
-
-  void test_invalidateAllInformation() {
-    Source librarySource = new TestSource();
-    DartEntry entry = _entryWithValidState(librarySource);
-    entry.invalidateAllInformation();
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-  }
-
-  void test_invalidateAllResolutionInformation() {
-    Source librarySource = new TestSource();
-    DartEntry entry = _entryWithValidState(librarySource);
-    entry.invalidateAllResolutionInformation(false);
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-  }
-
-  void test_invalidateAllResolutionInformation_includingUris() {
-    Source librarySource = new TestSource();
-    DartEntry entry = _entryWithValidState(librarySource);
-    entry.invalidateAllResolutionInformation(true);
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-  }
-
-  void test_isClient() {
-    DartEntry entry = new DartEntry();
-    // true
-    entry.setValue(DartEntry.IS_CLIENT, true);
-    expect(entry.getValue(DartEntry.IS_CLIENT), isTrue);
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-    // invalidate
-    entry.setState(DartEntry.IS_CLIENT, CacheState.INVALID);
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    // false
-    entry.setValue(DartEntry.IS_CLIENT, false);
-    expect(entry.getValue(DartEntry.IS_CLIENT), isFalse);
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-  }
-
-  void test_isLaunchable() {
-    DartEntry entry = new DartEntry();
-    // true
-    entry.setValue(DartEntry.IS_LAUNCHABLE, true);
-    expect(entry.getValue(DartEntry.IS_LAUNCHABLE), isTrue);
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-    // invalidate
-    entry.setState(DartEntry.IS_LAUNCHABLE, CacheState.INVALID);
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    // false
-    entry.setValue(DartEntry.IS_LAUNCHABLE, false);
-    expect(entry.getValue(DartEntry.IS_LAUNCHABLE), isFalse);
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-  }
-
-  void test_recordBuildElementError() {
-    Source firstLibrary = new TestSource('first.dart');
-    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
-    entry.recordBuildElementErrorInLibrary(
-        firstLibrary, new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-  }
-
-  void test_recordContentError() {
-    Source firstLibrary = new TestSource('first.dart');
-//    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary);
-    entry
-        .recordContentError(new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.ERROR));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    // The following lines are commented out because we don't currently have
-    // any way of setting the state for data associated with a library we
-    // don't know anything about.
-//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
-  }
-
-  void test_recordHintErrorInLibrary() {
-    Source firstLibrary = new TestSource('first.dart');
-    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
-    entry.recordHintErrorInLibrary(
-        firstLibrary, new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-  }
-
-  void test_recordParseError() {
-    Source firstLibrary = new TestSource('first.dart');
-//    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary);
-    entry.recordParseError(new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    // The following lines are commented out because we don't currently have
-    // any way of setting the state for data associated with a library we
-    // don't know anything about.
-//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
-  }
-
-  void test_recordResolutionError() {
-    Source firstLibrary = new TestSource('first.dart');
-//    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary);
-    entry.recordResolutionError(
-        new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    // The following lines are commented out because we don't currently have
-    // any way of setting the state for data associated with a library we
-    // don't know anything about.
-//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
-  }
-
-  void test_recordResolutionErrorInLibrary() {
-    Source firstLibrary = new TestSource('first.dart');
-    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
-    entry.recordResolutionErrorInLibrary(
-        firstLibrary, new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-  }
-
-  void test_recordScanError() {
-    Source firstLibrary = new TestSource('first.dart');
-//    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary);
-    entry.recordScanError(new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    // The following lines are commented out because we don't currently have
-    // any way of setting the state for data associated with a library we
-    // don't know anything about.
-//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
-  }
-
-  void test_recordVerificationErrorInLibrary() {
-    Source firstLibrary = new TestSource('first.dart');
-    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
-    entry.recordVerificationErrorInLibrary(
-        firstLibrary, new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-  }
-
-  void test_removeResolution_multiple_first() {
-    Source source1 = new TestSource('first.dart');
-    Source source2 = new TestSource('second.dart');
-    Source source3 = new TestSource('third.dart');
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
-    entry.removeResolution(source1);
-  }
-
-  void test_removeResolution_multiple_last() {
-    Source source1 = new TestSource('first.dart');
-    Source source2 = new TestSource('second.dart');
-    Source source3 = new TestSource('third.dart');
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
-    entry.removeResolution(source3);
-  }
-
-  void test_removeResolution_multiple_middle() {
-    Source source1 = new TestSource('first.dart');
-    Source source2 = new TestSource('second.dart');
-    Source source3 = new TestSource('third.dart');
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
-    entry.removeResolution(source2);
-  }
-
-  void test_removeResolution_single() {
-    Source source1 = new TestSource();
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.removeResolution(source1);
-  }
-
-  void test_resolvableCompilationUnit_builtUnit() {
-    Source librarySource = new TestSource('/lib.dart');
-    CompilationUnit unit = AstFactory.compilationUnit();
-    CompilationUnitElement element =
-        ElementFactory.compilationUnit('test.dart');
-    unit.element = element;
-    DartEntry entry = new DartEntry();
-    entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-    entry.setValueInLibrary(DartEntry.BUILT_UNIT, librarySource, unit);
-    entry.invalidateAllResolutionInformation(false);
-    CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
-    expect(resolvableUnit, isNotNull);
-    expect(resolvableUnit.element, isNull);
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_resolvableCompilationUnit_none() {
-    DartEntry entry = new DartEntry();
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_resolvableCompilationUnit_parsed() {
-    CompilationUnit unit = AstFactory.compilationUnit();
-    DartEntry entry = new DartEntry();
-    entry.setValue(DartEntry.PARSED_UNIT, unit);
-    expect(entry.resolvableCompilationUnit, unit);
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_resolvableCompilationUnit_resolved() {
-    Source librarySource = new TestSource('/lib.dart');
-    CompilationUnit unit = AstFactory.compilationUnit();
-    CompilationUnitElement element =
-        ElementFactory.compilationUnit('test.dart');
-    unit.element = element;
-    DartEntry entry = new DartEntry();
-    entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
-    entry.invalidateAllResolutionInformation(false);
-    CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
-    expect(resolvableUnit, isNotNull);
-    expect(resolvableUnit.element, isNull);
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_setState_element() {
-    _setState(DartEntry.ELEMENT);
-  }
-
-  void test_setState_exportedLibraries() {
-    _setState(DartEntry.EXPORTED_LIBRARIES);
-  }
-
-  void test_setState_hints() {
-    _setStateInLibrary(DartEntry.HINTS);
-  }
-
-  void test_setState_importedLibraries() {
-    _setState(DartEntry.IMPORTED_LIBRARIES);
-  }
-
-  void test_setState_includedParts() {
-    _setState(DartEntry.INCLUDED_PARTS);
-  }
-
-  void test_setState_invalid_element() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.setStateInLibrary(DartEntry.ELEMENT, null, CacheState.FLUSHED);
-      fail("Expected ArgumentError for ELEMENT");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_setState_invalid_resolutionErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.setState(DartEntry.RESOLUTION_ERRORS, CacheState.FLUSHED);
-      fail("Expected ArgumentError for RESOLUTION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_setState_invalid_validState() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.setState(SourceEntry.LINE_INFO, CacheState.VALID);
-      fail("Expected ArgumentError for a state of VALID");
-    } on ArgumentError {}
-  }
-
-  void test_setState_invalid_verificationErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.setState(DartEntry.VERIFICATION_ERRORS, CacheState.FLUSHED);
-      fail("Expected ArgumentError for VERIFICATION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_setState_isClient() {
-    _setState(DartEntry.IS_CLIENT);
-  }
-
-  void test_setState_isLaunchable() {
-    _setState(DartEntry.IS_LAUNCHABLE);
-  }
-
-  void test_setState_lineInfo() {
-    _setState(SourceEntry.LINE_INFO);
-  }
-
-  void test_setState_parsedUnit() {
-    _setState(DartEntry.PARSED_UNIT);
-  }
-
-  void test_setState_parseErrors() {
-    _setState(DartEntry.PARSE_ERRORS);
-  }
-
-  void test_setState_publicNamespace() {
-    _setState(DartEntry.PUBLIC_NAMESPACE);
-  }
-
-  void test_setState_resolutionErrors() {
-    _setStateInLibrary(DartEntry.RESOLUTION_ERRORS);
-  }
-
-  void test_setState_resolvedUnit() {
-    _setStateInLibrary(DartEntry.RESOLVED_UNIT);
-  }
-
-  void test_setState_scanErrors() {
-    _setState(DartEntry.SCAN_ERRORS);
-  }
-
-  void test_setState_sourceKind() {
-    _setState(DartEntry.SOURCE_KIND);
-  }
-
-  void test_setState_tokenStream() {
-    _setState(DartEntry.TOKEN_STREAM);
-  }
-
-  void test_setState_verificationErrors() {
-    _setStateInLibrary(DartEntry.VERIFICATION_ERRORS);
-  }
-
-  void test_setValue_element() {
-    _setValue(
-        DartEntry.ELEMENT,
-        new LibraryElementImpl.forNode(
-            null, AstFactory.libraryIdentifier2(["lib"])));
-  }
-
-  void test_setValue_exportedLibraries() {
-    _setValue(DartEntry.EXPORTED_LIBRARIES, <Source>[new TestSource()]);
-  }
-
-  void test_setValue_hints() {
-    _setValueInLibrary(DartEntry.HINTS,
-        <AnalysisError>[new AnalysisError(null, 0, 0, HintCode.DEAD_CODE)]);
-  }
-
-  void test_setValue_importedLibraries() {
-    _setValue(DartEntry.IMPORTED_LIBRARIES, <Source>[new TestSource()]);
-  }
-
-  void test_setValue_includedParts() {
-    _setValue(DartEntry.INCLUDED_PARTS, <Source>[new TestSource()]);
-  }
-
-  void test_setValue_isClient() {
-    _setValue(DartEntry.IS_CLIENT, true);
-  }
-
-  void test_setValue_isLaunchable() {
-    _setValue(DartEntry.IS_LAUNCHABLE, true);
-  }
-
-  void test_setValue_lineInfo() {
-    _setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
-  }
-
-  void test_setValue_parsedUnit() {
-    _setValue(DartEntry.PARSED_UNIT, AstFactory.compilationUnit());
-  }
-
-  void test_setValue_parseErrors() {
-    _setValue(DartEntry.PARSE_ERRORS, <AnalysisError>[
-      new AnalysisError(null, 0, 0, ParserErrorCode.ABSTRACT_CLASS_MEMBER)
-    ]);
-  }
-
-  void test_setValue_publicNamespace() {
-    _setValue(DartEntry.PUBLIC_NAMESPACE,
-        new Namespace(new HashMap<String, Element>()));
-  }
-
-  void test_setValue_resolutionErrors() {
-    _setValueInLibrary(DartEntry.RESOLUTION_ERRORS, <AnalysisError>[
-      new AnalysisError(
-          null, 0, 0, CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION)
-    ]);
-  }
-
-  void test_setValue_resolvedUnit() {
-    _setValueInLibrary(DartEntry.RESOLVED_UNIT, AstFactory.compilationUnit());
-  }
-
-  void test_setValue_scanErrors() {
-    _setValue(DartEntry.SCAN_ERRORS, <AnalysisError>[
-      new AnalysisError(
-          null, 0, 0, ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT)
-    ]);
-  }
-
-  void test_setValue_sourceKind() {
-    _setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
-  }
-
-  void test_setValue_tokenStream() {
-    _setValue(DartEntry.TOKEN_STREAM, new Token(TokenType.LT, 5));
-  }
-
-  void test_setValue_verificationErrors() {
-    _setValueInLibrary(DartEntry.VERIFICATION_ERRORS, <AnalysisError>[
-      new AnalysisError(null, 0, 0, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)
-    ]);
-  }
-
-  DartEntry _entryWithValidState([Source firstLibrary, Source secondLibrary]) {
-    DartEntry entry = new DartEntry();
-    entry.setValue(SourceEntry.CONTENT, null);
-    entry.setValue(SourceEntry.CONTENT_ERRORS, null);
-    entry.setValue(SourceEntry.LINE_INFO, null);
-    entry.setValue(DartEntry.CONTAINING_LIBRARIES, null);
-    entry.setValue(DartEntry.ELEMENT, null);
-    entry.setValue(DartEntry.EXPORTED_LIBRARIES, null);
-    entry.setValue(DartEntry.IMPORTED_LIBRARIES, null);
-    entry.setValue(DartEntry.INCLUDED_PARTS, null);
-    entry.setValue(DartEntry.IS_CLIENT, null);
-    entry.setValue(DartEntry.IS_LAUNCHABLE, null);
-    entry.setValue(DartEntry.PARSE_ERRORS, null);
-    entry.setValue(DartEntry.PARSED_UNIT, null);
-    entry.setValue(DartEntry.PUBLIC_NAMESPACE, null);
-    entry.setValue(DartEntry.SCAN_ERRORS, null);
-    entry.setValue(DartEntry.SOURCE_KIND, null);
-    entry.setValue(DartEntry.TOKEN_STREAM, null);
-    if (firstLibrary != null) {
-      entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary, null);
-      entry.setValueInLibrary(DartEntry.BUILT_UNIT, firstLibrary, null);
-      entry.setValueInLibrary(DartEntry.HINTS, firstLibrary, null);
-      entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary, null);
-      entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary, null);
-      entry.setValueInLibrary(
-          DartEntry.VERIFICATION_ERRORS, firstLibrary, null);
-    }
-    if (secondLibrary != null) {
-      entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary, null);
-      entry.setValueInLibrary(DartEntry.BUILT_UNIT, secondLibrary, null);
-      entry.setValueInLibrary(DartEntry.HINTS, secondLibrary, null);
-      entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary, null);
-      entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary, null);
-      entry.setValueInLibrary(
-          DartEntry.VERIFICATION_ERRORS, secondLibrary, null);
-    }
-    //
-    // Validate that the state was set correctly.
-    //
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-    if (firstLibrary != null) {
-      expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-          same(CacheState.VALID));
-      expect(
-          entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-          same(CacheState.VALID));
-    }
-    if (secondLibrary != null) {
-      expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-          same(CacheState.VALID));
-      expect(
-          entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-          same(CacheState.VALID));
-      expect(
-          entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-          same(CacheState.VALID));
-    }
-    return entry;
-  }
-
-  void _setState(DataDescriptor descriptor) {
-    DartEntry entry = new DartEntry();
-    expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
-    entry.setState(descriptor, CacheState.FLUSHED);
-    expect(entry.getState(descriptor), same(CacheState.FLUSHED));
-  }
-
-  void _setStateInLibrary(DataDescriptor descriptor) {
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
-    expect(entry.getStateInLibrary(descriptor, source),
-        isNot(same(CacheState.FLUSHED)));
-    entry.setStateInLibrary(descriptor, source, CacheState.FLUSHED);
-    expect(
-        entry.getStateInLibrary(descriptor, source), same(CacheState.FLUSHED));
-  }
-
-  void _setValue(DataDescriptor descriptor, Object newValue) {
-    DartEntry entry = new DartEntry();
-    Object value = entry.getValue(descriptor);
-    expect(newValue, isNot(same(value)));
-    entry.setValue(descriptor, newValue);
-    expect(entry.getState(descriptor), same(CacheState.VALID));
-    expect(entry.getValue(descriptor), same(newValue));
-  }
-
-  void _setValueInLibrary(DataDescriptor descriptor, Object newValue) {
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
-    Object value = entry.getValueInLibrary(descriptor, source);
-    expect(newValue, isNot(same(value)));
-    entry.setValueInLibrary(descriptor, source, newValue);
-    expect(entry.getStateInLibrary(descriptor, source), same(CacheState.VALID));
-    expect(entry.getValueInLibrary(descriptor, source), same(newValue));
-  }
-}
-
-@reflectiveTest
-class GenerateDartErrorsTaskTest extends EngineTestCase {
-  void test_accept() {
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(null, null, null, null);
-    expect(task.accept(new GenerateDartErrorsTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(null, null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getLibraryElement() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElement element = ElementFactory.library(context, "lib");
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(context, null, null, element);
-    expect(task.libraryElement, same(element));
-  }
-
-  void test_getSource() {
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(null, source, null, null);
-    expect(task.source, same(source));
-  }
-
-  void test_perform() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    context.applyChanges(changeSet);
-    context.setContents(
-        source,
-        r'''
-library lib;
-class A {
-  int f = new A();
-}''');
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnit unit =
-        context.getResolvedCompilationUnit(source, libraryElement);
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(context, source, unit, libraryElement);
-    task.perform(
-        new GenerateDartErrorsTaskTestTV_perform(libraryElement, source));
-  }
-
-  void test_perform_validateDirectives() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    context.applyChanges(changeSet);
-    // TODO(scheglov) "import" causes second error reported
-//    context.setContents(source, EngineTestCase.createSource([
-//        "library lib;",
-//        "import 'invaliduri^.dart';",
-//        "export '\${a}lib3.dart';",
-//        "part '/does/not/exist.dart';",
-//        "class A {}"]));
-    context.setContents(
-        source,
-        r'''
-library lib;
-part '/does/not/exist.dart';
-class A {}''');
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnit unit =
-        context.getResolvedCompilationUnit(source, libraryElement);
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(context, source, unit, libraryElement);
-    task.perform(new GenerateDartErrorsTaskTestTV_perform_validateDirectives(
-        libraryElement, source));
-  }
-}
-
-class GenerateDartErrorsTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) => true;
-}
-
-class GenerateDartErrorsTaskTestTV_perform extends TestTaskVisitor<bool> {
-  LibraryElement libraryElement;
-  Source source;
-  GenerateDartErrorsTaskTestTV_perform(this.libraryElement, this.source);
-  @override
-  bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryElement, same(libraryElement));
-    expect(task.source, same(source));
-    List<AnalysisError> errors = task.errors;
-    expect(errors, hasLength(1));
-    return true;
-  }
-}
-
-class GenerateDartErrorsTaskTestTV_perform_validateDirectives
-    extends TestTaskVisitor<bool> {
-  LibraryElement libraryElement;
-  Source source;
-  GenerateDartErrorsTaskTestTV_perform_validateDirectives(
-      this.libraryElement, this.source);
-  @override
-  bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryElement, same(libraryElement));
-    expect(task.source, same(source));
-    List<AnalysisError> errors = task.errors;
-    expect(errors, hasLength(1));
-    expect(errors[0].errorCode, same(CompileTimeErrorCode.URI_DOES_NOT_EXIST));
-    return true;
-  }
-}
-
-@reflectiveTest
-class GenerateDartHintsTaskTest extends EngineTestCase {
-  void test_accept() {
-    GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
-    expect(task.accept(new GenerateDartHintsTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getHintMap() {
-    GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
-    expect(task.hintMap, isNull);
-  }
-
-  void test_getLibraryElement() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElement element = ElementFactory.library(context, "lib");
-    GenerateDartHintsTask task =
-        new GenerateDartHintsTask(context, null, element);
-    expect(task.libraryElement, same(element));
-  }
-
-  void test_perform() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ChangeSet changeSet = new ChangeSet();
-    Source librarySource =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    changeSet.addedSource(librarySource);
-    Source unusedSource =
-        new FileBasedSource(FileUtilities2.createFile("/unused.dart"));
-    changeSet.addedSource(unusedSource);
-    Source partSource =
-        new FileBasedSource(FileUtilities2.createFile("/part.dart"));
-    changeSet.addedSource(partSource);
-    context.applyChanges(changeSet);
-    context.setContents(
-        librarySource,
-        r'''
-library lib;
-import 'unused.dart';
-part 'part.dart';''');
-    context.setContents(unusedSource, "library unused;");
-    context.setContents(partSource, "part of lib;");
-    List<TimestampedData<CompilationUnit>> units = new List<TimestampedData>(2);
-    units[0] = new TimestampedData<CompilationUnit>(
-        context.getModificationStamp(librarySource),
-        context.resolveCompilationUnit2(librarySource, librarySource));
-    units[1] = new TimestampedData<CompilationUnit>(
-        context.getModificationStamp(partSource),
-        context.resolveCompilationUnit2(partSource, librarySource));
-    GenerateDartHintsTask task = new GenerateDartHintsTask(
-        context, units, context.computeLibraryElement(librarySource));
-    task.perform(
-        new GenerateDartHintsTaskTestTV_perform(librarySource, partSource));
-  }
-}
-
-class GenerateDartHintsTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitGenerateDartHintsTask(GenerateDartHintsTask task) => true;
-}
-
-class GenerateDartHintsTaskTestTV_perform extends TestTaskVisitor<bool> {
-  Source librarySource;
-  Source partSource;
-  GenerateDartHintsTaskTestTV_perform(this.librarySource, this.partSource);
-  @override
-  bool visitGenerateDartHintsTask(GenerateDartHintsTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryElement, isNotNull);
-    HashMap<Source, List<AnalysisError>> hintMap = task.hintMap;
-    expect(hintMap, hasLength(2));
-    expect(hintMap[librarySource], hasLength(1));
-    expect(hintMap[partSource], hasLength(0));
-    return true;
-  }
-}
-
-@reflectiveTest
-class GenerateDartLintsTaskTest extends EngineTestCase {
-  void test_accept() {
-    GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
-    expect(task.accept(new GenerateDartLintsTaskTestTV_accept()), isTrue);
-  }
-
-  void test_exception() {
-    GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_libraryElement() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElement element = ElementFactory.library(context, "lib");
-    GenerateDartLintsTask task =
-        new GenerateDartLintsTask(context, null, element);
-    expect(task.libraryElement, same(element));
-  }
-
-  void test_lintMap() {
-    GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
-    expect(task.lintMap, isNull);
-  }
-
-  void test_perform() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ChangeSet changeSet = new ChangeSet();
-    Source librarySource =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    changeSet.addedSource(librarySource);
-    context.applyChanges(changeSet);
-    context.setContents(
-        librarySource,
-        r'''
-library lib;
-''');
-    List<TimestampedData<CompilationUnit>> units = new List<TimestampedData>(1);
-    units[0] = new TimestampedData<CompilationUnit>(
-        context.getModificationStamp(librarySource),
-        context.resolveCompilationUnit2(librarySource, librarySource));
-    GenerateDartLintsTask task = new GenerateDartLintsTask(
-        context, units, context.computeLibraryElement(librarySource));
-    task.perform(new GenerateDartLintsTaskTestTV_perform(librarySource));
-  }
-}
-
-class GenerateDartLintsTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitGenerateDartLintsTask(GenerateDartLintsTask task) => true;
-}
-
-class GenerateDartLintsTaskTestTV_perform extends TestTaskVisitor<bool> {
-  Source librarySource;
-  GenerateDartLintsTaskTestTV_perform(this.librarySource);
-  @override
-  bool visitGenerateDartLintsTask(GenerateDartLintsTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryElement, isNotNull);
-    return true;
-  }
-}
-
-@reflectiveTest
-class GetContentTaskTest extends EngineTestCase {
-  void test_accept() {
-    Source source = new TestSource('/test.dart', '');
-    GetContentTask task = new GetContentTask(null, source);
-    expect(task.accept(new GetContentTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    Source source = new TestSource('/test.dart', '');
-    GetContentTask task = new GetContentTask(null, source);
-    expect(task.exception, isNull);
-  }
-
-  void test_getModificationTime() {
-    Source source = new TestSource('/test.dart', '');
-    GetContentTask task = new GetContentTask(null, source);
-    expect(task.modificationTime, -1);
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('/test.dart', '');
-    GetContentTask task = new GetContentTask(null, source);
-    expect(task.source, same(source));
-  }
-
-  void test_perform_exception() {
-    TestSource source = new TestSource();
-    source.generateExceptionOnRead = true;
-    //    final InternalAnalysisContext context = new AnalysisContextImpl();
-    //    context.setSourceFactory(new SourceFactory(new FileUriResolver()));
-    GetContentTask task = new GetContentTask(null, source);
-    task.perform(new GetContentTaskTestTV_perform_exception());
-  }
-
-  void test_perform_valid() {
-    Source source = new TestSource('/test.dart', 'class A {}');
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    GetContentTask task = new GetContentTask(context, source);
-    task.perform(new GetContentTaskTestTV_perform_valid(context, source));
-  }
-}
-
-class GetContentTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitGetContentTask(GetContentTask task) => true;
-}
-
-class GetContentTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
-  @override
-  bool visitGetContentTask(GetContentTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class GetContentTaskTestTV_perform_valid extends TestTaskVisitor<bool> {
-  InternalAnalysisContext context;
-  Source source;
-  GetContentTaskTestTV_perform_valid(this.context, this.source);
-  @override
-  bool visitGetContentTask(GetContentTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.modificationTime, context.getModificationStamp(source));
-    expect(task.source, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class HtmlEntryTest extends EngineTestCase {
-  void set state(DataDescriptor descriptor) {
-    HtmlEntry entry = new HtmlEntry();
-    expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
-    entry.setState(descriptor, CacheState.FLUSHED);
-    expect(entry.getState(descriptor), same(CacheState.FLUSHED));
-  }
-
-  void test_creation() {
-    HtmlEntry entry = new HtmlEntry();
-    expect(entry, isNotNull);
-  }
-
-  void test_getAllErrors() {
-    Source source = new TestSource();
-    HtmlEntry entry = new HtmlEntry();
-    expect(entry.allErrors, hasLength(0));
-    entry.setValue(HtmlEntry.PARSE_ERRORS, <AnalysisError>[
-      new AnalysisError(source, 0, 0, ParserErrorCode.EXPECTED_TOKEN, [";"])
-    ]);
-    entry.setValue(HtmlEntry.RESOLUTION_ERRORS, <AnalysisError>[
-      new AnalysisError(source, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
-    ]);
-    entry.setValue(HtmlEntry.HINTS,
-        <AnalysisError>[new AnalysisError(source, 0, 0, HintCode.DEAD_CODE)]);
-    expect(entry.allErrors, hasLength(3));
-  }
-
-  void test_invalidateAllResolutionInformation() {
-    HtmlEntry entry = _entryWithValidState();
-    entry.invalidateAllResolutionInformation(false);
-    expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.INVALID));
-    expect(entry.getState(HtmlEntry.HINTS), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(
-        entry.getState(HtmlEntry.REFERENCED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.INVALID));
-  }
-
-  void test_invalidateAllResolutionInformation_includingUris() {
-    HtmlEntry entry = _entryWithValidState();
-    entry.invalidateAllResolutionInformation(true);
-    expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.INVALID));
-    expect(entry.getState(HtmlEntry.HINTS), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.REFERENCED_LIBRARIES),
-        same(CacheState.INVALID));
-    expect(
-        entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.INVALID));
-  }
-
-  void test_setState_element() {
-    state = HtmlEntry.ELEMENT;
-  }
-
-  void test_setState_hints() {
-    state = HtmlEntry.HINTS;
-  }
-
-  void test_setState_lineInfo() {
-    state = SourceEntry.LINE_INFO;
-  }
-
-  void test_setState_parsedUnit() {
-    state = HtmlEntry.PARSED_UNIT;
-  }
-
-  void test_setState_parseErrors() {
-    state = HtmlEntry.PARSE_ERRORS;
-  }
-
-  void test_setState_referencedLibraries() {
-    state = HtmlEntry.REFERENCED_LIBRARIES;
-  }
-
-  void test_setState_resolutionErrors() {
-    state = HtmlEntry.RESOLUTION_ERRORS;
-  }
-
-  void test_setValue_element() {
-    _setValue(HtmlEntry.ELEMENT, new HtmlElementImpl(null, "test.html"));
-  }
-
-  void test_setValue_hints() {
-    _setValue(HtmlEntry.HINTS,
-        <AnalysisError>[new AnalysisError(null, 0, 0, HintCode.DEAD_CODE)]);
-  }
-
-  void test_setValue_illegal() {
-    HtmlEntry entry = new HtmlEntry();
-    try {
-      entry.setValue(DartEntry.ELEMENT, null);
-      fail("Expected ArgumentError for DartEntry.ELEMENT");
-    } on ArgumentError {}
-  }
-
-  void test_setValue_lineInfo() {
-    _setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
-  }
-
-  void test_setValue_parsedUnit() {
-    _setValue(HtmlEntry.PARSED_UNIT, new ht.HtmlUnit(null, null, null));
-  }
-
-  void test_setValue_parseErrors() {
-    _setValue(HtmlEntry.PARSE_ERRORS, <AnalysisError>[
-      new AnalysisError(null, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
-    ]);
-  }
-
-  void test_setValue_referencedLibraries() {
-    _setValue(HtmlEntry.REFERENCED_LIBRARIES, <Source>[new TestSource()]);
-  }
-
-  void test_setValue_resolutionErrors() {
-    _setValue(HtmlEntry.RESOLUTION_ERRORS, <AnalysisError>[
-      new AnalysisError(null, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
-    ]);
-  }
-
-  HtmlEntry _entryWithValidState() {
-    HtmlEntry entry = new HtmlEntry();
-    entry.setValue(HtmlEntry.ELEMENT, null);
-    entry.setValue(HtmlEntry.HINTS, null);
-    entry.setValue(SourceEntry.LINE_INFO, null);
-    entry.setValue(HtmlEntry.PARSE_ERRORS, null);
-    entry.setValue(HtmlEntry.PARSED_UNIT, null);
-    entry.setValue(HtmlEntry.REFERENCED_LIBRARIES, null);
-    entry.setValue(HtmlEntry.RESOLUTION_ERRORS, null);
-    expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.HINTS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(
-        entry.getState(HtmlEntry.REFERENCED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.VALID));
-    return entry;
-  }
-
-  void _setValue(DataDescriptor descriptor, Object newValue) {
-    HtmlEntry entry = new HtmlEntry();
-    Object value = entry.getValue(descriptor);
-    expect(newValue, isNot(same(value)));
-    entry.setValue(descriptor, newValue);
-    expect(entry.getState(descriptor), same(CacheState.VALID));
-    expect(entry.getValue(descriptor), same(newValue));
-  }
-}
-
-@reflectiveTest
-class IncrementalAnalysisCacheTest {
-  Source _source = new TestSource();
-  DartEntry _entry = new DartEntry();
-  CompilationUnit _unit = new CompilationUnitMock();
-  IncrementalAnalysisCache _result;
-  void setUp() {
-    _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, _unit);
-  }
-
-  void test_cacheResult() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = new CompilationUnitMock();
-    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(newUnit));
-    expect(_result.oldContents, "hbazlo");
-    expect(_result.newContents, "hbazlo");
-    expect(_result.offset, 0);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 0);
-  }
-
-  void test_cacheResult_noCache() {
-    IncrementalAnalysisCache cache = null;
-    CompilationUnit newUnit = new CompilationUnitMock();
-    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_cacheResult_noCacheNoResult() {
-    IncrementalAnalysisCache cache = null;
-    CompilationUnit newUnit = null;
-    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_cacheResult_noResult() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = null;
-    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_clear_differentSource() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    Source otherSource = new TestSource("blat.dart", "blat");
-    _result = IncrementalAnalysisCache.clear(cache, otherSource);
-    expect(_result, same(cache));
-  }
-
-  void test_clear_nullCache() {
-    IncrementalAnalysisCache cache = null;
-    _result = IncrementalAnalysisCache.clear(cache, _source);
-    expect(_result, isNull);
-  }
-
-  void test_clear_sameSource() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    _result = IncrementalAnalysisCache.clear(cache, _source);
-    expect(_result, isNull);
-  }
-
-  void test_update_append() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hbazxlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 4);
-  }
-
-  void test_update_appendToCachedResult() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = new CompilationUnitMock();
-    cache = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(cache, isNotNull);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(newUnit));
-    expect(_result.oldContents, "hbazlo");
-    expect(_result.newContents, "hbazxlo");
-    expect(_result.offset, 4);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 1);
-  }
-
-  void test_update_appendWithNewResolvedUnit() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    CompilationUnit newUnit = new CompilationUnitMock();
-    newEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, newUnit);
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(newUnit));
-    expect(_result.oldContents, "hbazlo");
-    expect(_result.newContents, "hbazxlo");
-    expect(_result.offset, 4);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 1);
-  }
-
-  void test_update_appendWithNoNewResolvedUnit() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hbazxlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 4);
-  }
-
-  void test_update_delete() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hzlo", 1, 2, 0, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hzlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 1);
-  }
-
-  void test_update_insert_nonContiguous_after() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazlox", 6, 0, 1, newEntry);
-    expect(_result, isNull);
-  }
-
-  void test_update_insert_nonContiguous_before() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "xhbazlo", 0, 0, 1, newEntry);
-    expect(_result, isNull);
-  }
-
-  void test_update_newSource_entry() {
-    Source oldSource = new TestSource("blat.dart", "blat");
-    DartEntry oldEntry = new DartEntry();
-    CompilationUnit oldUnit = new CompilationUnitMock();
-    oldEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, oldUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, oldSource, "hello", "hbazlo", 1, 2, 3, oldEntry);
-    expect(cache.source, same(oldSource));
-    expect(cache.resolvedUnit, same(oldUnit));
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "foo", "foobz", 3, 0, 2, _entry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "foo");
-    expect(_result.newContents, "foobz");
-    expect(_result.offset, 3);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 2);
-  }
-
-  void test_update_newSource_noEntry() {
-    Source oldSource = new TestSource("blat.dart", "blat");
-    DartEntry oldEntry = new DartEntry();
-    CompilationUnit oldUnit = new CompilationUnitMock();
-    oldEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, oldUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, oldSource, "hello", "hbazlo", 1, 2, 3, oldEntry);
-    expect(cache.source, same(oldSource));
-    expect(cache.resolvedUnit, same(oldUnit));
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "foo", "foobar", 3, 0, 3, null);
-    expect(_result, isNull);
-  }
-
-  void test_update_noCache_entry() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hbazlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 3);
-    expect(_result.hasWork, isTrue);
-  }
-
-  void test_update_noCache_entry_noOldSource_append() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, null, "hellxo", 4, 0, 1, _entry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hellxo");
-    expect(_result.offset, 4);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 1);
-    expect(_result.hasWork, isTrue);
-  }
-
-  void test_update_noCache_entry_noOldSource_delete() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, null, "helo", 4, 1, 0, _entry);
-    expect(_result, isNull);
-  }
-
-  void test_update_noCache_entry_noOldSource_replace() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, null, "helxo", 4, 1, 1, _entry);
-    expect(_result, isNull);
-  }
-
-  void test_update_noCache_noEntry() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, null);
-    expect(_result, isNull);
-  }
-
-  void test_update_replace() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbarrlo", 3, 1, 2, null);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hbarrlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 4);
-  }
-
-  void test_verifyStructure_invalidUnit() {
-    String oldCode = "main() {foo;}";
-    String newCode = "main() {boo;}";
-    CompilationUnit badUnit = _parse("main() {bad;}");
-    _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, badUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, oldCode, newCode, 8, 1, 1, _entry);
-    CompilationUnit newUnit = _parse(newCode);
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_verifyStructure_noCache() {
-    IncrementalAnalysisCache cache = null;
-    CompilationUnit newUnit = new CompilationUnitMock();
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_verifyStructure_noCacheNoUnit() {
-    IncrementalAnalysisCache cache = null;
-    CompilationUnit newUnit = null;
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_verifyStructure_noUnit() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = null;
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, same(cache));
-    expect(_result.resolvedUnit, same(_unit));
-  }
-
-  void test_verifyStructure_otherSource() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = new CompilationUnitMock();
-    Source otherSource = new TestSource("blat.dart", "blat");
-    _result =
-        IncrementalAnalysisCache.verifyStructure(cache, otherSource, newUnit);
-    expect(_result, same(cache));
-    expect(_result.resolvedUnit, same(_unit));
-  }
-
-  void test_verifyStructure_validUnit() {
-    String oldCode = "main() {foo;}";
-    String newCode = "main() {boo;}";
-    CompilationUnit goodUnit = _parse(newCode);
-    _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, goodUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, oldCode, newCode, 1, 2, 3, _entry);
-    CompilationUnit newUnit = _parse(newCode);
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, same(cache));
-    expect(_result.resolvedUnit, same(goodUnit));
-  }
-
-  CompilationUnit _parse(String code) {
-    Scanner scanner = new Scanner(_source, new CharSequenceReader(code),
-        AnalysisErrorListener.NULL_LISTENER);
-    Parser parser = new Parser(_source, AnalysisErrorListener.NULL_LISTENER);
-    return parser.parseCompilationUnit(scanner.tokenize());
-  }
-}
-
-@reflectiveTest
-class IncrementalAnalysisTaskTest extends EngineTestCase {
-  void test_accept() {
-    IncrementalAnalysisTask task = new IncrementalAnalysisTask(null, null);
-    expect(task.accept(new IncrementalAnalysisTaskTestTV_accept()), isTrue);
-  }
-
-  void test_perform() {
-    // main() {} String foo;
-    // main() {String} String foo;
-    CompilationUnit newUnit =
-        _assertTask("main() {", "", "String", "} String foo;");
-    NodeList<CompilationUnitMember> declarations = newUnit.declarations;
-    FunctionDeclaration main = declarations[0] as FunctionDeclaration;
-    expect(main.name.name, "main");
-    BlockFunctionBody body = main.functionExpression.body as BlockFunctionBody;
-    ExpressionStatement statement =
-        body.block.statements[0] as ExpressionStatement;
-    expect(statement.toSource(), "String;");
-    SimpleIdentifier identifier = statement.expression as SimpleIdentifier;
-    expect(identifier.name, "String");
-    expect(identifier.staticElement, isNotNull);
-    TopLevelVariableDeclaration fooDecl =
-        declarations[1] as TopLevelVariableDeclaration;
-    SimpleIdentifier fooName = fooDecl.variables.variables[0].name;
-    expect(fooName.name, "foo");
-    expect(fooName.staticElement, isNotNull);
-    // assert element reference is preserved
-  }
-
-  CompilationUnit _assertTask(
-      String prefix, String removed, String added, String suffix) {
-    String oldCode = "$prefix$removed$suffix";
-    String newCode = "$prefix$added$suffix";
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    Source source = new TestSource("/test.dart", oldCode);
-    DartEntry entry = new DartEntry();
-    CompilationUnit oldUnit = context.resolveCompilationUnit2(source, source);
-    expect(oldUnit, isNotNull);
-    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, source, oldUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null,
-        source,
-        oldCode,
-        newCode,
-        prefix.length,
-        removed.length,
-        added.length,
-        entry);
-    expect(cache, isNotNull);
-    IncrementalAnalysisTask task = new IncrementalAnalysisTask(context, cache);
-    CompilationUnit newUnit =
-        task.perform(new IncrementalAnalysisTaskTestTV_assertTask(task));
-    expect(newUnit, isNotNull);
-    return newUnit;
-  }
-}
-
-class IncrementalAnalysisTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitIncrementalAnalysisTask(IncrementalAnalysisTask task) => true;
-}
-
-class IncrementalAnalysisTaskTestTV_assertTask
-    extends TestTaskVisitor<CompilationUnit> {
-  IncrementalAnalysisTask task;
-  IncrementalAnalysisTaskTestTV_assertTask(this.task);
-  @override
-  CompilationUnit visitIncrementalAnalysisTask(
-          IncrementalAnalysisTask incrementalAnalysisTask) =>
-      task.compilationUnit;
-}
-
-@reflectiveTest
-class LintGeneratorTest extends EngineTestCase {
-  void test_generate() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ChangeSet changeSet = new ChangeSet();
-    Source librarySource =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    changeSet.addedSource(librarySource);
-    context.applyChanges(changeSet);
-    context.setContents(
-        librarySource,
-        r'''
-library lib;
-''');
-
-    CompilationUnit unit =
-        context.resolveCompilationUnit2(librarySource, librarySource);
-    List<CompilationUnit> units = <CompilationUnit>[];
-    units.add(unit);
-
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-
-    LintGeneratorTest_Linter linter = new LintGeneratorTest_Linter();
-
-    LintGenerator lintGenerator =
-        new LintGenerator(units, errorListener, [linter]);
-    lintGenerator.generate();
-
-    linter.testExpectations();
-  }
-
-  void test_generate_null_visitor() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ChangeSet changeSet = new ChangeSet();
-    Source librarySource =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    changeSet.addedSource(librarySource);
-    context.applyChanges(changeSet);
-    context.setContents(
-        librarySource,
-        r'''
-library lib;
-''');
-
-    CompilationUnit unit =
-        context.resolveCompilationUnit2(librarySource, librarySource);
-    List<CompilationUnit> units = <CompilationUnit>[];
-    units.add(unit);
-
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-
-    Linter badLinter = new LintGeneratorTest_Linter_Null_Visitor();
-    LintGeneratorTest_Linter goodLinter = new LintGeneratorTest_Linter();
-
-    LintGenerator lintGenerator =
-        new LintGenerator(units, errorListener, [badLinter, goodLinter]);
-    // Test that generate does not fall down with a null visitor
-    lintGenerator.generate();
-    // Well-formed linter should still get called
-    goodLinter.testExpectations();
-  }
-}
-
-class LintGeneratorTest_Linter extends Linter with SimpleAstVisitor<Object> {
-  bool visited;
-
-  @override
-  AstVisitor getVisitor() => this;
-
-  testExpectations() {
-    expect(reporter, isNotNull);
-    expect(visited, isTrue);
-  }
-
-  @override
-  Object visitCompilationUnit(CompilationUnit node) {
-    visited = true;
-    return null;
-  }
-}
-
-class LintGeneratorTest_Linter_Null_Visitor extends Linter {
-  @override
-  AstVisitor getVisitor() => null;
-}
+class CompilationUnitMock extends TypedMock implements CompilationUnit {}
 
 class MockSourceFactory extends SourceFactory {
   MockSourceFactory() : super([]);
@@ -4794,773 +82,6 @@
 }
 
 @reflectiveTest
-class ParseDartTaskTest extends EngineTestCase {
-  void test_accept() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.accept(new ParseDartTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getCompilationUnit() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.compilationUnit, isNull);
-  }
-
-  void test_getErrors() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.errors, hasLength(0));
-  }
-
-  void test_getException() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('/test.dart');
-    ParseDartTask task = new ParseDartTask(null, source, null, null);
-    expect(task.source, same(source));
-  }
-
-  void test_hasNonPartOfDirective() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.hasNonPartOfDirective, isFalse);
-  }
-
-  void test_hasPartOfDirective() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.hasPartOfDirective, isFalse);
-  }
-
-  void test_perform_exception() {
-    TestSource source = new TestSource();
-    source.generateExceptionOnRead = true;
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseDartTask task = new ParseDartTask(context, source, null, null);
-    task.perform(new ParseDartTaskTestTV_perform_exception());
-  }
-
-  void test_perform_library() {
-    String content = r'''
-library lib;
-import 'lib2.dart';
-export 'lib3.dart';
-part 'part.dart';
-class A {''';
-    Source source = new TestSource('/test.dart', content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseDartTask task = _createParseTask(context, source, content);
-    task.perform(new ParseDartTaskTestTV_perform_library(context, source));
-  }
-
-  void test_perform_part() {
-    String content = r'''
-part of lib;
-class B {}''';
-    Source source = new TestSource('/test.dart', content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseDartTask task = _createParseTask(context, source, content);
-    task.perform(new ParseDartTaskTestTV_perform_part(context, source));
-  }
-
-  void test_perform_validateDirectives() {
-    String content = r'''
-library lib;
-import '/does/not/exist.dart';
-import '://invaliduri.dart';
-export '${a}lib3.dart';
-part 'part.dart';
-class A {}''';
-    Source source = new TestSource('/test.dart', content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseDartTask task = _createParseTask(context, source, content);
-    task.perform(
-        new ParseDartTaskTestTV_perform_validateDirectives(context, source));
-  }
-
-  void test_resolveDirective_dartUri() {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ImportDirective directive = AstFactory.importDirective3('dart:core', null);
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    Source source =
-        ParseDartTask.resolveDirective(context, null, directive, listener);
-    expect(source, isNotNull);
-  }
-
-  void test_resolveDirective_exception() {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ImportDirective directive = AstFactory.importDirective3('dart:core', null);
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    context.sourceFactory = new MockSourceFactory();
-    Source source =
-        ParseDartTask.resolveDirective(context, null, directive, listener);
-    expect(source, isNull);
-    expect(listener.errors, hasLength(1));
-  }
-
-  /**
-   * Create and return a task that will parse the given content from the given source in the given
-   * context.
-   *
-   * @param context the context to be passed to the task
-   * @param source the source to be parsed
-   * @param content the content of the source to be parsed
-   * @return the task that was created
-   * @throws AnalysisException if the task could not be created
-   */
-  ParseDartTask _createParseTask(
-      InternalAnalysisContext context, Source source, String content) {
-    ScanDartTask scanTask = new ScanDartTask(context, source, content);
-    scanTask.perform(new ParseDartTaskTestTV_createParseTask());
-    return new ParseDartTask(
-        context, source, scanTask.tokenStream, scanTask.lineInfo);
-  }
-}
-
-class ParseDartTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitParseDartTask(ParseDartTask task) => true;
-}
-
-class ParseDartTaskTestTV_createParseTask extends TestTaskVisitor<Object> {
-  @override
-  Object visitScanDartTask(ScanDartTask task) => null;
-}
-
-class ParseDartTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
-  @override
-  bool visitParseDartTask(ParseDartTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class ParseDartTaskTestTV_perform_library extends TestTaskVisitor<Object> {
-  InternalAnalysisContext context;
-  Source source;
-  ParseDartTaskTestTV_perform_library(this.context, this.source);
-  @override
-  Object visitParseDartTask(ParseDartTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.compilationUnit, isNotNull);
-    expect(task.errors, hasLength(1));
-    expect(task.source, same(source));
-    expect(task.hasNonPartOfDirective, isTrue);
-    expect(task.hasPartOfDirective, isFalse);
-    return null;
-  }
-}
-
-class ParseDartTaskTestTV_perform_part extends TestTaskVisitor<Object> {
-  InternalAnalysisContext context;
-  Source source;
-  ParseDartTaskTestTV_perform_part(this.context, this.source);
-  @override
-  Object visitParseDartTask(ParseDartTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.compilationUnit, isNotNull);
-    expect(task.errors, hasLength(0));
-    expect(task.source, same(source));
-    expect(task.hasNonPartOfDirective, isFalse);
-    expect(task.hasPartOfDirective, isTrue);
-    return null;
-  }
-}
-
-class ParseDartTaskTestTV_perform_validateDirectives
-    extends TestTaskVisitor<Object> {
-  InternalAnalysisContext context;
-  Source source;
-  ParseDartTaskTestTV_perform_validateDirectives(this.context, this.source);
-  @override
-  Object visitParseDartTask(ParseDartTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.compilationUnit, isNotNull);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    errorListener.addAll(task.errors);
-    errorListener.assertErrorsWithCodes([
-      CompileTimeErrorCode.URI_WITH_INTERPOLATION,
-      CompileTimeErrorCode.INVALID_URI
-    ]);
-    expect(task.source, same(source));
-    expect(task.hasNonPartOfDirective, isTrue);
-    expect(task.hasPartOfDirective, isFalse);
-    return null;
-  }
-}
-
-@reflectiveTest
-class ParseHtmlTaskTest extends EngineTestCase {
-  ParseHtmlTask parseContents(String contents, TestLogger testLogger) {
-    return parseSource(
-        new TestSource('/test.dart', contents), contents, testLogger);
-  }
-
-  ParseHtmlTask parseSource(
-      Source source, String contents, TestLogger testLogger) {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    context.setContents(source, contents);
-    ParseHtmlTask task = new ParseHtmlTask(context, source, contents);
-    Logger oldLogger = AnalysisEngine.instance.logger;
-    try {
-      AnalysisEngine.instance.logger = testLogger;
-      task.perform(new ParseHtmlTaskTestTV_parseSource(context, source));
-    } finally {
-      AnalysisEngine.instance.logger = oldLogger;
-    }
-    return task;
-  }
-
-  void test_accept() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.accept(new ParseHtmlTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.exception, isNull);
-  }
-
-  void test_getHtmlUnit() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.htmlUnit, isNull);
-  }
-
-  void test_getLineInfo() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.lineInfo, isNull);
-  }
-
-  void test_getReferencedLibraries() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.referencedLibraries, hasLength(0));
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('/test.dart');
-    ParseHtmlTask task = new ParseHtmlTask(null, source, "");
-    expect(task.source, same(source));
-  }
-
-  void test_perform_embedded_source() {
-    String contents = r'''
-<html>
-<head>
-  <script type='application/dart'>
-    void buttonPressed() {}
-  </script>
-</head>
-<body>
-</body>
-</html>''';
-    TestLogger testLogger = new TestLogger();
-    ParseHtmlTask task = parseContents(contents, testLogger);
-    expect(task.referencedLibraries, hasLength(0));
-    expect(testLogger.errorCount, 0);
-    expect(testLogger.infoCount, 0);
-  }
-
-  void test_perform_empty_source_reference() {
-    String contents = r'''
-<html>
-<head>
-  <script type='application/dart' src=''/>
-</head>
-<body>
-</body>
-</html>''';
-    TestLogger testLogger = new TestLogger();
-    ParseHtmlTask task = parseContents(contents, testLogger);
-    expect(task.referencedLibraries, hasLength(0));
-    expect(testLogger.errorCount, 0);
-    expect(testLogger.infoCount, 0);
-  }
-
-  void test_perform_invalid_source_reference() {
-    String contents = r'''
-<html>
-<head>
-  <script type='application/dart' src='an;invalid:[]uri'/>
-</head>
-<body>
-</body>
-</html>''';
-    TestLogger testLogger = new TestLogger();
-    ParseHtmlTask task = parseContents(contents, testLogger);
-    expect(task.referencedLibraries, hasLength(0));
-    expect(testLogger.errorCount, 0);
-    expect(testLogger.infoCount, 0);
-  }
-
-  void test_perform_non_existing_source_reference() {
-    String contents = r'''
-<html>
-<head>
-  <script type='application/dart' src='does/not/exist.dart'/>
-</head>
-<body>
-</body>
-</html>''';
-    TestLogger testLogger = new TestLogger();
-    ParseHtmlTask task = parseSource(
-        new ParseHtmlTaskTest_non_existing_source(contents),
-        contents,
-        testLogger);
-    expect(task.referencedLibraries, hasLength(0));
-    expect(testLogger.errorCount, 0);
-    expect(testLogger.infoCount, 0);
-  }
-
-  void test_perform_referenced_source() {
-    // TODO(scheglov) this test fails because we put into cache TestSource
-    // test.dart (and actually should test.html), but resolve
-    // src='test.dart' as a FileBasedSource
-    // We need to switch to a virtual file system and use it everywhere.
-//    String contents = EngineTestCase.createSource([
-//        "<html>",
-//        "<head>",
-//        "  <script type='application/dart' src='test.dart'/>",
-//        "</head>",
-//        "<body>",
-//        "</body>",
-//        "</html>"]);
-//    TestLogger testLogger = new TestLogger();
-//    ParseHtmlTask task = parseContents(contents, testLogger);
-//    EngineTestCase.assertLength(1, task.referencedLibraries);
-//    JUnitTestCase.assertEquals(0, testLogger.errorCount);
-//    JUnitTestCase.assertEquals(0, testLogger.errorCount);
-  }
-}
-
-class ParseHtmlTaskTest_non_existing_source extends TestSource {
-  ParseHtmlTaskTest_non_existing_source(String arg0) : super(arg0);
-  @override
-  Uri resolveRelativeUri(Uri containedUri) {
-    try {
-      return parseUriWithException("file:/does/not/exist.dart");
-    } on URISyntaxException {
-      return null;
-    }
-  }
-}
-
-class ParseHtmlTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitParseHtmlTask(ParseHtmlTask task) => true;
-}
-
-class ParseHtmlTaskTestTV_parseSource extends TestTaskVisitor<bool> {
-  InternalAnalysisContext context;
-  Source source;
-  ParseHtmlTaskTestTV_parseSource(this.context, this.source);
-  @override
-  bool visitParseHtmlTask(ParseHtmlTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.htmlUnit, isNotNull);
-    expect(task.lineInfo, isNotNull);
-    expect(task.source, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class PartitionManagerTest extends EngineTestCase {
-  void test_clearCache() {
-    PartitionManager manager = new PartitionManager();
-    DartSdk sdk = new MockDartSdk();
-    SdkCachePartition oldPartition = manager.forSdk(sdk);
-    manager.clearCache();
-    SdkCachePartition newPartition = manager.forSdk(sdk);
-    expect(newPartition, isNot(same(oldPartition)));
-  }
-
-  void test_creation() {
-    expect(new PartitionManager(), isNotNull);
-  }
-
-  void test_forSdk() {
-    PartitionManager manager = new PartitionManager();
-    DartSdk sdk1 = new MockDartSdk();
-    SdkCachePartition partition1 = manager.forSdk(sdk1);
-    expect(partition1, isNotNull);
-    expect(manager.forSdk(sdk1), same(partition1));
-    DartSdk sdk2 = new MockDartSdk();
-    SdkCachePartition partition2 = manager.forSdk(sdk2);
-    expect(partition2, isNotNull);
-    expect(manager.forSdk(sdk2), same(partition2));
-    expect(partition2, isNot(same(partition1)));
-  }
-}
-
-@reflectiveTest
-class ResolveDartLibraryTaskTest extends EngineTestCase {
-  void test_accept() {
-    ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
-    expect(task.accept(new ResolveDartLibraryTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getLibraryResolver() {
-    ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
-    expect(task.libraryResolver, isNull);
-  }
-
-  void test_getLibrarySource() {
-    Source source = new TestSource('/test.dart');
-    ResolveDartLibraryTask task =
-        new ResolveDartLibraryTask(null, null, source);
-    expect(task.librarySource, same(source));
-  }
-
-  void test_getUnitSource() {
-    Source source = new TestSource('/test.dart');
-    ResolveDartLibraryTask task =
-        new ResolveDartLibraryTask(null, source, null);
-    expect(task.unitSource, same(source));
-  }
-
-  void test_perform_exception() {
-    TestSource source = new TestSource();
-    source.generateExceptionOnRead = true;
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ResolveDartLibraryTask task =
-        new ResolveDartLibraryTask(context, source, source);
-    task.perform(new ResolveDartLibraryTaskTestTV_perform_exception());
-  }
-
-  void test_perform_library() {
-    Source source = new TestSource(
-        '/test.dart',
-        r'''
-library lib;
-class A {}''');
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ResolveDartLibraryTask task =
-        new ResolveDartLibraryTask(context, source, source);
-    task.perform(new ResolveDartLibraryTaskTestTV_perform_library(source));
-  }
-}
-
-class ResolveDartLibraryTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) => true;
-}
-
-class ResolveDartLibraryTaskTestTV_perform_exception
-    extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class ResolveDartLibraryTaskTestTV_perform_library
-    extends TestTaskVisitor<bool> {
-  Source source;
-  ResolveDartLibraryTaskTestTV_perform_library(this.source);
-  @override
-  bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryResolver, isNotNull);
-    expect(task.librarySource, same(source));
-    expect(task.unitSource, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class ResolveDartUnitTaskTest extends EngineTestCase {
-  void test_accept() {
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
-    expect(task.accept(new ResolveDartUnitTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getLibrarySource() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElementImpl element = ElementFactory.library(context, "lib");
-    Source source = element.source;
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, element);
-    expect(task.librarySource, same(source));
-  }
-
-  void test_getResolvedUnit() {
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
-    expect(task.resolvedUnit, isNull);
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('/test.dart');
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, source, null);
-    expect(task.source, same(source));
-  }
-
-  void test_perform_exception() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElementImpl element = ElementFactory.library(context, "lib");
-    TestSource source = new TestSource();
-    source.generateExceptionOnRead = true;
-    (element.definingCompilationUnit as CompilationUnitElementImpl).source =
-        source;
-    ResolveDartUnitTask task =
-        new ResolveDartUnitTask(context, source, element);
-    task.perform(new ResolveDartUnitTaskTestTV_perform_exception());
-  }
-
-  void test_perform_library() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElementImpl libraryElement = ElementFactory.library(context, "lib");
-    CompilationUnitElementImpl unitElement =
-        libraryElement.definingCompilationUnit as CompilationUnitElementImpl;
-    ClassElementImpl classElement = ElementFactory.classElement2("A");
-    classElement.nameOffset = 19;
-    ConstructorElementImpl constructorElement =
-        ElementFactory.constructorElement2(classElement, null);
-    constructorElement.synthetic = true;
-    classElement.constructors = <ConstructorElement>[constructorElement];
-    unitElement.types = <ClassElement>[classElement];
-    Source source = unitElement.source;
-    context.setContents(
-        source,
-        r'''
-library lib;
-class A {}''');
-    ResolveDartUnitTask task =
-        new ResolveDartUnitTask(context, source, libraryElement);
-    task.perform(
-        new ResolveDartUnitTaskTestTV_perform_library(source, context));
-  }
-}
-
-class ResolveDartUnitTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveDartUnitTask(ResolveDartUnitTask task) => true;
-}
-
-class ResolveDartUnitTaskTestTV_perform_exception
-    extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveDartUnitTask(ResolveDartUnitTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class ResolveDartUnitTaskTestTV_perform_library extends TestTaskVisitor<bool> {
-  Source source;
-  InternalAnalysisContext context;
-  ResolveDartUnitTaskTestTV_perform_library(this.source, this.context);
-  @override
-  bool visitResolveDartUnitTask(ResolveDartUnitTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.librarySource, same(source));
-    expect(task.resolvedUnit, isNotNull);
-    expect(task.source, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class ResolveHtmlTaskTest extends EngineTestCase {
-  void test_accept() {
-    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
-    expect(task.accept(new ResolveHtmlTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getElement() {
-    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
-    expect(task.element, isNull);
-  }
-
-  void test_getException() {
-    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getResolutionErrors() {
-    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
-    expect(task.resolutionErrors, hasLength(0));
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('test.dart', '');
-    ResolveHtmlTask task = new ResolveHtmlTask(null, source, 0, null);
-    expect(task.source, same(source));
-  }
-
-  void test_perform_exception() {
-    Source source = new TestSource();
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ResolveHtmlTask task = new ResolveHtmlTask(context, source, 0, null);
-    task.perform(new ResolveHtmlTaskTestTV_perform_exception());
-  }
-
-  void test_perform_valid() {
-    int modificationStamp = 73;
-    String content = r'''
-<html>
-<head>
-  <script type='application/dart'>
-    void f() { x = 0; }
-  </script>
-</head>
-<body>
-</body>
-</html>''';
-    Source source = new TestSource("/test.html", content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseHtmlTask parseTask = new ParseHtmlTask(context, source, content);
-    parseTask.perform(new ResolveHtmlTaskTestTV_perform_valid_2());
-    ResolveHtmlTask task = new ResolveHtmlTask(
-        context, source, modificationStamp, parseTask.htmlUnit);
-    task.perform(
-        new ResolveHtmlTaskTestTV_perform_valid(modificationStamp, source));
-  }
-}
-
-class ResolveHtmlTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveHtmlTask(ResolveHtmlTask task) => true;
-}
-
-class ResolveHtmlTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveHtmlTask(ResolveHtmlTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class ResolveHtmlTaskTestTV_perform_valid extends TestTaskVisitor<Object> {
-  int modificationStamp;
-  Source source;
-  ResolveHtmlTaskTestTV_perform_valid(this.modificationStamp, this.source);
-  @override
-  Object visitResolveHtmlTask(ResolveHtmlTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.element, isNotNull);
-    expect(task.resolutionErrors, hasLength(1));
-    expect(task.source, same(source));
-    return null;
-  }
-}
-
-class ResolveHtmlTaskTestTV_perform_valid_2 extends TestTaskVisitor<Object> {
-  @override
-  Object visitParseHtmlTask(ParseHtmlTask task) => null;
-}
-
-@reflectiveTest
-class ScanDartTaskTest extends EngineTestCase {
-  void test_accept() {
-    ScanDartTask task = new ScanDartTask(null, null, null);
-    expect(task.accept(new ScanDartTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getErrors() {
-    ScanDartTask task = new ScanDartTask(null, null, null);
-    expect(task.errors, hasLength(0));
-  }
-
-  void test_getException() {
-    ScanDartTask task = new ScanDartTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getLineInfo() {
-    ScanDartTask task = new ScanDartTask(null, null, null);
-    expect(task.lineInfo, isNull);
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('test.dart', '');
-    ScanDartTask task = new ScanDartTask(null, source, null);
-    expect(task.source, same(source));
-  }
-
-  void test_perform_valid() {
-    String content = 'class A {}';
-    Source source = new TestSource('test.dart', content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ScanDartTask task = new ScanDartTask(context, source, content);
-    task.perform(new ScanDartTaskTestTV_perform_valid(context, source));
-  }
-}
-
-class ScanDartTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitScanDartTask(ScanDartTask task) => true;
-}
-
-class ScanDartTaskTestTV_perform_valid extends TestTaskVisitor<bool> {
-  InternalAnalysisContext context;
-  Source source;
-  ScanDartTaskTestTV_perform_valid(this.context, this.source);
-  @override
-  bool visitScanDartTask(ScanDartTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.tokenStream, isNotNull);
-    expect(task.errors, hasLength(0));
-    expect(task.lineInfo, isNotNull);
-    expect(task.source, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class SdkCachePartitionTest extends EngineTestCase {
-  void test_contains_false() {
-    SdkCachePartition partition = new SdkCachePartition(null, 8);
-    Source source = new TestSource();
-    expect(partition.contains(source), isFalse);
-  }
-
-  void test_contains_true() {
-    SdkCachePartition partition = new SdkCachePartition(null, 8);
-    SourceFactory factory = new SourceFactory(
-        [new DartUriResolver(DirectoryBasedDartSdk.defaultSdk)]);
-    Source source = factory.forUri("dart:core");
-    expect(partition.contains(source), isTrue);
-  }
-
-  void test_creation() {
-    expect(new SdkCachePartition(null, 8), isNotNull);
-  }
-}
-
-@reflectiveTest
 class SourcesChangedEventTest {
   void test_added() {
     var source = new StringSource('', '/test.dart');
@@ -5704,7 +225,13 @@
   }
 
   @override
-  List<newContext.AnalysisTarget> get explicitTargets {
+  EmbedderYamlLocator get embedderYamlLocator {
+    fail("Unexpected invocation of get embedderYamlLocator");
+    return null;
+  }
+
+  @override
+  List<AnalysisTarget> get explicitTargets {
     fail("Unexpected invocation of visitCacheItems");
     return null;
   }
@@ -5740,12 +267,6 @@
   }
 
   @override
-  LibraryResolverFactory get libraryResolverFactory {
-    fail("Unexpected invocation of getLibraryResolverFactory");
-    return null;
-  }
-
-  @override
   List<Source> get librarySources {
     fail("Unexpected invocation of getLibrarySources");
     return null;
@@ -5775,7 +296,7 @@
   }
 
   @override
-  List<newContext.AnalysisTarget> get priorityTargets {
+  List<AnalysisTarget> get priorityTargets {
     fail("Unexpected invocation of visitCacheItems");
     return null;
   }
@@ -5787,12 +308,6 @@
   }
 
   @override
-  ResolverVisitorFactory get resolverVisitorFactory {
-    fail("Unexpected invocation of getResolverVisitorFactory");
-    return null;
-  }
-
-  @override
   SourceFactory get sourceFactory {
     fail("Unexpected invocation of getSourceFactory");
     return null;
@@ -5810,12 +325,6 @@
   }
 
   @override
-  AnalysisContextStatistics get statistics {
-    fail("Unexpected invocation of getStatistics");
-    return null;
-  }
-
-  @override
   TypeProvider get typeProvider {
     fail("Unexpected invocation of getTypeProvider");
     return null;
@@ -5827,20 +336,21 @@
   }
 
   @override
-  TypeResolverVisitorFactory get typeResolverVisitorFactory {
-    fail("Unexpected invocation of getTypeResolverVisitorFactory");
-    return null;
-  }
-
-  @override
   TypeSystem get typeSystem {
     fail("Unexpected invocation of getTypeSystem");
     return null;
   }
 
   @override
-  List<newContext.WorkManager> get workManagers {
+  List<WorkManager> get workManagers {
     fail("Unexpected invocation of workManagers");
+    return null;
+  }
+
+  @override
+  bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) {
+    fail("Unexpected invocation of aboutToComputeResult");
+    return false;
   }
 
   @override
@@ -5854,8 +364,9 @@
   }
 
   @override
-  void applyChanges(ChangeSet changeSet) {
+  ApplyChangesStatus applyChanges(ChangeSet changeSet) {
     fail("Unexpected invocation of applyChanges");
+    return null;
   }
 
   @override
@@ -5877,13 +388,6 @@
   }
 
   @override
-  @deprecated
-  HtmlElement computeHtmlElement(Source source) {
-    fail("Unexpected invocation of computeHtmlElement");
-    return null;
-  }
-
-  @override
   List<Source> computeImportedLibraries(Source source) {
     fail("Unexpected invocation of computeImportedLibraries");
     return null;
@@ -5908,12 +412,6 @@
   }
 
   @override
-  CompilationUnit computeResolvableCompilationUnit(Source source) {
-    fail("Unexpected invocation of computeResolvableCompilationUnit");
-    return null;
-  }
-
-  @override
   Future<CompilationUnit> computeResolvedCompilationUnitAsync(
       Source source, Source librarySource) {
     fail("Unexpected invocation of getResolvedCompilationUnitFuture");
@@ -5921,8 +419,7 @@
   }
 
   @override
-  Object computeResult(
-      newContext.AnalysisTarget target, newContext.ResultDescriptor result) {
+  Object computeResult(AnalysisTarget target, ResultDescriptor result) {
     fail("Unexpected invocation of computeResult");
     return null;
   }
@@ -5945,7 +442,7 @@
   }
 
   @override
-  CacheEntry getCacheEntry(newContext.AnalysisTarget target) {
+  CacheEntry getCacheEntry(AnalysisTarget target) {
     fail("Unexpected invocation of visitCacheItems");
     return null;
   }
@@ -5958,8 +455,9 @@
   }
 
   @override
-  Object getConfigurationData(newContext.ResultDescriptor key) {
+  Object getConfigurationData(ResultDescriptor key) {
     fail("Unexpected invocation of getConfigurationData");
+    return null;
   }
 
   @override
@@ -5987,13 +485,6 @@
   }
 
   @override
-  @deprecated
-  HtmlElement getHtmlElement(Source source) {
-    fail("Unexpected invocation of getHtmlElement");
-    return null;
-  }
-
-  @override
   List<Source> getHtmlFilesReferencing(Source source) {
     fail("Unexpected invocation of getHtmlFilesReferencing");
     return null;
@@ -6068,15 +559,7 @@
   }
 
   @override
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
-    fail("Unexpected invocation of getResolvedHtmlUnit");
-    return null;
-  }
-
-  @override
-  Object getResult(
-      newContext.AnalysisTarget target, newContext.ResultDescriptor result) {
+  Object getResult(AnalysisTarget target, ResultDescriptor result) {
     fail("Unexpected invocation of getResult");
     return null;
   }
@@ -6112,8 +595,7 @@
   }
 
   @override
-  Stream<ComputedResult> onResultComputed(
-      newContext.ResultDescriptor descriptor) {
+  Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
     fail("Unexpected invocation of onResultComputed");
     return null;
   }
@@ -6131,12 +613,6 @@
   }
 
   @override
-  ht.HtmlUnit parseHtmlUnit(Source source) {
-    fail("Unexpected invocation of parseHtmlUnit");
-    return null;
-  }
-
-  @override
   AnalysisResult performAnalysisTask() {
     fail("Unexpected invocation of performAnalysisTask");
     return null;
@@ -6167,20 +643,13 @@
   }
 
   @override
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
-    fail("Unexpected invocation of resolveHtmlUnit");
-    return null;
-  }
-
-  @override
   void setChangedContents(Source source, String contents, int offset,
       int oldLength, int newLength) {
     fail("Unexpected invocation of setChangedContents");
   }
 
   @override
-  void setConfigurationData(newContext.ResultDescriptor key, Object data) {
+  void setConfigurationData(ResultDescriptor key, Object data) {
     fail("Unexpected invocation of setConfigurationData");
   }
 
@@ -6190,7 +659,7 @@
   }
 
   @override
-  bool shouldErrorsBeAnalyzed(Source source, Object entry) {
+  bool shouldErrorsBeAnalyzed(Source source) {
     fail("Unexpected invocation of shouldErrorsBeAnalyzed");
     return false;
   }
@@ -6206,843 +675,8 @@
     return false;
   }
 
-  @deprecated
-  @override
-  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state)) {
-    fail("Unexpected invocation of visitCacheItems");
-  }
-
   @override
   void visitContentCache(ContentCacheVisitor visitor) {
     fail("Unexpected invocation of visitContentCache");
   }
 }
-
-class TestAnalysisContext_test_applyChanges extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_applyChanges();
-  @override
-  void applyChanges(ChangeSet changeSet) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_computeDocumentationComment
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeDocumentationComment();
-  @override
-  String computeDocumentationComment(Element element) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeErrors extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeErrors();
-  @override
-  List<AnalysisError> computeErrors(Source source) {
-    invoked = true;
-    return AnalysisError.NO_ERRORS;
-  }
-}
-
-class TestAnalysisContext_test_computeExportedLibraries
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeExportedLibraries();
-  @override
-  List<Source> computeExportedLibraries(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeHtmlElement extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeHtmlElement();
-  @override
-  @deprecated
-  HtmlElement computeHtmlElement(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeImportedLibraries
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeImportedLibraries();
-  @override
-  List<Source> computeImportedLibraries(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeKindOf extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeKindOf();
-  @override
-  SourceKind computeKindOf(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeLibraryElement
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeLibraryElement();
-  @override
-  LibraryElement computeLibraryElement(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeLineInfo extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeLineInfo();
-  @override
-  LineInfo computeLineInfo(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeResolvableCompilationUnit
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeResolvableCompilationUnit();
-  @override
-  CompilationUnit computeResolvableCompilationUnit(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_dispose extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_dispose();
-  @override
-  void dispose() {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_exists extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_exists();
-  @override
-  bool exists(Source source) {
-    invoked = true;
-    return false;
-  }
-}
-
-class TestAnalysisContext_test_getAnalysisOptions extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getAnalysisOptions();
-  @override
-  AnalysisOptions get analysisOptions {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getCompilationUnitElement
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getCompilationUnitElement();
-  @override
-  CompilationUnitElement getCompilationUnitElement(
-      Source unitSource, Source librarySource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getContents extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getContents();
-  @override
-  TimestampedData<String> getContents(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getElement extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getElement();
-  @override
-  Element getElement(ElementLocation location) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getErrors extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getErrors();
-  @override
-  AnalysisErrorInfo getErrors(Source source) {
-    invoked = true;
-    return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
-  }
-}
-
-class TestAnalysisContext_test_getHtmlElement extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getHtmlElement();
-  @override
-  @deprecated
-  HtmlElement getHtmlElement(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getHtmlFilesReferencing
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getHtmlFilesReferencing();
-  @override
-  List<Source> getHtmlFilesReferencing(Source source) {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getHtmlSources extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getHtmlSources();
-  @override
-  List<Source> get htmlSources {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getKindOf extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getKindOf();
-  @override
-  SourceKind getKindOf(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getLaunchableClientLibrarySources
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLaunchableClientLibrarySources();
-  @override
-  List<Source> get launchableClientLibrarySources {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLaunchableServerLibrarySources
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLaunchableServerLibrarySources();
-  @override
-  List<Source> get launchableServerLibrarySources {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLibrariesContaining
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibrariesContaining();
-  @override
-  List<Source> getLibrariesContaining(Source source) {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLibrariesDependingOn
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibrariesDependingOn();
-  @override
-  List<Source> getLibrariesDependingOn(Source librarySource) {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLibrariesReferencedFromHtml
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibrariesReferencedFromHtml();
-  @override
-  List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getLibraryElement extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibraryElement();
-  @override
-  LibraryElement getLibraryElement(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getLibrarySources extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibrarySources();
-  @override
-  List<Source> get librarySources {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLineInfo extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLineInfo();
-  @override
-  LineInfo getLineInfo(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getModificationStamp
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getModificationStamp();
-  @override
-  int getModificationStamp(Source source) {
-    invoked = true;
-    return 0;
-  }
-}
-
-class TestAnalysisContext_test_getPublicNamespace extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getPublicNamespace();
-  @override
-  Namespace getPublicNamespace(LibraryElement library) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getResolvedCompilationUnit_element
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getResolvedCompilationUnit_element();
-  @override
-  CompilationUnit getResolvedCompilationUnit(
-      Source unitSource, LibraryElement library) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getResolvedCompilationUnit_source
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getResolvedCompilationUnit_source();
-  @override
-  CompilationUnit getResolvedCompilationUnit2(
-      Source unitSource, Source librarySource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getResolvedHtmlUnit extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getResolvedHtmlUnit();
-  @override
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getSourceFactory extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getSourceFactory();
-  @override
-  SourceFactory get sourceFactory {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getStatistics extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getStatistics();
-  @override
-  AnalysisContextStatistics get statistics {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getTypeProvider extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getTypeProvider();
-  @override
-  TypeProvider get typeProvider {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_isClientLibrary extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_isClientLibrary();
-  @override
-  bool isClientLibrary(Source librarySource) {
-    invoked = true;
-    return false;
-  }
-}
-
-class TestAnalysisContext_test_isDisposed extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_isDisposed();
-  @override
-  bool get isDisposed {
-    invoked = true;
-    return false;
-  }
-}
-
-class TestAnalysisContext_test_isServerLibrary extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_isServerLibrary();
-  @override
-  bool isServerLibrary(Source librarySource) {
-    invoked = true;
-    return false;
-  }
-}
-
-class TestAnalysisContext_test_parseCompilationUnit
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_parseCompilationUnit();
-  @override
-  CompilationUnit parseCompilationUnit(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_parseHtmlUnit extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_parseHtmlUnit();
-  @override
-  ht.HtmlUnit parseHtmlUnit(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_performAnalysisTask extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_performAnalysisTask();
-  @override
-  AnalysisResult performAnalysisTask() {
-    invoked = true;
-    return new AnalysisResult(new List<ChangeNotice>(0), 0, null, 0);
-  }
-}
-
-class TestAnalysisContext_test_recordLibraryElements
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_recordLibraryElements();
-  @override
-  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_resolveCompilationUnit
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_resolveCompilationUnit();
-  @override
-  CompilationUnit resolveCompilationUnit2(
-      Source unitSource, Source librarySource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_resolveCompilationUnit_element
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_resolveCompilationUnit_element();
-  @override
-  CompilationUnit resolveCompilationUnit(
-      Source unitSource, LibraryElement library) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_resolveHtmlUnit extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_resolveHtmlUnit();
-  @override
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_setAnalysisOptions extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setAnalysisOptions();
-  @override
-  void set analysisOptions(AnalysisOptions options) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_setAnalysisPriorityOrder
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setAnalysisPriorityOrder();
-  @override
-  void set analysisPriorityOrder(List<Source> sources) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_setChangedContents extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setChangedContents();
-  @override
-  void setChangedContents(Source source, String contents, int offset,
-      int oldLength, int newLength) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_setContents extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setContents();
-  @override
-  void setContents(Source source, String contents) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_setSourceFactory extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setSourceFactory();
-  @override
-  void set sourceFactory(SourceFactory factory) {
-    invoked = true;
-  }
-}
-
-/**
- * Instances of the class `TestTaskVisitor` implement a task visitor that fails if any of its
- * methods are invoked. Subclasses typically override the expected methods to not cause a test
- * failure.
- */
-class TestTaskVisitor<E> implements AnalysisTaskVisitor<E> {
-  @override
-  E visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
-    fail("Unexpectedly invoked visitGenerateDartErrorsTask");
-    return null;
-  }
-
-  @override
-  E visitGenerateDartHintsTask(GenerateDartHintsTask task) {
-    fail("Unexpectedly invoked visitGenerateDartHintsTask");
-    return null;
-  }
-
-  @override
-  E visitGenerateDartLintsTask(GenerateDartLintsTask task) {
-    fail("Unexpectedly invoked visitGenerateDartLintsTask");
-    return null;
-  }
-
-  @override
-  E visitGetContentTask(GetContentTask task) {
-    fail("Unexpectedly invoked visitGetContentsTask");
-    return null;
-  }
-
-  @override
-  E visitIncrementalAnalysisTask(
-      IncrementalAnalysisTask incrementalAnalysisTask) {
-    fail("Unexpectedly invoked visitIncrementalAnalysisTask");
-    return null;
-  }
-
-  @override
-  E visitParseDartTask(ParseDartTask task) {
-    fail("Unexpectedly invoked visitParseDartTask");
-    return null;
-  }
-
-  @override
-  E visitParseHtmlTask(ParseHtmlTask task) {
-    fail("Unexpectedly invoked visitParseHtmlTask");
-    return null;
-  }
-
-  @override
-  E visitResolveDartLibraryCycleTask(ResolveDartLibraryCycleTask task) {
-    fail("Unexpectedly invoked visitResolveDartLibraryCycleTask");
-    return null;
-  }
-
-  @override
-  E visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
-    fail("Unexpectedly invoked visitResolveDartLibraryTask");
-    return null;
-  }
-
-  @override
-  E visitResolveDartUnitTask(ResolveDartUnitTask task) {
-    fail("Unexpectedly invoked visitResolveDartUnitTask");
-    return null;
-  }
-
-  @override
-  E visitResolveHtmlTask(ResolveHtmlTask task) {
-    fail("Unexpectedly invoked visitResolveHtmlTask");
-    return null;
-  }
-
-  @override
-  E visitScanDartTask(ScanDartTask task) {
-    fail("Unexpectedly invoked visitScanDartTask");
-    return null;
-  }
-}
-
-@reflectiveTest
-class UniversalCachePartitionTest extends EngineTestCase {
-  void test_contains() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    expect(partition.contains(source), isTrue);
-  }
-
-  void test_creation() {
-    expect(new UniversalCachePartition(null, 8, null), isNotNull);
-  }
-
-  void test_entrySet() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    partition.put(source, entry);
-    Map<Source, SourceEntry> entryMap = partition.map;
-    expect(entryMap.length, 1);
-    Source entryKey = entryMap.keys.first;
-    expect(entryKey, same(source));
-    expect(entryMap[entryKey], same(entry));
-  }
-
-  void test_get() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    expect(partition.get(source), isNull);
-  }
-
-  void test_put_noFlush() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    partition.put(source, entry);
-    expect(partition.get(source), same(entry));
-  }
-
-  void test_remove() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    partition.put(source, entry);
-    expect(partition.get(source), same(entry));
-    partition.remove(source);
-    expect(partition.get(source), isNull);
-  }
-
-  void test_setMaxCacheSize() {
-    UniversalCachePartition partition = new UniversalCachePartition(
-        null, 8, new _UniversalCachePartitionTest_test_setMaxCacheSize());
-    int size = 6;
-    for (int i = 0; i < size; i++) {
-      Source source = new TestSource("/test$i.dart");
-      DartEntry entry = new DartEntry();
-      entry.setValue(DartEntry.PARSED_UNIT, null);
-      partition.put(source, entry);
-      partition.accessedAst(source);
-    }
-    _assertNonFlushedCount(size, partition);
-    int newSize = size - 2;
-    partition.maxCacheSize = newSize;
-    _assertNonFlushedCount(newSize, partition);
-  }
-
-  void test_size() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    int size = 4;
-    for (int i = 0; i < size; i++) {
-      Source source = new TestSource("/test$i.dart");
-      partition.put(source, new DartEntry());
-      partition.accessedAst(source);
-    }
-    expect(partition.size(), size);
-  }
-
-  void _assertNonFlushedCount(
-      int expectedCount, UniversalCachePartition partition) {
-    int nonFlushedCount = 0;
-    Map<Source, SourceEntry> entryMap = partition.map;
-    entryMap.values.forEach((SourceEntry value) {
-      if (value.getState(DartEntry.PARSED_UNIT) != CacheState.FLUSHED) {
-        nonFlushedCount++;
-      }
-    });
-    expect(nonFlushedCount, expectedCount);
-  }
-}
-
-@reflectiveTest
-class WorkManagerTest extends EngineTestCase {
-  void test_addFirst() {
-    TestSource source1 = new TestSource("/f1.dart");
-    TestSource source2 = new TestSource("/f2.dart");
-    WorkManager manager = new WorkManager();
-    manager.add(source1, SourcePriority.UNKNOWN);
-    manager.addFirst(source2, SourcePriority.UNKNOWN);
-    WorkManager_WorkIterator iterator = manager.iterator();
-    expect(iterator.next(), same(source2));
-    expect(iterator.next(), same(source1));
-  }
-
-  void test_creation() {
-    expect(new WorkManager(), isNotNull);
-  }
-
-  void test_iterator_empty() {
-    WorkManager manager = new WorkManager();
-    WorkManager_WorkIterator iterator = manager.iterator();
-    expect(iterator.hasNext, isFalse);
-    try {
-      iterator.next();
-      fail("Expected NoSuchElementException");
-    } on NoSuchElementException {}
-  }
-
-  void test_iterator_nonEmpty() {
-    TestSource source = new TestSource();
-    WorkManager manager = new WorkManager();
-    manager.add(source, SourcePriority.UNKNOWN);
-    WorkManager_WorkIterator iterator = manager.iterator();
-    expect(iterator.hasNext, isTrue);
-    expect(iterator.next(), same(source));
-  }
-
-  void test_remove() {
-    TestSource source1 = new TestSource("/f1.dart");
-    TestSource source2 = new TestSource("/f2.dart");
-    TestSource source3 = new TestSource("/f3.dart");
-    WorkManager manager = new WorkManager();
-    manager.add(source1, SourcePriority.UNKNOWN);
-    manager.add(source2, SourcePriority.UNKNOWN);
-    manager.add(source3, SourcePriority.UNKNOWN);
-    manager.remove(source2);
-    WorkManager_WorkIterator iterator = manager.iterator();
-    expect(iterator.next(), same(source1));
-    expect(iterator.next(), same(source3));
-  }
-
-  void test_toString_empty() {
-    WorkManager manager = new WorkManager();
-    expect(manager.toString(), isNotNull);
-  }
-
-  void test_toString_nonEmpty() {
-    WorkManager manager = new WorkManager();
-    manager.add(new TestSource(), SourcePriority.HTML);
-    manager.add(new TestSource(), SourcePriority.LIBRARY);
-    manager.add(new TestSource(), SourcePriority.NORMAL_PART);
-    manager.add(new TestSource(), SourcePriority.PRIORITY_PART);
-    manager.add(new TestSource(), SourcePriority.UNKNOWN);
-    expect(manager.toString(), isNotNull);
-  }
-}
-
-class _AnalysisCacheTest_test_setMaxCacheSize implements CacheRetentionPolicy {
-  @override
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) =>
-      RetentionPriority.LOW;
-}
-
-class _AnalysisContext_sourceChangeDuringResolution
-    extends AnalysisContextForTests {
-  @override
-  DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.changedSource(task.librarySource);
-    applyChanges(changeSet);
-    return super.recordResolveDartLibraryTaskResults(task);
-  }
-}
-
-class _AnalysisContextImplTest_test_applyChanges_removeContainer
-    implements SourceContainer {
-  Source libB;
-  _AnalysisContextImplTest_test_applyChanges_removeContainer(this.libB);
-  @override
-  bool contains(Source source) => source == libB;
-}
-
-class _Source_getContent_throwException extends NonExistingSource {
-  _Source_getContent_throwException(String name)
-      : super(name, pathos.toUri(name), UriKind.FILE_URI);
-
-  @override
-  TimestampedData<String> get contents {
-    throw 'Read error';
-  }
-
-  @override
-  bool exists() => true;
-}
-
-class _UniversalCachePartitionTest_test_setMaxCacheSize
-    implements CacheRetentionPolicy {
-  @override
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) =>
-      RetentionPriority.LOW;
-}
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index eaef165..6a52fce 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -2,11 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_resolver_test;
+library analyzer.test.generated.incremental_resolver_test;
 
-import 'package:analyzer/src/context/cache.dart' as task;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/incremental_logger.dart' as log;
@@ -19,11 +20,11 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:unittest/unittest.dart';
 
 import '../reflective_tests.dart';
-import 'parser_test.dart';
 import 'resolver_test.dart';
 import 'test_support.dart';
 
@@ -1545,6 +1546,34 @@
 ''');
   }
 
+  void test_false_method_getKeyword_add() {
+    _assertDoesNotMatchOK(
+        r'''
+class A {
+  void foo() {}
+}
+''',
+        r'''
+class A {
+  void get foo {}
+}
+''');
+  }
+
+  void test_false_method_getKeyword_remove() {
+    _assertDoesNotMatchOK(
+        r'''
+class A {
+  void get foo {}
+}
+''',
+        r'''
+class A {
+  void foo() {}
+}
+''');
+  }
+
   void test_false_method_list_add() {
     _assertDoesNotMatchOK(
         r'''
@@ -1639,6 +1668,34 @@
 ''');
   }
 
+  void test_false_method_setKeyword_add() {
+    _assertDoesNotMatchOK(
+        r'''
+class A {
+  void foo(x) {}
+}
+''',
+        r'''
+class A {
+  void set foo(x) {}
+}
+''');
+  }
+
+  void test_false_method_setKeyword_remove() {
+    _assertDoesNotMatchOK(
+        r'''
+class A {
+  void set foo(x) {}
+}
+''',
+        r'''
+class A {
+  void foo(x) {}
+}
+''');
+  }
+
   void test_false_part_list_add() {
     addNamedSource('/unitA.dart', 'part of lib; class A {}');
     addNamedSource('/unitB.dart', 'part of lib; class B {}');
@@ -3001,7 +3058,7 @@
     LibraryElement library = resolve2(source);
     CompilationUnit oldUnit = resolveCompilationUnit(source, library);
     // parse
-    CompilationUnit newUnit = ParserTestCase.parseCompilationUnit(newContent);
+    CompilationUnit newUnit = IncrementalResolverTest._parseUnit(newContent);
     // build elements
     {
       ElementHolder holder = new ElementHolder();
@@ -3024,22 +3081,12 @@
 
   @override
   void reset() {
-    if (AnalysisEngine.instance.useTaskModel) {
-      analysisContext2 = AnalysisContextFactory.contextWithCore();
-    } else {
-      analysisContext2 = AnalysisContextFactory.oldContextWithCore();
-    }
+    analysisContext2 = AnalysisContextFactory.contextWithCore();
   }
 
   @override
   void resetWithOptions(AnalysisOptions options) {
-    if (AnalysisEngine.instance.useTaskModel) {
-      analysisContext2 =
-          AnalysisContextFactory.contextWithCoreAndOptions(options);
-    } else {
-      analysisContext2 =
-          AnalysisContextFactory.oldContextWithCoreAndOptions(options);
-    }
+    AnalysisContextFactory.contextWithCoreAndOptions(options);
   }
 
   void setUp() {
@@ -3389,28 +3436,10 @@
     int updateEndOld = updateOffset + edit.length;
     int updateOldNew = updateOffset + edit.replacement.length;
     IncrementalResolver resolver;
-    if (AnalysisEngine.instance.useTaskModel) {
-      LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source);
-      task.AnalysisCache cache = analysisContext2.analysisCache;
-      resolver = new IncrementalResolver(
-          null,
-          cache.get(source),
-          cache.get(lsu),
-          unit.element,
-          updateOffset,
-          updateEndOld,
-          updateOldNew);
-    } else {
-      resolver = new IncrementalResolver(
-          (analysisContext2 as AnalysisContextImpl)
-              .getReadableSourceEntryOrNull(source),
-          null,
-          null,
-          unit.element,
-          updateOffset,
-          updateEndOld,
-          updateOldNew);
-    }
+    LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source);
+    AnalysisCache cache = analysisContext2.analysisCache;
+    resolver = new IncrementalResolver(cache.get(source), cache.get(lsu),
+        unit.element, updateOffset, updateEndOld, updateOldNew);
     bool success = resolver.resolve(newNode);
     expect(success, isTrue);
     List<AnalysisError> newErrors = analysisContext.computeErrors(source);
@@ -3519,17 +3548,10 @@
 
   @override
   void setUp() {
-    AnalysisEngine.instance.useTaskModel = true;
     super.setUp();
     _resetWithIncremental(true);
   }
 
-  @override
-  void tearDown() {
-    super.tearDown();
-    AnalysisEngine.instance.useTaskModel = false;
-  }
-
   void test_computeConstants() {
     _resolveUnit(r'''
 int f() => 0;
@@ -4023,6 +4045,27 @@
 ''');
   }
 
+  void test_inBody_functionExpression() {
+    _resolveUnit(r'''
+class C extends D {
+  static final f = () {
+    var x = 0;
+  }();
+}
+
+class D {}
+''');
+    _updateAndValidate(r'''
+class C extends D {
+  static final f = () {
+    var x = 01;
+  }();
+}
+
+class D {}
+''');
+  }
+
   void test_inBody_insertStatement() {
     _resolveUnit(r'''
 main() {
@@ -4460,6 +4503,45 @@
 ''');
   }
 
+  void test_updateErrors_invalidVerifyErrors() {
+    _resolveUnit(r'''
+main() {
+  foo('aaa');
+}
+main2() {
+  foo('bbb');
+}
+foo(int p) {}
+''');
+    // Complete analysis, e.g. compute VERIFY_ERRORS.
+    _runTasks();
+    // Invalidate VERIFY_ERRORS.
+    AnalysisCache cache = analysisContext2.analysisCache;
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    CacheEntry cacheEntry = cache.get(target);
+    expect(cacheEntry.getValue(VERIFY_ERRORS), hasLength(2));
+    cacheEntry.setState(VERIFY_ERRORS, CacheState.INVALID);
+    // Perform incremental resolution.
+    _resetWithIncremental(true);
+    analysisContext2.setContents(
+        source,
+        r'''
+main() {
+  foo(0);
+}
+main2() {
+  foo('bbb');
+}
+foo(int p) {}
+''');
+    // VERIFY_ERRORS is still invalid.
+    expect(cacheEntry.getState(VERIFY_ERRORS), CacheState.INVALID);
+    // Continue analysis - run tasks, so recompute VERIFY_ERRORS.
+    _runTasks();
+    expect(cacheEntry.getState(VERIFY_ERRORS), CacheState.VALID);
+    expect(cacheEntry.getValue(VERIFY_ERRORS), hasLength(1));
+  }
+
   void test_updateErrors_removeExisting_hint() {
     _resolveUnit(r'''
 int main() {
@@ -4522,6 +4604,47 @@
 ''');
   }
 
+  void test_visibleRange() {
+    _resolveUnit(r'''
+class Test {
+  method1(p1) {
+    var v1;
+    f1() {}
+    return 1;
+  }
+  method2(p2) {
+    var v2;
+    f2() {}
+    return 2;
+  }
+  method3(p3) {
+    var v3;
+    f3() {}
+    return 3;
+  }
+}
+''');
+    _updateAndValidate(r'''
+class Test {
+  method1(p1) {
+    var v1;
+    f1() {}
+    return 1;
+  }
+  method2(p2) {
+    var v2;
+    f2() {}
+    return 2222;
+  }
+  method3(p3) {
+    var v3;
+    f3() {}
+    return 3;
+  }
+}
+''');
+  }
+
   void test_whitespace_getElementAt() {
     _resolveUnit(r'''
 class A {}
@@ -4595,9 +4718,13 @@
   }
 
   void _updateAndValidate(String newCode,
-      {bool expectedSuccess: true, bool compareWithFull: true}) {
+      {bool expectedSuccess: true,
+      bool compareWithFull: true,
+      bool runTasksBeforeIncremental: true}) {
     // Run any pending tasks tasks.
-    _runTasks();
+    if (runTasksBeforeIncremental) {
+      _runTasks();
+    }
     // Update the source - currently this may cause incremental resolution.
     // Then request the updated resolved unit.
     _resetWithIncremental(true);
@@ -4613,7 +4740,8 @@
     // The existing CompilationUnit[Element] should be updated.
     expect(newUnit, same(oldUnit));
     expect(newUnit.element, same(oldUnitElement));
-    expect(analysisContext.parseCompilationUnit(source), same(oldUnit));
+    expect(analysisContext.getResolvedCompilationUnit(source, oldLibrary),
+        same(oldUnit));
     // The only expected pending task should return the same resolved
     // "newUnit", so all clients will get it using the usual way.
     AnalysisResult analysisResult = analysisContext.performAnalysisTask();
@@ -4622,6 +4750,7 @@
     // Resolve "newCode" from scratch.
     if (compareWithFull) {
       _resetWithIncremental(false);
+      changeSource(source, '');
       changeSource(source, newCode);
       _runTasks();
       LibraryElement library = resolve2(source);
diff --git a/pkg/analyzer/test/generated/incremental_scanner_test.dart b/pkg/analyzer/test/generated/incremental_scanner_test.dart
index 6b72aa6..fad6244 100644
--- a/pkg/analyzer/test/generated/incremental_scanner_test.dart
+++ b/pkg/analyzer/test/generated/incremental_scanner_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_scanner_test;
+library analyzer.test.generated.incremental_scanner_test;
 
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/incremental_scanner.dart';
diff --git a/pkg/analyzer/test/generated/java_core_test.dart b/pkg/analyzer/test/generated/java_core_test.dart
index e60e9c1..0a914ec 100644
--- a/pkg/analyzer/test/generated/java_core_test.dart
+++ b/pkg/analyzer/test/generated/java_core_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.java_core_test;
+library analyzer.test.generated.java_core_test;
 
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/generated/java_io_test.dart b/pkg/analyzer/test/generated/java_io_test.dart
index 2bd611d..0316817 100644
--- a/pkg/analyzer/test/generated/java_io_test.dart
+++ b/pkg/analyzer/test/generated/java_io_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.java_io_test;
+library analyzer.test.generated.java_io_test;
 
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 56aa853..6792467 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.non_error_resolver_test;
+library analyzer.test.generated.non_error_resolver_test;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
@@ -35,6 +35,24 @@
     verify([source]);
   }
 
+  void test_class_type_alias_documentationComment() {
+    Source source = addSource('''
+/**
+ * Documentation
+ */
+class C = D with E;
+
+class D {}
+class E {}''');
+    computeLibrarySourceErrors(source);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = _getResolvedLibraryUnit(source);
+    ClassElement classC = unit.element.getType('C');
+    expect(classC.documentationComment, isNotNull);
+  }
+
   void test_ambiguousExport() {
     Source source = addSource(r'''
 library L;
@@ -262,6 +280,82 @@
     verify([source]);
   }
 
+  void test_assert_with_message_await() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+import 'dart:async';
+f() async {
+  assert(false, await g());
+}
+Future<String> g() => null;
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_dynamic() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  assert(false, g());
+}
+g() => null;
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_non_string() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  assert(false, 3);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_null() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  assert(false, null);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_string() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  assert(false, 'message');
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_suppresses_unused_var_hint() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  String message = 'msg';
+  assert(true, message);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_assignability_function_expr_rettype_from_typedef_cls() {
     // In the code below, the type of (() => f()) has a return type which is
     // a class, and that class is inferred from the return type of the typedef
@@ -850,10 +944,9 @@
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "p]", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is ParameterElement,
-          ParameterElement, ref.staticElement);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, "p]");
+      expect(ref.staticElement, new isInstanceOf<ParameterElement>());
     }
   }
 
@@ -872,22 +965,22 @@
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "Samurai]", (node) => node is SimpleIdentifier);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'Samurai]');
       ClassElement refElement = ref.staticElement;
       expect(refElement, isNotNull);
       expect(refElement.name, 'Samurai');
     }
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "int]", (node) => node is SimpleIdentifier);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'int]');
       ClassElement refElement = ref.staticElement;
       expect(refElement, isNotNull);
       expect(refElement.name, 'int');
     }
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "WITH_SWORD]", (node) => node is SimpleIdentifier);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'WITH_SWORD]');
       PropertyAccessorElement refElement = ref.staticElement;
       expect(refElement, isNotNull);
       expect(refElement.name, 'WITH_SWORD');
@@ -904,10 +997,9 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
-    SimpleIdentifier ref = EngineTestCase.findNode(
-        unit, code, "p]", (node) => node is SimpleIdentifier);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is ParameterElement, ParameterElement, ref.staticElement);
+    SimpleIdentifier ref =
+        EngineTestCase.findSimpleIdentifier(unit, code, 'p]');
+    expect(ref.staticElement, new isInstanceOf<ParameterElement>());
   }
 
   void test_commentReference_beforeFunction_expressionBody() {
@@ -919,10 +1011,42 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
-    SimpleIdentifier ref = EngineTestCase.findNode(
-        unit, code, "p]", (node) => node is SimpleIdentifier);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is ParameterElement, ParameterElement, ref.staticElement);
+    SimpleIdentifier ref =
+        EngineTestCase.findSimpleIdentifier(unit, code, 'p]');
+    expect(ref.staticElement, new isInstanceOf<ParameterElement>());
+  }
+
+  void test_commentReference_beforeFunctionTypeAlias() {
+    String code = r'''
+/// [p]
+typedef Foo(int p);
+''';
+    Source source = addSource(code);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = _getResolvedLibraryUnit(source);
+    SimpleIdentifier ref =
+        EngineTestCase.findSimpleIdentifier(unit, code, 'p]');
+    expect(ref.staticElement, new isInstanceOf<ParameterElement>());
+  }
+
+  void test_commentReference_beforeGetter() {
+    String code = r'''
+abstract class A {
+  /// [int]
+  get g => null;
+}''';
+    Source source = addSource(code);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = _getResolvedLibraryUnit(source);
+    {
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'int]');
+      expect(ref.staticElement, isNotNull);
+    }
   }
 
   void test_commentReference_beforeMethod() {
@@ -932,24 +1056,27 @@
   ma(int p1) {}
   /// [p2]
   mb(int p2);
+  /// [p3] and [p4]
+  mc(int p3, p4());
+  /// [p5]
+  md(int p5, {int p6});
 }''';
     Source source = addSource(code);
     computeLibrarySourceErrors(source);
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
-    {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "p1]", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is ParameterElement,
-          ParameterElement, ref.staticElement);
+    assertIsParameter(String search) {
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, search);
+      expect(ref.staticElement, new isInstanceOf<ParameterElement>());
     }
-    {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "p2]", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is ParameterElement,
-          ParameterElement, ref.staticElement);
-    }
+    assertIsParameter('p1');
+    assertIsParameter('p2');
+    assertIsParameter('p3');
+    assertIsParameter('p4');
+    assertIsParameter('p5');
+    assertIsParameter('p6');
   }
 
   void test_commentReference_class() {
@@ -963,10 +1090,9 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
-    SimpleIdentifier ref = EngineTestCase.findNode(
-        unit, code, "foo]", (node) => node is SimpleIdentifier);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is MethodElement, MethodElement, ref.staticElement);
+    SimpleIdentifier ref =
+        EngineTestCase.findSimpleIdentifier(unit, code, 'foo]');
+    expect(ref.staticElement, new isInstanceOf<MethodElement>());
   }
 
   void test_commentReference_setter() {
@@ -987,16 +1113,14 @@
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "x] in A", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
-          PropertyAccessorElement, ref.staticElement);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, "x] in A");
+      expect(ref.staticElement, new isInstanceOf<PropertyAccessorElement>());
     }
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "x] in B", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
-          PropertyAccessorElement, ref.staticElement);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'x] in B');
+      expect(ref.staticElement, new isInstanceOf<PropertyAccessorElement>());
     }
   }
 
@@ -1356,6 +1480,19 @@
     verify([source]);
   }
 
+  void test_constWithNonConstantArgument_constField() {
+    Source source = addSource(r'''
+class A {
+  const A(x);
+}
+main() {
+  const A(double.INFINITY);
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_constWithNonConstantArgument_literals() {
     Source source = addSource(r'''
 class A {
@@ -3493,7 +3630,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_getter() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_getter() {
     Source source = addSource(r'''
 class A {
   int get g => 0;
@@ -3507,7 +3645,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_method() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_method() {
     Source source = addSource(r'''
 class A {
   m(p) {}
@@ -3521,7 +3660,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_setter() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_setter() {
     Source source = addSource(r'''
 class A {
   set s(v) {}
@@ -3535,7 +3675,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() {
     // 15979
     Source source = addSource(r'''
 abstract class M {}
@@ -3562,7 +3703,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() {
     // 15979
     Source source = addSource(r'''
 class M {}
@@ -3660,7 +3802,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_superclass() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_superclass() {
     Source source = addSource(r'''
 class A {
   noSuchMethod(v) => '';
@@ -3673,7 +3816,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_overridesMethodInObject() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_overridesMethodInObject() {
     Source source = addSource(r'''
 class A {
   String toString([String prefix = '']) => '${prefix}Hello';
@@ -3719,6 +3863,21 @@
     verify([source]);
   }
 
+  void test_nonBoolNegationExpression_dynamic() {
+    Source source = addSource(r'''
+f1(bool dynamic) {
+  !dynamic;
+}
+f2() {
+  bool dynamic = true;
+  !dynamic;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonBoolOperand_and_bool() {
     Source source = addSource(r'''
 bool f(bool left, bool right) {
@@ -3759,6 +3918,15 @@
     verify([source]);
   }
 
+  void test_nonConstantDefaultValue_constField() {
+    Source source = addSource(r'''
+f([a = double.INFINITY]) {
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonConstantDefaultValue_function_named() {
     Source source = addSource("f({x : 2 + 3}) {}");
     computeLibrarySourceErrors(source);
@@ -3813,6 +3981,19 @@
     verify([source]);
   }
 
+  void test_nonConstantDefaultValue_typedConstList() {
+    Source source = addSource(r'''
+class A {
+  m([p111 = const <String>[]]) {}
+}
+class B extends A {
+  m([p222 = const <String>[]]) {}
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonConstantValueInInitializer_namedArgument() {
     Source source = addSource(r'''
 class A {
@@ -3827,7 +4008,23 @@
     verify([source]);
   }
 
-  void test_nonConstCaseExpression() {
+  void test_nonConstCaseExpression_constField() {
+    Source source = addSource(r'''
+f(double p) {
+  switch (p) {
+    case double.INFINITY:
+      return true;
+    default:
+      return false;
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  void test_nonConstCaseExpression_typeLiteral() {
     Source source = addSource(r'''
 f(Type t) {
   switch (t) {
@@ -3843,6 +4040,16 @@
     verify([source]);
   }
 
+  void test_nonConstListElement_constField() {
+    Source source = addSource(r'''
+main() {
+  const [double.INFINITY];
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonConstMapAsExpressionStatement_const() {
     Source source = addSource(r'''
 f() {
@@ -3873,6 +4080,27 @@
     verify([source]);
   }
 
+  void test_nonConstMapKey_constField() {
+    Source source = addSource(r'''
+main() {
+  const {double.INFINITY: 0};
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  void test_nonConstMapValue_constField() {
+    Source source = addSource(r'''
+main() {
+  const {0: double.INFINITY};
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonConstValueInInitializer_binary_bool() {
     Source source = addSource(r'''
 class A {
@@ -4888,7 +5116,8 @@
     verify([source]);
   }
 
-  void test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() {
+  void
+      test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
@@ -4925,7 +5154,8 @@
     verify([source]);
   }
 
-  void test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() {
+  void
+      test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 51e4941..5d304c7 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2,10 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.parser_test;
+library analyzer.test.generated.parser_test;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/incremental_scanner.dart';
@@ -16,7 +18,7 @@
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:unittest/unittest.dart';
+import 'package:unittest/unittest.dart' hide Configuration;
 
 import '../reflective_tests.dart';
 import '../utils.dart';
@@ -204,45 +206,16 @@
     expect(argumentList4.arguments, hasLength(1));
   }
 
+  void test_assignableExpression_arguments_normal_chain_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    _validate_assignableExpression_arguments_normal_chain_typeArguments(
+        "a/*<E>*/(b)/*<F>*/(c).d/*<G>*/(e).f");
+  }
+
   void test_assignableExpression_arguments_normal_chain_typeArguments() {
     enableGenericMethods = true;
-    PropertyAccess propertyAccess1 = parseExpression("a<E>(b)<F>(c).d<G>(e).f");
-    expect(propertyAccess1.propertyName.name, "f");
-    //
-    // a<E>(b)<F>(c).d>G?(e)
-    //
-    MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(
-        (obj) => obj is MethodInvocation,
-        MethodInvocation,
-        propertyAccess1.target);
-    expect(invocation2.methodName.name, "d");
-    expect(invocation2.typeArguments, isNotNull);
-    ArgumentList argumentList2 = invocation2.argumentList;
-    expect(argumentList2, isNotNull);
-    expect(argumentList2.arguments, hasLength(1));
-    //
-    // a<E>(b)<F>(c)
-    //
-    FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
-        (obj) => obj is FunctionExpressionInvocation,
-        FunctionExpressionInvocation,
-        invocation2.target);
-    expect(invocation3.typeArguments, isNotNull);
-    ArgumentList argumentList3 = invocation3.argumentList;
-    expect(argumentList3, isNotNull);
-    expect(argumentList3.arguments, hasLength(1));
-    //
-    // a(b)
-    //
-    MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(
-        (obj) => obj is MethodInvocation,
-        MethodInvocation,
-        invocation3.function);
-    expect(invocation4.methodName.name, "a");
-    expect(invocation4.typeArguments, isNotNull);
-    ArgumentList argumentList4 = invocation4.argumentList;
-    expect(argumentList4, isNotNull);
-    expect(argumentList4.arguments, hasLength(1));
+    _validate_assignableExpression_arguments_normal_chain_typeArguments(
+        "a<E>(b)<F>(c).d<G>(e).f");
   }
 
   void test_assignmentExpression_compound() {
@@ -529,6 +502,47 @@
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
+
+  void _validate_assignableExpression_arguments_normal_chain_typeArguments(
+      String code) {
+    PropertyAccess propertyAccess1 = parseExpression(code);
+    expect(propertyAccess1.propertyName.name, "f");
+    //
+    // a<E>(b)<F>(c).d<G>(e)
+    //
+    MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation,
+        MethodInvocation,
+        propertyAccess1.target);
+    expect(invocation2.methodName.name, "d");
+    expect(invocation2.typeArguments, isNotNull);
+    ArgumentList argumentList2 = invocation2.argumentList;
+    expect(argumentList2, isNotNull);
+    expect(argumentList2.arguments, hasLength(1));
+    //
+    // a<E>(b)<F>(c)
+    //
+    FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
+        (obj) => obj is FunctionExpressionInvocation,
+        FunctionExpressionInvocation,
+        invocation2.target);
+    expect(invocation3.typeArguments, isNotNull);
+    ArgumentList argumentList3 = invocation3.argumentList;
+    expect(argumentList3, isNotNull);
+    expect(argumentList3.arguments, hasLength(1));
+    //
+    // a(b)
+    //
+    MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation,
+        MethodInvocation,
+        invocation3.function);
+    expect(invocation4.methodName.name, "a");
+    expect(invocation4.typeArguments, isNotNull);
+    ArgumentList argumentList4 = invocation4.argumentList;
+    expect(argumentList4, isNotNull);
+    expect(argumentList4.arguments, hasLength(1));
+  }
 }
 
 /**
@@ -923,6 +937,18 @@
         [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]);
   }
 
+  void test_enableAsync_false_1() {
+    parseAsync = false;
+    parse4("parseFunctionDeclarationStatement",
+        "foo() async {}", [ParserErrorCode.ASYNC_NOT_SUPPORTED]);
+  }
+
+  void test_enableAsync_false_2() {
+    parseAsync = false;
+    parse4("parseFunctionDeclarationStatement",
+        "foo() sync* {}", [ParserErrorCode.ASYNC_NOT_SUPPORTED]);
+  }
+
   void test_emptyEnumBody() {
     parse3("parseEnumDeclaration", <Object>[emptyCommentAndMetadata()],
         "enum E {}", [ParserErrorCode.EMPTY_ENUM_BODY]);
@@ -1058,8 +1084,8 @@
   }
 
   void test_expectedToken_whileMissingInDoStatement() {
-    ParserTestCase.parseStatement(
-        "do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]);
+    ParserTestCase
+        .parseStatement("do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_expectedTypeName_is() {
@@ -1241,8 +1267,8 @@
   }
 
   void test_getterInFunction_expression_noReturnType() {
-    ParserTestCase.parseStatement(
-        "get x => _x;", [ParserErrorCode.GETTER_IN_FUNCTION]);
+    ParserTestCase
+        .parseStatement("get x => _x;", [ParserErrorCode.GETTER_IN_FUNCTION]);
   }
 
   void test_getterInFunction_expression_returnType() {
@@ -1332,6 +1358,11 @@
     parse4("parseStringLiteral", "'\$1'", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
+  void test_invalidLiteralInConfiguration() {
+    parse4("parseConfiguration", "if (a == 'x \$y z') 'a.dart'",
+        [ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION]);
+  }
+
   void test_invalidOperator() {
     parse3("parseClassMember", <Object>["C"], "void operator ===(x) {}",
         [ParserErrorCode.INVALID_OPERATOR]);
@@ -1426,6 +1457,44 @@
         "static f() {}", [ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER]);
   }
 
+  void test_method_invalidTypeParameterComments() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method = parse3(
+        "parseClassMember",
+        <Object>["C"],
+        "void m/*<E, hello!>*/() {}",
+        [
+          ParserErrorCode.EXPECTED_TOKEN /*>*/,
+          ParserErrorCode.MISSING_IDENTIFIER,
+          ParserErrorCode.EXPECTED_TOKEN /*(*/,
+          ParserErrorCode.EXPECTED_TOKEN /*)*/,
+          ParserErrorCode.MISSING_FUNCTION_BODY
+        ]);
+    expect(method.typeParameters.toString(), '<E, hello>',
+        reason: 'parser recovers what it can');
+  }
+
+  void test_method_invalidTypeParameters() {
+    // TODO(jmesserly): ideally we'd be better at parser recovery here.
+    // It doesn't try to advance past the invalid token `!` to find the
+    // valid `>`. If it did we'd get less cascading errors, at least for this
+    // particular example.
+    enableGenericMethods = true;
+    MethodDeclaration method = parse3(
+        "parseClassMember",
+        <Object>["C"],
+        "void m<E, hello!>() {}",
+        [
+          ParserErrorCode.EXPECTED_TOKEN /*>*/,
+          ParserErrorCode.MISSING_IDENTIFIER,
+          ParserErrorCode.EXPECTED_TOKEN /*(*/,
+          ParserErrorCode.EXPECTED_TOKEN /*)*/,
+          ParserErrorCode.MISSING_FUNCTION_BODY
+        ]);
+    expect(method.typeParameters.toString(), '<E, hello>',
+        reason: 'parser recovers what it can');
+  }
+
   void test_missingAssignableSelector_identifiersAssigned() {
     parseExpression("x.y = y;");
   }
@@ -1907,9 +1976,9 @@
         "parseSwitchStatement",
         "switch (a) {default: return 0; default: return 1; default: return 2;}",
         [
-      ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES,
-      ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES
-    ]);
+          ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES,
+          ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES
+        ]);
   }
 
   void test_topLevel_getter() {
@@ -1999,10 +2068,10 @@
 void main() {
   var x = "''',
         [
-      ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
-      ParserErrorCode.EXPECTED_TOKEN,
-      ParserErrorCode.EXPECTED_TOKEN
-    ]);
+          ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN
+        ]);
   }
 
   void test_unterminatedString_at_eol() {
@@ -2028,10 +2097,10 @@
 void main() {
   var x = """''',
         [
-      ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
-      ParserErrorCode.EXPECTED_TOKEN,
-      ParserErrorCode.EXPECTED_TOKEN
-    ]);
+          ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN
+        ]);
   }
 
   void test_unterminatedString_multiline_at_eof_4_quotes() {
@@ -2043,10 +2112,10 @@
 void main() {
   var x = """"''',
         [
-      ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
-      ParserErrorCode.EXPECTED_TOKEN,
-      ParserErrorCode.EXPECTED_TOKEN
-    ]);
+          ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN
+        ]);
   }
 
   void test_unterminatedString_multiline_at_eof_5_quotes() {
@@ -2058,10 +2127,10 @@
 void main() {
   var x = """""''',
         [
-      ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
-      ParserErrorCode.EXPECTED_TOKEN,
-      ParserErrorCode.EXPECTED_TOKEN
-    ]);
+          ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN
+        ]);
   }
 
   void test_useOfUnaryPlusOperator() {
@@ -2078,8 +2147,8 @@
   }
 
   void test_varAndType_topLevelVariable() {
-    ParserTestCase.parseCompilationUnit(
-        "var int x;", [ParserErrorCode.VAR_AND_TYPE]);
+    ParserTestCase
+        .parseCompilationUnit("var int x;", [ParserErrorCode.VAR_AND_TYPE]);
   }
 
   void test_varAsTypeName_as() {
@@ -2087,13 +2156,13 @@
   }
 
   void test_varClass() {
-    ParserTestCase.parseCompilationUnit(
-        "var class C {}", [ParserErrorCode.VAR_CLASS]);
+    ParserTestCase
+        .parseCompilationUnit("var class C {}", [ParserErrorCode.VAR_CLASS]);
   }
 
   void test_varEnum() {
-    ParserTestCase.parseCompilationUnit(
-        "var enum E {ONE}", [ParserErrorCode.VAR_ENUM]);
+    ParserTestCase
+        .parseCompilationUnit("var enum E {ONE}", [ParserErrorCode.VAR_ENUM]);
   }
 
   void test_varReturnType() {
@@ -2122,13 +2191,13 @@
   }
 
   void test_voidVariable_parseCompilationUnit_initializer() {
-    ParserTestCase.parseCompilationUnit(
-        "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase
+        .parseCompilationUnit("void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
   }
 
   void test_voidVariable_parseCompilationUnit_noInitializer() {
-    ParserTestCase.parseCompilationUnit(
-        "void x;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase
+        .parseCompilationUnit("void x;", [ParserErrorCode.VOID_VARIABLE]);
   }
 
   void test_voidVariable_parseCompilationUnitMember_initializer() {
@@ -2590,12 +2659,28 @@
   static bool parseFunctionBodies = true;
 
   /**
+   * A flag indicating whether parser is to parse async.
+   */
+  bool parseAsync = true;
+
+  /**
+   * A flag indicating whether conditional directives support should be enabled
+   * for a specific test.
+   */
+  bool enableConditionalDirectives = false;
+
+  /**
    * A flag indicating whether generic method support should be enabled for a
    * specific test.
    */
   bool enableGenericMethods = false;
 
   /**
+   * Whether generic method comments should be enabled for the test.
+   */
+  bool enableGenericMethodComments = false;
+
+  /**
    * Return a CommentAndMetadata object with the given values that can be used for testing.
    *
    * @param comment the comment to be wrapped in the object
@@ -2638,13 +2723,17 @@
     //
     Scanner scanner =
         new Scanner(null, new CharSequenceReader(source), listener);
+    scanner.scanGenericMethodComments = enableGenericMethodComments;
     Token tokenStream = scanner.tokenize();
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     //
     // Parse the source.
     //
     Parser parser = createParser(listener);
+    parser.parseAsync = parseAsync;
+    parser.parseConditionalDirectives = enableConditionalDirectives;
     parser.parseGenericMethods = enableGenericMethods;
+    parser.parseGenericMethodComments = enableGenericMethodComments;
     parser.parseFunctionBodies = parseFunctionBodies;
     Object result =
         invokeParserMethodImpl(parser, methodName, objects, tokenStream);
@@ -2772,10 +2861,12 @@
     GatheringErrorListener listener = new GatheringErrorListener();
     Scanner scanner =
         new Scanner(null, new CharSequenceReader(source), listener);
+    scanner.scanGenericMethodComments = enableGenericMethodComments;
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Token token = scanner.tokenize();
     Parser parser = createParser(listener);
     parser.parseGenericMethods = enableGenericMethods;
+    parser.parseGenericMethodComments = enableGenericMethodComments;
     Expression expression = parser.parseExpression(token);
     expect(expression, isNotNull);
     listener.assertErrorsWithCodes(errorCodes);
@@ -3412,8 +3503,8 @@
   }
 
   void test_incomplete_topLevelVariable() {
-    CompilationUnit unit = ParserTestCase.parseCompilationUnit(
-        "String", [ParserErrorCode.EXPECTED_EXECUTABLE]);
+    CompilationUnit unit = ParserTestCase
+        .parseCompilationUnit("String", [ParserErrorCode.EXPECTED_EXECUTABLE]);
     NodeList<CompilationUnitMember> declarations = unit.declarations;
     expect(declarations, hasLength(1));
     CompilationUnitMember member = declarations[0];
@@ -3562,8 +3653,8 @@
   }
 
   void test_incompleteLocalVariable_atTheEndOfBlock() {
-    Statement statement = ParserTestCase.parseStatement(
-        'String v }', [ParserErrorCode.EXPECTED_TOKEN]);
+    Statement statement = ParserTestCase
+        .parseStatement('String v }', [ParserErrorCode.EXPECTED_TOKEN]);
     expect(statement, new isInstanceOf<VariableDeclarationStatement>());
     expect(statement.toSource(), 'String v;');
   }
@@ -3583,15 +3674,15 @@
   }
 
   void test_incompleteLocalVariable_beforeNextBlock() {
-    Statement statement = ParserTestCase.parseStatement(
-        'String v {}', [ParserErrorCode.EXPECTED_TOKEN]);
+    Statement statement = ParserTestCase
+        .parseStatement('String v {}', [ParserErrorCode.EXPECTED_TOKEN]);
     expect(statement, new isInstanceOf<VariableDeclarationStatement>());
     expect(statement.toSource(), 'String v;');
   }
 
   void test_incompleteLocalVariable_parameterizedType() {
-    Statement statement = ParserTestCase.parseStatement(
-        'List<String> v {}', [ParserErrorCode.EXPECTED_TOKEN]);
+    Statement statement = ParserTestCase
+        .parseStatement('List<String> v {}', [ParserErrorCode.EXPECTED_TOKEN]);
     expect(statement, new isInstanceOf<VariableDeclarationStatement>());
     expect(statement.toSource(), 'List<String> v;');
   }
@@ -4641,6 +4732,13 @@
     expect(identifier.offset, 5);
   }
 
+  void fail_parseStatement_functionDeclaration_noReturnType_typeParameters() {
+    enableGenericMethods = true;
+    FunctionDeclarationStatement statement =
+        parse4("parseStatement", "f<E>(a, b) {};");
+    expect(statement.functionDeclaration, isNotNull);
+  }
+
   void test_computeStringValue_emptyInterpolationPrefix() {
     expect(_computeStringValue("'''", true, false), "");
   }
@@ -4739,28 +4837,34 @@
     ParserTestCase.parseCompilationUnit("var x = () {};");
   }
 
-  void test_function_literal_allowed_in_ArgumentList_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_ArgumentList_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = f(() {}); }");
   }
 
-  void test_function_literal_allowed_in_IndexExpression_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_IndexExpression_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = x[() {}]; }");
   }
 
-  void test_function_literal_allowed_in_ListLiteral_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_ListLiteral_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = [() {}]; }");
   }
 
-  void test_function_literal_allowed_in_MapLiteral_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_MapLiteral_in_ConstructorFieldInitializer() {
     ParserTestCase
         .parseCompilationUnit("class C { C() : a = {'key': () {}}; }");
   }
 
-  void test_function_literal_allowed_in_ParenthesizedExpression_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_ParenthesizedExpression_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = (() {}); }");
   }
 
-  void test_function_literal_allowed_in_StringInterpolation_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_StringInterpolation_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = \"\${(){}}\"; }");
   }
 
@@ -5092,6 +5196,36 @@
     expect(statement.assertKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.condition, isNotNull);
+    expect(statement.comma, isNull);
+    expect(statement.message, isNull);
+    expect(statement.rightParenthesis, isNotNull);
+    expect(statement.semicolon, isNotNull);
+  }
+
+  void test_parseAssertStatement_messageLowPrecedence() {
+    // Using a throw expression as an assert message would be silly in
+    // practice, but it's the lowest precedence expression type, so verifying
+    // that it works should give us high confidence that other expression types
+    // will work as well.
+    AssertStatement statement =
+        parse4('parseAssertStatement', 'assert (x, throw "foo");');
+    expect(statement.assertKeyword, isNotNull);
+    expect(statement.leftParenthesis, isNotNull);
+    expect(statement.condition, isNotNull);
+    expect(statement.comma, isNotNull);
+    expect(statement.message, isNotNull);
+    expect(statement.rightParenthesis, isNotNull);
+    expect(statement.semicolon, isNotNull);
+  }
+
+  void test_parseAssertStatement_messageString() {
+    AssertStatement statement =
+        parse4('parseAssertStatement', 'assert (x, "foo");');
+    expect(statement.assertKeyword, isNotNull);
+    expect(statement.leftParenthesis, isNotNull);
+    expect(statement.condition, isNotNull);
+    expect(statement.comma, isNotNull);
+    expect(statement.message, isNotNull);
     expect(statement.rightParenthesis, isNotNull);
     expect(statement.semicolon, isNotNull);
   }
@@ -5110,6 +5244,22 @@
     expect(propertyAccess.propertyName, isNotNull);
   }
 
+  void
+      test_parseAssignableExpression_expression_args_dot_typeParameterComments() {
+    enableGenericMethodComments = true;
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "(x)/*<F>*/(y).z");
+    FunctionExpressionInvocation invocation =
+        propertyAccess.target as FunctionExpressionInvocation;
+    expect(invocation.function, isNotNull);
+    expect(invocation.typeArguments, isNotNull);
+    ArgumentList argumentList = invocation.argumentList;
+    expect(argumentList, isNotNull);
+    expect(argumentList.arguments, hasLength(1));
+    expect(propertyAccess.operator, isNotNull);
+    expect(propertyAccess.propertyName, isNotNull);
+  }
+
   void test_parseAssignableExpression_expression_args_dot_typeParameters() {
     enableGenericMethods = true;
     PropertyAccess propertyAccess =
@@ -5169,6 +5319,21 @@
     expect(propertyAccess.propertyName, isNotNull);
   }
 
+  void
+      test_parseAssignableExpression_identifier_args_dot_typeParameterComments() {
+    enableGenericMethodComments = true;
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "x/*<E>*/(y).z");
+    MethodInvocation invocation = propertyAccess.target as MethodInvocation;
+    expect(invocation.methodName.name, "x");
+    expect(invocation.typeArguments, isNotNull);
+    ArgumentList argumentList = invocation.argumentList;
+    expect(argumentList, isNotNull);
+    expect(argumentList.arguments, hasLength(1));
+    expect(propertyAccess.operator, isNotNull);
+    expect(propertyAccess.propertyName, isNotNull);
+  }
+
   void test_parseAssignableExpression_identifier_args_dot_typeParameters() {
     enableGenericMethods = true;
     PropertyAccess propertyAccess =
@@ -5391,6 +5556,16 @@
     expect(section.argumentList, isNotNull);
   }
 
+  void test_parseCascadeSection_ia_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    FunctionExpressionInvocation section =
+        parse4("parseCascadeSection", "..[i]/*<E>*/(b)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is IndexExpression, IndexExpression, section.function);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+  }
+
   void test_parseCascadeSection_ia_typeArguments() {
     enableGenericMethods = true;
     FunctionExpressionInvocation section =
@@ -5412,6 +5587,19 @@
     expect(section.argumentList.arguments, hasLength(1));
   }
 
+  void test_parseCascadeSection_ii_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation section =
+        parse4("parseCascadeSection", "..a/*<E>*/(b).c/*<F>*/(d)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation, section.target);
+    expect(section.operator, isNotNull);
+    expect(section.methodName, isNotNull);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
   void test_parseCascadeSection_ii_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation section =
@@ -5450,6 +5638,17 @@
         (obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
   }
 
+  void test_parseCascadeSection_p_assign_withCascade_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    AssignmentExpression section =
+        parse4("parseCascadeSection", "..a = 3..m/*<E>*/()");
+    expect(section.leftHandSide, isNotNull);
+    expect(section.operator, isNotNull);
+    Expression rhs = section.rightHandSide;
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
+  }
+
   void test_parseCascadeSection_p_assign_withCascade_typeArguments() {
     enableGenericMethods = true;
     AssignmentExpression section =
@@ -5478,6 +5677,17 @@
     expect(section.argumentList.arguments, hasLength(1));
   }
 
+  void test_parseCascadeSection_pa_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation section = parse4("parseCascadeSection", "..a/*<E>*/(b)");
+    expect(section.target, isNull);
+    expect(section.operator, isNotNull);
+    expect(section.methodName, isNotNull);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
   void test_parseCascadeSection_pa_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation section = parse4("parseCascadeSection", "..a<E>(b)");
@@ -5499,6 +5709,17 @@
     expect(section.argumentList.arguments, hasLength(1));
   }
 
+  void test_parseCascadeSection_paa_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    FunctionExpressionInvocation section =
+        parse4("parseCascadeSection", "..a/*<E>*/(b)/*<F>*/(c)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
   void test_parseCascadeSection_paa_typeArguments() {
     enableGenericMethods = true;
     FunctionExpressionInvocation section =
@@ -5520,6 +5741,17 @@
     expect(section.argumentList.arguments, hasLength(1));
   }
 
+  void test_parseCascadeSection_paapaa_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    FunctionExpressionInvocation section = parse4(
+        "parseCascadeSection", "..a/*<E>*/(b)/*<F>*/(c).d/*<G>*/(e)/*<H>*/(f)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+    expect(section.typeArguments, isNotNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
   void test_parseCascadeSection_paapaa_typeArguments() {
     enableGenericMethods = true;
     FunctionExpressionInvocation section =
@@ -5538,6 +5770,14 @@
     expect(section.propertyName, isNotNull);
   }
 
+  void test_parseCascadeSection_pap_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    PropertyAccess section = parse4("parseCascadeSection", "..a/*<E>*/(b).c");
+    expect(section.target, isNotNull);
+    expect(section.operator, isNotNull);
+    expect(section.propertyName, isNotNull);
+  }
+
   void test_parseCascadeSection_pap_typeArguments() {
     enableGenericMethods = true;
     PropertyAccess section = parse4("parseCascadeSection", "..a<E>(b).c");
@@ -5867,6 +6107,74 @@
     expect(method.returnType, isNotNull);
   }
 
+  void test_parseClassMember_method_generic_comment_noReturnType() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "m/*<T>*/() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType, isNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_comment_returnType() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "/*=T*/ m/*<T>*/() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType.name.name, 'T');
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_comment_returnType_bound() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method = parse("parseClassMember", <Object>["C"],
+        "num/*=T*/ m/*<T extends num>*/() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType.name.name, 'T');
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    TypeParameter tp = method.typeParameters.typeParameters[0];
+    expect(tp.name.name, 'T');
+    expect(tp.extendsKeyword, isNotNull);
+    expect(tp.bound.name.name, 'num');
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_comment_void() {
+    enableGenericMethodComments = true;
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "void m/*<T>*/() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType, isNotNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
   void test_parseClassMember_method_generic_noReturnType() {
     enableGenericMethods = true;
     MethodDeclaration method =
@@ -6474,6 +6782,28 @@
     expect(reference.offset, 35);
   }
 
+  void test_parseCommentReferences_skipCodeBlock_4spaces_block() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(TokenType.MULTI_LINE_COMMENT,
+          "/**\n *     a[i]\n * non-code line\n */", 3)
+    ];
+    List<CommentReference> references =
+        parse("parseCommentReferences", <Object>[tokens], "");
+    expect(references, isEmpty);
+  }
+
+  void test_parseCommentReferences_skipCodeBlock_4spaces_lines() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(
+          TokenType.SINGLE_LINE_COMMENT, "/// Code block:", 0),
+      new DocumentationCommentToken(
+          TokenType.SINGLE_LINE_COMMENT, "///     a[i] == b[i]", 0)
+    ];
+    List<CommentReference> references =
+        parse("parseCommentReferences", <Object>[tokens], "");
+    expect(references, isEmpty);
+  }
+
   void test_parseCommentReferences_skipCodeBlock_bracketed() {
     List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
       new DocumentationCommentToken(
@@ -6488,6 +6818,30 @@
     expect(reference.offset, 24);
   }
 
+  void test_parseCommentReferences_skipCodeBlock_gitHub() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(
+          TokenType.MULTI_LINE_COMMENT, "/** `a[i]` and [b] */", 0)
+    ];
+    List<CommentReference> references =
+        parse("parseCommentReferences", <Object>[tokens], "");
+    expect(references, hasLength(1));
+    CommentReference reference = references[0];
+    expect(reference, isNotNull);
+    expect(reference.identifier, isNotNull);
+    expect(reference.offset, 16);
+  }
+
+  void test_parseCommentReferences_skipCodeBlock_gitHub_notTerminated() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(
+          TokenType.MULTI_LINE_COMMENT, "/** `a[i] and [b] */", 0)
+    ];
+    List<CommentReference> references =
+        parse("parseCommentReferences", <Object>[tokens], "");
+    expect(references, hasLength(2));
+  }
+
   void test_parseCommentReferences_skipCodeBlock_spaces() {
     List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
       new DocumentationCommentToken(TokenType.MULTI_LINE_COMMENT,
@@ -6702,6 +7056,30 @@
     expect(declaration.propertyKeyword, isNull);
   }
 
+  void test_parseCompilationUnitMember_function_generic_noReturnType() {
+    enableGenericMethods = true;
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "f<E>() {}");
+    expect(declaration.returnType, isNull);
+    expect(declaration.functionExpression.typeParameters, isNotNull);
+  }
+
+  void test_parseCompilationUnitMember_function_generic_returnType() {
+    enableGenericMethods = true;
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "E f<E>() {}");
+    expect(declaration.returnType, isNotNull);
+    expect(declaration.functionExpression.typeParameters, isNotNull);
+  }
+
+  void test_parseCompilationUnitMember_function_generic_void() {
+    enableGenericMethods = true;
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "void f<T>(T t) {}");
+    expect(declaration.functionExpression, isNotNull);
+    expect(declaration.propertyKeyword, isNull);
+  }
+
   void test_parseCompilationUnitMember_function_noType() {
     FunctionDeclaration declaration = parse("parseCompilationUnitMember",
         <Object>[emptyCommentAndMetadata()], "f() {}");
@@ -6887,6 +7265,54 @@
     expect(expression.elseExpression, isNotNull);
   }
 
+  void test_parseConfiguration_noOperator_dottedIdentifier() {
+    Configuration configuration =
+        parse4('parseConfiguration', "if (a.b) 'c.dart'");
+    expect(configuration.ifKeyword, isNotNull);
+    expect(configuration.leftParenthesis, isNotNull);
+    _expectDottedName(configuration.name, ["a", "b"]);
+    expect(configuration.equalToken, isNull);
+    expect(configuration.value, isNull);
+    expect(configuration.rightParenthesis, isNotNull);
+    expect(configuration.libraryUri, isNotNull);
+  }
+
+  void test_parseConfiguration_noOperator_simpleIdentifier() {
+    Configuration configuration =
+        parse4('parseConfiguration', "if (a) 'b.dart'");
+    expect(configuration.ifKeyword, isNotNull);
+    expect(configuration.leftParenthesis, isNotNull);
+    _expectDottedName(configuration.name, ["a"]);
+    expect(configuration.equalToken, isNull);
+    expect(configuration.value, isNull);
+    expect(configuration.rightParenthesis, isNotNull);
+    expect(configuration.libraryUri, isNotNull);
+  }
+
+  void test_parseConfiguration_operator_dottedIdentifier() {
+    Configuration configuration =
+        parse4('parseConfiguration', "if (a.b == 'c') 'd.dart'");
+    expect(configuration.ifKeyword, isNotNull);
+    expect(configuration.leftParenthesis, isNotNull);
+    _expectDottedName(configuration.name, ["a", "b"]);
+    expect(configuration.equalToken, isNotNull);
+    expect(configuration.value, isNotNull);
+    expect(configuration.rightParenthesis, isNotNull);
+    expect(configuration.libraryUri, isNotNull);
+  }
+
+  void test_parseConfiguration_operator_simpleIdentifier() {
+    Configuration configuration =
+        parse4('parseConfiguration', "if (a == 'b') 'c.dart'");
+    expect(configuration.ifKeyword, isNotNull);
+    expect(configuration.leftParenthesis, isNotNull);
+    _expectDottedName(configuration.name, ["a"]);
+    expect(configuration.equalToken, isNotNull);
+    expect(configuration.value, isNotNull);
+    expect(configuration.rightParenthesis, isNotNull);
+    expect(configuration.libraryUri, isNotNull);
+  }
+
   void test_parseConstExpression_instanceCreation() {
     InstanceCreationExpression expression =
         parse4("parseConstExpression", "const A()");
@@ -7152,6 +7578,16 @@
     expect(statement.semicolon, isNotNull);
   }
 
+  void test_parseDottedName_multiple() {
+    DottedName name = parse4("parseDottedName", "a.b.c");
+    _expectDottedName(name, ["a", "b", "c"]);
+  }
+
+  void test_parseDottedName_single() {
+    DottedName name = parse4("parseDottedName", "a");
+    _expectDottedName(name, ["a"]);
+  }
+
   void test_parseEmptyStatement() {
     EmptyStatement statement = parse4("parseEmptyStatement", ";");
     expect(statement.semicolon, isNotNull);
@@ -7208,6 +7644,35 @@
     expect(expression.rightOperand, isNotNull);
   }
 
+  void test_parseExportDirective_configuration_multiple() {
+    enableConditionalDirectives = true;
+    ExportDirective directive = parse(
+        "parseExportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "export 'lib/lib.dart' if (a) 'b.dart' if (c) 'd.dart';");
+    expect(directive.keyword, isNotNull);
+    expect(directive.uri, isNotNull);
+    expect(directive.configurations, hasLength(2));
+    _expectDottedName(directive.configurations[0].name, ['a']);
+    _expectDottedName(directive.configurations[1].name, ['c']);
+    expect(directive.combinators, hasLength(0));
+    expect(directive.semicolon, isNotNull);
+  }
+
+  void test_parseExportDirective_configuration_single() {
+    enableConditionalDirectives = true;
+    ExportDirective directive = parse(
+        "parseExportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "export 'lib/lib.dart' if (a.b == 'c.dart') '';");
+    expect(directive.keyword, isNotNull);
+    expect(directive.uri, isNotNull);
+    expect(directive.configurations, hasLength(1));
+    _expectDottedName(directive.configurations[0].name, ['a', 'b']);
+    expect(directive.combinators, hasLength(0));
+    expect(directive.semicolon, isNotNull);
+  }
+
   void test_parseExportDirective_hide() {
     ExportDirective directive = parse(
         "parseExportDirective",
@@ -7339,6 +7804,15 @@
     expect(invocation.argumentList, isNotNull);
   }
 
+  void test_parseExpression_superMethodInvocation_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation invocation = parse4("parseExpression", "super.m/*<E>*/()");
+    expect(invocation.target, isNotNull);
+    expect(invocation.methodName, isNotNull);
+    expect(invocation.typeArguments, isNotNull);
+    expect(invocation.argumentList, isNotNull);
+  }
+
   void test_parseExpression_superMethodInvocation_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation invocation = parse4("parseExpression", "super.m<E>()");
@@ -7386,7 +7860,19 @@
     expect(invocation.argumentList, isNotNull);
   }
 
-  void test_parseExpressionWithoutCascade_superMethodInvocation_typeArguments() {
+  void
+      test_parseExpressionWithoutCascade_superMethodInvocation_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation invocation =
+        parse4("parseExpressionWithoutCascade", "super.m/*<E>*/()");
+    expect(invocation.target, isNotNull);
+    expect(invocation.methodName, isNotNull);
+    expect(invocation.typeArguments, isNotNull);
+    expect(invocation.argumentList, isNotNull);
+  }
+
+  void
+      test_parseExpressionWithoutCascade_superMethodInvocation_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation invocation =
         parse4("parseExpressionWithoutCascade", "super.m<E>()");
@@ -8148,6 +8634,25 @@
     expect(declaration.propertyKeyword, isNull);
   }
 
+  void test_parseFunctionDeclaration_functionWithTypeParameters_comment() {
+    enableGenericMethodComments = true;
+    Comment comment = Comment.createDocumentationComment(new List<Token>(0));
+    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    FunctionDeclaration declaration = parse(
+        "parseFunctionDeclaration",
+        <Object>[commentAndMetadata(comment), null, returnType],
+        "f/*<E>*/() {}");
+    expect(declaration.documentationComment, comment);
+    expect(declaration.returnType, returnType);
+    expect(declaration.name, isNotNull);
+    FunctionExpression expression = declaration.functionExpression;
+    expect(expression, isNotNull);
+    expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNotNull);
+    expect(expression.parameters, isNotNull);
+    expect(declaration.propertyKeyword, isNull);
+  }
+
   void test_parseFunctionDeclaration_getter() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
@@ -8186,11 +8691,26 @@
     expect(statement.functionDeclaration, isNotNull);
   }
 
+  void test_parseFunctionDeclarationStatement_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionDeclarationStatement statement = parse4(
+        "parseFunctionDeclarationStatement",
+        "/*=E*/ f/*<E>*/(/*=E*/ p) => p * 2;");
+    FunctionDeclaration f = statement.functionDeclaration;
+    expect(f, isNotNull);
+    expect(f.functionExpression.typeParameters, isNotNull);
+    expect(f.returnType, isNotNull);
+    SimpleFormalParameter p = f.functionExpression.parameters.parameters[0];
+    expect(p.type, isNotNull);
+  }
+
   void test_parseFunctionDeclarationStatement_typeParameters() {
     enableGenericMethods = true;
     FunctionDeclarationStatement statement =
         parse4("parseFunctionDeclarationStatement", "E f<E>(E p) => p * 2;");
     expect(statement.functionDeclaration, isNotNull);
+    expect(statement.functionDeclaration.functionExpression.typeParameters,
+        isNotNull);
   }
 
   void test_parseFunctionExpression_body_inExpression() {
@@ -8202,6 +8722,18 @@
     expect((expression.body as ExpressionFunctionBody).semicolon, isNull);
   }
 
+  void test_parseFunctionExpression_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionExpression expression =
+        parse4("parseFunctionExpression", "/*<E>*/(/*=E*/ i) => i++");
+    expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNotNull);
+    expect(expression.parameters, isNotNull);
+    expect((expression.body as ExpressionFunctionBody).semicolon, isNull);
+    SimpleFormalParameter p = expression.parameters.parameters[0];
+    expect(p.type, isNotNull);
+  }
+
   void test_parseFunctionExpression_typeParameters() {
     enableGenericMethods = true;
     FunctionExpression expression =
@@ -8318,6 +8850,41 @@
     expect(clause.implementsKeyword, isNotNull);
   }
 
+  void test_parseImportDirective_configuration_multiple() {
+    enableConditionalDirectives = true;
+    ImportDirective directive = parse(
+        "parseImportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "import 'lib/lib.dart' if (a) 'b.dart' if (c) 'd.dart';");
+    expect(directive.keyword, isNotNull);
+    expect(directive.uri, isNotNull);
+    expect(directive.configurations, hasLength(2));
+    _expectDottedName(directive.configurations[0].name, ['a']);
+    _expectDottedName(directive.configurations[1].name, ['c']);
+    expect(directive.deferredKeyword, isNull);
+    expect(directive.asKeyword, isNull);
+    expect(directive.prefix, isNull);
+    expect(directive.combinators, hasLength(0));
+    expect(directive.semicolon, isNotNull);
+  }
+
+  void test_parseImportDirective_configuration_single() {
+    enableConditionalDirectives = true;
+    ImportDirective directive = parse(
+        "parseImportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "import 'lib/lib.dart' if (a.b == 'c.dart') '';");
+    expect(directive.keyword, isNotNull);
+    expect(directive.uri, isNotNull);
+    expect(directive.configurations, hasLength(1));
+    _expectDottedName(directive.configurations[0].name, ['a', 'b']);
+    expect(directive.deferredKeyword, isNull);
+    expect(directive.asKeyword, isNull);
+    expect(directive.prefix, isNull);
+    expect(directive.combinators, hasLength(0));
+    expect(directive.semicolon, isNotNull);
+  }
+
   void test_parseImportDirective_deferred() {
     ImportDirective directive = parse(
         "parseImportDirective",
@@ -8951,6 +9518,16 @@
     expect(parameter.parameters, isNotNull);
   }
 
+  void test_parseNormalFormalParameter_function_noType_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionTypedFormalParameter parameter =
+        parse4("parseNormalFormalParameter", "a/*<E>*/())");
+    expect(parameter.returnType, isNull);
+    expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNotNull);
+    expect(parameter.parameters, isNotNull);
+  }
+
   void test_parseNormalFormalParameter_function_noType_typeParameters() {
     enableGenericMethods = true;
     FunctionTypedFormalParameter parameter =
@@ -8970,6 +9547,16 @@
     expect(parameter.parameters, isNotNull);
   }
 
+  void test_parseNormalFormalParameter_function_type_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionTypedFormalParameter parameter =
+        parse4("parseNormalFormalParameter", "A a/*<E>*/())");
+    expect(parameter.returnType, isNotNull);
+    expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNotNull);
+    expect(parameter.parameters, isNotNull);
+  }
+
   void test_parseNormalFormalParameter_function_type_typeParameters() {
     enableGenericMethods = true;
     FunctionTypedFormalParameter parameter =
@@ -8989,6 +9576,16 @@
     expect(parameter.parameters, isNotNull);
   }
 
+  void test_parseNormalFormalParameter_function_void_typeParameterComments() {
+    enableGenericMethodComments = true;
+    FunctionTypedFormalParameter parameter =
+        parse4("parseNormalFormalParameter", "void a/*<E>*/())");
+    expect(parameter.returnType, isNotNull);
+    expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNotNull);
+    expect(parameter.parameters, isNotNull);
+  }
+
   void test_parseNormalFormalParameter_function_void_typeParameters() {
     enableGenericMethods = true;
     FunctionTypedFormalParameter parameter =
@@ -9125,7 +9722,20 @@
     expect(expression.argumentList, isNotNull);
   }
 
-  void test_parsePostfixExpression_none_methodInvocation_question_dot_typeArguments() {
+  void
+      test_parsePostfixExpression_none_methodInvocation_question_dot_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation expression =
+        parse4('parsePostfixExpression', 'a?.m/*<E>*/()');
+    expect(expression.target, isNotNull);
+    expect(expression.operator.type, TokenType.QUESTION_PERIOD);
+    expect(expression.methodName, isNotNull);
+    expect(expression.typeArguments, isNotNull);
+    expect(expression.argumentList, isNotNull);
+  }
+
+  void
+      test_parsePostfixExpression_none_methodInvocation_question_dot_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation expression = parse4('parsePostfixExpression', 'a?.m<E>()');
     expect(expression.target, isNotNull);
@@ -9135,6 +9745,18 @@
     expect(expression.argumentList, isNotNull);
   }
 
+  void
+      test_parsePostfixExpression_none_methodInvocation_typeArgumentComments() {
+    enableGenericMethodComments = true;
+    MethodInvocation expression =
+        parse4("parsePostfixExpression", "a.m/*<E>*/()");
+    expect(expression.target, isNotNull);
+    expect(expression.operator.type, TokenType.PERIOD);
+    expect(expression.methodName, isNotNull);
+    expect(expression.typeArguments, isNotNull);
+    expect(expression.argumentList, isNotNull);
+  }
+
   void test_parsePostfixExpression_none_methodInvocation_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation expression = parse4("parsePostfixExpression", "a.m<E>()");
@@ -9488,17 +10110,20 @@
     expect(statement.functionDeclaration, isNotNull);
   }
 
-  void test_parseStatement_functionDeclaration_noReturnType_typeParameters() {
-    enableGenericMethods = true;
+  void
+      test_parseStatement_functionDeclaration_noReturnType_typeParameterComments() {
+    enableGenericMethodComments = true;
     FunctionDeclarationStatement statement =
-        parse4("parseStatement", "f(a, b) {};");
+        parse4("parseStatement", "f/*<E>*/(a, b) {};");
     expect(statement.functionDeclaration, isNotNull);
+    expect(statement.functionDeclaration.functionExpression.typeParameters,
+        isNotNull);
   }
 
   void test_parseStatement_functionDeclaration_returnType() {
     // TODO(brianwilkerson) Implement more tests for this method.
     FunctionDeclarationStatement statement =
-        parse4("parseStatement", "int f(a, b) {};");
+        parse4("parseStatement", "int f(a, b) {};", []);
     expect(statement.functionDeclaration, isNotNull);
   }
 
@@ -10350,6 +10975,16 @@
     expect(declarationList.variables, hasLength(1));
   }
 
+  void test_parseVariableDeclarationListAfterMetadata_final_typeComment() {
+    enableGenericMethodComments = true;
+    VariableDeclarationList decl = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()],
+        "final/*=T*/ x");
+    expect(decl.type.name.name, 'T');
+    expect(decl.isFinal, true);
+  }
+
   void test_parseVariableDeclarationListAfterMetadata_type_multiple() {
     VariableDeclarationList declarationList = parse(
         "parseVariableDeclarationListAfterMetadata",
@@ -10390,6 +11025,16 @@
     expect(declarationList.variables, hasLength(1));
   }
 
+  void test_parseVariableDeclarationListAfterMetadata_var_typeComment() {
+    enableGenericMethodComments = true;
+    VariableDeclarationList decl = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()],
+        "var/*=T*/ x");
+    expect(decl.type.name.name, 'T');
+    expect(decl.keyword, isNull);
+  }
+
   void test_parseVariableDeclarationListAfterType_type() {
     TypeName type = new TypeName(new SimpleIdentifier(null), null);
     VariableDeclarationList declarationList = parse(
@@ -10623,6 +11268,17 @@
     return invokeParserMethod2("createSyntheticStringLiteral", "", listener);
   }
 
+  void _expectDottedName(DottedName name, List<String> expectedComponents) {
+    int count = expectedComponents.length;
+    NodeList<SimpleIdentifier> components = name.components;
+    expect(components, hasLength(count));
+    for (int i = 0; i < count; i++) {
+      SimpleIdentifier component = components[i];
+      expect(component, isNotNull);
+      expect(component.name, expectedComponents[i]);
+    }
+  }
+
   /**
    * Invoke the method [Parser.isFunctionDeclaration] with the parser set to the token
    * stream produced by scanning the given source.
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 1339162..4722a65 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -2,13 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.resolver_test;
+library analyzer.test.generated.resolver_test;
 
 import 'dart:collection';
 
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -28,6 +32,7 @@
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/dart.dart';
 import 'package:unittest/unittest.dart';
 
 import '../reflective_tests.dart';
@@ -44,16 +49,6 @@
   runReflectiveTests(ScopeTest);
   runReflectiveTests(ElementResolverTest);
   runReflectiveTests(InheritanceManagerTest);
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(LibraryElementBuilderTest);
-  }
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(LibraryResolver2Test);
-  }
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(LibraryResolverTest);
-  }
-  runReflectiveTests(LibraryTest);
   runReflectiveTests(StaticTypeAnalyzerTest);
   runReflectiveTests(StaticTypeAnalyzer2Test);
   runReflectiveTests(SubtypeManagerTest);
@@ -68,6 +63,7 @@
   runReflectiveTests(SimpleResolverTest);
   runReflectiveTests(StrictModeTest);
   runReflectiveTests(TypePropagationTest);
+  runReflectiveTests(StrongModeDownwardsInferenceTest);
   runReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
   runReflectiveTests(StrongModeTypePropagationTest);
 }
@@ -88,10 +84,6 @@
    * Return the context that was created.
    */
   static InternalAnalysisContext contextWithCore() {
-    if (AnalysisEngine.instance.useTaskModel) {
-      NewAnalysisContextForTests context = new NewAnalysisContextForTests();
-      return initContextWithCore(context);
-    }
     AnalysisContextForTests context = new AnalysisContextForTests();
     return initContextWithCore(context);
   }
@@ -102,11 +94,6 @@
    */
   static InternalAnalysisContext contextWithCoreAndOptions(
       AnalysisOptions options) {
-    if (AnalysisEngine.instance.useTaskModel) {
-      NewAnalysisContextForTests context = new NewAnalysisContextForTests();
-      context._internalSetAnalysisOptions(options);
-      return initContextWithCore(context);
-    }
     AnalysisContextForTests context = new AnalysisContextForTests();
     context._internalSetAnalysisOptions(options);
     return initContextWithCore(context);
@@ -136,6 +123,10 @@
     coreContext.setContents(coreSource, "");
     coreUnit.librarySource = coreUnit.source = coreSource;
     ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy");
+    proxyClassElement.constructors = <ConstructorElement>[
+      ElementFactory.constructorElement(proxyClassElement, null, true)
+        ..isCycleFree = true
+    ];
     ClassElement objectClassElement = provider.objectType.element;
     coreUnit.types = <ClassElement>[
       provider.boolType.element,
@@ -201,38 +192,35 @@
       ElementFactory.positionalParameter2("value", provider.dynamicType)
     ];
     futureConstructor.factory = true;
-    (futureConstructor.type as FunctionTypeImpl).typeArguments =
-        futureElement.type.typeArguments;
     futureElement.constructors = <ConstructorElement>[futureConstructor];
     //   Future then(onValue(T value), { Function onError });
-    List<ParameterElement> parameters = <ParameterElement>[
-      ElementFactory.requiredParameter2(
-          "value", futureElement.typeParameters[0].type)
-    ];
-    FunctionTypeAliasElementImpl aliasElement =
-        new FunctionTypeAliasElementImpl.forNode(null);
-    aliasElement.synthetic = true;
-    aliasElement.parameters = parameters;
-    aliasElement.returnType = provider.dynamicType;
-    aliasElement.enclosingElement = asyncUnit;
-    FunctionTypeImpl aliasType = new FunctionTypeImpl.forTypedef(aliasElement);
-    aliasElement.shareTypeParameters(futureElement.typeParameters);
-    aliasType.typeArguments = futureElement.type.typeArguments;
-    DartType futureDynamicType =
-        futureElement.type.substitute4([provider.dynamicType]);
-    MethodElement thenMethod = ElementFactory.methodElementWithParameters(
-        "then", futureElement.type.typeArguments, futureDynamicType, [
-      ElementFactory.requiredParameter2("onValue", aliasType),
+    TypeDefiningElement futureThenR = DynamicElementImpl.instance;
+    if (context.analysisOptions.strongMode) {
+      futureThenR = ElementFactory.typeParameterWithType('R');
+    }
+    FunctionElementImpl thenOnValue = ElementFactory.functionElement3(
+        'onValue', futureThenR, [futureElement.typeParameters[0]], null);
+
+    DartType futureRType = futureElement.type.substitute4([futureThenR.type]);
+    MethodElementImpl thenMethod = ElementFactory
+        .methodElementWithParameters(futureElement, "then", futureRType, [
+      ElementFactory.requiredParameter2("onValue", thenOnValue.type),
       ElementFactory.namedParameter2("onError", provider.functionType)
     ]);
+    if (!futureThenR.type.isDynamic) {
+      thenMethod.typeParameters = [futureThenR];
+    }
+    thenOnValue.enclosingElement = thenMethod;
+    thenOnValue.type = new FunctionTypeImpl(thenOnValue);
+    (thenMethod.parameters[0] as ParameterElementImpl).type = thenOnValue.type;
+    thenMethod.type = new FunctionTypeImpl(thenMethod);
+
     futureElement.methods = <MethodElement>[thenMethod];
     // Completer
     ClassElementImpl completerElement =
         ElementFactory.classElement2("Completer", ["T"]);
     ConstructorElementImpl completerConstructor =
         ElementFactory.constructorElement2(completerElement, null);
-    (completerConstructor.type as FunctionTypeImpl).typeArguments =
-        completerElement.type.typeArguments;
     completerElement.constructors = <ConstructorElement>[completerConstructor];
     // StreamSubscription
     ClassElementImpl streamSubscriptionElement =
@@ -255,11 +243,19 @@
     MethodElementImpl listenMethod =
         ElementFactory.methodElement('listen', returnType, parameterTypes);
     streamElement.methods = <MethodElement>[listenMethod];
+    listenMethod.type = new FunctionTypeImpl(listenMethod);
+
+    FunctionElementImpl listenParamFunction = parameterTypes[0].element;
+    listenParamFunction.enclosingElement = listenMethod;
+    listenParamFunction.type = new FunctionTypeImpl(listenParamFunction);
+    ParameterElementImpl listenParam = listenMethod.parameters[0];
+    listenParam.type = listenParamFunction.type;
 
     asyncUnit.types = <ClassElement>[
       completerElement,
       futureElement,
-      streamElement
+      streamElement,
+      streamSubscriptionElement
     ];
     LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
         coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
@@ -296,8 +292,8 @@
     ClassElementImpl htmlDocumentElement =
         ElementFactory.classElement("HtmlDocument", documentElement.type);
     htmlDocumentElement.methods = <MethodElement>[
-      ElementFactory.methodElement(
-          "query", elementType, <DartType>[provider.stringType])
+      ElementFactory
+          .methodElement("query", elementType, <DartType>[provider.stringType])
     ];
     htmlUnit.types = <ClassElement>[
       ElementFactory.classElement("AnchorElement", elementType),
@@ -317,8 +313,8 @@
       ElementFactory.functionElement3("query", elementElement,
           <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
     ];
-    TopLevelVariableElementImpl document = ElementFactory
-        .topLevelVariableElement3(
+    TopLevelVariableElementImpl document =
+        ElementFactory.topLevelVariableElement3(
             "document", false, true, htmlDocumentElement.type);
     htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
     htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
@@ -340,11 +336,12 @@
         ClassElement.EMPTY_LIST);
     TopLevelVariableElement ln10Element = ElementFactory
         .topLevelVariableElement3("LN10", true, false, provider.doubleType);
-    FunctionElement maxElement = ElementFactory.functionElement3(
-        "max",
-        provider.numType.element,
-        <ClassElement>[provider.numType.element, provider.numType.element],
-        ClassElement.EMPTY_LIST);
+    TypeParameterElement maxT =
+        ElementFactory.typeParameterWithType('T', provider.numType);
+    FunctionElementImpl maxElement = ElementFactory.functionElement3(
+        "max", maxT, [maxT, maxT], ClassElement.EMPTY_LIST);
+    maxElement.typeParameters = [maxT];
+    maxElement.type = new FunctionTypeImpl(maxElement);
     TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3(
         "PI", true, false, provider.doubleType);
     ClassElementImpl randomElement = ElementFactory.classElement2("Random");
@@ -401,34 +398,22 @@
     elementMap[asyncSource] = asyncLibrary;
     elementMap[htmlSource] = htmlLibrary;
     elementMap[mathSource] = mathLibrary;
+    //
+    // Set the public and export namespaces.  We don't use exports in the fake
+    // core library so public and export namespaces are the same.
+    //
+    for (LibraryElementImpl library in elementMap.values) {
+      library.exportNamespace =
+          library.publicNamespace = new PublicNamespaceBuilder().build(library);
+    }
     context.recordLibraryElements(elementMap);
     return context;
   }
-
-  /**
-   * Create an analysis context that has a fake core library already resolved.
-   * Return the context that was created.
-   */
-  static AnalysisContextImpl oldContextWithCore() {
-    AnalysisContextForTests context = new AnalysisContextForTests();
-    return initContextWithCore(context);
-  }
-
-  /**
-   * Create an analysis context that uses the given [options] and has a fake
-   * core library already resolved. Return the context that was created.
-   */
-  static AnalysisContextImpl oldContextWithCoreAndOptions(
-      AnalysisOptions options) {
-    AnalysisContextForTests context = new AnalysisContextForTests();
-    context._internalSetAnalysisOptions(options);
-    return initContextWithCore(context);
-  }
 }
 
 /**
- * Instances of the class `AnalysisContextForTests` implement an analysis context that has a
- * fake SDK that is much smaller and faster for testing purposes.
+ * An analysis context that has a fake SDK that is much smaller and faster for
+ * testing purposes.
  */
 class AnalysisContextForTests extends AnalysisContextImpl {
   @override
@@ -1297,6 +1282,7 @@
 
   @override
   void setUp() {
+    super.setUp();
     _listener = new GatheringErrorListener();
     _typeProvider = new TestTypeProvider();
     _resolver = _createResolver();
@@ -1449,6 +1435,47 @@
     _listener.assertNoErrors();
   }
 
+  void test_visitCommentReference_prefixedIdentifier_class_getter() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    // set accessors
+    String propName = "p";
+    PropertyAccessorElement getter =
+        ElementFactory.getterElement(propName, false, _typeProvider.intType);
+    PropertyAccessorElement setter =
+        ElementFactory.setterElement(propName, false, _typeProvider.intType);
+    classA.accessors = <PropertyAccessorElement>[getter, setter];
+    // set name scope
+    _visitor.nameScope = new EnclosedScope(null)
+      ..defineNameWithoutChecking('A', classA);
+    // prepare "A.p"
+    PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'p');
+    CommentReference commentReference = new CommentReference(null, prefixed);
+    // resolve
+    _resolveNode(commentReference);
+    expect(prefixed.prefix.staticElement, classA);
+    expect(prefixed.identifier.staticElement, getter);
+    _listener.assertNoErrors();
+  }
+
+  void test_visitCommentReference_prefixedIdentifier_class_method() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    // set method
+    MethodElement method =
+        ElementFactory.methodElement("m", _typeProvider.intType);
+    classA.methods = <MethodElement>[method];
+    // set name scope
+    _visitor.nameScope = new EnclosedScope(null)
+      ..defineNameWithoutChecking('A', classA);
+    // prepare "A.m"
+    PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'm');
+    CommentReference commentReference = new CommentReference(null, prefixed);
+    // resolve
+    _resolveNode(commentReference);
+    expect(prefixed.prefix.staticElement, classA);
+    expect(prefixed.identifier.staticElement, method);
+    _listener.assertNoErrors();
+  }
+
   void test_visitConstructorName_named() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String constructorName = "a";
@@ -1997,12 +2024,9 @@
         definingCompilationUnit.source = source;
     _definingLibrary = ElementFactory.library(context, "test");
     _definingLibrary.definingCompilationUnit = definingCompilationUnit;
-    Library library = new Library(context, _listener, source);
-    library.libraryElement = _definingLibrary;
     _visitor = new ResolverVisitor(
-        library.libraryElement, source, _typeProvider, library.errorListener,
-        nameScope: library.libraryScope,
-        inheritanceManager: library.inheritanceManager);
+        _definingLibrary, source, _typeProvider, _listener,
+        nameScope: new LibraryScope(_definingLibrary, _listener));
     try {
       return _visitor.elementResolver;
     } catch (exception) {
@@ -2358,6 +2382,61 @@
     verify([source]);
   }
 
+  void test_canBeNullAfterNullAware_false_methodInvocation() {
+    Source source = addSource(r'''
+m(x) {
+  x?.a()?.b();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_canBeNullAfterNullAware_false_propertyAccess() {
+    Source source = addSource(r'''
+m(x) {
+  x?.a?.b;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_canBeNullAfterNullAware_methodInvocation() {
+    Source source = addSource(r'''
+m(x) {
+  x?.a.b();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+    verify([source]);
+  }
+
+  void test_canBeNullAfterNullAware_parenthesized() {
+    Source source = addSource(r'''
+m(x) {
+  (x?.a).b;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+    verify([source]);
+  }
+
+  void test_canBeNullAfterNullAware_propertyAccess() {
+    Source source = addSource(r'''
+m(x) {
+  x?.a.b;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+    verify([source]);
+  }
+
   void test_deadCode_deadBlock_conditionalElse() {
     Source source = addSource(r'''
 f() {
@@ -2762,10 +2841,10 @@
     verify([source]);
   }
 
-  void test_deprecatedAnnotationUse_Deprecated() {
+  void test_deprecatedAnnotationUse_deprecated() {
     Source source = addSource(r'''
 class A {
-  @Deprecated('0.9')
+  @deprecated
   m() {}
   n() {m();}
 }''');
@@ -2774,10 +2853,10 @@
     verify([source]);
   }
 
-  void test_deprecatedAnnotationUse_deprecated() {
+  void test_deprecatedAnnotationUse_Deprecated() {
     Source source = addSource(r'''
 class A {
-  @deprecated
+  @Deprecated('0.9')
   m() {}
   n() {m();}
 }''');
@@ -3153,6 +3232,160 @@
     verify([source]);
   }
 
+  void test_nullAwareInCondition_assert() {
+    Source source = addSource(r'''
+m(x) {
+  assert (x?.a);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_conditionalExpression() {
+    Source source = addSource(r'''
+m(x) {
+  return x?.a ? 0 : 1;
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_do() {
+    Source source = addSource(r'''
+m(x) {
+  do {} while (x?.a);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_for() {
+    Source source = addSource(r'''
+m(x) {
+  for (var v = x; v?.a; v = v.next) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if() {
+    Source source = addSource(r'''
+m(x) {
+  if (x?.a) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalAnd_first() {
+    Source source = addSource(r'''
+m(x) {
+  if (x?.a && x.b) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalAnd_second() {
+    Source source = addSource(r'''
+m(x) {
+  if (x.a && x?.b) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalAnd_third() {
+    Source source = addSource(r'''
+m(x) {
+  if (x.a && x.b && x?.c) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalOr_first() {
+    Source source = addSource(r'''
+m(x) {
+  if (x?.a || x.b) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalOr_second() {
+    Source source = addSource(r'''
+m(x) {
+  if (x.a || x?.b) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_conditionalOr_third() {
+    Source source = addSource(r'''
+m(x) {
+  if (x.a || x.b || x?.c) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_not() {
+    Source source = addSource(r'''
+m(x) {
+  if (!x?.a) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_parenthesized() {
+    Source source = addSource(r'''
+m(x) {
+  if ((x?.a)) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_while() {
+    Source source = addSource(r'''
+m(x) {
+  while (x?.a) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+    verify([source]);
+  }
+
   void test_overrideOnNonOverridingGetter_invalid() {
     Source source = addSource(r'''
 library dart.core;
@@ -3374,6 +3607,36 @@
     verify([source]);
   }
 
+  void test_unnecessaryNoSuchMethod_blockBody() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) {
+    return super.noSuchMethod(y);
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+    verify([source]);
+  }
+
+  void test_unnecessaryNoSuchMethod_expressionBody() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) => super.noSuchMethod(y);
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+    verify([source]);
+  }
+
   void test_unnecessaryTypeCheck_null_is_Null() {
     Source source = addSource("bool b = null is Null;");
     computeLibrarySourceErrors(source);
@@ -3439,6 +3702,22 @@
     verify([source]);
   }
 
+  void test_unusedElement_class_isUsed_fieldDeclaration() {
+    enableUnusedElement = true;
+    var src = r'''
+class Foo {
+  _Bar x;
+}
+
+class _Bar {
+}
+''';
+    Source source = addSource(src);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_unusedElement_class_isUsed_implements() {
     enableUnusedElement = true;
     Source source = addSource(r'''
@@ -4626,7 +4905,7 @@
 }
 
 @reflectiveTest
-class InheritanceManagerTest extends EngineTestCase {
+class InheritanceManagerTest {
   /**
    * The type provider used to access the types.
    */
@@ -4647,7 +4926,6 @@
    */
   int _numOfMembersInObject = 0;
 
-  @override
   void setUp() {
     _typeProvider = new TestTypeProvider();
     _inheritanceManager = _createInheritanceManager();
@@ -4884,7 +5162,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
     // class I1 { int m(); }
     // class I2 { int get m; }
     // class A implements I2, I1 {}
@@ -4907,7 +5186,8 @@
         [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
     // class I1 { int m(); }
     // class I2 { String m(); }
     // class A implements I1, I2 {}
@@ -4917,8 +5197,8 @@
         ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
     classI1.methods = <MethodElement>[methodM1];
     ClassElementImpl classI2 = ElementFactory.classElement2("I2");
-    MethodElement methodM2 = ElementFactory.methodElement(
-        methodName, null, [_typeProvider.stringType]);
+    MethodElement methodM2 = ElementFactory
+        .methodElement(methodName, null, [_typeProvider.stringType]);
     classI2.methods = <MethodElement>[methodM2];
     ClassElementImpl classA = ElementFactory.classElement2("A");
     classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
@@ -4930,7 +5210,8 @@
         classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
     // class I1 { int m(); }
     // class I2 { int get m; }
     // class A implements I1, I2 {}
@@ -4953,7 +5234,8 @@
         [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
     // class I1 { dynamic m(int, [int]); }
     // class I2 { dynamic m(int, int, int); }
     // class A implements I1, I2 {}
@@ -5002,14 +5284,15 @@
         classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
     // class I1 { int m(); }
     // class I2 { String m(); }
     // class A implements I2, I1 {}
     ClassElementImpl classI1 = ElementFactory.classElement2("I1");
     String methodName = "m";
-    MethodElement methodM1 = ElementFactory.methodElement(
-        methodName, null, [_typeProvider.stringType]);
+    MethodElement methodM1 = ElementFactory
+        .methodElement(methodName, null, [_typeProvider.stringType]);
     classI1.methods = <MethodElement>[methodM1];
     ClassElementImpl classI2 = ElementFactory.classElement2("I2");
     MethodElement methodM2 =
@@ -5111,7 +5394,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
     // class I1 { int get g; }
     // class I2 { num get g; }
     // class A implements I1, I2 {}
@@ -5135,7 +5419,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
     // class I1 { dynamic m(int); }
     // class I2 { dynamic m(num); }
     // class A implements I1, I2 {}
@@ -5169,7 +5454,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
     // class I1 { set s(int); }
     // class I2 { set s(num); }
     // class A implements I1, I2 {}
@@ -5194,7 +5480,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
     // class A {}
     // class B extends A {}
     // class C extends B {}
@@ -5233,7 +5520,8 @@
     _assertNoErrors(classD);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
     // class A {}
     // class B extends A {}
     // class C extends B {}
@@ -5287,7 +5575,8 @@
     _assertNoErrors(classD);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
     // class A {}
     // class B extends A {}
     // class C extends B {}
@@ -5327,7 +5616,8 @@
     _assertNoErrors(classD);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
     // class I1 { int m(); }
     // class I2 { int m([int]); }
     // class A implements I1, I2 {}
@@ -5354,7 +5644,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
     // class I1 { int m(); }
     // class I2 { int m([int]); }
     // class I3 { int m([int, int]); }
@@ -5399,7 +5690,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
     // class I1 { int m(); }
     // class I2 { int m(); }
     // class I3 { int m([int]); }
@@ -5851,217 +6143,6 @@
 }
 
 @reflectiveTest
-class LibraryElementBuilderTest extends EngineTestCase {
-  /**
-   * The analysis context used to analyze sources.
-   */
-  InternalAnalysisContext _context;
-
-  /**
-   * Add a source file to the content provider. The file path should be absolute.
-   *
-   * @param filePath the path of the file being added
-   * @param contents the contents to be returned by the content provider for the specified file
-   * @return the source object representing the added file
-   */
-  Source addSource(String filePath, String contents) {
-    Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
-    _context.setContents(source, contents);
-    return source;
-  }
-
-  @override
-  void setUp() {
-    _context = AnalysisContextFactory.contextWithCore();
-  }
-
-  @override
-  void tearDown() {
-    _context = null;
-    super.tearDown();
-  }
-
-  void test_accessorsAcrossFiles() {
-    Source librarySource = addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'first.dart';
-part 'second.dart';''');
-    addSource(
-        "/first.dart",
-        r'''
-part of lib;
-int get V => 0;''');
-    addSource(
-        "/second.dart",
-        r'''
-part of lib;
-void set V(int v) {}''');
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    List<CompilationUnitElement> sourcedUnits = element.parts;
-    expect(sourcedUnits, hasLength(2));
-    List<PropertyAccessorElement> firstAccessors = sourcedUnits[0].accessors;
-    expect(firstAccessors, hasLength(1));
-    List<PropertyAccessorElement> secondAccessors = sourcedUnits[1].accessors;
-    expect(secondAccessors, hasLength(1));
-    expect(secondAccessors[0].variable, same(firstAccessors[0].variable));
-  }
-
-  void test_empty() {
-    Source librarySource = addSource("/lib.dart", "library lib;");
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    expect(element.name, "lib");
-    expect(element.entryPoint, isNull);
-    expect(element.importedLibraries, hasLength(0));
-    expect(element.imports, hasLength(0));
-    expect(element.library, same(element));
-    expect(element.prefixes, hasLength(0));
-    expect(element.parts, hasLength(0));
-    CompilationUnitElement unit = element.definingCompilationUnit;
-    expect(unit, isNotNull);
-    expect(unit.name, "lib.dart");
-    expect(unit.library, element);
-    expect(unit.accessors, hasLength(0));
-    expect(unit.functions, hasLength(0));
-    expect(unit.functionTypeAliases, hasLength(0));
-    expect(unit.types, hasLength(0));
-    expect(unit.topLevelVariables, hasLength(0));
-  }
-
-  void test_libraryElement_docRange() {
-    String code = r'''
-/// My dart doc.
-library lib;
-
-class A {}''';
-    Source librarySource = addSource("/lib.dart", code);
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    SourceRange docRange = element.docRange;
-    expect(docRange, isNotNull);
-    expect(docRange.offset, code.indexOf('/// My dart doc.'));
-    expect(docRange.length, '/// My dart doc.'.length);
-  }
-
-  void test_missingLibraryDirectiveWithPart() {
-    addSource("/a.dart", "part of lib;");
-    Source librarySource = addSource("/lib.dart", "part 'a.dart';");
-    LibraryElement element = _buildLibrary(
-        librarySource, [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
-    expect(element, isNotNull);
-  }
-
-  void test_missingPartOfDirective() {
-    addSource("/a.dart", "class A {}");
-    Source librarySource = addSource(
-        "/lib.dart",
-        r'''
-library lib;
-
-part 'a.dart';''');
-    LibraryElement element =
-        _buildLibrary(librarySource, [CompileTimeErrorCode.PART_OF_NON_PART]);
-    expect(element, isNotNull);
-  }
-
-  void test_multipleFiles() {
-    Source librarySource = addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'first.dart';
-part 'second.dart';
-
-class A {}''');
-    addSource(
-        "/first.dart",
-        r'''
-part of lib;
-class B {}''');
-    addSource(
-        "/second.dart",
-        r'''
-part of lib;
-class C {}''');
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    List<CompilationUnitElement> sourcedUnits = element.parts;
-    expect(sourcedUnits, hasLength(2));
-    _assertTypes(element.definingCompilationUnit, ["A"]);
-    if (sourcedUnits[0].name == "first.dart") {
-      _assertTypes(sourcedUnits[0], ["B"]);
-      _assertTypes(sourcedUnits[1], ["C"]);
-    } else {
-      _assertTypes(sourcedUnits[0], ["C"]);
-      _assertTypes(sourcedUnits[1], ["B"]);
-    }
-  }
-
-  void test_singleFile() {
-    Source librarySource = addSource(
-        "/lib.dart",
-        r'''
-/// My dart doc.
-library lib;
-
-class A {}''');
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    _assertTypes(element.definingCompilationUnit, ["A"]);
-  }
-
-  /**
-   * Ensure that there are elements representing all of the types in the given array of type names.
-   *
-   * @param unit the compilation unit containing the types
-   * @param typeNames the names of the types that should be found
-   */
-  void _assertTypes(CompilationUnitElement unit, List<String> typeNames) {
-    expect(unit, isNotNull);
-    List<ClassElement> types = unit.types;
-    expect(types, hasLength(typeNames.length));
-    for (ClassElement type in types) {
-      expect(type, isNotNull);
-      String actualTypeName = type.displayName;
-      bool wasExpected = false;
-      for (String expectedTypeName in typeNames) {
-        if (expectedTypeName == actualTypeName) {
-          wasExpected = true;
-        }
-      }
-      if (!wasExpected) {
-        fail("Found unexpected type $actualTypeName");
-      }
-    }
-  }
-
-  /**
-   * Build the element model for the library whose defining compilation unit has the given source.
-   *
-   * @param librarySource the source of the defining compilation unit for the library
-   * @param expectedErrorCodes the errors that are expected to be found while building the element
-   *          model
-   * @return the element model that was built for the library
-   * @throws Exception if the element model could not be built
-   */
-  LibraryElement _buildLibrary(Source librarySource,
-      [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
-    LibraryResolver resolver = new LibraryResolver(_context);
-    LibraryElementBuilder builder = new LibraryElementBuilder(
-        resolver.analysisContext, resolver.errorListener);
-    Library library = resolver.createLibrary(librarySource);
-    LibraryElement element = builder.buildLibrary(library);
-    GatheringErrorListener listener = new GatheringErrorListener();
-    listener.addAll2(resolver.errorListener);
-    listener.assertErrorsWithCodes(expectedErrorCodes);
-    return element;
-  }
-}
-
-@reflectiveTest
 class LibraryImportScopeTest extends ResolverTestCase {
   void test_conflictingImports() {
     AnalysisContext context = AnalysisContextFactory.contextWithCore();
@@ -6242,104 +6323,6 @@
 }
 
 @reflectiveTest
-class LibraryResolver2Test extends ResolverTestCase {
-  LibraryResolver2 _resolver;
-
-  Source _coreLibrarySource;
-
-  Source _asyncLibrarySource;
-
-  @override
-  void setUp() {
-    super.setUp();
-    _resolver = new LibraryResolver2(analysisContext2);
-    _coreLibrarySource =
-        analysisContext2.sourceFactory.forUri(DartSdk.DART_CORE);
-    _asyncLibrarySource =
-        analysisContext2.sourceFactory.forUri(DartSdk.DART_ASYNC);
-  }
-
-  void test_imports_relative() {
-    Source sourceA = addSource(r'''
-library libA;
-import 'libB.dart';
-class A {}''');
-    Source sourceB = addNamedSource(
-        "/libB.dart",
-        r'''
-library libB;
-import 'test.dart
-class B {}''');
-    List<ResolvableLibrary> cycle = new List<ResolvableLibrary>();
-    ResolvableLibrary coreLib = _createResolvableLibrary(_coreLibrarySource);
-    coreLib.libraryElement = analysisContext2
-        .computeLibraryElement(_coreLibrarySource) as LibraryElementImpl;
-    ResolvableLibrary asyncLib = _createResolvableLibrary(_asyncLibrarySource);
-    asyncLib.libraryElement = analysisContext2
-        .computeLibraryElement(_asyncLibrarySource) as LibraryElementImpl;
-    ResolvableLibrary libA = _createResolvableLibrary(sourceA);
-    ResolvableLibrary libB = _createResolvableLibrary(sourceB);
-    libA.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libB];
-    libB.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libA];
-    cycle.add(libA);
-    cycle.add(libB);
-    LibraryElement library = _resolver.resolveLibrary(sourceA, cycle);
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-  }
-
-  ResolvableLibrary _createResolvableLibrary(Source source) {
-    CompilationUnit unit = analysisContext2.parseCompilationUnit(source);
-    ResolvableLibrary resolvableLibrary = new ResolvableLibrary(source);
-    resolvableLibrary.resolvableCompilationUnits = <ResolvableCompilationUnit>[
-      new ResolvableCompilationUnit(source, unit)
-    ];
-    return resolvableLibrary;
-  }
-}
-
-@reflectiveTest
-class LibraryResolverTest extends ResolverTestCase {
-  LibraryResolver _resolver;
-
-  @override
-  void setUp() {
-    super.setUp();
-    _resolver = new LibraryResolver(analysisContext2);
-  }
-
-  void test_imports_dart_html() {
-    Source source = addSource(r'''
-library libA;
-import 'dart:html';
-class A {}''');
-    LibraryElement library = _resolver.resolveLibrary(source, true);
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "dart.dom.html"]);
-  }
-
-  void test_imports_none() {
-    Source source = addSource(r'''
-library libA;
-class A {}''');
-    LibraryElement library = _resolver.resolveLibrary(source, true);
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core"]);
-  }
-
-  void test_imports_relative() {
-    addNamedSource("/libB.dart", "library libB;");
-    Source source = addSource(r'''
-library libA;
-import 'libB.dart';
-class A {}''');
-    LibraryElement library = _resolver.resolveLibrary(source, true);
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-  }
-}
-
-@reflectiveTest
 class LibraryScopeTest extends ResolverTestCase {
   void test_creation_empty() {
     LibraryElement definingLibrary = createDefaultTestLibrary();
@@ -6376,112 +6359,6 @@
 }
 
 @reflectiveTest
-class LibraryTest extends EngineTestCase {
-  /**
-   * The error listener to which all errors will be reported.
-   */
-  GatheringErrorListener _errorListener;
-
-  /**
-   * The analysis context to pass in to all libraries created by the tests.
-   */
-  InternalAnalysisContext _analysisContext;
-
-  /**
-   * The library used by the tests.
-   */
-  Library _library;
-
-  @override
-  void setUp() {
-    _analysisContext = AnalysisContextFactory.contextWithCore();
-    _errorListener = new GatheringErrorListener();
-    _library = _createLibrary("/lib.dart");
-  }
-
-  @override
-  void tearDown() {
-    _errorListener = null;
-    _analysisContext = null;
-    _library = null;
-    super.tearDown();
-  }
-
-  void test_getExplicitlyImportsCore() {
-    expect(_library.explicitlyImportsCore, isFalse);
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getExports() {
-    expect(_library.exports, hasLength(0));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getImports() {
-    expect(_library.imports, hasLength(0));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getImportsAndExports() {
-    _library.importedLibraries = <Library>[_createLibrary("/imported.dart")];
-    _library.exportedLibraries = <Library>[_createLibrary("/exported.dart")];
-    expect(_library.importsAndExports, hasLength(2));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getLibraryScope() {
-    LibraryElementImpl element = new LibraryElementImpl.forNode(
-        _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
-    element.definingCompilationUnit =
-        new CompilationUnitElementImpl("lib.dart");
-    _library.libraryElement = element;
-    expect(_library.libraryScope, isNotNull);
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getLibrarySource() {
-    expect(_library.librarySource, isNotNull);
-  }
-
-  void test_setExplicitlyImportsCore() {
-    _library.explicitlyImportsCore = true;
-    expect(_library.explicitlyImportsCore, isTrue);
-    _errorListener.assertNoErrors();
-  }
-
-  void test_setExportedLibraries() {
-    Library exportLibrary = _createLibrary("/exported.dart");
-    _library.exportedLibraries = <Library>[exportLibrary];
-    List<Library> exports = _library.exports;
-    expect(exports, hasLength(1));
-    expect(exports[0], same(exportLibrary));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_setImportedLibraries() {
-    Library importLibrary = _createLibrary("/imported.dart");
-    _library.importedLibraries = <Library>[importLibrary];
-    List<Library> imports = _library.imports;
-    expect(imports, hasLength(1));
-    expect(imports[0], same(importLibrary));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_setLibraryElement() {
-    LibraryElementImpl element = new LibraryElementImpl.forNode(
-        _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
-    _library.libraryElement = element;
-    expect(_library.libraryElement, same(element));
-  }
-
-  Library _createLibrary(String definingCompilationUnitPath) => new Library(
-      _analysisContext,
-      _errorListener,
-      new FileBasedSource(
-          FileUtilities2.createFile(definingCompilationUnitPath)));
-}
-
-@reflectiveTest
 class MemberMapTest {
   /**
    * The null type.
@@ -6527,61 +6404,6 @@
   }
 }
 
-/**
- * An analysis context that has a fake SDK that is much smaller and faster for
- * testing purposes.
- */
-class NewAnalysisContextForTests extends newContext.AnalysisContextImpl {
-  @override
-  void set analysisOptions(AnalysisOptions options) {
-    AnalysisOptions currentOptions = analysisOptions;
-    bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
-            options.analyzeFunctionBodiesPredicate ||
-        currentOptions.generateImplicitErrors !=
-            options.generateImplicitErrors ||
-        currentOptions.generateSdkErrors != options.generateSdkErrors ||
-        currentOptions.dart2jsHint != options.dart2jsHint ||
-        (currentOptions.hint && !options.hint) ||
-        currentOptions.preserveComments != options.preserveComments ||
-        currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
-    if (needsRecompute) {
-      fail(
-          "Cannot set options that cause the sources to be reanalyzed in a test context");
-    }
-    super.analysisOptions = options;
-  }
-
-  @override
-  bool exists(Source source) =>
-      super.exists(source) || sourceFactory.dartSdk.context.exists(source);
-
-  @override
-  TimestampedData<String> getContents(Source source) {
-    if (source.isInSystemLibrary) {
-      return sourceFactory.dartSdk.context.getContents(source);
-    }
-    return super.getContents(source);
-  }
-
-  @override
-  int getModificationStamp(Source source) {
-    if (source.isInSystemLibrary) {
-      return sourceFactory.dartSdk.context.getModificationStamp(source);
-    }
-    return super.getModificationStamp(source);
-  }
-
-  /**
-   * Set the analysis options, even if they would force re-analysis. This method should only be
-   * invoked before the fake SDK is initialized.
-   *
-   * @param options the analysis options to be set
-   */
-  void _internalSetAnalysisOptions(AnalysisOptions options) {
-    super.analysisOptions = options;
-  }
-}
-
 @reflectiveTest
 class NonHintCodeTest extends ResolverTestCase {
   void test_deadCode_deadBlock_conditionalElse_debugConst() {
@@ -6900,6 +6722,28 @@
     verify([source]);
   }
 
+  void test_nullAwareInCondition_for_noCondition() {
+    Source source = addSource(r'''
+m(x) {
+  for (var v = x; ; v++) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_nullAwareInCondition_if_notTopLevel() {
+    Source source = addSource(r'''
+m(x) {
+  if (x?.y == null) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_overrideEqualsButNotHashCode() {
     Source source = addSource(r'''
 class A {
@@ -7344,6 +7188,67 @@
     verify([source]);
   }
 
+  void test_unnecessaryNoSuchMethod_blockBody_notReturnStatement() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) {
+    print(y);
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_unnecessaryNoSuchMethod_blockBody_notSingleStatement() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) {
+    print(y);
+    return super.noSuchMethod(y);
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_unnecessaryNoSuchMethod_expressionBody_notNoSuchMethod() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) => super.hashCode;
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_unnecessaryNoSuchMethod_expressionBody_notSuper() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) => 42;
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_unusedImport_annotationOnDirective() {
     Source source = addSource(r'''
 library L;
@@ -8190,6 +8095,7 @@
 
   @override
   void setUp() {
+    super.setUp();
     reset();
   }
 
@@ -9487,7 +9393,9 @@
     expect(declarations, hasLength(2));
     Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
         .variables
-        .variables[0].name.staticElement;
+        .variables[0]
+        .name
+        .staticElement;
     EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
         PropertyInducingElement, expectedElement);
     expectedElement = (expectedElement as PropertyInducingElement).getter;
@@ -9678,7 +9586,9 @@
     expect(declarations, hasLength(2));
     Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
         .variables
-        .variables[0].name.staticElement;
+        .variables[0]
+        .name
+        .staticElement;
     EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
         PropertyInducingElement, expectedElement);
     expectedElement = (expectedElement as PropertyInducingElement).getter;
@@ -10126,6 +10036,7 @@
 
   @override
   void setUp() {
+    super.setUp();
     _listener = new GatheringErrorListener();
     _typeProvider = new TestTypeProvider();
     _analyzer = _createAnalyzer();
@@ -11393,12 +11304,9 @@
     LibraryElementImpl definingLibrary =
         new LibraryElementImpl.forNode(context, null);
     definingLibrary.definingCompilationUnit = definingCompilationUnit;
-    Library library = new Library(context, _listener, source);
-    library.libraryElement = definingLibrary;
     _visitor = new ResolverVisitor(
-        library.libraryElement, source, _typeProvider, library.errorListener,
-        nameScope: library.libraryScope,
-        inheritanceManager: library.inheritanceManager);
+        definingLibrary, source, _typeProvider, _listener,
+        nameScope: new LibraryScope(definingLibrary, _listener));
     _visitor.overrideManager.enterScope();
     try {
       return _visitor.typeAnalyzer;
@@ -11896,11 +11804,1371 @@
 }
 
 /**
+ * Strong mode static analyzer downwards inference tests
+ */
+@reflectiveTest
+class StrongModeDownwardsInferenceTest extends ResolverTestCase {
+  TypeAssertions _assertions;
+
+  Asserter<DartType> _isDynamic;
+  Asserter<InterfaceType> _isFutureOfDynamic;
+  Asserter<InterfaceType> _isFutureOfInt;
+  Asserter<DartType> _isInt;
+  Asserter<DartType> _isNum;
+  Asserter<DartType> _isString;
+
+  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
+      _isFunction2Of;
+  AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf;
+  AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
+      _isInstantiationOf;
+  AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
+  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
+      _isMapOf;
+  AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf;
+  AsserterBuilder<DartType, DartType> _isType;
+
+  AsserterBuilder<Element, DartType> _hasElement;
+  AsserterBuilder<DartType, DartType> _sameElement;
+
+  @override
+  void setUp() {
+    super.setUp();
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.strongMode = true;
+    resetWithOptions(options);
+    _assertions = new TypeAssertions(typeProvider);
+    _isType = _assertions.isType;
+    _hasElement = _assertions.hasElement;
+    _isInstantiationOf = _assertions.isInstantiationOf;
+    _isInt = _assertions.isInt;
+    _isNum = _assertions.isNum;
+    _isString = _assertions.isString;
+    _isDynamic = _assertions.isDynamic;
+    _isListOf = _assertions.isListOf;
+    _isMapOf = _assertions.isMapOf;
+    _isFunction2Of = _assertions.isFunction2Of;
+    _sameElement = _assertions.sameElement;
+    _isFutureOf = _isInstantiationOf(_sameElement(typeProvider.futureType));
+    _isFutureOfDynamic = _isFutureOf([_isDynamic]);
+    _isFutureOfInt = _isFutureOf([_isInt]);
+    _isStreamOf = _isInstantiationOf(_sameElement(typeProvider.streamType));
+  }
+
+  void test_async_method_propagation() {
+    String code = r'''
+      import "dart:async";
+      class A {
+        Future f0() => new Future.value(3);
+        Future f1() async => new Future.value(3);
+        Future f2() async => await new Future.value(3);
+
+        Future<int> f3() => new Future.value(3);
+        Future<int> f4() async => new Future.value(3);
+        Future<int> f5() async => await new Future.value(3);
+
+        Future g0() { return new Future.value(3); }
+        Future g1() async { return new Future.value(3); }
+        Future g2() async { return await new Future.value(3); }
+
+        Future<int> g3() { return new Future.value(3); }
+        Future<int> g4() async { return new Future.value(3); }
+        Future<int> g5() async { return await new Future.value(3); }
+      }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
+      FunctionBody body = test.body;
+      Expression returnExp;
+      if (body is ExpressionFunctionBody) {
+        returnExp = body.expression;
+      } else {
+        ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
+        returnExp = stmt.expression;
+      }
+      DartType type = returnExp.staticType;
+      if (returnExp is AwaitExpression) {
+        type = returnExp.expression.staticType;
+      }
+      typeTest(type);
+    }
+
+    check("f0", _isFutureOfDynamic);
+    check("f1", _isFutureOfDynamic);
+    check("f2", _isFutureOfDynamic);
+
+    check("f3", _isFutureOfInt);
+    // This should be int when we handle the implicit Future<T> | T union
+    // https://github.com/dart-lang/sdk/issues/25322
+    check("f4", _isFutureOfDynamic);
+    check("f5", _isFutureOfInt);
+
+    check("g0", _isFutureOfDynamic);
+    check("g1", _isFutureOfDynamic);
+    check("g2", _isFutureOfDynamic);
+
+    check("g3", _isFutureOfInt);
+    // This should be int when we handle the implicit Future<T> | T union
+    // https://github.com/dart-lang/sdk/issues/25322
+    check("g4", _isFutureOfDynamic);
+    check("g5", _isFutureOfInt);
+  }
+
+  void test_async_propagation() {
+    String code = r'''
+      import "dart:async";
+
+      Future f0() => new Future.value(3);
+      Future f1() async => new Future.value(3);
+      Future f2() async => await new Future.value(3);
+
+      Future<int> f3() => new Future.value(3);
+      Future<int> f4() async => new Future.value(3);
+      Future<int> f5() async => await new Future.value(3);
+
+      Future g0() { return new Future.value(3); }
+      Future g1() async { return new Future.value(3); }
+      Future g2() async { return await new Future.value(3); }
+
+      Future<int> g3() { return new Future.value(3); }
+      Future<int> g4() async { return new Future.value(3); }
+      Future<int> g5() async { return await new Future.value(3); }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
+      FunctionBody body = test.functionExpression.body;
+      Expression returnExp;
+      if (body is ExpressionFunctionBody) {
+        returnExp = body.expression;
+      } else {
+        ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
+        returnExp = stmt.expression;
+      }
+      DartType type = returnExp.staticType;
+      if (returnExp is AwaitExpression) {
+        type = returnExp.expression.staticType;
+      }
+      typeTest(type);
+    }
+
+    check("f0", _isFutureOfDynamic);
+    check("f1", _isFutureOfDynamic);
+    check("f2", _isFutureOfDynamic);
+
+    check("f3", _isFutureOfInt);
+    // This should be int when we handle the implicit Future<T> | T union
+    // https://github.com/dart-lang/sdk/issues/25322
+    check("f4", _isFutureOfDynamic);
+    check("f5", _isFutureOfInt);
+
+    check("g0", _isFutureOfDynamic);
+    check("g1", _isFutureOfDynamic);
+    check("g2", _isFutureOfDynamic);
+
+    check("g3", _isFutureOfInt);
+    // This should be int when we handle the implicit Future<T> | T union
+    // https://github.com/dart-lang/sdk/issues/25322
+    check("g4", _isFutureOfDynamic);
+    check("g5", _isFutureOfInt);
+  }
+
+  void test_async_star_method_propagation() {
+    String code = r'''
+      import "dart:async";
+      class A {
+        Stream g0() async* { yield []; }
+        Stream g1() async* { yield* new Stream(); }
+
+        Stream<List<int>> g2() async* { yield []; }
+        Stream<List<int>> g3() async* { yield* new Stream(); }
+      }
+    ''';
+    CompilationUnit unit = resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
+      BlockFunctionBody body = test.body;
+      YieldStatement stmt = body.block.statements[0];
+      Expression exp = stmt.expression;
+      typeTest(exp.staticType);
+    }
+
+    check("g0", _isListOf(_isDynamic));
+    check("g1", _isStreamOf([_isDynamic]));
+
+    check("g2", _isListOf(_isInt));
+    check("g3", _isStreamOf([_isListOf(_isInt)]));
+  }
+
+  void test_async_star_propagation() {
+    String code = r'''
+      import "dart:async";
+
+      Stream g0() async* { yield []; }
+      Stream g1() async* { yield* new Stream(); }
+
+      Stream<List<int>> g2() async* { yield []; }
+      Stream<List<int>> g3() async* { yield* new Stream(); }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
+      BlockFunctionBody body = test.functionExpression.body;
+      YieldStatement stmt = body.block.statements[0];
+      Expression exp = stmt.expression;
+      typeTest(exp.staticType);
+    }
+
+    check("g0", _isListOf(_isDynamic));
+    check("g1", _isStreamOf([_isDynamic]));
+
+    check("g2", _isListOf(_isInt));
+    check("g3", _isStreamOf([_isListOf(_isInt)]));
+  }
+
+  void test_cascadeExpression() {
+    String code = r'''
+      class A<T> {
+        List<T> map(T a, List<T> mapper(T x)) => mapper(a);
+      }
+
+      void main () {
+        A<int> a = new A()..map(0, (x) => [x]);
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    CascadeExpression fetch(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      CascadeExpression exp = decl.initializer;
+      return exp;
+    }
+    Element elementA = AstFinder.getClass(unit, "A").element;
+
+    CascadeExpression cascade = fetch(0);
+    _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType);
+    MethodInvocation invoke = cascade.cascadeSections[0];
+    FunctionExpression function = invoke.argumentList.arguments[1];
+    ExecutableElement f0 = function.element;
+    _isListOf(_isInt)(f0.type.returnType);
+    expect(f0.type.normalParameterTypes[0], typeProvider.intType);
+  }
+
+  void test_constructorInitializer_propagation() {
+    String code = r'''
+      class A {
+        List<String> x;
+        A() : this.x = [];
+      }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    ConstructorDeclaration constructor =
+        AstFinder.getConstructorInClass(unit, "A", null);
+    ConstructorFieldInitializer assignment = constructor.initializers[0];
+    Expression exp = assignment.expression;
+    _isListOf(_isString)(exp.staticType);
+  }
+
+  void test_factoryConstructor_propagation() {
+    String code = r'''
+      class A<T> {
+        factory A() { return new B(); }
+      }
+      class B<S> extends A<S> {}
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    ConstructorDeclaration constructor =
+        AstFinder.getConstructorInClass(unit, "A", null);
+    BlockFunctionBody body = constructor.body;
+    ReturnStatement stmt = body.block.statements[0];
+    InstanceCreationExpression exp = stmt.expression;
+    ClassElement elementB = AstFinder.getClass(unit, "B").element;
+    ClassElement elementA = AstFinder.getClass(unit, "A").element;
+    expect(exp.constructorName.type.type.element, elementB);
+    _isInstantiationOf(_hasElement(elementB))(
+        [_isType(elementA.typeParameters[0].type)])(exp.staticType);
+  }
+
+  void test_fieldDeclaration_propagation() {
+    String code = r'''
+      class A {
+        List<String> f0 = ["hello"];
+      }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    VariableDeclaration field = AstFinder.getFieldInClass(unit, "A", "f0");
+
+    _isListOf(_isString)(field.initializer.staticType);
+  }
+
+  void test_functionDeclaration_body_propagation() {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      List<int> test1() => [];
+
+      Function2<int, int> test2 (int x) {
+        Function2<String, int> inner() {
+          return (x) => x.length;
+        }
+        return (x) => x;
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+    FunctionDeclaration test1 = AstFinder.getTopLevelFunction(unit, "test1");
+    ExpressionFunctionBody body = test1.functionExpression.body;
+    assertListOfInt(body.expression.staticType);
+
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test2");
+
+    FunctionDeclaration inner =
+        (statements[0] as FunctionDeclarationStatement).functionDeclaration;
+    BlockFunctionBody body0 = inner.functionExpression.body;
+    ReturnStatement return0 = body0.block.statements[0];
+    Expression anon0 = return0.expression;
+    FunctionType type0 = anon0.staticType;
+    expect(type0.returnType, typeProvider.intType);
+    expect(type0.normalParameterTypes[0], typeProvider.stringType);
+
+    FunctionExpression anon1 = (statements[1] as ReturnStatement).expression;
+    FunctionType type1 = anon1.element.type;
+    expect(type1.returnType, typeProvider.intType);
+    expect(type1.normalParameterTypes[0], typeProvider.intType);
+  }
+
+  void test_functionLiteral_assignment_typedArguments() {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      void main () {
+        Function2<int, String> l0 = (int x) => null;
+        Function2<int, String> l1 = (int x) => "hello";
+        Function2<int, String> l2 = (String x) => "hello";
+        Function2<int, String> l3 = (int x) => 3;
+        Function2<int, String> l4 = (int x) {return 3;};
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      FunctionExpression exp = decl.initializer;
+      return exp.element.type;
+    }
+    _isFunction2Of(_isInt, _isString)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isString, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isInt)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  void test_functionLiteral_assignment_unTypedArguments() {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      void main () {
+        Function2<int, String> l0 = (x) => null;
+        Function2<int, String> l1 = (x) => "hello";
+        Function2<int, String> l2 = (x) => "hello";
+        Function2<int, String> l3 = (x) => 3;
+        Function2<int, String> l4 = (x) {return 3;};
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      FunctionExpression exp = decl.initializer;
+      return exp.element.type;
+    }
+    _isFunction2Of(_isInt, _isString)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isInt, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isInt)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  void test_functionLiteral_body_propagation() {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      void main () {
+        Function2<int, List<String>> l0 = (int x) => ["hello"];
+        Function2<int, List<String>> l1 = (String x) => ["hello"];
+        Function2<int, List<String>> l2 = (int x) => [3];
+        Function2<int, List<String>> l3 = (int x) {return [3];};
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    Expression functionReturnValue(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      FunctionExpression exp = decl.initializer;
+      FunctionBody body = exp.body;
+      if (body is ExpressionFunctionBody) {
+        return body.expression;
+      } else {
+        Statement stmt = (body as BlockFunctionBody).block.statements[0];
+        return (stmt as ReturnStatement).expression;
+      }
+    }
+    Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
+    assertListOfString(functionReturnValue(0).staticType);
+    assertListOfString(functionReturnValue(1).staticType);
+    assertListOfString(functionReturnValue(2).staticType);
+    assertListOfString(functionReturnValue(3).staticType);
+  }
+
+  void test_functionLiteral_functionExpressionInvocation_typedArguments() {
+    String code = r'''
+      class Mapper<F, T> {
+        T map(T mapper(F x)) => mapper(null);
+      }
+
+      void main () {
+        (new Mapper<int, String>().map)((int x) => null);
+        (new Mapper<int, String>().map)((int x) => "hello");
+        (new Mapper<int, String>().map)((String x) => "hello");
+        (new Mapper<int, String>().map)((int x) => 3);
+        (new Mapper<int, String>().map)((int x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      FunctionExpressionInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return exp.element.type;
+    }
+    _isFunction2Of(_isInt, _isString)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isString, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isInt)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  void test_functionLiteral_functionExpressionInvocation_unTypedArguments() {
+    String code = r'''
+      class Mapper<F, T> {
+        T map(T mapper(F x)) => mapper(null);
+      }
+
+      void main () {
+        (new Mapper<int, String>().map)((x) => null);
+        (new Mapper<int, String>().map)((x) => "hello");
+        (new Mapper<int, String>().map)((x) => "hello");
+        (new Mapper<int, String>().map)((x) => 3);
+        (new Mapper<int, String>().map)((x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      FunctionExpressionInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return exp.element.type;
+    }
+    _isFunction2Of(_isInt, _isString)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isInt, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isInt)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  void test_functionLiteral_functionInvocation_typedArguments() {
+    String code = r'''
+      String map(String mapper(int x)) => mapper(null);
+
+      void main () {
+        map((int x) => null);
+        map((int x) => "hello");
+        map((String x) => "hello");
+        map((int x) => 3);
+        map((int x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      MethodInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return exp.element.type;
+    }
+    _isFunction2Of(_isInt, _isString)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isString, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isInt)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  void test_functionLiteral_functionInvocation_unTypedArguments() {
+    String code = r'''
+      String map(String mapper(int x)) => mapper(null);
+
+      void main () {
+        map((x) => null);
+        map((x) => "hello");
+        map((x) => "hello");
+        map((x) => 3);
+        map((x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      MethodInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return exp.element.type;
+    }
+    _isFunction2Of(_isInt, _isString)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isInt, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isInt)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  void test_functionLiteral_methodInvocation_typedArguments() {
+    String code = r'''
+      class Mapper<F, T> {
+        T map(T mapper(F x)) => mapper(null);
+      }
+
+      void main () {
+        new Mapper<int, String>().map((int x) => null);
+        new Mapper<int, String>().map((int x) => "hello");
+        new Mapper<int, String>().map((String x) => "hello");
+        new Mapper<int, String>().map((int x) => 3);
+        new Mapper<int, String>().map((int x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      MethodInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return exp.element.type;
+    }
+    _isFunction2Of(_isInt, _isString)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isString, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isInt)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  void test_functionLiteral_methodInvocation_unTypedArguments() {
+    String code = r'''
+      class Mapper<F, T> {
+        T map(T mapper(F x)) => mapper(null);
+      }
+
+      void main () {
+        new Mapper<int, String>().map((x) => null);
+        new Mapper<int, String>().map((x) => "hello");
+        new Mapper<int, String>().map((x) => "hello");
+        new Mapper<int, String>().map((x) => 3);
+        new Mapper<int, String>().map((x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      MethodInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return exp.element.type;
+    }
+    _isFunction2Of(_isInt, _isString)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isInt, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isInt)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  void test_functionLiteral_unTypedArgument_propagation() {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      void main () {
+        Function2<int, int> l0 = (x) => x;
+        Function2<int, int> l1 = (x) => x+1;
+        Function2<int, String> l2 = (x) => x;
+        Function2<int, String> l3 = (x) => x.toLowerCase();
+        Function2<String, String> l4 = (x) => x.toLowerCase();
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    Expression functionReturnValue(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      FunctionExpression exp = decl.initializer;
+      FunctionBody body = exp.body;
+      if (body is ExpressionFunctionBody) {
+        return body.expression;
+      } else {
+        Statement stmt = (body as BlockFunctionBody).block.statements[0];
+        return (stmt as ReturnStatement).expression;
+      }
+    }
+    expect(functionReturnValue(0).staticType, typeProvider.intType);
+    expect(functionReturnValue(1).staticType, typeProvider.intType);
+    expect(functionReturnValue(2).staticType, typeProvider.intType);
+    expect(functionReturnValue(3).staticType, typeProvider.dynamicType);
+    expect(functionReturnValue(4).staticType, typeProvider.stringType);
+  }
+
+  void test_inference_hints() {
+    Source source = addSource(r'''
+      void main () {
+        var x = 3;
+        List<int> l0 = [];
+     }
+   ''');
+    resolve2(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_instanceCreation() {
+    String code = r'''
+      class A<S, T> {
+        S x;
+        T y;
+        A(this.x, this.y);
+        A.named(this.x, this.y);
+      }
+
+      class B<S, T> extends A<T, S> {
+        B(S y, T x) : super(x, y);
+        B.named(S y, T x) : super.named(x, y);
+      }
+
+      class C<S> extends B<S, S> {
+        C(S a) : super(a, a);
+        C.named(S a) : super.named(a, a);
+      }
+
+      class D<S, T> extends B<T, int> {
+        D(T a) : super(a, 3);
+        D.named(T a) : super.named(a, 3);
+      }
+
+      class E<S, T> extends A<C<S>, T> {
+        E(T a) : super(null, a);
+      }
+
+      class F<S, T> extends A<S, T> {
+        F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
+        F.named(S x, T y, [S a, T b]) : super(a, b);
+      }
+
+      void test0() {
+        A<int, String> a0 = new A(3, "hello");
+        A<int, String> a1 = new A.named(3, "hello");
+        A<int, String> a2 = new A<int, String>(3, "hello");
+        A<int, String> a3 = new A<int, String>.named(3, "hello");
+        A<int, String> a4 = new A<int, dynamic>(3, "hello");
+        A<int, String> a5 = new A<dynamic, dynamic>.named(3, "hello");
+      }
+      void test1()  {
+        A<int, String> a0 = new A("hello", 3);
+        A<int, String> a1 = new A.named("hello", 3);
+      }
+      void test2() {
+        A<int, String> a0 = new B("hello", 3);
+        A<int, String> a1 = new B.named("hello", 3);
+        A<int, String> a2 = new B<String, int>("hello", 3);
+        A<int, String> a3 = new B<String, int>.named("hello", 3);
+        A<int, String> a4 = new B<String, dynamic>("hello", 3);
+        A<int, String> a5 = new B<dynamic, dynamic>.named("hello", 3);
+      }
+      void test3() {
+        A<int, String> a0 = new B(3, "hello");
+        A<int, String> a1 = new B.named(3, "hello");
+      }
+      void test4() {
+        A<int, int> a0 = new C(3);
+        A<int, int> a1 = new C.named(3);
+        A<int, int> a2 = new C<int>(3);
+        A<int, int> a3 = new C<int>.named(3);
+        A<int, int> a4 = new C<dynamic>(3);
+        A<int, int> a5 = new C<dynamic>.named(3);
+      }
+      void test5() {
+        A<int, int> a0 = new C("hello");
+        A<int, int> a1 = new C.named("hello");
+      }
+      void test6()  {
+        A<int, String> a0 = new D("hello");
+        A<int, String> a1 = new D.named("hello");
+        A<int, String> a2 = new D<int, String>("hello");
+        A<int, String> a3 = new D<String, String>.named("hello");
+        A<int, String> a4 = new D<num, dynamic>("hello");
+        A<int, String> a5 = new D<dynamic, dynamic>.named("hello");
+      }
+      void test7() {
+        A<int, String> a0 = new D(3);
+        A<int, String> a1 = new D.named(3);
+      }
+      void test8() {
+        // Currently we only allow variable constraints.  Test that we reject.
+        A<C<int>, String> a0 = new E("hello");
+      }
+      void test9() { // Check named and optional arguments
+        A<int, String> a0 = new F(3, "hello", a: [3], b: ["hello"]);
+        A<int, String> a1 = new F(3, "hello", a: ["hello"], b:[3]);
+        A<int, String> a2 = new F.named(3, "hello", 3, "hello");
+        A<int, String> a3 = new F.named(3, "hello");
+        A<int, String> a4 = new F.named(3, "hello", "hello", 3);
+        A<int, String> a5 = new F.named(3, "hello", "hello");
+      }
+    }''';
+    CompilationUnit unit = resolveSource(code);
+
+    Expression rhs(VariableDeclarationStatement stmt) {
+      VariableDeclaration decl = stmt.variables.variables[0];
+      Expression exp = decl.initializer;
+      return exp;
+    }
+
+    void hasType(Asserter<DartType> assertion, Expression exp) =>
+        assertion(exp.staticType);
+
+    Element elementA = AstFinder.getClass(unit, "A").element;
+    Element elementB = AstFinder.getClass(unit, "B").element;
+    Element elementC = AstFinder.getClass(unit, "C").element;
+    Element elementD = AstFinder.getClass(unit, "D").element;
+    Element elementE = AstFinder.getClass(unit, "E").element;
+    Element elementF = AstFinder.getClass(unit, "F").element;
+
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf =
+        _isInstantiationOf(_hasElement(elementA));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf =
+        _isInstantiationOf(_hasElement(elementB));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertCOf =
+        _isInstantiationOf(_hasElement(elementC));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertDOf =
+        _isInstantiationOf(_hasElement(elementD));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf =
+        _isInstantiationOf(_hasElement(elementE));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertFOf =
+        _isInstantiationOf(_hasElement(elementF));
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test0");
+
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[2]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[3]));
+      hasType(assertAOf([_isInt, _isDynamic]), rhs(statements[4]));
+      hasType(assertAOf([_isDynamic, _isDynamic]), rhs(statements[5]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test1");
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test2");
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[2]));
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[3]));
+      hasType(assertBOf([_isString, _isDynamic]), rhs(statements[4]));
+      hasType(assertBOf([_isDynamic, _isDynamic]), rhs(statements[5]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test3");
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test4");
+      hasType(assertCOf([_isInt]), rhs(statements[0]));
+      hasType(assertCOf([_isInt]), rhs(statements[1]));
+      hasType(assertCOf([_isInt]), rhs(statements[2]));
+      hasType(assertCOf([_isInt]), rhs(statements[3]));
+      hasType(assertCOf([_isDynamic]), rhs(statements[4]));
+      hasType(assertCOf([_isDynamic]), rhs(statements[5]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test5");
+      hasType(assertCOf([_isInt]), rhs(statements[0]));
+      hasType(assertCOf([_isInt]), rhs(statements[1]));
+    }
+
+    {
+      // The first type parameter is not constrained by the
+      // context.  We could choose a tighter type, but currently
+      // we just use dynamic.
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test6");
+      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
+      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
+      hasType(assertDOf([_isInt, _isString]), rhs(statements[2]));
+      hasType(assertDOf([_isString, _isString]), rhs(statements[3]));
+      hasType(assertDOf([_isNum, _isDynamic]), rhs(statements[4]));
+      hasType(assertDOf([_isDynamic, _isDynamic]), rhs(statements[5]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test7");
+      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
+      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test8");
+      hasType(assertEOf([_isDynamic, _isDynamic]), rhs(statements[0]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test9");
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[0]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[1]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[2]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[3]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[4]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[5]));
+    }
+  }
+
+  void test_listLiteral_nested() {
+    String code = r'''
+      void main () {
+        List<List<int>> l0 = [[]];
+        Iterable<List<int>> l1 = [[3]];
+        Iterable<List<int>> l2 = [[3], [4]];
+        List<List<int>> l3 = [["hello", 3], []];
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    ListLiteral literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp;
+    }
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+    Asserter<InterfaceType> assertListOfListOfInt = _isListOf(assertListOfInt);
+
+    assertListOfListOfInt(literal(0).staticType);
+    assertListOfListOfInt(literal(1).staticType);
+    assertListOfListOfInt(literal(2).staticType);
+    assertListOfListOfInt(literal(3).staticType);
+
+    assertListOfInt(literal(1).elements[0].staticType);
+    assertListOfInt(literal(2).elements[0].staticType);
+    assertListOfInt(literal(3).elements[0].staticType);
+  }
+
+  void test_listLiteral_simple() {
+    String code = r'''
+      void main () {
+        List<int> l0 = [];
+        List<int> l1 = [3];
+        List<int> l2 = ["hello"];
+        List<int> l3 = ["hello", 3];
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+    assertListOfInt(literal(0));
+    assertListOfInt(literal(1));
+    assertListOfInt(literal(2));
+    assertListOfInt(literal(3));
+  }
+
+  void test_listLiteral_simple_const() {
+    String code = r'''
+      void main () {
+        const List<int> c0 = const [];
+        const List<int> c1 = const [3];
+        const List<int> c2 = const ["hello"];
+        const List<int> c3 = const ["hello", 3];
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+    assertListOfInt(literal(0));
+    assertListOfInt(literal(1));
+    assertListOfInt(literal(2));
+    assertListOfInt(literal(3));
+  }
+
+  void test_listLiteral_simple_disabled() {
+    String code = r'''
+      void main () {
+        List<int> l0 = <num>[];
+        List<int> l1 = <num>[3];
+        List<int> l2 = <String>["hello"];
+        List<int> l3 = <dynamic>["hello", 3];
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    _isListOf(_isNum)(literal(0));
+    _isListOf(_isNum)(literal(1));
+    _isListOf(_isString)(literal(2));
+    _isListOf(_isDynamic)(literal(3));
+  }
+
+  void test_listLiteral_simple_subtype() {
+    String code = r'''
+      void main () {
+        Iterable<int> l0 = [];
+        Iterable<int> l1 = [3];
+        Iterable<int> l2 = ["hello"];
+        Iterable<int> l3 = ["hello", 3];
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+    assertListOfInt(literal(0));
+    assertListOfInt(literal(1));
+    assertListOfInt(literal(2));
+    assertListOfInt(literal(3));
+  }
+
+  void test_mapLiteral_nested() {
+    String code = r'''
+      void main () {
+        Map<int, List<String>> l0 = {};
+        Map<int, List<String>> l1 = {3: ["hello"]};
+        Map<int, List<String>> l2 = {"hello": ["hello"]};
+        Map<int, List<String>> l3 = {3: [3]};
+        Map<int, List<String>> l4 = {3:["hello"], "hello": [3]};
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    MapLiteral literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      MapLiteral exp = decl.initializer;
+      return exp;
+    }
+
+    Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
+    Asserter<InterfaceType> assertMapOfIntToListOfString =
+        _isMapOf(_isInt, assertListOfString);
+
+    assertMapOfIntToListOfString(literal(0).staticType);
+    assertMapOfIntToListOfString(literal(1).staticType);
+    assertMapOfIntToListOfString(literal(2).staticType);
+    assertMapOfIntToListOfString(literal(3).staticType);
+    assertMapOfIntToListOfString(literal(4).staticType);
+
+    assertListOfString(literal(1).entries[0].value.staticType);
+    assertListOfString(literal(2).entries[0].value.staticType);
+    assertListOfString(literal(3).entries[0].value.staticType);
+    assertListOfString(literal(4).entries[0].value.staticType);
+  }
+
+  void test_mapLiteral_simple() {
+    String code = r'''
+      void main () {
+        Map<int, String> l0 = {};
+        Map<int, String> l1 = {3: "hello"};
+        Map<int, String> l2 = {"hello": "hello"};
+        Map<int, String> l3 = {3: 3};
+        Map<int, String> l4 = {3:"hello", "hello": 3};
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      MapLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertMapOfIntToString =
+        _isMapOf(_isInt, _isString);
+
+    assertMapOfIntToString(literal(0));
+    assertMapOfIntToString(literal(1));
+    assertMapOfIntToString(literal(2));
+    assertMapOfIntToString(literal(3));
+  }
+
+  void test_mapLiteral_simple_disabled() {
+    String code = r'''
+      void main () {
+        Map<int, String> l0 = <int, dynamic>{};
+        Map<int, String> l1 = <int, dynamic>{3: "hello"};
+        Map<int, String> l2 = <int, dynamic>{"hello": "hello"};
+        Map<int, String> l3 = <int, dynamic>{3: 3};
+     }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      MapLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertMapOfIntToDynamic =
+        _isMapOf(_isInt, _isDynamic);
+
+    assertMapOfIntToDynamic(literal(0));
+    assertMapOfIntToDynamic(literal(1));
+    assertMapOfIntToDynamic(literal(2));
+    assertMapOfIntToDynamic(literal(3));
+  }
+
+  void test_methodDeclaration_body_propagation() {
+    String code = r'''
+      class A {
+        List<String> m0(int x) => ["hello"];
+        List<String> m1(int x) {return [3];};
+      }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+    Expression methodReturnValue(String methodName) {
+      MethodDeclaration method =
+          AstFinder.getMethodInClass(unit, "A", methodName);
+      FunctionBody body = method.body;
+      if (body is ExpressionFunctionBody) {
+        return body.expression;
+      } else {
+        Statement stmt = (body as BlockFunctionBody).block.statements[0];
+        return (stmt as ReturnStatement).expression;
+      }
+    }
+    Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
+    assertListOfString(methodReturnValue("m0").staticType);
+    assertListOfString(methodReturnValue("m1").staticType);
+  }
+
+  void test_redirectingConstructor_propagation() {
+    String code = r'''
+      class A {
+        A() : this.named([]);
+        A.named(List<String> x);
+      }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    ConstructorDeclaration constructor =
+        AstFinder.getConstructorInClass(unit, "A", null);
+    RedirectingConstructorInvocation invocation = constructor.initializers[0];
+    Expression exp = invocation.argumentList.arguments[0];
+    _isListOf(_isString)(exp.staticType);
+  }
+
+  void test_superConstructorInvocation_propagation() {
+    String code = r'''
+      class B {
+        B(List<String>);
+      }
+      class A extends B {
+        A() : super([]);
+      }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    ConstructorDeclaration constructor =
+        AstFinder.getConstructorInClass(unit, "A", null);
+    SuperConstructorInvocation invocation = constructor.initializers[0];
+    Expression exp = invocation.argumentList.arguments[0];
+    _isListOf(_isString)(exp.staticType);
+  }
+
+  void test_sync_star_method_propagation() {
+    String code = r'''
+      import "dart:async";
+      class A {
+        Iterable f0() sync* { yield []; }
+        Iterable f1() sync* { yield* new List(); }
+
+        Iterable<List<int>> f2() sync* { yield []; }
+        Iterable<List<int>> f3() sync* { yield* new List(); }
+      }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
+      BlockFunctionBody body = test.body;
+      YieldStatement stmt = body.block.statements[0];
+      Expression exp = stmt.expression;
+      typeTest(exp.staticType);
+    }
+
+    check("f0", _isListOf(_isDynamic));
+    check("f1", _isListOf(_isDynamic));
+
+    check("f2", _isListOf(_isInt));
+    check("f3", _isListOf(_isListOf(_isInt)));
+  }
+
+  void test_sync_star_propagation() {
+    String code = r'''
+      import "dart:async";
+
+      Iterable f0() sync* { yield []; }
+      Iterable f1() sync* { yield* new List(); }
+
+      Iterable<List<int>> f2() sync* { yield []; }
+      Iterable<List<int>> f3() sync* { yield* new List(); }
+   ''';
+    CompilationUnit unit = resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
+      BlockFunctionBody body = test.functionExpression.body;
+      YieldStatement stmt = body.block.statements[0];
+      Expression exp = stmt.expression;
+      typeTest(exp.staticType);
+    }
+
+    check("f0", _isListOf(_isDynamic));
+    check("f1", _isListOf(_isDynamic));
+
+    check("f2", _isListOf(_isInt));
+    check("f3", _isListOf(_isListOf(_isInt)));
+  }
+}
+
+/**
  * Strong mode static analyzer end to end tests
  */
 @reflectiveTest
 class StrongModeStaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared {
+  void test_genericMethod_functionExpressionInvocation_explicit() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+
+  var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3);
+  var methodCall = (c.f)/*<int>*/(3);
+  var staticCall = (C.g)/*<int>*/(3);
+  var staticFieldCall = (C.h)/*<int>*/(3);
+  var topFunCall = (topF)/*<int>*/(3);
+  var topFieldCall = (topG)/*<int>*/(3);
+  var localCall = (lf)/*<int>*/(3);
+  var paramCall = (pf)/*<int>*/(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
+  }
+
+  void fail_genericMethod_functionExpressionInvocation_inferred() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+
+  var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3);
+  var methodCall = (c.f)(3);
+  var staticCall = (C.g)(3);
+  var staticFieldCall = (C.h)(3);
+  var topFunCall = (topF)(3);
+  var topFieldCall = (topG)(3);
+  var localCall = (lf)(3);
+  var paramCall = (pf)(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
+  }
+
+  void fail_genericMethod_functionInvocation_inferred() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+  var methodCall = c.f(3);
+  var staticCall = C.g(3);
+  var staticFieldCall = C.h(3);
+  var topFunCall = topF(3);
+  var topFieldCall = topG(3);
+  var localCall = lf(3);
+  var paramCall = pf(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+  }
+
+  void fail_genericMethod_tearoff_instantiated() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(E e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+  var methodTearOffInst = c.f/*<int>*/;
+  var staticTearOffInst = C.g/*<int>*/;
+  var staticFieldTearOffInst = C.h/*<int>*/;
+  var topFunTearOffInst = topF/*<int>*/;
+  var topFieldTearOffInst = topG/*<int>*/;
+  var localTearOffInst = lf/*<int>*/;
+  var paramTearOffInst = pf/*<int>*/;
+}
+''');
+    expect(_findIdentifier('methodTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('staticTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('staticFieldTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('topFunTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('topFieldTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('localTearOffInst').staticType.toString(),
+        "(int) → int");
+    expect(_findIdentifier('paramTearOffInst').staticType.toString(),
+        "(int) → int");
+  }
+
   void setUp() {
+    super.setUp();
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.strongMode = true;
     resetWithOptions(options);
@@ -11938,6 +13206,425 @@
     expect(declaration.initializer.propagatedType, isNull);
   }
 
+  void test_genericFunction() {
+    _resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;');
+    SimpleIdentifier f = _findIdentifier('f');
+    FunctionElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
+    expect(e.type.typeParameters.toString(), '[]');
+    expect(e.type.toString(), '<T>(T) → T');
+
+    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  void test_genericFunction_bounds() {
+    _resolveTestUnit(r'/*=T*/ f/*<T extends num>*/(/*=T*/ x) => null;');
+    SimpleIdentifier f = _findIdentifier('f');
+    FunctionElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T extends num]');
+    expect(e.type.typeFormals.toString(), '[T extends num]');
+    expect(e.type.typeParameters.toString(), '[]');
+    expect(e.type.toString(), '<T extends num>(T) → T');
+  }
+
+  void test_genericFunction_parameter() {
+    _resolveTestUnit(r'''
+void g(/*=T*/ f/*<T>*/(/*=T*/ x)) {}
+''');
+    SimpleIdentifier f = _findIdentifier('f');
+    ParameterElementImpl e = f.staticElement;
+    FunctionType type = e.type;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(type.typeFormals.toString(), '[T]');
+    expect(type.toString(), '<T>(T) → T');
+    FunctionType ft = type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  void test_genericFunction_static() {
+    _resolveTestUnit(r'''
+class C<E> {
+  static /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+''');
+    SimpleIdentifier f = _findIdentifier('f');
+    MethodElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
+    // TODO(jmesserly): we could get rid of this {E/E} substitution, but it's
+    // probably harmless, as E won't be used in the function (error verifier
+    // checks this), and {E/E} is a no-op anyway.
+    expect(e.type.typeParameters.toString(), '[E]');
+    expect(e.type.typeArguments.toString(), '[E]');
+    expect(e.type.toString(), '<T>(T) → T');
+
+    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  void test_genericFunction_typedef() {
+    String code = r'''
+typedef T F<T>(T x);
+F f0;
+
+class C {
+  static F f1;
+  F f2;
+  void g(F f3) {
+    F f4;
+    f0(3);
+    f1(3);
+    f2(3);
+    f3(3);
+    f4(3);
+  }
+}
+
+class D<S> {
+  static F f1;
+  F f2;
+  void g(F f3) {
+    F f4;
+    f0(3);
+    f1(3);
+    f2(3);
+    f3(3);
+    f4(3);
+  }
+}
+''';
+    _resolveTestUnit(code);
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInMethod(testUnit, "C", "g");
+
+      ExpressionStatement exps0 = statements[1];
+      ExpressionStatement exps1 = statements[2];
+      ExpressionStatement exps2 = statements[3];
+      ExpressionStatement exps3 = statements[4];
+      ExpressionStatement exps4 = statements[5];
+      Expression exp0 = exps0.expression;
+      Expression exp1 = exps1.expression;
+      Expression exp2 = exps2.expression;
+      Expression exp3 = exps3.expression;
+      Expression exp4 = exps4.expression;
+      expect(exp0.staticType, typeProvider.dynamicType);
+      expect(exp1.staticType, typeProvider.dynamicType);
+      expect(exp2.staticType, typeProvider.dynamicType);
+      expect(exp3.staticType, typeProvider.dynamicType);
+      expect(exp4.staticType, typeProvider.dynamicType);
+    }
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInMethod(testUnit, "D", "g");
+
+      ExpressionStatement exps0 = statements[1];
+      ExpressionStatement exps1 = statements[2];
+      ExpressionStatement exps2 = statements[3];
+      ExpressionStatement exps3 = statements[4];
+      ExpressionStatement exps4 = statements[5];
+      Expression exp0 = exps0.expression;
+      Expression exp1 = exps1.expression;
+      Expression exp2 = exps2.expression;
+      Expression exp3 = exps3.expression;
+      Expression exp4 = exps4.expression;
+      expect(exp0.staticType, typeProvider.dynamicType);
+      expect(exp1.staticType, typeProvider.dynamicType);
+      expect(exp2.staticType, typeProvider.dynamicType);
+      expect(exp3.staticType, typeProvider.dynamicType);
+      expect(exp4.staticType, typeProvider.dynamicType);
+    }
+  }
+
+  void test_genericMethod() {
+    _resolveTestUnit(r'''
+class C<E> {
+  List/*<T>*/ f/*<T>*/(E e) => null;
+}
+main() {
+  C<String> cOfString;
+}
+''');
+    SimpleIdentifier f = _findIdentifier('f');
+    MethodElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
+    expect(e.type.typeParameters.toString(), '[E]');
+    expect(e.type.typeArguments.toString(), '[E]');
+    expect(e.type.toString(), '<T>(E) → List<T>');
+
+    SimpleIdentifier c = _findIdentifier('cOfString');
+    FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
+    expect(ft.toString(), '<T>(String) → List<T>');
+    ft = ft.instantiate([typeProvider.intType]);
+    expect(ft.toString(), '(String) → List<int>');
+    expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
+  }
+
+  void test_genericMethod_explicitTypeParams() {
+    _resolveTestUnit(r'''
+class C<E> {
+  List/*<T>*/ f/*<T>*/(E e) => null;
+}
+main() {
+  C<String> cOfString;
+  var x = cOfString.f/*<int>*/('hi');
+}
+''');
+    MethodInvocation f = _findIdentifier('f/*<int>*/').parent;
+    FunctionType ft = f.staticInvokeType;
+    expect(ft.toString(), '(String) → List<int>');
+    expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
+
+    SimpleIdentifier x = _findIdentifier('x');
+    expect(x.staticType,
+        typeProvider.listType.substitute4([typeProvider.intType]));
+  }
+
+  void test_genericMethod_functionInvocation_explicit() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+  var methodCall = c.f/*<int>*/(3);
+  var staticCall = C.g/*<int>*/(3);
+  var staticFieldCall = C.h/*<int>*/(3);
+  var topFunCall = topF/*<int>*/(3);
+  var topFieldCall = topG/*<int>*/(3);
+  var localCall = lf/*<int>*/(3);
+  var paramCall = pf/*<int>*/(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+  }
+
+  void test_genericMethod_functionTypedParameter() {
+    _resolveTestUnit(r'''
+class C<E> {
+  List/*<T>*/ f/*<T>*/(/*=T*/ f(E e)) => null;
+}
+main() {
+  C<String> cOfString;
+}
+''');
+    SimpleIdentifier f = _findIdentifier('f');
+    MethodElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
+    expect(e.type.typeParameters.toString(), '[E]');
+    expect(e.type.typeArguments.toString(), '[E]');
+    expect(e.type.toString(), '<T>((E) → T) → List<T>');
+
+    SimpleIdentifier c = _findIdentifier('cOfString');
+    FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
+    expect(ft.toString(), '<T>((String) → T) → List<T>');
+    ft = ft.instantiate([typeProvider.intType]);
+    expect(ft.toString(), '((String) → int) → List<int>');
+  }
+
+  void test_genericMethod_implicitDynamic() {
+    // Regression test for:
+    // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
+    // These should not cause any hints or warnings.
+    _resolveTestUnit(r'''
+class List<E> {
+  /*=T*/ map/*<T>*/(/*=T*/ f(E e)) => null;
+}
+void foo() {
+  List list = null;
+  list.map((e) => e);
+  list.map((e) => 3);
+}''');
+
+    SimpleIdentifier map1 = _findIdentifier('map((e) => e);');
+    MethodInvocation m1 = map1.parent;
+    expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
+    expect(map1.staticType, isNull);
+    expect(map1.propagatedType, isNull);
+    SimpleIdentifier map2 = _findIdentifier('map((e) => 3);');
+    MethodInvocation m2 = map2.parent;
+    expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
+    expect(map2.staticType, isNull);
+    expect(map2.propagatedType, isNull);
+  }
+
+  void test_genericMethod_nestedCapture() {
+    _resolveTestUnit(r'''
+class C<T> {
+  /*=T*/ f/*<S>*/(/*=S*/ x) {
+    new C<S>().f/*<int>*/(3);
+    new C<S>().f; // tear-off
+    return null;
+  }
+}
+''');
+    MethodInvocation f = _findIdentifier('f/*<int>*/(3);').parent;
+    expect(f.staticInvokeType.toString(), '(int) → S');
+    FunctionType ft = f.staticInvokeType;
+    expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]');
+
+    SimpleIdentifier f2 = _findIdentifier('f;');
+    expect(f2.staticType.toString(), '<S₀>(S₀) → S');
+  }
+
+  void test_genericMethod_nestedFunctions() {
+    _resolveTestUnit(r'''
+/*=S*/ f/*<S>*/(/*=S*/ x) {
+  g/*<S>*/(/*=S*/ x) => f;
+  return null;
+}
+''');
+    SimpleIdentifier g = _findIdentifier('f');
+    expect(g.staticType.toString(), '<S>(S) → S');
+    SimpleIdentifier f = _findIdentifier('g');
+    expect(f.staticType.toString(), '<S>(S) → dynamic');
+  }
+
+  void test_genericMethod_override() {
+    _resolveTestUnit(r'''
+class C {
+  /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  /*=T*/ f/*<T>*/(/*=T*/ x) => null; // from D
+}
+''');
+    SimpleIdentifier f =
+        _findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D');
+    MethodElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.typeFormals.toString(), '[T]');
+    expect(e.type.toString(), '<T>(T) → T');
+
+    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  void test_genericMethod_override_bounds() {
+    _resolveTestUnit(r'''
+class A {}
+class B extends A {}
+class C {
+  /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
+}
+''');
+  }
+
+  void test_genericMethod_override_invalidReturnType() {
+    Source source = addSource(r'''
+class C {
+  Iterable/*<T>*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  String f/*<S>*/(/*=S*/ x) => null;
+}''');
+    // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
+    // from CodeChecker don't have working equality.
+    List<AnalysisError> errors = analysisContext2.computeErrors(source);
+    expect(errors.map((e) => e.errorCode.name), [
+      'INVALID_METHOD_OVERRIDE_RETURN_TYPE',
+      'STRONG_MODE_INVALID_METHOD_OVERRIDE'
+    ]);
+    expect(errors[0].message, contains('Iterable<S>'),
+        reason: 'errors should be in terms of the type parameters '
+            'at the error location');
+    verify([source]);
+  }
+
+  void test_genericMethod_override_invalidTypeParamBounds() {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C {
+  /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
+}''');
+    // TODO(jmesserly): this is modified code from assertErrors, which we can't
+    // use directly because STRONG_MODE_* errors don't have working equality.
+    List<AnalysisError> errors = analysisContext2.computeErrors(source);
+    expect(errors.map((e) => e.errorCode.name), [
+      'STRONG_MODE_INVALID_METHOD_OVERRIDE',
+      'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND'
+    ]);
+    verify([source]);
+  }
+
+  void test_genericMethod_override_invalidTypeParamCount() {
+    Source source = addSource(r'''
+class C {
+  /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  /*=S*/ f/*<T, S>*/(/*=T*/ x) => null;
+}''');
+    // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
+    // from CodeChecker don't have working equality.
+    List<AnalysisError> errors = analysisContext2.computeErrors(source);
+    expect(errors.map((e) => e.errorCode.name), [
+      'STRONG_MODE_INVALID_METHOD_OVERRIDE',
+      'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS'
+    ]);
+    verify([source]);
+  }
+
+  void test_genericMethod_tearoff() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(E e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+  var methodTearOff = c.f;
+  var staticTearOff = C.g;
+  var staticFieldTearOff = C.h;
+  var topFunTearOff = topF;
+  var topFieldTearOff = topG;
+  var localTearOff = lf;
+  var paramTearOff = pf;
+}
+''');
+    expect(
+        _findIdentifier('methodTearOff').staticType.toString(), "<T>(int) → T");
+    expect(
+        _findIdentifier('staticTearOff').staticType.toString(), "<T>(T) → T");
+    expect(_findIdentifier('staticFieldTearOff').staticType.toString(),
+        "<T>(T) → T");
+    expect(
+        _findIdentifier('topFunTearOff').staticType.toString(), "<T>(T) → T");
+    expect(
+        _findIdentifier('topFieldTearOff').staticType.toString(), "<T>(T) → T");
+    expect(_findIdentifier('localTearOff').staticType.toString(), "<T>(T) → T");
+    expect(_findIdentifier('paramTearOff').staticType.toString(), "<T>(T) → T");
+  }
+
   void test_pseudoGeneric_max_doubleDouble() {
     String code = r'''
 import 'dart:math';
@@ -11954,6 +13641,22 @@
     expect(declaration.initializer.propagatedType, isNull);
   }
 
+  void test_pseudoGeneric_max_doubleDouble_prefixed() {
+    String code = r'''
+import 'dart:math' as math;
+main() {
+  var foo = math.max(1.0, 2.0);
+}
+''';
+    _resolveTestUnit(code);
+
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    expect(declaration.initializer.staticType.name, 'double');
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
   void test_pseudoGeneric_max_doubleInt() {
     String code = r'''
 import 'dart:math';
@@ -12021,6 +13724,98 @@
     expect(declaration.initializer.propagatedType, isNull);
   }
 
+  void test_pseudoGeneric_then_prefixed() {
+    String code = r'''
+import 'dart:async' as async;
+String toString(int x) => x.toString();
+main() {
+  async.Future<int> bar = null;
+  var foo = bar.then(toString);
+}
+''';
+    _resolveTestUnit(code);
+
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+
+    expect(declaration.initializer.staticType.toString(), "Future<String>");
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
+  void test_setterWithDynamicTypeIsError() {
+    Source source = addSource(r'''
+class A {
+  dynamic set f(String s) => null;
+}
+dynamic set g(int x) => null;
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+    ]);
+    verify([source]);
+  }
+
+  void test_setterWithExplicitVoidType_returningVoid() {
+    Source source = addSource(r'''
+void returnsVoid() {}
+class A {
+  void set f(String s) => returnsVoid();
+}
+void set g(int x) => returnsVoid();
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_setterWithNoVoidType() {
+    Source source = addSource(r'''
+class A {
+  set f(String s) {
+    return '42';
+  }
+}
+set g(int x) => 42;
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+      StaticTypeWarningCode.RETURN_OF_INVALID_TYPE
+    ]);
+    verify([source]);
+  }
+
+  void test_setterWithNoVoidType_returningVoid() {
+    Source source = addSource(r'''
+void returnsVoid() {}
+class A {
+  set f(String s) => returnsVoid();
+}
+set g(int x) => returnsVoid();
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_setterWithOtherTypeIsError() {
+    Source source = addSource(r'''
+class A {
+  String set f(String s) => null;
+}
+Object set g(x) => null;
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+    ]);
+    verify([source]);
+  }
+
   void test_ternaryOperator_null_left() {
     String code = r'''
 main() {
@@ -12056,6 +13851,7 @@
 class StrongModeTypePropagationTest extends ResolverTestCase {
   @override
   void setUp() {
+    super.setUp();
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.strongMode = true;
     resetWithOptions(options);
@@ -12173,9 +13969,6 @@
   }
 
   void test_localVariableInference_transitive_field_inferred_lexical() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     String code = r'''
 class A {
   final x = 3;
@@ -12192,9 +13985,6 @@
   }
 
   void test_localVariableInference_transitive_field_inferred_reversed() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     String code = r'''
 class A {
   f() {
@@ -12265,9 +14055,6 @@
   }
 
   void test_localVariableInference_transitive_toplevel_inferred_lexical() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     String code = r'''
 final x = 3;
 main() {
@@ -12280,9 +14067,6 @@
   }
 
   void test_localVariableInference_transitive_toplevel_inferred_reversed() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     String code = r'''
 main() {
   var v = x;
@@ -12320,7 +14104,7 @@
 }
 
 @reflectiveTest
-class SubtypeManagerTest extends EngineTestCase {
+class SubtypeManagerTest {
   /**
    * The inheritance manager being tested.
    */
@@ -12331,9 +14115,7 @@
    */
   CompilationUnitElementImpl _definingCompilationUnit;
 
-  @override
   void setUp() {
-    super.setUp();
     AnalysisContext context = AnalysisContextFactory.contextWithCore();
     FileBasedSource source =
         new FileBasedSource(FileUtilities2.createFile("/test.dart"));
@@ -12494,108 +14276,6 @@
 
 @reflectiveTest
 class TypePropagationTest extends ResolverTestCase {
-  void fail_finalPropertyInducingVariable_classMember_instance() {
-    addNamedSource(
-        "/lib.dart",
-        r'''
-class A {
-  final v = 0;
-}''');
-    String code = r'''
-import 'lib.dart';
-f(A a) {
-  return a.v; // marker
-}''';
-    _assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void fail_finalPropertyInducingVariable_classMember_instance_inherited() {
-    addNamedSource(
-        "/lib.dart",
-        r'''
-class A {
-  final v = 0;
-}''');
-    String code = r'''
-import 'lib.dart';
-class B extends A {
-  m() {
-    return v; // marker
-  }
-}''';
-    _assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void fail_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
-    addNamedSource(
-        "/lib.dart",
-        r'''
-class A {
-  final v = 0;
-}''');
-    String code = r'''
-import 'lib.dart';
-f(p) {
-  if (p is A) {
-    return p.v; // marker
-  }
-}''';
-    _assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void fail_finalPropertyInducingVariable_classMember_instance_unprefixed() {
-    String code = r'''
-class A {
-  final v = 0;
-  m() {
-    v; // marker
-  }
-}''';
-    _assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void fail_finalPropertyInducingVariable_classMember_static() {
-    addNamedSource(
-        "/lib.dart",
-        r'''
-class A {
-  static final V = 0;
-}''');
-    String code = r'''
-import 'lib.dart';
-f() {
-  return A.V; // marker
-}''';
-    _assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void fail_finalPropertyInducingVariable_topLevelVaraible_prefixed() {
-    addNamedSource("/lib.dart", "final V = 0;");
-    String code = r'''
-import 'lib.dart' as p;
-f() {
-  var v2 = p.V; // marker prefixed
-}''';
-    _assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void fail_finalPropertyInducingVariable_topLevelVaraible_simple() {
-    addNamedSource("/lib.dart", "final V = 0;");
-    String code = r'''
-import 'lib.dart';
-f() {
-  return V; // marker simple
-}''';
-    _assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
   void fail_mergePropagatedTypesAtJoinPoint_1() {
     // https://code.google.com/p/dart/issues/detail?id=19929
     _assertTypeOfMarkedExpression(
@@ -12880,6 +14560,109 @@
     expect(identifier.propagatedType.name, "CanvasRenderingContext2D");
   }
 
+  void test_finalPropertyInducingVariable_classMember_instance() {
+    addNamedSource(
+        "/lib.dart",
+        r'''
+class A {
+  final v = 0;
+}''');
+    String code = r'''
+import 'lib.dart';
+f(A a) {
+  return a.v; // marker
+}''';
+    _assertTypeOfMarkedExpression(
+        code, typeProvider.dynamicType, typeProvider.intType);
+  }
+
+  void test_finalPropertyInducingVariable_classMember_instance_inherited() {
+    addNamedSource(
+        "/lib.dart",
+        r'''
+class A {
+  final v = 0;
+}''');
+    String code = r'''
+import 'lib.dart';
+class B extends A {
+  m() {
+    return v; // marker
+  }
+}''';
+    _assertTypeOfMarkedExpression(
+        code, typeProvider.dynamicType, typeProvider.intType);
+  }
+
+  void
+      test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
+    addNamedSource(
+        "/lib.dart",
+        r'''
+class A {
+  final v = 0;
+}''');
+    String code = r'''
+import 'lib.dart';
+f(p) {
+  if (p is A) {
+    return p.v; // marker
+  }
+}''';
+    _assertTypeOfMarkedExpression(
+        code, typeProvider.dynamicType, typeProvider.intType);
+  }
+
+  void test_finalPropertyInducingVariable_classMember_instance_unprefixed() {
+    String code = r'''
+class A {
+  final v = 0;
+  m() {
+    v; // marker
+  }
+}''';
+    _assertTypeOfMarkedExpression(
+        code, typeProvider.dynamicType, typeProvider.intType);
+  }
+
+  void test_finalPropertyInducingVariable_classMember_static() {
+    addNamedSource(
+        "/lib.dart",
+        r'''
+class A {
+  static final V = 0;
+}''');
+    String code = r'''
+import 'lib.dart';
+f() {
+  return A.V; // marker
+}''';
+    _assertTypeOfMarkedExpression(
+        code, typeProvider.dynamicType, typeProvider.intType);
+  }
+
+  void test_finalPropertyInducingVariable_topLevelVariable_prefixed() {
+    addNamedSource("/lib.dart", "final V = 0;");
+    String code = r'''
+import 'lib.dart' as p;
+f() {
+  var v2 = p.V; // marker prefixed
+}''';
+    _assertTypeOfMarkedExpression(
+        code, typeProvider.dynamicType, typeProvider.intType);
+  }
+
+  void test_finalPropertyInducingVariable_topLevelVariable_simple() {
+    addNamedSource("/lib.dart", "final V = 0;");
+    String code = r'''
+import 'lib.dart';
+f() {
+  return V; // marker simple
+}''';
+    _assertTypeOfMarkedExpression(
+        code, typeProvider.dynamicType, typeProvider.intType);
+  }
+
   void test_forEach() {
     String code = r'''
 main() {
@@ -12936,6 +14719,39 @@
     }
   }
 
+  void test_forEach_async_inheritedStream() {
+    // From https://github.com/dart-lang/sdk/issues/24191, this ensures that
+    // `await for` works for types where the generic parameter doesn't
+    // correspond to the type of the Stream's data.
+    String code = r'''
+import 'dart:async';
+abstract class MyCustomStream<T> implements Stream<List<T>> {}
+f(MyCustomStream<String> stream) async {
+  await for (var e in stream) {
+    e;
+  }
+}''';
+    Source source = addSource(code);
+    LibraryElement library = resolve2(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = resolveCompilationUnit(source, library);
+    InterfaceType listOfStringType =
+        typeProvider.listType.substitute4([typeProvider.stringType]);
+    // in the declaration
+    {
+      SimpleIdentifier identifier = EngineTestCase.findNode(
+          unit, code, "e in", (node) => node is SimpleIdentifier);
+      expect(identifier.propagatedType, equals(listOfStringType));
+    }
+    // in the loop body
+    {
+      SimpleIdentifier identifier = EngineTestCase.findNode(
+          unit, code, "e;", (node) => node is SimpleIdentifier);
+      expect(identifier.propagatedType, equals(listOfStringType));
+    }
+  }
+
   void test_functionExpression_asInvocationArgument() {
     String code = r'''
 class MyMap<K, V> {
@@ -12998,7 +14814,8 @@
     expect(vParameter.identifier.propagatedType, same(stringType));
   }
 
-  void test_functionExpression_asInvocationArgument_functionExpressionInvocation() {
+  void
+      test_functionExpression_asInvocationArgument_functionExpressionInvocation() {
     String code = r'''
 main() {
   (f(String value)) {} ((v) {
@@ -13266,6 +15083,25 @@
     }
   }
 
+  void test_invocation_target_prefixed() {
+    addNamedSource(
+        '/helper.dart',
+        '''
+library helper;
+int max(int x, int y) => 0;
+''');
+    String code = '''
+import 'helper.dart' as helper;
+main() {
+  helper.max(10, 10); // marker
+}''';
+    SimpleIdentifier methodName =
+        _findMarkedIdentifier(code, "(10, 10); // marker");
+    MethodInvocation methodInvoke = methodName.parent;
+    expect(methodInvoke.methodName.staticElement, isNotNull);
+    expect(methodInvoke.methodName.propagatedElement, isNull);
+  }
+
   void test_is_conditional() {
     Source source = addSource(r'''
 class A {}
@@ -14153,24 +15989,23 @@
 }
 
 @reflectiveTest
-class TypeResolverVisitorTest extends EngineTestCase {
+class TypeResolverVisitorTest {
   /**
    * The error listener to which errors will be reported.
    */
   GatheringErrorListener _listener;
 
   /**
-   * The object representing the information about the library in which the types are being
-   * resolved.
-   */
-  Library _library;
-
-  /**
    * The type provider used to access the types.
    */
   TestTypeProvider _typeProvider;
 
   /**
+   * The library scope in which types are to be resolved.
+   */
+  LibraryScope libraryScope;
+
+  /**
    * The visitor used to resolve types needed to form the type hierarchy.
    */
   TypeResolverVisitor _visitor;
@@ -14195,22 +16030,20 @@
     _listener.assertNoErrors();
   }
 
-  @override
   void setUp() {
     _listener = new GatheringErrorListener();
     InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
     Source librarySource =
         new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
-    _library = new Library(context, _listener, librarySource);
     LibraryElementImpl element = new LibraryElementImpl.forNode(
         context, AstFactory.libraryIdentifier2(["lib"]));
     element.definingCompilationUnit =
         new CompilationUnitElementImpl("lib.dart");
-    _library.libraryElement = element;
     _typeProvider = new TestTypeProvider();
-    _visitor = new TypeResolverVisitor(_library.libraryElement, librarySource,
-        _typeProvider, _library.errorListener,
-        nameScope: _library.libraryScope);
+    libraryScope = new LibraryScope(element, _listener);
+    _visitor = new TypeResolverVisitor(
+        element, librarySource, _typeProvider, _listener,
+        nameScope: libraryScope);
   }
 
   void test_visitCatchClause_exception() {
@@ -14770,7 +16603,7 @@
   void _resolveNode(AstNode node, [List<Element> definedElements]) {
     if (definedElements != null) {
       for (Element element in definedElements) {
-        _library.libraryScope.define(element);
+        libraryScope.define(element);
       }
     }
     node.accept(_visitor);
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 119d4aa..d0d8949 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.scanner_test;
+library analyzer.test.generated.scanner_test;
 
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -264,6 +264,18 @@
     expect(token.precedingComments, isNull);
   }
 
+  void test_comment_generic_method_type_assign() {
+    _assertComment(TokenType.MULTI_LINE_COMMENT, "/*=comment*/");
+    _assertComment(TokenType.GENERIC_METHOD_TYPE_ASSIGN, "/*=comment*/",
+        genericMethodComments: true);
+  }
+
+  void test_comment_generic_method_type_list() {
+    _assertComment(TokenType.MULTI_LINE_COMMENT, "/*<comment>*/");
+    _assertComment(TokenType.GENERIC_METHOD_TYPE_LIST, "/*<comment>*/",
+        genericMethodComments: true);
+  }
+
   void test_comment_multi() {
     _assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment */");
   }
@@ -1048,11 +1060,12 @@
     _scanWithListener("'\${(}'", listener);
   }
 
-  void _assertComment(TokenType commentType, String source) {
+  void _assertComment(TokenType commentType, String source,
+      {bool genericMethodComments: false}) {
     //
     // Test without a trailing end-of-line marker
     //
-    Token token = _scan(source);
+    Token token = _scan(source, genericMethodComments: genericMethodComments);
     expect(token, isNotNull);
     expect(token.type, TokenType.EOF);
     Token comment = token.precedingComments;
@@ -1064,7 +1077,7 @@
     //
     // Test with a trailing end-of-line marker
     //
-    token = _scan("$source\n");
+    token = _scan("$source\n", genericMethodComments: genericMethodComments);
     expect(token, isNotNull);
     expect(token.type, TokenType.EOF);
     comment = token.precedingComments;
@@ -1233,16 +1246,21 @@
     expect(token.type, TokenType.EOF);
   }
 
-  Token _scan(String source) {
+  Token _scan(String source, {bool genericMethodComments: false}) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    Token token = _scanWithListener(source, listener);
+    Token token = _scanWithListener(source, listener,
+        genericMethodComments: genericMethodComments);
     listener.assertNoErrors();
     return token;
   }
 
-  Token _scanWithListener(String source, GatheringErrorListener listener) {
+  Token _scanWithListener(String source, GatheringErrorListener listener,
+      {bool genericMethodComments: false}) {
     Scanner scanner =
         new Scanner(null, new CharSequenceReader(source), listener);
+    if (genericMethodComments) {
+      scanner.scanGenericMethodComments = true;
+    }
     Token result = scanner.tokenize();
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     return result;
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index c16f1f8..9932cf8 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -2,13 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.generated.source_factory;
+library analyzer.test.generated.test.generated.source_factory;
 
 import 'dart:convert';
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine, Logger;
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -64,8 +65,17 @@
       resolvers.add(customResolver);
     }
     SourceFactory factory = new SourceFactory(resolvers, packages);
-    Source source = factory.resolveUri(containingSource, uri);
-    return source != null ? source.fullName : null;
+
+    expect(AnalysisEngine.instance.logger, Logger.NULL);
+    var logger = new TestLogger();
+    AnalysisEngine.instance.logger = logger;
+    try {
+      Source source = factory.resolveUri(containingSource, uri);
+      expect(logger.log, []);
+      return source != null ? source.fullName : null;
+    } finally {
+      AnalysisEngine.instance.logger = Logger.NULL;
+    }
   }
 
   Uri restorePackageUri(
@@ -122,6 +132,10 @@
               customResolver: testResolver);
           expect(uri, testResolver.uriPath);
         });
+        test('Bad package URI', () {
+          String uri = resolvePackageUri(config: '', uri: 'package:foo');
+          expect(uri, isNull);
+        });
         test('Invalid URI', () {
           // TODO(pquitslund): fix clients to handle errors appropriately
           //   CLI: print message 'invalid package file format'
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 99ab84c..2c1e2d2 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.static_type_warning_code_test;
+library analyzer.test.generated.static_type_warning_code_test;
 
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -58,6 +58,30 @@
     assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
   }
 
+  void test_assert_message_suppresses_type_promotion() {
+    // If a variable is assigned to inside the expression for an assert
+    // message, type promotion should be suppressed, just as it would be if the
+    // assignment occurred outside an assert statement.  (Note that it is a
+    // dubious practice for the computation of an assert message to have side
+    // effects, since it is only evaluated if the assert fails).
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+class C {
+  void foo() {}
+}
+
+f(Object x) {
+  if (x is C) {
+    x.foo();
+    assert(true, () { x = new C(); return 'msg'; }());
+  }
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+    // Do not verify since `x.foo()` fails to resolve.
+  }
+
   void test_await_flattened() {
     Source source = addSource('''
 import 'dart:async';
@@ -1098,7 +1122,8 @@
     verify([source]);
   }
 
-  void test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() {
+  void
+      test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
@@ -1127,7 +1152,8 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
   }
 
-  void test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after() {
+  void
+      test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
@@ -1138,7 +1164,8 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
   }
 
-  void test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before() {
+  void
+      test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
@@ -1418,6 +1445,18 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
   }
 
+  void test_undefinedGetter_typeLiteral_cascadeTarget() {
+    Source source = addSource(r'''
+class T {
+  static int get foo => 42;
+}
+main() {
+  T..foo;
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
   void test_undefinedGetter_typeLiteral_conditionalAccess() {
     // When applied to a type literal, the conditional access operator '?.'
     // cannot be used to access instance getters of Type.
@@ -1589,6 +1628,19 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
   }
 
+  void test_undefinedMethod_typeLiteral_cascadeTarget() {
+    Source source = addSource('''
+class T {
+  static void foo() {}
+}
+main() {
+  T..foo();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
   void test_undefinedMethod_typeLiteral_conditionalAccess() {
     // When applied to a type literal, the conditional access operator '?.'
     // cannot be used to access instance methods of Type.
@@ -1600,6 +1652,19 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
   }
 
+  void test_undefinedMethodWithConstructor() {
+    Source source = addSource(r'''
+class C {
+  C.m();
+}
+f() {
+  C c = C.m();
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(
+        source, [StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR]);
+  }
+
   void test_undefinedOperator_indexBoth() {
     Source source = addSource(r'''
 class A {}
@@ -1676,6 +1741,18 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
   }
 
+  void test_undefinedSetter_typeLiteral_cascadeTarget() {
+    Source source = addSource(r'''
+class T {
+  static void set foo(_) {}
+}
+main() {
+  T..foo = 42;
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
+  }
+
   void test_undefinedSetter_void() {
     Source source = addSource(r'''
 class T {
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index f48528e..eb6aa8b 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.static_warning_code_test;
+library analyzer.test.generated.static_warning_code_test;
 
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index fb84d46..e737b56 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.generated;
+library analyzer.test.generated.test_all;
 
 import 'package:unittest/unittest.dart';
 
@@ -10,7 +10,7 @@
 import 'all_the_rest_test.dart' as all_the_rest;
 import 'ast_test.dart' as ast_test;
 import 'compile_time_error_code_test.dart' as compile_time_error_code_test;
-import 'element_test.dart' as element_test;
+import 'declaration_resolver_test.dart' as declaration_resolver_test;
 import 'engine_test.dart' as engine_test;
 import 'incremental_resolver_test.dart' as incremental_resolver_test;
 import 'incremental_scanner_test.dart' as incremental_scanner_test;
@@ -33,7 +33,7 @@
     all_the_rest.main();
     ast_test.main();
     compile_time_error_code_test.main();
-    element_test.main();
+    declaration_resolver_test.main();
     engine_test.main();
     incremental_resolver_test.main();
     incremental_scanner_test.main();
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 20cc0e2..87b1282 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -2,17 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.test_support;
+library analyzer.test.generated.test_support;
 
 import 'dart:collection';
 
-import 'package:analyzer/src/generated/ast.dart' show AstNode, NodeLocator;
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart'
+    show AstNode, NodeLocator, SimpleIdentifier;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:unittest/unittest.dart';
 
 import 'resolver_test.dart';
@@ -91,7 +95,13 @@
     return null;
   }
 
-  void setUp() {}
+  void setUp() {
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    new ExtensionManager().processPlugins(plugins);
+  }
 
   void tearDown() {}
 
@@ -124,6 +134,18 @@
     AstNode node = new NodeLocator(offset).searchWithin(root);
     return node.getAncestor(predicate);
   }
+
+  /**
+   * Find the [SimpleIdentifier] with at offset of the "prefix".
+   */
+  static SimpleIdentifier findSimpleIdentifier(
+      AstNode root, String code, String prefix) {
+    int offset = code.indexOf(prefix);
+    if (offset == -1) {
+      throw new IllegalArgumentException("Not found '$prefix'.");
+    }
+    return new NodeLocator(offset).searchWithin(root);
+  }
 }
 
 /**
@@ -515,33 +537,18 @@
  */
 class TestLogger implements Logger {
   /**
-   * The number of error messages that were logged.
+   * All logged messages.
    */
-  int errorCount = 0;
-
-  /**
-   * The number of informational messages that were logged.
-   */
-  int infoCount = 0;
+  List<String> log = [];
 
   @override
   void logError(String message, [CaughtException exception]) {
-    errorCount++;
-  }
-
-  @override
-  void logError2(String message, Object exception) {
-    errorCount++;
+    log.add("error: $message");
   }
 
   @override
   void logInformation(String message, [CaughtException exception]) {
-    infoCount++;
-  }
-
-  @override
-  void logInformation2(String message, Object exception) {
-    infoCount++;
+    log.add("info: $message");
   }
 }
 
@@ -557,10 +564,6 @@
    */
   bool generateExceptionOnRead = false;
 
-  @override
-  int get modificationStamp =>
-      generateExceptionOnRead ? -1 : _modificationStamp;
-
   /**
    * The number of times that the contents of this source have been requested.
    */
@@ -586,10 +589,15 @@
   }
 
   int get hashCode => 0;
+
   bool get isInSystemLibrary {
     return false;
   }
 
+  @override
+  int get modificationStamp =>
+      generateExceptionOnRead ? -1 : _modificationStamp;
+
   String get shortName {
     return _name;
   }
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index d49c75c..6486b63 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -4,9 +4,12 @@
 
 // Tests related to the [TypeSystem] class.
 
-library engine.type_system_test;
+library analyzer.test.generated.type_system_test;
 
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
@@ -20,6 +23,883 @@
   runReflectiveTests(TypeSystemTest);
   runReflectiveTests(StrongSubtypingTest);
   runReflectiveTests(StrongAssignabilityTest);
+  runReflectiveTests(StrongGenericFunctionInferenceTest);
+}
+
+@reflectiveTest
+class StrongAssignabilityTest {
+  TypeProvider typeProvider;
+  TypeSystem typeSystem;
+
+  DartType get bottomType => typeProvider.bottomType;
+  InterfaceType get doubleType => typeProvider.doubleType;
+  DartType get dynamicType => typeProvider.dynamicType;
+  InterfaceType get functionType => typeProvider.functionType;
+  InterfaceType get intType => typeProvider.intType;
+  InterfaceType get listType => typeProvider.listType;
+  InterfaceType get numType => typeProvider.numType;
+  InterfaceType get objectType => typeProvider.objectType;
+  InterfaceType get stringType => typeProvider.stringType;
+  DartType get voidType => VoidTypeImpl.instance;
+
+  void setUp() {
+    typeProvider = new TestTypeProvider();
+    typeSystem = new StrongTypeSystemImpl();
+  }
+
+  void test_isAssignableTo_bottom_isBottom() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      intType,
+      doubleType,
+      numType,
+      stringType,
+      interfaceType,
+      bottomType
+    ];
+
+    _checkGroups(bottomType, interassignable: interassignable);
+  }
+
+  void test_isAssignableTo_call_method() {
+    ClassElementImpl classBottom = ElementFactory.classElement2("B");
+    MethodElement methodBottom =
+        ElementFactory.methodElement("call", objectType, <DartType>[intType]);
+    classBottom.methods = <MethodElement>[methodBottom];
+
+    DartType top =
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
+    InterfaceType bottom = classBottom.type;
+
+    _checkIsStrictAssignableTo(bottom, top);
+  }
+
+  void test_isAssignableTo_classes() {
+    ClassElement classTop = ElementFactory.classElement2("A");
+    ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
+    ClassElement classRight = ElementFactory.classElement("C", classTop.type);
+    ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
+      ..interfaces = <InterfaceType>[classRight.type];
+    InterfaceType top = classTop.type;
+    InterfaceType left = classLeft.type;
+    InterfaceType right = classRight.type;
+    InterfaceType bottom = classBottom.type;
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  void test_isAssignableTo_double() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      doubleType,
+      numType,
+      bottomType
+    ];
+    List<DartType> unrelated = <DartType>[intType, stringType, interfaceType,];
+
+    _checkGroups(doubleType,
+        interassignable: interassignable, unrelated: unrelated);
+  }
+
+  void test_isAssignableTo_dynamic_isTop() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      intType,
+      doubleType,
+      numType,
+      stringType,
+      interfaceType,
+      bottomType
+    ];
+    _checkGroups(dynamicType, interassignable: interassignable);
+  }
+
+  void test_isAssignableTo_fuzzy_arrows() {
+    FunctionType top = TypeBuilder
+        .function(required: <DartType>[dynamicType], result: objectType);
+    FunctionType left = TypeBuilder
+        .function(required: <DartType>[objectType], result: objectType);
+    FunctionType right = TypeBuilder
+        .function(required: <DartType>[dynamicType], result: bottomType);
+    FunctionType bottom = TypeBuilder
+        .function(required: <DartType>[objectType], result: bottomType);
+
+    _checkCrossLattice(top, left, right, bottom);
+  }
+
+  void test_isAssignableTo_generics() {
+    ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
+    InterfaceType LType = LClass.type;
+    ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
+    DartType typeParam = MClass.typeParameters[0].type;
+    InterfaceType superType = LType.substitute4(<DartType>[typeParam]);
+    MClass.interfaces = <InterfaceType>[superType];
+    InterfaceType MType = MClass.type;
+
+    InterfaceType top = LType.substitute4(<DartType>[dynamicType]);
+    InterfaceType left = MType.substitute4(<DartType>[dynamicType]);
+    InterfaceType right = LType.substitute4(<DartType>[intType]);
+    InterfaceType bottom = MType.substitute4(<DartType>[intType]);
+
+    _checkCrossLattice(top, left, right, bottom);
+  }
+
+  void test_isAssignableTo_int() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      intType,
+      numType,
+      bottomType
+    ];
+    List<DartType> unrelated = <DartType>[
+      doubleType,
+      stringType,
+      interfaceType,
+    ];
+
+    _checkGroups(intType,
+        interassignable: interassignable, unrelated: unrelated);
+  }
+
+  void test_isAssignableTo_named_optional() {
+    DartType r =
+        TypeBuilder.function(required: <DartType>[intType], result: intType);
+    DartType o = TypeBuilder.function(
+        required: <DartType>[], optional: <DartType>[intType], result: intType);
+    DartType n = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType},
+        result: intType);
+    DartType rr = TypeBuilder
+        .function(required: <DartType>[intType, intType], result: intType);
+    DartType ro = TypeBuilder.function(
+        required: <DartType>[intType],
+        optional: <DartType>[intType],
+        result: intType);
+    DartType rn = TypeBuilder.function(
+        required: <DartType>[intType],
+        named: <String, DartType>{'x': intType},
+        result: intType);
+    DartType oo = TypeBuilder.function(
+        required: <DartType>[],
+        optional: <DartType>[intType, intType],
+        result: intType);
+    DartType nn = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType, 'y': intType},
+        result: intType);
+    DartType nnn = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType},
+        result: intType);
+
+    _checkGroups(r,
+        interassignable: [r, o, ro, rn, oo], unrelated: [n, rr, nn, nnn]);
+    _checkGroups(o,
+        interassignable: [o, oo], unrelated: [n, rr, ro, rn, nn, nnn]);
+    _checkGroups(n,
+        interassignable: [n, nn, nnn], unrelated: [r, o, rr, ro, rn, oo]);
+    _checkGroups(rr,
+        interassignable: [rr, ro, oo], unrelated: [r, o, n, rn, nn, nnn]);
+    _checkGroups(ro, interassignable: [ro, oo], unrelated: [o, n, rn, nn, nnn]);
+    _checkGroups(rn,
+        interassignable: [rn], unrelated: [o, n, rr, ro, oo, nn, nnn]);
+    _checkGroups(oo, interassignable: [oo], unrelated: [n, rn, nn, nnn]);
+    _checkGroups(nn,
+        interassignable: [nn, nnn], unrelated: [r, o, rr, ro, rn, oo]);
+    _checkGroups(nnn,
+        interassignable: [nnn], unrelated: [r, o, rr, ro, rn, oo]);
+  }
+
+  void test_isAssignableTo_num() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> interassignable = <DartType>[
+      dynamicType,
+      objectType,
+      numType,
+      intType,
+      doubleType,
+      bottomType
+    ];
+    List<DartType> unrelated = <DartType>[stringType, interfaceType,];
+
+    _checkGroups(numType,
+        interassignable: interassignable, unrelated: unrelated);
+  }
+
+  void test_isAssignableTo_simple_function() {
+    FunctionType top =
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
+    FunctionType left =
+        TypeBuilder.function(required: <DartType>[intType], result: intType);
+    FunctionType right = TypeBuilder
+        .function(required: <DartType>[objectType], result: objectType);
+    FunctionType bottom =
+        TypeBuilder.function(required: <DartType>[objectType], result: intType);
+
+    _checkCrossLattice(top, left, right, bottom);
+  }
+
+  void test_isAssignableTo_void_functions() {
+    FunctionType top =
+        TypeBuilder.function(required: <DartType>[intType], result: voidType);
+    FunctionType bottom =
+        TypeBuilder.function(required: <DartType>[objectType], result: intType);
+
+    _checkEquivalent(bottom, top);
+  }
+
+  void _checkCrossLattice(
+      DartType top, DartType left, DartType right, DartType bottom) {
+    _checkGroups(top, interassignable: <DartType>[top, left, right, bottom]);
+    _checkGroups(left, interassignable: <DartType>[top, left, right, bottom]);
+    _checkGroups(right, interassignable: <DartType>[top, left, right, bottom]);
+    _checkGroups(bottom, interassignable: <DartType>[top, left, right, bottom]);
+  }
+
+  void _checkEquivalent(DartType type1, DartType type2) {
+    _checkIsAssignableTo(type1, type2);
+    _checkIsAssignableTo(type2, type1);
+  }
+
+  void _checkGroups(DartType t1,
+      {List<DartType> interassignable, List<DartType> unrelated}) {
+    if (interassignable != null) {
+      for (DartType t2 in interassignable) {
+        _checkEquivalent(t1, t2);
+      }
+    }
+    if (unrelated != null) {
+      for (DartType t2 in unrelated) {
+        _checkUnrelated(t1, t2);
+      }
+    }
+  }
+
+  void _checkIsAssignableTo(DartType type1, DartType type2) {
+    expect(typeSystem.isAssignableTo(type1, type2), true);
+  }
+
+  void _checkIsNotAssignableTo(DartType type1, DartType type2) {
+    expect(typeSystem.isAssignableTo(type1, type2), false);
+  }
+
+  void _checkIsStrictAssignableTo(DartType type1, DartType type2) {
+    _checkIsAssignableTo(type1, type2);
+    _checkIsNotAssignableTo(type2, type1);
+  }
+
+  void _checkLattice(
+      DartType top, DartType left, DartType right, DartType bottom) {
+    _checkGroups(top, interassignable: <DartType>[top, left, right, bottom]);
+    _checkGroups(left,
+        interassignable: <DartType>[top, left, bottom],
+        unrelated: <DartType>[right]);
+    _checkGroups(right,
+        interassignable: <DartType>[top, right, bottom],
+        unrelated: <DartType>[left]);
+    _checkGroups(bottom, interassignable: <DartType>[top, left, right, bottom]);
+  }
+
+  void _checkUnrelated(DartType type1, DartType type2) {
+    _checkIsNotAssignableTo(type1, type2);
+    _checkIsNotAssignableTo(type2, type1);
+  }
+}
+
+@reflectiveTest
+class StrongGenericFunctionInferenceTest {
+  TypeProvider typeProvider;
+  StrongTypeSystemImpl typeSystem;
+
+  DartType get bottomType => typeProvider.bottomType;
+  InterfaceType get doubleType => typeProvider.doubleType;
+  DartType get dynamicType => typeProvider.dynamicType;
+  InterfaceType get functionType => typeProvider.functionType;
+  InterfaceType get intType => typeProvider.intType;
+  InterfaceType get iterableType => typeProvider.iterableType;
+  InterfaceType get listType => typeProvider.listType;
+  InterfaceType get numType => typeProvider.numType;
+  InterfaceType get objectType => typeProvider.objectType;
+  InterfaceType get stringType => typeProvider.stringType;
+  DartType get voidType => VoidTypeImpl.instance;
+
+  void setUp() {
+    typeProvider = new TestTypeProvider();
+    typeSystem = new StrongTypeSystemImpl();
+  }
+
+  void test_boundedByAnotherTypeParameter() {
+    // <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
+    var tFrom = TypeBuilder.variable('TFrom');
+    var tTo =
+        TypeBuilder.variable('TTo', bound: iterableType.substitute4([tFrom]));
+    var cast = TypeBuilder
+        .function(types: [tFrom, tTo], required: [tFrom], result: tTo);
+    expect(_inferCall(cast, [stringType]), [
+      stringType,
+      iterableType.substitute4([stringType])
+    ]);
+  }
+
+  void test_boundedRecursively() {
+    // class Clonable<T extends Clonable<T>>
+    ClassElementImpl clonable =
+        ElementFactory.classElement('Clonable', objectType, ['T']);
+    (clonable.typeParameters[0] as TypeParameterElementImpl).bound =
+        clonable.type;
+    // class Foo extends Clonable<Foo>
+    ClassElementImpl foo = ElementFactory.classElement('Foo', null);
+    foo.supertype = clonable.type.substitute4([foo.type]);
+
+    // <S extends Clonable<S>>
+    var s = TypeBuilder.variable('S');
+    (s.element as TypeParameterElementImpl).bound =
+        clonable.type.substitute4([s]);
+    // (S, S) -> S
+    var clone = TypeBuilder.function(types: [s], required: [s, s], result: s);
+    expect(_inferCall(clone, [foo.type, foo.type]), [foo.type]);
+
+    // Something invalid...
+    expect(_inferCall(clone, [stringType, numType]), [
+      clonable.type.substitute4([dynamicType])
+    ]);
+  }
+
+  void test_genericCastFunction() {
+    // <TFrom, TTo>(TFrom) -> TTo
+    var tFrom = TypeBuilder.variable('TFrom');
+    var tTo = TypeBuilder.variable('TTo');
+    var cast = TypeBuilder
+        .function(types: [tFrom, tTo], required: [tFrom], result: tTo);
+    expect(_inferCall(cast, [intType]), [intType, dynamicType]);
+  }
+
+  void test_genericCastFunctionWithUpperBound() {
+    // <TFrom, TTo extends TFrom>(TFrom) -> TTo
+    var tFrom = TypeBuilder.variable('TFrom');
+    var tTo = TypeBuilder.variable('TTo', bound: tFrom);
+    var cast = TypeBuilder
+        .function(types: [tFrom, tTo], required: [tFrom], result: tTo);
+    expect(_inferCall(cast, [intType]), [intType, intType]);
+  }
+
+  void test_parametersToFunctionParam() {
+    // <T>(f(T t)) -> T
+    var t = TypeBuilder.variable('T');
+    var cast = TypeBuilder.function(types: [
+      t
+    ], required: [
+      TypeBuilder.function(required: [t], result: dynamicType)
+    ], result: t);
+    expect(
+        _inferCall(cast, [
+          TypeBuilder.function(required: [numType], result: dynamicType)
+        ]),
+        [numType]);
+  }
+
+  void test_parametersUseLeastUpperBound() {
+    // <T>(T x, T y) -> T
+    var t = TypeBuilder.variable('T');
+    var cast = TypeBuilder.function(types: [t], required: [t, t], result: t);
+    expect(_inferCall(cast, [intType, doubleType]), [numType]);
+  }
+
+  void test_parameterTypeUsesUpperBound() {
+    // <T extends num>(T) -> dynamic
+    var t = TypeBuilder.variable('T', bound: numType);
+    var f =
+        TypeBuilder.function(types: [t], required: [t], result: dynamicType);
+    expect(_inferCall(f, [intType]), [intType]);
+  }
+
+  void test_returnFunctionWithGenericParameter() {
+    // <T>(T -> T) -> (T -> void)
+    var t = TypeBuilder.variable('T');
+    var f = TypeBuilder.function(types: [
+      t
+    ], required: [
+      TypeBuilder.function(required: [t], result: t)
+    ], result: TypeBuilder.function(required: [t], result: voidType));
+    expect(
+        _inferCall(f, [
+          TypeBuilder.function(required: [numType], result: intType)
+        ]),
+        [numType]);
+  }
+
+  void test_returnFunctionWithGenericParameterAndReturn() {
+    // <T>(T -> T) -> (T -> T)
+    var t = TypeBuilder.variable('T');
+    var f = TypeBuilder.function(types: [
+      t
+    ], required: [
+      TypeBuilder.function(required: [t], result: t)
+    ], result: TypeBuilder.function(required: [t], result: t));
+    expect(
+        _inferCall(f, [
+          TypeBuilder.function(required: [numType], result: intType)
+        ]),
+        [numType]);
+  }
+
+  void test_returnFunctionWithGenericReturn() {
+    // <T>(T -> T) -> (() -> T)
+    var t = TypeBuilder.variable('T');
+    var f = TypeBuilder.function(types: [
+      t
+    ], required: [
+      TypeBuilder.function(required: [t], result: t)
+    ], result: TypeBuilder.function(required: [], result: t));
+    expect(
+        _inferCall(f, [
+          TypeBuilder.function(required: [numType], result: intType)
+        ]),
+        [intType]);
+  }
+
+  void test_unifyParametersToFunctionParam() {
+    // <T>(f(T t), g(T t)) -> T
+    var t = TypeBuilder.variable('T');
+    var cast = TypeBuilder.function(types: [
+      t
+    ], required: [
+      TypeBuilder.function(required: [t], result: dynamicType),
+      TypeBuilder.function(required: [t], result: dynamicType)
+    ], result: t);
+    expect(
+        _inferCall(cast, [
+          TypeBuilder.function(required: [intType], result: dynamicType),
+          TypeBuilder.function(required: [doubleType], result: dynamicType)
+        ]),
+        [dynamicType]);
+  }
+
+  void test_unusedReturnTypeIsDynamic() {
+    // <T>() -> T
+    var t = TypeBuilder.variable('T');
+    var f = TypeBuilder.function(types: [t], required: [], result: t);
+    expect(_inferCall(f, []), [dynamicType]);
+  }
+
+  void test_unusedReturnTypeWithUpperBound() {
+    // <T extends num>() -> T
+    var t = TypeBuilder.variable('T', bound: numType);
+    var f = TypeBuilder.function(types: [t], required: [], result: t);
+    expect(_inferCall(f, []), [numType]);
+  }
+
+  List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments) {
+    FunctionType inferred = typeSystem.inferCallFromArguments(
+        typeProvider, ft, ft.parameters.map((p) => p.type).toList(), arguments);
+    return inferred.typeArguments;
+  }
+}
+
+@reflectiveTest
+class StrongSubtypingTest {
+  TypeProvider typeProvider;
+  TypeSystem typeSystem;
+
+  DartType get bottomType => typeProvider.bottomType;
+  InterfaceType get doubleType => typeProvider.doubleType;
+  DartType get dynamicType => typeProvider.dynamicType;
+  InterfaceType get functionType => typeProvider.functionType;
+  InterfaceType get intType => typeProvider.intType;
+  InterfaceType get listType => typeProvider.listType;
+  InterfaceType get numType => typeProvider.numType;
+  InterfaceType get objectType => typeProvider.objectType;
+  InterfaceType get stringType => typeProvider.stringType;
+  DartType get voidType => VoidTypeImpl.instance;
+
+  void setUp() {
+    typeProvider = new TestTypeProvider();
+    typeSystem = new StrongTypeSystemImpl();
+  }
+
+  void test_bottom_isBottom() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> equivalents = <DartType>[bottomType];
+    List<DartType> supertypes = <DartType>[
+      dynamicType,
+      objectType,
+      intType,
+      doubleType,
+      numType,
+      stringType,
+      functionType,
+      interfaceType
+    ];
+    _checkGroups(bottomType, equivalents: equivalents, supertypes: supertypes);
+  }
+
+  void test_call_method() {
+    ClassElementImpl classBottom = ElementFactory.classElement2("Bottom");
+    MethodElement methodBottom =
+        ElementFactory.methodElement("call", objectType, <DartType>[intType]);
+    classBottom.methods = <MethodElement>[methodBottom];
+
+    DartType top =
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
+    InterfaceType bottom = classBottom.type;
+
+    _checkIsStrictSubtypeOf(bottom, top);
+  }
+
+  void test_classes() {
+    ClassElement classTop = ElementFactory.classElement2("A");
+    ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
+    ClassElement classRight = ElementFactory.classElement("C", classTop.type);
+    ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
+      ..interfaces = <InterfaceType>[classRight.type];
+    InterfaceType top = classTop.type;
+    InterfaceType left = classLeft.type;
+    InterfaceType right = classRight.type;
+    InterfaceType bottom = classBottom.type;
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  void test_double() {
+    List<DartType> equivalents = <DartType>[doubleType];
+    List<DartType> supertypes = <DartType>[numType];
+    List<DartType> unrelated = <DartType>[intType];
+    _checkGroups(doubleType,
+        equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
+  }
+
+  void test_dynamic_isTop() {
+    DartType interfaceType = ElementFactory.classElement2('A', []).type;
+    List<DartType> equivalents = <DartType>[dynamicType, objectType];
+    List<DartType> subtypes = <DartType>[
+      intType,
+      doubleType,
+      numType,
+      stringType,
+      functionType,
+      interfaceType,
+      bottomType
+    ];
+    _checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
+  }
+
+  void test_fuzzy_arrows() {
+    FunctionType top = TypeBuilder
+        .function(required: <DartType>[dynamicType], result: objectType);
+    FunctionType left = TypeBuilder
+        .function(required: <DartType>[objectType], result: objectType);
+    FunctionType right = TypeBuilder
+        .function(required: <DartType>[dynamicType], result: bottomType);
+    FunctionType bottom = TypeBuilder
+        .function(required: <DartType>[objectType], result: bottomType);
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  void test_genericFunction_generic_monomorphic() {
+    DartType s = TypeBuilder.variable("S");
+    DartType t = TypeBuilder.variable("T", bound: s);
+    DartType u = TypeBuilder.variable("U", bound: intType);
+    DartType v = TypeBuilder.variable("V", bound: u);
+
+    _checkIsStrictSubtypeOf(
+        TypeBuilder.function(types: [s, t], required: [s], result: t),
+        TypeBuilder.function(required: [dynamicType], result: dynamicType));
+
+    _checkIsNotSubtypeOf(
+        TypeBuilder.function(types: [u, v], required: [u], result: v),
+        TypeBuilder.function(required: [objectType], result: objectType));
+
+    _checkIsStrictSubtypeOf(
+        TypeBuilder.function(types: [u, v], required: [u], result: v),
+        TypeBuilder.function(required: [intType], result: intType));
+  }
+
+  void test_genericFunction_simple() {
+    DartType s = TypeBuilder.variable("S");
+    DartType t = TypeBuilder.variable("T");
+
+    _checkEquivalent(
+        TypeBuilder.function(types: [t]), TypeBuilder.function(types: [s]));
+
+    _checkEquivalent(TypeBuilder.function(types: [t], required: [t], result: t),
+        TypeBuilder.function(types: [s], required: [s], result: s));
+  }
+
+  void test_genericFunction_simple_bounded() {
+    DartType s = TypeBuilder.variable("S");
+    DartType t = TypeBuilder.variable("T", bound: s);
+    DartType u = TypeBuilder.variable("U");
+    DartType v = TypeBuilder.variable("V", bound: u);
+
+    _checkEquivalent(TypeBuilder.function(types: [s, t]),
+        TypeBuilder.function(types: [u, v]));
+
+    _checkEquivalent(
+        TypeBuilder.function(types: [s, t], required: [s], result: t),
+        TypeBuilder.function(types: [u, v], required: [u], result: v));
+
+    {
+      DartType top =
+          TypeBuilder.function(types: [s, t], required: [t], result: s);
+      DartType left =
+          TypeBuilder.function(types: [u, v], required: [u], result: u);
+      DartType right =
+          TypeBuilder.function(types: [u, v], required: [v], result: v);
+      DartType bottom =
+          TypeBuilder.function(types: [s, t], required: [s], result: t);
+      _checkLattice(top, left, right, bottom);
+    }
+  }
+
+  void test_genericFunction_simple_fBounded() {
+    ClassElementImpl AClass = ElementFactory.classElement2('A', ["Q"]);
+    InterfaceType AType = AClass.type;
+    ClassElementImpl BClass = ElementFactory.classElement2('B', ["R"]);
+    BClass.supertype = AType.substitute4([BClass.typeParameters[0].type]);
+    InterfaceType BType = BClass.type;
+
+    DartType s = TypeBuilder.variable("S");
+    (s.element as TypeParameterElementImpl).bound = AType.substitute4([s]);
+    DartType t = TypeBuilder.variable("T", bound: s);
+    DartType u = TypeBuilder.variable("U");
+    (u.element as TypeParameterElementImpl).bound = BType.substitute4([u]);
+    DartType v = TypeBuilder.variable("V", bound: u);
+
+    _checkIsStrictSubtypeOf(
+        TypeBuilder.function(types: [s]), TypeBuilder.function(types: [u]));
+
+    _checkIsStrictSubtypeOf(
+        TypeBuilder.function(types: [s, t], required: [s], result: t),
+        TypeBuilder.function(types: [u, v], required: [u], result: v));
+  }
+
+  void test_generics() {
+    ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
+    InterfaceType LType = LClass.type;
+    ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
+    DartType typeParam = MClass.typeParameters[0].type;
+    InterfaceType superType = LType.substitute4(<DartType>[typeParam]);
+    MClass.interfaces = <InterfaceType>[superType];
+    InterfaceType MType = MClass.type;
+
+    InterfaceType top = LType.substitute4(<DartType>[dynamicType]);
+    InterfaceType left = MType.substitute4(<DartType>[dynamicType]);
+    InterfaceType right = LType.substitute4(<DartType>[intType]);
+    InterfaceType bottom = MType.substitute4(<DartType>[intType]);
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  void test_int() {
+    List<DartType> equivalents = <DartType>[intType];
+    List<DartType> supertypes = <DartType>[numType];
+    List<DartType> unrelated = <DartType>[doubleType];
+    _checkGroups(intType,
+        equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
+  }
+
+  void test_named_optional() {
+    DartType r =
+        TypeBuilder.function(required: <DartType>[intType], result: intType);
+    DartType o = TypeBuilder.function(
+        required: <DartType>[], optional: <DartType>[intType], result: intType);
+    DartType n = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType},
+        result: intType);
+    DartType rr = TypeBuilder
+        .function(required: <DartType>[intType, intType], result: intType);
+    DartType ro = TypeBuilder.function(
+        required: <DartType>[intType],
+        optional: <DartType>[intType],
+        result: intType);
+    DartType rn = TypeBuilder.function(
+        required: <DartType>[intType],
+        named: <String, DartType>{'x': intType},
+        result: intType);
+    DartType oo = TypeBuilder.function(
+        required: <DartType>[],
+        optional: <DartType>[intType, intType],
+        result: intType);
+    DartType nn = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType, 'y': intType},
+        result: intType);
+    DartType nnn = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType},
+        result: intType);
+
+    _checkGroups(r,
+        equivalents: [r],
+        subtypes: [o, ro, rn, oo],
+        unrelated: [n, rr, nn, nnn]);
+    _checkGroups(o,
+        equivalents: [o], subtypes: [oo], unrelated: [n, rr, ro, rn, nn, nnn]);
+    _checkGroups(n,
+        equivalents: [n],
+        subtypes: [nn, nnn],
+        unrelated: [r, o, rr, ro, rn, oo]);
+    _checkGroups(rr,
+        equivalents: [rr],
+        subtypes: [ro, oo],
+        unrelated: [r, o, n, rn, nn, nnn]);
+    _checkGroups(ro,
+        equivalents: [ro], subtypes: [oo], unrelated: [o, n, rn, nn, nnn]);
+    _checkGroups(rn,
+        equivalents: [rn],
+        subtypes: [],
+        unrelated: [o, n, rr, ro, oo, nn, nnn]);
+    _checkGroups(oo,
+        equivalents: [oo], subtypes: [], unrelated: [n, rn, nn, nnn]);
+    _checkGroups(nn,
+        equivalents: [nn], subtypes: [nnn], unrelated: [r, o, rr, ro, rn, oo]);
+    _checkGroups(nnn,
+        equivalents: [nnn], subtypes: [], unrelated: [r, o, rr, ro, rn, oo]);
+  }
+
+  void test_num() {
+    List<DartType> equivalents = <DartType>[numType];
+    List<DartType> supertypes = <DartType>[];
+    List<DartType> unrelated = <DartType>[stringType];
+    List<DartType> subtypes = <DartType>[intType, doubleType];
+    _checkGroups(numType,
+        equivalents: equivalents,
+        supertypes: supertypes,
+        unrelated: unrelated,
+        subtypes: subtypes);
+  }
+
+  void test_simple_function() {
+    FunctionType top =
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
+    FunctionType left =
+        TypeBuilder.function(required: <DartType>[intType], result: intType);
+    FunctionType right = TypeBuilder
+        .function(required: <DartType>[objectType], result: objectType);
+    FunctionType bottom =
+        TypeBuilder.function(required: <DartType>[objectType], result: intType);
+
+    _checkLattice(top, left, right, bottom);
+  }
+
+  /// Regression test for https://github.com/dart-lang/sdk/issues/25069
+  void test_simple_function_void() {
+    FunctionType functionType =
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
+    _checkIsNotSubtypeOf(voidType, functionType);
+  }
+
+  void test_void_functions() {
+    FunctionType top =
+        TypeBuilder.function(required: <DartType>[intType], result: voidType);
+    FunctionType bottom =
+        TypeBuilder.function(required: <DartType>[objectType], result: intType);
+
+    _checkIsStrictSubtypeOf(bottom, top);
+  }
+
+  void _checkEquivalent(DartType type1, DartType type2) {
+    _checkIsSubtypeOf(type1, type2);
+    _checkIsSubtypeOf(type2, type1);
+  }
+
+  void _checkGroups(DartType t1,
+      {List<DartType> equivalents,
+      List<DartType> unrelated,
+      List<DartType> subtypes,
+      List<DartType> supertypes}) {
+    if (equivalents != null) {
+      for (DartType t2 in equivalents) {
+        _checkEquivalent(t1, t2);
+      }
+    }
+    if (unrelated != null) {
+      for (DartType t2 in unrelated) {
+        _checkUnrelated(t1, t2);
+      }
+    }
+    if (subtypes != null) {
+      for (DartType t2 in subtypes) {
+        _checkIsStrictSubtypeOf(t2, t1);
+      }
+    }
+    if (supertypes != null) {
+      for (DartType t2 in supertypes) {
+        _checkIsStrictSubtypeOf(t1, t2);
+      }
+    }
+  }
+
+  void _checkIsNotSubtypeOf(DartType type1, DartType type2) {
+    expect(typeSystem.isSubtypeOf(type1, type2), false);
+  }
+
+  void _checkIsStrictSubtypeOf(DartType type1, DartType type2) {
+    _checkIsSubtypeOf(type1, type2);
+    _checkIsNotSubtypeOf(type2, type1);
+  }
+
+  void _checkIsSubtypeOf(DartType type1, DartType type2) {
+    expect(typeSystem.isSubtypeOf(type1, type2), true);
+  }
+
+  void _checkLattice(
+      DartType top, DartType left, DartType right, DartType bottom) {
+    _checkGroups(top,
+        equivalents: <DartType>[top],
+        subtypes: <DartType>[left, right, bottom]);
+    _checkGroups(left,
+        equivalents: <DartType>[left],
+        subtypes: <DartType>[bottom],
+        unrelated: <DartType>[right],
+        supertypes: <DartType>[top]);
+    _checkGroups(right,
+        equivalents: <DartType>[right],
+        subtypes: <DartType>[bottom],
+        unrelated: <DartType>[left],
+        supertypes: <DartType>[top]);
+    _checkGroups(bottom,
+        equivalents: <DartType>[bottom],
+        supertypes: <DartType>[top, left, right]);
+  }
+
+  void _checkUnrelated(DartType type1, DartType type2) {
+    _checkIsNotSubtypeOf(type1, type2);
+    _checkIsNotSubtypeOf(type2, type1);
+  }
+}
+
+class TypeBuilder {
+  static FunctionTypeImpl function(
+      {List<DartType> types,
+      List<DartType> required,
+      List<DartType> optional,
+      Map<String, DartType> named,
+      DartType result}) {
+    result = result ?? VoidTypeImpl.instance;
+    required = required ?? [];
+    FunctionElementImpl f = ElementFactory.functionElement8(required, result,
+        optional: optional, named: named);
+    if (types != null) {
+      f.typeParameters =
+          new List<TypeParameterElement>.from(types.map((t) => t.element));
+    }
+    return f.type = new FunctionTypeImpl(f);
+  }
+
+  static TypeParameterType variable(String name, {DartType bound}) =>
+      ElementFactory.typeParameterWithType(name, bound).type;
 }
 
 @reflectiveTest
@@ -368,561 +1248,3 @@
         expectedResult);
   }
 }
-
-class TypeBuilder {
-  static FunctionType functionType(
-      List<DartType> parameters, DartType returnType,
-      {List<DartType> optional, Map<String, DartType> named}) {
-    return ElementFactory
-        .functionElement8(parameters, returnType,
-            optional: optional, named: named)
-        .type;
-  }
-}
-
-@reflectiveTest
-class StrongSubtypingTest {
-  TypeProvider typeProvider;
-  TypeSystem typeSystem;
-
-  DartType get bottomType => typeProvider.bottomType;
-  InterfaceType get doubleType => typeProvider.doubleType;
-  DartType get dynamicType => typeProvider.dynamicType;
-  InterfaceType get functionType => typeProvider.functionType;
-  InterfaceType get intType => typeProvider.intType;
-  InterfaceType get listType => typeProvider.listType;
-  InterfaceType get numType => typeProvider.numType;
-  InterfaceType get objectType => typeProvider.objectType;
-  InterfaceType get stringType => typeProvider.stringType;
-  DartType get voidType => VoidTypeImpl.instance;
-
-  void setUp() {
-    typeProvider = new TestTypeProvider();
-    typeSystem = new StrongTypeSystemImpl();
-  }
-
-  void test_isSubtypeOf_dynamic_isTop() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> equivalents = <DartType>[dynamicType, objectType];
-    List<DartType> subtypes = <DartType>[
-      intType,
-      doubleType,
-      numType,
-      stringType,
-      functionType,
-      interfaceType,
-      bottomType
-    ];
-    _checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
-  }
-
-  void test_isSubtypeOf_bottom_isBottom() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> equivalents = <DartType>[bottomType];
-    List<DartType> supertypes = <DartType>[
-      dynamicType,
-      objectType,
-      intType,
-      doubleType,
-      numType,
-      stringType,
-      functionType,
-      interfaceType
-    ];
-    _checkGroups(bottomType, equivalents: equivalents, supertypes: supertypes);
-  }
-
-  void test_isSubtypeOf_int() {
-    List<DartType> equivalents = <DartType>[intType];
-    List<DartType> supertypes = <DartType>[numType];
-    List<DartType> unrelated = <DartType>[doubleType];
-    _checkGroups(intType,
-        equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
-  }
-
-  void test_isSubtypeOf_double() {
-    List<DartType> equivalents = <DartType>[doubleType];
-    List<DartType> supertypes = <DartType>[numType];
-    List<DartType> unrelated = <DartType>[intType];
-    _checkGroups(doubleType,
-        equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
-  }
-
-  void test_isSubtypeOf_num() {
-    List<DartType> equivalents = <DartType>[numType];
-    List<DartType> supertypes = <DartType>[];
-    List<DartType> unrelated = <DartType>[stringType];
-    List<DartType> subtypes = <DartType>[intType, doubleType];
-    _checkGroups(numType,
-        equivalents: equivalents,
-        supertypes: supertypes,
-        unrelated: unrelated,
-        subtypes: subtypes);
-  }
-
-  void test_isSubtypeOf_classes() {
-    ClassElement classTop = ElementFactory.classElement2("A");
-    ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
-    ClassElement classRight = ElementFactory.classElement("C", classTop.type);
-    ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
-      ..interfaces = <InterfaceType>[classRight.type];
-    InterfaceType top = classTop.type;
-    InterfaceType left = classLeft.type;
-    InterfaceType right = classRight.type;
-    InterfaceType bottom = classBottom.type;
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void test_isSubtypeOf_simple_function() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[intType], objectType);
-    FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void test_isSubtypeOf_call_method() {
-    ClassElementImpl classBottom = ElementFactory.classElement2("Bottom");
-    MethodElement methodBottom =
-        ElementFactory.methodElement("call", objectType, <DartType>[intType]);
-    classBottom.methods = <MethodElement>[methodBottom];
-
-    DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
-    InterfaceType bottom = classBottom.type;
-
-    _checkIsStrictSubtypeOf(bottom, top);
-  }
-
-  void test_isSubtypeOf_fuzzy_arrows() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[dynamicType], objectType);
-    FunctionType left =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], bottomType);
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void test_isSubtypeOf_void_functions() {
-    FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
-
-    _checkIsStrictSubtypeOf(bottom, top);
-  }
-
-  void test_isSubtypeOf_named_optional() {
-    DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
-    DartType o = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType]);
-    DartType n = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType});
-    DartType rr =
-        TypeBuilder.functionType(<DartType>[intType, intType], intType);
-    DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
-        optional: <DartType>[intType]);
-    DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
-        named: <String, DartType>{'x': intType});
-    DartType oo = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType, intType]);
-    DartType nn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType});
-    DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
-
-    _checkGroups(r,
-        equivalents: [r],
-        subtypes: [o, ro, rn, oo],
-        unrelated: [n, rr, nn, nnn]);
-    _checkGroups(o,
-        equivalents: [o], subtypes: [oo], unrelated: [n, rr, ro, rn, nn, nnn]);
-    _checkGroups(n,
-        equivalents: [n],
-        subtypes: [nn, nnn],
-        unrelated: [r, o, rr, ro, rn, oo]);
-    _checkGroups(rr,
-        equivalents: [rr],
-        subtypes: [ro, oo],
-        unrelated: [r, o, n, rn, nn, nnn]);
-    _checkGroups(ro,
-        equivalents: [ro], subtypes: [oo], unrelated: [o, n, rn, nn, nnn]);
-    _checkGroups(rn,
-        equivalents: [rn],
-        subtypes: [],
-        unrelated: [o, n, rr, ro, oo, nn, nnn]);
-    _checkGroups(oo,
-        equivalents: [oo], subtypes: [], unrelated: [n, rn, nn, nnn]);
-    _checkGroups(nn,
-        equivalents: [nn], subtypes: [nnn], unrelated: [r, o, rr, ro, rn, oo]);
-    _checkGroups(nnn,
-        equivalents: [nnn], subtypes: [], unrelated: [r, o, rr, ro, rn, oo]);
-  }
-
-  void test_isSubtypeOf_generics() {
-    ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
-    InterfaceType LType = LClass.type;
-    ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
-    DartType typeParam = MClass.typeParameters[0].type;
-    InterfaceType superType = LType.substitute4(<DartType>[typeParam]);
-    MClass.interfaces = <InterfaceType>[superType];
-    InterfaceType MType = MClass.type;
-
-    InterfaceType top = LType.substitute4(<DartType>[dynamicType]);
-    InterfaceType left = MType.substitute4(<DartType>[dynamicType]);
-    InterfaceType right = LType.substitute4(<DartType>[intType]);
-    InterfaceType bottom = MType.substitute4(<DartType>[intType]);
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void _checkLattice(
-      DartType top, DartType left, DartType right, DartType bottom) {
-    _checkGroups(top,
-        equivalents: <DartType>[top],
-        subtypes: <DartType>[left, right, bottom]);
-    _checkGroups(left,
-        equivalents: <DartType>[left],
-        subtypes: <DartType>[bottom],
-        unrelated: <DartType>[right],
-        supertypes: <DartType>[top]);
-    _checkGroups(right,
-        equivalents: <DartType>[right],
-        subtypes: <DartType>[bottom],
-        unrelated: <DartType>[left],
-        supertypes: <DartType>[top]);
-    _checkGroups(bottom,
-        equivalents: <DartType>[bottom],
-        supertypes: <DartType>[top, left, right]);
-  }
-
-  void _checkGroups(DartType t1,
-      {List<DartType> equivalents,
-      List<DartType> unrelated,
-      List<DartType> subtypes,
-      List<DartType> supertypes}) {
-    if (equivalents != null) {
-      for (DartType t2 in equivalents) {
-        _checkEquivalent(t1, t2);
-      }
-    }
-    if (unrelated != null) {
-      for (DartType t2 in unrelated) {
-        _checkUnrelated(t1, t2);
-      }
-    }
-    if (subtypes != null) {
-      for (DartType t2 in subtypes) {
-        _checkIsStrictSubtypeOf(t2, t1);
-      }
-    }
-    if (supertypes != null) {
-      for (DartType t2 in supertypes) {
-        _checkIsStrictSubtypeOf(t1, t2);
-      }
-    }
-  }
-
-  void _checkUnrelated(DartType type1, DartType type2) {
-    _checkIsNotSubtypeOf(type1, type2);
-    _checkIsNotSubtypeOf(type2, type1);
-  }
-
-  void _checkEquivalent(DartType type1, DartType type2) {
-    _checkIsSubtypeOf(type1, type2);
-    _checkIsSubtypeOf(type2, type1);
-  }
-
-  void _checkIsStrictSubtypeOf(DartType type1, DartType type2) {
-    _checkIsSubtypeOf(type1, type2);
-    _checkIsNotSubtypeOf(type2, type1);
-  }
-
-  void _checkIsSubtypeOf(DartType type1, DartType type2) {
-    expect(typeSystem.isSubtypeOf(type1, type2), true);
-  }
-
-  void _checkIsNotSubtypeOf(DartType type1, DartType type2) {
-    expect(typeSystem.isSubtypeOf(type1, type2), false);
-  }
-}
-
-@reflectiveTest
-class StrongAssignabilityTest {
-  TypeProvider typeProvider;
-  TypeSystem typeSystem;
-
-  DartType get bottomType => typeProvider.bottomType;
-  InterfaceType get doubleType => typeProvider.doubleType;
-  DartType get dynamicType => typeProvider.dynamicType;
-  InterfaceType get functionType => typeProvider.functionType;
-  InterfaceType get intType => typeProvider.intType;
-  InterfaceType get listType => typeProvider.listType;
-  InterfaceType get numType => typeProvider.numType;
-  InterfaceType get objectType => typeProvider.objectType;
-  InterfaceType get stringType => typeProvider.stringType;
-  DartType get voidType => VoidTypeImpl.instance;
-
-  void setUp() {
-    typeProvider = new TestTypeProvider();
-    typeSystem = new StrongTypeSystemImpl();
-  }
-
-  void test_isAssignableTo_dynamic_isTop() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      intType,
-      doubleType,
-      numType,
-      stringType,
-      interfaceType,
-      bottomType
-    ];
-    _checkGroups(dynamicType, interassignable: interassignable);
-  }
-
-  void test_isAssignableTo_bottom_isBottom() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      intType,
-      doubleType,
-      numType,
-      stringType,
-      interfaceType,
-      bottomType
-    ];
-
-    _checkGroups(bottomType, interassignable: interassignable);
-  }
-
-  void test_isAssignableTo_int() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      intType,
-      numType,
-      bottomType
-    ];
-    List<DartType> unrelated = <DartType>[
-      doubleType,
-      stringType,
-      interfaceType,
-    ];
-
-    _checkGroups(intType,
-        interassignable: interassignable, unrelated: unrelated);
-  }
-
-  void test_isAssignableTo_double() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      doubleType,
-      numType,
-      bottomType
-    ];
-    List<DartType> unrelated = <DartType>[intType, stringType, interfaceType,];
-
-    _checkGroups(doubleType,
-        interassignable: interassignable, unrelated: unrelated);
-  }
-
-  void test_isAssignableTo_num() {
-    DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    List<DartType> interassignable = <DartType>[
-      dynamicType,
-      objectType,
-      numType,
-      intType,
-      doubleType,
-      bottomType
-    ];
-    List<DartType> unrelated = <DartType>[stringType, interfaceType,];
-
-    _checkGroups(numType,
-        interassignable: interassignable, unrelated: unrelated);
-  }
-
-  void test_isAssignableTo_classes() {
-    ClassElement classTop = ElementFactory.classElement2("A");
-    ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
-    ClassElement classRight = ElementFactory.classElement("C", classTop.type);
-    ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
-      ..interfaces = <InterfaceType>[classRight.type];
-    InterfaceType top = classTop.type;
-    InterfaceType left = classLeft.type;
-    InterfaceType right = classRight.type;
-    InterfaceType bottom = classBottom.type;
-
-    _checkLattice(top, left, right, bottom);
-  }
-
-  void test_isAssignableTo_simple_function() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[intType], objectType);
-    FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
-
-    _checkCrossLattice(top, left, right, bottom);
-  }
-
-  void test_isAssignableTo_call_method() {
-    ClassElementImpl classBottom = ElementFactory.classElement2("B");
-    MethodElement methodBottom =
-        ElementFactory.methodElement("call", objectType, <DartType>[intType]);
-    classBottom.methods = <MethodElement>[methodBottom];
-
-    DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
-    InterfaceType bottom = classBottom.type;
-
-    _checkIsStrictAssignableTo(bottom, top);
-  }
-
-  void test_isAssignableTo_fuzzy_arrows() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[dynamicType], objectType);
-    FunctionType left =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], bottomType);
-
-    _checkCrossLattice(top, left, right, bottom);
-  }
-
-  void test_isAssignableTo_void_functions() {
-    FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
-
-    _checkEquivalent(bottom, top);
-  }
-
-  void test_isAssignableTo_named_optional() {
-    DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
-    DartType o = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType]);
-    DartType n = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType});
-    DartType rr =
-        TypeBuilder.functionType(<DartType>[intType, intType], intType);
-    DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
-        optional: <DartType>[intType]);
-    DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
-        named: <String, DartType>{'x': intType});
-    DartType oo = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType, intType]);
-    DartType nn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType});
-    DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
-
-    _checkGroups(r,
-        interassignable: [r, o, ro, rn, oo], unrelated: [n, rr, nn, nnn]);
-    _checkGroups(o,
-        interassignable: [o, oo], unrelated: [n, rr, ro, rn, nn, nnn]);
-    _checkGroups(n,
-        interassignable: [n, nn, nnn], unrelated: [r, o, rr, ro, rn, oo]);
-    _checkGroups(rr,
-        interassignable: [rr, ro, oo], unrelated: [r, o, n, rn, nn, nnn]);
-    _checkGroups(ro, interassignable: [ro, oo], unrelated: [o, n, rn, nn, nnn]);
-    _checkGroups(rn,
-        interassignable: [rn], unrelated: [o, n, rr, ro, oo, nn, nnn]);
-    _checkGroups(oo, interassignable: [oo], unrelated: [n, rn, nn, nnn]);
-    _checkGroups(nn,
-        interassignable: [nn, nnn], unrelated: [r, o, rr, ro, rn, oo]);
-    _checkGroups(nnn,
-        interassignable: [nnn], unrelated: [r, o, rr, ro, rn, oo]);
-  }
-
-  void test_isAssignableTo_generics() {
-    ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
-    InterfaceType LType = LClass.type;
-    ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
-    DartType typeParam = MClass.typeParameters[0].type;
-    InterfaceType superType = LType.substitute4(<DartType>[typeParam]);
-    MClass.interfaces = <InterfaceType>[superType];
-    InterfaceType MType = MClass.type;
-
-    InterfaceType top = LType.substitute4(<DartType>[dynamicType]);
-    InterfaceType left = MType.substitute4(<DartType>[dynamicType]);
-    InterfaceType right = LType.substitute4(<DartType>[intType]);
-    InterfaceType bottom = MType.substitute4(<DartType>[intType]);
-
-    _checkCrossLattice(top, left, right, bottom);
-  }
-
-  void _checkCrossLattice(
-      DartType top, DartType left, DartType right, DartType bottom) {
-    _checkGroups(top, interassignable: <DartType>[top, left, right, bottom]);
-    _checkGroups(left, interassignable: <DartType>[top, left, right, bottom]);
-    _checkGroups(right, interassignable: <DartType>[top, left, right, bottom]);
-    _checkGroups(bottom, interassignable: <DartType>[top, left, right, bottom]);
-  }
-
-  void _checkLattice(
-      DartType top, DartType left, DartType right, DartType bottom) {
-    _checkGroups(top, interassignable: <DartType>[top, left, right, bottom]);
-    _checkGroups(left,
-        interassignable: <DartType>[top, left, bottom],
-        unrelated: <DartType>[right]);
-    _checkGroups(right,
-        interassignable: <DartType>[top, right, bottom],
-        unrelated: <DartType>[left]);
-    _checkGroups(bottom, interassignable: <DartType>[top, left, right, bottom]);
-  }
-
-  void _checkGroups(DartType t1,
-      {List<DartType> interassignable, List<DartType> unrelated}) {
-    if (interassignable != null) {
-      for (DartType t2 in interassignable) {
-        _checkEquivalent(t1, t2);
-      }
-    }
-    if (unrelated != null) {
-      for (DartType t2 in unrelated) {
-        _checkUnrelated(t1, t2);
-      }
-    }
-  }
-
-  void _checkUnrelated(DartType type1, DartType type2) {
-    _checkIsNotAssignableTo(type1, type2);
-    _checkIsNotAssignableTo(type2, type1);
-  }
-
-  void _checkEquivalent(DartType type1, DartType type2) {
-    _checkIsAssignableTo(type1, type2);
-    _checkIsAssignableTo(type2, type1);
-  }
-
-  void _checkIsStrictAssignableTo(DartType type1, DartType type2) {
-    _checkIsAssignableTo(type1, type2);
-    _checkIsNotAssignableTo(type2, type1);
-  }
-
-  void _checkIsAssignableTo(DartType type1, DartType type2) {
-    expect(typeSystem.isAssignableTo(type1, type2), true);
-  }
-
-  void _checkIsNotAssignableTo(DartType type1, DartType type2) {
-    expect(typeSystem.isAssignableTo(type1, type2), false);
-  }
-}
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 24263e7..bd5876b 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities_test;
+library analyzer.test.generated.utilities_test;
 
 import 'dart:collection';
 
@@ -2109,6 +2109,12 @@
   Expression get(AssertStatement node) => node.condition;
 }
 
+class Getter_NodeReplacerTest_test_assertStatement_2
+    implements NodeReplacerTest_Getter {
+  @override
+  Expression get(AssertStatement node) => node.message;
+}
+
 class Getter_NodeReplacerTest_test_assignmentExpression
     implements NodeReplacerTest_Getter {
   @override
@@ -3460,9 +3466,10 @@
   }
 
   void test_assertStatement() {
-    AssertStatement node =
-        AstFactory.assertStatement(AstFactory.booleanLiteral(true));
+    AssertStatement node = AstFactory.assertStatement(
+        AstFactory.booleanLiteral(true), AstFactory.string2('foo'));
     _assertReplace(node, new Getter_NodeReplacerTest_test_assertStatement());
+    _assertReplace(node, new Getter_NodeReplacerTest_test_assertStatement_2());
   }
 
   void test_assignmentExpression() {
@@ -4566,6 +4573,21 @@
 
 @reflectiveTest
 class StringUtilitiesTest {
+  void test_computeLineStarts_n() {
+    List<int> starts = StringUtilities.computeLineStarts('a\nbb\nccc');
+    expect(starts, <int>[0, 2, 5]);
+  }
+
+  void test_computeLineStarts_r() {
+    List<int> starts = StringUtilities.computeLineStarts('a\rbb\rccc');
+    expect(starts, <int>[0, 2, 5]);
+  }
+
+  void test_computeLineStarts_rn() {
+    List<int> starts = StringUtilities.computeLineStarts('a\r\nbb\r\nccc');
+    expect(starts, <int>[0, 3, 7]);
+  }
+
   void test_EMPTY() {
     expect(StringUtilities.EMPTY, "");
     expect(StringUtilities.EMPTY.isEmpty, isTrue);
diff --git a/pkg/analyzer/test/instrumentation/instrumentation_test.dart b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
index 290b71a..a938d4d 100644
--- a/pkg/analyzer/test/instrumentation/instrumentation_test.dart
+++ b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
@@ -2,7 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.instrumentation;
+library analyzer.test.instrumentation.instrumentation_test;
+
+import 'dart:async';
 
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:unittest/unittest.dart';
@@ -174,7 +176,7 @@
   }
 
   @override
-  void shutdown() {
+  Future shutdown() async {
     // Ignored
   }
 }
diff --git a/pkg/analyzer/test/instrumentation/test_all.dart b/pkg/analyzer/test/instrumentation/test_all.dart
index f9bfc2d..46bb206 100644
--- a/pkg/analyzer/test/instrumentation/test_all.dart
+++ b/pkg/analyzer/test/instrumentation/test_all.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.instrumentation.test_all;
+library analyzer.test.instrumentation.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/parse_compilation_unit_test.dart b/pkg/analyzer/test/parse_compilation_unit_test.dart
index 71e4838..c5313da 100644
--- a/pkg/analyzer/test/parse_compilation_unit_test.dart
+++ b/pkg/analyzer/test/parse_compilation_unit_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.parse.compilation.unit;
+library analyzer.test.parse_compilation_unit_test;
 
 import 'package:analyzer/analyzer.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/reflective_tests.dart b/pkg/analyzer/test/reflective_tests.dart
index 8180cf7..24c36cb 100644
--- a/pkg/analyzer/test/reflective_tests.dart
+++ b/pkg/analyzer/test/reflective_tests.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library reflective_tests;
+library analyzer.test.reflective_tests;
 
 @MirrorsUsed(metaTargets: 'ReflectiveTest')
 import 'dart:mirrors';
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index 4cf41fd..d71304b 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.source.analysis_options_provider;
+library analyzer.test.source.analysis_options_provider_test;
 
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
@@ -13,6 +13,60 @@
 
 main() {
   initializeTestEnvironment();
+
+  group('AnalysisOptionsProvider', () {
+    void expectMergesTo(String defaults, String overrides, String expected) {
+      var optionsProvider = new AnalysisOptionsProvider();
+      var defaultOptions = optionsProvider.getOptionsFromString(defaults);
+      var overrideOptions = optionsProvider.getOptionsFromString(overrides);
+      var merged = optionsProvider.merge(defaultOptions, overrideOptions);
+      expect(merged, optionsProvider.getOptionsFromString(expected));
+    }
+
+    group('merging', () {
+      test('integration', () {
+        expectMergesTo(
+            '''
+analyzer:
+  plugins:
+    - p1
+    - p2
+  errors:
+    unused_local_variable : error
+linter:
+  rules:
+    - camel_case_types
+    - one_member_abstracts
+''',
+            '''
+analyzer:
+  plugins:
+    - p3
+  errors:
+    unused_local_variable : ignore # overrides error
+linter:
+  rules:
+    one_member_abstracts: false # promotes and disables
+    always_specify_return_types: true
+''',
+            '''
+analyzer:
+  plugins:
+    - p1
+    - p2
+    - p3
+  errors:
+    unused_local_variable : ignore
+linter:
+  rules:
+    camel_case_types: true
+    one_member_abstracts: false
+    always_specify_return_types: true
+''');
+      });
+    });
+  });
+
   group('AnalysisOptionsProvider', () {
     setUp(() {
       buildResourceProvider();
@@ -24,21 +78,21 @@
       var optionsProvider = new AnalysisOptionsProvider();
       Map<String, YamlNode> options =
           optionsProvider.getOptions(resourceProvider.getFolder('/'));
-      expect(options.length, equals(1));
+      expect(options, hasLength(1));
       expect(options['analyzer'], isNotNull);
       YamlMap analyzer = options['analyzer'];
-      expect(analyzer.length, equals(1));
+      expect(analyzer, hasLength(1));
       expect(analyzer['ignore'], isNotNull);
       YamlList ignore = analyzer['ignore'];
-      expect(ignore.length, equals(2));
-      expect(ignore[0], equals('ignoreme.dart'));
-      expect(ignore[1], equals('sdk_ext/**'));
+      expect(ignore, hasLength(2));
+      expect(ignore[0], 'ignoreme.dart');
+      expect(ignore[1], 'sdk_ext/**');
     });
     test('test_doesnotexist', () {
       var optionsProvider = new AnalysisOptionsProvider();
       Map<String, YamlNode> options =
           optionsProvider.getOptions(resourceProvider.getFolder('/empty'));
-      expect(options.length, equals(0));
+      expect(options, isEmpty);
     });
   });
   group('AnalysisOptionsProvider', () {
@@ -75,12 +129,37 @@
       expect(exceptionCaught, isTrue);
     });
   });
+  group('AnalysisOptionsProvider', () {
+    test('test_bad_yaml (1)', () {
+      var src = '''
+    analyzer: # <= bang
+strong-mode: true
+''';
+
+      var optionsProvider = new AnalysisOptionsProvider();
+      expect(() => optionsProvider.getOptionsFromString(src),
+          throwsA(new isInstanceOf<OptionsFormatException>()));
+    });
+
+    test('test_bad_yaml (2)', () {
+      var src = '''
+analyzer:
+  strong-mode:true # missing space (sdk/issues/24885)
+''';
+
+      var optionsProvider = new AnalysisOptionsProvider();
+      // Should not throw an exception.
+      var options = optionsProvider.getOptionsFromString(src);
+      // Should return a non-null options list.
+      expect(options, isNotNull);
+    });
+  });
 }
 
 MemoryResourceProvider resourceProvider;
 
-buildResourceProvider({bool emptyAnalysisOptions : false,
-                       bool badAnalysisOptions : false}) {
+buildResourceProvider(
+    {bool emptyAnalysisOptions: false, bool badAnalysisOptions: false}) {
   resourceProvider = new MemoryResourceProvider();
   resourceProvider.newFolder('/empty');
   resourceProvider.newFolder('/tmp');
@@ -90,8 +169,8 @@
     resourceProvider.newFile('/.analysis_options', r'''#empty''');
   } else {
     resourceProvider.newFile(
-      '/.analysis_options',
-      r'''
+        '/.analysis_options',
+        r'''
 analyzer:
   ignore:
     - ignoreme.dart
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
new file mode 100644
index 0000000..c152773
--- /dev/null
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -0,0 +1,88 @@
+// 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.test.source.embedder_test;
+
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/source/embedder.dart';
+import 'package:unittest/unittest.dart';
+
+import '../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  group('EmbedderUriResolverTest', () {
+    setUp(() {
+      buildResourceProvider();
+    });
+    tearDown(() {
+      clearResourceProvider();
+    });
+    test('test_NullEmbedderYamls', () {
+      var resolver = new EmbedderUriResolver(null);
+      expect(resolver.length, equals(0));
+    });
+    test('test_NoEmbedderYamls', () {
+      var locator = new EmbedderYamlLocator({
+        'fox': [resourceProvider.getResource('/empty')]
+      });
+      expect(locator.embedderYamls.length, equals(0));
+    });
+    test('test_EmbedderYaml', () {
+      var locator = new EmbedderYamlLocator({
+        'fox': [resourceProvider.getResource('/tmp')]
+      });
+      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      // We have four mappings.
+      expect(resolver.length, equals(4));
+      // Check that they map to the correct paths.
+      expect(resolver['dart:fox'], equals("/tmp/slippy.dart"));
+      expect(resolver['dart:bear'], equals("/tmp/grizzly.dart"));
+      expect(resolver['dart:relative'], equals("/relative.dart"));
+      expect(resolver['dart:deep'], equals("/tmp/deep/directory/file.dart"));
+    });
+    test('test_BadYAML', () {
+      var locator = new EmbedderYamlLocator(null);
+      locator.addEmbedderYaml(null, r'''{{{,{{}}},}}''');
+      expect(locator.embedderYamls.length, equals(0));
+    });
+    test('test_restoreAbsolute', () {
+      var locator = new EmbedderYamlLocator({
+        'fox': [resourceProvider.getResource('/tmp')]
+      });
+      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var source = resolver.resolveAbsolute(Uri.parse('dart:fox'));
+      expect(source, isNotNull);
+      // Restore source's uri.
+      var restoreUri = resolver.restoreAbsolute(source);
+      expect(restoreUri, isNotNull);
+      // Verify that it is 'dart:fox'.
+      expect(restoreUri.toString(), equals('dart:fox'));
+      expect(restoreUri.scheme, equals('dart'));
+      expect(restoreUri.path, equals('fox'));
+    });
+  });
+}
+
+MemoryResourceProvider resourceProvider;
+
+buildResourceProvider() {
+  resourceProvider = new MemoryResourceProvider();
+  resourceProvider.newFolder('/empty');
+  resourceProvider.newFolder('/tmp');
+  resourceProvider.newFile(
+      '/tmp/_embedder.yaml',
+      r'''
+embedder_libs:
+  "dart:fox": "slippy.dart"
+  "dart:bear": "grizzly.dart"
+  "dart:relative": "../relative.dart"
+  "dart:deep": "deep/directory/file.dart"
+  "fart:loudly": "nomatter.dart"
+''');
+}
+
+clearResourceProvider() {
+  resourceProvider = null;
+}
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
new file mode 100644
index 0000000..3c3facb
--- /dev/null
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -0,0 +1,150 @@
+// 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.test.source.error_processor;
+
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
+import 'package:unittest/unittest.dart';
+import 'package:yaml/src/yaml_node.dart';
+
+import '../generated/test_support.dart';
+import '../utils.dart';
+
+main() {
+  AnalysisError invalid_assignment =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
+    ['x'],
+    ['y']
+  ]);
+
+  AnalysisError missing_return =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
+    ['x']
+  ]);
+
+  AnalysisError unused_local_variable = new AnalysisError(
+      new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+    ['x']
+  ]);
+
+  AnalysisError use_of_void_result =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.USE_OF_VOID_RESULT, [
+    ['x']
+  ]);
+
+  initializeTestEnvironment();
+  oneTimeSetup();
+
+  setUp(() {
+    context = new TestContext();
+  });
+
+  group('ErrorProcessorTest', () {
+    test('configureOptions', () {
+      configureOptions('''
+analyzer:
+  errors:
+    invalid_assignment: error # severity ERROR
+    missing_return: false # ignore
+    unused_local_variable: true # skipped
+    use_of_void_result: unsupported_action # skipped
+''');
+      expect(getProcessor(invalid_assignment).severity, ErrorSeverity.ERROR);
+      expect(getProcessor(missing_return).severity, isNull);
+      expect(getProcessor(unused_local_variable), isNull);
+      expect(getProcessor(use_of_void_result), isNull);
+    });
+  });
+
+  group('ErrorConfigTest', () {
+    var config = '''
+analyzer:
+  errors:
+    invalid_assignment: unsupported_action # should be skipped
+    missing_return: false
+    unused_local_variable: error
+''';
+
+    group('processing', () {
+      test('yaml map', () {
+        var options = optionsProvider.getOptionsFromString(config);
+        var errorConfig = new ErrorConfig(options['analyzer']['errors']);
+        expect(errorConfig.processors, hasLength(2));
+
+        // ignore
+        var missingReturnProcessor = errorConfig.processors
+            .firstWhere((p) => p.appliesTo(missing_return));
+        expect(missingReturnProcessor.severity, isNull);
+
+        // error
+        var unusedLocalProcessor = errorConfig.processors
+            .firstWhere((p) => p.appliesTo(unused_local_variable));
+        expect(unusedLocalProcessor.severity, ErrorSeverity.ERROR);
+
+        // skip
+        var invalidAssignmentProcessor = errorConfig.processors.firstWhere(
+            (p) => p.appliesTo(invalid_assignment),
+            orElse: () => null);
+        expect(invalidAssignmentProcessor, isNull);
+      });
+      test('string map', () {
+        var options = {
+          'invalid_assignment': 'unsupported_action', // should be skipped
+          'missing_return': 'false',
+          'unused_local_variable': 'error'
+        };
+        var errorConfig = new ErrorConfig(options);
+        expect(errorConfig.processors, hasLength(2));
+
+        // ignore
+        var missingReturnProcessor = errorConfig.processors
+            .firstWhere((p) => p.appliesTo(missing_return));
+        expect(missingReturnProcessor.severity, isNull);
+
+        // error
+        var unusedLocalProcessor = errorConfig.processors
+            .firstWhere((p) => p.appliesTo(unused_local_variable));
+        expect(unusedLocalProcessor.severity, ErrorSeverity.ERROR);
+
+        // skip
+        var invalidAssignmentProcessor = errorConfig.processors.firstWhere(
+            (p) => p.appliesTo(invalid_assignment),
+            orElse: () => null);
+        expect(invalidAssignmentProcessor, isNull);
+      });
+    });
+  });
+}
+
+TestContext context;
+
+AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
+ErrorProcessor processor;
+
+void configureOptions(String options) {
+  Map<String, YamlNode> optionMap =
+      optionsProvider.getOptionsFromString(options);
+  configureContextOptions(context, optionMap);
+}
+
+ErrorProcessor getProcessor(AnalysisError error) =>
+    ErrorProcessor.getProcessor(context, error);
+
+void oneTimeSetup() {
+  List<Plugin> plugins = <Plugin>[];
+  plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+  plugins.add(AnalysisEngine.instance.commandLinePlugin);
+  plugins.add(AnalysisEngine.instance.optionsPlugin);
+  ExtensionManager manager = new ExtensionManager();
+  manager.processPlugins(plugins);
+}
+
+class TestContext extends AnalysisContextImpl {}
diff --git a/pkg/analyzer/test/source/package_map_provider_test.dart b/pkg/analyzer/test/source/package_map_provider_test.dart
index af5bedf..f02b60a 100644
--- a/pkg/analyzer/test/source/package_map_provider_test.dart
+++ b/pkg/analyzer/test/source/package_map_provider_test.dart
@@ -2,125 +2,138 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.package.map.provider;
+library analyzer.test.source.package_map_provider_test;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
+import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:unittest/unittest.dart';
 
+import '../reflective_tests.dart';
 import '../utils.dart';
 
 main() {
   initializeTestEnvironment();
+  runReflectiveTests(PubPackageMapProviderTest);
+}
 
-  group('PubPackageMapProvider', () {
-    group('parsePackageMap', () {
-      MemoryResourceProvider resourceProvider;
-      PubPackageMapProvider packageMapProvider;
-      const String projectPath = '/path/to/project';
-      Folder projectFolder;
+@reflectiveTest
+class PubPackageMapProviderTest {
+  static const String projectPath = '/path/to/project';
 
-      setUp(() {
-        resourceProvider = new MemoryResourceProvider();
-        packageMapProvider = new PubPackageMapProvider(
-            resourceProvider, DirectoryBasedDartSdk.defaultSdk);
-        projectFolder = resourceProvider.newFolder(projectPath);
-      });
+  DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
+  MemoryResourceProvider resourceProvider;
+  PubPackageMapProvider packageMapProvider;
+  Folder projectFolder;
 
-      PackageMapInfo parsePackageMap(Object obj) {
-        return packageMapProvider.parsePackageMap(obj, projectFolder);
-      }
+  PackageMapInfo parsePackageMap(Map obj) {
+    return packageMapProvider.parsePackageMap(obj, projectFolder);
+  }
 
-      test('normal folder', () {
-        String packageName = 'foo';
-        String folderPath = '/path/to/folder';
-        resourceProvider.newFolder(folderPath);
-        Map<String, List<Folder>> result = parsePackageMap({
-          'packages': {packageName: folderPath}
-        }).packageMap;
-        expect(result, hasLength(1));
-        expect(result.keys, contains(packageName));
-        expect(result[packageName], hasLength(1));
-        expect(result[packageName][0], new isInstanceOf<Folder>());
-        expect(result[packageName][0].path, equals(folderPath));
-      });
+  void setUp() {
+    resourceProvider = new MemoryResourceProvider();
+    packageMapProvider = new PubPackageMapProvider(resourceProvider, sdk);
+    projectFolder = resourceProvider.newFolder(projectPath);
+  }
 
-      test("don't ignore nonexistent folder", () {
-        String packageName = 'foo';
-        String folderPath = '/path/to/folder';
-        Map<String, List<Folder>> result = parsePackageMap({
-          'packages': {packageName: folderPath}
-        }).packageMap;
-        expect(result, hasLength(1));
-        expect(result.keys, contains(packageName));
-        expect(result[packageName], hasLength(1));
-        expect(result[packageName][0], new isInstanceOf<Folder>());
-        expect(result[packageName][0].path, equals(folderPath));
-      });
-
-      test('package maps to list', () {
-        String packageName = 'foo';
-        String folderPath1 = '/path/to/folder1';
-        String folderPath2 = '/path/to/folder2';
-        resourceProvider.newFolder(folderPath1);
-        resourceProvider.newFolder(folderPath2);
-        Map<String, List<Folder>> result = parsePackageMap({
-          'packages': {
-            packageName: [folderPath1, folderPath2]
-          }
-        }).packageMap;
-        expect(result, hasLength(1));
-        expect(result.keys, contains(packageName));
-        expect(result[packageName], hasLength(2));
-        for (int i = 0; i < 2; i++) {
-          expect(result[packageName][i], new isInstanceOf<Folder>());
-          expect(result[packageName][i].path, isIn([folderPath1, folderPath2]));
-        }
-      });
-
-      test('Handle dependencies', () {
-        String path1 = '/path/to/folder1/pubspec.lock';
-        String path2 = '/path/to/folder2/pubspec.lock';
-        resourceProvider.newFile(path1, '...');
-        resourceProvider.newFile(path2, '...');
-        Set<String> dependencies = parsePackageMap({
-          'packages': {},
-          'input_files': [path1, path2]
-        }).dependencies;
-        expect(dependencies, hasLength(2));
-        expect(dependencies, contains(path1));
-        expect(dependencies, contains(path2));
-      });
-
-      test('Relative path in packages', () {
-        String packagePath = '/path/to/package';
-        String relativePackagePath = '../package';
-        String packageName = 'foo';
-        resourceProvider.newFolder(projectPath);
-        resourceProvider.newFolder(packagePath);
-        Map<String, List<Folder>> result = parsePackageMap({
-          'packages': {
-            packageName: [relativePackagePath]
-          }
-        }).packageMap;
-        expect(result[packageName][0].path, equals(packagePath));
-      });
-
-      test('Relative path in dependencies', () {
-        String dependencyPath = '/path/to/pubspec.lock';
-        String relativeDependencyPath = '../pubspec.lock';
-        resourceProvider.newFolder(projectPath);
-        resourceProvider.newFile(dependencyPath, 'contents');
-        Set<String> dependencies = parsePackageMap({
-          'packages': {},
-          'input_files': [relativeDependencyPath]
-        }).dependencies;
-        expect(dependencies, hasLength(1));
-        expect(dependencies, contains(dependencyPath));
-      });
+  void test_computePackageMap_noLockFile() {
+    packageMapProvider =
+        new PubPackageMapProvider(resourceProvider, sdk, (Folder folder) {
+      fail('Unexpected "pub list" invocation');
     });
-  });
+    PackageMapInfo info = packageMapProvider.computePackageMap(projectFolder);
+    expect(info.packageMap, isNull);
+    expect(info.dependencies, unorderedEquals(['$projectPath/pubspec.lock']));
+  }
+
+  void test_parsePackageMap_dontIgnoreNonExistingFolder() {
+    String packageName = 'foo';
+    String folderPath = '/path/to/folder';
+    Map<String, List<Folder>> result = parsePackageMap({
+      'packages': {packageName: folderPath}
+    }).packageMap;
+    expect(result, hasLength(1));
+    expect(result.keys, contains(packageName));
+    expect(result[packageName], hasLength(1));
+    expect(result[packageName][0], new isInstanceOf<Folder>());
+    expect(result[packageName][0].path, equals(folderPath));
+  }
+
+  void test_parsePackageMap_handleDependencies() {
+    String path1 = '/path/to/folder1/pubspec.lock';
+    String path2 = '/path/to/folder2/pubspec.lock';
+    resourceProvider.newFile(path1, '...');
+    resourceProvider.newFile(path2, '...');
+    Set<String> dependencies = parsePackageMap({
+      'packages': {},
+      'input_files': [path1, path2]
+    }).dependencies;
+    expect(dependencies, hasLength(2));
+    expect(dependencies, contains(path1));
+    expect(dependencies, contains(path2));
+  }
+
+  void test_parsePackageMap_normalFolder() {
+    String packageName = 'foo';
+    String folderPath = '/path/to/folder';
+    resourceProvider.newFolder(folderPath);
+    Map<String, List<Folder>> result = parsePackageMap({
+      'packages': {packageName: folderPath}
+    }).packageMap;
+    expect(result, hasLength(1));
+    expect(result.keys, contains(packageName));
+    expect(result[packageName], hasLength(1));
+    expect(result[packageName][0], new isInstanceOf<Folder>());
+    expect(result[packageName][0].path, equals(folderPath));
+  }
+
+  void test_parsePackageMap_packageMapsToList() {
+    String packageName = 'foo';
+    String folderPath1 = '/path/to/folder1';
+    String folderPath2 = '/path/to/folder2';
+    resourceProvider.newFolder(folderPath1);
+    resourceProvider.newFolder(folderPath2);
+    Map<String, List<Folder>> result = parsePackageMap({
+      'packages': {
+        packageName: [folderPath1, folderPath2]
+      }
+    }).packageMap;
+    expect(result, hasLength(1));
+    expect(result.keys, contains(packageName));
+    expect(result[packageName], hasLength(2));
+    for (int i = 0; i < 2; i++) {
+      expect(result[packageName][i], new isInstanceOf<Folder>());
+      expect(result[packageName][i].path, isIn([folderPath1, folderPath2]));
+    }
+  }
+
+  void test_parsePackageMap_relativePahInPackages() {
+    String packagePath = '/path/to/package';
+    String relativePackagePath = '../package';
+    String packageName = 'foo';
+    resourceProvider.newFolder(projectPath);
+    resourceProvider.newFolder(packagePath);
+    Map<String, List<Folder>> result = parsePackageMap({
+      'packages': {
+        packageName: [relativePackagePath]
+      }
+    }).packageMap;
+    expect(result[packageName][0].path, equals(packagePath));
+  }
+
+  void test_parsePackageMap_relativePathInDependencies() {
+    String dependencyPath = '/path/to/pubspec.lock';
+    String relativeDependencyPath = '../pubspec.lock';
+    resourceProvider.newFolder(projectPath);
+    resourceProvider.newFile(dependencyPath, 'contents');
+    Set<String> dependencies = parsePackageMap({
+      'packages': {},
+      'input_files': [relativeDependencyPath]
+    }).dependencies;
+    expect(dependencies, hasLength(1));
+    expect(dependencies, contains(dependencyPath));
+  }
 }
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index caf88da..0017961 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.source.package_map_resolver;
+library analyzer.test.source.package_map_resolver_test;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/source/path_filter_test.dart b/pkg/analyzer/test/source/path_filter_test.dart
index a7e58fb..1cada77 100644
--- a/pkg/analyzer/test/source/path_filter_test.dart
+++ b/pkg/analyzer/test/source/path_filter_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.source.path_filter;
+library analyzer.test.source.path_filter_test;
 
 import 'package:analyzer/source/path_filter.dart';
 import 'package:path/path.dart';
diff --git a/pkg/analyzer/test/source/sdk_ext_test.dart b/pkg/analyzer/test/source/sdk_ext_test.dart
index 01416af..dbb7425 100644
--- a/pkg/analyzer/test/source/sdk_ext_test.dart
+++ b/pkg/analyzer/test/source/sdk_ext_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.source.sdk_ext;
+library analyzer.test.source.sdk_ext_test;
 
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/sdk_ext.dart';
diff --git a/pkg/analyzer/test/source/test_all.dart b/pkg/analyzer/test/source/test_all.dart
index 6930bce..725d23e 100644
--- a/pkg/analyzer/test/source/test_all.dart
+++ b/pkg/analyzer/test/source/test_all.dart
@@ -2,12 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.source;
+library analyzer.test.source.test_all;
 
 import 'package:unittest/unittest.dart';
 
 import '../utils.dart';
 import 'analysis_options_provider_test.dart' as analysis_options_provider_test;
+import 'embedder_test.dart' as embedder_test;
+import 'error_processor_test.dart' as error_processor_test;
 import 'package_map_provider_test.dart' as package_map_provider_test;
 import 'package_map_resolver_test.dart' as package_map_resolver_test;
 import 'path_filter_test.dart' as path_filter_test;
@@ -18,9 +20,11 @@
   initializeTestEnvironment();
   group('source', () {
     analysis_options_provider_test.main();
+    embedder_test.main();
+    error_processor_test.main();
     package_map_provider_test.main();
     package_map_resolver_test.main();
-    sdk_ext_test.main();
     path_filter_test.main();
+    sdk_ext_test.main();
   });
 }
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index 135fd42..18bde46 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -2,19 +2,20 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.abstract_context_test;
+library analyzer.test.src.context.abstract_context;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/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 AnalysisCache, AnalysisContextImpl, AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/task/model.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:unittest/unittest.dart';
 
 import 'mock_sdk.dart';
@@ -124,6 +125,14 @@
   }
 
   void setUp() {
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+
     prepareAnalysisContext();
   }
 
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 75c156a..37bd49c 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -2,15 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.driver_test;
+library analyzer.test.src.context.cache_test;
 
 import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    show
-        AnalysisContext,
-        CacheState,
-        InternalAnalysisContext,
-        RetentionPriority;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -34,9 +29,7 @@
   runReflectiveTests(ResultDataTest);
 }
 
-AnalysisCache createCache(
-    {AnalysisContext context,
-    RetentionPriority policy: RetentionPriority.LOW}) {
+AnalysisCache createCache({AnalysisContext context}) {
   CachePartition partition = new UniversalCachePartition(context);
   return new AnalysisCache(<CachePartition>[partition]);
 }
@@ -961,12 +954,31 @@
     expect(createPartition(), isNotNull);
   }
 
+  void test_dispose() {
+    CachePartition partition = createPartition();
+    Source source1 = new TestSource('/1.dart');
+    Source source2 = new TestSource('/2.dart');
+    CacheEntry entry1 = new CacheEntry(source1);
+    CacheEntry entry2 = new CacheEntry(source2);
+    // add two sources
+    partition.put(entry1);
+    partition.put(entry2);
+    expect(partition.entryMap, hasLength(2));
+    expect(partition.pathToSource, hasLength(2));
+    expect(partition.sources, unorderedEquals([source1, source2]));
+    // dispose, no sources
+    partition.dispose();
+    expect(partition.entryMap, isEmpty);
+    expect(partition.pathToSource, isEmpty);
+    expect(partition.sources, isEmpty);
+  }
+
   void test_entrySet() {
     CachePartition partition = createPartition();
     AnalysisTarget target = new TestSource();
     CacheEntry entry = new CacheEntry(target);
     partition.put(entry);
-    Map<AnalysisTarget, CacheEntry> entryMap = partition.map;
+    Map<AnalysisTarget, CacheEntry> entryMap = partition.entryMap;
     expect(entryMap, hasLength(1));
     AnalysisTarget entryKey = entryMap.keys.first;
     expect(entryKey, target);
@@ -1102,9 +1114,7 @@
 }
 
 class _InternalAnalysisContextMock extends TypedMock
-    implements InternalAnalysisContext {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+    implements InternalAnalysisContext {}
 
 /**
  * Keep the given [keepDescriptor], invalidate all the other results.
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 4d68fd3..41feb593 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -2,34 +2,19 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.context.context_test;
+library analyzer.test.src.context.context_test;
 
 import 'dart:async';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    show
-        AnalysisContext,
-        AnalysisContextStatistics,
-        AnalysisDelta,
-        AnalysisEngine,
-        AnalysisErrorInfo,
-        AnalysisLevel,
-        AnalysisNotScheduledError,
-        AnalysisOptions,
-        AnalysisOptionsImpl,
-        AnalysisResult,
-        CacheState,
-        ChangeNotice,
-        ChangeSet,
-        IncrementalAnalysisCache,
-        TimestampedData;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -152,6 +137,19 @@
     });
   }
 
+  void test_applyChanges_add_makesExplicit() {
+    Source source = newSource('/test.dart');
+    // get the entry, it's not explicit
+    CacheEntry entry = context.getCacheEntry(source);
+    expect(entry.explicitlyAdded, isFalse);
+    // add the source
+    ChangeSet changeSet = new ChangeSet();
+    changeSet.addedSource(source);
+    context.applyChanges(changeSet);
+    // now the entry is explicit
+    expect(entry.explicitlyAdded, isTrue);
+  }
+
   Future test_applyChanges_change() {
     SourcesChangedListener listener = new SourcesChangedListener();
     context.onSourcesChanged.listen(listener.onData);
@@ -243,8 +241,9 @@
     Element declarationElement = declaration.variables.variables[0].element;
     TopLevelVariableDeclaration use =
         partUnit.declarations[0] as TopLevelVariableDeclaration;
-    Element useElement = (use.variables.variables[0].initializer
-        as SimpleIdentifier).staticElement;
+    Element useElement =
+        (use.variables.variables[0].initializer as SimpleIdentifier)
+            .staticElement;
     expect((useElement as PropertyAccessorElement).variable,
         same(declarationElement));
     return pumpEventQueue().then((_) {
@@ -283,8 +282,9 @@
   }
 
   void test_applyChanges_overriddenSource() {
-    // Note: addSource adds the source to the contentCache.
-    Source source = addSource("/test.dart", "library test;");
+    String content = "library test;";
+    Source source = addSource("/test.dart", content);
+    context.setContents(source, content);
     context.computeErrors(source);
     while (!context.sourcesNeedingProcessing.isEmpty) {
       context.performAnalysisTask();
@@ -293,7 +293,8 @@
     // it is already overridden in the content cache.
     ChangeSet changeSet = new ChangeSet();
     changeSet.changedSource(source);
-    context.applyChanges(changeSet);
+    ApplyChangesStatus changesStatus = context.applyChanges(changeSet);
+    expect(changesStatus.hasChanges, isFalse);
     expect(context.sourcesNeedingProcessing, hasLength(0));
   }
 
@@ -312,7 +313,6 @@
     expect(importedLibraries, hasLength(2));
     context.computeErrors(libA);
     context.computeErrors(libB);
-    expect(context.sourcesNeedingProcessing, hasLength(0));
     context.setContents(libB, null);
     _removeSource(libB);
     List<Source> sources = context.sourcesNeedingProcessing;
@@ -382,7 +382,6 @@
     context.computeLibraryElement(libA);
     context.computeErrors(libA);
     context.computeErrors(libB);
-    expect(context.sourcesNeedingProcessing, hasLength(0));
     ChangeSet changeSet = new ChangeSet();
     SourceContainer removedContainer =
         new _AnalysisContextImplTest_test_applyChanges_removeContainer(libB);
@@ -605,12 +604,15 @@
       expect(unit, isNotNull);
       completed = true;
     });
-    return pumpEventQueue().then((_) {
-      expect(completed, isFalse);
-      _performPendingAnalysisTasks();
-    }).then((_) => pumpEventQueue()).then((_) {
-      expect(completed, isTrue);
-    });
+    return pumpEventQueue()
+        .then((_) {
+          expect(completed, isFalse);
+          _performPendingAnalysisTasks();
+        })
+        .then((_) => pumpEventQueue())
+        .then((_) {
+          expect(completed, isTrue);
+        });
   }
 
   Future test_computeResolvedCompilationUnitAsync_afterDispose() {
@@ -699,21 +701,24 @@
       expect(unit, isNotNull);
       completed = true;
     });
-    return pumpEventQueue().then((_) {
-      expect(completed, isFalse);
-      _performPendingAnalysisTasks();
-    }).then((_) => pumpEventQueue()).then((_) {
-      expect(completed, isTrue);
-    });
+    return pumpEventQueue()
+        .then((_) {
+          expect(completed, isFalse);
+          _performPendingAnalysisTasks();
+        })
+        .then((_) => pumpEventQueue())
+        .then((_) {
+          expect(completed, isTrue);
+        });
   }
 
   void test_configurationData() {
-    var key = new ResultDescriptor('test_key', '');
+    var key = new ResultDescriptor('test_key', 'TEST_DEFAULT');
     var testData = ['test', 'data'];
     context.setConfigurationData(key, testData);
     expect(context.getConfigurationData(key), testData);
-    var unusedKey = new ResultDescriptor('unused_key', '');
-    expect(context.getConfigurationData(unusedKey), null);
+    var unusedKey = new ResultDescriptor('unused_key', 'UNUSED_DEFAULT');
+    expect(context.getConfigurationData(unusedKey), 'UNUSED_DEFAULT');
   }
 
   void test_dispose() {
@@ -838,7 +843,7 @@
   }
 
   void test_exists_true() {
-    expect(context.exists(new AnalysisContextImplTest_Source_exists_true()),
+    expect(context.exists(new _AnalysisContextImplTest_Source_exists_true()),
         isTrue);
   }
 
@@ -1298,7 +1303,7 @@
     int stamp = 42;
     expect(
         context.getModificationStamp(
-            new AnalysisContextImplTest_Source_getModificationStamp_fromSource(
+            new _AnalysisContextImplTest_Source_getModificationStamp_fromSource(
                 stamp)),
         stamp);
   }
@@ -1306,7 +1311,7 @@
   void test_getModificationStamp_overridden() {
     int stamp = 42;
     Source source =
-        new AnalysisContextImplTest_Source_getModificationStamp_overridden(
+        new _AnalysisContextImplTest_Source_getModificationStamp_overridden(
             stamp);
     context.setContents(source, "");
     expect(stamp != context.getModificationStamp(source), isTrue);
@@ -1366,16 +1371,6 @@
     expect(context.getSourcesWithFullName(filePath), unorderedEquals(expected));
   }
 
-  void test_getStatistics() {
-    AnalysisContextStatistics statistics = context.statistics;
-    expect(statistics, isNotNull);
-    // The following lines are fragile.
-    // The values depend on the number of libraries in the SDK.
-//    assertLength(0, statistics.getCacheRows());
-//    assertLength(0, statistics.getExceptions());
-//    assertLength(0, statistics.getSources());
-  }
-
   void test_handleContentsChanged() {
     ContentCache contentCache = new ContentCache();
     context.contentCache = contentCache;
@@ -1948,11 +1943,8 @@
     addSource('/test.dart', 'main() {}');
     _analyzeAll_assertFinished();
     // verify
-    expect(libraryElementUris, contains('dart:core'));
     expect(libraryElementUris, contains('file:///test.dart'));
-    expect(parsedUnitUris, contains('dart:core'));
     expect(parsedUnitUris, contains('file:///test.dart'));
-    expect(resolvedUnitUris, contains('dart:core'));
     expect(resolvedUnitUris, contains('file:///test.dart'));
   }
 
@@ -2711,6 +2703,27 @@
   }
 }
 
+class _AnalysisContextImplTest_Source_exists_true extends TestSource {
+  @override
+  bool exists() => true;
+}
+
+class _AnalysisContextImplTest_Source_getModificationStamp_fromSource
+    extends TestSource {
+  int stamp;
+  _AnalysisContextImplTest_Source_getModificationStamp_fromSource(this.stamp);
+  @override
+  int get modificationStamp => stamp;
+}
+
+class _AnalysisContextImplTest_Source_getModificationStamp_overridden
+    extends TestSource {
+  int stamp;
+  _AnalysisContextImplTest_Source_getModificationStamp_overridden(this.stamp);
+  @override
+  int get modificationStamp => stamp;
+}
+
 class _AnalysisContextImplTest_test_applyChanges_removeContainer
     implements SourceContainer {
   Source libB;
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index 121fb5d..5cf93dd 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.mock_sdk;
+library analyzer.test.src.context.mock_sdk;
 
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
@@ -86,6 +86,11 @@
 abstract class Iterable<E> {
   Iterator<E> get iterator;
   bool get isEmpty;
+
+  Iterable/*<R>*/ map/*<R>*/(/*=R*/ f(E e));
+
+  /*=R*/ fold/*<R>*/(/*=R*/ initialValue,
+      /*=R*/ combine(/*=R*/ previousValue, E element));
 }
 
 abstract class List<E> implements Iterable<E> {
@@ -123,7 +128,10 @@
 class Future<T> {
   factory Future.delayed(Duration duration, [T computation()]) => null;
   factory Future.value([value]) => null;
-  static Future wait(List<Future> futures) => null;
+
+  static Future<List</*<T>*/> wait/*<T>*/(
+      Iterable<Future/*<T>*/> futures) => null;
+  Future/*<R>*/ then/*<R>*/(/*=R*/ onValue(T value)) => null;
 }
 ''',
       const <_MockSdkFile>[
@@ -162,11 +170,14 @@
       '/lib/math/math.dart',
       '''
 library dart.math;
+
 const double E = 2.718281828459045;
 const double PI = 3.1415926535897932;
 const double LN10 =  2.302585092994046;
-num min(num a, num b) => 0;
-num max(num a, num b) => 0;
+
+num/*=T*/ min/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) => null;
+num/*=T*/ max/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) => null;
+
 external double cos(num x);
 external double sin(num x);
 external double sqrt(num x);
@@ -264,7 +275,7 @@
       }
       if (filePath.startsWith("$libraryPath/")) {
         String pathInLibrary = filePath.substring(libraryPath.length + 1);
-        String path = '${library.shortName}/${pathInLibrary}';
+        String path = '${library.shortName}/$pathInLibrary';
         try {
           resource.File file = provider.getResource(uri.path);
           Uri dartUri = new Uri(scheme: 'dart', path: path);
@@ -310,6 +321,13 @@
   }
 }
 
+class _MockSdkFile {
+  final String path;
+  final String content;
+
+  const _MockSdkFile(this.path, this.content);
+}
+
 class _MockSdkLibrary implements SdkLibrary {
   final String shortName;
   final String path;
@@ -343,13 +361,6 @@
   UnimplementedError get unimplemented => new UnimplementedError();
 }
 
-class _MockSdkFile {
-  final String path;
-  final String content;
-
-  const _MockSdkFile(this.path, this.content);
-}
-
 /**
  * An [AnalysisContextImpl] that only contains sources for a Dart SDK.
  */
@@ -363,8 +374,7 @@
     if (factory == null) {
       return super.createCacheFromSourceFactory(factory);
     }
-    return new AnalysisCache(<CachePartition>[
-      AnalysisEngine.instance.partitionManager_new.forSdk(sdk)
-    ]);
+    return new AnalysisCache(
+        <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
   }
 }
diff --git a/pkg/analyzer/test/src/context/test_all.dart b/pkg/analyzer/test/src/context/test_all.dart
index bbd021d..301b13c 100644
--- a/pkg/analyzer/test/src/context/test_all.dart
+++ b/pkg/analyzer/test/src/context/test_all.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.context.test_all;
+library analyzer.test.src.context.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
new file mode 100644
index 0000000..bf01506
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -0,0 +1,4007 @@
+// 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 analyzer.test.generated.element_test;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../generated/resolver_test.dart'
+    show TestTypeProvider, AnalysisContextHelper;
+import '../../../generated/test_support.dart';
+import '../../../reflective_tests.dart';
+import '../../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(FieldElementImplTest);
+  runReflectiveTests(FunctionTypeImplTest);
+  runReflectiveTests(InterfaceTypeImplTest);
+  runReflectiveTests(TypeParameterTypeImplTest);
+  runReflectiveTests(VoidTypeImplTest);
+  runReflectiveTests(ClassElementImplTest);
+  runReflectiveTests(CompilationUnitElementImplTest);
+  runReflectiveTests(ElementLocationImplTest);
+  runReflectiveTests(ElementImplTest);
+  runReflectiveTests(LibraryElementImplTest);
+  runReflectiveTests(MethodElementImplTest);
+  runReflectiveTests(MultiplyDefinedElementImplTest);
+  runReflectiveTests(ParameterElementImplTest);
+}
+
+@reflectiveTest
+class ClassElementImplTest extends EngineTestCase {
+  void test_computeNode_ClassDeclaration() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource(
+        "/test.dart",
+        r'''
+class A {}
+@deprecated class B {}
+enum C {C1, C2, C3}
+@deprecated enum D {D1, D2, D3}''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // A
+    {
+      ClassElement elementA = unitElement.getType("A");
+      expect(elementA.isDeprecated, isFalse);
+      expect(elementA.isEnum, isFalse);
+      ClassDeclaration nodeA = elementA.computeNode();
+      expect(nodeA, isNotNull);
+      expect(nodeA.name.name, "A");
+      expect(nodeA.element, same(elementA));
+    }
+    // B
+    {
+      ClassElement elementB = unitElement.getType("B");
+      expect(elementB.isDeprecated, isTrue);
+      expect(elementB.isEnum, isFalse);
+      ClassDeclaration nodeB = elementB.computeNode();
+      expect(nodeB, isNotNull);
+      expect(nodeB.name.name, "B");
+      expect(nodeB.element, same(elementB));
+    }
+    // C
+    {
+      ClassElement elementC = unitElement.getEnum("C");
+      expect(elementC.isDeprecated, isFalse);
+      expect(elementC.isEnum, isTrue);
+      EnumDeclaration nodeC = elementC.computeNode();
+      expect(nodeC, isNotNull);
+      expect(nodeC.name.name, "C");
+      expect(nodeC.element, same(elementC));
+    }
+    // D
+    {
+      ClassElement elementD = unitElement.getEnum("D");
+      expect(elementD.isDeprecated, isTrue);
+      expect(elementD.isEnum, isTrue);
+      EnumDeclaration nodeC = elementD.computeNode();
+      expect(nodeC, isNotNull);
+      expect(nodeC.name.name, "D");
+      expect(nodeC.element, same(elementD));
+    }
+  }
+
+  void test_computeNode_ClassTypeAlias() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource(
+        "/test.dart",
+        r'''
+abstract class A<K, V> = Object with MapMixin<K, V>;
+''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // A
+    {
+      ClassElement elementA = unitElement.getType("A");
+      ClassTypeAlias nodeA = elementA.computeNode();
+      expect(nodeA, isNotNull);
+      expect(nodeA.name.name, "A");
+      expect(nodeA.element, same(elementA));
+    }
+  }
+
+  void test_getAllSupertypes_interface() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl elementC = ElementFactory.classElement2("C");
+    InterfaceType typeObject = classA.supertype;
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    InterfaceType typeC = elementC.type;
+    elementC.interfaces = <InterfaceType>[typeB];
+    List<InterfaceType> supers = elementC.allSupertypes;
+    List<InterfaceType> types = new List<InterfaceType>();
+    types.addAll(supers);
+    expect(types.contains(typeA), isTrue);
+    expect(types.contains(typeB), isTrue);
+    expect(types.contains(typeObject), isTrue);
+    expect(types.contains(typeC), isFalse);
+  }
+
+  void test_getAllSupertypes_mixins() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    InterfaceType typeObject = classA.supertype;
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    InterfaceType typeC = classC.type;
+    classC.mixins = <InterfaceType>[typeB];
+    List<InterfaceType> supers = classC.allSupertypes;
+    List<InterfaceType> types = new List<InterfaceType>();
+    types.addAll(supers);
+    expect(types.contains(typeA), isFalse);
+    expect(types.contains(typeB), isTrue);
+    expect(types.contains(typeObject), isTrue);
+    expect(types.contains(typeC), isFalse);
+  }
+
+  void test_getAllSupertypes_recursive() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.supertype = classB.type;
+    List<InterfaceType> supers = classB.allSupertypes;
+    expect(supers, hasLength(1));
+  }
+
+  void test_getField() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String fieldName = "f";
+    FieldElementImpl field =
+        ElementFactory.fieldElement(fieldName, false, false, false, null);
+    classA.fields = <FieldElement>[field];
+    expect(classA.getField(fieldName), same(field));
+    expect(field.isEnumConstant, false);
+    // no such field
+    expect(classA.getField("noSuchField"), same(null));
+  }
+
+  void test_getMethod_declared() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[method];
+    expect(classA.getMethod(methodName), same(method));
+  }
+
+  void test_getMethod_undeclared() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[method];
+    expect(classA.getMethod("${methodName}x"), isNull);
+  }
+
+  void test_hasNonFinalField_false_const() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    classA.fields = <FieldElement>[
+      ElementFactory.fieldElement("f", false, false, true, classA.type)
+    ];
+    expect(classA.hasNonFinalField, isFalse);
+  }
+
+  void test_hasNonFinalField_false_final() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    classA.fields = <FieldElement>[
+      ElementFactory.fieldElement("f", false, true, false, classA.type)
+    ];
+    expect(classA.hasNonFinalField, isFalse);
+  }
+
+  void test_hasNonFinalField_false_recursive() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.supertype = classB.type;
+    expect(classA.hasNonFinalField, isFalse);
+  }
+
+  void test_hasNonFinalField_true_immediate() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    classA.fields = <FieldElement>[
+      ElementFactory.fieldElement("f", false, false, false, classA.type)
+    ];
+    expect(classA.hasNonFinalField, isTrue);
+  }
+
+  void test_hasNonFinalField_true_inherited() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.fields = <FieldElement>[
+      ElementFactory.fieldElement("f", false, false, false, classA.type)
+    ];
+    expect(classB.hasNonFinalField, isTrue);
+  }
+
+  void test_hasStaticMember_false_empty() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    // no members
+    expect(classA.hasStaticMember, isFalse);
+  }
+
+  void test_hasStaticMember_false_instanceMethod() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    MethodElement method = ElementFactory.methodElement("foo", null);
+    classA.methods = <MethodElement>[method];
+    expect(classA.hasStaticMember, isFalse);
+  }
+
+  void test_hasStaticMember_instanceGetter() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    PropertyAccessorElement getter =
+        ElementFactory.getterElement("foo", false, null);
+    classA.accessors = <PropertyAccessorElement>[getter];
+    expect(classA.hasStaticMember, isFalse);
+  }
+
+  void test_hasStaticMember_true_getter() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    PropertyAccessorElementImpl getter =
+        ElementFactory.getterElement("foo", false, null);
+    classA.accessors = <PropertyAccessorElement>[getter];
+    // "foo" is static
+    getter.static = true;
+    expect(classA.hasStaticMember, isTrue);
+  }
+
+  void test_hasStaticMember_true_method() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    MethodElementImpl method = ElementFactory.methodElement("foo", null);
+    classA.methods = <MethodElement>[method];
+    // "foo" is static
+    method.static = true;
+    expect(classA.hasStaticMember, isTrue);
+  }
+
+  void test_hasStaticMember_true_setter() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    PropertyAccessorElementImpl setter =
+        ElementFactory.setterElement("foo", false, null);
+    classA.accessors = <PropertyAccessorElement>[setter];
+    // "foo" is static
+    setter.static = true;
+    expect(classA.hasStaticMember, isTrue);
+  }
+
+  void test_isEnum() {
+    String firstConst = "A";
+    String secondConst = "B";
+    ClassElementImpl enumE = ElementFactory
+        .enumElement(new TestTypeProvider(), "E", [firstConst, secondConst]);
+
+    // E is an enum
+    expect(enumE.isEnum, true);
+
+    // A and B are static members
+    expect(enumE.getField(firstConst).isEnumConstant, true);
+    expect(enumE.getField(secondConst).isEnumConstant, true);
+  }
+
+  void test_lookUpConcreteMethod_declared() {
+    // class A {
+    //   m() {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpConcreteMethod(methodName, library), same(method));
+  }
+
+  void test_lookUpConcreteMethod_declaredAbstract() {
+    // class A {
+    //   m();
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElementImpl method = ElementFactory.methodElement(methodName, null);
+    method.abstract = true;
+    classA.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpConcreteMethod(methodName, library), isNull);
+  }
+
+  void test_lookUpConcreteMethod_declaredAbstractAndInherited() {
+    // class A {
+    //   m() {}
+    // }
+    // class B extends A {
+    //   m();
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    MethodElementImpl method = ElementFactory.methodElement(methodName, null);
+    method.abstract = true;
+    classB.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpConcreteMethod(methodName, library),
+        same(inheritedMethod));
+  }
+
+  void test_lookUpConcreteMethod_declaredAndInherited() {
+    // class A {
+    //   m() {}
+    // }
+    // class B extends A {
+    //   m() {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classB.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpConcreteMethod(methodName, library), same(method));
+  }
+
+  void test_lookUpConcreteMethod_declaredAndInheritedAbstract() {
+    // abstract class A {
+    //   m();
+    // }
+    // class B extends A {
+    //   m() {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    classA.abstract = true;
+    String methodName = "m";
+    MethodElementImpl inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    inheritedMethod.abstract = true;
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classB.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpConcreteMethod(methodName, library), same(method));
+  }
+
+  void test_lookUpConcreteMethod_inherited() {
+    // class A {
+    //   m() {}
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpConcreteMethod(methodName, library),
+        same(inheritedMethod));
+  }
+
+  void test_lookUpConcreteMethod_undeclared() {
+    // class A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpConcreteMethod("m", library), isNull);
+  }
+
+  void test_lookUpGetter_declared() {
+    // class A {
+    //   get g {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String getterName = "g";
+    PropertyAccessorElement getter =
+        ElementFactory.getterElement(getterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[getter];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpGetter(getterName, library), same(getter));
+  }
+
+  void test_lookUpGetter_inherited() {
+    // class A {
+    //   get g {}
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String getterName = "g";
+    PropertyAccessorElement getter =
+        ElementFactory.getterElement(getterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[getter];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpGetter(getterName, library), same(getter));
+  }
+
+  void test_lookUpGetter_undeclared() {
+    // class A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpGetter("g", library), isNull);
+  }
+
+  void test_lookUpGetter_undeclared_recursive() {
+    // class A extends B {
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.supertype = classB.type;
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classA.lookUpGetter("g", library), isNull);
+  }
+
+  void test_lookUpInheritedConcreteGetter_declared() {
+    // class A {
+    //   get g {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String getterName = "g";
+    PropertyAccessorElement getter =
+        ElementFactory.getterElement(getterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[getter];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpInheritedConcreteGetter(getterName, library), isNull);
+  }
+
+  void test_lookUpInheritedConcreteGetter_inherited() {
+    // class A {
+    //   get g {}
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String getterName = "g";
+    PropertyAccessorElement inheritedGetter =
+        ElementFactory.getterElement(getterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[inheritedGetter];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpInheritedConcreteGetter(getterName, library),
+        same(inheritedGetter));
+  }
+
+  void test_lookUpInheritedConcreteGetter_undeclared() {
+    // class A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
+  }
+
+  void test_lookUpInheritedConcreteGetter_undeclared_recursive() {
+    // class A extends B {
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.supertype = classB.type;
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
+  }
+
+  void test_lookUpInheritedConcreteMethod_declared() {
+    // class A {
+    //   m() {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpInheritedConcreteMethod(methodName, library), isNull);
+  }
+
+  void test_lookUpInheritedConcreteMethod_declaredAbstractAndInherited() {
+    // class A {
+    //   m() {}
+    // }
+    // class B extends A {
+    //   m();
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    MethodElementImpl method = ElementFactory.methodElement(methodName, null);
+    method.abstract = true;
+    classB.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpInheritedConcreteMethod(methodName, library),
+        same(inheritedMethod));
+  }
+
+  void test_lookUpInheritedConcreteMethod_declaredAndInherited() {
+    // class A {
+    //   m() {}
+    // }
+    // class B extends A {
+    //   m() {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classB.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpInheritedConcreteMethod(methodName, library),
+        same(inheritedMethod));
+  }
+
+  void test_lookUpInheritedConcreteMethod_declaredAndInheritedAbstract() {
+    // abstract class A {
+    //   m();
+    // }
+    // class B extends A {
+    //   m() {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    classA.abstract = true;
+    String methodName = "m";
+    MethodElementImpl inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    inheritedMethod.abstract = true;
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classB.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpInheritedConcreteMethod(methodName, library), isNull);
+  }
+
+  void
+      test_lookUpInheritedConcreteMethod_declaredAndInheritedWithAbstractBetween() {
+    // class A {
+    //   m() {}
+    // }
+    // class B extends A {
+    //   m();
+    // }
+    // class C extends B {
+    //   m() {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    MethodElementImpl abstractMethod =
+        ElementFactory.methodElement(methodName, null);
+    abstractMethod.abstract = true;
+    classB.methods = <MethodElement>[abstractMethod];
+    ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
+    MethodElementImpl method = ElementFactory.methodElement(methodName, null);
+    classC.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB, classC];
+    expect(classC.lookUpInheritedConcreteMethod(methodName, library),
+        same(inheritedMethod));
+  }
+
+  void test_lookUpInheritedConcreteMethod_inherited() {
+    // class A {
+    //   m() {}
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpInheritedConcreteMethod(methodName, library),
+        same(inheritedMethod));
+  }
+
+  void test_lookUpInheritedConcreteMethod_undeclared() {
+    // class A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpInheritedConcreteMethod("m", library), isNull);
+  }
+
+  void test_lookUpInheritedConcreteSetter_declared() {
+    // class A {
+    //   set g(x) {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String setterName = "s";
+    PropertyAccessorElement setter =
+        ElementFactory.setterElement(setterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[setter];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpInheritedConcreteSetter(setterName, library), isNull);
+  }
+
+  void test_lookUpInheritedConcreteSetter_inherited() {
+    // class A {
+    //   set g(x) {}
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String setterName = "s";
+    PropertyAccessorElement setter =
+        ElementFactory.setterElement(setterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[setter];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpInheritedConcreteSetter(setterName, library),
+        same(setter));
+  }
+
+  void test_lookUpInheritedConcreteSetter_undeclared() {
+    // class A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
+  }
+
+  void test_lookUpInheritedConcreteSetter_undeclared_recursive() {
+    // class A extends B {
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.supertype = classB.type;
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
+  }
+
+  void test_lookUpInheritedMethod_declared() {
+    // class A {
+    //   m() {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpInheritedMethod(methodName, library), isNull);
+  }
+
+  void test_lookUpInheritedMethod_declaredAndInherited() {
+    // class A {
+    //   m() {}
+    // }
+    // class B extends A {
+    //   m() {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classB.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpInheritedMethod(methodName, library),
+        same(inheritedMethod));
+  }
+
+  void test_lookUpInheritedMethod_inherited() {
+    // class A {
+    //   m() {}
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement inheritedMethod =
+        ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[inheritedMethod];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpInheritedMethod(methodName, library),
+        same(inheritedMethod));
+  }
+
+  void test_lookUpInheritedMethod_undeclared() {
+    // class A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpInheritedMethod("m", library), isNull);
+  }
+
+  void test_lookUpMethod_declared() {
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[method];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpMethod(methodName, library), same(method));
+  }
+
+  void test_lookUpMethod_inherited() {
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElement method = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[method];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpMethod(methodName, library), same(method));
+  }
+
+  void test_lookUpMethod_undeclared() {
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpMethod("m", library), isNull);
+  }
+
+  void test_lookUpMethod_undeclared_recursive() {
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.supertype = classB.type;
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classA.lookUpMethod("m", library), isNull);
+  }
+
+  void test_lookUpSetter_declared() {
+    // class A {
+    //   set g(x) {}
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String setterName = "s";
+    PropertyAccessorElement setter =
+        ElementFactory.setterElement(setterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[setter];
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpSetter(setterName, library), same(setter));
+  }
+
+  void test_lookUpSetter_inherited() {
+    // class A {
+    //   set g(x) {}
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String setterName = "s";
+    PropertyAccessorElement setter =
+        ElementFactory.setterElement(setterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[setter];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classB.lookUpSetter(setterName, library), same(setter));
+  }
+
+  void test_lookUpSetter_undeclared() {
+    // class A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA];
+    expect(classA.lookUpSetter("s", library), isNull);
+  }
+
+  void test_lookUpSetter_undeclared_recursive() {
+    // class A extends B {
+    // }
+    // class B extends A {
+    // }
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.supertype = classB.type;
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classA, classB];
+    expect(classA.lookUpSetter("s", library), isNull);
+  }
+}
+
+@reflectiveTest
+class CompilationUnitElementImplTest extends EngineTestCase {
+  void test_getElementAt() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    String code = r'''
+class A {
+  int field;
+}
+main() {
+  int localVar = 42;
+}
+''';
+    Source libSource = contextHelper.addSource("/my_lib.dart", code);
+    // prepare library/unit elements
+    LibraryElement libraryElement = context.computeLibraryElement(libSource);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // A
+    ClassElement elementA;
+    {
+      int offset = code.indexOf('A {');
+      elementA = unitElement.getElementAt(offset);
+      expect(elementA, isNotNull);
+      expect(elementA.enclosingElement, unitElement);
+      expect(elementA.name, 'A');
+    }
+    // A.field
+    {
+      int offset = code.indexOf('field;');
+      FieldElement element = unitElement.getElementAt(offset);
+      expect(element, isNotNull);
+      expect(element.enclosingElement, elementA);
+      expect(element.name, 'field');
+    }
+    // main
+    FunctionElement mainElement;
+    {
+      int offset = code.indexOf('main() {');
+      mainElement = unitElement.getElementAt(offset);
+      expect(mainElement, isNotNull);
+      expect(mainElement.enclosingElement, unitElement);
+      expect(mainElement.name, 'main');
+    }
+    // main.localVar
+    {
+      int offset = code.indexOf('localVar');
+      LocalVariableElement element = unitElement.getElementAt(offset);
+      expect(element, isNotNull);
+      expect(element.enclosingElement, mainElement);
+      expect(element.name, 'localVar');
+    }
+    // null
+    expect(unitElement.getElementAt(1000), isNull);
+  }
+
+  void test_getElementAt_multipleUnitsInLibrary() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source libSource = contextHelper.addSource(
+        "/my_lib.dart",
+        r'''
+library my_lib;
+part 'unit_a.dart';
+part 'unit_b.dart';
+''');
+    Source unitSourceA =
+        contextHelper.addSource("/unit_a.dart", 'part of my_lib;class A {}');
+    Source unitSourceB =
+        contextHelper.addSource("/unit_b.dart", 'part of my_lib;class B {}');
+    int offset = 'part of my_lib;class A {}'.indexOf('A {}');
+    // prepare library/unit elements
+    context.computeLibraryElement(libSource);
+    CompilationUnitElement unitElementA =
+        context.getCompilationUnitElement(unitSourceA, libSource);
+    CompilationUnitElement unitElementB =
+        context.getCompilationUnitElement(unitSourceB, libSource);
+    // A
+    {
+      ClassElement element = unitElementA.getElementAt(offset);
+      expect(element, isNotNull);
+      expect(element.enclosingElement, unitElementA);
+      expect(element.name, 'A');
+    }
+    // B
+    {
+      ClassElement element = unitElementB.getElementAt(offset);
+      expect(element, isNotNull);
+      expect(element.enclosingElement, unitElementB);
+      expect(element.name, 'B');
+    }
+  }
+
+  void test_getEnum_declared() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    CompilationUnitElementImpl unit =
+        ElementFactory.compilationUnit("/lib.dart");
+    String enumName = "E";
+    ClassElement enumElement =
+        ElementFactory.enumElement(typeProvider, enumName);
+    unit.enums = <ClassElement>[enumElement];
+    expect(unit.getEnum(enumName), same(enumElement));
+  }
+
+  void test_getEnum_undeclared() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    CompilationUnitElementImpl unit =
+        ElementFactory.compilationUnit("/lib.dart");
+    String enumName = "E";
+    ClassElement enumElement =
+        ElementFactory.enumElement(typeProvider, enumName);
+    unit.enums = <ClassElement>[enumElement];
+    expect(unit.getEnum("${enumName}x"), isNull);
+  }
+
+  void test_getType_declared() {
+    CompilationUnitElementImpl unit =
+        ElementFactory.compilationUnit("/lib.dart");
+    String className = "C";
+    ClassElement classElement = ElementFactory.classElement2(className);
+    unit.types = <ClassElement>[classElement];
+    expect(unit.getType(className), same(classElement));
+  }
+
+  void test_getType_undeclared() {
+    CompilationUnitElementImpl unit =
+        ElementFactory.compilationUnit("/lib.dart");
+    String className = "C";
+    ClassElement classElement = ElementFactory.classElement2(className);
+    unit.types = <ClassElement>[classElement];
+    expect(unit.getType("${className}x"), isNull);
+  }
+}
+
+@reflectiveTest
+class ElementImplTest extends EngineTestCase {
+  void test_equals() {
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElementImpl classElement = ElementFactory.classElement2("C");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classElement];
+    FieldElement field = ElementFactory.fieldElement(
+        "next", false, false, false, classElement.type);
+    classElement.fields = <FieldElement>[field];
+    expect(field == field, isTrue);
+    expect(field == field.getter, isFalse);
+    expect(field == field.setter, isFalse);
+    expect(field.getter == field.setter, isFalse);
+  }
+
+  void test_isAccessibleIn_private_differentLibrary() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
+    ClassElement classElement = ElementFactory.classElement2("_C");
+    (library1.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classElement];
+    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
+    expect(classElement.isAccessibleIn(library2), isFalse);
+  }
+
+  void test_isAccessibleIn_private_sameLibrary() {
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElement classElement = ElementFactory.classElement2("_C");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classElement];
+    expect(classElement.isAccessibleIn(library), isTrue);
+  }
+
+  void test_isAccessibleIn_public_differentLibrary() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
+    ClassElement classElement = ElementFactory.classElement2("C");
+    (library1.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classElement];
+    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
+    expect(classElement.isAccessibleIn(library2), isTrue);
+  }
+
+  void test_isAccessibleIn_public_sameLibrary() {
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    ClassElement classElement = ElementFactory.classElement2("C");
+    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+        <ClassElement>[classElement];
+    expect(classElement.isAccessibleIn(library), isTrue);
+  }
+
+  void test_isPrivate_false() {
+    Element element = ElementFactory.classElement2("C");
+    expect(element.isPrivate, isFalse);
+  }
+
+  void test_isPrivate_null() {
+    Element element = ElementFactory.classElement2(null);
+    expect(element.isPrivate, isTrue);
+  }
+
+  void test_isPrivate_true() {
+    Element element = ElementFactory.classElement2("_C");
+    expect(element.isPrivate, isTrue);
+  }
+
+  void test_isPublic_false() {
+    Element element = ElementFactory.classElement2("_C");
+    expect(element.isPublic, isFalse);
+  }
+
+  void test_isPublic_null() {
+    Element element = ElementFactory.classElement2(null);
+    expect(element.isPublic, isFalse);
+  }
+
+  void test_isPublic_true() {
+    Element element = ElementFactory.classElement2("C");
+    expect(element.isPublic, isTrue);
+  }
+
+  void test_SORT_BY_OFFSET() {
+    ClassElementImpl classElementA = ElementFactory.classElement2("A");
+    classElementA.nameOffset = 1;
+    ClassElementImpl classElementB = ElementFactory.classElement2("B");
+    classElementB.nameOffset = 2;
+    expect(Element.SORT_BY_OFFSET(classElementA, classElementA), 0);
+    expect(Element.SORT_BY_OFFSET(classElementA, classElementB) < 0, isTrue);
+    expect(Element.SORT_BY_OFFSET(classElementB, classElementA) > 0, isTrue);
+  }
+}
+
+@reflectiveTest
+class ElementLocationImplTest extends EngineTestCase {
+  void test_create_encoding() {
+    String encoding = "a;b;c";
+    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
+    expect(location.encoding, encoding);
+  }
+
+  /**
+   * For example unnamed constructor.
+   */
+  void test_create_encoding_emptyLast() {
+    String encoding = "a;b;c;";
+    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
+    expect(location.encoding, encoding);
+  }
+
+  void test_equals_equal() {
+    String encoding = "a;b;c";
+    ElementLocationImpl first = new ElementLocationImpl.con2(encoding);
+    ElementLocationImpl second = new ElementLocationImpl.con2(encoding);
+    expect(first == second, isTrue);
+  }
+
+  void test_equals_notEqual_differentLengths() {
+    ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
+    ElementLocationImpl second = new ElementLocationImpl.con2("a;b;c;d");
+    expect(first == second, isFalse);
+  }
+
+  void test_equals_notEqual_notLocation() {
+    ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
+    expect(first == "a;b;d", isFalse);
+  }
+
+  void test_equals_notEqual_sameLengths() {
+    ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
+    ElementLocationImpl second = new ElementLocationImpl.con2("a;b;d");
+    expect(first == second, isFalse);
+  }
+
+  void test_getComponents() {
+    String encoding = "a;b;c";
+    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
+    List<String> components = location.components;
+    expect(components, hasLength(3));
+    expect(components[0], "a");
+    expect(components[1], "b");
+    expect(components[2], "c");
+  }
+
+  void test_getEncoding() {
+    String encoding = "a;b;c;;d";
+    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
+    expect(location.encoding, encoding);
+  }
+
+  void test_hashCode_equal() {
+    String encoding = "a;b;c";
+    ElementLocationImpl first = new ElementLocationImpl.con2(encoding);
+    ElementLocationImpl second = new ElementLocationImpl.con2(encoding);
+    expect(first.hashCode == second.hashCode, isTrue);
+  }
+}
+
+@reflectiveTest
+class FieldElementImplTest extends EngineTestCase {
+  void test_computeNode() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource(
+        "/test.dart",
+        r'''
+class A {
+  int a;
+}
+enum B {B1, B2, B3}''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // A
+    {
+      FieldElement elementA = unitElement.getType("A").getField('a');
+      VariableDeclaration nodeA = elementA.computeNode();
+      expect(nodeA, isNotNull);
+      expect(nodeA.name.name, "a");
+      expect(nodeA.element, same(elementA));
+    }
+    // B
+    {
+      FieldElement elementB = unitElement.getEnum("B").getField('B2');
+      EnumConstantDeclaration nodeB = elementB.computeNode();
+      expect(nodeB, isNotNull);
+      expect(nodeB.name.name, "B2");
+      expect(nodeB.element, same(elementB));
+    }
+  }
+}
+
+@reflectiveTest
+class FunctionTypeImplTest extends EngineTestCase {
+  void test_creation() {
+    expect(
+        new FunctionTypeImpl(
+            new FunctionElementImpl.forNode(AstFactory.identifier3("f"))),
+        isNotNull);
+  }
+
+  void test_equality_recursive() {
+    FunctionTypeAliasElementImpl s =
+        ElementFactory.functionTypeAliasElement('s');
+    FunctionTypeAliasElementImpl t =
+        ElementFactory.functionTypeAliasElement('t');
+    FunctionTypeAliasElementImpl u =
+        ElementFactory.functionTypeAliasElement('u');
+    FunctionTypeAliasElementImpl v =
+        ElementFactory.functionTypeAliasElement('v');
+    s.returnType = t.type;
+    t.returnType = s.type;
+    u.returnType = v.type;
+    v.returnType = u.type;
+    // We don't care whether the types compare equal or not.  We just need the
+    // computation to terminate.
+    expect(s.type == u.type, new isInstanceOf<bool>());
+  }
+
+  void test_getElement() {
+    FunctionElementImpl typeElement =
+        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
+    FunctionTypeImpl type = new FunctionTypeImpl(typeElement);
+    expect(type.element, typeElement);
+  }
+
+  void test_getNamedParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl(
+        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
+    Map<String, DartType> types = type.namedParameterTypes;
+    expect(types, hasLength(0));
+  }
+
+  void test_getNormalParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl(
+        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
+    List<DartType> types = type.normalParameterTypes;
+    expect(types, hasLength(0));
+  }
+
+  void test_getReturnType() {
+    DartType expectedReturnType = VoidTypeImpl.instance;
+    FunctionElementImpl functionElement =
+        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
+    functionElement.returnType = expectedReturnType;
+    FunctionTypeImpl type = new FunctionTypeImpl(functionElement);
+    DartType returnType = type.returnType;
+    expect(returnType, expectedReturnType);
+  }
+
+  void test_getTypeArguments() {
+    FunctionTypeImpl type = new FunctionTypeImpl(
+        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
+    List<DartType> types = type.typeArguments;
+    expect(types, hasLength(0));
+  }
+
+  void test_hashCode_element() {
+    FunctionTypeImpl type = new FunctionTypeImpl(
+        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
+    type.hashCode;
+  }
+
+  void test_hashCode_noElement() {
+    FunctionTypeImpl type = new FunctionTypeImpl(null);
+    type.hashCode;
+  }
+
+  void test_hashCode_recursive() {
+    FunctionTypeAliasElementImpl s =
+        ElementFactory.functionTypeAliasElement('s');
+    FunctionTypeAliasElementImpl t =
+        ElementFactory.functionTypeAliasElement('t');
+    s.returnType = t.type;
+    t.returnType = s.type;
+    // We don't care what the hash code is.  We just need its computation to
+    // terminate.
+    expect(t.type.hashCode, new isInstanceOf<int>());
+  }
+
+  void test_isAssignableTo_normalAndPositionalArgs() {
+    // ([a]) -> void <: (a) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    FunctionType t =
+        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
+    FunctionType s =
+        ElementFactory.functionElement5("s", <ClassElement>[a]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+    expect(s.isSubtypeOf(t), isFalse);
+    // assignable iff subtype
+    expect(t.isAssignableTo(s), isTrue);
+    expect(s.isAssignableTo(t), isFalse);
+  }
+
+  void test_isSubtypeOf_baseCase_classFunction() {
+    // () -> void <: Function
+    ClassElementImpl functionElement = ElementFactory.classElement2("Function");
+    InterfaceTypeImpl functionType =
+        new _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction(
+            functionElement);
+    FunctionType f = ElementFactory.functionElement("f").type;
+    expect(f.isSubtypeOf(functionType), isTrue);
+  }
+
+  void test_isSubtypeOf_baseCase_notFunctionType() {
+    // class C
+    // ! () -> void <: C
+    FunctionType f = ElementFactory.functionElement("f").type;
+    InterfaceType t = ElementFactory.classElement2("C").type;
+    expect(f.isSubtypeOf(t), isFalse);
+  }
+
+  void test_isSubtypeOf_baseCase_null() {
+    // ! () -> void <: null
+    FunctionType f = ElementFactory.functionElement("f").type;
+    expect(f.isSubtypeOf(null), isFalse);
+  }
+
+  void test_isSubtypeOf_baseCase_self() {
+    // () -> void <: () -> void
+    FunctionType f = ElementFactory.functionElement("f").type;
+    expect(f.isSubtypeOf(f), isTrue);
+  }
+
+  void test_isSubtypeOf_namedParameters_isAssignable() {
+    // B extends A
+    // ({name: A}) -> void <: ({name: B}) -> void
+    // ({name: B}) -> void <: ({name: A}) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t = ElementFactory.functionElement4(
+        "t", null, null, <String>["name"], <ClassElement>[a]).type;
+    FunctionType s = ElementFactory.functionElement4(
+        "s", null, null, <String>["name"], <ClassElement>[b]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+    expect(s.isSubtypeOf(t), isTrue);
+  }
+
+  void test_isSubtypeOf_namedParameters_isNotAssignable() {
+    // ! ({name: A}) -> void <: ({name: B}) -> void
+    FunctionType t = ElementFactory.functionElement4(
+        "t",
+        null,
+        null,
+        <String>["name"],
+        <ClassElement>[ElementFactory.classElement2("A")]).type;
+    FunctionType s = ElementFactory.functionElement4(
+        "s",
+        null,
+        null,
+        <String>["name"],
+        <ClassElement>[ElementFactory.classElement2("B")]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+  }
+
+  void test_isSubtypeOf_namedParameters_namesDifferent() {
+    // B extends A
+    // void t({A name}) {}
+    // void s({A diff}) {}
+    // ! t <: s
+    // ! s <: t
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t = ElementFactory.functionElement4(
+        "t", null, null, <String>["name"], <ClassElement>[a]).type;
+    FunctionType s = ElementFactory.functionElement4(
+        "s", null, null, <String>["diff"], <ClassElement>[b]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+    expect(s.isSubtypeOf(t), isFalse);
+  }
+
+  void test_isSubtypeOf_namedParameters_orderOfParams() {
+    // B extends A
+    // ({A: A, B: B}) -> void <: ({B: B, A: A}) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t = ElementFactory.functionElement4(
+        "t", null, null, <String>["A", "B"], <ClassElement>[a, b]).type;
+    FunctionType s = ElementFactory.functionElement4(
+        "s", null, null, <String>["B", "A"], <ClassElement>[b, a]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+  }
+
+  void test_isSubtypeOf_namedParameters_orderOfParams2() {
+    // B extends A
+    // ! ({B: B}) -> void <: ({B: B, A: A}) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t = ElementFactory.functionElement4(
+        "t", null, null, <String>["B"], <ClassElement>[b]).type;
+    FunctionType s = ElementFactory.functionElement4(
+        "s", null, null, <String>["B", "A"], <ClassElement>[b, a]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+  }
+
+  void test_isSubtypeOf_namedParameters_orderOfParams3() {
+    // B extends A
+    // ({A: A, B: B}) -> void <: ({A: A}) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t = ElementFactory.functionElement4(
+        "t", null, null, <String>["A", "B"], <ClassElement>[a, b]).type;
+    FunctionType s = ElementFactory.functionElement4(
+        "s", null, null, <String>["B"], <ClassElement>[b]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+  }
+
+  void test_isSubtypeOf_namedParameters_sHasMoreParams() {
+    // B extends A
+    // ! ({name: A}) -> void <: ({name: B, name2: B}) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t = ElementFactory.functionElement4(
+        "t", null, null, <String>["name"], <ClassElement>[a]).type;
+    FunctionType s = ElementFactory.functionElement4(
+        "s", null, null, <String>["name", "name2"], <ClassElement>[b, b]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+  }
+
+  void test_isSubtypeOf_namedParameters_tHasMoreParams() {
+    // B extends A
+    // ({name: A, name2: A}) -> void <: ({name: B}) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t = ElementFactory.functionElement4(
+        "t", null, null, <String>["name", "name2"], <ClassElement>[a, a]).type;
+    FunctionType s = ElementFactory.functionElement4(
+        "s", null, null, <String>["name"], <ClassElement>[b]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+  }
+
+  void test_isSubtypeOf_normalAndPositionalArgs_1() {
+    // ([a]) -> void <: (a) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    FunctionType t =
+        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
+    FunctionType s =
+        ElementFactory.functionElement5("s", <ClassElement>[a]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+    expect(s.isSubtypeOf(t), isFalse);
+  }
+
+  void test_isSubtypeOf_normalAndPositionalArgs_2() {
+    // (a, [a]) -> void <: (a) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    FunctionType t = ElementFactory
+        .functionElement6("t", <ClassElement>[a], <ClassElement>[a]).type;
+    FunctionType s =
+        ElementFactory.functionElement5("s", <ClassElement>[a]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+    expect(s.isSubtypeOf(t), isFalse);
+  }
+
+  void test_isSubtypeOf_normalAndPositionalArgs_3() {
+    // ([a]) -> void <: () -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    FunctionType t =
+        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
+    FunctionType s = ElementFactory.functionElement("s").type;
+    expect(t.isSubtypeOf(s), isTrue);
+    expect(s.isSubtypeOf(t), isFalse);
+  }
+
+  void test_isSubtypeOf_normalAndPositionalArgs_4() {
+    // (a, b, [c, d, e]) -> void <: (a, b, c, [d]) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement2("B");
+    ClassElement c = ElementFactory.classElement2("C");
+    ClassElement d = ElementFactory.classElement2("D");
+    ClassElement e = ElementFactory.classElement2("E");
+    FunctionType t = ElementFactory.functionElement6(
+        "t", <ClassElement>[a, b], <ClassElement>[c, d, e]).type;
+    FunctionType s = ElementFactory
+        .functionElement6("s", <ClassElement>[a, b, c], <ClassElement>[d]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+    expect(s.isSubtypeOf(t), isFalse);
+  }
+
+  void test_isSubtypeOf_normalParameters_isAssignable() {
+    // B extends A
+    // (a) -> void <: (b) -> void
+    // (b) -> void <: (a) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t =
+        ElementFactory.functionElement5("t", <ClassElement>[a]).type;
+    FunctionType s =
+        ElementFactory.functionElement5("s", <ClassElement>[b]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+    expect(s.isSubtypeOf(t), isTrue);
+  }
+
+  void test_isSubtypeOf_normalParameters_isNotAssignable() {
+    // ! (a) -> void <: (b) -> void
+    FunctionType t = ElementFactory.functionElement5(
+        "t", <ClassElement>[ElementFactory.classElement2("A")]).type;
+    FunctionType s = ElementFactory.functionElement5(
+        "s", <ClassElement>[ElementFactory.classElement2("B")]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+  }
+
+  void test_isSubtypeOf_normalParameters_sHasMoreParams() {
+    // B extends A
+    // ! (a) -> void <: (b, b) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t =
+        ElementFactory.functionElement5("t", <ClassElement>[a]).type;
+    FunctionType s =
+        ElementFactory.functionElement5("s", <ClassElement>[b, b]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+  }
+
+  void test_isSubtypeOf_normalParameters_tHasMoreParams() {
+    // B extends A
+    // ! (a, a) -> void <: (a) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t =
+        ElementFactory.functionElement5("t", <ClassElement>[a, a]).type;
+    FunctionType s =
+        ElementFactory.functionElement5("s", <ClassElement>[b]).type;
+    // note, this is a different assertion from the other "tHasMoreParams"
+    // tests, this is intentional as it is a difference of the "normal
+    // parameters"
+    expect(t.isSubtypeOf(s), isFalse);
+  }
+
+  void test_isSubtypeOf_Object() {
+    // () -> void <: Object
+    FunctionType f = ElementFactory.functionElement("f").type;
+    InterfaceType t = ElementFactory.object.type;
+    expect(f.isSubtypeOf(t), isTrue);
+  }
+
+  void test_isSubtypeOf_positionalParameters_isAssignable() {
+    // B extends A
+    // ([a]) -> void <: ([b]) -> void
+    // ([b]) -> void <: ([a]) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t =
+        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
+    FunctionType s =
+        ElementFactory.functionElement6("s", null, <ClassElement>[b]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+    expect(s.isSubtypeOf(t), isTrue);
+  }
+
+  void test_isSubtypeOf_positionalParameters_isNotAssignable() {
+    // ! ([a]) -> void <: ([b]) -> void
+    FunctionType t = ElementFactory.functionElement6(
+        "t", null, <ClassElement>[ElementFactory.classElement2("A")]).type;
+    FunctionType s = ElementFactory.functionElement6(
+        "s", null, <ClassElement>[ElementFactory.classElement2("B")]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+  }
+
+  void test_isSubtypeOf_positionalParameters_sHasMoreParams() {
+    // B extends A
+    // ! ([a]) -> void <: ([b, b]) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t =
+        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
+    FunctionType s =
+        ElementFactory.functionElement6("s", null, <ClassElement>[b, b]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+  }
+
+  void test_isSubtypeOf_positionalParameters_tHasMoreParams() {
+    // B extends A
+    // ([a, a]) -> void <: ([b]) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t =
+        ElementFactory.functionElement6("t", null, <ClassElement>[a, a]).type;
+    FunctionType s =
+        ElementFactory.functionElement6("s", null, <ClassElement>[b]).type;
+    expect(t.isSubtypeOf(s), isTrue);
+  }
+
+  void test_isSubtypeOf_returnType_sIsVoid() {
+    // () -> void <: void
+    FunctionType t = ElementFactory.functionElement("t").type;
+    FunctionType s = ElementFactory.functionElement("s").type;
+    // function s has the implicit return type of void, we assert it here
+    expect(VoidTypeImpl.instance == s.returnType, isTrue);
+    expect(t.isSubtypeOf(s), isTrue);
+  }
+
+  void test_isSubtypeOf_returnType_tAssignableToS() {
+    // B extends A
+    // () -> A <: () -> B
+    // () -> B <: () -> A
+    ClassElement a = ElementFactory.classElement2("A");
+    ClassElement b = ElementFactory.classElement("B", a.type);
+    FunctionType t = ElementFactory.functionElement2("t", a).type;
+    FunctionType s = ElementFactory.functionElement2("s", b).type;
+    expect(t.isSubtypeOf(s), isTrue);
+    expect(s.isSubtypeOf(t), isTrue);
+  }
+
+  void test_isSubtypeOf_returnType_tNotAssignableToS() {
+    // ! () -> A <: () -> B
+    FunctionType t = ElementFactory
+        .functionElement2("t", ElementFactory.classElement2("A"))
+        .type;
+    FunctionType s = ElementFactory
+        .functionElement2("s", ElementFactory.classElement2("B"))
+        .type;
+    expect(t.isSubtypeOf(s), isFalse);
+  }
+
+  void test_isSubtypeOf_typeParameters_matchesBounds() {
+    TestTypeProvider provider = new TestTypeProvider();
+    InterfaceType boolType = provider.boolType;
+    InterfaceType stringType = provider.stringType;
+    TypeParameterElementImpl parameterB =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("B"));
+    parameterB.bound = boolType;
+    TypeParameterTypeImpl typeB = new TypeParameterTypeImpl(parameterB);
+    TypeParameterElementImpl parameterS =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("S"));
+    parameterS.bound = stringType;
+    TypeParameterTypeImpl typeS = new TypeParameterTypeImpl(parameterS);
+    FunctionElementImpl functionAliasElement =
+        new FunctionElementImpl.forNode(AstFactory.identifier3("func"));
+    functionAliasElement.parameters = <ParameterElement>[
+      ElementFactory.requiredParameter2("a", typeB),
+      ElementFactory.positionalParameter2("b", typeS)
+    ];
+    functionAliasElement.returnType = stringType;
+    FunctionTypeImpl functionAliasType =
+        new FunctionTypeImpl(functionAliasElement);
+    functionAliasElement.type = functionAliasType;
+    FunctionElementImpl functionElement =
+        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
+    functionElement.parameters = <ParameterElement>[
+      ElementFactory.requiredParameter2("c", boolType),
+      ElementFactory.positionalParameter2("d", stringType)
+    ];
+    functionElement.returnType = provider.dynamicType;
+    FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
+    functionElement.type = functionType;
+    expect(functionType.isAssignableTo(functionAliasType), isTrue);
+  }
+
+  void test_isSubtypeOf_wrongFunctionType_normal_named() {
+    // ! (a) -> void <: ({name: A}) -> void
+    // ! ({name: A}) -> void <: (a) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    FunctionType t =
+        ElementFactory.functionElement5("t", <ClassElement>[a]).type;
+    FunctionType s = ElementFactory
+        .functionElement7("s", null, <String>["name"], <ClassElement>[a]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+    expect(s.isSubtypeOf(t), isFalse);
+  }
+
+  void test_isSubtypeOf_wrongFunctionType_optional_named() {
+    // ! ([a]) -> void <: ({name: A}) -> void
+    // ! ({name: A}) -> void <: ([a]) -> void
+    ClassElement a = ElementFactory.classElement2("A");
+    FunctionType t =
+        ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
+    FunctionType s = ElementFactory
+        .functionElement7("s", null, <String>["name"], <ClassElement>[a]).type;
+    expect(t.isSubtypeOf(s), isFalse);
+    expect(s.isSubtypeOf(t), isFalse);
+  }
+
+  void test_namedParameterTypes_pruned_no_type_arguments() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeAliasElementImpl g =
+        ElementFactory.functionTypeAliasElement('g');
+    f.parameters = [ElementFactory.namedParameter2('x', g.type)];
+    FunctionTypeImpl paramType = f.type.namedParameterTypes['x'];
+    expect(paramType.prunedTypedefs, hasLength(1));
+    expect(paramType.prunedTypedefs[0], same(f));
+  }
+
+  void test_namedParameterTypes_pruned_with_type_arguments() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeAliasElementImpl g =
+        ElementFactory.functionTypeAliasElement('g');
+    f.typeParameters = [ElementFactory.typeParameterElement('T')];
+    f.parameters = [ElementFactory.namedParameter2('x', g.type)];
+    FunctionTypeImpl paramType = f.type.namedParameterTypes['x'];
+    expect(paramType.prunedTypedefs, hasLength(1));
+    expect(paramType.prunedTypedefs[0], same(f));
+  }
+
+  void test_newPrune_no_previous_prune() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeImpl type = f.type;
+    List<FunctionTypeAliasElement> pruneList = type.newPrune;
+    expect(pruneList, hasLength(1));
+    expect(pruneList[0], same(f));
+  }
+
+  void test_newPrune_non_typedef() {
+    // No pruning needs to be done for function types that aren't associated
+    // with typedefs because those types can't be directly referred to by the
+    // user (and hence can't participate in circularities).
+    FunctionElementImpl f = ElementFactory.functionElement('f');
+    FunctionTypeImpl type = f.type;
+    expect(type.newPrune, isNull);
+  }
+
+  void test_newPrune_synthetic_typedef() {
+    // No pruning needs to be done for function types that are associated with
+    // synthetic typedefs because those types are only created for
+    // function-typed formal parameters, which can't be directly referred to by
+    // the user (and hence can't participate in circularities).
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    f.synthetic = true;
+    FunctionTypeImpl type = f.type;
+    expect(type.newPrune, isNull);
+  }
+
+  void test_newPrune_with_previous_prune() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeAliasElementImpl g =
+        ElementFactory.functionTypeAliasElement('g');
+    FunctionTypeImpl type = f.type;
+    FunctionTypeImpl prunedType = type.pruned([g]);
+    List<FunctionTypeAliasElement> pruneList = prunedType.newPrune;
+    expect(pruneList, hasLength(2));
+    expect(pruneList, contains(f));
+    expect(pruneList, contains(g));
+  }
+
+  void test_normalParameterTypes_pruned_no_type_arguments() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeAliasElementImpl g =
+        ElementFactory.functionTypeAliasElement('g');
+    f.parameters = [ElementFactory.requiredParameter2('x', g.type)];
+    FunctionTypeImpl paramType = f.type.normalParameterTypes[0];
+    expect(paramType.prunedTypedefs, hasLength(1));
+    expect(paramType.prunedTypedefs[0], same(f));
+  }
+
+  void test_normalParameterTypes_pruned_with_type_arguments() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeAliasElementImpl g =
+        ElementFactory.functionTypeAliasElement('g');
+    f.typeParameters = [ElementFactory.typeParameterElement('T')];
+    f.parameters = [ElementFactory.requiredParameter2('x', g.type)];
+    FunctionTypeImpl paramType = f.type.normalParameterTypes[0];
+    expect(paramType.prunedTypedefs, hasLength(1));
+    expect(paramType.prunedTypedefs[0], same(f));
+  }
+
+  void test_optionalParameterTypes_pruned_no_type_arguments() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeAliasElementImpl g =
+        ElementFactory.functionTypeAliasElement('g');
+    f.parameters = [ElementFactory.positionalParameter2('x', g.type)];
+    FunctionTypeImpl paramType = f.type.optionalParameterTypes[0];
+    expect(paramType.prunedTypedefs, hasLength(1));
+    expect(paramType.prunedTypedefs[0], same(f));
+  }
+
+  void test_optionalParameterTypes_pruned_with_type_arguments() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeAliasElementImpl g =
+        ElementFactory.functionTypeAliasElement('g');
+    f.typeParameters = [ElementFactory.typeParameterElement('T')];
+    f.parameters = [ElementFactory.positionalParameter2('x', g.type)];
+    FunctionTypeImpl paramType = f.type.optionalParameterTypes[0];
+    expect(paramType.prunedTypedefs, hasLength(1));
+    expect(paramType.prunedTypedefs[0], same(f));
+  }
+
+  void test_returnType_pruned_no_type_arguments() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeAliasElementImpl g =
+        ElementFactory.functionTypeAliasElement('g');
+    f.returnType = g.type;
+    FunctionTypeImpl paramType = f.type.returnType;
+    expect(paramType.prunedTypedefs, hasLength(1));
+    expect(paramType.prunedTypedefs[0], same(f));
+  }
+
+  void test_returnType_pruned_with_type_arguments() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    FunctionTypeAliasElementImpl g =
+        ElementFactory.functionTypeAliasElement('g');
+    f.typeParameters = [ElementFactory.typeParameterElement('T')];
+    f.returnType = g.type;
+    FunctionTypeImpl paramType = f.type.returnType;
+    expect(paramType.prunedTypedefs, hasLength(1));
+    expect(paramType.prunedTypedefs[0], same(f));
+  }
+
+  void test_substitute2_equal() {
+    ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
+    TypeParameterType parameterType = definingClass.typeParameters[0].type;
+    MethodElementImpl functionElement =
+        new MethodElementImpl.forNode(AstFactory.identifier3("m"));
+    String namedParameterName = "c";
+    functionElement.parameters = <ParameterElement>[
+      ElementFactory.requiredParameter2("a", parameterType),
+      ElementFactory.positionalParameter2("b", parameterType),
+      ElementFactory.namedParameter2(namedParameterName, parameterType)
+    ];
+    functionElement.returnType = parameterType;
+    definingClass.methods = <MethodElement>[functionElement];
+    FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
+    InterfaceTypeImpl argumentType = new InterfaceTypeImpl(
+        new ClassElementImpl.forNode(AstFactory.identifier3("D")));
+    FunctionType result = functionType
+        .substitute2(<DartType>[argumentType], <DartType>[parameterType]);
+    expect(result.returnType, argumentType);
+    List<DartType> normalParameters = result.normalParameterTypes;
+    expect(normalParameters, hasLength(1));
+    expect(normalParameters[0], argumentType);
+    List<DartType> optionalParameters = result.optionalParameterTypes;
+    expect(optionalParameters, hasLength(1));
+    expect(optionalParameters[0], argumentType);
+    Map<String, DartType> namedParameters = result.namedParameterTypes;
+    expect(namedParameters, hasLength(1));
+    expect(namedParameters[namedParameterName], argumentType);
+  }
+
+  void test_substitute2_notEqual() {
+    DartType returnType = new InterfaceTypeImpl(
+        new ClassElementImpl.forNode(AstFactory.identifier3("R")));
+    DartType normalParameterType = new InterfaceTypeImpl(
+        new ClassElementImpl.forNode(AstFactory.identifier3("A")));
+    DartType optionalParameterType = new InterfaceTypeImpl(
+        new ClassElementImpl.forNode(AstFactory.identifier3("B")));
+    DartType namedParameterType = new InterfaceTypeImpl(
+        new ClassElementImpl.forNode(AstFactory.identifier3("C")));
+    FunctionElementImpl functionElement =
+        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
+    String namedParameterName = "c";
+    functionElement.parameters = <ParameterElement>[
+      ElementFactory.requiredParameter2("a", normalParameterType),
+      ElementFactory.positionalParameter2("b", optionalParameterType),
+      ElementFactory.namedParameter2(namedParameterName, namedParameterType)
+    ];
+    functionElement.returnType = returnType;
+    FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
+    InterfaceTypeImpl argumentType = new InterfaceTypeImpl(
+        new ClassElementImpl.forNode(AstFactory.identifier3("D")));
+    TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
+    FunctionType result = functionType
+        .substitute2(<DartType>[argumentType], <DartType>[parameterType]);
+    expect(result.returnType, returnType);
+    List<DartType> normalParameters = result.normalParameterTypes;
+    expect(normalParameters, hasLength(1));
+    expect(normalParameters[0], normalParameterType);
+    List<DartType> optionalParameters = result.optionalParameterTypes;
+    expect(optionalParameters, hasLength(1));
+    expect(optionalParameters[0], optionalParameterType);
+    Map<String, DartType> namedParameters = result.namedParameterTypes;
+    expect(namedParameters, hasLength(1));
+    expect(namedParameters[namedParameterName], namedParameterType);
+  }
+
+  void test_toString_recursive() {
+    FunctionTypeAliasElementImpl t =
+        ElementFactory.functionTypeAliasElement("t");
+    FunctionTypeAliasElementImpl s =
+        ElementFactory.functionTypeAliasElement("s");
+    t.returnType = s.type;
+    s.returnType = t.type;
+    expect(t.type.toString(), '() \u2192 () \u2192 ...');
+  }
+
+  void test_toString_recursive_via_interface_type() {
+    FunctionTypeAliasElementImpl f =
+        ElementFactory.functionTypeAliasElement('f');
+    ClassElementImpl c = ElementFactory.classElement2('C', ['T']);
+    f.returnType = c.type.substitute4([f.type]);
+    expect(f.type.toString(), '() \u2192 C<...>');
+  }
+
+  void test_withTypeArguments() {
+    ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
+    MethodElementImpl methodElement =
+        new MethodElementImpl.forNode(AstFactory.identifier3("m"));
+    enclosingClass.methods = <MethodElement>[methodElement];
+    FunctionTypeImpl type = new FunctionTypeImpl(methodElement);
+    DartType expectedType = enclosingClass.typeParameters[0].type;
+    List<DartType> arguments = type.typeArguments;
+    expect(arguments, hasLength(1));
+    expect(arguments[0], expectedType);
+  }
+}
+
+@reflectiveTest
+class InterfaceTypeImplTest extends EngineTestCase {
+  /**
+   * The type provider used to access the types.
+   */
+  TestTypeProvider _typeProvider;
+
+  @override
+  void setUp() {
+    super.setUp();
+    _typeProvider = new TestTypeProvider();
+  }
+
+  void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
+    //
+    //   Object
+    //     |
+    //     A
+    //    / \
+    //   B   C
+    //   |   |
+    //   |   D
+    //    \ /
+    //     E
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement2("B");
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    ClassElementImpl classD = ElementFactory.classElement2("D");
+    ClassElementImpl classE = ElementFactory.classElement2("E");
+    classB.interfaces = <InterfaceType>[classA.type];
+    classC.interfaces = <InterfaceType>[classA.type];
+    classD.interfaces = <InterfaceType>[classC.type];
+    classE.interfaces = <InterfaceType>[classB.type, classD.type];
+    // assertion: even though the longest path to Object for typeB is 2, and
+    // typeE implements typeB, the longest path for typeE is 4 since it also
+    // implements typeD
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
+        2);
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type),
+        4);
+  }
+
+  void test_computeLongestInheritancePathToObject_multipleSuperclassPaths() {
+    //
+    //   Object
+    //     |
+    //     A
+    //    / \
+    //   B   C
+    //   |   |
+    //   |   D
+    //    \ /
+    //     E
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElement classC = ElementFactory.classElement("C", classA.type);
+    ClassElement classD = ElementFactory.classElement("D", classC.type);
+    ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
+    classE.interfaces = <InterfaceType>[classD.type];
+    // assertion: even though the longest path to Object for typeB is 2, and
+    // typeE extends typeB, the longest path for typeE is 4 since it also
+    // implements typeD
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
+        2);
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type),
+        4);
+  }
+
+  void test_computeLongestInheritancePathToObject_object() {
+    //
+    //   Object
+    //     |
+    //     A
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType object = classA.supertype;
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(object), 0);
+  }
+
+  void test_computeLongestInheritancePathToObject_recursion() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.supertype = classB.type;
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type),
+        2);
+  }
+
+  void test_computeLongestInheritancePathToObject_singleInterfacePath() {
+    //
+    //   Object
+    //     |
+    //     A
+    //     |
+    //     B
+    //     |
+    //     C
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement2("B");
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    classB.interfaces = <InterfaceType>[classA.type];
+    classC.interfaces = <InterfaceType>[classB.type];
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type),
+        1);
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
+        2);
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classC.type),
+        3);
+  }
+
+  void test_computeLongestInheritancePathToObject_singleSuperclassPath() {
+    //
+    //   Object
+    //     |
+    //     A
+    //     |
+    //     B
+    //     |
+    //     C
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElement classC = ElementFactory.classElement("C", classB.type);
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type),
+        1);
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
+        2);
+    expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classC.type),
+        3);
+  }
+
+  void test_computeSuperinterfaceSet_genericInterfacePath() {
+    //
+    //  A
+    //  | implements
+    //  B<T>
+    //  | implements
+    //  C<T>
+    //
+    //  D
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement2("B", ["T"]);
+    ClassElementImpl classC = ElementFactory.classElement2("C", ["T"]);
+    ClassElement classD = ElementFactory.classElement2("D");
+    InterfaceType typeA = classA.type;
+    classB.interfaces = <InterfaceType>[typeA];
+    InterfaceTypeImpl typeBT = new InterfaceTypeImpl(classB);
+    DartType typeT = classC.type.typeArguments[0];
+    typeBT.typeArguments = <DartType>[typeT];
+    classC.interfaces = <InterfaceType>[typeBT];
+    // A
+    Set<InterfaceType> superinterfacesOfA =
+        InterfaceTypeImpl.computeSuperinterfaceSet(typeA);
+    expect(superinterfacesOfA, hasLength(1));
+    InterfaceType typeObject = ElementFactory.object.type;
+    expect(superinterfacesOfA.contains(typeObject), isTrue);
+    // B<D>
+    InterfaceTypeImpl typeBD = new InterfaceTypeImpl(classB);
+    typeBD.typeArguments = <DartType>[classD.type];
+    Set<InterfaceType> superinterfacesOfBD =
+        InterfaceTypeImpl.computeSuperinterfaceSet(typeBD);
+    expect(superinterfacesOfBD, hasLength(2));
+    expect(superinterfacesOfBD.contains(typeObject), isTrue);
+    expect(superinterfacesOfBD.contains(typeA), isTrue);
+    // C<D>
+    InterfaceTypeImpl typeCD = new InterfaceTypeImpl(classC);
+    typeCD.typeArguments = <DartType>[classD.type];
+    Set<InterfaceType> superinterfacesOfCD =
+        InterfaceTypeImpl.computeSuperinterfaceSet(typeCD);
+    expect(superinterfacesOfCD, hasLength(3));
+    expect(superinterfacesOfCD.contains(typeObject), isTrue);
+    expect(superinterfacesOfCD.contains(typeA), isTrue);
+    expect(superinterfacesOfCD.contains(typeBD), isTrue);
+  }
+
+  void test_computeSuperinterfaceSet_genericSuperclassPath() {
+    //
+    //  A
+    //  |
+    //  B<T>
+    //  |
+    //  C<T>
+    //
+    //  D
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    ClassElement classB = ElementFactory.classElement("B", typeA, ["T"]);
+    ClassElementImpl classC = ElementFactory.classElement2("C", ["T"]);
+    InterfaceTypeImpl typeBT = new InterfaceTypeImpl(classB);
+    DartType typeT = classC.type.typeArguments[0];
+    typeBT.typeArguments = <DartType>[typeT];
+    classC.supertype = typeBT;
+    ClassElement classD = ElementFactory.classElement2("D");
+    // A
+    Set<InterfaceType> superinterfacesOfA =
+        InterfaceTypeImpl.computeSuperinterfaceSet(typeA);
+    expect(superinterfacesOfA, hasLength(1));
+    InterfaceType typeObject = ElementFactory.object.type;
+    expect(superinterfacesOfA.contains(typeObject), isTrue);
+    // B<D>
+    InterfaceTypeImpl typeBD = new InterfaceTypeImpl(classB);
+    typeBD.typeArguments = <DartType>[classD.type];
+    Set<InterfaceType> superinterfacesOfBD =
+        InterfaceTypeImpl.computeSuperinterfaceSet(typeBD);
+    expect(superinterfacesOfBD, hasLength(2));
+    expect(superinterfacesOfBD.contains(typeObject), isTrue);
+    expect(superinterfacesOfBD.contains(typeA), isTrue);
+    // C<D>
+    InterfaceTypeImpl typeCD = new InterfaceTypeImpl(classC);
+    typeCD.typeArguments = <DartType>[classD.type];
+    Set<InterfaceType> superinterfacesOfCD =
+        InterfaceTypeImpl.computeSuperinterfaceSet(typeCD);
+    expect(superinterfacesOfCD, hasLength(3));
+    expect(superinterfacesOfCD.contains(typeObject), isTrue);
+    expect(superinterfacesOfCD.contains(typeA), isTrue);
+    expect(superinterfacesOfCD.contains(typeBD), isTrue);
+  }
+
+  void test_computeSuperinterfaceSet_multipleInterfacePaths() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement2("B");
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    ClassElementImpl classD = ElementFactory.classElement2("D");
+    ClassElementImpl classE = ElementFactory.classElement2("E");
+    classB.interfaces = <InterfaceType>[classA.type];
+    classC.interfaces = <InterfaceType>[classA.type];
+    classD.interfaces = <InterfaceType>[classC.type];
+    classE.interfaces = <InterfaceType>[classB.type, classD.type];
+    // D
+    Set<InterfaceType> superinterfacesOfD =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classD.type);
+    expect(superinterfacesOfD, hasLength(3));
+    expect(superinterfacesOfD.contains(ElementFactory.object.type), isTrue);
+    expect(superinterfacesOfD.contains(classA.type), isTrue);
+    expect(superinterfacesOfD.contains(classC.type), isTrue);
+    // E
+    Set<InterfaceType> superinterfacesOfE =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classE.type);
+    expect(superinterfacesOfE, hasLength(5));
+    expect(superinterfacesOfE.contains(ElementFactory.object.type), isTrue);
+    expect(superinterfacesOfE.contains(classA.type), isTrue);
+    expect(superinterfacesOfE.contains(classB.type), isTrue);
+    expect(superinterfacesOfE.contains(classC.type), isTrue);
+    expect(superinterfacesOfE.contains(classD.type), isTrue);
+  }
+
+  void test_computeSuperinterfaceSet_multipleSuperclassPaths() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElement classC = ElementFactory.classElement("C", classA.type);
+    ClassElement classD = ElementFactory.classElement("D", classC.type);
+    ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
+    classE.interfaces = <InterfaceType>[classD.type];
+    // D
+    Set<InterfaceType> superinterfacesOfD =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classD.type);
+    expect(superinterfacesOfD, hasLength(3));
+    expect(superinterfacesOfD.contains(ElementFactory.object.type), isTrue);
+    expect(superinterfacesOfD.contains(classA.type), isTrue);
+    expect(superinterfacesOfD.contains(classC.type), isTrue);
+    // E
+    Set<InterfaceType> superinterfacesOfE =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classE.type);
+    expect(superinterfacesOfE, hasLength(5));
+    expect(superinterfacesOfE.contains(ElementFactory.object.type), isTrue);
+    expect(superinterfacesOfE.contains(classA.type), isTrue);
+    expect(superinterfacesOfE.contains(classB.type), isTrue);
+    expect(superinterfacesOfE.contains(classC.type), isTrue);
+    expect(superinterfacesOfE.contains(classD.type), isTrue);
+  }
+
+  void test_computeSuperinterfaceSet_recursion() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    classA.supertype = classB.type;
+    Set<InterfaceType> superinterfacesOfB =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
+    expect(superinterfacesOfB, hasLength(2));
+  }
+
+  void test_computeSuperinterfaceSet_singleInterfacePath() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement2("B");
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    classB.interfaces = <InterfaceType>[classA.type];
+    classC.interfaces = <InterfaceType>[classB.type];
+    // A
+    Set<InterfaceType> superinterfacesOfA =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classA.type);
+    expect(superinterfacesOfA, hasLength(1));
+    expect(superinterfacesOfA.contains(ElementFactory.object.type), isTrue);
+    // B
+    Set<InterfaceType> superinterfacesOfB =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
+    expect(superinterfacesOfB, hasLength(2));
+    expect(superinterfacesOfB.contains(ElementFactory.object.type), isTrue);
+    expect(superinterfacesOfB.contains(classA.type), isTrue);
+    // C
+    Set<InterfaceType> superinterfacesOfC =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classC.type);
+    expect(superinterfacesOfC, hasLength(3));
+    expect(superinterfacesOfC.contains(ElementFactory.object.type), isTrue);
+    expect(superinterfacesOfC.contains(classA.type), isTrue);
+    expect(superinterfacesOfC.contains(classB.type), isTrue);
+  }
+
+  void test_computeSuperinterfaceSet_singleSuperclassPath() {
+    //
+    //  A
+    //  |
+    //  B
+    //  |
+    //  C
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElement classC = ElementFactory.classElement("C", classB.type);
+    // A
+    Set<InterfaceType> superinterfacesOfA =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classA.type);
+    expect(superinterfacesOfA, hasLength(1));
+    expect(superinterfacesOfA.contains(ElementFactory.object.type), isTrue);
+    // B
+    Set<InterfaceType> superinterfacesOfB =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
+    expect(superinterfacesOfB, hasLength(2));
+    expect(superinterfacesOfB.contains(ElementFactory.object.type), isTrue);
+    expect(superinterfacesOfB.contains(classA.type), isTrue);
+    // C
+    Set<InterfaceType> superinterfacesOfC =
+        InterfaceTypeImpl.computeSuperinterfaceSet(classC.type);
+    expect(superinterfacesOfC, hasLength(3));
+    expect(superinterfacesOfC.contains(ElementFactory.object.type), isTrue);
+    expect(superinterfacesOfC.contains(classA.type), isTrue);
+    expect(superinterfacesOfC.contains(classB.type), isTrue);
+  }
+
+  void test_creation() {
+    expect(new InterfaceTypeImpl(ElementFactory.classElement2("A")), isNotNull);
+  }
+
+  void test_getAccessors() {
+    ClassElementImpl typeElement = ElementFactory.classElement2("A");
+    PropertyAccessorElement getterG =
+        ElementFactory.getterElement("g", false, null);
+    PropertyAccessorElement getterH =
+        ElementFactory.getterElement("h", false, null);
+    typeElement.accessors = <PropertyAccessorElement>[getterG, getterH];
+    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
+    expect(type.accessors.length, 2);
+  }
+
+  void test_getAccessors_empty() {
+    ClassElementImpl typeElement = ElementFactory.classElement2("A");
+    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
+    expect(type.accessors.length, 0);
+  }
+
+  void test_getConstructors() {
+    ClassElementImpl typeElement = ElementFactory.classElement2("A");
+    ConstructorElementImpl constructorOne =
+        ElementFactory.constructorElement(typeElement, 'one', false);
+    ConstructorElementImpl constructorTwo =
+        ElementFactory.constructorElement(typeElement, 'two', false);
+    typeElement.constructors = <ConstructorElement>[
+      constructorOne,
+      constructorTwo
+    ];
+    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
+    expect(type.constructors, hasLength(2));
+  }
+
+  void test_getConstructors_empty() {
+    ClassElementImpl typeElement = ElementFactory.classElement2("A");
+    typeElement.constructors = ConstructorElement.EMPTY_LIST;
+    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
+    expect(type.constructors, isEmpty);
+  }
+
+  void test_getElement() {
+    ClassElementImpl typeElement = ElementFactory.classElement2("A");
+    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
+    expect(type.element, typeElement);
+  }
+
+  void test_getGetter_implemented() {
+    //
+    // class A { g {} }
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String getterName = "g";
+    PropertyAccessorElement getterG =
+        ElementFactory.getterElement(getterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[getterG];
+    InterfaceType typeA = classA.type;
+    expect(typeA.getGetter(getterName), same(getterG));
+  }
+
+  void test_getGetter_parameterized() {
+    //
+    // class A<E> { E get g {} }
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
+    DartType typeE = classA.type.typeArguments[0];
+    String getterName = "g";
+    PropertyAccessorElementImpl getterG =
+        ElementFactory.getterElement(getterName, false, typeE);
+    classA.accessors = <PropertyAccessorElement>[getterG];
+    getterG.type = new FunctionTypeImpl(getterG);
+    //
+    // A<I>
+    //
+    InterfaceType typeI = ElementFactory.classElement2("I").type;
+    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
+    typeAI.typeArguments = <DartType>[typeI];
+    PropertyAccessorElement getter = typeAI.getGetter(getterName);
+    expect(getter, isNotNull);
+    FunctionType getterType = getter.type;
+    expect(getterType.returnType, same(typeI));
+  }
+
+  void test_getGetter_unimplemented() {
+    //
+    // class A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    expect(typeA.getGetter("g"), isNull);
+  }
+
+  void test_getInterfaces_nonParameterized() {
+    //
+    // class C implements A, B
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    ClassElementImpl classB = ElementFactory.classElement2("B");
+    InterfaceType typeB = classB.type;
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    classC.interfaces = <InterfaceType>[typeA, typeB];
+    List<InterfaceType> interfaces = classC.type.interfaces;
+    expect(interfaces, hasLength(2));
+    if (identical(interfaces[0], typeA)) {
+      expect(interfaces[1], same(typeB));
+    } else {
+      expect(interfaces[0], same(typeB));
+      expect(interfaces[1], same(typeA));
+    }
+  }
+
+  void test_getInterfaces_parameterized() {
+    //
+    // class A<E>
+    // class B<F> implements A<F>
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
+    ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
+    InterfaceType typeB = classB.type;
+    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
+    typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
+    classB.interfaces = <InterfaceType>[typeAF];
+    //
+    // B<I>
+    //
+    InterfaceType typeI = ElementFactory.classElement2("I").type;
+    InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
+    typeBI.typeArguments = <DartType>[typeI];
+    List<InterfaceType> interfaces = typeBI.interfaces;
+    expect(interfaces, hasLength(1));
+    InterfaceType result = interfaces[0];
+    expect(result.element, same(classA));
+    expect(result.typeArguments[0], same(typeI));
+  }
+
+  void test_getMethod_implemented() {
+    //
+    // class A { m() {} }
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[methodM];
+    InterfaceType typeA = classA.type;
+    expect(typeA.getMethod(methodName), same(methodM));
+  }
+
+  void test_getMethod_parameterized() {
+    //
+    // class A<E> { E m(E p) {} }
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
+    DartType typeE = classA.type.typeArguments[0];
+    String methodName = "m";
+    MethodElementImpl methodM =
+        ElementFactory.methodElement(methodName, typeE, [typeE]);
+    classA.methods = <MethodElement>[methodM];
+    methodM.type = new FunctionTypeImpl(methodM);
+    //
+    // A<I>
+    //
+    InterfaceType typeI = ElementFactory.classElement2("I").type;
+    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
+    typeAI.typeArguments = <DartType>[typeI];
+    MethodElement method = typeAI.getMethod(methodName);
+    expect(method, isNotNull);
+    FunctionType methodType = method.type;
+    expect(methodType.returnType, same(typeI));
+    List<DartType> parameterTypes = methodType.normalParameterTypes;
+    expect(parameterTypes, hasLength(1));
+    expect(parameterTypes[0], same(typeI));
+  }
+
+  void test_getMethod_unimplemented() {
+    //
+    // class A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    expect(typeA.getMethod("m"), isNull);
+  }
+
+  void test_getMethods() {
+    ClassElementImpl typeElement = ElementFactory.classElement2("A");
+    MethodElementImpl methodOne = ElementFactory.methodElement("one", null);
+    MethodElementImpl methodTwo = ElementFactory.methodElement("two", null);
+    typeElement.methods = <MethodElement>[methodOne, methodTwo];
+    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
+    expect(type.methods.length, 2);
+  }
+
+  void test_getMethods_empty() {
+    ClassElementImpl typeElement = ElementFactory.classElement2("A");
+    InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
+    expect(type.methods.length, 0);
+  }
+
+  void test_getMixins_nonParameterized() {
+    //
+    // class C extends Object with A, B
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    ClassElementImpl classB = ElementFactory.classElement2("B");
+    InterfaceType typeB = classB.type;
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    classC.mixins = <InterfaceType>[typeA, typeB];
+    List<InterfaceType> interfaces = classC.type.mixins;
+    expect(interfaces, hasLength(2));
+    if (identical(interfaces[0], typeA)) {
+      expect(interfaces[1], same(typeB));
+    } else {
+      expect(interfaces[0], same(typeB));
+      expect(interfaces[1], same(typeA));
+    }
+  }
+
+  void test_getMixins_parameterized() {
+    //
+    // class A<E>
+    // class B<F> extends Object with A<F>
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
+    ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
+    InterfaceType typeB = classB.type;
+    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
+    typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
+    classB.mixins = <InterfaceType>[typeAF];
+    //
+    // B<I>
+    //
+    InterfaceType typeI = ElementFactory.classElement2("I").type;
+    InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
+    typeBI.typeArguments = <DartType>[typeI];
+    List<InterfaceType> interfaces = typeBI.mixins;
+    expect(interfaces, hasLength(1));
+    InterfaceType result = interfaces[0];
+    expect(result.element, same(classA));
+    expect(result.typeArguments[0], same(typeI));
+  }
+
+  void test_getSetter_implemented() {
+    //
+    // class A { s() {} }
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String setterName = "s";
+    PropertyAccessorElement setterS =
+        ElementFactory.setterElement(setterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[setterS];
+    InterfaceType typeA = classA.type;
+    expect(typeA.getSetter(setterName), same(setterS));
+  }
+
+  void test_getSetter_parameterized() {
+    //
+    // class A<E> { set s(E p) {} }
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
+    DartType typeE = classA.type.typeArguments[0];
+    String setterName = "s";
+    PropertyAccessorElementImpl setterS =
+        ElementFactory.setterElement(setterName, false, typeE);
+    classA.accessors = <PropertyAccessorElement>[setterS];
+    setterS.type = new FunctionTypeImpl(setterS);
+    //
+    // A<I>
+    //
+    InterfaceType typeI = ElementFactory.classElement2("I").type;
+    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
+    typeAI.typeArguments = <DartType>[typeI];
+    PropertyAccessorElement setter = typeAI.getSetter(setterName);
+    expect(setter, isNotNull);
+    FunctionType setterType = setter.type;
+    List<DartType> parameterTypes = setterType.normalParameterTypes;
+    expect(parameterTypes, hasLength(1));
+    expect(parameterTypes[0], same(typeI));
+  }
+
+  void test_getSetter_unimplemented() {
+    //
+    // class A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    expect(typeA.getSetter("s"), isNull);
+  }
+
+  void test_getSuperclass_nonParameterized() {
+    //
+    // class B extends A
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    ClassElementImpl classB = ElementFactory.classElement("B", typeA);
+    InterfaceType typeB = classB.type;
+    expect(typeB.superclass, same(typeA));
+  }
+
+  void test_getSuperclass_parameterized() {
+    //
+    // class A<E>
+    // class B<F> extends A<F>
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
+    ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
+    InterfaceType typeB = classB.type;
+    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
+    typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
+    classB.supertype = typeAF;
+    //
+    // B<I>
+    //
+    InterfaceType typeI = ElementFactory.classElement2("I").type;
+    InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
+    typeBI.typeArguments = <DartType>[typeI];
+    InterfaceType superclass = typeBI.superclass;
+    expect(superclass.element, same(classA));
+    expect(superclass.typeArguments[0], same(typeI));
+  }
+
+  void test_getTypeArguments_empty() {
+    InterfaceType type = ElementFactory.classElement2("A").type;
+    expect(type.typeArguments, hasLength(0));
+  }
+
+  void test_hashCode() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    expect(0 == typeA.hashCode, isFalse);
+  }
+
+  void test_isAssignableTo_typeVariables() {
+    //
+    // class A<E> {}
+    // class B<F, G> {
+    //   A<F> af;
+    //   f (A<G> ag) {
+    //     af = ag;
+    //   }
+    // }
+    //
+    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    ClassElement classB = ElementFactory.classElement2("B", ["F", "G"]);
+    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
+    typeAF.typeArguments = <DartType>[classB.typeParameters[0].type];
+    InterfaceTypeImpl typeAG = new InterfaceTypeImpl(classA);
+    typeAG.typeArguments = <DartType>[classB.typeParameters[1].type];
+    expect(typeAG.isAssignableTo(typeAF), isFalse);
+  }
+
+  void test_isAssignableTo_void() {
+    InterfaceTypeImpl intType = _typeProvider.intType;
+    expect(VoidTypeImpl.instance.isAssignableTo(intType), isFalse);
+  }
+
+  void test_isDirectSupertypeOf_extends() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    expect(typeA.isDirectSupertypeOf(typeB), isTrue);
+  }
+
+  void test_isDirectSupertypeOf_false() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement2("B");
+    ClassElement classC = ElementFactory.classElement("C", classB.type);
+    InterfaceType typeA = classA.type;
+    InterfaceType typeC = classC.type;
+    expect(typeA.isDirectSupertypeOf(typeC), isFalse);
+  }
+
+  void test_isDirectSupertypeOf_implements() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement2("B");
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    classB.interfaces = <InterfaceType>[typeA];
+    expect(typeA.isDirectSupertypeOf(typeB), isTrue);
+  }
+
+  void test_isDirectSupertypeOf_with() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement2("B");
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    classB.mixins = <InterfaceType>[typeA];
+    expect(typeA.isDirectSupertypeOf(typeB), isTrue);
+  }
+
+  void test_isMoreSpecificThan_bottom() {
+    DartType type = ElementFactory.classElement2("A").type;
+    expect(BottomTypeImpl.instance.isMoreSpecificThan(type), isTrue);
+  }
+
+  void test_isMoreSpecificThan_covariance() {
+    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    ClassElement classI = ElementFactory.classElement2("I");
+    ClassElement classJ = ElementFactory.classElement("J", classI.type);
+    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
+    InterfaceTypeImpl typeAJ = new InterfaceTypeImpl(classA);
+    typeAI.typeArguments = <DartType>[classI.type];
+    typeAJ.typeArguments = <DartType>[classJ.type];
+    expect(typeAJ.isMoreSpecificThan(typeAI), isTrue);
+    expect(typeAI.isMoreSpecificThan(typeAJ), isFalse);
+  }
+
+  void test_isMoreSpecificThan_directSupertype() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    expect(typeB.isMoreSpecificThan(typeA), isTrue);
+    // the opposite test tests a different branch in isMoreSpecificThan()
+    expect(typeA.isMoreSpecificThan(typeB), isFalse);
+  }
+
+  void test_isMoreSpecificThan_dynamic() {
+    InterfaceType type = ElementFactory.classElement2("A").type;
+    expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
+  }
+
+  void test_isMoreSpecificThan_generic() {
+    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    ClassElement classB = ElementFactory.classElement2("B");
+    DartType dynamicType = DynamicTypeImpl.instance;
+    InterfaceType typeAOfDynamic =
+        classA.type.substitute4(<DartType>[dynamicType]);
+    InterfaceType typeAOfB = classA.type.substitute4(<DartType>[classB.type]);
+    expect(typeAOfDynamic.isMoreSpecificThan(typeAOfB), isFalse);
+    expect(typeAOfB.isMoreSpecificThan(typeAOfDynamic), isTrue);
+  }
+
+  void test_isMoreSpecificThan_self() {
+    InterfaceType type = ElementFactory.classElement2("A").type;
+    expect(type.isMoreSpecificThan(type), isTrue);
+  }
+
+  void test_isMoreSpecificThan_transitive_interface() {
+    //
+    //  class A {}
+    //  class B extends A {}
+    //  class C implements B {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    classC.interfaces = <InterfaceType>[classB.type];
+    InterfaceType typeA = classA.type;
+    InterfaceType typeC = classC.type;
+    expect(typeC.isMoreSpecificThan(typeA), isTrue);
+  }
+
+  void test_isMoreSpecificThan_transitive_mixin() {
+    //
+    //  class A {}
+    //  class B extends A {}
+    //  class C with B {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    classC.mixins = <InterfaceType>[classB.type];
+    InterfaceType typeA = classA.type;
+    InterfaceType typeC = classC.type;
+    expect(typeC.isMoreSpecificThan(typeA), isTrue);
+  }
+
+  void test_isMoreSpecificThan_transitive_recursive() {
+    //
+    //  class A extends B {}
+    //  class B extends A {}
+    //  class C {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    InterfaceType typeA = classA.type;
+    InterfaceType typeC = classC.type;
+    classA.supertype = classB.type;
+    expect(typeA.isMoreSpecificThan(typeC), isFalse);
+  }
+
+  void test_isMoreSpecificThan_transitive_superclass() {
+    //
+    //  class A {}
+    //  class B extends A {}
+    //  class C extends B {}
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElement classC = ElementFactory.classElement("C", classB.type);
+    InterfaceType typeA = classA.type;
+    InterfaceType typeC = classC.type;
+    expect(typeC.isMoreSpecificThan(typeA), isTrue);
+  }
+
+  void test_isMoreSpecificThan_typeParameterType() {
+    //
+    // class A<E> {}
+    //
+    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    InterfaceType typeA = classA.type;
+    TypeParameterType parameterType = classA.typeParameters[0].type;
+    DartType objectType = _typeProvider.objectType;
+    expect(parameterType.isMoreSpecificThan(objectType), isTrue);
+    expect(parameterType.isMoreSpecificThan(typeA), isFalse);
+  }
+
+  void test_isMoreSpecificThan_typeParameterType_withBound() {
+    //
+    // class A {}
+    // class B<E extends A> {}
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    ClassElementImpl classB = ElementFactory.classElement2("B");
+    TypeParameterElementImpl parameterEA =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+    TypeParameterType parameterAEType = new TypeParameterTypeImpl(parameterEA);
+    parameterEA.bound = typeA;
+    parameterEA.type = parameterAEType;
+    classB.typeParameters = <TypeParameterElementImpl>[parameterEA];
+    expect(parameterAEType.isMoreSpecificThan(typeA), isTrue);
+  }
+
+  void test_isSubtypeOf_directSubtype() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    expect(typeB.isSubtypeOf(typeA), isTrue);
+    expect(typeA.isSubtypeOf(typeB), isFalse);
+  }
+
+  void test_isSubtypeOf_dynamic() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    DartType dynamicType = DynamicTypeImpl.instance;
+    expect(dynamicType.isSubtypeOf(typeA), isTrue);
+    expect(typeA.isSubtypeOf(dynamicType), isTrue);
+  }
+
+  void test_isSubtypeOf_function() {
+    //
+    // void f(String s) {}
+    // class A {
+    //   void call(String s) {}
+    // }
+    //
+    InterfaceType stringType = _typeProvider.stringType;
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    classA.methods = <MethodElement>[
+      ElementFactory.methodElement("call", VoidTypeImpl.instance, [stringType])
+    ];
+    FunctionType functionType = ElementFactory
+        .functionElement5("f", <ClassElement>[stringType.element]).type;
+    expect(classA.type.isSubtypeOf(functionType), isTrue);
+  }
+
+  void test_isSubtypeOf_generic() {
+    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    ClassElement classB = ElementFactory.classElement2("B");
+    DartType dynamicType = DynamicTypeImpl.instance;
+    InterfaceType typeAOfDynamic =
+        classA.type.substitute4(<DartType>[dynamicType]);
+    InterfaceType typeAOfB = classA.type.substitute4(<DartType>[classB.type]);
+    expect(typeAOfDynamic.isSubtypeOf(typeAOfB), isTrue);
+    expect(typeAOfB.isSubtypeOf(typeAOfDynamic), isTrue);
+  }
+
+  void test_isSubtypeOf_interface() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    InterfaceType typeObject = classA.supertype;
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    InterfaceType typeC = classC.type;
+    classC.interfaces = <InterfaceType>[typeB];
+    expect(typeC.isSubtypeOf(typeB), isTrue);
+    expect(typeC.isSubtypeOf(typeObject), isTrue);
+    expect(typeC.isSubtypeOf(typeA), isTrue);
+    expect(typeA.isSubtypeOf(typeC), isFalse);
+  }
+
+  void test_isSubtypeOf_mixins() {
+    //
+    // class A {}
+    // class B extends A {}
+    // class C with B {}
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    InterfaceType typeObject = classA.supertype;
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    InterfaceType typeC = classC.type;
+    classC.mixins = <InterfaceType>[typeB];
+    expect(typeC.isSubtypeOf(typeB), isTrue);
+    expect(typeC.isSubtypeOf(typeObject), isTrue);
+    expect(typeC.isSubtypeOf(typeA), isTrue);
+    expect(typeA.isSubtypeOf(typeC), isFalse);
+  }
+
+  void test_isSubtypeOf_object() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    InterfaceType typeObject = classA.supertype;
+    expect(typeA.isSubtypeOf(typeObject), isTrue);
+    expect(typeObject.isSubtypeOf(typeA), isFalse);
+  }
+
+  void test_isSubtypeOf_self() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    expect(typeA.isSubtypeOf(typeA), isTrue);
+  }
+
+  void test_isSubtypeOf_transitive_recursive() {
+    //
+    //  class A extends B {}
+    //  class B extends A {}
+    //  class C {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    InterfaceType typeA = classA.type;
+    InterfaceType typeC = classC.type;
+    classA.supertype = classB.type;
+    expect(typeA.isSubtypeOf(typeC), isFalse);
+  }
+
+  void test_isSubtypeOf_transitive_superclass() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElement classC = ElementFactory.classElement("C", classB.type);
+    InterfaceType typeA = classA.type;
+    InterfaceType typeC = classC.type;
+    expect(typeC.isSubtypeOf(typeA), isTrue);
+    expect(typeA.isSubtypeOf(typeC), isFalse);
+  }
+
+  void test_isSubtypeOf_typeArguments() {
+    DartType dynamicType = DynamicTypeImpl.instance;
+    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    ClassElement classI = ElementFactory.classElement2("I");
+    ClassElement classJ = ElementFactory.classElement("J", classI.type);
+    ClassElement classK = ElementFactory.classElement2("K");
+    InterfaceType typeA = classA.type;
+    InterfaceType typeA_dynamic = typeA.substitute4(<DartType>[dynamicType]);
+    InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
+    InterfaceTypeImpl typeAJ = new InterfaceTypeImpl(classA);
+    InterfaceTypeImpl typeAK = new InterfaceTypeImpl(classA);
+    typeAI.typeArguments = <DartType>[classI.type];
+    typeAJ.typeArguments = <DartType>[classJ.type];
+    typeAK.typeArguments = <DartType>[classK.type];
+    // A<J> <: A<I> since J <: I
+    expect(typeAJ.isSubtypeOf(typeAI), isTrue);
+    expect(typeAI.isSubtypeOf(typeAJ), isFalse);
+    // A<I> <: A<I> since I <: I
+    expect(typeAI.isSubtypeOf(typeAI), isTrue);
+    // A <: A<I> and A <: A<J>
+    expect(typeA_dynamic.isSubtypeOf(typeAI), isTrue);
+    expect(typeA_dynamic.isSubtypeOf(typeAJ), isTrue);
+    // A<I> <: A and A<J> <: A
+    expect(typeAI.isSubtypeOf(typeA_dynamic), isTrue);
+    expect(typeAJ.isSubtypeOf(typeA_dynamic), isTrue);
+    // A<I> !<: A<K> and A<K> !<: A<I>
+    expect(typeAI.isSubtypeOf(typeAK), isFalse);
+    expect(typeAK.isSubtypeOf(typeAI), isFalse);
+  }
+
+  void test_isSubtypeOf_typeParameter() {
+    //
+    // class A<E> {}
+    //
+    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    InterfaceType typeA = classA.type;
+    TypeParameterType parameterType = classA.typeParameters[0].type;
+    expect(typeA.isSubtypeOf(parameterType), isFalse);
+  }
+
+  void test_isSupertypeOf_directSupertype() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    expect(typeB.isSupertypeOf(typeA), isFalse);
+    expect(typeA.isSupertypeOf(typeB), isTrue);
+  }
+
+  void test_isSupertypeOf_dynamic() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    DartType dynamicType = DynamicTypeImpl.instance;
+    expect(dynamicType.isSupertypeOf(typeA), isTrue);
+    expect(typeA.isSupertypeOf(dynamicType), isTrue);
+  }
+
+  void test_isSupertypeOf_indirectSupertype() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElement classC = ElementFactory.classElement("C", classB.type);
+    InterfaceType typeA = classA.type;
+    InterfaceType typeC = classC.type;
+    expect(typeC.isSupertypeOf(typeA), isFalse);
+    expect(typeA.isSupertypeOf(typeC), isTrue);
+  }
+
+  void test_isSupertypeOf_interface() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    InterfaceType typeObject = classA.supertype;
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    InterfaceType typeC = classC.type;
+    classC.interfaces = <InterfaceType>[typeB];
+    expect(typeB.isSupertypeOf(typeC), isTrue);
+    expect(typeObject.isSupertypeOf(typeC), isTrue);
+    expect(typeA.isSupertypeOf(typeC), isTrue);
+    expect(typeC.isSupertypeOf(typeA), isFalse);
+  }
+
+  void test_isSupertypeOf_mixins() {
+    //
+    // class A {}
+    // class B extends A {}
+    // class C with B {}
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    ClassElementImpl classC = ElementFactory.classElement2("C");
+    InterfaceType typeObject = classA.supertype;
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    InterfaceType typeC = classC.type;
+    classC.mixins = <InterfaceType>[typeB];
+    expect(typeB.isSupertypeOf(typeC), isTrue);
+    expect(typeObject.isSupertypeOf(typeC), isTrue);
+    expect(typeA.isSupertypeOf(typeC), isTrue);
+    expect(typeC.isSupertypeOf(typeA), isFalse);
+  }
+
+  void test_isSupertypeOf_object() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    InterfaceType typeObject = classA.supertype;
+    expect(typeA.isSupertypeOf(typeObject), isFalse);
+    expect(typeObject.isSupertypeOf(typeA), isTrue);
+  }
+
+  void test_isSupertypeOf_self() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    expect(typeA.isSupertypeOf(typeA), isTrue);
+  }
+
+  void test_lookUpGetter_implemented() {
+    //
+    // class A { g {} }
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String getterName = "g";
+    PropertyAccessorElement getterG =
+        ElementFactory.getterElement(getterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[getterG];
+    InterfaceType typeA = classA.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    expect(typeA.lookUpGetter(getterName, library), same(getterG));
+  }
+
+  void test_lookUpGetter_inherited() {
+    //
+    // class A { g {} }
+    // class B extends A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String getterName = "g";
+    PropertyAccessorElement getterG =
+        ElementFactory.getterElement(getterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[getterG];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    InterfaceType typeB = classB.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    expect(typeB.lookUpGetter(getterName, library), same(getterG));
+  }
+
+  void test_lookUpGetter_mixin_shadowing() {
+    //
+    // class B {}
+    // class M1 { get g {} }
+    // class M2 { get g {} }
+    // class C extends B with M1, M2 {}
+    //
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String getterName = 'g';
+    ClassElementImpl classB = ElementFactory.classElement2('B');
+    ClassElementImpl classM1 = ElementFactory.classElement2('M1');
+    PropertyAccessorElementImpl getterM1g = ElementFactory.getterElement(
+        getterName, false, typeProvider.dynamicType);
+    classM1.accessors = <PropertyAccessorElement>[getterM1g];
+    ClassElementImpl classM2 = ElementFactory.classElement2('M2');
+    PropertyAccessorElementImpl getterM2g = ElementFactory.getterElement(
+        getterName, false, typeProvider.dynamicType);
+    classM2.accessors = <PropertyAccessorElement>[getterM2g];
+    ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
+    classC.mixins = <InterfaceType>[classM1.type, classM2.type];
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElementImpl unit = library.definingCompilationUnit;
+    unit.types = <ClassElement>[classB, classM1, classM2, classC];
+    expect(classC.type.lookUpGetter(getterName, library), getterM2g);
+  }
+
+  void test_lookUpGetter_recursive() {
+    //
+    // class A extends B {}
+    // class B extends A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    ClassElementImpl classB = ElementFactory.classElement("B", typeA);
+    classA.supertype = classB.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    expect(typeA.lookUpGetter("g", library), isNull);
+  }
+
+  void test_lookUpGetter_unimplemented() {
+    //
+    // class A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    expect(typeA.lookUpGetter("g", library), isNull);
+  }
+
+  void test_lookUpMethod_implemented() {
+    //
+    // class A { m() {} }
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[methodM];
+    InterfaceType typeA = classA.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    expect(typeA.lookUpMethod(methodName, library), same(methodM));
+  }
+
+  void test_lookUpMethod_inherited() {
+    //
+    // class A { m() {} }
+    // class B extends A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String methodName = "m";
+    MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
+    classA.methods = <MethodElement>[methodM];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    InterfaceType typeB = classB.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    expect(typeB.lookUpMethod(methodName, library), same(methodM));
+  }
+
+  void test_lookUpMethod_mixin_shadowing() {
+    //
+    // class B {}
+    // class M1 { m() {} }
+    // class M2 { m() {} }
+    // class C extends B with M1, M2 {}
+    //
+    String methodName = 'm';
+    ClassElementImpl classB = ElementFactory.classElement2('B');
+    ClassElementImpl classM1 = ElementFactory.classElement2('M1');
+    MethodElementImpl methodM1m =
+        ElementFactory.methodElement(methodName, null);
+    classM1.methods = <MethodElement>[methodM1m];
+    ClassElementImpl classM2 = ElementFactory.classElement2('M2');
+    MethodElementImpl methodM2m =
+        ElementFactory.methodElement(methodName, null);
+    classM2.methods = <MethodElement>[methodM2m];
+    ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
+    classC.mixins = <InterfaceType>[classM1.type, classM2.type];
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElementImpl unit = library.definingCompilationUnit;
+    unit.types = <ClassElement>[classB, classM1, classM2, classC];
+    expect(classC.type.lookUpMethod(methodName, library), methodM2m);
+  }
+
+  void test_lookUpMethod_parameterized() {
+    //
+    // class A<E> { E m(E p) {} }
+    // class B<F> extends A<F> {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
+    DartType typeE = classA.type.typeArguments[0];
+    String methodName = "m";
+    MethodElementImpl methodM =
+        ElementFactory.methodElement(methodName, typeE, [typeE]);
+    classA.methods = <MethodElement>[methodM];
+    methodM.type = new FunctionTypeImpl(methodM);
+    ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
+    InterfaceType typeB = classB.type;
+    InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
+    typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
+    classB.supertype = typeAF;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    //
+    // B<I>
+    //
+    InterfaceType typeI = ElementFactory.classElement2("I").type;
+    InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
+    typeBI.typeArguments = <DartType>[typeI];
+    MethodElement method = typeBI.lookUpMethod(methodName, library);
+    expect(method, isNotNull);
+    FunctionType methodType = method.type;
+    expect(methodType.returnType, same(typeI));
+    List<DartType> parameterTypes = methodType.normalParameterTypes;
+    expect(parameterTypes, hasLength(1));
+    expect(parameterTypes[0], same(typeI));
+  }
+
+  void test_lookUpMethod_recursive() {
+    //
+    // class A extends B {}
+    // class B extends A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    ClassElementImpl classB = ElementFactory.classElement("B", typeA);
+    classA.supertype = classB.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    expect(typeA.lookUpMethod("m", library), isNull);
+  }
+
+  void test_lookUpMethod_unimplemented() {
+    //
+    // class A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    expect(typeA.lookUpMethod("m", library), isNull);
+  }
+
+  void test_lookUpSetter_implemented() {
+    //
+    // class A { s(x) {} }
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String setterName = "s";
+    PropertyAccessorElement setterS =
+        ElementFactory.setterElement(setterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[setterS];
+    InterfaceType typeA = classA.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    expect(typeA.lookUpSetter(setterName, library), same(setterS));
+  }
+
+  void test_lookUpSetter_inherited() {
+    //
+    // class A { s(x) {} }
+    // class B extends A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    String setterName = "g";
+    PropertyAccessorElement setterS =
+        ElementFactory.setterElement(setterName, false, null);
+    classA.accessors = <PropertyAccessorElement>[setterS];
+    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+    InterfaceType typeB = classB.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    expect(typeB.lookUpSetter(setterName, library), same(setterS));
+  }
+
+  void test_lookUpSetter_mixin_shadowing() {
+    //
+    // class B {}
+    // class M1 { set s() {} }
+    // class M2 { set s() {} }
+    // class C extends B with M1, M2 {}
+    //
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String setterName = 's';
+    ClassElementImpl classB = ElementFactory.classElement2('B');
+    ClassElementImpl classM1 = ElementFactory.classElement2('M1');
+    PropertyAccessorElementImpl setterM1g = ElementFactory.setterElement(
+        setterName, false, typeProvider.dynamicType);
+    classM1.accessors = <PropertyAccessorElement>[setterM1g];
+    ClassElementImpl classM2 = ElementFactory.classElement2('M2');
+    PropertyAccessorElementImpl setterM2g = ElementFactory.getterElement(
+        setterName, false, typeProvider.dynamicType);
+    classM2.accessors = <PropertyAccessorElement>[setterM2g];
+    ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
+    classC.mixins = <InterfaceType>[classM1.type, classM2.type];
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElementImpl unit = library.definingCompilationUnit;
+    unit.types = <ClassElement>[classB, classM1, classM2, classC];
+    expect(classC.type.lookUpGetter(setterName, library), setterM2g);
+  }
+
+  void test_lookUpSetter_recursive() {
+    //
+    // class A extends B {}
+    // class B extends A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    ClassElementImpl classB = ElementFactory.classElement("B", typeA);
+    classA.supertype = classB.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    expect(typeA.lookUpSetter("s", library), isNull);
+  }
+
+  void test_lookUpSetter_unimplemented() {
+    //
+    // class A {}
+    //
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    InterfaceType typeA = classA.type;
+    LibraryElementImpl library =
+        ElementFactory.library(createAnalysisContext(), "lib");
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    expect(typeA.lookUpSetter("s", library), isNull);
+  }
+
+  void test_setTypeArguments() {
+    InterfaceTypeImpl type =
+        ElementFactory.classElement2("A").type as InterfaceTypeImpl;
+    List<DartType> typeArguments = <DartType>[
+      ElementFactory.classElement2("B").type,
+      ElementFactory.classElement2("C").type
+    ];
+    type.typeArguments = typeArguments;
+    expect(type.typeArguments, typeArguments);
+  }
+
+  void test_substitute_equal() {
+    ClassElement classAE = ElementFactory.classElement2("A", ["E"]);
+    InterfaceType typeAE = classAE.type;
+    InterfaceType argumentType = ElementFactory.classElement2("B").type;
+    List<DartType> args = [argumentType];
+    List<DartType> params = [classAE.typeParameters[0].type];
+    InterfaceType typeAESubbed = typeAE.substitute2(args, params);
+    expect(typeAESubbed.element, classAE);
+    List<DartType> resultArguments = typeAESubbed.typeArguments;
+    expect(resultArguments, hasLength(1));
+    expect(resultArguments[0], argumentType);
+  }
+
+  void test_substitute_exception() {
+    try {
+      ClassElementImpl classA = ElementFactory.classElement2("A");
+      InterfaceTypeImpl type = new InterfaceTypeImpl(classA);
+      InterfaceType argumentType = ElementFactory.classElement2("B").type;
+      type.substitute2(<DartType>[argumentType], <DartType>[]);
+      fail(
+          "Expected to encounter exception, argument and parameter type array lengths not equal.");
+    } catch (e) {
+      // Expected result
+    }
+  }
+
+  void test_substitute_notEqual() {
+    // The [test_substitute_equals] above has a slightly higher level
+    // implementation.
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    TypeParameterElementImpl parameterElement =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+    InterfaceTypeImpl type = new InterfaceTypeImpl(classA);
+    TypeParameterTypeImpl parameter =
+        new TypeParameterTypeImpl(parameterElement);
+    type.typeArguments = <DartType>[parameter];
+    InterfaceType argumentType = ElementFactory.classElement2("B").type;
+    TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("F")));
+    InterfaceType result =
+        type.substitute2(<DartType>[argumentType], <DartType>[parameterType]);
+    expect(result.element, classA);
+    List<DartType> resultArguments = result.typeArguments;
+    expect(resultArguments, hasLength(1));
+    expect(resultArguments[0], parameter);
+  }
+}
+
+@reflectiveTest
+class LibraryElementImplTest extends EngineTestCase {
+  void test_creation() {
+    expect(
+        new LibraryElementImpl.forNode(
+            createAnalysisContext(), AstFactory.libraryIdentifier2(["l"])),
+        isNotNull);
+  }
+
+  void test_getImportedLibraries() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library1 = ElementFactory.library(context, "l1");
+    LibraryElementImpl library2 = ElementFactory.library(context, "l2");
+    LibraryElementImpl library3 = ElementFactory.library(context, "l3");
+    LibraryElementImpl library4 = ElementFactory.library(context, "l4");
+    PrefixElement prefixA =
+        new PrefixElementImpl.forNode(AstFactory.identifier3("a"));
+    PrefixElement prefixB =
+        new PrefixElementImpl.forNode(AstFactory.identifier3("b"));
+    List<ImportElementImpl> imports = [
+      ElementFactory.importFor(library2, null),
+      ElementFactory.importFor(library2, prefixB),
+      ElementFactory.importFor(library3, null),
+      ElementFactory.importFor(library3, prefixA),
+      ElementFactory.importFor(library3, prefixB),
+      ElementFactory.importFor(library4, prefixA)
+    ];
+    library1.imports = imports;
+    List<LibraryElement> libraries = library1.importedLibraries;
+    expect(libraries,
+        unorderedEquals(<LibraryElement>[library2, library3, library4]));
+  }
+
+  void test_getPrefixes() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "l1");
+    PrefixElement prefixA =
+        new PrefixElementImpl.forNode(AstFactory.identifier3("a"));
+    PrefixElement prefixB =
+        new PrefixElementImpl.forNode(AstFactory.identifier3("b"));
+    List<ImportElementImpl> imports = [
+      ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
+      ElementFactory.importFor(ElementFactory.library(context, "l3"), null),
+      ElementFactory.importFor(ElementFactory.library(context, "l4"), prefixA),
+      ElementFactory.importFor(ElementFactory.library(context, "l5"), prefixA),
+      ElementFactory.importFor(ElementFactory.library(context, "l6"), prefixB)
+    ];
+    library.imports = imports;
+    List<PrefixElement> prefixes = library.prefixes;
+    expect(prefixes, hasLength(2));
+    if (identical(prefixA, prefixes[0])) {
+      expect(prefixes[1], same(prefixB));
+    } else {
+      expect(prefixes[0], same(prefixB));
+      expect(prefixes[1], same(prefixA));
+    }
+  }
+
+  void test_getUnits() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "test");
+    CompilationUnitElement unitLib = library.definingCompilationUnit;
+    CompilationUnitElementImpl unitA =
+        ElementFactory.compilationUnit("unit_a.dart", unitLib.source);
+    CompilationUnitElementImpl unitB =
+        ElementFactory.compilationUnit("unit_b.dart", unitLib.source);
+    library.parts = <CompilationUnitElement>[unitA, unitB];
+    expect(library.units,
+        unorderedEquals(<CompilationUnitElement>[unitLib, unitA, unitB]));
+  }
+
+  void test_getVisibleLibraries_cycle() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    libraryA.imports = <ImportElementImpl>[
+      ElementFactory.importFor(library, null)
+    ];
+    library.imports = <ImportElementImpl>[
+      ElementFactory.importFor(libraryA, null)
+    ];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA]));
+  }
+
+  void test_getVisibleLibraries_directExports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    library.exports = <ExportElementImpl>[ElementFactory.exportFor(libraryA)];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    expect(libraries, unorderedEquals(<LibraryElement>[library]));
+  }
+
+  void test_getVisibleLibraries_directImports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    library.imports = <ImportElementImpl>[
+      ElementFactory.importFor(libraryA, null)
+    ];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA]));
+  }
+
+  void test_getVisibleLibraries_indirectExports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
+    libraryA.exports = <ExportElementImpl>[ElementFactory.exportFor(libraryAA)];
+    library.imports = <ImportElementImpl>[
+      ElementFactory.importFor(libraryA, null)
+    ];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    expect(libraries,
+        unorderedEquals(<LibraryElement>[library, libraryA, libraryAA]));
+  }
+
+  void test_getVisibleLibraries_indirectImports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
+    LibraryElementImpl libraryB = ElementFactory.library(context, "B");
+    libraryA.imports = <ImportElementImpl>[
+      ElementFactory.importFor(libraryAA, null)
+    ];
+    library.imports = <ImportElementImpl>[
+      ElementFactory.importFor(libraryA, null),
+      ElementFactory.importFor(libraryB, null)
+    ];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    expect(
+        libraries,
+        unorderedEquals(
+            <LibraryElement>[library, libraryA, libraryAA, libraryB]));
+  }
+
+  void test_getVisibleLibraries_noImports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    expect(
+        library.visibleLibraries, unorderedEquals(<LibraryElement>[library]));
+  }
+
+  void test_isUpToDate() {
+    AnalysisContext context = createAnalysisContext();
+    context.sourceFactory = new SourceFactory([]);
+    LibraryElement library = ElementFactory.library(context, "foo");
+    context.setContents(library.definingCompilationUnit.source, "sdfsdff");
+    // Assert that we are not up to date if the target has an old time stamp.
+    expect(library.isUpToDate(0), isFalse);
+    // Assert that we are up to date with a target modification time in the
+    // future.
+    expect(library.isUpToDate(JavaSystem.currentTimeMillis() + 1000), isTrue);
+  }
+
+  void test_setImports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = new LibraryElementImpl.forNode(
+        context, AstFactory.libraryIdentifier2(["l1"]));
+    List<ImportElementImpl> expectedImports = [
+      ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
+      ElementFactory.importFor(ElementFactory.library(context, "l3"), null)
+    ];
+    library.imports = expectedImports;
+    List<ImportElement> actualImports = library.imports;
+    expect(actualImports, hasLength(expectedImports.length));
+    for (int i = 0; i < actualImports.length; i++) {
+      expect(actualImports[i], same(expectedImports[i]));
+    }
+  }
+}
+
+@reflectiveTest
+class MethodElementImplTest extends EngineTestCase {
+  void test_computeNode() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource(
+        "/test.dart",
+        r'''
+abstract class A {
+  String m1() => null;
+  m2();
+}
+''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // m1
+    {
+      MethodElement m1Element = unitElement.getType("A").getMethod('m1');
+      MethodDeclaration m1Node = m1Element.computeNode();
+      expect(m1Node, isNotNull);
+      expect(m1Node.name.name, "m1");
+      expect(m1Node.element, same(m1Element));
+    }
+    // m2
+    {
+      MethodElement m2Element = unitElement.getType("A").getMethod('m2');
+      MethodDeclaration m2Node = m2Element.computeNode();
+      expect(m2Node, isNotNull);
+      expect(m2Node.name.name, "m2");
+      expect(m2Node.element, same(m2Element));
+    }
+  }
+
+  void test_computeNode_withoutFunctionBody() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.analyzeFunctionBodies = false;
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper(options);
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource(
+        "/test.dart",
+        r'''
+abstract class A {
+  String m1() => null;
+  m2();
+}
+''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // m1
+    {
+      MethodElement m1Element = unitElement.getType("A").getMethod('m1');
+      MethodDeclaration m1Node = m1Element.computeNode();
+      expect(m1Node, isNotNull);
+      expect(m1Node.name.name, "m1");
+      expect(m1Node.element, same(m1Element));
+    }
+    // m2
+    {
+      MethodElement m2Element = unitElement.getType("A").getMethod('m2');
+      MethodDeclaration m2Node = m2Element.computeNode();
+      expect(m2Node, isNotNull);
+      expect(m2Node.name.name, "m2");
+      expect(m2Node.element, same(m2Element));
+    }
+  }
+}
+
+@reflectiveTest
+class MultiplyDefinedElementImplTest extends EngineTestCase {
+  void test_fromElements_conflicting() {
+    Element firstElement = ElementFactory.localVariableElement2("xx");
+    Element secondElement = ElementFactory.localVariableElement2("yy");
+    Element result = MultiplyDefinedElementImpl.fromElements(
+        null, firstElement, secondElement);
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MultiplyDefinedElement, MultiplyDefinedElement, result);
+    List<Element> elements =
+        (result as MultiplyDefinedElement).conflictingElements;
+    expect(elements, hasLength(2));
+    for (int i = 0; i < elements.length; i++) {
+      EngineTestCase.assertInstanceOf((obj) => obj is LocalVariableElement,
+          LocalVariableElement, elements[i]);
+    }
+  }
+
+  void test_fromElements_multiple() {
+    Element firstElement = ElementFactory.localVariableElement2("xx");
+    Element secondElement = ElementFactory.localVariableElement2("yy");
+    Element thirdElement = ElementFactory.localVariableElement2("zz");
+    Element result = MultiplyDefinedElementImpl.fromElements(
+        null,
+        MultiplyDefinedElementImpl.fromElements(
+            null, firstElement, secondElement),
+        thirdElement);
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MultiplyDefinedElement, MultiplyDefinedElement, result);
+    List<Element> elements =
+        (result as MultiplyDefinedElement).conflictingElements;
+    expect(elements, hasLength(3));
+    for (int i = 0; i < elements.length; i++) {
+      EngineTestCase.assertInstanceOf((obj) => obj is LocalVariableElement,
+          LocalVariableElement, elements[i]);
+    }
+  }
+
+  void test_fromElements_nonConflicting() {
+    Element element = ElementFactory.localVariableElement2("xx");
+    expect(MultiplyDefinedElementImpl.fromElements(null, element, element),
+        same(element));
+  }
+}
+
+@reflectiveTest
+class ParameterElementImplTest extends EngineTestCase {
+  void test_computeNode_DefaultFormalParameter() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource(
+        "/test.dart",
+        r'''
+main([int p = 42]) {
+}''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // p
+    {
+      ParameterElement element = unitElement.functions[0].parameters[0];
+      DefaultFormalParameter node = element.computeNode();
+      expect(node, isNotNull);
+      expect(node.identifier.name, 'p');
+      expect(node.element, same(element));
+    }
+  }
+
+  void test_computeNode_FieldFormalParameter() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource(
+        "/test.dart",
+        r'''
+class A {
+  int p;
+  A(this.p) {
+  }
+}''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // p
+    {
+      ClassElement classA = unitElement.types[0];
+      ConstructorElement constructorA = classA.constructors[0];
+      FieldFormalParameterElement element = constructorA.parameters[0];
+      FieldFormalParameter node = element.computeNode();
+      expect(node, isNotNull);
+      expect(node.identifier.name, 'p');
+      expect(node.element, same(element));
+    }
+  }
+
+  void test_computeNode_FunctionTypedFormalParameter() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource(
+        "/test.dart",
+        r'''
+main(p(int a, int b)) {
+}''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // p
+    {
+      ParameterElement element = unitElement.functions[0].parameters[0];
+      FunctionTypedFormalParameter node = element.computeNode();
+      expect(node, isNotNull);
+      expect(node.identifier.name, 'p');
+      expect(node.element, same(element));
+    }
+  }
+
+  void test_computeNode_SimpleFormalParameter() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource(
+        "/test.dart",
+        r'''
+main(int p) {
+}''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // p
+    {
+      ParameterElement element = unitElement.functions[0].parameters[0];
+      SimpleFormalParameter node = element.computeNode();
+      expect(node, isNotNull);
+      expect(node.identifier.name, 'p');
+      expect(node.element, same(element));
+    }
+  }
+}
+
+@reflectiveTest
+class TypeParameterTypeImplTest extends EngineTestCase {
+  void test_creation() {
+    expect(
+        new TypeParameterTypeImpl(
+            new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"))),
+        isNotNull);
+  }
+
+  void test_getElement() {
+    TypeParameterElementImpl element =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+    expect(type.element, element);
+  }
+
+  void test_isMoreSpecificThan_typeArguments_dynamic() {
+    TypeParameterElementImpl element =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+    // E << dynamic
+    expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
+  }
+
+  void test_isMoreSpecificThan_typeArguments_object() {
+    TypeParameterElementImpl element =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+    // E << Object
+    expect(type.isMoreSpecificThan(ElementFactory.object.type), isTrue);
+  }
+
+  void test_isMoreSpecificThan_typeArguments_resursive() {
+    ClassElementImpl classS = ElementFactory.classElement2("A");
+    TypeParameterElementImpl typeParameterU =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("U"));
+    TypeParameterTypeImpl typeParameterTypeU =
+        new TypeParameterTypeImpl(typeParameterU);
+    TypeParameterElementImpl typeParameterT =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
+    TypeParameterTypeImpl typeParameterTypeT =
+        new TypeParameterTypeImpl(typeParameterT);
+    typeParameterT.bound = typeParameterTypeU;
+    typeParameterU.bound = typeParameterTypeU;
+    // <T extends U> and <U extends T>
+    // T << S
+    expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isFalse);
+  }
+
+  void test_isMoreSpecificThan_typeArguments_self() {
+    TypeParameterElementImpl element =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+    // E << E
+    expect(type.isMoreSpecificThan(type), isTrue);
+  }
+
+  void test_isMoreSpecificThan_typeArguments_transitivity_interfaceTypes() {
+    //  class A {}
+    //  class B extends A {}
+    //
+    ClassElement classA = ElementFactory.classElement2("A");
+    ClassElement classB = ElementFactory.classElement("B", classA.type);
+    InterfaceType typeA = classA.type;
+    InterfaceType typeB = classB.type;
+    TypeParameterElementImpl typeParameterT =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
+    typeParameterT.bound = typeB;
+    TypeParameterTypeImpl typeParameterTypeT =
+        new TypeParameterTypeImpl(typeParameterT);
+    // <T extends B>
+    // T << A
+    expect(typeParameterTypeT.isMoreSpecificThan(typeA), isTrue);
+  }
+
+  void test_isMoreSpecificThan_typeArguments_transitivity_typeParameters() {
+    ClassElementImpl classS = ElementFactory.classElement2("A");
+    TypeParameterElementImpl typeParameterU =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("U"));
+    typeParameterU.bound = classS.type;
+    TypeParameterTypeImpl typeParameterTypeU =
+        new TypeParameterTypeImpl(typeParameterU);
+    TypeParameterElementImpl typeParameterT =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
+    typeParameterT.bound = typeParameterTypeU;
+    TypeParameterTypeImpl typeParameterTypeT =
+        new TypeParameterTypeImpl(typeParameterT);
+    // <T extends U> and <U extends S>
+    // T << S
+    expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue);
+  }
+
+  void test_isMoreSpecificThan_typeArguments_upperBound() {
+    ClassElementImpl classS = ElementFactory.classElement2("A");
+    TypeParameterElementImpl typeParameterT =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
+    typeParameterT.bound = classS.type;
+    TypeParameterTypeImpl typeParameterTypeT =
+        new TypeParameterTypeImpl(typeParameterT);
+    // <T extends S>
+    // T << S
+    expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue);
+  }
+
+  void test_substitute_equal() {
+    TypeParameterElementImpl element =
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+    TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+    InterfaceTypeImpl argument = new InterfaceTypeImpl(
+        new ClassElementImpl.forNode(AstFactory.identifier3("A")));
+    TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(element);
+    expect(type.substitute2(<DartType>[argument], <DartType>[parameter]),
+        same(argument));
+  }
+
+  void test_substitute_notEqual() {
+    TypeParameterTypeImpl type = new TypeParameterTypeImpl(
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
+    InterfaceTypeImpl argument = new InterfaceTypeImpl(
+        new ClassElementImpl.forNode(AstFactory.identifier3("A")));
+    TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(
+        new TypeParameterElementImpl.forNode(AstFactory.identifier3("F")));
+    expect(type.substitute2(<DartType>[argument], <DartType>[parameter]),
+        same(type));
+  }
+}
+
+@reflectiveTest
+class VoidTypeImplTest extends EngineTestCase {
+  /**
+   * Reference {code VoidTypeImpl.getInstance()}.
+   */
+  DartType _voidType = VoidTypeImpl.instance;
+
+  void test_isMoreSpecificThan_void_A() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    expect(_voidType.isMoreSpecificThan(classA.type), isFalse);
+  }
+
+  void test_isMoreSpecificThan_void_dynamic() {
+    expect(_voidType.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
+  }
+
+  void test_isMoreSpecificThan_void_void() {
+    expect(_voidType.isMoreSpecificThan(_voidType), isTrue);
+  }
+
+  void test_isSubtypeOf_void_A() {
+    ClassElement classA = ElementFactory.classElement2("A");
+    expect(_voidType.isSubtypeOf(classA.type), isFalse);
+  }
+
+  void test_isSubtypeOf_void_dynamic() {
+    expect(_voidType.isSubtypeOf(DynamicTypeImpl.instance), isTrue);
+  }
+
+  void test_isSubtypeOf_void_void() {
+    expect(_voidType.isSubtypeOf(_voidType), isTrue);
+  }
+
+  void test_isVoid() {
+    expect(_voidType.isVoid, isTrue);
+  }
+}
+
+class _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction
+    extends InterfaceTypeImpl {
+  _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction(ClassElement arg0)
+      : super(arg0);
+
+  @override
+  bool get isDartCoreFunction => true;
+}
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
new file mode 100644
index 0000000..c401919
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -0,0 +1,18 @@
+// 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 analyzer.test.generated.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'element_test.dart' as element;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('element tests', () {
+    element.main();
+  });
+}
diff --git a/pkg/analyzer/test/src/dart/test_all.dart b/pkg/analyzer/test/src/dart/test_all.dart
new file mode 100644
index 0000000..f0c4598
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/test_all.dart
@@ -0,0 +1,18 @@
+// 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 analyzer.test.generated.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../utils.dart';
+import 'element/test_all.dart' as element;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('dart tests', () {
+    element.main();
+  });
+}
diff --git a/pkg/analyzer/test/src/mock_sdk.dart b/pkg/analyzer/test/src/mock_sdk.dart
index d4f6ac1..b08e293 100644
--- a/pkg/analyzer/test/src/mock_sdk.dart
+++ b/pkg/analyzer/test/src/mock_sdk.dart
@@ -2,11 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.mock_sdk;
+library analyzer.test.src.mock_sdk;
 
 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/context/context.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -201,11 +201,7 @@
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      if (AnalysisEngine.instance.useTaskModel) {
-        _analysisContext = new newContext.SdkAnalysisContext();
-      } else {
-        _analysisContext = new SdkAnalysisContext();
-      }
+      _analysisContext = new SdkAnalysisContext();
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
       ChangeSet changeSet = new ChangeSet();
@@ -255,7 +251,7 @@
       }
       if (filePath.startsWith("$libraryPath/")) {
         String pathInLibrary = filePath.substring(libraryPath.length + 1);
-        String path = '${library.shortName}/${pathInLibrary}';
+        String path = '${library.shortName}/$pathInLibrary';
         try {
           resource.File file = provider.getResource(uri.path);
           Uri dartUri = new Uri(scheme: 'dart', path: path);
diff --git a/pkg/analyzer/test/src/plugin/plugin_config_test.dart b/pkg/analyzer/test/src/plugin/plugin_config_test.dart
index cc06b96..2c9fa04 100644
--- a/pkg/analyzer/test/src/plugin/plugin_config_test.dart
+++ b/pkg/analyzer/test/src/plugin/plugin_config_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.plugin.plugin_config_test;
+library analyzer.test.src.plugin.plugin_config_test;
 
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/src/plugin/plugin_configuration.dart';
diff --git a/pkg/analyzer/test/src/summary/flat_buffers_test.dart b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
new file mode 100644
index 0000000..e7b7804
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
@@ -0,0 +1,235 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.src.summary.flat_buffers_test;
+
+import 'package:analyzer/src/summary/flat_buffers.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(BuilderTest);
+}
+
+@reflectiveTest
+class BuilderTest {
+  void test_error_addInt32_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.addInt32(0, 0);
+    }, throwsStateError);
+  }
+
+  void test_error_addOffset_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.addOffset(0, new Offset(0));
+    }, throwsStateError);
+  }
+
+  void test_error_endTable_withoutStartTable() {
+    Builder builder = new Builder();
+    expect(() {
+      builder.endTable();
+    }, throwsStateError);
+  }
+
+  void test_error_startTable_duringTable() {
+    Builder builder = new Builder();
+    builder.startTable();
+    expect(() {
+      builder.startTable();
+    }, throwsStateError);
+  }
+
+  void test_error_writeString_duringTable() {
+    Builder builder = new Builder();
+    builder.startTable();
+    expect(() {
+      builder.writeString('12345');
+    }, throwsStateError);
+  }
+
+  void test_low() {
+    Builder builder = new Builder(initialSize: 0);
+    builder.lowReset();
+    expect((builder..lowWriteUint8(1)).lowFinish(), [1]);
+    expect((builder..lowWriteUint32(2)).lowFinish(), [2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..lowWriteUint8(3)).lowFinish(),
+        [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..lowWriteUint8(4)).lowFinish(),
+        [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..lowWriteUint8(5)).lowFinish(),
+        [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+    expect((builder..lowWriteUint32(6)).lowFinish(),
+        [6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
+  }
+
+  void test_table_default() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      builder.startTable();
+      builder.addInt32(0, 10, 10);
+      builder.addInt32(1, 20, 10);
+      Offset offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer object = new BufferPointer.fromBytes(byteList).derefObject();
+    // was not written, so uses the new default value
+    expect(const Int32Reader().vTableGet(object, 0, 15), 15);
+    // has the written value
+    expect(const Int32Reader().vTableGet(object, 1, 15), 20);
+  }
+
+  void test_table_types() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset<String> stringOffset = builder.writeString('12345');
+      builder.startTable();
+      builder.addBool(0, true);
+      builder.addInt8(1, 10);
+      builder.addInt32(2, 20);
+      builder.addOffset(3, stringOffset);
+      builder.addInt32(4, 40);
+      Offset offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer object = new BufferPointer.fromBytes(byteList).derefObject();
+    expect(const BoolReader().vTableGet(object, 0), true);
+    expect(const Int8Reader().vTableGet(object, 1), 10);
+    expect(const Int32Reader().vTableGet(object, 2), 20);
+    expect(const StringReader().vTableGet(object, 3), '12345');
+    expect(const Int32Reader().vTableGet(object, 4), 40);
+  }
+
+  void test_writeList_ofInt32() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset offset = builder.writeListInt32(<int>[1, 2, 3, 4, 5]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    List<int> items = const ListReader<int>(const Int32Reader()).read(root);
+    expect(items, hasLength(5));
+    expect(items, orderedEquals(<int>[1, 2, 3, 4, 5]));
+  }
+
+  void test_writeList_ofObjects() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      // write the object #1
+      Offset object1;
+      {
+        builder.startTable();
+        builder.addInt32(0, 10);
+        builder.addInt32(1, 20);
+        object1 = builder.endTable();
+      }
+      // write the object #1
+      Offset object2;
+      {
+        builder.startTable();
+        builder.addInt32(0, 100);
+        builder.addInt32(1, 200);
+        object2 = builder.endTable();
+      }
+      // write the list
+      Offset offset = builder.writeList([object1, object2]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    List<TestPointImpl> items =
+        const ListReader<TestPointImpl>(const TestPointReader()).read(root);
+    expect(items, hasLength(2));
+    expect(items[0].x, 10);
+    expect(items[0].y, 20);
+    expect(items[1].x, 100);
+    expect(items[1].y, 200);
+  }
+
+  void test_writeList_ofStrings_asRoot() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset<String> str1 = builder.writeString('12345');
+      Offset<String> str2 = builder.writeString('ABC');
+      Offset offset = builder.writeList([str1, str2]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    List<String> items =
+        const ListReader<String>(const StringReader()).read(root);
+    expect(items, hasLength(2));
+    expect(items, contains('12345'));
+    expect(items, contains('ABC'));
+  }
+
+  void test_writeList_ofStrings_inObject() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset listOffset = builder.writeList(
+          [builder.writeString('12345'), builder.writeString('ABC')]);
+      builder.startTable();
+      builder.addOffset(0, listOffset);
+      Offset offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    StringListWrapperImpl reader = new StringListWrapperReader().read(root);
+    List<String> items = reader.items;
+    expect(items, hasLength(2));
+    expect(items, contains('12345'));
+    expect(items, contains('ABC'));
+  }
+}
+
+class StringListWrapperImpl {
+  final BufferPointer bp;
+
+  StringListWrapperImpl(this.bp);
+
+  List<String> get items =>
+      const ListReader<String>(const StringReader()).vTableGet(bp, 0);
+}
+
+class StringListWrapperReader extends TableReader<StringListWrapperImpl> {
+  const StringListWrapperReader();
+
+  @override
+  StringListWrapperImpl createObject(BufferPointer object) {
+    return new StringListWrapperImpl(object);
+  }
+}
+
+class TestPointImpl {
+  final BufferPointer bp;
+
+  TestPointImpl(this.bp);
+
+  int get x => const Int32Reader().vTableGet(bp, 0, 0);
+
+  int get y => const Int32Reader().vTableGet(bp, 1, 0);
+}
+
+class TestPointReader extends TableReader<TestPointImpl> {
+  const TestPointReader();
+
+  @override
+  TestPointImpl createObject(BufferPointer object) {
+    return new TestPointImpl(object);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/name_filter_test.dart b/pkg/analyzer/test/src/summary/name_filter_test.dart
new file mode 100644
index 0000000..a3c9ae5
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/name_filter_test.dart
@@ -0,0 +1,251 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/name_filter.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(NameFilterTest);
+}
+
+class MockUnlinkedCombinator implements UnlinkedCombinator {
+  @override
+  final List<String> hides;
+
+  @override
+  final List<String> shows;
+
+  MockUnlinkedCombinator(
+      {this.hides: const <String>[], this.shows: const <String>[]});
+
+  @override
+  Map<String, Object> toMap() {
+    fail('toMap() called unexpectedly');
+    return null;
+  }
+}
+
+@reflectiveTest
+class NameFilterTest {
+  test_accepts_accessors_hide() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(hides: ['bar']));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('foo='), isTrue);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('bar='), isFalse);
+  }
+
+  test_accepts_accessors_show() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo']));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('foo='), isTrue);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('bar='), isFalse);
+  }
+
+  test_forNamespaceCombinator_hide() {
+    NameFilter filter = new NameFilter.forNamespaceCombinator(
+        new HideElementCombinatorImpl()..hiddenNames = ['foo', 'bar']);
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forNamespaceCombinator_show() {
+    NameFilter filter = new NameFilter.forNamespaceCombinator(
+        new ShowElementCombinatorImpl()..shownNames = ['foo', 'bar']);
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forNamespaceCombinators() {
+    NameFilter filter = new NameFilter.forNamespaceCombinators([
+      new HideElementCombinatorImpl()..hiddenNames = ['foo'],
+      new HideElementCombinatorImpl()..hiddenNames = ['bar']
+    ]);
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forUnlinkedCombinator_hide() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(hides: ['foo', 'bar']));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forUnlinkedCombinator_show() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo', 'bar']));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo', 'bar'].toSet());
+  }
+
+  test_forUnlinkedCombinators() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinators([
+      new MockUnlinkedCombinator(hides: ['foo']),
+      new MockUnlinkedCombinator(hides: ['bar'])
+    ]);
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_identity() {
+    expect(NameFilter.identity.accepts('foo'), isTrue);
+    expect(NameFilter.identity.hiddenNames, isNotNull);
+    expect(NameFilter.identity.hiddenNames, isEmpty);
+    expect(NameFilter.identity.shownNames, isNull);
+  }
+
+  test_merge_hides_hides() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(hides: ['foo'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(hides: ['bar'])));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_hides_identity() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(hides: ['foo', 'bar']))
+        .merge(NameFilter.identity);
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_hides_shows() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(hides: ['bar', 'baz'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['foo', 'bar'])));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo'].toSet());
+  }
+
+  test_merge_identity_hides() {
+    NameFilter filter = NameFilter.identity.merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(hides: ['foo', 'bar'])));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isTrue);
+    expect(filter.shownNames, isNull);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_identity_identity() {
+    NameFilter filter = NameFilter.identity.merge(NameFilter.identity);
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.hiddenNames, isNotNull);
+    expect(filter.hiddenNames, isEmpty);
+    expect(filter.shownNames, isNull);
+  }
+
+  test_merge_identity_shows() {
+    NameFilter filter = NameFilter.identity.merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['foo', 'bar'])));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_shows_hides() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo', 'bar'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(hides: ['bar', 'baz'])));
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo'].toSet());
+  }
+
+  test_merge_shows_identity() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['foo', 'bar']))
+        .merge(NameFilter.identity);
+    expect(filter.accepts('foo'), isTrue);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['foo', 'bar'].toSet());
+  }
+
+  test_merge_shows_shows() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo', 'bar'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['bar', 'baz'])));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isTrue);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, ['bar'].toSet());
+  }
+
+  test_merge_shows_shows_emptyResult() {
+    NameFilter filter = new NameFilter.forUnlinkedCombinator(
+        new MockUnlinkedCombinator(shows: ['foo'])).merge(
+        new NameFilter.forUnlinkedCombinator(
+            new MockUnlinkedCombinator(shows: ['bar'])));
+    expect(filter.accepts('foo'), isFalse);
+    expect(filter.accepts('bar'), isFalse);
+    expect(filter.accepts('baz'), isFalse);
+    expect(filter.hiddenNames, isNull);
+    expect(filter.shownNames, isNotNull);
+    expect(filter.shownNames, isEmpty);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
new file mode 100644
index 0000000..c27b507
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -0,0 +1,1396 @@
+// 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 test.src.serialization.elements_test;
+
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/resolver.dart' show Namespace;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../generated/resolver_test.dart';
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(ResynthTest);
+}
+
+@reflectiveTest
+class ResynthTest extends ResolverTestCase {
+  Set<Source> otherLibrarySources = new Set<Source>();
+
+  void addLibrary(String uri) {
+    otherLibrarySources.add(analysisContext2.sourceFactory.forUri(uri));
+  }
+
+  void addLibrarySource(String filePath, String contents) {
+    otherLibrarySources.add(addNamedSource(filePath, contents));
+  }
+
+  void checkLibrary(String text,
+      {bool allowErrors: false, int resynthesisCount: 1}) {
+    Source source = addSource(text);
+    LibraryElementImpl original = resolve2(source);
+    LibraryElementImpl resynthesized = resynthesizeLibrary(
+        source, original, allowErrors,
+        resynthesisCount: resynthesisCount);
+    checkLibraryElements(original, resynthesized);
+  }
+
+  void checkLibraryElements(
+      LibraryElementImpl original, LibraryElementImpl resynthesized) {
+    compareElements(resynthesized, original, '(library)');
+    expect(resynthesized.displayName, original.displayName);
+    expect(original.enclosingElement, isNull);
+    expect(resynthesized.enclosingElement, isNull);
+    expect(resynthesized.hasExtUri, original.hasExtUri);
+    compareCompilationUnitElements(resynthesized.definingCompilationUnit,
+        original.definingCompilationUnit);
+    expect(resynthesized.parts.length, original.parts.length);
+    for (int i = 0; i < resynthesized.parts.length; i++) {
+      compareCompilationUnitElements(resynthesized.parts[i], original.parts[i]);
+    }
+    expect(resynthesized.imports.length, original.imports.length);
+    for (int i = 0; i < resynthesized.imports.length; i++) {
+      compareImportElements(resynthesized.imports[i], original.imports[i],
+          'import ${original.imports[i].uri}');
+    }
+    expect(resynthesized.exports.length, original.exports.length);
+    for (int i = 0; i < resynthesized.exports.length; i++) {
+      compareExportElements(resynthesized.exports[i], original.exports[i],
+          'export ${original.exports[i].uri}');
+    }
+    expect(resynthesized.nameLength, original.nameLength);
+    if (original.entryPoint == null) {
+      expect(resynthesized.entryPoint, isNull);
+    } else {
+      expect(resynthesized.entryPoint, isNotNull);
+      compareFunctionElements(
+          resynthesized.entryPoint, original.entryPoint, '(entry point)');
+    }
+    compareNamespaces(resynthesized.publicNamespace, original.publicNamespace,
+        '(public namespace)');
+    compareNamespaces(resynthesized.exportNamespace, original.exportNamespace,
+        '(export namespace)');
+    // TODO(paulberry): test metadata.
+  }
+
+  void compareClassElements(
+      ClassElementImpl resynthesized, ClassElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    expect(resynthesized.fields.length, original.fields.length,
+        reason: '$desc fields.length');
+    for (int i = 0; i < resynthesized.fields.length; i++) {
+      String name = original.fields[i].name;
+      compareFieldElements(resynthesized.getField(name), original.fields[i],
+          '$desc.field $name');
+    }
+    compareTypes(
+        resynthesized.supertype, original.supertype, '$desc supertype');
+    expect(resynthesized.interfaces.length, original.interfaces.length);
+    for (int i = 0; i < resynthesized.interfaces.length; i++) {
+      compareTypes(resynthesized.interfaces[i], original.interfaces[i],
+          '$desc interface ${original.interfaces[i].name}');
+    }
+    expect(resynthesized.mixins.length, original.mixins.length);
+    for (int i = 0; i < resynthesized.mixins.length; i++) {
+      compareTypes(resynthesized.mixins[i], original.mixins[i],
+          '$desc mixin ${original.mixins[i].name}');
+    }
+    expect(resynthesized.typeParameters.length, original.typeParameters.length);
+    for (int i = 0; i < resynthesized.typeParameters.length; i++) {
+      compareTypeParameterElements(
+          resynthesized.typeParameters[i],
+          original.typeParameters[i],
+          '$desc type parameter ${original.typeParameters[i].name}');
+    }
+    expect(resynthesized.constructors.length, original.constructors.length,
+        reason: '$desc constructors.length');
+    for (int i = 0; i < resynthesized.constructors.length; i++) {
+      compareConstructorElements(
+          resynthesized.constructors[i],
+          original.constructors[i],
+          '$desc constructor ${original.constructors[i].name}');
+    }
+    expect(resynthesized.accessors.length, original.accessors.length);
+    for (int i = 0; i < resynthesized.accessors.length; i++) {
+      String name = original.accessors[i].name;
+      if (name.endsWith('=')) {
+        comparePropertyAccessorElements(
+            resynthesized.getSetter(name),
+            original.accessors[i],
+            '$desc setter ${original.accessors[i].name}');
+      } else {
+        comparePropertyAccessorElements(
+            resynthesized.getGetter(name),
+            original.accessors[i],
+            '$desc getter ${original.accessors[i].name}');
+      }
+    }
+    expect(resynthesized.methods.length, original.methods.length);
+    for (int i = 0; i < resynthesized.methods.length; i++) {
+      compareMethodElements(resynthesized.methods[i], original.methods[i],
+          '$desc.${original.methods[i].name}');
+    }
+    compareTypes(resynthesized.type, original.type, desc);
+  }
+
+  void compareCompilationUnitElements(CompilationUnitElementImpl resynthesized,
+      CompilationUnitElementImpl original) {
+    String desc = 'Compilation unit ${original.source.uri}';
+    compareUriReferencedElements(resynthesized, original, desc);
+    expect(resynthesized.source, original.source);
+    expect(resynthesized.librarySource, original.librarySource);
+    expect(resynthesized.types.length, original.types.length);
+    for (int i = 0; i < resynthesized.types.length; i++) {
+      compareClassElements(
+          resynthesized.types[i], original.types[i], original.types[i].name);
+    }
+    expect(resynthesized.topLevelVariables.length,
+        original.topLevelVariables.length);
+    for (int i = 0; i < resynthesized.topLevelVariables.length; i++) {
+      compareTopLevelVariableElements(
+          resynthesized.topLevelVariables[i],
+          original.topLevelVariables[i],
+          'variable ${original.topLevelVariables[i].name}');
+    }
+    expect(resynthesized.functions.length, original.functions.length);
+    for (int i = 0; i < resynthesized.functions.length; i++) {
+      compareFunctionElements(resynthesized.functions[i], original.functions[i],
+          'function ${original.functions[i].name}');
+    }
+    expect(resynthesized.functionTypeAliases.length,
+        original.functionTypeAliases.length);
+    for (int i = 0; i < resynthesized.functionTypeAliases.length; i++) {
+      compareFunctionTypeAliasElements(
+          resynthesized.functionTypeAliases[i],
+          original.functionTypeAliases[i],
+          original.functionTypeAliases[i].name);
+    }
+    expect(resynthesized.enums.length, original.enums.length);
+    for (int i = 0; i < resynthesized.enums.length; i++) {
+      compareClassElements(
+          resynthesized.enums[i], original.enums[i], original.enums[i].name);
+    }
+    expect(resynthesized.accessors.length, original.accessors.length);
+    for (int i = 0; i < resynthesized.accessors.length; i++) {
+      if (original.accessors[i].isGetter) {
+        comparePropertyAccessorElements(resynthesized.accessors[i],
+            original.accessors[i], 'getter ${original.accessors[i].name}');
+      } else {
+        comparePropertyAccessorElements(resynthesized.accessors[i],
+            original.accessors[i], 'setter ${original.accessors[i].name}');
+      }
+    }
+    // TODO(paulberry): test metadata and offsetToElementMap.
+  }
+
+  void compareConstructorElements(ConstructorElementImpl resynthesized,
+      ConstructorElementImpl original, String desc) {
+    compareExecutableElements(resynthesized, original, desc);
+    // TODO(paulberry): test redirectedConstructor and constantInitializers
+  }
+
+  void compareElements(
+      ElementImpl resynthesized, ElementImpl original, String desc) {
+    expect(resynthesized, isNotNull);
+    expect(resynthesized.kind, original.kind);
+    expect(resynthesized.location, original.location, reason: desc);
+    expect(resynthesized.name, original.name);
+    expect(resynthesized.nameOffset, original.nameOffset, reason: desc);
+    expect(resynthesized.documentationComment, original.documentationComment,
+        reason: desc);
+    expect(resynthesized.docRange, original.docRange, reason: desc);
+    for (Modifier modifier in Modifier.values) {
+      if (modifier == Modifier.MIXIN) {
+        // Skipping for now.  TODO(paulberry): fix.
+        continue;
+      }
+      bool got = resynthesized.hasModifier(modifier);
+      bool want = original.hasModifier(modifier);
+      expect(got, want,
+          reason: 'Mismatch in $desc.$modifier: got $got, want $want');
+    }
+  }
+
+  void compareExecutableElements(ExecutableElementImpl resynthesized,
+      ExecutableElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    expect(resynthesized.parameters.length, original.parameters.length);
+    for (int i = 0; i < resynthesized.parameters.length; i++) {
+      compareParameterElements(
+          resynthesized.parameters[i],
+          original.parameters[i],
+          '$desc parameter ${original.parameters[i].name}');
+    }
+    compareTypes(
+        resynthesized.returnType, original.returnType, '$desc return type');
+    compareTypes(resynthesized.type, original.type, desc);
+  }
+
+  void compareExportElements(ExportElementImpl resynthesized,
+      ExportElementImpl original, String desc) {
+    compareUriReferencedElements(resynthesized, original, desc);
+    expect(resynthesized.exportedLibrary.location,
+        original.exportedLibrary.location);
+    expect(resynthesized.combinators.length, original.combinators.length);
+    for (int i = 0; i < resynthesized.combinators.length; i++) {
+      compareNamespaceCombinators(
+          resynthesized.combinators[i], original.combinators[i]);
+    }
+  }
+
+  void compareFieldElements(
+      FieldElementImpl resynthesized, FieldElementImpl original, String desc) {
+    comparePropertyInducingElements(resynthesized, original, desc);
+    // TODO(paulberry): test evaluationResult
+  }
+
+  void compareFunctionElements(FunctionElementImpl resynthesized,
+      FunctionElementImpl original, String desc) {
+    compareExecutableElements(resynthesized, original, desc);
+  }
+
+  void compareFunctionTypeAliasElements(
+      FunctionTypeAliasElementImpl resynthesized,
+      FunctionTypeAliasElementImpl original,
+      String desc) {
+    compareElements(resynthesized, original, desc);
+    expect(resynthesized.parameters.length, original.parameters.length);
+    for (int i = 0; i < resynthesized.parameters.length; i++) {
+      compareParameterElements(
+          resynthesized.parameters[i],
+          original.parameters[i],
+          '$desc parameter ${original.parameters[i].name}');
+    }
+    compareTypes(
+        resynthesized.returnType, original.returnType, '$desc return type');
+    compareTypes(resynthesized.type, original.type, desc);
+    expect(resynthesized.typeParameters.length, original.typeParameters.length);
+    for (int i = 0; i < resynthesized.typeParameters.length; i++) {
+      compareTypeParameterElements(
+          resynthesized.typeParameters[i],
+          original.typeParameters[i],
+          '$desc type parameter ${original.typeParameters[i].name}');
+    }
+  }
+
+  void compareImportElements(ImportElementImpl resynthesized,
+      ImportElementImpl original, String desc) {
+    compareUriReferencedElements(resynthesized, original, desc);
+    expect(resynthesized.importedLibrary.location,
+        original.importedLibrary.location);
+    if (original.prefix == null) {
+      expect(resynthesized.prefix, isNull);
+    } else {
+      comparePrefixElements(
+          resynthesized.prefix, original.prefix, original.prefix.name);
+    }
+    expect(resynthesized.combinators.length, original.combinators.length);
+    for (int i = 0; i < resynthesized.combinators.length; i++) {
+      compareNamespaceCombinators(
+          resynthesized.combinators[i], original.combinators[i]);
+    }
+  }
+
+  void compareMethodElements(MethodElementImpl resynthesized,
+      MethodElementImpl original, String desc) {
+    // TODO(paulberry): do we need to deal with
+    // MultiplyInheritedMethodElementImpl?
+    // TODO(paulberry): compare type parameters for generic methods.
+    compareExecutableElements(resynthesized, original, desc);
+  }
+
+  void compareNamespaceCombinators(
+      NamespaceCombinator resynthesized, NamespaceCombinator original) {
+    if (original is ShowElementCombinatorImpl &&
+        resynthesized is ShowElementCombinatorImpl) {
+      expect(resynthesized.shownNames, original.shownNames);
+    } else if (original is HideElementCombinatorImpl &&
+        resynthesized is HideElementCombinatorImpl) {
+      expect(resynthesized.hiddenNames, original.hiddenNames);
+    } else if (resynthesized.runtimeType != original.runtimeType) {
+      fail(
+          'Type mismatch: expected ${original.runtimeType}, got ${resynthesized.runtimeType}');
+    } else {
+      fail('Unimplemented comparison for ${original.runtimeType}');
+    }
+  }
+
+  void compareNamespaces(
+      Namespace resynthesized, Namespace original, String desc) {
+    Map<String, Element> resynthesizedMap = resynthesized.definedNames;
+    Map<String, Element> originalMap = original.definedNames;
+    expect(resynthesizedMap.keys.toSet(), originalMap.keys.toSet(),
+        reason: desc);
+    for (String key in originalMap.keys) {
+      Element resynthesizedElement = resynthesizedMap[key];
+      Element originalElement = originalMap[key];
+      compareElements(resynthesizedElement, originalElement, key);
+    }
+  }
+
+  void compareParameterElements(ParameterElementImpl resynthesized,
+      ParameterElementImpl original, String desc) {
+    compareVariableElements(resynthesized, original, desc);
+    expect(resynthesized.parameters.length, original.parameters.length);
+    for (int i = 0; i < resynthesized.parameters.length; i++) {
+      compareParameterElements(
+          resynthesized.parameters[i],
+          original.parameters[i],
+          '$desc parameter ${original.parameters[i].name}');
+    }
+    expect(resynthesized.parameterKind, original.parameterKind);
+  }
+
+  void comparePrefixElements(PrefixElementImpl resynthesized,
+      PrefixElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    // TODO(paulberry): test _importedLibraries.
+  }
+
+  void comparePropertyAccessorElements(
+      PropertyAccessorElementImpl resynthesized,
+      PropertyAccessorElementImpl original,
+      String desc) {
+    // TODO(paulberry): do I need to worry about
+    // MultiplyInheritedPropertyAccessorElementImpl?
+    compareExecutableElements(resynthesized, original, desc);
+    expect(resynthesized.variable, isNotNull);
+    expect(resynthesized.variable.location, original.variable.location);
+  }
+
+  void comparePropertyInducingElements(
+      PropertyInducingElementImpl resynthesized,
+      PropertyInducingElementImpl original,
+      String desc) {
+    compareVariableElements(resynthesized, original, desc);
+    if (original.getter == null) {
+      expect(resynthesized.getter, isNull);
+    } else {
+      expect(resynthesized.getter, isNotNull);
+      expect(resynthesized.getter.location, original.getter.location);
+    }
+    if (original.setter == null) {
+      expect(resynthesized.setter, isNull);
+    } else {
+      expect(resynthesized.setter, isNotNull);
+      expect(resynthesized.setter.location, original.setter.location);
+    }
+  }
+
+  void compareTopLevelVariableElements(
+      TopLevelVariableElementImpl resynthesized,
+      TopLevelVariableElementImpl original,
+      String desc) {
+    comparePropertyInducingElements(resynthesized, original, desc);
+    // TODO(paulberry): test evaluationResult
+  }
+
+  void compareTypeImpls(
+      TypeImpl resynthesized, TypeImpl original, String desc) {
+    expect(resynthesized.element.location, original.element.location,
+        reason: desc);
+    expect(resynthesized.name, original.name, reason: desc);
+  }
+
+  void compareTypeParameterElements(TypeParameterElementImpl resynthesized,
+      TypeParameterElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    compareTypes(resynthesized.type, original.type, desc);
+    compareTypes(resynthesized.bound, original.bound, '$desc bound');
+  }
+
+  void compareTypes(DartType resynthesized, DartType original, String desc) {
+    if (original == null) {
+      expect(resynthesized, isNull, reason: desc);
+    } else if (resynthesized is InterfaceTypeImpl &&
+        original is InterfaceTypeImpl) {
+      compareTypeImpls(resynthesized, original, desc);
+      expect(resynthesized.typeArguments.length, original.typeArguments.length);
+      for (int i = 0; i < resynthesized.typeArguments.length; i++) {
+        compareTypes(resynthesized.typeArguments[i], original.typeArguments[i],
+            '$desc type argument ${original.typeArguments[i].name}');
+      }
+    } else if (resynthesized is TypeParameterTypeImpl &&
+        original is TypeParameterTypeImpl) {
+      compareTypeImpls(resynthesized, original, desc);
+    } else if (resynthesized is DynamicTypeImpl &&
+        original is DynamicTypeImpl) {
+      expect(resynthesized, same(original));
+    } else if (resynthesized is UndefinedTypeImpl &&
+        original is UndefinedTypeImpl) {
+      expect(resynthesized, same(original));
+    } else if (resynthesized is FunctionTypeImpl &&
+        original is FunctionTypeImpl) {
+      compareTypeImpls(resynthesized, original, desc);
+      expect(resynthesized.isInstantiated, original.isInstantiated,
+          reason: desc);
+      if (original.element.isSynthetic &&
+          original.element is FunctionTypeAliasElementImpl &&
+          resynthesized.element is FunctionTypeAliasElementImpl) {
+        compareFunctionTypeAliasElements(
+            resynthesized.element, original.element, desc);
+      }
+      expect(resynthesized.typeArguments.length, original.typeArguments.length,
+          reason: desc);
+      for (int i = 0; i < resynthesized.typeArguments.length; i++) {
+        compareTypes(resynthesized.typeArguments[i], original.typeArguments[i],
+            '$desc type argument ${original.typeArguments[i].name}');
+      }
+      if (original.typeParameters == null) {
+        expect(resynthesized.typeParameters, isNull, reason: desc);
+      } else {
+        expect(resynthesized.typeParameters, isNotNull, reason: desc);
+        expect(
+            resynthesized.typeParameters.length, original.typeParameters.length,
+            reason: desc);
+        for (int i = 0; i < resynthesized.typeParameters.length; i++) {
+          compareTypeParameterElements(resynthesized.typeParameters[i],
+              original.typeParameters[i], '$desc type parameter $i');
+        }
+      }
+      expect(resynthesized.typeFormals.length, original.typeFormals.length,
+          reason: desc);
+      for (int i = 0; i < resynthesized.typeFormals.length; i++) {
+        compareTypeParameterElements(resynthesized.typeFormals[i],
+            original.typeFormals[i], '$desc bound type parameter $i');
+      }
+    } else if (resynthesized is VoidTypeImpl && original is VoidTypeImpl) {
+      expect(resynthesized, same(original));
+    } else if (resynthesized.runtimeType != original.runtimeType) {
+      fail(
+          'Type mismatch: expected ${original.runtimeType}, got ${resynthesized.runtimeType}');
+    } else {
+      fail('Unimplemented comparison for ${original.runtimeType}');
+    }
+  }
+
+  void compareUriReferencedElements(UriReferencedElementImpl resynthesized,
+      UriReferencedElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    expect(resynthesized.uri, original.uri);
+    expect(resynthesized.uriOffset, original.uriOffset, reason: desc);
+    expect(resynthesized.uriEnd, original.uriEnd, reason: desc);
+  }
+
+  void compareVariableElements(VariableElementImpl resynthesized,
+      VariableElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    compareTypes(resynthesized.type, original.type, desc);
+    // TODO(paulberry): test initializer
+  }
+
+  fail_library_hasExtUri() {
+    checkLibrary('import "dart-ext:doesNotExist.dart";');
+  }
+
+  LibraryElementImpl resynthesizeLibrary(
+      Source source, LibraryElementImpl original, bool allowErrors,
+      {int resynthesisCount: 1}) {
+    if (!allowErrors) {
+      assertNoErrors(source);
+    }
+    String uri = source.uri.toString();
+    addLibrary('dart:core');
+    return resynthesizeLibraryElement(uri, original,
+        resynthesisCount: resynthesisCount);
+  }
+
+  LibraryElementImpl resynthesizeLibraryElement(
+      String uri, LibraryElementImpl original,
+      {int resynthesisCount: 1}) {
+    Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
+    PrelinkedLibrary getPrelinkedSummaryFor(LibraryElement lib) {
+      LibrarySerializationResult serialized =
+          serializeLibrary(lib, typeProvider);
+      for (int i = 0; i < serialized.unlinkedUnits.length; i++) {
+        unlinkedSummaries[serialized.unitUris[i]] =
+            new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer());
+      }
+      return new PrelinkedLibrary.fromBuffer(serialized.prelinked.toBuffer());
+    }
+    Map<String, PrelinkedLibrary> prelinkedSummaries =
+        <String, PrelinkedLibrary>{uri: getPrelinkedSummaryFor(original)};
+    for (Source source in otherLibrarySources) {
+      LibraryElement original = resolve2(source);
+      String uri = source.uri.toString();
+      prelinkedSummaries[uri] = getPrelinkedSummaryFor(original);
+    }
+    PrelinkedLibrary getPrelinkedSummary(String uri) {
+      PrelinkedLibrary serializedLibrary = prelinkedSummaries[uri];
+      if (serializedLibrary == null) {
+        fail('Unexpectedly tried to get prelinked summary for $uri');
+      }
+      return serializedLibrary;
+    }
+    UnlinkedUnit getUnlinkedSummary(String uri) {
+      UnlinkedUnit serializedUnit = unlinkedSummaries[uri];
+      if (serializedUnit == null) {
+        fail('Unexpectedly tried to get unlinked summary for $uri');
+      }
+      return serializedUnit;
+    }
+    SummaryResynthesizer resynthesizer = new SummaryResynthesizer(
+        analysisContext,
+        analysisContext.typeProvider,
+        getPrelinkedSummary,
+        getUnlinkedSummary,
+        analysisContext.sourceFactory);
+    LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri);
+    // Check that no other summaries needed to be resynthesized to resynthesize
+    // the library element.
+    // TODO(paulberry): once export namespaces are resynthesized from
+    // prelinked data, resynthesisCount should be hardcoded to 1.
+    expect(resynthesizer.resynthesisCount, resynthesisCount);
+    return resynthesized;
+  }
+
+  test_class_alias() {
+    checkLibrary('class C = D with E, F; class D {} class E {} class F {}');
+  }
+
+  test_class_alias_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C = D with E;
+
+class D {}
+class E {}''');
+  }
+
+  test_class_alias_with_forwarding_constructors() {
+    addLibrarySource(
+        '/a.dart',
+        '''
+class Base {
+  Base._priv();
+  Base();
+  Base.noArgs();
+  Base.requiredArg(x);
+  Base.positionalArg([x]);
+  Base.namedArg({x});
+  factory Base.fact() => null;
+  factory Base.fact2() = Base.noArgs;
+}
+''');
+    checkLibrary('''
+import "a.dart";
+class M {}
+class MixinApp = Base with M;
+''');
+  }
+
+  test_class_alias_with_forwarding_constructors_type_substitution() {
+    checkLibrary('''
+class Base<T> {
+  Base.ctor(T t, List<T> l);
+}
+class M {}
+class MixinApp = Base with M;
+''');
+  }
+
+  test_class_alias_with_forwarding_constructors_type_substitution_complex() {
+    checkLibrary('''
+class Base<T> {
+  Base.ctor(T t, List<T> l);
+}
+class M {}
+class MixinApp<U> = Base<List<U>> with M;
+''');
+  }
+
+  test_class_alias_with_mixin_members() {
+    checkLibrary('''
+class C = D with E;
+class D {}
+class E {
+  int get a => null;
+  void set b(int i) {}
+  void f() {}
+  int x;
+}''');
+  }
+
+  test_class_constructor_const() {
+    checkLibrary('class C { const C(); }');
+  }
+
+  test_class_constructor_const_external() {
+    checkLibrary('class C { external const C(); }');
+  }
+
+  test_class_constructor_explicit_named() {
+    checkLibrary('class C { C.foo(); }');
+  }
+
+  test_class_constructor_explicit_type_params() {
+    checkLibrary('class C<T, U> { C(); }');
+  }
+
+  test_class_constructor_explicit_unnamed() {
+    checkLibrary('class C { C(); }');
+  }
+
+  test_class_constructor_external() {
+    checkLibrary('class C { external C(); }');
+  }
+
+  test_class_constructor_factory() {
+    checkLibrary('class C { factory C() => null; }');
+  }
+
+  test_class_constructor_field_formal_dynamic_dynamic() {
+    checkLibrary('class C { dynamic x; C(dynamic this.x); }');
+  }
+
+  test_class_constructor_field_formal_dynamic_typed() {
+    checkLibrary('class C { dynamic x; C(int this.x); }');
+  }
+
+  test_class_constructor_field_formal_dynamic_untyped() {
+    checkLibrary('class C { dynamic x; C(this.x); }');
+  }
+
+  test_class_constructor_field_formal_typed_dynamic() {
+    checkLibrary('class C { num x; C(dynamic this.x); }');
+  }
+
+  test_class_constructor_field_formal_typed_typed() {
+    checkLibrary('class C { num x; C(int this.x); }');
+  }
+
+  test_class_constructor_field_formal_typed_untyped() {
+    checkLibrary('class C { num x; C(this.x); }');
+  }
+
+  test_class_constructor_field_formal_untyped_dynamic() {
+    checkLibrary('class C { var x; C(dynamic this.x); }');
+  }
+
+  test_class_constructor_field_formal_untyped_typed() {
+    checkLibrary('class C { var x; C(int this.x); }');
+  }
+
+  test_class_constructor_field_formal_untyped_untyped() {
+    checkLibrary('class C { var x; C(this.x); }');
+  }
+
+  test_class_constructor_implicit() {
+    checkLibrary('class C {}');
+  }
+
+  test_class_constructor_implicit_type_params() {
+    checkLibrary('class C<T, U> {}');
+  }
+
+  test_class_constructor_params() {
+    checkLibrary('class C { C(x, y); }');
+  }
+
+  test_class_constructors() {
+    checkLibrary('class C { C.foo(); C.bar(); }');
+  }
+
+  test_class_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C {}''');
+  }
+
+  test_class_documented_with_references() {
+    checkLibrary('''
+/**
+ * Docs referring to [D] and [E]
+ */
+class C {}
+
+class D {}
+class E {}''');
+  }
+
+  test_class_documented_with_windows_line_endings() {
+    checkLibrary('/**\r\n * Docs\r\n */\r\nclass C {}');
+  }
+
+  test_class_field_const() {
+    checkLibrary('class C { static const int i = 0; }');
+  }
+
+  test_class_field_implicit_type() {
+    checkLibrary('class C { var x; }');
+  }
+
+  test_class_field_static() {
+    checkLibrary('class C { static int i; }');
+  }
+
+  test_class_fields() {
+    checkLibrary('class C { int i; int j; }');
+  }
+
+  test_class_getter_external() {
+    checkLibrary('class C { external int get x; }');
+  }
+
+  test_class_getter_implicit_return_type() {
+    checkLibrary('class C { get x => null; }');
+  }
+
+  test_class_getter_static() {
+    checkLibrary('class C { static int get x => null; }');
+  }
+
+  test_class_getters() {
+    checkLibrary('class C { int get x => null; get y => null; }');
+  }
+
+  test_class_implicitField_getterFirst() {
+    checkLibrary('class C { int get x => 0; void set x(int value) {} }');
+  }
+
+  test_class_implicitField_setterFirst() {
+    checkLibrary('class C { void set x(int value) {} int get x => 0; }');
+  }
+
+  test_class_interfaces() {
+    checkLibrary('class C implements D, E {} class D {} class E {}');
+  }
+
+  test_class_method_external() {
+    checkLibrary('class C { external f(); }');
+  }
+
+  test_class_method_params() {
+    checkLibrary('class C { f(x, y) {} }');
+  }
+
+  test_class_method_static() {
+    checkLibrary('class C { static f() {} }');
+  }
+
+  test_class_methods() {
+    checkLibrary('class C { f() {} g() {} }');
+  }
+
+  test_class_mixins() {
+    checkLibrary('class C extends Object with D, E {} class D {} class E {}');
+  }
+
+  test_class_setter_external() {
+    checkLibrary('class C { external void set x(int value); }');
+  }
+
+  test_class_setter_implicit_param_type() {
+    checkLibrary('class C { void set x(value) {} }');
+  }
+
+  test_class_setter_implicit_return_type() {
+    checkLibrary('class C { set x(int value) {} }');
+  }
+
+  test_class_setter_static() {
+    checkLibrary('class C { static void set x(int value) {} }');
+  }
+
+  test_class_setters() {
+    checkLibrary('class C { void set x(int value) {} set y(value) {} }');
+  }
+
+  test_class_supertype() {
+    checkLibrary('class C extends D {} class D {}');
+  }
+
+  test_class_type_parameters() {
+    checkLibrary('class C<T, U> {}');
+  }
+
+  test_class_type_parameters_bound() {
+    checkLibrary('class C<T extends Object, U extends D> {} class D {}');
+  }
+
+  test_class_type_parameters_f_bound_complex() {
+    checkLibrary('class C<T extends List<U>, U> {}');
+  }
+
+  test_class_type_parameters_f_bound_simple() {
+    checkLibrary('class C<T extends U, U> {}');
+  }
+
+  test_classes() {
+    checkLibrary('class C {} class D {}');
+  }
+
+  test_constructor_documented() {
+    checkLibrary('''
+class C {
+  /**
+   * Docs
+   */
+  C();
+}''');
+  }
+
+  test_core() {
+    String uri = 'dart:core';
+    LibraryElementImpl original =
+        resolve2(analysisContext2.sourceFactory.forUri(uri));
+    LibraryElementImpl resynthesized =
+        resynthesizeLibraryElement(uri, original);
+    checkLibraryElements(original, resynthesized);
+  }
+
+  test_enum_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+enum E { v }''');
+  }
+
+  test_enum_value_documented() {
+    checkLibrary('''
+enum E {
+  /**
+   * Docs
+   */
+  v
+}''');
+  }
+
+  test_enum_values() {
+    checkLibrary('enum E { v1, v2 }');
+  }
+
+  test_enums() {
+    checkLibrary('enum E1 { v1 } enum E2 { v2 }');
+  }
+
+  test_export_hide() {
+    addLibrary('dart:async');
+    checkLibrary('export "dart:async" hide Stream, Future;',
+        resynthesisCount: 2);
+  }
+
+  test_export_multiple_combinators() {
+    addLibrary('dart:async');
+    checkLibrary('export "dart:async" hide Stream show Future;',
+        resynthesisCount: 2);
+  }
+
+  test_export_show() {
+    addLibrary('dart:async');
+    checkLibrary('export "dart:async" show Future, Stream;',
+        resynthesisCount: 2);
+  }
+
+  test_exports() {
+    addLibrarySource('/a.dart', 'library a;');
+    addLibrarySource('/b.dart', 'library b;');
+    checkLibrary('export "a.dart"; export "b.dart";', resynthesisCount: 3);
+  }
+
+  test_field_documented() {
+    checkLibrary('''
+class C {
+  /**
+   * Docs
+   */
+  var x;
+}''');
+  }
+
+  test_function_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+f() {}''');
+  }
+
+  test_function_entry_point() {
+    checkLibrary('main() {}');
+  }
+
+  test_function_entry_point_in_export() {
+    addLibrarySource('/a.dart', 'library a; main() {}');
+    checkLibrary('export "a.dart";', resynthesisCount: 2);
+  }
+
+  test_function_entry_point_in_export_hidden() {
+    addLibrarySource('/a.dart', 'library a; main() {}');
+    checkLibrary('export "a.dart" hide main;', resynthesisCount: 2);
+  }
+
+  test_function_entry_point_in_part() {
+    addNamedSource('/a.dart', 'part of my.lib; main() {}');
+    checkLibrary('library my.lib; part "a.dart";');
+  }
+
+  test_function_external() {
+    checkLibrary('external f();');
+  }
+
+  test_function_parameter_kind_named() {
+    // TODO(paulberry): also test default value.
+    checkLibrary('f({x}) {}');
+  }
+
+  test_function_parameter_kind_positional() {
+    // TODO(paulberry): also test default value.
+    checkLibrary('f([x]) {}');
+  }
+
+  test_function_parameter_kind_required() {
+    checkLibrary('f(x) {}');
+  }
+
+  test_function_parameter_parameters() {
+    checkLibrary('f(g(x, y)) {}');
+  }
+
+  test_function_parameter_return_type() {
+    checkLibrary('f(int g()) {}');
+  }
+
+  test_function_parameter_return_type_void() {
+    checkLibrary('f(void g()) {}');
+  }
+
+  test_function_parameter_type() {
+    checkLibrary('f(int i) {}');
+  }
+
+  test_function_parameters() {
+    checkLibrary('f(x, y) {}');
+  }
+
+  test_function_return_type() {
+    checkLibrary('int f() => null;');
+  }
+
+  test_function_return_type_implicit() {
+    checkLibrary('f() => null;');
+  }
+
+  test_function_return_type_void() {
+    checkLibrary('void f() {}');
+  }
+
+  test_function_type_parameter() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('T f<T, U>(U u) => null;');
+  }
+
+  test_function_type_parameter_with_function_typed_parameter() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('void f<T, U>(T x(U u)) {}');
+  }
+
+  test_functions() {
+    checkLibrary('f() {} g() {}');
+  }
+
+  test_getter_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+get x => null;''');
+  }
+
+  test_getter_external() {
+    checkLibrary('external int get x;');
+  }
+
+  test_getters() {
+    checkLibrary('int get x => null; get y => null;');
+  }
+
+  test_implicitTopLevelVariable_getterFirst() {
+    checkLibrary('int get x => 0; void set x(int value) {}');
+  }
+
+  test_implicitTopLevelVariable_setterFirst() {
+    checkLibrary('void set x(int value) {} int get x => 0;');
+  }
+
+  test_import_hide() {
+    addLibrary('dart:async');
+    checkLibrary('import "dart:async" hide Stream, Completer; Future f;');
+  }
+
+  test_import_multiple_combinators() {
+    addLibrary('dart:async');
+    checkLibrary('import "dart:async" hide Stream show Future; Future f;');
+  }
+
+  test_import_prefixed() {
+    addLibrarySource('/a.dart', 'library a; class C {}');
+    checkLibrary('import "a.dart" as a; a.C c;');
+  }
+
+  test_import_show() {
+    addLibrary('dart:async');
+    checkLibrary('import "dart:async" show Future, Stream; Future f;');
+  }
+
+  test_imports() {
+    addLibrarySource('/a.dart', 'library a; class C {}');
+    addLibrarySource('/b.dart', 'library b; class D {}');
+    checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
+  }
+
+  test_library() {
+    checkLibrary('');
+  }
+
+  test_library_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+library foo;''');
+  }
+
+  test_library_name_with_spaces() {
+    checkLibrary('library foo . bar ;');
+  }
+
+  test_library_named() {
+    checkLibrary('library foo.bar;');
+  }
+
+  test_method_documented() {
+    checkLibrary('''
+class C {
+  /**
+   * Docs
+   */
+  f() {}
+}''');
+  }
+
+  test_method_parameter_parameters() {
+    checkLibrary('class C { f(g(x, y)) {} }');
+  }
+
+  test_method_parameter_parameters_in_generic_class() {
+    checkLibrary('class C<A, B> { f(A g(B x)) {} }');
+  }
+
+  test_method_parameter_return_type() {
+    checkLibrary('class C { f(int g()) {} }');
+  }
+
+  test_method_parameter_return_type_void() {
+    checkLibrary('class C { f(void g()) {} }');
+  }
+
+  test_method_type_parameter() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('class C { T f<T, U>(U u) => null; }');
+  }
+
+  test_method_type_parameter_in_generic_class() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('class C<T, U> { V f<V, W>(T t, U u, W w) => null; }');
+  }
+
+  test_method_type_parameter_with_function_typed_parameter() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
+    checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
+  }
+
+  test_operator() {
+    checkLibrary('class C { C operator+(C other) => null; }');
+  }
+
+  test_operator_equal() {
+    checkLibrary('class C { bool operator==(C other) => false; }');
+  }
+
+  test_operator_external() {
+    checkLibrary('class C { external C operator+(C other); }');
+  }
+
+  test_operator_greater_equal() {
+    checkLibrary('class C { bool operator>=(C other) => false; }');
+  }
+
+  test_operator_index() {
+    checkLibrary('class C { bool operator[](int i) => null; }');
+  }
+
+  test_operator_index_set() {
+    checkLibrary('class C { void operator[]=(int i, bool v) {} }');
+  }
+
+  test_operator_less_equal() {
+    checkLibrary('class C { bool operator<=(C other) => false; }');
+  }
+
+  test_parts() {
+    addNamedSource('/a.dart', 'part of my.lib;');
+    addNamedSource('/b.dart', 'part of my.lib;');
+    checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
+  }
+
+  test_setter_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+void set x(value) {}''');
+  }
+
+  test_setter_external() {
+    checkLibrary('external void set x(int value);');
+  }
+
+  test_setters() {
+    checkLibrary('void set x(int value) {} set y(value) {}');
+  }
+
+  test_type_arguments_explicit() {
+    checkLibrary('Map<String, int> m;');
+  }
+
+  test_type_arguments_implicit() {
+    checkLibrary('Map m;');
+  }
+
+  test_type_dynamic() {
+    checkLibrary('dynamic d;');
+  }
+
+  test_type_reference_lib_to_lib() {
+    checkLibrary('class C {} enum E { v } typedef F(); C c; E e; F f;');
+  }
+
+  test_type_reference_lib_to_part() {
+    addNamedSource(
+        '/a.dart', 'part of l; class C {} enum E { v } typedef F();');
+    checkLibrary('library l; part "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_part_to_lib() {
+    addNamedSource('/a.dart', 'part of l; C c; E e; F f;');
+    checkLibrary(
+        'library l; part "a.dart"; class C {} enum E { v } typedef F();');
+  }
+
+  test_type_reference_part_to_other_part() {
+    addNamedSource(
+        '/a.dart', 'part of l; class C {} enum E { v } typedef F();');
+    addNamedSource('/b.dart', 'part of l; C c; E e; F f;');
+    checkLibrary('library l; part "a.dart"; part "b.dart";');
+  }
+
+  test_type_reference_part_to_part() {
+    addNamedSource('/a.dart',
+        'part of l; class C {} enum E { v } typedef F(); C c; E e; F f;');
+    checkLibrary('library l; part "a.dart";');
+  }
+
+  test_type_reference_to_class() {
+    checkLibrary('class C {} C c;');
+  }
+
+  test_type_reference_to_class_with_type_arguments() {
+    checkLibrary('class C<T, U> {} C<int, String> c;');
+  }
+
+  test_type_reference_to_class_with_type_arguments_implicit() {
+    checkLibrary('class C<T, U> {} C c;');
+  }
+
+  test_type_reference_to_enum() {
+    checkLibrary('enum E { v } E e;');
+  }
+
+  test_type_reference_to_import() {
+    addLibrarySource('/a.dart', 'class C {} enum E { v }; typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_export() {
+    addLibrarySource('/a.dart', 'export "b.dart";');
+    addLibrarySource('/b.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_export_export() {
+    addLibrarySource('/a.dart', 'export "b.dart";');
+    addLibrarySource('/b.dart', 'export "c.dart";');
+    addLibrarySource('/c.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_export_export_in_subdirs() {
+    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
+    addLibrarySource('/a/b/b.dart', 'export "../c/c.dart";');
+    addLibrarySource('/a/c/c.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a/a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_export_in_subdirs() {
+    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
+    addLibrarySource('/a/b/b.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a/a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_part() {
+    addLibrarySource('/a.dart', 'library l; part "b.dart";');
+    addNamedSource(
+        '/b.dart', 'part of l; class C {} enum E { v } typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_part2() {
+    addLibrarySource('/a.dart', 'library l; part "p1.dart"; part "p2.dart";');
+    addNamedSource('/p1.dart', 'part of l; class C1 {}');
+    addNamedSource('/p2.dart', 'part of l; class C2 {}');
+    checkLibrary('import "a.dart"; C1 c1; C2 c2;');
+  }
+
+  test_type_reference_to_import_part_in_subdir() {
+    addLibrarySource('/a/b.dart', 'library l; part "c.dart";');
+    addNamedSource(
+        '/a/c.dart', 'part of l; class C {} enum E { v } typedef F();');
+    checkLibrary('import "a/b.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_relative() {
+    addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_typedef() {
+    checkLibrary('typedef F(); F f;');
+  }
+
+  test_type_reference_to_typedef_with_type_arguments() {
+    checkLibrary('typedef U F<T, U>(T t); F<int, String> f;');
+  }
+
+  test_type_reference_to_typedef_with_type_arguments_implicit() {
+    checkLibrary('typedef U F<T, U>(T t); F f;');
+  }
+
+  test_type_unresolved() {
+    checkLibrary('C c;', allowErrors: true);
+  }
+
+  test_type_unresolved_prefixed() {
+    checkLibrary('import "dart:core" as core; core.C c;', allowErrors: true);
+  }
+
+  test_typedef_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+typedef F();''');
+  }
+
+  test_typedef_parameter_parameters() {
+    checkLibrary('typedef F(g(x, y));');
+  }
+
+  test_typedef_parameter_parameters_in_generic_class() {
+    checkLibrary('typedef F<A, B>(A g(B x));');
+  }
+
+  test_typedef_parameter_return_type() {
+    checkLibrary('typedef F(int g());');
+  }
+
+  test_typedef_parameter_type() {
+    checkLibrary('typedef F(int i);');
+  }
+
+  test_typedef_parameter_type_generic() {
+    checkLibrary('typedef F<T>(T t);');
+  }
+
+  test_typedef_parameters() {
+    checkLibrary('typedef F(x, y);');
+  }
+
+  test_typedef_return_type() {
+    checkLibrary('typedef int F();');
+  }
+
+  test_typedef_return_type_generic() {
+    checkLibrary('typedef T F<T>();');
+  }
+
+  test_typedef_return_type_implicit() {
+    checkLibrary('typedef F();');
+  }
+
+  test_typedef_return_type_void() {
+    checkLibrary('typedef void F();');
+  }
+
+  test_typedef_type_parameters() {
+    checkLibrary('typedef U F<T, U>(T t);');
+  }
+
+  test_typedef_type_parameters_bound() {
+    checkLibrary('typedef U F<T extends Object, U extends D>(T t); class D {}');
+  }
+
+  test_typedef_type_parameters_f_bound_complex() {
+    checkLibrary('typedef U F<T extends List<U>, U>(T t);');
+  }
+
+  test_typedef_type_parameters_f_bound_simple() {
+    checkLibrary('typedef U F<T extends U, U>(T t);');
+  }
+
+  test_typedefs() {
+    checkLibrary('f() {} g() {}');
+  }
+
+  test_variable_const() {
+    checkLibrary('const int i = 0;');
+  }
+
+  test_variable_documented() {
+    checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+var x;''');
+  }
+
+  test_variable_implicit_type() {
+    checkLibrary('var x;');
+  }
+
+  test_variables() {
+    checkLibrary('int i; int j;');
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/summary_sdk_test.dart b/pkg/analyzer/test/src/summary/summary_sdk_test.dart
new file mode 100644
index 0000000..5ec807e
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/summary_sdk_test.dart
@@ -0,0 +1,260 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.src.summary.summary_sdk_test;
+
+import 'dart:io';
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, CacheState;
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/summary_sdk.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart' show AnalysisContextTarget;
+import 'package:analyzer/task/model.dart';
+import 'package:path/path.dart' as pathos;
+import 'package:unittest/unittest.dart';
+
+import '../../generated/test_support.dart';
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(SummarySdkAnalysisContextTest);
+}
+
+@reflectiveTest
+class SummarySdkAnalysisContextTest {
+  static String _analyzerPackagePath;
+  static bool _analyzerPackagePathInitialized = false;
+
+  static SdkBundle sdkBundle;
+
+  SummarySdkAnalysisContext context;
+
+  void setUp() {
+    _initializeSdkContext();
+  }
+
+  test_libraryResults() {
+    if (context == null) {
+      return;
+    }
+    // verify that there are at least some interesting libraries in the bundle
+    expect(sdkBundle.prelinkedLibraryUris, contains('dart:core'));
+    expect(sdkBundle.prelinkedLibraryUris, contains('dart:async'));
+    expect(sdkBundle.prelinkedLibraryUris, contains('dart:html'));
+    // verify every library
+    for (String uri in sdkBundle.prelinkedLibraryUris) {
+      // TODO(scheglov) breaks at _LibraryResynthesizer.buildImplicitTopLevelVariable
+      if (uri == 'dart:io' || uri == 'dart:_isolate_helper') {
+        continue;
+      }
+      _assertLibraryResults(uri);
+    }
+  }
+
+  test_sourceKind() {
+    if (context == null) {
+      return;
+    }
+    // libraries
+    _assertHasSourceKind('dart:core', SourceKind.LIBRARY);
+    _assertHasSourceKind('dart:async', SourceKind.LIBRARY);
+    _assertHasSourceKind('dart:math', SourceKind.LIBRARY);
+    // parts
+    _assertHasSourceKind('dart:core/bool.dart', SourceKind.PART);
+    _assertHasSourceKind('dart:async/future.dart', SourceKind.PART);
+    // unknown
+    _assertHasSourceKind('dart:no_such_library.dart', null);
+    _assertHasSourceKind('dart:core/no_such_part.dart', null);
+  }
+
+  test_typeProvider() {
+    if (context == null) {
+      return;
+    }
+    AnalysisContextTarget target = AnalysisContextTarget.request;
+    CacheEntry cacheEntry = context.getCacheEntry(target);
+    bool hasResult = context.aboutToComputeResult(cacheEntry, TYPE_PROVIDER);
+    expect(hasResult, isTrue);
+    expect(cacheEntry.getState(TYPE_PROVIDER), CacheState.VALID);
+    TypeProvider typeProvider = cacheEntry.getValue(TYPE_PROVIDER);
+    expect(typeProvider.objectType, isNotNull);
+    expect(typeProvider.boolType, isNotNull);
+    expect(typeProvider.intType, isNotNull);
+    expect(typeProvider.futureType, isNotNull);
+    expect(typeProvider.futureDynamicType, isNotNull);
+    expect(typeProvider.streamType, isNotNull);
+    expect(typeProvider.streamDynamicType, isNotNull);
+  }
+
+  void _assertHasLibraryElement(CacheEntry cacheEntry,
+      ResultDescriptor<LibraryElement> resultDescriptor) {
+    bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
+    expect(hasResult, isTrue);
+    expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
+    LibraryElement library = cacheEntry.getValue(resultDescriptor);
+    expect(library, isNotNull);
+  }
+
+  void _assertHasSourceKind(String uri, SourceKind expectedValue) {
+    Source target = context.sourceFactory.forUri(uri);
+    CacheEntry cacheEntry = context.getCacheEntry(target);
+    ResultDescriptor<SourceKind> resultDescriptor = SOURCE_KIND;
+    bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
+    if (expectedValue == null) {
+      expect(hasResult, isFalse);
+      expect(cacheEntry.getState(resultDescriptor), CacheState.INVALID);
+    } else {
+      expect(hasResult, isTrue);
+      expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
+      SourceKind value = cacheEntry.getValue(resultDescriptor);
+      expect(value, expectedValue);
+    }
+  }
+
+  void _assertIsLibraryElementReady(
+      CacheEntry cacheEntry, ResultDescriptor<bool> resultDescriptor) {
+    bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
+    expect(hasResult, isTrue);
+    expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
+    bool ready = cacheEntry.getValue(resultDescriptor);
+    expect(ready, isTrue);
+  }
+
+  void _assertLibraryResults(String uri) {
+    Source target = context.sourceFactory.forUri(uri);
+    CacheEntry cacheEntry = context.getCacheEntry(target);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT1);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT2);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT3);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT4);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT5);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT6);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT7);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT8);
+    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT);
+    _assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT2);
+    _assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT5);
+    _assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT6);
+  }
+
+  void _initializeSdkBundle() {
+    if (sdkBundle != null) {
+      return;
+    }
+    // prepare analyzer path
+    String analyzerPath = getAnalyzerPackagePath();
+    if (analyzerPath == null) {
+      return;
+    }
+    // prepare summary path
+    String sdkSummaryPath = pathos.join(
+        analyzerPath, 'test', 'src', 'summary', 'sdk_analysis_summary');
+    File file = new File(sdkSummaryPath);
+    if (!file.existsSync()) {
+      return;
+    }
+    // load SdkBundle
+    List<int> bytes = file.readAsBytesSync();
+    sdkBundle = new SdkBundle.fromBuffer(bytes);
+  }
+
+  void _initializeSdkContext() {
+    _initializeSdkBundle();
+    if (sdkBundle == null) {
+      return;
+    }
+    context = new _TestSummarySdkAnalysisContext(sdkBundle);
+    DartSdk sdk = new _TestSummaryDartSdk();
+    context.sourceFactory = new SourceFactory([new DartUriResolver(sdk)]);
+  }
+
+  static String getAnalyzerPackagePath() {
+    if (!_analyzerPackagePathInitialized) {
+      _analyzerPackagePathInitialized = true;
+      _analyzerPackagePath = _computeAnalyzerPackagePath();
+    }
+    return _analyzerPackagePath;
+  }
+
+  /**
+   * Return the path to the `analyzer` package root, or `null` if it cannot
+   * be determined.
+   *
+   * This method expects that one of the `analyzer` tests was run, so
+   * [Platform.script] is inside of the `analyzer/test` folder.
+   */
+  static String _computeAnalyzerPackagePath() {
+    Uri uri = Platform.script;
+    if (uri == null || uri.scheme != 'file') {
+      return null;
+    }
+    String path = pathos.fromUri(uri);
+    List<String> segments = pathos.split(path);
+    while (segments.length > 2) {
+      if (segments[segments.length - 1] == 'test' &&
+          segments[segments.length - 2] == 'analyzer') {
+        segments.removeLast();
+        return pathos.joinAll(segments);
+      }
+      segments.removeLast();
+    }
+    return null;
+  }
+}
+
+class _TestSummaryDartSdk implements DartSdk {
+  @override
+  Source mapDartUri(String uriStr) {
+    Uri uri = Uri.parse(uriStr);
+    List<String> segments = uri.pathSegments;
+    if (segments.length == 1) {
+      String libraryName = segments.first;
+      String path = '/sdk/$libraryName/$libraryName.dart';
+      return new _TestSummarySdkSource(path, uri);
+    } else {
+      String path = '/sdk/' + segments.join('/');
+      return new _TestSummarySdkSource(path, uri);
+    }
+  }
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
+ * [SummarySdkAnalysisContext] with simplified cache creation.
+ */
+class _TestSummarySdkAnalysisContext extends SummarySdkAnalysisContext {
+  _TestSummarySdkAnalysisContext(SdkBundle bundle) : super(bundle);
+
+  @override
+  AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
+    return new AnalysisCache(<CachePartition>[new SdkCachePartition(this)]);
+  }
+}
+
+class _TestSummarySdkSource extends TestSourceWithUri {
+  _TestSummarySdkSource(String path, Uri uri) : super(path, uri);
+
+  @override
+  bool get isInSystemLibrary => true;
+
+  @override
+  Uri resolveRelativeUri(Uri relativeUri) {
+    Uri baseUri = uri;
+    if (uri.scheme == 'dart') {
+      String libraryName = uri.path;
+      baseUri = Uri.parse('dart:$libraryName/$libraryName.dart');
+    }
+    return baseUri.resolveUri(relativeUri);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/summary_test.dart b/pkg/analyzer/test/src/summary/summary_test.dart
new file mode 100644
index 0000000..8b25e9d
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/summary_test.dart
@@ -0,0 +1,2966 @@
+// 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.test.src.summary.summary_test;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/summary/base.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/prelink.dart';
+import 'package:analyzer/src/summary/public_namespace_computer.dart'
+    as public_namespace;
+import 'package:analyzer/src/summary/summarize_elements.dart'
+    as summarize_elements;
+import 'package:unittest/unittest.dart';
+
+import '../../generated/resolver_test.dart';
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(SummarizeElementsTest);
+  runReflectiveTests(PrelinkerTest);
+}
+
+/**
+ * Convert a summary object (or a portion of one) into a canonical form that
+ * can be easily compared using [expect].  If [orderByName] is true, and the
+ * object is a [List], it is sorted by the `name` field of its elements.
+ */
+Object canonicalize(Object obj, {bool orderByName: false}) {
+  if (obj is SummaryClass) {
+    Map<String, Object> result = <String, Object>{};
+    obj.toMap().forEach((String key, Object value) {
+      bool orderByName = false;
+      if (obj is UnlinkedPublicNamespace && key == 'names') {
+        orderByName = true;
+      }
+      result[key] = canonicalize(value, orderByName: orderByName);
+    });
+    return result;
+  } else if (obj is List) {
+    List<Object> result = <Object>[];
+    for (Object item in obj) {
+      result.add(canonicalize(item));
+    }
+    if (orderByName) {
+      result.sort((Object a, Object b) {
+        if (a is Map && b is Map) {
+          return Comparable.compare(a['name'], b['name']);
+        } else {
+          return 0;
+        }
+      });
+    }
+    return result;
+  } else if (obj is String || obj is num || obj is bool) {
+    return obj;
+  } else {
+    return obj.toString();
+  }
+}
+
+UnlinkedPublicNamespace computePublicNamespaceFromText(
+    String text, Source source) {
+  CharacterReader reader = new CharSequenceReader(text);
+  Scanner scanner =
+      new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER);
+  Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
+  parser.parseGenericMethods = true;
+  CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
+  UnlinkedPublicNamespace namespace = new UnlinkedPublicNamespace.fromBuffer(
+      public_namespace.computePublicNamespace(unit).toBuffer());
+  return namespace;
+}
+
+/**
+ * Override of [SummaryTest] which verifies the correctness of the prelinker by
+ * creating summaries from the element model, discarding their prelinked
+ * information, and then recreating it using the prelinker.
+ */
+@reflectiveTest
+class PrelinkerTest extends SummarizeElementsTest {
+  /**
+   * The public namespaces of the sdk are computed once so that we don't bog
+   * down the test.  Structured as a map from absolute URI to the corresponding
+   * public namespace.
+   *
+   * Note: should an exception occur during computation of this variable, it
+   * will silently be set to null to allow other tests to run.
+   */
+  static final Map<String, UnlinkedPublicNamespace> sdkPublicNamespace = () {
+    try {
+      AnalysisContext analysisContext =
+          AnalysisContextFactory.contextWithCore();
+      Map<String, UnlinkedPublicNamespace> uriToNamespace =
+          <String, UnlinkedPublicNamespace>{};
+      List<LibraryElement> libraries = [
+        analysisContext.typeProvider.objectType.element.library,
+        analysisContext.typeProvider.futureType.element.library
+      ];
+      for (LibraryElement library in libraries) {
+        summarize_elements.LibrarySerializationResult serializedLibrary =
+            summarize_elements.serializeLibrary(
+                library, analysisContext.typeProvider);
+        for (int i = 0; i < serializedLibrary.unlinkedUnits.length; i++) {
+          uriToNamespace[
+              serializedLibrary.unitUris[i]] = new UnlinkedUnit.fromBuffer(
+              serializedLibrary.unlinkedUnits[i].toBuffer()).publicNamespace;
+        }
+      }
+      return uriToNamespace;
+    } catch (_) {
+      return null;
+    }
+  }();
+
+  final Map<String, UnlinkedPublicNamespace> uriToPublicNamespace =
+      <String, UnlinkedPublicNamespace>{};
+
+  @override
+  bool get expectAbsoluteUrisInDependencies => false;
+
+  @override
+  Source addNamedSource(String filePath, String contents) {
+    Source source = super.addNamedSource(filePath, contents);
+    uriToPublicNamespace[absUri(filePath)] =
+        computePublicNamespaceFromText(contents, source);
+    return source;
+  }
+
+  String resolveToAbsoluteUri(LibraryElement library, String relativeUri) {
+    Source resolvedSource =
+        analysisContext.sourceFactory.resolveUri(library.source, relativeUri);
+    if (resolvedSource == null) {
+      fail('Failed to resolve relative uri "$relativeUri"');
+    }
+    return resolvedSource.uri.toString();
+  }
+
+  @override
+  void serializeLibraryElement(LibraryElement library) {
+    super.serializeLibraryElement(library);
+    Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
+    expect(unlinkedUnits.length, unitUris.length);
+    for (int i = 1; i < unlinkedUnits.length; i++) {
+      uriToUnit[unitUris[i]] = unlinkedUnits[i];
+    }
+    UnlinkedUnit getPart(String relativeUri) {
+      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
+      UnlinkedUnit unit = uriToUnit[absoluteUri];
+      if (unit == null) {
+        fail('Prelinker unexpectedly requested unit for "$relativeUri"'
+            ' (resolves to "$absoluteUri").');
+      }
+      return unit;
+    }
+    UnlinkedPublicNamespace getImport(String relativeUri) {
+      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
+      UnlinkedPublicNamespace namespace = sdkPublicNamespace[absoluteUri];
+      if (namespace == null) {
+        namespace = uriToPublicNamespace[absoluteUri];
+      }
+      if (namespace == null && !allowMissingFiles) {
+        fail('Prelinker unexpectedly requested namespace for "$relativeUri"'
+            ' (resolves to "$absoluteUri").'
+            '  Namespaces available: ${uriToPublicNamespace.keys}');
+      }
+      return namespace;
+    }
+    prelinked = new PrelinkedLibrary.fromBuffer(
+        prelink(unlinkedUnits[0], getPart, getImport).toBuffer());
+  }
+}
+
+/**
+ * Override of [SummaryTest] which creates summaries from the element model.
+ */
+@reflectiveTest
+class SummarizeElementsTest extends ResolverTestCase with SummaryTest {
+  /**
+   * The list of absolute unit URIs corresponding to the compilation units in
+   * [unlinkedUnits].
+   */
+  List<String> unitUris;
+
+  /**
+   * Map containing all source files in this test, and their corresponding file
+   * contents.
+   */
+  final Map<Source, String> _fileContents = <Source, String>{};
+
+  @override
+  bool get checkAstDerivedData => false;
+
+  @override
+  bool get expectAbsoluteUrisInDependencies => true;
+
+  @override
+  Source addNamedSource(String filePath, String contents) {
+    Source source = super.addNamedSource(filePath, contents);
+    _fileContents[source] = contents;
+    return source;
+  }
+
+  /**
+   * Serialize the library containing the given class [element], then
+   * deserialize it and return the summary of the class.
+   */
+  UnlinkedClass serializeClassElement(ClassElement element) {
+    serializeLibraryElement(element.library);
+    return findClass(element.name, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given [library] element, then deserialize it and store the
+   * resulting summary in [prelinked] and [unlinkedUnits].
+   */
+  void serializeLibraryElement(LibraryElement library) {
+    summarize_elements.LibrarySerializationResult serializedLib =
+        summarize_elements.serializeLibrary(library, typeProvider);
+    {
+      List<int> buffer = serializedLib.prelinked.toBuffer();
+      prelinked = new PrelinkedLibrary.fromBuffer(buffer);
+    }
+    unlinkedUnits = serializedLib.unlinkedUnits.map((UnlinkedUnitBuilder b) {
+      List<int> buffer = b.toBuffer();
+      return new UnlinkedUnit.fromBuffer(buffer);
+    }).toList();
+    unitUris = serializedLib.unitUris;
+  }
+
+  @override
+  void serializeLibraryText(String text, {bool allowErrors: false}) {
+    Source source = addSource(text);
+    _fileContents[source] = text;
+    LibraryElement library = resolve2(source);
+    if (!allowErrors) {
+      assertNoErrors(source);
+    }
+    serializeLibraryElement(library);
+    expect(
+        unlinkedUnits[0].imports.length, prelinked.importDependencies.length);
+    expect(prelinked.units.length, unlinkedUnits.length);
+    for (int i = 0; i < prelinked.units.length; i++) {
+      expect(unlinkedUnits[i].references.length,
+          prelinked.units[i].references.length);
+    }
+    verifyPublicNamespace();
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableGenericMethods = true;
+    resetWithOptions(options);
+  }
+
+  test_class_no_superclass() {
+    UnlinkedClass cls = serializeClassElement(typeProvider.objectType.element);
+    expect(cls.supertype, isNull);
+    expect(cls.hasNoSupertype, isTrue);
+  }
+
+  /**
+   * Verify that [public_namespace.computePublicNamespace] produces data that's
+   * equivalent to that produced by [summarize_elements.serializeLibrary].
+   */
+  void verifyPublicNamespace() {
+    for (int i = 0; i < unlinkedUnits.length; i++) {
+      Source source = analysisContext.sourceFactory.forUri(unitUris[i]);
+      String text = _fileContents[source];
+      if (text == null) {
+        if (!allowMissingFiles) {
+          fail('Could not find file while verifying public namespace: '
+              '${unitUris[i]}');
+        }
+      } else {
+        UnlinkedPublicNamespace namespace =
+            computePublicNamespaceFromText(text, source);
+        expect(canonicalize(namespace),
+            canonicalize(unlinkedUnits[i].publicNamespace),
+            reason: 'publicNamespace(${unitUris[i]})');
+      }
+    }
+  }
+}
+
+/**
+ * Base class containing most summary tests.  This allows summary tests to be
+ * re-used to exercise all the different ways in which summaries can be
+ * generated (e.g. direct from the AST, from the element model, from a
+ * "relinking" process, etc.)
+ */
+abstract class SummaryTest {
+  /**
+   * Prelinked summary that results from serializing and then deserializing the
+   * library under test.
+   */
+  PrelinkedLibrary prelinked;
+
+  /**
+   * Unlinked compilation unit summaries that result from serializing and
+   * deserializing the library under test.
+   */
+  List<UnlinkedUnit> unlinkedUnits;
+
+  /**
+   * A test will set this to `true` if it contains `import`, `export`, or
+   * `part` declarations that deliberately refer to non-existent files.
+   */
+  bool allowMissingFiles = false;
+
+  /**
+   * `true` if the summary was created directly from the AST (and hence
+   * contains information that is not obtainable from the element model alone).
+   * TODO(paulberry): modify the element model so that it contains all the data
+   * that summaries need, so that this flag is no longer needed.
+   */
+  bool get checkAstDerivedData;
+
+  /**
+   * Get access to the prelinked defining compilation unit.
+   */
+  PrelinkedUnit get definingUnit => prelinked.units[0];
+
+  /**
+   * `true` if the prelinked portion of the summary is expected to contain
+   * absolute URIs.  This happens because the element model doesn't (yet) store
+   * enough information to recover relative URIs, TODO(paulberry): fix this.
+   */
+  bool get expectAbsoluteUrisInDependencies;
+
+  /**
+   * Convert [path] to a suitably formatted absolute path URI for the current
+   * platform.
+   */
+  String absUri(String path) {
+    return FileUtilities2.createFile(path).toURI().toString();
+  }
+
+  /**
+   * Add the given source file so that it may be referenced by the file under
+   * test.
+   */
+  Source addNamedSource(String filePath, String contents);
+
+  /**
+   * Verify that the [dependency]th element of the dependency table represents
+   * a file reachable via the given [absoluteUri] and [relativeUri].
+   */
+  void checkDependency(int dependency, String absoluteUri, String relativeUri) {
+    if (expectAbsoluteUrisInDependencies) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUri = absoluteUri;
+    }
+    expect(dependency, new isInstanceOf<int>());
+    expect(prelinked.dependencies[dependency].uri, relativeUri);
+  }
+
+  /**
+   * Verify that the given [dependency] lists the given [absoluteUris] or
+   * [relativeUris] as its parts.
+   */
+  void checkDependencyParts(PrelinkedDependency dependency,
+      List<String> absoluteUris, List<String> relativeUris) {
+    if (expectAbsoluteUrisInDependencies) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUris = absoluteUris;
+    }
+    expect(dependency.parts, relativeUris);
+  }
+
+  /**
+   * Check that the given [documentationComment] matches the first
+   * Javadoc-style comment found in [text].
+   *
+   * Note that the algorithm for finding the Javadoc-style comment in [text] is
+   * a simple-minded text search; it is easily confused by corner cases such as
+   * strings containing comments, nested comments, etc.
+   */
+  void checkDocumentationComment(
+      UnlinkedDocumentationComment documentationComment, String text) {
+    expect(documentationComment, isNotNull);
+    int commentStart = text.indexOf('/*');
+    expect(commentStart, isNot(-1));
+    int commentEnd = text.indexOf('*/');
+    expect(commentEnd, isNot(-1));
+    commentEnd += 2;
+    String expectedCommentText =
+        text.substring(commentStart, commentEnd).replaceAll('\r\n', '\n');
+    expect(documentationComment.text, expectedCommentText);
+    expect(documentationComment.offset, commentStart);
+    expect(documentationComment.length, commentEnd - commentStart);
+  }
+
+  /**
+   * Verify that the given [typeRef] represents the type `dynamic`.
+   */
+  void checkDynamicTypeRef(UnlinkedTypeRef typeRef) {
+    checkTypeRef(typeRef, null, null, null);
+  }
+
+  /**
+   * Verify that the dependency table contains an entry for a file reachable
+   * via the given [absoluteUri] and [relativeUri].
+   *
+   * The [PrelinkedDependency] is returned.
+   */
+  PrelinkedDependency checkHasDependency(
+      String absoluteUri, String relativeUri) {
+    if (expectAbsoluteUrisInDependencies) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUri = absoluteUri;
+    }
+    List<String> found = <String>[];
+    for (PrelinkedDependency dep in prelinked.dependencies) {
+      if (dep.uri == relativeUri) {
+        return dep;
+      }
+      found.add(dep.uri);
+    }
+    fail('Did not find dependency $relativeUri.  Found: $found');
+    return null;
+  }
+
+  /**
+   * Verify that the dependency table *does not* contain any entries for a file
+   * reachable via the given [absoluteUri] and [relativeUri].
+   */
+  void checkLacksDependency(String absoluteUri, String relativeUri) {
+    if (expectAbsoluteUrisInDependencies) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUri = absoluteUri;
+    }
+    for (PrelinkedDependency dep in prelinked.dependencies) {
+      if (dep.uri == relativeUri) {
+        fail('Unexpected dependency found: $relativeUri');
+      }
+    }
+  }
+
+  /**
+   * Verify that the given [typeRef] represents a reference to a type parameter
+   * having the given [deBruijnIndex].
+   */
+  void checkParamTypeRef(UnlinkedTypeRef typeRef, int deBruijnIndex) {
+    expect(typeRef, new isInstanceOf<UnlinkedTypeRef>());
+    expect(typeRef.reference, 0);
+    expect(typeRef.typeArguments, isEmpty);
+    expect(typeRef.paramReference, deBruijnIndex);
+  }
+
+  /**
+   * Verify that [prefixReference] is a valid reference to a prefix having the
+   * given [name].
+   */
+  void checkPrefix(int prefixReference, String name) {
+    expect(prefixReference, isNot(0));
+    expect(unlinkedUnits[0].references[prefixReference].prefixReference, 0);
+    expect(unlinkedUnits[0].references[prefixReference].name, name);
+    expect(definingUnit.references[prefixReference].dependency, 0);
+    expect(definingUnit.references[prefixReference].kind,
+        PrelinkedReferenceKind.prefix);
+    expect(definingUnit.references[prefixReference].unit, 0);
+  }
+
+  /**
+   * Verify that the given [typeRef] represents a reference to a type declared
+   * in a file reachable via [absoluteUri] and [relativeUri], having name
+   * [expectedName].  If [expectedPrefix] is supplied, verify that the type is
+   * reached via the given prefix.  If [allowTypeParameters] is true, allow the
+   * type reference to supply type parameters.  [expectedKind] is the kind of
+   * object referenced.  [prelinkedSourceUnit] and [unlinkedSourceUnit] refer
+   * to the compilation unit within which the [typeRef] appears; if not
+   * specified they are assumed to refer to the defining compilation unit.
+   * [expectedTargetUnit] is the index of the compilation unit in which the
+   * target of the [typeRef] is expected to appear; if not specified it is
+   * assumed to be the defining compilation unit.  [numTypeParameters] is the
+   * number of type parameters of the thing being referred to.
+   */
+  void checkTypeRef(UnlinkedTypeRef typeRef, String absoluteUri,
+      String relativeUri, String expectedName,
+      {String expectedPrefix,
+      bool allowTypeParameters: false,
+      PrelinkedReferenceKind expectedKind: PrelinkedReferenceKind.classOrEnum,
+      int expectedTargetUnit: 0,
+      PrelinkedUnit prelinkedSourceUnit,
+      UnlinkedUnit unlinkedSourceUnit,
+      int numTypeParameters: 0}) {
+    prelinkedSourceUnit ??= definingUnit;
+    unlinkedSourceUnit ??= unlinkedUnits[0];
+    expect(typeRef, new isInstanceOf<UnlinkedTypeRef>());
+    expect(typeRef.paramReference, 0);
+    int index = typeRef.reference;
+    UnlinkedReference reference = unlinkedSourceUnit.references[index];
+    PrelinkedReference referenceResolution =
+        prelinkedSourceUnit.references[index];
+    if (index == 0) {
+      // Index 0 is reserved for "dynamic".
+      expect(reference.name, isEmpty);
+      expect(reference.prefixReference, 0);
+    }
+    if (absoluteUri == null) {
+      expect(referenceResolution.dependency, 0);
+    } else {
+      checkDependency(referenceResolution.dependency, absoluteUri, relativeUri);
+    }
+    if (!allowTypeParameters) {
+      expect(typeRef.typeArguments, isEmpty);
+    }
+    if (expectedKind == PrelinkedReferenceKind.unresolved) {
+      // summarize_elements.dart isn't yet able to record the name of
+      // unresolved references.  TODO(paulberry): fix this.
+      expect(reference.name, '*unresolved*');
+    } else if (expectedName == null) {
+      expect(reference.name, isEmpty);
+    } else {
+      expect(reference.name, expectedName);
+    }
+    if (expectedPrefix == null) {
+      expect(reference.prefixReference, 0);
+    } else {
+      checkPrefix(reference.prefixReference, expectedPrefix);
+    }
+    expect(referenceResolution.kind, expectedKind);
+    expect(referenceResolution.unit, expectedTargetUnit);
+    expect(referenceResolution.numTypeParameters, numTypeParameters);
+  }
+
+  /**
+   * Verify that the given [typeRef] represents a reference to an unresolved
+   * type.
+   */
+  void checkUnresolvedTypeRef(
+      UnlinkedTypeRef typeRef, String expectedPrefix, String expectedName) {
+    // When serializing from the element model, unresolved type refs lose their
+    // name.
+    checkTypeRef(typeRef, null, null, checkAstDerivedData ? expectedName : null,
+        expectedPrefix: expectedPrefix,
+        expectedKind: PrelinkedReferenceKind.unresolved);
+  }
+
+  fail_enum_value_documented() {
+    // TODO(paulberry): currently broken because of dartbug.com/25385
+    String text = '''
+enum E {
+  /**
+   * Docs
+   */
+  v
+}''';
+    UnlinkedEnumValue value = serializeEnumText(text).values[0];
+    expect(value.documentationComment, isNotNull);
+    checkDocumentationComment(value.documentationComment, text);
+  }
+
+  fail_test_import_missing() {
+    // TODO(paulberry): At the moment unresolved imports are not included in
+    // the element model, so we can't pass this test.
+    // Unresolved imports are included since this is necessary for proper
+    // dependency tracking.
+    allowMissingFiles = true;
+    serializeLibraryText('import "foo.dart";', allowErrors: true);
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    checkDependency(
+        prelinked.importDependencies[0], absUri('/foo.dart'), 'foo.dart');
+  }
+
+  fail_type_reference_to_nonexistent_file_via_prefix() {
+    // TODO(paulberry): this test currently fails because there is not enough
+    // information in the element model to figure out that the unresolved
+    // reference `p.C` uses the prefix `p`.
+    allowMissingFiles = true;
+    UnlinkedTypeRef typeRef = serializeTypeText('p.C',
+        otherDeclarations: 'import "foo.dart" as p;', allowErrors: true);
+    checkUnresolvedTypeRef(typeRef, 'p', 'C');
+  }
+
+  fail_type_reference_to_type_visible_via_multiple_import_prefixes() {
+    // TODO(paulberry): this test currently fails because the element model
+    // doesn't record enough information to track which prefix is used to refer
+    // to a type.
+    addNamedSource('/lib1.dart', 'class C');
+    addNamedSource('/lib2.dart', 'export "lib1.dart";');
+    addNamedSource('/lib3.dart', 'export "lib1.dart";');
+    addNamedSource('/lib4.dart', 'export "lib1.dart";');
+    serializeLibraryText('''
+import 'lib2.dart';
+import 'lib3.dart' as a;
+import 'lib4.dart' as b;
+C c2;
+a.C c3;
+b.C c4;''');
+    // Note: it is important that each reference to class C records the prefix
+    // used to find it; otherwise it's possible that relinking might produce an
+    // incorrect result after a change to lib2.dart, lib3.dart, or lib4.dart.
+    checkTypeRef(
+        findVariable('c2').type, absUri('/lib1.dart'), 'lib1.dart', 'C');
+    checkTypeRef(
+        findVariable('c3').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
+        expectedPrefix: 'a');
+    checkTypeRef(
+        findVariable('c4').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
+        expectedPrefix: 'b');
+  }
+
+  /**
+   * Find the class with the given [className] in the summary, and return its
+   * [UnlinkedClass] data structure.  If [unit] is not given, the class is
+   * looked for in the defining compilation unit.
+   */
+  UnlinkedClass findClass(String className,
+      {bool failIfAbsent: false, UnlinkedUnit unit}) {
+    unit ??= unlinkedUnits[0];
+    UnlinkedClass result;
+    for (UnlinkedClass cls in unit.classes) {
+      if (cls.name == className) {
+        if (result != null) {
+          fail('Duplicate class $className');
+        }
+        result = cls;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Class $className not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the enum with the given [enumName] in the summary, and return its
+   * [UnlinkedEnum] data structure.  If [unit] is not given, the enum is looked
+   * for in the defining compilation unit.
+   */
+  UnlinkedEnum findEnum(String enumName,
+      {bool failIfAbsent: false, UnlinkedUnit unit}) {
+    unit ??= unlinkedUnits[0];
+    UnlinkedEnum result;
+    for (UnlinkedEnum e in unit.enums) {
+      if (e.name == enumName) {
+        if (result != null) {
+          fail('Duplicate enum $enumName');
+        }
+        result = e;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Enum $enumName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the executable with the given [executableName] in the summary, and
+   * return its [UnlinkedExecutable] data structure.  If [executables] is not
+   * given, then the executable is searched for in the defining compilation
+   * unit.
+   */
+  UnlinkedExecutable findExecutable(String executableName,
+      {List<UnlinkedExecutable> executables, bool failIfAbsent: false}) {
+    executables ??= unlinkedUnits[0].executables;
+    UnlinkedExecutable result;
+    for (UnlinkedExecutable executable in executables) {
+      if (executable.name == executableName) {
+        if (result != null) {
+          fail('Duplicate executable $executableName');
+        }
+        result = executable;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Executable $executableName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the typedef with the given [typedefName] in the summary, and return
+   * its [UnlinkedTypedef] data structure.  If [unit] is not given, the typedef
+   * is looked for in the defining compilation unit.
+   */
+  UnlinkedTypedef findTypedef(String typedefName,
+      {bool failIfAbsent: false, UnlinkedUnit unit}) {
+    unit ??= unlinkedUnits[0];
+    UnlinkedTypedef result;
+    for (UnlinkedTypedef type in unit.typedefs) {
+      if (type.name == typedefName) {
+        if (result != null) {
+          fail('Duplicate typedef $typedefName');
+        }
+        result = type;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Typedef $typedefName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the top level variable with the given [variableName] in the summary,
+   * and return its [UnlinkedVariable] data structure.  If [variables] is not
+   * specified, the variable is looked for in the defining compilation unit.
+   */
+  UnlinkedVariable findVariable(String variableName,
+      {List<UnlinkedVariable> variables, bool failIfAbsent: false}) {
+    variables ??= unlinkedUnits[0].variables;
+    UnlinkedVariable result;
+    for (UnlinkedVariable variable in variables) {
+      if (variable.name == variableName) {
+        if (result != null) {
+          fail('Duplicate variable $variableName');
+        }
+        result = variable;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Variable $variableName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the class
+   * with the given [className].
+   */
+  UnlinkedClass serializeClassText(String text, [String className = 'C']) {
+    serializeLibraryText(text);
+    return findClass(className, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the enum with
+   * the given [enumName].
+   */
+  UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) {
+    serializeLibraryText(text);
+    return findEnum(enumName, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the
+   * executable with the given [executableName].
+   */
+  UnlinkedExecutable serializeExecutableText(String text,
+      [String executableName = 'f']) {
+    serializeLibraryText(text);
+    return findExecutable(executableName, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text], then deserialize it and store its
+   * summary in [lib].
+   */
+  void serializeLibraryText(String text, {bool allowErrors: false});
+
+  /**
+   * Serialize the given method [text] and return the summary of the executable
+   * with the given [executableName].
+   */
+  UnlinkedExecutable serializeMethodText(String text,
+      [String executableName = 'f']) {
+    serializeLibraryText('class C { $text }');
+    return findExecutable(executableName,
+        executables: findClass('C', failIfAbsent: true).executables,
+        failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the typedef
+   * with the given [typedefName].
+   */
+  UnlinkedTypedef serializeTypedefText(String text,
+      [String typedefName = 'F']) {
+    serializeLibraryText(text);
+    return findTypedef(typedefName, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize a type declaration using the given [text] as a type name, and
+   * return a summary of the corresponding [UnlinkedTypeRef].  If the type
+   * declaration needs to refer to types that are not available in core, those
+   * types may be declared in [otherDeclarations].
+   */
+  UnlinkedTypeRef serializeTypeText(String text,
+      {String otherDeclarations: '', bool allowErrors: false}) {
+    return serializeVariableText('$otherDeclarations\n$text v;',
+        allowErrors: allowErrors).type;
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the variable
+   * with the given [variableName].
+   */
+  UnlinkedVariable serializeVariableText(String text,
+      {String variableName: 'v', bool allowErrors: false}) {
+    serializeLibraryText(text, allowErrors: allowErrors);
+    return findVariable(variableName, failIfAbsent: true);
+  }
+
+  test_cascaded_export_hide_hide() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C hide B, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_export_hide_show() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C show A, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_export_show_hide() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B hide B, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_export_show_show() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B show A, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_hide_hide() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' hide C hide B, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_hide_show() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' hide C show A, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_show_hide() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' show A, B hide B, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_show_show() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' show A, B show A, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_class_abstract() {
+    UnlinkedClass cls = serializeClassText('abstract class C {}');
+    expect(cls.isAbstract, true);
+  }
+
+  test_class_alias_abstract() {
+    UnlinkedClass cls = serializeClassText(
+        'abstract class C = D with E; class D {} class E {}');
+    expect(cls.isAbstract, true);
+  }
+
+  test_class_alias_concrete() {
+    UnlinkedClass cls =
+        serializeClassText('class C = _D with _E; class _D {} class _E {}');
+    expect(cls.isAbstract, false);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        PrelinkedReferenceKind.classOrEnum);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_class_alias_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C = D with E;
+
+class D {}
+class E {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_alias_flag() {
+    UnlinkedClass cls =
+        serializeClassText('class C = D with E; class D {} class E {}');
+    expect(cls.isMixinApplication, true);
+  }
+
+  test_class_alias_generic() {
+    serializeClassText('class C<A, B> = _D with _E; class _D {} class _E {}');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 2);
+  }
+
+  test_class_alias_mixin_order() {
+    UnlinkedClass cls = serializeClassText('''
+class C = D with E, F;
+class D {}
+class E {}
+class F {}
+''');
+    expect(cls.mixins, hasLength(2));
+    checkTypeRef(cls.mixins[0], null, null, 'E');
+    checkTypeRef(cls.mixins[1], null, null, 'F');
+  }
+
+  test_class_alias_no_implicit_constructors() {
+    UnlinkedClass cls = serializeClassText('''
+class C = D with E;
+class D {
+  D.foo();
+  D.bar();
+}
+class E {}
+''');
+    expect(cls.executables, isEmpty);
+  }
+
+  test_class_alias_private() {
+    serializeClassText('class _C = _D with _E; class _D {} class _E {}', '_C');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_class_alias_reference_generic() {
+    UnlinkedTypeRef typeRef = serializeTypeText('C',
+        otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}');
+    checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
+  }
+
+  test_class_alias_reference_generic_imported() {
+    addNamedSource(
+        '/lib.dart', 'class C<D, E> = F with G; class F {} class G {}');
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
+    checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
+        numTypeParameters: 2);
+  }
+
+  test_class_alias_supertype() {
+    UnlinkedClass cls =
+        serializeClassText('class C = D with E; class D {} class E {}');
+    checkTypeRef(cls.supertype, null, null, 'D');
+    expect(cls.hasNoSupertype, isFalse);
+  }
+
+  test_class_concrete() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.isAbstract, false);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        PrelinkedReferenceKind.classOrEnum);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_class_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_documented_with_references() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs referring to [D] and [E]
+ */
+class C {}
+
+class D {}
+class E {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_documented_with_with_windows_line_endings() {
+    String text = '/**\r\n * Docs\r\n */\r\nclass C {}';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_interface() {
+    UnlinkedClass cls = serializeClassText('''
+class C implements D {}
+class D {}
+''');
+    expect(cls.interfaces, hasLength(1));
+    checkTypeRef(cls.interfaces[0], null, null, 'D');
+  }
+
+  test_class_interface_order() {
+    UnlinkedClass cls = serializeClassText('''
+class C implements D, E {}
+class D {}
+class E {}
+''');
+    expect(cls.interfaces, hasLength(2));
+    checkTypeRef(cls.interfaces[0], null, null, 'D');
+    checkTypeRef(cls.interfaces[1], null, null, 'E');
+  }
+
+  test_class_mixin() {
+    UnlinkedClass cls = serializeClassText('''
+class C extends Object with D {}
+class D {}
+''');
+    expect(cls.mixins, hasLength(1));
+    checkTypeRef(cls.mixins[0], null, null, 'D');
+  }
+
+  test_class_mixin_order() {
+    UnlinkedClass cls = serializeClassText('''
+class C extends Object with D, E {}
+class D {}
+class E {}
+''');
+    expect(cls.mixins, hasLength(2));
+    checkTypeRef(cls.mixins[0], null, null, 'D');
+    checkTypeRef(cls.mixins[1], null, null, 'E');
+  }
+
+  test_class_name() {
+    var classText = 'class C {}';
+    UnlinkedClass cls = serializeClassText(classText);
+    expect(cls.name, 'C');
+    expect(cls.nameOffset, classText.indexOf('C'));
+  }
+
+  test_class_no_flags() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.isAbstract, false);
+    expect(cls.isMixinApplication, false);
+  }
+
+  test_class_no_interface() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.interfaces, isEmpty);
+  }
+
+  test_class_no_mixins() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.mixins, isEmpty);
+  }
+
+  test_class_no_type_param() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.typeParameters, isEmpty);
+  }
+
+  test_class_non_alias_flag() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.isMixinApplication, false);
+  }
+
+  test_class_private() {
+    serializeClassText('class _C {}', '_C');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_class_reference_generic() {
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('C', otherDeclarations: 'class C<D, E> {}');
+    checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
+  }
+
+  test_class_reference_generic_imported() {
+    addNamedSource('/lib.dart', 'class C<D, E> {}');
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
+    checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
+        numTypeParameters: 2);
+  }
+
+  test_class_superclass() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.supertype, isNull);
+    expect(cls.hasNoSupertype, isFalse);
+  }
+
+  test_class_superclass_explicit() {
+    UnlinkedClass cls = serializeClassText('class C extends D {} class D {}');
+    expect(cls.supertype, isNotNull);
+    checkTypeRef(cls.supertype, null, null, 'D');
+    expect(cls.hasNoSupertype, isFalse);
+  }
+
+  test_class_type_param_bound() {
+    UnlinkedClass cls = serializeClassText('class C<T extends List> {}');
+    expect(cls.typeParameters, hasLength(1));
+    expect(cls.typeParameters[0].name, 'T');
+    expect(cls.typeParameters[0].bound, isNotNull);
+    checkTypeRef(cls.typeParameters[0].bound, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true, numTypeParameters: 1);
+  }
+
+  test_class_type_param_f_bound() {
+    UnlinkedClass cls = serializeClassText('class C<T, U extends List<T>> {}');
+    UnlinkedTypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 2);
+  }
+
+  test_class_type_param_f_bound_self_ref() {
+    UnlinkedClass cls = serializeClassText('class C<T, U extends List<U>> {}');
+    UnlinkedTypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 1);
+  }
+
+  test_class_type_param_no_bound() {
+    String text = 'class C<T> {}';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.typeParameters, hasLength(1));
+    expect(cls.typeParameters[0].name, 'T');
+    expect(cls.typeParameters[0].nameOffset, text.indexOf('T'));
+    expect(cls.typeParameters[0].bound, isNull);
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
+  }
+
+  test_constructor() {
+    String text = 'class C { C(); }';
+    UnlinkedExecutable executable =
+        findExecutable('', executables: serializeClassText(text).executables);
+    expect(executable.kind, UnlinkedExecutableKind.constructor);
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('C();'));
+  }
+
+  test_constructor_anonymous() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
+    expect(executable.name, isEmpty);
+  }
+
+  test_constructor_const() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { const C(); }').executables);
+    expect(executable.isConst, isTrue);
+    expect(executable.isExternal, isFalse);
+  }
+
+  test_constructor_const_external() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { external const C(); }').executables);
+    expect(executable.isConst, isTrue);
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_constructor_documented() {
+    String text = '''
+class C {
+  /**
+   * Docs
+   */
+  C();
+}''';
+    UnlinkedExecutable executable = serializeClassText(text).executables[0];
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_constructor_external() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { external C(); }').executables);
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_constructor_factory() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { factory C() => null; }').executables);
+    expect(executable.isFactory, isTrue);
+  }
+
+  test_constructor_implicit() {
+    // Implicit constructors are not serialized.
+    UnlinkedExecutable executable = findExecutable(null,
+        executables: serializeClassText('class C { C(); }').executables,
+        failIfAbsent: false);
+    expect(executable, isNull);
+  }
+
+  test_constructor_initializing_formal() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.isInitializingFormal, isTrue);
+  }
+
+  test_constructor_initializing_formal_explicit_type() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(int this.x); final x; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_constructor_initializing_formal_function_typed() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(this.x()); final x; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.isFunctionTyped, isTrue);
+  }
+
+  test_constructor_initializing_formal_function_typed_explicit_return_type() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { C(int this.x()); Function x; }')
+                .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_constructor_initializing_formal_function_typed_implicit_return_type() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(this.x()); Function x; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    // Since the parameter is function-typed it is considered to have an
+    // explicit type, even though that explicit type itself has an implicit
+    // return type.
+    expect(parameter.hasImplicitType, isFalse);
+    checkDynamicTypeRef(parameter.type);
+  }
+
+  test_constructor_initializing_formal_function_typed_no_parameters() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(this.x()); final x; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.parameters, isEmpty);
+  }
+
+  test_constructor_initializing_formal_function_typed_parameter() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(this.x(a)); final x; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.parameters, hasLength(1));
+  }
+
+  test_constructor_initializing_formal_function_typed_parameter_order() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(this.x(a, b)); final x; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.parameters, hasLength(2));
+    expect(parameter.parameters[0].name, 'a');
+    expect(parameter.parameters[1].name, 'b');
+  }
+
+  test_constructor_initializing_formal_implicit_type() {
+    // Note: the implicit type of an initializing formal is the type of the
+    // field.
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { C(this.x); int x; }').executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
+    expect(parameter.hasImplicitType, isTrue);
+  }
+
+  test_constructor_initializing_formal_name() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.name, 'x');
+  }
+
+  test_constructor_initializing_formal_named() {
+    // TODO(paulberry): also test default value
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C({this.x}); final x; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.kind, UnlinkedParamKind.named);
+  }
+
+  test_constructor_initializing_formal_non_function_typed() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.isFunctionTyped, isFalse);
+  }
+
+  test_constructor_initializing_formal_positional() {
+    // TODO(paulberry): also test default value
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C([this.x]); final x; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.kind, UnlinkedParamKind.positional);
+  }
+
+  test_constructor_initializing_formal_required() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.kind, UnlinkedParamKind.required);
+  }
+
+  test_constructor_initializing_formal_typedef() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText(
+                'typedef F<T>(T x); class C<X> { C(this.f); F<X> f; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.parameters, hasLength(1));
+  }
+
+  test_constructor_named() {
+    String text = 'class C { C.foo(); }';
+    UnlinkedExecutable executable = findExecutable('foo',
+        executables: serializeClassText(text).executables);
+    expect(executable.name, 'foo');
+    expect(executable.nameOffset, text.indexOf('foo'));
+  }
+
+  test_constructor_non_const() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
+    expect(executable.isConst, isFalse);
+  }
+
+  test_constructor_non_factory() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
+    expect(executable.isFactory, isFalse);
+  }
+
+  test_constructor_return_type() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
+    expect(executable.returnType, isNull);
+  }
+
+  test_constructor_return_type_parameterized() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C<T, U> { C(); }').executables);
+    expect(executable.returnType, isNull);
+  }
+
+  test_dependencies_export_none() {
+    // Exports are not listed as dependencies since no change to the exported
+    // file can change the summary of the exporting file.
+    // TODO(paulberry): this needs to change since the element model for a
+    // library includes its export namespace.
+    addNamedSource('/a.dart', 'library a; export "b.dart";');
+    addNamedSource('/b.dart', 'library b;');
+    serializeLibraryText('export "a.dart";');
+    checkLacksDependency(absUri('/a.dart'), 'a.dart');
+    checkLacksDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_to_export() {
+    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
+    addNamedSource('/b.dart', 'library b;');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_to_export_in_subdirs_absolute_export() {
+    addNamedSource('/a/a.dart',
+        'library a; export "${absUri('/a/b/b.dart')}"; class A {}');
+    addNamedSource('/a/b/b.dart', 'library b;');
+    serializeLibraryText('import "a/a.dart"; A a;');
+    checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
+  }
+
+  test_dependencies_import_to_export_in_subdirs_absolute_import() {
+    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
+    addNamedSource('/a/b/b.dart', 'library b;');
+    serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;');
+    checkHasDependency(absUri('/a/a.dart'), absUri('/a/a.dart'));
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
+  }
+
+  test_dependencies_import_to_export_in_subdirs_relative() {
+    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
+    addNamedSource('/a/b/b.dart', 'library b;');
+    serializeLibraryText('import "a/a.dart"; A a;');
+    checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/a/b/b.dart'), 'a/b/b.dart');
+  }
+
+  test_dependencies_import_to_export_loop() {
+    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
+    addNamedSource('/b.dart', 'library b; export "a.dart";');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // Serialization should have been able to walk the transitive export
+    // dependencies to b.dart without going into an infinite loop.
+    checkHasDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_to_export_transitive_closure() {
+    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
+    addNamedSource('/b.dart', 'library b; export "c.dart";');
+    addNamedSource('/c.dart', 'library c;');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // The main test library depends on c.dart, because names defined in
+    // c.dart are exported by b.dart and then re-exported by a.dart.
+    checkHasDependency(absUri('/c.dart'), 'c.dart');
+  }
+
+  test_dependencies_import_transitive_closure() {
+    addNamedSource(
+        '/a.dart', 'library a; import "b.dart"; class A extends B {}');
+    addNamedSource('/b.dart', 'library b; class B {}');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // The main test library doesn't depend on b.dart, because no change to
+    // b.dart can possibly affect the serialized element model for it.
+    checkLacksDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_parts() {
+    addNamedSource(
+        '/a.dart', 'library a; part "b.dart"; part "c.dart"; class A {}');
+    addNamedSource('/b.dart', 'part of a;');
+    addNamedSource('/c.dart', 'part of a;');
+    serializeLibraryText('import "a.dart"; A a;');
+    PrelinkedDependency dep = checkHasDependency(absUri('/a.dart'), 'a.dart');
+    checkDependencyParts(
+        dep, [absUri('/b.dart'), absUri('/c.dart')], ['b.dart', 'c.dart']);
+  }
+
+  test_dependencies_parts_relative_to_importing_library() {
+    addNamedSource('/a/b.dart', 'export "c/d.dart";');
+    addNamedSource('/a/c/d.dart',
+        'library d; part "e/f.dart"; part "g/h.dart"; class D {}');
+    addNamedSource('/a/c/e/f.dart', 'part of d;');
+    addNamedSource('/a/c/g/h.dart', 'part of d;');
+    serializeLibraryText('import "a/b.dart"; D d;');
+    PrelinkedDependency dep =
+        checkHasDependency(absUri('/a/c/d.dart'), 'a/c/d.dart');
+    checkDependencyParts(
+        dep,
+        [absUri('/a/c/e/f.dart'), absUri('/a/c/g/h.dart')],
+        ['a/c/e/f.dart', 'a/c/g/h.dart']);
+  }
+
+  test_elements_in_part() {
+    addNamedSource(
+        '/part1.dart',
+        '''
+part of my.lib;
+
+class C {}
+enum E { v }
+var v;
+f() {}
+typedef F();
+''');
+    serializeLibraryText('library my.lib; part "part1.dart";');
+    UnlinkedUnit unit = unlinkedUnits[1];
+    expect(findClass('C', unit: unit), isNotNull);
+    expect(findEnum('E', unit: unit), isNotNull);
+    expect(findVariable('v', variables: unit.variables), isNotNull);
+    expect(findExecutable('f', executables: unit.executables), isNotNull);
+    expect(findTypedef('F', unit: unit), isNotNull);
+  }
+
+  test_enum() {
+    String text = 'enum E { v1 }';
+    UnlinkedEnum e = serializeEnumText(text);
+    expect(e.name, 'E');
+    expect(e.nameOffset, text.indexOf('E'));
+    expect(e.values, hasLength(1));
+    expect(e.values[0].name, 'v1');
+    expect(e.values[0].nameOffset, text.indexOf('v1'));
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        PrelinkedReferenceKind.classOrEnum);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'E');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_enum_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+enum E { v }''';
+    UnlinkedEnum enm = serializeEnumText(text);
+    expect(enm.documentationComment, isNotNull);
+    checkDocumentationComment(enm.documentationComment, text);
+  }
+
+  test_enum_order() {
+    UnlinkedEnum e = serializeEnumText('enum E { v1, v2 }');
+    expect(e.values, hasLength(2));
+    expect(e.values[0].name, 'v1');
+    expect(e.values[1].name, 'v2');
+  }
+
+  test_enum_private() {
+    serializeEnumText('enum _E { v1 }', '_E');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_executable_abstract() {
+    UnlinkedExecutable executable =
+        serializeClassText('abstract class C { f(); }').executables[0];
+    expect(executable.isAbstract, isTrue);
+  }
+
+  test_executable_concrete() {
+    UnlinkedExecutable executable =
+        serializeClassText('abstract class C { f() {} }').executables[0];
+    expect(executable.isAbstract, isFalse);
+  }
+
+  test_executable_function() {
+    String text = '  f() {}';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.hasImplicitReturnType, isTrue);
+    checkDynamicTypeRef(executable.returnType);
+    expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('f'));
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        PrelinkedReferenceKind.other);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_executable_function_explicit_return() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('dynamic f() => null;');
+    expect(executable.hasImplicitReturnType, isFalse);
+    checkDynamicTypeRef(executable.returnType);
+  }
+
+  test_executable_function_external() {
+    UnlinkedExecutable executable = serializeExecutableText('external f();');
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_function_private() {
+    serializeExecutableText('_f() {}', '_f');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_executable_getter() {
+    String text = 'int get f => 1;';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.kind, UnlinkedExecutableKind.getter);
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('f'));
+    expect(findVariable('f'), isNull);
+    expect(findExecutable('f='), isNull);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        PrelinkedReferenceKind.other);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
+  }
+
+  test_executable_getter_external() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('external int get f;');
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_getter_private() {
+    serializeExecutableText('int get _f => 1;', '_f');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_executable_getter_type() {
+    UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
+    checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
+    expect(executable.parameters, isEmpty);
+  }
+
+  test_executable_getter_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('get f => 1;');
+    checkDynamicTypeRef(executable.returnType);
+    expect(executable.hasImplicitReturnType, isTrue);
+    expect(executable.parameters, isEmpty);
+  }
+
+  test_executable_member_function() {
+    UnlinkedExecutable executable = findExecutable('f',
+        executables: serializeClassText('class C { f() {} }').executables);
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.hasImplicitReturnType, isTrue);
+    expect(executable.isExternal, isFalse);
+  }
+
+  test_executable_member_function_explicit_return() {
+    UnlinkedExecutable executable = findExecutable('f',
+        executables:
+            serializeClassText('class C { dynamic f() => null; }').executables);
+    expect(executable.hasImplicitReturnType, isFalse);
+  }
+
+  test_executable_member_function_external() {
+    UnlinkedExecutable executable = findExecutable('f',
+        executables:
+            serializeClassText('class C { external f(); }').executables);
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_member_getter() {
+    UnlinkedClass cls = serializeClassText('class C { int get f => 1; }');
+    UnlinkedExecutable executable =
+        findExecutable('f', executables: cls.executables, failIfAbsent: true);
+    expect(executable.kind, UnlinkedExecutableKind.getter);
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
+    expect(findVariable('f', variables: cls.fields), isNull);
+    expect(findExecutable('f=', executables: cls.executables), isNull);
+  }
+
+  test_executable_member_getter_external() {
+    UnlinkedClass cls = serializeClassText('class C { external int get f; }');
+    UnlinkedExecutable executable =
+        findExecutable('f', executables: cls.executables, failIfAbsent: true);
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_member_setter() {
+    UnlinkedClass cls = serializeClassText('class C { void set f(value) {} }');
+    UnlinkedExecutable executable =
+        findExecutable('f=', executables: cls.executables, failIfAbsent: true);
+    expect(executable.kind, UnlinkedExecutableKind.setter);
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
+    expect(findVariable('f', variables: cls.fields), isNull);
+    expect(findExecutable('f', executables: cls.executables), isNull);
+  }
+
+  test_executable_member_setter_external() {
+    UnlinkedClass cls =
+        serializeClassText('class C { external void set f(value); }');
+    UnlinkedExecutable executable =
+        findExecutable('f=', executables: cls.executables, failIfAbsent: true);
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_member_setter_implicit_return() {
+    UnlinkedClass cls = serializeClassText('class C { set f(value) {} }');
+    UnlinkedExecutable executable =
+        findExecutable('f=', executables: cls.executables, failIfAbsent: true);
+    expect(executable.hasImplicitReturnType, isTrue);
+    checkDynamicTypeRef(executable.returnType);
+  }
+
+  test_executable_name() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.name, 'f');
+  }
+
+  test_executable_no_flags() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.isAbstract, isFalse);
+    expect(executable.isConst, isFalse);
+    expect(executable.isFactory, isFalse);
+    expect(executable.isStatic, isFalse);
+  }
+
+  test_executable_non_static() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { f() {} }').executables[0];
+    expect(executable.isStatic, isFalse);
+  }
+
+  test_executable_non_static_top_level() {
+    // Top level executables are considered non-static.
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.isStatic, isFalse);
+  }
+
+  test_executable_operator() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { C operator+(C c) => null; }').executables[
+            0];
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.name, '+');
+    expect(executable.hasImplicitReturnType, false);
+    expect(executable.isAbstract, false);
+    expect(executable.isConst, false);
+    expect(executable.isFactory, false);
+    expect(executable.isStatic, false);
+    expect(executable.parameters, hasLength(1));
+    checkTypeRef(executable.returnType, null, null, 'C');
+    expect(executable.typeParameters, isEmpty);
+    expect(executable.isExternal, false);
+  }
+
+  test_executable_operator_equal() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { bool operator==(C other) => false; }')
+            .executables[0];
+    expect(executable.name, '==');
+  }
+
+  test_executable_operator_external() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { external C operator+(C c); }')
+            .executables[0];
+    expect(executable.isExternal, true);
+  }
+
+  test_executable_operator_greater_equal() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { bool operator>=(C other) => false; }')
+            .executables[0];
+    expect(executable.name, '>=');
+  }
+
+  test_executable_operator_index() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { bool operator[](int i) => null; }')
+            .executables[0];
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.name, '[]');
+    expect(executable.hasImplicitReturnType, false);
+    expect(executable.isAbstract, false);
+    expect(executable.isConst, false);
+    expect(executable.isFactory, false);
+    expect(executable.isStatic, false);
+    expect(executable.parameters, hasLength(1));
+    checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'bool');
+    expect(executable.typeParameters, isEmpty);
+  }
+
+  test_executable_operator_index_set() {
+    UnlinkedExecutable executable = serializeClassText(
+        'class C { void operator[]=(int i, bool v) => null; }').executables[0];
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.name, '[]=');
+    expect(executable.hasImplicitReturnType, false);
+    expect(executable.isAbstract, false);
+    expect(executable.isConst, false);
+    expect(executable.isFactory, false);
+    expect(executable.isStatic, false);
+    expect(executable.parameters, hasLength(2));
+    expect(executable.returnType, isNull);
+    expect(executable.typeParameters, isEmpty);
+  }
+
+  test_executable_operator_less_equal() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { bool operator<=(C other) => false; }')
+            .executables[0];
+    expect(executable.name, '<=');
+  }
+
+  test_executable_param_function_typed() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
+    expect(executable.parameters[0].isFunctionTyped, isTrue);
+    // Since the parameter is function-typed it is considered to have an
+    // explicit type, even though that explicit type itself has an implicit
+    // return type.
+    expect(executable.parameters[0].hasImplicitType, isFalse);
+  }
+
+  test_executable_param_function_typed_explicit_return_type() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('f(dynamic g()) {}');
+    expect(executable.parameters[0].hasImplicitType, isFalse);
+  }
+
+  test_executable_param_function_typed_param() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g(x)) {}');
+    expect(executable.parameters[0].parameters, hasLength(1));
+  }
+
+  test_executable_param_function_typed_param_none() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
+    expect(executable.parameters[0].parameters, isEmpty);
+  }
+
+  test_executable_param_function_typed_param_order() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g(x, y)) {}');
+    expect(executable.parameters[0].parameters, hasLength(2));
+    expect(executable.parameters[0].parameters[0].name, 'x');
+    expect(executable.parameters[0].parameters[1].name, 'y');
+  }
+
+  test_executable_param_function_typed_return_type() {
+    UnlinkedExecutable executable = serializeExecutableText('f(int g()) {}');
+    checkTypeRef(
+        executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_executable_param_function_typed_return_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
+    checkDynamicTypeRef(executable.parameters[0].type);
+  }
+
+  test_executable_param_function_typed_return_type_void() {
+    UnlinkedExecutable executable = serializeExecutableText('f(void g()) {}');
+    expect(executable.parameters[0].type, isNull);
+  }
+
+  test_executable_param_kind_named() {
+    UnlinkedExecutable executable = serializeExecutableText('f({x}) {}');
+    expect(executable.parameters[0].kind, UnlinkedParamKind.named);
+  }
+
+  test_executable_param_kind_positional() {
+    UnlinkedExecutable executable = serializeExecutableText('f([x]) {}');
+    expect(executable.parameters[0].kind, UnlinkedParamKind.positional);
+  }
+
+  test_executable_param_kind_required() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    expect(executable.parameters[0].kind, UnlinkedParamKind.required);
+  }
+
+  test_executable_param_name() {
+    String text = 'f(x) {}';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.parameters, hasLength(1));
+    expect(executable.parameters[0].name, 'x');
+    expect(executable.parameters[0].nameOffset, text.indexOf('x'));
+  }
+
+  test_executable_param_no_flags() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    expect(executable.parameters[0].isFunctionTyped, isFalse);
+    expect(executable.parameters[0].isInitializingFormal, isFalse);
+  }
+
+  test_executable_param_non_function_typed() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g) {}');
+    expect(executable.parameters[0].isFunctionTyped, isFalse);
+  }
+
+  test_executable_param_none() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.parameters, isEmpty);
+  }
+
+  test_executable_param_order() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x, y) {}');
+    expect(executable.parameters, hasLength(2));
+    expect(executable.parameters[0].name, 'x');
+    expect(executable.parameters[1].name, 'y');
+  }
+
+  test_executable_param_type_explicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f(dynamic x) {}');
+    checkDynamicTypeRef(executable.parameters[0].type);
+    expect(executable.parameters[0].hasImplicitType, isFalse);
+  }
+
+  test_executable_param_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    checkDynamicTypeRef(executable.parameters[0].type);
+    expect(executable.parameters[0].hasImplicitType, isTrue);
+  }
+
+  test_executable_return_type() {
+    UnlinkedExecutable executable = serializeExecutableText('int f() => 1;');
+    checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
+    expect(executable.hasImplicitReturnType, isFalse);
+  }
+
+  test_executable_return_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    checkDynamicTypeRef(executable.returnType);
+    expect(executable.hasImplicitReturnType, isTrue);
+  }
+
+  test_executable_return_type_void() {
+    UnlinkedExecutable executable = serializeExecutableText('void f() {}');
+    expect(executable.returnType, isNull);
+  }
+
+  test_executable_setter() {
+    String text = 'void set f(value) {}';
+    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
+    expect(executable.kind, UnlinkedExecutableKind.setter);
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('f'));
+    expect(findVariable('f'), isNull);
+    expect(findExecutable('f'), isNull);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        PrelinkedReferenceKind.other);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f=');
+  }
+
+  test_executable_setter_external() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('external void set f(value);', 'f=');
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_setter_implicit_return() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('set f(value) {}', 'f=');
+    expect(executable.hasImplicitReturnType, isTrue);
+    checkDynamicTypeRef(executable.returnType);
+  }
+
+  test_executable_setter_private() {
+    serializeExecutableText('void set _f(value) {}', '_f=');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_executable_setter_type() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('void set f(int value) {}', 'f=');
+    expect(executable.returnType, isNull);
+    expect(executable.parameters, hasLength(1));
+    expect(executable.parameters[0].name, 'value');
+    checkTypeRef(
+        executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_executable_static() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { static f() {} }').executables[0];
+    expect(executable.isStatic, isTrue);
+  }
+
+  test_executable_type_param_f_bound_function() {
+    UnlinkedExecutable ex =
+        serializeExecutableText('void f<T, U extends List<T>>() {}');
+    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 2);
+  }
+
+  test_executable_type_param_f_bound_method() {
+    UnlinkedExecutable ex =
+        serializeMethodText('void f<T, U extends List<T>>() {}');
+    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 2);
+  }
+
+  test_executable_type_param_f_bound_self_ref_function() {
+    UnlinkedExecutable ex =
+        serializeExecutableText('void f<T, U extends List<U>>() {}');
+    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 1);
+  }
+
+  test_executable_type_param_f_bound_self_ref_method() {
+    UnlinkedExecutable ex =
+        serializeMethodText('void f<T, U extends List<U>>() {}');
+    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 1);
+  }
+
+  test_executable_type_param_in_parameter_function() {
+    UnlinkedExecutable ex = serializeExecutableText('void f<T>(T t) {}');
+    checkParamTypeRef(ex.parameters[0].type, 1);
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
+  }
+
+  test_executable_type_param_in_parameter_method() {
+    UnlinkedExecutable ex = serializeMethodText('void f<T>(T t) {}');
+    checkParamTypeRef(ex.parameters[0].type, 1);
+  }
+
+  test_executable_type_param_in_return_type_function() {
+    UnlinkedExecutable ex = serializeExecutableText('T f<T>() => null;');
+    checkParamTypeRef(ex.returnType, 1);
+  }
+
+  test_executable_type_param_in_return_type_method() {
+    UnlinkedExecutable ex = serializeMethodText('T f<T>() => null;');
+    checkParamTypeRef(ex.returnType, 1);
+  }
+
+  test_export_hide_order() {
+    serializeLibraryText('export "dart:async" hide Future, Stream;');
+    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
+    expect(
+        unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
+        isEmpty);
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
+        hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[0],
+        'Future');
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[1],
+        'Stream');
+  }
+
+  test_export_no_combinators() {
+    serializeLibraryText('export "dart:async";');
+    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators, isEmpty);
+  }
+
+  test_export_offset() {
+    String libraryText = '    export "dart:async";';
+    serializeLibraryText(libraryText);
+    expect(unlinkedUnits[0].exports[0].uriOffset,
+        libraryText.indexOf('"dart:async"'));
+    expect(unlinkedUnits[0].exports[0].uriEnd, libraryText.indexOf(';'));
+    expect(unlinkedUnits[0].exports[0].offset, libraryText.indexOf('export'));
+  }
+
+  test_export_show_order() {
+    serializeLibraryText('export "dart:async" show Future, Stream;');
+    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
+    expect(
+        unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
+        hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
+        isEmpty);
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[0],
+        'Future');
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[1],
+        'Stream');
+  }
+
+  test_export_uri() {
+    addNamedSource('/a.dart', 'library my.lib;');
+    String uriString = '"a.dart"';
+    String libraryText = 'export $uriString;';
+    serializeLibraryText(libraryText);
+    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].uri, 'a.dart');
+  }
+
+  test_field() {
+    UnlinkedClass cls = serializeClassText('class C { int i; }');
+    UnlinkedVariable variable = findVariable('i', variables: cls.fields);
+    expect(variable, isNotNull);
+    expect(variable.isConst, isFalse);
+    expect(variable.isStatic, isFalse);
+    expect(variable.isFinal, isFalse);
+    expect(findExecutable('i', executables: cls.executables), isNull);
+    expect(findExecutable('i=', executables: cls.executables), isNull);
+  }
+
+  test_field_const() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { static const int i = 0; }').fields[0];
+    expect(variable.isConst, isTrue);
+  }
+
+  test_field_documented() {
+    String text = '''
+class C {
+  /**
+   * Docs
+   */
+  var v;
+}''';
+    UnlinkedVariable variable = serializeClassText(text).fields[0];
+    expect(variable.documentationComment, isNotNull);
+    checkDocumentationComment(variable.documentationComment, text);
+  }
+
+  test_field_final() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { final int i = 0; }').fields[0];
+    expect(variable.isFinal, isTrue);
+  }
+
+  test_field_static() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { static int i; }').fields[0];
+    expect(variable.isStatic, isTrue);
+  }
+
+  test_function_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+f() {}''';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_generic_method_in_generic_class() {
+    UnlinkedClass cls = serializeClassText(
+        'class C<T, U> { void m<V, W>(T t, U u, V v, W w) {} }');
+    List<UnlinkedParam> params = cls.executables[0].parameters;
+    checkParamTypeRef(params[0].type, 4);
+    checkParamTypeRef(params[1].type, 3);
+    checkParamTypeRef(params[2].type, 2);
+    checkParamTypeRef(params[3].type, 1);
+  }
+
+  test_getter_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+get f => null;''';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_import_deferred() {
+    serializeLibraryText(
+        'import "dart:async" deferred as a; main() { print(a.Future); }');
+    expect(unlinkedUnits[0].imports[0].isDeferred, isTrue);
+  }
+
+  test_import_dependency() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    checkDependency(
+        prelinked.importDependencies[0], 'dart:async', 'dart:async');
+  }
+
+  test_import_explicit() {
+    serializeLibraryText('import "dart:core"; int i;');
+    expect(unlinkedUnits[0].imports, hasLength(1));
+    expect(unlinkedUnits[0].imports[0].isImplicit, isFalse);
+  }
+
+  test_import_hide_order() {
+    serializeLibraryText(
+        'import "dart:async" hide Future, Stream; Completer c;');
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].imports[0].combinators[0].shows, isEmpty);
+    expect(unlinkedUnits[0].imports[0].combinators[0].hides, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators[0].hides[0], 'Future');
+    expect(unlinkedUnits[0].imports[0].combinators[0].hides[1], 'Stream');
+  }
+
+  test_import_implicit() {
+    // The implicit import of dart:core is represented in the model.
+    serializeLibraryText('');
+    expect(unlinkedUnits[0].imports, hasLength(1));
+    checkDependency(prelinked.importDependencies[0], 'dart:core', 'dart:core');
+    expect(unlinkedUnits[0].imports[0].uri, isEmpty);
+    expect(unlinkedUnits[0].imports[0].uriOffset, 0);
+    expect(unlinkedUnits[0].imports[0].uriEnd, 0);
+    expect(unlinkedUnits[0].imports[0].prefixReference, 0);
+    expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
+    expect(unlinkedUnits[0].imports[0].isImplicit, isTrue);
+  }
+
+  test_import_no_combinators() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
+  }
+
+  test_import_no_flags() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    expect(unlinkedUnits[0].imports[0].isImplicit, isFalse);
+    expect(unlinkedUnits[0].imports[0].isDeferred, isFalse);
+  }
+
+  test_import_non_deferred() {
+    serializeLibraryText(
+        'import "dart:async" as a; main() { print(a.Future); }');
+    expect(unlinkedUnits[0].imports[0].isDeferred, isFalse);
+  }
+
+  test_import_of_file_with_missing_part() {
+    // Other references in foo.dart should be resolved even though foo.dart's
+    // part declaration for bar.dart refers to a non-existent file.
+    allowMissingFiles = true;
+    addNamedSource('/foo.dart', 'part "bar.dart"; class C {}');
+    serializeLibraryText('import "foo.dart"; C x;');
+    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
+  }
+
+  test_import_of_missing_export() {
+    // Other references in foo.dart should be resolved even though foo.dart's
+    // re-export of bar.dart refers to a non-existent file.
+    allowMissingFiles = true;
+    addNamedSource('/foo.dart', 'export "bar.dart"; class C {}');
+    serializeLibraryText('import "foo.dart"; C x;');
+    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
+  }
+
+  test_import_offset() {
+    String libraryText = '    import "dart:async"; Future x;';
+    serializeLibraryText(libraryText);
+    expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import'));
+    expect(unlinkedUnits[0].imports[0].uriOffset,
+        libraryText.indexOf('"dart:async"'));
+    expect(unlinkedUnits[0].imports[0].uriEnd, libraryText.indexOf('; Future'));
+  }
+
+  test_import_prefix_name() {
+    String libraryText = 'import "dart:async" as a; a.Future x;';
+    serializeLibraryText(libraryText);
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    checkPrefix(unlinkedUnits[0].imports[0].prefixReference, 'a');
+    expect(unlinkedUnits[0].imports[0].prefixOffset, libraryText.indexOf('a;'));
+  }
+
+  test_import_prefix_none() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].prefixReference, 0);
+  }
+
+  test_import_prefix_not_in_public_namespace() {
+    serializeLibraryText('import "dart:async" as a; a.Future v;');
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'v');
+    expect(unlinkedUnits[0].publicNamespace.names[1].name, 'v=');
+  }
+
+  test_import_prefix_reference() {
+    UnlinkedVariable variable =
+        serializeVariableText('import "dart:async" as a; a.Future v;');
+    checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
+        expectedPrefix: 'a', numTypeParameters: 1);
+  }
+
+  test_import_prefixes_take_precedence_over_imported_names() {
+    addNamedSource('/a.dart', 'class b {} class A');
+    addNamedSource('/b.dart', 'class Cls {}');
+    addNamedSource('/c.dart', 'class Cls {}');
+    addNamedSource('/d.dart', 'class c {} class D');
+    serializeLibraryText('''
+import 'a.dart';
+import 'b.dart' as b;
+import 'c.dart' as c;
+import 'd.dart';
+A aCls;
+b.Cls bCls;
+c.Cls cCls;
+D dCls;
+''');
+    checkTypeRef(findVariable('aCls').type, absUri('/a.dart'), 'a.dart', 'A');
+    checkTypeRef(findVariable('bCls').type, absUri('/b.dart'), 'b.dart', 'Cls',
+        expectedPrefix: 'b');
+    checkTypeRef(findVariable('cCls').type, absUri('/c.dart'), 'c.dart', 'Cls',
+        expectedPrefix: 'c');
+    checkTypeRef(findVariable('dCls').type, absUri('/d.dart'), 'd.dart', 'D');
+  }
+
+  test_import_reference() {
+    UnlinkedVariable variable =
+        serializeVariableText('import "dart:async"; Future v;');
+    checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
+        numTypeParameters: 1);
+  }
+
+  test_import_reference_merged_no_prefix() {
+    serializeLibraryText('''
+import "dart:async" show Future;
+import "dart:async" show Stream;
+
+Future f;
+Stream s;
+''');
+    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
+        numTypeParameters: 1);
+    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
+        numTypeParameters: 1);
+  }
+
+  test_import_reference_merged_prefixed() {
+    serializeLibraryText('''
+import "dart:async" as a show Future;
+import "dart:async" as a show Stream;
+
+a.Future f;
+a.Stream s;
+''');
+    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
+        expectedPrefix: 'a', numTypeParameters: 1);
+    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
+        expectedPrefix: 'a', numTypeParameters: 1);
+  }
+
+  test_import_reference_merged_prefixed_separate_libraries() {
+    addNamedSource('/a.dart', 'class A {}');
+    addNamedSource('/b.dart', 'class B {}');
+    serializeLibraryText('''
+import 'a.dart' as p;
+import 'b.dart' as p;
+
+p.A a;
+p.B b;
+''');
+    checkTypeRef(findVariable('a').type, absUri('/a.dart'), 'a.dart', 'A',
+        expectedPrefix: 'p');
+    checkTypeRef(findVariable('b').type, absUri('/b.dart'), 'b.dart', 'B',
+        expectedPrefix: 'p');
+  }
+
+  test_import_show_order() {
+    String libraryText =
+        'import "dart:async" show Future, Stream; Future x; Stream y;';
+    serializeLibraryText(libraryText);
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].imports[0].combinators[0].shows, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators[0].hides, isEmpty);
+    expect(unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future');
+    expect(unlinkedUnits[0].imports[0].combinators[0].shows[1], 'Stream');
+  }
+
+  test_import_uri() {
+    String uriString = '"dart:async"';
+    String libraryText = 'import $uriString; Future x;';
+    serializeLibraryText(libraryText);
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].uri, 'dart:async');
+  }
+
+  test_library_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+library foo;''';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].libraryDocumentationComment, isNotNull);
+    checkDocumentationComment(
+        unlinkedUnits[0].libraryDocumentationComment, text);
+  }
+
+  test_library_name_with_spaces() {
+    String text = 'library foo . bar ;';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].libraryName, 'foo.bar');
+    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo . bar'));
+    expect(unlinkedUnits[0].libraryNameLength, 'foo . bar'.length);
+  }
+
+  test_library_named() {
+    String text = 'library foo.bar;';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].libraryName, 'foo.bar');
+    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo.bar'));
+    expect(unlinkedUnits[0].libraryNameLength, 'foo.bar'.length);
+  }
+
+  test_library_unnamed() {
+    serializeLibraryText('');
+    expect(unlinkedUnits[0].libraryName, isEmpty);
+    expect(unlinkedUnits[0].libraryNameOffset, 0);
+    expect(unlinkedUnits[0].libraryNameLength, 0);
+  }
+
+  test_library_with_missing_part() {
+    // References to other parts should still be resolved.
+    allowMissingFiles = true;
+    addNamedSource('/bar.dart', 'part of my.lib; class C {}');
+    serializeLibraryText(
+        'library my.lib; part "foo.dart"; part "bar.dart"; C c;',
+        allowErrors: true);
+    checkTypeRef(findVariable('c').type, null, null, 'C',
+        expectedTargetUnit: 2);
+  }
+
+  test_local_names_take_precedence_over_imported_names() {
+    addNamedSource('/a.dart', 'class C {} class D {}');
+    serializeLibraryText('''
+import 'a.dart';
+class C {}
+C c;
+D d;''');
+    checkTypeRef(findVariable('c').type, null, null, 'C');
+    checkTypeRef(findVariable('d').type, absUri('/a.dart'), 'a.dart', 'D');
+  }
+
+  test_method_documented() {
+    String text = '''
+class C {
+  /**
+   * Docs
+   */
+  f() {}
+}''';
+    UnlinkedExecutable executable = serializeClassText(text).executables[0];
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_part_declaration() {
+    addNamedSource('/a.dart', 'part of my.lib;');
+    String text = 'library my.lib; part "a.dart"; // <-part';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.parts[0], 'a.dart');
+    expect(unlinkedUnits[0].parts, hasLength(1));
+    expect(unlinkedUnits[0].parts[0].uriOffset, text.indexOf('"a.dart"'));
+    expect(unlinkedUnits[0].parts[0].uriEnd, text.indexOf('; // <-part'));
+  }
+
+  test_parts_defining_compilation_unit() {
+    serializeLibraryText('');
+    expect(prelinked.units, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.parts, isEmpty);
+  }
+
+  test_parts_included() {
+    addNamedSource('/part1.dart', 'part of my.lib;');
+    String partString = '"part1.dart"';
+    String libraryText = 'library my.lib; part $partString;';
+    serializeLibraryText(libraryText);
+    expect(prelinked.units, hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.parts[0], 'part1.dart');
+  }
+
+  test_public_namespace_of_part() {
+    addNamedSource('/a.dart', 'part of foo; class C {}');
+    serializeLibraryText('library foo; part "a.dart";');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+    expect(unlinkedUnits[1].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[1].publicNamespace.names[0].name, 'C');
+  }
+
+  test_setter_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+void set f(value) {}''';
+    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_type_arguments_explicit() {
+    UnlinkedTypeRef typeRef = serializeTypeText('List<int>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true, numTypeParameters: 1);
+    expect(typeRef.typeArguments, hasLength(1));
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_type_arguments_explicit_dynamic() {
+    UnlinkedTypeRef typeRef = serializeTypeText('List<dynamic>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true, numTypeParameters: 1);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_explicit_dynamic_typedef() {
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        allowTypeParameters: true,
+        expectedKind: PrelinkedReferenceKind.typedef,
+        numTypeParameters: 1);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_explicit_typedef() {
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        allowTypeParameters: true,
+        expectedKind: PrelinkedReferenceKind.typedef,
+        numTypeParameters: 1);
+    expect(typeRef.typeArguments, hasLength(1));
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_type_arguments_implicit() {
+    UnlinkedTypeRef typeRef = serializeTypeText('List');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true, numTypeParameters: 1);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_implicit_typedef() {
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('F', otherDeclarations: 'typedef T F<T>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        allowTypeParameters: true,
+        expectedKind: PrelinkedReferenceKind.typedef,
+        numTypeParameters: 1);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_order() {
+    UnlinkedTypeRef typeRef = serializeTypeText('Map<int, Object>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
+        allowTypeParameters: true, numTypeParameters: 2);
+    expect(typeRef.typeArguments, hasLength(2));
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
+    checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object');
+  }
+
+  test_type_dynamic() {
+    checkDynamicTypeRef(serializeTypeText('dynamic'));
+  }
+
+  test_type_reference_from_part() {
+    addNamedSource('/a.dart', 'part of foo; C v;');
+    serializeLibraryText('library foo; part "a.dart"; class C {}');
+    checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
+        null, null, 'C',
+        expectedKind: PrelinkedReferenceKind.classOrEnum,
+        prelinkedSourceUnit: prelinked.units[1],
+        unlinkedSourceUnit: unlinkedUnits[1]);
+  }
+
+  test_type_reference_from_part_withPrefix() {
+    addNamedSource('/a.dart', 'class C {}');
+    addNamedSource('/p.dart', 'part of foo; a.C v;');
+    serializeLibraryText(
+        'library foo; import "a.dart"; import "a.dart" as a; part "p.dart";',
+        allowErrors: true);
+    checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
+        absUri('/a.dart'), 'a.dart', 'C',
+        expectedPrefix: 'a',
+        prelinkedSourceUnit: prelinked.units[1],
+        unlinkedSourceUnit: unlinkedUnits[1]);
+  }
+
+  test_type_reference_to_class_argument() {
+    UnlinkedClass cls = serializeClassText('class C<T, U> { T t; U u; }');
+    {
+      UnlinkedTypeRef typeRef =
+          findVariable('t', variables: cls.fields, failIfAbsent: true).type;
+      checkParamTypeRef(typeRef, 2);
+    }
+    {
+      UnlinkedTypeRef typeRef =
+          findVariable('u', variables: cls.fields, failIfAbsent: true).type;
+      checkParamTypeRef(typeRef, 1);
+    }
+  }
+
+  test_type_reference_to_import_of_export() {
+    addNamedSource('/a.dart', 'library a; export "b.dart";');
+    addNamedSource('/b.dart', 'library b; class C {}');
+    checkTypeRef(serializeTypeText('C', otherDeclarations: 'import "a.dart";'),
+        absUri('/b.dart'), 'b.dart', 'C');
+  }
+
+  test_type_reference_to_import_of_export_via_prefix() {
+    addNamedSource('/a.dart', 'library a; export "b.dart";');
+    addNamedSource('/b.dart', 'library b; class C {}');
+    checkTypeRef(
+        serializeTypeText('p.C', otherDeclarations: 'import "a.dart" as p;'),
+        absUri('/b.dart'),
+        'b.dart',
+        'C',
+        expectedPrefix: 'p');
+  }
+
+  test_type_reference_to_imported_part() {
+    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
+    addNamedSource('/b.dart', 'part of my.lib; class C {}');
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'library my.lib; import "a.dart";'),
+        absUri('/a.dart'),
+        'a.dart',
+        'C',
+        expectedTargetUnit: 1);
+  }
+
+  test_type_reference_to_imported_part_with_prefix() {
+    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
+    addNamedSource('/b.dart', 'part of my.lib; class C {}');
+    checkTypeRef(
+        serializeTypeText('p.C',
+            otherDeclarations: 'library my.lib; import "a.dart" as p;'),
+        absUri('/a.dart'),
+        'a.dart',
+        'C',
+        expectedPrefix: 'p',
+        expectedTargetUnit: 1);
+  }
+
+  test_type_reference_to_internal_class() {
+    checkTypeRef(serializeTypeText('C', otherDeclarations: 'class C {}'), null,
+        null, 'C');
+  }
+
+  test_type_reference_to_internal_class_alias() {
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'class C = D with E; class D {} class E {}'),
+        null,
+        null,
+        'C');
+  }
+
+  test_type_reference_to_internal_enum() {
+    checkTypeRef(serializeTypeText('E', otherDeclarations: 'enum E { value }'),
+        null, null, 'E');
+  }
+
+  test_type_reference_to_local_part() {
+    addNamedSource('/a.dart', 'part of my.lib; class C {}');
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'library my.lib; part "a.dart";'),
+        null,
+        null,
+        'C',
+        expectedTargetUnit: 1);
+  }
+
+  test_type_reference_to_part() {
+    addNamedSource('/a.dart', 'part of foo; class C { C(); }');
+    serializeLibraryText('library foo; part "a.dart"; C c;');
+    checkTypeRef(unlinkedUnits[0].variables.single.type, null, null, 'C',
+        expectedKind: PrelinkedReferenceKind.classOrEnum,
+        expectedTargetUnit: 1);
+  }
+
+  test_type_reference_to_typedef() {
+    checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'),
+        null, null, 'F',
+        expectedKind: PrelinkedReferenceKind.typedef);
+  }
+
+  test_type_unit_counts_unreferenced_units() {
+    addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";');
+    addNamedSource('/b.dart', 'part of a;');
+    addNamedSource('/c.dart', 'part of a; class C {}');
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('C', otherDeclarations: 'import "a.dart";');
+    // The referenced unit should be 2, since unit 0 is a.dart and unit 1 is
+    // b.dart.  a.dart and b.dart are counted even though nothing is imported
+    // from them.
+    checkTypeRef(typeRef, absUri('/a.dart'), 'a.dart', 'C',
+        expectedTargetUnit: 2);
+  }
+
+  test_type_unresolved() {
+    UnlinkedTypeRef typeRef = serializeTypeText('Foo', allowErrors: true);
+    checkUnresolvedTypeRef(typeRef, null, 'Foo');
+  }
+
+  test_typedef_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+typedef F();''';
+    UnlinkedTypedef typedef = serializeTypedefText(text);
+    expect(typedef.documentationComment, isNotNull);
+    checkDocumentationComment(typedef.documentationComment, text);
+  }
+
+  test_typedef_name() {
+    String text = 'typedef F();';
+    UnlinkedTypedef type = serializeTypedefText(text);
+    expect(type.name, 'F');
+    expect(type.nameOffset, text.indexOf('F'));
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        PrelinkedReferenceKind.typedef);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'F');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_typedef_param_none() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F();');
+    expect(type.parameters, isEmpty);
+  }
+
+  test_typedef_param_order() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F(x, y);');
+    expect(type.parameters, hasLength(2));
+    expect(type.parameters[0].name, 'x');
+    expect(type.parameters[1].name, 'y');
+  }
+
+  test_typedef_private() {
+    serializeTypedefText('typedef _F();', '_F');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_typedef_reference_generic() {
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('F', otherDeclarations: 'typedef void F<A, B>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        numTypeParameters: 2, expectedKind: PrelinkedReferenceKind.typedef);
+  }
+
+  test_typedef_reference_generic_imported() {
+    addNamedSource('/lib.dart', 'typedef void F<A, B>();');
+    UnlinkedTypeRef typeRef =
+        serializeTypeText('F', otherDeclarations: 'import "lib.dart";');
+    checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'F',
+        numTypeParameters: 2, expectedKind: PrelinkedReferenceKind.typedef);
+  }
+
+  test_typedef_return_type_explicit() {
+    UnlinkedTypedef type = serializeTypedefText('typedef int F();');
+    checkTypeRef(type.returnType, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_typedef_type_param_in_parameter() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F<T>(T t);');
+    checkParamTypeRef(type.parameters[0].type, 1);
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
+  }
+
+  test_typedef_type_param_in_return_type() {
+    UnlinkedTypedef type = serializeTypedefText('typedef T F<T>();');
+    checkParamTypeRef(type.returnType, 1);
+  }
+
+  test_typedef_type_param_none() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F();');
+    expect(type.typeParameters, isEmpty);
+  }
+
+  test_typedef_type_param_order() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F<T, U>();');
+    expect(type.typeParameters, hasLength(2));
+    expect(type.typeParameters[0].name, 'T');
+    expect(type.typeParameters[1].name, 'U');
+  }
+
+  test_variable() {
+    String text = 'int i;';
+    UnlinkedVariable v = serializeVariableText(text, variableName: 'i');
+    expect(v.nameOffset, text.indexOf('i;'));
+    expect(findExecutable('i'), isNull);
+    expect(findExecutable('i='), isNull);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        PrelinkedReferenceKind.other);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'i');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+    expect(unlinkedUnits[0].publicNamespace.names[1].kind,
+        PrelinkedReferenceKind.other);
+    expect(unlinkedUnits[0].publicNamespace.names[1].name, 'i=');
+    expect(unlinkedUnits[0].publicNamespace.names[1].numTypeParameters, 0);
+  }
+
+  test_variable_const() {
+    UnlinkedVariable variable =
+        serializeVariableText('const int i = 0;', variableName: 'i');
+    expect(variable.isConst, isTrue);
+  }
+
+  test_variable_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+var v;''';
+    UnlinkedVariable variable = serializeVariableText(text);
+    expect(variable.documentationComment, isNotNull);
+    checkDocumentationComment(variable.documentationComment, text);
+  }
+
+  test_variable_explicit_dynamic() {
+    UnlinkedVariable variable = serializeVariableText('dynamic v;');
+    checkDynamicTypeRef(variable.type);
+    expect(variable.hasImplicitType, isFalse);
+  }
+
+  test_variable_final_top_level() {
+    UnlinkedVariable variable =
+        serializeVariableText('final int i = 0;', variableName: 'i');
+    expect(variable.isFinal, isTrue);
+  }
+
+  test_variable_implicit_dynamic() {
+    UnlinkedVariable variable = serializeVariableText('var v;');
+    checkDynamicTypeRef(variable.type);
+    expect(variable.hasImplicitType, isTrue);
+  }
+
+  test_variable_name() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.name, 'i');
+  }
+
+  test_variable_no_flags() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.isStatic, isFalse);
+    expect(variable.isConst, isFalse);
+    expect(variable.isFinal, isFalse);
+  }
+
+  test_variable_non_const() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i = 0;', variableName: 'i');
+    expect(variable.isConst, isFalse);
+  }
+
+  test_variable_non_final() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.isFinal, isFalse);
+  }
+
+  test_variable_non_static() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { int i; }').fields[0];
+    expect(variable.isStatic, isFalse);
+  }
+
+  test_variable_non_static_top_level() {
+    // Top level variables are considered non-static.
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.isStatic, isFalse);
+  }
+
+  test_variable_static() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { static int i; }').fields[0];
+    expect(variable.isStatic, isTrue);
+  }
+
+  test_variable_type() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_varible_private() {
+    serializeVariableText('int _i;', variableName: '_i');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
new file mode 100644
index 0000000..252c95f
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -0,0 +1,26 @@
+// 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 test.src.serialization.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../utils.dart';
+import 'flat_buffers_test.dart' as flat_buffers_test;
+import 'name_filter_test.dart' as name_filter_test;
+import 'resynthesize_test.dart' as resynthesize_test;
+import 'summary_sdk_test.dart' as summary_sdk_test;
+import 'summary_test.dart' as summary_test;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('summary tests', () {
+    flat_buffers_test.main();
+    name_filter_test.main();
+    resynthesize_test.main();
+    summary_sdk_test.main();
+    summary_test.main();
+  });
+}
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index a60b879..23930d8 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -2,12 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.dart_test;
+library analyzer.test.src.task.dart_test;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.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'
     show AnalysisOptionsImpl, CacheState;
 import 'package:analyzer/src/generated/error.dart';
@@ -44,6 +46,7 @@
   runReflectiveTests(ComputeConstantValueTaskTest);
   runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
   runReflectiveTests(ComputeLibraryCycleTaskTest);
+  runReflectiveTests(ComputePropagableVariableDependenciesTaskTest);
   runReflectiveTests(ContainingLibrariesTaskTest);
   runReflectiveTests(DartErrorsTaskTest);
   runReflectiveTests(EvaluateUnitConstantsTaskTest);
@@ -58,7 +61,10 @@
   runReflectiveTests(LibraryUnitErrorsTaskTest);
   runReflectiveTests(ParseDartTaskTest);
   runReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
+  runReflectiveTests(PropagateVariableTypesInUnitTaskTest);
+  runReflectiveTests(PropagateVariableTypeTaskTest);
   runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
+  runReflectiveTests(ResolveLibraryTaskTest);
   runReflectiveTests(ResolveLibraryTypeNamesTaskTest);
   runReflectiveTests(ResolveUnitTaskTest);
   runReflectiveTests(ResolveUnitTypeNamesTaskTest);
@@ -91,6 +97,8 @@
     new isInstanceOf<ComputeConstantValueTask>();
 isInstanceOf isComputeInferableStaticVariableDependenciesTask =
     new isInstanceOf<ComputeInferableStaticVariableDependenciesTask>();
+isInstanceOf isComputePropagableVariableDependenciesTask =
+    new isInstanceOf<ComputePropagableVariableDependenciesTask>();
 isInstanceOf isContainingLibrariesTask =
     new isInstanceOf<ContainingLibrariesTask>();
 isInstanceOf isDartErrorsTask = new isInstanceOf<DartErrorsTask>();
@@ -115,6 +123,11 @@
 isInstanceOf isParseDartTask = new isInstanceOf<ParseDartTask>();
 isInstanceOf isPartiallyResolveUnitReferencesTask =
     new isInstanceOf<PartiallyResolveUnitReferencesTask>();
+isInstanceOf isPropagateVariableTypesInUnitTask =
+    new isInstanceOf<PropagateVariableTypesInUnitTask>();
+isInstanceOf isPropagateVariableTypeTask =
+    new isInstanceOf<PropagateVariableTypeTask>();
+isInstanceOf isResolveLibraryTask = new isInstanceOf<ResolveLibraryTask>();
 isInstanceOf isResolveLibraryTypeNamesTask =
     new isInstanceOf<ResolveLibraryTypeNamesTask>();
 isInstanceOf isResolveUnitTask = new isInstanceOf<ResolveUnitTask>();
@@ -134,6 +147,19 @@
   Source source;
   LibrarySpecificUnit target;
 
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT1);
+    expect(outputs[RESOLVED_UNIT1], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT1], isTrue);
+  }
+
   test_perform_find_constants() {
     _performBuildTask('''
 const x = 1;
@@ -176,10 +202,11 @@
 }
 class B = Object with A;
 ''');
-    expect(outputs, hasLength(3));
+    expect(outputs, hasLength(4));
     expect(outputs[COMPILATION_UNIT_CONSTANTS], isNotNull);
     expect(outputs[COMPILATION_UNIT_ELEMENT], isNotNull);
     expect(outputs[RESOLVED_UNIT1], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT1], isTrue);
   }
 
   test_perform_reuseElement() {
@@ -457,6 +484,19 @@
 
 @reflectiveTest
 class BuildEnumMemberElementsTaskTest extends _AbstractDartTaskTest {
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT2);
+    expect(outputs[RESOLVED_UNIT2], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT2], isTrue);
+  }
+
   test_perform() {
     Source source = newSource(
         '/test.dart',
@@ -1106,8 +1146,9 @@
         computeResult(target, CONSTANT_VALUE,
             matcher: isComputeConstantValueTask);
         expect(outputs[CONSTANT_VALUE], same(target));
-        EvaluationResultImpl evaluationResult = (annotation.elementAnnotation
-            as ElementAnnotationImpl).evaluationResult;
+        EvaluationResultImpl evaluationResult =
+            (annotation.elementAnnotation as ElementAnnotationImpl)
+                .evaluationResult;
         return evaluationResult;
       }
     }
@@ -1274,9 +1315,10 @@
     // should be set to the same error state.
     for (String otherVariableName in otherVariables) {
       PropertyInducingElement otherVariableElement =
-          _findVariable(unit, otherVariableName);
-      _expectCircularityError((otherVariableElement
-          as TopLevelVariableElementImpl).evaluationResult);
+          AstFinder.getTopLevelVariableElement(unit, otherVariableName);
+      _expectCircularityError(
+          (otherVariableElement as TopLevelVariableElementImpl)
+              .evaluationResult);
     }
   }
 
@@ -1288,7 +1330,8 @@
   EvaluationResultImpl _evaluateConstant(
       CompilationUnit unit, String variableName) {
     // Find the element for the given constant.
-    PropertyInducingElement variableElement = _findVariable(unit, variableName);
+    PropertyInducingElement variableElement =
+        AstFinder.getTopLevelVariableElement(unit, variableName);
     // Now compute the value of the constant.
     computeResult(variableElement, CONSTANT_VALUE,
         matcher: isComputeConstantValueTask);
@@ -1306,13 +1349,6 @@
         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);
@@ -1335,6 +1371,19 @@
     enableStrongMode();
   }
 
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT5);
+    expect(outputs[RESOLVED_UNIT5], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT5], isTrue);
+  }
+
   test_perform() {
     AnalysisTarget source = newSource(
         '/test.dart',
@@ -1531,6 +1580,62 @@
     expect(dep2, hasLength(1)); // dart:core
   }
 
+  void test_library_cycle_override_inference_incremental() {
+    enableStrongMode();
+    Source lib1Source = newSource(
+        '/my_lib1.dart',
+        '''
+library my_lib1;
+import 'my_lib3.dart';
+''');
+    Source lib2Source = newSource(
+        '/my_lib2.dart',
+        '''
+library my_lib2;
+import 'my_lib1.dart';
+''');
+    Source lib3Source = newSource(
+        '/my_lib3.dart',
+        '''
+library my_lib3;
+import 'my_lib2.dart';
+
+class A {
+  int foo(int x) => null;
+}
+class B extends A {
+  foo(x) => null;
+}
+''');
+    AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
+    AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
+    AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);
+
+    computeResult(lib1Target, RESOLVED_UNIT);
+    computeResult(lib2Target, RESOLVED_UNIT);
+    computeResult(lib3Target, RESOLVED_UNIT);
+    CompilationUnit unit = outputs[RESOLVED_UNIT];
+    ClassElement b = unit.declarations[1].element;
+    expect(b.getMethod('foo').returnType.toString(), 'int');
+
+    // add a dummy edit.
+    context.setContents(
+        lib1Source,
+        '''
+library my_lib1;
+import 'my_lib3.dart';
+var foo = 123;
+''');
+
+    computeResult(lib1Target, RESOLVED_UNIT);
+    computeResult(lib2Target, RESOLVED_UNIT);
+    computeResult(lib3Target, RESOLVED_UNIT);
+    unit = outputs[RESOLVED_UNIT];
+    b = unit.declarations[1].element;
+    expect(b.getMethod('foo').returnType.toString(), 'int',
+        reason: 'edit should not affect member inference');
+  }
+
   void test_library_cycle_self_loop() {
     List<Source> sources = newSources({
       '/a.dart': '''
@@ -1645,7 +1750,7 @@
     List<CompilationUnitElement> dep3 = results[3][LIBRARY_CYCLE_DEPENDENCIES];
     expect(dep0, hasLength(1)); // dart:core
     expect(dep1, hasLength(1)); // dart:core
-    expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart
+    expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart
     expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart
   }
 
@@ -1760,6 +1865,134 @@
 }
 
 @reflectiveTest
+class ComputePropagableVariableDependenciesTaskTest
+    extends _AbstractDartTaskTest {
+  test_perform_instanceField() {
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+class A {
+  final a = a1 + a2 + a3 + a4 + B.b1 + B.b2 + B.b3 + B.b4;
+  static const a1 = 1;
+  final a2 = 2;
+  final a3;
+  var   a4 = 4;
+}
+class B {
+  static const b1 = 1;
+  static final b2 = 2;
+  static final b3;
+  static var   b4 = 4;
+}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT5);
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    FieldElement elementA = AstFinder.getFieldInClassElement(unit, 'A', 'a');
+    // compute
+    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
+        matcher: isComputePropagableVariableDependenciesTask);
+    // verify
+    expect(outputs, hasLength(1));
+    List<VariableElement> dependencies =
+        outputs[PROPAGABLE_VARIABLE_DEPENDENCIES];
+    expect(
+        dependencies,
+        unorderedEquals([
+          AstFinder.getFieldInClassElement(unit, 'A', 'a1'),
+          AstFinder.getFieldInClassElement(unit, 'A', 'a2'),
+          AstFinder.getFieldInClassElement(unit, 'B', 'b1'),
+          AstFinder.getFieldInClassElement(unit, 'B', 'b2')
+        ]));
+  }
+
+  test_perform_topLevel() {
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+const a = d1 + d2 + d3 + d4;
+const d1 = 1;
+final d2 = 2;
+final d3;
+var   d4 = 4;
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT5);
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    TopLevelVariableElement elementA =
+        AstFinder.getTopLevelVariableElement(unit, 'a');
+    // compute
+    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
+        matcher: isComputePropagableVariableDependenciesTask);
+    // verify
+    expect(outputs, hasLength(1));
+    List<VariableElement> dependencies =
+        outputs[PROPAGABLE_VARIABLE_DEPENDENCIES];
+    expect(
+        dependencies,
+        unorderedEquals([
+          AstFinder.getTopLevelVariableElement(unit, 'd1'),
+          AstFinder.getTopLevelVariableElement(unit, 'd2')
+        ]));
+  }
+
+  test_perform_topLevel_ignoreLocal() {
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+final a = () {
+  const b = 2;
+  const c = 3;
+  return b + c;
+}() + d;
+final d = 4;
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT5);
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    TopLevelVariableElement elementA =
+        AstFinder.getTopLevelVariableElement(unit, 'a');
+    // compute
+    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
+        matcher: isComputePropagableVariableDependenciesTask);
+    // verify
+    expect(outputs, hasLength(1));
+    List<VariableElement> dependencies =
+        outputs[PROPAGABLE_VARIABLE_DEPENDENCIES];
+    expect(dependencies,
+        unorderedEquals([AstFinder.getTopLevelVariableElement(unit, 'd')]));
+  }
+
+  test_perform_topLevel_withoutSpaceAfterType() {
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+const List<int>a=[b, c];
+const b = 1;
+const c = 2;
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT5);
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    TopLevelVariableElement elementA =
+        AstFinder.getTopLevelVariableElement(unit, 'a');
+    // compute
+    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
+        matcher: isComputePropagableVariableDependenciesTask);
+    // verify
+    expect(outputs, hasLength(1));
+    List<VariableElement> dependencies =
+        outputs[PROPAGABLE_VARIABLE_DEPENDENCIES];
+    expect(
+        dependencies,
+        unorderedEquals([
+          AstFinder.getTopLevelVariableElement(unit, 'b'),
+          AstFinder.getTopLevelVariableElement(unit, 'c')
+        ]));
+  }
+}
+
+@reflectiveTest
 class ContainingLibrariesTaskTest extends _AbstractDartTaskTest {
   test_perform_definingCompilationUnit() {
     AnalysisTarget library = newSource('/test.dart', 'library test;');
@@ -1831,6 +2064,19 @@
 
 @reflectiveTest
 class EvaluateUnitConstantsTaskTest extends _AbstractDartTaskTest {
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT11);
+    expect(outputs[RESOLVED_UNIT11], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
+  }
+
   test_perform() {
     Source source = newSource(
         '/test.dart',
@@ -1845,9 +2091,9 @@
 const x = const C();
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT10,
+    computeResult(target, RESOLVED_UNIT11,
         matcher: isEvaluateUnitConstantsTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
     CompilationUnitElement unitElement = unit.element;
     expect(
         (unitElement.types[0].constructors[0] as ConstructorElementImpl)
@@ -2295,6 +2541,19 @@
 
 @reflectiveTest
 class InferInstanceMembersInUnitTaskTest extends _AbstractDartTaskTest {
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT9);
+    expect(outputs[RESOLVED_UNIT9], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+  }
+
   void test_perform() {
     enableStrongMode();
     AnalysisTarget source = newSource(
@@ -2312,14 +2571,14 @@
 class Y {}
 class Z {}
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
         matcher: isInferInstanceMembersInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT8];
-    VariableDeclaration field = getFieldInClass(unit, 'B', 'f');
-    MethodDeclaration method = getMethodInClass(unit, 'B', 'm');
-    DartType typeX = getClass(unit, 'X').element.type;
-    DartType typeY = getClass(unit, 'Y').element.type;
-    DartType typeZ = getClass(unit, 'Z').element.type;
+    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    VariableDeclaration field = AstFinder.getFieldInClass(unit, 'B', 'f');
+    MethodDeclaration method = AstFinder.getMethodInClass(unit, 'B', 'm');
+    DartType typeX = AstFinder.getClass(unit, 'X').element.type;
+    DartType typeY = AstFinder.getClass(unit, 'Y').element.type;
+    DartType typeZ = AstFinder.getClass(unit, 'Z').element.type;
 
     expect(field.element.type, typeX);
     expect(method.element.returnType, typeY);
@@ -2346,16 +2605,19 @@
 }
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8,
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9,
         matcher: isInferInstanceMembersInUnitTask);
-    CompilationUnit firstUnit = outputs[RESOLVED_UNIT8];
+    CompilationUnit firstUnit = outputs[RESOLVED_UNIT9];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8);
-    CompilationUnit secondUnit = outputs[RESOLVED_UNIT8];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
+    CompilationUnit secondUnit = outputs[RESOLVED_UNIT9];
 
-    VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a');
-    VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b');
-    VariableDeclaration variableC = getFieldInClass(secondUnit, 'M', 'c');
+    VariableDeclaration variableA =
+        AstFinder.getTopLevelVariable(firstUnit, 'a');
+    VariableDeclaration variableB =
+        AstFinder.getTopLevelVariable(secondUnit, 'b');
+    VariableDeclaration variableC =
+        AstFinder.getFieldInClass(secondUnit, 'M', 'c');
     InterfaceType stringType = context.typeProvider.stringType;
 
     expect(variableA.element.type, stringType);
@@ -2375,10 +2637,12 @@
   String field = topLevel;
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
-    CompilationUnit unit = outputs[RESOLVED_UNIT8];
-    VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel');
-    VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field');
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
+    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    VariableDeclaration topLevelDecl =
+        AstFinder.getTopLevelVariable(unit, 'topLevel');
+    VariableDeclaration fieldDecl =
+        AstFinder.getFieldInClass(unit, 'C', 'field');
     VariableElement topLevel = topLevelDecl.name.staticElement;
     VariableElement field = fieldDecl.name.staticElement;
 
@@ -2391,6 +2655,19 @@
 
 @reflectiveTest
 class InferStaticVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT7);
+    expect(outputs[RESOLVED_UNIT7], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT7], isTrue);
+  }
+
   void test_perform_const_field() {
     enableStrongMode();
     AnalysisTarget source = newSource(
@@ -2400,10 +2677,10 @@
   static const X = "";
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
         matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT6];
-    VariableDeclaration declaration = getFieldInClass(unit, 'M', 'X');
+    CompilationUnit unit = outputs[RESOLVED_UNIT7];
+    VariableDeclaration declaration = AstFinder.getFieldInClass(unit, 'M', 'X');
     InterfaceType stringType = context.typeProvider.stringType;
     expect(declaration.element.type, stringType);
   }
@@ -2419,7 +2696,7 @@
   return xSquared;
 };
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
         matcher: isInferStaticVariableTypesInUnitTask);
   }
 
@@ -2442,17 +2719,20 @@
 class M {}
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT6,
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT7,
         matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit firstUnit = outputs[RESOLVED_UNIT6];
+    CompilationUnit firstUnit = outputs[RESOLVED_UNIT7];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT6);
-    CompilationUnit secondUnit = outputs[RESOLVED_UNIT6];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT7);
+    CompilationUnit secondUnit = outputs[RESOLVED_UNIT7];
 
-    VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a');
-    VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b');
-    VariableDeclaration variableC = getTopLevelVariable(firstUnit, 'c');
-    ClassDeclaration classM = getClass(secondUnit, 'M');
+    VariableDeclaration variableA =
+        AstFinder.getTopLevelVariable(firstUnit, 'a');
+    VariableDeclaration variableB =
+        AstFinder.getTopLevelVariable(secondUnit, 'b');
+    VariableDeclaration variableC =
+        AstFinder.getTopLevelVariable(firstUnit, 'c');
+    ClassDeclaration classM = AstFinder.getClass(secondUnit, 'M');
     DartType typeM = classM.element.type;
 
     expect(variableA.element.type, typeM);
@@ -2473,9 +2753,9 @@
   return 1 + X;
 };
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
         matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT6];
+    CompilationUnit unit = outputs[RESOLVED_UNIT7];
     TopLevelVariableDeclaration declaration = unit.declarations[1];
     FunctionExpression function =
         declaration.variables.variables[0].initializer;
@@ -2499,7 +2779,8 @@
 ''');
     computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
     CompilationUnit unit = outputs[RESOLVED_UNIT5];
-    VariableDeclaration declaration = getFieldInClass(unit, 'C', 'field');
+    VariableDeclaration declaration =
+        AstFinder.getFieldInClass(unit, 'C', 'field');
     VariableElement variable = declaration.name.staticElement;
     InferStaticVariableTypeTask inferTask =
         new InferStaticVariableTypeTask(task.context, variable);
@@ -2514,7 +2795,8 @@
 ''');
     computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
     CompilationUnit unit = outputs[RESOLVED_UNIT5];
-    VariableDeclaration declaration = getTopLevelVariable(unit, 'topLevel');
+    VariableDeclaration declaration =
+        AstFinder.getTopLevelVariable(unit, 'topLevel');
     VariableElement variable = declaration.name.staticElement;
     InferStaticVariableTypeTask inferTask =
         new InferStaticVariableTypeTask(task.context, variable);
@@ -2533,8 +2815,10 @@
 ''');
     computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
     CompilationUnit unit = outputs[RESOLVED_UNIT5];
-    VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel3');
-    VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field3');
+    VariableDeclaration topLevelDecl =
+        AstFinder.getTopLevelVariable(unit, 'topLevel3');
+    VariableDeclaration fieldDecl =
+        AstFinder.getFieldInClass(unit, 'C', 'field3');
     VariableElement topLevel = topLevelDecl.name.staticElement;
     VariableElement field = fieldDecl.name.staticElement;
 
@@ -2559,9 +2843,9 @@
     computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
     CompilationUnit unit = outputs[RESOLVED_UNIT5];
     VariableElement topLevel =
-        getTopLevelVariable(unit, 'topLevel').name.staticElement;
+        AstFinder.getTopLevelVariable(unit, 'topLevel').name.staticElement;
     VariableElement field =
-        getFieldInClass(unit, 'C', 'field').name.staticElement;
+        AstFinder.getFieldInClass(unit, 'C', 'field').name.staticElement;
 
     computeResult(field, INFERRED_STATIC_VARIABLE,
         matcher: isInferStaticVariableTypeTask);
@@ -2582,9 +2866,11 @@
     computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
     CompilationUnit unit = outputs[RESOLVED_UNIT5];
     VariableElement piFirst =
-        getTopLevelVariable(unit, 'piFirst').name.staticElement;
-    VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement;
-    VariableElement tau = getTopLevelVariable(unit, 'tau').name.staticElement;
+        AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
+    VariableElement pi =
+        AstFinder.getTopLevelVariable(unit, 'pi').name.staticElement;
+    VariableElement tau =
+        AstFinder.getTopLevelVariable(unit, 'tau').name.staticElement;
 
     computeResult(piFirst, INFERRED_STATIC_VARIABLE,
         matcher: isInferStaticVariableTypeTask);
@@ -2602,7 +2888,8 @@
 ''');
     computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
     CompilationUnit unit = outputs[RESOLVED_UNIT5];
-    VariableElement a = getTopLevelVariable(unit, 'a').name.staticElement;
+    VariableElement a =
+        AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;
 
     computeResult(a, INFERRED_STATIC_VARIABLE,
         matcher: isInferStaticVariableTypeTask);
@@ -2618,7 +2905,8 @@
 ''');
     computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
     CompilationUnit unit = outputs[RESOLVED_UNIT5];
-    VariableElement a = getTopLevelVariable(unit, 'a').name.staticElement;
+    VariableElement a =
+        AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;
 
     computeResult(a, INFERRED_STATIC_VARIABLE,
         matcher: isInferStaticVariableTypeTask);
@@ -2705,6 +2993,41 @@
     expect(outputs[UNITS], hasLength(1));
   }
 
+  test_perform_enableAsync_false() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableAsync = false;
+    prepareAnalysisContext(options);
+    _performParseTask(r'''
+import 'dart:async';
+class B {void foo() async {}}''');
+    expect(outputs, hasLength(9));
+    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
+    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
+    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
+    expect(outputs[INCLUDED_PARTS], hasLength(0));
+    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
+    expect(outputs[PARSE_ERRORS], hasLength(1));
+    expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
+    expect(outputs[UNITS], hasLength(1));
+  }
+
+  test_perform_enableAsync_true() {
+    _performParseTask(r'''
+import 'dart:async';
+class B {void foo() async {}}''');
+    expect(outputs, hasLength(9));
+    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
+    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
+    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
+    expect(outputs[INCLUDED_PARTS], hasLength(0));
+    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
+    expect(outputs[PARSE_ERRORS], hasLength(0));
+    expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
+    expect(outputs[UNITS], hasLength(1));
+  }
+
   test_perform_computeSourceKind_noDirectives_hasContainingLibrary() {
     // Parse "lib.dart" to let the context know that "test.dart" is included.
     computeResult(
@@ -2739,6 +3062,13 @@
     expect(outputs[UNITS], hasLength(1));
   }
 
+  test_perform_flushTokenStream() {
+    _performParseTask(r'''
+class Test {}
+''');
+    expect(analysisCache.getState(source, TOKEN_STREAM), CacheState.FLUSHED);
+  }
+
   test_perform_invalidDirectives() {
     _performParseTask(r'''
 library lib;
@@ -2817,35 +3147,36 @@
 
 @reflectiveTest
 class PartiallyResolveUnitReferencesTaskTest extends _AbstractDartTaskTest {
-  test_perform() {
+  test_perform_propagable() {
     enableStrongMode();
     Source source = newSource(
         '/test.dart',
         '''
-int a = b;
-int b = c;
-var d = 0;
-class A {}
+const t1 = 1;
+final t2 = 2;
+var   t3 = 3;
+final t4;
 class C {
-  static final f = '';
-  var g = 0;
+  static const fs1 = 1;
+  static final fs2 = 2;
+  static var   fs3 = 3;
+  static final fs4;
+  const fi1 = 1;
+  final fi2 = 2;
+  var   fi3 = 3;
+  final fi4;
 }
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5,
+    computeResult(target, PROPAGABLE_VARIABLES_IN_UNIT,
         matcher: isPartiallyResolveUnitReferencesTask);
-    // Test the outputs
-    expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(4));
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
-    expect(unit, same(outputs[RESOLVED_UNIT5]));
-    // Test the state of the AST
-    TopLevelVariableDeclaration a = unit.declarations[0];
-    VariableDeclaration variableA = a.variables.variables[0];
-    SimpleIdentifier initializer = variableA.initializer;
-    expect(initializer.staticElement, isNotNull);
+    // PROPAGABLE_VARIABLES_IN_UNIT
+    List<VariableElement> variables = outputs[PROPAGABLE_VARIABLES_IN_UNIT];
+    expect(variables.map((v) => v.displayName),
+        unorderedEquals(['t1', 't2', 'fs1', 'fs2', 'fi1', 'fi2']));
   }
 
-  test_perform_importExport() {
+  test_perform_strong_importExport() {
     newSource(
         '/a.dart',
         '''
@@ -2886,7 +3217,40 @@
     expect(methodElement, isNull);
   }
 
-  test_perform_notResolved() {
+  test_perform_strong_inferable() {
+    enableStrongMode();
+    Source source = newSource(
+        '/test.dart',
+        '''
+int a = b;
+int b = c;
+var d = 0;
+class A {}
+class C {
+  static final f = '';
+  var g = 0;
+}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT5,
+        matcher: isPartiallyResolveUnitReferencesTask);
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    // INFERABLE_STATIC_VARIABLES_IN_UNIT
+    {
+      List<VariableElement> variables =
+          outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT];
+      expect(variables, hasLength(4));
+      expect(variables.map((v) => v.displayName),
+          unorderedEquals(['a', 'b', 'd', 'f']));
+    }
+    // Test the state of the AST
+    TopLevelVariableDeclaration a = unit.declarations[0];
+    VariableDeclaration variableA = a.variables.variables[0];
+    SimpleIdentifier initializer = variableA.initializer;
+    expect(initializer.staticElement, isNotNull);
+  }
+
+  test_perform_strong_notResolved() {
     enableStrongMode();
     Source source = newSource(
         '/test.dart',
@@ -2953,6 +3317,138 @@
 }
 
 @reflectiveTest
+class PropagateVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT6);
+    expect(outputs[RESOLVED_UNIT6], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT6], isTrue);
+  }
+
+  void test_perform_cycle() {
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+final piFirst = true;
+final pi = piFirst ? 3.14 : tau / 2;
+final tau = piFirst ? pi * 2 : 6.28;
+''');
+    // compute
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
+        matcher: isPropagateVariableTypesInUnitTask);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
+    // verify
+    TopLevelVariableElement piFirst =
+        AstFinder.getTopLevelVariableElement(unit, 'piFirst');
+    TopLevelVariableElement pi =
+        AstFinder.getTopLevelVariableElement(unit, 'pi');
+    TopLevelVariableElement tau =
+        AstFinder.getTopLevelVariableElement(unit, 'tau');
+    expect(piFirst.propagatedType, context.typeProvider.boolType);
+    expect(pi.propagatedType, isNull);
+    expect(tau.propagatedType, isNull);
+  }
+
+  void test_perform_topLevel() {
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+//final a = b + c.length;
+final a = b;
+final b = 1;
+final c = '2';
+''');
+    // compute
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
+        matcher: isPropagateVariableTypesInUnitTask);
+    CompilationUnit unit = outputs[RESOLVED_UNIT6];
+    // verify
+    InterfaceType intType = context.typeProvider.intType;
+    InterfaceType stringType = context.typeProvider.stringType;
+    expect(AstFinder.getTopLevelVariableElement(unit, 'a').propagatedType,
+        intType);
+    expect(AstFinder.getTopLevelVariableElement(unit, 'b').propagatedType,
+        intType);
+    expect(AstFinder.getTopLevelVariableElement(unit, 'c').propagatedType,
+        stringType);
+  }
+}
+
+@reflectiveTest
+class PropagateVariableTypeTaskTest extends _AbstractDartTaskTest {
+  void test_perform_cycle() {
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+final piFirst = true;
+final pi = piFirst ? 3.14 : tau / 2;
+final tau = piFirst ? pi * 2 : 6.28;
+''');
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    TopLevelVariableElement piFirst =
+        AstFinder.getTopLevelVariableElement(unit, 'piFirst');
+    TopLevelVariableElement pi =
+        AstFinder.getTopLevelVariableElement(unit, 'pi');
+    TopLevelVariableElement tau =
+        AstFinder.getTopLevelVariableElement(unit, 'tau');
+    // compute
+    computeResult(piFirst, PROPAGATED_VARIABLE,
+        matcher: isPropagateVariableTypeTask);
+    expect(piFirst.propagatedType, context.typeProvider.boolType);
+    expect(pi.propagatedType, isNull);
+    expect(tau.propagatedType, isNull);
+  }
+
+  void test_perform_null() {
+    enableStrongMode();
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+var a = null;
+''');
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    TopLevelVariableElement a = AstFinder.getTopLevelVariableElement(unit, 'a');
+    // compute
+    computeResult(a, PROPAGATED_VARIABLE, matcher: isPropagateVariableTypeTask);
+    expect(a.propagatedType, isNull);
+  }
+
+  void test_perform_topLevel() {
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+final a = b + c.length;
+final b = 1;
+final c = '2';
+''');
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
+    CompilationUnit unit = outputs[RESOLVED_UNIT5];
+    TopLevelVariableElement elementA =
+        AstFinder.getTopLevelVariableElement(unit, 'a');
+    TopLevelVariableElement elementB =
+        AstFinder.getTopLevelVariableElement(unit, 'b');
+    TopLevelVariableElement elementC =
+        AstFinder.getTopLevelVariableElement(unit, 'c');
+    // compute
+    computeResult(elementA, PROPAGATED_VARIABLE,
+        matcher: isPropagateVariableTypeTask);
+    InterfaceType intType = context.typeProvider.intType;
+    InterfaceType stringType = context.typeProvider.stringType;
+    expect(elementA.propagatedType, intType);
+    expect(elementB.propagatedType, intType);
+    expect(elementC.propagatedType, stringType);
+  }
+}
+
+@reflectiveTest
 class ResolveInstanceFieldsInUnitTaskTest extends _AbstractDartTaskTest {
   @override
   void setUp() {
@@ -2960,6 +3456,19 @@
     enableStrongMode();
   }
 
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT8);
+    expect(outputs[RESOLVED_UNIT8], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
+  }
+
   // Test inference of instance fields across units
   void test_perform_inference_cross_unit_instance() {
     List<Source> sources = newSources({
@@ -2987,35 +3496,34 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT8);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT8];
 
     // B.b2 shoud be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT8);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT8];
 
     // B.b2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b2"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
 
     // A.a2 should now be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT8);
 
     // A.a2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), intType, intType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b2"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
   }
 
   // Test inference of instance fields across units
@@ -3042,24 +3550,22 @@
           }
     '''
     });
-    InterfaceType intType = context.typeProvider.intType;
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT8);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT8];
 
     // A.a2 should now be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT8);
 
-    // A.a2 should now be fully resolved and inferred.
+    // A.a2 should now be fully resolved and inferred (but not re-resolved).
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
   }
 
   // Test inference of instance fields across units with cycles
@@ -3093,41 +3599,40 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT8);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT8];
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b1"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT8);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT8];
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a1"), intType, intType);
+        AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b1"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b2"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT8);
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a1"), intType, intType);
+        AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), intType, intType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b1"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b2"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
   }
 
   // Test inference between static and instance fields
@@ -3156,28 +3661,53 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT8);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT8];
 
     // A.a2 should now be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
 
     // B.b2 shoud be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "B", "b2"), dynamicType, intType);
+        AstFinder.getFieldInClass(unit0, "B", "b2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT7];
+        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT8);
 
-    // A.a2 should now be fully resolved and inferred.
+    // A.a2 should now be fully resolved and inferred (but not re-resolved).
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
 
     // B.b2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "B", "b2"), intType, intType);
+        AstFinder.getFieldInClass(unit0, "B", "b2"), intType, intType);
+  }
+}
+
+@reflectiveTest
+class ResolveLibraryTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    Source sourceLib = newSource(
+        '/my_lib.dart',
+        '''
+library my_lib;
+const a = new A();
+class A {
+  const A();
+}
+@a
+class C {}
+''');
+    computeResult(sourceLib, LIBRARY_ELEMENT, matcher: isResolveLibraryTask);
+    // validate
+    LibraryElement library = outputs[LIBRARY_ELEMENT];
+    ClassElement classC = library.getType('C');
+    List<ElementAnnotation> metadata = classC.metadata;
+    expect(metadata, hasLength(1));
+    ElementAnnotation annotation = metadata[0];
+    expect(annotation, isNotNull);
+    expect((annotation as ElementAnnotationImpl).evaluationResult, isNotNull);
   }
 }
 
@@ -3244,6 +3774,19 @@
 
 @reflectiveTest
 class ResolveUnitTaskTest extends _AbstractDartTaskTest {
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT10);
+    expect(outputs[RESOLVED_UNIT10], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
+  }
+
   void test_perform() {
     AnalysisTarget source = newSource(
         '/test.dart',
@@ -3258,9 +3801,9 @@
   }
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10,
         matcher: isResolveUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
 
     FunctionDeclaration f = unit.declarations[0];
     _assertResolved(f.functionExpression.body);
@@ -3271,6 +3814,33 @@
     expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
   }
 
+  void test_perform_ensurePropagatedVariableTypes() {
+    newSource(
+        '/lib.dart',
+        '''
+class A {
+  final v = 1;
+}
+''');
+    AnalysisTarget source = newSource(
+        '/test.dart',
+        '''
+import 'lib.dart';
+main(A a) {
+  a.v.isEven;
+}
+''');
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10,
+        matcher: isResolveUnitTask);
+    expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
+    FunctionDeclaration main = unit.declarations[0];
+    BlockFunctionBody body = main.functionExpression.body;
+    ExpressionStatement statement = body.block.statements.single;
+    Expression expression = statement.expression;
+    expect(expression.bestType, context.typeProvider.boolType);
+  }
+
   void _assertResolved(FunctionBody body) {
     ResolutionVerifier verifier = new ResolutionVerifier();
     body.accept(verifier);
@@ -3280,6 +3850,19 @@
 
 @reflectiveTest
 class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest {
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT3);
+    expect(outputs[RESOLVED_UNIT3], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT3], isTrue);
+  }
+
   test_perform() {
     Source source = newSource(
         '/test.dart',
@@ -3379,6 +3962,19 @@
     expect(variable.isPotentiallyMutatedInScope, mutatedInScope);
   }
 
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT4);
+    expect(outputs[RESOLVED_UNIT4], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT4], isTrue);
+  }
+
   test_perform_buildClosureLibraryElements() {
     Source source = newSource(
         '/test.dart',
@@ -3514,14 +4110,18 @@
 var pi = piFirst ? 3.14 : tau / 2;
 var tau = piFirst ? pi * 2 : 6.28;
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
     VariableElement piFirst =
-        getTopLevelVariable(unit, 'piFirst').name.staticElement;
-    VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement;
-    VariableElement tau = getTopLevelVariable(unit, 'tau').name.staticElement;
-    Expression piFirstUse = (getTopLevelVariable(unit, 'tau').initializer
-        as ConditionalExpression).condition;
+        AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
+    VariableElement pi =
+        AstFinder.getTopLevelVariable(unit, 'pi').name.staticElement;
+    VariableElement tau =
+        AstFinder.getTopLevelVariable(unit, 'tau').name.staticElement;
+    Expression piFirstUse = (AstFinder
+            .getTopLevelVariable(unit, 'tau')
+            .initializer as ConditionalExpression)
+        .condition;
 
     expect(piFirstUse.staticType, context.typeProvider.boolType);
     expect(piFirst.type, context.typeProvider.boolType);
@@ -3553,26 +4153,26 @@
           }
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT10);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT9];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT10);
+    CompilationUnit unit2 = outputs[RESOLVED_UNIT10];
 
     InterfaceType intType = context.typeProvider.intType;
 
     assertVariableDeclarationTypes(
-        getTopLevelVariable(unit1, "x"), intType, intType);
+        AstFinder.getTopLevelVariable(unit1, "x"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "A", "x"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "A", "x"), intType, intType);
 
     assertVariableDeclarationTypes(
-        getTopLevelVariable(unit2, "y"), intType, intType);
+        AstFinder.getTopLevelVariable(unit2, "y"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit2, "B", "y"), intType, intType);
+        AstFinder.getFieldInClass(unit2, "B", "y"), intType, intType);
 
     List<Statement> statements =
-        getStatementsInTopLevelFunction(unit2, "test1");
+        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");
 
     assertAssignmentStatementTypes(statements[1], intType, intType);
     assertAssignmentStatementTypes(statements[2], intType, intType);
@@ -3604,7 +4204,7 @@
     '''
     });
     List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT9).toList();
+        computeLibraryResults(sources, RESOLVED_UNIT10).toList();
     CompilationUnit unit0 = units[0];
     CompilationUnit unit1 = units[1];
     CompilationUnit unit2 = units[2];
@@ -3612,13 +4212,13 @@
     InterfaceType intType = context.typeProvider.intType;
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), intType, intType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b2"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
 
     List<Statement> statements =
-        getStatementsInTopLevelFunction(unit2, "test1");
+        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");
 
     assertAssignmentStatementTypes(statements[1], intType, intType);
   }
@@ -3651,18 +4251,21 @@
     '''
     });
     List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT9).toList();
+        computeLibraryResults(sources, RESOLVED_UNIT10).toList();
     CompilationUnit unit0 = units[0];
-    CompilationUnit unit1 = units[1];
     CompilationUnit unit2 = units[2];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
 
     assertVariableDeclarationStatementTypes(
-        getStatementsInTopLevelFunction(unit0, "foo")[0], stringType, intType);
+        AstFinder.getStatementsInTopLevelFunction(unit0, "foo")[0],
+        stringType,
+        intType);
     assertVariableDeclarationStatementTypes(
-        getStatementsInTopLevelFunction(unit2, "foo")[0], stringType, intType);
+        AstFinder.getStatementsInTopLevelFunction(unit2, "foo")[0],
+        stringType,
+        intType);
   }
 
   // Test inference interactions between local variables and top level
@@ -3689,27 +4292,27 @@
           }
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT10);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT9];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT10);
+    CompilationUnit unit2 = outputs[RESOLVED_UNIT10];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
 
     assertVariableDeclarationTypes(
-        getTopLevelVariable(unit1, "x"), intType, intType);
+        AstFinder.getTopLevelVariable(unit1, "x"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "A", "x"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "A", "x"), intType, intType);
 
     assertVariableDeclarationTypes(
-        getTopLevelVariable(unit2, "y"), intType, intType);
+        AstFinder.getTopLevelVariable(unit2, "y"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit2, "B", "y"), intType, intType);
+        AstFinder.getFieldInClass(unit2, "B", "y"), intType, intType);
 
     List<Statement> statements =
-        getStatementsInTopLevelFunction(unit2, "test1");
+        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");
 
     assertAssignmentStatementTypes(statements[0], intType, stringType);
     assertAssignmentStatementTypes(statements[1], intType, stringType);
@@ -3743,7 +4346,7 @@
     '''
     });
     List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT9).toList();
+        computeLibraryResults(sources, RESOLVED_UNIT10).toList();
     CompilationUnit unit0 = units[0];
     CompilationUnit unit1 = units[1];
     CompilationUnit unit2 = units[2];
@@ -3751,17 +4354,17 @@
     InterfaceType intType = context.typeProvider.intType;
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a1"), intType, intType);
+        AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit0, "A", "a2"), intType, intType);
+        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b1"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit1, "B", "b2"), intType, intType);
+        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
 
     List<Statement> statements =
-        getStatementsInTopLevelFunction(unit2, "test1");
+        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");
 
     assertAssignmentStatementTypes(statements[1], intType, intType);
     assertAssignmentStatementTypes(statements[2], intType, intType);
@@ -3779,13 +4382,14 @@
         y = "hi";
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
 
-    List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test");
 
     assertVariableDeclarationStatementTypes(statements[0], intType, intType);
     assertAssignmentStatementTypes(statements[1], intType, stringType);
@@ -3817,13 +4421,14 @@
         final z = 42; // should infer `int`
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
 
-    List<Statement> statements = getStatementsInMethod(unit, "A", "test1");
+    List<Statement> statements =
+        AstFinder.getStatementsInMethod(unit, "A", "test1");
 
     assertVariableDeclarationStatementTypes(statements[0], intType, intType);
     assertAssignmentStatementTypes(statements[1], intType, stringType);
@@ -3838,9 +4443,9 @@
     assertAssignmentStatementTypes(statements[8], intType, intType);
 
     assertVariableDeclarationTypes(
-        getFieldInClass(unit, "A", "x"), intType, intType);
+        AstFinder.getFieldInClass(unit, "A", "x"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit, "A", "z"), intType, intType);
+        AstFinder.getFieldInClass(unit, "A", "z"), intType, intType);
   }
 
   // Test inference of instance fields across units
@@ -3865,13 +4470,14 @@
       int y = 0; // field def after use
       final z = 42; // should infer `int`
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
 
-    List<Statement> statements = getStatementsInTopLevelFunction(unit, "test1");
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test1");
 
     assertVariableDeclarationStatementTypes(statements[0], intType, intType);
     assertAssignmentStatementTypes(statements[1], intType, stringType);
@@ -3886,11 +4492,11 @@
     assertAssignmentStatementTypes(statements[8], intType, intType);
 
     assertVariableDeclarationTypes(
-        getTopLevelVariable(unit, "x"), intType, intType);
+        AstFinder.getTopLevelVariable(unit, "x"), intType, intType);
     assertVariableDeclarationTypes(
-        getTopLevelVariable(unit, "y"), intType, intType);
+        AstFinder.getTopLevelVariable(unit, "y"), intType, intType);
     assertVariableDeclarationTypes(
-        getTopLevelVariable(unit, "z"), intType, intType);
+        AstFinder.getTopLevelVariable(unit, "z"), intType, intType);
   }
 
   // Test inference between static and instance fields
@@ -3917,8 +4523,8 @@
         new A().y2 = /*severe:StaticTypeError*/"hi";
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -3926,19 +4532,20 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     assertVariableDeclarationTypes(
-        getTopLevelVariable(unit, "x"), dynamicType, bottomType);
+        AstFinder.getTopLevelVariable(unit, "x"), dynamicType, bottomType);
     assertVariableDeclarationTypes(
-        getTopLevelVariable(unit, "y"), intType, intType);
+        AstFinder.getTopLevelVariable(unit, "y"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit, "A", "x"), dynamicType, bottomType);
+        AstFinder.getFieldInClass(unit, "A", "x"), dynamicType, bottomType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit, "A", "y"), intType, intType);
+        AstFinder.getFieldInClass(unit, "A", "y"), intType, intType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit, "A", "x2"), dynamicType, bottomType);
+        AstFinder.getFieldInClass(unit, "A", "x2"), dynamicType, bottomType);
     assertVariableDeclarationTypes(
-        getFieldInClass(unit, "A", "y2"), intType, intType);
+        AstFinder.getFieldInClass(unit, "A", "y2"), intType, intType);
 
-    List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test");
 
     assertAssignmentStatementTypes(statements[0], dynamicType, stringType);
     assertAssignmentStatementTypes(statements[1], intType, stringType);
@@ -3958,13 +4565,14 @@
         x = "hi";
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
 
-    List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test");
     VariableDeclaration decl =
         (statements[0] as VariableDeclarationStatement).variables.variables[0];
     expect(decl.element.type, intType);
@@ -3985,6 +4593,19 @@
     enableStrongMode();
   }
 
+  test_created_resolved_unit() {
+    Source source = newSource(
+        '/test.dart',
+        r'''
+library lib;
+class A {}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT);
+    expect(outputs[RESOLVED_UNIT], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT], isTrue);
+  }
+
   void test_perform_recordDynamicInvoke() {
     enableStrongMode();
     AnalysisTarget source = newSource(
@@ -4002,7 +4623,8 @@
     _fillErrorListener(STRONG_MODE_ERRORS);
     expect(errorListener.errors, isEmpty);
 
-    List<Statement> statements = getStatementsInTopLevelFunction(unit, "main");
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
     ExpressionStatement statement = statements[1];
     IndexExpression idx = statement.expression;
     expect(DynamicInvoke.get(idx.target), isNotNull);
@@ -4026,7 +4648,7 @@
 
     var errors = errorListener.errors;
     expect(errors.length, 1);
-    expect(errors[0].errorCode.name, "dev_compiler.StaticTypeError");
+    expect(errors[0].errorCode.name, "STRONG_MODE_STATIC_TYPE_ERROR");
   }
 }
 
@@ -4049,6 +4671,27 @@
     ]);
   }
 
+  test_perform_ConstantValidator_duplicateFields() {
+    Source source = newSource(
+        '/test.dart',
+        '''
+class Test {
+  final int x = 1;
+  final int x = 2;
+  const Test();
+}
+
+main() {
+  const Test();
+}
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
+    // validate
+    _fillErrorListener(VERIFY_ERRORS);
+    errorListener.assertNoErrors();
+  }
+
   test_perform_directiveError() {
     Source source = newSource(
         '/test.dart',
@@ -4195,114 +4838,6 @@
     context.analysisOptions = options;
   }
 
-  /**
-   * Return the declaration of the class with the given [className] in the given
-   * compilation [unit].
-   */
-  ClassDeclaration getClass(CompilationUnit unit, String className) {
-    NodeList<CompilationUnitMember> unitMembers = unit.declarations;
-    for (CompilationUnitMember unitMember in unitMembers) {
-      if (unitMember is ClassDeclaration && unitMember.name.name == className) {
-        return unitMember;
-      }
-    }
-    fail('No class named $className in ${unit.element.source}');
-    return null;
-  }
-
-  /**
-   * Return the declaration of the field with the given [fieldName] in the class
-   * with the given [className] in the given compilation [unit].
-   */
-  VariableDeclaration getFieldInClass(
-      CompilationUnit unit, String className, String fieldName) {
-    ClassDeclaration unitMember = getClass(unit, className);
-    NodeList<ClassMember> classMembers = unitMember.members;
-    for (ClassMember classMember in classMembers) {
-      if (classMember is FieldDeclaration) {
-        NodeList<VariableDeclaration> fields = classMember.fields.variables;
-        for (VariableDeclaration field in fields) {
-          if (field.name.name == fieldName) {
-            return field;
-          }
-        }
-      }
-    }
-    fail('No field named $fieldName in $className');
-    return null;
-  }
-
-  /**
-   * Return the declaration of the method with the given [methodName] in the
-   * class with the given [className] in the given compilation [unit].
-   */
-  MethodDeclaration getMethodInClass(
-      CompilationUnit unit, String className, String methodName) {
-    ClassDeclaration unitMember = getClass(unit, className);
-    NodeList<ClassMember> classMembers = unitMember.members;
-    for (ClassMember classMember in classMembers) {
-      if (classMember is MethodDeclaration) {
-        if (classMember.name.name == methodName) {
-          return classMember;
-        }
-      }
-    }
-    fail('No method named $methodName in $className');
-    return null;
-  }
-
-  List<Statement> getStatementsInMethod(
-      CompilationUnit unit, String className, String methodName) {
-    MethodDeclaration method = getMethodInClass(unit, className, methodName);
-    BlockFunctionBody body = method.body;
-    return body.block.statements;
-  }
-
-  List<Statement> getStatementsInTopLevelFunction(
-      CompilationUnit unit, String functionName) {
-    FunctionDeclaration function = getTopLevelFunction(unit, functionName);
-    BlockFunctionBody body = function.functionExpression.body;
-    return body.block.statements;
-  }
-
-  /**
-   * Return the declaration of the top-level function with the given
-   * [functionName] in the given compilation [unit].
-   */
-  FunctionDeclaration getTopLevelFunction(
-      CompilationUnit unit, String functionName) {
-    NodeList<CompilationUnitMember> unitMembers = unit.declarations;
-    for (CompilationUnitMember unitMember in unitMembers) {
-      if (unitMember is FunctionDeclaration) {
-        if (unitMember.name.name == functionName) {
-          return unitMember;
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return the declaration of the top-level variable with the given
-   * [variableName] in the given compilation [unit].
-   */
-  VariableDeclaration getTopLevelVariable(
-      CompilationUnit unit, String variableName) {
-    NodeList<CompilationUnitMember> unitMembers = unit.declarations;
-    for (CompilationUnitMember unitMember in unitMembers) {
-      if (unitMember is TopLevelVariableDeclaration) {
-        NodeList<VariableDeclaration> variables =
-            unitMember.variables.variables;
-        for (VariableDeclaration variable in variables) {
-          if (variable.name.name == variableName) {
-            return variable;
-          }
-        }
-      }
-    }
-    return null;
-  }
-
   void setUp() {
     super.setUp();
     emptySource = newSource('/test.dart');
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 a10cfef..7938cc9 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.dart_work_manager_test;
+library analyzer.test.src.task.dart_work_manager_test;
 
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/ast.dart';
@@ -210,8 +210,8 @@
   }
 
   void test_applyPriorityTargets_isLibrary_computeErrors() {
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
-    when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
     entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
     entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
     entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
@@ -234,8 +234,8 @@
   }
 
   void test_applyPriorityTargets_isLibrary_computeUnit() {
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(false);
-    when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(false);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(false);
+    when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(false);
     entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
     entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
     entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
@@ -593,8 +593,8 @@
     entry1.setValue(SCAN_ERRORS, <AnalysisError>[error1], []);
     entry1.setValue(PARSE_ERRORS, <AnalysisError>[error2], []);
     // PARSED_UNIT is ready, set errors
-    manager.resultsComputed(
-        source1, {PARSED_UNIT: AstFactory.compilationUnit()});
+    manager
+        .resultsComputed(source1, {PARSED_UNIT: AstFactory.compilationUnit()});
     // all of the errors are included
     ChangeNoticeImpl notice = context.getNotice(source1);
     expect(notice.errors, unorderedEquals([error1, error2]));
@@ -611,8 +611,7 @@
     expect(cache.getState(part1, CONTAINING_LIBRARIES), CacheState.VALID);
     // configure AnalysisContext mock
     when(context.prioritySources).thenReturn(<Source>[]);
-    when(context.shouldErrorsBeAnalyzed(anyObject, anyObject))
-        .thenReturn(false);
+    when(context.shouldErrorsBeAnalyzed(anyObject)).thenReturn(false);
     // library1 parts
     manager.resultsComputed(library1, {
       INCLUDED_PARTS: [part1, part2],
@@ -705,7 +704,7 @@
   void test_resultsComputed_sourceKind_isLibrary() {
     manager.unknownSourceQueue.addAll([source1, source2, source3]);
     when(context.prioritySources).thenReturn(<Source>[]);
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
     manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
     expect_librarySourceQueue([source2]);
     expect_unknownSourceQueue([source1, source3]);
@@ -714,7 +713,7 @@
   void test_resultsComputed_sourceKind_isLibrary_isPriority_computeErrors() {
     manager.unknownSourceQueue.addAll([source1, source2, source3]);
     when(context.prioritySources).thenReturn(<Source>[source2]);
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
     manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
     expect_unknownSourceQueue([source1, source3]);
     expect(manager.priorityResultQueue,
@@ -724,7 +723,7 @@
   void test_resultsComputed_sourceKind_isLibrary_isPriority_computeUnit() {
     manager.unknownSourceQueue.addAll([source1, source2, source3]);
     when(context.prioritySources).thenReturn(<Source>[source2]);
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(false);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(false);
     manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
     expect_unknownSourceQueue([source1, source3]);
     expect(
@@ -762,13 +761,9 @@
   }
 }
 
-class _DartSdkMock extends TypedMock implements DartSdk {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _DartSdkMock extends TypedMock implements DartSdk {}
 
-class _DartWorkManagerMock extends TypedMock implements DartWorkManager {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _DartWorkManagerMock extends TypedMock implements DartWorkManager {}
 
 class _InternalAnalysisContextMock extends TypedMock
     implements InternalAnalysisContext {
@@ -800,20 +795,15 @@
     return _pendingNotices.putIfAbsent(
         source, () => new ChangeNoticeImpl(source));
   }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class _SourceFactoryMock extends TypedMock implements SourceFactory {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _SourceFactoryMock extends TypedMock implements SourceFactory {}
 
 class _SourceMock extends TypedMock implements Source {
   final String shortName;
   _SourceMock(this.shortName);
   @override
   String get fullName => '/' + shortName;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
   @override
   String toString() => fullName;
 }
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index aed091c..221636a 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -2,16 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.driver_test;
+library analyzer.test.src.task.driver_test;
 
 import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide
-        AnalysisCache,
-        AnalysisContextImpl,
-        AnalysisTask,
-        UniversalCachePartition,
-        WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/inputs.dart';
@@ -42,6 +36,7 @@
   void setUp() {
     context = new _InternalAnalysisContextMock();
     analysisDriver = new AnalysisDriver(taskManager, workManagers, context);
+    when(context.aboutToComputeResult(anyObject, anyObject)).thenReturn(false);
   }
 }
 
@@ -350,7 +345,7 @@
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target,
         descriptor: descriptor, value: 42);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
 
     bool streamNotified = false;
     analysisDriver.onResultComputed(result).listen((event) {
@@ -374,7 +369,7 @@
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target,
         descriptor: descriptor, exception: exception);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
 
     analysisDriver.performWorkItem(item);
     CacheEntry targetEntry = context.getCacheEntry(item.target);
@@ -389,7 +384,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, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
 
     analysisDriver.performWorkItem(item);
     CacheEntry targetEntry = context.getCacheEntry(item.target);
@@ -407,7 +402,7 @@
         [result]);
     CaughtException exception =
         new CaughtException(new AnalysisException(), null);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     item.exception = exception;
 
     analysisDriver.performWorkItem(item);
@@ -423,8 +418,8 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {'one': inputResult.of(target)},
         [new ResultDescriptor('output', null)]);
-    analysisDriver.currentWorkOrder =
-        new WorkOrder(taskManager, new WorkItem(null, null, descriptor, null));
+    analysisDriver.currentWorkOrder = new WorkOrder(
+        taskManager, new WorkItem(null, null, descriptor, null, 0, null));
 
     analysisDriver.reset();
     expect(analysisDriver.currentWorkOrder, isNull);
@@ -622,7 +617,7 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     AnalysisTask task = item.buildTask();
     expect(task, isNotNull);
   }
@@ -639,7 +634,7 @@
             new TestAnalysisTask(context, target, results: outputResults),
         (target) => {'one': inputResult.of(target)},
         outputResults);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     expect(() => item.buildTask(), throwsStateError);
   }
 
@@ -647,7 +642,7 @@
     AnalysisTarget target = new TestSource();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (target) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     expect(item, isNotNull);
     expect(item.context, context);
     expect(item.descriptor, descriptor);
@@ -661,7 +656,7 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     WorkItem result = item.gatherInputs(taskManager, []);
     expect(result, isNull);
     expect(item.exception, isNull);
@@ -686,7 +681,7 @@
     taskManager.addTaskDescriptor(task1);
     taskManager.addTaskDescriptor(task2);
     // gather inputs
-    WorkItem item = new WorkItem(context, target, task2, null);
+    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
     WorkItem inputItem = item.gatherInputs(taskManager, []);
     expect(inputItem, isNotNull);
   }
@@ -699,11 +694,66 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {'one': inputResult.of(target)},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     WorkItem result = item.gatherInputs(taskManager, []);
     expect(result, isNull);
     expect(item.exception, isNotNull);
   }
+
+  test_gatherInputs_aboutToComputeResult_hasResult() {
+    AnalysisTarget target = new TestSource();
+    ResultDescriptor resultA = new ResultDescriptor('resultA', null);
+    ResultDescriptor resultB = new ResultDescriptor('resultB', null);
+    // prepare tasks
+    TaskDescriptor task1 = new TaskDescriptor(
+        'task',
+        (context, target) =>
+            new TestAnalysisTask(context, target, results: [resultA]),
+        (target) => {},
+        [resultA]);
+    TaskDescriptor task2 = new TaskDescriptor(
+        'task',
+        (context, target) => new TestAnalysisTask(context, target),
+        (target) => {'one': resultA.of(target)},
+        [resultB]);
+    taskManager.addTaskDescriptor(task1);
+    taskManager.addTaskDescriptor(task2);
+    // configure mocks
+    when(context.aboutToComputeResult(anyObject, resultA)).thenReturn(true);
+    // gather inputs
+    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
+    WorkItem inputItem = item.gatherInputs(taskManager, []);
+    expect(inputItem, isNull);
+  }
+
+  test_gatherInputs_aboutToComputeResult_noResult() {
+    AnalysisTarget target = new TestSource();
+    ResultDescriptor resultA = new ResultDescriptor('resultA', null);
+    ResultDescriptor resultB = new ResultDescriptor('resultB', null);
+    // prepare tasks
+    TaskDescriptor task1 = new TaskDescriptor(
+        'task',
+        (context, target) =>
+            new TestAnalysisTask(context, target, results: [resultA]),
+        (target) => {},
+        [resultA]);
+    TaskDescriptor task2 = new TaskDescriptor(
+        'task',
+        (context, target) => new TestAnalysisTask(context, target),
+        (target) => {'one': resultA.of(target)},
+        [resultB]);
+    taskManager.addTaskDescriptor(task1);
+    taskManager.addTaskDescriptor(task2);
+    // configure ResultProvider
+    // configure mocks
+    when(context.aboutToComputeResult(anyObject, resultA)).thenReturn(false);
+    // gather inputs
+    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
+    WorkItem inputItem = item.gatherInputs(taskManager, []);
+    expect(inputItem, isNotNull);
+    expect(inputItem.target, target);
+    expect(inputItem.descriptor, task1);
+  }
 }
 
 @reflectiveTest
@@ -712,8 +762,8 @@
     TaskManager manager = new TaskManager();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
-    WorkOrder order =
-        new WorkOrder(manager, new WorkItem(null, null, descriptor, null));
+    WorkOrder order = new WorkOrder(
+        manager, new WorkItem(null, null, descriptor, null, 0, null));
     expect(order, isNotNull);
     expect(order.currentItems, isNull);
     expect(order.current, isNull);
@@ -723,7 +773,7 @@
     TaskManager manager = new TaskManager();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem workItem = new WorkItem(null, null, descriptor, null);
+    WorkItem workItem = new WorkItem(null, null, descriptor, null, 0, null);
     WorkOrder order = new WorkOrder(manager, workItem);
     // "item" has no child items
     expect(order.moveNext(), isTrue);
@@ -761,8 +811,6 @@
     }
     return entry;
   }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /**
@@ -788,6 +836,4 @@
   }
 }
 
-class _WorkManagerMock extends TypedMock implements WorkManager {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _WorkManagerMock extends TypedMock implements WorkManager {}
diff --git a/pkg/analyzer/test/src/task/general_test.dart b/pkg/analyzer/test/src/task/general_test.dart
index b335664..da4c462 100644
--- a/pkg/analyzer/test/src/task/general_test.dart
+++ b/pkg/analyzer/test/src/task/general_test.dart
@@ -2,10 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.general_test;
+library analyzer.test.src.task.general_test;
 
-import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisTask, GetContentTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/general.dart';
 import 'package:analyzer/task/general.dart';
@@ -81,6 +80,4 @@
   }
 }
 
-class _MockContext extends TypedMock implements AnalysisContext {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockContext extends TypedMock implements AnalysisContext {}
diff --git a/pkg/analyzer/test/src/task/html_test.dart b/pkg/analyzer/test/src/task/html_test.dart
index 0806e90..c8f1f97 100644
--- a/pkg/analyzer/test/src/task/html_test.dart
+++ b/pkg/analyzer/test/src/task/html_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.html_test;
+library analyzer.test.src.task.html_test;
 
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/html.dart';
@@ -303,15 +303,22 @@
     <title>test page</title>
   </head>
   <body>
-    <h1>Test</h1>
+    <h1 myAttr='my value'>Test</h1>
   </body>
 </html>
 ''';
     AnalysisTarget target = newSource('/test.html', code);
     computeResult(target, HTML_DOCUMENT);
     expect(task, isParseHtmlTask);
-    expect(outputs[HTML_DOCUMENT], isNotNull);
     expect(outputs[HTML_DOCUMENT_ERRORS], isEmpty);
+    // HTML_DOCUMENT
+    {
+      Document document = outputs[HTML_DOCUMENT];
+      expect(document, isNotNull);
+      // verify that attributes are not lower-cased
+      Element element = document.body.getElementsByTagName('h1').single;
+      expect(element.attributes['myAttr'], 'my value');
+    }
     // LINE_INFO
     {
       LineInfo lineInfo = outputs[LINE_INFO];
diff --git a/pkg/analyzer/test/src/task/html_work_manager_test.dart b/pkg/analyzer/test/src/task/html_work_manager_test.dart
index 0785f97..8d1d168 100644
--- a/pkg/analyzer/test/src/task/html_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/html_work_manager_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.html_work_manager_test;
+library analyzer.test.src.task.html_work_manager_test;
 
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/engine.dart'
@@ -110,8 +110,8 @@
   }
 
   void test_applyPriorityTargets() {
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
-    when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
     manager.priorityResultQueue.add(new TargetedResult(source1, HTML_ERRORS));
     manager.priorityResultQueue.add(new TargetedResult(source2, HTML_ERRORS));
     // -source1 +source3
@@ -346,6 +346,4 @@
     return _pendingNotices.putIfAbsent(
         source, () => new ChangeNoticeImpl(source));
   }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
index b495be7..114a452 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.incremental_element_builder_test;
+library analyzer.test.src.task.incremental_element_builder_test;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/incremental_element_builder.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
index 3943a99..be97598 100644
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ b/pkg/analyzer/test/src/task/inputs_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.inputs_test;
+library analyzer.test.src.task.inputs_test;
 
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/src/task/model.dart';
@@ -37,6 +37,7 @@
   ConstantTaskInputBuilder builder;
 
   void setUp() {
+    super.setUp();
     builder = new ConstantTaskInputBuilder(input);
   }
 
@@ -555,7 +556,7 @@
 }
 
 @reflectiveTest
-class ObjectToListTaskInputBuilderTest extends EngineTestCase {
+class ObjectToListTaskInputBuilderTest {
   static final AnalysisTarget target = new TestSource();
   static final ResultDescriptorImpl result =
       new ResultDescriptorImpl('result', null);
@@ -705,7 +706,7 @@
 }
 
 @reflectiveTest
-class SimpleTaskInputBuilderTest extends EngineTestCase {
+class SimpleTaskInputBuilderTest {
   static final AnalysisTarget target = new TestSource();
   static final ResultDescriptorImpl result =
       new ResultDescriptorImpl('result', null);
diff --git a/pkg/analyzer/test/src/task/manager_test.dart b/pkg/analyzer/test/src/task/manager_test.dart
index 783c015..e78cba4 100644
--- a/pkg/analyzer/test/src/task/manager_test.dart
+++ b/pkg/analyzer/test/src/task/manager_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.manager_test;
+library analyzer.test.src.task.manager_test;
 
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/task/manager.dart';
diff --git a/pkg/analyzer/test/src/task/model_test.dart b/pkg/analyzer/test/src/task/model_test.dart
index 00cdcfa..4db1ee2 100644
--- a/pkg/analyzer/test/src/task/model_test.dart
+++ b/pkg/analyzer/test/src/task/model_test.dart
@@ -2,9 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.model_test;
+library analyzer.test.src.task.model_test;
 
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/task/model.dart';
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 5dddc25..ebdca70 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -2,16 +2,18 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.options_test;
+library analyzer.test.src.task.options_test;
 
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:unittest/unittest.dart';
+import 'package:yaml/yaml.dart';
 
 import '../../generated/test_support.dart';
 import '../../reflective_tests.dart';
@@ -20,6 +22,7 @@
 
 main() {
   initializeTestEnvironment();
+  runReflectiveTests(ContextConfigurationTest);
   runReflectiveTests(GenerateOptionsErrorsTaskTest);
   runReflectiveTests(OptionsFileValidatorTest);
 }
@@ -28,10 +31,118 @@
     new isInstanceOf<GenerateOptionsErrorsTask>();
 
 @reflectiveTest
+class ContextConfigurationTest extends AbstractContextTest {
+  final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
+
+  AnalysisOptions get analysisOptions => context.analysisOptions;
+
+  configureContext(String optionsSource) =>
+      configureContextOptions(context, parseOptions(optionsSource));
+
+  Map<String, YamlNode> parseOptions(String source) =>
+      optionsProvider.getOptionsFromString(source);
+
+  test_configure_bad_options_contents() {
+    configureContext('''
+analyzer:
+  strong-mode:true # misformatted
+''');
+    expect(analysisOptions.strongMode, false);
+  }
+
+  test_configure_enableAsync() {
+    configureContext('''
+analyzer:
+  language:
+''');
+    expect(analysisOptions.enableAsync, true);
+  }
+
+  test_configure_enableAsync_false() {
+    configureContext('''
+analyzer:
+  language:
+    enableAsync: false
+''');
+    expect(analysisOptions.enableAsync, false);
+  }
+
+  test_configure_enableGenericMethods() {
+    expect(analysisOptions.enableGenericMethods, false);
+    configureContext('''
+analyzer:
+  language:
+    enableGenericMethods: true
+''');
+    expect(analysisOptions.enableGenericMethods, true);
+  }
+
+  test_configure_enableSuperMixins() {
+    configureContext('''
+analyzer:
+  language:
+    enableSuperMixins: true
+''');
+    expect(analysisOptions.enableSuperMixins, true);
+  }
+
+  test_configure_error_processors() {
+    configureContext('''
+analyzer:
+  errors:
+    invalid_assignment: ignore
+    unused_local_variable: error
+''');
+
+    List<ErrorProcessor> processors =
+        context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+    expect(processors, hasLength(2));
+
+    var unused_local = new AnalysisError(
+        new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+      ['x']
+    ]);
+    var invalid_assignment =
+        new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
+      ['x'],
+      ['y']
+    ]);
+
+    // ignore
+    var invalidAssignment =
+        processors.firstWhere((p) => p.appliesTo(invalid_assignment));
+    expect(invalidAssignment.severity, isNull);
+
+    // error
+    var unusedLocal = processors.firstWhere((p) => p.appliesTo(unused_local));
+    expect(unusedLocal.severity, ErrorSeverity.ERROR);
+  }
+
+  test_configure_strong_mode() {
+    configureContext('''
+analyzer:
+  strong-mode: true
+''');
+    expect(analysisOptions.strongMode, true);
+  }
+
+  test_configure_strong_mode_bad_value() {
+    configureContext('''
+analyzer:
+  strong-mode: foo
+''');
+    expect(analysisOptions.strongMode, false);
+  }
+}
+
+@reflectiveTest
 class GenerateOptionsErrorsTaskTest extends AbstractContextTest {
   final optionsFilePath = '/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';
 
   Source source;
+  LineInfo lineInfo(String source) =>
+      GenerateOptionsErrorsTask.computeLineInfo(source);
+
   @override
   setUp() {
     super.setUp();
@@ -46,6 +157,18 @@
         unorderedEquals([GenerateOptionsErrorsTask.CONTENT_INPUT_NAME]));
   }
 
+  test_compute_lineInfo() {
+    expect(lineInfo('foo\nbar').getLocation(4).lineNumber, 2);
+    expect(lineInfo('foo\nbar').getLocation(4).columnNumber, 1);
+    expect(lineInfo('foo\r\nbar').getLocation(5).lineNumber, 2);
+    expect(lineInfo('foo\r\nbar').getLocation(5).columnNumber, 1);
+    expect(lineInfo('foo\rbar').getLocation(4).lineNumber, 2);
+    expect(lineInfo('foo\rbar').getLocation(4).columnNumber, 1);
+    expect(lineInfo('foo').getLocation(0).lineNumber, 1);
+    expect(lineInfo('foo').getLocation(0).columnNumber, 1);
+    expect(lineInfo('').getLocation(1).lineNumber, 1);
+  }
+
   test_constructor() {
     GenerateOptionsErrorsTask task =
         new GenerateOptionsErrorsTask(context, source);
@@ -110,9 +233,12 @@
     expect(task, isGenerateOptionsErrorsTask);
     List<AnalysisError> errors = outputs[ANALYSIS_OPTIONS_ERRORS];
     expect(errors, hasLength(1));
-    expect(errors[0].errorCode, AnalysisOptionsWarningCode.UNSUPPORTED_OPTION);
-    expect(errors[0].message,
-        "The option 'not_supported' is not supported by analyzer");
+    expect(errors[0].errorCode,
+        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES);
+    expect(
+        errors[0].message,
+        "The option 'not_supported' is not supported by analyzer, supported "
+        "values are 'errors', 'exclude', 'language', 'plugins' and 'strong-mode'");
   }
 }
 
@@ -122,6 +248,79 @@
       new OptionsFileValidator(new TestSource());
   final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
 
+  test_analyzer_error_code_supported() {
+    validate(
+        '''
+analyzer:
+  errors:
+    unused_local_variable: ignore
+    invalid_assignment: warning
+    missing_return: error
+    dead_code: info
+''',
+        []);
+  }
+
+  test_analyzer_error_code_supported_bad_value() {
+    validate(
+        '''
+analyzer:
+  errors:
+    unused_local_variable: ftw
+    ''',
+        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
+  }
+
+  test_analyzer_error_code_unsupported() {
+    validate(
+        '''
+analyzer:
+  errors:
+    not_supported: ignore
+    ''',
+        [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
+  }
+
+  test_analyzer_language_supported() {
+    validate(
+        '''
+analyzer:
+  language:
+    enableSuperMixins: true
+''',
+        []);
+  }
+
+  test_analyzer_language_unsupported_key() {
+    validate(
+        '''
+analyzer:
+  language:
+    unsupported: true
+''',
+        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
+  }
+
+  test_analyzer_language_unsupported_value() {
+    validate(
+        '''
+analyzer:
+  language:
+    enableSuperMixins: foo
+''',
+        [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
+  }
+
+  test_analyzer_strong_mode_error_code_supported() {
+    validate(
+        '''
+analyzer:
+  errors:
+    strong_mode_assignment_cast: ignore
+''',
+        []);
+  }
+
   test_analyzer_supported_exclude() {
     validate(
         '''
@@ -141,13 +340,22 @@
         []);
   }
 
+  test_analyzer_supported_strong_mode_supported_bad_value() {
+    validate(
+        '''
+analyzer:
+  strong-mode: w00t
+    ''',
+        [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
+  }
+
   test_analyzer_unsupported_option() {
     validate(
         '''
 analyzer:
   not_supported: true
     ''',
-        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION]);
+        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
   }
 
   test_linter_supported_rules() {
@@ -166,7 +374,7 @@
 linter:
   unsupported: true
     ''',
-        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION]);
+        [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
   }
 
   void validate(String source, List<AnalysisOptionsErrorCode> expected) {
diff --git a/pkg/analyzer/test/src/task/options_work_manager_test.dart b/pkg/analyzer/test/src/task/options_work_manager_test.dart
index 424a729..cf6cac0 100644
--- a/pkg/analyzer/test/src/task/options_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/options_work_manager_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.options_work_manager_test;
+library analyzer.test.src.task.options_work_manager_test;
 
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/engine.dart'
@@ -111,8 +111,8 @@
   }
 
   void test_applyPriorityTargets() {
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
-    when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
     manager.priorityResultQueue
         .add(new TargetedResult(source1, ANALYSIS_OPTIONS_ERRORS));
     manager.priorityResultQueue
@@ -136,8 +136,8 @@
         source1, 1, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
     AnalysisError error2 = new AnalysisError(
         source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
-    entry1.setValue(
-        ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
+    entry1
+        .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
 
     List<AnalysisError> errors = manager.getErrors(source1);
     expect(errors, unorderedEquals([error1, error2]));
@@ -233,8 +233,8 @@
         source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
     LineInfo lineInfo = new LineInfo([0]);
     entry1.setValue(LINE_INFO, lineInfo, []);
-    entry1.setValue(
-        ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
+    entry1
+        .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
     // RESOLVED_UNIT is ready, set errors
     manager.resultsComputed(source1, {ANALYSIS_OPTIONS_ERRORS: null});
     // all of the errors are included
@@ -282,6 +282,4 @@
   @override
   ChangeNoticeImpl getNotice(Source source) =>
       _pendingNotices.putIfAbsent(source, () => new ChangeNoticeImpl(source));
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index aa51b50..55b73a8 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -5,7 +5,7 @@
 // TODO(jmesserly): this file needs to be refactored, it's a port from
 // package:dev_compiler's tests
 /// General type checking tests
-library test.src.task.strong.checker_test;
+library analyzer.test.src.task.strong.checker_test;
 
 import 'package:unittest/unittest.dart';
 
@@ -32,10 +32,15 @@
           // it requires inference to work because of dartbug.com/23381
           SplayTreeMap([int compare(K key1, K key2),
                         bool isValidKey(potentialKey)]) {
-            : _comparator = /*warning:DownCastComposite*/(compare == null) ? Comparable.compare : compare,
-              _validKey = /*info:InferredType should be pass*/(isValidKey != null) ? isValidKey : ((v) => true);
-              _Predicate<Object> _v = /*warning:DownCastComposite*/(isValidKey != null) ? isValidKey : ((v) => true);
-              _v = /*info:InferredType should be pass*/(isValidKey != null) ? _v : ((v) => true);
+            : _comparator = /*warning:DOWN_CAST_COMPOSITE*/(compare == null)
+                           ? Comparable.compare : compare,
+              _validKey = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
+                         ? isValidKey : ((v) => true);
+             _Predicate<Object> _v = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
+                                    ? isValidKey : (/*info:INFERRED_TYPE_CLOSURE*/(v) => true);
+        // TODO(leafp): Fix unimplemented LUB in analyzer
+        _v = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
+             ? _v : (/*info:INFERRED_TYPE_CLOSURE*/(v) => true);
           }
         }
         void main() {
@@ -44,9 +49,9 @@
           int i = 42;
 
           // Check the boolean conversion of the condition.
-          print((/*severe:StaticTypeError*/i) ? false : true);
-          print((/*info:DownCastImplicit*/obj) ? false : true);
-          print((/*info:DynamicCast*/dyn) ? false : true);
+          print((/*severe:STATIC_TYPE_ERROR*/i) ? false : true);
+          print((/*info:DOWN_CAST_IMPLICIT*/obj) ? false : true);
+          print((/*info:DYNAMIC_CAST*/dyn) ? false : true);
         }
       '''
   });
@@ -60,24 +65,24 @@
         bool b = false;
 
         if (b) {}
-        if (/*info:DynamicCast*/dyn) {}
-        if (/*info:DownCastImplicit*/obj) {}
-        if (/*severe:StaticTypeError*/i) {}
+        if (/*info:DYNAMIC_CAST*/dyn) {}
+        if (/*info:DOWN_CAST_IMPLICIT*/obj) {}
+        if (/*severe:STATIC_TYPE_ERROR*/i) {}
 
         while (b) {}
-        while (/*info:DynamicCast*/dyn) {}
-        while (/*info:DownCastImplicit*/obj) {}
-        while (/*severe:StaticTypeError*/i) {}
+        while (/*info:DYNAMIC_CAST*/dyn) {}
+        while (/*info:DOWN_CAST_IMPLICIT*/obj) {}
+        while (/*severe:STATIC_TYPE_ERROR*/i) {}
 
         do {} while (b);
-        do {} while (/*info:DynamicCast*/dyn);
-        do {} while (/*info:DownCastImplicit*/obj);
-        do {} while (/*severe:StaticTypeError*/i);
+        do {} while (/*info:DYNAMIC_CAST*/dyn);
+        do {} while (/*info:DOWN_CAST_IMPLICIT*/obj);
+        do {} while (/*severe:STATIC_TYPE_ERROR*/i);
 
         for (;b;) {}
-        for (;/*info:DynamicCast*/dyn;) {}
-        for (;/*info:DownCastImplicit*/obj;) {}
-        for (;/*severe:StaticTypeError*/i;) {}
+        for (;/*info:DYNAMIC_CAST*/dyn;) {}
+        for (;/*info:DOWN_CAST_IMPLICIT*/obj;) {}
+        for (;/*severe:STATIC_TYPE_ERROR*/i;) {}
       }
     '''
   });
@@ -97,33 +102,43 @@
           B f = new B();
           int x;
           double y;
-          // The analyzer has what I believe is a bug (dartbug.com/23252) which
-          // causes the return type of calls to f to be treated as dynamic.
-          x = /*info:DynamicCast should be pass*/f(3);
-          x = /*severe:StaticTypeError*/f.col(3.0);
-          y = /*info:DynamicCast should be severe:StaticTypeError*/f(3);
+          x = f(3);
+          x = /*severe:STATIC_TYPE_ERROR*/f.col(3.0);
+          y = /*severe:STATIC_TYPE_ERROR*/f(3);
           y = f.col(3.0);
-          f(/*severe:StaticTypeError*/3.0);
-          f.col(/*severe:StaticTypeError*/3);
+          f(/*severe:STATIC_TYPE_ERROR*/3.0);
+          f.col(/*severe:STATIC_TYPE_ERROR*/3);
         }
         {
           Function f = new B();
           int x;
           double y;
-          x = /*info:DynamicCast, info:DynamicInvoke*/f(3);
-          x = /*info:DynamicCast, info:DynamicInvoke*/f.col(3.0);
-          y = /*info:DynamicCast, info:DynamicInvoke*/f(3);
-          y = /*info:DynamicCast, info:DynamicInvoke*/f.col(3.0);
-          (/*info:DynamicInvoke*/f(3.0));
-          (/*info:DynamicInvoke*/f.col(3));
+          x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
+          x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f.col(3.0);
+          y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
+          y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f.col(3.0);
+          (/*info:DYNAMIC_INVOKE*/f(3.0));
+          (/*info:DYNAMIC_INVOKE*/f.col(3));
         }
         {
           A f = new B();
           int x;
           double y;
-          x = /*info:DynamicCast, info:DynamicInvoke*/f(3);
-          y = /*info:DynamicCast, info:DynamicInvoke*/f(3);
-          (/*info:DynamicInvoke*/f(3.0));
+          x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
+          y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
+          (/*info:DYNAMIC_INVOKE*/f(3.0));
+        }
+        {
+          dynamic g = new B();
+          (/*info:DYNAMIC_INVOKE*/g.call(32.0));
+          (/*info:DYNAMIC_INVOKE*/g.col(42.0));
+          (/*info:DYNAMIC_INVOKE*/g.foo(42.0));
+          (/*info:DYNAMIC_INVOKE*/g.x);
+          A f = new B();
+          f.call(32.0);
+          (/*info:DYNAMIC_INVOKE*/f.col(42.0));
+          (/*info:DYNAMIC_INVOKE*/f.foo(42.0));
+          (/*info:DYNAMIC_INVOKE*/f.x);
         }
       }
     '''
@@ -140,8 +155,8 @@
       class A {
         String x = "hello world";
 
-        void baz1(y) => x + /*info:DynamicCast*/y;
-        static baz2(y) => /*info:DynamicInvoke*/y + y;
+        void baz1(y) => x + /*info:DYNAMIC_CAST*/y;
+        static baz2(y) => /*info:DYNAMIC_INVOKE*/y + y;
       }
 
       void foo(String str) {
@@ -153,7 +168,7 @@
       }
 
       void bar(a) {
-        foo(/*info:DynamicCast,info:DynamicInvoke*/a.x);
+        foo(/*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/a.x);
       }
 
       baz() => new B();
@@ -166,42 +181,42 @@
       void main() {
         var a = new A();
         bar(a);
-        (/*info:DynamicInvoke*/bar1(a));
+        (/*info:DYNAMIC_INVOKE*/bar1(a));
         var b = bar;
-        (/*info:DynamicInvoke*/b(a));
+        (/*info:DYNAMIC_INVOKE*/b(a));
         var f1 = foo;
         f1("hello");
         dynamic f2 = foo;
-        (/*info:DynamicInvoke*/f2("hello"));
+        (/*info:DYNAMIC_INVOKE*/f2("hello"));
         DynFun f3 = foo;
-        (/*info:DynamicInvoke*/f3("hello"));
-        (/*info:DynamicInvoke*/f3(42));
+        (/*info:DYNAMIC_INVOKE*/f3("hello"));
+        (/*info:DYNAMIC_INVOKE*/f3(42));
         StrFun f4 = foo;
         f4("hello");
         a.baz1("hello");
         var b1 = a.baz1;
-        (/*info:DynamicInvoke*/b1("hello"));
+        (/*info:DYNAMIC_INVOKE*/b1("hello"));
         A.baz2("hello");
         var b2 = A.baz2;
-        (/*info:DynamicInvoke*/b2("hello"));
+        (/*info:DYNAMIC_INVOKE*/b2("hello"));
 
         dynamic a1 = new B();
-        (/*info:DynamicInvoke*/a1.x);
+        (/*info:DYNAMIC_INVOKE*/a1.x);
         a1.toString();
-        (/*info:DynamicInvoke*/a1.toString(42));
+        (/*info:DYNAMIC_INVOKE*/a1.toString(42));
         var toStringClosure = a1.toString;
-        (/*info:DynamicInvoke*/a1.toStringClosure());
-        (/*info:DynamicInvoke*/a1.toStringClosure(42));
-        (/*info:DynamicInvoke*/a1.toStringClosure("hello"));
+        (/*info:DYNAMIC_INVOKE*/a1.toStringClosure());
+        (/*info:DYNAMIC_INVOKE*/a1.toStringClosure(42));
+        (/*info:DYNAMIC_INVOKE*/a1.toStringClosure("hello"));
         a1.hashCode;
 
         dynamic toString = () => null;
-        (/*info:DynamicInvoke*/toString());
+        (/*info:DYNAMIC_INVOKE*/toString());
 
-        (/*info:DynamicInvoke*/helper.toString());
+        (/*info:DYNAMIC_INVOKE*/helper.toString());
         var toStringClosure2 = helper.toString;
-        (/*info:DynamicInvoke*/toStringClosure2());
-        int hashCode = /*info:DynamicCast*/helper.hashCode;
+        (/*info:DYNAMIC_INVOKE*/toStringClosure2());
+        int hashCode = /*info:DYNAMIC_CAST*/helper.hashCode;
 
         baz().toString();
         baz().hashCode;
@@ -218,27 +233,27 @@
         int x;
         String y;
 
-        A(this.x) : this.y = /*severe:StaticTypeError*/42;
+        A(this.x) : this.y = /*severe:STATIC_TYPE_ERROR*/42;
 
-        A.c1(p): this.x = /*info:DownCastImplicit*/z, this.y = /*info:DynamicCast*/p;
+        A.c1(p): this.x = /*info:DOWN_CAST_IMPLICIT*/z, this.y = /*info:DYNAMIC_CAST*/p;
 
         A.c2(this.x, this.y);
 
-        A.c3(/*severe:InvalidParameterDeclaration*/num this.x, String this.y);
+        A.c3(/*severe:INVALID_PARAMETER_DECLARATION*/num this.x, String this.y);
       }
 
       class B extends A {
-        B() : super(/*severe:StaticTypeError*/"hello");
+        B() : super(/*severe:STATIC_TYPE_ERROR*/"hello");
 
-        B.c2(int x, String y) : super.c2(/*severe:StaticTypeError*/y, 
-                                         /*severe:StaticTypeError*/x);
+        B.c2(int x, String y) : super.c2(/*severe:STATIC_TYPE_ERROR*/y,
+                                         /*severe:STATIC_TYPE_ERROR*/x);
 
-        B.c3(num x, Object y) : super.c3(x, /*info:DownCastImplicit*/y);
+        B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y);
       }
 
       void main() {
-         A a = new A.c2(/*info:DownCastImplicit*/z, /*severe:StaticTypeError*/z);
-         var b = new B.c2(/*severe:StaticTypeError*/"hello", /*info:DownCastImplicit*/obj);
+         A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*severe:STATIC_TYPE_ERROR*/z);
+         var b = new B.c2(/*severe:STATIC_TYPE_ERROR*/"hello", /*info:DOWN_CAST_IMPLICIT*/obj);
       }
    '''
   });
@@ -246,7 +261,7 @@
   testChecker('Unbound variable', {
     '/main.dart': '''
       void main() {
-         dynamic y = /*pass should be severe:StaticTypeError*/unboundVariable;
+         dynamic y = /*pass should be severe:STATIC_TYPE_ERROR*/unboundVariable;
       }
    '''
   });
@@ -254,7 +269,18 @@
   testChecker('Unbound type name', {
     '/main.dart': '''
       void main() {
-         /*pass should be severe:StaticTypeError*/AToB y;
+         /*pass should be severe:STATIC_TYPE_ERROR*/AToB y;
+      }
+   '''
+  });
+
+  // Regression test for https://github.com/dart-lang/sdk/issues/25069
+  testChecker('Void subtyping', {
+    '/main.dart': '''
+      typedef int Foo();
+      void foo() {}
+      void main () {
+        Foo x = /*severe:STATIC_TYPE_ERROR*/foo();
       }
    '''
   });
@@ -298,11 +324,11 @@
          A a;
          B b;
          o = y;
-         i = /*info:DynamicCast*/y;
-         d = /*info:DynamicCast*/y;
-         n = /*info:DynamicCast*/y;
-         a = /*info:DynamicCast*/y;
-         b = /*info:DynamicCast*/y;
+         i = /*info:DYNAMIC_CAST*/y;
+         d = /*info:DYNAMIC_CAST*/y;
+         n = /*info:DYNAMIC_CAST*/y;
+         a = /*info:DYNAMIC_CAST*/y;
+         b = /*info:DYNAMIC_CAST*/y;
       }
    '''
   });
@@ -323,11 +349,11 @@
          B b;
          y = a;
          o = a;
-         i = /*severe:StaticTypeError*/a;
-         d = /*severe:StaticTypeError*/a;
-         n = /*severe:StaticTypeError*/a;
+         i = /*severe:STATIC_TYPE_ERROR*/a;
+         d = /*severe:STATIC_TYPE_ERROR*/a;
+         n = /*severe:STATIC_TYPE_ERROR*/a;
          a = a;
-         b = /*info:DownCastImplicit*/a;
+         b = /*info:DOWN_CAST_IMPLICIT*/a;
       }
    '''
   });
@@ -350,12 +376,12 @@
          C c;
          y = b;
          o = b;
-         i = /*severe:StaticTypeError*/b;
-         d = /*severe:StaticTypeError*/b;
-         n = /*severe:StaticTypeError*/b;
+         i = /*severe:STATIC_TYPE_ERROR*/b;
+         d = /*severe:STATIC_TYPE_ERROR*/b;
+         n = /*severe:STATIC_TYPE_ERROR*/b;
          a = b;
          b = b;
-         c = /*severe:StaticTypeError*/b;
+         c = /*severe:STATIC_TYPE_ERROR*/b;
       }
    '''
   });
@@ -380,21 +406,21 @@
            top = bot;
          }
          {
-           left = /*info:DownCastImplicit*/top;
+           left = /*info:DOWN_CAST_IMPLICIT*/top;
            left = left;
-           left = /*severe:StaticTypeError*/right;
+           left = /*severe:STATIC_TYPE_ERROR*/right;
            left = bot;
          }
          {
-           right = /*info:DownCastImplicit*/top;
-           right = /*severe:StaticTypeError*/left;
+           right = /*info:DOWN_CAST_IMPLICIT*/top;
+           right = /*severe:STATIC_TYPE_ERROR*/left;
            right = right;
            right = bot;
          }
          {
-           bot = /*info:DownCastImplicit*/top;
-           bot = /*info:DownCastImplicit*/left;
-           bot = /*info:DownCastImplicit*/right;
+           bot = /*info:DOWN_CAST_IMPLICIT*/top;
+           bot = /*info:DOWN_CAST_IMPLICIT*/left;
+           bot = /*info:DOWN_CAST_IMPLICIT*/right;
            bot = bot;
          }
       }
@@ -413,7 +439,7 @@
       Object top(int x) => x;
       int left(int x) => x;
       Object right(Object x) => x;
-      int _bot(Object x) => /*info:DownCastImplicit*/x;
+      int _bot(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
       int bot(Object x) => x as int;
 
       void main() {
@@ -430,23 +456,23 @@
         }
         {
           Left f;
-          f = /*warning:DownCastComposite*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
           f = left;
-          f = /*warning:DownCastComposite*/right; // Should we reject this?
+          f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
           f = bot;
         }
         {
           Right f;
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left; // Should we reject this?
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
           f = right;
           f = bot;
         }
         {
           Bot f;
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left;
-          f = /*warning:DownCastComposite*/right;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left;
+          f = /*warning:DOWN_CAST_COMPOSITE*/right;
           f = bot;
         }
       }
@@ -466,7 +492,7 @@
       typedef B Bot(A x);   // Bottom of the lattice
 
       B left(B x) => x;
-      B _bot(A x) => /*info:DownCastImplicit*/x;
+      B _bot(A x) => /*info:DOWN_CAST_IMPLICIT*/x;
       B bot(A x) => x as B;
       A top(B x) => x;
       A right(A x) => x;
@@ -485,23 +511,23 @@
         }
         {
           Left f;
-          f = /*warning:DownCastComposite*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
           f = left;
-          f = /*warning:DownCastComposite*/right; // Should we reject this?
+          f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
           f = bot;
         }
         {
           Right f;
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left; // Should we reject this?
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
           f = right;
           f = bot;
         }
         {
           Bot f;
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left;
-          f = /*warning:DownCastComposite*/right;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left;
+          f = /*warning:DOWN_CAST_COMPOSITE*/right;
           f = bot;
         }
       }
@@ -521,7 +547,7 @@
       dynamic left(A x) => x;
       A bot(A x) => x;
       dynamic top(dynamic x) => x;
-      A right(dynamic x) => /*info:DynamicCast*/x;
+      A right(dynamic x) => /*info:DYNAMIC_CAST*/x;
 
       void main() {
         {
@@ -533,23 +559,23 @@
         }
         {
           Left f;
-          f = /*warning:DownCastComposite*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
           f = left;
-          f = /*warning:DownCastComposite*/right;
+          f = /*warning:DOWN_CAST_COMPOSITE*/right;
           f = bot;
         }
         {
           Right f;
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left;
           f = right;
           f = bot;
         }
         {
           Bottom f;
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left;
-          f = /*warning:DownCastComposite*/right;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left;
+          f = /*warning:DOWN_CAST_COMPOSITE*/right;
           f = bot;
         }
       }
@@ -579,23 +605,23 @@
         }
         {
           Function2<B, B> f;
-          f = /*warning:DownCastComposite*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
           f = left;
-          f = /*warning:DownCastComposite*/right; // Should we reject this?
+          f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
           f = bot;
         }
         {
           Function2<A, A> f;
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left; // Should we reject this?
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
           f = right;
           f = bot;
         }
         {
           Function2<A, B> f;
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left;
-          f = /*warning:DownCastComposite*/right;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left;
+          f = /*warning:DOWN_CAST_COMPOSITE*/right;
           f = bot;
         }
       }
@@ -622,19 +648,19 @@
           top = top;
           top = left;
 
-          left = /*warning:DownCastComposite*/top;
+          left = /*warning:DOWN_CAST_COMPOSITE*/top;
           left = left;
-          left = /*warning:DownCastComposite*/right; // Should we reject this?
+          left = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
           left = bot;
 
-          right = /*warning:DownCastComposite*/top;
-          right = /*warning:DownCastComposite*/left; // Should we reject this?
+          right = /*warning:DOWN_CAST_COMPOSITE*/top;
+          right = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
           right = right;
           right = bot;
 
-          bot = /*warning:DownCastComposite*/top;
-          bot = /*warning:DownCastComposite*/left;
-          bot = /*warning:DownCastComposite*/right;
+          bot = /*warning:DOWN_CAST_COMPOSITE*/top;
+          bot = /*warning:DOWN_CAST_COMPOSITE*/left;
+          bot = /*warning:DOWN_CAST_COMPOSITE*/right;
           bot = bot;
         }
       }
@@ -655,20 +681,20 @@
       BToA top(AToB f) => f;
       AToB left(AToB f) => f;
       BToA right(BToA f) => f;
-      AToB _bot(BToA f) => /*warning:DownCastComposite*/f;
+      AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
       AToB bot(BToA f) => f as AToB;
 
       Function2<B, A> top(AToB f) => f;
       Function2<A, B> left(AToB f) => f;
       Function2<B, A> right(BToA f) => f;
-      Function2<A, B> _bot(BToA f) => /*warning:DownCastComposite*/f;
+      Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
       Function2<A, B> bot(BToA f) => f as Function2<A, B>;
 
 
       BToA top(Function2<A, B> f) => f;
       AToB left(Function2<A, B> f) => f;
       BToA right(Function2<B, A> f) => f;
-      AToB _bot(Function2<B, A> f) => /*warning:DownCastComposite*/f;
+      AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f;
       AToB bot(Function2<B, A> f) => f as AToB;
 
       void main() {
@@ -681,24 +707,24 @@
         }
         {
           Function2<AToB, AToB> f; // Left
-          f = /*warning:DownCastComposite*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
           f = left;
-          f = /*warning:DownCastComposite*/right; // Should we reject this?
+          f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
           f = bot;
         }
         {
           Function2<BToA, BToA> f; // Right
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left; // Should we reject this?
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
           f = right;
           f = bot;
         }
         {
           Function2<BToA, AToB> f; // Bot
           f = bot;
-          f = /*warning:DownCastComposite*/left;
-          f = /*warning:DownCastComposite*/top;
-          f = /*warning:DownCastComposite*/left;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left;
         }
       }
    '''
@@ -725,21 +751,21 @@
         top = top;
         top = left;
 
-        left = /*warning:DownCastComposite*/top;
+        left = /*warning:DOWN_CAST_COMPOSITE*/top;
         left = left;
         left =
-            /*warning:DownCastComposite should be severe:StaticTypeError*/right;
+            /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/right;
         left = bot;
 
-        right = /*warning:DownCastComposite*/top;
+        right = /*warning:DOWN_CAST_COMPOSITE*/top;
         right =
-            /*warning:DownCastComposite should be severe:StaticTypeError*/left;
+            /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/left;
         right = right;
         right = bot;
 
-        bot = /*warning:DownCastComposite*/top;
-        bot = /*warning:DownCastComposite*/left;
-        bot = /*warning:DownCastComposite*/right;
+        bot = /*warning:DOWN_CAST_COMPOSITE*/top;
+        bot = /*warning:DOWN_CAST_COMPOSITE*/left;
+        bot = /*warning:DOWN_CAST_COMPOSITE*/right;
         bot = bot;
       }
     }
@@ -774,92 +800,92 @@
 
          r = r;
          r = o;
-         r = /*severe:StaticTypeError*/n;
-         r = /*severe:StaticTypeError*/rr;
+         r = /*severe:STATIC_TYPE_ERROR*/n;
+         r = /*severe:STATIC_TYPE_ERROR*/rr;
          r = ro;
          r = rn;
          r = oo;
-         r = /*severe:StaticTypeError*/nn;
-         r = /*severe:StaticTypeError*/nnn;
+         r = /*severe:STATIC_TYPE_ERROR*/nn;
+         r = /*severe:STATIC_TYPE_ERROR*/nnn;
 
-         o = /*warning:DownCastComposite*/r;
+         o = /*warning:DOWN_CAST_COMPOSITE*/r;
          o = o;
-         o = /*severe:StaticTypeError*/n;
-         o = /*severe:StaticTypeError*/rr;
-         o = /*severe:StaticTypeError*/ro;
-         o = /*severe:StaticTypeError*/rn;
+         o = /*severe:STATIC_TYPE_ERROR*/n;
+         o = /*severe:STATIC_TYPE_ERROR*/rr;
+         o = /*severe:STATIC_TYPE_ERROR*/ro;
+         o = /*severe:STATIC_TYPE_ERROR*/rn;
          o = oo;
-         o = /*severe:StaticTypeError*/nn
-         o = /*severe:StaticTypeError*/nnn;
+         o = /*severe:STATIC_TYPE_ERROR*/nn
+         o = /*severe:STATIC_TYPE_ERROR*/nnn;
 
-         n = /*severe:StaticTypeError*/r;
-         n = /*severe:StaticTypeError*/o;
+         n = /*severe:STATIC_TYPE_ERROR*/r;
+         n = /*severe:STATIC_TYPE_ERROR*/o;
          n = n;
-         n = /*severe:StaticTypeError*/rr;
-         n = /*severe:StaticTypeError*/ro;
-         n = /*severe:StaticTypeError*/rn;
-         n = /*severe:StaticTypeError*/oo;
+         n = /*severe:STATIC_TYPE_ERROR*/rr;
+         n = /*severe:STATIC_TYPE_ERROR*/ro;
+         n = /*severe:STATIC_TYPE_ERROR*/rn;
+         n = /*severe:STATIC_TYPE_ERROR*/oo;
          n = nn;
          n = nnn;
 
-         rr = /*severe:StaticTypeError*/r;
-         rr = /*severe:StaticTypeError*/o;
-         rr = /*severe:StaticTypeError*/n;
+         rr = /*severe:STATIC_TYPE_ERROR*/r;
+         rr = /*severe:STATIC_TYPE_ERROR*/o;
+         rr = /*severe:STATIC_TYPE_ERROR*/n;
          rr = rr;
          rr = ro;
-         rr = /*severe:StaticTypeError*/rn;
+         rr = /*severe:STATIC_TYPE_ERROR*/rn;
          rr = oo;
-         rr = /*severe:StaticTypeError*/nn;
-         rr = /*severe:StaticTypeError*/nnn;
+         rr = /*severe:STATIC_TYPE_ERROR*/nn;
+         rr = /*severe:STATIC_TYPE_ERROR*/nnn;
 
-         ro = /*warning:DownCastComposite*/r;
-         ro = /*severe:StaticTypeError*/o;
-         ro = /*severe:StaticTypeError*/n;
-         ro = /*warning:DownCastComposite*/rr;
+         ro = /*warning:DOWN_CAST_COMPOSITE*/r;
+         ro = /*severe:STATIC_TYPE_ERROR*/o;
+         ro = /*severe:STATIC_TYPE_ERROR*/n;
+         ro = /*warning:DOWN_CAST_COMPOSITE*/rr;
          ro = ro;
-         ro = /*severe:StaticTypeError*/rn;
+         ro = /*severe:STATIC_TYPE_ERROR*/rn;
          ro = oo;
-         ro = /*severe:StaticTypeError*/nn;
-         ro = /*severe:StaticTypeError*/nnn;
+         ro = /*severe:STATIC_TYPE_ERROR*/nn;
+         ro = /*severe:STATIC_TYPE_ERROR*/nnn;
 
-         rn = /*warning:DownCastComposite*/r;
-         rn = /*severe:StaticTypeError*/o;
-         rn = /*severe:StaticTypeError*/n;
-         rn = /*severe:StaticTypeError*/rr;
-         rn = /*severe:StaticTypeError*/ro;
+         rn = /*warning:DOWN_CAST_COMPOSITE*/r;
+         rn = /*severe:STATIC_TYPE_ERROR*/o;
+         rn = /*severe:STATIC_TYPE_ERROR*/n;
+         rn = /*severe:STATIC_TYPE_ERROR*/rr;
+         rn = /*severe:STATIC_TYPE_ERROR*/ro;
          rn = rn;
-         rn = /*severe:StaticTypeError*/oo;
-         rn = /*severe:StaticTypeError*/nn;
-         rn = /*severe:StaticTypeError*/nnn;
+         rn = /*severe:STATIC_TYPE_ERROR*/oo;
+         rn = /*severe:STATIC_TYPE_ERROR*/nn;
+         rn = /*severe:STATIC_TYPE_ERROR*/nnn;
 
-         oo = /*warning:DownCastComposite*/r;
-         oo = /*warning:DownCastComposite*/o;
-         oo = /*severe:StaticTypeError*/n;
-         oo = /*warning:DownCastComposite*/rr;
-         oo = /*warning:DownCastComposite*/ro;
-         oo = /*severe:StaticTypeError*/rn;
+         oo = /*warning:DOWN_CAST_COMPOSITE*/r;
+         oo = /*warning:DOWN_CAST_COMPOSITE*/o;
+         oo = /*severe:STATIC_TYPE_ERROR*/n;
+         oo = /*warning:DOWN_CAST_COMPOSITE*/rr;
+         oo = /*warning:DOWN_CAST_COMPOSITE*/ro;
+         oo = /*severe:STATIC_TYPE_ERROR*/rn;
          oo = oo;
-         oo = /*severe:StaticTypeError*/nn;
-         oo = /*severe:StaticTypeError*/nnn;
+         oo = /*severe:STATIC_TYPE_ERROR*/nn;
+         oo = /*severe:STATIC_TYPE_ERROR*/nnn;
 
-         nn = /*severe:StaticTypeError*/r;
-         nn = /*severe:StaticTypeError*/o;
-         nn = /*warning:DownCastComposite*/n;
-         nn = /*severe:StaticTypeError*/rr;
-         nn = /*severe:StaticTypeError*/ro;
-         nn = /*severe:StaticTypeError*/rn;
-         nn = /*severe:StaticTypeError*/oo;
+         nn = /*severe:STATIC_TYPE_ERROR*/r;
+         nn = /*severe:STATIC_TYPE_ERROR*/o;
+         nn = /*warning:DOWN_CAST_COMPOSITE*/n;
+         nn = /*severe:STATIC_TYPE_ERROR*/rr;
+         nn = /*severe:STATIC_TYPE_ERROR*/ro;
+         nn = /*severe:STATIC_TYPE_ERROR*/rn;
+         nn = /*severe:STATIC_TYPE_ERROR*/oo;
          nn = nn;
          nn = nnn;
 
-         nnn = /*severe:StaticTypeError*/r;
-         nnn = /*severe:StaticTypeError*/o;
-         nnn = /*warning:DownCastComposite*/n;
-         nnn = /*severe:StaticTypeError*/rr;
-         nnn = /*severe:StaticTypeError*/ro;
-         nnn = /*severe:StaticTypeError*/rn;
-         nnn = /*severe:StaticTypeError*/oo;
-         nnn = /*warning:DownCastComposite*/nn;
+         nnn = /*severe:STATIC_TYPE_ERROR*/r;
+         nnn = /*severe:STATIC_TYPE_ERROR*/o;
+         nnn = /*warning:DOWN_CAST_COMPOSITE*/n;
+         nnn = /*severe:STATIC_TYPE_ERROR*/rr;
+         nnn = /*severe:STATIC_TYPE_ERROR*/ro;
+         nnn = /*severe:STATIC_TYPE_ERROR*/rn;
+         nnn = /*severe:STATIC_TYPE_ERROR*/oo;
+         nnn = /*warning:DOWN_CAST_COMPOSITE*/nn;
          nnn = nnn;
       }
    '''
@@ -882,38 +908,38 @@
          {
            I2I f;
            f = new A();
-           f = /*severe:StaticTypeError*/new B();
+           f = /*severe:STATIC_TYPE_ERROR*/new B();
            f = i2i;
-           f = /*warning:DownCastComposite*/n2n;
-           f = /*warning:DownCastComposite*/i2i as Object;
-           f = /*warning:DownCastComposite*/n2n as Function;
+           f = /*warning:DOWN_CAST_COMPOSITE*/n2n;
+           f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
+           f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
          }
          {
            N2N f;
-           f = /*severe:StaticTypeError*/new A();
+           f = /*severe:STATIC_TYPE_ERROR*/new A();
            f = new B();
-           f = /*warning:DownCastComposite*/i2i;
+           f = /*warning:DOWN_CAST_COMPOSITE*/i2i;
            f = n2n;
-           f = /*warning:DownCastComposite*/i2i as Object;
-           f = /*warning:DownCastComposite*/n2n as Function;
+           f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
+           f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
          }
          {
            A f;
            f = new A();
-           f = /*severe:StaticTypeError*/new B();
-           f = /*severe:StaticTypeError*/i2i;
-           f = /*severe:StaticTypeError*/n2n;
-           f = /*info:DownCastImplicit*/i2i as Object;
-           f = /*info:DownCastImplicit*/n2n as Function;
+           f = /*severe:STATIC_TYPE_ERROR*/new B();
+           f = /*severe:STATIC_TYPE_ERROR*/i2i;
+           f = /*severe:STATIC_TYPE_ERROR*/n2n;
+           f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
+           f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
          }
          {
            B f;
-           f = /*severe:StaticTypeError*/new A();
+           f = /*severe:STATIC_TYPE_ERROR*/new A();
            f = new B();
-           f = /*severe:StaticTypeError*/i2i;
-           f = /*severe:StaticTypeError*/n2n;
-           f = /*info:DownCastImplicit*/i2i as Object;
-           f = /*info:DownCastImplicit*/n2n as Function;
+           f = /*severe:STATIC_TYPE_ERROR*/i2i;
+           f = /*severe:STATIC_TYPE_ERROR*/n2n;
+           f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
+           f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
          }
          {
            Function f;
@@ -921,7 +947,7 @@
            f = new B();
            f = i2i;
            f = n2n;
-           f = /*info:DownCastImplicit*/i2i as Object;
+           f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
            f = (n2n as Function);
          }
       }
@@ -980,36 +1006,36 @@
           lOfOs = lOfAs;
         }
         {
-          lOfAs = /*warning:DownCastComposite*/mOfDs;
-          lOfAs = /*severe:StaticTypeError*/mOfOs;
+          lOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
+          lOfAs = /*severe:STATIC_TYPE_ERROR*/mOfOs;
           lOfAs = mOfAs;
-          lOfAs = /*warning:DownCastComposite*/lOfDs;
-          lOfAs = /*info:DownCastImplicit*/lOfOs;
+          lOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
+          lOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
           lOfAs = lOfAs;
         }
         {
           mOfDs = mOfDs;
           mOfDs = mOfOs;
           mOfDs = mOfAs;
-          mOfDs = /*info:DownCastImplicit*/lOfDs;
-          mOfDs = /*info:DownCastImplicit*/lOfOs;
-          mOfDs = /*warning:DownCastComposite*/lOfAs;
+          mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
+          mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
+          mOfDs = /*warning:DOWN_CAST_COMPOSITE*/lOfAs;
         }
         {
           mOfOs = mOfDs;
           mOfOs = mOfOs;
           mOfOs = mOfAs;
-          mOfOs = /*info:DownCastImplicit*/lOfDs;
-          mOfOs = /*info:DownCastImplicit*/lOfOs;
-          mOfOs = /*severe:StaticTypeError*/lOfAs;
+          mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
+          mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
+          mOfOs = /*severe:STATIC_TYPE_ERROR*/lOfAs;
         }
         {
-          mOfAs = /*warning:DownCastComposite*/mOfDs;
-          mOfAs = /*info:DownCastImplicit*/mOfOs;
+          mOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
+          mOfAs = /*info:DOWN_CAST_IMPLICIT*/mOfOs;
           mOfAs = mOfAs;
-          mOfAs = /*warning:DownCastComposite*/lOfDs;
-          mOfAs = /*info:DownCastImplicit*/lOfOs;
-          mOfAs = /*info:DownCastImplicit*/lOfAs;
+          mOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
+          mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
+          mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfAs;
         }
 
       }
@@ -1024,9 +1050,9 @@
             String s = "hello";
             {
                List<int> l = <int>[i];
-               l = <int>[/*severe:StaticTypeError*/s];
-               l = <int>[/*info:DownCastImplicit*/n];
-               l = <int>[i, /*info:DownCastImplicit*/n, /*severe:StaticTypeError*/s];
+               l = <int>[/*severe:STATIC_TYPE_ERROR*/s];
+               l = <int>[/*info:DOWN_CAST_IMPLICIT*/n];
+               l = <int>[i, /*info:DOWN_CAST_IMPLICIT*/n, /*severe:STATIC_TYPE_ERROR*/s];
             }
             {
                List l = [i];
@@ -1036,11 +1062,11 @@
             }
             {
                Map<String, int> m = <String, int>{s: i};
-               m = <String, int>{s: /*severe:StaticTypeError*/s};
-               m = <String, int>{s: /*info:DownCastImplicit*/n};
+               m = <String, int>{s: /*severe:STATIC_TYPE_ERROR*/s};
+               m = <String, int>{s: /*info:DOWN_CAST_IMPLICIT*/n};
                m = <String, int>{s: i,
-                                 s: /*info:DownCastImplicit*/n,
-                                 s: /*severe:StaticTypeError*/s};
+                                 s: /*info:DOWN_CAST_IMPLICIT*/n,
+                                 s: /*severe:STATIC_TYPE_ERROR*/s};
             }
            // TODO(leafp): We can't currently test for key errors since the
            // error marker binds to the entire entry.
@@ -1063,15 +1089,15 @@
     '/main.dart': '''
           class A {
             static const num n = 3.0;
-            static const int i = /*info:AssignmentCast*/n;
+            static const int i = /*info:ASSIGNMENT_CAST*/n;
             final int fi;
-            const A(num a) : this.fi = /*info:DownCastImplicit*/a;
+            const A(num a) : this.fi = /*info:DOWN_CAST_IMPLICIT*/a;
           }
           class B extends A {
-            const B(Object a) : super(/*info:DownCastImplicit*/a);
+            const B(Object a) : super(/*info:DOWN_CAST_IMPLICIT*/a);
           }
           void foo(Object o) {
-            var a = const A(/*info:DownCastImplicit*/o);
+            var a = const A(/*info:DOWN_CAST_IMPLICIT*/o);
           }
      '''
   });
@@ -1081,18 +1107,27 @@
           main() {
             bool b = true;
             num x = b ? 1 : 2.3;
-            int y = /*info:AssignmentCast*/b ? 1 : 2.3;
+            int y = /*info:ASSIGNMENT_CAST*/b ? 1 : 2.3;
             String z = !b ? "hello" : null;
             z = b ? null : "hello";
           }
       '''
   });
 
+  // This is a regression test for https://github.com/dart-lang/sdk/issues/25071
+  testChecker('unbound redirecting constructor', {
+    '/main.dart': '''
+      class Foo {
+        Foo() : this.init();
+      }
+       '''
+  });
+
   testChecker('redirecting constructor', {
     '/main.dart': '''
           class A {
             A(A x) {}
-            A.two() : this(/*severe:StaticTypeError*/3);
+            A.two() : this(/*severe:STATIC_TYPE_ERROR*/3);
           }
        '''
   });
@@ -1101,7 +1136,7 @@
     '/main.dart': '''
           class A { A(A x) {} }
           class B extends A {
-            B() : super(/*severe:StaticTypeError*/3);
+            B() : super(/*severe:STATIC_TYPE_ERROR*/3);
           }
        '''
   });
@@ -1120,14 +1155,55 @@
           }
 
           class Child extends Base {
-            /*severe:InvalidMethodOverride*/A f1; // invalid for getter
-            /*severe:InvalidMethodOverride*/C f2; // invalid for setter
+            /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
+            /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
+            /*severe:INVALID_FIELD_OVERRIDE*/var f3;
+            /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic f4;
+          }
+
+          class Child2 implements Base {
+            /*severe:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
+            /*severe:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
             var f3;
-            /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/dynamic f4;
+            /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic f4;
           }
        '''
   });
 
+  testChecker('private override', {
+    '/helper.dart': '''
+          import 'main.dart' as main;
+
+          class Base {
+            var f1;
+            var _f2;
+            var _f3;
+            get _f4 => null;
+
+            int _m1();
+          }
+
+          class GrandChild extends main.Child {
+            /*severe:INVALID_FIELD_OVERRIDE*/var _f2;
+            /*severe:INVALID_FIELD_OVERRIDE*/var _f3;
+            var _f4;
+
+            /*severe:INVALID_METHOD_OVERRIDE*/String _m1();
+          }
+    ''',
+    '/main.dart': '''
+          import 'helper.dart' as helper;
+
+          class Child extends helper.Base {
+            /*severe:INVALID_FIELD_OVERRIDE*/var f1;
+            var _f2;
+            var _f4;
+
+            String _m1();
+          }
+    '''
+  });
+
   testChecker('getter/getter override', {
     '/main.dart': '''
           class A {}
@@ -1142,10 +1218,10 @@
           }
 
           class Child extends Base {
-            /*severe:InvalidMethodOverride*/A get f1 => null;
+            /*severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
             C get f2 => null;
             get f3 => null;
-            /*severe:InvalidMethodOverride*/dynamic get f4 => null;
+            /*severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
           }
        '''
   });
@@ -1164,10 +1240,17 @@
           }
 
           class Child extends Base {
-            /*severe:InvalidMethodOverride*/A get f1 => null;
+            /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
+            /*severe:INVALID_FIELD_OVERRIDE*/C get f2 => null;
+            /*severe:INVALID_FIELD_OVERRIDE*/get f3 => null;
+            /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
+          }
+
+          class Child2 implements Base {
+            /*severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
             C get f2 => null;
             get f3 => null;
-            /*severe:InvalidMethodOverride*/dynamic get f4 => null;
+            /*severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
           }
        '''
   });
@@ -1188,9 +1271,9 @@
 
           class Child extends Base {
             void set f1(A value) {}
-            /*severe:InvalidMethodOverride*/void set f2(C value) {}
+            /*severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
             void set f3(value) {}
-            /*severe:InvalidMethodOverride*/void set f4(dynamic value) {}
+            /*severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
             set f5(B value) {}
           }
        '''
@@ -1211,6 +1294,20 @@
           }
 
           class Child extends Base {
+            /*severe:INVALID_FIELD_OVERRIDE*/B get f1 => null;
+            /*severe:INVALID_FIELD_OVERRIDE*/B get f2 => null;
+            /*severe:INVALID_FIELD_OVERRIDE*/B get f3 => null;
+            /*severe:INVALID_FIELD_OVERRIDE*/B get f4 => null;
+            /*severe:INVALID_FIELD_OVERRIDE*/B get f5 => null;
+
+            /*severe:INVALID_FIELD_OVERRIDE*/void set f1(A value) {}
+            /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
+            /*severe:INVALID_FIELD_OVERRIDE*/void set f3(value) {}
+            /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
+            /*severe:INVALID_FIELD_OVERRIDE*/set f5(B value) {}
+          }
+
+          class Child2 implements Base {
             B get f1 => null;
             B get f2 => null;
             B get f3 => null;
@@ -1218,9 +1315,9 @@
             B get f5 => null;
 
             void set f1(A value) {}
-            /*severe:InvalidMethodOverride*/void set f2(C value) {}
+            /*severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
             void set f3(value) {}
-            /*severe:InvalidMethodOverride*/void set f4(dynamic value) {}
+            /*severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
             set f5(B value) {}
           }
        '''
@@ -1242,12 +1339,55 @@
           }
 
           class Child extends Base {
-            /*severe:InvalidMethodOverride*/A m1(A value) {}
-            /*severe:InvalidMethodOverride*/C m2(C value) {}
-            /*severe:InvalidMethodOverride*/A m3(C value) {}
+            /*severe:INVALID_METHOD_OVERRIDE*/A m1(A value) {}
+            /*severe:INVALID_METHOD_OVERRIDE*/C m2(C value) {}
+            /*severe:INVALID_METHOD_OVERRIDE*/A m3(C value) {}
             C m4(A value) {}
             m5(value) {}
-            /*severe:InvalidMethodOverride*/dynamic m6(dynamic value) {}
+            /*severe:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) {}
+          }
+       '''
+  });
+
+  testChecker('generic class method override', {
+    '/main.dart': '''
+          class A {}
+          class B extends A {}
+
+          class Base<T extends B> {
+            T foo() => null;
+          }
+
+          class Derived<S extends A> extends Base<B> {
+            /*severe:INVALID_METHOD_OVERRIDE*/S foo() => null;
+          }
+
+          class Derived2<S extends B> extends Base<B> {
+            S foo() => null;
+          }
+       '''
+  });
+
+  testChecker('generic method override', {
+    '/main.dart': '''
+          class Future<T> {
+            /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
+          }
+
+          class DerivedFuture<T> extends Future<T> {
+            /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
+          }
+
+          class DerivedFuture2<A> extends Future<A> {
+            /*=B*/ then/*<B>*/(/*=B*/ onValue(A a)) => null;
+          }
+
+          class DerivedFuture3<T> extends Future<T> {
+            /*=S*/ then/*<S>*/(Object onValue(T t)) => null;
+          }
+
+          class DerivedFuture4<A> extends Future<A> {
+            /*=B*/ then/*<B>*/(Object onValue(A a)) => null;
           }
        '''
   });
@@ -1268,23 +1408,23 @@
         var c = foo();
 
         ~a;
-        (/*info:DynamicInvoke*/~d);
+        (/*info:DYNAMIC_INVOKE*/~d);
 
-        !/*severe:StaticTypeError*/a;
-        !/*info:DynamicCast*/d;
+        !/*severe:STATIC_TYPE_ERROR*/a;
+        !/*info:DYNAMIC_CAST*/d;
 
         -a;
-        (/*info:DynamicInvoke*/-d);
+        (/*info:DYNAMIC_INVOKE*/-d);
 
         ++a;
         --a;
-        (/*info:DynamicInvoke*/++d);
-        (/*info:DynamicInvoke*/--d);
+        (/*info:DYNAMIC_INVOKE*/++d);
+        (/*info:DYNAMIC_INVOKE*/--d);
 
         a++;
         a--;
-        (/*info:DynamicInvoke*/d++);
-        (/*info:DynamicInvoke*/d--);
+        (/*info:DYNAMIC_INVOKE*/d++);
+        (/*info:DYNAMIC_INVOKE*/d--);
       }'''
   });
 
@@ -1316,39 +1456,56 @@
             B b = new B();
             var c = foo();
             a = a * b;
-            a = a * /*info:DynamicCast*/c;
+            a = a * /*info:DYNAMIC_CAST*/c;
             a = a / b;
             a = a ~/ b;
             a = a % b;
             a = a + b;
-            a = a + /*severe:StaticTypeError*/a;
+            a = a + /*severe:STATIC_TYPE_ERROR*/a;
             a = a - b;
-            b = /*severe:StaticTypeError*/b - b;
+            b = /*severe:STATIC_TYPE_ERROR*/b - b;
             a = a << b;
             a = a >> b;
             a = a & b;
             a = a ^ b;
             a = a | b;
-            c = (/*info:DynamicInvoke*/c + b);
+            c = (/*info:DYNAMIC_INVOKE*/c + b);
 
             String x = 'hello';
             int y = 42;
             x = x + x;
-            x = x + /*info:DynamicCast*/c;
-            x = x + /*severe:StaticTypeError*/y;
+            x = x + /*info:DYNAMIC_CAST*/c;
+            x = x + /*severe:STATIC_TYPE_ERROR*/y;
 
             bool p = true;
             p = p && p;
-            p = p && /*info:DynamicCast*/c;
-            p = (/*info:DynamicCast*/c) && p;
-            p = (/*info:DynamicCast*/c) && /*info:DynamicCast*/c;
-            p = (/*severe:StaticTypeError*/y) && p;
+            p = p && /*info:DYNAMIC_CAST*/c;
+            p = (/*info:DYNAMIC_CAST*/c) && p;
+            p = (/*info:DYNAMIC_CAST*/c) && /*info:DYNAMIC_CAST*/c;
+            p = (/*severe:STATIC_TYPE_ERROR*/y) && p;
             p = c == y;
 
             a = a[b];
-            a = a[/*info:DynamicCast*/c];
-            c = (/*info:DynamicInvoke*/c[b]);
-            a[/*severe:StaticTypeError*/y];
+            a = a[/*info:DYNAMIC_CAST*/c];
+            c = (/*info:DYNAMIC_INVOKE*/c[b]);
+            a[/*severe:STATIC_TYPE_ERROR*/y];
+          }
+       '''
+  });
+
+  testChecker('null coalescing operator', {
+    '/main.dart': '''
+          class A {}
+          class C<T> {}
+          main() {
+            A a, b;
+            a ??= new A();
+            b = b ?? new A();
+
+            // downwards inference
+            C<int> c, d;
+            c ??= /*info:INFERRED_TYPE_ALLOCATION*/new C();
+            d = d ?? /*info:INFERRED_TYPE_ALLOCATION*/new C();
           }
        '''
   });
@@ -1384,7 +1541,7 @@
           test() {
             int x = 0;
             x += 5;
-            (/*severe:StaticTypeError*/x += 3.14);
+            (/*severe:STATIC_TYPE_ERROR*/x += 3.14);
 
             double y = 0.0;
             y += 5;
@@ -1394,43 +1551,43 @@
             z += 5;
             z += 3.14;
 
-            x = /*info:DownCastImplicit*/x + z;
-            x += /*info:DownCastImplicit*/z;
-            y = /*info:DownCastImplicit*/y + z;
-            y += /*info:DownCastImplicit*/z;
+            x = /*info:DOWN_CAST_IMPLICIT*/x + z;
+            x += /*info:DOWN_CAST_IMPLICIT*/z;
+            y = /*info:DOWN_CAST_IMPLICIT*/y + z;
+            y += /*info:DOWN_CAST_IMPLICIT*/z;
 
             dynamic w = 42;
-            x += /*info:DynamicCast*/w;
-            y += /*info:DynamicCast*/w;
-            z += /*info:DynamicCast*/w;
+            x += /*info:DYNAMIC_CAST*/w;
+            y += /*info:DYNAMIC_CAST*/w;
+            z += /*info:DYNAMIC_CAST*/w;
 
             A a = new A();
             B b = new B();
             var c = foo();
             a = a * b;
             a *= b;
-            a *= /*info:DynamicCast*/c;
+            a *= /*info:DYNAMIC_CAST*/c;
             a /= b;
             a ~/= b;
             a %= b;
             a += b;
-            a += /*severe:StaticTypeError*/a;
+            a += /*severe:STATIC_TYPE_ERROR*/a;
             a -= b;
-            (/*severe:StaticTypeError*/b -= b);
+            (/*severe:STATIC_TYPE_ERROR*/b -= b);
             a <<= b;
             a >>= b;
             a &= b;
             a ^= b;
             a |= b;
-            (/*info:DynamicInvoke*/c += b);
+            (/*info:DYNAMIC_INVOKE*/c += b);
 
             var d = new D();
             a[b] += d;
-            a[/*info:DynamicCast*/c] += d;
-            a[/*severe:StaticTypeError*/z] += d;
-            a[b] += /*info:DynamicCast*/c;
-            a[b] += /*severe:StaticTypeError*/z;
-            (/*info:DynamicInvoke*/(/*info:DynamicInvoke*/c[b]) += d);
+            a[/*info:DYNAMIC_CAST*/c] += d;
+            a[/*severe:STATIC_TYPE_ERROR*/z] += d;
+            a[b] += /*info:DYNAMIC_CAST*/c;
+            a[b] += /*severe:STATIC_TYPE_ERROR*/z;
+            (/*info:DYNAMIC_INVOKE*/(/*info:DYNAMIC_INVOKE*/c[b]) += d);
           }
        '''
   });
@@ -1446,7 +1603,7 @@
             var y, z;
             Derived()
                 : y = print('Derived.1'),
-                  /*severe:InvalidSuperInvocation*/super(),
+                  /*severe:INVALID_SUPER_INVOCATION*/super(),
                   z = print('Derived.2') {
               print('Derived.3');
             }
@@ -1474,7 +1631,7 @@
     '/main.dart': '''
           foo() {
             for (int i = 0; i < 10; i++) {
-              i = /*severe:StaticTypeError*/"hi";
+              i = /*severe:STATIC_TYPE_ERROR*/"hi";
             }
           }
           bar() {
@@ -1496,19 +1653,35 @@
             }
 
             class T1 extends Base {
-              /*severe:InvalidMethodOverride*/B get f => null;
+              /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/B get f => null;
             }
 
             class T2 extends Base {
-              /*severe:InvalidMethodOverride*/set f(B b) => null;
+              /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/set f(B b) => null;
             }
 
             class T3 extends Base {
-              /*severe:InvalidMethodOverride*/final B f;
+              /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/final B f;
             }
             class T4 extends Base {
               // two: one for the getter one for the setter.
-              /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/B f;
+              /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/B f;
+            }
+
+            class T5 implements Base {
+              /*severe:INVALID_METHOD_OVERRIDE*/B get f => null;
+            }
+
+            class T6 implements Base {
+              /*severe:INVALID_METHOD_OVERRIDE*/set f(B b) => null;
+            }
+
+            class T7 implements Base {
+              /*severe:INVALID_METHOD_OVERRIDE*/final B f;
+            }
+            class T8 implements Base {
+              // two: one for the getter one for the setter.
+              /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/B f;
             }
          '''
     });
@@ -1523,7 +1696,7 @@
             }
 
             class Test extends Base {
-                /*severe:InvalidMethodOverride*/m(B a) {}
+                /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
             }
          '''
     });
@@ -1534,12 +1707,14 @@
 
             class Grandparent {
                 m(A a) {}
+                int x;
             }
             class Parent extends Grandparent {
             }
 
             class Test extends Parent {
-                /*severe:InvalidMethodOverride*/m(B a) {}
+                /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+                /*severe:INVALID_FIELD_OVERRIDE*/int x;
             }
          '''
     });
@@ -1558,7 +1733,7 @@
 
             class Test extends Parent {
                 // Reported only once
-                /*severe:InvalidMethodOverride*/m(B a) {}
+                /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
             }
          '''
     });
@@ -1572,7 +1747,7 @@
                 m(A a) {}
             }
             class Parent extends Grandparent {
-                /*severe:InvalidMethodOverride*/m(B a) {}
+                /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
             }
 
             class Test extends Parent {
@@ -1588,17 +1763,20 @@
 
             class Base {
                 m(A a) {}
+                int x;
             }
 
             class M1 {
                 m(B a) {}
             }
 
-            class M2 {}
+            class M2 {
+                int x;
+            }
 
-            class T1 extends Base with /*severe:InvalidMethodOverride*/M1 {}
-            class T2 extends Base with /*severe:InvalidMethodOverride*/M1, M2 {}
-            class T3 extends Base with M2, /*severe:InvalidMethodOverride*/M1 {}
+            class T1 extends Base with /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
+            class T2 extends Base with /*severe:INVALID_METHOD_OVERRIDE*/M1, /*severe:INVALID_FIELD_OVERRIDE*/M2 {}
+            class T3 extends Base with /*severe:INVALID_FIELD_OVERRIDE*/M2, /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
          '''
     });
 
@@ -1612,13 +1790,15 @@
 
             class M1 {
                 m(B a) {}
+                int x;
             }
 
             class M2 {
                 m(A a) {}
+                int x;
             }
 
-            class T1 extends Base with M1, /*severe:InvalidMethodOverride*/M2 {}
+            class T1 extends Base with M1, /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_FIELD_OVERRIDE*/M2 {}
          '''
     });
 
@@ -1647,7 +1827,7 @@
             }
 
             class T1 extends Base
-                with M1, /*severe:InvalidMethodOverride*/M2, M3 {}
+                with M1, /*severe:INVALID_METHOD_OVERRIDE*/M2, M3 {}
          '''
     });
 
@@ -1661,7 +1841,7 @@
             }
 
             class T1 implements I {
-                /*severe:InvalidMethodOverride*/m(B a) {}
+                /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
             }
          '''
     });
@@ -1680,7 +1860,7 @@
             }
 
 
-            class T1 /*severe:InvalidMethodOverride*/extends Base implements I {
+            class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base implements I {
             }
          '''
     });
@@ -1698,7 +1878,7 @@
                 m(B a) {}
             }
 
-            class T1 extends Object with /*severe:InvalidMethodOverride*/M
+            class T1 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
                implements I {}
          '''
     });
@@ -1719,18 +1899,18 @@
                 m(B a) {}
             }
 
-            class T1 /*severe:InvalidMethodOverride*/extends Base
+            class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
                 implements I1 {}
 
             class T2 extends Base implements I1 {
-                /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a) {}
+                /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/m(a) {}
             }
 
-            class T3 extends Object with /*severe:InvalidMethodOverride*/Base
+            class T3 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/Base
                 implements I1 {}
 
             class T4 extends Object with Base implements I1 {
-                /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a) {}
+                /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/m(a) {}
             }
          '''
     });
@@ -1748,7 +1928,7 @@
               abstract class I2 implements I1 {}
 
               class T1 implements I2 {
-                  /*severe:InvalidMethodOverride*/m(B a) {}
+                  /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
            '''
     });
@@ -1763,7 +1943,7 @@
               abstract class I2 extends I1 {}
 
               class T1 implements I2 {
-                  /*severe:InvalidMethodOverride*/m(B a) {}
+                  /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
            '''
     });
@@ -1778,7 +1958,7 @@
               abstract class I2 extends Object with M1 {}
 
               class T1 implements I2 {
-                  /*severe:InvalidMethodOverride*/m(B a) {}
+                  /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
            '''
     });
@@ -1793,7 +1973,7 @@
               abstract class Base implements I1 {}
 
               class T1 extends Base {
-                  /*severe:InvalidMethodOverride*/m(B a) {}
+                  /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
            '''
     });
@@ -1835,7 +2015,7 @@
                   m(B a) {}
               }
 
-              class T1 extends Object with /*severe:InvalidMethodOverride*/M
+              class T1 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
                   implements I2 {
               }
            '''
@@ -1854,7 +2034,7 @@
                   m(B a) {}
               }
 
-              class T1 extends Object with /*severe:InvalidMethodOverride*/M
+              class T1 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
                   implements I2 {
               }
            '''
@@ -1873,7 +2053,7 @@
                   m(B a) {}
               }
 
-              class T1 extends Object with /*severe:InvalidMethodOverride*/M
+              class T1 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
                   implements I2 {
               }
            '''
@@ -1892,7 +2072,7 @@
                   m(B a) {}
               }
 
-              class T1 extends Base with /*severe:InvalidMethodOverride*/M {
+              class T1 extends Base with /*severe:INVALID_METHOD_OVERRIDE*/M {
               }
            '''
     });
@@ -1934,7 +2114,7 @@
                   m(B a) {}
               }
 
-              class T1 /*severe:InvalidMethodOverride*/extends Base
+              class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
                   implements I2 {
               }
            '''
@@ -1953,7 +2133,7 @@
                   m(B a) {}
               }
 
-              class T1 /*severe:InvalidMethodOverride*/extends Base
+              class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
                   implements I2 {
               }
            '''
@@ -1972,7 +2152,7 @@
                   m(B a) {}
               }
 
-              class T1 /*severe:InvalidMethodOverride*/extends Base
+              class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
                   implements I2 {
               }
            '''
@@ -1987,7 +2167,7 @@
               }
 
               abstract class Base implements I1 {
-                  /*severe:InvalidMethodOverride*/m(B a) {}
+                  /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
 
               class T1 extends Base {
@@ -1996,7 +2176,7 @@
                   // TODO(sigmund): consider tracking overrides in a fine-grain
                   // manner, then this and the double-overrides would not be
                   // reported.
-                  /*severe:InvalidMethodOverride*/m(B a) {}
+                  /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
            '''
     });
@@ -2010,7 +2190,7 @@
               }
 
               class Base implements I1 {
-                  /*severe:InvalidMethodOverride*/m(B a) {}
+                  /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
 
               class T1 extends Base {
@@ -2037,7 +2217,7 @@
               }
 
               class T1 implements I2 {
-                /*severe:InvalidMethodOverride*/m(B a) {}
+                /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
            '''
     });
@@ -2058,12 +2238,12 @@
               // Note: no error reported in `extends Base` to avoid duplicating
               // the error in T1.
               class T1 extends Base implements I1 {
-                /*severe:InvalidMethodOverride*/m(B a) {}
+                /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
 
               // If there is no error in the class, we do report the error at
               // the base class:
-              class T2 /*severe:InvalidMethodOverride*/extends Base
+              class T2 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
                   implements I1 {
               }
            '''
@@ -2083,10 +2263,10 @@
               }
 
               class T1 extends Object with M implements I1 {
-                /*severe:InvalidMethodOverride*/m(B a) {}
+                /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
               }
 
-              class T2 extends Object with /*severe:InvalidMethodOverride*/M
+              class T2 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
                   implements I1 {
               }
            '''
@@ -2112,10 +2292,10 @@
               }
 
               // Note: otherwise both errors would be reported on this line
-              class T1 /*severe:InvalidMethodOverride*/extends Parent1
+              class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Parent1
                   implements I1 {
               }
-              class T2 /*severe:InvalidMethodOverride*/extends Parent2
+              class T2 /*severe:INVALID_METHOD_OVERRIDE*/extends Parent2
                   implements I1 {
               }
            '''
@@ -2142,8 +2322,8 @@
               // different.
               // TODO(sigmund): should we merge these as well?
               class T1 extends Object
-                  with /*severe:InvalidMethodOverride*/M1
-                  with /*severe:InvalidMethodOverride*/M2
+                  with /*severe:INVALID_METHOD_OVERRIDE*/M1
+                  with /*severe:INVALID_METHOD_OVERRIDE*/M2
                   implements I1 {
               }
            '''
@@ -2169,8 +2349,8 @@
               // Here we want to report both, because the error location is
               // different.
               // TODO(sigmund): should we merge these as well?
-              class T1 /*severe:InvalidMethodOverride*/extends Base
-                  with /*severe:InvalidMethodOverride*/M
+              class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+                  with /*severe:INVALID_METHOD_OVERRIDE*/M
                   implements I1 {
               }
            '''
@@ -2198,18 +2378,18 @@
 
           void main() {
             bool b;
-            b = /*info:NonGroundTypeCheckInfo*/foo is I2I;
-            b = /*info:NonGroundTypeCheckInfo*/foo is D2I;
-            b = /*info:NonGroundTypeCheckInfo*/foo is I2D;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is I2I;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is D2I;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is I2D;
             b = foo is D2D;
 
-            b = /*info:NonGroundTypeCheckInfo*/bar is II2I;
-            b = /*info:NonGroundTypeCheckInfo*/bar is DI2I;
-            b = /*info:NonGroundTypeCheckInfo*/bar is ID2I;
-            b = /*info:NonGroundTypeCheckInfo*/bar is II2D;
-            b = /*info:NonGroundTypeCheckInfo*/bar is DD2I;
-            b = /*info:NonGroundTypeCheckInfo*/bar is DI2D;
-            b = /*info:NonGroundTypeCheckInfo*/bar is ID2D;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is II2I;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DI2I;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is ID2I;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is II2D;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DD2I;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DI2D;
+            b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is ID2D;
             b = bar is DD2D;
 
             // For as, the validity of checks is deferred to runtime.
@@ -2241,22 +2421,24 @@
 
         foo1() async => x;
         Future foo2() async => x;
-        Future<int> foo3() async => (/*info:DynamicCast*/x);
-        Future<int> foo4() async => (/*severe:StaticTypeError*/new Future<int>.value(/*info:DynamicCast*/x));
+        Future<int> foo3() async => (/*info:DYNAMIC_CAST*/x);
+        Future<int> foo4() async => (new Future<int>.value(/*info:DYNAMIC_CAST*/x));
+        Future<int> foo5() async => (/*severe:STATIC_TYPE_ERROR*/new Future<String>.value(/*info:DYNAMIC_CAST*/x));
 
         bar1() async { return x; }
         Future bar2() async { return x; }
-        Future<int> bar3() async { return (/*info:DynamicCast*/x); }
-        Future<int> bar4() async { return (/*severe:StaticTypeError*/new Future<int>.value(/*info:DynamicCast*/x)); }
+        Future<int> bar3() async { return (/*info:DYNAMIC_CAST*/x); }
+        Future<int> bar4() async { return (new Future<int>.value(/*info:DYNAMIC_CAST*/x)); }
+        Future<int> bar5() async { return (/*severe:STATIC_TYPE_ERROR*/new Future<String>.value(/*info:DYNAMIC_CAST*/x)); }
 
         int y;
         Future<int> z;
 
         void baz() async {
-          int a = /*info:DynamicCast*/await x;
+          int a = /*info:DYNAMIC_CAST*/await x;
           int b = await y;
           int c = await z;
-          String d = /*severe:StaticTypeError*/await z;
+          String d = /*severe:STATIC_TYPE_ERROR*/await z;
         }
 
         Future<bool> get issue_264 async {
@@ -2264,7 +2446,7 @@
           if (new Random().nextBool()) {
             return true;
           } else {
-            return /*severe:StaticTypeError*/new Future<bool>.value(false);
+            return new Future<bool>.value(false);
           }
         }
     '''
@@ -2278,14 +2460,14 @@
 
         bar1() async* { yield x; }
         Stream bar2() async* { yield x; }
-        Stream<int> bar3() async* { yield (/*info:DynamicCast*/x); }
-        Stream<int> bar4() async* { yield (/*severe:StaticTypeError*/new Stream<int>()); }
+        Stream<int> bar3() async* { yield (/*info:DYNAMIC_CAST*/x); }
+        Stream<int> bar4() async* { yield (/*severe:STATIC_TYPE_ERROR*/new Stream<int>()); }
 
-        baz1() async* { yield* (/*info:DynamicCast*/x); }
-        Stream baz2() async* { yield* (/*info:DynamicCast*/x); }
-        Stream<int> baz3() async* { yield* (/*warning:DownCastComposite*/x); }
+        baz1() async* { yield* (/*info:DYNAMIC_CAST*/x); }
+        Stream baz2() async* { yield* (/*info:DYNAMIC_CAST*/x); }
+        Stream<int> baz3() async* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); }
         Stream<int> baz4() async* { yield* new Stream<int>(); }
-        Stream<int> baz5() async* { yield* (/*info:InferredTypeAllocation*/new Stream()); }
+        Stream<int> baz5() async* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/new Stream()); }
     '''
     });
 
@@ -2297,14 +2479,14 @@
 
         bar1() sync* { yield x; }
         Iterable bar2() sync* { yield x; }
-        Iterable<int> bar3() sync* { yield (/*info:DynamicCast*/x); }
-        Iterable<int> bar4() sync* { yield (/*severe:StaticTypeError*/new Iterable<int>()); }
+        Iterable<int> bar3() sync* { yield (/*info:DYNAMIC_CAST*/x); }
+        Iterable<int> bar4() sync* { yield (/*severe:STATIC_TYPE_ERROR*/new Iterable<int>()); }
 
-        baz1() sync* { yield* (/*info:DynamicCast*/x); }
-        Iterable baz2() sync* { yield* (/*info:DynamicCast*/x); }
-        Iterable<int> baz3() sync* { yield* (/*warning:DownCastComposite*/x); }
+        baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); }
+        Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); }
+        Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); }
         Iterable<int> baz4() sync* { yield* new Iterable<int>(); }
-        Iterable<int> baz5() sync* { yield* (/*info:InferredTypeAllocation*/new Iterable()); }
+        Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/new Iterable()); }
     '''
     });
   });
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 125b356..d823b20 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -5,7 +5,7 @@
 // TODO(jmesserly): this file needs to be refactored, it's a port from
 // package:dev_compiler's tests
 /// Tests for type inference.
-library test.src.task.strong.inferred_type_test;
+library analyzer.test.src.task.strong.inferred_type_test;
 
 import 'package:unittest/unittest.dart';
 
@@ -17,7 +17,7 @@
     '/main.dart': '''
       test1() {
         int x = 3;
-        x = /*severe:StaticTypeError*/"hi";
+        x = /*severe:STATIC_TYPE_ERROR*/"hi";
       }
     '''
   });
@@ -27,7 +27,7 @@
     '/main.dart': '''
       test2() {
         var x = 3;
-        x = /*severe:StaticTypeError*/"hi";
+        x = /*severe:STATIC_TYPE_ERROR*/"hi";
       }
     '''
   });
@@ -67,13 +67,13 @@
 
         test1() {
           var a = x;
-          a = /*severe:StaticTypeError*/"hi";
+          a = /*severe:STATIC_TYPE_ERROR*/"hi";
           a = 3;
           var b = y;
-          b = /*severe:StaticTypeError*/"hi";
+          b = /*severe:STATIC_TYPE_ERROR*/"hi";
           b = 4;
           var c = z;
-          c = /*severe:StaticTypeError*/"hi";
+          c = /*severe:STATIC_TYPE_ERROR*/"hi";
           c = 4;
         }
 
@@ -89,13 +89,13 @@
 
       test1() {
         var a = x;
-        a = /*severe:StaticTypeError*/"hi";
+        a = /*severe:STATIC_TYPE_ERROR*/"hi";
         a = 3;
         var b = y;
-        b = /*severe:StaticTypeError*/"hi";
+        b = /*severe:STATIC_TYPE_ERROR*/"hi";
         b = 4;
         var c = z;
-        c = /*severe:StaticTypeError*/"hi";
+        c = /*severe:STATIC_TYPE_ERROR*/"hi";
         c = 4;
       }
 
@@ -118,11 +118,11 @@
 
       test() {
         x = "hi";
-        y = /*severe:StaticTypeError*/"hi";
+        y = /*severe:STATIC_TYPE_ERROR*/"hi";
         A.x = "hi";
-        A.y = /*severe:StaticTypeError*/"hi";
+        A.y = /*severe:STATIC_TYPE_ERROR*/"hi";
         new A().x2 = "hi";
-        new A().y2 = /*severe:StaticTypeError*/"hi";
+        new A().y2 = /*severe:STATIC_TYPE_ERROR*/"hi";
       }
     '''
   });
@@ -136,8 +136,8 @@
           var y = x;
 
           test1() {
-            x = /*severe:StaticTypeError*/"hi";
-            y = /*severe:StaticTypeError*/"hi";
+            x = /*severe:STATIC_TYPE_ERROR*/"hi";
+            y = /*severe:STATIC_TYPE_ERROR*/"hi";
           }
     '''
   });
@@ -151,8 +151,8 @@
           class B { static var y = A.x; }
 
           test1() {
-            A.x = /*severe:StaticTypeError*/"hi";
-            B.y = /*severe:StaticTypeError*/"hi";
+            A.x = /*severe:STATIC_TYPE_ERROR*/"hi";
+            B.y = /*severe:STATIC_TYPE_ERROR*/"hi";
           }
     '''
   });
@@ -286,7 +286,7 @@
             x = D.d2;
             x = new C().c2;
             x = new D().d3;
-            x = /*info:DynamicCast*/new D().d4;
+            x = /*info:DYNAMIC_CAST*/new D().d4;
 
 
             // Similarly if the library contains parts.
@@ -294,7 +294,7 @@
             x = E.e2;
             x = E.e3;
             x = new E().e4;
-            x = /*info:DynamicCast*/new E().e5;
+            x = /*info:DYNAMIC_CAST*/new E().e5;
             x = new E().e6;
             x = F.f1;
             x = new F().f2;
@@ -323,32 +323,62 @@
         var j = null as B;
 
         test1() {
-          a = /*severe:StaticTypeError*/"hi";
+          a = /*severe:STATIC_TYPE_ERROR*/"hi";
           a = new B(3);
-          b = /*severe:StaticTypeError*/"hi";
+          b = /*severe:STATIC_TYPE_ERROR*/"hi";
           b = new B(3);
           c1 = [];
-          c1 = /*severe:StaticTypeError*/{};
+          c1 = /*severe:STATIC_TYPE_ERROR*/{};
           c2 = [];
-          c2 = /*severe:StaticTypeError*/{};
+          c2 = /*severe:STATIC_TYPE_ERROR*/{};
           d = {};
-          d = /*severe:StaticTypeError*/3;
+          d = /*severe:STATIC_TYPE_ERROR*/3;
           e = new A();
-          e = /*severe:StaticTypeError*/{};
+          e = /*severe:STATIC_TYPE_ERROR*/{};
           f = 3;
-          f = /*severe:StaticTypeError*/false;
+          f = /*severe:STATIC_TYPE_ERROR*/false;
           g = 1;
-          g = /*severe:StaticTypeError*/false;
-          h = /*severe:StaticTypeError*/false;
+          g = /*severe:STATIC_TYPE_ERROR*/false;
+          h = /*severe:STATIC_TYPE_ERROR*/false;
           h = new B();
           i = false;
           j = new B();
-          j = /*severe:StaticTypeError*/false;
-          j = /*severe:StaticTypeError*/[];
+          j = /*severe:STATIC_TYPE_ERROR*/false;
+          j = /*severe:STATIC_TYPE_ERROR*/[];
         }
     '''
   });
 
+  testChecker('infer list literal nested in map literal', {
+    '/main.dart': r'''
+class Resource {}
+class Folder extends Resource {}
+
+Resource getResource(String str) => null;
+
+class Foo<T> {
+  Foo(T t);
+}
+
+main() {
+  // List inside map
+  var map = <String, List<Folder>>{
+    'pkgA': /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')],
+    'pkgB': /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/')]
+  };
+  // Also try map inside list
+  var list = <Map<String, Folder>>[
+    /*info:INFERRED_TYPE_LITERAL*/{ 'pkgA': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/') },
+    /*info:INFERRED_TYPE_LITERAL*/{ 'pkgB': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/') },
+  ];
+  // Instance creation too
+  var foo = new Foo<List<Folder>>(
+    /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')]
+  );
+}
+    '''
+  });
+
   // but flags can enable this behavior.
   testChecker('infer if complex expressions read possibly inferred field', {
     '/a.dart': '''
@@ -373,7 +403,7 @@
           a = t1;
           i = t2;
           b = t3;
-          i = /*info:DynamicCast*/t4;
+          i = /*info:DYNAMIC_CAST*/t4;
           i = new B().y; // B.y was inferred though
         }
     '''
@@ -389,7 +419,7 @@
       class Bar<T extends Iterable<String>> {
         void foo(T t) {
           for (var i in t) {
-            int x = /*severe:StaticTypeError*/i;
+            int x = /*severe:STATIC_TYPE_ERROR*/i;
           }
         }
       }
@@ -397,7 +427,7 @@
       class Baz<T, E extends Iterable<T>, S extends E> {
         void foo(S t) {
           for (var i in t) {
-            int x = /*severe:StaticTypeError*/i;
+            int x = /*severe:STATIC_TYPE_ERROR*/i;
             T y = i;
           }
         }
@@ -406,36 +436,36 @@
       test() {
         var list = <Foo>[];
         for (var x in list) {
-          String y = /*severe:StaticTypeError*/x;
+          String y = /*severe:STATIC_TYPE_ERROR*/x;
         }
 
         for (dynamic x in list) {
-          String y = /*info:DynamicCast*/x;
+          String y = /*info:DYNAMIC_CAST*/x;
         }
 
-        for (String x in /*severe:StaticTypeError*/list) {
+        for (String x in /*severe:STATIC_TYPE_ERROR*/list) {
           String y = x;
         }
 
         var z;
         for(z in list) {
-          String y = /*info:DynamicCast*/z;
+          String y = /*info:DYNAMIC_CAST*/z;
         }
 
         Iterable iter = list;
-        for (Foo x in /*warning:DownCastComposite*/iter) {
+        for (Foo x in /*warning:DOWN_CAST_COMPOSITE*/iter) {
           var y = x;
         }
 
         dynamic iter2 = list;
-        for (Foo x in /*warning:DownCastComposite*/iter2) {
+        for (Foo x in /*warning:DOWN_CAST_COMPOSITE*/iter2) {
           var y = x;
         }
 
         var map = <String, Foo>{};
         // Error: map must be an Iterable.
-        for (var x in /*severe:StaticTypeError*/map) {
-          String y = /*info:DynamicCast*/x;
+        for (var x in /*severe:STATIC_TYPE_ERROR*/map) {
+          String y = /*info:DYNAMIC_CAST*/x;
         }
 
         // We're not properly inferring that map.keys is an Iterable<String>
@@ -481,9 +511,9 @@
 
       test() {
         dynamic a = new A();
-        A b = /*info:DynamicCast*/a;
-        print(/*info:DynamicInvoke*/a.x);
-        print(/*info:DynamicInvoke*/(/*info:DynamicInvoke*/a.x) + 2);
+        A b = /*info:DYNAMIC_CAST*/a;
+        print(/*info:DYNAMIC_INVOKE*/a.x);
+        print(/*info:DYNAMIC_INVOKE*/(/*info:DYNAMIC_INVOKE*/a.x) + 2);
       }
     '''
   });
@@ -496,10 +526,10 @@
 
       test5() {
         var a1 = new A();
-        a1.x = /*severe:StaticTypeError*/"hi";
+        a1.x = /*severe:STATIC_TYPE_ERROR*/"hi";
 
         A a2 = new A();
-        a2.x = /*severe:StaticTypeError*/"hi";
+        a2.x = /*severe:STATIC_TYPE_ERROR*/"hi";
       }
     '''
   });
@@ -540,11 +570,11 @@
         }
 
         class B extends A {
-          get x => 3;
+          /*severe:INVALID_FIELD_OVERRIDE*/get x => 3;
         }
 
         foo() {
-          String y = /*severe:StaticTypeError*/new B().x;
+          String y = /*severe:STATIC_TYPE_ERROR*/new B().x;
           int z = new B().x;
         }
     '''
@@ -561,7 +591,7 @@
         }
 
         foo() {
-          String y = /*severe:StaticTypeError*/new B().x;
+          String y = /*severe:STATIC_TYPE_ERROR*/new B().x;
           int z = new B().x;
         }
     '''
@@ -576,12 +606,12 @@
         }
 
         class B implements A<int> {
-          /*severe:InvalidMethodOverride*/dynamic get x => 3;
+          /*severe:INVALID_METHOD_OVERRIDE*/dynamic get x => 3;
         }
 
         foo() {
-          String y = /*info:DynamicCast*/new B().x;
-          int z = /*info:DynamicCast*/new B().x;
+          String y = /*info:DYNAMIC_CAST*/new B().x;
+          int z = /*info:DYNAMIC_CAST*/new B().x;
         }
     '''
     });
@@ -595,11 +625,11 @@
 
         class B implements A<int> {
           get x => 3;
-          get w => /*severe:StaticTypeError*/"hello";
+          get w => /*severe:STATIC_TYPE_ERROR*/"hello";
         }
 
         foo() {
-          String y = /*severe:StaticTypeError*/new B().x;
+          String y = /*severe:STATIC_TYPE_ERROR*/new B().x;
           int z = new B().x;
         }
     '''
@@ -613,11 +643,11 @@
 
         class B<E> extends A<E> {
           E y;
-          get x => y;
+          /*severe:INVALID_FIELD_OVERRIDE*/get x => y;
         }
 
         foo() {
-          int y = /*severe:StaticTypeError*/new B<String>().x;
+          int y = /*severe:STATIC_TYPE_ERROR*/new B<String>().x;
           String z = new B<String>().x;
         }
     '''
@@ -646,7 +676,7 @@
         }
 
         foo () {
-          int y = /*severe:StaticTypeError*/new B().m(null, null);
+          int y = /*severe:STATIC_TYPE_ERROR*/new B().m(null, null);
           String z = new B().m(null, null);
         }
     '''
@@ -669,7 +699,7 @@
         }
         foo () {
           int y = new C().x;
-          String y = /*severe:StaticTypeError*/new C().x;
+          String y = /*severe:STATIC_TYPE_ERROR*/new C().x;
         }
     '''
   });
@@ -705,7 +735,7 @@
         }
 
         foo () {
-          int y = /*severe:StaticTypeError*/new B<String>().m(null, null).value;
+          int y = /*severe:STATIC_TYPE_ERROR*/new B<String>().m(null, null).value;
           String z = new B<String>().m(null, null).value;
         }
     '''
@@ -719,12 +749,12 @@
           }
 
           class B implements A {
-            /*severe:InvalidMethodOverride*/dynamic get x => 3;
+            /*severe:INVALID_METHOD_OVERRIDE*/dynamic get x => 3;
           }
 
           foo() {
-            String y = /*info:DynamicCast*/new B().x;
-            int z = /*info:DynamicCast*/new B().x;
+            String y = /*info:DYNAMIC_CAST*/new B().x;
+            int z = /*info:DYNAMIC_CAST*/new B().x;
           }
       '''
     });
@@ -747,13 +777,13 @@
           final I2 a;
         }
 
-        class C1 extends A implements B {
-          /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
+        class C1 implements A, B {
+          /*severe:INVALID_METHOD_OVERRIDE*/get a => null;
         }
 
         // Still ambiguous
-        class C2 extends B implements A {
-          /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
+        class C2 implements B, A {
+          /*severe:INVALID_METHOD_OVERRIDE*/get a => null;
         }
     '''
   });
@@ -780,12 +810,12 @@
           final I2 a;
         }
 
-        class C1 extends A implements B {
+        class C1 implements A, B {
           I3 get a => null;
         }
 
-        class C2 extends A implements B {
-          /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
+        class C2 implements A, B {
+          /*severe:INVALID_METHOD_OVERRIDE*/get a => null;
         }
     '''
   });
@@ -797,13 +827,13 @@
           var x;
         }
 
-        class B extends A {
+        class B implements A {
           var x = 2;
         }
 
         foo() {
-          String y = /*info:DynamicCast*/new B().x;
-          int z = /*info:DynamicCast*/new B().x;
+          String y = /*info:DYNAMIC_CAST*/new B().x;
+          int z = /*info:DYNAMIC_CAST*/new B().x;
         }
     '''
   });
@@ -815,12 +845,12 @@
           final x;
         }
 
-        class B extends A {
+        class B implements A {
           final x = 2;
         }
 
         foo() {
-          String y = /*severe:StaticTypeError*/new B().x;
+          String y = /*severe:STATIC_TYPE_ERROR*/new B().x;
           int z = new B().x;
         }
     '''
@@ -832,7 +862,7 @@
           var x, y = 2, z = "hi";
         }
 
-        class B extends A {
+        class B implements A {
           var x = 2, y = 3, z, w = 2;
         }
 
@@ -840,14 +870,14 @@
           String s;
           int i;
 
-          s = /*info:DynamicCast*/new B().x;
-          s = /*severe:StaticTypeError*/new B().y;
+          s = /*info:DYNAMIC_CAST*/new B().x;
+          s = /*severe:STATIC_TYPE_ERROR*/new B().y;
           s = new B().z;
-          s = /*severe:StaticTypeError*/new B().w;
+          s = /*severe:STATIC_TYPE_ERROR*/new B().w;
 
-          i = /*info:DynamicCast*/new B().x;
+          i = /*info:DYNAMIC_CAST*/new B().x;
           i = new B().y;
-          i = /*severe:StaticTypeError*/new B().z;
+          i = /*severe:STATIC_TYPE_ERROR*/new B().z;
           i = new B().w;
         }
     '''
@@ -960,9 +990,9 @@
 
   testChecker('downwards inference: miscellaneous', {
     '/main.dart': '''
-      typedef (T x);
+      typedef T Function2<S, T>(S x);
       class A<T> {
-        Function2<T> x;
+        Function2<T, T> x;
         A(this.x);
       }
       void main() {
@@ -970,18 +1000,18 @@
             var x = "hello";
             var y = 3;
             void f(List<Map<int, String>> l) {};
-            f(/*info:InferredTypeLiteral*/[{y: x}]);
+            f(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/{y: x}]);
           }
           {
             int f(int x) {};
-            A<int> a = /*info:InferredTypeAllocation*/new A(f);
+            A<int> a = /*info:INFERRED_TYPE_ALLOCATION*/new A(f);
           }
       }
       '''
   });
 
   group('downwards inference on instance creations', () {
-    String info = 'info:InferredTypeAllocation';
+    String info = 'info:INFERRED_TYPE_ALLOCATION';
     String code = '''
       class A<S, T> {
         S x;
@@ -1020,59 +1050,59 @@
           A<int, String> a1 = /*$info*/new A.named(3, "hello");
           A<int, String> a2 = new A<int, String>(3, "hello");
           A<int, String> a3 = new A<int, String>.named(3, "hello");
-          A<int, String> a4 = /*severe:StaticTypeError*/new A<int, dynamic>(3, "hello");
-          A<int, String> a5 = /*severe:StaticTypeError*/new A<dynamic, dynamic>.named(3, "hello");
+          A<int, String> a4 = /*severe:STATIC_TYPE_ERROR*/new A<int, dynamic>(3, "hello");
+          A<int, String> a5 = /*severe:STATIC_TYPE_ERROR*/new A<dynamic, dynamic>.named(3, "hello");
         }
         {
-          A<int, String> a0 = /*severe:StaticTypeError*/new A("hello", 3);
-          A<int, String> a1 = /*severe:StaticTypeError*/new A.named("hello", 3);
+          A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new A(/*severe:STATIC_TYPE_ERROR*/"hello", /*severe:STATIC_TYPE_ERROR*/3);
+          A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new A.named(/*severe:STATIC_TYPE_ERROR*/"hello", /*severe:STATIC_TYPE_ERROR*/3);
         }
         {
           A<int, String> a0 = /*$info*/new B("hello", 3);
           A<int, String> a1 = /*$info*/new B.named("hello", 3);
           A<int, String> a2 = new B<String, int>("hello", 3);
           A<int, String> a3 = new B<String, int>.named("hello", 3);
-          A<int, String> a4 = /*severe:StaticTypeError*/new B<String, dynamic>("hello", 3);
-          A<int, String> a5 = /*severe:StaticTypeError*/new B<dynamic, dynamic>.named("hello", 3);
+          A<int, String> a4 = /*severe:STATIC_TYPE_ERROR*/new B<String, dynamic>("hello", 3);
+          A<int, String> a5 = /*severe:STATIC_TYPE_ERROR*/new B<dynamic, dynamic>.named("hello", 3);
         }
         {
-          A<int, String> a0 = /*severe:StaticTypeError*/new B(3, "hello");
-          A<int, String> a1 = /*severe:StaticTypeError*/new B.named(3, "hello");
+          A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new B(/*severe:STATIC_TYPE_ERROR*/3, /*severe:STATIC_TYPE_ERROR*/"hello");
+          A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new B.named(/*severe:STATIC_TYPE_ERROR*/3, /*severe:STATIC_TYPE_ERROR*/"hello");
         }
         {
           A<int, int> a0 = /*$info*/new C(3);
           A<int, int> a1 = /*$info*/new C.named(3);
           A<int, int> a2 = new C<int>(3);
           A<int, int> a3 = new C<int>.named(3);
-          A<int, int> a4 = /*severe:StaticTypeError*/new C<dynamic>(3);
-          A<int, int> a5 = /*severe:StaticTypeError*/new C<dynamic>.named(3);
+          A<int, int> a4 = /*severe:STATIC_TYPE_ERROR*/new C<dynamic>(3);
+          A<int, int> a5 = /*severe:STATIC_TYPE_ERROR*/new C<dynamic>.named(3);
         }
         {
-          A<int, int> a0 = /*severe:StaticTypeError*/new C("hello");
-          A<int, int> a1 = /*severe:StaticTypeError*/new C.named("hello");
+          A<int, int> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new C(/*severe:STATIC_TYPE_ERROR*/"hello");
+          A<int, int> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new C.named(/*severe:STATIC_TYPE_ERROR*/"hello");
         }
         {
           A<int, String> a0 = /*$info*/new D("hello");
           A<int, String> a1 = /*$info*/new D.named("hello");
           A<int, String> a2 = new D<int, String>("hello");
           A<int, String> a3 = new D<String, String>.named("hello");
-          A<int, String> a4 = /*severe:StaticTypeError*/new D<num, dynamic>("hello");
-          A<int, String> a5 = /*severe:StaticTypeError*/new D<dynamic, dynamic>.named("hello");
+          A<int, String> a4 = /*severe:STATIC_TYPE_ERROR*/new D<num, dynamic>("hello");
+          A<int, String> a5 = /*severe:STATIC_TYPE_ERROR*/new D<dynamic, dynamic>.named("hello");
         }
         {
-          A<int, String> a0 = /*severe:StaticTypeError*/new D(3);
-          A<int, String> a1 = /*severe:StaticTypeError*/new D.named(3);
+          A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new D(/*severe:STATIC_TYPE_ERROR*/3);
+          A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new D.named(/*severe:STATIC_TYPE_ERROR*/3);
         }
         { // Currently we only allow variable constraints.  Test that we reject.
-          A<C<int>, String> a0 = /*severe:StaticTypeError*/new E("hello");
+          A<C<int>, String> a0 = /*severe:STATIC_TYPE_ERROR*/new E("hello");
         }
         { // Check named and optional arguments
-          A<int, String> a0 = /*$info*/new F(3, "hello", a: [3], b: ["hello"]);
-          A<int, String> a1 = /*severe:StaticTypeError*/new F(3, "hello", a: ["hello"], b:[3]);
+          A<int, String> a0 = /*$info*/new F(3, "hello", a: /*info:INFERRED_TYPE_LITERAL*/[3], b: /*info:INFERRED_TYPE_LITERAL*/["hello"]);
+          A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new F(3, "hello", a: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"], b: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/3]);
           A<int, String> a2 = /*$info*/new F.named(3, "hello", 3, "hello");
           A<int, String> a3 = /*$info*/new F.named(3, "hello");
-          A<int, String> a4 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello", 3);
-          A<int, String> a5 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello");
+          A<int, String> a4 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello", /*severe:STATIC_TYPE_ERROR*/"hello", /*severe:STATIC_TYPE_ERROR*/3);
+          A<int, String> a5 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello", /*severe:STATIC_TYPE_ERROR*/"hello");
         }
       }
         ''';
@@ -1080,18 +1110,18 @@
   });
 
   group('downwards inference on list literals', () {
-    String info = "info:InferredTypeLiteral";
+    String info = "info:INFERRED_TYPE_LITERAL";
     String code = '''
       void foo([List<String> list1 = /*$info*/const [],
-                List<String> list2 = /*severe:StaticTypeError*/const [42]]) {
+                List<String> list2 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:STATIC_TYPE_ERROR*/42]]) {
       }
 
       void main() {
         {
           List<int> l0 = /*$info*/[];
           List<int> l1 = /*$info*/[3];
-          List<int> l2 = /*severe:StaticTypeError*/["hello"];
-          List<int> l3 = /*severe:StaticTypeError*/["hello", 3];
+          List<int> l2 = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"];
+          List<int> l3 = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3];
         }
         {
           List<dynamic> l0 = [];
@@ -1100,30 +1130,87 @@
           List<dynamic> l3 = ["hello", 3];
         }
         {
-          List<int> l0 = /*severe:StaticTypeError*/<num>[];
-          List<int> l1 = /*severe:StaticTypeError*/<num>[3];
-          List<int> l2 = /*severe:StaticTypeError*/<num>[/*severe:StaticTypeError*/"hello"];
-          List<int> l3 = /*severe:StaticTypeError*/<num>[/*severe:StaticTypeError*/"hello", 3];
+          List<int> l0 = /*severe:STATIC_TYPE_ERROR*/<num>[];
+          List<int> l1 = /*severe:STATIC_TYPE_ERROR*/<num>[3];
+          List<int> l2 = /*severe:STATIC_TYPE_ERROR*/<num>[/*severe:STATIC_TYPE_ERROR*/"hello"];
+          List<int> l3 = /*severe:STATIC_TYPE_ERROR*/<num>[/*severe:STATIC_TYPE_ERROR*/"hello", 3];
         }
         {
           Iterable<int> i0 = /*$info*/[];
           Iterable<int> i1 = /*$info*/[3];
-          Iterable<int> i2 = /*severe:StaticTypeError*/["hello"];
-          Iterable<int> i3 = /*severe:StaticTypeError*/["hello", 3];
+          Iterable<int> i2 = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"];
+          Iterable<int> i3 = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3];
         }
         {
           const List<int> c0 = /*$info*/const [];
           const List<int> c1 = /*$info*/const [3];
-          const List<int> c2 = /*severe:StaticTypeError*/const ["hello"];
-          const List<int> c3 = /*severe:StaticTypeError*/const ["hello", 3];
+          const List<int> c2 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:STATIC_TYPE_ERROR*/"hello"];
+          const List<int> c3 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:STATIC_TYPE_ERROR*/"hello", 3];
         }
       }
       ''';
     testChecker('infer downwards', {'/main.dart': code});
+
+    testChecker('infer if value types match context', {'/main.dart': r'''
+class DartType {}
+typedef void Asserter<T>(T type);
+typedef Asserter<T> AsserterBuilder<S, T>(S arg);
+
+Asserter<DartType> _isInt;
+Asserter<DartType> _isString;
+
+abstract class C {
+  static AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+  static AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf;
+
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+
+  method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {
+    assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertBOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertCOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertEOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  }
+}
+
+abstract class G<T> {
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+
+  method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {
+    assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    this.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    this.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertEOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  }
+}
+
+AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf;
+
+main() {
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  assertBOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  assertCOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  C.assertBOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  C.assertCOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+
+  C c;
+  c.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  c.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+
+  G<int> g;
+  g.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  g.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+}
+    '''});
   });
 
   group('downwards inference on function arguments', () {
-    String info = "info:InferredTypeLiteral";
+    String info = "info:INFERRED_TYPE_LITERAL";
     String code = '''
       void f0(List<int> a) {};
       void f1({List<int> a}) {};
@@ -1133,46 +1220,158 @@
       void main() {
         f0(/*$info*/[]);
         f0(/*$info*/[3]);
-        f0(/*severe:StaticTypeError*/["hello"]);
-        f0(/*severe:StaticTypeError*/["hello", 3]);
+        f0(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
+        f0(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
 
         f1(a: /*$info*/[]);
         f1(a: /*$info*/[3]);
-        f1(a: /*severe:StaticTypeError*/["hello"]);
-        f1(a: /*severe:StaticTypeError*/["hello", 3]);
+        f1(a: /*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
+        f1(a: /*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
 
         f2(/*$info*/[]);
         f2(/*$info*/[3]);
-        f2(/*severe:StaticTypeError*/["hello"]);
-        f2(/*severe:StaticTypeError*/["hello", 3]);
+        f2(/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
+        f2(/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
 
         f3(/*$info*/[]);
-        f3(/*$info*/[[3]]);
-        f3(/*severe:StaticTypeError*/[["hello"]]);
-        f3(/*severe:StaticTypeError*/[["hello"], [3]]);
+        f3(/*$info*/[/*$info*/[3]]);
+        f3(/*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
+        f3(/*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"], /*$info*/[3]]);
 
         f4(a: /*$info*/[]);
-        f4(a: /*$info*/[[3]]);
-        f4(a: /*severe:StaticTypeError*/[["hello"]]);
-        f4(a: /*severe:StaticTypeError*/[["hello"], [3]]);
+        f4(a: /*$info*/[/*$info*/[3]]);
+        f4(a: /*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
+        f4(a: /*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"], /*$info*/[3]]);
+      }
+      ''';
+    testChecker('infer downwards', {'/main.dart': code});
+  });
+
+  group('downwards inference on constructor arguments', () {
+    String info = "info:INFERRED_TYPE_LITERAL";
+    String code = '''
+      class F0 {
+        F0(List<int> a) {};
+      }
+      class F1 {
+        F1({List<int> a}) {};
+      }
+      class F2 {
+        F2(Iterable<int> a) {};
+      }
+      class F3 {
+        F3(Iterable<Iterable<int>> a) {};
+      }
+      class F4 {
+        F4({Iterable<Iterable<int>> a}) {};
+      }
+      void main() {
+        new F0(/*$info*/[]);
+        new F0(/*$info*/[3]);
+        new F0(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
+        new F0(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello",
+                                            3]);
+
+        new F1(a: /*$info*/[]);
+        new F1(a: /*$info*/[3]);
+        new F1(a: /*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
+        new F1(a: /*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+
+        new F2(/*$info*/[]);
+        new F2(/*$info*/[3]);
+        new F2(/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
+        new F2(/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+
+        new F3(/*$info*/[]);
+        new F3(/*$info*/[/*$info*/[3]]);
+        new F3(/*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
+        new F3(/*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"],
+                         /*$info*/[3]]);
+
+        new F4(a: /*$info*/[]);
+        new F4(a: /*$info*/[/*$info*/[3]]);
+        new F4(a: /*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
+        new F4(a: /*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"],
+                            /*$info*/[3]]);
+      }
+      ''';
+    testChecker('infer downwards', {'/main.dart': code});
+  });
+
+  group('downwards inference on generic constructor arguments', () {
+    String info = "info:INFERRED_TYPE_LITERAL";
+    String code = '''
+      class F0<T> {
+        F0(List<T> a) {};
+      }
+      class F1<T> {
+        F1({List<T> a}) {};
+      }
+      class F2<T> {
+        F2(Iterable<T> a) {};
+      }
+      class F3<T> {
+        F3(Iterable<Iterable<T>> a) {};
+      }
+      class F4<T> {
+        F4({Iterable<Iterable<T>> a}) {};
+      }
+      void main() {
+        new F0<int>(/*$info*/[]);
+        new F0<int>(/*$info*/[3]);
+        new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
+        new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello",
+                                            3]);
+
+        new F1<int>(a: /*$info*/[]);
+        new F1<int>(a: /*$info*/[3]);
+        new F1<int>(a: /*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
+        new F1<int>(a: /*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+
+        new F2<int>(/*$info*/[]);
+        new F2<int>(/*$info*/[3]);
+        new F2<int>(/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
+        new F2<int>(/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+
+        new F3<int>(/*$info*/[]);
+        new F3<int>(/*$info*/[/*$info*/[3]]);
+        new F3<int>(/*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
+        new F3<int>(/*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"],
+                         /*$info*/[3]]);
+
+        new F4<int>(a: /*$info*/[]);
+        new F4<int>(a: /*$info*/[/*$info*/[3]]);
+        new F4<int>(a: /*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
+        new F4<int>(a: /*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"],
+                            /*$info*/[3]]);
+
+        new F3(/*$info*/[]);
+        new F3(/*$info*/[[3]]);
+        new F3(/*$info*/[["hello"]]);
+        new F3(/*$info*/[["hello"], [3]]);
+
+        new F4(a: /*$info*/[]);
+        new F4(a: /*$info*/[[3]]);
+        new F4(a: /*$info*/[["hello"]]);
+        new F4(a: /*$info*/[["hello"], [3]]);
       }
       ''';
     testChecker('infer downwards', {'/main.dart': code});
   });
 
   group('downwards inference on map literals', () {
-    String info = "info:InferredTypeLiteral";
+    String info = "info:INFERRED_TYPE_LITERAL";
     String code = '''
       void foo([Map<int, String> m1 = /*$info*/const {1: "hello"},
-                Map<int, String> m1 = /*severe:StaticTypeError*/const {"hello": "world"}]) {
+        Map<int, String> m1 = /*$info*/const {(/*severe:STATIC_TYPE_ERROR*/"hello"): "world"}]) {
       }
       void main() {
         {
           Map<int, String> l0 = /*$info*/{};
           Map<int, String> l1 = /*$info*/{3: "hello"};
-          Map<int, String> l2 = /*severe:StaticTypeError*/{"hello": "hello"};
-          Map<int, String> l3 = /*severe:StaticTypeError*/{3: 3};
-          Map<int, String> l4 = /*severe:StaticTypeError*/{3:"hello", "hello": 3};
+          Map<int, String> l2 = /*$info*/{(/*severe:STATIC_TYPE_ERROR*/"hello"): "hello"};
+          Map<int, String> l3 = /*$info*/{3: /*severe:STATIC_TYPE_ERROR*/3};
+          Map<int, String> l4 = /*$info*/{3:"hello", (/*severe:STATIC_TYPE_ERROR*/"hello"): /*severe:STATIC_TYPE_ERROR*/3};
         }
         {
           Map<dynamic, dynamic> l0 = {};
@@ -1185,27 +1384,27 @@
           Map<dynamic, String> l0 = /*$info*/{};
           Map<dynamic, String> l1 = /*$info*/{3: "hello"};
           Map<dynamic, String> l2 = /*$info*/{"hello": "hello"};
-          Map<dynamic, String> l3 = /*severe:StaticTypeError*/{3: 3};
-          Map<dynamic, String> l4 = /*severe:StaticTypeError*/{3:"hello", "hello": 3};
+          Map<dynamic, String> l3 = /*$info*/{3: /*severe:STATIC_TYPE_ERROR*/3};
+          Map<dynamic, String> l4 = /*$info*/{3:"hello", "hello": /*severe:STATIC_TYPE_ERROR*/3};
         }
         {
           Map<int, dynamic> l0 = /*$info*/{};
           Map<int, dynamic> l1 = /*$info*/{3: "hello"};
-          Map<int, dynamic> l2 = /*severe:StaticTypeError*/{"hello": "hello"};
+          Map<int, dynamic> l2 = /*$info*/{(/*severe:STATIC_TYPE_ERROR*/"hello"): "hello"};
           Map<int, dynamic> l3 = /*$info*/{3: 3};
-          Map<int, dynamic> l3 = /*severe:StaticTypeError*/{3:"hello", "hello": 3};
+          Map<int, dynamic> l4 = /*$info*/{3:"hello", (/*severe:STATIC_TYPE_ERROR*/"hello"): 3};
         }
         {
-          Map<int, String> l0 = /*severe:StaticTypeError*/<num, dynamic>{};
-          Map<int, String> l1 = /*severe:StaticTypeError*/<num, dynamic>{3: "hello"};
-          Map<int, String> l3 = /*severe:StaticTypeError*/<num, dynamic>{3: 3};
+          Map<int, String> l0 = /*severe:STATIC_TYPE_ERROR*/<num, dynamic>{};
+          Map<int, String> l1 = /*severe:STATIC_TYPE_ERROR*/<num, dynamic>{3: "hello"};
+          Map<int, String> l3 = /*severe:STATIC_TYPE_ERROR*/<num, dynamic>{3: 3};
         }
         {
           const Map<int, String> l0 = /*$info*/const {};
           const Map<int, String> l1 = /*$info*/const {3: "hello"};
-          const Map<int, String> l2 = /*severe:StaticTypeError*/const {"hello": "hello"};
-          const Map<int, String> l3 = /*severe:StaticTypeError*/const {3: 3};
-          const Map<int, String> l4 = /*severe:StaticTypeError*/const {3:"hello", "hello": 3};
+          const Map<int, String> l2 = /*$info*/const {(/*severe:STATIC_TYPE_ERROR*/"hello"): "hello"};
+          const Map<int, String> l3 = /*$info*/const {3: /*severe:STATIC_TYPE_ERROR*/3};
+          const Map<int, String> l4 = /*$info*/const {3:"hello", (/*severe:STATIC_TYPE_ERROR*/"hello"): /*severe:STATIC_TYPE_ERROR*/3};
         }
       }
       ''';
@@ -1218,45 +1417,123 @@
 
       void main () {
         {
-          Function2<int, String> l0 = (int x) => null;
+          Function2<int, String> l0 = /*info:INFERRED_TYPE_CLOSURE*/(int x) => null;
           Function2<int, String> l1 = (int x) => "hello";
-          Function2<int, String> l2 = /*severe:StaticTypeError*/(String x) => "hello";
-          Function2<int, String> l3 = /*severe:StaticTypeError*/(int x) => 3;
-          Function2<int, String> l4 = /*warning:UninferredClosure should be severe:StaticTypeError*/(int x) {return 3};
+          Function2<int, String> l2 = /*severe:STATIC_TYPE_ERROR*/(String x) => "hello";
+          Function2<int, String> l3 = /*severe:STATIC_TYPE_ERROR*/(int x) => 3;
+          Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*severe:STATIC_TYPE_ERROR*/3;};
         }
         {
-          Function2<int, String> l0 = /*info:InferredTypeClosure*/(x) => null;
-          Function2<int, String> l1 = /*info:InferredTypeClosure*/(x) => "hello";
-          Function2<int, String> l2 = /*severe:StaticTypeError*/(x) => 3;
-          Function2<int, String> l3 = /*warning:UninferredClosure should be severe:StaticTypeError*/(x) {return 3};
+          Function2<int, String> l0 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) => null;
+          Function2<int, String> l1 = /*info:INFERRED_TYPE_CLOSURE*/(x) => "hello";
+          Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, severe:STATIC_TYPE_ERROR*/(x) => 3;
+          Function2<int, String> l3 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) {return /*severe:STATIC_TYPE_ERROR*/3;};
+          Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) {return /*severe:STATIC_TYPE_ERROR*/x;};
         }
         {
-          Function2<int, List<String>> l0 = (int x) => null;
-          Function2<int, List<String>> l1 = /*info:InferredTypeClosure*/(int x) => ["hello"];
-          Function2<int, List<String>> l2 = /*severe:StaticTypeError*/(String x) => ["hello"];
-          Function2<int, List<String>> l3 = /*warning:UninferredClosure should be severe:StaticTypeError*/(int x) => [3];
-          Function2<int, List<String>> l4 = /*warning:UninferredClosure should be severe:StaticTypeError*/(int x) {return [3]};
+          Function2<int, List<String>> l0 = /*info:INFERRED_TYPE_CLOSURE*/(int x) => null;
+          Function2<int, List<String>> l1 = (int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
+          Function2<int, List<String>> l2 = /*severe:STATIC_TYPE_ERROR*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
+          Function2<int, List<String>> l3 = (int x) => /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/3];
+          Function2<int, List<String>> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/3];};
         }
         {
-          Function2<int, int> l0 = /*info:InferredTypeClosure*/(x) => x;
-          Function2<int, int> l1 = /*info:InferredTypeClosure*/(x) => /*info:DynamicInvoke should be pass*/x+1;
-          Function2<int, String> l2 = /*info:InferredTypeClosure should be severe:StaticTypeError*/(x) => x;
-          Function2<int, String> l3 = /*info:InferredTypeClosure should be severe:StaticTypeError*/(x) => /*info:DynamicInvoke should be pass*/x.substring(3);
-          Function2<String, String> l4 = /*info:InferredTypeClosure*/(x) => /*info:DynamicInvoke should be pass*/x.substring(3);
+          Function2<int, int> l0 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x;
+          Function2<int, int> l1 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x+1;
+          Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, severe:STATIC_TYPE_ERROR*/(x) => x;
+          Function2<int, String> l3 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) => /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/x.substring(3);
+          Function2<String, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x.substring(3);
         }
       }
       '''
   });
 
+  testChecker('downwards inference initializing formal, default formal', {
+    '/main.dart': '''
+      typedef T Function2<S, T>([S x]);
+      class Foo {
+        List<int> x;
+        Foo([this.x = /*info:INFERRED_TYPE_LITERAL*/const [1]]);
+        Foo.named([List<int> x = /*info:INFERRED_TYPE_LITERAL*/const [1]]);
+      }
+      void f([List<int> l = /*info:INFERRED_TYPE_LITERAL*/const [1]]) {}
+// We do this inference in an early task but don't preserve the infos.
+      Function2<List<int>, String> g = /*pass should be info:INFERRED_TYPE_CLOSURE*/([llll = /*info:INFERRED_TYPE_LITERAL*/const [1]]) => "hello";
+'''
+  });
+
+  testChecker('downwards inference async/await', {
+    '/main.dart': '''
+      import 'dart:async';
+      Future<int> test() async {
+        List<int> l0 = /*warning:DOWN_CAST_COMPOSITE should be pass*/await /*pass should be info:INFERRED_TYPE_LITERAL*/[3];
+        List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL*/[3]);
+        '''
+  });
+
+  testChecker('downwards inference foreach', {
+    '/main.dart': '''
+      import 'dart:async';
+      void main() {
+        for(int x in /*info:INFERRED_TYPE_LITERAL*/[1, 2, 3]) {
+        }
+        await for(int x in /*info:INFERRED_TYPE_ALLOCATION*/new Stream()) {
+        }
+      }
+        '''
+  });
+
+  testChecker('downwards inference yield/yield*', {
+    '/main.dart': '''
+      import 'dart:async';
+        Stream<List<int>> foo() async* {
+          yield /*info:INFERRED_TYPE_LITERAL*/[];
+          yield /*severe:STATIC_TYPE_ERROR*/new Stream();
+          yield* /*severe:STATIC_TYPE_ERROR*/[];
+          yield* /*info:INFERRED_TYPE_ALLOCATION*/new Stream();
+        }
+
+        Iterable<Map<int, int>> bar() sync* {
+          yield /*info:INFERRED_TYPE_LITERAL*/{};
+          yield /*severe:STATIC_TYPE_ERROR*/new List();
+          yield* /*severe:STATIC_TYPE_ERROR*/{};
+          yield* /*info:INFERRED_TYPE_ALLOCATION*/new List();
+        }
+        '''
+  });
+
+  testChecker('downwards inference, annotations', {
+    '/main.dart': '''
+        class Foo {
+          const Foo(List<String> l);
+          const Foo.named(List<String> l);
+        }
+        @Foo(/*info:INFERRED_TYPE_LITERAL*/const [])
+        class Bar {}
+        @Foo.named(/*info:INFERRED_TYPE_LITERAL*/const [])
+        class Baz {}
+        '''
+  });
+
+  testChecker('downwards inference, assignment statements', {
+    '/main.dart': '''
+    void main() {
+      List<int> l;
+      l = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"];
+      l = (l = /*info:INFERRED_TYPE_LITERAL*/[1]);
+    }
+'''
+  });
+
   testChecker('inferred initializing formal checks default value', {
     '/main.dart': '''
       class Foo {
         var x = 1;
-        Foo([this.x = /*severe:StaticTypeError*/"1"]);
+        Foo([this.x = /*severe:STATIC_TYPE_ERROR*/"1"]);
       }'''
   });
 
-  group('quasi-generics', () {
+  group('generic methods', () {
     testChecker('dart:math min/max', {
       '/main.dart': '''
         import 'dart:math';
@@ -1274,20 +1551,20 @@
           printDouble(min(1.0, 2.0));
 
           // No help for user-defined functions from num->num->num.
-          printInt(/*info:DownCastImplicit*/myMax(1, 2));
+          printInt(/*info:DOWN_CAST_IMPLICIT*/myMax(1, 2));
           printInt(myMax(1, 2) as int);
 
           // Mixing int and double means return type is num.
-          printInt(/*info:DownCastImplicit*/max(1, 2.0));
-          printInt(/*info:DownCastImplicit*/min(1, 2.0));
-          printDouble(/*info:DownCastImplicit*/max(1, 2.0));
-          printDouble(/*info:DownCastImplicit*/min(1, 2.0));
+          printInt(/*info:DOWN_CAST_IMPLICIT*/max(1, 2.0));
+          printInt(/*info:DOWN_CAST_IMPLICIT*/min(1, 2.0));
+          printDouble(/*info:DOWN_CAST_IMPLICIT*/max(1, 2.0));
+          printDouble(/*info:DOWN_CAST_IMPLICIT*/min(1, 2.0));
 
           // Types other than int and double are not accepted.
           printInt(
-              /*info:DownCastImplicit*/min(
-                  /*severe:StaticTypeError*/"hi",
-                  /*severe:StaticTypeError*/"there"));
+              /*info:DOWN_CAST_IMPLICIT*/min(
+                  /*severe:STATIC_TYPE_ERROR*/"hi",
+                  /*severe:STATIC_TYPE_ERROR*/"there"));
         }
     '''
     });
@@ -1296,7 +1573,7 @@
       '/main.dart': '''
         import 'dart:async';
 
-        Future<int> make(int x) => (/*info:InferredTypeAllocation*/new Future(() => x));
+        Future<int> make(int x) => (/*info:INFERRED_TYPE_ALLOCATION*/new Future(() => x));
 
         main() {
           Iterable<Future<int>> list = <int>[1, 2, 3].map(make);
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 330801f..0141e38 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -4,23 +4,187 @@
 
 // TODO(jmesserly): this file needs to be refactored, it's a port from
 // package:dev_compiler's tests
-library test.src.task.strong.strong_test_helper;
+library analyzer.test.src.task.strong.strong_test_helper;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/context/context.dart' show SdkAnalysisContext;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart' hide SdkAnalysisContext;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
-import 'package:analyzer/src/task/strong/rules.dart';
-import 'package:logging/logging.dart'; // TODO(jmesserly): remove
-import 'package:source_span/source_span.dart'; // TODO(jmesserly): remove
+import 'package:logging/logging.dart';
+import 'package:source_span/source_span.dart';
 import 'package:unittest/unittest.dart';
 
+const String GREEN_COLOR = '\u001b[32m';
+
+const String NO_COLOR = '\u001b[0m';
+
+const String _CYAN_COLOR = '\u001b[36m';
+
+const String _MAGENTA_COLOR = '\u001b[35m';
+
+const String _RED_COLOR = '\u001b[31m';
+
+/// Sample mock SDK sources.
+final Map<String, String> mockSdkSources = {
+  // The list of types below is derived from:
+  //   * types we use via our smoke queries, including HtmlElement and
+  //     types from `_typeHandlers` (deserialize.dart)
+  //   * types that are used internally by the resolver (see
+  //   _initializeFrom in resolver.dart).
+  'dart:core': '''
+        library dart.core;
+
+        void print(Object o) {}
+
+        class Object {
+          int get hashCode {}
+          Type get runtimeType {}
+          String toString(){}
+          bool ==(other){}
+        }
+        class Function {}
+        class StackTrace {}
+        class Symbol {}
+        class Type {}
+
+        class String {
+          String operator +(String other) {}
+          String substring(int len) {}
+        }
+        class bool {}
+        class num {
+          num operator +(num other) {}
+        }
+        class int extends num {
+          bool operator<(num other) {}
+          int operator-() {}
+        }
+        class double extends num {}
+        class DateTime {}
+        class Null {}
+
+        class Deprecated {
+          final String expires;
+          const Deprecated(this.expires);
+        }
+        const Object deprecated = const Deprecated("next release");
+        class _Override { const _Override(); }
+        const Object override = const _Override();
+        class _Proxy { const _Proxy(); }
+        const Object proxy = const _Proxy();
+
+        class Iterable<E> {
+          Iterable/*<R>*/ map/*<R>*/(/*=R*/ f(E e));
+
+          /*=R*/ fold/*<R>*/(/*=R*/ initialValue,
+              /*=R*/ combine(/*=R*/ previousValue, E element));
+        }
+        class List<E> implements Iterable<E> {
+          List([int length]);
+          List.filled(int length, E fill);
+        }
+        class Map<K, V> {
+          Iterable<K> get keys {}
+        }
+        ''',
+  'dart:async': '''
+        class Future<T> {
+          Future(computation()) {}
+          Future.value(T t) {}
+          static Future<List/*<T>*/> wait/*<T>*/(
+              Iterable<Future/*<T>*/> futures) => null;
+          Future/*<R>*/ then/*<R>*/(/*=R*/ onValue(T value)) => null;
+        }
+        class Stream<T> {}
+  ''',
+  'dart:html': '''
+        library dart.html;
+        class HtmlElement {}
+        ''',
+  'dart:math': '''
+        library dart.math;
+        class Random {
+          bool nextBool() {}
+        }
+        num/*=T*/ min/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) => null;
+        num/*=T*/ max/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) => null;
+        ''',
+};
+
+/// Returns an ANSII color escape sequence corresponding to [levelName]. Colors
+/// are defined for: severe, error, warning, or info. Returns null if the level
+/// name is not recognized.
+String colorOf(String levelName) {
+  levelName = levelName.toLowerCase();
+  if (levelName == 'shout' || levelName == 'severe' || levelName == 'error') {
+    return _RED_COLOR;
+  }
+  if (levelName == 'warning') return _MAGENTA_COLOR;
+  if (levelName == 'info') return _CYAN_COLOR;
+  return null;
+}
+
+SourceSpanWithContext createSpanHelper(
+    LineInfo lineInfo, int start, int end, Source source, String content) {
+  var startLoc = locationForOffset(lineInfo, source.uri, start);
+  var endLoc = locationForOffset(lineInfo, source.uri, end);
+
+  var lineStart = startLoc.offset - startLoc.column;
+  // Find the end of the line. This is not exposed directly on LineInfo, but
+  // we can find it pretty easily.
+  // TODO(jmesserly): for now we do the simple linear scan. Ideally we can get
+  // some help from the LineInfo API.
+  int lineEnd = endLoc.offset;
+  int lineNum = lineInfo.getLocation(lineEnd).lineNumber;
+  while (lineEnd < content.length &&
+      lineInfo.getLocation(++lineEnd).lineNumber == lineNum);
+
+  var text = content.substring(start, end);
+  var lineText = content.substring(lineStart, lineEnd);
+  return new SourceSpanWithContext(startLoc, endLoc, text, lineText);
+}
+
+String errorCodeName(ErrorCode errorCode) {
+  var name = errorCode.name;
+  final prefix = 'STRONG_MODE_';
+  if (name.startsWith(prefix)) {
+    return name.substring(prefix.length);
+  } else {
+    // TODO(jmesserly): this is for backwards compat, but not sure it's very
+    // useful to log this.
+    return 'AnalyzerMessage';
+  }
+}
+
+// TODO(jmesserly): can we reuse the same mock SDK as Analyzer tests?
+SourceLocation locationForOffset(LineInfo lineInfo, Uri uri, int offset) {
+  var loc = lineInfo.getLocation(offset);
+  return new SourceLocation(offset,
+      sourceUrl: uri, line: loc.lineNumber - 1, column: loc.columnNumber - 1);
+}
+
+/// Returns all libraries transitively imported or exported from [start].
+List<LibraryElement> reachableLibraries(LibraryElement start) {
+  var results = <LibraryElement>[];
+  var seen = new Set();
+  void find(LibraryElement lib) {
+    if (seen.contains(lib)) return;
+    seen.add(lib);
+    results.add(lib);
+    lib.importedLibraries.forEach(find);
+    lib.exportedLibraries.forEach(find);
+  }
+  find(start);
+  return results;
+}
+
 /// Run the checker on a program with files contents as indicated in
 /// [testFiles].
 ///
@@ -47,6 +211,7 @@
 ///
 void testChecker(String name, Map<String, String> testFiles) {
   test(name, () {
+    AnalysisEngine.instance.processRequiredPlugins();
     expect(testFiles.containsKey('/main.dart'), isTrue,
         reason: '`/main.dart` is missing in testFiles');
 
@@ -60,9 +225,9 @@
     });
     var uriResolver = new TestUriResolver(provider);
     // Enable task model strong mode
-    AnalysisEngine.instance.useTaskModel = true;
     var context = AnalysisEngine.instance.createAnalysisContext();
     context.analysisOptions.strongMode = true;
+    context.analysisOptions.strongModeHints = true;
 
     context.sourceFactory = new SourceFactory([
       new MockDartSdk(mockSdkSources, reportMissing: true).resolver,
@@ -76,7 +241,7 @@
 
     var collector = new _ErrorCollector();
     var checker = new CodeChecker(
-        new TypeRules(context.typeProvider), collector,
+        context.typeProvider, new StrongTypeSystemImpl(), collector,
         hints: true);
 
     // Extract expectations from the comments in the test files, and
@@ -92,6 +257,13 @@
 
         var librarySource = context.getLibrariesContaining(source).single;
         var resolved = context.resolveCompilationUnit2(source, librarySource);
+        var analyzerErrors = context
+            .getErrors(source)
+            .errors
+            .where((error) =>
+                error.errorCode.name.startsWith('STRONG_MODE_INFERRED_TYPE'))
+            .toList();
+        errors.addAll(analyzerErrors);
         checker.visitCompilationUnit(resolved);
 
         new _ExpectedErrorVisitor(errors).validate(resolved);
@@ -100,17 +272,55 @@
   });
 }
 
-class _ErrorCollector implements AnalysisErrorListener {
-  List<AnalysisError> errors;
-  final bool hints;
-  _ErrorCollector({this.hints: true});
+/// Dart SDK which contains a mock implementation of the SDK libraries. May be
+/// used to speed up execution when most of the core libraries is not needed.
+class MockDartSdk implements DartSdk {
+  final Map<Uri, _MockSdkSource> _sources = {};
+  final bool reportMissing;
+  final Map<String, SdkLibrary> _libs = {};
+  final String sdkVersion = '0';
+  final AnalysisContext context = new SdkAnalysisContext();
+  DartUriResolver _resolver;
+  MockDartSdk(Map<String, String> sources, {this.reportMissing}) {
+    sources.forEach((uriString, contents) {
+      var uri = Uri.parse(uriString);
+      _sources[uri] = new _MockSdkSource(uri, contents);
+      _libs[uriString] = new SdkLibraryImpl(uri.path)
+        ..setDart2JsLibrary()
+        ..setVmLibrary();
+    });
+    _resolver = new DartUriResolver(this);
+    context.sourceFactory = new SourceFactory([_resolver]);
+  }
+  DartUriResolver get resolver => _resolver;
 
-  void onError(AnalysisError error) {
-    // Unless DDC hints are requested, filter them out.
-    var HINT = ErrorSeverity.INFO.ordinal;
-    if (hints || error.errorCode.errorSeverity.ordinal > HINT) {
-      errors.add(error);
+  List<SdkLibrary> get sdkLibraries => _libs.values.toList();
+
+  List<String> get uris => _sources.keys.map((uri) => '$uri').toList();
+  Source fromEncoding(UriKind kind, Uri uri) {
+    if (kind != UriKind.DART_URI) {
+      throw new UnsupportedError('expected dart: uri kind, got $kind.');
     }
+    return _getSource(uri);
+  }
+
+  @override
+  Source fromFileUri(Uri uri) {
+    throw new UnsupportedError('MockDartSdk.fromFileUri');
+  }
+
+  SdkLibrary getSdkLibrary(String dartUri) => _libs[dartUri];
+
+  Source mapDartUri(String dartUri) => _getSource(Uri.parse(dartUri));
+
+  Source _getSource(Uri uri) {
+    var src = _sources[uri];
+    if (src == null) {
+      if (reportMissing) print('warning: missing mock for $uri.');
+      _sources[uri] =
+          src = new _MockSdkSource(uri, 'library dart.${uri.path};');
+    }
+    return src;
   }
 }
 
@@ -130,6 +340,57 @@
   }
 }
 
+class _ErrorCollector implements AnalysisErrorListener {
+  List<AnalysisError> errors;
+  final bool hints;
+  _ErrorCollector({this.hints: true});
+
+  void onError(AnalysisError error) {
+    // Unless DDC hints are requested, filter them out.
+    var HINT = ErrorSeverity.INFO.ordinal;
+    if (hints || error.errorCode.errorSeverity.ordinal > HINT) {
+      errors.add(error);
+    }
+  }
+}
+
+/// Describes an expected message that should be produced by the checker.
+class _ErrorExpectation {
+  final Level level;
+  final String typeName;
+  _ErrorExpectation(this.level, this.typeName);
+
+  String toString() => '$level $typeName';
+
+  static _ErrorExpectation parse(String descriptor) {
+    descriptor = descriptor.trim();
+    var tokens = descriptor.split(' ');
+    if (tokens.length == 1) return _parse(tokens[0]);
+    expect(tokens.length, 4, reason: 'invalid error descriptor');
+    expect(tokens[1], "should", reason: 'invalid error descriptor');
+    expect(tokens[2], "be", reason: 'invalid error descriptor');
+    if (tokens[0] == "pass") return null;
+    // TODO(leafp) For now, we just use whatever the current expectation is,
+    // eventually we could do more automated reporting here.
+    return _parse(tokens[0]);
+  }
+
+  static _ErrorExpectation _parse(String descriptor) {
+    var tokens = descriptor.split(':');
+    expect(tokens.length, 2, reason: 'invalid error descriptor');
+    var name = tokens[0].toUpperCase();
+    var typeName = tokens[1];
+
+    var level =
+        Level.LEVELS.firstWhere((l) => l.name == name, orElse: () => null);
+    expect(level, isNotNull,
+        reason: 'invalid level in error descriptor: `${tokens[0]}`');
+    expect(typeName, isNotNull,
+        reason: 'invalid type in error descriptor: ${tokens[1]}');
+    return new _ErrorExpectation(level, typeName);
+  }
+}
+
 class _ExpectedErrorVisitor extends UnifyingAstVisitor {
   final Set<AnalysisError> _actualErrors;
   CompilationUnit _unit;
@@ -165,19 +426,37 @@
         var commentText = '$comment';
         var start = commentText.lastIndexOf('/*');
         var end = commentText.lastIndexOf('*/');
-        if (start != -1 && end != -1) {
+        if (start != -1 &&
+            end != -1 &&
+            !commentText.startsWith('/*<', start) &&
+            !commentText.startsWith('/*=', start)) {
           expect(start, lessThan(end));
           var errors = commentText.substring(start + 2, end).split(',');
           var expectations =
               errors.map(_ErrorExpectation.parse).where((x) => x != null);
 
-          for (var e in expectations) _expectError(node, e);
+          for (var e in expectations) {
+            _expectError(node, e);
+          }
         }
       }
     }
     return super.visitNode(node);
   }
 
+  Level _actualErrorLevel(AnalysisError actual) {
+    return const <ErrorSeverity, Level>{
+      ErrorSeverity.ERROR: Level.SEVERE,
+      ErrorSeverity.WARNING: Level.WARNING,
+      ErrorSeverity.INFO: Level.INFO
+    }[actual.errorCode.errorSeverity];
+  }
+
+  SourceSpan _createSpan(int offset, int len) {
+    return createSpanHelper(_unit.lineInfo, offset, offset + len,
+        _unit.element.source, _unitSourceCode);
+  }
+
   void _expectError(AstNode node, _ErrorExpectation expected) {
     // See if we can find the expected error in our actual errors
     for (var actual in _actualErrors) {
@@ -200,139 +479,12 @@
     fail('expected error was not reported at:\n\n$levelName: $msg');
   }
 
-  Level _actualErrorLevel(AnalysisError actual) {
-    return const <ErrorSeverity, Level>{
-      ErrorSeverity.ERROR: Level.SEVERE,
-      ErrorSeverity.WARNING: Level.WARNING,
-      ErrorSeverity.INFO: Level.INFO
-    }[actual.errorCode.errorSeverity];
-  }
-
   String _formatActualError(AnalysisError actual) {
     var span = _createSpan(actual.offset, actual.length);
     var levelName = _actualErrorLevel(actual).name.toLowerCase();
     var msg = span.message(actual.message, color: colorOf(levelName));
     return '$levelName: [${errorCodeName(actual.errorCode)}] $msg';
   }
-
-  SourceSpan _createSpan(int offset, int len) {
-    return createSpanHelper(_unit.lineInfo, offset, offset + len,
-        _unit.element.source, _unitSourceCode);
-  }
-}
-
-SourceLocation locationForOffset(LineInfo lineInfo, Uri uri, int offset) {
-  var loc = lineInfo.getLocation(offset);
-  return new SourceLocation(offset,
-      sourceUrl: uri, line: loc.lineNumber - 1, column: loc.columnNumber - 1);
-}
-
-SourceSpanWithContext createSpanHelper(
-    LineInfo lineInfo, int start, int end, Source source, String content) {
-  var startLoc = locationForOffset(lineInfo, source.uri, start);
-  var endLoc = locationForOffset(lineInfo, source.uri, end);
-
-  var lineStart = startLoc.offset - startLoc.column;
-  // Find the end of the line. This is not exposed directly on LineInfo, but
-  // we can find it pretty easily.
-  // TODO(jmesserly): for now we do the simple linear scan. Ideally we can get
-  // some help from the LineInfo API.
-  int lineEnd = endLoc.offset;
-  int lineNum = lineInfo.getLocation(lineEnd).lineNumber;
-  while (lineEnd < content.length &&
-      lineInfo.getLocation(++lineEnd).lineNumber == lineNum);
-
-  var text = content.substring(start, end);
-  var lineText = content.substring(lineStart, lineEnd);
-  return new SourceSpanWithContext(startLoc, endLoc, text, lineText);
-}
-
-/// Describes an expected message that should be produced by the checker.
-class _ErrorExpectation {
-  final Level level;
-  final String typeName;
-  _ErrorExpectation(this.level, this.typeName);
-
-  static _ErrorExpectation _parse(String descriptor) {
-    var tokens = descriptor.split(':');
-    expect(tokens.length, 2, reason: 'invalid error descriptor');
-    var name = tokens[0].toUpperCase();
-    var typeName = tokens[1];
-
-    var level =
-        Level.LEVELS.firstWhere((l) => l.name == name, orElse: () => null);
-    expect(level, isNotNull,
-        reason: 'invalid level in error descriptor: `${tokens[0]}`');
-    expect(typeName, isNotNull,
-        reason: 'invalid type in error descriptor: ${tokens[1]}');
-    return new _ErrorExpectation(level, typeName);
-  }
-
-  static _ErrorExpectation parse(String descriptor) {
-    descriptor = descriptor.trim();
-    var tokens = descriptor.split(' ');
-    if (tokens.length == 1) return _parse(tokens[0]);
-    expect(tokens.length, 4, reason: 'invalid error descriptor');
-    expect(tokens[1], "should", reason: 'invalid error descriptor');
-    expect(tokens[2], "be", reason: 'invalid error descriptor');
-    if (tokens[0] == "pass") return null;
-    // TODO(leafp) For now, we just use whatever the current expectation is,
-    // eventually we could do more automated reporting here.
-    return _parse(tokens[0]);
-  }
-
-  String toString() => '$level $typeName';
-}
-
-/// Dart SDK which contains a mock implementation of the SDK libraries. May be
-/// used to speed up execution when most of the core libraries is not needed.
-class MockDartSdk implements DartSdk {
-  final Map<Uri, _MockSdkSource> _sources = {};
-  final bool reportMissing;
-  final Map<String, SdkLibrary> _libs = {};
-  final String sdkVersion = '0';
-  List<String> get uris => _sources.keys.map((uri) => '$uri').toList();
-  final AnalysisContext context = new SdkAnalysisContext();
-  DartUriResolver _resolver;
-  DartUriResolver get resolver => _resolver;
-
-  MockDartSdk(Map<String, String> sources, {this.reportMissing}) {
-    sources.forEach((uriString, contents) {
-      var uri = Uri.parse(uriString);
-      _sources[uri] = new _MockSdkSource(uri, contents);
-      _libs[uriString] = new SdkLibraryImpl(uri.path)
-        ..setDart2JsLibrary()
-        ..setVmLibrary();
-    });
-    _resolver = new DartUriResolver(this);
-    context.sourceFactory = new SourceFactory([_resolver]);
-  }
-
-  List<SdkLibrary> get sdkLibraries => _libs.values.toList();
-  SdkLibrary getSdkLibrary(String dartUri) => _libs[dartUri];
-  Source mapDartUri(String dartUri) => _getSource(Uri.parse(dartUri));
-
-  Source fromEncoding(UriKind kind, Uri uri) {
-    if (kind != UriKind.DART_URI) {
-      throw new UnsupportedError('expected dart: uri kind, got $kind.');
-    }
-    return _getSource(uri);
-  }
-
-  Source _getSource(Uri uri) {
-    var src = _sources[uri];
-    if (src == null) {
-      if (reportMissing) print('warning: missing mock for $uri.');
-      _sources[uri] =
-          src = new _MockSdkSource(uri, 'library dart.${uri.path};');
-    }
-    return src;
-  }
-
-  @override
-  Source fromFileUri(Uri uri) {
-    throw new UnsupportedError('MockDartSdk.fromFileUri');
-  }
 }
 
 class _MockSdkSource implements Source {
@@ -340,28 +492,28 @@
   final Uri uri;
   final String _contents;
 
-  _MockSdkSource(this.uri, this._contents);
-
-  bool exists() => true;
-
-  int get hashCode => uri.hashCode;
-
   final int modificationStamp = 1;
 
+  _MockSdkSource(this.uri, this._contents);
+
   TimestampedData<String> get contents =>
       new TimestampedData(modificationStamp, _contents);
 
   String get encoding => "${uriKind.encoding}$uri";
 
-  Source get source => this;
-
   String get fullName => shortName;
 
+  int get hashCode => uri.hashCode;
+
+  bool get isInSystemLibrary => true;
+
   String get shortName => uri.path;
 
+  Source get source => this;
+
   UriKind get uriKind => UriKind.DART_URI;
 
-  bool get isInSystemLibrary => true;
+  bool exists() => true;
 
   Source resolveRelative(Uri relativeUri) =>
       throw new UnsupportedError('not expecting relative urls in dart: mocks');
@@ -369,132 +521,3 @@
   Uri resolveRelativeUri(Uri relativeUri) =>
       throw new UnsupportedError('not expecting relative urls in dart: mocks');
 }
-
-/// Sample mock SDK sources.
-final Map<String, String> mockSdkSources = {
-  // The list of types below is derived from:
-  //   * types we use via our smoke queries, including HtmlElement and
-  //     types from `_typeHandlers` (deserialize.dart)
-  //   * types that are used internally by the resolver (see
-  //   _initializeFrom in resolver.dart).
-  'dart:core': '''
-        library dart.core;
-
-        void print(Object o) {}
-
-        class Object {
-          int get hashCode {}
-          Type get runtimeType {}
-          String toString(){}
-          bool ==(other){}
-        }
-        class Function {}
-        class StackTrace {}
-        class Symbol {}
-        class Type {}
-
-        class String {
-          String operator +(String other) {}
-        }
-        class bool {}
-        class num {
-          num operator +(num other) {}
-        }
-        class int extends num {
-          bool operator<(num other) {}
-          int operator-() {}
-        }
-        class double extends num {}
-        class DateTime {}
-        class Null {}
-
-        class Deprecated {
-          final String expires;
-          const Deprecated(this.expires);
-        }
-        const Object deprecated = const Deprecated("next release");
-        class _Override { const _Override(); }
-        const Object override = const _Override();
-        class _Proxy { const _Proxy(); }
-        const Object proxy = const _Proxy();
-
-        class Iterable<E> {
-          fold(initialValue, combine(previousValue, E element)) {}
-          Iterable map(f(E element)) {}
-        }
-        class List<E> implements Iterable<E> {
-          List([int length]);
-          List.filled(int length, E fill);
-        }
-        class Map<K, V> {
-          Iterable<K> get keys {}
-        }
-        ''',
-  'dart:async': '''
-        class Future<T> {
-          Future(computation()) {}
-          Future.value(T t) {}
-          Future then(onValue(T value)) {}
-          static Future<List> wait(Iterable<Future> futures) {}
-        }
-        class Stream<T> {}
-  ''',
-  'dart:html': '''
-        library dart.html;
-        class HtmlElement {}
-        ''',
-  'dart:math': '''
-        library dart.math;
-        class Random {
-          bool nextBool() {}
-        }
-        num min(num x, num y) {}
-        num max(num x, num y) {}
-        ''',
-};
-
-/// Returns all libraries transitively imported or exported from [start].
-List<LibraryElement> reachableLibraries(LibraryElement start) {
-  var results = <LibraryElement>[];
-  var seen = new Set();
-  void find(LibraryElement lib) {
-    if (seen.contains(lib)) return;
-    seen.add(lib);
-    results.add(lib);
-    lib.importedLibraries.forEach(find);
-    lib.exportedLibraries.forEach(find);
-  }
-  find(start);
-  return results;
-}
-
-String errorCodeName(ErrorCode errorCode) {
-  var name = errorCode.name;
-  final prefix = 'dev_compiler.';
-  if (name.startsWith(prefix)) {
-    return name.substring(prefix.length);
-  } else {
-    // TODO(jmesserly): this is for backwards compat, but not sure it's very
-    // useful to log this.
-    return 'AnalyzerMessage';
-  }
-}
-
-/// Returns an ANSII color escape sequence corresponding to [levelName]. Colors
-/// are defined for: severe, error, warning, or info. Returns null if the level
-/// name is not recognized.
-String colorOf(String levelName) {
-  levelName = levelName.toLowerCase();
-  if (levelName == 'shout' || levelName == 'severe' || levelName == 'error') {
-    return _RED_COLOR;
-  }
-  if (levelName == 'warning') return _MAGENTA_COLOR;
-  if (levelName == 'info') return _CYAN_COLOR;
-  return null;
-}
-
-const String _RED_COLOR = '\u001b[31m';
-const String _MAGENTA_COLOR = '\u001b[35m';
-const String _CYAN_COLOR = '\u001b[36m';
-const String GREEN_COLOR = '\u001b[32m';
-const String NO_COLOR = '\u001b[0m';
diff --git a/pkg/analyzer/test/src/task/strong_mode_test.dart b/pkg/analyzer/test/src/task/strong_mode_test.dart
index ff87d92..6859d48 100644
--- a/pkg/analyzer/test/src/task/strong_mode_test.dart
+++ b/pkg/analyzer/test/src/task/strong_mode_test.dart
@@ -2,10 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.strong_mode_test;
+library analyzer.test.src.task.strong_mode_test;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:unittest/unittest.dart';
@@ -338,6 +339,29 @@
     expect(getterB.returnType, getterA.returnType);
   }
 
+  void test_inferCompilationUnit_fieldFormal() {
+    InstanceMemberInferrer inferrer = createInferrer;
+    String fieldName = 'f';
+    CompilationUnitElement unit = resolve('''
+class A {
+  final $fieldName = 0;
+  A([this.$fieldName = 'hello']);
+}
+''');
+    ClassElement classA = unit.getType('A');
+    FieldElement fieldA = classA.getField(fieldName);
+    FieldFormalParameterElement paramA =
+        classA.unnamedConstructor.parameters[0];
+    expect(fieldA.type.isDynamic, isTrue);
+    expect(paramA.type.isDynamic, isTrue);
+
+    inferrer.inferCompilationUnit(unit);
+
+    DartType intType = inferrer.typeProvider.intType;
+    expect(fieldA.type, intType);
+    expect(paramA.type, intType);
+  }
+
   void test_inferCompilationUnit_getter_multiple_different() {
     InstanceMemberInferrer inferrer = createInferrer;
     String getterName = 'g';
@@ -498,87 +522,6 @@
     expect(getterB.returnType, getterA.returnType);
   }
 
-  void test_inferCompilationUnit_setter_single() {
-    InstanceMemberInferrer inferrer = createInferrer;
-    String setterName = 'g';
-    CompilationUnitElement unit = resolve('''
-class A {
-  set $setterName(int x) {}
-}
-class B extends A {
-  set $setterName(x) {}
-}
-''');
-    ClassElement classA = unit.getType('A');
-    FieldElement fieldA = classA.getField(setterName);
-    PropertyAccessorElement setterA = classA.getSetter(setterName);
-    ClassElement classB = unit.getType('B');
-    FieldElement fieldB = classB.getField(setterName);
-    PropertyAccessorElement setterB = classB.getSetter(setterName);
-    expect(fieldB.type.isDynamic, isTrue);
-    expect(setterB.parameters[0].type.isDynamic, isTrue);
-
-    inferrer.inferCompilationUnit(unit);
-
-    expect(fieldB.type, fieldA.type);
-    expect(setterB.parameters[0].type, setterA.parameters[0].type);
-  }
-
-  void test_inferCompilationUnit_setter_single_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
-    String setterName = 'g';
-    CompilationUnitElement unit = resolve('''
-class A<E> {
-  set $setterName(E x) {}
-}
-class B<E> extends A<E> {
-  set $setterName(x) {}
-}
-''');
-    ClassElement classB = unit.getType('B');
-    DartType typeBE = classB.typeParameters[0].type;
-    FieldElement fieldB = classB.getField(setterName);
-    PropertyAccessorElement setterB = classB.getSetter(setterName);
-    expect(fieldB.type.isDynamic, isTrue);
-    expect(setterB.parameters[0].type.isDynamic, isTrue);
-
-    inferrer.inferCompilationUnit(unit);
-
-    expect(fieldB.type, typeBE);
-    expect(setterB.parameters[0].type, typeBE);
-  }
-
-  void test_inferCompilationUnit_setter_single_inconsistentAccessors() {
-    InstanceMemberInferrer inferrer = createInferrer;
-    String getterName = 'g';
-    CompilationUnitElement unit = resolve('''
-class A {
-  int get $getterName => 0;
-  set $getterName(String value) {}
-}
-class B extends A {
-  set $getterName(x) {}
-}
-''');
-    ClassElement classA = unit.getType('A');
-    PropertyAccessorElement setterA = classA.getSetter(getterName);
-    ClassElement classB = unit.getType('B');
-    FieldElement fieldB = classB.getField(getterName);
-    PropertyAccessorElement setterB = classB.getSetter(getterName);
-    expect(fieldB.type.isDynamic, isTrue);
-    expect(setterB.parameters[0].type.isDynamic, isTrue);
-
-    inferrer.inferCompilationUnit(unit);
-
-    // Expected behavior is that the getter is inferred: getters and setters
-    // are treated as independent methods.
-    expect(setterB.parameters[0].type, setterA.parameters[0].type);
-
-    // Note that B's synthetic field type will be String. This matches what
-    // resolver would do if we explicitly typed the parameter as 'String'
-    expect(fieldB.type, setterB.parameters[0].type);
-  }
-
   void test_inferCompilationUnit_invalid_inheritanceCycle() {
     InstanceMemberInferrer inferrer = createInferrer;
     CompilationUnitElement unit = resolve('''
@@ -689,7 +632,8 @@
     expect(parameterC.type.isDynamic, isTrue);
   }
 
-  void test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired() {
+  void
+      test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired() {
     InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
@@ -955,27 +899,85 @@
         reason: 'function type should still have type arguments');
   }
 
-  void test_inferCompilationUnit_fieldFormal() {
+  void test_inferCompilationUnit_setter_single() {
     InstanceMemberInferrer inferrer = createInferrer;
-    String fieldName = 'f';
+    String setterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A {
-  final $fieldName = 0;
-  A([this.$fieldName = 'hello']);
+  set $setterName(int x) {}
+}
+class B extends A {
+  set $setterName(x) {}
 }
 ''');
     ClassElement classA = unit.getType('A');
-    FieldElement fieldA = classA.getField(fieldName);
-    FieldFormalParameterElement paramA =
-        classA.unnamedConstructor.parameters[0];
-    expect(fieldA.type.isDynamic, isTrue);
-    expect(paramA.type.isDynamic, isTrue);
+    FieldElement fieldA = classA.getField(setterName);
+    PropertyAccessorElement setterA = classA.getSetter(setterName);
+    ClassElement classB = unit.getType('B');
+    FieldElement fieldB = classB.getField(setterName);
+    PropertyAccessorElement setterB = classB.getSetter(setterName);
+    expect(fieldB.type.isDynamic, isTrue);
+    expect(setterB.parameters[0].type.isDynamic, isTrue);
 
     inferrer.inferCompilationUnit(unit);
 
-    DartType intType = inferrer.typeProvider.intType;
-    expect(fieldA.type, intType);
-    expect(paramA.type, intType);
+    expect(fieldB.type, fieldA.type);
+    expect(setterB.parameters[0].type, setterA.parameters[0].type);
+  }
+
+  void test_inferCompilationUnit_setter_single_generic() {
+    InstanceMemberInferrer inferrer = createInferrer;
+    String setterName = 'g';
+    CompilationUnitElement unit = resolve('''
+class A<E> {
+  set $setterName(E x) {}
+}
+class B<E> extends A<E> {
+  set $setterName(x) {}
+}
+''');
+    ClassElement classB = unit.getType('B');
+    DartType typeBE = classB.typeParameters[0].type;
+    FieldElement fieldB = classB.getField(setterName);
+    PropertyAccessorElement setterB = classB.getSetter(setterName);
+    expect(fieldB.type.isDynamic, isTrue);
+    expect(setterB.parameters[0].type.isDynamic, isTrue);
+
+    inferrer.inferCompilationUnit(unit);
+
+    expect(fieldB.type, typeBE);
+    expect(setterB.parameters[0].type, typeBE);
+  }
+
+  void test_inferCompilationUnit_setter_single_inconsistentAccessors() {
+    InstanceMemberInferrer inferrer = createInferrer;
+    String getterName = 'g';
+    CompilationUnitElement unit = resolve('''
+class A {
+  int get $getterName => 0;
+  set $getterName(String value) {}
+}
+class B extends A {
+  set $getterName(x) {}
+}
+''');
+    ClassElement classA = unit.getType('A');
+    PropertyAccessorElement setterA = classA.getSetter(getterName);
+    ClassElement classB = unit.getType('B');
+    FieldElement fieldB = classB.getField(getterName);
+    PropertyAccessorElement setterB = classB.getSetter(getterName);
+    expect(fieldB.type.isDynamic, isTrue);
+    expect(setterB.parameters[0].type.isDynamic, isTrue);
+
+    inferrer.inferCompilationUnit(unit);
+
+    // Expected behavior is that the getter is inferred: getters and setters
+    // are treated as independent methods.
+    expect(setterB.parameters[0].type, setterA.parameters[0].type);
+
+    // Note that B's synthetic field type will be String. This matches what
+    // resolver would do if we explicitly typed the parameter as 'String'
+    expect(fieldB.type, setterB.parameters[0].type);
   }
 }
 
diff --git a/pkg/analyzer/test/src/task/test_all.dart b/pkg/analyzer/test/src/task/test_all.dart
index ffe976c..41e568e 100644
--- a/pkg/analyzer/test/src/task/test_all.dart
+++ b/pkg/analyzer/test/src/task/test_all.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.test_all;
+library analyzer.test.src.task.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/src/task/test_support.dart b/pkg/analyzer/test/src/task/test_support.dart
index e68952b..6db9c95 100644
--- a/pkg/analyzer/test/src/task/test_support.dart
+++ b/pkg/analyzer/test/src/task/test_support.dart
@@ -2,9 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.task.test_support;
+library analyzer.test.src.task.test_support;
 
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/task/model.dart';
 
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index f9ad08a..14226d8 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -2,13 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.test_all;
+library analyzer.test.src.test_all;
 
 import 'package:unittest/unittest.dart';
 
 import '../utils.dart';
 import 'context/test_all.dart' as context;
 import 'plugin/plugin_config_test.dart' as plugin;
+import 'summary/test_all.dart' as summary;
 import 'task/test_all.dart' as task;
 import 'util/test_all.dart' as util;
 
@@ -18,6 +19,7 @@
   group('src tests', () {
     context.main();
     plugin.main();
+    summary.main();
     task.main();
     util.main();
   });
diff --git a/pkg/analyzer/test/src/util/absolute_path_test.dart b/pkg/analyzer/test/src/util/absolute_path_test.dart
new file mode 100644
index 0000000..98b38c5
--- /dev/null
+++ b/pkg/analyzer/test/src/util/absolute_path_test.dart
@@ -0,0 +1,142 @@
+// 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.test.src.util.absolute_path_test;
+
+import 'package:analyzer/src/util/absolute_path.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(AbsolutePathContextPosixTest);
+  runReflectiveTests(AbsolutePathContextWindowsTest);
+}
+
+@reflectiveTest
+class AbsolutePathContextPosixTest {
+  AbsolutePathContext context = new AbsolutePathContext(false);
+
+  void test_append() {
+    expect(context.append(r'/path/to', r'foo.dart'), r'/path/to/foo.dart');
+  }
+
+  void test_basename() {
+    expect(context.basename(r'/path/to/foo.dart'), r'foo.dart');
+    expect(context.basename(r'/path/to'), r'to');
+    expect(context.basename(r'/path'), r'path');
+    expect(context.basename(r'/'), r'');
+  }
+
+  void test_dirname() {
+    expect(context.dirname(r'/path/to/foo.dart'), r'/path/to');
+    expect(context.dirname(r'/path/to'), r'/path');
+    expect(context.dirname(r'/path'), r'/');
+    expect(context.dirname(r'/'), r'/');
+  }
+
+  void test_isValid_absolute() {
+    expect(context.isValid(r'/foo/bar'), isTrue);
+    expect(context.isValid(r'/foo'), isTrue);
+    expect(context.isValid(r'/'), isTrue);
+    expect(context.isValid(r''), isFalse);
+    expect(context.isValid(r'foo/bar'), isFalse);
+  }
+
+  void test_isValid_normalized() {
+    expect(context.isValid(r'/foo/bar'), isTrue);
+    expect(context.isValid(r'/foo/..bar'), isTrue);
+    expect(context.isValid(r'/foo/.bar/baz'), isTrue);
+    expect(context.isValid(r'/foo/...'), isTrue);
+    expect(context.isValid(r'/foo/bar..'), isTrue);
+    expect(context.isValid(r'/foo/.../bar'), isTrue);
+    expect(context.isValid(r'/foo/.bar/.'), isFalse);
+    expect(context.isValid(r'/foo/bar/../baz'), isFalse);
+    expect(context.isValid(r'/foo/bar/..'), isFalse);
+    expect(context.isValid(r'/foo/./bar'), isFalse);
+    expect(context.isValid(r'/.'), isFalse);
+  }
+
+  void test_isWithin() {
+    expect(context.isWithin(r'/root/path', r'/root/path/a'), isTrue);
+    expect(context.isWithin(r'/root/path', r'/root/other'), isFalse);
+    expect(context.isWithin(r'/root/path', r'/root/path'), isFalse);
+  }
+
+  void test_split() {
+    expect(context.split(r'/path/to/foo'), [r'', r'path', r'to', r'foo']);
+    expect(context.split(r'/path'), [r'', r'path']);
+  }
+
+  void test_suffix() {
+    expect(context.suffix(r'/root/path', r'/root/path/a/b.dart'), r'a/b.dart');
+    expect(context.suffix(r'/root/path', r'/root/other.dart'), isNull);
+  }
+}
+
+@reflectiveTest
+class AbsolutePathContextWindowsTest {
+  AbsolutePathContext context = new AbsolutePathContext(true);
+
+  void test_append() {
+    expect(context.append(r'C:\path\to', r'foo.dart'), r'C:\path\to\foo.dart');
+  }
+
+  void test_basename() {
+    expect(context.basename(r'C:\path\to\foo.dart'), r'foo.dart');
+    expect(context.basename(r'C:\path\to'), r'to');
+    expect(context.basename(r'C:\path'), r'path');
+    expect(context.basename(r'C:\'), r'');
+  }
+
+  void test_dirname() {
+    expect(context.dirname(r'C:\path\to\foo.dart'), r'C:\path\to');
+    expect(context.dirname(r'C:\path\to'), r'C:\path');
+    expect(context.dirname(r'C:\path'), r'C:\');
+    expect(context.dirname(r'C:\'), r'C:\');
+  }
+
+  void test_isValid_absolute() {
+    expect(context.isValid(r'C:\foo\bar'), isTrue);
+    expect(context.isValid(r'c:\foo\bar'), isTrue);
+    expect(context.isValid(r'D:\foo\bar'), isTrue);
+    expect(context.isValid(r'C:\foo'), isTrue);
+    expect(context.isValid(r'C:\'), isTrue);
+    expect(context.isValid(r''), isFalse);
+    expect(context.isValid(r'foo\bar'), isFalse);
+  }
+
+  void test_isValid_normalized() {
+    expect(context.isValid(r'C:\foo\bar'), isTrue);
+    expect(context.isValid(r'C:\foo\..bar'), isTrue);
+    expect(context.isValid(r'C:\foo\.bar\baz'), isTrue);
+    expect(context.isValid(r'C:\foo\...'), isTrue);
+    expect(context.isValid(r'C:\foo\bar..'), isTrue);
+    expect(context.isValid(r'C:\foo\...\bar'), isTrue);
+    expect(context.isValid(r'C:\foo\.bar\.'), isFalse);
+    expect(context.isValid(r'C:\foo\bar\..\baz'), isFalse);
+    expect(context.isValid(r'C:\foo\bar\..'), isFalse);
+    expect(context.isValid(r'C:\foo\.\bar'), isFalse);
+    expect(context.isValid(r'C:\.'), isFalse);
+  }
+
+  void test_isWithin() {
+    expect(context.isWithin(r'C:\root\path', r'C:\root\path\a'), isTrue);
+    expect(context.isWithin(r'C:\root\path', r'C:\root\other'), isFalse);
+    expect(context.isWithin(r'C:\root\path', r'C:\root\path'), isFalse);
+  }
+
+  void test_split() {
+    expect(context.split(r'C:\path\to\foo'), [r'C:', r'path', r'to', r'foo']);
+    expect(context.split(r'C:\path'), [r'C:', r'path']);
+  }
+
+  void test_suffix() {
+    expect(
+        context.suffix(r'C:\root\path', r'C:\root\path\a\b.dart'), r'a\b.dart');
+    expect(context.suffix(r'C:\root\path', r'C:\root\other.dart'), isNull);
+  }
+}
diff --git a/pkg/analyzer/test/src/util/asserts_test.dart b/pkg/analyzer/test/src/util/asserts_test.dart
index a504e43..a3587d3 100644
--- a/pkg/analyzer/test/src/util/asserts_test.dart
+++ b/pkg/analyzer/test/src/util/asserts_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.util.asserts;
+library analyzer.test.src.util.asserts_test;
 
 import 'package:analyzer/src/util/asserts.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/glob_test.dart b/pkg/analyzer/test/src/util/glob_test.dart
new file mode 100644
index 0000000..c27ff7e
--- /dev/null
+++ b/pkg/analyzer/test/src/util/glob_test.dart
@@ -0,0 +1,133 @@
+// 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.test.src.util.glob_test;
+
+import 'package:analyzer/src/util/glob.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(GlobPosixTest);
+  runReflectiveTests(GlobWindowsTest);
+}
+
+@reflectiveTest
+class GlobPosixTest {
+  void test_case() {
+    Glob glob = new Glob(r'\', r'**.DaRt');
+    expect(glob.matches(r'aaa.dart'), isTrue);
+    expect(glob.matches(r'bbb.DART'), isTrue);
+    expect(glob.matches(r'ccc.dArT'), isTrue);
+    expect(glob.matches(r'ddd.DaRt'), isTrue);
+  }
+
+  void test_question() {
+    Glob glob = new Glob(r'/', r'?.dart');
+    expect(glob.matches(r'a.dart'), isTrue);
+    expect(glob.matches(r'b.dart'), isTrue);
+    expect(glob.matches(r'cc.dart'), isFalse);
+  }
+
+  void test_specialChars() {
+    Glob glob = new Glob(r'/', r'*.dart');
+    expect(glob.matches(r'a.dart'), isTrue);
+    expect(glob.matches('_-\a.dart'), isTrue);
+    expect(glob.matches(r'^$*?.dart'), isTrue);
+    expect(glob.matches(r'()[]{}.dart'), isTrue);
+    expect(glob.matches('\u2665.dart'), isTrue);
+  }
+
+  void test_specialChars2() {
+    Glob glob = new Glob(r'/', r'a[]b.dart');
+    expect(glob.matches(r'a[]b.dart'), isTrue);
+    expect(glob.matches(r'aNb.dart'), isFalse);
+  }
+
+  void test_star() {
+    Glob glob = new Glob(r'/', r'web/*.dart');
+    expect(glob.matches(r'web/foo.dart'), isTrue);
+    expect(glob.matches(r'web/barbaz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'web/foo.html'), isFalse);
+    // not in 'web'
+    expect(glob.matches(r'lib/foo.dart'), isFalse);
+    expect(glob.matches(r'/web/foo.dart'), isFalse);
+    // in sub-folder
+    expect(glob.matches(r'web/sub/foo.dart'), isFalse);
+  }
+
+  void test_starStar() {
+    Glob glob = new Glob(r'/', r'**.dart');
+    expect(glob.matches(r'foo/bar.dart'), isTrue);
+    expect(glob.matches(r'foo/bar/baz.dart'), isTrue);
+    expect(glob.matches(r'/foo/bar.dart'), isTrue);
+    expect(glob.matches(r'/foo/bar/baz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'/web/foo.html'), isFalse);
+  }
+
+  void test_starStar_star() {
+    Glob glob = new Glob(r'/', r'**/*.dart');
+    expect(glob.matches(r'foo/bar.dart'), isTrue);
+    expect(glob.matches(r'foo/bar/baz.dart'), isTrue);
+    expect(glob.matches(r'/foo/bar.dart'), isTrue);
+    expect(glob.matches(r'/foo/bar/baz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'/web/foo.html'), isFalse);
+  }
+}
+
+@reflectiveTest
+class GlobWindowsTest {
+  void test_case() {
+    Glob glob = new Glob(r'\', r'**.dart');
+    expect(glob.matches(r'aaa.dart'), isTrue);
+    expect(glob.matches(r'bbb.DART'), isTrue);
+    expect(glob.matches(r'ccc.dArT'), isTrue);
+    expect(glob.matches(r'ddd.DaRt'), isTrue);
+  }
+
+  void test_question() {
+    Glob glob = new Glob(r'\', r'?.dart');
+    expect(glob.matches(r'a.dart'), isTrue);
+    expect(glob.matches(r'b.dart'), isTrue);
+    expect(glob.matches(r'cc.dart'), isFalse);
+  }
+
+  void test_specialChars() {
+    Glob glob = new Glob(r'\', r'*.dart');
+    expect(glob.matches(r'a.dart'), isTrue);
+    expect(glob.matches('_-\a.dart'), isTrue);
+    expect(glob.matches(r'^$*?.dart'), isTrue);
+    expect(glob.matches(r'()[]{}.dart'), isTrue);
+    expect(glob.matches('\u2665.dart'), isTrue);
+  }
+
+  void test_star() {
+    Glob glob = new Glob(r'\', r'web/*.dart');
+    expect(glob.matches(r'web\foo.dart'), isTrue);
+    expect(glob.matches(r'web\barbaz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'web\foo.html'), isFalse);
+    // not in 'web'
+    expect(glob.matches(r'lib\foo.dart'), isFalse);
+    expect(glob.matches(r'\web\foo.dart'), isFalse);
+    // in sub-folder
+    expect(glob.matches(r'web\sub\foo.dart'), isFalse);
+  }
+
+  void test_starStar() {
+    Glob glob = new Glob(r'\', r'**.dart');
+    expect(glob.matches(r'foo\bar.dart'), isTrue);
+    expect(glob.matches(r'foo\bar\baz.dart'), isTrue);
+    expect(glob.matches(r'C:\foo\bar.dart'), isTrue);
+    expect(glob.matches(r'C:\foo\bar\baz.dart'), isTrue);
+    // does not end with 'dart'
+    expect(glob.matches(r'C:\web\foo.html'), isFalse);
+  }
+}
diff --git a/pkg/analyzer/test/src/util/lru_map_test.dart b/pkg/analyzer/test/src/util/lru_map_test.dart
index ef580a0..f460b10 100644
--- a/pkg/analyzer/test/src/util/lru_map_test.dart
+++ b/pkg/analyzer/test/src/util/lru_map_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.util.lru_map;
+library analyzer.test.src.util.lru_map_test;
 
 import 'package:analyzer/src/util/lru_map.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/test_all.dart b/pkg/analyzer/test/src/util/test_all.dart
index f611c58..d992264 100644
--- a/pkg/analyzer/test/src/util/test_all.dart
+++ b/pkg/analyzer/test/src/util/test_all.dart
@@ -2,19 +2,25 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.src.util;
+library analyzer.test.src.util.test_all;
 
 import 'package:unittest/unittest.dart';
 
 import '../../utils.dart';
+import 'absolute_path_test.dart' as absolute_path_test;
 import 'asserts_test.dart' as asserts_test;
+import 'glob_test.dart' as glob_test;
 import 'lru_map_test.dart' as lru_map_test;
+import 'yaml_test.dart' as yaml_test;
 
 /// Utility for manually running all tests.
 main() {
   initializeTestEnvironment();
-  group('task tests', () {
+  group('util tests', () {
+    absolute_path_test.main();
     asserts_test.main();
+    glob_test.main();
     lru_map_test.main();
+    yaml_test.main();
   });
 }
diff --git a/pkg/analyzer/test/src/util/yaml_test.dart b/pkg/analyzer/test/src/util/yaml_test.dart
new file mode 100644
index 0000000..feb812b
--- /dev/null
+++ b/pkg/analyzer/test/src/util/yaml_test.dart
@@ -0,0 +1,104 @@
+// 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.test.util.yaml_test;
+
+import 'package:analyzer/src/util/yaml.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+
+  group('yaml', () {
+    group('merge', () {
+      test('map', () {
+        expect(
+            merge({
+              'one': true,
+              'two': false,
+              'three': {
+                'nested': {'four': true, 'six': true}
+              }
+            }, {
+              'three': {
+                'nested': {'four': false, 'five': true},
+                'five': true
+              },
+              'seven': true
+            }),
+            equals({
+              'one': true,
+              'two': false,
+              'three': {
+                'nested': {'four': false, 'five': true, 'six': true},
+                'five': true
+              },
+              'seven': true
+            }));
+      });
+
+      test('list', () {
+        expect(merge([1, 2, 3], [2, 3, 4, 5]), equals([1, 2, 3, 4, 5]));
+      });
+
+      test('list w/ promotion', () {
+        expect(merge(['one', 'two', 'three'], {'three': false, 'four': true}),
+            equals({'one': true, 'two': true, 'three': false, 'four': true}));
+        expect(merge({'one': false, 'two': false}, ['one', 'three']),
+            equals({'one': true, 'two': false, 'three': true}));
+      });
+
+      test('map w/ list promotion', () {
+        var map1 = {
+          'one': ['a', 'b', 'c']
+        };
+        var map2 = {
+          'one': {'a': true, 'b': false}
+        };
+        var map3 = {
+          'one': {'a': true, 'b': false, 'c': true}
+        };
+        expect(merge(map1, map2), map3);
+      });
+
+      test('map w/ no promotion', () {
+        var map1 = {
+          'one': ['a', 'b', 'c']
+        };
+        var map2 = {
+          'one': {'a': 'foo', 'b': 'bar'}
+        };
+        var map3 = {
+          'one': {'a': 'foo', 'b': 'bar'}
+        };
+        expect(merge(map1, map2), map3);
+      });
+
+      test('map w/ no promotion (2)', () {
+        var map1 = {
+          'one': {'a': 'foo', 'b': 'bar'}
+        };
+        var map2 = {
+          'one': ['a', 'b', 'c']
+        };
+        var map3 = {
+          'one': ['a', 'b', 'c']
+        };
+        expect(merge(map1, map2), map3);
+      });
+
+      test('object', () {
+        expect(merge(1, 2), 2);
+        expect(merge(1, 'foo'), 'foo');
+        expect(merge({'foo': 1}, 'foo'), 'foo');
+      });
+    });
+  });
+}
+
+final Merger merger = new Merger();
+
+Object merge(Object o1, Object o2) => merger.merge(o1, o2);
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index c21cc3f..8155789 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.engine;
+library analyzer.test.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index 7c9fbe0..e162219 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -4,7 +4,11 @@
 
 library analyzer.test.utils;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:path/path.dart' as path;
 import 'package:unittest/unittest.dart';
 
@@ -12,3 +16,289 @@
   groupSep = ' | ';
   JavaFile.pathContext = path.posix;
 }
+
+/**
+ * The type of an assertion which asserts properties of [T]s.
+ */
+typedef void Asserter<T>(T type);
+
+/**
+ * The type of a function which given an [S], builds an assertion over [T]s.
+ */
+typedef Asserter<T> AsserterBuilder<S, T>(S arg);
+
+/**
+ * The type of a function which given an [S0] and an S1, builds an assertion
+ * over [T]s.
+ */
+typedef Asserter<T> AsserterBuilder2<S0, S1, T>(S0 arg0, S1 arg1);
+
+/**
+ * The type of a function which given an [R] returns an [AsserterBuilder] over
+ * [S]s and [T]s.  That is, it returns a function which given an [S], returns
+ * a function over [T]s.
+ */
+typedef AsserterBuilder<S, T> AsserterBuilderBuilder<R, S, T>(R arg);
+
+class AstFinder {
+  /**
+   * Return the declaration of the class with the given [className] in the given
+   * compilation [unit].
+   */
+  static ClassDeclaration getClass(CompilationUnit unit, String className) {
+    NodeList<CompilationUnitMember> unitMembers = unit.declarations;
+    for (CompilationUnitMember unitMember in unitMembers) {
+      if (unitMember is ClassDeclaration && unitMember.name.name == className) {
+        return unitMember;
+      }
+    }
+    fail('No class named $className in ${unit.element.source}');
+    return null;
+  }
+
+  /**
+   * Return the declaration of the constructor with the given [constructorName] in
+   * the class with the given [className] in the given compilation [unit].  If
+   * constructorName is null, return the default constructor;
+   */
+  static ConstructorDeclaration getConstructorInClass(
+      CompilationUnit unit, String className, String constructorName) {
+    ClassDeclaration unitMember = getClass(unit, className);
+    NodeList<ClassMember> classMembers = unitMember.members;
+    for (ClassMember classMember in classMembers) {
+      if (classMember is ConstructorDeclaration) {
+        if (classMember.name?.name == constructorName) {
+          return classMember;
+        }
+      }
+    }
+    fail('No constructor named $constructorName in $className');
+    return null;
+  }
+
+  /**
+   * Return the declaration of the field with the given [fieldName] in the class
+   * with the given [className] in the given compilation [unit].
+   */
+  static VariableDeclaration getFieldInClass(
+      CompilationUnit unit, String className, String fieldName) {
+    ClassDeclaration unitMember = getClass(unit, className);
+    NodeList<ClassMember> classMembers = unitMember.members;
+    for (ClassMember classMember in classMembers) {
+      if (classMember is FieldDeclaration) {
+        NodeList<VariableDeclaration> fields = classMember.fields.variables;
+        for (VariableDeclaration field in fields) {
+          if (field.name.name == fieldName) {
+            return field;
+          }
+        }
+      }
+    }
+    fail('No field named $fieldName in $className');
+    return null;
+  }
+
+  /**
+   * Return the element of the field with the given [fieldName] in the class
+   * with the given [className] in the given compilation [unit].
+   */
+  static FieldElement getFieldInClassElement(
+      CompilationUnit unit, String className, String fieldName) {
+    return getFieldInClass(unit, className, fieldName)?.name?.staticElement;
+  }
+
+  /**
+   * Return the declaration of the method with the given [methodName] in the
+   * class with the given [className] in the given compilation [unit].
+   */
+  static MethodDeclaration getMethodInClass(
+      CompilationUnit unit, String className, String methodName) {
+    ClassDeclaration unitMember = getClass(unit, className);
+    NodeList<ClassMember> classMembers = unitMember.members;
+    for (ClassMember classMember in classMembers) {
+      if (classMember is MethodDeclaration) {
+        if (classMember.name.name == methodName) {
+          return classMember;
+        }
+      }
+    }
+    fail('No method named $methodName in $className');
+    return null;
+  }
+
+  /**
+   * Return the statements in the body of a the method with the given
+   * [methodName] in the class with the given [className] in the given
+   * compilation [unit].
+   */
+  static List<Statement> getStatementsInMethod(
+      CompilationUnit unit, String className, String methodName) {
+    MethodDeclaration method = getMethodInClass(unit, className, methodName);
+    BlockFunctionBody body = method.body;
+    return body.block.statements;
+  }
+
+  /**
+   * Return the statements in the body of the top-level function with the given
+   * [functionName] in the given compilation [unit].
+   */
+  static List<Statement> getStatementsInTopLevelFunction(
+      CompilationUnit unit, String functionName) {
+    FunctionDeclaration function = getTopLevelFunction(unit, functionName);
+    BlockFunctionBody body = function.functionExpression.body;
+    return body.block.statements;
+  }
+
+  /**
+   * Return the declaration of the top-level function with the given
+   * [functionName] in the given compilation [unit].
+   */
+  static FunctionDeclaration getTopLevelFunction(
+      CompilationUnit unit, String functionName) {
+    NodeList<CompilationUnitMember> unitMembers = unit.declarations;
+    for (CompilationUnitMember unitMember in unitMembers) {
+      if (unitMember is FunctionDeclaration) {
+        if (unitMember.name.name == functionName) {
+          return unitMember;
+        }
+      }
+    }
+    fail('No toplevel function named $functionName found');
+    return null;
+  }
+
+  /**
+   * Return the declaration of the top-level variable with the given
+   * [variableName] in the given compilation [unit].
+   */
+  static VariableDeclaration getTopLevelVariable(
+      CompilationUnit unit, String variableName) {
+    NodeList<CompilationUnitMember> unitMembers = unit.declarations;
+    for (CompilationUnitMember unitMember in unitMembers) {
+      if (unitMember is TopLevelVariableDeclaration) {
+        NodeList<VariableDeclaration> variables =
+            unitMember.variables.variables;
+        for (VariableDeclaration variable in variables) {
+          if (variable.name.name == variableName) {
+            return variable;
+          }
+        }
+      }
+    }
+    fail('No toplevel variable named $variableName found');
+    return null;
+  }
+
+  /**
+   * Return the top-level variable element with the given [name].
+   */
+  static TopLevelVariableElement getTopLevelVariableElement(
+      CompilationUnit unit, String name) {
+    return getTopLevelVariable(unit, name)?.name?.staticElement;
+  }
+}
+
+/**
+ * Class for compositionally building up assertions on types
+ */
+class TypeAssertions {
+  // TODO(leafp): Make these matchers.
+  // https://www.dartdocs.org/documentation/matcher/0.12.0%2B1/matcher/Matcher-class.html
+
+  /* Provides primitive types for basic type assertions */
+  final TypeProvider _typeProvider;
+
+  TypeAssertions(this._typeProvider);
+
+  /**
+   * Primitive assertion for the dynamic type
+   */
+  Asserter<DartType> get isDynamic => isType(_typeProvider.dynamicType);
+
+  /**
+   * Primitive assertion for the int type
+   */
+  Asserter<DartType> get isInt => isType(_typeProvider.intType);
+
+  /**
+   * Primitive assertion for the list type
+   */
+  Asserter<DartType> get isList => sameElement(_typeProvider.listType);
+
+  /**
+   * Primitive assertion for the map type
+   */
+  Asserter<DartType> get isMap => sameElement(_typeProvider.mapType);
+
+  /**
+   * Primitive assertion for the num type
+   */
+  Asserter<DartType> get isNum => isType(_typeProvider.numType);
+
+  /**
+   * Primitive assertion for the string type
+   */
+  Asserter<DartType> get isString => isType(_typeProvider.stringType);
+
+  /**
+   * Given a type, produce an assertion that a type has the same element.
+   */
+  Asserter<DartType> hasElement(Element element) =>
+      (DartType type) => expect(element, same(type.element));
+
+  /**
+   * Given assertions for the argument and return types, produce an
+   *  assertion over unary function types.
+   */
+  Asserter<DartType> isFunction2Of(
+          Asserter<DartType> argType, Asserter<DartType> returnType) =>
+      (DartType type) {
+        FunctionType fType = (type as FunctionType);
+        argType(fType.normalParameterTypes[0]);
+        returnType(fType.returnType);
+      };
+
+  /**
+   * Given an assertion for the base type and assertions over the type
+   * parameters, produce an assertion over instantations.
+   */
+  AsserterBuilder<List<Asserter<DartType>>, DartType> isInstantiationOf(
+          Asserter<DartType> baseAssert) =>
+      (List<Asserter<DartType>> argAsserts) => (DartType type) {
+            InterfaceType t = (type as InterfaceType);
+            baseAssert(t);
+            List<DartType> typeArguments = t.typeArguments;
+            expect(typeArguments, hasLength(argAsserts.length));
+            for (int i = 0; i < typeArguments.length; i++) {
+              argAsserts[i](typeArguments[i]);
+            }
+          };
+
+  /**
+   * Assert that a type is the List type, and that the given assertion holds
+   * over the type parameter.
+   */
+  Asserter<InterfaceType> isListOf(Asserter<DartType> argAssert) =>
+      isInstantiationOf(isList)([argAssert]);
+
+  /**
+   * Assert that a type is the Map type, and that the given assertions hold
+   * over the type parameters.
+   */
+  Asserter<InterfaceType> isMapOf(
+          Asserter<DartType> argAssert0, Asserter<DartType> argAssert1) =>
+      isInstantiationOf(isMap)([argAssert0, argAssert1]);
+
+  /**
+   * Assert that one type is the same as another
+   */
+  Asserter<DartType> isType(DartType argument) => (DartType t) {
+        expect(t, same(argument));
+      };
+
+  /**
+   * Given a type, produce an assertion that a type has the same element.
+   */
+  Asserter<DartType> sameElement(DartType elementType) =>
+      hasElement(elementType.element);
+}
diff --git a/pkg/analyzer/tool/generate_files b/pkg/analyzer/tool/generate_files
index 4d0b220..4f0ea0d 100755
--- a/pkg/analyzer/tool/generate_files
+++ b/pkg/analyzer/tool/generate_files
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
@@ -48,3 +48,4 @@
 
 cd "${SCRIPT_DIR}"
 "${DART}" "${VM_OPTIONS[@]}" "task_dependency_graph/generate.dart"
+"${DART}" "${VM_OPTIONS[@]}" "summary/generate.dart"
diff --git a/pkg/analyzer/tool/summary/build_sdk_summary.dart b/pkg/analyzer/tool/summary/build_sdk_summary.dart
new file mode 100644
index 0000000..db17c57
--- /dev/null
+++ b/pkg/analyzer/tool/summary/build_sdk_summary.dart
@@ -0,0 +1,87 @@
+import 'dart:io';
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart';
+
+main(List<String> args) {
+  if (args.length < 1 || args.length > 2) {
+    _printUsage();
+    return;
+  }
+  //
+  // Prepare output file path.
+  //
+  String outputFilePath = args[0];
+  if (FileSystemEntity.isDirectorySync(outputFilePath)) {
+    print("'$outputFilePath' is a directory.");
+    _printUsage();
+    return;
+  }
+  //
+  // Prepare SDK path.
+  //
+  String sdkPath;
+  if (args.length == 2) {
+    sdkPath = args[1];
+    if (!FileSystemEntity.isDirectorySync('$sdkPath/lib')) {
+      print("'$sdkPath/lib' does not exist.");
+      _printUsage();
+      return;
+    }
+  } else {
+    sdkPath = DirectoryBasedDartSdk.defaultSdkDirectory.getAbsolutePath();
+  }
+  //
+  // Prepare SDK.
+  //
+  DirectoryBasedDartSdk sdk = new DirectoryBasedDartSdk(new JavaFile(sdkPath));
+  AnalysisContext context = sdk.context;
+  //
+  // Serialize each SDK library.
+  //
+  List<String> prelinkedLibraryUris = <String>[];
+  List<PrelinkedLibraryBuilder> prelinkedLibraries =
+      <PrelinkedLibraryBuilder>[];
+  List<String> unlinkedUnitUris = <String>[];
+  List<UnlinkedUnitBuilder> unlinkedUnits = <UnlinkedUnitBuilder>[];
+  for (SdkLibrary lib in sdk.sdkLibraries) {
+    print('Resolving and serializing: ${lib.shortName}');
+    Source librarySource = sdk.mapDartUri(lib.shortName);
+    LibraryElement libraryElement =
+        context.computeLibraryElement(librarySource);
+    LibrarySerializationResult libraryResult =
+        serializeLibrary(libraryElement, context.typeProvider);
+    prelinkedLibraryUris.add(lib.shortName);
+    prelinkedLibraries.add(libraryResult.prelinked);
+    unlinkedUnitUris.addAll(libraryResult.unitUris);
+    unlinkedUnits.addAll(libraryResult.unlinkedUnits);
+  }
+  //
+  // Write the whole SDK bundle.
+  //
+  SdkBundleBuilder sdkBundle = encodeSdkBundle(
+      prelinkedLibraryUris: prelinkedLibraryUris,
+      prelinkedLibraries: prelinkedLibraries,
+      unlinkedUnitUris: unlinkedUnitUris,
+      unlinkedUnits: unlinkedUnits);
+  File file = new File(outputFilePath);
+  file.writeAsBytesSync(sdkBundle.toBuffer(), mode: FileMode.WRITE_ONLY);
+}
+
+/**
+ * The name of the SDK summary builder application.
+ */
+const BINARY_NAME = "build_sdk_summary";
+
+/**
+ * Print information about how to use the SDK summary builder.
+ */
+void _printUsage() {
+  print('Usage: $BINARY_NAME output_file_path [sdk_path]');
+}
diff --git a/pkg/analyzer/tool/summary/check_test.dart b/pkg/analyzer/tool/summary/check_test.dart
new file mode 100644
index 0000000..ac5f7bb
--- /dev/null
+++ b/pkg/analyzer/tool/summary/check_test.dart
@@ -0,0 +1,23 @@
+// 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.tool.summary.check_test;
+
+import 'dart:io';
+
+import 'package:analyzer/src/codegen/tools.dart';
+import 'package:path/path.dart';
+
+import 'generate.dart';
+
+/**
+ * Check that the target file has been code generated.  If it hasn't tell the
+ * user to run generate.dart.
+ */
+main() {
+  String script = Platform.script.toFilePath(windows: Platform.isWindows);
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.checkAll(
+      pkgPath, 'tool/summary/generate.dart', <GeneratedContent>[target]);
+}
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
new file mode 100644
index 0000000..1918074
--- /dev/null
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -0,0 +1,583 @@
+// 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 file contains code to generate serialization/deserialization logic for
+ * summaries based on an "IDL" description of the summary format (written in
+ * stylized Dart).
+ *
+ * For each class in the "IDL" input, two corresponding classes are generated:
+ * - A class with the same name which represents deserialized summary data in
+ *   memory.  This class has read-only semantics.
+ * - A "builder" class which can be used to generate serialized summary data.
+ *   This class has write-only semantics.
+ *
+ * Each of the "builder" classes has a single `finish` method which writes
+ * the entity being built into the given FlatBuffer and returns the `Offset`
+ * reference to it.
+ */
+library analyzer.tool.summary.generate;
+
+import 'dart:convert';
+import 'dart:io' hide File;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:path/path.dart';
+
+import 'idl_model.dart' as idlModel;
+
+main() {
+  String script = Platform.script.toFilePath(windows: Platform.isWindows);
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.generateAll(pkgPath, <GeneratedContent>[target]);
+}
+
+final GeneratedFile target =
+    new GeneratedFile('lib/src/summary/format.dart', (String pkgPath) {
+  // Parse the input "IDL" file and pass it to the [_CodeGenerator].
+  PhysicalResourceProvider provider = new PhysicalResourceProvider(
+      PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS);
+  String idlPath = join(pkgPath, 'tool', 'summary', 'idl.dart');
+  File idlFile = provider.getFile(idlPath);
+  Source idlSource = provider.getFile(idlPath).createSource();
+  String idlText = idlFile.readAsStringSync();
+  BooleanErrorListener errorListener = new BooleanErrorListener();
+  CharacterReader idlReader = new CharSequenceReader(idlText);
+  Scanner scanner = new Scanner(idlSource, idlReader, errorListener);
+  Token tokenStream = scanner.tokenize();
+  LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+  Parser parser = new Parser(idlSource, new BooleanErrorListener());
+  CompilationUnit idlParsed = parser.parseCompilationUnit(tokenStream);
+  _CodeGenerator codeGenerator = new _CodeGenerator();
+  codeGenerator.processCompilationUnit(lineInfo, idlParsed);
+  return codeGenerator._outBuffer.toString();
+});
+
+class _CodeGenerator {
+  /**
+   * Buffer in which generated code is accumulated.
+   */
+  final StringBuffer _outBuffer = new StringBuffer();
+
+  /**
+   * Current indentation level.
+   */
+  String _indentation = '';
+
+  /**
+   * Semantic model of the "IDL" input file.
+   */
+  idlModel.Idl _idl;
+
+  /**
+   * Perform basic sanity checking of the IDL (over and above that done by
+   * [extractIdl]).
+   */
+  void checkIdl() {
+    _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) {
+      for (idlModel.FieldDeclaration field in cls.fields) {
+        String fieldName = field.name;
+        idlModel.FieldType type = field.type;
+        if (type.isList) {
+          if (_idl.classes.containsKey(type.typeName)) {
+            // List of classes is ok
+          } else if (type.typeName == 'int') {
+            // List of ints is ok
+          } else if (type.typeName == 'String') {
+            // List of strings is ok
+          } else {
+            throw new Exception(
+                '$name.$fieldName: illegal type (list of ${type.typeName})');
+          }
+        }
+      }
+    });
+  }
+
+  /**
+   * Generate a string representing the Dart type which should be used to
+   * represent [type] when deserialized.
+   */
+  String dartType(idlModel.FieldType type) {
+    if (type.isList) {
+      return 'List<${type.typeName}>';
+    } else {
+      return type.typeName;
+    }
+  }
+
+  /**
+   * Generate a Dart expression representing the default value for a field
+   * having the given [type], or `null` if there is no default value.
+   */
+  String defaultValue(idlModel.FieldType type) {
+    if (type.isList) {
+      return 'const <${type.typeName}>[]';
+    } else if (_idl.enums.containsKey(type.typeName)) {
+      return '${type.typeName}.${_idl.enums[type.typeName].values[0]}';
+    } else if (type.typeName == 'int') {
+      return '0';
+    } else if (type.typeName == 'String') {
+      return "''";
+    } else if (type.typeName == 'bool') {
+      return 'false';
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Generate a string representing the Dart type which should be used to
+   * represent [type] while building a serialized data structure.
+   */
+  String encodedType(idlModel.FieldType type) {
+    String typeStr;
+    if (_idl.classes.containsKey(type.typeName)) {
+      typeStr = '${type.typeName}Builder';
+    } else {
+      typeStr = type.typeName;
+    }
+    if (type.isList) {
+      return 'List<$typeStr>';
+    } else {
+      return typeStr;
+    }
+  }
+
+  /**
+   * Process the AST in [idlParsed] and store the resulting semantic model in
+   * [_idl].  Also perform some error checking.
+   */
+  void extractIdl(LineInfo lineInfo, CompilationUnit idlParsed) {
+    _idl = new idlModel.Idl();
+    for (CompilationUnitMember decl in idlParsed.declarations) {
+      if (decl is ClassDeclaration) {
+        bool isTopLevel = false;
+        for (Annotation annotation in decl.metadata) {
+          if (annotation.arguments == null &&
+              annotation.name.name == 'topLevel') {
+            isTopLevel = true;
+          }
+        }
+        String doc = _getNodeDoc(lineInfo, decl);
+        idlModel.ClassDeclaration cls =
+            new idlModel.ClassDeclaration(doc, decl.name.name, isTopLevel);
+        _idl.classes[cls.name] = cls;
+        for (ClassMember classMember in decl.members) {
+          if (classMember is FieldDeclaration) {
+            TypeName type = classMember.fields.type;
+            bool isList = false;
+            if (type.name.name == 'List' &&
+                type.typeArguments != null &&
+                type.typeArguments.arguments.length == 1) {
+              isList = true;
+              type = type.typeArguments.arguments[0];
+            }
+            if (type.typeArguments != null) {
+              throw new Exception('Cannot handle type arguments in `$type`');
+            }
+            String doc = _getNodeDoc(lineInfo, classMember);
+            idlModel.FieldType fieldType =
+                new idlModel.FieldType(type.name.name, isList);
+            for (VariableDeclaration field in classMember.fields.variables) {
+              cls.fields.add(new idlModel.FieldDeclaration(
+                  doc, field.name.name, fieldType));
+            }
+          } else {
+            throw new Exception('Unexpected class member `$classMember`');
+          }
+        }
+      } else if (decl is EnumDeclaration) {
+        String doc = _getNodeDoc(lineInfo, decl);
+        idlModel.EnumDeclaration enm =
+            new idlModel.EnumDeclaration(doc, decl.name.name);
+        _idl.enums[enm.name] = enm;
+        for (EnumConstantDeclaration constDecl in decl.constants) {
+          enm.values.add(constDecl.name.name);
+        }
+      } else if (decl is TopLevelVariableDeclaration) {
+        // Ignore top level variable declarations; they are present just to make
+        // the IDL analyze without warnings.
+      } else {
+        throw new Exception('Unexpected declaration `$decl`');
+      }
+    }
+  }
+
+  /**
+   * Execute [callback] with two spaces added to [_indentation].
+   */
+  void indent(void callback()) {
+    String oldIndentation = _indentation;
+    try {
+      _indentation += '  ';
+      callback();
+    } finally {
+      _indentation = oldIndentation;
+    }
+  }
+
+  /**
+   * Add the string [s] to the output as a single line, indenting as
+   * appropriate.
+   */
+  void out([String s = '']) {
+    if (s == '') {
+      _outBuffer.writeln('');
+    } else {
+      _outBuffer.writeln('$_indentation$s');
+    }
+  }
+
+  void outDoc(String documentation) {
+    if (documentation != null) {
+      documentation.split('\n').forEach(out);
+    }
+  }
+
+  /**
+   * Entry point to the code generator.  Interpret the AST in [idlParsed],
+   * generate code, and output it to [_outBuffer].
+   */
+  void processCompilationUnit(LineInfo lineInfo, CompilationUnit idlParsed) {
+    extractIdl(lineInfo, idlParsed);
+    checkIdl();
+    out('// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file');
+    out('// for details. All rights reserved. Use of this source code is governed by a');
+    out('// BSD-style license that can be found in the LICENSE file.');
+    out('//');
+    out('// This file has been automatically generated.  Please do not edit it manually.');
+    out('// To regenerate the file, use the script "pkg/analyzer/tool/generate_files".');
+    out();
+    out('library analyzer.src.summary.format;');
+    out();
+    out("import 'base.dart' as base;");
+    out("import 'flat_buffers.dart' as fb;");
+    out();
+    _idl.enums.forEach((String name, idlModel.EnumDeclaration enm) {
+      outDoc(enm.documentation);
+      out('enum $name {');
+      indent(() {
+        for (String value in enm.values) {
+          out('$value,');
+        }
+      });
+      out('}');
+      out();
+    });
+    for (var cls in _idl.classes.values) {
+      List<String> builderParams = _generateBuilder(cls);
+      out();
+      _generateEncodeFunction(cls, builderParams);
+      out();
+      _generateInterface(cls);
+      out();
+      _generateReader(cls);
+      out();
+      _generateImpl(cls);
+      out();
+    }
+  }
+
+  /**
+   * Enclose [s] in quotes, escaping as necessary.
+   */
+  String quoted(String s) {
+    return JSON.encode(s);
+  }
+
+  List<String> _generateBuilder(idlModel.ClassDeclaration cls) {
+    String builderName = cls.name + 'Builder';
+    List<String> builderParams = <String>[];
+    out('class $builderName {');
+    indent(() {
+      out('bool _finished = false;');
+      // Generate fields.
+      out();
+      for (idlModel.FieldDeclaration field in cls.fields) {
+        String fieldName = field.name;
+        idlModel.FieldType type = field.type;
+        String typeStr = encodedType(type);
+        out('$typeStr _$fieldName;');
+      }
+      // Generate constructor.
+      out();
+      out('$builderName();');
+      // Generate setters.
+      for (idlModel.FieldDeclaration field in cls.fields) {
+        String fieldName = field.name;
+        String typeStr = encodedType(field.type);
+        out();
+        outDoc(field.documentation);
+        builderParams.add('$typeStr $fieldName');
+        out('void set $fieldName($typeStr _value) {');
+        indent(() {
+          String stateFieldName = '_' + fieldName;
+          out('assert(!_finished);');
+          out('$stateFieldName = _value;');
+        });
+        out('}');
+      }
+      // Generate finish.
+      if (cls.isTopLevel) {
+        out();
+        out('List<int> toBuffer() {');
+        indent(() {
+          out('fb.Builder fbBuilder = new fb.Builder();');
+          out('return fbBuilder.finish(finish(fbBuilder));');
+        });
+        out('}');
+      }
+      out();
+      out('fb.Offset finish(fb.Builder fbBuilder) {');
+      indent(() {
+        out('assert(!_finished);');
+        out('_finished = true;');
+        // Write objects and remember Offset(s).
+        cls.fields.asMap().forEach((index, idlModel.FieldDeclaration field) {
+          idlModel.FieldType fieldType = field.type;
+          String offsetName = 'offset_' + field.name;
+          if (fieldType.isList ||
+              fieldType.typeName == 'String' ||
+              _idl.classes.containsKey(fieldType.typeName)) {
+            out('fb.Offset $offsetName;');
+          }
+        });
+        cls.fields.asMap().forEach((index, idlModel.FieldDeclaration field) {
+          idlModel.FieldType fieldType = field.type;
+          String valueName = '_' + field.name;
+          String offsetName = 'offset_' + field.name;
+          String condition;
+          String writeCode;
+          if (fieldType.isList) {
+            condition = ' || $valueName.isEmpty';
+            if (_idl.classes.containsKey(fieldType.typeName)) {
+              String itemCode = 'b.finish(fbBuilder)';
+              String listCode = '$valueName.map((b) => $itemCode).toList()';
+              writeCode = '$offsetName = fbBuilder.writeList($listCode);';
+            } else if (fieldType.typeName == 'int') {
+              writeCode = '$offsetName = fbBuilder.writeListInt32($valueName);';
+            } else {
+              assert(fieldType.typeName == 'String');
+              String itemCode = 'fbBuilder.writeString(b)';
+              String listCode = '$valueName.map((b) => $itemCode).toList()';
+              writeCode = '$offsetName = fbBuilder.writeList($listCode);';
+            }
+          } else if (fieldType.typeName == 'String') {
+            writeCode = '$offsetName = fbBuilder.writeString($valueName);';
+          } else if (_idl.classes.containsKey(fieldType.typeName)) {
+            writeCode = '$offsetName = $valueName.finish(fbBuilder);';
+          }
+          if (writeCode != null) {
+            if (condition == null) {
+              out('if ($valueName != null) {');
+            } else {
+              out('if (!($valueName == null$condition)) {');
+            }
+            indent(() {
+              out(writeCode);
+            });
+            out('}');
+          }
+        });
+        // Write the table.
+        out('fbBuilder.startTable();');
+        cls.fields.asMap().forEach((index, idlModel.FieldDeclaration field) {
+          idlModel.FieldType fieldType = field.type;
+          String valueName = '_' + field.name;
+          String condition = '$valueName != null';
+          String writeCode;
+          if (fieldType.isList ||
+              fieldType.typeName == 'String' ||
+              _idl.classes.containsKey(fieldType.typeName)) {
+            String offsetName = 'offset_' + field.name;
+            condition = '$offsetName != null';
+            writeCode = 'fbBuilder.addOffset($index, $offsetName);';
+          } else if (fieldType.typeName == 'bool') {
+            condition = '$valueName == true';
+            writeCode = 'fbBuilder.addBool($index, true);';
+          } else if (fieldType.typeName == 'int') {
+            condition += ' && $valueName != ${defaultValue(fieldType)}';
+            writeCode = 'fbBuilder.addInt32($index, $valueName);';
+          } else if (_idl.enums.containsKey(fieldType.typeName)) {
+            condition += ' && $valueName != ${defaultValue(fieldType)}';
+            writeCode = 'fbBuilder.addInt32($index, $valueName.index);';
+          }
+          if (writeCode == null) {
+            throw new UnimplementedError('Writing type ${fieldType.typeName}');
+          }
+          out('if ($condition) {');
+          indent(() {
+            out(writeCode);
+          });
+          out('}');
+        });
+        out('return fbBuilder.endTable();');
+      });
+      out('}');
+    });
+    out('}');
+    return builderParams;
+  }
+
+  void _generateEncodeFunction(
+      idlModel.ClassDeclaration cls, List<String> builderParams) {
+    String className = cls.name;
+    String builderName = className + 'Builder';
+    out('$builderName encode$className({${builderParams.join(', ')}}) {');
+    indent(() {
+      out('$builderName builder = new $builderName();');
+      for (idlModel.FieldDeclaration field in cls.fields) {
+        String fieldName = field.name;
+        out('builder.$fieldName = $fieldName;');
+      }
+      out('return builder;');
+    });
+    out('}');
+  }
+
+  void _generateImpl(idlModel.ClassDeclaration cls) {
+    String name = cls.name;
+    String implName = '_${name}Impl';
+    out('class $implName implements $name {');
+    indent(() {
+      out('final fb.BufferPointer _bp;');
+      out();
+      out('$implName(this._bp);');
+      out();
+      // Write cache fields.
+      for (idlModel.FieldDeclaration field in cls.fields) {
+        String returnType = dartType(field.type);
+        String fieldName = field.name;
+        out('$returnType _$fieldName;');
+      }
+      out();
+      // Write toMap().
+      out('@override');
+      out('Map<String, Object> toMap() => {');
+      indent(() {
+        for (idlModel.FieldDeclaration field in cls.fields) {
+          String fieldName = field.name;
+          out('${quoted(fieldName)}: $fieldName,');
+        }
+      });
+      out('};');
+      // Write getters.
+      cls.fields.asMap().forEach((index, field) {
+        String fieldName = field.name;
+        idlModel.FieldType type = field.type;
+        String typeName = type.typeName;
+        // Prepare "readExpr" or "readCode" + "def"
+        String readExpr;
+        String readCode;
+        String def = defaultValue(type);
+        if (type.isList) {
+          if (typeName == 'int') {
+            String itemCode = 'const fb.Int32Reader()';
+            readCode = 'const fb.ListReader<int>($itemCode)';
+          } else if (typeName == 'String') {
+            String itemCode = 'const fb.StringReader()';
+            readCode = 'const fb.ListReader<String>($itemCode)';
+          } else {
+            String itemCode = '$typeName>(const _${typeName}Reader()';
+            readCode = 'const fb.ListReader<$itemCode)';
+          }
+        } else if (typeName == 'bool') {
+          readCode = 'const fb.BoolReader()';
+        } else if (typeName == 'int') {
+          readCode = 'const fb.Int32Reader()';
+        } else if (typeName == 'String') {
+          readCode = 'const fb.StringReader()';
+        } else if (_idl.enums.containsKey(typeName)) {
+          readExpr =
+              '$typeName.values[const fb.Int32Reader().vTableGet(_bp, $index, 0)]';
+        } else if (_idl.classes.containsKey(typeName)) {
+          readCode = 'const _${typeName}Reader()';
+        }
+        if (readExpr == null) {
+          assert(readCode != null);
+          readExpr = '$readCode.vTableGet(_bp, $index, $def)';
+        }
+        // Write the getter implementation.
+        out();
+        out('@override');
+        String returnType = dartType(type);
+        out('$returnType get $fieldName {');
+        indent(() {
+          out('_$fieldName ??= $readExpr;');
+          out('return _$fieldName;');
+        });
+        out('}');
+      });
+    });
+    out('}');
+  }
+
+  void _generateInterface(idlModel.ClassDeclaration cls) {
+    String name = cls.name;
+    outDoc(cls.documentation);
+    out('abstract class $name extends base.SummaryClass {');
+    indent(() {
+      if (cls.isTopLevel) {
+        out('factory $name.fromBuffer(List<int> buffer) {');
+        indent(() {
+          out('fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);');
+          out('return const _${name}Reader().read(rootRef);');
+        });
+        out('}');
+      }
+      cls.fields.asMap().forEach((index, field) {
+        String fieldName = field.name;
+        idlModel.FieldType type = field.type;
+        out();
+        outDoc(field.documentation);
+        out('${dartType(type)} get $fieldName;');
+      });
+    });
+    out('}');
+  }
+
+  void _generateReader(idlModel.ClassDeclaration cls) {
+    String name = cls.name;
+    String readerName = '_${name}Reader';
+    String implName = '_${name}Impl';
+    out('class $readerName extends fb.TableReader<$implName> {');
+    indent(() {
+      out('const $readerName();');
+      out();
+      out('@override');
+      out('$implName createObject(fb.BufferPointer bp) => new $implName(bp);');
+    });
+    out('}');
+  }
+
+  /**
+   * Return the documentation text of the given [node], or `null` if the [node]
+   * does not have a comment.  Each line is `\n` separated.
+   */
+  String _getNodeDoc(LineInfo lineInfo, AnnotatedNode node) {
+    Comment comment = node.documentationComment;
+    if (comment != null &&
+        comment.isDocumentation &&
+        comment.tokens.length == 1 &&
+        comment.tokens.first.type == TokenType.MULTI_LINE_COMMENT) {
+      Token token = comment.tokens.first;
+      int column = lineInfo.getLocation(token.offset).columnNumber;
+      String indent = ' ' * (column - 1);
+      return token.lexeme.split('\n').map((String line) {
+        if (line.startsWith(indent)) {
+          line = line.substring(indent.length);
+        }
+        return line;
+      }).join('\n');
+    }
+    return null;
+  }
+}
diff --git a/pkg/analyzer/tool/summary/idl.dart b/pkg/analyzer/tool/summary/idl.dart
index b450499..39e7a4a 100644
--- a/pkg/analyzer/tool/summary/idl.dart
+++ b/pkg/analyzer/tool/summary/idl.dart
@@ -57,24 +57,44 @@
 const private = null;
 
 /**
+ * Annotation describing a class which can be the top level object in an
+ * encoded summary.
+ */
+const topLevel = null;
+
+/**
  * Information about a dependency that exists between one library and another
  * due to an "import" declaration.
  */
 class PrelinkedDependency {
   /**
-   * The relative URI used to import one library from the other.
+   * The relative URI of the dependent library.  This URI is relative to the
+   * importing library, even if there are intervening `export` declarations.
+   * So, for example, if `a.dart` imports `b/c.dart` and `b/c.dart` exports
+   * `d/e.dart`, the URI listed for `a.dart`'s dependency on `e.dart` will be
+   * `b/d/e.dart`.
    */
   String uri;
+
+  /**
+   * URI for the compilation units listed in the library's `part` declarations.
+   * These URIs are relative to the importing library.
+   */
+  List<String> parts;
 }
 
 /**
  * Pre-linked summary of a library.
  */
+@topLevel
 class PrelinkedLibrary {
   /**
-   * The unlinked library summary.
+   * The pre-linked summary of all the compilation units constituting the
+   * library.  The summary of the defining compilation unit is listed first,
+   * followed by the summary of each part, in the order of the `part`
+   * declarations in the defining compilation unit.
    */
-  UnlinkedLibrary unlinked;
+  List<PrelinkedUnit> units;
 
   /**
    * The libraries that this library depends on (either via an explicit import
@@ -88,19 +108,44 @@
   List<PrelinkedDependency> dependencies;
 
   /**
-   * For each import in [UnlinkedLibrary.imports], an index into [dependencies]
+   * For each import in [UnlinkedUnit.imports], an index into [dependencies]
    * of the library being imported.
    *
    * TODO(paulberry): if [dependencies] is removed, this can be removed as
    * well, since there will effectively be a one-to-one mapping.
    */
   List<int> importDependencies;
+}
+
+/**
+ * Information about the resolution of an [UnlinkedReference].
+ */
+class PrelinkedReference {
+  /**
+   * Index into [PrelinkedLibrary.dependencies] indicating which imported library
+   * declares the entity being referred to.
+   */
+  int dependency;
 
   /**
-   * For each reference in [UnlinkedLibrary.references], information about how
-   * that reference is resolved.
+   * The kind of the entity being referred to.  For the pseudo-type `dynamic`,
+   * the kind is [PrelinkedReferenceKind.classOrEnum].
    */
-  List<PrelinkedReference> references;
+  PrelinkedReferenceKind kind;
+
+  /**
+   * Integer index indicating which unit in the imported library contains the
+   * definition of the entity.  As with indices into [PrelinkedLibrary.units],
+   * zero represents the defining compilation unit, and nonzero values
+   * represent parts in the order of the corresponding `part` declarations.
+   */
+  int unit;
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  int numTypeParameters;
 }
 
 /**
@@ -124,25 +169,51 @@
   other,
 
   /**
+   * The entity is a prefix.
+   */
+  prefix,
+
+  /**
    * The entity being referred to does not exist.
    */
   unresolved
 }
 
 /**
- * Information about the resolution of an [UnlinkedReference].
+ * Pre-linked summary of a compilation unit.
  */
-class PrelinkedReference {
+class PrelinkedUnit {
   /**
-   * Index into [UnlinkedLibrary.dependencies] indicating which imported library
-   * declares the entity being referred to.
+   * For each reference in [UnlinkedUnit.references], information about how
+   * that reference is resolved.
    */
-  int dependency;
+  List<PrelinkedReference> references;
+}
+
+/**
+ * Information about SDK.
+ */
+@topLevel
+class SdkBundle {
+  /**
+   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
+   */
+  List<String> prelinkedLibraryUris;
 
   /**
-   * The kind of the entity being referred to.
+   * Pre-linked libraries.
    */
-  PrelinkedReferenceKind kind;
+  List<PrelinkedLibrary> prelinkedLibraries;
+
+  /**
+   * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
+   */
+  List<String> unlinkedUnitUris;
+
+  /**
+   * Unlinked information for the compilation units constituting the SDK.
+   */
+  List<UnlinkedUnit> unlinkedUnits;
 }
 
 /**
@@ -155,11 +226,17 @@
   String name;
 
   /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * class is declared in.
+   * Offset of the class name relative to the beginning of the file.
    */
   @informative
-  int unit;
+  int nameOffset;
+
+  /**
+   * Documentation comment for the class, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
 
   /**
    * Type parameters of the class, if any.
@@ -174,7 +251,7 @@
   UnlinkedTypeRef supertype;
 
   /**
-   * Mixins appering in a `with` clause, if any.
+   * Mixins appearing in a `with` clause, if any.
    */
   List<UnlinkedTypeRef> mixins;
 
@@ -202,6 +279,12 @@
    * Indicates whether the class is declared using mixin application syntax.
    */
   bool isMixinApplication;
+
+  /**
+   * Indicates whether this class is the core "Object" class (and hence has no
+   * supertype)
+   */
+  bool hasNoSupertype;
 }
 
 /**
@@ -221,6 +304,30 @@
 }
 
 /**
+ * Unlinked summary information about a documentation comment.
+ */
+class UnlinkedDocumentationComment {
+  /**
+   * Text of the documentation comment, with '\r\n' replaced by '\n'.
+   *
+   * References appearing within the doc comment in square brackets are not
+   * specially encoded.
+   */
+  String text;
+
+  /**
+   * Offset of the beginning of the documentation comment relative to the
+   * beginning of the file.
+   */
+  int offset;
+
+  /**
+   * Length of the documentation comment (prior to replacing '\r\n' with '\n').
+   */
+  int length;
+}
+
+/**
  * Unlinked summary information about an enum declaration.
  */
 class UnlinkedEnum {
@@ -230,16 +337,22 @@
   String name;
 
   /**
+   * Offset of the enum name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
+   * Documentation comment for the enum, or `null` if there is no documentation
+   * comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
+
+  /**
    * Values listed in the enum declaration, in declaration order.
    */
   List<UnlinkedEnumValue> values;
-
-  /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * enum is declared in.
-   */
-  @informative
-  int unit;
 }
 
 /**
@@ -251,31 +364,19 @@
    * Name of the enumerated value.
    */
   String name;
-}
-
-/**
- * Enum used to indicate the kind of an executable.
- */
-enum UnlinkedExecutableKind {
-  /**
-   * Executable is a function or method.
-   */
-  functionOrMethod,
 
   /**
-   * Executable is a getter.
+   * Offset of the enum value name relative to the beginning of the file.
    */
-  getter,
+  @informative
+  int nameOffset;
 
   /**
-   * Executable is a setter.
+   * Documentation comment for the enum value, or `null` if there is no
+   * documentation comment.
    */
-  setter,
-
-  /**
-   * Executable is a constructor.
-   */
-  constructor
+  @informative
+  UnlinkedDocumentationComment documentationComment;
 }
 
 /**
@@ -291,12 +392,20 @@
   String name;
 
   /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * executable is declared in.  Zero for executables which are nested inside
-   * another declaration (i.e. local functions and method declarations).
+   * Offset of the executable name relative to the beginning of the file.  For
+   * named constructors, this excludes the class name and excludes the ".".
+   * For unnamed constructors, this is the offset of the class name (i.e. the
+   * offset of the second "C" in "class C { C(); }").
    */
   @informative
-  int unit;
+  int nameOffset;
+
+  /**
+   * Documentation comment for the executable, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
 
   /**
    * Type parameters of the executable, if any.  Empty if support for generic
@@ -306,8 +415,8 @@
 
   /**
    * Declared return type of the executable.  Absent if the return type is
-   * `void`.  Note that when strong mode is enabled, the actual return type may
-   * be different due to type inference.
+   * `void` or the executable is a constructor.  Note that when strong mode is
+   * enabled, the actual return type may be different due to type inference.
    */
   UnlinkedTypeRef returnType;
 
@@ -347,12 +456,75 @@
    * Indicates whether the executable is declared using the `factory` keyword.
    */
   bool isFactory;
+
+  /**
+   * Indicates whether the executable lacks an explicit return type
+   * declaration.  False for constructors and setters.
+   */
+  bool hasImplicitReturnType;
+
+  /**
+   * Indicates whether the executable is declared using the `external` keyword.
+   */
+  bool isExternal;
 }
 
 /**
- * Unlinked summary information about an export declaration.
+ * Enum used to indicate the kind of an executable.
  */
-class UnlinkedExport {
+enum UnlinkedExecutableKind {
+  /**
+   * Executable is a function or method.
+   */
+  functionOrMethod,
+
+  /**
+   * Executable is a getter.
+   */
+  getter,
+
+  /**
+   * Executable is a setter.
+   */
+  setter,
+
+  /**
+   * Executable is a constructor.
+   */
+  constructor
+}
+
+/**
+ * Unlinked summary information about an export declaration (stored outside
+ * [UnlinkedPublicNamespace]).
+ */
+class UnlinkedExportNonPublic {
+  /**
+   * Offset of the "export" keyword.
+   */
+  @informative
+  int offset;
+
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  @informative
+  int uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  @informative
+  int uriEnd;
+}
+
+/**
+ * Unlinked summary information about an export declaration (stored inside
+ * [UnlinkedPublicNamespace]).
+ */
+class UnlinkedExportPublic {
   /**
    * URI used in the source code to reference the exported library.
    */
@@ -381,12 +553,12 @@
   int offset;
 
   /**
-   * Index into [UnlinkedLibrary.prefixes] of the prefix declared by this
+   * Index into [UnlinkedUnit.references] of the prefix declared by this
    * import declaration, or zero if this import declaration declares no prefix.
    *
    * Note that multiple imports can declare the same prefix.
    */
-  int prefix;
+  int prefixReference;
 
   /**
    * Combinators contained in this import declaration.
@@ -402,89 +574,27 @@
    * Indicates whether the import declaration is implicit.
    */
   bool isImplicit;
-}
-
-/**
- * Unlinked summary of an entire library.
- */
-class UnlinkedLibrary {
-  /**
-   * Top level and prefixed names referred to by this library.
-   */
-  List<UnlinkedReference> references;
 
   /**
-   * Information about the units constituting this library.  The first unit
-   * listed is always the defining compilation unit.
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.  If [isImplicit] is true, zero.
    */
-  List<UnlinkedUnit> units;
+  @informative
+  int uriOffset;
 
   /**
-   * Name of the library (from a "library" declaration, if present).
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.  If [isImplicit] is true, zero.
    */
-  String name;
+  @informative
+  int uriEnd;
 
   /**
-   * Classes declared in the library.
+   * Offset of the prefix name relative to the beginning of the file, or zero
+   * if there is no prefix.
    */
-  List<UnlinkedClass> classes;
-
-  /**
-   * Enums declared in the library.
-   */
-  List<UnlinkedEnum> enums;
-
-  /**
-   * Top level executable objects (functions, getters, and setters) declared in
-   * the library.
-   */
-  List<UnlinkedExecutable> executables;
-
-  /**
-   * Export declarations in the library.
-   */
-  List<UnlinkedExport> exports;
-
-  /**
-   * Import declarations in the library.
-   */
-  List<UnlinkedImport> imports;
-
-  /**
-   * Typedefs declared in the library.
-   */
-  List<UnlinkedTypedef> typedefs;
-
-  /**
-   * Top level variables declared in the library.
-   */
-  List<UnlinkedVariable> variables;
-
-  /**
-   * Prefixes introduced by import declarations.  The first element in this
-   * array is a pseudo-prefix used by references made with no prefix.
-   */
-  List<UnlinkedPrefix> prefixes;
-}
-
-/**
- * Enum used to indicate the kind of a parameter.
- */
-enum UnlinkedParamKind {
-  /**
-   * Parameter is required.
-   */
-  required,
-
-  /**
-   * Parameter is positional optional (enclosed in `[]`)
-   */
-  positional,
-
-  /**
-   * Parameter is named optional (enclosed in `{}`)
-   */
-  named
+  @informative
+  int prefixOffset;
 }
 
 /**
@@ -497,6 +607,12 @@
   String name;
 
   /**
+   * Offset of the parameter name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
    * If [isFunctionTyped] is `true`, the declared return type.  If
    * [isFunctionTyped] is `false`, the declared type.  Absent if
    * [isFunctionTyped] is `true` and the declared return type is `void`.  Note
@@ -525,14 +641,109 @@
    * declared using `this.` syntax).
    */
   bool isInitializingFormal;
+
+  /**
+   * Indicates whether this parameter lacks an explicit type declaration.
+   * Always false for a function-typed parameter.
+   */
+  bool hasImplicitType;
 }
 
-class UnlinkedPrefix {
+/**
+ * Enum used to indicate the kind of a parameter.
+ */
+enum UnlinkedParamKind {
   /**
-   * The name of the prefix, or the empty string in the case of the
-   * pseudo-prefix which represents "no prefix".
+   * Parameter is required.
+   */
+  required,
+
+  /**
+   * Parameter is positional optional (enclosed in `[]`)
+   */
+  positional,
+
+  /**
+   * Parameter is named optional (enclosed in `{}`)
+   */
+  named
+}
+
+/**
+ * Unlinked summary information about a part declaration.
+ */
+class UnlinkedPart {
+  /**
+   * Offset of the URI string (including quotes) relative to the beginning of
+   * the file.
+   */
+  @informative
+  int uriOffset;
+
+  /**
+   * End of the URI string (including quotes) relative to the beginning of the
+   * file.
+   */
+  @informative
+  int uriEnd;
+}
+
+/**
+ * Unlinked summary information about a specific name contributed by a
+ * compilation unit to a library's public namespace.
+ *
+ * TODO(paulberry): add a count of generic parameters, so that resynthesis
+ * doesn't have to peek into the library to obtain this info.
+ *
+ * TODO(paulberry): for classes, add info about static members and
+ * constructors, since this will be needed to prelink info about constants.
+ *
+ * TODO(paulberry): some of this information is redundant with information
+ * elsewhere in the summary.  Consider reducing the redundancy to reduce
+ * summary size.
+ */
+class UnlinkedPublicName {
+  /**
+   * The name itself.
    */
   String name;
+
+  /**
+   * The kind of object referred to by the name.
+   */
+  PrelinkedReferenceKind kind;
+
+  /**
+   * If the entity being referred to is generic, the number of type parameters
+   * it accepts.  Otherwise zero.
+   */
+  int numTypeParameters;
+}
+
+/**
+ * Unlinked summary information about what a compilation unit contributes to a
+ * library's public namespace.  This is the subset of [UnlinkedUnit] that is
+ * required from dependent libraries in order to perform prelinking.
+ */
+@topLevel
+class UnlinkedPublicNamespace {
+  /**
+   * Public names defined in the compilation unit.
+   *
+   * TODO(paulberry): consider sorting these names to reduce unnecessary
+   * relinking.
+   */
+  List<UnlinkedPublicName> names;
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  List<UnlinkedExportPublic> exports;
+
+  /**
+   * URIs referenced by part declarations in the compilation unit.
+   */
+  List<String> parts;
 }
 
 /**
@@ -541,15 +752,20 @@
  */
 class UnlinkedReference {
   /**
-   * Name of the entity being referred to.
+   * Name of the entity being referred to.  The empty string refers to the
+   * pseudo-type `dynamic`.
    */
   String name;
 
   /**
-   * Prefix used to refer to the entity.  This is an index into
-   * [UnlinkedLibrary.prefixes].
+   * Prefix used to refer to the entity, or zero if no prefix is used.  This is
+   * an index into [UnlinkedUnit.references].
+   *
+   * Prefix references must always point backward; that is, for all i, if
+   * UnlinkedUnit.references[i].prefixReference != 0, then
+   * UnlinkedUnit.references[i].prefixReference < i.
    */
-  int prefix;
+  int prefixReference;
 }
 
 /**
@@ -562,11 +778,17 @@
   String name;
 
   /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * typedef is declared in.
+   * Offset of the typedef name relative to the beginning of the file.
    */
   @informative
-  int unit;
+  int nameOffset;
+
+  /**
+   * Documentation comment for the typedef, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
 
   /**
    * Type parameters of the typedef, if any.
@@ -594,6 +816,12 @@
   String name;
 
   /**
+   * Offset of the type parameter name relative to the beginning of the file.
+   */
+  @informative
+  int nameOffset;
+
+  /**
    * Bound of the type parameter, if a bound is explicitly declared.  Otherwise
    * null.
    */
@@ -605,23 +833,35 @@
  */
 class UnlinkedTypeRef {
   /**
-   * Index into [UnlinkedLibrary.references] for the type being referred to, or
+   * Index into [UnlinkedUnit.references] for the type being referred to, or
    * zero if this is a reference to a type parameter.
+   *
+   * Note that since zero is also a valid index into
+   * [UnlinkedUnit.references], we cannot distinguish between references to
+   * type parameters and references to types by checking [reference] against
+   * zero.  To distinguish between references to type parameters and references
+   * to types, check whether [paramReference] is zero.
    */
   int reference;
 
   /**
-   * If this is a reference to a type parameter, one-based index into
-   * [UnlinkedClass.typeParameters] or [UnlinkedTypedef.typeParameters] for the
-   * parameter being referenced.  Otherwise zero.
+   * If this is a reference to a type parameter, one-based index into the list
+   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
+   * Bruijn index conventions; that is, innermost parameters come first, and
+   * if a class or method has multiple parameters, they are indexed from right
+   * to left.  So for instance, if the enclosing declaration is
    *
-   * If generic method syntax is enabled, this may also be a one-based index
-   * into [UnlinkedExecutable.typeParameters].  Note that this creates an
-   * ambiguity since it allows executables with type parameters to be nested
-   * inside other declarations with type parameters (which might themselves be
-   * executables).  The ambiguity is resolved by considering this to be a
-   * one-based index into a list that concatenates all type parameters that are
-   * in scope, listing the outermost type parameters first.
+   *     class C<T,U> {
+   *       m<V,W> {
+   *         ...
+   *       }
+   *     }
+   *
+   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
+   * respectively.
+   *
+   * If the type being referred to is not a type parameter, [paramReference] is
+   * zero.
    */
   int paramReference;
 
@@ -633,18 +873,88 @@
 }
 
 /**
- * Unlinked summary information about a compilation unit ("part file").  Note
- * that since a declaration can be moved from one part file to another without
- * changing semantics, the declarations themselves aren't stored here; they are
- * stored in [UnlinkedLibrary] and they refer to [UnlinkedUnit]s via an index
- * into [UnlinkedLibrary.units].
+ * Unlinked summary information about a compilation unit ("part file").
  */
+@topLevel
 class UnlinkedUnit {
   /**
-   * String used in the defining compilation unit to reference the part file.
-   * Empty for the defining compilation unit itself.
+   * Name of the library (from a "library" declaration, if present).
    */
-  String uri;
+  String libraryName;
+
+  /**
+   * Offset of the library name relative to the beginning of the file (or 0 if
+   * the library has no name).
+   */
+  @informative
+  int libraryNameOffset;
+
+  /**
+   * Length of the library name as it appears in the source code (or 0 if the
+   * library has no name).
+   */
+  @informative
+  int libraryNameLength;
+
+  /**
+   * Documentation comment for the library, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment libraryDocumentationComment;
+
+  /**
+   * Unlinked public namespace of this compilation unit.
+   */
+  UnlinkedPublicNamespace publicNamespace;
+
+  /**
+   * Top level and prefixed names referred to by this compilation unit.  The
+   * zeroth element of this array is always populated and always represents a
+   * reference to the pseudo-type "dynamic".
+   */
+  List<UnlinkedReference> references;
+
+  /**
+   * Classes declared in the compilation unit.
+   */
+  List<UnlinkedClass> classes;
+
+  /**
+   * Enums declared in the compilation unit.
+   */
+  List<UnlinkedEnum> enums;
+
+  /**
+   * Top level executable objects (functions, getters, and setters) declared in
+   * the compilation unit.
+   */
+  List<UnlinkedExecutable> executables;
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  List<UnlinkedExportNonPublic> exports;
+
+  /**
+   * Import declarations in the compilation unit.
+   */
+  List<UnlinkedImport> imports;
+
+  /**
+   * Part declarations in the compilation unit.
+   */
+  List<UnlinkedPart> parts;
+
+  /**
+   * Typedefs declared in the compilation unit.
+   */
+  List<UnlinkedTypedef> typedefs;
+
+  /**
+   * Top level variables declared in the compilation unit.
+   */
+  List<UnlinkedVariable> variables;
 }
 
 /**
@@ -658,12 +968,17 @@
   String name;
 
   /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * variable is declared in.  Zero for variables which are nested inside
-   * another declaration (i.e. local variables and fields).
+   * Offset of the variable name relative to the beginning of the file.
    */
   @informative
-  int unit;
+  int nameOffset;
+
+  /**
+   * Documentation comment for the variable, or `null` if there is no
+   * documentation comment.
+   */
+  @informative
+  UnlinkedDocumentationComment documentationComment;
 
   /**
    * Declared type of the variable.  Note that when strong mode is enabled, the
@@ -689,4 +1004,9 @@
    * Indicates whether the variable is declared using the `const` keyword.
    */
   bool isConst;
+
+  /**
+   * Indicates whether this variable lacks an explicit type declaration.
+   */
+  bool hasImplicitType;
 }
diff --git a/pkg/analyzer/tool/summary/idl_model.dart b/pkg/analyzer/tool/summary/idl_model.dart
new file mode 100644
index 0000000..07be039
--- /dev/null
+++ b/pkg/analyzer/tool/summary/idl_model.dart
@@ -0,0 +1,104 @@
+// 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 file contains a set of concrete classes representing an in-memory
+ * semantic model of the IDL used to code generate summary serialization and
+ * deserialization code.
+ */
+library analyzer.tool.summary.idl_model;
+
+/**
+ * Information about a single class defined in the IDL.
+ */
+class ClassDeclaration extends Declaration {
+  /**
+   * Fields defined in the class.
+   */
+  final List<FieldDeclaration> fields = <FieldDeclaration>[];
+
+  /**
+   * Indicates whether the class has the `topLevel` annotation.
+   */
+  final bool isTopLevel;
+
+  ClassDeclaration(String documentation, String name, this.isTopLevel)
+      : super(documentation, name);
+}
+
+/**
+ * Information about a declaration in the IDL.
+ */
+class Declaration {
+  /**
+   * The optional documentation, may be `null`.
+   */
+  final String documentation;
+
+  /**
+   * The name of the declaration.
+   */
+  final String name;
+
+  Declaration(this.documentation, this.name);
+}
+
+/**
+ * Information about a single enum defined in the IDL.
+ */
+class EnumDeclaration extends Declaration {
+  /**
+   * List of enumerated values.
+   */
+  final List<String> values = <String>[];
+
+  EnumDeclaration(String documentation, String name)
+      : super(documentation, name);
+}
+
+/**
+ * Information about a single class field defined in the IDL.
+ */
+class FieldDeclaration extends Declaration {
+  /**
+   * The file of the field.
+   */
+  final FieldType type;
+
+  FieldDeclaration(String documentation, String name, this.type)
+      : super(documentation, name);
+}
+
+/**
+ * Information about the type of a class field defined in the IDL.
+ */
+class FieldType {
+  /**
+   * Type of the field (e.g. 'int').
+   */
+  final String typeName;
+
+  /**
+   * Indicates whether this field contains a list of the type specified in
+   * [typeName].
+   */
+  final bool isList;
+
+  FieldType(this.typeName, this.isList);
+}
+
+/**
+ * Top level representation of the summary IDL.
+ */
+class Idl {
+  /**
+   * Classes defined in the IDL.
+   */
+  final Map<String, ClassDeclaration> classes = <String, ClassDeclaration>{};
+
+  /**
+   * Enums defined in the IDL.
+   */
+  final Map<String, EnumDeclaration> enums = <String, EnumDeclaration>{};
+}
diff --git a/pkg/analyzer/tool/task_dependency_graph/check_test.dart b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
index a2d1118..c689d63 100644
--- a/pkg/analyzer/tool/task_dependency_graph/check_test.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
@@ -2,10 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library task_dependency_graph.check_test;
+library analyzer.tool.task_dependency_graph.check_test;
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:path/path.dart';
 
 import 'generate.dart';
@@ -16,19 +17,7 @@
  */
 main() {
   String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  Driver driver = new Driver();
-  if (!driver.checkFile()) {
-    print('${driver.file.absolute} does not have expected contents.');
-    print('Please regenerate using:');
-    String executable = Platform.executable;
-    String packageRoot = '';
-    if (Platform.packageRoot.isNotEmpty) {
-      packageRoot = ' --package-root=${Platform.packageRoot}';
-    }
-    String generateScript = join(dirname(script), 'generate.dart');
-    print('  $executable$packageRoot $generateScript');
-    exit(1);
-  } else {
-    print('Generated file is up to date.');
-  }
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.checkAll(pkgPath, 'tool/task_dependency_graph/generate.dart',
+      <GeneratedContent>[target]);
 }
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index a98eaba..9b960f3 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -15,16 +15,18 @@
  *   of exactly one task.
  * - Convert this tool to use package_config to find the package map.
  */
-library task_dependency_graph.generate;
+library analyzer.tool.task_dependency_graph.generate;
 
 import 'dart:io' hide File;
 import 'dart:io' as io;
 
 import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -32,14 +34,21 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:path/path.dart' as path;
+import 'package:path/path.dart';
 
 /**
  * Generate the target .dot file.
  */
 main() {
-  new Driver().generateFile();
+  String script = Platform.script.toFilePath(windows: Platform.isWindows);
+  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  GeneratedContent.generateAll(pkgPath, <GeneratedContent>[target]);
 }
 
+final GeneratedFile target = new GeneratedFile(
+    'tool/task_dependency_graph/tasks.dot',
+    (String pkgPath) => new Driver(pkgPath).generateFileContents());
+
 typedef void GetterFinderCallback(PropertyAccessorElement element);
 
 class Driver {
@@ -52,9 +61,7 @@
   InterfaceType extensionPointIdType;
   final String rootDir;
 
-  Driver()
-      : rootDir =
-            findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
+  Driver(String pkgPath) : rootDir = new Directory(pkgPath).absolute.path;
 
   /**
    * Get an [io.File] object corresponding to the file in which the generated
@@ -64,18 +71,6 @@
       path.join(rootDir, 'tool', 'task_dependency_graph', 'tasks.dot'));
 
   /**
-   * Determine if the output [file] contains the expected contents.
-   */
-  bool checkFile() {
-    String expectedContents = generateFileContents();
-    String actualContents = file.readAsStringSync();
-    // Normalize Windows line endings to Unix line endings so that the
-    // comparison doesn't fail on Windows.
-    actualContents = actualContents.replaceAll('\r\n', '\n');
-    return expectedContents == actualContents;
-  }
-
-  /**
    * Starting at [node], find all calls to registerExtension() which refer to
    * the given [extensionIdVariable], and execute [callback] for the associated
    * result descriptors.
@@ -123,24 +118,17 @@
   }
 
   /**
-   * Generate the task dependency graph and write it to the output [file].
-   */
-  void generateFile() {
-    String fileContents = generateFileContents();
-    file.writeAsStringSync(fileContents);
-  }
-
-  /**
    * Generate the task dependency graph and return it as a [String].
    */
   String generateFileContents() {
+    AnalysisEngine.instance.processRequiredPlugins();
     List<String> lines = <String>[];
     resourceProvider = PhysicalResourceProvider.INSTANCE;
     DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
     context = AnalysisEngine.instance.createAnalysisContext();
     String packageRootPath;
-    if (Platform.packageRoot.isNotEmpty) {
-      packageRootPath = Platform.packageRoot;
+    if (Platform.packageRoot != null) {
+      packageRootPath = Uri.parse(Platform.packageRoot).toFilePath();
     } else {
       packageRootPath = path.join(rootDir, 'packages');
     }
@@ -268,21 +256,6 @@
     throw new Exception(
         'Could not find extension ID corresponding to $resultListGetterName');
   }
-
-  /**
-   * Find the root directory of the analyzer package by proceeding
-   * upward to the 'tool' dir, and then going up one more directory.
-   */
-  static String findRoot(String pathname) {
-    while (path.basename(pathname) != 'tool') {
-      String parent = path.dirname(pathname);
-      if (parent.length >= pathname.length) {
-        throw new Exception("Can't find root directory");
-      }
-      pathname = parent;
-    }
-    return path.dirname(pathname);
-  }
 }
 
 /**
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index 4e915c8..49a1c1a 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -15,9 +15,11 @@
   BUILD_LIBRARY_ERRORS [shape=box]
   BuildCompilationUnitElementTask -> COMPILATION_UNIT_CONSTANTS
   BuildCompilationUnitElementTask -> COMPILATION_UNIT_ELEMENT
+  BuildCompilationUnitElementTask -> CREATED_RESOLVED_UNIT1
   BuildCompilationUnitElementTask -> RESOLVED_UNIT1
   BuildDirectiveElementsTask -> BUILD_DIRECTIVES_ERRORS
   BuildDirectiveElementsTask -> LIBRARY_ELEMENT2
+  BuildEnumMemberElementsTask -> CREATED_RESOLVED_UNIT2
   BuildEnumMemberElementsTask -> RESOLVED_UNIT2
   BuildExportNamespaceTask -> LIBRARY_ELEMENT4
   BuildLibraryElementTask -> BUILD_LIBRARY_ERRORS
@@ -31,6 +33,8 @@
   COMPILATION_UNIT_ELEMENT [shape=box]
   CONSTANT_DEPENDENCIES -> ComputeConstantValueTask
   CONSTANT_DEPENDENCIES [shape=box]
+  CONSTANT_EXPRESSIONS_DEPENDENCIES -> EvaluateUnitConstantsTask
+  CONSTANT_EXPRESSIONS_DEPENDENCIES [shape=box]
   CONSTANT_VALUE -> ComputeConstantValueTask
   CONSTANT_VALUE -> EvaluateUnitConstantsTask
   CONSTANT_VALUE [shape=box]
@@ -38,12 +42,32 @@
   CONTAINING_LIBRARIES [shape=box]
   CONTENT -> ScanDartTask
   CONTENT [shape=box]
+  CREATED_RESOLVED_UNIT [shape=box]
+  CREATED_RESOLVED_UNIT1 [shape=box]
+  CREATED_RESOLVED_UNIT10 [shape=box]
+  CREATED_RESOLVED_UNIT11 [shape=box]
+  CREATED_RESOLVED_UNIT2 [shape=box]
+  CREATED_RESOLVED_UNIT3 [shape=box]
+  CREATED_RESOLVED_UNIT4 [shape=box]
+  CREATED_RESOLVED_UNIT5 [shape=box]
+  CREATED_RESOLVED_UNIT6 [shape=box]
+  CREATED_RESOLVED_UNIT7 -> ResolveInstanceFieldsInUnitTask
+  CREATED_RESOLVED_UNIT7 [shape=box]
+  CREATED_RESOLVED_UNIT8 -> InferInstanceMembersInUnitTask
+  CREATED_RESOLVED_UNIT8 [shape=box]
+  CREATED_RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
+  CREATED_RESOLVED_UNIT9 -> InferStaticVariableTypeTask
+  CREATED_RESOLVED_UNIT9 -> PartiallyResolveUnitReferencesTask
+  CREATED_RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
+  CREATED_RESOLVED_UNIT9 -> ResolveUnitTask
+  CREATED_RESOLVED_UNIT9 [shape=box]
   ComputeConstantDependenciesTask -> CONSTANT_DEPENDENCIES
   ComputeConstantValueTask -> CONSTANT_VALUE
   ComputeInferableStaticVariableDependenciesTask -> INFERABLE_STATIC_VARIABLE_DEPENDENCIES
   ComputeLibraryCycleTask -> LIBRARY_CYCLE
   ComputeLibraryCycleTask -> LIBRARY_CYCLE_DEPENDENCIES
   ComputeLibraryCycleTask -> LIBRARY_CYCLE_UNITS
+  ComputePropagableVariableDependenciesTask -> PROPAGABLE_VARIABLE_DEPENDENCIES
   ContainingLibrariesTask -> CONTAINING_LIBRARIES
   DART_ERRORS -> LibraryErrorsReadyTask
   DART_ERRORS [shape=box]
@@ -54,13 +78,14 @@
   EXPORTED_LIBRARIES -> BuildDirectiveElementsTask
   EXPORTED_LIBRARIES -> ReadyLibraryElement2Task
   EXPORTED_LIBRARIES -> ReadyLibraryElement5Task
+  EXPORTED_LIBRARIES -> ReadyLibraryElement6Task
   EXPORTED_LIBRARIES -> ReadyResolvedUnit10Task
-  EXPORTED_LIBRARIES -> ReadyResolvedUnit9Task
-  EXPORTED_LIBRARIES -> ReadyResolvedUnitTask
+  EXPORTED_LIBRARIES -> ReadyResolvedUnit11Task
   EXPORTED_LIBRARIES [shape=box]
   EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
   EXPORT_SOURCE_CLOSURE [shape=box]
-  EvaluateUnitConstantsTask -> RESOLVED_UNIT10
+  EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT11
+  EvaluateUnitConstantsTask -> RESOLVED_UNIT11
   GatherUsedImportedElementsTask -> USED_IMPORTED_ELEMENTS
   GatherUsedLocalElementsTask -> USED_LOCAL_ELEMENTS
   GenerateHintsTask -> HINTS
@@ -70,9 +95,9 @@
   IMPORTED_LIBRARIES -> BuildDirectiveElementsTask
   IMPORTED_LIBRARIES -> ReadyLibraryElement2Task
   IMPORTED_LIBRARIES -> ReadyLibraryElement5Task
+  IMPORTED_LIBRARIES -> ReadyLibraryElement6Task
   IMPORTED_LIBRARIES -> ReadyResolvedUnit10Task
-  IMPORTED_LIBRARIES -> ReadyResolvedUnit9Task
-  IMPORTED_LIBRARIES -> ReadyResolvedUnitTask
+  IMPORTED_LIBRARIES -> ReadyResolvedUnit11Task
   IMPORTED_LIBRARIES -> ResolveUnitTypeNamesTask
   IMPORTED_LIBRARIES [shape=box]
   INCLUDED_PARTS -> BuildLibraryElementTask
@@ -85,9 +110,11 @@
   INFERRED_STATIC_VARIABLE -> InferStaticVariableTypesInUnitTask
   INFERRED_STATIC_VARIABLE [shape=box]
   IS_LAUNCHABLE [shape=box]
-  InferInstanceMembersInUnitTask -> RESOLVED_UNIT8
+  InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT9
+  InferInstanceMembersInUnitTask -> RESOLVED_UNIT9
   InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
-  InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT6
+  InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT7
+  InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT7
   LIBRARY_CYCLE [shape=box]
   LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
   LIBRARY_CYCLE_DEPENDENCIES -> InferStaticVariableTypeTask
@@ -98,7 +125,7 @@
   LIBRARY_CYCLE_UNITS -> ResolveInstanceFieldsInUnitTask
   LIBRARY_CYCLE_UNITS -> ResolveUnitTask
   LIBRARY_CYCLE_UNITS [shape=box]
-  LIBRARY_ELEMENT -> EvaluateUnitConstantsTask
+  LIBRARY_ELEMENT -> LibraryErrorsReadyTask
   LIBRARY_ELEMENT [shape=box]
   LIBRARY_ELEMENT1 -> BuildDirectiveElementsTask
   LIBRARY_ELEMENT1 -> ResolveVariableReferencesTask
@@ -115,15 +142,24 @@
   LIBRARY_ELEMENT4 -> ResolveUnitTypeNamesTask
   LIBRARY_ELEMENT4 [shape=box]
   LIBRARY_ELEMENT5 -> PartiallyResolveUnitReferencesTask
+  LIBRARY_ELEMENT5 -> PropagateVariableTypesInLibraryTask
   LIBRARY_ELEMENT5 -> ReadyLibraryElement5Task
   LIBRARY_ELEMENT5 -> ResolveInstanceFieldsInUnitTask
-  LIBRARY_ELEMENT5 -> ResolveLibraryReferencesTask
-  LIBRARY_ELEMENT5 -> ResolveUnitTask
   LIBRARY_ELEMENT5 [shape=box]
+  LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryClosureTask
+  LIBRARY_ELEMENT6 -> ReadyLibraryElement6Task
+  LIBRARY_ELEMENT6 [shape=box]
+  LIBRARY_ELEMENT7 -> ResolveLibraryReferencesTask
+  LIBRARY_ELEMENT7 -> ResolveUnitTask
+  LIBRARY_ELEMENT7 [shape=box]
+  LIBRARY_ELEMENT8 -> EvaluateUnitConstantsTask
+  LIBRARY_ELEMENT8 -> ResolveLibraryTask
+  LIBRARY_ELEMENT8 [shape=box]
   LIBRARY_ERRORS_READY [shape=box]
   LIBRARY_SPECIFIC_UNITS -> GenerateHintsTask
+  LIBRARY_SPECIFIC_UNITS -> PropagateVariableTypesInLibraryTask
   LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnit10Task
-  LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnit9Task
+  LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnit11Task
   LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnitTask
   LIBRARY_SPECIFIC_UNITS -> ResolveLibraryReferencesTask
   LIBRARY_SPECIFIC_UNITS -> ResolveLibraryTypeNamesTask
@@ -142,6 +178,13 @@
   PARSED_UNIT [shape=box]
   PARSE_ERRORS -> dartErrorsForSource
   PARSE_ERRORS [shape=box]
+  PROPAGABLE_VARIABLES_IN_UNIT -> PropagateVariableTypesInUnitTask
+  PROPAGABLE_VARIABLES_IN_UNIT [shape=box]
+  PROPAGABLE_VARIABLE_DEPENDENCIES -> PropagateVariableTypeTask
+  PROPAGABLE_VARIABLE_DEPENDENCIES [shape=box]
+  PROPAGATED_VARIABLE -> PropagateVariableTypeTask
+  PROPAGATED_VARIABLE -> PropagateVariableTypesInUnitTask
+  PROPAGATED_VARIABLE [shape=box]
   ParseDartTask -> EXPLICITLY_IMPORTED_LIBRARIES
   ParseDartTask -> EXPORTED_LIBRARIES
   ParseDartTask -> IMPORTED_LIBRARIES
@@ -151,23 +194,31 @@
   ParseDartTask -> PARSE_ERRORS
   ParseDartTask -> SOURCE_KIND
   ParseDartTask -> UNITS
+  PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT5
   PartiallyResolveUnitReferencesTask -> INFERABLE_STATIC_VARIABLES_IN_UNIT
+  PartiallyResolveUnitReferencesTask -> PROPAGABLE_VARIABLES_IN_UNIT
   PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT5
+  PropagateVariableTypeTask -> PROPAGATED_VARIABLE
+  PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT7
+  PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT6
+  PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT6
+  PropagateVariableTypesInUnitTask -> RESOLVED_UNIT6
   READY_LIBRARY_ELEMENT2 -> ComputeLibraryCycleTask
   READY_LIBRARY_ELEMENT2 -> ReadyLibraryElement2Task
   READY_LIBRARY_ELEMENT2 [shape=box]
   READY_LIBRARY_ELEMENT5 -> PartiallyResolveUnitReferencesTask
   READY_LIBRARY_ELEMENT5 -> ReadyLibraryElement5Task
   READY_LIBRARY_ELEMENT5 [shape=box]
-  READY_RESOLVED_UNIT -> ReadyResolvedUnitTask
+  READY_LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryClosureTask
+  READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement6Task
+  READY_LIBRARY_ELEMENT6 [shape=box]
+  READY_RESOLVED_UNIT -> ResolveLibraryTask
   READY_RESOLVED_UNIT -> VerifyUnitTask
   READY_RESOLVED_UNIT [shape=box]
   READY_RESOLVED_UNIT10 -> ReadyResolvedUnit10Task
-  READY_RESOLVED_UNIT10 -> StrongModeVerifyUnitTask
   READY_RESOLVED_UNIT10 [shape=box]
-  READY_RESOLVED_UNIT9 -> ReadyResolvedUnit9Task
-  READY_RESOLVED_UNIT9 -> ResolveLibraryReferencesTask
-  READY_RESOLVED_UNIT9 [shape=box]
+  READY_RESOLVED_UNIT11 -> ReadyResolvedUnit11Task
+  READY_RESOLVED_UNIT11 [shape=box]
   REFERENCED_NAMES [shape=box]
   RESOLVED_UNIT -> GenerateHintsTask
   RESOLVED_UNIT -> GenerateLintsTask
@@ -178,9 +229,16 @@
   RESOLVED_UNIT1 -> BuildEnumMemberElementsTask
   RESOLVED_UNIT1 -> BuildLibraryElementTask
   RESOLVED_UNIT1 [shape=box]
+  RESOLVED_UNIT10 -> ComputeConstantDependenciesTask
+  RESOLVED_UNIT10 -> EvaluateUnitConstantsTask
+  RESOLVED_UNIT10 -> GatherUsedImportedElementsTask
+  RESOLVED_UNIT10 -> GatherUsedLocalElementsTask
   RESOLVED_UNIT10 -> ReadyResolvedUnit10Task
-  RESOLVED_UNIT10 -> StrongModeVerifyUnitTask
+  RESOLVED_UNIT10 -> ResolveLibraryReferencesTask
   RESOLVED_UNIT10 [shape=box]
+  RESOLVED_UNIT11 -> ReadyResolvedUnit11Task
+  RESOLVED_UNIT11 -> StrongModeVerifyUnitTask
+  RESOLVED_UNIT11 [shape=box]
   RESOLVED_UNIT2 -> ResolveUnitTypeNamesTask
   RESOLVED_UNIT2 [shape=box]
   RESOLVED_UNIT3 -> ResolveLibraryTypeNamesTask
@@ -189,25 +247,19 @@
   RESOLVED_UNIT4 -> PartiallyResolveUnitReferencesTask
   RESOLVED_UNIT4 [shape=box]
   RESOLVED_UNIT5 -> ComputeInferableStaticVariableDependenciesTask
-  RESOLVED_UNIT5 -> InferStaticVariableTypeTask
-  RESOLVED_UNIT5 -> InferStaticVariableTypesInUnitTask
+  RESOLVED_UNIT5 -> ComputePropagableVariableDependenciesTask
+  RESOLVED_UNIT5 -> PropagateVariableTypeTask
+  RESOLVED_UNIT5 -> PropagateVariableTypesInUnitTask
   RESOLVED_UNIT5 [shape=box]
-  RESOLVED_UNIT6 -> ResolveInstanceFieldsInUnitTask
+  RESOLVED_UNIT6 -> InferStaticVariableTypeTask
+  RESOLVED_UNIT6 -> InferStaticVariableTypesInUnitTask
+  RESOLVED_UNIT6 -> PropagateVariableTypesInLibraryTask
   RESOLVED_UNIT6 [shape=box]
-  RESOLVED_UNIT7 -> InferInstanceMembersInUnitTask
+  RESOLVED_UNIT7 -> ResolveInstanceFieldsInUnitTask
   RESOLVED_UNIT7 [shape=box]
   RESOLVED_UNIT8 -> InferInstanceMembersInUnitTask
-  RESOLVED_UNIT8 -> InferStaticVariableTypeTask
-  RESOLVED_UNIT8 -> PartiallyResolveUnitReferencesTask
-  RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
-  RESOLVED_UNIT8 -> ResolveUnitTask
   RESOLVED_UNIT8 [shape=box]
-  RESOLVED_UNIT9 -> ComputeConstantDependenciesTask
-  RESOLVED_UNIT9 -> EvaluateUnitConstantsTask
-  RESOLVED_UNIT9 -> GatherUsedImportedElementsTask
-  RESOLVED_UNIT9 -> GatherUsedLocalElementsTask
-  RESOLVED_UNIT9 -> ReadyResolvedUnit9Task
-  RESOLVED_UNIT9 -> ResolveLibraryReferencesTask
+  RESOLVED_UNIT9 -> ResolveUnitTask
   RESOLVED_UNIT9 [shape=box]
   RESOLVE_TYPE_NAMES_ERRORS -> LibraryUnitErrorsTask
   RESOLVE_TYPE_NAMES_ERRORS [shape=box]
@@ -215,17 +267,24 @@
   RESOLVE_UNIT_ERRORS [shape=box]
   ReadyLibraryElement2Task -> READY_LIBRARY_ELEMENT2
   ReadyLibraryElement5Task -> READY_LIBRARY_ELEMENT5
+  ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT6
   ReadyResolvedUnit10Task -> READY_RESOLVED_UNIT10
-  ReadyResolvedUnit9Task -> READY_RESOLVED_UNIT9
+  ReadyResolvedUnit11Task -> READY_RESOLVED_UNIT11
   ReadyResolvedUnitTask -> READY_RESOLVED_UNIT
-  ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT7
-  ResolveLibraryReferencesTask -> LIBRARY_ELEMENT
+  ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT8
+  ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT8
+  ResolveLibraryReferencesTask -> LIBRARY_ELEMENT8
   ResolveLibraryReferencesTask -> REFERENCED_NAMES
+  ResolveLibraryTask -> LIBRARY_ELEMENT
   ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT5
-  ResolveUnitTask -> RESOLVED_UNIT9
+  ResolveUnitTask -> CONSTANT_EXPRESSIONS_DEPENDENCIES
+  ResolveUnitTask -> CREATED_RESOLVED_UNIT10
+  ResolveUnitTask -> RESOLVED_UNIT10
   ResolveUnitTask -> RESOLVE_UNIT_ERRORS
+  ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT3
   ResolveUnitTypeNamesTask -> RESOLVED_UNIT3
   ResolveUnitTypeNamesTask -> RESOLVE_TYPE_NAMES_ERRORS
+  ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT4
   ResolveVariableReferencesTask -> RESOLVED_UNIT4
   ResolveVariableReferencesTask -> VARIABLE_REFERENCE_ERRORS
   SCAN_ERRORS -> dartErrorsForSource
@@ -237,6 +296,7 @@
   ScanDartTask -> LINE_INFO
   ScanDartTask -> SCAN_ERRORS
   ScanDartTask -> TOKEN_STREAM
+  StrongModeVerifyUnitTask -> CREATED_RESOLVED_UNIT
   StrongModeVerifyUnitTask -> RESOLVED_UNIT
   StrongModeVerifyUnitTask -> STRONG_MODE_ERRORS
   TOKEN_STREAM -> ParseDartTask
@@ -248,6 +308,7 @@
   TYPE_PROVIDER -> InferInstanceMembersInUnitTask
   TYPE_PROVIDER -> InferStaticVariableTypeTask
   TYPE_PROVIDER -> PartiallyResolveUnitReferencesTask
+  TYPE_PROVIDER -> PropagateVariableTypeTask
   TYPE_PROVIDER -> ResolveInstanceFieldsInUnitTask
   TYPE_PROVIDER -> ResolveLibraryTypeNamesTask
   TYPE_PROVIDER -> ResolveUnitTask
diff --git a/pkg/analyzer_cli/.gitignore b/pkg/analyzer_cli/.gitignore
new file mode 100644
index 0000000..3a4106f
--- /dev/null
+++ b/pkg/analyzer_cli/.gitignore
@@ -0,0 +1,11 @@
+.buildlog
+.DS_Store
+.idea
+/.packages
+.project
+.pub/
+.settings/
+analyzer_cli.iml
+build/
+packages
+pubspec.lock
diff --git a/pkg/analyzer_cli/CHANGELOG.md b/pkg/analyzer_cli/CHANGELOG.md
new file mode 100644
index 0000000..c4298d7
--- /dev/null
+++ b/pkg/analyzer_cli/CHANGELOG.md
@@ -0,0 +1,16 @@
+# Changelog
+
+## 1.1.1
+
+- Removed outmoded `--url-mapping` command line option.
+
+## 1.1.0
+
+- New `--lints` command line option.
+
+## 0.0.
+
+
+## 0.0.1
+
+- Initial version
diff --git a/pkg/analyzer_cli/README.md b/pkg/analyzer_cli/README.md
new file mode 100644
index 0000000..947e730
--- /dev/null
+++ b/pkg/analyzer_cli/README.md
@@ -0,0 +1,83 @@
+# dartanalyzer
+
+Use _dartanalyzer_ to statically analyze your code at the command line,
+checking for errors and warnings that are specified in the
+[Dart Language Specification](https://www.dartlang.org/docs/spec/).
+DartPad, code editors, and IDEs such as WebStorm use the same
+analysis engine that dartanalyzer uses.
+
+## Basic usage
+
+Run the analyzer from the top directory of the package.
+Here's an example of testing a Dart file.
+
+```
+dartanalyzer bin/test.dart
+```
+
+## Options
+
+The following are the most commonly used options for dartanalyzer:
+
+* `--packages=`<br>
+ Specify the path to the package resolution configuration file.
+ For more information see
+ [Package Resolution Configuration File](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md).
+This option cannot be used with `--package-root`.
+
+* `--package-warnings`<br>
+  Show warnings not only for code in the specified .dart file and
+  others in its library, but also for libraries imported with `package:`.
+
+* `--options=`<br>
+  Specify the path to an analysis options file.
+
+* `--lints`<br>
+  Show the results from the linter.
+
+* `--no-hints`<br>
+  Don't show hints for improving the code.
+
+* `--ignore-unrecognized-flags`<br>
+  Rather than printing the help message,
+  ignore any unrecognized command-line flags.
+
+* `--version`<br>
+  Show the analyzer version.
+
+* `-h` _or_ `--help`<br>
+  Show all the command-line options.
+
+The following are advanced options to use with dartanalyzer:
+
+* `-b` _or_ `--batch`<br>
+  Run in batch mode.
+
+* `--dart-sdk=`<br>
+  Specify the directory that contains the Dart SDK.
+
+* `--fatal-warnings`<br>
+  Except for type warnings, treat warnings as fatal.
+
+* `--format=machine`<br>
+  Produce output in a format suitable for parsing.
+
+* `--url-mapping=libraryUri,/path/to/library.dart`<br>
+  Tells the analyzer to use the specified library as the source
+  for that particular import.
+
+The following options are deprecated:
+
+* `-p` _or_ `--package-root=`<br>
+  **Deprecated.** Specify the directory to search for any libraries that are
+  imported using `package:`. _This option is replaced as of Dart 1.12 with
+  `--packages`._
+
+* `--machine`<br>
+  **Deprecated.** Replaced by `--format`.
+
+* `--show-package-warnings`<br>
+  **Deprecated.** Replaced by `--package-warnings`.
+
+* `--show-sdk-warnings`<br>
+  **Deprecated.** Replaced by `--warnings`.
diff --git a/pkg/analyzer_cli/bin/analyzer.dart b/pkg/analyzer_cli/bin/analyzer.dart
new file mode 100644
index 0000000..b0a32fe
--- /dev/null
+++ b/pkg/analyzer_cli/bin/analyzer.dart
@@ -0,0 +1,16 @@
+#!/usr/bin/env dart
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_cli/src/driver.dart';
+
+
+
+
+/// The entry point for the analyzer.
+void main(List<String> args) {
+  var starter = new Driver();
+  starter.start(args);
+  
+}
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
new file mode 100644
index 0000000..75cbe52
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -0,0 +1,328 @@
+// 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_cli.src.analyzer_impl;
+
+import 'dart:collection';
+import 'dart:io';
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:analyzer_cli/src/error_formatter.dart';
+import 'package:analyzer_cli/src/options.dart';
+
+/// The maximum number of sources for which AST structures should be kept in the cache.
+const int _maxCacheSize = 512;
+
+DirectoryBasedDartSdk sdk;
+
+int currentTimeMillis() => new DateTime.now().millisecondsSinceEpoch;
+
+/// Analyzes single library [File].
+class AnalyzerImpl {
+  static final PerformanceTag _prepareErrorsTag =
+      new PerformanceTag("AnalyzerImpl.prepareErrors");
+  static final PerformanceTag _resolveLibraryTag =
+      new PerformanceTag("AnalyzerImpl._resolveLibrary");
+
+  final CommandLineOptions options;
+  final int startTime;
+
+  final AnalysisContext context;
+
+  final Source librarySource;
+
+  /// All [Source]s references by the analyzed library.
+  final Set<Source> sources = new Set<Source>();
+
+  /// All [AnalysisErrorInfo]s in the analyzed library.
+  final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>();
+
+  /// [HashMap] between sources and analysis error infos.
+  final HashMap<Source, AnalysisErrorInfo> sourceErrorsMap =
+      new HashMap<Source, AnalysisErrorInfo>();
+
+  /// If the file specified on the command line is part of a package, the name
+  /// of that package.  Otherwise `null`.  This allows us to analyze the file
+  /// specified on the command line as though it is reached via a "package:"
+  /// URI, but avoid suppressing its output in the event that the user has not
+  /// specified the "--package-warnings" option.
+  String _selfPackageName;
+
+  AnalyzerImpl(this.context, this.librarySource, this.options, this.startTime);
+
+  /// Returns the maximal [ErrorSeverity] of the recorded errors.
+  ErrorSeverity get maxErrorSeverity {
+    var status = ErrorSeverity.NONE;
+    for (AnalysisErrorInfo errorInfo in errorInfos) {
+      for (AnalysisError error in errorInfo.errors) {
+        if (_processError(error) == null) {
+          continue;
+        }
+        var severity = computeSeverity(error, options);
+        status = status.max(severity);
+      }
+    }
+    return status;
+  }
+
+  void addCompilationUnitSource(CompilationUnitElement unit,
+      Set<LibraryElement> libraries, Set<CompilationUnitElement> units) {
+    if (unit == null || units.contains(unit)) {
+      return;
+    }
+    units.add(unit);
+    sources.add(unit.source);
+  }
+
+  void addLibrarySources(LibraryElement library, Set<LibraryElement> libraries,
+      Set<CompilationUnitElement> units) {
+    if (library == null || !libraries.add(library)) {
+      return;
+    }
+    // Maybe skip library.
+    {
+      UriKind uriKind = library.source.uriKind;
+      // Optionally skip package: libraries.
+      if (!options.showPackageWarnings && _isOtherPackage(library.source.uri)) {
+        return;
+      }
+      // Optionally skip SDK libraries.
+      if (!options.showSdkWarnings && uriKind == UriKind.DART_URI) {
+        return;
+      }
+    }
+    // Add compilation units.
+    addCompilationUnitSource(library.definingCompilationUnit, libraries, units);
+    for (CompilationUnitElement child in library.parts) {
+      addCompilationUnitSource(child, libraries, units);
+    }
+    // Add referenced libraries.
+    for (LibraryElement child in library.importedLibraries) {
+      addLibrarySources(child, libraries, units);
+    }
+    for (LibraryElement child in library.exportedLibraries) {
+      addLibrarySources(child, libraries, units);
+    }
+  }
+
+  /// Treats the [sourcePath] as the top level library and analyzes it using a
+  /// synchronous algorithm over the analysis engine. If [printMode] is `0`,
+  /// then no error or performance information is printed. If [printMode] is `1`,
+  /// then both will be printed. If [printMode] is `2`, then only performance
+  /// information will be printed, and it will be marked as being for a cold VM.
+  ErrorSeverity analyzeSync({int printMode: 1}) {
+    setupForAnalysis();
+    return _analyzeSync(printMode);
+  }
+
+  /// Fills [errorInfos] using [sources].
+  void prepareErrors() {
+    return _prepareErrorsTag.makeCurrentWhile(() {
+      for (Source source in sources) {
+        context.computeErrors(source);
+        errorInfos.add(context.getErrors(source));
+      }
+    });
+  }
+
+  /// Fills [sources].
+  void prepareSources(LibraryElement library) {
+    var units = new Set<CompilationUnitElement>();
+    var libraries = new Set<LibraryElement>();
+    addLibrarySources(library, libraries, units);
+  }
+
+  /// Setup local fields such as the analysis context for analysis.
+  void setupForAnalysis() {
+    sources.clear();
+    errorInfos.clear();
+    Uri libraryUri = librarySource.uri;
+    if (libraryUri.scheme == 'package' && libraryUri.pathSegments.length > 0) {
+      _selfPackageName = libraryUri.pathSegments[0];
+    }
+  }
+
+  /// The sync version of analysis.
+  ErrorSeverity _analyzeSync(int printMode) {
+    // Don't try to analyze parts.
+    if (context.computeKindOf(librarySource) == SourceKind.PART) {
+      stderr.writeln("Only libraries can be analyzed.");
+      stderr.writeln(
+          "${librarySource.fullName} is a part and can not be analyzed.");
+      return ErrorSeverity.ERROR;
+    }
+    var libraryElement = _resolveLibrary();
+    prepareSources(libraryElement);
+    prepareErrors();
+
+    // Print errors and performance numbers.
+    if (printMode == 1) {
+      _printErrors();
+    } else if (printMode == 2) {
+      _printColdPerf();
+    }
+
+    // Compute max severity and set exitCode.
+    ErrorSeverity status = maxErrorSeverity;
+    if (status == ErrorSeverity.WARNING && options.warningsAreFatal) {
+      status = ErrorSeverity.ERROR;
+    }
+    return status;
+  }
+
+  /// Determine whether the given URI refers to a package other than the package
+  /// being analyzed.
+  bool _isOtherPackage(Uri uri) {
+    if (uri.scheme != 'package') {
+      return false;
+    }
+    if (_selfPackageName != null &&
+        uri.pathSegments.length > 0 &&
+        uri.pathSegments[0] == _selfPackageName) {
+      return false;
+    }
+    return true;
+  }
+
+  _printColdPerf() {
+    // Print cold VM performance numbers.
+    int totalTime = currentTimeMillis() - startTime;
+    int otherTime = totalTime;
+    for (PerformanceTag tag in PerformanceTag.all) {
+      if (tag != PerformanceTag.UNKNOWN) {
+        int tagTime = tag.elapsedMs;
+        outSink.writeln('${tag.label}-cold:$tagTime');
+        otherTime -= tagTime;
+      }
+    }
+    outSink.writeln('other-cold:$otherTime');
+    outSink.writeln("total-cold:$totalTime");
+  }
+
+  _printErrors() {
+    // The following is a hack. We currently print out to stderr to ensure that
+    // when in batch mode we print to stderr, this is because the prints from
+    // batch are made to stderr. The reason that options.shouldBatch isn't used
+    // is because when the argument flags are constructed in BatchRunner and
+    // passed in from batch mode which removes the batch flag to prevent the
+    // "cannot have the batch flag and source file" error message.
+    StringSink sink = options.machineFormat ? errorSink : outSink;
+
+    // Print errors.
+    ErrorFormatter formatter = new ErrorFormatter(sink, options, _processError);
+    formatter.formatErrors(errorInfos);
+  }
+
+  /// Check various configuration options to get a desired severity for this
+  /// [error] (or `null` if it's to be suppressed).
+  ProcessedSeverity _processError(AnalysisError error) {
+    ErrorSeverity severity = computeSeverity(error, options, context);
+    bool isOverridden = false;
+
+    // First check for a filter.
+    if (severity == null) {
+      // Null severity means the error has been explicitly ignored.
+      return null;
+    } else {
+      isOverridden = true;
+    }
+
+    // If not overridden, some "natural" severities get globally filtered.
+    if (!isOverridden) {
+      // Check for global hint filtering.
+      if (severity == ErrorSeverity.INFO && options.disableHints) {
+        return null;
+      }
+
+      // Skip TODOs.
+      if (severity == ErrorType.TODO) {
+        return null;
+      }
+    }
+
+    return new ProcessedSeverity(severity, isOverridden);
+  }
+
+  LibraryElement _resolveLibrary() {
+    return _resolveLibraryTag.makeCurrentWhile(() {
+      return context.computeLibraryElement(librarySource);
+    });
+  }
+
+  /// Compute the severity of the error; however:
+  ///   * if [options.enableTypeChecks] is false, then de-escalate checked-mode
+  ///   compile time errors to a severity of [ErrorSeverity.INFO].
+  ///   * if [options.hintsAreFatal] is true, escalate hints to errors.
+  static ErrorSeverity computeSeverity(
+      AnalysisError error, CommandLineOptions options,
+      [AnalysisContext context]) {
+    if (context != null) {
+      ErrorProcessor processor = ErrorProcessor.getProcessor(context, error);
+      // If there is a processor for this error, defer to it.
+      if (processor != null) {
+        return processor.severity;
+      }
+    }
+
+    if (!options.enableTypeChecks &&
+        error.errorCode.type == ErrorType.CHECKED_MODE_COMPILE_TIME_ERROR) {
+      return ErrorSeverity.INFO;
+    }
+
+    if (options.hintsAreFatal && error.errorCode is HintCode) {
+      return ErrorSeverity.ERROR;
+    }
+
+    return error.errorCode.errorSeverity;
+  }
+
+  /// Return the corresponding package directory or `null` if none is found.
+  static JavaFile getPackageDirectoryFor(JavaFile sourceFile) {
+    // We are going to ask parent file, so get absolute path.
+    sourceFile = sourceFile.getAbsoluteFile();
+    // Look in the containing directories.
+    JavaFile dir = sourceFile.getParentFile();
+    while (dir != null) {
+      JavaFile packagesDir = new JavaFile.relative(dir, "packages");
+      if (packagesDir.exists()) {
+        return packagesDir;
+      }
+      dir = dir.getParentFile();
+    }
+    // Not found.
+    return null;
+  }
+}
+
+/// This [Logger] prints out information comments to [outSink] and error messages
+/// to [errorSink].
+class StdLogger extends Logger {
+  StdLogger();
+
+  @override
+  void logError(String message, [CaughtException exception]) {
+    errorSink.writeln(message);
+    if (exception != null) {
+      errorSink.writeln(exception);
+    }
+  }
+
+  @override
+  void logInformation(String message, [CaughtException exception]) {
+    outSink.writeln(message);
+    if (exception != null) {
+      outSink.writeln(exception);
+    }
+  }
+}
diff --git a/pkg/analyzer_cli/lib/src/boot_loader.dart b/pkg/analyzer_cli/lib/src/boot_loader.dart
new file mode 100644
index 0000000..6df71ae
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/boot_loader.dart
@@ -0,0 +1,196 @@
+// 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_cli.src.boot_loader;
+
+import 'dart:async';
+import 'dart:isolate';
+
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart' as engine;
+import 'package:analyzer/src/plugin/plugin_configuration.dart';
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:analyzer_cli/src/options.dart';
+import 'package:source_span/source_span.dart';
+import 'package:yaml/src/yaml_node.dart';
+
+const _analyzerPackageName = 'analyzer';
+
+/// Return non-null if there is a validation issue with this plugin.
+String validate(PluginInfo plugin) {
+  var missing = <String>[];
+  if (plugin.className == null) {
+    missing.add('class name');
+  }
+  if (plugin.libraryUri == null) {
+    missing.add('library uri');
+  }
+  if (missing.isEmpty) {
+    // All good.
+    return null;
+  }
+  return 'Plugin ${plugin.name} skipped, config missing: ${missing.join(", ")}';
+}
+
+List<PluginInfo> _validate(Iterable<PluginInfo> plugins) {
+  List<PluginInfo> validated = <PluginInfo>[];
+  plugins.forEach((PluginInfo plugin) {
+    String validation = validate(plugin);
+    if (validation != null) {
+      errorSink.writeln(validation);
+    } else {
+      validated.add(plugin);
+    }
+  });
+  return validated;
+}
+
+/// Source code assembler.
+class Assembler {
+  /// Plugins to configure.
+  final Iterable<PluginInfo> plugins;
+
+  /// Create an assembler for the given plugin [config].
+  Assembler(this.plugins);
+
+  /// A string enumerating required package `import`s.
+  String get enumerateImports =>
+      plugins.map((PluginInfo p) => "import '${p.libraryUri}';").join('\n');
+
+  /// A string listing initialized plugin instances.
+  String get pluginList =>
+      plugins.map((PluginInfo p) => 'new ${p.className}()').join(', ');
+
+  /// Create a file containing a `main()` suitable for loading in spawned
+  /// isolate.
+  String createMain() => _generateMain();
+
+  String _generateMain() => """
+// 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 code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+import 'package:analyzer_cli/src/driver.dart';
+
+$enumerateImports
+
+void main(List<String> args) {
+  var starter = new Driver();
+  starter.userDefinedPlugins = [$pluginList];
+  starter.start(args);
+}
+""";
+}
+
+/// Given environment information extracted from command-line `args`, creates a
+/// a loadable analyzer "image".
+class BootLoader {
+  /// Emits an error message to [errorSink] if plugin config can't be read.
+  static final ErrorHandler _pluginConfigErrorHandler = (Exception e) {
+    String details;
+    if (e is PluginConfigFormatException) {
+      details = e.message;
+      var node = e.yamlNode;
+      if (node is YamlNode) {
+        SourceLocation location = node.span.start;
+        details += ' (line ${location.line}, column ${location.column})';
+      }
+    } else {
+      details = e.toString();
+    }
+
+    errorSink.writeln('Plugin configuration skipped: $details');
+  };
+
+  /// Reads plugin config info from `.analysis_options`.
+  PluginConfigOptionsProcessor _pluginOptionsProcessor =
+      new PluginConfigOptionsProcessor(_pluginConfigErrorHandler);
+
+  /// Create a loadable analyzer image configured with plugins derived from
+  /// the given analyzer command-line `args`.
+  Image createImage(List<String> args) {
+    // Parse commandline options.
+    CommandLineOptions options = CommandLineOptions.parse(args);
+
+    // Process analysis options file (and notify all interested parties).
+    _processAnalysisOptions(options);
+
+    // TODO(pquitslund): Pass in .packages info
+    return new Image(_pluginOptionsProcessor.config,
+        args: args, packageRootPath: options.packageRootPath);
+  }
+
+  void _processAnalysisOptions(CommandLineOptions options) {
+    // Determine options file path.
+    var filePath = options.analysisOptionsFile ??
+        engine.AnalysisEngine.ANALYSIS_OPTIONS_FILE;
+    try {
+      var file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
+      AnalysisOptionsProvider analysisOptionsProvider =
+          new AnalysisOptionsProvider();
+      Map<String, YamlNode> options =
+          analysisOptionsProvider.getOptionsFromFile(file);
+      //TODO(pq): thread in proper context.
+      var temporaryContext = new AnalysisContextImpl();
+      _pluginOptionsProcessor.optionsProcessed(temporaryContext, options);
+    } on Exception catch (e) {
+      _pluginOptionsProcessor.onError(e);
+    }
+  }
+}
+
+/// A loadable "image" of a a configured analyzer instance.
+class Image {
+  /// (Optional) package root path.
+  final String packageRootPath;
+
+  /// (Optional) package map.
+  final Map<String, Uri> packages;
+
+  /// (Optional) args to be passed on to the loaded main.
+  final List<String> args;
+
+  /// Plugin configuration.
+  final PluginConfig config;
+
+  /// Create an image with the given [config] and optionally [packages],
+  /// [packageRootPath], and command line [args].
+  Image(this.config, {this.packages, this.packageRootPath, this.args});
+
+  /// Load this image.
+  ///
+  /// Loading an image consists in assembling an analyzer `main()`, configured
+  /// to include the appropriate analyzer plugins as specified in
+  /// `.analyzer_options` which is then run in a spawned isolate.
+  Future load() {
+    List<PluginInfo> plugins = _validate(config.plugins);
+    String mainSource = new Assembler(plugins).createMain();
+
+    Completer completer = new Completer();
+    ReceivePort exitListener = new ReceivePort();
+    exitListener.listen((data) {
+      completer.complete();
+      exitListener.close();
+    });
+
+    Uri uri =
+        Uri.parse('data:application/dart;charset=utf-8,${Uri.encodeComponent(
+        mainSource)}');
+
+    // TODO(pquitslund): update once .packages are supported.
+    String packageRoot =
+        packageRootPath != null ? packageRootPath : './packages';
+    Uri packageUri = new Uri.file(packageRoot);
+
+    Isolate.spawnUri(uri, args, null /* msg */,
+        packageRoot: packageUri, onExit: exitListener.sendPort);
+
+    return completer.future;
+  }
+}
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
new file mode 100644
index 0000000..0b6ae40
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -0,0 +1,658 @@
+// 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_cli.src.driver;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:analyzer/file_system/file_system.dart' as fileSystem;
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/plugin/options.dart';
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/package_map_provider.dart';
+import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/source/pub_package_map_provider.dart';
+import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/interner.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/utilities_general.dart'
+    show PerformanceTag;
+import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer_cli/src/analyzer_impl.dart';
+import 'package:analyzer_cli/src/options.dart';
+import 'package:analyzer_cli/src/perf_report.dart';
+import 'package:linter/src/plugin/linter_plugin.dart';
+import 'package:package_config/discovery.dart' as pkgDiscovery;
+import 'package:package_config/packages.dart' show Packages;
+import 'package:package_config/packages_file.dart' as pkgfile show parse;
+import 'package:package_config/src/packages_impl.dart' show MapPackages;
+import 'package:path/path.dart' as path;
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
+import 'package:yaml/yaml.dart';
+
+/// Shared IO sink for standard error reporting.
+///
+/// *Visible for testing.*
+StringSink errorSink = stderr;
+
+/// Shared IO sink for standard out reporting.
+///
+/// *Visible for testing.*
+StringSink outSink = stdout;
+
+/// Test this option map to see if it specifies lint rules.
+bool containsLintRuleEntry(Map<String, YamlNode> options) {
+  var linterNode = options['linter'];
+  return linterNode is YamlMap && linterNode.containsKey('rules');
+}
+
+typedef ErrorSeverity _BatchRunnerHandler(List<String> args);
+
+class Driver {
+  static final PerformanceTag _analyzeAllTag =
+      new PerformanceTag("Driver._analyzeAll");
+
+  /// The plugins that are defined outside the `analyzer_cli` package.
+  List<Plugin> _userDefinedPlugins = <Plugin>[];
+
+  /// Indicates whether the analyzer is running in batch mode.
+  bool _isBatch;
+
+  /// The context that was most recently created by a call to [_analyzeAll], or
+  /// `null` if [_analyzeAll] hasn't been called yet.
+  AnalysisContext _context;
+
+  /// If [_context] is not `null`, the [CommandLineOptions] that guided its
+  /// creation.
+  CommandLineOptions _previousOptions;
+
+  /// This Driver's current analysis context.
+  ///
+  /// *Visible for testing.*
+  AnalysisContext get context => _context;
+
+  /// Set the [plugins] that are defined outside the `analyzer_cli` package.
+  void set userDefinedPlugins(List<Plugin> plugins) {
+    _userDefinedPlugins = plugins == null ? <Plugin>[] : plugins;
+  }
+
+  /// Use the given command-line [args] to start this analysis driver.
+  void start(List<String> args) {
+    int startTime = new DateTime.now().millisecondsSinceEpoch;
+
+    StringUtilities.INTERNER = new MappedInterner();
+
+    _processPlugins();
+
+    // Parse commandline options.
+    CommandLineOptions options = CommandLineOptions.parse(args);
+
+    // Cache options of interest to inform analysis.
+    _setupEnv(options);
+
+    // Do analysis.
+    if (_isBatch) {
+      _BatchRunner.runAsBatch(args, (List<String> args) {
+        CommandLineOptions options = CommandLineOptions.parse(args);
+        return _analyzeAll(options);
+      });
+    } else {
+      ErrorSeverity severity = _analyzeAll(options);
+      // In case of error propagate exit code.
+      if (severity == ErrorSeverity.ERROR) {
+        exitCode = severity.ordinal;
+      }
+    }
+
+    if (options.perfReport != null) {
+      String json = makePerfReport(startTime, currentTimeMillis(), options);
+      new File(options.perfReport).writeAsStringSync(json);
+    }
+  }
+
+  ErrorSeverity _analyzeAll(CommandLineOptions options) {
+    return _analyzeAllTag.makeCurrentWhile(() {
+      return _analyzeAllImpl(options);
+    });
+  }
+
+  /// Perform analysis according to the given [options].
+  ErrorSeverity _analyzeAllImpl(CommandLineOptions options) {
+    if (!options.machineFormat) {
+      outSink.writeln("Analyzing ${options.sourceFiles}...");
+    }
+
+    // Create a context, or re-use the previous one.
+    try {
+      _createAnalysisContext(options);
+    } on _DriverError catch (error) {
+      outSink.writeln(error.msg);
+      return ErrorSeverity.ERROR;
+    }
+
+    // Add all the files to be analyzed en masse to the context.  Skip any
+    // files that were added earlier (whether explicitly or implicitly) to
+    // avoid causing those files to be unnecessarily re-read.
+    Set<Source> knownSources = _context.sources.toSet();
+    List<Source> sourcesToAnalyze = <Source>[];
+    ChangeSet changeSet = new ChangeSet();
+    for (String sourcePath in options.sourceFiles) {
+      sourcePath = sourcePath.trim();
+      // Check that file exists.
+      if (!new File(sourcePath).existsSync()) {
+        errorSink.writeln('File not found: $sourcePath');
+        exitCode = ErrorSeverity.ERROR.ordinal;
+        //Fail fast; don't analyze more files
+        return ErrorSeverity.ERROR;
+      }
+      // Check that file is Dart file.
+      if (!AnalysisEngine.isDartFileName(sourcePath)) {
+        errorSink.writeln('$sourcePath is not a Dart file');
+        exitCode = ErrorSeverity.ERROR.ordinal;
+        // Fail fast; don't analyze more files.
+        return ErrorSeverity.ERROR;
+      }
+      Source source = _computeLibrarySource(sourcePath);
+      if (!knownSources.contains(source)) {
+        changeSet.addedSource(source);
+      }
+      sourcesToAnalyze.add(source);
+    }
+    _context.applyChanges(changeSet);
+
+    // Analyze the libraries.
+    ErrorSeverity allResult = ErrorSeverity.NONE;
+    var libUris = <Uri>[];
+    var parts = <Source>[];
+    for (Source source in sourcesToAnalyze) {
+      if (context.computeKindOf(source) == SourceKind.PART) {
+        parts.add(source);
+        continue;
+      }
+      ErrorSeverity status = _runAnalyzer(source, options);
+      allResult = allResult.max(status);
+      libUris.add(source.uri);
+    }
+
+    // Check that each part has a corresponding source in the input list.
+    for (Source part in parts) {
+      bool found = false;
+      for (var lib in context.getLibrariesContaining(part)) {
+        if (libUris.contains(lib.uri)) {
+          found = true;
+        }
+      }
+      if (!found) {
+        errorSink.writeln("${part.fullName} is a part and cannot be analyzed.");
+        errorSink.writeln("Please pass in a library that contains this part.");
+        exitCode = ErrorSeverity.ERROR.ordinal;
+        allResult = allResult.max(ErrorSeverity.ERROR);
+      }
+    }
+
+    return allResult;
+  }
+
+  /// Determine whether the context created during a previous call to
+  /// [_analyzeAll] can be re-used in order to analyze using [options].
+  bool _canContextBeReused(CommandLineOptions options) {
+    // TODO(paulberry): add a command-line option that disables context re-use.
+    if (_context == null) {
+      return false;
+    }
+    if (options.packageRootPath != _previousOptions.packageRootPath) {
+      return false;
+    }
+    if (options.packageConfigPath != _previousOptions.packageConfigPath) {
+      return false;
+    }
+    if (!_equalMaps(
+        options.definedVariables, _previousOptions.definedVariables)) {
+      return false;
+    }
+    if (options.log != _previousOptions.log) {
+      return false;
+    }
+    if (options.disableHints != _previousOptions.disableHints) {
+      return false;
+    }
+    if (options.enableStrictCallChecks !=
+        _previousOptions.enableStrictCallChecks) {
+      return false;
+    }
+    if (options.showPackageWarnings != _previousOptions.showPackageWarnings) {
+      return false;
+    }
+    if (options.showSdkWarnings != _previousOptions.showSdkWarnings) {
+      return false;
+    }
+    if (options.lints != _previousOptions.lints) {
+      return false;
+    }
+    if (options.strongMode != _previousOptions.strongMode) {
+      return false;
+    }
+    if (options.enableSuperMixins != _previousOptions.enableSuperMixins) {
+      return false;
+    }
+    return true;
+  }
+
+  /// Decide on the appropriate policy for which files need to be fully parsed
+  /// and which files need to be diet parsed, based on [options], and return an
+  /// [AnalyzeFunctionBodiesPredicate] that implements this policy.
+  AnalyzeFunctionBodiesPredicate _chooseDietParsingPolicy(
+      CommandLineOptions options) {
+    if (_isBatch) {
+      // As analyzer is currently implemented, once a file has been diet
+      // parsed, it can't easily be un-diet parsed without creating a brand new
+      // context and losing caching.  In batch mode, we can't predict which
+      // files we'll need to generate errors and warnings for in the future, so
+      // we can't safely diet parse anything.
+      return (Source source) => true;
+    }
+
+    // Determine the set of packages requiring a full parse.  Use null to
+    // represent the case where all packages require a full parse.
+    Set<String> packagesRequiringFullParse;
+    if (options.showPackageWarnings) {
+      // We are showing warnings from all packages so all packages require a
+      // full parse.
+      packagesRequiringFullParse = null;
+    } else {
+      // We aren't showing warnings for dependent packages, but we may still
+      // need to show warnings for "self" packages, so we need to do a full
+      // parse in any package containing files mentioned on the command line.
+      // TODO(paulberry): implement this.  As a temporary workaround, we're
+      // fully parsing all packages.
+      packagesRequiringFullParse = null;
+    }
+    return (Source source) {
+      if (source.uri.scheme == 'dart') {
+        return options.showSdkWarnings;
+      } else if (source.uri.scheme == 'package') {
+        if (packagesRequiringFullParse == null) {
+          return true;
+        } else if (source.uri.pathSegments.length == 0) {
+          // We should never see a URI like this, but fully parse it to be
+          // safe.
+          return true;
+        } else {
+          return packagesRequiringFullParse
+              .contains(source.uri.pathSegments[0]);
+        }
+      } else {
+        return true;
+      }
+    };
+  }
+
+  /// Decide on the appropriate method for resolving URIs based on the given
+  /// [options] and [customUrlMappings] settings, and return a
+  /// [SourceFactory] that has been configured accordingly.
+  SourceFactory _chooseUriResolutionPolicy(CommandLineOptions options) {
+    Packages packages;
+    Map<String, List<fileSystem.Folder>> packageMap;
+    UriResolver packageUriResolver;
+
+    // Process options, caching package resolution details.
+    if (options.packageConfigPath != null) {
+      String packageConfigPath = options.packageConfigPath;
+      Uri fileUri = new Uri.file(packageConfigPath);
+      try {
+        File configFile = new File.fromUri(fileUri).absolute;
+        List<int> bytes = configFile.readAsBytesSync();
+        Map<String, Uri> map = pkgfile.parse(bytes, configFile.uri);
+        packages = new MapPackages(map);
+        packageMap = _getPackageMap(packages);
+      } catch (e) {
+        printAndFail(
+            'Unable to read package config data from $packageConfigPath: $e');
+      }
+    } else if (options.packageRootPath != null) {
+      packageMap = _PackageRootPackageMapBuilder
+          .buildPackageMap(options.packageRootPath);
+
+      JavaFile packageDirectory = new JavaFile(options.packageRootPath);
+      packageUriResolver = new PackageUriResolver([packageDirectory]);
+    } else {
+      fileSystem.Resource cwd =
+          PhysicalResourceProvider.INSTANCE.getResource('.');
+
+      // Look for .packages.
+      packages = _discoverPackagespec(new Uri.directory(cwd.path));
+
+      if (packages != null) {
+        packageMap = _getPackageMap(packages);
+      } else {
+        // Fall back to pub list-package-dirs.
+
+        PubPackageMapProvider pubPackageMapProvider =
+            new PubPackageMapProvider(PhysicalResourceProvider.INSTANCE, sdk);
+        PackageMapInfo packageMapInfo =
+            pubPackageMapProvider.computePackageMap(cwd);
+        packageMap = packageMapInfo.packageMap;
+
+        // Only create a packageUriResolver if pub list-package-dirs succeeded.
+        // If it failed, that's not a problem; it simply means we have no way
+        // to resolve packages.
+        if (packageMapInfo.packageMap != null) {
+          packageUriResolver = new PackageMapUriResolver(
+              PhysicalResourceProvider.INSTANCE, packageMap);
+        }
+      }
+    }
+
+    // Now, build our resolver list.
+
+    // 'dart:' URIs come first.
+    List<UriResolver> resolvers = [new DartUriResolver(sdk)];
+
+    // Next SdkExts.
+    if (packageMap != null) {
+      resolvers.add(new SdkExtUriResolver(packageMap));
+    }
+
+    // Then package URIs.
+    if (packageUriResolver != null) {
+      resolvers.add(packageUriResolver);
+    }
+
+    // Finally files.
+    resolvers.add(new FileUriResolver());
+
+    return new SourceFactory(resolvers, packages);
+  }
+
+  /// Convert the given [sourcePath] (which may be relative to the current
+  /// working directory) to a [Source] object that can be fed to the analysis
+  /// context.
+  Source _computeLibrarySource(String sourcePath) {
+    sourcePath = _normalizeSourcePath(sourcePath);
+    JavaFile sourceFile = new JavaFile(sourcePath);
+    Source source = sdk.fromFileUri(sourceFile.toURI());
+    if (source != null) {
+      return source;
+    }
+    source = new FileBasedSource(sourceFile, sourceFile.toURI());
+    Uri uri = _context.sourceFactory.restoreUri(source);
+    if (uri == null) {
+      return source;
+    }
+    return new FileBasedSource(sourceFile, uri);
+  }
+
+  /// Create an analysis context that is prepared to analyze sources according
+  /// to the given [options], and store it in [_context].
+  void _createAnalysisContext(CommandLineOptions options) {
+    if (_canContextBeReused(options)) {
+      return;
+    }
+    _previousOptions = options;
+    // Choose a package resolution policy and a diet parsing policy based on
+    // the command-line options.
+    SourceFactory sourceFactory = _chooseUriResolutionPolicy(options);
+    AnalyzeFunctionBodiesPredicate dietParsingPolicy =
+        _chooseDietParsingPolicy(options);
+    // Create a context using these policies.
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+
+    context.sourceFactory = sourceFactory;
+
+    Map<String, String> definedVariables = options.definedVariables;
+    if (!definedVariables.isEmpty) {
+      DeclaredVariables declaredVariables = context.declaredVariables;
+      definedVariables.forEach((String variableName, String value) {
+        declaredVariables.define(variableName, value);
+      });
+    }
+
+    if (options.log) {
+      AnalysisEngine.instance.logger = new StdLogger();
+    }
+
+    // Set context options.
+    AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
+    contextOptions.hint = !options.disableHints;
+    contextOptions.enableStrictCallChecks = options.enableStrictCallChecks;
+    contextOptions.enableSuperMixins = options.enableSuperMixins;
+    contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy;
+    contextOptions.generateImplicitErrors = options.showPackageWarnings;
+    contextOptions.generateSdkErrors = options.showSdkWarnings;
+    contextOptions.lint = options.lints;
+    contextOptions.strongMode = options.strongMode;
+    context.analysisOptions = contextOptions;
+    _context = context;
+
+    // Process analysis options file (and notify all interested parties).
+    _processAnalysisOptions(options, context);
+  }
+
+  /// Return discovered packagespec, or `null` if none is found.
+  Packages _discoverPackagespec(Uri root) {
+    try {
+      Packages packages = pkgDiscovery.findPackagesFromFile(root);
+      if (packages != Packages.noPackages) {
+        return packages;
+      }
+    } catch (_) {
+      // Ignore and fall through to null.
+    }
+
+    return null;
+  }
+
+  fileSystem.File _getOptionsFile(CommandLineOptions options) {
+    fileSystem.File file;
+    String filePath = options.analysisOptionsFile;
+    if (filePath != null) {
+      file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
+      if (!file.exists) {
+        printAndFail('Options file not found: $filePath',
+            exitCode: ErrorSeverity.ERROR.ordinal);
+      }
+    } else {
+      filePath = AnalysisEngine.ANALYSIS_OPTIONS_FILE;
+      file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
+    }
+    return file;
+  }
+
+  Map<String, List<fileSystem.Folder>> _getPackageMap(Packages packages) {
+    if (packages == null) {
+      return null;
+    }
+
+    Map<String, List<fileSystem.Folder>> folderMap =
+        new Map<String, List<fileSystem.Folder>>();
+    packages.asMap().forEach((String packagePath, Uri uri) {
+      folderMap[packagePath] = [
+        PhysicalResourceProvider.INSTANCE.getFolder(path.fromUri(uri))
+      ];
+    });
+    return folderMap;
+  }
+
+  void _processAnalysisOptions(
+      CommandLineOptions options, AnalysisContext context) {
+    fileSystem.File file = _getOptionsFile(options);
+    List<OptionsProcessor> optionsProcessors =
+        AnalysisEngine.instance.optionsPlugin.optionsProcessors;
+    try {
+      AnalysisOptionsProvider analysisOptionsProvider =
+          new AnalysisOptionsProvider();
+      Map<String, YamlNode> optionMap =
+          analysisOptionsProvider.getOptionsFromFile(file);
+      optionsProcessors.forEach(
+          (OptionsProcessor p) => p.optionsProcessed(context, optionMap));
+
+      // Fill in lint rule defaults in case lints are enabled and rules are
+      // not specified in an options file.
+      if (options.lints && !containsLintRuleEntry(optionMap)) {
+        setLints(context, linterPlugin.contributedRules);
+      }
+
+      // Ask engine to further process options.
+      if (optionMap != null) {
+        configureContextOptions(context, optionMap);
+      }
+    } on Exception catch (e) {
+      optionsProcessors.forEach((OptionsProcessor p) => p.onError(e));
+    }
+  }
+
+  void _processPlugins() {
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    plugins.add(linterPlugin);
+    plugins.addAll(_userDefinedPlugins);
+
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+  }
+
+  /// Analyze a single source.
+  ErrorSeverity _runAnalyzer(Source source, CommandLineOptions options) {
+    int startTime = currentTimeMillis();
+    AnalyzerImpl analyzer =
+        new AnalyzerImpl(_context, source, options, startTime);
+    var errorSeverity = analyzer.analyzeSync();
+    if (errorSeverity == ErrorSeverity.ERROR) {
+      exitCode = errorSeverity.ordinal;
+    }
+    if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) {
+      exitCode = errorSeverity.ordinal;
+    }
+    return errorSeverity;
+  }
+
+  void _setupEnv(CommandLineOptions options) {
+    // In batch mode, SDK is specified on the main command line rather than in
+    // the command lines sent to stdin.  So process it before deciding whether
+    // to activate batch mode.
+    if (sdk == null) {
+      sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath));
+    }
+    _isBatch = options.shouldBatch;
+  }
+
+  /// Perform a deep comparison of two string maps.
+  static bool _equalMaps(Map<String, String> m1, Map<String, String> m2) {
+    if (m1.length != m2.length) {
+      return false;
+    }
+    for (String key in m1.keys) {
+      if (!m2.containsKey(key) || m1[key] != m2[key]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /// Convert [sourcePath] into an absolute path.
+  static String _normalizeSourcePath(String sourcePath) =>
+      path.normalize(new File(sourcePath).absolute.path);
+}
+
+/// Provides a framework to read command line options from stdin and feed them
+/// to a callback.
+class _BatchRunner {
+  /// Run the tool in 'batch' mode, receiving command lines through stdin and
+  /// returning pass/fail status through stdout. This feature is intended for
+  /// use in unit testing.
+  static void runAsBatch(List<String> sharedArgs, _BatchRunnerHandler handler) {
+    outSink.writeln('>>> BATCH START');
+    Stopwatch stopwatch = new Stopwatch();
+    stopwatch.start();
+    int testsFailed = 0;
+    int totalTests = 0;
+    ErrorSeverity batchResult = ErrorSeverity.NONE;
+    // Read line from stdin.
+    Stream cmdLine =
+        stdin.transform(UTF8.decoder).transform(new LineSplitter());
+    cmdLine.listen((String line) {
+      // Maybe finish.
+      if (line.isEmpty) {
+        var time = stopwatch.elapsedMilliseconds;
+        outSink.writeln(
+            '>>> BATCH END (${totalTests - testsFailed}/$totalTests) ${time}ms');
+        exitCode = batchResult.ordinal;
+      }
+      // Prepare aruments.
+      var args;
+      {
+        var lineArgs = line.split(new RegExp('\\s+'));
+        args = new List<String>();
+        args.addAll(sharedArgs);
+        args.addAll(lineArgs);
+        args.remove('-b');
+        args.remove('--batch');
+      }
+      // Analyze single set of arguments.
+      try {
+        totalTests++;
+        ErrorSeverity result = handler(args);
+        bool resultPass = result != ErrorSeverity.ERROR;
+        if (!resultPass) {
+          testsFailed++;
+        }
+        batchResult = batchResult.max(result);
+        // Write stderr end token and flush.
+        errorSink.writeln('>>> EOF STDERR');
+        String resultPassString = resultPass ? 'PASS' : 'FAIL';
+        outSink.writeln(
+            '>>> TEST $resultPassString ${stopwatch.elapsedMilliseconds}ms');
+      } catch (e, stackTrace) {
+        errorSink.writeln(e);
+        errorSink.writeln(stackTrace);
+        errorSink.writeln('>>> EOF STDERR');
+        outSink.writeln('>>> TEST CRASH');
+      }
+    });
+  }
+}
+
+class _DriverError implements Exception {
+  String msg;
+  _DriverError(this.msg);
+}
+
+/// [SdkExtUriResolver] needs a Map from package name to folder. In the case
+/// that the analyzer is invoked with a --package-root option, we need to
+/// manually create this mapping. Given [packageRootPath],
+/// [_PackageRootPackageMapBuilder] creates a simple mapping from package name
+/// to full path on disk (resolving any symbolic links).
+class _PackageRootPackageMapBuilder {
+  static Map<String, List<fileSystem.Folder>> buildPackageMap(
+      String packageRootPath) {
+    var packageRoot = new Directory(packageRootPath);
+    if (!packageRoot.existsSync()) {
+      throw new _DriverError(
+          'Package root directory ($packageRootPath) does not exist.');
+    }
+    var packages = packageRoot.listSync(followLinks: false);
+    var result = new Map<String, List<fileSystem.Folder>>();
+    for (var package in packages) {
+      var packageName = path.basename(package.path);
+      var realPath = package.resolveSymbolicLinksSync();
+      result[packageName] = [
+        PhysicalResourceProvider.INSTANCE.getFolder(realPath)
+      ];
+    }
+    return result;
+  }
+}
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
new file mode 100644
index 0000000..0154d73
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -0,0 +1,220 @@
+// 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_cli.src.error_formatter;
+
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_cli/src/options.dart';
+
+/// Returns the given error's severity.
+ProcessedSeverity _identity(AnalysisError error) =>
+    new ProcessedSeverity(error.errorCode.errorSeverity);
+
+/// Returns desired severity for the given [error] (or `null` if it's to be
+/// suppressed).
+typedef ProcessedSeverity _SeverityProcessor(AnalysisError error);
+
+/// Helper for formatting [AnalysisError]s.
+/// The two format options are a user consumable format and a machine consumable
+/// format.
+class ErrorFormatter {
+  final StringSink out;
+  final CommandLineOptions options;
+  final _SeverityProcessor processSeverity;
+
+  ErrorFormatter(this.out, this.options, [this.processSeverity = _identity]);
+
+  /// Compute the severity for this [error] or `null` if this error should be
+  /// filtered.
+  ErrorSeverity computeSeverity(AnalysisError error) =>
+      processSeverity(error)?.severity;
+
+  void formatError(
+      Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
+    Source source = error.source;
+    LineInfo_Location location = errorToLine[error].getLocation(error.offset);
+    int length = error.length;
+
+    ProcessedSeverity processedSeverity = processSeverity(error);
+    ErrorSeverity severity = processedSeverity.severity;
+
+    if (options.machineFormat) {
+      if (!processedSeverity.overridden) {
+        if (severity == ErrorSeverity.WARNING && options.warningsAreFatal) {
+          severity = ErrorSeverity.ERROR;
+        }
+      }
+      out.write(severity);
+      out.write('|');
+      out.write(error.errorCode.type);
+      out.write('|');
+      out.write(error.errorCode.name);
+      out.write('|');
+      out.write(escapePipe(source.fullName));
+      out.write('|');
+      out.write(location.lineNumber);
+      out.write('|');
+      out.write(location.columnNumber);
+      out.write('|');
+      out.write(length);
+      out.write('|');
+      out.write(escapePipe(error.message));
+    } else {
+      // Get display name.
+      String errorType = severity.displayName;
+
+      // Translate INFOs into LINTS and HINTS.
+      if (severity == ErrorSeverity.INFO) {
+        if (error.errorCode.type == ErrorType.HINT ||
+            error.errorCode.type == ErrorType.LINT) {
+          errorType = error.errorCode.type.displayName;
+        }
+      }
+
+      // [warning] 'foo' is not a... (/Users/.../tmp/foo.dart, line 1, col 2)
+      out.write('[$errorType] ${error.message} ');
+      out.write('(${source.fullName}');
+      out.write(', line ${location.lineNumber}, col ${location.columnNumber})');
+    }
+    out.writeln();
+  }
+
+  void formatErrors(List<AnalysisErrorInfo> errorInfos) {
+    var errors = new List<AnalysisError>();
+    var errorToLine = new Map<AnalysisError, LineInfo>();
+    for (AnalysisErrorInfo errorInfo in errorInfos) {
+      for (AnalysisError error in errorInfo.errors) {
+        if (computeSeverity(error) != null) {
+          errors.add(error);
+          errorToLine[error] = errorInfo.lineInfo;
+        }
+      }
+    }
+    // Sort errors.
+    errors.sort((AnalysisError error1, AnalysisError error2) {
+      // Severity.
+      ErrorSeverity severity1 = computeSeverity(error1);
+      ErrorSeverity severity2 = computeSeverity(error2);
+      int compare = severity2.compareTo(severity1);
+      if (compare != 0) {
+        return compare;
+      }
+      // Path.
+      compare = Comparable.compare(error1.source.fullName.toLowerCase(),
+          error2.source.fullName.toLowerCase());
+      if (compare != 0) {
+        return compare;
+      }
+      // Offset.
+      return error1.offset - error2.offset;
+    });
+    // Format errors.
+    int errorCount = 0;
+    int warnCount = 0;
+    int hintCount = 0;
+    int lintCount = 0;
+    for (AnalysisError error in errors) {
+      ProcessedSeverity processedSeverity = processSeverity(error);
+      ErrorSeverity severity = processedSeverity.severity;
+      if (severity == ErrorSeverity.ERROR) {
+        errorCount++;
+      } else if (severity == ErrorSeverity.WARNING) {
+        /// Only treat a warning as an error if it's not been set by a
+        /// proccesser.
+        if (!processedSeverity.overridden && options.warningsAreFatal) {
+          errorCount++;
+        } else {
+          warnCount++;
+        }
+      } else if (error.errorCode.type == ErrorType.HINT) {
+        hintCount++;
+      } else if (error.errorCode.type == ErrorType.LINT) {
+        lintCount++;
+      }
+      formatError(errorToLine, error);
+    }
+    // Print statistics.
+    if (!options.machineFormat) {
+      var hasErrors = errorCount != 0;
+      var hasWarns = warnCount != 0;
+      var hasHints = hintCount != 0;
+      var hasLints = lintCount != 0;
+      bool hasContent = false;
+      if (hasErrors) {
+        out.write(errorCount);
+        out.write(' ');
+        out.write(pluralize("error", errorCount));
+        hasContent = true;
+      }
+      if (hasWarns) {
+        if (hasContent) {
+          if (!hasHints && !hasLints) {
+            out.write(' and ');
+          } else {
+            out.write(", ");
+          }
+        }
+        out.write(warnCount);
+        out.write(' ');
+        out.write(pluralize("warning", warnCount));
+        hasContent = true;
+      }
+      if (hasHints) {
+        if (hasContent) {
+          if (!hasLints) {
+            out.write(' and ');
+          } else {
+            out.write(", ");
+          }
+        }
+        out.write(hintCount);
+        out.write(' ');
+        out.write(pluralize("hint", hintCount));
+        hasContent = true;
+      }
+      if (hasLints) {
+        if (hasContent) {
+          out.write(" and ");
+        }
+        out.write(lintCount);
+        out.write(' ');
+        out.write(pluralize("lint", lintCount));
+        hasContent = true;
+      }
+      if (hasContent) {
+        out.writeln(" found.");
+      } else {
+        out.writeln("No issues found");
+      }
+    }
+  }
+
+  static String escapePipe(String input) {
+    var result = new StringBuffer();
+    for (var c in input.codeUnits) {
+      if (c == '\\' || c == '|') {
+        result.write('\\');
+      }
+      result.writeCharCode(c);
+    }
+    return result.toString();
+  }
+
+  static String pluralize(String word, int count) {
+    if (count == 1) {
+      return word;
+    } else {
+      return word + "s";
+    }
+  }
+}
+
+/// A severity with awareness of whether it was overriden by a processor.
+class ProcessedSeverity {
+  ErrorSeverity severity;
+  bool overridden;
+  ProcessedSeverity(this.severity, [this.overridden = false]);
+}
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
new file mode 100644
index 0000000..2bc48b9
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -0,0 +1,503 @@
+// 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_cli.src.options;
+
+import 'dart:io';
+
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:args/args.dart';
+import 'package:cli_util/cli_util.dart' show getSdkDir;
+
+const _binaryName = 'dartanalyzer';
+
+/// Shared exit handler.
+///
+/// *Visible for testing.*
+ExitHandler exitHandler = exit;
+
+/// Print the given [message] to stderr and exit with the given [exitCode].
+void printAndFail(String message, {int exitCode: 15}) {
+  errorSink.writeln(message);
+  exitHandler(exitCode);
+}
+
+/// Exit handler.
+///
+/// *Visible for testing.*
+typedef void ExitHandler(int code);
+
+/// Analyzer commandline configuration options.
+class CommandLineOptions {
+  /// The path to an analysis options file
+  final String analysisOptionsFile;
+
+  /// The path to the dart SDK
+  String dartSdkPath;
+
+  /// A table mapping the names of defined variables to their values.
+  final Map<String, String> definedVariables;
+
+  /// Whether to report hints
+  final bool disableHints;
+
+  /// Whether to display version information
+  final bool displayVersion;
+
+  /// Whether to enable null-aware operators (DEP 9).
+  final bool enableNullAwareOperators;
+
+  /// Whether to strictly follow the specification when generating warnings on
+  /// "call" methods (fixes dartbug.com/21938).
+  final bool enableStrictCallChecks;
+
+  /// Whether to relax restrictions on mixins (DEP 34).
+  final bool enableSuperMixins;
+
+  /// Whether to treat type mismatches found during constant evaluation as
+  /// errors.
+  final bool enableTypeChecks;
+
+  /// Whether to treat hints as fatal
+  final bool hintsAreFatal;
+
+  /// Whether to ignore unrecognized flags
+  final bool ignoreUnrecognizedFlags;
+
+  /// Whether to report lints
+  final bool lints;
+
+  /// Whether to log additional analysis messages and exceptions
+  final bool log;
+
+  /// Whether to use machine format for error display
+  final bool machineFormat;
+
+  /// The path to the package root
+  final String packageRootPath;
+
+  /// The path to a `.packages` configuration file
+  final String packageConfigPath;
+
+  /// The path to a file to write a performance log.
+  /// (Or null if not enabled.)
+  final String perfReport;
+
+  /// Batch mode (for unit testing)
+  final bool shouldBatch;
+
+  /// Whether to show package: warnings
+  final bool showPackageWarnings;
+
+  /// Whether to show SDK warnings
+  final bool showSdkWarnings;
+
+  /// The source files to analyze
+  final List<String> sourceFiles;
+
+  /// Whether to treat warnings as fatal
+  final bool warningsAreFatal;
+
+  /// Whether to use strong static checking.
+  final bool strongMode;
+
+  /// Initialize options from the given parsed [args].
+  CommandLineOptions._fromArgs(
+      ArgResults args, Map<String, String> definedVariables)
+      : dartSdkPath = args['dart-sdk'],
+        this.definedVariables = definedVariables,
+        analysisOptionsFile = args['options'],
+        disableHints = args['no-hints'],
+        displayVersion = args['version'],
+        enableNullAwareOperators = args['enable-null-aware-operators'],
+        enableStrictCallChecks = args['enable-strict-call-checks'],
+        enableSuperMixins = args['supermixin'],
+        enableTypeChecks = args['enable_type_checks'],
+        hintsAreFatal = args['fatal-hints'],
+        ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'],
+        lints = args['lints'],
+        log = args['log'],
+        machineFormat = args['machine'] || args['format'] == 'machine',
+        packageConfigPath = args['packages'],
+        packageRootPath = args['package-root'],
+        perfReport = args['x-perf-report'],
+        shouldBatch = args['batch'],
+        showPackageWarnings =
+            args['show-package-warnings'] || args['package-warnings'],
+        showSdkWarnings = args['show-sdk-warnings'] || args['warnings'],
+        sourceFiles = args.rest,
+        warningsAreFatal = args['fatal-warnings'],
+        strongMode = args['strong'];
+
+  /// Parse [args] into [CommandLineOptions] describing the specified
+  /// analyzer options. In case of a format error, calls [printAndFail], which
+  /// by default prints an error message to stderr and exits.
+  static CommandLineOptions parse(List<String> args,
+      [printAndFail = printAndFail]) {
+    CommandLineOptions options = _parse(args);
+    // Check SDK.
+    {
+      // Infer if unspecified.
+      if (options.dartSdkPath == null) {
+        Directory sdkDir = getSdkDir(args);
+        if (sdkDir != null) {
+          options.dartSdkPath = sdkDir.path;
+        }
+      }
+
+      var sdkPath = options.dartSdkPath;
+
+      // Check that SDK is specified.
+      if (sdkPath == null) {
+        printAndFail('No Dart SDK found.');
+        return null; // Only reachable in testing.
+      }
+      // Check that SDK is existing directory.
+      if (!(new Directory(sdkPath)).existsSync()) {
+        printAndFail('Invalid Dart SDK path: $sdkPath');
+        return null; // Only reachable in testing.
+      }
+    }
+
+    // Check package config.
+    {
+      if (options.packageRootPath != null &&
+          options.packageConfigPath != null) {
+        printAndFail("Cannot specify both '--package-root' and '--packages.");
+        return null; // Only reachable in testing.
+      }
+    }
+
+    // OK.  Report deprecated options.
+    if (options.enableNullAwareOperators) {
+      errorSink.writeln(
+          "Info: Option '--enable-null-aware-operators' is no longer needed. "
+          "Null aware operators are supported by default.");
+    }
+
+    return options;
+  }
+
+  static String _getVersion() {
+    try {
+      // This is relative to bin/snapshot, so ../..
+      String versionPath =
+          Platform.script.resolve('../../version').toFilePath();
+      File versionFile = new File(versionPath);
+      return versionFile.readAsStringSync().trim();
+    } catch (_) {
+      // This happens when the script is not running in the context of an SDK.
+      return "<unknown>";
+    }
+  }
+
+  static CommandLineOptions _parse(List<String> args) {
+    args = args.expand((String arg) => arg.split('=')).toList();
+    var parser = new CommandLineParser()
+      ..addFlag('batch',
+          abbr: 'b',
+          help: 'Read commands from standard input (for testing).',
+          defaultsTo: false,
+          negatable: false)
+      ..addOption('dart-sdk', help: 'The path to the Dart SDK.')
+      ..addOption('packages',
+          help:
+              'Path to the package resolution configuration file, which supplies '
+              'a mapping of package names to paths.  This option cannot be '
+              'used with --package-root.')
+      ..addOption('package-root',
+          abbr: 'p',
+          help: 'Path to a package root directory (deprecated). This option '
+              'cannot be used with --packages.')
+      ..addOption('options', help: 'Path to an analysis options file.')
+      ..addOption('format',
+          help: 'Specifies the format in which errors are displayed.')
+      ..addFlag('machine',
+          help: 'Print errors in a format suitable for parsing (deprecated).',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag('version',
+          help: 'Print the analyzer version.',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag('lints',
+          help: 'Show lint results.', defaultsTo: false, negatable: false)
+      ..addFlag('no-hints',
+          help: 'Do not show hint results.',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag('ignore-unrecognized-flags',
+          help: 'Ignore unrecognized command line flags.',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag('fatal-hints',
+          help: 'Treat hints as fatal.', defaultsTo: false, negatable: false)
+      ..addFlag('fatal-warnings',
+          help: 'Treat non-type warnings as fatal.',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag('package-warnings',
+          help: 'Show warnings from package: imports.',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag('show-package-warnings',
+          help: 'Show warnings from package: imports (deprecated).',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag('warnings',
+          help: 'Show warnings from SDK imports.',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag('show-sdk-warnings',
+          help: 'Show warnings from SDK imports (deprecated).',
+          defaultsTo: false,
+          negatable: false)
+      ..addOption('x-perf-report',
+          help: 'Writes a performance report to the given file (experimental).')
+      ..addFlag('help',
+          abbr: 'h',
+          help: 'Display this help message.',
+          defaultsTo: false,
+          negatable: false)
+      ..addOption('url-mapping',
+          help: '--url-mapping=libraryUri,/path/to/library.dart directs the '
+              'analyzer to use "library.dart" as the source for an import '
+              'of "libraryUri".',
+          allowMultiple: true,
+          splitCommas: false)
+      //
+      // Hidden flags.
+      //
+      ..addFlag('enable-async',
+          help: 'Enable support for the proposed async feature.',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
+      ..addFlag('enable-enum',
+          help: 'Enable support for the proposed enum feature.',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
+      ..addFlag('enable-null-aware-operators',
+          help: 'Enable support for null-aware operators (DEP 9).',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
+      ..addFlag('enable-strict-call-checks',
+          help: 'Fix issue 21938.',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
+      ..addFlag('enable-new-task-model',
+          help: 'Ennable new task model.',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
+      ..addFlag('supermixin',
+          help: 'Relax restrictions on mixins (DEP 34).',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
+      ..addFlag('log',
+          help: 'Log additional messages and exceptions.',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
+      ..addFlag('enable_type_checks',
+          help: 'Check types in constant evaluation.',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
+      ..addFlag('strong',
+          help: 'Enable strong static checks (https://goo.gl/DqcBsw)');
+
+    try {
+      // TODO(scheglov) https://code.google.com/p/dart/issues/detail?id=11061
+      args =
+          args.map((String arg) => arg == '-batch' ? '--batch' : arg).toList();
+      Map<String, String> definedVariables = <String, String>{};
+      var results = parser.parse(args, definedVariables);
+      // Help requests.
+      if (results['help']) {
+        _showUsage(parser);
+        exitHandler(0);
+        return null; // Only reachable in testing.
+      }
+      // Batch mode and input files.
+      if (results['batch']) {
+        if (results.rest.isNotEmpty) {
+          errorSink.writeln('No source files expected in the batch mode.');
+          _showUsage(parser);
+          exitHandler(15);
+          return null; // Only reachable in testing.
+        }
+      } else if (results['version']) {
+        outSink.write('$_binaryName version ${_getVersion()}');
+        exitHandler(0);
+        return null; // Only reachable in testing.
+      } else {
+        if (results.rest.isEmpty) {
+          _showUsage(parser);
+          exitHandler(15);
+          return null; // Only reachable in testing.
+        }
+      }
+      return new CommandLineOptions._fromArgs(results, definedVariables);
+    } on FormatException catch (e) {
+      errorSink.writeln(e.message);
+      _showUsage(parser);
+      exitHandler(15);
+      return null; // Only reachable in testing.
+    }
+  }
+
+  static _showUsage(parser) {
+    errorSink
+        .writeln('Usage: $_binaryName [options...] <libraries to analyze...>');
+    errorSink.writeln(parser.getUsage());
+    errorSink.writeln('');
+    errorSink.writeln(
+        'For more information, see http://www.dartlang.org/tools/analyzer.');
+  }
+}
+
+/// Commandline argument parser.
+///
+/// TODO(pq): when the args package supports ignoring unrecognized
+/// options/flags, this class can be replaced with a simple [ArgParser]
+/// instance.
+class CommandLineParser {
+  final List<String> _knownFlags;
+  final bool _alwaysIgnoreUnrecognized;
+  final ArgParser _parser;
+
+  /// Creates a new command line parser.
+  CommandLineParser({bool alwaysIgnoreUnrecognized: false})
+      : _knownFlags = <String>[],
+        _alwaysIgnoreUnrecognized = alwaysIgnoreUnrecognized,
+        _parser = new ArgParser(allowTrailingOptions: true);
+
+  ArgParser get parser => _parser;
+
+  /// Defines a flag.
+  /// See [ArgParser.addFlag()].
+  void addFlag(String name,
+      {String abbr,
+      String help,
+      bool defaultsTo: false,
+      bool negatable: true,
+      void callback(bool value),
+      bool hide: false}) {
+    _knownFlags.add(name);
+    _parser.addFlag(name,
+        abbr: abbr,
+        help: help,
+        defaultsTo: defaultsTo,
+        negatable: negatable,
+        callback: callback,
+        hide: hide);
+  }
+
+  /// Defines a value-taking option.
+  /// See [ArgParser.addOption()].
+  void addOption(String name,
+      {String abbr,
+      String help,
+      List<String> allowed,
+      Map<String, String> allowedHelp,
+      String defaultsTo,
+      void callback(value),
+      bool allowMultiple: false,
+      bool splitCommas}) {
+    _knownFlags.add(name);
+    _parser.addOption(name,
+        abbr: abbr,
+        help: help,
+        allowed: allowed,
+        allowedHelp: allowedHelp,
+        defaultsTo: defaultsTo,
+        callback: callback,
+        allowMultiple: allowMultiple,
+        splitCommas: splitCommas);
+  }
+
+  /// Generates a string displaying usage information for the defined options.
+  /// See [ArgParser.usage].
+  String getUsage() => _parser.usage;
+
+  /// Parses [args], a list of command-line arguments, matches them against the
+  /// flags and options defined by this parser, and returns the result. The
+  /// values of any defined variables are captured in the given map.
+  /// See [ArgParser].
+  ArgResults parse(List<String> args, Map<String, String> definedVariables) =>
+      _parser.parse(
+          _filterUnknowns(parseDefinedVariables(args, definedVariables)));
+
+  List<String> parseDefinedVariables(
+      List<String> args, Map<String, String> definedVariables) {
+    int count = args.length;
+    List<String> remainingArgs = <String>[];
+    for (int i = 0; i < count; i++) {
+      String arg = args[i];
+      if (arg == '--') {
+        while (i < count) {
+          remainingArgs.add(args[i++]);
+        }
+      } else if (arg.startsWith("-D")) {
+        definedVariables[arg.substring(2)] = args[++i];
+      } else {
+        remainingArgs.add(arg);
+      }
+    }
+    return remainingArgs;
+  }
+
+  List<String> _filterUnknowns(List<String> args) {
+    // Only filter args if the ignore flag is specified, or if
+    // _alwaysIgnoreUnrecognized was set to true.
+    if (_alwaysIgnoreUnrecognized ||
+        args.contains('--ignore-unrecognized-flags')) {
+      //TODO(pquitslund): replace w/ the following once library skew issues are
+      // sorted out
+      //return args.where((arg) => !arg.startsWith('--') ||
+      //  _knownFlags.contains(arg.substring(2)));
+
+      // Filter all unrecognized flags and options.
+      List<String> filtered = <String>[];
+      for (int i = 0; i < args.length; ++i) {
+        String arg = args[i];
+        if (arg.startsWith('--') && arg.length > 2) {
+          String option = arg.substring(2);
+          // strip the last '=value'
+          int equalsOffset = option.lastIndexOf('=');
+          if (equalsOffset != -1) {
+            option = option.substring(0, equalsOffset);
+          }
+          // Check the option
+          if (!_knownFlags.contains(option)) {
+            //"eat" params by advancing to the next flag/option
+            i = _getNextFlagIndex(args, i);
+          } else {
+            filtered.add(arg);
+          }
+        } else {
+          filtered.add(arg);
+        }
+      }
+
+      return filtered;
+    } else {
+      return args;
+    }
+  }
+
+  int _getNextFlagIndex(args, i) {
+    for (; i < args.length; ++i) {
+      if (args[i].startsWith('--')) {
+        return i;
+      }
+    }
+    return i;
+  }
+}
diff --git a/pkg/analyzer_cli/lib/src/perf_report.dart b/pkg/analyzer_cli/lib/src/perf_report.dart
new file mode 100644
index 0000000..208e560
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/perf_report.dart
@@ -0,0 +1,106 @@
+// 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_cli.src.perf_report;
+
+import 'dart:convert' show JsonEncoder;
+import 'dart:io' show File, Platform;
+
+import 'package:analyzer/src/generated/utilities_general.dart'
+    show PerformanceTag;
+import 'package:analyzer/task/model.dart' show AnalysisTask;
+import 'package:analyzer_cli/src/options.dart' show CommandLineOptions;
+
+const _JSON = const JsonEncoder.withIndent("  ");
+
+bool _isCheckedMode = () {
+  bool x = true;
+  try {
+    // Trigger an exception if we're in checked mode.
+    x = "" as dynamic;
+    return x != ""; // return false; suppress unused variable warning
+  } catch (e) {
+    return true;
+  }
+}();
+
+String _osType = () {
+  if (Platform.isLinux) {
+    return "linux";
+  } else if (Platform.isMacOS) {
+    return "mac";
+  } else if (Platform.isWindows) {
+    return "windows";
+  } else if (Platform.isAndroid) {
+    return "android";
+  } else {
+    return "unknown";
+  }
+}();
+
+String makePerfReport(int startTime, int endTime, CommandLineOptions options) {
+  int totalTime = endTime - startTime;
+  int otherTime = totalTime;
+
+  var platformJson = <String, dynamic>{
+    'osType': _osType,
+    'dartSdkVersion': Platform.version,
+    'checkedMode': _isCheckedMode,
+  };
+
+  var optionsJson = <String, dynamic>{
+    'dartSdkPath': options.dartSdkPath,
+    'strongMode': options.strongMode,
+    'showPackageWarnings': options.showPackageWarnings,
+    'showSdkWarnings': options.showSdkWarnings,
+    'definedVariables': options.definedVariables,
+    'packageRootPath': options.packageRootPath,
+    'packageConfigPath': options.packageConfigPath,
+    'sourceFiles': options.sourceFiles,
+  };
+
+  // Convert performance tags to JSON representation.
+  var perfTagsJson = <String, dynamic>{};
+  for (PerformanceTag tag in PerformanceTag.all) {
+    if (tag != PerformanceTag.UNKNOWN) {
+      int tagTime = tag.elapsedMs;
+      perfTagsJson[tag.label] = tagTime;
+      otherTime -= tagTime;
+    }
+  }
+  perfTagsJson['other'] = otherTime;
+
+  // Generate task table.
+  var taskRows = <_TaskRow>[];
+  int totalTaskTime = 0;
+  for (var key in AnalysisTask.stopwatchMap.keys) {
+    var time = AnalysisTask.stopwatchMap[key].elapsedMilliseconds;
+    if (time == 0) continue;
+    totalTaskTime += time;
+    var count = AnalysisTask.countMap[key];
+    taskRows.add(new _TaskRow(key.toString(), time, count));
+  }
+  taskRows.sort((a, b) => b.time.compareTo(a.time));
+
+  var reportJson = <String, dynamic>{
+    'perfReportVersion': 0,
+    'platform': platformJson,
+    'options': optionsJson,
+    'totalElapsedTime': totalTime,
+    'totalTaskTime': totalTaskTime,
+    'performanceTags': perfTagsJson,
+    'tasks': taskRows.map((r) => r.toJson()).toList(),
+  };
+
+  return _JSON.convert(reportJson);
+}
+
+class _TaskRow {
+  final String name;
+  final int time;
+  final int count;
+  _TaskRow(this.name, this.time, this.count);
+
+  Map toJson() => <String, dynamic>{'name': name, 'time': time, 'count': count};
+}
diff --git a/pkg/analyzer_cli/lib/src/plugin/plugin_manager.dart b/pkg/analyzer_cli/lib/src/plugin/plugin_manager.dart
new file mode 100644
index 0000000..13a8202
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/plugin/plugin_manager.dart
@@ -0,0 +1,110 @@
+// 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_cli.src.plugin.plugin_manager;
+
+import 'dart:io';
+
+import 'package:analyzer/src/plugin/plugin_configuration.dart';
+import 'package:path/path.dart' as path;
+
+const _manifestFileName = 'plugins.yaml';
+
+/// Given a local configuration (as defined in `.analysis_options`)
+/// and information from a plugin manifest, return plugin info
+/// appropriate for configuring this plugin.
+PluginInfo combine(PluginInfo localConfig, PluginInfo manifestInfo) {
+  return new PluginInfo(
+      name: localConfig.name,
+      version: manifestInfo.version,
+      className: manifestInfo.className,
+      libraryUri: manifestInfo.libraryUri);
+}
+
+/// Call-back to allow for the injection of manifest readers that do not need
+/// to go to disk (for testing purposes).
+typedef String ManifestReader(Uri uri);
+
+/// Wraps a [plugin] info object elaborated with any configuration information
+/// extracted from an associated manifest and [status].
+class PluginDetails {
+  /// Plugin status.
+  final PluginStatus status;
+
+  /// Plugin info.
+  final PluginInfo plugin;
+
+  /// Wrap a [plugin] with [status] info.
+  PluginDetails(this.plugin) : status = PluginStatus.Applicable;
+  PluginDetails.notApplicable(this.plugin)
+      : status = PluginStatus.NotApplicable;
+  PluginDetails.notFound(this.plugin) : status = PluginStatus.NotFound;
+}
+
+/// Manages plugin information derived from plugin manifests.
+class PluginManager {
+  /// Mapping from package name to package location.
+  final Map<String, Uri> _packageMap;
+
+  /// The package naming the app to host plugins.
+  final String hostPackage;
+
+  /// Function to perform the reading of manifest URIs. (For testing.)
+  ManifestReader _manifestReader;
+
+  /// Create a plugin manager with backing package map information.
+  PluginManager(this._packageMap, this.hostPackage,
+      [ManifestReader manifestReader]) {
+    _manifestReader =
+        manifestReader != null ? manifestReader : _findAndReadManifestAtUri;
+  }
+
+  /// Find a plugin manifest describing the given [pluginPackage].
+  PluginManifest findManifest(String pluginPackage) {
+    Uri uri = _packageMap[pluginPackage];
+    String contents = _manifestReader(uri);
+    if (contents == null) {
+      return null;
+    }
+    return parsePluginManifestString(contents);
+  }
+
+  /// Return [PluginDetails] derived from associated plugin manifests
+  /// corresponding to plugins specified in the given [config].
+  Iterable<PluginDetails> getPluginDetails(PluginConfig config) =>
+      config.plugins.map((PluginInfo localConfig) {
+        PluginManifest manifest = findManifest(localConfig.name);
+        return _getDetails(localConfig, manifest);
+      });
+
+  String _findAndReadManifestAtUri(Uri uri) {
+    File manifestFile = _findManifest(uri);
+    return manifestFile?.readAsStringSync();
+  }
+
+  File _findManifest(Uri uri) {
+    if (uri == null) {
+      return null;
+    }
+
+    Directory directory = new Directory.fromUri(uri);
+    File file = new File(path.join(directory.path, _manifestFileName));
+
+    return file.existsSync() ? file : null;
+  }
+
+  PluginDetails _getDetails(PluginInfo localConfig, PluginManifest manifest) {
+    if (manifest == null) {
+      return new PluginDetails.notFound(localConfig);
+    }
+    if (!manifest.contributesTo.contains(hostPackage)) {
+      return new PluginDetails.notApplicable(localConfig);
+    }
+
+    return new PluginDetails(combine(localConfig, manifest.plugin));
+  }
+}
+
+/// Describes plugin status.
+enum PluginStatus { Applicable, NotApplicable, NotFound }
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
new file mode 100644
index 0000000..0fe04f6
--- /dev/null
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -0,0 +1,18 @@
+name: analyzer_cli
+version: 1.1.2
+author: Dart Team <misc@dartlang.org>
+description: Command line interface for the Dart Analyzer.
+homepage: https://github.com/dart-lang/analyzer_cli
+environment:
+  sdk: '>=1.12.0 <2.0.0'
+dependencies:
+  analyzer: ^0.27.0
+  args: ^0.13.0
+  cli_util: ^0.0.1
+  linter: ^0.1.10
+  package_config: ^0.1.1
+  plugin: ^0.1.0
+  yaml: ^2.1.2
+dev_dependencies:
+  typed_mock: '>=0.0.4 <1.0.0'
+  unittest: '>=0.9.0 <0.12.0'
diff --git a/pkg/analyzer_cli/test/all.dart b/pkg/analyzer_cli/test/all.dart
new file mode 100644
index 0000000..9f08563
--- /dev/null
+++ b/pkg/analyzer_cli/test/all.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'boot_loader_test.dart' as boot_loader;
+import 'driver_test.dart' as driver;
+import 'error_test.dart' as error;
+import 'options_test.dart' as options;
+import 'perf_report_test.dart' as perf;
+import 'plugin_manager_test.dart' as plugin_manager;
+import 'reporter_test.dart' as reporter;
+import 'super_mixin_test.dart' as super_mixin;
+//import 'sdk_ext_test.dart' as sdk_ext;
+//import 'strong_mode_test.dart' as strong_mode;
+
+main() {
+  boot_loader.main();
+  driver.main();
+  // TODO(pq): fix tests to run safely on the bots
+  // https://github.com/dart-lang/sdk/issues/25001
+  //sdk_ext.main();
+  //strong_mode.main();
+  error.main();
+  options.main();
+  perf.main();
+  plugin_manager.main();
+  reporter.main();
+  super_mixin.main();
+}
diff --git a/pkg/analyzer_cli/test/boot_loader_test.dart b/pkg/analyzer_cli/test/boot_loader_test.dart
new file mode 100644
index 0000000..d24d961
--- /dev/null
+++ b/pkg/analyzer_cli/test/boot_loader_test.dart
@@ -0,0 +1,98 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.test.boot_loader_test;
+
+import 'dart:io';
+
+import 'package:analyzer/src/plugin/plugin_configuration.dart';
+import 'package:analyzer_cli/src/boot_loader.dart';
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:analyzer_cli/src/options.dart';
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+main() {
+  StringSink savedOutSink, savedErrorSink;
+  int savedExitCode;
+  ExitHandler savedExitHandler;
+
+  /// Base setup.
+  _setUp() {
+    savedOutSink = outSink;
+    savedErrorSink = errorSink;
+    savedExitHandler = exitHandler;
+    savedExitCode = exitCode;
+    exitHandler = (code) => exitCode = code;
+    outSink = new StringBuffer();
+    errorSink = new StringBuffer();
+  }
+
+  /// Base teardown.
+  _tearDown() {
+    outSink = savedOutSink;
+    errorSink = savedErrorSink;
+    exitCode = savedExitCode;
+    exitHandler = savedExitHandler;
+  }
+
+  setUp(() => _setUp());
+
+  tearDown(() => _tearDown());
+
+  initializeTestEnvironment();
+
+  group('Bootloader', () {
+    group('plugin processing', () {
+      test('bad format', () {
+        BootLoader loader = new BootLoader();
+        loader.createImage([
+          '--options',
+          path.join(testDirectory, 'data/bad_plugin_options.yaml'),
+          path.join(testDirectory, 'data/test_file.dart')
+        ]);
+        expect(
+            errorSink.toString(),
+            'Plugin configuration skipped: Unrecognized plugin config '
+            'format, expected `YamlMap`, got `YamlList` '
+            '(line 2, column 4)\n');
+      });
+      test('plugin config', () {
+        BootLoader loader = new BootLoader();
+        Image image = loader.createImage([
+          '--options',
+          path.join(testDirectory, 'data/plugin_options.yaml'),
+          path.join(testDirectory, 'data/test_file.dart')
+        ]);
+        var plugins = image.config.plugins;
+        expect(plugins, hasLength(1));
+        expect(plugins.first.name, 'my_plugin1');
+      });
+      group('plugin validation', () {
+        test('requires class name', () {
+          expect(
+              validate(new PluginInfo(
+                  name: 'test_plugin', libraryUri: 'my_package/foo.dart')),
+              isNotNull);
+        });
+        test('requires library URI', () {
+          expect(
+              validate(
+                  new PluginInfo(name: 'test_plugin', className: 'MyPlugin')),
+              isNotNull);
+        });
+        test('check', () {
+          expect(
+              validate(new PluginInfo(
+                  name: 'test_plugin',
+                  className: 'MyPlugin',
+                  libraryUri: 'my_package/foo.dart')),
+              isNull);
+        });
+      });
+    });
+  });
+}
diff --git a/pkg/analyzer_cli/test/data/angular_options.yaml b/pkg/analyzer_cli/test/data/angular_options.yaml
new file mode 100644
index 0000000..e17c22a
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/angular_options.yaml
@@ -0,0 +1,7 @@
+analyzer:
+  plugins:
+    angular2_analyzer_plugin:
+      path: /Users/pquitslund/src/git/clones/angular2-dart-analyzer/analyzer_plugin/
+      class_name: AngularAnalyzerPlugin
+      library_uri: package:angular2_analyzer_plugin/plugin.dart
+    
\ No newline at end of file
diff --git a/pkg/analyzer_cli/test/data/bad_plugin_options.yaml b/pkg/analyzer_cli/test/data/bad_plugin_options.yaml
new file mode 100644
index 0000000..9a389b0
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/bad_plugin_options.yaml
@@ -0,0 +1,6 @@
+analyzer:
+  plugins:
+    - lists
+    - are
+    - not
+    - supported
diff --git a/pkg/analyzer_cli/test/data/empty_options.yaml b/pkg/analyzer_cli/test/data/empty_options.yaml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/empty_options.yaml
diff --git a/pkg/analyzer_cli/test/data/file_with_error.dart b/pkg/analyzer_cli/test/data/file_with_error.dart
new file mode 100644
index 0000000..6b4f997
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/file_with_error.dart
@@ -0,0 +1,3 @@
+
+error
+
diff --git a/pkg/analyzer_cli/test/data/file_with_hint.dart b/pkg/analyzer_cli/test/data/file_with_hint.dart
new file mode 100644
index 0000000..7c46754
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/file_with_hint.dart
@@ -0,0 +1,3 @@
+main() {
+  int unused;
+}
diff --git a/pkg/analyzer_cli/test/data/file_with_warning.dart b/pkg/analyzer_cli/test/data/file_with_warning.dart
new file mode 100644
index 0000000..6f21a74
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/file_with_warning.dart
@@ -0,0 +1,3 @@
+main() {
+  undefined();
+}
diff --git a/pkg/analyzer_cli/test/data/library_and_parts/lib.dart b/pkg/analyzer_cli/test/data/library_and_parts/lib.dart
new file mode 100644
index 0000000..a1ff776
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/library_and_parts/lib.dart
@@ -0,0 +1,3 @@
+library example;
+
+part 'part1.dart';
diff --git a/pkg/analyzer_cli/test/data/library_and_parts/part1.dart b/pkg/analyzer_cli/test/data/library_and_parts/part1.dart
new file mode 100644
index 0000000..f2fe166
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/library_and_parts/part1.dart
@@ -0,0 +1 @@
+part of example;
diff --git a/pkg/analyzer_cli/test/data/library_and_parts/part2.dart b/pkg/analyzer_cli/test/data/library_and_parts/part2.dart
new file mode 100644
index 0000000..47f4917
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/library_and_parts/part2.dart
@@ -0,0 +1 @@
+part of nothing;
diff --git a/pkg/analyzer_cli/test/data/linter_project/.analysis_options b/pkg/analyzer_cli/test/data/linter_project/.analysis_options
new file mode 100644
index 0000000..6af57a5
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/linter_project/.analysis_options
@@ -0,0 +1,3 @@
+linter:
+  rules:
+    - camel_case_types
diff --git a/pkg/analyzer_cli/test/data/linter_project/test_file.dart b/pkg/analyzer_cli/test/data/linter_project/test_file.dart
new file mode 100644
index 0000000..c1726a8
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/linter_project/test_file.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.test.data.linter_project.test_file;
+
+class a {}
diff --git a/pkg/analyzer_cli/test/data/no_lints_project/.analysis_options b/pkg/analyzer_cli/test/data/no_lints_project/.analysis_options
new file mode 100644
index 0000000..1bb8bf6
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/no_lints_project/.analysis_options
@@ -0,0 +1 @@
+# empty
diff --git a/pkg/analyzer_cli/test/data/no_lints_project/test_file.dart b/pkg/analyzer_cli/test/data/no_lints_project/test_file.dart
new file mode 100644
index 0000000..93088d6
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/no_lints_project/test_file.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.test.data.no_lints_project.test_file;
+
+class a {}
diff --git a/pkg/analyzer_cli/test/data/no_packages_file/sdk_ext_user.dart b/pkg/analyzer_cli/test/data/no_packages_file/sdk_ext_user.dart
new file mode 100644
index 0000000..b346f7f
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/no_packages_file/sdk_ext_user.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:foo';
+
+main() {
+  // import of 'dart:foo' should resolve to a file which defines bar().
+  bar();
+}
diff --git a/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options b/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
new file mode 100644
index 0000000..1d2a841
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
@@ -0,0 +1,7 @@
+analyzer:
+  errors:
+    unused_local_variable: ignore
+    missing_return: error
+    undefined_function: warning
+  language:
+    enableSuperMixins: true
diff --git a/pkg/analyzer_cli/test/data/options_tests_project/test_file.dart b/pkg/analyzer_cli/test/data/options_tests_project/test_file.dart
new file mode 100644
index 0000000..2bccf65
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/options_tests_project/test_file.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.test.data.options_test_project.test_file;
+
+
+int foo() {
+
+  baz(); // Undefined function.
+
+  // Missing return
+}
diff --git a/pkg/analyzer_cli/test/data/package_with_sdk_extension/lib/_sdkext b/pkg/analyzer_cli/test/data/package_with_sdk_extension/lib/_sdkext
new file mode 100644
index 0000000..71160ea
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/package_with_sdk_extension/lib/_sdkext
@@ -0,0 +1,3 @@
+{
+  "dart:foo": "foo.dart"
+}
diff --git a/pkg/analyzer_cli/test/data/package_with_sdk_extension/lib/foo.dart b/pkg/analyzer_cli/test/data/package_with_sdk_extension/lib/foo.dart
new file mode 100644
index 0000000..c56eef9
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/package_with_sdk_extension/lib/foo.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.
+
+void bar() {}
diff --git a/pkg/analyzer_cli/test/data/packages_file/sdk_ext_user.dart b/pkg/analyzer_cli/test/data/packages_file/sdk_ext_user.dart
new file mode 100644
index 0000000..b346f7f
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/packages_file/sdk_ext_user.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:foo';
+
+main() {
+  // import of 'dart:foo' should resolve to a file which defines bar().
+  bar();
+}
diff --git a/pkg/analyzer_cli/test/data/plugin_options.yaml b/pkg/analyzer_cli/test/data/plugin_options.yaml
new file mode 100644
index 0000000..483e76f
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/plugin_options.yaml
@@ -0,0 +1,7 @@
+analyzer:
+  plugins:
+    my_plugin1:
+      version: any
+      library_uri: 'package:my_plugin/my_plugin.dart'
+      class_name: MyPlugin
+    
\ No newline at end of file
diff --git a/pkg/analyzer_cli/test/data/strong_example.dart b/pkg/analyzer_cli/test/data/strong_example.dart
new file mode 100644
index 0000000..2f332cd
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/strong_example.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This produces an error with --strong enabled, but not otherwise.
+class MyIterable extends Iterable<String> {
+  // Error: invalid override
+  Iterator<Object> get iterator => [1, 2, 3].iterator;
+}
+
+main() {
+  var i = new MyIterable().iterator..moveNext();
+  print(i.current);
+
+  // Error: type check failed
+  List<String> list = <dynamic>[1, 2, 3];
+  print(list);
+}
diff --git a/pkg/analyzer_cli/test/data/super_mixin_example.dart b/pkg/analyzer_cli/test/data/super_mixin_example.dart
new file mode 100644
index 0000000..ea90486
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/super_mixin_example.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This produces errors normally, but --supermixin disables them.
+class Test extends Object with C {
+  void foo() {}
+}
+
+abstract class B {
+  void foo();
+}
+
+abstract class C extends B {
+  void bar() {
+    super.foo();
+  }
+}
diff --git a/pkg/analyzer_cli/test/data/test_file.dart b/pkg/analyzer_cli/test/data/test_file.dart
new file mode 100644
index 0000000..1ac3540
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/test_file.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.
+
+library analyzer_cli.test.data.test_file;
diff --git a/pkg/analyzer_cli/test/data/test_options.yaml b/pkg/analyzer_cli/test/data/test_options.yaml
new file mode 100644
index 0000000..ae890ee
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/test_options.yaml
@@ -0,0 +1,2 @@
+test_plugin: 
+  foo: bar
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
new file mode 100644
index 0000000..244788c
--- /dev/null
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -0,0 +1,423 @@
+// 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_cli.test.driver;
+
+import 'dart:io';
+
+import 'package:analyzer/plugin/options.dart';
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:analyzer_cli/src/options.dart';
+import 'package:path/path.dart' as path;
+import 'package:plugin/plugin.dart';
+import 'package:unittest/unittest.dart';
+import 'package:yaml/src/yaml_node.dart';
+
+import 'utils.dart';
+
+main() {
+  StringSink savedOutSink, savedErrorSink;
+  int savedExitCode;
+  ExitHandler savedExitHandler;
+
+  /// Base setup.
+  _setUp() {
+    savedOutSink = outSink;
+    savedErrorSink = errorSink;
+    savedExitHandler = exitHandler;
+    savedExitCode = exitCode;
+    exitHandler = (code) => exitCode = code;
+    outSink = new StringBuffer();
+    errorSink = new StringBuffer();
+  }
+
+  /// Base teardown.
+  _tearDown() {
+    outSink = savedOutSink;
+    errorSink = savedErrorSink;
+    exitCode = savedExitCode;
+    exitHandler = savedExitHandler;
+  }
+
+  setUp(() => _setUp());
+
+  tearDown(() => _tearDown());
+
+  initializeTestEnvironment();
+
+  group('Driver', () {
+    group('options', () {
+      test('custom processor', () {
+        Driver driver = new Driver();
+        TestProcessor processor = new TestProcessor();
+        driver.userDefinedPlugins = [new TestPlugin(processor)];
+        driver.start([
+          '--options',
+          path.join(testDirectory, 'data/test_options.yaml'),
+          path.join(testDirectory, 'data/test_file.dart')
+        ]);
+        expect(processor.options['test_plugin'], isNotNull);
+        expect(processor.exception, isNull);
+      });
+    });
+
+    group('exit codes', () {
+      test('fatal hints', () {
+        drive('data/file_with_hint.dart', args: ['--fatal-hints']);
+        expect(exitCode, 3);
+      });
+
+      test('not fatal hints', () {
+        drive('data/file_with_hint.dart');
+        expect(exitCode, 0);
+      });
+
+      test('fatal errors', () {
+        drive('data/file_with_error.dart');
+        expect(exitCode, 3);
+      });
+
+      test('not fatal warnings', () {
+        drive('data/file_with_warning.dart');
+        expect(exitCode, 0);
+      });
+
+      test('fatal warnings', () {
+        drive('data/file_with_warning.dart', args: ['--fatal-warnings']);
+        expect(exitCode, 3);
+      });
+
+      test('missing options file', () {
+        drive('data/test_file.dart', options: 'data/NO_OPTIONS_HERE');
+        expect(exitCode, 3);
+      });
+
+      test('missing dart file', () {
+        drive('data/NO_DART_FILE_HERE.dart');
+        expect(exitCode, 3);
+      });
+
+      test('part file', () {
+        drive('data/library_and_parts/part2.dart');
+        expect(exitCode, 3);
+      });
+
+      test('non-dangling part file', () {
+        Driver driver = new Driver();
+        driver.start([
+          path.join(testDirectory, 'data/library_and_parts/lib.dart'),
+          path.join(testDirectory, 'data/library_and_parts/part1.dart')
+        ]);
+        expect(exitCode, 0);
+      });
+
+      test('extra part file', () {
+        Driver driver = new Driver();
+        driver.start([
+          path.join(testDirectory, 'data/library_and_parts/lib.dart'),
+          path.join(testDirectory, 'data/library_and_parts/part1.dart'),
+          path.join(testDirectory, 'data/library_and_parts/part2.dart')
+        ]);
+        expect(exitCode, 3);
+      });
+    });
+
+    group('linter', () {
+      group('lints in options', () {
+        // Shared lint command.
+        var runLinter = () => drive('data/linter_project/test_file.dart',
+            options: 'data/linter_project/.analysis_options',
+            args: ['--lints']);
+
+        test('gets analysis options', () {
+          runLinter();
+
+          /// Lints should be enabled.
+          expect(driver.context.analysisOptions.lint, isTrue);
+
+          /// The .analysis_options file only specifies 'camel_case_types'.
+          var lintNames = getLints(driver.context).map((r) => r.name);
+          expect(lintNames, orderedEquals(['camel_case_types']));
+        });
+
+        test('generates lints', () {
+          runLinter();
+          expect(outSink.toString(),
+              contains('[lint] Name types using UpperCamelCase.'));
+        });
+      });
+
+      group('default lints', () {
+        // Shared lint command.
+        var runLinter = () => drive('data/linter_project/test_file.dart',
+            options: 'data/linter_project/.analysis_options',
+            args: ['--lints']);
+
+        test('gets default lints', () {
+          runLinter();
+
+          /// Lints should be enabled.
+          expect(driver.context.analysisOptions.lint, isTrue);
+
+          /// Default list should include camel_case_types.
+          var lintNames = getLints(driver.context).map((r) => r.name);
+          expect(lintNames, contains('camel_case_types'));
+        });
+
+        test('generates lints', () {
+          runLinter();
+          expect(outSink.toString(),
+              contains('[lint] Name types using UpperCamelCase.'));
+        });
+      });
+
+      group('no `--lints` flag (none in options)', () {
+        // Shared lint command.
+        var runLinter = () => drive('data/no_lints_project/test_file.dart',
+            options: 'data/no_lints_project/.analysis_options');
+
+        test('lints disabled', () {
+          runLinter();
+          expect(driver.context.analysisOptions.lint, isFalse);
+        });
+
+        test('no registered lints', () {
+          runLinter();
+          expect(getLints(driver.context), isEmpty);
+        });
+
+        test('no generated warnings', () {
+          runLinter();
+          expect(outSink.toString(), contains('No issues found'));
+        });
+      });
+    });
+
+    test('containsLintRuleEntry', () {
+      Map<String, YamlNode> options;
+      options = parseOptions('''
+linter:
+  rules:
+    - foo
+        ''');
+      expect(containsLintRuleEntry(options), true);
+      options = parseOptions('''
+        ''');
+      expect(containsLintRuleEntry(options), false);
+      options = parseOptions('''
+linter:
+  rules:
+    # - foo
+        ''');
+      expect(containsLintRuleEntry(options), true);
+      options = parseOptions('''
+linter:
+ # rules:
+    # - foo
+        ''');
+      expect(containsLintRuleEntry(options), false);
+    });
+
+    group('options processing', () {
+      group('basic config', () {
+        // Shared driver command.
+        var doDrive = () => drive('data/options_tests_project/test_file.dart',
+            options: 'data/options_tests_project/.analysis_options');
+
+        test('filters', () {
+          doDrive();
+          expect(processors, hasLength(3));
+
+          // unused_local_variable: ignore
+          var unused_local_variable = new AnalysisError(
+              new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+            ['x']
+          ]);
+          expect(processorFor(unused_local_variable).severity, isNull);
+
+          // missing_return: error
+          var missing_return = new AnalysisError(
+              new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
+            ['x']
+          ]);
+          expect(processorFor(missing_return).severity, ErrorSeverity.ERROR);
+          expect(
+              outSink.toString(),
+              contains(
+                  "[error] This function declares a return type of 'int'"));
+          expect(outSink.toString(),
+              contains("1 error and 1 warning found."));
+        });
+
+        test('language', () {
+          doDrive();
+          expect(driver.context.analysisOptions.enableSuperMixins, isTrue);
+        });
+      });
+
+      group('with flags', () {
+        // Shared driver command.
+        var doDrive = () => drive('data/options_tests_project/test_file.dart',
+            args: ['--fatal-warnings'],
+            options: 'data/options_tests_project/.analysis_options');
+
+        test('override fatal warning', () {
+          doDrive();
+          // missing_return: error
+          var undefined_function = new AnalysisError(new TestSource(), 0, 1,
+              StaticTypeWarningCode.UNDEFINED_FUNCTION, [
+            ['x']
+          ]);
+          expect(
+              processorFor(undefined_function).severity, ErrorSeverity.WARNING);
+          // Should not be made fatal by `--fatal-warnings`.
+          expect(outSink.toString(),
+              contains("[warning] The function 'baz' is not defined"));
+          expect(outSink.toString(),
+              contains("1 error and 1 warning found."));
+        });
+      });
+    });
+
+//TODO(pq): fix to be bot-friendly (sdk#25258).
+//    group('in temp directory', () {
+//      Directory savedCurrentDirectory;
+//      Directory tempDir;
+//      setUp(() {
+//        // Call base setUp.
+//        _setUp();
+//        savedCurrentDirectory = Directory.current;
+//        tempDir = Directory.systemTemp.createTempSync('analyzer_');
+//      });
+//      tearDown(() {
+//        Directory.current = savedCurrentDirectory;
+//        tempDir.deleteSync(recursive: true);
+//        // Call base tearDown.
+//        _tearDown();
+//      });
+//
+//      test('packages folder', () {
+//        Directory.current = tempDir;
+//        new File(path.join(tempDir.path, 'test.dart')).writeAsStringSync('''
+//import 'package:foo/bar.dart';
+//main() {
+//  baz();
+//}
+//        ''');
+//        Directory packagesDir =
+//            new Directory(path.join(tempDir.path, 'packages'));
+//        packagesDir.createSync();
+//        Directory fooDir = new Directory(path.join(packagesDir.path, 'foo'));
+//        fooDir.createSync();
+//        new File(path.join(fooDir.path, 'bar.dart')).writeAsStringSync('''
+//void baz() {}
+//        ''');
+//        new Driver().start(['test.dart']);
+//        expect(exitCode, 0);
+//      });
+//
+//      test('no package resolution', () {
+//        Directory.current = tempDir;
+//        new File(path.join(tempDir.path, 'test.dart')).writeAsStringSync('''
+//import 'package:path/path.dart';
+//main() {}
+//        ''');
+//        new Driver().start(['test.dart']);
+//        expect(exitCode, 3);
+//        String stdout = outSink.toString();
+//        expect(stdout, contains('[error] Target of URI does not exist'));
+//        expect(stdout, contains('1 error found.'));
+//        expect(errorSink.toString(), '');
+//      });
+//
+//      test('bad package root', () {
+//        new Driver().start(['--package-root', 'does/not/exist', 'test.dart']);
+//        String stdout = outSink.toString();
+//        expect(exitCode, 3);
+//        expect(
+//            stdout,
+//            contains(
+//                'Package root directory (does/not/exist) does not exist.'));
+//      });
+//    });
+  });
+
+
+}
+
+const emptyOptionsFile = 'data/empty_options.yaml';
+
+/// Shared driver.
+Driver driver;
+
+List<ErrorProcessor> get processors =>
+    driver.context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+
+ErrorProcessor processorFor(AnalysisError error) =>
+    processors.firstWhere((p) => p.appliesTo(error));
+
+/// Start a driver for the given [source], optionally providing additional
+/// [args] and an [options] file path.  The value of [options] defaults to
+/// an empty options file to avoid unwanted configuration from an otherwise
+/// discovered options file.
+void drive(String source,
+    {String options: emptyOptionsFile, List<String> args: const <String>[]}) {
+  driver = new Driver();
+  var cmd = [
+    '--options',
+    path.join(testDirectory, options),
+    path.join(testDirectory, source)
+  ]..addAll(args);
+  driver.start(cmd);
+}
+
+Map<String, YamlNode> parseOptions(String src) =>
+    new AnalysisOptionsProvider().getOptionsFromString(src);
+
+class TestPlugin extends Plugin {
+  TestProcessor processor;
+  TestPlugin(this.processor);
+
+  @override
+  String get uniqueIdentifier => 'test_plugin.core';
+
+  @override
+  void registerExtensionPoints(RegisterExtensionPoint register) {
+    // None
+  }
+
+  @override
+  void registerExtensions(RegisterExtension register) {
+    register(OPTIONS_PROCESSOR_EXTENSION_POINT_ID, processor);
+  }
+}
+
+class TestProcessor extends OptionsProcessor {
+  Map<String, YamlNode> options;
+  Exception exception;
+
+  @override
+  void onError(Exception exception) {
+    this.exception = exception;
+  }
+
+  @override
+  void optionsProcessed(
+      AnalysisContext context, Map<String, YamlNode> options) {
+    this.options = options;
+  }
+}
+
+class TestSource implements Source {
+  TestSource();
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analyzer_cli/test/error_test.dart b/pkg/analyzer_cli/test/error_test.dart
new file mode 100644
index 0000000..ad80133
--- /dev/null
+++ b/pkg/analyzer_cli/test/error_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+library analyzer_cli.test.error;
+
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+void main() {
+  group('error', () {
+    test("a valid Dart file doesn't throw any errors", () {
+      expect(errorsForFile('void main() => print("Hello, world!");'), isNull);
+    });
+
+    test("an empty Dart file doesn't throw any errors", () {
+      expect(errorsForFile(''), isNull);
+    });
+
+    test("an error on the first line", () {
+      expect(errorsForFile('void foo;\n'), equals(
+          "Error in test.dart: Variables cannot have a type of 'void'\n"));
+    });
+
+    test("an error on the last line", () {
+      expect(errorsForFile('\nvoid foo;'), equals(
+          "Error in test.dart: Variables cannot have a type of 'void'\n"));
+    });
+
+    test("an error in the middle", () {
+      expect(errorsForFile('\nvoid foo;\n'), equals(
+          "Error in test.dart: Variables cannot have a type of 'void'\n"));
+    });
+
+    var veryLongString = new List.filled(107, ' ').join('');
+
+    test("an error at the end of a very long line", () {
+      expect(errorsForFile('$veryLongString     void foo;'), equals(
+          "Error in test.dart: Variables cannot have a type of 'void'\n"));
+    });
+
+    test("an error at the beginning of a very long line", () {
+      expect(errorsForFile('void foo;     $veryLongString'), equals(
+          "Error in test.dart: Variables cannot have a type of 'void'\n"));
+    });
+
+    test("an error in the middle of a very long line", () {
+      expect(errorsForFile('$veryLongString void foo;$veryLongString'), equals(
+          "Error in test.dart: Variables cannot have a type of 'void'\n"));
+    });
+  });
+}
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
new file mode 100644
index 0000000..7a62bda
--- /dev/null
+++ b/pkg/analyzer_cli/test/mocks.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.
+
+library analyzer_cli.test.mocks;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_cli/src/options.dart';
+import 'package:typed_mock/typed_mock.dart';
+
+class MockAnalysisError extends TypedMock implements AnalysisError {}
+
+class MockAnalysisErrorInfo extends TypedMock implements AnalysisErrorInfo {}
+
+class MockCommandLineOptions extends TypedMock implements CommandLineOptions {}
+
+class MockErrorCode extends TypedMock implements ErrorCode {}
+
+class MockErrorType extends TypedMock implements ErrorType {}
+
+class MockLineInfo extends TypedMock implements LineInfo {}
+
+class MockLineInfo_Location extends TypedMock implements LineInfo_Location {}
+
+class MockSource extends TypedMock implements Source {}
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
new file mode 100644
index 0000000..900747b
--- /dev/null
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -0,0 +1,190 @@
+// 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_cli.test.options;
+
+import 'package:analyzer_cli/src/options.dart';
+import 'package:args/args.dart';
+import 'package:unittest/unittest.dart';
+
+main() {
+  group('CommandLineOptions', () {
+    group('parse', () {
+      test('defaults', () {
+        CommandLineOptions options =
+            CommandLineOptions.parse(['--dart-sdk', '.', 'foo.dart']);
+        expect(options, isNotNull);
+        expect(options.dartSdkPath, isNotNull);
+        expect(options.disableHints, isFalse);
+        expect(options.lints, isFalse);
+        expect(options.displayVersion, isFalse);
+        expect(options.enableStrictCallChecks, isFalse);
+        expect(options.enableSuperMixins, isFalse);
+        expect(options.enableTypeChecks, isFalse);
+        expect(options.hintsAreFatal, isFalse);
+        expect(options.ignoreUnrecognizedFlags, isFalse);
+        expect(options.log, isFalse);
+        expect(options.machineFormat, isFalse);
+        expect(options.packageRootPath, isNull);
+        expect(options.shouldBatch, isFalse);
+        expect(options.showPackageWarnings, isFalse);
+        expect(options.showSdkWarnings, isFalse);
+        expect(options.sourceFiles, equals(['foo.dart']));
+        expect(options.warningsAreFatal, isFalse);
+        expect(options.strongMode, isFalse);
+      });
+
+      test('batch', () {
+        CommandLineOptions options =
+            CommandLineOptions.parse(['--dart-sdk', '.', '--batch']);
+        expect(options.shouldBatch, isTrue);
+      });
+
+      test('defined variables', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '-Dfoo=bar', 'foo.dart']);
+        expect(options.definedVariables['foo'], equals('bar'));
+        expect(options.definedVariables['bar'], isNull);
+      });
+
+      test('enable strict call checks', () {
+        CommandLineOptions options = CommandLineOptions.parse(
+            ['--dart-sdk', '.', '--enable-strict-call-checks', 'foo.dart']);
+        expect(options.enableStrictCallChecks, isTrue);
+      });
+
+      test('enable super mixins', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--supermixin', 'foo.dart']);
+        expect(options.enableSuperMixins, isTrue);
+      });
+
+      test('enable type checks', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--enable_type_checks', 'foo.dart']);
+        expect(options.enableTypeChecks, isTrue);
+      });
+
+      test('hintsAreFatal', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--fatal-hints', 'foo.dart']);
+        expect(options.hintsAreFatal, isTrue);
+      });
+
+      test('log', () {
+        CommandLineOptions options =
+            CommandLineOptions.parse(['--dart-sdk', '.', '--log', 'foo.dart']);
+        expect(options.log, isTrue);
+      });
+
+      test('machine format', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--format=machine', 'foo.dart']);
+        expect(options.machineFormat, isTrue);
+      });
+
+      test('no-hints', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--no-hints', 'foo.dart']);
+        expect(options.disableHints, isTrue);
+      });
+
+      test('options', () {
+        CommandLineOptions options = CommandLineOptions.parse(
+            ['--dart-sdk', '.', '--options', 'options.yaml', 'foo.dart']);
+        expect(options.analysisOptionsFile, equals('options.yaml'));
+      });
+
+      test('lints', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--lints', 'foo.dart']);
+        expect(options.lints, isTrue);
+      });
+
+      test('package root', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '-p', 'bar', 'foo.dart']);
+        expect(options.packageRootPath, equals('bar'));
+      });
+
+      test('package warnings', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--package-warnings', 'foo.dart']);
+        expect(options.showPackageWarnings, isTrue);
+      });
+
+      test('sdk warnings', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--warnings', 'foo.dart']);
+        expect(options.showSdkWarnings, isTrue);
+      });
+
+      test('sourceFiles', () {
+        CommandLineOptions options = CommandLineOptions.parse(
+            ['--dart-sdk', '.', '--log', 'foo.dart', 'foo2.dart', 'foo3.dart']);
+        expect(options.sourceFiles,
+            equals(['foo.dart', 'foo2.dart', 'foo3.dart']));
+      });
+
+      test('warningsAreFatal', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--dart-sdk', '.', '--fatal-warnings', 'foo.dart']);
+        expect(options.warningsAreFatal, isTrue);
+      });
+
+      test('notice unrecognized flags', () {
+        expect(
+            () => new CommandLineParser()
+                .parse(['--bar', '--baz', 'foo.dart'], {}),
+            throwsA(new isInstanceOf<FormatException>()));
+      });
+
+      test('ignore unrecognized flags', () {
+        CommandLineOptions options = CommandLineOptions.parse([
+          '--ignore-unrecognized-flags',
+          '--bar',
+          '--baz',
+          '--dart-sdk',
+          '.',
+          'foo.dart'
+        ]);
+        expect(options, isNotNull);
+        expect(options.sourceFiles, equals(['foo.dart']));
+      });
+
+      test('ignore unrecognized options', () {
+        CommandLineParser parser =
+            new CommandLineParser(alwaysIgnoreUnrecognized: true);
+        parser.addOption('optionA');
+        parser.addFlag('flagA');
+        ArgResults argResults =
+            parser.parse(['--optionA=1', '--optionB=2', '--flagA'], {});
+        expect(argResults['optionA'], '1');
+        expect(argResults['flagA'], isTrue);
+      });
+
+      test('strong mode', () {
+        CommandLineOptions options = CommandLineOptions
+            .parse(['--strong', 'foo.dart']);
+        expect(options.strongMode, isTrue);
+      });
+
+      test("can't specify package and package-root", () {
+        var failureMessage;
+        CommandLineOptions.parse(
+            ['--package-root', '.', '--packages', '.', 'foo.dart'],
+            (msg) => failureMessage = msg);
+        expect(failureMessage,
+            equals("Cannot specify both '--package-root' and '--packages."));
+      });
+
+      test("bad SDK dir", () {
+        var failureMessage;
+        CommandLineOptions.parse(
+            ['--dart-sdk', '&&&&&', 'foo.dart'], (msg) => failureMessage = msg);
+        expect(failureMessage, equals('Invalid Dart SDK path: &&&&&'));
+      });
+    });
+  });
+}
diff --git a/pkg/analyzer_cli/test/perf_report_test.dart b/pkg/analyzer_cli/test/perf_report_test.dart
new file mode 100644
index 0000000..f668485
--- /dev/null
+++ b/pkg/analyzer_cli/test/perf_report_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.test.perf_report;
+
+import 'dart:convert' show JSON;
+
+import 'package:analyzer_cli/src/options.dart';
+import 'package:analyzer_cli/src/perf_report.dart';
+import 'package:unittest/unittest.dart';
+
+main() {
+  test('makePerfReport', () {
+    var options = CommandLineOptions.parse(["somefile.dart"]);
+    var encoded = makePerfReport(1000, 1234, options);
+
+    var json = JSON.decode(encoded);
+    expect(json['totalElapsedTime'], 234);
+    expect(json['options']['sourceFiles'], ["somefile.dart"]);
+  });
+}
diff --git a/pkg/analyzer_cli/test/plugin_manager_test.dart b/pkg/analyzer_cli/test/plugin_manager_test.dart
new file mode 100644
index 0000000..16280b2
--- /dev/null
+++ b/pkg/analyzer_cli/test/plugin_manager_test.dart
@@ -0,0 +1,93 @@
+// 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_cli.test.plugin_manager_test;
+
+import 'package:analyzer/src/plugin/plugin_configuration.dart';
+import 'package:analyzer_cli/src/plugin/plugin_manager.dart';
+import 'package:unittest/unittest.dart';
+
+main() {
+  group('plugin manager tests', () {
+    test('combine plugin info', () {
+      PluginInfo localInfo = new PluginInfo(name: 'my_plugin');
+      PluginInfo manifestInfo = new PluginInfo(
+          className: 'MyPlugin', libraryUri: 'my_plugin/my_plugin.dart');
+
+      PluginInfo merged = combine(localInfo, manifestInfo);
+      expect(merged.name, equals('my_plugin'));
+      expect(merged.className, equals('MyPlugin'));
+      expect(merged.libraryUri, equals('my_plugin/my_plugin.dart'));
+    });
+
+    test('find manifest', () {
+      const manifestSrc = '''
+library_uri: 'my_plugin/my_plugin.dart'
+''';
+      var packageMap = {'my_plugin': new Uri.file('my_plugin')};
+
+      PluginManager pm =
+          new PluginManager(packageMap, 'analyzer', (Uri uri) => manifestSrc);
+
+      PluginManifest manifest = pm.findManifest('my_plugin');
+      expect(manifest, isNotNull);
+      expect(manifest.plugin.libraryUri, equals('my_plugin/my_plugin.dart'));
+    });
+
+    final plugin1Uri = new Uri.file('my_plugin1');
+    final plugin2Uri = new Uri.file('my_plugin2');
+    final plugin3Uri = new Uri.file('my_plugin3');
+
+    const serverPluginManifest = '''
+library_uri: 'my_plugin2/my_plugin2.dart'
+contributes_to: analysis_server
+''';
+    const analyzerPluginManifest = '''
+library_uri: 'my_plugin3/my_plugin3.dart'
+contributes_to: analyzer
+''';
+
+    var packageMap = {
+      'my_plugin': plugin1Uri,
+      'my_plugin2': plugin2Uri,
+      'my_plugin3': plugin3Uri
+    };
+
+    var manifestReader = (Uri uri) {
+      if (uri == plugin2Uri) return serverPluginManifest;
+      if (uri == plugin3Uri) return analyzerPluginManifest;
+      return null;
+    };
+
+    test('get plugin details', () {
+      PluginManager pm =
+          new PluginManager(packageMap, 'analysis_server', manifestReader);
+
+      PluginInfo notFound = new PluginInfo(name: 'my_plugin1');
+      PluginInfo applicable = new PluginInfo(name: 'my_plugin2');
+      PluginInfo notApplicable = new PluginInfo(name: 'my_plugin3');
+
+      PluginConfig localConfig =
+          new PluginConfig([notFound, applicable, notApplicable]);
+
+      Iterable<PluginDetails> details = pm.getPluginDetails(localConfig);
+      expect(details, hasLength(3));
+
+      List<PluginDetails> plugins = sortByName(details);
+
+      expect(plugins[0].plugin.name, equals('my_plugin1'));
+      expect(plugins[0].status, equals(PluginStatus.NotFound));
+      expect(plugins[1].plugin.name, equals('my_plugin2'));
+      expect(
+          plugins[1].plugin.libraryUri, equals('my_plugin2/my_plugin2.dart'));
+      expect(plugins[1].status, equals(PluginStatus.Applicable));
+      expect(plugins[2].plugin.name, equals('my_plugin3'));
+      expect(plugins[2].status, equals(PluginStatus.NotApplicable));
+    });
+  });
+}
+
+List<PluginDetails> sortByName(Iterable<PluginDetails> details) =>
+    details.toList()
+      ..sort((p1, p2) => p1.plugin.name.compareTo(p2.plugin.name));
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
new file mode 100644
index 0000000..94b0896
--- /dev/null
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -0,0 +1,76 @@
+// 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_cli.test.formatter;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer_cli/src/error_formatter.dart';
+import 'package:typed_mock/typed_mock.dart';
+import 'package:unittest/unittest.dart' hide ErrorFormatter;
+
+import 'mocks.dart';
+
+main() {
+  group('reporter', () {
+    var out = new StringBuffer();
+
+    tearDown(() => out.clear());
+
+    // Options
+    var options = new MockCommandLineOptions();
+    when(options.enableTypeChecks).thenReturn(false);
+    when(options.hintsAreFatal).thenReturn(false);
+    when(options.machineFormat).thenReturn(false);
+
+    var reporter = new ErrorFormatter(out, options);
+
+    test('error', () {
+      var error = mockError(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
+      reporter.formatErrors([error]);
+
+      expect(
+          out.toString(),
+          '''[error] MSG (/foo/bar/baz.dart, line 3, col 3)
+1 error found.
+''');
+    });
+
+    test('hint', () {
+      var error = mockError(ErrorType.HINT, ErrorSeverity.INFO);
+      reporter.formatErrors([error]);
+
+      expect(
+          out.toString(),
+          '''[hint] MSG (/foo/bar/baz.dart, line 3, col 3)
+1 hint found.
+''');
+    });
+  });
+}
+
+MockAnalysisErrorInfo mockError(ErrorType type, ErrorSeverity severity) {
+  // ErrorInfo
+  var info = new MockAnalysisErrorInfo();
+  var error = new MockAnalysisError();
+  var lineInfo = new MockLineInfo();
+  var location = new MockLineInfo_Location();
+  when(location.columnNumber).thenReturn(3);
+  when(location.lineNumber).thenReturn(3);
+  when(lineInfo.getLocation(anyObject)).thenReturn(location);
+  when(info.lineInfo).thenReturn(lineInfo);
+
+  // Details
+  var code = new MockErrorCode();
+  when(code.type).thenReturn(type);
+  when(code.errorSeverity).thenReturn(severity);
+  when(code.name).thenReturn('mock_code');
+  when(error.errorCode).thenReturn(code);
+  when(error.message).thenReturn('MSG');
+  var source = new MockSource();
+  when(source.fullName).thenReturn('/foo/bar/baz.dart');
+  when(error.source).thenReturn(source);
+  when(info.errors).thenReturn([error]);
+
+  return info;
+}
diff --git a/pkg/analyzer_cli/test/sdk_ext_test.dart b/pkg/analyzer_cli/test/sdk_ext_test.dart
new file mode 100644
index 0000000..e7aa5ce
--- /dev/null
+++ b/pkg/analyzer_cli/test/sdk_ext_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test that sdk extensions are properly detected in various scenarios.
+library analyzer_cli.test.sdk_ext;
+
+import 'dart:io';
+
+import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+// TODO(pq): fix tests to run safely on the bots
+// https://github.com/dart-lang/sdk/issues/25001
+main() {}
+not_main() {
+  group('Sdk extensions', () {
+    StringSink savedOutSink, savedErrorSink;
+    int savedExitCode;
+    Directory savedCurrentDirectory;
+    setUp(() {
+      savedOutSink = outSink;
+      savedErrorSink = errorSink;
+      savedExitCode = exitCode;
+      outSink = new StringBuffer();
+      errorSink = new StringBuffer();
+      savedCurrentDirectory = Directory.current;
+    });
+    tearDown(() {
+      outSink = savedOutSink;
+      errorSink = savedErrorSink;
+      exitCode = savedExitCode;
+      Directory.current = savedCurrentDirectory;
+    });
+
+    test('--packages option supplied', () async {
+      var testDir = path.join(testDirectory, 'data', 'no_packages_file');
+      Directory.current = new Directory(testDir);
+      var packagesPath = path.join('..', 'packages_file', '.packages');
+      new Driver().start(['--packages', packagesPath, 'sdk_ext_user.dart']);
+
+      expect(exitCode, 0);
+    });
+
+    test('.packages file present', () async {
+      var testDir = path.join(testDirectory, 'data', 'packages_file');
+      Directory.current = new Directory(testDir);
+      new Driver().start(['sdk_ext_user.dart']);
+
+      expect(exitCode, 0);
+    });
+  });
+}
diff --git a/pkg/analyzer_cli/test/strong_mode_test.dart b/pkg/analyzer_cli/test/strong_mode_test.dart
new file mode 100644
index 0000000..7060fa8
--- /dev/null
+++ b/pkg/analyzer_cli/test/strong_mode_test.dart
@@ -0,0 +1,56 @@
+// 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_cli.test.strong_mode;
+
+import 'dart:io';
+
+import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+import 'driver_test.dart';
+import 'utils.dart';
+
+/// End-to-end test for --strong checking.
+///
+/// Most strong mode tests are in Analyzer, but this verifies the option is
+/// working and producing extra errors as expected.
+///
+/// Generally we don't want a lot of cases here as it requires spinning up a
+/// full analysis context.
+///
+// TODO(pq): fix tests to run safely on the bots
+// https://github.com/dart-lang/sdk/issues/25001
+main() {}
+not_main() {
+  group('--strong', () {
+    StringSink savedOutSink, savedErrorSink;
+    int savedExitCode;
+    setUp(() {
+      savedOutSink = outSink;
+      savedErrorSink = errorSink;
+      savedExitCode = exitCode;
+      outSink = new StringBuffer();
+      errorSink = new StringBuffer();
+    });
+    tearDown(() {
+      outSink = savedOutSink;
+      errorSink = savedErrorSink;
+      exitCode = savedExitCode;
+    });
+
+    test('produces stricter errors', () async {
+      var testPath = path.join(testDirectory, 'data/strong_example.dart');
+      new Driver().start(['--options', emptyOptionsFile, '--strong', testPath]);
+
+      expect(exitCode, 3);
+      var stdout = outSink.toString();
+      expect(stdout, contains('[error] Invalid override'));
+      expect(stdout, contains('[error] Type check failed'));
+      expect(stdout, contains('2 errors found.'));
+      expect(errorSink.toString(), '');
+    });
+  });
+}
diff --git a/pkg/analyzer_cli/test/super_mixin_test.dart b/pkg/analyzer_cli/test/super_mixin_test.dart
new file mode 100644
index 0000000..d2b7afe
--- /dev/null
+++ b/pkg/analyzer_cli/test/super_mixin_test.dart
@@ -0,0 +1,66 @@
+// 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_cli.test.super_mixin;
+
+import 'dart:io';
+
+import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+/// End-to-end test for --supermixins.
+///
+/// Most super mixin tests are in Analyzer, but this verifies the option is
+/// working and producing extra errors as expected.
+///
+/// Generally we don't want a lot of cases here as it requires spinning up a
+/// full analysis context.
+void main() {
+  group('--supermixins', () {
+    StringSink savedOutSink, savedErrorSink;
+    int savedExitCode;
+    setUp(() {
+      savedOutSink = outSink;
+      savedErrorSink = errorSink;
+      savedExitCode = exitCode;
+      outSink = new StringBuffer();
+      errorSink = new StringBuffer();
+    });
+    tearDown(() {
+      outSink = savedOutSink;
+      errorSink = savedErrorSink;
+      exitCode = savedExitCode;
+    });
+
+    test('produces errors when option absent', () async {
+      var testPath = path.join(testDirectory, 'data/super_mixin_example.dart');
+      new Driver().start([testPath]);
+
+      expect(exitCode, 3);
+      var stdout = outSink.toString();
+      expect(
+          stdout,
+          contains(
+              "[error] The class 'C' cannot be used as a mixin because it extends a class other than Object"));
+      expect(
+          stdout,
+          contains(
+              "[error] The class 'C' cannot be used as a mixin because it references 'super'"));
+      expect(stdout, contains('2 errors found.'));
+      expect(errorSink.toString(), '');
+    });
+
+    test('produces no errors when option present', () async {
+      var testPath = path.join(testDirectory, 'data/super_mixin_example.dart');
+      new Driver().start(['--supermixin', testPath]);
+
+      expect(exitCode, 0);
+      var stdout = outSink.toString();
+      expect(stdout, contains('No issues found'));
+    });
+  });
+}
diff --git a/pkg/analyzer_cli/test/utils.dart b/pkg/analyzer_cli/test/utils.dart
new file mode 100644
index 0000000..07dbe4b
--- /dev/null
+++ b/pkg/analyzer_cli/test/utils.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.
+
+library analyzer_cli.test.utils;
+
+import 'dart:io';
+import 'dart:mirrors';
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:path/path.dart' as pathos;
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+/// Gets the test directory in a way that works with
+/// package:test and package:unittest.
+/// See <https://github.com/dart-lang/test/issues/110> for more info.
+final String testDirectory = pathos.dirname(
+    pathos.fromUri((reflectClass(_TestUtils).owner as LibraryMirror).uri));
+
+/// Returns the string representation of the [AnalyzerErrorGroup] thrown when
+/// parsing [contents] as a Dart file. If [contents] doesn't throw any errors,
+/// this will return null.
+///
+/// This replaces the filename in the error string with its basename, since the
+/// full path will vary from machine to machine. It also replaces the exception
+/// message with "..." to decouple these tests from the specific exception
+/// messages.
+String errorsForFile(String contents) {
+  return withTempDir((temp) {
+    var path = pathos.join(temp, 'test.dart');
+    new File(path).writeAsStringSync(contents);
+    try {
+      parseDartFile(path);
+    } on AnalyzerErrorGroup catch (e) {
+      return e.toString().replaceAllMapped(
+          new RegExp(r"^(Error on line \d+ of )((?:[A-Z]+:)?[^:]+): .*$",
+              multiLine: true),
+          (match) => match[1] + pathos.basename(match[2]) + ': ...');
+    }
+    return null;
+  });
+}
+
+/// Test env setup (copied from `analyzer/test/utils.dart`).
+void initializeTestEnvironment() {
+  groupSep = ' | ';
+  JavaFile.pathContext = path.posix;
+}
+
+/// Creates a temporary directory and passes its path to [fn]. Once [fn]
+/// completes, the temporary directory and all its contents will be deleted.
+///
+/// Returns the return value of [fn].
+dynamic withTempDir(fn(String path)) {
+  var tempDir = Directory.systemTemp.createTempSync('analyzer_').path;
+  try {
+    return fn(tempDir);
+  } finally {
+    new Directory(tempDir).deleteSync(recursive: true);
+  }
+}
+
+class _TestUtils {}
diff --git a/pkg/compiler/lib/compiler_new.dart b/pkg/compiler/lib/compiler_new.dart
index 7d4ef18..b6c1e4f 100644
--- a/pkg/compiler/lib/compiler_new.dart
+++ b/pkg/compiler/lib/compiler_new.dart
@@ -168,7 +168,7 @@
     throw new ArgumentError("compilerOutput must be non-null");
   }
 
-  Compiler compiler = new Compiler(
+  CompilerImpl compiler = new CompilerImpl(
       compilerInput,
       compilerOutput,
       compilerDiagnostics,
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 5d6d2b89..8f81d15 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -14,29 +14,37 @@
     NonFilePackagesDirectoryPackages;
 import 'package:package_config/src/util.dart' show
     checkValidPackageUri;
-import 'package:sdk_library_metadata/libraries.dart' as library_info;
 
 import '../compiler_new.dart' as api;
 import 'commandline_options.dart';
 import 'common.dart';
 import 'common/tasks.dart' show
     GenericTask;
-import 'compiler.dart' as leg;
+import 'compiler.dart';
 import 'diagnostics/diagnostic_listener.dart' show
     DiagnosticOptions;
 import 'diagnostics/messages.dart' show
     Message;
 import 'elements/elements.dart' as elements;
 import 'io/source_file.dart';
+import 'platform_configuration.dart' as platform_configuration;
 import 'script.dart';
 
 const bool forceIncrementalSupport =
     const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT');
 
-class Compiler extends leg.Compiler {
+/// Locations of the platform descriptor files relative to the library root.
+const String _clientPlatform = "lib/dart_client.platform";
+const String _serverPlatform = "lib/dart_server.platform";
+const String _sharedPlatform = "lib/dart_shared.platform";
+const String _dart2dartPlatform = "lib/dart2dart.platform";
+
+/// Implements the [Compiler] using a [api.CompilerInput] for supplying the
+/// sources.
+class CompilerImpl extends Compiler {
   api.CompilerInput provider;
   api.CompilerDiagnostics handler;
-  final Uri libraryRoot;
+  final Uri platformConfigUri;
   final Uri packageConfig;
   final Uri packageRoot;
   final api.PackagesDiscoveryProvider packagesDiscoveryProvider;
@@ -44,23 +52,29 @@
   List<String> options;
   Map<String, dynamic> environment;
   bool mockableLibraryUsed = false;
-  final Set<library_info.Category> allowedLibraryCategories;
+
+  /// A mapping of the dart: library-names to their location.
+  ///
+  /// Initialized in [setupSdk].
+  Map<String, Uri> sdkLibraries;
 
   GenericTask userHandlerTask;
   GenericTask userProviderTask;
   GenericTask userPackagesDiscoveryTask;
 
-  Compiler(this.provider,
+  Uri get libraryRoot => platformConfigUri.resolve(".");
+
+  CompilerImpl(this.provider,
            api.CompilerOutput outputProvider,
            this.handler,
-           this.libraryRoot,
+           Uri libraryRoot,
            this.packageRoot,
            List<String> options,
            this.environment,
            [this.packageConfig,
             this.packagesDiscoveryProvider])
       : this.options = options,
-        this.allowedLibraryCategories = getAllowedLibraryCategories(options),
+        this.platformConfigUri = resolvePlatformConfig(libraryRoot, options),
         super(
             outputProvider: outputProvider,
             enableTypeAssertions: hasOption(options, Flags.enableCheckedMode),
@@ -102,6 +116,8 @@
             useContentSecurityPolicy:
               hasOption(options, Flags.useContentSecurityPolicy),
             useStartupEmitter: hasOption(options, Flags.fastStartup),
+            enableConditionalDirectives:
+                hasOption(options, Flags.conditionalDirectives),
             hasIncrementalSupport:
                 forceIncrementalSupport ||
                 hasOption(options, Flags.incrementalSupport),
@@ -110,8 +126,8 @@
                 fatalWarnings: hasOption(options, Flags.fatalWarnings),
                 suppressHints: hasOption(options, Flags.suppressHints),
                 terseDiagnostics: hasOption(options, Flags.terse),
-                showPackageWarnings:
-                    hasOption(options, Flags.showPackageWarnings)),
+                shownPackageWarnings: extractOptionalCsvOption(
+                      options, Flags.showPackageWarnings)),
             enableExperimentalMirrors:
                 hasOption(options, Flags.enableExperimentalMirrors),
             enableAssertMessage:
@@ -175,37 +191,58 @@
     return const <String>[];
   }
 
-  static Set<library_info.Category> getAllowedLibraryCategories(
-      List<String> options) {
-    Iterable<library_info.Category> categories =
-      extractCsvOption(options, '--categories=')
-          .map(library_info.parseCategory)
-          .where((x) => x != null);
-    if (categories.isEmpty) {
-      return new Set.from([library_info.Category.client]);
+  /// Extract list of comma separated values provided for [flag]. Returns an
+  /// empty list if [option] contain [flag] without arguments. Returns `null` if
+  /// [option] doesn't contain [flag] with or without arguments.
+  static List<String> extractOptionalCsvOption(
+      List<String> options, String flag) {
+    String prefix = '$flag=';
+    for (String option in options) {
+      if (option == flag) {
+        return const <String>[];
+      }
+      if (option.startsWith(flag)) {
+        return option.substring(prefix.length).split(',');
+      }
     }
-    return new Set.from(categories);
+    return null;
+  }
+
+  static Uri resolvePlatformConfig(Uri libraryRoot,
+                                   List<String> options) {
+    String platformConfigPath =
+        extractStringOption(options, "--platform-config=", null);
+    if (platformConfigPath != null) {
+      return libraryRoot.resolve(platformConfigPath);
+    } else if (hasOption(options, '--output-type=dart')) {
+      return libraryRoot.resolve(_dart2dartPlatform);
+    } else {
+      Iterable<String> categories = extractCsvOption(options, '--categories=');
+      if (categories.length == 0) {
+        return libraryRoot.resolve(_clientPlatform);
+      }
+      assert(categories.length <= 2);
+      if (categories.contains("Client")) {
+        if (categories.contains("Server")) {
+          return libraryRoot.resolve(_sharedPlatform);
+        }
+        return libraryRoot.resolve(_clientPlatform);
+      }
+      assert(categories.contains("Server"));
+      return libraryRoot.resolve(_serverPlatform);
+    }
   }
 
   static bool hasOption(List<String> options, String option) {
     return options.indexOf(option) >= 0;
   }
 
-  String lookupPatchPath(String dartLibraryName) {
-    library_info.LibraryInfo info = lookupLibraryInfo(dartLibraryName);
-    if (info == null) return null;
-    if (!info.isDart2jsLibrary) return null;
-    String path = info.dart2jsPatchPath;
-    if (path == null) return null;
-    return "lib/$path";
-  }
-
   void log(message) {
     callUserHandler(
         null, null, null, null, message, api.Diagnostic.VERBOSE_INFO);
   }
 
-  /// See [leg.Compiler.translateResolvedUri].
+  /// See [Compiler.translateResolvedUri].
   Uri translateResolvedUri(elements.LibraryElement importingLibrary,
                            Uri resolvedUri, Spannable spannable) {
     if (resolvedUri.scheme == 'dart') {
@@ -304,81 +341,58 @@
   }
 
   /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative
-  /// to [libraryRoot] according to the information in [library_info.libraries].
+  /// to [platformConfigUri] according to the information in the file at
+  /// [platformConfigUri].
   ///
   /// Returns null and emits an error if the library could not be found or
   /// imported into [importingLibrary].
   ///
-  /// If [importingLibrary] is a platform or patch library all dart2js libraries
-  /// can be resolved. Otherwise only libraries with categories in
-  /// [allowedLibraryCategories] can be resolved.
+  /// Internal libraries (whose name starts with '_') can be only resolved if
+  /// [importingLibrary] is a platform or patch library.
   Uri translateDartUri(elements.LibraryElement importingLibrary,
                        Uri resolvedUri, Spannable spannable) {
 
-    library_info.LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path);
+    Uri location = lookupLibraryUri(resolvedUri.path);
 
-    bool allowInternalLibraryAccess = false;
-    if (importingLibrary != null) {
-      if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) {
-        allowInternalLibraryAccess = true;
-      } else if (importingLibrary.canonicalUri.path.contains(
-          'sdk/tests/compiler/dart2js_native')) {
-        allowInternalLibraryAccess = true;
-      }
+    if (location == null) {
+      reporter.reportErrorMessage(
+          spannable,
+          MessageKind.LIBRARY_NOT_FOUND,
+          {'resolvedUri': resolvedUri});
+      return null;
     }
 
-    String computePath() {
-      if (libraryInfo == null) {
-        return null;
-      } else if (!libraryInfo.isDart2jsLibrary) {
-        return null;
-      } else {
-        if (libraryInfo.isInternal &&
-            !allowInternalLibraryAccess) {
-          if (importingLibrary != null) {
-            reporter.reportErrorMessage(
-                spannable,
-                MessageKind.INTERNAL_LIBRARY_FROM,
-                {'resolvedUri': resolvedUri,
-                  'importingUri': importingLibrary.canonicalUri});
-          } else {
-            reporter.reportErrorMessage(
-                spannable,
-                MessageKind.INTERNAL_LIBRARY,
-                {'resolvedUri': resolvedUri});
-            registerDisallowedLibraryUse(resolvedUri);
-          }
-          return null;
-        } else if (!allowInternalLibraryAccess &&
-            !allowedLibraryCategories.any(libraryInfo.categories.contains)) {
-          registerDisallowedLibraryUse(resolvedUri);
-          // TODO(sigurdm): Currently we allow the sdk libraries to import
-          // libraries from any category. We might want to revisit this.
-          return null;
+    if (resolvedUri.path.startsWith('_')  ) {
+      bool allowInternalLibraryAccess = importingLibrary != null &&
+          (importingLibrary.isPlatformLibrary ||
+              importingLibrary.isPatch ||
+              importingLibrary.canonicalUri.path
+                  .contains('sdk/tests/compiler/dart2js_native'));
+
+      if (!allowInternalLibraryAccess) {
+        if (importingLibrary != null) {
+          reporter.reportErrorMessage(
+              spannable,
+              MessageKind.INTERNAL_LIBRARY_FROM,
+              {'resolvedUri': resolvedUri,
+                'importingUri': importingLibrary.canonicalUri});
         } else {
-          return (libraryInfo.dart2jsPath != null)
-              ? libraryInfo.dart2jsPath
-              : libraryInfo.path;
+          reporter.reportErrorMessage(
+              spannable,
+              MessageKind.INTERNAL_LIBRARY,
+              {'resolvedUri': resolvedUri});
+          registerDisallowedLibraryUse(resolvedUri);
         }
+        return null;
       }
     }
 
-    String path = computePath();
-
-    if (path == null) {
-      if (libraryInfo == null) {
-        reporter.reportErrorMessage(
-            spannable,
-            MessageKind.LIBRARY_NOT_FOUND,
-            {'resolvedUri': resolvedUri});
-      } else {
-        reporter.reportErrorMessage(
-            spannable,
-            MessageKind.LIBRARY_NOT_SUPPORTED,
-            {'resolvedUri': resolvedUri});
-      }
-      // TODO(johnniwinther): Support signaling the error through the returned
-      // value.
+    if (location.scheme == "unsupported") {
+      reporter.reportErrorMessage(
+          spannable,
+          MessageKind.LIBRARY_NOT_SUPPORTED,
+          {'resolvedUri': resolvedUri});
+      registerDisallowedLibraryUse(resolvedUri);
       return null;
     }
 
@@ -388,13 +402,7 @@
       // supports this use case better.
       mockableLibraryUsed = true;
     }
-    return libraryRoot.resolve("lib/$path");
-  }
-
-  Uri resolvePatchUri(String dartLibraryPath) {
-    String patchPath = lookupPatchPath(dartLibraryPath);
-    if (patchPath == null) return null;
-    return libraryRoot.resolve(patchPath);
+    return location;
   }
 
   Uri translatePackageUri(Spannable node, Uri uri) {
@@ -420,11 +428,17 @@
   Future<elements.LibraryElement> analyzeUri(
       Uri uri,
       {bool skipLibraryWithPartOfTag: true}) {
-    if (packages == null) {
-      return setupPackages(uri).then((_) => super.analyzeUri(uri));
+    List<Future> setupFutures = new List<Future>();
+    if (sdkLibraries == null) {
+      setupFutures.add(setupSdk());
     }
-    return super.analyzeUri(
-        uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag);
+    if (packages == null) {
+      setupFutures.add(setupPackages(uri));
+    }
+    return Future.wait(setupFutures).then((_) {
+      return super.analyzeUri(uri,
+          skipLibraryWithPartOfTag: skipLibraryWithPartOfTag);
+    });
   }
 
   Future setupPackages(Uri uri) {
@@ -465,10 +479,24 @@
     return new Future.value();
   }
 
-  Future<bool> run(Uri uri) {
-    log('Allowed library categories: $allowedLibraryCategories');
+  Future<Null> setupSdk() {
+    if (sdkLibraries == null) {
+      return platform_configuration.load(platformConfigUri, provider)
+          .then((Map<String, Uri> mapping) {
+        sdkLibraries = mapping;
+      });
+    } else {
+      // The incremental compiler sets up the sdk before run.
+      // Therefore this will be called a second time.
+      return new Future.value(null);
+    }
+  }
 
-    return setupPackages(uri).then((_) {
+  Future<bool> run(Uri uri) {
+    log('Using platform configuration at ${platformConfigUri}');
+
+    return Future.wait([setupSdk(), setupPackages(uri)]).then((_) {
+      assert(sdkLibraries != null);
       assert(packages != null);
 
       return super.run(uri).then((bool success) {
@@ -495,13 +523,6 @@
   void reportDiagnostic(DiagnosticMessage message,
                         List<DiagnosticMessage> infos,
                         api.Diagnostic kind) {
-    // TODO(johnniwinther): Move this to the [DiagnosticReporter]?
-    if (kind == api.Diagnostic.ERROR ||
-        kind == api.Diagnostic.CRASH ||
-        (reporter.options.fatalWarnings &&
-         kind == api.Diagnostic.WARNING)) {
-      compilationFailed = true;
-    }
     _reportDiagnosticMessage(message, kind);
     for (DiagnosticMessage info in infos) {
       _reportDiagnosticMessage(info, api.Diagnostic.INFO);
@@ -559,10 +580,15 @@
     }
   }
 
-
   fromEnvironment(String name) => environment[name];
 
-  library_info.LibraryInfo lookupLibraryInfo(String libraryName) {
-    return library_info.libraries[libraryName];
+  Uri lookupLibraryUri(String libraryName) {
+    assert(invariant(NO_LOCATION_SPANNABLE,
+        sdkLibraries != null, message: "setupSdk() has not been run"));
+    return sdkLibraries[libraryName];
+  }
+
+  Uri resolvePatchUri(String libraryName) {
+    return backend.resolvePatchUri(libraryName, platformConfigUri);
   }
 }
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index da13773..d015b7c 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -103,7 +103,7 @@
 // TODO(ahe): These classes continuously cause problems.  We need to
 // find a more general solution.
 class ClosureFieldElement extends ElementX
-    implements FieldElement, CapturedVariable {
+    implements FieldElement, CapturedVariable, PrivatelyNamedJSEntity {
   /// The [BoxLocal] or [LocalElement] being accessed through the field.
   final Local local;
 
@@ -120,6 +120,11 @@
 
   MemberElement get memberContext => closureClass.methodElement.memberContext;
 
+  @override
+  Entity get declaredEntity => local;
+  @override
+  Entity get rootOfScope => closureClass;
+
   bool get hasNode => false;
 
   Node get node {
@@ -196,8 +201,8 @@
               STATE_DONE) {
     JavaScriptBackend backend = compiler.backend;
     ClassElement superclass = methodElement.isInstanceMember
-        ? backend.boundClosureClass
-        : backend.closureClass;
+        ? backend.helpers.boundClosureClass
+        : backend.helpers.closureClass;
     superclass.ensureResolved(compiler.resolution);
     supertype = superclass.thisType;
     interfaces = const Link<DartType>();
@@ -246,10 +251,12 @@
 // TODO(ngeoffray, ahe): These classes continuously cause problems.  We need to
 // find a more general solution.
 class BoxFieldElement extends ElementX
-    implements TypedElement, CapturedVariable, FieldElement {
+    implements TypedElement, CapturedVariable, FieldElement,
+        PrivatelyNamedJSEntity {
   final BoxLocal box;
 
-  BoxFieldElement(String name, this.variableElement, BoxLocal box)
+  BoxFieldElement(String name, this.variableElement,
+      BoxLocal box)
       : this.box = box,
         super(name, ElementKind.FIELD, box.executableContext);
 
@@ -257,6 +264,11 @@
 
   DartType get type => variableElement.type;
 
+  @override
+  Entity get declaredEntity => variableElement;
+  @override
+  Entity get rootOfScope => box;
+
   final VariableElement variableElement;
 
   accept(ElementVisitor visitor, arg) {
@@ -519,6 +531,8 @@
   ///
   /// Also, the names should be distinct from real field names to prevent
   /// clashes with selectors for those fields.
+  ///
+  /// These names are not used in generated code, just as element name.
   String getClosureVariableName(String name, int id) {
     return "_captured_${name}_$id";
   }
@@ -532,6 +546,8 @@
   ///
   /// Also, the names should be distinct from real field names to prevent
   /// clashes with selectors for those fields.
+  ///
+  /// These names are not used in generated code, just as element name.
   String getBoxFieldName(int id) {
     return "_box_$id";
   }
@@ -906,6 +922,7 @@
   }
 
   visitFor(For node) {
+    List<LocalVariableElement> boxedLoopVariables = <LocalVariableElement>[];
     inNewScope(node, () {
       // First visit initializer and update so we can easily check if a loop
       // variable was captured in one of these subexpressions.
@@ -929,24 +946,27 @@
       // condition or body are indeed flagged as mutated.
       if (node.conditionStatement != null) visit(node.conditionStatement);
       if (node.body != null) visit(node.body);
+
+      // See if we have declared loop variables that need to be boxed.
+      if (node.initializer == null) return;
+      VariableDefinitions definitions =
+          node.initializer.asVariableDefinitions();
+      if (definitions == null) return;
+      for (Link<Node> link = definitions.definitions.nodes;
+           !link.isEmpty;
+           link = link.tail) {
+        Node definition = link.head;
+        LocalVariableElement element = elements[definition];
+        // Non-mutated variables should not be boxed.  The mutatedVariables set
+        // gets cleared when 'inNewScope' returns, so check it here.
+        if (isCapturedVariable(element) && mutatedVariables.contains(element)) {
+          boxedLoopVariables.add(element);
+        }
+      }
     });
-    // See if we have declared loop variables that need to be boxed.
-    if (node.initializer == null) return;
-    VariableDefinitions definitions = node.initializer.asVariableDefinitions();
-    if (definitions == null) return;
     ClosureScope scopeData = closureData.capturingScopes[node];
     if (scopeData == null) return;
-    List<LocalVariableElement> result = <LocalVariableElement>[];
-    for (Link<Node> link = definitions.definitions.nodes;
-         !link.isEmpty;
-         link = link.tail) {
-      Node definition = link.head;
-      LocalVariableElement element = elements[definition];
-      if (isCapturedVariable(element)) {
-        result.add(element);
-      }
-    }
-    scopeData.boxedLoopVariables = result;
+    scopeData.boxedLoopVariables = boxedLoopVariables;
   }
 
   /** Returns a non-unique name for the given closure element. */
@@ -994,6 +1014,9 @@
     String closureName = computeClosureName(element);
     ClosureClassElement globalizedElement = new ClosureClassElement(
         node, closureName, compiler, element);
+    // Extend [globalizedElement] as an instantiated class in the closed world.
+    compiler.world.registerClass(
+        globalizedElement, isDirectlyInstantiated: true);
     FunctionElement callElement =
         new SynthesizedCallMethodElementX(Identifiers.call,
                                           element,
@@ -1130,3 +1153,14 @@
     return typeVariable == other.typeVariable;
   }
 }
+
+///
+/// Move the below classes to a JS model eventually.
+///
+abstract class JSEntity implements Entity {
+  Entity get declaredEntity;
+}
+
+abstract class PrivatelyNamedJSEntity implements JSEntity {
+  Entity get rootOfScope;
+}
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 03f274e..fdb8ca2 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -46,4 +46,12 @@
   static const String useCpsIr = '--use-cps-ir';
   static const String verbose = '--verbose';
   static const String version = '--version';
+
+  // Experimental flags.
+  static const String conditionalDirectives = '--conditional-directives';
+}
+
+class Option {
+  static const String showPackageWarnings =
+      '${Flags.showPackageWarnings}|${Flags.showPackageWarnings}=.*';
 }
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index 4638207..d2fa5ec 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -7,6 +7,10 @@
 import 'dart:async' show Future;
 
 import '../common.dart';
+import '../common/codegen.dart' show
+    CodegenImpact;
+import '../common/resolution.dart' show
+    ResolutionImpact;
 import '../compiler.dart' show
     Compiler;
 import '../compile_time_constants.dart' show
@@ -31,19 +35,21 @@
 import '../enqueue.dart' show
     Enqueuer,
     CodegenEnqueuer,
-    ResolutionEnqueuer,
-    WorldImpact;
+    ResolutionEnqueuer;
 import '../io/code_output.dart' show
     CodeBuffer;
 import '../io/source_information.dart' show
     SourceInformationStrategy;
+import '../js_backend/backend_helpers.dart' as js_backend show
+    BackendHelpers;
 import '../js_backend/js_backend.dart' as js_backend show
     JavaScriptBackend;
 import '../library_loader.dart' show
     LibraryLoader,
     LoadedLibraries;
 import '../native/native.dart' as native show
-    NativeEnqueuer;
+    NativeEnqueuer,
+    maybeEnableNative;
 import '../patch_parser.dart' show
     checkNativeAnnotation, checkJsInteropAnnotation;
 import '../resolution/tree_elements.dart' show
@@ -53,13 +59,14 @@
     Send;
 import '../universe/call_structure.dart' show
     CallStructure;
+import '../universe/world_impact.dart' show
+    ImpactStrategy,
+    WorldImpact;
 
 import 'codegen.dart' show
     CodegenWorkItem;
 import 'registry.dart' show
     Registry;
-import 'resolution.dart' show
-    ResolutionCallbacks;
 import 'tasks.dart' show
     CompilerTask;
 import 'work.dart' show
@@ -86,8 +93,8 @@
   /// the frontend and the backend.
   ConstantCompilerTask get constantCompilerTask;
 
-  /// Backend callback methods for the resolution phase.
-  ResolutionCallbacks get resolutionCallbacks;
+  /// Backend transformation methods for the world impacts.
+  ImpactTransformer get impactTransformer;
 
   /// The strategy used for collecting and emitting source information.
   SourceInformationStrategy get sourceInformationStrategy {
@@ -108,6 +115,7 @@
   void initializeHelperClasses() {}
 
   void enqueueHelpers(ResolutionEnqueuer world, Registry registry);
+
   WorldImpact codegen(CodegenWorkItem work);
 
   // The backend determines the native resolution enqueuer, with a no-op
@@ -174,11 +182,6 @@
     enqueuer.registerInstantiatedType(type, mirrorUsage: mirrorUsage);
   }
 
-  /// Register an is check to the backend.
-  void registerIsCheckForCodegen(DartType type,
-                                 Enqueuer enqueuer,
-                                 Registry registry) {}
-
   /// Register a runtime type variable bound tests between [typeArgument] and
   /// [bound].
   void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument,
@@ -225,33 +228,39 @@
   /// Call this method to enable support for isolates.
   void enableIsolateSupport(Enqueuer enqueuer) {}
 
-  void registerRequiredType(DartType type) {}
-
   void registerConstSymbol(String name) {}
 
   bool isNullImplementation(ClassElement cls) {
-    return cls == compiler.nullClass;
+    return cls == compiler.coreClasses.nullClass;
   }
 
-  ClassElement get intImplementation => compiler.intClass;
-  ClassElement get doubleImplementation => compiler.doubleClass;
-  ClassElement get numImplementation => compiler.numClass;
-  ClassElement get stringImplementation => compiler.stringClass;
-  ClassElement get listImplementation => compiler.listClass;
-  ClassElement get growableListImplementation => compiler.listClass;
-  ClassElement get fixedListImplementation => compiler.listClass;
-  ClassElement get constListImplementation => compiler.listClass;
-  ClassElement get mapImplementation => compiler.mapClass;
-  ClassElement get constMapImplementation => compiler.mapClass;
-  ClassElement get functionImplementation => compiler.functionClass;
-  ClassElement get typeImplementation => compiler.typeClass;
-  ClassElement get boolImplementation => compiler.boolClass;
-  ClassElement get nullImplementation => compiler.nullClass;
-  ClassElement get uint32Implementation => compiler.intClass;
-  ClassElement get uint31Implementation => compiler.intClass;
-  ClassElement get positiveIntImplementation => compiler.intClass;
+  ClassElement get intImplementation => compiler.coreClasses.intClass;
+  ClassElement get doubleImplementation => compiler.coreClasses.doubleClass;
+  ClassElement get numImplementation => compiler.coreClasses.numClass;
+  ClassElement get stringImplementation => compiler.coreClasses.stringClass;
+  ClassElement get listImplementation => compiler.coreClasses.listClass;
+  ClassElement get growableListImplementation => compiler.coreClasses.listClass;
+  ClassElement get fixedListImplementation => compiler.coreClasses.listClass;
+  ClassElement get constListImplementation => compiler.coreClasses.listClass;
+  ClassElement get mapImplementation => compiler.coreClasses.mapClass;
+  ClassElement get constMapImplementation => compiler.coreClasses.mapClass;
+  ClassElement get functionImplementation => compiler.coreClasses.functionClass;
+  ClassElement get typeImplementation => compiler.coreClasses.typeClass;
+  ClassElement get boolImplementation => compiler.coreClasses.boolClass;
+  ClassElement get nullImplementation => compiler.coreClasses.nullClass;
+  ClassElement get uint32Implementation => compiler.coreClasses.intClass;
+  ClassElement get uint31Implementation => compiler.coreClasses.intClass;
+  ClassElement get positiveIntImplementation => compiler.coreClasses.intClass;
+  ClassElement get syncStarIterableImplementation =>
+      compiler.coreClasses.iterableClass;
+  ClassElement get asyncFutureImplementation =>
+      compiler.coreClasses.futureClass;
+  ClassElement get asyncStarStreamImplementation =>
+      compiler.coreClasses.streamClass;
 
-  ClassElement defaultSuperclass(ClassElement element) => compiler.objectClass;
+  ClassElement defaultSuperclass(ClassElement element) {
+    return compiler.coreClasses.objectClass;
+  }
 
   bool isInterceptorClass(ClassElement element) => false;
 
@@ -259,6 +268,20 @@
   /// backend has specialized handling for the element.
   bool isForeign(Element element) => false;
 
+  /// Returns `true` if [element] is a native element, that is, that the
+  /// corresponding entity already exists in the target language.
+  bool isNative(Element element) => false;
+
+  /// Returns `true` if [element] is implemented via typed JavaScript interop.
+  // TODO(johnniwinther): Move this to [JavaScriptBackend].
+  bool isJsInterop(Element element) => false;
+
+  /// Returns `true` if the `native` pseudo keyword is supported for [library].
+  bool canLibraryUseNative(LibraryElement library) {
+    // TODO(johnniwinther): Move this to [JavaScriptBackend].
+    return native.maybeEnableNative(compiler, library);
+  }
+
   /// Processes [element] for resolution and returns the [FunctionElement] that
   /// defines the implementation of [element].
   FunctionElement resolveExternalFunction(FunctionElement element) => element;
@@ -270,8 +293,8 @@
     // TODO(johnniwinther): Remove this when patching is only done by the
     // JavaScript backend.
     Uri canonicalUri = library.canonicalUri;
-    if (canonicalUri == js_backend.JavaScriptBackend.DART_JS_HELPER ||
-        canonicalUri == js_backend.JavaScriptBackend.DART_INTERCEPTORS) {
+    if (canonicalUri == js_backend.BackendHelpers.DART_JS_HELPER ||
+        canonicalUri == js_backend.BackendHelpers.DART_INTERCEPTORS) {
       return true;
     }
     return false;
@@ -286,7 +309,8 @@
   /// This method is called immediately after the [library] and its parts have
   /// been scanned.
   Future onLibraryScanned(LibraryElement library, LibraryLoader loader) {
-    if (library.canUseNative) {
+    // TODO(johnniwinther): Move this to [JavaScriptBackend].
+    if (canLibraryUseNative(library)) {
       library.forEachLocalMember((Element element) {
         if (element.isClass) {
           checkNativeAnnotation(compiler, element);
@@ -296,7 +320,7 @@
     checkJsInteropAnnotation(compiler, library);
     library.forEachLocalMember((Element element) {
       checkJsInteropAnnotation(compiler, element);
-      if (element.isClass && element.isJsInterop) {
+      if (element.isClass && isJsInterop(element)) {
         ClassElement classElement = element;
         classElement.forEachMember((_, memberElement) {
           checkJsInteropAnnotation(compiler, memberElement);
@@ -395,6 +419,19 @@
                            Element element,
                            CallStructure callStructure,
                            ForeignResolver resolver) {}
+
+  /// Returns the location of the patch-file associated with [libraryName]
+  /// resolved from [plaformConfigUri].
+  ///
+  /// Returns null if there is none.
+  Uri resolvePatchUri(String libraryName, Uri plaformConfigUri);
+
+  /// Creates an impact strategy to use for compilation.
+  ImpactStrategy createImpactStrategy(
+      {bool supportDeferredLoad: true,
+       bool supportDumpInfo: true}) {
+    return const ImpactStrategy();
+  }
 }
 
 /// Interface for resolving calls to foreign functions.
@@ -409,3 +446,18 @@
   /// Resolves [typeName] to a type in the context of [node].
   DartType resolveTypeFromString(Node node, String typeName);
 }
+
+/// Backend transformation methods for the world impacts.
+class ImpactTransformer {
+  /// Transform the [ResolutionImpact] into a [WorldImpact] adding the
+  /// backend dependencies for features used in [worldImpact].
+  WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
+    return worldImpact;
+  }
+
+  /// Transform the [CodegenImpact] into a [WorldImpact] adding the
+  /// backend dependencies for features used in [worldImpact].
+  WorldImpact transformCodegenImpact(CodegenImpact worldImpact) {
+    return worldImpact;
+  }
+}
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index ab154f9..7e9b40f 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -19,148 +19,223 @@
     FunctionElement,
     LocalFunctionElement;
 import '../enqueue.dart' show
-    CodegenEnqueuer,
-    WorldImpact;
-import '../js_backend/js_backend.dart' show
-    JavaScriptBackend;
+    CodegenEnqueuer;
 import '../resolution/tree_elements.dart' show
     TreeElements;
-import '../universe/selector.dart' show
-    Selector;
-import '../universe/universe.dart' show
-    UniverseSelector;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
+import '../universe/world_impact.dart' show
+    WorldImpact,
+    WorldImpactBuilder,
+    WorldImpactVisitor;
 import '../util/util.dart' show
+    Pair,
     Setlet;
 import 'registry.dart' show
-    Registry;
+    Registry,
+    EagerRegistry;
 import 'work.dart' show
     ItemCompilationContext,
     WorkItem;
 
+class CodegenImpact extends WorldImpact {
+  const CodegenImpact();
+
+  // TODO(johnniwinther): Remove this.
+  Registry get registry => null;
+
+  Iterable<ConstantValue> get compileTimeConstants => const <ConstantValue>[];
+
+  Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
+    return const <Pair<DartType, DartType>>[];
+  }
+
+  Iterable<String> get constSymbols => const <String>[];
+
+  Iterable<Set<ClassElement>> get specializedGetInterceptors {
+    return const <Set<ClassElement>>[];
+  }
+
+  bool get usesInterceptor => false;
+
+  Iterable<ClassElement> get typeConstants => const <ClassElement>[];
+
+  Iterable<Element> get asyncMarkers => const <FunctionElement>[];
+}
+
+class _CodegenImpact extends WorldImpactBuilder implements CodegenImpact {
+  // TODO(johnniwinther): Remove this.
+  final Registry registry;
+
+  Setlet<ConstantValue> _compileTimeConstants;
+  Setlet<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks;
+  Setlet<String> _constSymbols;
+  List<Set<ClassElement>> _specializedGetInterceptors;
+  bool _usesInterceptor = false;
+  Setlet<ClassElement> _typeConstants;
+  Setlet<FunctionElement> _asyncMarkers;
+
+  _CodegenImpact(this.registry);
+
+  void apply(WorldImpactVisitor visitor) {
+    staticUses.forEach(visitor.visitStaticUse);
+    dynamicUses.forEach(visitor.visitDynamicUse);
+    typeUses.forEach(visitor.visitTypeUse);
+  }
+
+  void registerCompileTimeConstant(ConstantValue constant) {
+    if (_compileTimeConstants == null) {
+      _compileTimeConstants = new Setlet<ConstantValue>();
+    }
+    _compileTimeConstants.add(constant);
+  }
+
+  Iterable<ConstantValue> get compileTimeConstants {
+    return _compileTimeConstants != null
+        ? _compileTimeConstants : const <ConstantValue>[];
+  }
+
+  void registerTypeVariableBoundsSubtypeCheck(DartType subtype,
+                                              DartType supertype) {
+    if (_typeVariableBoundsSubtypeChecks == null) {
+      _typeVariableBoundsSubtypeChecks = new Setlet<Pair<DartType, DartType>>();
+    }
+    _typeVariableBoundsSubtypeChecks.add(
+        new Pair<DartType, DartType>(subtype, supertype));
+  }
+
+  Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
+    return _typeVariableBoundsSubtypeChecks != null
+        ? _typeVariableBoundsSubtypeChecks : const <Pair<DartType, DartType>>[];
+  }
+
+  void registerConstSymbol(String name) {
+    if (_constSymbols == null) {
+      _constSymbols = new Setlet<String>();
+    }
+    _constSymbols.add(name);
+  }
+
+  Iterable<String> get constSymbols {
+    return _constSymbols != null
+        ? _constSymbols : const <String>[];
+  }
+
+  void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
+    if (_specializedGetInterceptors == null) {
+      _specializedGetInterceptors = <Set<ClassElement>>[];
+    }
+    _specializedGetInterceptors.add(classes);
+  }
+
+  Iterable<Set<ClassElement>> get specializedGetInterceptors {
+    return _specializedGetInterceptors != null
+        ? _specializedGetInterceptors : const <Set<ClassElement>>[];
+  }
+
+  void registerUseInterceptor() {
+    _usesInterceptor = true;
+  }
+
+  bool get usesInterceptor => _usesInterceptor;
+
+  void registerTypeConstant(ClassElement element) {
+    if (_typeConstants == null) {
+      _typeConstants = new Setlet<ClassElement>();
+    }
+    _typeConstants.add(element);
+  }
+
+  Iterable<ClassElement> get typeConstants {
+    return _typeConstants != null
+        ? _typeConstants : const <ClassElement>[];
+  }
+
+  void registerAsyncMarker(FunctionElement element) {
+    if (_asyncMarkers == null) {
+      _asyncMarkers = new Setlet<FunctionElement>();
+    }
+    _asyncMarkers.add(element);
+  }
+
+  Iterable<Element> get asyncMarkers {
+    return _asyncMarkers != null
+        ? _asyncMarkers : const <FunctionElement>[];
+  }
+}
+
 // TODO(johnniwinther): Split this class into interface and implementation.
 // TODO(johnniwinther): Move this implementation to the JS backend.
 class CodegenRegistry extends Registry {
   final Compiler compiler;
-  final TreeElements treeElements;
+  final Element currentElement;
+  final _CodegenImpact worldImpact;
 
-  CodegenRegistry(this.compiler, this.treeElements);
+  CodegenRegistry(Compiler compiler, AstElement currentElement)
+      : this.compiler = compiler,
+        this.currentElement = currentElement,
+        this.worldImpact = new _CodegenImpact(new EagerRegistry(
+          'EagerRegistry for $currentElement', compiler.enqueuer.codegen));
 
   bool get isForResolution => false;
 
-  Element get currentElement => treeElements.analyzedElement;
-
   String toString() => 'CodegenRegistry for $currentElement';
 
-  CodegenEnqueuer get world => compiler.enqueuer.codegen;
-  JavaScriptBackend get backend => compiler.backend;
-
-  void registerAssert(bool hasMessage) {
-    // Codegen does not register asserts.  They have been lowered to calls.
-    assert(false);
-  }
-
+  @deprecated
   void registerInstantiatedClass(ClassElement element) {
-    backend.registerInstantiatedType(element.rawType, world, this);
+    registerInstantiation(element.rawType);
   }
 
-  void registerInstantiatedType(InterfaceType type) {
-    backend.registerInstantiatedType(type, world, this);
+  void registerStaticUse(StaticUse staticUse) {
+    worldImpact.registerStaticUse(staticUse);
   }
 
-  void registerStaticUse(Element element) {
-    world.registerStaticUse(element);
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    worldImpact.registerDynamicUse(dynamicUse);
   }
 
-  void registerDynamicInvocation(UniverseSelector selector) {
-    world.registerDynamicInvocation(selector);
-    compiler.dumpInfoTask.elementUsesSelector(currentElement, selector);
-  }
-
-  void registerDynamicSetter(UniverseSelector selector) {
-    world.registerDynamicSetter(selector);
-    compiler.dumpInfoTask.elementUsesSelector(currentElement, selector);
-  }
-
-  void registerDynamicGetter(UniverseSelector selector) {
-    world.registerDynamicGetter(selector);
-    compiler.dumpInfoTask.elementUsesSelector(currentElement, selector);
-  }
-
-  void registerGetterForSuperMethod(Element element) {
-    world.registerGetterForSuperMethod(element);
-  }
-
-  void registerFieldGetter(Element element) {
-    world.registerFieldGetter(element);
-  }
-
-  void registerFieldSetter(Element element) {
-    world.registerFieldSetter(element);
-  }
-
-  void registerIsCheck(DartType type) {
-    world.registerIsCheck(type);
-    backend.registerIsCheckForCodegen(type, world, this);
+  void registerTypeUse(TypeUse typeUse) {
+    worldImpact.registerTypeUse(typeUse);
   }
 
   void registerCompileTimeConstant(ConstantValue constant) {
-    backend.registerCompileTimeConstant(constant, this);
+    worldImpact.registerCompileTimeConstant(constant);
   }
 
   void registerTypeVariableBoundsSubtypeCheck(DartType subtype,
                                               DartType supertype) {
-    backend.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
+    worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
   }
 
   void registerInstantiatedClosure(LocalFunctionElement element) {
-    backend.registerInstantiatedClosure(element, this);
-  }
-
-  void registerGetOfStaticFunction(FunctionElement element) {
-    world.registerGetOfStaticFunction(element);
-  }
-
-  void registerSelectorUse(Selector selector) {
-    world.registerSelectorUse(new UniverseSelector(selector, null));
+    worldImpact.registerStaticUse(new StaticUse.closure(element));
   }
 
   void registerConstSymbol(String name) {
-    backend.registerConstSymbol(name);
+    worldImpact.registerConstSymbol(name);
   }
 
   void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
-    backend.registerSpecializedGetInterceptor(classes);
+    worldImpact.registerSpecializedGetInterceptor(classes);
   }
 
   void registerUseInterceptor() {
-    backend.registerUseInterceptor(world);
+    worldImpact.registerUseInterceptor();
   }
 
   void registerTypeConstant(ClassElement element) {
-    backend.customElementsAnalysis.registerTypeConstant(element, world);
-    backend.lookupMapAnalysis.registerTypeConstant(element);
-  }
-
-  void registerStaticInvocation(Element element) {
-    world.registerStaticUse(element);
-  }
-
-  void registerSuperInvocation(Element element) {
-    world.registerStaticUse(element);
-  }
-
-  void registerDirectInvocation(Element element) {
-    world.registerStaticUse(element);
+    worldImpact.registerTypeConstant(element);
   }
 
   void registerInstantiation(InterfaceType type) {
-    backend.registerInstantiatedType(type, world, this);
+    registerTypeUse(new TypeUse.instantiation(type));
   }
 
   void registerAsyncMarker(FunctionElement element) {
-    backend.registerAsyncMarker(element, world, this);
+    worldImpact.registerAsyncMarker(element);
   }
-
 }
 
 /// [WorkItem] used exclusively by the [CodegenEnqueuer].
@@ -193,7 +268,7 @@
   WorldImpact run(Compiler compiler, CodegenEnqueuer world) {
     if (world.isProcessed(element)) return const WorldImpact();
 
-    registry = new CodegenRegistry(compiler, resolutionTree);
+    registry = new CodegenRegistry(compiler, element);
     return compiler.codegen(this, world);
   }
 }
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 45c7b1f..70ebabe 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -38,6 +38,9 @@
 
   /// The name of the runtime type property on 'Object'.
   static const String runtimeType_ = 'runtimeType';
+
+  /// The name of the getter returning the size of containers and strings.
+  static const String length = 'length';
 }
 
 /// [Name]s commonly used.
@@ -67,6 +70,10 @@
   static const Name INDEX_NAME = const PublicName("[]");
   static const Name INDEX_SET_NAME = const PublicName("[]=");
   static const Name CALL_NAME = Names.call;
+
+  static const Name length = const PublicName(Identifiers.length);
+
+  static const Name runtimeType_ = const PublicName(Identifiers.runtimeType_);
 }
 
 /// [Selector]s commonly used.
@@ -90,10 +97,18 @@
   static final Selector noSuchMethod_ =
       new Selector.call(Names.noSuchMethod_, CallStructure.ONE_ARG);
 
+  /// The selector for tearing off noSuchMethod.
+  static final Selector noSuchMethodGetter =
+      new Selector.getter(Names.noSuchMethod_);
+
   /// The selector for calling the to-string method on 'Object'.
   static final Selector toString_ =
       new Selector.call(Names.toString_, CallStructure.NO_ARGS);
 
+  /// The selector for tearing off toString.
+  static final Selector toStringGetter =
+      new Selector.getter(Names.toString_);
+
   static final Selector hashCode_ =
       new Selector.getter(const PublicName('hashCode'));
 
@@ -101,6 +116,24 @@
       new Selector.call(const PublicName("compareTo"), CallStructure.ONE_ARG);
 
   static final Selector equals = new Selector.binaryOperator('==');
+
+  static final Selector length = new Selector.getter(Names.length);
+
+  static final Selector codeUnitAt =
+      new Selector.call(const PublicName('codeUnitAt'), CallStructure.ONE_ARG);
+
+  static final Selector index = new Selector.index();
+
+  static final Selector runtimeType_ = new Selector.getter(Names.runtimeType_);
+
+  /// List of all the selectors held in static fields.
+  ///
+  /// These objects are shared between different runs in batch-mode and must
+  /// thus remain in the [Selector.canonicalizedValues] map.
+  static final List<Selector> ALL = <Selector>[
+      cancel, current, iterator, moveNext, noSuchMethod_, noSuchMethodGetter,
+      toString_, toStringGetter, hashCode_, compareTo, equals, length,
+      codeUnitAt, index, runtimeType_];
 }
 
 /// [Uri]s commonly used.
@@ -123,4 +156,4 @@
   /// The URI for 'dart:_native_typed_data'.
   static final Uri dart__native_typed_data =
       new Uri(scheme: 'dart', path: '_native_typed_data');
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/common/registry.dart b/pkg/compiler/lib/src/common/registry.dart
index 055a7c6..1ba7b9d 100644
--- a/pkg/compiler/lib/src/common/registry.dart
+++ b/pkg/compiler/lib/src/common/registry.dart
@@ -5,12 +5,15 @@
 library dart2js.common.registry;
 
 import '../dart_types.dart' show
-  InterfaceType;
+    InterfaceType;
+import '../enqueue.dart' show
+    Enqueuer;
 import '../elements/elements.dart' show
-  Element,
-  FunctionElement;
-import '../universe/universe.dart' show
-  UniverseSelector;
+    Element,
+    FunctionElement;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse;
 
 /// Interface for registration of element dependencies.
 abstract class Registry {
@@ -19,15 +22,36 @@
 
   bool get isForResolution;
 
-  void registerDynamicInvocation(UniverseSelector selector);
+  void registerDynamicUse(DynamicUse staticUse);
 
-  void registerDynamicGetter(UniverseSelector selector);
-
-  void registerDynamicSetter(UniverseSelector selector);
-
-  void registerStaticInvocation(Element element);
+  void registerStaticUse(StaticUse staticUse);
 
   void registerInstantiation(InterfaceType type);
+}
 
-  void registerGetOfStaticFunction(FunctionElement element);
+// TODO(johnniwinther): Remove this.
+class EagerRegistry extends Registry {
+  final String name;
+  final Enqueuer world;
+
+  EagerRegistry(this.name, this.world);
+
+  bool get isForResolution => world.isResolutionQueue;
+
+  @override
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    world.registerDynamicUse(dynamicUse);
+  }
+
+  @override
+  void registerInstantiation(InterfaceType type) {
+    world.registerInstantiatedType(type);
+  }
+
+  @override
+  void registerStaticUse(StaticUse staticUse) {
+    world.registerStaticUse(staticUse);
+  }
+
+  String toString() => name;
 }
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 88cb4b9..e422ef8 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -8,6 +8,8 @@
 import '../common.dart';
 import '../compiler.dart' show
     Compiler;
+import '../constants/expressions.dart' show
+    ConstantExpression;
 import '../core_types.dart' show
     CoreTypes;
 import '../dart_types.dart' show
@@ -26,18 +28,15 @@
     TypedefElement,
     TypeVariableElement;
 import '../enqueue.dart' show
-    ResolutionEnqueuer,
-    WorldImpact;
+    ResolutionEnqueuer;
+import '../parser/element_listener.dart' show
+    ScannerOptions;
 import '../tree/tree.dart' show
     AsyncForIn,
     Send,
     TypeAnnotation;
-import '../universe/universe.dart' show
-    UniverseSelector;
-import '../util/util.dart' show
-    Setlet;
-import 'registry.dart' show
-    Registry;
+import '../universe/world_impact.dart' show
+    WorldImpact;
 import 'work.dart' show
     ItemCompilationContext,
     WorkItem;
@@ -59,27 +58,16 @@
   bool get isAnalyzed => _isAnalyzed;
 }
 
-// TODO(johnniwinther): Rename this to something like  `BackendResolutionApi`
-// and clean up the interface.
-/// Backend callbacks function specific to the resolution phase.
-class ResolutionCallbacks {
-  /// Transform the [ResolutionImpact] into a [WorldImpact] adding the
-  /// backend dependencies for features used in [worldImpact].
-  WorldImpact transformImpact(ResolutionImpact worldImpact) => worldImpact;
-}
-
 class ResolutionImpact extends WorldImpact {
   const ResolutionImpact();
 
-  // TODO(johnniwinther): Remove this.
-  void registerDependency(Element element) {}
-
   Iterable<Feature> get features => const <Feature>[];
-  Iterable<DartType> get requiredTypes => const <DartType>[];
   Iterable<MapLiteralUse> get mapLiterals => const <MapLiteralUse>[];
   Iterable<ListLiteralUse> get listLiterals => const <ListLiteralUse>[];
-  Iterable<DartType> get typeLiterals => const <DartType>[];
   Iterable<String> get constSymbolNames => const <String>[];
+  Iterable<ConstantExpression> get constantLiterals {
+    return const <ConstantExpression>[];
+  }
 }
 
 /// A language feature seen during resolution.
@@ -111,6 +99,8 @@
   STACK_TRACE_IN_CATCH,
   /// String interpolation.
   STRING_INTERPOLATION,
+  /// String juxtaposition.
+  STRING_JUXTAPOSITION,
   /// An implicit call to `super.noSuchMethod`, like calling an unresolved
   /// super method.
   SUPER_NO_SUCH_METHOD,
@@ -182,129 +172,6 @@
   }
 }
 
-/// Mutable implementation of [WorldImpact] used to transform
-/// [ResolutionImpact] to [WorldImpact].
-// TODO(johnniwinther): Remove [Registry] when dependency is tracked directly
-// on [WorldImpact].
-class TransformedWorldImpact extends WorldImpact {
-  final ResolutionImpact worldImpact;
-
-  Setlet<Element> _staticUses;
-  Setlet<InterfaceType> _instantiatedTypes;
-  Setlet<UniverseSelector> _dynamicGetters;
-  Setlet<UniverseSelector> _dynamicInvocations;
-  Setlet<UniverseSelector> _dynamicSetters;
-
-  TransformedWorldImpact(this.worldImpact);
-
-  @override
-  Iterable<DartType> get asCasts => worldImpact.asCasts;
-
-  @override
-  Iterable<DartType> get checkedModeChecks => worldImpact.checkedModeChecks;
-
-  @override
-  Iterable<MethodElement> get closurizedFunctions {
-    return worldImpact.closurizedFunctions;
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicGetters {
-    return _dynamicGetters != null
-        ? _dynamicGetters : worldImpact.dynamicGetters;
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicInvocations {
-    return _dynamicInvocations != null
-        ? _dynamicInvocations : worldImpact.dynamicInvocations;
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicSetters {
-    return _dynamicSetters != null
-        ? _dynamicSetters : worldImpact.dynamicSetters;
-  }
-
-  @override
-  Iterable<DartType> get isChecks => worldImpact.isChecks;
-
-  @override
-  Iterable<Element> get staticUses {
-    if (_staticUses == null) {
-      return worldImpact.staticUses;
-    }
-    return _staticUses;
-  }
-
-  _unsupported(String message) => throw new UnsupportedError(message);
-
-  void registerDynamicGetter(UniverseSelector selector) {
-    if (_dynamicGetters == null) {
-      _dynamicGetters = new Setlet<UniverseSelector>();
-      _dynamicGetters.addAll(worldImpact.dynamicGetters);
-    }
-    _dynamicGetters.add(selector);
-  }
-
-  void registerDynamicInvocation(UniverseSelector selector) {
-    if (_dynamicInvocations == null) {
-      _dynamicInvocations = new Setlet<UniverseSelector>();
-      _dynamicInvocations.addAll(worldImpact.dynamicInvocations);
-    }
-    _dynamicInvocations.add(selector);
-  }
-
-  void registerDynamicSetter(UniverseSelector selector) {
-    if (_dynamicSetters == null) {
-      _dynamicSetters = new Setlet<UniverseSelector>();
-      _dynamicSetters.addAll(worldImpact.dynamicSetters);
-    }
-    _dynamicSetters.add(selector);
-  }
-
-  void registerInstantiatedType(InterfaceType type) {
-    // TODO(johnniwinther): Remove this when dependency tracking is done on
-    // the world impact itself.
-    worldImpact.registerDependency(type.element);
-    if (_instantiatedTypes == null) {
-      _instantiatedTypes = new Setlet<InterfaceType>();
-    }
-    _instantiatedTypes.add(type);
-  }
-
-  @override
-  Iterable<InterfaceType> get instantiatedTypes {
-    return _instantiatedTypes != null
-        ? _instantiatedTypes : const <InterfaceType>[];
-  }
-
-  @override
-  Iterable<DartType> get typeLiterals {
-    return worldImpact.typeLiterals;
-  }
-
-  void registerStaticUse(Element element) {
-    // TODO(johnniwinther): Remove this when dependency tracking is done on
-    // the world impact itself.
-    worldImpact.registerDependency(element);
-    if (_staticUses == null) {
-      _staticUses = new Setlet<Element>();
-    }
-    _staticUses.add(element);
-  }
-
-  @override
-  Iterable<LocalFunctionElement> get closures => worldImpact.closures;
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write('TransformedWorldImpact($worldImpact)');
-    sb.write(super.toString());
-    return sb.toString();
-  }
-}
-
 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`.
 abstract class Resolution {
   Parsing get parsing;
@@ -319,8 +186,21 @@
   DartType resolveTypeAnnotation(Element element, TypeAnnotation node);
 
   bool hasBeenResolved(Element element);
+
+  /// Returns the precomputed [WorldImpact] for [element].
   WorldImpact getWorldImpact(Element element);
+
+  /// Computes the [WorldImpact] for [element].
   WorldImpact computeWorldImpact(Element element);
+
+  /// Removes the [WorldImpact] for [element] from the resolution cache. Later
+  /// calls to [getWorldImpact] or [computeWorldImpact] returns an empty impact.
+  void uncacheWorldImpact(Element element);
+
+  /// Removes the [WorldImpact]s for all [Element]s in the resolution cache. ,
+  /// Later calls to [getWorldImpact] or [computeWorldImpact] returns an empty
+  /// impact.
+  void emptyCache();
 }
 
 // TODO(johnniwinther): Rename to `Parser` or `ParsingContext`.
@@ -328,4 +208,5 @@
   DiagnosticReporter get reporter;
   void parsePatchClass(ClassElement cls);
   measure(f());
+  ScannerOptions getScannerOptionsFor(Element element);
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/common/work.dart b/pkg/compiler/lib/src/common/work.dart
index 49f23c0..482d9e8 100644
--- a/pkg/compiler/lib/src/common/work.dart
+++ b/pkg/compiler/lib/src/common/work.dart
@@ -10,7 +10,8 @@
 import '../elements/elements.dart' show
     AstElement;
 import '../enqueue.dart' show
-    Enqueuer,
+    Enqueuer;
+import '../universe/world_impact.dart' show
     WorldImpact;
 
 
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 99672db..d633e6b 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -16,11 +16,12 @@
 import 'constants/evaluation.dart';
 import 'constants/expressions.dart';
 import 'constants/values.dart';
+import 'core_types.dart' show
+    CoreTypes;
 import 'dart_types.dart';
 import 'elements/elements.dart';
 import 'elements/modelx.dart' show
     FunctionElementX;
-import 'helpers/helpers.dart';
 import 'resolution/tree_elements.dart' show
     TreeElements;
 import 'resolution/operators.dart';
@@ -161,6 +162,8 @@
 
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreTypes get coreTypes => compiler.coreTypes;
+
   @override
   ConstantValue getConstantValueForVariable(VariableElement element) {
     return getConstantValue(initialVariableValues[element.declaration]);
@@ -256,7 +259,7 @@
             expression = null;
           }
         } else {
-          DartType constantType = value.getType(compiler.coreTypes);
+          DartType constantType = value.getType(coreTypes);
           if (!constantSystem.isSubtype(
               compiler.types, constantType, elementType)) {
             if (isConst) {
@@ -367,7 +370,7 @@
 
   ConstantSystem get constantSystem => handler.constantSystem;
   Resolution get resolution => compiler.resolution;
-
+  CoreTypes get coreTypes => compiler.coreTypes;
   DiagnosticReporter get reporter => compiler.reporter;
 
   AstConstant evaluate(Node node) {
@@ -505,7 +508,7 @@
       subexpressions.add(subexpression.expression);
       ConstantValue expression = subexpression.value;
       DartString expressionString;
-      if (expression.isNum || expression.isBool) {
+      if (expression.isNum || expression.isBool || expression.isNull) {
         PrimitiveConstantValue primitive = expression;
         expressionString =
             new DartString.literal(primitive.primitiveValue.toString());
@@ -532,7 +535,7 @@
   }
 
   AstConstant visitLiteralSymbol(LiteralSymbol node) {
-    InterfaceType type = compiler.symbolClass.rawType;
+    InterfaceType type = coreTypes.symbolType;
     String text = node.slowNameString;
     List<AstConstant> arguments = <AstConstant>[
       new AstConstant(context, node, new StringConstantExpression(text),
@@ -724,13 +727,13 @@
     if (condition == null) {
       return null;
     } else if (!condition.value.isBool) {
-      DartType conditionType = condition.value.getType(compiler.coreTypes);
+      DartType conditionType = condition.value.getType(coreTypes);
       if (isEvaluatingConstant) {
         reporter.reportErrorMessage(
             node.condition,
             MessageKind.NOT_ASSIGNABLE,
             {'fromType': conditionType,
-             'toType': compiler.boolClass.rawType});
+             'toType': coreTypes.boolType});
         return new ErroneousAstConstant(context, node);
       }
       return null;
@@ -823,19 +826,33 @@
     // The redirection chain of this element may not have been resolved through
     // a post-process action, so we have to make sure it is done here.
     compiler.resolver.resolveRedirectionChain(constructor, node);
-    InterfaceType constructedType =
-        constructor.computeEffectiveTargetType(type);
-    ConstructorElement target = constructor.effectiveTarget;
-    // The constructor must be an implementation to ensure that field
-    // initializers are handled correctly.
-    ConstructorElement implementation = target.implementation;
 
-    if (implementation.isErroneous) {
-      // TODO(johnniwinther): This should probably be an [ErroneousAstConstant].
-      return new AstConstant(context, node, new ConstructedConstantExpression(
-              type, constructor, callStructure, const <ConstantExpression>[]),
-          new ConstructedConstantValue(
-              constructedType, const <FieldElement, ConstantValue>{}));
+    bool isInvalid = false;
+    InterfaceType constructedType = type;
+    ConstructorElement implementation;
+    if (constructor.isRedirectingFactory) {
+      if (constructor.isEffectiveTargetMalformed) {
+        isInvalid = true;
+      } else {
+        constructedType =
+            constructor.computeEffectiveTargetType(type);
+        ConstructorElement target = constructor.effectiveTarget;
+        // The constructor must be an implementation to ensure that field
+        // initializers are handled correctly.
+        implementation = target.implementation;
+      }
+    } else {
+      // The constructor must be an implementation to ensure that field
+      // initializers are handled correctly.
+      implementation = constructor.implementation;
+      isInvalid = implementation.isMalformed;
+      if (implementation.isGenerativeConstructor &&
+          constructor.enclosingClass.isAbstract) {
+        isInvalid = true;
+      }
+    }
+    if (isInvalid) {
+      return signalNotCompileTimeConstant(node);
     }
 
     List<AstConstant> concreteArguments;
@@ -885,45 +902,45 @@
     }
 
     if (!firstArgument.isString) {
-      DartType type = defaultValue.getType(compiler.coreTypes);
+      DartType type = defaultValue.getType(coreTypes);
       reporter.reportErrorMessage(
           normalizedArguments[0].node,
           MessageKind.NOT_ASSIGNABLE,
           {'fromType': type,
-           'toType': compiler.stringClass.rawType});
+           'toType': coreTypes.stringType});
       return null;
     }
 
     if (constructor == compiler.intEnvironment &&
         !(defaultValue.isNull || defaultValue.isInt)) {
-      DartType type = defaultValue.getType(compiler.coreTypes);
+      DartType type = defaultValue.getType(coreTypes);
       reporter.reportErrorMessage(
           normalizedArguments[1].node,
           MessageKind.NOT_ASSIGNABLE,
           {'fromType': type,
-           'toType': compiler.intClass.rawType});
+           'toType': coreTypes.intType});
       return null;
     }
 
     if (constructor == compiler.boolEnvironment &&
         !(defaultValue.isNull || defaultValue.isBool)) {
-      DartType type = defaultValue.getType(compiler.coreTypes);
+      DartType type = defaultValue.getType(coreTypes);
       reporter.reportErrorMessage(
           normalizedArguments[1].node,
           MessageKind.NOT_ASSIGNABLE,
           {'fromType': type,
-           'toType': compiler.boolClass.rawType});
+           'toType': coreTypes.boolType});
       return null;
     }
 
     if (constructor == compiler.stringEnvironment &&
         !(defaultValue.isNull || defaultValue.isString)) {
-      DartType type = defaultValue.getType(compiler.coreTypes);
+      DartType type = defaultValue.getType(coreTypes);
       reporter.reportErrorMessage(
           normalizedArguments[1].node,
           MessageKind.NOT_ASSIGNABLE,
           {'fromType': type,
-           'toType': compiler.stringClass.rawType});
+           'toType': coreTypes.stringType});
       return null;
     }
 
@@ -1064,7 +1081,7 @@
   void potentiallyCheckType(TypedElement element, AstConstant constant) {
     if (compiler.enableTypeAssertions) {
       DartType elementType = element.type.substByContext(constructedType);
-      DartType constantType = constant.value.getType(compiler.coreTypes);
+      DartType constantType = constant.value.getType(coreTypes);
       if (!constantSystem.isSubtype(
           compiler.types, constantType, elementType)) {
         reporter.withCurrentElement(constant.element, () {
@@ -1089,7 +1106,7 @@
    * parameters (like [:this.x:]), also updates the [fieldValues] map.
    */
   void assignArgumentsToParameters(List<AstConstant> arguments) {
-    if (constructor.isErroneous) return;
+    if (constructor.isMalformed) return;
     // Assign arguments to parameters.
     FunctionSignature signature = constructor.functionSignature;
     int index = 0;
@@ -1148,10 +1165,16 @@
           // A super initializer or constructor redirection.
           Send call = link.head;
           FunctionElement target = elements[call];
-          List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
-              call, elements.getSelector(call).callStructure, call.arguments,
-              target, compileArgument: evaluateConstant);
-          evaluateSuperOrRedirectSend(compiledArguments, target);
+          if (!target.isMalformed) {
+            List<AstConstant> compiledArguments =
+                evaluateArgumentsToConstructor(
+                  call,
+                  elements.getSelector(call).callStructure,
+                  call.arguments,
+                  target,
+                  compileArgument: evaluateConstant);
+            evaluateSuperOrRedirectSend(compiledArguments, target);
+          }
           foundSuperOrRedirect = true;
         } else {
           // A field initializer.
@@ -1169,7 +1192,7 @@
       // the class is not Object.
       ClassElement enclosingClass = constructor.enclosingClass;
       ClassElement superClass = enclosingClass.superclass;
-      if (enclosingClass != compiler.objectClass) {
+      if (!enclosingClass.isObject) {
         assert(superClass != null);
         assert(superClass.isResolved);
 
@@ -1193,7 +1216,7 @@
    * native JavaScript constructor.
    */
   void evaluateConstructorFieldValues(List<AstConstant> arguments) {
-    if (constructor.isErroneous) return;
+    if (constructor.isMalformed) return;
     reporter.withCurrentElement(constructor, () {
       assignArgumentsToParameters(arguments);
       evaluateConstructorInitializers();
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 2f980bb..53be699 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -17,12 +17,13 @@
 import 'common/backend_api.dart' show
     Backend;
 import 'common/codegen.dart' show
-    CodegenRegistry,
+    CodegenImpact,
     CodegenWorkItem;
 import 'common/names.dart' show
     Identifiers,
     Uris;
 import 'common/registry.dart' show
+    EagerRegistry,
     Registry;
 import 'common/resolution.dart' show
     Parsing,
@@ -37,6 +38,7 @@
 import 'compile_time_constants.dart';
 import 'constants/values.dart';
 import 'core_types.dart' show
+    CoreClasses,
     CoreTypes;
 import 'dart_backend/dart_backend.dart' as dart_backend;
 import 'dart_types.dart' show
@@ -69,10 +71,11 @@
     Enqueuer,
     EnqueueTask,
     ResolutionEnqueuer,
-    QueueFilter,
-    WorldImpact;
+    QueueFilter;
 import 'io/source_information.dart' show
     SourceInformation;
+import 'js_backend/backend_helpers.dart' as js_backend show
+    BackendHelpers;
 import 'js_backend/js_backend.dart' as js_backend show
     JavaScriptBackend;
 import 'library_loader.dart' show
@@ -81,11 +84,15 @@
     LoadedLibraries;
 import 'mirrors_used.dart' show
     MirrorUsageAnalyzerTask;
+import 'common/names.dart' show
+    Selectors;
 import 'null_compiler_output.dart' show
     NullCompilerOutput,
     NullSink;
 import 'parser/diet_parser_task.dart' show
     DietParserTask;
+import 'parser/element_listener.dart' show
+    ScannerOptions;
 import 'parser/parser_task.dart' show
     ParserTask;
 import 'patch_parser.dart' show
@@ -127,6 +134,11 @@
     Selector;
 import 'universe/universe.dart' show
     Universe;
+import 'universe/use.dart' show
+    StaticUse;
+import 'universe/world_impact.dart' show
+    ImpactStrategy,
+    WorldImpact;
 import 'util/util.dart' show
     Link,
     Setlet;
@@ -146,6 +158,8 @@
 
   final CacheStrategy cacheStrategy;
 
+  ImpactStrategy impactStrategy = const ImpactStrategy();
+
   /**
    * Map from token to the first preceding comment token.
    */
@@ -278,25 +292,8 @@
   /// Initialized when dart:typed_data is loaded.
   LibraryElement typedDataLibrary;
 
-  ClassElement get objectClass => _coreTypes.objectClass;
-  ClassElement get boolClass => _coreTypes.boolClass;
-  ClassElement get numClass => _coreTypes.numClass;
-  ClassElement get intClass => _coreTypes.intClass;
-  ClassElement get doubleClass => _coreTypes.doubleClass;
-  ClassElement get resourceClass => _coreTypes.resourceClass;
-  ClassElement get stringClass => _coreTypes.stringClass;
-  ClassElement get functionClass => _coreTypes.functionClass;
-  ClassElement get nullClass => _coreTypes.nullClass;
-  ClassElement get listClass => _coreTypes.listClass;
-  ClassElement get typeClass => _coreTypes.typeClass;
-  ClassElement get mapClass => _coreTypes.mapClass;
-  ClassElement get symbolClass => _coreTypes.symbolClass;
-  ClassElement get stackTraceClass => _coreTypes.stackTraceClass;
-  ClassElement get futureClass => _coreTypes.futureClass;
-  ClassElement get iterableClass => _coreTypes.iterableClass;
-  ClassElement get streamClass => _coreTypes.streamClass;
-
   DiagnosticReporter get reporter => _reporter;
+  CoreClasses get coreClasses => _coreTypes;
   CoreTypes get coreTypes => _coreTypes;
   Resolution get resolution => _resolution;
   Parsing get parsing => _parsing;
@@ -329,6 +326,7 @@
   ClassElement symbolImplementationClass;
 
   // Initialized when symbolImplementationClass has been resolved.
+  // TODO(johnniwinther): Move this to [BackendHelpers].
   FunctionElement symbolValidatedConstructor;
 
   // Initialized when mirrorsUsedClass has been resolved.
@@ -456,6 +454,7 @@
             this.deferredMapUri: null,
             this.dumpInfo: false,
             bool useStartupEmitter: false,
+            bool enableConditionalDirectives: false,
             this.useContentSecurityPolicy: false,
             bool hasIncrementalSupport: false,
             this.enableExperimentalMirrors: false,
@@ -517,9 +516,12 @@
       libraryLoader = new LibraryLoaderTask(this),
       serialization = new SerializationTask(this),
       scanner = new ScannerTask(this),
-      dietParser = new DietParserTask(this),
-      parser = new ParserTask(this),
-      patchParser = new PatchParserTask(this),
+      dietParser = new DietParserTask(
+          this, enableConditionalDirectives: enableConditionalDirectives),
+      parser = new ParserTask(
+          this, enableConditionalDirectives: enableConditionalDirectives),
+      patchParser = new PatchParserTask(
+          this, enableConditionalDirectives: enableConditionalDirectives),
       resolver = new ResolverTask(this, backend.constantCompilerTask),
       closureToClassMapper = new closureMapping.ClosureTask(this),
       checker = new TypeCheckerTask(this),
@@ -554,10 +556,14 @@
     reporter.internalError(spannable, "$methodName not implemented.");
   }
 
+  // Compiles the dart script at [uri].
+  //
+  // The resulting future will complete with true if the compilation
+  // succeded.
   Future<bool> run(Uri uri) {
     totalCompileTime.start();
 
-    return new Future.sync(() => runCompiler(uri))
+    return new Future.sync(() => runInternal(uri))
         .catchError((error) => _reporter.onError(uri, error))
         .whenComplete(() {
       tracer.close();
@@ -611,7 +617,7 @@
       _coreTypes.streamClass = findRequiredElement(library, 'Stream');
     } else if (uri == Uris.dart__native_typed_data) {
       typedDataClass = findRequiredElement(library, 'NativeTypedData');
-    } else if (uri == js_backend.JavaScriptBackend.DART_JS_HELPER) {
+    } else if (uri == js_backend.BackendHelpers.DART_JS_HELPER) {
       patchAnnotationClass = findRequiredElement(library, '_Patch');
       nativeAnnotationClass = findRequiredElement(library, 'Native');
     }
@@ -697,7 +703,7 @@
       for (Uri uri in disallowedLibraryUris) {
         if (loadedLibraries.containsLibrary(uri)) {
           Set<String> importChains =
-              computeImportChainsFor(loadedLibraries, Uri.parse('dart:io'));
+              computeImportChainsFor(loadedLibraries, uri);
           reporter.reportInfo(NO_LOCATION_SPANNABLE,
              MessageKind.DISALLOWED_LIBRARY_IMPORT,
               {'uri': uri,
@@ -730,8 +736,9 @@
                  MessageTemplate.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)});
       }
 
-      functionClass.ensureResolved(resolution);
-      functionApplyMethod = functionClass.lookupLocalMember('apply');
+      coreClasses.functionClass.ensureResolved(resolution);
+      functionApplyMethod =
+          coreClasses.functionClass.lookupLocalMember('apply');
 
       if (preserveComments) {
         return libraryLoader.loadLibrary(Uris.dart_mirrors)
@@ -770,23 +777,20 @@
 
   void onClassResolved(ClassElement cls) {
     if (mirrorSystemClass == cls) {
-      mirrorSystemGetNameFunction =
-        cls.lookupLocalMember('getName');
-    } else if (symbolClass == cls) {
+      mirrorSystemGetNameFunction = cls.lookupLocalMember('getName');
+    } else if (coreClasses.symbolClass == cls) {
       symbolConstructor = cls.constructors.head;
     } else if (symbolImplementationClass == cls) {
-      symbolValidatedConstructor = symbolImplementationClass.lookupConstructor(
+      symbolValidatedConstructor = cls.lookupConstructor(
           symbolValidatedConstructorSelector.name);
     } else if (mirrorsUsedClass == cls) {
       mirrorsUsedConstructor = cls.constructors.head;
-    } else if (intClass == cls) {
-      intEnvironment = intClass.lookupConstructor(Identifiers.fromEnvironment);
-    } else if (stringClass == cls) {
-      stringEnvironment =
-          stringClass.lookupConstructor(Identifiers.fromEnvironment);
-    } else if (boolClass == cls) {
-      boolEnvironment =
-          boolClass.lookupConstructor(Identifiers.fromEnvironment);
+    } else if (coreClasses.intClass == cls) {
+      intEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment);
+    } else if (coreClasses.stringClass == cls) {
+      stringEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment);
+    } else if (coreClasses.boolClass == cls) {
+      boolEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment);
     }
   }
 
@@ -825,13 +829,15 @@
   Element _unnamedListConstructor;
   Element get unnamedListConstructor {
     if (_unnamedListConstructor != null) return _unnamedListConstructor;
-    return _unnamedListConstructor = listClass.lookupDefaultConstructor();
+    return _unnamedListConstructor =
+        coreClasses.listClass.lookupDefaultConstructor();
   }
 
   Element _filledListConstructor;
   Element get filledListConstructor {
     if (_filledListConstructor != null) return _filledListConstructor;
-    return _filledListConstructor = listClass.lookupConstructor("filled");
+    return _filledListConstructor =
+        coreClasses.listClass.lookupConstructor("filled");
   }
 
   /**
@@ -840,7 +846,7 @@
    */
   Uri resolvePatchUri(String dartLibraryPath);
 
-  Future runCompiler(Uri uri) {
+  Future runInternal(Uri uri) {
     // TODO(ahe): This prevents memory leaks when invoking the compiler
     // multiple times. Implement a better mechanism where we can store
     // such caches in the compiler and get access to them through a
@@ -848,6 +854,13 @@
     StringToken.canonicalizedSubstrings.clear();
     Selector.canonicalizedValues.clear();
 
+    // The selector objects held in static fields must remain canonical.
+    for (Selector selector in Selectors.ALL) {
+      Selector.canonicalizedValues
+        .putIfAbsent(selector.hashCode, () => <Selector>[])
+        .add(selector);
+    }
+
     assert(uri != null || analyzeOnly || hasIncrementalSupport);
     return new Future.sync(() {
       if (librariesToAnalyzeWhenRun != null) {
@@ -891,7 +904,7 @@
             Identifiers.main, mainApp);
       }
       mainFunction = backend.helperForMissingMain();
-    } else if (main.isErroneous && main.isSynthesized) {
+    } else if (main.isError && main.isSynthesized) {
       if (main is ErroneousElement) {
         errorElement = main;
       } else {
@@ -917,7 +930,7 @@
               parameter);
           mainFunction = backend.helperForMainArity();
           // Don't warn about main not being used:
-          enqueuer.resolution.registerStaticUse(main);
+          enqueuer.resolution.registerStaticUse(new StaticUse.foreignUse(main));
         });
       }
     }
@@ -937,7 +950,7 @@
     }
   }
 
-  /// Analyze all member of the library in [libraryUri].
+  /// Analyze all members of the library in [libraryUri].
   ///
   /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the
   /// library has a `part of` tag, assuming it is a part and not a library.
@@ -949,11 +962,10 @@
       {bool skipLibraryWithPartOfTag: true}) {
     assert(analyzeMain);
     reporter.log('Analyzing $libraryUri ($buildId)');
-    return libraryLoader.loadLibrary(libraryUri).then((LibraryElement library) {
-      var compilationUnit = library.compilationUnit;
-      if (skipLibraryWithPartOfTag && compilationUnit.partTag != null) {
-        return null;
-      }
+    return libraryLoader.loadLibrary(
+        libraryUri, skipFileWithPartOfTag: true).then(
+            (LibraryElement library) {
+      if (library == null) return null;
       fullyEnqueueLibrary(library, enqueuer.resolution);
       emptyQueue(enqueuer.resolution);
       enqueuer.resolution.logSummary(reporter.log);
@@ -972,6 +984,9 @@
     // something to the resolution queue.  So we cannot wait with
     // this until after the resolution queue is processed.
     deferredLoadTask.beforeResolution(this);
+    impactStrategy = backend.createImpactStrategy(
+        supportDeferredLoad: deferredLoadTask.isProgramSplit,
+        supportDumpInfo: dumpInfo);
 
     phase = PHASE_RESOLVING;
     if (analyzeAll) {
@@ -1106,7 +1121,7 @@
 
   void processQueue(Enqueuer world, Element main) {
     world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries);
-    if (main != null && !main.isErroneous) {
+    if (main != null && !main.isMalformed) {
       FunctionElement mainMethod = main;
       mainMethod.computeType(resolution);
       if (mainMethod.functionSignature.parameterCount != 0) {
@@ -1127,6 +1142,9 @@
     }
     emptyQueue(world);
     world.queueIsClosed = true;
+    // Notify the impact strategy impacts are no longer needed for this
+    // enqueuer.
+    impactStrategy.onImpactUsed(world.impactUse);
     backend.onQueueClosed();
     assert(compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods());
   }
@@ -1176,7 +1194,7 @@
            element.impliesType ||
            element.isField ||
            element.isFunction ||
-           element.isGenerativeConstructor ||
+           element.isConstructor ||
            element.isGetter ||
            element.isSetter,
            message: 'Unexpected element kind: ${element.kind}'));
@@ -1231,6 +1249,32 @@
     _reporter.onCrashInUserCode(message, exception, stackTrace);
   }
 
+  /// Messages for which compile-time errors are reported but compilation
+  /// continues regardless.
+  static const List<MessageKind> BENIGN_ERRORS = const <MessageKind>[
+      MessageKind.INVALID_METADATA,
+      MessageKind.INVALID_METADATA_GENERIC,
+  ];
+
+  bool markCompilationAsFailed(DiagnosticMessage message, api.Diagnostic kind) {
+    if (testMode) {
+      // When in test mode, i.e. on the build-bot, we always stop compilation.
+      return true;
+    }
+    if (reporter.options.fatalWarnings) {
+      return true;
+    }
+    return !BENIGN_ERRORS.contains(message.message.kind);
+  }
+
+  void fatalDiagnosticReported(DiagnosticMessage message,
+                               List<DiagnosticMessage> infos,
+                               api.Diagnostic kind) {
+    if (markCompilationAsFailed(message, kind)) {
+      compilationFailed = true;
+    }
+  }
+
   /**
    * Translates the [resolvedUri] into a readable URI.
    *
@@ -1301,7 +1345,7 @@
 
   void reportUnusedCode() {
     void checkLive(member) {
-      if (member.isErroneous) return;
+      if (member.isMalformed) return;
       if (member.isFunction) {
         if (!enqueuer.resolution.hasBeenProcessed(member)) {
           reporter.reportHintMessage(
@@ -1439,7 +1483,7 @@
   int hints = 0;
 }
 
-class _CompilerCoreTypes implements CoreTypes {
+class _CompilerCoreTypes implements CoreTypes, CoreClasses {
   final Resolution resolution;
 
   ClassElement objectClass;
@@ -1554,6 +1598,12 @@
   }
 
   @override
+  InterfaceType get stackTraceType {
+    stackTraceClass.ensureResolved(resolution);
+    return stackTraceClass.rawType;
+  }
+
+  @override
   InterfaceType iterableType([DartType elementType]) {
     iterableClass.ensureResolved(resolution);
     InterfaceType type = iterableClass.rawType;
@@ -1643,7 +1693,7 @@
   void reportDiagnosticInternal(DiagnosticMessage message,
                                 List<DiagnosticMessage> infos,
                                 api.Diagnostic kind) {
-    if (!options.showPackageWarnings &&
+    if (!options.showAllPackageWarnings &&
         message.spannable != NO_LOCATION_SPANNABLE) {
       switch (kind) {
       case api.Diagnostic.WARNING:
@@ -1651,6 +1701,10 @@
         Element element = elementFromSpannable(message.spannable);
         if (!compiler.inUserCode(element, assumeInUserCode: true)) {
           Uri uri = compiler.getCanonicalUri(element);
+          if (options.showPackageWarningsFor(uri)) {
+            reportDiagnostic(message, infos, kind);
+            return;
+          }
           SuppressionInfo info =
               suppressedWarnings.putIfAbsent(uri, () => new SuppressionInfo());
           if (kind == api.Diagnostic.WARNING) {
@@ -1677,6 +1731,12 @@
                         List<DiagnosticMessage> infos,
                         api.Diagnostic kind) {
     compiler.reportDiagnostic(message, infos, kind);
+    if (kind == api.Diagnostic.ERROR ||
+        kind == api.Diagnostic.CRASH ||
+        (options.fatalWarnings &&
+         kind == api.Diagnostic.WARNING)) {
+      compiler.fatalDiagnosticReported(message, infos, kind);
+    }
   }
 
   /**
@@ -1731,6 +1791,67 @@
     }
     if (uri == null && currentElement != null) {
       uri = currentElement.compilationUnit.script.resourceUri;
+      assert(invariant(currentElement, () {
+
+        /// Check that [begin] and [end] can be found between [from] and [to].
+        validateToken(Token from, Token to) {
+          if (from == null || to == null) return true;
+          bool foundBegin = false;
+          bool foundEnd = false;
+          Token token = from;
+          while (true) {
+            if (token == begin) {
+              foundBegin = true;
+            }
+            if (token == end) {
+              foundEnd = true;
+            }
+            if (foundBegin && foundEnd) {
+              return true;
+            }
+            if (token == to || token == token.next || token.next == null) {
+              break;
+            }
+            token = token.next;
+          }
+
+          // Create a good message for when the tokens were not found.
+          StringBuffer sb = new StringBuffer();
+          sb.write('Invalid current element: $currentElement. ');
+          sb.write('Looking for ');
+          sb.write('[${begin} (${begin.hashCode}),');
+          sb.write('${end} (${end.hashCode})] in');
+
+          token = from;
+          while (true) {
+            sb.write('\n ${token} (${token.hashCode})');
+            if (token == to || token == token.next || token.next == null) {
+              break;
+            }
+            token = token.next;
+          }
+          return sb.toString();
+        }
+
+        if (currentElement.enclosingClass != null &&
+            currentElement.enclosingClass.isEnumClass) {
+          // Enums ASTs are synthesized (and give messed up messages).
+          return true;
+        }
+
+        if (currentElement is AstElement) {
+          AstElement astElement = currentElement;
+          if (astElement.hasNode) {
+            Token from = astElement.node.getBeginToken();
+            Token to = astElement.node.getEndToken();
+            if (astElement.metadata.isNotEmpty) {
+              from = astElement.metadata.first.beginToken;
+            }
+            return validateToken(from, to);
+          }
+        }
+        return true;
+      }, message: "Invalid current element: $currentElement [$begin,$end]."));
     }
     return new SourceSpan.fromTokens(uri, begin, end);
   }
@@ -1905,7 +2026,7 @@
   }
 
   void reportSuppressedMessagesSummary() {
-    if (!options.showPackageWarnings && !options.suppressWarnings) {
+    if (!options.showAllPackageWarnings && !options.suppressWarnings) {
       suppressedWarnings.forEach((Uri uri, SuppressionInfo info) {
         MessageKind kind = MessageKind.HIDDEN_WARNINGS_HINTS;
         if (info.warnings == 0) {
@@ -1997,13 +2118,27 @@
         compiler.checker.check(element);
       }
       WorldImpact worldImpact =
-          compiler.backend.resolutionCallbacks.transformImpact(
+          compiler.backend.impactTransformer.transformResolutionImpact(
               resolutionImpact);
       return worldImpact;
     });
   }
 
   @override
+  void uncacheWorldImpact(Element element) {
+    assert(invariant(element, _worldImpactCache[element] != null,
+        message: "WorldImpact not computed for $element."));
+    _worldImpactCache[element] = const WorldImpact();
+  }
+
+  @override
+  void emptyCache() {
+    for (Element element in _worldImpactCache.keys) {
+      _worldImpactCache[element] = const WorldImpact();
+    }
+  }
+
+  @override
   bool hasBeenResolved(Element element) {
     return _worldImpactCache.containsKey(element);
   }
@@ -2030,13 +2165,23 @@
       }
     });
   }
+
+  ScannerOptions getScannerOptionsFor(Element element) {
+    return new ScannerOptions(
+      canUseNative: compiler.backend.canLibraryUseNative(element.library));
+  }
 }
 
-class GlobalDependencyRegistry extends CodegenRegistry {
+class GlobalDependencyRegistry extends EagerRegistry {
+  final Compiler compiler;
   Setlet<Element> _otherDependencies;
 
-  GlobalDependencyRegistry(Compiler compiler)
-      : super(compiler, new TreeElementMapping(null));
+  GlobalDependencyRegistry(this.compiler) : super('GlobalDependencies', null);
+
+  // TODO(johnniwinther): Rename world/universe/enqueuer through out the
+  // compiler.
+  @override
+  Enqueuer get world => compiler.enqueuer.codegen;
 
   void registerDependency(Element element) {
     if (element == null) return;
@@ -2049,4 +2194,4 @@
   Iterable<Element> get otherDependencies {
     return _otherDependencies != null ? _otherDependencies : const <Element>[];
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/constant_system_dart.dart b/pkg/compiler/lib/src/constant_system_dart.dart
index 4a15ac9..c2c819e 100644
--- a/pkg/compiler/lib/src/constant_system_dart.dart
+++ b/pkg/compiler/lib/src/constant_system_dart.dart
@@ -332,6 +332,16 @@
   apply(left, right) => identical(left, right);
 }
 
+class IfNullOperation implements BinaryOperation {
+  final String name = '??';
+  const IfNullOperation();
+  ConstantValue fold(ConstantValue left, ConstantValue right) {
+    if (left.isNull) return right;
+    return left;
+  }
+  apply(left, right) => left ?? right;
+}
+
 abstract class CodeUnitAtOperation implements BinaryOperation {
   final String name = 'charCodeAt';
   const CodeUnitAtOperation();
@@ -382,6 +392,7 @@
   final greaterEqual = const GreaterEqualOperation();
   final greater = const GreaterOperation();
   final identity = const IdentityOperation();
+  final ifNull = const IfNullOperation();
   final lessEqual = const LessEqualOperation();
   final less = const LessOperation();
   final modulo = const ModuloOperation();
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index d99d795..06c9fad 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -43,6 +43,7 @@
   BinaryOperation get greaterEqual;
   BinaryOperation get greater;
   BinaryOperation get identity;
+  BinaryOperation get ifNull;
   BinaryOperation get lessEqual;
   BinaryOperation get less;
   BinaryOperation get modulo;
@@ -118,6 +119,7 @@
       case BinaryOperatorKind.GT:   return greater;
       case BinaryOperatorKind.GTEQ:  return greaterEqual;
       case BinaryOperatorKind.EQ:  return equal;
+      case BinaryOperatorKind.IF_NULL: return ifNull;
       default:    return null;
     }
   }
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index f1ad90b..02f7b1a 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -804,6 +804,7 @@
     BinaryOperatorKind.GTEQ: 7,
     BinaryOperatorKind.LTEQ: 7,
     BinaryOperatorKind.MOD: 13,
+    BinaryOperatorKind.IF_NULL: 3,
   };
 }
 
@@ -1605,4 +1606,4 @@
   }
 
   String toString() => sb.toString();
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 24b6370..945aaba 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -375,6 +375,9 @@
       : this.primitiveValue = value,
         this.hashCode = value.slowToString().hashCode;
 
+  StringConstantValue.fromString(String value)
+      : this(new DartString.literal(value));
+
   bool get isString => true;
 
   DartType getType(CoreTypes types) => types.stringType;
@@ -499,6 +502,7 @@
   final List<ConstantValue> keys;
   final List<ConstantValue> values;
   final int hashCode;
+  Map<ConstantValue, ConstantValue> _lookupMap;
 
   MapConstantValue(InterfaceType type,
                    List<ConstantValue> keys,
@@ -536,6 +540,12 @@
 
   int get length => keys.length;
 
+  ConstantValue lookup(ConstantValue key) {
+    var lookupMap = _lookupMap ??=
+        new Map<ConstantValue, ConstantValue>.fromIterables(keys, values);
+    return lookupMap[key];
+  }
+
   accept(ConstantValueVisitor visitor, arg) => visitor.visitMap(this, arg);
 
   String unparse() {
@@ -748,4 +758,4 @@
 
   @override
   String unparse() => '>>non-constant<<';
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/core_types.dart b/pkg/compiler/lib/src/core_types.dart
index 1b71c2e..ff30de2 100644
--- a/pkg/compiler/lib/src/core_types.dart
+++ b/pkg/compiler/lib/src/core_types.dart
@@ -7,6 +7,60 @@
 import 'dart_types.dart';
 import 'elements/elements.dart' show ClassElement;
 
+/// The core classes in Dart.
+abstract class CoreClasses {
+  /// The `Object` class defined in 'dart:core'.
+  ClassElement get objectClass;
+
+  /// The `bool` class defined in 'dart:core'.
+  ClassElement get boolClass;
+
+  /// The `num` class defined in 'dart:core'.
+  ClassElement get numClass;
+
+  /// The `int` class defined in 'dart:core'.
+  ClassElement get intClass;
+
+  /// The `double` class defined in 'dart:core'.
+  ClassElement get doubleClass;
+
+  /// The `Resource` class defined in 'dart:core'.
+  ClassElement get resourceClass;
+
+  /// The `String` class defined in 'dart:core'.
+  ClassElement get stringClass;
+
+  /// The `Symbol` class defined in 'dart:core'.
+  ClassElement get symbolClass;
+
+  /// The `Function` class defined in 'dart:core'.
+  ClassElement get functionClass;
+
+  /// The `Null` class defined in 'dart:core'.
+  ClassElement get nullClass;
+
+  /// The `Type` class defined in 'dart:core'.
+  ClassElement get typeClass;
+
+  /// The `StackTrace` class defined in 'dart:core';
+  ClassElement get stackTraceClass;
+
+  /// The `List` class defined in 'dart:core';
+  ClassElement get listClass;
+
+  /// The `Map` class defined in 'dart:core';
+  ClassElement get mapClass;
+
+  /// The `Iterable` class defined in 'dart:core';
+  ClassElement get iterableClass;
+
+  /// The `Future` class defined in 'async';
+  ClassElement get futureClass;
+
+  /// The `Stream` class defined in 'async';
+  ClassElement get streamClass;
+}
+
 /// The core types in Dart.
 abstract class CoreTypes {
   /// The `Object` type defined in 'dart:core'.
@@ -42,6 +96,9 @@
   /// The `Type` type defined in 'dart:core'.
   InterfaceType get typeType;
 
+  /// The `StackTrace` type defined in 'dart:core';
+  InterfaceType get stackTraceType;
+
   /// Returns an instance of the `List` type defined in 'dart:core' with
   /// [elementType] as its type argument.
   ///
diff --git a/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart b/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
new file mode 100644
index 0000000..422aaa3
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
@@ -0,0 +1,129 @@
+library dart2js.cps_ir.backward_null_check_remover;
+
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart';
+import '../common/names.dart';
+import '../universe/selector.dart';
+import 'type_mask_system.dart';
+import 'cps_fragment.dart';
+
+/// Removes null checks that are follwed by another instruction that will
+/// perform the same check.
+///
+/// For example:
+///
+///     x.toString; // NullCheck instruction
+///     print(x.length);
+///
+/// ==>
+///
+///     print(x.length);
+///
+/// `x.length` will throw when x is null, so the original [NullCheck] is not
+/// needed.  This changes the error message, but at least for now we are
+/// willing to accept this.
+///
+/// Note that code motion may not occur after this pass, since the [NullCheck]
+/// nodes are not there to restrict it.
+//
+// TODO(asgerf): It would be nice with a clear specification of when we allow
+//   the wording of error message to change.  E.g. "toString" is already pretty
+//   bad so changing that should be ok, but changing a field access is not as
+//   clear.
+//
+class BackwardNullCheckRemover extends BlockVisitor implements Pass {
+  String get passName => 'Backward null-check remover';
+
+  final TypeMaskSystem typeSystem;
+
+  /// When the analysis of an expression completes, [nullCheckValue] refers to
+  /// a value that is checked in the beginning of that expression.
+  Primitive nullCheckedValue;
+
+  /// The [nullCheckedValue] at the entry point of a continuation.
+  final Map<Continuation, Primitive> nullCheckedValueAt =
+      <Continuation, Primitive>{};
+
+  BackwardNullCheckRemover(this.typeSystem);
+
+  void rewrite(FunctionDefinition node) {
+    BlockVisitor.traverseInPostOrder(node, this);
+  }
+
+  /// Returns a reference to an operand of [prim], where [prim] throws if null
+  /// is passed into that operand.
+  Reference<Primitive> getNullCheckedOperand(Primitive prim) {
+    if (prim is NullCheck) return prim.value;
+    if (prim is GetLength) return prim.object;
+    if (prim is GetField) return prim.object;
+    if (prim is GetIndex) return prim.object;
+    if (prim is SetField) return prim.object;
+    if (prim is SetIndex) return prim.object;
+    if (prim is InvokeMethod && !selectorsOnNull.contains(prim.selector)) {
+      return prim.dartReceiverReference;
+    }
+    if (prim is ForeignCode) {
+      return prim.isNullGuardOnNullFirstArgument() ? prim.arguments[0] : null;
+    }
+    return null;
+  }
+
+  /// It has been determined that the null check in [prim] made redundant by
+  /// [newNullCheck].  Eliminate [prim] if it is not needed any more.
+  void tryEliminateRedundantNullCheck(Primitive prim, Primitive newNullCheck) {
+    if (prim is NullCheck) {
+      Primitive value = prim.value.definition;
+      LetPrim let = prim.parent;
+      prim..replaceUsesWith(value)..destroy();
+      let.remove();
+    } else if (prim is GetLength || prim is GetField || prim is GetIndex) {
+      if (prim.hasNoEffectiveUses) {
+        destroyRefinementsOfDeadPrimitive(prim);
+        LetPrim let = prim.parent;
+        prim..destroy();
+        let.remove();
+      }
+    }
+  }
+
+  /// True if [prim] can be moved above a null check.  This is safe if [prim]
+  /// cannot throw or have side effects and does not carry any path-sensitive
+  /// type information, such as [Refinement] nodes do.
+  //
+  // TODO(asgerf): This prevents elimination of the .length created for a bounds
+  //   check, because there is a refinement node below it.  To handle this, we
+  //   would have to relocate the [Refinement] node below the new null check.
+  bool canMoveAboveNullCheck(Primitive prim) {
+    return prim.isSafeForReordering;
+  }
+
+  void visitLetPrim(LetPrim node) {
+    Primitive prim = node.primitive;
+    Primitive receiver = getNullCheckedOperand(prim)?.definition;
+    if (receiver != null) {
+      if (nullCheckedValue != null && receiver.sameValue(nullCheckedValue)) {
+        tryEliminateRedundantNullCheck(prim, nullCheckedValue);
+      }
+      nullCheckedValue = receiver;
+    } else if (!canMoveAboveNullCheck(prim)) {
+      nullCheckedValue = null;
+    }
+  }
+
+  void visitContinuation(Continuation cont) {
+    if (nullCheckedValue != null) {
+      nullCheckedValueAt[cont] = nullCheckedValue;
+      nullCheckedValue = null;
+    }
+  }
+
+  void visitLetHandler(LetHandler node) {
+    nullCheckedValue = null;
+  }
+
+  visitInvokeContinuation(InvokeContinuation node) {
+    if (!node.isRecursive) {
+      nullCheckedValue = nullCheckedValueAt[node.continuation.definition];
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
index 1467745..44cbbb0 100644
--- a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
+++ b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
@@ -10,8 +10,10 @@
 import '../constants/values.dart';
 import 'cps_fragment.dart';
 import 'type_mask_system.dart';
+import '../types/types.dart';
 import '../world.dart';
 import '../elements/elements.dart';
+import 'loop_effects.dart';
 
 /// Eliminates bounds checks when they can be proven safe.
 ///
@@ -30,7 +32,6 @@
 ///
 /// Loops are analyzed in two passes. The first pass establishes monotonicity
 /// of loop variables, which the second pass uses to compute upper/lower bounds.
-/// The first pass also records whether any side effects occurred in the loop.
 ///
 /// The two-pass scheme is suboptimal compared to a least fixed-point
 /// computation, but does not require repeated iteration.  Repeated iteration
@@ -56,7 +57,6 @@
   final Map<Primitive, Map<int, SignedVariable>> lengthOf = {};
 
   /// Fields for the two-pass handling of loops.
-  final Set<Continuation> loopsWithSideEffects = new Set<Continuation>();
   final Map<Parameter, Monotonicity> monotonicity = <Parameter, Monotonicity>{};
   bool isStrongLoopPass;
   bool foundLoop = false;
@@ -65,6 +65,7 @@
   ///
   /// The IR is divided into regions wherein the lengths of indexable objects
   /// are known not to change. Regions are identified by their "effect number".
+  LoopSideEffects loopEffects;
   final Map<Continuation, int> effectNumberAt = <Continuation, int>{};
   int currentEffectNumber = 0;
   int effectNumberCounter = 0;
@@ -72,6 +73,7 @@
   BoundsChecker(this.types, this.world);
 
   void rewrite(FunctionDefinition node) {
+    loopEffects = new LoopSideEffects(node, world);
     isStrongLoopPass = false;
     visit(node);
     if (foundLoop) {
@@ -111,17 +113,24 @@
   }
 
   /// Get a constraint variable representing the length of [indexableObject] at
-  /// program locations with the given [effectCounter].
-  SignedVariable getLength(Primitive indexableObject, int effectCounter) {
+  /// program locations with the given [effectNumber].
+  SignedVariable getLength(Primitive indexableObject, int effectNumber) {
     indexableObject = indexableObject.effectiveDefinition;
-    if (indexableObject.type != null &&
-        types.isDefinitelyFixedLengthIndexable(indexableObject.type)) {
-      // Always use the same effect counter if the length is immutable.
-      effectCounter = 0;
+    TypeMask type = indexableObject.type.nonNullable();
+    if (types.isDefinitelyFixedLengthIndexable(type)) {
+      // Always use the same effect number if the length is immutable.
+      effectNumber = 0;
     }
     return lengthOf
         .putIfAbsent(indexableObject, () => <int, SignedVariable>{})
-        .putIfAbsent(effectCounter, () => octagon.makeVariable(0, MAX_UINT32));
+        .putIfAbsent(effectNumber, () {
+            int length = types.getContainerLength(type);
+            if (length != null) {
+              return octagon.makeVariable(length, length);
+            } else {
+              return octagon.makeVariable(0, MAX_UINT32);
+            }
+        });
   }
 
   // ------------- CONSTRAINT HELPERS -----------------
@@ -165,6 +174,16 @@
     applyConstraint(v2, v1.negated, -1);
   }
 
+  void makeLessThanOrEqualToConstant(SignedVariable v1, int k) {
+    // v1 + v1 <= 2k
+    applyConstraint(v1, v1, 2 * k);
+  }
+
+  void makeGreaterThanOrEqualToConstant(SignedVariable v1, int k) {
+    // -v1 - v1 <= -2k
+    applyConstraint(v1.negated, v1.negated, -2 * k);
+  }
+
   void makeConstant(SignedVariable v1, int k) {
     // We model this using the constraints:
     //    v1 + v1 <=  2k
@@ -225,6 +244,11 @@
     return testConstraint(v1, v2.negated, 0);
   }
 
+  /// Return true if we can prove that `v1 < v2`.
+  bool isDefinitelyLessThan(SignedVariable v1, SignedVariable v2) {
+    return testConstraint(v1, v2.negated, -1);
+  }
+
   /// Return true if we can prove that `v1 >= v2`.
   bool isDefinitelyGreaterThanOrEqualTo(SignedVariable v1, SignedVariable v2) {
     return testConstraint(v2, v1.negated, 0);
@@ -326,56 +350,138 @@
 
   @override
   void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    if (node.operator != BuiltinOperator.NumAdd &&
-        node.operator != BuiltinOperator.NumSubtract) {
-      return;
+    if (!isInt(node)) return;
+    if (node.arguments.length == 1) {
+      applyUnaryOperator(node);
+    } else if (node.arguments.length == 2) {
+      applyBinaryOperator(node);
     }
-    if (!isInt(node.arguments[0].definition) ||
-        !isInt(node.arguments[1].definition)) {
-      return;
-    }
-    if (!isInt(node)) {
-      // TODO(asgerf): The result of this operation should always be an integer,
-      // but currently type propagation does not always prove this.
-      return;
-    }
-    // We have `v1 = v2 +/- v3`, but the octagon cannot represent constraints
-    // involving more than two variables. Check if one operand is a constant.
-    int getConstantArgument(int n) {
-      Primitive prim = node.arguments[n].definition;
-      if (prim is Constant && prim.value.isInt) {
-        IntConstantValue constant = prim.value;
-        return constant.primitiveValue;
-      }
-      return null;
-    }
-    int constant = getConstantArgument(0);
-    int operandIndex = 1;
-    if (constant == null) {
-      constant = getConstantArgument(1);
-      operandIndex = 0;
-    }
-    if (constant == null) {
-      // Neither argument was a constant.
-      // Classical octagon-based analyzers would compute upper and lower bounds
-      // for the two operands and add constraints for the result based on
-      // those.  For performance reasons we omit that.
-      // TODO(asgerf): It seems expensive, but we should evaluate it.
-      return;
-    }
-    SignedVariable v1 = getValue(node);
-    SignedVariable v2 = getValue(node.arguments[operandIndex].definition);
+  }
 
-    if (node.operator == BuiltinOperator.NumAdd) {
-      // v1 = v2 + const
-      makeFloatingPointSum(v1, v2, constant);
-    } else if (operandIndex == 0) {
-      // v1 = v2 - const
-      makeFloatingPointSum(v1, v2, -constant);
-    } else {
-      // v1 = const - v2   <==>   v1 = (-v2) + const
-      makeFloatingPointSum(v1, v2.negated, constant);
+  void applyBinaryOperator(ApplyBuiltinOperator node) {
+    Primitive left = node.arguments[0].definition;
+    Primitive right = node.arguments[1].definition;
+    if (!isInt(left) || !isInt(right)) {
+      return;
     }
+    SignedVariable leftVar = getValue(left);
+    SignedVariable rightVar = getValue(right);
+    SignedVariable result = getValue(node);
+    switch (node.operator) {
+      case BuiltinOperator.NumAdd:
+        int leftConst = getIntConstant(left);
+        if (leftConst != null) {
+          makeFloatingPointSum(result, rightVar, leftConst);
+        }
+        int rightConst = getIntConstant(right);
+        if (rightConst != null) {
+          makeFloatingPointSum(result, leftVar, rightConst);
+        }
+        // Attempt to compute the sign of the result.
+        // TODO(asgerf): Compute upper/lower bounds instead of using 0.
+        if (testConstraint(leftVar, rightVar, 0)) {
+          makeLessThanOrEqualToConstant(result, 0);
+        }
+        if (testConstraint(leftVar.negated, rightVar.negated, 0)) {
+          makeGreaterThanOrEqualToConstant(result, 0);
+        }
+        // Classical octagon-based analyzers would compute upper and lower
+        // bounds for the two operands and add constraints for the result based
+        // on those.  For performance reasons we only compute the sign
+        // TODO(asgerf): It seems expensive, but we should evaluate it.
+        break;
+
+      case BuiltinOperator.NumSubtract:
+        int leftConst = getIntConstant(left);
+        if (leftConst != null) {
+          // result = leftConst - right = (-right) + leftConst
+          makeFloatingPointSum(result, rightVar.negated, leftConst);
+        }
+        int rightConst = getIntConstant(right);
+        if (rightConst != null) {
+          // result = left - rightConst = left + (-rightConst)
+          makeFloatingPointSum(result, leftVar, -rightConst);
+        }
+        // Attempt to compute the sign of the result.
+        if (isDefinitelyGreaterThanOrEqualTo(leftVar, rightVar)) {
+          makeGreaterThanOrEqualToConstant(result, 0);
+        }
+        if (isDefinitelyLessThanOrEqualTo(leftVar, rightVar)) {
+          makeLessThanOrEqualToConstant(result, 0);
+        }
+        break;
+
+      case BuiltinOperator.NumTruncatingDivideToSigned32:
+        if (isDefinitelyGreaterThanOrEqualToConstant(leftVar, 0)) {
+          // If we divide by a positive number, the result is closer to zero.
+          // If we divide by a negative number, the result is negative, and
+          // thus less than the original (non-negative) number.
+          // TODO(asgerf): The divisor is currently always positive, because
+          // type propagation checks that, but we could do better.
+          makeLessThanOrEqual(result, leftVar);
+        }
+        break;
+
+      case BuiltinOperator.NumShr:
+        if (isDefinitelyGreaterThanOrEqualToConstant(leftVar, 0)) {
+          makeLessThanOrEqual(result, leftVar);
+        }
+        int shiftAmount = getIntConstant(right);
+        if (shiftAmount != null) {
+          // TODO(asgerf): Compute upper bound on [leftVar] and use that
+          // instead of MAX_UINT32.
+          makeLessThanOrEqualToConstant(result, MAX_UINT32 >> shiftAmount);
+        }
+        break;
+
+      case BuiltinOperator.NumRemainder:
+        // TODO(asgerf): This check overlaps with checks performed in a type
+        //   propagation transformation, and we can do it more precisely here.
+        //   Should we do the rewrite here?
+        if (isDefinitelyGreaterThanOrEqualToConstant(leftVar, 0) &&
+            isDefinitelyGreaterThanOrEqualToConstant(rightVar, 1)) {
+          makeLessThanOrEqual(result, leftVar);
+          makeLessThan(result, rightVar);
+        }
+        break;
+
+      case BuiltinOperator.NumAnd:
+        // We use the faster UInt32 check instead of constraint based checks
+        // here, because the common case is that one operand is a constant.
+        if (isUInt32(left)) {
+          makeLessThanOrEqual(result, leftVar);
+        }
+        if (isUInt32(right)) {
+          makeLessThanOrEqual(result, rightVar);
+        }
+        break;
+
+      default:
+    }
+  }
+
+  void applyUnaryOperator(ApplyBuiltinOperator node) {
+    Primitive argument = node.arguments[0].definition;
+    if (!isInt(argument)) return;
+    if (node.operator == BuiltinOperator.NumNegate) {
+      valueOf[node] = getValue(argument).negated;
+    }
+  }
+
+  int getIntConstant(Primitive prim) {
+    if (prim is Constant && prim.value.isInt) {
+      IntConstantValue constant = prim.value;
+      return constant.primitiveValue;
+    }
+    return null;
+  }
+
+  @override
+  void visitRefinement(Refinement node) {
+    // In general we should get the container length of the refined type and
+    // add a constraint if we know the length after the refinement.
+    // However, our current type system removes container information when a
+    // type becomes part of a union, so this cannot happen.
   }
 
   @override
@@ -383,6 +489,45 @@
     valueOf[node] = getLength(node.object.definition, currentEffectNumber);
   }
 
+  @override
+  void visitBoundsCheck(BoundsCheck node) {
+    if (node.checks == BoundsCheck.NONE) return;
+    assert(node.index != null); // Because there is at least one check.
+    SignedVariable length = node.length == null
+        ? null
+        : getValue(node.length.definition);
+    SignedVariable index = getValue(node.index.definition);
+    if (node.hasUpperBoundCheck) {
+      if (isDefinitelyLessThan(index, length)) {
+        node.checks &= ~BoundsCheck.UPPER_BOUND;
+      } else {
+        makeLessThan(index, length);
+      }
+    }
+    if (node.hasLowerBoundCheck) {
+      if (isDefinitelyGreaterThanOrEqualToConstant(index, 0)) {
+        node.checks &= ~BoundsCheck.LOWER_BOUND;
+      } else {
+        makeGreaterThanOrEqualToConstant(index, 0);
+      }
+    }
+    if (node.hasEmptinessCheck) {
+      if (isDefinitelyGreaterThanOrEqualToConstant(length, 1)) {
+        node.checks &= ~BoundsCheck.EMPTINESS;
+      } else {
+        makeGreaterThanOrEqualToConstant(length, 1);
+      }
+    }
+    if (!node.lengthUsedInCheck && node.length != null) {
+      node..length.unlink()..length = null;
+    }
+    if (node.checks == BoundsCheck.NONE) {
+      // We can't remove the bounds check node because it may still be used to
+      // restrict code motion.  But the index is no longer needed.
+      node..index.unlink()..index = null;
+    }
+  }
+
   void analyzeLoopEntry(InvokeContinuation node) {
     foundLoop = true;
     Continuation cont = node.continuation.definition;
@@ -395,19 +540,15 @@
         Monotonicity mono = monotonicity[param];
         if (mono == null) {
           // Value never changes. This is extremely uncommon.
-          initialValue.substituteFor(param);
+          param.replaceUsesWith(initialValue);
         } else if (mono == Monotonicity.Increasing) {
           makeGreaterThanOrEqual(getValue(param), initialVariable);
         } else if (mono == Monotonicity.Decreasing) {
           makeLessThanOrEqual(getValue(param), initialVariable);
         }
       }
-      if (loopsWithSideEffects.contains(cont)) {
-        currentEffectNumber = makeNewEffect();
-      }
-    } else {
-      // During the weak pass, conservatively make a new effect number in the
-      // loop body. This may be strengthened during the strong pass.
+    }
+    if (loopEffects.loopChangesLength(cont)) {
       currentEffectNumber = effectNumberAt[cont] = makeNewEffect();
     }
     push(cont);
@@ -440,12 +581,6 @@
         markMonotonicity(cont.parameters[i], Monotonicity.Decreasing);
       }
     }
-
-    // If a side effect has occurred between the entry and continue, mark
-    // the loop as having side effects.
-    if (currentEffectNumber != effectNumberAt[cont]) {
-      loopsWithSideEffects.add(cont);
-    }
   }
 
   void markMonotonicity(Parameter param, Monotonicity mono) {
@@ -475,7 +610,7 @@
     }
   }
 
-  // ---------------- CALL EXPRESSIONS --------------------
+  // ---------------- PRIMITIVES --------------------
 
   @override
   void visitInvokeMethod(InvokeMethod node) {
@@ -485,7 +620,6 @@
         .changesIndex()) {
       currentEffectNumber = makeNewEffect();
     }
-    push(node.continuation.definition);
   }
 
   @override
@@ -493,7 +627,6 @@
     if (world.getSideEffectsOfElement(node.target).changesIndex()) {
       currentEffectNumber = makeNewEffect();
     }
-    push(node.continuation.definition);
   }
 
   @override
@@ -506,7 +639,6 @@
     if (world.getSideEffectsOfElement(target).changesIndex()) {
       currentEffectNumber = makeNewEffect();
     }
-    push(node.continuation.definition);
   }
 
   @override
@@ -514,19 +646,16 @@
     if (world.getSideEffectsOfElement(node.target).changesIndex()) {
       currentEffectNumber = makeNewEffect();
     }
-    push(node.continuation.definition);
   }
 
   @override
   void visitTypeCast(TypeCast node) {
-    push(node.continuation.definition);
   }
 
   @override
   void visitGetLazyStatic(GetLazyStatic node) {
     // TODO(asgerf): How do we get the side effects of a lazy field initializer?
     currentEffectNumber = makeNewEffect();
-    push(node.continuation.definition);
   }
 
   @override
@@ -534,23 +663,18 @@
     if (node.nativeBehavior.sideEffects.changesIndex()) {
       currentEffectNumber = makeNewEffect();
     }
-    push(node.continuation.definition);
   }
 
   @override
   void visitAwait(Await node) {
     currentEffectNumber = makeNewEffect();
-    push(node.continuation.definition);
   }
 
   @override
   void visitYield(Yield node) {
     currentEffectNumber = makeNewEffect();
-    push(node.continuation.definition);
   }
 
-  // ---------------- PRIMITIVES --------------------
-
   @override
   void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
     Primitive receiver = node.receiver.definition;
diff --git a/pkg/compiler/lib/src/cps_ir/builtin_operator.dart b/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
index 31f815a..2db4ac5 100644
--- a/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
+++ b/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
@@ -55,6 +55,14 @@
   /// This case can be compiled to  `(a / b) | 0`.
   NumTruncatingDivideToSigned32,
 
+  /// Corresponds to JavaScript's negation, which converts 0 to -0.0.
+  NumNegate,
+
+  /// Bit inversions, with coercion to uint32.
+  ///
+  /// Compiles to `(~x) >>> 0`.
+  NumBitNot,
+
   /// Concatenates any number of strings.
   ///
   /// Takes any number of arguments, and each argument must be a string.
@@ -62,6 +70,12 @@
   /// Returns the empty string if no arguments are given.
   StringConcatenate,
 
+  /// Corresponds to `a.charCodeAt(b)`. `a' must be a String. The index `b` must
+  /// be in range `0 <= b < a.length`.
+  /// TODO(sra): Consider replacing with a Primitive to allow lowering when 'a'
+  /// is nullable (i.e. throws).
+  CharCodeAt,
+
   /// Returns true if the two arguments are the same value, and that value is
   /// not NaN, or if one argument is +0 and the other is -0.
   ///
@@ -144,26 +158,41 @@
 
 /// A method supported natively in the CPS and Tree IRs using the
 /// `ApplyBuiltinMethod` instructions.
-/// 
+///
 /// These methods all operate on a distinguished 'object' argument, and
 /// take zero or more additional arguments.
-/// 
+///
 /// These methods may mutate and depend on the state of the object argument,
 /// but may not depend on or mutate any other state. An exception is thrown
 /// if the object is null, but otherwise they cannot throw or diverge.
 enum BuiltinMethod {
   /// Add an item to a native list.
-  /// 
+  ///
   /// Takes any number of arguments, each argument will be added to the
   /// list on the order given (as per the JS `push` method).
-  /// 
+  ///
   /// Compiles to `object.push(x1, ..., xN)`.
   Push,
 
   /// Remove and return the last item from a native list.
-  /// 
+  ///
   /// Takes no arguments.
-  /// 
+  ///
   /// Compiles to `object.pop()`.
   Pop,
 }
+
+/// True for the built-in operators that may be used in a compound assignment.
+bool isCompoundableOperator(BuiltinOperator operator) {
+  switch(operator) {
+    case BuiltinOperator.NumAdd:
+    case BuiltinOperator.NumSubtract:
+    case BuiltinOperator.NumMultiply:
+    case BuiltinOperator.NumDivide:
+    case BuiltinOperator.NumRemainder:
+    case BuiltinOperator.StringConcatenate:
+      return true;
+    default:
+      return false;
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart b/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
index 7fc2ae3..7e62fa5 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
@@ -104,6 +104,7 @@
 
   Primitive makeZero() => makeConstant(new IntConstantValue(0));
   Primitive makeOne() => makeConstant(new IntConstantValue(1));
+  Primitive makeMinusOne() => makeConstant(new IntConstantValue(-1));
   Primitive makeNull() => makeConstant(new NullConstantValue());
   Primitive makeTrue() => makeConstant(new TrueConstantValue());
   Primitive makeFalse() => makeConstant(new FalseConstantValue());
@@ -113,6 +114,10 @@
     return letPrim(new ApplyBuiltinOperator(op, args, sourceInformation));
   }
 
+  Primitive refine(Primitive value, TypeMask type) {
+    return letPrim(new Refinement(value, type));
+  }
+
   Primitive invokeBuiltin(BuiltinMethod method,
                           Primitive receiver,
                           List<Primitive> arguments,
@@ -123,35 +128,23 @@
     return letPrim(apply);
   }
 
-  /// Inserts an invocation. binds its continuation, and returns the
-  /// continuation parameter (i.e. the return value of the invocation).
-  ///
-  /// The continuation body becomes the new hole.
-  Parameter invokeMethod(Primitive receiver,
-                         Selector selector,
-                         TypeMask mask,
-                         List<Primitive> arguments) {
-    Continuation cont = new Continuation(<Parameter>[new Parameter(null)]);
+  /// Inserts an invocation and returns a primitive holding the returned value.
+  Primitive invokeMethod(Primitive receiver,
+      Selector selector,
+      TypeMask mask,
+      List<Primitive> arguments,
+      [CallingConvention callingConvention = CallingConvention.Normal]) {
     InvokeMethod invoke =
-      new InvokeMethod(receiver, selector, mask, arguments, cont,
-                       sourceInformation);
-    put(new LetCont(cont, invoke));
-    context = cont;
-    return cont.parameters.single;
+        new InvokeMethod(receiver, selector, mask, arguments,
+                         sourceInformation: sourceInformation,
+                         callingConvention: callingConvention);
+    return letPrim(invoke);
   }
 
-  /// Inserts an invocation. binds its continuation, and returns the
-  /// continuation parameter (i.e. the return value of the invocation).
-  ///
-  /// The continuation body becomes the new hole.
-  Parameter invokeStatic(FunctionElement target, List<Primitive> arguments) {
-    Continuation cont = new Continuation(<Parameter>[new Parameter(null)]);
-    InvokeStatic invoke =
-      new InvokeStatic(target, new Selector.fromElement(target), arguments,
-                       cont, sourceInformation);
-    put(new LetCont(cont, invoke));
-    context = cont;
-    return cont.parameters.single;
+  /// Inserts an invocation and returns a primitive holding the returned value.
+  Primitive invokeStatic(FunctionElement target, List<Primitive> arguments) {
+    return letPrim(new InvokeStatic(target, new Selector.fromElement(target),
+        arguments, sourceInformation));
   }
 
   /// Inserts an invocation to a static function that throws an error.
@@ -196,31 +189,39 @@
 
   /// Branch on [condition].
   ///
-  /// Returns a new fragment for the 'then' branch.
+  /// Returns a new fragment for the 'then' branch, or the 'else' branch
+  /// if [negate] is true.
   ///
-  /// The 'else' branch becomes the new hole.
-  CpsFragment ifTruthy(Primitive condition) {
+  /// The other branch becomes the new hole.
+  CpsFragment branch(Primitive condition,
+                     {bool negate: false,
+                      bool strict: false}) {
     Continuation trueCont = new Continuation(<Parameter>[]);
     Continuation falseCont = new Continuation(<Parameter>[]);
     put(new LetCont.two(trueCont, falseCont,
-            new Branch.loose(condition, trueCont, falseCont)));
-    context = falseCont;
-    return new CpsFragment(sourceInformation, trueCont);
+            new Branch(condition, trueCont, falseCont, strict: strict)));
+    if (negate) {
+      context = trueCont;
+      return new CpsFragment(sourceInformation, falseCont);
+    } else {
+      context = falseCont;
+      return new CpsFragment(sourceInformation, trueCont);
+    }
   }
 
   /// Branch on [condition].
   ///
+  /// Returns a new fragment for the 'then' branch.
+  ///
+  /// The 'else' branch becomes the new hole.
+  CpsFragment ifTruthy(Primitive condition) => branch(condition);
+
+  /// Branch on [condition].
+  ///
   /// Returns a new fragment for the 'else' branch.
   ///
   /// The 'then' branch becomes the new hole.
-  CpsFragment ifFalsy(Primitive condition) {
-    Continuation trueCont = new Continuation(<Parameter>[]);
-    Continuation falseCont = new Continuation(<Parameter>[]);
-    put(new LetCont.two(trueCont, falseCont,
-            new Branch.loose(condition, trueCont, falseCont)));
-    context = trueCont;
-    return new CpsFragment(sourceInformation, falseCont);
-  }
+  CpsFragment ifFalsy(Primitive condition) => branch(condition, negate: true);
 
   /// Create a new empty continuation and bind it here.
   ///
@@ -253,10 +254,45 @@
   Continuation letCont([List<Parameter> parameters]) {
     if (parameters == null) parameters = <Parameter>[];
     Continuation cont = new Continuation(parameters);
+    bindContinuation(cont);
+    return cont;
+  }
+
+  /// Binds an existing continuation at this position.
+  ///
+  /// The LetCont body becomes the new hole.
+  void bindContinuation(Continuation cont) {
     LetCont let = new LetCont(cont, null);
     put(let);
     context = let;
-    return cont;
+  }
+
+  /// Inlines [target] at the current position, substituting the provided
+  /// arguments.
+  ///
+  /// Returns a primitive containing the function's return value.
+  ///
+  /// The new hole is the the point after [target] has returned. The fragment
+  /// remains open, even if [target] never returns.
+  ///
+  /// The [target] function is destroyed and should not be reused.
+  Primitive inlineFunction(FunctionDefinition target,
+                           Primitive thisArgument,
+                           List<Primitive> arguments,
+                           {Entity hint}) {
+    if (thisArgument != null) {
+      target.thisParameter.replaceUsesWith(thisArgument);
+    }
+    for (int i = 0; i < arguments.length; ++i) {
+      target.parameters[i].replaceUsesWith(arguments[i]);
+    }
+    Continuation returnCont = target.returnContinuation;
+    bindContinuation(returnCont);
+    put(target.body);
+    Parameter returnValue = returnCont.parameters.single;
+    returnValue.hint = hint;
+    context = returnCont;
+    return returnValue;
   }
 
   /// Returns a fragment whose context is the body of the given continuation.
@@ -322,3 +358,17 @@
   parent.body = newNode;
   newNode.parent = parent;
 }
+
+/// Removes all [Refinement] uses of a given primitive that has no effective
+/// uses.
+void destroyRefinementsOfDeadPrimitive(Primitive prim) {
+  while (prim.firstRef != null) {
+    Refinement refine = prim.firstRef.parent;
+    destroyRefinementsOfDeadPrimitive(refine);
+    LetPrim letPrim = refine.parent;
+    InteriorNode parent = letPrim.parent;
+    parent.body = letPrim.body;
+    letPrim.body.parent = parent;
+    prim.firstRef.unlink();
+  }
+}
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 3f69cd0..0a80f33 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -4,7 +4,7 @@
 
 library dart2js.ir_builder;
 
-import '../closure.dart' hide ClosureScope;
+import '../closure.dart' as closure;
 import '../common.dart';
 import '../common/names.dart' show
     Names,
@@ -34,7 +34,6 @@
     SelectorKind;
 
 import 'cps_ir_builder_task.dart' show
-    DartCapturedVariables,
     GlobalProgramInformation;
 import 'cps_ir_nodes.dart' as ir;
 
@@ -160,6 +159,13 @@
     if (hasExtraArgument) _continuationEnvironment.extend(null, null);
   }
 
+  /// Construct a collector for collecting only return jumps.
+  ///
+  /// There is no jump target, it is implicitly the exit from the function.
+  /// There is no environment at the destination.
+  JumpCollector.retrn(this._continuation)
+      : _continuationEnvironment = null, target = null;
+
   /// True if the collector has not recorded any jumps to its continuation.
   bool get isEmpty;
 
@@ -176,7 +182,8 @@
   /// values to finally blocks for returns inside try/finally and to pass
   /// values of expressions that have internal control flow to their join-point
   /// continuations.
-  void addJump(IrBuilder builder, [ir.Primitive value]);
+  void addJump(IrBuilder builder,
+      [ir.Primitive value, SourceInformation sourceInformation]);
 
   /// Add a set of variables that were boxed on entry to a try block.
   ///
@@ -202,7 +209,7 @@
     for (Iterable<LocalVariableElement> boxedOnEntry in _boxedTryVariables) {
       for (LocalVariableElement variable in boxedOnEntry) {
         assert(builder.isInMutableVariable(variable));
-        ir.Primitive value = builder.buildLocalVariableGet(variable);
+        ir.Primitive value = builder.buildLocalGet(variable);
         builder.environment.update(variable, value);
       }
     }
@@ -260,7 +267,8 @@
     return _continuationEnvironment;
   }
 
-  void addJump(IrBuilder builder, [ir.Primitive value]) {
+  void addJump(IrBuilder builder,
+      [ir.Primitive value, SourceInformation sourceInformation]) {
     assert(_continuation == null);
     _buildTryExit(builder);
     ir.InvokeContinuation invoke = new ir.InvokeContinuation.uninitialized(
@@ -369,7 +377,8 @@
   ir.Continuation get continuation => _continuation;
   Environment get environment => _continuationEnvironment;
 
-  void addJump(IrBuilder builder, [ir.Primitive value]) {
+  void addJump(IrBuilder builder,
+      [ir.Primitive value, SourceInformation sourceInformation]) {
     assert(_continuation.parameters.length <= builder.environment.length);
     isEmpty = false;
     _buildTryExit(builder);
@@ -389,6 +398,29 @@
   }
 }
 
+/// Collect 'return' jumps.
+///
+/// A return jump is one that targets the return continuation of a function.
+/// Thus, returns from inside try/finally are not return jumps because they are
+/// intercepted by a block that contains the finally handler code.
+class ReturnJumpCollector extends JumpCollector {
+  bool isEmpty = true;
+  ir.Continuation get continuation => _continuation;
+  Environment environment = null;
+
+  /// Construct a return jump collector for a given return continuation.
+  ReturnJumpCollector(ir.Continuation continuation) : super.retrn(continuation);
+
+  void addJump(IrBuilder builder,
+      [ir.Primitive value, SourceInformation sourceInformation]) {
+    isEmpty = false;
+    builder.add(new ir.InvokeContinuation(continuation, <ir.Primitive>[value],
+        isEscapingTry: isEscapingTry,
+        sourceInformation: sourceInformation));
+    builder._current = null;
+  }
+}
+
 /// Function for building a node in the context of the current builder.
 typedef ir.Node BuildFunction(node);
 
@@ -467,7 +499,7 @@
   /// A null value indicates that the target is the function's return
   /// continuation.  Otherwise, when inside the try block of try/finally
   /// a return is intercepted to give a place to generate the finally code.
-  JumpCollector returnCollector = null;
+  JumpCollector returnCollector;
 
   /// Parameter holding the internal value of 'this' passed to the function.
   ///
@@ -484,7 +516,9 @@
   /// the environment.
   final Map<Local, ClosureLocation> boxedVariables = {};
 
-  IrBuilderSharedState(this.program, this.constants, this.currentElement);
+  IrBuilderSharedState(this.program, this.constants, this.currentElement) {
+    returnCollector = new ReturnJumpCollector(returnContinuation);
+  }
 }
 
 class ThisParameterLocal implements Local {
@@ -619,24 +653,15 @@
     return primitive;
   }
 
-  ir.Primitive _continueWithExpression(ir.Expression build(ir.Continuation k)) {
-    ir.Parameter v = new ir.Parameter(null);
-    ir.Continuation k = new ir.Continuation([v]);
-    ir.Expression expression = build(k);
-    add(new ir.LetCont(k, expression));
-    return v;
-  }
-
-  ir.Primitive _buildInvokeStatic(Element element,
-                                  Selector selector,
-                                  List<ir.Primitive> arguments,
-                                  SourceInformation sourceInformation) {
+  ir.Primitive buildInvokeStatic(Element element,
+                                 Selector selector,
+                                 List<ir.Primitive> arguments,
+                                 SourceInformation sourceInformation) {
     assert(!element.isLocal);
     assert(!element.isInstanceMember);
     assert(isOpen);
-    return _continueWithExpression(
-        (k) => new ir.InvokeStatic(element, selector, arguments, k,
-                                   sourceInformation));
+    return addPrimitive(
+        new ir.InvokeStatic(element, selector, arguments, sourceInformation));
   }
 
   ir.Primitive _buildInvokeSuper(Element target,
@@ -645,9 +670,8 @@
                                  SourceInformation sourceInformation) {
     assert(target.isInstanceMember);
     assert(isOpen);
-    return _continueWithExpression(
-        (k) => new ir.InvokeMethodDirectly(
-            buildThis(), target, selector, arguments, k, sourceInformation));
+    return addPrimitive(new ir.InvokeMethodDirectly(
+        buildThis(), target, selector, arguments, sourceInformation));
   }
 
   ir.Primitive _buildInvokeDynamic(ir.Primitive receiver,
@@ -656,9 +680,9 @@
                                    List<ir.Primitive> arguments,
                                    SourceInformation sourceInformation) {
     assert(isOpen);
-    return _continueWithExpression(
-        (k) => new ir.InvokeMethod(receiver, selector, mask, arguments, k,
-                                   sourceInformation));
+    return addPrimitive(new ir.InvokeMethod(
+        receiver, selector, mask, arguments,
+        sourceInformation: sourceInformation));
   }
 
   ir.Primitive _buildInvokeCall(ir.Primitive target,
@@ -671,6 +695,16 @@
         target, selector, mask, arguments, sourceInformation);
   }
 
+  ir.Primitive buildStaticNoSuchMethod(Selector selector,
+                                       List<ir.Primitive> arguments) {
+    ir.Primitive receiver = buildStringConstant('');
+    ir.Primitive name = buildStringConstant(selector.name);
+    ir.Primitive argumentList = buildListLiteral(null, arguments);
+    ir.Primitive expectedArgumentNames = buildNullConstant();
+    return buildStaticFunctionInvocation(
+        program.throwNoSuchMethod,
+        <ir.Primitive>[receiver, name, argumentList, expectedArgumentNames]);
+  }
 
   /// Create a [ir.Constant] from [value] and add it to the CPS term.
   ir.Constant buildConstant(ConstantValue value,
@@ -714,27 +748,11 @@
   /// Creates a non-constant list literal of the provided [type] and with the
   /// provided [values].
   ir.Primitive buildListLiteral(InterfaceType type,
-                                Iterable<ir.Primitive> values) {
+                                Iterable<ir.Primitive> values,
+                                {TypeMask allocationSiteType}) {
     assert(isOpen);
-    return addPrimitive(new ir.LiteralList(type, values.toList()));
-  }
-
-  /// Creates a non-constant map literal of the provided [type] and with the
-  /// entries build from the [keys] and [values] using [build].
-  ir.Primitive buildMapLiteral(InterfaceType type,
-                               Iterable keys,
-                               Iterable values,
-                               BuildFunction build) {
-    assert(isOpen);
-    List<ir.LiteralMapEntry> entries = <ir.LiteralMapEntry>[];
-    Iterator key = keys.iterator;
-    Iterator value = values.iterator;
-    while (key.moveNext() && value.moveNext()) {
-      entries.add(new ir.LiteralMapEntry(
-          build(key.current), build(value.current)));
-    }
-    assert(!key.moveNext() && !value.moveNext());
-    return addPrimitive(new ir.LiteralMap(type, entries));
+    return addPrimitive(new ir.LiteralList(type, values.toList(),
+        allocationSiteType: allocationSiteType));
   }
 
   /// Creates a conditional expression with the provided [condition] where the
@@ -947,32 +965,6 @@
     return value;
   }
 
-  /// Create a read access of the [local] variable or parameter.
-  ir.Primitive buildLocalVariableGet(LocalElement local) {
-    // TODO(johnniwinther): Separate function access from variable access.
-    return _buildLocalGet(local);
-  }
-
-  /// Create a read access of the local [function], i.e. closurization of
-  /// [function].
-  ir.Primitive buildLocalFunctionGet(LocalFunctionElement function) {
-    // TODO(johnniwinther): Separate function access from variable access.
-    return _buildLocalGet(function);
-  }
-
-  /// Create an invocation of the the [local] variable or parameter where
-  /// argument structure is defined by [callStructure] and the argument values
-  /// are defined by [arguments].
-  ir.Primitive buildLocalVariableInvocation(
-      LocalVariableElement local,
-      CallStructure callStructure,
-      List<ir.Primitive> arguments,
-      {SourceInformation callSourceInformation}) {
-    return buildCallInvocation(
-        buildLocalVariableGet(local), callStructure, arguments,
-        sourceInformation: callSourceInformation);
-  }
-
   /// Create an invocation of the local [function] where argument structure is
   /// defined by [callStructure] and the argument values are defined by
   /// [arguments].
@@ -983,53 +975,30 @@
       SourceInformation sourceInformation) {
     // TODO(johnniwinther): Maybe this should have its own ir node.
     return buildCallInvocation(
-        buildLocalFunctionGet(function), callStructure, arguments,
+        buildLocalGet(function), callStructure, arguments,
         sourceInformation: sourceInformation);
   }
 
-  /// Create a static invocation of [function] where argument structure is
-  /// defined by [callStructure] and the argument values are defined by
-  /// [arguments].
+  /// Create a static invocation of [function].
+  ///
+  /// The arguments are not named and their values are defined by [arguments].
   ir.Primitive buildStaticFunctionInvocation(
       MethodElement function,
-      CallStructure callStructure,
       List<ir.Primitive> arguments,
       {SourceInformation sourceInformation}) {
-    Selector selector =
-        new Selector(SelectorKind.CALL, function.memberName, callStructure);
-    return _buildInvokeStatic(
-        function, selector, arguments, sourceInformation);
-  }
-
-  /// Create a read access of the static [field].
-  ir.Primitive buildStaticFieldGet(FieldElement field,
-                                   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));
+    Selector selector = new Selector.call(
+        function.memberName, new CallStructure(arguments.length));
+    return buildInvokeStatic(function, selector, arguments, sourceInformation);
   }
 
   /// Create a getter invocation of the static [getter].
   ir.Primitive buildStaticGetterGet(MethodElement getter,
                                     SourceInformation sourceInformation) {
     Selector selector = new Selector.getter(getter.memberName);
-    return _buildInvokeStatic(
+    return buildInvokeStatic(
         getter, selector, const <ir.Primitive>[], sourceInformation);
   }
 
-  /// Create a read access of the static [function], i.e. a closurization of
-  /// [function].
-  ir.Primitive buildStaticFunctionGet(MethodElement function,
-                                      {SourceInformation sourceInformation}) {
-    return addPrimitive(new ir.GetStatic(function, sourceInformation));
-  }
-
   /// Create a write access to the static [field] with the [value].
   ir.Primitive buildStaticFieldSet(FieldElement field,
                                    ir.Primitive value,
@@ -1043,7 +1012,7 @@
                                     ir.Primitive value,
                                     {SourceInformation sourceInformation}) {
     Selector selector = new Selector.setter(setter.memberName);
-    _buildInvokeStatic(
+    buildInvokeStatic(
         setter, selector, <ir.Primitive>[value], sourceInformation);
     return value;
   }
@@ -1056,13 +1025,10 @@
       Selector selector,
       List<ir.Primitive> arguments) {
     // TODO(johnniwinther): This should have its own ir node.
-    return _buildInvokeStatic(element, selector, arguments, null);
+    return buildInvokeStatic(element, selector, arguments, null);
   }
 
-  /// Concatenate string values.
-  ///
-  /// The arguments must be strings; usually a call to [buildStringify] is
-  /// needed to ensure the proper conversion takes places.
+  /// Concatenate string values.  The arguments must be strings.
   ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments,
                                         {SourceInformation sourceInformation}) {
     assert(isOpen);
@@ -1161,8 +1127,9 @@
     }
   }
 
-  void jumpTo(JumpCollector collector, [ir.Primitive value]) {
-    collector.addJump(this, value);
+  void jumpTo(JumpCollector collector,
+      [ir.Primitive value, SourceInformation sourceInformation]) {
+    collector.addJump(this, value, sourceInformation);
   }
 
   void addRecursiveContinuation(BackwardJumpCollector collector) {
@@ -1356,14 +1323,11 @@
     // in expressionReceiver.iterator () iteratorInvoked
     ir.Primitive expressionReceiver = buildExpression(this);
     List<ir.Primitive> emptyArguments = <ir.Primitive>[];
-    ir.Parameter iterator = new ir.Parameter(null);
-    ir.Continuation iteratorInvoked = new ir.Continuation([iterator]);
-    add(new ir.LetCont(iteratorInvoked,
+    ir.Primitive iterator = addPrimitive(
         new ir.InvokeMethod(expressionReceiver,
             Selectors.iterator,
             iteratorMask,
-            emptyArguments,
-            iteratorInvoked)));
+            emptyArguments));
 
     // Fill with:
     // let cont loop(x, ...) =
@@ -1373,14 +1337,11 @@
     // in loop(v, ...)
     JumpCollector loop = new BackwardJumpCollector(environment, target: target);
     addRecursiveContinuation(loop);
-    ir.Parameter condition = new ir.Parameter(null);
-    ir.Continuation moveNextInvoked = new ir.Continuation([condition]);
-    add(new ir.LetCont(moveNextInvoked,
+    ir.Primitive condition = addPrimitive(
         new ir.InvokeMethod(iterator,
             Selectors.moveNext,
             moveNextMask,
-            emptyArguments,
-            moveNextInvoked)));
+            emptyArguments));
 
     // As a delimited term, build:
     // <<BODY>> =
@@ -1395,27 +1356,31 @@
     if (buildVariableDeclaration != null) {
       buildVariableDeclaration(bodyBuilder);
     }
-    ir.Parameter currentValue = new ir.Parameter(null);
-    ir.Continuation currentInvoked = new ir.Continuation([currentValue]);
-    bodyBuilder.add(new ir.LetCont(currentInvoked,
+    ir.Primitive currentValue = bodyBuilder.addPrimitive(
         new ir.InvokeMethod(
             iterator,
             Selectors.current,
             currentMask,
-            emptyArguments, currentInvoked)));
-    // TODO(sra): Does this cover all cases? The general setter case include
-    // super.
+            emptyArguments));
     // TODO(johnniwinther): Extract this as a provided strategy.
     if (Elements.isLocal(variableElement)) {
       bodyBuilder.buildLocalVariableSet(variableElement, currentValue);
-    } else if (Elements.isErroneous(variableElement)) {
-      bodyBuilder.buildErroneousInvocation(variableElement,
-          new Selector.setter(
-              new Name(variableElement.name, variableElement.library)),
-          <ir.Primitive>[currentValue]);
+    } else if (Elements.isError(variableElement) ||
+               Elements.isMalformed(variableElement)) {
+      Selector selector = new Selector.setter(
+          new Name(variableElement.name, variableElement.library));
+      List<ir.Primitive> value = <ir.Primitive>[currentValue];
+      // Note the order of the comparisons below.  It can be the case that an
+      // element isError and isMalformed.
+      if (Elements.isError(variableElement)) {
+        bodyBuilder.buildStaticNoSuchMethod(selector, value);
+      } else {
+        bodyBuilder.buildErroneousInvocation(variableElement, selector, value);
+      }
     } else if (Elements.isStaticOrTopLevel(variableElement)) {
       if (variableElement.isField) {
-        bodyBuilder.buildStaticFieldSet(variableElement, currentValue);
+        bodyBuilder.addPrimitive(
+            new ir.SetStatic(variableElement, currentValue));
       } else {
         bodyBuilder.buildStaticSetterSet(variableElement, currentValue);
       }
@@ -1661,7 +1626,7 @@
         if (caseInfo == cases.last && defaultCase == null) {
           thenBuilder.jumpTo(join);
         } else {
-          ir.Primitive exception = thenBuilder._buildInvokeStatic(
+          ir.Primitive exception = thenBuilder.buildInvokeStatic(
               error,
               new Selector.fromElement(error),
               <ir.Primitive>[],
@@ -1729,7 +1694,7 @@
         new Map<Local, ir.MutableVariable>.from(mutableVariables);
     for (LocalVariableElement variable in variables.boxedOnEntry) {
       assert(!tryCatchBuilder.isInMutableVariable(variable));
-      ir.Primitive value = tryCatchBuilder.buildLocalVariableGet(variable);
+      ir.Primitive value = tryCatchBuilder.buildLocalGet(variable);
       tryCatchBuilder.makeMutableVariable(variable);
       tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
     }
@@ -1747,7 +1712,7 @@
     IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder();
     for (LocalVariableElement variable in variables.boxedOnEntry) {
       assert(catchBuilder.isInMutableVariable(variable));
-      ir.Primitive value = catchBuilder.buildLocalVariableGet(variable);
+      ir.Primitive value = catchBuilder.buildLocalGet(variable);
       // After this point, the variables that were boxed on entry to the try
       // are no longer treated as mutable.
       catchBuilder.removeMutableVariable(variable);
@@ -1812,6 +1777,7 @@
       }
       builder.state.breakCollectors.forEach(interceptJump);
       builder.state.continueCollectors.forEach(interceptJump);
+      interceptJump(builder.state.returnCollector);
     }
 
     void leaveTry(IrBuilder builder) {
@@ -1822,6 +1788,7 @@
       }
       builder.state.breakCollectors.forEach(restoreJump);
       builder.state.continueCollectors.forEach(restoreJump);
+      restoreJump(builder.state.returnCollector);
     }
 
     List<ir.Parameter> buildCatch(IrBuilder builder,
@@ -2030,26 +1997,7 @@
     if (value == null) {
       value = buildNullConstant();
     }
-    if (state.returnCollector == null) {
-      add(new ir.InvokeContinuation(state.returnContinuation, [value],
-              sourceInformation: sourceInformation));
-      _current = null;
-    } else {
-      // Inside the try block of try/finally, all returns go to a join-point
-      // continuation that contains the finally code.  The return value is
-      // passed as an extra argument.
-      jumpTo(state.returnCollector, value);
-    }
-  }
-
-  /// Build a call to the closure conversion helper for the [Function] typed
-  /// value in [value].
-  ir.Primitive _convertDartClosure(ir.Primitive value, FunctionType type) {
-    ir.Constant arity = buildIntegerConstant(type.computeArity());
-    return buildStaticFunctionInvocation(
-        program.closureConverter,
-        CallStructure.TWO_ARGS,
-        <ir.Primitive>[value, arity]);
+    jumpTo(state.returnCollector, value, sourceInformation);
   }
 
   /// Generate the body for a native function [function] that is annotated with
@@ -2073,8 +2021,8 @@
   /// `fixedBackendName`, passing all parameters as arguments.  The target can
   /// be the JavaScript implementation of a function, getter, or setter.
   void buildRedirectingNativeFunctionBody(FunctionElement function,
+                                          String name,
                                           SourceInformation source) {
-    String name = function.fixedBackendName;
     List<ir.Primitive> arguments = <ir.Primitive>[];
     NativeBehavior behavior = new NativeBehavior();
     behavior.sideEffects.setAllSideEffects();
@@ -2093,7 +2041,9 @@
       if (type is FunctionType) {
         // The parameter type is a function type either directly or through
         // typedef(s).
-        input = _convertDartClosure(input, type);
+        ir.Constant arity = buildIntegerConstant(type.computeArity());
+        input = buildStaticFunctionInvocation(
+            program.closureConverter, <ir.Primitive>[input, arity]);
       }
       arguments.add(input);
       argumentTemplates.add('#');
@@ -2436,24 +2386,24 @@
 
   /// Add [functionElement] to the environment with provided [definition].
   void declareLocalFunction(LocalFunctionElement functionElement,
-                            ClosureClassElement classElement,
+                            closure.ClosureClassElement classElement,
                             SourceInformation sourceInformation) {
     ir.Primitive closure =
          buildFunctionExpression(classElement, sourceInformation);
     declareLocalVariable(functionElement, initialValue: closure);
   }
 
-  ir.Primitive buildFunctionExpression(ClosureClassElement classElement,
+  ir.Primitive buildFunctionExpression(closure.ClosureClassElement classElement,
                                        SourceInformation sourceInformation) {
     List<ir.Primitive> arguments = <ir.Primitive>[];
-    for (ClosureFieldElement field in classElement.closureFields) {
+    for (closure.ClosureFieldElement field in classElement.closureFields) {
       // Captured 'this' and type variables are not always available as locals
       // in the environment, so treat those specially.
       ir.Primitive value;
-      if (field.local is ThisLocal) {
+      if (field.local is closure.ThisLocal) {
         value = buildThis();
-      } else if (field.local is TypeVariableLocal) {
-        TypeVariableLocal variable = field.local;
+      } else if (field.local is closure.TypeVariableLocal) {
+        closure.TypeVariableLocal variable = field.local;
         value = buildTypeVariableAccess(variable.typeVariable);
       } else {
         value = environment.lookup(field.local);
@@ -2464,8 +2414,8 @@
         classElement, arguments, const <ir.Primitive>[], sourceInformation));
   }
 
-  /// Create a read access of [local] variable or parameter.
-  ir.Primitive _buildLocalGet(LocalElement local) {
+  /// Create a read access of [local] function, variable, or parameter.
+  ir.Primitive buildLocalGet(LocalElement local) {
     assert(isOpen);
     ClosureLocation location = state.boxedVariables[local];
     if (location != null) {
@@ -2570,18 +2520,6 @@
     return value;
   }
 
-  ir.Primitive buildInvokeDirectly(MethodElement target,
-                                   ir.Primitive receiver,
-                                   List<ir.Primitive> arguments,
-                                   {SourceInformation sourceInformation}) {
-    assert(isOpen);
-    Selector selector =
-        new Selector.call(target.memberName, new CallStructure(arguments.length));
-    return _continueWithExpression(
-        (k) => new ir.InvokeMethodDirectly(
-            receiver, target, selector, arguments, k, sourceInformation));
-  }
-
   /// Loads parameters to a constructor body into the environment.
   ///
   /// The header for a constructor body differs from other functions in that
@@ -2607,7 +2545,8 @@
       CallStructure callStructure,
       DartType type,
       List<ir.Primitive> arguments,
-      SourceInformation sourceInformation) {
+      SourceInformation sourceInformation,
+      {TypeMask allocationSiteType}) {
     assert(isOpen);
     Selector selector =
         new Selector(SelectorKind.CALL, element.memberName, callStructure);
@@ -2623,9 +2562,9 @@
       arguments = new List<ir.Primitive>.from(arguments)
           ..addAll(typeArguments);
     }
-    return _continueWithExpression(
-        (k) => new ir.InvokeConstructor(
-            type, element, selector, arguments, k, sourceInformation));
+    return addPrimitive(new ir.InvokeConstructor(
+        type, element, selector, arguments, sourceInformation,
+        allocationSiteType: allocationSiteType));
   }
 
   ir.Primitive buildTypeExpression(DartType type) {
@@ -2658,7 +2597,7 @@
     // If the local exists in the environment, use that.
     // This is put here when we are inside a constructor or field initializer,
     // (or possibly a closure inside one of these).
-    Local local = new TypeVariableLocal(variable, state.currentElement);
+    Local local = new closure.TypeVariableLocal(variable, state.currentElement);
     if (environment.contains(local)) {
       return environment.lookup(local);
     }
@@ -2674,7 +2613,7 @@
   /// with the value of [binding].
   void declareTypeVariable(TypeVariableType variable, DartType binding) {
     environment.extend(
-        new TypeVariableLocal(variable, state.currentElement),
+        new closure.TypeVariableLocal(variable, state.currentElement),
         buildTypeExpression(binding));
   }
 
@@ -2698,12 +2637,11 @@
                                 {Element dependency}) {
     assert(behavior != null);
     TypeMask type = program.getTypeMaskForForeign(behavior);
-    ir.Primitive result = _continueWithExpression((k) => new ir.ForeignCode(
+    ir.Primitive result = addPrimitive(new ir.ForeignCode(
         codeTemplate,
         type,
         arguments,
         behavior,
-        k,
         dependency: dependency));
     if (!codeTemplate.isExpression) {
       // Close the term if this is a "throw" expression or native body.
@@ -2723,12 +2661,10 @@
     type = program.unaliasType(type);
 
     if (type.isMalformed) {
-      FunctionElement helper = program.throwTypeErrorHelper;
       ErroneousElement element = type.element;
       ir.Primitive message = buildStringConstant(element.message);
       return buildStaticFunctionInvocation(
-          helper,
-          CallStructure.ONE_ARG,
+          program.throwTypeErrorHelper,
           <ir.Primitive>[message]);
     }
 
@@ -2760,8 +2696,7 @@
         // `x as Object` and `x as dynamic` are the same as `x`.
         return value;
       }
-      return _continueWithExpression(
-              (k) => new ir.TypeCast(value, type, typeArguments, k));
+      return addPrimitive(new ir.TypeCast(value, type, typeArguments));
     }
   }
 
@@ -2795,24 +2730,6 @@
     return buildIdentical(value, buildNullConstant(),
         sourceInformation: sourceInformation);
   }
-
-  /// Convert the given value to a string.
-  ir.Primitive buildStringify(ir.Primitive value) {
-    return buildStaticFunctionInvocation(
-        program.stringifyFunction,
-        new CallStructure.unnamed(1),
-        <ir.Primitive>[value]);
-  }
-
-  ir.Node buildAwait(ir.Primitive value) {
-    return _continueWithExpression((k) => new ir.Await(value, k));
-  }
-
-  void buildYield(ir.Primitive value, bool hasStar) {
-    _continueWithExpression((k) {
-      return new ir.Yield(value, hasStar, k);
-    });
-  }
 }
 
 /// Location of a variable relative to a given closure.
@@ -2821,7 +2738,7 @@
   /// The location of [box] can be obtained separately from an
   /// enclosing [ClosureEnvironment] or [ClosureScope].
   /// If `null`, then the location is [field] on the enclosing function object.
-  final BoxLocal box;
+  final closure.BoxLocal box;
 
   /// The field in which the variable is stored.
   final Entity field;
@@ -2829,6 +2746,21 @@
   bool get isBox => box != null;
 
   ClosureLocation(this.box, this.field);
+
+  /// Converts a map containing closure.dart's [CapturedVariable]s into one
+  /// containing [ClosureLocation]s.
+  ///
+  /// There is a 1:1 corresponce between these; we do this because the
+  /// IR builder should not depend on synthetic elements.
+  static Map<Local, ClosureLocation> mapFrom(
+      Map<Local, closure.CapturedVariable> map) {
+    Map result = {};
+    map.forEach((Local k, closure.CapturedVariable v) {
+      closure.BoxLocal box = v is closure.BoxFieldElement ? v.box : null;
+      result[k] = new ClosureLocation(box, v);
+    });
+    return result;
+  }
 }
 
 /// Introduces a new box and binds local variables to this box.
@@ -2838,7 +2770,7 @@
 /// [ClosureScope] when a given scope has no boxed variables.
 class ClosureScope {
   /// This box is now in scope and [capturedVariables] may use it.
-  final BoxLocal box;
+  final closure.BoxLocal box;
 
   /// Maps [LocalElement]s to their location.
   final Map<Local, ClosureLocation> capturedVariables;
@@ -2847,7 +2779,14 @@
   /// of boxed variables that are declared in the initializer.
   final List<VariableElement> boxedLoopVariables;
 
-  ClosureScope(this.box, this.capturedVariables, this.boxedLoopVariables);
+  factory ClosureScope(closure.ClosureScope scope) {
+    return scope == null ? null : new ClosureScope._internal(scope);
+  }
+
+  ClosureScope._internal(closure.ClosureScope scope)
+      : box = scope.boxElement,
+        capturedVariables = ClosureLocation.mapFrom(scope.capturedVariables),
+        boxedLoopVariables = scope.boxedLoopVariables;
 }
 
 /// Environment passed when building a nested function, describing how
@@ -2859,12 +2798,21 @@
 
   /// If non-null, [thisLocal] has an entry in [freeVariables] describing where
   /// to find the captured value of `this`.
-  final ThisLocal thisLocal;
+  final closure.ThisLocal thisLocal;
 
   /// Maps [LocalElement]s, [BoxLocal]s and [ThisLocal] to their location.
   final Map<Local, ClosureLocation> freeVariables;
 
-  ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables);
+  factory ClosureEnvironment(closure.ClosureClassMap closureClassMap) {
+    if (closureClassMap.closureElement == null) return null;
+    return new ClosureEnvironment._internal(closureClassMap);
+  }
+
+  ClosureEnvironment._internal(closure.ClosureClassMap closureClassMap)
+      : selfReference = closureClassMap.closureElement,
+        thisLocal = closureClassMap.thisLocal,
+        freeVariables =
+            ClosureLocation.mapFrom(closureClassMap.freeVariableMap);
 }
 
 class TryStatementInfo {
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 9f2ad07..5c55f63 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
@@ -4,8 +4,7 @@
 
 library dart2js.ir_builder_task;
 
-import '../closure.dart' as closurelib;
-import '../closure.dart' hide ClosureScope;
+import '../closure.dart' as closure;
 import '../common.dart';
 import '../common/names.dart' show
     Names,
@@ -22,14 +21,14 @@
     ConstructorBodyElementX,
     FunctionSignatureX;
 import '../io/source_information.dart';
+import '../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend/js_backend.dart' show
     JavaScriptBackend,
     SyntheticConstantKind;
 import '../resolution/tree_elements.dart' show
     TreeElements;
 import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart' show
-    SendResolverMixin;
 import '../resolution/operators.dart' as op;
 import '../tree/tree.dart' as ast;
 import '../types/types.dart' show
@@ -43,7 +42,8 @@
 import 'cps_ir_nodes.dart' as ir;
 import 'cps_ir_builder.dart';
 import '../native/native.dart' show
-    NativeBehavior;
+    NativeBehavior,
+    HasCapturedPlaceholders;
 
 // TODO(karlklose): remove.
 import '../js/js.dart' as js show js, Template, Expression, Name;
@@ -53,6 +53,8 @@
 import 'package:js_runtime/shared/embedded_names.dart'
     show JsBuiltin, JsGetName;
 import '../constants/values.dart';
+import 'type_mask_system.dart' show
+    TypeMaskSystem;
 
 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode);
 
@@ -76,7 +78,8 @@
 
   String get name => 'CPS builder';
 
-  ir.FunctionDefinition buildNode(AstElement element) {
+  ir.FunctionDefinition buildNode(AstElement element,
+                                  TypeMaskSystem typeMaskSystem) {
     return measure(() {
       bailoutMessage = null;
 
@@ -87,8 +90,9 @@
             sourceInformationStrategy.createBuilderForContext(element);
 
         IrBuilderVisitor builder =
-            new JsIrBuilderVisitor(
-                elementsMapping, compiler, sourceInformationBuilder);
+            new IrBuilderVisitor(
+                elementsMapping, compiler, sourceInformationBuilder,
+                typeMaskSystem);
         ir.FunctionDefinition irNode = builder.buildExecutable(element);
         if (irNode == null) {
           bailoutMessage = builder.bailoutMessage;
@@ -110,10 +114,9 @@
 /// For expressions, the primitive holding the resulting value is returned.
 /// For statements, `null` is returned.
 // TODO(johnniwinther): Implement [SemanticDeclVisitor].
-abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
+class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
     with IrBuilderMixin<ast.Node>,
          SemanticSendResolvedMixin<ir.Primitive, dynamic>,
-         SendResolverMixin,
          ErrorBulkMixin<ir.Primitive, dynamic>,
          BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>,
          BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>,
@@ -127,6 +130,7 @@
   final TreeElements elements;
   final Compiler compiler;
   final SourceInformationBuilder sourceInformationBuilder;
+  final TypeMaskSystem typeMaskSystem;
 
   /// A map from try statements in the source to analysis information about
   /// them.
@@ -157,53 +161,719 @@
   /// Construct a top-level visitor.
   IrBuilderVisitor(this.elements,
                    this.compiler,
-                   this.sourceInformationBuilder);
+                   this.sourceInformationBuilder,
+                   this.typeMaskSystem);
 
+  JavaScriptBackend get backend => compiler.backend;
+  BackendHelpers get helpers => backend.helpers;
   DiagnosticReporter get reporter => compiler.reporter;
 
   String bailoutMessage = null;
 
+  ir.Primitive visit(ast.Node node) => node.accept(this);
+
   @override
   ir.Primitive apply(ast.Node node, _) => node.accept(this);
 
-  @override
   SemanticSendVisitor get sendVisitor => this;
 
-  /**
-   * Builds the [ir.FunctionDefinition] for an executable element. In case the
-   * function uses features that cannot be expressed in the IR, this element
-   * returns `null`.
-   */
-  ir.FunctionDefinition buildExecutable(ExecutableElement element);
-
-  ClosureClassMap get closureClassMap;
-  ClosureScope getClosureScopeForNode(ast.Node node);
-  ClosureEnvironment getClosureEnvironment();
-
-  /// Normalizes the argument list to a static invocation (i.e. where the target
-  /// element is known).
+  /// Result of closure conversion for the current body of code.
   ///
-  /// For the JS backend, inserts default arguments and normalizes order of
-  /// named arguments.
+  /// Will be initialized upon entering the body of a function.
+  /// It is computed by the [ClosureTranslator].
+  closure.ClosureClassMap closureClassMap;
+
+  /// If [node] has declarations for variables that should be boxed,
+  /// returns a [ClosureScope] naming a box to create, and enumerating the
+  /// variables that should be stored in the box.
   ///
-  /// For the Dart backend, returns [arguments].
-  List<ir.Primitive> normalizeStaticArguments(
-      CallStructure callStructure,
+  /// Also see [ClosureScope].
+  ClosureScope getClosureScopeForNode(ast.Node node) {
+    // We translate a ClosureScope from closure.dart into IR builder's variant
+    // because the IR builder should not depend on the synthetic elements
+    // created in closure.dart.
+    return new ClosureScope(closureClassMap.capturingScopes[node]);
+  }
+
+  /// Returns the [ClosureScope] for any function, possibly different from the
+  /// one currently being built.
+  ClosureScope getClosureScopeForFunction(FunctionElement function) {
+    closure.ClosureClassMap map =
+        compiler.closureToClassMapper.computeClosureToClassMapping(
+            function,
+            function.node,
+            elements);
+    return new ClosureScope(map.capturingScopes[function.node]);
+  }
+
+  /// If the current function is a nested function with free variables (or a
+  /// captured reference to `this`), returns a [ClosureEnvironment]
+  /// indicating how to access these.
+  ClosureEnvironment getClosureEnvironment() {
+    return new ClosureEnvironment(closureClassMap);
+  }
+
+  IrBuilder getBuilderFor(Element element) {
+    return new IrBuilder(
+        new GlobalProgramInformation(compiler),
+        backend.constants,
+        element);
+  }
+
+  /// Builds the [ir.FunctionDefinition] for an executable element. In case the
+  /// function uses features that cannot be expressed in the IR, this element
+  /// returns `null`.
+  ir.FunctionDefinition buildExecutable(ExecutableElement element) {
+    return nullIfGiveup(() {
+      ir.FunctionDefinition root;
+      switch (element.kind) {
+        case ElementKind.GENERATIVE_CONSTRUCTOR:
+          root = buildConstructor(element);
+          break;
+
+        case ElementKind.GENERATIVE_CONSTRUCTOR_BODY:
+          root = buildConstructorBody(element);
+          break;
+
+        case ElementKind.FACTORY_CONSTRUCTOR:
+        case ElementKind.FUNCTION:
+        case ElementKind.GETTER:
+        case ElementKind.SETTER:
+          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:
+          reporter.internalError(element, "Unexpected element type $element");
+      }
+      return root;
+    });
+  }
+
+  /// Loads the type variables for all super classes of [superClass] into the
+  /// IR builder's environment with their corresponding values.
+  ///
+  /// The type variables for [currentClass] must already be in the IR builder's
+  /// environment.
+  ///
+  /// Type variables are stored as [TypeVariableLocal] in the environment.
+  ///
+  /// This ensures that access to type variables mentioned inside the
+  /// constructors and initializers will happen through the local environment
+  /// instead of using 'this'.
+  void loadTypeVariablesForSuperClasses(ClassElement currentClass) {
+    if (currentClass.isObject) return;
+    loadTypeVariablesForType(currentClass.supertype);
+    if (currentClass is MixinApplicationElement) {
+      loadTypeVariablesForType(currentClass.mixinType);
+    }
+  }
+
+  /// Loads all type variables for [type] and all of its super classes into
+  /// the environment. All type variables mentioned in [type] must already
+  /// be in the environment.
+  void loadTypeVariablesForType(InterfaceType type) {
+    ClassElement clazz = type.element;
+    assert(clazz.typeVariables.length == type.typeArguments.length);
+    for (int i = 0; i < clazz.typeVariables.length; ++i) {
+      irBuilder.declareTypeVariable(clazz.typeVariables[i],
+          type.typeArguments[i]);
+    }
+    loadTypeVariablesForSuperClasses(clazz);
+  }
+
+  /// Returns the constructor body associated with the given constructor or
+  /// creates a new constructor body, if none can be found.
+  ///
+  /// Returns `null` if the constructor does not have a body.
+  ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
+    // TODO(asgerf): This is largely inherited from the SSA builder.
+    // The ConstructorBodyElement has an invalid function signature, but we
+    // cannot add a BoxLocal as parameter, because BoxLocal is not an element.
+    // Instead of forging ParameterElements to forge a FunctionSignature, we
+    // need a way to create backend methods without creating more fake elements.
+    assert(constructor.isGenerativeConstructor);
+    assert(constructor.isImplementation);
+    if (constructor.isSynthesized) return null;
+    ast.FunctionExpression node = constructor.node;
+    // If we know the body doesn't have any code, we don't generate it.
+    if (!node.hasBody()) return null;
+    if (node.hasEmptyBody()) return null;
+    ClassElement classElement = constructor.enclosingClass;
+    ConstructorBodyElement bodyElement;
+    classElement.forEachBackendMember((Element backendMember) {
+      if (backendMember.isGenerativeConstructorBody) {
+        ConstructorBodyElement body = backendMember;
+        if (body.constructor == constructor) {
+          bodyElement = backendMember;
+        }
+      }
+    });
+    if (bodyElement == null) {
+      bodyElement = new ConstructorBodyElementX(constructor);
+      classElement.addBackendMember(bodyElement);
+
+      if (constructor.isPatch) {
+        // Create origin body element for patched constructors.
+        ConstructorBodyElementX patch = bodyElement;
+        ConstructorBodyElementX origin =
+        new ConstructorBodyElementX(constructor.origin);
+        origin.applyPatch(patch);
+        classElement.origin.addBackendMember(bodyElement.origin);
+      }
+    }
+    assert(bodyElement.isGenerativeConstructorBody);
+    return bodyElement;
+  }
+
+  /// The list of parameters to send from the generative constructor
+  /// to the generative constructor body.
+  ///
+  /// Boxed parameters are not in the list, instead, a [BoxLocal] is passed
+  /// containing the boxed parameters.
+  ///
+  /// For example, given the following constructor,
+  ///
+  ///     Foo(x, y) : field = (() => ++x) { print(x + y) }
+  ///
+  /// the argument `x` would be replaced by a [BoxLocal]:
+  ///
+  ///     Foo_body(box0, y) { print(box0.x + y) }
+  ///
+  List<Local> getConstructorBodyParameters(ConstructorBodyElement body) {
+    List<Local> parameters = <Local>[];
+    ClosureScope scope = getClosureScopeForFunction(body.constructor);
+    if (scope != null) {
+      parameters.add(scope.box);
+    }
+    body.functionSignature.orderedForEachParameter((ParameterElement param) {
+      if (scope != null && scope.capturedVariables.containsKey(param)) {
+        // Do not pass this parameter; the box will carry its value.
+      } else {
+        parameters.add(param);
+      }
+    });
+    return parameters;
+  }
+
+  /// Builds the IR for a given constructor.
+  ///
+  /// 1. Computes the type held in all own or "inherited" type variables.
+  /// 2. Evaluates all own or inherited field initializers.
+  /// 3. Creates the object and assigns its fields and runtime type.
+  /// 4. Calls constructor body and super constructor bodies.
+  /// 5. 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;
+
+    IrBuilder builder = getBuilderFor(constructor);
+
+    final bool requiresTypeInformation =
+    builder.program.requiresRuntimeTypesFor(classElement);
+
+    return withBuilder(builder, () {
+      // Setup parameters and create a box if anything is captured.
+      List<Local> parameters = <Local>[];
+      constructor.functionSignature.orderedForEachParameter(
+          (ParameterElement p) => parameters.add(p));
+
+      int firstTypeArgumentParameterIndex;
+
+      // If instances of the class may need runtime type information, we add a
+      // synthetic parameter for each type parameter.
+      if (requiresTypeInformation) {
+        firstTypeArgumentParameterIndex = parameters.length;
+        classElement.typeVariables.forEach((TypeVariableType variable) {
+          parameters.add(new closure.TypeVariableLocal(variable, constructor));
+        });
+      } else {
+        classElement.typeVariables.forEach((TypeVariableType variable) {
+          irBuilder.declareTypeVariable(variable, const DynamicType());
+        });
+      }
+
+      // Create IR parameters and setup the environment.
+      List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters,
+          closureScope: getClosureScopeForFunction(constructor));
+
+      // Create a list of the values of all type argument parameters, if any.
+      List<ir.Primitive> typeInformation;
+      if (requiresTypeInformation) {
+        typeInformation = irParameters.sublist(firstTypeArgumentParameterIndex);
+      } else {
+        typeInformation = const <ir.Primitive>[];
+      }
+
+      // -- Load values for type variables declared on super classes --
+      // Field initializers for super classes can reference these, so they
+      // must be available before evaluating field initializers.
+      // This could be interleaved with field initialization, but we choose do
+      // get it out of the way here to avoid complications with mixins.
+      loadTypeVariablesForSuperClasses(classElement);
+
+      /// Maps each field from this class or a superclass to its initial value.
+      Map<FieldElement, ir.Primitive> fieldValues =
+      <FieldElement, ir.Primitive>{};
+
+      // -- Evaluate field initializers ---
+      // Evaluate field initializers in constructor and super constructors.
+      List<ConstructorElement> constructorList = <ConstructorElement>[];
+      evaluateConstructorFieldInitializers(
+          constructor, constructorList, fieldValues);
+
+      // All parameters in all constructors are now bound in the environment.
+      // BoxLocals for captured parameters are also in the environment.
+      // The initial value of all fields are now bound in [fieldValues].
+
+      // --- Create the object ---
+      // Get the initial field values in the canonical order.
+      List<ir.Primitive> instanceArguments = <ir.Primitive>[];
+      classElement.forEachInstanceField((ClassElement c, FieldElement field) {
+        ir.Primitive value = fieldValues[field];
+        if (value != null) {
+          instanceArguments.add(value);
+        } else {
+          assert(backend.isNativeOrExtendsNative(c));
+          // Native fields are initialized elsewhere.
+        }
+      }, includeSuperAndInjectedMembers: true);
+
+      ir.Primitive instance = new ir.CreateInstance(
+          classElement,
+          instanceArguments,
+          typeInformation,
+          constructor.hasNode
+              ? sourceInformationBuilder.buildCreate(constructor.node)
+          // TODO(johnniwinther): Provide source information for creation
+          // through synthetic constructors.
+              : null);
+      irBuilder.add(new ir.LetPrim(instance));
+
+      // --- Call constructor bodies ---
+      for (ConstructorElement target in constructorList) {
+        ConstructorBodyElement bodyElement = getConstructorBody(target);
+        if (bodyElement == null) continue; // Skip if constructor has no body.
+        List<ir.Primitive> bodyArguments = <ir.Primitive>[];
+        for (Local param in getConstructorBodyParameters(bodyElement)) {
+          bodyArguments.add(irBuilder.environment.lookup(param));
+        }
+        Selector selector = new Selector.call(target.memberName,
+            new CallStructure(bodyArguments.length));
+        irBuilder.addPrimitive(new ir.InvokeMethodDirectly(
+            instance, bodyElement, selector, bodyArguments, null));
+      }
+
+      // --- step 4: return the created object ----
+      irBuilder.buildReturn(
+          value: instance,
+          sourceInformation:
+          sourceInformationBuilder.buildImplicitReturn(constructor));
+
+      return irBuilder.makeFunctionDefinition();
+    });
+  }
+
+  /// Make a visitor suitable for translating ASTs taken from [context].
+  ///
+  /// Every visitor can only be applied to nodes in one context, because
+  /// the [elements] field is specific to that context.
+  IrBuilderVisitor makeVisitorForContext(AstElement context) {
+    return new IrBuilderVisitor(
+        context.resolvedAst.elements,
+        compiler,
+        sourceInformationBuilder.forContext(context),
+        typeMaskSystem);
+  }
+
+  /// Builds the IR for an [expression] taken from a different [context].
+  ///
+  /// Such expressions need to be compiled with a different [sourceFile] and
+  /// [elements] mapping.
+  ir.Primitive inlineExpression(AstElement context, ast.Expression expression) {
+    IrBuilderVisitor visitor = makeVisitorForContext(context);
+    return visitor.withBuilder(irBuilder, () => visitor.visit(expression));
+  }
+
+  /// Evaluate the implicit super call in the given mixin constructor.
+  void forwardSynthesizedMixinConstructor(
+      ConstructorElement constructor,
+      List<ConstructorElement> supers,
+      Map<FieldElement, ir.Primitive> fieldValues) {
+    assert(constructor.enclosingClass.implementation.isMixinApplication);
+    assert(constructor.isSynthesized);
+    ConstructorElement target =
+        constructor.definingConstructor.implementation;
+    // The resolver gives us the exact same FunctionSignature for the two
+    // constructors. The parameters for the synthesized constructor
+    // are already in the environment, so the target constructor's parameters
+    // are also in the environment since their elements are the same.
+    assert(constructor.functionSignature == target.functionSignature);
+    IrBuilderVisitor visitor = makeVisitorForContext(target);
+    visitor.withBuilder(irBuilder, () {
+      visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
+    });
+  }
+
+  /// In preparation of inlining (part of) [target], the [arguments] are moved
+  /// into the environment bindings for the corresponding parameters.
+  ///
+  /// Defaults for optional arguments are evaluated in order to ensure
+  /// all parameters are available in the environment.
+  void loadArguments(ConstructorElement target,
+      CallStructure call,
+      List<ir.Primitive> arguments) {
+    assert(target.isImplementation);
+    assert(target == elements.analyzedElement);
+    FunctionSignature signature = target.functionSignature;
+
+    // Establish a scope in case parameters are captured.
+    ClosureScope scope = getClosureScopeForFunction(target);
+    irBuilder.enterScope(scope);
+
+    // Load required parameters
+    int index = 0;
+    signature.forEachRequiredParameter((ParameterElement param) {
+      irBuilder.declareLocalVariable(param, initialValue: arguments[index]);
+      index++;
+    });
+
+    // Load optional parameters, evaluating default values for omitted ones.
+    signature.forEachOptionalParameter((ParameterElement param) {
+      ir.Primitive value;
+      // Load argument if provided.
+      if (signature.optionalParametersAreNamed) {
+        int nameIndex = call.namedArguments.indexOf(param.name);
+        if (nameIndex != -1) {
+          int translatedIndex = call.positionalArgumentCount + nameIndex;
+          value = arguments[translatedIndex];
+        }
+      } else if (index < arguments.length) {
+        value = arguments[index];
+      }
+      // Load default if argument was not provided.
+      if (value == null) {
+        if (param.initializer != null) {
+          value = visit(param.initializer);
+        } else {
+          value = irBuilder.buildNullConstant();
+        }
+      }
+      irBuilder.declareLocalVariable(param, initialValue: value);
+      index++;
+    });
+  }
+
+  /// Evaluates a call to the given constructor from an initializer list.
+  ///
+  /// Calls [loadArguments] and [evaluateConstructorFieldInitializers] in a
+  /// visitor that has the proper [TreeElements] mapping.
+  void evaluateConstructorCallFromInitializer(
+      ConstructorElement target,
+      CallStructure call,
+      List<ir.Primitive> arguments,
+      List<ConstructorElement> supers,
+      Map<FieldElement, ir.Primitive> fieldValues) {
+    IrBuilderVisitor visitor = makeVisitorForContext(target);
+    visitor.withBuilder(irBuilder, () {
+      visitor.loadArguments(target, call, arguments);
+      visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
+    });
+  }
+
+  /// Evaluates all field initializers on [constructor] and all constructors
+  /// invoked through `this()` or `super()` ("superconstructors").
+  ///
+  /// The resulting field values will be available in [fieldValues]. The values
+  /// are not stored in any fields.
+  ///
+  /// This procedure assumes that the parameters to [constructor] are available
+  /// in the IR builder's environment.
+  ///
+  /// The parameters to superconstructors are, however, assumed *not* to be in
+  /// the environment, but will be put there by this procedure.
+  ///
+  /// All constructors will be added to [supers], with superconstructors first.
+  void evaluateConstructorFieldInitializers(
+      ConstructorElement constructor,
+      List<ConstructorElement> supers,
+      Map<FieldElement, ir.Primitive> fieldValues) {
+    assert(constructor.isImplementation);
+    assert(constructor == elements.analyzedElement);
+    ClassElement enclosingClass = constructor.enclosingClass.implementation;
+    // 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 {
+          if (backend.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();
+          }
+        }
+      });
+    }
+    // If this is a mixin constructor, it does not have its own parameter list
+    // or initializer list. Directly forward to the super constructor.
+    // Note that the declaration-site initializers originating from the
+    // mixed-in class were handled above.
+    if (enclosingClass.isMixinApplication) {
+      forwardSynthesizedMixinConstructor(constructor, supers, fieldValues);
+      return;
+    }
+    // Evaluate initializing parameters, e.g. `Foo(this.x)`.
+    constructor.functionSignature.orderedForEachParameter(
+        (ParameterElement parameter) {
+      if (parameter.isInitializingFormal) {
+        InitializingFormalElement fieldParameter = parameter;
+        fieldValues[fieldParameter.fieldElement] =
+            irBuilder.buildLocalGet(parameter);
+      }
+    });
+    // Evaluate constructor initializers, e.g. `Foo() : x = 50`.
+    ast.FunctionExpression node = constructor.node;
+    bool hasConstructorCall = false; // Has this() or super() initializer?
+    if (node != null && node.initializers != null) {
+      for(ast.Node initializer in node.initializers) {
+        if (initializer is ast.SendSet) {
+          // Field initializer.
+          FieldElement field = elements[initializer];
+          fieldValues[field] = visit(initializer.arguments.head);
+        } else if (initializer is ast.Send) {
+          // Super or this initializer.
+          ConstructorElement target = elements[initializer].implementation;
+          Selector selector = elements.getSelector(initializer);
+          List<ir.Primitive> arguments = initializer.arguments.mapToList(visit);
+          evaluateConstructorCallFromInitializer(
+              target,
+              selector.callStructure,
+              arguments,
+              supers,
+              fieldValues);
+          hasConstructorCall = true;
+        } else {
+          reporter.internalError(initializer,
+              "Unexpected initializer type $initializer");
+        }
+      }
+    }
+    // If no super() or this() was found, also call default superconstructor.
+    if (!hasConstructorCall && !enclosingClass.isObject) {
+      ClassElement superClass = enclosingClass.superclass;
+      FunctionElement target = superClass.lookupDefaultConstructor();
+      if (target == null) {
+        reporter.internalError(superClass, "No default constructor available.");
+      }
+      target = target.implementation;
+      evaluateConstructorCallFromInitializer(
+          target,
+          CallStructure.NO_ARGS,
+          const [],
+          supers,
+          fieldValues);
+    }
+    // Add this constructor after the superconstructors.
+    supers.add(constructor);
+  }
+
+  TryBoxedVariables _analyzeTryBoxedVariables(ast.Node node) {
+    TryBoxedVariables variables = new TryBoxedVariables(elements);
+    try {
+      variables.analyze(node);
+    } catch (e) {
+      bailoutMessage = variables.bailoutMessage;
+      rethrow;
+    }
+    return variables;
+  }
+
+  /// Builds the IR for the body of a constructor.
+  ///
+  /// This function is invoked from one or more "factory" constructors built by
+  /// [buildConstructor].
+  ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) {
+    ConstructorElement constructor = body.constructor;
+    ast.FunctionExpression node = constructor.node;
+    closureClassMap =
+        compiler.closureToClassMapper.computeClosureToClassMapping(
+            constructor,
+            node,
+            elements);
+
+    // We compute variables boxed in mutable variables on entry to each try
+    // block, not including variables captured by a closure (which are boxed
+    // in the heap).  This duplicates some of the work of closure conversion
+    // without directly using the results.  This duplication is wasteful and
+    // error-prone.
+    // TODO(kmillikin): We should combine closure conversion and try/catch
+    // variable analysis in some way.
+    TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
+    tryStatements = variables.tryStatements;
+    IrBuilder builder = getBuilderFor(body);
+
+    return withBuilder(builder, () {
+      irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body),
+          getClosureScopeForNode(node));
+      visit(node.body);
+      return irBuilder.makeFunctionDefinition();
+    });
+  }
+
+  ir.FunctionDefinition buildFunction(FunctionElement element) {
+    assert(invariant(element, element.isImplementation));
+    ast.FunctionExpression node = element.node;
+
+    assert(!element.isSynthesized);
+    assert(node != null);
+    assert(elements[node] != null);
+
+    closureClassMap =
+        compiler.closureToClassMapper.computeClosureToClassMapping(
+            element,
+            node,
+            elements);
+    TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
+    tryStatements = variables.tryStatements;
+    IrBuilder builder = getBuilderFor(element);
+    return withBuilder(builder, () => _makeFunctionBody(element, node));
+  }
+
+  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, () {
+      irBuilder.buildFunctionHeader(<Local>[]);
+      ir.Primitive initialValue = visit(element.initializer);
+      ast.VariableDefinitions node = element.node;
+      ast.SendSet sendSet = node.definitions.nodes.head;
+      irBuilder.buildReturn(
+          value: initialValue,
+          sourceInformation:
+          sourceInformationBuilder.buildReturn(sendSet.assignmentOperator));
+      return irBuilder.makeFunctionDefinition();
+    });
+  }
+
+  /// Builds the IR for a constant taken from a different [context].
+  ///
+  /// Such constants need to be compiled with a different [sourceFile] and
+  /// [elements] mapping.
+  ir.Primitive inlineConstant(AstElement context, ast.Expression exp) {
+    IrBuilderVisitor visitor = makeVisitorForContext(context);
+    return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp));
+  }
+
+  /// Creates a primitive for the default value of [parameter].
+  ir.Primitive translateDefaultValue(ParameterElement parameter) {
+    if (parameter.initializer == null) {
+      return irBuilder.buildNullConstant();
+    } else {
+      return inlineConstant(parameter.executableContext, parameter.initializer);
+    }
+  }
+
+  /// Normalizes the argument list of a static invocation.
+  ///
+  /// A static invocation is one where the target is known.  The argument list
+  /// [arguments] is normalized by adding default values for optional arguments
+  /// that are not passed, and by sorting it in place so that named arguments
+  /// appear in a canonical order.  A [CallStructure] reflecting this order
+  /// is returned.
+  CallStructure normalizeStaticArguments(CallStructure callStructure,
       FunctionElement target,
-      List<ir.Primitive> arguments);
+      List<ir.Primitive> arguments) {
+    target = target.implementation;
+    FunctionSignature signature = target.functionSignature;
+    if (!signature.optionalParametersAreNamed &&
+        signature.parameterCount == arguments.length) {
+      return callStructure;
+    }
 
-  /// Normalizes the argument list of a dynamic invocation (i.e. where the
-  /// target element is unknown).
+    if (!signature.optionalParametersAreNamed) {
+      int i = signature.requiredParameterCount;
+      signature.forEachOptionalParameter((ParameterElement element) {
+        if (i < callStructure.positionalArgumentCount) {
+          ++i;
+        } else {
+          arguments.add(translateDefaultValue(element));
+        }
+      });
+      return new CallStructure(signature.parameterCount);
+    }
+
+    int offset = signature.requiredParameterCount;
+    List<ir.Primitive> namedArguments = arguments.sublist(offset);
+    arguments.length = offset;
+    List<String> normalizedNames = <String>[];
+    // Iterate over the optional parameters of the signature, and try to
+    // find them in the callStructure's named arguments. If found, we use the
+    // value in the temporary list, otherwise the default value.
+    signature.orderedOptionalParameters.forEach((ParameterElement element) {
+      int nameIndex = callStructure.namedArguments.indexOf(element.name);
+      arguments.add(nameIndex == -1 ? translateDefaultValue(element)
+          : namedArguments[nameIndex]);
+      normalizedNames.add(element.name);
+    });
+    return new CallStructure(signature.parameterCount, normalizedNames);
+  }
+
+  /// Normalizes the argument list of a dynamic invocation.
   ///
-  /// For the JS backend, normalizes order of named arguments.
-  ///
-  /// For the Dart backend, returns [arguments].
-  List<ir.Primitive> normalizeDynamicArguments(
-      CallStructure callStructure,
-      List<ir.Primitive> arguments);
+  /// A dynamic invocation is one where the target is not known.  The argument
+  /// list [arguments] is normalized by sorting it in place so that the named
+  /// arguments appear in a canonical order.  A [CallStructure] reflecting this
+  /// order is returned.
+  CallStructure normalizeDynamicArguments(CallStructure callStructure,
+      List<ir.Primitive> arguments) {
+    assert(arguments.length == callStructure.argumentCount);
+    if (callStructure.namedArguments.isEmpty) return callStructure;
+    int destinationIndex = callStructure.positionalArgumentCount;
+    List<ir.Primitive> namedArguments = arguments.sublist(destinationIndex);
+    for (String argName in callStructure.getOrderedNamedArguments()) {
+      int sourceIndex = callStructure.namedArguments.indexOf(argName);
+      arguments[destinationIndex++] = namedArguments[sourceIndex];
+    }
+    return new CallStructure(callStructure.argumentCount,
+        callStructure.getOrderedNamedArguments());
+  }
 
   /// Read the value of [field].
-  ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src);
+  ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
+    ConstantValue constant = getConstantForVariable(field);
+    if (constant != null && !field.isAssignable) {
+      typeMaskSystem.associateConstantValueWithElement(constant, field);
+      return irBuilder.buildConstant(constant, sourceInformation: src);
+    } else if (backend.constants.lazyStatics.contains(field)) {
+      return irBuilder.addPrimitive(new ir.GetLazyStatic(field, src));
+    } else {
+      return irBuilder.addPrimitive(new ir.GetStatic(field, src));
+    }
+  }
 
   ir.FunctionDefinition _makeFunctionBody(FunctionElement element,
                                           ast.FunctionExpression node) {
@@ -215,7 +885,7 @@
     if (element.isFactoryConstructor) {
       // Type arguments are passed in as extra parameters.
       for (DartType typeVariable in element.enclosingClass.typeVariables) {
-        parameters.add(new TypeVariableLocal(typeVariable, element));
+        parameters.add(new closure.TypeVariableLocal(typeVariable, element));
       }
     }
 
@@ -227,7 +897,26 @@
     return irBuilder.makeFunctionDefinition();
   }
 
-  ir.Primitive visit(ast.Node node) => node.accept(this);
+  /// Builds the IR for creating an instance of the closure class corresponding
+  /// to the given nested function.
+  closure.ClosureClassElement makeSubFunction(ast.FunctionExpression node) {
+    closure.ClosureClassMap innerMap =
+        compiler.closureToClassMapper.getMappingForNestedFunction(node);
+    closure.ClosureClassElement closureClass = innerMap.closureClassElement;
+    return closureClass;
+  }
+
+  ir.Primitive visitFunctionExpression(ast.FunctionExpression node) {
+    return irBuilder.buildFunctionExpression(makeSubFunction(node),
+        sourceInformationBuilder.buildCreate(node));
+  }
+
+  visitFunctionDeclaration(ast.FunctionDeclaration node) {
+    LocalFunctionElement element = elements[node.function];
+    Object inner = makeSubFunction(node.function);
+    irBuilder.declareLocalFunction(element, inner,
+        sourceInformationBuilder.buildCreate(node.function));
+  }
 
   // ## Statements ##
   visitBlock(ast.Block node) {
@@ -279,7 +968,7 @@
   /// constructor.  This is only required, if the forwarding factory
   /// constructor can potentially be the target of a reflective call, because
   /// the builder shortcuts calls to redirecting factories at the call site
-  /// (see [JsIrBuilderVisitor.handleConstructorInvoke]).
+  /// (see [handleConstructorInvoke]).
   visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
     ConstructorElement targetConstructor =
         elements.getRedirectingTargetConstructor(node).implementation;
@@ -301,8 +990,8 @@
     CallStructure callStructure = new CallStructure(
         redirectingSignature.parameterCount,
         namedParameters);
-    arguments = normalizeStaticArguments(callStructure, targetConstructor,
-        arguments);
+    callStructure =
+        normalizeStaticArguments(callStructure, targetConstructor, arguments);
     ir.Primitive instance = irBuilder.buildConstructorInvocation(
         targetConstructor,
         callStructure,
@@ -376,13 +1065,15 @@
   }
 
   visitAwait(ast.Await node) {
+    assert(irBuilder.isOpen);
     ir.Primitive value = visit(node.expression);
-    return irBuilder.buildAwait(value);
+    return irBuilder.addPrimitive(new ir.Await(value));
   }
 
   visitYield(ast.Yield node) {
+    assert(irBuilder.isOpen);
     ir.Primitive value = visit(node.expression);
-    return irBuilder.buildYield(value, node.hasStar);
+    return irBuilder.addPrimitive(new ir.Yield(value, node.hasStar));
   }
 
   visitSyncForIn(ast.SyncForIn node) {
@@ -409,6 +1100,21 @@
         closureScope: getClosureScopeForNode(node));
   }
 
+  /// If compiling with trusted type annotations, assumes that [value] is
+  /// now known to be `null` or an instance of [type].
+  ///
+  /// This is also where we should add type checks in checked mode, but this
+  /// is not supported yet.
+  ir.Primitive checkType(ir.Primitive value, DartType dartType) {
+    if (!compiler.trustTypeAnnotations) return value;
+    TypeMask type = typeMaskSystem.subtypesOf(dartType).nullable();
+    return irBuilder.addPrimitive(new ir.Refinement(value, type));
+  }
+
+  ir.Primitive checkTypeVsElement(ir.Primitive value, TypedElement element) {
+    return checkType(value, element.type);
+  }
+
   ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) {
     assert(irBuilder.isOpen);
     for (ast.Node definition in node.definitions.nodes) {
@@ -420,6 +1126,7 @@
         assert(!definition.arguments.isEmpty);
         assert(definition.arguments.tail.isEmpty);
         initialValue = visit(definition.arguments.head);
+        initialValue = checkTypeVsElement(initialValue, element);
       } else {
         assert(definition is ast.Identifier);
       }
@@ -440,7 +1147,7 @@
     SourceInformation source = sourceInformationBuilder.buildReturn(node);
     if (node.beginToken.value == 'native') {
       FunctionElement function = irBuilder.state.currentElement;
-      assert(function.isNative);
+      assert(backend.isNative(function));
       ast.Node nativeBody = node.expression;
       if (nativeBody != null) {
         ast.LiteralString jsCode = nativeBody.asLiteralString();
@@ -454,7 +1161,8 @@
               'functions with zero parameters.'));
         irBuilder.buildNativeFunctionBody(function, javaScriptCode);
       } else {
-        irBuilder.buildRedirectingNativeFunctionBody(function, source);
+        String name = backend.getFixedBackendName(function);
+        irBuilder.buildRedirectingNativeFunctionBody(function, name, source);
       }
     } else {
       irBuilder.buildReturn(
@@ -499,8 +1207,7 @@
     }
     ir.Primitive value = visit(node.expression);
     JumpTarget target = elements.getTargetDefinition(node);
-    Element error =
-        (compiler.backend as JavaScriptBackend).helpers.fallThroughError;
+    Element error = helpers.fallThroughError;
     irBuilder.buildSimpleSwitch(target, value, cases, defaultCase, error,
         sourceInformationBuilder.buildGeneric(node));
   }
@@ -602,25 +1309,37 @@
         sourceInformation: sourceInformation);
   }
 
+  /// Returns the allocation site-specific type for a given allocation.
+  ///
+  /// Currently, it is an error to call this with anything that is not the
+  /// allocation site for a List object (a literal list or a call to one
+  /// of the List constructors).
+  TypeMask getAllocationSiteType(ast.Node node) {
+    return compiler.typesTask.getGuaranteedTypeOfNode(
+        elements.analyzedElement, node);
+  }
+
   ir.Primitive visitLiteralList(ast.LiteralList node) {
     if (node.isConst) {
       return translateConstant(node);
     }
     List<ir.Primitive> values = node.elements.nodes.mapToList(visit);
     InterfaceType type = elements.getType(node);
-    return irBuilder.buildListLiteral(type, values);
+    return irBuilder.buildListLiteral(type, values,
+        allocationSiteType: getAllocationSiteType(node));
   }
 
   ir.Primitive visitLiteralMap(ast.LiteralMap node) {
+    assert(irBuilder.isOpen);
     if (node.isConst) {
       return translateConstant(node);
     }
     InterfaceType type = elements.getType(node);
-    return irBuilder.buildMapLiteral(
-        type,
-        node.entries.nodes.map((e) => e.key),
-        node.entries.nodes.map((e) => e.value),
-        build);
+    List<ir.LiteralMapEntry> entries =
+        node.entries.nodes.mapToList((ast.LiteralMapEntry e) {
+          return new ir.LiteralMapEntry(visit(e.key), visit(e.value));
+        });
+    return irBuilder.addPrimitive(new ir.LiteralMap(type, entries));
   }
 
   ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) {
@@ -671,7 +1390,21 @@
   // ## Sends ##
   @override
   void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
-    giveup(node, 'deferred access is not implemented');
+    if (prefix != null) buildCheckDeferredIsLoaded(prefix, node);
+  }
+
+  /// Create a call to check that a deferred import has already been loaded.
+  ir.Primitive buildCheckDeferredIsLoaded(PrefixElement prefix, ast.Send node) {
+    SourceInformation sourceInformation =
+        sourceInformationBuilder.buildCall(node, node.selector);
+    ir.Primitive name = irBuilder.buildStringConstant(
+        compiler.deferredLoadTask.getImportDeferName(node, prefix));
+    ir.Primitive uri =
+        irBuilder.buildStringConstant('${prefix.deferredImport.uri}');
+    return irBuilder.buildStaticFunctionInvocation(
+        helpers.checkDeferredIsLoaded,
+        <ir.Primitive>[name, uri],
+        sourceInformation: sourceInformation);
   }
 
   ir.Primitive visitNamedArgument(ast.NamedArgument node) {
@@ -685,10 +1418,9 @@
                                      ast.NodeList argumentsNode,
                                      CallStructure callStructure, _) {
     ir.Primitive receiver = visit(expression);
-    List<ir.Primitive> arguments = node.arguments.mapToList(visit);
-    arguments = normalizeDynamicArguments(callStructure, arguments);
-    return irBuilder.buildCallInvocation(
-        receiver, callStructure, arguments,
+    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
+    callStructure = normalizeDynamicArguments(callStructure, arguments);
+    return irBuilder.buildCallInvocation(receiver, callStructure, arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(node, argumentsNode));
   }
@@ -759,23 +1491,14 @@
     return element.isConst
         ? irBuilder.buildConstant(getConstantForVariable(element),
             sourceInformation: sourceInformationBuilder.buildGet(node))
-        : irBuilder.buildLocalVariableGet(element);
+        : irBuilder.buildLocalGet(element);
   }
 
-  @override
   ir.Primitive handleLocalGet(
       ast.Send node,
       LocalElement element,
       _) {
-    return irBuilder.buildLocalVariableGet(element);
-  }
-
-  @override
-  ir.Primitive visitLocalFunctionGet(
-      ast.Send node,
-      LocalFunctionElement function,
-      _) {
-    return irBuilder.buildLocalFunctionGet(function);
+    return irBuilder.buildLocalGet(element);
   }
 
   @override
@@ -783,7 +1506,7 @@
       ast.Send node,
       MethodElement function,
       _) {
-    return irBuilder.buildStaticFunctionGet(function);
+    return irBuilder.addPrimitive(new ir.GetStatic(function));
   }
 
   @override
@@ -791,8 +1514,26 @@
       ast.Send node,
       FunctionElement getter,
       _) {
-    return irBuilder.buildStaticGetterGet(
-        getter, sourceInformationBuilder.buildGet(node));
+    return buildStaticGetterGet(getter, node);
+  }
+
+  /// Create a getter invocation of the static getter [getter]. This also
+  /// handles the special case where [getter] is the `loadLibrary`
+  /// pseudo-function on library prefixes of deferred imports.
+  ir.Primitive buildStaticGetterGet(MethodElement getter, ast.Send node) {
+    SourceInformation sourceInformation =
+        sourceInformationBuilder.buildGet(node);
+    if (getter.isDeferredLoaderGetter) {
+      PrefixElement prefix = getter.enclosingElement;
+      ir.Primitive loadId = irBuilder.buildStringConstant(
+          compiler.deferredLoadTask.getImportDeferName(node, prefix));
+      return irBuilder.buildStaticFunctionInvocation(
+          compiler.loadLibraryFunction,
+          <ir.Primitive>[loadId],
+          sourceInformation: sourceInformation);
+    } else {
+      return irBuilder.buildStaticGetterGet(getter, sourceInformation);
+    }
   }
 
   @override
@@ -916,12 +1657,16 @@
                                ast.Node left,
                                op.BinaryOperator operator,
                                ast.Node right) {
-    Selector selector = new Selector.binaryOperator(operator.selectorName);
     ir.Primitive receiver = visit(left);
+    Selector selector = new Selector.binaryOperator(operator.selectorName);
     List<ir.Primitive> arguments = <ir.Primitive>[visit(right)];
-    arguments = normalizeDynamicArguments(selector.callStructure, arguments);
+    CallStructure callStructure =
+        normalizeDynamicArguments(selector.callStructure, arguments);
     return irBuilder.buildDynamicInvocation(
-        receiver, selector, elements.getTypeMask(node), arguments,
+        receiver,
+        new Selector(selector.kind, selector.memberName, callStructure),
+        elements.getTypeMask(node),
+        arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(node, node.selector));
   }
@@ -938,12 +1683,16 @@
   ir.Primitive visitIndex(ast.Send node,
                           ast.Node receiver,
                           ast.Node index, _) {
-    Selector selector = new Selector.index();
     ir.Primitive target = visit(receiver);
+    Selector selector = new Selector.index();
     List<ir.Primitive> arguments = <ir.Primitive>[visit(index)];
-    arguments = normalizeDynamicArguments(selector.callStructure, arguments);
+    CallStructure callStructure =
+        normalizeDynamicArguments(selector.callStructure, arguments);
     return irBuilder.buildDynamicInvocation(
-        target, selector, elements.getTypeMask(node), arguments,
+        target,
+        new Selector(selector.kind, selector.memberName, callStructure),
+        elements.getTypeMask(node),
+        arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(receiver, node.selector));
   }
@@ -951,11 +1700,9 @@
   ir.Primitive translateSuperBinary(FunctionElement function,
                                     op.BinaryOperator operator,
                                     ast.Node argument) {
-    CallStructure callStructure = CallStructure.ONE_ARG;
     List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)];
-    arguments = normalizeDynamicArguments(callStructure, arguments);
-    return irBuilder.buildSuperMethodInvocation(
-        function, callStructure, arguments);
+    return irBuilder.buildSuperMethodInvocation(function,
+        CallStructure.ONE_ARG, arguments);
   }
 
   @override
@@ -1047,28 +1794,33 @@
 
   // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
   // semantic correlation between arguments and invocation.
-  List<ir.Primitive> translateDynamicArguments(ast.NodeList nodeList,
-                                               CallStructure callStructure) {
-    List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
+  CallStructure translateDynamicArguments(ast.NodeList nodeList,
+                                          CallStructure callStructure,
+                                          List<ir.Primitive> arguments) {
+    assert(arguments.isEmpty);
+    for (ast.Node node in nodeList) arguments.add(visit(node));
     return normalizeDynamicArguments(callStructure, arguments);
   }
 
   // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
   // semantic correlation between arguments and invocation.
-  List<ir.Primitive> translateStaticArguments(ast.NodeList nodeList,
-                                              Element element,
-                                              CallStructure callStructure) {
-    List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
+  CallStructure translateStaticArguments(ast.NodeList nodeList,
+                                         Element element,
+                                         CallStructure callStructure,
+                                         List<ir.Primitive> arguments) {
+    assert(arguments.isEmpty);
+    for (ast.Node node in nodeList) arguments.add(visit(node));
     return normalizeStaticArguments(callStructure, element, arguments);
   }
 
   ir.Primitive translateCallInvoke(ir.Primitive target,
-                                   ast.NodeList arguments,
+                                   ast.NodeList argumentsNode,
                                    CallStructure callStructure,
                                    SourceInformation sourceInformation) {
-
-    return irBuilder.buildCallInvocation(target, callStructure,
-        translateDynamicArguments(arguments, callStructure),
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(target, callStructure, arguments,
         sourceInformation: sourceInformation);
   }
 
@@ -1086,15 +1838,73 @@
   }
 
   @override
+  ir.Primitive handleConstructorInvoke(
+      ast.NewExpression node,
+      ConstructorElement constructor,
+      DartType type,
+      ast.NodeList argumentsNode,
+      CallStructure callStructure,
+      _) {
+
+    // TODO(sigmund): move these checks down after visiting arguments
+    // (see issue #25355)
+    ast.Send send = node.send;
+    // If an allocation refers to a type using a deferred import prefix (e.g.
+    // `new lib.A()`), we must ensure that the deferred import has already been
+    // loaded.
+    var prefix = compiler.deferredLoadTask.deferredPrefixElement(
+        send, elements);
+    if (prefix != null) buildCheckDeferredIsLoaded(prefix, send);
+
+    // We also emit deferred import checks when using redirecting factories that
+    // refer to deferred prefixes.
+    if (constructor.isRedirectingFactory && !constructor.isCyclicRedirection) {
+      ConstructorElement current = constructor;
+      while (current.isRedirectingFactory) {
+        var prefix = current.redirectionDeferredPrefix;
+        if (prefix != null) buildCheckDeferredIsLoaded(prefix, send);
+        current = current.immediateRedirectionTarget;
+      }
+    }
+
+    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
+    // Use default values from the effective target, not the immediate target.
+    ConstructorElement target = constructor.effectiveTarget;
+
+    callStructure = normalizeStaticArguments(callStructure, target, arguments);
+    TypeMask allocationSiteType;
+
+    if (Elements.isFixedListConstructorCall(constructor, send, compiler) ||
+        Elements.isGrowableListConstructorCall(constructor, send, compiler) ||
+        Elements.isFilledListConstructorCall(constructor, send, compiler) ||
+        Elements.isConstructorOfTypedArraySubclass(constructor, compiler)) {
+      allocationSiteType = getAllocationSiteType(send);
+    }
+    return irBuilder.buildConstructorInvocation(
+        target,
+        callStructure,
+        constructor.computeEffectiveTargetType(type),
+        arguments,
+        sourceInformationBuilder.buildNew(node),
+        allocationSiteType: allocationSiteType);
+  }
+
+  @override
   ir.Primitive handleDynamicInvoke(
       ast.Send node,
       ast.Node receiver,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       Selector selector,
       _) {
+    ir.Primitive target = translateReceiver(receiver);
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    CallStructure callStructure = translateDynamicArguments(
+        argumentsNode, selector.callStructure, arguments);
     return irBuilder.buildDynamicInvocation(
-        translateReceiver(receiver), selector, elements.getTypeMask(node),
-        translateDynamicArguments(arguments, selector.callStructure),
+        target,
+        new Selector(selector.kind, selector.memberName, callStructure),
+        elements.getTypeMask(node),
+        arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(node, node.selector));
   }
@@ -1103,39 +1913,37 @@
   ir.Primitive visitIfNotNullDynamicPropertyInvoke(
       ast.Send node,
       ast.Node receiver,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       Selector selector,
       _) {
     ir.Primitive target = visit(receiver);
     return irBuilder.buildIfNotNullSend(
         target,
-        nested(() => irBuilder.buildDynamicInvocation(
-            target, selector, elements.getTypeMask(node),
-            translateDynamicArguments(arguments, selector.callStructure))));
+        nested(() {
+          List<ir.Primitive> arguments = <ir.Primitive>[];
+          CallStructure callStructure = translateDynamicArguments(
+              argumentsNode, selector.callStructure, arguments);
+          return irBuilder.buildDynamicInvocation(
+              target,
+              new Selector(selector.kind, selector.memberName, callStructure),
+              elements.getTypeMask(node),
+              arguments);
+        }));
   }
 
   ir.Primitive handleLocalInvoke(
       ast.Send node,
       LocalElement element,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    return irBuilder.buildLocalVariableInvocation(element, callStructure,
-        translateDynamicArguments(arguments, callStructure),
-        callSourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
-  }
-
-  @override
-  ir.Primitive visitLocalFunctionInvoke(
-      ast.Send node,
-      LocalFunctionElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return irBuilder.buildLocalFunctionInvocation(function, callStructure,
-        translateDynamicArguments(arguments, callStructure),
-        sourceInformationBuilder.buildCall(node, arguments));
+    ir.Primitive function = irBuilder.buildLocalGet(element);
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(function, callStructure, arguments,
+        sourceInformation:
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
@@ -1147,25 +1955,39 @@
   ir.Primitive handleStaticFieldInvoke(
       ast.Send node,
       FieldElement field,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
     SourceInformation src = sourceInformationBuilder.buildGet(node);
     ir.Primitive target = buildStaticFieldGet(field, src);
-    return irBuilder.buildCallInvocation(target,
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(
+        target,
         callStructure,
-        translateDynamicArguments(arguments, callStructure),
+        arguments,
         sourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
-  ir.Primitive handleStaticFunctionInvoke(
-      ast.Send node,
+  ir.Primitive handleStaticFunctionInvoke(ast.Send node,
       MethodElement function,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
-      _);
+      _) {
+    if (compiler.backend.isForeign(function)) {
+      return handleForeignCode(node, function, argumentsNode, callStructure);
+    } else {
+      List<ir.Primitive> arguments = <ir.Primitive>[];
+      callStructure = translateStaticArguments(argumentsNode, function,
+          callStructure, arguments);
+      Selector selector = new Selector.call(function.memberName, callStructure);
+      return irBuilder.buildInvokeStatic(function, selector, arguments,
+          sourceInformationBuilder.buildCall(node, node.selector));
+    }
+  }
 
   @override
   ir.Primitive handleStaticFunctionIncompatibleInvoke(
@@ -1173,7 +1995,7 @@
       MethodElement function,
       ast.NodeList arguments,
       CallStructure callStructure, _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         elements.getSelector(node),
         arguments.nodes.mapToList(visit));
   }
@@ -1182,58 +2004,74 @@
   ir.Primitive handleStaticGetterInvoke(
       ast.Send node,
       FunctionElement getter,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    ir.Primitive target = irBuilder.buildStaticGetterGet(
-        getter, sourceInformationBuilder.buildGet(node));
-    return irBuilder.buildCallInvocation(target,
+    ir.Primitive target = buildStaticGetterGet(getter, node);
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(
+        target,
         callStructure,
-        translateDynamicArguments(arguments, callStructure),
+        arguments,
         sourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
   ir.Primitive visitSuperFieldInvoke(
       ast.Send node,
       FieldElement field,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
     ir.Primitive target = irBuilder.buildSuperFieldGet(field);
-    return irBuilder.buildCallInvocation(target,
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(
+        target,
         callStructure,
-        translateDynamicArguments(arguments, callStructure),
+        arguments,
         sourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
   ir.Primitive visitSuperGetterInvoke(
       ast.Send node,
       FunctionElement getter,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    ir.Primitive target = irBuilder.buildSuperGetterGet(
-        getter, sourceInformationBuilder.buildGet(node));
-    return irBuilder.buildCallInvocation(target,
+    ir.Primitive target = irBuilder.buildSuperGetterGet(getter,
+        sourceInformationBuilder.buildGet(node));
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(
+        target,
         callStructure,
-        translateDynamicArguments(arguments, callStructure),
+        arguments,
         sourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
   ir.Primitive visitSuperMethodInvoke(
       ast.Send node,
       MethodElement method,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    return irBuilder.buildSuperMethodInvocation(method, callStructure,
-        translateDynamicArguments(arguments, callStructure),
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure = translateStaticArguments(argumentsNode, method,
+        callStructure, arguments);
+    return irBuilder.buildSuperMethodInvocation(
+        method,
+        callStructure,
+        arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(node, node.selector));
   }
@@ -1244,22 +2082,30 @@
       MethodElement method,
       ast.NodeList arguments,
       CallStructure callStructure, _) {
+    List<ir.Primitive> normalizedArguments = <ir.Primitive>[];
+    CallStructure normalizedCallStructure =
+      translateDynamicArguments(arguments, callStructure, normalizedArguments);
     return buildInstanceNoSuchMethod(
-        elements.getSelector(node),
+        new Selector.call(method.memberName, normalizedCallStructure),
         elements.getTypeMask(node),
-        translateDynamicArguments(arguments, callStructure));
+        normalizedArguments);
   }
 
   @override
   ir.Primitive visitUnresolvedSuperInvoke(
       ast.Send node,
       Element element,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       Selector selector, _) {
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    CallStructure callStructure = translateDynamicArguments(
+        argumentsNode, selector.callStructure, arguments);
+    // TODO(johnniwinther): Supply a member name to the visit function instead
+    // of looking it up in elements.
     return buildInstanceNoSuchMethod(
-        elements.getSelector(node),
+        new Selector.call(elements.getSelector(node).memberName, callStructure),
         elements.getTypeMask(node),
-        translateDynamicArguments(arguments, selector.callStructure));
+        arguments);
   }
 
   @override
@@ -1313,9 +2159,9 @@
 
   ir.Primitive translateCompounds(
       ast.SendSet node,
-      {ir.Primitive getValue(),
-       CompoundRhs rhs,
-       void setValue(ir.Primitive value)}) {
+      ir.Primitive getValue(),
+      CompoundRhs rhs,
+      void setValue(ir.Primitive value)) {
     ir.Primitive value = getValue();
     op.BinaryOperator operator = rhs.operator;
     if (operator.kind == op.BinaryOperatorKind.IF_NULL) {
@@ -1337,24 +2183,28 @@
       rhsValue = irBuilder.buildIntegerConstant(1);
     }
     List<ir.Primitive> arguments = <ir.Primitive>[rhsValue];
-    arguments = normalizeDynamicArguments(
-        operatorSelector.callStructure, arguments);
+    CallStructure callStructure =
+        normalizeDynamicArguments(operatorSelector.callStructure, arguments);
     TypeMask operatorTypeMask =
         elements.getOperatorTypeMaskInComplexSendSet(node);
     SourceInformation operatorSourceInformation =
         sourceInformationBuilder.buildCall(node, node.assignmentOperator);
     ir.Primitive result = irBuilder.buildDynamicInvocation(
-        value, operatorSelector, operatorTypeMask, arguments,
-            sourceInformation: operatorSourceInformation);
+        value,
+        new Selector(operatorSelector.kind, operatorSelector.memberName,
+            callStructure),
+        operatorTypeMask,
+        arguments,
+        sourceInformation: operatorSourceInformation);
     setValue(result);
     return rhs.kind == CompoundKind.POSTFIX ? value : result;
   }
 
   ir.Primitive translateSetIfNull(
       ast.SendSet node,
-      {ir.Primitive getValue(),
-       ast.Node rhs,
-       void setValue(ir.Primitive value)}) {
+      ir.Primitive getValue(),
+      ast.Node rhs,
+      void setValue(ir.Primitive value)) {
     ir.Primitive value = getValue();
     // Unlike other compound operators if-null conditionally will not do the
     // assignment operation.
@@ -1402,7 +2252,9 @@
       LocalElement element,
       ast.Node rhs,
       _) {
-    return irBuilder.buildLocalVariableSet(element, visit(rhs));
+    ir.Primitive value = visit(rhs);
+    value = checkTypeVsElement(value, element);
+    return irBuilder.buildLocalVariableSet(element, value);
   }
 
   @override
@@ -1411,7 +2263,9 @@
       FieldElement field,
       ast.Node rhs,
       _) {
-    return irBuilder.buildStaticFieldSet(field, visit(rhs));
+    ir.Primitive value = visit(rhs);
+    irBuilder.addPrimitive(new ir.SetStatic(field, value));
+    return value;
   }
 
   @override
@@ -1457,14 +2311,12 @@
       ConstantExpression constant,
       CompoundRhs rhs,
       arg) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          return buildConstantExpression(constant,
-            sourceInformationBuilder.buildGet(node));
-        },
-        rhs: rhs,
-        setValue: (value) {}); // The binary operator will throw before this.
+    SourceInformation src = sourceInformationBuilder.buildGet(node);
+    return translateCompounds(node, () {
+      return buildConstantExpression(constant, src);
+    }, rhs, (ir.Primitive value) {
+      // The binary operator will throw before this.
+    });
   }
 
   @override
@@ -1487,21 +2339,19 @@
       arg) {
     ir.Primitive target = translateReceiver(receiver);
     ir.Primitive helper() {
-      return translateCompounds(
-          node,
-          getValue: () => irBuilder.buildDynamicGet(
-              target,
-              new Selector.getter(name),
-              elements.getGetterTypeMaskInComplexSendSet(node),
-              sourceInformationBuilder.buildGet(node)),
-          rhs: rhs,
-          setValue: (ir.Primitive result) {
-            irBuilder.buildDynamicSet(
-                target,
-                new Selector.setter(name),
-                elements.getTypeMask(node),
-                result);
-          });
+      return translateCompounds(node, () {
+        return irBuilder.buildDynamicGet(
+            target,
+            new Selector.getter(name),
+            elements.getGetterTypeMaskInComplexSendSet(node),
+            sourceInformationBuilder.buildGet(node));
+      }, rhs, (ir.Primitive result) {
+        irBuilder.buildDynamicSet(
+            target,
+            new Selector.setter(name),
+            elements.getTypeMask(node),
+            result);
+      });
     }
     return node.isConditional
         ? irBuilder.buildIfNotNullSend(target, nested(helper))
@@ -1517,21 +2367,19 @@
       _) {
     ir.Primitive target = translateReceiver(receiver);
     ir.Primitive helper() {
-      return translateSetIfNull(
-          node,
-          getValue: () => irBuilder.buildDynamicGet(
-              target,
-              new Selector.getter(name),
-              elements.getGetterTypeMaskInComplexSendSet(node),
-              sourceInformationBuilder.buildGet(node)),
-          rhs: rhs,
-          setValue: (ir.Primitive result) {
-            irBuilder.buildDynamicSet(
-                target,
-                new Selector.setter(name),
-                elements.getTypeMask(node),
-                result);
-          });
+      return translateSetIfNull(node, () {
+        return irBuilder.buildDynamicGet(
+            target,
+            new Selector.getter(name),
+            elements.getGetterTypeMaskInComplexSendSet(node),
+            sourceInformationBuilder.buildGet(node));
+      }, rhs, (ir.Primitive result) {
+        irBuilder.buildDynamicSet(
+            target,
+            new Selector.setter(name),
+            elements.getTypeMask(node),
+            result);
+      });
     }
     return node.isConditional
         ? irBuilder.buildIfNotNullSend(target, nested(helper))
@@ -1541,7 +2389,7 @@
   ir.Primitive buildLocalNoSuchSetter(LocalElement local, ir.Primitive value) {
     Selector selector = new Selector.setter(
         new Name(local.name, local.library, isSetter: true));
-    return buildStaticNoSuchMethod(selector, [value]);
+    return irBuilder.buildStaticNoSuchMethod(selector, [value]);
   }
 
   @override
@@ -1551,23 +2399,17 @@
       CompoundRhs rhs,
       arg,
       {bool isSetterValid}) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          if (local.isFunction) {
-            return irBuilder.buildLocalFunctionGet(local);
-          } else {
-            return irBuilder.buildLocalVariableGet(local);
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          if (isSetterValid) {
-            irBuilder.buildLocalVariableSet(local, result);
-          } else {
-            return buildLocalNoSuchSetter(local, result);
-          }
-        });
+    return translateCompounds(node, () {
+      return irBuilder.buildLocalGet(local);
+    }, rhs, (ir.Primitive result) {
+      if (isSetterValid) {
+        irBuilder.buildLocalVariableSet(local, result);
+      } else {
+        Selector selector = new Selector.setter(
+            new Name(local.name, local.library, isSetter: true));
+        irBuilder.buildStaticNoSuchMethod(selector, <ir.Primitive>[result]);
+      }
+    });
   }
 
   @override
@@ -1577,35 +2419,17 @@
       ast.Node rhs,
       _,
       {bool isSetterValid}) {
-    return translateSetIfNull(
-        node,
-        getValue: () {
-          if (local.isFunction) {
-            return irBuilder.buildLocalFunctionGet(local);
-          } else {
-            return irBuilder.buildLocalVariableGet(local);
-          }
-        },
-        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(new Name(element.name, element.library)),
-        const <ir.Primitive>[]);
-  }
-
-  ir.Primitive buildStaticNoSuchSetter(Element element, ir.Primitive value) {
-    return buildStaticNoSuchMethod(
-        new Selector.setter(new Name(element.name, element.library)),
-        <ir.Primitive>[value]);
+    return translateSetIfNull(node, () {
+      return irBuilder.buildLocalGet(local);
+    }, rhs, (ir.Primitive result) {
+      if (isSetterValid) {
+        irBuilder.buildLocalVariableSet(local, result);
+      } else {
+        Selector selector = new Selector.setter(
+            new Name(local.name, local.library, isSetter: true));
+        irBuilder.buildStaticNoSuchMethod(selector, <ir.Primitive>[result]);
+      }
+    });
   }
 
   @override
@@ -1617,33 +2441,35 @@
       CompoundSetter setterKind,
       CompoundRhs rhs,
       arg) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              SourceInformation src = sourceInformationBuilder.buildGet(node);
-              return irBuilder.buildStaticFieldGet(getter, src);
-            case CompoundGetter.GETTER:
-              return irBuilder.buildStaticGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildStaticFunctionGet(getter);
-            case CompoundGetter.UNRESOLVED:
-              return buildStaticNoSuchGetter(getter);
-          }
-        },
-        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:
-              return buildStaticNoSuchSetter(setter, result);
-          }
-        });
+    return translateCompounds(node, () {
+      switch (getterKind) {
+        case CompoundGetter.FIELD:
+          SourceInformation src = sourceInformationBuilder.buildGet(node);
+          return buildStaticFieldGet(getter, src);
+        case CompoundGetter.GETTER:
+          return buildStaticGetterGet(getter, node);
+        case CompoundGetter.METHOD:
+          return irBuilder.addPrimitive(new ir.GetStatic(getter));
+        case CompoundGetter.UNRESOLVED:
+          return irBuilder.buildStaticNoSuchMethod(
+              new Selector.getter(new Name(getter.name, getter.library)),
+              <ir.Primitive>[]);
+      }
+    }, rhs, (ir.Primitive result) {
+      switch (setterKind) {
+        case CompoundSetter.FIELD:
+          irBuilder.addPrimitive(new ir.SetStatic(setter, result));
+          return;
+        case CompoundSetter.SETTER:
+          irBuilder.buildStaticSetterSet(setter, result);
+          return;
+        case CompoundSetter.INVALID:
+          irBuilder.buildStaticNoSuchMethod(
+              new Selector.setter(new Name(setter.name, setter.library)),
+              <ir.Primitive>[result]);
+          return;
+      }
+    });
   }
 
   @override
@@ -1655,33 +2481,35 @@
       CompoundSetter setterKind,
       ast.Node rhs,
       _) {
-    return translateSetIfNull(
-        node,
-        getValue: () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              SourceInformation src = sourceInformationBuilder.buildGet(node);
-              return irBuilder.buildStaticFieldGet(getter, src);
-            case CompoundGetter.GETTER:
-              return irBuilder.buildStaticGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildStaticFunctionGet(getter);
-            case CompoundGetter.UNRESOLVED:
-              return buildStaticNoSuchGetter(getter);
-          }
-        },
-        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:
-              return buildStaticNoSuchSetter(setter, result);
-          }
-        });
+    return translateSetIfNull(node, () {
+      switch (getterKind) {
+        case CompoundGetter.FIELD:
+          SourceInformation src = sourceInformationBuilder.buildGet(node);
+          return buildStaticFieldGet(getter, src);
+        case CompoundGetter.GETTER:
+          return buildStaticGetterGet(getter, node);
+        case CompoundGetter.METHOD:
+          return irBuilder.addPrimitive(new ir.GetStatic(getter));
+        case CompoundGetter.UNRESOLVED:
+          return irBuilder.buildStaticNoSuchMethod(
+              new Selector.getter(new Name(getter.name, getter.library)),
+              <ir.Primitive>[]);
+      }
+    }, rhs, (ir.Primitive result) {
+      switch (setterKind) {
+        case CompoundSetter.FIELD:
+          irBuilder.addPrimitive(new ir.SetStatic(setter, result));
+          return;
+        case CompoundSetter.SETTER:
+          irBuilder.buildStaticSetterSet(setter, result);
+          return;
+        case CompoundSetter.INVALID:
+          irBuilder.buildStaticNoSuchMethod(
+              new Selector.setter(new Name(setter.name, setter.library)),
+              <ir.Primitive>[result]);
+          return;
+      }
+    });
   }
 
   ir.Primitive buildSuperNoSuchGetter(Element element, TypeMask mask) {
@@ -1709,35 +2537,33 @@
       CompoundSetter setterKind,
       CompoundRhs rhs,
       arg) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              return irBuilder.buildSuperFieldGet(getter);
-            case CompoundGetter.GETTER:
-              return irBuilder.buildSuperGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildSuperMethodGet(getter);
-            case CompoundGetter.UNRESOLVED:
-              return buildSuperNoSuchGetter(
-                  getter,
-                  elements.getGetterTypeMaskInComplexSendSet(node));
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive 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, elements.getTypeMask(node), result);
-          }
-        });
+    return translateCompounds(node, () {
+      switch (getterKind) {
+        case CompoundGetter.FIELD:
+          return irBuilder.buildSuperFieldGet(getter);
+        case CompoundGetter.GETTER:
+          return irBuilder.buildSuperGetterGet(
+              getter, sourceInformationBuilder.buildGet(node));
+        case CompoundGetter.METHOD:
+          return irBuilder.buildSuperMethodGet(getter);
+        case CompoundGetter.UNRESOLVED:
+          return buildSuperNoSuchGetter(
+              getter, elements.getGetterTypeMaskInComplexSendSet(node));
+      }
+    }, rhs, (ir.Primitive result) {
+      switch (setterKind) {
+        case CompoundSetter.FIELD:
+          irBuilder.buildSuperFieldSet(setter, result);
+          return;
+        case CompoundSetter.SETTER:
+          irBuilder.buildSuperSetterSet(setter, result);
+          return;
+        case CompoundSetter.INVALID:
+          buildSuperNoSuchSetter(
+              setter, elements.getTypeMask(node), result);
+          return;
+      }
+    });
   }
 
   @override
@@ -1749,35 +2575,34 @@
       CompoundSetter setterKind,
       ast.Node rhs,
       _) {
-    return translateSetIfNull(
-        node,
-        getValue: () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              return irBuilder.buildSuperFieldGet(getter);
-            case CompoundGetter.GETTER:
-              return irBuilder.buildSuperGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildSuperMethodGet(getter);
-            case CompoundGetter.UNRESOLVED:
-              return buildSuperNoSuchGetter(
-                  getter,
-                  elements.getGetterTypeMaskInComplexSendSet(node));
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive 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, elements.getTypeMask(node), result);
-          }
-        });
+    return translateSetIfNull(node, () {
+      switch (getterKind) {
+        case CompoundGetter.FIELD:
+          return irBuilder.buildSuperFieldGet(getter);
+        case CompoundGetter.GETTER:
+          return irBuilder.buildSuperGetterGet(
+              getter, sourceInformationBuilder.buildGet(node));
+        case CompoundGetter.METHOD:
+          return irBuilder.buildSuperMethodGet(getter);
+        case CompoundGetter.UNRESOLVED:
+          return buildSuperNoSuchGetter(
+              getter,
+              elements.getGetterTypeMaskInComplexSendSet(node));
+      }
+    }, rhs, (ir.Primitive result) {
+      switch (setterKind) {
+        case CompoundSetter.FIELD:
+          irBuilder.buildSuperFieldSet(setter, result);
+          return;
+        case CompoundSetter.SETTER:
+          irBuilder.buildSuperSetterSet(setter, result);
+          return;
+        case CompoundSetter.INVALID:
+          buildSuperNoSuchSetter(
+              setter, elements.getTypeMask(node), result);
+          return;
+      }
+    });
   }
 
   @override
@@ -1786,15 +2611,13 @@
       TypeVariableElement typeVariable,
       CompoundRhs rhs,
       arg) {
-    return translateCompounds(
-        node,
-        getValue: () {
-          return irBuilder.buildReifyTypeVariable(
-            typeVariable.type,
-            sourceInformationBuilder.buildGet(node));
-        },
-        rhs: rhs,
-        setValue: (value) {}); // The binary operator will throw before this.
+    return translateCompounds(node, () {
+      return irBuilder.buildReifyTypeVariable(
+          typeVariable.type,
+          sourceInformationBuilder.buildGet(node));
+    }, rhs, (ir.Primitive value) {
+      // The binary operator will throw before this.
+    });
   }
 
   @override
@@ -1817,29 +2640,25 @@
       arg) {
     ir.Primitive target = visit(receiver);
     ir.Primitive indexValue = visit(index);
-    return translateCompounds(
-        node,
-        getValue: () {
-          Selector selector = new Selector.index();
-          List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
-          arguments =
-              normalizeDynamicArguments(selector.callStructure, arguments);
-          return irBuilder.buildDynamicInvocation(
-              target,
-              selector,
-              elements.getGetterTypeMaskInComplexSendSet(node),
-              arguments,
-              sourceInformation:
-                  sourceInformationBuilder.buildCall(receiver, node));
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildDynamicIndexSet(
-              target,
-              elements.getTypeMask(node),
-              indexValue,
-              result);
-        });
+    return translateCompounds(node, () {
+      Selector selector = new Selector.index();
+      List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
+      CallStructure callStructure =
+          normalizeDynamicArguments(selector.callStructure, arguments);
+      return irBuilder.buildDynamicInvocation(
+          target,
+          new Selector(selector.kind, selector.memberName, callStructure),
+          elements.getGetterTypeMaskInComplexSendSet(node),
+          arguments,
+          sourceInformation:
+          sourceInformationBuilder.buildCall(receiver, node));
+    }, rhs, (ir.Primitive result) {
+      irBuilder.buildDynamicIndexSet(
+          target,
+          elements.getTypeMask(node),
+          indexValue,
+          result);
+    });
   }
 
   @override
@@ -1853,29 +2672,260 @@
       {bool isGetterValid,
        bool isSetterValid}) {
     ir.Primitive indexValue = visit(index);
-    return translateCompounds(
-        node,
-        getValue: () {
-          if (isGetterValid) {
-            return irBuilder.buildSuperIndex(indexFunction, indexValue);
-          } else {
-            return buildInstanceNoSuchMethod(
-                new Selector.index(),
-                elements.getGetterTypeMaskInComplexSendSet(node),
-                <ir.Primitive>[indexValue]);
-          }
-        },
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          if (isSetterValid) {
-            irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result);
-          } else {
-            buildInstanceNoSuchMethod(
-                new Selector.indexSet(),
-                elements.getTypeMask(node),
-                <ir.Primitive>[indexValue, result]);
-          }
-        });
+    return translateCompounds(node, () {
+      return isGetterValid
+          ? irBuilder.buildSuperIndex(indexFunction, indexValue)
+          : buildInstanceNoSuchMethod(
+              new Selector.index(),
+              elements.getGetterTypeMaskInComplexSendSet(node),
+              <ir.Primitive>[indexValue]);
+    }, rhs, (ir.Primitive result) {
+      if (isSetterValid) {
+        irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result);
+      } else {
+        buildInstanceNoSuchMethod(
+            new Selector.indexSet(),
+            elements.getTypeMask(node),
+            <ir.Primitive>[indexValue, result]);
+      }
+    });
+  }
+
+  /// Build code to handle foreign code, that is, native JavaScript code, or
+  /// builtin values and operations of the backend.
+  ir.Primitive handleForeignCode(ast.Send node,
+      MethodElement function,
+      ast.NodeList argumentList,
+      CallStructure callStructure) {
+
+    void validateArgumentCount({int minimum, int exactly}) {
+      assert((minimum == null) != (exactly == null));
+      int count = 0;
+      int maximum;
+      if (exactly != null) {
+        minimum = exactly;
+        maximum = exactly;
+      }
+      for (ast.Node argument in argumentList) {
+        count++;
+        if (maximum != null && count > maximum) {
+          internalError(argument, 'Additional argument.');
+        }
+      }
+      if (count < minimum) {
+        internalError(node, 'Expected at least $minimum arguments.');
+      }
+    }
+
+    /// Call a helper method from the isolate library. The isolate library uses
+    /// its own isolate structure, that encapsulates dart2js's isolate.
+    ir.Primitive buildIsolateHelperInvocation(MethodElement element,
+        CallStructure callStructure) {
+      if (element == null) {
+        reporter.internalError(node,
+            'Isolate library and compiler mismatch.');
+      }
+      List<ir.Primitive> arguments = <ir.Primitive>[];
+      callStructure = translateStaticArguments(argumentList, element,
+          callStructure, arguments);
+      Selector selector = new Selector.call(element.memberName, callStructure);
+      return irBuilder.buildInvokeStatic(element, selector, arguments,
+          sourceInformationBuilder.buildCall(node, node.selector));
+    }
+
+    /// Lookup the value of the enum described by [node].
+    getEnumValue(ast.Node node, EnumClassElement enumClass, List values) {
+      Element element = elements[node];
+      if (element is! FieldElement || element.enclosingClass != enumClass) {
+        internalError(node, 'expected a JsBuiltin enum value');
+      }
+
+      int index = enumClass.enumValues.indexOf(element);
+      return values[index];
+    }
+
+    /// Returns the String the node evaluates to, or throws an error if the
+    /// result is not a string constant.
+    String expectStringConstant(ast.Node node) {
+      ir.Primitive nameValue = visit(node);
+      if (nameValue is ir.Constant && nameValue.value.isString) {
+        StringConstantValue constantValue = nameValue.value;
+        return constantValue.primitiveValue.slowToString();
+      } else {
+        return internalError(node, 'expected a literal string');
+      }
+    }
+
+    Link<ast.Node> argumentNodes  = argumentList.nodes;
+    NativeBehavior behavior =
+    compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
+    switch (function.name) {
+      case 'JS':
+        validateArgumentCount(minimum: 2);
+        // The first two arguments are the type and the foreign code template,
+        // which already have been analyzed by the resolver and can be retrieved
+        // using [NativeBehavior]. We can ignore these arguments in the backend.
+        List<ir.Primitive> arguments =
+        argumentNodes.skip(2).mapToList(visit, growable: false);
+        if (behavior.codeTemplate.positionalArgumentCount != arguments.length) {
+          reporter.reportErrorMessage(
+              node, MessageKind.GENERIC,
+              {'text':
+              'Mismatch between number of placeholders'
+                  ' and number of arguments.'});
+          return irBuilder.buildNullConstant();
+        }
+
+        if (HasCapturedPlaceholders.check(behavior.codeTemplate.ast)) {
+          reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE);
+          return irBuilder.buildNullConstant();
+        }
+
+        return irBuilder.buildForeignCode(behavior.codeTemplate, arguments,
+            behavior);
+
+      case 'DART_CLOSURE_TO_JS':
+      // TODO(ahe): This should probably take care to wrap the closure in
+      // another closure that saves the current isolate.
+      case 'RAW_DART_FUNCTION_REF':
+        validateArgumentCount(exactly: 1);
+
+        ast.Node argument = node.arguments.single;
+        FunctionElement closure = elements[argument].implementation;
+        if (!Elements.isStaticOrTopLevelFunction(closure)) {
+          internalError(argument,
+              'only static or toplevel function supported');
+        }
+        if (closure.functionSignature.hasOptionalParameters) {
+          internalError(argument,
+              'closures with optional parameters not supported');
+        }
+        return irBuilder.buildForeignCode(
+            js.js.expressionTemplateYielding(
+                backend.emitter.staticFunctionAccess(closure)),
+            <ir.Primitive>[],
+            NativeBehavior.PURE,
+            dependency: closure);
+
+      case 'JS_BUILTIN':
+      // The first argument is a description of the type and effect of the
+      // builtin, which has already been analyzed in the frontend.  The second
+      // argument must be a [JsBuiltin] value.  All other arguments are
+      // values used by the JavaScript template that is associated with the
+      // builtin.
+        validateArgumentCount(minimum: 2);
+
+        ast.Node builtin = argumentNodes.tail.head;
+        JsBuiltin value = getEnumValue(builtin, helpers.jsBuiltinEnum,
+            JsBuiltin.values);
+        js.Template template = backend.emitter.builtinTemplateFor(value);
+        List<ir.Primitive> arguments =
+        argumentNodes.skip(2).mapToList(visit, growable: false);
+        return irBuilder.buildForeignCode(template, arguments, behavior);
+
+      case 'JS_EMBEDDED_GLOBAL':
+        validateArgumentCount(exactly: 2);
+
+        String name = expectStringConstant(argumentNodes.tail.head);
+        js.Expression access =
+        backend.emitter.generateEmbeddedGlobalAccess(name);
+        js.Template template = js.js.expressionTemplateYielding(access);
+        return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior);
+
+      case 'JS_INTERCEPTOR_CONSTANT':
+        validateArgumentCount(exactly: 1);
+
+        ast.Node argument = argumentNodes.head;
+        ir.Primitive argumentValue = visit(argument);
+        if (argumentValue is ir.Constant && argumentValue.value.isType) {
+          TypeConstantValue constant = argumentValue.value;
+          ConstantValue interceptorValue =
+          new InterceptorConstantValue(constant.representedType);
+          return irBuilder.buildConstant(interceptorValue);
+        }
+        return internalError(argument, 'expected Type as argument');
+
+      case 'JS_EFFECT':
+        return irBuilder.buildNullConstant();
+
+      case 'JS_GET_NAME':
+        validateArgumentCount(exactly: 1);
+
+        ast.Node argument = argumentNodes.head;
+        JsGetName id = getEnumValue(argument, helpers.jsGetNameEnum,
+            JsGetName.values);
+        js.Name name = backend.namer.getNameForJsGetName(argument, id);
+        ConstantValue nameConstant =
+        new SyntheticConstantValue(SyntheticConstantKind.NAME,
+            js.js.quoteName(name));
+
+        return irBuilder.buildConstant(nameConstant);
+
+      case 'JS_GET_FLAG':
+        validateArgumentCount(exactly: 1);
+
+        String name = expectStringConstant(argumentNodes.first);
+        bool value = false;
+        switch (name) {
+          case 'MUST_RETAIN_METADATA':
+            value = backend.mustRetainMetadata;
+            break;
+          case 'USE_CONTENT_SECURITY_POLICY':
+            value = compiler.useContentSecurityPolicy;
+            break;
+          default:
+            internalError(node, 'Unknown internal flag "$name".');
+        }
+        return irBuilder.buildBooleanConstant(value);
+
+      case 'JS_STRING_CONCAT':
+        validateArgumentCount(exactly: 2);
+        List<ir.Primitive> arguments = argumentNodes.mapToList(visit);
+        return irBuilder.buildStringConcatenation(arguments);
+
+      case 'JS_CURRENT_ISOLATE_CONTEXT':
+        validateArgumentCount(exactly: 0);
+
+        if (!compiler.hasIsolateSupport) {
+          // If the isolate library is not used, we just generate code
+          // to fetch the current isolate.
+          continue getStaticState;
+        }
+        return buildIsolateHelperInvocation(helpers.currentIsolate,
+            CallStructure.NO_ARGS);
+
+      getStaticState: case 'JS_GET_STATIC_STATE':
+        validateArgumentCount(exactly: 0);
+
+        return irBuilder.buildForeignCode(
+            js.js.parseForeignJS(backend.namer.staticStateHolder),
+            const <ir.Primitive>[],
+            NativeBehavior.PURE);
+
+      case 'JS_SET_STATIC_STATE':
+        validateArgumentCount(exactly: 1);
+
+        ir.Primitive value = visit(argumentNodes.single);
+        String isolateName = backend.namer.staticStateHolder;
+        return irBuilder.buildForeignCode(
+            js.js.parseForeignJS("$isolateName = #"),
+            <ir.Primitive>[value],
+            NativeBehavior.PURE);
+
+      case 'JS_CALL_IN_ISOLATE':
+        validateArgumentCount(exactly: 2);
+
+        if (!compiler.hasIsolateSupport) {
+          ir.Primitive closure = visit(argumentNodes.tail.head);
+          return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS,
+              const <ir.Primitive>[]);
+        }
+        return buildIsolateHelperInvocation(helpers.callInIsolate,
+            CallStructure.TWO_ARGS);
+
+      default:
+        return giveup(node, 'unplemented native construct: ${function.name}');
+    }
   }
 
   /// Evaluates a string interpolation and appends each part to [accumulator]
@@ -1900,7 +2950,9 @@
       buildStringParts(node.expression, accumulator);
     } else {
       ir.Primitive value = visit(node);
-      accumulator.add(irBuilder.buildStringify(value));
+      accumulator.add(irBuilder.buildStaticFunctionInvocation(
+          helpers.stringInterpolationHelper,
+          <ir.Primitive>[value]));
     }
   }
 
@@ -1932,18 +2984,15 @@
     return irBuilder.buildNonTailThrow(visit(node.expression));
   }
 
-  ir.Primitive buildStaticNoSuchMethod(
-      Selector selector,
-      List<ir.Primitive> arguments);
-
-  ir.Primitive buildInstanceNoSuchMethod(
-      Selector selector,
+  ir.Primitive buildInstanceNoSuchMethod(Selector selector,
       TypeMask mask,
-      List<ir.Primitive> arguments);
-
-  ir.Primitive buildRuntimeError(String message);
-
-  ir.Primitive buildAbstractClassInstantiationError(ClassElement element);
+      List<ir.Primitive> arguments) {
+    return irBuilder.buildDynamicInvocation(
+        irBuilder.buildThis(),
+        Selectors.noSuchMethod_,
+        mask,
+        [irBuilder.buildInvocationMirror(selector, arguments)]);
+  }
 
   @override
   ir.Primitive visitUnresolvedCompound(
@@ -1953,7 +3002,7 @@
       ast.Node rhs, _) {
     // TODO(asgerf): What is unresolved? The getter and/or the setter?
     //               If it was the setter, we must evaluate the right-hand side.
-    return buildStaticNoSuchMethod(elements.getSelector(node), []);
+    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), []);
   }
 
   @override
@@ -1964,7 +3013,11 @@
       ast.NodeList arguments,
       Selector selector, _) {
     // If the class is missing it's a runtime error.
-    return buildRuntimeError("Unresolved class: '${element.name}'");
+    ir.Primitive message =
+        irBuilder.buildStringConstant("Unresolved class: '${element.name}'");
+    return irBuilder.buildStaticFunctionInvocation(
+        helpers.throwRuntimeError,
+        <ir.Primitive>[message]);
   }
 
   @override
@@ -1972,29 +3025,36 @@
       ast.NewExpression node,
       Element constructor,
       DartType type,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       Selector selector, _) {
     // If the class is there but the constructor is missing, it's an NSM error.
-    return buildStaticNoSuchMethod(selector,
-        translateDynamicArguments(arguments, selector.callStructure));
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    CallStructure callStructure = translateDynamicArguments(
+        argumentsNode, selector.callStructure, arguments);
+    return irBuilder.buildStaticNoSuchMethod(
+        new Selector(selector.kind, selector.memberName, callStructure),
+        arguments);
   }
 
   @override
   ir.Primitive visitConstructorIncompatibleInvoke(
       ast.NewExpression node,
-      Element constructor,
+      ConstructorElement constructor,
       DartType type,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure, _) {
-    return buildStaticNoSuchMethod(elements.getSelector(node.send),
-        translateDynamicArguments(arguments, callStructure));
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildStaticNoSuchMethod(
+        new Selector.call(constructor.memberName, callStructure), arguments);
   }
 
   @override
   ir.Primitive visitUnresolvedGet(
       ast.Send node,
       Element element, _) {
-    return buildStaticNoSuchMethod(elements.getSelector(node), []);
+    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), []);
   }
 
   @override
@@ -2003,7 +3063,7 @@
       Element element,
       ast.NodeList arguments,
       Selector selector, _) {
-    return buildStaticNoSuchMethod(elements.getSelector(node),
+    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node),
         arguments.nodes.mapToList(visit));
   }
 
@@ -2012,13 +3072,16 @@
        ast.NewExpression node,
        ConstructorElement constructor,
        InterfaceType type,
-       ast.NodeList arguments,
+       ast.NodeList argumentsNode,
        CallStructure callStructure, _) {
     String nameString = Elements.reconstructConstructorName(constructor);
     Name name = new Name(nameString, constructor.library);
-    return buildStaticNoSuchMethod(
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.call(name, callStructure),
-        translateDynamicArguments(arguments, callStructure));
+        arguments);
   }
 
   @override
@@ -2026,7 +3089,8 @@
       ast.Send node,
       Element element,
       ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(elements.getSelector(node), [visit(rhs)]);
+    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node),
+        [visit(rhs)]);
   }
 
   @override
@@ -2077,7 +3141,7 @@
       ast.Node rhs, _) {
     InterfaceType type = constant.type;
     ClassElement element = type.element;
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(element.memberName),
         [visit(rhs)]);
   }
@@ -2089,7 +3153,7 @@
       ast.Node rhs, _) {
     TypedefType type = constant.type;
     TypedefElement element = type.element;
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(element.memberName),
         [visit(rhs)]);
   }
@@ -2099,7 +3163,7 @@
       ast.SendSet node,
       TypeVariableElement element,
       ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(element.memberName), [visit(rhs)]);
   }
 
@@ -2108,7 +3172,7 @@
       ast.SendSet node,
       ConstantExpression constant,
       ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(Names.dynamic_), [visit(rhs)]);
   }
 
@@ -2119,7 +3183,12 @@
       InterfaceType type,
       ast.NodeList arguments,
       CallStructure callStructure, _) {
-    return buildAbstractClassInstantiationError(element.enclosingClass);
+    for (ast.Node argument in arguments) visit(argument);
+    ir.Primitive name =
+        irBuilder.buildStringConstant(element.enclosingClass.name);
+    return irBuilder.buildStaticFunctionInvocation(
+        helpers.throwAbstractClassInstantiationError,
+        <ir.Primitive>[name]);
   }
 
   @override
@@ -2128,7 +3197,7 @@
       FieldElement field,
       ast.Node rhs, _) {
     // TODO(asgerf): Include class name somehow for static class members?
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(field.memberName),
         [visit(rhs)]);
   }
@@ -2149,7 +3218,7 @@
       ast.SendSet node,
       LocalElement local,
       ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(new Name(local.name, local.library)),
         [visit(rhs)]);
   }
@@ -2160,7 +3229,7 @@
       MethodElement function,
       ast.Node rhs,
       _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(function.memberName),
         [visit(rhs)]);
   }
@@ -2171,7 +3240,7 @@
       GetterElement getter,
       ast.Node rhs,
       _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(getter.memberName),
         [visit(rhs)]);
   }
@@ -2181,7 +3250,7 @@
       ast.Send node,
       SetterElement setter,
       _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.getter(setter.memberName),
         []);
   }
@@ -2190,13 +3259,13 @@
   ir.Primitive handleStaticSetterInvoke(
       ast.Send node,
       SetterElement setter,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure, _) {
     // Translate as a method call.
-    List<ir.Primitive> args = arguments.nodes.mapToList(visit);
-    return buildStaticNoSuchMethod(
+    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.call(setter.memberName, callStructure),
-        args);
+        arguments);
   }
 
   @override
@@ -2237,14 +3306,15 @@
   ir.Primitive visitSuperSetterInvoke(
       ast.Send node,
       SetterElement setter,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure, _) {
-    List<ir.Primitive> args =
-        translateDynamicArguments(arguments, callStructure);
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
     return buildInstanceNoSuchMethod(
         new Selector.call(setter.memberName, callStructure),
         elements.getTypeMask(node),
-        args);
+        arguments);
   }
 
   ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
@@ -2275,16 +3345,11 @@
 
 final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
 
-/// Classifies local variables and local functions as captured, if they
-/// are accessed from within a nested function.
-///
-/// This class is specific to the [DartIrBuilder], in that it gives up if it
-/// sees a feature that is currently unsupport by that builder. In particular,
-/// loop variables captured in a for-loop initializer, condition, or update
-/// expression are unsupported.
-class DartCapturedVariables extends ast.Visitor {
+/// Determines which local variables should be boxed in a mutable variable
+/// inside a given try block.
+class TryBoxedVariables extends ast.Visitor {
   final TreeElements elements;
-  DartCapturedVariables(this.elements);
+  TryBoxedVariables(this.elements);
 
   FunctionElement currentFunction;
   bool insideInitializer = false;
@@ -2330,25 +3395,6 @@
     node.visitChildren(this);
   }
 
-  visitFor(ast.For node) {
-    if (node.initializer != null) visit(node.initializer);
-    if (node.condition != null) visit(node.condition);
-    if (node.update != null) visit(node.update);
-
-    // Give up if a variable was captured outside of the loop body.
-    if (node.initializer is ast.VariableDefinitions) {
-      ast.VariableDefinitions definitions = node.initializer;
-      for (ast.Node node in definitions.definitions.nodes) {
-        LocalElement loopVariable = elements[node];
-        if (capturedVariables.contains(loopVariable)) {
-          return giveup(node, 'For-loop variable captured in loop header');
-        }
-      }
-    }
-
-    if (node.body != null) visit(node.body);
-  }
-
   void handleSend(ast.Send node) {
     Element element = elements[node];
     if (Elements.isLocal(element) &&
@@ -2406,18 +3452,14 @@
     if (currentFunction.asyncMarker != AsyncMarker.SYNC &&
         currentFunction.asyncMarker != AsyncMarker.SYNC_STAR &&
         currentFunction.asyncMarker != AsyncMarker.ASYNC) {
-      giveup(node, "cannot handle sync*/async* functions");
+      giveup(node, "cannot handle async* functions");
     }
 
-    bool savedInsideInitializer = insideInitializer;
     if (node.initializers != null) {
-      insideInitializer = true;
       visit(node.initializers);
     }
-    insideInitializer = false;
     visit(node.body);
     currentFunction = savedFunction;
-    insideInitializer = savedInsideInitializer;
   }
 
   visitTryStatement(ast.TryStatement node) {
@@ -2488,13 +3530,10 @@
     return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls);
   }
 
-  FunctionElement get stringifyFunction {
-    return _backend.helpers.stringInterpolationHelper;
-  }
-
   FunctionElement get throwTypeErrorHelper => _backend.helpers.throwTypeError;
+  Element get throwNoSuchMethod => _backend.helpers.throwNoSuchMethod;
 
-  ClassElement get nullClass => _compiler.nullClass;
+  ClassElement get nullClass => _compiler.coreClasses.nullClass;
 
   DartType unaliasType(DartType type) => type.unaliased;
 
@@ -2517,1069 +3556,3 @@
     _backend.emitter.nativeEmitter.nativeMethods.add(function);
   }
 }
-
-/// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder].
-class JsIrBuilderVisitor extends IrBuilderVisitor {
-  JavaScriptBackend get backend => compiler.backend;
-
-  /// Result of closure conversion for the current body of code.
-  ///
-  /// Will be initialized upon entering the body of a function.
-  /// It is computed by the [ClosureTranslator].
-  ClosureClassMap closureClassMap;
-
-  JsIrBuilderVisitor(TreeElements elements,
-                     Compiler compiler,
-                     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) {
-    ClosureClassMap innerMap =
-        compiler.closureToClassMapper.getMappingForNestedFunction(node);
-    ClosureClassElement closureClass = innerMap.closureClassElement;
-    return closureClass;
-  }
-
-  ir.Primitive visitFunctionExpression(ast.FunctionExpression node) {
-    return irBuilder.buildFunctionExpression(makeSubFunction(node),
-        sourceInformationBuilder.buildCreate(node));
-  }
-
-  visitFunctionDeclaration(ast.FunctionDeclaration node) {
-    LocalFunctionElement element = elements[node.function];
-    Object inner = makeSubFunction(node.function);
-    irBuilder.declareLocalFunction(element, inner,
-        sourceInformationBuilder.buildCreate(node.function));
-  }
-
-  Map mapValues(Map map, dynamic fn(dynamic)) {
-    Map result = {};
-    map.forEach((key, value) {
-      result[key] = fn(value);
-    });
-    return result;
-  }
-
-  /// Converts closure.dart's CapturedVariable into a ClosureLocation.
-  /// There is a 1:1 corresponce between these; we do this because the
-  /// IR builder should not depend on synthetic elements.
-  ClosureLocation getLocation(CapturedVariable v) {
-    if (v is BoxFieldElement) {
-      return new ClosureLocation(v.box, v);
-    } else {
-      ClosureFieldElement field = v;
-      return new ClosureLocation(null, field);
-    }
-  }
-
-  /// If the current function is a nested function with free variables (or a
-  /// captured reference to `this`), returns a [ClosureEnvironment]
-  /// indicating how to access these.
-  ClosureEnvironment getClosureEnvironment() {
-    if (closureClassMap.closureElement == null) return null;
-    return new ClosureEnvironment(
-        closureClassMap.closureElement,
-        closureClassMap.thisLocal,
-        mapValues(closureClassMap.freeVariableMap, getLocation));
-  }
-
-  /// If [node] has declarations for variables that should be boxed,
-  /// returns a [ClosureScope] naming a box to create, and enumerating the
-  /// variables that should be stored in the box.
-  ///
-  /// Also see [ClosureScope].
-  ClosureScope getClosureScopeForNode(ast.Node node) {
-    closurelib.ClosureScope scope = closureClassMap.capturingScopes[node];
-    if (scope == null) return null;
-    // We translate a ClosureScope from closure.dart into IR builder's variant
-    // because the IR builder should not depend on the synthetic elements
-    // created in closure.dart.
-    return new ClosureScope(scope.boxElement,
-                            mapValues(scope.capturedVariables, getLocation),
-                            scope.boxedLoopVariables);
-  }
-
-  /// Returns the [ClosureScope] for any function, possibly different from the
-  /// one currently being built.
-  ClosureScope getClosureScopeForFunction(FunctionElement function) {
-    ClosureClassMap map =
-        compiler.closureToClassMapper.computeClosureToClassMapping(
-            function,
-            function.node,
-            elements);
-    closurelib.ClosureScope scope = map.capturingScopes[function.node];
-    if (scope == null) return null;
-    return new ClosureScope(scope.boxElement,
-                            mapValues(scope.capturedVariables, getLocation),
-                            scope.boxedLoopVariables);
-  }
-
-  ir.FunctionDefinition buildExecutable(ExecutableElement element) {
-    return nullIfGiveup(() {
-      ir.FunctionDefinition root;
-      switch (element.kind) {
-        case ElementKind.GENERATIVE_CONSTRUCTOR:
-          root = buildConstructor(element);
-          break;
-
-        case ElementKind.GENERATIVE_CONSTRUCTOR_BODY:
-          root = buildConstructorBody(element);
-          break;
-
-        case ElementKind.FUNCTION:
-        case ElementKind.GETTER:
-        case ElementKind.SETTER:
-          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:
-          reporter.internalError(element, "Unexpected element type $element");
-      }
-      return root;
-    });
-  }
-
-  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, () {
-      irBuilder.buildFunctionHeader(<Local>[]);
-      ir.Primitive initialValue = visit(element.initializer);
-      ast.VariableDefinitions node = element.node;
-      ast.SendSet sendSet = node.definitions.nodes.head;
-      irBuilder.buildReturn(
-          value: initialValue,
-          sourceInformation:
-              sourceInformationBuilder.buildReturn(sendSet.assignmentOperator));
-      return irBuilder.makeFunctionDefinition();
-    });
-  }
-
-  /// Make a visitor suitable for translating ASTs taken from [context].
-  ///
-  /// Every visitor can only be applied to nodes in one context, because
-  /// the [elements] field is specific to that context.
-  JsIrBuilderVisitor makeVisitorForContext(AstElement context) {
-    return new JsIrBuilderVisitor(
-        context.resolvedAst.elements,
-        compiler,
-        sourceInformationBuilder.forContext(context));
-  }
-
-  /// Builds the IR for an [expression] taken from a different [context].
-  ///
-  /// Such expressions need to be compiled with a different [sourceFile] and
-  /// [elements] mapping.
-  ir.Primitive inlineExpression(AstElement context, ast.Expression expression) {
-    JsIrBuilderVisitor visitor = makeVisitorForContext(context);
-    return visitor.withBuilder(irBuilder, () => visitor.visit(expression));
-  }
-
-  /// Builds the IR for a constant taken from a different [context].
-  ///
-  /// Such constants need to be compiled with a different [sourceFile] and
-  /// [elements] mapping.
-  ir.Primitive inlineConstant(AstElement context, ast.Expression exp) {
-    JsIrBuilderVisitor visitor = makeVisitorForContext(context);
-    return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp));
-  }
-
-  IrBuilder getBuilderFor(Element element) {
-    return new IrBuilder(
-        new GlobalProgramInformation(compiler),
-        compiler.backend.constants,
-        element);
-  }
-
-  /// Builds the IR for a given constructor.
-  ///
-  /// 1. Computes the type held in all own or "inherited" type variables.
-  /// 2. Evaluates all own or inherited field initializers.
-  /// 3. Creates the object and assigns its fields and runtime type.
-  /// 4. Calls constructor body and super constructor bodies.
-  /// 5. 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;
-
-    IrBuilder builder = getBuilderFor(constructor);
-
-    final bool requiresTypeInformation =
-        builder.program.requiresRuntimeTypesFor(classElement);
-
-    return withBuilder(builder, () {
-      // Setup parameters and create a box if anything is captured.
-      List<Local> parameters = <Local>[];
-      constructor.functionSignature.orderedForEachParameter(
-          (ParameterElement p) => parameters.add(p));
-
-      int firstTypeArgumentParameterIndex;
-
-      // If instances of the class may need runtime type information, we add a
-      // synthetic parameter for each type parameter.
-      if (requiresTypeInformation) {
-        firstTypeArgumentParameterIndex = parameters.length;
-        classElement.typeVariables.forEach((TypeVariableType variable) {
-          parameters.add(new TypeVariableLocal(variable, constructor));
-        });
-      } else {
-        classElement.typeVariables.forEach((TypeVariableType variable) {
-          irBuilder.declareTypeVariable(variable, const DynamicType());
-        });
-      }
-
-      // Create IR parameters and setup the environment.
-      List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters,
-          closureScope: getClosureScopeForFunction(constructor));
-
-      // Create a list of the values of all type argument parameters, if any.
-      List<ir.Primitive> typeInformation;
-      if (requiresTypeInformation) {
-        typeInformation = irParameters.sublist(firstTypeArgumentParameterIndex);
-      } else {
-        typeInformation = const <ir.Primitive>[];
-      }
-
-      // -- Load values for type variables declared on super classes --
-      // Field initializers for super classes can reference these, so they
-      // must be available before evaluating field initializers.
-      // This could be interleaved with field initialization, but we choose do
-      // get it out of the way here to avoid complications with mixins.
-      loadTypeVariablesForSuperClasses(classElement);
-
-      /// Maps each field from this class or a superclass to its initial value.
-      Map<FieldElement, ir.Primitive> fieldValues =
-          <FieldElement, ir.Primitive>{};
-
-      // -- Evaluate field initializers ---
-      // Evaluate field initializers in constructor and super constructors.
-      List<ConstructorElement> constructorList = <ConstructorElement>[];
-      evaluateConstructorFieldInitializers(
-          constructor, constructorList, fieldValues);
-
-      // All parameters in all constructors are now bound in the environment.
-      // BoxLocals for captured parameters are also in the environment.
-      // The initial value of all fields are now bound in [fieldValues].
-
-      // --- Create the object ---
-      // Get the initial field values in the canonical order.
-      List<ir.Primitive> instanceArguments = <ir.Primitive>[];
-      classElement.forEachInstanceField((ClassElement c, FieldElement field) {
-        ir.Primitive value = fieldValues[field];
-        if (value != null) {
-          instanceArguments.add(value);
-        } else {
-          assert(Elements.isNativeOrExtendsNative(c));
-          // Native fields are initialized elsewhere.
-        }
-      }, includeSuperAndInjectedMembers: true);
-
-      ir.Primitive instance = new ir.CreateInstance(
-          classElement,
-          instanceArguments,
-          typeInformation,
-          constructor.hasNode
-              ? sourceInformationBuilder.buildCreate(constructor.node)
-              // TODO(johnniwinther): Provide source information for creation
-              // through synthetic constructors.
-              : null);
-      irBuilder.add(new ir.LetPrim(instance));
-
-      // --- Call constructor bodies ---
-      for (ConstructorElement target in constructorList) {
-        ConstructorBodyElement bodyElement = getConstructorBody(target);
-        if (bodyElement == null) continue; // Skip if constructor has no body.
-        List<ir.Primitive> bodyArguments = <ir.Primitive>[];
-        for (Local param in getConstructorBodyParameters(bodyElement)) {
-          bodyArguments.add(irBuilder.environment.lookup(param));
-        }
-        irBuilder.buildInvokeDirectly(bodyElement, instance, bodyArguments);
-      }
-
-      // --- step 4: return the created object ----
-      irBuilder.buildReturn(
-          value: instance,
-          sourceInformation:
-            sourceInformationBuilder.buildImplicitReturn(constructor));
-
-      return irBuilder.makeFunctionDefinition();
-    });
-  }
-
-  /// Evaluates all field initializers on [constructor] and all constructors
-  /// invoked through `this()` or `super()` ("superconstructors").
-  ///
-  /// The resulting field values will be available in [fieldValues]. The values
-  /// are not stored in any fields.
-  ///
-  /// This procedure assumes that the parameters to [constructor] are available
-  /// in the IR builder's environment.
-  ///
-  /// The parameters to superconstructors are, however, assumed *not* to be in
-  /// the environment, but will be put there by this procedure.
-  ///
-  /// All constructors will be added to [supers], with superconstructors first.
-  void evaluateConstructorFieldInitializers(
-      ConstructorElement constructor,
-      List<ConstructorElement> supers,
-      Map<FieldElement, ir.Primitive> fieldValues) {
-    assert(constructor.isImplementation);
-    assert(constructor == elements.analyzedElement);
-    ClassElement enclosingClass = constructor.enclosingClass.implementation;
-    // 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 {
-          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();
-          }
-        }
-      });
-    }
-    // If this is a mixin constructor, it does not have its own parameter list
-    // or initializer list. Directly forward to the super constructor.
-    // Note that the declaration-site initializers originating from the
-    // mixed-in class were handled above.
-    if (enclosingClass.isMixinApplication) {
-      forwardSynthesizedMixinConstructor(constructor, supers, fieldValues);
-      return;
-    }
-    // Evaluate initializing parameters, e.g. `Foo(this.x)`.
-    constructor.functionSignature.orderedForEachParameter(
-        (ParameterElement parameter) {
-      if (parameter.isInitializingFormal) {
-        InitializingFormalElement fieldParameter = parameter;
-        fieldValues[fieldParameter.fieldElement] =
-            irBuilder.buildLocalVariableGet(parameter);
-      }
-    });
-    // Evaluate constructor initializers, e.g. `Foo() : x = 50`.
-    ast.FunctionExpression node = constructor.node;
-    bool hasConstructorCall = false; // Has this() or super() initializer?
-    if (node != null && node.initializers != null) {
-      for(ast.Node initializer in node.initializers) {
-        if (initializer is ast.SendSet) {
-          // Field initializer.
-          FieldElement field = elements[initializer];
-          fieldValues[field] = visit(initializer.arguments.head);
-        } else if (initializer is ast.Send) {
-          // Super or this initializer.
-          ConstructorElement target = elements[initializer].implementation;
-          Selector selector = elements.getSelector(initializer);
-          List<ir.Primitive> arguments = initializer.arguments.mapToList(visit);
-          evaluateConstructorCallFromInitializer(
-              target,
-              selector.callStructure,
-              arguments,
-              supers,
-              fieldValues);
-          hasConstructorCall = true;
-        } else {
-          reporter.internalError(initializer,
-                                 "Unexpected initializer type $initializer");
-        }
-      }
-    }
-    // If no super() or this() was found, also call default superconstructor.
-    if (!hasConstructorCall && !enclosingClass.isObject) {
-      ClassElement superClass = enclosingClass.superclass;
-      FunctionElement target = superClass.lookupDefaultConstructor();
-      if (target == null) {
-        reporter.internalError(superClass, "No default constructor available.");
-      }
-      target = target.implementation;
-      evaluateConstructorCallFromInitializer(
-          target,
-          CallStructure.NO_ARGS,
-          const [],
-          supers,
-          fieldValues);
-    }
-    // Add this constructor after the superconstructors.
-    supers.add(constructor);
-  }
-
-  /// Evaluates a call to the given constructor from an initializer list.
-  ///
-  /// Calls [loadArguments] and [evaluateConstructorFieldInitializers] in a
-  /// visitor that has the proper [TreeElements] mapping.
-  void evaluateConstructorCallFromInitializer(
-      ConstructorElement target,
-      CallStructure call,
-      List<ir.Primitive> arguments,
-      List<ConstructorElement> supers,
-      Map<FieldElement, ir.Primitive> fieldValues) {
-    JsIrBuilderVisitor visitor = makeVisitorForContext(target);
-    visitor.withBuilder(irBuilder, () {
-      visitor.loadArguments(target, call, arguments);
-      visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
-    });
-  }
-
-  /// Evaluate the implicit super call in the given mixin constructor.
-  void forwardSynthesizedMixinConstructor(
-        ConstructorElement constructor,
-        List<ConstructorElement> supers,
-        Map<FieldElement, ir.Primitive> fieldValues) {
-    assert(constructor.enclosingClass.implementation.isMixinApplication);
-    assert(constructor.isSynthesized);
-    ConstructorElement target =
-        constructor.definingConstructor.implementation;
-    // The resolver gives us the exact same FunctionSignature for the two
-    // constructors. The parameters for the synthesized constructor
-    // are already in the environment, so the target constructor's parameters
-    // are also in the environment since their elements are the same.
-    assert(constructor.functionSignature == target.functionSignature);
-    JsIrBuilderVisitor visitor = makeVisitorForContext(target);
-    visitor.withBuilder(irBuilder, () {
-      visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
-    });
-  }
-
-  /// Loads the type variables for all super classes of [superClass] into the
-  /// IR builder's environment with their corresponding values.
-  ///
-  /// The type variables for [currentClass] must already be in the IR builder's
-  /// environment.
-  ///
-  /// Type variables are stored as [TypeVariableLocal] in the environment.
-  ///
-  /// This ensures that access to type variables mentioned inside the
-  /// constructors and initializers will happen through the local environment
-  /// instead of using 'this'.
-  void loadTypeVariablesForSuperClasses(ClassElement currentClass) {
-    if (currentClass.isObject) return;
-    loadTypeVariablesForType(currentClass.supertype);
-    if (currentClass is MixinApplicationElement) {
-      loadTypeVariablesForType(currentClass.mixinType);
-    }
-  }
-
-  /// Loads all type variables for [type] and all of its super classes into
-  /// the environment. All type variables mentioned in [type] must already
-  /// be in the environment.
-  void loadTypeVariablesForType(InterfaceType type) {
-    ClassElement clazz = type.element;
-    assert(clazz.typeVariables.length == type.typeArguments.length);
-    for (int i = 0; i < clazz.typeVariables.length; ++i) {
-      irBuilder.declareTypeVariable(clazz.typeVariables[i],
-                                    type.typeArguments[i]);
-    }
-    loadTypeVariablesForSuperClasses(clazz);
-  }
-
-  /// In preparation of inlining (part of) [target], the [arguments] are moved
-  /// into the environment bindings for the corresponding parameters.
-  ///
-  /// Defaults for optional arguments are evaluated in order to ensure
-  /// all parameters are available in the environment.
-  void loadArguments(ConstructorElement target,
-                     CallStructure call,
-                     List<ir.Primitive> arguments) {
-    assert(target.isImplementation);
-    assert(target == elements.analyzedElement);
-    FunctionSignature signature = target.functionSignature;
-
-    // Establish a scope in case parameters are captured.
-    ClosureScope scope = getClosureScopeForFunction(target);
-    irBuilder.enterScope(scope);
-
-    // Load required parameters
-    int index = 0;
-    signature.forEachRequiredParameter((ParameterElement param) {
-      irBuilder.declareLocalVariable(param, initialValue: arguments[index]);
-      index++;
-    });
-
-    // Load optional parameters, evaluating default values for omitted ones.
-    signature.forEachOptionalParameter((ParameterElement param) {
-      ir.Primitive value;
-      // Load argument if provided.
-      if (signature.optionalParametersAreNamed) {
-        int nameIndex = call.namedArguments.indexOf(param.name);
-        if (nameIndex != -1) {
-          int translatedIndex = call.positionalArgumentCount + nameIndex;
-          value = arguments[translatedIndex];
-        }
-      } else if (index < arguments.length) {
-        value = arguments[index];
-      }
-      // Load default if argument was not provided.
-      if (value == null) {
-        if (param.initializer != null) {
-          value = visit(param.initializer);
-        } else {
-          value = irBuilder.buildNullConstant();
-        }
-      }
-      irBuilder.declareLocalVariable(param, initialValue: value);
-      index++;
-    });
-  }
-
-  /**
-   * Returns the constructor body associated with the given constructor or
-   * creates a new constructor body, if none can be found.
-   *
-   * Returns `null` if the constructor does not have a body.
-   */
-  ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
-    // TODO(asgerf): This is largely inherited from the SSA builder.
-    // The ConstructorBodyElement has an invalid function signature, but we
-    // cannot add a BoxLocal as parameter, because BoxLocal is not an element.
-    // Instead of forging ParameterElements to forge a FunctionSignature, we
-    // need a way to create backend methods without creating more fake elements.
-    assert(constructor.isGenerativeConstructor);
-    assert(constructor.isImplementation);
-    if (constructor.isSynthesized) return null;
-    ast.FunctionExpression node = constructor.node;
-    // If we know the body doesn't have any code, we don't generate it.
-    if (!node.hasBody()) return null;
-    if (node.hasEmptyBody()) return null;
-    ClassElement classElement = constructor.enclosingClass;
-    ConstructorBodyElement bodyElement;
-    classElement.forEachBackendMember((Element backendMember) {
-      if (backendMember.isGenerativeConstructorBody) {
-        ConstructorBodyElement body = backendMember;
-        if (body.constructor == constructor) {
-          bodyElement = backendMember;
-        }
-      }
-    });
-    if (bodyElement == null) {
-      bodyElement = new ConstructorBodyElementX(constructor);
-      classElement.addBackendMember(bodyElement);
-
-      if (constructor.isPatch) {
-        // Create origin body element for patched constructors.
-        ConstructorBodyElementX patch = bodyElement;
-        ConstructorBodyElementX origin =
-            new ConstructorBodyElementX(constructor.origin);
-        origin.applyPatch(patch);
-        classElement.origin.addBackendMember(bodyElement.origin);
-      }
-    }
-    assert(bodyElement.isGenerativeConstructorBody);
-    return bodyElement;
-  }
-
-  /// The list of parameters to send from the generative constructor
-  /// to the generative constructor body.
-  ///
-  /// Boxed parameters are not in the list, instead, a [BoxLocal] is passed
-  /// containing the boxed parameters.
-  ///
-  /// For example, given the following constructor,
-  ///
-  ///     Foo(x, y) : field = (() => ++x) { print(x + y) }
-  ///
-  /// the argument `x` would be replaced by a [BoxLocal]:
-  ///
-  ///     Foo_body(box0, y) { print(box0.x + y) }
-  ///
-  List<Local> getConstructorBodyParameters(ConstructorBodyElement body) {
-    List<Local> parameters = <Local>[];
-    ClosureScope scope = getClosureScopeForFunction(body.constructor);
-    if (scope != null) {
-      parameters.add(scope.box);
-    }
-    body.functionSignature.orderedForEachParameter((ParameterElement param) {
-      if (scope != null && scope.capturedVariables.containsKey(param)) {
-        // Do not pass this parameter; the box will carry its value.
-      } else {
-        parameters.add(param);
-      }
-    });
-    return parameters;
-  }
-
-  DartCapturedVariables _analyzeCapturedVariables(ast.Node node) {
-    DartCapturedVariables variables = new DartCapturedVariables(elements);
-    try {
-      variables.analyze(node);
-    } catch (e) {
-      bailoutMessage = variables.bailoutMessage;
-      rethrow;
-    }
-    return variables;
-  }
-
-  /// Builds the IR for the body of a constructor.
-  ///
-  /// This function is invoked from one or more "factory" constructors built by
-  /// [buildConstructor].
-  ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) {
-    ConstructorElement constructor = body.constructor;
-    ast.FunctionExpression node = constructor.node;
-    closureClassMap =
-        compiler.closureToClassMapper.computeClosureToClassMapping(
-            constructor,
-            node,
-            elements);
-
-    // We compute variables boxed in mutable variables on entry to each try
-    // block, not including variables captured by a closure (which are boxed
-    // in the heap).  This duplicates some of the work of closure conversion
-    // without directly using the results.  This duplication is wasteful and
-    // error-prone.
-    // TODO(kmillikin): We should combine closure conversion and try/catch
-    // variable analysis in some way.
-    DartCapturedVariables variables = _analyzeCapturedVariables(node);
-    tryStatements = variables.tryStatements;
-    IrBuilder builder = getBuilderFor(body);
-
-    return withBuilder(builder, () {
-      irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body),
-                                           getClosureScopeForNode(node));
-      visit(node.body);
-      return irBuilder.makeFunctionDefinition();
-    });
-  }
-
-  ir.FunctionDefinition buildFunction(FunctionElement element) {
-    assert(invariant(element, element.isImplementation));
-    ast.FunctionExpression node = element.node;
-
-    assert(!element.isSynthesized);
-    assert(node != null);
-    assert(elements[node] != null);
-
-    closureClassMap =
-        compiler.closureToClassMapper.computeClosureToClassMapping(
-            element,
-            node,
-            elements);
-    DartCapturedVariables variables = _analyzeCapturedVariables(node);
-    tryStatements = variables.tryStatements;
-    IrBuilder builder = getBuilderFor(element);
-    return withBuilder(builder, () => _makeFunctionBody(element, node));
-  }
-
-  /// Creates a primitive for the default value of [parameter].
-  ir.Primitive translateDefaultValue(ParameterElement parameter) {
-    if (parameter.initializer == null) {
-      return irBuilder.buildNullConstant();
-    } else {
-      return inlineConstant(parameter.executableContext, parameter.initializer);
-    }
-  }
-
-  /// Inserts default arguments and normalizes order of named arguments.
-  List<ir.Primitive> normalizeStaticArguments(
-      CallStructure callStructure,
-      FunctionElement target,
-      List<ir.Primitive> arguments) {
-    target = target.implementation;
-    FunctionSignature signature = target.functionSignature;
-    if (!signature.optionalParametersAreNamed &&
-        signature.parameterCount == arguments.length) {
-      // Optimization: don't copy the argument list for trivial cases.
-      return arguments;
-    }
-
-    List<ir.Primitive> result = <ir.Primitive>[];
-    int i = 0;
-    signature.forEachRequiredParameter((ParameterElement element) {
-      result.add(arguments[i]);
-      ++i;
-    });
-
-    if (!signature.optionalParametersAreNamed) {
-      signature.forEachOptionalParameter((ParameterElement element) {
-        if (i < arguments.length) {
-          result.add(arguments[i]);
-          ++i;
-        } else {
-          result.add(translateDefaultValue(element));
-        }
-      });
-    } else {
-      int offset = i;
-      // Iterate over the optional parameters of the signature, and try to
-      // find them in [compiledNamedArguments]. If found, we use the
-      // value in the temporary list, otherwise the default value.
-      signature.orderedOptionalParameters.forEach((ParameterElement element) {
-        int nameIndex = callStructure.namedArguments.indexOf(element.name);
-        if (nameIndex != -1) {
-          int translatedIndex = offset + nameIndex;
-          result.add(arguments[translatedIndex]);
-        } else {
-          result.add(translateDefaultValue(element));
-        }
-      });
-    }
-    return result;
-  }
-
-  /// Normalizes order of named arguments.
-  List<ir.Primitive> normalizeDynamicArguments(
-      CallStructure callStructure,
-      List<ir.Primitive> arguments) {
-    assert(arguments.length == callStructure.argumentCount);
-    // Optimization: don't copy the argument list for trivial cases.
-    if (callStructure.namedArguments.isEmpty) return arguments;
-    List<ir.Primitive> result = <ir.Primitive>[];
-    for (int i=0; i < callStructure.positionalArgumentCount; i++) {
-      result.add(arguments[i]);
-    }
-    for (String argName in callStructure.getOrderedNamedArguments()) {
-      int nameIndex = callStructure.namedArguments.indexOf(argName);
-      int translatedIndex = callStructure.positionalArgumentCount + nameIndex;
-      result.add(arguments[translatedIndex]);
-    }
-    return result;
-  }
-
-  @override
-  ir.Primitive handleConstructorInvoke(
-      ast.NewExpression node,
-      ConstructorElement constructor,
-      DartType type,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    List<ir.Primitive> arguments =
-        node.send.arguments.mapToList(visit, growable:false);
-    // Use default values from the effective target, not the immediate target.
-    ConstructorElement target = constructor.effectiveTarget;
-    arguments = normalizeStaticArguments(callStructure, target, arguments);
-    return irBuilder.buildConstructorInvocation(
-        target,
-        callStructure,
-        constructor.computeEffectiveTargetType(type),
-        arguments,
-        sourceInformationBuilder.buildNew(node));
-  }
-
-  @override
-  ir.Primitive buildStaticNoSuchMethod(Selector selector,
-                                       List<ir.Primitive> arguments) {
-    Element thrower = backend.helpers.throwNoSuchMethod;
-    ir.Primitive receiver = irBuilder.buildStringConstant('');
-    ir.Primitive name = irBuilder.buildStringConstant(selector.name);
-    ir.Primitive argumentList = irBuilder.buildListLiteral(null, arguments);
-    ir.Primitive expectedArgumentNames = irBuilder.buildNullConstant();
-    return irBuilder.buildStaticFunctionInvocation(
-        thrower,
-        new CallStructure.unnamed(4),
-        [receiver, name, argumentList, expectedArgumentNames]);
-  }
-
-  @override
-  ir.Primitive buildInstanceNoSuchMethod(Selector selector,
-                                         TypeMask mask,
-                                         List<ir.Primitive> arguments) {
-    return irBuilder.buildDynamicInvocation(
-        irBuilder.buildThis(),
-        Selectors.noSuchMethod_,
-        mask,
-        [irBuilder.buildInvocationMirror(selector, arguments)]);
-  }
-
-  @override
-  ir.Primitive buildRuntimeError(String message) {
-    return irBuilder.buildStaticFunctionInvocation(
-        backend.helpers.throwRuntimeError,
-        new CallStructure.unnamed(1),
-        [irBuilder.buildStringConstant(message)]);
-  }
-
-  @override
-  ir.Primitive buildAbstractClassInstantiationError(ClassElement element) {
-    return irBuilder.buildStaticFunctionInvocation(
-        backend.helpers.throwAbstractClassInstantiationError,
-        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) {
-    ConstantValue constant = getConstantForVariable(field);
-    if (constant != null && !field.isAssignable) {
-      return irBuilder.buildConstant(constant, sourceInformation: src);
-    } else if (backend.constants.lazyStatics.contains(field)) {
-      return irBuilder.buildStaticFieldLazyGet(field, src);
-    } else {
-      return irBuilder.buildStaticFieldGet(field, src);
-    }
-  }
-
-  /// Build code to handle foreign code, that is, native JavaScript code, or
-  /// builtin values and operations of the backend.
-  ir.Primitive handleForeignCode(ast.Send node,
-                                 MethodElement function,
-                                 ast.NodeList argumentList,
-                                 CallStructure callStructure) {
-
-    void validateArgumentCount({int minimum, int exactly}) {
-      assert((minimum == null) != (exactly == null));
-      int count = 0;
-      int maximum;
-      if (exactly != null) {
-        minimum = exactly;
-        maximum = exactly;
-      }
-      for (ast.Node argument in argumentList) {
-        count++;
-        if (maximum != null && count > maximum) {
-          internalError(argument, 'Additional argument.');
-        }
-      }
-      if (count < minimum) {
-        internalError(node, 'Expected at least $minimum arguments.');
-      }
-    }
-
-    /// Call a helper method from the isolate library. The isolate library uses
-    /// its own isolate structure, that encapsulates dart2js's isolate.
-    ir.Primitive buildIsolateHelperInvocation(String helperName,
-                                              CallStructure callStructure) {
-      Element element = backend.isolateHelperLibrary.find(helperName);
-      if (element == null) {
-        reporter.internalError(node,
-            'Isolate library and compiler mismatch.');
-      }
-      List<ir.Primitive> arguments = translateStaticArguments(argumentList,
-          element, callStructure);
-      return irBuilder.buildStaticFunctionInvocation(element,
-          callStructure, arguments,
-          sourceInformation:
-                sourceInformationBuilder.buildCall(node, node.selector));
-    }
-
-    /// Lookup the value of the enum described by [node].
-    getEnumValue(ast.Node node, EnumClassElement enumClass, List values) {
-      Element element = elements[node];
-      if (element is! FieldElement || element.enclosingClass != enumClass) {
-        internalError(node, 'expected a JsBuiltin enum value');
-      }
-
-      int index = enumClass.enumValues.indexOf(element);
-      return values[index];
-    }
-
-    /// Returns the String the node evaluates to, or throws an error if the
-    /// result is not a string constant.
-    String expectStringConstant(ast.Node node) {
-      ir.Primitive nameValue = visit(node);
-      if (nameValue is ir.Constant && nameValue.value.isString) {
-        StringConstantValue constantValue = nameValue.value;
-        return constantValue.primitiveValue.slowToString();
-      } else {
-        return internalError(node, 'expected a literal string');
-      }
-    }
-
-    Link<ast.Node> argumentNodes  = argumentList.nodes;
-    NativeBehavior behavior =
-        compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
-    switch (function.name) {
-      case 'JS':
-        validateArgumentCount(minimum: 2);
-        // The first two arguments are the type and the foreign code template,
-        // which already have been analyzed by the resolver and can be retrieved
-        // using [NativeBehavior]. We can ignore these arguments in the backend.
-        List<ir.Primitive> arguments =
-            argumentNodes.skip(2).mapToList(visit, growable: false);
-        return irBuilder.buildForeignCode(behavior.codeTemplate, arguments,
-            behavior);
-
-      case 'DART_CLOSURE_TO_JS':
-        // TODO(ahe): This should probably take care to wrap the closure in
-        // another closure that saves the current isolate.
-      case 'RAW_DART_FUNCTION_REF':
-        validateArgumentCount(exactly: 1);
-
-        ast.Node argument = node.arguments.single;
-        FunctionElement closure = elements[argument].implementation;
-        if (!Elements.isStaticOrTopLevelFunction(closure)) {
-          internalError(argument,
-              'only static or toplevel function supported');
-        }
-        if (closure.functionSignature.hasOptionalParameters) {
-          internalError(argument,
-              'closures with optional parameters not supported');
-        }
-        return irBuilder.buildForeignCode(
-            js.js.expressionTemplateYielding(
-                backend.emitter.staticFunctionAccess(closure)),
-            <ir.Primitive>[],
-            NativeBehavior.PURE,
-            dependency: closure);
-
-      case 'JS_BUILTIN':
-        // The first argument is a description of the type and effect of the
-        // builtin, which has already been analyzed in the frontend.  The second
-        // argument must be a [JsBuiltin] value.  All other arguments are
-        // values used by the JavaScript template that is associated with the
-        // builtin.
-        validateArgumentCount(minimum: 2);
-
-        ast.Node builtin = argumentNodes.tail.head;
-        JsBuiltin value = getEnumValue(builtin, backend.jsBuiltinEnum,
-                                       JsBuiltin.values);
-        js.Template template = backend.emitter.builtinTemplateFor(value);
-        List<ir.Primitive> arguments =
-            argumentNodes.skip(2).mapToList(visit, growable: false);
-        return irBuilder.buildForeignCode(template, arguments, behavior);
-
-      case 'JS_EMBEDDED_GLOBAL':
-        validateArgumentCount(exactly: 2);
-
-        String name = expectStringConstant(argumentNodes.tail.head);
-        js.Expression access =
-            backend.emitter.generateEmbeddedGlobalAccess(name);
-        js.Template template = js.js.expressionTemplateYielding(access);
-        return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior);
-
-      case 'JS_INTERCEPTOR_CONSTANT':
-        validateArgumentCount(exactly: 1);
-
-        ast.Node argument = argumentNodes.head;
-        ir.Primitive argumentValue = visit(argument);
-        if (argumentValue is ir.Constant && argumentValue.value.isType) {
-          TypeConstantValue constant = argumentValue.value;
-          ConstantValue interceptorValue =
-              new InterceptorConstantValue(constant.representedType);
-          return irBuilder.buildConstant(interceptorValue);
-        } else {
-          internalError(argument, 'expected Type as argument');
-        }
-        break;
-
-      case 'JS_EFFECT':
-        return irBuilder.buildNullConstant();
-
-      case 'JS_GET_NAME':
-        validateArgumentCount(exactly: 1);
-
-        ast.Node argument = argumentNodes.head;
-        JsGetName id = getEnumValue(argument, backend.jsGetNameEnum,
-            JsGetName.values);
-        js.Name name = backend.namer.getNameForJsGetName(argument, id);
-        ConstantValue nameConstant =
-            new SyntheticConstantValue(SyntheticConstantKind.NAME,
-                                       js.js.quoteName(name));
-
-        return irBuilder.buildConstant(nameConstant);
-
-      case 'JS_GET_FLAG':
-        validateArgumentCount(exactly: 1);
-
-        String name = expectStringConstant(argumentNodes.first);
-        bool value = false;
-        switch (name) {
-          case 'MUST_RETAIN_METADATA':
-            value = backend.mustRetainMetadata;
-            break;
-          case 'USE_CONTENT_SECURITY_POLICY':
-            value = compiler.useContentSecurityPolicy;
-            break;
-          default:
-            internalError(node, 'Unknown internal flag "$name".');
-        }
-        return irBuilder.buildBooleanConstant(value);
-
-      case 'JS_STRING_CONCAT':
-        validateArgumentCount(exactly: 2);
-        List<ir.Primitive> arguments = argumentNodes.mapToList(visit);
-        return irBuilder.buildStringConcatenation(arguments);
-
-      case 'JS_CURRENT_ISOLATE_CONTEXT':
-        validateArgumentCount(exactly: 0);
-
-        if (!compiler.hasIsolateSupport) {
-          // If the isolate library is not used, we just generate code
-          // to fetch the current isolate.
-          continue getStaticState;
-        }
-        return buildIsolateHelperInvocation('_currentIsolate',
-            CallStructure.NO_ARGS);
-
-      getStaticState: case 'JS_GET_STATIC_STATE':
-        validateArgumentCount(exactly: 0);
-
-        return irBuilder.buildForeignCode(
-            js.js.parseForeignJS(backend.namer.staticStateHolder),
-            const <ir.Primitive>[],
-            NativeBehavior.PURE);
-
-      case 'JS_SET_STATIC_STATE':
-        validateArgumentCount(exactly: 1);
-
-        ir.Primitive value = visit(argumentNodes.single);
-        String isolateName = backend.namer.staticStateHolder;
-        return irBuilder.buildForeignCode(
-            js.js.parseForeignJS("$isolateName = #"),
-            <ir.Primitive>[value],
-            NativeBehavior.PURE);
-
-      case 'JS_CALL_IN_ISOLATE':
-        validateArgumentCount(exactly: 2);
-
-        if (!compiler.hasIsolateSupport) {
-          ir.Primitive closure = visit(argumentNodes.tail.head);
-          return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS,
-              const <ir.Primitive>[]);
-        }
-        return buildIsolateHelperInvocation('_callInIsolate',
-            CallStructure.TWO_ARGS);
-
-      default:
-        giveup(node, 'unplemented native construct: ${function.name}');
-        break;
-    }
-  }
-
-  @override
-  ir.Primitive handleStaticFunctionInvoke(ast.Send node,
-                                          MethodElement function,
-                                          ast.NodeList argumentList,
-                                          CallStructure callStructure,
-                                          _) {
-    if (compiler.backend.isForeign(function)) {
-      return handleForeignCode(node, function, argumentList, callStructure);
-    } else {
-      return irBuilder.buildStaticFunctionInvocation(function, callStructure,
-          translateStaticArguments(argumentList, function, callStructure),
-          sourceInformation:
-              sourceInformationBuilder.buildCall(node, node.selector));
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
index dfc07a3..a295902 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
@@ -10,6 +10,8 @@
 /// enabled, you typically want the other as well, so we use the same flag.
 const bool ENABLE_DUMP = tracer.TRACE_FILTER_PATTERN != null;
 
+enum ScopeType { InScope, InDefinition, NotInScope }
+
 /// Performs integrity checks on the CPS IR.
 ///
 /// To be run for debugging purposes, not for use in production.
@@ -27,45 +29,63 @@
 class CheckCpsIntegrity extends TrampolineRecursiveVisitor {
 
   FunctionDefinition topLevelNode;
+  final Map<Definition, ScopeType> inScope = <Definition, ScopeType>{};
+  final List<Definition> definitions = [];
   String previousPass;
 
-  Set<Definition> seenDefinitions = new Set<Definition>();
-  Map<Definition, Set<Reference>> seenReferences =
-      <Definition, Set<Reference>>{};
-
-  Set<Definition> inScope = new Set<Definition>();
-  Set<Continuation> insideContinuations = new Set<Continuation>();
-
-  void markAsSeen(Definition def) {
-    if (!seenDefinitions.add(def)) {
-      error('Redeclared $def', def);
+  void handleDeclaration(Definition def) {
+    definitions.add(def);
+    // Check the reference chain for cycles broken links.
+    Reference anchor = null;
+    int i = 0;
+    for (Reference ref = def.firstRef; ref != null; ref = ref.next) {
+      if (ref.definition != def) {
+        error('Reference to ${ref.definition} found in '
+              'reference chain for $def', def);
+      }
+      if (ref == anchor) {
+        error('Cyclic reference chain for $def', def);
+      }
+      if (i & ++i == 0) { // Move the anchor every 2^Nth step.
+        anchor = ref;
+      }
     }
-    seenReferences[def] = new Set<Reference>();
   }
 
   void enterScope(Iterable<Definition> definitions) {
-    inScope.addAll(definitions);
-    pushAction(() => inScope.removeAll(definitions));
+    for (Definition def in definitions) {
+      inScope[def] = ScopeType.InScope;
+    }
+    pushAction(() {
+      for (Definition def in definitions) {
+        inScope[def] = ScopeType.NotInScope;
+      }
+    });
   }
 
   void enterContinuation(Continuation cont) {
-    insideContinuations.add(cont);
-    pushAction(() => insideContinuations.remove(cont));
+    inScope[cont] = ScopeType.InDefinition;
+    pushAction(() {
+      inScope[cont] = ScopeType.NotInScope;
+    });
   }
 
   void check(FunctionDefinition node, String previousPass) {
-    topLevelNode = node;
+    // [check] will be called multiple times per instance to avoid reallocating
+    // the large [inScope] map. Reset the other fields.
+    this.topLevelNode = node;
     this.previousPass = previousPass;
+    this.definitions.clear();
     ParentChecker.checkParents(node, this);
     visit(node);
     // Check for broken reference chains. We check this last, so out-of-scope
     // references are not classified as a broken reference chain.
-    seenDefinitions.forEach(checkReferenceChain);
+    definitions.forEach(checkReferenceChain);
   }
 
   @override
   Expression traverseLetCont(LetCont node) {
-    node.continuations.forEach(markAsSeen);
+    node.continuations.forEach(handleDeclaration);
     node.continuations.forEach(push);
 
     // Put all continuations in scope when visiting the body.
@@ -76,7 +96,7 @@
 
   @override
   Expression traverseLetPrim(LetPrim node) {
-    markAsSeen(node.primitive);
+    handleDeclaration(node.primitive);
 
     // Process references in the primitive.
     visit(node.primitive);
@@ -89,9 +109,9 @@
 
   @override
   Expression traverseLetMutable(LetMutable node) {
-    markAsSeen(node.variable);
+    handleDeclaration(node.variable);
     processReference(node.value);
-    
+
     // Put the primitive in scope when visiting the body.
     enterScope([node.variable]);
 
@@ -103,7 +123,7 @@
     if (cont.isReturnContinuation) {
       error('Non-return continuation missing body', cont);
     }
-    cont.parameters.forEach(markAsSeen);
+    cont.parameters.forEach(handleDeclaration);
     enterScope(cont.parameters);
     // Put every continuation in scope at its own body. The isRecursive
     // flag is checked explicitly using [insideContinuations].
@@ -115,12 +135,12 @@
   @override
   visitFunctionDefinition(FunctionDefinition node) {
     if (node.thisParameter != null) {
-      markAsSeen(node.thisParameter);
+      handleDeclaration(node.thisParameter);
       enterScope([node.thisParameter]);
     }
-    node.parameters.forEach(markAsSeen);
+    node.parameters.forEach(handleDeclaration);
     enterScope(node.parameters);
-    markAsSeen(node.returnContinuation);
+    handleDeclaration(node.returnContinuation);
     enterScope([node.returnContinuation]);
     if (!node.returnContinuation.isReturnContinuation) {
       error('Return continuation with a body', node);
@@ -129,22 +149,28 @@
   }
 
   @override
-  processReference(Reference reference) {
-    if (!inScope.contains(reference.definition)) {
-      error('Referenced out of scope: ${reference.definition}', reference);
+  processReference(Reference ref) {
+    Definition def = ref.definition;
+    if (inScope[def] == ScopeType.NotInScope) {
+      error('Referenced out of scope: $def', ref);
     }
-    if (!seenReferences[reference.definition].add(reference)) {
-      error('Duplicate use of Reference to ${reference.definition}', reference);
+    if (ref.previous == ref) {
+      error('Shared Reference object to $def', ref);
     }
+    if (ref.previous == null && def.firstRef != ref ||
+        ref.previous != null && ref.previous.next != ref) {
+      error('Broken .previous link in reference to $def', def);
+    }
+    ref.previous = ref; // Mark reference as "seen". We will repair it later.
   }
 
   @override
   processInvokeContinuation(InvokeContinuation node) {
     Continuation target = node.continuation.definition;
-    if (node.isRecursive && !insideContinuations.contains(target)) {
+    if (node.isRecursive && inScope[target] == ScopeType.InScope) {
       error('Non-recursive InvokeContinuation marked as recursive', node);
     }
-    if (!node.isRecursive && insideContinuations.contains(target)) {
+    if (!node.isRecursive && inScope[target] == ScopeType.InDefinition) {
       error('Recursive InvokeContinuation marked as non-recursive', node);
     }
     if (node.isRecursive && !target.isRecursive) {
@@ -156,25 +182,15 @@
   }
 
   void checkReferenceChain(Definition def) {
-    Set<Reference> chainedReferences = new Set<Reference>();
-    Reference prev = null;
+    Reference previous = null;
     for (Reference ref = def.firstRef; ref != null; ref = ref.next) {
-      if (ref.definition != def) {
-        error('Reference in chain for $def points to ${ref.definition}', def);
+      if (ref.previous != ref) {
+        // Reference was not seen during IR traversal, so it is orphaned.
+        error('Orphaned reference in reference chain for $def', def);
       }
-      if (ref.previous != prev) {
-        error('Broken .previous link in reference to $def', def);
-      }
-      prev = ref;
-      if (!chainedReferences.add(ref)) {
-        error('Cyclic reference chain for $def', def);
-      }
-    }
-    if (!chainedReferences.containsAll(seenReferences[def])) {
-      error('Seen reference to $def not in reference chain', def);
-    }
-    if (!seenReferences[def].containsAll(chainedReferences)) {
-      error('Reference chain for $def contains orphaned references', def);
+      // Repair the .previous link that was used for marking.
+      ref.previous = previous;
+      previous = ref;
     }
   }
 
@@ -192,7 +208,7 @@
       sexpr = '(Set DUMP_IR flag to enable SExpr dump)';
     }
     throw 'CPS integrity violation\n'
-          'After $previousPass on ${topLevelNode.element}\n'
+          'After \'$previousPass\' on ${topLevelNode.element}\n'
           '$message\n\n'
           '$sexpr\n';
   }
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 cbb45f0..49c8a6b 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -4,6 +4,7 @@
 library dart2js.ir_nodes;
 
 import 'dart:collection';
+import 'cps_fragment.dart' show CpsFragment;
 import '../constants/values.dart' as values;
 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
 import '../elements/elements.dart';
@@ -17,7 +18,7 @@
 // These imports are only used for the JavaScript specific nodes.  If we want to
 // support more than one native backend, we should probably create better
 // abstractions for native code and its type and effect system.
-import '../js/js.dart' as js show Template;
+import '../js/js.dart' as js show Template, isNullGuardOnFirstArgument;
 import '../native/native.dart' as native show NativeBehavior;
 
 abstract class Node {
@@ -63,6 +64,8 @@
   /// For [InteriorExpression]s this is the body, for [CallExpressions] it is
   /// the body of the continuation, and for [TailExpressions] it is `null`.
   Expression get next;
+
+  accept(BlockVisitor visitor);
 }
 
 /// Represents a node with a child node, which can be accessed through the
@@ -76,6 +79,8 @@
 abstract class InteriorNode extends Node {
   Expression get body;
   void set body(Expression body);
+
+  accept(BlockVisitor visitor);
 }
 
 /// An expression that creates new bindings and continues evaluation in
@@ -123,12 +128,6 @@
   }
 }
 
-/// An expression that passes a continuation to a call.
-abstract class CallExpression extends Expression {
-  Reference<Continuation> get continuation;
-  Expression get next => continuation.definition.body;
-}
-
 /// An expression without a continuation or a subexpression body.
 ///
 /// These break straight-line control flow and can be thought of as ending a
@@ -149,19 +148,21 @@
   bool get hasAtLeastOneUse => firstRef != null;
   bool get hasMultipleUses  => !hasAtMostOneUse;
 
-  void substituteFor(Definition<T> other) {
-    if (other == this) return;
-    if (other.hasNoUses) return;
-    Reference<T> previous, current = other.firstRef;
+  void replaceUsesWith(Definition<T> newDefinition) {
+    if (newDefinition == this) return;
+    if (hasNoUses) return;
+    Reference<T> previous, current = firstRef;
     do {
-      current.definition = this;
+      current.definition = newDefinition;
       previous = current;
       current = current.next;
     } while (current != null);
-    previous.next = firstRef;
-    if (firstRef != null) firstRef.previous = previous;
-    firstRef = other.firstRef;
-    other.firstRef = null;
+    previous.next = newDefinition.firstRef;
+    if (newDefinition.firstRef != null) {
+      newDefinition.firstRef.previous = previous;
+    }
+    newDefinition.firstRef = firstRef;
+    firstRef = null;
   }
 }
 
@@ -207,18 +208,10 @@
 ///
 /// All primitives except [Parameter] must be bound by a [LetPrim].
 abstract class Primitive extends Variable<Primitive> {
-  /// The [VariableElement] or [ParameterElement] from which the primitive
-  /// binding originated.
-  Entity hint;
+  Primitive() : super(null);
 
-  /// Use the given element as a hint for naming this primitive.
-  ///
-  /// Has no effect if this primitive already has a non-null [element].
-  void useElementAsHint(Entity hint) {
-    if (this.hint == null) {
-      this.hint = hint;
-    }
-  }
+  /// True if this primitive has a value that can be used by other expressions.
+  bool get hasValue;
 
   /// True if the primitive can be removed, assuming it has no uses
   /// (this getter does not check if there are any uses).
@@ -235,7 +228,14 @@
   // TODO(johnniwinther): Require source information for all primitives.
   SourceInformation get sourceInformation => null;
 
-  /// If this is a [Refinement] node, returns the value being refined.
+  /// If this is a [Refinement], [BoundsCheck] or [NullCheck] node, returns the
+  /// value being refined, the indexable object being checked, or the value
+  /// that was checked to be non-null, respectively.
+  ///
+  /// Those instructions all return the corresponding operand directly, and
+  /// this getter can be used to get (closer to) where the value came from.
+  //
+  // TODO(asgerf): Also do this for [TypeCast]?
   Primitive get effectiveDefinition => this;
 
   /// True if the two primitives are (refinements of) the same value.
@@ -268,6 +268,54 @@
     assert(hasNoUses);
     RemovalVisitor.remove(this);
   }
+
+  /// Replaces this definition, both at the binding site and at all uses sites.
+  ///
+  /// This can be thought of as changing the definition of a `let` while
+  /// preserving the variable name:
+  ///
+  ///     let x = OLD in BODY
+  ///       ==>
+  ///     let x = NEW in BODY
+  ///
+  void replaceWith(Primitive newDefinition) {
+    assert(this is! Parameter);
+    assert(newDefinition is! Parameter);
+    assert(newDefinition.parent == null);
+    replaceUsesWith(newDefinition);
+    destroy();
+    LetPrim let = parent;
+    let.primitive = newDefinition;
+    newDefinition.parent = let;
+    newDefinition.useElementAsHint(hint);
+  }
+
+  /// Replaces this definition with a CPS fragment (a term with a hole in it),
+  /// given the value to replace the uses of the definition with.
+  ///
+  /// This can be thought of as substituting:
+  ///
+  ///     let x = OLD in BODY
+  ///       ==>
+  ///     FRAGMENT[BODY{newPrimitive/x}]
+  void replaceWithFragment(CpsFragment fragment, Primitive newPrimitive) {
+    assert(this is! Parameter);
+    replaceUsesWith(newPrimitive);
+    destroy();
+    LetPrim let = parent;
+    fragment.insertBelow(let);
+    let.remove();
+  }
+}
+
+/// A primitive that is generally not safe for elimination, but may be marked
+/// as safe by type propagation
+//
+// TODO(asgerf): Store the flag in a bitmask in [Primitive] and get rid of this
+//               class.
+abstract class UnsafePrimitive extends Primitive {
+  bool isSafeForElimination = false;
+  bool isSafeForReordering = false;
 }
 
 /// Operands to invocations and primitives are always variables.  They point to
@@ -326,7 +374,7 @@
     return body = expr;
   }
 
-  accept(Visitor visitor) => visitor.visitLetPrim(this);
+  accept(BlockVisitor visitor) => visitor.visitLetPrim(this);
 
   void setParentPointers() {
     primitive.parent = this;
@@ -366,7 +414,7 @@
     return continuations.first.body = expr;
   }
 
-  accept(Visitor visitor) => visitor.visitLetCont(this);
+  accept(BlockVisitor visitor) => visitor.visitLetCont(this);
 
   void setParentPointers() {
     _setParentsOnNodes(continuations, this);
@@ -389,7 +437,7 @@
 
   LetHandler(this.handler, this.body);
 
-  accept(Visitor visitor) => visitor.visitLetHandler(this);
+  accept(BlockVisitor visitor) => visitor.visitLetHandler(this);
 
   void setParentPointers() {
     handler.parent = this;
@@ -418,7 +466,7 @@
     return body = expr;
   }
 
-  accept(Visitor visitor) => visitor.visitLetMutable(this);
+  accept(BlockVisitor visitor) => visitor.visitLetMutable(this);
 
   void setParentPointers() {
     variable.parent = this;
@@ -427,6 +475,64 @@
   }
 }
 
+enum CallingConvention {
+  /// JS receiver is the Dart receiver, there are no extra arguments.
+  ///
+  /// This includes cases (e.g., static functions, constructors) where there
+  /// is no receiver.
+  ///
+  /// For example: `foo.bar$1(x)`
+  Normal,
+
+  /// JS receiver is an interceptor, the first argument is the Dart receiver.
+  ///
+  /// For example: `getInterceptor(foo).bar$1(foo, x)`
+  Intercepted,
+
+  /// JS receiver is the Dart receiver, the first argument is a dummy value.
+  ///
+  /// For example: `foo.bar$1(0, x)`
+  DummyIntercepted,
+
+  /// JS receiver is the Dart receiver, there are no extra arguments.
+  ///
+  /// Compiles to a one-shot interceptor, e.g: `J.bar$1(foo, x)`
+  OneShotIntercepted,
+}
+
+/// Base class of function invocations.
+///
+/// This class defines the common interface of function invocations.
+abstract class InvocationPrimitive extends UnsafePrimitive {
+  Reference<Primitive> get receiver => null;
+  List<Reference<Primitive>> get arguments;
+  SourceInformation get sourceInformation;
+
+  Reference<Primitive> get dartReceiverReference => null;
+  Primitive get dartReceiver => dartReceiverReference.definition;
+
+  CallingConvention get callingConvention => CallingConvention.Normal;
+
+  Reference<Primitive> dartArgumentReference(int n) {
+    switch (callingConvention) {
+      case CallingConvention.Normal:
+      case CallingConvention.OneShotIntercepted:
+        return arguments[n];
+
+      case CallingConvention.Intercepted:
+      case CallingConvention.DummyIntercepted:
+        return arguments[n + 1];
+    }
+  }
+
+  Primitive dartArgument(int n) => dartArgumentReference(n).definition;
+
+  int get dartArgumentsLength =>
+      arguments.length -
+      (callingConvention == CallingConvention.Intercepted ||
+          callingConvention == CallingConvention.DummyIntercepted ? 1 : 0);
+}
+
 /// Invoke a static function.
 ///
 /// All optional arguments declared by [target] are passed in explicitly, and
@@ -435,32 +541,29 @@
 /// Discussion:
 /// All information in the [selector] is technically redundant; it will likely
 /// be removed.
-class InvokeStatic extends CallExpression {
+class InvokeStatic extends InvocationPrimitive {
   final FunctionElement target;
   final Selector selector;
   final List<Reference<Primitive>> arguments;
-  final Reference<Continuation> continuation;
   final SourceInformation sourceInformation;
 
   InvokeStatic(this.target,
                this.selector,
                List<Primitive> args,
-               Continuation cont,
                [this.sourceInformation])
-      : arguments = _referenceList(args),
-        continuation = new Reference<Continuation>(cont);
+      : arguments = _referenceList(args);
 
   InvokeStatic.byReference(this.target,
                            this.selector,
                            this.arguments,
-                           this.continuation,
                            [this.sourceInformation]);
 
   accept(Visitor visitor) => visitor.visitInvokeStatic(this);
 
+  bool get hasValue => true;
+
   void setParentPointers() {
     _setParentsOnList(arguments, this);
-    continuation.parent = this;
   }
 }
 
@@ -473,24 +576,20 @@
 ///
 /// The [selector] records the names of named arguments. The value of named
 /// arguments occur at the end of the [arguments] list, in normalized order.
-class InvokeMethod extends CallExpression {
+class InvokeMethod extends InvocationPrimitive {
   Reference<Primitive> receiver;
   Selector selector;
   TypeMask mask;
   final List<Reference<Primitive>> arguments;
-  final Reference<Continuation> continuation;
   final SourceInformation sourceInformation;
 
-  /// If true, the [receiver] is intercepted and the actual receiver is in
-  /// the first argument. Otherwise, the [receiver] is the actual receiver.
-  ///
-  /// This flag is always false for non-intercepted selectors, but it may also
-  /// be false for intercepted selectors after dummy receiver optimization
-  /// (in this case the first argument is a dummy value).
-  ///
-  /// It is always false before the unsugaring pass, where interceptors have
-  /// not yet been introduced.
-  bool receiverIsIntercepted = false;
+  CallingConvention callingConvention = CallingConvention.Normal;
+
+  Reference<Primitive> get dartReceiverReference {
+    return callingConvention == CallingConvention.Intercepted
+        ? arguments[0]
+        : receiver;
+  }
 
   /// If true, it is known that the receiver cannot be `null`.
   bool receiverIsNotNull = false;
@@ -499,25 +598,18 @@
                this.selector,
                this.mask,
                List<Primitive> arguments,
-               Continuation continuation,
-               [this.sourceInformation])
+               {this.sourceInformation,
+                this.callingConvention: CallingConvention.Normal})
       : this.receiver = new Reference<Primitive>(receiver),
-        this.arguments = _referenceList(arguments),
-        this.continuation = new Reference<Continuation>(continuation);
-
-  InvokeMethod.byReference(this.receiver,
-                           this.selector,
-                           this.mask,
-                           this.arguments,
-                           this.continuation,
-                           this.sourceInformation);
+        this.arguments = _referenceList(arguments);
 
   accept(Visitor visitor) => visitor.visitInvokeMethod(this);
 
+  bool get hasValue => true;
+
   void setParentPointers() {
     receiver.parent = this;
     _setParentsOnList(arguments, this);
-    continuation.parent = this;
   }
 }
 
@@ -540,30 +632,37 @@
 ///
 /// All optional arguments declared by [target] are passed in explicitly, and
 /// occur at the end of [arguments] list, in normalized order.
-class InvokeMethodDirectly extends CallExpression {
+class InvokeMethodDirectly extends InvocationPrimitive {
   Reference<Primitive> receiver;
   final FunctionElement target;
   final Selector selector;
   final List<Reference<Primitive>> arguments;
-  final Reference<Continuation> continuation;
   final SourceInformation sourceInformation;
 
+  CallingConvention callingConvention;
+
+  Reference<Primitive> get dartReceiverReference {
+    return callingConvention == CallingConvention.Intercepted
+        ? arguments[0]
+        : receiver;
+  }
+
   InvokeMethodDirectly(Primitive receiver,
                        this.target,
                        this.selector,
                        List<Primitive> arguments,
-                       Continuation continuation,
-                       this.sourceInformation)
+                       this.sourceInformation,
+                       {this.callingConvention: CallingConvention.Normal})
       : this.receiver = new Reference<Primitive>(receiver),
-        this.arguments = _referenceList(arguments),
-        this.continuation = new Reference<Continuation>(continuation);
+        this.arguments = _referenceList(arguments);
 
   accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this);
 
+  bool get hasValue => true;
+
   void setParentPointers() {
     receiver.parent = this;
     _setParentsOnList(arguments, this);
-    continuation.parent = this;
   }
 }
 
@@ -582,28 +681,34 @@
 ///
 /// Note that [InvokeConstructor] does it itself allocate an object.
 /// The invoked constructor will do that using [CreateInstance].
-class InvokeConstructor extends CallExpression {
+class InvokeConstructor extends InvocationPrimitive {
   final DartType dartType;
   final ConstructorElement target;
   final List<Reference<Primitive>> arguments;
-  final Reference<Continuation> continuation;
   final Selector selector;
   final SourceInformation sourceInformation;
 
+  /// If non-null, this is an allocation site-specific type that is potentially
+  /// better than the inferred return type of [target].
+  ///
+  /// In particular, container type masks depend on the allocation site and
+  /// can therefore not be inferred solely based on the call target.
+  TypeMask allocationSiteType;
+
   InvokeConstructor(this.dartType,
                     this.target,
                     this.selector,
                     List<Primitive> args,
-                    Continuation cont,
-                    this.sourceInformation)
-      : arguments = _referenceList(args),
-        continuation = new Reference<Continuation>(cont);
+                    this.sourceInformation,
+                    {this.allocationSiteType})
+      : arguments = _referenceList(args);
 
   accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
 
+  bool get hasValue => true;
+
   void setParentPointers() {
     _setParentsOnList(arguments, this);
-    continuation.parent = this;
   }
 }
 
@@ -621,7 +726,8 @@
   Refinement(Primitive value, this.refineType)
     : value = new Reference<Primitive>(value);
 
-  bool get isSafeForElimination => true;
+  bool get hasValue => true;
+  bool get isSafeForElimination => false;
   bool get isSafeForReordering => false;
 
   accept(Visitor visitor) => visitor.visitRefinement(this);
@@ -633,9 +739,167 @@
   }
 }
 
+/// Checks that [index] is a valid index on a given indexable [object].
+///
+/// Compiles to the following, with a subset of the conditions in the `if`:
+///
+///     if (index < 0 || index >= object.length || object.length === 0)
+///         ThrowIndexOutOfRangeException(object, index);
+///
+/// [index] must be an integer, and [object] must refer to null or an indexable
+/// object, and [length] must be the length of [object] at the time of the
+/// check.
+///
+/// Returns [object] so the bounds check can be used to restrict code motion.
+/// It is possible to have a bounds check node that performs no checks but
+/// is retained to restrict code motion.
+///
+/// The [index] reference may be null if there are no checks to perform,
+/// and the [length] reference may be null if there is no upper bound or
+/// emptiness check.
+///
+/// If a separate code motion guard for the index is required, e.g. because it
+/// must be known to be non-negative in an operator that does not involve
+/// [object], a [Refinement] can be created for it with the non-negative integer
+/// type.
+class BoundsCheck extends Primitive {
+  final Reference<Primitive> object;
+  Reference<Primitive> index;
+  Reference<Primitive> length; // FIXME write docs for length
+  int checks;
+  final SourceInformation sourceInformation;
+
+  /// If true, check that `index >= 0`.
+  bool get hasLowerBoundCheck => checks & LOWER_BOUND != 0;
+
+  /// If true, check that `index < object.length`.
+  bool get hasUpperBoundCheck => checks & UPPER_BOUND != 0;
+
+  /// If true, check that `object.length !== 0`.
+  ///
+  /// Equivalent to a lower bound check with `object.length - 1` as the index,
+  /// but this check is faster.
+  ///
+  /// Although [index] is not used in the condition, it is used to generate
+  /// the thrown error.  Currently it is always `-1` for emptiness checks,
+  /// because that corresponds to `object.length - 1` in the error case.
+  bool get hasEmptinessCheck => checks & EMPTINESS != 0;
+
+  /// True if the [length] is needed to perform the check.
+  bool get lengthUsedInCheck => checks & (UPPER_BOUND | EMPTINESS) != 0;
+
+  bool get hasNoChecks => checks == NONE;
+
+  static const int UPPER_BOUND = 1 << 0;
+  static const int LOWER_BOUND = 1 << 1;
+  static const int EMPTINESS = 1 << 2; // See [hasEmptinessCheck].
+  static const int BOTH_BOUNDS = UPPER_BOUND | LOWER_BOUND;
+  static const int NONE = 0;
+
+  BoundsCheck(Primitive object, Primitive index, Primitive length,
+      [this.checks = BOTH_BOUNDS, this.sourceInformation])
+      : this.object = new Reference<Primitive>(object),
+        this.index = new Reference<Primitive>(index),
+        this.length = length == null ? null : new Reference<Primitive>(length);
+
+  BoundsCheck.noCheck(Primitive object, [this.sourceInformation])
+      : this.object = new Reference<Primitive>(object),
+        this.checks = NONE;
+
+  accept(Visitor visitor) => visitor.visitBoundsCheck(this);
+
+  void setParentPointers() {
+    object.parent = this;
+    if (index != null) {
+      index.parent = this;
+    }
+    if (length != null) {
+      length.parent = this;
+    }
+  }
+
+  String get checkString {
+    if (hasUpperBoundCheck && hasLowerBoundCheck) {
+      return 'upper-lower-checks';
+    } else if (hasUpperBoundCheck) {
+      return 'upper-check';
+    } else if (hasLowerBoundCheck) {
+      return 'lower-check';
+    } else if (hasEmptinessCheck) {
+      return 'emptiness-check';
+    } else {
+      return 'no-check';
+    }
+  }
+
+  bool get isSafeForElimination => checks == NONE;
+  bool get isSafeForReordering => false;
+  bool get hasValue => true; // Can be referenced to restrict code motion.
+
+  Primitive get effectiveDefinition => object.definition.effectiveDefinition;
+}
+
+/// Throw an exception if [value] is `null`.
+///
+/// Returns [value] so this can be used to restrict code motion.
+///
+/// In the simplest form this compiles to `value.toString;`.
+///
+/// [selector] holds the selector that is the cause of the null check. This is
+/// usually a method that was inlined where [value] the receiver.
+///
+/// If [selector] is set and [useSelector] is true, `toString` is replaced with
+/// the (possibly minified) invocation name of the selector.  This can be
+/// shorter and generate a more meaningful error message, but is expensive if
+/// [value] is non-null and does not have that property at runtime.
+///
+/// If [condition] is set, it is assumed that [condition] is true if and only
+/// if [value] is null.  The check then compiles to:
+///
+///     if (condition) value.toString;  (or .selector if non-null)
+///
+/// The latter form is useful when [condition] is a form understood by the JS
+/// runtime, such as a `typeof` test.
+class NullCheck extends Primitive {
+  final Reference<Primitive> value;
+  final Selector selector;
+  final bool useSelector;
+  final Reference<Primitive> condition;
+  final SourceInformation sourceInformation;
+
+  NullCheck(Primitive value, this.sourceInformation,
+            {Primitive condition,
+             this.selector,
+             this.useSelector: false})
+      : this.value = new Reference<Primitive>(value),
+        this.condition =
+            condition == null ? null : new Reference<Primitive>(condition);
+
+  NullCheck.guarded(Primitive condition, Primitive value, this.selector,
+        this.sourceInformation)
+      : this.condition = new Reference<Primitive>(condition),
+        this.value = new Reference<Primitive>(value),
+        this.useSelector = true;
+
+  bool get isSafeForElimination => false;
+  bool get isSafeForReordering => false;
+  bool get hasValue => true;
+
+  accept(Visitor visitor) => visitor.visitNullCheck(this);
+
+  void setParentPointers() {
+    value.parent = this;
+    if (condition != null) {
+      condition.parent = this;
+    }
+  }
+
+  Primitive get effectiveDefinition => value.definition.effectiveDefinition;
+}
+
 /// An "is" type test.
 ///
-/// Returns `true` if [value] is an instance of [type].
+/// Returns `true` if [value] is an instance of [dartType].
 ///
 /// [type] must not be the [Object], `dynamic` or [Null] types (though it might
 /// be a type variable containing one of these types). This design is chosen
@@ -657,12 +921,6 @@
   /// Otherwise the list is empty.
   final List<Reference<Primitive>> typeArguments;
 
-  /// The Interceptor for [value].  May be `null` if the test can be done
-  /// without an interceptor.  May be the same as [value] after self-interceptor
-  /// optimization.
-  // TODO(24523): Remove this field.
-  Reference<Primitive> interceptor;
-
   TypeTest(Primitive value,
            this.dartType,
            List<Primitive> typeArguments)
@@ -671,13 +929,13 @@
 
   accept(Visitor visitor) => visitor.visitTypeTest(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
   void setParentPointers() {
     value.parent = this;
     _setParentsOnList(typeArguments, this);
-    if (interceptor != null) interceptor.parent = this;
   }
 }
 
@@ -693,6 +951,7 @@
 
   accept(Visitor visitor) => visitor.visitTypeTestViaFlag(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -711,26 +970,26 @@
 /// [value], which is typically in scope in the continuation. However, it might
 /// simplify type propagation, since a better type can be computed for the
 /// continuation parameter without needing flow-sensitive analysis.
-class TypeCast extends CallExpression {
+class TypeCast extends UnsafePrimitive {
   Reference<Primitive> value;
   final DartType dartType;
 
   /// See the corresponding field on [TypeTest].
   final List<Reference<Primitive>> typeArguments;
-  final Reference<Continuation> continuation;
 
   TypeCast(Primitive value,
            this.dartType,
-           List<Primitive> typeArguments,
-           Continuation cont)
+           List<Primitive> typeArguments)
       : this.value = new Reference<Primitive>(value),
-        this.typeArguments = _referenceList(typeArguments),
-        this.continuation = new Reference<Continuation>(cont);
+        this.typeArguments = _referenceList(typeArguments);
 
   accept(Visitor visitor) => visitor.visitTypeCast(this);
 
+  bool get hasValue => true;
+
   void setParentPointers() {
     value.parent = this;
+    _setParentsOnList(typeArguments, this);
   }
 }
 
@@ -749,6 +1008,7 @@
 
   accept(Visitor visitor) => visitor.visitApplyBuiltinOperator(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -778,6 +1038,7 @@
 
   accept(Visitor visitor) => visitor.visitApplyBuiltinMethod(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => false;
   bool get isSafeForReordering => false;
 
@@ -796,7 +1057,7 @@
 
   Throw(Primitive value) : value = new Reference<Primitive>(value);
 
-  accept(Visitor visitor) => visitor.visitThrow(this);
+  accept(BlockVisitor visitor) => visitor.visitThrow(this);
 
   void setParentPointers() {
     value.parent = this;
@@ -809,7 +1070,7 @@
 /// implicitly throws the exception parameter of the enclosing handler with
 /// the same stack trace as the enclosing handler.
 class Rethrow extends TailExpression {
-  accept(Visitor visitor) => visitor.visitRethrow(this);
+  accept(BlockVisitor visitor) => visitor.visitRethrow(this);
   void setParentPointers() {}
 }
 
@@ -818,7 +1079,7 @@
 /// This can be placed as the body of a call continuation, when the caller is
 /// known never to invoke it, e.g. because the calling expression always throws.
 class Unreachable extends TailExpression {
-  accept(Visitor visitor) => visitor.visitUnreachable(this);
+  accept(BlockVisitor visitor) => visitor.visitUnreachable(this);
   void setParentPointers() {}
 }
 
@@ -837,6 +1098,7 @@
 
   accept(Visitor visitor) => visitor.visitGetMutable(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => false;
 
@@ -861,6 +1123,7 @@
 
   accept(Visitor visitor) => visitor.visitSetMutable(this);
 
+  bool get hasValue => false;
   bool get isSafeForElimination => false;
   bool get isSafeForReordering => false;
 
@@ -905,7 +1168,7 @@
         arguments = null,
         sourceInformation = null;
 
-  accept(Visitor visitor) => visitor.visitInvokeContinuation(this);
+  accept(BlockVisitor visitor) => visitor.visitInvokeContinuation(this);
 
   void setParentPointers() {
     if (continuation != null) continuation.parent = this;
@@ -928,23 +1191,28 @@
   /// boolean.
   bool isStrictCheck;
 
-  Branch.strict(Primitive condition,
-                Continuation trueCont,
-                Continuation falseCont)
+  Branch(Primitive condition,
+         Continuation trueCont,
+         Continuation falseCont,
+         {bool strict})
       : this.condition = new Reference<Primitive>(condition),
         trueContinuation = new Reference<Continuation>(trueCont),
         falseContinuation = new Reference<Continuation>(falseCont),
-        isStrictCheck = true;
+        isStrictCheck = strict {
+    assert(strict != null);
+  }
+
+  Branch.strict(Primitive condition,
+                Continuation trueCont,
+                Continuation falseCont)
+        : this(condition, trueCont, falseCont, strict: true);
 
   Branch.loose(Primitive condition,
                Continuation trueCont,
                Continuation falseCont)
-      : this.condition = new Reference<Primitive>(condition),
-        trueContinuation = new Reference<Continuation>(trueCont),
-        falseContinuation = new Reference<Continuation>(falseCont),
-        this.isStrictCheck = false;
+      : this(condition, trueCont, falseCont, strict: false);
 
-  accept(Visitor visitor) => visitor.visitBranch(this);
+  accept(BlockVisitor visitor) => visitor.visitBranch(this);
 
   void setParentPointers() {
     condition.parent = this;
@@ -965,6 +1233,7 @@
 
   accept(Visitor visitor) => visitor.visitSetField(this);
 
+  bool get hasValue => false;
   bool get isSafeForElimination => false;
   bool get isSafeForReordering => false;
 
@@ -991,6 +1260,7 @@
 
   accept(Visitor visitor) => visitor.visitGetField(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => objectIsNotNull;
   bool get isSafeForReordering => false;
 
@@ -1010,6 +1280,7 @@
 
   GetLength(Primitive object) : this.object = new Reference<Primitive>(object);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => objectIsNotNull;
   bool get isSafeForReordering => false;
 
@@ -1020,10 +1291,10 @@
   }
 }
 
-/// Read an entry from a string or native list.
+/// Read an entry from an indexable object.
 ///
-/// [object] must be null or a native list or a string, and [index] must be
-/// an integer.
+/// [object] must be null or an indexable object, and [index] must be
+/// an integer where `0 <= index < object.length`.
 class GetIndex extends Primitive {
   final Reference<Primitive> object;
   final Reference<Primitive> index;
@@ -1035,6 +1306,7 @@
       : this.object = new Reference<Primitive>(object),
         this.index = new Reference<Primitive>(index);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => objectIsNotNull;
   bool get isSafeForReordering => false;
 
@@ -1061,6 +1333,7 @@
         this.index = new Reference<Primitive>(index),
         this.value = new Reference<Primitive>(value);
 
+  bool get hasValue => false;
   bool get isSafeForElimination => false;
   bool get isSafeForReordering => false;
 
@@ -1075,24 +1348,40 @@
 
 /// Reads the value of a static field or tears off a static method.
 ///
-/// Note that lazily initialized fields should be read using GetLazyStatic.
+/// If [GetStatic] is used to load a lazily initialized static field, it must
+/// have been initialized beforehand, and a [witness] must be set to restrict
+/// code motion.
 class GetStatic extends Primitive {
   /// Can be [FieldElement] or [FunctionElement].
   final Element element;
   final SourceInformation sourceInformation;
 
+  /// If reading a lazily initialized field, [witness] must refer to a node
+  /// that initializes the field or always occurs after the field initializer.
+  ///
+  /// The value of the witness is not used.
+  Reference<Primitive> witness;
+
   GetStatic(this.element, [this.sourceInformation]);
 
+  /// Read a lazily initialized static field that is known to have been
+  /// initialized by [witness] or earlier.
+  GetStatic.witnessed(this.element, Primitive witness, [this.sourceInformation])
+      : witness = witness == null ? null : new Reference<Primitive>(witness);
+
   accept(Visitor visitor) => visitor.visitGetStatic(this);
 
-  bool get isSafeForElimination {
-    return true;
-  }
+  bool get hasValue => true;
+  bool get isSafeForElimination => true;
   bool get isSafeForReordering {
     return element is FunctionElement || element.isFinal;
   }
 
-  void setParentPointers() {}
+  void setParentPointers() {
+    if (witness != null) {
+      witness.parent = this;
+    }
+  }
 }
 
 /// Sets the value of a static field.
@@ -1106,6 +1395,7 @@
 
   accept(Visitor visitor) => visitor.visitSetStatic(this);
 
+  bool get hasValue => false;
   bool get isSafeForElimination => false;
   bool get isSafeForReordering => false;
 
@@ -1118,29 +1408,24 @@
 ///
 /// 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 CallExpression {
+class GetLazyStatic extends UnsafePrimitive {
   final FieldElement element;
-  final Reference<Continuation> continuation;
   final SourceInformation sourceInformation;
 
-  GetLazyStatic(this.element,
-                Continuation continuation,
-                [this.sourceInformation])
-      : continuation = new Reference<Continuation>(continuation);
+  GetLazyStatic(this.element, [this.sourceInformation]);
 
   accept(Visitor visitor) => visitor.visitGetLazyStatic(this);
 
-  void setParentPointers() {
-    continuation.parent = this;
-  }
+  bool get hasValue => true;
+
+  void setParentPointers() {}
 }
 
 /// Creates an object for holding boxed variables captured by a closure.
 class CreateBox extends Primitive {
   accept(Visitor visitor) => visitor.visitCreateBox(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1173,6 +1458,7 @@
 
   accept(Visitor visitor) => visitor.visitCreateInstance(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1184,28 +1470,36 @@
   }
 }
 
+/// Obtains the interceptor for the given value.  This is a method table
+/// corresponding to the Dart class of the value.
+///
+/// All values are either intercepted or self-intercepted.  The interceptor for
+/// an "intercepted value" is one of the subclasses of Interceptor.
+/// The interceptor for a "self-intercepted value" is the value itself.
+///
+/// If the input is an intercepted value, and any of its superclasses is in
+/// [interceptedClasses], the method table for the input is returned.
+/// Otherwise, the input itself is returned.
+///
+/// There are thus three significant cases:
+/// - the input is a self-interceptor
+/// - the input is an intercepted value and is caught by [interceptedClasses]
+/// - the input is an intercepted value but is bypassed by [interceptedClasses]
+///
+/// The [flags] field indicates which of the above cases may happen, with
+/// additional special cases for null (which can either by intercepted or
+/// bypassed).
 class Interceptor extends Primitive {
   final Reference<Primitive> input;
   final Set<ClassElement> interceptedClasses = new Set<ClassElement>();
   final SourceInformation sourceInformation;
 
-  /// If non-null, all uses of this the interceptor call are guaranteed to
-  /// see this value.
-  ///
-  /// The interceptor call is not immediately replaced by the constant, because
-  /// that might prevent the interceptor from being shared.
-  ///
-  /// The precise input type is not known when sharing interceptors, because
-  /// refinement nodes have been removed by then. So this field carries the
-  /// known constant until we know if it should be shared or replaced by
-  /// the constant.
-  values.InterceptorConstantValue constantValue;
-
   Interceptor(Primitive input, this.sourceInformation)
       : this.input = new Reference<Primitive>(input);
 
   accept(Visitor visitor) => visitor.visitInterceptor(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1224,6 +1518,7 @@
 
   accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1232,24 +1527,32 @@
   }
 }
 
-class ForeignCode extends CallExpression {
+class ForeignCode extends UnsafePrimitive {
   final js.Template codeTemplate;
   final TypeMask type;
   final List<Reference<Primitive>> arguments;
   final native.NativeBehavior nativeBehavior;
   final FunctionElement dependency;
-  final Reference<Continuation> continuation;
 
   ForeignCode(this.codeTemplate, this.type, List<Primitive> arguments,
-      this.nativeBehavior, Continuation continuation, {this.dependency})
-      : this.arguments = _referenceList(arguments),
-        this.continuation = new Reference<Continuation>(continuation);
+      this.nativeBehavior, {this.dependency})
+      : this.arguments = _referenceList(arguments);
 
   accept(Visitor visitor) => visitor.visitForeignCode(this);
 
+  bool get hasValue => true;
+
   void setParentPointers() {
     _setParentsOnList(arguments, this);
-    continuation.parent = this;
+  }
+
+  bool isNullGuardOnNullFirstArgument() {
+    if (arguments.length < 1) return false;
+    // TODO(sra): Fix NativeThrowBehavior to distinguish MAY from
+    // throws-nsm-on-null-followed-by-MAY and remove
+    // [isNullGuardForFirstArgument].
+    if (nativeBehavior.throwBehavior.isNullNSMGuard) return true;
+    return js.isNullGuardOnFirstArgument(codeTemplate);
   }
 }
 
@@ -1263,6 +1566,7 @@
 
   accept(Visitor visitor) => visitor.visitConstant(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1274,11 +1578,16 @@
   final InterfaceType dartType;
   final List<Reference<Primitive>> values;
 
-  LiteralList(this.dartType, List<Primitive> values)
+  /// If non-null, this is an allocation site-specific type for the list
+  /// created here.
+  TypeMask allocationSiteType;
+
+  LiteralList(this.dartType, List<Primitive> values, {this.allocationSiteType})
       : this.values = _referenceList(values);
 
   accept(Visitor visitor) => visitor.visitLiteralList(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1304,6 +1613,7 @@
 
   accept(Visitor visitor) => visitor.visitLiteralMap(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1315,29 +1625,6 @@
   }
 }
 
-/// Currently unused.
-///
-/// Nested functions (from Dart code) are translated to classes by closure
-/// conversion, hence they are instantiated with [CreateInstance].
-///
-/// We keep this around for now because it might come in handy when we
-/// handle async/await in the CPS IR.
-///
-/// Instantiates a nested function. [MutableVariable]s are in scope in the
-/// inner function, but primitives are not shared across function boundaries.
-class CreateFunction extends Primitive {
-  final FunctionDefinition definition;
-
-  CreateFunction(this.definition);
-
-  accept(Visitor visitor) => visitor.visitCreateFunction(this);
-
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {}
-}
-
 class Parameter extends Primitive {
   Parameter(Entity hint) {
     super.hint = hint;
@@ -1347,6 +1634,7 @@
 
   String toString() => 'Parameter(${hint == null ? null : hint.name})';
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1371,7 +1659,7 @@
     : parameters = <Parameter>[new Parameter(null)],
       isRecursive = false;
 
-  accept(Visitor visitor) => visitor.visitContinuation(this);
+  accept(BlockVisitor visitor) => visitor.visitContinuation(this);
 
   void setParentPointers() {
     _setParentsOnNodes(parameters, this);
@@ -1385,13 +1673,24 @@
   ///
   /// Is `null` until initialized by type propagation.
   TypeMask type;
+
+  /// The [VariableElement] or [ParameterElement] from which the variable
+  /// binding originated.
+  Entity hint;
+
+  Variable(this.hint);
+
+  /// Use the given element as a hint for naming this primitive.
+  ///
+  /// Has no effect if this primitive already has a non-null [element].
+  void useElementAsHint(Entity hint) {
+    this.hint ??= hint;
+  }
 }
 
 /// Identifies a mutable variable.
 class MutableVariable extends Variable<MutableVariable> {
-  Entity hint;
-
-  MutableVariable(this.hint);
+  MutableVariable(Entity hint) : super(hint);
 
   accept(Visitor v) => v.visitMutableVariable(this);
 
@@ -1415,7 +1714,7 @@
       this.returnContinuation,
       this.body);
 
-  accept(Visitor visitor) => visitor.visitFunctionDefinition(this);
+  accept(BlockVisitor visitor) => visitor.visitFunctionDefinition(this);
 
   void setParentPointers() {
     if (thisParameter != null) thisParameter.parent = this;
@@ -1440,6 +1739,7 @@
   @override
   accept(Visitor visitor) => visitor.visitReifyRuntimeType(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1464,6 +1764,7 @@
   @override
   accept(Visitor visitor) => visitor.visitReadTypeVariable(this);
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1493,6 +1794,7 @@
     return visitor.visitTypeExpression(this);
   }
 
+  bool get hasValue => true;
   bool get isSafeForElimination => true;
   bool get isSafeForReordering => true;
 
@@ -1501,42 +1803,40 @@
   }
 }
 
-class Await extends CallExpression {
+class Await extends UnsafePrimitive {
   final Reference<Primitive> input;
-  final Reference<Continuation> continuation;
 
-  Await(Primitive input, Continuation continuation)
-    : this.input = new Reference<Primitive>(input),
-      this.continuation = new Reference<Continuation>(continuation);
+  Await(Primitive input)
+    : this.input = new Reference<Primitive>(input);
 
   @override
   accept(Visitor visitor) {
     return visitor.visitAwait(this);
   }
 
+  bool get hasValue => true;
+
   void setParentPointers() {
     input.parent = this;
-    continuation.parent = this;
   }
 }
 
-class Yield extends CallExpression {
+class Yield extends UnsafePrimitive {
   final Reference<Primitive> input;
-  final Reference<Continuation> continuation;
   final bool hasStar;
 
-  Yield(Primitive input, this.hasStar, Continuation continuation)
-    : this.input = new Reference<Primitive>(input),
-      this.continuation = new Reference<Continuation>(continuation);
+  Yield(Primitive input, this.hasStar)
+    : this.input = new Reference<Primitive>(input);
 
   @override
   accept(Visitor visitor) {
     return visitor.visitYield(this);
   }
 
+  bool get hasValue => true;
+
   void setParentPointers() {
     input.parent = this;
-    continuation.parent = this;
   }
 }
 
@@ -1556,44 +1856,119 @@
   }
 }
 
-abstract class Visitor<T> {
+/// Visitor for block-level traversals that do not need to dispatch on
+/// primitives.
+abstract class BlockVisitor<T> {
+  const BlockVisitor();
+
+  T visit(Node node) => node.accept(this);
+
+  // Block headers.
+  T visitFunctionDefinition(FunctionDefinition node) => null;
+  T visitContinuation(Continuation node) => null;
+
+  // Interior expressions.
+  T visitLetPrim(LetPrim node) => null;
+  T visitLetCont(LetCont node) => null;
+  T visitLetHandler(LetHandler node) => null;
+  T visitLetMutable(LetMutable node) => null;
+
+  // Tail expressions.
+  T visitInvokeContinuation(InvokeContinuation node) => null;
+  T visitThrow(Throw node) => null;
+  T visitRethrow(Rethrow node) => null;
+  T visitBranch(Branch node) => null;
+  T visitUnreachable(Unreachable node) => null;
+
+  /// Visits block-level nodes in lexical post-order (not post-dominator order).
+  ///
+  /// Continuations and function definitions are considered "block headers".
+  /// The block itself is the sequence of interior expressions in the body,
+  /// terminated by a tail expression.
+  ///
+  /// Each block is visited starting with its tail expression, then every
+  /// interior expression from bottom to top, and finally the block header
+  /// is visited.
+  ///
+  /// Blocks are visited in post-order, so the body of a continuation is always
+  /// processed before its non-recursive invocation sites.
+  ///
+  /// The IR may be transformed during the traversal, but only the original
+  /// nodes will be visited.
+  static void traverseInPostOrder(FunctionDefinition root, BlockVisitor v) {
+    List<Continuation> stack = <Continuation>[];
+    List<Node> nodes = <Node>[];
+    void walkBlock(InteriorNode block) {
+      nodes.add(block);
+      Expression node = block.body;
+      nodes.add(node);
+      while (node.next != null) {
+        if (node is LetCont) {
+          stack.addAll(node.continuations);
+        } else if (node is LetHandler) {
+          stack.add(node.handler);
+        }
+        node = node.next;
+        nodes.add(node);
+      }
+    }
+    walkBlock(root);
+    while (stack.isNotEmpty) {
+      walkBlock(stack.removeLast());
+    }
+    nodes.reversed.forEach(v.visit);
+  }
+
+  /// Visits block-level nodes in lexical pre-order.
+  ///
+  /// The IR may be transformed during the traversal, but the currently
+  /// visited node should not be removed, as its 'body' pointer is needed
+  /// for the traversal.
+  static void traverseInPreOrder(FunctionDefinition root, BlockVisitor v) {
+    List<Continuation> stack = <Continuation>[];
+    void walkBlock(InteriorNode block) {
+      v.visit(block);
+      Expression node = block.body;
+      v.visit(node);
+      while (node.next != null) {
+        if (node is LetCont) {
+          stack.addAll(node.continuations);
+        } else if (node is LetHandler) {
+          stack.add(node.handler);
+        }
+        node = node.next;
+        v.visit(node);
+      }
+    }
+    walkBlock(root);
+    while (stack.isNotEmpty) {
+      walkBlock(stack.removeLast());
+    }
+  }
+}
+
+abstract class Visitor<T> implements BlockVisitor<T> {
   const Visitor();
 
   T visit(Node node);
 
-  // Concrete classes.
-  T visitFunctionDefinition(FunctionDefinition node);
-
-  // Expressions.
-  T visitLetPrim(LetPrim node);
-  T visitLetCont(LetCont node);
-  T visitLetHandler(LetHandler node);
-  T visitLetMutable(LetMutable node);
-  T visitInvokeContinuation(InvokeContinuation node);
+  // Definitions.
   T visitInvokeStatic(InvokeStatic node);
   T visitInvokeMethod(InvokeMethod node);
   T visitInvokeMethodDirectly(InvokeMethodDirectly node);
   T visitInvokeConstructor(InvokeConstructor node);
-  T visitThrow(Throw node);
-  T visitRethrow(Rethrow node);
-  T visitBranch(Branch node);
   T visitTypeCast(TypeCast node);
   T visitSetMutable(SetMutable node);
   T visitSetStatic(SetStatic node);
-  T visitGetLazyStatic(GetLazyStatic node);
   T visitSetField(SetField node);
-  T visitUnreachable(Unreachable node);
+  T visitGetLazyStatic(GetLazyStatic node);
   T visitAwait(Await node);
   T visitYield(Yield node);
-
-  // Definitions.
   T visitLiteralList(LiteralList node);
   T visitLiteralMap(LiteralMap node);
   T visitConstant(Constant node);
-  T visitCreateFunction(CreateFunction node);
   T visitGetMutable(GetMutable node);
   T visitParameter(Parameter node);
-  T visitContinuation(Continuation node);
   T visitMutableVariable(MutableVariable node);
   T visitGetStatic(GetStatic node);
   T visitInterceptor(Interceptor node);
@@ -1612,8 +1987,8 @@
   T visitGetIndex(GetIndex node);
   T visitSetIndex(SetIndex node);
   T visitRefinement(Refinement node);
-
-  // Support for literal foreign code.
+  T visitBoundsCheck(BoundsCheck node);
+  T visitNullCheck(NullCheck node);
   T visitForeignCode(ForeignCode node);
 }
 
@@ -1685,7 +2060,6 @@
   processInvokeStatic(InvokeStatic node) {}
   visitInvokeStatic(InvokeStatic node) {
     processInvokeStatic(node);
-    processReference(node.continuation);
     node.arguments.forEach(processReference);
   }
 
@@ -1700,7 +2074,6 @@
   visitInvokeMethod(InvokeMethod node) {
     processInvokeMethod(node);
     processReference(node.receiver);
-    processReference(node.continuation);
     node.arguments.forEach(processReference);
   }
 
@@ -1708,14 +2081,12 @@
   visitInvokeMethodDirectly(InvokeMethodDirectly node) {
     processInvokeMethodDirectly(node);
     processReference(node.receiver);
-    processReference(node.continuation);
     node.arguments.forEach(processReference);
   }
 
   processInvokeConstructor(InvokeConstructor node) {}
   visitInvokeConstructor(InvokeConstructor node) {
     processInvokeConstructor(node);
-    processReference(node.continuation);
     node.arguments.forEach(processReference);
   }
 
@@ -1741,7 +2112,6 @@
   processTypeCast(TypeCast node) {}
   visitTypeCast(TypeCast node) {
     processTypeCast(node);
-    processReference(node.continuation);
     processReference(node.value);
     node.typeArguments.forEach(processReference);
   }
@@ -1750,7 +2120,6 @@
   visitTypeTest(TypeTest node) {
     processTypeTest(node);
     processReference(node.value);
-    if (node.interceptor != null) processReference(node.interceptor);
     node.typeArguments.forEach(processReference);
   }
 
@@ -1770,7 +2139,6 @@
   processGetLazyStatic(GetLazyStatic node) {}
   visitGetLazyStatic(GetLazyStatic node) {
     processGetLazyStatic(node);
-    processReference(node.continuation);
   }
 
   processLiteralList(LiteralList node) {}
@@ -1793,12 +2161,6 @@
     processConstant(node);
   }
 
-  processCreateFunction(CreateFunction node) {}
-  visitCreateFunction(CreateFunction node) {
-    processCreateFunction(node);
-    visit(node.definition);
-  }
-
   processMutableVariable(node) {}
   visitMutableVariable(MutableVariable node) {
     processMutableVariable(node);
@@ -1844,6 +2206,9 @@
   processGetStatic(GetStatic node) {}
   visitGetStatic(GetStatic node) {
     processGetStatic(node);
+    if (node.witness != null) {
+      processReference(node.witness);
+    }
   }
 
   processSetStatic(SetStatic node) {}
@@ -1897,9 +2262,6 @@
   processForeignCode(ForeignCode node) {}
   visitForeignCode(ForeignCode node) {
     processForeignCode(node);
-    if (node.continuation != null) {
-      processReference(node.continuation);
-    }
     node.arguments.forEach(processReference);
   }
 
@@ -1912,14 +2274,12 @@
   visitAwait(Await node) {
     processAwait(node);
     processReference(node.input);
-    processReference(node.continuation);
   }
 
   processYield(Yield node) {}
   visitYield(Yield node) {
     processYield(node);
     processReference(node.input);
-    processReference(node.continuation);
   }
 
   processGetLength(GetLength node) {}
@@ -1948,6 +2308,27 @@
     processRefinement(node);
     processReference(node.value);
   }
+
+  processBoundsCheck(BoundsCheck node) {}
+  visitBoundsCheck(BoundsCheck node) {
+    processBoundsCheck(node);
+    processReference(node.object);
+    if (node.index != null) {
+      processReference(node.index);
+    }
+    if (node.length != null) {
+      processReference(node.length);
+    }
+  }
+
+  processNullCheck(NullCheck node) {}
+  visitNullCheck(NullCheck node) {
+    processNullCheck(node);
+    processReference(node.value);
+    if (node.condition != null) {
+      processReference(node.condition);
+    }
+  }
 }
 
 typedef void StackAction();
@@ -2004,7 +2385,9 @@
     if (cont.isReturnContinuation) {
       traverseContinuation(cont);
     } else {
-      _trampoline(traverseContinuation(cont));
+      int initialHeight = _stack.length;
+      Expression body = traverseContinuation(cont);
+      _trampoline(body, initialHeight: initialHeight);
     }
   }
 
@@ -2044,8 +2427,8 @@
     return node.body;
   }
 
-  void _trampoline(Expression node) {
-    int initialHeight = _stack.length;
+  void _trampoline(Expression node, {int initialHeight}) {
+    initialHeight = initialHeight ?? _stack.length;
     _processBlock(node);
     while (_stack.length > initialHeight) {
       StackAction callback = _stack.removeLast();
@@ -2079,3 +2462,380 @@
     (new RemovalVisitor()).visit(node);
   }
 }
+
+/// A visitor to copy instances of [Definition] or its subclasses, except for
+/// instances of [Continuation].
+///
+/// The visitor maintains a map from original definitions to their copies.
+/// When the [copy] method is called for a non-Continuation definition,
+/// a copy is created, added to the map and returned as the result. Copying a
+/// definition assumes that the definitions of all references have already
+/// been copied by the same visitor.
+class DefinitionCopyingVisitor extends Visitor<Definition> {
+  Map<Definition, Definition> _copies = <Definition, Definition>{};
+
+  /// Put a copy into the map.
+  ///
+  /// This method should be used instead of directly adding copies to the map.
+  Definition putCopy(Definition original, Definition copy) {
+    if (copy is Variable) {
+      Variable originalVariable = original;
+      copy.type = originalVariable.type;
+      copy.hint = originalVariable.hint;
+    }
+    return _copies[original] = copy;
+  }
+
+  /// Get the copy of a [Reference]'s definition from the map.
+  Definition getCopy(Reference reference) => _copies[reference.definition];
+
+  /// Map a list of [Reference]s to the list of their definition's copies.
+  List<Definition> getList(List<Reference> list) => list.map(getCopy).toList();
+
+  /// Copy a non-[Continuation] [Definition].
+  Definition copy(Definition node) {
+    assert (node is! Continuation);
+    return putCopy(node, visit(node));
+  }
+
+  Definition visit(Node node) => node.accept(this);
+
+  visitFunctionDefinition(FunctionDefinition node) {}
+  visitLetPrim(LetPrim node) {}
+  visitLetCont(LetCont node) {}
+  visitLetHandler(LetHandler node) {}
+  visitLetMutable(LetMutable node) {}
+  visitInvokeContinuation(InvokeContinuation node) {}
+  visitThrow(Throw node) {}
+  visitRethrow(Rethrow node) {}
+  visitBranch(Branch node) {}
+  visitUnreachable(Unreachable node) {}
+  visitContinuation(Continuation node) {}
+
+  Definition visitInvokeStatic(InvokeStatic node) {
+    return new InvokeStatic(node.target, node.selector, getList(node.arguments),
+        node.sourceInformation);
+  }
+
+  Definition visitInvokeMethod(InvokeMethod node) {
+    return new InvokeMethod(getCopy(node.receiver), node.selector, node.mask,
+        getList(node.arguments),
+        sourceInformation: node.sourceInformation,
+        callingConvention: node.callingConvention);
+  }
+
+  Definition visitInvokeMethodDirectly(InvokeMethodDirectly node) {
+    return new InvokeMethodDirectly(getCopy(node.receiver), node.target,
+        node.selector,
+        getList(node.arguments),
+        node.sourceInformation,
+        callingConvention: node.callingConvention);
+  }
+
+  Definition visitInvokeConstructor(InvokeConstructor node) {
+    return new InvokeConstructor(node.dartType, node.target, node.selector,
+        getList(node.arguments),
+        node.sourceInformation)
+        ..allocationSiteType = node.allocationSiteType;
+  }
+
+  Definition visitTypeCast(TypeCast node) {
+    return new TypeCast(getCopy(node.value), node.dartType,
+        getList(node.typeArguments));
+  }
+
+  Definition visitSetMutable(SetMutable node) {
+    return new SetMutable(getCopy(node.variable), getCopy(node.value));
+  }
+
+  Definition visitSetStatic(SetStatic node) {
+    return new SetStatic(node.element, getCopy(node.value),
+        node.sourceInformation);
+  }
+
+  Definition visitSetField(SetField node) {
+    return new SetField(getCopy(node.object), node.field, getCopy(node.value));
+  }
+
+  Definition visitGetLazyStatic(GetLazyStatic node) {
+    return new GetLazyStatic(node.element, node.sourceInformation);
+  }
+
+  Definition visitAwait(Await node) {
+    return new Await(getCopy(node.input));
+  }
+
+  Definition visitYield(Yield node) {
+    return new Yield(getCopy(node.input), node.hasStar);
+  }
+
+  Definition visitLiteralList(LiteralList node) {
+    return new LiteralList(node.dartType, getList(node.values))
+        ..allocationSiteType = node.allocationSiteType;
+  }
+
+  Definition visitLiteralMap(LiteralMap node) {
+    List<LiteralMapEntry> entries = node.entries.map((LiteralMapEntry entry) {
+      return new LiteralMapEntry(getCopy(entry.key), getCopy(entry.value));
+    }).toList();
+    return new LiteralMap(node.dartType, entries);
+  }
+
+  Definition visitConstant(Constant node) {
+    return new Constant(node.value, sourceInformation: node.sourceInformation);
+  }
+
+  Definition visitGetMutable(GetMutable node) {
+    return new GetMutable(getCopy(node.variable));
+  }
+
+  Definition visitParameter(Parameter node) {
+    return new Parameter(node.hint);
+  }
+
+  Definition visitMutableVariable(MutableVariable node) {
+    return new MutableVariable(node.hint);
+  }
+
+  Definition visitGetStatic(GetStatic node) {
+    return new GetStatic(node.element, node.sourceInformation);
+  }
+
+  Definition visitInterceptor(Interceptor node) {
+    return new Interceptor(getCopy(node.input), node.sourceInformation)
+        ..interceptedClasses.addAll(node.interceptedClasses);
+  }
+
+  Definition visitCreateInstance(CreateInstance node) {
+    return new CreateInstance(node.classElement, getList(node.arguments),
+        getList(node.typeInformation),
+        node.sourceInformation);
+  }
+
+  Definition visitGetField(GetField node) {
+    return new GetField(getCopy(node.object), node.field);
+  }
+
+  Definition visitCreateBox(CreateBox node) {
+    return new CreateBox();
+  }
+
+  Definition visitReifyRuntimeType(ReifyRuntimeType node) {
+    return new ReifyRuntimeType(getCopy(node.value), node.sourceInformation);
+  }
+
+  Definition visitReadTypeVariable(ReadTypeVariable node) {
+    return new ReadTypeVariable(node.variable, getCopy(node.target),
+        node.sourceInformation);
+  }
+
+  Definition visitTypeExpression(TypeExpression node) {
+    return new TypeExpression(node.dartType, getList(node.arguments));
+  }
+
+  Definition visitCreateInvocationMirror(CreateInvocationMirror node) {
+    return new CreateInvocationMirror(node.selector, getList(node.arguments));
+  }
+
+  Definition visitTypeTest(TypeTest node) {
+    return new TypeTest(getCopy(node.value), node.dartType,
+        getList(node.typeArguments));
+  }
+
+  Definition visitTypeTestViaFlag(TypeTestViaFlag node) {
+    return new TypeTestViaFlag(getCopy(node.interceptor), node.dartType);
+  }
+
+  Definition visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
+    return new ApplyBuiltinOperator(node.operator, getList(node.arguments),
+        node.sourceInformation);
+  }
+
+  Definition visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
+    return new ApplyBuiltinMethod(node.method, getCopy(node.receiver),
+        getList(node.arguments),
+        node.sourceInformation,
+        receiverIsNotNull: node.receiverIsNotNull);
+  }
+
+  Definition visitGetLength(GetLength node) {
+    return new GetLength(getCopy(node.object));
+  }
+
+  Definition visitGetIndex(GetIndex node) {
+    return new GetIndex(getCopy(node.object), getCopy(node.index));
+  }
+
+  Definition visitSetIndex(SetIndex node) {
+    return new SetIndex(getCopy(node.object), getCopy(node.index),
+        getCopy(node.value));
+  }
+
+  Definition visitRefinement(Refinement node) {
+    return new Refinement(getCopy(node.value), node.refineType);
+  }
+
+  Definition visitBoundsCheck(BoundsCheck node) {
+    if (node.hasNoChecks) {
+      return new BoundsCheck.noCheck(getCopy(node.object),
+          node.sourceInformation);
+    } else {
+      return new BoundsCheck(getCopy(node.object), getCopy(node.index),
+          node.length == null ? null : getCopy(node.length),
+          node.checks,
+          node.sourceInformation);
+    }
+  }
+
+  Definition visitNullCheck(NullCheck node) {
+    return new NullCheck(getCopy(node.value), node.sourceInformation,
+        condition: node.condition == null ? null : getCopy(node.condition),
+        selector: node.selector,
+        useSelector: node.useSelector);
+  }
+
+  Definition visitForeignCode(ForeignCode node) {
+    return new ForeignCode(node.codeTemplate, node.type,
+        getList(node.arguments),
+        node.nativeBehavior,
+        dependency: node.dependency);
+  }
+}
+
+/// A trampolining visitor to copy [FunctionDefinition]s.
+class CopyingVisitor extends TrampolineRecursiveVisitor {
+  // The visitor maintains a map from original continuations to their copies.
+  Map<Continuation, Continuation> _copies = <Continuation, Continuation>{};
+
+  // The visitor uses an auxiliary visitor to copy definitions.
+  DefinitionCopyingVisitor _definitions = new DefinitionCopyingVisitor();
+
+  // While copying a block, the state of the visitor is a 'linked list' of
+  // the expressions in the block's body, with a pointer to the last element
+  // of the list.
+  Expression _first = null;
+  Expression _current = null;
+
+  void plug(Expression body) {
+    if (_first == null) {
+      _first = body;
+    } else {
+      assert(_current != null);
+      InteriorExpression interior = _current;
+      interior.body = body;
+    }
+    _current = body;
+  }
+
+  // Continuations are added to the visitor's stack to be visited after copying
+  // the current block is finished.  The stack action saves the current block,
+  // copies the continuation's body, sets the body on the copy of the
+  // continuation, and restores the current block.
+  //
+  // Note that continuations are added to the copy map before the stack action
+  // to visit them is performed.
+  void push(Continuation cont) {
+    assert(!cont.isReturnContinuation);
+    _stack.add(() {
+      Expression savedFirst = _first;
+      _first = _current = null;
+      _processBlock(cont.body);
+      _copies[cont].body = _first;
+      _first = savedFirst;
+      _current = null;
+    });
+  }
+
+  FunctionDefinition copy(FunctionDefinition node) {
+    assert(_first == null && _current == null);
+    _first = _current = null;
+    // Definitions are copied where they are bound, before processing
+    // expressions in the scope of their binding.
+    Parameter thisParameter = node.thisParameter == null
+        ? null
+        : _definitions.copy(node.thisParameter);
+    List<Parameter> parameters =
+        node.parameters.map(_definitions.copy).toList();
+    // Though the return continuation's parameter does not have any uses,
+    // we still make a proper copy to ensure that hints, type, etc. are
+    // copied.
+    Parameter returnParameter =
+        _definitions.copy(node.returnContinuation.parameters.first);
+    Continuation returnContinuation = _copies[node.returnContinuation] =
+        new Continuation([returnParameter]);
+
+    visit(node.body);
+    FunctionDefinition copy = new FunctionDefinition(node.element,
+        thisParameter,
+        parameters,
+        returnContinuation,
+        _first);
+    _first = _current = null;
+    return copy;
+  }
+
+  Node visit(Node node) => node.accept(this);
+
+  Expression traverseLetCont(LetCont node) {
+    // Continuations are copied where they are bound, before processing
+    // expressions in the scope of their binding.
+    List<Continuation> continuations = node.continuations.map((Continuation c) {
+      push(c);
+      return _copies[c] =
+          new Continuation(c.parameters.map(_definitions.copy).toList());
+    }).toList();
+    plug(new LetCont.many(continuations, null));
+    return node.body;
+  }
+
+  Expression traverseLetHandler(LetHandler node) {
+    // Continuations are copied where they are bound, before processing
+    // expressions in the scope of their binding.
+    push(node.handler);
+    Continuation handler = _copies[node.handler] =
+        new Continuation(node.handler.parameters.map(_definitions.copy)
+            .toList());
+    plug(new LetHandler(handler, null));
+    return node.body;
+  }
+
+  Expression traverseLetPrim(LetPrim node) {
+    plug(new LetPrim(_definitions.copy(node.primitive)));
+    return node.body;
+  }
+
+  Expression traverseLetMutable(LetMutable node) {
+    plug(new LetMutable(_definitions.copy(node.variable),
+        _definitions.getCopy(node.value)));
+    return node.body;
+  }
+
+  // Tail expressions do not have references, so we do not need to map them
+  // to their copies.
+  visitInvokeContinuation(InvokeContinuation node) {
+    plug(new InvokeContinuation(_copies[node.continuation.definition],
+        _definitions.getList(node.arguments),
+        isRecursive: node.isRecursive,
+        isEscapingTry: node.isEscapingTry,
+        sourceInformation: node.sourceInformation));
+  }
+
+  visitThrow(Throw node) {
+    plug(new Throw(_definitions.getCopy(node.value)));
+  }
+
+  visitRethrow(Rethrow node) {
+    plug(new Rethrow());
+  }
+
+  visitBranch(Branch node) {
+    plug(new Branch.loose(_definitions.getCopy(node.condition),
+        _copies[node.trueContinuation.definition],
+        _copies[node.falseContinuation.definition])
+      ..isStrictCheck = node.isStrictCheck);
+  }
+
+  visitUnreachable(Unreachable node) {
+    plug(new Unreachable());
+  }
+}
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 79164b5..bde9b0e 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
@@ -33,6 +33,10 @@
     return decorator(r, namer.getName(r.definition));
   }
 
+  String optionalAccess(Reference<Definition> reference) {
+    return reference == null ? '()' : '(${access(reference)})';
+  }
+
   String visitParameter(Parameter node) {
     return namer.nameParameter(node);
   }
@@ -44,6 +48,7 @@
   /// Main entry point for creating a [String] from a [Node].  All recursive
   /// calls must go through this method.
   String visit(Node node) {
+    if (node == null) return '**** NULL ****';
     String s = node.accept(this);
     return decorator(node, s);
   }
@@ -108,72 +113,71 @@
   }
 
   String formatArguments(CallStructure call,
-                         List<Reference<Primitive>> arguments,
-                         {bool isIntercepted: false}) {
+      List<Reference<Primitive>> arguments,
+      [CallingConvention callingConvention = CallingConvention.Normal]) {
     int positionalArgumentCount = call.positionalArgumentCount;
-    if (isIntercepted) ++positionalArgumentCount;
+    if (callingConvention == CallingConvention.Intercepted ||
+        callingConvention == CallingConvention.DummyIntercepted) {
+      ++positionalArgumentCount;
+    }
     List<String> args =
-        arguments.getRange(0, positionalArgumentCount).map(access).toList();
+        arguments.take(positionalArgumentCount).map(access).toList();
     List<String> argumentNames = call.getOrderedNamedArguments();
     for (int i = 0; i < argumentNames.length; ++i) {
       String name = argumentNames[i];
       String arg = access(arguments[positionalArgumentCount + i]);
       args.add("($name: $arg)");
     }
+    // Constructors can have type parameter after the named arguments.
+    args.addAll(
+        arguments.skip(positionalArgumentCount + argumentNames.length)
+            .map(access));
     return '(${args.join(' ')})';
   }
 
   String visitInvokeStatic(InvokeStatic node) {
     String name = node.target.name;
-    String cont = access(node.continuation);
     String args = formatArguments(node.selector.callStructure, node.arguments);
-    return '$indentation(InvokeStatic $name $args $cont)';
+    return '(InvokeStatic $name $args)';
   }
 
   String visitInvokeMethod(InvokeMethod node) {
     String name = node.selector.name;
     String rcv = access(node.receiver);
-    String cont = access(node.continuation);
     String args = formatArguments(node.selector.callStructure, node.arguments,
-        isIntercepted: node.receiverIsIntercepted);
-    return '$indentation(InvokeMethod $rcv $name $args $cont)';
+        node.callingConvention);
+    return '(InvokeMethod $rcv $name $args)';
   }
 
   String visitInvokeMethodDirectly(InvokeMethodDirectly node) {
     String receiver = access(node.receiver);
     String name = node.selector.name;
-    String cont = access(node.continuation);
-    String args = formatArguments(node.selector.callStructure, node.arguments);
-    return '$indentation(InvokeMethodDirectly $receiver $name $args $cont)';
+    String args = formatArguments(node.selector.callStructure, node.arguments,
+        node.callingConvention);
+    return '(InvokeMethodDirectly $receiver $name $args)';
   }
 
   String visitInvokeConstructor(InvokeConstructor node) {
-    String className;
     // TODO(karlklose): for illegal nodes constructed for tests or unresolved
     // constructor calls in the DartBackend, we get an element with no enclosing
     // class.  Clean this up by introducing a name field to the node and
     // removing [ErroneousElement]s from the IR.
-    if (node.dartType != null) {
-      className = node.dartType.toString();
-    } else {
-      className = node.target.enclosingClass.name;
+    String name = node.dartType != null
+        ? node.dartType.toString()
+        : node.target.enclosingClass.name;
+    if (!node.target.name.isEmpty) {
+      name = '${name}.${node.target.name}';
     }
-    String callName;
-    if (node.target.name.isEmpty) {
-      callName = '${className}';
-    } else {
-      callName = '${className}.${node.target.name}';
-    }
-    String cont = access(node.continuation);
     String args = formatArguments(node.selector.callStructure, node.arguments);
-    return '$indentation(InvokeConstructor $callName $args $cont)';
+    return '(InvokeConstructor $name $args)';
   }
 
   String visitInvokeContinuation(InvokeContinuation node) {
     String name = access(node.continuation);
     if (node.isRecursive) name = 'rec $name';
     String args = node.arguments.map(access).join(' ');
-    return '$indentation(InvokeContinuation $name ($args))';
+    String escaping = node.isEscapingTry ? ' escape' : '';
+    return '$indentation(InvokeContinuation $name ($args)$escaping)';
   }
 
   String visitThrow(Throw node) {
@@ -202,12 +206,6 @@
     return '(Constant $value)';
   }
 
-  String visitCreateFunction(CreateFunction node) {
-    String function =
-        indentBlock(() => indentBlock(() => visit(node.definition)));
-    return '(CreateFunction\n$function)';
-  }
-
   String visitContinuation(Continuation node) {
     String name = newContinuationName(node);
     if (node.isRecursive) name = 'rec $name';
@@ -232,19 +230,14 @@
 
   String visitTypeCast(TypeCast node) {
     String value = access(node.value);
-    String cont = access(node.continuation);
     String typeArguments = node.typeArguments.map(access).join(' ');
-    return '$indentation(TypeCast $value ${node.dartType}'
-                         ' ($typeArguments) $cont)';
+    return '(TypeCast $value ${node.dartType} ($typeArguments))';
   }
 
   String visitTypeTest(TypeTest node) {
     String value = access(node.value);
     String typeArguments = node.typeArguments.map(access).join(' ');
-    String interceptor = node.interceptor == null
-        ? ''
-        : access(node.interceptor);
-    return '(TypeTest $value ${node.dartType} ($typeArguments) ($interceptor))';
+    return '(TypeTest $value ${node.dartType} ($typeArguments))';
   }
 
   String visitTypeTestViaFlag(TypeTestViaFlag node) {
@@ -289,8 +282,7 @@
 
   String visitGetLazyStatic(GetLazyStatic node) {
     String element = node.element.name;
-    String cont = access(node.continuation);
-    return '$indentation(GetLazyStatic $element $cont)';
+    return '(GetLazyStatic $element)';
   }
 
   String visitCreateBox(CreateBox node) {
@@ -342,10 +334,7 @@
 
   String visitForeignCode(ForeignCode node) {
     String arguments = node.arguments.map(access).join(' ');
-    String continuation = node.continuation == null ? ''
-        : ' ${access(node.continuation)}';
-    return '$indentation(JS "${node.codeTemplate.source}"'
-        ' ($arguments)$continuation)';
+    return '(JS "${node.codeTemplate.source}" ($arguments))';
   }
 
   String visitGetLength(GetLength node) {
@@ -369,21 +358,32 @@
   @override
   String visitAwait(Await node) {
     String value = access(node.input);
-    String continuation = access(node.continuation);
-    return '(Await $value $continuation)';
+    return '(Await $value)';
   }
 
   @override
   String visitYield(Yield node) {
     String value = access(node.input);
-    String continuation = access(node.continuation);
-    return '(Yield $value $continuation)';
+    return '(Yield $value)';
   }
 
   String visitRefinement(Refinement node) {
     String value = access(node.value);
     return '(Refinement $value ${node.type})';
   }
+
+  String visitBoundsCheck(BoundsCheck node) {
+    String object = access(node.object);
+    String index = optionalAccess(node.index);
+    String length = optionalAccess(node.length);
+    return '(BoundsCheck $object $index $length ${node.checkString})';
+  }
+
+  String visitNullCheck(NullCheck node) {
+    String value = access(node.value);
+    String condition = optionalAccess(node.condition);
+    return '(NullCheck $value $condition (${node.selector ?? ""}))';
+  }
 }
 
 class ConstantStringifier extends ConstantValueVisitor<String, Null> {
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 1b4d2f4..e732f3d 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -81,17 +81,15 @@
         });
       });
       tag("HIR", () {
+        String formatParameter(cps_ir.Parameter param) {
+          return '${names.name(param)} ${param.type}';
+        }
         if (entryPointParameters != null) {
-          String formatParameter(cps_ir.Parameter param) {
-            return '${names.name(param)} ${param.type}';
-          }
           String params = entryPointParameters.map(formatParameter).join(', ');
           printStmt('x0', 'Entry ($params)');
         }
-        for (cps_ir.Parameter param in block.parameters) {
-          String name = names.name(param);
-          printStmt(name, "Parameter $name [useCount=${countUses(param)}]");
-        }
+        String params = block.parameters.map(formatParameter).join(', ');
+        printStmt('x0', 'Parameters ($params)');
         visit(block.body);
       });
     });
@@ -142,35 +140,26 @@
   }
 
   visitInvokeStatic(cps_ir.InvokeStatic node) {
-    String dummy = names.name(node);
     String callName = node.selector.name;
     String args = node.arguments.map(formatReference).join(', ');
-    String kont = formatReference(node.continuation);
-    printStmt(dummy, "InvokeStatic $callName ($args) $kont");
+    return "InvokeStatic $callName ($args)";
   }
 
   visitInvokeMethod(cps_ir.InvokeMethod node) {
-    String dummy = names.name(node);
     String receiver = formatReference(node.receiver);
     String callName = node.selector.name;
     String args = node.arguments.map(formatReference).join(', ');
-    String kont = formatReference(node.continuation);
-    printStmt(dummy,
-        "InvokeMethod $receiver $callName ($args) $kont");
+    return "InvokeMethod $receiver $callName ($args)";
   }
 
   visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
-    String dummy = names.name(node);
     String receiver = formatReference(node.receiver);
     String callName = node.selector.name;
     String args = node.arguments.map(formatReference).join(', ');
-    String kont = formatReference(node.continuation);
-    printStmt(dummy,
-        "InvokeMethodDirectly $receiver $callName ($args) $kont");
+    return "InvokeMethodDirectly $receiver $callName ($args)";
   }
 
   visitInvokeConstructor(cps_ir.InvokeConstructor node) {
-    String dummy = names.name(node);
     String className = node.target.enclosingClass.name;
     String callName;
     if (node.target.name.isEmpty) {
@@ -179,8 +168,7 @@
       callName = '${className}.${node.target.name}';
     }
     String args = node.arguments.map(formatReference).join(', ');
-    String kont = formatReference(node.continuation);
-    printStmt(dummy, "InvokeConstructor $callName ($args) $kont");
+    return "InvokeConstructor $callName ($args)";
   }
 
   visitThrow(cps_ir.Throw node) {
@@ -215,11 +203,9 @@
   }
 
   visitTypeCast(cps_ir.TypeCast node) {
-    String dummy = names.name(node);
     String value = formatReference(node.value);
     String args = node.typeArguments.map(formatReference).join(', ');
-    String kont = formatReference(node.continuation);
-    printStmt(dummy, "TypeCast ($value ${node.dartType} ($args)) $kont");
+    return "TypeCast ($value ${node.dartType} ($args))";
   }
 
   visitInvokeContinuation(cps_ir.InvokeContinuation node) {
@@ -239,18 +225,14 @@
   }
 
   visitAwait(cps_ir.Await node) {
-    String dummy = names.name(node);
     String value = formatReference(node.input);
-    String continuation = formatReference(node.continuation);
-    printStmt(dummy, 'Await $value $continuation');
+    return 'Await $value';
   }
 
   visitYield(cps_ir.Yield node) {
-    String dummy = names.name(node);
     String name = node.hasStar ? 'YieldStar' : 'Yield';
     String value = formatReference(node.input);
-    String continuation = formatReference(node.continuation);
-    printStmt(dummy, '$name $value $continuation');
+    return '$name $value';
   }
 
   visitSetMutable(cps_ir.SetMutable node) {
@@ -260,6 +242,7 @@
   }
 
   String formatReference(cps_ir.Reference ref) {
+    if (ref == null) return 'null';
     cps_ir.Definition target = ref.definition;
     if (target is cps_ir.Continuation && target.isReturnContinuation) {
       return "return"; // Do not generate a name for the return continuation
@@ -309,9 +292,8 @@
   }
 
   visitGetLazyStatic(cps_ir.GetLazyStatic node) {
-    String dummy = names.name(node);
-    String kont = formatReference(node.continuation);
-    printStmt(dummy, "GetLazyStatic $kont");
+    String element = node.element.name;
+    return "GetLazyStatic $element";
   }
 
   visitCreateBox(cps_ir.CreateBox node) {
@@ -327,11 +309,8 @@
   }
 
   visitInterceptor(cps_ir.Interceptor node) {
-    return "Interceptor(${formatReference(node.input)})";
-  }
-
-  visitCreateFunction(cps_ir.CreateFunction node) {
-    return "CreateFunction ${node.definition.element.name}";
+    return 'Interceptor(${formatReference(node.input)}, '
+           '${node.interceptedClasses})';
   }
 
   visitGetMutable(cps_ir.GetMutable node) {
@@ -361,10 +340,7 @@
   visitTypeTest(cps_ir.TypeTest node) {
     String value = formatReference(node.value);
     String args = node.typeArguments.map(formatReference).join(', ');
-    String interceptor = node.interceptor == null
-        ? ''
-        : ' ${formatReference(node.interceptor)}';
-    return "TypeTest ($value ${node.dartType} ($args)$interceptor)";
+    return "TypeTest ($value ${node.dartType} ($args))";
   }
 
   visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) {
@@ -385,13 +361,11 @@
     return 'ApplyBuiltinMethod $method $receiver ($args)';
   }
 
-  @override
   visitForeignCode(cps_ir.ForeignCode node) {
     String id = names.name(node);
     String arguments = node.arguments.map(formatReference).join(', ');
-    String continuation = formatReference(node.continuation);
-    printStmt(id, "ForeignCode ${node.type} ${node.codeTemplate.source} "
-        "$arguments $continuation");
+    printStmt(id,
+        "ForeignCode ${node.type} ${node.codeTemplate.source} $arguments");
   }
 
   visitGetLength(cps_ir.GetLength node) {
@@ -412,10 +386,26 @@
     return 'SetIndex $object $index $value';
   }
 
-  @override
   visitRefinement(cps_ir.Refinement node) {
     String value = formatReference(node.value);
-    return 'Refinement $value ${node.type}';
+    return 'Refinement $value ${node.refineType}';
+  }
+
+  visitBoundsCheck(cps_ir.BoundsCheck node) {
+    String object = formatReference(node.object);
+    String index = node.index == null
+        ? 'no-index'
+        : formatReference(node.index);
+    String length = node.length == null
+        ? 'no-length'
+        : formatReference(node.length);
+    return 'BoundsCheck $object $index $length ${node.checkString}';
+  }
+
+  visitNullCheck(cps_ir.NullCheck node) {
+    String value = formatReference(node.value);
+    String condition = formatReference(node.condition);
+    return 'NullCheck $value condition:$condition selector:${node.selector}';
   }
 }
 
@@ -527,20 +517,20 @@
     addEdgeToContinuation(exp.continuation);
   }
 
-  visitInvokeStatic(cps_ir.InvokeStatic exp) {
-    addEdgeToContinuation(exp.continuation);
+  visitInvokeStatic(cps_ir.InvokeStatic node) {
+    unexpectedNode(node);
   }
 
-  visitInvokeMethod(cps_ir.InvokeMethod exp) {
-    addEdgeToContinuation(exp.continuation);
+  visitInvokeMethod(cps_ir.InvokeMethod node) {
+    unexpectedNode(node);
   }
 
-  visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly exp) {
-    addEdgeToContinuation(exp.continuation);
+  visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
+    unexpectedNode(node);
   }
 
-  visitInvokeConstructor(cps_ir.InvokeConstructor exp) {
-    addEdgeToContinuation(exp.continuation);
+  visitInvokeConstructor(cps_ir.InvokeConstructor node) {
+    unexpectedNode(node);
   }
 
   visitThrow(cps_ir.Throw exp) {
@@ -552,8 +542,8 @@
   visitUnreachable(cps_ir.Unreachable node) {
   }
 
-  visitGetLazyStatic(cps_ir.GetLazyStatic exp) {
-    addEdgeToContinuation(exp.continuation);
+  visitGetLazyStatic(cps_ir.GetLazyStatic node) {
+    unexpectedNode(node);
   }
 
   visitBranch(cps_ir.Branch exp) {
@@ -567,8 +557,8 @@
     }
   }
 
-  visitTypeCast(cps_ir.TypeCast exp) {
-    addEdgeToContinuation(exp.continuation);
+  visitTypeCast(cps_ir.TypeCast node) {
+    unexpectedNode(node);
   }
 
   visitContinuation(cps_ir.Continuation c) {
@@ -596,10 +586,6 @@
     unexpectedNode(node);
   }
 
-  visitCreateFunction(cps_ir.CreateFunction node) {
-    unexpectedNode(node);
-  }
-
   visitGetMutable(cps_ir.GetMutable node) {
     unexpectedNode(node);
   }
@@ -688,23 +674,27 @@
     unexpectedNode(node);
   }
 
-  @override
   visitForeignCode(cps_ir.ForeignCode node) {
-    addEdgeToContinuation(node.continuation);
+    unexpectedNode(node);
   }
 
-  @override
   visitAwait(cps_ir.Await node) {
-    addEdgeToContinuation(node.continuation);
+    unexpectedNode(node);
   }
 
-  @override
   visitYield(cps_ir.Yield node) {
-    addEdgeToContinuation(node.continuation);
+    unexpectedNode(node);
   }
 
-  @override
   visitRefinement(cps_ir.Refinement node) {
     unexpectedNode(node);
   }
+
+  visitBoundsCheck(cps_ir.BoundsCheck node) {
+    unexpectedNode(node);
+  }
+
+  visitNullCheck(cps_ir.NullCheck node) {
+    unexpectedNode(node);
+  }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart b/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart
new file mode 100644
index 0000000..6f733e3
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.cps_ir.eagerly_load_statics;
+
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart' show Pass;
+import '../elements/elements.dart';
+
+/// Replaces [GetLazyStatic] with [GetStatic] when the static field is known
+/// to have been initialized.
+///
+/// Apart from [GetStatic] generating better code, this improves the side-effect
+/// analysis in the [GVN] pass, since [GetStatic] has no effects.
+class EagerlyLoadStatics extends TrampolineRecursiveVisitor implements Pass {
+  String get passName => 'Eagerly load statics';
+
+  Map<FieldElement, Primitive> initializerFor = <FieldElement, Primitive>{};
+
+  final Map<Continuation, Map<FieldElement, Primitive>> initializersAt =
+      <Continuation, Map<FieldElement, Primitive>>{};
+
+  static Map<FieldElement, Primitive> cloneFieldMap(
+        Map<FieldElement, Primitive> map) {
+    return new Map<FieldElement, Primitive>.from(map);
+  }
+
+  void rewrite(FunctionDefinition node) {
+    visit(node.body);
+  }
+
+  Expression traverseLetCont(LetCont node) {
+    for (Continuation cont in node.continuations) {
+      initializersAt[cont] = cloneFieldMap(initializerFor);
+      push(cont);
+    }
+    return node.body;
+  }
+
+  Expression traverseLetHandler(LetHandler node) {
+    initializersAt[node.handler] = cloneFieldMap(initializerFor);
+    push(node.handler);
+    return node.body;
+  }
+
+  Expression traverseContinuation(Continuation cont) {
+    initializerFor = initializersAt[cont];
+    return cont.body;
+  }
+
+  void visitGetLazyStatic(GetLazyStatic node) {
+    Primitive initializer = initializerFor[node.element];
+    if (initializer != null) {
+      GetStatic newNode = new GetStatic.witnessed(node.element, initializer,
+          node.sourceInformation);
+      newNode.type = node.type;
+      node.replaceWith(newNode);
+    } else {
+      initializerFor[node.element] = node;
+    }
+  }
+
+  void visitSetStatic(SetStatic node) {
+    initializerFor.putIfAbsent(node.element, () => node);
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/finalize.dart b/pkg/compiler/lib/src/cps_ir/finalize.dart
new file mode 100644
index 0000000..1406a58
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/finalize.dart
@@ -0,0 +1,81 @@
+library dart2js.cps_ir.finalize;
+
+import 'cps_ir_nodes.dart';
+import 'cps_fragment.dart';
+import 'optimizers.dart' show Pass;
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../js_backend/backend_helpers.dart';
+
+/// A transformation pass that must run immediately before the tree IR builder.
+///
+/// This expands [BoundsCheck] nodes into more low-level operations.
+class Finalize extends TrampolineRecursiveVisitor implements Pass {
+  String get passName => 'Finalize';
+
+  JavaScriptBackend backend;
+  BackendHelpers get helpers => backend.helpers;
+
+  Finalize(this.backend);
+
+  void rewrite(FunctionDefinition node) {
+    visit(node);
+  }
+
+  Expression traverseLetPrim(LetPrim node) {
+    CpsFragment cps = visit(node.primitive);
+    if (cps == null) return node.body;
+    cps.insertBelow(node);
+    Expression next = node.body;
+    node.remove();
+    return next;
+  }
+
+  bool areAdjacent(Primitive first, Primitive second) {
+    return first.parent == second.parent.parent;
+  }
+
+  CpsFragment visitBoundsCheck(BoundsCheck node) {
+    CpsFragment cps = new CpsFragment(node.sourceInformation);
+    if (node.hasNoChecks) {
+      node..replaceUsesWith(node.object.definition)..destroy();
+      return cps;
+    }
+    Continuation fail = cps.letCont();
+    if (node.hasLowerBoundCheck) {
+      cps.ifTruthy(cps.applyBuiltin(BuiltinOperator.NumLt,
+          [node.index.definition, cps.makeZero()]))
+          .invokeContinuation(fail);
+    }
+    if (node.hasUpperBoundCheck) {
+      Primitive length = node.length.definition;
+      if (length is GetLength &&
+          length.hasExactlyOneUse &&
+          areAdjacent(length, node)) {
+        // Rebind the GetLength here, so it does not get stuck outside the
+        // condition, blocked from propagating by the lower bounds check.
+        LetPrim lengthBinding = length.parent;
+        lengthBinding.remove();
+        cps.letPrim(length);
+      }
+      cps.ifTruthy(cps.applyBuiltin(BuiltinOperator.NumGe,
+          [node.index.definition, length]))
+          .invokeContinuation(fail);
+    }
+    if (node.hasEmptinessCheck) {
+      cps.ifTruthy(cps.applyBuiltin(BuiltinOperator.StrictEq,
+          [node.length.definition, cps.makeZero()]))
+          .invokeContinuation(fail);
+    }
+    cps.insideContinuation(fail).invokeStaticThrower(
+          helpers.throwIndexOutOfRangeException,
+          [node.object.definition, node.index.definition]);
+    node..replaceUsesWith(node.object.definition)..destroy();
+    return cps;
+  }
+
+  void visitGetStatic(GetStatic node) {
+    if (node.witness != null) {
+      node..witness.unlink()..witness = null;
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/gvn.dart b/pkg/compiler/lib/src/cps_ir/gvn.dart
new file mode 100644
index 0000000..a4a591f
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/gvn.dart
@@ -0,0 +1,769 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.cps_ir.gvn;
+
+import 'cps_ir_nodes.dart';
+import '../universe/side_effects.dart';
+import '../elements/elements.dart';
+import 'optimizers.dart' show Pass;
+import 'loop_hierarchy.dart';
+import 'loop_effects.dart';
+import '../world.dart';
+import '../compiler.dart' show Compiler;
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../constants/values.dart';
+import 'type_mask_system.dart';
+
+/// Eliminates redundant primitives by reusing the value of another primitive
+/// that is known to have the same result.  Primitives are also hoisted out of
+/// loops when possible.
+///
+/// Reusing values can introduce new temporaries, which in some cases is more
+/// expensive than recomputing the value on-demand. For example, pulling an
+/// expression such as "n+1" out of a loop is generally not worth it.
+/// Such primitives are said to be "trivial".
+///
+/// Trivial primitives are shared on-demand, i.e. they are only shared if
+/// this enables a non-trivial primitive to be hoisted out of a loop.
+//
+//  TODO(asgerf): Enable hoisting across refinement guards when this is safe:
+//    - Determine the type required for a given primitive to be "safe"
+//    - Recompute the type of a primitive after hoisting.
+//        E.g. GetIndex on a String can become a GetIndex on an arbitrary
+//             indexable, which is still safe but the type may change
+//    - Since the new type may be worse, insert a refinement at the old
+//      definition site, so we do not degrade existing type information.
+//
+//  TODO(asgerf): Put this pass at a better place in the pipeline.  We currently
+//    cannot put it anywhere we want, because this pass relies on refinement
+//    nodes being present (for safety), whereas other passes rely on refinement
+//    nodes being absent (for simplicity & precision).
+//
+class GVN extends TrampolineRecursiveVisitor implements Pass {
+  String get passName => 'GVN';
+
+  final Compiler compiler;
+  final TypeMaskSystem types;
+  JavaScriptBackend get backend => compiler.backend;
+  World get world => compiler.world;
+
+  final GvnTable gvnTable = new GvnTable();
+  GvnVectorBuilder gvnVectorBuilder;
+  LoopHierarchy loopHierarchy;
+  LoopSideEffects loopEffects;
+
+  /// Effect numbers at the given join point.
+  Map<Continuation, EffectNumbers> effectsAt = <Continuation, EffectNumbers>{};
+
+  /// The effect numbers at the current position (during traversal).
+  EffectNumbers effectNumbers = new EffectNumbers();
+
+  /// The loop currently enclosing the binding of a given primitive.
+  final Map<Primitive, Continuation> loopHeaderFor =
+      <Primitive, Continuation>{};
+
+  /// The GVNs for primitives that have been hoisted outside the given loop.
+  ///
+  /// These should be removed from the environment when exiting the loop.
+  final Map<Continuation, List<int>> loopHoistedBindings =
+      <Continuation, List<int>>{};
+
+  /// Maps GVNs to a currently-in-scope binding for that value.
+  final Map<int, Primitive> environment = <int, Primitive>{};
+
+  /// Maps GVN'able primitives to their global value number.
+  final Map<Primitive, int> gvnFor = <Primitive, int>{};
+
+  Continuation currentLoopHeader;
+
+  GVN(this.compiler, this.types);
+
+  int _usedEffectNumbers = 0;
+  int makeNewEffect() => ++_usedEffectNumbers;
+
+  void rewrite(FunctionDefinition node) {
+    gvnVectorBuilder = new GvnVectorBuilder(gvnFor, compiler, types);
+    loopHierarchy = new LoopHierarchy(node);
+    loopEffects =
+        new LoopSideEffects(node, world, loopHierarchy: loopHierarchy);
+    visit(node);
+  }
+
+  // ------------------ GLOBAL VALUE NUMBERING ---------------------
+
+  /// True if [prim] can be eliminated if its value is already in scope.
+  bool canReplaceWithExistingValue(Primitive prim) {
+    // Primitives that have no side effects other than potentially throwing are
+    // known not the throw if the value is already in scope. Handling those
+    // specially is equivalent to updating refinements during GVN.
+    // GetLazyStatic cannot have side effects because the field has already
+    // been initialized.
+    return prim.isSafeForElimination ||
+           prim is GetField ||
+           prim is GetLength ||
+           prim is GetIndex ||
+           prim is GetLazyStatic;
+  }
+
+  @override
+  Expression traverseLetPrim(LetPrim node) {
+    Expression next = node.body;
+    Primitive prim = node.primitive;
+
+    loopHeaderFor[prim] = currentLoopHeader;
+
+    if (prim is Refinement) {
+      // Do not share refinements (they have no runtime or code size cost), and
+      // do not put them in the GVN table because GvnVectorBuilder unfolds
+      // refinements by itself.
+      return next;
+    }
+
+    // Update effect numbers due to side effects from a static initializer.
+    // GetLazyStatic is GVN'ed like a GetStatic, but the effects of the static
+    // initializer occur before reading the field.
+    if (prim is GetLazyStatic) {
+      visit(prim);
+    }
+
+    // Compute the GVN vector for this computation.
+    List vector = gvnVectorBuilder.make(prim, effectNumbers);
+
+    // Update effect numbers due to side effects.
+    // Do this after computing the GVN vector so the primitive's GVN is not
+    // influenced by its own side effects, except in the case of GetLazyStatic.
+    if (prim is! GetLazyStatic) {
+      visit(prim);
+    }
+
+    if (vector == null) {
+      // The primitive is not GVN'able. Move on.
+      return next;
+    }
+
+    // Compute the GVN for this primitive.
+    int gvn = gvnTable.insert(vector);
+    gvnFor[prim] = gvn;
+
+    // Try to reuse a previously computed value with the same GVN.
+    Primitive existing = environment[gvn];
+    if (existing != null &&
+        canReplaceWithExistingValue(prim) &&
+        !isFastConstant(prim)) {
+      if (prim is Interceptor) {
+        Interceptor interceptor = existing;
+        interceptor.interceptedClasses.addAll(prim.interceptedClasses);
+      }
+      prim..replaceUsesWith(existing)..destroy();
+      node.remove();
+      return next;
+    }
+
+    if (tryToHoistOutOfLoop(prim, gvn)) {
+      return next;
+    }
+
+    // The primitive could not be hoisted.  Put the primitive in the
+    // environment while processing the body of the LetPrim.
+    environment[gvn] = prim;
+    pushAction(() {
+      assert(environment[gvn] == prim);
+      environment[gvn] = existing;
+    });
+
+    return next;
+  }
+
+  bool isFirstImpureExpressionInLoop(Expression exp) {
+    InteriorNode node = exp.parent;
+    for (; node is Expression; node = node.parent) {
+      if (node is LetPrim && node.primitive.isSafeForElimination) {
+        continue;
+      }
+      if (node is LetCont) {
+        continue;
+      }
+      return false;
+    }
+    return node == currentLoopHeader;
+  }
+
+  bool isHoistablePrimitive(Primitive prim) {
+    if (prim.isSafeForElimination) return true;
+    if (prim is NullCheck ||
+        prim is BoundsCheck ||
+        prim is GetLength ||
+        prim is GetField ||
+        prim is GetIndex) {
+      // Expressions that potentially throw but have no other effects can be
+      // hoisted if they occur as the first impure expression in a loop.
+      // Note regarding BoundsCheck: the current array length is an input to
+      // check, so the check itself has no heap dependency.  It will only be
+      // hoisted if the length was hoisted.
+      // TODO(asgerf): In general we could hoist these out of multiple loops,
+      //   but the trick we use here only works for one loop level.
+      return isFirstImpureExpressionInLoop(prim.parent);
+    }
+    return false;
+  }
+
+  /// Try to hoist the binding of [prim] out of loops. Returns `true` if it was
+  /// hoisted or marked as a trivial hoist-on-demand primitive.
+  bool tryToHoistOutOfLoop(Primitive prim, int gvn) {
+    // Bail out fast if the primitive is not inside a loop.
+    if (currentLoopHeader == null) return false;
+
+    // Do not hoist primitives with side effects.
+    if (!isHoistablePrimitive(prim)) return false;
+
+    LetPrim letPrim = prim.parent;
+
+    // Find the depth of the outermost scope where we can bind the primitive
+    // without bringing a reference out of scope. 0 is the depth of the
+    // top-level scope.
+    int hoistDepth = 0;
+    List<Primitive> inputsHoistedOnDemand = <Primitive>[];
+    InputVisitor.forEach(prim, (Reference ref) {
+      Primitive input = ref.definition;
+      if (canIgnoreRefinementGuards(prim)) {
+        input = input.effectiveDefinition;
+      }
+      if (isFastConstant(input)) {
+        // Fast constants can be hoisted all the way out, but should only be
+        // hoisted if needed to hoist something else.
+        inputsHoistedOnDemand.add(input);
+      } else {
+        Continuation loopHeader = loopHeaderFor[input];
+        Continuation referencedLoop =
+            loopHierarchy.lowestCommonAncestor(loopHeader, currentLoopHeader);
+        int depth = loopHierarchy.getDepth(referencedLoop);
+        if (depth > hoistDepth) {
+          hoistDepth = depth;
+        }
+      }
+    });
+
+    // Bail out if it can not be hoisted further out than it is now.
+    if (hoistDepth == loopHierarchy.getDepth(currentLoopHeader)) return false;
+
+    // Walk up the loop hierarchy and check at every step that any heap
+    // dependencies can safely be hoisted out of the loop.
+    Continuation enclosingLoop = currentLoopHeader;
+    Continuation hoistTarget = null;
+    while (loopHierarchy.getDepth(enclosingLoop) > hoistDepth &&
+           canHoistHeapDependencyOutOfLoop(prim, enclosingLoop)) {
+      hoistTarget = enclosingLoop;
+      enclosingLoop = loopHierarchy.getEnclosingLoop(enclosingLoop);
+    }
+
+    // Bail out if heap dependencies prohibit any hoisting at all.
+    if (hoistTarget == null) return false;
+
+    if (isFastConstant(prim)) {
+      // The overhead from introducting a temporary might be greater than
+      // the overhead of evaluating this primitive at every iteration.
+      // Only hoist if this enables hoisting of a non-trivial primitive.
+      return true;
+    }
+
+    LetCont loopBinding = hoistTarget.parent;
+
+    // The primitive may depend on values that have not yet been
+    // hoisted as far as they can.  Hoist those now.
+    for (Primitive input in inputsHoistedOnDemand) {
+      hoistTrivialPrimitive(input, loopBinding, enclosingLoop);
+    }
+
+    // Hoist the primitive.
+    letPrim.remove();
+    letPrim.insertAbove(loopBinding);
+    loopHeaderFor[prim] = enclosingLoop;
+
+    // If a refinement guard was bypassed, use the best refinement
+    // currently in scope.
+    if (canIgnoreRefinementGuards(prim)) {
+      int target = loopHierarchy.getDepth(enclosingLoop);
+      InputVisitor.forEach(prim, (Reference ref) {
+        Primitive input = ref.definition;
+        while (input is Refinement) {
+          Continuation loop = loopHeaderFor[input];
+          loop = loopHierarchy.lowestCommonAncestor(loop, currentLoopHeader);
+          if (loopHierarchy.getDepth(loop) <= target) break;
+          Refinement refinement = input;
+          input = refinement.value.definition;
+        }
+        ref.changeTo(input);
+      });
+    }
+
+    // Put the primitive in the environment while processing the loop.
+    environment[gvn] = prim;
+    loopHoistedBindings
+        .putIfAbsent(hoistTarget, () => <int>[])
+        .add(gvn);
+    return true;
+  }
+
+  /// If the given primitive is a trivial primitive that should be hoisted
+  /// on-demand, hoist it and its dependent values above [loopBinding].
+  void hoistTrivialPrimitive(Primitive prim,
+                             LetCont loopBinding,
+                             Continuation enclosingLoop) {
+    assert(isFastConstant(prim));
+
+    // The primitive might already be bound in an outer scope.  Do not relocate
+    // the primitive unless we are lifting it. For example;
+    //    t1 = a + b
+    //    t2 = t1 + c
+    //    t3 = t1 * t2
+    // If it was decided that `t3` should be hoisted, `t1` will be seen twice by
+    // this method: by the direct reference and by reference through `t2`.
+    // The second time it is seen, it will already have been moved.
+    Continuation currentLoop = loopHeaderFor[prim];
+    int currentDepth = loopHierarchy.getDepth(currentLoop);
+    int targetDepth = loopHierarchy.getDepth(enclosingLoop);
+    if (currentDepth <= targetDepth) return;
+
+    // Hoist the trivial primitives being depended on so they remain in scope.
+    InputVisitor.forEach(prim, (Reference ref) {
+      hoistTrivialPrimitive(ref.definition, loopBinding, enclosingLoop);
+    });
+
+    // Move the primitive.
+    LetPrim binding = prim.parent;
+    binding.remove();
+    binding.insertAbove(loopBinding);
+    loopHeaderFor[prim] = enclosingLoop;
+  }
+
+  bool canIgnoreRefinementGuards(Primitive primitive) {
+    return primitive is Interceptor;
+  }
+
+  /// Returns true if [prim] is a constant that has no significant runtime cost.
+  bool isFastConstant(Primitive prim) {
+    return prim is Constant && (prim.value.isPrimitive || prim.value.isDummy);
+  }
+
+  /// True if [element] is a final or constant field or a function.
+  bool isImmutable(Element element) {
+    if (element.isField && backend.isNative(element)) return false;
+    return element.isField && world.fieldNeverChanges(element) ||
+           element.isFunction;
+  }
+
+  bool isImmutableLength(GetLength length) {
+    return types.isDefinitelyFixedLengthIndexable(length.object.definition.type,
+        allowNull: true);
+  }
+
+  /// Assuming [prim] has no side effects, returns true if it can safely
+  /// be hoisted out of [loop] without changing its value or changing the timing
+  /// of a thrown exception.
+  bool canHoistHeapDependencyOutOfLoop(Primitive prim, Continuation loop) {
+    // If the primitive might throw, we have to check that it is the first
+    // impure expression in the loop.  This has already been checked if
+    // [loop] is the current loop header, but for other loops we just give up.
+    if (!prim.isSafeForElimination && loop != currentLoopHeader) {
+      return false;
+    }
+    if (prim is GetLength && !isImmutableLength(prim)) {
+      return !loopEffects.loopChangesLength(loop);
+    } else if (prim is GetField && !isImmutable(prim.field)) {
+      return !loopEffects.getSideEffectsInLoop(loop).changesInstanceProperty();
+    } else if (prim is GetStatic && !isImmutable(prim.element)) {
+      return !loopEffects.getSideEffectsInLoop(loop).changesStaticProperty();
+    } else if (prim is GetIndex) {
+      return !loopEffects.getSideEffectsInLoop(loop).changesIndex();
+    } else {
+      return true;
+    }
+  }
+
+  // ------------------ TRAVERSAL AND EFFECT NUMBERING ---------------------
+  //
+  // These methods traverse the IR while updating the current effect numbers.
+  // They are not specific to GVN.
+  //
+  // TODO(asgerf): Avoid duplicated code for side effect analysis.
+  // Should be easier to fix once primitives and call expressions are the same.
+
+  void addSideEffects(SideEffects fx, {bool length: true}) {
+    if (fx.changesInstanceProperty()) {
+      effectNumbers.instanceField = makeNewEffect();
+    }
+    if (fx.changesStaticProperty()) {
+      effectNumbers.staticField = makeNewEffect();
+    }
+    if (fx.changesIndex()) {
+      effectNumbers.indexableContent = makeNewEffect();
+    }
+    if (length && fx.changesIndex()) {
+      effectNumbers.indexableLength = makeNewEffect();
+    }
+  }
+
+  void addAllSideEffects() {
+    effectNumbers.instanceField = makeNewEffect();
+    effectNumbers.staticField = makeNewEffect();
+    effectNumbers.indexableContent = makeNewEffect();
+    effectNumbers.indexableLength = makeNewEffect();
+  }
+
+  Expression traverseLetHandler(LetHandler node) {
+    // Assume any kind of side effects may occur in the try block.
+    effectsAt[node.handler] = new EffectNumbers()
+      ..instanceField = makeNewEffect()
+      ..staticField = makeNewEffect()
+      ..indexableContent = makeNewEffect()
+      ..indexableLength = makeNewEffect();
+    push(node.handler);
+    return node.body;
+  }
+
+  Expression traverseContinuation(Continuation cont) {
+    Continuation oldLoopHeader = currentLoopHeader;
+    currentLoopHeader = loopHierarchy.getLoopHeader(cont);
+    pushAction(() {
+      currentLoopHeader = oldLoopHeader;
+    });
+    for (Parameter param in cont.parameters) {
+      loopHeaderFor[param] = currentLoopHeader;
+    }
+    if (cont.isRecursive) {
+      addSideEffects(loopEffects.getSideEffectsInLoop(cont), length: false);
+      if (loopEffects.loopChangesLength(cont)) {
+        effectNumbers.indexableLength = makeNewEffect();
+      }
+      pushAction(() {
+        List<int> hoistedBindings = loopHoistedBindings[cont];
+        if (hoistedBindings != null) {
+          hoistedBindings.forEach(environment.remove);
+        }
+      });
+    } else {
+      EffectNumbers join = effectsAt[cont];
+      if (join != null) {
+        effectNumbers = join;
+      } else {
+        // This is a call continuation seen immediately after its use.
+        // Reuse the current effect numbers.
+      }
+    }
+
+    return cont.body;
+  }
+
+  void visitInvokeContinuation(InvokeContinuation node) {
+    Continuation cont = node.continuation.definition;
+    if (cont.isRecursive) return;
+    EffectNumbers join = effectsAt[cont];
+    if (join == null) {
+      effectsAt[cont] = effectNumbers.copy();
+    } else {
+      if (effectNumbers.instanceField != join.instanceField) {
+        join.instanceField = makeNewEffect();
+      }
+      if (effectNumbers.staticField != join.staticField) {
+        join.staticField = makeNewEffect();
+      }
+      if (effectNumbers.indexableContent != join.indexableContent) {
+        join.indexableContent = makeNewEffect();
+      }
+      if (effectNumbers.indexableLength != join.indexableLength) {
+        join.indexableLength = makeNewEffect();
+      }
+    }
+  }
+
+  void visitBranch(Branch node) {
+    Continuation trueCont = node.trueContinuation.definition;
+    Continuation falseCont = node.falseContinuation.definition;
+    // Copy the effect number vector once, so the analysis of one branch does
+    // not influence the other.
+    effectsAt[trueCont] = effectNumbers;
+    effectsAt[falseCont] = effectNumbers.copy();
+  }
+
+  void visitInvokeMethod(InvokeMethod node) {
+    addSideEffects(world.getSideEffectsOfSelector(node.selector, node.mask));
+  }
+
+  void visitInvokeStatic(InvokeStatic node) {
+    addSideEffects(world.getSideEffectsOfElement(node.target));
+  }
+
+  void visitInvokeMethodDirectly(InvokeMethodDirectly node) {
+    FunctionElement target = node.target;
+    if (target is ConstructorBodyElement) {
+      ConstructorBodyElement body = target;
+      target = body.constructor;
+    }
+    addSideEffects(world.getSideEffectsOfElement(target));
+  }
+
+  void visitInvokeConstructor(InvokeConstructor node) {
+    addSideEffects(world.getSideEffectsOfElement(node.target));
+  }
+
+  void visitSetStatic(SetStatic node) {
+    effectNumbers.staticField = makeNewEffect();
+  }
+
+  void visitSetField(SetField node) {
+    effectNumbers.instanceField = makeNewEffect();
+  }
+
+  void visitSetIndex(SetIndex node) {
+    effectNumbers.indexableContent = makeNewEffect();
+  }
+
+  void visitForeignCode(ForeignCode node) {
+    addSideEffects(node.nativeBehavior.sideEffects);
+  }
+
+  void visitGetLazyStatic(GetLazyStatic node) {
+    // TODO(asgerf): How do we get the side effects of a lazy field initializer?
+    addAllSideEffects();
+  }
+
+  void visitAwait(Await node) {
+    addAllSideEffects();
+  }
+
+  void visitYield(Yield node) {
+    addAllSideEffects();
+  }
+
+  void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
+    // Push and pop.
+    effectNumbers.indexableContent = makeNewEffect();
+    effectNumbers.indexableLength = makeNewEffect();
+  }
+}
+
+/// For each of the four categories of heap locations, the IR is divided into
+/// regions wherein the given heap locations are known not to be modified.
+///
+/// Each region is identified by its "effect number".  Effect numbers from
+/// different categories have no relationship to each other.
+class EffectNumbers {
+  int indexableLength = 0;
+  int indexableContent = 0;
+  int staticField = 0;
+  int instanceField = 0;
+
+  EffectNumbers copy() {
+    return new EffectNumbers()
+      ..indexableLength = indexableLength
+      ..indexableContent = indexableContent
+      ..staticField = staticField
+      ..instanceField = instanceField;
+  }
+}
+
+/// Maps vectors to numbers, such that two vectors with the same contents
+/// map to the same number.
+class GvnTable {
+  Map<GvnEntry, int> _table = <GvnEntry, int>{};
+  int _usedGvns = 0;
+  int _makeNewGvn() => ++_usedGvns;
+
+  int insert(List vector) {
+    return _table.putIfAbsent(new GvnEntry(vector), _makeNewGvn);
+  }
+}
+
+/// Wrapper around a [List] that compares for equality based on contents
+/// instead of object identity.
+class GvnEntry {
+  final List vector;
+  final int hashCode;
+
+  GvnEntry(List vector) : vector = vector, hashCode = computeHashCode(vector);
+
+  bool operator==(other) {
+    if (other is! GvnEntry) return false;
+    GvnEntry entry = other;
+    List otherVector = entry.vector;
+    if (vector.length != otherVector.length) return false;
+    for (int i = 0; i < vector.length; ++i) {
+      if (vector[i] != otherVector[i]) return false;
+    }
+    return true;
+  }
+
+  /// Combines the hash codes of [vector] using Jenkin's hash function, with
+  /// intermediate results truncated to SMI range.
+  static int computeHashCode(List vector) {
+    int hash = 0;
+    for (int i = 0; i < vector.length; ++i) {
+      hash = 0x1fffffff & (hash + vector[i].hashCode);
+      hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+      hash = hash ^ (hash >> 6);
+    }
+    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) <<  3));
+    hash = hash ^ (hash >> 11);
+    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+  }
+}
+
+/// Converts GVN'able primitives to a vector containing all the values
+/// to be considered when computing a GVN for it.
+///
+/// This includes the instruction type, inputs, effect numbers for any part
+/// of the heap being depended on, as well as any instruction-specific payload
+/// such as any DartTypes, Elements, and operator kinds.
+///
+/// Each `visit` or `process` method for a primitive must initialize [vector]
+/// if the primitive is GVN'able and fill in any components except the inputs.
+/// The inputs will be filled in by [processReference].
+class GvnVectorBuilder extends DeepRecursiveVisitor {
+  List vector;
+  final Map<Primitive, int> gvnFor;
+  final Compiler compiler;
+  World get world => compiler.world;
+  JavaScriptBackend get backend => compiler.backend;
+  final TypeMaskSystem types;
+  EffectNumbers effectNumbers;
+
+  GvnVectorBuilder(this.gvnFor, this.compiler, this.types);
+
+  List make(Primitive prim, EffectNumbers effectNumbers) {
+    this.effectNumbers = effectNumbers;
+    vector = null;
+    visit(prim);
+    return vector;
+  }
+
+  /// The `process` methods below do not insert the referenced arguments into
+  /// the vector, but instead rely on them being inserted here.
+  processReference(Reference ref) {
+    if (vector == null) return;
+    Primitive prim = ref.definition.effectiveDefinition;
+    vector.add(gvnFor[prim] ?? prim);
+  }
+
+  processTypeTest(TypeTest node) {
+    vector = [GvnCode.TYPE_TEST, node.dartType];
+  }
+
+  processTypeTestViaFlag(TypeTestViaFlag node) {
+    vector = [GvnCode.TYPE_TEST_VIA_FLAG, node.dartType];
+  }
+
+  processApplyBuiltinOperator(ApplyBuiltinOperator node) {
+    vector = [GvnCode.BUILTIN_OPERATOR, node.operator.index];
+  }
+
+  processGetLength(GetLength node) {
+    if (isImmutableLength(node)) {
+      // Omit the effect number for fixed-length lists.  Note that if a the list
+      // gets refined to a fixed-length type, we still won't be able to GVN a
+      // GetLength across the refinement, because the first GetLength uses an
+      // effect number in its vector while the second one does not.
+      vector = [GvnCode.GET_LENGTH];
+    } else {
+      vector = [GvnCode.GET_LENGTH, effectNumbers.indexableLength];
+    }
+  }
+
+  bool isImmutable(Element element) {
+    return element.isFunction ||
+           element.isField && world.fieldNeverChanges(element);
+  }
+
+  bool isImmutableLength(GetLength length) {
+    return types.isDefinitelyFixedLengthIndexable(length.object.definition.type,
+        allowNull: true);
+  }
+
+  bool isNativeField(FieldElement field) {
+    // TODO(asgerf): We should add a GetNativeField instruction.
+    return backend.isNative(field);
+  }
+
+  processGetField(GetField node) {
+    if (isNativeField(node.field)) {
+      vector = null; // Native field access cannot be GVN'ed.
+    } else if (isImmutable(node.field)) {
+      vector = [GvnCode.GET_FIELD, node.field];
+    } else {
+      vector = [GvnCode.GET_FIELD, node.field, effectNumbers.instanceField];
+    }
+  }
+
+  processGetIndex(GetIndex node) {
+    vector = [GvnCode.GET_INDEX, effectNumbers.indexableContent];
+  }
+
+  visitGetStatic(GetStatic node) {
+    if (isImmutable(node.element)) {
+      vector = [GvnCode.GET_STATIC, node.element];
+    } else {
+      vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField];
+    }
+    // Suppress visit to witness argument.
+  }
+
+  processGetLazyStatic(GetLazyStatic node) {
+    if (isImmutable(node.element)) {
+      vector = [GvnCode.GET_STATIC, node.element];
+    } else {
+      vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField];
+    }
+  }
+
+  processConstant(Constant node) {
+    vector = [GvnCode.CONSTANT, node.value];
+  }
+
+  processReifyRuntimeType(ReifyRuntimeType node) {
+    vector = [GvnCode.REIFY_RUNTIME_TYPE];
+  }
+
+  processReadTypeVariable(ReadTypeVariable node) {
+    vector = [GvnCode.READ_TYPE_VARIABLE, node.variable];
+  }
+
+  processTypeExpression(TypeExpression node) {
+    vector = [GvnCode.TYPE_EXPRESSION, node.dartType];
+  }
+
+  processInterceptor(Interceptor node) {
+    vector = [GvnCode.INTERCEPTOR];
+  }
+}
+
+class GvnCode {
+  static const int TYPE_TEST = 1;
+  static const int TYPE_TEST_VIA_FLAG = 2;
+  static const int BUILTIN_OPERATOR = 3;
+  static const int GET_LENGTH = 4;
+  static const int GET_FIELD = 5;
+  static const int GET_INDEX = 6;
+  static const int GET_STATIC = 7;
+  static const int CONSTANT = 8;
+  static const int REIFY_RUNTIME_TYPE = 9;
+  static const int READ_TYPE_VARIABLE = 10;
+  static const int TYPE_EXPRESSION = 11;
+  static const int INTERCEPTOR = 12;
+}
+
+typedef ReferenceCallback(Reference ref);
+class InputVisitor extends DeepRecursiveVisitor {
+  ReferenceCallback callback;
+
+  InputVisitor(this.callback);
+
+  @override
+  processReference(Reference ref) {
+    callback(ref);
+  }
+
+  static void forEach(Primitive node, ReferenceCallback callback) {
+    new InputVisitor(callback).visit(node);
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/inline.dart b/pkg/compiler/lib/src/cps_ir/inline.dart
new file mode 100644
index 0000000..cc046ee
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/inline.dart
@@ -0,0 +1,536 @@
+// 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 cps_ir.optimization.inline;
+
+import 'cps_fragment.dart';
+import 'cps_ir_builder.dart' show ThisParameterLocal;
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart';
+import 'type_mask_system.dart' show TypeMaskSystem;
+import '../dart_types.dart' show DartType, GenericType;
+import '../world.dart' show World;
+import '../elements/elements.dart';
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../js_backend/codegen/task.dart' show CpsFunctionCompiler;
+import '../types/types.dart' show
+    FlatTypeMask, ForwardingTypeMask, TypeMask, UnionTypeMask;
+import '../universe/call_structure.dart' show CallStructure;
+import '../universe/selector.dart' show Selector;
+
+/// Inlining stack entries.
+///
+/// During inlining, a stack is used to detect cycles in the call graph.
+class StackEntry {
+  // Dynamically resolved calls might be targeting an adapter function that
+  // fills in optional arguments not passed at the call site.  Therefore these
+  // calls are represented by the eventual target and the call structure at
+  // the call site, which together identify the target.  Statically resolved
+  // calls are represented by the target element and a null call structure.
+  final ExecutableElement target;
+  final CallStructure callStructure;
+
+  StackEntry(this.target, this.callStructure);
+
+  bool match(ExecutableElement otherTarget, CallStructure otherCallStructure) {
+    if (target != otherTarget) return false;
+    if (callStructure == null) return otherCallStructure == null;
+    return otherCallStructure != null &&
+        callStructure.match(otherCallStructure);
+  }
+}
+
+/// Inlining cache entries.
+class CacheEntry {
+  // The cache maps a function element to a list of entries, where each entry
+  // is a tuple of (call structure, abstract receiver, abstract arguments)
+  // along with the inlining decision and optional IR function definition.
+  final CallStructure callStructure;
+  final TypeMask receiver;
+  final List<TypeMask> arguments;
+
+  final bool decision;
+  final FunctionDefinition function;
+
+  CacheEntry(this.callStructure, this.receiver, this.arguments, this.decision,
+      this.function);
+
+  bool match(CallStructure otherCallStructure, TypeMask otherReceiver,
+      List<TypeMask> otherArguments) {
+    if (callStructure == null) {
+      if (otherCallStructure != null) return false;
+    } else if (otherCallStructure == null ||
+               !callStructure.match(otherCallStructure)) {
+      return false;
+    }
+
+    if (receiver != otherReceiver) return false;
+    assert(arguments.length == otherArguments.length);
+    for (int i = 0; i < arguments.length; ++i) {
+      if (arguments[i] != otherArguments[i]) return false;
+    }
+    return true;
+  }
+}
+
+/// An inlining cache.
+///
+/// During inlining a cache is used to remember inlining decisions for shared
+/// parts of the call graph, to avoid exploring them more than once.
+///
+/// The cache maps a tuple of (function element, call structure,
+/// abstract receiver, abstract arguments) to a boolean inlining decision and
+/// an IR function definition if the decision is positive.
+class InliningCache {
+  static const int ABSENT = -1;
+  static const int NO_INLINE = 0;
+
+  final Map<ExecutableElement, List<CacheEntry>> map =
+      <ExecutableElement, List<CacheEntry>>{};
+
+  // When function definitions are put into or removed from the cache, they are
+  // copied because the compiler passes will mutate them.
+  final CopyingVisitor copier = new CopyingVisitor();
+
+  void _putInternal(ExecutableElement element, CallStructure callStructure,
+      TypeMask receiver,
+      List<TypeMask> arguments,
+      bool decision,
+      FunctionDefinition function) {
+    map.putIfAbsent(element, () => <CacheEntry>[])
+        .add(new CacheEntry(callStructure, receiver, arguments, decision,
+            function));
+  }
+
+  /// Put a positive inlining decision in the cache.
+  ///
+  /// A positive inlining decision maps to an IR function definition.
+  void putPositive(ExecutableElement element, CallStructure callStructure,
+      TypeMask receiver,
+      List<TypeMask> arguments,
+      FunctionDefinition function) {
+    _putInternal(element, callStructure, receiver, arguments, true,
+        copier.copy(function));
+  }
+
+  /// Put a negative inlining decision in the cache.
+  void putNegative(ExecutableElement element,
+      CallStructure callStructure,
+      TypeMask receiver,
+      List<TypeMask> arguments) {
+    _putInternal(element, callStructure, receiver, arguments, false, null);
+  }
+
+  /// Look up a tuple in the cache.
+  ///
+  /// A positive lookup result return the IR function definition.  A negative
+  /// lookup result returns [NO_INLINE].  If there is no cached result,
+  /// [ABSENT] is returned.
+  get(ExecutableElement element, CallStructure callStructure, TypeMask receiver,
+      List<TypeMask> arguments) {
+    List<CacheEntry> entries = map[element];
+    if (entries != null) {
+      for (CacheEntry entry in entries) {
+        if (entry.match(callStructure, receiver, arguments)) {
+          if (entry.decision) {
+            FunctionDefinition function = copier.copy(entry.function);
+            ParentVisitor.setParents(function);
+            return function;
+          }
+          return NO_INLINE;
+        }
+      }
+    }
+    return ABSENT;
+  }
+}
+
+class Inliner implements Pass {
+  get passName => 'Inline calls';
+
+  final CpsFunctionCompiler functionCompiler;
+
+  final InliningCache cache = new InliningCache();
+
+  final List<StackEntry> stack = <StackEntry>[];
+
+  Inliner(this.functionCompiler);
+
+  bool isCalledOnce(Element element) {
+    return functionCompiler.compiler.typesTask.typesInferrer.isCalledOnce(
+        element);
+  }
+
+  void rewrite(FunctionDefinition node, [CallStructure callStructure]) {
+    ExecutableElement function = node.element;
+
+    // Inlining in asynchronous or generator functions is disabled.  Inlining
+    // triggers a bug in the async rewriter.
+    // TODO(kmillikin): Fix the bug and eliminate this restriction if it makes
+    // sense.
+    if (function is FunctionElement &&
+        function.asyncMarker != AsyncMarker.SYNC) {
+      return;
+    }
+
+    // Do not inline in functions containing try statements.  V8 does not
+    // optimize code in such functions, so inlining will move optimizable code
+    // into a context where it cannot be optimized.
+    if (function.resolvedAst.elements.containsTryStatement) {
+      return;
+    }
+
+    stack.add(new StackEntry(function, callStructure));
+    new InliningVisitor(this).visit(node);
+    assert(stack.last.match(function, callStructure));
+    stack.removeLast();
+    new ShrinkingReducer().rewrite(node);
+  }
+}
+
+/// Compute an abstract size of an IR function definition.
+///
+/// The size represents the cost of inlining at a call site.
+class SizeVisitor extends TrampolineRecursiveVisitor {
+  int size = 0;
+
+  void countArgument(Reference<Primitive> argument, Parameter parameter) {
+    // If a parameter is unused and the corresponding argument has only the
+    // one use at the invocation, then inlining the call might enable
+    // elimination of the argument.  This 'pays for itself' by decreasing the
+    // cost of inlining at the call site.
+    if (argument != null &&
+        argument.definition.hasExactlyOneUse &&
+        parameter.hasNoUses) {
+      --size;
+    }
+  }
+
+  static int sizeOf(InvocationPrimitive invoke, FunctionDefinition function) {
+    SizeVisitor visitor = new SizeVisitor();
+    visitor.visit(function);
+    visitor.countArgument(invoke.receiver, function.thisParameter);
+    for (int i = 0; i < invoke.arguments.length; ++i) {
+      visitor.countArgument(invoke.arguments[i], function.parameters[i]);
+    }
+    return visitor.size;
+  }
+
+  // Inlining a function incurs a cost equal to the number of primitives and
+  // non-jump tail expressions.
+  // TODO(kmillikin): Tune the size computation and size bound.
+  processLetPrim(LetPrim node) {
+    if (node.primitive is! Refinement) {
+      ++size;
+    }
+  }
+  processLetMutable(LetMutable node) => ++size;
+  processBranch(Branch node) => ++size;
+  processThrow(Throw nose) => ++size;
+  processRethrow(Rethrow node) => ++size;
+}
+
+class InliningVisitor extends TrampolineRecursiveVisitor {
+  final Inliner _inliner;
+
+  // A successful inlining attempt returns the [Primitive] that represents the
+  // result of the inlined call or null.  If the result is non-null, the body
+  // of the inlined function is available in this field.
+  CpsFragment _fragment;
+
+  InliningVisitor(this._inliner);
+
+  JavaScriptBackend get backend => _inliner.functionCompiler.backend;
+  TypeMaskSystem get typeSystem => _inliner.functionCompiler.typeSystem;
+  World get world => _inliner.functionCompiler.compiler.world;
+
+  FunctionDefinition compileToCpsIr(AstElement element) {
+    return _inliner.functionCompiler.compileToCpsIr(element);
+  }
+
+  void optimizeBeforeInlining(FunctionDefinition function) {
+    _inliner.functionCompiler.optimizeCpsBeforeInlining(function);
+  }
+
+  void applyCpsPass(Pass pass, FunctionDefinition function) {
+    return _inliner.functionCompiler.applyCpsPass(pass, function);
+  }
+
+  bool isRecursive(Element target, CallStructure callStructure) {
+    return _inliner.stack.any((StackEntry s) => s.match(target, callStructure));
+  }
+
+  @override
+  Expression traverseLetPrim(LetPrim node) {
+    // A successful inlining attempt will set the node's body to null, so it is
+    // read before visiting the primitive.
+    Expression next = node.body;
+    Primitive replacement = visit(node.primitive);
+    if (replacement != null) {
+      node.primitive.replaceWithFragment(_fragment, replacement);
+    }
+    return next;
+  }
+
+  TypeMask abstractType(Reference<Primitive> ref) {
+    return ref.definition.type ?? typeSystem.dynamicType;
+  }
+
+  /// Build the IR term for the function that adapts a call site targeting a
+  /// function that takes optional arguments not passed at the call site.
+  FunctionDefinition buildAdapter(InvokeMethod node, FunctionElement target) {
+    Parameter thisParameter = new Parameter(new ThisParameterLocal(target))
+        ..type = node.receiver.definition.type;
+    List<Parameter> parameters = new List<Parameter>.generate(
+        node.arguments.length,
+        (int index) {
+          // TODO(kmillikin): Use a hint for the parameter names.
+          return new Parameter(null)
+              ..type = node.arguments[index].definition.type;
+        });
+    Continuation returnContinuation = new Continuation.retrn();
+    CpsFragment cps = new CpsFragment();
+
+    FunctionSignature signature = target.functionSignature;
+    int requiredParameterCount = signature.requiredParameterCount;
+    if (node.callingConvention == CallingConvention.Intercepted ||
+        node.callingConvention == CallingConvention.DummyIntercepted) {
+      ++requiredParameterCount;
+    }
+    List<Primitive> arguments = new List<Primitive>.generate(
+        requiredParameterCount,
+        (int index) => parameters[index]);
+
+    int parameterIndex = requiredParameterCount;
+    CallStructure newCallStructure;
+    if (signature.optionalParametersAreNamed) {
+      List<String> incomingNames =
+          node.selector.callStructure.getOrderedNamedArguments();
+      List<String> outgoingNames = <String>[];
+      int nameIndex = 0;
+      signature.orderedOptionalParameters.forEach((ParameterElement formal) {
+        if (nameIndex < incomingNames.length &&
+            formal.name == incomingNames[nameIndex]) {
+          arguments.add(parameters[parameterIndex++]);
+          ++nameIndex;
+        } else {
+          Constant defaultValue = cps.makeConstant(
+              backend.constants.getConstantValueForVariable(formal));
+          defaultValue.type = typeSystem.getParameterType(formal);
+          arguments.add(defaultValue);
+        }
+        outgoingNames.add(formal.name);
+      });
+      newCallStructure =
+      new CallStructure(signature.parameterCount, outgoingNames);
+    } else {
+      signature.forEachOptionalParameter((ParameterElement formal) {
+        if (parameterIndex < parameters.length) {
+          arguments.add(parameters[parameterIndex++]);
+        } else {
+          Constant defaultValue = cps.makeConstant(
+              backend.constants.getConstantValueForVariable(formal));
+          defaultValue.type = typeSystem.getParameterType(formal);
+          arguments.add(defaultValue);
+        }
+      });
+      newCallStructure = new CallStructure(signature.parameterCount);
+    }
+
+    Selector newSelector =
+        new Selector(node.selector.kind, node.selector.memberName,
+            newCallStructure);
+    Primitive result = cps.invokeMethod(thisParameter, newSelector, node.mask,
+        arguments, node.callingConvention);
+    result.type = typeSystem.getInvokeReturnType(node.selector, node.mask);
+    cps.invokeContinuation(returnContinuation, <Primitive>[result]);
+    return new FunctionDefinition(target, thisParameter, parameters,
+        returnContinuation,
+        cps.root);
+  }
+
+  // Given an invocation and a known target, possibly perform inlining.
+  //
+  // An optional call structure indicates a dynamic call.  Calls that are
+  // already resolved statically have a null call structure.
+  //
+  // The [Primitive] representing the result of the inlined call is returned
+  // if the call was inlined, and the inlined function body is available in
+  // [_fragment].  If the call was not inlined, null is returned.
+  Primitive tryInlining(InvocationPrimitive invoke, FunctionElement target,
+                        CallStructure callStructure) {
+    // Quick checks: do not inline or even cache calls to targets without an
+    // AST node, targets that are asynchronous or generator functions, or
+    // targets containing a try statement.
+    if (!target.hasNode) return null;
+    if (target.asyncMarker != AsyncMarker.SYNC) return null;
+    // V8 does not optimize functions containing a try statement.  Inlining
+    // code containing a try statement will make the optimizable calling code
+    // become unoptimizable.
+    if (target.resolvedAst.elements.containsTryStatement) {
+      return null;
+    }
+
+    Reference<Primitive> dartReceiver = invoke.dartReceiverReference;
+    TypeMask abstractReceiver =
+        dartReceiver == null ? null : abstractType(dartReceiver);
+    // The receiver is non-null in a method body, unless the receiver is known
+    // to be `null` (isEmpty covers `null` and unreachable).
+    TypeMask abstractReceiverInMethod = abstractReceiver == null
+        ? null
+        : abstractReceiver.isEmpty
+            ? abstractReceiver
+            : abstractReceiver.nonNullable();
+    List<TypeMask> abstractArguments =
+        invoke.arguments.map(abstractType).toList();
+    var cachedResult = _inliner.cache.get(target, callStructure,
+        abstractReceiverInMethod,
+        abstractArguments);
+
+    // Negative inlining result in the cache.
+    if (cachedResult == InliningCache.NO_INLINE) return null;
+
+    Primitive finish(FunctionDefinition function) {
+      _fragment = new CpsFragment(invoke.sourceInformation);
+      Primitive receiver = invoke.receiver?.definition;
+      List<Primitive> arguments =
+          invoke.arguments.map((Reference ref) => ref.definition).toList();
+      // Add a null check to the inlined function body if necessary.  The
+      // cached function body does not contain the null check.
+      if (dartReceiver != null && abstractReceiver.isNullable) {
+        Primitive check = nullReceiverGuard(
+            invoke, _fragment, dartReceiver.definition, abstractReceiver);
+        if (invoke.callingConvention == CallingConvention.Intercepted) {
+          arguments[0] = check;
+        } else {
+          receiver = check;
+        }
+      }
+      return _fragment.inlineFunction(function, receiver, arguments,
+          hint: invoke.hint);
+    }
+
+    // Positive inlining result in the cache.
+    if (cachedResult is FunctionDefinition) {
+      return finish(cachedResult);
+    }
+
+    // We have not seen this combination of target and abstract arguments
+    // before.  Make an inlining decision.
+    assert(cachedResult == InliningCache.ABSENT);
+    Primitive doNotInline() {
+      _inliner.cache.putNegative(
+          target, callStructure, abstractReceiverInMethod, abstractArguments);
+      return null;
+    }
+    if (backend.annotations.noInline(target)) return doNotInline();
+    if (isRecursive(target, callStructure)) return doNotInline();
+
+    FunctionDefinition function;
+    if (callStructure != null &&
+        target.functionSignature.parameterCount !=
+            callStructure.argumentCount) {
+      // The argument count at the call site does not match the target's
+      // formal parameter count.  Build the IR term for an adapter function
+      // body.
+      function = buildAdapter(invoke, target);
+    } else {
+      function = _inliner.functionCompiler.compileToCpsIr(target);
+      void setValue(Variable variable, Reference<Primitive> value) {
+        variable.type = value.definition.type;
+      }
+      if (invoke.callingConvention == CallingConvention.Intercepted) {
+        setValue(function.thisParameter, invoke.receiver);
+        function.parameters[0].type = abstractReceiverInMethod;
+        for (int i = 1; i < invoke.arguments.length; ++i) {
+          setValue(function.parameters[i], invoke.arguments[i]);
+        }
+      } else {
+        if (invoke.receiver != null) {
+          function.thisParameter.type = abstractReceiverInMethod;
+        }
+        for (int i = 0; i < invoke.arguments.length; ++i) {
+          setValue(function.parameters[i], invoke.arguments[i]);
+        }
+      }
+      optimizeBeforeInlining(function);
+    }
+
+    // Inline calls in the body.
+    _inliner.rewrite(function, callStructure);
+
+    // Compute the size.
+    // TODO(kmillikin): Tune the size bound.
+    int size = SizeVisitor.sizeOf(invoke, function);
+    if (!_inliner.isCalledOnce(target) && size > 11) return doNotInline();
+
+    _inliner.cache.putPositive(target, callStructure, abstractReceiverInMethod,
+        abstractArguments, function);
+    return finish(function);
+  }
+
+  Primitive nullReceiverGuard(InvocationPrimitive invoke,
+                              CpsFragment fragment,
+                              Primitive dartReceiver,
+                              TypeMask abstractReceiver) {
+    Selector selector = invoke is InvokeMethod ? invoke.selector : null;
+    if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) {
+      Primitive condition = _fragment.letPrim(
+          new ApplyBuiltinOperator(BuiltinOperator.IsNotNumber,
+                                   <Primitive>[dartReceiver],
+                                   invoke.sourceInformation));
+      condition.type = typeSystem.boolType;
+      Primitive check = _fragment.letPrim(
+          new NullCheck.guarded(
+              condition, dartReceiver, selector, invoke.sourceInformation));
+      check.type = abstractReceiver.nonNullable();
+      return check;
+    }
+
+    Primitive check = _fragment.letPrim(
+        new NullCheck(dartReceiver, invoke.sourceInformation,
+                      selector: selector));
+    check.type = abstractReceiver.nonNullable();
+    return check;
+  }
+
+
+  @override
+  Primitive visitInvokeStatic(InvokeStatic node) {
+    return tryInlining(node, node.target, null);
+  }
+
+  @override
+  Primitive visitInvokeMethod(InvokeMethod node) {
+    Primitive receiver = node.dartReceiver;
+    Element element = world.locateSingleElement(node.selector, receiver.type);
+    if (element == null || element is! FunctionElement) return null;
+    if (node.selector.isGetter != element.isGetter) return null;
+    if (node.selector.isSetter != element.isSetter) return null;
+    if (node.selector.name != element.name) return null;
+
+    return tryInlining(node, element.asFunctionElement(),
+        node.selector.callStructure);
+  }
+
+  @override
+  Primitive visitInvokeMethodDirectly(InvokeMethodDirectly node) {
+    if (node.selector.isGetter != node.target.isGetter) return null;
+    if (node.selector.isSetter != node.target.isSetter) return null;
+    return tryInlining(node, node.target, null);
+  }
+
+  @override
+  Primitive visitInvokeConstructor(InvokeConstructor node) {
+    if (node.dartType is GenericType) {
+      // We cannot inline a constructor invocation containing type arguments
+      // because CreateInstance in the body does not know the type arguments.
+      // We would incorrectly instantiate a class like A instead of A<B>.
+      // TODO(kmillikin): try to fix this.
+      GenericType generic = node.dartType;
+      if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null;
+    }
+    return tryInlining(node, node.target, null);
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart b/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
index e9a0364..207753f 100644
--- a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
+++ b/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
@@ -4,10 +4,13 @@
 
 library cps_ir.optimization.insert_refinements;
 
+import 'dart:math' show min;
 import 'optimizers.dart' show Pass;
 import 'cps_ir_nodes.dart';
+import '../elements/elements.dart';
 import '../common/names.dart';
 import '../types/types.dart' show TypeMask;
+import '../universe/selector.dart';
 import 'type_mask_system.dart';
 
 /// Inserts [Refinement] nodes in the IR to allow for sparse path-sensitive
@@ -34,9 +37,13 @@
 
   /// Updates references to refer to the refinement currently in scope.
   void processReference(Reference node) {
-    Refinement refined = refinementFor[node.definition];
-    if (refined != null) {
-      node.changeTo(refined);
+    Definition definition = node.definition;
+    if (definition is Primitive) {
+      Primitive prim = definition.effectiveDefinition;
+      Refinement refined = refinementFor[prim];
+      if (refined != null && refined != definition) {
+        node.changeTo(refined);
+      }
     }
   }
 
@@ -60,7 +67,6 @@
       // Create a new LetCont binding only this continuation.
       let.continuations.remove(cont);
       let = new LetCont(cont, null);
-      cont.parent = let;
     } else {
       let.remove(); // Reuse the existing LetCont.
     }
@@ -71,11 +77,15 @@
     return prim is Interceptor ? prim.input.definition : prim;
   }
 
-  /// Enqueues [cont] for processing in a context where [refined] is the
-  /// current refinement for its value.
-  void pushRefinement(Continuation cont, Refinement refined) {
+  /// Sets [refined] to be the current refinement for its value, and pushes an
+  /// action that will restore the original scope again.
+  ///
+  /// The refinement is inserted as the child of [insertionParent] if it has
+  /// at least one use after its scope has been processed.
+  void applyRefinement(InteriorNode insertionParent, Refinement refined) {
     Primitive value = refined.effectiveDefinition;
     Primitive currentRefinement = refinementFor[value];
+    refinementFor[value] = refined;
     pushAction(() {
       refinementFor[value] = currentRefinement;
       if (refined.hasNoUses) {
@@ -83,19 +93,47 @@
         refined.destroy();
       } else {
         LetPrim let = new LetPrim(refined);
-        refined.parent = let;
-        let.insertBelow(cont);
+        let.insertBelow(insertionParent);
       }
     });
-    push(cont);
-    pushAction(() {
-      refinementFor[value] = refined;
-    });
   }
 
-  void visitInvokeMethod(InvokeMethod node) {
-    Continuation cont = node.continuation.definition;
+  /// Enqueues [cont] for processing in a context where [refined] is the
+  /// current refinement for its value.
+  void pushRefinement(Continuation cont, Refinement refined) {
+    pushAction(() {
+      applyRefinement(cont, refined);
+      push(cont);
+    });
+  }
 
+  /// Refine the type of each argument on [node] according to the provided
+  /// type masks.
+  void _refineArguments(
+      InvocationPrimitive node, List<TypeMask> argumentSuccessTypes) {
+    if (argumentSuccessTypes == null) return;
+
+    // Note: node.dartArgumentsLength is shorter when the call doesn't include
+    // some optional arguments.
+    int length = min(argumentSuccessTypes.length, node.dartArgumentsLength);
+    for (int i = 0; i < length; i++) {
+      TypeMask argSuccessType = argumentSuccessTypes[i];
+
+      // Skip arguments that provide no refinement.
+      if (argSuccessType == types.dynamicType) continue;
+
+      applyRefinement(node.parent,
+          new Refinement(node.dartArgument(i), argSuccessType));
+    }
+  }
+
+  void visitInvokeStatic(InvokeStatic node) {
+    node.arguments.forEach(processReference);
+    _refineArguments(node,
+        _getSuccessTypesForStaticMethod(types, node.target));
+  }
+
+  void visitInvokeMethod(InvokeMethod node) {
     // Update references to their current refined values.
     processReference(node.receiver);
     node.arguments.forEach(processReference);
@@ -104,30 +142,48 @@
     // not the interceptor.
     Primitive receiver = unfoldInterceptor(node.receiver.definition);
 
-    // Sink the continuation to the call to ensure everything in scope
-    // here is also in scope inside the continuations.
-    sinkContinuationToUse(cont, node);
-
-    if (node.selector.isClosureCall) {
-      // Do not try to refine the receiver of closure calls; the class world
-      // does not know about closure classes.
-      push(cont);
-    } else {
+    // Do not try to refine the receiver of closure calls; the class world
+    // does not know about closure classes.
+    Selector selector = node.selector;
+    if (!selector.isClosureCall) {
       // Filter away receivers that throw on this selector.
-      TypeMask type = types.receiverTypeFor(node.selector, node.mask);
+      TypeMask type = types.receiverTypeFor(selector, node.mask);
       Refinement refinement = new Refinement(receiver, type);
-      pushRefinement(cont, refinement);
+      LetPrim letPrim = node.parent;
+      applyRefinement(letPrim, refinement);
+
+      // Refine arguments of methods on numbers which we know will throw on
+      // invalid argument values.
+      _refineArguments(node,
+          _getSuccessTypesForInstanceMethod(types, type, selector));
     }
   }
 
-  CallExpression getCallWithResult(Primitive prim) {
-    if (prim is Parameter && prim.parent is Continuation) {
-      Continuation cont = prim.parent;
-      if (cont.hasExactlyOneUse && cont.firstRef.parent is CallExpression) {
-        return cont.firstRef.parent;
-      }
-    }
-    return null;
+  void visitTypeCast(TypeCast node) {
+    Primitive value = node.value.definition;
+
+    processReference(node.value);
+    node.typeArguments.forEach(processReference);
+
+    // Refine the type of the input.
+    TypeMask type = types.subtypesOf(node.dartType).nullable();
+    Refinement refinement = new Refinement(value, type);
+    LetPrim letPrim = node.parent;
+    applyRefinement(letPrim, refinement);
+  }
+
+  void visitRefinement(Refinement node) {
+    // We found a pre-existing refinement node. These are generated by the
+    // IR builder to hold information from --trust-type-annotations.
+    // Update its input to use our own current refinement, then update the
+    // environment to use this refinement.
+    processReference(node.value);
+    Primitive value = node.value.definition.effectiveDefinition;
+    Primitive oldRefinement = refinementFor[value];
+    refinementFor[value] = node;
+    pushAction(() {
+      refinementFor[value] = oldRefinement;
+    });
   }
 
   bool isTrue(Primitive prim) {
@@ -137,7 +193,6 @@
   void visitBranch(Branch node) {
     processReference(node.condition);
     Primitive condition = node.condition.definition;
-    CallExpression call = getCallWithResult(condition);
 
     Continuation trueCont = node.trueContinuation.definition;
     Continuation falseCont = node.falseContinuation.definition;
@@ -181,9 +236,9 @@
       }
     }
 
-    if (call is InvokeMethod && call.selector == Selectors.equals) {
-      refineEquality(call.arguments[0].definition,
-                     call.arguments[1].definition,
+    if (condition is InvokeMethod && condition.selector == Selectors.equals) {
+      refineEquality(condition.dartReceiver,
+                     condition.dartArgument(0),
                      trueCont,
                      falseCont);
       return;
@@ -205,15 +260,176 @@
   @override
   Expression traverseLetCont(LetCont node) {
     for (Continuation cont in node.continuations) {
-      if (cont.hasExactlyOneUse &&
-          (cont.firstRef.parent is InvokeMethod ||
-           cont.firstRef.parent is Branch)) {
-        // Do not push the continuation here.
-        // visitInvokeMethod and visitBranch will do that.
-      } else {
+      // Do not push the branch continuations here. visitBranch will do that.
+      if (!(cont.hasExactlyOneUse && cont.firstRef.parent is Branch)) {
         push(cont);
       }
     }
     return node.body;
   }
 }
+
+// TODO(sigmund): ideally this whitelist information should be stored as
+// metadata annotations on the runtime libraries so we can keep it in sync with
+// the implementation more easily.
+// TODO(sigmund): add support for constructors.
+// TODO(sigmund): add checks for RegExp and DateTime (currently not exposed as
+// easily in TypeMaskSystem).
+// TODO(sigmund): after the above TODOs are fixed, add:
+//   ctor JSArray.fixed: [types.uint32Type],
+//   ctor JSArray.growable: [types.uintType],
+//   ctor DateTime': [int, int, int, int, int, int, int],
+//   ctor DateTime.utc': [int, int, int, int, int, int, int],
+//   ctor DateTime._internal': [int, int, int, int, int, int, int, bool],
+//   ctor RegExp': [string, dynamic, dynamic],
+//   method RegExp.allMatches: [string, int],
+//   method RegExp.firstMatch: [string],
+//   method RegExp.hasMatch: [string],
+List<TypeMask> _getSuccessTypesForInstanceMethod(
+    TypeMaskSystem types, TypeMask receiver, Selector selector) {
+  if (types.isDefinitelyInt(receiver)) {
+    switch (selector.name) {
+      case 'toSigned':
+      case 'toUnsigned':
+      case 'modInverse':
+      case 'gcd':
+        return [types.intType];
+
+      case 'modPow':
+       return [types.intType, types.intType];
+    }
+    // Note: num methods on int values are handled below.
+  }
+
+  if (types.isDefinitelyNum(receiver)) {
+    switch (selector.name) {
+      case 'clamp':
+          return [types.numType, types.numType];
+      case 'toStringAsFixed':
+      case 'toStringAsPrecision':
+      case 'toRadixString':
+          return [types.intType];
+      case 'toStringAsExponential':
+          return [types.intType.nullable()];
+      case 'compareTo':
+      case 'remainder':
+      case '+':
+      case '-':
+      case '/':
+      case '*':
+      case '%':
+      case '~/':
+      case '<<':
+      case '>>':
+      case '&':
+      case '|':
+      case '^':
+      case '<':
+      case '>':
+      case '<=':
+      case '>=':
+          return [types.numType];
+      default:
+        return null;
+    }
+  }
+
+  if (types.isDefinitelyString(receiver)) {
+    switch (selector.name) {
+      case 'allMatches':
+        return [types.stringType, types.intType];
+      case 'endsWith':
+        return [types.stringType];
+      case 'replaceAll':
+        return [types.dynamicType, types.stringType];
+      case 'replaceFirst':
+        return [types.dynamicType, types.stringType, types.intType];
+      case 'replaceFirstMapped':
+        return [
+          types.dynamicType,
+          types.dynamicType.nonNullable(),
+          types.intType
+        ];
+      case 'split':
+        return [types.dynamicType.nonNullable()];
+      case 'replaceRange':
+        return [types.intType, types.intType, types.stringType];
+      case 'startsWith':
+        return [types.dynamicType, types.intType];
+      case 'substring':
+        return [types.intType, types.uintType.nullable()];
+      case 'indexOf':
+        return [types.dynamicType.nonNullable(), types.uintType];
+      case 'lastIndexOf':
+        return [types.dynamicType.nonNullable(), types.uintType.nullable()];
+      case 'contains':
+        return [
+          types.dynamicType.nonNullable(),
+          // TODO(sigmund): update runtime to add check for int?
+          types.dynamicType
+        ];
+      case 'codeUnitAt':
+        return [types.uintType];
+      case '+':
+        return [types.stringType];
+      case '*':
+        return [types.uint32Type];
+      case '[]':
+        return [types.uintType];
+      default:
+        return null;
+    }
+  }
+
+  if (types.isDefinitelyArray(receiver)) {
+    switch (selector.name) {
+      case 'removeAt':
+      case 'insert':
+        return [types.uintType];
+      case 'sublist':
+        return [types.uintType, types.uintType.nullable()];
+      case 'length':
+         return selector.isSetter ? [types.uintType] : null;
+      case '[]':
+      case '[]=':
+        return [types.uintType];
+      default:
+        return null;
+    }
+  }
+  return null;
+}
+
+List<TypeMask> _getSuccessTypesForStaticMethod(
+    TypeMaskSystem types, FunctionElement target) {
+  var lib = target.library;
+  if (lib.isDartCore) {
+    var cls = target.enclosingClass?.name;
+    if (cls == 'int' && target.name == 'parse') {
+      // source, onError, radix
+      return [types.stringType, types.dynamicType, types.uint31Type.nullable()];
+    } else if (cls == 'double' && target.name == 'parse') {
+      return [types.stringType, types.dynamicType];
+    }
+  }
+
+  if (lib.isPlatformLibrary && '${lib.canonicalUri}' == 'dart:math') {
+    switch(target.name) {
+      case 'sqrt':
+      case 'sin':
+      case 'cos':
+      case 'tan':
+      case 'acos':
+      case 'asin':
+      case 'atan':
+      case 'atan2':
+      case 'exp':
+      case 'log':
+        return [types.numType];
+      case 'pow':
+        return [types.numType, types.numType];
+    }
+  }
+
+  return null;
+}
diff --git a/pkg/compiler/lib/src/cps_ir/loop_effects.dart b/pkg/compiler/lib/src/cps_ir/loop_effects.dart
new file mode 100644
index 0000000..c7680b0
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/loop_effects.dart
@@ -0,0 +1,185 @@
+library dart2js.cps_ir.loop_effects;
+
+import 'cps_ir_nodes.dart';
+import 'loop_hierarchy.dart';
+import '../universe/side_effects.dart';
+import '../elements/elements.dart';
+import '../world.dart';
+
+/// Determines which the [SideEffects] that may occur during each loop in
+/// a given function, in addition to whether the loop may change the length
+/// of an indexable object.
+///
+/// TODO(asgerf): Make length a flag on [SideEffects] for better precision and
+/// so we don't need to special case the length in this class.
+class LoopSideEffects extends TrampolineRecursiveVisitor {
+  LoopHierarchy loopHierarchy;
+  final World world;
+  final Map<Continuation, List<Continuation>> exitContinuations = {};
+  final Map<Continuation, SideEffects> loopSideEffects = {};
+  final Set<Continuation> loopsChangingLength = new Set<Continuation>();
+  Continuation currentLoopHeader;
+  SideEffects currentLoopSideEffects = new SideEffects.empty();
+  bool currentLoopChangesLength = false;
+
+  LoopSideEffects(FunctionDefinition node, this.world, {this.loopHierarchy}) {
+    if (loopHierarchy == null) {
+      loopHierarchy = new LoopHierarchy(node);
+    }
+    visit(node);
+  }
+
+  /// Returns the accumulated effects and dependencies on all paths from the
+  /// loop entry to any recursive invocation of the loop.
+  SideEffects getSideEffectsInLoop(Continuation loop) {
+    return loopSideEffects[loop];
+  }
+
+  /// True if the length of an indexable object may change between the loop
+  /// entry and a recursive invocation of the loop.
+  bool loopChangesLength(Continuation loop) {
+    return loopsChangingLength.contains(loop);
+  }
+
+  @override
+  Expression traverseContinuation(Continuation cont) {
+    if (cont.isRecursive) {
+      SideEffects oldEffects = currentLoopSideEffects;
+      bool oldChangesLength = currentLoopChangesLength;
+      loopSideEffects[cont] = currentLoopSideEffects = new SideEffects.empty();
+      exitContinuations[cont] = <Continuation>[];
+      pushAction(() {
+        oldEffects.add(currentLoopSideEffects);
+        if (currentLoopChangesLength) {
+          loopsChangingLength.add(cont);
+        }
+        currentLoopChangesLength = currentLoopChangesLength || oldChangesLength;
+        currentLoopSideEffects = oldEffects;
+        exitContinuations[cont].forEach(push);
+      });
+    }
+    Continuation oldLoopHeader = currentLoopHeader;
+    currentLoopHeader = loopHierarchy.getLoopHeader(cont);
+    pushAction(() {
+      currentLoopHeader = oldLoopHeader;
+    });
+    return cont.body;
+  }
+
+  @override
+  Expression traverseLetHandler(LetHandler node) {
+    enqueueContinuation(node.handler);
+    return node.body;
+  }
+
+  @override
+  Expression traverseLetCont(LetCont node) {
+    node.continuations.forEach(enqueueContinuation);
+    return node.body;
+  }
+
+  void enqueueContinuation(Continuation cont) {
+    Continuation loop = loopHierarchy.getEnclosingLoop(cont);
+    if (loop == currentLoopHeader) {
+      push(cont);
+    } else {
+      // Multiple loops can be exited at once.
+      // Register as an exit from the outermost loop being exited.
+      Continuation inner = currentLoopHeader;
+      Continuation outer = loopHierarchy.getEnclosingLoop(currentLoopHeader);
+      while (outer != loop) {
+        if (inner == null) {
+          // The shrinking reductions pass must run before any pass that relies
+          // on computing loop side effects.
+          world.compiler.reporter.internalError(null,
+              'Unreachable continuations must be removed before computing '
+              'loop side effects.');
+        }
+        inner = outer;
+        outer = loopHierarchy.getEnclosingLoop(outer);
+      }
+      exitContinuations[inner].add(cont);
+    }
+  }
+
+  void addSideEffects(SideEffects effects) {
+    currentLoopSideEffects.add(effects);
+    if (effects.changesIndex()) {
+      currentLoopChangesLength = true;
+    }
+  }
+
+  void addAllSideEffects() {
+    currentLoopSideEffects.setAllSideEffects();
+    currentLoopSideEffects.setDependsOnSomething();
+    currentLoopChangesLength = true;
+  }
+
+  void visitInvokeMethod(InvokeMethod node) {
+    addSideEffects(world.getSideEffectsOfSelector(node.selector, node.mask));
+  }
+
+  void visitInvokeStatic(InvokeStatic node) {
+    addSideEffects(world.getSideEffectsOfElement(node.target));
+  }
+
+  void visitInvokeMethodDirectly(InvokeMethodDirectly node) {
+    FunctionElement target = node.target;
+    if (target is ConstructorBodyElement) {
+      ConstructorBodyElement body = target;
+      target = body.constructor;
+    }
+    addSideEffects(world.getSideEffectsOfElement(target));
+  }
+
+  void visitInvokeConstructor(InvokeConstructor node) {
+    addSideEffects(world.getSideEffectsOfElement(node.target));
+  }
+
+  void visitSetStatic(SetStatic node) {
+    currentLoopSideEffects.setChangesStaticProperty();
+  }
+
+  void visitGetStatic(GetStatic node) {
+    currentLoopSideEffects.setDependsOnStaticPropertyStore();
+  }
+
+  void visitGetField(GetField node) {
+    currentLoopSideEffects.setDependsOnInstancePropertyStore();
+  }
+
+  void visitSetField(SetField node) {
+    currentLoopSideEffects.setChangesInstanceProperty();
+  }
+
+  void visitGetIndex(GetIndex node) {
+    currentLoopSideEffects.setDependsOnIndexStore();
+  }
+
+  void visitSetIndex(SetIndex node) {
+    // Set the change index flag without setting the change length flag.
+    currentLoopSideEffects.setChangesIndex();
+  }
+
+  void visitForeignCode(ForeignCode node) {
+    addSideEffects(node.nativeBehavior.sideEffects);
+  }
+
+  void visitGetLazyStatic(GetLazyStatic node) {
+    // TODO(asgerf): How do we get the side effects of a lazy field initializer?
+    addAllSideEffects();
+  }
+
+  void visitAwait(Await node) {
+    addAllSideEffects();
+  }
+
+  void visitYield(Yield node) {
+    addAllSideEffects();
+  }
+
+  void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
+    currentLoopSideEffects.setChangesIndex();
+    currentLoopChangesLength = true; // Push and pop.
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart b/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
index fc63944..897a44e 100644
--- a/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
+++ b/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
@@ -5,23 +5,24 @@
 library dart2js.cps_ir.loop_hierarchy;
 
 import 'cps_ir_nodes.dart';
+import 'cps_fragment.dart';
 
 /// Determines the effective nesting of loops.
-/// 
+///
 /// The effective nesting of loops is different from the lexical nesting, since
-/// recursive continuations can generally contain all the code following 
+/// recursive continuations can generally contain all the code following
 /// after the loop in addition to the looping code itself.
-/// 
+///
 /// For example, the 'else' branch below is not effectively part of the loop:
-/// 
-///   let rec kont x = 
-///     if (<loop condition>) 
+///
+///   let rec kont x =
+///     if (<loop condition>)
 ///       <loop body>
 ///       InvokeContinuation kont x'
-///     else 
+///     else
 ///       <after loop>
 ///       return p.foo()
-/// 
+///
 /// We use the term "loop" to mean recursive continuation.
 /// The `null` value is used to represent a context not part of any loop.
 class LoopHierarchy {
@@ -33,10 +34,13 @@
   Map<Continuation, Continuation> loopTarget = <Continuation, Continuation>{};
 
   /// Current nesting depth.
-  int currentDepth = 0;
+  int _currentDepth = 0;
+
+  /// The loop target to use for missing code.  Used by [update].
+  Continuation _exitLoop;
 
   /// Computes the loop hierarchy for the given function.
-  /// 
+  ///
   /// Parent pointers must be computed for [node].
   LoopHierarchy(FunctionDefinition node) {
     _processBlock(node.body, null);
@@ -47,21 +51,21 @@
     return cont.isRecursive ? cont : loopTarget[cont];
   }
 
-  /// Returns the innermost loop which the given loop is part of, other
+  /// Returns the innermost loop which the given continuation is part of, other
   /// than itself.
-  Continuation getEnclosingLoop(Continuation loop) {
-    return loopTarget[loop];
+  Continuation getEnclosingLoop(Continuation cont) {
+    return loopTarget[cont];
   }
 
   /// Marks the innermost loop as a subloop of the other loop.
-  /// 
+  ///
   /// Returns the innermost loop.
-  /// 
+  ///
   /// Both continuations, [c1] and [c2] may be null (i.e. no loop).
-  /// 
+  ///
   /// A loop is said to be a subloop of an enclosing loop if it can invoke
   /// that loop recursively. This information is stored in [loopTarget].
-  /// 
+  ///
   /// This method is only invoked with two distinct loops if there is a
   /// point that can reach a recursive invocation of both loops.
   /// This implies that one loop is nested in the other, because they must
@@ -83,45 +87,29 @@
 
   /// Analyzes the body of [cont] and returns the innermost loop
   /// that can be invoked recursively from [cont] (other than [cont] itself).
-  /// 
+  ///
   /// [catchLoop] is the innermost loop that can be invoked recursively
   /// from the current exception handler.
   Continuation _processContinuation(Continuation cont, Continuation catchLoop) {
     if (cont.isRecursive) {
-      ++currentDepth;
-      loopDepth[cont] = currentDepth;
+      ++_currentDepth;
+      loopDepth[cont] = _currentDepth;
       Continuation target = _processBlock(cont.body, catchLoop);
       _markInnerLoop(loopTarget[cont], target);
-      --currentDepth;
+      --_currentDepth;
     } else {
       loopTarget[cont] = _processBlock(cont.body, catchLoop);
     }
     return loopTarget[cont];
   }
 
-  bool _isCallContinuation(Continuation cont) {
-    return cont.hasExactlyOneUse && cont.firstRef.parent is CallExpression;
-  }
-
   /// Analyzes a basic block and returns the innermost loop that
   /// can be invoked recursively from that block.
   Continuation _processBlock(Expression node, Continuation catchLoop) {
-    List<Continuation> callContinuations = <Continuation>[];
-    for (; node is! TailExpression; node = node.next) {
+    for (; node != null && node is! TailExpression; node = node.next) {
       if (node is LetCont) {
         for (Continuation cont in node.continuations) {
-          if (!_isCallContinuation(cont)) {
-            // Process non-call continuations at the binding site, so they
-            // their loop target is known at all use sites.
-            _processContinuation(cont, catchLoop);
-          } else {
-            // To avoid deep recursion, do not analyze call continuations
-            // recursively. This basic block traversal steps into the
-            // call contiunation after visiting its use site. We store the
-            // continuations in a list so we can set the loop target once
-            // it is known.
-            callContinuations.add(cont);
-          }
+          _processContinuation(cont, catchLoop);
         }
       } else if (node is LetHandler) {
         catchLoop = _processContinuation(node.handler, catchLoop);
@@ -138,16 +126,52 @@
       target = _markInnerLoop(
           loopTarget[node.trueContinuation.definition],
           loopTarget[node.falseContinuation.definition]);
+    } else if (node == null) {
+      // If the code ends abruptly, use the exit loop provided in [update].
+      target = _exitLoop;
     } else {
-      assert(node is Unreachable || node is Throw);
+      assert(node is Unreachable || node is Throw || node == null);
     }
-    target = _markInnerLoop(target, catchLoop);
-    for (Continuation cont in callContinuations) {
-      // Store the loop target on each call continuation in the basic block.
-      // Because we walk over call continuations as part of the basic block
-      // traversal, these do not get their loop target set otherwise.
-      loopTarget[cont] = target;
+    return _markInnerLoop(target, catchLoop);
+  }
+
+  /// Returns the the innermost loop that effectively encloses both
+  /// c1 and c2 (or `null` if there is no such loop).
+  Continuation lowestCommonAncestor(Continuation c1, Continuation c2) {
+    int d1 = getDepth(c1), d2 = getDepth(c2);
+    while (c1 != c2) {
+      if (d1 <= d2) {
+        c2 = getEnclosingLoop(c2);
+        d2 = getDepth(c2);
+      } else {
+        c1 = getEnclosingLoop(c1);
+        d1 = getDepth(c1);
+      }
     }
-    return target;
+    return c1;
+  }
+
+  /// Returns the lexical nesting depth of [loop].
+  int getDepth(Continuation loop) {
+    if (loop == null) return 0;
+    return loopDepth[loop];
+  }
+
+  /// Sets the loop header for each continuation bound inside the given
+  /// fragment.
+  ///
+  /// If the fragment is open, [exitLoop] denotes the loop header for
+  /// the code that will occur after the fragment.
+  ///
+  /// [catchLoop] is the loop target for the catch clause of the try/catch
+  /// surrounding the inserted fragment.
+  void update(CpsFragment fragment,
+              {Continuation exitLoop,
+               Continuation catchLoop}) {
+    if (fragment.isEmpty) return;
+    _exitLoop = exitLoop;
+    _currentDepth = getDepth(exitLoop);
+    _processBlock(fragment.root, catchLoop);
+    _exitLoop = null;
   }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/loop_invariant_branch.dart b/pkg/compiler/lib/src/cps_ir/loop_invariant_branch.dart
new file mode 100644
index 0000000..e9f04a6
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/loop_invariant_branch.dart
@@ -0,0 +1,252 @@
+library dart2js.cps_ir.loop_invariant_branch;
+
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart';
+import 'loop_hierarchy.dart';
+import 'cps_fragment.dart';
+import 'redundant_join.dart' show AlphaRenamer;
+
+/// Hoists branches out of loops, where:
+/// - the branch is at the entry point of a loop
+/// - the branch condition is loop-invariant
+/// - one arm of the branch is not effectively part of the loop
+///
+/// Schematically:
+///
+///     b = COND
+///     while (true) {
+///       if (b)
+///         BRANCH (contains no continue to loop)
+///       else
+///         LOOP
+///     }
+///
+///     ==>
+///
+///     b = COND
+///     if (b)
+///       BRANCH
+///     else
+///       while (true)
+///         LOOP
+///
+/// As in [RedundantJoinEliminator], parameters are treated as names with
+/// lexical scoping during this pass, and a given parameter "name" may be
+/// declared by more than one continuation. The reference chains for parameters
+/// are therefore meaningless during this pass, until repaired by [AlphaRenamer]
+/// at the end.
+class LoopInvariantBranchMotion extends BlockVisitor implements Pass {
+  String get passName => 'Loop invariant branch motion';
+
+  LoopHierarchy loopHierarchy;
+  final Map<Primitive, Continuation> loopHeaderFor =
+      <Primitive, Continuation>{};
+  final Map<Continuation, Continuation> catchLoopFor =
+      <Continuation, Continuation>{};
+  Continuation currentLoopHeader;
+  Continuation currentCatchLoop;
+  List<Continuation> loops = <Continuation>[];
+  bool wasHoisted = false;
+
+  void rewrite(FunctionDefinition node) {
+    loopHierarchy = new LoopHierarchy(node);
+    BlockVisitor.traverseInPreOrder(node, this);
+    // Process loops bottom-up so a branch can be hoisted multiple times.
+    loops.reversed.forEach(hoistEntryCheck);
+    if (wasHoisted) {
+      new AlphaRenamer().visit(node);
+    }
+  }
+
+  void visitLetHandler(LetHandler node) {
+    currentCatchLoop = loopHierarchy.getLoopHeader(node.handler);
+  }
+
+  void visitContinuation(Continuation node) {
+    currentLoopHeader = loopHierarchy.getLoopHeader(node);
+    for (Parameter param in node.parameters) {
+      loopHeaderFor[param] = currentLoopHeader;
+    }
+    catchLoopFor[node] = currentCatchLoop;
+    if (node.isRecursive) {
+      loops.add(node);
+    }
+  }
+
+  void visitLetPrim(LetPrim node) {
+    loopHeaderFor[node.primitive] = currentLoopHeader;
+  }
+
+  void hoistEntryCheck(Continuation loop) {
+    // Keep hoisting branches out of the loop, there can be more than one.
+    while (tryHoistEntryCheck(loop));
+  }
+
+  Expression getEffectiveBody(Expression exp) {
+    // TODO(asgerf): We could also bypass constants here but constant pooling
+    //               is likely to be a better solution for that.
+    while (exp is LetCont) {
+      exp = exp.next;
+    }
+    return exp;
+  }
+
+  /// Adds [parameters] to [cont] and updates every invocation to pass the
+  /// corresponding parameter values as arguments. Thus, the parameters are
+  /// passed in explicitly instead of being captured.
+  ///
+  /// This only works because [AlphaRenamer] cleans up at the end of this pass.
+  ///
+  /// Schematically:
+  ///
+  ///     let outer(x1, x2, x3) =
+  ///       let inner(y) = BODY
+  ///       [ .. inner(y') .. ]
+  ///
+  ///   ==> (append parameters)
+  ///
+  ///     let outer(x1, x2, x3) =
+  ///       let inner(y, x1, x2, x3) = BODY
+  ///       [ .. inner(y', x1, x2, x3) .. ]
+  ///
+  ///   ==> (hoist, not performed by this method)
+  ///
+  ///     let inner(y, x1, x2, x3) = BODY
+  ///     let outer(x1, x2, x3) =
+  ///       [ .. inner(y', x1, x2, x3) .. ]
+  ///
+  void appendParameters(Continuation cont, List<Parameter> parameters) {
+    cont.parameters.addAll(parameters);
+    for (Reference ref = cont.firstRef; ref != null; ref = ref.next) {
+      Node use = ref.parent;
+      if (use is InvokeContinuation) {
+        for (Parameter loopParam in parameters) {
+          use.arguments.add(new Reference<Primitive>(loopParam)..parent = use);
+        }
+      }
+    }
+  }
+
+  bool tryHoistEntryCheck(Continuation loop) {
+    // Check if this is a loop starting with a branch.
+    Expression body = getEffectiveBody(loop.body);
+    if (body is! Branch) return false;
+    Branch branch = body;
+
+    // Is the condition loop invariant?
+    Primitive condition = branch.condition.definition;
+    if (loopHeaderFor[condition] == loop) return false;
+
+    Continuation trueCont = branch.trueContinuation.definition;
+    Continuation falseCont = branch.falseContinuation.definition;
+    Continuation hoistedCase; // The branch to hoist.
+    Continuation loopCase; // The branch that is part of the loop.
+
+    // Check that one branch is part of the loop, and the other is an exit.
+    if (loopHierarchy.getLoopHeader(trueCont) != loop &&
+        loopHierarchy.getLoopHeader(falseCont) == loop) {
+      hoistedCase = trueCont;
+      loopCase = falseCont;
+    } else if (loopHierarchy.getLoopHeader(falseCont) != loop &&
+               loopHierarchy.getLoopHeader(trueCont) == loop) {
+      hoistedCase = falseCont;
+      loopCase = trueCont;
+    } else {
+      return false;
+    }
+
+    // Hoist non-loop continuations out of the loop.
+    // The hoisted branch can reference other continuations bound in the loop,
+    // so to stay in scope, those need to be hoisted as well.
+    //
+    //     let b = COND
+    //     let loop(x) =
+    //       let join(y) = JOIN
+    //       let hoistCase() = HOIST
+    //       let loopCase() = LOOP
+    //       branch b hoistCase loopCase
+    //     in loop(i)
+    //
+    //    ==>
+    //
+    //     let b = COND
+    //     let join(y,x) = JOIN
+    //     let hoistCase(x) = HOIST
+    //     let loop(x) =
+    //       let loopCase() = LOOP
+    //       branch b hoistCase loopCase
+    //     in loop(i)
+    //
+    LetCont loopBinding = loop.parent;
+    Expression it = loop.body;
+    while (it is LetCont) {
+      LetCont let = it;
+      it = let.body;
+      for (Continuation cont in let.continuations) {
+        if (loopHierarchy.getEnclosingLoop(cont) != loop) {
+          appendParameters(cont, loop.parameters);
+          new LetCont(cont, null).insertAbove(loopBinding);
+        }
+      }
+      let.continuations.removeWhere((cont) => cont.parent != let);
+      if (let.continuations.isEmpty) {
+        let.remove();
+      }
+    }
+
+    // Create a new branch to call the hoisted continuation or the loop:
+    //
+    //     let loop(x) =
+    //       let loopCase() = LOOP
+    //       branch b hoistCase loopCase
+    //     in loop(i)
+    //
+    //    ==>
+    //
+    //     let newTrue() = hoistCase(i)
+    //     let newFalse() =
+    //       let loop(x) =
+    //         let loopCase() = LOOP
+    //         branch b hoistCase loopCase
+    //     branch b newTrue newFalse
+    //
+    InvokeContinuation loopEntry = loopBinding.body;
+    List<Primitive> loopArgs =
+        loopEntry.arguments.map((ref) => ref.definition).toList();
+    CpsFragment cps = new CpsFragment();
+    cps.branch(condition,
+          strict: branch.isStrictCheck,
+          negate: hoistedCase == falseCont)
+       .invokeContinuation(hoistedCase, loopArgs);
+
+    // The continuations created in the fragment need to have their loop header
+    // set so the loop hierarchy remains intact
+    loopHierarchy.update(cps,
+        exitLoop: loopHierarchy.getEnclosingLoop(loop),
+        catchLoop: catchLoopFor[loop]);
+
+    // Insert above the loop. This will put the loop itself in a branch.
+    cps.insertAbove(loopBinding);
+
+    // Replace the old branch with the loopCase, still bound inside the loop:
+    //
+    //   let loop(x) =
+    //     let loopCase() = LOOP
+    //     branch b hoistCase loopCase
+    //   in loop(i)
+    //
+    //  ==>
+    //
+    //   let loop(x) =
+    //     let loopCase() = LOOP
+    //     loopCase()
+    //   in loop(i)
+    //
+    destroyAndReplace(branch, new InvokeContinuation(loopCase, []));
+
+    // Record that at least one branch was hoisted to trigger alpha renaming.
+    wasHoisted = true;
+
+    return true;
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/mutable_ssa.dart b/pkg/compiler/lib/src/cps_ir/mutable_ssa.dart
index d4630b5..e5ea7a8 100644
--- a/pkg/compiler/lib/src/cps_ir/mutable_ssa.dart
+++ b/pkg/compiler/lib/src/cps_ir/mutable_ssa.dart
@@ -168,7 +168,7 @@
         if (shouldRewrite(variable)) {
           // Replace with the reaching definition from the environment.
           Primitive value = environment[variable];
-          value.substituteFor(getter);
+          getter.replaceUsesWith(value);
           mergeHints(variable, value);
           node.remove();
         }
diff --git a/pkg/compiler/lib/src/cps_ir/octagon.dart b/pkg/compiler/lib/src/cps_ir/octagon.dart
index 8dfd5f1..691c15d 100644
--- a/pkg/compiler/lib/src/cps_ir/octagon.dart
+++ b/pkg/compiler/lib/src/cps_ir/octagon.dart
@@ -4,6 +4,8 @@
 
 library dart2js.cps_ir.octagon;
 
+import 'dart:collection';
+
 /// For every variable in the constraint system, two [SignedVariable]s exist,
 /// representing the positive and negative uses of the variable.
 ///
@@ -20,9 +22,6 @@
   static int _hashCount = 0;
   final int hashCode = (_hashCount = _hashCount + 1) & 0x0fffffff;
 
-  /// Temporary field used by the constraint solver's graph search.
-  bool _isBeingVisited = false;
-
   SignedVariable._make() {
     _negated = new SignedVariable._makeTwin(this);
   }
@@ -87,17 +86,14 @@
   ///
   /// The constraint should be removed again using [popConstraint].
   void pushConstraint(Constraint constraint) {
-    if (_unsolvableCounter > 0) {
+    if (_unsolvableCounter > 0 ||
+        _unsolvableCounter == 0 && _checkUnsolvable(constraint)) {
       ++_unsolvableCounter;
     }
     constraint.v1._constraints.add(constraint);
     if (constraint.v1 != constraint.v2) {
       constraint.v2._constraints.add(constraint);
     }
-    // Check if this constraint has made the system unsolvable.
-    if (_unsolvableCounter == 0 && _checkUnsolvable(constraint)) {
-      _unsolvableCounter = 1;
-    }
   }
 
   /// Remove a constraint that was previously added with [pushConstraint].
@@ -115,101 +111,87 @@
     }
   }
 
-  // Temporaries using during path finding.
-  SignedVariable _goal;
-  Map<SignedVariable, int> _distanceToGoal;
-
-  /// Return true if the recently added [constraint] made the system unsolvable.
+  /// Return true if [constraint] would make the constraint system unsolvable.
   ///
-  /// This function assumes the system was solvable before adding [constraint].
+  /// Assumes the system is currently solvable.
   bool _checkUnsolvable(Constraint constraint) {
     // Constraints are transitively composed like so:
-    //    v1 - v2 <= k1
-    //    v2 - v3 <= k2
+    //    v1 + v2 <= k1
+    //   -v2 + v3 <= k2
     // implies:
-    //    v1 - v3 <= k1 + k2
+    //    v1 + v3 <= k1 + k2
     //
-    // We construct a graph such that the tightest bound on `v1 - v3` is the
-    // weight of the shortest path from `v1` to `v3`.
+    // We construct a graph such that the tightest bound on `v1 + v3` is the
+    // weight of the shortest path from `v1` to `-v3`.
     //
-    // Ever constraint `v1 - v2 <= k` gives rise to two edges:
-    //     (v1)  --k--> (v2)
-    //     (-v2) --k--> (-v2)
+    // Every constraint `v1 + v2 <= k` gives rise to two edges:
+    //     (v1) --k--> (-v2)
+    //     (v2) --k--> (-v1)
     //
     // The system is unsolvable if and only if a negative-weight cycle exists
     // in this graph (this corresponds to a variable being less than itself).
 
-    // We assume the system was solvable to begin with, so we only look for
-    // cycles that use the new edges.
-    //
-    // The new [constraint] `v1 + v2 <= k` just added the edges:
-    //     (v1)  --k--> (-v2)
-    //     (v2)  --k--> (-v1)
-    //
-    // Look for a path from (-v2) to (v1) with weight at most -k-1, as this
-    // will complete a negative-weight cycle.
-
-    // It suffices to do this once. We need not check for the converse path
-    // (-v1) to (v2) because of the symmetry in the graph.
-    //
-    // Note that the graph symmetry is not a redundancy. Some cycles include
-    // both of the new edges at once, so they must be added to the graph
-    // beforehand.
-    _goal = constraint.v2;
-    _distanceToGoal = <SignedVariable, int>{};
-    int targetWeight = -constraint.bound - 1;
-    int pathWeight = _search(constraint.v1.negated, targetWeight, 0);
-    return pathWeight != null && pathWeight <= targetWeight;
+    // Check if a negative-weight cycle would be created by adding [constraint].
+    int length = _cycleLength(constraint);
+    return length != null && length < 0;
   }
 
-  static const int MAX_DEPTH = 100;
-
-  /// Returns the shortest path from [v1] to [_goal] (or any path shorter than
-  /// [budget]), or `null` if no path exists.
-  int _search(SignedVariable v1, int budget, int depth) {
-    if (v1 == _goal && budget >= 0) return 0;
-
-    // Disregard paths that use a lot of edges.
-    // In extreme cases (e.g. hundreds of `push` calls or nested ifs) this can
-    // get slow and/or overflow the stack.  Most paths that matter are very
-    // short (1-5 edges) with some occasional 10-30 length paths in math code.
-    if (depth >= MAX_DEPTH) return null;
-
-    // We found a cycle, but not the one we're looking for. If the constraint
-    // system was solvable to being with, then this must be a positive-weight
-    // cycle, and no shortest path goes through a positive-weight cycle.
-    if (v1._isBeingVisited) return null;
-
-    // Check if we have previously searched from here.
-    if (_distanceToGoal.containsKey(v1)) {
-      // We have already searched this node, return the cached answer.
-      // Note that variables may explicitly map to null, so the double lookup
-      // is necessary.
-      return _distanceToGoal[v1];
+  /// Returns the length of the shortest simple cycle that would be created by
+  /// adding [constraint] to the graph.
+  ///
+  /// Assumes there are no existing negative-weight cycles. The new cycle
+  /// may have negative weight as [constraint] has not been added yet.
+  int _cycleLength(Constraint constraint) {
+    // Single-source shortest path using a FIFO queue.
+    Queue<SignedVariable> worklist = new Queue<SignedVariable>();
+    Map<SignedVariable, int> distance = {};
+    void updateDistance(SignedVariable v, int newDistance) {
+      int oldDistance = distance[v];
+      if (oldDistance == null || oldDistance > newDistance) {
+        distance[v] = newDistance;
+        worklist.addLast(v);
+      }
     }
-
-    v1._isBeingVisited = true;
-
-    int shortestDistance = v1 == _goal ? 0 : null;
-    for (Constraint c in v1._constraints) {
-      SignedVariable v2 = c.v1 == v1 ? c.v2 : c.v1;
-      int distance = _search(v2.negated, budget - c.bound, depth + 1);
-      if (distance != null) {
-        distance += c.bound; // Pay the cost of using the edge.
-         if (distance <= budget) {
-          // Success! We found a path that is short enough so return fast.
-          // All recursive calls will now return immediately, so there is no
-          // need to update distanceToGoal, but we need to clear the
-          // beingVisited flag for the next query.
-          v1._isBeingVisited = false;
-          return distance;
-        } else if (shortestDistance == null || distance < shortestDistance) {
-          shortestDistance = distance;
+    void iterateWorklist() {
+      while (!worklist.isEmpty) {
+        SignedVariable v1 = worklist.removeFirst();
+        int distanceToV1 = distance[v1];
+        for (Constraint c in v1._constraints) {
+          SignedVariable v2 = c.v1 == v1 ? c.v2 : c.v1;
+          updateDistance(v2.negated, distanceToV1 + c.bound);
         }
       }
     }
-    v1._isBeingVisited = false;
-    _distanceToGoal[v1] = shortestDistance;
-    return shortestDistance;
+    // Two new edges will be added by the constraint `v1 + v2 <= k`:
+    //
+    //   A. (v1) --> (-v2)
+    //   B. (v2) --> (-v1)
+    //
+    // We need to check for two kinds of cycles:
+    //
+    //   Using only A:       (-v2) --> (v1) --A--> (-v2)
+    //   Using B and then A: (-v2) --> (v2) --B--> (-v1) --> (v1) --A--> (-v2)
+    //
+    // Because of the graph symmetry, cycles using only B or using A and then B
+    // exist if and only if the corresponding cycle above exist, so there is no
+    // need to check for those.
+    //
+    // Do a single-source shortest paths reaching out from (-v2).
+    updateDistance(constraint.v2.negated, 0);
+    iterateWorklist();
+    if (constraint.v1 != constraint.v2) {
+      int distanceToV2 = distance[constraint.v2];
+      if (distanceToV2 != null) {
+        // Allow one use of the B edge.
+        // This must be done outside fixpoint iteration as an infinite loop
+        // would arise when an negative-weight cycle using only B exists.
+        updateDistance(constraint.v1.negated, distanceToV2 + constraint.bound);
+        iterateWorklist();
+      }
+    }
+    // Get the distance to (v1) and check if the A edge would complete a cycle.
+    int distanceToV1 = distance[constraint.v1];
+    if (distanceToV1 == null) return null;
+    return distanceToV1 + constraint.bound;
   }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart b/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
new file mode 100644
index 0000000..689dac6
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
@@ -0,0 +1,323 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.cps_ir.optimize_interceptors;
+
+import 'optimizers.dart';
+import 'cps_ir_nodes.dart';
+import 'loop_hierarchy.dart';
+import 'cps_fragment.dart';
+import '../constants/values.dart';
+import '../elements/elements.dart';
+import '../js_backend/backend_helpers.dart' show BackendHelpers;
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../types/types.dart' show TypeMask;
+import '../io/source_information.dart' show SourceInformation;
+import '../world.dart';
+import 'type_mask_system.dart';
+
+/// Replaces `getInterceptor` calls with interceptor constants when possible,
+/// or with "almost constant" expressions like "x && CONST" when the input
+/// is either null or has a known interceptor.
+///
+/// Narrows the set of intercepted classes for interceptor calls.
+///
+/// Replaces calls on interceptors with one-shot interceptors.
+class OptimizeInterceptors extends TrampolineRecursiveVisitor implements Pass {
+  String get passName => 'Optimize interceptors';
+
+  final TypeMaskSystem typeSystem;
+  final JavaScriptBackend backend;
+  LoopHierarchy loopHierarchy;
+  Continuation currentLoopHeader;
+
+  OptimizeInterceptors(this.backend, this.typeSystem);
+
+  BackendHelpers get helpers => backend.helpers;
+  World get classWorld => backend.compiler.world;
+
+  Map<Interceptor, Continuation> loopHeaderFor = <Interceptor, Continuation>{};
+
+  void rewrite(FunctionDefinition node) {
+    // TODO(asgerf): Computing the LoopHierarchy here may be overkill when all
+    //               we want is to hoist constants out of loops.
+    loopHierarchy = new LoopHierarchy(node);
+    visit(node.body);
+    new ShareConstants().visit(node);
+  }
+
+  @override
+  Expression traverseContinuation(Continuation cont) {
+    Continuation oldLoopHeader = currentLoopHeader;
+    currentLoopHeader = loopHierarchy.getLoopHeader(cont);
+    pushAction(() {
+      currentLoopHeader = oldLoopHeader;
+    });
+    return cont.body;
+  }
+
+  bool hasNoFalsyValues(ClassElement class_) {
+    return class_ != helpers.jsInterceptorClass &&
+       class_ != helpers.jsNullClass &&
+       class_ != helpers.jsBoolClass &&
+       class_ != helpers.jsStringClass &&
+       !class_.isSubclassOf(helpers.jsNumberClass);
+  }
+
+  Continuation getCurrentOuterLoop({Continuation scope}) {
+    Continuation inner = null, outer = currentLoopHeader;
+    while (outer != scope) {
+      inner = outer;
+      outer = loopHierarchy.getEnclosingLoop(outer);
+    }
+    return inner;
+  }
+
+  /// Binds the given constant in a primitive, in scope of the [useSite].
+  ///
+  /// The constant will be hoisted out of loops, and shared with other requests
+  /// for the same constant as long as it is in scope.
+  Primitive makeConstantFor(ConstantValue constant,
+                            {Expression useSite,
+                             TypeMask type,
+                             SourceInformation sourceInformation,
+                             Entity hint}) {
+    Constant prim =
+        new Constant(constant, sourceInformation: sourceInformation);
+    prim.hint = hint;
+    prim.type = type;
+    LetPrim letPrim = new LetPrim(prim);
+    Continuation loop = getCurrentOuterLoop();
+    if (loop != null) {
+      LetCont loopBinding = loop.parent;
+      letPrim.insertAbove(loopBinding);
+    } else {
+      letPrim.insertAbove(useSite);
+    }
+    return prim;
+  }
+
+  void computeInterceptedClasses(Interceptor interceptor) {
+    Set<ClassElement> intercepted = interceptor.interceptedClasses;
+    intercepted.clear();
+    for (Reference ref = interceptor.firstRef; ref != null; ref = ref.next) {
+      Node use = ref.parent;
+      if (use is InvokeMethod) {
+        TypeMask type = use.dartReceiver.type;
+        bool canOccurAsReceiver(ClassElement elem) {
+          return classWorld.isInstantiated(elem) &&
+              !typeSystem.areDisjoint(type,
+                  typeSystem.getInterceptorSubtypes(elem));
+        }
+        Iterable<ClassElement> classes =
+            backend.getInterceptedClassesOn(use.selector.name);
+        intercepted.addAll(classes.where(canOccurAsReceiver));
+      } else {
+        intercepted.clear();
+        intercepted.add(backend.helpers.jsInterceptorClass);
+        break;
+      }
+    }
+    if (intercepted.contains(backend.helpers.jsInterceptorClass) ||
+        intercepted.contains(backend.helpers.jsNullClass)) {
+      // If the null value is intercepted, update the type of the interceptor.
+      // The Tree IR uses this information to determine if the method lookup
+      // on an InvokeMethod might throw.
+      interceptor.type = interceptor.type.nonNullable();
+    }
+  }
+
+  /// True if [node] may return [JSNumber] instead of [JSInt] or [JSDouble].
+  bool jsNumberClassSuffices(Interceptor node) {
+    // No methods on JSNumber call 'down' to methods on JSInt or JSDouble.  If
+    // all uses of the interceptor are for methods is defined only on JSNumber
+    // then JSNumber will suffice in place of choosing between JSInt or
+    // JSDouble.
+    for (Reference ref = node.firstRef; ref != null; ref = ref.next) {
+      if (ref.parent is InvokeMethod) {
+        InvokeMethod invoke = ref.parent;
+        if (invoke.receiver != ref) return false;
+        var interceptedClasses =
+            backend.getInterceptedClassesOn(invoke.selector.name);
+        if (interceptedClasses.contains(helpers.jsDoubleClass)) return false;
+        if (interceptedClasses.contains(helpers.jsIntClass)) return false;
+        continue;
+      }
+      // Other uses need full distinction.
+      return false;
+    }
+    return true;
+  }
+
+  /// True if [node] can intercept a `null` value and return the [JSNull]
+  /// interceptor.
+  bool canInterceptNull(Interceptor node) {
+    for (Reference ref = node.firstRef; ref != null; ref = ref.next) {
+      Node use = ref.parent;
+      if (use is InvokeMethod) {
+        if (selectorsOnNull.contains(use.selector) &&
+            use.dartReceiver.type.isNullable) {
+          return true;
+        }
+      } else {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Returns the only interceptor class that may be returned by [node], or
+  /// `null` if no such class could be found.
+  ClassElement getSingleInterceptorClass(Interceptor node) {
+    // TODO(asgerf): This could be more precise if we used the use-site type,
+    // since the interceptor may have been hoisted out of a loop, where a less
+    // precise type is known.
+    Primitive input = node.input.definition;
+    TypeMask type = input.type;
+    if (canInterceptNull(node)) return null;
+    type = type.nonNullable();
+    if (typeSystem.isDefinitelyArray(type)) {
+      return backend.helpers.jsArrayClass;
+    }
+    if (typeSystem.isDefinitelyInt(type)) {
+      return backend.helpers.jsIntClass;
+    }
+    if (typeSystem.isDefinitelyNum(type) && jsNumberClassSuffices(node)) {
+      return backend.helpers.jsNumberClass;
+    }
+    ClassElement singleClass = type.singleClass(classWorld);
+    if (singleClass != null &&
+        singleClass.isSubclassOf(backend.helpers.jsInterceptorClass)) {
+      return singleClass;
+    }
+    return null;
+  }
+
+  /// Try to replace [interceptor] with a constant, and return `true` if
+  /// successful.
+  bool constifyInterceptor(Interceptor interceptor) {
+    LetPrim let = interceptor.parent;
+    Primitive input = interceptor.input.definition;
+    ClassElement classElement = getSingleInterceptorClass(interceptor);
+
+    if (classElement == null) return false;
+    ConstantValue constant = new InterceptorConstantValue(classElement.rawType);
+
+    if (!input.type.isNullable) {
+      Primitive constantPrim = makeConstantFor(constant,
+          useSite: let,
+          type: interceptor.type,
+          sourceInformation: interceptor.sourceInformation);
+      constantPrim.useElementAsHint(interceptor.hint);
+      interceptor..replaceUsesWith(constantPrim)..destroy();
+      let.remove();
+    } else {
+      Primitive constantPrim = makeConstantFor(constant,
+          useSite: let,
+          type: interceptor.type.nonNullable(),
+          sourceInformation: interceptor.sourceInformation);
+      CpsFragment cps = new CpsFragment(interceptor.sourceInformation);
+      Parameter param = new Parameter(interceptor.hint);
+      param.type = interceptor.type;
+      Continuation cont = cps.letCont(<Parameter>[param]);
+      if (hasNoFalsyValues(classElement)) {
+        // If null is the only falsy value, compile as "x && CONST".
+        cps.ifFalsy(input).invokeContinuation(cont, [input]);
+      } else {
+        // If there are other falsy values compile as "x == null ? x : CONST".
+        Primitive condition = cps.applyBuiltin(
+            BuiltinOperator.LooseEq,
+            [input, cps.makeNull()]);
+        cps.ifTruthy(condition).invokeContinuation(cont, [input]);
+      }
+      cps.invokeContinuation(cont, [constantPrim]);
+      cps.context = cont;
+      cps.insertAbove(let);
+      interceptor..replaceUsesWith(param)..destroy();
+      let.remove();
+    }
+    return true;
+  }
+
+  @override
+  Expression traverseLetPrim(LetPrim node) {
+    Expression next = node.body;
+    visit(node.primitive);
+    return next;
+  }
+
+  @override
+  void visitInterceptor(Interceptor node) {
+    if (constifyInterceptor(node)) return;
+    computeInterceptedClasses(node);
+    if (node.hasExactlyOneUse) {
+      // Set the loop header on single-use interceptors so [visitInvokeMethod]
+      // can determine if it should become a one-shot interceptor.
+      loopHeaderFor[node] = currentLoopHeader;
+    }
+  }
+
+  @override
+  void visitInvokeMethod(InvokeMethod node) {
+    if (node.callingConvention != CallingConvention.Intercepted) return;
+    Primitive interceptor = node.receiver.definition;
+    if (interceptor is! Interceptor ||
+        interceptor.hasMultipleUses ||
+        loopHeaderFor[interceptor] != currentLoopHeader) {
+      return;
+    }
+    // TODO(asgerf): Consider heuristics for when to use one-shot interceptors.
+    //   E.g. using only one-shot interceptors with a fast path.
+    node.callingConvention = CallingConvention.OneShotIntercepted;
+    node..receiver.unlink()..receiver = node.arguments.removeAt(0);
+  }
+
+  @override
+  void visitTypeTestViaFlag(TypeTestViaFlag node) {
+    Primitive interceptor = node.interceptor.definition;
+    if (interceptor is! Interceptor ||
+        interceptor.hasMultipleUses ||
+        loopHeaderFor[interceptor] != currentLoopHeader ||
+        !backend.mayGenerateInstanceofCheck(node.dartType)) {
+      return;
+    }
+    Interceptor inter = interceptor;
+    Primitive value = inter.input.definition;
+    node.replaceWith(new TypeTest(value, node.dartType, [])..type = node.type);
+  }
+}
+
+/// Shares interceptor constants when one is in scope of another.
+///
+/// Interceptor optimization runs after GVN, hence this clean-up step is needed.
+///
+/// TODO(asgerf): Handle in separate constant optimization pass? With some other
+///   constant-related optimizations, like cloning small constants at use-site.
+class ShareConstants extends TrampolineRecursiveVisitor {
+  Map<ConstantValue, Constant> sharedConstantFor = <ConstantValue, Constant>{};
+
+  Expression traverseLetPrim(LetPrim node) {
+    Expression next = node.body;
+    if (node.primitive is Constant && shouldShareConstant(node.primitive)) {
+      Constant prim = node.primitive;
+      Constant existing = sharedConstantFor[prim.value];
+      if (existing != null) {
+        existing.useElementAsHint(prim.hint);
+        prim..replaceUsesWith(existing)..destroy();
+        node.remove();
+        return next;
+      }
+      sharedConstantFor[prim.value] = prim;
+      pushAction(() {
+        assert(sharedConstantFor[prim.value] == prim);
+        sharedConstantFor.remove(prim.value);
+      });
+    }
+    return next;
+  }
+
+  bool shouldShareConstant(Constant constant) {
+    return constant.value.isInterceptor;
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/optimizers.dart b/pkg/compiler/lib/src/cps_ir/optimizers.dart
index 336806d..812b204 100644
--- a/pkg/compiler/lib/src/cps_ir/optimizers.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimizers.dart
@@ -6,6 +6,8 @@
 
 import 'cps_ir_nodes.dart';
 import '../constants/values.dart';
+import '../common/names.dart';
+import '../universe/selector.dart';
 
 export 'type_propagation.dart' show TypePropagator;
 export 'scalar_replacement.dart' show ScalarReplacer;
@@ -14,9 +16,15 @@
 export 'shrinking_reductions.dart' show ShrinkingReducer;
 export 'mutable_ssa.dart' show MutableVariableEliminator;
 export 'insert_refinements.dart' show InsertRefinements;
-export 'remove_refinements.dart' show RemoveRefinements;
-export 'share_interceptors.dart' show ShareInterceptors;
+export 'update_refinements.dart' show UpdateRefinements;
+export 'redundant_refinement.dart' show RedundantRefinementEliminator;
+export 'optimize_interceptors.dart' show OptimizeInterceptors;
 export 'bounds_checker.dart' show BoundsChecker;
+export 'backward_null_check_remover.dart' show BackwardNullCheckRemover;
+export 'gvn.dart' show GVN;
+export 'inline.dart' show Inliner;
+export 'eagerly_load_statics.dart' show EagerlyLoadStatics;
+export 'loop_invariant_branch.dart' show LoopInvariantBranchMotion;
 export 'parent_visitor.dart' show ParentVisitor;
 
 /// An optimization pass over the CPS IR.
@@ -46,3 +54,9 @@
 bool isTruthyConstant(ConstantValue value, {bool strict: false}) {
   return strict ? value.isTrue : !isFalsyConstant(value);
 }
+
+/// Selectors that do not throw when invoked on the null value.
+final List<Selector> selectorsOnNull = <Selector>[
+    Selectors.equals, Selectors.hashCode_, Selectors.runtimeType_,
+    Selectors.toString_, Selectors.toStringGetter,
+    Selectors.noSuchMethodGetter];
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
index 183f8e3..7f16af9 100644
--- a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
+++ b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
@@ -138,7 +138,7 @@
       // * and implicitly remove param from continuation signature and
       //   invocations by not incrementing `dst`. References of removed
       //   arguments are unlinked to keep definition usages up to date.
-      uniqueDefinition.substituteFor(oldDefinition);
+      oldDefinition.replaceUsesWith(uniqueDefinition);
       for (InvokeContinuation invoke in invokes) {
         invoke.arguments[src].unlink();
       }
@@ -191,7 +191,7 @@
 
 /// Ensures [continuation] has its own LetCont binding by creating
 /// a new LetCont below its current binding, if necessary.
-/// 
+///
 /// Returns the LetCont that now binds [continuation].
 LetCont _makeUniqueBinding(Continuation continuation) {
   LetCont letCont = continuation.parent;
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_refinement.dart b/pkg/compiler/lib/src/cps_ir/redundant_refinement.dart
new file mode 100644
index 0000000..cff47d6
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/redundant_refinement.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.cps_ir.redundant_refinement;
+
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart' show Pass;
+import 'type_mask_system.dart';
+
+/// Removes [Refinement] nodes where the input value is already known to
+/// satisfy the refinement type.
+///
+/// Note: This pass improves loop-invariant code motion in the GVN pass because
+/// GVN will currently not hoist a primitive across a refinement guard.
+/// But some opportunities for hoisting are still missed.  A field access can
+/// safely be hoisted across a non-redundant refinement as long as the less
+/// refined value is still known to have the field.  For example:
+///
+///     class A { var field; }
+///     class B extends A {}
+///
+///     var x = getA();       // Return type is subclass of A.
+///     while (x is B) {      // Refinement to B is not redundant.
+///         x.field.baz++;    // x.field is safe for hoisting,
+///     }                     // but blocked by the refinement node.
+///
+/// Ideally, this pass should go away and GVN should handle refinements
+/// directly.
+class RedundantRefinementEliminator extends TrampolineRecursiveVisitor
+                                    implements Pass {
+  String get passName => 'Redundant refinement elimination';
+
+  TypeMaskSystem typeSystem;
+
+  RedundantRefinementEliminator(this.typeSystem);
+
+  void rewrite(FunctionDefinition node) {
+    visit(node);
+  }
+
+  Expression traverseLetPrim(LetPrim node) {
+    Expression next = node.body;
+    if (node.primitive is Refinement) {
+      Refinement refinement = node.primitive;
+      Primitive value = refinement.value.definition;
+      if (typeSystem.isMorePreciseOrEqual(value.type, refinement.refineType)) {
+        refinement..replaceUsesWith(value)..destroy();
+        node.remove();
+        return next;
+      }
+    }
+    return next;
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/remove_refinements.dart b/pkg/compiler/lib/src/cps_ir/remove_refinements.dart
deleted file mode 100644
index 98f1c17..0000000
--- a/pkg/compiler/lib/src/cps_ir/remove_refinements.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library cps_ir.optimization.remove_refinements;
-
-import 'optimizers.dart' show Pass;
-import 'cps_ir_nodes.dart';
-
-/// Removes all [Refinement] nodes from the IR.
-///
-/// This simplifies subsequent passes that don't rely on path-sensitive
-/// type information but depend on equality between primitives.
-class RemoveRefinements extends TrampolineRecursiveVisitor implements Pass {
-  String get passName => 'Remove refinement nodes';
-
-  void rewrite(FunctionDefinition node) {
-    visit(node);
-  }
-
-  @override
-  Expression traverseLetPrim(LetPrim node) {
-    Expression next = node.body;
-    if (node.primitive is Refinement) {
-      Refinement refinement = node.primitive;
-      refinement.value.definition.substituteFor(refinement);
-      refinement.destroy();
-      node.remove();
-    }
-    return next;
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart b/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart
index 0ff315c..b220847 100644
--- a/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart
+++ b/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart
@@ -18,7 +18,7 @@
 
 /**
  * Replaces aggregates with a set of local values.  Performs inlining of
- * single-use closures to generate more replacable aggregates.
+ * single-use closures to generate more replaceable aggregates.
  */
 class ScalarReplacer extends Pass {
   String get passName => 'Scalar replacement';
@@ -41,7 +41,7 @@
 
 /**
  * Do scalar replacement of aggregates on instances. Since scalar replacement
- * can create new candidiates, iterate until all scalar replacements are done.
+ * can create new candidates, iterate until all scalar replacements are done.
  */
 class ScalarReplacementVisitor extends TrampolineRecursiveVisitor {
 
@@ -104,7 +104,8 @@
         (ClassElement enclosingClass, FieldElement field) {
           Primitive argument = allocation.arguments[i++].definition;
           fieldInitialValues[field] = argument;
-        });
+        },
+        includeSuperAndInjectedMembers: true);
     }
 
     // Create [MutableVariable]s for each written field. Initialize the
@@ -141,12 +142,12 @@
           GetMutable getter = new GetMutable(variable);
           getter.type = getField.type;
           getter.variable.parent = getter;
-          getter.substituteFor(getField);
+          getField.replaceUsesWith(getter);
           replacePrimitive(getField, getter);
           deletePrimitive(getField);
         } else {
           Primitive value = fieldInitialValues[getField.field];
-          value.substituteFor(getField);
+          getField.replaceUsesWith(value);
           deleteLetPrimOf(getField);
         }
       } else if (use is SetField && use.object == ref) {
@@ -157,7 +158,7 @@
         SetMutable setter = new SetMutable(variable, value);
         setter.variable.parent = setter;
         setter.value.parent = setter;
-        setter.substituteFor(setField);
+        setField.replaceUsesWith(setter);
         replacePrimitive(setField, setter);
         deletePrimitive(setField);
       } else {
diff --git a/pkg/compiler/lib/src/cps_ir/share_interceptors.dart b/pkg/compiler/lib/src/cps_ir/share_interceptors.dart
deleted file mode 100644
index 3706725..0000000
--- a/pkg/compiler/lib/src/cps_ir/share_interceptors.dart
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.cps_ir.share_interceptors;
-
-import 'optimizers.dart';
-import 'cps_ir_nodes.dart';
-import 'loop_hierarchy.dart';
-import '../constants/values.dart';
-
-/// Removes redundant `getInterceptor` calls.
-/// 
-/// The pass performs three optimizations for interceptors:
-///- pull interceptors out of loops
-///- replace interceptors with constants
-///- share interceptors when one is in scope of the other
-class ShareInterceptors extends TrampolineRecursiveVisitor implements Pass {
-  String get passName => 'Share interceptors';
-
-  /// The innermost loop containing a given primitive.
-  final Map<Primitive, Continuation> loopHeaderFor =
-      <Primitive, Continuation>{};
-
-  /// An interceptor currently in scope for a given primitive.
-  final Map<Primitive, Primitive> interceptorFor =
-      <Primitive, Primitive>{};
-
-  /// A primitive currently in scope holding a given interceptor constant.
-  final Map<ConstantValue, Primitive> sharedConstantFor =
-      <ConstantValue, Primitive>{};
-
-  /// Interceptors to be hoisted out of the given loop.
-  final Map<Continuation, List<Primitive>> loopHoistedInterceptors =
-      <Continuation, List<Primitive>>{};
-
-  LoopHierarchy loopHierarchy;
-  Continuation currentLoopHeader;
-
-  void rewrite(FunctionDefinition node) {
-    loopHierarchy = new LoopHierarchy(node);
-    visit(node.body);
-  }
-
-  @override
-  Expression traverseContinuation(Continuation cont) {
-    Continuation oldLoopHeader = currentLoopHeader;
-    pushAction(() {
-      currentLoopHeader = oldLoopHeader;
-    });
-    currentLoopHeader = loopHierarchy.getLoopHeader(cont);
-    for (Parameter param in cont.parameters) {
-      loopHeaderFor[param] = currentLoopHeader;
-    }
-    if (cont.isRecursive) {
-      pushAction(() {
-        // After the loop body has been processed, all interceptors hoisted
-        // to this loop fall out of scope and should be removed from the
-        // environment.
-        List<Primitive> hoisted = loopHoistedInterceptors[cont];
-        if (hoisted != null) {
-          for (Primitive interceptor in hoisted) {
-            if (interceptor is Interceptor) {
-              Primitive input = interceptor.input.definition;
-              assert(interceptorFor[input] == interceptor);
-              interceptorFor.remove(input);
-            } else if (interceptor is Constant) {
-              assert(sharedConstantFor[interceptor.value] == interceptor);
-              sharedConstantFor.remove(interceptor.value);
-            } else {
-              throw "Unexpected interceptor: $interceptor";
-            }
-          }
-        }
-      });
-    }
-    return cont.body;
-  }
-
-  @override
-  Expression traverseLetPrim(LetPrim node) {
-    loopHeaderFor[node.primitive] = currentLoopHeader;
-    Expression next = node.body;
-    if (node.primitive is! Interceptor) {
-      return next;
-    }
-    Interceptor interceptor = node.primitive;
-    Primitive input = interceptor.input.definition;
-
-    // Try to reuse an existing interceptor for the same input.
-    Primitive existing = interceptorFor[input];
-    if (existing != null) {
-      if (existing is Interceptor) {
-        existing.interceptedClasses.addAll(interceptor.interceptedClasses);
-      }
-      existing.substituteFor(interceptor);
-      interceptor.destroy();
-      node.remove();
-      return next;
-    }
-
-    // There is no interceptor obtained from this particular input, but
-    // there might one obtained from another input that is known to
-    // have the same result, so try to reuse that.
-    InterceptorConstantValue constant = interceptor.constantValue;
-    if (constant != null) {
-      existing = sharedConstantFor[constant];
-      if (existing != null) {
-        existing.substituteFor(interceptor);
-        interceptor.destroy();
-        node.remove();
-        return next;
-      }
-
-      // The interceptor could not be shared. Replace it with a constant.
-      Constant constantPrim = new Constant(constant);
-      node.primitive = constantPrim;
-      constantPrim.parent = node;
-      constantPrim.hint = interceptor.hint;
-      constantPrim.type = interceptor.type;
-      constantPrim.substituteFor(interceptor);
-      interceptor.destroy();
-      sharedConstantFor[constant] = constantPrim;
-    } else {
-      interceptorFor[input] = interceptor;
-    }
-
-    // Determine the outermost loop where the input to the interceptor call
-    // is available.  Constant interceptors take no input and can thus be
-    // hoisted all way to the top-level.
-    Continuation referencedLoop = constant != null
-        ? null
-        : lowestCommonAncestor(loopHeaderFor[input], currentLoopHeader);
-    if (referencedLoop != currentLoopHeader) {
-      // [referencedLoop] contains the binding for [input], so we cannot hoist
-      // the interceptor outside that loop.  Find the loop nested one level
-      // inside referencedLoop, and hoist the interceptor just outside that one.
-      Continuation loop = currentLoopHeader;
-      Continuation enclosing = loopHierarchy.getEnclosingLoop(loop);
-      while (enclosing != referencedLoop) {
-        assert(loop != null);
-        loop = enclosing;
-        enclosing = loopHierarchy.getEnclosingLoop(loop);
-      }
-      assert(loop != null);
-
-      // Move the LetPrim above the loop binding.
-      LetCont loopBinding = loop.parent;
-      node.remove();
-      node.insertAbove(loopBinding);
-
-      // A different loop now contains the interceptor.
-      loopHeaderFor[node.primitive] = enclosing;
-
-      // Register the interceptor as hoisted to that loop, so it will be
-      // removed from the environment when it falls out of scope.
-      loopHoistedInterceptors
-          .putIfAbsent(loop, () => <Primitive>[])
-          .add(node.primitive);
-    } else if (constant != null) {
-      // The LetPrim was not hoisted. Remove the bound interceptor from the
-      // environment when leaving the LetPrim body.
-      pushAction(() {
-        assert(sharedConstantFor[constant] == node.primitive);
-        sharedConstantFor.remove(constant);
-      });
-    } else {
-      pushAction(() {
-        assert(interceptorFor[input] == node.primitive);
-        interceptorFor.remove(input);
-      });
-    }
-    return next;
-  }
-
-  /// Returns the the innermost loop that effectively encloses both
-  /// c1 and c2 (or `null` if there is no such loop).
-  Continuation lowestCommonAncestor(Continuation c1, Continuation c2) {
-    int d1 = getDepth(c1), d2 = getDepth(c2);
-    while (c1 != c2) {
-      if (d1 <= d2) {
-        c2 = loopHierarchy.getEnclosingLoop(c2);
-        d2 = getDepth(c2);
-      } else {
-        c1 = loopHierarchy.getEnclosingLoop(c1);
-        d1 = getDepth(c1);
-      }
-    }
-    return c1;
-  }
-
-  int getDepth(Continuation loop) {
-    if (loop == null) return -1;
-    return loopHierarchy.loopDepth[loop];
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
index a6017cb..16a1d15 100644
--- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
+++ b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
@@ -6,6 +6,7 @@
 
 import 'cps_ir_nodes.dart';
 import 'optimizers.dart';
+import 'cps_fragment.dart';
 
 /**
  * [ShrinkingReducer] applies shrinking reductions to CPS terms as described
@@ -91,7 +92,8 @@
     assert(_isDeadVal(task.node));
 
     // Remove dead primitive.
-    LetPrim letPrim = task.node;;
+    LetPrim letPrim = task.node;
+    destroyRefinementsOfDeadPrimitive(letPrim.primitive);
     _removeNode(letPrim);
 
     // Perform bookkeeping on removed body and scan for new redexes.
@@ -138,8 +140,8 @@
 
     // Substitute the invocation argument for the continuation parameter.
     for (int i = 0; i < invoke.arguments.length; i++) {
-      Reference argRef = invoke.arguments[i];
-      argRef.definition.substituteFor(cont.parameters[i]);
+      cont.parameters[i].replaceUsesWith(invoke.arguments[i].definition);
+      invoke.arguments[i].definition.useElementAsHint(cont.parameters[i].hint);
     }
 
     // Perform bookkeeping on substituted body and scan for new redexes.
@@ -167,8 +169,23 @@
     InvokeContinuation invoke = cont.body;
     Continuation wrappedCont = invoke.continuation.definition;
 
+    for (int i = 0; i < cont.parameters.length; ++i) {
+      wrappedCont.parameters[i].useElementAsHint(cont.parameters[i].hint);
+    }
+
+    // If the invocation of wrappedCont is escaping, then all invocations of
+    // cont will be as well, after the reduction.
+    if (invoke.isEscapingTry) {
+      Reference current = cont.firstRef;
+      while (current != null) {
+        InvokeContinuation owner = current.parent;
+        owner.isEscapingTry = true;
+        current = current.next;
+      }
+    }
+
     // Replace all occurrences with the wrapped continuation.
-    wrappedCont.substituteFor(cont);
+    cont.replaceUsesWith(wrappedCont);
 
     // Perform bookkeeping on removed body and scan for new redexes.
     new _RemovalVisitor(_worklist).visit(cont);
@@ -232,7 +249,8 @@
 /// Returns true iff the bound primitive is unused, and has no effects
 /// preventing it from being eliminated.
 bool _isDeadVal(LetPrim node) {
-  return node.primitive.hasNoUses && node.primitive.isSafeForElimination;
+  return node.primitive.hasNoEffectiveUses &&
+         node.primitive.isSafeForElimination;
 }
 
 /// Returns true iff the continuation is unused.
diff --git a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
index ba44ed1..25fb1c9 100644
--- a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
@@ -9,91 +9,193 @@
 import '../constants/values.dart';
 import '../dart_types.dart' as types;
 import '../elements/elements.dart';
+import '../js_backend/backend_helpers.dart' show BackendHelpers;
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../types/abstract_value_domain.dart';
 import '../types/types.dart';
 import '../types/constants.dart' show computeTypeMask;
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show World;
+import '../closure.dart' show ClosureFieldElement, BoxLocal, TypeVariableLocal;
 
-enum AbstractBool {
-  True, False, Maybe, Nothing
-}
-
-class TypeMaskSystem {
+class TypeMaskSystem implements AbstractValueDomain {
   final TypesTask inferrer;
   final World classWorld;
   final JavaScriptBackend backend;
 
-  TypeMask get dynamicType => inferrer.dynamicType;
-  TypeMask get typeType => inferrer.typeType;
-  TypeMask get functionType => inferrer.functionType;
-  TypeMask get boolType => inferrer.boolType;
-  TypeMask get intType => inferrer.intType;
-  TypeMask get doubleType => inferrer.doubleType;
-  TypeMask get numType => inferrer.numType;
-  TypeMask get stringType => inferrer.stringType;
-  TypeMask get listType => inferrer.listType;
-  TypeMask get mapType => inferrer.mapType;
-  TypeMask get nonNullType => inferrer.nonNullType;
-  TypeMask get nullType => inferrer.nullType;
-  TypeMask get extendableNativeListType => backend.extendableArrayType;
+  TypeMask _numStringBoolType;
+  TypeMask _fixedLengthType;
+  TypeMask _interceptorType;
+  TypeMask _interceptedTypes; // Does not include null.
 
+  TypeMask __indexableTypeTest;
+
+  // The full type of a constant (e.g. a ContainerTypeMask) is not available on
+  // the constant. Type inference flows the type to some place where it is used,
+  // e.g. a parameter. For constant values that are the value of static const
+  // fields we need to remember the association.
+  final Map<ConstantValue, TypeMask> _constantMasks =
+      <ConstantValue, TypeMask>{};
+
+  @override
+  TypeMask get dynamicType => inferrer.dynamicType;
+
+  @override
+  TypeMask get typeType => inferrer.typeType;
+
+  @override
+  TypeMask get functionType => inferrer.functionType;
+
+  @override
+  TypeMask get boolType => inferrer.boolType;
+
+  @override
+  TypeMask get intType => inferrer.intType;
+
+  @override
+  TypeMask get doubleType => inferrer.doubleType;
+
+  @override
+  TypeMask get numType => inferrer.numType;
+
+  @override
+  TypeMask get stringType => inferrer.stringType;
+
+  @override
+  TypeMask get listType => inferrer.listType;
+
+  @override
+  TypeMask get mapType => inferrer.mapType;
+
+  @override
+  TypeMask get nonNullType => inferrer.nonNullType;
+
+  @override
+  TypeMask get nullType => inferrer.nullType;
+
+  @override
+  TypeMask get extendableArrayType => backend.extendableArrayType;
+
+  @override
+  TypeMask get fixedArrayType => backend.fixedArrayType;
+
+  @override
+  TypeMask get arrayType =>
+      new TypeMask.nonNullSubclass(helpers.jsArrayClass, classWorld);
+
+  @override
   TypeMask get uint31Type => inferrer.uint31Type;
+
+  @override
   TypeMask get uint32Type => inferrer.uint32Type;
+
+  @override
   TypeMask get uintType => inferrer.positiveIntType;
 
-  TypeMask numStringBoolType;
-  TypeMask fixedLengthType;
-  TypeMask interceptorType;
+  @override
+  TypeMask get numStringBoolType {
+    if (_numStringBoolType == null) {
+      // Build the number+string+bool type. To make containment tests more
+      // inclusive, we use the num, String, bool types for this, not
+      // the JSNumber, JSString, JSBool subclasses.
+      TypeMask anyNum =
+          new TypeMask.nonNullSubtype(classWorld.numClass, classWorld);
+      TypeMask anyString =
+          new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
+      TypeMask anyBool =
+          new TypeMask.nonNullSubtype(classWorld.boolClass, classWorld);
+      _numStringBoolType =
+          new TypeMask.unionOf(<TypeMask>[anyNum, anyString, anyBool],
+              classWorld);
+    }
+    return _numStringBoolType;
+  }
 
-  ClassElement get jsNullClass => backend.jsNullClass;
+  @override
+  TypeMask get fixedLengthType {
+    if (_fixedLengthType == null) {
+      List<TypeMask> fixedLengthTypes =
+          <TypeMask>[stringType, backend.fixedArrayType];
+      if (classWorld.isInstantiated(helpers.typedArrayClass)) {
+        fixedLengthTypes.add(nonNullSubclass(helpers.typedArrayClass));
+      }
+      _fixedLengthType = new TypeMask.unionOf(fixedLengthTypes, classWorld);
+    }
+    return _fixedLengthType;
+  }
+
+  @override
+  TypeMask get interceptorType {
+    if (_interceptorType == null) {
+      _interceptorType =
+        new TypeMask.nonNullSubtype(helpers.jsInterceptorClass, classWorld);
+    }
+    return _interceptorType;
+  }
+
+  @override
+  TypeMask get interceptedTypes { // Does not include null.
+    if (_interceptedTypes == null) {
+      // We redundantly include subtypes of num/string/bool as intercepted
+      // types, because the type system does not infer that their
+      // implementations are all subclasses of Interceptor.
+      _interceptedTypes = new TypeMask.unionOf(
+          <TypeMask>[interceptorType, numStringBoolType], classWorld);
+    }
+    return _interceptedTypes;
+  }
+
+  TypeMask get _indexableTypeTest {
+    if (__indexableTypeTest == null) {
+      // Make a TypeMask containing Indexable and (redundantly) subtypes of
+      // string because the type inference does not infer that all strings are
+      // indexables.
+      TypeMask indexable =
+          new TypeMask.nonNullSubtype(helpers.jsIndexableClass, classWorld);
+      TypeMask anyString =
+          new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
+      __indexableTypeTest = new TypeMask.unionOf(
+          <TypeMask>[indexable, anyString],
+          classWorld);
+    }
+    return __indexableTypeTest;
+  }
+
+  ClassElement get jsNullClass => helpers.jsNullClass;
+
+  BackendHelpers get helpers => backend.helpers;
 
   // TODO(karlklose): remove compiler here.
   TypeMaskSystem(dart2js.Compiler compiler)
       : inferrer = compiler.typesTask,
         classWorld = compiler.world,
         backend = compiler.backend {
-
-    // Build the number+string+bool type. To make containment tests more
-    // inclusive, we use the num, String, bool types for this, not
-    // the JSNumber, JSString, JSBool subclasses.
-    TypeMask anyNum =
-        new TypeMask.nonNullSubtype(classWorld.numClass, classWorld);
-    TypeMask anyString =
-        new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
-    TypeMask anyBool =
-        new TypeMask.nonNullSubtype(classWorld.boolClass, classWorld);
-    numStringBoolType =
-        new TypeMask.unionOf(<TypeMask>[anyNum, anyString, anyBool],
-            classWorld);
-    interceptorType =
-        new TypeMask.nonNullSubtype(backend.jsInterceptorClass, classWorld);
-
-    TypeMask typedArray = nonNullSubclass(backend.typedArrayClass);
-    fixedLengthType = new TypeMask.unionOf(
-            <TypeMask>[stringType, backend.fixedArrayType, typedArray],
-            classWorld);
   }
 
+  @override
   bool methodUsesReceiverArgument(FunctionElement function) {
     assert(backend.isInterceptedMethod(function));
     ClassElement clazz = function.enclosingClass.declaration;
-    return clazz.isSubclassOf(backend.jsInterceptorClass) ||
+    return clazz.isSubclassOf(helpers.jsInterceptorClass) ||
            classWorld.isUsedAsMixin(clazz);
   }
 
+  @override
   Element locateSingleElement(TypeMask mask, Selector selector) {
     return mask.locateSingleElement(selector, mask, classWorld.compiler);
   }
 
+  @override
   ClassElement singleClass(TypeMask mask) {
     return mask.singleClass(classWorld);
   }
 
+  @override
   bool needsNoSuchMethodHandling(TypeMask mask, Selector selector) {
     return mask.needsNoSuchMethodHandling(selector, classWorld);
   }
 
+  @override
   TypeMask getReceiverType(MethodElement method) {
     assert(method.isInstanceMember);
     if (classWorld.isUsedAsMixin(method.enclosingClass.declaration)) {
@@ -106,14 +208,17 @@
     }
   }
 
+  @override
   TypeMask getParameterType(ParameterElement parameter) {
     return inferrer.getGuaranteedTypeOfElement(parameter);
   }
 
+  @override
   TypeMask getReturnType(FunctionElement function) {
     return inferrer.getGuaranteedReturnTypeOfElement(function);
   }
 
+  @override
   TypeMask getInvokeReturnType(Selector selector, TypeMask mask) {
     TypeMask result = inferrer.getGuaranteedTypeOfSelector(selector, mask);
     // Tearing off .call from a function returns the function itself.
@@ -125,20 +230,53 @@
     return result;
   }
 
+  @override
   TypeMask getFieldType(FieldElement field) {
+    if (field is ClosureFieldElement) {
+      // The type inference does not report types for all closure fields.
+      // Box fields are never null.
+      if (field.local is BoxLocal) return nonNullType;
+      // Closure fields for type variables contain the internal representation
+      // of the type (which can be null), not the Type object.
+      if (field.local is TypeVariableLocal) return dynamicType;
+    }
     return inferrer.getGuaranteedTypeOfElement(field);
   }
 
+  @override
   TypeMask join(TypeMask a, TypeMask b) {
     return a.union(b, classWorld);
   }
 
-  TypeMask getTypeOf(ConstantValue constant) {
-    return computeTypeMask(inferrer.compiler, constant);
+  @override
+  TypeMask intersection(TypeMask a, TypeMask b) {
+    if (a == null) return b;
+    if (b == null) return a;
+    return a.intersection(b, classWorld);
   }
 
-  // Returns the constant value if a TypeMask represents a single value.
-  // Returns `null` if [mask] is not a constant.
+  void associateConstantValueWithElement(ConstantValue constant,
+                                         Element element) {
+    // TODO(25093): Replace this code with an approach that works for anonymous
+    // constants and non-constant literals.
+    if (constant is ListConstantValue || constant is MapConstantValue) {
+      // Inferred type is usually better (e.g. a ContainerTypeMask) but is
+      // occasionally less general.
+      TypeMask computed = computeTypeMask(inferrer.compiler, constant);
+      TypeMask inferred = inferrer.getGuaranteedTypeOfElement(element);
+      TypeMask best = intersection(inferred, computed);
+      assert(!best.isEmpty);
+      _constantMasks[constant] = best;
+    }
+  }
+
+  @override
+  TypeMask getTypeOf(ConstantValue constant) {
+    return _constantMasks[constant] ??
+           computeTypeMask(inferrer.compiler, constant);
+  }
+
+  @override
   ConstantValue getConstantOf(TypeMask mask) {
     if (!mask.isValue) return null;
     if (mask.isNullable) return null;  // e.g. 'true or null'.
@@ -148,7 +286,9 @@
     return null;
   }
 
+  @override
   TypeMask nonNullExact(ClassElement element) {
+    // TODO(johnniwinther): I don't think the follow is valid anymore.
     // The class world does not know about classes created by
     // closure conversion, so just treat those as a subtypes of Function.
     // TODO(asgerf): Maybe closure conversion should create a new ClassWorld?
@@ -156,36 +296,43 @@
     return new TypeMask.nonNullExact(element.declaration, classWorld);
   }
 
+  @override
   TypeMask nonNullSubclass(ClassElement element) {
     if (element.isClosure) return functionType;
     return new TypeMask.nonNullSubclass(element.declaration, classWorld);
   }
 
+  @override
   TypeMask nonNullSubtype(ClassElement element) {
     if (element.isClosure) return functionType;
     return new TypeMask.nonNullSubtype(element.declaration, classWorld);
   }
 
+  @override
   bool isDefinitelyBool(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
     return t.nonNullable().containsOnlyBool(classWorld);
   }
 
+  @override
   bool isDefinitelyNum(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
     return t.nonNullable().containsOnlyNum(classWorld);
   }
 
+  @override
   bool isDefinitelyString(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
     return t.nonNullable().containsOnlyString(classWorld);
   }
 
+  @override
   bool isDefinitelyNumStringBool(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
     return numStringBoolType.containsMask(t.nonNullable(), classWorld);
   }
 
+  @override
   bool isDefinitelyNotNumStringBool(TypeMask t) {
     return areDisjoint(t, numStringBoolType);
   }
@@ -194,6 +341,7 @@
   ///
   /// This does not imply that the value is an integer, since most other values
   /// such as null are also not a non-integer double.
+  @override
   bool isDefinitelyNotNonIntegerDouble(TypeMask t) {
     // Even though int is a subclass of double in the JS type system, we can
     // still check this with disjointness, because [doubleType] is the *exact*
@@ -204,77 +352,113 @@
     return areDisjoint(t, doubleType);
   }
 
+  @override
   bool isDefinitelyNonNegativeInt(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
     // The JSPositiveInt class includes zero, despite the name.
-    return t.satisfies(backend.jsPositiveIntClass, classWorld);
+    return t.satisfies(helpers.jsPositiveIntClass, classWorld);
   }
 
+  @override
   bool isDefinitelyInt(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.satisfies(backend.jsIntClass, classWorld);
+    return t.nonNullable().containsOnlyInt(classWorld);
   }
 
+  @override
   bool isDefinitelyUint31(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.satisfies(backend.jsUInt31Class, classWorld);
+    return t.satisfies(helpers.jsUInt31Class, classWorld);
   }
 
+  @override
   bool isDefinitelyUint32(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.satisfies(backend.jsUInt32Class, classWorld);
+    return t.satisfies(helpers.jsUInt32Class, classWorld);
   }
 
+  @override
   bool isDefinitelyUint(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.satisfies(backend.jsPositiveIntClass, classWorld);
+    return t.satisfies(helpers.jsPositiveIntClass, classWorld);
   }
 
-  // TODO(sra): Find a better name.  'NativeList' is a bad name because there
-  // are many native classes in dart:html that implement List but are not (and
-  // should not be) included in this predicate.
-  bool isDefinitelyNativeList(TypeMask t, {bool allowNull: false}) {
+  @override
+  bool isDefinitelyArray(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsArrayClass, classWorld);
+    return t.nonNullable().satisfies(helpers.jsArrayClass, classWorld);
   }
 
-  bool isDefinitelyMutableNativeList(TypeMask t, {bool allowNull: false}) {
+  @override
+  bool isDefinitelyMutableArray(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsMutableArrayClass, classWorld);
+    return t.nonNullable().satisfies(helpers.jsMutableArrayClass, classWorld);
   }
 
-  bool isDefinitelyFixedNativeList(TypeMask t, {bool allowNull: false}) {
+  @override
+  bool isDefinitelyFixedArray(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsFixedArrayClass, classWorld);
+    return t.nonNullable().satisfies(helpers.jsFixedArrayClass, classWorld);
   }
 
-  bool isDefinitelyExtendableNativeList(TypeMask t, {bool allowNull: false}) {
+  @override
+  bool isDefinitelyExtendableArray(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsExtendableArrayClass,
+    return t.nonNullable().satisfies(helpers.jsExtendableArrayClass,
                                      classWorld);
   }
 
+  @override
   bool isDefinitelyIndexable(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsIndexableClass, classWorld);
+    return _indexableTypeTest.containsMask(t.nonNullable(), classWorld);
   }
 
+  @override
   bool isDefinitelyMutableIndexable(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(backend.jsMutableIndexableClass,
+    return t.nonNullable().satisfies(helpers.jsMutableIndexableClass,
         classWorld);
   }
 
+  @override
   bool isDefinitelyFixedLengthIndexable(TypeMask t, {bool allowNull: false}) {
     if (!allowNull && t.isNullable) return false;
     return fixedLengthType.containsMask(t.nonNullable(), classWorld);
   }
 
-  bool areDisjoint(TypeMask leftType, TypeMask rightType) {
-    TypeMask intersection = leftType.intersection(rightType, classWorld);
-    return intersection.isEmpty && !intersection.isNullable;
+  @override
+  bool isDefinitelyIntercepted(TypeMask t, {bool allowNull}) {
+    assert(allowNull != null);
+    if (!allowNull && t.isNullable) return false;
+    return interceptedTypes.containsMask(t.nonNullable(), classWorld);
   }
 
+  /// Given a class from the interceptor hierarchy, returns a [TypeMask]
+  /// matching all values with that interceptor (or a subtype thereof).
+  @override
+  TypeMask getInterceptorSubtypes(ClassElement class_) {
+    if (class_ == helpers.jsInterceptorClass) {
+      return interceptorType.nullable();
+    } else if (class_ == helpers.jsNullClass) {
+      return nullType;
+    } else {
+      return nonNullSubclass(class_);
+    }
+  }
+
+  @override
+  bool areDisjoint(TypeMask leftType, TypeMask rightType) {
+    TypeMask intersected = intersection(leftType, rightType);
+    return intersected.isEmpty && !intersected.isNullable;
+  }
+
+  @override
+  bool isMorePreciseOrEqual(TypeMask t1, TypeMask t2) {
+    return t2.containsMask(t1, classWorld);
+  }
+
+  @override
   AbstractBool isSubtypeOf(TypeMask value,
                            types.DartType type,
                            {bool allowNull}) {
@@ -310,6 +494,7 @@
 
   /// Returns whether [type] is one of the falsy values: false, 0, -0, NaN,
   /// the empty string, or null.
+  @override
   AbstractBool boolify(TypeMask type) {
     if (isDefinitelyNotNumStringBool(type) && !type.isNullable) {
       return AbstractBool.True;
@@ -317,12 +502,14 @@
     return AbstractBool.Maybe;
   }
 
+  @override
   AbstractBool strictBoolify(TypeMask type) {
     if (areDisjoint(type, boolType)) return AbstractBool.False;
     return AbstractBool.Maybe;
   }
 
   /// Create a type mask containing at least all subtypes of [type].
+  @override
   TypeMask subtypesOf(types.DartType type) {
     if (type is types.InterfaceType) {
       ClassElement element = type.element;
@@ -355,12 +542,14 @@
 
   /// Returns a subset of [mask] containing at least the types
   /// that can respond to [selector] without throwing.
+  @override
   TypeMask receiverTypeFor(Selector selector, TypeMask mask) {
     return classWorld.allFunctions.receiverType(selector, mask);
   }
 
   /// The result of an index operation on something of [type], or the dynamic
   /// type if unknown.
+  @override
   TypeMask elementTypeOfIndexable(TypeMask type) {
     if (type is UnionTypeMask) {
       return new TypeMask.unionOf(
@@ -372,8 +561,8 @@
     if (isDefinitelyString(type)) {
       return stringType;
     }
-    if (type.satisfies(backend.typedArrayClass, classWorld)) {
-      if (type.satisfies(backend.typedArrayOfIntClass, classWorld)) {
+    if (type.satisfies(helpers.typedArrayClass, classWorld)) {
+      if (type.satisfies(helpers.typedArrayOfIntClass, classWorld)) {
         return intType;
       }
       return numType;
@@ -382,6 +571,7 @@
   }
 
   /// The length of something of [type], or `null` if unknown.
+  @override
   int getContainerLength(TypeMask type) {
     if (type is ContainerTypeMask) {
       return type.length;
@@ -389,4 +579,19 @@
       return null;
     }
   }
+
+  /// Returns the type of the entry at a given index, `null` if unknown.
+  TypeMask indexWithConstant(TypeMask container, ConstantValue indexValue) {
+    if (container is DictionaryTypeMask) {
+      if (indexValue is StringConstantValue) {
+        String key = indexValue.primitiveValue.slowToString();
+        TypeMask result = container.typeMap[key];
+        if (result != null) return result;
+      }
+    }
+    if (container is ContainerTypeMask) {
+      return container.elementType;
+    }
+    return null;
+  }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 5784d3d..aa26e31 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -19,6 +19,8 @@
 import '../elements/elements.dart';
 import '../io/source_information.dart' show
     SourceInformation;
+import '../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend/js_backend.dart' show
     JavaScriptBackend;
 import '../js_backend/codegen/task.dart' show
@@ -28,6 +30,8 @@
 import '../resolution/send_structure.dart';
 import '../tree/tree.dart' as ast;
 import '../types/types.dart';
+import '../types/abstract_value_domain.dart' show
+    AbstractBool;
 import '../universe/selector.dart' show
     Selector;
 import '../world.dart' show World;
@@ -39,31 +43,32 @@
   final TypeMaskSystem typeSystem;
   final ConstantSystem constantSystem;
   final types.DartTypes dartTypes;
-  final AbstractValue anything;
-  final AbstractValue nullValue;
+  final AbstractConstantValue anything;
+  final AbstractConstantValue nullValue;
 
-  ConstantPropagationLattice(TypeMaskSystem typeSystem,
-                             this.constantSystem,
-                             this.dartTypes)
-    : this.typeSystem = typeSystem,
-      anything = new AbstractValue.nonConstant(typeSystem.dynamicType),
-      nullValue = new AbstractValue.constantValue(
+  ConstantPropagationLattice(CpsFunctionCompiler functionCompiler)
+    : typeSystem = functionCompiler.typeSystem,
+      constantSystem = functionCompiler.compiler.backend.constantSystem,
+      dartTypes = functionCompiler.compiler.types,
+      anything = new AbstractConstantValue.nonConstant(
+          functionCompiler.typeSystem.dynamicType),
+      nullValue = new AbstractConstantValue.constantValue(
           new NullConstantValue(), new TypeMask.empty());
 
-  final AbstractValue nothing = new AbstractValue.nothing();
+  final AbstractConstantValue nothing = new AbstractConstantValue.nothing();
 
-  AbstractValue constant(ConstantValue value, [TypeMask type]) {
+  AbstractConstantValue constant(ConstantValue value, [TypeMask type]) {
     if (type == null) type = typeSystem.getTypeOf(value);
-    return new AbstractValue.constantValue(value, type);
+    return new AbstractConstantValue.constantValue(value, type);
   }
 
-  AbstractValue nonConstant([TypeMask type]) {
+  AbstractConstantValue nonConstant([TypeMask type]) {
     if (type == null) type = typeSystem.dynamicType;
-    return new AbstractValue.nonConstant(type);
+    return new AbstractConstantValue.nonConstant(type);
   }
 
   /// Compute the join of two values in the lattice.
-  AbstractValue join(AbstractValue x, AbstractValue y) {
+  AbstractConstantValue join(AbstractConstantValue x, AbstractConstantValue y) {
     assert(x != null);
     assert(y != null);
 
@@ -74,36 +79,39 @@
     } else if (x.isConstant && y.isConstant && x.constant == y.constant) {
       return x;
     } else {
-      return new AbstractValue.nonConstant(typeSystem.join(x.type, y.type));
+      return new AbstractConstantValue.nonConstant(
+          typeSystem.join(x.type, y.type));
     }
   }
 
   /// True if all members of this value are booleans.
-  bool isDefinitelyBool(AbstractValue value, {bool allowNull: false}) {
+  bool isDefinitelyBool(AbstractConstantValue value, {bool allowNull: false}) {
     return value.isNothing ||
       typeSystem.isDefinitelyBool(value.type, allowNull: allowNull);
   }
 
   /// True if all members of this value are numbers.
-  bool isDefinitelyNum(AbstractValue value, {bool allowNull: false}) {
+  bool isDefinitelyNum(AbstractConstantValue value, {bool allowNull: false}) {
     return value.isNothing ||
       typeSystem.isDefinitelyNum(value.type, allowNull: allowNull);
   }
 
   /// True if all members of this value are strings.
-  bool isDefinitelyString(AbstractValue value, {bool allowNull: false}) {
+  bool isDefinitelyString(AbstractConstantValue value,
+                          {bool allowNull: false}) {
     return value.isNothing ||
       typeSystem.isDefinitelyString(value.type, allowNull: allowNull);
   }
 
   /// True if all members of this value are numbers, strings, or booleans.
-  bool isDefinitelyNumStringBool(AbstractValue value, {bool allowNull: false}) {
+  bool isDefinitelyNumStringBool(AbstractConstantValue value,
+                                 {bool allowNull: false}) {
     return value.isNothing ||
       typeSystem.isDefinitelyNumStringBool(value.type, allowNull: allowNull);
   }
 
   /// True if this value cannot be a string, number, or boolean.
-  bool isDefinitelyNotNumStringBool(AbstractValue value) {
+  bool isDefinitelyNotNumStringBool(AbstractConstantValue value) {
     return value.isNothing ||
       typeSystem.isDefinitelyNotNumStringBool(value.type);
   }
@@ -112,71 +120,72 @@
   ///
   /// In other words, if true is returned, and the value is a number, then
   /// it is a whole number and is not NaN, Infinity, or minus Infinity.
-  bool isDefinitelyNotNonIntegerDouble(AbstractValue value) {
+  bool isDefinitelyNotNonIntegerDouble(AbstractConstantValue value) {
     return value.isNothing ||
       value.isConstant && !value.constant.isDouble ||
       typeSystem.isDefinitelyNotNonIntegerDouble(value.type);
   }
 
-  bool isDefinitelyInt(AbstractValue value,
+  bool isDefinitelyInt(AbstractConstantValue value,
                        {bool allowNull: false}) {
     return value.isNothing ||
         typeSystem.isDefinitelyInt(value.type, allowNull: allowNull);
   }
 
-  bool isDefinitelyUint31(AbstractValue value,
-                       {bool allowNull: false}) {
+  bool isDefinitelyUint31(AbstractConstantValue value,
+                          {bool allowNull: false}) {
     return value.isNothing ||
         typeSystem.isDefinitelyUint31(value.type, allowNull: allowNull);
   }
 
-  bool isDefinitelyUint32(AbstractValue value,
-                       {bool allowNull: false}) {
+  bool isDefinitelyUint32(AbstractConstantValue value,
+                          {bool allowNull: false}) {
     return value.isNothing ||
         typeSystem.isDefinitelyUint32(value.type, allowNull: allowNull);
   }
 
-  bool isDefinitelyUint(AbstractValue value,
+  bool isDefinitelyUint(AbstractConstantValue value,
                        {bool allowNull: false}) {
     return value.isNothing ||
         typeSystem.isDefinitelyUint(value.type, allowNull: allowNull);
   }
 
-  bool isDefinitelyNativeList(AbstractValue value,
+  bool isDefinitelyArray(AbstractConstantValue value,
                               {bool allowNull: false}) {
     return value.isNothing ||
-        typeSystem.isDefinitelyNativeList(value.type, allowNull: allowNull);
+        typeSystem.isDefinitelyArray(value.type, allowNull: allowNull);
   }
 
-  bool isDefinitelyMutableNativeList(AbstractValue value,
+  bool isDefinitelyMutableArray(AbstractConstantValue value,
                                      {bool allowNull: false}) {
     return value.isNothing ||
-         typeSystem.isDefinitelyMutableNativeList(value.type,
+         typeSystem.isDefinitelyMutableArray(value.type,
                                                   allowNull: allowNull);
   }
 
-  bool isDefinitelyFixedNativeList(AbstractValue value,
+  bool isDefinitelyFixedArray(AbstractConstantValue value,
+                              {bool allowNull: false}) {
+    return value.isNothing ||
+        typeSystem.isDefinitelyFixedArray(value.type,
+                                          allowNull: allowNull);
+  }
+
+  bool isDefinitelyExtendableArray(AbstractConstantValue value,
                                    {bool allowNull: false}) {
     return value.isNothing ||
-        typeSystem.isDefinitelyFixedNativeList(value.type,
+        typeSystem.isDefinitelyExtendableArray(value.type,
                                                allowNull: allowNull);
   }
 
-  bool isDefinitelyExtendableNativeList(AbstractValue value,
-                                        {bool allowNull: false}) {
-    return value.isNothing ||
-        typeSystem.isDefinitelyExtendableNativeList(value.type,
-                                                    allowNull: allowNull);
-  }
-
-  bool isDefinitelyIndexable(AbstractValue value, {bool allowNull: false}) {
+  bool isDefinitelyIndexable(AbstractConstantValue value,
+                             {bool allowNull: false}) {
     return value.isNothing ||
         typeSystem.isDefinitelyIndexable(value.type, allowNull: allowNull);
   }
 
   /// Returns `true` if [value] represents an int value that must be in the
   /// inclusive range.
-  bool isDefinitelyIntInRange(AbstractValue value, {int min, int max}) {
+  bool isDefinitelyIntInRange(AbstractConstantValue value, {int min, int max}) {
     if (value.isNothing) return true;
     if (!isDefinitelyInt(value)) return false;
     PrimitiveConstantValue constant = value.constant;
@@ -197,7 +206,7 @@
   /// If [allowNull] is true, `null` is considered an instance of anything,
   /// otherwise it is only considered an instance of [Object], [dynamic], and
   /// [Null].
-  AbstractBool isSubtypeOf(AbstractValue value,
+  AbstractBool isSubtypeOf(AbstractConstantValue value,
                            types.DartType type,
                            {bool allowNull}) {
     assert(allowNull != null);
@@ -243,8 +252,16 @@
   ///
   /// This method returns `null` if a good result could not be found. In that
   /// case, it is best to fall back on interprocedural type information.
-  AbstractValue unaryOp(UnaryOperator operator,
-                        AbstractValue value) {
+  AbstractConstantValue unaryOp(UnaryOperator operator,
+                                AbstractConstantValue value) {
+    switch (operator.kind) {
+      case UnaryOperatorKind.COMPLEMENT:
+        return bitNotSpecial(value);
+      case UnaryOperatorKind.NEGATE:
+        return negateSpecial(value);
+      default:
+        break;
+    }
     // TODO(asgerf): Also return information about whether this can throw?
     if (value.isNothing) {
       return nothing;
@@ -267,9 +284,9 @@
   ///
   /// This method returns `null` if a good result could not be found. In that
   /// case, it is best to fall back on interprocedural type information.
-  AbstractValue binaryOp(BinaryOperator operator,
-                         AbstractValue left,
-                         AbstractValue right) {
+  AbstractConstantValue binaryOp(BinaryOperator operator,
+                         AbstractConstantValue left,
+                         AbstractConstantValue right) {
     switch (operator.kind) {
       case BinaryOperatorKind.ADD:
         return addSpecial(left, right);
@@ -334,8 +351,30 @@
     return null; // The caller will use return type from type inference.
   }
 
-  AbstractValue foldBinary(BinaryOperation operation,
-      AbstractValue left, AbstractValue right) {
+  AbstractConstantValue foldUnary(UnaryOperation operation,
+                                  AbstractConstantValue value) {
+    if (value.isNothing) return nothing;
+    if (value.isConstant) {
+      ConstantValue result = operation.fold(value.constant);
+      if (result != null) return constant(result);
+    }
+    return null;
+  }
+
+  AbstractConstantValue bitNotSpecial(AbstractConstantValue value) {
+    return foldUnary(constantSystem.bitNot, value);
+  }
+
+  AbstractConstantValue negateSpecial(AbstractConstantValue value) {
+    AbstractConstantValue folded = foldUnary(constantSystem.negate, value);
+    if (folded != null) return folded;
+    if (isDefinitelyInt(value)) return nonConstant(typeSystem.intType);
+    return null;
+  }
+
+
+  AbstractConstantValue foldBinary(BinaryOperation operation,
+      AbstractConstantValue left, AbstractConstantValue right) {
     if (left.isNothing || right.isNothing) return nothing;
     if (left.isConstant && right.isConstant) {
       ConstantValue result = operation.fold(left.constant, right.constant);
@@ -344,32 +383,37 @@
     return null;
   }
 
-  AbstractValue closedOnInt(AbstractValue left, AbstractValue right) {
-    if (isDefinitelyInt(left) && isDefinitelyInt(right)) {
+  AbstractConstantValue closedOnInt(AbstractConstantValue left,
+                                    AbstractConstantValue right) {
+    if (isDefinitelyInt(left) && isDefinitelyInt(right, allowNull: true)) {
       return nonConstant(typeSystem.intType);
     }
     return null;
   }
 
-  AbstractValue closedOnUint(AbstractValue left, AbstractValue right) {
-    if (isDefinitelyUint(left) && isDefinitelyUint(right)) {
+  AbstractConstantValue closedOnUint(AbstractConstantValue left,
+                                     AbstractConstantValue right) {
+    if (isDefinitelyUint(left) && isDefinitelyUint(right, allowNull: true)) {
       return nonConstant(typeSystem.uintType);
     }
     return null;
   }
 
-  AbstractValue closedOnUint31(AbstractValue left, AbstractValue right) {
-    if (isDefinitelyUint31(left) && isDefinitelyUint31(right)) {
+  AbstractConstantValue closedOnUint31(AbstractConstantValue left,
+                                       AbstractConstantValue right) {
+    if (isDefinitelyUint31(left) && isDefinitelyUint31(right, allowNull: true)) {
       return nonConstant(typeSystem.uint31Type);
     }
     return null;
   }
 
-  AbstractValue addSpecial(AbstractValue left, AbstractValue right) {
-    AbstractValue folded = foldBinary(constantSystem.add, left, right);
+  AbstractConstantValue addSpecial(AbstractConstantValue left,
+                                   AbstractConstantValue right) {
+    AbstractConstantValue folded = foldBinary(constantSystem.add, left, right);
     if (folded != null) return folded;
     if (isDefinitelyNum(left)) {
-      if (isDefinitelyUint31(left) && isDefinitelyUint31(right)) {
+      if (isDefinitelyUint31(left) &&
+          isDefinitelyUint31(right, allowNull: true)) {
         return nonConstant(typeSystem.uint32Type);
       }
       return closedOnUint(left, right) ?? closedOnInt(left, right);
@@ -377,30 +421,35 @@
     return null;
   }
 
-  AbstractValue subtractSpecial(AbstractValue left, AbstractValue right) {
-    AbstractValue folded = foldBinary(constantSystem.subtract, left, right);
+  AbstractConstantValue subtractSpecial(AbstractConstantValue left,
+                                        AbstractConstantValue right) {
+    AbstractConstantValue folded =
+        foldBinary(constantSystem.subtract, left, right);
     return folded ?? closedOnInt(left, right);
   }
 
-  AbstractValue multiplySpecial(AbstractValue left, AbstractValue right) {
-    AbstractValue folded = foldBinary(constantSystem.multiply, left, right);
+  AbstractConstantValue multiplySpecial(AbstractConstantValue left,
+                                        AbstractConstantValue right) {
+    AbstractConstantValue folded =
+        foldBinary(constantSystem.multiply, left, right);
     return folded ?? closedOnUint(left, right) ?? closedOnInt(left, right);
   }
 
-  AbstractValue divideSpecial(AbstractValue left, AbstractValue right) {
+  AbstractConstantValue divideSpecial(AbstractConstantValue left,
+                                      AbstractConstantValue right) {
     return foldBinary(constantSystem.divide, left, right);
   }
 
-  AbstractValue truncatingDivideSpecial(
-      AbstractValue left, AbstractValue right) {
-    AbstractValue folded =
+  AbstractConstantValue truncatingDivideSpecial(
+      AbstractConstantValue left, AbstractConstantValue right) {
+    AbstractConstantValue folded =
         foldBinary(constantSystem.truncatingDivide, left, right);
     if (folded != null) return folded;
     if (isDefinitelyNum(left)) {
       if (isDefinitelyUint32(left) && isDefinitelyIntInRange(right, min: 2)) {
         return nonConstant(typeSystem.uint31Type);
       }
-      if (isDefinitelyUint(right)) {
+      if (isDefinitelyUint(right, allowNull: true)) {
         // `0` will be an exception, other values will shrink the result.
         if (isDefinitelyUint31(left)) return nonConstant(typeSystem.uint31Type);
         if (isDefinitelyUint32(left)) return nonConstant(typeSystem.uint32Type);
@@ -411,19 +460,29 @@
     return null;
   }
 
-  AbstractValue moduloSpecial(AbstractValue left, AbstractValue right) {
-    AbstractValue folded = foldBinary(constantSystem.modulo, left, right);
+  AbstractConstantValue moduloSpecial(AbstractConstantValue left,
+                                      AbstractConstantValue right) {
+    AbstractConstantValue folded =
+        foldBinary(constantSystem.modulo, left, right);
     return folded ?? closedOnUint(left, right) ?? closedOnInt(left, right);
   }
 
-  AbstractValue remainderSpecial(AbstractValue left, AbstractValue right) {
+  AbstractConstantValue remainderSpecial(AbstractConstantValue left,
+                                         AbstractConstantValue right) {
     if (left.isNothing || right.isNothing) return nothing;
-    AbstractValue folded = null;  // Remainder not in constant system.
+    AbstractConstantValue folded = null;  // Remainder not in constant system.
     return folded ?? closedOnUint(left, right) ?? closedOnInt(left, right);
   }
 
-  AbstractValue equalSpecial(AbstractValue left, AbstractValue right) {
-    AbstractValue folded = foldBinary(constantSystem.equal, left, right);
+  AbstractConstantValue codeUnitAtSpecial(AbstractConstantValue left,
+                                          AbstractConstantValue right) {
+    return foldBinary(constantSystem.codeUnitAt, left, right);
+  }
+
+  AbstractConstantValue equalSpecial(AbstractConstantValue left,
+                                     AbstractConstantValue right) {
+    AbstractConstantValue folded =
+        foldBinary(constantSystem.equal, left, right);
     if (folded != null) return folded;
     bool behavesLikeIdentity =
         isDefinitelyNumStringBool(left, allowNull: true) ||
@@ -435,11 +494,14 @@
     return null;
   }
 
-  AbstractValue andSpecial(AbstractValue left, AbstractValue right) {
-    AbstractValue folded = foldBinary(constantSystem.bitAnd, left, right);
+  AbstractConstantValue andSpecial(AbstractConstantValue left,
+                                   AbstractConstantValue right) {
+    AbstractConstantValue folded =
+        foldBinary(constantSystem.bitAnd, left, right);
     if (folded != null) return folded;
     if (isDefinitelyNum(left)) {
-      if (isDefinitelyUint31(left) || isDefinitelyUint31(right)) {
+      if (isDefinitelyUint31(left) ||
+          isDefinitelyUint31(right, allowNull: true)) {
         // Either 31-bit argument will truncate the other.
         return nonConstant(typeSystem.uint31Type);
       }
@@ -447,22 +509,29 @@
     return null;
   }
 
-  AbstractValue orSpecial(AbstractValue left, AbstractValue right) {
-    AbstractValue folded = foldBinary(constantSystem.bitOr, left, right);
+  AbstractConstantValue orSpecial(AbstractConstantValue left,
+                                  AbstractConstantValue right) {
+    AbstractConstantValue folded =
+        foldBinary(constantSystem.bitOr, left, right);
     return folded ?? closedOnUint31(left, right);
   }
 
-  AbstractValue xorSpecial(AbstractValue left, AbstractValue right) {
-    AbstractValue folded = foldBinary(constantSystem.bitXor, left, right);
+  AbstractConstantValue xorSpecial(AbstractConstantValue left,
+                                   AbstractConstantValue right) {
+    AbstractConstantValue folded =
+        foldBinary(constantSystem.bitXor, left, right);
     return folded ?? closedOnUint31(left, right);
   }
 
-  AbstractValue shiftLeftSpecial(AbstractValue left, AbstractValue right) {
+  AbstractConstantValue shiftLeftSpecial(AbstractConstantValue left,
+                                         AbstractConstantValue right) {
     return foldBinary(constantSystem.shiftLeft, left, right);
   }
 
-  AbstractValue shiftRightSpecial(AbstractValue left, AbstractValue right) {
-    AbstractValue folded = foldBinary(constantSystem.shiftRight, left, right);
+  AbstractConstantValue shiftRightSpecial(AbstractConstantValue left,
+                                          AbstractConstantValue right) {
+    AbstractConstantValue folded =
+        foldBinary(constantSystem.shiftRight, left, right);
     if (folded != null) return folded;
     if (isDefinitelyUint31(left)) {
       return nonConstant(typeSystem.uint31Type);
@@ -476,28 +545,91 @@
     return null;
   }
 
-  AbstractValue lessSpecial(AbstractValue left, AbstractValue right) {
+  AbstractConstantValue lessSpecial(AbstractConstantValue left,
+                                    AbstractConstantValue right) {
     return foldBinary(constantSystem.less, left, right);
   }
 
-  AbstractValue lessEqualSpecial(AbstractValue left, AbstractValue right) {
+  AbstractConstantValue lessEqualSpecial(AbstractConstantValue left,
+                                         AbstractConstantValue right) {
     return foldBinary(constantSystem.lessEqual, left, right);
   }
 
-  AbstractValue greaterSpecial(AbstractValue left, AbstractValue right) {
+  AbstractConstantValue greaterSpecial(AbstractConstantValue left,
+                                       AbstractConstantValue right) {
     return foldBinary(constantSystem.greater, left, right);
   }
 
-  AbstractValue greaterEqualSpecial(AbstractValue left, AbstractValue right) {
+  AbstractConstantValue greaterEqualSpecial(AbstractConstantValue left,
+                                            AbstractConstantValue right) {
     return foldBinary(constantSystem.greaterEqual, left, right);
   }
 
+  AbstractConstantValue intConstant(int value) {
+    return constant(new IntConstantValue(value));
+  }
 
-  AbstractValue stringConstant(String value) {
+  AbstractConstantValue lengthSpecial(AbstractConstantValue input) {
+    if (input.isConstant) {
+      ConstantValue constant = input.constant;
+      if (constant is StringConstantValue) {
+        return intConstant(constant.length);
+      } else if (constant is ListConstantValue) {
+        return intConstant(constant.length);
+      }
+    }
+    int length = typeSystem.getContainerLength(input.type);
+    if (length != null) {
+      return intConstant(length);
+    }
+    return null;  // The caller will use return type from type inference.
+  }
+
+  AbstractConstantValue stringConstant(String value) {
     return constant(new StringConstantValue(new ast.DartString.literal(value)));
   }
 
-  AbstractValue stringify(AbstractValue value) {
+  AbstractConstantValue indexSpecial(AbstractConstantValue left,
+                                     AbstractConstantValue right) {
+    if (left.isNothing || right.isNothing) return nothing;
+    if (right.isConstant) {
+      ConstantValue index = right.constant;
+      if (left.isConstant) {
+        ConstantValue receiver = left.constant;
+        if (receiver is StringConstantValue) {
+          if (index is IntConstantValue) {
+            String stringValue = receiver.primitiveValue.slowToString();
+            int indexValue = index.primitiveValue;
+            if (0 <= indexValue && indexValue < stringValue.length) {
+              return stringConstant(stringValue[indexValue]);
+            } else {
+              return nothing;  // Will throw.
+            }
+          }
+        } else if (receiver is ListConstantValue) {
+          if (index is IntConstantValue) {
+            int indexValue = index.primitiveValue;
+            if (0 <= indexValue && indexValue < receiver.length) {
+              return constant(receiver.entries[indexValue]);
+            } else {
+              return nothing;  // Will throw.
+            }
+          }
+        } else if (receiver is MapConstantValue) {
+          ConstantValue result = receiver.lookup(index);
+          if (result != null) {
+            return constant(result);
+          }
+          return constant(new NullConstantValue());
+        }
+      }
+      TypeMask type = typeSystem.indexWithConstant(left.type, index);
+      if (type != null) return nonConstant(type);
+    }
+    return null;  // The caller will use return type from type inference.
+  }
+
+  AbstractConstantValue stringify(AbstractConstantValue value) {
     if (value.isNothing) return nothing;
     if (value.isNonConst) return nonConstant(typeSystem.stringType);
     ConstantValue constantValue = value.constant;
@@ -515,7 +647,7 @@
 
   /// Returns whether [value] is one of the falsy values: false, 0, -0, NaN,
   /// the empty string, or null.
-  AbstractBool boolify(AbstractValue value) {
+  AbstractBool boolify(AbstractConstantValue value) {
     if (value.isNothing) return AbstractBool.Nothing;
     if (value.isConstant) {
       ConstantValue constantValue = value.constant;
@@ -529,7 +661,7 @@
   }
 
   /// Returns whether [value] is the value `true`.
-  AbstractBool strictBoolify(AbstractValue value) {
+  AbstractBool strictBoolify(AbstractConstantValue value) {
     if (value.isNothing) return AbstractBool.Nothing;
     if (value.isConstant) {
       return value.constant.isTrue ? AbstractBool.True : AbstractBool.False;
@@ -538,17 +670,32 @@
   }
 
   /// The possible return types of a method that may be targeted by
-  /// [typedSelector]. If the given selector is not a [TypedSelector], any
-  /// reachable method matching the selector may be targeted.
-  AbstractValue getInvokeReturnType(Selector selector, TypeMask mask) {
-    return fromMask(typeSystem.getInvokeReturnType(selector, mask));
+  /// [selector] on [receiver].
+  AbstractConstantValue getInvokeReturnType(
+      Selector selector, AbstractConstantValue receiver) {
+    return fromMask(typeSystem.getInvokeReturnType(selector, receiver.type));
   }
 
-  AbstractValue fromMask(TypeMask mask) {
+  AbstractConstantValue fromMask(TypeMask mask) {
     ConstantValue constantValue = typeSystem.getConstantOf(mask);
     if (constantValue != null) return constant(constantValue, mask);
     return nonConstant(mask);
   }
+
+  AbstractConstantValue nonNullable(AbstractConstantValue value) {
+    if (value.isNullConstant) return nothing;
+    if (!value.isNullable) return value;
+    return nonConstant(value.type.nonNullable());
+  }
+
+  /// If [value] is an integer constant, returns its value, otherwise `null`.
+  int intValue(AbstractConstantValue value) {
+    if (value.isConstant && value.constant.isInt) {
+      PrimitiveConstantValue constant = value.constant;
+      return constant.primitiveValue;
+    }
+    return null;
+  }
 }
 
 /**
@@ -562,36 +709,26 @@
  * by Wegman, Zadeck.
  */
 class TypePropagator extends Pass {
-  String get passName => 'Sparse constant propagation';
+  String get passName => 'Type propagation';
 
-  final dart2js.Compiler _compiler;
   final CpsFunctionCompiler _functionCompiler;
+  final Map<Variable, ConstantValue> _values= <Variable, ConstantValue>{};
   final ConstantPropagationLattice _lattice;
-  final InternalErrorFunction _internalError;
-  final Map<Variable, ConstantValue> _values = <Variable, ConstantValue>{};
-  final TypeMaskSystem _typeSystem;
 
-  TypePropagator(dart2js.Compiler compiler,
-                 TypeMaskSystem typeSystem,
-                 this._functionCompiler)
-      : _compiler = compiler,
-        _internalError = compiler.reporter.internalError,
-        _typeSystem = typeSystem,
-        _lattice = new ConstantPropagationLattice(
-            typeSystem,
-            compiler.backend.constantSystem,
-            compiler.types);
+  TypePropagator(CpsFunctionCompiler functionCompiler)
+      : _functionCompiler = functionCompiler,
+        _lattice = new ConstantPropagationLattice(functionCompiler);
+
+  dart2js.Compiler get _compiler => _functionCompiler.compiler;
+  InternalErrorFunction get _internalError => _compiler.reporter.internalError;
 
   @override
   void rewrite(FunctionDefinition root) {
-    Map<Expression, ConstantValue> replacements = <Expression, ConstantValue>{};
-
     // Analyze. In this phase, the entire term is analyzed for reachability
     // and the abstract value of each expression.
     TypePropagationVisitor analyzer = new TypePropagationVisitor(
         _lattice,
         _values,
-        replacements,
         _internalError);
 
     analyzer.analyze(root);
@@ -604,7 +741,6 @@
         _functionCompiler,
         _lattice,
         analyzer,
-        replacements,
         _internalError);
     transformer.transform(root);
   }
@@ -631,14 +767,15 @@
  */
 class TransformingVisitor extends DeepRecursiveVisitor {
   final TypePropagationVisitor analyzer;
-  final Map<Expression, ConstantValue> replacements;
   final ConstantPropagationLattice lattice;
   final dart2js.Compiler compiler;
   final CpsFunctionCompiler functionCompiler;
 
   JavaScriptBackend get backend => compiler.backend;
+  BackendHelpers get helpers => backend.helpers;
   TypeMaskSystem get typeSystem => lattice.typeSystem;
   types.DartTypes get dartTypes => lattice.dartTypes;
+  World get classWorld => typeSystem.classWorld;
   Map<Variable, ConstantValue> get values => analyzer.values;
 
   final InternalErrorFunction internalError;
@@ -649,10 +786,24 @@
                       this.functionCompiler,
                       this.lattice,
                       this.analyzer,
-                      this.replacements,
                       this.internalError);
 
   void transform(FunctionDefinition root) {
+    // If one of the parameters has no value, the function is unreachable.
+    // We assume all values in scope have a non-empty type (otherwise the
+    // scope is unreachable), so this optimization is required.
+    // TODO(asgerf): Can we avoid emitting the function is the first place?
+    for (Parameter param in root.parameters) {
+      if (getValue(param).isNothing) {
+        // Replace with `throw "Unreachable";`
+        CpsFragment cps = new CpsFragment(null);
+        Primitive message = cps.makeConstant(
+            new StringConstantValue.fromString("Unreachable"));
+        cps.put(new Throw(message));
+        replaceSubtree(root.body, cps.result);
+        return;
+      }
+    }
     push(root.body);
     while (stack.isNotEmpty) {
       visit(stack.removeLast());
@@ -688,39 +839,79 @@
   }
 
   void visitLetPrim(LetPrim node) {
-    AbstractValue value = getValue(node.primitive);
-    if (node.primitive is! Constant &&
-        node.primitive is! Refinement &&
-        node.primitive.isSafeForElimination &&
-        value.isConstant) {
-      // If the value is a known constant, compile it as a constant.
-      Constant newPrim = makeConstantPrimitive(value.constant);
-      newPrim.substituteFor(node.primitive);
-      RemovalVisitor.remove(node.primitive);
-      node.primitive = newPrim;
-      newPrim.parent = node;
-    } else {
-      Primitive newPrim = visit(node.primitive);
-      if (newPrim != null) {
-        newPrim.substituteFor(node.primitive);
-        RemovalVisitor.remove(node.primitive);
-        node.primitive = newPrim;
-        newPrim.parent = node;
-        reanalyze(newPrim);
-      }
-      if (node.primitive.hasNoUses && node.primitive.isSafeForElimination) {
-        // Remove unused primitives before entering the body.
-        // This would also be done by shrinking reductions, but usage analyses
-        // such as isAlwaysBoolified are more precise without the dead uses, so
-        // we prefer to remove them early.
-        RemovalVisitor.remove(node.primitive);
-        node.parent.body = node.body;
-        node.body.parent = node.parent;
+    Primitive prim = node.primitive;
+
+    // Try to remove a dead primitive.
+    if (prim.hasNoUses && prim.isSafeForElimination) {
+      push(node.body);
+      prim.destroy();
+      node.remove();
+      return;
+    }
+
+    // Try to constant-fold the primitive.
+    if (prim is! Constant && prim is! Refinement && prim.isSafeForElimination) {
+      AbstractConstantValue value = getValue(prim);
+      if (value.isConstant) {
+        if (constantIsSafeToCopy(value.constant)) {
+          prim.replaceWith(makeConstantPrimitive(value.constant));
+          push(node.body);
+          return;
+        }
       }
     }
+
+    // Try to specialize the primitive.
+    var replacement = visit(prim);
+    if (replacement is CpsFragment) {
+      reanalyzeFragment(replacement);
+      replacement.insertBelow(node);
+      push(node.body); // Get the body before removing the node.
+      prim.destroy();
+      node.remove();
+      return;
+    }
+    if (replacement is Primitive) {
+      prim.replaceWith(replacement);
+      reanalyze(replacement);
+      // Reanalyze this node. Further specialization may be possible.
+      push(node);
+      return;
+    }
+    assert(replacement == null);
+
+    // Remove dead code after a primitive that always throws.
+    if (isAlwaysThrowingOrDiverging(prim)) {
+      replaceSubtree(node.body, new Unreachable());
+      return;
+    }
+
     push(node.body);
   }
 
+  bool constantIsSafeToCopy(ConstantValue constant) {
+    // TODO(25230, 25231): We should refer to large shared strings by name.
+    // This number is chosen to prevent huge strings being copied. Don't make
+    // this too small, otherwise it will suppress otherwise harmless constant
+    // folding.
+    const int MAXIMUM_LENGTH_OF_DUPLICATED_STRING = 500;
+    return constant is StringConstantValue
+        ? constant.length < MAXIMUM_LENGTH_OF_DUPLICATED_STRING
+        : true;
+  }
+
+  bool isAlwaysThrowingOrDiverging(Primitive prim) {
+    if (prim is SetField) {
+      return getValue(prim.object.definition).isNullConstant;
+    }
+    if (prim is SetIndex) {
+      return getValue(prim.object.definition).isNullConstant;
+    }
+    // If a primitive has a value, but can't return anything, it must throw
+    // or diverge.
+    return prim.hasValue && prim.type.isEmpty && !prim.type.isNullable;
+  }
+
   void visitContinuation(Continuation node) {
     if (node.isReturnContinuation) return;
     if (!analyzer.reachableContinuations.contains(node)) {
@@ -740,27 +931,35 @@
     analyzer.reanalyzeSubtree(node);
   }
 
+  /// Sets parent pointers and computes types for the given fragment.
+  void reanalyzeFragment(CpsFragment code) {
+    if (code.isEmpty) return;
+    if (code.isOpen) {
+      // Temporarily close the fragment while analyzing it.
+      // TODO(asgerf): Perhaps the analyzer should just cope with missing nodes.
+      InteriorNode context = code.context;
+      code.put(new Unreachable());
+      reanalyze(code.root);
+      code.context = context;
+      context.body = null;
+    } else {
+      reanalyze(code.root);
+    }
+  }
+
   /// Removes the entire subtree of [node] and inserts [replacement].
   ///
-  /// By default, all references in the [node] subtree are unlinked, and parent
-  /// pointers in [replacement] are initialized and its types recomputed.
-  ///
-  /// If the caller needs to manually unlink the node, because some references
-  /// were adopted by other nodes, it can be disabled by passing `false`
-  /// as the [unlink] parameter.
+  /// All references in the [node] subtree are unlinked all types in
+  /// [replacement] are recomputed.
   ///
   /// [replacement] must be "fresh", i.e. it must not contain significant parts
-  /// of the original IR inside of it since the [ParentVisitor] will
-  /// redundantly reprocess it.
-  void replaceSubtree(Expression node, Expression replacement,
-                      {bool unlink: true}) {
+  /// of the original IR inside of it, as this leads to redundant reprocessing.
+  void replaceSubtree(Expression node, Expression replacement) {
     InteriorNode parent = node.parent;
     parent.body = replacement;
     replacement.parent = parent;
     node.parent = null;
-    if (unlink) {
-      RemovalVisitor.remove(node);
-    }
+    RemovalVisitor.remove(node);
     reanalyze(replacement);
   }
 
@@ -787,16 +986,6 @@
     node.parent = context;
   }
 
-  /// Binds [prim] before [node].
-  void insertLetPrim(Expression node, Primitive prim) {
-    InteriorNode parent = node.parent;
-    LetPrim let = new LetPrim(prim);
-    parent.body = let;
-    let.body = node;
-    node.parent = let;
-    let.parent = parent;
-  }
-
   /// Make a constant primitive for [constant] and set its entry in [values].
   Constant makeConstantPrimitive(ConstantValue constant) {
     Constant primitive = new Constant(constant);
@@ -833,7 +1022,7 @@
     Continuation trueCont = node.trueContinuation.definition;
     Continuation falseCont = node.falseContinuation.definition;
     Primitive condition = node.condition.definition;
-    AbstractValue conditionValue = getValue(condition);
+    AbstractConstantValue conditionValue = getValue(condition);
 
     // Change to non-strict check if the condition is a boolean or null.
     if (lattice.isDefinitelyBool(conditionValue, allowNull: true)) {
@@ -858,44 +1047,6 @@
       push(invoke);
       return;
     }
-
-    if (condition is ApplyBuiltinOperator &&
-        (condition.operator == BuiltinOperator.LooseEq ||
-         condition.operator == BuiltinOperator.StrictEq)) {
-      Primitive leftArg = condition.arguments[0].definition;
-      Primitive rightArg = condition.arguments[1].definition;
-      AbstractValue left = getValue(leftArg);
-      AbstractValue right = getValue(rightArg);
-      if (right.isNullConstant &&
-          lattice.isDefinitelyNotNumStringBool(left)) {
-        // Rewrite:
-        //   if (x == null) S1 else S2
-        //     =>
-        //   if (x) S2 else S1   (note the swapped branches)
-        Branch branch = new Branch.loose(leftArg, falseCont, trueCont);
-        replaceSubtree(node, branch);
-        return;
-      } else if (left.isNullConstant &&
-                 lattice.isDefinitelyNotNumStringBool(right)) {
-        Branch branch = new Branch.loose(rightArg, falseCont, trueCont);
-        replaceSubtree(node, branch);
-        return;
-      } else if (right.isTrueConstant &&
-                 lattice.isDefinitelyBool(left, allowNull: true)) {
-        // Rewrite:
-        //   if (x == true) S1 else S2
-        //     =>
-        //   if (x) S1 else S2
-        Branch branch = new Branch.loose(leftArg, trueCont, falseCont);
-        replaceSubtree(node, branch);
-        return;
-      } else if (left.isTrueConstant &&
-                 lattice.isDefinitelyBool(right, allowNull: true)) {
-        Branch branch = new Branch.loose(rightArg, trueCont, falseCont);
-        replaceSubtree(node, branch);
-        return;
-      }
-    }
   }
 
   void visitInvokeContinuation(InvokeContinuation node) {
@@ -910,8 +1061,10 @@
         !cont.isRecursive &&
         !node.isEscapingTry) {
       for (int i = 0; i < node.arguments.length; ++i) {
-        node.arguments[i].definition.useElementAsHint(cont.parameters[i].hint);
-        node.arguments[i].definition.substituteFor(cont.parameters[i]);
+        Primitive argument = node.arguments[i].definition;
+        Parameter parameter = cont.parameters[i];
+        argument.useElementAsHint(parameter.hint);
+        parameter.replaceUsesWith(argument);
         node.arguments[i].unlink();
       }
       node.continuation.unlink();
@@ -936,25 +1089,64 @@
   /// Replaces [node] with a more specialized instruction, if possible.
   ///
   /// Returns `true` if the node was replaced.
-  bool specializeOperatorCall(InvokeMethod node) {
-    Continuation cont = node.continuation.definition;
-    bool replaceWithBinary(BuiltinOperator operator,
-                           Primitive left,
-                           Primitive right) {
-      Primitive prim =
-          new ApplyBuiltinOperator(operator, <Primitive>[left, right],
-                                   node.sourceInformation);
-      LetPrim let = makeLetPrimInvoke(prim, cont);
-      replaceSubtree(node, let);
-      push(let);
-      return true; // So returning early is more convenient.
+  specializeOperatorCall(InvokeMethod node) {
+    bool trustPrimitives = compiler.trustPrimitives;
+
+    /// Throws a [NoSuchMethodError] if the receiver is null, where [guard]
+    /// is a predicate that is true if and only if the receiver is null.
+    ///
+    /// See [NullCheck.guarded].
+    Primitive guardReceiver(CpsFragment cps, BuiltinOperator guard) {
+      if (guard == null || getValue(node.dartReceiver).isDefinitelyNotNull) {
+        return node.dartReceiver;
+      }
+      if (!trustPrimitives) {
+        // TODO(asgerf): Perhaps a separate optimization should decide that
+        // the guarded check is better based on the type?
+        Primitive check = cps.applyBuiltin(guard, [node.dartReceiver]);
+        return cps.letPrim(new NullCheck.guarded(check, node.dartReceiver,
+          node.selector, node.sourceInformation));
+      } else {
+        // Refine the receiver to be non-null for use in the operator.
+        // This restricts code motion and improves the type computed for the
+        // built-in operator that depends on it.
+        // This must be done even if trusting primitives.
+        return cps.letPrim(
+            new Refinement(node.dartReceiver, typeSystem.nonNullType));
+      }
+    }
+
+    /// Replaces the call with [operator], using the receiver and first argument
+    /// as operands (in that order).
+    ///
+    /// If [guard] is given, the receiver is checked using [guardReceiver],
+    /// unless it is known not to be null.
+    CpsFragment makeBinary(BuiltinOperator operator, {BuiltinOperator guard}) {
+      CpsFragment cps = new CpsFragment(node.sourceInformation);
+      Primitive left = guardReceiver(cps, guard);
+      Primitive right = node.dartArgument(0);
+      Primitive result = cps.applyBuiltin(operator, [left, right]);
+      result.hint = node.hint;
+      node.replaceUsesWith(result);
+      return cps;
+    }
+
+    /// Like [makeBinary] but for unary operators with the receiver as the
+    /// argument.
+    CpsFragment makeUnary(BuiltinOperator operator, {BuiltinOperator guard}) {
+      CpsFragment cps = new CpsFragment(node.sourceInformation);
+      Primitive argument = guardReceiver(cps, guard);
+      Primitive result = cps.applyBuiltin(operator, [argument]);
+      result.hint = node.hint;
+      node.replaceUsesWith(result);
+      return cps;
     }
 
     if (node.selector.isOperator && node.arguments.length == 2) {
-      Primitive leftArg = getDartReceiver(node);
-      Primitive rightArg = getDartArgument(node, 0);
-      AbstractValue left = getValue(leftArg);
-      AbstractValue right = getValue(rightArg);
+      Primitive leftArg = node.dartReceiver;
+      Primitive rightArg = node.dartArgument(0);
+      AbstractConstantValue left = getValue(leftArg);
+      AbstractConstantValue right = getValue(rightArg);
 
       String opname = node.selector.name;
       if (opname == '==') {
@@ -962,8 +1154,7 @@
         // fact that Dart-null corresponds to both JS-null and JS-undefined.
         // Please see documentation for IsFalsy, StrictEq, and LooseEq.
         if (left.isNullConstant || right.isNullConstant) {
-          return replaceWithBinary(BuiltinOperator.Identical,
-                                   leftArg, rightArg);
+          return makeBinary(BuiltinOperator.Identical);
         }
         // There are several implementations of == that behave like identical.
         // Specialize it if we definitely call one of those.
@@ -971,91 +1162,120 @@
         for (Element target in getAllTargets(left.type, node.selector)) {
           ClassElement clazz = target.enclosingClass.declaration;
           if (clazz != compiler.world.objectClass &&
-              clazz != backend.jsInterceptorClass &&
-              clazz != backend.jsNullClass) {
+              clazz != helpers.jsInterceptorClass &&
+              clazz != helpers.jsNullClass) {
             behavesLikeIdentical = false;
             break;
           }
         }
         if (behavesLikeIdentical) {
-          return replaceWithBinary(BuiltinOperator.Identical,
-                                   leftArg, rightArg);
+          return makeBinary(BuiltinOperator.Identical);
         }
       } else {
-        if (lattice.isDefinitelyNum(left, allowNull: false) &&
-            lattice.isDefinitelyNum(right, allowNull: false)) {
+        if (lattice.isDefinitelyNum(left, allowNull: true) &&
+            lattice.isDefinitelyNum(right, allowNull: trustPrimitives)) {
           // Try to insert a numeric operator.
           BuiltinOperator operator = NumBinaryBuiltins[opname];
           if (operator != null) {
-            return replaceWithBinary(operator, leftArg, rightArg);
+            return makeBinary(operator, guard: BuiltinOperator.IsNotNumber);
           }
           // Shift operators are not in [NumBinaryBuiltins] because Dart shifts
           // behave different to JS shifts, especially in the handling of the
           // shift count.
           // Try to insert a shift-left operator.
           if (opname == '<<' &&
-              lattice.isDefinitelyInt(left) &&
+              lattice.isDefinitelyInt(left, allowNull: true) &&
               lattice.isDefinitelyIntInRange(right, min: 0, max: 31)) {
-            return replaceWithBinary(BuiltinOperator.NumShl, leftArg, rightArg);
+            return makeBinary(BuiltinOperator.NumShl,
+                guard: BuiltinOperator.IsNotNumber);
           }
           // Try to insert a shift-right operator. JavaScript's right shift is
           // consistent with Dart's only for left operands in the unsigned
           // 32-bit range.
           if (opname == '>>' &&
-              lattice.isDefinitelyUint32(left) &&
+              lattice.isDefinitelyUint32(left, allowNull: true) &&
               lattice.isDefinitelyIntInRange(right, min: 0, max: 31)) {
-            return replaceWithBinary(BuiltinOperator.NumShr, leftArg, rightArg);
+            return makeBinary(BuiltinOperator.NumShr,
+                guard: BuiltinOperator.IsNotNumber);
           }
           // Try to use remainder for '%'. Both operands must be non-negative
           // and the divisor must be non-zero.
           if (opname == '%' &&
-              lattice.isDefinitelyUint(left) &&
+              lattice.isDefinitelyUint(left, allowNull: true) &&
               lattice.isDefinitelyUint(right) &&
               lattice.isDefinitelyIntInRange(right, min: 1)) {
-            return replaceWithBinary(
-                BuiltinOperator.NumRemainder, leftArg, rightArg);
+            return makeBinary(BuiltinOperator.NumRemainder,
+                guard: BuiltinOperator.IsNotNumber);
           }
 
           if (opname == '~/' &&
-              lattice.isDefinitelyUint32(left) &&
+              lattice.isDefinitelyUint32(left, allowNull: true) &&
               lattice.isDefinitelyIntInRange(right, min: 2)) {
-            return replaceWithBinary(
-                BuiltinOperator.NumTruncatingDivideToSigned32,
-                leftArg, rightArg);
+            return makeBinary(BuiltinOperator.NumTruncatingDivideToSigned32,
+                guard: BuiltinOperator.IsNotNumber);
           }
         }
-        if (lattice.isDefinitelyString(left, allowNull: false) &&
-            lattice.isDefinitelyString(right, allowNull: false) &&
+        if (lattice.isDefinitelyString(left, allowNull: trustPrimitives) &&
+            lattice.isDefinitelyString(right, allowNull: trustPrimitives) &&
             opname == '+') {
-          return replaceWithBinary(BuiltinOperator.StringConcatenate,
-                                   leftArg, rightArg);
+          // TODO(asgerf): Add IsString builtin so we can use a guard here.
+          return makeBinary(BuiltinOperator.StringConcatenate);
+        }
+      }
+    }
+    if (node.selector.isOperator && node.arguments.length == 1) {
+      Primitive argument = node.dartReceiver;
+      AbstractConstantValue value = getValue(argument);
+
+      if (lattice.isDefinitelyNum(value, allowNull: true)) {
+        String opname = node.selector.name;
+        if (opname == '~') {
+          return makeUnary(BuiltinOperator.NumBitNot,
+              guard: BuiltinOperator.IsNotNumber);
+        }
+        if (opname == 'unary-') {
+          return makeUnary(BuiltinOperator.NumNegate,
+              guard: BuiltinOperator.IsNotNumber);
         }
       }
     }
     if (node.selector.isCall) {
       String name = node.selector.name;
-      Primitive receiver = getDartReceiver(node);
-      AbstractValue receiverValue = getValue(receiver);
+      Primitive receiver = node.dartReceiver;
+      AbstractConstantValue receiverValue = getValue(receiver);
       if (name == 'remainder') {
         if (node.arguments.length == 2) {
-          Primitive arg = getDartArgument(node, 0);
-          AbstractValue argValue = getValue(arg);
-          if (lattice.isDefinitelyInt(receiverValue) &&
+          Primitive arg = node.dartArgument(0);
+          AbstractConstantValue argValue = getValue(arg);
+          if (lattice.isDefinitelyInt(receiverValue, allowNull: true) &&
               lattice.isDefinitelyInt(argValue) &&
               isIntNotZero(argValue)) {
-            return
-                replaceWithBinary(BuiltinOperator.NumRemainder, receiver, arg);
+            return makeBinary(BuiltinOperator.NumRemainder,
+                guard: BuiltinOperator.IsNotNumber);
+          }
+        }
+      } else if (name == 'codeUnitAt') {
+        if (node.arguments.length == 2) {
+          Primitive index = node.dartArgument(0);
+          if (lattice.isDefinitelyString(receiverValue) &&
+              lattice.isDefinitelyInt(getValue(index))) {
+            CpsFragment cps = new CpsFragment(node.sourceInformation);
+            receiver = makeBoundsCheck(cps, receiver, index);
+            ApplyBuiltinOperator get =
+                cps.applyBuiltin(BuiltinOperator.CharCodeAt,
+                                 <Primitive>[receiver, index]);
+            node.replaceUsesWith(get);
+            get.hint = node.hint;
+            return cps;
           }
         }
       }
     }
-    // We should only get here if the node was not specialized.
-    assert(node.parent != null);
-    return false;
+    return null;
   }
 
   /// Returns `true` if [value] represents an int value that cannot be zero.
-  bool isIntNotZero(AbstractValue value) {
+  bool isIntNotZero(AbstractConstantValue value) {
     return lattice.isDefinitelyIntInRange(value, min: 1) ||
         lattice.isDefinitelyIntInRange(value, max: -1);
   }
@@ -1064,54 +1284,29 @@
     return backend.isInterceptedSelector(selector);
   }
 
-  Primitive getDartReceiver(InvokeMethod node) {
-    if (node.receiverIsIntercepted) {
-      return node.arguments[0].definition;
-    } else {
-      return node.receiver.definition;
-    }
-  }
-
-  Primitive getDartArgument(InvokeMethod node, int n) {
-    if (isInterceptedSelector(node.selector)) {
-      return node.arguments[n+1].definition;
-    } else {
-      return node.arguments[n].definition;
-    }
-  }
-
   /// If [node] is a getter or setter invocation, tries to replace the
   /// invocation with a direct access to a field.
   ///
   /// Returns `true` if the node was replaced.
-  bool specializeFieldAccess(InvokeMethod node) {
-    if (!node.selector.isGetter && !node.selector.isSetter) return false;
-    AbstractValue receiver = getValue(getDartReceiver(node));
+  Primitive specializeFieldAccess(InvokeMethod node) {
+    if (!node.selector.isGetter && !node.selector.isSetter) return null;
+    AbstractConstantValue receiver = getValue(node.dartReceiver);
     Element target =
         typeSystem.locateSingleElement(receiver.type, node.selector);
-    if (target is! FieldElement) return false;
+    if (target is! FieldElement) return null;
     // TODO(asgerf): Inlining native fields will make some tests pass for the
     // wrong reason, so for testing reasons avoid inlining them.
-    if (target.isNative || target.isJsInterop) return false;
-    Continuation cont = node.continuation.definition;
+    if (backend.isNative(target) || backend.isJsInterop(target)) {
+      return null;
+    }
     if (node.selector.isGetter) {
-      GetField get = new GetField(getDartReceiver(node), target);
-      LetPrim let = makeLetPrimInvoke(get, cont);
-      replaceSubtree(node, let);
-      push(let);
-      return true;
+      return new GetField(node.dartReceiver, target);
     } else {
-      if (target.isFinal) return false;
-      assert(cont.parameters.single.hasNoUses);
-      cont.parameters.clear();
-      CpsFragment cps = new CpsFragment(node.sourceInformation);
-      cps.letPrim(new SetField(getDartReceiver(node),
-                               target,
-                               getDartArgument(node, 0)));
-      cps.invokeContinuation(cont);
-      replaceSubtree(node, cps.result);
-      push(cps.result);
-      return true;
+      if (target.isFinal) return null;
+      assert(node.hasNoUses);
+      return new SetField(node.dartReceiver,
+                          target,
+                          node.dartArgument(0));
     }
   }
 
@@ -1121,23 +1316,18 @@
   ///
   /// Returns a CPS fragment whose context is the branch where no error
   /// was thrown.
-  CpsFragment makeBoundsCheck(Primitive list,
-                              Primitive index,
-                              SourceInformation sourceInfo) {
-    CpsFragment cps = new CpsFragment(sourceInfo);
-    Continuation fail = cps.letCont();
-    Primitive isTooSmall = cps.applyBuiltin(
-        BuiltinOperator.NumLt,
-        <Primitive>[index, cps.makeZero()]);
-    cps.ifTruthy(isTooSmall).invokeContinuation(fail);
-    Primitive isTooLarge = cps.applyBuiltin(
-        BuiltinOperator.NumGe,
-        <Primitive>[index, cps.letPrim(new GetLength(list))]);
-    cps.ifTruthy(isTooLarge).invokeContinuation(fail);
-    cps.insideContinuation(fail).invokeStaticThrower(
-        backend.helpers.throwIndexOutOfBoundsError,
-        <Primitive>[list, index]);
-    return cps;
+  Primitive makeBoundsCheck(CpsFragment cps,
+                            Primitive list,
+                            Primitive index,
+                            [int checkKind = BoundsCheck.BOTH_BOUNDS]) {
+    if (compiler.trustPrimitives) {
+      return cps.letPrim(new BoundsCheck.noCheck(list, cps.sourceInformation));
+    } else {
+      GetLength length = cps.letPrim(new GetLength(list));
+      list = cps.refine(list, typeSystem.nonNullType);
+      return cps.letPrim(new BoundsCheck(list, index, length, checkKind,
+          cps.sourceInformation));
+    }
   }
 
   /// Create a check that throws if the length of [list] is not equal to
@@ -1153,7 +1343,7 @@
         BuiltinOperator.StrictNeq,
         <Primitive>[originalLength, cps.letPrim(new GetLength(list))]);
     cps.ifTruthy(lengthChanged).invokeStaticThrower(
-        backend.helpers.throwConcurrentModificationError,
+        helpers.throwConcurrentModificationError,
         <Primitive>[list]);
     return cps;
   }
@@ -1161,190 +1351,196 @@
   /// Tries to replace [node] with a direct `length` or index access.
   ///
   /// Returns `true` if the node was replaced.
-  bool specializeIndexableAccess(InvokeMethod node) {
-    Primitive receiver = getDartReceiver(node);
-    AbstractValue receiverValue = getValue(receiver);
+  specializeIndexableAccess(InvokeMethod node) {
+    Primitive receiver = node.dartReceiver;
+    AbstractConstantValue receiverValue = getValue(receiver);
     if (!typeSystem.isDefinitelyIndexable(receiverValue.type,
             allowNull: true)) {
-      return false;
+      return null;
     }
-    SourceInformation sourceInfo = node.sourceInformation;
-    Continuation cont = node.continuation.definition;
     switch (node.selector.name) {
       case 'length':
-        if (!node.selector.isGetter) return false;
-        CpsFragment cps = new CpsFragment(sourceInfo);
-        cps.invokeContinuation(cont, [cps.letPrim(new GetLength(receiver))]);
-        replaceSubtree(node, cps.result);
-        push(cps.result);
-        return true;
+        if (!node.selector.isGetter) return null;
+        return new GetLength(receiver);
 
       case '[]':
-        Primitive index = getDartArgument(node, 0);
-        if (!lattice.isDefinitelyInt(getValue(index))) return false;
-        CpsFragment cps = makeBoundsCheck(receiver, index, sourceInfo);
+        Primitive index = node.dartArgument(0);
+        if (!lattice.isDefinitelyInt(getValue(index))) return null;
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        receiver = makeBoundsCheck(cps, receiver, index);
         GetIndex get = cps.letPrim(new GetIndex(receiver, index));
-        cps.invokeContinuation(cont, [get]);
-        replaceSubtree(node, cps.result);
-        push(cps.result);
-        return true;
+        node.replaceUsesWith(get);
+        // TODO(asgerf): Make replaceUsesWith set the hint?
+        get.hint = node.hint;
+        return cps;
 
       case '[]=':
-        if (receiverValue.isNullable) return false;
-        if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type)) {
-          return false;
+        if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type,
+                allowNull: true)) {
+          return null;
         }
-        Primitive index = getDartArgument(node, 0);
-        Primitive value = getDartArgument(node, 1);
-        if (!lattice.isDefinitelyInt(getValue(index))) return false;
-        CpsFragment cps = makeBoundsCheck(receiver, index, sourceInfo);
+        Primitive index = node.dartArgument(0);
+        Primitive value = node.dartArgument(1);
+        if (!lattice.isDefinitelyInt(getValue(index))) return null;
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        receiver = makeBoundsCheck(cps, receiver, index);
         cps.letPrim(new SetIndex(receiver, index, value));
-        assert(cont.parameters.single.hasNoUses);
-        cont.parameters.clear();
-        cps.invokeContinuation(cont, []);
-        replaceSubtree(node, cps.result);
-        push(cps.result);
-        return true;
+        assert(node.hasNoUses);
+        return cps;
+
+      case 'isEmpty':
+        if (!node.selector.isGetter) return null;
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        Primitive length = cps.letPrim(new GetLength(receiver));
+        Constant zero = cps.makeZero();
+        ApplyBuiltinOperator op = cps.applyBuiltin(BuiltinOperator.StrictEq,
+                                                   [length, zero]);
+        node.replaceUsesWith(op);
+        op.hint = node.hint;
+        return cps;
+
+      case 'isNotEmpty':
+        if (!node.selector.isGetter) return null;
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        Primitive length = cps.letPrim(new GetLength(receiver));
+        Constant zero = cps.makeZero();
+        ApplyBuiltinOperator op = cps.applyBuiltin(BuiltinOperator.StrictNeq,
+                                                   [length, zero]);
+        node.replaceUsesWith(op);
+        op.hint = node.hint;
+        return cps;
 
       default:
-        return false;
+        return null;
     }
   }
 
   /// Tries to replace [node] with one or more direct array access operations.
   ///
   /// Returns `true` if the node was replaced.
-  bool specializeArrayAccess(InvokeMethod node) {
-    Primitive list = getDartReceiver(node);
-    AbstractValue listValue = getValue(list);
+  CpsFragment specializeArrayAccess(InvokeMethod node) {
+    Primitive list = node.dartReceiver;
+    AbstractConstantValue listValue = getValue(list);
     // Ensure that the object is a native list or null.
-    if (!lattice.isDefinitelyNativeList(listValue, allowNull: true)) {
-      return false;
+    if (!lattice.isDefinitelyArray(listValue, allowNull: true)) {
+      return null;
     }
     bool isFixedLength =
-        lattice.isDefinitelyFixedNativeList(listValue, allowNull: true);
-    bool isMutable =
-        lattice.isDefinitelyMutableNativeList(listValue, allowNull: true);
+        lattice.isDefinitelyFixedArray(listValue, allowNull: true);
     bool isExtendable =
-        lattice.isDefinitelyExtendableNativeList(listValue, allowNull: true);
+        lattice.isDefinitelyExtendableArray(listValue, allowNull: true);
     SourceInformation sourceInfo = node.sourceInformation;
-    Continuation cont = node.continuation.definition;
     switch (node.selector.name) {
       case 'add':
         if (!node.selector.isCall ||
             node.selector.positionalArgumentCount != 1 ||
             node.selector.namedArgumentCount != 0) {
-          return false;
+          return null;
         }
-        if (!isExtendable) return false;
-        Primitive addedItem = getDartArgument(node, 0);
+        if (!isExtendable) return null;
+        Primitive addedItem = node.dartArgument(0);
         CpsFragment cps = new CpsFragment(sourceInfo);
         cps.invokeBuiltin(BuiltinMethod.Push,
             list,
             <Primitive>[addedItem]);
-        cps.invokeContinuation(cont, [cps.makeNull()]);
-        replaceSubtree(node, cps.result);
-        push(cps.result);
-        return true;
+        if (node.hasAtLeastOneUse) {
+          node.replaceUsesWith(cps.makeNull());
+        }
+        return cps;
 
       case 'removeLast':
         if (!node.selector.isCall ||
             node.selector.argumentCount != 0) {
-          return false;
+          return null;
         }
-        if (!isExtendable) return false;
+        if (!isExtendable) return null;
         CpsFragment cps = new CpsFragment(sourceInfo);
-        Primitive length = cps.letPrim(new GetLength(list));
-        Primitive isEmpty = cps.applyBuiltin(
-            BuiltinOperator.StrictEq,
-            [length, cps.makeZero()]);
-        CpsFragment fail = cps.ifTruthy(isEmpty);
-        fail.invokeStaticThrower(
-            backend.helpers.throwIndexOutOfBoundsError,
-            [list, fail.makeConstant(new IntConstantValue(-1))]);
+        list = makeBoundsCheck(cps, list, cps.makeMinusOne(),
+            BoundsCheck.EMPTINESS);
         Primitive removedItem = cps.invokeBuiltin(BuiltinMethod.Pop,
             list,
             <Primitive>[]);
-        cps.invokeContinuation(cont, [removedItem]);
-        replaceSubtree(node, cps.result);
-        push(cps.result);
-        return true;
+        removedItem.hint = node.hint;
+        node.replaceUsesWith(removedItem);
+        return cps;
 
       case 'addAll':
         if (!node.selector.isCall ||
             node.selector.argumentCount != 1) {
-          return false;
+          return null;
         }
-        if (!isExtendable) return false;
-        Primitive addedList = getDartArgument(node, 0);
-        // Rewrite addAll([x1, ..., xN]) to push(x1, ..., xN).
+        if (!isExtendable) return null;
+        Primitive addedList = node.dartArgument(0);
+        // Rewrite addAll([x1, ..., xN]) to push(x1), ..., push(xN).
         // Ensure that the list is not mutated between creation and use.
         // We aim for the common case where this is the only use of the list,
         // which also guarantees that this list is not mutated before use.
         if (addedList is! LiteralList || !addedList.hasExactlyOneUse) {
-          return false;
+          return null;
         }
         LiteralList addedLiteral = addedList;
         CpsFragment cps = new CpsFragment(sourceInfo);
-        cps.invokeBuiltin(BuiltinMethod.Push,
-            list,
-            addedLiteral.values.map((ref) => ref.definition).toList());
-        cps.invokeContinuation(cont, [cps.makeNull()]);
-        replaceSubtree(node, cps.result);
-        push(cps.result);
-        return true;
+        for (Reference value in addedLiteral.values) {
+          cps.invokeBuiltin(BuiltinMethod.Push,
+              list,
+              <Primitive>[value.definition]);
+        }
+        if (node.hasAtLeastOneUse) {
+          node.replaceUsesWith(cps.makeNull());
+        }
+        return cps;
 
       case 'elementAt':
         if (!node.selector.isCall ||
             node.selector.positionalArgumentCount != 1 ||
             node.selector.namedArgumentCount != 0) {
-          return false;
+          return null;
         }
-        if (listValue.isNullable) return false;
-        Primitive index = getDartArgument(node, 0);
-        if (!lattice.isDefinitelyInt(getValue(index))) return false;
-        CpsFragment cps = makeBoundsCheck(list, index, sourceInfo);
+        if (listValue.isNullable) return null;
+        Primitive index = node.dartArgument(0);
+        if (!lattice.isDefinitelyInt(getValue(index))) return null;
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        list = makeBoundsCheck(cps, list, index);
         GetIndex get = cps.letPrim(new GetIndex(list, index));
-        cps.invokeContinuation(cont, [get]);
-        replaceSubtree(node, cps.result);
-        push(cps.result);
-        return true;
+        get.hint = node.hint;
+        node.replaceUsesWith(get);
+        return cps;
 
       case 'forEach':
         Element element =
             compiler.world.locateSingleElement(node.selector, listValue.type);
         if (element == null ||
             !element.isFunction ||
-            !node.selector.isCall) return false;
+            !node.selector.isCall) return null;
         assert(node.selector.positionalArgumentCount == 1);
         assert(node.selector.namedArgumentCount == 0);
         FunctionDefinition target = functionCompiler.compileToCpsIr(element);
 
-        node.receiver.definition.substituteFor(target.thisParameter);
-        for (int i = 0; i < node.arguments.length; ++i) {
-          node.arguments[i].definition.substituteFor(target.parameters[i]);
-        }
-        node.continuation.definition.substituteFor(target.returnContinuation);
-
-        replaceSubtree(node, target.body);
-        push(target.body);
-        return true;
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        Primitive result = cps.inlineFunction(target,
+            node.receiver.definition,
+            node.arguments.map((ref) => ref.definition).toList(),
+            hint: node.hint);
+        node.replaceUsesWith(result);
+        return cps;
 
       case 'iterator':
-        if (!node.selector.isGetter) return false;
-        Primitive iterator = cont.parameters.single;
-        Continuation iteratorCont = cont;
+        // TODO(asgerf): This should be done differently.
+        //               The types are recomputed in a very error-prone manner.
+        if (!node.selector.isGetter) return null;
+        Primitive iterator = node;
+        LetPrim iteratorBinding = node.parent;
 
         // Check that all uses of the iterator are 'moveNext' and 'current'.
         assert(!isInterceptedSelector(Selectors.moveNext));
         assert(!isInterceptedSelector(Selectors.current));
         for (Reference ref in iterator.effectiveUses) {
-          if (ref.parent is! InvokeMethod) return false;
+          if (ref.parent is! InvokeMethod) return null;
           InvokeMethod use = ref.parent;
-          if (ref != use.receiver) return false;
+          if (ref != use.receiver) return null;
           if (use.selector != Selectors.moveNext &&
               use.selector != Selectors.current) {
-            return false;
+            return null;
           }
         }
 
@@ -1357,17 +1553,14 @@
         // Rewrite all uses of the iterator.
         for (Reference ref in iterator.effectiveUses) {
           InvokeMethod use = ref.parent;
-          Continuation useCont = use.continuation.definition;
           if (use.selector == Selectors.current) {
             // Rewrite iterator.current to a use of the 'current' variable.
-            Parameter result = useCont.parameters.single;
-            if (result.hint != null) {
+            if (use.hint != null) {
               // If 'current' was originally moved into a named variable, use
               // that variable name for the mutable variable.
-              current.hint = result.hint;
+              current.hint = use.hint;
             }
-            LetPrim let = makeLetPrimInvoke(new GetMutable(current), useCont);
-            replaceSubtree(use, let);
+            use.replaceWith(new GetMutable(current));
           } else {
             assert (use.selector == Selectors.moveNext);
             // Rewrite iterator.moveNext() to:
@@ -1385,6 +1578,8 @@
 
             // [cps] contains the code we insert instead of moveNext().
             CpsFragment cps = new CpsFragment(node.sourceInformation);
+            Parameter result = new Parameter(node.hint);
+            Continuation moveNextCont = cps.letCont(<Parameter>[result]);
 
             // We must check for concurrent modification when calling moveNext.
             // When moveNext is used as a loop condition, the check prevents
@@ -1412,7 +1607,7 @@
             //
             // The check before the loop can often be eliminated because it
             // follows immediately after the 'iterator' call.
-            InteriorNode parent = getEffectiveParent(use);
+            InteriorNode parent = getEffectiveParent(use.parent);
             if (!isFixedLength) {
               if (parent is Continuation && parent.isRecursive) {
                 // Check for concurrent modification before every invocation
@@ -1423,7 +1618,7 @@
                      ref != null;
                      ref = ref.next) {
                   Expression invocationCaller = ref.parent;
-                  if (getEffectiveParent(invocationCaller) == iteratorCont) {
+                  if (getEffectiveParent(invocationCaller) == iteratorBinding) {
                     // No need to check for concurrent modification immediately
                     // after the call to 'iterator'.
                     continue;
@@ -1447,18 +1642,25 @@
             CpsFragment falseBranch = cps.ifFalsy(hasMore);
             falseBranch
               ..setMutable(current, falseBranch.makeNull())
-              ..invokeContinuation(useCont, [falseBranch.makeFalse()]);
+              ..invokeContinuation(moveNextCont, [falseBranch.makeFalse()]);
 
             // Return true if there are more element.
+            current.type = typeSystem.elementTypeOfIndexable(listValue.type);
             cps.setMutable(current,
                 cps.letPrim(new GetIndex(list, cps.getMutable(index))));
             cps.setMutable(index, cps.applyBuiltin(
                 BuiltinOperator.NumAdd,
                 [cps.getMutable(index), cps.makeOne()]));
-            cps.invokeContinuation(useCont, [cps.makeTrue()]);
+            cps.invokeContinuation(moveNextCont, [cps.makeTrue()]);
+
+            reanalyzeFragment(cps);
 
             // Replace the moveNext() call. It will be visited later.
-            replaceSubtree(use, cps.result);
+            LetPrim let = use.parent;
+            cps.context = moveNextCont;
+            cps.insertBelow(let);
+            let.remove();
+            use..replaceUsesWith(result)..destroy();
           }
         }
 
@@ -1470,46 +1672,21 @@
         cps.letMutable(index, cps.makeZero());
         cps.letMutable(current, cps.makeNull());
         cps.letPrim(originalLength);
-
-        // Insert this fragment before the continuation body and replace the
-        // iterator call with a call to the continuation without arguments.
-        // For scoping reasons, the variables must be bound inside the
-        // continuation, not at the invocation-site.
-        iteratorCont.parameters.clear();
-        insertBefore(iteratorCont.body, cps);
-        InvokeContinuation invoke = new InvokeContinuation(iteratorCont, []);
-        replaceSubtree(node, invoke);
-        push(invoke);
-        return true;
+        return cps;
 
       default:
-        return false;
+        return null;
     }
   }
 
-  /// If [prim] is the parameter to a call continuation, returns the
-  /// corresponding call.
-  CallExpression getCallWithResult(Primitive prim) {
-    if (prim is Parameter && prim.parent is Continuation) {
-      Continuation cont = prim.parent;
-      if (cont.hasExactlyOneUse) {
-        Node use = cont.firstRef.parent;
-        if (use is CallExpression) {
-          return use;
-        }
-      }
-    }
-    return null;
-  }
-
   /// Returns the first parent of [node] that is not a pure expression.
   InteriorNode getEffectiveParent(Expression node) {
     while (true) {
-      Node parent = node.parent;
+      InteriorNode parent = node.parent;
       if (parent is LetCont ||
           parent is LetPrim && parent.primitive.isSafeForReordering ||
           parent is LetPrim && parent.primitive is Refinement) {
-        node = parent;
+        node = parent as dynamic; // Make analyzer accept cross cast.
       } else {
         return parent;
       }
@@ -1523,14 +1700,14 @@
   ///       =>
   ///     obj.foo$<n>(<args>)
   ///
-  bool specializeClosureCall(InvokeMethod node) {
+  Primitive specializeClosureCall(InvokeMethod node) {
     Selector call = node.selector;
-    if (!call.isClosureCall) return false;
+    if (!call.isClosureCall) return null;
 
     assert(!isInterceptedSelector(call));
     assert(call.argumentCount == node.arguments.length);
 
-    Primitive tearOff = node.receiver.definition.effectiveDefinition;
+    Primitive tearOff = node.dartReceiver.effectiveDefinition;
     // Note: We don't know if [tearOff] is actually a tear-off.
     // We name variables based on the pattern we are trying to match.
 
@@ -1539,69 +1716,73 @@
       FunctionSignature signature = target.functionSignature;
 
       // If the selector does not apply, don't bother (will throw at runtime).
-      if (!call.signatureApplies(target)) return false;
+      if (!call.signatureApplies(target)) return null;
 
       // If some optional arguments are missing, give up.
       // TODO(asgerf): Improve optimization by inserting default arguments.
-      if (call.argumentCount != signature.parameterCount) return false;
+      if (call.argumentCount != signature.parameterCount) return null;
 
-      InvokeStatic invoke = new InvokeStatic.byReference(
-          target,
+      // Replace with InvokeStatic.
+      // The tear-off will be cleaned up by shrinking reductions.
+      return new InvokeStatic(target,
           new Selector.fromElement(target),
-          node.arguments,
-          node.continuation,
+          node.arguments.map((ref) => ref.definition).toList(),
           node.sourceInformation);
-      node.receiver.unlink();
-      replaceSubtree(node, invoke, unlink: false);
-      push(invoke);
-      return true;
     }
-    CallExpression tearOffInvoke = getCallWithResult(tearOff);
-    if (tearOffInvoke is InvokeMethod && tearOffInvoke.selector.isGetter) {
-      Selector getter = tearOffInvoke.selector;
+    if (tearOff is InvokeMethod && tearOff.selector.isGetter) {
+      Selector getter = tearOff.selector;
 
       // TODO(asgerf): Support torn-off intercepted methods.
-      if (isInterceptedSelector(getter)) return false;
+      if (isInterceptedSelector(getter)) return null;
 
-      Continuation getterCont = tearOffInvoke.continuation.definition;
+      LetPrim tearOffBinding = tearOff.parent;
 
-      Primitive object = tearOffInvoke.receiver.definition;
+      Primitive object = tearOff.receiver.definition;
 
       // Ensure that the object actually has a foo member, since we might
       // otherwise alter a noSuchMethod call.
       TypeMask type = getValue(object).type;
-      if (typeSystem.needsNoSuchMethodHandling(type, getter)) return false;
+      if (typeSystem.needsNoSuchMethodHandling(type, getter)) return null;
 
-      // Determine if the getter invocation can have side-effects.
       Element element = typeSystem.locateSingleElement(type, getter);
+
+      // If it's definitely not a tear-off, the rewrite is not worth it.
+      // If we don't know what the target is, we assume that it's better to
+      // rewrite (as long as it's safe to do so).
+      if (element != null && element.isGetter) return null;
+
+      // Either the target is a tear-off or we don't know what it is.
+      // If we don't know for sure, the getter might have side effects, which
+      // can make the rewriting unsafe, because we risk suppressing side effects
+      // in the getter.
+      // Determine if the getter invocation can have side-effects.
       bool isPure = element != null && !element.isGetter;
 
       // If there are multiple uses, we cannot eliminate the getter call and
       // therefore risk duplicating its side effects.
-      if (!isPure && tearOff.hasMultipleEffectiveUses) return false;
+      if (!isPure && tearOff.hasMultipleEffectiveUses) return null;
 
-      // If the getter call is impure, we risk reordering side effects.
-      if (!isPure && getEffectiveParent(node) != getterCont) {
-        return false;
+      // If the getter call is impure, we risk reordering side effects,
+      // unless it is immediately prior to the closure call.
+      if (!isPure && getEffectiveParent(node.parent) != tearOffBinding) {
+        return null;
       }
 
-      InvokeMethod invoke = new InvokeMethod.byReference(
-        new Reference<Primitive>(object),
+      InvokeMethod invoke = new InvokeMethod(
+        object,
         new Selector.call(getter.memberName, call.callStructure),
         type,
-        node.arguments,
-        node.continuation,
-        node.sourceInformation);
-      node.receiver.unlink();
-      replaceSubtree(node, invoke, unlink: false);
+        node.arguments.map((ref) => ref.definition).toList(),
+        sourceInformation: node.sourceInformation);
+      node.receiver.changeTo(new Parameter(null)); // Remove the tear off use.
 
       if (tearOff.hasNoEffectiveUses) {
         // Eliminate the getter call if it has no more uses.
         // This cannot be delegated to other optimizations because we need to
         // avoid duplication of side effects.
         destroyRefinementsOfDeadPrimitive(tearOff);
-        getterCont.parameters.clear();
-        replaceSubtree(tearOffInvoke, new InvokeContinuation(getterCont, []));
+        tearOff.destroy();
+        tearOffBinding.remove();
       } else {
         // There are more uses, so we cannot eliminate the getter call. This
         // means we duplicated the effects of the getter call, but we should
@@ -1609,59 +1790,46 @@
         assert(isPure);
       }
 
-      push(invoke);
-      return true;
+      return invoke;
     }
-    return false;
-  }
-
-  void destroyRefinementsOfDeadPrimitive(Primitive prim) {
-    while (prim.firstRef != null) {
-      Refinement refine = prim.firstRef.parent;
-      destroyRefinementsOfDeadPrimitive(refine);
-      LetPrim letPrim = refine.parent;
-      InteriorNode parent = letPrim.parent;
-      parent.body = letPrim.body;
-      letPrim.body.parent = parent;
-      prim.firstRef.unlink();
-    }
+    return null;
   }
 
   /// Inlines a single-use closure if it leaves the closure object with only
   /// field accesses.  This is optimized later by [ScalarReplacer].
-  bool specializeSingleUseClosureCall(InvokeMethod node) {
+  CpsFragment specializeSingleUseClosureCall(InvokeMethod node) {
     Selector call = node.selector;
-    if (!call.isClosureCall) return false;
+    if (!call.isClosureCall) return null;
 
     assert(!isInterceptedSelector(call));
     assert(call.argumentCount == node.arguments.length);
 
     Primitive receiver = node.receiver.definition;
-    if (receiver is !CreateInstance) return false;
+    if (receiver is !CreateInstance) return null;
     CreateInstance createInstance = receiver;
-    if (!createInstance.hasExactlyOneUse) return false;
+    if (!createInstance.hasExactlyOneUse) return null;
 
     // Inline only closures. This avoids inlining the 'call' method of a class
     // that has many allocation sites.
-    if (createInstance.classElement is !ClosureClassElement) return false;
+    if (createInstance.classElement is !ClosureClassElement) return null;
 
     ClosureClassElement closureClassElement = createInstance.classElement;
     Element element = closureClassElement.localLookup(Identifiers.call);
 
-    if (element == null || !element.isFunction) return false;
+    if (element == null || !element.isFunction) return null;
     FunctionElement functionElement = element;
-    if (functionElement.asyncMarker != AsyncMarker.SYNC) return false;
+    if (functionElement.asyncMarker != AsyncMarker.SYNC) return null;
 
-    if (!call.signatureApplies(functionElement)) return false;
+    if (!call.signatureApplies(functionElement)) return null;
     // Inline only for exact match.
     // TODO(sra): Handle call with defaulted arguments.
     Selector targetSelector = new Selector.fromElement(functionElement);
-    if (call.callStructure != targetSelector.callStructure) return false;
+    if (call.callStructure != targetSelector.callStructure) return null;
 
     // Don't inline if [target] contains try-catch or try-finally. JavaScript
     // engines typically do poor optimization of the entire function containing
     // the 'try'.
-    if (functionElement.resolvedAst.elements.containsTryStatement) return false;
+    if (functionElement.resolvedAst.elements.containsTryStatement) return null;
 
     FunctionDefinition target =
         functionCompiler.compileToCpsIr(functionElement);
@@ -1677,53 +1845,65 @@
       // Closures do not currently have writable fields, but closure conversion
       // could esily be changed to allocate some cells in a closure object.
       if (use is SetField && ref == use.object) continue;
-      return false;
+      return null;
     }
 
-    node.receiver.definition.substituteFor(target.thisParameter);
-    for (int i = 0; i < node.arguments.length; ++i) {
-      node.arguments[i].definition.substituteFor(target.parameters[i]);
+    CpsFragment cps = new CpsFragment(node.sourceInformation);
+    Primitive returnValue = cps.inlineFunction(target,
+        node.receiver.definition,
+        node.arguments.map((ref) => ref.definition).toList(),
+        hint: node.hint);
+    node.replaceUsesWith(returnValue);
+    return cps;
+  }
+
+  visitInterceptor(Interceptor node) {
+    // Replace the interceptor with its input if the value is not intercepted.
+    // If the input might be null, we cannot do this since the interceptor
+    // might have to return JSNull.  That case is handled by visitInvokeMethod
+    // and visitInvokeMethodDirectly which can sometimes tolerate that null
+    // is used instead of JSNull.
+    Primitive input = node.input.definition;
+    if (!input.type.isNullable &&
+        typeSystem.areDisjoint(input.type, typeSystem.interceptorType)) {
+      node.replaceUsesWith(input);
     }
-    node.continuation.definition.substituteFor(target.returnContinuation);
-
-    replaceSubtree(node, target.body);
-    push(target.body);
-    return true;
   }
 
-  /// Side-effect free expressions with constant results are be replaced by:
-  ///
-  ///    (LetPrim p = constant (InvokeContinuation k p)).
-  ///
-  /// The new expression will be visited.
-  ///
-  /// Returns true if the node was replaced.
-  bool constifyExpression(CallExpression node) {
-    Continuation continuation = node.continuation.definition;
-    ConstantValue constant = replacements[node];
-    if (constant == null) return false;
-    Constant primitive = makeConstantPrimitive(constant);
-    LetPrim letPrim = makeLetPrimInvoke(primitive, continuation);
-    replaceSubtree(node, letPrim);
-    push(letPrim);
-    return true;
+  visitInvokeMethodDirectly(InvokeMethodDirectly node) {
+    TypeMask receiverType = node.dartReceiver.type;
+    if (node.callingConvention == CallingConvention.Intercepted &&
+        typeSystem.areDisjoint(receiverType, typeSystem.interceptorType)) {
+      // Some direct calls take an interceptor because the target class is
+      // mixed into a native class.  If it is known at the call site that the
+      // receiver is non-intercepted, get rid of the interceptor.
+      node.receiver.changeTo(node.dartReceiver);
+    }
   }
 
-  void visitInvokeMethod(InvokeMethod node) {
-    if (constifyExpression(node)) return;
-    if (specializeOperatorCall(node)) return;
-    if (specializeFieldAccess(node)) return;
-    if (specializeIndexableAccess(node)) return;
-    if (specializeArrayAccess(node)) return;
-    if (specializeSingleUseClosureCall(node)) return;
-    if (specializeClosureCall(node)) return;
+  visitInvokeMethod(InvokeMethod node) {
+    var specialized =
+        specializeOperatorCall(node) ??
+        specializeFieldAccess(node) ??
+        specializeIndexableAccess(node) ??
+        specializeArrayAccess(node) ??
+        specializeSingleUseClosureCall(node) ??
+        specializeClosureCall(node);
+    if (specialized != null) return specialized;
 
-    AbstractValue receiver = getValue(node.receiver.definition);
+    TypeMask receiverType = node.dartReceiver.type;
+    node.mask = typeSystem.intersection(node.mask, receiverType);
 
-    if (node.receiverIsIntercepted &&
-        node.receiver.definition.sameValue(node.arguments[0].definition)) {
-      // The receiver and first argument are the same; that means we already
-      // determined in visitInterceptor that we are targeting a non-interceptor.
+    bool canBeNonThrowingCallOnNull =
+        selectorsOnNull.contains(node.selector) &&
+        receiverType.isNullable;
+
+    if (node.callingConvention == CallingConvention.Intercepted &&
+        !canBeNonThrowingCallOnNull &&
+        typeSystem.areDisjoint(receiverType, typeSystem.interceptorType)) {
+      // Use the Dart receiver as the JS receiver. This changes the wording of
+      // the error message when the receiver is null, but we accept this.
+      node.receiver.changeTo(node.dartReceiver);
 
       // Check if any of the possible targets depend on the extra receiver
       // argument. Mixins do this, and tear-offs always needs the extra receiver
@@ -1736,195 +1916,83 @@
         return typeSystem.methodUsesReceiverArgument(function) ||
                node.selector.isGetter && !function.isGetter;
       }
-      if (!getAllTargets(receiver.type, node.selector).any(needsReceiver)) {
+      if (!getAllTargets(receiverType, node.selector).any(needsReceiver)) {
         // Replace the extra receiver argument with a dummy value if the
         // target definitely does not use it.
         Constant dummy = makeConstantPrimitive(new IntConstantValue(0));
-        insertLetPrim(node, dummy);
+        new LetPrim(dummy).insertAbove(node.parent);
         node.arguments[0].changeTo(dummy);
-        node.receiverIsIntercepted = false;
+        node.callingConvention = CallingConvention.DummyIntercepted;
       }
     }
   }
 
-  void visitTypeCast(TypeCast node) {
-    Continuation cont = node.continuation.definition;
-
-    AbstractValue value = getValue(node.value.definition);
+  CpsFragment visitTypeCast(TypeCast node) {
+    AbstractConstantValue value = getValue(node.value.definition);
     switch (lattice.isSubtypeOf(value, node.dartType, allowNull: true)) {
       case AbstractBool.Maybe:
       case AbstractBool.Nothing:
-        break;
+        return null;
 
       case AbstractBool.True:
-        // Cast always succeeds, replace it with InvokeContinuation.
-        InvokeContinuation invoke =
-            new InvokeContinuation(cont, <Primitive>[node.value.definition]);
-        replaceSubtree(node, invoke);
-        push(invoke);
-        return;
+        // Return an unused primitive moved again.
+        node.replaceUsesWith(node.value.definition);
+        return new CpsFragment(); // Remove the node.
 
       case AbstractBool.False:
-        // Cast always fails, remove unreachable continuation body.
-        replaceSubtree(cont.body, new Unreachable());
-        break;
+        // Note: The surrounding LetPrim will remove the following code because
+        // it always throws. We don't need to do it here.
+        return null;
     }
   }
 
   /// Specialize calls to internal static methods.
-  ///
-  /// Returns true if the call was replaced.
-  bool specializeInternalMethodCall(InvokeStatic node) {
-    // TODO(asgerf): This is written to easily scale to more cases,
-    //               either add more cases or clean up.
-    Continuation cont = node.continuation.definition;
-    Primitive arg(int n) => node.arguments[n].definition;
-    AbstractValue argType(int n) => getValue(arg(n));
-
-    bool replaceWithBinary(BuiltinOperator operator,
-                           Primitive left,
-                           Primitive right) {
-      Primitive prim =
-          new ApplyBuiltinOperator(operator, <Primitive>[left, right],
-                                   node.sourceInformation);
-      LetPrim let = makeLetPrimInvoke(prim, cont);
-      replaceSubtree(node, let);
-      push(let);
-      return true; // So returning early is more convenient.
-    }
-
-    if (node.target.library.isInternalLibrary) {
-      switch(node.target.name) {
-        case InternalMethod.Stringify:
-          if (lattice.isDefinitelyString(argType(0))) {
-            InvokeContinuation invoke =
-                new InvokeContinuation(cont, <Primitive>[arg(0)]);
-            replaceSubtree(node, invoke);
-            push(invoke);
-            return true;
-          }
-          break;
+  specializeInternalMethodCall(InvokeStatic node) {
+    if (node.target == backend.helpers.stringInterpolationHelper) {
+      AbstractConstantValue value = getValue(node.arguments[0].definition);
+      if (lattice.isDefinitelyString(value)) {
+        node.replaceUsesWith(node.arguments[0].definition);
+        return new CpsFragment();
       }
-    } else if (node.target.library.isDartCore) {
-      switch(node.target.name) {
-        case CorelibMethod.Identical:
-          if (node.arguments.length == 2) {
-            return replaceWithBinary(BuiltinOperator.Identical, arg(0), arg(1));
-          }
-          break;
+    } else if (node.target == compiler.identicalFunction) {
+      if (node.arguments.length == 2) {
+        return new ApplyBuiltinOperator(BuiltinOperator.Identical,
+            [node.arguments[0].definition, node.arguments[1].definition],
+            node.sourceInformation);
       }
     }
-    return false;
+    return null;
   }
 
-  /// Try to inline static invocations.
-  ///
-  /// Performs the inlining and returns true if the call was inlined.  Inlining
-  /// uses a fixed heuristic:
-  ///
-  /// * Inline functions with a single expression statement or return statement
-  /// provided that the subexpression is an invocation of foreign code.
-  bool inlineInvokeStatic(InvokeStatic node) {
-    // The target might not have an AST, for example if it deferred.
-    if (!node.target.hasNode) return false;
-
-    // True if an expression is non-expansive, in the sense defined by this
-    // predicate.
-    bool isNonExpansive(ast.Expression expr) {
-      if (expr is ast.LiteralNull ||
-          expr is ast.LiteralBool ||
-          expr is ast.LiteralInt ||
-          expr is ast.LiteralDouble) {
-        return true;
-      }
-      if (expr is ast.Send) {
-        SendStructure structure =
-            node.target.treeElements.getSendStructure(expr);
-        if (structure is InvokeStructure) {
-          // Calls to foreign functions.
-          return structure.semantics.kind == AccessKind.TOPLEVEL_METHOD &&
-              backend.isForeign(structure.semantics.element);
-        } else if (structure is IsStructure || structure is IsNotStructure) {
-          // is and is! checks on nonexpansive expressions.
-          return isNonExpansive(expr.receiver);
-        } else if (structure is EqualsStructure ||
-            structure is NotEqualsStructure) {
-          // == and != on nonexpansive expressions.
-          return isNonExpansive(expr.receiver) &&
-              isNonExpansive(expr.argumentsNode.nodes.head);
-        } else if (structure is GetStructure) {
-          // Parameters.
-          return structure.semantics.kind == AccessKind.PARAMETER;
-        }
-      }
-      return false;
-    }
-
-    ast.Statement body = node.target.node.body;
-    bool shouldInline() {
-      if (backend.annotations.noInline(node.target)) return false;
-      if (node.target.resolvedAst.elements.containsTryStatement) return false;
-
-      // Inline functions that are a single return statement, expression
-      // statement, or block containing a return statement or expression
-      // statement.
-      if (body is ast.Return) {
-        return isNonExpansive(body.expression);
-      } else if (body is ast.ExpressionStatement) {
-        return isNonExpansive(body.expression);
-      } else if (body is ast.Block) {
-        var link = body.statements.nodes;
-        if (link.isNotEmpty && link.tail.isEmpty) {
-          if (link.head is ast.Return) {
-            return isNonExpansive(link.head.expression);
-          } else if (link.head is ast.ExpressionStatement) {
-            return isNonExpansive(link.head.expression);
-          }
-        }
-      }
-      return false;
-    }
-
-    if (!shouldInline()) return false;
-
-    FunctionDefinition target = functionCompiler.compileToCpsIr(node.target);
-    for (int i = 0; i < node.arguments.length; ++i) {
-      node.arguments[i].definition.substituteFor(target.parameters[i]);
-    }
-    node.continuation.definition.substituteFor(target.returnContinuation);
-
-    replaceSubtree(node, target.body);
-    push(target.body);
-    return true;
+  visitInvokeStatic(InvokeStatic node) {
+    return specializeInternalMethodCall(node);
   }
 
-  void visitInvokeStatic(InvokeStatic node) {
-    if (constifyExpression(node)) return;
-    if (specializeInternalMethodCall(node)) return;
-    if (inlineInvokeStatic(node)) return;
-  }
-
-  AbstractValue getValue(Variable node) {
+  AbstractConstantValue getValue(Variable node) {
+    assert(node.type != null);
     ConstantValue constant = values[node];
     if (constant != null) {
-      return new AbstractValue.constantValue(constant, node.type);
+      return new AbstractConstantValue.constantValue(constant, node.type);
     }
-    if (node.type != null) {
-      return new AbstractValue.nonConstant(node.type);
-    }
-    return lattice.nothing;
+    return new AbstractConstantValue.nonConstant(node.type);
   }
 
 
   /*************************** PRIMITIVES **************************/
   //
-  // The visit method for a primitive may optionally return a new
-  // primitive. If non-null, the surrounding LetPrim will substitute it
-  // and bind the new primitive instead.
+  // The visit method for a primitive may return one of the following:
+  // - Primitive:
+  //     The visited primitive will be replaced by the returned primitive.
+  //     The type of the primitive will be recomputed.
+  // - CpsFragment:
+  //     The primitive binding will be destroyed and replaced by the given
+  //     code fragment.  All types in the fragment will be recomputed.
+  // - Null:
+  //     Nothing happens. The primitive remains as it is.
   //
 
   void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    ast.DartString getString(AbstractValue value) {
+    ast.DartString getString(AbstractConstantValue value) {
       StringConstantValue constant = value.constant;
       return constant.primitiveValue;
     }
@@ -1935,9 +2003,11 @@
         int i = 0;
         while (i < node.arguments.length - 1) {
           int startOfSequence = i;
-          AbstractValue firstValue = getValue(node.arguments[i++].definition);
+          AbstractConstantValue firstValue =
+              getValue(node.arguments[i++].definition);
           if (!firstValue.isConstant) continue;
-          AbstractValue secondValue = getValue(node.arguments[i++].definition);
+          AbstractConstantValue secondValue =
+              getValue(node.arguments[i++].definition);
           if (!secondValue.isConstant) continue;
 
           ast.DartString string =
@@ -1947,14 +2017,15 @@
           // We found a sequence of at least two constants.
           // Look for the end of the sequence.
           while (i < node.arguments.length) {
-            AbstractValue value = getValue(node.arguments[i].definition);
+            AbstractConstantValue value =
+                getValue(node.arguments[i].definition);
             if (!value.isConstant) break;
             string = new ast.ConsDartString(string, getString(value));
             ++i;
           }
           Constant prim =
               makeConstantPrimitive(new StringConstantValue(string));
-          insertLetPrim(node.parent, prim);
+          new LetPrim(prim).insertAbove(node.parent);
           for (int k = startOfSequence; k < i; ++k) {
             node.arguments[k].unlink();
             node.arguments[k] = null; // Remove the argument after the loop.
@@ -1966,6 +2037,11 @@
         if (argumentsWereRemoved) {
           node.arguments.removeWhere((ref) => ref == null);
         }
+        if (node.arguments.length == 1) {
+          Primitive input = node.arguments[0].definition;
+          node.replaceUsesWith(input);
+          input.useElementAsHint(node.hint);
+        }
         // TODO(asgerf): Rebalance nested StringConcats that arise from
         //               rewriting the + operator to StringConcat.
         break;
@@ -1973,19 +2049,19 @@
       case BuiltinOperator.Identical:
         Primitive leftArg = node.arguments[0].definition;
         Primitive rightArg = node.arguments[1].definition;
-        AbstractValue left = getValue(leftArg);
-        AbstractValue right = getValue(rightArg);
+        AbstractConstantValue left = getValue(leftArg);
+        AbstractConstantValue right = getValue(rightArg);
         if (lattice.isDefinitelyBool(left) &&
             right.isConstant &&
             right.constant.isTrue) {
           // Replace identical(x, true) by x when x is known to be a boolean.
           // Note that this is not safe if x is null, because the value might
-          // not be used as a condition. A rule for [IsTrue] handles that case.
-          leftArg.substituteFor(node);
+          // not be used as a condition.
+          node.replaceUsesWith(leftArg);
         } else if (lattice.isDefinitelyBool(right) &&
             left.isConstant &&
             left.constant.isTrue) {
-          rightArg.substituteFor(node);
+          node.replaceUsesWith(rightArg);
         } else if (left.isNullConstant || right.isNullConstant) {
           // Use `==` for comparing against null, so JS undefined and JS null
           // are considered equal.
@@ -2014,52 +2090,21 @@
   }
 
   void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    if (node.method == BuiltinMethod.Push) {
-      // Convert consecutive pushes into a single push.
-      InteriorNode parent = getEffectiveParent(node.parent);
-      if (parent is LetPrim && parent.primitive is ApplyBuiltinMethod) {
-        ApplyBuiltinMethod previous = parent.primitive;
-        if (previous.method == BuiltinMethod.Push &&
-            previous.receiver.definition.sameValue(node.receiver.definition)) {
-          // We found two consecutive pushes.
-          // Move all arguments from the first push onto the second one.
-          List<Reference<Primitive>> arguments = previous.arguments;
-          for (Reference ref in arguments) {
-            ref.parent = node;
-          }
-          arguments.addAll(node.arguments);
-          node.arguments = arguments;
-          // Elimnate the old push.
-          previous.receiver.unlink();
-          assert(previous.hasNoUses);
-          parent.parent.body = parent.body;
-          parent.body.parent = parent.parent;
-        }
-      }
-    }
   }
 
-  Primitive visitTypeTest(TypeTest node) {
+  visitTypeTest(TypeTest node) {
     Primitive prim = node.value.definition;
 
     Primitive unaryBuiltinOperator(BuiltinOperator operator) =>
         new ApplyBuiltinOperator(
             operator, <Primitive>[prim], node.sourceInformation);
 
-    void unlinkInterceptor() {
-      if (node.interceptor != null) {
-        node.interceptor.unlink();
-        node.interceptor = null;
-      }
-    }
-
-    AbstractValue value = getValue(prim);
+    AbstractConstantValue value = getValue(prim);
     types.DartType dartType = node.dartType;
 
     if (!(dartType.isInterfaceType && dartType.isRaw)) {
       // TODO(23685): Efficient function arity check.
       // TODO(sra): Pass interceptor to runtime subtype functions.
-      unlinkInterceptor();
       return null;
     }
 
@@ -2101,7 +2146,7 @@
       // This has lower priority than the 'typeof'-based tests because
       // 'typeof' expressions might give the VM some more useful information.
       Primitive nullConst = makeConstantPrimitive(new NullConstantValue());
-      insertLetPrim(node.parent, nullConst);
+      new LetPrim(nullConst).insertAbove(node.parent);
       return new ApplyBuiltinOperator(
           BuiltinOperator.LooseNeq,
           <Primitive>[prim, nullConst],
@@ -2131,51 +2176,62 @@
     if (dartType == dartTypes.coreTypes.stringType ||
         dartType == dartTypes.coreTypes.boolType) {
       // These types are recognized in tree_ir TypeOperator codegen.
-      unlinkInterceptor();
       return null;
     }
 
-    // TODO(sra): Propagate sourceInformation.
     // TODO(sra): If getInterceptor(x) === x or JSNull, rewrite
     //     getInterceptor(x).$isFoo ---> x != null && x.$isFoo
-    return new TypeTestViaFlag(node.interceptor.definition, dartType);
+    CpsFragment cps = new CpsFragment(node.sourceInformation);
+    Interceptor interceptor =
+        cps.letPrim(new Interceptor(prim, node.sourceInformation));
+    Primitive testViaFlag =
+        cps.letPrim(new TypeTestViaFlag(interceptor, dartType));
+    node.replaceUsesWith(testViaFlag);
+    return cps;
   }
 
   Primitive visitTypeTestViaFlag(TypeTestViaFlag node) {
     return null;
   }
 
-  Primitive visitInterceptor(Interceptor node) {
-    AbstractValue value = getValue(node.input.definition);
-    // If the exact class of the input is known, replace with a constant
-    // or the input itself.
-    ClassElement singleClass;
-    if (lattice.isDefinitelyInt(value)) {
-      // Classes like JSUInt31 and JSUInt32 do not exist at runtime, so ensure
-      // all the int classes get mapped tor their runtime class.
-      singleClass = backend.jsIntClass;
-    } else if (lattice.isDefinitelyNativeList(value)) {
-      // Ensure all the array subclasses get mapped to the array class.
-      singleClass = backend.jsArrayClass;
-    } else {
-      singleClass = typeSystem.singleClass(value.type);
+  visitBoundsCheck(BoundsCheck node) {
+    // Eliminate bounds checks using constant folding.
+    // The [BoundsChecker] pass does not try to eliminate checks that could be
+    // eliminated by constant folding.
+    if (node.hasNoChecks) return;
+    int index = lattice.intValue(getValue(node.index.definition));
+    int length = node.length == null
+        ? null
+        : lattice.intValue(getValue(node.length.definition));
+    if (index != null && length != null && index < length) {
+      node.checks &= ~BoundsCheck.UPPER_BOUND;
     }
-    if (singleClass != null &&
-        singleClass.isSubclassOf(backend.jsInterceptorClass)) {
-      node.constantValue = new InterceptorConstantValue(singleClass.rawType);
+    if (index != null && index >= 0) {
+      node.checks &= ~BoundsCheck.LOWER_BOUND;
     }
-    // Filter out intercepted classes that do not match the input type.
-    node.interceptedClasses.retainWhere((ClassElement clazz) {
-      if (clazz == typeSystem.jsNullClass) {
-        return value.isNullable;
-      } else {
-        TypeMask classMask = typeSystem.nonNullSubclass(clazz);
-        return !typeSystem.areDisjoint(value.type, classMask);
-      }
-    });
-    // Remove the interceptor call if it can only return its input.
-    if (node.interceptedClasses.isEmpty) {
-      node.input.definition.substituteFor(node);
+    if (length != null && length > 0) {
+      node.checks &= ~BoundsCheck.EMPTINESS;
+    }
+    if (!node.lengthUsedInCheck && node.length != null) {
+      node..length.unlink()..length = null;
+    }
+    if (node.checks == BoundsCheck.NONE) {
+      // We can't remove the bounds check node because it may still be used to
+      // restrict code motion.  But the index is no longer needed.
+      // TODO(asgerf): Since this was eliminated by constant folding, it should
+      //     be safe to remove because any path-sensitive information we relied
+      //     upon to do this are expressed by other refinement nodes that also
+      //     restrict code motion.  However, if we want to run this pass after
+      //     [BoundsChecker] that would not be safe any more, so for now we
+      //     keep the node for forward compatibilty.
+      node..index.unlink()..index = null;
+    }
+  }
+
+  visitNullCheck(NullCheck node) {
+    if (!getValue(node.value.definition).isNullable) {
+      node.replaceUsesWith(node.value.definition);
+      return new CpsFragment();
     }
     return null;
   }
@@ -2210,13 +2266,17 @@
 
   JavaScriptBackend get backend => typeSystem.backend;
 
+  dart2js.Compiler get compiler => backend.compiler;
+
   World get classWorld => typeSystem.classWorld;
 
-  AbstractValue get nothing => lattice.nothing;
+  AbstractConstantValue get nothing => lattice.nothing;
 
-  AbstractValue nonConstant([TypeMask type]) => lattice.nonConstant(type);
+  AbstractConstantValue nonConstant([TypeMask type]) {
+    return lattice.nonConstant(type);
+  }
 
-  AbstractValue constantValue(ConstantValue constant, [TypeMask type]) {
+  AbstractConstantValue constantValue(ConstantValue constant, [TypeMask type]) {
     return lattice.constant(constant, type);
   }
 
@@ -2224,13 +2284,8 @@
   // Access through [getValue] and [setValue].
   final Map<Variable, ConstantValue> values;
 
-  /// Expressions that invoke their call continuation with a constant value
-  /// and without any side effects. These can be replaced by the constant.
-  final Map<Expression, ConstantValue> replacements;
-
   TypePropagationVisitor(this.lattice,
                          this.values,
-                         this.replacements,
                          this.internalError);
 
   void analyze(FunctionDefinition root) {
@@ -2286,13 +2341,13 @@
   /// Returns the lattice value corresponding to [node], defaulting to nothing.
   ///
   /// Never returns null.
-  AbstractValue getValue(Variable node) {
+  AbstractConstantValue getValue(Variable node) {
     ConstantValue constant = values[node];
     if (constant != null) {
-      return new AbstractValue.constantValue(constant, node.type);
+      return new AbstractConstantValue.constantValue(constant, node.type);
     }
     if (node.type != null) {
-      return new AbstractValue.nonConstant(node.type);
+      return new AbstractConstantValue.nonConstant(node.type);
     }
     return lattice.nothing;
   }
@@ -2300,9 +2355,9 @@
   /// Joins the passed lattice [updateValue] to the current value of [node],
   /// and adds it to the definition work set if it has changed and [node] is
   /// a definition.
-  void setValue(Variable node, AbstractValue updateValue) {
-    AbstractValue oldValue = getValue(node);
-    AbstractValue newValue = lattice.join(oldValue, updateValue);
+  void setValue(Variable node, AbstractConstantValue updateValue) {
+    AbstractConstantValue oldValue = getValue(node);
+    AbstractConstantValue newValue = lattice.join(oldValue, updateValue);
     node.type = newValue.type; // Ensure type is initialized even if bottom.
     if (oldValue == newValue) {
       return;
@@ -2315,72 +2370,63 @@
     defWorklist.add(node);
   }
 
-  /// Updates the value of a [CallExpression]'s continuation parameter.
-  void setResult(CallExpression call,
-                 AbstractValue updateValue,
+  /// Sets the type of the given primitive.
+  ///
+  /// If [updateValue] is a constant and [canReplace] is true, the primitive
+  /// is also marked as safe for elimination, so it can be constant-folded.
+  void setResult(UnsafePrimitive prim,
+                 AbstractConstantValue updateValue,
                  {bool canReplace: false}) {
-    Continuation cont = call.continuation.definition;
-    setValue(cont.parameters.single, updateValue);
-    if (!updateValue.isNothing) {
-      setReachable(cont);
-
-      if (updateValue.isConstant && canReplace) {
-        replacements[call] = updateValue.constant;
-      } else {
-        // A replacement might have been set in a previous iteration.
-        replacements.remove(call);
-      }
-    }
+    // TODO(asgerf): Separate constant folding from side effect analysis.
+    setValue(prim, updateValue);
+    prim.isSafeForElimination = canReplace && updateValue.isConstant;
   }
 
   bool isInterceptedSelector(Selector selector) {
     return backend.isInterceptedSelector(selector);
   }
 
-  Primitive getDartReceiver(InvokeMethod node) {
-    if (node.receiverIsIntercepted) {
-      return node.arguments[0].definition;
-    } else {
-      return node.receiver.definition;
-    }
-  }
-
-  Primitive getDartArgument(InvokeMethod node, int n) {
-    if (isInterceptedSelector(node.selector)) {
-      return node.arguments[n+1].definition;
-    } else {
-      return node.arguments[n].definition;
-    }
-  }
-
   // -------------------------- Visitor overrides ------------------------------
   void visit(Node node) { node.accept(this); }
 
   void visitFunctionDefinition(FunctionDefinition node) {
-    int firstActualParameter = 0;
-    if (backend.isInterceptedMethod(node.element)) {
-      if (typeSystem.methodUsesReceiverArgument(node.element)) {
+    bool isIntercepted = backend.isInterceptedMethod(node.element);
+
+    // If the abstract value of the function parameters is Nothing, use the
+    // inferred parameter type.  Otherwise (e.g., when inlining) do not
+    // change the abstract value.
+    if (node.thisParameter != null && getValue(node.thisParameter).isNothing) {
+      if (isIntercepted &&
+          typeSystem.methodUsesReceiverArgument(node.element)) {
         setValue(node.thisParameter, nonConstant(typeSystem.nonNullType));
-        setValue(node.parameters[0],
-                 nonConstant(typeSystem.getReceiverType(node.element)));
       } else {
         setValue(node.thisParameter,
-              nonConstant(typeSystem.getReceiverType(node.element)));
+            nonConstant(typeSystem.getReceiverType(node.element)));
+      }
+    }
+    if (isIntercepted && getValue(node.parameters[0]).isNothing) {
+      if (typeSystem.methodUsesReceiverArgument(node.element)) {
+        setValue(node.parameters[0],
+            nonConstant(typeSystem.getReceiverType(node.element)));
+      } else {
         setValue(node.parameters[0], nonConstant());
       }
-      firstActualParameter = 1;
-    } else if (node.thisParameter != null) {
-      setValue(node.thisParameter,
-               nonConstant(typeSystem.getReceiverType(node.element)));
     }
-    for (Parameter param in node.parameters.skip(firstActualParameter)) {
-      // TODO(karlklose): remove reference to the element model.
-      TypeMask type = param.hint is ParameterElement
-          ? typeSystem.getParameterType(param.hint)
-          : typeSystem.dynamicType;
-      setValue(param, lattice.fromMask(type));
+    bool hasParameterWithoutValue = false;
+    for (Parameter param in node.parameters.skip(isIntercepted ? 1 : 0)) {
+      if (getValue(param).isNothing) {
+        TypeMask type = param.hint is ParameterElement
+            ? typeSystem.getParameterType(param.hint)
+            : typeSystem.dynamicType;
+        setValue(param, lattice.fromMask(type));
+        if (type.isEmpty && !type.isNullable) {
+          hasParameterWithoutValue = true;
+        }
+      }
     }
-    push(node.body);
+    if (!hasParameterWithoutValue) { // Don't analyze unreachable code.
+      push(node.body);
+    }
   }
 
   void visitLetPrim(LetPrim node) {
@@ -2415,13 +2461,10 @@
   }
 
   void visitInvokeStatic(InvokeStatic node) {
-    if (node.target.library != null && node.target.library.isInternalLibrary) {
-      switch (node.target.name) {
-        case InternalMethod.Stringify:
-          AbstractValue argValue = getValue(node.arguments[0].definition);
-          setResult(node, lattice.stringify(argValue), canReplace: true);
-          return;
-      }
+    if (node.target == backend.helpers.stringInterpolationHelper) {
+      AbstractConstantValue argValue = getValue(node.arguments[0].definition);
+      setResult(node, lattice.stringify(argValue), canReplace: true);
+      return;
     }
 
     TypeMask returnType = typeSystem.getReturnType(node.target);
@@ -2436,73 +2479,111 @@
     // continuation. Note that this is effectively a phi node in SSA terms.
     for (int i = 0; i < node.arguments.length; i++) {
       Primitive def = node.arguments[i].definition;
-      AbstractValue cell = getValue(def);
+      AbstractConstantValue cell = getValue(def);
       setValue(cont.parameters[i], cell);
     }
   }
 
   void visitInvokeMethod(InvokeMethod node) {
-    AbstractValue receiver = getValue(node.receiver.definition);
+    AbstractConstantValue receiver = getValue(node.dartReceiver);
     node.receiverIsNotNull = receiver.isDefinitelyNotNull;
     if (receiver.isNothing) {
-      return;  // And come back later.
+      return setResult(node, lattice.nothing);
     }
+
+    void finish(AbstractConstantValue result, {bool canReplace: false}) {
+      if (result == null) {
+        canReplace = false;
+        result = lattice.getInvokeReturnType(node.selector, receiver);
+      }
+      setResult(node, result, canReplace: canReplace);
+    }
+
+    if (node.selector.isGetter) {
+      // Constant fold known length of containers.
+      if (node.selector == Selectors.length) {
+        if (typeSystem.isDefinitelyIndexable(receiver.type, allowNull: true)) {
+          AbstractConstantValue length = lattice.lengthSpecial(receiver);
+          return finish(length, canReplace: !receiver.isNullable);
+        }
+      }
+      return finish(null);
+    }
+
+    if (node.selector.isCall) {
+      if (node.selector == Selectors.codeUnitAt) {
+        AbstractConstantValue right = getValue(node.dartArgument(0));
+        AbstractConstantValue result =
+            lattice.codeUnitAtSpecial(receiver, right);
+        return finish(result, canReplace: !receiver.isNullable);
+      }
+      return finish(null);
+    }
+
+    if (node.selector == Selectors.index) {
+      AbstractConstantValue right = getValue(node.dartArgument(0));
+      AbstractConstantValue result = lattice.indexSpecial(receiver, right);
+      return finish(result, canReplace: !receiver.isNullable);
+    }
+
     if (!node.selector.isOperator) {
-      // TODO(jgruber): Handle known methods on constants such as String.length.
-      setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
-      return;
+      return finish(null);
     }
 
     // Calculate the resulting constant if possible.
-    AbstractValue result;
     String opname = node.selector.name;
     if (node.arguments.length == 1) {
-      AbstractValue argument = getValue(getDartReceiver(node));
       // Unary operator.
       if (opname == "unary-") {
         opname = "-";
       }
       UnaryOperator operator = UnaryOperator.parse(opname);
-      result = lattice.unaryOp(operator, argument);
+      AbstractConstantValue result = lattice.unaryOp(operator, receiver);
+      return finish(result, canReplace: !receiver.isNullable);
     } else if (node.arguments.length == 2) {
       // Binary operator.
-      AbstractValue left = getValue(getDartReceiver(node));
-      AbstractValue right = getValue(getDartArgument(node, 0));
+      AbstractConstantValue right = getValue(node.dartArgument(0));
       BinaryOperator operator = BinaryOperator.parse(opname);
-      result = lattice.binaryOp(operator, left, right);
+      AbstractConstantValue result =
+          lattice.binaryOp(operator, receiver, right);
+      return finish(result, canReplace: !receiver.isNullable);
     }
-
-    // Update value of the continuation parameter. Again, this is effectively
-    // a phi.
-    if (result == null) {
-      setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
-    } else {
-      setResult(node, result, canReplace: true);
-    }
+    return finish(null);
   }
 
   void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
 
-    void binaryOp(
-        AbstractValue operation(AbstractValue left, AbstractValue right),
+    void unaryOp(
+        AbstractConstantValue operation(AbstractConstantValue argument),
         TypeMask defaultType) {
-      AbstractValue left = getValue(node.arguments[0].definition);
-      AbstractValue right = getValue(node.arguments[1].definition);
+      AbstractConstantValue value = getValue(node.arguments[0].definition);
+      setValue(node, operation(value) ?? nonConstant(defaultType));
+    }
+
+    void binaryOp(
+        AbstractConstantValue operation(AbstractConstantValue left,
+                                        AbstractConstantValue right),
+        TypeMask defaultType) {
+      AbstractConstantValue left = getValue(node.arguments[0].definition);
+      AbstractConstantValue right = getValue(node.arguments[1].definition);
       setValue(node, operation(left, right) ?? nonConstant(defaultType));
     }
 
     void binaryNumOp(
-        AbstractValue operation(AbstractValue left, AbstractValue right)) {
+        AbstractConstantValue operation(AbstractConstantValue left,
+                                        AbstractConstantValue right)) {
       binaryOp(operation, typeSystem.numType);
     }
 
     void binaryUint32Op(
-        AbstractValue operation(AbstractValue left, AbstractValue right)) {
+        AbstractConstantValue operation(AbstractConstantValue left,
+                                        AbstractConstantValue right)) {
       binaryOp(operation, typeSystem.uint32Type);
     }
 
     void binaryBoolOp(
-        AbstractValue operation(AbstractValue left, AbstractValue right)) {
+        AbstractConstantValue operation(AbstractConstantValue left,
+                                        AbstractConstantValue right)) {
       binaryOp(operation, typeSystem.boolType);
     }
 
@@ -2510,8 +2591,9 @@
       case BuiltinOperator.StringConcatenate:
         ast.DartString stringValue = const ast.LiteralDartString('');
         for (Reference<Primitive> arg in node.arguments) {
-          AbstractValue value = getValue(arg.definition);
+          AbstractConstantValue value = getValue(arg.definition);
           if (value.isNothing) {
+            setValue(node, lattice.nothing);
             return; // And come back later
           } else if (value.isConstant &&
                      value.constant.isString &&
@@ -2531,16 +2613,22 @@
         }
         break;
 
+      case BuiltinOperator.CharCodeAt:
+        binaryOp(lattice.codeUnitAtSpecial, typeSystem.uint31Type);
+        break;
+
       case BuiltinOperator.Identical:
       case BuiltinOperator.StrictEq:
       case BuiltinOperator.LooseEq:
-        AbstractValue leftConst = getValue(node.arguments[0].definition);
-        AbstractValue rightConst = getValue(node.arguments[1].definition);
+        AbstractConstantValue leftConst =
+            getValue(node.arguments[0].definition);
+        AbstractConstantValue rightConst =
+            getValue(node.arguments[1].definition);
         ConstantValue leftValue = leftConst.constant;
         ConstantValue rightValue = rightConst.constant;
         if (leftConst.isNothing || rightConst.isNothing) {
-          // Come back later.
-          return;
+          setValue(node, lattice.nothing);
+          return; // And come back later.
         } else if (!leftConst.isConstant || !rightConst.isConstant) {
           TypeMask leftType = leftConst.type;
           TypeMask rightType = rightConst.type;
@@ -2624,6 +2712,14 @@
         binaryBoolOp(lattice.greaterEqualSpecial);
         break;
 
+      case BuiltinOperator.NumBitNot:
+        unaryOp(lattice.bitNotSpecial, typeSystem.uint32Type);
+        break;
+
+      case BuiltinOperator.NumNegate:
+        unaryOp(lattice.negateSpecial, typeSystem.numType);
+        break;
+
       case BuiltinOperator.StrictNeq:
       case BuiltinOperator.LooseNeq:
       case BuiltinOperator.IsFalsy:
@@ -2644,7 +2740,7 @@
   }
 
   void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    AbstractValue receiver = getValue(node.receiver.definition);
+    AbstractConstantValue receiver = getValue(node.receiver.definition);
     if (node.method == BuiltinMethod.Pop) {
       setValue(node, nonConstant(
           typeSystem.elementTypeOfIndexable(receiver.type)));
@@ -2659,7 +2755,11 @@
   }
 
   void visitInvokeConstructor(InvokeConstructor node) {
-    setResult(node, nonConstant(typeSystem.getReturnType(node.target)));
+    if (node.allocationSiteType != null) {
+      setResult(node, nonConstant(node.allocationSiteType));
+    } else {
+      setResult(node, nonConstant(typeSystem.getReturnType(node.target)));
+    }
   }
 
   void visitThrow(Throw node) {
@@ -2672,7 +2772,7 @@
   }
 
   void visitBranch(Branch node) {
-    AbstractValue conditionCell = getValue(node.condition.definition);
+    AbstractConstantValue conditionCell = getValue(node.condition.definition);
     AbstractBool boolifiedValue = node.isStrictCheck
         ? lattice.strictBoolify(conditionCell)
         : lattice.boolify(conditionCell);
@@ -2705,7 +2805,7 @@
   }
 
   void handleTypeTest(
-      Primitive node, AbstractValue input, types.DartType dartType) {
+      Primitive node, AbstractConstantValue input, types.DartType dartType) {
     TypeMask boolType = typeSystem.boolType;
     switch(lattice.isSubtypeOf(input, dartType, allowNull: false)) {
       case AbstractBool.Nothing:
@@ -2726,27 +2826,26 @@
   }
 
   void visitTypeCast(TypeCast node) {
-    Continuation cont = node.continuation.definition;
-    AbstractValue input = getValue(node.value.definition);
+    AbstractConstantValue input = getValue(node.value.definition);
     switch (lattice.isSubtypeOf(input, node.dartType, allowNull: true)) {
       case AbstractBool.Nothing:
+        setValue(node, lattice.nothing);
         break; // And come back later.
 
       case AbstractBool.True:
-        setReachable(cont);
-        setValue(cont.parameters.single, input);
+        setValue(node, input);
         break;
 
       case AbstractBool.False:
-        break; // Cast fails. Continuation should remain unreachable.
+        setValue(node, lattice.nothing); // Cast fails.
+        break;
 
       case AbstractBool.Maybe:
-        setReachable(cont);
         // Narrow type of output to those that survive the cast.
         TypeMask type = input.type.intersection(
-            typeSystem.subtypesOf(node.dartType),
+            typeSystem.subtypesOf(node.dartType).nullable(),
             classWorld);
-        setValue(cont.parameters.single, nonConstant(type));
+        setValue(node, nonConstant(type));
         break;
     }
   }
@@ -2756,9 +2855,11 @@
   }
 
   void visitLiteralList(LiteralList node) {
-    // Constant lists are translated into (Constant ListConstant(...)) IR nodes,
-    // and thus LiteralList nodes are NonConst.
-    setValue(node, nonConstant(typeSystem.extendableNativeListType));
+    if (node.allocationSiteType != null) {
+      setValue(node, nonConstant(node.allocationSiteType));
+    } else {
+      setValue(node, nonConstant(typeSystem.extendableArrayType));
+    }
   }
 
   void visitLiteralMap(LiteralMap node) {
@@ -2777,10 +2878,6 @@
     }
   }
 
-  void visitCreateFunction(CreateFunction node) {
-    throw 'CreateFunction is not used';
-  }
-
   void visitGetMutable(GetMutable node) {
     setValue(node, getValue(node.variable.definition));
   }
@@ -2815,11 +2912,11 @@
 
   void visitInterceptor(Interceptor node) {
     push(node.input.definition);
-    AbstractValue value = getValue(node.input.definition);
+    AbstractConstantValue value = getValue(node.input.definition);
     if (value.isNothing) {
       setValue(node, nothing);
     } else if (value.isNullable &&
-        !node.interceptedClasses.contains(backend.jsNullClass)) {
+        !node.interceptedClasses.contains(backend.helpers.jsNullClass)) {
       // If the input is null and null is not mapped to an interceptor then
       // null gets returned.
       // TODO(asgerf): Add the NullInterceptor when it enables us to
@@ -2831,8 +2928,21 @@
   }
 
   void visitGetField(GetField node) {
-    node.objectIsNotNull = getValue(node.object.definition).isDefinitelyNotNull;
-    setValue(node, nonConstant(typeSystem.getFieldType(node.field)));
+    AbstractConstantValue object = getValue(node.object.definition);
+    if (object.isNothing || object.isNullConstant) {
+      setValue(node, nothing);
+      return;
+    }
+    node.objectIsNotNull = object.isDefinitelyNotNull;
+    if (object.isConstant && object.constant.isConstructedObject) {
+      ConstructedConstantValue constructedConstant = object.constant;
+      ConstantValue value = constructedConstant.fields[node.field];
+      if (value != null) {
+        setValue(node, constantValue(value));
+        return;
+      }
+    }
+    setValue(node, lattice.fromMask(typeSystem.getFieldType(node.field)));
   }
 
   void visitSetField(SetField node) {}
@@ -2842,7 +2952,8 @@
   }
 
   void visitCreateInstance(CreateInstance node) {
-    setValue(node, nonConstant(typeSystem.nonNullExact(node.classElement.declaration)));
+    setValue(node,
+        nonConstant(typeSystem.nonNullExact(node.classElement.declaration)));
   }
 
   void visitReifyRuntimeType(ReifyRuntimeType node) {
@@ -2869,35 +2980,36 @@
 
   @override
   void visitForeignCode(ForeignCode node) {
-    if (node.continuation != null) {
-      setResult(node, nonConstant(node.type));
-    }
+    setValue(node, nonConstant(node.type));
   }
 
   @override
   void visitGetLength(GetLength node) {
-    AbstractValue input = getValue(node.object.definition);
-    node.objectIsNotNull = getValue(node.object.definition).isDefinitelyNotNull;
-    int length = typeSystem.getContainerLength(input.type);
+    AbstractConstantValue input = getValue(node.object.definition);
+    node.objectIsNotNull = input.isDefinitelyNotNull;
+    AbstractConstantValue length = lattice.lengthSpecial(input);
     if (length != null) {
       // TODO(asgerf): Constant-folding the length might degrade the VM's
       // own bounds-check elimination?
-      setValue(node, constantValue(new IntConstantValue(length)));
+      setValue(node, length);
     } else {
-      setValue(node, nonConstant(typeSystem.intType));
+      setValue(node, nonConstant(typeSystem.uint32Type));
     }
   }
 
   @override
   void visitGetIndex(GetIndex node) {
-    AbstractValue input = getValue(node.object.definition);
-    setValue(node, nonConstant(typeSystem.elementTypeOfIndexable(input.type)));
+    AbstractConstantValue object = getValue(node.object.definition);
+    if (object.isNothing || object.isNullConstant) {
+      setValue(node, nothing);
+    } else {
+      node.objectIsNotNull = object.isDefinitelyNotNull;
+      setValue(node, nonConstant(typeSystem.elementTypeOfIndexable(object.type)));
+    }
   }
 
   @override
-  void visitSetIndex(SetIndex node) {
-    setValue(node, nonConstant());
-  }
+  void visitSetIndex(SetIndex node) {}
 
   @override
   void visitAwait(Await node) {
@@ -2906,12 +3018,12 @@
 
   @override
   visitYield(Yield node) {
-    setReachable(node.continuation.definition);
+    setValue(node, nonConstant());
   }
 
   @override
   void visitRefinement(Refinement node) {
-    AbstractValue value = getValue(node.value.definition);
+    AbstractConstantValue value = getValue(node.value.definition);
     if (value.isNothing ||
         typeSystem.areDisjoint(value.type, node.refineType)) {
       setValue(node, nothing);
@@ -2922,6 +3034,16 @@
           nonConstant(value.type.intersection(node.refineType, classWorld)));
     }
   }
+
+  @override
+  void visitBoundsCheck(BoundsCheck node) {
+    setValue(node, getValue(node.object.definition));
+  }
+
+  @override
+  void visitNullCheck(NullCheck node) {
+    setValue(node, lattice.nonNullable(getValue(node.value.definition)));
+  }
 }
 
 /// Represents the abstract value of a primitive value at some point in the
@@ -2933,7 +3055,7 @@
 ///   CONSTANT: is a constant. The value is stored in the [constant] field,
 ///             and the type of the constant is in the [type] field.
 ///   NONCONST: not a constant, but [type] may hold some information.
-class AbstractValue {
+class AbstractConstantValue {
   static const int NOTHING  = 0;
   static const int CONSTANT = 1;
   static const int NONCONST = 2;
@@ -2942,25 +3064,26 @@
   final ConstantValue constant;
   final TypeMask type;
 
-  AbstractValue._internal(this.kind, this.constant, this.type) {
+  AbstractConstantValue._internal(this.kind, this.constant, this.type) {
     assert(kind != CONSTANT || constant != null);
     assert(constant is! SyntheticConstantValue);
   }
 
-  AbstractValue.nothing()
+  AbstractConstantValue.nothing()
       : this._internal(NOTHING, null, new TypeMask.nonNullEmpty());
 
-  AbstractValue.constantValue(ConstantValue constant, TypeMask type)
+  AbstractConstantValue.constantValue(ConstantValue constant, TypeMask type)
       : this._internal(CONSTANT, constant, type);
 
-  factory AbstractValue.nonConstant(TypeMask type) {
+  factory AbstractConstantValue.nonConstant(TypeMask type) {
     if (type.isEmpty) {
       if (type.isNullable)
-        return new AbstractValue.constantValue(new NullConstantValue(), type);
+        return new AbstractConstantValue.constantValue(
+            new NullConstantValue(), type);
       else
-        return new AbstractValue.nothing();
+        return new AbstractConstantValue.nothing();
     } else {
-      return new AbstractValue._internal(NONCONST, null, type);
+      return new AbstractConstantValue._internal(NONCONST, null, type);
     }
   }
 
@@ -2969,6 +3092,7 @@
   bool get isNonConst => (kind == NONCONST);
   bool get isNullConstant => kind == CONSTANT && constant.isNull;
   bool get isTrueConstant => kind == CONSTANT && constant.isTrue;
+  bool get isFalseConstant => kind == CONSTANT && constant.isFalse;
 
   bool get isNullable => kind != NOTHING && type.isNullable;
   bool get isDefinitelyNotNull => kind == NOTHING || !type.isNullable;
@@ -2978,7 +3102,7 @@
     return hash & 0x3fffffff;
   }
 
-  bool operator ==(AbstractValue that) {
+  bool operator ==(AbstractConstantValue that) {
     return that.kind == this.kind &&
            that.constant == this.constant &&
            that.type == this.type;
@@ -2995,16 +3119,6 @@
   }
 }
 
-/// Enum-like class with the names of internal methods we care about.
-abstract class InternalMethod {
-  static const String Stringify = 'S';
-}
-
-/// Enum-like class with the names of dart:core methods we care about.
-abstract class CorelibMethod {
-  static const String Identical = 'identical';
-}
-
 /// Suggested name for a synthesized loop index.
 class LoopIndexEntity extends Entity {
   String get name => 'i';
diff --git a/pkg/compiler/lib/src/cps_ir/update_refinements.dart b/pkg/compiler/lib/src/cps_ir/update_refinements.dart
new file mode 100644
index 0000000..d93e747
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/update_refinements.dart
@@ -0,0 +1,67 @@
+library dart2js.cps_ir.update_refinements;
+
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart' show Pass;
+import 'type_mask_system.dart';
+
+/// Updates all references to use the most refined version in scope.
+///
+/// [GVN] and [RedundantJoinElimination], and possibly other passes, can create
+/// references that don't use the best refinement in scope. This pass improves
+/// the refinement information.
+///
+//
+// TODO(asgerf): Could be done during GVN for another adjacent pass.
+//   It is easier to measure performance and rearrange passes when it has its
+//   own pass, but we can merge it with an adjacent pass later.
+//
+class UpdateRefinements extends TrampolineRecursiveVisitor implements Pass {
+  String get passName => 'Update refinements';
+
+  final TypeMaskSystem typeSystem;
+
+  Map<Primitive, Refinement> refinementFor = <Primitive, Refinement>{};
+
+  UpdateRefinements(this.typeSystem);
+
+  void rewrite(FunctionDefinition node) {
+    visit(node);
+  }
+
+  Expression traverseLetPrim(LetPrim node) {
+    visit(node.primitive);
+    return node.body;
+  }
+
+  @override
+  visitRefinement(Refinement node) {
+    if (refine(node.value)) {
+      // Update the type if the input has changed.
+      node.type = typeSystem.intersection(node.value.definition.type,
+          node.refineType);
+    }
+    Primitive value = node.effectiveDefinition;
+    Refinement old = refinementFor[value];
+    refinementFor[value] = node;
+    pushAction(() {
+      refinementFor[value] = old;
+    });
+  }
+
+  @override
+  processReference(Reference ref) {
+    refine(ref);
+  }
+
+  bool refine(Reference ref) {
+    Definition def = ref.definition;
+    if (def is Primitive) {
+      Refinement refinement = refinementFor[def.effectiveDefinition];
+      if (refinement != null && refinement != ref.definition) {
+        ref.changeTo(refinement);
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 662316b..f46ad8d 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -317,6 +317,7 @@
     new OptionHandler('--out=.+|-o.*', setOutput, multipleArguments: true),
     new OptionHandler(Flags.allowMockCompilation, passThrough),
     new OptionHandler(Flags.fastStartup, passThrough),
+    new OptionHandler(Flags.conditionalDirectives, passThrough),
     new OptionHandler('${Flags.minify}|-m', implyCompilation),
     new OptionHandler(Flags.preserveUris, passThrough),
     new OptionHandler('--force-strip=.*', setStrip),
@@ -350,7 +351,7 @@
     new OptionHandler(Flags.dumpInfo, setDumpInfo),
     new OptionHandler('--disallow-unsafe-eval',
                       (_) => hasDisallowUnsafeEval = true),
-    new OptionHandler(Flags.showPackageWarnings, passThrough),
+    new OptionHandler(Option.showPackageWarnings, passThrough),
     new OptionHandler(Flags.useContentSecurityPolicy, passThrough),
     new OptionHandler(Flags.enableExperimentalMirrors, passThrough),
     new OptionHandler(Flags.enableAssertMessage, passThrough),
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
index 5001b54..7d99b21 100644
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend.dart
@@ -42,7 +42,7 @@
 
   DartConstantTask constantCompilerTask;
 
-  DartResolutionCallbacks resolutionCallbacks;
+  DartImpactTransformer impactTransformer;
 
   final Set<ClassElement> usedTypeLiterals = new Set<ClassElement>();
 
@@ -113,7 +113,7 @@
             multiFile: multiFile,
             enableMinification: compiler.enableMinification),
         super(compiler) {
-    resolutionCallbacks = new DartResolutionCallbacks(this);
+    impactTransformer = new DartImpactTransformer(this);
   }
 
 
@@ -137,16 +137,18 @@
     }
     // Enqueue the methods that the VM might invoke on user objects because
     // we don't trust the resolution to always get these included.
-    world.registerInvocation(new UniverseSelector(Selectors.toString_, null));
-    world.registerInvokedGetter(
-        new UniverseSelector(Selectors.hashCode_, null));
-    world.registerInvocation(
-        new UniverseSelector(new Selector.binaryOperator('=='), null));
-    world.registerInvocation(
-        new UniverseSelector(Selectors.compareTo, null));
+    world.registerDynamicUse(new DynamicUse(Selectors.toString_, null));
+    world.registerDynamicUse(
+        new DynamicUse(Selectors.hashCode_, null));
+    world.registerDynamicUse(
+        new DynamicUse(new Selector.binaryOperator('=='), null));
+    world.registerDynamicUse(
+        new DynamicUse(Selectors.compareTo, null));
   }
 
-  WorldImpact codegen(CodegenWorkItem work) => const WorldImpact();
+  WorldImpact codegen(CodegenWorkItem work) {
+    return const WorldImpact();
+  }
 
   /**
    * Tells whether we should output given element. Corelib classes like
@@ -263,10 +265,7 @@
                                 Enqueuer enqueuer,
                                 Registry registry,
                                 {bool mirrorUsage: false}) {
-    registerPlatformMembers(type,
-        registerGetter: registry.registerDynamicGetter,
-        registerSetter: registry.registerDynamicSetter,
-        registerInvocation: registry.registerDynamicInvocation);
+    registerPlatformMembers(type, registerUse: registry.registerDynamicUse);
     super.registerInstantiatedType(
         type, enqueuer, registry, mirrorUsage: mirrorUsage);
   }
@@ -275,9 +274,7 @@
   /// of types defined in the platform libraries.
   void registerPlatformMembers(
       InterfaceType type,
-      {void registerGetter(UniverseSelector selector),
-       void registerSetter(UniverseSelector selector),
-       void registerInvocation(UniverseSelector selector)}) {
+      {void registerUse(DynamicUse dynamicUse)}) {
 
     // Without patching, dart2dart has no way of performing sound tree-shaking
     // in face external functions. Therefore we employ another scheme:
@@ -329,16 +326,8 @@
               FunctionElement function = element.asFunctionElement();
               element.computeType(resolution);
               Selector selector = new Selector.fromElement(element);
-              if (selector.isGetter) {
-                registerGetter(
-                    new UniverseSelector(selector, null));
-              } else if (selector.isSetter) {
-                registerSetter(
-                    new UniverseSelector(selector, null));
-              } else {
-                registerInvocation(
-                    new UniverseSelector(selector, null));
-              }
+              registerUse(
+                  new DynamicUse(selector, null));
             });
           }
         }
@@ -353,30 +342,32 @@
         node, MessageKind.DEFERRED_LIBRARY_DART_2_DART);
     return false;
   }
-}
-
-class DartResolutionCallbacks extends ResolutionCallbacks {
-  final DartBackend backend;
-
-  DartResolutionCallbacks(this.backend);
 
   @override
-  WorldImpact transformImpact(ResolutionImpact worldImpact) {
+  Uri resolvePatchUri(String libraryName, Uri) {
+    // Dart2dart does not use patches.
+    return null;
+  }
+}
+
+class DartImpactTransformer extends ImpactTransformer {
+  final DartBackend backend;
+
+  DartImpactTransformer(this.backend);
+
+  @override
+  WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
     TransformedWorldImpact transformed =
         new TransformedWorldImpact(worldImpact);
-    for (DartType typeLiteral in worldImpact.typeLiterals) {
-      if (typeLiteral.isInterfaceType) {
-        backend.usedTypeLiterals.add(typeLiteral.element);
+    for (TypeUse typeUse in worldImpact.typeUses) {
+      if (typeUse.kind == TypeUseKind.TYPE_LITERAL &&
+          typeUse.type.isInterfaceType) {
+        backend.usedTypeLiterals.add(typeUse.type.element);
       }
-    }
-    for (InterfaceType instantiatedType in worldImpact.instantiatedTypes) {
-      // TODO(johnniwinther): Remove this when dependency tracking is done on
-      // the world impact itself.
-      transformed.registerInstantiatedType(instantiatedType);
-      backend.registerPlatformMembers(instantiatedType,
-          registerGetter: transformed.registerDynamicGetter,
-          registerSetter: transformed.registerDynamicSetter,
-          registerInvocation: transformed.registerDynamicInvocation);
+      if (typeUse.kind == TypeUseKind.INSTANTIATION) {
+        backend.registerPlatformMembers(typeUse.type,
+            registerUse: transformed.registerDynamicUse);
+      }
     }
     return transformed;
   }
diff --git a/pkg/compiler/lib/src/dart_backend/dart_backend.dart b/pkg/compiler/lib/src/dart_backend/dart_backend.dart
index 57b7af5..ee653f0 100644
--- a/pkg/compiler/lib/src/dart_backend/dart_backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/dart_backend.dart
@@ -11,7 +11,8 @@
     CompilerOutputProvider;
 import '../common.dart';
 import '../common/backend_api.dart' show
-    Backend;
+    Backend,
+    ImpactTransformer;
 import '../common/codegen.dart' show
     CodegenWorkItem;
 import '../common/names.dart' show
@@ -21,9 +22,7 @@
     Registry;
 import '../common/resolution.dart' show
     Resolution,
-    ResolutionCallbacks,
-    ResolutionImpact,
-    TransformedWorldImpact;
+    ResolutionImpact;
 import '../common/tasks.dart' show
     CompilerTask;
 import '../compiler.dart' show
@@ -36,8 +35,7 @@
 import '../elements/elements.dart';
 import '../enqueue.dart' show
     Enqueuer,
-    ResolutionEnqueuer,
-    WorldImpact;
+    ResolutionEnqueuer;
 import '../library_loader.dart' show
     LoadedLibraries;
 import '../mirror_renamer/mirror_renamer.dart';
@@ -49,8 +47,13 @@
 import '../tree/tree.dart';
 import '../universe/selector.dart' show
     Selector;
-import '../universe/universe.dart' show
-    UniverseSelector;
+import '../universe/use.dart' show
+    DynamicUse,
+    TypeUse,
+    TypeUseKind;
+import '../universe/world_impact.dart' show
+    WorldImpact,
+    TransformedWorldImpact;
 import '../util/util.dart';
 import 'backend_ast_to_frontend_ast.dart' as backend2frontend;
 
diff --git a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart b/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
index 42c15f9..0a2d0e1 100644
--- a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
+++ b/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
@@ -97,7 +97,7 @@
 
   visitDynamicSend(Send node) {
     final element = elements[node];
-    if (element == null || !element.isErroneous) {
+    if (element == null || !element.isMalformed) {
       collector.tryMakeMemberPlaceholder(node.selector);
     }
   }
@@ -107,7 +107,7 @@
     // element == null means dynamic property access.
     if (element == null) {
       collector.tryMakeMemberPlaceholder(node.selector);
-    } else if (element.isErroneous) {
+    } else if (element.isMalformed) {
       collector.makeUnresolvedPlaceholder(node);
       return;
     } else if (element.isPrefix) {
@@ -489,7 +489,7 @@
     Element constructor = treeElements[send];
     assert(constructor != null);
     assert(send.receiver == null);
-    if (!Elements.isErroneous(constructor)) {
+    if (!Elements.isMalformed(constructor)) {
       tryMakeConstructorPlaceholder(node.send.selector, constructor);
       // TODO(smok): Should this be in visitNamedArgument?
       // Field names can be exposed as names of optional arguments, e.g.
@@ -530,7 +530,7 @@
 
   visitSendSet(SendSet send) {
     Element element = treeElements[send];
-    if (Elements.isErroneous(element)) {
+    if (Elements.isMalformed(element)) {
       // Complicated case: constructs like receiver.selector++ can resolve
       // to ErroneousElement.  Fortunately, receiver.selector still
       // can be resoved via treeElements[send.selector], that's all
@@ -540,7 +540,7 @@
     tryMakePrivateIdentifier(send.selector, element);
     if (element == null) {
       if (send.receiver != null) tryMakeMemberPlaceholder(send.selector);
-    } else if (!element.isErroneous) {
+    } else if (!element.isMalformed) {
       if (Elements.isStaticOrTopLevel(element)) {
         // TODO(smok): Worth investigating why sometimes we get getter/setter
         // here and sometimes abstract field.
diff --git a/pkg/compiler/lib/src/dart_backend/renamer.dart b/pkg/compiler/lib/src/dart_backend/renamer.dart
index 02f9365..6465af8 100644
--- a/pkg/compiler/lib/src/dart_backend/renamer.dart
+++ b/pkg/compiler/lib/src/dart_backend/renamer.dart
@@ -135,7 +135,7 @@
 
   String _renameGlobal(Entity entity) {
     assert(entity is! Element ||
-           Elements.isErroneous(entity) ||
+           Elements.isMalformed(entity) ||
            Elements.isStaticOrTopLevel(entity) ||
            entity is TypeVariableElement);
     // TODO(smok): We may want to reuse class static field and method names.
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 4e095df..c24ecbf 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -28,12 +28,11 @@
     FunctionElement,
     ImportElement,
     LibraryElement,
+    LocalFunctionElement,
     MetadataAnnotation,
     PrefixElement,
     ScopeContainerElement,
     TypedefElement;
-import 'enqueue.dart' show
-    WorldImpact;
 import 'js_backend/js_backend.dart' show
     JavaScriptBackend;
 import 'resolution/resolution.dart' show
@@ -49,6 +48,15 @@
     LiteralString,
     NewExpression,
     Node;
+import 'universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse,
+    TypeUseKind;
+import 'universe/world_impact.dart' show
+    ImpactUseCase,
+    WorldImpact,
+    WorldImpactVisitorImpl;
 import 'util/setlet.dart' show
     Setlet;
 import 'util/uri_extras.dart' as uri_extras;
@@ -74,7 +82,6 @@
   final bool isMainOutput;
 
   /// A unique name representing this [OutputUnit].
-  /// Based on the set of [imports].
   String name;
 
   OutputUnit({this.isMainOutput: false});
@@ -119,6 +126,8 @@
   /// Will be `true` if the program contains deferred libraries.
   bool isProgramSplit = false;
 
+  static const ImpactUseCase IMPACT_USE = const ImpactUseCase('Deferred load');
+
   /// A mapping from the name of a defer import to all the output units it
   /// depends on in a list of lists to be loaded in the order they appear.
   ///
@@ -128,7 +137,10 @@
   /// can be loaded in parallel. And finally lib1 can be loaded.
   final Map<String, List<OutputUnit>> hunksToLoad =
       new Map<String, List<OutputUnit>>();
-  final Map<_DeferredImport, String> _importDeferName =
+
+  /// A cache of the result of calling `computeImportDeferName` on the keys of
+  /// this map.
+  final Map<_DeferredImport, String> importDeferName =
       <_DeferredImport, String>{};
 
   /// A mapping from elements and constants to their output unit. Query this via
@@ -149,7 +161,7 @@
 
   /// Because the token-stream is forgotten later in the program, we cache a
   /// description of each deferred import.
-  final Map<_DeferredImport, ImportDescription>_deferredImportDescriptions =
+  final Map<_DeferredImport, ImportDescription> _deferredImportDescriptions =
       <_DeferredImport, ImportDescription>{};
 
   // For each deferred import we want to know exactly what elements have to
@@ -198,7 +210,7 @@
   /// Returns the unique name for the deferred import of [prefix].
   String getImportDeferName(Spannable node, PrefixElement prefix) {
     String name =
-        _importDeferName[new _DeclaredDeferredImport(prefix.deferredImport)];
+        importDeferName[new _DeclaredDeferredImport(prefix.deferredImport)];
     if (name == null) {
       reporter.internalError(node, "No deferred name for $prefix.");
     }
@@ -259,8 +271,8 @@
       Set<ConstantValue> constants,
       isMirrorUsage) {
 
-    if (element.isErroneous) {
-      // Erroneous elements are ignored.
+    if (element.isMalformed) {
+      // Malformed elements are ignored.
       return;
     }
 
@@ -312,24 +324,39 @@
 
         WorldImpact worldImpact =
             compiler.resolution.getWorldImpact(analyzableElement);
-        elements.addAll(worldImpact.staticUses);
-        elements.addAll(worldImpact.closures);
-        for (DartType type in worldImpact.typeLiterals) {
-          if (type.isTypedef || type.isInterfaceType) {
-            elements.add(type.element);
-          }
-        }
-        for (InterfaceType type in worldImpact.instantiatedTypes) {
-          elements.add(type.element);
-        }
+        compiler.impactStrategy.visitImpact(
+            analyzableElement,
+            worldImpact,
+            new WorldImpactVisitorImpl(
+                visitStaticUse: (StaticUse staticUse) {
+                  elements.add(staticUse.element);
+                },
+                visitTypeUse: (TypeUse typeUse) {
+                  DartType type = typeUse.type;
+                  switch (typeUse.kind) {
+                    case TypeUseKind.TYPE_LITERAL:
+                      if (type.isTypedef || type.isInterfaceType) {
+                        elements.add(type.element);
+                      }
+                      break;
+                    case TypeUseKind.INSTANTIATION:
+                    case TypeUseKind.IS_CHECK:
+                    case TypeUseKind.AS_CAST:
+                    case TypeUseKind.CATCH_TYPE:
+                      collectTypeDependencies(type);
+                      break;
+                    case TypeUseKind.CHECKED_MODE_CHECK:
+                      if (compiler.enableTypeAssertions) {
+                        collectTypeDependencies(type);
+                      }
+                      break;
+                  }
+                }),
+             IMPACT_USE);
 
         TreeElements treeElements = analyzableElement.resolvedAst.elements;
         assert(treeElements != null);
 
-        for (DartType type in treeElements.requiredTypes) {
-          collectTypeDependencies(type);
-        }
-
         treeElements.forEachConstantNode((Node node, _) {
           // Explicitly depend on the backend constants.
           ConstantValue value =
@@ -557,7 +584,7 @@
     void computeImportDeferName(_DeferredImport import) {
       String result = import.computeImportDeferName(compiler);
       assert(result != null);
-      _importDeferName[import] = makeUnique(result, usedImportNames);
+      importDeferName[import] = makeUnique(result, usedImportNames);
     }
 
     int counter = 1;
@@ -579,25 +606,25 @@
     // Sort the output units in descending order of the number of imports they
     // include.
 
-    // The loading of the output units mut be ordered because a superclass needs
-    // to be initialized before its subclass.
+    // The loading of the output units must be ordered because a superclass
+    // needs to be initialized before its subclass.
     // But a class can only depend on another class in an output unit shared by
     // a strict superset of the imports:
     // By contradiction: Assume a class C in output unit shared by imports in
     // the set S1 = (lib1,.., lib_n) depends on a class D in an output unit
     // shared by S2 such that S2 not a superset of S1. Let lib_s be a library in
-    // S1 not in S2. lib_s must depend on C, and then in turn on D therefore D
+    // S1 not in S2. lib_s must depend on C, and then in turn on D. Therefore D
     // is not in the right output unit.
     sortedOutputUnits.sort((a, b) => b.imports.length - a.imports.length);
 
     // For each deferred import we find out which outputUnits to load.
     for (_DeferredImport import in _allDeferredImports.keys) {
       if (import == _fakeMainImport) continue;
-      hunksToLoad[_importDeferName[import]] = new List<OutputUnit>();
+      hunksToLoad[importDeferName[import]] = new List<OutputUnit>();
       for (OutputUnit outputUnit in sortedOutputUnits) {
         if (outputUnit == mainOutputUnit) continue;
         if (outputUnit.imports.contains(import)) {
-          hunksToLoad[_importDeferName[import]].add(outputUnit);
+          hunksToLoad[importDeferName[import]].add(outputUnit);
         }
       }
     }
@@ -620,7 +647,7 @@
       _mapDependencies(element: compiler.mainFunction, import: _fakeMainImport);
 
       // Also add "global" dependencies to the main OutputUnit.  These are
-      // things that the backend need but cannot associate with a particular
+      // things that the backend needs but cannot associate with a particular
       // element, for example, startRootIsolate.  This set also contains
       // elements for which we lack precise information.
       for (Element element in compiler.globalDependencies.otherDependencies) {
@@ -695,6 +722,9 @@
       // Generate a unique name for each OutputUnit.
       _assignNamesToOutputUnits(allOutputUnits);
     });
+    // Notify the impact strategy impacts are no longer needed for deferred
+    // load.
+    compiler.impactStrategy.onImpactUsed(IMPACT_USE);
   }
 
   void beforeResolution(Compiler compiler) {
@@ -850,8 +880,8 @@
   /// Where
   ///
   /// - <library uri> is the relative uri of the library making a deferred
-  ///   import
-  /// - <library name> is the name of the libary, and "<unnamed>" if it is
+  ///   import.
+  /// - <library name> is the name of the library, and "<unnamed>" if it is
   ///   unnamed.
   /// - <prefix> is the `as` prefix used for a given deferred import.
   /// - <list of files> is a list of the filenames the must be loaded when that
@@ -861,14 +891,14 @@
     Map<String, Map<String, dynamic>> mapping =
         new Map<String, Map<String, dynamic>>();
     _deferredImportDescriptions.keys.forEach((_DeferredImport import) {
-      List<OutputUnit> outputUnits = hunksToLoad[_importDeferName[import]];
+      List<OutputUnit> outputUnits = hunksToLoad[importDeferName[import]];
       ImportDescription description = _deferredImportDescriptions[import];
       Map<String, dynamic> libraryMap =
           mapping.putIfAbsent(description.importingUri,
               () => <String, dynamic>{"name": description.importingLibraryName,
                                       "imports": <String, List<String>>{}});
 
-      libraryMap["imports"][description.prefix] = outputUnits.map(
+      libraryMap["imports"][importDeferName[import]] = outputUnits.map(
             (OutputUnit outputUnit) {
           return backend.deferredPartFileName(outputUnit.name);
         }).toList();
diff --git a/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart b/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
new file mode 100644
index 0000000..90d4ecf
--- /dev/null
+++ b/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
@@ -0,0 +1,3732 @@
+// 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.
+
+// The messages in this file should meet the following guide lines:
+//
+// 1. The message should be a complete sentence starting with an uppercase
+// letter, and ending with a period.
+//
+// 2. Reserved words and embedded identifiers should be in single quotes, so
+// prefer double quotes for the complete message. For example, "The
+// class '#{className}' can't use 'super'." Notice that the word 'class' in the
+// preceding message is not quoted as it refers to the concept 'class', not the
+// reserved word. On the other hand, 'super' refers to the reserved word. Do
+// not quote 'null' and numeric literals.
+//
+// 3. Do not try to compose messages, as it can make translating them hard.
+//
+// 4. Try to keep the error messages short, but informative.
+//
+// 5. Use simple words and terminology, assume the reader of the message
+// doesn't have an advanced degree in math, and that English is not the
+// reader's native language. Do not assume any formal computer science
+// training. For example, do not use Latin abbreviations (prefer "that is" over
+// "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
+// only if" and "iff", that level of precision is unnecessary.
+//
+// 6. Prefer contractions when they are in common use, for example, prefer
+// "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
+// off-putting to people new to programming.
+//
+// 7. Use common terminology, preferably from the Dart Language
+// Specification. This increases the user's chance of finding a good
+// explanation on the web.
+//
+// 8. Do not try to be cute or funny. It is extremely frustrating to work on a
+// product that crashes with a "tongue-in-cheek" message, especially if you did
+// not want to use this product to begin with.
+//
+// 9. Do not lie, that is, do not write error messages containing phrases like
+// "can't happen".  If the user ever saw this message, it would be a
+// lie. Prefer messages like: "Internal error: This function should not be
+// called when 'x' is null.".
+//
+// 10. Prefer to not use imperative tone. That is, the message should not sound
+// accusing or like it is ordering the user around. The computer should
+// describe the problem, not criticize for violating the specification.
+//
+// Other things to keep in mind:
+//
+// An INFO message should always be preceded by a non-INFO message, and the
+// INFO messages are additional details about the preceding non-INFO
+// message. For example, consider duplicated elements. First report a WARNING
+// or ERROR about the duplicated element, and then report an INFO about the
+// location of the existing element.
+//
+// Generally, we want to provide messages that consists of three sentences:
+// 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
+// combine the first two in [template] and the last in [howToFix].
+
+/// Padding used before and between import chains in the message for
+/// [MessageKind.IMPORT_EXPERIMENTAL_MIRRORS].
+const String IMPORT_EXPERIMENTAL_MIRRORS_PADDING = '\n*   ';
+
+/// Padding used before and between import chains in the message for
+/// [MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND].
+const String MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING = '\n   ';
+
+/// Padding used before and between import chains in the message for
+/// [MessageKind.DISALLOWED_LIBRARY_IMPORT].
+const String DISALLOWED_LIBRARY_IMPORT_PADDING = '\n  ';
+
+const DONT_KNOW_HOW_TO_FIX = "Computer says no!";
+
+final Map<String, Map> MESSAGES = {
+  /// Do not use this. It is here for legacy and debugging. It violates item
+  /// 4 of the guide lines for error messages in the beginning of the file.
+  'GENERIC': {'id': 'SOWPSL', 'template': "#{text}",},
+
+  'NOT_ASSIGNABLE': {
+    'id': 'VYNMAP',
+    'template': "'#{fromType}' is not assignable to '#{toType}'.",
+  },
+
+  'FORIN_NOT_ASSIGNABLE': {
+    'id': 'XQSRXO',
+    'template': "The element type '#{currentType}' of '#{expressionType}' "
+        "is not assignable to '#{elementType}'.",
+  },
+
+  'VOID_EXPRESSION': {
+    'id': 'QHEVSC',
+    'template': "Expression does not yield a value.",
+  },
+
+  'VOID_VARIABLE': {
+    'id': 'RFEURK',
+    'template': "Variable cannot be of type void.",
+  },
+
+  'RETURN_VALUE_IN_VOID': {
+    'id': 'FUNYDS',
+    'template': "Cannot return value from void function.",
+  },
+
+  'RETURN_NOTHING': {
+    'id': 'HPPODJ',
+    'template': "Value of type '#{returnType}' expected.",
+  },
+
+  'MISSING_ARGUMENT': {
+    'id': 'LHMCIK',
+    'template': "Missing argument of type '#{argumentType}'.",
+  },
+
+  'ADDITIONAL_ARGUMENT': {'id': 'GMITMA', 'template': "Additional argument.",},
+
+  'NAMED_ARGUMENT_NOT_FOUND': {
+    'id': 'UCEARQ',
+    'template': "No named argument '#{argumentName}' found on method.",
+  },
+
+  'MEMBER_NOT_FOUND': {
+    'id': 'MMQODC',
+    'template': "No member named '#{memberName}' in class '#{className}'.",
+  },
+
+  'AWAIT_MEMBER_NOT_FOUND': {
+    'id': 'XIDLIP',
+    'template': "No member named 'await' in class '#{className}'.",
+    'howToFix': "Did you mean to add the 'async' marker "
+        "to '#{functionName}'?",
+    'examples': [
+      """
+class A {
+m() => await -3;
+}
+main() => new A().m();
+"""
+    ],
+  },
+
+  'AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE': {
+    'id': 'HBIYGN',
+    'template': "No member named 'await' in class '#{className}'.",
+    'howToFix': "Did you mean to add the 'async' marker "
+        "to the enclosing function?",
+    'examples': [
+      """
+class A {
+m() => () => await -3;
+}
+main() => new A().m();
+"""
+    ],
+  },
+
+  'METHOD_NOT_FOUND': {
+    'id': 'QYYHBU',
+    'template': "No method named '#{memberName}' in class '#{className}'.",
+  },
+
+  'OPERATOR_NOT_FOUND': {
+    'id': 'SXGOYS',
+    'template': "No operator '#{memberName}' in class '#{className}'.",
+  },
+
+  'SETTER_NOT_FOUND': {
+    'id': 'ADFRVF',
+    'template': "No setter named '#{memberName}' in class '#{className}'.",
+  },
+
+  'SETTER_NOT_FOUND_IN_SUPER': {
+    'id': 'OCVRNJ',
+    'template': "No setter named '#{name}' in superclass of '#{className}'.",
+  },
+
+  'GETTER_NOT_FOUND': {
+    'id': 'PBNXAC',
+    'template': "No getter named '#{memberName}' in class '#{className}'.",
+  },
+
+  'NOT_CALLABLE': {
+    'id': 'SEMKJO',
+    'template': "'#{elementName}' is not callable.",
+  },
+
+  'MEMBER_NOT_STATIC': {
+    'id': 'QIOISX',
+    'template': "'#{className}.#{memberName}' is not static.",
+  },
+
+  'NO_INSTANCE_AVAILABLE': {
+    'id': 'FQPYLR',
+    'template': "'#{name}' is only available in instance methods.",
+  },
+
+  'NO_THIS_AVAILABLE': {
+    'id': 'LXPXKG',
+    'template': "'this' is only available in instance methods.",
+  },
+
+  'PRIVATE_ACCESS': {
+    'id': 'DIMHCR',
+    'template': "'#{name}' is declared private within library "
+        "'#{libraryName}'.",
+  },
+
+  'THIS_IS_THE_DECLARATION': {
+    'id': 'YIJWTO',
+    'template': "This is the declaration of '#{name}'.",
+  },
+
+  'THIS_IS_THE_METHOD': {
+    'id': 'PYXWLF',
+    'template': "This is the method declaration.",
+  },
+
+  'CANNOT_RESOLVE': {'id': 'SPVJYO', 'template': "Cannot resolve '#{name}'.",},
+
+  'CANNOT_RESOLVE_AWAIT': {
+    'id': 'YQYLRS',
+    'template': "Cannot resolve '#{name}'.",
+    'howToFix': "Did you mean to add the 'async' marker "
+        "to '#{functionName}'?",
+    'examples': ["main() => await -3;", "foo() => await -3; main() => foo();"],
+  },
+
+  'CANNOT_RESOLVE_AWAIT_IN_CLOSURE': {
+    'id': 'SIXRAA',
+    'template': "Cannot resolve '#{name}'.",
+    'howToFix': "Did you mean to add the 'async' marker "
+        "to the enclosing function?",
+    'examples': ["main() { (() => await -3)(); }",],
+  },
+
+  'CANNOT_RESOLVE_IN_INITIALIZER': {
+    'id': 'VVEQFD',
+    'template':
+        "Cannot resolve '#{name}'. It would be implicitly looked up on this "
+        "instance, but instances are not available in initializers.",
+    'howToFix': "Try correcting the unresolved reference or move the "
+        "initialization to a constructor body.",
+    'examples': [
+      """
+class A {
+var test = unresolvedName;
+}
+main() => new A();
+"""
+    ],
+  },
+
+  'CANNOT_RESOLVE_CONSTRUCTOR': {
+    'id': 'QRPATN',
+    'template': "Cannot resolve constructor '#{constructorName}'.",
+  },
+
+  'CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT': {
+    'id': 'IFKCHF',
+    'template': "cannot resolve constructor '#{constructorName}' "
+        "for implicit super call.",
+    'howToFix': "Try explicitly invoking a constructor of the super class",
+    'examples': [
+      """
+class A {
+A.foo() {}
+}
+class B extends A {
+B();
+}
+main() => new B();
+"""
+    ],
+  },
+
+  'INVALID_UNNAMED_CONSTRUCTOR_NAME': {
+    'id': 'VPJLVI',
+    'template': "Unnamed constructor name must be '#{name}'.",
+  },
+
+  'INVALID_CONSTRUCTOR_NAME': {
+    'id': 'LMDCAS',
+    'template': "Constructor name must start with '#{name}'.",
+  },
+
+  'CANNOT_RESOLVE_TYPE': {
+    'id': 'PQIAPG',
+    'template': "Cannot resolve type '#{typeName}'.",
+  },
+
+  'DUPLICATE_DEFINITION': {
+    'id': 'LVTYNW',
+    'template': "Duplicate definition of '#{name}'.",
+    'howToFix': "Try to rename or remove this definition.",
+    'examples': [
+      """
+class C {
+void f() {}
+int get f => 1;
+}
+
+main() {
+new C();
+}
+
+"""
+    ],
+  },
+
+  'EXISTING_DEFINITION': {
+    'id': 'DAUYKK',
+    'template': "Existing definition of '#{name}'.",
+  },
+
+  'DUPLICATE_IMPORT': {
+    'id': 'KYJFJN',
+    'template': "Duplicate import of '#{name}'.",
+  },
+
+  'HIDDEN_IMPORT': {
+    'id': 'ACRDPR',
+    'template': "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+        "from library '#{hidingUri}'.",
+    'howToFix': "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
+    'examples': [
+      {
+        'main.dart': """
+import 'dart:async'; // This imports a class Future.
+import 'future.dart';
+
+void main() => new Future();""",
+        'future.dart': """
+library future;
+
+class Future {}"""
+      },
+      {
+        'main.dart': """
+import 'future.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() => new Future();""",
+        'future.dart': """
+library future;
+
+class Future {}"""
+      },
+      {
+        'main.dart': """
+import 'export.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() => new Future();""",
+        'future.dart': """
+library future;
+
+class Future {}""",
+        'export.dart': """
+library export;
+
+export 'future.dart';"""
+      },
+      {
+        'main.dart': """
+import 'future.dart' as prefix;
+import 'dart:async' as prefix; // This imports a class Future.
+
+void main() => new prefix.Future();""",
+        'future.dart': """
+library future;
+
+class Future {}"""
+      }
+    ],
+  },
+
+  'HIDDEN_IMPLICIT_IMPORT': {
+    'id': 'WDNFSI',
+    'template': "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+        "from library '#{hidingUri}'.",
+    'howToFix': "Try adding an explicit "
+        "'import \"#{hiddenUri}\" hide #{name}'.",
+    'examples': [
+      {
+        'main.dart': """
+// This hides the implicit import of class Type from dart:core.
+import 'type.dart';
+
+void main() => new Type();""",
+        'type.dart': """
+library type;
+
+class Type {}"""
+      },
+      {
+        'conflictsWithDart.dart': """
+library conflictsWithDart;
+
+class Duration {
+static var x = 100;
+}
+""",
+        'conflictsWithDartAsWell.dart': """
+library conflictsWithDartAsWell;
+
+class Duration {
+static var x = 100;
+}
+""",
+        'main.dart': r"""
+library testDartConflicts;
+
+import 'conflictsWithDart.dart';
+import 'conflictsWithDartAsWell.dart';
+
+main() {
+print("Hail Caesar ${Duration.x}");
+}
+"""
+      }
+    ],
+  },
+
+  'DUPLICATE_EXPORT': {
+    'id': 'XGNOCL',
+    'template': "Duplicate export of '#{name}'.",
+    'howToFix': "Try adding 'hide #{name}' to one of the exports.",
+    'examples': [
+      {
+        'main.dart': """
+export 'decl1.dart';
+export 'decl2.dart';
+
+main() {}""",
+        'decl1.dart': "class Class {}",
+        'decl2.dart': "class Class {}"
+      }
+    ],
+  },
+
+  'DUPLICATE_EXPORT_CONT': {
+    'id': 'BDROED',
+    'template': "This is another export of '#{name}'.",
+  },
+
+  'DUPLICATE_EXPORT_DECL': {
+    'id': 'GFFLMA',
+    'template':
+        "The exported '#{name}' from export #{uriString} is defined here.",
+  },
+
+  'EMPTY_HIDE': {
+    'id': 'ODFAOC',
+    'template': "Library '#{uri}' doesn't export a '#{name}' declaration.",
+    'howToFix': "Try removing '#{name}' the 'hide' clause.",
+    'examples': [
+      {
+        'main.dart': """
+import 'dart:core' hide Foo;
+
+main() {}"""
+      },
+      {
+        'main.dart': """
+export 'dart:core' hide Foo;
+
+main() {}"""
+      },
+    ],
+  },
+
+  'EMPTY_SHOW': {
+    'id': 'EXONIK',
+    'template': "Library '#{uri}' doesn't export a '#{name}' declaration.",
+    'howToFix': "Try removing '#{name}' from the 'show' clause.",
+    'examples': [
+      {
+        'main.dart': """
+import 'dart:core' show Foo;
+
+main() {}"""
+      },
+      {
+        'main.dart': """
+export 'dart:core' show Foo;
+
+main() {}"""
+      },
+    ],
+  },
+
+  'NOT_A_TYPE': {'id': 'CTTAXD', 'template': "'#{node}' is not a type.",},
+
+  'NOT_A_PREFIX': {'id': 'LKEUMI', 'template': "'#{node}' is not a prefix.",},
+
+  'PREFIX_AS_EXPRESSION': {
+    'id': 'CYIMBJ',
+    'template': "Library prefix '#{prefix}' is not a valid expression.",
+  },
+
+  'CANNOT_FIND_CONSTRUCTOR': {
+    'id': 'DROVNH',
+    'template': "Cannot find constructor '#{constructorName}' in class "
+        "'#{className}'.",
+  },
+
+  'CANNOT_FIND_UNNAMED_CONSTRUCTOR': {
+    'id': 'GDCTGB',
+    'template': "Cannot find unnamed constructor in class "
+        "'#{className}'.",
+  },
+
+  'CYCLIC_CLASS_HIERARCHY': {
+    'id': 'HKFYOA',
+    'template': "'#{className}' creates a cycle in the class hierarchy.",
+  },
+
+  'CYCLIC_REDIRECTING_FACTORY': {
+    'id': 'QGETJC',
+    'template': "Redirecting factory leads to a cyclic redirection.",
+  },
+
+  'INVALID_RECEIVER_IN_INITIALIZER': {
+    'id': 'SYUTHA',
+    'template': "Field initializer expected.",
+  },
+
+  'NO_SUPER_IN_STATIC': {
+    'id': 'HSCESG',
+    'template': "'super' is only available in instance methods.",
+  },
+
+  'DUPLICATE_INITIALIZER': {
+    'id': 'GKVFEP',
+    'template': "Field '#{fieldName}' is initialized more than once.",
+  },
+
+  'ALREADY_INITIALIZED': {
+    'id': 'NCRMVD',
+    'template': "'#{fieldName}' was already initialized here.",
+  },
+
+  'INIT_STATIC_FIELD': {
+    'id': 'DBSRHA',
+    'template': "Cannot initialize static field '#{fieldName}'.",
+  },
+
+  'NOT_A_FIELD': {
+    'id': 'FYEPLC',
+    'template': "'#{fieldName}' is not a field.",
+  },
+
+  'CONSTRUCTOR_CALL_EXPECTED': {
+    'id': 'GEJCDX',
+    'template': "only call to 'this' or 'super' constructor allowed.",
+  },
+
+  'INVALID_FOR_IN': {
+    'id': 'AUQJBG',
+    'template': "Invalid for-in variable declaration.",
+  },
+
+  'INVALID_INITIALIZER': {'id': 'JKUKSA', 'template': "Invalid initializer.",},
+
+  'FUNCTION_WITH_INITIALIZER': {
+    'id': 'BNRDDK',
+    'template': "Only constructors can have initializers.",
+  },
+
+  'REDIRECTING_CONSTRUCTOR_CYCLE': {
+    'id': 'CQTMEP',
+    'template': "Cyclic constructor redirection.",
+  },
+
+  'REDIRECTING_CONSTRUCTOR_HAS_BODY': {
+    'id': 'WXJQNE',
+    'template': "Redirecting constructor can't have a body.",
+  },
+
+  'CONST_CONSTRUCTOR_HAS_BODY': {
+    'id': 'GNEFQG',
+    'template': "Const constructor or factory can't have a body.",
+    'howToFix': "Remove the 'const' keyword or the body",
+    'examples': [
+      """
+class C {
+const C() {}
+}
+
+main() => new C();"""
+    ],
+  },
+
+  'REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER': {
+    'id': 'NUIDSF',
+    'template': "Redirecting constructor cannot have other initializers.",
+  },
+
+  'SUPER_INITIALIZER_IN_OBJECT': {
+    'id': 'DXYGND',
+    'template': "'Object' cannot have a super initializer.",
+  },
+
+  'DUPLICATE_SUPER_INITIALIZER': {
+    'id': 'FFKOWP',
+    'template': "Cannot have more than one super initializer.",
+  },
+
+  'SUPER_CALL_TO_FACTORY': {
+    'id': 'YTOWGV',
+    'template': "The target of the superinitializer must be a generative "
+        "constructor.",
+    'howToFix': "Try calling another constructor on the superclass.",
+    'examples': [
+      """
+class Super {
+factory Super() => null;
+}
+class Class extends Super {}
+main() => new Class();
+""",
+      """
+class Super {
+factory Super() => null;
+}
+class Class extends Super {
+Class();
+}
+main() => new Class();
+""",
+      """
+class Super {
+factory Super() => null;
+}
+class Class extends Super {
+Class() : super();
+}
+main() => new Class();
+""",
+      """
+class Super {
+factory Super.foo() => null;
+}
+class Class extends Super {
+Class() : super.foo();
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'THIS_CALL_TO_FACTORY': {
+    'id': 'JLATDB',
+    'template': "The target of the redirection clause must be a generative "
+        "constructor",
+    'howToFix': "Try redirecting to another constructor.",
+    'examples': [
+      """
+class Class {
+factory Class() => null;
+Class.foo() : this();
+}
+main() => new Class.foo();
+""",
+      """
+class Class {
+factory Class.foo() => null;
+Class() : this.foo();
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'INVALID_CONSTRUCTOR_ARGUMENTS': {
+    'id': 'WVPLKL',
+    'template': "Arguments do not match the expected parameters of constructor "
+        "'#{constructorName}'.",
+  },
+
+  'NO_MATCHING_CONSTRUCTOR': {
+    'id': 'OJQQLE',
+    'template':
+        "'super' call arguments and constructor parameters do not match.",
+  },
+
+  'NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT': {
+    'id': 'WHCVID',
+    'template': "Implicit 'super' call arguments and constructor parameters "
+        "do not match.",
+  },
+
+  'CONST_CALLS_NON_CONST': {
+    'id': 'CQFHXC',
+    'template': "'const' constructor cannot call a non-const constructor.",
+  },
+
+  'CONST_CALLS_NON_CONST_FOR_IMPLICIT': {
+    'id': 'SFCEXS',
+    'template': "'const' constructor cannot call a non-const constructor. "
+        "This constructor has an implicit call to a "
+        "super non-const constructor.",
+    'howToFix': "Try making the super constructor const.",
+    'examples': [
+      """
+class C {
+C(); // missing const
+}
+class D extends C {
+final d;
+const D(this.d);
+}
+main() => new D(0);"""
+    ],
+  },
+
+  'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS': {
+    'id': 'XBHUDL',
+    'template': "Can't declare constructor 'const' on class #{className} "
+        "because the class contains non-final instance fields.",
+    'howToFix': "Try making all fields final.",
+    'examples': [
+      """
+class C {
+// 'a' must be declared final to allow for the const constructor.
+var a;
+const C(this.a);
+}
+
+main() => new C(0);"""
+    ],
+  },
+
+  'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD': {
+    'id': 'YYAHVD',
+    'template': "This non-final field prevents using const constructors.",
+  },
+
+  'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR': {
+    'id': 'FROWJB',
+    'template': "This const constructor is not allowed due to "
+        "non-final fields.",
+  },
+
+  'INITIALIZING_FORMAL_NOT_ALLOWED': {
+    'id': 'YIPXYP',
+    'template': "Initializing formal parameter only allowed in generative "
+        "constructor.",
+  },
+
+  'INVALID_PARAMETER': {
+    'id': 'OWWLIX',
+    'template': "Cannot resolve parameter.",
+  },
+
+  'NOT_INSTANCE_FIELD': {
+    'id': 'VSPKMU',
+    'template': "'#{fieldName}' is not an instance field.",
+  },
+
+  'THIS_PROPERTY': {'id': 'MWFIGH', 'template': "Expected an identifier.",},
+
+  'NO_CATCH_NOR_FINALLY': {
+    'id': 'OPJXPP',
+    'template': "Expected 'catch' or 'finally'.",
+  },
+
+  'EMPTY_CATCH_DECLARATION': {
+    'id': 'UNHCPY',
+    'template': "Expected an identifier in catch declaration.",
+  },
+
+  'EXTRA_CATCH_DECLARATION': {
+    'id': 'YGGRAK',
+    'template': "Extra parameter in catch declaration.",
+  },
+
+  'PARAMETER_WITH_TYPE_IN_CATCH': {
+    'id': 'EXQVDU',
+    'template': "Cannot use type annotations in catch.",
+  },
+
+  'PARAMETER_WITH_MODIFIER_IN_CATCH': {
+    'id': 'BQLKRF',
+    'template': "Cannot use modifiers in catch.",
+  },
+
+  'OPTIONAL_PARAMETER_IN_CATCH': {
+    'id': 'DAICPP',
+    'template': "Cannot use optional parameters in catch.",
+  },
+
+  'THROW_WITHOUT_EXPRESSION': {
+    'id': 'YHACYV',
+    'template': "Cannot use re-throw outside of catch block "
+        "(expression expected after 'throw').",
+  },
+
+  'UNBOUND_LABEL': {
+    'id': 'GLDXHY',
+    'template': "Cannot resolve label '#{labelName}'.",
+  },
+
+  'NO_BREAK_TARGET': {
+    'id': 'VBXXBE',
+    'template': "'break' statement not inside switch or loop.",
+  },
+
+  'NO_CONTINUE_TARGET': {
+    'id': 'JTTHHM',
+    'template': "'continue' statement not inside loop.",
+  },
+
+  'EXISTING_LABEL': {
+    'id': 'AHCSXF',
+    'template': "Original declaration of duplicate label '#{labelName}'.",
+  },
+
+  'DUPLICATE_LABEL': {
+    'id': 'HPULLI',
+    'template': "Duplicate declaration of label '#{labelName}'.",
+  },
+
+  'UNUSED_LABEL': {'id': 'KFREJO', 'template': "Unused label '#{labelName}'.",},
+
+  'INVALID_CONTINUE': {
+    'id': 'DSKTPX',
+    'template': "Target of continue is not a loop or switch case.",
+  },
+
+  'INVALID_BREAK': {
+    'id': 'MFCCWX',
+    'template': "Target of break is not a statement.",
+  },
+
+  'DUPLICATE_TYPE_VARIABLE_NAME': {
+    'id': 'BAYCCM',
+    'template': "Type variable '#{typeVariableName}' already declared.",
+  },
+
+  'TYPE_VARIABLE_WITHIN_STATIC_MEMBER': {
+    'id': 'XQLXRL',
+    'template': "Cannot refer to type variable '#{typeVariableName}' "
+        "within a static member.",
+  },
+
+  'TYPE_VARIABLE_IN_CONSTANT': {
+    'id': 'ANDEVG',
+    'template': "Constant expressions can't refer to type variables.",
+    'howToFix': "Try removing the type variable or replacing it with a "
+        "concrete type.",
+    'examples': [
+      """
+class C<T> {
+const C();
+
+m(T t) => const C<T>();
+}
+
+void main() => new C().m(null);
+"""
+    ],
+  },
+
+  'INVALID_TYPE_VARIABLE_BOUND': {
+    'id': 'WQAEDK',
+    'template': "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
+        "type variable '#{typeVariable}' of type '#{thisType}'.",
+    'howToFix': "Try to change or remove the type argument.",
+    'examples': [
+      """
+class C<T extends num> {}
+
+// 'String' is not a valid instantiation of T with bound num.'.
+main() => new C<String>();
+"""
+    ],
+  },
+
+  'INVALID_USE_OF_SUPER': {
+    'id': 'JKYYSN',
+    'template': "'super' not allowed here.",
+  },
+
+  'INVALID_CASE_DEFAULT': {
+    'id': 'ABSPBM',
+    'template': "'default' only allowed on last case of a switch.",
+  },
+
+  'SWITCH_CASE_TYPES_NOT_EQUAL': {
+    'id': 'UFQPBC',
+    'template': "'case' expressions do not all have type '#{type}'.",
+  },
+
+  'SWITCH_CASE_TYPES_NOT_EQUAL_CASE': {
+    'id': 'RDMVAC',
+    'template': "'case' expression of type '#{type}'.",
+  },
+
+  'SWITCH_CASE_FORBIDDEN': {
+    'id': 'UHSCSU',
+    'template': "'case' expression may not be of type '#{type}'.",
+  },
+
+  'SWITCH_CASE_VALUE_OVERRIDES_EQUALS': {
+    'id': 'NRTWXL',
+    'template': "'case' expression type '#{type}' overrides 'operator =='.",
+  },
+
+  'INVALID_ARGUMENT_AFTER_NAMED': {
+    'id': 'WAJURC',
+    'template': "Unnamed argument after named argument.",
+  },
+
+  'NOT_A_COMPILE_TIME_CONSTANT': {
+    'id': 'SBCHWL',
+    'template': "Not a compile-time constant.",
+  },
+
+  'DEFERRED_COMPILE_TIME_CONSTANT': {
+    'id': 'FHXTCK',
+    'template': "A deferred value cannot be used as a compile-time constant.",
+  },
+
+  'DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION': {
+    'id': 'TSBXLG',
+    'template': "A deferred class cannot be used to create a "
+        "compile-time constant.",
+  },
+
+  'CYCLIC_COMPILE_TIME_CONSTANTS': {
+    'id': 'JJWJYE',
+    'template': "Cycle in the compile-time constant computation.",
+  },
+
+  'CONSTRUCTOR_IS_NOT_CONST': {
+    'id': 'DOJCUX',
+    'template': "Constructor is not a 'const' constructor.",
+  },
+
+  'CONST_MAP_KEY_OVERRIDES_EQUALS': {
+    'id': 'VJNWEL',
+    'template': "Const-map key type '#{type}' overrides 'operator =='.",
+  },
+
+  'NO_SUCH_LIBRARY_MEMBER': {
+    'id': 'IOXVBA',
+    'template': "'#{libraryName}' has no member named '#{memberName}'.",
+  },
+
+  'CANNOT_INSTANTIATE_TYPEDEF': {
+    'id': 'KOYNMU',
+    'template': "Cannot instantiate typedef '#{typedefName}'.",
+  },
+
+  'REQUIRED_PARAMETER_WITH_DEFAULT': {
+    'id': 'CJWECI',
+    'template': "Non-optional parameters can't have a default value.",
+    'howToFix':
+        "Try removing the default value or making the parameter optional.",
+    'examples': [
+      """
+main() {
+foo(a: 1) => print(a);
+foo(2);
+}""",
+      """
+main() {
+foo(a = 1) => print(a);
+foo(2);
+}"""
+    ],
+  },
+
+  'NAMED_PARAMETER_WITH_EQUALS': {
+    'id': 'RPJDXD',
+    'template': "Named optional parameters can't use '=' to specify a default "
+        "value.",
+    'howToFix': "Try replacing '=' with ':'.",
+    'examples': [
+      """
+main() {
+foo({a = 1}) => print(a);
+foo(a: 2);
+}"""
+    ],
+  },
+
+  'POSITIONAL_PARAMETER_WITH_EQUALS': {
+    'id': 'JMSSDX',
+    'template': "Positional optional parameters can't use ':' to specify a "
+        "default value.",
+    'howToFix': "Try replacing ':' with '='.",
+    'examples': [
+      """
+main() {
+foo([a: 1]) => print(a);
+foo(2);
+}"""
+    ],
+  },
+
+  'TYPEDEF_FORMAL_WITH_DEFAULT': {
+    'id': 'NABHHS',
+    'template': "A parameter of a typedef can't specify a default value.",
+    'howToFix': "Try removing the default value.",
+    'examples': [
+      """
+typedef void F([int arg = 0]);
+
+main() {
+F f;
+}""",
+      """
+typedef void F({int arg: 0});
+
+main() {
+F f;
+}"""
+    ],
+  },
+
+  'FUNCTION_TYPE_FORMAL_WITH_DEFAULT': {
+    'id': 'APKYLU',
+    'template': "A function type parameter can't specify a default value.",
+    'howToFix': "Try removing the default value.",
+    'examples': [
+      """
+foo(f(int i, [a = 1])) {}
+
+main() {
+foo(1, 2);
+}""",
+      """
+foo(f(int i, {a: 1})) {}
+
+main() {
+foo(1, a: 2);
+}"""
+    ],
+  },
+
+  'REDIRECTING_FACTORY_WITH_DEFAULT': {
+    'id': 'AWSSEY',
+    'template':
+        "A parameter of a redirecting factory constructor can't specify a "
+        "default value.",
+    'howToFix': "Try removing the default value.",
+    'examples': [
+      """
+class A {
+A([a]);
+factory A.foo([a = 1]) = A;
+}
+
+main() {
+new A.foo(1);
+}""",
+      """
+class A {
+A({a});
+factory A.foo({a: 1}) = A;
+}
+
+main() {
+new A.foo(a: 1);
+}"""
+    ],
+  },
+
+  'FORMAL_DECLARED_CONST': {
+    'id': 'AVPRDK',
+    'template': "A formal parameter can't be declared const.",
+    'howToFix': "Try removing 'const'.",
+    'examples': [
+      """
+foo(const x) {}
+main() => foo(42);
+""",
+      """
+foo({const x}) {}
+main() => foo(42);
+""",
+      """
+foo([const x]) {}
+main() => foo(42);
+"""
+    ],
+  },
+
+  'FORMAL_DECLARED_STATIC': {
+    'id': 'PJKDMX',
+    'template': "A formal parameter can't be declared static.",
+    'howToFix': "Try removing 'static'.",
+    'examples': [
+      """
+foo(static x) {}
+main() => foo(42);
+""",
+      """
+foo({static x}) {}
+main() => foo(42);
+""",
+      """
+foo([static x]) {}
+main() => foo(42);
+"""
+    ],
+  },
+
+  'FINAL_FUNCTION_TYPE_PARAMETER': {
+    'id': 'JIOPIQ',
+    'template': "A function type parameter can't be declared final.",
+    'howToFix': "Try removing 'final'.",
+    'examples': [
+      """
+foo(final int x(int a)) {}
+main() => foo((y) => 42);
+""",
+      """
+foo({final int x(int a)}) {}
+main() => foo((y) => 42);
+""",
+      """
+foo([final int x(int a)]) {}
+main() => foo((y) => 42);
+"""
+    ],
+  },
+
+  'VAR_FUNCTION_TYPE_PARAMETER': {
+    'id': 'FOQOHK',
+    'template': "A function type parameter can't be declared with 'var'.",
+    'howToFix': "Try removing 'var'.",
+    'examples': [
+      """
+foo(var int x(int a)) {}
+main() => foo((y) => 42);
+""",
+      """
+foo({var int x(int a)}) {}
+main() => foo((y) => 42);
+""",
+      """
+foo([var int x(int a)]) {}
+main() => foo((y) => 42);
+"""
+    ],
+  },
+
+  'CANNOT_INSTANTIATE_TYPE_VARIABLE': {
+    'id': 'JAYHCH',
+    'template': "Cannot instantiate type variable '#{typeVariableName}'.",
+  },
+
+  'CYCLIC_TYPE_VARIABLE': {
+    'id': 'RQMPSO',
+    'template': "Type variable '#{typeVariableName}' is a supertype of itself.",
+  },
+
+  'CYCLIC_TYPEDEF': {
+    'id': 'VFERCQ',
+    'template': "A typedef can't refer to itself.",
+    'howToFix': "Try removing all references to '#{typedefName}' "
+        "in the definition of '#{typedefName}'.",
+    'examples': [
+      """
+typedef F F(); // The return type 'F' is a self-reference.
+main() { F f = null; }"""
+    ],
+  },
+
+  'CYCLIC_TYPEDEF_ONE': {
+    'id': 'ASWLWR',
+    'template': "A typedef can't refer to itself through another typedef.",
+    'howToFix': "Try removing all references to "
+        "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
+    'examples': [
+      """
+typedef G F(); // The return type 'G' is a self-reference through typedef 'G'.
+typedef F G(); // The return type 'F' is a self-reference through typedef 'F'.
+main() { F f = null; }""",
+      """
+typedef G F(); // The return type 'G' creates a self-reference.
+typedef H G(); // The return type 'H' creates a self-reference.
+typedef H(F f); // The argument type 'F' creates a self-reference.
+main() { F f = null; }"""
+    ],
+  },
+
+  'CLASS_NAME_EXPECTED': {'id': 'DPKNHY', 'template': "Class name expected.",},
+
+  'CANNOT_EXTEND': {
+    'id': 'GCIQXD',
+    'template': "'#{type}' cannot be extended.",
+  },
+
+  'CANNOT_IMPLEMENT': {
+    'id': 'IBOQKV',
+    'template': "'#{type}' cannot be implemented.",
+  },
+
+  // TODO(johnnwinther): Split messages into reasons for malformedness.
+  'CANNOT_EXTEND_MALFORMED': {
+    'id': 'YPFJBD',
+    'template': "Class '#{className}' can't extend the type '#{malformedType}' "
+        "because it is malformed.",
+    'howToFix': "Try correcting the malformed type annotation or removing the "
+        "'extends' clause.",
+    'examples': [
+      """
+class A extends Malformed {}
+main() => new A();"""
+    ],
+  },
+
+  'CANNOT_IMPLEMENT_MALFORMED': {
+    'id': 'XJUIAQ',
+    'template':
+        "Class '#{className}' can't implement the type '#{malformedType}' "
+        "because it is malformed.",
+    'howToFix': "Try correcting the malformed type annotation or removing the "
+        "type from the 'implements' clause.",
+    'examples': [
+      """
+class A implements Malformed {}
+main() => new A();"""
+    ],
+  },
+
+  'CANNOT_MIXIN_MALFORMED': {
+    'id': 'SSMNXN',
+    'template': "Class '#{className}' can't mixin the type '#{malformedType}' "
+        "because it is malformed.",
+    'howToFix': "Try correcting the malformed type annotation or removing the "
+        "type from the 'with' clause.",
+    'examples': [
+      """
+class A extends Object with Malformed {}
+main() => new A();"""
+    ],
+  },
+
+  'CANNOT_MIXIN': {
+    'id': 'KLSXDQ',
+    'template': "The type '#{type}' can't be mixed in.",
+    'howToFix': "Try removing '#{type}' from the 'with' clause.",
+    'examples': [
+      """
+class C extends Object with String {}
+
+main() => new C();
+""",
+      """
+typedef C = Object with String;
+
+main() => new C();
+"""
+    ],
+  },
+
+  'CANNOT_EXTEND_ENUM': {
+    'id': 'JEPRST',
+    'template':
+        "Class '#{className}' can't extend the type '#{enumType}' because "
+        "it is declared by an enum.",
+    'howToFix': "Try making '#{enumType}' a normal class or removing the "
+        "'extends' clause.",
+    'examples': [
+      """
+enum Enum { A }
+class B extends Enum {}
+main() => new B();"""
+    ],
+  },
+
+  'CANNOT_IMPLEMENT_ENUM': {
+    'id': 'JMJMSH',
+    'template': "Class '#{className}' can't implement the type '#{enumType}' "
+        "because it is declared by an enum.",
+    'howToFix': "Try making '#{enumType}' a normal class or removing the "
+        "type from the 'implements' clause.",
+    'examples': [
+      """
+enum Enum { A }
+class B implements Enum {}
+main() => new B();"""
+    ],
+  },
+
+  'CANNOT_MIXIN_ENUM': {
+    'id': 'YSYDIM',
+    'template':
+        "Class '#{className}' can't mixin the type '#{enumType}' because it "
+        "is declared by an enum.",
+    'howToFix': "Try making '#{enumType}' a normal class or removing the "
+        "type from the 'with' clause.",
+    'examples': [
+      """
+enum Enum { A }
+class B extends Object with Enum {}
+main() => new B();"""
+    ],
+  },
+
+  'CANNOT_INSTANTIATE_ENUM': {
+    'id': 'CQYIFU',
+    'template': "Enum type '#{enumName}' cannot be instantiated.",
+    'howToFix': "Try making '#{enumType}' a normal class or use an enum "
+        "constant.",
+    'examples': [
+      """
+enum Enum { A }
+main() => new Enum(0);""",
+      """
+enum Enum { A }
+main() => const Enum(0);"""
+    ],
+  },
+
+  'EMPTY_ENUM_DECLARATION': {
+    'id': 'JFPDOH',
+    'template': "Enum '#{enumName}' must contain at least one value.",
+    'howToFix': "Try adding an enum constant or making #{enumName} a "
+        "normal class.",
+    'examples': [
+      """
+enum Enum {}
+main() { Enum e; }"""
+    ],
+  },
+
+  'MISSING_ENUM_CASES': {
+    'id': 'HHEOIW',
+    'template': "Missing enum constants in switch statement: #{enumValues}.",
+    'howToFix': "Try adding the missing constants or a default case.",
+    'examples': [
+      """
+enum Enum { A, B }
+main() {
+switch (Enum.A) {
+case Enum.B: break;
+}
+}""",
+      """
+enum Enum { A, B, C }
+main() {
+switch (Enum.A) {
+case Enum.B: break;
+}
+}"""
+    ],
+  },
+
+  'DUPLICATE_EXTENDS_IMPLEMENTS': {
+    'id': 'BKRKEO',
+    'template': "'#{type}' can not be both extended and implemented.",
+  },
+
+  'DUPLICATE_IMPLEMENTS': {
+    'id': 'IWJFTU',
+    'template': "'#{type}' must not occur more than once "
+        "in the implements clause.",
+  },
+
+  'MULTI_INHERITANCE': {
+    'id': 'NWXGOI',
+    'template':
+        "Dart2js does not currently support inheritance of the same class "
+        "with different type arguments: Both #{firstType} and #{secondType} "
+        "are supertypes of #{thisType}.",
+  },
+
+  'ILLEGAL_SUPER_SEND': {
+    'id': 'LDRGIU',
+    'template': "'#{name}' cannot be called on super.",
+  },
+
+  'NO_SUCH_SUPER_MEMBER': {
+    'id': 'HIJJVG',
+    'template':
+        "Cannot resolve '#{memberName}' in a superclass of '#{className}'.",
+  },
+
+  'ADDITIONAL_TYPE_ARGUMENT': {
+    'id': 'HWYHWH',
+    'template': "Additional type argument.",
+  },
+
+  'MISSING_TYPE_ARGUMENT': {
+    'id': 'KYTQWA',
+    'template': "Missing type argument.",
+  },
+
+  // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or
+  // MISSING_TYPE_ARGUMENT instead.
+  'TYPE_ARGUMENT_COUNT_MISMATCH': {
+    'id': 'ECXGRM',
+    'template': "Incorrect number of type arguments on '#{type}'.",
+  },
+
+  'GETTER_MISMATCH': {
+    'id': 'MNODFW',
+    'template': "Setter disagrees on: '#{modifiers}'.",
+  },
+
+  'SETTER_MISMATCH': {
+    'id': 'FMNHPL',
+    'template': "Getter disagrees on: '#{modifiers}'.",
+  },
+
+  'ILLEGAL_SETTER_FORMALS': {
+    'id': 'COTPVN',
+    'template': "A setter must have exactly one argument.",
+  },
+
+  'NO_STATIC_OVERRIDE': {
+    'id': 'EHINXB',
+    'template':
+        "Static member cannot override instance member '#{memberName}' of "
+        "'#{className}'.",
+  },
+
+  'NO_STATIC_OVERRIDE_CONT': {
+    'id': 'TEVJMA',
+    'template': "This is the instance member that cannot be overridden "
+        "by a static member.",
+  },
+
+  'INSTANCE_STATIC_SAME_NAME': {
+    'id': 'LTBFBO',
+    'template': "Instance member '#{memberName}' and static member of "
+        "superclass '#{className}' have the same name.",
+  },
+
+  'INSTANCE_STATIC_SAME_NAME_CONT': {
+    'id': 'CHSUCQ',
+    'template': "This is the static member with the same name.",
+  },
+
+  'INVALID_OVERRIDE_METHOD': {
+    'id': 'NINKPI',
+    'template': "The type '#{declaredType}' of method '#{name}' declared in "
+        "'#{class}' is not a subtype of the overridden method type "
+        "'#{inheritedType}' inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDDEN_METHOD': {
+    'id': 'BQHUPY',
+    'template': "This is the overridden method '#{name}' declared in class "
+        "'#{class}'.",
+  },
+
+  'INVALID_OVERRIDE_GETTER': {
+    'id': 'KLMPWO',
+    'template': "The type '#{declaredType}' of getter '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden getter inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDDEN_GETTER': {
+    'id': 'ASSKCT',
+    'template': "This is the overridden getter '#{name}' declared in class "
+        "'#{class}'.",
+  },
+
+  'INVALID_OVERRIDE_GETTER_WITH_FIELD': {
+    'id': 'TCCGXU',
+    'template': "The type '#{declaredType}' of field '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden getter inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDE_FIELD_WITH_GETTER': {
+    'id': 'UMMEXO',
+    'template': "The type '#{declaredType}' of getter '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden field inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDE_SETTER': {
+    'id': 'BWRGEC',
+    'template': "The type '#{declaredType}' of setter '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden setter inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDDEN_SETTER': {
+    'id': 'XQUOLL',
+    'template': "This is the overridden setter '#{name}' declared in class "
+        "'#{class}'.",
+  },
+
+  'INVALID_OVERRIDE_SETTER_WITH_FIELD': {
+    'id': 'GKGOFA',
+    'template': "The type '#{declaredType}' of field '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden setter inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDE_FIELD_WITH_SETTER': {
+    'id': 'OOXKHQ',
+    'template': "The type '#{declaredType}' of setter '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden field inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDE_FIELD': {
+    'id': 'LDPKOL',
+    'template': "The type '#{declaredType}' of field '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden field inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDDEN_FIELD': {
+    'id': 'UNQFWX',
+    'template': "This is the overridden field '#{name}' declared in class "
+        "'#{class}'.",
+  },
+
+  'CANNOT_OVERRIDE_FIELD_WITH_METHOD': {
+    'id': 'SYKCSK',
+    'template': "Method '#{name}' in '#{class}' can't override field from "
+        "'#{inheritedClass}'.",
+  },
+
+  'CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT': {
+    'id': 'HYHQSO',
+    'template': "This is the field that cannot be overridden by a method.",
+  },
+
+  'CANNOT_OVERRIDE_METHOD_WITH_FIELD': {
+    'id': 'UROMAS',
+    'template': "Field '#{name}' in '#{class}' can't override method from "
+        "'#{inheritedClass}'.",
+  },
+
+  'CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT': {
+    'id': 'NSORYS',
+    'template': "This is the method that cannot be overridden by a field.",
+  },
+
+  'CANNOT_OVERRIDE_GETTER_WITH_METHOD': {
+    'id': 'MMFIOH',
+    'template': "Method '#{name}' in '#{class}' can't override getter from "
+        "'#{inheritedClass}'.",
+  },
+
+  'CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT': {
+    'id': 'YGWPDH',
+    'template': "This is the getter that cannot be overridden by a method.",
+  },
+
+  'CANNOT_OVERRIDE_METHOD_WITH_GETTER': {
+    'id': 'BNKNXO',
+    'template': "Getter '#{name}' in '#{class}' can't override method from "
+        "'#{inheritedClass}'.",
+  },
+
+  'CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT': {
+    'id': 'KFBCYX',
+    'template': "This is the method that cannot be overridden by a getter.",
+  },
+
+  'MISSING_FORMALS': {
+    'id': 'BOERAF',
+    'template': "Formal parameters are missing.",
+  },
+
+  'EXTRA_FORMALS': {
+    'id': 'UTWRIU',
+    'template': "Formal parameters are not allowed here.",
+  },
+
+  'UNARY_OPERATOR_BAD_ARITY': {
+    'id': 'TNHLAL',
+    'template': "Operator '#{operatorName}' must have no parameters.",
+  },
+
+  'MINUS_OPERATOR_BAD_ARITY': {
+    'id': 'SXDRRU',
+    'template': "Operator '-' must have 0 or 1 parameters.",
+  },
+
+  'BINARY_OPERATOR_BAD_ARITY': {
+    'id': 'QKWAUM',
+    'template': "Operator '#{operatorName}' must have exactly 1 parameter.",
+  },
+
+  'TERNARY_OPERATOR_BAD_ARITY': {
+    'id': 'LSMQGF',
+    'template': "Operator '#{operatorName}' must have exactly 2 parameters.",
+  },
+
+  'OPERATOR_OPTIONAL_PARAMETERS': {
+    'id': 'HSGRBV',
+    'template': "Operator '#{operatorName}' cannot have optional parameters.",
+  },
+
+  'OPERATOR_NAMED_PARAMETERS': {
+    'id': 'EACWGS',
+    'template': "Operator '#{operatorName}' cannot have named parameters.",
+  },
+
+  'CONSTRUCTOR_WITH_RETURN_TYPE': {
+    'id': 'OPMBHF',
+    'template': "Cannot have return type for constructor.",
+  },
+
+  'CANNOT_RETURN_FROM_CONSTRUCTOR': {
+    'id': 'NFUGNH',
+    'template': "Constructors can't return values.",
+    'howToFix': "Remove the return statement or use a factory constructor.",
+    'examples': [
+      """
+class C {
+C() {
+  return 1;
+}
+}
+
+main() => new C();"""
+    ],
+  },
+
+  'ILLEGAL_FINAL_METHOD_MODIFIER': {
+    'id': 'YUKCVU',
+    'template': "Cannot have final modifier on method.",
+  },
+
+  'ILLEGAL_CONST_FIELD_MODIFIER': {
+    'id': 'JGFAGV',
+    'template': "Cannot have const modifier on non-static field.",
+    'howToFix': "Try adding a static modifier, or removing the const modifier.",
+    'examples': [
+      """
+class C {
+const int a = 1;
+}
+
+main() => new C();"""
+    ],
+  },
+
+  'ILLEGAL_CONSTRUCTOR_MODIFIERS': {
+    'id': 'WODRHN',
+    'template': "Illegal constructor modifiers: '#{modifiers}'.",
+  },
+
+  'ILLEGAL_MIXIN_APPLICATION_MODIFIERS': {
+    'id': 'OFLFHN',
+    'template': "Illegal mixin application modifiers: '#{modifiers}'.",
+  },
+
+  'ILLEGAL_MIXIN_SUPERCLASS': {
+    'id': 'TPVVYN',
+    'template': "Class used as mixin must have Object as superclass.",
+  },
+
+  'ILLEGAL_MIXIN_OBJECT': {
+    'id': 'CMVTLF',
+    'template': "Cannot use Object as mixin.",
+  },
+
+  'ILLEGAL_MIXIN_CONSTRUCTOR': {
+    'id': 'HXBUIB',
+    'template': "Class used as mixin cannot have non-factory constructor.",
+  },
+
+  'ILLEGAL_MIXIN_CYCLE': {
+    'id': 'ANXAMU',
+    'template': "Class used as mixin introduces mixin cycle: "
+        "'#{mixinName1}' <-> '#{mixinName2}'.",
+  },
+
+  'ILLEGAL_MIXIN_WITH_SUPER': {
+    'id': 'KIEUGK',
+    'template': "Cannot use class '#{className}' as a mixin because it uses "
+        "'super'.",
+  },
+
+  'ILLEGAL_MIXIN_SUPER_USE': {
+    'id': 'QKUPLH',
+    'template': "Use of 'super' in class used as mixin.",
+  },
+
+  'PARAMETER_NAME_EXPECTED': {
+    'id': 'JOUOBT',
+    'template': "parameter name expected.",
+  },
+
+  'CANNOT_RESOLVE_GETTER': {
+    'id': 'TDHKSW',
+    'template': "Cannot resolve getter.",
+  },
+
+  'CANNOT_RESOLVE_SETTER': {
+    'id': 'QQFANP',
+    'template': "Cannot resolve setter.",
+  },
+
+  'ASSIGNING_FINAL_FIELD_IN_SUPER': {
+    'id': 'LXUPCC',
+    'template': "Cannot assign a value to final field '#{name}' "
+        "in superclass '#{superclassName}'.",
+  },
+
+  'ASSIGNING_METHOD': {
+    'id': 'JUVMYC',
+    'template': "Cannot assign a value to a method.",
+  },
+
+  'ASSIGNING_METHOD_IN_SUPER': {
+    'id': 'AGMAXN',
+    'template': "Cannot assign a value to method '#{name}' "
+        "in superclass '#{superclassName}'.",
+  },
+
+  'ASSIGNING_TYPE': {
+    'id': 'VXTPWE',
+    'template': "Cannot assign a value to a type.",
+  },
+
+  'IF_NULL_ASSIGNING_TYPE': {
+    'id': 'XBRHGK',
+    'template':
+        "Cannot assign a value to a type. Note that types are never null, "
+        "so this ??= assignment has no effect.",
+    'howToFix': "Try removing the '??=' assignment.",
+    'examples': ["class A {} main() { print(A ??= 3);}",],
+  },
+
+  'VOID_NOT_ALLOWED': {
+    'id': 'DMMDXT',
+    'template':
+        "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', "
+        "or a type.",
+    'examples': ["void x; main() {}", "foo(void x) {} main() { foo(null); }",],
+  },
+
+  'NULL_NOT_ALLOWED': {
+    'id': 'STYNSK',
+    'template': "`null` can't be used here.",
+  },
+
+  'BEFORE_TOP_LEVEL': {
+    'id': 'GRCXQF',
+    'template': "Part header must come before top-level definitions.",
+  },
+
+  'IMPORT_PART_OF': {
+    'id': 'VANCWE',
+    'template': "The imported library must not have a 'part-of' directive.",
+    'howToFix': "Try removing the 'part-of' directive or replacing the "
+        "import of the library with a 'part' directive.",
+    'examples': [
+      {
+        'main.dart': """
+library library;
+
+import 'part.dart';
+
+main() {}
+""",
+        'part.dart': """
+part of library;
+"""
+      }
+    ],
+  },
+
+  'IMPORT_PART_OF_HERE': {
+    'id': 'TRSZOJ',
+    'template': 'The library is imported here.',
+  },
+
+  'MAIN_HAS_PART_OF': {
+    'id': 'MFMRRL',
+    'template': "The main application file must not have a 'part-of' "
+                "directive.",
+    'howToFix': "Try removing the 'part-of' directive or starting compilation "
+                "from another file.",
+    'examples': [
+      {
+        'main.dart': """
+part of library;
+
+main() {}
+"""
+      }
+    ],
+  },
+
+  'LIBRARY_NAME_MISMATCH': {
+    'id': 'AXGYPQ',
+    'template': "Expected part of library name '#{libraryName}'.",
+    'howToFix': "Try changing the directive to 'part of #{libraryName};'.",
+    'examples': [
+      {
+        'main.dart': """
+library lib.foo;
+
+part 'part.dart';
+
+main() {}
+""",
+        'part.dart': """
+part of lib.bar;
+"""
+      }
+    ],
+  },
+
+  'MISSING_LIBRARY_NAME': {
+    'id': 'NYQNCA',
+    'template': "Library has no name. Part directive expected library name "
+        "to be '#{libraryName}'.",
+    'howToFix': "Try adding 'library #{libraryName};' to the library.",
+    'examples': [
+      {
+        'main.dart': """
+part 'part.dart';
+
+main() {}
+""",
+        'part.dart': """
+part of lib.foo;
+"""
+      }
+    ],
+  },
+
+  'THIS_IS_THE_PART_OF_TAG': {
+    'id': 'RPSJRS',
+    'template': "This is the part of directive.",
+  },
+
+  'MISSING_PART_OF_TAG': {
+    'id': 'QNYCMV',
+    'template': "This file has no part-of tag, but it is being used as a part.",
+  },
+
+  'DUPLICATED_PART_OF': {
+    'id': 'UJDYHF',
+    'template': "Duplicated part-of directive.",
+  },
+
+  'DUPLICATED_LIBRARY_NAME': {
+    'id': 'OSEHXI',
+    'template': "Duplicated library name '#{libraryName}'.",
+  },
+
+  'DUPLICATED_RESOURCE': {
+    'id': 'UFWKBY',
+    'template': "The resource '#{resourceUri}' is loaded through both "
+        "'#{canonicalUri1}' and '#{canonicalUri2}'.",
+  },
+
+  'DUPLICATED_LIBRARY_RESOURCE': {
+    'id': 'KYGYTT',
+    'template':
+        "The library '#{libraryName}' in '#{resourceUri}' is loaded through "
+        "both '#{canonicalUri1}' and '#{canonicalUri2}'.",
+  },
+
+  // This is used as an exception.
+  'INVALID_SOURCE_FILE_LOCATION': {
+    'id': 'WIGJFG',
+    'template': """
+Invalid offset (#{offset}) in source map.
+File: #{fileName}
+Length: #{length}""",
+  },
+
+  'TOP_LEVEL_VARIABLE_DECLARED_STATIC': {
+    'id': 'IVNDML',
+    'template': "Top-level variable cannot be declared static.",
+  },
+
+  'REFERENCE_IN_INITIALIZATION': {
+    'id': 'OVWTEU',
+    'template': "Variable '#{variableName}' is referenced during its "
+        "initialization.",
+    'howToFix': "If you are trying to reference a shadowed variable, rename "
+        "one of the variables.",
+    'examples': [
+      """
+foo(t) {
+var t = t;
+return t;
+}
+
+main() => foo(1);
+"""
+    ],
+  },
+
+  'CONST_WITHOUT_INITIALIZER': {
+    'id': 'UDWCNH',
+    'template': "A constant variable must be initialized.",
+    'howToFix': "Try adding an initializer or "
+        "removing the 'const' modifier.",
+    'examples': [
+      """
+void main() {
+const c; // This constant variable must be initialized.
+}"""
+    ],
+  },
+
+  'FINAL_WITHOUT_INITIALIZER': {
+    'id': 'YMESFI',
+    'template': "A final variable must be initialized.",
+    'howToFix': "Try adding an initializer or "
+        "removing the 'final' modifier.",
+    'examples': ["class C { static final field; } main() => C.field;"],
+  },
+
+  'CONST_LOOP_VARIABLE': {
+    'id': 'WUSKMG',
+    'template': "A loop variable cannot be constant.",
+    'howToFix': "Try remove the 'const' modifier or "
+        "replacing it with a 'final' modifier.",
+    'examples': [
+      """
+void main() {
+  for (const c in []) {}
+}"""
+    ],
+  },
+
+  'MEMBER_USES_CLASS_NAME': {
+    'id': 'TVFYRK',
+    'template': "Member variable can't have the same name as the class it is "
+        "declared in.",
+    'howToFix': "Try renaming the variable.",
+    'examples': [
+      """
+class A { var A; }
+main() {
+var a = new A();
+a.A = 1;
+}
+""",
+      """
+class A { static var A; }
+main() => A.A = 1;
+"""
+    ],
+  },
+
+  'WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT': {
+    'id': 'IXYNUF',
+    'template': "Wrong number of arguments to assert. Should be 1, but given "
+        "#{argumentCount}.",
+  },
+
+  'ASSERT_IS_GIVEN_NAMED_ARGUMENTS': {
+    'id': 'EJFDTO',
+    'template':
+        "'assert' takes no named arguments, but given #{argumentCount}.",
+  },
+
+  'FACTORY_REDIRECTION_IN_NON_FACTORY': {
+    'id': 'DTBWEX',
+    'template': "Factory redirection only allowed in factories.",
+  },
+
+  'MISSING_FACTORY_KEYWORD': {
+    'id': 'HOQYYA',
+    'template': "Did you forget a factory keyword here?",
+  },
+
+  'NO_SUCH_METHOD_IN_NATIVE': {
+    'id': 'MSDDBX',
+    'template':
+        "'NoSuchMethod' is not supported for classes that extend native "
+        "classes.",
+  },
+
+  'DEFERRED_LIBRARY_DART_2_DART': {
+    'id': 'RIRQAH',
+    'template': "Deferred loading is not supported by the dart backend yet. "
+        "The output will not be split.",
+  },
+
+  'DEFERRED_LIBRARY_WITHOUT_PREFIX': {
+    'id': 'CARRII',
+    'template': "This import is deferred but there is no prefix keyword.",
+    'howToFix': "Try adding a prefix to the import."
+  },
+
+  'DEFERRED_OLD_SYNTAX': {
+    'id': 'QCBRAE',
+    'template': "The DeferredLibrary annotation is obsolete.",
+    'howToFix':
+        "Use the \"import 'lib.dart' deferred as prefix\" syntax instead.",
+  },
+
+  'DEFERRED_LIBRARY_DUPLICATE_PREFIX': {
+    'id': 'BBMJTD',
+    'template': "The prefix of this deferred import is not unique.",
+    'howToFix': "Try changing the import prefix."
+  },
+
+  'DEFERRED_TYPE_ANNOTATION': {
+    'id': 'JOUEFD',
+    'template': "The type #{node} is deferred. "
+        "Deferred types are not valid as type annotations.",
+    'howToFix': "Try using a non-deferred abstract class as an interface.",
+  },
+
+  'ILLEGAL_STATIC': {
+    'id': 'HFBHVE',
+    'template': "Modifier static is only allowed on functions declared in "
+        "a class.",
+  },
+
+  'STATIC_FUNCTION_BLOAT': {
+    'id': 'SJHTKF',
+    'template': "Using '#{class}.#{name}' may lead to unnecessarily large "
+        "generated code.",
+    'howToFix': "Try adding '@MirrorsUsed(...)' as described at "
+        "https://goo.gl/Akrrog.",
+  },
+
+  'NON_CONST_BLOAT': {
+    'id': 'RDRSHO',
+    'template': "Using 'new #{name}' may lead to unnecessarily large generated "
+        "code.",
+    'howToFix': "Try using 'const #{name}' or adding '@MirrorsUsed(...)' as "
+        "described at https://goo.gl/Akrrog.",
+  },
+
+  'STRING_EXPECTED': {
+    'id': 'OEJOOI',
+    'template': "Expected a 'String', but got an instance of '#{type}'.",
+  },
+
+  'PRIVATE_IDENTIFIER': {
+    'id': 'XAHVWI',
+    'template': "'#{value}' is not a valid Symbol name because it starts with "
+        "'_'.",
+  },
+
+  'PRIVATE_NAMED_PARAMETER': {
+    'id': 'VFGCLK',
+    'template': "Named optional parameter can't have a library private name.",
+    'howToFix': "Try removing the '_' or making the parameter positional or "
+        "required.",
+    'examples': ["""foo({int _p}) {} main() => foo();"""],
+  },
+
+  'UNSUPPORTED_LITERAL_SYMBOL': {
+    'id': 'OYCDII',
+    'template':
+        "Symbol literal '##{value}' is currently unsupported by dart2js.",
+  },
+
+  'INVALID_SYMBOL': {
+    'id': 'RUXMBL',
+    'template': '''
+'#{value}' is not a valid Symbol name because is not:
+* an empty String,
+* a user defined operator,
+* a qualified non-private identifier optionally followed by '=', or
+* a qualified non-private identifier followed by '.' and a user-defined '''
+        "operator.",
+  },
+
+  'AMBIGUOUS_REEXPORT': {
+    'id': 'YNTOND',
+    'template': "'#{name}' is (re)exported by multiple libraries.",
+  },
+
+  'AMBIGUOUS_LOCATION': {
+    'id': 'SKLTYA',
+    'template': "'#{name}' is defined here.",
+  },
+
+  'IMPORTED_HERE': {'id': 'IMUXAE', 'template': "'#{name}' is imported here.",},
+
+  'OVERRIDE_EQUALS_NOT_HASH_CODE': {
+    'id': 'MUHYXI',
+    'template': "The class '#{class}' overrides 'operator==', "
+        "but not 'get hashCode'.",
+  },
+
+  'INTERNAL_LIBRARY_FROM': {
+    'id': 'RXOCLX',
+    'template': "Internal library '#{resolvedUri}' is not accessible from "
+        "'#{importingUri}'.",
+  },
+
+  'INTERNAL_LIBRARY': {
+    'id': 'SYLJAV',
+    'template': "Internal library '#{resolvedUri}' is not accessible.",
+  },
+
+  'JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS': {
+    'id': 'LSHKJK',
+    'template':
+        "Js-interop class '#{cls}' cannot extend from the non js-interop "
+        "class '#{superclass}'.",
+    'howToFix': "Annotate the superclass with @JS.",
+    'examples': [
+      """
+            import 'package:js/js.dart';
+
+            class Foo { }
+
+            @JS()
+            class Bar extends Foo { }
+
+            main() {
+              new Bar();
+            }
+            """
+    ],
+  },
+
+  'JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER': {
+    'id': 'QLLLEE',
+    'template':
+        "Member '#{member}' in js-interop class '#{cls}' is not external.",
+    'howToFix': "Mark all interop methods external",
+    'examples': [
+      """
+            import 'package:js/js.dart';
+
+            @JS()
+            class Foo {
+              bar() {}
+            }
+
+            main() {
+              new Foo().bar();
+            }
+            """
+    ],
+  },
+
+  'JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS': {
+    'id': 'TDQHRY',
+    'template': "Js-interop method '#{method}' has named arguments but is not "
+        "a factory constructor of an @anonymous @JS class.",
+    'howToFix': "Remove all named arguments from js-interop method or "
+        "in the case of a factory constructor annotate the class "
+        "as @anonymous.",
+    'examples': [
+      """
+            import 'package:js/js.dart';
+
+            @JS()
+            class Foo {
+              external bar(foo, {baz});
+            }
+
+            main() {
+              new Foo().bar(4, baz: 5);
+            }
+            """
+    ],
+  },
+
+  'JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS': {
+    'id': 'EHEKUY',
+    'template':
+        "Parameter '#{parameter}' in anonymous js-interop class '#{cls}' "
+        "object literal constructor is positional instead of named."
+        ".",
+    'howToFix': "Make all arguments in external factory object literal "
+        "constructors named.",
+    'examples': [
+      """
+            import 'package:js/js.dart';
+
+            @anonymous
+            @JS()
+            class Foo {
+              external factory Foo(foo, {baz});
+            }
+
+            main() {
+              new Foo(5, baz: 5);
+            }
+            """
+    ],
+  },
+
+  'LIBRARY_NOT_FOUND': {
+    'id': 'BARPSL',
+    'template': "Library not found '#{resolvedUri}'.",
+  },
+
+  'LIBRARY_NOT_SUPPORTED': {
+    'id': 'GDXUNS',
+    'template': "Library not supported '#{resolvedUri}'.",
+    'howToFix': "Try removing the dependency or enabling support using "
+        "the '--categories' option.",
+    'examples': [
+//            """
+//            import 'dart:io';
+//            main() {}
+//            """
+    ],
+    // TODO(johnniwinther): Enable example when message_kind_test.dart
+    // supports library loader callbacks.
+  },
+
+  'UNSUPPORTED_EQ_EQ_EQ': {
+    'id': 'GPOVNO',
+    'template': "'===' is not an operator. "
+        "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?",
+  },
+
+  'UNSUPPORTED_BANG_EQ_EQ': {
+    'id': 'HDYKMV',
+    'template': "'!==' is not an operator. "
+        "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?",
+  },
+
+  'UNSUPPORTED_PREFIX_PLUS': {
+    'id': 'LSQTHP',
+    'template': "'+' is not a prefix operator. ",
+    'howToFix': "Try removing '+'.",
+    'examples': ["main() => +2;  // No longer a valid way to write '2'"],
+  },
+
+  'UNSUPPORTED_THROW_WITHOUT_EXP': {
+    'id': 'QOAKGE',
+    'template': "No expression after 'throw'. "
+        "Did you mean 'rethrow'?",
+  },
+
+  'DEPRECATED_TYPEDEF_MIXIN_SYNTAX': {
+    'id': 'BBGGFE',
+    'template': "'typedef' not allowed here. ",
+    'howToFix': "Try replacing 'typedef' with 'class'.",
+    'examples': [
+      """
+class B { }
+class M1 {  }
+typedef C = B with M1;  // Need to replace 'typedef' with 'class'.
+main() { new C(); }
+"""
+    ],
+  },
+
+  'MIRRORS_EXPECTED_STRING': {
+    'id': 'XSKTIB',
+    'template':
+        "Can't use '#{name}' here because it's an instance of '#{type}' "
+        "and a 'String' value is expected.",
+    'howToFix': "Did you forget to add quotes?",
+    'examples': [
+      """
+// 'Foo' is a type literal, not a string.
+@MirrorsUsed(symbols: const [Foo])
+import 'dart:mirrors';
+
+class Foo {}
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_EXPECTED_STRING_OR_TYPE': {
+    'id': 'JQDJPL',
+    'template':
+        "Can't use '#{name}' here because it's an instance of '#{type}' "
+        "and a 'String' or 'Type' value is expected.",
+    'howToFix': "Did you forget to add quotes?",
+    'examples': [
+      """
+// 'main' is a method, not a class.
+@MirrorsUsed(targets: const [main])
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_EXPECTED_STRING_OR_LIST': {
+    'id': 'UVYCOE',
+    'template':
+        "Can't use '#{name}' here because it's an instance of '#{type}' "
+        "and a 'String' or 'List' value is expected.",
+    'howToFix': "Did you forget to add quotes?",
+    'examples': [
+      """
+// 'Foo' is not a string.
+@MirrorsUsed(symbols: Foo)
+import 'dart:mirrors';
+
+class Foo {}
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_EXPECTED_STRING_TYPE_OR_LIST': {
+    'id': 'WSYDFL',
+    'template':
+        "Can't use '#{name}' here because it's an instance of '#{type}' "
+        "but a 'String', 'Type', or 'List' value is expected.",
+    'howToFix': "Did you forget to add quotes?",
+    'examples': [
+      """
+// '1' is not a string.
+@MirrorsUsed(targets: 1)
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY': {
+    'id': 'VDBBNE',
+    'template': "Can't find '#{name}' in the current library.",
+    // TODO(ahe): The closest identifiers in edit distance would be nice.
+    'howToFix': "Did you forget to add an import?",
+    'examples': [
+      """
+// 'window' is not in scope because dart:html isn't imported.
+@MirrorsUsed(targets: 'window')
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_CANNOT_RESOLVE_IN_LIBRARY': {
+    'id': 'RUEKXE',
+    'template': "Can't find '#{name}' in the library '#{library}'.",
+    // TODO(ahe): The closest identifiers in edit distance would be nice.
+    'howToFix': "Is '#{name}' spelled right?",
+    'examples': [
+      """
+// 'List' is misspelled.
+@MirrorsUsed(targets: 'dart.core.Lsit')
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_CANNOT_FIND_IN_ELEMENT': {
+    'id': 'ACPDCS',
+    'template': "Can't find '#{name}' in '#{element}'.",
+    // TODO(ahe): The closest identifiers in edit distance would be nice.
+    'howToFix': "Is '#{name}' spelled right?",
+    'examples': [
+      """
+// 'addAll' is misspelled.
+@MirrorsUsed(targets: 'dart.core.List.addAl')
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'INVALID_URI': {
+    'id': 'QQEQMK',
+    'template': "'#{uri}' is not a valid URI.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+// can't have a '[' in a URI
+import '../../Udyn[mic ils/expect.dart';
+
+main() {}
+"""
+    ],
+  },
+
+  'INVALID_PACKAGE_CONFIG': {
+    'id': 'XKFAJO',
+    'template': """Package config file '#{uri}' is invalid.
+#{exception}""",
+    'howToFix': DONT_KNOW_HOW_TO_FIX
+  },
+
+  'INVALID_PACKAGE_URI': {
+    'id': 'MFVNNJ',
+    'template': "'#{uri}' is not a valid package URI (#{exception}).",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+// can't have a 'top level' package URI
+import 'package:foo.dart';
+
+main() {}
+""",
+      """
+// can't have 2 slashes
+import 'package://foo/foo.dart';
+
+main() {}
+""",
+      """
+// package name must be valid
+import 'package:not\valid/foo.dart';
+
+main() {}
+"""
+    ],
+  },
+
+  'READ_SCRIPT_ERROR': {
+    'id': 'JDDYLH',
+    'template': "Can't read '#{uri}' (#{exception}).",
+    // Don't know how to fix since the underlying error is unknown.
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+// 'foo.dart' does not exist.
+import 'foo.dart';
+
+main() {}
+"""
+    ],
+  },
+
+  'READ_SELF_ERROR': {
+    'id': 'CRJUAV',
+    'template': "#{exception}",
+    // Don't know how to fix since the underlying error is unknown.
+    'howToFix': DONT_KNOW_HOW_TO_FIX
+  },
+
+  'EXTRANEOUS_MODIFIER': {
+    'id': 'DPLVJG',
+    'template': "Can't have modifier '#{modifier}' here.",
+    'howToFix': "Try removing '#{modifier}'.",
+    'examples': [
+      "var String foo; main(){}",
+      // "var get foo; main(){}",
+      "var set foo; main(){}",
+      "var final foo; main(){}",
+      "var var foo; main(){}",
+      "var const foo; main(){}",
+      "var abstract foo; main(){}",
+      "var static foo; main(){}",
+      "var external foo; main(){}",
+      "get var foo; main(){}",
+      "set var foo; main(){}",
+      "final var foo; main(){}",
+      "var var foo; main(){}",
+      "const var foo; main(){}",
+      "abstract var foo; main(){}",
+      "static var foo; main(){}",
+      "external var foo; main(){}"
+    ],
+  },
+
+  'EXTRANEOUS_MODIFIER_REPLACE': {
+    'id': 'SSXDLN',
+    'template': "Can't have modifier '#{modifier}' here.",
+    'howToFix': "Try replacing modifier '#{modifier}' with 'var', 'final', "
+        "or a type.",
+    'examples': [
+      // "get foo; main(){}",
+      "set foo; main(){}",
+      "abstract foo; main(){}",
+      "static foo; main(){}",
+      "external foo; main(){}"
+    ],
+  },
+
+  'ABSTRACT_CLASS_INSTANTIATION': {
+    'id': 'KOBCRO',
+    'template': "Can't instantiate abstract class.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': ["abstract class A {} main() { new A(); }"],
+  },
+
+  'BODY_EXPECTED': {
+    'id': 'YXCAHO',
+    'template': "Expected a function body or '=>'.",
+    // TODO(ahe): In some scenarios, we can suggest removing the 'static'
+    // keyword.
+    'howToFix': "Try adding {}.",
+    'examples': ["main();"],
+  },
+
+  'MIRROR_BLOAT': {
+    'id': 'BSEAIT',
+    'template':
+        "#{count} methods retained for use by dart:mirrors out of #{total}"
+        " total methods (#{percentage}%).",
+  },
+
+  'MIRROR_IMPORT': {'id': 'BDAETE', 'template': "Import of 'dart:mirrors'.",},
+
+  'MIRROR_IMPORT_NO_USAGE': {
+    'id': 'OJOHTR',
+    'template':
+        "This import is not annotated with @MirrorsUsed, which may lead to "
+        "unnecessarily large generated code.",
+    'howToFix': "Try adding '@MirrorsUsed(...)' as described at "
+        "https://goo.gl/Akrrog.",
+  },
+
+  'JS_PLACEHOLDER_CAPTURE': {
+    'id': 'EJXEGQ',
+    'template': "JS code must not use '#' placeholders inside functions.",
+    'howToFix': "Use an immediately called JavaScript function to capture the"
+        " the placeholder values as JavaScript function parameters.",
+  },
+
+  'WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT': {
+    'id': 'JHRISO',
+    'template':
+        "Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant.",
+  },
+
+  'EXPECTED_IDENTIFIER_NOT_RESERVED_WORD': {
+    'id': 'FEJXJF',
+    'template': "'#{keyword}' is a reserved word and can't be used here.",
+    'howToFix': "Try using a different name.",
+    'examples': ["do() {} main() {}"],
+  },
+
+  'NAMED_FUNCTION_EXPRESSION': {
+    'id': 'CTHFPI',
+    'template': "Function expression '#{name}' cannot be named.",
+    'howToFix': "Try removing the name.",
+    'examples': ["main() { var f = func() {}; }"],
+  },
+
+  'UNUSED_METHOD': {
+    'id': 'PKLRQL',
+    'template': "The method '#{name}' is never called.",
+    'howToFix': "Consider deleting it.",
+    'examples': ["deadCode() {} main() {}"],
+  },
+
+  'UNUSED_CLASS': {
+    'id': 'TBIECC',
+    'template': "The class '#{name}' is never used.",
+    'howToFix': "Consider deleting it.",
+    'examples': ["class DeadCode {} main() {}"],
+  },
+
+  'UNUSED_TYPEDEF': {
+    'id': 'JBIPCN',
+    'template': "The typedef '#{name}' is never used.",
+    'howToFix': "Consider deleting it.",
+    'examples': ["typedef DeadCode(); main() {}"],
+  },
+
+  'ABSTRACT_METHOD': {
+    'id': 'HOKOBG',
+    'template': "The method '#{name}' has no implementation in "
+        "class '#{class}'.",
+    'howToFix': "Try adding a body to '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+class Class {
+method();
+}
+main() => new Class().method();
+"""
+    ],
+  },
+
+  'ABSTRACT_GETTER': {
+    'id': 'VKTRNK',
+    'template': "The getter '#{name}' has no implementation in "
+        "class '#{class}'.",
+    'howToFix': "Try adding a body to '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+class Class {
+get getter;
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'ABSTRACT_SETTER': {
+    'id': 'XGDGKK',
+    'template': "The setter '#{name}' has no implementation in "
+        "class '#{class}'.",
+    'howToFix': "Try adding a body to '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+class Class {
+set setter(_);
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'INHERIT_GETTER_AND_METHOD': {
+    'id': 'UMEUEG',
+    'template': "The class '#{class}' can't inherit both getters and methods "
+        "by the named '#{name}'.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+class A {
+get member => null;
+}
+class B {
+member() {}
+}
+class Class implements A, B {
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'INHERITED_METHOD': {
+    'id': 'GMSVBM',
+    'template': "The inherited method '#{name}' is declared here in class "
+        "'#{class}'.",
+  },
+
+  'INHERITED_EXPLICIT_GETTER': {
+    'id': 'KKAVRS',
+    'template': "The inherited getter '#{name}' is declared here in class "
+        "'#{class}'.",
+  },
+
+  'INHERITED_IMPLICIT_GETTER': {
+    'id': 'JBAMEJ',
+    'template': "The inherited getter '#{name}' is implicitly declared by this "
+        "field in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_METHOD_ONE': {
+    'id': 'CMCLWO',
+    'template': "'#{class}' doesn't implement '#{method}' "
+        "declared in '#{declarer}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+m();
+}
+class C implements I {}
+main() => new C();
+""",
+      """
+abstract class I {
+m();
+}
+class C extends I {}
+main() => new C();
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_METHOD': {
+    'id': 'IJSNQB',
+    'template': "'#{class}' doesn't implement '#{method}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+m();
+}
+
+abstract class J {
+m();
+}
+
+class C implements I, J {}
+
+main() {
+new C();
+}
+""",
+      """
+abstract class I {
+m();
+}
+
+abstract class J {
+m();
+}
+
+class C extends I implements J {}
+
+main() {
+new C();
+}
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_METHOD_CONT': {
+    'id': 'KFBKPO',
+    'template': "The method '#{name}' is declared here in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_SETTER_ONE': {
+    'id': 'QGKTEA',
+    'template': "'#{class}' doesn't implement the setter '#{name}' "
+        "declared in '#{declarer}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+set m(_);
+}
+class C implements I {}
+class D implements I {
+set m(_) {}
+}
+main() {
+new D().m = 0;
+new C();
+}
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_SETTER': {
+    'id': 'VEEGJQ',
+    'template': "'#{class}' doesn't implement the setter '#{name}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+set m(_);
+}
+abstract class J {
+set m(_);
+}
+class C implements I, J {}
+main() => new C();
+""",
+      """
+abstract class I {
+set m(_);
+}
+abstract class J {
+set m(_);
+}
+class C extends I implements J {}
+main() => new C();
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_EXPLICIT_SETTER': {
+    'id': 'SABABA',
+    'template': "The setter '#{name}' is declared here in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_IMPLICIT_SETTER': {
+    'id': 'SWESAQ',
+    'template': "The setter '#{name}' is implicitly declared by this field "
+        "in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_GETTER_ONE': {
+    'id': 'ODEPFW',
+    'template': "'#{class}' doesn't implement the getter '#{name}' "
+        "declared in '#{declarer}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+get m;
+}
+class C implements I {}
+main() => new C();
+""",
+      """
+abstract class I {
+get m;
+}
+class C extends I {}
+main() => new C();
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_GETTER': {
+    'id': 'VHSECG',
+    'template': "'#{class}' doesn't implement the getter '#{name}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+get m;
+}
+abstract class J {
+get m;
+}
+class C implements I, J {}
+main() => new C();
+""",
+      """
+abstract class I {
+get m;
+}
+abstract class J {
+get m;
+}
+class C extends I implements J {}
+main() => new C();
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_EXPLICIT_GETTER': {
+    'id': 'HFDJPP',
+    'template': "The getter '#{name}' is declared here in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_IMPLICIT_GETTER': {
+    'id': 'BSCQNO',
+    'template': "The getter '#{name}' is implicitly declared by this field "
+        "in class '#{class}'.",
+  },
+
+  'INVALID_METADATA': {
+    'id': 'RKJGDE',
+    'template':
+        "A metadata annotation must be either a reference to a compile-time "
+        "constant variable or a call to a constant constructor.",
+    'howToFix':
+        "Try using a different constant value or referencing it through a "
+        "constant variable.",
+    'examples': [
+'@Object main() {}',
+'@print main() {}']
+  },
+
+  'INVALID_METADATA_GENERIC': {
+    'id': 'WEEDQD',
+    'template':
+        "A metadata annotation using a constant constructor cannot use type "
+        "arguments.",
+    'howToFix':
+        "Try removing the type arguments or referencing the constant "
+        "through a constant variable.",
+    'examples': [
+      '''
+class C<T> {
+  const C();
+}
+@C<int>() main() {}
+'''],
+  },
+
+  'EQUAL_MAP_ENTRY_KEY': {
+    'id': 'KIDLPM',
+    'template': "An entry with the same key already exists in the map.",
+    'howToFix': "Try removing the previous entry or changing the key in one "
+        "of the entries.",
+    'examples': [
+      """
+main() {
+var m = const {'foo': 1, 'foo': 2};
+}"""
+    ],
+  },
+
+  'BAD_INPUT_CHARACTER': {
+    'id': 'SHQWJY',
+    'template': "Character U+#{characterHex} isn't allowed here.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+main() {
+String x = ç;
+}
+"""
+    ],
+  },
+
+  'UNTERMINATED_STRING': {
+    'id': 'TRLTHK',
+    'template': "String must end with #{quote}.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+main() {
+return '
+;
+}
+""",
+      """
+main() {
+return \"
+;
+}
+""",
+      """
+main() {
+return r'
+;
+}
+""",
+      """
+main() {
+return r\"
+;
+}
+""",
+      """
+main() => '''
+""",
+      """
+main() => \"\"\"
+""",
+      """
+main() => r'''
+""",
+      """
+main() => r\"\"\"
+"""
+    ],
+  },
+
+  'UNMATCHED_TOKEN': {
+    'id': 'AGJKMQ',
+    'template': "Can't find '#{end}' to match '#{begin}'.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': ["main(", "main(){", "main(){]}",],
+  },
+
+  'UNTERMINATED_TOKEN': {
+    'id': 'VIIXHQ',
+    'template':
+        // This is a fall-back message that shouldn't happen.
+        "Incomplete token.",
+  },
+
+  'EXPONENT_MISSING': {
+    'id': 'CXPLCR',
+    'template':
+        "Numbers in exponential notation should always contain an exponent"
+        " (an integer number with an optional sign).",
+    'howToFix': "Make sure there is an exponent, and remove any whitespace "
+        "before it.",
+    'examples': [
+      """
+main() {
+var i = 1e;
+}
+"""
+    ],
+  },
+
+  'HEX_DIGIT_EXPECTED': {
+    'id': 'GKCAGV',
+    'template': "A hex digit (0-9 or A-F) must follow '0x'.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX, // Seems obvious from the error message.
+    'examples': [
+      """
+main() {
+var i = 0x;
+}
+"""
+    ],
+  },
+
+  'MALFORMED_STRING_LITERAL': {
+    'id': 'DULNSD',
+    'template':
+        r"A '$' has special meaning inside a string, and must be followed by "
+        "an identifier or an expression in curly braces ({}).",
+    'howToFix': r"Try adding a backslash (\) to escape the '$'.",
+    'examples': [
+      r"""
+main() {
+return '$';
+}
+""",
+      r'''
+main() {
+return "$";
+}
+''',
+      r"""
+main() {
+return '''$''';
+}
+""",
+      r'''
+main() {
+return """$""";
+}
+'''
+    ],
+  },
+
+  'UNTERMINATED_COMMENT': {
+    'id': 'NECJNM',
+    'template': "Comment starting with '/*' must end with '*/'.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      r"""
+main() {
+}
+/*"""
+    ],
+  },
+
+  'MISSING_TOKEN_BEFORE_THIS': {
+    'id': 'AFKXGU',
+    'template': "Expected '#{token}' before this.",
+    // Consider the second example below: the parser expects a ')' before
+    // 'y', but a ',' would also have worked. We don't have enough
+    // information to give a good suggestion.
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': ["main() => true ? 1;", "main() => foo(x: 1 y: 2);",],
+  },
+
+  'MISSING_TOKEN_AFTER_THIS': {
+    'id': 'FMUFJL',
+    'template': "Expected '#{token}' after this.",
+    // See [MISSING_TOKEN_BEFORE_THIS], we don't have enough information
+    // to give a good suggestion.
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      "main(x) {x}",
+      """
+class S1 {}
+class S2 {}
+class S3 {}
+class A = S1 with S2, S3
+main() => new A();
+"""
+    ],
+  },
+
+  'CONSIDER_ANALYZE_ALL': {
+    'id': 'HHILSH',
+    'template': "Could not find '#{main}'.  Nothing will be analyzed.",
+    'howToFix': "Try using '--analyze-all' to analyze everything.",
+    'examples': [''],
+  },
+
+  'MISSING_MAIN': {
+    'id': 'HNAOPV',
+    'template': "Could not find '#{main}'.",
+    // No example, test uses '--analyze-only' which will produce the above
+    // message [CONSIDER_ANALYZE_ALL].  An example for a human operator
+    // would be an empty file.
+    'howToFix': "Try adding a method named '#{main}' to your program."
+  },
+
+  'MAIN_NOT_A_FUNCTION': {
+    'id': 'PIURPA',
+    'template': "'#{main}' is not a function.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX, // Don't state the obvious.
+    'examples': ['var main;'],
+  },
+
+  'MAIN_WITH_EXTRA_PARAMETER': {
+    'id': 'ONOGQB',
+    'template': "'#{main}' cannot have more than two parameters.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX, // Don't state the obvious.
+    'examples': ['main(a, b, c) {}'],
+  },
+
+  'COMPILER_CRASHED': {
+    'id': 'MHDWAV',
+    'template': "The compiler crashed when compiling this element.",
+  },
+
+  'PLEASE_REPORT_THE_CRASH': {
+    'id': 'UUTHXX',
+    'template': '''
+The compiler is broken.
+
+When compiling the above element, the compiler crashed. It is not
+possible to tell if this is caused by a problem in your program or
+not. Regardless, the compiler should not crash.
+
+The Dart team would greatly appreciate if you would take a moment to
+report this problem at http://dartbug.com/new.
+
+Please include the following information:
+
+* the name and version of your operating system,
+
+* the Dart SDK build number (#{buildId}), and
+
+* the entire message you see here (including the full stack trace
+below as well as the source location above).
+''',
+  },
+
+  'POTENTIAL_MUTATION': {
+    'id': 'YGNLLB',
+    'template': "Variable '#{variableName}' is not known to be of type "
+        "'#{shownType}' because it is potentially mutated in the scope for "
+        "promotion.",
+  },
+
+  'POTENTIAL_MUTATION_HERE': {
+    'id': 'ATMSVX',
+    'template': "Variable '#{variableName}' is potentially mutated here.",
+  },
+
+  'POTENTIAL_MUTATION_IN_CLOSURE': {
+    'id': 'XUAHTW',
+    'template': "Variable '#{variableName}' is not known to be of type "
+        "'#{shownType}' because it is potentially mutated within a closure.",
+  },
+
+  'POTENTIAL_MUTATION_IN_CLOSURE_HERE': {
+    'id': 'UHFXLG',
+    'template': "Variable '#{variableName}' is potentially mutated in a "
+        "closure here.",
+  },
+
+  'ACCESSED_IN_CLOSURE': {
+    'id': 'JJHKSF',
+    'template': "Variable '#{variableName}' is not known to be of type "
+        "'#{shownType}' because it is accessed by a closure in the scope for "
+        "promotion and potentially mutated in the scope of "
+        "'#{variableName}'.",
+  },
+
+  'ACCESSED_IN_CLOSURE_HERE': {
+    'id': 'KMJVEA',
+    'template': "Variable '#{variableName}' is accessed in a closure here.",
+  },
+
+  'NOT_MORE_SPECIFIC': {
+    'id': 'EJHQAG',
+    'template': "Variable '#{variableName}' is not shown to have type "
+        "'#{shownType}' because '#{shownType}' is not more specific than the "
+        "known type '#{knownType}' of '#{variableName}'.",
+  },
+
+  'NOT_MORE_SPECIFIC_SUBTYPE': {
+    'id': 'APICDL',
+    'template': "Variable '#{variableName}' is not shown to have type "
+        "'#{shownType}' because '#{shownType}' is not a subtype of the "
+        "known type '#{knownType}' of '#{variableName}'.",
+  },
+
+  'NOT_MORE_SPECIFIC_SUGGESTION': {
+    'id': 'FFNCJX',
+    'template': "Variable '#{variableName}' is not shown to have type "
+        "'#{shownType}' because '#{shownType}' is not more specific than the "
+        "known type '#{knownType}' of '#{variableName}'.",
+    'howToFix': "Try replacing '#{shownType}' with '#{shownTypeSuggestion}'.",
+  },
+
+  'NO_COMMON_SUBTYPES': {
+    'id': 'XKJOEC',
+    'template': "Types '#{left}' and '#{right}' have no common subtypes.",
+  },
+
+  'HIDDEN_WARNINGS_HINTS': {
+    'id': 'JBAWEK',
+    'template':
+        "#{warnings} warning(s) and #{hints} hint(s) suppressed in #{uri}.",
+  },
+
+  'HIDDEN_WARNINGS': {
+    'id': 'JIYWDC',
+    'template': "#{warnings} warning(s) suppressed in #{uri}.",
+  },
+
+  'HIDDEN_HINTS': {
+    'id': 'RHNXQT',
+    'template': "#{hints} hint(s) suppressed in #{uri}.",
+  },
+
+  'PREAMBLE': {
+    'id': 'GXGWIF',
+    'template': "When run on the command-line, the compiled output might"
+        " require a preamble file located in:\n"
+        "  <sdk>/lib/_internal/js_runtime/lib/preambles.",
+  },
+
+  'INVALID_SYNC_MODIFIER': {
+    'id': 'FNYUYU',
+    'template': "Invalid modifier 'sync'.",
+    'howToFix': "Try replacing 'sync' with 'sync*'.",
+    'examples': ["main() sync {}"],
+  },
+
+  'INVALID_AWAIT_FOR': {
+    'id': 'IEYGCY',
+    'template': "'await' is only supported on for-in loops.",
+    'howToFix': "Try rewriting the loop as a for-in loop or removing the "
+        "'await' keyword.",
+    'examples': [
+      """
+main() async* {
+await for (int i = 0; i < 10; i++) {}
+}
+"""
+    ],
+  },
+
+  'INVALID_AWAIT_FOR_IN': {
+    'id': 'FIEYGC',
+    'template': "'await' is only supported in methods with an 'async' or "
+                "'async*' body modifier.",
+    'howToFix': "Try adding 'async' or 'async*' to the method body or "
+                "removing the 'await' keyword.",
+    'examples': [
+      """
+main(o) sync* {
+  await for (var e in o) {}
+}
+"""
+    ],
+  },
+
+  'INVALID_AWAIT': {
+    'id': 'IEYHYD',
+    'template': "'await' is only supported in methods with an 'async' or "
+                "'async*' body modifier.",
+    'howToFix': "Try adding 'async' or 'async*' to the method body.",
+    'examples': [
+      """
+main() sync* {
+  await null;
+}
+"""
+    ],
+  },
+
+  'INVALID_YIELD': {
+    'id': 'IPGGCY',
+    'template': "'yield' is only supported in methods with a 'sync*' or "
+                "'async*' body modifier.",
+    'howToFix': "Try adding 'sync*' or 'async*' to the method body.",
+    'examples': [
+      """
+main() async {
+  yield 0;
+}
+"""
+    ],
+  },
+
+  'ASYNC_MODIFIER_ON_ABSTRACT_METHOD': {
+    'id': 'VRISLY',
+    'template':
+        "The modifier '#{modifier}' is not allowed on an abstract method.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier or adding a "
+        "body to the method.",
+    'examples': [
+      """
+abstract class A {
+method() async;
+}
+class B extends A {
+method() {}
+}
+main() {
+A a = new B();
+a.method();
+}
+"""
+    ],
+  },
+
+  'ASYNC_MODIFIER_ON_CONSTRUCTOR': {
+    'id': 'DHCFON',
+    'template': "The modifier '#{modifier}' is not allowed on constructors.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier.",
+    'examples': [
+      """
+class A {
+A() async;
+}
+main() => new A();""",
+      """
+class A {
+A();
+factory A.a() async* {}
+}
+main() => new A.a();"""
+    ],
+  },
+
+  'ASYNC_MODIFIER_ON_SETTER': {
+    'id': 'NMJLJE',
+    'template': "The modifier '#{modifier}' is not allowed on setters.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier.",
+    'examples': [
+      """
+class A {
+set foo(v) async {}
+}
+main() => new A().foo = 0;"""
+    ],
+  },
+
+  'YIELDING_MODIFIER_ON_ARROW_BODY': {
+    'id': 'UOGLUX',
+    'template':
+        "The modifier '#{modifier}' is not allowed on methods implemented "
+        "using '=>'.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier or implementing "
+        "the method body using a block: '{ ... }'.",
+    'examples': ["main() sync* => null;", "main() async* => null;"],
+  },
+
+  // TODO(johnniwinther): Check for 'async' as identifier.
+  'ASYNC_KEYWORD_AS_IDENTIFIER': {
+    'id': 'VTWSMA',
+    'template':
+        "'#{keyword}' cannot be used as an identifier in a function body "
+        "marked with '#{modifier}'.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier or renaming the "
+        "identifier.",
+    'examples': [
+      """
+main() async {
+var await;
+}""",
+      """
+main() async* {
+var yield;
+}""",
+      """
+main() sync* {
+var yield;
+}"""
+    ],
+  },
+
+  'RETURN_IN_GENERATOR': {
+    'id': 'AWGUVF',
+    'template':
+        "'return' with a value is not allowed in a method body using the "
+        "'#{modifier}' modifier.",
+    'howToFix': "Try removing the value, replacing 'return' with 'yield' "
+        "or changing the method body modifier.",
+    'examples': [
+      """
+foo() async* { return 0; }
+main() => foo();
+""",
+      """
+foo() sync* { return 0; }
+main() => foo();
+"""
+    ],
+  },
+
+  'NATIVE_NOT_SUPPORTED': {
+    'id': 'QMMLUT',
+    'template': "'native' modifier is not supported.",
+    'howToFix': "Try removing the 'native' implementation or analyzing the "
+        "code with the --allow-native-extensions option.",
+    'examples': [
+      """
+main() native "Main";
+"""
+    ],
+  },
+
+  'DART_EXT_NOT_SUPPORTED': {
+    'id': 'JLPQFJ',
+    'template': "The 'dart-ext' scheme is not supported.",
+    'howToFix': "Try analyzing the code with the --allow-native-extensions "
+        "option.",
+    'examples': [
+      """
+import 'dart-ext:main';
+
+main() {}
+"""
+    ],
+  },
+
+  'LIBRARY_TAG_MUST_BE_FIRST': {
+    'id': 'JFUSRX',
+    'template':
+        "The library declaration should come before other declarations.",
+    'howToFix': "Try moving the declaration to the top of the file.",
+    'examples': [
+      """
+import 'dart:core';
+library foo;
+main() {}
+""",
+    ],
+  },
+
+  'ONLY_ONE_LIBRARY_TAG': {
+    'id': 'CCXFMY',
+    'template': "There can only be one library declaration.",
+    'howToFix': "Try removing all other library declarations.",
+    'examples': [
+      """
+library foo;
+library bar;
+main() {}
+""",
+      """
+library foo;
+import 'dart:core';
+library bar;
+main() {}
+""",
+    ],
+  },
+
+  'IMPORT_BEFORE_PARTS': {
+    'id': 'NSMOQI',
+    'template': "Import declarations should come before parts.",
+    'howToFix': "Try moving this import further up in the file.",
+    'examples': [
+      {
+        'main.dart': """
+library test.main;
+part 'part.dart';
+import 'dart:core';
+main() {}
+""",
+        'part.dart': """
+part of test.main;
+""",
+      }
+    ],
+  },
+
+  'EXPORT_BEFORE_PARTS': {
+    'id': 'KYJTTC',
+    'template': "Export declarations should come before parts.",
+    'howToFix': "Try moving this export further up in the file.",
+    'examples': [
+      {
+        'main.dart': """
+library test.main;
+part 'part.dart';
+export 'dart:core';
+main() {}
+""",
+        'part.dart': """
+part of test.main;
+""",
+      }
+    ],
+
+//////////////////////////////////////////////////////////////////////////////
+// Patch errors start.
+//////////////////////////////////////////////////////////////////////////////
+  },
+
+  'PATCH_RETURN_TYPE_MISMATCH': {
+    'id': 'DTOQDU',
+    'template': "Patch return type '#{patchReturnType}' does not match "
+        "'#{originReturnType}' on origin method '#{methodName}'.",
+  },
+
+  'PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH': {
+    'id': 'KJUUYC',
+    'template': "Required parameter count of patch method "
+        "(#{patchParameterCount}) does not match parameter count on origin "
+        "method '#{methodName}' (#{originParameterCount}).",
+  },
+
+  'PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH': {
+    'id': 'GUTGTE',
+    'template': "Optional parameter count of patch method "
+        "(#{patchParameterCount}) does not match parameter count on origin "
+        "method '#{methodName}' (#{originParameterCount}).",
+  },
+
+  'PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH': {
+    'id': 'MCHEIC',
+    'template': "Optional parameters of origin and patch method "
+        "'#{methodName}' must both be either named or positional.",
+  },
+
+  'PATCH_PARAMETER_MISMATCH': {
+    'id': 'XISHPB',
+    'template': "Patch method parameter '#{patchParameter}' does not match "
+        "'#{originParameter}' on origin method '#{methodName}'.",
+  },
+
+  'PATCH_PARAMETER_TYPE_MISMATCH': {
+    'id': 'UGRBYD',
+    'template': "Patch method parameter '#{parameterName}' type "
+        "'#{patchParameterType}' does not match '#{originParameterType}' on "
+        "origin method '#{methodName}'.",
+  },
+
+  'PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION': {
+    'id': 'WSNMKD',
+    'template': "External method without an implementation.",
+  },
+
+  'PATCH_POINT_TO_FUNCTION': {
+    'id': 'CAVBPN',
+    'template': "This is the function patch '#{functionName}'.",
+  },
+
+  'PATCH_POINT_TO_CLASS': {
+    'id': 'TWDLDX',
+    'template': "This is the class patch '#{className}'.",
+  },
+
+  'PATCH_POINT_TO_GETTER': {
+    'id': 'TRBBNY',
+    'template': "This is the getter patch '#{getterName}'.",
+  },
+
+  'PATCH_POINT_TO_SETTER': {
+    'id': 'DAXDLW',
+    'template': "This is the setter patch '#{setterName}'.",
+  },
+
+  'PATCH_POINT_TO_CONSTRUCTOR': {
+    'id': 'VYQISY',
+    'template': "This is the constructor patch '#{constructorName}'.",
+  },
+
+  'PATCH_POINT_TO_PARAMETER': {
+    'id': 'TFPAGO',
+    'template': "This is the patch parameter '#{parameterName}'.",
+  },
+
+  'PATCH_NON_EXISTING': {
+    'id': 'AWOACF',
+    'template': "Origin does not exist for patch '#{name}'.",
+  },
+
+  // TODO(ahe): Eventually, this error should be removed as it will be
+  // handled by the regular parser.
+  'PATCH_NONPATCHABLE': {
+    'id': 'WQEPJI',
+    'template': "Only classes and functions can be patched.",
+  },
+
+  'PATCH_NON_EXTERNAL': {
+    'id': 'MHLXNK',
+    'template': "Only external functions can be patched.",
+  },
+
+  'PATCH_NON_CLASS': {
+    'id': 'UIALAB',
+    'template': "Patching non-class with class patch '#{className}'.",
+  },
+
+  'PATCH_NON_GETTER': {
+    'id': 'VTNQCJ',
+    'template': "Cannot patch non-getter '#{name}' with getter patch.",
+  },
+
+  'PATCH_NO_GETTER': {
+    'id': 'XOPDHD',
+    'template': "No getter found for getter patch '#{getterName}'.",
+  },
+
+  'PATCH_NON_SETTER': {
+    'id': 'XBOMMN',
+    'template': "Cannot patch non-setter '#{name}' with setter patch.",
+  },
+
+  'PATCH_NO_SETTER': {
+    'id': 'YITARQ',
+    'template': "No setter found for setter patch '#{setterName}'.",
+  },
+
+  'PATCH_NON_CONSTRUCTOR': {
+    'id': 'TWAEQV',
+    'template': "Cannot patch non-constructor with constructor patch "
+        "'#{constructorName}'.",
+  },
+
+  'PATCH_NON_FUNCTION': {
+    'id': 'EDXBPI',
+    'template': "Cannot patch non-function with function patch "
+        "'#{functionName}'.",
+  },
+
+  'INJECTED_PUBLIC_MEMBER': {
+    'id': 'JGMXMI',
+    'template': "Non-patch members in patch libraries must be private.",
+  },
+
+  'EXTERNAL_WITH_BODY': {
+    'id': 'GAVMSQ',
+    'template':
+        "External function '#{functionName}' cannot have a function body.",
+    'options': ["--output-type=dart"],
+    'howToFix': "Try removing the 'external' modifier or the function body.",
+    'examples': [
+      """
+external foo() => 0;
+main() => foo();
+""",
+      """
+external foo() {}
+main() => foo();
+"""
+    ],
+
+//////////////////////////////////////////////////////////////////////////////
+// Patch errors end.
+//////////////////////////////////////////////////////////////////////////////
+  },
+
+  'EXPERIMENTAL_ASSERT_MESSAGE': {
+    'id': 'NENGIS',
+    'template': "Experimental language feature 'assertion with message'"
+        " is not supported.",
+    'howToFix':
+        "Use option '--assert-message' to use assertions with messages.",
+    'examples': [
+      r'''
+main() {
+int n = -7;
+assert(n > 0, 'must be positive: $n');
+}
+'''
+    ],
+  },
+
+  'IMPORT_EXPERIMENTAL_MIRRORS': {
+    'id': 'SCJYPH',
+    'template': '''
+
+****************************************************************
+* WARNING: dart:mirrors support in dart2js is experimental,
+*          and not recommended.
+*          This implementation of mirrors is incomplete,
+*          and often greatly increases the size of the generated
+*          JavaScript code.
+*
+* Your app imports dart:mirrors via:'''
+        '''
+$IMPORT_EXPERIMENTAL_MIRRORS_PADDING#{importChain}
+*
+* You can disable this message by using the --enable-experimental-mirrors
+* command-line flag.
+*
+* To learn what to do next, please visit:
+*    http://dartlang.org/dart2js-reflection
+****************************************************************
+''',
+  },
+
+  'DISALLOWED_LIBRARY_IMPORT': {
+    'id': 'OCSFJU',
+    'template': '''
+Your app imports the unsupported library '#{uri}' via:
+'''
+        '''
+$DISALLOWED_LIBRARY_IMPORT_PADDING#{importChain}
+
+Use the --categories option to support import of '#{uri}'.
+''',
+  },
+
+  'MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND': {
+    'id': 'JBTRRM',
+    'template': """
+dart:mirrors library is not supported when using this backend.
+
+Your app imports dart:mirrors via:"""
+        """
+$MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING#{importChain}""",
+  },
+
+  'CALL_NOT_SUPPORTED_ON_NATIVE_CLASS': {
+    'id': 'HAULDW',
+    'template': "Non-supported 'call' member on a native class, or a "
+        "subclass of a native class.",
+  },
+
+  'DIRECTLY_THROWING_NSM': {
+    'id': 'XLTPCS',
+    'template': "This 'noSuchMethod' implementation is guaranteed to throw an "
+        "exception. The generated code will be smaller if it is "
+        "rewritten.",
+    'howToFix': "Rewrite to "
+        "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'.",
+  },
+
+  'COMPLEX_THROWING_NSM': {
+    'id': 'PLCXVX',
+    'template': "This 'noSuchMethod' implementation is guaranteed to throw an "
+        "exception. The generated code will be smaller and the compiler "
+        "will be able to perform more optimizations if it is rewritten.",
+    'howToFix': "Rewrite to "
+        "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'.",
+  },
+
+  'COMPLEX_RETURNING_NSM': {
+    'id': 'HUTCTQ',
+    'template': "Overriding 'noSuchMethod' causes the compiler to generate "
+        "more code and prevents the compiler from doing some optimizations.",
+    'howToFix': "Consider removing this 'noSuchMethod' implementation."
+  },
+
+  'UNRECOGNIZED_VERSION_OF_LOOKUP_MAP': {
+    'id': 'OVAFEW',
+    'template': "Unsupported version of package:lookup_map.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX
+  },
+};
diff --git a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
index e4bd449..8d5baac 100644
--- a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
+++ b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
@@ -16,8 +16,10 @@
   /// Emit terse diagnostics without howToFix.
   final bool terseDiagnostics;
 
-  /// If `true`, warnings and hints not from user code are reported.
-  final bool showPackageWarnings;
+  /// List of packages for which warnings and hints are reported. If `null`,
+  /// no package warnings or hints are reported. If empty, all warnings and
+  /// hints are reported.
+  final List<String> _shownPackageWarnings;
 
   /// If `true`, warnings are not reported.
   final bool suppressWarnings;
@@ -33,7 +35,29 @@
     this.fatalWarnings: false,
     this.suppressHints: false,
     this.terseDiagnostics: false,
-    this.showPackageWarnings: false});
+    List<String> shownPackageWarnings: null})
+      : _shownPackageWarnings = shownPackageWarnings;
+
+
+  /// Returns `true` if warnings and hints are shown for all packages.
+  bool get showAllPackageWarnings {
+    return _shownPackageWarnings != null && _shownPackageWarnings.isEmpty;
+  }
+
+  /// Returns `true` if warnings and hints are hidden for all packages.
+  bool get hidePackageWarnings => _shownPackageWarnings == null;
+
+  /// Returns `true` if warnings should be should for [uri].
+  bool showPackageWarningsFor(Uri uri) {
+    if (showAllPackageWarnings) {
+      return true;
+    }
+    if (_shownPackageWarnings != null) {
+      return uri.scheme == 'package' &&
+          _shownPackageWarnings.contains(uri.pathSegments.first);
+    }
+    return false;
+  }
 }
 
 // TODO(johnniwinther): Rename and cleanup this interface. Add severity enum.
@@ -45,6 +69,11 @@
 
   internalError(Spannable spannable, message);
 
+  /// Creates a [SourceSpan] for [node] in scope of the current element.
+  ///
+  /// If [node] is a [Node] or [Token] we assert in checked mode that the
+  /// corresponding tokens can be found within the tokens of the current
+  /// element.
   SourceSpan spanFromSpannable(Spannable node);
 
   void reportErrorMessage(
@@ -85,10 +114,8 @@
   void reportInfo(Spannable node, MessageKind errorCode,
                   [Map arguments = const {}]);
 
-  // TODO(ahe): We should not expose this here.  Perhaps a
-  // [SourceSpan] should implement [Spannable], and we should have a
-  // way to construct a [SourceSpan] from a [Spannable] and an
-  // [Element].
+  /// Set current element of this reporter to [element]. This is used for
+  /// creating [SourceSpan] in [spanFromSpannable].
   withCurrentElement(Element element, f());
 
   DiagnosticMessage createMessage(
diff --git a/pkg/compiler/lib/src/diagnostics/invariant.dart b/pkg/compiler/lib/src/diagnostics/invariant.dart
index b6d4d0f..349d89b 100644
--- a/pkg/compiler/lib/src/diagnostics/invariant.dart
+++ b/pkg/compiler/lib/src/diagnostics/invariant.dart
@@ -48,6 +48,10 @@
   }
   if (condition is Function){
     condition = condition();
+    if (condition is String) {
+      message = condition;
+      condition = false;
+    }
   }
   if (!condition) {
     if (message is Function) {
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 900ef01..b529e1c 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -2,77 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-
-/**
- * The messages in this file should meet the following guide lines:
- *
- * 1. The message should be a complete sentence starting with an uppercase
- * letter, and ending with a period.
- *
- * 2. Reserved words and embedded identifiers should be in single quotes, so
- * prefer double quotes for the complete message. For example, "The
- * class '#{className}' can't use 'super'." Notice that the word 'class' in the
- * preceding message is not quoted as it refers to the concept 'class', not the
- * reserved word. On the other hand, 'super' refers to the reserved word. Do
- * not quote 'null' and numeric literals.
- *
- * 3. Do not try to compose messages, as it can make translating them hard.
- *
- * 4. Try to keep the error messages short, but informative.
- *
- * 5. Use simple words and terminology, assume the reader of the message
- * doesn't have an advanced degree in math, and that English is not the
- * reader's native language. Do not assume any formal computer science
- * training. For example, do not use Latin abbreviations (prefer "that is" over
- * "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
- * only if" and "iff", that level of precision is unnecessary.
- *
- * 6. Prefer contractions when they are in common use, for example, prefer
- * "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
- * off-putting to people new to programming.
- *
- * 7. Use common terminology, preferably from the Dart Language
- * Specification. This increases the user's chance of finding a good
- * explanation on the web.
- *
- * 8. Do not try to be cute or funny. It is extremely frustrating to work on a
- * product that crashes with a "tongue-in-cheek" message, especially if you did
- * not want to use this product to begin with.
- *
- * 9. Do not lie, that is, do not write error messages containing phrases like
- * "can't happen".  If the user ever saw this message, it would be a
- * lie. Prefer messages like: "Internal error: This function should not be
- * called when 'x' is null.".
- *
- * 10. Prefer to not use imperative tone. That is, the message should not sound
- * accusing or like it is ordering the user around. The computer should
- * describe the problem, not criticize for violating the specification.
- *
- * Other things to keep in mind:
- *
- * An INFO message should always be preceded by a non-INFO message, and the
- * INFO messages are additional details about the preceding non-INFO
- * message. For example, consider duplicated elements. First report a WARNING
- * or ERROR about the duplicated element, and then report an INFO about the
- * location of the existing element.
- *
- * Generally, we want to provide messages that consists of three sentences:
- * 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
- * combine the first two in [template] and the last in [howToFix].
- */
-
 library dart2js.messages;
 
-import '../tokens/token.dart' show
-    ErrorToken,
-    Token;
+import 'package:dart_messages/shared_messages.dart' as shared_messages;
 
-import 'invariant.dart' show
-    invariant;
-import 'spannable.dart' show
-    CURRENT_ELEMENT_SPANNABLE;
+import '../tokens/token.dart' show ErrorToken, Token;
 
-const DONT_KNOW_HOW_TO_FIX = "Computer says no!";
+import 'invariant.dart' show invariant;
+import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
+
+import 'dart2js_messages.dart' as dart2js_messages;
 
 /// Keys for the [MessageTemplate]s.
 enum MessageKind {
@@ -107,6 +46,7 @@
   CANNOT_EXTEND_ENUM,
   CANNOT_EXTEND_MALFORMED,
   CANNOT_FIND_CONSTRUCTOR,
+  CANNOT_FIND_UNNAMED_CONSTRUCTOR,
   CANNOT_IMPLEMENT,
   CANNOT_IMPLEMENT_ENUM,
   CANNOT_IMPLEMENT_MALFORMED,
@@ -145,6 +85,7 @@
   CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
   CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
   CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD,
+  CONST_LOOP_VARIABLE,
   CONST_MAP_KEY_OVERRIDES_EQUALS,
   CONST_WITHOUT_INITIALIZER,
   CONSTRUCTOR_CALL_EXPECTED,
@@ -232,11 +173,13 @@
   IMPORT_BEFORE_PARTS,
   IMPORT_EXPERIMENTAL_MIRRORS,
   IMPORT_PART_OF,
+  IMPORT_PART_OF_HERE,
   IMPORTED_HERE,
   INHERIT_GETTER_AND_METHOD,
   INHERITED_EXPLICIT_GETTER,
   INHERITED_IMPLICIT_GETTER,
   INHERITED_METHOD,
+  INJECTED_PUBLIC_MEMBER,
   INIT_STATIC_FIELD,
   INITIALIZING_FORMAL_NOT_ALLOWED,
   INSTANCE_STATIC_SAME_NAME,
@@ -244,7 +187,9 @@
   INTERNAL_LIBRARY,
   INTERNAL_LIBRARY_FROM,
   INVALID_ARGUMENT_AFTER_NAMED,
+  INVALID_AWAIT,
   INVALID_AWAIT_FOR,
+  INVALID_AWAIT_FOR_IN,
   INVALID_BREAK,
   INVALID_CASE_DEFAULT,
   INVALID_CONSTRUCTOR_ARGUMENTS,
@@ -252,6 +197,8 @@
   INVALID_CONTINUE,
   INVALID_FOR_IN,
   INVALID_INITIALIZER,
+  INVALID_METADATA,
+  INVALID_METADATA_GENERIC,
   INVALID_OVERRIDDEN_FIELD,
   INVALID_OVERRIDDEN_GETTER,
   INVALID_OVERRIDDEN_METHOD,
@@ -275,14 +222,17 @@
   INVALID_UNNAMED_CONSTRUCTOR_NAME,
   INVALID_URI,
   INVALID_USE_OF_SUPER,
+  INVALID_YIELD,
   JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS,
   JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
   JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
   JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS,
+  JS_PLACEHOLDER_CAPTURE,
   LIBRARY_NAME_MISMATCH,
   LIBRARY_NOT_FOUND,
   LIBRARY_NOT_SUPPORTED,
   LIBRARY_TAG_MUST_BE_FIRST,
+  MAIN_HAS_PART_OF,
   MAIN_NOT_A_FUNCTION,
   MAIN_WITH_EXTRA_PARAMETER,
   MALFORMED_STRING_LITERAL,
@@ -402,12 +352,14 @@
   SETTER_NOT_FOUND_IN_SUPER,
   STATIC_FUNCTION_BLOAT,
   STRING_EXPECTED,
+  SUPER_CALL_TO_FACTORY,
   SUPER_INITIALIZER_IN_OBJECT,
   SWITCH_CASE_FORBIDDEN,
   SWITCH_CASE_TYPES_NOT_EQUAL,
   SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
   SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
   TERNARY_OPERATOR_BAD_ARITY,
+  THIS_CALL_TO_FACTORY,
   THIS_IS_THE_DECLARATION,
   THIS_IS_THE_METHOD,
   THIS_IS_THE_PART_OF_TAG,
@@ -454,6 +406,463 @@
   YIELDING_MODIFIER_ON_ARROW_BODY,
 }
 
+const _KIND_TO_STRING_MAP = const <MessageKind, String>{
+  MessageKind.ABSTRACT_CLASS_INSTANTIATION: "ABSTRACT_CLASS_INSTANTIATION",
+  MessageKind.ABSTRACT_GETTER: "ABSTRACT_GETTER",
+  MessageKind.ABSTRACT_METHOD: "ABSTRACT_METHOD",
+  MessageKind.ABSTRACT_SETTER: "ABSTRACT_SETTER",
+  MessageKind.ACCESSED_IN_CLOSURE: "ACCESSED_IN_CLOSURE",
+  MessageKind.ACCESSED_IN_CLOSURE_HERE: "ACCESSED_IN_CLOSURE_HERE",
+  MessageKind.ADDITIONAL_ARGUMENT: "ADDITIONAL_ARGUMENT",
+  MessageKind.ADDITIONAL_TYPE_ARGUMENT: "ADDITIONAL_TYPE_ARGUMENT",
+  MessageKind.ALREADY_INITIALIZED: "ALREADY_INITIALIZED",
+  MessageKind.AMBIGUOUS_LOCATION: "AMBIGUOUS_LOCATION",
+  MessageKind.AMBIGUOUS_REEXPORT: "AMBIGUOUS_REEXPORT",
+  MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS:
+      "ASSERT_IS_GIVEN_NAMED_ARGUMENTS",
+  MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER: "ASSIGNING_FINAL_FIELD_IN_SUPER",
+  MessageKind.ASSIGNING_METHOD: "ASSIGNING_METHOD",
+  MessageKind.ASSIGNING_METHOD_IN_SUPER: "ASSIGNING_METHOD_IN_SUPER",
+  MessageKind.ASSIGNING_TYPE: "ASSIGNING_TYPE",
+  MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER: "ASYNC_KEYWORD_AS_IDENTIFIER",
+  MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD:
+      "ASYNC_MODIFIER_ON_ABSTRACT_METHOD",
+  MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR: "ASYNC_MODIFIER_ON_CONSTRUCTOR",
+  MessageKind.ASYNC_MODIFIER_ON_SETTER: "ASYNC_MODIFIER_ON_SETTER",
+  MessageKind.AWAIT_MEMBER_NOT_FOUND: "AWAIT_MEMBER_NOT_FOUND",
+  MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE:
+      "AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE",
+  MessageKind.BAD_INPUT_CHARACTER: "BAD_INPUT_CHARACTER",
+  MessageKind.BEFORE_TOP_LEVEL: "BEFORE_TOP_LEVEL",
+  MessageKind.BINARY_OPERATOR_BAD_ARITY: "BINARY_OPERATOR_BAD_ARITY",
+  MessageKind.BODY_EXPECTED: "BODY_EXPECTED",
+  MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS:
+      "CALL_NOT_SUPPORTED_ON_NATIVE_CLASS",
+  MessageKind.CANNOT_EXTEND: "CANNOT_EXTEND",
+  MessageKind.CANNOT_EXTEND_ENUM: "CANNOT_EXTEND_ENUM",
+  MessageKind.CANNOT_EXTEND_MALFORMED: "CANNOT_EXTEND_MALFORMED",
+  MessageKind.CANNOT_FIND_CONSTRUCTOR: "CANNOT_FIND_CONSTRUCTOR",
+  MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR:
+      "CANNOT_FIND_UNNAMED_CONSTRUCTOR",
+  MessageKind.CANNOT_IMPLEMENT: "CANNOT_IMPLEMENT",
+  MessageKind.CANNOT_IMPLEMENT_ENUM: "CANNOT_IMPLEMENT_ENUM",
+  MessageKind.CANNOT_IMPLEMENT_MALFORMED: "CANNOT_IMPLEMENT_MALFORMED",
+  MessageKind.CANNOT_INSTANTIATE_ENUM: "CANNOT_INSTANTIATE_ENUM",
+  MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE:
+      "CANNOT_INSTANTIATE_TYPE_VARIABLE",
+  MessageKind.CANNOT_INSTANTIATE_TYPEDEF: "CANNOT_INSTANTIATE_TYPEDEF",
+  MessageKind.CANNOT_MIXIN: "CANNOT_MIXIN",
+  MessageKind.CANNOT_MIXIN_ENUM: "CANNOT_MIXIN_ENUM",
+  MessageKind.CANNOT_MIXIN_MALFORMED: "CANNOT_MIXIN_MALFORMED",
+  MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD:
+      "CANNOT_OVERRIDE_FIELD_WITH_METHOD",
+  MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT:
+      "CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT",
+  MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD:
+      "CANNOT_OVERRIDE_GETTER_WITH_METHOD",
+  MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT:
+      "CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT",
+  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD:
+      "CANNOT_OVERRIDE_METHOD_WITH_FIELD",
+  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT:
+      "CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT",
+  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER:
+      "CANNOT_OVERRIDE_METHOD_WITH_GETTER",
+  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT:
+      "CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT",
+  MessageKind.CANNOT_RESOLVE: "CANNOT_RESOLVE",
+  MessageKind.CANNOT_RESOLVE_AWAIT: "CANNOT_RESOLVE_AWAIT",
+  MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE:
+      "CANNOT_RESOLVE_AWAIT_IN_CLOSURE",
+  MessageKind.CANNOT_RESOLVE_CONSTRUCTOR: "CANNOT_RESOLVE_CONSTRUCTOR",
+  MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT:
+      "CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT",
+  MessageKind.CANNOT_RESOLVE_GETTER: "CANNOT_RESOLVE_GETTER",
+  MessageKind.CANNOT_RESOLVE_IN_INITIALIZER: "CANNOT_RESOLVE_IN_INITIALIZER",
+  MessageKind.CANNOT_RESOLVE_SETTER: "CANNOT_RESOLVE_SETTER",
+  MessageKind.CANNOT_RESOLVE_TYPE: "CANNOT_RESOLVE_TYPE",
+  MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR: "CANNOT_RETURN_FROM_CONSTRUCTOR",
+  MessageKind.CLASS_NAME_EXPECTED: "CLASS_NAME_EXPECTED",
+  MessageKind.COMPILER_CRASHED: "COMPILER_CRASHED",
+  MessageKind.COMPLEX_RETURNING_NSM: "COMPLEX_RETURNING_NSM",
+  MessageKind.COMPLEX_THROWING_NSM: "COMPLEX_THROWING_NSM",
+  MessageKind.CONSIDER_ANALYZE_ALL: "CONSIDER_ANALYZE_ALL",
+  MessageKind.CONST_CALLS_NON_CONST: "CONST_CALLS_NON_CONST",
+  MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT:
+      "CONST_CALLS_NON_CONST_FOR_IMPLICIT",
+  MessageKind.CONST_CONSTRUCTOR_HAS_BODY: "CONST_CONSTRUCTOR_HAS_BODY",
+  MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS:
+      "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS",
+  MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR:
+      "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR",
+  MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD:
+      "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD",
+  MessageKind.CONST_LOOP_VARIABLE: "CONST_LOOP_VARIABLE",
+  MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS: "CONST_MAP_KEY_OVERRIDES_EQUALS",
+  MessageKind.CONST_WITHOUT_INITIALIZER: "CONST_WITHOUT_INITIALIZER",
+  MessageKind.CONSTRUCTOR_CALL_EXPECTED: "CONSTRUCTOR_CALL_EXPECTED",
+  MessageKind.CONSTRUCTOR_IS_NOT_CONST: "CONSTRUCTOR_IS_NOT_CONST",
+  MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE: "CONSTRUCTOR_WITH_RETURN_TYPE",
+  MessageKind.CYCLIC_CLASS_HIERARCHY: "CYCLIC_CLASS_HIERARCHY",
+  MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS: "CYCLIC_COMPILE_TIME_CONSTANTS",
+  MessageKind.CYCLIC_REDIRECTING_FACTORY: "CYCLIC_REDIRECTING_FACTORY",
+  MessageKind.CYCLIC_TYPE_VARIABLE: "CYCLIC_TYPE_VARIABLE",
+  MessageKind.CYCLIC_TYPEDEF: "CYCLIC_TYPEDEF",
+  MessageKind.CYCLIC_TYPEDEF_ONE: "CYCLIC_TYPEDEF_ONE",
+  MessageKind.DART_EXT_NOT_SUPPORTED: "DART_EXT_NOT_SUPPORTED",
+  MessageKind.DEFERRED_COMPILE_TIME_CONSTANT: "DEFERRED_COMPILE_TIME_CONSTANT",
+  MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION:
+      "DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION",
+  MessageKind.DEFERRED_LIBRARY_DART_2_DART: "DEFERRED_LIBRARY_DART_2_DART",
+  MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX:
+      "DEFERRED_LIBRARY_DUPLICATE_PREFIX",
+  MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX:
+      "DEFERRED_LIBRARY_WITHOUT_PREFIX",
+  MessageKind.DEFERRED_OLD_SYNTAX: "DEFERRED_OLD_SYNTAX",
+  MessageKind.DEFERRED_TYPE_ANNOTATION: "DEFERRED_TYPE_ANNOTATION",
+  MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX:
+      "DEPRECATED_TYPEDEF_MIXIN_SYNTAX",
+  MessageKind.DIRECTLY_THROWING_NSM: "DIRECTLY_THROWING_NSM",
+  MessageKind.DISALLOWED_LIBRARY_IMPORT: "DISALLOWED_LIBRARY_IMPORT",
+  MessageKind.DUPLICATE_DEFINITION: "DUPLICATE_DEFINITION",
+  MessageKind.DUPLICATE_EXPORT: "DUPLICATE_EXPORT",
+  MessageKind.DUPLICATE_EXPORT_CONT: "DUPLICATE_EXPORT_CONT",
+  MessageKind.DUPLICATE_EXPORT_DECL: "DUPLICATE_EXPORT_DECL",
+  MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS: "DUPLICATE_EXTENDS_IMPLEMENTS",
+  MessageKind.DUPLICATE_IMPLEMENTS: "DUPLICATE_IMPLEMENTS",
+  MessageKind.DUPLICATE_IMPORT: "DUPLICATE_IMPORT",
+  MessageKind.DUPLICATE_INITIALIZER: "DUPLICATE_INITIALIZER",
+  MessageKind.DUPLICATE_LABEL: "DUPLICATE_LABEL",
+  MessageKind.DUPLICATE_SUPER_INITIALIZER: "DUPLICATE_SUPER_INITIALIZER",
+  MessageKind.DUPLICATE_TYPE_VARIABLE_NAME: "DUPLICATE_TYPE_VARIABLE_NAME",
+  MessageKind.DUPLICATED_LIBRARY_NAME: "DUPLICATED_LIBRARY_NAME",
+  MessageKind.DUPLICATED_LIBRARY_RESOURCE: "DUPLICATED_LIBRARY_RESOURCE",
+  MessageKind.DUPLICATED_PART_OF: "DUPLICATED_PART_OF",
+  MessageKind.DUPLICATED_RESOURCE: "DUPLICATED_RESOURCE",
+  MessageKind.EMPTY_CATCH_DECLARATION: "EMPTY_CATCH_DECLARATION",
+  MessageKind.EMPTY_ENUM_DECLARATION: "EMPTY_ENUM_DECLARATION",
+  MessageKind.EMPTY_HIDE: "EMPTY_HIDE",
+  MessageKind.EQUAL_MAP_ENTRY_KEY: "EQUAL_MAP_ENTRY_KEY",
+  MessageKind.EMPTY_SHOW: "EMPTY_SHOW",
+  MessageKind.EXISTING_DEFINITION: "EXISTING_DEFINITION",
+  MessageKind.EXISTING_LABEL: "EXISTING_LABEL",
+  MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD:
+      "EXPECTED_IDENTIFIER_NOT_RESERVED_WORD",
+  MessageKind.EXPERIMENTAL_ASSERT_MESSAGE: "EXPERIMENTAL_ASSERT_MESSAGE",
+  MessageKind.EXPONENT_MISSING: "EXPONENT_MISSING",
+  MessageKind.EXPORT_BEFORE_PARTS: "EXPORT_BEFORE_PARTS",
+  MessageKind.EXTERNAL_WITH_BODY: "EXTERNAL_WITH_BODY",
+  MessageKind.EXTRA_CATCH_DECLARATION: "EXTRA_CATCH_DECLARATION",
+  MessageKind.EXTRA_FORMALS: "EXTRA_FORMALS",
+  MessageKind.EXTRANEOUS_MODIFIER: "EXTRANEOUS_MODIFIER",
+  MessageKind.EXTRANEOUS_MODIFIER_REPLACE: "EXTRANEOUS_MODIFIER_REPLACE",
+  MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY:
+      "FACTORY_REDIRECTION_IN_NON_FACTORY",
+  MessageKind.FINAL_FUNCTION_TYPE_PARAMETER: "FINAL_FUNCTION_TYPE_PARAMETER",
+  MessageKind.FINAL_WITHOUT_INITIALIZER: "FINAL_WITHOUT_INITIALIZER",
+  MessageKind.FORIN_NOT_ASSIGNABLE: "FORIN_NOT_ASSIGNABLE",
+  MessageKind.FORMAL_DECLARED_CONST: "FORMAL_DECLARED_CONST",
+  MessageKind.FORMAL_DECLARED_STATIC: "FORMAL_DECLARED_STATIC",
+  MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT:
+      "FUNCTION_TYPE_FORMAL_WITH_DEFAULT",
+  MessageKind.FUNCTION_WITH_INITIALIZER: "FUNCTION_WITH_INITIALIZER",
+  MessageKind.GENERIC: "GENERIC",
+  MessageKind.GETTER_MISMATCH: "GETTER_MISMATCH",
+  MessageKind.GETTER_NOT_FOUND: "GETTER_NOT_FOUND",
+  MessageKind.HEX_DIGIT_EXPECTED: "HEX_DIGIT_EXPECTED",
+  MessageKind.HIDDEN_HINTS: "HIDDEN_HINTS",
+  MessageKind.HIDDEN_IMPLICIT_IMPORT: "HIDDEN_IMPLICIT_IMPORT",
+  MessageKind.HIDDEN_IMPORT: "HIDDEN_IMPORT",
+  MessageKind.HIDDEN_WARNINGS: "HIDDEN_WARNINGS",
+  MessageKind.HIDDEN_WARNINGS_HINTS: "HIDDEN_WARNINGS_HINTS",
+  MessageKind.IF_NULL_ASSIGNING_TYPE: "IF_NULL_ASSIGNING_TYPE",
+  MessageKind.ILLEGAL_CONST_FIELD_MODIFIER: "ILLEGAL_CONST_FIELD_MODIFIER",
+  MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS: "ILLEGAL_CONSTRUCTOR_MODIFIERS",
+  MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER: "ILLEGAL_FINAL_METHOD_MODIFIER",
+  MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS:
+      "ILLEGAL_MIXIN_APPLICATION_MODIFIERS",
+  MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR: "ILLEGAL_MIXIN_CONSTRUCTOR",
+  MessageKind.ILLEGAL_MIXIN_CYCLE: "ILLEGAL_MIXIN_CYCLE",
+  MessageKind.ILLEGAL_MIXIN_OBJECT: "ILLEGAL_MIXIN_OBJECT",
+  MessageKind.ILLEGAL_MIXIN_SUPER_USE: "ILLEGAL_MIXIN_SUPER_USE",
+  MessageKind.ILLEGAL_MIXIN_SUPERCLASS: "ILLEGAL_MIXIN_SUPERCLASS",
+  MessageKind.ILLEGAL_MIXIN_WITH_SUPER: "ILLEGAL_MIXIN_WITH_SUPER",
+  MessageKind.ILLEGAL_SETTER_FORMALS: "ILLEGAL_SETTER_FORMALS",
+  MessageKind.ILLEGAL_STATIC: "ILLEGAL_STATIC",
+  MessageKind.ILLEGAL_SUPER_SEND: "ILLEGAL_SUPER_SEND",
+  MessageKind.IMPORT_BEFORE_PARTS: "IMPORT_BEFORE_PARTS",
+  MessageKind.IMPORT_EXPERIMENTAL_MIRRORS: "IMPORT_EXPERIMENTAL_MIRRORS",
+  MessageKind.IMPORT_PART_OF: "IMPORT_PART_OF",
+  MessageKind.IMPORT_PART_OF_HERE: "IMPORT_PART_OF_HERE",
+  MessageKind.IMPORTED_HERE: "IMPORTED_HERE",
+  MessageKind.INHERIT_GETTER_AND_METHOD: "INHERIT_GETTER_AND_METHOD",
+  MessageKind.INHERITED_EXPLICIT_GETTER: "INHERITED_EXPLICIT_GETTER",
+  MessageKind.INHERITED_IMPLICIT_GETTER: "INHERITED_IMPLICIT_GETTER",
+  MessageKind.INHERITED_METHOD: "INHERITED_METHOD",
+  MessageKind.INJECTED_PUBLIC_MEMBER: "INJECTED_PUBLIC_MEMBER",
+  MessageKind.INIT_STATIC_FIELD: "INIT_STATIC_FIELD",
+  MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED:
+      "INITIALIZING_FORMAL_NOT_ALLOWED",
+  MessageKind.INSTANCE_STATIC_SAME_NAME: "INSTANCE_STATIC_SAME_NAME",
+  MessageKind.INSTANCE_STATIC_SAME_NAME_CONT: "INSTANCE_STATIC_SAME_NAME_CONT",
+  MessageKind.INTERNAL_LIBRARY: "INTERNAL_LIBRARY",
+  MessageKind.INTERNAL_LIBRARY_FROM: "INTERNAL_LIBRARY_FROM",
+  MessageKind.INVALID_ARGUMENT_AFTER_NAMED: "INVALID_ARGUMENT_AFTER_NAMED",
+  MessageKind.INVALID_AWAIT: "INVALID_AWAIT",
+  MessageKind.INVALID_AWAIT_FOR: "INVALID_AWAIT_FOR",
+  MessageKind.INVALID_AWAIT_FOR_IN: "INVALID_AWAIT_FOR_IN",
+  MessageKind.INVALID_BREAK: "INVALID_BREAK",
+  MessageKind.INVALID_CASE_DEFAULT: "INVALID_CASE_DEFAULT",
+  MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS: "INVALID_CONSTRUCTOR_ARGUMENTS",
+  MessageKind.INVALID_CONSTRUCTOR_NAME: "INVALID_CONSTRUCTOR_NAME",
+  MessageKind.INVALID_CONTINUE: "INVALID_CONTINUE",
+  MessageKind.INVALID_FOR_IN: "INVALID_FOR_IN",
+  MessageKind.INVALID_INITIALIZER: "INVALID_INITIALIZER",
+  MessageKind.INVALID_METADATA: "INVALID_METADATA",
+  MessageKind.INVALID_METADATA_GENERIC: "INVALID_METADATA_GENERIC",
+  MessageKind.INVALID_OVERRIDDEN_FIELD: "INVALID_OVERRIDDEN_FIELD",
+  MessageKind.INVALID_OVERRIDDEN_GETTER: "INVALID_OVERRIDDEN_GETTER",
+  MessageKind.INVALID_OVERRIDDEN_METHOD: "INVALID_OVERRIDDEN_METHOD",
+  MessageKind.INVALID_OVERRIDDEN_SETTER: "INVALID_OVERRIDDEN_SETTER",
+  MessageKind.INVALID_OVERRIDE_FIELD: "INVALID_OVERRIDE_FIELD",
+  MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER:
+      "INVALID_OVERRIDE_FIELD_WITH_GETTER",
+  MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER:
+      "INVALID_OVERRIDE_FIELD_WITH_SETTER",
+  MessageKind.INVALID_OVERRIDE_GETTER: "INVALID_OVERRIDE_GETTER",
+  MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD:
+      "INVALID_OVERRIDE_GETTER_WITH_FIELD",
+  MessageKind.INVALID_OVERRIDE_METHOD: "INVALID_OVERRIDE_METHOD",
+  MessageKind.INVALID_OVERRIDE_SETTER: "INVALID_OVERRIDE_SETTER",
+  MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD:
+      "INVALID_OVERRIDE_SETTER_WITH_FIELD",
+  MessageKind.INVALID_PACKAGE_CONFIG: "INVALID_PACKAGE_CONFIG",
+  MessageKind.INVALID_PACKAGE_URI: "INVALID_PACKAGE_URI",
+  MessageKind.INVALID_PARAMETER: "INVALID_PARAMETER",
+  MessageKind.INVALID_RECEIVER_IN_INITIALIZER:
+      "INVALID_RECEIVER_IN_INITIALIZER",
+  MessageKind.INVALID_SOURCE_FILE_LOCATION: "INVALID_SOURCE_FILE_LOCATION",
+  MessageKind.INVALID_SYMBOL: "INVALID_SYMBOL",
+  MessageKind.INVALID_SYNC_MODIFIER: "INVALID_SYNC_MODIFIER",
+  MessageKind.INVALID_TYPE_VARIABLE_BOUND: "INVALID_TYPE_VARIABLE_BOUND",
+  MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME:
+      "INVALID_UNNAMED_CONSTRUCTOR_NAME",
+  MessageKind.INVALID_URI: "INVALID_URI",
+  MessageKind.INVALID_USE_OF_SUPER: "INVALID_USE_OF_SUPER",
+  MessageKind.INVALID_YIELD: "INVALID_YIELD",
+  MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS:
+      "JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS",
+  MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER:
+      "JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER",
+  MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS:
+      "JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS",
+  MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS:
+      "JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS",
+  MessageKind.JS_PLACEHOLDER_CAPTURE: "JS_PLACEHOLDER_CAPTURE",
+  MessageKind.LIBRARY_NAME_MISMATCH: "LIBRARY_NAME_MISMATCH",
+  MessageKind.LIBRARY_NOT_FOUND: "LIBRARY_NOT_FOUND",
+  MessageKind.LIBRARY_NOT_SUPPORTED: "LIBRARY_NOT_SUPPORTED",
+  MessageKind.LIBRARY_TAG_MUST_BE_FIRST: "LIBRARY_TAG_MUST_BE_FIRST",
+  MessageKind.MAIN_HAS_PART_OF: "MAIN_HAS_PART_OF",
+  MessageKind.MAIN_NOT_A_FUNCTION: "MAIN_NOT_A_FUNCTION",
+  MessageKind.MAIN_WITH_EXTRA_PARAMETER: "MAIN_WITH_EXTRA_PARAMETER",
+  MessageKind.MALFORMED_STRING_LITERAL: "MALFORMED_STRING_LITERAL",
+  MessageKind.MEMBER_NOT_FOUND: "MEMBER_NOT_FOUND",
+  MessageKind.MEMBER_NOT_STATIC: "MEMBER_NOT_STATIC",
+  MessageKind.MEMBER_USES_CLASS_NAME: "MEMBER_USES_CLASS_NAME",
+  MessageKind.METHOD_NOT_FOUND: "METHOD_NOT_FOUND",
+  MessageKind.MINUS_OPERATOR_BAD_ARITY: "MINUS_OPERATOR_BAD_ARITY",
+  MessageKind.MIRROR_BLOAT: "MIRROR_BLOAT",
+  MessageKind.MIRROR_IMPORT: "MIRROR_IMPORT",
+  MessageKind.MIRROR_IMPORT_NO_USAGE: "MIRROR_IMPORT_NO_USAGE",
+  MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT: "MIRRORS_CANNOT_FIND_IN_ELEMENT",
+  MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY:
+      "MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY",
+  MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY:
+      "MIRRORS_CANNOT_RESOLVE_IN_LIBRARY",
+  MessageKind.MIRRORS_EXPECTED_STRING: "MIRRORS_EXPECTED_STRING",
+  MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST:
+      "MIRRORS_EXPECTED_STRING_OR_LIST",
+  MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE:
+      "MIRRORS_EXPECTED_STRING_OR_TYPE",
+  MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST:
+      "MIRRORS_EXPECTED_STRING_TYPE_OR_LIST",
+  MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND:
+      "MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND",
+  MessageKind.MISSING_ARGUMENT: "MISSING_ARGUMENT",
+  MessageKind.MISSING_ENUM_CASES: "MISSING_ENUM_CASES",
+  MessageKind.MISSING_FACTORY_KEYWORD: "MISSING_FACTORY_KEYWORD",
+  MessageKind.MISSING_FORMALS: "MISSING_FORMALS",
+  MessageKind.MISSING_LIBRARY_NAME: "MISSING_LIBRARY_NAME",
+  MessageKind.MISSING_MAIN: "MISSING_MAIN",
+  MessageKind.MISSING_PART_OF_TAG: "MISSING_PART_OF_TAG",
+  MessageKind.MISSING_TOKEN_AFTER_THIS: "MISSING_TOKEN_AFTER_THIS",
+  MessageKind.MISSING_TOKEN_BEFORE_THIS: "MISSING_TOKEN_BEFORE_THIS",
+  MessageKind.MISSING_TYPE_ARGUMENT: "MISSING_TYPE_ARGUMENT",
+  MessageKind.MULTI_INHERITANCE: "MULTI_INHERITANCE",
+  MessageKind.NAMED_ARGUMENT_NOT_FOUND: "NAMED_ARGUMENT_NOT_FOUND",
+  MessageKind.NAMED_FUNCTION_EXPRESSION: "NAMED_FUNCTION_EXPRESSION",
+  MessageKind.NAMED_PARAMETER_WITH_EQUALS: "NAMED_PARAMETER_WITH_EQUALS",
+  MessageKind.NATIVE_NOT_SUPPORTED: "NATIVE_NOT_SUPPORTED",
+  MessageKind.NO_BREAK_TARGET: "NO_BREAK_TARGET",
+  MessageKind.NO_CATCH_NOR_FINALLY: "NO_CATCH_NOR_FINALLY",
+  MessageKind.NO_COMMON_SUBTYPES: "NO_COMMON_SUBTYPES",
+  MessageKind.NO_CONTINUE_TARGET: "NO_CONTINUE_TARGET",
+  MessageKind.NO_INSTANCE_AVAILABLE: "NO_INSTANCE_AVAILABLE",
+  MessageKind.NO_MATCHING_CONSTRUCTOR: "NO_MATCHING_CONSTRUCTOR",
+  MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT:
+      "NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT",
+  MessageKind.NO_STATIC_OVERRIDE: "NO_STATIC_OVERRIDE",
+  MessageKind.NO_STATIC_OVERRIDE_CONT: "NO_STATIC_OVERRIDE_CONT",
+  MessageKind.NO_SUCH_LIBRARY_MEMBER: "NO_SUCH_LIBRARY_MEMBER",
+  MessageKind.NO_SUCH_METHOD_IN_NATIVE: "NO_SUCH_METHOD_IN_NATIVE",
+  MessageKind.NO_SUCH_SUPER_MEMBER: "NO_SUCH_SUPER_MEMBER",
+  MessageKind.NO_SUPER_IN_STATIC: "NO_SUPER_IN_STATIC",
+  MessageKind.NO_THIS_AVAILABLE: "NO_THIS_AVAILABLE",
+  MessageKind.NON_CONST_BLOAT: "NON_CONST_BLOAT",
+  MessageKind.NOT_A_COMPILE_TIME_CONSTANT: "NOT_A_COMPILE_TIME_CONSTANT",
+  MessageKind.NOT_A_FIELD: "NOT_A_FIELD",
+  MessageKind.NOT_A_PREFIX: "NOT_A_PREFIX",
+  MessageKind.NOT_A_TYPE: "NOT_A_TYPE",
+  MessageKind.NOT_ASSIGNABLE: "NOT_ASSIGNABLE",
+  MessageKind.NOT_CALLABLE: "NOT_CALLABLE",
+  MessageKind.NOT_INSTANCE_FIELD: "NOT_INSTANCE_FIELD",
+  MessageKind.NOT_MORE_SPECIFIC: "NOT_MORE_SPECIFIC",
+  MessageKind.NOT_MORE_SPECIFIC_SUBTYPE: "NOT_MORE_SPECIFIC_SUBTYPE",
+  MessageKind.NOT_MORE_SPECIFIC_SUGGESTION: "NOT_MORE_SPECIFIC_SUGGESTION",
+  MessageKind.NULL_NOT_ALLOWED: "NULL_NOT_ALLOWED",
+  MessageKind.ONLY_ONE_LIBRARY_TAG: "ONLY_ONE_LIBRARY_TAG",
+  MessageKind.OPERATOR_NAMED_PARAMETERS: "OPERATOR_NAMED_PARAMETERS",
+  MessageKind.OPERATOR_NOT_FOUND: "OPERATOR_NOT_FOUND",
+  MessageKind.OPERATOR_OPTIONAL_PARAMETERS: "OPERATOR_OPTIONAL_PARAMETERS",
+  MessageKind.OPTIONAL_PARAMETER_IN_CATCH: "OPTIONAL_PARAMETER_IN_CATCH",
+  MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE: "OVERRIDE_EQUALS_NOT_HASH_CODE",
+  MessageKind.PARAMETER_NAME_EXPECTED: "PARAMETER_NAME_EXPECTED",
+  MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH:
+      "PARAMETER_WITH_MODIFIER_IN_CATCH",
+  MessageKind.PARAMETER_WITH_TYPE_IN_CATCH: "PARAMETER_WITH_TYPE_IN_CATCH",
+  MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION:
+      "PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION",
+  MessageKind.PATCH_NO_GETTER: "PATCH_NO_GETTER",
+  MessageKind.PATCH_NO_SETTER: "PATCH_NO_SETTER",
+  MessageKind.PATCH_NON_CLASS: "PATCH_NON_CLASS",
+  MessageKind.PATCH_NON_CONSTRUCTOR: "PATCH_NON_CONSTRUCTOR",
+  MessageKind.PATCH_NON_EXISTING: "PATCH_NON_EXISTING",
+  MessageKind.PATCH_NON_EXTERNAL: "PATCH_NON_EXTERNAL",
+  MessageKind.PATCH_NON_FUNCTION: "PATCH_NON_FUNCTION",
+  MessageKind.PATCH_NON_GETTER: "PATCH_NON_GETTER",
+  MessageKind.PATCH_NON_SETTER: "PATCH_NON_SETTER",
+  MessageKind.PATCH_NONPATCHABLE: "PATCH_NONPATCHABLE",
+  MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH:
+      "PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH",
+  MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH:
+      "PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH",
+  MessageKind.PATCH_PARAMETER_MISMATCH: "PATCH_PARAMETER_MISMATCH",
+  MessageKind.PATCH_PARAMETER_TYPE_MISMATCH: "PATCH_PARAMETER_TYPE_MISMATCH",
+  MessageKind.PATCH_POINT_TO_CLASS: "PATCH_POINT_TO_CLASS",
+  MessageKind.PATCH_POINT_TO_CONSTRUCTOR: "PATCH_POINT_TO_CONSTRUCTOR",
+  MessageKind.PATCH_POINT_TO_FUNCTION: "PATCH_POINT_TO_FUNCTION",
+  MessageKind.PATCH_POINT_TO_GETTER: "PATCH_POINT_TO_GETTER",
+  MessageKind.PATCH_POINT_TO_PARAMETER: "PATCH_POINT_TO_PARAMETER",
+  MessageKind.PATCH_POINT_TO_SETTER: "PATCH_POINT_TO_SETTER",
+  MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH:
+      "PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH",
+  MessageKind.PATCH_RETURN_TYPE_MISMATCH: "PATCH_RETURN_TYPE_MISMATCH",
+  MessageKind.PLEASE_REPORT_THE_CRASH: "PLEASE_REPORT_THE_CRASH",
+  MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS:
+      "POSITIONAL_PARAMETER_WITH_EQUALS",
+  MessageKind.POTENTIAL_MUTATION: "POTENTIAL_MUTATION",
+  MessageKind.POTENTIAL_MUTATION_HERE: "POTENTIAL_MUTATION_HERE",
+  MessageKind.POTENTIAL_MUTATION_IN_CLOSURE: "POTENTIAL_MUTATION_IN_CLOSURE",
+  MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE:
+      "POTENTIAL_MUTATION_IN_CLOSURE_HERE",
+  MessageKind.PREAMBLE: "PREAMBLE",
+  MessageKind.PREFIX_AS_EXPRESSION: "PREFIX_AS_EXPRESSION",
+  MessageKind.PRIVATE_ACCESS: "PRIVATE_ACCESS",
+  MessageKind.PRIVATE_IDENTIFIER: "PRIVATE_IDENTIFIER",
+  MessageKind.PRIVATE_NAMED_PARAMETER: "PRIVATE_NAMED_PARAMETER",
+  MessageKind.READ_SCRIPT_ERROR: "READ_SCRIPT_ERROR",
+  MessageKind.READ_SELF_ERROR: "READ_SELF_ERROR",
+  MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE: "REDIRECTING_CONSTRUCTOR_CYCLE",
+  MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY:
+      "REDIRECTING_CONSTRUCTOR_HAS_BODY",
+  MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER:
+      "REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER",
+  MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT:
+      "REDIRECTING_FACTORY_WITH_DEFAULT",
+  MessageKind.REFERENCE_IN_INITIALIZATION: "REFERENCE_IN_INITIALIZATION",
+  MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT:
+      "REQUIRED_PARAMETER_WITH_DEFAULT",
+  MessageKind.RETURN_IN_GENERATOR: "RETURN_IN_GENERATOR",
+  MessageKind.RETURN_NOTHING: "RETURN_NOTHING",
+  MessageKind.RETURN_VALUE_IN_VOID: "RETURN_VALUE_IN_VOID",
+  MessageKind.SETTER_MISMATCH: "SETTER_MISMATCH",
+  MessageKind.SETTER_NOT_FOUND: "SETTER_NOT_FOUND",
+  MessageKind.SETTER_NOT_FOUND_IN_SUPER: "SETTER_NOT_FOUND_IN_SUPER",
+  MessageKind.STATIC_FUNCTION_BLOAT: "STATIC_FUNCTION_BLOAT",
+  MessageKind.STRING_EXPECTED: "STRING_EXPECTED",
+  MessageKind.SUPER_CALL_TO_FACTORY: "SUPER_CALL_TO_FACTORY",
+  MessageKind.SUPER_INITIALIZER_IN_OBJECT: "SUPER_INITIALIZER_IN_OBJECT",
+  MessageKind.SWITCH_CASE_FORBIDDEN: "SWITCH_CASE_FORBIDDEN",
+  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL: "SWITCH_CASE_TYPES_NOT_EQUAL",
+  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE:
+      "SWITCH_CASE_TYPES_NOT_EQUAL_CASE",
+  MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS:
+      "SWITCH_CASE_VALUE_OVERRIDES_EQUALS",
+  MessageKind.TERNARY_OPERATOR_BAD_ARITY: "TERNARY_OPERATOR_BAD_ARITY",
+  MessageKind.THIS_CALL_TO_FACTORY: "THIS_CALL_TO_FACTORY",
+  MessageKind.THIS_IS_THE_DECLARATION: "THIS_IS_THE_DECLARATION",
+  MessageKind.THIS_IS_THE_METHOD: "THIS_IS_THE_METHOD",
+  MessageKind.THIS_IS_THE_PART_OF_TAG: "THIS_IS_THE_PART_OF_TAG",
+  MessageKind.THIS_PROPERTY: "THIS_PROPERTY",
+  MessageKind.THROW_WITHOUT_EXPRESSION: "THROW_WITHOUT_EXPRESSION",
+  MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC:
+      "TOP_LEVEL_VARIABLE_DECLARED_STATIC",
+  MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH: "TYPE_ARGUMENT_COUNT_MISMATCH",
+  MessageKind.TYPE_VARIABLE_IN_CONSTANT: "TYPE_VARIABLE_IN_CONSTANT",
+  MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER:
+      "TYPE_VARIABLE_WITHIN_STATIC_MEMBER",
+  MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT: "TYPEDEF_FORMAL_WITH_DEFAULT",
+  MessageKind.UNARY_OPERATOR_BAD_ARITY: "UNARY_OPERATOR_BAD_ARITY",
+  MessageKind.UNBOUND_LABEL: "UNBOUND_LABEL",
+  MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER: "UNIMPLEMENTED_EXPLICIT_GETTER",
+  MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER: "UNIMPLEMENTED_EXPLICIT_SETTER",
+  MessageKind.UNIMPLEMENTED_GETTER: "UNIMPLEMENTED_GETTER",
+  MessageKind.UNIMPLEMENTED_GETTER_ONE: "UNIMPLEMENTED_GETTER_ONE",
+  MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER: "UNIMPLEMENTED_IMPLICIT_GETTER",
+  MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER: "UNIMPLEMENTED_IMPLICIT_SETTER",
+  MessageKind.UNIMPLEMENTED_METHOD: "UNIMPLEMENTED_METHOD",
+  MessageKind.UNIMPLEMENTED_METHOD_CONT: "UNIMPLEMENTED_METHOD_CONT",
+  MessageKind.UNIMPLEMENTED_METHOD_ONE: "UNIMPLEMENTED_METHOD_ONE",
+  MessageKind.UNIMPLEMENTED_SETTER: "UNIMPLEMENTED_SETTER",
+  MessageKind.UNIMPLEMENTED_SETTER_ONE: "UNIMPLEMENTED_SETTER_ONE",
+  MessageKind.UNMATCHED_TOKEN: "UNMATCHED_TOKEN",
+  MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP:
+      "UNRECOGNIZED_VERSION_OF_LOOKUP_MAP",
+  MessageKind.UNSUPPORTED_BANG_EQ_EQ: "UNSUPPORTED_BANG_EQ_EQ",
+  MessageKind.UNSUPPORTED_EQ_EQ_EQ: "UNSUPPORTED_EQ_EQ_EQ",
+  MessageKind.UNSUPPORTED_LITERAL_SYMBOL: "UNSUPPORTED_LITERAL_SYMBOL",
+  MessageKind.UNSUPPORTED_PREFIX_PLUS: "UNSUPPORTED_PREFIX_PLUS",
+  MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP: "UNSUPPORTED_THROW_WITHOUT_EXP",
+  MessageKind.UNTERMINATED_COMMENT: "UNTERMINATED_COMMENT",
+  MessageKind.UNTERMINATED_STRING: "UNTERMINATED_STRING",
+  MessageKind.UNTERMINATED_TOKEN: "UNTERMINATED_TOKEN",
+  MessageKind.UNUSED_CLASS: "UNUSED_CLASS",
+  MessageKind.UNUSED_LABEL: "UNUSED_LABEL",
+  MessageKind.UNUSED_METHOD: "UNUSED_METHOD",
+  MessageKind.UNUSED_TYPEDEF: "UNUSED_TYPEDEF",
+  MessageKind.VAR_FUNCTION_TYPE_PARAMETER: "VAR_FUNCTION_TYPE_PARAMETER",
+  MessageKind.VOID_EXPRESSION: "VOID_EXPRESSION",
+  MessageKind.VOID_NOT_ALLOWED: "VOID_NOT_ALLOWED",
+  MessageKind.VOID_VARIABLE: "VOID_VARIABLE",
+  MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT:
+      "WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT",
+  MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT:
+      "WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT",
+  MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY:
+      "YIELDING_MODIFIER_ON_ARROW_BODY",
+};
+
 /// A message template for an error, warning, hint or info message generated
 /// by the compiler. Each template is associated with a [MessageKind] that
 /// uniquely identifies the message template.
@@ -462,6 +871,8 @@
 class MessageTemplate {
   final MessageKind kind;
 
+  final String id;
+
   /// Should describe what is wrong and why.
   final String template;
 
@@ -481,3016 +892,8 @@
   /// Additional options needed for the examples to work.
   final List<String> options;
 
-  const MessageTemplate(
-      this.kind,
-      this.template,
-      {this.howToFix,
-       this.examples,
-       this.options: const <String>[]});
-
-  /// All templates used by the compiler.
-  ///
-  /// The map is complete mapping from [MessageKind] to their corresponding
-  /// [MessageTemplate].
-  static const Map<MessageKind, MessageTemplate> TEMPLATES =
-    const <MessageKind, MessageTemplate>{
-      /// Do not use this. It is here for legacy and debugging. It violates item
-      /// 4 of the guide lines for error messages in the beginning of the file.
-      MessageKind.GENERIC:
-        const MessageTemplate(MessageKind.GENERIC, '#{text}'),
-
-      MessageKind.NOT_ASSIGNABLE:
-        const MessageTemplate(MessageKind.NOT_ASSIGNABLE,
-          "'#{fromType}' is not assignable to '#{toType}'."),
-
-      MessageKind.FORIN_NOT_ASSIGNABLE:
-        const MessageTemplate(MessageKind.FORIN_NOT_ASSIGNABLE,
-          "The element type '#{currentType}' of '#{expressionType}' "
-          "is not assignable to '#{elementType}'."),
-
-      MessageKind.VOID_EXPRESSION:
-        const MessageTemplate(MessageKind.VOID_EXPRESSION,
-          "Expression does not yield a value."),
-
-      MessageKind.VOID_VARIABLE:
-        const MessageTemplate(MessageKind.VOID_VARIABLE,
-          "Variable cannot be of type void."),
-
-      MessageKind.RETURN_VALUE_IN_VOID:
-        const MessageTemplate(MessageKind.RETURN_VALUE_IN_VOID,
-          "Cannot return value from void function."),
-
-      MessageKind.RETURN_NOTHING:
-        const MessageTemplate(MessageKind.RETURN_NOTHING,
-          "Value of type '#{returnType}' expected."),
-
-      MessageKind.MISSING_ARGUMENT:
-        const MessageTemplate(MessageKind.MISSING_ARGUMENT,
-          "Missing argument of type '#{argumentType}'."),
-
-      MessageKind.ADDITIONAL_ARGUMENT:
-        const MessageTemplate(MessageKind.ADDITIONAL_ARGUMENT,
-          "Additional argument."),
-
-      MessageKind.NAMED_ARGUMENT_NOT_FOUND:
-        const MessageTemplate(MessageKind.NAMED_ARGUMENT_NOT_FOUND,
-          "No named argument '#{argumentName}' found on method."),
-
-      MessageKind.MEMBER_NOT_FOUND:
-        const MessageTemplate(MessageKind.MEMBER_NOT_FOUND,
-          "No member named '#{memberName}' in class '#{className}'."),
-
-      MessageKind.AWAIT_MEMBER_NOT_FOUND:
-        const MessageTemplate(MessageKind.AWAIT_MEMBER_NOT_FOUND,
-          "No member named 'await' in class '#{className}'.",
-          howToFix: "Did you mean to add the 'async' marker "
-                    "to '#{functionName}'?",
-          examples: const ["""
-class A {
-  m() => await -3;
-}
-main() => new A().m();
-"""]),
-
-      MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE:
-        const MessageTemplate(MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE,
-          "No member named 'await' in class '#{className}'.",
-          howToFix: "Did you mean to add the 'async' marker "
-                    "to the enclosing function?",
-          examples: const ["""
-class A {
-  m() => () => await -3;
-}
-main() => new A().m();
-"""]),
-
-      MessageKind.METHOD_NOT_FOUND:
-        const MessageTemplate(MessageKind.METHOD_NOT_FOUND,
-          "No method named '#{memberName}' in class '#{className}'."),
-
-      MessageKind.OPERATOR_NOT_FOUND:
-        const MessageTemplate(MessageKind.OPERATOR_NOT_FOUND,
-          "No operator '#{memberName}' in class '#{className}'."),
-
-      MessageKind.SETTER_NOT_FOUND:
-        const MessageTemplate(MessageKind.SETTER_NOT_FOUND,
-          "No setter named '#{memberName}' in class '#{className}'."),
-
-      MessageKind.SETTER_NOT_FOUND_IN_SUPER:
-        const MessageTemplate(MessageKind.SETTER_NOT_FOUND_IN_SUPER,
-          "No setter named '#{name}' in superclass of '#{className}'."),
-
-      MessageKind.GETTER_NOT_FOUND:
-        const MessageTemplate(MessageKind.GETTER_NOT_FOUND,
-          "No getter named '#{memberName}' in class '#{className}'."),
-
-      MessageKind.NOT_CALLABLE:
-        const MessageTemplate(MessageKind.NOT_CALLABLE,
-          "'#{elementName}' is not callable."),
-
-      MessageKind.MEMBER_NOT_STATIC:
-        const MessageTemplate(MessageKind.MEMBER_NOT_STATIC,
-          "'#{className}.#{memberName}' is not static."),
-
-      MessageKind.NO_INSTANCE_AVAILABLE:
-        const MessageTemplate(MessageKind.NO_INSTANCE_AVAILABLE,
-          "'#{name}' is only available in instance methods."),
-
-      MessageKind.NO_THIS_AVAILABLE:
-        const MessageTemplate(MessageKind.NO_THIS_AVAILABLE,
-          "'this' is only available in instance methods."),
-
-      MessageKind.PRIVATE_ACCESS:
-        const MessageTemplate(MessageKind.PRIVATE_ACCESS,
-          "'#{name}' is declared private within library "
-          "'#{libraryName}'."),
-
-      MessageKind.THIS_IS_THE_DECLARATION:
-        const MessageTemplate(MessageKind.THIS_IS_THE_DECLARATION,
-          "This is the declaration of '#{name}'."),
-
-      MessageKind.THIS_IS_THE_METHOD:
-        const MessageTemplate(MessageKind.THIS_IS_THE_METHOD,
-          "This is the method declaration."),
-
-      MessageKind.CANNOT_RESOLVE:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE,
-          "Cannot resolve '#{name}'."),
-
-      MessageKind.CANNOT_RESOLVE_AWAIT:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_AWAIT,
-          "Cannot resolve '#{name}'.",
-          howToFix: "Did you mean to add the 'async' marker "
-                    "to '#{functionName}'?",
-          examples: const [
-              "main() => await -3;",
-              "foo() => await -3; main() => foo();"
-          ]),
-
-      MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE,
-          "Cannot resolve '#{name}'.",
-          howToFix: "Did you mean to add the 'async' marker "
-                    "to the enclosing function?",
-          examples: const [
-              "main() { (() => await -3)(); }",
-          ]),
-
-      MessageKind.CANNOT_RESOLVE_IN_INITIALIZER:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_IN_INITIALIZER,
-          "Cannot resolve '#{name}'. It would be implicitly looked up on this "
-          "instance, but instances are not available in initializers.",
-          howToFix: "Try correcting the unresolved reference or move the "
-              "initialization to a constructor body.",
-          examples: const ["""
-class A {
-  var test = unresolvedName;
-}
-main() => new A();
-"""]),
-
-      MessageKind.CANNOT_RESOLVE_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_CONSTRUCTOR,
-          "Cannot resolve constructor '#{constructorName}'."),
-
-      MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT:
-        const MessageTemplate(
-          MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT,
-          "cannot resolve constructor '#{constructorName}' "
-          "for implicit super call.",
-          howToFix: "Try explicitly invoking a constructor of the super class",
-          examples: const ["""
-class A {
-  A.foo() {}
-}
-class B extends A {
-  B();
-}
-main() => new B();
-"""]),
-
-      MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME:
-        const MessageTemplate(MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME,
-          "Unnamed constructor name must be '#{name}'."),
-
-      MessageKind.INVALID_CONSTRUCTOR_NAME:
-        const MessageTemplate(MessageKind.INVALID_CONSTRUCTOR_NAME,
-          "Constructor name must start with '#{name}'."),
-
-      MessageKind.CANNOT_RESOLVE_TYPE:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_TYPE,
-          "Cannot resolve type '#{typeName}'."),
-
-      MessageKind.DUPLICATE_DEFINITION:
-        const MessageTemplate(MessageKind.DUPLICATE_DEFINITION,
-          "Duplicate definition of '#{name}'.",
-          howToFix: "Try to rename or remove this definition.",
-          examples: const ["""
-class C {
-  void f() {}
-  int get f => 1;
-}
-
-main() {
-  new C();
-}
-
-"""]),
-
-      MessageKind.EXISTING_DEFINITION:
-        const MessageTemplate(MessageKind.EXISTING_DEFINITION,
-          "Existing definition of '#{name}'."),
-
-      MessageKind.DUPLICATE_IMPORT:
-        const MessageTemplate(MessageKind.DUPLICATE_IMPORT,
-          "Duplicate import of '#{name}'."),
-
-      MessageKind.HIDDEN_IMPORT:
-        const MessageTemplate(MessageKind.HIDDEN_IMPORT,
-          "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
-          "from library '#{hidingUri}'.",
-          howToFix:
-            "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
-          examples: const [
-              const {
-'main.dart':
-"""
-import 'dart:async'; // This imports a class Future.
-import 'future.dart';
-
-void main() => new Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}"""},
-
-          const {
-'main.dart':
-"""
-import 'future.dart';
-import 'dart:async'; // This imports a class Future.
-
-void main() => new Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}"""},
-
-          const {
-'main.dart':
-"""
-import 'export.dart';
-import 'dart:async'; // This imports a class Future.
-
-void main() => new Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}""",
-
-'export.dart':
-"""
-library export;
-
-export 'future.dart';"""},
-
-         const {
-'main.dart':
-"""
-import 'future.dart' as prefix;
-import 'dart:async' as prefix; // This imports a class Future.
-
-void main() => new prefix.Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}"""}]),
-
-
-      MessageKind.HIDDEN_IMPLICIT_IMPORT:
-        const MessageTemplate(MessageKind.HIDDEN_IMPLICIT_IMPORT,
-          "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
-          "from library '#{hidingUri}'.",
-          howToFix: "Try adding an explicit "
-                    "'import \"#{hiddenUri}\" hide #{name}'.",
-          examples: const [
-              const {
-'main.dart':
-"""
-// This hides the implicit import of class Type from dart:core.
-import 'type.dart';
-
-void main() => new Type();""",
-
-'type.dart':
-"""
-library type;
-
-class Type {}"""},
-          const {
-'conflictsWithDart.dart':
-"""
-library conflictsWithDart;
-
-class Duration {
-  static var x = 100;
-}
-""",
-
-'conflictsWithDartAsWell.dart':
-"""
-library conflictsWithDartAsWell;
-
-class Duration {
-  static var x = 100;
-}
-""",
-
-'main.dart':
-r"""
-library testDartConflicts;
-
-import 'conflictsWithDart.dart';
-import 'conflictsWithDartAsWell.dart';
-
-main() {
-  print("Hail Caesar ${Duration.x}");
-}
-"""}]),
-
-      MessageKind.DUPLICATE_EXPORT:
-        const MessageTemplate(MessageKind.DUPLICATE_EXPORT,
-          "Duplicate export of '#{name}'.",
-          howToFix: "Try adding 'hide #{name}' to one of the exports.",
-          examples: const [const {
-'main.dart': """
-export 'decl1.dart';
-export 'decl2.dart';
-
-main() {}""",
-'decl1.dart': "class Class {}",
-'decl2.dart': "class Class {}"}]),
-
-      MessageKind.DUPLICATE_EXPORT_CONT:
-        const MessageTemplate(MessageKind.DUPLICATE_EXPORT_CONT,
-          "This is another export of '#{name}'."),
-
-      MessageKind.DUPLICATE_EXPORT_DECL:
-        const MessageTemplate(MessageKind.DUPLICATE_EXPORT_DECL,
-          "The exported '#{name}' from export #{uriString} is defined here."),
-
-      MessageKind.EMPTY_HIDE:
-        const MessageTemplate(MessageKind.EMPTY_HIDE,
-            "Library '#{uri}' doesn't export a '#{name}' declaration.",
-      howToFix: "Try removing '#{name}' the 'hide' clause.",
-      examples: const [
-        const {
-            'main.dart': """
-import 'dart:core' hide Foo;
-
-main() {}"""},
-        const {
-'main.dart': """
-export 'dart:core' hide Foo;
-
-main() {}"""},
-]),
-
-      MessageKind.EMPTY_SHOW:
-        const MessageTemplate(MessageKind.EMPTY_SHOW,
-            "Library '#{uri}' doesn't export a '#{name}' declaration.",
-      howToFix: "Try removing '#{name}' from the 'show' clause.",
-      examples: const [
-        const {
-            'main.dart': """
-import 'dart:core' show Foo;
-
-main() {}"""},
-        const {
-'main.dart': """
-export 'dart:core' show Foo;
-
-main() {}"""},
-]),
-
-      MessageKind.NOT_A_TYPE:
-        const MessageTemplate(MessageKind.NOT_A_TYPE,
-          "'#{node}' is not a type."),
-
-      MessageKind.NOT_A_PREFIX:
-        const MessageTemplate(MessageKind.NOT_A_PREFIX,
-          "'#{node}' is not a prefix."),
-
-      MessageKind.PREFIX_AS_EXPRESSION:
-        const MessageTemplate(MessageKind.PREFIX_AS_EXPRESSION,
-          "Library prefix '#{prefix}' is not a valid expression."),
-
-      MessageKind.CANNOT_FIND_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.CANNOT_FIND_CONSTRUCTOR,
-          "Cannot find constructor '#{constructorName}'."),
-
-      MessageKind.CYCLIC_CLASS_HIERARCHY:
-        const MessageTemplate(MessageKind.CYCLIC_CLASS_HIERARCHY,
-          "'#{className}' creates a cycle in the class hierarchy."),
-
-      MessageKind.CYCLIC_REDIRECTING_FACTORY:
-        const MessageTemplate(MessageKind.CYCLIC_REDIRECTING_FACTORY,
-          'Redirecting factory leads to a cyclic redirection.'),
-
-      MessageKind.INVALID_RECEIVER_IN_INITIALIZER:
-        const MessageTemplate(MessageKind.INVALID_RECEIVER_IN_INITIALIZER,
-          "Field initializer expected."),
-
-      MessageKind.NO_SUPER_IN_STATIC:
-        const MessageTemplate(MessageKind.NO_SUPER_IN_STATIC,
-          "'super' is only available in instance methods."),
-
-      MessageKind.DUPLICATE_INITIALIZER:
-        const MessageTemplate(MessageKind.DUPLICATE_INITIALIZER,
-          "Field '#{fieldName}' is initialized more than once."),
-
-      MessageKind.ALREADY_INITIALIZED:
-        const MessageTemplate(MessageKind.ALREADY_INITIALIZED,
-          "'#{fieldName}' was already initialized here."),
-
-      MessageKind.INIT_STATIC_FIELD:
-        const MessageTemplate(MessageKind.INIT_STATIC_FIELD,
-          "Cannot initialize static field '#{fieldName}'."),
-
-      MessageKind.NOT_A_FIELD:
-        const MessageTemplate(MessageKind.NOT_A_FIELD,
-          "'#{fieldName}' is not a field."),
-
-      MessageKind.CONSTRUCTOR_CALL_EXPECTED:
-        const MessageTemplate(MessageKind.CONSTRUCTOR_CALL_EXPECTED,
-          "only call to 'this' or 'super' constructor allowed."),
-
-      MessageKind.INVALID_FOR_IN:
-        const MessageTemplate(MessageKind.INVALID_FOR_IN,
-          "Invalid for-in variable declaration."),
-
-      MessageKind.INVALID_INITIALIZER:
-        const MessageTemplate(MessageKind.INVALID_INITIALIZER,
-          "Invalid initializer."),
-
-      MessageKind.FUNCTION_WITH_INITIALIZER:
-        const MessageTemplate(MessageKind.FUNCTION_WITH_INITIALIZER,
-          "Only constructors can have initializers."),
-
-      MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE:
-        const MessageTemplate(MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE,
-          "Cyclic constructor redirection."),
-
-      MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY:
-        const MessageTemplate(MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY,
-          "Redirecting constructor can't have a body."),
-
-      MessageKind.CONST_CONSTRUCTOR_HAS_BODY:
-        const MessageTemplate(MessageKind.CONST_CONSTRUCTOR_HAS_BODY,
-          "Const constructor or factory can't have a body.",
-          howToFix: "Remove the 'const' keyword or the body",
-          examples: const ["""
-class C {
-  const C() {}
-}
-
-main() => new C();"""]),
-
-      MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER:
-        const MessageTemplate(
-          MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER,
-          "Redirecting constructor cannot have other initializers."),
-
-      MessageKind.SUPER_INITIALIZER_IN_OBJECT:
-        const MessageTemplate(MessageKind.SUPER_INITIALIZER_IN_OBJECT,
-          "'Object' cannot have a super initializer."),
-
-      MessageKind.DUPLICATE_SUPER_INITIALIZER:
-        const MessageTemplate(MessageKind.DUPLICATE_SUPER_INITIALIZER,
-          "Cannot have more than one super initializer."),
-
-      MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS:
-        const MessageTemplate(MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS,
-          "Arguments do not match the expected parameters of constructor "
-          "'#{constructorName}'."),
-
-      MessageKind.NO_MATCHING_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.NO_MATCHING_CONSTRUCTOR,
-          "'super' call arguments and constructor parameters do not match."),
-
-      MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT:
-        const MessageTemplate(MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT,
-              "Implicit 'super' call arguments and constructor parameters "
-              "do not match."),
-
-      MessageKind.CONST_CALLS_NON_CONST:
-        const MessageTemplate(MessageKind.CONST_CALLS_NON_CONST,
-          "'const' constructor cannot call a non-const constructor."),
-
-      MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT:
-        const MessageTemplate(MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT,
-              "'const' constructor cannot call a non-const constructor. "
-              "This constructor has an implicit call to a "
-              "super non-const constructor.",
-              howToFix: "Try making the super constructor const.",
-              examples: const ["""
-class C {
-  C(); // missing const
-}
-class D extends C {
-  final d;
-  const D(this.d);
-}
-main() => new D(0);"""]),
-
-      MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS:
-        const MessageTemplate(
-          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
-          "Can't declare constructor 'const' on class #{className} "
-          "because the class contains non-final instance fields.",
-          howToFix: "Try making all fields final.",
-          examples: const ["""
-class C {
-  // 'a' must be declared final to allow for the const constructor.
-  var a;
-  const C(this.a);
-}
-
-main() => new C(0);"""]),
-
-      MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD:
-        const MessageTemplate(
-          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD,
-          "This non-final field prevents using const constructors."),
-
-      MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR:
-        const MessageTemplate(
-          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
-          "This const constructor is not allowed due to "
-          "non-final fields."),
-
-
-      MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED:
-        const MessageTemplate(MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED,
-          "Initializing formal parameter only allowed in generative "
-          "constructor."),
-
-      MessageKind.INVALID_PARAMETER:
-        const MessageTemplate(MessageKind.INVALID_PARAMETER,
-          "Cannot resolve parameter."),
-
-      MessageKind.NOT_INSTANCE_FIELD:
-        const MessageTemplate(MessageKind.NOT_INSTANCE_FIELD,
-          "'#{fieldName}' is not an instance field."),
-
-      MessageKind.THIS_PROPERTY:
-        const MessageTemplate(MessageKind.THIS_PROPERTY,
-          "Expected an identifier."),
-
-      MessageKind.NO_CATCH_NOR_FINALLY:
-        const MessageTemplate(MessageKind.NO_CATCH_NOR_FINALLY,
-          "Expected 'catch' or 'finally'."),
-
-      MessageKind.EMPTY_CATCH_DECLARATION:
-        const MessageTemplate(MessageKind.EMPTY_CATCH_DECLARATION,
-          "Expected an identifier in catch declaration."),
-
-      MessageKind.EXTRA_CATCH_DECLARATION:
-        const MessageTemplate(MessageKind.EXTRA_CATCH_DECLARATION,
-          "Extra parameter in catch declaration."),
-
-      MessageKind.PARAMETER_WITH_TYPE_IN_CATCH:
-        const MessageTemplate(MessageKind.PARAMETER_WITH_TYPE_IN_CATCH,
-          "Cannot use type annotations in catch."),
-
-      MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH:
-        const MessageTemplate(MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH,
-          "Cannot use modifiers in catch."),
-
-      MessageKind.OPTIONAL_PARAMETER_IN_CATCH:
-        const MessageTemplate(MessageKind.OPTIONAL_PARAMETER_IN_CATCH,
-          "Cannot use optional parameters in catch."),
-
-      MessageKind.THROW_WITHOUT_EXPRESSION:
-        const MessageTemplate(MessageKind.THROW_WITHOUT_EXPRESSION,
-          "Cannot use re-throw outside of catch block "
-          "(expression expected after 'throw')."),
-
-      MessageKind.UNBOUND_LABEL:
-        const MessageTemplate(MessageKind.UNBOUND_LABEL,
-          "Cannot resolve label '#{labelName}'."),
-
-      MessageKind.NO_BREAK_TARGET:
-        const MessageTemplate(MessageKind.NO_BREAK_TARGET,
-          "'break' statement not inside switch or loop."),
-
-      MessageKind.NO_CONTINUE_TARGET:
-        const MessageTemplate(MessageKind.NO_CONTINUE_TARGET,
-          "'continue' statement not inside loop."),
-
-      MessageKind.EXISTING_LABEL:
-        const MessageTemplate(MessageKind.EXISTING_LABEL,
-          "Original declaration of duplicate label '#{labelName}'."),
-
-      MessageKind.DUPLICATE_LABEL:
-        const MessageTemplate(MessageKind.DUPLICATE_LABEL,
-          "Duplicate declaration of label '#{labelName}'."),
-
-      MessageKind.UNUSED_LABEL:
-        const MessageTemplate(MessageKind.UNUSED_LABEL,
-          "Unused label '#{labelName}'."),
-
-      MessageKind.INVALID_CONTINUE:
-        const MessageTemplate(MessageKind.INVALID_CONTINUE,
-          "Target of continue is not a loop or switch case."),
-
-      MessageKind.INVALID_BREAK:
-        const MessageTemplate(MessageKind.INVALID_BREAK,
-          "Target of break is not a statement."),
-
-      MessageKind.DUPLICATE_TYPE_VARIABLE_NAME:
-        const MessageTemplate(MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
-          "Type variable '#{typeVariableName}' already declared."),
-
-      MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER:
-        const MessageTemplate(MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
-              "Cannot refer to type variable '#{typeVariableName}' "
-              "within a static member."),
-
-      MessageKind.TYPE_VARIABLE_IN_CONSTANT:
-        const MessageTemplate(MessageKind.TYPE_VARIABLE_IN_CONSTANT,
-          "Constant expressions can't refer to type variables.",
-          howToFix: "Try removing the type variable or replacing it with a "
-                    "concrete type.",
-          examples: const ["""
-class C<T> {
-  const C();
-
-  m(T t) => const C<T>();
-}
-
-void main() => new C().m(null);
-"""
-]),
-
-      MessageKind.INVALID_TYPE_VARIABLE_BOUND:
-        const MessageTemplate(MessageKind.INVALID_TYPE_VARIABLE_BOUND,
-          "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
-          "type variable '#{typeVariable}' of type '#{thisType}'.",
-          howToFix: "Try to change or remove the type argument.",
-          examples: const ["""
-class C<T extends num> {}
-
-// 'String' is not a valid instantiation of T with bound num.'.
-main() => new C<String>();
-"""]),
-
-      MessageKind.INVALID_USE_OF_SUPER:
-        const MessageTemplate(MessageKind.INVALID_USE_OF_SUPER,
-          "'super' not allowed here."),
-
-      MessageKind.INVALID_CASE_DEFAULT:
-        const MessageTemplate(MessageKind.INVALID_CASE_DEFAULT,
-          "'default' only allowed on last case of a switch."),
-
-      MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL:
-        const MessageTemplate(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
-          "'case' expressions do not all have type '#{type}'."),
-
-      MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE:
-        const MessageTemplate(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
-          "'case' expression of type '#{type}'."),
-
-      MessageKind.SWITCH_CASE_FORBIDDEN:
-        const MessageTemplate(MessageKind.SWITCH_CASE_FORBIDDEN,
-          "'case' expression may not be of type '#{type}'."),
-
-      MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS:
-        const MessageTemplate(MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
-              "'case' expression type '#{type}' overrides 'operator =='."),
-
-      MessageKind.INVALID_ARGUMENT_AFTER_NAMED:
-        const MessageTemplate(MessageKind.INVALID_ARGUMENT_AFTER_NAMED,
-          "Unnamed argument after named argument."),
-
-      MessageKind.NOT_A_COMPILE_TIME_CONSTANT:
-        const MessageTemplate(MessageKind.NOT_A_COMPILE_TIME_CONSTANT,
-          "Not a compile-time constant."),
-
-      MessageKind.DEFERRED_COMPILE_TIME_CONSTANT:
-        const MessageTemplate(MessageKind.DEFERRED_COMPILE_TIME_CONSTANT,
-          "A deferred value cannot be used as a compile-time constant."),
-
-      MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION:
-        const MessageTemplate(
-          MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION,
-          "A deferred class cannot be used to create a "
-          "compile-time constant."),
-
-      MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS:
-        const MessageTemplate(MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS,
-          "Cycle in the compile-time constant computation."),
-
-      MessageKind.CONSTRUCTOR_IS_NOT_CONST:
-        const MessageTemplate(MessageKind.CONSTRUCTOR_IS_NOT_CONST,
-          "Constructor is not a 'const' constructor."),
-
-      MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS:
-        const MessageTemplate(MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS,
-              "Const-map key type '#{type}' overrides 'operator =='."),
-
-      MessageKind.NO_SUCH_LIBRARY_MEMBER:
-        const MessageTemplate(MessageKind.NO_SUCH_LIBRARY_MEMBER,
-          "'#{libraryName}' has no member named '#{memberName}'."),
-
-      MessageKind.CANNOT_INSTANTIATE_TYPEDEF:
-        const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
-          "Cannot instantiate typedef '#{typedefName}'."),
-
-      MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT:
-        const MessageTemplate(MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT,
-          "Non-optional parameters can't have a default value.",
-          howToFix:
-            "Try removing the default value or making the parameter optional.",
-          examples: const ["""
-main() {
-  foo(a: 1) => print(a);
-  foo(2);
-}""", """
-main() {
-  foo(a = 1) => print(a);
-  foo(2);
-}"""]),
-
-      MessageKind.NAMED_PARAMETER_WITH_EQUALS:
-        const MessageTemplate(MessageKind.NAMED_PARAMETER_WITH_EQUALS,
-          "Named optional parameters can't use '=' to specify a default "
-          "value.",
-          howToFix: "Try replacing '=' with ':'.",
-          examples: const ["""
-main() {
-  foo({a = 1}) => print(a);
-  foo(a: 2);
-}"""]),
-
-      MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS:
-        const MessageTemplate(MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS,
-          "Positional optional parameters can't use ':' to specify a "
-          "default value.",
-          howToFix: "Try replacing ':' with '='.",
-          examples: const ["""
-main() {
-  foo([a: 1]) => print(a);
-  foo(2);
-}"""]),
-
-      MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT:
-        const MessageTemplate(MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT,
-          "A parameter of a typedef can't specify a default value.",
-          howToFix:
-            "Try removing the default value.",
-          examples: const ["""
-typedef void F([int arg = 0]);
-
-main() {
-  F f;
-}""", """
-typedef void F({int arg: 0});
-
-main() {
-  F f;
-}"""]),
-
-      MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT:
-        const MessageTemplate(MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT,
-          "A function type parameter can't specify a default value.",
-          howToFix:
-            "Try removing the default value.",
-          examples: const ["""
-foo(f(int i, [a = 1])) {}
-
-main() {
-  foo(1, 2);
-}""", """
-foo(f(int i, {a: 1})) {}
-
-main() {
-  foo(1, a: 2);
-}"""]),
-
-      MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT:
-        const MessageTemplate(MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT,
-          "A parameter of a redirecting factory constructor can't specify a "
-          "default value.",
-          howToFix:
-            "Try removing the default value.",
-          examples: const ["""
-class A {
-  A([a]);
-  factory A.foo([a = 1]) = A;
-}
-
-main() {
-  new A.foo(1);
-}""", """
-class A {
-  A({a});
-  factory A.foo({a: 1}) = A;
-}
-
-main() {
-  new A.foo(a: 1);
-}"""]),
-
-      MessageKind.FORMAL_DECLARED_CONST:
-        const MessageTemplate(MessageKind.FORMAL_DECLARED_CONST,
-          "A formal parameter can't be declared const.",
-          howToFix: "Try removing 'const'.",
-          examples: const ["""
-foo(const x) {}
-main() => foo(42);
-""", """
-foo({const x}) {}
-main() => foo(42);
-""", """
-foo([const x]) {}
-main() => foo(42);
-"""]),
-
-      MessageKind.FORMAL_DECLARED_STATIC:
-        const MessageTemplate(MessageKind.FORMAL_DECLARED_STATIC,
-          "A formal parameter can't be declared static.",
-          howToFix: "Try removing 'static'.",
-          examples: const ["""
-foo(static x) {}
-main() => foo(42);
-""", """
-foo({static x}) {}
-main() => foo(42);
-""", """
-foo([static x]) {}
-main() => foo(42);
-"""]),
-
-      MessageKind.FINAL_FUNCTION_TYPE_PARAMETER:
-        const MessageTemplate(MessageKind.FINAL_FUNCTION_TYPE_PARAMETER,
-          "A function type parameter can't be declared final.",
-          howToFix: "Try removing 'final'.",
-          examples: const ["""
-foo(final int x(int a)) {}
-main() => foo((y) => 42);
-""", """
-foo({final int x(int a)}) {}
-main() => foo((y) => 42);
-""", """
-foo([final int x(int a)]) {}
-main() => foo((y) => 42);
-"""]),
-
-      MessageKind.VAR_FUNCTION_TYPE_PARAMETER:
-        const MessageTemplate(MessageKind.VAR_FUNCTION_TYPE_PARAMETER,
-          "A function type parameter can't be declared with 'var'.",
-          howToFix: "Try removing 'var'.",
-          examples: const ["""
-foo(var int x(int a)) {}
-main() => foo((y) => 42);
-""", """
-foo({var int x(int a)}) {}
-main() => foo((y) => 42);
-""", """
-foo([var int x(int a)]) {}
-main() => foo((y) => 42);
-"""]),
-
-      MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE:
-        const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
-          "Cannot instantiate type variable '#{typeVariableName}'."),
-
-      MessageKind.CYCLIC_TYPE_VARIABLE:
-        const MessageTemplate(MessageKind.CYCLIC_TYPE_VARIABLE,
-          "Type variable '#{typeVariableName}' is a supertype of itself."),
-
-      MessageKind.CYCLIC_TYPEDEF:
-        const MessageTemplate(MessageKind.CYCLIC_TYPEDEF,
-          "A typedef can't refer to itself.",
-          howToFix: "Try removing all references to '#{typedefName}' "
-                    "in the definition of '#{typedefName}'.",
-          examples: const ["""
-typedef F F(); // The return type 'F' is a self-reference.
-main() { F f = null; }"""]),
-
-      MessageKind.CYCLIC_TYPEDEF_ONE:
-        const MessageTemplate(MessageKind.CYCLIC_TYPEDEF_ONE,
-          "A typedef can't refer to itself through another typedef.",
-          howToFix:
-            "Try removing all references to "
-            "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
-          examples: const ["""
-typedef G F(); // The return type 'G' is a self-reference through typedef 'G'.
-typedef F G(); // The return type 'F' is a self-reference through typedef 'F'.
-main() { F f = null; }""",
-"""
-typedef G F(); // The return type 'G' creates a self-reference.
-typedef H G(); // The return type 'H' creates a self-reference.
-typedef H(F f); // The argument type 'F' creates a self-reference.
-main() { F f = null; }"""]),
-
-      MessageKind.CLASS_NAME_EXPECTED:
-        const MessageTemplate(MessageKind.CLASS_NAME_EXPECTED,
-          "Class name expected."),
-
-      MessageKind.CANNOT_EXTEND:
-        const MessageTemplate(MessageKind.CANNOT_EXTEND,
-          "'#{type}' cannot be extended."),
-
-      MessageKind.CANNOT_IMPLEMENT:
-        const MessageTemplate(MessageKind.CANNOT_IMPLEMENT,
-          "'#{type}' cannot be implemented."),
-
-      // TODO(johnnwinther): Split messages into reasons for malformedness.
-      MessageKind.CANNOT_EXTEND_MALFORMED:
-        const MessageTemplate(MessageKind.CANNOT_EXTEND_MALFORMED,
-          "Class '#{className}' can't extend the type '#{malformedType}' "
-          "because it is malformed.",
-          howToFix:
-            "Try correcting the malformed type annotation or removing the "
-            "'extends' clause.",
-          examples: const ["""
-class A extends Malformed {}
-main() => new A();"""]),
-
-      MessageKind.CANNOT_IMPLEMENT_MALFORMED:
-        const MessageTemplate(MessageKind.CANNOT_IMPLEMENT_MALFORMED,
-          "Class '#{className}' can't implement the type '#{malformedType}' "
-          "because it is malformed.",
-          howToFix:
-            "Try correcting the malformed type annotation or removing the "
-            "type from the 'implements' clause.",
-          examples: const ["""
-class A implements Malformed {}
-main() => new A();"""]),
-
-      MessageKind.CANNOT_MIXIN_MALFORMED:
-        const MessageTemplate(MessageKind.CANNOT_MIXIN_MALFORMED,
-          "Class '#{className}' can't mixin the type '#{malformedType}' "
-          "because it is malformed.",
-          howToFix:
-            "Try correcting the malformed type annotation or removing the "
-            "type from the 'with' clause.",
-          examples: const ["""
-class A extends Object with Malformed {}
-main() => new A();"""]),
-
-      MessageKind.CANNOT_MIXIN:
-        const MessageTemplate(MessageKind.CANNOT_MIXIN,
-          "The type '#{type}' can't be mixed in.",
-          howToFix: "Try removing '#{type}' from the 'with' clause.",
-          examples: const ["""
-class C extends Object with String {}
-
-main() => new C();
-""", """
-typedef C = Object with String;
-
-main() => new C();
-"""]),
-
-      MessageKind.CANNOT_EXTEND_ENUM:
-        const MessageTemplate(MessageKind.CANNOT_EXTEND_ENUM,
-          "Class '#{className}' can't extend the type '#{enumType}' because "
-          "it is declared by an enum.",
-          howToFix: "Try making '#{enumType}' a normal class or removing the "
-            "'extends' clause.",
-          examples: const ["""
-enum Enum { A }
-class B extends Enum {}
-main() => new B();"""]),
-
-      MessageKind.CANNOT_IMPLEMENT_ENUM:
-        const MessageTemplate(MessageKind.CANNOT_IMPLEMENT_ENUM,
-          "Class '#{className}' can't implement the type '#{enumType}' "
-          "because it is declared by an enum.",
-          howToFix: "Try making '#{enumType}' a normal class or removing the "
-            "type from the 'implements' clause.",
-          examples: const ["""
-enum Enum { A }
-class B implements Enum {}
-main() => new B();"""]),
-
-      MessageKind.CANNOT_MIXIN_ENUM:
-        const MessageTemplate(MessageKind.CANNOT_MIXIN_ENUM,
-          "Class '#{className}' can't mixin the type '#{enumType}' because it "
-          "is declared by an enum.",
-          howToFix: "Try making '#{enumType}' a normal class or removing the "
-            "type from the 'with' clause.",
-          examples: const ["""
-enum Enum { A }
-class B extends Object with Enum {}
-main() => new B();"""]),
-
-      MessageKind.CANNOT_INSTANTIATE_ENUM:
-        const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_ENUM,
-          "Enum type '#{enumName}' cannot be instantiated.",
-          howToFix: "Try making '#{enumType}' a normal class or use an enum "
-                    "constant.",
-          examples: const ["""
-enum Enum { A }
-main() => new Enum(0);""", """
-enum Enum { A }
-main() => const Enum(0);"""]),
-
-      MessageKind.EMPTY_ENUM_DECLARATION:
-        const MessageTemplate(MessageKind.EMPTY_ENUM_DECLARATION,
-          "Enum '#{enumName}' must contain at least one value.",
-          howToFix: "Try adding an enum constant or making #{enumName} a "
-                    "normal class.",
-          examples: const ["""
-enum Enum {}
-main() { Enum e; }"""]),
-
-      MessageKind.MISSING_ENUM_CASES:
-        const MessageTemplate(MessageKind.MISSING_ENUM_CASES,
-          "Missing enum constants in switch statement: #{enumValues}.",
-          howToFix: "Try adding the missing constants or a default case.",
-          examples: const ["""
-enum Enum { A, B }
-main() {
-  switch (Enum.A) {
-  case Enum.B: break;
-  }
-}""", """
-enum Enum { A, B, C }
-main() {
-  switch (Enum.A) {
-  case Enum.B: break;
-  }
-}"""]),
-
-      MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS:
-        const MessageTemplate(MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
-          "'#{type}' can not be both extended and implemented."),
-
-      MessageKind.DUPLICATE_IMPLEMENTS:
-        const MessageTemplate(MessageKind.DUPLICATE_IMPLEMENTS,
-          "'#{type}' must not occur more than once "
-          "in the implements clause."),
-
-      MessageKind.MULTI_INHERITANCE:
-        const MessageTemplate(MessageKind.MULTI_INHERITANCE,
-          "Dart2js does not currently support inheritance of the same class "
-          "with different type arguments: Both #{firstType} and #{secondType} "
-          "are supertypes of #{thisType}."),
-
-      MessageKind.ILLEGAL_SUPER_SEND:
-        const MessageTemplate(MessageKind.ILLEGAL_SUPER_SEND,
-          "'#{name}' cannot be called on super."),
-
-      MessageKind.NO_SUCH_SUPER_MEMBER:
-        const MessageTemplate(MessageKind.NO_SUCH_SUPER_MEMBER,
-          "Cannot resolve '#{memberName}' in a superclass of '#{className}'."),
-
-      MessageKind.ADDITIONAL_TYPE_ARGUMENT:
-        const MessageTemplate(MessageKind.ADDITIONAL_TYPE_ARGUMENT,
-          "Additional type argument."),
-
-      MessageKind.MISSING_TYPE_ARGUMENT:
-        const MessageTemplate(MessageKind.MISSING_TYPE_ARGUMENT,
-          "Missing type argument."),
-
-      // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or
-      // MISSING_TYPE_ARGUMENT instead.
-      MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH:
-        const MessageTemplate(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
-          "Incorrect number of type arguments on '#{type}'."),
-
-      MessageKind.GETTER_MISMATCH:
-        const MessageTemplate(MessageKind.GETTER_MISMATCH,
-          "Setter disagrees on: '#{modifiers}'."),
-
-      MessageKind.SETTER_MISMATCH:
-        const MessageTemplate(MessageKind.SETTER_MISMATCH,
-          "Getter disagrees on: '#{modifiers}'."),
-
-      MessageKind.ILLEGAL_SETTER_FORMALS:
-        const MessageTemplate(MessageKind.ILLEGAL_SETTER_FORMALS,
-          "A setter must have exactly one argument."),
-
-      MessageKind.NO_STATIC_OVERRIDE:
-        const MessageTemplate(MessageKind.NO_STATIC_OVERRIDE,
-          "Static member cannot override instance member '#{memberName}' of "
-          "'#{className}'."),
-
-      MessageKind.NO_STATIC_OVERRIDE_CONT:
-        const MessageTemplate(MessageKind.NO_STATIC_OVERRIDE_CONT,
-          "This is the instance member that cannot be overridden "
-          "by a static member."),
-
-      MessageKind.INSTANCE_STATIC_SAME_NAME:
-        const MessageTemplate(MessageKind.INSTANCE_STATIC_SAME_NAME,
-          "Instance member '#{memberName}' and static member of "
-          "superclass '#{className}' have the same name."),
-
-      MessageKind.INSTANCE_STATIC_SAME_NAME_CONT:
-        const MessageTemplate(MessageKind.INSTANCE_STATIC_SAME_NAME_CONT,
-          "This is the static member with the same name."),
-
-      MessageKind.INVALID_OVERRIDE_METHOD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_METHOD,
-          "The type '#{declaredType}' of method '#{name}' declared in "
-          "'#{class}' is not a subtype of the overridden method type "
-          "'#{inheritedType}' inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDDEN_METHOD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_METHOD,
-          "This is the overridden method '#{name}' declared in class "
-          "'#{class}'."),
-
-      MessageKind.INVALID_OVERRIDE_GETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_GETTER,
-          "The type '#{declaredType}' of getter '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden getter inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDDEN_GETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_GETTER,
-          "This is the overridden getter '#{name}' declared in class "
-          "'#{class}'."),
-
-      MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
-          "The type '#{declaredType}' of field '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden getter inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
-          "The type '#{declaredType}' of getter '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden field inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDE_SETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_SETTER,
-          "The type '#{declaredType}' of setter '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden setter inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDDEN_SETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_SETTER,
-          "This is the overridden setter '#{name}' declared in class "
-          "'#{class}'."),
-
-      MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
-          "The type '#{declaredType}' of field '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden setter inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
-          "The type '#{declaredType}' of setter '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden field inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDE_FIELD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD,
-          "The type '#{declaredType}' of field '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden field inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDDEN_FIELD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_FIELD,
-          "This is the overridden field '#{name}' declared in class "
-          "'#{class}'."),
-
-      MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD:
-        const MessageTemplate(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
-          "Method '#{name}' in '#{class}' can't override field from "
-          "'#{inheritedClass}'."),
-
-      MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT,
-          "This is the field that cannot be overridden by a method."),
-
-      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
-          "Field '#{name}' in '#{class}' can't override method from "
-          "'#{inheritedClass}'."),
-
-      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT,
-          "This is the method that cannot be overridden by a field."),
-
-      MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD:
-        const MessageTemplate(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
-              "Method '#{name}' in '#{class}' can't override getter from "
-              "'#{inheritedClass}'."),
-
-      MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT,
-          "This is the getter that cannot be overridden by a method."),
-
-      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER:
-        const MessageTemplate(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
-          "Getter '#{name}' in '#{class}' can't override method from "
-          "'#{inheritedClass}'."),
-
-      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT,
-          "This is the method that cannot be overridden by a getter."),
-
-      MessageKind.MISSING_FORMALS:
-        const MessageTemplate(MessageKind.MISSING_FORMALS,
-          "Formal parameters are missing."),
-
-      MessageKind.EXTRA_FORMALS:
-        const MessageTemplate(MessageKind.EXTRA_FORMALS,
-          "Formal parameters are not allowed here."),
-
-      MessageKind.UNARY_OPERATOR_BAD_ARITY:
-        const MessageTemplate(MessageKind.UNARY_OPERATOR_BAD_ARITY,
-          "Operator '#{operatorName}' must have no parameters."),
-
-      MessageKind.MINUS_OPERATOR_BAD_ARITY:
-        const MessageTemplate(MessageKind.MINUS_OPERATOR_BAD_ARITY,
-          "Operator '-' must have 0 or 1 parameters."),
-
-      MessageKind.BINARY_OPERATOR_BAD_ARITY:
-        const MessageTemplate(MessageKind.BINARY_OPERATOR_BAD_ARITY,
-          "Operator '#{operatorName}' must have exactly 1 parameter."),
-
-      MessageKind.TERNARY_OPERATOR_BAD_ARITY:
-        const MessageTemplate(MessageKind.TERNARY_OPERATOR_BAD_ARITY,
-          "Operator '#{operatorName}' must have exactly 2 parameters."),
-
-      MessageKind.OPERATOR_OPTIONAL_PARAMETERS:
-        const MessageTemplate(MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
-          "Operator '#{operatorName}' cannot have optional parameters."),
-
-      MessageKind.OPERATOR_NAMED_PARAMETERS:
-        const MessageTemplate(MessageKind.OPERATOR_NAMED_PARAMETERS,
-          "Operator '#{operatorName}' cannot have named parameters."),
-
-      MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE:
-        const MessageTemplate(MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE,
-          "Cannot have return type for constructor."),
-
-      MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR,
-          "Constructors can't return values.",
-          howToFix: "Remove the return statement or use a factory constructor.",
-          examples: const ["""
-class C {
-  C() {
-    return 1;
-  }
-}
-
-main() => new C();"""]),
-
-      MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER:
-        const MessageTemplate(MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER,
-          "Cannot have final modifier on method."),
-
-      MessageKind.ILLEGAL_CONST_FIELD_MODIFIER:
-        const MessageTemplate(MessageKind.ILLEGAL_CONST_FIELD_MODIFIER,
-          "Cannot have const modifier on non-static field.",
-          howToFix:
-            "Try adding a static modifier, or removing the const modifier.",
-          examples: const ["""
-class C {
-  const int a = 1;
-}
-
-main() => new C();"""]),
-
-      MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS:
-        const MessageTemplate(MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
-          "Illegal constructor modifiers: '#{modifiers}'."),
-
-      MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
-              "Illegal mixin application modifiers: '#{modifiers}'."),
-
-      MessageKind.ILLEGAL_MIXIN_SUPERCLASS:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_SUPERCLASS,
-          "Class used as mixin must have Object as superclass."),
-
-      MessageKind.ILLEGAL_MIXIN_OBJECT:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_OBJECT,
-          "Cannot use Object as mixin."),
-
-      MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR,
-          "Class used as mixin cannot have non-factory constructor."),
-
-      MessageKind.ILLEGAL_MIXIN_CYCLE:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_CYCLE,
-          "Class used as mixin introduces mixin cycle: "
-          "'#{mixinName1}' <-> '#{mixinName2}'."),
-
-      MessageKind.ILLEGAL_MIXIN_WITH_SUPER:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
-          "Cannot use class '#{className}' as a mixin because it uses "
-          "'super'."),
-
-      MessageKind.ILLEGAL_MIXIN_SUPER_USE:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_SUPER_USE,
-          "Use of 'super' in class used as mixin."),
-
-      MessageKind.PARAMETER_NAME_EXPECTED:
-        const MessageTemplate(MessageKind.PARAMETER_NAME_EXPECTED,
-          "parameter name expected."),
-
-      MessageKind.CANNOT_RESOLVE_GETTER:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_GETTER,
-          "Cannot resolve getter."),
-
-      MessageKind.CANNOT_RESOLVE_SETTER:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_SETTER,
-          "Cannot resolve setter."),
-
-      MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER:
-        const MessageTemplate(MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER,
-          "Cannot assign a value to final field '#{name}' "
-          "in superclass '#{superclassName}'."),
-
-      MessageKind.ASSIGNING_METHOD:
-        const MessageTemplate(MessageKind.ASSIGNING_METHOD,
-          "Cannot assign a value to a method."),
-
-      MessageKind.ASSIGNING_METHOD_IN_SUPER:
-        const MessageTemplate(MessageKind.ASSIGNING_METHOD_IN_SUPER,
-          "Cannot assign a value to method '#{name}' "
-          "in superclass '#{superclassName}'."),
-
-      MessageKind.ASSIGNING_TYPE:
-        const MessageTemplate(MessageKind.ASSIGNING_TYPE,
-          "Cannot assign a value to a type."),
-
-      MessageKind.IF_NULL_ASSIGNING_TYPE:
-        const MessageTemplate(MessageKind.IF_NULL_ASSIGNING_TYPE,
-          "Cannot assign a value to a type. Note that types are never null, "
-          "so this ??= assignment has no effect.",
-          howToFix: "Try removing the '??=' assignment.",
-          examples: const [
-              "class A {} main() { print(A ??= 3);}",
-          ]),
-
-      MessageKind.VOID_NOT_ALLOWED:
-        const MessageTemplate(MessageKind.VOID_NOT_ALLOWED,
-          "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', "
-            "or a type.",
-          examples: const [
-              "void x; main() {}",
-              "foo(void x) {} main() { foo(null); }",
-          ]),
-
-      MessageKind.NULL_NOT_ALLOWED:
-        const MessageTemplate(MessageKind.NULL_NOT_ALLOWED,
-          "`null` can't be used here."),
-
-      MessageKind.BEFORE_TOP_LEVEL:
-        const MessageTemplate(MessageKind.BEFORE_TOP_LEVEL,
-          "Part header must come before top-level definitions."),
-
-      MessageKind.IMPORT_PART_OF:
-        const MessageTemplate(MessageKind.IMPORT_PART_OF,
-          "The imported library must not have a 'part-of' directive.",
-          howToFix: "Try removing the 'part-of' directive or replacing the "
-                    "import of the library with a 'part' directive.",
-          examples: const [const {
-'main.dart': """
-library library;
-
-import 'part.dart';
-
-main() {}
-""",
-
-'part.dart': """
-part of library;
-"""}]),
-
-      MessageKind.LIBRARY_NAME_MISMATCH:
-        const MessageTemplate(MessageKind.LIBRARY_NAME_MISMATCH,
-          "Expected part of library name '#{libraryName}'.",
-          howToFix: "Try changing the directive to 'part of #{libraryName};'.",
-          examples: const [const {
-'main.dart': """
-library lib.foo;
-
-part 'part.dart';
-
-main() {}
-""",
-
-'part.dart': """
-part of lib.bar;
-"""}]),
-
-      MessageKind.MISSING_LIBRARY_NAME:
-        const MessageTemplate(MessageKind.MISSING_LIBRARY_NAME,
-          "Library has no name. Part directive expected library name "
-          "to be '#{libraryName}'.",
-          howToFix: "Try adding 'library #{libraryName};' to the library.",
-          examples: const [const {
-'main.dart': """
-part 'part.dart';
-
-main() {}
-""",
-
-'part.dart': """
-part of lib.foo;
-"""}]),
-
-      MessageKind.THIS_IS_THE_PART_OF_TAG:
-        const MessageTemplate(MessageKind.THIS_IS_THE_PART_OF_TAG,
-          "This is the part of directive."),
-
-      MessageKind.MISSING_PART_OF_TAG:
-        const MessageTemplate(MessageKind.MISSING_PART_OF_TAG,
-          "This file has no part-of tag, but it is being used as a part."),
-
-      MessageKind.DUPLICATED_PART_OF:
-        const MessageTemplate(MessageKind.DUPLICATED_PART_OF,
-          "Duplicated part-of directive."),
-
-      MessageKind.DUPLICATED_LIBRARY_NAME:
-        const MessageTemplate(MessageKind.DUPLICATED_LIBRARY_NAME,
-          "Duplicated library name '#{libraryName}'."),
-
-      MessageKind.DUPLICATED_RESOURCE:
-        const MessageTemplate(MessageKind.DUPLICATED_RESOURCE,
-          "The resource '#{resourceUri}' is loaded through both "
-          "'#{canonicalUri1}' and '#{canonicalUri2}'."),
-
-      MessageKind.DUPLICATED_LIBRARY_RESOURCE:
-        const MessageTemplate(MessageKind.DUPLICATED_LIBRARY_RESOURCE,
-          "The library '#{libraryName}' in '#{resourceUri}' is loaded through "
-          "both '#{canonicalUri1}' and '#{canonicalUri2}'."),
-
-      // This is used as an exception.
-      MessageKind.INVALID_SOURCE_FILE_LOCATION:
-        const MessageTemplate(MessageKind.INVALID_SOURCE_FILE_LOCATION, '''
-Invalid offset (#{offset}) in source map.
-File: #{fileName}
-Length: #{length}'''),
-
-      MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC:
-        const MessageTemplate(MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC,
-              "Top-level variable cannot be declared static."),
-
-      MessageKind.REFERENCE_IN_INITIALIZATION:
-        const MessageTemplate(MessageKind.REFERENCE_IN_INITIALIZATION,
-           "Variable '#{variableName}' is referenced during its "
-           "initialization.",
-           howToFix:
-             "If you are trying to reference a shadowed variable, rename "
-             "one of the variables.",
-           examples: const ["""
-foo(t) {
-  var t = t;
-  return t;
-}
-
-main() => foo(1);
-"""]),
-
-      MessageKind.CONST_WITHOUT_INITIALIZER:
-        const MessageTemplate(MessageKind.CONST_WITHOUT_INITIALIZER,
-          "A constant variable must be initialized.",
-          howToFix: "Try adding an initializer or "
-                    "removing the 'const' modifier.",
-          examples: const ["""
-void main() {
-  const c; // This constant variable must be initialized.
-}"""]),
-
-      MessageKind.FINAL_WITHOUT_INITIALIZER:
-        const MessageTemplate(MessageKind.FINAL_WITHOUT_INITIALIZER,
-          "A final variable must be initialized.",
-          howToFix: "Try adding an initializer or "
-                    "removing the 'final' modifier.",
-          examples: const [
-              "class C { static final field; } main() => C.field;"]),
-
-      MessageKind.MEMBER_USES_CLASS_NAME:
-        const MessageTemplate(MessageKind.MEMBER_USES_CLASS_NAME,
-          "Member variable can't have the same name as the class it is "
-          "declared in.",
-          howToFix: "Try renaming the variable.",
-          examples: const ["""
-class A { var A; }
-main() {
-  var a = new A();
-  a.A = 1;
-}
-""", """
-class A { static var A; }
-main() => A.A = 1;
-"""]),
-
-      MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT:
-        const MessageTemplate(
-          MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT,
-          "Wrong number of arguments to assert. Should be 1, but given "
-          "#{argumentCount}."),
-
-      MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS:
-        const MessageTemplate(MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS,
-          "'assert' takes no named arguments, but given #{argumentCount}."),
-
-      MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY:
-        const MessageTemplate(MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY,
-          "Factory redirection only allowed in factories."),
-
-      MessageKind.MISSING_FACTORY_KEYWORD:
-        const MessageTemplate(MessageKind.MISSING_FACTORY_KEYWORD,
-          "Did you forget a factory keyword here?"),
-
-      MessageKind.NO_SUCH_METHOD_IN_NATIVE:
-        const MessageTemplate(MessageKind.NO_SUCH_METHOD_IN_NATIVE,
-          "'NoSuchMethod' is not supported for classes that extend native "
-          "classes."),
-
-      MessageKind.DEFERRED_LIBRARY_DART_2_DART:
-        const MessageTemplate(MessageKind.DEFERRED_LIBRARY_DART_2_DART,
-          "Deferred loading is not supported by the dart backend yet. "
-          "The output will not be split."),
-
-      MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX:
-        const MessageTemplate(MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX,
-          "This import is deferred but there is no prefix keyword.",
-          howToFix: "Try adding a prefix to the import."),
-
-      MessageKind.DEFERRED_OLD_SYNTAX:
-        const MessageTemplate(MessageKind.DEFERRED_OLD_SYNTAX,
-          "The DeferredLibrary annotation is obsolete.",
-          howToFix:
-            "Use the \"import 'lib.dart' deferred as prefix\" syntax instead."),
-
-      MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX:
-        const MessageTemplate(MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX,
-          "The prefix of this deferred import is not unique.",
-          howToFix: "Try changing the import prefix."),
-
-      MessageKind.DEFERRED_TYPE_ANNOTATION:
-        const MessageTemplate(MessageKind.DEFERRED_TYPE_ANNOTATION,
-          "The type #{node} is deferred. "
-          "Deferred types are not valid as type annotations.",
-          howToFix:
-            "Try using a non-deferred abstract class as an interface."),
-
-      MessageKind.ILLEGAL_STATIC:
-        const MessageTemplate(MessageKind.ILLEGAL_STATIC,
-          "Modifier static is only allowed on functions declared in "
-          "a class."),
-
-      MessageKind.STATIC_FUNCTION_BLOAT:
-        const MessageTemplate(MessageKind.STATIC_FUNCTION_BLOAT,
-          "Using '#{class}.#{name}' may lead to unnecessarily large "
-          "generated code.",
-          howToFix:
-              "Try adding '@MirrorsUsed(...)' as described at "
-              "https://goo.gl/Akrrog."),
-
-      MessageKind.NON_CONST_BLOAT:
-        const MessageTemplate(MessageKind.NON_CONST_BLOAT,
-          "Using 'new #{name}' may lead to unnecessarily large generated "
-          "code.",
-          howToFix:
-              "Try using 'const #{name}' or adding '@MirrorsUsed(...)' as "
-              "described at https://goo.gl/Akrrog."),
-
-      MessageKind.STRING_EXPECTED:
-        const MessageTemplate(MessageKind.STRING_EXPECTED,
-          "Expected a 'String', but got an instance of '#{type}'."),
-
-      MessageKind.PRIVATE_IDENTIFIER:
-        const MessageTemplate(MessageKind.PRIVATE_IDENTIFIER,
-          "'#{value}' is not a valid Symbol name because it starts with "
-          "'_'."),
-
-      MessageKind.PRIVATE_NAMED_PARAMETER:
-        const MessageTemplate(MessageKind.PRIVATE_NAMED_PARAMETER,
-          "Named optional parameter can't have a library private name.",
-          howToFix:
-            "Try removing the '_' or making the parameter positional or "
-            "required.",
-          examples: const ["""foo({int _p}) {} main() => foo();"""]),
-
-      MessageKind.UNSUPPORTED_LITERAL_SYMBOL:
-        const MessageTemplate(MessageKind.UNSUPPORTED_LITERAL_SYMBOL,
-          "Symbol literal '##{value}' is currently unsupported by dart2js."),
-
-      MessageKind.INVALID_SYMBOL:
-        const MessageTemplate(MessageKind.INVALID_SYMBOL, '''
-'#{value}' is not a valid Symbol name because is not:
- * an empty String,
- * a user defined operator,
- * a qualified non-private identifier optionally followed by '=', or
- * a qualified non-private identifier followed by '.' and a user-defined '''
-"operator."),
-
-      MessageKind.AMBIGUOUS_REEXPORT:
-        const MessageTemplate(MessageKind.AMBIGUOUS_REEXPORT,
-          "'#{name}' is (re)exported by multiple libraries."),
-
-      MessageKind.AMBIGUOUS_LOCATION:
-        const MessageTemplate(MessageKind.AMBIGUOUS_LOCATION,
-          "'#{name}' is defined here."),
-
-      MessageKind.IMPORTED_HERE:
-        const MessageTemplate(MessageKind.IMPORTED_HERE,
-          "'#{name}' is imported here."),
-
-      MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE:
-        const MessageTemplate(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
-          "The class '#{class}' overrides 'operator==', "
-          "but not 'get hashCode'."),
-
-      MessageKind.INTERNAL_LIBRARY_FROM:
-        const MessageTemplate(MessageKind.INTERNAL_LIBRARY_FROM,
-          "Internal library '#{resolvedUri}' is not accessible from "
-          "'#{importingUri}'."),
-
-      MessageKind.INTERNAL_LIBRARY:
-        const MessageTemplate(MessageKind.INTERNAL_LIBRARY,
-          "Internal library '#{resolvedUri}' is not accessible."),
-
-      MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS:
-        const MessageTemplate(
-          MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS,
-          "Js-interop class '#{cls}' cannot extend from the non js-interop "
-          "class '#{superclass}'.",
-          howToFix: "Annotate the superclass with @JS.",
-          examples: const [
-              """
-              import 'package:js/js.dart';
-
-              class Foo { }
-
-              @JS()
-              class Bar extends Foo { }
-
-              main() {
-                new Bar();
-              }
-              """]),
-
-      MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER:
-        const MessageTemplate(
-          MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
-          "Member '#{member}' in js-interop class '#{cls}' is not external.",
-          howToFix: "Mark all interop methods external",
-          examples: const [
-              """
-              import 'package:js/js.dart';
-
-              @JS()
-              class Foo {
-                bar() {}
-              }
-
-              main() {
-                new Foo().bar();
-              }
-              """]),
-
-      MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS:
-        const MessageTemplate(
-          MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS,
-          "Js-interop method '#{method}' has named arguments but is not "
-          "a factory constructor of an @anonymous @JS class.",
-          howToFix: "Remove all named arguments from js-interop method or "
-                    "in the case of a factory constructor annotate the class "
-                    "as @anonymous.",
-          examples: const [
-              """
-              import 'package:js/js.dart';
-
-              @JS()
-              class Foo {
-                external bar(foo, {baz});
-              }
-
-              main() {
-                new Foo().bar(4, baz: 5);
-              }
-              """]),
-
-      MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS:
-        const MessageTemplate(
-          MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
-          "Parameter '#{parameter}' in anonymous js-interop class '#{cls}' "
-          "object literal constructor is positional instead of named."
-          ".",
-          howToFix: "Make all arguments in external factory object literal "
-                    "constructors named.",
-          examples: const [
-              """
-              import 'package:js/js.dart';
-
-              @anonymous
-              @JS()
-              class Foo {
-                external factory Foo(foo, {baz});
-              }
-
-              main() {
-                new Foo(5, baz: 5);
-              }
-              """]),
-
-      MessageKind.LIBRARY_NOT_FOUND:
-        const MessageTemplate(MessageKind.LIBRARY_NOT_FOUND,
-          "Library not found '#{resolvedUri}'."),
-
-      MessageKind.LIBRARY_NOT_SUPPORTED:
-        const MessageTemplate(MessageKind.LIBRARY_NOT_SUPPORTED,
-          "Library not supported '#{resolvedUri}'.",
-          howToFix: "Try removing the dependency or enabling support using "
-                    "the '--categories' option.",
-          examples: const [/*
-              """
-              import 'dart:io';
-              main() {}
-              """
-          */]),
-          // TODO(johnniwinther): Enable example when message_kind_test.dart
-          // supports library loader callbacks.
-
-      MessageKind.UNSUPPORTED_EQ_EQ_EQ:
-        const MessageTemplate(MessageKind.UNSUPPORTED_EQ_EQ_EQ,
-          "'===' is not an operator. "
-          "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?"),
-
-      MessageKind.UNSUPPORTED_BANG_EQ_EQ:
-        const MessageTemplate(MessageKind.UNSUPPORTED_BANG_EQ_EQ,
-          "'!==' is not an operator. "
-          "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?"),
-
-      MessageKind.UNSUPPORTED_PREFIX_PLUS:
-        const MessageTemplate(MessageKind.UNSUPPORTED_PREFIX_PLUS,
-          "'+' is not a prefix operator. ",
-          howToFix: "Try removing '+'.",
-          examples: const [
-              "main() => +2;  // No longer a valid way to write '2'"
-          ]),
-
-      MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP:
-        const MessageTemplate(MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP,
-          "No expression after 'throw'. "
-          "Did you mean 'rethrow'?"),
-
-      MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX:
-        const MessageTemplate(MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX,
-          "'typedef' not allowed here. ",
-          howToFix: "Try replacing 'typedef' with 'class'.",
-          examples: const [
-              """
-class B { }
-class M1 {  }
-typedef C = B with M1;  // Need to replace 'typedef' with 'class'.
-main() { new C(); }
-"""]),
-
-      MessageKind.MIRRORS_EXPECTED_STRING:
-        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING,
-          "Can't use '#{name}' here because it's an instance of '#{type}' "
-          "and a 'String' value is expected.",
-          howToFix: "Did you forget to add quotes?",
-          examples: const [
-              """
-// 'Foo' is a type literal, not a string.
-@MirrorsUsed(symbols: const [Foo])
-import 'dart:mirrors';
-
-class Foo {}
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE:
-        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE,
-          "Can't use '#{name}' here because it's an instance of '#{type}' "
-          "and a 'String' or 'Type' value is expected.",
-          howToFix: "Did you forget to add quotes?",
-          examples: const [
-              """
-// 'main' is a method, not a class.
-@MirrorsUsed(targets: const [main])
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST:
-        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST,
-          "Can't use '#{name}' here because it's an instance of '#{type}' "
-          "and a 'String' or 'List' value is expected.",
-          howToFix: "Did you forget to add quotes?",
-          examples: const [
-              """
-// 'Foo' is not a string.
-@MirrorsUsed(symbols: Foo)
-import 'dart:mirrors';
-
-class Foo {}
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST:
-        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST,
-          "Can't use '#{name}' here because it's an instance of '#{type}' "
-          "but a 'String', 'Type', or 'List' value is expected.",
-          howToFix: "Did you forget to add quotes?",
-          examples: const [
-              """
-// '1' is not a string.
-@MirrorsUsed(targets: 1)
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY:
-        const MessageTemplate(
-          MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY,
-          "Can't find '#{name}' in the current library.",
-          // TODO(ahe): The closest identifiers in edit distance would be nice.
-          howToFix: "Did you forget to add an import?",
-          examples: const [
-              """
-// 'window' is not in scope because dart:html isn't imported.
-@MirrorsUsed(targets: 'window')
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY:
-        const MessageTemplate(MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY,
-          "Can't find '#{name}' in the library '#{library}'.",
-          // TODO(ahe): The closest identifiers in edit distance would be nice.
-          howToFix: "Is '#{name}' spelled right?",
-          examples: const [
-              """
-// 'List' is misspelled.
-@MirrorsUsed(targets: 'dart.core.Lsit')
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT:
-        const MessageTemplate(MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT,
-          "Can't find '#{name}' in '#{element}'.",
-          // TODO(ahe): The closest identifiers in edit distance would be nice.
-          howToFix: "Is '#{name}' spelled right?",
-          examples: const [
-              """
-// 'addAll' is misspelled.
-@MirrorsUsed(targets: 'dart.core.List.addAl')
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.INVALID_URI:
-        const MessageTemplate(MessageKind.INVALID_URI,
-          "'#{uri}' is not a valid URI.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-            """
-// can't have a '[' in a URI
-import '../../Udyn[mic ils/expect.dart';
-
-main() {}
-"""]),
-
-      MessageKind.INVALID_PACKAGE_CONFIG:
-          const MessageTemplate(MessageKind.INVALID_PACKAGE_CONFIG,
-            """Package config file '#{uri}' is invalid.
-#{exception}""",
-            howToFix: DONT_KNOW_HOW_TO_FIX
-      ),
-
-      MessageKind.INVALID_PACKAGE_URI:
-        const MessageTemplate(MessageKind.INVALID_PACKAGE_URI,
-          "'#{uri}' is not a valid package URI (#{exception}).",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-            """
-// can't have a 'top level' package URI
-import 'package:foo.dart';
-
-main() {}
-""", """
-// can't have 2 slashes
-import 'package://foo/foo.dart';
-
-main() {}
-""", """
-// package name must be valid
-import 'package:not\valid/foo.dart';
-
-main() {}
-"""]),
-
-      MessageKind.READ_SCRIPT_ERROR:
-        const MessageTemplate(MessageKind.READ_SCRIPT_ERROR,
-          "Can't read '#{uri}' (#{exception}).",
-          // Don't know how to fix since the underlying error is unknown.
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-              """
-// 'foo.dart' does not exist.
-import 'foo.dart';
-
-main() {}
-"""]),
-
-      MessageKind.READ_SELF_ERROR:
-        const MessageTemplate(MessageKind.READ_SELF_ERROR,
-          "#{exception}",
-          // Don't know how to fix since the underlying error is unknown.
-          howToFix: DONT_KNOW_HOW_TO_FIX),
-
-      MessageKind.EXTRANEOUS_MODIFIER:
-        const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER,
-          "Can't have modifier '#{modifier}' here.",
-          howToFix: "Try removing '#{modifier}'.",
-          examples: const [
-              "var String foo; main(){}",
-              // "var get foo; main(){}",
-              "var set foo; main(){}",
-              "var final foo; main(){}",
-              "var var foo; main(){}",
-              "var const foo; main(){}",
-              "var abstract foo; main(){}",
-              "var static foo; main(){}",
-              "var external foo; main(){}",
-              "get var foo; main(){}",
-              "set var foo; main(){}",
-              "final var foo; main(){}",
-              "var var foo; main(){}",
-              "const var foo; main(){}",
-              "abstract var foo; main(){}",
-              "static var foo; main(){}",
-              "external var foo; main(){}"]),
-
-      MessageKind.EXTRANEOUS_MODIFIER_REPLACE:
-        const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER_REPLACE,
-          "Can't have modifier '#{modifier}' here.",
-          howToFix:
-            "Try replacing modifier '#{modifier}' with 'var', 'final', "
-            "or a type.",
-          examples: const [
-              // "get foo; main(){}",
-              "set foo; main(){}",
-              "abstract foo; main(){}",
-              "static foo; main(){}",
-              "external foo; main(){}"]),
-
-      MessageKind.ABSTRACT_CLASS_INSTANTIATION:
-        const MessageTemplate(MessageKind.ABSTRACT_CLASS_INSTANTIATION,
-          "Can't instantiate abstract class.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const ["abstract class A {} main() { new A(); }"]),
-
-      MessageKind.BODY_EXPECTED:
-        const MessageTemplate(MessageKind.BODY_EXPECTED,
-          "Expected a function body or '=>'.",
-          // TODO(ahe): In some scenarios, we can suggest removing the 'static'
-          // keyword.
-          howToFix: "Try adding {}.",
-          examples: const [
-              "main();"]),
-
-      MessageKind.MIRROR_BLOAT:
-        const MessageTemplate(MessageKind.MIRROR_BLOAT,
-          "#{count} methods retained for use by dart:mirrors out of #{total}"
-          " total methods (#{percentage}%)."),
-
-      MessageKind.MIRROR_IMPORT:
-        const MessageTemplate(MessageKind.MIRROR_IMPORT,
-          "Import of 'dart:mirrors'."),
-
-      MessageKind.MIRROR_IMPORT_NO_USAGE:
-        const MessageTemplate(MessageKind.MIRROR_IMPORT_NO_USAGE,
-          "This import is not annotated with @MirrorsUsed, which may lead to "
-          "unnecessarily large generated code.",
-          howToFix:
-              "Try adding '@MirrorsUsed(...)' as described at "
-              "https://goo.gl/Akrrog."),
-
-      MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT:
-        const MessageTemplate(
-          MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT,
-          "Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant."),
-
-      MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD:
-        const MessageTemplate(MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
-              "'#{keyword}' is a reserved word and can't be used here.",
-              howToFix: "Try using a different name.",
-              examples: const ["do() {} main() {}"]),
-
-      MessageKind. NAMED_FUNCTION_EXPRESSION:
-        const MessageTemplate(MessageKind.NAMED_FUNCTION_EXPRESSION,
-          "Function expression '#{name}' cannot be named.",
-          howToFix: "Try removing the name.",
-          examples: const ["main() { var f = func() {}; }"]),
-
-      MessageKind.UNUSED_METHOD:
-        const MessageTemplate(MessageKind.UNUSED_METHOD,
-          "The method '#{name}' is never called.",
-          howToFix: "Consider deleting it.",
-          examples: const ["deadCode() {} main() {}"]),
-
-      MessageKind.UNUSED_CLASS:
-        const MessageTemplate(MessageKind.UNUSED_CLASS,
-          "The class '#{name}' is never used.",
-          howToFix: "Consider deleting it.",
-          examples: const ["class DeadCode {} main() {}"]),
-
-      MessageKind.UNUSED_TYPEDEF:
-        const MessageTemplate(MessageKind.UNUSED_TYPEDEF,
-          "The typedef '#{name}' is never used.",
-          howToFix: "Consider deleting it.",
-          examples: const ["typedef DeadCode(); main() {}"]),
-
-      MessageKind.ABSTRACT_METHOD:
-        const MessageTemplate(MessageKind.ABSTRACT_METHOD,
-          "The method '#{name}' has no implementation in "
-          "class '#{class}'.",
-          howToFix: "Try adding a body to '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-class Class {
-  method();
-}
-main() => new Class().method();
-"""]),
-
-      MessageKind.ABSTRACT_GETTER:
-        const MessageTemplate(MessageKind.ABSTRACT_GETTER,
-          "The getter '#{name}' has no implementation in "
-          "class '#{class}'.",
-          howToFix: "Try adding a body to '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-class Class {
-  get getter;
-}
-main() => new Class();
-"""]),
-
-      MessageKind.ABSTRACT_SETTER:
-        const MessageTemplate(MessageKind.ABSTRACT_SETTER,
-          "The setter '#{name}' has no implementation in "
-          "class '#{class}'.",
-          howToFix: "Try adding a body to '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-class Class {
-  set setter(_);
-}
-main() => new Class();
-"""]),
-
-      MessageKind.INHERIT_GETTER_AND_METHOD:
-        const MessageTemplate(MessageKind.INHERIT_GETTER_AND_METHOD,
-          "The class '#{class}' can't inherit both getters and methods "
-          "by the named '#{name}'.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const ["""
-class A {
-  get member => null;
-}
-class B {
-  member() {}
-}
-class Class implements A, B {
-}
-main() => new Class();
-"""]),
-
-      MessageKind.INHERITED_METHOD:
-        const MessageTemplate(MessageKind.INHERITED_METHOD,
-          "The inherited method '#{name}' is declared here in class "
-          "'#{class}'."),
-
-      MessageKind.INHERITED_EXPLICIT_GETTER:
-        const MessageTemplate(MessageKind.INHERITED_EXPLICIT_GETTER,
-          "The inherited getter '#{name}' is declared here in class "
-          "'#{class}'."),
-
-      MessageKind.INHERITED_IMPLICIT_GETTER:
-        const MessageTemplate(MessageKind.INHERITED_IMPLICIT_GETTER,
-          "The inherited getter '#{name}' is implicitly declared by this "
-          "field in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_METHOD_ONE:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD_ONE,
-          "'#{class}' doesn't implement '#{method}' "
-          "declared in '#{declarer}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  m();
-}
-class C implements I {}
-main() => new C();
-""", """
-abstract class I {
-  m();
-}
-class C extends I {}
-main() => new C();
-"""]),
-
-      MessageKind.UNIMPLEMENTED_METHOD:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD,
-          "'#{class}' doesn't implement '#{method}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  m();
-}
-
-abstract class J {
-  m();
-}
-
-class C implements I, J {}
-
-main() {
- new C();
-}
-""", """
-abstract class I {
-  m();
-}
-
-abstract class J {
-  m();
-}
-
-class C extends I implements J {}
-
-main() {
- new C();
-}
-"""]),
-
-      MessageKind.UNIMPLEMENTED_METHOD_CONT:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD_CONT,
-          "The method '#{name}' is declared here in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_SETTER_ONE:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_SETTER_ONE,
-          "'#{class}' doesn't implement the setter '#{name}' "
-          "declared in '#{declarer}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  set m(_);
-}
-class C implements I {}
-class D implements I {
-  set m(_) {}
-}
-main() {
- new D().m = 0;
- new C();
-}
-"""]),
-
-      MessageKind.UNIMPLEMENTED_SETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_SETTER,
-          "'#{class}' doesn't implement the setter '#{name}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  set m(_);
-}
-abstract class J {
-  set m(_);
-}
-class C implements I, J {}
-main() => new C();
-""", """
-abstract class I {
-  set m(_);
-}
-abstract class J {
-  set m(_);
-}
-class C extends I implements J {}
-main() => new C();
-"""]),
-
-      MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
-          "The setter '#{name}' is declared here in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER,
-          "The setter '#{name}' is implicitly declared by this field "
-          "in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_GETTER_ONE:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_GETTER_ONE,
-          "'#{class}' doesn't implement the getter '#{name}' "
-          "declared in '#{declarer}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  get m;
-}
-class C implements I {}
-main() => new C();
-""", """
-abstract class I {
-  get m;
-}
-class C extends I {}
-main() => new C();
-"""]),
-
-      MessageKind.UNIMPLEMENTED_GETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_GETTER,
-          "'#{class}' doesn't implement the getter '#{name}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  get m;
-}
-abstract class J {
-  get m;
-}
-class C implements I, J {}
-main() => new C();
-""", """
-abstract class I {
-  get m;
-}
-abstract class J {
-  get m;
-}
-class C extends I implements J {}
-main() => new C();
-"""]),
-
-      MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
-          "The getter '#{name}' is declared here in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
-          "The getter '#{name}' is implicitly declared by this field "
-          "in class '#{class}'."),
-
-      MessageKind.EQUAL_MAP_ENTRY_KEY:
-        const MessageTemplate(MessageKind.EQUAL_MAP_ENTRY_KEY,
-          "An entry with the same key already exists in the map.",
-          howToFix:
-            "Try removing the previous entry or changing the key in one "
-            "of the entries.",
-          examples: const ["""
-main() {
-  var m = const {'foo': 1, 'foo': 2};
-}"""]),
-
-      MessageKind.BAD_INPUT_CHARACTER:
-        const MessageTemplate(MessageKind.BAD_INPUT_CHARACTER,
-          "Character U+#{characterHex} isn't allowed here.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const ["""
-main() {
-  String x = ç;
-}
-"""]),
-
-      MessageKind.UNTERMINATED_STRING:
-        const MessageTemplate(MessageKind.UNTERMINATED_STRING,
-          "String must end with #{quote}.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const ["""
-main() {
-  return '
-;
-}
-""",
-"""
-main() {
-  return \"
-;
-}
-""",
-"""
-main() {
-  return r'
-;
-}
-""",
-"""
-main() {
-  return r\"
-;
-}
-""",
-"""
-main() => '''
-""",
-"""
-main() => \"\"\"
-""",
-"""
-main() => r'''
-""",
-"""
-main() => r\"\"\"
-"""]),
-
-      MessageKind.UNMATCHED_TOKEN:
-        const MessageTemplate(MessageKind.UNMATCHED_TOKEN,
-          "Can't find '#{end}' to match '#{begin}'.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const[
-              "main(",
-              "main(){",
-              "main(){]}",
-            ]),
-
-      MessageKind.UNTERMINATED_TOKEN:
-        const MessageTemplate(MessageKind.UNTERMINATED_TOKEN,
-          // This is a fall-back message that shouldn't happen.
-          "Incomplete token."),
-
-      MessageKind.EXPONENT_MISSING:
-        const MessageTemplate(MessageKind.EXPONENT_MISSING,
-          "Numbers in exponential notation should always contain an exponent"
-          " (an integer number with an optional sign).",
-          howToFix:
-            "Make sure there is an exponent, and remove any whitespace "
-            "before it.",
-          examples: const ["""
-main() {
-  var i = 1e;
-}
-"""]),
-
-      MessageKind.HEX_DIGIT_EXPECTED:
-        const MessageTemplate(MessageKind.HEX_DIGIT_EXPECTED,
-          "A hex digit (0-9 or A-F) must follow '0x'.",
-          howToFix:
-            DONT_KNOW_HOW_TO_FIX, // Seems obvious from the error message.
-          examples: const ["""
-main() {
-  var i = 0x;
-}
-"""]),
-
-      MessageKind.MALFORMED_STRING_LITERAL:
-        const MessageTemplate(MessageKind.MALFORMED_STRING_LITERAL,
-          r"A '$' has special meaning inside a string, and must be followed by "
-          "an identifier or an expression in curly braces ({}).",
-          howToFix: r"Try adding a backslash (\) to escape the '$'.",
-          examples: const [r"""
-main() {
-  return '$';
-}
-""",
-r'''
-main() {
-  return "$";
-}
-''',
-r"""
-main() {
-  return '''$''';
-}
-""",
-r'''
-main() {
-  return """$""";
-}
-''']),
-
-      MessageKind.UNTERMINATED_COMMENT:
-        const MessageTemplate(MessageKind.UNTERMINATED_COMMENT,
-          "Comment starting with '/*' must end with '*/'.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [r"""
-main() {
-}
-/*"""]),
-
-      MessageKind.MISSING_TOKEN_BEFORE_THIS:
-        const MessageTemplate(MessageKind.MISSING_TOKEN_BEFORE_THIS,
-          "Expected '#{token}' before this.",
-          // Consider the second example below: the parser expects a ')' before
-          // 'y', but a ',' would also have worked. We don't have enough
-          // information to give a good suggestion.
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-              "main() => true ? 1;",
-              "main() => foo(x: 1 y: 2);",
-            ]),
-
-      MessageKind.MISSING_TOKEN_AFTER_THIS:
-        const MessageTemplate(MessageKind.MISSING_TOKEN_AFTER_THIS,
-          "Expected '#{token}' after this.",
-          // See [MISSING_TOKEN_BEFORE_THIS], we don't have enough information
-          // to give a good suggestion.
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-              "main(x) {x}",
-"""
-class S1 {}
-class S2 {}
-class S3 {}
-class A = S1 with S2, S3
-main() => new A();
-"""
-]),
-
-      MessageKind.CONSIDER_ANALYZE_ALL:
-        const MessageTemplate(MessageKind.CONSIDER_ANALYZE_ALL,
-          "Could not find '#{main}'.  Nothing will be analyzed.",
-          howToFix: "Try using '--analyze-all' to analyze everything.",
-          examples: const ['']),
-
-      MessageKind.MISSING_MAIN:
-        const MessageTemplate(MessageKind.MISSING_MAIN,
-          "Could not find '#{main}'.",
-          howToFix: "Try adding a method named '#{main}' to your program."
-          /* No example, test uses '--analyze-only' which will produce the above
-           * message [CONSIDER_ANALYZE_ALL].  An example for a human operator
-           * would be an empty file.*/),
-
-      MessageKind.MAIN_NOT_A_FUNCTION:
-        const MessageTemplate(MessageKind.MAIN_NOT_A_FUNCTION,
-          "'#{main}' is not a function.",
-          howToFix: DONT_KNOW_HOW_TO_FIX, /* Don't state the obvious. */
-          examples: const ['var main;']),
-
-      MessageKind.MAIN_WITH_EXTRA_PARAMETER:
-        const MessageTemplate(MessageKind.MAIN_WITH_EXTRA_PARAMETER,
-          "'#{main}' cannot have more than two parameters.",
-          howToFix: DONT_KNOW_HOW_TO_FIX, /* Don't state the obvious. */
-          examples: const ['main(a, b, c) {}']),
-
-      MessageKind.COMPILER_CRASHED:
-        const MessageTemplate(MessageKind.COMPILER_CRASHED,
-          "The compiler crashed when compiling this element."),
-
-      MessageKind.PLEASE_REPORT_THE_CRASH:
-        const MessageTemplate(MessageKind.PLEASE_REPORT_THE_CRASH, '''
-The compiler is broken.
-
-When compiling the above element, the compiler crashed. It is not
-possible to tell if this is caused by a problem in your program or
-not. Regardless, the compiler should not crash.
-
-The Dart team would greatly appreciate if you would take a moment to
-report this problem at http://dartbug.com/new.
-
-Please include the following information:
-
-* the name and version of your operating system,
-
-* the Dart SDK build number (#{buildId}), and
-
-* the entire message you see here (including the full stack trace
-  below as well as the source location above).
-'''),
-
-      MessageKind.POTENTIAL_MUTATION:
-        const MessageTemplate(MessageKind.POTENTIAL_MUTATION,
-          "Variable '#{variableName}' is not known to be of type "
-          "'#{shownType}' because it is potentially mutated in the scope for "
-          "promotion."),
-
-      MessageKind.POTENTIAL_MUTATION_HERE:
-        const MessageTemplate(MessageKind.POTENTIAL_MUTATION_HERE,
-          "Variable '#{variableName}' is potentially mutated here."),
-
-      MessageKind.POTENTIAL_MUTATION_IN_CLOSURE:
-        const MessageTemplate(MessageKind.POTENTIAL_MUTATION_IN_CLOSURE,
-          "Variable '#{variableName}' is not known to be of type "
-          "'#{shownType}' because it is potentially mutated within a closure."),
-
-      MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE:
-        const MessageTemplate(MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE,
-              "Variable '#{variableName}' is potentially mutated in a "
-              "closure here."),
-
-      MessageKind.ACCESSED_IN_CLOSURE:
-        const MessageTemplate(MessageKind.ACCESSED_IN_CLOSURE,
-          "Variable '#{variableName}' is not known to be of type "
-          "'#{shownType}' because it is accessed by a closure in the scope for "
-          "promotion and potentially mutated in the scope of "
-          "'#{variableName}'."),
-
-      MessageKind.ACCESSED_IN_CLOSURE_HERE:
-        const MessageTemplate(MessageKind.ACCESSED_IN_CLOSURE_HERE,
-          "Variable '#{variableName}' is accessed in a closure here."),
-
-      MessageKind.NOT_MORE_SPECIFIC:
-        const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC,
-          "Variable '#{variableName}' is not shown to have type "
-          "'#{shownType}' because '#{shownType}' is not more specific than the "
-          "known type '#{knownType}' of '#{variableName}'."),
-
-      MessageKind.NOT_MORE_SPECIFIC_SUBTYPE:
-        const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC_SUBTYPE,
-          "Variable '#{variableName}' is not shown to have type "
-          "'#{shownType}' because '#{shownType}' is not a subtype of the "
-          "known type '#{knownType}' of '#{variableName}'."),
-
-      MessageKind.NOT_MORE_SPECIFIC_SUGGESTION:
-        const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC_SUGGESTION,
-          "Variable '#{variableName}' is not shown to have type "
-          "'#{shownType}' because '#{shownType}' is not more specific than the "
-          "known type '#{knownType}' of '#{variableName}'.",
-          howToFix:
-            "Try replacing '#{shownType}' with '#{shownTypeSuggestion}'."),
-
-      MessageKind.NO_COMMON_SUBTYPES:
-        const MessageTemplate(MessageKind.NO_COMMON_SUBTYPES,
-           "Types '#{left}' and '#{right}' have no common subtypes."),
-
-      MessageKind.HIDDEN_WARNINGS_HINTS:
-        const MessageTemplate(MessageKind.HIDDEN_WARNINGS_HINTS,
-          "#{warnings} warning(s) and #{hints} hint(s) suppressed in #{uri}."),
-
-      MessageKind.HIDDEN_WARNINGS:
-        const MessageTemplate(MessageKind.HIDDEN_WARNINGS,
-          "#{warnings} warning(s) suppressed in #{uri}."),
-
-      MessageKind.HIDDEN_HINTS:
-        const MessageTemplate(MessageKind.HIDDEN_HINTS,
-          "#{hints} hint(s) suppressed in #{uri}."),
-
-      MessageKind.PREAMBLE:
-        const MessageTemplate(MessageKind.PREAMBLE,
-        "When run on the command-line, the compiled output might"
-        " require a preamble file located in:\n"
-        "  <sdk>/lib/_internal/js_runtime/lib/preambles."),
-
-      MessageKind.INVALID_SYNC_MODIFIER:
-        const MessageTemplate(MessageKind.INVALID_SYNC_MODIFIER,
-          "Invalid modifier 'sync'.",
-          options: const ['--enable-async'],
-          howToFix: "Try replacing 'sync' with 'sync*'.",
-          examples: const [
-            "main() sync {}"
-          ]),
-
-      MessageKind.INVALID_AWAIT_FOR:
-        const MessageTemplate(MessageKind.INVALID_AWAIT_FOR,
-          "'await' is only supported on for-in loops.",
-          options: const ['--enable-async'],
-          howToFix: "Try rewriting the loop as a for-in loop or removing the "
-                    "'await' keyword.",
-          examples: const ["""
-main() async* {
-  await for (int i = 0; i < 10; i++) {}
-}
-"""]),
-
-      MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD:
-        const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
-          "The modifier '#{modifier}' is not allowed on an abstract method.",
-          options: const ['--enable-async'],
-          howToFix: "Try removing the '#{modifier}' modifier or adding a "
-                    "body to the method.",
-          examples: const ["""
-abstract class A {
-  method() async;
-}
-class B extends A {
-  method() {}
-}
-main() {
-  A a = new B();
-  a.method();
-}
-"""]),
-
-      MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
-              "The modifier '#{modifier}' is not allowed on constructors.",
-              options: const ['--enable-async'],
-              howToFix: "Try removing the '#{modifier}' modifier.",
-              examples: const ["""
-class A {
-  A() async;
-}
-main() => new A();""",
-
-"""
-class A {
-  A();
-  factory A.a() async* {}
-}
-main() => new A.a();"""]),
-
-      MessageKind.ASYNC_MODIFIER_ON_SETTER:
-        const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_SETTER,
-              "The modifier '#{modifier}' is not allowed on setters.",
-              options: const ['--enable-async'],
-              howToFix: "Try removing the '#{modifier}' modifier.",
-              examples: const ["""
-class A {
-  set foo(v) async {}
-}
-main() => new A().foo = 0;"""]),
-
-      MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY:
-        const MessageTemplate(MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
-          "The modifier '#{modifier}' is not allowed on methods implemented "
-          "using '=>'.",
-          options: const ['--enable-async'],
-          howToFix: "Try removing the '#{modifier}' modifier or implementing "
-                    "the method body using a block: '{ ... }'.",
-          examples: const ["main() sync* => null;", "main() async* => null;"]),
-
-      // TODO(johnniwinther): Check for 'async' as identifier.
-      MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER:
-        const MessageTemplate(MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER,
-          "'#{keyword}' cannot be used as an identifier in a function body "
-          "marked with '#{modifier}'.",
-          options: const ['--enable-async'],
-          howToFix: "Try removing the '#{modifier}' modifier or renaming the "
-                    "identifier.",
-          examples: const ["""
-main() async {
- var await;
-}""",
-"""
-main() async* {
- var yield;
-}""",
-"""
-main() sync* {
- var yield;
-}"""]),
-
-      MessageKind.RETURN_IN_GENERATOR:
-        const MessageTemplate(MessageKind.RETURN_IN_GENERATOR,
-          "'return' with a value is not allowed in a method body using the "
-          "'#{modifier}' modifier.",
-          howToFix: "Try removing the value, replacing 'return' with 'yield' "
-                    "or changing the method body modifier.",
-          examples: const [
-"""
-foo() async* { return 0; }
-main() => foo();
-""",
-
-"""
-foo() sync* { return 0; }
-main() => foo();
-"""]),
-
-      MessageKind.NATIVE_NOT_SUPPORTED:
-        const MessageTemplate(MessageKind.NATIVE_NOT_SUPPORTED,
-          "'native' modifier is not supported.",
-          howToFix: "Try removing the 'native' implementation or analyzing the "
-                    "code with the --allow-native-extensions option.",
-          examples: const ["""
-main() native "Main";
-"""]),
-
-      MessageKind.DART_EXT_NOT_SUPPORTED:
-        const MessageTemplate(MessageKind.DART_EXT_NOT_SUPPORTED,
-          "The 'dart-ext' scheme is not supported.",
-          howToFix: "Try analyzing the code with the --allow-native-extensions "
-                    "option.",
-          examples: const ["""
-import 'dart-ext:main';
-
-main() {}
-"""]),
-
-      MessageKind.LIBRARY_TAG_MUST_BE_FIRST:
-        const MessageTemplate(MessageKind.LIBRARY_TAG_MUST_BE_FIRST,
-          "The library declaration should come before other declarations.",
-          howToFix: "Try moving the declaration to the top of the file.",
-          examples: const [
-"""
-import 'dart:core';
-library foo;
-main() {}
-""",
-      ]),
-
-      MessageKind.ONLY_ONE_LIBRARY_TAG:
-        const MessageTemplate(MessageKind.ONLY_ONE_LIBRARY_TAG,
-          "There can only be one library declaration.",
-          howToFix: "Try removing all other library declarations.",
-          examples: const [
-"""
-library foo;
-library bar;
-main() {}
-""",
-"""
-library foo;
-import 'dart:core';
-library bar;
-main() {}
-""",
-      ]),
-
-      MessageKind.IMPORT_BEFORE_PARTS:
-        const MessageTemplate(MessageKind.IMPORT_BEFORE_PARTS,
-          "Import declarations should come before parts.",
-          howToFix: "Try moving this import further up in the file.",
-          examples: const [
-              const <String, String>{
-                'main.dart': """
-library test.main;
-part 'part.dart';
-import 'dart:core';
-main() {}
-""",
-                'part.dart': """
-part of test.main;
-""",
-          }]),
-
-      MessageKind.EXPORT_BEFORE_PARTS:
-        const MessageTemplate(MessageKind.EXPORT_BEFORE_PARTS,
-          "Export declarations should come before parts.",
-          howToFix: "Try moving this export further up in the file.",
-          examples: const [
-              const <String, String>{
-                'main.dart': """
-library test.main;
-part 'part.dart';
-export 'dart:core';
-main() {}
-""",
-               'part.dart': """
-part of test.main;
-""",
-          }]),
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Patch errors start.
-  //////////////////////////////////////////////////////////////////////////////
-
-      MessageKind.PATCH_RETURN_TYPE_MISMATCH:
-        const MessageTemplate(MessageKind.PATCH_RETURN_TYPE_MISMATCH,
-          "Patch return type '#{patchReturnType}' does not match "
-          "'#{originReturnType}' on origin method '#{methodName}'."),
-
-      MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH:
-        const MessageTemplate(
-          MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH,
-          "Required parameter count of patch method "
-          "(#{patchParameterCount}) does not match parameter count on origin "
-          "method '#{methodName}' (#{originParameterCount})."),
-
-      MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH:
-        const MessageTemplate(
-          MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH,
-          "Optional parameter count of patch method "
-          "(#{patchParameterCount}) does not match parameter count on origin "
-          "method '#{methodName}' (#{originParameterCount})."),
-
-      MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH:
-        const MessageTemplate(
-          MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
-          "Optional parameters of origin and patch method "
-          "'#{methodName}' must both be either named or positional."),
-
-      MessageKind.PATCH_PARAMETER_MISMATCH:
-        const MessageTemplate(MessageKind.PATCH_PARAMETER_MISMATCH,
-          "Patch method parameter '#{patchParameter}' does not match "
-          "'#{originParameter}' on origin method '#{methodName}'."),
-
-      MessageKind.PATCH_PARAMETER_TYPE_MISMATCH:
-        const MessageTemplate(MessageKind.PATCH_PARAMETER_TYPE_MISMATCH,
-          "Patch method parameter '#{parameterName}' type "
-          "'#{patchParameterType}' does not match '#{originParameterType}' on "
-          "origin method '#{methodName}'."),
-
-      MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION:
-        const MessageTemplate(MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION,
-          "External method without an implementation."),
-
-      MessageKind.PATCH_POINT_TO_FUNCTION:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_FUNCTION,
-          "This is the function patch '#{functionName}'."),
-
-      MessageKind.PATCH_POINT_TO_CLASS:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_CLASS,
-          "This is the class patch '#{className}'."),
-
-      MessageKind.PATCH_POINT_TO_GETTER:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_GETTER,
-          "This is the getter patch '#{getterName}'."),
-
-      MessageKind.PATCH_POINT_TO_SETTER:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_SETTER,
-          "This is the setter patch '#{setterName}'."),
-
-      MessageKind.PATCH_POINT_TO_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
-          "This is the constructor patch '#{constructorName}'."),
-
-      MessageKind.PATCH_POINT_TO_PARAMETER:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_PARAMETER,
-          "This is the patch parameter '#{parameterName}'."),
-
-      MessageKind.PATCH_NON_EXISTING:
-        const MessageTemplate(MessageKind.PATCH_NON_EXISTING,
-          "Origin does not exist for patch '#{name}'."),
-
-      // TODO(ahe): Eventually, this error should be removed as it will be
-      // handled by the regular parser.
-      MessageKind.PATCH_NONPATCHABLE:
-        const MessageTemplate(MessageKind.PATCH_NONPATCHABLE,
-          "Only classes and functions can be patched."),
-
-      MessageKind.PATCH_NON_EXTERNAL:
-        const MessageTemplate(MessageKind.PATCH_NON_EXTERNAL,
-          "Only external functions can be patched."),
-
-      MessageKind.PATCH_NON_CLASS:
-        const MessageTemplate(MessageKind.PATCH_NON_CLASS,
-          "Patching non-class with class patch '#{className}'."),
-
-      MessageKind.PATCH_NON_GETTER:
-        const MessageTemplate(MessageKind.PATCH_NON_GETTER,
-          "Cannot patch non-getter '#{name}' with getter patch."),
-
-      MessageKind.PATCH_NO_GETTER:
-        const MessageTemplate(MessageKind.PATCH_NO_GETTER,
-          "No getter found for getter patch '#{getterName}'."),
-
-      MessageKind.PATCH_NON_SETTER:
-        const MessageTemplate(MessageKind.PATCH_NON_SETTER,
-          "Cannot patch non-setter '#{name}' with setter patch."),
-
-      MessageKind.PATCH_NO_SETTER:
-        const MessageTemplate(MessageKind.PATCH_NO_SETTER,
-          "No setter found for setter patch '#{setterName}'."),
-
-      MessageKind.PATCH_NON_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.PATCH_NON_CONSTRUCTOR,
-          "Cannot patch non-constructor with constructor patch "
-          "'#{constructorName}'."),
-
-      MessageKind.PATCH_NON_FUNCTION:
-        const MessageTemplate(MessageKind.PATCH_NON_FUNCTION,
-          "Cannot patch non-function with function patch "
-          "'#{functionName}'."),
-
-      MessageKind.EXTERNAL_WITH_BODY:
-        const MessageTemplate(MessageKind.EXTERNAL_WITH_BODY,
-          "External function '#{functionName}' cannot have a function body.",
-          options: const ["--output-type=dart"],
-          howToFix:
-            "Try removing the 'external' modifier or the function body.",
-          examples: const ["""
-external foo() => 0;
-main() => foo();
-""", """
-external foo() {}
-main() => foo();
-"""]),
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Patch errors end.
-  //////////////////////////////////////////////////////////////////////////////
-
-      MessageKind.EXPERIMENTAL_ASSERT_MESSAGE:
-        const MessageTemplate(MessageKind.EXPERIMENTAL_ASSERT_MESSAGE,
-          "Experimental language feature 'assertion with message'"
-          " is not supported.",
-          howToFix:
-            "Use option '--assert-message' to use assertions with messages.",
-          examples: const [r'''
-main() {
-  int n = -7;
-  assert(n > 0, 'must be positive: $n');
-}
-''']),
-
-      MessageKind.IMPORT_EXPERIMENTAL_MIRRORS:
-        const MessageTemplate(MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, r'''
-
-****************************************************************
-* WARNING: dart:mirrors support in dart2js is experimental,
-*          and not recommended.
-*          This implementation of mirrors is incomplete,
-*          and often greatly increases the size of the generated
-*          JavaScript code.
-*
-* Your app imports dart:mirrors via:''''''
-$IMPORT_EXPERIMENTAL_MIRRORS_PADDING#{importChain}
-*
-* You can disable this message by using the --enable-experimental-mirrors
-* command-line flag.
-*
-* To learn what to do next, please visit:
-*    http://dartlang.org/dart2js-reflection
-****************************************************************
-'''),
-
-      MessageKind.DISALLOWED_LIBRARY_IMPORT:
-        const MessageTemplate(MessageKind.DISALLOWED_LIBRARY_IMPORT, '''
-Your app imports the unsupported library '#{uri}' via:
-''''''
-$DISALLOWED_LIBRARY_IMPORT_PADDING#{importChain}
-
-Use the --categories option to support import of '#{uri}'.
-'''),
-
-      MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND:
-        const MessageTemplate(
-          MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND,
-          """
-dart:mirrors library is not supported when using this backend.
-
-Your app imports dart:mirrors via:""""""
-$MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING#{importChain}"""),
-
-      MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS:
-        const MessageTemplate(MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS,
-          "Non-supported 'call' member on a native class, or a "
-          "subclass of a native class."),
-
-      MessageKind.DIRECTLY_THROWING_NSM:
-        const MessageTemplate(MessageKind.DIRECTLY_THROWING_NSM,
-          "This 'noSuchMethod' implementation is guaranteed to throw an "
-          "exception. The generated code will be smaller if it is "
-          "rewritten.",
-          howToFix: "Rewrite to "
-                    "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'."),
-
-      MessageKind.COMPLEX_THROWING_NSM:
-        const MessageTemplate(MessageKind.COMPLEX_THROWING_NSM,
-          "This 'noSuchMethod' implementation is guaranteed to throw an "
-          "exception. The generated code will be smaller and the compiler "
-          "will be able to perform more optimizations if it is rewritten.",
-          howToFix: "Rewrite to "
-                    "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'."),
-
-      MessageKind.COMPLEX_RETURNING_NSM:
-        const MessageTemplate(MessageKind.COMPLEX_RETURNING_NSM,
-          "Overriding 'noSuchMethod' causes the compiler to generate "
-          "more code and prevents the compiler from doing some optimizations.",
-          howToFix: "Consider removing this 'noSuchMethod' implementation."),
-
-      MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP:
-        const MessageTemplate(MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP,
-          "Unsupported version of package:lookup_map.",
-          howToFix: DONT_KNOW_HOW_TO_FIX),
-
-  }; // End of TEMPLATES.
-
-  /// Padding used before and between import chains in the message for
-  /// [MessageKind.IMPORT_EXPERIMENTAL_MIRRORS].
-  static const String IMPORT_EXPERIMENTAL_MIRRORS_PADDING = '\n*   ';
-
-  /// Padding used before and between import chains in the message for
-  /// [MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND].
-  static const String MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING = '\n   ';
-
-  /// Padding used before and between import chains in the message for
-  /// [MessageKind.DISALLOWED_LIBRARY_IMPORT].
-  static const String DISALLOWED_LIBRARY_IMPORT_PADDING = '\n  ';
+  const MessageTemplate(this.kind, this.id, this.template, this.howToFix,
+      this.examples, this.options);
 
   toString() => template;
 
@@ -3498,7 +901,42 @@
     return new Message(this, arguments, terse);
   }
 
-  bool get hasHowToFix => howToFix != null && howToFix != DONT_KNOW_HOW_TO_FIX;
+  bool get hasHowToFix =>
+      howToFix != null && howToFix != dart2js_messages.DONT_KNOW_HOW_TO_FIX;
+
+  static final Map<MessageKind, MessageTemplate> TEMPLATES =
+      _constructMessageTemplates();
+
+  static String get IMPORT_EXPERIMENTAL_MIRRORS_PADDING =>
+      dart2js_messages.IMPORT_EXPERIMENTAL_MIRRORS_PADDING;
+
+  static String get MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING =>
+      dart2js_messages.MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING;
+
+  static String get DISALLOWED_LIBRARY_IMPORT_PADDING =>
+      dart2js_messages.DISALLOWED_LIBRARY_IMPORT_PADDING;
+
+  static Map<MessageKind, MessageTemplate> _constructMessageTemplates() {
+    Map<MessageKind, MessageTemplate> result = <MessageKind, MessageTemplate>{};
+    for (MessageKind kind in MessageKind.values) {
+      String name = _KIND_TO_STRING_MAP[kind];
+      if (name == null) {
+        throw new ArgumentError("No mapping for $kind in _KIND_TO_STRING_MAP");
+      }
+      Map data =
+          shared_messages.MESSAGES[name] ?? dart2js_messages.MESSAGES[name];
+      if (data == null) throw new ArgumentError.value(name);
+
+      String id = data['id'];
+      String template = data['template'];
+      String howToFix = data['howToFix'];
+      List examples = data['examples'];
+      List<String> options = data['options'] ?? const <String>[];
+      result[kind] =
+          new MessageTemplate(kind, id, template, howToFix, examples, options);
+    }
+    return result;
+  }
 }
 
 class Message {
@@ -3508,7 +946,10 @@
   String message;
 
   Message(this.template, this.arguments, this.terse) {
-    assert(() { computeMessage(); return true; });
+    assert(() {
+      computeMessage();
+      return true;
+    });
   }
 
   MessageKind get kind => template.kind;
@@ -3522,7 +963,7 @@
       assert(invariant(
           CURRENT_ELEMENT_SPANNABLE,
           kind == MessageKind.GENERIC ||
-            !message.contains(new RegExp(r'#\{.+\}')),
+              !message.contains(new RegExp(r'#\{.+\}')),
           message: 'Missing arguments in error message: "$message"'));
       if (!terse && template.hasHowToFix) {
         String howToFix = template.howToFix;
@@ -3539,8 +980,8 @@
     return computeMessage();
   }
 
-  bool operator==(other) {
-    if (other is !Message) return false;
+  bool operator ==(other) {
+    if (other is! Message) return false;
     return (template == other.template) && (toString() == other.toString());
   }
 
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 22fa2f0..207954d 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -4,31 +4,41 @@
 
 library dump_info;
 
-import 'dart:convert'
-    show HtmlEscape, JsonEncoder, StringConversionSink, ChunkedConversionSink;
+import 'dart:convert' show
+    ChunkedConversionSink,
+    HtmlEscape,
+    JsonEncoder,
+    StringConversionSink;
 
 import 'package:dart2js_info/info.dart';
 
 import 'common.dart';
 import 'common/tasks.dart' show
     CompilerTask;
-import 'constants/values.dart' show ConstantValue;
+import 'constants/values.dart' show
+    ConstantValue,
+    InterceptorConstantValue;
 import 'compiler.dart' show
     Compiler;
-import 'elements/elements.dart';
-import 'elements/visitor.dart';
-import 'types/types.dart' show
-    TypeMask;
 import 'deferred_load.dart' show
     OutputUnit;
+import 'elements/elements.dart';
+import 'elements/visitor.dart';
+import 'info/send_info.dart' show
+    collectSendMeasurements;
 import 'js_backend/js_backend.dart' show
     JavaScriptBackend;
 import 'js_emitter/full_emitter/emitter.dart' as full show
     Emitter;
 import 'js/js.dart' as jsAst;
+import 'types/types.dart' show
+    TypeMask;
 import 'universe/universe.dart' show
-    UniverseSelector;
-import 'info/send_info.dart' show collectSendMeasurements;
+    ReceiverConstraint;
+import 'universe/world_impact.dart' show
+    ImpactUseCase,
+    WorldImpact,
+    WorldImpactVisitorImpl;
 
 class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> {
   final Compiler compiler;
@@ -45,10 +55,10 @@
       // TODO(sigmund): add dependencies on other constants
       var size = compiler.dumpInfoTask._nodeToSize[node];
       var code = jsAst.prettyPrint(node, compiler).getText();
-      var info = new ConstantInfo(size: size, code: code);
+      var info = new ConstantInfo(
+          size: size, code: code, outputUnit: _unitInfoForConstant(constant));
       _constantToInfo[constant] = info;
       result.constants.add(info);
-
     });
     compiler.libraryLoader.libraries.forEach(visit);
   }
@@ -58,10 +68,10 @@
   /// Whether to emit information about [element].
   ///
   /// By default we emit information for any element that contributes to the
-  /// output size. Either becuase the it is a function being emitted or inlined,
+  /// output size. Either because the it is a function being emitted or inlined,
   /// or because it is an element that holds dependencies to other elements.
   bool shouldKeep(Element element) {
-    return compiler.dumpInfoTask.selectorsFromElement.containsKey(element) ||
+    return compiler.dumpInfoTask.impacts.containsKey(element) ||
         compiler.dumpInfoTask.inlineCount.containsKey(element);
   }
 
@@ -82,7 +92,7 @@
     String libname = element.hasLibraryName ? element.libraryName : "<unnamed>";
     int size = compiler.dumpInfoTask.sizeOf(element);
     LibraryInfo info =
-      new LibraryInfo(libname, element.canonicalUri, null, size);
+        new LibraryInfo(libname, element.canonicalUri, null, size);
     _elementToInfo[element] = info;
 
     LibraryElement realElement = element.isPatched ? element.patch : element;
@@ -113,8 +123,8 @@
 
   TypedefInfo visitTypedefElement(TypedefElement element, _) {
     if (!element.isResolved) return null;
-    TypedefInfo info = new TypedefInfo(element.name, '${element.alias}',
-        _unitInfoForElement(element));
+    TypedefInfo info = new TypedefInfo(
+        element.name, '${element.alias}', _unitInfoForElement(element));
     _elementToInfo[element] = info;
     result.typedefs.add(info);
     return info;
@@ -284,6 +294,7 @@
 
     FunctionInfo info = new FunctionInfo(
         name: name,
+        functionKind: kind,
         // We use element.hashCode because it is globally unique and it is
         // available while we are doing codegen.
         coverageId: '${element.hashCode}',
@@ -323,9 +334,7 @@
     return info;
   }
 
-  OutputUnitInfo _unitInfoForElement(Element element) {
-    OutputUnit outputUnit =
-      compiler.deferredLoadTask.outputUnitForElement(element);
+  OutputUnitInfo _infoFromOutputUnit(OutputUnit outputUnit) {
     return _outputToInfo.putIfAbsent(outputUnit, () {
       // Dump-info currently only works with the full emitter. If another
       // emitter is used it will fail here.
@@ -333,15 +342,32 @@
       full.Emitter emitter = backend.emitter.emitter;
       OutputUnitInfo info = new OutputUnitInfo(
           outputUnit.name, emitter.outputBuffers[outputUnit].length);
+      info.imports.addAll(outputUnit.imports
+          .map((d) => compiler.deferredLoadTask.importDeferName[d]));
       result.outputUnits.add(info);
       return info;
     });
   }
+
+  OutputUnitInfo _unitInfoForElement(Element element) {
+    return _infoFromOutputUnit(
+        compiler.deferredLoadTask.outputUnitForElement(element));
+  }
+
+  OutputUnitInfo _unitInfoForConstant(ConstantValue constant) {
+    OutputUnit outputUnit =
+        compiler.deferredLoadTask.outputUnitForConstant(constant);
+    if (outputUnit == null) {
+      assert(constant is InterceptorConstantValue);
+      return null;
+    }
+    return _infoFromOutputUnit(outputUnit);
+  }
 }
 
 class Selection {
   final Element selectedElement;
-  final TypeMask mask;
+  final ReceiverConstraint mask;
   Selection(this.selectedElement, this.mask);
 }
 
@@ -356,6 +382,8 @@
 }
 
 class DumpInfoTask extends CompilerTask implements InfoReporter {
+  static const ImpactUseCase IMPACT_USE = const ImpactUseCase('Dump info');
+
   DumpInfoTask(Compiler compiler) : super(compiler);
 
   String get name => "Dump Info";
@@ -378,12 +406,13 @@
   // pretty-printed contents.
   final Map<jsAst.Node, int> _nodeToSize = <jsAst.Node, int>{};
 
-  final Map<Element, Set<UniverseSelector>> selectorsFromElement = {};
   final Map<Element, int> inlineCount = <Element, int>{};
   // A mapping from an element to a list of elements that are
   // inlined inside of it.
   final Map<Element, List<Element>> inlineMap = <Element, List<Element>>{};
 
+  final Map<Element, WorldImpact> impacts = <Element, WorldImpact>{};
+
   /// Register the size of the generated output.
   void reportSize(int programSize) {
     _programSize = programSize;
@@ -396,40 +425,46 @@
     inlineMap[inlinedFrom].add(element);
   }
 
-  /**
-   * Registers that a function uses a selector in the
-   * function body
-   */
-  void elementUsesSelector(Element element, UniverseSelector selector) {
-    if (compiler.dumpInfo) {
-      selectorsFromElement
-          .putIfAbsent(element, () => new Set<UniverseSelector>())
-          .add(selector);
-    }
-  }
-
   final Map<Element, Set<Element>> _dependencies = {};
   void registerDependency(Element source, Element target) {
     _dependencies.putIfAbsent(source, () => new Set()).add(target);
   }
 
+  void registerImpact(Element element, WorldImpact impact) {
+    if (compiler.dumpInfo) {
+      impacts[element] = impact;
+    }
+  }
+
+  void unregisterImpact(Element element) {
+    impacts.remove(element);
+  }
+
   /**
    * Returns an iterable of [Selection]s that are used by
    * [element].  Each [Selection] contains an element that is
    * used and the selector that selected the element.
    */
   Iterable<Selection> getRetaining(Element element) {
-    if (!selectorsFromElement.containsKey(element)) {
-      return const <Selection>[];
-    } else {
-      return selectorsFromElement[element].expand((UniverseSelector selector) {
-        return compiler.world.allFunctions
-            .filter(selector.selector, selector.mask)
-            .map((element) {
-          return new Selection(element, selector.mask);
-        });
-      });
-    }
+    WorldImpact impact = impacts[element];
+    if (impact == null) return const <Selection>[];
+
+    var selections = <Selection>[];
+    compiler.impactStrategy.visitImpact(
+        element,
+        impact,
+        new WorldImpactVisitorImpl(
+            visitDynamicUse: (dynamicUse) {
+              selections.addAll(compiler.world.allFunctions
+                        .filter(dynamicUse.selector, dynamicUse.mask)
+                        .map((e) => new Selection(e, dynamicUse.mask)));
+            },
+            visitStaticUse: (staticUse) {
+              selections.add(new Selection(staticUse.element, null));
+            }
+        ),
+        IMPACT_USE);
+    return selections;
   }
 
   // Returns true if we care about tracking the size of
@@ -529,6 +564,8 @@
         info.uses.add(new DependencyInfo(useInfo, '${selection.mask}'));
       }
     }
+    // Notify the impact strategy impacts are no longer needed for dump info.
+    compiler.impactStrategy.onImpactUsed(IMPACT_USE);
 
     // Track dependencies that come from inlining.
     for (Element element in inlineMap.keys) {
@@ -547,9 +584,9 @@
       var a = infoCollector._elementToInfo[element];
       if (a == null) continue;
       result.dependencies[a] = _dependencies[element]
-        .map((o) => infoCollector._elementToInfo[o])
-        .where((o) => o != null)
-        .toList();
+          .map((o) => infoCollector._elementToInfo[o])
+          .where((o) => o != null)
+          .toList();
     }
 
     result.deferredFiles = compiler.deferredLoadTask.computeDeferredMap();
@@ -567,7 +604,7 @@
 
     ChunkedConversionSink<Object> sink = encoder.startChunkedConversion(
         new StringConversionSink.fromStringSink(buffer));
-    sink.add(result.toJson());
+    sink.add(new AllInfoJsonCodec().encode(result));
     reporter.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, {
       'text': "View the dumped .info.json file at "
           "https://dart-lang.github.io/dump-info-visualizer"
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
index f9c4e59..1e24ff0 100644
--- a/pkg/compiler/lib/src/elements/common.dart
+++ b/pkg/compiler/lib/src/elements/common.dart
@@ -60,6 +60,9 @@
   bool get isGenerativeConstructorBody =>
       kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
 
+  bool get isFactoryConstructor =>
+      kind == ElementKind.FACTORY_CONSTRUCTOR;
+
   @override
   bool get isVariable => kind == ElementKind.VARIABLE;
 
@@ -76,12 +79,15 @@
   bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
 
   @override
-  bool get isErroneous => kind == ElementKind.ERROR;
+  bool get isError => kind == ElementKind.ERROR;
 
   @override
   bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;
 
   @override
+  bool get isMalformed => false;
+
+  @override
   bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;
 
   @override
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 60fcb20..c25e955 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -84,10 +84,10 @@
       const ElementKind('class', ElementCategory.CLASS);
   static const ElementKind GENERATIVE_CONSTRUCTOR =
       const ElementKind('generative_constructor', ElementCategory.FACTORY);
+  static const ElementKind FACTORY_CONSTRUCTOR =
+      const ElementKind('factory_constructor', ElementCategory.FACTORY);
   static const ElementKind FIELD =
       const ElementKind('field', ElementCategory.VARIABLE);
-  static const ElementKind FIELD_LIST =
-      const ElementKind('field_list', ElementCategory.NONE);
   static const ElementKind GENERATIVE_CONSTRUCTOR_BODY =
       const ElementKind('generative_constructor_body', ElementCategory.NONE);
   static const ElementKind COMPILATION_UNIT =
@@ -212,8 +212,8 @@
   /// `true` if this element is a top level function, static or instance
   /// method, local function or closure defined by a function expression.
   ///
-  /// This property is `true` for operator methods and factory constructors but
-  /// `false` for getter and setter methods, and generative constructors.
+  /// This property is `true` for operator methods but `false` for getter and
+  /// setter methods, and generative and factory constructors.
   ///
   /// See also [isConstructor], [isGenerativeConstructor], and
   /// [isFactoryConstructor] for constructor properties, and [isAccessor],
@@ -272,7 +272,7 @@
   bool get isInitializingFormal;
 
   /// `true` if this element represents a resolution error.
-  bool get isErroneous;
+  bool get isError;
 
   /// `true` if this element represents an ambiguous name.
   ///
@@ -281,6 +281,10 @@
   /// is produced.
   bool get isAmbiguous;
 
+  /// True if there has been errors during resolution or parsing of this
+  /// element.
+  bool get isMalformed;
+
   /// `true` if this element represents an entity whose access causes one or
   /// more warnings.
   bool get isWarnOnUse;
@@ -305,8 +309,6 @@
   /// as all other classes.
   bool get isTopLevel;
   bool get isAssignable;
-  bool get isNative;
-  bool get isJsInterop;
 
   bool get isDeferredLoaderGetter;
 
@@ -401,11 +403,6 @@
   bool get isSynthesized;
   bool get isMixinApplication;
 
-  bool get hasFixedBackendName;
-  String get fixedBackendName;
-
-  String get jsInteropName;
-
   bool get isAbstract;
 
   Scope buildScope();
@@ -415,16 +412,20 @@
   AnalyzableElement get analyzableElement;
 
   accept(ElementVisitor visitor, arg);
-
-  void setJsInteropName(String name);
-  void markAsJsInterop();
 }
 
 class Elements {
   static bool isUnresolved(Element e) {
-    return e == null || e.isErroneous;
+    return e == null || e.isMalformed;
   }
-  static bool isErroneous(Element e) => e != null && e.isErroneous;
+
+  static bool isError(Element e) {
+    return e != null && e.isError;
+  }
+
+  static bool isMalformed(Element e) {
+    return e != null && e.isMalformed;
+  }
 
   /// Unwraps [element] reporting any warnings attached to it, if any.
   static Element unwrap(Element element,
@@ -499,8 +500,7 @@
   }
 
   static bool isStaticOrTopLevelFunction(Element element) {
-    return isStaticOrTopLevel(element)
-           && (identical(element.kind, ElementKind.FUNCTION));
+    return isStaticOrTopLevel(element) && element.isFunction;
   }
 
   static bool isInstanceMethod(Element element) {
@@ -520,13 +520,6 @@
         (element.isFunction || element.isAccessor);
   }
 
-  static bool isNativeOrExtendsNative(ClassElement element) {
-    if (element == null) return false;
-    if (element.isNative || element.isJsInterop) return true;
-    assert(element.isResolved);
-    return isNativeOrExtendsNative(element.superclass);
-  }
-
   static bool isInstanceSend(Send send, TreeElements elements) {
     Element element = elements[send];
     if (element == null) return !isClosureSend(send, element);
@@ -746,9 +739,9 @@
     constructor = constructor.effectiveTarget;
     ClassElement cls = constructor.enclosingClass;
     return cls.library == compiler.typedDataLibrary
-        && cls.isNative
+        && compiler.backend.isNative(cls)
         && compiler.world.isSubtypeOf(cls, compiler.typedDataClass)
-        && compiler.world.isSubtypeOf(cls, compiler.listClass)
+        && compiler.world.isSubtypeOf(cls, compiler.coreClasses.listClass)
         && constructor.name == '';
   }
 
@@ -786,7 +779,7 @@
 /// or otherwise invalid.
 ///
 /// Accessing any field or calling any method defined on [ErroneousElement]
-/// except [isErroneous] will currently throw an exception. (This might
+/// except [isError] will currently throw an exception. (This might
 /// change when we actually want more information on the erroneous element,
 /// e.g., the name of the element we were trying to resolve.)
 ///
@@ -904,7 +897,6 @@
    */
   bool get isInternalLibrary;
 
-  bool get canUseNative;
   bool get exportsHandled;
 
   LibraryElement get implementation;
@@ -1257,8 +1249,6 @@
   /// constructor so its immediate redirection target is `null`.
   ConstructorElement get immediateRedirectionTarget;
 
-  bool get isCyclicRedirection;
-
   /// The prefix of the immediateRedirectionTarget, if it is deferred.
   /// [null] if it is not deferred.
   PrefixElement get redirectionDeferredPrefix;
@@ -1269,6 +1259,25 @@
   /// Is `true` if this constructor is a redirecting factory constructor.
   bool get isRedirectingFactory;
 
+  /// Is `true` if this constructor is a redirecting factory constructor that is
+  /// part of a redirection cycle.
+  bool get isCyclicRedirection;
+
+  /// Is `true` if the effective target of this constructor is malformed.
+  ///
+  /// A constructor is considered malformed if any of the following applies:
+  ///
+  ///     * the constructor is undefined,
+  ///     * the type of the constructor is undefined,
+  ///     * the constructor is a redirecting factory and either
+  ///       - it is part of a redirection cycle,
+  ///       - the effective target is a generative constructor on an abstract
+  ///         class, or
+  ///       - this constructor is constant but the effective target is not,
+  ///       - the arguments to this constructor are incompatible with the
+  ///         parameters of the effective target.
+  bool get isEffectiveTargetMalformed;
+
   /// Compute the type of the effective target of this constructor for an
   /// instantiation site with type [:newType:].
   InterfaceType computeEffectiveTargetType(InterfaceType newType);
@@ -1394,8 +1403,6 @@
   ClassElement get declaration;
   ClassElement get implementation;
 
-  String get nativeTagInfo;
-
   /// `true` if this class is an enum declaration.
   bool get isEnumClass;
 
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 6dfd751..550b3c9 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -45,6 +45,12 @@
 import 'visitor.dart' show
     ElementVisitor;
 
+/// Object that identifies a declaration site.
+///
+/// For most elements, this is the element itself, but for variable declarations
+/// where multi-declarations like `var a, b, c` are allowed, the declaration
+/// site is a separate object.
+// TODO(johnniwinther): Add [beginToken] and [endToken] getters.
 abstract class DeclarationSite {
 }
 
@@ -58,7 +64,7 @@
   List<MetadataAnnotation> metadataInternal;
 
   ElementX(this.name, this.kind, this.enclosingElement) {
-    assert(isErroneous || implementationLibrary != null);
+    assert(isError || implementationLibrary != null);
   }
 
   Modifiers get modifiers => Modifiers.EMPTY;
@@ -100,7 +106,6 @@
   bool get isInstanceMember => false;
   bool get isDeferredLoaderGetter => false;
 
-  bool get isFactoryConstructor => modifiers.isFactory;
   bool get isConst => modifiers.isConst;
   bool get isFinal => modifiers.isFinal;
   bool get isStatic => modifiers.isStatic;
@@ -122,7 +127,7 @@
 
   bool get isAssignable {
     if (isFinal || isConst) return false;
-    if (isFunction || isGenerativeConstructor) return false;
+    if (isFunction || isConstructor) return false;
     return true;
   }
 
@@ -232,62 +237,6 @@
     }
   }
 
-  String _fixedBackendName = null;
-  bool _isNative = false;
-  String _jsInteropName = null;
-  bool _isJsInterop = false;
-
-  /// Whether the element is implemented via typed JavaScript interop.
-  bool get isJsInterop => _isJsInterop;
-  /// JavaScript name for the element if it is implemented via typed JavaScript
-  /// interop.
-  String get jsInteropName => _jsInteropName;
-
-  void markAsJsInterop() {
-    _isJsInterop = true;
-  }
-
-  void setJsInteropName(String name) {
-    assert(invariant(this,
-        _isJsInterop,
-        message: 'Element is not js interop but given a js interop name.'));
-    _jsInteropName = name;
-  }
-
-  /// Whether the element corresponds to a native JavaScript construct either
-  /// through the existing [setNative] mechanism which is only allowed
-  /// for internal libraries or via the new typed JavaScriptInterop mechanism
-  /// which is allowed for user libraries.
-  bool get isNative => _isNative || isJsInterop;
-  bool get hasFixedBackendName => fixedBackendName != null || isJsInterop;
-
-  String _jsNameHelper(Element e) {
-    assert(invariant(this,
-        !(_isJsInterop &&  _jsInteropName == null),
-        message:
-            'Element is js interop but js interop name has not yet been'
-            'computed.'));
-    if (e.jsInteropName != null && e.jsInteropName.isNotEmpty) {
-      return e.jsInteropName;
-    }
-    return e.isLibrary ? 'self' : e.name;
-  }
-
-  String get fixedBackendName {
-    if (_fixedBackendName == null && isJsInterop) {
-      // If an element isJsInterop but _isJsInterop is false that means it is
-      // considered interop as the parent class is interop.
-      _fixedBackendName =  _jsNameHelper(isConstructor ? enclosingClass : this);
-    }
-    return _fixedBackendName;
-  }
-
-  // Marks this element as a native element.
-  void setNative(String name) {
-    _isNative = true;
-    _fixedBackendName = name;
-  }
-
   FunctionElement asFunctionElement() => null;
 
   bool get isAbstract => modifiers.isAbstract;
@@ -323,6 +272,8 @@
 
   bool get isCyclicRedirection => false;
 
+  bool get isMalformed => true;
+
   PrefixElement get redirectionDeferredPrefix => null;
 
   AbstractFieldElement abstractField;
@@ -377,6 +328,11 @@
   }
 
   @override
+  get isEffectiveTargetMalformed {
+    throw new UnsupportedError("isEffectiveTargetMalformed");
+  }
+
+  @override
   bool get isFromEnvironmentConstructor => false;
 }
 
@@ -397,89 +353,133 @@
       Element enclosing)
       : super(messageKind, messageArguments, name, enclosing);
 
+  @override
   bool get isRedirectingGenerative => false;
 
+  @override
   void set isRedirectingGenerative(_) {
     throw new UnsupportedError("isRedirectingGenerative");
   }
 
+  @override
   bool get isRedirectingFactory => false;
 
+  @override
   get definingElement {
     throw new UnsupportedError("definingElement");
   }
 
+  @override
   get asyncMarker {
     throw new UnsupportedError("asyncMarker");
   }
 
+  @override
   set asyncMarker(_) {
     throw new UnsupportedError("asyncMarker=");
   }
 
-  get internalEffectiveTarget {
-    throw new UnsupportedError("internalEffectiveTarget");
+  @override
+  get effectiveTargetInternal {
+    throw new UnsupportedError("effectiveTargetInternal");
   }
 
-  set internalEffectiveTarget(_) {
-    throw new UnsupportedError("internalEffectiveTarget=");
+  @override
+  set effectiveTargetInternal(_) {
+    throw new UnsupportedError("effectiveTargetInternal=");
   }
 
+  @override
+  get _effectiveTargetType {
+    throw new UnsupportedError("_effectiveTargetType");
+  }
+
+  @override
+  set _effectiveTargetType(_) {
+    throw new UnsupportedError("_effectiveTargetType=");
+  }
+
+  @override
   get effectiveTargetType {
     throw new UnsupportedError("effectiveTargetType");
   }
 
-  set effectiveTargetType(_) {
-    throw new UnsupportedError("effectiveTargetType=");
+  @override
+  get _isEffectiveTargetMalformed {
+    throw new UnsupportedError("_isEffectiveTargetMalformed");
   }
 
+  @override
+  set _isEffectiveTargetMalformed(_) {
+    throw new UnsupportedError("_isEffectiveTargetMalformed=");
+  }
+
+  @override
+  get isEffectiveTargetMalformed {
+    throw new UnsupportedError("isEffectiveTargetMalformed");
+  }
+
+  @override
+  void setEffectiveTarget(ConstructorElement target,
+                            InterfaceType type,
+                            {bool isMalformed: false}) {
+    throw new UnsupportedError("setEffectiveTarget");
+  }
+
+  @override
   void _computeSignature(Resolution resolution) {
     throw new UnsupportedError("_computeSignature");
   }
 
+  @override
   get typeCache {
     throw new UnsupportedError("typeCache");
   }
 
+  @override
   set typeCache(_) {
     throw new UnsupportedError("typeCache=");
   }
 
+  @override
   get immediateRedirectionTarget {
     throw new UnsupportedError("immediateRedirectionTarget");
   }
 
+  @override
   set immediateRedirectionTarget(_) {
     throw new UnsupportedError("immediateRedirectionTarget=");
   }
 
+  @override
   get _functionSignatureCache {
     throw new UnsupportedError("functionSignatureCache");
   }
 
+  @override
   set _functionSignatureCache(_) {
     throw new UnsupportedError("functionSignatureCache=");
   }
 
+  @override
   set functionSignature(_) {
     throw new UnsupportedError("functionSignature=");
   }
 
+  @override
   get nestedClosures {
     throw new UnsupportedError("nestedClosures");
   }
 
+  @override
   set nestedClosures(_) {
     throw new UnsupportedError("nestedClosures=");
   }
 
+  @override
   set redirectionDeferredPrefix(_) {
     throw new UnsupportedError("redirectionDeferredPrefix=");
   }
-
-  void set effectiveTarget(_) {
-    throw new UnsupportedError("effectiveTarget=");
-  }
 }
 
 /// A message attached to a [WarnOnUseElementX].
@@ -636,7 +636,7 @@
       : super(messageKind, messageArguments, enclosingElement, existingElement,
               newElement);
 
-  bool get isErroneous => true;
+  bool get isMalformed => true;
 }
 
 class ScopeX {
@@ -791,9 +791,9 @@
   void setPartOf(PartOf tag, DiagnosticReporter reporter) {
     LibraryElementX library = enclosingElement;
     if (library.entryCompilationUnit == this) {
+      // This compilation unit is loaded as a library. The error is reported by
+      // the library loader.
       partTag = tag;
-      reporter.reportErrorMessage(
-          tag, MessageKind.IMPORT_PART_OF);
       return;
     }
     if (!localMembers.isEmpty) {
@@ -1054,7 +1054,6 @@
   LinkBuilder<LibraryTag> tagsBuilder = new LinkBuilder<LibraryTag>();
   List<LibraryTag> tagsCache;
   LibraryName libraryTag;
-  bool canUseNative = false;
   Link<Element> localMembers = const Link<Element>();
   final ScopeX localScope = new ScopeX();
   final ImportScope importScope = new ImportScope();
@@ -1707,7 +1706,7 @@
 
   get initializer => null;
 
-  bool get isErroneous => true;
+  bool get isMalformed => true;
 
   get nestedClosures {
     throw new UnsupportedError("nestedClosures");
@@ -1913,7 +1912,7 @@
 
   bool get isLocal => false;
 
-  bool get isErroneous => true;
+  bool get isMalformed => true;
 
   DynamicType get type => const DynamicType();
 }
@@ -2053,18 +2052,6 @@
     typeCache = _functionSignatureCache.type;
   }
 
-  /// An function is part of JsInterop in the following cases:
-  /// * It has a jsInteropName annotation
-  /// * It is external member of a class or library tagged as JsInterop.
-  bool get isJsInterop {
-    if (!isExternal) return false;
-
-    if (super.isJsInterop) return true;
-    if (isClassMember) return contextClass.isJsInterop;
-    if (isTopLevel) return library.isJsInterop;
-    return false;
-  }
-
   List<ParameterElement> get parameters {
     // TODO(johnniwinther): Store the list directly, possibly by using List
     // instead of Link in FunctionSignature.
@@ -2120,6 +2107,25 @@
 
   MemberElement get memberContext => this;
 
+  @override
+  SourceSpan get sourcePosition {
+    SourceSpan span = super.sourcePosition;
+    if (span != null && hasNode) {
+      FunctionExpression functionExpression = node.asFunctionExpression();
+      if (functionExpression != null) {
+        Token begin = functionExpression.getBeginToken();
+        Token end;
+        if (functionExpression.parameters != null) {
+          end = functionExpression.parameters.getEndToken();
+        } else {
+          end = functionExpression.name.getEndToken();
+        }
+        span = new SourceSpan.fromTokens(span.uri, begin, end);
+      }
+    }
+    return span;
+  }
+
   void reuseElement() {
     super.reuseElement();
     nestedClosures.clear();
@@ -2270,35 +2276,55 @@
   // generative constructors.
   bool get isCyclicRedirection => effectiveTarget.isRedirectingFactory;
 
-  /// This field is set by the post process queue when checking for cycles.
-  ConstructorElement internalEffectiveTarget;
-  DartType effectiveTargetType;
+  /// These fields are set by the post process queue when checking for cycles.
+  ConstructorElement effectiveTargetInternal;
+  DartType _effectiveTargetType;
+  bool _isEffectiveTargetMalformed;
 
-  void set effectiveTarget(ConstructorElement constructor) {
-    assert(constructor != null && internalEffectiveTarget == null);
-    internalEffectiveTarget = constructor;
+  void setEffectiveTarget(ConstructorElement target,
+                          DartType type,
+                          {bool isMalformed: false}) {
+    assert(invariant(this, target != null,
+        message: 'No effective target provided for $this.'));
+    assert(invariant(this, effectiveTargetInternal == null,
+        message: 'Effective target has already been computed for $this.'));
+    effectiveTargetInternal = target;
+    _effectiveTargetType = type;
+    _isEffectiveTargetMalformed = isMalformed;
   }
 
   ConstructorElement get effectiveTarget {
-    if (Elements.isErroneous(immediateRedirectionTarget)) {
+    if (Elements.isMalformed(immediateRedirectionTarget)) {
       return immediateRedirectionTarget;
     }
-    assert(!isRedirectingFactory || internalEffectiveTarget != null);
-    if (isRedirectingFactory) return internalEffectiveTarget;
+    assert(!isRedirectingFactory || effectiveTargetInternal != null);
+    if (isRedirectingFactory) {
+      return effectiveTargetInternal;
+    }
     if (isPatched) {
-      return internalEffectiveTarget ?? this;
+      return effectiveTargetInternal ?? this;
     }
     return this;
   }
 
+  InterfaceType get effectiveTargetType {
+    assert(invariant(this, _effectiveTargetType != null,
+        message: 'Effective target type has not yet been computed for $this.'));
+    return _effectiveTargetType;
+  }
+
   InterfaceType computeEffectiveTargetType(InterfaceType newType) {
     if (!isRedirectingFactory) return newType;
-    assert(invariant(this, effectiveTargetType != null,
-        message: 'Redirection target type has not yet been computed for '
-                 '$this.'));
     return effectiveTargetType.substByContext(newType);
   }
 
+  bool get isEffectiveTargetMalformed {
+    if (!isRedirectingFactory) return false;
+    assert(invariant(this, _isEffectiveTargetMalformed != null,
+            message: 'Malformedness has not yet been computed for $this.'));
+    return _isEffectiveTargetMalformed == true;
+  }
+
   accept(ElementVisitor visitor, arg) {
     return visitor.visitConstructorElement(this, arg);
   }
@@ -2435,7 +2461,7 @@
 
   void _computeSignature(Resolution resolution) {
     if (hasFunctionSignature) return;
-    if (definingConstructor.isErroneous) {
+    if (definingConstructor.isMalformed) {
       functionSignature = new FunctionSignatureX(
           type: new FunctionType.synthesized(enclosingClass.thisType));
     }
@@ -2557,7 +2583,6 @@
 
   DartType supertype;
   Link<DartType> interfaces;
-  String nativeTagInfo;
   int supertypeLoadState;
   int resolutionState;
   bool isProxy = false;
@@ -2682,20 +2707,8 @@
   }
 
   bool implementsFunction(Compiler compiler) {
-    return asInstanceOf(compiler.functionClass) != null || callType != null;
-  }
-
-  bool get isNative => nativeTagInfo != null || isJsInterop;
-
-  void setNative(String name) {
-    // TODO(johnniwinther): Assert that this is only called once. The memory
-    // compiler copies pre-processed elements into a new compiler through
-    // [Compiler.onLibraryScanned] and thereby causes multiple calls to this
-    // method.
-    assert(invariant(this, nativeTagInfo == null || nativeTagInfo == name,
-        message: "Native tag info set inconsistently on $this: "
-                 "Existing name '$nativeTagInfo', new name '$name'."));
-    nativeTagInfo = name;
+    return asInstanceOf(compiler.coreClasses.functionClass) != null ||
+        callType != null;
   }
 
   // TODO(johnniwinther): Remove these when issue 18630 is fixed.
@@ -2783,7 +2796,8 @@
   }
 }
 
-class EnumClassElementX extends ClassElementX implements EnumClassElement {
+class EnumClassElementX extends ClassElementX
+    implements EnumClassElement, DeclarationSite {
   final Enum node;
   List<FieldElement> _enumValues;
 
@@ -2820,6 +2834,9 @@
         message: "enumValues has already been computed for $this."));
     _enumValues = values;
   }
+
+  @override
+  DeclarationSite get declarationSite => this;
 }
 
 class EnumConstructorElementX extends ConstructorElementX {
@@ -2880,17 +2897,14 @@
   }
 }
 
-class MixinApplicationElementX extends BaseClassElementX
+abstract class MixinApplicationElementX extends BaseClassElementX
     implements MixinApplicationElement {
-  final Node node;
-  final Modifiers modifiers;
 
   Link<ConstructorElement> constructors = new Link<ConstructorElement>();
 
   InterfaceType mixinType;
 
-  MixinApplicationElementX(String name, Element enclosing, int id,
-                           this.node, this.modifiers)
+  MixinApplicationElementX(String name, Element enclosing, int id)
       : super(name, enclosing, id, STATE_NOT_STARTED);
 
   ClassElement get mixin => mixinType != null ? mixinType.element : null;
@@ -2967,6 +2981,35 @@
   }
 }
 
+class NamedMixinApplicationElementX extends MixinApplicationElementX
+    implements DeclarationSite {
+  final NamedMixinApplication node;
+
+  NamedMixinApplicationElementX(
+      String name,
+      CompilationUnitElement enclosing,
+      int id,
+      this.node)
+      : super(name, enclosing, id);
+
+  Modifiers get modifiers => node.modifiers;
+
+  DeclarationSite get declarationSite => this;
+}
+
+class UnnamedMixinApplicationElementX extends MixinApplicationElementX {
+  final Node node;
+
+  UnnamedMixinApplicationElementX(
+      String name,
+      CompilationUnitElement enclosing,
+      int id,
+      this.node)
+      : super(name, enclosing, id);
+
+  bool get isAbstract => true;
+}
+
 class LabelDefinitionX implements LabelDefinition {
   final Label label;
   final String labelName;
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 522bb29..2c7403f 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -51,6 +51,16 @@
 import 'universe/selector.dart' show
     Selector;
 import 'universe/universe.dart';
+import 'universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    StaticUseKind,
+    TypeUse,
+    TypeUseKind;
+import 'universe/world_impact.dart' show
+    ImpactUseCase,
+    WorldImpact,
+    WorldImpactVisitor;
 import 'util/util.dart' show
     Link,
     Setlet;
@@ -86,61 +96,6 @@
   }
 }
 
-class WorldImpact {
-  const WorldImpact();
-
-  Iterable<UniverseSelector> get dynamicInvocations =>
-      const <UniverseSelector>[];
-  Iterable<UniverseSelector> get dynamicGetters => const <UniverseSelector>[];
-  Iterable<UniverseSelector> get dynamicSetters => const <UniverseSelector>[];
-
-  // TODO(johnniwinther): Split this into more precise subsets.
-  Iterable<Element> get staticUses => const <Element>[];
-
-  // TODO(johnniwinther): Replace this by called constructors with type
-  // arguments.
-  Iterable<InterfaceType> get instantiatedTypes => const <InterfaceType>[];
-
-  // TODO(johnniwinther): Collect checked types for checked mode separately to
-  // support serialization.
-  Iterable<DartType> get isChecks => const <DartType>[];
-
-  Iterable<DartType> get checkedModeChecks => const <DartType>[];
-
-  Iterable<DartType> get asCasts => const <DartType>[];
-
-  Iterable<MethodElement> get closurizedFunctions => const <MethodElement>[];
-
-  Iterable<LocalFunctionElement> get closures => const <LocalFunctionElement>[];
-
-  Iterable<DartType> get typeLiterals => const <DartType>[];
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-
-    void add(String title, Iterable iterable) {
-      if (iterable.isNotEmpty) {
-        sb.write('\n $title:');
-        iterable.forEach((e) => sb.write('\n  $e'));
-      }
-    }
-
-    add('dynamic invocations', dynamicInvocations);
-    add('dynamic getters', dynamicGetters);
-    add('dynamic setters', dynamicSetters);
-    add('static uses', staticUses);
-    add('instantiated types', instantiatedTypes);
-    add('is-checks', isChecks);
-    add('checked-mode checks', checkedModeChecks);
-    add('as-casts', asCasts);
-    add('closurized functions', closurizedFunctions);
-    add('closures', closures);
-    add('type literals', typeLiterals);
-
-    return sb.toString();
-  }
-}
-
 abstract class Enqueuer {
   final String name;
   final Compiler compiler; // TODO(ahe): Remove this dependency.
@@ -164,10 +119,14 @@
   bool hasEnqueuedReflectiveElements = false;
   bool hasEnqueuedReflectiveStaticFields = false;
 
+  WorldImpactVisitor impactVisitor;
+
   Enqueuer(this.name,
            this.compiler,
            this.itemCompilationContextCreator,
-           this.strategy);
+           this.strategy) {
+    impactVisitor = new _EnqueuerImpactVisitor(this);
+  }
 
   // TODO(johnniwinther): Move this to [ResolutionEnqueuer].
   Resolution get resolution => compiler.resolution;
@@ -189,6 +148,8 @@
 
   Iterable<ClassElement> get processedClasses => _processedClasses;
 
+  ImpactUseCase get impactUse;
+
   /**
    * Documentation wanted -- johnniwinther
    *
@@ -213,35 +174,28 @@
 
   /// Apply the [worldImpact] of processing [element] to this enqueuer.
   void applyImpact(Element element, WorldImpact worldImpact) {
-    // TODO(johnniwinther): Optimize the application of the world impact.
-    worldImpact.dynamicInvocations.forEach(registerDynamicInvocation);
-    worldImpact.dynamicGetters.forEach(registerDynamicGetter);
-    worldImpact.dynamicSetters.forEach(registerDynamicSetter);
-    worldImpact.staticUses.forEach(registerStaticUse);
-    worldImpact.instantiatedTypes.forEach(registerInstantiatedType);
-    worldImpact.isChecks.forEach(registerIsCheck);
-    worldImpact.asCasts.forEach(registerIsCheck);
-    if (compiler.enableTypeAssertions) {
-      worldImpact.checkedModeChecks.forEach(registerIsCheck);
-    }
-    worldImpact.closurizedFunctions.forEach(registerGetOfStaticFunction);
-    worldImpact.closures.forEach(registerClosure);
+    compiler.impactStrategy.visitImpact(
+        element, worldImpact, impactVisitor, impactUse);
   }
 
-  // TODO(johnniwinther): Remove the need for passing the [registry].
   void registerInstantiatedType(InterfaceType type,
                                 {bool mirrorUsage: false}) {
     task.measure(() {
       ClassElement cls = type.element;
       cls.ensureResolved(resolution);
+      bool isNative = compiler.backend.isNative(cls);
       universe.registerTypeInstantiation(
           type,
+          isNative: isNative,
           byMirrors: mirrorUsage,
           onImplemented: (ClassElement cls) {
         compiler.backend.registerImplementedClass(
                     cls, this, compiler.globalDependencies);
       });
-      processInstantiatedClass(cls);
+      // TODO(johnniwinther): Share this reasoning with [Universe].
+      if (!cls.isAbstract || isNative || mirrorUsage) {
+        processInstantiatedClass(cls);
+      }
     });
   }
 
@@ -267,7 +221,7 @@
       // its metadata parsed and analyzed.
       // Note: this assumes that there are no non-native fields on native
       // classes, which may not be the case when a native class is subclassed.
-      if (cls.isNative) {
+      if (compiler.backend.isNative(cls)) {
         compiler.world.registerUsedElement(member);
         nativeEnqueuer.handleFieldAnnotations(member);
         if (universe.hasInvokedGetter(member, compiler.world) ||
@@ -390,33 +344,18 @@
             superclass, this, compiler.globalDependencies);
       }
 
-      while (cls != null) {
-        processClass(cls);
-        cls = cls.superclass;
+      ClassElement superclass = cls;
+      while (superclass != null) {
+        processClass(superclass);
+        superclass = superclass.superclass;
       }
     });
   }
 
-  void registerInvocation(UniverseSelector selector) {
+  void registerDynamicUse(DynamicUse dynamicUse) {
     task.measure(() {
-      if (universe.registerInvocation(selector)) {
-        handleUnseenSelector(selector);
-      }
-    });
-  }
-
-  void registerInvokedGetter(UniverseSelector selector) {
-    task.measure(() {
-      if (universe.registerInvokedGetter(selector)) {
-        handleUnseenSelector(selector);
-      }
-    });
-  }
-
-  void registerInvokedSetter(UniverseSelector selector) {
-    task.measure(() {
-      if (universe.registerInvokedSetter(selector)) {
-        handleUnseenSelector(selector);
+      if (universe.registerDynamicUse(dynamicUse)) {
+        handleUnseenSelector(dynamicUse);
       }
     });
   }
@@ -452,7 +391,7 @@
           this,
           compiler.mirrorDependencies,
           mirrorUsage: true);
-      registerStaticUse(ctor.declaration);
+      registerStaticUse(new StaticUse.foreignUse(ctor.declaration));
     }
   }
 
@@ -469,19 +408,19 @@
         typedef.ensureResolved(resolution);
         compiler.world.allTypedefs.add(element);
       } else if (Elements.isStaticOrTopLevel(element)) {
-        registerStaticUse(element.declaration);
+        registerStaticUse(new StaticUse.foreignUse(element.declaration));
       } else if (element.isInstanceMember) {
         // We need to enqueue all members matching this one in subclasses, as
         // well.
         // TODO(herhut): Use TypedSelector.subtype for enqueueing
-        UniverseSelector selector = new UniverseSelector(
+        DynamicUse dynamicUse = new DynamicUse(
             new Selector.fromElement(element), null);
-        registerSelectorUse(selector);
+        registerDynamicUse(dynamicUse);
         if (element.isField) {
-          UniverseSelector selector = new UniverseSelector(
+          DynamicUse dynamicUse = new DynamicUse(
               new Selector.setter(new Name(
                   element.name, element.library, isSetter: true)), null);
-          registerInvokedSetter(selector);
+          registerDynamicUse(dynamicUse);
         }
       }
     }
@@ -626,19 +565,19 @@
     processSet(instanceFunctionsByName, n, f);
   }
 
-  void handleUnseenSelector(UniverseSelector universeSelector) {
-    strategy.processSelector(this, universeSelector);
+  void handleUnseenSelector(DynamicUse universeSelector) {
+    strategy.processDynamicUse(this, universeSelector);
   }
 
-  void handleUnseenSelectorInternal(UniverseSelector universeSelector) {
-    Selector selector = universeSelector.selector;
+  void handleUnseenSelectorInternal(DynamicUse dynamicUse) {
+    Selector selector = dynamicUse.selector;
     String methodName = selector.name;
     processInstanceMembers(methodName, (Element member) {
-      if (universeSelector.appliesUnnamed(member, compiler.world)) {
+      if (dynamicUse.appliesUnnamed(member, compiler.world)) {
         if (member.isFunction && selector.isGetter) {
           registerClosurizedMember(member);
         }
-        if (member.isField && member.enclosingClass.isNative) {
+        if (member.isField && compiler.backend.isNative(member.enclosingClass)) {
           if (selector.isGetter || selector.isCall) {
             nativeEnqueuer.registerFieldLoad(member);
             // We have to also handle storing to the field because we only get
@@ -663,7 +602,7 @@
     });
     if (selector.isGetter) {
       processInstanceFunctions(methodName, (Element member) {
-        if (universeSelector.appliesUnnamed(member, compiler.world)) {
+        if (dynamicUse.appliesUnnamed(member, compiler.world)) {
           registerClosurizedMember(member);
           return true;
         }
@@ -677,63 +616,63 @@
    *
    * Invariant: [element] must be a declaration element.
    */
-  void registerStaticUse(Element element) {
-    if (element == null) return;
-    strategy.processStaticUse(this, element);
+  void registerStaticUse(StaticUse staticUse) {
+    strategy.processStaticUse(this, staticUse);
   }
 
-  void registerStaticUseInternal(Element element) {
+  void registerStaticUseInternal(StaticUse staticUse) {
+    Element element = staticUse.element;
     assert(invariant(element, element.isDeclaration,
         message: "Element ${element} is not the declaration."));
-    if (Elements.isStaticOrTopLevel(element) && element.isField) {
-      universe.registerStaticFieldUse(element);
-    }
-    addToWorkList(element);
+    universe.registerStaticUse(staticUse);
     compiler.backend.registerStaticUse(element, this);
-  }
-
-  void registerGetOfStaticFunction(FunctionElement element) {
-    registerStaticUse(element);
-    compiler.backend.registerGetOfStaticFunction(this);
-    universe.staticFunctionsNeedingGetter.add(element);
-  }
-
-  void registerDynamicInvocation(UniverseSelector selector) {
-    assert(selector != null);
-    registerInvocation(selector);
-  }
-
-  void registerSelectorUse(UniverseSelector universeSelector) {
-    if (universeSelector.selector.isGetter) {
-      registerInvokedGetter(universeSelector);
-    } else if (universeSelector.selector.isSetter) {
-      registerInvokedSetter(universeSelector);
-    } else {
-      registerInvocation(universeSelector);
+    bool addElement = true;
+    switch (staticUse.kind) {
+      case StaticUseKind.STATIC_TEAR_OFF:
+        compiler.backend.registerGetOfStaticFunction(this);
+        break;
+      case StaticUseKind.FIELD_GET:
+      case StaticUseKind.FIELD_SET:
+      case StaticUseKind.CLOSURE:
+        // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and
+        // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
+        // Also [CLOSURE] contains [LocalFunctionElement] which we cannot
+        // enqueue.
+        addElement = false;
+        break;
+      case StaticUseKind.SUPER_FIELD_SET:
+      case StaticUseKind.SUPER_TEAR_OFF:
+      case StaticUseKind.GENERAL:
+        break;
+    }
+    if (addElement) {
+      addToWorkList(element);
     }
   }
 
-  void registerDynamicGetter(UniverseSelector selector) {
-    registerInvokedGetter(selector);
+  void registerTypeUse(TypeUse typeUse) {
+    DartType type = typeUse.type;
+    switch (typeUse.kind) {
+      case TypeUseKind.INSTANTIATION:
+        registerInstantiatedType(type);
+        break;
+      case TypeUseKind.INSTANTIATION:
+      case TypeUseKind.IS_CHECK:
+      case TypeUseKind.AS_CAST:
+      case TypeUseKind.CATCH_TYPE:
+        _registerIsCheck(type);
+        break;
+      case TypeUseKind.CHECKED_MODE_CHECK:
+        if (compiler.enableTypeAssertions) {
+          _registerIsCheck(type);
+        }
+        break;
+      case TypeUseKind.TYPE_LITERAL:
+        break;
+    }
   }
 
-  void registerDynamicSetter(UniverseSelector selector) {
-    registerInvokedSetter(selector);
-  }
-
-  void registerGetterForSuperMethod(Element element) {
-    universe.methodsNeedingSuperGetter.add(element);
-  }
-
-  void registerFieldGetter(Element element) {
-    universe.fieldGetters.add(element);
-  }
-
-  void registerFieldSetter(Element element) {
-    universe.fieldSetters.add(element);
-  }
-
-  void registerIsCheck(DartType type) {
+  void _registerIsCheck(DartType type) {
     type = universe.registerIsCheck(type, compiler);
     // Even in checked mode, type annotations for return type and argument
     // types do not imply type checks, so there should never be a check
@@ -758,10 +697,6 @@
     universe.closurizedMembers.add(element);
   }
 
-  void registerClosure(LocalFunctionElement element) {
-    universe.allClosures.add(element);
-  }
-
   void forEach(void f(WorkItem work)) {
     do {
       while (queue.isNotEmpty) {
@@ -813,6 +748,10 @@
    */
   final Queue<DeferredTask> deferredTaskQueue;
 
+  static const ImpactUseCase IMPACT_USE = const ImpactUseCase('ResolutionEnqueuer');
+
+  ImpactUseCase get impactUse => IMPACT_USE;
+
   ResolutionEnqueuer(Compiler compiler,
                      ItemCompilationContext itemCompilationContextCreator(),
                      EnqueuerStrategy strategy)
@@ -852,7 +791,7 @@
   }
 
   bool internalAddToWorkList(Element element) {
-    if (element.isErroneous) return false;
+    if (element.isMalformed) return false;
 
     assert(invariant(element, element is AnalyzableElement,
         message: 'Element $element is not analyzable.'));
@@ -960,15 +899,18 @@
 /// [Enqueuer] which is specific to code generation.
 class CodegenEnqueuer extends Enqueuer {
   final Queue<CodegenWorkItem> queue;
-  final Map<Element, js.Expression> generatedCode =
-      new Map<Element, js.Expression>();
+  final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{};
 
   final Set<Element> newlyEnqueuedElements;
 
-  final Set<UniverseSelector> newlySeenSelectors;
+  final Set<DynamicUse> newlySeenSelectors;
 
   bool enabledNoSuchMethod = false;
 
+  static const ImpactUseCase IMPACT_USE = const ImpactUseCase('CodegenEnqueuer');
+
+  ImpactUseCase get impactUse => IMPACT_USE;
+
   CodegenEnqueuer(Compiler compiler,
                   ItemCompilationContext itemCompilationContextCreator(),
                   EnqueuerStrategy strategy)
@@ -1043,11 +985,11 @@
     }
   }
 
-  void handleUnseenSelector(UniverseSelector selector) {
+  void handleUnseenSelector(DynamicUse dynamicUse) {
     if (compiler.hasIncrementalSupport) {
-      newlySeenSelectors.add(selector);
+      newlySeenSelectors.add(dynamicUse);
     }
-    super.handleUnseenSelector(selector);
+    super.handleUnseenSelector(dynamicUse);
   }
 }
 
@@ -1087,11 +1029,11 @@
   /// Process a class instantiated in live code.
   void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) {}
 
-  /// Process an element statically accessed in live code.
-  void processStaticUse(Enqueuer enqueuer, Element element) {}
+  /// Process a static use of and element in live code.
+  void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) {}
 
-  /// Process a selector for a call site in live code.
-  void processSelector(Enqueuer enqueuer, UniverseSelector selector) {}
+  /// Process a dynamic use for a call site in live code.
+  void processDynamicUse(Enqueuer enqueuer, DynamicUse dynamicUse) {}
 }
 
 class TreeShakingEnqueuerStrategy implements EnqueuerStrategy {
@@ -1103,12 +1045,33 @@
   }
 
   @override
-  void processStaticUse(Enqueuer enqueuer, Element element) {
-    enqueuer.registerStaticUseInternal(element);
+  void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) {
+    enqueuer.registerStaticUseInternal(staticUse);
   }
 
   @override
-  void processSelector(Enqueuer enqueuer, UniverseSelector selector) {
-    enqueuer.handleUnseenSelectorInternal(selector);
+  void processDynamicUse(Enqueuer enqueuer, DynamicUse dynamicUse) {
+    enqueuer.handleUnseenSelectorInternal(dynamicUse);
+  }
+}
+
+class _EnqueuerImpactVisitor implements WorldImpactVisitor {
+  final Enqueuer enqueuer;
+
+  _EnqueuerImpactVisitor(this.enqueuer);
+
+  @override
+  void visitDynamicUse(DynamicUse dynamicUse) {
+    enqueuer.registerDynamicUse(dynamicUse);
+  }
+
+  @override
+  void visitStaticUse(StaticUse staticUse) {
+    enqueuer.registerStaticUse(staticUse);
+  }
+
+  @override
+  void visitTypeUse(TypeUse typeUse) {
+    enqueuer.registerTypeUse(typeUse);
   }
 }
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index aa78001..b7d1ef7 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -2,11 +2,20 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of type_graph_inferrer;
+library compiler.src.inferrer.closure_tracer;
+
+import '../types/types.dart' show TypeMask;
+import '../common/names.dart' show Names;
+import '../elements/elements.dart';
+import '../universe/selector.dart' show Selector;
+import 'node_tracer.dart';
+import 'type_graph_nodes.dart';
+import 'debug.dart' as debug;
+
 
 class ClosureTracerVisitor extends TracerVisitor<ApplyableTypeInformation> {
   final Iterable<FunctionElement> tracedElements;
-  final List<CallSiteTypeInformation> callsToAnalyze =
+  final List<CallSiteTypeInformation> _callsToAnalyze =
       new List<CallSiteTypeInformation>();
 
   ClosureTracerVisitor(this.tracedElements, tracedType, inferrer)
@@ -15,7 +24,7 @@
   void run() {
     analyze();
     if (!continueAnalyzing) return;
-    callsToAnalyze.forEach(analyzeCall);
+    _callsToAnalyze.forEach(_analyzeCall);
     for(FunctionElement e in tracedElements) {
       e.functionSignature.forEachParameter((Element parameter) {
         ElementTypeInformation info =
@@ -25,18 +34,18 @@
     }
   }
 
-  void tagAsFunctionApplyTarget([String reason]) {
+  void _tagAsFunctionApplyTarget([String reason]) {
     tracedType.mightBePassedToFunctionApply = true;
-    if (_VERBOSE) {
+    if (debug.VERBOSE) {
       print("Closure $tracedType might be passed to apply: $reason");
     }
   }
 
-  void registerCallForLaterAnalysis(CallSiteTypeInformation info) {
-    callsToAnalyze.add(info);
+  void _registerCallForLaterAnalysis(CallSiteTypeInformation info) {
+    _callsToAnalyze.add(info);
   }
 
-  void analyzeCall(CallSiteTypeInformation info) {
+  void _analyzeCall(CallSiteTypeInformation info) {
     Selector selector = info.selector;
     TypeMask mask = info.mask;
     tracedElements.forEach((FunctionElement functionElement) {
@@ -46,15 +55,17 @@
     });
   }
 
+  @override
   visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
     super.visitClosureCallSiteTypeInformation(info);
     if (info.closure == currentUser) {
-      registerCallForLaterAnalysis(info);
+      _registerCallForLaterAnalysis(info);
     } else {
       bailout('Passed to a closure');
     }
   }
 
+  @override
   visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
     super.visitStaticCallSiteTypeInformation(info);
     Element called = info.calledElement;
@@ -70,23 +81,22 @@
         && inferrer.types.getInferredTypeOf(called) == currentUser) {
       // This node can be a closure call as well. For example, `foo()`
       // where `foo` is a getter.
-      registerCallForLaterAnalysis(info);
+      _registerCallForLaterAnalysis(info);
     }
-    if (checkIfFunctionApply(called) &&
+    if (_checkIfFunctionApply(called) &&
         info.arguments != null &&
         info.arguments.contains(currentUser)) {
-      tagAsFunctionApplyTarget("static call");
+      _tagAsFunctionApplyTarget("static call");
     }
   }
 
-  bool checkIfCurrentUser(element) {
-    return inferrer.types.getInferredTypeOf(element) == currentUser;
-  }
+  bool _checkIfCurrentUser(element) =>
+      inferrer.types.getInferredTypeOf(element) == currentUser;
 
-  bool checkIfFunctionApply(element) {
-    return compiler.functionApplyMethod == element;
-  }
+  bool _checkIfFunctionApply(element) =>
+      compiler.functionApplyMethod == element;
 
+  @override
   visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
     super.visitDynamicCallSiteTypeInformation(info);
     if (info.selector.isCall) {
@@ -94,11 +104,11 @@
         if (!info.targets.every((element) => element.isFunction)) {
           bailout('Passed to a closure');
         }
-        if (info.targets.any(checkIfFunctionApply)) {
-          tagAsFunctionApplyTarget("dynamic call");
+        if (info.targets.any(_checkIfFunctionApply)) {
+          _tagAsFunctionApplyTarget("dynamic call");
         }
-      } else if (info.targets.any((element) => checkIfCurrentUser(element))) {
-        registerCallForLaterAnalysis(info);
+      } else if (info.targets.any((element) => _checkIfCurrentUser(element))) {
+        _registerCallForLaterAnalysis(info);
       }
     } else if (info.selector.isGetter &&
         info.selector.memberName == Names.call) {
@@ -112,6 +122,7 @@
   StaticTearOffClosureTracerVisitor(tracedElement, tracedType, inferrer)
       : super([tracedElement], tracedType, inferrer);
 
+  @override
   visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
     super.visitStaticCallSiteTypeInformation(info);
     if (info.calledElement == tracedElements.first
diff --git a/pkg/compiler/lib/src/inferrer/debug.dart b/pkg/compiler/lib/src/inferrer/debug.dart
new file mode 100644
index 0000000..502f966
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer/debug.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.
+
+/// Values used only for debugging type inference.
+library compiler.src.inferrer.debug;
+
+bool VERBOSE = false;
+bool PRINT_SUMMARY = false;
+final ANOMALY_WARN = false;
+
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index 7daed4e..fbb7880 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -16,8 +16,6 @@
 import '../elements/elements.dart';
 import '../resolution/operators.dart';
 import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart' show
-    SendResolverMixin;
 import '../resolution/tree_elements.dart' show
     TreeElements;
 import '../tree/tree.dart';
@@ -55,6 +53,9 @@
   T get constMapType;
   T get stringType;
   T get typeType;
+  T get syncStarIterableType;
+  T get asyncFutureType; // Subtype of Future returned by async methods.
+  T get asyncStarStreamType;
 
   T stringLiteralType(DartString value);
   T boolLiteralType(LiteralBool value);
@@ -90,6 +91,11 @@
   T narrowType(T type, DartType annotation, {bool isNullable: true});
 
   /**
+   * Returns the non-nullable type [T].
+   */
+  T narrowNotNull(T type);
+
+  /**
    * Returns a new type that unions [firstInput] and [secondInput].
    */
   T allocateDiamondPhi(T firstInput, T secondInput);
@@ -468,9 +474,13 @@
 
       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.
+        // If-null assignments may return either the new or the original value
+        // narrowed to non-null.
         type = types.addPhiInput(
-            local, types.allocatePhi(locals.block, local, currentType), type);
+            local,
+            types.allocatePhi(locals.block, local,
+                              types.narrowNotNull(currentType)),
+            type);
       }
       locals[local] = type;
       if (currentType != type) {
@@ -603,25 +613,33 @@
   void mergeAfterBreaks(List<LocalsHandler<T>> handlers,
                         {bool keepOwnLocals: true}) {
     Node level = locals.block;
+    // Use a separate locals handler to perform the merge in, so that Phi
+    // creation does not invalidate previous type knowledge while we might
+    // still look it up.
+    LocalsHandler merged = new LocalsHandler.from(this, level);
     Set<Local> seenLocals = new Setlet<Local>();
-    // If we want to keep the locals, we first merge [this] into itself to
-    // create the required Phi nodes.
-    if (keepOwnLocals && !seenReturnOrThrow) {
-      mergeHandler(this, seenLocals);
-    }
     bool allBranchesAbort = true;
     // Merge all other handlers.
     for (LocalsHandler handler in handlers) {
       allBranchesAbort = allBranchesAbort && handler.seenReturnOrThrow;
-      mergeHandler(handler, seenLocals);
+      merged.mergeHandler(handler, seenLocals);
     }
-    // Clean up Phi nodes with single input.
-    locals.forEachLocal((Local variable, T type) {
-      if (!seenLocals.contains(variable)) return;
-      T newType = types.simplifyPhi(level, variable, type);
-      if (newType != type) {
-        locals[variable] = newType;
+    // If we want to keep own locals, we merge [seenLocals] from [this] into
+    // [merged] to update the Phi nodes with original values.
+    if (keepOwnLocals && !seenReturnOrThrow) {
+      for (Local variable in seenLocals) {
+        T originalType = locals[variable];
+        if (originalType != null) {
+          merged.locals[variable] = types.addPhiInput(variable,
+                                                      merged.locals[variable],
+                                                      originalType);
+        }
       }
+    }
+    // Clean up Phi nodes with single input and store back result into
+    // actual locals handler.
+    merged.locals.forEachOwnLocal((Local variable, T type) {
+      locals[variable] = types.simplifyPhi(level, variable, type);
     });
     seenReturnOrThrow = allBranchesAbort &&
                         (!keepOwnLocals || seenReturnOrThrow);
@@ -692,8 +710,7 @@
 
 abstract class InferrerVisitor<T, E extends MinimalInferrerEngine<T>>
     extends Visitor<T>
-    with SendResolverMixin,
-         SemanticSendResolvedMixin<T, dynamic>,
+    with SemanticSendResolvedMixin<T, dynamic>,
          CompoundBulkMixin<T, dynamic>,
          SetIfNullBulkMixin<T, dynamic>,
          PrefixBulkMixin<T, dynamic>,
@@ -871,7 +888,7 @@
     // TODO(kasperl): We should be able to tell that the type of a literal
     // symbol is always a non-null exact symbol implementation -- not just
     // any non-null subtype of the symbol interface.
-    return types.nonNullSubtype(compiler.symbolClass);
+    return types.nonNullSubtype(compiler.coreClasses.symbolClass);
   }
 
   @override
@@ -1066,7 +1083,7 @@
           }
         } else {
           // Narrow the elements to a non-null type.
-          DartType objectType = compiler.objectClass.rawType;
+          DartType objectType = compiler.coreTypes.objectType;
           if (Elements.isLocal(receiverElement)) {
             narrow(receiverElement, objectType, node);
           }
@@ -1116,7 +1133,7 @@
   T visitIfNull(Send node, Node left, Node right, _) {
     T firstType = visit(left);
     T secondType = visit(right);
-    return types.allocateDiamondPhi(firstType, secondType);
+    return types.allocateDiamondPhi(types.narrowNotNull(firstType), secondType);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/inferrer/list_tracer.dart b/pkg/compiler/lib/src/inferrer/list_tracer.dart
index b3e8ab3..a57087f 100644
--- a/pkg/compiler/lib/src/inferrer/list_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/list_tracer.dart
@@ -2,7 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of type_graph_inferrer;
+library compiler.src.inferrer.list_tracer;
+
+import '../elements/elements.dart';
+import '../universe/selector.dart' show Selector;
+import '../util/util.dart' show Setlet;
+
+import 'node_tracer.dart';
+import 'type_graph_nodes.dart';
 
 /**
  * A set of selector names that [List] implements, that we know do not
diff --git a/pkg/compiler/lib/src/inferrer/map_tracer.dart b/pkg/compiler/lib/src/inferrer/map_tracer.dart
index 94caa57..1ab3c24 100644
--- a/pkg/compiler/lib/src/inferrer/map_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/map_tracer.dart
@@ -2,7 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of type_graph_inferrer;
+library compiler.src.inferrer.map_tracer;
+
+import '../elements/elements.dart';
+import '../universe/selector.dart' show Selector;
+
+import 'node_tracer.dart';
+import 'type_graph_nodes.dart';
 
 Set<String> okMapSelectorsSet = new Set.from(
     const <String>[
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index 371adb5..174ae56 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -2,7 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of type_graph_inferrer;
+library compiler.src.inferrer.node_tracer;
+
+import '../common/names.dart' show Identifiers;
+import '../compiler.dart' show Compiler;
+import '../elements/elements.dart';
+import '../types/types.dart' show ContainerTypeMask, MapTypeMask;
+import '../util/util.dart' show Setlet;
+
+import 'type_graph_inferrer.dart' show TypeGraphInferrerEngine;
+import 'type_graph_nodes.dart';
+import 'debug.dart' as debug;
 
 // A set of selectors we know do not escape the elements inside the
 // list.
@@ -64,6 +74,7 @@
     'keys'
   ]);
 
+/// Common logic to trace a value through the type inference graph nodes.
 abstract class TracerVisitor<T extends TypeInformation>
     implements TypeInformationVisitor {
   final T tracedType;
@@ -136,7 +147,7 @@
   }
 
   void bailout(String reason) {
-    if (_VERBOSE) {
+    if (debug.VERBOSE) {
       print('Bailing out on $tracedType because: $reason');
     }
     continueAnalyzing = false;
@@ -202,7 +213,7 @@
         flow.users.forEach((user) {
           if (user is !DynamicCallSiteTypeInformation) return;
           if (user.receiver != flow) return;
-          if (inferrer._returnsListElementTypeSet.contains(user.selector)) {
+          if (inferrer.returnsListElementTypeSet.contains(user.selector)) {
             addNewEscapeInformation(user);
           } else if (!doesNotEscapeListSet.contains(user.selector.name)) {
             bailout('Escape from a list via [${user.selector.name}]');
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index 5e817af..f897876 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -15,6 +15,9 @@
 import '../constants/values.dart' show
     ConstantValue,
     IntConstantValue;
+import '../core_types.dart' show
+    CoreClasses,
+    CoreTypes;
 import '../cps_ir/cps_ir_nodes.dart' as cps_ir show
     Node;
 import '../dart_types.dart' show
@@ -49,148 +52,6 @@
 import 'inferrer_visitor.dart';
 
 /**
- * An implementation of [TypeSystem] for [TypeMask].
- */
-class TypeMaskSystem implements TypeSystem<TypeMask> {
-  final Compiler compiler;
-  final ClassWorld classWorld;
-  TypeMaskSystem(Compiler compiler)
-      : this.compiler = compiler,
-        this.classWorld = compiler.world;
-
-  TypeMask narrowType(TypeMask type,
-                      DartType annotation,
-                      {bool isNullable: true}) {
-    if (annotation.treatAsDynamic) return type;
-    if (annotation.element == compiler.objectClass) return type;
-    TypeMask otherType;
-    if (annotation.isTypedef || annotation.isFunctionType) {
-      otherType = functionType;
-    } else if (annotation.isTypeVariable) {
-      // TODO(ngeoffray): Narrow to bound.
-      return type;
-    } else if (annotation.isVoid) {
-      otherType = nullType;
-    } else {
-      assert(annotation.isInterfaceType);
-      otherType = new TypeMask.nonNullSubtype(annotation.element, classWorld);
-    }
-    if (isNullable) otherType = otherType.nullable();
-    if (type == null) return otherType;
-    return type.intersection(otherType, classWorld);
-  }
-
-  TypeMask computeLUB(TypeMask firstType, TypeMask secondType) {
-    if (firstType == null) {
-      return secondType;
-    } else if (secondType == dynamicType || firstType == dynamicType) {
-      return dynamicType;
-    } else if (firstType == secondType) {
-      return firstType;
-    } else {
-      TypeMask union = firstType.union(secondType, classWorld);
-      // TODO(kasperl): If the union isn't nullable it seems wasteful
-      // to use dynamic. Fix that.
-      return union.containsAll(classWorld) ? dynamicType : union;
-    }
-  }
-
-  TypeMask allocateDiamondPhi(TypeMask firstType, TypeMask secondType) {
-    return computeLUB(firstType, secondType);
-  }
-
-  TypeMask get dynamicType => compiler.typesTask.dynamicType;
-  TypeMask get nullType => compiler.typesTask.nullType;
-  TypeMask get intType => compiler.typesTask.intType;
-  TypeMask get uint32Type => compiler.typesTask.uint32Type;
-  TypeMask get uint31Type => compiler.typesTask.uint31Type;
-  TypeMask get positiveIntType => compiler.typesTask.positiveIntType;
-  TypeMask get doubleType => compiler.typesTask.doubleType;
-  TypeMask get numType => compiler.typesTask.numType;
-  TypeMask get boolType => compiler.typesTask.boolType;
-  TypeMask get functionType => compiler.typesTask.functionType;
-  TypeMask get listType => compiler.typesTask.listType;
-  TypeMask get constListType => compiler.typesTask.constListType;
-  TypeMask get fixedListType => compiler.typesTask.fixedListType;
-  TypeMask get growableListType => compiler.typesTask.growableListType;
-  TypeMask get mapType => compiler.typesTask.mapType;
-  TypeMask get constMapType => compiler.typesTask.constMapType;
-  TypeMask get stringType => compiler.typesTask.stringType;
-  TypeMask get typeType => compiler.typesTask.typeType;
-  bool isNull(TypeMask mask) => mask.isEmpty && mask.isNullable;
-
-  TypeMask stringLiteralType(ast.DartString value) => stringType;
-  TypeMask boolLiteralType(ast.LiteralBool value) => boolType;
-
-  TypeMask nonNullSubtype(ClassElement type)
-      => new TypeMask.nonNullSubtype(type.declaration, classWorld);
-  TypeMask nonNullSubclass(ClassElement type)
-      => new TypeMask.nonNullSubclass(type.declaration, classWorld);
-  TypeMask nonNullExact(ClassElement type)
-      => new TypeMask.nonNullExact(type.declaration, classWorld);
-  TypeMask nonNullEmpty() => new TypeMask.nonNullEmpty();
-
-  TypeMask allocateList(TypeMask type,
-                        ast.Node node,
-                        Element enclosing,
-                        [TypeMask elementType, int length]) {
-    return new ContainerTypeMask(type, node, enclosing, elementType, length);
-  }
-
-  TypeMask allocateMap(TypeMask type, ast.Node node, Element element,
-                       [List<TypeMask> keys, List<TypeMask> values]) {
-    return type;
-  }
-
-  TypeMask allocateClosure(ast.Node node, Element element) {
-    return functionType;
-  }
-
-  TypeMask newTypedSelector(TypeMask receiver, TypeMask mask) {
-    return receiver;
-  }
-
-  TypeMask addPhiInput(Local variable,
-                       TypeMask phiType,
-                       TypeMask newType) {
-    return computeLUB(phiType, newType);
-  }
-
-  TypeMask allocatePhi(ast.Node node,
-                       Local variable,
-                       TypeMask inputType) {
-    return inputType;
-  }
-
-  TypeMask allocateLoopPhi(ast.Node node,
-                           Local variable,
-                           TypeMask inputType) {
-    return inputType;
-  }
-
-  TypeMask simplifyPhi(ast.Node node,
-                       Local variable,
-                       TypeMask phiType) {
-    return phiType;
-  }
-
-  bool selectorNeedsUpdate(TypeMask type, TypeMask mask) {
-    return type != mask;
-  }
-
-  TypeMask refineReceiver(Selector selector,
-                          TypeMask mask,
-                          TypeMask receiverType,
-                          bool isConditional) {
-    TypeMask newType =
-        compiler.world.allFunctions.receiverType(selector, mask);
-    return receiverType.intersection(newType, classWorld);
-  }
-
-  TypeMask getConcreteTypeFor(TypeMask mask) => mask;
-}
-
-/**
  * Common super class used by [SimpleTypeInferrerVisitor] to propagate
  * type information about visited nodes, as well as to request type
  * information of elements.
@@ -207,6 +68,10 @@
       : this.compiler = compiler,
         this.classWorld = compiler.world;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  CoreTypes get coreTypes => compiler.coreTypes;
+
   /**
    * Records the default type of parameter [parameter].
    */
@@ -388,20 +253,20 @@
     for (var type in typesReturned) {
       T mappedType;
       if (type == native.SpecialType.JsObject) {
-        mappedType = types.nonNullExact(compiler.objectClass);
-      } else if (type.element == compiler.stringClass) {
+        mappedType = types.nonNullExact(coreClasses.objectClass);
+      } else if (type == coreTypes.stringType) {
         mappedType = types.stringType;
-      } else if (type.element == compiler.intClass) {
+      } else if (type == coreTypes.intType) {
         mappedType = types.intType;
-      } else if (type.element == compiler.numClass ||
-                 type.element == compiler.doubleClass) {
+      } else if (type == coreTypes.numType ||
+                 type == coreTypes.doubleType) {
         // Note: the backend double class is specifically for non-integer
         // doubles, and a native behavior returning 'double' does not guarantee
         // a non-integer return type, so we return the number type for those.
         mappedType = types.numType;
-      } else if (type.element == compiler.boolClass) {
+      } else if (type == coreTypes.boolType) {
         mappedType = types.boolType;
-      } else if (type.element == compiler.nullClass) {
+      } else if (type == coreTypes.nullType) {
         mappedType = types.nullType;
       } else if (type.isVoid) {
         mappedType = types.nullType;
@@ -451,9 +316,9 @@
   }
 
   bool isNativeElement(Element element) {
-    if (element.isNative) return true;
+    if (compiler.backend.isNative(element)) return true;
     return element.isClassMember
-        && element.enclosingClass.isNative
+        && compiler.backend.isNative(element.enclosingClass)
         && element.isField;
   }
 
@@ -472,6 +337,15 @@
   }
 }
 
+/// [SimpleTypeInferrerVisitor] can be thought of as a type-inference graph
+/// builder for a single element.
+///
+/// Calling [run] will start the work of visiting the body of the code to
+/// construct a set of infernece-nodes that abstractly represent what the code
+/// is doing.
+///
+/// This visitor is parameterized by an [InferenceEngine], which internally
+/// decides how to represent inference nodes.
 class SimpleTypeInferrerVisitor<T>
     extends InferrerVisitor<T, InferrerEngine<T, TypeSystem<T>>> {
   T returnType;
@@ -555,7 +429,7 @@
       inferrer.setDefaultTypeOfParameter(element, type);
     });
 
-    if (analyzedElement.isNative) {
+    if (compiler.backend.isNative(analyzedElement)) {
       // Native methods do not have a body, and we currently just say
       // they return dynamic.
       return types.dynamicType;
@@ -637,27 +511,55 @@
           }
         });
       }
-      returnType = types.nonNullExact(cls);
+      if (analyzedElement.isGenerativeConstructor && cls.isAbstract) {
+        if (compiler.world.isDirectlyInstantiated(cls)) {
+          returnType = types.nonNullExact(cls);
+        } else if (compiler.world.isIndirectlyInstantiated(cls)) {
+          returnType = types.nonNullSubclass(cls);
+        } else  {
+          // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this
+          // case; it's never called.
+          returnType = types.nonNullEmpty();
+        }
+      } else {
+        returnType = types.nonNullExact(cls);
+      }
     } else {
       signature.forEachParameter((LocalParameterElement element) {
         locals.update(element, inferrer.typeOfElement(element), node);
       });
       visit(node.body);
-      if (function.asyncMarker != AsyncMarker.SYNC) {
-        // TODO(herhut): Should be type Future/Iterable/Stream instead of
-        // dynamic.
-        returnType = inferrer.addReturnTypeFor(
-            analyzedElement, returnType, types.dynamicType);
-      } else if (returnType == null) {
-        // No return in the body.
-        returnType = locals.seenReturnOrThrow
-            ? types.nonNullEmpty()  // Body always throws.
-            : types.nullType;
-      } else if (!locals.seenReturnOrThrow) {
-        // We haven't seen returns on all branches. So the method may
-        // also return null.
-        returnType = inferrer.addReturnTypeFor(
-            analyzedElement, returnType, types.nullType);
+      switch (function.asyncMarker) {
+        case AsyncMarker.SYNC:
+          if (returnType == null) {
+            // No return in the body.
+            returnType = locals.seenReturnOrThrow
+                ? types.nonNullEmpty()  // Body always throws.
+                : types.nullType;
+          } else if (!locals.seenReturnOrThrow) {
+            // We haven't seen returns on all branches. So the method may
+            // also return null.
+            returnType = inferrer.addReturnTypeFor(
+                analyzedElement, returnType, types.nullType);
+          }
+          break;
+
+        case AsyncMarker.SYNC_STAR:
+          // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
+          //               contained is the method body's return type.
+          returnType = inferrer.addReturnTypeFor(
+              analyzedElement, returnType, types.syncStarIterableType);
+          break;
+
+        case AsyncMarker.ASYNC:
+          returnType = inferrer.addReturnTypeFor(
+                analyzedElement, returnType, types.asyncFutureType);
+          break;
+
+        case AsyncMarker.ASYNC_STAR:
+          returnType = inferrer.addReturnTypeFor(
+                analyzedElement, returnType, types.asyncStarStreamType);
+          break;
       }
     }
 
@@ -901,7 +803,7 @@
       T getterType;
       T newType;
 
-      if (Elements.isErroneous(element)) return types.dynamicType;
+      if (Elements.isMalformed(element)) return types.dynamicType;
 
       if (Elements.isStaticOrTopLevelField(element)) {
         Element getterElement = elements[node.selector];
@@ -1260,7 +1162,7 @@
                           T rhsType,
                           ast.Node rhs) {
     ArgumentsTypes arguments = new ArgumentsTypes<T>([rhsType], null);
-    if (Elements.isErroneous(element)) {
+    if (Elements.isMalformed(element)) {
       // Code will always throw.
     } else if (Elements.isStaticOrTopLevelField(element)) {
       handleStaticSend(node, setterSelector, setterMask, element, arguments);
@@ -2211,7 +2113,7 @@
 
   T visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
     Element element = elements.getRedirectingTargetConstructor(node);
-    if (Elements.isErroneous(element)) {
+    if (Elements.isMalformed(element)) {
       recordReturnType(types.dynamicType);
     } else {
       // We don't create a selector for redirecting factories, and
@@ -2276,9 +2178,9 @@
   T visitAsyncForIn(ast.AsyncForIn node) {
     T expressionType = visit(node.expression);
 
-    Selector currentSelector = elements.getCurrentSelector(node);
+    Selector currentSelector = Selectors.current;
     TypeMask currentMask = elements.getCurrentTypeMask(node);
-    Selector moveNextSelector = elements.getMoveNextSelector(node);
+    Selector moveNextSelector = Selectors.moveNext;
     TypeMask moveNextMask = elements.getMoveNextTypeMask(node);
 
     js.JavaScriptBackend backend = compiler.backend;
@@ -2295,11 +2197,11 @@
 
   T visitSyncForIn(ast.SyncForIn node) {
     T expressionType = visit(node.expression);
-    Selector iteratorSelector = elements.getIteratorSelector(node);
+    Selector iteratorSelector = Selectors.iterator;
     TypeMask iteratorMask = elements.getIteratorTypeMask(node);
-    Selector currentSelector = elements.getCurrentSelector(node);
+    Selector currentSelector = Selectors.current;
     TypeMask currentMask = elements.getCurrentTypeMask(node);
-    Selector moveNextSelector = elements.getMoveNextSelector(node);
+    Selector moveNextSelector = Selectors.moveNext;
     TypeMask moveNextMask = elements.getMoveNextTypeMask(node);
 
     T iteratorType = handleDynamicSend(
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 86551cb..4ff72ab 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -4,9 +4,7 @@
 
 library type_graph_inferrer;
 
-import 'dart:collection' show
-    IterableBase,
-    Queue;
+import 'dart:collection' show Queue;
 
 import '../common.dart';
 import '../common/names.dart' show
@@ -15,8 +13,6 @@
 import '../compiler.dart' show
     Compiler;
 import '../constants/values.dart';
-import '../cps_ir/cps_ir_nodes.dart' as cps_ir show
-    Node;
 import '../dart_types.dart' show
     DartType,
     FunctionType,
@@ -26,7 +22,6 @@
 import '../js_backend/js_backend.dart' show
     Annotations,
     JavaScriptBackend;
-import '../native/native.dart' as native;
 import '../resolution/tree_elements.dart' show
     TreeElementMapping;
 import '../tree/tree.dart' as ast show
@@ -38,11 +33,9 @@
     TryStatement;
 import '../types/types.dart' show
     ContainerTypeMask,
-    DictionaryTypeMask,
     MapTypeMask,
     TypeMask,
-    TypesInferrer,
-    ValueTypeMask;
+    TypesInferrer;
 import '../types/constants.dart' show
     computeTypeMask;
 import '../universe/call_structure.dart' show
@@ -62,15 +55,12 @@
     TypeSystem;
 import 'simple_types_inferrer.dart';
 
-part 'closure_tracer.dart';
-part 'list_tracer.dart';
-part 'map_tracer.dart';
-part 'node_tracer.dart';
-part 'type_graph_nodes.dart';
+import 'closure_tracer.dart';
+import 'list_tracer.dart';
+import 'map_tracer.dart';
+import 'type_graph_nodes.dart';
+import 'debug.dart' as debug;
 
-bool _VERBOSE = false;
-bool _PRINT_SUMMARY = false;
-final _ANOMALY_WARN = false;
 
 class TypeInformationSystem extends TypeSystem<TypeInformation> {
   final Compiler compiler;
@@ -233,6 +223,27 @@
         getConcreteTypeFor(compiler.typesTask.dynamicType);
   }
 
+  TypeInformation asyncFutureTypeCache;
+  TypeInformation get asyncFutureType {
+    if (asyncFutureTypeCache != null) return asyncFutureTypeCache;
+    return asyncFutureTypeCache =
+        getConcreteTypeFor(compiler.typesTask.asyncFutureType);
+  }
+
+  TypeInformation syncStarIterableTypeCache;
+  TypeInformation get syncStarIterableType {
+    if (syncStarIterableTypeCache != null) return syncStarIterableTypeCache;
+    return syncStarIterableTypeCache =
+        getConcreteTypeFor(compiler.typesTask.syncStarIterableType);
+  }
+
+  TypeInformation asyncStarStreamTypeCache;
+  TypeInformation get asyncStarStreamType {
+    if (asyncStarStreamTypeCache != null) return asyncStarStreamTypeCache;
+    return asyncStarStreamTypeCache =
+        getConcreteTypeFor(compiler.typesTask.asyncStarStreamType);
+  }
+
   TypeInformation nonNullEmptyType;
 
   TypeInformation stringLiteralType(ast.DartString value) {
@@ -316,6 +327,16 @@
     }
   }
 
+  TypeInformation narrowNotNull(TypeInformation type) {
+    if (type.type.isExact && !type.type.isNullable) {
+      return type;
+    }
+    TypeInformation newType =
+        new NarrowTypeInformation(type, dynamicType.type.nonNullable());
+    allocatedTypes.add(newType);
+    return newType;
+  }
+
   ElementTypeInformation getInferredTypeOf(Element element) {
     element = element.implementation;
     return typeInformations.putIfAbsent(element, () {
@@ -517,11 +538,28 @@
   }
 
   TypeMask joinTypeMasks(Iterable<TypeMask> masks) {
-    TypeMask newType = const TypeMask.nonNullEmpty();
+    var dynamicType = compiler.typesTask.dynamicType;
+    // Optimization: we are iterating over masks twice, but because `masks` is a
+    // mapped iterable, we save the intermediate results to avoid computing them
+    // again.
+    var list = [];
     for (TypeMask mask in masks) {
-      newType = newType.union(mask, classWorld);
+      // Don't do any work on computing unions if we know that after all that
+      // work the result will be `dynamic`.
+      // TODO(sigmund): change to `mask == dynamicType` so we can continue to
+      // track the non-nullable bit.
+      if (mask.containsAll(classWorld)) return dynamicType;
+      list.add(mask);
     }
-    return newType.containsAll(classWorld) ? dynamicType.type : newType;
+
+    TypeMask newType = null;
+    for (TypeMask mask in masks) {
+      newType = newType == null ? mask : newType.union(mask, classWorld);
+      // Likewise - stop early if we already reach dynamic.
+      if (newType.containsAll(classWorld)) return dynamicType;
+    }
+
+    return newType ?? const TypeMask.nonNullEmpty();
   }
 }
 
@@ -591,7 +629,7 @@
    * A set of selector names that [List] implements, that we know return
    * their element type.
    */
-  final Set<Selector> _returnsListElementTypeSet = new Set<Selector>.from(
+  final Set<Selector> returnsListElementTypeSet = new Set<Selector>.from(
     <Selector>[
       new Selector.getter(const PublicName('first')),
       new Selector.getter(const PublicName('last')),
@@ -606,7 +644,7 @@
   bool returnsListElementType(Selector selector, TypeMask mask) {
     return mask != null &&
            mask.isContainer &&
-           _returnsListElementTypeSet.contains(selector);
+           returnsListElementTypeSet.contains(selector);
   }
 
   bool returnsMapValueType(Selector selector, TypeMask mask) {
@@ -702,7 +740,7 @@
         if (!tracer.continueAnalyzing) {
           elements.forEach((FunctionElement e) {
             compiler.world.registerMightBePassedToApply(e);
-            if (_VERBOSE) print("traced closure $e as ${true} (bail)");
+            if (debug.VERBOSE) print("traced closure $e as ${true} (bail)");
             e.functionSignature.forEachParameter((parameter) {
               types.getInferredTypeOf(parameter).giveUp(
                   this,
@@ -723,7 +761,7 @@
           if (tracer.tracedType.mightBePassedToFunctionApply) {
             compiler.world.registerMightBePassedToApply(e);
           };
-          if (_VERBOSE) {
+          if (debug.VERBOSE) {
             print("traced closure $e as "
                 "${compiler.world.getMightBePassedToApply(e)}");
           }
@@ -777,7 +815,7 @@
     workQueue.addAll(seenTypes);
     refine();
 
-    if (_PRINT_SUMMARY) {
+    if (debug.PRINT_SUMMARY) {
       types.allocatedLists.values.forEach((ListTypeInformation info) {
         print('${info.type} '
               'for ${info.originalType.allocationNode} '
@@ -925,7 +963,7 @@
         overallRefineCount++;
         info.refineCount++;
         if (info.refineCount > MAX_CHANGE_COUNT) {
-          if (_ANOMALY_WARN) {
+          if (debug.ANOMALY_WARN) {
             print("ANOMALY WARNING: max refinement reached for $info");
           }
           info.giveUp(this);
@@ -1226,7 +1264,7 @@
         assert(invariant(element,
             element.isField ||
             element.isFunction ||
-            element.isGenerativeConstructor ||
+            element.isConstructor ||
             element.isGetter ||
             element.isSetter,
             message: 'Unexpected element kind: ${element.kind}'));
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index dd50651..cbc662c 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -2,7 +2,44 @@
 // for 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 type_graph_inferrer;
+library compiler.src.inferrer.type_graph_nodes;
+
+import 'dart:collection' show IterableBase;
+
+import '../common.dart';
+import '../common/names.dart' show Identifiers;
+import '../compiler.dart' show Compiler;
+import '../constants/values.dart';
+import '../cps_ir/cps_ir_nodes.dart' as cps_ir show Node;
+import '../dart_types.dart' show
+    DartType,
+    FunctionType,
+    InterfaceType,
+    TypeKind;
+import '../elements/elements.dart';
+import '../native/native.dart' as native;
+import '../tree/tree.dart' as ast show
+    DartString,
+    Node,
+    LiteralBool,
+    Send,
+    SendSet,
+    TryStatement;
+import '../types/types.dart' show
+    ContainerTypeMask,
+    DictionaryTypeMask,
+    MapTypeMask,
+    TypeMask,
+    ValueTypeMask;
+import '../universe/selector.dart' show Selector;
+import '../util/util.dart' show ImmutableEmptySet, Setlet;
+import '../world.dart' show ClassWorld;
+
+import 'inferrer_visitor.dart' show ArgumentsTypes;
+import 'type_graph_inferrer.dart' show
+    TypeGraphInferrerEngine,
+    TypeInformationSystem;
+import 'debug.dart' as debug;
 
 /**
  * Common class for all nodes in the graph. The current nodes are:
@@ -455,14 +492,14 @@
       return mask;
     }
     if (element.isField) {
-      return new TypeMaskSystem(compiler).narrowType(mask, element.type);
+      return _narrowType(compiler, mask, element.type);
     }
     assert(element.isFunction ||
            element.isGetter ||
            element.isFactoryConstructor);
 
     FunctionType type = element.type;
-    return new TypeMaskSystem(compiler).narrowType(mask, type.returnType);
+    return _narrowType(compiler, mask, type.returnType);
   }
 
   TypeMask computeType(TypeGraphInferrerEngine inferrer) {
@@ -594,7 +631,7 @@
     // ignore type annotations to ensure that the checks are actually inserted
     // into the function body and retained until runtime.
     assert(!compiler.enableTypeAssertions);
-    return new TypeMaskSystem(compiler).narrowType(mask, element.type);
+    return _narrowType(compiler, mask, element.type);
   }
 
   TypeMask computeType(TypeGraphInferrerEngine inferrer) {
@@ -935,7 +972,7 @@
           ValueTypeMask arg = arguments.positional[0].type;
           String key = arg.value.primitiveValue.slowToString();
           if (dictionaryTypeMask.typeMap.containsKey(key)) {
-            if (_VERBOSE) {
+            if (debug.VERBOSE) {
               print("Dictionary lookup for $key yields "
                     "${dictionaryTypeMask.typeMap[key]}.");
             }
@@ -943,14 +980,14 @@
           } else {
             // The typeMap is precise, so if we do not find the key, the lookup
             // will be [null] at runtime.
-            if (_VERBOSE) {
+            if (debug.VERBOSE) {
               print("Dictionary lookup for $key yields [null].");
             }
             return inferrer.types.nullType.type;
           }
         }
         MapTypeMask mapTypeMask = typeMask;
-        if (_VERBOSE) {
+        if (debug.VERBOSE) {
           print(
               "Map lookup for $selector yields ${mapTypeMask.valueType}.");
         }
@@ -1180,7 +1217,7 @@
     TypeMask input = assignments.first.type;
     TypeMask intersection = input.intersection(typeAnnotation,
         inferrer.classWorld);
-    if (_ANOMALY_WARN) {
+    if (debug.ANOMALY_WARN) {
       if (!input.containsMask(intersection, inferrer.classWorld) ||
           !typeAnnotation.containsMask(intersection, inferrer.classWorld)) {
         print("ANOMALY WARNING: narrowed $input to $intersection via "
@@ -1611,3 +1648,24 @@
   T visitClosureTypeInformation(ClosureTypeInformation info);
   T visitAwaitTypeInformation(AwaitTypeInformation info);
 }
+
+TypeMask _narrowType(Compiler compiler, TypeMask type, DartType annotation,
+    {bool isNullable: true}) {
+  if (annotation.treatAsDynamic) return type;
+  if (annotation.isObject) return type;
+  TypeMask otherType;
+  if (annotation.isTypedef || annotation.isFunctionType) {
+    otherType = compiler.typesTask.functionType;
+  } else if (annotation.isTypeVariable) {
+    // TODO(ngeoffray): Narrow to bound.
+    return type;
+  } else if (annotation.isVoid) {
+    otherType = compiler.typesTask.nullType;
+  } else {
+    assert(annotation.isInterfaceType);
+    otherType = new TypeMask.nonNullSubtype(annotation.element, compiler.world);
+  }
+  if (isNullable) otherType = otherType.nullable();
+  if (type == null) return otherType;
+  return type.intersection(otherType, compiler.world);
+}
diff --git a/pkg/compiler/lib/src/info/send_info.dart b/pkg/compiler/lib/src/info/send_info.dart
index b29fe96..8292be4 100644
--- a/pkg/compiler/lib/src/info/send_info.dart
+++ b/pkg/compiler/lib/src/info/send_info.dart
@@ -23,7 +23,6 @@
     ElementVisitor;
 import '../resolution/operators.dart';
 import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart';
 import '../resolution/tree_elements.dart';
 import '../constants/expressions.dart';
 import '../parser/partial_elements.dart' show
@@ -84,7 +83,7 @@
 
 /// Visitor that categorizes data about an individual send.
 class _StatsVisitor<T> extends Visitor
-    with SendResolverMixin, SemanticSendResolvedMixin<dynamic, T>
+    with SemanticSendResolvedMixin<dynamic, T>
     implements SemanticSendVisitor<dynamic, T> {
 
   // TODO(sigmund): consider passing in several AnalysisResults at once, so we
diff --git a/pkg/compiler/lib/src/io/source_file.dart b/pkg/compiler/lib/src/io/source_file.dart
index d799a9b..f2058ad 100644
--- a/pkg/compiler/lib/src/io/source_file.dart
+++ b/pkg/compiler/lib/src/io/source_file.dart
@@ -137,31 +137,53 @@
     if (colorize == null) {
       colorize = (text) => text;
     }
-    var line = getLine(start);
-    var column = getColumn(line, start);
+    if (end > length) {
+      start = length - 1;
+      end = length;
+    }
 
-    var buf = new StringBuffer('${filename}:');
+    int lineStart = getLine(start);
+    int columnStart = getColumn(lineStart, start);
+    int lineEnd = getLine(end);
+    int columnEnd = getColumn(lineEnd, end);
+
+    StringBuffer buf = new StringBuffer('${filename}:');
     if (start != end || start != 0) {
       // Line/column info is relevant.
-      buf.write('${line + 1}:${column + 1}:');
+      buf.write('${lineStart + 1}:${columnStart + 1}:');
     }
     buf.write('\n$message\n');
 
     if (start != end && includeSourceLine) {
-      String textLine = getLineText(line);
+      if (lineStart == lineEnd) {
+        String textLine = getLineText(lineStart);
 
-      int toColumn = min(column + (end-start), textLine.length);
-      buf.write(textLine.substring(0, column));
-      buf.write(colorize(textLine.substring(column, toColumn)));
-      buf.write(textLine.substring(toColumn));
+        int toColumn = min(columnStart + (end-start), textLine.length);
+        buf.write(textLine.substring(0, columnStart));
+        buf.write(colorize(textLine.substring(columnStart, toColumn)));
+        buf.write(textLine.substring(toColumn));
 
-      int i = 0;
-      for (; i < column; i++) {
-        buf.write(' ');
-      }
+        int i = 0;
+        for (; i < columnStart; i++) {
+          buf.write(' ');
+        }
 
-      for (; i < toColumn; i++) {
-        buf.write(colorize('^'));
+        for (; i < toColumn; i++) {
+          buf.write(colorize('^'));
+        }
+      } else {
+        for (int line = lineStart; line <= lineEnd; line++) {
+          String textLine = getLineText(line);
+          if (line == lineStart) {
+            buf.write(textLine.substring(0, columnStart));
+            buf.write(colorize(textLine.substring(columnStart)));
+          } else if (line == lineEnd) {
+            buf.write(colorize(textLine.substring(0, columnEnd)));
+            buf.write(textLine.substring(columnEnd));
+          } else {
+            buf.write(colorize(textLine));
+          }
+        }
       }
     }
 
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index 1a08cfb..3a9fd2e 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -162,4 +162,27 @@
 
   @override
   String get value => _literal.value;
-}
\ No newline at end of file
+}
+
+/// Returns `true` if [template] will immediately give a TypeError if the first
+/// placeholder is `null` or `undefined`.
+bool isNullGuardOnFirstArgument(Template template) {
+  // We look for a template of the form
+  //
+  //     #.something
+  //     #.something()
+  //
+  Node node = template.ast;
+  if (node is Call) {
+    Call call = node;
+    node = call.target;
+  }
+  if (node is PropertyAccess) {
+    PropertyAccess access = node;
+    if (access.receiver is InterpolatedExpression) {
+      InterpolatedExpression hole = access.receiver;
+      return hole.isPositional && hole.nameOrPosition == 0;
+    }
+  }
+  return false;
+}
diff --git a/pkg/compiler/lib/src/js/placeholder_safety.dart b/pkg/compiler/lib/src/js/placeholder_safety.dart
new file mode 100644
index 0000000..b103489
--- /dev/null
+++ b/pkg/compiler/lib/src/js/placeholder_safety.dart
@@ -0,0 +1,328 @@
+// 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 js.safety;
+
+import "js.dart" as js;
+
+typedef bool PositionPredicate(int position);
+
+/// PlaceholderSafetyAnalysis determines which placeholders in a JavaScript
+/// template may be replaced with an arbitrary expression. Placeholders may be
+/// replaced with an arbitrary expression providied the template ensures the
+/// placeholders are evaluated in the same left-to-right order with no
+/// additional effects interleaved.
+///
+/// The result is semi-conservative, giving reasonable results for many simple
+/// JS fragments. The non-conservative part is the assumption that arithmetic
+/// operators are used on 'good' operands that do not force arbitrary code to be
+/// executed via conversions (valueOf() and toString() methods).
+class PlaceholderSafetyAnalysis extends js.BaseVisitor<int> {
+  final PositionPredicate isNullableInput;
+  int nextPosition = 0;
+  int maxSafePosition = -1;
+  bool safe = true;
+
+  // We do a crude abstract interpretation to find operations that might throw
+  // exceptions. The possible values of expressions are represented by
+  // integers. Small non-negative integers 0, 1, 2, ... represent the values of
+  // the placeholders. Other values are:
+  static const int NONNULL_VALUE = -1;  // Unknown but not null.
+  static const int UNKNOWN_VALUE = -2;  // Unknown and might be null.
+
+  PlaceholderSafetyAnalysis._(this.isNullableInput);
+
+  /// Returns the number of placeholders that can be substituted into the
+  /// template AST [node] without changing the order of observable effects.
+  /// [isNullableInput] is a function that takes the 0-based index of a
+  /// placeholder and returns `true` if expression at run time may be null, and
+  /// `false` if the value is never null.
+  static int analyze(js.Node node, PositionPredicate isNullableInput) {
+    PlaceholderSafetyAnalysis analysis =
+        new PlaceholderSafetyAnalysis._(isNullableInput);
+    analysis.visit(node);
+    return analysis.maxSafePosition + 1;
+  }
+
+  bool canBeNull(int value) {
+    if (value == NONNULL_VALUE) return false;
+    if (value == UNKNOWN_VALUE) return true;
+    return isNullableInput(value);
+  }
+
+  int unsafe(int value) {
+    safe = false;
+    return value;
+  }
+
+  int visit(js.Node node) {
+    return node.accept(this);
+  }
+
+  int visitNode(js.Node node) {
+    safe = false;
+    super.visitNode(node);
+    return UNKNOWN_VALUE;
+  }
+
+  int visitLiteralNull(js.LiteralNull node) {
+    return UNKNOWN_VALUE;
+  }
+
+  int visitLiteral(js.Literal node) {
+    return NONNULL_VALUE;
+  }
+
+  int handleInterpolatedNode(js.InterpolatedNode node) {
+    assert(node.isPositional);
+    int position = nextPosition++;
+    if (safe) maxSafePosition = position;
+    return position;
+  }
+
+  int visitInterpolatedExpression(js.InterpolatedExpression node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitInterpolatedLiteral(js.InterpolatedLiteral node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitInterpolatedSelector(js.InterpolatedSelector node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitInterpolatedStatement(js.InterpolatedStatement node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitInterpolatedDeclaration(js.InterpolatedDeclaration node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitObjectInitializer(js.ObjectInitializer node) {
+    for (js.Property property in node.properties) {
+      visit(property);
+    }
+    return NONNULL_VALUE;
+  }
+
+  int visitProperty(js.Property node) {
+    visit(node.name);
+    visit(node.value);
+    return UNKNOWN_VALUE;
+  }
+
+  int visitArrayInitializer(js.ArrayInitializer node) {
+    node.elements.forEach(visit);
+    return NONNULL_VALUE;
+  }
+
+  int visitArrayHole(js.ArrayHole node) {
+    return UNKNOWN_VALUE;
+  }
+
+  int visitAccess(js.PropertyAccess node) {
+    int first = visit(node.receiver);
+    int second = visit(node.selector);
+    // TODO(sra): If the JS is annotated as never throwing, we can avoid this.
+    if (canBeNull(first)) safe = false;
+    return UNKNOWN_VALUE;
+  }
+
+  int visitAssignment(js.Assignment node) {
+    js.Expression left = node.leftHandSide;
+    js.Expression right = node.value;
+
+    int leftToRight() {
+      visit(left);
+      visit(right);
+      return UNKNOWN_VALUE;
+    }
+
+    if (left is js.InterpolatedNode) {
+      // A bare interpolated expression should not be the LHS of an assignment.
+      safe = false;
+      return leftToRight();
+    }
+    
+    // Assignment operators dereference the LHS before evaluating the RHS.
+    if (node.op != null) return leftToRight();
+
+    // Assignment (1) evaluates the LHS as a Reference `lval`, (2) evaluates the
+    // RHS as a value, (3) dereferences the `lval` in PutValue.
+    if (left is js.VariableReference) {
+      int value = visit(right); 
+      // Assignment could change an observed global or cause a ReferenceError.
+      safe = false;
+      return value;
+    }
+    if (left is js.PropertyAccess) {
+      // "a.b.x = c.y" gives a TypeError for null values in this order: `a`,
+      // `c`, `a.b`.
+      int receiver = visit(left.receiver);
+      int selector = visit(left.selector);
+      int value = visit(right);
+      if (canBeNull(receiver)) safe = false;
+      return value;
+    }
+    // Be conserative with unrecognized LHS expressions.
+    safe = false;
+    return leftToRight();
+  }
+
+  int visitCall(js.Call node) {
+    // TODO(sra): Recognize JavaScript built-ins like
+    // 'Object.prototype.hasOwnProperty.call'.
+    visit(node.target);
+    node.arguments.forEach(visit);
+    return unsafe(UNKNOWN_VALUE);
+  }
+
+  int visitNew(js.New node) {
+    visit(node.target);
+    node.arguments.forEach(visit);
+    return unsafe(NONNULL_VALUE);
+  }
+
+  int visitBinary(js.Binary node) {
+    switch (node.op) {
+      // We make the non-conservative assumption that these operations are not
+      // used in ways that force calling arbitrary code via valueOf() or
+      // toString().
+      case "*":
+      case "/":
+      case "%":
+      case "+":
+      case "-":
+      case "<<":
+      case ">>":
+      case ">>>":
+      case "<":
+      case ">":
+      case "<=":
+      case ">=":
+      case "==":
+      case "===":
+      case "!=":
+      case "!==":
+      case "&":
+      case "^":
+      case "|":
+        int left = visit(node.left);
+        int right = visit(node.right);
+        return NONNULL_VALUE;  // Number, String, Boolean.
+
+      case ',':
+        int left = visit(node.left);
+        int right = visit(node.right);
+        return right;
+
+      case "&&":
+      case "||":
+        int left = visit(node.left);
+        // TODO(sra): Might be safe, e.g.  "x || 0".
+        safe = false;
+        int right = visit(node.right);
+        return UNKNOWN_VALUE;
+
+      case "instanceof":
+      case "in":
+        int left = visit(node.left);
+        int right = visit(node.right);
+        return UNKNOWN_VALUE;
+
+      default:
+        return unsafe(UNKNOWN_VALUE);
+    }
+  }
+
+  int visitConditional(js.Conditional node) {
+    int cond = visit(node.condition);
+    // TODO(sra): Might be safe, e.g.  "# ? 1 : 2".
+    safe = false;
+    int thenValue = visit(node.then);
+    int elseValue = visit(node.otherwise);
+    return UNKNOWN_VALUE;
+  }
+
+  int visitThrow(js.Throw node) {
+    visit(node.expression);
+    return unsafe(UNKNOWN_VALUE);
+  }
+
+  int visitPrefix(js.Prefix node) {
+    if (node.op == 'typeof') {
+      // "typeof a" first evaluates to a Reference. If the Reference is to a
+      // variable that is not present, "undefined" is returned without
+      // dereferencing.
+      if (node.argument is js.VariableUse) return NONNULL_VALUE;  // A string.
+    }
+
+    visit(node.argument);
+
+    switch (node.op) {
+      case '+':
+      case '-':
+      case '!':
+      case '~':
+        // Non-conservative assumption that these operators are used on values
+        // that do not call arbitrary code via valueOf() or toString().
+        return NONNULL_VALUE;
+
+      case 'typeof':
+        return NONNULL_VALUE;  // Always a string.
+
+      case 'void':
+        return UNKNOWN_VALUE;
+
+      case '--':
+      case '++':
+        return NONNULL_VALUE;  // Always a number.
+
+      default:
+        safe = false;
+        return UNKNOWN_VALUE;
+    }
+  }
+
+  int visitPostfix(js.Postfix node) {
+    assert(node.op == '--' || node.op == '++');
+    visit(node.argument);
+    return NONNULL_VALUE;  // Always a number, even for "(a=null, a++)".
+  }
+
+  int visitVariableUse(js.VariableUse node) {
+    // We could get a ReferenceError unless the variable is in scope.  For JS
+    // fragments, the only use of VariableUse outside a `function(){...}` should
+    // be for global references. Certain global names are almost certainly not
+    // reference errors, e.g 'Array'.
+    switch (node.name) {
+      case 'Array':
+      case 'Date':
+      case 'Function':
+      case 'Math':
+      case 'Number':
+      case 'Object':
+      case 'RegExp':
+      case 'String':
+      case 'self':
+      case 'window':
+        return NONNULL_VALUE;
+      default:
+        return unsafe(UNKNOWN_VALUE);
+    }
+  }
+
+  int visitFun(js.Fun node) {
+    bool oldSafe = safe;
+    int oldNextPosition = nextPosition;
+    visit(node.body);
+    // Creating a function has no effect on order unless there are embedded
+    // placeholders.
+    safe = (nextPosition == oldNextPosition) && oldSafe;
+    return NONNULL_VALUE;
+  }
+}
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 4be28d1..bbac37f 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -1023,7 +1023,7 @@
     }
 
     if (node.init != null) {
-      addExpressionStatement(visitExpression(node.init));
+      visitExpressionIgnoreResult(node.init);
     }
     int startLabel = newLabel("for condition");
     // If there is no update, continuing the loop is the same as going to the
@@ -1553,29 +1553,17 @@
 
   @override
   js.Expression visitVariableDeclarationList(js.VariableDeclarationList node) {
-    List<js.Expression> initializations = new List<js.Expression>();
-
-    // Declaration of local variables is hoisted outside the helper but the
-    // initialization is done here.
     for (js.VariableInitialization initialization in node.declarations) {
       js.VariableDeclaration declaration = initialization.declaration;
       localVariables.add(declaration);
       if (initialization.value != null) {
         withExpression(initialization.value, (js.Expression value) {
-          initializations.add(
+          addExpressionStatement(
               new js.Assignment(new js.VariableUse(declaration.name), value));
         }, store: false);
       }
     }
-    if (initializations.isEmpty) {
-      // Dummy expression. Will be dropped by [visitExpressionIgnoreResult].
-      return js.number(0);
-    } else {
-      return initializations.reduce(
-          (js.Expression first, js.Expression second) {
-        return new js.Binary(",", first, second);
-      });
-    }
+    return js.number(0); // Dummy expression.
   }
 
   @override
@@ -2457,12 +2445,12 @@
 
   @override
   bool visitStringConcatenation(js.StringConcatenation node) {
-    return true;
+    return false;
   }
 
   @override
   bool visitName(js.Name node) {
-    return true;
+    return false;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 892f819..05b00d1 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -220,43 +220,18 @@
 }
 
 class JavaScriptBackend extends Backend {
-  static final Uri DART_JS_HELPER = new Uri(scheme: 'dart', path: '_js_helper');
-  static final Uri DART_INTERCEPTORS =
-      new Uri(scheme: 'dart', path: '_interceptors');
-  static final Uri DART_FOREIGN_HELPER =
-      new Uri(scheme: 'dart', path: '_foreign_helper');
-  static final Uri DART_JS_MIRRORS =
-      new Uri(scheme: 'dart', path: '_js_mirrors');
-  static final Uri DART_JS_NAMES =
-      new Uri(scheme: 'dart', path: '_js_names');
-  static final Uri DART_EMBEDDED_NAMES =
-      new Uri(scheme: 'dart', path: '_js_embedded_names');
-  static final Uri DART_ISOLATE_HELPER =
-      new Uri(scheme: 'dart', path: '_isolate_helper');
-  static final Uri PACKAGE_JS =
-         new Uri(scheme: 'package', path: 'js/js.dart');
-  static final Uri PACKAGE_LOOKUP_MAP =
-      new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart');
-
-  static const String INVOKE_ON = '_getCachedInvocation';
-  static const String START_ROOT_ISOLATE = 'startRootIsolate';
-
-
   String get patchVersion => emitter.patchVersion;
 
   bool get supportsReflection => emitter.emitter.supportsReflection;
 
   final Annotations annotations;
 
-  /// Reference to the internal library to lookup functions to always inline.
-  LibraryElement internalLibrary;
-
 
   /// Set of classes that need to be considered for reflection although not
   /// otherwise visible during resolution.
   Iterable<ClassElement> get classesRequiredForReflection {
     // TODO(herhut): Clean this up when classes needed for rti are tracked.
-    return [closureClass, jsIndexableClass];
+    return [helpers.closureClass, helpers.jsIndexableClass];
   }
 
   FunctionCompiler functionCompiler;
@@ -272,75 +247,6 @@
 
   FunctionInlineCache inlineCache = new FunctionInlineCache();
 
-  LibraryElement jsHelperLibrary;
-  LibraryElement asyncLibrary;
-  LibraryElement interceptorsLibrary;
-  LibraryElement foreignLibrary;
-  LibraryElement isolateHelperLibrary;
-
-  ClassElement closureClass;
-  ClassElement boundClosureClass;
-  Element assertUnreachableMethod;
-  Element invokeOnMethod;
-
-  ClassElement jsInterceptorClass;
-  ClassElement jsStringClass;
-  ClassElement jsArrayClass;
-  ClassElement jsNumberClass;
-  ClassElement jsIntClass;
-  ClassElement jsDoubleClass;
-  ClassElement jsNullClass;
-  ClassElement jsBoolClass;
-  ClassElement jsPlainJavaScriptObjectClass;
-  ClassElement jsUnknownJavaScriptObjectClass;
-  ClassElement jsJavaScriptFunctionClass;
-  ClassElement jsJavaScriptObjectClass;
-
-  ClassElement jsIndexableClass;
-  ClassElement jsMutableIndexableClass;
-
-  ClassElement jsMutableArrayClass;
-  ClassElement jsFixedArrayClass;
-  ClassElement jsExtendableArrayClass;
-  ClassElement jsUnmodifiableArrayClass;
-  ClassElement jsPositiveIntClass;
-  ClassElement jsUInt32Class;
-  ClassElement jsUInt31Class;
-
-  Element jsIndexableLength;
-  Element jsArrayTypedConstructor;
-  Element jsArrayRemoveLast;
-  Element jsArrayAdd;
-  Element jsStringSplit;
-  Element jsStringToString;
-  Element jsStringOperatorAdd;
-  Element objectEquals;
-
-  ClassElement typeLiteralClass;
-  ClassElement mapLiteralClass;
-  ClassElement constMapLiteralClass;
-  ClassElement typeVariableClass;
-  ConstructorElement mapLiteralConstructor;
-  ConstructorElement mapLiteralConstructorEmpty;
-  Element mapLiteralUntypedMaker;
-  Element mapLiteralUntypedEmptyMaker;
-
-  ClassElement noSideEffectsClass;
-  ClassElement noThrowsClass;
-  ClassElement noInlineClass;
-  ClassElement forceInlineClass;
-  ClassElement irRepresentationClass;
-
-  ClassElement jsAnnotationClass;
-  ClassElement jsAnonymousClass;
-
-  Element getInterceptorMethod;
-
-  ClassElement jsInvocationMirrorClass;
-
-  ClassElement typedArrayClass;
-  ClassElement typedArrayOfIntClass;
-
   /// If [true], the compiler will emit code that logs whenever a method is
   /// called. When TRACE_METHOD is 'console' this will be logged
   /// directly in the JavaScript console. When TRACE_METHOD is 'post' the
@@ -365,8 +271,8 @@
   TypeMask _indexablePrimitiveTypeCache;
   TypeMask get indexablePrimitiveType {
     if (_indexablePrimitiveTypeCache == null) {
-      _indexablePrimitiveTypeCache =
-          new TypeMask.nonNullSubtype(jsIndexableClass, compiler.world);
+      _indexablePrimitiveTypeCache = new TypeMask.nonNullSubtype(
+          helpers.jsIndexableClass, compiler.world);
     }
     return _indexablePrimitiveTypeCache;
   }
@@ -374,8 +280,8 @@
   TypeMask _readableArrayTypeCache;
   TypeMask get readableArrayType {
     if (_readableArrayTypeCache == null) {
-      _readableArrayTypeCache = new TypeMask.nonNullSubclass(jsArrayClass,
-          compiler.world);
+      _readableArrayTypeCache = new TypeMask.nonNullSubclass(
+          helpers.jsArrayClass, compiler.world);
     }
     return _readableArrayTypeCache;
   }
@@ -383,8 +289,8 @@
   TypeMask _mutableArrayTypeCache;
   TypeMask get mutableArrayType {
     if (_mutableArrayTypeCache == null) {
-      _mutableArrayTypeCache = new TypeMask.nonNullSubclass(jsMutableArrayClass,
-          compiler.world);
+      _mutableArrayTypeCache = new TypeMask.nonNullSubclass(
+          helpers.jsMutableArrayClass, compiler.world);
     }
     return _mutableArrayTypeCache;
   }
@@ -392,8 +298,8 @@
   TypeMask _fixedArrayTypeCache;
   TypeMask get fixedArrayType {
     if (_fixedArrayTypeCache == null) {
-      _fixedArrayTypeCache = new TypeMask.nonNullExact(jsFixedArrayClass,
-          compiler.world);
+      _fixedArrayTypeCache = new TypeMask.nonNullExact(
+          helpers.jsFixedArrayClass, compiler.world);
     }
     return _fixedArrayTypeCache;
   }
@@ -401,8 +307,8 @@
   TypeMask _extendableArrayTypeCache;
   TypeMask get extendableArrayType {
     if (_extendableArrayTypeCache == null) {
-      _extendableArrayTypeCache =
-          new TypeMask.nonNullExact(jsExtendableArrayClass, compiler.world);
+      _extendableArrayTypeCache = new TypeMask.nonNullExact(
+          helpers.jsExtendableArrayClass, compiler.world);
     }
     return _extendableArrayTypeCache;
   }
@@ -410,8 +316,8 @@
   TypeMask _unmodifiableArrayTypeCache;
   TypeMask get unmodifiableArrayType {
     if (_unmodifiableArrayTypeCache == null) {
-      _unmodifiableArrayTypeCache =
-          new TypeMask.nonNullExact(jsUnmodifiableArrayClass, compiler.world);
+      _unmodifiableArrayTypeCache = new TypeMask.nonNullExact(
+          helpers.jsUnmodifiableArrayClass, compiler.world);
     }
     return _fixedArrayTypeCache;
   }
@@ -428,24 +334,12 @@
   /// Maps special classes to their implementation (JSXxx) class.
   Map<ClassElement, ClassElement> implementationClasses;
 
-  Element getNativeInterceptorMethod;
   bool needToInitializeIsolateAffinityTag = false;
   bool needToInitializeDispatchProperty = false;
 
-  /// Holds the method "getIsolateAffinityTag" when dart:_js_helper has been
-  /// loaded.
-  FunctionElement getIsolateAffinityTagMarker;
-
   final Namer namer;
 
   /**
-   * Interface used to determine if an object has the JavaScript
-   * indexing behavior. The interface is only visible to specific
-   * libraries.
-   */
-  ClassElement jsIndexingBehaviorInterface;
-
-  /**
    * A collection of selectors that must have a one shot interceptor
    * generated.
    */
@@ -516,35 +410,6 @@
   final RuntimeTypes rti;
   final RuntimeTypesEncoder rtiEncoder;
 
-  /// Holds the method "disableTreeShaking" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement disableTreeShakingMarker;
-
-  /// Holds the method "preserveNames" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement preserveNamesMarker;
-
-  /// Holds the method "preserveMetadata" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement preserveMetadataMarker;
-
-  /// Holds the method "preserveUris" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement preserveUrisMarker;
-
-  /// Holds the method "preserveLibraryNames" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionElement preserveLibraryNamesMarker;
-
-  /// Holds the method "requiresPreamble" in _js_helper.
-  FunctionElement requiresPreambleMarker;
-
-  /// Holds the class for the [JsGetName] enum.
-  EnumClassElement jsGetNameEnum;
-
-  /// Holds the class for the [JsBuiltins] enum.
-  EnumClassElement jsBuiltinEnum;
-
   /// True if a call to preserveMetadataMarker has been seen.  This means that
   /// metadata must be retained for dart:mirrors to work correctly.
   bool mustRetainMetadata = false;
@@ -631,7 +496,7 @@
 
   JavaScriptConstantTask constantCompilerTask;
 
-  JavaScriptResolutionCallbacks resolutionCallbacks;
+  JavaScriptImpactTransformer impactTransformer;
 
   PatchResolverTask patchResolverTask;
 
@@ -670,7 +535,7 @@
 
     noSuchMethodRegistry = new NoSuchMethodRegistry(this);
     constantCompilerTask = new JavaScriptConstantTask(compiler);
-    resolutionCallbacks = new JavaScriptResolutionCallbacks(this);
+    impactTransformer = new JavaScriptImpactTransformer(this);
     patchResolverTask = new PatchResolverTask(compiler);
     functionCompiler = compiler.useCpsIr
          ? new CpsFunctionCompiler(
@@ -682,6 +547,10 @@
 
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  CoreTypes get coreTypes => compiler.coreTypes;
+
   Resolution get resolution => compiler.resolution;
 
   /// Returns constant environment for the JavaScript interpretation of the
@@ -691,30 +560,17 @@
   }
 
   FunctionElement resolveExternalFunction(FunctionElement element) {
-    if (isForeign(element) || element.isJsInterop) return element;
+    if (isForeign(element) || isJsInterop(element)) return element;
     return patchResolverTask.measure(() {
       return patchResolverTask.resolveExternalFunction(element);
     });
   }
 
-  // TODO(karlklose): Split into findHelperFunction and findHelperClass and
-  // add a check that the element has the expected kind.
-  Element findHelper(String name) => find(jsHelperLibrary, name);
-  Element findAsyncHelper(String name) => find(asyncLibrary, name);
-  Element findInterceptor(String name) => find(interceptorsLibrary, name);
-
-  Element find(LibraryElement library, String name) {
-    Element element = library.implementation.findLocal(name);
-    assert(invariant(library, element != null,
-        message: "Element '$name' not found in '${library.canonicalUri}'."));
-    return element;
-  }
-
-  bool isForeign(Element element) => element.library == foreignLibrary;
+  bool isForeign(Element element) => element.library == helpers.foreignLibrary;
 
   bool isBackendLibrary(LibraryElement library) {
-    return library == interceptorsLibrary ||
-           library == jsHelperLibrary;
+    return library == helpers.interceptorsLibrary ||
+           library == helpers.jsHelperLibrary;
   }
 
   static Namer determineNamer(Compiler compiler) {
@@ -725,6 +581,52 @@
         new Namer(compiler);
   }
 
+  /// The backend must *always* call this method when enqueuing an
+  /// element. Calls done by the backend are not seen by global
+  /// optimizations, so they would make these optimizations unsound.
+  /// Therefore we need to collect the list of helpers the backend may
+  /// use.
+  // TODO(johnniwinther): Replace this with a more precise modelling; type
+  // inference of these elements is disabled.
+  Element registerBackendUse(Element element) {
+    if (element != null) {
+      bool registerUse = false;
+      if (element == helpers.streamIteratorConstructor ||
+          element == helpers.compiler.symbolConstructor ||
+          element == helpers.compiler.symbolValidatedConstructor ||
+          element == helpers.syncCompleterConstructor ||
+          element == coreClasses.symbolClass ||
+          element == helpers.objectNoSuchMethod) {
+        // TODO(johnniwinther): These are valid but we could be more precise.
+        registerUse = true;
+      } else if (element.implementationLibrary.isPatch ||
+                 element.library == helpers.jsHelperLibrary ||
+                 element.library == helpers.interceptorsLibrary ||
+                 element.library == helpers.isolateHelperLibrary) {
+        // TODO(johnniwinther): We should be more precise about these.
+        registerUse = true;
+      } else if (element == coreClasses.listClass ||
+                 element == helpers.mapLiteralClass ||
+                 element == coreClasses.functionClass ||
+                 element == coreClasses.stringClass) {
+        // TODO(johnniwinther): Avoid these.
+        registerUse = true;
+      }
+      if (!registerUse) {
+        assert(invariant(element, false,
+            message: "Backend use of $element is not allowed."));
+        return element;
+      }
+      helpersUsed.add(element.declaration);
+      if (element.isClass && element.isPatched) {
+        // Both declaration and implementation may declare fields, so we
+        // add both to the list of helpers.
+        helpersUsed.add(element.implementation);
+      }
+    }
+    return element;
+  }
+
   bool usedByBackend(Element element) {
     if (element.isParameter
         || element.isInitializingFormal
@@ -756,7 +658,7 @@
 
   bool isInterceptorClass(ClassElement element) {
     if (element == null) return false;
-    if (Elements.isNativeOrExtendsNative(element)) return true;
+    if (isNativeOrExtendsNative(element)) return true;
     if (interceptedClasses.contains(element)) return true;
     if (classesMixedIntoInterceptedClasses.contains(element)) return true;
     return false;
@@ -799,10 +701,175 @@
     return aliasedSuperMembers.contains(member);
   }
 
+  /// The JavaScript names for elements implemented via typed JavaScript
+  /// interop.
+  Map<Element, String> jsInteropNames = <Element, String>{};
+
+  /// The JavaScript names for native JavaScript elements implemented.
+  Map<Element, String> nativeMemberName = <Element, String>{};
+
+  /// Tag info for native JavaScript classes names. See
+  /// [setNativeClassTagInfo].
+  Map<ClassElement, String> nativeClassTagInfo = <ClassElement, String>{};
+
+  /// Returns `true` if [element] is explicitly marked as part of JsInterop.
+  bool _isJsInterop(Element element) {
+    return jsInteropNames.containsKey(element.declaration);
+  }
+
+  /// Returns [element] as an explicit part of JsInterop. The js interop name is
+  /// expected to be computed later.
+  void markAsJsInterop(Element element) {
+    jsInteropNames[element.declaration] = null;
+  }
+
+  /// Sets the explicit js interop [name] for [element].
+  void setJsInteropName(Element element, String name) {
+    assert(invariant(element,
+        isJsInterop(element),
+        message:
+          'Element $element is not js interop but given a js interop name.'));
+    jsInteropNames[element.declaration] = name;
+  }
+
+  /// Returns the explicit js interop name for [element].
+  String getJsInteropName(Element element) {
+    return jsInteropNames[element.declaration];
+  }
+
+  /// Returns `true` if [element] is part of JsInterop.
+  @override
+  bool isJsInterop(Element element) {
+    // An function is part of JsInterop in the following cases:
+    // * It has a jsInteropName annotation
+    // * It is external member of a class or library tagged as JsInterop.
+    if (element.isFunction || element.isConstructor || element.isAccessor) {
+      FunctionElement function = element;
+      if (!function.isExternal) return false;
+
+      if (_isJsInterop(function)) return true;
+      if (function.isClassMember) return isJsInterop(function.contextClass);
+      if (function.isTopLevel) return isJsInterop(function.library);
+      return false;
+    } else {
+      return _isJsInterop(element);
+    }
+  }
+
+  /// Returns `true` if the name of [element] is fixed for the generated
+  /// JavaScript.
+  bool hasFixedBackendName(Element element) {
+    return isJsInterop(element) ||
+        nativeMemberName.containsKey(element.declaration);
+  }
+
+  String _jsNameHelper(Element element) {
+    String jsInteropName = jsInteropNames[element.declaration];
+    assert(invariant(element,
+        !(_isJsInterop(element) && jsInteropName == null),
+        message:
+            'Element $element is js interop but js interop name has not yet '
+            'been computed.'));
+    if (jsInteropName != null && jsInteropName.isNotEmpty) {
+      return jsInteropName;
+    }
+    return element.isLibrary ? 'self' : element.name;
+  }
+
+  /// Computes the name for [element] to use in the generated JavaScript. This
+  /// is either given through a native annotation or a js interop annotation.
+  String getFixedBackendName(Element element) {
+    String name = nativeMemberName[element.declaration];
+    if (name == null && isJsInterop(element)) {
+      // If an element isJsInterop but _isJsInterop is false that means it is
+      // considered interop as the parent class is interop.
+      name = _jsNameHelper(
+          element.isConstructor ? element.enclosingClass : element);
+      nativeMemberName[element.declaration] = name;
+    }
+    return name;
+  }
+
+  /// Whether [element] corresponds to a native JavaScript construct either
+  /// through the native mechanism (`@Native(...)` or the `native` pseudo
+  /// keyword) which is only allowed for internal libraries or via the typed
+  /// JavaScriptInterop mechanism which is allowed for user libraries.
+  @override
+  bool isNative(Element element) {
+    if (isJsInterop(element)) return true;
+    if (element.isClass) {
+      return nativeClassTagInfo.containsKey(element.declaration);
+    } else {
+      return nativeMemberName.containsKey(element.declaration);
+    }
+  }
+
+  /// Sets the native [name] for the member [element]. This name is used for
+  /// [element] in the generated JavaScript.
+  void setNativeMemberName(MemberElement element, String name) {
+    // TODO(johnniwinther): Avoid setting this more than once. The enqueuer
+    // might enqueue [element] several times (before processing it) and computes
+    // name on each call to `internalAddToWorkList`.
+    assert(invariant(element,
+        nativeMemberName[element.declaration] == null ||
+        nativeMemberName[element.declaration] == name,
+        message:
+          "Native member name set inconsistently on $element: "
+          "Existing name '${nativeMemberName[element.declaration]}', "
+          "new name '$name'."));
+    nativeMemberName[element.declaration] = name;
+  }
+
+  /// Sets the native tag info for [cls].
+  ///
+  /// The tag info string contains comma-separated 'words' which are either
+  /// dispatch tags (having JavaScript identifier syntax) and directives that
+  /// begin with `!`.
+  void setNativeClassTagInfo(ClassElement cls, String tagInfo) {
+    // TODO(johnniwinther): Assert that this is only called once. The memory
+    // compiler copies pre-processed elements into a new compiler through
+    // [Compiler.onLibraryScanned] and thereby causes multiple calls to this
+    // method.
+    assert(invariant(cls,
+        nativeClassTagInfo[cls.declaration] == null ||
+        nativeClassTagInfo[cls.declaration] == tagInfo,
+        message:
+          "Native tag info set inconsistently on $cls: "
+          "Existing tag info '${nativeClassTagInfo[cls.declaration]}', "
+          "new tag info '$tagInfo'."));
+    nativeClassTagInfo[cls.declaration] = tagInfo;
+  }
+
+  /// Returns the list of native tag words for [cls].
+  List<String> getNativeTagsOfClassRaw(ClassElement cls) {
+    String quotedName = nativeClassTagInfo[cls.declaration];
+    return quotedName.substring(1, quotedName.length - 1).split(',');
+  }
+
+  /// Returns the list of non-directive native tag words for [cls].
+  List<String> getNativeTagsOfClass(ClassElement cls) {
+    return getNativeTagsOfClassRaw(cls).where(
+        (s) => !s.startsWith('!')).toList();
+  }
+
+  /// Returns `true` if [cls] has a `!nonleaf` tag word.
+  bool hasNativeTagsForcedNonLeaf(ClassElement cls) {
+    return getNativeTagsOfClassRaw(cls).contains('!nonleaf');
+  }
+
+  bool isNativeOrExtendsNative(ClassElement element) {
+    if (element == null) return false;
+    if (isNative(element) || isJsInterop(element)) {
+      return true;
+    }
+    assert(element.isResolved);
+    return isNativeOrExtendsNative(element.superclass);
+  }
+
   bool isInterceptedMethod(Element element) {
     if (!element.isInstanceMember) return false;
     if (element.isGenerativeConstructorBody) {
-      return Elements.isNativeOrExtendsNative(element.enclosingClass);
+      return isNativeOrExtendsNative(element.enclosingClass);
     }
     return interceptedElements[element.name] != null;
   }
@@ -851,6 +918,26 @@
     });
   }
 
+  /// True if the given class is an internal class used for type inference
+  /// and never exists at runtime.
+  bool isCompileTimeOnlyClass(ClassElement class_) {
+    return class_ == helpers.jsPositiveIntClass ||
+           class_ == helpers.jsUInt32Class ||
+           class_ == helpers.jsUInt31Class ||
+           class_ == helpers.jsFixedArrayClass ||
+           class_ == helpers.jsUnmodifiableArrayClass ||
+           class_ == helpers.jsMutableArrayClass ||
+           class_ == helpers.jsExtendableArrayClass;
+  }
+
+  /// Maps compile-time classes to their runtime class.  The runtime class is
+  /// always a superclass or the class itself.
+  ClassElement getRuntimeClass(ClassElement class_) {
+    if (class_.isSubclassOf(helpers.jsIntClass)) return helpers.jsIntClass;
+    if (class_.isSubclassOf(helpers.jsArrayClass)) return helpers.jsArrayClass;
+    return class_;
+  }
+
   final Map<String, Set<ClassElement>> interceptedClassesCache =
       new Map<String, Set<ClassElement>>();
 
@@ -867,7 +954,8 @@
       Set<ClassElement> result = new Set<ClassElement>();
       for (Element element in intercepted) {
         ClassElement classElement = element.enclosingClass;
-        if (Elements.isNativeOrExtendsNative(classElement)
+        if (isCompileTimeOnlyClass(classElement)) continue;
+        if (isNativeOrExtendsNative(classElement)
             || interceptedClasses.contains(classElement)) {
           result.add(classElement);
         }
@@ -888,7 +976,7 @@
     for (MixinApplicationElement use in uses) {
       Iterable<ClassElement> subclasses = classWorld.strictSubclassesOf(use);
       for (ClassElement subclass in subclasses) {
-        if (Elements.isNativeOrExtendsNative(subclass)) {
+        if (isNativeOrExtendsNative(subclass)) {
           if (result == null) result = new Set<ClassElement>();
           result.add(subclass);
         }
@@ -906,7 +994,7 @@
       ClassElement interceptorClass) {
     if (interceptorClass == null) return;
     interceptorClass.ensureResolved(resolution);
-    compiler.objectClass.forEachMember((_, Element member) {
+    coreClasses.objectClass.forEachMember((_, Element member) {
       if (member.isGenerativeConstructor) return;
       Element interceptorMember = interceptorClass.lookupMember(member.name);
       // Interceptors must override all Object methods due to calling convention
@@ -928,7 +1016,7 @@
         }
         if (member.isSynthesized) return;
         // All methods on [Object] are shadowed by [Interceptor].
-        if (classElement == compiler.objectClass) return;
+        if (classElement == coreClasses.objectClass) return;
         Set<Element> set = interceptedElements.putIfAbsent(
             member.name, () => new Set<Element>());
         set.add(member);
@@ -949,12 +1037,12 @@
                        Enqueuer enqueuer,
                        Registry registry) {
     if (enqueuer.isResolutionQueue) {
-      _interceptedClasses.add(jsInterceptorClass);
+      _interceptedClasses.add(helpers.jsInterceptorClass);
       _interceptedClasses.add(cls);
       cls.ensureResolved(resolution);
       cls.forEachMember((ClassElement classElement, Element member) {
           // All methods on [Object] are shadowed by [Interceptor].
-          if (classElement == compiler.objectClass) return;
+          if (classElement == coreClasses.objectClass) return;
           Set<Element> set = interceptedElements.putIfAbsent(
               member.name, () => new Set<Element>());
           set.add(member);
@@ -971,7 +1059,7 @@
 
   void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
     jsAst.Name name = namer.nameForGetInterceptor(classes);
-    if (classes.contains(jsInterceptorClass)) {
+    if (classes.contains(helpers.jsInterceptorClass)) {
       // We can't use a specialized [getInterceptorMethod], so we make
       // sure we emit the one with all checks.
       specializedGetInterceptors[name] = interceptedClasses;
@@ -980,8 +1068,7 @@
     }
   }
 
-  void registerCompileTimeConstant(ConstantValue constant, Registry registry,
-      {bool addForEmission: true}) {
+  void registerCompileTimeConstant(ConstantValue constant, Registry registry) {
     registerCompileTimeConstantInternal(constant, registry);
 
     if (!registry.isForResolution &&
@@ -992,11 +1079,12 @@
     }
 
     for (ConstantValue dependency in constant.getDependencies()) {
-      registerCompileTimeConstant(dependency, registry,
-          addForEmission: false);
+      registerCompileTimeConstant(dependency, registry);
     }
+  }
 
-    if (addForEmission) constants.addCompileTimeConstantForEmission(constant);
+  void addCompileTimeConstantForEmission(ConstantValue constant) {
+    constants.addCompileTimeConstantForEmission(constant);
   }
 
   void registerCompileTimeConstantInternal(ConstantValue constant,
@@ -1006,7 +1094,7 @@
 
     if (constant.isFunction) {
       FunctionConstantValue function = constant;
-      registry.registerGetOfStaticFunction(function.element);
+      registry.registerStaticUse(new StaticUse.staticTearOff(function.element));
     } else if (constant.isInterceptor) {
       // An interceptor constant references the class's prototype chain.
       InterceptorConstantValue interceptor = constant;
@@ -1020,17 +1108,24 @@
 
   void registerInstantiatedConstantType(DartType type, Registry registry) {
     DartType instantiatedType =
-        type.isFunctionType ? compiler.functionClass.rawType : type;
+        type.isFunctionType ? coreTypes.functionType : type;
     if (type is InterfaceType) {
       registry.registerInstantiation(instantiatedType);
       if (!type.treatAsRaw && classNeedsRti(type.element)) {
-        registry.registerStaticInvocation(helpers.setRuntimeTypeInfo);
+        registry.registerStaticUse(
+            new StaticUse.staticInvoke(
+                // TODO(johnniwinther): Find the right [CallStructure].
+                helpers.setRuntimeTypeInfo, null));
       }
       if (type.element == typeImplementation) {
         // If we use a type literal in a constant, the compile time
         // constant emitter will generate a call to the createRuntimeType
         // helper so we register a use of that.
-        registry.registerStaticInvocation(helpers.createRuntimeType);
+        registry.registerStaticUse(
+            new StaticUse.staticInvoke(
+                // TODO(johnniwinther): Find the right [CallStructure].
+
+                helpers.createRuntimeType, null));
       }
     }
   }
@@ -1040,7 +1135,7 @@
                                 Registry registry) {
     assert(registry.isForResolution);
     ConstantValue constant = constants.getConstantValueForMetadata(metadata);
-    registerCompileTimeConstant(constant, registry, addForEmission: false);
+    registerCompileTimeConstant(constant, registry);
     metadataConstants.add(new Dependency(constant, annotatedElement));
   }
 
@@ -1066,38 +1161,39 @@
 
     // Register any helper that will be needed by the backend.
     if (enqueuer.isResolutionQueue) {
-      if (cls == compiler.intClass
-          || cls == compiler.doubleClass
-          || cls == compiler.numClass) {
+      if (cls == coreClasses.intClass ||
+          cls == coreClasses.doubleClass ||
+          cls == coreClasses.numClass) {
         // The backend will try to optimize number operations and use the
         // `iae` helper directly.
-        enqueue(enqueuer, findHelper('iae'), registry);
-      } else if (cls == compiler.listClass
-                 || cls == compiler.stringClass) {
+        enqueue(enqueuer, helpers.throwIllegalArgumentException, registry);
+      } else if (cls == coreClasses.listClass ||
+                 cls == coreClasses.stringClass) {
         // The backend will try to optimize array and string access and use the
         // `ioore` and `iae` helpers directly.
-        enqueue(enqueuer, findHelper('ioore'), registry);
-        enqueue(enqueuer, findHelper('iae'), registry);
-      } else if (cls == compiler.functionClass) {
-        enqueueClass(enqueuer, closureClass, registry);
-      } else if (cls == compiler.mapClass) {
+        enqueue(enqueuer, helpers.throwIndexOutOfRangeException, registry);
+        enqueue(enqueuer, helpers.throwIllegalArgumentException, registry);
+      } else if (cls == coreClasses.functionClass) {
+        enqueueClass(enqueuer, helpers.closureClass, registry);
+      } else if (cls == coreClasses.mapClass) {
         // The backend will use a literal list to initialize the entries
         // of the map.
-        enqueueClass(enqueuer, compiler.listClass, registry);
-        enqueueClass(enqueuer, mapLiteralClass, registry);
+        enqueueClass(enqueuer, coreClasses.listClass, registry);
+        enqueueClass(enqueuer, helpers.mapLiteralClass, registry);
         // For map literals, the dependency between the implementation class
         // and [Map] is not visible, so we have to add it manually.
-        rti.registerRtiDependency(mapLiteralClass, cls);
-      } else if (cls == boundClosureClass) {
+        rti.registerRtiDependency(helpers.mapLiteralClass, cls);
+      } else if (cls == helpers.boundClosureClass) {
         // TODO(johnniwinther): Is this a noop?
-        enqueueClass(enqueuer, boundClosureClass, registry);
-      } else if (Elements.isNativeOrExtendsNative(cls)) {
-        enqueue(enqueuer, getNativeInterceptorMethod, registry);
-        enqueueClass(enqueuer, jsInterceptorClass, compiler.globalDependencies);
-        enqueueClass(enqueuer, jsJavaScriptObjectClass, registry);
-        enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry);
-        enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry);
-      } else if (cls == mapLiteralClass) {
+        enqueueClass(enqueuer, helpers.boundClosureClass, registry);
+      } else if (isNativeOrExtendsNative(cls)) {
+        enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry);
+        enqueueClass(enqueuer, helpers.jsInterceptorClass,
+            compiler.globalDependencies);
+        enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry);
+        enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry);
+        enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry);
+      } else if (cls == helpers.mapLiteralClass) {
         // For map literals, the dependency between the implementation class
         // and [Map] is not visible, so we have to add it manually.
         Element getFactory(String name, int arity) {
@@ -1105,13 +1201,14 @@
           // have a patch class.
           ClassElement implementation = cls.patch != null ? cls.patch : cls;
           ConstructorElement ctor = implementation.lookupConstructor(name);
-          if (ctor == null
-              || (Name.isPrivateName(name)
-                  && ctor.library != mapLiteralClass.library)) {
-            reporter.internalError(mapLiteralClass,
-                                   "Map literal class $mapLiteralClass missing "
-                                   "'$name' constructor"
-                                   "  ${mapLiteralClass.constructors}");
+          if (ctor == null ||
+              (Name.isPrivateName(name) &&
+               ctor.library != helpers.mapLiteralClass.library)) {
+            reporter.internalError(
+                helpers.mapLiteralClass,
+                "Map literal class ${helpers.mapLiteralClass} missing "
+                "'$name' constructor"
+                "  ${helpers.mapLiteralClass.constructors}");
           }
           return ctor;
         }
@@ -1121,73 +1218,79 @@
           ClassElement implementation = cls.patch != null ? cls.patch : cls;
           Element element = implementation.lookupLocalMember(name);
           if (element == null || !element.isFunction || !element.isStatic) {
-            reporter.internalError(mapLiteralClass,
-                "Map literal class $mapLiteralClass missing "
+            reporter.internalError(helpers.mapLiteralClass,
+                "Map literal class ${helpers.mapLiteralClass} missing "
                 "'$name' static member function");
           }
           return element;
         }
-        mapLiteralConstructor = getFactory('_literal', 1);
-        mapLiteralConstructorEmpty = getFactory('_empty', 0);
-        enqueueInResolution(mapLiteralConstructor, registry);
-        enqueueInResolution(mapLiteralConstructorEmpty, registry);
+        helpers.mapLiteralConstructor = getFactory('_literal', 1);
+        helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0);
+        enqueueInResolution(helpers.mapLiteralConstructor, registry);
+        enqueueInResolution(helpers.mapLiteralConstructorEmpty, registry);
 
-        mapLiteralUntypedMaker = getMember('_makeLiteral');
-        mapLiteralUntypedEmptyMaker = getMember('_makeEmpty');
-        enqueueInResolution(mapLiteralUntypedMaker, registry);
-        enqueueInResolution(mapLiteralUntypedEmptyMaker, registry);
+        helpers.mapLiteralUntypedMaker = getMember('_makeLiteral');
+        helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty');
+        enqueueInResolution(helpers.mapLiteralUntypedMaker, registry);
+        enqueueInResolution(helpers.mapLiteralUntypedEmptyMaker, registry);
       }
     }
-    if (cls == closureClass) {
-      enqueue(enqueuer, findHelper('closureFromTearOff'), registry);
+    if (cls == helpers.closureClass) {
+      enqueue(enqueuer, helpers.closureFromTearOff, registry);
     }
-    if (cls == compiler.stringClass || cls == jsStringClass) {
-      addInterceptors(jsStringClass, enqueuer, registry);
-    } else if (cls == compiler.listClass ||
-               cls == jsArrayClass ||
-               cls == jsFixedArrayClass ||
-               cls == jsExtendableArrayClass ||
-               cls == jsUnmodifiableArrayClass) {
-      addInterceptors(jsArrayClass, enqueuer, registry);
-      addInterceptors(jsMutableArrayClass, enqueuer, registry);
-      addInterceptors(jsFixedArrayClass, enqueuer, registry);
-      addInterceptors(jsExtendableArrayClass, enqueuer, registry);
-      addInterceptors(jsUnmodifiableArrayClass, enqueuer, registry);
-    } else if (cls == compiler.intClass || cls == jsIntClass) {
-      addInterceptors(jsIntClass, enqueuer, registry);
-      addInterceptors(jsPositiveIntClass, enqueuer, registry);
-      addInterceptors(jsUInt32Class, enqueuer, registry);
-      addInterceptors(jsUInt31Class, enqueuer, registry);
-      addInterceptors(jsNumberClass, enqueuer, registry);
-    } else if (cls == compiler.doubleClass || cls == jsDoubleClass) {
-      addInterceptors(jsDoubleClass, enqueuer, registry);
-      addInterceptors(jsNumberClass, enqueuer, registry);
-    } else if (cls == compiler.boolClass || cls == jsBoolClass) {
-      addInterceptors(jsBoolClass, enqueuer, registry);
-    } else if (cls == compiler.nullClass || cls == jsNullClass) {
-      addInterceptors(jsNullClass, enqueuer, registry);
-    } else if (cls == compiler.numClass || cls == jsNumberClass) {
-      addInterceptors(jsIntClass, enqueuer, registry);
-      addInterceptors(jsPositiveIntClass, enqueuer, registry);
-      addInterceptors(jsUInt32Class, enqueuer, registry);
-      addInterceptors(jsUInt31Class, enqueuer, registry);
-      addInterceptors(jsDoubleClass, enqueuer, registry);
-      addInterceptors(jsNumberClass, enqueuer, registry);
-    } else if (cls == jsJavaScriptObjectClass) {
-      addInterceptors(jsJavaScriptObjectClass, enqueuer, registry);
-    } else if (cls == jsPlainJavaScriptObjectClass) {
-      addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, registry);
-    } else if (cls == jsUnknownJavaScriptObjectClass) {
-      addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, registry);
-    } else if (cls == jsJavaScriptFunctionClass) {
-      addInterceptors(jsJavaScriptFunctionClass, enqueuer, registry);
-    } else if (Elements.isNativeOrExtendsNative(cls)) {
+    if (cls == coreClasses.stringClass ||
+        cls == helpers.jsStringClass) {
+      addInterceptors(helpers.jsStringClass, enqueuer, registry);
+    } else if (cls == coreClasses.listClass ||
+               cls == helpers.jsArrayClass ||
+               cls == helpers.jsFixedArrayClass ||
+               cls == helpers.jsExtendableArrayClass ||
+               cls == helpers.jsUnmodifiableArrayClass) {
+      addInterceptors(helpers.jsArrayClass, enqueuer, registry);
+      addInterceptors(helpers.jsMutableArrayClass, enqueuer, registry);
+      addInterceptors(helpers.jsFixedArrayClass, enqueuer, registry);
+      addInterceptors(helpers.jsExtendableArrayClass, enqueuer, registry);
+      addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer, registry);
+    } else if (cls == coreClasses.intClass ||
+               cls == helpers.jsIntClass) {
+      addInterceptors(helpers.jsIntClass, enqueuer, registry);
+      addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry);
+      addInterceptors(helpers.jsUInt32Class, enqueuer, registry);
+      addInterceptors(helpers.jsUInt31Class, enqueuer, registry);
+      addInterceptors(helpers.jsNumberClass, enqueuer, registry);
+    } else if (cls == coreClasses.doubleClass ||
+               cls == helpers.jsDoubleClass) {
+      addInterceptors(helpers.jsDoubleClass, enqueuer, registry);
+      addInterceptors(helpers.jsNumberClass, enqueuer, registry);
+    } else if (cls == coreClasses.boolClass ||
+               cls == helpers.jsBoolClass) {
+      addInterceptors(helpers.jsBoolClass, enqueuer, registry);
+    } else if (cls == coreClasses.nullClass ||
+               cls == helpers.jsNullClass) {
+      addInterceptors(helpers.jsNullClass, enqueuer, registry);
+    } else if (cls == coreClasses.numClass ||
+               cls == helpers.jsNumberClass) {
+      addInterceptors(helpers.jsIntClass, enqueuer, registry);
+      addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry);
+      addInterceptors(helpers.jsUInt32Class, enqueuer, registry);
+      addInterceptors(helpers.jsUInt31Class, enqueuer, registry);
+      addInterceptors(helpers.jsDoubleClass, enqueuer, registry);
+      addInterceptors(helpers.jsNumberClass, enqueuer, registry);
+    } else if (cls == helpers.jsJavaScriptObjectClass) {
+      addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer, registry);
+    } else if (cls == helpers.jsPlainJavaScriptObjectClass) {
+      addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer, registry);
+    } else if (cls == helpers.jsUnknownJavaScriptObjectClass) {
+      addInterceptors(helpers.jsUnknownJavaScriptObjectClass, enqueuer, registry);
+    } else if (cls == helpers.jsJavaScriptFunctionClass) {
+      addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer, registry);
+    } else if (isNativeOrExtendsNative(cls)) {
       addInterceptorsForNativeClassMembers(cls, enqueuer);
-    } else if (cls == jsIndexingBehaviorInterface) {
+    } else if (cls == helpers.jsIndexingBehaviorInterface) {
       // These two helpers are used by the emitter and the codegen.
       // Because we cannot enqueue elements at the time of emission,
       // we make sure they are always generated.
-      enqueue(enqueuer, findHelper('isJsIndexable'), registry);
+      enqueue(enqueuer, helpers.isJsIndexable, registry);
     }
 
     customElementsAnalysis.registerInstantiatedClass(cls, enqueuer);
@@ -1209,10 +1312,10 @@
     assert(!enqueuer.isResolutionQueue);
     if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return;
     Registry registry = compiler.globalDependencies;
-    enqueue(enqueuer, getNativeInterceptorMethod, registry);
-    enqueueClass(enqueuer, jsJavaScriptObjectClass, registry);
-    enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry);
-    enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry);
+    enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry);
+    enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry);
+    enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry);
+    enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry);
     needToInitializeIsolateAffinityTag = true;
     needToInitializeDispatchProperty = true;
   }
@@ -1222,27 +1325,27 @@
   }
 
   void enqueueHelpers(ResolutionEnqueuer world, Registry registry) {
-    assert(interceptorsLibrary != null);
+    assert(helpers.interceptorsLibrary != null);
     // TODO(ngeoffray): Not enqueuing those two classes currently make
     // the compiler potentially crash. However, any reasonable program
     // will instantiate those two classes.
-    addInterceptors(jsBoolClass, world, registry);
-    addInterceptors(jsNullClass, world, registry);
+    addInterceptors(helpers.jsBoolClass, world, registry);
+    addInterceptors(helpers.jsNullClass, world, registry);
     if (compiler.enableTypeAssertions) {
       // Unconditionally register the helper that checks if the
       // expression in an if/while/for is a boolean.
       // TODO(ngeoffray): Should we have the resolver register those instead?
-      Element e = findHelper('boolConversionCheck');
+      Element e = helpers.boolConversionCheck;
       if (e != null) enqueue(world, e, registry);
     }
 
     if (TRACE_CALLS) {
-      traceHelper = findHelper(
-          TRACE_METHOD == 'console' ? 'consoleTraceHelper' : 'postTraceHelper');
+      traceHelper = TRACE_METHOD == 'console'
+          ? helpers.consoleTraceHelper : helpers.postTraceHelper;
       assert(traceHelper != null);
       enqueueInResolution(traceHelper, registry);
     }
-    enqueueInResolution(assertUnreachableMethod, registry);
+    enqueueInResolution(helpers.assertUnreachableMethod, registry);
     registerCheckedModeHelpers(registry);
   }
 
@@ -1283,27 +1386,19 @@
     super.registerClosureWithFreeTypeVariables(closure, enqueuer, registry);
   }
 
-  /// Call during codegen if an instance of [closure] is being created.
-  void registerInstantiatedClosure(LocalFunctionElement closure,
-                                   CodegenRegistry registry) {
-    if (methodNeedsRti(closure)) {
-      registerComputeSignature(compiler.enqueuer.codegen, registry);
-    }
-  }
-
   void registerBoundClosure(Enqueuer enqueuer) {
-    boundClosureClass.ensureResolved(resolution);
+    helpers.boundClosureClass.ensureResolved(resolution);
     registerInstantiatedType(
-        boundClosureClass.rawType,
+        helpers.boundClosureClass.rawType,
         enqueuer,
         // Precise dependency is not important here.
         compiler.globalDependencies);
   }
 
   void registerGetOfStaticFunction(Enqueuer enqueuer) {
-    closureClass.ensureResolved(resolution);
+    helpers.closureClass.ensureResolved(resolution);
     registerInstantiatedType(
-        closureClass.rawType,
+        helpers.closureClass.rawType,
         enqueuer,
         compiler.globalDependencies);
   }
@@ -1320,42 +1415,7 @@
     enqueueInResolution(helpers.setRuntimeTypeInfo, registry);
     registerGetRuntimeTypeArgument(registry);
     enqueueInResolution(helpers.getRuntimeTypeInfo, registry);
-    enqueueClass(enqueuer, compiler.listClass, registry);
-  }
-
-  void registerIsCheckForCodegen(DartType type,
-                                 Enqueuer world,
-                                 Registry registry) {
-    assert(!registry.isForResolution);
-    type = type.unaliased;
-    enqueueClass(world, compiler.boolClass, registry);
-    bool inCheckedMode = compiler.enableTypeAssertions;
-    // [registerIsCheck] is also called for checked mode checks, so we
-    // need to register checked mode helpers.
-    if (inCheckedMode) {
-      // All helpers are added to resolution queue in enqueueHelpers. These
-      // calls to enqueueInResolution serve as assertions that the helper was
-      // in fact added.
-      // TODO(13155): Find a way to enqueue helpers lazily.
-      CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false);
-      if (helper != null) {
-        enqueue(world, helper.getElement(compiler), registry);
-      }
-      // We also need the native variant of the check (for DOM types).
-      helper = getNativeCheckedModeHelper(type, typeCast: false);
-      if (helper != null) {
-        enqueue(world, helper.getElement(compiler), registry);
-      }
-    }
-    if (!type.treatAsRaw || type.containsTypeVariables) {
-      enqueueClass(world, compiler.listClass, registry);
-    }
-    if (type.element != null && type.element.isNative) {
-      // We will neeed to add the "$is" and "$as" properties on the
-      // JavaScript object prototype, so we make sure
-      // [:defineProperty:] is compiled.
-      enqueue(world, findHelper('defineProperty'), registry);
-    }
+    enqueueClass(enqueuer, coreClasses.listClass, registry);
   }
 
   void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument,
@@ -1366,7 +1426,8 @@
   void registerCheckDeferredIsLoaded(Registry registry) {
     enqueueInResolution(helpers.checkDeferredIsLoaded, registry);
     // Also register the types of the arguments passed to this method.
-    enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, registry);
+    enqueueClass(
+        compiler.enqueuer.resolution, coreClasses.stringClass, registry);
   }
 
   void registerNoSuchMethod(FunctionElement noSuchMethod) {
@@ -1409,8 +1470,8 @@
 
   void enableNoSuchMethod(Enqueuer world) {
     enqueue(world, helpers.createInvocationMirror, compiler.globalDependencies);
-    world.registerInvocation(
-        new UniverseSelector(Selectors.noSuchMethod_, null));
+    world.registerDynamicUse(
+        new DynamicUse(Selectors.noSuchMethod_, null));
   }
 
   void enableIsolateSupport(Enqueuer enqueuer) {
@@ -1424,31 +1485,22 @@
       // The JavaScript backend of [Isolate.spawnUri] uses the same internal
       // implementation as [Isolate.spawn], and fails if it cannot look main up
       // by name.
-      enqueuer.registerGetOfStaticFunction(compiler.mainFunction);
+      enqueuer.registerStaticUse(
+          new StaticUse.staticTearOff(compiler.mainFunction));
     }
     if (enqueuer.isResolutionQueue) {
-      for (String name in const [START_ROOT_ISOLATE,
-                                 '_currentIsolate',
-                                 '_callInIsolate']) {
-        Element element = find(isolateHelperLibrary, name);
+
+      void enqueue(Element element) {
         enqueuer.addToWorkList(element);
         compiler.globalDependencies.registerDependency(element);
         helpersUsed.add(element.declaration);
       }
-    } else {
-      enqueuer.addToWorkList(find(isolateHelperLibrary, START_ROOT_ISOLATE));
-    }
-  }
 
-  void registerRequiredType(DartType type) {
-    // If [argument] has type variables or is a type variable, this method
-    // registers a RTI dependency between the class where the type variable is
-    // defined (that is the enclosing class of the current element being
-    // resolved) and the class of [type]. If the class of [type] requires RTI,
-    // then the class of the type variable does too.
-    ClassElement contextClass = Types.getClassContext(type);
-    if (contextClass != null) {
-      rti.registerRtiDependency(type.element, contextClass);
+      enqueue(helpers.startRootIsolate);
+      enqueue(helpers.currentIsolate);
+      enqueue(helpers.callInIsolate);
+    } else {
+      enqueuer.addToWorkList(helpers.startRootIsolate);
     }
   }
 
@@ -1463,9 +1515,9 @@
   bool isDefaultEqualityImplementation(Element element) {
     assert(element.name == '==');
     ClassElement classElement = element.enclosingClass;
-    return classElement == compiler.objectClass
-        || classElement == jsInterceptorClass
-        || classElement == jsNullClass;
+    return classElement == coreClasses.objectClass
+        || classElement == helpers.jsInterceptorClass
+        || classElement == helpers.jsNullClass;
   }
 
   bool methodNeedsRti(FunctionElement function) {
@@ -1473,23 +1525,6 @@
            compiler.enabledRuntimeType;
   }
 
-  /// The backend must *always* call this method when enqueuing an
-  /// element. Calls done by the backend are not seen by global
-  /// optimizations, so they would make these optimizations unsound.
-  /// Therefore we need to collect the list of helpers the backend may
-  /// use.
-  Element registerBackendUse(Element element) {
-    if (element != null) {
-      helpersUsed.add(element.declaration);
-      if (element.isClass && element.isPatched) {
-        // Both declaration and implementation may declare fields, so we
-        // add both to the list of helpers.
-        helpersUsed.add(element.implementation);
-      }
-    }
-    return element;
-  }
-
   /// Enqueue [e] in [enqueuer].
   ///
   /// This method calls [registerBackendUse].
@@ -1560,26 +1595,29 @@
     if (compiler.elementHasCompileTimeError(element)) {
       generatedCode[element] = jsAst.js(
           "function () { throw new Error('Compile time error in $element') }");
-      return const WorldImpact();
+      return const CodegenImpact();
     }
     var kind = element.kind;
     if (kind == ElementKind.TYPEDEF) {
       return const WorldImpact();
     }
-    if (element.isConstructor && element.enclosingClass == jsNullClass) {
+    if (element.isConstructor &&
+        element.enclosingClass == helpers.jsNullClass) {
       // Work around a problem compiling JSNull's constructor.
-      return const WorldImpact();
+      return const CodegenImpact();
     }
     if (kind.category == ElementCategory.VARIABLE) {
       ConstantValue initialValue =
           constants.getConstantValueForVariable(element);
       if (initialValue != null) {
         registerCompileTimeConstant(initialValue, work.registry);
+        addCompileTimeConstantForEmission(initialValue);
         // We don't need to generate code for static or top-level
         // variables. For instance variables, we may need to generate
         // the checked setter.
         if (Elements.isStaticOrTopLevel(element)) {
-          return const WorldImpact();
+          return impactTransformer.transformCodegenImpact(
+              work.registry.worldImpact);
         }
       } else {
         // If the constant-handler was not able to produce a result we have to
@@ -1587,12 +1625,16 @@
         // the static variable.
         // We also need to register the use of the cyclic-error helper.
         compiler.enqueuer.codegen.registerStaticUse(
-            helpers.cyclicThrowHelper);
+            new StaticUse.staticInvoke(
+                helpers.cyclicThrowHelper, CallStructure.ONE_ARG));
       }
     }
 
     generatedCode[element] = functionCompiler.compile(work);
-    return const WorldImpact();
+    WorldImpact worldImpact =
+        impactTransformer.transformCodegenImpact(work.registry.worldImpact);
+    compiler.dumpInfoTask.registerImpact(element, worldImpact);
+    return worldImpact;
   }
 
   native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) {
@@ -1604,9 +1646,12 @@
   }
 
   ClassElement defaultSuperclass(ClassElement element) {
-    if (element.isJsInterop) return jsJavaScriptObjectClass;
+    if (isJsInterop(element)) {
+      return helpers.jsJavaScriptObjectClass;
+    }
     // Native classes inherit from Interceptor.
-    return element.isNative ? jsInterceptorClass : compiler.objectClass;
+    return isNative(element)
+        ? helpers.jsInterceptorClass : coreClasses.objectClass;
   }
 
   /**
@@ -1719,29 +1764,35 @@
       assert(!typeCast); // Cannot cast to void.
       if (nativeCheckOnly) return null;
       return 'voidTypeCheck';
-    } else if (element == jsStringClass || element == compiler.stringClass) {
+    } else if (element == helpers.jsStringClass ||
+               element == coreClasses.stringClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'stringTypeCast'
           : 'stringTypeCheck';
-    } else if (element == jsDoubleClass || element == compiler.doubleClass) {
+    } else if (element == helpers.jsDoubleClass ||
+               element == coreClasses.doubleClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'doubleTypeCast'
           : 'doubleTypeCheck';
-    } else if (element == jsNumberClass || element == compiler.numClass) {
+    } else if (element == helpers.jsNumberClass ||
+               element == coreClasses.numClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'numTypeCast'
           : 'numTypeCheck';
-    } else if (element == jsBoolClass || element == compiler.boolClass) {
+    } else if (element == helpers.jsBoolClass ||
+               element == coreClasses.boolClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'boolTypeCast'
           : 'boolTypeCheck';
-    } else if (element == jsIntClass || element == compiler.intClass
-               || element == jsUInt32Class || element == jsUInt31Class
-               || element == jsPositiveIntClass) {
+    } else if (element == helpers.jsIntClass ||
+               element == coreClasses.intClass ||
+               element == helpers.jsUInt32Class ||
+               element == helpers.jsUInt31Class ||
+               element == helpers.jsPositiveIntClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'intTypeCast'
@@ -1766,7 +1817,8 @@
             ? 'stringSuperTypeCast'
             : 'stringSuperTypeCheck';
       }
-    } else if ((element == compiler.listClass || element == jsArrayClass) &&
+    } else if ((element == coreClasses.listClass ||
+                element == helpers.jsArrayClass) &&
                type.treatAsRaw) {
       if (nativeCheckOnly) return null;
       return typeCast
@@ -1815,7 +1867,7 @@
     // We register all the helpers in the resolution queue.
     // TODO(13155): Find a way to register fewer helpers.
     for (CheckedModeHelper helper in checkedModeHelpers) {
-      enqueueInResolution(helper.getElement(compiler), registry);
+      enqueueInResolution(helper.getStaticUse(compiler).element, registry);
     }
   }
 
@@ -1825,16 +1877,16 @@
    */
   bool hasDirectCheckFor(DartType type) {
     Element element = type.element;
-    return element == compiler.stringClass ||
-        element == compiler.boolClass ||
-        element == compiler.numClass ||
-        element == compiler.intClass ||
-        element == compiler.doubleClass ||
-        element == jsArrayClass ||
-        element == jsMutableArrayClass ||
-        element == jsExtendableArrayClass ||
-        element == jsFixedArrayClass ||
-        element == jsUnmodifiableArrayClass;
+    return element == coreClasses.stringClass ||
+        element == coreClasses.boolClass ||
+        element == coreClasses.numClass ||
+        element == coreClasses.intClass ||
+        element == coreClasses.doubleClass ||
+        element == helpers.jsArrayClass ||
+        element == helpers.jsMutableArrayClass ||
+        element == helpers.jsExtendableArrayClass ||
+        element == helpers.jsFixedArrayClass ||
+        element == helpers.jsUnmodifiableArrayClass;
   }
 
   bool mayGenerateInstanceofCheck(DartType type) {
@@ -1848,49 +1900,51 @@
   }
 
   bool isNullImplementation(ClassElement cls) {
-    return cls == jsNullClass;
+    return cls == helpers.jsNullClass;
   }
 
-  ClassElement get intImplementation => jsIntClass;
-  ClassElement get uint32Implementation => jsUInt32Class;
-  ClassElement get uint31Implementation => jsUInt31Class;
-  ClassElement get positiveIntImplementation => jsPositiveIntClass;
-  ClassElement get doubleImplementation => jsDoubleClass;
-  ClassElement get numImplementation => jsNumberClass;
-  ClassElement get stringImplementation => jsStringClass;
-  ClassElement get listImplementation => jsArrayClass;
-  ClassElement get constListImplementation => jsUnmodifiableArrayClass;
-  ClassElement get fixedListImplementation => jsFixedArrayClass;
-  ClassElement get growableListImplementation => jsExtendableArrayClass;
-  ClassElement get mapImplementation => mapLiteralClass;
-  ClassElement get constMapImplementation => constMapLiteralClass;
-  ClassElement get typeImplementation => typeLiteralClass;
-  ClassElement get boolImplementation => jsBoolClass;
-  ClassElement get nullImplementation => jsNullClass;
+  ClassElement get intImplementation => helpers.jsIntClass;
+  ClassElement get uint32Implementation => helpers.jsUInt32Class;
+  ClassElement get uint31Implementation => helpers.jsUInt31Class;
+  ClassElement get positiveIntImplementation => helpers.jsPositiveIntClass;
+  ClassElement get doubleImplementation => helpers.jsDoubleClass;
+  ClassElement get numImplementation => helpers.jsNumberClass;
+  ClassElement get stringImplementation => helpers.jsStringClass;
+  ClassElement get listImplementation => helpers.jsArrayClass;
+  ClassElement get constListImplementation => helpers.jsUnmodifiableArrayClass;
+  ClassElement get fixedListImplementation => helpers.jsFixedArrayClass;
+  ClassElement get growableListImplementation => helpers.jsExtendableArrayClass;
+  ClassElement get mapImplementation => helpers.mapLiteralClass;
+  ClassElement get constMapImplementation => helpers.constMapLiteralClass;
+  ClassElement get typeImplementation => helpers.typeLiteralClass;
+  ClassElement get boolImplementation => helpers.jsBoolClass;
+  ClassElement get nullImplementation => helpers.jsNullClass;
+  ClassElement get syncStarIterableImplementation => helpers.syncStarIterable;
+  ClassElement get asyncFutureImplementation => helpers.futureImplementation;
+  ClassElement get asyncStarStreamImplementation => helpers.controllerStream;
 
   void registerStaticUse(Element element, Enqueuer enqueuer) {
-    if (element == disableTreeShakingMarker) {
+    if (element == helpers.disableTreeShakingMarker) {
       compiler.disableTypeInferenceForMirrors = true;
       isTreeShakingDisabled = true;
-    } else if (element == preserveNamesMarker) {
+    } else if (element == helpers.preserveNamesMarker) {
       mustPreserveNames = true;
-    } else if (element == preserveMetadataMarker) {
+    } else if (element == helpers.preserveMetadataMarker) {
       mustRetainMetadata = true;
-    } else if (element == preserveUrisMarker) {
+    } else if (element == helpers.preserveUrisMarker) {
       if (compiler.preserveUris) mustPreserveUris = true;
-    } else if (element == preserveLibraryNamesMarker) {
+    } else if (element == helpers.preserveLibraryNamesMarker) {
       mustRetainLibraryNames = true;
-    } else if (element == getIsolateAffinityTagMarker) {
+    } else if (element == helpers.getIsolateAffinityTagMarker) {
       needToInitializeIsolateAffinityTag = true;
     } else if (element.isDeferredLoaderGetter) {
       // TODO(sigurdm): Create a function registerLoadLibraryAccess.
       if (compiler.loadLibraryFunction == null) {
-        compiler.loadLibraryFunction =
-            findHelper("_loadLibraryWrapper");
+        compiler.loadLibraryFunction = helpers.loadLibraryWrapper;
         enqueueInResolution(compiler.loadLibraryFunction,
                             compiler.globalDependencies);
       }
-    } else if (element == requiresPreambleMarker) {
+    } else if (element == helpers.requiresPreambleMarker) {
       requiresPreamble = true;
     }
     customElementsAnalysis.registerStaticUse(element, enqueuer);
@@ -1942,39 +1996,7 @@
   }
 
   void onLibraryCreated(LibraryElement library) {
-    Uri uri = library.canonicalUri;
-    if (uri == DART_JS_HELPER) {
-      jsHelperLibrary = library;
-    } else if (uri == Uris.dart_async) {
-      asyncLibrary = library;
-    } else if (uri == Uris.dart__internal) {
-      internalLibrary = library;
-    } else if (uri ==  DART_INTERCEPTORS) {
-      interceptorsLibrary = library;
-    } else if (uri ==  DART_FOREIGN_HELPER) {
-      foreignLibrary = library;
-    } else if (uri == DART_ISOLATE_HELPER) {
-      isolateHelperLibrary = library;
-    }
-  }
-
-  void initializeHelperClasses() {
-    final List missingHelperClasses = [];
-    ClassElement lookupHelperClass(String name) {
-      ClassElement result = findHelper(name);
-      if (result == null) {
-        missingHelperClasses.add(name);
-      }
-      return result;
-    }
-    jsInvocationMirrorClass = lookupHelperClass('JSInvocationMirror');
-    boundClosureClass = lookupHelperClass('BoundClosure');
-    closureClass = lookupHelperClass('Closure');
-    if (!missingHelperClasses.isEmpty) {
-      reporter.internalError(jsHelperLibrary,
-          'dart:_js_helper library does not contain required classes: '
-          '$missingHelperClasses');
-    }
+    helpers.onLibraryCreated(library);
   }
 
   Future onLibraryScanned(LibraryElement library, LibraryLoader loader) {
@@ -1990,84 +2012,12 @@
         }
       }
     }).then((_) {
+      helpers.onLibraryScanned(library);
       Uri uri = library.canonicalUri;
-
-      FunctionElement findMethod(String name) {
-        return find(library, name);
-      }
-
-      ClassElement findClass(String name) {
-        return find(library, name);
-      }
-
-      if (uri == DART_INTERCEPTORS) {
-        getInterceptorMethod = findMethod('getInterceptor');
-        getNativeInterceptorMethod = findMethod('getNativeInterceptor');
-        jsInterceptorClass = findClass('Interceptor');
-        jsStringClass = findClass('JSString');
-        jsArrayClass = findClass('JSArray');
-        // The int class must be before the double class, because the
-        // emitter relies on this list for the order of type checks.
-        jsIntClass = findClass('JSInt');
-        jsPositiveIntClass = findClass('JSPositiveInt');
-        jsUInt32Class = findClass('JSUInt32');
-        jsUInt31Class = findClass('JSUInt31');
-        jsDoubleClass = findClass('JSDouble');
-        jsNumberClass = findClass('JSNumber');
-        jsNullClass = findClass('JSNull');
-        jsBoolClass = findClass('JSBool');
-        jsMutableArrayClass = findClass('JSMutableArray');
-        jsFixedArrayClass = findClass('JSFixedArray');
-        jsExtendableArrayClass = findClass('JSExtendableArray');
-        jsUnmodifiableArrayClass = findClass('JSUnmodifiableArray');
-        jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject');
-        jsJavaScriptObjectClass = findClass('JavaScriptObject');
-        jsJavaScriptFunctionClass = findClass('JavaScriptFunction');
-        jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject');
-        jsIndexableClass = findClass('JSIndexable');
-        jsMutableIndexableClass = findClass('JSMutableIndexable');
-      } else if (uri == DART_JS_HELPER) {
-        initializeHelperClasses();
-        helpers.assertTest = findHelper('assertTest');
-        helpers.assertThrow = findHelper('assertThrow');
-        helpers.assertHelper = findHelper('assertHelper');
-        assertUnreachableMethod = findHelper('assertUnreachable');
-
-        typeLiteralClass = findClass('TypeImpl');
-        constMapLiteralClass = findClass('ConstantMap');
-        typeVariableClass = findClass('TypeVariable');
-
-        jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior');
-
-        noSideEffectsClass = findClass('NoSideEffects');
-        noThrowsClass = findClass('NoThrows');
-        noInlineClass = findClass('NoInline');
-        forceInlineClass = findClass('ForceInline');
-        irRepresentationClass = findClass('IrRepresentation');
-
-        getIsolateAffinityTagMarker = findMethod('getIsolateAffinityTag');
-
-        requiresPreambleMarker = findMethod('requiresPreamble');
-      } else if (uri == DART_JS_MIRRORS) {
-        disableTreeShakingMarker = find(library, 'disableTreeShaking');
-        preserveMetadataMarker = find(library, 'preserveMetadata');
-        preserveUrisMarker = find(library, 'preserveUris');
-        preserveLibraryNamesMarker = find(library, 'preserveLibraryNames');
-      } else if (uri == DART_JS_NAMES) {
-        preserveNamesMarker = find(library, 'preserveNames');
-      } else if (uri == DART_EMBEDDED_NAMES) {
-        jsGetNameEnum = find(library, 'JsGetName');
-        jsBuiltinEnum = find(library, 'JsBuiltin');
-      } else if (uri == Uris.dart_html) {
+      if (uri == Uris.dart_html) {
         htmlLibraryIsLoaded = true;
-      } else if (uri == PACKAGE_LOOKUP_MAP) {
+      } else if (uri == LookupMapAnalysis.PACKAGE_LOOKUP_MAP) {
         lookupMapAnalysis.init(library);
-      } else if (uri == Uris.dart__native_typed_data) {
-        typedArrayClass = findClass('NativeTypedArray');
-        typedArrayOfIntClass = findClass('NativeTypedArrayOfInt');
-      } else if (uri == PACKAGE_JS) {
-        jsAnnotationClass = find(library, 'JS');
-        jsAnonymousClass = find(library, '_Anonymous');
       }
       annotations.onLibraryScanned(library);
     });
@@ -2078,74 +2028,29 @@
       return new Future.value();
     }
 
-    assert(loadedLibraries.containsLibrary(Uris.dart_core));
-    assert(loadedLibraries.containsLibrary(DART_INTERCEPTORS));
-    assert(loadedLibraries.containsLibrary(DART_JS_HELPER));
-
-    if (jsInvocationMirrorClass != null) {
-      jsInvocationMirrorClass.ensureResolved(resolution);
-      invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON);
-    }
-
-    // [LinkedHashMap] is reexported from dart:collection and can therefore not
-    // be loaded from dart:core in [onLibraryScanned].
-    mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap');
-    assert(invariant(compiler.coreLibrary, mapLiteralClass != null,
-        message: "Element 'LinkedHashMap' not found in 'dart:core'."));
+    helpers.onLibrariesLoaded(loadedLibraries);
 
     implementationClasses = <ClassElement, ClassElement>{};
-    implementationClasses[compiler.intClass] = jsIntClass;
-    implementationClasses[compiler.boolClass] = jsBoolClass;
-    implementationClasses[compiler.numClass] = jsNumberClass;
-    implementationClasses[compiler.doubleClass] = jsDoubleClass;
-    implementationClasses[compiler.stringClass] = jsStringClass;
-    implementationClasses[compiler.listClass] = jsArrayClass;
-    implementationClasses[compiler.nullClass] = jsNullClass;
+    implementationClasses[coreClasses.intClass] = helpers.jsIntClass;
+    implementationClasses[coreClasses.boolClass] = helpers.jsBoolClass;
+    implementationClasses[coreClasses.numClass] = helpers.jsNumberClass;
+    implementationClasses[coreClasses.doubleClass] = helpers.jsDoubleClass;
+    implementationClasses[coreClasses.stringClass] = helpers.jsStringClass;
+    implementationClasses[coreClasses.listClass] = helpers.jsArrayClass;
+    implementationClasses[coreClasses.nullClass] = helpers.jsNullClass;
 
     // These methods are overwritten with generated versions.
-    inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true);
-
-    // TODO(kasperl): Some tests do not define the special JSArray
-    // subclasses, so we check to see if they are defined before
-    // trying to resolve them.
-    if (jsFixedArrayClass != null) {
-      jsFixedArrayClass.ensureResolved(resolution);
-    }
-    if (jsExtendableArrayClass != null) {
-      jsExtendableArrayClass.ensureResolved(resolution);
-    }
-    if (jsUnmodifiableArrayClass != null) {
-      jsUnmodifiableArrayClass.ensureResolved(resolution);
-    }
-
-    jsIndexableClass.ensureResolved(resolution);
-    jsIndexableLength = compiler.lookupElementIn(
-        jsIndexableClass, 'length');
-    if (jsIndexableLength != null && jsIndexableLength.isAbstractField) {
-      AbstractFieldElement element = jsIndexableLength;
-      jsIndexableLength = element.getter;
-    }
-
-    jsArrayClass.ensureResolved(resolution);
-    jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed');
-    jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast');
-    jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add');
-
-    jsStringClass.ensureResolved(resolution);
-    jsStringSplit = compiler.lookupElementIn(jsStringClass, 'split');
-    jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+');
-    jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString');
-
-    objectEquals = compiler.lookupElementIn(compiler.objectClass, '==');
+    inlineCache.markAsNonInlinable(
+        helpers.getInterceptorMethod, insideLoop: true);
 
     specialOperatorEqClasses
-        ..add(compiler.objectClass)
-        ..add(jsInterceptorClass)
-        ..add(jsNullClass);
+        ..add(coreClasses.objectClass)
+        ..add(helpers.jsInterceptorClass)
+        ..add(helpers.jsNullClass);
 
-    validateInterceptorImplementsAllObjectMethods(jsInterceptorClass);
+    validateInterceptorImplementsAllObjectMethods(helpers.jsInterceptorClass);
     // The null-interceptor must also implement *all* methods.
-    validateInterceptorImplementsAllObjectMethods(jsNullClass);
+    validateInterceptorImplementsAllObjectMethods(helpers.jsNullClass);
 
     return new Future.value();
   }
@@ -2358,11 +2263,11 @@
     // As we do not think about closures as classes, yet, we have to make sure
     // their superclasses are available for reflection manually.
     if (foundClosure) {
-      reflectableMembers.add(closureClass);
+      reflectableMembers.add(helpers.closureClass);
     }
     Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers;
     if (closurizedMembers.any(reflectableMembers.contains)) {
-      reflectableMembers.add(boundClosureClass);
+      reflectableMembers.add(helpers.boundClosureClass);
     }
     // Add typedefs.
     reflectableMembers
@@ -2398,7 +2303,7 @@
         new jsAst.PropertyAccess(use2, dispatchProperty);
 
     List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record];
-    FunctionElement helper = findHelper('isJsIndexable');
+    FunctionElement helper = helpers.isJsIndexable;
     jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper);
     return new jsAst.Call(helperExpression, arguments);
   }
@@ -2411,7 +2316,7 @@
         compiler.typedDataClass != null &&
         compiler.world.isInstantiated(compiler.typedDataClass) &&
         mask.satisfies(compiler.typedDataClass, compiler.world) &&
-        mask.satisfies(jsIndexingBehaviorInterface, compiler.world);
+        mask.satisfies(helpers.jsIndexingBehaviorInterface, compiler.world);
   }
 
   bool couldBeTypedArray(TypeMask mask) {
@@ -2425,7 +2330,7 @@
         intersects(mask,
             new TypeMask.subtype(compiler.typedDataClass, compiler.world)) &&
         intersects(mask,
-            new TypeMask.subtype(jsIndexingBehaviorInterface, compiler.world));
+            new TypeMask.subtype(helpers.jsIndexingBehaviorInterface, compiler.world));
   }
 
   /// Returns all static fields that are referenced through [targetsUsed].
@@ -2472,7 +2377,7 @@
 
     if (compiler.hasIncrementalSupport) {
       // Always enable tear-off closures during incremental compilation.
-      Element e = findHelper('closureFromTearOff');
+      Element e = helpers.closureFromTearOff;
       if (e != null && !enqueuer.isProcessed(e)) {
         registerBackendUse(e);
         enqueuer.addToWorkList(e);
@@ -2498,22 +2403,12 @@
       reporter.log('Retaining metadata.');
 
       compiler.libraryLoader.libraries.forEach(retainMetadataOf);
-      if (enqueuer.isResolutionQueue) {
-        for (Dependency dependency in metadataConstants) {
-          registerCompileTimeConstant(
-              dependency.constant,
-              new EagerRegistry(compiler,
-                  dependency.annotatedElement.analyzableElement.treeElements),
-              addForEmission: false);
-        }
-      } else {
-        for (Dependency dependency in metadataConstants) {
-          registerCompileTimeConstant(
-              dependency.constant,
-              new CodegenRegistry(compiler,
-                  dependency.annotatedElement.analyzableElement.treeElements),
-              addForEmission: false);
-        }
+      for (Dependency dependency in metadataConstants) {
+        registerCompileTimeConstant(
+            dependency.constant,
+            new EagerRegistry('EagerRegistry for ${dependency}', enqueuer));
+      }
+      if (!enqueuer.isResolutionQueue) {
         metadataConstants.clear();
       }
     }
@@ -2530,13 +2425,19 @@
   }
 
   void onElementResolved(Element element, TreeElements elements) {
-    if ((element.isFunction || element.isGenerativeConstructor) &&
+    if (element.isMalformed) {
+      // Elements that are marker as malformed during parsing or resolution
+      // might be registered here. These should just be ignored.
+      return;
+    }
+
+    if ((element.isFunction || element.isConstructor) &&
         annotations.noInline(element)) {
       inlineCache.markAsNonInlinable(element);
     }
 
     LibraryElement library = element.library;
-    if (!library.isPlatformLibrary && !library.canUseNative) return;
+    if (!library.isPlatformLibrary && !canLibraryUseNative(library)) return;
     bool hasNoInline = false;
     bool hasForceInline = false;
     bool hasNoThrows = false;
@@ -2548,7 +2449,7 @@
       if (!constantValue.isConstructedObject) continue;
       ObjectConstantValue value = constantValue;
       ClassElement cls = value.type.element;
-      if (cls == forceInlineClass) {
+      if (cls == helpers.forceInlineClass) {
         hasForceInline = true;
         if (VERBOSE_OPTIMIZER_HINTS) {
           reporter.reportHintMessage(
@@ -2557,7 +2458,7 @@
               {'text': "Must inline"});
         }
         inlineCache.markAsMustInline(element);
-      } else if (cls == noInlineClass) {
+      } else if (cls == helpers.noInlineClass) {
         hasNoInline = true;
         if (VERBOSE_OPTIMIZER_HINTS) {
           reporter.reportHintMessage(
@@ -2566,12 +2467,13 @@
               {'text': "Cannot inline"});
         }
         inlineCache.markAsNonInlinable(element);
-      } else if (cls == noThrowsClass) {
+      } else if (cls == helpers.noThrowsClass) {
         hasNoThrows = true;
-        if (!Elements.isStaticOrTopLevelFunction(element)) {
+        if (!Elements.isStaticOrTopLevelFunction(element) &&
+            !element.isFactoryConstructor) {
           reporter.internalError(element,
               "@NoThrows() is currently limited to top-level"
-              " or static functions");
+              " or static functions and factory constructors.");
         }
         if (VERBOSE_OPTIMIZER_HINTS) {
           reporter.reportHintMessage(
@@ -2580,7 +2482,7 @@
               {'text': "Cannot throw"});
         }
         compiler.world.registerCannotThrow(element);
-      } else if (cls == noSideEffectsClass) {
+      } else if (cls == helpers.noSideEffectsClass) {
         hasNoSideEffects = true;
         if (VERBOSE_OPTIMIZER_HINTS) {
           reporter.reportHintMessage(
@@ -2603,7 +2505,7 @@
       reporter.internalError(element,
           "@NoSideEffects() should always be combined with @NoInline.");
     }
-    if (element == invokeOnMethod) {
+    if (element == helpers.invokeOnMethod) {
       compiler.enabledInvokeOn = true;
     }
   }
@@ -2614,13 +2516,11 @@
         : null;
   }
 
-  FunctionElement helperForBadMain() => findHelper('badMain');
+  FunctionElement helperForBadMain() => helpers.badMain;
 
-  FunctionElement helperForMissingMain() => findHelper('missingMain');
+  FunctionElement helperForMissingMain() => helpers.missingMain;
 
-  FunctionElement helperForMainArity() {
-    return findHelper('mainHasTooManyParameters');
-  }
+  FunctionElement helperForMainArity() => helpers.mainHasTooManyParameters;
 
   void forgetElement(Element element) {
     constants.forgetElement(element);
@@ -2650,33 +2550,6 @@
     return "${outName}_$name$extension";
   }
 
-  void registerAsyncMarker(FunctionElement element,
-                           Enqueuer enqueuer,
-                           Registry registry) {
-    if (element.asyncMarker == AsyncMarker.ASYNC) {
-      _registerAsync(enqueuer, registry);
-    } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) {
-      _registerSyncStar(enqueuer, registry);
-    } else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) {
-      _registerAsyncStar(enqueuer, registry);
-    }
-  }
-
-  void _registerAsync(Enqueuer enqueuer,
-                      Registry registry) {
-    enqueueImpact(enqueuer, impacts.asyncBody, registry);
-  }
-
-  void _registerSyncStar(Enqueuer enqueuer,
-                         Registry registry) {
-    enqueueImpact(enqueuer, impacts.syncStarBody, registry);
-  }
-
-  void _registerAsyncStar(Enqueuer enqueuer,
-                          Registry registry) {
-    enqueueImpact(enqueuer, impacts.asyncStarBody, registry);
-  }
-
   @override
   bool enableDeferredLoadingIfSupported(Spannable node, Registry registry) {
     registerCheckDeferredIsLoaded(registry);
@@ -2754,6 +2627,39 @@
     }
     return rewriter.rewrite(code);
   }
+
+  /// The locations of js patch-files relative to the sdk-descriptors.
+  static const _patchLocations = const <String, String>{
+    "async": "_internal/js_runtime/lib/async_patch.dart",
+    "collection":  "_internal/js_runtime/lib/collection_patch.dart",
+    "convert": "_internal/js_runtime/lib/convert_patch.dart",
+    "core": "_internal/js_runtime/lib/core_patch.dart",
+    "developer": "_internal/js_runtime/lib/developer_patch.dart",
+    "io": "_internal/js_runtime/lib/io_patch.dart",
+    "isolate": "_internal/js_runtime/lib/isolate_patch.dart",
+    "math": "_internal/js_runtime/lib/math_patch.dart",
+    "mirrors": "_internal/js_runtime/lib/mirrors_patch.dart",
+    "typed_data": "_internal/js_runtime/lib/typed_data_patch.dart",
+    "_internal": "_internal/js_runtime/lib/internal_patch.dart"
+  };
+
+  @override
+  Uri resolvePatchUri(String libraryName, Uri platformConfigUri) {
+    String patchLocation = _patchLocations[libraryName];
+    if (patchLocation == null) return null;
+    return platformConfigUri.resolve(patchLocation);
+  }
+
+  @override
+  ImpactStrategy createImpactStrategy(
+      {bool supportDeferredLoad: true,
+       bool supportDumpInfo: true}) {
+    return new JavaScriptImpactStrategy(
+        resolution,
+        compiler.dumpInfoTask,
+        supportDeferredLoad: supportDeferredLoad,
+        supportDumpInfo: supportDumpInfo);
+  }
 }
 
 /// Handling of special annotations for tests.
@@ -2795,7 +2701,7 @@
       // TODO(floitsch): restrict to elements from the test directory.
       return true;
     }
-    return _hasAnnotation(element, backend.noInlineClass);
+    return _hasAnnotation(element, backend.helpers.noInlineClass);
   }
 
   /// Returns `true` if parameter and returns types should be trusted for
@@ -2830,14 +2736,15 @@
   }
 }
 
-class JavaScriptResolutionCallbacks extends ResolutionCallbacks {
+class JavaScriptImpactTransformer extends ImpactTransformer {
   final JavaScriptBackend backend;
 
-  JavaScriptResolutionCallbacks(this.backend);
+  JavaScriptImpactTransformer(this.backend);
 
   BackendImpacts get impacts => backend.impacts;
 
-  WorldImpact transformImpact(ResolutionImpact worldImpact) {
+  @override
+  WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
     TransformedWorldImpact transformed =
         new TransformedWorldImpact(worldImpact);
     for (Feature feature in worldImpact.features) {
@@ -2885,6 +2792,9 @@
         case Feature.STRING_INTERPOLATION:
           registerBackendImpact(transformed, impacts.stringInterpolation);
           break;
+        case Feature.STRING_JUXTAPOSITION:
+          registerBackendImpact(transformed, impacts.stringJuxtaposition);
+          break;
         case Feature.SUPER_NO_SUCH_METHOD:
           registerBackendImpact(transformed, impacts.superNoSuchMethod);
           break;
@@ -2911,25 +2821,53 @@
           break;
       }
     }
-    for (DartType type in worldImpact.isChecks) {
-      onIsCheck(type, transformed);
+
+    bool hasAsCast = false;
+    bool hasTypeLiteral = false;
+    for (TypeUse typeUse in worldImpact.typeUses) {
+      DartType type = typeUse.type;
+      switch (typeUse.kind) {
+        case TypeUseKind.INSTANTIATION:
+          registerRequiredType(type);
+          break;
+        case TypeUseKind.IS_CHECK:
+          onIsCheck(type, transformed);
+          break;
+        case TypeUseKind.AS_CAST:
+          onIsCheck(type, transformed);
+          hasAsCast = true;
+          break;
+        case TypeUseKind.CHECKED_MODE_CHECK:
+          if (backend.compiler.enableTypeAssertions) {
+            onIsCheck(type, transformed);
+          }
+          break;
+        case TypeUseKind.CATCH_TYPE:
+          onIsCheck(type, transformed);
+          break;
+        case TypeUseKind.TYPE_LITERAL:
+          backend.customElementsAnalysis.registerTypeLiteral(type);
+          if (type.isTypedef) {
+            backend.compiler.world.allTypedefs.add(type.element);
+          }
+          if (type.isTypeVariable) {
+            ClassElement cls = type.element.enclosingClass;
+            backend.rti.registerClassUsingTypeVariableExpression(cls);
+            registerBackendImpact(transformed, impacts.typeVariableExpression);
+          }
+          hasTypeLiteral = true;
+          break;
+      }
     }
 
-    if (worldImpact.asCasts.isNotEmpty) {
-      for (DartType type in worldImpact.asCasts) {
-        onIsCheck(type, transformed);
-      }
+    if (hasAsCast) {
       registerBackendImpact(transformed, impacts.asCheck);
     }
 
-    if (backend.compiler.enableTypeAssertions) {
-      for (DartType type in worldImpact.checkedModeChecks) {
-        onIsCheck(type, transformed);
-      }
-    }
-
-    for (DartType requiredType in worldImpact.requiredTypes) {
-      backend.registerRequiredType(requiredType);
+    if (hasTypeLiteral) {
+      transformed.registerTypeUse(new TypeUse.instantiation(
+          backend.compiler.coreTypes.typeType));
+      registerBackendImpact(transformed, impacts.typeLiteral);
     }
 
     for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) {
@@ -2938,51 +2876,61 @@
       if (mapLiteralUse.isConstant) {
         registerBackendImpact(transformed, impacts.constantMapLiteral);
       } else {
-        transformed.registerInstantiatedType(mapLiteralUse.type);
+        transformed.registerTypeUse(
+            new TypeUse.instantiation(mapLiteralUse.type));
       }
+      registerRequiredType(mapLiteralUse.type);
     }
 
     for (ListLiteralUse listLiteralUse in worldImpact.listLiterals) {
       // TODO(johnniwinther): Use the [isConstant] and [isEmpty] property when
       // factory constructors are registered directly.
-      transformed.registerInstantiatedType(listLiteralUse.type);
+      transformed.registerTypeUse(
+          new TypeUse.instantiation(listLiteralUse.type));
+      registerRequiredType(listLiteralUse.type);
     }
 
-    if (worldImpact.typeLiterals.isNotEmpty) {
-      transformed.registerInstantiatedType(backend.compiler.coreTypes.typeType);
-      registerBackendImpact(transformed, impacts.typeLiteral);
-      for (DartType typeLiteral in worldImpact.typeLiterals) {
-        backend.customElementsAnalysis.registerTypeLiteral(typeLiteral);
-        if (typeLiteral.isTypedef) {
-          backend.compiler.world.allTypedefs.add(typeLiteral.element);
-        }
-        if (typeLiteral.isTypeVariable) {
-          ClassElement cls = typeLiteral.element.enclosingClass;
-          backend.rti.registerClassUsingTypeVariableExpression(cls);
-          registerBackendImpact(transformed, impacts.typeVariableExpression);
+    if (worldImpact.constSymbolNames.isNotEmpty) {
+      registerBackendImpact(transformed, impacts.constSymbol);
+      for (String constSymbolName in worldImpact.constSymbolNames) {
+        backend.registerConstSymbol(constSymbolName);
+      }
+    }
+
+    for (StaticUse staticUse in worldImpact.staticUses) {
+      if (staticUse.kind == StaticUseKind.CLOSURE) {
+        registerBackendImpact(transformed, impacts.closure);
+        LocalFunctionElement closure = staticUse.element;
+        if (closure.type.containsTypeVariables) {
+          backend.compiler.enqueuer.resolution.universe
+              .closuresWithFreeTypeVariables.add(closure);
+          registerBackendImpact(transformed, impacts.computeSignature);
         }
       }
     }
 
-    for (String constSymbolName in worldImpact.constSymbolNames) {
-      backend.registerConstSymbol(constSymbolName);
-    }
-
-    for (LocalFunctionElement closure in worldImpact.closures) {
-      if (closure.computeType(backend.resolution).containsTypeVariables) {
-        backend.compiler.enqueuer.resolution.universe
-            .closuresWithFreeTypeVariables.add(closure);
-        registerBackendImpact(transformed, impacts.computeSignature);
+    for (ConstantExpression constant in worldImpact.constantLiterals) {
+      switch (constant.kind) {
+        case ConstantExpressionKind.NULL:
+          registerBackendImpact(transformed, impacts.nullLiteral);
+          break;
+        case ConstantExpressionKind.BOOL:
+          registerBackendImpact(transformed, impacts.boolLiteral);
+          break;
+        case ConstantExpressionKind.INT:
+          registerBackendImpact(transformed, impacts.intLiteral);
+          break;
+        case ConstantExpressionKind.DOUBLE:
+          registerBackendImpact(transformed, impacts.doubleLiteral);
+          break;
+        case ConstantExpressionKind.STRING:
+          registerBackendImpact(transformed, impacts.stringLiteral);
+          break;
+        default:
+          assert(invariant(NO_LOCATION_SPANNABLE, false,
+              message: "Unexpected constant literal: ${constant.kind}."));
       }
     }
-    // TODO(johnniwinther): Remove this when dependency tracking is done on
-    // the world impact itself.
-    for (InterfaceType instantiatedType in worldImpact.instantiatedTypes) {
-      transformed.registerInstantiatedType(instantiatedType);
-    }
-    for (Element element in worldImpact.staticUses) {
-      transformed.registerStaticUse(element);
-    }
 
     return transformed;
   }
@@ -2992,24 +2940,42 @@
     for (Element staticUse in backendImpact.staticUses) {
       assert(staticUse != null);
       backend.registerBackendUse(staticUse);
-      worldImpact.registerStaticUse(staticUse);
+      worldImpact.registerStaticUse(
+          // TODO(johnniwinther): Store the correct use in impacts.
+          new StaticUse.foreignUse(staticUse));
     }
     for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) {
       backend.registerBackendUse(instantiatedType.element);
-      worldImpact.registerInstantiatedType(instantiatedType);
+      worldImpact.registerTypeUse(
+          new TypeUse.instantiation(instantiatedType));
     }
     for (ClassElement cls in backendImpact.instantiatedClasses) {
       cls.ensureResolved(backend.resolution);
       backend.registerBackendUse(cls);
-      worldImpact.registerInstantiatedType(cls.rawType);
+      worldImpact.registerTypeUse(
+          new TypeUse.instantiation(cls.rawType));
     }
     for (BackendImpact otherImpact in backendImpact.otherImpacts) {
       registerBackendImpact(worldImpact, otherImpact);
     }
   }
 
+  /// Register [type] as required for the runtime type information system.
+  void registerRequiredType(DartType type) {
+    // If [argument] has type variables or is a type variable, this method
+    // registers a RTI dependency between the class where the type variable is
+    // defined (that is the enclosing class of the current element being
+    // resolved) and the class of [type]. If the class of [type] requires RTI,
+    // then the class of the type variable does too.
+    ClassElement contextClass = Types.getClassContext(type);
+    if (contextClass != null) {
+      backend.rti.registerRtiDependency(type.element, contextClass);
+    }
+  }
+
   // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType].
   void onIsCheck(DartType type, TransformedWorldImpact transformed) {
+    registerRequiredType(type);
     type.computeUnaliased(backend.resolution);
     type = type.unaliased;
     registerBackendImpact(transformed, impacts.typeCheck);
@@ -3037,10 +3003,122 @@
     if (type is FunctionType) {
       registerBackendImpact(transformed, impacts.functionTypeCheck);
     }
-    if (type.element != null && type.element.isNative) {
+    if (type.element != null && backend.isNative(type.element)) {
       registerBackendImpact(transformed, impacts.nativeTypeCheck);
     }
   }
+
+  void onIsCheckForCodegen(DartType type, TransformedWorldImpact transformed) {
+    type = type.unaliased;
+    registerBackendImpact(transformed, impacts.typeCheck);
+
+    bool inCheckedMode = backend.compiler.enableTypeAssertions;
+    // [registerIsCheck] is also called for checked mode checks, so we
+    // need to register checked mode helpers.
+    if (inCheckedMode) {
+      // All helpers are added to resolution queue in enqueueHelpers. These
+      // calls to enqueueInResolution serve as assertions that the helper was
+      // in fact added.
+      // TODO(13155): Find a way to enqueue helpers lazily.
+      CheckedModeHelper helper =
+          backend.getCheckedModeHelper(type, typeCast: false);
+      if (helper != null) {
+        StaticUse staticUse = helper.getStaticUse(backend.compiler);
+        transformed.registerStaticUse(staticUse);
+        backend.registerBackendUse(staticUse.element);
+      }
+      // We also need the native variant of the check (for DOM types).
+      helper = backend.getNativeCheckedModeHelper(type, typeCast: false);
+      if (helper != null) {
+        StaticUse staticUse = helper.getStaticUse(backend.compiler);
+        transformed.registerStaticUse(staticUse);
+        backend.registerBackendUse(staticUse.element);
+      }
+    }
+    if (!type.treatAsRaw || type.containsTypeVariables) {
+      registerBackendImpact(transformed, impacts.genericIsCheck);
+    }
+    if (type.element != null && backend.isNative(type.element)) {
+      // We will neeed to add the "$is" and "$as" properties on the
+      // JavaScript object prototype, so we make sure
+      // [:defineProperty:] is compiled.
+      registerBackendImpact(transformed, impacts.nativeTypeCheck);
+    }
+  }
+
+  @override
+  WorldImpact transformCodegenImpact(CodegenImpact impact) {
+    TransformedWorldImpact transformed = new TransformedWorldImpact(impact);
+    EagerRegistry registry = impact.registry;
+    Enqueuer world = registry.world;
+
+    for (TypeUse typeUse in impact.typeUses) {
+      DartType type = typeUse.type;
+      switch (typeUse.kind) {
+        case TypeUseKind.INSTANTIATION:
+          backend.lookupMapAnalysis.registerInstantiatedType(type, registry);
+          break;
+        case TypeUseKind.IS_CHECK:
+          onIsCheckForCodegen(type, transformed);
+          break;
+        default:
+      }
+    }
+
+    for (ConstantValue constant in impact.compileTimeConstants) {
+      backend.registerCompileTimeConstant(constant, registry);
+      backend.addCompileTimeConstantForEmission(constant);
+    }
+
+    for (Pair<DartType, DartType> check in
+            impact.typeVariableBoundsSubtypeChecks) {
+      backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b);
+    }
+
+
+    for (StaticUse staticUse in impact.staticUses) {
+      if (staticUse.kind == StaticUseKind.CLOSURE) {
+        LocalFunctionElement closure = staticUse.element;
+        if (backend.methodNeedsRti(closure)) {
+           registerBackendImpact(transformed, impacts.computeSignature);
+         }
+      }
+    }
+
+    for (String name in impact.constSymbols) {
+      backend.registerConstSymbol(name);
+    }
+
+    for (Set<ClassElement> classes in impact.specializedGetInterceptors) {
+      backend.registerSpecializedGetInterceptor(classes);
+    }
+
+    if (impact.usesInterceptor) {
+      backend.registerUseInterceptor(world);
+    }
+
+    for (ClassElement element in impact.typeConstants) {
+      backend.customElementsAnalysis.registerTypeConstant(element);
+      backend.lookupMapAnalysis.registerTypeConstant(element);
+    }
+
+    for (FunctionElement element in impact.asyncMarkers) {
+      switch (element.asyncMarker) {
+        case AsyncMarker.ASYNC:
+          registerBackendImpact(transformed, impacts.asyncBody);
+          break;
+        case AsyncMarker.SYNC_STAR:
+          registerBackendImpact(transformed, impacts.syncStarBody);
+          break;
+        case AsyncMarker.ASYNC_STAR:
+          registerBackendImpact(transformed, impacts.asyncStarBody);
+          break;
+      }
+    }
+
+    // TODO(johnniwinther): Remove eager registration.
+    return transformed;
+  }
 }
 
 /// Records that [constant] is used by the element behind [registry].
@@ -3051,3 +3129,45 @@
   const Dependency(this.constant, this.annotatedElement);
 }
 
+class JavaScriptImpactStrategy extends ImpactStrategy {
+  final Resolution resolution;
+  final DumpInfoTask dumpInfoTask;
+  final bool supportDeferredLoad;
+  final bool supportDumpInfo;
+
+  JavaScriptImpactStrategy(this.resolution,
+                           this.dumpInfoTask,
+                           {this.supportDeferredLoad,
+                            this.supportDumpInfo});
+
+  @override
+  void visitImpact(Element element,
+                   WorldImpact impact,
+                   WorldImpactVisitor visitor,
+                   ImpactUseCase impactUse) {
+    // TODO(johnniwinther): Compute the application strategy once for each use.
+    if (impactUse == ResolutionEnqueuer.IMPACT_USE) {
+      if (supportDeferredLoad) {
+        impact.apply(visitor);
+      } else {
+        impact.apply(visitor);
+        resolution.uncacheWorldImpact(element);
+      }
+    } else if (impactUse == DeferredLoadTask.IMPACT_USE) {
+      impact.apply(visitor);
+      // Impacts are uncached globally in [onImpactUsed].
+    } else if (impactUse == DumpInfoTask.IMPACT_USE) {
+      impact.apply(visitor);
+      dumpInfoTask.unregisterImpact(element);
+    } else {
+      impact.apply(visitor);
+    }
+  }
+
+  @override
+  void onImpactUsed(ImpactUseCase impactUse) {
+    if (impactUse == DeferredLoadTask.IMPACT_USE) {
+      resolution.emptyCache();
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/js_backend/backend_helpers.dart b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
index 3c59891..804594c 100644
--- a/pkg/compiler/lib/src/js_backend/backend_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
@@ -4,20 +4,51 @@
 
 library dart2js.js_backend.helpers;
 
+import '../common.dart';
+import '../common/names.dart' show
+    Identifiers,
+    Uris;
 import '../common/resolution.dart' show
     Resolution;
 import '../compiler.dart' show
     Compiler;
+import '../core_types.dart' show
+    CoreClasses;
 import '../elements/elements.dart' show
+    AbstractFieldElement,
     ClassElement,
+    ConstructorElement,
     Element,
+    EnumClassElement,
+    FunctionElement,
     LibraryElement,
     MethodElement;
+import '../library_loader.dart' show
+    LoadedLibraries;
 
 import 'js_backend.dart';
 
 /// Helper classes and functions for the JavaScript backend.
 class BackendHelpers {
+  static final Uri DART_JS_HELPER = new Uri(scheme: 'dart', path: '_js_helper');
+  static final Uri DART_INTERCEPTORS =
+      new Uri(scheme: 'dart', path: '_interceptors');
+  static final Uri DART_FOREIGN_HELPER =
+      new Uri(scheme: 'dart', path: '_foreign_helper');
+  static final Uri DART_JS_MIRRORS =
+      new Uri(scheme: 'dart', path: '_js_mirrors');
+  static final Uri DART_JS_NAMES =
+      new Uri(scheme: 'dart', path: '_js_names');
+  static final Uri DART_EMBEDDED_NAMES =
+      new Uri(scheme: 'dart', path: '_js_embedded_names');
+  static final Uri DART_ISOLATE_HELPER =
+      new Uri(scheme: 'dart', path: '_isolate_helper');
+  static final Uri PACKAGE_JS =
+         new Uri(scheme: 'package', path: 'js/js.dart');
+
+  static const String INVOKE_ON = '_getCachedInvocation';
+  static const String START_ROOT_ISOLATE = 'startRootIsolate';
+
   final Compiler compiler;
 
   Element cachedCheckConcurrentModificationError;
@@ -28,16 +59,350 @@
 
   Resolution get resolution => backend.resolution;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  DiagnosticReporter get reporter => compiler.reporter;
+
   MethodElement assertTest;
   MethodElement assertThrow;
   MethodElement assertHelper;
 
-  Element findHelper(String name) => backend.findHelper(name);
-  Element findAsyncHelper(String name) => backend.findAsyncHelper(name);
-  Element findInterceptor(String name) => backend.findInterceptor(name);
 
+  LibraryElement jsHelperLibrary;
+  LibraryElement asyncLibrary;
+  LibraryElement interceptorsLibrary;
+  LibraryElement foreignLibrary;
+  LibraryElement isolateHelperLibrary;
+
+  /// Reference to the internal library to lookup functions to always inline.
+  LibraryElement internalLibrary;
+
+  ClassElement closureClass;
+  ClassElement boundClosureClass;
+  Element assertUnreachableMethod;
+  Element invokeOnMethod;
+
+  ClassElement jsInterceptorClass;
+  ClassElement jsStringClass;
+  ClassElement jsArrayClass;
+  ClassElement jsNumberClass;
+  ClassElement jsIntClass;
+  ClassElement jsDoubleClass;
+  ClassElement jsNullClass;
+  ClassElement jsBoolClass;
+  ClassElement jsPlainJavaScriptObjectClass;
+  ClassElement jsUnknownJavaScriptObjectClass;
+  ClassElement jsJavaScriptFunctionClass;
+  ClassElement jsJavaScriptObjectClass;
+
+  ClassElement jsIndexableClass;
+  ClassElement jsMutableIndexableClass;
+
+  ClassElement jsMutableArrayClass;
+  ClassElement jsFixedArrayClass;
+  ClassElement jsExtendableArrayClass;
+  ClassElement jsUnmodifiableArrayClass;
+  ClassElement jsPositiveIntClass;
+  ClassElement jsUInt32Class;
+  ClassElement jsUInt31Class;
+
+  Element jsIndexableLength;
+  Element jsArrayTypedConstructor;
+  Element jsArrayRemoveLast;
+  Element jsArrayAdd;
+  Element jsStringSplit;
+  Element jsStringToString;
+  Element jsStringOperatorAdd;
+  Element objectEquals;
+
+  ClassElement typeLiteralClass;
+  ClassElement mapLiteralClass;
+  ClassElement constMapLiteralClass;
+  ClassElement typeVariableClass;
+  ConstructorElement mapLiteralConstructor;
+  ConstructorElement mapLiteralConstructorEmpty;
+  Element mapLiteralUntypedMaker;
+  Element mapLiteralUntypedEmptyMaker;
+
+  ClassElement noSideEffectsClass;
+  ClassElement noThrowsClass;
+  ClassElement noInlineClass;
+  ClassElement forceInlineClass;
+  ClassElement irRepresentationClass;
+
+  ClassElement jsAnnotationClass;
+  ClassElement jsAnonymousClass;
+
+  Element getInterceptorMethod;
+
+  ClassElement jsInvocationMirrorClass;
+
+  ClassElement typedArrayClass;
+  ClassElement typedArrayOfIntClass;
+
+  /**
+   * Interface used to determine if an object has the JavaScript
+   * indexing behavior. The interface is only visible to specific
+   * libraries.
+   */
+  ClassElement jsIndexingBehaviorInterface;
+
+  Element getNativeInterceptorMethod;
+
+  /// Holds the method "getIsolateAffinityTag" when dart:_js_helper has been
+  /// loaded.
+  FunctionElement getIsolateAffinityTagMarker;
+
+  /// Holds the method "disableTreeShaking" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement disableTreeShakingMarker;
+
+  /// Holds the method "preserveNames" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement preserveNamesMarker;
+
+  /// Holds the method "preserveMetadata" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement preserveMetadataMarker;
+
+  /// Holds the method "preserveUris" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement preserveUrisMarker;
+
+  /// Holds the method "preserveLibraryNames" in js_mirrors when
+  /// dart:mirrors has been loaded.
+  FunctionElement preserveLibraryNamesMarker;
+
+  /// Holds the method "requiresPreamble" in _js_helper.
+  FunctionElement requiresPreambleMarker;
+
+  /// Holds the class for the [JsGetName] enum.
+  EnumClassElement jsGetNameEnum;
+
+  /// Holds the class for the [JsBuiltins] enum.
+  EnumClassElement jsBuiltinEnum;
+
+  // TODO(johnniwinther): Make these private.
+  // TODO(johnniwinther): Split into findHelperFunction and findHelperClass and
+  // add a check that the element has the expected kind.
+  Element findHelper(String name) => find(jsHelperLibrary, name);
+  Element findAsyncHelper(String name) => find(asyncLibrary, name);
+  Element findInterceptor(String name) => find(interceptorsLibrary, name);
   Element find(LibraryElement library, String name) {
-    return backend.find(library, name);
+    Element element = library.implementation.findLocal(name);
+    assert(invariant(library, element != null,
+        message: "Element '$name' not found in '${library.canonicalUri}'."));
+    return element;
+  }
+
+  void onLibraryCreated(LibraryElement library) {
+    Uri uri = library.canonicalUri;
+    if (uri == DART_JS_HELPER) {
+      jsHelperLibrary = library;
+    } else if (uri == Uris.dart_async) {
+      asyncLibrary = library;
+    } else if (uri == Uris.dart__internal) {
+      internalLibrary = library;
+    } else if (uri ==  DART_INTERCEPTORS) {
+      interceptorsLibrary = library;
+    } else if (uri ==  DART_FOREIGN_HELPER) {
+      foreignLibrary = library;
+    } else if (uri == DART_ISOLATE_HELPER) {
+      isolateHelperLibrary = library;
+    }
+  }
+
+  void initializeHelperClasses(DiagnosticReporter reporter) {
+    final List missingHelperClasses = [];
+    ClassElement lookupHelperClass(String name) {
+      ClassElement result = findHelper(name);
+      if (result == null) {
+        missingHelperClasses.add(name);
+      }
+      return result;
+    }
+    jsInvocationMirrorClass = lookupHelperClass('JSInvocationMirror');
+    boundClosureClass = lookupHelperClass('BoundClosure');
+    closureClass = lookupHelperClass('Closure');
+    if (!missingHelperClasses.isEmpty) {
+      reporter.internalError(jsHelperLibrary,
+          'dart:_js_helper library does not contain required classes: '
+          '$missingHelperClasses');
+    }
+  }
+
+  void onLibraryScanned(LibraryElement library) {
+    Uri uri = library.canonicalUri;
+
+    FunctionElement findMethod(String name) {
+      return find(library, name);
+    }
+
+    ClassElement findClass(String name) {
+      return find(library, name);
+    }
+
+    if (uri == DART_INTERCEPTORS) {
+      getInterceptorMethod = findMethod('getInterceptor');
+      getNativeInterceptorMethod = findMethod('getNativeInterceptor');
+      jsInterceptorClass = findClass('Interceptor');
+      jsStringClass = findClass('JSString');
+      jsArrayClass = findClass('JSArray');
+      // The int class must be before the double class, because the
+      // emitter relies on this list for the order of type checks.
+      jsIntClass = findClass('JSInt');
+      jsPositiveIntClass = findClass('JSPositiveInt');
+      jsUInt32Class = findClass('JSUInt32');
+      jsUInt31Class = findClass('JSUInt31');
+      jsDoubleClass = findClass('JSDouble');
+      jsNumberClass = findClass('JSNumber');
+      jsNullClass = findClass('JSNull');
+      jsBoolClass = findClass('JSBool');
+      jsMutableArrayClass = findClass('JSMutableArray');
+      jsFixedArrayClass = findClass('JSFixedArray');
+      jsExtendableArrayClass = findClass('JSExtendableArray');
+      jsUnmodifiableArrayClass = findClass('JSUnmodifiableArray');
+      jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject');
+      jsJavaScriptObjectClass = findClass('JavaScriptObject');
+      jsJavaScriptFunctionClass = findClass('JavaScriptFunction');
+      jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject');
+      jsIndexableClass = findClass('JSIndexable');
+      jsMutableIndexableClass = findClass('JSMutableIndexable');
+    } else if (uri == DART_JS_HELPER) {
+      initializeHelperClasses(reporter);
+      assertTest = findHelper('assertTest');
+      assertThrow = findHelper('assertThrow');
+      assertHelper = findHelper('assertHelper');
+      assertUnreachableMethod = findHelper('assertUnreachable');
+
+      typeLiteralClass = findClass('TypeImpl');
+      constMapLiteralClass = findClass('ConstantMap');
+      typeVariableClass = findClass('TypeVariable');
+
+      jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior');
+
+      noSideEffectsClass = findClass('NoSideEffects');
+      noThrowsClass = findClass('NoThrows');
+      noInlineClass = findClass('NoInline');
+      forceInlineClass = findClass('ForceInline');
+      irRepresentationClass = findClass('IrRepresentation');
+
+      getIsolateAffinityTagMarker = findMethod('getIsolateAffinityTag');
+
+      requiresPreambleMarker = findMethod('requiresPreamble');
+    } else if (uri == DART_JS_MIRRORS) {
+      disableTreeShakingMarker = find(library, 'disableTreeShaking');
+      preserveMetadataMarker = find(library, 'preserveMetadata');
+      preserveUrisMarker = find(library, 'preserveUris');
+      preserveLibraryNamesMarker = find(library, 'preserveLibraryNames');
+    } else if (uri == DART_JS_NAMES) {
+      preserveNamesMarker = find(library, 'preserveNames');
+    } else if (uri == DART_EMBEDDED_NAMES) {
+      jsGetNameEnum = find(library, 'JsGetName');
+      jsBuiltinEnum = find(library, 'JsBuiltin');
+    } else if (uri == Uris.dart__native_typed_data) {
+      typedArrayClass = findClass('NativeTypedArray');
+      typedArrayOfIntClass = findClass('NativeTypedArrayOfInt');
+    } else if (uri == PACKAGE_JS) {
+      jsAnnotationClass = find(library, 'JS');
+      jsAnonymousClass = find(library, '_Anonymous');
+    }
+  }
+
+
+  void onLibrariesLoaded(LoadedLibraries loadedLibraries) {
+    assert(loadedLibraries.containsLibrary(Uris.dart_core));
+    assert(loadedLibraries.containsLibrary(DART_INTERCEPTORS));
+    assert(loadedLibraries.containsLibrary(DART_JS_HELPER));
+
+    if (jsInvocationMirrorClass != null) {
+      jsInvocationMirrorClass.ensureResolved(resolution);
+      invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON);
+    }
+
+    // [LinkedHashMap] is reexported from dart:collection and can therefore not
+    // be loaded from dart:core in [onLibraryScanned].
+    mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap');
+    assert(invariant(compiler.coreLibrary, mapLiteralClass != null,
+        message: "Element 'LinkedHashMap' not found in 'dart:core'."));
+
+    // TODO(kasperl): Some tests do not define the special JSArray
+    // subclasses, so we check to see if they are defined before
+    // trying to resolve them.
+    if (jsFixedArrayClass != null) {
+      jsFixedArrayClass.ensureResolved(resolution);
+    }
+    if (jsExtendableArrayClass != null) {
+      jsExtendableArrayClass.ensureResolved(resolution);
+    }
+    if (jsUnmodifiableArrayClass != null) {
+      jsUnmodifiableArrayClass.ensureResolved(resolution);
+    }
+
+    jsIndexableClass.ensureResolved(resolution);
+    jsIndexableLength = compiler.lookupElementIn(
+        jsIndexableClass, 'length');
+    if (jsIndexableLength != null && jsIndexableLength.isAbstractField) {
+      AbstractFieldElement element = jsIndexableLength;
+      jsIndexableLength = element.getter;
+    }
+
+    jsArrayClass.ensureResolved(resolution);
+    jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed');
+    jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast');
+    jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add');
+
+    jsStringClass.ensureResolved(resolution);
+    jsStringSplit = compiler.lookupElementIn(jsStringClass, 'split');
+    jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+');
+    jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString');
+
+    objectEquals = compiler.lookupElementIn(coreClasses.objectClass, '==');
+  }
+
+  Element get badMain {
+    return findHelper('badMain');
+  }
+
+  Element get missingMain {
+    return findHelper('missingMain');
+  }
+
+  Element get mainHasTooManyParameters {
+    return findHelper('mainHasTooManyParameters');
+  }
+
+  Element get loadLibraryWrapper {
+    return findHelper("_loadLibraryWrapper");
+  }
+
+  Element get boolConversionCheck {
+    return findHelper('boolConversionCheck');
+  }
+
+  Element get consoleTraceHelper {
+    return findHelper('consoleTraceHelper');
+  }
+
+  Element get postTraceHelper {
+    return findHelper('postTraceHelper');
+  }
+
+  FunctionElement get closureFromTearOff {
+    return findHelper('closureFromTearOff');
+  }
+
+  Element get isJsIndexable {
+    return findHelper('isJsIndexable');
+  }
+
+
+  Element get throwIllegalArgumentException {
+    return findHelper('iae');
+  }
+
+  Element get throwIndexOutOfRangeException {
+    return findHelper('ioore');
   }
 
   Element get exceptionUnwrapper {
@@ -68,10 +433,6 @@
     return findHelper('throwConcurrentModificationError');
   }
 
-  Element get throwIndexOutOfBoundsError {
-    return findHelper('ioore');
-  }
-
   Element get stringInterpolationHelper {
     return findHelper('S');
   }
@@ -222,6 +583,18 @@
     return classElement;
   }
 
+  Element get futureImplementation {
+    ClassElement classElement = findAsyncHelper('_Future');
+    classElement.ensureResolved(resolution);
+    return classElement;
+  }
+
+  Element get controllerStream {
+    ClassElement classElement = findAsyncHelper("_ControllerStream");
+    classElement.ensureResolved(resolution);
+    return classElement;
+  }
+
   Element get syncStarIterableConstructor {
     ClassElement classElement = syncStarIterable;
     classElement.ensureResolved(resolution);
@@ -252,6 +625,30 @@
     return classElement.lookupConstructor("");
   }
 
+  ClassElement get VoidRuntimeType {
+    return findHelper('VoidRuntimeType');
+  }
+
+  ClassElement get RuntimeType {
+    return findHelper('RuntimeType');
+  }
+
+  ClassElement get RuntimeFunctionType {
+    return findHelper('RuntimeFunctionType');
+  }
+
+  ClassElement get RuntimeTypePlain {
+    return findHelper('RuntimeTypePlain');
+  }
+
+  ClassElement get RuntimeTypeGeneric {
+    return findHelper('RuntimeTypeGeneric');
+  }
+
+  ClassElement get DynamicRuntimeType {
+    return findHelper('DynamicRuntimeType');
+  }
+
   MethodElement get functionTypeTestMetaHelper {
     return findHelper('functionTypeTestMetaHelper');
   }
@@ -259,4 +656,38 @@
   MethodElement get defineProperty {
     return findHelper('defineProperty');
   }
-}
\ No newline at end of file
+
+  Element get startRootIsolate {
+    return find(isolateHelperLibrary, START_ROOT_ISOLATE);
+  }
+
+  Element get currentIsolate {
+    return find(isolateHelperLibrary, '_currentIsolate');
+  }
+
+  Element get callInIsolate {
+    return find(isolateHelperLibrary, '_callInIsolate');
+  }
+
+  Element get findIndexForNativeSubclassType {
+    return findInterceptor('findIndexForNativeSubclassType');
+  }
+
+  Element get convertRtiToRuntimeType {
+    return findHelper('convertRtiToRuntimeType');
+  }
+
+  ClassElement get stackTraceClass {
+    return findHelper('_StackTrace');
+  }
+
+  MethodElement _objectNoSuchMethod;
+
+  MethodElement get objectNoSuchMethod {
+    if (_objectNoSuchMethod == null) {
+      _objectNoSuchMethod =
+          coreClasses.objectClass.lookupLocalMember(Identifiers.noSuchMethod_);
+    }
+    return _objectNoSuchMethod;
+  }
+}
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 90dba81..f25e13b 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -8,6 +8,8 @@
     Identifiers;
 import '../compiler.dart' show
     Compiler;
+import '../core_types.dart' show
+    CoreClasses;
 import '../dart_types.dart' show
     InterfaceType;
 import '../elements/elements.dart' show
@@ -41,249 +43,613 @@
 
   BackendHelpers get helpers => backend.helpers;
 
-  BackendImpact get getRuntimeTypeArgument => new BackendImpact(
-      staticUses: [
-        helpers.getRuntimeTypeArgument,
-        helpers.getTypeArgumentByIndex,
-        helpers.copyTypeArguments]);
+  CoreClasses get coreClasses => compiler.coreClasses;
 
-  BackendImpact get computeSignature => new BackendImpact(
-      staticUses: [
-        helpers.setRuntimeTypeInfo,
-        helpers.getRuntimeTypeInfo,
-        helpers.computeSignature,
-        helpers.getRuntimeTypeArguments],
-      instantiatedClasses: [
-        compiler.listClass]);
+  BackendImpact _getRuntimeTypeArgument;
 
-  BackendImpact get asyncBody => new BackendImpact(
-      staticUses: [
-        helpers.asyncHelper,
-        helpers.syncCompleterConstructor,
-        helpers.streamIteratorConstructor,
-        helpers.wrapBody]);
-
-  BackendImpact get syncStarBody => new BackendImpact(
-      staticUses: [
-        helpers.syncStarIterableConstructor,
-        helpers.endOfIteration,
-        helpers.yieldStar,
-        helpers.syncStarUncaughtError],
-      instantiatedClasses: [
-        helpers.syncStarIterable]);
-
-  BackendImpact get asyncStarBody => new BackendImpact(
-      staticUses: [
-        helpers.asyncStarHelper,
-        helpers.streamOfController,
-        helpers.yieldSingle,
-        helpers.yieldStar,
-        helpers.asyncStarControllerConstructor,
-        helpers.streamIteratorConstructor,
-        helpers.wrapBody],
-      instantiatedClasses: [
-        helpers.asyncStarController]);
-
-  BackendImpact get typeVariableBoundCheck => new BackendImpact(
-      staticUses: [
-        helpers.throwTypeError,
-        helpers.assertIsSubtype]);
-
-  BackendImpact get abstractClassInstantiation => new BackendImpact(
-      staticUses: [
-        helpers.throwAbstractClassInstantiationError],
-      otherImpacts: [
-        needsString('Needed to encode the message.')]);
-
-  BackendImpact get fallThroughError => new BackendImpact(
-      staticUses: [
-        helpers.fallThroughError]);
-
-  BackendImpact get asCheck => new BackendImpact(
-      staticUses: [
-        helpers.throwRuntimeError]);
-
-  BackendImpact get throwNoSuchMethod => new BackendImpact(
-      staticUses: [
-        helpers.throwNoSuchMethod],
-      otherImpacts: [
-        // Also register the types of the arguments passed to this method.
-        needsList(
-            'Needed to encode the arguments for throw NoSuchMethodError.'),
-        needsString(
-            'Needed to encode the name for throw NoSuchMethodError.')]);
-
-  BackendImpact get throwRuntimeError => new BackendImpact(
-      staticUses: [
-        helpers.throwRuntimeError],
-      // Also register the types of the arguments passed to this method.
-      instantiatedClasses: [
-        helpers.compiler.stringClass]);
-
-  BackendImpact get superNoSuchMethod => new BackendImpact(
-      staticUses: [
-        helpers.createInvocationMirror,
-        helpers.compiler.objectClass.lookupLocalMember(
-            Identifiers.noSuchMethod_)],
-      otherImpacts: [
-        needsInt(
-            'Needed to encode the invocation kind of super.noSuchMethod.'),
-        needsList(
-            'Needed to encode the arguments of super.noSuchMethod.'),
-        needsString(
-            'Needed to encode the name of super.noSuchMethod.')]);
-
-  BackendImpact get constantMapLiteral {
-
-    ClassElement find(String name) {
-      return helpers.find(backend.jsHelperLibrary, name);
+  BackendImpact get getRuntimeTypeArgument {
+    if (_getRuntimeTypeArgument == null) {
+      _getRuntimeTypeArgument = new BackendImpact(
+          staticUses: [
+            helpers.getRuntimeTypeArgument,
+            helpers.getTypeArgumentByIndex,
+            helpers.copyTypeArguments]);
     }
-
-    return new BackendImpact(
-      instantiatedClasses: [
-        find(JavaScriptMapConstant.DART_CLASS),
-        find(JavaScriptMapConstant.DART_PROTO_CLASS),
-        find(JavaScriptMapConstant.DART_STRING_CLASS),
-        find(JavaScriptMapConstant.DART_GENERAL_CLASS)]);
+    return _getRuntimeTypeArgument;
   }
 
-  BackendImpact get symbolConstructor => new BackendImpact(
-      staticUses: [
-        helpers.compiler.symbolValidatedConstructor]);
+  BackendImpact _computeSignature;
 
+  BackendImpact get computeSignature {
+    if (_computeSignature == null) {
+      _computeSignature = new BackendImpact(
+          staticUses: [
+            helpers.setRuntimeTypeInfo,
+            helpers.getRuntimeTypeInfo,
+            helpers.computeSignature,
+            helpers.getRuntimeTypeArguments],
+          otherImpacts: [
+            listValues]);
+    }
+    return _computeSignature;
+  }
 
-  BackendImpact get incDecOperation =>
-      needsInt('Needed for the `+ 1` or `- 1` operation of ++/--.');
+  BackendImpact _asyncBody;
+
+  BackendImpact get asyncBody {
+    if (_asyncBody == null) {
+      _asyncBody = new BackendImpact(
+          staticUses: [
+            helpers.asyncHelper,
+            helpers.syncCompleterConstructor,
+            helpers.streamIteratorConstructor,
+            helpers.wrapBody]);
+    }
+    return _asyncBody;
+  }
+
+  BackendImpact _syncStarBody;
+
+  BackendImpact get syncStarBody {
+    if (_syncStarBody == null) {
+      _syncStarBody = new BackendImpact(
+          staticUses: [
+            helpers.syncStarIterableConstructor,
+            helpers.endOfIteration,
+            helpers.yieldStar,
+            helpers.syncStarUncaughtError],
+          instantiatedClasses: [
+            helpers.syncStarIterable]);
+    }
+    return _syncStarBody;
+  }
+
+  BackendImpact _asyncStarBody;
+
+  BackendImpact get asyncStarBody {
+    if (_asyncStarBody == null) {
+      _asyncStarBody = new BackendImpact(
+          staticUses: [
+            helpers.asyncStarHelper,
+            helpers.streamOfController,
+            helpers.yieldSingle,
+            helpers.yieldStar,
+            helpers.asyncStarControllerConstructor,
+            helpers.streamIteratorConstructor,
+            helpers.wrapBody],
+          instantiatedClasses: [
+            helpers.asyncStarController]);
+    }
+    return _asyncStarBody;
+  }
+
+  BackendImpact _typeVariableBoundCheck;
+
+  BackendImpact get typeVariableBoundCheck {
+    if (_typeVariableBoundCheck == null) {
+      _typeVariableBoundCheck = new BackendImpact(
+          staticUses: [
+            helpers.throwTypeError,
+            helpers.assertIsSubtype]);
+    }
+    return _typeVariableBoundCheck;
+  }
+
+  BackendImpact _abstractClassInstantiation;
+
+  BackendImpact get abstractClassInstantiation {
+    if (_abstractClassInstantiation == null) {
+      _abstractClassInstantiation = new BackendImpact(
+          staticUses: [
+            helpers.throwAbstractClassInstantiationError],
+          otherImpacts: [
+            _needsString('Needed to encode the message.')]);
+    }
+    return _abstractClassInstantiation;
+  }
+
+  BackendImpact _fallThroughError;
+
+  BackendImpact get fallThroughError {
+    if (_fallThroughError == null) {
+      _fallThroughError = new BackendImpact(
+          staticUses: [
+            helpers.fallThroughError]);
+    }
+    return _fallThroughError;
+  }
+
+  BackendImpact _asCheck;
+
+  BackendImpact get asCheck {
+    if (_asCheck == null) {
+      _asCheck = new BackendImpact(
+          staticUses: [
+            helpers.throwRuntimeError]);
+    }
+    return _asCheck;
+  }
+
+  BackendImpact _throwNoSuchMethod;
+
+  BackendImpact get throwNoSuchMethod {
+    if (_throwNoSuchMethod == null) {
+      _throwNoSuchMethod = new BackendImpact(
+          staticUses: [
+            helpers.throwNoSuchMethod],
+          otherImpacts: [
+            // Also register the types of the arguments passed to this method.
+            _needsList(
+                'Needed to encode the arguments for throw NoSuchMethodError.'),
+            _needsString(
+                'Needed to encode the name for throw NoSuchMethodError.')]);
+    }
+    return _throwNoSuchMethod;
+  }
+
+  BackendImpact _stringValues;
+
+  BackendImpact get stringValues {
+    if (_stringValues == null) {
+      _stringValues = new BackendImpact(
+          instantiatedClasses: [
+            helpers.jsStringClass]);
+    }
+    return _stringValues;
+  }
+
+  BackendImpact _numValues;
+
+  BackendImpact get numValues {
+    if (_numValues == null) {
+      _numValues = new BackendImpact(
+          instantiatedClasses: [
+            helpers.jsIntClass,
+            helpers.jsPositiveIntClass,
+            helpers.jsUInt32Class,
+            helpers.jsUInt31Class,
+            helpers.jsNumberClass,
+            helpers.jsDoubleClass]);
+    }
+    return _numValues;
+  }
+
+  BackendImpact get intValues => numValues;
+
+  BackendImpact get doubleValues => numValues;
+
+  BackendImpact _boolValues;
+
+  BackendImpact get boolValues {
+    if (_boolValues == null) {
+      _boolValues = new BackendImpact(
+          instantiatedClasses: [
+            helpers.jsBoolClass]);
+    }
+    return _boolValues;
+  }
+
+  BackendImpact _nullValue;
+
+  BackendImpact get nullValue {
+    if (_nullValue == null) {
+      _nullValue = new BackendImpact(
+          instantiatedClasses: [
+            helpers.jsNullClass]);
+    }
+    return _nullValue;
+  }
+
+  BackendImpact _listValues;
+
+  BackendImpact get listValues {
+    if (_listValues == null) {
+      _listValues = new BackendImpact(
+          instantiatedClasses: [
+            helpers.jsArrayClass,
+            helpers.jsMutableArrayClass,
+            helpers.jsFixedArrayClass,
+            helpers.jsExtendableArrayClass,
+            helpers.jsUnmodifiableArrayClass]);
+    }
+    return _listValues;
+  }
+
+  BackendImpact _throwRuntimeError;
+
+  BackendImpact get throwRuntimeError {
+    if (_throwRuntimeError == null) {
+      _throwRuntimeError = new BackendImpact(
+          staticUses: [
+            helpers.throwRuntimeError],
+          otherImpacts: [
+            // Also register the types of the arguments passed to this method.
+            stringValues]);
+    }
+    return _throwRuntimeError;
+  }
+
+  BackendImpact _superNoSuchMethod;
+
+  BackendImpact get superNoSuchMethod {
+    if (_superNoSuchMethod == null) {
+      _superNoSuchMethod = new BackendImpact(
+          staticUses: [
+            helpers.createInvocationMirror,
+            helpers.objectNoSuchMethod],
+          otherImpacts: [
+            _needsInt(
+                'Needed to encode the invocation kind of super.noSuchMethod.'),
+            _needsList(
+                'Needed to encode the arguments of super.noSuchMethod.'),
+            _needsString(
+                'Needed to encode the name of super.noSuchMethod.')]);
+    }
+    return _superNoSuchMethod;
+  }
+
+  BackendImpact _constantMapLiteral;
+
+  BackendImpact get constantMapLiteral {
+    if (_constantMapLiteral == null) {
+
+      ClassElement find(String name) {
+        return helpers.find(helpers.jsHelperLibrary, name);
+      }
+
+      _constantMapLiteral = new BackendImpact(
+          instantiatedClasses: [
+            find(JavaScriptMapConstant.DART_CLASS),
+            find(JavaScriptMapConstant.DART_PROTO_CLASS),
+            find(JavaScriptMapConstant.DART_STRING_CLASS),
+            find(JavaScriptMapConstant.DART_GENERAL_CLASS)]);
+    }
+    return _constantMapLiteral;
+  }
+
+  BackendImpact _symbolConstructor;
+
+  BackendImpact get symbolConstructor {
+    if (_symbolConstructor == null) {
+      _symbolConstructor = new BackendImpact(
+        staticUses: [
+          helpers.compiler.symbolValidatedConstructor]);
+    }
+    return _symbolConstructor;
+  }
+
+  BackendImpact _constSymbol;
+
+  BackendImpact get constSymbol {
+    if (_constSymbol == null) {
+      _constSymbol = new BackendImpact(
+        instantiatedClasses: [
+          coreClasses.symbolClass],
+        staticUses: [
+          compiler.symbolConstructor.declaration]);
+    }
+    return _constSymbol;
+  }
+
+  BackendImpact _incDecOperation;
+
+  BackendImpact get incDecOperation {
+    if (_incDecOperation == null) {
+      _incDecOperation =
+          _needsInt('Needed for the `+ 1` or `- 1` operation of ++/--.');
+    }
+    return _incDecOperation;
+  }
 
   /// Helper for registering that `int` is needed.
-  BackendImpact needsInt(String reason) {
+  BackendImpact _needsInt(String reason) {
     // TODO(johnniwinther): Register [reason] for use in dump-info.
-    return new BackendImpact(
-        instantiatedClasses: [helpers.compiler.intClass]);
+    return intValues;
   }
 
   /// Helper for registering that `List` is needed.
-  BackendImpact needsList(String reason) {
+  BackendImpact _needsList(String reason) {
     // TODO(johnniwinther): Register [reason] for use in dump-info.
-    return new BackendImpact(
-        instantiatedClasses: [helpers.compiler.listClass]);
+    return listValues;
   }
 
   /// Helper for registering that `String` is needed.
-  BackendImpact needsString(String reason) {
+  BackendImpact _needsString(String reason) {
     // TODO(johnniwinther): Register [reason] for use in dump-info.
-    return new BackendImpact(
-        instantiatedClasses: [
-          helpers.compiler.stringClass]);
+    return stringValues;
   }
 
-  BackendImpact get assertWithoutMessage => new BackendImpact(
-      staticUses: [
-        helpers.assertHelper]);
+  BackendImpact _assertWithoutMessage;
 
-  BackendImpact get assertWithMessage => new BackendImpact(
-      staticUses: [
-        helpers.assertTest,
-        helpers.assertThrow]);
+  BackendImpact get assertWithoutMessage {
+    if (_assertWithoutMessage == null) {
+      _assertWithoutMessage = new BackendImpact(
+          staticUses: [
+            helpers.assertHelper]);
+    }
+    return _assertWithoutMessage;
+  }
 
-  BackendImpact get asyncForIn => new BackendImpact(
-      staticUses: [
-        helpers.streamIteratorConstructor]);
+  BackendImpact _assertWithMessage;
 
-  BackendImpact get stringInterpolation => new BackendImpact(
-      staticUses: [
-        helpers.stringInterpolationHelper]);
+  BackendImpact get assertWithMessage {
+    if (_assertWithMessage == null) {
+      _assertWithMessage = new BackendImpact(
+          staticUses: [
+            helpers.assertTest,
+            helpers.assertThrow]);
+    }
+    return _assertWithMessage;
+  }
 
-  BackendImpact get catchStatement => new BackendImpact(
-      staticUses: [
-        helpers.exceptionUnwrapper],
-      instantiatedClasses: [
-        backend.jsPlainJavaScriptObjectClass,
-        backend.jsUnknownJavaScriptObjectClass]);
+  BackendImpact _asyncForIn;
 
-  BackendImpact get throwExpression => new BackendImpact(
-      // We don't know ahead of time whether we will need the throw in a
-      // statement context or an expression context, so we register both
-      // here, even though we may not need the throwExpression helper.
-      staticUses: [
-        helpers.wrapExceptionHelper,
-        helpers.throwExpressionHelper]);
+  BackendImpact get asyncForIn {
+    if (_asyncForIn == null) {
+      _asyncForIn = new BackendImpact(
+          staticUses: [
+            helpers.streamIteratorConstructor]);
+    }
+    return _asyncForIn;
+  }
 
-  BackendImpact get lazyField => new BackendImpact(
-      staticUses: [
-        helpers.cyclicThrowHelper]);
+  BackendImpact _stringInterpolation;
 
-  BackendImpact get typeLiteral => new BackendImpact(
-      instantiatedClasses: [
-        backend.typeImplementation],
-      staticUses: [
-        helpers.createRuntimeType]);
+  BackendImpact get stringInterpolation {
+    if (_stringInterpolation == null) {
+      _stringInterpolation = new BackendImpact(
+          staticUses: [
+            helpers.stringInterpolationHelper],
+          otherImpacts: [
+            _needsString('Strings are created.')]);
+    }
+    return _stringInterpolation;
+  }
 
-  BackendImpact get stackTraceInCatch => new BackendImpact(
-      staticUses: [
-        helpers.traceFromException]);
+  BackendImpact _stringJuxtaposition;
 
-  BackendImpact get syncForIn => new BackendImpact(
-      // The SSA builder recognizes certain for-in loops and can generate calls
-      // to throwConcurrentModificationError.
-      staticUses: [
-        helpers.checkConcurrentModificationError]);
+  BackendImpact get stringJuxtaposition {
+    if (_stringJuxtaposition == null) {
+      _stringJuxtaposition = _needsString('String.concat is used.');
+    }
+    return _stringJuxtaposition;
+  }
 
-  BackendImpact get typeVariableExpression => new BackendImpact(
-      staticUses: [
-        helpers.setRuntimeTypeInfo,
-        helpers.getRuntimeTypeInfo,
-        helpers.runtimeTypeToString,
-        helpers.createRuntimeType],
-      instantiatedClasses: [
-        helpers.compiler.listClass],
-      otherImpacts: [
-        getRuntimeTypeArgument,
-        needsInt('Needed for accessing a type variable literal on this.')]);
+  BackendImpact get nullLiteral => nullValue;
 
-  BackendImpact get typeCheck => new BackendImpact(
-      instantiatedClasses: [
-        helpers.compiler.boolClass]);
+  BackendImpact get boolLiteral => boolValues;
 
-  BackendImpact get checkedModeTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.throwRuntimeError]);
+  BackendImpact get intLiteral => intValues;
 
-  BackendImpact get malformedTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.throwTypeError]);
+  BackendImpact get doubleLiteral => doubleValues;
 
-  BackendImpact get genericTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.checkSubtype,
-        // TODO(johnniwinther): Investigate why this is needed.
-        helpers.setRuntimeTypeInfo,
-        helpers.getRuntimeTypeInfo],
-      instantiatedClasses: [
-        helpers.compiler.listClass],
-      otherImpacts: [
-        getRuntimeTypeArgument]);
+  BackendImpact get stringLiteral => stringValues;
 
-  BackendImpact get genericCheckedModeTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.assertSubtype]);
+  BackendImpact _catchStatement;
 
-  BackendImpact get typeVariableTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.checkSubtypeOfRuntimeType]);
+  BackendImpact get catchStatement {
+    if (_catchStatement == null) {
+      _catchStatement = new BackendImpact(
+          staticUses: [
+            helpers.exceptionUnwrapper],
+          instantiatedClasses: [
+            helpers.jsPlainJavaScriptObjectClass,
+            helpers.jsUnknownJavaScriptObjectClass]);
+    }
+    return _catchStatement;
+  }
 
-  BackendImpact get typeVariableCheckedModeTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.assertSubtypeOfRuntimeType]);
+  BackendImpact _throwExpression;
 
-  BackendImpact get functionTypeCheck => new BackendImpact(
-      staticUses: [
-        helpers.functionTypeTestMetaHelper]);
+  BackendImpact get throwExpression {
+    if (_throwExpression == null) {
+      _throwExpression = new BackendImpact(
+          // We don't know ahead of time whether we will need the throw in a
+          // statement context or an expression context, so we register both
+          // here, even though we may not need the throwExpression helper.
+          staticUses: [
+            helpers.wrapExceptionHelper,
+            helpers.throwExpressionHelper]);
+    }
+    return _throwExpression;
+  }
 
-  BackendImpact get nativeTypeCheck => new BackendImpact(
-      staticUses: [
-        // We will neeed to add the "$is" and "$as" properties on the
-        // JavaScript object prototype, so we make sure
-        // [:defineProperty:] is compiled.
-        helpers.defineProperty]);
+  BackendImpact _lazyField;
+
+  BackendImpact get lazyField {
+    if (_lazyField == null) {
+      _lazyField = new BackendImpact(
+          staticUses: [
+            helpers.cyclicThrowHelper]);
+    }
+    return _lazyField;
+  }
+
+  BackendImpact _typeLiteral;
+
+  BackendImpact get typeLiteral {
+    if (_typeLiteral == null) {
+      _typeLiteral = new BackendImpact(
+          instantiatedClasses: [
+            backend.typeImplementation],
+          staticUses: [
+            helpers.createRuntimeType]);
+    }
+    return _typeLiteral;
+  }
+
+  BackendImpact _stackTraceInCatch;
+
+  BackendImpact get stackTraceInCatch {
+    if (_stackTraceInCatch == null) {
+      _stackTraceInCatch = new BackendImpact(
+          instantiatedClasses: [
+            helpers.stackTraceClass],
+          staticUses: [
+            helpers.traceFromException]);
+    }
+    return _stackTraceInCatch;
+  }
+
+  BackendImpact _syncForIn;
+
+  BackendImpact get syncForIn {
+    if (_syncForIn == null) {
+      _syncForIn = new BackendImpact(
+          // The SSA builder recognizes certain for-in loops and can generate
+          // calls to throwConcurrentModificationError.
+          staticUses: [
+            helpers.checkConcurrentModificationError]);
+    }
+    return _syncForIn;
+  }
+
+  BackendImpact _typeVariableExpression;
+
+  BackendImpact get typeVariableExpression {
+    if (_typeVariableExpression == null) {
+      _typeVariableExpression = new BackendImpact(
+          staticUses: [
+            helpers.setRuntimeTypeInfo,
+            helpers.getRuntimeTypeInfo,
+            helpers.runtimeTypeToString,
+            helpers.createRuntimeType],
+          otherImpacts: [
+            listValues,
+            getRuntimeTypeArgument,
+            _needsInt('Needed for accessing a type variable literal on this.')
+          ]);
+    }
+    return _typeVariableExpression;
+  }
+
+  BackendImpact _typeCheck;
+
+  BackendImpact get typeCheck {
+    if (_typeCheck == null) {
+      _typeCheck = new BackendImpact(
+          otherImpacts: [
+            boolValues]);
+    }
+    return _typeCheck;
+  }
+
+  BackendImpact _checkedModeTypeCheck;
+
+  BackendImpact get checkedModeTypeCheck {
+    if (_checkedModeTypeCheck == null) {
+      _checkedModeTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.throwRuntimeError]);
+    }
+    return _checkedModeTypeCheck;
+  }
+
+  BackendImpact _malformedTypeCheck;
+
+  BackendImpact get malformedTypeCheck {
+    if (_malformedTypeCheck == null) {
+      _malformedTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.throwTypeError]);
+    }
+    return _malformedTypeCheck;
+  }
+
+  BackendImpact _genericTypeCheck;
+
+  BackendImpact get genericTypeCheck {
+    if (_genericTypeCheck == null) {
+      _genericTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.checkSubtype,
+            // TODO(johnniwinther): Investigate why this is needed.
+            helpers.setRuntimeTypeInfo,
+            helpers.getRuntimeTypeInfo],
+          otherImpacts: [
+            listValues,
+            getRuntimeTypeArgument]);
+    }
+    return _genericTypeCheck;
+  }
+
+  BackendImpact _genericIsCheck;
+
+  BackendImpact get genericIsCheck {
+    if (_genericIsCheck == null) {
+      _genericIsCheck = new BackendImpact(
+          otherImpacts: [
+            intValues]);
+    }
+    return _genericIsCheck;
+  }
+
+  BackendImpact _genericCheckedModeTypeCheck;
+
+  BackendImpact get genericCheckedModeTypeCheck {
+    if (_genericCheckedModeTypeCheck == null) {
+      _genericCheckedModeTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.assertSubtype]);
+    }
+    return _genericCheckedModeTypeCheck;
+  }
+
+  BackendImpact _typeVariableTypeCheck;
+
+  BackendImpact get typeVariableTypeCheck {
+    if (_typeVariableTypeCheck == null) {
+      _typeVariableTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.checkSubtypeOfRuntimeType]);
+    }
+    return _typeVariableTypeCheck;
+  }
+
+  BackendImpact _typeVariableCheckedModeTypeCheck;
+
+  BackendImpact get typeVariableCheckedModeTypeCheck {
+    if (_typeVariableCheckedModeTypeCheck == null) {
+      _typeVariableCheckedModeTypeCheck = new BackendImpact(
+        staticUses: [
+          helpers.assertSubtypeOfRuntimeType]);
+    }
+    return _typeVariableCheckedModeTypeCheck;
+  }
+
+  BackendImpact _functionTypeCheck;
+
+  BackendImpact get functionTypeCheck {
+    if (_functionTypeCheck == null) {
+      _functionTypeCheck = new BackendImpact(
+          staticUses: [
+            helpers.functionTypeTestMetaHelper]);
+    }
+    return _functionTypeCheck;
+  }
+
+  BackendImpact _nativeTypeCheck;
+
+  BackendImpact get nativeTypeCheck {
+    if (_nativeTypeCheck == null) {
+      _nativeTypeCheck = new BackendImpact(
+          staticUses: [
+            // We will neeed to add the "$is" and "$as" properties on the
+            // JavaScript object prototype, so we make sure
+            // [:defineProperty:] is compiled.
+            helpers.defineProperty]);
+    }
+    return _nativeTypeCheck;
+  }
+
+  BackendImpact _closure;
+
+  BackendImpact get closure {
+    if (_closure == null) {
+      _closure = new BackendImpact(
+          instantiatedClasses: [
+            coreClasses.functionClass]);
+    }
+    return _closure;
+  }
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
index 003ab69..a40caad 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -9,21 +9,24 @@
 
   const CheckedModeHelper(String this.name);
 
-  Element getElement(Compiler compiler) {
+  StaticUse getStaticUse(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    return backend.findHelper(name);
+    return new StaticUse.staticInvoke(
+        backend.helpers.findHelper(name), callStructure);
   }
 
+  CallStructure get callStructure => CallStructure.ONE_ARG;
+
   jsAst.Expression generateCall(SsaCodeGenerator codegen,
                                 HTypeConversion node) {
-    Element helperElement = getElement(codegen.compiler);
-    codegen.registry.registerStaticUse(helperElement);
+    StaticUse staticUse = getStaticUse(codegen.compiler);
+    codegen.registry.registerStaticUse(staticUse);
     List<jsAst.Expression> arguments = <jsAst.Expression>[];
     codegen.use(node.checkedInput);
     arguments.add(codegen.pop());
     generateAdditionalArguments(codegen, node, arguments);
     jsAst.Expression helper =
-        codegen.backend.emitter.staticFunctionAccess(helperElement);
+        codegen.backend.emitter.staticFunctionAccess(staticUse.element);
     return new jsAst.Call(helper, arguments);
   }
 
@@ -73,6 +76,8 @@
 class MalformedCheckedModeHelper extends CheckedModeHelper {
   const MalformedCheckedModeHelper(String name) : super(name);
 
+  CallStructure get callStructure => CallStructure.TWO_ARGS;
+
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
@@ -84,6 +89,8 @@
 class PropertyCheckedModeHelper extends CheckedModeHelper {
   const PropertyCheckedModeHelper(String name) : super(name);
 
+  CallStructure get callStructure => CallStructure.TWO_ARGS;
+
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
@@ -96,6 +103,8 @@
 class TypeVariableCheckedModeHelper extends CheckedModeHelper {
   const TypeVariableCheckedModeHelper(String name) : super(name);
 
+  CallStructure get callStructure => CallStructure.TWO_ARGS;
+
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
@@ -108,6 +117,8 @@
 class SubtypeCheckedModeHelper extends CheckedModeHelper {
   const SubtypeCheckedModeHelper(String name) : super(name);
 
+  CallStructure get callStructure => const CallStructure.unnamed(4);
+
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index 92852b7..bc8ed93 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -20,13 +20,18 @@
 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
 import '../../tree_ir/tree_ir_nodes.dart' show
     BuiltinMethod,
-    BuiltinOperator;
+    BuiltinOperator,
+    isCompoundableOperator;
 import '../../types/types.dart' show
     TypeMask;
+import '../../universe/call_structure.dart' show
+    CallStructure;
 import '../../universe/selector.dart' show
     Selector;
-import '../../universe/universe.dart' show
-    UniverseSelector;
+import '../../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
 import '../../util/maplet.dart';
 
 class CodegenBailout {
@@ -64,7 +69,19 @@
   final tree_ir.FallthroughStack shortContinue =
       new tree_ir.FallthroughStack();
 
-  Set<tree_ir.Label> usedLabels = new Set<tree_ir.Label>();
+  /// When the top element is true, [Unreachable] statements will be emitted
+  /// as [Return]s, otherwise they are emitted as empty because they are
+  /// followed by the end of the method.
+  ///
+  /// Note on why the [fallthrough] stack should not be used for this:
+  /// Ordinary statements may choose whether to use the [fallthrough] target,
+  /// and the choice to do so may disable an optimization in [visitIf].
+  /// But omitting an unreachable 'return' should have lower priority than
+  /// the optimizations in [visitIf], so [visitIf] will instead tell the
+  /// [Unreachable] statements whether they may use fallthrough or not.
+  List<bool> emitUnreachableAsReturn = <bool>[false];
+
+  final Map<tree_ir.Label, String> labelNames = <tree_ir.Label, String>{};
 
   List<js.Statement> accumulator = new List<js.Statement>();
 
@@ -72,6 +89,7 @@
 
   /// Generates JavaScript code for the body of [function].
   js.Fun buildFunction(tree_ir.FunctionDefinition function) {
+    registerDefaultParameterValues(function.element);
     currentFunction = function.element;
     visitStatement(function.body);
 
@@ -235,7 +253,17 @@
   js.Expression buildStaticInvoke(Element target,
                                   List<js.Expression> arguments,
                                   {SourceInformation sourceInformation}) {
-    registry.registerStaticInvocation(target.declaration);
+    if (target.isConstructor) {
+      // TODO(johnniwinther): Avoid dependency on [isGenerativeConstructor] by
+      // using backend-specific [StatisUse] classes.
+      registry.registerStaticUse(
+          new StaticUse.constructorInvoke(target.declaration,
+              new CallStructure.unnamed(arguments.length)));
+    } else {
+      registry.registerStaticUse(
+          new StaticUse.staticInvoke(target.declaration,
+              new CallStructure.unnamed(arguments.length)));
+    }
     js.Expression elementAccess = glue.staticFunctionAccess(target);
     return new js.Call(elementAccess, arguments,
         sourceInformation: sourceInformation);
@@ -245,35 +273,28 @@
   js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) {
     if (node.constant != null) return giveup(node);
 
-    registry.registerInstantiatedType(node.type);
+    registry.registerInstantiation(node.type);
     FunctionElement target = node.target;
     List<js.Expression> arguments = visitExpressionList(node.arguments);
     return buildStaticInvoke(
-        target, arguments, sourceInformation: node.sourceInformation);
+        target,
+        arguments,
+        sourceInformation: node.sourceInformation);
   }
 
-  void registerMethodInvoke(tree_ir.InvokeMethod node) {
-    Selector selector = node.selector;
-    TypeMask mask = node.mask;
-    if (selector.isGetter) {
-      registry.registerDynamicGetter(new UniverseSelector(selector, mask));
-    } else if (selector.isSetter) {
-      registry.registerDynamicSetter(new UniverseSelector(selector, mask));
-    } else {
-      assert(invariant(CURRENT_ELEMENT_SPANNABLE,
-          selector.isCall || selector.isOperator ||
-          selector.isIndex || selector.isIndexSet,
-          message: 'unexpected kind ${selector.kind}'));
+  void registerMethodInvoke(Selector selector, TypeMask receiverType) {
+    registry.registerDynamicUse(new DynamicUse(selector, receiverType));
+    if (!selector.isGetter && !selector.isSetter) {
       // TODO(sigurdm): We should find a better place to register the call.
       Selector call = new Selector.callClosureFrom(selector);
-      registry.registerDynamicInvocation(new UniverseSelector(call, null));
-      registry.registerDynamicInvocation(new UniverseSelector(selector, mask));
+      registry.registerDynamicUse(new DynamicUse(call, null));
     }
   }
 
   @override
   js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) {
-    registerMethodInvoke(node);
+    TypeMask mask = glue.extendMaskIfReachesAll(node.selector, node.mask);
+    registerMethodInvoke(node.selector, mask);
     return js.propertyCall(visitExpression(node.receiver),
                            glue.invocationName(node.selector),
                            visitExpressionList(node.arguments))
@@ -290,8 +311,20 @@
 
   @override
   js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) {
-    registry.registerDirectInvocation(node.target.declaration);
+    if (node.isTearOff) {
+      // If this is a tear-off, register the fact that a tear-off closure
+      // will be created, and that this tear-off must bypass ordinary
+      // dispatch to ensure the super method is invoked.
+      registry.registerStaticUse(new StaticUse.staticInvoke(
+          glue.closureFromTearOff, new CallStructure.unnamed(
+            glue.closureFromTearOff.parameters.length)));
+      registry.registerStaticUse(new StaticUse.superTearOff(node.target));
+    }
     if (node.target is ConstructorBodyElement) {
+      registry.registerStaticUse(
+          new StaticUse.constructorBodyInvoke(
+              node.target.declaration,
+              new CallStructure.unnamed(node.arguments.length)));
       // A constructor body cannot be overriden or intercepted, so we can
       // use the short form for this invocation.
       return js.js('#.#(#)',
@@ -300,6 +333,10 @@
            visitExpressionList(node.arguments)])
           .withSourceInformation(node.sourceInformation);
     }
+    registry.registerStaticUse(
+        new StaticUse.superInvoke(
+            node.target.declaration,
+            new CallStructure.unnamed(node.arguments.length)));
     return js.js('#.#.call(#, #)',
         [glue.prototypeAccess(node.target.enclosingClass),
          glue.invocationName(node.selector),
@@ -309,6 +346,17 @@
   }
 
   @override
+  js.Expression visitOneShotInterceptor(tree_ir.OneShotInterceptor node) {
+    registerMethodInvoke(node.selector, node.mask);
+    registry.registerUseInterceptor();
+    return js.js('#.#(#)',
+        [glue.getInterceptorLibrary(),
+         glue.registerOneShotInterceptor(node.selector),
+         visitExpressionList(node.arguments)])
+        .withSourceInformation(node.sourceInformation);
+  }
+
+  @override
   js.Expression visitLiteralList(tree_ir.LiteralList node) {
     registry.registerInstantiatedClass(glue.listClass);
     List<js.Expression> entries = visitExpressionList(node.values);
@@ -353,13 +401,26 @@
     return new js.This();
   }
 
+  /// Ensure that 'instanceof' checks may be performed against [class_].
+  ///
+  /// Even if the class is never instantiated, a JS constructor must be emitted
+  /// so the 'instanceof' expression does not throw an exception at runtime.
+  ///
+  /// It does not help to ask the class world if the class is instantiated,
+  /// because it could still get tree-shaken if it is unused after optimization.
+  void registerInstanceofCheck(ClassElement class_) {
+    // TODO(asgerf): This is the only hook we have to ensure the JS constructor
+    //   gets emitted, but it is very imprecise. We should do better.
+    registry.registerInstantiatedClass(class_);
+  }
+
   @override
   js.Expression visitTypeOperator(tree_ir.TypeOperator node) {
     js.Expression value = visitExpression(node.value);
     List<js.Expression> typeArguments = visitExpressionList(node.typeArguments);
     DartType type = node.type;
     if (type is InterfaceType) {
-      glue.registerIsCheck(type, registry);
+      registry.registerTypeUse(new TypeUse.isCheck(type));
       ClassElement clazz = type.element;
 
       if (glue.isStringClass(clazz)) {
@@ -372,6 +433,11 @@
           return js.js(r'typeof # === "boolean"', <js.Expression>[value]);
         }
         // TODO(sra): Implement fast cast via calling 'boolTypeCast'.
+      } else if (node.isTypeTest &&
+                 node.typeArguments.isEmpty &&
+                 glue.mayGenerateInstanceofCheck(type)) {
+        registerInstanceofCheck(clazz);
+        return js.js('# instanceof #', [value, glue.constructorAccess(clazz)]);
       }
 
       // The helper we use needs the JSArray class to exist, but for some
@@ -404,7 +470,7 @@
           function,
           <js.Expression>[value, isT, typeArgumentArray, asT]);
     } else if (type is TypeVariableType || type is FunctionType) {
-      glue.registerIsCheck(type, registry);
+      registry.registerTypeUse(new TypeUse.isCheck(type));
 
       Element function = node.isTypeTest
           ? glue.getCheckSubtypeOfRuntimeType()
@@ -425,7 +491,8 @@
     js.Expression object = visitExpression(node.object);
     DartType dartType = node.dartType;
     assert(dartType.isInterfaceType);
-    glue.registerIsCheck(dartType, registry);
+    registry.registerTypeUse(new TypeUse.isCheck(dartType));
+    //glue.registerIsCheck(dartType, registry);
     js.Expression property = glue.getTypeTestTag(dartType);
     return js.js(r'#.#', [object, property]);
   }
@@ -439,11 +506,67 @@
     return new js.VariableUse(getVariableName(variable));
   }
 
+  /// Returns the JS operator for the given built-in operator for use in a
+  /// compound assignment (not including the '=' sign).
+  String getAsCompoundOperator(BuiltinOperator operator) {
+    switch (operator) {
+      case BuiltinOperator.NumAdd:
+      case BuiltinOperator.StringConcatenate:
+        return '+';
+      case BuiltinOperator.NumSubtract:
+        return '-';
+      case BuiltinOperator.NumMultiply:
+        return '*';
+      case BuiltinOperator.NumDivide:
+        return '/';
+      case BuiltinOperator.NumRemainder:
+        return '%';
+      default:
+        throw 'Not a compoundable operator: $operator';
+    }
+  }
+
+  bool isCompoundableBuiltin(tree_ir.Expression exp) {
+    return exp is tree_ir.ApplyBuiltinOperator &&
+           exp.arguments.length == 2 &&
+           isCompoundableOperator(exp.operator);
+  }
+
+  bool isOneConstant(tree_ir.Expression exp) {
+    return exp is tree_ir.Constant && exp.value.isOne;
+  }
+
+  js.Expression makeAssignment(
+      js.Expression leftHand,
+      tree_ir.Expression value,
+      {BuiltinOperator compound}) {
+    if (isOneConstant(value)) {
+      if (compound == BuiltinOperator.NumAdd) {
+        return new js.Prefix('++', leftHand);
+      }
+      if (compound == BuiltinOperator.NumSubtract) {
+        return new js.Prefix('--', leftHand);
+      }
+    }
+    if (compound != null) {
+      return new js.Assignment.compound(leftHand,
+          getAsCompoundOperator(compound), visitExpression(value));
+    }
+    return new js.Assignment(leftHand, visitExpression(value));
+  }
+
   @override
   js.Expression visitAssign(tree_ir.Assign node) {
-    return new js.Assignment(
-        buildVariableAccess(node.variable),
-        visitExpression(node.value));
+    js.Expression variable = buildVariableAccess(node.variable);
+    if (isCompoundableBuiltin(node.value)) {
+      tree_ir.ApplyBuiltinOperator rhs = node.value;
+      tree_ir.Expression left = rhs.arguments[0];
+      tree_ir.Expression right = rhs.arguments[1];
+      if (left is tree_ir.VariableUse && left.variable == node.variable) {
+        return makeAssignment(variable, right, compound: rhs.operator);
+      }
+    }
+    return makeAssignment(variable, node.value);
   }
 
   @override
@@ -458,8 +581,7 @@
       shortContinue.use();
       accumulator.add(new js.Continue(null));
     } else {
-      usedLabels.add(node.target);
-      accumulator.add(new js.Continue(node.target.name));
+      accumulator.add(new js.Continue(makeLabel(node.target)));
     }
   }
 
@@ -470,6 +592,13 @@
            other is tree_ir.Break && node.target == other.target;
   }
 
+  /// True if the given break is equivalent to an unlabeled continue.
+  bool isShortContinue(tree_ir.Break node) {
+    tree_ir.Statement next = node.target.binding.next;
+    return next is tree_ir.Continue &&
+           next.target.binding == shortContinue.target;
+  }
+
   @override
   void visitBreak(tree_ir.Break node) {
     if (isEffectiveBreakTarget(node, fallthrough.target)) {
@@ -479,24 +608,45 @@
       // Unlabeled break to the break target or to an equivalent break.
       shortBreak.use();
       accumulator.add(new js.Break(null));
+    } else if (isShortContinue(node)) {
+      // An unlabeled continue is better than a labeled break.
+      shortContinue.use();
+      accumulator.add(new js.Continue(null));
     } else {
-      usedLabels.add(node.target);
-      accumulator.add(new js.Break(node.target.name));
+      accumulator.add(new js.Break(makeLabel(node.target)));
     }
   }
 
   @override
   void visitExpressionStatement(tree_ir.ExpressionStatement node) {
-    accumulator.add(new js.ExpressionStatement(
-        visitExpression(node.expression)));
-    visitStatement(node.next);
+    js.Expression exp = visitExpression(node.expression);
+    if (node.next is tree_ir.Unreachable && emitUnreachableAsReturn.last) {
+      // Emit as 'return exp' to assist local analysis in the VM.
+      accumulator.add(new js.Return(exp));
+    } else {
+      accumulator.add(new js.ExpressionStatement(exp));
+      visitStatement(node.next);
+    }
+  }
+
+  bool isNullReturn(tree_ir.Statement node) {
+    return node is tree_ir.Return && isNull(node.value);
+  }
+
+  bool isEndOfMethod(tree_ir.Statement node) {
+    return isNullReturn(node) ||
+           node is tree_ir.Break && isNullReturn(node.target.binding.next);
   }
 
   @override
   void visitIf(tree_ir.If node) {
     js.Expression condition = visitExpression(node.condition);
     int usesBefore = fallthrough.useCount;
+    // Unless the 'else' part ends the method. make sure to terminate any
+    // uncompletable code paths in the 'then' part.
+    emitUnreachableAsReturn.add(!isEndOfMethod(node.elseStatement));
     js.Statement thenBody = buildBodyStatement(node.thenStatement);
+    emitUnreachableAsReturn.removeLast();
     bool thenHasFallthrough = (fallthrough.useCount > usesBefore);
     if (thenHasFallthrough) {
       js.Statement elseBody = buildBodyStatement(node.elseStatement);
@@ -518,13 +668,18 @@
     visitStatement(node.next);
   }
 
+  /// Creates a name for [label] if it does not already have one.
+  ///
+  /// This also marks the label as being used.
+  String makeLabel(tree_ir.Label label) {
+    return labelNames.putIfAbsent(label, () => 'L${labelNames.length}');
+  }
+
   /// Wraps a node in a labeled statement unless the label is unused.
   js.Statement insertLabel(tree_ir.Label label, js.Statement node) {
-    if (usedLabels.remove(label)) {
-      return new js.LabeledStatement(label.name, node);
-    } else {
-      return node;
-    }
+    String name = labelNames[label];
+    if (name == null) return node; // Label is unused.
+    return new js.LabeledStatement(name, node);
   }
 
   /// Returns the current [accumulator] wrapped in a block if neccessary.
@@ -567,7 +722,9 @@
     shortBreak.push(node.next);
     shortContinue.push(node);
     fallthrough.push(node);
+    emitUnreachableAsReturn.add(true);
     js.Statement body = buildBodyStatement(node.body);
+    emitUnreachableAsReturn.removeLast();
     fallthrough.pop();
     shortContinue.pop();
     shortBreak.pop();
@@ -597,7 +754,9 @@
     shortBreak.push(fallthrough.target);
     shortContinue.push(node);
     fallthrough.push(node);
+    emitUnreachableAsReturn.add(true);
     js.Statement jsBody = buildBodyStatement(node.body);
+    emitUnreachableAsReturn.removeLast();
     fallthrough.pop();
     shortContinue.pop();
     if (shortBreak.useCount > 0) {
@@ -630,14 +789,11 @@
   }
 
   @override
-  void visitRethrow(tree_ir.Rethrow node) {
-    glue.reportInternalError('rethrow seen in JavaScript output');
-  }
-
-  @override
   void visitUnreachable(tree_ir.Unreachable node) {
-    // Output nothing.
-    // TODO(asgerf): Emit a throw/return to assist local analysis in the VM?
+    if (emitUnreachableAsReturn.last) {
+      // Emit a return to assist local analysis in the VM.
+      accumulator.add(new js.Return());
+    }
   }
 
   @override
@@ -663,7 +819,7 @@
     //               carry a DartType so we can register the instantiated type
     //               with its type arguments. Otherwise dataflow analysis is
     //               needed to reconstruct the instantiated type.
-    registry.registerInstantiatedClass(classElement);
+    registry.registerInstantiation(classElement.rawType);
     if (classElement is ClosureClassElement) {
       registry.registerInstantiatedClosure(classElement.methodElement);
     }
@@ -704,9 +860,14 @@
 
   @override
   js.Expression visitInterceptor(tree_ir.Interceptor node) {
-    glue.registerUseInterceptorInCodegen();
-    registry.registerSpecializedGetInterceptor(node.interceptedClasses);
-    js.Name helperName = glue.getInterceptorName(node.interceptedClasses);
+    registry.registerUseInterceptor();
+    // Default to all intercepted classes if they have not been computed.
+    // This is to ensure we can run codegen without prior optimization passes.
+    Set<ClassElement> interceptedClasses = node.interceptedClasses.isEmpty
+        ? glue.interceptedClasses
+        : node.interceptedClasses;
+    registry.registerSpecializedGetInterceptor(interceptedClasses);
+    js.Name helperName = glue.getInterceptorName(interceptedClasses);
     js.Expression globalHolder = glue.getInterceptorLibrary();
     return js.js('#.#(#)',
         [globalHolder, helperName, visitExpression(node.input)])
@@ -715,20 +876,20 @@
 
   @override
   js.Expression visitGetField(tree_ir.GetField node) {
-    registry.registerFieldGetter(node.field);
+    registry.registerStaticUse(new StaticUse.fieldGet(node.field));
     return new js.PropertyAccess(
         visitExpression(node.object),
         glue.instanceFieldPropertyName(node.field));
   }
 
   @override
-  js.Assignment visitSetField(tree_ir.SetField node) {
-    registry.registerFieldSetter(node.field);
+  js.Expression visitSetField(tree_ir.SetField node) {
+    registry.registerStaticUse(new StaticUse.fieldSet(node.field));
     js.PropertyAccess field =
         new js.PropertyAccess(
             visitExpression(node.object),
             glue.instanceFieldPropertyName(node.field));
-    return new js.Assignment(field, visitExpression(node.value));
+    return makeAssignment(field, node.value, compound: node.compound);
   }
 
   @override
@@ -736,25 +897,29 @@
     assert(node.element is FieldElement || node.element is FunctionElement);
     if (node.element is FunctionElement) {
       // Tear off a method.
-      registry.registerGetOfStaticFunction(node.element.declaration);
+      registry.registerStaticUse(
+          new StaticUse.staticTearOff(node.element.declaration));
       return glue.isolateStaticClosureAccess(node.element);
     }
-    if (glue.isLazilyInitialized(node.element)) {
+    if (node.useLazyGetter) {
       // Read a lazily initialized field.
-      registry.registerStaticUse(node.element.declaration);
+      registry.registerStaticUse(
+          new StaticUse.staticInit(node.element.declaration));
       js.Expression getter = glue.isolateLazyInitializerAccess(node.element);
       return new js.Call(getter, <js.Expression>[],
           sourceInformation: node.sourceInformation);
     }
     // Read an eagerly initialized field.
-    registry.registerStaticUse(node.element.declaration);
+    registry.registerStaticUse(
+        new StaticUse.staticGet(node.element.declaration));
     return glue.staticFieldAccess(node.element);
   }
 
   @override
   js.Expression visitSetStatic(tree_ir.SetStatic node) {
     assert(node.element is FieldElement);
-    registry.registerStaticUse(node.element.declaration);
+    registry.registerStaticUse(
+        new StaticUse.staticSet(node.element.declaration));
     js.Expression field = glue.staticFieldAccess(node.element);
     js.Expression value = visitExpression(node.value);
     return new js.Assignment(field, value);
@@ -774,17 +939,17 @@
 
   @override
   js.Expression visitSetIndex(tree_ir.SetIndex node) {
-    return js.js('#[#] = #',
-        [visitExpression(node.object),
-         visitExpression(node.index),
-         visitExpression(node.value)]);
+    js.Expression index = new js.PropertyAccess(
+        visitExpression(node.object), visitExpression(node.index));
+    return makeAssignment(index, node.value, compound: node.compound);
   }
 
   js.Expression buildStaticHelperInvocation(
       FunctionElement helper,
       List<js.Expression> arguments,
       {SourceInformation sourceInformation}) {
-    registry.registerStaticUse(helper);
+    registry.registerStaticUse(new StaticUse.staticInvoke(
+        helper, new CallStructure.unnamed(arguments.length)));
     return buildStaticInvoke(
         helper, arguments, sourceInformation: sourceInformation);
   }
@@ -826,8 +991,15 @@
   }
 
   js.Node handleForeignCode(tree_ir.ForeignCode node) {
-    registry.registerStaticUse(node.dependency);
-    // TODO(sra): Should this be in CodegenRegistry?
+    if (node.dependency != null) {
+      // Dependency is only used if [node] calls a Dart function. Currently only
+      // through foreign function `RAW_DART_FUNCTION_REF`.
+      registry.registerStaticUse(
+          new StaticUse.staticInvoke(
+              node.dependency,
+              new CallStructure.unnamed(node.arguments.length)));
+    }
+    // TODO(sra,johnniwinther): Should this be in CodegenRegistry?
     glue.registerNativeBehavior(node.nativeBehavior, node);
     return node.codeTemplate.instantiate(visitExpressionList(node.arguments));
   }
@@ -846,6 +1018,33 @@
   void visitYield(tree_ir.Yield node) {
     js.Expression value = visitExpression(node.input);
     accumulator.add(new js.DartYield(value, node.hasStar));
+    visitStatement(node.next);
+  }
+
+  @override
+  void visitNullCheck(tree_ir.NullCheck node) {
+    js.Expression value = visitExpression(node.value);
+    // TODO(sra): Try to use the selector even when [useSelector] is false. The
+    // reason we use 'toString' is that it is always defined so avoids a slow
+    // lookup (in V8) of an absent property. We could use the property for the
+    // selector if we knew it was present. The property is present if the
+    // associated method was not inlined away, or if there is a noSuchMethod
+    // hook for that selector. We don't know these things here, but the decision
+    // could be deferred by creating a deferred property that was resolved after
+    // codegen.
+    js.Expression access = node.selector != null && node.useSelector
+        ? js.js('#.#', [value, glue.invocationName(node.selector)])
+        : js.js('#.toString', [value]);
+    if (node.condition != null) {
+      js.Expression condition = visitExpression(node.condition);
+      js.Statement body = isNullReturn(node.next)
+          ? new js.ExpressionStatement(access)
+          : new js.Return(access);
+      accumulator.add(new js.If.noElse(condition, body));
+    } else {
+      accumulator.add(new js.ExpressionStatement(access));
+    }
+    visitStatement(node.next);
   }
 
   @override
@@ -883,11 +1082,18 @@
       case BuiltinOperator.NumShr:
         // No normalization required since output is always uint32.
         return js.js('# >>> #', args);
+      case BuiltinOperator.NumBitNot:
+        return js.js('(~#) >>> 0', args);
+      case BuiltinOperator.NumNegate:
+        return js.js('-#', args);
       case BuiltinOperator.StringConcatenate:
         if (args.isEmpty) return js.string('');
         return args.reduce((e1,e2) => new js.Binary('+', e1, e2));
+      case BuiltinOperator.CharCodeAt:
+        return js.js('#.charCodeAt(#)', args);
       case BuiltinOperator.Identical:
-        registry.registerStaticInvocation(glue.identicalFunction);
+        registry.registerStaticUse(new StaticUse.staticInvoke(
+            glue.identicalFunction, new CallStructure.unnamed(args.length)));
         return buildStaticHelperInvocation(glue.identicalFunction, args);
       case BuiltinOperator.StrictEq:
         return new js.Binary('===', args[0], args[1]);
@@ -1008,9 +1214,21 @@
     return new js.Await(visitExpression(node.input));
   }
 
-  visitFunctionExpression(tree_ir.FunctionExpression node) {
-    // FunctionExpressions are currently unused.
-    // We might need them if we want to emit raw JS nested functions.
-    throw 'FunctionExpressions should not be used';
+  /// Ensures that parameter defaults will be emitted.
+  ///
+  /// Ideally, this should be done when generating the relevant stub methods,
+  /// since those are the ones that actually reference the constants, but those
+  /// are created by the emitter when it is too late to register new constants.
+  ///
+  /// For non-static methods, we have no way of knowing if the defaults are
+  /// actually used, so we conservatively register them all.
+  void registerDefaultParameterValues(ExecutableElement element) {
+    if (element is! FunctionElement) return;
+    FunctionElement function = element;
+    if (function.isStatic) return; // Defaults are inlined at call sites.
+    function.functionSignature.forEachOptionalParameter((param) {
+      ConstantValue constant = glue.getDefaultParameterValue(param);
+      registry.registerCompileTimeConstant(constant);
+    });
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index e6f5909..b7d4c24 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -4,6 +4,8 @@
 
 library code_generator_dependencies;
 
+import '../backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend.dart';
 
 import '../../common.dart';
@@ -28,7 +30,7 @@
     Selector;
 import '../../world.dart' show
     ClassWorld;
-
+import '../../types/types.dart';
 
 /// Encapsulates the dependencies of the function-compiler to the compiler,
 /// backend and emitter.
@@ -39,10 +41,12 @@
 
   CodegenEnqueuer get _enqueuer => _compiler.enqueuer.codegen;
 
-  FunctionElement get getInterceptorMethod => _backend.getInterceptorMethod;
+  FunctionElement get getInterceptorMethod => _helpers.getInterceptorMethod;
 
   JavaScriptBackend get _backend => _compiler.backend;
 
+  BackendHelpers get _helpers => _backend.helpers;
+
   CodeEmitterTask get _emitter => _backend.emitter;
 
   Namer get _namer => _backend.namer;
@@ -65,10 +69,6 @@
     return classWorld.isUsedAsMixin(classElement);
   }
 
-  ConstantValue getConstantValueForVariable(VariableElement variable) {
-    return _backend.constants.getConstantValueForVariable(variable);
-  }
-
   js.Expression staticFunctionAccess(FunctionElement element) {
     return _backend.emitter.staticFunctionAccess(element);
   }
@@ -93,14 +93,14 @@
     return _namer.safeVariableName(name);
   }
 
-  ClassElement get listClass => _compiler.listClass;
+  ClassElement get listClass => _compiler.coreClasses.listClass;
 
   ConstructorElement get mapLiteralConstructor {
-    return _backend.mapLiteralConstructor;
+    return _helpers.mapLiteralConstructor;
   }
 
   ConstructorElement get mapLiteralConstructorEmpty {
-    return _backend.mapLiteralConstructorEmpty;
+    return _helpers.mapLiteralConstructorEmpty;
   }
 
   FunctionElement get identicalFunction => _compiler.identicalFunction;
@@ -110,11 +110,7 @@
   }
 
   FunctionElement get createInvocationMirrorMethod {
-    return _backend.helpers.createInvocationMirror;
-  }
-
-  void registerUseInterceptorInCodegen() {
-    _backend.registerUseInterceptor(_enqueuer);
+    return _helpers.createInvocationMirror;
   }
 
   bool isInterceptedSelector(Selector selector) {
@@ -126,7 +122,7 @@
   }
 
   bool isInterceptorClass(ClassElement element) {
-    return element.isSubclassOf(_backend.jsInterceptorClass);
+    return element.isSubclassOf(_helpers.jsInterceptorClass);
   }
 
   Set<ClassElement> getInterceptedClassesOn(Selector selector) {
@@ -165,59 +161,59 @@
 
   js.Expression getInterceptorLibrary() {
     return new js.VariableUse(
-        _backend.namer.globalObjectFor(_backend.interceptorsLibrary));
+        _backend.namer.globalObjectFor(_helpers.interceptorsLibrary));
   }
 
   FunctionElement getWrapExceptionHelper() {
-    return _backend.helpers.wrapExceptionHelper;
+    return _helpers.wrapExceptionHelper;
   }
 
   FunctionElement getExceptionUnwrapper() {
-    return _backend.helpers.exceptionUnwrapper;
+    return _helpers.exceptionUnwrapper;
   }
 
   FunctionElement getTraceFromException() {
-    return _backend.helpers.traceFromException;
+    return _helpers.traceFromException;
   }
 
   FunctionElement getCreateRuntimeType() {
-    return _backend.helpers.createRuntimeType;
+    return _helpers.createRuntimeType;
   }
 
   FunctionElement getRuntimeTypeToString() {
-    return _backend.helpers.runtimeTypeToString;
+    return _helpers.runtimeTypeToString;
   }
 
   FunctionElement getRuntimeTypeArgument() {
-    return _backend.helpers.getRuntimeTypeArgument;
+    return _helpers.getRuntimeTypeArgument;
   }
 
   FunctionElement getTypeArgumentByIndex() {
-    return _backend.helpers.getTypeArgumentByIndex;
+    return _helpers.getTypeArgumentByIndex;
   }
 
   FunctionElement getAddRuntimeTypeInformation() {
-    return _backend.helpers.setRuntimeTypeInfo;
+    return _helpers.setRuntimeTypeInfo;
   }
 
   /// checkSubtype(value, $isT, typeArgs, $asT)
   FunctionElement getCheckSubtype() {
-    return _backend.helpers.checkSubtype;
+    return _helpers.checkSubtype;
   }
 
   /// subtypeCast(value, $isT, typeArgs, $asT)
   FunctionElement getSubtypeCast() {
-    return _backend.helpers.subtypeCast;
+    return _helpers.subtypeCast;
   }
 
   /// checkSubtypeOfRuntime(value, runtimeType)
   FunctionElement getCheckSubtypeOfRuntimeType() {
-    return _backend.helpers.checkSubtypeOfRuntimeType;
+    return _helpers.checkSubtypeOfRuntimeType;
   }
 
   /// subtypeOfRuntimeTypeCast(value, runtimeType)
   FunctionElement getSubtypeOfRuntimeTypeCast() {
-    return _backend.helpers.subtypeOfRuntimeTypeCast;
+    return _helpers.subtypeOfRuntimeTypeCast;
   }
 
   js.Expression getRuntimeTypeName(ClassElement cls) {
@@ -247,15 +243,10 @@
         (_) => arguments[variableIndex++]);
     assert(variableIndex == arguments.length);
     // Representation contains JavaScript Arrays.
-    registry.registerInstantiatedClass(_backend.jsArrayClass);
+    registry.registerInstantiatedClass(_helpers.jsArrayClass);
     return representation;
   }
 
-  void registerIsCheck(DartType type, Registry registry) {
-    _enqueuer.registerIsCheck(type);
-    _backend.registerIsCheckForCodegen(type, _enqueuer, registry);
-  }
-
   js.Name getTypeTestTag(DartType type) {
     return _backend.namer.operatorIsType(type);
   }
@@ -272,23 +263,41 @@
     return _compiler.world.hasAnyStrictSubtype(element);
   }
 
-  ClassElement get jsFixedArrayClass => _backend.jsFixedArrayClass;
-  ClassElement get jsExtendableArrayClass => _backend.jsExtendableArrayClass;
+  ClassElement get jsFixedArrayClass => _helpers.jsFixedArrayClass;
+  ClassElement get jsExtendableArrayClass => _helpers.jsExtendableArrayClass;
   ClassElement get jsUnmodifiableArrayClass =>
-      _backend.jsUnmodifiableArrayClass;
-  ClassElement get jsMutableArrayClass => _backend.jsMutableArrayClass;
+      _helpers.jsUnmodifiableArrayClass;
+  ClassElement get jsMutableArrayClass => _helpers.jsMutableArrayClass;
 
   bool isStringClass(ClassElement classElement) =>
-      classElement == _backend.jsStringClass ||
-      classElement == _compiler.stringClass;
+      classElement == _helpers.jsStringClass ||
+      classElement == _compiler.coreClasses.stringClass;
 
   bool isBoolClass(ClassElement classElement) =>
-      classElement == _backend.jsBoolClass ||
-      classElement == _compiler.boolClass;
+      classElement == _helpers.jsBoolClass ||
+      classElement == _compiler.coreClasses.boolClass;
 
-  // TODO(sra): Should this be part of CodegenRegistry?
+  // TODO(sra,johnniwinther): Should this be part of CodegenRegistry?
   void registerNativeBehavior(NativeBehavior nativeBehavior, node) {
     if (nativeBehavior == null) return;
     _enqueuer.nativeEnqueuer.registerNativeBehavior(nativeBehavior, node);
   }
+
+  ConstantValue getDefaultParameterValue(ParameterElement elem) {
+    return _backend.constants.getConstantValueForVariable(elem);
+  }
+
+  TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
+    return _compiler.world.extendMaskIfReachesAll(selector, mask);
+  }
+
+  FunctionElement get closureFromTearOff => _backend.helpers.closureFromTearOff;
+
+  js.Name registerOneShotInterceptor(Selector selector) {
+    return _backend.registerOneShotInterceptor(selector);
+  }
+
+  bool mayGenerateInstanceofCheck(DartType type) {
+    return _backend.mayGenerateInstanceofCheck(type);
+  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index 28beb1c..034dd10 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -27,6 +27,7 @@
 import '../../cps_ir/optimizers.dart';
 import '../../cps_ir/optimizers.dart' as cps_opt;
 import '../../cps_ir/type_mask_system.dart';
+import '../../cps_ir/finalize.dart' show Finalize;
 import '../../diagnostics/invariant.dart' show
     DEBUG_MODE;
 import '../../elements/elements.dart';
@@ -65,18 +66,22 @@
   final GenericTask treeBuilderTask;
   final GenericTask treeOptimizationTask;
 
+  Inliner inliner;
+
   CpsFunctionCompiler(Compiler compiler, JavaScriptBackend backend,
                       SourceInformationStrategy sourceInformationFactory)
       : fallbackCompiler =
             new ssa.SsaFunctionCompiler(backend, sourceInformationFactory),
         cpsBuilderTask = new IrBuilderTask(compiler, sourceInformationFactory),
-        this.sourceInformationFactory = sourceInformationFactory,
+        sourceInformationFactory = sourceInformationFactory,
         constantSystem = backend.constantSystem,
         compiler = compiler,
         glue = new Glue(compiler),
         cpsOptimizationTask = new GenericTask('CPS optimization', compiler),
         treeBuilderTask = new GenericTask('Tree builder', compiler),
-        treeOptimizationTask = new GenericTask('Tree optimization', compiler);
+      treeOptimizationTask = new GenericTask('Tree optimization', compiler) {
+    inliner = new Inliner(this);
+  }
 
   String get name => 'CPS Ir pipeline';
 
@@ -86,9 +91,9 @@
 
   /// Generates JavaScript code for `work.element`.
   js.Fun compile(CodegenWorkItem work) {
+    if (typeSystem == null) typeSystem = new TypeMaskSystem(compiler);
     AstElement element = work.element;
     return reporter.withCurrentElement(element, () {
-      typeSystem = new TypeMaskSystem(compiler);
       try {
         // TODO(karlklose): remove this fallback when we do not need it for
         // testing anymore.
@@ -101,7 +106,10 @@
           tracer.traceCompilation(element.name, null);
         }
         cps.FunctionDefinition cpsFunction = compileToCpsIr(element);
-        cpsFunction = optimizeCpsIr(cpsFunction);
+        optimizeCpsBeforeInlining(cpsFunction);
+        applyCpsPass(inliner, cpsFunction);
+        optimizeCpsAfterInlining(cpsFunction);
+        cpsIntegrityChecker = null;
         tree_ir.FunctionDefinition treeFunction = compileToTreeIr(cpsFunction);
         treeFunction = optimizeTreeIr(treeFunction);
         return compileToJavaScript(work, treeFunction);
@@ -133,7 +141,8 @@
   }
 
   cps.FunctionDefinition compileToCpsIr(AstElement element) {
-    cps.FunctionDefinition cpsFunction = cpsBuilderTask.buildNode(element);
+    cps.FunctionDefinition cpsFunction =
+        cpsBuilderTask.buildNode(element, typeSystem);
     if (cpsFunction == null) {
       if (cpsBuilderTask.bailoutMessage == null) {
         giveUp('unable to build cps definition of $element');
@@ -185,33 +194,51 @@
     }
   }
 
-  static bool checkCpsIntegrity(cps.FunctionDefinition node, String pass) {
-    new CheckCpsIntegrity().check(node, pass);
+  CheckCpsIntegrity cpsIntegrityChecker;
+
+  bool checkCpsIntegrity(cps.FunctionDefinition node, String previousPass) {
+    cpsOptimizationTask.measureSubtask('Check integrity', () {
+      if (cpsIntegrityChecker == null) {
+        cpsIntegrityChecker = new CheckCpsIntegrity();
+      }
+      cpsIntegrityChecker.check(node, previousPass);
+    });
     return true; // So this can be used from assert().
   }
 
-  cps.FunctionDefinition optimizeCpsIr(cps.FunctionDefinition cpsFunction) {
-    TypeMaskSystem typeSystem = new TypeMaskSystem(compiler);
+  void optimizeCpsBeforeInlining(cps.FunctionDefinition cpsFunction) {
+    cpsOptimizationTask.measure(() {
+      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
+      applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
+      applyCpsPass(new InsertRefinements(typeSystem), cpsFunction);
+      applyCpsPass(new TypePropagator(this), cpsFunction);
+      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
+    });
+  }
 
-    applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
-    applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
-    applyCpsPass(new InsertRefinements(typeSystem), cpsFunction);
-    applyCpsPass(new TypePropagator(compiler, typeSystem, this), cpsFunction);
-    applyCpsPass(new RemoveRefinements(), cpsFunction);
-    applyCpsPass(new ShrinkingReducer(), cpsFunction);
-    applyCpsPass(new ScalarReplacer(compiler), cpsFunction);
-    applyCpsPass(new MutableVariableEliminator(), cpsFunction);
-    applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
-    applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
-    applyCpsPass(new BoundsChecker(typeSystem, compiler.world), cpsFunction);
-    applyCpsPass(new ShrinkingReducer(), cpsFunction);
-    applyCpsPass(new ShareInterceptors(), cpsFunction);
-    applyCpsPass(new ShrinkingReducer(), cpsFunction);
-
-    return cpsFunction;
+  void optimizeCpsAfterInlining(cps.FunctionDefinition cpsFunction) {
+    cpsOptimizationTask.measure(() {
+      applyCpsPass(new RedundantRefinementEliminator(typeSystem), cpsFunction);
+      applyCpsPass(new EagerlyLoadStatics(), cpsFunction);
+      applyCpsPass(new GVN(compiler, typeSystem), cpsFunction);
+      applyCpsPass(new UpdateRefinements(typeSystem), cpsFunction);
+      applyCpsPass(new BoundsChecker(typeSystem, compiler.world), cpsFunction);
+      applyCpsPass(new LoopInvariantBranchMotion(), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
+      applyCpsPass(new ScalarReplacer(compiler), cpsFunction);
+      applyCpsPass(new MutableVariableEliminator(), cpsFunction);
+      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
+      applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
+      applyCpsPass(new OptimizeInterceptors(backend, typeSystem), cpsFunction);
+      applyCpsPass(new BackwardNullCheckRemover(typeSystem), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
+    });
   }
 
   tree_ir.FunctionDefinition compileToTreeIr(cps.FunctionDefinition cpsNode) {
+    applyCpsPass(new Finalize(backend), cpsNode);
     tree_builder.Builder builder = new tree_builder.Builder(
         reporter.internalError);
     tree_ir.FunctionDefinition treeNode =
@@ -222,8 +249,10 @@
     return treeNode;
   }
 
-  static bool checkTreeIntegrity(tree_ir.FunctionDefinition node) {
-    new CheckTreeIntegrity().check(node);
+  bool checkTreeIntegrity(tree_ir.FunctionDefinition node) {
+    treeOptimizationTask.measureSubtask('Check integrity', () {
+      new CheckTreeIntegrity().check(node);
+    });
     return true; // So this can be used from assert().
   }
 
@@ -236,11 +265,13 @@
       assert(checkTreeIntegrity(node));
     }
 
-    applyTreePass(new StatementRewriter());
-    applyTreePass(new VariableMerger());
-    applyTreePass(new LoopRewriter());
-    applyTreePass(new LogicalRewriter());
-    applyTreePass(new PullIntoInitializers());
+    treeOptimizationTask.measure(() {
+      applyTreePass(new StatementRewriter());
+      applyTreePass(new VariableMerger());
+      applyTreePass(new LoopRewriter());
+      applyTreePass(new LogicalRewriter());
+      applyTreePass(new PullIntoInitializers());
+    });
 
     return node;
   }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
index 3fa6f18..2596b91 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
@@ -2,13 +2,14 @@
 
 import '../../cps_ir/cps_ir_nodes.dart';
 
-import '../../cps_ir/optimizers.dart' show ParentVisitor, Pass;
+import '../../cps_ir/optimizers.dart' show Pass;
 import '../../constants/values.dart';
 import '../../elements/elements.dart';
 import '../../js_backend/codegen/glue.dart';
 import '../../universe/selector.dart' show Selector;
 import '../../cps_ir/cps_ir_builder.dart' show ThisParameterLocal;
 import '../../cps_ir/cps_fragment.dart';
+import '../../common/names.dart';
 
 class ExplicitReceiverParameterEntity implements Local {
   String get name => 'receiver';
@@ -77,7 +78,7 @@
     }
 
     if (inInterceptedMethod && methodUsesReceiverArgument(function.element)) {
-      explicitReceiverParameter.substituteFor(thisParameter);
+      thisParameter.replaceUsesWith(explicitReceiverParameter);
     }
 
     visit(function);
@@ -95,11 +96,6 @@
     return new Constant(new NullConstantValue());
   }
 
-  void insertLetPrim(Primitive primitive, Expression node) {
-    LetPrim let = new LetPrim(primitive);
-    let.insertAbove(node);
-  }
-
   void insertEqNullCheck(FunctionDefinition function) {
     // Replace
     //
@@ -122,30 +118,15 @@
     cps.insertAbove(function.body);
   }
 
-  /// Insert a static call to [function] at the point of [node] with result
-  /// [result].
-  ///
-  /// Rewrite [node] to
-  ///
-  /// let cont continuation(result) = node
-  /// in invoke function arguments continuation
-  void insertStaticCall(FunctionElement function, List<Primitive> arguments,
-      Parameter result, Expression node) {
-    InteriorNode parent = node.parent;
-    Continuation continuation = new Continuation([result]);
-
-    Selector selector = new Selector.fromElement(function);
+  /// Insert a static call to [function] immediately above [node].
+  Primitive insertStaticCallAbove(FunctionElement function,
+      List<Primitive> arguments, Expression node) {
     // TODO(johnniwinther): Come up with an implementation of SourceInformation
     // for calls such as this one that don't appear in the original source.
     InvokeStatic invoke = new InvokeStatic(
-        function, selector, arguments, continuation, null);
-
-    LetCont letCont = new LetCont(continuation, invoke);
-
-    parent.body = letCont;
-    letCont.parent = parent;
-    continuation.body = node;
-    node.parent = continuation;
+        function, new Selector.fromElement(function), arguments, null);
+    new LetPrim(invoke).insertAbove(node);
+    return invoke;
   }
 
   @override
@@ -161,16 +142,22 @@
     Expression body = node.handler.body;
     if (_exceptionParameter.hasAtLeastOneUse ||
         stackTraceParameter.hasAtLeastOneUse) {
-      Parameter exceptionValue = new Parameter(null);
-      exceptionValue.substituteFor(_exceptionParameter);
-      insertStaticCall(_glue.getExceptionUnwrapper(), [_exceptionParameter],
-          exceptionValue, body);
+      InvokeStatic unwrapped = insertStaticCallAbove(
+          _glue.getExceptionUnwrapper(),
+          [new Parameter(null)], // Dummy argument, see below.
+          body);
+      _exceptionParameter.replaceUsesWith(unwrapped);
+
+      // Replace the dummy with the exception parameter.  It must be set after
+      // replacing all uses of [_exceptionParameter].
+      unwrapped.arguments[0].changeTo(_exceptionParameter);
 
       if (stackTraceParameter.hasAtLeastOneUse) {
-        Parameter stackTraceValue = new Parameter(null);
-        stackTraceValue.substituteFor(stackTraceParameter);
-        insertStaticCall(_glue.getTraceFromException(), [_exceptionParameter],
-            stackTraceValue, body);
+        InvokeStatic stackTraceValue = insertStaticCallAbove(
+            _glue.getTraceFromException(),
+            [_exceptionParameter],
+            body);
+        stackTraceParameter.replaceUsesWith(stackTraceValue);
       }
     }
 
@@ -185,9 +172,10 @@
 
   processThrow(Throw node) {
     // The subexpression of throw is wrapped in the JavaScript output.
-    Parameter wrappedException = new Parameter(null);
-    insertStaticCall(_glue.getWrapExceptionHelper(), [node.value.definition],
-        wrappedException, node);
+    Primitive wrappedException = insertStaticCallAbove(
+        _glue.getWrapExceptionHelper(),
+        [node.value.definition],
+        node);
     node.value.changeTo(wrappedException);
   }
 
@@ -202,22 +190,26 @@
     // worry about unlinking.
   }
 
-  // TODO(24523): Insert interceptor on demand when we discover we want to use
-  // one rather than on every check.
-  processTypeTest(TypeTest node) {
-    assert(node.interceptor == null);
-    Primitive receiver = node.value.definition;
-    Primitive interceptor = new Interceptor(receiver, node.sourceInformation)
-        ..interceptedClasses.addAll(_glue.interceptedClasses);
-    insertLetPrim(interceptor, node.parent);
-    node.interceptor = new Reference<Primitive>(interceptor);
-    node.interceptor.parent = node;
+  bool isNullConstant(Primitive prim) {
+    return prim is Constant && prim.value.isNull;
   }
 
   processInvokeMethod(InvokeMethod node) {
     Selector selector = node.selector;
     if (!_glue.isInterceptedSelector(selector)) return;
 
+    // Some platform libraries will compare non-interceptable objects against
+    // null using the Dart == operator.  These must be translated directly.
+    if (node.selector == Selectors.equals &&
+        node.arguments.length == 1 &&
+        isNullConstant(node.arguments[0].definition)) {
+      node.replaceWith(new ApplyBuiltinOperator(
+          BuiltinOperator.Identical,
+          [node.receiver.definition, node.arguments[0].definition],
+          node.sourceInformation));
+      return;
+    }
+
     Primitive receiver = node.receiver.definition;
     Primitive newReceiver;
 
@@ -227,23 +219,20 @@
       //  Change 'receiver.foo()'  to  'this.foo(receiver)'.
       newReceiver = thisParameter;
     } else {
-      LetCont contBinding = node.parent;
-      newReceiver = new Interceptor(receiver, node.sourceInformation)
-          ..interceptedClasses.addAll(_glue.getInterceptedClassesOn(selector));
+      newReceiver = new Interceptor(receiver, node.sourceInformation);
       if (receiver.hint != null) {
         newReceiver.hint = new InterceptorEntity(receiver.hint);
       }
-      insertLetPrim(newReceiver, contBinding);
+      new LetPrim(newReceiver).insertAbove(node.parent);
     }
     node.arguments.insert(0, node.receiver);
     node.receiver = new Reference<Primitive>(newReceiver)..parent = node;
-    node.receiverIsIntercepted = true;
+    node.callingConvention = CallingConvention.Intercepted;
   }
 
   processInvokeMethodDirectly(InvokeMethodDirectly node) {
     if (!_glue.isInterceptedMethod(node.target)) return;
 
-    Selector selector = node.selector;
     Primitive receiver = node.receiver.definition;
     Primitive newReceiver;
 
@@ -253,19 +242,14 @@
       //  Change 'receiver.foo()'  to  'this.foo(receiver)'.
       newReceiver = thisParameter;
     } else {
-      LetCont contBinding = node.parent;
-      newReceiver = new Interceptor(receiver, node.sourceInformation)
-        ..interceptedClasses.addAll(_glue.getInterceptedClassesOn(selector));
+      newReceiver = new Interceptor(receiver, node.sourceInformation);
       if (receiver.hint != null) {
         newReceiver.hint = new InterceptorEntity(receiver.hint);
       }
-      insertLetPrim(newReceiver, contBinding);
+      new LetPrim(newReceiver).insertAbove(node.parent);
     }
     node.arguments.insert(0, node.receiver);
     node.receiver = new Reference<Primitive>(newReceiver)..parent = node;
-  }
-
-  processInterceptor(Interceptor node) {
-    _glue.registerSpecializedGetInterceptor(node.interceptedClasses);
+    node.callingConvention = CallingConvention.Intercepted;
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 5b87b15..0550d8d 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -153,9 +153,8 @@
    */
   @override
   jsAst.Expression visitString(StringConstantValue constant, [_]) {
-    StringBuffer sb = new StringBuffer();
-    writeJsonEscapedCharsOn(constant.primitiveValue.slowToString(), sb);
-    return new jsAst.LiteralString('"$sb"');
+    return js.escapedString(constant.primitiveValue.slowToString(),
+                            ascii: true);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index 3dca32b..290d563 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -4,13 +4,19 @@
 
 library dart2js.constant_system.js;
 
-import '../compiler.dart' show Compiler;
+import '../compiler.dart' show
+    Compiler;
 import '../constants/constant_system.dart';
 import '../constants/values.dart';
 import '../constant_system_dart.dart';
+import '../core_types.dart' show
+    CoreTypes;
 import '../dart_types.dart';
-import '../elements/elements.dart' show ClassElement;
-import '../tree/tree.dart' show DartString, LiteralDartString;
+import '../elements/elements.dart' show
+    ClassElement;
+import '../tree/tree.dart' show
+    DartString,
+    LiteralDartString;
 import 'js_backend.dart';
 
 const JAVA_SCRIPT_CONSTANT_SYSTEM = const JavaScriptConstantSystem();
@@ -185,6 +191,7 @@
   final greaterEqual = const GreaterEqualOperation();
   final greater = const GreaterOperation();
   final identity = const JavaScriptIdentityOperation();
+  final ifNull = const IfNullOperation();
   final lessEqual = const LessEqualOperation();
   final less = const LessOperation();
   final modulo =
@@ -291,6 +298,7 @@
                              List<ConstantValue> keys,
                              List<ConstantValue> values) {
     JavaScriptBackend backend = compiler.backend;
+    CoreTypes coreTypes = compiler.coreTypes;
 
     bool onlyStringKeys = true;
     ConstantValue protoValue = null;
@@ -311,17 +319,16 @@
     bool hasProtoKey = (protoValue != null);
     DartType keysType;
     if (sourceType.treatAsRaw) {
-      keysType = compiler.listClass.rawType;
+      keysType = coreTypes.listType();
     } else {
-      List<DartType> arguments = <DartType>[sourceType.typeArguments.first];
-      keysType = new InterfaceType(compiler.listClass, arguments);
+      keysType = coreTypes.listType(sourceType.typeArguments.first);
     }
     ListConstantValue keysList = new ListConstantValue(keysType, keys);
     String className = onlyStringKeys
         ? (hasProtoKey ? JavaScriptMapConstant.DART_PROTO_CLASS
                        : JavaScriptMapConstant.DART_STRING_CLASS)
         : JavaScriptMapConstant.DART_GENERAL_CLASS;
-    ClassElement classElement = backend.jsHelperLibrary.find(className);
+    ClassElement classElement = backend.helpers.jsHelperLibrary.find(className);
     classElement.ensureResolved(compiler.resolution);
     List<DartType> typeArgument = sourceType.typeArguments;
     InterfaceType type;
@@ -349,7 +356,7 @@
   static const String DART_STRING_CLASS = "ConstantStringMap";
   static const String DART_PROTO_CLASS = "ConstantProtoMap";
   static const String DART_GENERAL_CLASS = "GeneralConstantMap";
-  static const String LENGTH_NAME = "length";
+  static const String LENGTH_NAME = "_length";
   static const String JS_OBJECT_NAME = "_jsObject";
   static const String KEYS_NAME = "_keys";
   static const String PROTO_VALUE = "_protoValue";
diff --git a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
index 8ddbb43..1a5e287 100644
--- a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
@@ -68,12 +68,12 @@
 
   void registerInstantiatedClass(ClassElement classElement, Enqueuer enqueuer) {
     classElement.ensureResolved(compiler.resolution);
-    if (!Elements.isNativeOrExtendsNative(classElement)) return;
+    if (!backend.isNativeOrExtendsNative(classElement)) return;
     if (classElement.isMixinApplication) return;
     if (classElement.isAbstract) return;
     // JsInterop classes are opaque interfaces without a concrete
     // implementation.
-    if (classElement.isJsInterop) return;
+    if (backend.isJsInterop(classElement)) return;
     joinFor(enqueuer).instantiatedClasses.add(classElement);
   }
 
@@ -91,9 +91,8 @@
     }
   }
 
-  void registerTypeConstant(Element element, Enqueuer enqueuer) {
+  void registerTypeConstant(Element element) {
     assert(element.isClass);
-    assert(!enqueuer.isResolutionQueue);
     codegenJoin.selectedClasses.add(element);
   }
 
@@ -101,8 +100,7 @@
     assert(element != null);
     if (!fetchedTableAccessorMethod) {
       fetchedTableAccessorMethod = true;
-      tableAccessorMethod = backend.findInterceptor(
-          'findIndexForNativeSubclassType');
+      tableAccessorMethod = backend.helpers.findIndexForNativeSubclassType;
     }
     if (element == tableAccessorMethod) {
       joinFor(enqueuer).demanded = true;
@@ -149,18 +147,20 @@
     if (!demanded) return;
     var newActiveClasses = new Set<ClassElement>();
     for (ClassElement classElement in instantiatedClasses) {
-      bool isNative = classElement.isNative;
+      bool isNative = backend.isNative(classElement);
       bool isExtension =
-          !isNative && Elements.isNativeOrExtendsNative(classElement);
+          !isNative && backend.isNativeOrExtendsNative(classElement);
       // Generate table entries for native classes that are explicitly named and
       // extensions that fix our criteria.
       if ((isNative && selectedClasses.contains(classElement)) ||
           (isExtension &&
               (allClassesSelected || selectedClasses.contains(classElement)))) {
         newActiveClasses.add(classElement);
-        Iterable<Element> escapingConstructors =
+        Iterable<ConstructorElement> escapingConstructors =
             computeEscapingConstructors(classElement);
-        escapingConstructors.forEach(enqueuer.registerStaticUse);
+        for (ConstructorElement constructor in escapingConstructors) {
+          enqueuer.registerStaticUse(new StaticUse.foreignUse(constructor));
+        }
         escapingConstructors
             .forEach(compiler.globalDependencies.registerDependency);
         // Force the generaton of the type constant that is the key to an entry
@@ -168,6 +168,7 @@
         ConstantValue constant = makeTypeConstant(classElement);
         backend.registerCompileTimeConstant(
             constant, compiler.globalDependencies);
+        backend.addCompileTimeConstantForEmission(constant);
       }
     }
     activeClasses.addAll(newActiveClasses);
@@ -179,17 +180,18 @@
     return backend.constantSystem.createType(compiler, elementType);
   }
 
-  List<Element> computeEscapingConstructors(ClassElement classElement) {
-    List<Element> result = <Element>[];
+  List<ConstructorElement> computeEscapingConstructors(
+      ClassElement classElement) {
+    List<ConstructorElement> result = <ConstructorElement>[];
     // Only classes that extend native classes have constructors in the table.
     // We could refine this to classes that extend Element, but that would break
     // the tests and there is no sane reason to subclass other native classes.
-    if (classElement.isNative) return result;
+    if (backend.isNative(classElement)) return result;
 
-    selectGenerativeConstructors(ClassElement enclosing, Element member) {
+    void selectGenerativeConstructors(ClassElement enclosing, Element member) {
       if (member.isGenerativeConstructor) {
         // Ignore constructors that cannot be called with zero arguments.
-        FunctionElement constructor = member;
+        ConstructorElement constructor = member;
         constructor.computeType(compiler.resolution);
         FunctionSignature parameters = constructor.functionSignature;
         if (parameters.requiredParameterCount == 0) {
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
index 707e7e76..0a89b42 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -14,17 +14,15 @@
   // this could be because the field belongs to a mixin. In such a case this
   // will return `null` and a normal field name has to be used.
   jsAst.Name _minifiedInstanceFieldPropertyName(Element element) {
-    if (element.hasFixedBackendName) {
-      return new StringBackedName(element.fixedBackendName);
+    if (backend.hasFixedBackendName(element)) {
+      return new StringBackedName(backend.getFixedBackendName(element));
     }
 
     _FieldNamingScope names;
     if (element is BoxFieldElement) {
       names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
     } else {
-      ClassElement cls = element is ClosureFieldElement
-          ? element.closureClass
-          : element.enclosingClass;
+      ClassElement cls = element.enclosingClass;
       names =
           new _FieldNamingScope.forClass(cls, compiler.world, fieldRegistry);
     }
@@ -77,7 +75,7 @@
         nameStore.add(
             new StringBackedName(MinifyNamer._reservedNativeProperties[index]));
       } else {
-        nameStore.add(namer.getFreshName(NamingScope.instance, "field$index"));
+        nameStore.add(namer.getFreshName(namer.instanceScope, "field$index"));
       }
     }
 
diff --git a/pkg/compiler/lib/src/js_backend/frequency_namer.dart b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
index 0aaf8f6..fa3b79b 100644
--- a/pkg/compiler/lib/src/js_backend/frequency_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
@@ -21,12 +21,15 @@
   final String setterPrefix = 's';
   final String callPrefix = ''; // this will create function names $<n>
 
+  jsAst.Name get staticsPropertyName =>
+      _staticsPropertyName ??= getFreshName(instanceScope, 'static');
+
   FrequencyBasedNamer(Compiler compiler) : super(compiler) {
     fieldRegistry = new _FieldNamingRegistry(this);
   }
 
   TokenScope newScopeFor(NamingScope scope) {
-    if (scope == NamingScope.instance) {
+    if (scope == instanceScope) {
       Set<String> illegalNames = new Set<String>.from(jsReserved);
       for (String illegal in MinifyNamer._reservedNativeProperties) {
         illegalNames.add(illegal);
@@ -50,8 +53,7 @@
 
     // Get the name the normal namer would use as a key.
     String proposed = _generateFreshStringForName(proposedName,
-                                                  getUsedNames(scope),
-                                                  getSuggestedNames(scope),
+                                                  scope,
                                                   sanitizeForNatives:
                                                   sanitizeForNatives,
                                                   sanitizeForAnnotations:
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index 3da429f..99d383c 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -14,8 +14,10 @@
 import '../common.dart';
 import '../common/backend_api.dart' show
     Backend,
+    ImpactTransformer,
     ForeignResolver;
 import '../common/codegen.dart' show
+    CodegenImpact,
     CodegenRegistry,
     CodegenWorkItem;
 import '../common/names.dart' show
@@ -23,6 +25,7 @@
     Selectors,
     Uris;
 import '../common/registry.dart' show
+    EagerRegistry,
     Registry;
 import '../common/tasks.dart' show
     CompilerTask;
@@ -31,9 +34,7 @@
     ListLiteralUse,
     MapLiteralUse,
     Resolution,
-    ResolutionCallbacks,
-    ResolutionImpact,
-    TransformedWorldImpact;
+    ResolutionImpact;
 import '../common/work.dart' show
     ItemCompilationContext;
 import '../compiler.dart' show
@@ -42,15 +43,20 @@
 import '../constants/constant_system.dart';
 import '../constants/expressions.dart';
 import '../constants/values.dart';
+import '../core_types.dart' show
+    CoreClasses,
+    CoreTypes;
 import '../dart_types.dart';
+import '../deferred_load.dart' show
+    DeferredLoadTask;
+import '../dump_info.dart' show
+    DumpInfoTask;
 import '../elements/elements.dart';
 import '../elements/visitor.dart' show
     BaseElementVisitor;
 import '../enqueue.dart' show
     Enqueuer,
-    ResolutionEnqueuer,
-    WorldImpact;
-import '../helpers/helpers.dart';
+    ResolutionEnqueuer;
 import '../io/code_output.dart';
 import '../io/source_information.dart' show
     SourceInformationStrategy,
@@ -72,10 +78,6 @@
     USE_LAZY_EMITTER;
 import '../library_loader.dart' show LibraryLoader, LoadedLibraries;
 import '../native/native.dart' as native;
-import '../patch_parser.dart' show
-    checkJsInteropAnnotation;
-import '../resolution/registry.dart' show
-    EagerRegistry;
 import '../resolution/tree_elements.dart' show
     TreeElements;
 import '../ssa/ssa.dart';
@@ -87,6 +89,18 @@
     Selector,
     SelectorKind;
 import '../universe/universe.dart';
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    StaticUseKind,
+    TypeUse,
+    TypeUseKind;
+import '../universe/world_impact.dart' show
+    ImpactStrategy,
+    ImpactUseCase,
+    TransformedWorldImpact,
+    WorldImpact,
+    WorldImpactVisitor;
 import '../util/characters.dart';
 import '../util/util.dart';
 import '../world.dart' show
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index 4199c69..ad5c04c 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -31,6 +31,7 @@
 import '../universe/selector.dart' show Selector;
 import '../universe/universe.dart' show SelectorConstraints;
 
+import 'backend_helpers.dart' show BackendHelpers;
 import 'js_backend.dart' show JavaScriptBackend;
 
 class JsInteropAnalysis {
@@ -45,11 +46,13 @@
 
   JsInteropAnalysis(this.backend);
 
+  BackendHelpers get helpers => backend.helpers;
+
   void onQueueClosed() {
     if (_inCodegen) return;
 
-    if (backend.jsAnnotationClass != null) {
-      nameField = backend.jsAnnotationClass.lookupMember('name');
+    if (helpers.jsAnnotationClass != null) {
+      nameField = helpers.jsAnnotationClass.lookupMember('name');
       backend.compiler.libraryLoader.libraries
           .forEach(processJsInteropAnnotationsInLibrary);
     }
@@ -65,14 +68,15 @@
           annotation.constant);
       if (constant == null || constant is! ConstructedConstantValue) continue;
       ConstructedConstantValue constructedConstant = constant;
-      if (constructedConstant.type.element == backend.jsAnnotationClass) {
+      if (constructedConstant.type.element == helpers.jsAnnotationClass) {
         ConstantValue value = constructedConstant.fields[nameField];
         if (value.isString) {
           StringConstantValue stringValue = value;
-          e.setJsInteropName(stringValue.primitiveValue.slowToString());
+          backend.setJsInteropName(
+              e, stringValue.primitiveValue.slowToString());
         } else {
           // TODO(jacobr): report a warning if the value is not a String.
-          e.setJsInteropName('');
+          backend.setJsInteropName(e, '');
         }
         enabledJsInterop = true;
         return;
@@ -81,7 +85,7 @@
   }
 
   bool hasAnonymousAnnotation(Element element) {
-    if (backend.jsAnonymousClass == null) return false;
+    if (backend.helpers.jsAnonymousClass == null) return false;
     return element.metadata.any((MetadataAnnotation annotation) {
       ConstantValue constant = backend.compiler.constants.getConstantValue(
           annotation.constant);
@@ -89,7 +93,7 @@
           constant is! ConstructedConstantValue) return false;
       ConstructedConstantValue constructedConstant = constant;
       return constructedConstant.type.element ==
-          backend.jsAnonymousClass;
+          backend.helpers.jsAnonymousClass;
     });
   }
 
@@ -107,7 +111,7 @@
     processJsInteropAnnotation(library);
     library.implementation.forEachLocalMember((Element element) {
       processJsInteropAnnotation(element);
-      if (!element.isJsInterop) return;
+      if (!backend.isJsInterop(element)) return;
       if (element is FunctionElement) {
         _checkFunctionParameters(element);
       }
@@ -121,7 +125,7 @@
       if (!backend.compiler.world.isImplemented(classElement)) return;
 
       if (!classElement
-          .implementsInterface(backend.jsJavaScriptObjectClass)) {
+          .implementsInterface(helpers.jsJavaScriptObjectClass)) {
         backend.reporter.reportErrorMessage(classElement,
             MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS, {
           'cls': classElement.name,
@@ -134,7 +138,7 @@
         processJsInteropAnnotation(member);
 
         if (!member.isSynthesized &&
-            classElement.isJsInterop &&
+            backend.isJsInterop(classElement) &&
             member is FunctionElement) {
           FunctionElement fn = member;
           if (!fn.isExternal && !fn.isAbstract && !fn.isConstructor &&
diff --git a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
index a6c1990..111eb22 100644
--- a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
@@ -68,6 +68,9 @@
 // ClassElement of a type to refer to keys we need to discover).
 // TODO(sigmund): detect uses of mirrors
 class LookupMapAnalysis {
+  static final Uri PACKAGE_LOOKUP_MAP =
+      new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart');
+
   /// Reference to [JavaScriptBackend] to be able to enqueue work when we
   /// discover that a key in a map is potentially used.
   final JavaScriptBackend backend;
@@ -205,8 +208,7 @@
     if (key is ConstructedConstantValue) {
       ClassElement element = key.type.element;
       return _typesWithEquals.putIfAbsent(element, () =>
-          element.lookupMember('==').enclosingClass !=
-          backend.compiler.objectClass);
+          !element.lookupMember('==').enclosingClass.isObject);
     }
     return false;
   }
@@ -411,8 +413,7 @@
     ConstantValue constant = unusedEntries.remove(key);
     usedEntries[key] = constant;
     analysis.backend.registerCompileTimeConstant(constant,
-        analysis.backend.compiler.globalDependencies,
-        addForEmission: false);
+        analysis.backend.compiler.globalDependencies);
   }
 
   /// Restores [original] to contain all of the entries marked as possibly used.
diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
index b781bc0..0ba2e4e 100644
--- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/minify_namer.dart
@@ -34,19 +34,17 @@
   /// minified names will always avoid clashing with annotated names or natives.
   @override
   String _generateFreshStringForName(String proposedName,
-      Set<String> usedNames,
-      Map<String, String> suggestedNames,
+      NamingScope scope,
       {bool sanitizeForNatives: false,
        bool sanitizeForAnnotations: false}) {
     String freshName;
-    String suggestion = suggestedNames[proposedName];
-    if (suggestion != null && !usedNames.contains(suggestion)) {
+    String suggestion = scope.suggestName(proposedName);
+    if (suggestion != null && scope.isUnused(suggestion)) {
       freshName = suggestion;
     } else {
-      freshName = _getUnusedName(proposedName, usedNames,
-          suggestedNames.values);
+      freshName = _getUnusedName(proposedName, scope);
     }
-    usedNames.add(freshName);
+    scope.registerUse(freshName);
     return freshName;
   }
 
@@ -85,12 +83,14 @@
         String disambiguatedName = name;
         reservePublicMemberName(name, disambiguatedName);
       }
-      usedInstanceNames.add(name);
+      instanceScope.registerUse(name);
       // Getter and setter names are autogenerated by prepending 'g' and 's' to
       // field names.  Therefore there are some field names we don't want to
       // use.  It is implicit in the next line that the banned prefix is
       // only one character.
-      if (_hasBannedPrefix(name)) usedInstanceNames.add(name.substring(1));
+      if (_hasBannedPrefix(name)) {
+        instanceScope.registerUse(name.substring(1));
+      }
     }
 
     // These popular names are present in most programs and deserve
@@ -99,8 +99,7 @@
     // minifier was less stable from version to version of the program being
     // minified.
     _populateSuggestedNames(
-        suggestedInstanceNames,
-        usedInstanceNames,
+        instanceScope,
         const <String>[
             r'$add', r'add$1', r'$and',
             r'$or',
@@ -115,8 +114,7 @@
             r'$tdiv', r'toString$0']);
 
     _populateSuggestedNames(
-        suggestedGlobalNames,
-        usedGlobalNames,
+        globalScope,
         const <String>[
             r'Object', 'wrapException', r'$eq', r'S', r'ioore',
             r'UnsupportedError$', r'length', r'$sub',
@@ -135,8 +133,7 @@
             ]);
   }
 
-  void _populateSuggestedNames(Map<String, String> suggestionMap,
-                               Set<String> used,
+  void _populateSuggestedNames(NamingScope scope,
                                List<String> suggestions) {
     int c = $a - 1;
     String letter;
@@ -145,9 +142,9 @@
         assert(c != $Z);
         c = (c == $z) ? $A : c + 1;
         letter = new String.fromCharCodes([c]);
-      } while (_hasBannedPrefix(letter) || used.contains(letter));
-      assert(suggestionMap[name] == null);
-      suggestionMap[name] = letter;
+      } while (_hasBannedPrefix(letter) || scope.isUsed(letter));
+      assert(!scope.hasSuggestion(name));
+      scope.addSuggestion(name, letter);
     }
   }
 
@@ -156,8 +153,7 @@
   // is slightly less efficient than just getting the next name in a series,
   // but it means that small changes in the input program will give smallish
   // changes in the output, which can be useful for diffing etc.
-  String _getUnusedName(String proposedName, Set<String> usedNames,
-                        Iterable<String> suggestions) {
+  String _getUnusedName(String proposedName, NamingScope scope) {
     int hash = _calculateHash(proposedName);
     // Avoid very small hashes that won't try many names.
     hash = hash < 1000 ? hash * 314159 : hash;  // Yes, it's prime.
@@ -177,10 +173,10 @@
           h2 ~/= ALPHANUMERIC_CHARACTERS;
         }
         final candidate = new String.fromCharCodes(codes);
-        if (!usedNames.contains(candidate) &&
+        if (scope.isUnused(candidate) &&
             !jsReserved.contains(candidate) &&
             !_hasBannedPrefix(candidate) &&
-            (n != 1 || !suggestions.contains(candidate))) {
+            (n != 1 || scope.isSuggestion(candidate))) {
           return candidate;
         }
         // Try again with a slightly different hash.  After around 10 turns
@@ -188,7 +184,7 @@
         h ~/= 7;
       }
     }
-    return _badName(hash, usedNames);
+    return _badName(hash, scope);
   }
 
   /// Instance members starting with g and s are reserved for getters and
@@ -217,7 +213,7 @@
 
   /// If we can't find a hash based name in the three-letter space, then base
   /// the name on a letter and a counter.
-  String _badName(int hash, Set<String> usedNames) {
+  String _badName(int hash, NamingScope scope) {
     int count = _badNames.putIfAbsent(hash, () => 0);
     String startLetter =
         new String.fromCharCodes([_letterNumber(hash + count)]);
@@ -226,7 +222,7 @@
     int i = 0;
     do {
       name = "$startLetter${i++}";
-    } while (usedNames.contains(name));
+    } while (scope.isUsed(name));
     // We don't need to check for banned prefix because the name is in the form
     // xnnn, where nnn is a number.  There can be no getter or setter called
     // gnnn since that would imply a numeric field name.
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 783b518..bd55710 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -356,6 +356,11 @@
   jsAst.Name _literalSetterPrefix;
   jsAst.Name _literalLazyGetterPrefix;
 
+  jsAst.Name _staticsPropertyName;
+
+  jsAst.Name get staticsPropertyName =>
+      _staticsPropertyName ??= new StringBackedName('static');
+
   // Name of property in a class description for the native dispatch metadata.
   final String nativeSpecProperty = '%';
 
@@ -370,7 +375,7 @@
   /// Although global names are distributed across a number of global objects,
   /// (see [globalObjectFor]), we currently use a single namespace for all these
   /// names.
-  final Set<String> usedGlobalNames = new Set<String>();
+  final NamingScope globalScope = new NamingScope();
   final Map<Element, jsAst.Name> userGlobals =
       new HashMap<Element, jsAst.Name>();
   final Map<String, jsAst.Name> internalGlobals =
@@ -379,7 +384,7 @@
   /// Used disambiguated names in the instance namespace, issued by
   /// [_disambiguateMember], [_disambiguateInternalMember],
   /// [_disambiguateOperator], and [reservePublicMemberName].
-  final Set<String> usedInstanceNames = new Set<String>();
+  final NamingScope instanceScope = new NamingScope();
   final Map<String, jsAst.Name> userInstanceMembers =
       new HashMap<String, jsAst.Name>();
   final Map<Element, jsAst.Name> internalInstanceMembers =
@@ -388,18 +393,11 @@
       new HashMap<String, jsAst.Name>();
 
   /// Used to disambiguate names for constants in [constantName].
-  final Set<String> usedConstantNames = new Set<String>();
+  final NamingScope constantScope = new NamingScope();
 
-  Set<String> getUsedNames(NamingScope scope) {
-    if (scope == NamingScope.global) {
-      return usedGlobalNames;
-    } else if (scope == NamingScope.instance){
-      return usedInstanceNames;
-    } else {
-      assert(scope == NamingScope.constant);
-      return usedConstantNames;
-    }
-  }
+  /// Used to store scopes for instances of [PrivatelyNamedJsEntity]
+  final Map<Entity, NamingScope> _privateNamingScopes =
+      new Map<Entity, NamingScope>();
 
   final Map<String, int> popularNameCounters = <String, int>{};
 
@@ -417,28 +415,9 @@
   final Map<String, LibraryElement> shortPrivateNameOwners =
       <String, LibraryElement>{};
 
-  /// Maps proposed names to *suggested* disambiguated names.
-  ///
-  /// Suggested names are hints to the [MinifyNamer], suggesting that a specific
-  /// names be given to the first item with the given proposed name.
-  ///
-  /// This is currently used in [MinifyNamer] to assign very short minified
-  /// names to things that tend to be used very often.
   final Map<String, String> suggestedGlobalNames = <String, String>{};
   final Map<String, String> suggestedInstanceNames = <String, String>{};
 
-  Map<String, String> getSuggestedNames(NamingScope scope) {
-    if (scope == NamingScope.global) {
-      return suggestedGlobalNames;
-    } else if (scope == NamingScope.instance) {
-      return suggestedInstanceNames;
-    } else {
-      assert(scope == NamingScope.constant);
-      return const {};
-    }
-  }
-
-
   /// Used to store unique keys for library names. Keys are not used as names,
   /// nor are they visible in the output. The only serve as an internal
   /// key into maps.
@@ -457,8 +436,12 @@
 
   JavaScriptBackend get backend => compiler.backend;
 
+  BackendHelpers get helpers => backend.helpers;
+
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   String get deferredTypesName => 'deferredTypes';
   String get isolateName => 'Isolate';
   String get isolatePropertiesName => r'$isolateProperties';
@@ -472,6 +455,11 @@
   String get closureInvocationSelectorName => Identifiers.call;
   bool get shouldMinify => false;
 
+  NamingScope _getPrivateScopeFor(PrivatelyNamedJSEntity entity) {
+    return _privateNamingScopes.putIfAbsent(entity.rootOfScope,
+                                            () => new NamingScope());
+  }
+
   /// Returns the string that is to be used as the result of a call to
   /// [JS_GET_NAME] at [node] with argument [name].
   jsAst.Name getNameForJsGetName(Node node, JsGetName name) {
@@ -506,14 +494,13 @@
       case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG:
         return asName(functionTypeNamedParametersTag);
       case JsGetName.IS_INDEXABLE_FIELD_NAME:
-        Element cls = backend.findHelper('JavaScriptIndexingBehavior');
-        return operatorIs(cls);
+        return operatorIs(helpers.jsIndexingBehaviorInterface);
       case JsGetName.NULL_CLASS_TYPE_NAME:
-        return runtimeTypeName(compiler.nullClass);
+        return runtimeTypeName(coreClasses.nullClass);
       case JsGetName.OBJECT_CLASS_TYPE_NAME:
-        return runtimeTypeName(compiler.objectClass);
+        return runtimeTypeName(coreClasses.objectClass);
       case JsGetName.FUNCTION_CLASS_TYPE_NAME:
-        return runtimeTypeName(compiler.functionClass);
+        return runtimeTypeName(coreClasses.functionClass);
       default:
         reporter.reportErrorMessage(
           node,
@@ -542,7 +529,7 @@
     jsAst.Name result = constantNames[constant];
     if (result == null) {
       String longName = constantLongName(constant);
-      result = getFreshName(NamingScope.constant, longName);
+      result = getFreshName(constantScope, longName);
       constantNames[constant] = result;
     }
     return _newReference(result);
@@ -637,8 +624,9 @@
   }
 
   String _jsNameHelper(Element e) {
-    if (e.jsInteropName != null && e.jsInteropName.isNotEmpty)
-      return e.jsInteropName;
+    String jsInteropName = backend.getJsInteropName(e);
+    if (jsInteropName != null && jsInteropName.isNotEmpty)
+      return jsInteropName;
     return e.isLibrary ? 'self' : e.name;
   }
 
@@ -649,7 +637,7 @@
   /// Map class of the goog.map JavaScript library would have path
   /// "goog.maps.Map".
   String fixedBackendPath(Element element) {
-    if (!element.isJsInterop) return null;
+    if (!backend.isJsInterop(element)) return null;
     if (element.isInstanceMember) return 'this';
     if (element.isConstructor) return fixedBackendPath(element.enclosingClass);
     if (element.isLibrary) return 'self';
@@ -791,18 +779,21 @@
   jsAst.Name instanceFieldPropertyName(FieldElement element) {
     ClassElement enclosingClass = element.enclosingClass;
 
-    if (element.hasFixedBackendName) {
-      return new StringBackedName(element.fixedBackendName);
+    if (backend.hasFixedBackendName(element)) {
+      return new StringBackedName(backend.getFixedBackendName(element));
     }
 
-    // Instances of BoxFieldElement are special. They are already created with
-    // a unique and safe name. However, as boxes are not really instances of
-    // classes, the usual naming scheme that tries to avoid name clashes with
-    // super classes does not apply. We still do not mark the name as a
-    // fixedBackendName, as we want to allow other namers to do something more
-    // clever with them.
-    if (element is BoxFieldElement) {
-      return new StringBackedName(element.name);
+    // Some elements, like e.g. instances of BoxFieldElement are special.
+    // They are created with a unique and safe name for the element model.
+    // While their name is unique, it is not very readable. So we try to
+    // preserve the original, proposed name.
+    // However, as boxes are not really instances of classes, the usual naming
+    // scheme that tries to avoid name clashes with super classes does not
+    // apply. So we can directly grab a name.
+    Entity asEntity = element;
+    if (asEntity is JSEntity) {
+      return _disambiguateInternalMember(element,
+                                         () => asEntity.declaredEntity.name);
     }
 
     // If the name of the field might clash with another field,
@@ -832,8 +823,8 @@
 
   /// True if [class_] is a non-native class that inherits from a native class.
   bool _isUserClassExtendingNative(ClassElement class_) {
-    return !class_.isNative &&
-           Elements.isNativeOrExtendsNative(class_.superclass);
+    return !backend.isNative(class_) &&
+           backend.isNativeOrExtendsNative(class_.superclass);
   }
 
   /// Annotated name for the setter of [element].
@@ -878,7 +869,7 @@
   jsAst.Name _disambiguateInternalGlobal(String name) {
     jsAst.Name newName = internalGlobals[name];
     if (newName == null) {
-      newName = getFreshName(NamingScope.global, name);
+      newName = getFreshName(globalScope, name);
       internalGlobals[name] = newName;
     }
     return _newReference(newName);
@@ -925,7 +916,7 @@
     jsAst.Name newName = userGlobals[element];
     if (newName == null) {
       String proposedName = _proposeNameForGlobal(element);
-      newName = getFreshName(NamingScope.global, proposedName);
+      newName = getFreshName(globalScope, proposedName);
       userGlobals[element] = newName;
     }
     return _newReference(newName);
@@ -965,7 +956,7 @@
         // proposed name must be a valid identifier, but not necessarily unique.
         proposedName += r'$' + suffixes.join(r'$');
       }
-      newName = getFreshName(NamingScope.instance, proposedName,
+      newName = getFreshName(instanceScope, proposedName,
                              sanitizeForAnnotations: true);
       userInstanceMembers[key] = newName;
     }
@@ -988,7 +979,7 @@
     jsAst.Name newName = userInstanceMembers[key];
     if (newName == null) {
       String name = proposeName();
-      newName = getFreshName(NamingScope.instance, name,
+      newName = getFreshName(instanceScope, name,
                              sanitizeForAnnotations: true);
       userInstanceMembers[key] = newName;
     }
@@ -1010,9 +1001,9 @@
     String suffix = ''; // We don't need any suffixes.
     String key = '$libraryPrefix@$originalName@$suffix';
     assert(!userInstanceMembers.containsKey(key));
-    assert(!usedInstanceNames.contains(disambiguatedName));
+    assert(!instanceScope.isUsed(disambiguatedName));
     userInstanceMembers[key] = new StringBackedName(disambiguatedName);
-    usedInstanceNames.add(disambiguatedName);
+    instanceScope.registerUse(disambiguatedName);
   }
 
   /// Disambiguated name unique to [element].
@@ -1026,11 +1017,22 @@
     jsAst.Name newName = internalInstanceMembers[element];
     if (newName == null) {
       String name = proposeName();
-      bool mayClashNative = _isUserClassExtendingNative(element.enclosingClass);
-      newName = getFreshName(NamingScope.instance, name,
-                             sanitizeForAnnotations: true,
-                             sanitizeForNatives: mayClashNative);
-      internalInstanceMembers[element] = newName;
+
+      Entity asEntity = element;
+      if (asEntity is PrivatelyNamedJSEntity) {
+        NamingScope scope = _getPrivateScopeFor(asEntity);
+        newName = getFreshName(scope, name,
+                               sanitizeForAnnotations: true,
+                               sanitizeForNatives: false);
+        internalInstanceMembers[element] = newName;
+      } else {
+        bool mayClashNative =
+            _isUserClassExtendingNative(element.enclosingClass);
+        newName = getFreshName(instanceScope, name,
+                               sanitizeForAnnotations: true,
+                               sanitizeForNatives: mayClashNative);
+        internalInstanceMembers[element] = newName;
+      }
     }
     return _newReference(newName);
   }
@@ -1044,15 +1046,14 @@
   jsAst.Name _disambiguateOperator(String operatorIdentifier) {
     jsAst.Name newName = userInstanceOperators[operatorIdentifier];
     if (newName == null) {
-      newName = getFreshName(NamingScope.instance, operatorIdentifier);
+      newName = getFreshName(instanceScope, operatorIdentifier);
       userInstanceOperators[operatorIdentifier] = newName;
     }
     return _newReference(newName);
   }
 
   String _generateFreshStringForName(String proposedName,
-      Set<String> usedNames,
-      Map<String, String> suggestedNames,
+      NamingScope scope,
       {bool sanitizeForAnnotations: false,
        bool sanitizeForNatives: false}) {
     if (sanitizeForAnnotations) {
@@ -1063,18 +1064,18 @@
     }
     proposedName = _sanitizeForKeywords(proposedName);
     String candidate;
-    if (!usedNames.contains(proposedName)) {
+    if (scope.isUnused(proposedName)) {
       candidate = proposedName;
     } else {
       int counter = popularNameCounters[proposedName];
       int i = (counter == null) ? 0 : counter;
-      while (usedNames.contains("$proposedName$i")) {
+      while (scope.isUsed("$proposedName$i")) {
         i++;
       }
       popularNameCounters[proposedName] = i + 1;
       candidate = "$proposedName$i";
     }
-    usedNames.add(candidate);
+    scope.registerUse(candidate);
     return candidate;
   }
 
@@ -1096,8 +1097,7 @@
                            bool sanitizeForNatives: false}) {
     String candidate =
         _generateFreshStringForName(proposedName,
-                                    getUsedNames(scope),
-                                    getSuggestedNames(scope),
+                                    scope,
                                     sanitizeForAnnotations:
                                         sanitizeForAnnotations,
                                     sanitizeForNatives: sanitizeForNatives);
@@ -1204,23 +1204,23 @@
 
   String suffixForGetInterceptor(Iterable<ClassElement> classes) {
     String abbreviate(ClassElement cls) {
-      if (cls == compiler.objectClass) return "o";
-      if (cls == backend.jsStringClass) return "s";
-      if (cls == backend.jsArrayClass) return "a";
-      if (cls == backend.jsDoubleClass) return "d";
-      if (cls == backend.jsIntClass) return "i";
-      if (cls == backend.jsNumberClass) return "n";
-      if (cls == backend.jsNullClass) return "u";
-      if (cls == backend.jsBoolClass) return "b";
-      if (cls == backend.jsInterceptorClass) return "I";
+      if (cls == coreClasses.objectClass) return "o";
+      if (cls == helpers.jsStringClass) return "s";
+      if (cls == helpers.jsArrayClass) return "a";
+      if (cls == helpers.jsDoubleClass) return "d";
+      if (cls == helpers.jsIntClass) return "i";
+      if (cls == helpers.jsNumberClass) return "n";
+      if (cls == helpers.jsNullClass) return "u";
+      if (cls == helpers.jsBoolClass) return "b";
+      if (cls == helpers.jsInterceptorClass) return "I";
       return cls.name;
     }
     List<String> names = classes
-        .where((cls) => !Elements.isNativeOrExtendsNative(cls))
+        .where((cls) => !backend.isNativeOrExtendsNative(cls))
         .map(abbreviate)
         .toList();
     // There is one dispatch mechanism for all native classes.
-    if (classes.any((cls) => Elements.isNativeOrExtendsNative(cls))) {
+    if (classes.any((cls) => backend.isNativeOrExtendsNative(cls))) {
       names.add("x");
     }
     // Sort the names of the classes after abbreviating them to ensure
@@ -1231,8 +1231,8 @@
 
   /// Property name used for `getInterceptor` or one of its specializations.
   jsAst.Name nameForGetInterceptor(Iterable<ClassElement> classes) {
-    FunctionElement getInterceptor = backend.getInterceptorMethod;
-    if (classes.contains(backend.jsInterceptorClass)) {
+    FunctionElement getInterceptor = helpers.getInterceptorMethod;
+    if (classes.contains(helpers.jsInterceptorClass)) {
       // If the base Interceptor class is in the set of intercepted classes, we
       // need to go through the generic getInterceptorMethod, since any subclass
       // of the base Interceptor could match.
@@ -1254,7 +1254,7 @@
     // other global names.
     jsAst.Name root = invocationName(selector);
 
-    if (classes.contains(backend.jsInterceptorClass)) {
+    if (classes.contains(helpers.jsInterceptorClass)) {
       // If the base Interceptor class is in the set of intercepted classes,
       // this is the most general specialization which uses the generic
       // getInterceptor method.
@@ -1364,7 +1364,7 @@
   String globalObjectFor(Element element) {
     if (_isPropertyOfStaticStateHolder(element)) return staticStateHolder;
     LibraryElement library = element.library;
-    if (library == backend.interceptorsLibrary) return 'J';
+    if (library == helpers.interceptorsLibrary) return 'J';
     if (library.isInternalLibrary) return 'H';
     if (library.isPlatformLibrary) {
       if ('${library.canonicalUri}' == 'dart:html') return 'W';
@@ -1432,7 +1432,7 @@
   jsAst.Name getFunctionTypeName(FunctionType functionType) {
     return functionTypeNameMap.putIfAbsent(functionType, () {
       String proposedName = functionTypeNamer.computeName(functionType);
-      return getFreshName(NamingScope.instance, proposedName);
+      return getFreshName(instanceScope, proposedName);
     });
   }
 
@@ -1568,7 +1568,6 @@
   void forgetElement(Element element) {
     jsAst.Name globalName = userGlobals[element];
     invariant(element, globalName != null, message: 'No global name.');
-    usedGlobalNames.remove(globalName);
     userGlobals.remove(element);
   }
 }
@@ -1894,6 +1893,8 @@
 
   @override
   int visitDeferred(DeferredConstantValue constant, [_]) {
+    // TODO(sra): Investigate that the use of hashCode here is probably a source
+    // of instability.
     int hash = constant.prefix.hashCode;
     return _combine(hash, _visit(constant.referenced));
   }
@@ -2024,8 +2025,29 @@
   }
 }
 
-enum NamingScope {
-  global,
-  instance,
-  constant
+
+class NamingScope {
+  /// Maps proposed names to *suggested* disambiguated names.
+  ///
+  /// Suggested names are hints to the [MinifyNamer], suggesting that a specific
+  /// names be given to the first item with the given proposed name.
+  ///
+  /// This is currently used in [MinifyNamer] to assign very short minified
+  /// names to things that tend to be used very often.
+  final Map<String, String> _suggestedNames = new Map<String, String>();
+  final Set<String> _usedNames = new Set<String>();
+
+  bool isUsed(String name) => _usedNames.contains(name);
+  bool isUnused(String name) => !_usedNames.contains(name);
+  bool registerUse(String name) => _usedNames.add(name);
+
+  String suggestName(String original) => _suggestedNames[original];
+  void addSuggestion(String original, String suggestion) {
+    assert(!_suggestedNames.containsKey(original));
+    _suggestedNames[original] = suggestion;
+  }
+  bool hasSuggestion(String original) => _suggestedNames.containsKey(original);
+  bool isSuggestion(String candidate) {
+    return _suggestedNames.containsValue(candidate);
+  }
 }
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 3bb7e45..ee09ed3 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
@@ -167,9 +167,9 @@
 
   bool _isDefaultNoSuchMethodImplementation(FunctionElement element) {
     ClassElement classElement = element.enclosingClass;
-    return classElement == _compiler.objectClass
-        || classElement == _backend.jsInterceptorClass
-        || classElement == _backend.jsNullClass;
+    return classElement == _compiler.coreClasses.objectClass
+        || classElement == _backend.helpers.jsInterceptorClass
+        || classElement == _backend.helpers.jsNullClass;
   }
 
   bool _hasForwardingSyntax(FunctionElement element) {
diff --git a/pkg/compiler/lib/src/js_backend/patch_resolver.dart b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
index c8e609d..60573ed 100644
--- a/pkg/compiler/lib/src/js_backend/patch_resolver.dart
+++ b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
@@ -31,7 +31,7 @@
       });
       checkMatchingPatchSignatures(element, patch);
       element = patch;
-    } else if (!element.isJsInterop) {
+    } else if (!compiler.backend.isJsInterop(element)) {
       reporter.reportErrorMessage(
          element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
     }
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index a5136ad..849fae3 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -264,8 +264,9 @@
     // the calls of the list constructor whenever we determine that
     // JSArray needs type arguments.
     // TODO(karlklose): make this dependency visible from code.
-    if (backend.jsArrayClass != null) {
-      registerRtiDependency(backend.jsArrayClass, compiler.listClass);
+    if (backend.helpers.jsArrayClass != null) {
+      registerRtiDependency(
+          backend.helpers.jsArrayClass, compiler.coreClasses.listClass);
     }
     // Compute the set of all classes and methods that need runtime type
     // information.
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 2ebda27..3fb220a 100644
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
@@ -32,7 +32,7 @@
 
   TypeVariableHandler(this._compiler);
 
-  ClassElement get _typeVariableClass => _backend.typeVariableClass;
+  ClassElement get _typeVariableClass => _backend.helpers.typeVariableClass;
   CodeEmitterTask get _task => _backend.emitter;
   MetadataCollector get _metadataCollector => _task.metadataCollector;
   JavaScriptBackend get _backend => _compiler.backend;
@@ -56,7 +56,9 @@
         _backend.registerInstantiatedType(
             _typeVariableClass.rawType, enqueuer, registry);
         enqueuer.registerStaticUse(
-            _backend.registerBackendUse(_backend.helpers.createRuntimeType));
+            new StaticUse.staticInvoke(
+                _backend.registerBackendUse(_backend.helpers.createRuntimeType),
+                CallStructure.ONE_ARG));
         _seenClassesWithTypeVariables = true;
       }
     } else {
@@ -119,6 +121,7 @@
               arguments);
       ConstantValue value = constant.value;
       _backend.registerCompileTimeConstant(value, _compiler.globalDependencies);
+      _backend.addCompileTimeConstantForEmission(value);
       _backend.constants.addCompileTimeConstantForEmission(value);
       constants.add(
           _reifyTypeVariableConstant(value, currentTypeVariable.element));
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index cdd676b..87f9d41 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -206,7 +206,7 @@
   Namer namer = backend.namer;
   Compiler compiler = backend.compiler;
 
-  Element closureFromTearOff = backend.findHelper('closureFromTearOff');
+  Element closureFromTearOff = backend.helpers.closureFromTearOff;
   jsAst.Expression tearOffAccessExpression;
   jsAst.Expression tearOffGlobalObjectString;
   jsAst.Expression tearOffGlobalObject;
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
new file mode 100644
index 0000000..8e574c8
--- /dev/null
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -0,0 +1,213 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.js_emitter.constant_ordering;
+
+import '../constants/values.dart';
+
+import '../common.dart';
+//import '../core_types.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart'
+    show Element,
+         Elements,
+         FieldElement;
+import '../tree/tree.dart' show DartString;
+import '../js_backend/js_backend.dart' show SyntheticConstantKind;
+
+/// A canonical but arbrary ordering of constants. The ordering is 'stable'
+/// under perturbation of the source.
+int deepCompareConstants(ConstantValue a, ConstantValue b) {
+  return _CompareVisitor.compareValues(a, b);
+}
+
+class _CompareVisitor implements ConstantValueVisitor<int, ConstantValue> {
+  const _CompareVisitor();
+
+  static int compareValues(ConstantValue a, ConstantValue b) {
+    if (identical(a, b)) return 0;
+    int r = _KindVisitor.kind(a).compareTo(_KindVisitor.kind(b));
+    if (r != 0) return r;
+    r = a.accept(const _CompareVisitor(), b);
+    return r;
+  }
+
+  static int compareNullable(int compare(a, b), a, b) {
+    if (a == null && b == null) return 0;
+    if (a == null) return -1;
+    if (b == null) return 1;
+    return compare(a, b);
+  }
+
+  static int compareLists(int compare(a, b), List a, List b) {
+    int r = a.length.compareTo(b.length);
+    if (r != 0) return r;
+    for (int i = 0; i < a.length; i++) {
+      r = compare(a[i], b[i]);
+      if (r != 0) return r;
+    }
+    return 0;
+  }
+
+  static int compareElements(Element a, Element b) {
+    int r = a.name.compareTo(b.name);
+    if (r != 0) return r;
+    return Elements.compareByPosition(a, b);
+  }
+
+  static int compareDartTypes(DartType a, DartType b) {
+    if (a == b) return 0;
+    int r = a.kind.index.compareTo(b.kind.index);
+    if (r != 0) return r;
+    r = compareNullable(compareElements, a.element, b.element);
+    if (r != 0) return r;
+
+    if (a is GenericType) {
+      GenericType aGeneric = a;
+      GenericType bGeneric = b;
+      r = compareLists(compareDartTypes,
+                       aGeneric.typeArguments, bGeneric.typeArguments);
+      if (r != 0) return r;
+    }
+    throw 'unexpected compareDartTypes  $a  $b';
+  }
+
+  int visitFunction(FunctionConstantValue a, FunctionConstantValue b) {
+    return compareElements(a.element, b.element);
+  }
+
+  int visitNull(NullConstantValue a, NullConstantValue b) {
+    return 0;
+  }
+
+  int visitInt(IntConstantValue a, IntConstantValue b) {
+    return a.primitiveValue.compareTo(b.primitiveValue);
+  }
+
+  int visitDouble(DoubleConstantValue a, DoubleConstantValue b) {
+    return a.primitiveValue.compareTo(b.primitiveValue);
+  }
+
+  int visitBool(BoolConstantValue a, BoolConstantValue b) {
+    int aInt = a.primitiveValue ? 1 : 0;
+    int bInt = b.primitiveValue ? 1 : 0;
+    return aInt.compareTo(bInt);
+  }
+
+  int visitString(StringConstantValue a, StringConstantValue b) {
+    DartString aString = a.primitiveValue;
+    DartString bString = b.primitiveValue;
+    int r = aString.length.compareTo(bString.length);
+    if (r != 0) return r;
+    return aString.slowToString().compareTo(bString.slowToString());
+  }
+
+  int visitList(ListConstantValue a, ListConstantValue b) {
+    int r = compareLists(compareValues, a.entries, b.entries);
+    if (r != 0) return r;
+    return compareDartTypes(a.type, b.type);
+  }
+
+  int visitMap(MapConstantValue a, MapConstantValue b) {
+    int r = compareLists(compareValues, a.keys, b.keys);
+    if (r != 0) return r;
+    r = compareLists(compareValues, a.values, b.values);
+    if (r != 0) return r;
+    return compareDartTypes(a.type, b.type);
+  }
+
+  int visitConstructed(ConstructedConstantValue a, ConstructedConstantValue b) {
+    int r = compareDartTypes(a.type, b.type);
+    if (r != 0) return r;
+
+    List<FieldElement> aFields = a.fields.keys.toList()..sort(compareElements);
+    List<FieldElement> bFields = b.fields.keys.toList()..sort(compareElements);
+
+    r = compareLists(compareElements, aFields, bFields);
+    if (r != 0) return r;
+
+    return compareLists(compareValues,
+        aFields.map((field) => a.fields[field]).toList(),
+        aFields.map((field) => b.fields[field]).toList());
+  }
+
+  int visitType(TypeConstantValue a, TypeConstantValue b) {
+    int r = compareDartTypes(a.representedType, b.representedType);
+    if (r != 0) return r;
+    return compareDartTypes(a.type, b.type);
+  }
+
+  int visitInterceptor(InterceptorConstantValue a, InterceptorConstantValue b) {
+    return compareDartTypes(a.dispatchedType, b.dispatchedType);
+  }
+
+  int visitSynthetic(SyntheticConstantValue a, SyntheticConstantValue b) {
+    // [SyntheticConstantValue]s have abstract fields that are set only by
+    // convention.  Lucky for us, they do not occur as top level constant, only
+    // as elements of a few constants.  If this becomes a source of instability,
+    // we will need to add a total ordering on JavaScript ASTs including
+    // deferred elements.
+    SyntheticConstantKind aKind = a.kind;
+    SyntheticConstantKind bKind = b.kind;
+    int r = aKind.index - bKind.index;
+    if (r != 0) return r;
+    switch (a.kind) {
+      case SyntheticConstantKind.DUMMY_INTERCEPTOR:
+      case SyntheticConstantKind.EMPTY_VALUE:
+        // Never emitted.
+        return 0;
+
+      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
+        // An opaque deferred JS AST reference to a type in reflection data.
+        return 0;
+      case SyntheticConstantKind.NAME:
+        // An opaque deferred JS AST reference to a name.
+        return 0;
+      default:
+        // Should not happen.
+        throw 'unexpected SyntheticConstantKind $aKind';
+    }
+  }
+
+  int visitDeferred(DeferredConstantValue a, DeferredConstantValue b) {
+    int r = compareValues(a.referenced, b.referenced);
+    if (r != 0) return r;
+    return compareElements(a.prefix, b.prefix);
+  }
+}
+
+class _KindVisitor implements ConstantValueVisitor<int, Null> {
+  const _KindVisitor();
+
+  static const int FUNCTION = 1;
+  static const int NULL = 2;
+  static const int INT = 3;
+  static const int DOUBLE = 4;
+  static const int BOOL = 5;
+  static const int STRING = 6;
+  static const int LIST = 7;
+  static const int MAP = 8;
+  static const int CONSTRUCTED = 9;
+  static const int TYPE = 10;
+  static const int INTERCEPTOR = 11;
+  static const int SYNTHETIC = 12;
+  static const int DEFERRED = 13;
+
+  static int kind(ConstantValue constant) =>
+      constant.accept(const _KindVisitor(), null);
+
+  int visitFunction(FunctionConstantValue a, _) => FUNCTION;
+  int visitNull(NullConstantValue a, _) => NULL;
+  int visitInt(IntConstantValue a, _) => INT;
+  int visitDouble(DoubleConstantValue a, _) => DOUBLE;
+  int visitBool(BoolConstantValue a, _) => BOOL;
+  int visitString(StringConstantValue a, _) => STRING;
+  int visitList(ListConstantValue a, _) => LIST;
+  int visitMap(MapConstantValue a, _) => MAP;
+  int visitConstructed(ConstructedConstantValue a, _) => CONSTRUCTED;
+  int visitType(TypeConstantValue a, _) => TYPE;
+  int visitInterceptor(InterceptorConstantValue a, _) => INTERCEPTOR;
+  int visitSynthetic(SyntheticConstantValue a, _) => SYNTHETIC;
+  int visitDeferred(DeferredConstantValue a, _) => DEFERRED;
+}
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
index cb03c3e..06aa189 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
@@ -45,7 +45,7 @@
     emitRuntimeTypeInformation(cls, builder);
     emitNativeInfo(cls, builder);
 
-    if (classElement == backend.closureClass) {
+    if (classElement == backend.helpers.closureClass) {
       // We add a special getter here to allow for tearing off a closure from
       // itself.
       jsAst.Fun function = js('function() { return this; }');
@@ -253,8 +253,7 @@
       emitter.containerBuilder.addMemberMethod(method, builder);
     }
 
-    if (identical(classElement, compiler.objectClass)
-        && backend.enabledNoSuchMethod) {
+    if (classElement.isObject && backend.enabledNoSuchMethod) {
       // Emit the noSuchMethod handlers on the Object prototype now,
       // so that the code in the dynamicFunction helper can find
       // them. Note that this helper is invoked before analyzing the
@@ -329,8 +328,9 @@
     }
 
     if (!statics.isEmpty) {
-      classBuilder.addPropertyByName('static',
-                                     new jsAst.ObjectInitializer(statics));
+      classBuilder.addProperty(
+          namer.staticsPropertyName, // 'static' or its minified name.
+          new jsAst.ObjectInitializer(statics, isOneLiner: false));
     }
 
     // TODO(ahe): This method (generateClass) should return a jsAst.Expression.
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart
index 78c963d..6c7ee56 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart
@@ -11,6 +11,8 @@
 
   JavaScriptBackend get backend => emitter.backend;
 
+  BackendHelpers get helpers => backend.helpers;
+
   CodeEmitterTask get task => emitter.task;
 
   Compiler get compiler => emitter.compiler;
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index 473766a..fb34fae 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -17,6 +17,7 @@
 import '../js_emitter.dart' as js_emitter show Emitter;
 import '../model.dart';
 import '../program_builder/program_builder.dart';
+import '../constant_ordering.dart' show deepCompareConstants;
 
 import '../../common.dart';
 import '../../common/names.dart' show
@@ -24,6 +25,8 @@
 import '../../compiler.dart' show
     Compiler;
 import '../../constants/values.dart';
+import '../../core_types.dart' show
+    CoreClasses;
 import '../../dart_types.dart' show
     DartType;
 import '../../deferred_load.dart' show OutputUnit;
@@ -54,6 +57,8 @@
     SourceMapBuilder;
 import '../../js/js.dart' as jsAst;
 import '../../js/js.dart' show js;
+import '../../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../../js_backend/js_backend.dart' show
     CheckedModeHelper,
     CompoundName,
@@ -131,6 +136,7 @@
   ConstantEmitter constantEmitter;
   NativeEmitter get nativeEmitter => task.nativeEmitter;
   TypeTestRegistry get typeTestRegistry => task.typeTestRegistry;
+  CoreClasses get coreClasses => compiler.coreClasses;
 
   // The full code that is written to each hunk part-file.
   Map<OutputUnit, CodeOutput> outputBuffers = new Map<OutputUnit, CodeOutput>();
@@ -247,11 +253,9 @@
     // which compresses a tiny bit better.
     int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
     if (r != 0) return r;
-    // Resolve collisions in the long name by using the constant name (i.e. JS
-    // name) which is unique.
-    // TODO(herhut): Find a better way to resolve collisions.
-    return namer.constantName(a).hashCode.compareTo(
-        namer.constantName(b).hashCode);
+
+    // Resolve collisions in the long name by using a structural order.
+    return deepCompareConstants(a, b);
   }
 
   @override
@@ -370,7 +374,7 @@
     switch (builtin) {
       case JsBuiltin.dartObjectConstructor:
         return jsAst.js.expressionTemplateYielding(
-            typeAccess(compiler.objectClass));
+            typeAccess(coreClasses.objectClass));
 
       case JsBuiltin.isCheckPropertyToJsConstructorName:
         int isPrefixLength = namer.operatorIsPrefix.length;
@@ -445,13 +449,13 @@
   /// In minified mode we want to keep the name for the most common core types.
   bool _isNativeTypeNeedingReflectionName(Element element) {
     if (!element.isClass) return false;
-    return (element == compiler.intClass ||
-            element == compiler.doubleClass ||
-            element == compiler.numClass ||
-            element == compiler.stringClass ||
-            element == compiler.boolClass ||
-            element == compiler.nullClass ||
-            element == compiler.listClass);
+    return (element == coreClasses.intClass ||
+            element == coreClasses.doubleClass ||
+            element == coreClasses.numClass ||
+            element == coreClasses.stringClass ||
+            element == coreClasses.boolClass ||
+            element == coreClasses.nullClass ||
+            element == coreClasses.listClass);
   }
 
   /// Returns the "reflection name" of an [Element] or [Selector].
@@ -670,56 +674,66 @@
     return new jsAst.Block(parts);
   }
 
-  jsAst.Statement buildLazilyInitializedStaticFields() {
-    JavaScriptConstantCompiler handler = backend.constants;
-    List<VariableElement> lazyFields =
-        handler.getLazilyInitializedFieldsForEmission();
+  jsAst.Statement buildLazilyInitializedStaticFields(
+      Iterable<StaticField> lazyFields, {bool isMainFragment: true}) {
     if (lazyFields.isNotEmpty) {
       needsLazyInitializer = true;
-      List<jsAst.Expression> laziesInfo = buildLaziesInfo(lazyFields);
+      List<jsAst.Expression> laziesInfo =
+          buildLaziesInfo(lazyFields, isMainFragment);
       return js.statement('''
       (function(lazies) {
         for (var i = 0; i < lazies.length; ) {
           var fieldName = lazies[i++];
           var getterName = lazies[i++];
+          var lazyValue = lazies[i++];
           if (#notMinified) {
             var staticName = lazies[i++];
           }
-          var lazyValue = lazies[i++];
-
+          if (#isDeferredFragment) {
+            var fieldHolder = lazies[i++];
+          }
           // We build the lazy-check here:
           //   lazyInitializer(fieldName, getterName, lazyValue, staticName);
           // 'staticName' is used for error reporting in non-minified mode.
           // 'lazyValue' must be a closure that constructs the initial value.
-          if (#notMinified) {
-            #lazy(fieldName, getterName, lazyValue, staticName);
+          if (#isMainFragment) {
+            if (#notMinified) {
+              #lazy(fieldName, getterName, lazyValue, staticName);
+            } else {
+              #lazy(fieldName, getterName, lazyValue);
+            }
           } else {
-            #lazy(fieldName, getterName, lazyValue);
+            if (#notMinified) {
+              #lazy(fieldName, getterName, lazyValue, staticName, fieldHolder);
+            } else {
+              #lazy(fieldName, getterName, lazyValue, null, fieldHolder);
+            }
           }
         }
       })(#laziesInfo)
       ''', {'notMinified': !compiler.enableMinification,
             'laziesInfo': new jsAst.ArrayInitializer(laziesInfo),
-            'lazy': js(lazyInitializerName)});
+            'lazy': js(lazyInitializerName),
+            'isMainFragment': isMainFragment,
+            'isDeferredFragment': !isMainFragment});
     } else {
       return js.comment("No lazy statics.");
     }
   }
 
-  List<jsAst.Expression> buildLaziesInfo(List<VariableElement> lazies) {
+  List<jsAst.Expression> buildLaziesInfo(
+      Iterable<StaticField> lazies, bool isMainFragment) {
     List<jsAst.Expression> laziesInfo = <jsAst.Expression>[];
-    for (VariableElement element in Elements.sortedByPosition(lazies)) {
-      jsAst.Expression code = backend.generatedCode[element];
-      // The code is null if we ended up not needing the lazily
-      // initialized field after all because of constant folding
-      // before code generation.
-      if (code == null) continue;
-      laziesInfo.add(js.quoteName(namer.globalPropertyName(element)));
-      laziesInfo.add(js.quoteName(namer.lazyInitializerName(element)));
+    for (StaticField field in lazies) {
+      laziesInfo.add(js.quoteName(field.name));
+      laziesInfo.add(js.quoteName(namer.deriveLazyInitializerName(field.name)));
+      laziesInfo.add(field.code);
       if (!compiler.enableMinification) {
-        laziesInfo.add(js.string(element.name));
+        laziesInfo.add(js.quoteName(field.name));
       }
-      laziesInfo.add(code);
+      if (!isMainFragment) {
+        laziesInfo.add(js('#', field.holder.name));
+      }
     }
     return laziesInfo;
   }
@@ -1187,8 +1201,8 @@
       // We can be pretty sure that the objectClass is initialized, since
       // typedefs are only emitted with reflection, which requires lots of
       // classes.
-      assert(compiler.objectClass != null);
-      builder.superName = namer.className(compiler.objectClass);
+      assert(coreClasses.objectClass != null);
+      builder.superName = namer.className(coreClasses.objectClass);
       jsAst.Node declaration = builder.toObjectInitializer();
       jsAst.Name mangledName = namer.globalPropertyName(typedef);
       String reflectionName = getReflectionName(typedef, mangledName);
@@ -1366,6 +1380,16 @@
     assembleTypedefs(program);
   }
 
+  jsAst.Statement buildDeferredHeader() {
+    /// 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.
+    return js.statement('self.#deferredInitializers = '
+                        'self.#deferredInitializers || Object.create(null);',
+                        {'deferredInitializers': deferredInitializers});
+  }
+
   jsAst.Program buildOutputAstForMain(Program program,
       Map<OutputUnit, _DeferredOutputUnitHash> deferredLoadHashes) {
     MainFragment mainFragment = program.mainFragment;
@@ -1378,14 +1402,7 @@
               ..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.
-      statements.add(
-          js.statement('self.#deferredInitializers = '
-                       'self.#deferredInitializers || Object.create(null);',
-                       {'deferredInitializers': deferredInitializers}));
+      statements.add(buildDeferredHeader());
     }
 
     // Collect the AST for the decriptors
@@ -1563,7 +1580,8 @@
           mainOutputUnit),
       "typeToInterceptorMap":
           interceptorEmitter.buildTypeToInterceptorMap(program),
-      "lazyStaticFields": buildLazilyInitializedStaticFields(),
+      "lazyStaticFields": buildLazilyInitializedStaticFields(
+          mainFragment.staticLazilyInitializedFields),
       "metadata": buildMetadata(program, mainOutputUnit),
       "convertToFastObject": buildConvertToFastObjectFunction(),
       "convertToSlowObject": buildConvertToSlowObjectFunction(),
@@ -1833,14 +1851,16 @@
 
   ClassBuilder getElementDescriptor(Element element, Fragment fragment) {
     Element owner = element.library;
-    if (!element.isLibrary && !element.isTopLevel && !element.isNative) {
+    if (!element.isLibrary &&
+        !element.isTopLevel &&
+        !backend.isNative(element)) {
       // For static (not top level) elements, record their code in a buffer
       // specific to the class. For now, not supported for native classes and
       // native elements.
       ClassElement cls =
           element.enclosingClassOrCompilationUnit.declaration;
       if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) &&
-          !cls.isNative &&
+          !backend.isNative(cls) &&
           compiler.deferredLoadTask.outputUnitForElement(element) ==
               compiler.deferredLoadTask.outputUnitForElement(cls)) {
         owner = cls;
@@ -1987,11 +2007,14 @@
       body.add(buildCompileTimeConstants(fragment.constants,
                                          isMainFragment: false));
       body.add(buildStaticNonFinalFieldInitializations(outputUnit));
+      body.add(buildLazilyInitializedStaticFields(
+          fragment.staticLazilyInitializedFields, isMainFragment: false));
 
       List<jsAst.Statement> statements = <jsAst.Statement>[];
 
       statements
           ..add(buildGeneratedBy())
+          ..add(buildDeferredHeader())
           ..add(js.statement('${deferredInitializers}.current = '
                              """function (#, ${namer.staticStateHolder}) {
                                   #
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
index c9132ed..573dc34 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
@@ -41,9 +41,9 @@
       Set<ClassElement> classes = specializedGetInterceptors[name];
       parts.add(
           js.statement('#.# = #',
-                       [namer.globalObjectFor(backend.interceptorsLibrary),
-                        name,
-                        buildGetInterceptorMethod(name, classes)]));
+              [namer.globalObjectFor(backend.helpers.interceptorsLibrary),
+               name,
+               buildGetInterceptorMethod(name, classes)]));
     }
 
     return new jsAst.Block(parts);
@@ -56,7 +56,8 @@
 
     InterceptorStubGenerator stubGenerator =
         new InterceptorStubGenerator(compiler, namer, backend);
-    String globalObject = namer.globalObjectFor(backend.interceptorsLibrary);
+    String globalObject =
+        namer.globalObjectFor(backend.helpers.interceptorsLibrary);
     for (jsAst.Name name in names) {
       jsAst.Expression function =
           stubGenerator.generateOneShotInterceptor(name);
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
index f14b9a3..f8911bd 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
@@ -160,7 +160,7 @@
     }
     // Startup code that loops over the method names and puts handlers on the
     // Object class to catch noSuchMethod invocations.
-    ClassElement objectClass = compiler.objectClass;
+    ClassElement objectClass = compiler.coreClasses.objectClass;
     jsAst.Expression createInvocationMirror = backend.emitter
         .staticFunctionAccess(backend.helpers.createInvocationMirror);
     if (useDiffEncoding) {
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
index e256e7b..ecd8a4b 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
@@ -102,6 +102,8 @@
      'mangledNames': mangledNamesAccess,
      'mangledGlobalNames': mangledGlobalNamesAccess,
      'statics': staticsAccess,
+     'staticsPropertyName': namer.staticsPropertyName,
+     'staticsPropertyNameString': js.quoteName(namer.staticsPropertyName),
      'typeInformation': typeInformationAccess,
      'globalFunctions': globalFunctionsAccess,
      'enabledInvokeOn': compiler.enabledInvokeOn,
@@ -129,14 +131,14 @@
      'needsNativeSupport': program.needsNativeSupport,
      'enabledJsInterop': backend.jsInteropAnalysis.enabledJsInterop,
      'jsInteropBoostrap':backend.jsInteropAnalysis.buildJsInteropBootstrap(),
-     'isInterceptorClass': namer.operatorIs(backend.jsInterceptorClass),
-     'isObject' : namer.operatorIs(compiler.objectClass),
+     'isInterceptorClass': namer.operatorIs(backend.helpers.jsInterceptorClass),
+     'isObject' : namer.operatorIs(compiler.coreClasses.objectClass),
      'specProperty': js.string(namer.nativeSpecProperty),
      'trivialNsmHandlers': emitter.buildTrivialNsmHandlers(),
      'hasRetainedMetadata': backend.hasRetainedMetadata,
      'types': typesAccess,
      'objectClassName': js.quoteName(
-         namer.runtimeTypeName(compiler.objectClass)),
+         namer.runtimeTypeName(compiler.coreClasses.objectClass)),
      'needsStructuredMemberInfo': emitter.needsStructuredMemberInfo,
      'usesMangledNames':
           compiler.mirrorsLibrary != null || compiler.enabledFunctionApply,
@@ -526,10 +528,10 @@
       for (var i = 0; i < properties.length; i++) {
         var property = properties[i];
         var firstChar = property.charCodeAt(0);
-        if (property === "static") {
-          processStatics(#statics[cls] = descriptor.static,
+        if (property === #staticsPropertyNameString) {
+          processStatics(#statics[cls] = descriptor.#staticsPropertyName,
                          processedClasses);
-          delete descriptor.static;
+          delete descriptor.#staticsPropertyName;
         } else if (firstChar === 43) { // 43 is "+".
           mangledNames[previousProperty] = property.substring(1);
           var flag = descriptor[property];
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
index 886d3ed..3d3270c 100644
--- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -13,6 +13,8 @@
 
   Emitter get emitter => backend.emitter.emitter;
 
+  BackendHelpers get helpers => backend.helpers;
+
   jsAst.Expression generateGetInterceptorMethod(Set<ClassElement> classes) {
     jsAst.Expression interceptorFor(ClassElement cls) {
       return backend.emitter.interceptorPrototypeAccess(cls);
@@ -25,20 +27,20 @@
     jsAst.Statement buildInterceptorCheck(ClassElement cls) {
       jsAst.Expression condition;
       assert(backend.isInterceptorClass(cls));
-      if (cls == backend.jsBoolClass) {
+      if (cls == helpers.jsBoolClass) {
         condition = js('(typeof receiver) == "boolean"');
-      } else if (cls == backend.jsIntClass ||
-                 cls == backend.jsDoubleClass ||
-                 cls == backend.jsNumberClass) {
+      } else if (cls == helpers.jsIntClass ||
+                 cls == helpers.jsDoubleClass ||
+                 cls == helpers.jsNumberClass) {
         throw 'internal error';
-      } else if (cls == backend.jsArrayClass ||
-                 cls == backend.jsMutableArrayClass ||
-                 cls == backend.jsFixedArrayClass ||
-                 cls == backend.jsExtendableArrayClass) {
+      } else if (cls == helpers.jsArrayClass ||
+                 cls == helpers.jsMutableArrayClass ||
+                 cls == helpers.jsFixedArrayClass ||
+                 cls == helpers.jsExtendableArrayClass) {
         condition = js('receiver.constructor == Array');
-      } else if (cls == backend.jsStringClass) {
+      } else if (cls == helpers.jsStringClass) {
         condition = js('(typeof receiver) == "string"');
-      } else if (cls == backend.jsNullClass) {
+      } else if (cls == helpers.jsNullClass) {
         condition = js('receiver == null');
       } else {
         throw 'internal error';
@@ -58,16 +60,16 @@
           .hasInstantiatedNativeClasses();
 
     for (ClassElement cls in classes) {
-      if (cls == backend.jsArrayClass ||
-          cls == backend.jsMutableArrayClass ||
-          cls == backend.jsFixedArrayClass ||
-          cls == backend.jsExtendableArrayClass) hasArray = true;
-      else if (cls == backend.jsBoolClass) hasBool = true;
-      else if (cls == backend.jsDoubleClass) hasDouble = true;
-      else if (cls == backend.jsIntClass) hasInt = true;
-      else if (cls == backend.jsNullClass) hasNull = true;
-      else if (cls == backend.jsNumberClass) hasNumber = true;
-      else if (cls == backend.jsStringClass) hasString = true;
+      if (cls == helpers.jsArrayClass ||
+          cls == helpers.jsMutableArrayClass ||
+          cls == helpers.jsFixedArrayClass ||
+          cls == helpers.jsExtendableArrayClass) hasArray = true;
+      else if (cls == helpers.jsBoolClass) hasBool = true;
+      else if (cls == helpers.jsDoubleClass) hasDouble = true;
+      else if (cls == helpers.jsIntClass) hasInt = true;
+      else if (cls == helpers.jsNullClass) hasNull = true;
+      else if (cls == helpers.jsNumberClass) hasNumber = true;
+      else if (cls == helpers.jsStringClass) hasString = true;
       else {
         // The set of classes includes classes mixed-in to interceptor classes
         // and user extensions of native classes.
@@ -79,7 +81,7 @@
         // unresolved PlainJavaScriptObject by testing for anyNativeClasses.
 
         if (anyNativeClasses) {
-          if (Elements.isNativeOrExtendsNative(cls)) hasNative = true;
+          if (backend.isNativeOrExtendsNative(cls)) hasNative = true;
         }
       }
     }
@@ -103,13 +105,13 @@
       /// is the fallback used when we have determined that receiver
       /// is a JavaScript Number.
       jsAst.Expression interceptorForNumber = interceptorFor(
-          hasDouble ? backend.jsDoubleClass : backend.jsNumberClass);
+          hasDouble ? helpers.jsDoubleClass : helpers.jsNumberClass);
 
       if (hasInt) {
         whenNumber = js.statement('''{
             if (Math.floor(receiver) == receiver) return #;
             return #;
-        }''', [interceptorFor(backend.jsIntClass), interceptorForNumber]);
+        }''', [interceptorFor(helpers.jsIntClass), interceptorForNumber]);
       } else {
         whenNumber = js.statement('return #', interceptorForNumber);
       }
@@ -118,10 +120,10 @@
     }
 
     if (hasString) {
-      statements.add(buildInterceptorCheck(backend.jsStringClass));
+      statements.add(buildInterceptorCheck(helpers.jsStringClass));
     }
     if (hasNull) {
-      statements.add(buildInterceptorCheck(backend.jsNullClass));
+      statements.add(buildInterceptorCheck(helpers.jsNullClass));
     } else {
       // Returning "undefined" or "null" here will provoke a JavaScript
       // TypeError which is later identified as a null-error by
@@ -130,12 +132,12 @@
           js.statement('if (receiver == null) return receiver'));
     }
     if (hasBool) {
-      statements.add(buildInterceptorCheck(backend.jsBoolClass));
+      statements.add(buildInterceptorCheck(helpers.jsBoolClass));
     }
     // TODO(ahe): It might be faster to check for Array before
     // function and bool.
     if (hasArray) {
-      statements.add(buildInterceptorCheck(backend.jsArrayClass));
+      statements.add(buildInterceptorCheck(helpers.jsArrayClass));
     }
 
     if (hasNative) {
@@ -147,18 +149,19 @@
           if (receiver instanceof #) return receiver;
           return #(receiver);
       }''', [
-          interceptorFor(backend.jsJavaScriptFunctionClass),
-          backend.emitter.constructorAccess(compiler.objectClass),
+          interceptorFor(helpers.jsJavaScriptFunctionClass),
+          backend.emitter.constructorAccess(compiler.coreClasses.objectClass),
           backend.emitter
-              .staticFunctionAccess(backend.getNativeInterceptorMethod)]));
+              .staticFunctionAccess(helpers.getNativeInterceptorMethod)]));
 
     } else {
-      ClassElement jsUnknown = backend.jsUnknownJavaScriptObjectClass;
+      ClassElement jsUnknown = helpers.jsUnknownJavaScriptObjectClass;
       if (compiler.codegenWorld
               .directlyInstantiatedClasses.contains(jsUnknown)) {
         statements.add(
             js.statement('if (!(receiver instanceof #)) return #;',
-                [backend.emitter.constructorAccess(compiler.objectClass),
+                [backend.emitter.constructorAccess(
+                     compiler.coreClasses.objectClass),
                  interceptorFor(jsUnknown)]));
       }
 
@@ -183,9 +186,9 @@
             return a0 != null && receiver === a0;
         }''');
       }
-      if (!classes.contains(backend.jsIntClass)
-          && !classes.contains(backend.jsNumberClass)
-          && !classes.contains(backend.jsDoubleClass)) {
+      if (!classes.contains(helpers.jsIntClass)
+          && !classes.contains(helpers.jsNumberClass)
+          && !classes.contains(helpers.jsDoubleClass)) {
         return null;
       }
       if (selector.argumentCount == 1) {
@@ -214,25 +217,30 @@
     } else if (selector.isIndex || selector.isIndexSet) {
       // For an index operation, this code generates:
       //
-      //    if (receiver.constructor == Array || typeof receiver == "string") {
-      //      if (a0 >>> 0 === a0 && a0 < receiver.length) {
-      //        return receiver[a0];
+      //    if (typeof a0 === "number") {
+      //      if (receiver.constructor == Array ||
+      //          typeof receiver == "string") {
+      //        if (a0 >>> 0 === a0 && a0 < receiver.length) {
+      //          return receiver[a0];
+      //        }
       //      }
       //    }
       //
       // For an index set operation, this code generates:
       //
-      //    if (receiver.constructor == Array && !receiver.immutable$list) {
-      //      if (a0 >>> 0 === a0 && a0 < receiver.length) {
-      //        return receiver[a0] = a1;
+      //    if (typeof a0 === "number") {
+      //      if (receiver.constructor == Array && !receiver.immutable$list) {
+      //        if (a0 >>> 0 === a0 && a0 < receiver.length) {
+      //          return receiver[a0] = a1;
+      //        }
       //      }
       //    }
-      bool containsArray = classes.contains(backend.jsArrayClass);
-      bool containsString = classes.contains(backend.jsStringClass);
+      bool containsArray = classes.contains(helpers.jsArrayClass);
+      bool containsString = classes.contains(helpers.jsStringClass);
       bool containsJsIndexable =
-          backend.jsIndexingBehaviorInterface.isResolved && classes.any((cls) {
+          helpers.jsIndexingBehaviorInterface.isResolved && classes.any((cls) {
         return compiler.world.isSubtypeOf(cls,
-            backend.jsIndexingBehaviorInterface);
+            helpers.jsIndexingBehaviorInterface);
       });
       // The index set operator requires a check on its set value in
       // checked mode, so we don't optimize the interceptor if the
@@ -267,9 +275,10 @@
         }
 
         return js.statement('''
-          if (#)
-            if ((a0 >>> 0) === a0 && a0 < receiver.length)
-              return receiver[a0];
+          if (typeof a0 === "number")
+            if (#)
+              if ((a0 >>> 0) === a0 && a0 < receiver.length)
+                return receiver[a0];
           ''', typeCheck);
       } else {
         jsAst.Expression typeCheck;
@@ -282,9 +291,10 @@
         }
 
         return js.statement(r'''
-          if (# && !receiver.immutable$list &&
-              (a0 >>> 0) === a0 && a0 < receiver.length)
-            return receiver[a0] = a1;
+          if (typeof a0 === "number")
+            if (# && !receiver.immutable$list &&
+                (a0 >>> 0) === a0 && a0 < receiver.length)
+              return receiver[a0] = a1;
           ''', typeCheck);
       }
     }
@@ -309,7 +319,7 @@
     }
 
     jsAst.Name invocationName = backend.namer.invocationName(selector);
-    String globalObject = namer.globalObjectFor(backend.interceptorsLibrary);
+    String globalObject = namer.globalObjectFor(helpers.interceptorsLibrary);
 
     jsAst.Statement optimizedPath =
         _fastPathForOneShotInterceptor(selector, classes);
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index 540aad6..dbc6c9b 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -48,6 +48,8 @@
     TypeVariableElement;
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
+import '../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend/js_backend.dart' show
     CheckedModeHelper,
     CompoundName,
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
index 6a325ff..b2db5ab 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
@@ -150,7 +150,7 @@
     switch (builtin) {
       case JsBuiltin.dartObjectConstructor:
         return js.js.expressionTemplateYielding(
-            typeAccess(_compiler.objectClass));
+            typeAccess(_compiler.coreClasses.objectClass));
 
       case JsBuiltin.isCheckPropertyToJsConstructorName:
         int isPrefixLength = namer.operatorIsPrefix.length;
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
index 0545b57..96838ac 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
@@ -9,6 +9,8 @@
 import '../../constants/values.dart' show
     ConstantValue,
     FunctionConstantValue;
+import '../../core_types.dart' show
+    CoreClasses;
 import '../../elements/elements.dart' show
     ClassElement,
     FunctionElement;
@@ -19,6 +21,7 @@
     ConstantEmitter;
 
 import '../js_emitter.dart' show NativeEmitter;
+import '../constant_ordering.dart' show deepCompareConstants;
 
 import 'package:js_runtime/shared/embedded_names.dart' show
     CREATE_NEW_ISOLATE,
@@ -106,9 +109,9 @@
     // which compresses a tiny bit better.
     int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
     if (r != 0) return r;
-    // Resolve collisions in the long name by using the constant name (i.e. JS
-    // name) which is unique.
-    return namer.constantName(a).compareTo(namer.constantName(b));
+
+    // Resolve collisions in the long name by using a structural order.
+    return deepCompareConstants(a, b);
   }
 
   js.Expression generateStaticClosureAccess(FunctionElement element) {
@@ -346,12 +349,13 @@
   js.Property emitMangledGlobalNames() {
     List<js.Property> names = <js.Property>[];
 
+    CoreClasses coreClasses = compiler.coreClasses;
     // We want to keep the original names for the most common core classes when
     // calling toString on them.
     List<ClassElement> nativeClassesNeedingUnmangledName =
-        [compiler.intClass, compiler.doubleClass, compiler.numClass,
-         compiler.stringClass, compiler.boolClass, compiler.nullClass,
-         compiler.listClass];
+        [coreClasses.intClass, coreClasses.doubleClass, coreClasses.numClass,
+         coreClasses.stringClass, coreClasses.boolClass, coreClasses.nullClass,
+         coreClasses.listClass];
     nativeClassesNeedingUnmangledName.forEach((element) {
         names.add(new js.Property(js.quoteName(namer.className(element)),
                                   js.string(element.name)));
diff --git a/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
index f391ed9..d3204e9 100644
--- a/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
@@ -11,6 +11,8 @@
 
   MainCallStubGenerator(this.compiler, this.backend, this.emitterTask);
 
+  BackendHelpers get helpers => backend.helpers;
+
   /// Returns the code equivalent to:
   ///   `function(args) { $.startRootIsolate(X.main$closure(), args); }`
   jsAst.Expression _buildIsolateSetupClosure(Element appMain,
@@ -23,13 +25,12 @@
         [emitterTask.staticFunctionAccess(isolateMain), mainAccess]);
   }
 
-
   jsAst.Statement generateInvokeMain() {
     Element main = compiler.mainFunction;
     jsAst.Expression mainCallClosure = null;
     if (compiler.hasIsolateSupport) {
       Element isolateMain =
-        backend.isolateHelperLibrary.find(JavaScriptBackend.START_ROOT_ISOLATE);
+        helpers.isolateHelperLibrary.find(BackendHelpers.START_ROOT_ISOLATE);
       mainCallClosure = _buildIsolateSetupClosure(main, isolateMain);
     } else if (compiler.hasIncrementalSupport) {
       mainCallClosure = js(
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
index 9f87335..378b4a53 100644
--- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -34,8 +34,10 @@
 
   JavaScriptBackend get backend => compiler.backend;
 
+  BackendHelpers get helpers => backend.helpers;
+
   jsAst.Expression get defPropFunction {
-    Element element = backend.findHelper('defineProperty');
+    Element element = helpers.defineProperty;
     return emitterTask.staticFunctionAccess(element);
   }
 
@@ -86,11 +88,11 @@
     Class jsInterceptorClass = null;
 
     void walk(Class cls) {
-      if (cls.element == compiler.objectClass) {
+      if (cls.element == compiler.coreClasses.objectClass) {
         objectClass = cls;
         return;
       }
-      if (cls.element == backend.jsInterceptorClass) {
+      if (cls.element == helpers.jsInterceptorClass) {
         jsInterceptorClass = cls;
         return;
       }
@@ -134,9 +136,10 @@
       } else if (extensionPoints.containsKey(cls)) {
         needed = true;
       }
-      if (classElement.isJsInterop) {
+      if (backend.isJsInterop(classElement)) {
         needed = true;  // TODO(jacobr): we don't need all interop classes.
-      } else if (cls.isNative && native.nativeTagsForcedNonLeaf(classElement)) {
+      } else if (cls.isNative &&
+                 backend.hasNativeTagsForcedNonLeaf(classElement)) {
         needed = true;
         nonLeafClasses.add(cls);
       }
@@ -155,8 +158,8 @@
 
     for (Class cls in classes) {
       if (!cls.isNative) continue;
-      if (cls.element.isJsInterop) continue;
-      List<String> nativeTags = native.nativeTagsOfClass(cls.element);
+      if (backend.isJsInterop(cls.element)) continue;
+      List<String> nativeTags = backend.getNativeTagsOfClass(cls.element);
 
       if (nonLeafClasses.contains(cls) ||
           extensionPoints.containsKey(cls)) {
@@ -261,7 +264,7 @@
       FunctionElement member,
       List<jsAst.Parameter> stubParameters) {
     FunctionSignature parameters = member.functionSignature;
-    Element converter = backend.findHelper('convertDartClosureToJS');
+    Element converter = helpers.closureConverter;
     jsAst.Expression closureConverter =
         emitterTask.staticFunctionAccess(converter);
     parameters.forEachParameter((ParameterElement parameter) {
@@ -312,7 +315,7 @@
     assert(invariant(member, nativeMethods.contains(member)));
     // When calling a JS method, we call it with the native name, and only the
     // arguments up until the last one provided.
-    target = member.fixedBackendName;
+    target = backend.getFixedBackendName(member);
 
     if (isInterceptedMethod) {
       receiver = argumentsBuffer[0];
@@ -323,7 +326,7 @@
       assert(invariant(member, member.isStatic));
       arguments = argumentsBuffer.sublist(0,
           indexOfLastOptionalArgumentInParameters + 1);
-      if (member.isJsInterop) {
+      if (backend.isJsInterop(member)) {
         // fixedBackendPath is allowed to have the form foo.bar.baz for
         // interop. This template is uncached to avoid possibly running out of
         // memory when Dart2Js is run in server mode. In reality the risk of
@@ -359,7 +362,7 @@
     // is whether the receiver can be native, not the type of the test.
     if (element == null || !element.isClass) return false;
     ClassElement cls = element;
-    if (Elements.isNativeOrExtendsNative(cls)) return true;
+    if (backend.isNativeOrExtendsNative(cls)) return true;
     return isSupertypeOfNativeClass(element);
   }
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index 0d95278..c006e05 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -118,7 +118,7 @@
     });
 
     var body;  // List or jsAst.Statement.
-    if (member.hasFixedBackendName) {
+    if (backend.hasFixedBackendName(member)) {
       body = emitterTask.nativeEmitter.generateParameterStubStatements(
           member, isInterceptedMethod, namer.invocationName(selector),
           parametersBuffer, argumentsBuffer,
@@ -190,7 +190,7 @@
                                                    {bool canTearOff: true}) {
     if (member.enclosingElement.isClosure) {
       ClosureClassElement cls = member.enclosingElement;
-      if (cls.supertype.element == backend.boundClosureClass) {
+      if (cls.supertype.element == backend.helpers.boundClosureClass) {
         reporter.internalError(cls.methodElement, 'Bound closure1.');
       }
       if (cls.methodElement.isInstanceMember) {
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 62ba314..268d671 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -42,6 +42,10 @@
 
   JavaScriptBackend get backend => compiler.backend;
 
+  BackendHelpers get helpers => backend.helpers;
+
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   Collector(this.compiler, this.namer, this.rtiNeededClasses, this.emitter);
 
   Set<ClassElement> computeInterceptorsReferencedFromConstants() {
@@ -67,7 +71,7 @@
     Set<ClassElement> unneededClasses = new Set<ClassElement>();
     // The [Bool] class is not marked as abstract, but has a factory
     // constructor that always throws. We never need to emit it.
-    unneededClasses.add(compiler.boolClass);
+    unneededClasses.add(coreClasses.boolClass);
 
     // Go over specialized interceptors and then constants to know which
     // interceptors are needed.
@@ -84,18 +88,18 @@
     // Add unneeded interceptors to the [unneededClasses] set.
     for (ClassElement interceptor in backend.interceptedClasses) {
       if (!needed.contains(interceptor)
-          && interceptor != compiler.objectClass) {
+          && interceptor != coreClasses.objectClass) {
         unneededClasses.add(interceptor);
       }
     }
 
     // These classes are just helpers for the backend's type system.
-    unneededClasses.add(backend.jsMutableArrayClass);
-    unneededClasses.add(backend.jsFixedArrayClass);
-    unneededClasses.add(backend.jsExtendableArrayClass);
-    unneededClasses.add(backend.jsUInt32Class);
-    unneededClasses.add(backend.jsUInt31Class);
-    unneededClasses.add(backend.jsPositiveIntClass);
+    unneededClasses.add(helpers.jsMutableArrayClass);
+    unneededClasses.add(helpers.jsFixedArrayClass);
+    unneededClasses.add(helpers.jsExtendableArrayClass);
+    unneededClasses.add(helpers.jsUInt32Class);
+    unneededClasses.add(helpers.jsUInt31Class);
+    unneededClasses.add(helpers.jsPositiveIntClass);
 
     return (ClassElement cls) => !unneededClasses.contains(cls);
   }
@@ -213,30 +217,30 @@
     neededClasses.addAll(classesOnlyNeededForRti);
 
     // TODO(18175, floitsch): remove once issue 18175 is fixed.
-    if (neededClasses.contains(backend.jsIntClass)) {
-      neededClasses.add(compiler.intClass);
+    if (neededClasses.contains(helpers.jsIntClass)) {
+      neededClasses.add(coreClasses.intClass);
     }
-    if (neededClasses.contains(backend.jsDoubleClass)) {
-      neededClasses.add(compiler.doubleClass);
+    if (neededClasses.contains(helpers.jsDoubleClass)) {
+      neededClasses.add(coreClasses.doubleClass);
     }
-    if (neededClasses.contains(backend.jsNumberClass)) {
-      neededClasses.add(compiler.numClass);
+    if (neededClasses.contains(helpers.jsNumberClass)) {
+      neededClasses.add(coreClasses.numClass);
     }
-    if (neededClasses.contains(backend.jsStringClass)) {
-      neededClasses.add(compiler.stringClass);
+    if (neededClasses.contains(helpers.jsStringClass)) {
+      neededClasses.add(coreClasses.stringClass);
     }
-    if (neededClasses.contains(backend.jsBoolClass)) {
-      neededClasses.add(compiler.boolClass);
+    if (neededClasses.contains(helpers.jsBoolClass)) {
+      neededClasses.add(coreClasses.boolClass);
     }
-    if (neededClasses.contains(backend.jsArrayClass)) {
-      neededClasses.add(compiler.listClass);
+    if (neededClasses.contains(helpers.jsArrayClass)) {
+      neededClasses.add(coreClasses.listClass);
     }
 
     // 4. Finally, sort the classes.
     List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses);
 
     for (ClassElement element in sortedClasses) {
-      if (Elements.isNativeOrExtendsNative(element) &&
+      if (backend.isNativeOrExtendsNative(element) &&
           !classesOnlyNeededForRti.contains(element)) {
         // For now, native classes and related classes cannot be deferred.
         nativeClassesAndSubclasses.add(element);
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
index 0388bc9..894bd92 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
@@ -80,7 +80,7 @@
       // Keep track of whether or not we're dealing with a field mixin
       // into a native class.
       bool isMixinNativeField =
-          isClass && element.isNative && holder.isMixinApplication;
+          isClass && backend.isNative(element) && holder.isMixinApplication;
 
       // See if we can dynamically create getters and setters.
       // We can only generate getters and setters for [element] since
@@ -93,7 +93,7 @@
         needsSetter = fieldNeedsSetter(field);
       }
 
-      if ((isInstantiated && !holder.isNative)
+      if ((isInstantiated && !backend.isNative(holder))
           || needsGetter
           || needsSetter) {
         js.Name accessorName = namer.fieldAccessorName(field);
@@ -149,7 +149,7 @@
     if (field.isFinal || field.isConst) return false;
     if (backend.shouldRetainSetter(field)) return true;
     return field.isClassMember &&
-    compiler.codegenWorld.hasInvokedSetter(field, compiler.world);
+        compiler.codegenWorld.hasInvokedSetter(field, compiler.world);
   }
 
   static bool fieldAccessNeverThrows(VariableElement field) {
@@ -165,6 +165,6 @@
     // We never generate accessors for top-level/static fields.
     if (!member.isInstanceMember) return true;
     DartType type = member.type;
-    return type.treatAsDynamic || (type.element == compiler.objectClass);
+    return type.treatAsDynamic || type.isObject;
   }
 }
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 8ac784a..42f7138 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -16,16 +16,19 @@
     TypeTestProperties;
 import '../model.dart';
 
+import '../../closure.dart' show
+    ClosureFieldElement;
 import '../../common.dart';
 import '../../common/names.dart' show
-    Names;
+    Names,
+    Selectors;
 import '../../compiler.dart' show
     Compiler;
 import '../../constants/values.dart' show
     ConstantValue,
     InterceptorConstantValue;
-import '../../closure.dart' show
-    ClosureFieldElement;
+import '../../core_types.dart' show
+    CoreClasses;
 import '../../dart_types.dart' show
     DartType,
     FunctionType,
@@ -45,13 +48,13 @@
     TypedefElement,
     VariableElement;
 import '../../js/js.dart' as js;
+import '../../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../../js_backend/js_backend.dart' show
     Namer,
     JavaScriptBackend,
     JavaScriptConstantCompiler,
     StringBackedName;
-import '../../universe/call_structure.dart' show
-    CallStructure;
 import '../../universe/selector.dart' show
     Selector;
 import '../../universe/universe.dart' show
@@ -96,6 +99,7 @@
         this._registry = new Registry(compiler);
 
   JavaScriptBackend get backend => _compiler.backend;
+  BackendHelpers get helpers => backend.helpers;
   Universe get universe => _compiler.codegenWorld;
 
   /// Mapping from [ClassElement] to constructed [Class]. We need this to
@@ -306,15 +310,12 @@
 
   List<StaticField> _buildStaticLazilyInitializedFields(
       LibrariesMap librariesMap) {
-    // TODO(floitsch): lazy fields should just be in their respective
-    // libraries.
-    if (librariesMap != _registry.mainLibrariesMap) {
-      return const <StaticField>[];
-    }
-
     JavaScriptConstantCompiler handler = backend.constants;
-    List<VariableElement> lazyFields =
-        handler.getLazilyInitializedFieldsForEmission();
+    DeferredLoadTask loadTask = _compiler.deferredLoadTask;
+    Iterable<VariableElement> lazyFields = handler
+        .getLazilyInitializedFieldsForEmission()
+        .where((element) =>
+            loadTask.outputUnitForElement(element) == librariesMap.outputUnit);
     return Elements.sortedByPosition(lazyFields)
         .map(_buildLazyField)
         .where((field) => field != null)  // Happens when the field was unused.
@@ -350,15 +351,14 @@
   }
 
   void _addJsInteropStubs(LibrariesMap librariesMap) {
-    if (_classes.containsKey(_compiler.objectClass)) {
-      var toStringInvocation = namer.invocationName(new Selector.call(
-          new Name("toString", _compiler.objectClass.library),
-          CallStructure.NO_ARGS));
+    if (_classes.containsKey(_compiler.coreClasses.objectClass)) {
+      var toStringInvocation = namer.invocationName(Selectors.toString_);
       // TODO(jacobr): register toString as used so that it is always accessible
       // from JavaScript.
-      _classes[_compiler.objectClass].callStubs.add(_buildStubMethod(
-          new StringBackedName("toString"),
-          js.js('function() { return this.#(this) }', toStringInvocation)));
+      _classes[_compiler.coreClasses.objectClass].callStubs.add(
+          _buildStubMethod(
+              new StringBackedName("toString"),
+              js.js('function() { return this.#(this) }', toStringInvocation)));
     }
 
     // We add all members from classes marked with isJsInterop to the base
@@ -368,11 +368,11 @@
     // a regular getter that returns a JavaScript function and tearing off
     // a method in the case where there exist multiple JavaScript classes
     // that conflict on whether the member is a getter or a method.
-    var interceptorClass = _classes[backend.jsJavaScriptObjectClass];
+    var interceptorClass = _classes[helpers.jsJavaScriptObjectClass];
     var stubNames = new Set<String>();
     librariesMap.forEach((LibraryElement library, List<Element> elements) {
       for (Element e in elements) {
-        if (e is ClassElement && e.isJsInterop) {
+        if (e is ClassElement && backend.isJsInterop(e)) {
           e.declaration.forEachMember((_, Element member) {
             if (!member.isInstanceMember) return;
             if (member.isGetter || member.isField || member.isFunction) {
@@ -423,7 +423,7 @@
                   functionType = returnType;
                 } else if (returnType.treatAsDynamic ||
                     _compiler.types.isSubtype(returnType,
-                        backend.resolution.coreTypes.functionType)) {
+                        backend.coreTypes.functionType)) {
                   if (returnType.isTypedef) {
                     TypedefType typedef = returnType;
                     // TODO(jacobr): can we just use typdef.unaliased instead?
@@ -499,7 +499,7 @@
         .map(_buildStaticMethod)
         .toList();
 
-    if (library == backend.interceptorsLibrary) {
+    if (library == helpers.interceptorsLibrary) {
       statics.addAll(_generateGetInterceptorMethods());
       statics.addAll(_generateOneShotInterceptors());
     }
@@ -531,12 +531,12 @@
         element, name, null, [], instanceFields, [], [], [], [], [], [], null,
         isDirectlyInstantiated: true,
         onlyForRti: false,
-        isNative: element.isNative);
+        isNative: backend.isNative(element));
   }
 
   Class _buildClass(ClassElement element) {
     bool onlyForRti = collector.classesOnlyNeededForRti.contains(element);
-    if (element.isJsInterop) {
+    if (backend.isJsInterop(element)) {
       // TODO(jacobr): check whether the class has any active static fields
       // if it does not we can suppress it completely.
       onlyForRti = true;
@@ -578,7 +578,7 @@
 
     List<StubMethod> noSuchMethodStubs = <StubMethod>[];
 
-    if (backend.enabledNoSuchMethod && element == _compiler.objectClass) {
+    if (backend.enabledNoSuchMethod && element.isObject) {
       Map<js.Name, Selector> selectors =
           classStubGenerator.computeSelectorsForNsmHandlers();
       selectors.forEach((js.Name name, Selector selector) {
@@ -594,7 +594,7 @@
       });
     }
 
-    if (element == backend.closureClass) {
+    if (element == helpers.closureClass) {
       // We add a special getter here to allow for tearing off a closure from
       // itself.
       js.Name name = namer.getterForMember(Names.call);
@@ -622,9 +622,9 @@
 
     List<StubMethod> checkedSetters = <StubMethod>[];
     List<StubMethod> isChecks = <StubMethod>[];
-    if (element.isJsInterop) {
+    if (backend.isJsInterop(element)) {
       typeTests.properties.forEach((js.Name name, js.Node code) {
-        _classes[backend.jsInterceptorClass].isChecks.add(
+        _classes[helpers.jsInterceptorClass].isChecks.add(
             _buildStubMethod(name, code));
       });
     } else {
@@ -649,12 +649,12 @@
     // TODO(floitsch): we shouldn't update the registry in the middle of
     // building a class.
     Holder holder = _registry.registerHolder(holderName);
-    bool isInstantiated = !element.isJsInterop &&
+    bool isInstantiated = !backend.isJsInterop(element) &&
         _compiler.codegenWorld.directlyInstantiatedClasses.contains(element);
 
     Class result;
     if (element.isMixinApplication && !onlyForRti) {
-      assert(!element.isNative);
+      assert(!backend.isNative(element));
       assert(methods.isEmpty);
 
       result = new MixinApplication(element,
@@ -680,7 +680,7 @@
                          typeTests.functionTypeIndex,
                          isDirectlyInstantiated: isInstantiated,
                          onlyForRti: onlyForRti,
-                         isNative: element.isNative);
+                         isNative: backend.isNative(element));
     }
     _classes[element] = result;
     return result;
@@ -864,7 +864,7 @@
     InterceptorStubGenerator stubGenerator =
         new InterceptorStubGenerator(_compiler, namer, backend);
 
-    String holderName = namer.globalObjectFor(backend.interceptorsLibrary);
+    String holderName = namer.globalObjectFor(helpers.interceptorsLibrary);
     // TODO(floitsch): we shouldn't update the registry in the middle of
     // generating the interceptor methods.
     Holder holder = _registry.registerHolder(holderName);
@@ -929,7 +929,7 @@
     InterceptorStubGenerator stubGenerator =
         new InterceptorStubGenerator(_compiler, namer, backend);
 
-    String holderName = namer.globalObjectFor(backend.interceptorsLibrary);
+    String holderName = namer.globalObjectFor(helpers.interceptorsLibrary);
     // TODO(floitsch): we shouldn't update the registry in the middle of
     // generating the interceptor methods.
     Holder holder = _registry.registerHolder(holderName);
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index 8b20e2d..61c1b08 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -68,7 +68,7 @@
     /// native classes.
     /// TODO(herhut): Generate tests for native classes dynamically, as well.
     void generateIsTest(Element other) {
-      if (classElement.isJsInterop || classElement.isNative ||
+      if (backend.isNative(classElement) ||
           !classElement.isSubclassOf(other)) {
         result.properties[namer.operatorIs(other)] = js('1');
       }
@@ -180,7 +180,8 @@
       return backend.rti.isTrivialSubstitution(a, b);
     }
 
-    if (superclass != null && superclass != compiler.objectClass &&
+    if (superclass != null &&
+        superclass != compiler.coreClasses.objectClass &&
         !haveSameTypeVariables(cls, superclass)) {
       // We cannot inherit the generated substitutions, because the type
       // variable layout for this class is different.  Instead we generate
@@ -216,7 +217,7 @@
 
     // A class that defines a `call` method implicitly implements
     // [Function] and needs checks for all typedefs that are used in is-checks.
-    if (checkedClasses.contains(compiler.functionClass) ||
+    if (checkedClasses.contains(compiler.coreClasses.functionClass) ||
         checkedFunctionTypes.isNotEmpty) {
       Element call = cls.lookupLocalMember(Identifiers.call);
       if (call == null) {
@@ -228,7 +229,7 @@
         // A superclass might already implement the Function interface. In such
         // a case, we can avoid emiting the is test here.
         if (!cls.superclass.implementsFunction(compiler)) {
-          _generateInterfacesIsTests(compiler.functionClass,
+          _generateInterfacesIsTests(compiler.coreClasses.functionClass,
                                     generateIsTest,
                                     generateSubstitution,
                                     generated);
@@ -313,7 +314,7 @@
               js.number(index));
     }
     jsAst.Expression convertRtiToRuntimeType = backend.emitter
-         .staticFunctionAccess(backend.findHelper('convertRtiToRuntimeType'));
+         .staticFunctionAccess(backend.helpers.convertRtiToRuntimeType);
 
     return new StubMethod(name,
                           js('function () { return #(#) }',
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index 7f8e845..40fd877 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -146,7 +146,7 @@
     switch (builtin) {
       case JsBuiltin.dartObjectConstructor:
         return js.js.expressionTemplateYielding(
-            typeAccess(_compiler.objectClass));
+            typeAccess(_compiler.coreClasses.objectClass));
 
       case JsBuiltin.isCheckPropertyToJsConstructorName:
         int isPrefixLength = namer.operatorIsPrefix.length;
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index c8e6a75..14dea34 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -55,11 +55,6 @@
 // names we want. Furthermore, the pretty-printer minifies local variables, thus
 // reducing their size.
 const String mainBoilerplate = '''
-{
-// Declare deferred-initializer global, which is used to keep track of the
-// loaded fragments.
-#deferredInitializer;
-
 (function() {
 // Copies the own properties from [from] to [to].
 function copyProperties(from, to) {
@@ -355,8 +350,8 @@
 
 // Invokes main (making sure that it records the 'current-script' value).
 #invokeMain;
-})();
-}''';
+})()
+''';
 
 /// Deferred fragments (aka 'hunks') are built similarly to the main fragment.
 ///
@@ -441,8 +436,7 @@
         .where((Holder holder) => !holder.isStaticStateHolder);
 
     return js.js.statement(mainBoilerplate,
-        {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap),
-         'typeNameProperty': js.string(ModelEmitter.typeNameProperty),
+        {'typeNameProperty': js.string(ModelEmitter.typeNameProperty),
          'cyclicThrow': backend.emitter.staticFunctionAccess(
                  backend.helpers.cyclicThrowHelper),
          'operatorIsPrefix': js.string(namer.operatorIsPrefix),
@@ -516,15 +510,6 @@
     });
   }
 
-  js.Statement emitDeferredInitializerGlobal(Map loadMap) {
-    if (loadMap.isEmpty) return new js.Block.empty();
-
-    String global = ModelEmitter.deferredInitializersGlobal;
-    return js.js.statement(
-        "if (typeof($global) === 'undefined') var # = Object.create(null);",
-        new js.VariableDeclaration(global, allowRename: false));
-  }
-
   /// Emits all holders, except for the static-state holder.
   ///
   /// The emitted holders contain classes (only the constructors) and all
@@ -1091,12 +1076,13 @@
   js.Property emitMangledGlobalNames() {
     List<js.Property> names = <js.Property>[];
 
+    CoreClasses coreClasses = compiler.coreClasses;
     // We want to keep the original names for the most common core classes when
     // calling toString on them.
     List<ClassElement> nativeClassesNeedingUnmangledName =
-        [compiler.intClass, compiler.doubleClass, compiler.numClass,
-         compiler.stringClass, compiler.boolClass, compiler.nullClass,
-         compiler.listClass];
+        [coreClasses.intClass, coreClasses.doubleClass, coreClasses.numClass,
+          coreClasses.stringClass, coreClasses.boolClass, coreClasses.nullClass,
+          coreClasses.listClass];
     // TODO(floitsch): this should probably be on a per-fragment basis.
     nativeClassesNeedingUnmangledName.forEach((element) {
       names.add(new js.Property(js.quoteName(namer.className(element)),
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 2a06960..9e81bca 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -35,6 +35,8 @@
     FunctionConstantValue;
 import '../../compiler.dart' show
     Compiler;
+import '../../core_types.dart' show
+    CoreClasses;
 import '../../elements/elements.dart' show
     ClassElement,
     FunctionElement;
@@ -54,6 +56,7 @@
 import '../../util/uri_extras.dart' show
     relativize;
 
+import '../constant_ordering.dart' show deepCompareConstants;
 import '../headers.dart';
 import '../js_emitter.dart' show
     NativeEmitter;
@@ -138,9 +141,9 @@
     // which compresses a tiny bit better.
     int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
     if (r != 0) return r;
-    // Resolve collisions in the long name by using the constant name (i.e. JS
-    // name) which is unique.
-    return namer.constantName(a).compareTo(namer.constantName(b));
+
+    // Resolve collisions in the long name by using a structural order.
+    return deepCompareConstants(a, b);
   }
 
   js.Expression generateStaticClosureAccess(FunctionElement element) {
@@ -206,7 +209,8 @@
       token.setHash(hunkHashes[key]);
     });
 
-    writeMainFragment(mainFragment, mainCode);
+    writeMainFragment(mainFragment, mainCode,
+      isSplit: program.deferredFragments.isNotEmpty);
 
     if (backend.requiresPreamble &&
         !backend.htmlLibraryIsLoaded) {
@@ -247,10 +251,18 @@
     return hunkHashes;
   }
 
+  js.Statement buildDeferredInitializerGlobal() {
+    String global = deferredInitializersGlobal;
+    return js.js.statement(
+        "if (typeof($global) === 'undefined') var # = Object.create(null);",
+        new js.VariableDeclaration(global, allowRename: false));
+  }
+
   // Writes the given [fragment]'s [code] into a file.
   //
   // Updates the shared [outputBuffers] field with the output.
-  void writeMainFragment(MainFragment fragment, js.Statement code) {
+  void writeMainFragment(MainFragment fragment, js.Statement code,
+      {bool isSplit}) {
     LineColumnCollector lineColumnCollector;
     List<CodeOutputListener> codeOutputListeners;
     if (shouldGenerateSourceMap) {
@@ -266,6 +278,7 @@
     js.Program program = new js.Program([
         buildGeneratedBy(),
         new js.Comment(HOOKS_API_USAGE),
+        isSplit ? buildDeferredInitializerGlobal() : new js.Block.empty(),
         code]);
 
     mainOutput.addBuffer(js.prettyPrint(program, compiler,
@@ -319,6 +332,7 @@
 
     js.Program program = new js.Program([
         buildGeneratedBy(),
+        buildDeferredInitializerGlobal(),
         js.js.statement('$deferredInitializersGlobal.current = #', code)]);
 
     output.addBuffer(js.prettyPrint(program, compiler,
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 5759b52..238d393 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -31,7 +31,6 @@
     PrefixElementX,
     SyntheticImportElement;
 
-import 'native/native.dart' as native;
 import 'script.dart';
 import 'tree/tree.dart';
 import 'util/util.dart' show
@@ -148,7 +147,13 @@
   /// [LibraryElement] for the library and computes the import/export scope,
   /// loading and computing the import/export scopes of all required libraries
   /// in the process. The method handles cyclic dependency between libraries.
-  Future<LibraryElement> loadLibrary(Uri resolvedUri);
+  ///
+  /// If [skipFileWithPartOfTag] is `true`, `null` is returned if the
+  /// compilation unit for [resolvedUri] contains a `part of` tag. This is only
+  /// used for analysis through [Compiler.analyzeUri].
+  Future<LibraryElement> loadLibrary(
+      Uri resolvedUri,
+      {bool skipFileWithPartOfTag: false});
 
   /// Reset the library loader task to prepare for compilation. If provided,
   /// libraries matching [reuseLibrary] are reused.
@@ -340,18 +345,27 @@
     Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
     libraryResourceUriMap[resourceUri] = library;
 
-    String name = library.libraryOrScriptName;
-    libraryNames[name] = library;
+    if (library.hasLibraryName) {
+      String name = library.libraryName;
+      libraryNames[name] = library;
+    }
   }
 
-  Future<LibraryElement> loadLibrary(Uri resolvedUri) {
+  Future<LibraryElement> loadLibrary(
+      Uri resolvedUri,
+      {bool skipFileWithPartOfTag: false}) {
     return measure(() {
       assert(currentHandler == null);
       // TODO(johnniwinther): Ensure that currentHandler correctly encloses the
       // loading of a library cluster.
       currentHandler = new LibraryDependencyHandler(this);
-      return createLibrary(currentHandler, null, resolvedUri)
+      return createLibrary(currentHandler, null, resolvedUri,
+          skipFileWithPartOfTag: skipFileWithPartOfTag)
           .then((LibraryElement library) {
+        if (library == null) {
+          currentHandler = null;
+          return null;
+        }
         return reporter.withCurrentElement(library, () {
           return measure(() {
             currentHandler.computeExports();
@@ -385,7 +399,21 @@
       return reporter.withCurrentElement(library, () {
 
         Uri computeUri(LibraryDependency node) {
-          String tagUriString = node.uri.dartString.slowToString();
+          StringNode uriNode = node.uri;
+          if (node.conditionalUris != null) {
+            for (ConditionalUri conditionalUri in node.conditionalUris) {
+              String key = conditionalUri.key.slowNameString;
+              String value = conditionalUri.value == null
+                  ? "true"
+                  : conditionalUri.value.dartString.slowToString();
+              String actual = compiler.fromEnvironment(key);
+              if (value == actual) {
+                uriNode = conditionalUri.uri;
+                break;
+              }
+            }
+          }
+          String tagUriString = uriNode.dartString.slowToString();
           try {
             return Uri.parse(tagUriString);
           } on FormatException {
@@ -493,7 +521,7 @@
              'canonicalUri2': existing.canonicalUri});
       }
     } else if (library.hasLibraryName) {
-      String name = library.libraryOrScriptName;
+      String name = library.libraryName;
       existing = libraryNames.putIfAbsent(name, () => library);
       if (!identical(existing, library)) {
         reporter.withCurrentElement(library, () {
@@ -550,7 +578,7 @@
       LibraryDependencyElementX libraryDependency) {
     Uri base = library.canonicalUri;
     Uri resolvedUri = base.resolveUri(libraryDependency.uri);
-    return createLibrary(handler, library, resolvedUri, libraryDependency)
+    return createLibrary(handler, library, resolvedUri, node: libraryDependency)
         .then((LibraryElement loadedLibrary) {
           if (loadedLibrary == null) return;
           reporter.withCurrentElement(library, () {
@@ -587,10 +615,12 @@
    *
    * If a new library is created, the [handler] is notified.
    */
-  Future<LibraryElement> createLibrary(LibraryDependencyHandler handler,
-                                       LibraryElement importingLibrary,
-                                       Uri resolvedUri,
-                                       [Spannable node]) {
+  Future<LibraryElement> createLibrary(
+      LibraryDependencyHandler handler,
+      LibraryElement importingLibrary,
+      Uri resolvedUri,
+      {Spannable node,
+       bool skipFileWithPartOfTag: false}) {
     Uri readableUri =
         compiler.translateResolvedUri(importingLibrary, resolvedUri, node);
     LibraryElement library = libraryCanonicalUriMap[resolvedUri];
@@ -611,6 +641,33 @@
         if (script == null) return null;
         LibraryElement element =
             createLibrarySync(handler, script, resolvedUri);
+        CompilationUnitElementX compilationUnit = element.entryCompilationUnit;
+        if (compilationUnit.partTag != null) {
+          if (skipFileWithPartOfTag) {
+            // TODO(johnniwinther): Avoid calling [Compiler.onLibraryCreated]
+            // for this library.
+            libraryCanonicalUriMap.remove(resolvedUri);
+            return null;
+          }
+          if (importingLibrary == null) {
+            DiagnosticMessage error = reporter.withCurrentElement(
+                compilationUnit,
+                () => reporter.createMessage(
+                    compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF));
+            reporter.reportError(error);
+          } else {
+            DiagnosticMessage error = reporter.withCurrentElement(
+                compilationUnit,
+                () => reporter.createMessage(
+                    compilationUnit.partTag, MessageKind.IMPORT_PART_OF));
+            DiagnosticMessage info = reporter.withCurrentElement(
+                importingLibrary,
+                () => reporter.createMessage(
+                    node,
+                    MessageKind.IMPORT_PART_OF_HERE));
+            reporter.reportError(error, [info]);
+          }
+        }
         return processLibraryTags(handler, element).then((_) {
           reporter.withCurrentElement(element, () {
             handler.registerLibraryExports(element);
@@ -631,7 +688,6 @@
         handler.registerNewLibrary(element);
         libraryCanonicalUriMap[resolvedUri] = element;
       }
-      native.maybeEnableNative(compiler, element);
       compiler.scanner.scanLibrary(element);
       return element;
     });
@@ -975,7 +1031,7 @@
 
     Element existingElement = exportScope[name];
     if (existingElement != null && existingElement != element) {
-      if (existingElement.isErroneous) {
+      if (existingElement.isMalformed) {
         createDuplicateExportMessage(element, exports);
         createDuplicateExportDeclMessage(element, exports);
         element = existingElement;
@@ -1067,7 +1123,7 @@
         if (element == null) {
           if (combinator.isHide) {
             if (library.isPackageLibrary &&
-                !reporter.options.showPackageWarnings) {
+                reporter.options.hidePackageWarnings) {
               // Only report hide hint on packages if we show warnings on these:
               // The hide may be non-empty in some versions of the package, in
               // which case you shouldn't remove the combinator.
diff --git a/pkg/compiler/lib/src/mirrors/analyze.dart b/pkg/compiler/lib/src/mirrors/analyze.dart
index 733cbae..ad3c0ea 100644
--- a/pkg/compiler/lib/src/mirrors/analyze.dart
+++ b/pkg/compiler/lib/src/mirrors/analyze.dart
@@ -54,7 +54,7 @@
     diagnosticHandler(uri, begin, end, message, kind);
   }
 
-  Compiler compiler = new apiimpl.Compiler(
+  Compiler compiler = new apiimpl.CompilerImpl(
       new LegacyCompilerInput(inputProvider),
       new LegacyCompilerOutput(),
       new LegacyCompilerDiagnostics(internalDiagnosticHandler),
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart
index a5e6e94..b2a2ea5 100644
--- a/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart
+++ b/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart
@@ -397,7 +397,7 @@
 
   ClassMirror get originalDeclaration =>
       mirrorSystem._getTypeDeclarationMirror(
-          mirrorSystem.compiler.functionClass);
+          mirrorSystem.compiler.coreClasses.functionClass);
 
   // TODO(johnniwinther): Substitute type arguments for type variables.
   ClassMirror get superclass => originalDeclaration.superclass;
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 63d5bd6..438dbe6 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -140,9 +140,15 @@
   ///
   /// Two forms of the string is supported:
   ///
-  /// 1) A single type string of the form 'void', '', 'var' or 'T1|...|Tn'
-  ///    which defines the types returned and for the later form also created by
-  ///    the call to JS.
+  /// 1) A single type string of the form 'void', '', 'var' or 'T1|...|Tn' which
+  ///    defines the types returned, and, for the last form, the types also
+  ///    created by the call to JS.  'var' (and '') are like 'dynamic' or
+  ///    'Object' except that 'dynamic' would indicate that objects of any type
+  ///    are created, which defeats tree-shaking.  Think of 'var' (and '') as
+  ///    meaning 'any pre-existing type'.
+  ///
+  ///    The types Ti are non-nullable, so add class `Null` to specify a
+  ///    nullable type, e.g `'String|Null'`.
   ///
   /// 2) A sequence of <tag>:<value> pairs of the following kinds
   ///
@@ -155,7 +161,7 @@
   ///    A <type-tag> is either 'returns' or 'creates' and <type-string> is a
   ///    type string like in 1). The type string marked by 'returns' defines the
   ///    types returned and 'creates' defines the types created by the call to
-  ///    JS.
+  ///    JS. If 'creates' is missing, it defaults to 'returns'.
   ///
   ///    An <effect-tag> is either 'effects' or 'depends' and <effect-string> is
   ///    either 'all', 'none' or a comma-separated list of 'no-index',
@@ -309,23 +315,30 @@
 
     String returns = values['returns'];
     if (returns != null) {
-      resolveTypesString(returns, onVar: () {
-        typesReturned.add(objectType);
-        typesReturned.add(nullType);
-      }, onType: (type) {
-        typesReturned.add(type);
-      });
+      resolveTypesString(returns,
+        onVar: () {
+          typesReturned.add(objectType);
+          typesReturned.add(nullType);
+        },
+        onType: (type) {
+          typesReturned.add(type);
+        });
     }
 
     String creates = values['creates'];
     if (creates != null) {
-      resolveTypesString(creates, onVoid: () {
-        reportError("Invalid type string 'creates:$creates'");
-      }, onVar: () {
-        reportError("Invalid type string 'creates:$creates'");
-      }, onType: (type) {
-        typesInstantiated.add(type);
-      });
+      resolveTypesString(creates,
+        onVoid: () {
+          reportError("Invalid type string 'creates:$creates'");
+        },
+        onType: (type) {
+          typesInstantiated.add(type);
+        });
+    } else if (returns != null) {
+      resolveTypesString(returns,
+        onType: (type) {
+          typesInstantiated.add(type);
+        });
     }
 
     const throwsOption = const <String, NativeThrowBehavior>{
@@ -646,7 +659,7 @@
     FunctionType type = method.computeType(compiler.resolution);
     var behavior = new NativeBehavior();
     var returnType = type.returnType;
-    bool isInterop = method.isJsInterop;
+    bool isInterop = compiler.backend.isJsInterop(method);
     // Note: For dart:html and other internal libraries we maintain, we can
     // trust the return type and use it to limit what we enqueue. We have to
     // be more conservative about JS interop types and assume they can return
@@ -682,7 +695,7 @@
     Resolution resolution = compiler.resolution;
     DartType type = field.computeType(resolution);
     var behavior = new NativeBehavior();
-    bool isInterop = field.isJsInterop;
+    bool isInterop = compiler.backend.isJsInterop(field);
     // TODO(sigmund,sra): consider doing something better for numeric types.
     behavior.typesReturned.add(
         !isInterop || compiler.trustJSInteropTypeAnnotations ? type
@@ -804,7 +817,7 @@
       if (!isInterop) {
         typesInstantiated.add(type);
       } else {
-        if (type.element != null && type.element.isNative) {
+        if (type.element != null && backend.isNative(type.element)) {
           // Any declared native or interop type (isNative implies isJsInterop)
           // is assumed to be allocated.
           typesInstantiated.add(type);
@@ -818,7 +831,7 @@
           // annotations. This means that to some degree we still use the return
           // type to decide whether to include native types, even if we don't
           // trust the type annotation.
-          ClassElement cls = backend.jsJavaScriptObjectClass;
+          ClassElement cls = backend.helpers.jsJavaScriptObjectClass;
           cls.ensureResolved(resolution);
           typesInstantiated.add(cls.thisType);
         } else {
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index 42ceba2..c96f7da 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -95,9 +95,11 @@
         processedLibraries = compiler.cacheStrategy.newSet();
 
   JavaScriptBackend get backend => compiler.backend;
+  BackendHelpers get helpers => backend.helpers;
   Resolution get resolution => compiler.resolution;
 
   DiagnosticReporter get reporter => compiler.reporter;
+  CoreTypes get coreTypes => compiler.coreTypes;
 
   void processNativeClasses(Iterable<LibraryElement> libraries) {
     if (compiler.hasIncrementalSupport) {
@@ -107,8 +109,8 @@
       libraries = libraries.where(processedLibraries.add);
     }
     libraries.forEach(processNativeClassesInLibrary);
-    if (backend.isolateHelperLibrary != null) {
-      processNativeClassesInLibrary(backend.isolateHelperLibrary);
+    if (helpers.isolateHelperLibrary != null) {
+      processNativeClassesInLibrary(helpers.isolateHelperLibrary);
     }
     processSubclassesOfNativeClasses(libraries);
     if (!enableLiveTypeAnalysis) {
@@ -120,7 +122,7 @@
   void processNativeClassesInLibrary(LibraryElement library) {
     // Use implementation to ensure the inclusion of injected members.
     library.implementation.forEachLocalMember((Element element) {
-      if (element.isClass && element.isNative) {
+      if (element.isClass && backend.isNative(element)) {
         processNativeClass(element);
       }
     });
@@ -162,7 +164,7 @@
     // fact a subclass of a native class.
 
     ClassElement nativeSuperclassOf(ClassElement classElement) {
-      if (classElement.isNative) return classElement;
+      if (backend.isNative(classElement)) return classElement;
       if (classElement.superclass == null) return null;
       return nativeSuperclassOf(classElement.superclass);
     }
@@ -173,7 +175,7 @@
       ClassElement nativeSuperclass = nativeSuperclassOf(element);
       if (nativeSuperclass != null) {
         nativeClassesAndSubclasses.add(element);
-        if (!element.isNative) {
+        if (!backend.isNative(element)) {
           nonNativeSubclasses.putIfAbsent(nativeSuperclass,
               () => new Set<ClassElement>())
             .add(element);
@@ -268,7 +270,7 @@
   void findAnnotationClasses() {
     if (_annotationCreatesClass != null) return;
     ClassElement find(name) {
-      Element e = backend.findHelper(name);
+      Element e = helpers.findHelper(name);
       if (e == null || e is! ClassElement) {
         reporter.internalError(NO_LOCATION_SPANNABLE,
             "Could not find implementation class '${name}'.");
@@ -348,14 +350,17 @@
 
   registerElement(Element element) {
     reporter.withCurrentElement(element, () {
-      if (element.isFunction || element.isGetter || element.isSetter) {
+      if (element.isFunction ||
+          element.isFactoryConstructor ||
+          element.isGetter ||
+          element.isSetter) {
         handleMethodAnnotations(element);
-        if (element.isNative) {
+        if (backend.isNative(element)) {
           registerMethodUsed(element);
         }
       } else if (element.isField) {
         handleFieldAnnotations(element);
-        if (element.isNative) {
+        if (backend.isNative(element)) {
           registerFieldLoad(element);
           registerFieldStore(element);
         }
@@ -364,7 +369,7 @@
   }
 
   handleFieldAnnotations(Element element) {
-    if (element.enclosingElement.isNative) {
+    if (backend.isNative(element.enclosingElement)) {
       // Exclude non-instance (static) fields - they not really native and are
       // compiled as isolate globals.  Access of a property of a constructor
       // function or a non-method property in the prototype chain, must be coded
@@ -387,10 +392,10 @@
 
   /// Sets the native name of [element], either from an annotation, or
   /// defaulting to the Dart name.
-  void setNativeName(ElementX element) {
+  void setNativeName(MemberElement element) {
     String name = findJsNameFromAnnotation(element);
     if (name == null) name = element.name;
-    element.setNative(name);
+    backend.setNativeMemberName(element, name);
   }
 
   /// Sets the native name of the static native method [element], using the
@@ -401,26 +406,27 @@
   ///    use the declared @JSName as the expression
   /// 3. If [element] does not have a @JSName annotation, qualify the name of
   ///    the method with the @Native name of the enclosing class.
-  void setNativeNameForStaticMethod(ElementX element) {
+  void setNativeNameForStaticMethod(MethodElement element) {
     String name = findJsNameFromAnnotation(element);
     if (name == null) name = element.name;
     if (isIdentifier(name)) {
-      List<String> nativeNames = nativeTagsOfClassRaw(element.enclosingClass);
+      List<String> nativeNames =
+          backend.getNativeTagsOfClassRaw(element.enclosingClass);
       if (nativeNames.length != 1) {
         reporter.internalError(element,
             'Unable to determine a native name for the enclosing class, '
             'options: $nativeNames');
       }
-      element.setNative('${nativeNames[0]}.$name');
+      backend.setNativeMemberName(element, '${nativeNames[0]}.$name');
     } else {
-      element.setNative(name);
+      backend.setNativeMemberName(element, name);
     }
   }
 
   bool isIdentifier(String s) => _identifier.hasMatch(s);
 
   bool isNativeMethod(FunctionElementX element) {
-    if (!element.library.canUseNative) return false;
+    if (!backend.canLibraryUseNative(element.library)) return false;
     // Native method?
     return reporter.withCurrentElement(element, () {
       Node node = element.parseNode(resolution.parsing);
@@ -467,20 +473,20 @@
         continue;
       }
       if (type is InterfaceType) {
-        if (type.element == compiler.intClass) {
+        if (type == coreTypes.intType) {
           backend.registerInstantiatedType(type, world, registry);
-        } else if (type.element == compiler.doubleClass) {
+        } else if (type == coreTypes.doubleType) {
           backend.registerInstantiatedType(type, world, registry);
-        } else if (type.element == compiler.numClass) {
+        } else if (type == coreTypes.numType) {
           backend.registerInstantiatedType(
-              compiler.coreTypes.doubleType, world, registry);
+              coreTypes.doubleType, world, registry);
           backend.registerInstantiatedType(
-              compiler.coreTypes.intType, world, registry);
-        } else if (type.element == compiler.stringClass) {
+              coreTypes.intType, world, registry);
+        } else if (type == coreTypes.stringType) {
           backend.registerInstantiatedType(type, world, registry);
-        } else if (type.element == compiler.nullClass) {
+        } else if (type == coreTypes.nullType) {
           backend.registerInstantiatedType(type, world, registry);
-        } else if (type.element == compiler.boolClass) {
+        } else if (type == coreTypes.boolType) {
           backend.registerInstantiatedType(type, world, registry);
         } else if (compiler.types.isSubtype(
                       type, backend.listImplementation.rawType)) {
@@ -511,7 +517,7 @@
   onFirstNativeClass() {
     staticUse(name) {
       backend.enqueue(
-          world, backend.findHelper(name), compiler.globalDependencies);
+          world, helpers.findHelper(name), compiler.globalDependencies);
     }
 
     staticUse('defineProperty');
@@ -545,10 +551,10 @@
     super.processNativeClass(classElement);
 
     // Js Interop interfaces do not have tags.
-    if (classElement.isJsInterop) return;
+    if (backend.isJsInterop(classElement)) return;
     // Since we map from dispatch tags to classes, a dispatch tag must be used
     // on only one native class.
-    for (String tag in nativeTagsOfClass(classElement)) {
+    for (String tag in backend.getNativeTagsOfClass(classElement)) {
       ClassElement owner = tagOwner[tag];
       if (owner != null) {
         if (owner != classElement) {
@@ -648,7 +654,7 @@
   }
 
   void addSubtypes(ClassElement cls, NativeEmitter emitter) {
-    if (!cls.isNative) return;
+    if (!backend.isNative(cls)) return;
     if (doneAddSubtypes.contains(cls)) return;
     doneAddSubtypes.add(cls);
 
@@ -668,7 +674,7 @@
     // natives classes.
     ClassElement superclass = cls.superclass;
     while (superclass != null && superclass.isMixinApplication) {
-      assert(!superclass.isNative);
+      assert(!backend.isNative(superclass));
       superclass = superclass.superclass;
     }
 
diff --git a/pkg/compiler/lib/src/native/js.dart b/pkg/compiler/lib/src/native/js.dart
index 7dc7d70..5d1d37b 100644
--- a/pkg/compiler/lib/src/native/js.dart
+++ b/pkg/compiler/lib/src/native/js.dart
@@ -4,6 +4,35 @@
 
 part of native;
 
+
+class HasCapturedPlaceholders extends js.BaseVisitor {
+
+  HasCapturedPlaceholders._();
+
+  static bool check(js.Node node) {
+    HasCapturedPlaceholders visitor = new HasCapturedPlaceholders._();
+    node.accept(visitor);
+    return visitor.found;
+  }
+
+  int enclosingFunctions = 0;
+  bool found = false;
+
+  @override
+  visitFun(js.Fun node) {
+    ++enclosingFunctions;
+    node.visitChildren(this);
+    --enclosingFunctions;
+  }
+
+  @override
+  visitInterpolatedNode(js.InterpolatedNode node) {
+    if (enclosingFunctions > 0) {
+      found = true;
+    }
+  }
+}
+
 class SideEffectsVisitor extends js.BaseVisitor {
   final SideEffects sideEffects;
   SideEffectsVisitor(this.sideEffects);
diff --git a/pkg/compiler/lib/src/native/native.dart b/pkg/compiler/lib/src/native/native.dart
index 994ff37..ad88cbe 100644
--- a/pkg/compiler/lib/src/native/native.dart
+++ b/pkg/compiler/lib/src/native/native.dart
@@ -30,6 +30,8 @@
     FunctionElementX,
     LibraryElementX;
 import '../js/js.dart' as js;
+import '../js_backend/backend_helpers.dart' show
+    BackendHelpers;
 import '../js_backend/js_backend.dart';
 import '../js_emitter/js_emitter.dart' show
     CodeEmitterTask,
@@ -56,8 +58,8 @@
 part 'scanner.dart';
 part 'ssa.dart';
 
-void maybeEnableNative(Compiler compiler,
-                       LibraryElementX library) {
+bool maybeEnableNative(Compiler compiler,
+                       LibraryElement library) {
   String libraryName = library.canonicalUri.toString();
   if (library.entryCompilationUnit.script.name.contains(
           'sdk/tests/compiler/dart2js_native')
@@ -72,21 +74,7 @@
       || libraryName == 'dart:web_gl'
       || libraryName == 'dart:web_sql'
       || compiler.allowNativeExtensions) {
-    library.canUseNative = true;
+    return true;
   }
+  return false;
 }
-
-// The tags string contains comma-separated 'words' which are either dispatch
-// tags (having JavaScript identifier syntax) and directives that begin with
-// `!`.
-List<String> nativeTagsOfClassRaw(ClassElement cls) {
-  String quotedName = cls.nativeTagInfo;
-  return quotedName.substring(1, quotedName.length - 1).split(',');
-}
-
-List<String> nativeTagsOfClass(ClassElement cls) {
-  return nativeTagsOfClassRaw(cls).where((s) => !s.startsWith('!')).toList();
-}
-
-bool nativeTagsForcedNonLeaf(ClassElement cls) =>
-    nativeTagsOfClassRaw(cls).contains('!nonleaf');
diff --git a/pkg/compiler/lib/src/native/scanner.dart b/pkg/compiler/lib/src/native/scanner.dart
index cfdb703..c18bfa8 100644
--- a/pkg/compiler/lib/src/native/scanner.dart
+++ b/pkg/compiler/lib/src/native/scanner.dart
@@ -5,8 +5,7 @@
 part of native;
 
 void checkAllowedLibrary(ElementListener listener, Token token) {
-  LibraryElement currentLibrary = listener.compilationUnitElement.library;
-  if (currentLibrary.canUseNative) return;
+  if (listener.scannerOptions.canUseNative) return;
   listener.reportError(token, MessageKind.NATIVE_NOT_SUPPORTED);
 }
 
diff --git a/pkg/compiler/lib/src/native/ssa.dart b/pkg/compiler/lib/src/native/ssa.dart
index 1dfa536..b51c64d 100644
--- a/pkg/compiler/lib/src/native/ssa.dart
+++ b/pkg/compiler/lib/src/native/ssa.dart
@@ -35,8 +35,8 @@
   // 3) foo() native "return 42";
   //      hasBody = true
   bool hasBody = false;
-  assert(element.isNative);
-  String nativeMethodName = element.fixedBackendName;
+  assert(backend.isNative(element));
+  String nativeMethodName = backend.getFixedBackendName(element);
   if (nativeBody != null) {
     LiteralString jsCode = nativeBody.asLiteralString();
     String str = jsCode.dartString.slowToString();
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index a5da246..cd6dd0e 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -157,13 +157,13 @@
 
   void add(Compiler compiler, InterfaceType type) {
     if (type.element == cls) {
-      if (type.element != compiler.objectClass) {
-        allSupertypes.addLast(compiler.objectClass.rawType);
+      if (type.element != compiler.coreClasses.objectClass) {
+        allSupertypes.addLast(compiler.coreTypes.objectType);
       }
       DiagnosticReporter reporter = compiler.reporter;
       _addAtDepth(reporter, type, maxDepth + 1);
     } else {
-      if (type.element != compiler.objectClass) {
+      if (type.element != compiler.coreClasses.objectClass) {
         allSupertypes.addLast(type);
       }
       DiagnosticReporter reporter = compiler.reporter;
diff --git a/pkg/compiler/lib/src/parser/class_element_parser.dart b/pkg/compiler/lib/src/parser/class_element_parser.dart
index 745665d..319cba5 100644
--- a/pkg/compiler/lib/src/parser/class_element_parser.dart
+++ b/pkg/compiler/lib/src/parser/class_element_parser.dart
@@ -13,7 +13,8 @@
     PartialParser;
 
 class ClassElementParser extends PartialParser {
-  ClassElementParser(Listener listener) : super(listener);
+  ClassElementParser(Listener listener)
+      : super(listener, enableConditionalDirectives: false);
 
   Token parseClassBody(Token token) => fullParseClassBody(token);
 }
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
index 4ae413b..9afc8d4 100644
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ b/pkg/compiler/lib/src/parser/diet_parser_task.dart
@@ -17,20 +17,30 @@
 import 'listener.dart' show
     ParserError;
 import 'element_listener.dart' show
-    ElementListener;
+    ElementListener,
+    ScannerOptions;
 import 'partial_parser.dart' show
     PartialParser;
 
 class DietParserTask extends CompilerTask {
-  DietParserTask(Compiler compiler) : super(compiler);
+  final bool _enableConditionalDirectives;
+
+  DietParserTask(Compiler compiler, {bool enableConditionalDirectives})
+      : this._enableConditionalDirectives = enableConditionalDirectives,
+        super(compiler);
+
   final String name = 'Diet Parser';
 
   dietParse(CompilationUnitElement compilationUnit, Token tokens) {
     measure(() {
       Function idGenerator = compiler.getNextFreeClassId;
-      ElementListener listener =
-          new ElementListener(compiler.reporter, compilationUnit, idGenerator);
-      PartialParser parser = new PartialParser(listener);
+      ScannerOptions scannerOptions = new ScannerOptions(
+          canUseNative: compiler.backend.canLibraryUseNative(
+              compilationUnit.library));
+      ElementListener listener = new ElementListener(
+          scannerOptions, compiler.reporter, compilationUnit, idGenerator);
+      PartialParser parser = new PartialParser(
+          listener, enableConditionalDirectives: _enableConditionalDirectives);
       try {
         parser.parseUnit(tokens);
       } on ParserError catch(_) {
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 94da7df..48bfae31 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -18,7 +18,7 @@
     EnumClassElementX,
     FieldElementX,
     LibraryElementX,
-    MixinApplicationElementX,
+    NamedMixinApplicationElementX,
     VariableList;
 import '../native/native.dart' as native;
 import '../string_validator.dart' show
@@ -54,6 +54,16 @@
 
 typedef int IdGenerator();
 
+/// Options used for scanning.
+///
+/// Use this to conditionally support special tokens.
+class ScannerOptions {
+  /// If `true` the pseudo keyword `native` is supported.
+  final bool canUseNative;
+
+  const ScannerOptions({this.canUseNative: false});
+}
+
 /**
  * A parser event listener designed to work with [PartialParser]. It
  * builds elements representing the top-level declarations found in
@@ -63,6 +73,7 @@
 class ElementListener extends Listener {
   final IdGenerator idGenerator;
   final DiagnosticReporter reporter;
+  final ScannerOptions scannerOptions;
   final CompilationUnitElementX compilationUnitElement;
   final StringValidator stringValidator;
   Link<StringQuoting> interpolationScope;
@@ -84,6 +95,7 @@
   bool suppressParseErrors = false;
 
   ElementListener(
+      this.scannerOptions,
       DiagnosticReporter reporter,
       this.compilationUnitElement,
       this.idGenerator)
@@ -138,12 +150,34 @@
     if (asKeyword != null) {
       prefix = popNode();
     }
+    NodeList conditionalUris = popNode();
     StringNode uri = popLiteralString();
-    addLibraryTag(new Import(importKeyword, uri, prefix, combinators,
+    addLibraryTag(new Import(importKeyword, uri, conditionalUris,
+                             prefix, combinators,
                              popMetadata(compilationUnitElement),
                              isDeferred: isDeferred));
   }
 
+  void endDottedName(int count, Token token) {
+    NodeList identifiers = makeNodeList(count, null, null, '.');
+    pushNode(new DottedName(token, identifiers));
+  }
+
+  void endConditionalUris(int count) {
+    if (count == 0) {
+      pushNode(null);
+    } else {
+      pushNode(makeNodeList(count, null, null, " "));
+    }
+  }
+
+  void endConditionalUri(Token ifToken, Token equalSign) {
+    StringNode uri = popNode();
+    LiteralString conditionValue = (equalSign != null) ? popNode() : null;
+    DottedName identifier = popNode();
+    pushNode(new ConditionalUri(ifToken, identifier, conditionValue, uri));
+  }
+
   void endEnum(Token enumKeyword, Token endBrace, int count) {
     NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
     Identifier name = popNode();
@@ -157,8 +191,9 @@
 
   void endExport(Token exportKeyword, Token semicolon) {
     NodeList combinators = popNode();
+    NodeList conditionalUris = popNode();
     StringNode uri = popNode();
-    addLibraryTag(new Export(exportKeyword, uri, combinators,
+    addLibraryTag(new Export(exportKeyword, uri, conditionalUris, combinators,
                              popMetadata(compilationUnitElement)));
   }
 
@@ -266,9 +301,8 @@
 
     int id = idGenerator();
     Element enclosing = compilationUnitElement;
-    pushElement(new MixinApplicationElementX(name.source, enclosing, id,
-                                             namedMixinApplication,
-                                             modifiers));
+    pushElement(new NamedMixinApplicationElementX(
+        name.source, enclosing, id, namedMixinApplication));
     rejectBuiltInIdentifier(name);
   }
 
@@ -591,7 +625,9 @@
     reportFatalError(node, message);
   }
 
-  void pushElement(Element element) {
+  void pushElement(ElementX element) {
+    assert(invariant(element, element.declarationSite != null,
+        message: 'Missing declaration site for $element.'));
     popMetadata(element);
     compilationUnitElement.addMember(element, reporter);
   }
diff --git a/pkg/compiler/lib/src/parser/listener.dart b/pkg/compiler/lib/src/parser/listener.dart
index 6511abc..618b86a 100644
--- a/pkg/compiler/lib/src/parser/listener.dart
+++ b/pkg/compiler/lib/src/parser/listener.dart
@@ -232,6 +232,24 @@
                  Token asKeyword, Token semicolon) {
   }
 
+  void beginConditionalUris(Token token) {
+  }
+
+  void endConditionalUris(int count) {
+  }
+
+  void beginConditionalUri(Token ifKeyword) {
+  }
+
+  void endConditionalUri(Token ifKeyword, Token equalitySign) {
+  }
+
+  void beginDottedName(Token token) {
+  }
+
+  void endDottedName(int count, Token firstIdentifier) {
+  }
+
   void beginInitializedIdentifier(Token token) {
   }
 
diff --git a/pkg/compiler/lib/src/parser/member_listener.dart b/pkg/compiler/lib/src/parser/member_listener.dart
index a6856b3..0399d71 100644
--- a/pkg/compiler/lib/src/parser/member_listener.dart
+++ b/pkg/compiler/lib/src/parser/member_listener.dart
@@ -19,20 +19,23 @@
     Token;
 import '../tree/tree.dart';
 
+import 'element_listener.dart' show
+    ScannerOptions;
+import 'node_listener.dart' show
+    NodeListener;
 import 'partial_elements.dart' show
     PartialConstructorElement,
     PartialFunctionElement,
     PartialMetadataAnnotation;
-import 'node_listener.dart' show
-    NodeListener;
 
 class MemberListener extends NodeListener {
   final ClassElementX enclosingClass;
 
-  MemberListener(DiagnosticReporter listener,
+  MemberListener(ScannerOptions scannerOptions,
+                 DiagnosticReporter listener,
                  ClassElementX enclosingElement)
       : this.enclosingClass = enclosingElement,
-        super(listener, enclosingElement.compilationUnit);
+        super(scannerOptions, listener, enclosingElement.compilationUnit);
 
   bool isConstructorName(Node nameNode) {
     if (enclosingClass == null ||
@@ -116,7 +119,7 @@
     }
     Element memberElement = new PartialConstructorElement(
         name, beginToken, endToken,
-        ElementKind.FUNCTION,
+        ElementKind.FACTORY_CONSTRUCTOR,
         method.modifiers,
         enclosingClass);
     addMember(memberElement);
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
index c6bd18a..3a3e91b 100644
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ b/pkg/compiler/lib/src/parser/node_listener.dart
@@ -21,15 +21,17 @@
     Link;
 
 import 'element_listener.dart' show
-    ElementListener;
+    ElementListener,
+    ScannerOptions;
 import 'partial_elements.dart' show
     PartialFunctionElement;
 
 class NodeListener extends ElementListener {
   NodeListener(
+      ScannerOptions scannerOptions,
       DiagnosticReporter reporter,
       CompilationUnitElement element)
-    : super(reporter, element, null);
+    : super(scannerOptions, reporter, element, null);
 
   void addLibraryTag(LibraryTag tag) {
     pushNode(tag);
diff --git a/pkg/compiler/lib/src/parser/parser.dart b/pkg/compiler/lib/src/parser/parser.dart
index 7adddb5..f2e0577 100644
--- a/pkg/compiler/lib/src/parser/parser.dart
+++ b/pkg/compiler/lib/src/parser/parser.dart
@@ -98,11 +98,12 @@
 class Parser {
   final Listener listener;
   bool mayParseFunctionExpressions = true;
-  bool yieldIsKeyword;
-  bool awaitIsKeyword;
+  final bool enableConditionalDirectives;
+  bool asyncAwaitKeywordsEnabled;
 
   Parser(this.listener,
-         {this.yieldIsKeyword: false, this.awaitIsKeyword: false});
+      {this.enableConditionalDirectives: false,
+       this.asyncAwaitKeywordsEnabled: false});
 
   Token parseUnit(Token token) {
     listener.beginCompilationUnit(token);
@@ -151,12 +152,13 @@
     return token;
   }
 
-  /// import uri (as identifier)? combinator* ';'
+  /// import uri (if (test) uri)* (as identifier)? combinator* ';'
   Token parseImport(Token token) {
     Token importKeyword = token;
     listener.beginImport(importKeyword);
     assert(optional('import', token));
     token = parseLiteralStringOrRecoverExpression(token.next);
+    token = parseConditionalUris(token);
     Token deferredKeyword;
     if (optional('deferred', token)) {
       deferredKeyword = token;
@@ -174,12 +176,57 @@
     return token;
   }
 
-  /// export uri combinator* ';'
+  /// if (test) uri
+  Token parseConditionalUris(Token token) {
+    listener.beginConditionalUris(token);
+    int count = 0;
+    if (enableConditionalDirectives) {
+      while (optional('if', token)) {
+        count++;
+        token = parseConditionalUri(token);
+      }
+    }
+    listener.endConditionalUris(count);
+    return token;
+  }
+
+  Token parseConditionalUri(Token token) {
+    listener.beginConditionalUri(token);
+    Token ifKeyword = token;
+    token = expect('if', token);
+    token = expect('(', token);
+    token = parseDottedName(token);
+    Token equalitySign;
+    if (optional('==', token)) {
+      equalitySign = token;
+      token = parseLiteralStringOrRecoverExpression(token.next);
+    }
+    token = expect(')', token);
+    token = parseLiteralStringOrRecoverExpression(token);
+    listener.endConditionalUri(ifKeyword, equalitySign);
+    return token;
+  }
+
+  Token parseDottedName(Token token) {
+    listener.beginDottedName(token);
+    Token firstIdentifier = token;
+    token = parseIdentifier(token);
+    int count = 1;
+    while (optional('.', token)) {
+      token = parseIdentifier(token.next);
+      count++;
+    }
+    listener.endDottedName(count, firstIdentifier);
+    return token;
+  }
+
+  /// export uri conditional-uris* combinator* ';'
   Token parseExport(Token token) {
     Token exportKeyword = token;
     listener.beginExport(exportKeyword);
     assert(optional('export', token));
     token = parseLiteralStringOrRecoverExpression(token.next);
+    token = parseConditionalUris(token);
     token = parseCombinators(token);
     Token semicolon = token;
     token = expect(';', token);
@@ -660,15 +707,27 @@
 
   /**
    * Returns true if the stringValue of the [token] is either [value1],
+   * [value2], or [value3].
+   */
+  bool isOneOf3(Token token, String value1, String value2, String value3) {
+    String stringValue = token.stringValue;
+    return
+        value1 == stringValue ||
+        value2 == stringValue ||
+        value3 == stringValue;
+  }
+
+  /**
+   * Returns true if the stringValue of the [token] is either [value1],
    * [value2], [value3], or [value4].
    */
   bool isOneOf4(Token token,
                 String value1, String value2, String value3, String value4) {
     String stringValue = token.stringValue;
-    return identical(value1, stringValue) ||
-           identical(value2, stringValue) ||
-           identical(value3, stringValue) ||
-           identical(value4, stringValue);
+    return value1 == stringValue ||
+           value2 == stringValue ||
+           value3 == stringValue ||
+           value4 == stringValue;
   }
 
   bool notEofOrValue(String value, Token token) {
@@ -931,6 +990,8 @@
                             Token name) {
 
     Token externalModifier;
+    // TODO(johnniwinther): Move error reporting to resolution to give more
+    // specific error messages.
     for (Token modifier in modifiers) {
       if (externalModifier == null && optional('external', modifier)) {
         externalModifier = modifier;
@@ -954,12 +1015,10 @@
     Token token = parseIdentifier(name);
 
     token = parseFormalParametersOpt(token);
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     token = parseFunctionBody(token, false, externalModifier != null);
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     Token endToken = token;
     token = token.next;
     if (token.kind == BAD_INPUT_TOKEN) {
@@ -1306,6 +1365,8 @@
     Token constModifier;
     int modifierCount = 0;
     int allowedModifierCount = 1;
+    // TODO(johnniwinther): Move error reporting to resolution to give more
+    // specific error messages.
     for (Token modifier in modifiers) {
       if (externalModifier == null && optional('external', modifier)) {
         modifierCount++;
@@ -1337,6 +1398,11 @@
             modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier});
       }
     }
+    if (getOrSet != null &&  constModifier != null) {
+      listener.reportError(
+          constModifier, MessageKind.EXTRANEOUS_MODIFIER,
+          {'modifier': constModifier});
+    }
     parseModifierList(modifiers);
 
     if (type == null) {
@@ -1348,7 +1414,6 @@
     if (optional('operator', name)) {
       token = parseOperatorName(name);
       if (staticModifier != null) {
-        // TODO(ahe): Consider a more specific error message.
         listener.reportError(
             staticModifier, MessageKind.EXTRANEOUS_MODIFIER,
             {'modifier': staticModifier});
@@ -1360,8 +1425,7 @@
     token = parseQualifiedRestOpt(token);
     token = parseFormalParametersOpt(token);
     token = parseInitializersOpt(token);
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     if (optional('=', token)) {
       token = parseRedirectingFactoryBody(token);
@@ -1369,8 +1433,7 @@
       token = parseFunctionBody(
           token, false, staticModifier == null || externalModifier != null);
     }
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     listener.endMethod(getOrSet, start, token);
     return token.next;
   }
@@ -1448,16 +1511,14 @@
     listener.endFunctionName(token);
     token = parseFormalParametersOpt(token);
     token = parseInitializersOpt(token);
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     if (optional('=', token)) {
       token = parseRedirectingFactoryBody(token);
     } else {
       token = parseFunctionBody(token, false, true);
     }
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     listener.endFunction(getOrSet, token);
     return token.next;
   }
@@ -1465,13 +1526,11 @@
   Token parseUnnamedFunction(Token token) {
     listener.beginUnnamedFunction(token);
     token = parseFormalParameters(token);
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     bool isBlock = optional('{', token);
     token = parseFunctionBody(token, true, false);
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     listener.endUnnamedFunction(token);
     return isBlock ? token.next : token;
   }
@@ -1492,13 +1551,11 @@
     listener.endFunctionName(token);
     token = parseFormalParameters(token);
     listener.handleNoInitializers();
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     bool isBlock = optional('{', token);
     token = parseFunctionBody(token, true, false);
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     listener.endFunction(null, token);
     return isBlock ? token.next : token;
   }
@@ -1567,14 +1624,12 @@
   Token parseAsyncModifier(Token token) {
     Token async;
     Token star;
-    awaitIsKeyword = false;
-    yieldIsKeyword = false;
+    asyncAwaitKeywordsEnabled = false;
     if (optional('async', token)) {
-      awaitIsKeyword = true;
+      asyncAwaitKeywordsEnabled = true;
       async = token;
       token = token.next;
       if (optional('*', token)) {
-        yieldIsKeyword = true;
         star = token;
         token = token.next;
       }
@@ -1582,7 +1637,7 @@
       async = token;
       token = token.next;
       if (optional('*', token)) {
-        yieldIsKeyword = true;
+        asyncAwaitKeywordsEnabled = true;
         star = token;
         token = token.next;
       } else {
@@ -1606,7 +1661,7 @@
       return parseVariablesDeclaration(token);
     } else if (identical(value, 'if')) {
       return parseIfStatement(token);
-    } else if (awaitIsKeyword && identical(value, 'await')) {
+    } else if (asyncAwaitKeywordsEnabled && identical(value, 'await')) {
       if (identical(token.next.stringValue, 'for')) {
         return parseForStatement(token, token.next);
       } else {
@@ -1637,7 +1692,7 @@
       return parseAssertStatement(token);
     } else if (identical(value, ';')) {
       return parseEmptyStatement(token);
-    } else if (yieldIsKeyword && identical(value, 'yield')) {
+    } else if (asyncAwaitKeywordsEnabled && identical(value, 'yield')) {
       return parseYieldStatement(token);
     } else if (identical(value, 'const')) {
       return parseExpressionStatementOrConstDeclaration(token);
@@ -1919,7 +1974,7 @@
   Token parseUnaryExpression(Token token, bool allowCascades) {
     String value = token.stringValue;
     // Prefix:
-    if (awaitIsKeyword && optional('await', token)) {
+    if (asyncAwaitKeywordsEnabled && optional('await', token)) {
       return parseAwaitExpression(token, allowCascades);
     } else if (identical(value, '+')) {
       // Dart no longer allows prefix-plus.
@@ -1970,44 +2025,47 @@
 
   Token parsePrimary(Token token) {
     final kind = token.kind;
-    if (identical(kind, IDENTIFIER_TOKEN)) {
+    if (kind == IDENTIFIER_TOKEN) {
       return parseSendOrFunctionLiteral(token);
-    } else if (identical(kind, INT_TOKEN)
-        || identical(kind, HEXADECIMAL_TOKEN)) {
+    } else if (kind == INT_TOKEN
+        || kind == HEXADECIMAL_TOKEN) {
       return parseLiteralInt(token);
-    } else if (identical(kind, DOUBLE_TOKEN)) {
+    } else if (kind == DOUBLE_TOKEN) {
       return parseLiteralDouble(token);
-    } else if (identical(kind, STRING_TOKEN)) {
+    } else if (kind == STRING_TOKEN) {
       return parseLiteralString(token);
-    } else if (identical(kind, HASH_TOKEN)) {
+    } else if (kind == HASH_TOKEN) {
       return parseLiteralSymbol(token);
-    } else if (identical(kind, KEYWORD_TOKEN)) {
+    } else if (kind == KEYWORD_TOKEN) {
       final value = token.stringValue;
-      if ((identical(value, 'true')) || (identical(value, 'false'))) {
+      if (value == 'true' || value == 'false') {
         return parseLiteralBool(token);
-      } else if (identical(value, 'null')) {
+      } else if (value == 'null') {
         return parseLiteralNull(token);
-      } else if (identical(value, 'this')) {
+      } else if (value == 'this') {
         return parseThisExpression(token);
-      } else if (identical(value, 'super')) {
+      } else if (value == 'super') {
         return parseSuperExpression(token);
-      } else if (identical(value, 'new')) {
+      } else if (value == 'new') {
         return parseNewExpression(token);
-      } else if (identical(value, 'const')) {
+      } else if (value == 'const') {
         return parseConstExpression(token);
-      } else if (identical(value, 'void')) {
+      } else if (value == 'void') {
         return parseFunctionExpression(token);
+      } else if (asyncAwaitKeywordsEnabled &&
+                 (value == 'yield' || value == 'async')) {
+        return listener.expectedExpression(token);
       } else if (token.isIdentifier()) {
         return parseSendOrFunctionLiteral(token);
       } else {
         return listener.expectedExpression(token);
       }
-    } else if (identical(kind, OPEN_PAREN_TOKEN)) {
+    } else if (kind == OPEN_PAREN_TOKEN) {
       return parseParenthesizedExpressionOrFunctionLiteral(token);
-    } else if ((identical(kind, LT_TOKEN)) ||
-               (identical(kind, OPEN_SQUARE_BRACKET_TOKEN)) ||
-               (identical(kind, OPEN_CURLY_BRACKET_TOKEN)) ||
-               identical(token.stringValue, '[]')) {
+    } else if ((kind == LT_TOKEN) ||
+               (kind == OPEN_SQUARE_BRACKET_TOKEN) ||
+               (kind == OPEN_CURLY_BRACKET_TOKEN) ||
+               token.stringValue == '[]') {
       return parseLiteralListOrMap(token);
     } else {
       return listener.expectedExpression(token);
@@ -2427,7 +2485,7 @@
     if (identical(value, ';')) {
       listener.handleNoExpression(token);
       return token;
-    } else if ((identical(value, 'var')) || (identical(value, 'final'))) {
+    } else if (isOneOf3(token, 'var', 'final', 'const')) {
       return parseVariablesDeclarationNoSemicolon(token);
     }
     Token identifier = peekIdentifierAfterType(token);
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
index 0a84c12..fa715aa 100644
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ b/pkg/compiler/lib/src/parser/parser_task.dart
@@ -16,6 +16,8 @@
 import '../tree/tree.dart' show
     Node;
 
+import 'element_listener.dart' show
+    ScannerOptions;
 import 'listener.dart' show
     ParserError;
 import 'node_listener.dart' show
@@ -24,7 +26,13 @@
     Parser;
 
 class ParserTask extends CompilerTask {
-  ParserTask(Compiler compiler) : super(compiler);
+  final bool _enableConditionalDirectives;
+
+  ParserTask(Compiler compiler,
+             {bool enableConditionalDirectives: false})
+      : this._enableConditionalDirectives = enableConditionalDirectives,
+        super(compiler);
+
   String get name => 'Parser';
 
   Node parse(ElementX element) {
@@ -33,8 +41,10 @@
 
   Node parseCompilationUnit(Token token) {
     return measure(() {
-      NodeListener listener = new NodeListener(reporter, null);
-      Parser parser = new Parser(listener);
+      NodeListener listener = new NodeListener(
+          const ScannerOptions(), reporter, null);
+      Parser parser = new Parser(
+          listener, enableConditionalDirectives: _enableConditionalDirectives);
       try {
         parser.parseUnit(token);
       } on ParserError catch(_) {
diff --git a/pkg/compiler/lib/src/parser/partial_elements.dart b/pkg/compiler/lib/src/parser/partial_elements.dart
index 6e3e11c..d72c6b7 100644
--- a/pkg/compiler/lib/src/parser/partial_elements.dart
+++ b/pkg/compiler/lib/src/parser/partial_elements.dart
@@ -66,7 +66,7 @@
 
   bool hasParseError = false;
 
-  bool get isErroneous => hasParseError;
+  bool get isMalformed => hasParseError;
 
   DeclarationSite get declarationSite => this;
 }
@@ -237,6 +237,8 @@
   }
 }
 
+// TODO(johnniwinther): Create [PartialGenerativeConstructor] and
+// [PartialFactoryConstructor] subclasses and make this abstract.
 class PartialConstructorElement extends ConstructorElementX
     with PartialElement, PartialFunctionMixin {
   PartialConstructorElement(String name,
@@ -295,7 +297,9 @@
     // TODO(johnniwinther): Compute this in the resolver.
     VariableDefinitions node = parseNode(element, resolution.parsing);
     if (node.type != null) {
-      type = resolution.resolveTypeAnnotation(element, node.type);
+      type = resolution.reporter.withCurrentElement(element, () {
+        return resolution.resolveTypeAnnotation(element, node.type);
+      });
     } else {
       type = const DynamicType();
     }
@@ -342,7 +346,7 @@
 
   PartialMetadataAnnotation(this.beginToken, this.tokenAfterEndToken);
 
-  bool get isErroneous => hasParseError;
+  bool get isMalformed => hasParseError;
 
   DeclarationSite get declarationSite => this;
 
@@ -421,7 +425,8 @@
     DiagnosticReporter reporter = parsing.reporter;
     reporter.withCurrentElement(this, () {
       parsing.measure(() {
-        MemberListener listener = new MemberListener(reporter, this);
+        MemberListener listener = new MemberListener(
+            parsing.getScannerOptionsFor(this), reporter, this);
         Parser parser = new ClassElementParser(listener);
         try {
           Token token = parser.parseTopLevelDeclaration(beginToken);
@@ -479,7 +484,8 @@
   return parsing.measure(() {
     return reporter.withCurrentElement(element, () {
       CompilationUnitElement unit = element.compilationUnit;
-      NodeListener listener = new NodeListener(reporter, unit);
+      NodeListener listener = new NodeListener(
+          parsing.getScannerOptionsFor(element), reporter, unit);
       listener.memberErrors = listener.memberErrors.prepend(false);
       try {
         if (partial.hasParseError) {
diff --git a/pkg/compiler/lib/src/parser/partial_parser.dart b/pkg/compiler/lib/src/parser/partial_parser.dart
index 01de07c..1c7722f 100644
--- a/pkg/compiler/lib/src/parser/partial_parser.dart
+++ b/pkg/compiler/lib/src/parser/partial_parser.dart
@@ -20,7 +20,9 @@
     Parser;
 
 class PartialParser extends Parser {
-  PartialParser(Listener listener) : super(listener);
+  PartialParser(Listener listener, {bool enableConditionalDirectives})
+      : super(listener,
+          enableConditionalDirectives: enableConditionalDirectives);
 
   Token parseClassBody(Token token) => skipClassBody(token);
 
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index 1b9e8f3..593b08f 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -159,8 +159,11 @@
 
 class PatchParserTask extends CompilerTask {
   final String name = "Patching Parser";
+  final bool _enableConditionalDirectives;
 
-  PatchParserTask(Compiler compiler): super(compiler);
+  PatchParserTask(Compiler compiler, {bool enableConditionalDirectives})
+      : this._enableConditionalDirectives = enableConditionalDirectives,
+        super(compiler);
 
   /**
    * Scans a library patch file, applies the method patches and
@@ -195,7 +198,9 @@
                                                         compilationUnit,
                                                         idGenerator);
       try {
-        new PartialParser(patchListener).parseUnit(tokens);
+        new PartialParser(patchListener,
+            enableConditionalDirectives: _enableConditionalDirectives)
+            .parseUnit(tokens);
       } on ParserError catch (e) {
         // No need to recover from a parser error in platform libraries, user
         // will never see this if the libraries are tested correctly.
@@ -212,7 +217,8 @@
 
     measure(() => reporter.withCurrentElement(cls, () {
       MemberListener listener = new PatchMemberListener(compiler, cls);
-      Parser parser = new PatchClassElementParser(listener);
+      Parser parser = new PatchClassElementParser(
+          listener, enableConditionalDirectives: _enableConditionalDirectives);
       try {
         Token token = parser.parseTopLevelDeclaration(cls.beginToken);
         assert(identical(token, cls.endToken.next));
@@ -233,7 +239,9 @@
 
   PatchMemberListener(Compiler compiler, ClassElement enclosingClass)
       : this.compiler = compiler,
-        super(compiler.reporter, enclosingClass);
+        super(compiler.parsing.getScannerOptionsFor(enclosingClass),
+              compiler.reporter,
+              enclosingClass);
 
   @override
   void addMember(Element patch) {
@@ -249,6 +257,9 @@
         // Skip this element.
       }
     } else {
+      if (Name.isPublicName(patch.name)) {
+        reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
+      }
       enclosingClass.addMember(patch, reporter);
     }
   }
@@ -259,7 +270,9 @@
  * declarations.
  */
 class PatchClassElementParser extends PartialParser {
-  PatchClassElementParser(Listener listener) : super(listener);
+  PatchClassElementParser(Listener listener, {bool enableConditionalDirectives})
+      : super(listener,
+          enableConditionalDirectives: enableConditionalDirectives);
 
   Token parseClassBody(Token token) => fullParseClassBody(token);
 }
@@ -274,7 +287,8 @@
                        CompilationUnitElement patchElement,
                        int idGenerator())
     : this.compiler = compiler,
-      super(compiler.reporter, patchElement, idGenerator);
+      super(compiler.parsing.getScannerOptionsFor(patchElement),
+            compiler.reporter, patchElement, idGenerator);
 
   @override
   void pushElement(Element patch) {
@@ -292,6 +306,9 @@
         // Skip this element.
       }
     } else {
+      if (Name.isPublicName(patch.name)) {
+        reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
+      }
       compilationUnitElement.addMember(patch, reporter);
     }
   }
@@ -445,8 +462,8 @@
     if (element.isClass) {
       String native = getNativeAnnotation(annotation);
       if (native != null) {
-        ClassElementX declaration = element.declaration;
-        declaration.setNative(native);
+        JavaScriptBackend backend = compiler.backend;
+        backend.setNativeClassTagInfo(element, native);
         return native;
       }
     }
@@ -478,7 +495,8 @@
              MetadataAnnotation annotation) {
     bool hasJsInterop = hasJsNameAnnotation(annotation);
     if (hasJsInterop) {
-      element.markAsJsInterop();
+      JavaScriptBackend backend = compiler.backend;
+      backend.markAsJsInterop(element);
     }
     // Due to semantics of apply in the baseclass we have to return null to
     // indicate that no match was found.
@@ -492,7 +510,7 @@
                 ConstantValue constant) {
     JavaScriptBackend backend = compiler.backend;
     if (constant.getType(compiler.coreTypes).element !=
-        backend.jsAnnotationClass) {
+        backend.helpers.jsAnnotationClass) {
       compiler.reporter.internalError(annotation, 'Invalid @JS(...) annotation.');
     }
   }
diff --git a/pkg/compiler/lib/src/platform_configuration.dart b/pkg/compiler/lib/src/platform_configuration.dart
new file mode 100644
index 0000000..41da852
--- /dev/null
+++ b/pkg/compiler/lib/src/platform_configuration.dart
@@ -0,0 +1,142 @@
+// Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+/// Tools for loading and parsing platform-configuration files.
+library plaform_configuration;
+
+import "dart:async";
+import "package:charcode/ascii.dart";
+import "../compiler_new.dart" as api;
+
+/// Parses an Ini-like format.
+///
+/// Sections are initialized with a name enclosed in brackets.
+/// Each section contain zero or more properties of the form "name:value".
+/// Empty lines are ignored.
+/// Lines starting with # are ignored.
+/// Duplicate names are not allowed.
+/// All keys and values will be passed through [String.trim].
+///
+/// If an error is found, a [FormatException] is thrown, using [sourceUri] in
+/// the error message.
+///
+/// Example
+/// ```
+/// [a]
+/// b:c
+///
+/// [d]
+/// e:file:///tmp/bla
+/// ```
+/// Will parse to {"a": {"b":"c"}, "d": {"e": "file:///tmp/bla"}}.
+
+Map<String, Map<String, String>> parseIni(List<int> source,
+    {Set<String> allowedSections, Uri sourceUri}) {
+  int startOfLine = 0;
+  int currentLine = 0;
+
+  error(String message, int index) {
+    int column = index - startOfLine + 1;
+    throw new FormatException(
+        "$sourceUri:$currentLine:$column: $message", sourceUri, index);
+  }
+
+  Map<String, Map<String, String>> result =
+      new Map<String, Map<String, String>>();
+  Map<String, String> currentSection = null;
+
+  if (source.length == 0) return result;
+  bool endOfFile = false;
+
+  // Iterate once per $lf in file.
+  while (!endOfFile) {
+    currentLine += 1;
+    int endOfLine = source.indexOf($lf, startOfLine);
+    if (endOfLine == -1) {
+      // The dart2js provider adds a final 0 to the file.
+      endOfLine = source.last == 0 ? source.length - 1 : source.length;
+      endOfFile = true;
+    }
+    if (startOfLine != endOfLine) {
+      int firstChar = source[startOfLine];
+      if (firstChar == $hash) {
+        // Comment, do nothing.
+      } else if (firstChar == $open_bracket) {
+        // Section header
+        int endOfHeader = source.indexOf($close_bracket, startOfLine);
+        if (endOfHeader == -1) {
+          error("'[' must be matched by ']' on the same line.", startOfLine);
+        }
+        if (endOfHeader == startOfLine + 1) {
+          error("Empty header name", startOfLine + 1);
+        }
+        if (endOfHeader != endOfLine - 1) {
+          error("Section heading lines must end with ']'", endOfHeader + 1);
+        }
+        int startOfSectionName = startOfLine + 1;
+        String sectionName = new String.fromCharCodes(
+            source, startOfSectionName, endOfHeader).trim();
+        currentSection = new Map<String, String>();
+        if (result.containsKey(sectionName)) {
+          error("Duplicate section name '$sectionName'", startOfSectionName);
+        }
+        if (allowedSections != null && !allowedSections.contains(sectionName)) {
+          error("Unrecognized section name '$sectionName'", startOfSectionName);
+        }
+        result[sectionName] = currentSection;
+      } else {
+        // Property line
+        if (currentSection == null) {
+          error("Property outside section", startOfLine);
+        }
+        int separator = source.indexOf($colon, startOfLine);
+        if (separator == startOfLine) {
+          error("Empty property name", startOfLine);
+        }
+        if (separator == -1 || separator > endOfLine) {
+          error("Property line without ':'", startOfLine);
+        }
+        String propertyName =
+            new String.fromCharCodes(source, startOfLine, separator).trim();
+        if (currentSection.containsKey(propertyName)) {
+          error("Duplicate property name '$propertyName'", startOfLine);
+        }
+        String propertyValue =
+            new String.fromCharCodes(source, separator + 1, endOfLine).trim();
+        currentSection[propertyName] = propertyValue;
+      }
+    }
+    startOfLine = endOfLine + 1;
+  }
+  return result;
+}
+
+const String librariesSection = "libraries";
+const String dartSpecSection = "dart-spec";
+const String featuresSection = "features";
+
+Map<String, Uri> libraryMappings(
+    Map<String, Map<String, String>> sections, Uri baseLocation) {
+  assert(sections.containsKey(librariesSection));
+  Map<String, Uri> result = new Map<String, Uri>();
+  sections[librariesSection].forEach((String name, String value) {
+    result[name] = baseLocation.resolve(value);
+  });
+  return result;
+}
+
+final Set<String> allowedSections =
+    new Set.from([librariesSection, dartSpecSection, featuresSection]);
+
+Future<Map<String, Uri>> load(Uri location, api.CompilerInput provider) {
+  return provider.readFromUri(location).then((contents) {
+    if (contents is String) {
+      contents = contents.codeUnits;
+    }
+    return libraryMappings(
+        parseIni(contents,
+            allowedSections: allowedSections, sourceUri: location),
+        location);
+  });
+}
diff --git a/pkg/compiler/lib/src/resolution/access_semantics.dart b/pkg/compiler/lib/src/resolution/access_semantics.dart
index a41b867..baead69 100644
--- a/pkg/compiler/lib/src/resolution/access_semantics.dart
+++ b/pkg/compiler/lib/src/resolution/access_semantics.dart
@@ -180,8 +180,12 @@
   SUPER_GETTER_FIELD,
 
   /// Read from a superclass where the getter is unresolved.
+  // TODO(johnniwinther): Use [AccessKind.SUPER_GETTER] when the erroneous
+  // element is no longer needed.
   UNRESOLVED_SUPER_GETTER,
   /// Read from a superclass getter and write to an unresolved setter.
+  // TODO(johnniwinther): Use [AccessKind.SUPER_SETTER] when the erroneous
+  // element is no longer needed.
   UNRESOLVED_SUPER_SETTER,
 }
 
@@ -388,49 +392,31 @@
 /// Enum representing the different kinds of destinations which a constructor
 /// invocation might refer to.
 enum ConstructorAccessKind {
-  /// An invocation of a generative constructor.
+  /// An invocation of a (redirecting) generative constructor.
   ///
   /// For instance
   ///     class C {
   ///       C();
+  ///       C.redirect() : this();
   ///     }
-  ///     m() => new C();
+  ///     m1() => new C();
+  ///     m2() => new C.redirect();
   ///
   GENERATIVE,
 
-  /// An invocation of a redirecting generative constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       C() : this._();
-  ///       C._();
-  ///     }
-  ///     m() => new C();
-  ///
-  REDIRECTING_GENERATIVE,
-
-  /// An invocation of a factory constructor.
+  /// An invocation of a (redirecting) factory constructor.
   ///
   /// For instance
   ///     class C {
   ///       factory C() => new C._();
+  ///       factory C.redirect() => C._;
   ///       C._();
   ///     }
-  ///     m() => new C();
+  ///     m1() => new C();
+  ///     m2() => new C.redirect();
   ///
   FACTORY,
 
-  /// An invocation of a redirecting factory constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       factory C() = C._;
-  ///       C._();
-  ///     }
-  ///     m() => new C();
-  ///
-  REDIRECTING_FACTORY,
-
   /// An invocation of a (redirecting) generative constructor of an abstract
   /// class.
   ///
@@ -469,17 +455,6 @@
   ///
   NON_CONSTANT_CONSTRUCTOR,
 
-  /// An invocation of an ill-defined redirecting factory constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       factory C() = Unresolved;
-  ///     }
-  ///     m() => new C();
-  ///
-  ERRONEOUS_REDIRECTING_FACTORY,
-
-
   /// An invocation of a constructor with incompatible arguments.
   ///
   /// For instance
@@ -504,35 +479,5 @@
 
   ConstructorAccessSemantics(this.kind, this.element, this.type);
 
-  /// The effect target of the access. Used to defined redirecting factory
-  /// constructor invocations.
-  ConstructorAccessSemantics get effectiveTargetSemantics => this;
-
-  /// `true` if this invocation is erroneous.
-  bool get isErroneous {
-    return kind == ConstructorAccessKind.ABSTRACT ||
-           kind == ConstructorAccessKind.UNRESOLVED_TYPE ||
-           kind == ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR ||
-           kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR ||
-           kind == ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY ||
-           kind == ConstructorAccessKind.INCOMPATIBLE;
-  }
-
   String toString() => 'ConstructorAccessSemantics($kind, $element, $type)';
 }
-
-/// Data structure used to classify the semantics of a redirecting factory
-/// constructor invocation.
-class RedirectingFactoryConstructorAccessSemantics
-    extends ConstructorAccessSemantics {
-  final ConstructorAccessSemantics effectiveTargetSemantics;
-
-  RedirectingFactoryConstructorAccessSemantics(
-      ConstructorAccessKind kind,
-      Element element,
-      DartType type,
-      this.effectiveTargetSemantics)
-      : super(kind, element, type);
-}
-
-
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index c156e8f..f46b9fdc 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -5,8 +5,13 @@
 library dart2js.resolution.class_hierarchy;
 
 import '../common.dart';
+import '../common/resolution.dart' show
+    Feature;
 import '../compiler.dart' show
     Compiler;
+import '../core_types.dart' show
+    CoreClasses,
+    CoreTypes;
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../elements/modelx.dart' show
@@ -14,7 +19,8 @@
     ErroneousElementX,
     MixinApplicationElementX,
     SynthesizedConstructorElementX,
-    TypeVariableElementX;
+    TypeVariableElementX,
+    UnnamedMixinApplicationElementX;
 import '../ordered_typeset.dart' show
     OrderedTypeSet,
     OrderedTypeSetBuilder;
@@ -49,7 +55,7 @@
         scope = Scope.buildEnclosingScope(element),
         super(compiler, registry);
 
-  DartType get objectType => compiler.objectClass.rawType;
+  DartType get objectType => compiler.coreTypes.objectType;
 
   void resolveTypeVariableBounds(NodeList node) {
     if (node == null) return;
@@ -190,15 +196,24 @@
 
     if (!element.hasConstructor) {
       Element superMember = element.superclass.localLookup('');
-      if (superMember == null || !superMember.isGenerativeConstructor) {
-        MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
-        Map arguments = {'constructorName': ''};
+      if (superMember == null) {
+        MessageKind kind = MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR;
+        Map arguments = {'className': element.superclass.name};
         // TODO(ahe): Why is this a compile-time error? Or if it is an error,
         // why do we bother to registerThrowNoSuchMethod below?
         reporter.reportErrorMessage(node, kind, arguments);
         superMember = new ErroneousElementX(
             kind, arguments, '', element);
-        registry.registerThrowNoSuchMethod();
+        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+      } else if (!superMember.isGenerativeConstructor) {
+          MessageKind kind = MessageKind.SUPER_CALL_TO_FACTORY;
+          Map arguments = {'className': element.superclass.name};
+          // TODO(ahe): Why is this a compile-time error? Or if it is an error,
+          // why do we bother to registerThrowNoSuchMethod below?
+          reporter.reportErrorMessage(node, kind, arguments);
+          superMember = new ErroneousElementX(
+              kind, arguments, '', element);
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       } else {
         ConstructorElement superConstructor = superMember;
         superConstructor.computeType(resolution);
@@ -211,7 +226,7 @@
       }
       FunctionElement constructor =
           new SynthesizedConstructorElementX.forDefault(superMember, element);
-      if (superMember.isErroneous) {
+      if (superMember.isMalformed) {
         compiler.elementsWithCompileTimeErrors.add(constructor);
       }
       element.setDefaultConstructor(constructor, reporter);
@@ -310,12 +325,12 @@
   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));
+    MixinApplicationElementX mixinApplication =
+        new UnnamedMixinApplicationElementX(
+          "${superName}+${mixinName}",
+          element.compilationUnit,
+          compiler.getNextFreeClassId(),
+          node);
     // Create synthetic type variables for the mixin application.
     List<DartType> typeVariables = <DartType>[];
     int index = 0;
@@ -365,16 +380,17 @@
     return constructor;
   }
 
-  void doApplyMixinTo(MixinApplicationElementX mixinApplication,
-                      DartType supertype,
-                      DartType mixinType) {
+  void doApplyMixinTo(
+      MixinApplicationElementX mixinApplication,
+      DartType supertype,
+      DartType mixinType) {
     Node node = mixinApplication.parseNode(resolution.parsing);
 
     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));
+      assert(invariant(node, supertype.isObject));
     } else {
       mixinApplication.supertype = supertype;
     }
@@ -582,7 +598,7 @@
       allSupertypes.add(compiler, cls.computeType(resolution));
       cls.allSupertypesAndSelf = allSupertypes.toTypeSet();
     } else {
-      assert(identical(cls, compiler.objectClass));
+      assert(cls == compiler.coreClasses.objectClass);
       cls.allSupertypesAndSelf =
           new OrderedTypeSet.singleton(cls.computeType(resolution));
     }
@@ -608,16 +624,17 @@
 
   isBlackListed(DartType type) {
     LibraryElement lib = element.library;
+    CoreTypes coreTypes = compiler.coreTypes;
     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));
+       type == coreTypes.boolType ||
+       type == coreTypes.numType ||
+       type == coreTypes.intType ||
+       type == coreTypes.doubleType ||
+       type == coreTypes.stringType ||
+       type == coreTypes.nullType);
   }
 }
 
@@ -630,6 +647,8 @@
       this.classElement = cls,
       super(compiler);
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   void loadSupertype(ClassElement element, Node from) {
     if (!element.isResolved) {
       compiler.resolver.loadSupertypes(element, from);
@@ -647,8 +666,8 @@
 
   void visitClassNode(ClassNode node) {
     if (node.superclass == null) {
-      if (!identical(classElement, compiler.objectClass)) {
-        loadSupertype(compiler.objectClass, node);
+      if (classElement != coreClasses.objectClass) {
+        loadSupertype(coreClasses.objectClass, node);
       }
     } else {
       node.superclass.accept(this);
@@ -657,7 +676,7 @@
   }
 
   void visitEnum(Enum node) {
-    loadSupertype(compiler.objectClass, node);
+    loadSupertype(coreClasses.objectClass, node);
   }
 
   void visitMixinApplication(MixinApplication node) {
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart
index 125d4bf..a23a490 100644
--- a/pkg/compiler/lib/src/resolution/class_members.dart
+++ b/pkg/compiler/lib/src/resolution/class_members.dart
@@ -314,20 +314,21 @@
   void checkImplementsFunctionWithCall() {
     assert(!cls.isAbstract);
 
-    if (cls.asInstanceOf(compiler.functionClass) == null) return;
+    ClassElement functionClass = compiler.coreClasses.functionClass;
+    if (cls.asInstanceOf(functionClass) == null) return;
     if (cls.lookupMember(Identifiers.call) != null) return;
     // TODO(johnniwinther): Make separate methods for backend exceptions.
     // Avoid warnings on backend implementation classes for closures.
     if (compiler.backend.isBackendLibrary(cls.library)) return;
 
-    reportMessage(compiler.functionClass, MessageKind.UNIMPLEMENTED_METHOD, () {
+    reportMessage(functionClass, MessageKind.UNIMPLEMENTED_METHOD, () {
       reporter.reportWarningMessage(
           cls,
           MessageKind.UNIMPLEMENTED_METHOD_ONE,
           {'class': cls.name,
            'name': Identifiers.call,
            'method': Identifiers.call,
-           'declarer': compiler.functionClass.name});
+           'declarer': functionClass.name});
     });
   }
 
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 76aa6fc..aa70072 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -5,6 +5,8 @@
 library dart2js.resolution.constructors;
 
 import '../common.dart';
+import '../common/resolution.dart' show
+    Feature;
 import '../compiler.dart' show
     Compiler;
 import '../constants/constructors.dart' show
@@ -26,8 +28,8 @@
     Link;
 import '../universe/call_structure.dart' show
     CallStructure;
-import '../universe/selector.dart' show
-    Selector;
+import '../universe/use.dart' show
+    StaticUse;
 
 import 'members.dart' show
     lookupInScope,
@@ -64,7 +66,9 @@
     return node.receiver.asIdentifier().isThis();
   }
 
-  reportDuplicateInitializerError(Element field, Node init, Node existing) {
+  reportDuplicateInitializerError(Element field,
+                                  Node init,
+                                  Spannable existing) {
     reporter.reportError(
         reporter.createMessage(
             init,
@@ -88,7 +92,9 @@
       field.parseNode(visitor.resolution.parsing);
       Expression initializer = field.initializer;
       if (initializer != null) {
-        reportDuplicateInitializerError(field, init, initializer);
+        reportDuplicateInitializerError(field, init,
+            reporter.withCurrentElement(field,
+                () => reporter.spanFromSpannable(initializer)));
       }
     }
     initialized[field] = init;
@@ -125,9 +131,11 @@
     }
     if (target != null) {
       registry.useElement(init, target);
-      registry.registerStaticUse(target);
       checkForDuplicateInitializers(target, init);
     }
+    if (field != null) {
+      registry.registerStaticUse(new StaticUse.fieldInit(field));
+    }
     // Resolve initializing value.
     ResolutionResult result = visitor.visitInStaticContext(
         init.arguments.head,
@@ -146,7 +154,7 @@
                                            {bool isSuperCall}) {
     if (isSuperCall) {
       // Calculate correct lookup target and constructor name.
-      if (identical(constructor.enclosingClass, visitor.compiler.objectClass)) {
+      if (constructor.enclosingClass.isObject) {
         reporter.reportErrorMessage(
             diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
         isValidAsConstant = false;
@@ -157,42 +165,49 @@
     return constructor.enclosingClass.thisType;
   }
 
-  ResolutionResult resolveSuperOrThisForSend(Send call) {
+  ResolutionResult resolveSuperOrThisForSend(Send node) {
     // Resolve the selector and the arguments.
     ArgumentsResult argumentsResult = visitor.inStaticContext(() {
-      visitor.resolveSelector(call, null);
-      return visitor.resolveArguments(call.argumentsNode);
+      // TODO(johnniwinther): Remove this when [SendStructure] is used directly.
+      visitor.resolveSelector(node, null);
+      return visitor.resolveArguments(node.argumentsNode);
     }, inConstantInitializer: isConst);
 
-    bool isSuperCall = Initializers.isSuperConstructorCall(call);
+    bool isSuperCall = Initializers.isSuperConstructorCall(node);
     InterfaceType targetType =
-        getSuperOrThisLookupTarget(call, isSuperCall: isSuperCall);
+        getSuperOrThisLookupTarget(node, isSuperCall: isSuperCall);
     ClassElement lookupTarget = targetType.element;
-    Selector constructorSelector =
-        visitor.getRedirectingThisOrSuperConstructorSelector(call);
-    ConstructorElement calledConstructor = findConstructor(
-        constructor.library, lookupTarget, constructorSelector.name);
+    String constructorName =
+        visitor.getRedirectingThisOrSuperConstructorName(node).text;
+    ConstructorElement foundConstructor = findConstructor(
+        constructor.library, lookupTarget, constructorName);
 
     final bool isImplicitSuperCall = false;
     final String className = lookupTarget.name;
-    verifyThatConstructorMatchesCall(calledConstructor,
-                                     argumentsResult.callStructure,
-                                     isImplicitSuperCall,
-                                     call,
-                                     className,
-                                     constructorSelector);
-    if (calledConstructor != null) {
-      registry.useElement(call, calledConstructor);
-      registry.registerStaticUse(calledConstructor);
+    CallStructure callStructure = argumentsResult.callStructure;
+    ConstructorElement calledConstructor = verifyThatConstructorMatchesCall(
+        node,
+        foundConstructor,
+        callStructure,
+        className,
+        constructorName: constructorName,
+        isThisCall: !isSuperCall,
+        isImplicitSuperCall: false);
+    // TODO(johnniwinther): Remove this when information is pulled from an
+    // [InitializerStructure].
+    registry.useElement(node, calledConstructor);
+    if (!calledConstructor.isError) {
+      registry.registerStaticUse(
+          new StaticUse.superConstructorInvoke(
+              calledConstructor, callStructure));
     }
     if (isConst) {
       if (isValidAsConstant &&
           calledConstructor.isConst &&
           argumentsResult.isValidAsConstant) {
-        CallStructure callStructure = argumentsResult.callStructure;
         List<ConstantExpression> arguments = argumentsResult.constantArguments;
         return new ConstantResult(
-            call,
+            node,
             new ConstructedConstantExpression(
                 targetType,
                 calledConstructor,
@@ -210,36 +225,33 @@
     // If the class has a super resolve the implicit super call.
     ClassElement classElement = constructor.enclosingClass;
     ClassElement superClass = classElement.superclass;
-    if (classElement != visitor.compiler.objectClass) {
+    if (!classElement.isObject) {
       assert(superClass != null);
       assert(superClass.isResolved);
 
       InterfaceType targetType =
           getSuperOrThisLookupTarget(functionNode, isSuperCall: true);
       ClassElement lookupTarget = targetType.element;
-      Selector constructorSelector = new Selector.callDefaultConstructor();
-      ConstructorElement calledConstructor = findConstructor(
-          constructor.library,
-          lookupTarget,
-          constructorSelector.name);
+      ConstructorElement calledConstructor =
+          findConstructor(constructor.library, lookupTarget, '');
 
       final String className = lookupTarget.name;
-      final bool isImplicitSuperCall = true;
-      verifyThatConstructorMatchesCall(calledConstructor,
-                                       CallStructure.NO_ARGS,
-                                       isImplicitSuperCall,
-                                       functionNode,
-                                       className,
-                                       constructorSelector);
-      if (calledConstructor != null) {
-        registry.registerImplicitSuperCall(calledConstructor);
-        registry.registerStaticUse(calledConstructor);
+      CallStructure callStructure = CallStructure.NO_ARGS;
+      ConstructorElement result = verifyThatConstructorMatchesCall(
+          functionNode,
+          calledConstructor,
+          callStructure,
+          className,
+          isImplicitSuperCall: true);
+      if (!result.isError) {
+        registry.registerStaticUse(
+            new StaticUse.constructorInvoke(calledConstructor, callStructure));
       }
 
       if (isConst && isValidAsConstant) {
         return new ConstructedConstantExpression(
             targetType,
-            calledConstructor,
+            result,
             CallStructure.NO_ARGS,
             const <ConstantExpression>[]);
       }
@@ -247,41 +259,65 @@
     return null;
   }
 
-  void verifyThatConstructorMatchesCall(
+  ConstructorElement reportAndCreateErroneousConstructor(
+      Spannable diagnosticNode,
+      String name,
+      MessageKind kind,
+      Map arguments) {
+    isValidAsConstant = false;
+    reporter.reportErrorMessage(
+        diagnosticNode, kind, arguments);
+    return new ErroneousConstructorElementX(
+        kind, arguments, name, visitor.currentClass);
+  }
+
+  /// Checks that [lookedupConstructor] is valid as a target for the super/this
+  /// constructor call using with the given [callStructure].
+  ///
+  /// If [lookedupConstructor] is valid it is returned, otherwise an error is
+  /// reported and an [ErroneousConstructorElement] is returned.
+  ConstructorElement verifyThatConstructorMatchesCall(
+      Node node,
       ConstructorElementX lookedupConstructor,
-      CallStructure call,
-      bool isImplicitSuperCall,
-      Node diagnosticNode,
+      CallStructure callStructure,
       String className,
-      Selector constructorSelector) {
-    if (lookedupConstructor == null ||
-        !lookedupConstructor.isGenerativeConstructor) {
-      String fullConstructorName = Elements.constructorNameForDiagnostics(
-              className,
-              constructorSelector.name);
+      {String constructorName: '',
+       bool isImplicitSuperCall: false,
+       bool isThisCall: false}) {
+    Element result = lookedupConstructor;
+    if (lookedupConstructor == null) {
+      String fullConstructorName =
+          Elements.constructorNameForDiagnostics(className, constructorName);
       MessageKind kind = isImplicitSuperCall
           ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
           : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
-      reporter.reportErrorMessage(
-          diagnosticNode, kind, {'constructorName': fullConstructorName});
-      isValidAsConstant = false;
+      result = reportAndCreateErroneousConstructor(
+          node, constructorName,
+          kind, {'constructorName': fullConstructorName});
+    } else if (!lookedupConstructor.isGenerativeConstructor) {
+      MessageKind kind = isThisCall
+          ? MessageKind.THIS_CALL_TO_FACTORY
+          : MessageKind.SUPER_CALL_TO_FACTORY;
+      result = reportAndCreateErroneousConstructor(
+          node, constructorName, kind, {});
     } else {
       lookedupConstructor.computeType(visitor.resolution);
-      if (!call.signatureApplies(lookedupConstructor.functionSignature)) {
+      if (!callStructure.signatureApplies(
+               lookedupConstructor.functionSignature)) {
         MessageKind kind = isImplicitSuperCall
-                           ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
-                           : MessageKind.NO_MATCHING_CONSTRUCTOR;
-        reporter.reportErrorMessage(diagnosticNode, kind);
-        isValidAsConstant = false;
-      } else if (constructor.isConst
-                 && !lookedupConstructor.isConst) {
+            ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
+            : MessageKind.NO_MATCHING_CONSTRUCTOR;
+        result = reportAndCreateErroneousConstructor(
+            node, constructorName, kind, {});
+      } else if (constructor.isConst && !lookedupConstructor.isConst) {
         MessageKind kind = isImplicitSuperCall
-                           ? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT
-                           : MessageKind.CONST_CALLS_NON_CONST;
-        reporter.reportErrorMessage(diagnosticNode, kind);
-        isValidAsConstant = false;
+            ? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT
+            : MessageKind.CONST_CALLS_NON_CONST;
+        result = reportAndCreateErroneousConstructor(
+            node, constructorName, kind, {});
       }
     }
+    return result;
   }
 
   /**
@@ -453,28 +489,30 @@
       MessageKind kind,
       Map arguments,
       {bool isError: false,
-       bool missingConstructor: false}) {
+       bool missingConstructor: false,
+       List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) {
     if (missingConstructor) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     } else {
-      registry.registerThrowRuntimeError();
+      registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
     }
+    DiagnosticMessage message =
+        reporter.createMessage(diagnosticNode, kind, arguments);
     if (isError || inConstContext) {
-      reporter.reportErrorMessage(
-          diagnosticNode, kind, arguments);
+      reporter.reportError(message, infos);
     } else {
-      reporter.reportWarningMessage(
-          diagnosticNode, kind, arguments);
+      reporter.reportWarning(message, infos);
     }
     ErroneousElement error = new ErroneousConstructorElementX(
         kind, arguments, name, enclosing);
     if (type == null) {
       type = new MalformedType(error, null);
     }
-    return new ConstructorResult(resultKind, error, type);
+    return new ConstructorResult.forError(resultKind, error, type);
   }
 
   ConstructorResult resolveConstructor(
+      PrefixElement prefix,
       InterfaceType type,
       Node diagnosticNode,
       String constructorName) {
@@ -483,37 +521,46 @@
     ConstructorElement constructor = findConstructor(
         resolver.enclosingElement.library, cls, constructorName);
     if (constructor == null) {
-      String fullConstructorName =
-          Elements.constructorNameForDiagnostics(cls.name, constructorName);
+      MessageKind kind = constructorName.isEmpty
+          ? MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR
+          : MessageKind.CANNOT_FIND_CONSTRUCTOR;
       return reportAndCreateErroneousConstructorElement(
           diagnosticNode,
           ConstructorResultKind.UNRESOLVED_CONSTRUCTOR, type,
-          cls, constructorName,
-          MessageKind.CANNOT_FIND_CONSTRUCTOR,
-          {'constructorName': fullConstructorName},
+          cls, constructorName, kind,
+          {'className': cls.name, 'constructorName': constructorName},
           missingConstructor: true);
     } else if (inConstContext && !constructor.isConst) {
       reporter.reportErrorMessage(
           diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
       return new ConstructorResult(
-          ConstructorResultKind.NON_CONSTANT, constructor, type);
+          ConstructorResultKind.NON_CONSTANT, prefix, constructor, type);
     } else {
+      if (cls.isEnumClass && resolver.currentClass != cls) {
+        return reportAndCreateErroneousConstructorElement(
+            diagnosticNode,
+            ConstructorResultKind.INVALID_TYPE, type,
+            cls, constructorName,
+            MessageKind.CANNOT_INSTANTIATE_ENUM,
+            {'enumName': cls.name},
+            isError: true);
+      }
       if (constructor.isGenerativeConstructor) {
         if (cls.isAbstract) {
           reporter.reportWarningMessage(
               diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
-          registry.registerAbstractClassInstantiation();
+          registry.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION);
           return new ConstructorResult(
-              ConstructorResultKind.ABSTRACT, constructor, type);
+              ConstructorResultKind.ABSTRACT, prefix, constructor, type);
         } else {
           return new ConstructorResult(
-              ConstructorResultKind.GENERATIVE, constructor, type);
+              ConstructorResultKind.GENERATIVE, prefix, constructor, type);
         }
       } else {
         assert(invariant(diagnosticNode, constructor.isFactoryConstructor,
             message: "Unexpected constructor $constructor."));
         return new ConstructorResult(
-            ConstructorResultKind.FACTORY, constructor, type);
+            ConstructorResultKind.FACTORY, prefix, constructor, type);
       }
     }
   }
@@ -544,10 +591,11 @@
     // class.
     if (result.type != null) {
       // The unnamed constructor may not exist, so [e] may become unresolved.
-      result = resolveConstructor(result.type, diagnosticNode, '');
+      result = resolveConstructor(
+          result.prefix, result.type, diagnosticNode, '');
     } else {
       Element element = result.element;
-      if (element.isErroneous) {
+      if (element.isMalformed) {
         result = constructorResultForErroneous(diagnosticNode, element);
       } else {
         result = reportAndCreateErroneousConstructorElement(
@@ -568,8 +616,17 @@
         node,
         malformedIsError: inConstContext,
         deferredIsMalformed: false);
-    registry.registerRequiredType(type, resolver.enclosingElement);
-    return constructorResultForType(node, type);
+    Send send = node.typeName.asSend();
+    PrefixElement prefix;
+    if (send != null) {
+      // The type name is of the form [: prefix . identifier :].
+      String name = send.receiver.asIdentifier().source;
+      Element element = lookupInScope(reporter, send, resolver.scope, name);
+      if (element != null && element.isPrefix) {
+        prefix = element;
+      }
+    }
+    return constructorResultForType(node, type, prefix: prefix);
   }
 
   ConstructorResult visitSend(Send node) {
@@ -577,7 +634,7 @@
     assert(invariant(node.receiver, receiver != null,
         message: 'No result returned for $node.receiver.'));
     if (receiver.kind != null) {
-      assert(invariant(node, receiver.element.isErroneous,
+      assert(invariant(node, receiver.element.isMalformed,
           message: "Unexpected prefix result: $receiver."));
       // We have already found an error.
       return receiver;
@@ -590,7 +647,8 @@
 
     if (receiver.type != null) {
       if (receiver.type.isInterfaceType) {
-        return resolveConstructor(receiver.type, name, name.source);
+        return resolveConstructor(
+            receiver.prefix, receiver.type, name, name.source);
       } else {
         // TODO(johnniwinther): Update the message for the different types.
         return reportAndCreateErroneousConstructorElement(
@@ -602,7 +660,8 @@
     } else if (receiver.element.isPrefix) {
       PrefixElement prefix = receiver.element;
       Element member = prefix.lookupLocalMember(name.source);
-      return constructorResultForElement(node, name.source, member);
+      return constructorResultForElement(
+          node, name.source, member, prefix: prefix);
     } else {
       return reporter.internalError(
           node.receiver, 'unexpected receiver $receiver');
@@ -611,10 +670,8 @@
 
   ConstructorResult visitIdentifier(Identifier node) {
     String name = node.source;
-    Element element = resolver.reportLookupErrorIfAny(
-        lookupInScope(reporter, node, resolver.scope, name), node, name);
+    Element element = lookupInScope(reporter, node, resolver.scope, name);
     registry.useElement(node, element);
-    // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
     return constructorResultForElement(node, name, element);
   }
 
@@ -626,7 +683,8 @@
   }
 
   ConstructorResult constructorResultForElement(
-      Node node, String name, Element element) {
+      Node node, String name, Element element,
+      {PrefixElement prefix}) {
     element = Elements.unwrap(element, reporter, node);
     if (element == null) {
       return reportAndCreateErroneousConstructorElement(
@@ -635,14 +693,23 @@
           resolver.enclosingElement, name,
           MessageKind.CANNOT_RESOLVE,
           {'name': name});
-    } else if (element.isErroneous) {
+    } else if (element.isAmbiguous) {
+      AmbiguousElement ambiguous = element;
+      return reportAndCreateErroneousConstructorElement(
+          node,
+          ConstructorResultKind.INVALID_TYPE, null,
+          resolver.enclosingElement, name,
+          ambiguous.messageKind,
+          ambiguous.messageArguments,
+          infos: ambiguous.computeInfos(resolver.enclosingElement, reporter));
+    } else if (element.isMalformed) {
       return constructorResultForErroneous(node, element);
     } else if (element.isClass) {
       ClassElement cls = element;
       cls.computeType(resolution);
-      return constructorResultForType(node, cls.rawType);
+      return constructorResultForType(node, cls.rawType, prefix: prefix);
     } else if (element.isPrefix) {
-      return new ConstructorResult.forElement(element);
+      return new ConstructorResult.forPrefix(element);
     } else if (element.isTypedef) {
       TypedefElement typdef = element;
       typdef.ensureResolved(resolution);
@@ -666,9 +733,9 @@
       error = new ErroneousConstructorElementX(
           MessageKind.NOT_A_TYPE, {'node': node},
           error.name, error);
-      registry.registerThrowRuntimeError();
+      registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
     }
-    return new ConstructorResult(
+    return new ConstructorResult.forError(
         ConstructorResultKind.INVALID_TYPE,
         error,
         new MalformedType(error, null));
@@ -676,13 +743,14 @@
 
   ConstructorResult constructorResultForType(
       Node node,
-      DartType type) {
+      DartType type,
+      {PrefixElement prefix}) {
     String name = type.name;
     if (type.isMalformed) {
-      return new ConstructorResult(
+      return new ConstructorResult.forError(
           ConstructorResultKind.INVALID_TYPE, type.element, type);
     } else if (type.isInterfaceType) {
-      return new ConstructorResult.forType(type);
+      return new ConstructorResult.forType(prefix, type);
     } else if (type.isTypedef) {
       return reportAndCreateErroneousConstructorElement(
           node,
@@ -702,40 +770,88 @@
 
 }
 
+/// The kind of constructor found by the [ConstructorResolver].
 enum ConstructorResultKind {
+  /// A generative or redirecting generative constructor.
   GENERATIVE,
+  /// A factory or redirecting factory constructor.
   FACTORY,
+  /// A generative or redirecting generative constructor on an abstract class.
   ABSTRACT,
+  /// No constructor was found because the type was invalid, for instance
+  /// unresolved, an enum class, a type variable, a typedef or a non-type.
   INVALID_TYPE,
+  /// No constructor of the sought name was found on the class.
   UNRESOLVED_CONSTRUCTOR,
+  /// A non-constant constructor was found for a const constructor invocation.
   NON_CONSTANT,
 }
 
+/// The (partial) result of the resolution of a new expression used in
+/// [ConstructorResolver].
 class ConstructorResult {
+  /// The prefix used to access the constructor. For instance `prefix` in `new
+  /// prefix.Class.constructorName()`.
+  final PrefixElement prefix;
+
+  /// The kind of the found constructor.
   final ConstructorResultKind kind;
+
+  /// The currently found element. Since [ConstructorResult] is used for partial
+  /// results, this might be a [PrefixElement], a [ClassElement], a
+  /// [ConstructorElement] or in the negative cases an [ErroneousElement].
   final Element element;
+
+  /// The type of the new expression. For instance `Foo<String>` in
+  /// `new prefix.Foo<String>.constructorName()`.
   final DartType type;
 
-  ConstructorResult(this.kind, this.element, this.type);
+  /// Creates a fully resolved constructor access where [element] is resolved
+  /// to a constructor and [type] to an interface type.
+  ConstructorResult(this.kind,
+                    this.prefix,
+                    ConstructorElement this.element,
+                    InterfaceType this.type);
 
-  ConstructorResult.forElement(this.element)
-      : kind = null,
+  /// Creates a fully resolved constructor access where [element] is an
+  /// [ErroneousElement].
+  // TODO(johnniwinther): Do we still need the prefix for cases like
+  // `new deferred.Class.unresolvedConstructor()` ?
+  ConstructorResult.forError(
+      this.kind, ErroneousElement this.element, this.type)
+      : prefix = null;
+
+  /// Creates a constructor access that is partially resolved to a prefix. For
+  /// instance `prefix` of `new prefix.Class()`.
+  ConstructorResult.forPrefix(this.element)
+      : prefix = null,
+        kind = null,
         type = null;
 
-  ConstructorResult.forType(this.type)
+  /// Creates a constructor access that is partially resolved to a type. For
+  /// instance `Foo<String>` of `new Foo<String>.constructorName()`.
+  ConstructorResult.forType(this.prefix, this.type)
       : kind = null,
         element = null;
 
+  bool get isDeferred => prefix != null && prefix.isDeferred;
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write('ConstructorResult(');
     if (kind != null) {
       sb.write('kind=$kind,');
+      if (prefix != null) {
+        sb.write('prefix=$prefix,');
+      }
       sb.write('element=$element,');
       sb.write('type=$type');
     } else if (element != null) {
       sb.write('element=$element');
     } else {
+      if (prefix != null) {
+        sb.write('prefix=$prefix,');
+      }
       sb.write('type=$type');
     }
     sb.write(')');
diff --git a/pkg/compiler/lib/src/resolution/enum_creator.dart b/pkg/compiler/lib/src/resolution/enum_creator.dart
index f9913c2..953225b 100644
--- a/pkg/compiler/lib/src/resolution/enum_creator.dart
+++ b/pkg/compiler/lib/src/resolution/enum_creator.dart
@@ -180,6 +180,8 @@
   }
 }
 
+// TODO(johnniwinther): Avoid creating synthesized ASTs for enums when SSA is
+// removed.
 class EnumCreator {
   final DiagnosticReporter reporter;
   final CoreTypes coreTypes;
diff --git a/pkg/compiler/lib/src/resolution/member_impl.dart b/pkg/compiler/lib/src/resolution/member_impl.dart
index 072ddd1..9a2d7b0 100644
--- a/pkg/compiler/lib/src/resolution/member_impl.dart
+++ b/pkg/compiler/lib/src/resolution/member_impl.dart
@@ -227,7 +227,7 @@
 
   bool get isMethod => member.isMethod;
 
-  bool get isErroneous => false;
+  bool get isMalformed => false;
 
   String toString() => '${type.getStringAsDeclared('$name')} synthesized '
                        'from ${inheritedMembers}';
@@ -248,7 +248,7 @@
 
   bool get isMethod => false;
 
-  bool get isErroneous => true;
+  bool get isMalformed => true;
 
   String toString() => "erroneous member '$name' synthesized "
                        "from ${inheritedMembers}";
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 90f5365..da82058 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -7,6 +7,8 @@
 import '../common.dart';
 import '../common/names.dart' show
     Selectors;
+import '../common/resolution.dart' show
+    Feature;
 import '../compiler.dart' show
     Compiler;
 import '../constants/constructors.dart' show
@@ -37,8 +39,10 @@
     CallStructure;
 import '../universe/selector.dart' show
     Selector;
-import '../universe/universe.dart' show
-    UniverseSelector;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
 
 import 'access_semantics.dart';
 import 'class_members.dart' show MembersCreator;
@@ -47,7 +51,8 @@
 
 import 'constructors.dart' show
     ConstructorResolver,
-    ConstructorResult;
+    ConstructorResult,
+    ConstructorResultKind;
 import 'label_scope.dart' show
     StatementScope;
 import 'registry.dart' show
@@ -121,7 +126,7 @@
   /// When visiting the type declaration of the variable in a [ForIn] loop,
   /// the initializer of the variable is implicit and we should not emit an
   /// error when verifying that all final variables are initialized.
-  bool allowFinalWithoutInitializer = false;
+  bool inLoopVariable = false;
 
   /// The nodes for which variable access and mutation must be registered in
   /// order to determine when the static type of variables types is promoted.
@@ -184,6 +189,8 @@
           ? ConstantState.CONSTANT : ConstantState.NON_CONSTANT,
       super(compiler, registry);
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   CoreTypes get coreTypes => compiler.coreTypes;
 
   AsyncMarker get currentAsyncMarker {
@@ -228,14 +235,6 @@
     return element;
   }
 
-  doInCheckContext(action()) {
-    bool wasInCheckContext = inCheckContext;
-    inCheckContext = true;
-    var result = action();
-    inCheckContext = wasInCheckContext;
-    return result;
-  }
-
   doInPromotionScope(Node node, action()) {
     promotionScope = promotionScope.prepend(node);
     var result = action();
@@ -339,7 +338,7 @@
     } else {
       kind = MessageKind.CANNOT_RESOLVE;
     }
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     return reportAndCreateErroneousElement(
         node, name, kind, arguments, isError: inInitializer);
   }
@@ -367,7 +366,7 @@
       if (Elements.isUnresolved(element) && name == 'dynamic') {
         // TODO(johnniwinther): Remove this hack when we can return more complex
         // objects than [Element] from this method.
-        element = compiler.typeClass;
+        element = coreClasses.typeClass;
         // Set the type to be `dynamic` to mark that this is a type literal.
         registry.setType(node, const DynamicType());
       }
@@ -376,8 +375,8 @@
         if (!inInstanceContext) {
           element = reportCannotResolve(node, name);
         }
-      } else if (element.isErroneous) {
-        // Use the erroneous element.
+      } else if (element.isMalformed) {
+        // Use the malformed element.
       } else {
         if ((element.kind.category & allowedCategory) == 0) {
           element = reportAndCreateErroneousElement(
@@ -406,20 +405,19 @@
   TypeResult visitTypeAnnotation(TypeAnnotation node) {
     DartType type = resolveTypeAnnotation(node);
     if (inCheckContext) {
-      registry.registerCheckedModeCheck(type);
+      registry.registerTypeUse(new TypeUse.checkedModeCheck(type));
     }
     return new TypeResult(type);
   }
 
   bool isNamedConstructor(Send node) => node.receiver != null;
 
-  Selector getRedirectingThisOrSuperConstructorSelector(Send node) {
+  Name getRedirectingThisOrSuperConstructorName(Send node) {
     if (isNamedConstructor(node)) {
       String constructorName = node.selector.asIdentifier().source;
-      return new Selector.callConstructor(
-          new Name(constructorName, enclosingElement.library));
+      return new Name(constructorName, enclosingElement.library);
     } else {
-      return new Selector.callDefaultConstructor();
+      return const PublicName('');
     }
   }
 
@@ -432,10 +430,10 @@
     Link<Node> initializers = node.initializers.nodes;
     if (!initializers.isEmpty &&
         Initializers.isConstructorRedirect(initializers.head)) {
-      Selector selector =
-          getRedirectingThisOrSuperConstructorSelector(initializers.head);
+      Name name =
+          getRedirectingThisOrSuperConstructorName(initializers.head);
       final ClassElement classElement = constructor.enclosingClass;
-      return classElement.lookupConstructor(selector.name);
+      return classElement.lookupConstructor(name.text);
     }
     return null;
   }
@@ -492,7 +490,7 @@
     });
     if (inCheckContext) {
       functionParameters.forEachParameter((ParameterElement element) {
-        registry.registerCheckedModeCheck(element.type);
+        registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type));
       });
     }
   }
@@ -506,7 +504,8 @@
     }
     // TODO(sra): We could completely ignore the assert in production mode if we
     // didn't need it to be resolved for type checking.
-    registry.registerAssert(node.hasMessage);
+    registry.registerFeature(
+        node.hasMessage ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT);
     visit(node.condition);
     visit(node.message);
     return const NoneResult();
@@ -638,8 +637,7 @@
     scope = oldScope;
     enclosingElement = previousEnclosingElement;
 
-    registry.registerClosure(function);
-    registry.registerInstantiatedClass(compiler.functionClass);
+    registry.registerStaticUse(new StaticUse.closure(function));
     return const NoneResult();
   }
 
@@ -781,7 +779,7 @@
           node, 'super',
           MessageKind.NO_SUPER_IN_STATIC, {},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return new StaticAccess.invalid(error);
     }
     if (node.isConditional) {
@@ -790,7 +788,7 @@
           node, 'super',
           MessageKind.INVALID_USE_OF_SUPER, {},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return new StaticAccess.invalid(error);
     }
     if (currentClass.supertype == null) {
@@ -801,10 +799,10 @@
           MessageKind.GENERIC,
           {'text': "Object has no superclass"},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return new StaticAccess.invalid(error);
     }
-    registry.registerSuperUse(node);
+    registry.registerSuperUse(reporter.spanFromSpannable(node));
     return null;
   }
 
@@ -816,7 +814,7 @@
           node, 'this',
           MessageKind.NO_THIS_AVAILABLE, const {},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return new StaticAccess.invalid(error);
     }
     return null;
@@ -824,7 +822,7 @@
 
   /// Compute the [AccessSemantics] corresponding to a super access of [target].
   AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) {
-    if (target.isErroneous) {
+    if (target.isMalformed) {
       return new StaticAccess.unresolvedSuper(target);
     } else if (target.isGetter) {
       return new StaticAccess.superGetter(target);
@@ -850,8 +848,8 @@
       Element getter,
       Element setter,
       {bool isIndex: false}) {
-    if (getter.isErroneous) {
-      if (setter.isErroneous) {
+    if (getter.isMalformed) {
+      if (setter.isMalformed) {
         return new StaticAccess.unresolvedSuper(getter);
       } else if (setter.isFunction) {
         assert(invariant(node, setter.name == '[]=',
@@ -865,7 +863,7 @@
             CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter);
       }
     } else if (getter.isField) {
-      if (setter.isErroneous) {
+      if (setter.isMalformed) {
         assert(invariant(node, getter.isFinal,
             message: "Unexpected super setter '$setter' for getter '$getter."));
         return new StaticAccess.superFinalField(getter);
@@ -886,7 +884,7 @@
             CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter);
       }
     } else if (getter.isGetter) {
-      if (setter.isErroneous) {
+      if (setter.isMalformed) {
         return new CompoundAccessSemantics(
             CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
       } else if (setter.isField) {
@@ -901,7 +899,7 @@
     } else {
       assert(invariant(node, getter.isFunction,
           message: "Unexpected super getter '$getter'."));
-      if (setter.isErroneous) {
+      if (setter.isMalformed) {
         if (isIndex) {
           return new CompoundAccessSemantics(
               CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
@@ -953,10 +951,8 @@
       Element target) {
 
     target = target.declaration;
-    if (target.isErroneous) {
+    if (target.isMalformed) {
       // This handles elements with parser errors.
-      // TODO(johnniwinther): Elements with parse error should not set
-      // [isErroneous] to `true`.
       return new StaticAccess.unresolved(target);
     }
     if (target.isStatic) {
@@ -1042,8 +1038,8 @@
       }
       // We still need to register the invocation, because we might
       // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
-      registry.registerDynamicInvocation(new UniverseSelector(selector, null));
-      registry.registerSuperNoSuchMethod();
+      registry.registerDynamicUse(new DynamicUse(selector, null));
+      registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
     }
     return computeSuperAccessSemantics(node, target);
   }
@@ -1109,17 +1105,17 @@
     if (getterError) {
       // We still need to register the invocation, because we might
       // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
-      registry.registerDynamicInvocation(
-          new UniverseSelector(getterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(getterSelector, null));
     }
     if (setterError) {
       // We still need to register the invocation, because we might
       // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
-      registry.registerDynamicInvocation(
-          new UniverseSelector(setterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(setterSelector, null));
     }
     if (getterError || setterError) {
-      registry.registerSuperNoSuchMethod();
+      registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
     }
     return computeCompoundSuperAccessSemantics(
         node, getter, setter, isIndex: isIndex);
@@ -1170,7 +1166,7 @@
       type = resolveTypeAnnotation(typeNode);
       sendStructure = new IsStructure(type);
     }
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
     registry.registerSendStructure(node, sendStructure);
     return const NoneResult();
   }
@@ -1182,7 +1178,7 @@
 
     Node typeNode = node.arguments.head;
     DartType type = resolveTypeAnnotation(typeNode);
-    registry.registerAsCast(type);
+    registry.registerTypeUse(new TypeUse.asCast(type));
     registry.registerSendStructure(node, new AsStructure(type));
     return const NoneResult();
   }
@@ -1219,7 +1215,10 @@
         // TODO(johnniwinther): Add information to [AccessSemantics] about
         // whether it is erroneous.
         if (semantics.kind == AccessKind.SUPER_METHOD) {
-          registry.registerStaticUse(semantics.element.declaration);
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.element.declaration,
+                  selector.callStructure));
         }
         // TODO(23998): Remove this when all information goes through
         // the [SendStructure].
@@ -1228,7 +1227,7 @@
     } else {
       ResolutionResult expressionResult = visitExpression(expression);
       semantics = const DynamicAccess.expression();
-      registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+      registry.registerDynamicUse(new DynamicUse(selector, null));
 
       if (expressionResult.isConstant) {
         bool isValidConstant;
@@ -1391,7 +1390,10 @@
         // TODO(johnniwinther): Add information to [AccessSemantics] about
         // whether it is erroneous.
         if (semantics.kind == AccessKind.SUPER_METHOD) {
-          registry.registerStaticUse(semantics.element.declaration);
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.element.declaration,
+                  selector.callStructure));
         }
         // TODO(23998): Remove this when all information goes through
         // the [SendStructure].
@@ -1401,7 +1403,7 @@
     } else {
       ResolutionResult leftResult = visitExpression(left);
       ResolutionResult rightResult = visitExpression(right);
-      registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+      registry.registerDynamicUse(new DynamicUse(selector, null));
       semantics = const DynamicAccess.expression();
 
       if (leftResult.isConstant && rightResult.isConstant) {
@@ -1536,7 +1538,7 @@
     // TODO(23998): Remove this when all information goes through the
     // [SendStructure].
     registry.setSelector(node, selector);
-    registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+    registry.registerDynamicUse(new DynamicUse(selector, null));
     registry.registerSendStructure(node,
         new InvokeStructure(const DynamicAccess.expression(), selector));
     return const NoneResult();
@@ -1569,8 +1571,8 @@
       AccessSemantics accessSemantics = checkThisAccess(node);
       if (accessSemantics == null) {
         accessSemantics = const DynamicAccess.thisAccess();
-        registry.registerDynamicInvocation(
-            new UniverseSelector(selector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(selector, null));
       }
       registry.registerSendStructure(node,
           new InvokeStructure(accessSemantics, selector));
@@ -1610,22 +1612,24 @@
           superMethod.computeType(resolution);
           if (!callStructure.signatureApplies(
                   superMethod.functionSignature)) {
-            registry.registerThrowNoSuchMethod();
-            registry.registerDynamicInvocation(
-                new UniverseSelector(selector, null));
-            registry.registerSuperNoSuchMethod();
+            registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+            registry.registerDynamicUse(
+                new DynamicUse(selector, null));
+            registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
             isIncompatibleInvoke = true;
           } else {
-            registry.registerStaticInvocation(semantics.element);
+            registry.registerStaticUse(
+                new StaticUse.superInvoke(semantics.element, callStructure));
           }
           break;
         case AccessKind.SUPER_FIELD:
         case AccessKind.SUPER_FINAL_FIELD:
         case AccessKind.SUPER_GETTER:
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.superGet(semantics.element));
           selector = callStructure.callSelector;
-          registry.registerDynamicInvocation(
-              new UniverseSelector(selector, null));
+          registry.registerDynamicUse(
+              new DynamicUse(selector, null));
           break;
         case AccessKind.SUPER_SETTER:
         case AccessKind.UNRESOLVED_SUPER:
@@ -1648,12 +1652,14 @@
         case AccessKind.SUPER_METHOD:
           // TODO(johnniwinther): Method this should be registered as a
           // closurization.
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.superTearOff(semantics.element));
           break;
         case AccessKind.SUPER_FIELD:
         case AccessKind.SUPER_FINAL_FIELD:
         case AccessKind.SUPER_GETTER:
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.superGet(semantics.element));
           break;
         case AccessKind.SUPER_SETTER:
         case AccessKind.UNRESOLVED_SUPER:
@@ -1743,7 +1749,7 @@
       Send node, Name name, ClassElement receiverClass) {
     // TODO(johnniwinther): Share code with [handleStaticInstanceMemberAccess]
     // and [handlePrivateStaticMemberAccess].
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     // TODO(johnniwinther): Produce a different error if [name] is resolves to
     // a constructor.
 
@@ -1769,7 +1775,7 @@
       SendSet node, Name name, ClassElement receiverClass) {
     // TODO(johnniwinther): Share code with [handleStaticInstanceMemberUpdate]
     // and [handlePrivateStaticMemberUpdate].
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     // TODO(johnniwinther): Produce a different error if [name] is resolves to
     // a constructor.
 
@@ -1791,7 +1797,7 @@
   ResolutionResult handleStaticInstanceMemberAccess(
       Send node, Name name, ClassElement receiverClass, Element member) {
 
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     // TODO(johnniwinther): With the simplified [TreeElements] invariant,
     // try to resolve injected elements if [currentClass] is in the patch
     // library of [receiverClass].
@@ -1814,7 +1820,7 @@
   ResolutionResult handleStaticInstanceMemberUpdate(
       SendSet node, Name name, ClassElement receiverClass, Element member) {
 
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     // TODO(johnniwinther): With the simplified [TreeElements] invariant,
     // try to resolve injected elements if [currentClass] is in the patch
     // library of [receiverClass].
@@ -1834,7 +1840,7 @@
   /// but `a` is not defined in the current library.
   ResolutionResult handlePrivateStaticMemberAccess(
       Send node, Name name, ClassElement receiverClass, Element member) {
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     ErroneousElement error = reportAndCreateErroneousElement(
         node, name.text, MessageKind.PRIVATE_ACCESS,
         {'libraryName': member.library.libraryOrScriptName,
@@ -1850,7 +1856,7 @@
   /// `a` but `a` is not defined in the current library.
   ResolutionResult handlePrivateStaticMemberUpdate(
       SendSet node, Name name, ClassElement receiverClass, Element member) {
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     ErroneousElement error = reportAndCreateErroneousElement(
         node, name.text, MessageKind.PRIVATE_ACCESS,
         {'libraryName': member.library.libraryOrScriptName,
@@ -1937,7 +1943,7 @@
           MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
           {'typeVariableName': name},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       semantics = new StaticAccess.invalid(error);
       // TODO(johnniwinther): Clean up registration of elements and selectors
       // for this case.
@@ -1979,7 +1985,7 @@
           MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
           {'typeVariableName': name},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       semantics = new StaticAccess.invalid(error);
     } else {
       ErroneousElement error;
@@ -2001,7 +2007,7 @@
       registry.useElement(node, error);
       // TODO(johnniwinther): Register only on read?
       registry.registerTypeLiteral(node, element.type);
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       semantics = new StaticAccess.typeParameterTypeLiteral(element);
     }
     return handleUpdate(node, name, semantics);
@@ -2080,7 +2086,7 @@
     // the [SendStructure].
     registry.useElement(node, error);
     registry.registerTypeLiteral(node, type);
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
 
     return handleUpdate(node, name, semantics);
   }
@@ -2121,7 +2127,8 @@
         node.isCall ? coreTypes.typeType : type);
     AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant);
     return handleConstantTypeLiteralAccess(
-        node, const PublicName('dynamic'), compiler.typeClass, type, semantics);
+        node, const PublicName('dynamic'),
+        coreClasses.typeClass, type, semantics);
   }
 
   /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or
@@ -2132,7 +2139,8 @@
         new TypeConstantExpression(const DynamicType());
     AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant);
     return handleConstantTypeLiteralUpdate(
-        node, const PublicName('dynamic'), compiler.typeClass, type, semantics);
+        node, const PublicName('dynamic'),
+        coreClasses.typeClass, type, semantics);
   }
 
   /// Handle access to a type literal of a class. Like `C` or
@@ -2207,7 +2215,7 @@
     ResolutionResult result;
     Element member = prefix.lookupLocalMember(name.text);
     if (member == null) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       Element error = reportAndCreateErroneousElement(
           node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER,
           {'libraryName': prefix.name, 'memberName': name});
@@ -2235,7 +2243,7 @@
     ResolutionResult result;
     Element member = prefix.lookupLocalMember(name.text);
     if (member == null) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       Element error = reportAndCreateErroneousElement(
           node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER,
           {'libraryName': prefix.name, 'memberName': name});
@@ -2269,7 +2277,7 @@
           MessageKind.PREFIX_AS_EXPRESSION,
           {'prefix': name},
           isError: true);
-      registry.registerCompileTimeError(error);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return handleErroneousAccess(
           node, name, new StaticAccess.invalid(error));
     }
@@ -2333,14 +2341,14 @@
       CallStructure callStructure =
           resolveArguments(node.argumentsNode).callStructure;
       selector = new Selector.call(name, callStructure);
-      registry.registerDynamicInvocation(
-          new UniverseSelector(selector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(selector, null));
       sendStructure = new InvokeStructure(semantics, selector);
     } else {
       assert(invariant(node, node.isPropertyAccess));
       selector = new Selector.getter(name);
-      registry.registerDynamicGetter(
-          new UniverseSelector(selector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(selector, null));
       sendStructure = new GetStructure(semantics);
     }
     registry.registerSendStructure(node, sendStructure);
@@ -2355,11 +2363,11 @@
       SendSet node, Name name, Element element, AccessSemantics semantics) {
     Selector getterSelector = new Selector.getter(name);
     Selector setterSelector = new Selector.setter(name.setter);
-    registry.registerDynamicSetter(
-        new UniverseSelector(setterSelector, null));
+    registry.registerDynamicUse(
+        new DynamicUse(setterSelector, null));
     if (node.isComplex) {
-      registry.registerDynamicGetter(
-          new UniverseSelector(getterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(getterSelector, null));
     }
 
     // TODO(23998): Remove these when elements are only accessed through the
@@ -2388,7 +2396,7 @@
         name.text,
         MessageKind.THIS_PROPERTY, {},
         isError: true);
-    registry.registerCompileTimeError(error);
+    registry.registerFeature(Feature.COMPILE_TIME_ERROR);
     AccessSemantics accessSemantics = new StaticAccess.invalid(error);
     return handleErroneousAccess(node, name, accessSemantics);
   }
@@ -2479,12 +2487,12 @@
       CallStructure callStructure =
           resolveArguments(node.argumentsNode).callStructure;
       selector = new Selector.call(name, callStructure);
-      registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+      registry.registerDynamicUse(new DynamicUse(selector, null));
       sendStructure = new InvokeStructure(semantics, selector);
     } else {
       assert(invariant(node, node.isPropertyAccess));
       selector = new Selector.getter(name);
-      registry.registerDynamicGetter(new UniverseSelector(selector, null));
+      registry.registerDynamicUse(new DynamicUse(selector, null));
       sendStructure = new GetStructure(semantics);
     }
     // TODO(23998): Remove this when all information goes through
@@ -2507,7 +2515,7 @@
         element.messageKind,
         element.messageArguments,
         infos: element.computeInfos(enclosingElement, reporter));
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
 
     // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
     AccessSemantics semantics = new StaticAccess.unresolved(error);
@@ -2526,7 +2534,7 @@
         element.messageKind,
         element.messageArguments,
         infos: element.computeInfos(enclosingElement, reporter));
-    registry.registerThrowNoSuchMethod();
+    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
 
     // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
     AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
@@ -2541,7 +2549,7 @@
         isError: true);
     // TODO(johnniwinther): Support static instance access as an
     // [AccessSemantics].
-    registry.registerCompileTimeError(error);
+    registry.registerFeature(Feature.COMPILE_TIME_ERROR);
     return new StaticAccess.invalid(error);
   }
 
@@ -2560,9 +2568,9 @@
           LocalFunctionElementX function = semantics.element;
           function.computeType(resolution);
           if (!callStructure.signatureApplies(function.functionSignature)) {
-            registry.registerThrowNoSuchMethod();
-            registry.registerDynamicInvocation(
-                new UniverseSelector(selector, null));
+            registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+            registry.registerDynamicUse(
+                new DynamicUse(selector, null));
             isIncompatibleInvoke = true;
           }
           break;
@@ -2571,8 +2579,8 @@
         case AccessKind.LOCAL_VARIABLE:
         case AccessKind.FINAL_LOCAL_VARIABLE:
           selector = callStructure.callSelector;
-          registry.registerDynamicInvocation(
-              new UniverseSelector(selector, null));
+          registry.registerDynamicUse(
+              new DynamicUse(selector, null));
           break;
         default:
           reporter.internalError(node,
@@ -2681,7 +2689,7 @@
 
     ResolutionResult result = handleUpdate(node, name, semantics);
     if (error != null) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       // TODO(23998): Remove this when all information goes through
       // the [SendStructure].
       registry.useElement(node, error);
@@ -2733,12 +2741,13 @@
           MethodElement method = semantics.element;
           method.computeType(resolution);
           if (!callStructure.signatureApplies(method.functionSignature)) {
-            registry.registerThrowNoSuchMethod();
-            registry.registerDynamicInvocation(
-                new UniverseSelector(selector, null));
+            registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+            registry.registerDynamicUse(
+                new DynamicUse(selector, null));
             isIncompatibleInvoke = true;
           } else {
-            registry.registerStaticUse(semantics.element);
+            registry.registerStaticUse(
+                new StaticUse.staticInvoke(semantics.element, callStructure));
             handleForeignCall(node, semantics.element, callStructure);
             if (method == compiler.identicalFunction &&
                 argumentsResult.isValidAsConstant) {
@@ -2755,15 +2764,16 @@
         case AccessKind.TOPLEVEL_FIELD:
         case AccessKind.FINAL_TOPLEVEL_FIELD:
         case AccessKind.TOPLEVEL_GETTER:
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.staticGet(semantics.element));
           selector = callStructure.callSelector;
-          registry.registerDynamicInvocation(
-              new UniverseSelector(selector, null));
+          registry.registerDynamicUse(
+              new DynamicUse(selector, null));
           break;
         case AccessKind.STATIC_SETTER:
         case AccessKind.TOPLEVEL_SETTER:
         case AccessKind.UNRESOLVED:
-          registry.registerThrowNoSuchMethod();
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
           member = reportAndCreateErroneousElement(
               node.selector, name.text,
               MessageKind.CANNOT_RESOLVE_GETTER, const {});
@@ -2782,10 +2792,8 @@
       switch (semantics.kind) {
         case AccessKind.STATIC_METHOD:
         case AccessKind.TOPLEVEL_METHOD:
-          // TODO(johnniwinther): Method this should be registered as a
-          // closurization.
-          registry.registerStaticUse(semantics.element);
-          registry.registerGetOfStaticFunction(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.staticTearOff(semantics.element));
           break;
         case AccessKind.STATIC_FIELD:
         case AccessKind.FINAL_STATIC_FIELD:
@@ -2793,12 +2801,13 @@
         case AccessKind.TOPLEVEL_FIELD:
         case AccessKind.FINAL_TOPLEVEL_FIELD:
         case AccessKind.TOPLEVEL_GETTER:
-          registry.registerStaticUse(semantics.element);
+          registry.registerStaticUse(
+              new StaticUse.staticGet(semantics.element));
           break;
         case AccessKind.STATIC_SETTER:
         case AccessKind.TOPLEVEL_SETTER:
         case AccessKind.UNRESOLVED:
-          registry.registerThrowNoSuchMethod();
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
           member = reportAndCreateErroneousElement(
               node.selector, name.text,
               MessageKind.CANNOT_RESOLVE_GETTER, const {});
@@ -2836,7 +2845,7 @@
         ErroneousElement error = reportAndCreateErroneousElement(
             node.selector, name.text,
             MessageKind.CANNOT_RESOLVE_SETTER, const {});
-        registry.registerThrowNoSuchMethod();
+        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
 
         if (node.isComplex) {
           // `a++` or `a += b` where `a` has no setter.
@@ -2852,13 +2861,14 @@
               ? new StaticAccess.topLevelGetter(abstractField.getter)
               : new StaticAccess.staticGetter(abstractField.getter);
         }
-        registry.registerStaticUse(abstractField.getter);
+        registry.registerStaticUse(
+            new StaticUse.staticGet(abstractField.getter));
       } else if (node.isComplex) {
         if (abstractField.getter == null) {
           ErroneousElement error = reportAndCreateErroneousElement(
               node.selector, name.text,
               MessageKind.CANNOT_RESOLVE_GETTER, const {});
-          registry.registerThrowNoSuchMethod();
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
           // `a++` or `a += b` where `a` has no getter.
           semantics = new CompoundAccessSemantics(
               element.isTopLevel
@@ -2866,7 +2876,8 @@
                   : CompoundAccessKind.UNRESOLVED_STATIC_GETTER,
               error,
               abstractField.setter);
-          registry.registerStaticUse(abstractField.setter);
+          registry.registerStaticUse(
+              new StaticUse.staticSet(abstractField.setter));
         } else {
           // `a++` or `a += b` where `a` has both a getter and a setter.
           semantics = new CompoundAccessSemantics(
@@ -2875,23 +2886,25 @@
                   : CompoundAccessKind.STATIC_GETTER_SETTER,
               abstractField.getter,
               abstractField.setter);
-          registry.registerStaticUse(abstractField.getter);
-          registry.registerStaticUse(abstractField.setter);
+          registry.registerStaticUse(
+              new StaticUse.staticGet(abstractField.getter));
+          registry.registerStaticUse(
+              new StaticUse.staticSet(abstractField.setter));
         }
       } else {
         // `a = b` where `a` has a setter.
         semantics = element.isTopLevel
             ? new StaticAccess.topLevelSetter(abstractField.setter)
             : new StaticAccess.staticSetter(abstractField.setter);
-        registry.registerStaticUse(abstractField.setter);
+        registry.registerStaticUse(
+            new StaticUse.staticSet(abstractField.setter));
       }
     } else {
       MemberElement member = element;
       // TODO(johnniwinther): Needed to provoke a parsing and with it discovery
       // of parse errors to make [element] erroneous. Fix this!
       member.computeType(resolution);
-      registry.registerStaticUse(member);
-      if (member.isErroneous) {
+      if (member.isMalformed) {
         // [member] has parse errors.
         semantics = new StaticAccess.unresolved(member);
       } else if (member.isFunction) {
@@ -2899,10 +2912,11 @@
         ErroneousElement error = reportAndCreateErroneousElement(
             node.selector, name.text,
             MessageKind.ASSIGNING_METHOD, const {});
-        registry.registerThrowNoSuchMethod();
+        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
         if (node.isComplex) {
           // `a++` or `a += b` where `a` is a function.
-          registry.registerGetOfStaticFunction(element);
+          registry.registerStaticUse(
+              new StaticUse.staticTearOff(element));
         }
         semantics = member.isTopLevel
             ? new StaticAccess.topLevelMethod(member)
@@ -2911,15 +2925,20 @@
         // `a = b`, `a++` or `a += b` where `a` is a field.
         assert(invariant(node, member.isField,
             message: "Unexpected element: $member."));
+        if (node.isComplex) {
+          // `a++` or `a += b` where `a` is a field.
+          registry.registerStaticUse(new StaticUse.staticGet(member));
+        }
         if (member.isFinal || member.isConst) {
           ErroneousElement error = reportAndCreateErroneousElement(
                node.selector, name.text,
                MessageKind.CANNOT_RESOLVE_SETTER, const {});
-          registry.registerThrowNoSuchMethod();
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
           semantics = member.isTopLevel
               ? new StaticAccess.finalTopLevelField(member)
               : new StaticAccess.finalStaticField(member);
         } else {
+          registry.registerStaticUse(new StaticUse.staticSet(member));
           semantics = member.isTopLevel
               ? new StaticAccess.topLevelField(member)
               : new StaticAccess.staticField(member);
@@ -2934,10 +2953,8 @@
     if (element.isAmbiguous) {
       return handleAmbiguousSend(node, name, element);
     }
-    if (element.isErroneous) {
+    if (element.isMalformed) {
       // This handles elements with parser errors.
-      // TODO(johnniwinther): Elements with parse error should not set
-      // [isErroneous] to `true`.
       assert(invariant(node, element is! ErroneousElement,
           message: "Unexpected erroneous element $element."));
       return handleErroneousAccess(node, name,
@@ -2976,10 +2993,8 @@
     if (element.isAmbiguous) {
       return handleAmbiguousUpdate(node, name, element);
     }
-    if (element.isErroneous) {
-      // This handles elements with parser errors.
-      // TODO(johnniwinther): Elements with parse error should not set
-      // [isErroneous] to `true`.
+    if (element.isMalformed) {
+      // This handles elements with parser errors..
       assert(invariant(node, element is! ErroneousElement,
           message: "Unexpected erroneous element $element."));
       return handleUpdate(node, name,new StaticAccess.unresolved(element));
@@ -3000,6 +3015,17 @@
     } else if (element.isTypeVariable) {
       // `T = b`, `T++`, or 'T += b` where 'T' is a type variable.
       return handleTypeVariableTypeLiteralUpdate(node, name, element);
+    } else if (element.isPrefix) {
+      // `p = b` where `p` is a prefix.
+      ErroneousElement error = reportAndCreateErroneousElement(
+           node,
+           name.text,
+           MessageKind.PREFIX_AS_EXPRESSION,
+           {'prefix': name},
+           isError: true);
+      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
+      return handleUpdate(
+          node, name, new StaticAccess.invalid(error));
     } else if (element.isLocal) {
       return handleLocalUpdate(node, name, element);
     } else if (element.isStatic || element.isTopLevel) {
@@ -3132,12 +3158,12 @@
       registry.setSelector(node, setterSelector);
       registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
 
-      registry.registerDynamicInvocation(
-          new UniverseSelector(getterSelector, null));
-      registry.registerDynamicInvocation(
-          new UniverseSelector(setterSelector, null));
-      registry.registerDynamicInvocation(
-          new UniverseSelector(operatorSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(getterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(setterSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(operatorSelector, null));
 
       SendStructure sendStructure = node.isPrefix
           ? new IndexPrefixStructure(semantics, operator)
@@ -3156,8 +3182,8 @@
         // TODO(23998): Remove this when selectors are only accessed
         // through the send structure.
         registry.setSelector(node, setterSelector);
-        registry.registerDynamicInvocation(
-            new UniverseSelector(setterSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(setterSelector, null));
 
         SendStructure sendStructure = new IndexSetStructure(semantics);
         registry.registerSendStructure(node, sendStructure);
@@ -3175,12 +3201,12 @@
         registry.setSelector(node, setterSelector);
         registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
 
-        registry.registerDynamicInvocation(
-            new UniverseSelector(getterSelector, null));
-        registry.registerDynamicInvocation(
-            new UniverseSelector(setterSelector, null));
-        registry.registerDynamicInvocation(
-            new UniverseSelector(operatorSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(getterSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(setterSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(operatorSelector, null));
 
         SendStructure sendStructure =
             new CompoundIndexSetStructure(semantics, operator);
@@ -3197,6 +3223,7 @@
     String operatorText = node.assignmentOperator.source;
     Node index = node.arguments.head;
     visitExpression(index);
+
     AccessSemantics semantics = checkSuperAccess(node);
     if (node.isPrefix || node.isPostfix) {
       // `super[a]++` or `++super[a]`.
@@ -3216,16 +3243,24 @@
         semantics = computeSuperAccessSemanticsForSelectors(
             node, getterSelector, setterSelector, isIndex: true);
 
-        registry.registerStaticInvocation(semantics.getter);
-        registry.registerStaticInvocation(semantics.setter);
+        if (!semantics.getter.isError) {
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.getter, getterSelector.callStructure));
+        }
+        if (!semantics.setter.isError) {
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.setter, setterSelector.callStructure));
+        }
 
         // TODO(23998): Remove these when elements are only accessed
         // through the send structure.
         registry.useElement(node, semantics.setter);
         registry.useElement(node.selector, semantics.getter);
       }
-      registry.registerDynamicInvocation(
-          new UniverseSelector(operatorSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(operatorSelector, null));
 
       SendStructure sendStructure = node.isPrefix
           ? new IndexPrefixStructure(semantics, operator)
@@ -3252,7 +3287,11 @@
         // TODO(23998): Remove this when selectors are only accessed
         // through the send structure.
         registry.setSelector(node, setterSelector);
-        registry.registerStaticInvocation(semantics.setter);
+        if (!semantics.setter.isError) {
+          registry.registerStaticUse(
+              new StaticUse.superInvoke(
+                  semantics.setter, setterSelector.callStructure));
+        }
 
         SendStructure sendStructure = new IndexSetStructure(semantics);
         registry.registerSendStructure(node, sendStructure);
@@ -3267,8 +3306,16 @@
           semantics = computeSuperAccessSemanticsForSelectors(
               node, getterSelector, setterSelector, isIndex: true);
 
-          registry.registerStaticInvocation(semantics.getter);
-          registry.registerStaticInvocation(semantics.setter);
+          if (!semantics.getter.isError) {
+            registry.registerStaticUse(
+                new StaticUse.superInvoke(
+                    semantics.getter, getterSelector.callStructure));
+          }
+          if (!semantics.setter.isError) {
+            registry.registerStaticUse(
+                new StaticUse.superInvoke(
+                    semantics.setter, setterSelector.callStructure));
+          }
 
           // TODO(23998): Remove these when elements are only accessed
           // through the send structure.
@@ -3282,8 +3329,8 @@
         registry.setSelector(node, setterSelector);
         registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
 
-        registry.registerDynamicInvocation(
-            new UniverseSelector(operatorSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(operatorSelector, null));
 
         SendStructure sendStructure =
             new CompoundIndexSetStructure(semantics, operator);
@@ -3303,14 +3350,75 @@
     String operatorText = node.assignmentOperator.source;
     Selector getterSelector = new Selector.getter(name);
     Selector setterSelector = new Selector.setter(name);
+
+    void registerStaticUses(AccessSemantics semantics) {
+      switch (semantics.kind) {
+        case AccessKind.SUPER_METHOD:
+          registry.registerStaticUse(
+              new StaticUse.superTearOff(semantics.element));
+          break;
+        case AccessKind.SUPER_GETTER:
+          registry.registerStaticUse(new StaticUse.superGet(semantics.getter));
+          break;
+        case AccessKind.SUPER_SETTER:
+          registry.registerStaticUse(
+              new StaticUse.superSetterSet(semantics.setter));
+          break;
+        case AccessKind.SUPER_FIELD:
+          registry.registerStaticUse(
+              new StaticUse.superGet(semantics.element));
+          registry.registerStaticUse(
+              new StaticUse.superFieldSet(semantics.element));
+          break;
+        case AccessKind.SUPER_FINAL_FIELD:
+          registry.registerStaticUse(
+              new StaticUse.superGet(semantics.element));
+          break;
+        case AccessKind.COMPOUND:
+          CompoundAccessSemantics compoundSemantics = semantics;
+          switch (compoundSemantics.compoundAccessKind) {
+            case CompoundAccessKind.SUPER_GETTER_FIELD:
+            case CompoundAccessKind.SUPER_FIELD_FIELD:
+              registry.registerStaticUse(
+                  new StaticUse.superGet(semantics.getter));
+              registry.registerStaticUse(
+                  new StaticUse.superFieldSet(semantics.setter));
+              break;
+            case CompoundAccessKind.SUPER_FIELD_SETTER:
+            case CompoundAccessKind.SUPER_GETTER_SETTER:
+              registry.registerStaticUse(
+                  new StaticUse.superGet(semantics.getter));
+              registry.registerStaticUse(
+                  new StaticUse.superSetterSet(semantics.setter));
+              break;
+            case CompoundAccessKind.SUPER_METHOD_SETTER:
+              registry.registerStaticUse(
+                  new StaticUse.superSetterSet(semantics.setter));
+              break;
+            case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
+              registry.registerStaticUse(
+                  new StaticUse.superSetterSet(semantics.setter));
+              break;
+            case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
+              registry.registerStaticUse(
+                  new StaticUse.superGet(semantics.getter));
+              break;
+            default:
+              break;
+          }
+          break;
+        default:
+          break;
+      }
+    }
+
     AccessSemantics semantics = checkSuperAccess(node);
     if (node.isPrefix || node.isPostfix) {
       // `super.a++` or `++super.a`.
       if (semantics == null) {
         semantics = computeSuperAccessSemanticsForSelectors(
             node, getterSelector, setterSelector);
-        registry.registerStaticInvocation(semantics.getter);
-        registry.registerStaticInvocation(semantics.setter);
+        registerStaticUses(semantics);
       }
       return handleUpdate(node, name, semantics);
     } else {
@@ -3321,7 +3429,6 @@
           semantics =
               computeSuperAccessSemanticsForSelector(
                   node, setterSelector, alternateName: name);
-          registry.registerStaticInvocation(semantics.setter);
           switch (semantics.kind) {
             case AccessKind.SUPER_FINAL_FIELD:
               reporter.reportWarningMessage(
@@ -3330,9 +3437,9 @@
                   {'name': name,
                    'superclassName': semantics.setter.enclosingClass.name});
               // TODO(johnniwinther): This shouldn't be needed.
-              registry.registerDynamicInvocation(
-                  new UniverseSelector(setterSelector, null));
-              registry.registerSuperNoSuchMethod();
+              registry.registerDynamicUse(
+                  new DynamicUse(setterSelector, null));
+              registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
               break;
             case AccessKind.SUPER_METHOD:
               reporter.reportWarningMessage(
@@ -3340,12 +3447,19 @@
                   {'name': name,
                    'superclassName': semantics.setter.enclosingClass.name});
               // TODO(johnniwinther): This shouldn't be needed.
-              registry.registerDynamicInvocation(
-                  new UniverseSelector(setterSelector, null));
-              registry.registerSuperNoSuchMethod();
+              registry.registerDynamicUse(
+                  new DynamicUse(setterSelector, null));
+              registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
+              break;
+            case AccessKind.SUPER_FIELD:
+              registry.registerStaticUse(
+                  new StaticUse.superFieldSet(semantics.setter));
+              break;
+            case AccessKind.SUPER_SETTER:
+              registry.registerStaticUse(
+                  new StaticUse.superSetterSet(semantics.setter));
               break;
             default:
-              registry.registerStaticInvocation(semantics.setter);
               break;
           }
         }
@@ -3355,8 +3469,7 @@
         if (semantics == null) {
           semantics = computeSuperAccessSemanticsForSelectors(
               node, getterSelector, setterSelector);
-          registry.registerStaticInvocation(semantics.getter);
-          registry.registerStaticInvocation(semantics.setter);
+          registerStaticUses(semantics);
         }
         return handleUpdate(node, name, semantics);
       }
@@ -3390,14 +3503,14 @@
       registry.useElement(node, semantics.setter);
       registry.useElement(node.selector, semantics.getter);
 
-      registry.registerDynamicInvocation(
-          new UniverseSelector(operatorSelector, null));
+      registry.registerDynamicUse(
+          new DynamicUse(operatorSelector, null));
 
       SendStructure sendStructure = node.isPrefix
           ? new PrefixStructure(semantics, operator)
           : new PostfixStructure(semantics, operator);
       registry.registerSendStructure(node, sendStructure);
-      registry.registerIncDecOperation();
+      registry.registerFeature(Feature.INC_DEC_OPERATION);
     } else {
       Node rhs = node.arguments.head;
       visitExpression(rhs);
@@ -3432,8 +3545,8 @@
         registry.setSelector(node, setterSelector);
         registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
 
-        registry.registerDynamicInvocation(
-            new UniverseSelector(operatorSelector, null));
+        registry.registerDynamicUse(
+            new DynamicUse(operatorSelector, null));
 
         SendStructure sendStructure;
         if (operator.kind == AssignmentOperatorKind.IF_NULL) {
@@ -3468,56 +3581,33 @@
     }
   }
 
-  void registerSend(Selector selector, Element target) {
-    if (target == null || target.isInstanceMember) {
-      if (selector.isGetter) {
-        registry.registerDynamicGetter(
-            new UniverseSelector(selector, null));
-      } else if (selector.isSetter) {
-        registry.registerDynamicSetter(
-            new UniverseSelector(selector, null));
-      } else {
-        registry.registerDynamicInvocation(
-            new UniverseSelector(selector, null));
-      }
-    } else if (Elements.isStaticOrTopLevel(target)) {
-      // Avoid registration of type variables since they are not analyzable but
-      // instead resolved through their enclosing type declaration.
-      if (!target.isTypeVariable) {
-        // [target] might be the implementation element and only declaration
-        // elements may be registered.
-        registry.registerStaticUse(target.declaration);
-      }
-    }
-  }
-
   ConstantResult visitLiteralInt(LiteralInt node) {
-    registry.registerInstantiatedType(coreTypes.intType);
     ConstantExpression constant = new IntConstantExpression(node.value);
+    registry.registerConstantLiteral(constant);
     registry.setConstant(node, constant);
     return new ConstantResult(node, constant);
   }
 
   ConstantResult visitLiteralDouble(LiteralDouble node) {
-    registry.registerInstantiatedType(coreTypes.doubleType);
     ConstantExpression constant = new DoubleConstantExpression(node.value);
+    registry.registerConstantLiteral(constant);
     registry.setConstant(node, constant);
     return new ConstantResult(node, constant);
   }
 
   ConstantResult visitLiteralBool(LiteralBool node) {
-    registry.registerInstantiatedType(coreTypes.boolType);
     ConstantExpression constant = new BoolConstantExpression(node.value);
+    registry.registerConstantLiteral(constant);
     registry.setConstant(node, constant);
     return new ConstantResult(node, constant);
   }
 
   ResolutionResult visitLiteralString(LiteralString node) {
-    registry.registerInstantiatedType(coreTypes.stringType);
     if (node.dartString != null) {
       // [dartString] might be null on parser errors.
       ConstantExpression constant =
           new StringConstantExpression(node.dartString.slowToString());
+      registry.registerConstantLiteral(constant);
       registry.setConstant(node, constant);
       return new ConstantResult(node, constant);
     }
@@ -3525,16 +3615,15 @@
   }
 
   ConstantResult visitLiteralNull(LiteralNull node) {
-    registry.registerInstantiatedType(coreTypes.nullType);
     ConstantExpression constant = new NullConstantExpression();
+    registry.registerConstantLiteral(constant);
     registry.setConstant(node, constant);
     return new ConstantResult(node, constant);
   }
 
   ConstantResult visitLiteralSymbol(LiteralSymbol node) {
-    registry.registerInstantiatedClass(compiler.symbolClass);
-    registry.registerStaticUse(compiler.symbolConstructor.declaration);
     String name = node.slowNameString;
+    // TODO(johnniwinther): Use [registerConstantLiteral] instead.
     registry.registerConstSymbol(name);
     if (!validateSymbol(node, name, reportError: false)) {
       reporter.reportErrorMessage(
@@ -3549,7 +3638,7 @@
   }
 
   ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) {
-    registry.registerInstantiatedType(coreTypes.stringType);
+    registry.registerFeature(Feature.STRING_JUXTAPOSITION);
     ResolutionResult first = visit(node.first);
     ResolutionResult second = visit(node.second);
     if (first.isConstant && second.isConstant) {
@@ -3598,37 +3687,60 @@
   }
 
   ResolutionResult visitYield(Yield node) {
-    compiler.streamClass.ensureResolved(resolution);
-    compiler.iterableClass.ensureResolved(resolution);
+    if (!currentAsyncMarker.isYielding) {
+      reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
+    }
+    if (currentAsyncMarker.isAsync) {
+      coreClasses.streamClass.ensureResolved(resolution);
+    } else {
+      coreClasses.iterableClass.ensureResolved(resolution);
+    }
     visit(node.expression);
     return const NoneResult();
   }
 
   ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) {
-    final isSymbolConstructor = enclosingElement == compiler.symbolConstructor;
     if (!enclosingElement.isFactoryConstructor) {
       reporter.reportErrorMessage(
           node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY);
       reporter.reportHintMessage(
           enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD);
     }
+
     ConstructorElementX constructor = enclosingElement;
     bool isConstConstructor = constructor.isConst;
     bool isValidAsConstant = isConstConstructor;
-    ConstructorElement redirectionTarget = resolveRedirectingFactory(
-        node, inConstContext: isConstConstructor).element;
+    ConstructorResult result = resolveRedirectingFactory(
+        node, inConstContext: isConstConstructor);
+    ConstructorElement redirectionTarget = result.element;
     constructor.immediateRedirectionTarget = redirectionTarget;
 
     Node constructorReference = node.constructorReference;
-    if (constructorReference is Send) {
-      constructor.redirectionDeferredPrefix =
-          compiler.deferredLoadTask.deferredPrefixElement(constructorReference,
-                                                          registry.mapping);
+    if (result.isDeferred) {
+      constructor.redirectionDeferredPrefix = result.prefix;
     }
 
     registry.setRedirectingTargetConstructor(node, redirectionTarget);
+    switch (result.kind) {
+      case ConstructorResultKind.GENERATIVE:
+      case ConstructorResultKind.FACTORY:
+        // Register a post process to check for cycles in the redirection chain
+        // and set the actual generative constructor at the end of the chain.
+        addDeferredAction(constructor, () {
+          compiler.resolver.resolveRedirectionChain(constructor, node);
+        });
+        break;
+      case ConstructorResultKind.ABSTRACT:
+      case ConstructorResultKind.INVALID_TYPE:
+      case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR:
+      case ConstructorResultKind.NON_CONSTANT:
+        isValidAsConstant = false;
+        constructor.setEffectiveTarget(
+            result.element, result.type, isMalformed: true);
+        break;
+    }
     if (Elements.isUnresolved(redirectionTarget)) {
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       return const NoneResult();
     } else {
       if (isConstConstructor &&
@@ -3650,15 +3762,17 @@
     // redirecting constructor.
     ClassElement targetClass = redirectionTarget.enclosingClass;
     InterfaceType type = registry.getType(node);
-    FunctionType targetType = redirectionTarget.computeType(resolution)
-        .subst(type.typeArguments, targetClass.typeVariables);
+    FunctionType targetConstructorType =
+        redirectionTarget.computeType(resolution)
+            .subst(type.typeArguments, targetClass.typeVariables);
     FunctionType constructorType = constructor.computeType(resolution);
-    bool isSubtype = compiler.types.isSubtype(targetType, constructorType);
+    bool isSubtype = compiler.types.isSubtype(
+        targetConstructorType, constructorType);
     if (!isSubtype) {
       reporter.reportWarningMessage(
           node,
           MessageKind.NOT_ASSIGNABLE,
-          {'fromType': targetType, 'toType': constructorType});
+          {'fromType': targetConstructorType, 'toType': constructorType});
       // TODO(johnniwinther): Handle this (potentially) erroneous case.
       isValidAsConstant = false;
     }
@@ -3669,22 +3783,19 @@
     FunctionSignature constructorSignature = constructor.functionSignature;
     if (!targetSignature.isCompatibleWith(constructorSignature)) {
       assert(!isSubtype);
-      registry.registerThrowNoSuchMethod();
+      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
       isValidAsConstant = false;
     }
 
-    // Register a post process to check for cycles in the redirection chain and
-    // set the actual generative constructor at the end of the chain.
-    addDeferredAction(constructor, () {
-      compiler.resolver.resolveRedirectionChain(constructor, node);
-    });
-
-    registry.registerStaticUse(redirectionTarget);
-    // TODO(johnniwinther): Register the effective target type instead.
-    registry.registerInstantiatedClass(
-        redirectionTarget.enclosingClass.declaration);
-    if (isSymbolConstructor) {
-      registry.registerSymbolConstructor();
+    registry.registerStaticUse(
+        new StaticUse.constructorRedirect(redirectionTarget));
+    // TODO(johnniwinther): Register the effective target type as part of the
+    // static use instead.
+    registry.registerTypeUse(new TypeUse.instantiation(
+        redirectionTarget.enclosingClass.thisType
+            .subst(type.typeArguments, targetClass.typeVariables)));
+    if (enclosingElement == compiler.symbolConstructor) {
+      registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
     }
     if (isValidAsConstant) {
       List<String> names = <String>[];
@@ -3714,13 +3825,16 @@
   }
 
   ResolutionResult visitThrow(Throw node) {
-    registry.registerThrowExpression();
+    registry.registerFeature(Feature.THROW_EXPRESSION);
     visit(node.expression);
     return const NoneResult();
   }
 
   ResolutionResult visitAwait(Await node) {
-    compiler.futureClass.ensureResolved(resolution);
+    if (!currentAsyncMarker.isAsync) {
+      reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
+    }
+    coreClasses.futureClass.ensureResolved(resolution);
     visit(node.expression);
     return const NoneResult();
   }
@@ -3758,7 +3872,7 @@
     if (modifiers.isVar && (modifiers.isConst || node.type != null)) {
       reportExtraModifier('var');
     }
-    if (enclosingElement.isFunction) {
+    if (enclosingElement.isFunction || enclosingElement.isConstructor) {
       if (modifiers.isAbstract) {
         reportExtraModifier('abstract');
       }
@@ -3798,12 +3912,8 @@
   }
 
   ResolutionResult visitNewExpression(NewExpression node) {
-    bool isValidAsConstant = true;
-    ConstructorElement constructor = resolveConstructor(node).element;
-    final bool isSymbolConstructor = constructor == compiler.symbolConstructor;
-    final bool isMirrorsUsedConstant =
-        node.isConst && (constructor == compiler.mirrorsUsedConstructor);
-    Selector callSelector = resolveSelector(node.send, constructor);
+    ConstructorResult result = resolveConstructor(node);
+    ConstructorElement constructor = result.element;
     ArgumentsResult argumentsResult;
     if (node.isConst) {
       argumentsResult =
@@ -3811,43 +3921,88 @@
     } else {
       argumentsResult = resolveArguments(node.send.argumentsNode);
     }
+    // TODO(johnniwinther): Avoid the need for a [Selector].
+    Selector selector = resolveSelector(node.send, constructor);
+    CallStructure callStructure = selector.callStructure;
     registry.useElement(node.send, constructor);
-    if (Elements.isUnresolved(constructor)) {
-      return new ResolutionResult.forElement(constructor);
-    }
-    constructor.computeType(resolution);
-    if (!callSelector.applies(constructor, compiler.world)) {
-      registry.registerThrowNoSuchMethod();
+
+    DartType type = result.type;
+    ConstructorAccessKind kind;
+    NewStructure newStructure;
+    bool isInvalid = false;
+    switch (result.kind) {
+      case ConstructorResultKind.GENERATIVE:
+        // Ensure that the signature of [constructor] has been computed.
+        constructor.computeType(resolution);
+        if (!callStructure.signatureApplies(constructor.functionSignature)) {
+          isInvalid = true;
+          kind = ConstructorAccessKind.INCOMPATIBLE;
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+        } else {
+          kind = ConstructorAccessKind.GENERATIVE;
+        }
+        break;
+      case ConstructorResultKind.FACTORY:
+        // Ensure that the signature of [constructor] has been computed.
+        constructor.computeType(resolution);
+        if (!callStructure.signatureApplies(constructor.functionSignature)) {
+          // The effective target might still be valid(!) so the is not an
+          // invalid case in itself. For instance
+          //
+          //    class A {
+          //       factory A() = A.a;
+          //       A.a(a);
+          //    }
+          //    m() => new A(0); // This creates a warning but works at runtime.
+          //
+          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
+        }
+        kind = ConstructorAccessKind.FACTORY;
+        break;
+      case ConstructorResultKind.ABSTRACT:
+        isInvalid = true;
+        kind = ConstructorAccessKind.ABSTRACT;
+        break;
+      case ConstructorResultKind.INVALID_TYPE:
+        isInvalid = true;
+        kind = ConstructorAccessKind.UNRESOLVED_TYPE;
+        break;
+      case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR:
+        // TODO(johnniwinther): Unify codepaths to only have one return.
+        registry.registerNewStructure(node,
+            new NewInvokeStructure(
+                new ConstructorAccessSemantics(
+                    ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR,
+                    constructor,
+                    type),
+                selector));
+        return new ResolutionResult.forElement(constructor);
+      case ConstructorResultKind.NON_CONSTANT:
+        registry.registerNewStructure(node,
+            new NewInvokeStructure(
+                new ConstructorAccessSemantics(
+                    ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR,
+                    constructor,
+                    type),
+                selector));
+        return new ResolutionResult.forElement(constructor);
     }
 
-    // [constructor] might be the implementation element
-    // and only declaration elements may be registered.
-    registry.registerStaticUse(constructor.declaration);
-    ClassElement cls = constructor.enclosingClass;
-    if (cls.isEnumClass && currentClass != cls) {
-      reporter.reportErrorMessage(
-          node,
-          MessageKind.CANNOT_INSTANTIATE_ENUM,
-          {'enumName': cls.name});
-      isValidAsConstant = false;
+    if (!isInvalid) {
+      // [constructor] might be the implementation element
+      // and only declaration elements may be registered.
+      registry.registerStaticUse(
+          new StaticUse.constructorInvoke(
+              constructor.declaration, callStructure));
+      // TODO(johniwinther): Avoid registration of `type` in face of redirecting
+      // factory constructors.
+      registry.registerTypeUse(new TypeUse.instantiation(type));
     }
 
-    InterfaceType type = registry.getType(node);
-    if (node.isConst && type.containsTypeVariables) {
-      reporter.reportErrorMessage(
-          node.send.selector,
-          MessageKind.TYPE_VARIABLE_IN_CONSTANT);
-      isValidAsConstant = false;
-    }
-    // TODO(johniwinther): Avoid registration of `type` in face of redirecting
-    // factory constructors.
-    registry.registerInstantiatedType(type);
-    if (constructor.isGenerativeConstructor && cls.isAbstract) {
-      isValidAsConstant = false;
-    }
+    if (node.isConst) {
+      bool isValidAsConstant = !isInvalid && constructor.isConst;
 
-    if (isSymbolConstructor) {
-      if (node.isConst) {
+      if (constructor == compiler.symbolConstructor) {
         Node argumentNode = node.send.arguments.head;
         ConstantExpression constant =
             compiler.resolver.constantCompiler.compileNode(
@@ -3866,47 +4021,67 @@
             registry.registerConstSymbol(nameString);
           }
         }
-      } else {
-        if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(
-                enclosingElement)) {
-          reporter.reportHintMessage(
-              node.newToken, MessageKind.NON_CONST_BLOAT,
-              {'name': compiler.symbolClass.name});
-        }
+      } else if (constructor == compiler.mirrorsUsedConstructor) {
+        compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping);
       }
-    } else if (isMirrorsUsedConstant) {
-      compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping);
-    }
-    if (node.isConst) {
+
       analyzeConstantDeferred(node);
 
-      // TODO(johnniwinther): Compute this in the [ConstructorResolver].
-      // Check that the constructor is not deferred.
-      Send send = node.send.selector.asSend();
-      if (send != null) {
-        // Of the form `const a.b(...)`.
-        if (compiler.deferredLoadTask.deferredPrefixElement(
-                send, registry.mapping) != null) {
-          // `a` is a deferred prefix.
-          isValidAsConstant = false;
-          // TODO(johnniwinther): Create an [ErroneousConstantExpression] here
-          // when constants are only created during resolution.
-        }
+      if (type.containsTypeVariables) {
+        reporter.reportErrorMessage(
+            node.send.selector,
+            MessageKind.TYPE_VARIABLE_IN_CONSTANT);
+        isValidAsConstant = false;
+        isInvalid = true;
+      }
+
+      if (result.isDeferred) {
+        isValidAsConstant = false;
       }
 
       if (isValidAsConstant &&
-          constructor.isConst &&
-          argumentsResult.isValidAsConstant) {
+          argumentsResult.isValidAsConstant &&
+          // TODO(johnniwinther): Remove this when all constants are computed
+          // in resolution.
+          !constructor.isFromEnvironmentConstructor) {
         CallStructure callStructure = argumentsResult.callStructure;
         List<ConstantExpression> arguments = argumentsResult.constantArguments;
+
         ConstructedConstantExpression constant =
             new ConstructedConstantExpression(
                 type,
                 constructor,
                 callStructure,
                 arguments);
+        registry.registerNewStructure(node,
+            new ConstInvokeStructure(ConstantInvokeKind.CONSTRUCTED, constant));
         return new ConstantResult(node, constant);
+      } else if (isInvalid) {
+        // Known to be non-constant.
+        kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR;
+        registry.registerNewStructure(node,
+            new NewInvokeStructure(
+                new ConstructorAccessSemantics(kind, constructor, type),
+                selector));
+      } else {
+        // Might be valid but we don't know for sure. The compile-time constant
+        // evaluator will compute the actual constant as a deferred action.
+        registry.registerNewStructure(node,
+            new LateConstInvokeStructure(registry.mapping));
       }
+
+    } else {
+      // Not constant.
+      if (constructor == compiler.symbolConstructor &&
+          !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) {
+          reporter.reportHintMessage(
+              node.newToken, MessageKind.NON_CONST_BLOAT,
+              {'name': coreClasses.symbolClass.name});
+      }
+      registry.registerNewStructure(node,
+          new NewInvokeStructure(
+              new ConstructorAccessSemantics(kind, constructor, type),
+              selector));
     }
 
     return const NoneResult();
@@ -3919,9 +4094,9 @@
       ObjectConstantValue objectConstant = key;
       DartType keyType = objectConstant.type;
       ClassElement cls = keyType.element;
-      if (cls == compiler.stringClass) continue;
+      if (cls == coreClasses.stringClass) continue;
       Element equals = cls.lookupMember('==');
-      if (equals.enclosingClass != compiler.objectClass) {
+      if (equals.enclosingClass != coreClasses.objectClass) {
         reporter.reportErrorMessage(
             spannable,
             MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS,
@@ -3994,8 +4169,7 @@
         this, node, malformedIsError: malformedIsError,
         deferredIsMalformed: deferredIsMalformed);
     if (inCheckContext) {
-      registry.registerCheckedModeCheck(type);
-      registry.registerRequiredType(type, enclosingElement);
+      registry.registerTypeUse(new TypeUse.checkedModeCheck(type));
     }
     return type;
   }
@@ -4039,7 +4213,6 @@
         listType,
         isConstant: node.isConst,
         isEmpty: node.elements.isEmpty);
-    registry.registerRequiredType(listType, enclosingElement);
     if (node.isConst) {
       List<ConstantExpression> constantExpressions = <ConstantExpression>[];
       inConstantContext(() {
@@ -4088,8 +4261,10 @@
   }
 
   ResolutionResult visitStringInterpolation(StringInterpolation node) {
-    registry.registerInstantiatedType(coreTypes.stringType);
-    registry.registerStringInterpolation();
+    // TODO(johnniwinther): This should be a consequence of the registration
+    // of [registerStringInterpolation].
+    registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType));
+    registry.registerFeature(Feature.STRING_INTERPOLATION);
     registerImplicitInvocation(Selectors.toString_);
 
     bool isValidAsConstant = true;
@@ -4180,17 +4355,19 @@
   }
 
   registerImplicitInvocation(Selector selector) {
-    registry.registerDynamicInvocation(new UniverseSelector(selector, null));
+    registry.registerDynamicUse(new DynamicUse(selector, null));
   }
 
   ResolutionResult visitAsyncForIn(AsyncForIn node) {
-    registry.registerAsyncForIn(node);
-    registry.setCurrentSelector(node, Selectors.current);
-    registry.registerDynamicGetter(
-        new UniverseSelector(Selectors.current, null));
-    registry.setMoveNextSelector(node, Selectors.moveNext);
-    registry.registerDynamicInvocation(
-        new UniverseSelector(Selectors.moveNext, null));
+    if (!currentAsyncMarker.isAsync) {
+      reporter.reportErrorMessage(
+          node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN);
+    }
+    registry.registerFeature(Feature.ASYNC_FOR_IN);
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.current, null));
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.moveNext, null));
 
     visit(node.expression);
 
@@ -4201,16 +4378,13 @@
   }
 
   ResolutionResult visitSyncForIn(SyncForIn node) {
-    registry.registerSyncForIn(node);
-    registry.setIteratorSelector(node, Selectors.iterator);
-    registry.registerDynamicGetter(
-        new UniverseSelector(Selectors.iterator, null));
-    registry.setCurrentSelector(node, Selectors.current);
-    registry.registerDynamicGetter(
-        new UniverseSelector(Selectors.current, null));
-    registry.setMoveNextSelector(node, Selectors.moveNext);
-    registry.registerDynamicInvocation(
-        new UniverseSelector(Selectors.moveNext, null));
+    registry.registerFeature(Feature.SYNC_FOR_IN);
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.iterator, null));
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.current, null));
+    registry.registerDynamicUse(
+        new DynamicUse(Selectors.moveNext, null));
 
     visit(node.expression);
 
@@ -4226,10 +4400,10 @@
       Scope blockScope) {
     LibraryElement library = enclosingElement.library;
 
-    bool oldAllowFinalWithoutInitializer = allowFinalWithoutInitializer;
-    allowFinalWithoutInitializer = true;
+    bool oldAllowFinalWithoutInitializer = inLoopVariable;
+    inLoopVariable = true;
     visitIn(declaration, blockScope);
-    allowFinalWithoutInitializer = oldAllowFinalWithoutInitializer;
+    inLoopVariable = oldAllowFinalWithoutInitializer;
 
     Send send = declaration.asSend();
     VariableDefinitions variableDefinitions =
@@ -4272,7 +4446,13 @@
     }
     if (loopVariableSelector != null) {
       registry.setSelector(declaration, loopVariableSelector);
-      registerSend(loopVariableSelector, loopVariable);
+      if (loopVariable == null || loopVariable.isInstanceMember) {
+        registry.registerDynamicUse(
+            new DynamicUse(loopVariableSelector, null));
+      } else if (loopVariable.isStatic || loopVariable.isTopLevel) {
+        registry.registerStaticUse(
+            new StaticUse.staticSet(loopVariable.declaration));
+      }
     } else {
       // The selector may only be null if we reported an error.
       assert(invariant(declaration, compiler.compilationFailed));
@@ -4363,9 +4543,8 @@
         mapType,
         isConstant: node.isConst,
         isEmpty: node.entries.isEmpty);
-    registry.registerRequiredType(mapType, enclosingElement);
-    if (node.isConst) {
 
+    if (node.isConst) {
       List<ConstantExpression> keyExpressions = <ConstantExpression>[];
       List<ConstantExpression> valueExpressions = <ConstantExpression>[];
       inConstantContext(() {
@@ -4407,12 +4586,12 @@
   }
 
   DartType typeOfConstant(ConstantValue constant) {
-    if (constant.isInt) return compiler.intClass.rawType;
-    if (constant.isBool) return compiler.boolClass.rawType;
-    if (constant.isDouble) return compiler.doubleClass.rawType;
-    if (constant.isString) return compiler.stringClass.rawType;
-    if (constant.isNull) return compiler.nullClass.rawType;
-    if (constant.isFunction) return compiler.functionClass.rawType;
+    if (constant.isInt) return coreTypes.intType;
+    if (constant.isBool) return coreTypes.boolType;
+    if (constant.isDouble) return coreTypes.doubleType;
+    if (constant.isString) return coreTypes.stringType;
+    if (constant.isNull) return coreTypes.nullType;
+    if (constant.isFunction) return coreTypes.functionType;
     assert(constant.isObject);
     ObjectConstantValue objectConstant = constant;
     return objectConstant.type;
@@ -4421,7 +4600,7 @@
   bool overridesEquals(DartType type) {
     ClassElement cls = type.element;
     Element equals = cls.lookupMember('==');
-    return equals.enclosingClass != compiler.objectClass;
+    return equals.enclosingClass != coreClasses.objectClass;
   }
 
   void checkCaseExpressions(SwitchStatement node) {
@@ -4446,7 +4625,7 @@
             message: 'No constant computed for $node'));
 
         ConstantValue value = compiler.constants.getConstantValue(constant);
-        DartType caseType = typeOfConstant(value);
+        DartType caseType = value.getType(coreTypes);//typeOfConstant(value);
 
         if (firstCaseType == null) {
           firstCase = caseMatch;
@@ -4454,12 +4633,12 @@
 
           // We only report the bad type on the first class element. All others
           // get a "type differs" error.
-          if (caseType.element == compiler.doubleClass) {
+          if (caseType == coreTypes.doubleType) {
             reporter.reportErrorMessage(
                 node,
                 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
                 {'type': "double"});
-          } else if (caseType.element == compiler.functionClass) {
+          } else if (caseType == coreTypes.functionType) {
             reporter.reportErrorMessage(
                 node, MessageKind.SWITCH_CASE_FORBIDDEN,
                 {'type': "Function"});
@@ -4575,7 +4754,7 @@
     });
     // TODO(15575): We should warn if we can detect a fall through
     // error.
-    registry.registerFallThroughError();
+    registry.registerFeature(Feature.FALL_THROUGH_ERROR);
     return const NoneResult();
   }
 
@@ -4606,7 +4785,7 @@
   }
 
   ResolutionResult visitCatchBlock(CatchBlock node) {
-    registry.registerCatchStatement();
+    registry.registerFeature(Feature.CATCH_STATEMENT);
     // Check that if catch part is present, then
     // it has one or two formal parameters.
     VariableDefinitions exceptionDefinition;
@@ -4628,7 +4807,7 @@
                   extra, MessageKind.EXTRA_CATCH_DECLARATION);
             }
           }
-          registry.registerStackTraceInCatch();
+          registry.registerFeature(Feature.STACK_TRACE_IN_CATCH);
         }
       }
 
@@ -4659,26 +4838,29 @@
     }
 
     Scope blockScope = new BlockScope(scope);
-    doInCheckContext(() => visitIn(node.type, blockScope));
+    TypeResult exceptionTypeResult = visitIn(node.type, blockScope);
     visitIn(node.formals, blockScope);
     var oldInCatchBlock = inCatchBlock;
     inCatchBlock = true;
     visitIn(node.block, blockScope);
     inCatchBlock = oldInCatchBlock;
 
-    if (node.type != null && exceptionDefinition != null) {
-      DartType exceptionType = registry.getType(node.type);
-      Node exceptionVariable = exceptionDefinition.definitions.nodes.head;
-      VariableElementX exceptionElement =
-          registry.getDefinition(exceptionVariable);
-      exceptionElement.variables.type = exceptionType;
+    if (exceptionTypeResult != null) {
+      DartType exceptionType = exceptionTypeResult.type;
+      if (exceptionDefinition != null) {
+        Node exceptionVariable = exceptionDefinition.definitions.nodes.head;
+        VariableElementX exceptionElement =
+            registry.getDefinition(exceptionVariable);
+        exceptionElement.variables.type = exceptionType;
+      }
+      registry.registerTypeUse(new TypeUse.catchType(exceptionType));
     }
     if (stackTraceDefinition != null) {
       Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head;
       VariableElementX stackTraceElement =
           registry.getDefinition(stackTraceVariable);
-      registry.registerInstantiatedClass(compiler.stackTraceClass);
-      stackTraceElement.variables.type = compiler.stackTraceClass.rawType;
+      InterfaceType stackTraceType = coreTypes.stackTraceType;
+      stackTraceElement.variables.type = stackTraceType;
     }
     return const NoneResult();
   }
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index b93c6e9..b3c7686 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -19,6 +19,7 @@
     Compiler;
 import '../constants/expressions.dart';
 import '../dart_types.dart';
+import '../diagnostics/source_span.dart';
 import '../enqueue.dart' show
     ResolutionEnqueuer;
 import '../elements/elements.dart';
@@ -29,9 +30,16 @@
     CallStructure;
 import '../universe/selector.dart' show
     Selector;
-import '../universe/universe.dart' show
-    UniverseSelector;
-import '../world.dart' show World;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
+import '../universe/world_impact.dart' show
+    WorldImpactBuilder;
+import '../util/enumset.dart' show
+    EnumSet;
+import '../world.dart' show
+    World;
 
 import 'send_structure.dart';
 
@@ -40,165 +48,15 @@
 import 'tree_elements.dart' show
     TreeElementMapping;
 
-// TODO(johnniwinther): Remove this.
-class EagerRegistry extends Registry {
-  final Compiler compiler;
-  final TreeElementMapping mapping;
-
-  EagerRegistry(this.compiler, this.mapping);
-
-  ResolutionEnqueuer get world => compiler.enqueuer.resolution;
-
-  @override
-  bool get isForResolution => true;
-
-  @override
-  void registerDynamicGetter(UniverseSelector selector) {
-    world.registerDynamicGetter(selector);
-  }
-
-  @override
-  void registerDynamicInvocation(UniverseSelector selector) {
-    world.registerDynamicInvocation(selector);
-  }
-
-  @override
-  void registerDynamicSetter(UniverseSelector selector) {
-    world.registerDynamicSetter(selector);
-  }
-
-  @override
-  void registerGetOfStaticFunction(FunctionElement element) {
-    world.registerGetOfStaticFunction(element);
-  }
-
-  @override
-  void registerInstantiation(InterfaceType type) {
-    world.registerInstantiatedType(type);
-  }
-
-  @override
-  void registerStaticInvocation(Element element) {
-    registerDependency(element);
-    world.registerStaticUse(element);
-  }
-
-  String toString() => 'EagerRegistry for ${mapping.analyzedElement}';
-}
-
-class _ResolutionWorldImpact implements ResolutionImpact {
-  final Registry registry;
-  // TODO(johnniwinther): Do we benefit from lazy initialization of the
-  // [Setlet]s?
-  Setlet<UniverseSelector> _dynamicInvocations;
-  Setlet<UniverseSelector> _dynamicGetters;
-  Setlet<UniverseSelector> _dynamicSetters;
-  Setlet<InterfaceType> _instantiatedTypes;
-  Setlet<Element> _staticUses;
-  Setlet<DartType> _isChecks;
-  Setlet<DartType> _asCasts;
-  Setlet<DartType> _checkedModeChecks;
-  Setlet<MethodElement> _closurizedFunctions;
-  Setlet<LocalFunctionElement> _closures;
-  Setlet<Feature> _features;
-  // TODO(johnniwinther): This seems to be a union of other sets.
-  Setlet<DartType> _requiredTypes;
+class _ResolutionWorldImpact extends ResolutionImpact with WorldImpactBuilder {
+  final String name;
+  EnumSet<Feature> _features;
   Setlet<MapLiteralUse> _mapLiterals;
   Setlet<ListLiteralUse> _listLiterals;
-  Setlet<DartType> _typeLiterals;
   Setlet<String> _constSymbolNames;
+  Setlet<ConstantExpression> _constantLiterals;
 
-  _ResolutionWorldImpact(Compiler compiler, TreeElementMapping mapping)
-      : this.registry = new EagerRegistry(compiler, mapping);
-
-  void registerDependency(Element element) {
-    assert(element != null);
-    registry.registerDependency(element);
-  }
-
-  void registerDynamicGetter(UniverseSelector selector) {
-    assert(selector != null);
-    if (_dynamicGetters == null) {
-      _dynamicGetters = new Setlet<UniverseSelector>();
-    }
-    _dynamicGetters.add(selector);
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicGetters {
-    return _dynamicGetters != null
-        ? _dynamicGetters : const <UniverseSelector>[];
-  }
-
-  void registerDynamicInvocation(UniverseSelector selector) {
-    assert(selector != null);
-    if (_dynamicInvocations == null) {
-      _dynamicInvocations = new Setlet<UniverseSelector>();
-    }
-    _dynamicInvocations.add(selector);
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicInvocations {
-    return _dynamicInvocations != null
-        ? _dynamicInvocations : const <UniverseSelector>[];
-  }
-
-  void registerDynamicSetter(UniverseSelector selector) {
-    assert(selector != null);
-    if (_dynamicSetters == null) {
-      _dynamicSetters = new Setlet<UniverseSelector>();
-    }
-    _dynamicSetters.add(selector);
-  }
-
-  @override
-  Iterable<UniverseSelector> get dynamicSetters {
-    return _dynamicSetters != null
-        ? _dynamicSetters : const <UniverseSelector>[];
-  }
-
-  void registerInstantiatedType(InterfaceType type) {
-    assert(type != null);
-    if (_instantiatedTypes == null) {
-      _instantiatedTypes = new Setlet<InterfaceType>();
-    }
-    _instantiatedTypes.add(type);
-  }
-
-  @override
-  Iterable<InterfaceType> get instantiatedTypes {
-    return _instantiatedTypes != null
-        ? _instantiatedTypes : const <InterfaceType>[];
-  }
-
-  void registerTypeLiteral(DartType type) {
-    assert(type != null);
-    if (_typeLiterals == null) {
-      _typeLiterals = new Setlet<DartType>();
-    }
-    _typeLiterals.add(type);
-  }
-
-  @override
-  Iterable<DartType> get typeLiterals {
-    return _typeLiterals != null
-        ? _typeLiterals : const <DartType>[];
-  }
-
-  void registerRequiredType(DartType type) {
-    assert(type != null);
-    if (_requiredTypes == null) {
-      _requiredTypes = new Setlet<DartType>();
-    }
-    _requiredTypes.add(type);
-  }
-
-  @override
-  Iterable<DartType> get requiredTypes {
-    return _requiredTypes != null
-        ? _requiredTypes : const <DartType>[];
-  }
+  _ResolutionWorldImpact(this.name);
 
   void registerMapLiteral(MapLiteralUse mapLiteralUse) {
     assert(mapLiteralUse != null);
@@ -228,85 +86,6 @@
         ? _listLiterals : const <ListLiteralUse>[];
   }
 
-  void registerStaticUse(Element element) {
-    assert(element != null);
-    if (_staticUses == null) {
-      _staticUses = new Setlet<Element>();
-    }
-    _staticUses.add(element);
-  }
-
-  @override
-  Iterable<Element> get staticUses {
-    return _staticUses != null ? _staticUses : const <Element>[];
-  }
-
-  void registerIsCheck(DartType type) {
-    assert(type != null);
-    if (_isChecks == null) {
-      _isChecks = new Setlet<DartType>();
-    }
-    _isChecks.add(type);
-  }
-
-  @override
-  Iterable<DartType> get isChecks {
-    return _isChecks != null
-        ? _isChecks : const <DartType>[];
-  }
-
-  void registerAsCast(DartType type) {
-    if (_asCasts == null) {
-      _asCasts = new Setlet<DartType>();
-    }
-    _asCasts.add(type);
-  }
-
-  @override
-  Iterable<DartType> get asCasts {
-    return _asCasts != null
-        ? _asCasts : const <DartType>[];
-  }
-
-  void registerCheckedModeCheckedType(DartType type) {
-    if (_checkedModeChecks == null) {
-      _checkedModeChecks = new Setlet<DartType>();
-    }
-    _checkedModeChecks.add(type);
-  }
-
-  @override
-  Iterable<DartType> get checkedModeChecks {
-    return _checkedModeChecks != null
-        ? _checkedModeChecks : const <DartType>[];
-  }
-
-  void registerClosurizedFunction(MethodElement element) {
-    if (_closurizedFunctions == null) {
-      _closurizedFunctions = new Setlet<MethodElement>();
-    }
-    _closurizedFunctions.add(element);
-  }
-
-  @override
-  Iterable<MethodElement> get closurizedFunctions {
-    return _closurizedFunctions != null
-        ? _closurizedFunctions : const <MethodElement>[];
-  }
-
-  void registerClosure(LocalFunctionElement element) {
-    if (_closures == null) {
-      _closures = new Setlet<LocalFunctionElement>();
-    }
-    _closures.add(element);
-  }
-
-  @override
-  Iterable<LocalFunctionElement> get closures {
-    return _closures != null
-        ? _closures : const <LocalFunctionElement>[];
-  }
-
   void registerConstSymbolName(String name) {
     if (_constSymbolNames == null) {
       _constSymbolNames = new Setlet<String>();
@@ -322,17 +101,30 @@
 
   void registerFeature(Feature feature) {
     if (_features == null) {
-      _features = new Setlet<Feature>();
+      _features = new EnumSet<Feature>();
     }
     _features.add(feature);
   }
 
   @override
   Iterable<Feature> get features {
-    return _features != null ? _features : const <Feature>[];
+    return _features != null
+        ? _features.iterable(Feature.values) : const <Feature>[];
   }
 
-  String toString() => '$registry';
+  void registerConstantLiteral(ConstantExpression constant) {
+    if (_constantLiterals == null) {
+      _constantLiterals = new Setlet<ConstantExpression>();
+    }
+    _constantLiterals.add(constant);
+  }
+
+  Iterable<ConstantExpression> get constantLiterals {
+    return _constantLiterals != null
+        ? _constantLiterals : const <ConstantExpression>[];
+  }
+
+  String toString() => '_ResolutionWorldImpact($name)';
 }
 
 /// [ResolutionRegistry] collects all resolution information. It stores node
@@ -347,7 +139,8 @@
   ResolutionRegistry(Compiler compiler, TreeElementMapping mapping)
       : this.compiler = compiler,
         this.mapping = mapping,
-        this.worldImpact = new _ResolutionWorldImpact(compiler, mapping);
+        this.worldImpact = new _ResolutionWorldImpact(
+            mapping.analyzedElement.toString());
 
   bool get isForResolution => true;
 
@@ -407,8 +200,6 @@
     mapping.setSelector(node, selector);
   }
 
-  Selector getSelector(Node node) => mapping.getSelector(node);
-
   void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
     mapping.setGetterSelectorInComplexSendSet(node, selector);
   }
@@ -417,18 +208,6 @@
     mapping.setOperatorSelectorInComplexSendSet(node, selector);
   }
 
-  void setIteratorSelector(ForIn node, Selector selector) {
-    mapping.setIteratorSelector(node, selector);
-  }
-
-  void setMoveNextSelector(ForIn node, Selector selector) {
-    mapping.setMoveNextSelector(node, selector);
-  }
-
-  void setCurrentSelector(ForIn node, Selector selector) {
-    mapping.setCurrentSelector(node, selector);
-  }
-
   //////////////////////////////////////////////////////////////////////////////
   //  Node-to-Type mapping functionality.
   //////////////////////////////////////////////////////////////////////////////
@@ -527,83 +306,26 @@
   //  Various Backend/Enqueuer/World registration.
   //////////////////////////////////////////////////////////////////////////////
 
-  void registerStaticUse(Element element) {
-    worldImpact.registerStaticUse(element);
-  }
-
-  void registerImplicitSuperCall(FunctionElement superConstructor) {
-    registerDependency(superConstructor);
-  }
-
-  // TODO(johnniwinther): Remove this.
-  // Use [registerInstantiatedType] of `rawType` instead.
-  @deprecated
-  void registerInstantiatedClass(ClassElement element) {
-    element.ensureResolved(compiler.resolution);
-    registerInstantiatedType(element.rawType);
-  }
-
-  void registerLazyField() {
-    worldImpact.registerFeature(Feature.LAZY_FIELD);
+  void registerStaticUse(StaticUse staticUse) {
+    worldImpact.registerStaticUse(staticUse);
   }
 
   void registerMetadataConstant(MetadataAnnotation metadata) {
     backend.registerMetadataConstant(metadata, metadata.annotatedElement, this);
   }
 
-  void registerThrowRuntimeError() {
-    worldImpact.registerFeature(Feature.THROW_RUNTIME_ERROR);
+  /// Register the use of a type.
+  void registerTypeUse(TypeUse typeUse) {
+    worldImpact.registerTypeUse(typeUse);
   }
 
-  void registerCompileTimeError(ErroneousElement error) {
-    worldImpact.registerFeature(Feature.COMPILE_TIME_ERROR);
-  }
-
-  void registerTypeVariableBoundCheck() {
-    worldImpact.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
-  }
-
-  void registerThrowNoSuchMethod() {
-    worldImpact.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-  }
-
-  /// Register a checked mode check against [type].
-  void registerCheckedModeCheck(DartType type) {
-    worldImpact.registerCheckedModeCheckedType(type);
-    mapping.addRequiredType(type);
-  }
-
-  /// Register an is-test or is-not-test of [type].
-  void registerIsCheck(DartType type) {
-    worldImpact.registerIsCheck(type);
-    mapping.addRequiredType(type);
-  }
-
-  /// Register an as-cast of [type].
-  void registerAsCast(DartType type) {
-    worldImpact.registerAsCast(type);
-    mapping.addRequiredType(type);
-  }
-
-  void registerClosure(LocalFunctionElement element) {
-    worldImpact.registerClosure(element);
-  }
-
-  void registerSuperUse(Node node) {
-    mapping.addSuperUse(node);
-  }
-
-  void registerDynamicInvocation(UniverseSelector selector) {
-    worldImpact.registerDynamicInvocation(selector);
-  }
-
-  void registerSuperNoSuchMethod() {
-    worldImpact.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
+  void registerSuperUse(SourceSpan span) {
+    mapping.addSuperUse(span);
   }
 
   void registerTypeLiteral(Send node, DartType type) {
     mapping.setType(node, type);
-    worldImpact.registerTypeLiteral(type);
+    worldImpact.registerTypeUse(new TypeUse.typeLiteral(type));
   }
 
   void registerLiteralList(Node node,
@@ -633,60 +355,20 @@
         new ForeignResolutionResolver(visitor, this));
   }
 
-  void registerGetOfStaticFunction(FunctionElement element) {
-    worldImpact.registerClosurizedFunction(element);
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    worldImpact.registerDynamicUse(dynamicUse);
   }
 
-  void registerDynamicGetter(UniverseSelector selector) {
-    assert(selector.selector.isGetter);
-    worldImpact.registerDynamicGetter(selector);
-  }
-
-  void registerDynamicSetter(UniverseSelector selector) {
-    assert(selector.selector.isSetter);
-    worldImpact.registerDynamicSetter(selector);
+  void registerFeature(Feature feature) {
+    worldImpact.registerFeature(feature);
   }
 
   void registerConstSymbol(String name) {
     worldImpact.registerConstSymbolName(name);
   }
 
-  void registerSymbolConstructor() {
-    worldImpact.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
-  }
-
-  void registerInstantiatedType(InterfaceType type) {
-    worldImpact.registerInstantiatedType(type);
-    mapping.addRequiredType(type);
-  }
-
-  void registerAbstractClassInstantiation() {
-    worldImpact.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION);
-  }
-
-  void registerRequiredType(DartType type, Element enclosingElement) {
-    worldImpact.registerRequiredType(type);
-    mapping.addRequiredType(type);
-  }
-
-  void registerStringInterpolation() {
-    worldImpact.registerFeature(Feature.STRING_INTERPOLATION);
-  }
-
-  void registerFallThroughError() {
-    worldImpact.registerFeature(Feature.FALL_THROUGH_ERROR);
-  }
-
-  void registerCatchStatement() {
-    worldImpact.registerFeature(Feature.CATCH_STATEMENT);
-  }
-
-  void registerStackTraceInCatch() {
-    worldImpact.registerFeature(Feature.STACK_TRACE_IN_CATCH);
-  }
-
-  void registerSyncForIn(Node node) {
-    worldImpact.registerFeature(Feature.SYNC_FOR_IN);
+  void registerConstantLiteral(ConstantExpression constant) {
+    worldImpact.registerConstantLiteral(constant);
   }
 
   ClassElement defaultSuperclass(ClassElement element) {
@@ -698,60 +380,24 @@
     universe.registerMixinUse(mixinApplication, mixin);
   }
 
-  void registerThrowExpression() {
-    worldImpact.registerFeature(Feature.THROW_EXPRESSION);
-  }
-
-  void registerStaticInvocation(Element element) {
-    // TODO(johnniwinther): Increase precision of [registerStaticUse] and
-    // [registerDependency].
-    if (element == null) return;
-    registerStaticUse(element);
-  }
-
   void registerInstantiation(InterfaceType type) {
-    registerInstantiatedType(type);
-  }
-
-  void registerAssert(bool hasMessage) {
-    worldImpact.registerFeature(
-        hasMessage ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT);
+    worldImpact.registerTypeUse(new TypeUse.instantiation(type));
   }
 
   void registerSendStructure(Send node, SendStructure sendStructure) {
     mapping.setSendStructure(node, sendStructure);
   }
 
+  void registerNewStructure(NewExpression node, NewStructure newStructure) {
+    mapping.setNewStructure(node, newStructure);
+  }
+
   // TODO(johnniwinther): Remove this when [SendStructure]s are part of the
   // [ResolutionResult].
   SendStructure getSendStructure(Send node) {
     return mapping.getSendStructure(node);
   }
 
-  void registerAsyncMarker(FunctionElement element) {
-    switch (element.asyncMarker) {
-      case AsyncMarker.SYNC:
-        break;
-      case AsyncMarker.SYNC_STAR:
-        worldImpact.registerFeature(Feature.SYNC_STAR);
-        break;
-      case AsyncMarker.ASYNC:
-        worldImpact.registerFeature(Feature.ASYNC);
-        break;
-      case AsyncMarker.ASYNC_STAR:
-        worldImpact.registerFeature(Feature.ASYNC_STAR);
-        break;
-    }
-  }
-
-  void registerAsyncForIn(AsyncForIn node) {
-    worldImpact.registerFeature(Feature.ASYNC_FOR_IN);
-  }
-
-  void registerIncDecOperation() {
-    worldImpact.registerFeature(Feature.INC_DEC_OPERATION);
-  }
-
   void registerTryStatement() {
     mapping.containsTryStatement = true;
   }
@@ -770,7 +416,7 @@
 
   @override
   void registerInstantiatedType(InterfaceType type) {
-    registry.registerInstantiatedType(type);
+    registry.registerInstantiation(type);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index d0bae84..bcb686e 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -10,6 +10,7 @@
 import '../common/names.dart' show
     Identifiers;
 import '../common/resolution.dart' show
+    Feature,
     Parsing,
     Resolution,
     ResolutionImpact;
@@ -20,8 +21,16 @@
     Compiler;
 import '../compile_time_constants.dart' show
     ConstantCompiler;
+import '../constants/expressions.dart' show
+    ConstantExpression,
+    ConstantExpressionKind,
+    ConstructedConstantExpression,
+    ErroneousConstantExpression;
 import '../constants/values.dart' show
     ConstantValue;
+import '../core_types.dart' show
+    CoreClasses,
+    CoreTypes;
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../elements/modelx.dart' show
@@ -36,8 +45,6 @@
     ParameterMetadataAnnotation,
     SetterElementX,
     TypedefElementX;
-import '../enqueue.dart' show
-    WorldImpact;
 import '../tokens/token.dart' show
     isBinaryOperator,
     isMinusOperator,
@@ -45,6 +52,13 @@
     isUnaryOperator,
     isUserDefinableOperator;
 import '../tree/tree.dart';
+import '../universe/call_structure.dart' show
+    CallStructure;
+import '../universe/use.dart' show
+    StaticUse,
+    TypeUse;
+import '../universe/world_impact.dart' show
+    WorldImpact;
 import '../util/util.dart' show
     Link,
     LinkBuilder,
@@ -70,9 +84,13 @@
 
   Parsing get parsing => compiler.parsing;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  CoreTypes get coreTypes => compiler.coreTypes;
+
   ResolutionImpact resolve(Element element) {
     return measure(() {
-      if (Elements.isErroneous(element)) {
+      if (Elements.isMalformed(element)) {
         // TODO(johnniwinther): Add a predicate for this.
         assert(invariant(element, element is! ErroneousElement,
             message: "Element $element expected to have parse errors."));
@@ -87,15 +105,14 @@
         return result;
       }
 
-      ElementKind kind = element.kind;
-      if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) ||
-          identical(kind, ElementKind.FUNCTION) ||
-          identical(kind, ElementKind.GETTER) ||
-          identical(kind, ElementKind.SETTER)) {
+      if (element.isConstructor ||
+          element.isFunction ||
+          element.isGetter ||
+          element.isSetter) {
         return processMetadata(resolveMethodElement(element));
       }
 
-      if (identical(kind, ElementKind.FIELD)) {
+      if (element.isField) {
         return processMetadata(resolveField(element));
       }
       if (element.isClass) {
@@ -123,6 +140,9 @@
     while (redirection != null) {
       // Ensure that we follow redirections through implementation elements.
       redirection = redirection.implementation;
+      if (redirection.isError) {
+        break;
+      }
       if (seen.contains(redirection)) {
         reporter.reportErrorMessage(
             node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
@@ -138,6 +158,7 @@
                                  ResolutionRegistry registry) {
     DiagnosticReporter reporter = compiler.reporter;
     Resolution resolution = compiler.resolution;
+    CoreClasses coreClasses = compiler.coreClasses;
     FunctionExpression functionExpression = element.node;
     AsyncModifier asyncModifier = functionExpression.asyncModifier;
     if (asyncModifier != null) {
@@ -174,16 +195,18 @@
               {'modifier': element.asyncMarker});
         }
       }
-      registry.registerAsyncMarker(element);
       switch (element.asyncMarker) {
       case AsyncMarker.ASYNC:
-        compiler.futureClass.ensureResolved(resolution);
+        registry.registerFeature(Feature.ASYNC);
+        coreClasses.futureClass.ensureResolved(resolution);
         break;
       case AsyncMarker.ASYNC_STAR:
-        compiler.streamClass.ensureResolved(resolution);
+        registry.registerFeature(Feature.ASYNC_STAR);
+        coreClasses.streamClass.ensureResolved(resolution);
         break;
       case AsyncMarker.SYNC_STAR:
-        compiler.iterableClass.ensureResolved(resolution);
+        registry.registerFeature(Feature.SYNC_STAR);
+        coreClasses.iterableClass.ensureResolved(resolution);
         break;
       }
     }
@@ -192,7 +215,7 @@
   bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) {
     assert(classElement != null);
     while (classElement != null) {
-      if (classElement.isNative) return true;
+      if (compiler.backend.isNative(classElement)) return true;
       classElement = classElement.superclass;
     }
     return false;
@@ -264,7 +287,8 @@
       }
 
       // TODO(9631): support noSuchMethod on native classes.
-      if (Elements.isInstanceMethod(element) &&
+      if (element.isFunction &&
+          element.isInstanceMember &&
           element.name == Identifiers.noSuchMethod_ &&
           _isNativeClassOrExtendsNativeClass(enclosingClass)) {
         reporter.reportErrorMessage(
@@ -297,13 +321,14 @@
           // resolved. This is the only place where the resolver is
           // seeing this element.
           element.computeType(resolution);
-          if (!target.isErroneous) {
-            registry.registerStaticUse(target);
-            registry.registerImplicitSuperCall(target);
+          if (!target.isMalformed) {
+            registry.registerStaticUse(
+                new StaticUse.superConstructorInvoke(
+                    target, CallStructure.NO_ARGS));
           }
           return registry.worldImpact;
         } else {
-          assert(element.isDeferredLoaderGetter || element.isErroneous);
+          assert(element.isDeferredLoaderGetter || element.isMalformed);
           _ensureTreeElements(element);
           return const ResolutionImpact();
         }
@@ -365,7 +390,8 @@
       reporter.reportErrorMessage(
           element, MessageKind.FINAL_WITHOUT_INITIALIZER);
     } else {
-      registry.registerInstantiatedClass(compiler.nullClass);
+      // TODO(johnniwinther): Register a feature instead.
+      registry.registerTypeUse(new TypeUse.instantiation(coreTypes.nullType));
     }
 
     if (Elements.isStaticOrTopLevelField(element)) {
@@ -380,7 +406,7 @@
         if (!element.modifiers.isConst) {
           // TODO(johnniwinther): Determine the const-ness eagerly to avoid
           // unnecessary registrations.
-          registry.registerLazyField();
+          registry.registerFeature(Feature.LAZY_FIELD);
         }
       }
     }
@@ -415,15 +441,16 @@
     ConstructorElementX target = constructor;
     InterfaceType targetType;
     List<Element> seen = new List<Element>();
+    bool isMalformed = false;
     // Follow the chain of redirections and check for cycles.
     while (target.isRedirectingFactory || target.isPatched) {
-      if (target.internalEffectiveTarget != null) {
+      if (target.effectiveTargetInternal != 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;
+        target = target.effectiveTargetInternal;
         break;
       }
 
@@ -438,12 +465,20 @@
         reporter.reportErrorMessage(
             node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
         targetType = target.enclosingClass.thisType;
+        isMalformed = true;
         break;
       }
       seen.add(target);
       target = nextTarget;
     }
 
+    if (target.isGenerativeConstructor && target.enclosingClass.isAbstract) {
+      isMalformed = true;
+    }
+    if (target.isMalformed) {
+      isMalformed = true;
+    }
+
     if (targetType == null) {
       assert(!target.isRedirectingFactory);
       targetType = target.enclosingClass.thisType;
@@ -456,24 +491,18 @@
     // 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.'));
       if (!factory.isPatched) {
-        FunctionExpression functionNode = factory.parseNode(parsing);
+        FunctionExpression functionNode = factory.node;
         RedirectingFactoryBody redirectionNode = functionNode.body;
         DartType factoryType = treeElements.getType(redirectionNode);
         if (!factoryType.isDynamic) {
           targetType = targetType.substByContext(factoryType);
         }
       }
-      factory.effectiveTarget = target;
-      factory.effectiveTargetType = targetType;
+      factory.setEffectiveTarget(target, targetType, isMalformed: isMalformed);
     }
   }
 
@@ -484,7 +513,7 @@
    * called by [resolveClass] and [ClassSupertypeResolver].
    */
   void loadSupertypes(BaseClassElementX cls, Spannable from) {
-    reporter.withCurrentElement(cls, () => measure(() {
+    measure(() {
       if (cls.supertypeLoadState == STATE_DONE) return;
       if (cls.supertypeLoadState == STATE_STARTED) {
         reporter.reportErrorMessage(
@@ -494,7 +523,7 @@
         cls.supertypeLoadState = STATE_DONE;
         cls.hasIncompleteHierarchy = true;
         cls.allSupertypesAndSelf =
-            compiler.objectClass.allSupertypesAndSelf.extendClass(
+            coreClasses.objectClass.allSupertypesAndSelf.extendClass(
                 cls.computeType(resolution));
         cls.supertype = cls.allSupertypes.head;
         assert(invariant(from, cls.supertype != null,
@@ -511,7 +540,7 @@
           cls.supertypeLoadState = STATE_DONE;
         }
       });
-    }));
+    });
   }
 
   // TODO(johnniwinther): Remove this queue when resolution has been split into
@@ -539,7 +568,8 @@
         if (previousResolvedTypeDeclaration == null) {
           do {
             while (!pendingClassesToBeResolved.isEmpty) {
-              pendingClassesToBeResolved.removeFirst().ensureResolved(resolution);
+              pendingClassesToBeResolved.removeFirst()
+                  .ensureResolved(resolution);
             }
             while (!pendingClassesToBePostProcessed.isEmpty) {
               _postProcessClassElement(
@@ -733,7 +763,7 @@
                            ClassElement mixin) {
     // TODO(johnniwinther): Avoid the use of [TreeElements] here.
     if (resolutionTree == null) return;
-    Iterable<Node> superUses = resolutionTree.superUses;
+    Iterable<SourceSpan> superUses = resolutionTree.superUses;
     if (superUses.isEmpty) return;
     DiagnosticMessage error = reporter.createMessage(
         mixinApplication,
@@ -741,7 +771,7 @@
         {'className': mixin.name});
     // Show the user the problematic uses of 'super' in the mixin.
     List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-    for (Node use in superUses) {
+    for (SourceSpan use in superUses) {
       infos.add(reporter.createMessage(
           use,
           MessageKind.ILLEGAL_MIXIN_SUPER_USE));
@@ -831,8 +861,8 @@
     if (lookupElement == null) {
       reporter.internalError(member,
           "No abstract field for accessor");
-    } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) {
-      if (lookupElement.isErroneous || lookupElement.isAmbiguous) return;
+    } else if (!lookupElement.isAbstractField) {
+      if (lookupElement.isMalformed || lookupElement.isAmbiguous) return;
       reporter.internalError(member,
           "Inaccessible abstract field for accessor");
     }
@@ -844,14 +874,14 @@
     if (setter == null) return;
     int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
     int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
-    if (!identical(getterFlags, setterFlags)) {
+    if (getterFlags != setterFlags) {
       final mismatchedFlags =
         new Modifiers.withFlags(null, getterFlags ^ setterFlags);
-      reporter.reportErrorMessage(
+      reporter.reportWarningMessage(
           field.getter,
           MessageKind.GETTER_MISMATCH,
           {'modifiers': mismatchedFlags});
-      reporter.reportErrorMessage(
+      reporter.reportWarningMessage(
           field.setter,
           MessageKind.SETTER_MISMATCH,
           {'modifiers': mismatchedFlags});
@@ -1036,8 +1066,29 @@
       node.accept(visitor);
       // TODO(johnniwinther): Avoid passing the [TreeElements] to
       // [compileMetadata].
-      annotation.constant =
-          constantCompiler.compileMetadata(annotation, node, registry.mapping);
+      ConstantExpression constant = constantCompiler.compileMetadata(
+          annotation, node, registry.mapping);
+      switch (constant.kind) {
+        case ConstantExpressionKind.CONSTRUCTED:
+          ConstructedConstantExpression constructedConstant = constant;
+          if (constructedConstant.type.isGeneric) {
+            // Const constructor calls cannot have type arguments.
+            // TODO(24312): Remove this.
+            reporter.reportErrorMessage(
+                node, MessageKind.INVALID_METADATA_GENERIC);
+            constant = new ErroneousConstantExpression();
+          }
+          break;
+        case ConstantExpressionKind.VARIABLE:
+        case ConstantExpressionKind.ERRONEOUS:
+          break;
+        default:
+          reporter.reportErrorMessage(node, MessageKind.INVALID_METADATA);
+          constant = new ErroneousConstantExpression();
+          break;
+      }
+      annotation.constant = constant;
+
       constantCompiler.evaluate(annotation.constant);
       // TODO(johnniwinther): Register the relation between the annotation
       // and the annotated element instead. This will allow the backend to
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor.dart b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
index 92db2c4..cb391a3 100644
--- a/pkg/compiler/lib/src/resolution/semantic_visitor.dart
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
@@ -23,8 +23,10 @@
 
 /// Mixin that couples a [SendResolverMixin] to a [SemanticSendVisitor] in a
 /// [Visitor].
-abstract class SemanticSendResolvedMixin<R, A>
-    implements Visitor<R>, SendResolverMixin {
+abstract class SemanticSendResolvedMixin<R, A> implements Visitor<R> {
+  TreeElements get elements;
+
+  internalError(Spannable spannable, String message);
 
   SemanticSendVisitor<R, A> get sendVisitor;
 
@@ -63,7 +65,7 @@
     // TODO(johnniwinther): Support argument.
     A arg = null;
 
-    NewStructure structure = computeNewStructure(node);
+    NewStructure structure = elements.getNewStructure(node);
     if (structure == null) {
       return internalError(node, 'No structure for $node');
     } else {
@@ -127,7 +129,6 @@
 
 abstract class SemanticVisitor<R, A> extends Visitor<R>
     with SemanticSendResolvedMixin<R, A>,
-         SendResolverMixin,
          SemanticDeclarationResolvedMixin<R, A>,
          DeclarationResolverMixin {
   TreeElements elements;
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
index 479dca0..d592cf4 100644
--- a/pkg/compiler/lib/src/resolution/send_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
@@ -9,137 +9,11 @@
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../tree/tree.dart';
-import '../universe/call_structure.dart' show
-    CallStructure;
-import '../universe/selector.dart' show
-    Selector;
 
-import 'access_semantics.dart';
 import 'semantic_visitor.dart';
 import 'send_structure.dart';
 import 'tree_elements.dart';
 
-abstract class SendResolverMixin {
-  TreeElements get elements;
-
-  internalError(Spannable spannable, String message);
-
-  ConstructorAccessSemantics computeConstructorAccessSemantics(
-        ConstructorElement constructor,
-        CallStructure callStructure,
-        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;
-        if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
-          return new ConstructorAccessSemantics(
-              ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, constructor, type);
-        }
-      }
-      return new ConstructorAccessSemantics(
-          ConstructorAccessKind.UNRESOLVED_TYPE, constructor, type);
-    } else if (constructor.isRedirectingFactory) {
-      ConstructorElement effectiveTarget = constructor.effectiveTarget;
-      if (effectiveTarget == constructor ||
-          effectiveTarget.isErroneous ||
-          (mustBeConstant && !effectiveTarget.isConst)) {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY,
-            constructor,
-            type);
-      }
-      ConstructorAccessSemantics effectiveTargetSemantics =
-          computeConstructorAccessSemantics(
-              effectiveTarget,
-              callStructure,
-              constructor.computeEffectiveTargetType(type));
-      if (effectiveTargetSemantics.isErroneous) {
-        return new RedirectingFactoryConstructorAccessSemantics(
-            ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY,
-            constructor,
-            type,
-            effectiveTargetSemantics);
-      }
-      return new RedirectingFactoryConstructorAccessSemantics(
-          ConstructorAccessKind.REDIRECTING_FACTORY,
-          constructor,
-          type,
-          effectiveTargetSemantics);
-    } else {
-      if (!callStructure.signatureApplies(constructor.functionSignature)) {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.INCOMPATIBLE,
-            constructor,
-            type);
-      } else if (constructor.isFactoryConstructor) {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.FACTORY, constructor, type);
-      } else if (constructor.isRedirectingGenerative) {
-        if (constructor.enclosingClass.isAbstract) {
-            return new ConstructorAccessSemantics(
-                ConstructorAccessKind.ABSTRACT, constructor, type);
-        }
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.REDIRECTING_GENERATIVE, constructor, type);
-      } else if (constructor.enclosingClass.isAbstract) {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.ABSTRACT, constructor, type);
-      } else {
-        return new ConstructorAccessSemantics(
-            ConstructorAccessKind.GENERATIVE, constructor, type);
-      }
-    }
-  }
-
-  NewStructure computeNewStructure(NewExpression node) {
-    Element element = elements[node.send];
-    Selector selector = elements.getSelector(node.send);
-    DartType type = elements.getType(node);
-
-    ConstructorAccessSemantics constructorAccessSemantics =
-        computeConstructorAccessSemantics(
-            element, selector.callStructure, type,
-            mustBeConstant: node.isConst);
-    if (node.isConst) {
-      ConstantExpression constant = elements.getConstant(node);
-      if (constructorAccessSemantics.isErroneous ||
-          constant == null ||
-          constant.kind == ConstantExpressionKind.ERRONEOUS) {
-        // This is a non-constant constant constructor invocation, like
-        // `const Const(method())`.
-        constructorAccessSemantics = new ConstructorAccessSemantics(
-            ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type);
-      } else {
-        ConstantInvokeKind kind;
-        switch (constant.kind) {
-          case ConstantExpressionKind.CONSTRUCTED:
-            kind = ConstantInvokeKind.CONSTRUCTED;
-            break;
-          case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
-            kind = ConstantInvokeKind.BOOL_FROM_ENVIRONMENT;
-            break;
-          case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
-            kind = ConstantInvokeKind.INT_FROM_ENVIRONMENT;
-            break;
-          case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
-            kind = ConstantInvokeKind.STRING_FROM_ENVIRONMENT;
-            break;
-          default:
-            return internalError(
-                node, "Unexpected constant kind $kind: ${constant.getText()}");
-        }
-        return new ConstInvokeStructure(kind, constant);
-      }
-    }
-    return new NewInvokeStructure(constructorAccessSemantics, selector);
-  }
-}
-
 abstract class DeclStructure<R, A> {
   final FunctionElement element;
 
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
index 06c58de..5daa7bd 100644
--- a/pkg/compiler/lib/src/resolution/send_structure.dart
+++ b/pkg/compiler/lib/src/resolution/send_structure.dart
@@ -8,6 +8,8 @@
 import '../constants/expressions.dart';
 import '../dart_types.dart';
 import '../elements/elements.dart';
+import '../resolution/tree_elements.dart' show
+    TreeElements;
 import '../tree/tree.dart';
 import '../universe/call_structure.dart' show
     CallStructure;
@@ -2642,22 +2644,45 @@
   R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
     switch (semantics.kind) {
       case ConstructorAccessKind.GENERATIVE:
+        ConstructorElement constructor = semantics.element;
+        if (constructor.isRedirectingGenerative) {
+          return visitor.visitRedirectingGenerativeConstructorInvoke(
+              node, constructor, semantics.type,
+              node.send.argumentsNode, callStructure, arg);
+        }
         return visitor.visitGenerativeConstructorInvoke(
-            node, semantics.element, semantics.type,
-            node.send.argumentsNode, callStructure, arg);
-      case ConstructorAccessKind.REDIRECTING_GENERATIVE:
-        return visitor.visitRedirectingGenerativeConstructorInvoke(
-            node, semantics.element, semantics.type,
+            node, constructor, semantics.type,
             node.send.argumentsNode, callStructure, arg);
       case ConstructorAccessKind.FACTORY:
-        return visitor.visitFactoryConstructorInvoke(
-            node, semantics.element, semantics.type,
-            node.send.argumentsNode, callStructure, arg);
-      case ConstructorAccessKind.REDIRECTING_FACTORY:
-        return visitor.visitRedirectingFactoryConstructorInvoke(
-            node, semantics.element, semantics.type,
-            semantics.effectiveTargetSemantics.element,
-            semantics.effectiveTargetSemantics.type,
+        ConstructorElement constructor = semantics.element;
+        if (constructor.isRedirectingFactory) {
+          if (constructor.isEffectiveTargetMalformed) {
+            return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
+                node, semantics.element, semantics.type,
+                node.send.argumentsNode, callStructure, arg);
+          }
+          ConstructorElement effectiveTarget = constructor.effectiveTarget;
+          InterfaceType effectiveTargetType =
+              constructor.computeEffectiveTargetType(semantics.type);
+          if (callStructure.signatureApplies(
+                  effectiveTarget.functionSignature)) {
+            return visitor.visitRedirectingFactoryConstructorInvoke(
+                node, semantics.element, semantics.type,
+                effectiveTarget, effectiveTargetType,
+                node.send.argumentsNode, callStructure, arg);
+          } else {
+            return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
+                            node, semantics.element, semantics.type,
+                            node.send.argumentsNode, callStructure, arg);
+          }
+        }
+        if (callStructure.signatureApplies(constructor.functionSignature)) {
+          return visitor.visitFactoryConstructorInvoke(
+              node, constructor, semantics.type,
+              node.send.argumentsNode, callStructure, arg);
+        }
+        return visitor.visitConstructorIncompatibleInvoke(
+            node, constructor, semantics.type,
             node.send.argumentsNode, callStructure, arg);
       case ConstructorAccessKind.ABSTRACT:
         return visitor.visitAbstractClassConstructorInvoke(
@@ -2675,10 +2700,6 @@
         return visitor.errorNonConstantConstructorInvoke(
             node, semantics.element, semantics.type,
             node.send.argumentsNode, callStructure, arg);
-      case ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY:
-        return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
-            node, semantics.element, semantics.type,
-            node.send.argumentsNode, callStructure, arg);
       case ConstructorAccessKind.INCOMPATIBLE:
         return visitor.visitConstructorIncompatibleInvoke(
             node, semantics.element, semantics.type,
@@ -2723,6 +2744,50 @@
   }
 }
 
+/// A constant constructor invocation that couldn't be determined fully during
+/// resolution.
+// TODO(johnniwinther): Remove this when all constants are computed during
+// resolution.
+class LateConstInvokeStructure<R, A> extends NewStructure<R, A> {
+  final TreeElements elements;
+
+  LateConstInvokeStructure(this.elements);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
+    Element element = elements[node.send];
+    Selector selector = elements.getSelector(node.send);
+    DartType type = elements.getType(node);
+    ConstantExpression constant = elements.getConstant(node);
+    if (element.isMalformed ||
+        constant == null ||
+        constant.kind == ConstantExpressionKind.ERRONEOUS) {
+      // This is a non-constant constant constructor invocation, like
+      // `const Const(method())`.
+      return visitor.errorNonConstantConstructorInvoke(
+          node, element, type,
+          node.send.argumentsNode, selector.callStructure, arg);
+    } else {
+      ConstantInvokeKind kind;
+      switch (constant.kind) {
+        case ConstantExpressionKind.CONSTRUCTED:
+          return visitor.visitConstConstructorInvoke(node, constant, arg);
+        case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
+          return visitor.visitBoolFromEnvironmentConstructorInvoke(
+              node, constant, arg);
+        case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
+          return visitor.visitIntFromEnvironmentConstructorInvoke(
+              node, constant, arg);
+        case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
+          return visitor.visitStringFromEnvironmentConstructorInvoke(
+              node, constant, arg);
+        default:
+          throw new SpannableAssertionFailure(
+              node, "Unexpected constant kind $kind: ${constant.getText()}");
+      }
+    }
+  }
+}
+
 /// The structure of a parameter declaration.
 abstract class ParameterStructure<R, A> {
   final VariableDefinitions definitions;
diff --git a/pkg/compiler/lib/src/resolution/signatures.dart b/pkg/compiler/lib/src/resolution/signatures.dart
index 41f3033..df165a6 100644
--- a/pkg/compiler/lib/src/resolution/signatures.dart
+++ b/pkg/compiler/lib/src/resolution/signatures.dart
@@ -18,6 +18,8 @@
     InitializingFormalElementX,
     LocalParameterElementX;
 import '../tree/tree.dart';
+import '../universe/use.dart' show
+    TypeUse;
 import '../util/util.dart' show
     Link,
     LinkBuilder;
@@ -310,7 +312,7 @@
     int requiredParameterCount = 0;
     if (formalParameters == null) {
       if (!element.isGetter) {
-        if (element.isErroneous) {
+        if (element.isMalformed) {
           // If the element is erroneous, an error should already have been
           // reported. In the case of parse errors, it is possible that there
           // are formal parameters, but something else in the method failed to
@@ -341,7 +343,7 @@
       // Because there is no type annotation for the return type of
       // this element, we explicitly add one.
       if (compiler.enableTypeAssertions) {
-        registry.registerIsCheck(returnType);
+        registry.registerTypeUse(new TypeUse.checkedModeCheck(returnType));
       }
     } else {
       AsyncMarker asyncMarker = AsyncMarker.SYNC;
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
index 8d3071c..a60bb79 100644
--- a/pkg/compiler/lib/src/resolution/tree_elements.dart
+++ b/pkg/compiler/lib/src/resolution/tree_elements.dart
@@ -7,6 +7,7 @@
 import '../common.dart';
 import '../constants/expressions.dart';
 import '../dart_types.dart';
+import '../diagnostics/source_span.dart';
 import '../elements/elements.dart';
 import '../types/types.dart' show
     TypeMask;
@@ -22,19 +23,18 @@
 
 abstract class TreeElements {
   AnalyzableElement get analyzedElement;
-  Iterable<Node> get superUses;
-
-  /// The set of types that this TreeElement depends on.
-  /// This includes instantiated types, types in is-checks and as-expressions
-  /// and in checked mode the types of all type-annotations.
-  Iterable<DartType> get requiredTypes;
+  Iterable<SourceSpan> get superUses;
 
   void forEachConstantNode(f(Node n, ConstantExpression c));
 
   Element operator[](Node node);
   Map<Node, DartType> get typesCache;
 
-  SendStructure getSendStructure(Send send);
+  /// Returns the [SendStructure] that describes the semantics of [node].
+  SendStructure getSendStructure(Send node);
+
+  /// Returns the [NewStructure] that describes the semantics of [node].
+  NewStructure getNewStructure(NewExpression node);
 
   // TODO(johnniwinther): Investigate whether [Node] could be a [Send].
   Selector getSelector(Node node);
@@ -50,9 +50,6 @@
 
   /// Returns the for-in loop variable for [node].
   Element getForInVariable(ForIn node);
-  Selector getIteratorSelector(ForIn node);
-  Selector getMoveNextSelector(ForIn node);
-  Selector getCurrentSelector(ForIn node);
   TypeMask getIteratorTypeMask(ForIn node);
   TypeMask getMoveNextTypeMask(ForIn node);
   TypeMask getCurrentTypeMask(ForIn node);
@@ -80,9 +77,6 @@
   /// Returns the type that the type literal [node] refers to.
   DartType getTypeLiteralType(Send node);
 
-  /// Register a dependency on [type].
-  void addRequiredType(DartType type);
-
   /// Returns a list of nodes that potentially mutate [element] anywhere in its
   /// scope.
   List<Node> getPotentialMutations(VariableElement element);
@@ -118,14 +112,14 @@
   Map<Spannable, TypeMask> _typeMasks;
   Map<Node, DartType> _types;
   Map<Node, DartType> typesCache = <Node, DartType>{};
-  Setlet<Node> _superUses;
+  Setlet<SourceSpan> _superUses;
   Map<Node, ConstantExpression> _constants;
   Map<VariableElement, List<Node>> _potentiallyMutated;
   Map<Node, Map<VariableElement, List<Node>>> _potentiallyMutatedIn;
   Map<VariableElement, List<Node>> _potentiallyMutatedInClosure;
   Map<Node, Map<VariableElement, List<Node>>> _accessedByClosureIn;
   Maplet<Send, SendStructure> _sendStructureMap;
-  Setlet<DartType> _requiredTypes;
+  Maplet<NewExpression, NewStructure> _newStructureMap;
   bool containsTryStatement = false;
 
   /// Map from nodes to the targets they define.
@@ -149,7 +143,7 @@
     // TODO(johnniwinther): Simplify this invariant to use only declarations in
     // [TreeElements].
     assert(invariant(node, () {
-      if (!element.isErroneous && analyzedElement != null && element.isPatch) {
+      if (!element.isMalformed && analyzedElement != null && element.isPatch) {
         return analyzedElement.implementationLibrary.isPatch;
       }
       return true;
@@ -165,16 +159,28 @@
 
   operator [](Node node) => getTreeElement(node);
 
-  SendStructure getSendStructure(Send send) {
+  SendStructure getSendStructure(Send node) {
     if (_sendStructureMap == null) return null;
-    return _sendStructureMap[send];
+    return _sendStructureMap[node];
   }
 
-  void setSendStructure(Send send, SendStructure sendStructure) {
+  void setSendStructure(Send node, SendStructure sendStructure) {
     if (_sendStructureMap == null) {
       _sendStructureMap = new Maplet<Send, SendStructure>();
     }
-    _sendStructureMap[send] = sendStructure;
+    _sendStructureMap[node] = sendStructure;
+  }
+
+  NewStructure getNewStructure(NewExpression node) {
+    if (_newStructureMap == null) return null;
+    return _newStructureMap[node];
+  }
+
+  void setNewStructure(NewExpression node, NewStructure newStructure) {
+    if (_newStructureMap == null) {
+      _newStructureMap = new Maplet<NewExpression, NewStructure>();
+    }
+    _newStructureMap[node] = newStructure;
   }
 
   void setType(Node node, DartType type) {
@@ -186,28 +192,15 @@
 
   DartType getType(Node node) => _types != null ? _types[node] : null;
 
-  void addRequiredType(DartType type) {
-    if (_requiredTypes == null) _requiredTypes = new Setlet<DartType>();
-    _requiredTypes.add(type);
+  Iterable<SourceSpan> get superUses {
+    return _superUses != null ? _superUses : const <SourceSpan>[];
   }
 
-  Iterable<DartType> get requiredTypes {
-    if (_requiredTypes == null) {
-      return const <DartType>[];
-    } else {
-      return _requiredTypes;
-    }
-  }
-
-  Iterable<Node> get superUses {
-    return _superUses != null ? _superUses : const <Node>[];
-  }
-
-  void addSuperUse(Node node) {
+  void addSuperUse(SourceSpan span) {
     if (_superUses == null) {
-      _superUses = new Setlet<Node>();
+      _superUses = new Setlet<SourceSpan>();
     }
-    _superUses.add(node);
+    _superUses.add(span);
   }
 
   Selector _getSelector(Spannable node) {
@@ -245,34 +238,6 @@
     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];
   }
diff --git a/pkg/compiler/lib/src/resolution/type_resolver.dart b/pkg/compiler/lib/src/resolution/type_resolver.dart
index 3c6ab75..165790d 100644
--- a/pkg/compiler/lib/src/resolution/type_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/type_resolver.dart
@@ -6,6 +6,7 @@
 
 import '../common.dart';
 import '../common/resolution.dart' show
+    Feature,
     Resolution;
 import '../compiler.dart' show
     Compiler;
@@ -136,13 +137,13 @@
             reporter.createMessage(node, messageKind, messageArguments),
             infos);
       } else {
-        registry.registerThrowRuntimeError();
+        registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
         reporter.reportWarning(
             reporter.createMessage(node, messageKind, messageArguments),
             infos);
       }
       if (erroneousElement == null) {
-        registry.registerThrowRuntimeError();
+        registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
         erroneousElement = new ErroneousElementX(
             messageKind, messageArguments, typeName.source,
             visitor.enclosingElement);
@@ -165,7 +166,7 @@
           infos: ambiguous.computeInfos(
               registry.mapping.analyzedElement, reporter));
       ;
-    } else if (element.isErroneous) {
+    } else if (element.isMalformed) {
       if (element is ErroneousElement) {
         type = reportFailureAndCreateType(
             element.messageKind, element.messageArguments,
@@ -226,7 +227,7 @@
         if (!outer.isClass &&
             !outer.isTypedef &&
             !Elements.hasAccessToTypeVariables(visitor.enclosingElement)) {
-          registry.registerThrowRuntimeError();
+          registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
           type = reportFailureAndCreateType(
               MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
               {'typeVariableName': node},
@@ -240,7 +241,7 @@
             "Unexpected element kind ${element.kind}.");
       }
       if (addTypeVariableBoundsCheck) {
-        registry.registerTypeVariableBoundCheck();
+        registry.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
         visitor.addDeferredAction(
             visitor.enclosingElement,
             () => checkTypeVariableBounds(node, type));
diff --git a/pkg/compiler/lib/src/resolution/variables.dart b/pkg/compiler/lib/src/resolution/variables.dart
index e9d6b94..aec67f3 100644
--- a/pkg/compiler/lib/src/resolution/variables.dart
+++ b/pkg/compiler/lib/src/resolution/variables.dart
@@ -11,6 +11,8 @@
     LocalVariableElementX,
     VariableList;
 import '../tree/tree.dart';
+import '../universe/use.dart' show
+    TypeUse;
 import '../util/util.dart' show
     Link;
 
@@ -54,13 +56,20 @@
 
   Identifier visitIdentifier(Identifier node) {
     // The variable is initialized to null.
-    registry.registerInstantiatedClass(compiler.nullClass);
+    // TODO(johnniwinther): Register a feature instead.
+    registry.registerTypeUse(
+        new TypeUse.instantiation(compiler.coreTypes.nullType));
     if (definitions.modifiers.isConst) {
-      reporter.reportErrorMessage(
-          node, MessageKind.CONST_WITHOUT_INITIALIZER);
+      if (resolver.inLoopVariable) {
+        reporter.reportErrorMessage(
+            node, MessageKind.CONST_LOOP_VARIABLE);
+      } else {
+        reporter.reportErrorMessage(
+            node, MessageKind.CONST_WITHOUT_INITIALIZER);
+      }
     }
     if (definitions.modifiers.isFinal &&
-        !resolver.allowFinalWithoutInitializer) {
+        !resolver.inLoopVariable) {
       reporter.reportErrorMessage(
           node, MessageKind.FINAL_WITHOUT_INITIALIZER);
     }
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 86d27901..07cf4e6 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -51,9 +51,6 @@
 }
 
 abstract class ElementZ extends Element with ElementCommon {
-  @override
-  bool get isFactoryConstructor => false;
-
   String toString() {
     if (enclosingElement == null || isTopLevel) return 'Z$kind($name)';
     return 'Z$kind(${enclosingElement.name}#$name)';
@@ -1006,10 +1003,7 @@
       : super(decoder);
 
   @override
-  ElementKind get kind => ElementKind.FUNCTION;
-
-  @override
-  bool get isFactoryConstructor => true;
+  ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
 }
 
 abstract class MemberElementMixin
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 2b86c5e..551ba49 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -14,7 +14,8 @@
     Compiler;
 import '../elements/elements.dart';
 import '../enqueue.dart' show
-    ResolutionEnqueuer,
+    ResolutionEnqueuer;
+import '../universe/world_impact.dart' show
     WorldImpact;
 
 /// Task that supports deserialization of elements.
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index a913c77..540ba50 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -353,7 +353,7 @@
     // Instead of allocating and initializing the object, the constructor
     // 'upgrades' the native subclass object by initializing the Dart fields.
     bool isNativeUpgradeFactory = element.isGenerativeConstructor
-        && Elements.isNativeOrExtendsNative(cls);
+        && backend.isNativeOrExtendsNative(cls);
     if (backend.isInterceptedMethod(element)) {
       bool isInterceptorClass = backend.isInterceptorClass(cls.declaration);
       String name = isInterceptorClass ? 'receiver' : '_';
@@ -973,7 +973,6 @@
 class SsaBuilder extends ast.Visitor
     with BaseImplementationOfCompoundsMixin,
          BaseImplementationOfSetIfNullsMixin,
-         SendResolverMixin,
          SemanticSendResolvedMixin,
          NewBulkMixin,
          ErrorBulkMixin
@@ -1118,6 +1117,8 @@
 
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   @override
   SemanticSendVisitor get sendVisitor => this;
 
@@ -1145,18 +1146,18 @@
   HGraph build() {
     assert(invariant(target, target.isImplementation));
     HInstruction.idCounter = 0;
-    ElementKind kind = target.kind;
     // TODO(sigmund): remove `result` and return graph directly, need to ensure
     // that it can never be null (see result in buildFactory for instance).
     var result;
-    if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+    if (target.isGenerativeConstructor) {
       result = buildFactory(target);
-    } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
-               kind == ElementKind.FUNCTION ||
-               kind == ElementKind.GETTER ||
-               kind == ElementKind.SETTER) {
+    } else if (target.isGenerativeConstructorBody ||
+               target.isFactoryConstructor ||
+               target.isFunction ||
+               target.isGetter ||
+               target.isSetter) {
       result = buildMethod(target);
-    } else if (kind == ElementKind.FIELD) {
+    } else if (target.isField) {
       if (target.isInstanceMember) {
         assert(compiler.enableTypeAssertions);
         result = buildCheckedSetter(target);
@@ -1164,7 +1165,7 @@
         result = buildLazyInitializer(target);
       }
     } else {
-      reporter.internalError(target, 'Unexpected element kind $kind.');
+      reporter.internalError(target, 'Unexpected element kind $target.');
     }
     assert(result.isValid());
     return result;
@@ -1339,7 +1340,7 @@
     // enqueued.
     backend.registerStaticUse(element, compiler.enqueuer.codegen);
 
-    if (element.isJsInterop && !element.isFactoryConstructor) {
+    if (backend.isJsInterop(element) && !element.isFactoryConstructor) {
       // We only inline factory JavaScript interop constructors.
       return false;
     }
@@ -1374,11 +1375,11 @@
         }
       }
 
-      if (element.isJsInterop) return false;
+      if (backend.isJsInterop(element)) return false;
 
       // Don't inline operator== methods if the parameter can be null.
       if (element.name == '==') {
-        if (element.enclosingClass != compiler.objectClass
+        if (element.enclosingClass != coreClasses.objectClass
             && providedArguments[1].canBeNull()) {
           return false;
         }
@@ -1387,7 +1388,7 @@
       // Generative constructors of native classes should not be called directly
       // and have an extra argument that causes problems with inlining.
       if (element.isGenerativeConstructor
-          && Elements.isNativeOrExtendsNative(element.enclosingClass)) {
+          && backend.isNativeOrExtendsNative(element.enclosingClass)) {
         return false;
       }
 
@@ -1651,7 +1652,7 @@
     assert(elements.getFunctionDefinition(function) != null);
     openFunction(functionElement, function);
     String name = functionElement.name;
-    if (functionElement.isJsInterop) {
+    if (backend.isJsInterop(functionElement)) {
       push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
           sourceInformationBuilder.buildGeneric(function)));
       var value = pop();
@@ -1689,7 +1690,7 @@
           p.instructionType.isEmpty && !p.instructionType.isNullable);
       if (emptyParameters.length > 0) {
         addComment('${emptyParameters} inferred as [empty]');
-        pushInvokeStatic(function.body, backend.assertUnreachableMethod, []);
+        pushInvokeStatic(function.body, helpers.assertUnreachableMethod, []);
         pop();
         return closeFunction();
       }
@@ -2022,7 +2023,7 @@
       }
 
       Element target = constructor.definingConstructor.implementation;
-      bool match = !target.isErroneous &&
+      bool match = !target.isMalformed &&
           CallStructure.addForwardingElementArgumentsToList(
               constructor,
               arguments,
@@ -2136,7 +2137,7 @@
             if (initializer == null) {
               // Unassigned fields of native classes are not initialized to
               // prevent overwriting pre-initialized native properties.
-              if (!Elements.isNativeOrExtendsNative(classElement)) {
+              if (!backend.isNativeOrExtendsNative(classElement)) {
                 fieldValues[member] = graph.addConstantNull(compiler);
               }
             } else {
@@ -2169,8 +2170,8 @@
     ClassElement classElement =
         functionElement.enclosingClass.implementation;
     bool isNativeUpgradeFactory =
-        Elements.isNativeOrExtendsNative(classElement)
-            && !classElement.isJsInterop;
+        backend.isNativeOrExtendsNative(classElement)
+            && !backend.isJsInterop(classElement);
     ast.FunctionExpression function = functionElement.node;
     // Note that constructors (like any other static function) do not need
     // to deal with optional arguments. It is the callers job to provide all
@@ -2559,7 +2560,7 @@
       pushInvokeDynamic(
           null,
           new Selector.call(
-              new Name(name, backend.jsHelperLibrary), CallStructure.ONE_ARG),
+              new Name(name, helpers.jsHelperLibrary), CallStructure.ONE_ARG),
           null,
           arguments);
 
@@ -2576,9 +2577,9 @@
     type = type.unaliased;
     if (type.isDynamic) return original;
     if (!type.isInterfaceType) return original;
+    if (type.isObject) return original;
     // The type element is either a class or the void element.
     Element element = type.element;
-    if (element == compiler.objectClass) return original;
     TypeMask mask = new TypeMask.subtype(element, compiler.world);
     return new HTypeKnown.pinned(mask, original);
   }
@@ -2588,7 +2589,7 @@
     assert(type != null);
     type = localsHandler.substInContext(type);
     HInstruction other = buildTypeConversion(original, type, kind);
-    registry?.registerIsCheck(type);
+    registry?.registerTypeUse(new TypeUse.isCheck(type));
     return other;
   }
 
@@ -2652,7 +2653,7 @@
     if (_checkOrTrustTypes) {
       return potentiallyCheckOrTrustType(
           value,
-          compiler.boolClass.rawType,
+          compiler.coreTypes.boolType,
           kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
     }
     HInstruction result = new HBoolify(value, backend.boolType);
@@ -3234,7 +3235,7 @@
     // TODO(ahe): This should be registered in codegen, not here.
     // TODO(johnniwinther): Is [registerStaticUse] equivalent to
     // [addToWorkList]?
-    registry?.registerStaticUse(callElement);
+    registry?.registerStaticUse(new StaticUse.foreignUse(callElement));
 
     List<HInstruction> capturedVariables = <HInstruction>[];
     closureClassElement.closureFields.forEach((ClosureFieldElement field) {
@@ -3245,7 +3246,7 @@
     });
 
     TypeMask type =
-        new TypeMask.nonNullExact(compiler.functionClass, compiler.world);
+        new TypeMask.nonNullExact(closureClassElement, compiler.world);
     push(new HForeignNew(closureClassElement, type, capturedVariables)
         ..sourceInformation = sourceInformationBuilder.buildCreate(node));
 
@@ -3475,7 +3476,7 @@
       handleInvalidStaticGet(node, element);
     } else {
       // This happens when [element] has parse errors.
-      assert(invariant(node, element == null || element.isErroneous));
+      assert(invariant(node, element == null || element.isMalformed));
       // TODO(ahe): Do something like the above, that is, emit a runtime
       // error.
       stack.add(graph.addConstantNull(compiler));
@@ -3764,13 +3765,11 @@
         addWithPosition(new HStaticStore(element, value), location);
       }
       stack.add(value);
-    } else if (Elements.isErroneous(element)) {
-      if (element is ErroneousElement) {
-        generateNoSuchSetter(location, element,  send == null ? null : value);
-      } else {
-        // TODO(ahe): Do something like [generateWrongArgumentCountError].
-        stack.add(graph.addConstantNull(compiler));
-      }
+    } else if (Elements.isError(element)) {
+      generateNoSuchSetter(location, element,  send == null ? null : value);
+    } else if (Elements.isMalformed(element)) {
+      // TODO(ahe): Do something like [generateWrongArgumentCountError].
+      stack.add(graph.addConstantNull(compiler));
     } else {
       stack.add(value);
       LocalElement local = element;
@@ -3875,7 +3874,7 @@
       pushInvokeDynamic(
           node,
           new Selector.call(
-              new PrivateName('_isTest', backend.jsHelperLibrary),
+              new PrivateName('_isTest', helpers.jsHelperLibrary),
               CallStructure.ONE_ARG),
           null,
           arguments);
@@ -3981,7 +3980,7 @@
         arguments,
         element,
         compileArgument,
-        element.isJsInterop ?
+        backend.isJsInterop(element) ?
             handleConstantForOptionalParameterJsInterop :
             handleConstantForOptionalParameter);
   }
@@ -4155,6 +4154,10 @@
       return;
     }
 
+    if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) {
+      reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE);
+    }
+
     TypeMask ssaType =
         TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
 
@@ -4202,7 +4205,7 @@
       // Call a helper method from the isolate library. The isolate
       // library uses its own isolate structure, that encapsulates
       // Leg's isolate.
-      Element element = backend.isolateHelperLibrary.find('_currentIsolate');
+      Element element = helpers.currentIsolate;
       if (element == null) {
         reporter.internalError(node,
             'Isolate library and compiler mismatch.');
@@ -4277,7 +4280,7 @@
     Element element = elements[argument];
     if (element == null ||
         element is! FieldElement ||
-        element.enclosingClass != backend.jsGetNameEnum) {
+        element.enclosingClass != helpers.jsGetNameEnum) {
       reporter.reportErrorMessage(
           argument, MessageKind.GENERIC,
           {'text': 'Error: Expected a JsGetName enum value.'});
@@ -4302,7 +4305,7 @@
     Element builtinElement = elements[arguments[1]];
     if (builtinElement == null ||
         (builtinElement is! FieldElement) ||
-        builtinElement.enclosingClass != backend.jsBuiltinEnum) {
+        builtinElement.enclosingClass != helpers.jsBuiltinEnum) {
       reporter.reportErrorMessage(
           argument, MessageKind.GENERIC,
           {'text': 'Error: Expected a JsBuiltin enum value.'});
@@ -4411,7 +4414,7 @@
                               backend.dynamicType));
     } else {
       // Call a helper method from the isolate library.
-      Element element = backend.isolateHelperLibrary.find('_callInIsolate');
+      Element element = helpers.callInIsolate;
       if (element == null) {
         reporter.internalError(node,
             'Isolate library and compiler mismatch.');
@@ -4444,10 +4447,11 @@
           '"$name" does not handle closure with optional parameters.');
     }
 
-    registry?.registerStaticUse(element);
+    registry?.registerStaticUse(
+        new StaticUse.foreignUse(function));
     push(new HForeignCode(
         js.js.expressionTemplateYielding(
-            backend.emitter.staticFunctionAccess(element)),
+            backend.emitter.staticFunctionAccess(function)),
         backend.dynamicType,
         <HInstruction>[],
         nativeBehavior: native.NativeBehavior.PURE));
@@ -4545,13 +4549,13 @@
 
     ClassElement cls = currentNonClosureClass;
     Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
-    if (compiler.enabledInvokeOn
-        && element.enclosingElement.declaration != compiler.objectClass) {
+    if (compiler.enabledInvokeOn && !element.enclosingClass.isObject) {
       // Register the call as dynamic if [noSuchMethod] on the super
       // class is _not_ the default implementation from [Object], in
       // case the [noSuchMethod] implementation calls
       // [JSInvocationMirror._invokeOn].
-      registry?.registerSelectorUse(selector);
+      // TODO(johnniwinther): Register this more precisely.
+      registry?.registerDynamicUse(new DynamicUse(selector, null));
     }
     String publicName = name;
     if (selector.isSetter) publicName += '=';
@@ -4990,7 +4994,7 @@
       inputs.add(analyzeTypeArgument(argument));
     });
     // TODO(15489): Register at codegen.
-    registry?.registerInstantiatedType(type);
+    registry?.registerInstantiation(type);
     return callSetRuntimeTypeInfo(type.element, inputs, newObject);
   }
 
@@ -5067,13 +5071,19 @@
         TypeMask inferred =
             TypeMaskFactory.inferredForNode(sourceElement, send, compiler);
         ClassElement cls = element.enclosingClass;
-        assert(cls.thisType.element.isNative);
+        assert(backend.isNative(cls.thisType.element));
         return inferred.containsAll(compiler.world)
             ? new TypeMask.nonNullExact(cls.thisType.element, compiler.world)
             : inferred;
       } else if (element.isGenerativeConstructor) {
         ClassElement cls = element.enclosingClass;
-        return new TypeMask.nonNullExact(cls.thisType.element, compiler.world);
+        if (cls.isAbstract) {
+          // An error will be thrown.
+          return new TypeMask.nonNullEmpty();
+        } else {
+          return new TypeMask.nonNullExact(
+              cls.thisType.element, compiler.world);
+        }
       } else {
         return TypeMaskFactory.inferredReturnTypeForElement(
             originalElement, compiler);
@@ -5089,7 +5099,7 @@
     final bool isSymbolConstructor =
         constructorDeclaration == compiler.symbolConstructor;
     final bool isJSArrayTypedConstructor =
-        constructorDeclaration == backend.jsArrayTypedConstructor;
+        constructorDeclaration == helpers.jsArrayTypedConstructor;
 
     if (isSymbolConstructor) {
       constructor = compiler.symbolValidatedConstructor;
@@ -5124,24 +5134,40 @@
       stack.add(graph.addConstantNull(compiler));
       return;
     }
+
     if (checkTypeVariableBounds(node, type)) return;
 
-    var inputs = <HInstruction>[];
-    if (constructor.isGenerativeConstructor &&
-        Elements.isNativeOrExtendsNative(constructor.enclosingClass) &&
-        !constructor.isJsInterop) {
-      // Native class generative constructors take a pre-constructed object.
-      inputs.add(graph.addConstantNull(compiler));
+    // Abstract class instantiation error takes precedence over argument
+    // mismatch.
+    ClassElement cls = constructor.enclosingClass;
+    if (cls.isAbstract && constructor.isGenerativeConstructor) {
+      // However, we need to ensure that all arguments are evaluated before we
+      // throw the ACIE exception.
+      send.arguments.forEach((arg) {
+        visit(arg);
+        pop();
+      });
+      generateAbstractClassInstantiationError(send, cls.name);
+      return;
     }
+
     // TODO(5347): Try to avoid the need for calling [implementation] before
     // calling [makeStaticArgumentList].
     constructorImplementation = constructor.implementation;
-    if (constructorImplementation.isErroneous ||
+    if (constructorImplementation.isMalformed ||
         !callStructure.signatureApplies(
             constructorImplementation.functionSignature)) {
       generateWrongArgumentCountError(send, constructor, send.arguments);
       return;
     }
+
+    var inputs = <HInstruction>[];
+    if (constructor.isGenerativeConstructor &&
+        backend.isNativeOrExtendsNative(constructor.enclosingClass) &&
+        !backend.isJsInterop(constructor)) {
+      // Native class generative constructors take a pre-constructed object.
+      inputs.add(graph.addConstantNull(compiler));
+    }
     inputs.addAll(makeStaticArgumentList(callStructure,
                                          send.arguments,
                                          constructorImplementation));
@@ -5158,12 +5184,15 @@
       js.Template code = js.js.parseForeignJS('new Array(#)');
       var behavior = new native.NativeBehavior();
       behavior.typesReturned.add(expectedType);
-      // The allocation can throw only if the given length is a double
-      // or negative.
+      // The allocation can throw only if the given length is a double or
+      // outside the unsigned 32 bit range.
+      // TODO(sra): Array allocation should be an instruction so that canThrow
+      // can depend on a length type discovered in optimization.
       bool canThrow = true;
       if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) {
         var constant = inputs[0];
-        if (constant.constant.primitiveValue >= 0) canThrow = false;
+        int value = constant.constant.primitiveValue;
+        if (0 <= value && value < 0x100000000) canThrow = false;
       }
       HForeignCode foreign = new HForeignCode(code, elementType, inputs,
           nativeBehavior: behavior,
@@ -5185,13 +5214,7 @@
     } else {
       SourceInformation sourceInformation =
           sourceInformationBuilder.buildNew(send);
-      ClassElement cls = constructor.enclosingClass;
-      if (cls.isAbstract && constructor.isGenerativeConstructor) {
-        generateAbstractClassInstantiationError(send, cls.name);
-        return;
-      }
       potentiallyAddTypeArguments(inputs, cls, expectedType);
-
       addInlinedInstantiation(expectedType);
       pushInvokeStatic(node, constructor, inputs,
           typeMask: elementType,
@@ -5213,7 +5236,7 @@
     // not know about the type argument. Therefore we special case
     // this constructor to have the setRuntimeTypeInfo called where
     // the 'new' is done.
-    if (backend.classNeedsRti(compiler.listClass) &&
+    if (backend.classNeedsRti(coreClasses.listClass) &&
         (isFixedListConstructorCall || isGrowableListConstructorCall ||
          isJSArrayTypedConstructor)) {
       newInstance = handleListConstructor(type, send, pop());
@@ -5724,18 +5747,14 @@
   void bulkHandleNew(ast.NewExpression node, [_]) {
     Element element = elements[node.send];
     final bool isSymbolConstructor = element == compiler.symbolConstructor;
-    if (!Elements.isErroneous(element)) {
+    if (!Elements.isMalformed(element)) {
       ConstructorElement function = element;
       element = function.effectiveTarget;
     }
-    if (Elements.isErroneous(element)) {
-      if (element is !ErroneousElement) {
-        // TODO(ahe): Do something like [generateWrongArgumentCountError].
-        stack.add(graph.addConstantNull(compiler));
-        return;
-      }
+    if (Elements.isError(element)) {
       ErroneousElement error = element;
-      if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
+      if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR ||
+          error.messageKind == MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR) {
         generateThrowNoSuchMethod(
             node.send,
             noSuchMethodTargetSymbolString(error, 'constructor'),
@@ -5745,6 +5764,9 @@
         Message message = template.message(error.messageArguments);
         generateRuntimeError(node.send, message.toString());
       }
+    } else if (Elements.isMalformed(element)) {
+      // TODO(ahe): Do something like [generateWrongArgumentCountError].
+      stack.add(graph.addConstantNull(compiler));
     } else if (node.isConst) {
       stack.add(addConstant(node));
       if (isSymbolConstructor) {
@@ -5785,11 +5807,11 @@
       if (isLength || selector.isIndex) {
         return compiler.world.isSubtypeOf(
             element.enclosingClass.declaration,
-            backend.jsIndexableClass);
+            helpers.jsIndexableClass);
       } else if (selector.isIndexSet) {
         return compiler.world.isSubtypeOf(
             element.enclosingClass.declaration,
-            backend.jsMutableIndexableClass);
+            helpers.jsMutableIndexableClass);
       } else {
         return false;
       }
@@ -5803,9 +5825,9 @@
       if (selector.isSetter) return true;
       if (selector.isIndex) return true;
       if (selector.isIndexSet) return true;
-      if (element == backend.jsArrayAdd
-          || element == backend.jsArrayRemoveLast
-          || element == backend.jsStringSplit) {
+      if (element == helpers.jsArrayAdd ||
+          element == helpers.jsArrayRemoveLast ||
+          element == helpers.jsStringSplit) {
         return true;
       }
       return false;
@@ -5855,7 +5877,7 @@
   HForeignCode invokeJsInteropFunction(FunctionElement element,
                                        List<HInstruction> arguments,
                                        SourceInformation sourceInformation) {
-    assert(element.isJsInterop);
+    assert(backend.isJsInterop(element));
     nativeEmitter.nativeMethods.add(element);
     String templateString;
 
@@ -5897,7 +5919,7 @@
     }
     var target = new HForeignCode(js.js.parseForeignJS(
             "${backend.namer.fixedBackendPath(element)}."
-            "${element.fixedBackendName}"),
+            "${backend.getFixedBackendName(element)}"),
         backend.dynamicType,
         <HInstruction>[]);
     add(target);
@@ -5921,7 +5943,7 @@
 
     // The allocation effects include the declared type if it is native (which
     // includes js interop types).
-    if (type.element != null && type.element.isNative) {
+    if (type.element != null && backend.isNative(type.element)) {
       nativeBehavior.typesInstantiated.add(type);
     }
 
@@ -5930,7 +5952,7 @@
     if (!compiler.trustJSInteropTypeAnnotations || type.isObject ||
         type.isDynamic) {
       nativeBehavior.typesInstantiated.add(
-          backend.jsJavaScriptObjectClass.thisType);
+          backend.helpers.jsJavaScriptObjectClass.thisType);
     }
 
     String code;
@@ -5971,7 +5993,7 @@
     bool targetCanThrow = !compiler.world.getCannotThrow(element);
     // TODO(5346): Try to avoid the need for calling [declaration] before
     var instruction;
-    if (element.isJsInterop) {
+    if (backend.isJsInterop(element)) {
       instruction = invokeJsInteropFunction(element, arguments,
           sourceInformation);
     } else {
@@ -6897,7 +6919,7 @@
       return;
     }
 
-    if (getter.isErroneous) {
+    if (getter.isMalformed) {
       generateStaticUnresolvedGet(node, getter);
     } else if (getter.isField) {
       generateStaticFieldGet(node, getter);
@@ -7174,7 +7196,7 @@
     return type.isDynamic ||
            type.isObject ||
            (type is InterfaceType &&
-               type.element == compiler.futureClass);
+               type.element == coreClasses.futureClass);
   }
 
   visitReturn(ast.Return node) {
@@ -7227,8 +7249,8 @@
     visit(node.expression);
     HInstruction awaited = pop();
     // TODO(herhut): Improve this type.
-    push(new HAwait(awaited, new TypeMask.subclass(compiler.objectClass,
-                                                   compiler.world)));
+    push(new HAwait(awaited, new TypeMask.subclass(
+        coreClasses.objectClass, compiler.world)));
   }
 
   visitTypeAnnotation(ast.TypeAnnotation node) {
@@ -7265,7 +7287,7 @@
       arguments.add(analyzeTypeArgument(argument));
     }
     // TODO(15489): Register at codegen.
-    registry?.registerInstantiatedType(type);
+    registry?.registerInstantiation(type);
     return callSetRuntimeTypeInfo(type.element, arguments, object);
   }
 
@@ -7387,16 +7409,16 @@
     void buildInitializer() {}
 
     HInstruction buildCondition() {
-      Selector selector = elements.getMoveNextSelector(node);
+      Selector selector = Selectors.moveNext;
       TypeMask mask = elements.getMoveNextTypeMask(node);
       pushInvokeDynamic(node, selector, mask, [streamIterator]);
       HInstruction future = pop();
-      push(new HAwait(future, new TypeMask.subclass(compiler.objectClass,
-                                                    compiler.world)));
+      push(new HAwait(future,
+          new TypeMask.subclass(coreClasses.objectClass, compiler.world)));
       return popBoolified();
     }
     void buildBody() {
-      Selector call = elements.getCurrentSelector(node);
+      Selector call = Selectors.current;
       TypeMask callMask = elements.getCurrentTypeMask(node);
       pushInvokeDynamic(node, call, callMask, [streamIterator]);
 
@@ -7439,8 +7461,8 @@
           Selectors.cancel,
           null,
           [streamIterator]);
-      push(new HAwait(pop(), new TypeMask.subclass(compiler.objectClass,
-          compiler.world)));
+      push(new HAwait(pop(), new TypeMask.subclass(
+          coreClasses.objectClass, compiler.world)));
       pop();
     });
   }
@@ -7456,11 +7478,11 @@
     // method is inlined.  We would require full scalar replacement in that
     // case.
 
-    Selector selector = elements.getIteratorSelector(node);
+    Selector selector = Selectors.iterator;
     TypeMask mask = elements.getIteratorTypeMask(node);
 
     ClassWorld classWorld = compiler.world;
-    if (mask != null && mask.satisfies(backend.jsIndexableClass, classWorld)) {
+    if (mask != null && mask.satisfies(helpers.jsIndexableClass, classWorld)) {
       return buildSyncForInIndexable(node, mask);
     }
     buildSyncForInIterator(node);
@@ -7478,7 +7500,7 @@
     HInstruction iterator;
 
     void buildInitializer() {
-      Selector selector = elements.getIteratorSelector(node);
+      Selector selector = Selectors.iterator;
       TypeMask mask = elements.getIteratorTypeMask(node);
       visit(node.expression);
       HInstruction receiver = pop();
@@ -7487,14 +7509,14 @@
     }
 
     HInstruction buildCondition() {
-      Selector selector = elements.getMoveNextSelector(node);
+      Selector selector = Selectors.moveNext;
       TypeMask mask = elements.getMoveNextTypeMask(node);
       pushInvokeDynamic(node, selector, mask, [iterator]);
       return popBoolified();
     }
 
     void buildBody() {
-      Selector call = elements.getCurrentSelector(node);
+      Selector call = Selectors.current;
       TypeMask mask = elements.getCurrentTypeMask(node);
       pushInvokeDynamic(node, call, mask, [iterator]);
       buildAssignLoopVariable(node, pop());
@@ -7547,7 +7569,7 @@
     HInstruction originalLength = null;  // Set for growable lists.
 
     HInstruction buildGetLength() {
-      Element lengthElement = backend.jsIndexableLength;
+      Element lengthElement = helpers.jsIndexableLength;
       HFieldGet result = new HFieldGet(
           lengthElement, array, backend.positiveIntType,
           isAssignable: !isFixed);
@@ -7693,9 +7715,9 @@
     List<HInstruction> inputs = <HInstruction>[];
 
     if (listInputs.isEmpty) {
-      constructor = backend.mapLiteralConstructorEmpty;
+      constructor = helpers.mapLiteralConstructorEmpty;
     } else {
-      constructor = backend.mapLiteralConstructor;
+      constructor = helpers.mapLiteralConstructor;
       HLiteralList keyValuePairs = buildLiteralList(listInputs);
       add(keyValuePairs);
       inputs.add(keyValuePairs);
@@ -7723,9 +7745,9 @@
       // in the output.
       if (typeInputs.every((HInstruction input) => input.isNull())) {
         if (listInputs.isEmpty) {
-          constructor = backend.mapLiteralUntypedEmptyMaker;
+          constructor = helpers.mapLiteralUntypedEmptyMaker;
         } else {
-          constructor = backend.mapLiteralUntypedMaker;
+          constructor = helpers.mapLiteralUntypedMaker;
         }
       } else {
         inputs.addAll(typeInputs);
@@ -7741,7 +7763,7 @@
     // type inference might discover a more specific type, or find nothing (in
     // dart2js unit tests).
     TypeMask mapType =
-        new TypeMask.nonNullSubtype(backend.mapLiteralClass, compiler.world);
+        new TypeMask.nonNullSubtype(helpers.mapLiteralClass, compiler.world);
     TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
         constructor, compiler);
     TypeMask instructionType =
@@ -9083,13 +9105,13 @@
   void visit(DartType type, SsaBuilder builder) => type.accept(this, builder);
 
   void visitVoidType(VoidType type, SsaBuilder builder) {
-    ClassElement cls = builder.backend.findHelper('VoidRuntimeType');
+    ClassElement cls = builder.backend.helpers.VoidRuntimeType;
     builder.push(new HVoidType(type, new TypeMask.exact(cls, classWorld)));
   }
 
   void visitTypeVariableType(TypeVariableType type,
                              SsaBuilder builder) {
-    ClassElement cls = builder.backend.findHelper('RuntimeType');
+    ClassElement cls = builder.backend.helpers.RuntimeType;
     TypeMask instructionType = new TypeMask.subclass(cls, classWorld);
     if (!builder.sourceElement.enclosingElement.isClosure &&
         builder.sourceElement.isInstanceMember) {
@@ -9127,7 +9149,7 @@
       inputs.add(builder.pop());
     }
 
-    ClassElement cls = builder.backend.findHelper('RuntimeFunctionType');
+    ClassElement cls = builder.backend.helpers.RuntimeFunctionType;
     builder.push(new HFunctionType(inputs, type,
         new TypeMask.exact(cls, classWorld)));
   }
@@ -9148,9 +9170,9 @@
     }
     ClassElement cls;
     if (type.typeArguments.isEmpty) {
-      cls = builder.backend.findHelper('RuntimeTypePlain');
+      cls = builder.backend.helpers.RuntimeTypePlain;
     } else {
-      cls = builder.backend.findHelper('RuntimeTypeGeneric');
+      cls = builder.backend.helpers.RuntimeTypeGeneric;
     }
     builder.push(new HInterfaceType(inputs, type,
         new TypeMask.exact(cls, classWorld)));
@@ -9164,7 +9186,7 @@
 
   void visitDynamicType(DynamicType type, SsaBuilder builder) {
     JavaScriptBackend backend = builder.compiler.backend;
-    ClassElement cls = backend.findHelper('DynamicRuntimeType');
+    ClassElement cls = backend.helpers.DynamicRuntimeType;
     builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 1edaf6e..688030a 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -157,12 +157,16 @@
 
   CodegenRegistry get registry => work.registry;
 
+  BackendHelpers get helpers => backend.helpers;
+
   native.NativeEnqueuer get nativeEnqueuer {
     return compiler.enqueuer.codegen.nativeEnqueuer;
   }
 
   DiagnosticReporter get reporter => compiler.reporter;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   bool isGenerateAtUseSite(HInstruction instruction) {
     return generateAtUseSite.contains(instruction);
   }
@@ -704,8 +708,8 @@
           registry.registerInstantiatedClass(classElement);
         }
       }
-      register(backend.jsPlainJavaScriptObjectClass);
-      register(backend.jsUnknownJavaScriptObjectClass);
+      register(helpers.jsPlainJavaScriptObjectClass);
+      register(helpers.jsUnknownJavaScriptObjectClass);
 
       HLocalValue exception = info.catchVariable;
       String name = variableNames.getName(exception);
@@ -1521,7 +1525,7 @@
       js.Name name =
           backend.namer.nameForGetInterceptor(node.interceptedClasses);
       var isolate = new js.VariableUse(
-          backend.namer.globalObjectFor(backend.interceptorsLibrary));
+          backend.namer.globalObjectFor(helpers.interceptorsLibrary));
       use(node.receiver);
       List<js.Expression> arguments = <js.Expression>[pop()];
       push(js.propertyCall(isolate, name, arguments)
@@ -1539,21 +1543,21 @@
 
     // TODO(herhut): The namer should return the appropriate backendname here.
     if (target != null && !node.isInterceptedCall) {
-      if (target == backend.jsArrayAdd) {
+      if (target == helpers.jsArrayAdd) {
         methodName = 'push';
-      } else if (target == backend.jsArrayRemoveLast) {
+      } else if (target == helpers.jsArrayRemoveLast) {
         methodName = 'pop';
-      } else if (target == backend.jsStringSplit) {
+      } else if (target == helpers.jsStringSplit) {
         methodName = 'split';
         // Split returns a List, so we make sure the backend knows the
         // list class is instantiated.
-        registry.registerInstantiatedClass(compiler.listClass);
-      } else if (target.isNative && target.isFunction
+        registry.registerInstantiatedClass(coreClasses.listClass);
+      } else if (backend.isNative(target) && target.isFunction
                  && !node.isInterceptedCall) {
         // A direct (i.e. non-interceptor) native call is the result of
         // optimization.  The optimization ensures any type checks or
         // conversions have been satisified.
-        methodName = target.fixedBackendName;
+        methodName = backend.getFixedBackendName(target);
       }
     }
 
@@ -1575,13 +1579,15 @@
     List<js.Expression> arguments = visitArguments(node.inputs);
     push(js.propertyCall(object, methodName, arguments)
          .withSourceInformation(node.sourceInformation));
-    registry.registerStaticUse(node.element);
+    registry.registerStaticUse(
+        new StaticUse.constructorBodyInvoke(
+            node.element, new CallStructure.unnamed(arguments.length)));
   }
 
   void visitOneShotInterceptor(HOneShotInterceptor node) {
     List<js.Expression> arguments = visitArguments(node.inputs);
     var isolate = new js.VariableUse(
-        backend.namer.globalObjectFor(backend.interceptorsLibrary));
+        backend.namer.globalObjectFor(helpers.interceptorsLibrary));
     Selector selector = node.selector;
     TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
     js.Name methodName = backend.registerOneShotInterceptor(selector);
@@ -1637,25 +1643,25 @@
       // may know something about the types of closures that need
       // the specific closure call method.
       Selector call = new Selector.callClosureFrom(selector);
-      registry.registerDynamicInvocation(
-          new UniverseSelector(call, null));
+      registry.registerDynamicUse(
+          new DynamicUse(call, null));
     }
-    registry.registerDynamicInvocation(
-        new UniverseSelector(selector, mask));
+    registry.registerDynamicUse(
+        new DynamicUse(selector, mask));
   }
 
   void registerSetter(HInvokeDynamic node) {
     Selector selector = node.selector;
     TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
-    registry.registerDynamicSetter(
-        new UniverseSelector(selector, mask));
+    registry.registerDynamicUse(
+        new DynamicUse(selector, mask));
   }
 
   void registerGetter(HInvokeDynamic node) {
     Selector selector = node.selector;
     TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
-    registry.registerDynamicGetter(
-        new UniverseSelector(selector, mask));
+    registry.registerDynamicUse(
+        new DynamicUse(selector, mask));
   }
 
   visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
@@ -1681,8 +1687,8 @@
                          backend.namer.invocationName(call),
                          visitArguments(node.inputs))
             .withSourceInformation(node.sourceInformation));
-    registry.registerDynamicInvocation(
-        new UniverseSelector(call, null));
+    registry.registerDynamicUse(
+        new DynamicUse(call, null));
   }
 
   visitInvokeStatic(HInvokeStatic node) {
@@ -1691,7 +1697,7 @@
 
     if (instantiatedTypes != null && !instantiatedTypes.isEmpty) {
       instantiatedTypes.forEach((type) {
-        registry.registerInstantiatedType(type);
+        registry.registerInstantiation(type);
       });
     }
 
@@ -1706,7 +1712,8 @@
 
       assert(arguments.length == 2);
       Element throwFunction = backend.helpers.throwConcurrentModificationError;
-      registry.registerStaticInvocation(throwFunction);
+      registry.registerStaticUse(
+          new StaticUse.staticInvoke(throwFunction, CallStructure.ONE_ARG));
 
       // Calling using `(0, #)(#)` instead of `#(#)` separates the property load
       // of the static function access from the call.  For some reason this
@@ -1720,7 +1727,11 @@
           backend.emitter.staticFunctionAccess(throwFunction),
           arguments[1]]));
     } else {
-      registry.registerStaticInvocation(element);
+      CallStructure callStructure = new CallStructure.unnamed(arguments.length);
+      registry.registerStaticUse(
+          element.isConstructor
+            ? new StaticUse.constructorInvoke(element, callStructure)
+            : new StaticUse.staticInvoke(element, callStructure));
       push(backend.emitter.staticFunctionAccess(element));
       push(new js.Call(pop(), arguments,
           sourceInformation: node.sourceInformation));
@@ -1729,47 +1740,47 @@
   }
 
   visitInvokeSuper(HInvokeSuper node) {
-    Element superMethod = node.element;
-    registry.registerSuperInvocation(superMethod);
-    ClassElement superClass = superMethod.enclosingClass;
-    if (superMethod.kind == ElementKind.FIELD) {
+    Element superElement = node.element;
+    ClassElement superClass = superElement.enclosingClass;
+    if (superElement.isField) {
       js.Name fieldName =
-          backend.namer.instanceFieldPropertyName(superMethod);
+          backend.namer.instanceFieldPropertyName(superElement);
       use(node.inputs[0]);
       js.PropertyAccess access =
           new js.PropertyAccess(pop(), fieldName)
               .withSourceInformation(node.sourceInformation);
       if (node.isSetter) {
+        registry.registerStaticUse(
+            superElement.isSetter
+                ? new StaticUse.superSetterSet(superElement)
+                : new StaticUse.superFieldSet(superElement));
         use(node.value);
         push(new js.Assignment(access, pop())
             .withSourceInformation(node.sourceInformation));
       } else {
+        registry.registerStaticUse(new StaticUse.superGet(superElement));
         push(access);
       }
     } else {
       Selector selector = node.selector;
-
-      if (!backend.maybeRegisterAliasedSuperMember(superMethod, selector)) {
+      if (!backend.maybeRegisterAliasedSuperMember(superElement, selector)) {
         js.Name methodName;
-        if (selector.isGetter) {
-          // If the selector we need to register a typed getter to the
-          // [world]. The emitter needs to know if it needs to emit a
-          // bound closure for a method.
-
-          // If [superMethod] is mixed in, [superClass] might not be live.
-          // We use the superclass of the access instead.
-          TypeMask receiverType =
-              new TypeMask.nonNullExact(node.caller.superclass, compiler.world);
-          // TODO(floitsch): we know the target. We shouldn't register a
-          // dynamic getter.
-          registry.registerDynamicGetter(
-              new UniverseSelector(selector, receiverType));
-          registry.registerGetterForSuperMethod(node.element);
+        if (selector.isGetter && !superElement.isGetter) {
+          // If this is a tear-off, register the fact that a tear-off closure
+          // will be created, and that this tear-off must bypass ordinary
+          // dispatch to ensure the super method is invoked.
+          FunctionElement helper = backend.helpers.closureFromTearOff;
+          registry.registerStaticUse(new StaticUse.staticInvoke(helper,
+                new CallStructure.unnamed(helper.parameters.length)));
+          registry.registerStaticUse(new StaticUse.superTearOff(node.element));
           methodName = backend.namer.invocationName(selector);
         } else {
-          assert(invariant(node, compiler.hasIncrementalSupport));
-          methodName = backend.namer.instanceMethodName(superMethod);
+          methodName = backend.namer.instanceMethodName(superElement);
         }
+        registry.registerStaticUse(
+            new StaticUse.superInvoke(
+                superElement,
+                new CallStructure.unnamed(node.inputs.length)));
         push(js.js('#.#.call(#)',
                    [backend.emitter.prototypeAccess(superClass,
                                                     hasBeenInstantiated: true),
@@ -1777,9 +1788,13 @@
                 .withSourceInformation(node.sourceInformation));
       } else {
         use(node.receiver);
+        registry.registerStaticUse(
+            new StaticUse.superInvoke(
+                superElement,
+                new CallStructure.unnamed(node.inputs.length - 1)));
         push(
           js.js('#.#(#)', [
-            pop(), backend.namer.aliasedSuperMemberPropertyName(superMethod),
+            pop(), backend.namer.aliasedSuperMemberPropertyName(superElement),
             visitArguments(node.inputs, start: 1)]) // Skip receiver argument.
               .withSourceInformation(node.sourceInformation));
       }
@@ -1795,7 +1810,7 @@
       // that does not exist.
       push(new js.PropertyAccess.field(pop(), 'toString')
           .withSourceInformation(node.sourceInformation));
-    } else if (element == backend.jsIndexableLength) {
+    } else if (element == helpers.jsIndexableLength) {
       // We're accessing a native JavaScript property called 'length'
       // on a JS String or a JS array. Therefore, the name of that
       // property should not be mangled.
@@ -1805,13 +1820,13 @@
       js.Name name = backend.namer.instanceFieldPropertyName(element);
       push(new js.PropertyAccess(pop(), name)
           .withSourceInformation(node.sourceInformation));
-      registry.registerFieldGetter(element);
+      registry.registerStaticUse(new StaticUse.fieldGet(element));
     }
   }
 
   visitFieldSet(HFieldSet node) {
     Element element = node.element;
-    registry.registerFieldSetter(element);
+    registry.registerStaticUse(new StaticUse.fieldSet(element));
     js.Name name = backend.namer.instanceFieldPropertyName(element);
     use(node.receiver);
     js.Expression receiver = pop();
@@ -1822,7 +1837,8 @@
 
   visitReadModifyWrite(HReadModifyWrite node) {
     Element element = node.element;
-    registry.registerFieldSetter(element);
+    registry.registerStaticUse(new StaticUse.fieldGet(element));
+    registry.registerStaticUse(new StaticUse.fieldSet(element));
     js.Name name = backend.namer.instanceFieldPropertyName(element);
     use(node.receiver);
     js.Expression fieldReference = new js.PropertyAccess(pop(), name);
@@ -1897,7 +1913,7 @@
       return;
     }
     node.instantiatedTypes.forEach((type) {
-      registry.registerInstantiatedType(type);
+      registry.registerInstantiation(type);
     });
   }
 
@@ -1917,7 +1933,8 @@
                         SourceInformation sourceInformation) {
     if (constant.isFunction) {
       FunctionConstantValue function = constant;
-      registry.registerStaticUse(function.element);
+      registry.registerStaticUse(
+          new StaticUse.staticTearOff(function.element));
     }
     if (constant.isType) {
       // If the type is a web component, we need to ensure the constructors are
@@ -2078,7 +2095,7 @@
       pushStatement(new js.Throw(pop())
           .withSourceInformation(node.sourceInformation));
     } else {
-      generateThrowWithHelper('wrapException', node.inputs[0],
+      generateThrowWithHelper(helpers.wrapExceptionHelper, node.inputs[0],
           sourceInformation: node.sourceInformation);
     }
   }
@@ -2139,20 +2156,20 @@
       js.Statement thenBody = new js.Block.empty();
       js.Block oldContainer = currentContainer;
       currentContainer = thenBody;
-      generateThrowWithHelper('ioore', [node.array, node.reportedIndex]);
+      generateThrowWithHelper(helpers.throwIndexOutOfRangeException,
+          [node.array, node.reportedIndex]);
       currentContainer = oldContainer;
       thenBody = unwrapStatement(thenBody);
       pushStatement(new js.If.noElse(underOver, thenBody)
           .withSourceInformation(node.sourceInformation));
     } else {
-      generateThrowWithHelper('ioore', [node.array, node.index]);
+      generateThrowWithHelper(helpers.throwIndexOutOfRangeException,
+          [node.array, node.index]);
     }
   }
 
-  void generateThrowWithHelper(String helperName, argument,
+  void generateThrowWithHelper(Element helper, argument,
                                {SourceInformation sourceInformation}) {
-    Element helper = backend.findHelper(helperName);
-    registry.registerStaticUse(helper);
     js.Expression jsHelper = backend.emitter.staticFunctionAccess(helper);
     List arguments = [];
     var location;
@@ -2167,12 +2184,15 @@
       use(argument);
       arguments.add(pop());
     }
+    registry.registerStaticUse(
+        new StaticUse.staticInvoke(
+            helper, new CallStructure.unnamed(arguments.length)));
     js.Call value = new js.Call(jsHelper, arguments.toList(growable: false),
         sourceInformation: sourceInformation);
     // BUG(4906): Using throw/return here adds to the size of the generated code
     // but it has the advantage of explicitly telling the JS engine that
     // this code path will terminate abruptly. Needs more work.
-    if (helperName == 'wrapException') {
+    if (helper == helpers.wrapExceptionHelper) {
       pushStatement(new js.Throw(value)
           .withSourceInformation(sourceInformation));
     } else {
@@ -2194,8 +2214,9 @@
     HInstruction argument = node.inputs[0];
     use(argument);
 
-    Element helper = backend.findHelper("throwExpression");
-    registry.registerStaticUse(helper);
+    Element helper = helpers.throwExpressionHelper;
+    registry.registerStaticUse(
+        new StaticUse.staticInvoke(helper, CallStructure.ONE_ARG));
 
     js.Expression jsHelper = backend.emitter.staticFunctionAccess(helper);
     js.Call value = new js.Call(jsHelper, [pop()])
@@ -2213,17 +2234,20 @@
     if (element.isFunction) {
       push(backend.emitter.isolateStaticClosureAccess(element)
            .withSourceInformation(node.sourceInformation));
-      registry.registerGetOfStaticFunction(element);
+      registry.registerStaticUse(
+          new StaticUse.staticTearOff(element));
     } else {
       push(backend.emitter.staticFieldAccess(element)
            .withSourceInformation(node.sourceInformation));
+      registry.registerStaticUse(
+          new StaticUse.staticGet(element));
     }
-    registry.registerStaticUse(element);
   }
 
   void visitLazyStatic(HLazyStatic node) {
     Element element = node.element;
-    registry.registerStaticUse(element);
+    registry.registerStaticUse(
+        new StaticUse.staticInit(element));
     js.Expression lazyGetter =
         backend.emitter.isolateLazyInitializerAccess(element);
     js.Call call = new js.Call(lazyGetter, <js.Expression>[],
@@ -2232,7 +2256,8 @@
   }
 
   void visitStaticStore(HStaticStore node) {
-    registry.registerStaticUse(node.element);
+    registry.registerStaticUse(
+        new StaticUse.staticSet(node.element));
     js.Node variable = backend.emitter.staticFieldAccess(node.element);
     use(node.inputs[0]);
     push(new js.Assignment(variable, pop())
@@ -2266,7 +2291,8 @@
       }
     } else {
       Element convertToString = backend.helpers.stringInterpolationHelper;
-      registry.registerStaticUse(convertToString);
+      registry.registerStaticUse(
+          new StaticUse.staticInvoke(convertToString, CallStructure.ONE_ARG));
       js.Expression jsHelper =
           backend.emitter.staticFunctionAccess(convertToString);
       use(input);
@@ -2276,7 +2302,7 @@
   }
 
   void visitLiteralList(HLiteralList node) {
-    registry.registerInstantiatedClass(compiler.listClass);
+    registry.registerInstantiatedClass(coreClasses.listClass);
     generateArrayLiteral(node);
   }
 
@@ -2425,31 +2451,31 @@
                  SourceInformation sourceInformation,
                  {bool negative: false}) {
     Element element = type.element;
-    if (element == backend.jsArrayClass) {
+    if (element == helpers.jsArrayClass) {
       checkArray(input, negative ? '!==': '===');
       return;
-    } else if (element == backend.jsMutableArrayClass) {
+    } else if (element == helpers.jsMutableArrayClass) {
       if (negative) {
         checkImmutableArray(input);
       } else {
         checkMutableArray(input);
       }
       return;
-    } else if (element == backend.jsExtendableArrayClass) {
+    } else if (element == helpers.jsExtendableArrayClass) {
       if (negative) {
         checkFixedArray(input);
       } else {
         checkExtendableArray(input);
       }
       return;
-    } else if (element == backend.jsFixedArrayClass) {
+    } else if (element == helpers.jsFixedArrayClass) {
       if (negative) {
         checkExtendableArray(input);
       } else {
         checkFixedArray(input);
       }
       return;
-    } else if (element == backend.jsUnmodifiableArrayClass) {
+    } else if (element == helpers.jsUnmodifiableArrayClass) {
       if (negative) {
         checkMutableArray(input);
       } else {
@@ -2468,7 +2494,7 @@
   void checkTypeViaProperty(HInstruction input, DartType type,
                             SourceInformation sourceInformation,
                             {bool negative: false}) {
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
 
     use(input);
 
@@ -2489,7 +2515,7 @@
       HInstruction input, DartType type,
       SourceInformation sourceInformation,
       {bool negative: false}) {
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
 
     use(input);
 
@@ -2501,7 +2527,7 @@
       push(new js.Prefix('!', pop())
           .withSourceInformation(sourceInformation));
     }
-    registry.registerInstantiatedType(type);
+    registry.registerInstantiation(type);
   }
 
   void handleNumberOrStringSupertypeCheck(HInstruction input,
@@ -2509,7 +2535,7 @@
                                           DartType type,
                                           SourceInformation sourceInformation,
                                           {bool negative: false}) {
-    assert(!identical(type.element, compiler.listClass) &&
+    assert(!identical(type.element, coreClasses.listClass) &&
            !Elements.isListSupertype(type.element, compiler) &&
            !Elements.isStringOnlySupertype(type.element, compiler));
     String relation = negative ? '!==' : '===';
@@ -2535,7 +2561,7 @@
                                   DartType type,
                                   SourceInformation sourceInformation,
                                   {bool negative: false}) {
-    assert(!identical(type.element, compiler.listClass)
+    assert(!identical(type.element, coreClasses.listClass)
            && !Elements.isListSupertype(type.element, compiler)
            && !Elements.isNumberOrStringSupertype(type.element, compiler));
     String relation = negative ? '!==' : '===';
@@ -2555,7 +2581,7 @@
                                   DartType type,
                                   SourceInformation sourceInformation,
                                   { bool negative: false }) {
-    assert(!identical(type.element, compiler.stringClass)
+    assert(!identical(type.element, coreClasses.stringClass)
            && !Elements.isStringOnlySupertype(type.element, compiler)
            && !Elements.isNumberOrStringSupertype(type.element, compiler));
     String relation = negative ? '!==' : '===';
@@ -2581,7 +2607,7 @@
 
   void emitIs(HIs node, String relation, SourceInformation sourceInformation)  {
     DartType type = node.typeExpression;
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
     HInstruction input = node.expression;
 
     // If this is changed to single == there are several places below that must
@@ -2595,9 +2621,9 @@
     } else {
       assert(node.isRawCheck);
       HInstruction interceptor = node.interceptor;
-      ClassElement objectClass = compiler.objectClass;
+      ClassElement objectClass = coreClasses.objectClass;
       Element element = type.element;
-      if (element == compiler.nullClass) {
+      if (element == coreClasses.nullClass) {
         if (negative) {
           checkNonNull(input);
         } else {
@@ -2607,15 +2633,15 @@
         // The constant folder also does this optimization, but we make
         // it safe by assuming it may have not run.
         push(newLiteralBool(!negative, sourceInformation));
-      } else if (element == compiler.stringClass) {
+      } else if (element == coreClasses.stringClass) {
         checkString(input, relation, sourceInformation);
-      } else if (element == compiler.doubleClass) {
+      } else if (element == coreClasses.doubleClass) {
         checkDouble(input, relation, sourceInformation);
-      } else if (element == compiler.numClass) {
+      } else if (element == coreClasses.numClass) {
         checkNum(input, relation, sourceInformation);
-      } else if (element == compiler.boolClass) {
+      } else if (element == coreClasses.boolClass) {
         checkBool(input, relation, sourceInformation);
-      } else if (element == compiler.intClass) {
+      } else if (element == coreClasses.intClass) {
         // The is check in the code tells us that it might not be an
         // int. So we do a typeof first to avoid possible
         // deoptimizations on the JS engine due to the Math.floor check.
@@ -2639,7 +2665,7 @@
             input, interceptor, type,
             sourceInformation,
             negative: negative);
-      } else if (identical(element, compiler.listClass) ||
+      } else if (identical(element, coreClasses.listClass) ||
                  Elements.isListSupertype(element, compiler)) {
         handleListOrSupertypeCheck(
             input, interceptor, type,
@@ -2688,7 +2714,7 @@
     bool turnIntoNullCheck = !turnIntoNumCheck
         && (checkedType.nullable() == inputType)
         && (isIntCheck
-            || checkedType.satisfies(backend.jsIndexableClass, classWorld));
+            || checkedType.satisfies(helpers.jsIndexableClass, classWorld));
 
     if (turnIntoNullCheck) {
       use(input);
@@ -2729,7 +2755,8 @@
       js.Statement body = new js.Block.empty();
       currentContainer = body;
       if (node.isArgumentTypeCheck) {
-        generateThrowWithHelper('iae',
+        generateThrowWithHelper(
+            helpers.throwIllegalArgumentException,
             node.checkedInput,
             sourceInformation: node.sourceInformation);
       } else if (node.isReceiverTypeCheck) {
@@ -2752,9 +2779,10 @@
     if (type.isFunctionType) {
       // TODO(5022): We currently generate $isFunction checks for
       // function types.
-      registry.registerIsCheck(compiler.functionClass.rawType);
+      registry.registerTypeUse(
+          new TypeUse.isCheck(compiler.coreTypes.functionType));
     }
-    registry.registerIsCheck(type);
+    registry.registerTypeUse(new TypeUse.isCheck(type));
 
     CheckedModeHelper helper;
     if (node.isBooleanConversionCheck) {
@@ -2824,8 +2852,9 @@
 
   void visitReadTypeVariable(HReadTypeVariable node) {
     TypeVariableElement element = node.dartType.element;
-    Element helperElement = backend.findHelper('convertRtiToRuntimeType');
-    registry.registerStaticUse(helperElement);
+    Element helperElement = helpers.convertRtiToRuntimeType;
+    registry.registerStaticUse(
+        new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG));
 
     use(node.inputs[0]);
     if (node.hasReceiver) {
@@ -2843,8 +2872,7 @@
       }
     } else {
       push(js.js('#(#)', [
-          backend.emitter.staticFunctionAccess(
-              backend.findHelper('convertRtiToRuntimeType')),
+          backend.emitter.staticFunctionAccess(helperElement),
           pop()]));
     }
   }
@@ -2861,7 +2889,8 @@
     if (!typeArguments.isEmpty) {
       arguments.add(new js.ArrayInitializer(typeArguments));
     }
-    push(js.js('#(#)', [accessHelper('buildInterfaceType'), arguments]));
+    push(js.js('#(#)',
+        [accessHelper('buildInterfaceType', arguments.length), arguments]));
   }
 
   void visitVoidType(HVoidType node) {
@@ -2872,13 +2901,15 @@
     push(js.js('#()', accessHelper('getDynamicRuntimeType')));
   }
 
-  js.PropertyAccess accessHelper(String name) {
-    Element helper = backend.findHelper(name);
+  js.PropertyAccess accessHelper(String name, [int argumentCount = 0]) {
+    Element helper = helpers.findHelper(name);
     if (helper == null) {
       // For mocked-up tests.
       return js.js('(void 0).$name');
     }
-    registry.registerStaticUse(helper);
+    registry.registerStaticUse(
+        new StaticUse.staticInvoke(helper,
+            new CallStructure.unnamed(argumentCount)));
     return backend.emitter.staticFunctionAccess(helper);
   }
 
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 97b4b17..9cfb66b 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -34,6 +34,12 @@
 
   SsaSimplifyInterceptors(this.compiler, this.constantSystem, this.work);
 
+  JavaScriptBackend get backend => compiler.backend;
+
+  BackendHelpers get helpers => backend.helpers;
+
+  ClassWorld get classWorld => compiler.world;
+
   void visitGraph(HGraph graph) {
     this.graph = graph;
     visitDominatorTree(graph);
@@ -80,22 +86,20 @@
 
   bool canUseSelfForInterceptor(HInstruction receiver,
                                 Set<ClassElement> interceptedClasses) {
-    JavaScriptBackend backend = compiler.backend;
-    ClassWorld classWorld = compiler.world;
 
     if (receiver.canBePrimitive(compiler)) {
       // Primitives always need interceptors.
       return false;
     }
     if (receiver.canBeNull() &&
-        interceptedClasses.contains(backend.jsNullClass)) {
+        interceptedClasses.contains(helpers.jsNullClass)) {
       // Need the JSNull interceptor.
       return false;
     }
 
     // All intercepted classes extend `Interceptor`, so if the receiver can't be
     // a class extending `Interceptor` then it can be called directly.
-    return new TypeMask.nonNullSubclass(backend.jsInterceptorClass, classWorld)
+    return new TypeMask.nonNullSubclass(helpers.jsInterceptorClass, classWorld)
         .intersection(receiver.instructionType, classWorld)
         .isEmpty;
   }
@@ -131,29 +135,27 @@
       TypeMask type,
       Set<ClassElement> interceptedClasses) {
 
-    ClassWorld classWorld = compiler.world;
-    JavaScriptBackend backend = compiler.backend;
     if (type.isNullable) {
       if (type.isEmpty) {
-        return backend.jsNullClass;
+        return helpers.jsNullClass;
       }
     } else if (type.containsOnlyInt(classWorld)) {
-      return backend.jsIntClass;
+      return helpers.jsIntClass;
     } else if (type.containsOnlyDouble(classWorld)) {
-      return backend.jsDoubleClass;
+      return helpers.jsDoubleClass;
     } else if (type.containsOnlyBool(classWorld)) {
-      return backend.jsBoolClass;
+      return helpers.jsBoolClass;
     } else if (type.containsOnlyString(classWorld)) {
-      return backend.jsStringClass;
-    } else if (type.satisfies(backend.jsArrayClass, classWorld)) {
-      return backend.jsArrayClass;
+      return helpers.jsStringClass;
+    } else if (type.satisfies(helpers.jsArrayClass, classWorld)) {
+      return helpers.jsArrayClass;
     } else if (type.containsOnlyNum(classWorld) &&
-        !interceptedClasses.contains(backend.jsIntClass) &&
-        !interceptedClasses.contains(backend.jsDoubleClass)) {
+        !interceptedClasses.contains(helpers.jsIntClass) &&
+        !interceptedClasses.contains(helpers.jsDoubleClass)) {
       // If the method being intercepted is not defined in [int] or [double] we
       // can safely use the number interceptor.  This is because none of the
       // [int] or [double] methods are called from a method defined on [num].
-      return backend.jsNumberClass;
+      return helpers.jsNumberClass;
     } else {
       // Try to find constant interceptor for a native class.  If the receiver
       // is constrained to a leaf native class, we can use the class's
@@ -167,7 +169,7 @@
       // code is completely insensitive to the specific instance subclasses, we
       // can use the non-leaf class directly.
       ClassElement element = type.singleClass(classWorld);
-      if (element != null && element.isNative) {
+      if (element != null && backend.isNative(element)) {
         return element;
       }
     }
@@ -209,7 +211,6 @@
         user.inputs.where((input) => input == used).length;
 
     Set<ClassElement> interceptedClasses;
-    JavaScriptBackend backend = compiler.backend;
     HInstruction dominator = findDominator(node.usedBy);
     // If there is a call that dominates all other uses, we can use just the
     // selector of that instruction.
@@ -222,18 +223,18 @@
 
       // If we found that we need number, we must still go through all
       // uses to check if they require int, or double.
-      if (interceptedClasses.contains(backend.jsNumberClass) &&
-          !(interceptedClasses.contains(backend.jsDoubleClass) ||
-            interceptedClasses.contains(backend.jsIntClass))) {
+      if (interceptedClasses.contains(helpers.jsNumberClass) &&
+          !(interceptedClasses.contains(helpers.jsDoubleClass) ||
+            interceptedClasses.contains(helpers.jsIntClass))) {
         for (HInstruction user in node.usedBy) {
           if (user is! HInvoke) continue;
           Set<ClassElement> intercepted =
               backend.getInterceptedClassesOn(user.selector.name);
-          if (intercepted.contains(backend.jsIntClass)) {
-            interceptedClasses.add(backend.jsIntClass);
+          if (intercepted.contains(helpers.jsIntClass)) {
+            interceptedClasses.add(helpers.jsIntClass);
           }
-          if (intercepted.contains(backend.jsDoubleClass)) {
-            interceptedClasses.add(backend.jsDoubleClass);
+          if (intercepted.contains(helpers.jsDoubleClass)) {
+            interceptedClasses.add(helpers.jsDoubleClass);
           }
         }
       }
@@ -291,7 +292,7 @@
     // constant interceptor `C`.  Then we can use `(receiver && C)` for the
     // interceptor.
     if (receiver.canBeNull() && !node.isConditionalConstantInterceptor) {
-      if (!interceptedClasses.contains(backend.jsNullClass)) {
+      if (!interceptedClasses.contains(helpers.jsNullClass)) {
         // Can use `(receiver && C)` only if receiver is either null or truthy.
         if (!(receiver.canBePrimitiveNumber(compiler) ||
             receiver.canBePrimitiveBoolean(compiler) ||
@@ -331,7 +332,6 @@
       // See if we can rewrite the is-check to use 'instanceof', i.e. rewrite
       // "getInterceptor(x).$isT" to "x instanceof T".
       if (node == user.interceptor) {
-        JavaScriptBackend backend = compiler.backend;
         if (backend.mayGenerateInstanceofCheck(user.typeExpression)) {
           HInstruction instanceofCheck = new HIs.instanceOf(
               user.typeExpression, user.expression, user.instructionType);
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index e0c5611..754ed27 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -238,7 +238,8 @@
                                      Compiler compiler) {
     if (selector.name == name) return selector;
     JavaScriptBackend backend = compiler.backend;
-    return new Selector.call(new Name(name, backend.interceptorsLibrary),
+    return new Selector.call(
+        new Name(name, backend.helpers.interceptorsLibrary),
         new CallStructure(selector.argumentCount));
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 08f6987..0e1788b 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -922,75 +922,84 @@
   bool canBePrimitiveNumber(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     // TODO(sra): It should be possible to test only jsDoubleClass and
     // jsUInt31Class, since all others are superclasses of these two.
-    return containsType(instructionType, backend.jsNumberClass, classWorld)
-        || containsType(instructionType, backend.jsIntClass, classWorld)
-        || containsType(instructionType, backend.jsPositiveIntClass, classWorld)
-        || containsType(instructionType, backend.jsUInt32Class, classWorld)
-        || containsType(instructionType, backend.jsUInt31Class, classWorld)
-        || containsType(instructionType, backend.jsDoubleClass, classWorld);
+    return containsType(instructionType, helpers.jsNumberClass, classWorld)
+        || containsType(instructionType, helpers.jsIntClass, classWorld)
+        || containsType(instructionType, helpers.jsPositiveIntClass, classWorld)
+        || containsType(instructionType, helpers.jsUInt32Class, classWorld)
+        || containsType(instructionType, helpers.jsUInt31Class, classWorld)
+        || containsType(instructionType, helpers.jsDoubleClass, classWorld);
   }
 
   bool canBePrimitiveBoolean(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
-    return containsType(instructionType, backend.jsBoolClass, classWorld);
+    BackendHelpers helpers = backend.helpers;
+    return containsType(instructionType, helpers.jsBoolClass, classWorld);
   }
 
   bool canBePrimitiveArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
-    return containsType(instructionType, backend.jsArrayClass, classWorld)
-        || containsType(instructionType, backend.jsFixedArrayClass, classWorld)
+    BackendHelpers helpers = backend.helpers;
+    return containsType(instructionType, helpers.jsArrayClass, classWorld)
+        || containsType(instructionType, helpers.jsFixedArrayClass, classWorld)
         || containsType(
-            instructionType, backend.jsExtendableArrayClass, classWorld)
+            instructionType, helpers.jsExtendableArrayClass, classWorld)
         || containsType(instructionType,
-            backend.jsUnmodifiableArrayClass, classWorld);
+            helpers.jsUnmodifiableArrayClass, classWorld);
   }
 
   bool isIndexablePrimitive(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return instructionType.containsOnlyString(classWorld)
-        || isInstanceOf(instructionType, backend.jsIndexableClass, classWorld);
+        || isInstanceOf(instructionType, helpers.jsIndexableClass, classWorld);
   }
 
   bool isFixedArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     // TODO(sra): Recognize the union of these types as well.
     return containsOnlyType(
-            instructionType, backend.jsFixedArrayClass, classWorld)
+            instructionType, helpers.jsFixedArrayClass, classWorld)
         || containsOnlyType(
-            instructionType, backend.jsUnmodifiableArrayClass, classWorld);
+            instructionType, helpers.jsUnmodifiableArrayClass, classWorld);
   }
 
   bool isExtendableArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return containsOnlyType(
-        instructionType, backend.jsExtendableArrayClass, classWorld);
+        instructionType, helpers.jsExtendableArrayClass, classWorld);
   }
 
   bool isMutableArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return isInstanceOf(
-        instructionType, backend.jsMutableArrayClass, classWorld);
+        instructionType, helpers.jsMutableArrayClass, classWorld);
   }
 
   bool isReadableArray(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
-    return isInstanceOf(instructionType, backend.jsArrayClass, classWorld);
+    BackendHelpers helpers = backend.helpers;
+    return isInstanceOf(instructionType, helpers.jsArrayClass, classWorld);
   }
 
   bool isMutableIndexable(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return isInstanceOf(instructionType,
-        backend.jsMutableIndexableClass, classWorld);
+        helpers.jsMutableIndexableClass, classWorld);
   }
 
   bool isArray(Compiler compiler) => isReadableArray(compiler);
@@ -998,7 +1007,8 @@
   bool canBePrimitiveString(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
-    return containsType(instructionType, backend.jsStringClass, classWorld);
+    BackendHelpers helpers = backend.helpers;
+    return containsType(instructionType, helpers.jsStringClass, classWorld);
   }
 
   bool isInteger(Compiler compiler) {
@@ -1010,29 +1020,33 @@
   bool isUInt32(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return !instructionType.isNullable
-        && isInstanceOf(instructionType, backend.jsUInt32Class, classWorld);
+        && isInstanceOf(instructionType, helpers.jsUInt32Class, classWorld);
   }
 
   bool isUInt31(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return !instructionType.isNullable
-        && isInstanceOf(instructionType, backend.jsUInt31Class, classWorld);
+        && isInstanceOf(instructionType, helpers.jsUInt31Class, classWorld);
   }
 
   bool isPositiveInteger(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return !instructionType.isNullable &&
-        isInstanceOf(instructionType, backend.jsPositiveIntClass, classWorld);
+        isInstanceOf(instructionType, helpers.jsPositiveIntClass, classWorld);
   }
 
   bool isPositiveIntegerOrNull(Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     return isInstanceOf(
-        instructionType, backend.jsPositiveIntClass, classWorld);
+        instructionType, helpers.jsPositiveIntClass, classWorld);
   }
 
   bool isIntegerOrNull(Compiler compiler) {
@@ -1319,9 +1333,9 @@
     assert(type.kind != TypeKind.TYPE_VARIABLE);
     assert(type.treatAsRaw || type.isFunctionType);
     if (type.isDynamic) return this;
+    if (type.isObject) return this;
     // The type element is either a class or the void element.
     Element element = type.element;
-    if (identical(element, compiler.objectClass)) return this;
     JavaScriptBackend backend = compiler.backend;
     if (type.kind != TypeKind.INTERFACE) {
       return new HTypeConversion(type, kind, backend.dynamicType, this);
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 563b503..c98ceb1 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -111,8 +111,8 @@
     return true;
   }
   // TODO(sra): Recognize any combination of fixed length indexables.
-  if (mask.containsOnly(backend.jsFixedArrayClass) ||
-      mask.containsOnly(backend.jsUnmodifiableArrayClass) ||
+  if (mask.containsOnly(backend.helpers.jsFixedArrayClass) ||
+      mask.containsOnly(backend.helpers.jsUnmodifiableArrayClass) ||
       mask.containsOnlyString(classWorld) ||
       backend.isTypedArray(mask)) {
     return true;
@@ -145,6 +145,10 @@
                            this.optimizer,
                            this.work);
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  BackendHelpers get helpers => backend.helpers;
+
   void visitGraph(HGraph visitee) {
     graph = visitee;
     visitDominatorTree(visitee);
@@ -250,7 +254,7 @@
 
     // All values that cannot be 'true' are boolified to false.
     TypeMask mask = input.instructionType;
-    if (!mask.contains(backend.jsBoolClass, compiler.world)) {
+    if (!mask.contains(helpers.jsBoolClass, compiler.world)) {
       return graph.addConstantBool(false, compiler);
     }
     return node;
@@ -297,17 +301,17 @@
         ListConstantValue constant = constantInput.constant;
         return graph.addConstantInt(constant.length, compiler);
       }
-      Element element = backend.jsIndexableLength;
+      Element element = helpers.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 (HInstruction.isInstanceOf(
-              actualType, backend.jsUInt31Class, classWorld)) {
+              actualType, helpers.jsUInt31Class, classWorld)) {
         resultType = backend.uint31Type;
       } else if (HInstruction.isInstanceOf(
-              actualType, backend.jsUInt32Class, classWorld)) {
+              actualType, helpers.jsUInt32Class, classWorld)) {
         resultType = backend.uint32Type;
       }
       HFieldGet result = new HFieldGet(
@@ -351,22 +355,22 @@
     if (selector.isCall || selector.isOperator) {
       Element target;
       if (input.isExtendableArray(compiler)) {
-        if (applies(backend.jsArrayRemoveLast)) {
-          target = backend.jsArrayRemoveLast;
-        } else if (applies(backend.jsArrayAdd)) {
+        if (applies(helpers.jsArrayRemoveLast)) {
+          target = helpers.jsArrayRemoveLast;
+        } else if (applies(helpers.jsArrayAdd)) {
           // The codegen special cases array calls, but does not
           // inline argument type checks.
           if (!compiler.enableTypeAssertions) {
-            target = backend.jsArrayAdd;
+            target = helpers.jsArrayAdd;
           }
         }
       } else if (input.isStringOrNull(compiler)) {
-        if (applies(backend.jsStringSplit)) {
+        if (applies(helpers.jsStringSplit)) {
           HInstruction argument = node.inputs[2];
           if (argument.isString(compiler)) {
-            target = backend.jsStringSplit;
+            target = helpers.jsStringSplit;
           }
-        } else if (applies(backend.jsStringOperatorAdd)) {
+        } else if (applies(helpers.jsStringOperatorAdd)) {
           // `operator+` is turned into a JavaScript '+' so we need to
           // make sure the receiver and the argument are not null.
           // TODO(sra): Do this via [node.specializer].
@@ -376,7 +380,7 @@
             return new HStringConcat(input, argument, null,
                                      node.instructionType);
           }
-        } else if (applies(backend.jsStringToString)
+        } else if (applies(helpers.jsStringToString)
                    && !input.canBeNull()) {
           return input;
         }
@@ -397,7 +401,7 @@
         return result;
       }
     } else if (selector.isGetter) {
-      if (selector.applies(backend.jsIndexableLength, world)) {
+      if (selector.applies(helpers.jsIndexableLength, world)) {
         HInstruction optimized = tryOptimizeLengthInterceptedGetter(node);
         if (optimized != null) return optimized;
       }
@@ -424,7 +428,7 @@
         && element.name == node.selector.name) {
       FunctionElement method = element;
 
-      if (method.isNative) {
+      if (backend.isNative(method)) {
         HInstruction folded = tryInlineNativeMethod(node, method);
         if (folded != null) return folded;
       } else {
@@ -675,22 +679,22 @@
       return node;
     } else if (type.isTypedef) {
       return node;
-    } else if (element == compiler.functionClass) {
+    } else if (element == coreClasses.functionClass) {
       return node;
     }
 
-    if (element == compiler.objectClass || type.treatAsDynamic) {
+    if (type.isObject || type.treatAsDynamic) {
       return graph.addConstantBool(true, compiler);
     }
 
     ClassWorld classWorld = compiler.world;
     HInstruction expression = node.expression;
     if (expression.isInteger(compiler)) {
-      if (identical(element, compiler.intClass)
-          || identical(element, compiler.numClass)
-          || Elements.isNumberOrStringSupertype(element, compiler)) {
+      if (element == coreClasses.intClass ||
+          element == coreClasses.numClass ||
+          Elements.isNumberOrStringSupertype(element, compiler)) {
         return graph.addConstantBool(true, compiler);
-      } else if (identical(element, compiler.doubleClass)) {
+      } else if (element == coreClasses.doubleClass) {
         // We let the JS semantics decide for that check. Currently
         // the code we emit will always return true.
         return node;
@@ -698,11 +702,11 @@
         return graph.addConstantBool(false, compiler);
       }
     } else if (expression.isDouble(compiler)) {
-      if (identical(element, compiler.doubleClass)
-          || identical(element, compiler.numClass)
-          || Elements.isNumberOrStringSupertype(element, compiler)) {
+      if (element == coreClasses.doubleClass ||
+          element == coreClasses.numClass ||
+          Elements.isNumberOrStringSupertype(element, compiler)) {
         return graph.addConstantBool(true, compiler);
-      } else if (identical(element, compiler.intClass)) {
+      } else if (element == coreClasses.intClass) {
         // We let the JS semantics decide for that check. Currently
         // the code we emit will return true for a double that can be
         // represented as a 31-bit integer and for -0.0.
@@ -711,14 +715,14 @@
         return graph.addConstantBool(false, compiler);
       }
     } else if (expression.isNumber(compiler)) {
-      if (identical(element, compiler.numClass)) {
+      if (element == coreClasses.numClass) {
         return graph.addConstantBool(true, compiler);
       } else {
         // We cannot just return false, because the expression may be of
         // type int or double.
       }
-    } else if (expression.canBePrimitiveNumber(compiler)
-               && identical(element, compiler.intClass)) {
+    } else if (expression.canBePrimitiveNumber(compiler) &&
+               element == coreClasses.intClass) {
       // We let the JS semantics decide for that check.
       return node;
     // We need the [:hasTypeArguments:] check because we don't have
@@ -728,7 +732,7 @@
     } else if (!RuntimeTypes.hasTypeArguments(type)) {
       TypeMask expressionMask = expression.instructionType;
       assert(TypeMask.assertIsNormalized(expressionMask, classWorld));
-      TypeMask typeMask = (element == compiler.nullClass)
+      TypeMask typeMask = (element == coreClasses.nullClass)
           ? new TypeMask.subtype(element, classWorld)
           : new TypeMask.nonNullSubtype(element, classWorld);
       if (expressionMask.union(typeMask, classWorld) == typeMask) {
@@ -781,7 +785,7 @@
   HInstruction visitFieldGet(HFieldGet node) {
     if (node.isNullCheck) return node;
     var receiver = node.receiver;
-    if (node.element == backend.jsIndexableLength) {
+    if (node.element == helpers.jsIndexableLength) {
       JavaScriptItemCompilationContext context = work.compilationContext;
       if (context.allocatedFixedLists.contains(receiver)) {
         // TODO(ngeoffray): checking if the second input is an integer
@@ -858,7 +862,7 @@
     bool isAssignable = !compiler.world.fieldNeverChanges(field);
 
     TypeMask type;
-    if (field.enclosingClass.isNative) {
+    if (backend.isNative(field.enclosingClass)) {
       type = TypeMaskFactory.fromNativeBehavior(
           native.NativeBehavior.ofFieldLoad(field, compiler),
           compiler);
@@ -1003,6 +1007,8 @@
                    this.work,
                    this.boundsChecked);
 
+  BackendHelpers get helpers => backend.helpers;
+
   void visitGraph(HGraph graph) {
     this.graph = graph;
 
@@ -1028,7 +1034,7 @@
                                  HInstruction indexArgument) {
     Compiler compiler = backend.compiler;
     HFieldGet length = new HFieldGet(
-        backend.jsIndexableLength, array, backend.positiveIntType,
+        helpers.jsIndexableLength, array, backend.positiveIntType,
         isAssignable: !isFixedLength(array.instructionType, compiler));
     indexNode.block.addBefore(indexNode, length);
 
@@ -1067,7 +1073,7 @@
   void visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
     Element element = node.element;
     if (node.isInterceptedCall) return;
-    if (element != backend.jsArrayRemoveLast) return;
+    if (element != helpers.jsArrayRemoveLast) return;
     if (boundsChecked.contains(node)) return;
     // `0` is the index we want to check, but we want to report `-1`, as if we
     // executed `a[a.length-1]`
@@ -2129,6 +2135,8 @@
 
   MemorySet(this.compiler);
 
+  JavaScriptBackend get backend => compiler.backend;
+
   /**
    * Returns whether [first] and [second] always alias to the same object.
    */
@@ -2185,7 +2193,9 @@
   void registerFieldValueUpdate(Element element,
                                 HInstruction receiver,
                                 HInstruction value) {
-    if (element.isNative) return; // TODO(14955): Remove this restriction?
+    if (backend.isNative(element)) {
+      return; // TODO(14955): Remove this restriction?
+    }
     // [value] is being set in some place in memory, we remove it from
     // the non-escaping set.
     nonEscapingReceivers.remove(value);
@@ -2203,7 +2213,9 @@
   void registerFieldValue(Element element,
                           HInstruction receiver,
                           HInstruction value) {
-    if (element.isNative) return; // TODO(14955): Remove this restriction?
+    if (backend.isNative(element)) {
+      return; // TODO(14955): Remove this restriction?
+    }
     Map<HInstruction, HInstruction> map = fieldValues.putIfAbsent(
         element, () => <HInstruction, HInstruction> {});
     map[receiver] = value;
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index 5d56ba3..5139e5e 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -24,6 +24,8 @@
 import '../constants/constant_system.dart';
 import '../constants/expressions.dart';
 import '../constants/values.dart';
+import '../core_types.dart' show
+    CoreClasses;
 import '../dart_types.dart';
 import '../diagnostics/messages.dart' show
     Message,
@@ -44,8 +46,6 @@
 import '../native/native.dart' as native;
 import '../resolution/operators.dart';
 import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart' show
-    SendResolverMixin;
 import '../resolution/tree_elements.dart' show
     TreeElements;
 import '../tree/tree.dart' as ast;
@@ -58,8 +58,10 @@
     Selector;
 import '../universe/side_effects.dart' show
     SideEffects;
-import '../universe/universe.dart' show
-    UniverseSelector;
+import '../universe/use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
 import '../util/util.dart';
 import '../world.dart' show
     ClassWorld,
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart
index c8a39fa..a34e60b 100644
--- a/pkg/compiler/lib/src/ssa/types.dart
+++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -57,11 +57,12 @@
   static TypeMask fromNativeType(type, Compiler compiler) {
     ClassWorld classWorld = compiler.world;
     JavaScriptBackend backend = compiler.backend;
+    CoreClasses coreClasses = compiler.coreClasses;
     if (type == native.SpecialType.JsObject) {
-      return new TypeMask.nonNullExact(compiler.objectClass, classWorld);
+      return new TypeMask.nonNullExact(coreClasses.objectClass, classWorld);
     } else if (type.isVoid) {
       return backend.nullType;
-    } else if (type.element == compiler.nullClass) {
+    } else if (type.element == coreClasses.nullClass) {
       return backend.nullType;
     } else if (type.treatAsDynamic) {
       return backend.dynamicType;
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 2fb2d11..adda76e 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -262,7 +262,7 @@
             cls.declaration, classWorld);
         // TODO(ngeoffray): We currently only optimize on primitive
         // types.
-        if (!type.satisfies(backend.jsIndexableClass, classWorld) &&
+        if (!type.satisfies(backend.helpers.jsIndexableClass, classWorld) &&
             !type.containsOnlyNum(classWorld) &&
             !type.containsOnlyBool(classWorld)) {
           return false;
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index 3d05dc8..a940e71 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -693,7 +693,7 @@
       return visitInstruction(fieldGet);
     }
     JavaScriptBackend backend = compiler.backend;
-    assert(fieldGet.element == backend.jsIndexableLength);
+    assert(fieldGet.element == backend.helpers.jsIndexableLength);
     PositiveValue value = info.newPositiveValue(fieldGet);
     // We know this range is above zero. To simplify the analysis, we
     // put the zero value as the lower bound of this range. This
diff --git a/pkg/compiler/lib/src/tree/nodes.dart b/pkg/compiler/lib/src/tree/nodes.dart
index 7ef28dc..04d46f5 100644
--- a/pkg/compiler/lib/src/tree/nodes.dart
+++ b/pkg/compiler/lib/src/tree/nodes.dart
@@ -22,7 +22,9 @@
   R visitClassNode(ClassNode node) => visitNode(node);
   R visitCombinator(Combinator node) => visitNode(node);
   R visitConditional(Conditional node) => visitExpression(node);
+  R visitConditionalUri(ConditionalUri node) => visitNode(node);
   R visitContinueStatement(ContinueStatement node) => visitGotoStatement(node);
+  R visitDottedName(DottedName node) => visitExpression(node);
   R visitDoWhile(DoWhile node) => visitLoop(node);
   R visitEmptyStatement(EmptyStatement node) => visitStatement(node);
   R visitEnum(Enum node) => visitNode(node);
@@ -34,8 +36,8 @@
   R visitFunctionExpression(FunctionExpression node) => visitExpression(node);
   R visitGotoStatement(GotoStatement node) => visitStatement(node);
   R visitIdentifier(Identifier node) => visitExpression(node);
-  R visitIf(If node) => visitStatement(node);
   R visitImport(Import node) => visitLibraryDependency(node);
+  R visitIf(If node) => visitStatement(node);
   R visitLabel(Label node) => visitNode(node);
   R visitLabeledStatement(LabeledStatement node) => visitStatement(node);
   R visitLibraryDependency(LibraryDependency node) => visitLibraryTag(node);
@@ -159,7 +161,9 @@
   ClassNode asClassNode() => null;
   Combinator asCombinator() => null;
   Conditional asConditional() => null;
+  ConditionalUri asConditionalUri() => null;
   ContinueStatement asContinueStatement() => null;
+  DottedName asDottedName() => null;
   DoWhile asDoWhile() => null;
   EmptyStatement asEmptyStatement() => null;
   Enum asEnum() => null;
@@ -1022,6 +1026,7 @@
 
 class LiteralSymbol extends Expression {
   final Token hashToken;
+  // TODO: this could be a DottedNamed.
   final NodeList identifiers;
 
   LiteralSymbol(this.hashToken, this.identifiers);
@@ -1067,6 +1072,32 @@
   Token getEndToken() => token;
 }
 
+// TODO(floitsch): a dotted identifier isn't really an expression. Should it
+// inherit from Node instead?
+class DottedName extends Expression {
+  final Token token;
+  final NodeList identifiers;
+
+  DottedName(this.token, this.identifiers);
+
+  DottedName asDottedName() => this;
+
+  void visitChildren(Visitor visitor) {
+    identifiers.accept(visitor);
+  }
+
+  accept(Visitor visitor) => visitor.visitDottedName(this);
+
+  Token getBeginToken() => token;
+  Token getEndToken() => identifiers.getEndToken();
+
+  String get slowNameString {
+    Unparser unparser = new Unparser();
+    unparser.unparseNodeListOfIdentifiers(identifiers);
+    return unparser.result;
+  }
+}
+
 class Operator extends Identifier {
   static const COMPLEX_OPERATORS =
       const ["--", "++", '+=', "-=", "*=", "/=", "%=", "&=", "|=", "~/=", "^=",
@@ -1964,14 +1995,18 @@
  */
 abstract class LibraryDependency extends LibraryTag {
   final StringNode uri;
+  final NodeList conditionalUris;
   final NodeList combinators;
 
   LibraryDependency(this.uri,
+                    this.conditionalUris,
                     this.combinators,
                     List<MetadataAnnotation> metadata)
     : super(metadata);
 
   LibraryDependency asLibraryDependency() => this;
+
+  bool get hasConditionalUris => conditionalUris != null;
 }
 
 /**
@@ -1986,11 +2021,11 @@
   final Token importKeyword;
   final bool isDeferred;
 
-  Import(this.importKeyword, StringNode uri,
+  Import(this.importKeyword, StringNode uri, NodeList conditionalUris,
          this.prefix, NodeList combinators,
          List<MetadataAnnotation> metadata,
          {this.isDeferred})
-      : super(uri, combinators, metadata);
+      : super(uri, conditionalUris, combinators, metadata);
 
   bool get isImport => true;
 
@@ -2009,11 +2044,45 @@
   Token getEndToken() {
     if (combinators != null) return combinators.getEndToken().next;
     if (prefix != null) return prefix.getEndToken().next;
+    if (conditionalUris != null) return conditionalUris.getEndToken().next;
     return uri.getEndToken().next;
   }
 }
 
 /**
+ * A conditional uri inside an import or export clause.
+ *
+ * Example:
+ *
+ *     import 'foo.dart'
+ *       if (some.condition == "someValue") 'bar.dart'
+ *       if (other.condition) 'gee.dart';
+ */
+class ConditionalUri extends Node {
+  final Token ifToken;
+  final DottedName key;
+  // Value may be null.
+  final LiteralString value;
+  final StringNode uri;
+
+  ConditionalUri(this.ifToken, this.key, this.value, this.uri);
+
+  ConditionalUri asConditionalUri() => this;
+
+  accept(Visitor visitor) => visitor.visitConditionalUri(this);
+
+  visitChildren(Visitor visitor) {
+    key.accept(visitor);
+    if (value != null) value.accept(visitor);
+    uri.accept(visitor);
+  }
+
+  Token getBeginToken() => ifToken;
+
+  Token getEndToken() => uri.getEndToken();
+}
+
+/**
  * An `enum` declaration.
  *
  * An `enum` defines a number of named constants inside a non-extensible class
@@ -2052,9 +2121,10 @@
 
   Export(this.exportKeyword,
          StringNode uri,
+         NodeList conditionalUris,
          NodeList combinators,
          List<MetadataAnnotation> metadata)
-      : super(uri, combinators, metadata);
+      : super(uri, conditionalUris, combinators, metadata);
 
   bool get isExport => true;
 
@@ -2071,6 +2141,7 @@
 
   Token getEndToken() {
     if (combinators != null) return combinators.getEndToken().next;
+    if (conditionalUris != null) return conditionalUris.getEndToken().next;
     return uri.getEndToken().next;
   }
 }
diff --git a/pkg/compiler/lib/src/tree/prettyprint.dart b/pkg/compiler/lib/src/tree/prettyprint.dart
index 5096e74..552747e 100644
--- a/pkg/compiler/lib/src/tree/prettyprint.dart
+++ b/pkg/compiler/lib/src/tree/prettyprint.dart
@@ -88,10 +88,20 @@
     visitNodeWithChildren(node, "Conditional");
   }
 
+  visitConditionalUri(ConditionalUri node) {
+    visitNodeWithChildren(node, "ConditionalUri");
+  }
+
   visitContinueStatement(ContinueStatement node) {
     visitNodeWithChildren(node, "ContinueStatement");
   }
 
+  visitDottedName(DottedName node) {
+    openNode(node, "DottedName");
+    visitChildNode(node.identifiers, "identifiers");
+    closeNode();
+  }
+
   visitDoWhile(DoWhile node) {
     visitNodeWithChildren(node, "DoWhile");
   }
@@ -380,6 +390,9 @@
   visitExport(Export node) {
     openNode(node, "Export");
     visitChildNode(node.uri, "uri");
+    if (node.conditionalUris != null) {
+      visitChildNode(node.conditionalUris, "conditionalUris");
+    }
     visitChildNode(node.combinators, "combinators");
     closeNode();
   }
@@ -388,6 +401,9 @@
     openNode(node, "Import", {
       "isDeferred" : "${node.isDeferred}"});
     visitChildNode(node.uri, "uri");
+    if (node.conditionalUris != null) {
+      visitChildNode(node.conditionalUris, "conditionalUris");
+    }
     visitChildNode(node.combinators, "combinators");
     if (node.prefix != null) {
       visitChildNode(node.prefix, "prefix");
diff --git a/pkg/compiler/lib/src/tree/unparser.dart b/pkg/compiler/lib/src/tree/unparser.dart
index 6f141fd..807ea05 100644
--- a/pkg/compiler/lib/src/tree/unparser.dart
+++ b/pkg/compiler/lib/src/tree/unparser.dart
@@ -782,9 +782,33 @@
     newline();
   }
 
+  visitConditionalUri(ConditionalUri node) {
+    write(node.ifToken.value);
+    space();
+    write('(');
+    visit(node.key);
+    if (node.value != null) {
+      space();
+      write("==");
+      space();
+      visit(node.value);
+    }
+    write(")");
+    space();
+    visit(node.uri);
+  }
+
+  visitDottedName(DottedName node) {
+    unparseNodeListOfIdentifiers(node.identifiers);
+  }
+
   visitImport(Import node) {
     addToken(node.importKeyword);
     visit(node.uri);
+    if (node.hasConditionalUris) {
+      write(' ');
+      visitNodeList(node.conditionalUris);
+    }
     if (node.isDeferred) {
       write(' deferred');
     }
@@ -803,6 +827,10 @@
   visitExport(Export node) {
     addToken(node.exportKeyword);
     visit(node.uri);
+    if (node.hasConditionalUris) {
+      write(' ');
+      visitNodeList(node.conditionalUris);
+    }
     if (node.combinators != null) {
       write(' ');
       visit(node.combinators);
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
index 4f0be4a..b4f6dd8 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
@@ -63,11 +63,6 @@
 
   final FallthroughStack fallthrough = new FallthroughStack();
 
-  @override
-  void visitInnerFunction(FunctionDefinition node) {
-    new LogicalRewriter().rewrite(node);
-  }
-
   /// True if the given statement is equivalent to its fallthrough semantics.
   ///
   /// This means it will ultimately translate to an empty statement.
@@ -543,9 +538,9 @@
     }
   }
 
-  /// True if [e2] is known to return the same value as [e1] 
+  /// True if [e2] is known to return the same value as [e1]
   /// (with no additional side effects) if evaluated immediately after [e1].
-  /// 
+  ///
   /// Concretely, this is true if [e1] and [e2] are uses of the same variable,
   /// or if [e2] is a use of a variable assigned by [e1].
   bool isSameVariable(Expression e1, Expression e2) {
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
index 14069e8..2f5a9fd 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
@@ -52,13 +52,13 @@
 ///
 /// Note that the pattern above needs no iteration since nested ifs have been
 /// collapsed previously in the [StatementRewriter] phase.
-/// 
+///
 ///
 /// PULL INTO UPDATE EXPRESSION:
-/// 
+///
 /// Assignment expressions before the unique continue to a [whileCondition] are
 /// pulled into the updates for the loop.
-/// 
+///
 ///   L:
 ///   for (; condition; updates) {
 ///     S [ x = E; continue L ]
@@ -69,7 +69,7 @@
 ///     S [ continue L ]
 ///   }
 ///
-/// The decision to only pull in assignments is a heuristic to balance 
+/// The decision to only pull in assignments is a heuristic to balance
 /// readability and stack trace usability versus the modest code size
 /// reduction one might get by aggressively moving expressions into the
 /// updates.
@@ -88,11 +88,6 @@
     root.body = visitStatement(root.body);
   }
 
-  @override
-  void visitInnerFunction(FunctionDefinition node) {
-    node.body = new LoopRewriter().visitStatement(node.body);
-  }
-
   Statement visitContinue(Continue node) {
     usedContinueLabels.add(node.target);
     return node;
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 878d8e1..3b3a74a 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
@@ -168,6 +168,16 @@
     return node;
   }
 
+  Statement visitNullCheck(NullCheck node) {
+    if (node.condition != null) {
+      node.condition = visitExpression(node.condition);
+      // The value occurs in conditional context, so don't pull from that.
+    } else {
+      node.value = visitExpression(node.value);
+    }
+    return node;
+  }
+
   Expression visitAssign(Assign node) {
     bool inImpureContext = impureCounter > 0;
     bool inBranch = branchCounter > 0;
@@ -249,6 +259,12 @@
     return node;
   }
 
+  Expression visitOneShotInterceptor(OneShotInterceptor node) {
+    super.visitOneShotInterceptor(node);
+    ++impureCounter;
+    return node;
+  }
+
   Expression visitConditional(Conditional node) {
     node.condition = visitExpression(node.condition);
     // Visit the branches to detect impure subexpressions, but do not pull
@@ -338,15 +354,6 @@
     return node;
   }
 
-  void visitInnerFunction(FunctionDefinition node) {
-    new PullIntoInitializers().rewrite(node);
-  }
-
-  Expression visitFunctionExpression(FunctionExpression node) {
-    visitInnerFunction(node.definition);
-    return node;
-  }
-
   Expression visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
     rewriteList(node.arguments);
     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 0091ef9..f23533c 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -7,6 +7,8 @@
 import 'optimization.dart' show Pass;
 import '../tree_ir_nodes.dart';
 import '../../io/source_information.dart';
+import '../../elements/elements.dart';
+import '../../js/placeholder_safety.dart';
 
 /**
  * Translates to direct-style.
@@ -165,7 +167,7 @@
 
   /// Binding environment for variables that are assigned to effectively
   /// constant expressions (see [isEffectivelyConstant]).
-  Map<Variable, Expression> constantEnvironment;
+  Map<Variable, Expression> constantEnvironment = <Variable, Expression>{};
 
   /// Substitution map for labels. Any break to a label L should be substituted
   /// for a break to L' if L maps to L'.
@@ -184,14 +186,6 @@
   /// variable might have changed since it was put in the environment.
   final Map<Variable, int> dominatingAssignments = <Variable, int>{};
 
-  /// Rewriter for methods.
-  StatementRewriter() : constantEnvironment = <Variable, Expression>{};
-
-  /// Rewriter for nested functions.
-  StatementRewriter.nested(StatementRewriter parent)
-      : constantEnvironment = parent.constantEnvironment,
-        unseenUses = parent.unseenUses;
-
   /// A set of labels that can be safely inlined at their use.
   ///
   /// The successor statements for labeled statements that have only one break
@@ -200,6 +194,13 @@
   /// handler (i.e., if the code would be moved into a try from outside it).
   Set<Label> safeForInlining = new Set<Label>();
 
+  /// If the top element is true, assignments of form "x = CONST" may be
+  /// propagated into a following occurence of CONST.  This may confuse the JS
+  /// engine so it is disabled in some cases.
+  final List<bool> allowRhsPropagation = <bool>[true];
+
+  bool get isRhsPropagationAllowed => allowRhsPropagation.last;
+
   /// Returns the redirect target of [jump] or [jump] itself if it should not
   /// be redirected.
   Jump redirect(Jump jump) {
@@ -237,11 +238,16 @@
   /// If the given expression always returns the value of one of its
   /// subexpressions, and that subexpression is a variable use, returns that
   /// variable. Otherwise `null`.
-  Variable getRightHand(Expression e) {
+  Variable getRightHandVariable(Expression e) {
     Expression value = getValueSubexpression(e);
     return value is VariableUse ? value.variable : null;
   }
 
+  Constant getRightHandConstant(Expression e) {
+    Expression value = getValueSubexpression(e);
+    return value is Constant ? value : null;
+  }
+
   /// True if the given expression (taken from [constantEnvironment]) uses a
   /// variable that might have been reassigned since [node] was evaluated.
   bool hasUnsafeVariableUse(Expression node) {
@@ -277,6 +283,11 @@
     // it means we are looking at the first use.
     assert(unseenUses[node.variable] < node.variable.readCount);
     assert(unseenUses[node.variable] >= 0);
+
+    // We cannot reliably find the first dynamic use of a variable that is
+    // accessed from a JS function in a foreign code fragment.
+    if (node.variable.isCaptured) return node;
+
     bool isFirstUse = unseenUses[node.variable] == 0;
 
     // Propagate constant to use site.
@@ -315,7 +326,8 @@
       //
       //     { E.foo = x; bar(x) } ==> bar(E.foo = x)
       //
-      if (getRightHand(binding) == node.variable) {
+      if (isRhsPropagationAllowed &&
+          getRightHandVariable(binding) == node.variable) {
         environment.removeLast();
         --node.variable.readCount;
         return visitExpression(binding);
@@ -455,7 +467,9 @@
   }
 
   Expression visitAssign(Assign node) {
+    allowRhsPropagation.add(true);
     node.value = visitExpression(node.value);
+    allowRhsPropagation.removeLast();
     // Remove assignments to variables without any uses. This can happen
     // because the assignment was propagated into its use, e.g:
     //
@@ -470,10 +484,12 @@
 
   /// Process nodes right-to-left, the opposite of evaluation order in the case
   /// of argument lists..
-  void _rewriteList(List<Node> nodes) {
+  void _rewriteList(List<Node> nodes, {bool rhsPropagation: true}) {
+    allowRhsPropagation.add(rhsPropagation);
     for (int i = nodes.length - 1; i >= 0; --i) {
       nodes[i] = visitExpression(nodes[i]);
     }
+    allowRhsPropagation.removeLast();
   }
 
   Expression visitInvokeStatic(InvokeStatic node) {
@@ -496,6 +512,11 @@
     return node;
   }
 
+  Expression visitOneShotInterceptor(OneShotInterceptor node) {
+    _rewriteList(node.arguments);
+    return node;
+  }
+
   Expression visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
     if (node.receiverIsNotNull) {
       _rewriteList(node.arguments);
@@ -513,7 +534,19 @@
 
   Expression visitInvokeMethodDirectly(InvokeMethodDirectly node) {
     _rewriteList(node.arguments);
-    node.receiver = visitExpression(node.receiver);
+    // The target function might not exist before the enclosing class has been
+    // instantitated for the first time.  If the receiver might be the first
+    // instantiation of its class, we cannot propgate it into the receiver
+    // expression, because the target function is evaluated before the receiver.
+    // Calls to constructor bodies are compiled so that the receiver is
+    // evaluated first, so they are safe.
+    if (node.target is! ConstructorBodyElement) {
+      inEmptyEnvironment(() {
+        node.receiver = visitExpression(node.receiver);
+      });
+    } else {
+      node.receiver = visitExpression(node.receiver);
+    }
     return node;
   }
 
@@ -561,13 +594,15 @@
     return node;
   }
 
-  Expression visitFunctionExpression(FunctionExpression node) {
-    new StatementRewriter.nested(this).rewrite(node.definition);
-    return node;
+  bool isNullConstant(Expression node) {
+    return node is Constant && node.value.isNull;
   }
 
   Statement visitReturn(Return node) {
-    node.value = visitExpression(node.value);
+    if (!isNullConstant(node.value)) {
+      // Do not chain assignments into a null return.
+      node.value = visitExpression(node.value);
+    }
     return node;
   }
 
@@ -576,10 +611,6 @@
     return node;
   }
 
-  Statement visitRethrow(Rethrow node) {
-    return node;
-  }
-
   Statement visitUnreachable(Unreachable node) {
     return node;
   }
@@ -690,6 +721,12 @@
   }
 
   Expression visitConstant(Constant node) {
+    if (isRhsPropagationAllowed && !environment.isEmpty) {
+      Constant constant = getRightHandConstant(environment.last);
+      if (constant != null && constant.value == node.value) {
+        return visitExpression(environment.removeLast());
+      }
+    }
     return node;
   }
 
@@ -717,9 +754,37 @@
     return node;
   }
 
+  bool sameVariable(Expression e1, Expression e2) {
+    return e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable;
+  }
+
+  bool isCompoundableBuiltin(Expression e) {
+    return e is ApplyBuiltinOperator &&
+           e.arguments.length == 2 &&
+           isCompoundableOperator(e.operator);
+  }
+
+  void destroyVariableUse(VariableUse node) {
+    --node.variable.readCount;
+  }
+
   Expression visitSetField(SetField node) {
+    allowRhsPropagation.add(true);
     node.value = visitExpression(node.value);
+    if (isCompoundableBuiltin(node.value)) {
+      ApplyBuiltinOperator rhs = node.value;
+      Expression left = rhs.arguments[0];
+      Expression right = rhs.arguments[1];
+      if (left is GetField &&
+          left.field == node.field &&
+          sameVariable(left.object, node.object)) {
+        destroyVariableUse(left.object);
+        node.compound = rhs.operator;
+        node.value = right;
+      }
+    }
     node.object = visitExpression(node.object);
+    allowRhsPropagation.removeLast();
     return node;
   }
 
@@ -733,7 +798,9 @@
   }
 
   Expression visitSetStatic(SetStatic node) {
+    allowRhsPropagation.add(true);
     node.value = visitExpression(node.value);
+    allowRhsPropagation.removeLast();
     return node;
   }
 
@@ -789,6 +856,19 @@
 
   Expression visitSetIndex(SetIndex node) {
     node.value = visitExpression(node.value);
+    if (isCompoundableBuiltin(node.value)) {
+      ApplyBuiltinOperator rhs = node.value;
+      Expression left = rhs.arguments[0];
+      Expression right = rhs.arguments[1];
+      if (left is GetIndex &&
+          sameVariable(left.object, node.object) &&
+          sameVariable(left.index, node.index)) {
+        destroyVariableUse(left.object);
+        destroyVariableUse(left.index);
+        node.compound = rhs.operator;
+        node.value = right;
+      }
+    }
     node.index = visitExpression(node.index);
     node.object = visitExpression(node.object);
     return node;
@@ -843,31 +923,31 @@
   /// foo() must be evaluated before bar(), so the propagation is only possible
   /// by commuting the operator.
   Expression visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    if (environment.isEmpty || getLeftHand(environment.last) == null) {
-      // If there is no recent assignment that might propagate, so there is no
-      // opportunity for optimization here.
-      _rewriteList(node.arguments);
-      return node;
-    }
-    Variable propagatableVariable = getLeftHand(environment.last);
-    BuiltinOperator commuted = commuteBinaryOperator(node.operator);
-    if (commuted != null) {
-      assert(node.arguments.length == 2); // Only binary operators can commute.
-      Expression left = node.arguments[0];
-      if (left is VariableUse && propagatableVariable == left.variable) {
-        Expression right = node.arguments[1];
-        if (right is This ||
-            (right is VariableUse &&
-             propagatableVariable != right.variable &&
-             !constantEnvironment.containsKey(right.variable))) {
-          // An assignment can be propagated if we commute the operator.
-          node.operator = commuted;
-          node.arguments[0] = right;
-          node.arguments[1] = left;
+    if (!environment.isEmpty && getLeftHand(environment.last) != null) {
+      Variable propagatableVariable = getLeftHand(environment.last);
+      BuiltinOperator commuted = commuteBinaryOperator(node.operator);
+      if (commuted != null) {
+        // Only binary operators can commute.
+        assert(node.arguments.length == 2);
+        Expression left = node.arguments[0];
+        if (left is VariableUse && propagatableVariable == left.variable) {
+          Expression right = node.arguments[1];
+          if (right is This ||
+              (right is VariableUse &&
+               propagatableVariable != right.variable &&
+               !constantEnvironment.containsKey(right.variable))) {
+            // An assignment can be propagated if we commute the operator.
+            node.operator = commuted;
+            node.arguments[0] = right;
+            node.arguments[1] = left;
+          }
         }
       }
     }
-    _rewriteList(node.arguments);
+    // Avoid code like `p == (q.f = null)`. JS operators with a constant operand
+    // can sometimes be compiled to a specialized instruction in the JS engine,
+    // so retain syntactically constant operands.
+    _rewriteList(node.arguments, rhsPropagation: false);
     return node;
   }
 
@@ -1126,15 +1206,33 @@
     return polarity ? node.thenStatement : node.elseStatement;
   }
 
+  void handleForeignCode(ForeignCode node) {
+    // Some arguments will get inserted in a JS code template.  The arguments
+    // will not always be evaluated (e.g. the second placeholder in the template
+    // '# && #').
+    bool isNullable(int position) => node.nullableArguments[position];
+
+    int safeArguments =
+      PlaceholderSafetyAnalysis.analyze(node.codeTemplate.ast, isNullable);
+    inEmptyEnvironment(() {
+      for (int i = node.arguments.length - 1; i >= safeArguments; --i) {
+        node.arguments[i] = visitExpression(node.arguments[i]);
+      }
+    });
+    for (int i = safeArguments - 1; i >= 0; --i) {
+      node.arguments[i] = visitExpression(node.arguments[i]);
+    }
+  }
+
   @override
   Expression visitForeignExpression(ForeignExpression node) {
-    _rewriteList(node.arguments);
+    handleForeignCode(node);
     return node;
   }
 
   @override
   Statement visitForeignStatement(ForeignStatement node) {
-    _rewriteList(node.arguments);
+    handleForeignCode(node);
     return node;
   }
 
@@ -1150,6 +1248,23 @@
     node.next = visitStatement(node.next);
     return node;
   }
+
+  @override
+  Statement visitNullCheck(NullCheck node) {
+    inEmptyEnvironment(() {
+      node.next = visitStatement(node.next);
+    });
+    if (node.condition != null) {
+      inEmptyEnvironment(() {
+        // Value occurs in conditional context.
+        node.value = visitExpression(node.value);
+      });
+      node.condition = visitExpression(node.condition);
+    } else {
+      node.value = visitExpression(node.value);
+    }
+    return node;
+  }
 }
 
 /// Result of combining two expressions, with the potential for reverting the
@@ -1228,8 +1343,6 @@
       wasFound = true;
     }
   }
-
-  visitInnerFunction(FunctionDefinition node) {}
 }
 
 typedef VariableUseCallback(VariableUse use);
@@ -1241,8 +1354,6 @@
 
   visitVariableUse(VariableUse use) => callback(use);
 
-  visitInnerFunction(FunctionDefinition node) {}
-
   static void visit(Expression node, VariableUseCallback callback) {
     new VariableUseVisitor(callback).visitExpression(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 91a5aac..fb31f02 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
@@ -20,11 +20,6 @@
     visitStatement(node.body);
   }
 
-  @override
-  void visitInnerFunction(FunctionDefinition node) {
-    rewriteFunction(node);
-  }
-
   /// Rewrites the given function.
   /// This is called for the outermost function and inner functions.
   void rewriteFunction(FunctionDefinition node) {
@@ -112,11 +107,6 @@
     visitStatement(node.body);
   }
 
-  @override
-  void visitInnerFunction(FunctionDefinition node) {
-    // Do nothing. Inner functions are traversed in VariableMerger.
-  }
-
   /// Creates a new block with the current exception handler or [catchBlock]
   /// if provided.
   Block newBlock({Block catchBlock}) {
@@ -506,11 +496,6 @@
     node.body = visitStatement(node.body);
   }
 
-  @override
-  void visitInnerFunction(FunctionDefinition node) {
-    // Do nothing. Inner functions are traversed in VariableMerger.
-  }
-
   Expression visitVariableUse(VariableUse node) {
     node.variable = replaceRead(node.variable);
     return node;
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 5eddb37..b846c87 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -8,6 +8,7 @@
 import '../constants/values.dart';
 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
 import '../elements/elements.dart';
+import 'package:js_ast/js_ast.dart' as js;
 
 import 'tree_ir_nodes.dart';
 
@@ -52,6 +53,7 @@
       <cps_ir.Primitive, Variable>{};
   final Map<cps_ir.MutableVariable, Variable> mutable2variable =
       <cps_ir.MutableVariable, Variable>{};
+  final Set<cps_ir.Constant> inlinedConstants = new Set<cps_ir.Constant>();
 
   // Continuations with more than one use are replaced with Tree labels.  This
   // is the mapping from continuations to labels.
@@ -97,6 +99,7 @@
   /// Obtains the variable representing the given primitive. Returns null for
   /// primitives that have no reference and do not need a variable.
   Variable getVariable(cps_ir.Primitive primitive) {
+    primitive = primitive.effectiveDefinition;
     return primitive2variable.putIfAbsent(primitive,
         () => new Variable(currentElement, primitive.hint));
   }
@@ -106,23 +109,27 @@
   /// This increments the reference count for the given variable, so the
   /// returned expression must be used in the tree.
   Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) {
-    if (thisParameter != null && reference.definition == thisParameter) {
+    cps_ir.Primitive prim = reference.definition.effectiveDefinition;
+    if (prim is cps_ir.Constant && inlinedConstants.contains(prim)) {
+      return new Constant(prim.value);
+    }
+    if (thisParameter != null && prim == thisParameter) {
       return new This();
     }
-    return new VariableUse(getVariable(reference.definition));
+    return new VariableUse(getVariable(prim));
+  }
+
+  Expression getVariableUseOrNull(
+        cps_ir.Reference<cps_ir.Primitive> reference) {
+    return reference == null ? null : getVariableUse(reference);
   }
 
   Label getLabel(cps_ir.Continuation cont) {
     return labels.putIfAbsent(cont, () => new Label());
   }
 
-  Variable addFunctionParameter(cps_ir.Definition variable) {
-    if (variable is cps_ir.Parameter) {
-      return getVariable(variable);
-    } else {
-      return addMutableVariable(variable as cps_ir.MutableVariable)
-              ..isCaptured = true;
-    }
+  Variable addFunctionParameter(cps_ir.Parameter parameter) {
+    return getVariable(parameter);
   }
 
   FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
@@ -272,10 +279,57 @@
   /// Translates a CPS primitive to a tree expression.
   ///
   /// This simply calls the visit method for the primitive.
-  Expression translatePrimitive(cps_ir.Primitive prim) {
+  translatePrimitive(cps_ir.Primitive prim) {
     return prim.accept(this);
   }
 
+  /************************ CONSTANT COPYING *****************************/
+
+  /// Estimate of the number of characters needed to emit a use of the given
+  /// constant.
+  int constantSize(PrimitiveConstantValue value) {
+    // TODO(asgerf): We could interface with the emitter to get the exact size.
+    if (value is StringConstantValue) {
+      // Account for the quotes, but ignore the cost of encoding non-ASCII
+      // characters to avoid traversing the string and depending on encoding.
+      return value.length + 2;
+    } else if (value is BoolConstantValue) {
+      return 2; // Printed as !0 and !1 when minified
+    } else {
+      // TODO(asgerf): Get the exact length of numbers using '1e10' notation.
+      return '${value.primitiveValue}'.length;
+    }
+  }
+
+  /// The number of uses [prim] has, or `-1` if it is used in a phi assignment.
+  int countNonPhiUses(cps_ir.Primitive prim) {
+    int count = 0;
+    for (cps_ir.Reference ref = prim.firstRef; ref != null; ref = ref.next) {
+      cps_ir.Node use = ref.parent;
+      if (use is cps_ir.InvokeContinuation) {
+        return -1;
+      }
+      count++;
+    }
+    return count;
+  }
+
+  /// True if the given [constant] should be copied to every use site.
+  bool shouldCopyToUses(cps_ir.Constant constant) {
+    if (!constant.value.isPrimitive) return false;
+    if (constant.hasAtMostOneUse) return true;
+    int uses = countNonPhiUses(constant);
+    if (uses == -1) return false; // Copying might prevent elimination of a phi.
+    int size = constantSize(constant.value);
+    // Compare the expected code size output of copying vs sharing.
+    const int USE = 2; // Minified locals usually have length 2.
+    const int ASSIGN = USE + 2; // Variable and '=' and ';'
+    const int BIAS = 2; // Artificial bias to slightly favor copying.
+    int costOfSharing = USE * uses + size + ASSIGN + BIAS;
+    int costOfCopying = size * uses;
+    return costOfCopying <= costOfSharing;
+  }
+
   /************************ INTERIOR EXPRESSIONS  ************************/
   //
   // Visit methods for interior expressions must return a function:
@@ -283,15 +337,24 @@
   //    (Statement next) => <result statement>
   //
 
-  NodeCallback visitLetPrim(cps_ir.LetPrim node) => (Statement next) {
-    Variable variable = getVariable(node.primitive);
-    Expression value = translatePrimitive(node.primitive);
-    if (node.primitive.hasAtLeastOneUse) {
-      return Assign.makeStatement(variable, value, next);
-    } else {
-      return new ExpressionStatement(value, next);
+  NodeCallback visitLetPrim(cps_ir.LetPrim node) {
+    if (node.primitive is cps_ir.Constant && shouldCopyToUses(node.primitive)) {
+      inlinedConstants.add(node.primitive);
+      return (Statement next) => next;
     }
-  };
+    Variable variable = getVariable(node.primitive);
+    var value = translatePrimitive(node.primitive);
+    if (value is Expression) {
+      if (node.primitive.hasAtLeastOneUse) {
+        return (Statement next) => Assign.makeStatement(variable, value, next);
+      } else {
+        return (Statement next) => new ExpressionStatement(value, next);
+      }
+    } else {
+      assert(value is NodeCallback);
+      return value;
+    }
+  }
 
   // Continuations are bound at the same level, but they have to be
   // translated as if nested.  This is because the body can invoke any
@@ -337,117 +400,6 @@
     return (Statement next) => Assign.makeStatement(variable, value, next);
   }
 
-
-  /************************ CALL EXPRESSIONS  ************************/
-  //
-  // Visit methods for call expressions must return a function:
-  //
-  //    (Statement next) => <result statement>
-  //
-  // The result statement must include an assignment to the continuation
-  // parameter, if the parameter is used.
-  //
-
-  NodeCallback makeCallExpression(cps_ir.CallExpression call,
-                                  Expression expression) {
-    return (Statement next) {
-      cps_ir.Parameter result = call.continuation.definition.parameters.single;
-      if (result.hasAtLeastOneUse) {
-        return Assign.makeStatement(getVariable(result), expression, next);
-      } else {
-        return new ExpressionStatement(expression, next);
-      }
-    };
-  }
-
-  NodeCallback visitInvokeStatic(cps_ir.InvokeStatic node) {
-    List<Expression> arguments = translateArguments(node.arguments);
-    Expression invoke = new InvokeStatic(node.target, node.selector, arguments,
-                                         node.sourceInformation);
-    return makeCallExpression(node, invoke);
-  }
-
-  NodeCallback visitInvokeMethod(cps_ir.InvokeMethod node) {
-    InvokeMethod invoke = new InvokeMethod(
-        getVariableUse(node.receiver),
-        node.selector,
-        node.mask,
-        translateArguments(node.arguments),
-        node.sourceInformation);
-    invoke.receiverIsNotNull = node.receiverIsNotNull;
-    return makeCallExpression(node, invoke);
-  }
-
-  NodeCallback visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
-    Expression receiver = getVariableUse(node.receiver);
-    List<Expression> arguments = translateArguments(node.arguments);
-    Expression invoke = new InvokeMethodDirectly(receiver, node.target,
-        node.selector, arguments, node.sourceInformation);
-    return makeCallExpression(node, invoke);
-  }
-
-  NodeCallback visitTypeCast(cps_ir.TypeCast node) {
-    Expression value = getVariableUse(node.value);
-    List<Expression> typeArgs = translateArguments(node.typeArguments);
-    Expression expression =
-        new TypeOperator(value, node.dartType, typeArgs, isTypeTest: false);
-    return makeCallExpression(node, expression);
-  }
-
-  NodeCallback visitInvokeConstructor(cps_ir.InvokeConstructor node) {
-    List<Expression> arguments = translateArguments(node.arguments);
-    Expression invoke = new InvokeConstructor(
-        node.dartType,
-        node.target,
-        node.selector,
-        arguments,
-        node.sourceInformation);
-    return makeCallExpression(node, invoke);
-  }
-
-  NodeCallback visitForeignCode(cps_ir.ForeignCode node) {
-    if (node.codeTemplate.isExpression) {
-      Expression foreignCode = new ForeignExpression(
-          node.codeTemplate,
-          node.type,
-          node.arguments.map(getVariableUse).toList(growable: false),
-          node.nativeBehavior,
-          node.dependency);
-      return makeCallExpression(node, foreignCode);
-    } else {
-      return (Statement next) {
-        assert(next is Unreachable); // We are not using the `next` statement.
-        return new ForeignStatement(
-            node.codeTemplate,
-            node.type,
-            node.arguments.map(getVariableUse).toList(growable: false),
-            node.nativeBehavior,
-            node.dependency);
-      };
-    }
-  }
-
-  NodeCallback visitGetLazyStatic(cps_ir.GetLazyStatic node) {
-    // In the tree IR, GetStatic handles lazy fields because we do not need
-    // as fine-grained control over side effects.
-    GetStatic value = new GetStatic(node.element, node.sourceInformation);
-    return makeCallExpression(node, value);
-  }
-
-  @override
-  NodeCallback visitYield(cps_ir.Yield node) {
-    return (Statement next) {
-      return new Yield(getVariableUse(node.input), node.hasStar, next);
-    };
-  }
-
-  @override
-  NodeCallback visitAwait(cps_ir.Await node) {
-    Expression value = new Await(getVariableUse(node.input));
-    return makeCallExpression(node, value);
-  }
-
-
   /************************** TAIL EXPRESSIONS  **************************/
   //
   // Visit methods for tail expressions must return a statement directly
@@ -458,10 +410,6 @@
     return new Throw(value);
   }
 
-  Statement visitRethrow(cps_ir.Rethrow node) {
-    return new Rethrow();
-  }
-
   Statement visitUnreachable(cps_ir.Unreachable node) {
     return new Unreachable();
   }
@@ -562,7 +510,7 @@
 
   Expression visitGetField(cps_ir.GetField node) {
     return new GetField(getVariableUse(node.object), node.field,
-        objectIsNotNull: node.objectIsNotNull);
+        objectIsNotNull: !node.object.definition.type.isNullable);
   }
 
   Expression visitCreateBox(cps_ir.CreateBox node) {
@@ -606,15 +554,6 @@
     );
   }
 
-  FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) {
-    return createInnerBuilder().buildFunction(function);
-  }
-
-  Expression visitCreateFunction(cps_ir.CreateFunction node) {
-    FunctionDefinition def = makeSubFunction(node.definition);
-    return new FunctionExpression(def);
-  }
-
   Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
     return new ReifyRuntimeType(
         getVariableUse(node.value), node.sourceInformation);
@@ -668,7 +607,7 @@
     return new ApplyBuiltinMethod(node.method,
         getVariableUse(node.receiver),
         translateArguments(node.arguments),
-        receiverIsNotNull: node.receiverIsNotNull);
+        receiverIsNotNull: !node.receiver.definition.type.isNullable);
   }
 
   Expression visitGetLength(cps_ir.GetLength node) {
@@ -686,9 +625,119 @@
                         getVariableUse(node.value));
   }
 
+  Expression visitInvokeStatic(cps_ir.InvokeStatic node) {
+    List<Expression> arguments = translateArguments(node.arguments);
+    return new InvokeStatic(node.target, node.selector, arguments,
+                                         node.sourceInformation);
+  }
+
+  Expression visitInvokeMethod(cps_ir.InvokeMethod node) {
+    if (node.callingConvention == cps_ir.CallingConvention.OneShotIntercepted) {
+      List<Expression> arguments = new List.generate(
+          1 + node.arguments.length,
+          (n) => getVariableUse(n == 0 ? node.receiver : node.arguments[n - 1]),
+          growable: false);
+      return new OneShotInterceptor(node.selector, node.mask, arguments,
+          node.sourceInformation);
+    }
+    InvokeMethod invoke = new InvokeMethod(
+        getVariableUse(node.receiver),
+        node.selector,
+        node.mask,
+        translateArguments(node.arguments),
+        node.sourceInformation);
+    // Sometimes we know the Dart receiver is non-null because it has been
+    // refined, which implies that the JS receiver also can not be null at the
+    // use-site.  Interceptors are not refined, so this information is not
+    // always available on the JS receiver.
+    // Also check the JS receiver's type, however, because sometimes we know an
+    // interceptor is non-null because it intercepts JSNull.
+    invoke.receiverIsNotNull =
+        !node.dartReceiver.type.isNullable ||
+        !node.receiver.definition.type.isNullable;
+    return invoke;
+  }
+
+  Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
+    Expression receiver = getVariableUse(node.receiver);
+    List<Expression> arguments = translateArguments(node.arguments);
+    return new InvokeMethodDirectly(receiver, node.target,
+        node.selector, arguments, node.sourceInformation);
+  }
+
+  Expression visitTypeCast(cps_ir.TypeCast node) {
+    Expression value = getVariableUse(node.value);
+    List<Expression> typeArgs = translateArguments(node.typeArguments);
+    return new TypeOperator(value, node.dartType, typeArgs, isTypeTest: false);
+  }
+
+  Expression visitInvokeConstructor(cps_ir.InvokeConstructor node) {
+    List<Expression> arguments = translateArguments(node.arguments);
+    return new InvokeConstructor(
+        node.dartType,
+        node.target,
+        node.selector,
+        arguments,
+        node.sourceInformation);
+  }
+
+  visitForeignCode(cps_ir.ForeignCode node) {
+    List<Expression> arguments =
+        node.arguments.map(getVariableUse).toList(growable: false);
+    List<bool> nullableArguments = node.arguments
+        .map((argument) => argument.definition.type.isNullable)
+        .toList(growable: false);
+    if (node.codeTemplate.isExpression) {
+      return new ForeignExpression(
+          node.codeTemplate,
+          node.type,
+          arguments,
+          node.nativeBehavior,
+          nullableArguments,
+          node.dependency);
+    } else {
+      return (Statement next) {
+        assert(next is Unreachable); // We are not using the `next` statement.
+        return new ForeignStatement(
+            node.codeTemplate,
+            node.type,
+            arguments,
+            node.nativeBehavior,
+            nullableArguments,
+            node.dependency);
+      };
+    }
+  }
+
+  visitNullCheck(cps_ir.NullCheck node) => (Statement next) {
+    return new NullCheck(
+        condition: getVariableUseOrNull(node.condition),
+        value: getVariableUse(node.value),
+        selector: node.selector,
+        useSelector: node.useSelector,
+        next: next,
+        sourceInformation: node.sourceInformation);
+  };
+
+  Expression visitGetLazyStatic(cps_ir.GetLazyStatic node) {
+    return new GetStatic.lazy(node.element, node.sourceInformation);
+  }
+
   @override
-  Expression visitRefinement(cps_ir.Refinement node) {
-    throw 'Unexpected Refinement node in tree builder';
+  NodeCallback visitYield(cps_ir.Yield node) {
+    return (Statement next) {
+      return new Yield(getVariableUse(node.input), node.hasStar, next);
+    };
+  }
+
+  @override
+  Expression visitAwait(cps_ir.Await node) {
+    return new Await(getVariableUse(node.input));
+  }
+
+  @override
+  visitRefinement(cps_ir.Refinement node) {
+    return (Statement next) => next; // Compile to nothing.
   }
 
   /********** UNUSED VISIT METHODS *************/
@@ -703,4 +752,6 @@
   visitParameter(cps_ir.Parameter node) => unexpectedNode(node);
   visitContinuation(cps_ir.Continuation node) => unexpectedNode(node);
   visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node);
+  visitRethrow(cps_ir.Rethrow node) => unexpectedNode(node);
+  visitBoundsCheck(cps_ir.BoundsCheck node) => unexpectedNode(node);
 }
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart
index 3a1a0bc..691a330 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart
@@ -129,10 +129,6 @@
     labelUses[node.target]++;
   }
 
-  visitInnerFunction(FunctionDefinition node) {
-    checkBody(node);
-  }
-
   void checkBody(FunctionDefinition node) {
     node.parameters.forEach(declare);
     visitStatement(node.body);
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 4693bad..19eeb05 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -67,18 +67,6 @@
  * Labels name [LabeledStatement]s.
  */
 class Label {
-  // A counter used to generate names.  The counter is reset to 0 for each
-  // function emitted.
-  static int counter = 0;
-  static String _newName() => 'L${counter++}';
-
-  String cachedName;
-
-  String get name {
-    if (cachedName == null) cachedName = _newName();
-    return cachedName;
-  }
-
   /// Number of [Break] or [Continue] statements that target this label.
   /// The [Break] constructor will increment this automatically, but the
   /// counter must be decremented by hand when a [Break] becomes orphaned.
@@ -114,15 +102,12 @@
 
   /// Number of places where this variable occurs as:
   /// - left-hand of an [Assign]
-  /// - left-hand of a [FunctionDeclaration]
   /// - parameter in a [FunctionDefinition]
   /// - catch parameter in a [Try]
   int writeCount = 0;
 
-  /// True if a nested function reads or writes this variable.
-  ///
-  /// Always false in JS-mode because closure conversion eliminated nested
-  /// functions.
+  /// True if an inner JS function might access this variable through a
+  /// [ForeignCode] node.
   bool isCaptured = false;
 
   Variable(this.host, this.element) {
@@ -236,6 +221,8 @@
   InvokeMethodDirectly(this.receiver, this.target, this.selector,
       this.arguments, this.sourceInformation);
 
+  bool get isTearOff => selector.isGetter && !target.isGetter;
+
   accept(ExpressionVisitor visitor) => visitor.visitInvokeMethodDirectly(this);
   accept1(ExpressionVisitor1 visitor, arg) {
     return visitor.visitInvokeMethodDirectly(this, arg);
@@ -269,6 +256,26 @@
   }
 }
 
+/// Call a method using a one-shot interceptor.
+///
+/// There is no explicit receiver, the first argument serves that purpose.
+class OneShotInterceptor extends Expression implements Invoke {
+  final Selector selector;
+  final TypeMask mask;
+  final List<Expression> arguments;
+  final SourceInformation sourceInformation;
+
+  OneShotInterceptor(this.selector,
+                     this.mask,
+                     this.arguments,
+                     this.sourceInformation);
+
+  accept(ExpressionVisitor visitor) => visitor.visitOneShotInterceptor(this);
+  accept1(ExpressionVisitor1 visitor, arg) {
+    return visitor.visitOneShotInterceptor(this, arg);
+  }
+}
+
 /**
  * A constant.
  */
@@ -437,20 +444,6 @@
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitNot(this, arg);
 }
 
-/// Currently unused.
-///
-/// See CreateFunction in the cps_ir_nodes.dart.
-class FunctionExpression extends Expression {
-  final FunctionDefinition definition;
-
-  FunctionExpression(this.definition);
-
-  accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitFunctionExpression(this, arg);
-  }
-}
-
 /// A [LabeledStatement] or [WhileTrue] or [For].
 abstract class JumpTarget extends Statement {
   Label get label;
@@ -614,21 +607,6 @@
   accept1(StatementVisitor1 visitor, arg) => visitor.visitThrow(this, arg);
 }
 
-/// A rethrow of an exception.
-///
-/// Rethrow can only occur nested inside a catch block.  It implicitly throws
-/// the block's caught exception value without changing the caught stack
-/// trace.  It does not have a successor statement.
-class Rethrow extends Statement {
-  Statement get next => null;
-  void set next(Statement s) => throw 'UNREACHABLE';
-
-  Rethrow();
-
-  accept(StatementVisitor visitor) => visitor.visitRethrow(this);
-  accept1(StatementVisitor1 visitor, arg) => visitor.visitRethrow(this, arg);
-}
-
 /**
  * A conditional branch based on the true value of an [Expression].
  */
@@ -738,7 +716,11 @@
   Element field;
   Expression value;
 
-  SetField(this.object, this.field, this.value);
+  /// If non-null, this is a compound assignment to the field, using the given
+  /// operator.  The operator must be a compoundable operator.
+  BuiltinOperator compound;
+
+  SetField(this.object, this.field, this.value, {this.compound});
 
   accept(ExpressionVisitor visitor) => visitor.visitSetField(this);
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
@@ -759,15 +741,17 @@
       visitor.visitGetTypeTestProperty(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;
+  bool useLazyGetter = false;
 
   GetStatic(this.element, this.sourceInformation);
 
+  GetStatic.lazy(this.element, this.sourceInformation) : useLazyGetter = true;
+
   accept(ExpressionVisitor visitor) => visitor.visitGetStatic(this);
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetStatic(this, arg);
 }
@@ -806,8 +790,9 @@
   Expression object;
   Expression index;
   Expression value;
+  BuiltinOperator compound;
 
-  SetIndex(this.object, this.index, this.value);
+  SetIndex(this.object, this.index, this.value, {this.compound});
 
   accept(ExpressionVisitor v) => v.visitSetIndex(this);
   accept1(ExpressionVisitor1 v, arg) => v.visitSetIndex(this, arg);
@@ -880,17 +865,22 @@
   final types.TypeMask type;
   final List<Expression> arguments;
   final native.NativeBehavior nativeBehavior;
+  final List<bool> nullableArguments;  // One 'bit' per argument.
   final Element dependency;
 
   ForeignCode(this.codeTemplate, this.type, this.arguments, this.nativeBehavior,
-      this.dependency);
+      this.nullableArguments, this.dependency) {
+    assert(arguments.length == nullableArguments.length);
+  }
 }
 
 class ForeignExpression extends ForeignCode implements Expression {
-  ForeignExpression(js.Template codeTemplate, types.TypeMask type,
+  ForeignExpression(
+      js.Template codeTemplate, types.TypeMask type,
       List<Expression> arguments, native.NativeBehavior nativeBehavior,
+      List<bool> nullableArguments,
       Element dependency)
-      : super(codeTemplate, type, arguments, nativeBehavior,
+      : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
           dependency);
 
   accept(ExpressionVisitor visitor) {
@@ -903,10 +893,12 @@
 }
 
 class ForeignStatement extends ForeignCode implements Statement {
-  ForeignStatement(js.Template codeTemplate, types.TypeMask type,
+  ForeignStatement(
+      js.Template codeTemplate, types.TypeMask type,
       List<Expression> arguments, native.NativeBehavior nativeBehavior,
+      List<bool> nullableArguments,
       Element dependency)
-      : super(codeTemplate, type, arguments, nativeBehavior,
+      : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
           dependency);
 
   accept(StatementVisitor visitor) {
@@ -972,6 +964,26 @@
   }
 }
 
+class NullCheck extends Statement {
+  Expression condition;
+  Expression value;
+  Selector selector;
+  bool useSelector;
+  Statement next;
+  SourceInformation sourceInformation;
+
+  NullCheck({this.condition, this.value, this.selector, this.useSelector,
+      this.next, this.sourceInformation});
+
+  accept(StatementVisitor visitor) {
+    return visitor.visitNullCheck(this);
+  }
+
+  accept1(StatementVisitor1 visitor, arg) {
+    return visitor.visitNullCheck(this, arg);
+  }
+}
+
 abstract class ExpressionVisitor<E> {
   E visitExpression(Expression node) => node.accept(this);
   E visitVariableUse(VariableUse node);
@@ -980,6 +992,7 @@
   E visitInvokeMethod(InvokeMethod node);
   E visitInvokeMethodDirectly(InvokeMethodDirectly node);
   E visitInvokeConstructor(InvokeConstructor node);
+  E visitOneShotInterceptor(OneShotInterceptor node);
   E visitConstant(Constant node);
   E visitThis(This node);
   E visitConditional(Conditional node);
@@ -988,7 +1001,6 @@
   E visitLiteralList(LiteralList node);
   E visitLiteralMap(LiteralMap node);
   E visitTypeOperator(TypeOperator node);
-  E visitFunctionExpression(FunctionExpression node);
   E visitGetField(GetField node);
   E visitSetField(SetField node);
   E visitGetStatic(GetStatic node);
@@ -1018,6 +1030,7 @@
   E visitInvokeMethod(InvokeMethod node, A arg);
   E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg);
   E visitInvokeConstructor(InvokeConstructor node, A arg);
+  E visitOneShotInterceptor(OneShotInterceptor node, A arg);
   E visitConstant(Constant node, A arg);
   E visitThis(This node, A arg);
   E visitConditional(Conditional node, A arg);
@@ -1026,7 +1039,6 @@
   E visitLiteralList(LiteralList node, A arg);
   E visitLiteralMap(LiteralMap node, A arg);
   E visitTypeOperator(TypeOperator node, A arg);
-  E visitFunctionExpression(FunctionExpression node, A arg);
   E visitGetField(GetField node, A arg);
   E visitSetField(SetField node, A arg);
   E visitGetStatic(GetStatic node, A arg);
@@ -1053,7 +1065,6 @@
   S visitLabeledStatement(LabeledStatement node);
   S visitReturn(Return node);
   S visitThrow(Throw node);
-  S visitRethrow(Rethrow node);
   S visitBreak(Break node);
   S visitContinue(Continue node);
   S visitIf(If node);
@@ -1064,6 +1075,7 @@
   S visitUnreachable(Unreachable node);
   S visitForeignStatement(ForeignStatement node);
   S visitYield(Yield node);
+  S visitNullCheck(NullCheck node);
 }
 
 abstract class StatementVisitor1<S, A> {
@@ -1071,7 +1083,6 @@
   S visitLabeledStatement(LabeledStatement node, A arg);
   S visitReturn(Return node, A arg);
   S visitThrow(Throw node, A arg);
-  S visitRethrow(Rethrow node, A arg);
   S visitBreak(Break node, A arg);
   S visitContinue(Continue node, A arg);
   S visitIf(If node, A arg);
@@ -1082,14 +1093,13 @@
   S visitUnreachable(Unreachable node, A arg);
   S visitForeignStatement(ForeignStatement node, A arg);
   S visitYield(Yield node, A arg);
+  S visitNullCheck(NullCheck node, A arg);
 }
 
 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor {
   visitExpression(Expression e) => e.accept(this);
   visitStatement(Statement s) => s.accept(this);
 
-  visitInnerFunction(FunctionDefinition node);
-
   visitVariable(Variable variable) {}
 
   visitVariableUse(VariableUse node) {
@@ -1119,6 +1129,10 @@
     node.arguments.forEach(visitExpression);
   }
 
+  visitOneShotInterceptor(OneShotInterceptor node) {
+    node.arguments.forEach(visitExpression);
+  }
+
   visitConstant(Constant node) {}
 
   visitThis(This node) {}
@@ -1154,10 +1168,6 @@
     node.typeArguments.forEach(visitExpression);
   }
 
-  visitFunctionExpression(FunctionExpression node) {
-    visitInnerFunction(node.definition);
-  }
-
   visitLabeledStatement(LabeledStatement node) {
     visitStatement(node.body);
     visitStatement(node.next);
@@ -1171,8 +1181,6 @@
     visitExpression(node.value);
   }
 
-  visitRethrow(Rethrow node) {}
-
   visitBreak(Break node) {}
 
   visitContinue(Continue node) {}
@@ -1300,6 +1308,12 @@
     visitExpression(node.input);
     visitStatement(node.next);
   }
+
+  visitNullCheck(NullCheck node) {
+    if (node.condition != null) visitExpression(node.condition);
+    visitExpression(node.value);
+    visitStatement(node.next);
+  }
 }
 
 abstract class Transformer implements ExpressionVisitor<Expression>,
@@ -1309,10 +1323,6 @@
 }
 
 class RecursiveTransformer extends Transformer {
-  void visitInnerFunction(FunctionDefinition node) {
-    node.body = visitStatement(node.body);
-  }
-
   void _replaceExpressions(List<Expression> list) {
     for (int i = 0; i < list.length; i++) {
       list[i] = visitExpression(list[i]);
@@ -1348,6 +1358,11 @@
     return node;
   }
 
+  visitOneShotInterceptor(OneShotInterceptor node) {
+    _replaceExpressions(node.arguments);
+    return node;
+  }
+
   visitConstant(Constant node) => node;
 
   visitThis(This node) => node;
@@ -1389,11 +1404,6 @@
     return node;
   }
 
-  visitFunctionExpression(FunctionExpression node) {
-    visitInnerFunction(node.definition);
-    return node;
-  }
-
   visitLabeledStatement(LabeledStatement node) {
     node.body = visitStatement(node.body);
     node.next = visitStatement(node.next);
@@ -1410,8 +1420,6 @@
     return node;
   }
 
-  visitRethrow(Rethrow node) => node;
-
   visitBreak(Break node) => node;
 
   visitContinue(Continue node) => node;
@@ -1566,6 +1574,15 @@
     node.next = visitStatement(node.next);
     return node;
   }
+
+  visitNullCheck(NullCheck node) {
+    if (node.condition != null) {
+      node.condition = visitExpression(node.condition);
+    }
+    node.value = visitExpression(node.value);
+    node.next = visitStatement(node.next);
+    return node;
+  }
 }
 
 class FallthroughTarget {
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 130d268..979647a 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -82,10 +82,6 @@
     _addStatement(node);
   }
 
-  visitRethrow(Rethrow node) {
-    _addStatement(node);
-  }
-
   visitUnreachable(Unreachable node) {
     _addStatement(node);
   }
@@ -182,6 +178,11 @@
     _addStatement(node);
     visitStatement(node.next);
   }
+
+  visitNullCheck(NullCheck node) {
+    _addStatement(node);
+    visitStatement(node.next);
+  }
 }
 
 class TreeTracer extends TracerUtil with StatementVisitor {
@@ -271,10 +272,6 @@
     printStatement(null, "throw ${expr(node.value)}");
   }
 
-  visitRethrow(Rethrow node) {
-    printStatement(null, "rethrow");
-  }
-
   visitUnreachable(Unreachable node) {
     printStatement(null, "unreachable");
   }
@@ -346,6 +343,11 @@
     String name = node.hasStar ? 'yield*' : 'yield';
     printStatement(null, '$name ${expr(node.input)}');
   }
+
+  @override
+  visitNullCheck(NullCheck node) {
+    printStatement(null, 'NullCheck ${expr(node.value)}');
+  }
 }
 
 class SubexpressionVisitor extends ExpressionVisitor<String> {
@@ -401,6 +403,12 @@
     return "$keyword $callName($args)";
   }
 
+  String visitOneShotInterceptor(OneShotInterceptor node) {
+    String name = node.selector.name;
+    String args = formatArguments(node);
+    return "oneshot $name($args)";
+  }
+
   String visitLiteralList(LiteralList node) {
     String values = node.values.map(visitExpression).join(', ');
     return "list [$values]";
@@ -464,10 +472,6 @@
     return '!$operand';
   }
 
-  String visitFunctionExpression(FunctionExpression node) {
-    return "function ${node.definition.element.name}";
-  }
-
   String visitGetField(GetField node) {
     String object = visitExpression(node.object);
     String field = node.field.name;
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 90a85fb..71a0fc1 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -756,7 +756,7 @@
           // This is an access the implicit 'call' method of a function type.
           return new FunctionCallAccess(receiverElement, unaliasedBound);
         }
-        if (types.isSubtype(interface, compiler.functionClass.rawType)) {
+        if (types.isSubtype(interface, coreTypes.functionType)) {
           // This is an access of the special 'call' method implicitly defined
           // on 'Function'. This method can be called with any arguments, which
           // we ensure by giving it the type 'dynamic'.
@@ -1023,8 +1023,7 @@
   ElementAccess computeAccess(Send node, String name, Element element,
                               MemberKind memberKind,
                               {bool lookupClassMember: false}) {
-    if (element != null && element.isErroneous) {
-      // An error has already been reported for this node.
+    if (Elements.isMalformed(element)) {
       return const DynamicAccess();
     }
     if (node.receiver != null) {
@@ -1063,7 +1062,7 @@
     if (element == null) {
       // foo() where foo is unresolved.
       return lookupMember(node, thisType, name, memberKind, null);
-    } else if (element.isErroneous) {
+    } else if (element.isMalformed) {
       // foo() where foo is erroneous.
       return const DynamicAccess();
     } else if (element.impliesType) {
@@ -1199,14 +1198,21 @@
     Identifier selector = node.selector.asIdentifier();
     if (Elements.isClosureSend(node, element)) {
       if (element != null) {
-        // foo() where foo is a local or a parameter.
-        return analyzeInvocation(node, createPromotedAccess(element));
+        if (element.isError) {
+          // foo() where foo is erroneous
+          return analyzeInvocation(node, const DynamicAccess());
+        } else {
+          assert(invariant(node, element.isLocal,
+              message: "Unexpected element $element in closure send."));
+          // foo() where foo is a local or a parameter.
+          return analyzeInvocation(node, createPromotedAccess(element));
+        }
       } else {
         // exp() where exp is some complex expression like (o) or foo().
         DartType type = analyze(node.selector);
         return analyzeInvocation(node, new TypeAccess(type));
       }
-    } else if (Elements.isErroneous(element) && selector == null) {
+    } else if (Elements.isMalformed(element) && selector == null) {
       // exp() where exp is an erroneous construct like `new Unresolved()`.
       DartType type = analyze(node.selector);
       return analyzeInvocation(node, new TypeAccess(type));
@@ -1335,15 +1341,15 @@
       LinkBuilder<DartType> argumentTypesBuilder = new LinkBuilder<DartType>();
       DartType resultType =
           analyzeInvocation(node, access, argumentTypesBuilder);
-      if (identical(receiverType.element, compiler.intClass)) {
+      if (receiverType == intType) {
         if (identical(name, '+') ||
             identical(operatorName, '-') ||
             identical(name, '*') ||
             identical(name, '%')) {
           DartType argumentType = argumentTypesBuilder.toLink().head;
-          if (identical(argumentType.element, compiler.intClass)) {
+          if (argumentType == intType) {
             return intType;
-          } else if (identical(argumentType.element, compiler.doubleClass)) {
+          } else if (argumentType == doubleType) {
             return doubleType;
           }
         }
@@ -1590,7 +1596,7 @@
   }
 
   DartType visitLiteralSymbol(LiteralSymbol node) {
-    return compiler.symbolClass.rawType;
+    return coreTypes.symbolType;
   }
 
   DartType computeConstructorType(ConstructorElement constructor,
@@ -1829,8 +1835,6 @@
   visitAsyncForIn(AsyncForIn node) {
     DartType elementType = computeForInElementType(node);
     DartType expressionType = analyze(node.expression);
-    // TODO(johnniwinther): Move this to _CompilerCoreTypes.
-    compiler.streamClass.ensureResolved(resolution);
     DartType streamOfDynamic = coreTypes.streamType();
     if (!types.isAssignable(expressionType, streamOfDynamic)) {
       reportMessage(node.expression,
@@ -1842,7 +1846,7 @@
           Types.computeInterfaceType(resolution, expressionType);
       if (interfaceType != null) {
         InterfaceType streamType =
-            interfaceType.asInstanceOf(compiler.streamClass);
+            interfaceType.asInstanceOf(streamOfDynamic.element);
         if (streamType != null) {
           DartType streamElementType = streamType.typeArguments.first;
           if (!types.isAssignable(streamElementType, elementType)) {
diff --git a/pkg/compiler/lib/src/types/abstract_value_domain.dart b/pkg/compiler/lib/src/types/abstract_value_domain.dart
new file mode 100644
index 0000000..6512c5a
--- /dev/null
+++ b/pkg/compiler/lib/src/types/abstract_value_domain.dart
@@ -0,0 +1,169 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.abstract_value_domain;
+
+import '../constants/values.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../native/native.dart' show
+    NativeBehavior;
+import '../universe/selector.dart' show
+    Selector;
+import '../universe/universe.dart' show
+    ReceiverConstraint;
+
+enum AbstractBool {
+  True, False, Maybe, Nothing
+}
+
+/// A value in an abstraction of runtime values.
+abstract class AbstractValue {}
+
+/// A system that implements an abstraction over runtime values and provides
+/// access to interprocedural analysis results.
+// TODO(johnniwinther): Consider extracting the inference result access from
+// this interface.
+abstract class AbstractValueDomain {
+  AbstractValue get dynamicType;
+  AbstractValue get typeType;
+  AbstractValue get functionType;
+  AbstractValue get boolType;
+  AbstractValue get intType;
+  AbstractValue get doubleType;
+  AbstractValue get numType;
+  AbstractValue get stringType;
+  AbstractValue get listType;
+  AbstractValue get mapType;
+  AbstractValue get nonNullType;
+  AbstractValue get nullType;
+  AbstractValue get extendableArrayType;
+  AbstractValue get fixedArrayType;
+  AbstractValue get arrayType;
+  AbstractValue get uint31Type;
+  AbstractValue get uint32Type;
+  AbstractValue get uintType;
+
+  AbstractValue get numStringBoolType;
+
+  AbstractValue get fixedLengthType;
+
+  AbstractValue get interceptorType;
+
+  AbstractValue get interceptedTypes;
+
+  bool methodUsesReceiverArgument(FunctionElement function);
+
+  Element locateSingleElement(AbstractValue mask, Selector selector);
+
+  ClassElement singleClass(AbstractValue mask);
+
+  bool needsNoSuchMethodHandling(AbstractValue mask, Selector selector);
+
+  AbstractValue getReceiverType(MethodElement method);
+
+  AbstractValue getParameterType(ParameterElement parameter);
+
+  AbstractValue getReturnType(FunctionElement function);
+
+  AbstractValue getInvokeReturnType(Selector selector, AbstractValue mask);
+
+  AbstractValue getFieldType(FieldElement field);
+
+  AbstractValue join(AbstractValue a, AbstractValue b);
+
+  AbstractValue intersection(AbstractValue a, AbstractValue b);
+
+  AbstractValue getTypeOf(ConstantValue constant);
+
+  /// Returns the constant value if the [AbstractValue] represents a single
+  /// constant value. Returns `null` if [value] is not a constant.
+  ConstantValue getConstantOf(AbstractValue value);
+
+  AbstractValue nonNullExact(ClassElement element);
+
+  AbstractValue nonNullSubclass(ClassElement element);
+
+  AbstractValue nonNullSubtype(ClassElement element);
+
+  bool isDefinitelyBool(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyNum(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyString(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyNumStringBool(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyNotNumStringBool(AbstractValue t);
+
+  /// True if all values of [t] are either integers or not numbers at all.
+  ///
+  /// This does not imply that the value is an integer, since most other values
+  /// such as null are also not a non-integer double.
+  bool isDefinitelyNotNonIntegerDouble(AbstractValue t);
+
+  bool isDefinitelyNonNegativeInt(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyInt(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyUint31(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyUint32(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyUint(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyArray(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyMutableArray(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyFixedArray(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyExtendableArray(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyIndexable(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyMutableIndexable(AbstractValue t, {bool allowNull: false});
+
+  bool isDefinitelyFixedLengthIndexable(AbstractValue t,
+                                        {bool allowNull: false});
+
+  bool isDefinitelyIntercepted(AbstractValue t, {bool allowNull});
+
+  /// Given a class from the interceptor hierarchy, returns an [AbstractValue]
+  /// matching all values with that interceptor (or a subtype thereof).
+  AbstractValue getInterceptorSubtypes(ClassElement class_);
+
+  bool areDisjoint(AbstractValue leftType, AbstractValue rightType);
+
+  bool isMorePreciseOrEqual(AbstractValue t1, AbstractValue t2);
+
+  AbstractBool isSubtypeOf(AbstractValue value,
+                           DartType type,
+                           {bool allowNull});
+
+  /// Returns whether [value] is one of the falsy values: false, 0, -0, NaN,
+  /// the empty string, or null.
+  AbstractBool boolify(AbstractValue value);
+
+  AbstractBool strictBoolify(AbstractValue type);
+
+  /// Create a type mask containing at least all subtypes of [type].
+  AbstractValue subtypesOf(DartType type);
+
+  /// Returns a subset of [receiver] containing at least the types
+  /// that can respond to [selector] without throwing.
+  AbstractValue receiverTypeFor(Selector selector, AbstractValue receiver);
+
+  /// The result of an index operation on [value], or the dynamic type if
+  /// unknown.
+  AbstractValue elementTypeOfIndexable(AbstractValue value);
+
+  /// The length property of [value], or `null` if unknown.
+  int getContainerLength(AbstractValue value);
+
+  /// Returns the type of the entry of [container] at a given index.
+  /// Returns `null` if unknown.
+  AbstractValue indexWithConstant(AbstractValue container,
+                                  ConstantValue indexValue);
+}
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index ce19f17..6516d96 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -546,9 +546,8 @@
    */
   static bool hasConcreteMatch(ClassElement cls,
                                Selector selector,
-                               World world) {
-    assert(invariant(cls,
-        world.compiler.resolverWorld.isInstantiated(cls),
+                               ClassWorld world) {
+    assert(invariant(cls, world.isInstantiated(cls),
         message: '$cls has not been instantiated.'));
     Element element = findMatchIn(cls, selector);
     if (element == null) return false;
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index 2f5754f..3339738 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -75,7 +75,7 @@
  * operations on it are not guaranteed to be precise and they may
  * yield conservative answers that contain too many classes.
  */
-abstract class TypeMask implements ReceiverConstraint {
+abstract class TypeMask implements ReceiverConstraint, AbstractValue {
   factory TypeMask(ClassElement base,
                    int kind,
                    bool isNullable,
@@ -89,7 +89,7 @@
   factory TypeMask.exact(ClassElement base, ClassWorld classWorld) {
     assert(invariant(base, classWorld.isInstantiated(base),
         message: () => "Cannot create exact type mask for uninstantiated "
-                       "class $base.\n${classWorld.dump()}"));
+                       "class $base.\n${classWorld.dump(base)}"));
     return new FlatTypeMask.exact(base);
   }
 
@@ -99,21 +99,31 @@
   }
 
   factory TypeMask.subclass(ClassElement base, ClassWorld classWorld) {
-    if (classWorld.hasAnyStrictSubclass(base)) {
-      return new FlatTypeMask.subclass(base);
+    assert(invariant(base, classWorld.isInstantiated(base),
+        message: () => "Cannot create subclass type mask for uninstantiated "
+                       "class $base.\n${classWorld.dump(base)}"));
+    ClassElement topmost = classWorld.getLubOfInstantiatedSubclasses(base);
+    if (topmost == null) {
+      return new TypeMask.empty();
+    } else if (classWorld.hasAnyStrictSubclass(topmost)) {
+      return new FlatTypeMask.subclass(topmost);
     } else {
-      return new TypeMask.exactOrEmpty(base, classWorld);
+      return new TypeMask.exact(topmost, classWorld);
     }
   }
 
   factory TypeMask.subtype(ClassElement base, ClassWorld classWorld) {
-    if (classWorld.hasOnlySubclasses(base)) {
-      return new TypeMask.subclass(base, classWorld);
+    ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base);
+    if (topmost == null) {
+      return new TypeMask.empty();
     }
-    if (classWorld.hasAnyStrictSubtype(base)) {
-      return new FlatTypeMask.subtype(base);
+    if (classWorld.hasOnlySubclasses(topmost)) {
+      return new TypeMask.subclass(topmost, classWorld);
+    }
+    if (classWorld.hasAnyStrictSubtype(topmost)) {
+      return new FlatTypeMask.subtype(topmost);
     } else {
-      return new TypeMask.exactOrEmpty(base, classWorld);
+      return new TypeMask.exact(topmost, classWorld);
     }
   }
 
@@ -121,8 +131,8 @@
 
   factory TypeMask.nonNullExact(ClassElement base, ClassWorld classWorld) {
     assert(invariant(base, classWorld.isInstantiated(base),
-        message: () => "Cannot create exact type mask for "
-                 "uninstantiated class $base.\n${classWorld.dump(base)}"));
+        message: () => "Cannot create exact type mask for uninstantiated "
+                       "class $base.\n${classWorld.dump(base)}"));
     return new FlatTypeMask.nonNullExact(base);
   }
 
@@ -135,21 +145,31 @@
   }
 
   factory TypeMask.nonNullSubclass(ClassElement base, ClassWorld classWorld) {
-    if (classWorld.hasAnyStrictSubclass(base)) {
-      return new FlatTypeMask.nonNullSubclass(base);
+    assert(invariant(base, classWorld.isInstantiated(base),
+        message: () => "Cannot create subclass type mask for uninstantiated "
+                       "class $base.\n${classWorld.dump(base)}"));
+    ClassElement topmost = classWorld.getLubOfInstantiatedSubclasses(base);
+    if (topmost == null) {
+      return new TypeMask.nonNullEmpty();
+    } else if (classWorld.hasAnyStrictSubclass(topmost)) {
+      return new FlatTypeMask.nonNullSubclass(topmost);
     } else {
-      return new TypeMask.nonNullExactOrEmpty(base, classWorld);
+      return new TypeMask.nonNullExact(topmost, classWorld);
     }
   }
 
   factory TypeMask.nonNullSubtype(ClassElement base, ClassWorld classWorld) {
-    if (classWorld.hasOnlySubclasses(base)) {
-      return new TypeMask.nonNullSubclass(base, classWorld);
+    ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base);
+    if (topmost == null) {
+      return new TypeMask.nonNullEmpty();
     }
-    if (classWorld.hasAnyStrictSubtype(base)) {
-      return new FlatTypeMask.nonNullSubtype(base);
+    if (classWorld.hasOnlySubclasses(topmost)) {
+      return new TypeMask.nonNullSubclass(topmost, classWorld);
+    }
+    if (classWorld.hasAnyStrictSubtype(topmost)) {
+      return new FlatTypeMask.nonNullSubtype(topmost);
     } else {
-      return new TypeMask.nonNullExactOrEmpty(base, classWorld);
+      return new TypeMask.nonNullExact(topmost, classWorld);
     }
   }
 
@@ -315,12 +335,6 @@
   TypeMask intersection(TypeMask other, ClassWorld classWorld);
 
   /**
-   * Returns whether this [TypeMask] applied to [selector] can hit a
-   * [noSuchMethod].
-   */
-  bool needsNoSuchMethodHandling(Selector selector, ClassWorld classWorld);
-
-  /**
    * Returns whether [element] is a potential target when being
    * invoked on this type mask. [selector] is used to ensure library
    * privacy is taken into account.
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index 9d91f99..b9e5969 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -28,6 +28,9 @@
     ClassWorld,
     World;
 
+import 'abstract_value_domain.dart' show
+    AbstractValue;
+
 part 'container_type_mask.dart';
 part 'dictionary_type_mask.dart';
 part 'flat_type_mask.dart';
@@ -87,6 +90,9 @@
   TypeMask constMapTypeCache;
   TypeMask stringTypeCache;
   TypeMask typeTypeCache;
+  TypeMask syncStarIterableTypeCache;
+  TypeMask asyncFutureTypeCache;
+  TypeMask asyncStarStreamTypeCache;
 
   TypeMask get dynamicType {
     if (dynamicTypeCache == null) {
@@ -232,6 +238,30 @@
     return typeTypeCache;
   }
 
+  TypeMask get syncStarIterableType {
+    if (syncStarIterableTypeCache == null) {
+      syncStarIterableTypeCache = new TypeMask.nonNullExact(
+          compiler.backend.syncStarIterableImplementation, compiler.world);
+    }
+    return syncStarIterableTypeCache;
+  }
+
+  TypeMask get asyncFutureType {
+    if (asyncFutureTypeCache == null) {
+      asyncFutureTypeCache = new TypeMask.nonNullExact(
+          compiler.backend.asyncFutureImplementation, compiler.world);
+    }
+    return asyncFutureTypeCache;
+  }
+
+  TypeMask get asyncStarStreamType {
+    if (asyncStarStreamTypeCache == null) {
+      asyncStarStreamTypeCache = new TypeMask.nonNullExact(
+          compiler.backend.asyncStarStreamImplementation, compiler.world);
+    }
+    return asyncStarStreamTypeCache;
+  }
+
   TypeMask get nullType {
     if (nullTypeCache == null) {
       // TODO(johnniwinther): Assert that the null type has been resolved.
@@ -287,7 +317,7 @@
   TypeMask getGuaranteedTypeOfElement(Element element) {
     return measure(() {
       // TODO(24489): trust some JsInterop types.
-      if (element.isJsInterop) {
+      if (compiler.backend.isJsInterop(element)) {
         return dynamicType;
       }
       TypeMask guaranteedType = typesInferrer.getTypeOfElement(element);
@@ -298,7 +328,7 @@
   TypeMask getGuaranteedReturnTypeOfElement(Element element) {
     return measure(() {
       // TODO(24489): trust some JsInterop types.
-      if (element.isJsInterop) {
+      if (compiler.backend.isJsInterop(element)) {
         return dynamicType;
       }
 
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 63a421d..4a8397e 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -94,26 +94,31 @@
     bool useSubclass = masks.every((e) => !e.isSubtype);
     bool isNullable = masks.any((e) => e.isNullable);
 
+    List<ClassElement> masksBases = masks.map((mask) => mask.base).toList();
     Iterable<ClassElement> candidates =
-        classWorld.commonSupertypesOf(masks.map((mask) => mask.base));
+        classWorld.commonSupertypesOf(masksBases);
 
     // Compute the best candidate and its kind.
     ClassElement bestElement;
     int bestKind;
     int bestSize;
     for (ClassElement candidate in candidates) {
-      Iterable<ClassElement> subclasses = useSubclass
-          ? classWorld.strictSubclassesOf(candidate)
-          : const <ClassElement>[];
+      bool isInstantiatedStrictSubclass(cls) => cls != candidate &&
+          classWorld.isDirectlyInstantiated(cls) &&
+          classWorld.isSubclassOf(cls, candidate);
+
       int size;
       int kind;
-      if (masks.every((t) => subclasses.contains(t.base))) {
+      if (useSubclass && masksBases.every(isInstantiatedStrictSubclass)) {
         // If both [this] and [other] are subclasses of the supertype,
         // then we prefer to construct a subclass type mask because it
         // will always be at least as small as the corresponding
         // subtype type mask.
         kind = FlatTypeMask.SUBCLASS;
-        size = subclasses.length;
+        // TODO(sigmund, johnniwinther): computing length here (and below) is
+        // expensive. If we can't prevent `flatten` from being called a lot, it
+        // might be worth caching results.
+        size = classWorld.strictSubclassesOf(candidate).length;
         assert(size <= classWorld.strictSubtypesOf(candidate).length);
       } else {
         kind = FlatTypeMask.SUBTYPE;
diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
index 461950f..727390a 100644
--- a/pkg/compiler/lib/src/universe/call_structure.dart
+++ b/pkg/compiler/lib/src/universe/call_structure.dart
@@ -186,8 +186,8 @@
       ConstructorElement callee,
       /*T*/ compileArgument(ParameterElement element),
       /*T*/ compileConstant(ParameterElement element)) {
-    assert(invariant(caller, !callee.isErroneous,
-        message: "Cannot compute arguments to erroneous constructor: "
+    assert(invariant(caller, !callee.isMalformed,
+        message: "Cannot compute arguments to malformed constructor: "
                  "$caller calling $callee."));
 
     FunctionSignature signature = caller.functionSignature;
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index b418976..d895de2 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -4,9 +4,21 @@
 
 library dart2js.world.class_set;
 
-import 'dart:collection' show IterableBase;
-import '../elements/elements.dart' show ClassElement;
-import '../util/util.dart' show Link;
+import 'dart:collection' show
+    IterableBase;
+import '../elements/elements.dart' show
+    ClassElement;
+import '../util/enumset.dart' show
+    EnumSet;
+import '../util/util.dart' show
+    Link;
+
+/// Enum for the different kinds of instantiation of a class.
+enum Instantiation {
+  UNINSTANTIATED,
+  DIRECTLY_INSTANTIATED,
+  INDIRECTLY_INSTANTIATED,
+}
 
 /// Node for [cls] in a tree forming the subclass relation of [ClassElement]s.
 ///
@@ -34,7 +46,58 @@
 ///       E
 ///
 class ClassHierarchyNode {
+  /// Enum set for selecting instantiated classes in
+  /// [ClassHierarchyNode.subclassesByMask],
+  /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
+  static final EnumSet<Instantiation> INSTANTIATED =
+      new EnumSet<Instantiation>.fromValues(
+          const <Instantiation>[
+              Instantiation.DIRECTLY_INSTANTIATED,
+              Instantiation.INDIRECTLY_INSTANTIATED],
+          fixed: true);
+
+  /// Enum set for selecting directly instantiated classes in
+  /// [ClassHierarchyNode.subclassesByMask],
+  /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
+  static final EnumSet<Instantiation> DIRECTLY_INSTANTIATED =
+      new EnumSet<Instantiation>.fromValues(
+          const <Instantiation>[Instantiation.DIRECTLY_INSTANTIATED],
+          fixed: true);
+
+  /// Enum set for selecting all classes in
+  /// [ClassHierarchyNode.subclassesByMask],
+  /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
+  static final EnumSet<Instantiation> ALL =
+      new EnumSet<Instantiation>.fromValues(
+          Instantiation.values,
+          fixed: true);
+
+  /// Creates an enum set for selecting the returned classes in
+  /// [ClassHierarchyNode.subclassesByMask],
+  /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
+  static EnumSet<Instantiation> createMask(
+      {bool includeDirectlyInstantiated: true,
+       bool includeIndirectlyInstantiated: true,
+       bool includeUninstantiated: true}) {
+    EnumSet<Instantiation> mask = new EnumSet<Instantiation>();
+    if (includeDirectlyInstantiated) {
+      mask.add(Instantiation.DIRECTLY_INSTANTIATED);
+    }
+    if (includeIndirectlyInstantiated) {
+      mask.add(Instantiation.INDIRECTLY_INSTANTIATED);
+    }
+    if (includeUninstantiated) {
+      mask.add(Instantiation.UNINSTANTIATED);
+    }
+    return mask;
+  }
+
   final ClassElement cls;
+  final EnumSet<Instantiation> _mask =
+      new EnumSet<Instantiation>.fromValues(
+          const <Instantiation>[Instantiation.UNINSTANTIATED]);
+
+  ClassElement _leastUpperInstantiatedSubclass;
 
   /// `true` if [cls] has been directly instantiated.
   ///
@@ -43,7 +106,22 @@
   ///   class C extends B {}
   ///   main() => new C();
   ///
-  bool isDirectlyInstantiated = false;
+  bool get isDirectlyInstantiated =>
+      _mask.contains(Instantiation.DIRECTLY_INSTANTIATED);
+
+  void set isDirectlyInstantiated(bool value) {
+    if (value != isDirectlyInstantiated) {
+      if (value) {
+        _mask.remove(Instantiation.UNINSTANTIATED);
+        _mask.add(Instantiation.DIRECTLY_INSTANTIATED);
+      } else {
+        _mask.remove(Instantiation.DIRECTLY_INSTANTIATED);
+        if (_mask.isEmpty) {
+          _mask.add(Instantiation.UNINSTANTIATED);
+        }
+      }
+    }
+  }
 
   /// `true` if [cls] has been instantiated through subclasses.
   ///
@@ -53,7 +131,22 @@
   ///   class C extends B {}
   ///   main() => [new B(), new C()];
   ///
-  bool isIndirectlyInstantiated = false;
+  bool get isIndirectlyInstantiated =>
+      _mask.contains(Instantiation.INDIRECTLY_INSTANTIATED);
+
+  void set isIndirectlyInstantiated(bool value) {
+    if (value != isIndirectlyInstantiated) {
+      if (value) {
+        _mask.remove(Instantiation.UNINSTANTIATED);
+        _mask.add(Instantiation.INDIRECTLY_INSTANTIATED);
+      } else {
+        _mask.remove(Instantiation.INDIRECTLY_INSTANTIATED);
+        if (_mask.isEmpty) {
+          _mask.add(Instantiation.UNINSTANTIATED);
+        }
+      }
+    }
+  }
 
   /// The nodes for the direct subclasses of [cls].
   Link<ClassHierarchyNode> _directSubclasses = const Link<ClassHierarchyNode>();
@@ -93,23 +186,74 @@
        bool includeIndirectlyInstantiated: true,
        bool includeUninstantiated: true,
        bool strict: false}) {
-    return new ClassHierarchyNodeIterable(
-        this,
-        includeRoot: !strict,
+    EnumSet<Instantiation> mask = createMask(
         includeDirectlyInstantiated: includeDirectlyInstantiated,
-        includeIndirectlyInstantiated: includeIndirectlyInstantiated,
+        includeIndirectlyInstantiated:includeIndirectlyInstantiated,
         includeUninstantiated: includeUninstantiated);
+    return subclassesByMask(mask, strict: strict);
+  }
+
+  /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
+  ///
+  /// Subclasses are included if their instantiation properties intersect with
+  /// their corresponding [Instantiation] values in [mask]. If [strict] is
+  /// `true`, [cls] itself is _not_ returned.
+  Iterable<ClassElement> subclassesByMask(
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    return new ClassHierarchyNodeIterable(
+        this, mask, includeRoot: !strict);
+  }
+
+  /// Returns the most specific subclass of [cls] (including [cls]) that is
+  /// directly instantiated or a superclass of all directly instantiated
+  /// subclasses. If [cls] is not instantiated, `null` is returned.
+  ClassElement getLubOfInstantiatedSubclasses() {
+    if (!isInstantiated) return null;
+    if (_leastUpperInstantiatedSubclass == null) {
+      _leastUpperInstantiatedSubclass =
+          _computeLeastUpperInstantiatedSubclass();
+    }
+    return _leastUpperInstantiatedSubclass;
+  }
+
+  ClassElement _computeLeastUpperInstantiatedSubclass() {
+    if (isDirectlyInstantiated) {
+      return cls;
+    }
+    ClassHierarchyNode subclass;
+    for (Link<ClassHierarchyNode> link = _directSubclasses;
+         !link.isEmpty;
+         link = link.tail) {
+      if (link.head.isInstantiated) {
+        if (subclass == null) {
+          subclass = link.head;
+        } else {
+          return cls;
+        }
+      }
+    }
+    if (subclass != null) {
+      return subclass.getLubOfInstantiatedSubclasses();
+    }
+    return cls;
   }
 
   void printOn(StringBuffer sb, String indentation,
                {bool instantiatedOnly: false,
+                bool sorted: true,
                 ClassElement withRespectTo}) {
 
     bool isRelatedTo(ClassElement subclass) {
-      return subclass.implementsInterface(withRespectTo);
+      return subclass == withRespectTo ||
+          subclass.implementsInterface(withRespectTo);
     }
 
-    sb.write('$indentation$cls');
+    sb.write(indentation);
+    if (cls.isAbstract) {
+      sb.write('abstract ');
+    }
+    sb.write('class ${cls.name}:');
     if (isDirectlyInstantiated) {
       sb.write(' directly');
     }
@@ -120,11 +264,14 @@
     if (_directSubclasses.isEmpty) {
       sb.write(']');
     } else {
+      var subclasses = _directSubclasses;
+      if (sorted) {
+        subclasses = _directSubclasses.toList()..sort((a, b) {
+          return a.cls.name.compareTo(b.cls.name);
+        });
+      }
       bool needsComma = false;
-      for (Link<ClassHierarchyNode> link = _directSubclasses;
-           !link.isEmpty;
-           link = link.tail) {
-        ClassHierarchyNode child = link.head;
+      for (ClassHierarchyNode child in subclasses) {
         if (instantiatedOnly && !child.isInstantiated) {
           continue;
         }
@@ -140,6 +287,7 @@
             sb,
             '$indentation  ',
             instantiatedOnly: instantiatedOnly,
+            sorted: sorted,
             withRespectTo: withRespectTo);
         needsComma = true;
       }
@@ -211,6 +359,7 @@
 ///
 class ClassSet {
   final ClassHierarchyNode node;
+  ClassElement _leastUpperInstantiatedSubtype;
 
   List<ClassHierarchyNode> _directSubtypes;
 
@@ -229,11 +378,22 @@
        bool includeIndirectlyInstantiated: true,
        bool includeUninstantiated: true,
        bool strict: false}) {
-    return node.subclasses(
-        strict: strict,
+    EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
         includeDirectlyInstantiated: includeDirectlyInstantiated,
-        includeIndirectlyInstantiated: includeIndirectlyInstantiated,
+        includeIndirectlyInstantiated:includeIndirectlyInstantiated,
         includeUninstantiated: includeUninstantiated);
+    return subclassesByMask(mask, strict: strict);
+  }
+
+  /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
+  ///
+  /// Subclasses are included if their instantiation properties intersect with
+  /// their corresponding [Instantiation] values in [mask]. If [strict] is
+  /// `true`, [cls] itself is _not_ returned.
+  Iterable<ClassElement> subclassesByMask(
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    return node.subclassesByMask(mask, strict: strict);
   }
 
   /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
@@ -247,18 +407,31 @@
        bool includeIndirectlyInstantiated: true,
        bool includeUninstantiated: true,
        bool strict: false}) {
-    if (_directSubtypes == null) {
-      return node.subclasses(
-          strict: strict,
-          includeDirectlyInstantiated: includeDirectlyInstantiated,
-          includeIndirectlyInstantiated: includeIndirectlyInstantiated,
-          includeUninstantiated: includeUninstantiated);
-    }
-    return new SubtypesIterable.SubtypesIterator(this,
-        includeRoot: !strict,
+    EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
         includeDirectlyInstantiated: includeDirectlyInstantiated,
-        includeIndirectlyInstantiated: includeIndirectlyInstantiated,
+        includeIndirectlyInstantiated:includeIndirectlyInstantiated,
         includeUninstantiated: includeUninstantiated);
+    return subtypesByMask(mask, strict: strict);
+  }
+
+
+  /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
+  ///
+  /// Subtypes are included if their instantiation properties intersect with
+  /// their corresponding [Instantiation] values in [mask]. If [strict] is
+  /// `true`, [cls] itself is _not_ returned.
+  Iterable<ClassElement> subtypesByMask(
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    if (_directSubtypes == null) {
+      return node.subclassesByMask(
+          mask,
+          strict: strict);
+    }
+
+    return new SubtypesIterable.SubtypesIterator(this,
+        mask,
+        includeRoot: !strict);
   }
 
   /// Adds [subtype] as a subtype of [cls].
@@ -311,6 +484,42 @@
     }
   }
 
+  /// Returns the most specific subtype of [cls] (including [cls]) that is
+  /// directly instantiated or a superclass of all directly instantiated
+  /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned.
+  ClassElement getLubOfInstantiatedSubtypes() {
+    if (_leastUpperInstantiatedSubtype == null) {
+      _leastUpperInstantiatedSubtype = _computeLeastUpperInstantiatedSubtype();
+    }
+    return _leastUpperInstantiatedSubtype;
+  }
+
+  ClassElement _computeLeastUpperInstantiatedSubtype() {
+    if (node.isDirectlyInstantiated) {
+      return cls;
+    }
+    if (_directSubtypes == null) {
+      return node.getLubOfInstantiatedSubclasses();
+    }
+    ClassHierarchyNode subtype;
+    if (node.isInstantiated) {
+      subtype = node;
+    }
+    for (ClassHierarchyNode subnode in _directSubtypes) {
+      if (subnode.isInstantiated) {
+        if (subtype == null) {
+          subtype = subnode;
+        } else {
+          return cls;
+        }
+      }
+    }
+    if (subtype != null) {
+      return subtype.getLubOfInstantiatedSubclasses();
+    }
+    return null;
+  }
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write('[\n');
@@ -330,17 +539,13 @@
 /// Iterable for subclasses of a [ClassHierarchyNode].
 class ClassHierarchyNodeIterable extends IterableBase<ClassElement> {
   final ClassHierarchyNode root;
+  final EnumSet<Instantiation> mask;
   final bool includeRoot;
-  final bool includeDirectlyInstantiated;
-  final bool includeIndirectlyInstantiated;
-  final bool includeUninstantiated;
 
   ClassHierarchyNodeIterable(
       this.root,
-      {this.includeRoot: true,
-       this.includeDirectlyInstantiated: true,
-       this.includeIndirectlyInstantiated: true,
-       this.includeUninstantiated: true}) {
+      this.mask,
+      {this.includeRoot: true}) {
     if (root == null) throw new StateError("No root for iterable.");
   }
 
@@ -373,14 +578,12 @@
 
   bool get includeRoot => iterable.includeRoot;
 
-  bool get includeDirectlyInstantiated => iterable.includeDirectlyInstantiated;
+  EnumSet<Instantiation> get mask => iterable.mask;
 
-  bool get includeIndirectlyInstantiated {
-    return iterable.includeIndirectlyInstantiated;
+  bool get includeUninstantiated {
+    return mask.contains(Instantiation.UNINSTANTIATED);
   }
 
-  bool get includeUninstantiated => iterable.includeUninstantiated;
-
   @override
   ClassElement get current {
     return currentNode != null ? currentNode.cls : null;
@@ -429,33 +632,20 @@
   /// Returns `true` if the class of [node] is a valid result for this iterator.
   bool _isValid(ClassHierarchyNode node) {
     if (!includeRoot && node == root) return false;
-    if (includeDirectlyInstantiated && node.isDirectlyInstantiated) {
-      return true;
-    }
-    if (includeIndirectlyInstantiated && node.isIndirectlyInstantiated) {
-      return true;
-    }
-    if (includeUninstantiated && !node.isInstantiated) {
-      return true;
-    }
-    return false;
+    return mask.intersects(node._mask);
   }
 }
 
 /// Iterable for the subtypes in a [ClassSet].
 class SubtypesIterable extends IterableBase<ClassElement> {
   final ClassSet subtypeSet;
+  final EnumSet<Instantiation> mask;
   final bool includeRoot;
-  final bool includeDirectlyInstantiated;
-  final bool includeIndirectlyInstantiated;
-  final bool includeUninstantiated;
 
   SubtypesIterable.SubtypesIterator(
       this.subtypeSet,
-      {this.includeRoot: true,
-       this.includeDirectlyInstantiated: true,
-       this.includeIndirectlyInstantiated: true,
-       this.includeUninstantiated: true});
+      this.mask,
+      {this.includeRoot: true});
 
   @override
   Iterator<ClassElement> get iterator => new SubtypesIterator(this);
@@ -471,13 +661,7 @@
 
   bool get includeRoot => iterable.includeRoot;
 
-  bool get includeDirectlyInstantiated => iterable.includeDirectlyInstantiated;
-
-  bool get includeIndirectlyInstantiated {
-    return iterable.includeIndirectlyInstantiated;
-  }
-
-  bool get includeUninstantiated => iterable.includeUninstantiated;
+  EnumSet<Instantiation> get mask => iterable.mask;
 
   @override
   ClassElement get current {
@@ -491,11 +675,9 @@
   bool moveNext() {
     if (elements == null && hierarchyNodes == null) {
       // Initial state. Iterate through subclasses.
-      elements = iterable.subtypeSet.node.subclasses(
-          strict: !includeRoot,
-          includeDirectlyInstantiated: includeDirectlyInstantiated,
-          includeIndirectlyInstantiated: includeIndirectlyInstantiated,
-          includeUninstantiated: includeUninstantiated).iterator;
+      elements = iterable.subtypeSet.node.subclassesByMask(
+          mask,
+          strict: !includeRoot).iterator;
     }
     if (elements != null && elements.moveNext()) {
       return true;
@@ -505,10 +687,7 @@
       hierarchyNodes = iterable.subtypeSet._directSubtypes.iterator;
     }
     while (hierarchyNodes.moveNext()) {
-      elements = hierarchyNodes.current.subclasses(
-          includeDirectlyInstantiated: includeDirectlyInstantiated,
-          includeIndirectlyInstantiated: includeIndirectlyInstantiated,
-          includeUninstantiated: includeUninstantiated).iterator;
+      elements = hierarchyNodes.current.subclassesByMask(mask).iterator;
       if (elements.moveNext()) {
         return true;
       }
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index 72a1813..27273341 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -19,6 +19,8 @@
 
 import 'selector.dart' show
     Selector;
+import 'universe.dart' show
+    ReceiverConstraint;
 
 // TODO(kasperl): This actually holds getters and setters just fine
 // too and stricly they aren't functions. Maybe this needs a better
@@ -64,36 +66,37 @@
 
   /// Returns an object that allows iterating over all the functions
   /// that may be invoked with the given [selector].
-  Iterable<Element> filter(Selector selector, TypeMask mask) {
-    return query(selector, mask).functions;
+  Iterable<Element> filter(Selector selector, ReceiverConstraint constraint) {
+    return query(selector, constraint).functions;
   }
 
   /// Returns the mask for the potential receivers of a dynamic call to
-  /// [selector] on [mask].
+  /// [selector] on [constraint].
   ///
-  /// This will reduce the set of classes in [mask] to a [TypeMask] of the set
-  /// of classes that actually implement the selected member or implement the
-  /// handling 'noSuchMethod' where the selected member is unimplemented.
-  TypeMask receiverType(Selector selector, TypeMask mask) {
-    return query(selector, mask).computeMask(classWorld);
+  /// This will narrow the constraints of [constraint] to a [TypeMask] of the
+  /// set of classes that actually implement the selected member or implement
+  /// the handling 'noSuchMethod' where the selected member is unimplemented.
+  TypeMask receiverType(Selector selector, ReceiverConstraint constraint) {
+    return query(selector, constraint).computeMask(classWorld);
   }
 
   SelectorMask _createSelectorMask(
-      Selector selector, TypeMask mask, ClassWorld classWorld) {
-    return mask != null
-        ? new SelectorMask(selector, mask)
+      Selector selector, ReceiverConstraint constraint, ClassWorld classWorld) {
+    return constraint != null
+        ? new SelectorMask(selector, constraint)
         : new SelectorMask(selector,
             new TypeMask.subclass(classWorld.objectClass, classWorld));
   }
 
   /// Returns the set of functions that can be the target of a call to
-  /// [selector] on a receiver of type [mask] including 'noSuchMethod' methods
-  /// where applicable.
-  FunctionSetQuery query(Selector selector, TypeMask mask) {
+  /// [selector] on a receiver constrained by [constraint] including
+  /// 'noSuchMethod' methods where applicable.
+  FunctionSetQuery query(Selector selector, ReceiverConstraint constraint) {
     String name = selector.name;
-    SelectorMask selectorMask = _createSelectorMask(selector, mask, classWorld);
+    SelectorMask selectorMask =
+        _createSelectorMask(selector, constraint, classWorld);
     SelectorMask noSuchMethodMask =
-        new SelectorMask(Selectors.noSuchMethod_, selectorMask.mask);
+        new SelectorMask(Selectors.noSuchMethod_, selectorMask.constraint);
     FunctionSetNode node = nodes[name];
     FunctionSetNode noSuchMethods = nodes[Identifiers.noSuchMethod_];
     if (node != null) {
@@ -115,38 +118,38 @@
   }
 }
 
-/// A selector/mask pair representing the dynamic invocation of [selector] on
-/// a receiver of type [mask].
+/// A selector/constraint pair representing the dynamic invocation of [selector]
+/// on a receiver constrained by [constraint].
 class SelectorMask {
   final Selector selector;
-  final TypeMask mask;
+  final ReceiverConstraint constraint;
   final int hashCode;
 
-  SelectorMask(Selector selector, TypeMask mask)
+  SelectorMask(Selector selector, ReceiverConstraint constraint)
       : this.selector = selector,
-        this.mask = mask,
+        this.constraint = constraint,
         this.hashCode =
-            Hashing.mixHashCodeBits(selector.hashCode, mask.hashCode) {
-    assert(mask != null);
+            Hashing.mixHashCodeBits(selector.hashCode, constraint.hashCode) {
+    assert(constraint != null);
   }
 
   String get name => selector.name;
 
   bool applies(Element element, ClassWorld classWorld) {
     if (!selector.appliesUnnamed(element, classWorld)) return false;
-    return mask.canHit(element, selector, classWorld);
+    return constraint.canHit(element, selector, classWorld);
   }
 
   bool needsNoSuchMethodHandling(ClassWorld classWorld) {
-    return mask.needsNoSuchMethodHandling(selector, classWorld);
+    return constraint.needsNoSuchMethodHandling(selector, classWorld);
   }
 
   bool operator ==(other) {
     if (identical(this, other)) return true;
-    return selector == other.selector && mask == other.mask;
+    return selector == other.selector && constraint == other.constraint;
   }
 
-  String toString() => '($selector,$mask)';
+  String toString() => '($selector,$constraint)';
 }
 
 /// A node in the [FunctionSet] caching all [FunctionSetQuery] object for
@@ -298,8 +301,11 @@
         .map((cls) {
           if (classWorld.backend.isNullImplementation(cls)) {
             return const TypeMask.empty();
-          } else {
+          } else if (classWorld.isInstantiated(cls.declaration)) {
             return new TypeMask.nonNullSubclass(cls.declaration, classWorld);
+          } else {
+            // TODO(johnniwinther): Avoid the need for this case.
+            return const TypeMask.empty();
           }
         }),
         classWorld);
diff --git a/pkg/compiler/lib/src/universe/universe.dart b/pkg/compiler/lib/src/universe/universe.dart
index 78e586f..8b2f53e 100644
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ b/pkg/compiler/lib/src/universe/universe.dart
@@ -18,28 +18,11 @@
 
 import 'selector.dart' show
     Selector;
-
-class UniverseSelector {
-  final Selector selector;
-  final ReceiverConstraint mask;
-
-  UniverseSelector(this.selector, this.mask);
-
-  bool appliesUnnamed(Element element, ClassWorld world) {
-    return selector.appliesUnnamed(element, world) &&
-        (mask == null || mask.canHit(element, selector, world));
-  }
-
-  int get hashCode => selector.hashCode * 13 + mask.hashCode * 17;
-
-  bool operator ==(other) {
-    if (identical(this, other)) return true;
-    if (other is! UniverseSelector) return false;
-    return selector == other.selector && mask == other.mask;
-  }
-
-  String toString() => '$selector,$mask';
-}
+import 'use.dart' show
+    DynamicUse,
+    DynamicUseKind,
+    StaticUse,
+    StaticUseKind;
 
 /// The known constraint on receiver for a dynamic call site.
 ///
@@ -56,6 +39,10 @@
   /// invoked on a receiver with this constraint. [selector] is used to ensure
   /// library privacy is taken into account.
   bool canHit(Element element, Selector selector, ClassWorld classWorld);
+
+  /// Returns whether this [TypeMask] applied to [selector] can hit a
+  /// [noSuchMethod].
+  bool needsNoSuchMethodHandling(Selector selector, ClassWorld classWorld);
 }
 
 /// The combined constraints on receivers all the dynamic call sites of the same
@@ -75,7 +62,7 @@
 ///     new A().foo(a, b);
 ///     new B().foo(0, 42);
 ///
-/// the selector constaints for dynamic calls to 'foo' with two positional
+/// the selector constraints for dynamic calls to 'foo' with two positional
 /// arguments could be 'receiver of exact instance `A` or `B`'.
 abstract class SelectorConstraints {
   /// Returns `true` if [selector] applies to [element] under these constraints
@@ -141,12 +128,6 @@
   /// See [_directlyInstantiatedClasses].
   final Set<DartType> _instantiatedTypes = new Set<DartType>();
 
-  /// The set of all instantiated classes, either directly, as superclasses or
-  /// as supertypes.
-  ///
-  /// Invariant: Elements are declaration elements.
-  final Set<ClassElement> _allInstantiatedClasses = new Set<ClassElement>();
-
   /// Classes implemented by directly instantiated classes.
   final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
 
@@ -223,13 +204,6 @@
     return _directlyInstantiatedClasses;
   }
 
-  /// All instantiated classes, either directly, as superclasses or as
-  /// supertypes.
-  // TODO(johnniwinther): Improve semantic precision.
-  Iterable<ClassElement> get allInstantiatedClasses {
-    return _allInstantiatedClasses;
-  }
-
   /// All directly instantiated types, that is, the types of the directly
   /// instantiated classes.
   ///
@@ -237,13 +211,6 @@
   // TODO(johnniwinther): Improve semantic precision.
   Iterable<DartType> get instantiatedTypes => _instantiatedTypes;
 
-  /// Returns `true` if [cls] is considered to be instantiated, either directly,
-  /// through subclasses.
-  // TODO(johnniwinther): Improve semantic precision.
-  bool isInstantiated(ClassElement cls) {
-    return _allInstantiatedClasses.contains(cls.declaration);
-  }
-
   /// Returns `true` if [cls] is considered to be implemented by an
   /// instantiated class, either directly, through subclasses or through
   /// subtypes. The latter case only contains spurious information from
@@ -261,6 +228,7 @@
   // TODO(johnniwinther): Support unknown type arguments for generic types.
   void registerTypeInstantiation(InterfaceType type,
                                  {bool byMirrors: false,
+                                  bool isNative: false,
                                   void onImplemented(ClassElement cls)}) {
     _instantiatedTypes.add(type);
     ClassElement cls = type.element;
@@ -269,7 +237,7 @@
         // classes; a native abstract class may have non-abstract subclasses
         // not declared to the program.  Instances of these classes are
         // indistinguishable from the abstract class.
-        || cls.isNative
+        || isNative
         // Likewise, if this registration comes from the mirror system,
         // all bets are off.
         // TODO(herhut): Track classes required by mirrors seperately.
@@ -287,12 +255,6 @@
         }
       });
     }
-    while (cls != null) {
-      if (!_allInstantiatedClasses.add(cls)) {
-        return;
-      }
-      cls = cls.superclass;
-    }
   }
 
   bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
@@ -315,35 +277,37 @@
   }
 
   bool hasInvokedGetter(Element member, World world) {
-    return _hasMatchingSelector(_invokedGetters[member.name], member, world);
+    return _hasMatchingSelector(_invokedGetters[member.name], member, world) ||
+        member.isFunction && methodsNeedingSuperGetter.contains(member);
   }
 
   bool hasInvokedSetter(Element member, World world) {
     return _hasMatchingSelector(_invokedSetters[member.name], member, world);
   }
 
-  bool registerInvocation(UniverseSelector selector) {
-    return _registerNewSelector(selector, _invokedNames);
-  }
-
-  bool registerInvokedGetter(UniverseSelector selector) {
-    return _registerNewSelector(selector, _invokedGetters);
-  }
-
-  bool registerInvokedSetter(UniverseSelector selector) {
-    return _registerNewSelector(selector, _invokedSetters);
+  bool registerDynamicUse(DynamicUse dynamicUse) {
+    switch (dynamicUse.kind) {
+      case DynamicUseKind.INVOKE:
+        return _registerNewSelector(dynamicUse, _invokedNames);
+      case DynamicUseKind.GET:
+        return _registerNewSelector(dynamicUse, _invokedGetters);
+      case DynamicUseKind.SET:
+        return _registerNewSelector(dynamicUse, _invokedSetters);
+    }
   }
 
   bool _registerNewSelector(
-      UniverseSelector universeSelector,
+      DynamicUse dynamicUse,
       Map<String, Map<Selector, SelectorConstraints>> selectorMap) {
-    Selector selector = universeSelector.selector;
+    Selector selector = dynamicUse.selector;
     String name = selector.name;
-    ReceiverConstraint mask = universeSelector.mask;
+    ReceiverConstraint mask = dynamicUse.mask;
     Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
         name, () => new Maplet<Selector, SelectorConstraints>());
     UniverseSelectorConstraints constraints = selectors.putIfAbsent(
-        selector, () => selectorConstraintsStrategy.createSelectorConstraints(selector));
+        selector, () {
+      return selectorConstraintsStrategy.createSelectorConstraints(selector);
+    });
     return constraints.addReceiverConstraint(mask);
   }
 
@@ -390,11 +354,31 @@
     return type;
   }
 
-  void registerStaticFieldUse(FieldElement staticField) {
-    assert(Elements.isStaticOrTopLevel(staticField) && staticField.isField);
-    assert(staticField.isDeclaration);
-
-    allReferencedStaticFields.add(staticField);
+  void registerStaticUse(StaticUse staticUse) {
+    Element element = staticUse.element;
+    if (Elements.isStaticOrTopLevel(element) && element.isField) {
+      allReferencedStaticFields.add(element);
+    }
+    switch (staticUse.kind) {
+      case StaticUseKind.STATIC_TEAR_OFF:
+        staticFunctionsNeedingGetter.add(element);
+        break;
+      case StaticUseKind.FIELD_GET:
+        fieldGetters.add(element);
+        break;
+      case StaticUseKind.SUPER_FIELD_SET:
+      case StaticUseKind.FIELD_SET:
+        fieldSetters.add(element);
+        break;
+      case StaticUseKind.SUPER_TEAR_OFF:
+        methodsNeedingSuperGetter.add(element);
+        break;
+      case StaticUseKind.GENERAL:
+        break;
+      case StaticUseKind.CLOSURE:
+        allClosures.add(element);
+        break;
+    }
   }
 
   void forgetElement(Element element, Compiler compiler) {
@@ -404,7 +388,6 @@
     fieldSetters.remove(element);
     fieldGetters.remove(element);
     _directlyInstantiatedClasses.remove(element);
-    _allInstantiatedClasses.remove(element);
     if (element is ClassElement) {
       assert(invariant(
           element, element.thisType.isRaw,
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
new file mode 100644
index 0000000..77c1084
--- /dev/null
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -0,0 +1,325 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This library defined `uses`. A `use` is a single impact of the world, for
+/// instance an invocation of a top level function or a call to the `foo()`
+/// method on an unknown class.
+library dart2js.universe.use;
+
+import '../closure.dart' show
+  BoxFieldElement;
+import '../common.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../world.dart' show
+    ClassWorld;
+import '../util/util.dart' show
+    Hashing;
+
+import 'call_structure.dart' show
+    CallStructure;
+import 'selector.dart' show
+    Selector;
+import 'universe.dart' show
+    ReceiverConstraint;
+
+
+enum DynamicUseKind {
+  INVOKE,
+  GET,
+  SET,
+}
+
+/// The use of a dynamic property. [selector] defined the name and kind of the
+/// property and [mask] defines the known constraint for the object on which
+/// the property is accessed.
+class DynamicUse {
+  final Selector selector;
+  final ReceiverConstraint mask;
+
+  DynamicUse(this.selector, this.mask);
+
+  bool appliesUnnamed(Element element, ClassWorld world) {
+    return selector.appliesUnnamed(element, world) &&
+        (mask == null || mask.canHit(element, selector, world));
+  }
+
+  DynamicUseKind get kind {
+    if (selector.isGetter) {
+      return DynamicUseKind.GET;
+    } else if (selector.isSetter) {
+      return DynamicUseKind.SET;
+    } else {
+      return DynamicUseKind.INVOKE;
+    }
+  }
+
+  int get hashCode => selector.hashCode * 13 + mask.hashCode * 17;
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! DynamicUse) return false;
+    return selector == other.selector && mask == other.mask;
+  }
+
+  String toString() => '$selector,$mask';
+}
+
+enum StaticUseKind {
+  GENERAL,
+  STATIC_TEAR_OFF,
+  SUPER_TEAR_OFF,
+  SUPER_FIELD_SET,
+  FIELD_GET,
+  FIELD_SET,
+  CLOSURE,
+}
+
+/// Statically known use of an [Element].
+// TODO(johnniwinther): Create backend-specific implementations with better
+// invariants.
+class StaticUse {
+  final Element element;
+  final StaticUseKind kind;
+  final int hashCode;
+
+  StaticUse._(Element element, StaticUseKind kind)
+      : this.element = element,
+        this.kind = kind,
+        this.hashCode = Hashing.objectHash(element, Hashing.objectHash(kind)) {
+    assert(invariant(element, element.isDeclaration,
+        message: "Static use element $element must be "
+                 "the declaration element."));
+  }
+
+  /// Invocation of a static or top-level [element] with the given
+  /// [callStructure].
+  factory StaticUse.staticInvoke(MethodElement element,
+                                 CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static invoke element $element must be a top-level "
+                 "or static method."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Closurization of a static or top-level function [element].
+  factory StaticUse.staticTearOff(MethodElement element) {
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static tear-off element $element must be a top-level "
+                 "or static method."));
+    return new StaticUse._(element, StaticUseKind.STATIC_TEAR_OFF);
+  }
+
+  /// Read access of a static or top-level field or getter [element].
+  factory StaticUse.staticGet(MemberElement element) {
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static get element $element must be a top-level "
+                 "or static method."));
+    assert(invariant(element, element.isField || element.isGetter,
+        message: "Static get element $element must be a field or a getter."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Write access of a static or top-level field or setter [element].
+  factory StaticUse.staticSet(MemberElement element) {
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static set element $element must be a top-level "
+                 "or static method."));
+    assert(invariant(element, element.isField || element.isSetter,
+        message: "Static set element $element must be a field or a setter."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Invocation of the lazy initializer for a static or top-level field
+  /// [element].
+  factory StaticUse.staticInit(FieldElement element) {
+    assert(invariant(element, element.isStatic || element.isTopLevel,
+        message: "Static init element $element must be a top-level "
+                 "or static method."));
+    assert(invariant(element, element.isField,
+        message: "Static init element $element must be a field."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Invocation of a super method [element] with the given [callStructure].
+  factory StaticUse.superInvoke(MethodElement element,
+                                CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    assert(invariant(element, element.isInstanceMember,
+        message: "Super invoke element $element must be an instance method."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Read access of a super field or getter [element].
+  factory StaticUse.superGet(MemberElement element) {
+    assert(invariant(element, element.isInstanceMember,
+        message: "Super get element $element must be an instance method."));
+    assert(invariant(element, element.isField || element.isGetter,
+        message: "Super get element $element must be a field or a getter."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Write access of a super field [element].
+  factory StaticUse.superFieldSet(FieldElement element) {
+    assert(invariant(element, element.isInstanceMember,
+        message: "Super set element $element must be an instance method."));
+    assert(invariant(element, element.isField,
+        message: "Super set element $element must be a field."));
+    return new StaticUse._(element, StaticUseKind.SUPER_FIELD_SET);
+  }
+
+  /// Write access of a super setter [element].
+  factory StaticUse.superSetterSet(SetterElement element) {
+    assert(invariant(element, element.isInstanceMember,
+        message: "Super set element $element must be an instance method."));
+    assert(invariant(element, element.isSetter,
+        message: "Super set element $element must be a setter."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Closurization of a super method [element].
+  factory StaticUse.superTearOff(MethodElement element) {
+    assert(invariant(element, element.isInstanceMember && element.isFunction,
+        message: "Super invoke element $element must be an instance method."));
+    return new StaticUse._(element, StaticUseKind.SUPER_TEAR_OFF);
+  }
+
+  /// Invocation of a constructor [element] through a this or super
+  /// constructor call with the given [callStructure].
+  factory StaticUse.superConstructorInvoke(Element element,
+                                           CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    assert(invariant(element,
+        element.isGenerativeConstructor,
+        message: "Constructor invoke element $element must be a "
+                 "generative constructor."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Invocation of a constructor (body) [element] through a this or super
+  /// constructor call with the given [callStructure].
+  factory StaticUse.constructorBodyInvoke(ConstructorBodyElement element,
+                                          CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Constructor invocation of [element] with the given [callStructure].
+  factory StaticUse.constructorInvoke(ConstructorElement element,
+                                      CallStructure callStructure) {
+    // TODO(johnniwinther): Use the [callStructure].
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Constructor redirection to [element].
+  factory StaticUse.constructorRedirect(ConstructorElement element) {
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Initialization of an instance field [element].
+  factory StaticUse.fieldInit(FieldElement element) {
+    assert(invariant(element, element.isInstanceMember,
+        message: "Field init element $element must be an instance field."));
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  /// Read access of an instance field or boxed field [element].
+  factory StaticUse.fieldGet(Element element) {
+    assert(invariant(element,
+        element.isInstanceMember || element is BoxFieldElement,
+        message: "Field init element $element must be an instance "
+                 "or boxed field."));
+    return new StaticUse._(element, StaticUseKind.FIELD_GET);
+  }
+
+  /// Write access of an instance field or boxed field [element].
+  factory StaticUse.fieldSet(Element element) {
+    assert(invariant(element,
+        element.isInstanceMember || element is BoxFieldElement,
+        message: "Field init element $element must be an instance "
+                 "or boxed field."));
+    return new StaticUse._(element, StaticUseKind.FIELD_SET);
+  }
+
+  /// Read of a local function [element].
+  factory StaticUse.closure(LocalFunctionElement element) {
+    return new StaticUse._(element, StaticUseKind.CLOSURE);
+  }
+
+  /// Unknown use of [element].
+  @deprecated
+  factory StaticUse.foreignUse(Element element) {
+    return new StaticUse._(element, StaticUseKind.GENERAL);
+  }
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! StaticUse) return false;
+    return element == other.element &&
+           kind == other.kind;
+  }
+
+  String toString() => 'StaticUse($element,$kind)';
+}
+
+enum TypeUseKind {
+  IS_CHECK,
+  AS_CAST,
+  CHECKED_MODE_CHECK,
+  CATCH_TYPE,
+  TYPE_LITERAL,
+  INSTANTIATION,
+}
+
+/// Use of a [DartType].
+class TypeUse {
+  final DartType type;
+  final TypeUseKind kind;
+  final int hashCode;
+
+  TypeUse._(DartType type, TypeUseKind kind)
+      : this.type = type,
+        this.kind = kind,
+        this.hashCode = Hashing.objectHash(type, Hashing.objectHash(kind));
+
+  /// [type] used in an is check, like `e is T` or `e is! T`.
+  factory TypeUse.isCheck(DartType type) {
+    return new TypeUse._(type, TypeUseKind.IS_CHECK);
+  }
+
+  /// [type] used in an as cast, like `e as T`.
+  factory TypeUse.asCast(DartType type) {
+    return new TypeUse._(type, TypeUseKind.AS_CAST);
+  }
+
+  /// [type] used as a type annotation, like `T foo;`.
+  factory TypeUse.checkedModeCheck(DartType type) {
+    return new TypeUse._(type, TypeUseKind.CHECKED_MODE_CHECK);
+  }
+
+  /// [type] used in a on type catch clause, like `try {} on T catch (e) {}`.
+  factory TypeUse.catchType(DartType type) {
+    return new TypeUse._(type, TypeUseKind.CATCH_TYPE);
+  }
+
+  /// [type] used as a type literal, like `foo() => T;`.
+  factory TypeUse.typeLiteral(DartType type) {
+    return new TypeUse._(type, TypeUseKind.TYPE_LITERAL);
+  }
+
+  /// [type] used in an instantiation, like `new T();`.
+  factory TypeUse.instantiation(InterfaceType type) {
+    return new TypeUse._(type, TypeUseKind.INSTANTIATION);
+  }
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! TypeUse) return false;
+    return type == other.type &&
+           kind == other.kind;
+  }
+
+  String toString() => 'TypeUse($type,$kind)';
+}
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/universe/world_impact.dart b/pkg/compiler/lib/src/universe/world_impact.dart
new file mode 100644
index 0000000..95980a0
--- /dev/null
+++ b/pkg/compiler/lib/src/universe/world_impact.dart
@@ -0,0 +1,250 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.universe.world_impact;
+
+import '../dart_types.dart' show
+    DartType,
+    InterfaceType;
+import '../elements/elements.dart' show
+    Element,
+    LocalFunctionElement,
+    MethodElement;
+import '../util/util.dart' show
+    Setlet;
+
+import 'use.dart' show
+    DynamicUse,
+    StaticUse,
+    TypeUse;
+
+class WorldImpact {
+  const WorldImpact();
+
+  Iterable<DynamicUse> get dynamicUses =>
+      const <DynamicUse>[];
+
+  Iterable<StaticUse> get staticUses => const <StaticUse>[];
+
+  // TODO(johnniwinther): Replace this by called constructors with type
+  // arguments.
+  // TODO(johnniwinther): Collect all checked types for checked mode separately
+  // to support serialization.
+
+  Iterable<TypeUse> get typeUses => const <TypeUse>[];
+
+  void apply(WorldImpactVisitor visitor) {
+    staticUses.forEach(visitor.visitStaticUse);
+    dynamicUses.forEach(visitor.visitDynamicUse);
+    typeUses.forEach(visitor.visitTypeUse);
+  }
+
+  String toString() => dump(this);
+
+  static String dump(WorldImpact worldImpact) {
+    StringBuffer sb = new StringBuffer();
+    printOn(sb, worldImpact);
+    return sb.toString();
+  }
+
+  static void printOn(StringBuffer sb, WorldImpact worldImpact) {
+    void add(String title, Iterable iterable) {
+      if (iterable.isNotEmpty) {
+        sb.write('\n $title:');
+        iterable.forEach((e) => sb.write('\n  $e'));
+      }
+    }
+
+    add('dynamic uses', worldImpact.dynamicUses);
+    add('static uses', worldImpact.staticUses);
+    add('type uses', worldImpact.typeUses);
+  }
+}
+
+class WorldImpactBuilder {
+  // TODO(johnniwinther): Do we benefit from lazy initialization of the
+  // [Setlet]s?
+  Setlet<DynamicUse> _dynamicUses;
+  Setlet<StaticUse> _staticUses;
+  Setlet<TypeUse> _typeUses;
+
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    assert(dynamicUse != null);
+    if (_dynamicUses == null) {
+      _dynamicUses = new Setlet<DynamicUse>();
+    }
+    _dynamicUses.add(dynamicUse);
+  }
+
+  Iterable<DynamicUse> get dynamicUses {
+    return _dynamicUses != null
+        ? _dynamicUses : const <DynamicUse>[];
+  }
+
+  void registerTypeUse(TypeUse typeUse) {
+    assert(typeUse != null);
+    if (_typeUses == null) {
+      _typeUses = new Setlet<TypeUse>();
+    }
+    _typeUses.add(typeUse);
+  }
+
+  Iterable<TypeUse> get typeUses {
+    return _typeUses != null
+        ? _typeUses : const <TypeUse>[];
+  }
+
+  void registerStaticUse(StaticUse staticUse) {
+    assert(staticUse != null);
+    if (_staticUses == null) {
+      _staticUses = new Setlet<StaticUse>();
+    }
+    _staticUses.add(staticUse);
+  }
+
+  Iterable<StaticUse> get staticUses {
+    return _staticUses != null ? _staticUses : const <StaticUse>[];
+  }
+}
+
+/// Mutable implementation of [WorldImpact] used to transform
+/// [ResolutionImpact] or [CodegenImpact] to [WorldImpact].
+class TransformedWorldImpact implements WorldImpact {
+  final WorldImpact worldImpact;
+
+  Setlet<StaticUse> _staticUses;
+  Setlet<TypeUse> _typeUses;
+  Setlet<DynamicUse> _dynamicUses;
+
+  TransformedWorldImpact(this.worldImpact);
+
+  @override
+  Iterable<DynamicUse> get dynamicUses {
+    return _dynamicUses != null
+        ? _dynamicUses : worldImpact.dynamicUses;
+  }
+
+  void registerDynamicUse(DynamicUse dynamicUse) {
+    if (_dynamicUses == null) {
+      _dynamicUses = new Setlet<DynamicUse>();
+      _dynamicUses.addAll(worldImpact.dynamicUses);
+    }
+    _dynamicUses.add(dynamicUse);
+  }
+
+  void registerTypeUse(TypeUse typeUse) {
+    if (_typeUses == null) {
+      _typeUses = new Setlet<TypeUse>();
+      _typeUses.addAll(worldImpact.typeUses);
+    }
+    _typeUses.add(typeUse);
+  }
+
+  @override
+  Iterable<TypeUse> get typeUses {
+    return _typeUses != null
+        ? _typeUses : worldImpact.typeUses;
+  }
+
+  void registerStaticUse(StaticUse staticUse) {
+    if (_staticUses == null) {
+      _staticUses = new Setlet<StaticUse>();
+      _staticUses.addAll(worldImpact.staticUses);
+    }
+    _staticUses.add(staticUse);
+  }
+
+  @override
+  Iterable<StaticUse> get staticUses {
+    return _staticUses != null ? _staticUses : worldImpact.staticUses;
+  }
+
+  void apply(WorldImpactVisitor visitor) {
+    staticUses.forEach(visitor.visitStaticUse);
+    dynamicUses.forEach(visitor.visitDynamicUse);
+    typeUses.forEach(visitor.visitTypeUse);
+  }
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('TransformedWorldImpact($worldImpact)');
+    WorldImpact.printOn(sb, this);
+    return sb.toString();
+  }
+}
+
+/// Constant used to denote a specific use of a [WorldImpact].
+class ImpactUseCase {
+  final String name;
+
+  const ImpactUseCase(this.name);
+
+  String toString() => 'ImpactUseCase($name)';
+}
+
+/// Strategy used for processing [WorldImpact] object in various use cases.
+class ImpactStrategy {
+  const ImpactStrategy();
+
+  /// Applies [impact] to [visitor] for the [impactUseCase] of [element].
+  void visitImpact(Element element,
+                   WorldImpact impact,
+                   WorldImpactVisitor visitor,
+                   ImpactUseCase impactUseCase) {
+    // Apply unconditionally.
+    impact.apply(visitor);
+  }
+
+  /// Notifies the strategy that no more impacts of [impactUseCase] will be
+  /// applied.
+  void onImpactUsed(ImpactUseCase impactUseCase) {
+    // Do nothing.
+  }
+}
+
+/// Visitor used to process the uses of a [WorldImpact].
+abstract class WorldImpactVisitor {
+  void visitStaticUse(StaticUse staticUse);
+  void visitDynamicUse(DynamicUse dynamicUse);
+  void visitTypeUse(TypeUse typeUse);
+}
+
+// TODO(johnniwinther): Remove these when we get anonymous local classes.
+typedef void VisitUse<U>(U use);
+
+class WorldImpactVisitorImpl implements WorldImpactVisitor {
+  final VisitUse<StaticUse> _visitStaticUse;
+  final VisitUse<DynamicUse> _visitDynamicUse;
+  final VisitUse<TypeUse> _visitTypeUse;
+
+  WorldImpactVisitorImpl(
+      {VisitUse<StaticUse> visitStaticUse,
+       VisitUse<DynamicUse> visitDynamicUse,
+       VisitUse<TypeUse> visitTypeUse})
+      : _visitStaticUse = visitStaticUse,
+        _visitDynamicUse = visitDynamicUse,
+        _visitTypeUse = visitTypeUse;
+
+  @override
+  void visitStaticUse(StaticUse use) {
+    if (_visitStaticUse != null) {
+      _visitStaticUse(use);
+    }
+  }
+
+  @override
+  void visitDynamicUse(DynamicUse use) {
+    if (_visitDynamicUse != null) {
+      _visitDynamicUse(use);
+    }
+  }
+
+  @override
+  void visitTypeUse(TypeUse use) {
+    if (_visitTypeUse != null) {
+      _visitTypeUse(use);
+    }
+  }
+}
+
diff --git a/pkg/compiler/lib/src/util/enumset.dart b/pkg/compiler/lib/src/util/enumset.dart
new file mode 100644
index 0000000..953a873
--- /dev/null
+++ b/pkg/compiler/lib/src/util/enumset.dart
@@ -0,0 +1,199 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.util.enumset;
+
+import 'dart:collection';
+
+/// A set of enum values based on a bit mask of the shifted enum indices.
+abstract class EnumSet<E> {
+  /// Creates an empty mutable set.
+  factory EnumSet() = _EnumSet<E>;
+
+  /// Creates a mutable set from the bit mask [value].
+  factory EnumSet.fromValue(int value) = _EnumSet<E>.fromValue;
+
+  /// Creates an immutable set from the bit mask [value].
+  const factory EnumSet.fixed(int value) = _ConstEnumSet<E>;
+
+  /// Create a set containing the [values]. If [fixed] is `true` the set is
+  /// immutable.
+  factory EnumSet.fromValues(Iterable<E> values, {bool fixed: false}) {
+    if (fixed) {
+      return new _ConstEnumSet<E>.fromValues(values);
+    } else {
+      return new _EnumSet<E>.fromValues(values);
+    }
+  }
+
+  const EnumSet._();
+
+  /// The bit mask of the shifted indices for the enum values in this set.
+  int get value;
+
+  /// Adds [enumValue] to this set.
+  void add(E enumValue);
+
+  /// Removes [enumValue] from this set.
+  void remove(E enumValue);
+
+  /// Clears this set.
+  void clear();
+
+  /// Returns `true` if [enumValue] is in this set.
+  bool contains(E enumValue) {
+    return (value & (1 << (enumValue as dynamic).index)) != 0;
+  }
+
+  /// Returns an [Iterable] of the values is in this set using [values] to
+  /// convert the stored indices to enum values.
+  ///
+  /// The method is typically called with the `values` property of the enum
+  /// class as argument:
+  ///
+  ///     EnumSet<EnumClass> set = ...
+  ///     Iterable<EnumClass> iterable = set.iterable(EnumClass.values);
+  ///
+  Iterable<E> iterable(List<E> values) {
+    return new _EnumSetIterable(this, values);
+  }
+
+  /// Returns `true` if this and [other] have any elements in common.
+  bool intersects(EnumSet<E> other) {
+    return (value & other.value) != 0;
+  }
+
+  /// Returns `true` if this set is empty.
+  bool get isEmpty => value == 0;
+
+  int get hashCode => value.hashCode * 19;
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! EnumSet<E>) return false;
+    return value == other.value;
+  }
+
+  String toString() {
+    if (value == 0) return '0';
+    int index = value.bitLength - 1;
+    StringBuffer sb = new StringBuffer();
+    int mask = 1 << index;
+    while (index >= 0) {
+      sb.write((value & mask) != 0 ? '1' : '0');
+      index--;
+      mask >>= 1;
+    }
+    return sb.toString();
+  }
+}
+
+/// Mutable implementation of [EnumSet].
+class _EnumSet<E> extends EnumSet<E> {
+  int _value;
+
+  _EnumSet() : this.fromValue(0);
+
+  _EnumSet.fromValue(this._value) : super._();
+
+  _EnumSet.fromValues(Iterable<E> values)
+      : this._value = 0,
+        super._() {
+    values.forEach(add);
+  }
+
+  int get value => _value;
+
+  void add(E enumValue) {
+    _value |= 1 << (enumValue as dynamic).index;
+  }
+
+  void remove(E enumValue) {
+    _value &= ~(1 << (enumValue as dynamic).index);
+  }
+
+  void clear() {
+    _value = 0;
+  }
+}
+
+/// Immutable implementation of [EnumSet].
+class _ConstEnumSet<E> extends EnumSet<E> {
+  final int value;
+
+  const _ConstEnumSet(this.value) : super._();
+
+  factory _ConstEnumSet.fromValues(Iterable<E> values) {
+    int value = 0;
+    void add(E enumValue) {
+      if (enumValue != null) {
+        value |= 1 << (enumValue as dynamic).index;
+      }
+    }
+    values.forEach(add);
+    return new _ConstEnumSet(value);
+  }
+
+  @override
+  void add(E enumValue) {
+    throw new UnsupportedError('EnumSet.add');
+  }
+
+  @override
+  void clear() {
+    throw new UnsupportedError('EnumSet.clear');
+  }
+
+  @override
+  void remove(E enumValue) {
+    throw new UnsupportedError('EnumSet.remove');
+  }
+}
+
+class _EnumSetIterable<E> extends IterableBase<E> {
+  final EnumSet<E> _enumSet;
+  final List<E> _values;
+
+  _EnumSetIterable(this._enumSet, this._values);
+
+  @override
+  Iterator<E> get iterator => new _EnumSetIterator(_enumSet.value, _values);
+}
+
+class _EnumSetIterator<E> implements Iterator<E> {
+  int _value;
+  int _index;
+  int _mask;
+  final List<E> _values;
+  E _current;
+
+  _EnumSetIterator(this._value, this._values);
+
+  @override
+  E get current => _current;
+
+  @override
+  bool moveNext() {
+    if (_value == 0) {
+      return false;
+    } else {
+      if (_mask == null) {
+        _index = _value.bitLength - 1;
+        _mask = 1 << _index;
+      }
+      _current = null;
+      while (_index >= 0) {
+        if (_mask & _value != 0) {
+          _current = _values[_index];
+        }
+        _mask >>= 1;
+        _index--;
+        if (_current != null) {
+          break;
+        }
+      }
+      return _current != null;
+    }
+  }
+}
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index b8c6387..30b2081 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -11,6 +11,8 @@
     Backend;
 import 'compiler.dart' show
     Compiler;
+import 'core_types.dart' show
+    CoreClasses;
 import 'dart_types.dart';
 import 'elements/elements.dart' show
     ClassElement,
@@ -60,9 +62,16 @@
   /// The [ClassElement] for the [String] class defined in 'dart:core'.
   ClassElement get stringClass;
 
-  /// Returns `true` if [cls] is instantiated.
+  /// Returns `true` if [cls] is either directly or indirectly instantiated.
   bool isInstantiated(ClassElement cls);
 
+  /// Returns `true` if [cls] is directly instantiated.
+  bool isDirectlyInstantiated(ClassElement cls);
+
+  /// Returns `true` if [cls] is indirectly instantiated, that is through a
+  /// subclass.
+  bool isIndirectlyInstantiated(ClassElement cls);
+
   /// Returns `true` if [cls] is implemented by an instantiated class.
   bool isImplemented(ClassElement cls);
 
@@ -104,6 +113,16 @@
   /// Returns `true` if all live classes that implement [cls] extend it.
   bool hasOnlySubclasses(ClassElement cls);
 
+  /// Returns the most specific subclass of [cls] (including [cls]) that is
+  /// directly instantiated or a superclass of all directly instantiated
+  /// subclasses. If [cls] is not instantiated, `null` is returned.
+  ClassElement getLubOfInstantiatedSubclasses(ClassElement cls);
+
+  /// Returns the most specific subtype of [cls] (including [cls]) that is
+  /// directly instantiated or a superclass of all directly instantiated
+  /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned.
+  ClassElement getLubOfInstantiatedSubtypes(ClassElement cls);
+
   /// Returns an iterable over the common supertypes of the [classes].
   Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes);
 
@@ -135,14 +154,14 @@
 }
 
 class World implements ClassWorld {
-  ClassElement get objectClass => compiler.objectClass;
-  ClassElement get functionClass => compiler.functionClass;
-  ClassElement get boolClass => compiler.boolClass;
-  ClassElement get numClass => compiler.numClass;
-  ClassElement get intClass => compiler.intClass;
-  ClassElement get doubleClass => compiler.doubleClass;
-  ClassElement get stringClass => compiler.stringClass;
-  ClassElement get nullClass => compiler.nullClass;
+  ClassElement get objectClass => coreClasses.objectClass;
+  ClassElement get functionClass => coreClasses.functionClass;
+  ClassElement get boolClass => coreClasses.boolClass;
+  ClassElement get numClass => coreClasses.numClass;
+  ClassElement get intClass => coreClasses.intClass;
+  ClassElement get doubleClass => coreClasses.doubleClass;
+  ClassElement get stringClass => coreClasses.stringClass;
+  ClassElement get nullClass => coreClasses.nullClass;
 
   /// Cache of [ti.FlatTypeMask]s grouped by the 8 possible values of the
   /// [ti.FlatTypeMask.flags] property.
@@ -188,10 +207,22 @@
     return false;
   }
 
-  /// Returns `true` if [cls] is instantiated either directly or through a
-  /// subclass.
+  @override
   bool isInstantiated(ClassElement cls) {
-    return compiler.resolverWorld.isInstantiated(cls);
+    ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
+    return node != null && node.isInstantiated;
+  }
+
+  @override
+  bool isDirectlyInstantiated(ClassElement cls) {
+    ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
+    return node != null && node.isDirectlyInstantiated;
+  }
+
+  @override
+  bool isIndirectlyInstantiated(ClassElement cls) {
+    ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
+    return node != null && node.isIndirectlyInstantiated;
   }
 
   /// Returns `true` if [cls] is implemented by an instantiated class.
@@ -204,9 +235,8 @@
   Iterable<ClassElement> subclassesOf(ClassElement cls) {
     ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
     if (hierarchy == null) return const <ClassElement>[];
-    return hierarchy.subclasses(
-        includeIndirectlyInstantiated: false,
-        includeUninstantiated: false);
+    return hierarchy.subclassesByMask(
+        ClassHierarchyNode.DIRECTLY_INSTANTIATED);
   }
 
   /// Returns an iterable over the directly instantiated classes that extend
@@ -214,10 +244,8 @@
   Iterable<ClassElement> strictSubclassesOf(ClassElement cls) {
     ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
     if (subclasses == null) return const <ClassElement>[];
-    return subclasses.subclasses(
-        strict: true,
-        includeIndirectlyInstantiated: false,
-        includeUninstantiated: false);
+    return subclasses.subclassesByMask(
+        ClassHierarchyNode.DIRECTLY_INSTANTIATED, strict: true);
   }
 
   /// Returns an iterable over the directly instantiated that implement [cls]
@@ -227,9 +255,7 @@
     if (classSet == null) {
       return const <ClassElement>[];
     } else {
-      return classSet.subtypes(
-          includeIndirectlyInstantiated: false,
-          includeUninstantiated: false);
+      return classSet.subtypesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED);
     }
   }
 
@@ -240,10 +266,9 @@
     if (classSet == null) {
       return const <ClassElement>[];
     } else {
-      return classSet.subtypes(
-          strict: true,
-          includeIndirectlyInstantiated: false,
-          includeUninstantiated: false);
+      return classSet.subtypesByMask(
+          ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+          strict: true);
     }
   }
 
@@ -279,12 +304,28 @@
   /// Returns `true` if all directly instantiated classes that implement [cls]
   /// extend it.
   bool hasOnlySubclasses(ClassElement cls) {
+    // TODO(johnniwinther): move this to ClassSet?
+    if (cls == objectClass) return true;
     Iterable<ClassElement> subtypes = strictSubtypesOf(cls);
     if (subtypes == null) return true;
     Iterable<ClassElement> subclasses = strictSubclassesOf(cls);
     return subclasses != null && (subclasses.length == subtypes.length);
   }
 
+  @override
+  ClassElement getLubOfInstantiatedSubclasses(ClassElement cls) {
+    ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
+    return hierarchy != null
+        ? hierarchy.getLubOfInstantiatedSubclasses() : null;
+  }
+
+  @override
+  ClassElement getLubOfInstantiatedSubtypes(ClassElement cls) {
+    ClassSet classSet = _classSets[cls.declaration];
+    return classSet != null
+        ? classSet.getLubOfInstantiatedSubtypes() : null;
+  }
+
   /// Returns an iterable over the common supertypes of the [classes].
   Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) {
     Iterator<ClassElement> iterator = classes.iterator;
@@ -433,14 +474,19 @@
         this.compiler = compiler,
         alreadyPopulated = compiler.cacheStrategy.newSet();
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   DiagnosticReporter get reporter => compiler.reporter;
 
   /// Called to add [cls] to the set of known classes.
   ///
   /// This ensures that class hierarchy queries can be performed on [cls] and
   /// classes that extend or implement it.
-  void registerClass(ClassElement cls) {
+  void registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) {
     _ensureClassSet(cls);
+    if (isDirectlyInstantiated) {
+      _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
+    }
   }
 
   /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
@@ -488,29 +534,36 @@
     });
   }
 
+  void _updateClassHierarchyNodeForClass(
+      ClassElement cls,
+      {bool directlyInstantiated: false,
+       bool indirectlyInstantiated: false}) {
+    ClassHierarchyNode node = getClassHierarchyNode(cls);
+    bool changed = false;
+    if (directlyInstantiated && !node.isDirectlyInstantiated) {
+      node.isDirectlyInstantiated = true;
+      changed = true;
+    }
+    if (indirectlyInstantiated && !node.isIndirectlyInstantiated) {
+      node.isIndirectlyInstantiated = true;
+      changed = true;
+    }
+    if (changed && cls.superclass != null) {
+      _updateClassHierarchyNodeForClass(
+          cls.superclass, indirectlyInstantiated: true);
+    }
+    // Ensure that classes implicitly implementing `Function` are in its
+    // subtype set.
+    if (cls != coreClasses.functionClass &&
+        cls.implementsFunction(compiler)) {
+      ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass);
+      subtypeSet.addSubtype(node);
+    }
+  }
+
   void populate() {
     /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
     /// properties of the [ClassHierarchyNode] for [cls].
-    void updateClassHierarchyNodeForClass(
-        ClassElement cls,
-        {bool directlyInstantiated: false,
-         bool indirectlyInstantiated: false}) {
-      assert(!directlyInstantiated || isInstantiated(cls));
-      ClassHierarchyNode node = getClassHierarchyNode(cls);
-      bool changed = false;
-      if (directlyInstantiated && !node.isDirectlyInstantiated) {
-        node.isDirectlyInstantiated = true;
-        changed = true;
-      }
-      if (indirectlyInstantiated && !node.isIndirectlyInstantiated) {
-        node.isIndirectlyInstantiated = true;
-        changed = true;
-      }
-      if (changed && cls.superclass != null) {
-        updateClassHierarchyNodeForClass(
-            cls.superclass, indirectlyInstantiated: true);
-      }
-    }
 
     void addSubtypes(ClassElement cls) {
       if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) {
@@ -521,7 +574,7 @@
         reporter.internalError(cls, 'Class "${cls.name}" is not resolved.');
       }
 
-      updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
+      _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
 
       // Walk through the superclasses, and record the types
       // implemented by that type on the superclasses.
@@ -552,7 +605,7 @@
     } else {
       sb.write("Instantiated classes in the closed world:\n");
     }
-    getClassHierarchyNode(compiler.objectClass)
+    getClassHierarchyNode(coreClasses.objectClass)
         .printOn(sb, ' ', instantiatedOnly: cls == null, withRespectTo: cls);
     return sb.toString();
   }
@@ -610,7 +663,7 @@
 
   bool fieldNeverChanges(Element element) {
     if (!element.isField) return false;
-    if (element.isNative) {
+    if (backend.isNative(element)) {
       // Some native fields are views of data that may be changed by operations.
       // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2).
       // TODO(sra): Refine the effect classification so that native effects are
@@ -618,10 +671,14 @@
       return false;
     }
 
-    return element.isFinal
-        || element.isConst
-        || (element.isInstanceMember
-            && !compiler.resolverWorld.hasInvokedSetter(element, this));
+    if (element.isFinal || element.isConst) {
+      return true;
+    }
+    if (element.isInstanceMember) {
+      return !compiler.resolverWorld.hasInvokedSetter(element, this) &&
+             !compiler.resolverWorld.fieldSetters.contains(element);
+    }
+    return false;
   }
 
   SideEffects getSideEffectsOfElement(Element element) {
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index c885986..3b7e3ea 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -17,6 +17,8 @@
     path: ../../../../dart2js_info
   lookup_map:
     path: ../lookup_map
+  dart_messages:
+    path: ../dart_messages
 
 # Uncomment if running gclient, so you can depend directly on the downloaded
 # versions of dart2js's transitive dependencies:
diff --git a/pkg/compiler/samples/darttags/darttags.dart b/pkg/compiler/samples/darttags/darttags.dart
index 2000b9b..84b7562 100644
--- a/pkg/compiler/samples/darttags/darttags.dart
+++ b/pkg/compiler/samples/darttags/darttags.dart
@@ -87,10 +87,11 @@
   // Prepend "dart:" to the names.
   uris.addAll(names.map((String name) => Uri.parse('dart:$name')));
 
-  Uri libraryRoot = myLocation.resolve(SDK_ROOT);
+  Uri platformConfigUri = myLocation.resolve(SDK_ROOT)
+      .resolve("lib/dart2js_shared_sdk");
   Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
 
-  analyze(uris, libraryRoot, packageRoot, handler.provider, handler)
+  analyze(uris, platformConfigUri, packageRoot, handler.provider, handler)
       .then(processMirrors);
 }
 
diff --git a/pkg/compiler/samples/jsonify/jsonify.dart b/pkg/compiler/samples/jsonify/jsonify.dart
index 7638ca5..152f39e 100644
--- a/pkg/compiler/samples/jsonify/jsonify.dart
+++ b/pkg/compiler/samples/jsonify/jsonify.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:io';
 import 'dart:convert';
 
@@ -65,30 +66,39 @@
 
 jsonify(MirrorSystem mirrors) {
   var map = <String, String>{};
+  List<Future> futures = <Future>[];
+
+  Future mapUri(Uri uri) {
+    String filename = relativize(sdkRoot, uri, false);
+    return handler.provider.readStringFromUri(uri).then((contents) {
+      map['sdk:/$filename'] = contents;
+    });
+  }
 
   mirrors.libraries.forEach((_, LibraryMirror library) {
     BackDoor.compilationUnitsOf(library).forEach((compilationUnit) {
-      Uri uri = compilationUnit.uri;
-      String filename = relativize(sdkRoot, uri, false);
-      SourceFile file = handler.provider.sourceFiles[uri];
-      map['sdk:/$filename'] = file.slowText();
+      futures.add(mapUri(compilationUnit.uri));
     });
   });
 
   libraries.forEach((name, info) {
     var patch = info.dart2jsPatchPath;
     if (patch != null) {
-      Uri uri = sdkRoot.resolve('sdk/lib/$patch');
-      String filename = relativize(sdkRoot, uri, false);
-      SourceFile file = handler.provider.sourceFiles[uri];
-      map['sdk:/$filename'] = file.slowText();
+      futures.add(mapUri(sdkRoot.resolve('sdk/lib/$patch')));
     }
   });
 
-  if (outputJson) {
-    output.writeStringSync(JSON.encode(map));
-  } else {
-    output.writeStringSync('''
+  for (String filename in ["dart_client.platform",
+                           "dart_server.platform",
+                           "dart_shared.platform"]) {
+    futures.add(mapUri(sdkRoot.resolve('sdk/lib/$filename')));
+  }
+
+  Future.wait(futures).then((_) {
+    if (outputJson) {
+      output.writeStringSync(JSON.encode(map));
+    } else {
+      output.writeStringSync('''
 // 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.
@@ -99,8 +109,9 @@
 library dart.sdk_sources;
 
 const Map<String, String> SDK_SOURCES = const <String, String>''');
-    output.writeStringSync(JSON.encode(map).replaceAll(r'$', r'\$'));
-    output.writeStringSync(';\n');
-  }
-  output.closeSync();
+      output.writeStringSync(JSON.encode(map).replaceAll(r'$', r'\$'));
+      output.writeStringSync(';\n');
+    }
+    output.closeSync();
+  });
 }
diff --git a/pkg/dart2js_incremental/lib/caching_compiler.dart b/pkg/dart2js_incremental/lib/caching_compiler.dart
index 2bc2047..4185df1 100644
--- a/pkg/dart2js_incremental/lib/caching_compiler.dart
+++ b/pkg/dart2js_incremental/lib/caching_compiler.dart
@@ -6,12 +6,12 @@
 
 /// Do not call this method directly. It will be made private.
 // TODO(ahe): Make this method private.
-Future<Compiler> reuseCompiler(
+Future<CompilerImpl> reuseCompiler(
     {CompilerDiagnostics diagnosticHandler,
      CompilerInput inputProvider,
      CompilerOutput outputProvider,
      List<String> options: const [],
-     Compiler cachedCompiler,
+     CompilerImpl cachedCompiler,
      Uri libraryRoot,
      Uri packageRoot,
      bool packagesAreImmutable: false,
@@ -33,7 +33,7 @@
   if (environment == null) {
     environment = {};
   }
-  Compiler compiler = cachedCompiler;
+  CompilerImpl compiler = cachedCompiler;
   if (compiler == null ||
       compiler.libraryRoot != libraryRoot ||
       !compiler.hasIncrementalSupport ||
@@ -53,7 +53,7 @@
       }
     }
     oldTag.makeCurrent();
-    compiler = new Compiler(
+    compiler = new CompilerImpl(
         inputProvider,
         outputProvider,
         diagnosticHandler,
@@ -76,13 +76,16 @@
         ..needsStructuredMemberInfo = true;
 
     Uri core = Uri.parse("dart:core");
-    return compiler.libraryLoader.loadLibrary(core).then((_) {
-      // Likewise, always be prepared for runtimeType support.
-      // TODO(johnniwinther): Add global switch to force RTI.
-      compiler.enabledRuntimeType = true;
-      backend.registerRuntimeType(
-          compiler.enqueuer.resolution, compiler.globalDependencies);
-      return compiler;
+
+    return compiler.setupSdk().then((_) {
+      return compiler.libraryLoader.loadLibrary(core).then((_) {
+        // Likewise, always be prepared for runtimeType support.
+        // TODO(johnniwinther): Add global switch to force RTI.
+        compiler.enabledRuntimeType = true;
+        backend.registerRuntimeType(
+            compiler.enqueuer.resolution, compiler.globalDependencies);
+        return compiler;
+      });
     });
   } else {
     for (final task in compiler.tasks) {
diff --git a/pkg/dart2js_incremental/lib/dart2js_incremental.dart b/pkg/dart2js_incremental/lib/dart2js_incremental.dart
index 12d285c..1ce8039 100644
--- a/pkg/dart2js_incremental/lib/dart2js_incremental.dart
+++ b/pkg/dart2js_incremental/lib/dart2js_incremental.dart
@@ -12,7 +12,7 @@
     UserTag;
 
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 
 import 'package:compiler/compiler_new.dart' show
     CompilerDiagnostics,
@@ -59,7 +59,7 @@
   final List<String> _updates = <String>[];
   final IncrementalCompilerContext _context = new IncrementalCompilerContext();
 
-  Compiler _compiler;
+  CompilerImpl _compiler;
 
   IncrementalCompiler({
       this.libraryRoot,
@@ -86,16 +86,16 @@
 
   LibraryElement get mainApp => _compiler.mainApp;
 
-  Compiler get compiler => _compiler;
+  CompilerImpl get compiler => _compiler;
 
   Future<bool> compile(Uri script) {
-    return _reuseCompiler(null).then((Compiler compiler) {
+    return _reuseCompiler(null).then((CompilerImpl compiler) {
       _compiler = compiler;
       return compiler.run(script);
     });
   }
 
-  Future<Compiler> _reuseCompiler(
+  Future<CompilerImpl> _reuseCompiler(
       Future<bool> reuseLibrary(LibraryElement library)) {
     List<String> options = this.options == null
         ? <String> [] : new List<String>.from(this.options);
@@ -124,7 +124,7 @@
     }
     Future mappingInputProvider(Uri uri) {
       Uri updatedFile = updatedFiles[uri];
-      return inputProvider(updatedFile == null ? uri : updatedFile);
+      return inputProvider.readFromUri(updatedFile == null ? uri : updatedFile);
     }
     LibraryUpdater updater = new LibraryUpdater(
         _compiler,
@@ -133,8 +133,8 @@
         logVerbose,
         _context);
     _context.registerUriWithUpdates(updatedFiles.keys);
-    Future<Compiler> future = _reuseCompiler(updater.reuseLibrary);
-    return future.then((Compiler compiler) {
+    Future<CompilerImpl> future = _reuseCompiler(updater.reuseLibrary);
+    return future.then((CompilerImpl compiler) {
       _compiler = compiler;
       if (compiler.compilationFailed) {
         return null;
@@ -157,9 +157,7 @@
   return main(args);
 }""", {'updates': updates, 'helper': backend.namer.accessIncrementalHelper});
 
-    jsAst.Printer printer = new jsAst.Printer(_compiler, null);
-    printer.blockOutWithoutBraces(mainRunner);
-    return printer.outBuffer.getText();
+    return jsAst.prettyPrint(mainRunner, _compiler).getText();
   }
 }
 
diff --git a/pkg/dart_messages/bin/json_converter.dart b/pkg/dart_messages/bin/json_converter.dart
new file mode 100644
index 0000000..8d9b8ca
--- /dev/null
+++ b/pkg/dart_messages/bin/json_converter.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 'dart:convert';
+import 'dart:io';
+
+import '../lib/shared_messages.dart' as shared_messages;
+
+/// Translates the shared messages in `../lib/shared_messages` to JSON and
+/// emits it into `../lib/shared_messages.json`.
+void main() {
+  var input = shared_messages.MESSAGES;
+  var outPath =
+      Platform.script.resolve('../lib/shared_messages.json').toFilePath();
+  print("Input: ${input.length} entries");
+  print("Output: $outPath");
+  new File(outPath).writeAsStringSync(JSON.encode(shared_messages.MESSAGES));
+  print("Done");
+}
diff --git a/pkg/dart_messages/bin/message_id.dart b/pkg/dart_messages/bin/message_id.dart
new file mode 100644
index 0000000..2d7ed53
--- /dev/null
+++ b/pkg/dart_messages/bin/message_id.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:math' as math;
+
+import '../lib/shared_messages.dart' as shared_messages;
+
+math.Random random = new math.Random();
+
+const idLength = 6;
+final $A = "A".codeUnitAt(0);
+final $Z = "Z".codeUnitAt(0);
+
+String computeId() {
+  List charCodes = [];
+  for (int i = 0; i < idLength; i++) {
+    charCodes.add($A + random.nextInt($Z - $A));
+  }
+  return new String.fromCharCodes(charCodes);
+}
+
+/// Computes a random message ID that hasn't been used before.
+void main() {
+  var usedIds =
+      shared_messages.MESSAGES.values.map((entry) => entry['id']).toSet();
+
+  print("${usedIds.length} existing ids");
+
+  var newId;
+  do {
+    newId = computeId();
+  } while (!usedIds.contains(newId));
+  print("Available id: $newId");
+}
diff --git a/pkg/dart_messages/lib/shared_messages.dart b/pkg/dart_messages/lib/shared_messages.dart
new file mode 100644
index 0000000..bd51f58
--- /dev/null
+++ b/pkg/dart_messages/lib/shared_messages.dart
@@ -0,0 +1,62 @@
+// 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.
+
+// An update to this file must be followed by regenerating the corresponding
+// json file. Use `json_converter.dart` in the bin directory.
+//
+// Every message in this file must have an id. Use `message_id.dart` in the
+// bin directory to generate a fresh one.
+
+// The messages in this file should meet the following guide lines:
+//
+// 1. The message should be a complete sentence starting with an uppercase
+// letter, and ending with a period.
+//
+// 2. Reserved words and embedded identifiers should be in single quotes, so
+// prefer double quotes for the complete message. For example, "The
+// class '#{className}' can't use 'super'." Notice that the word 'class' in the
+// preceding message is not quoted as it refers to the concept 'class', not the
+// reserved word. On the other hand, 'super' refers to the reserved word. Do
+// not quote 'null' and numeric literals.
+//
+// 3. Do not try to compose messages, as it can make translating them hard.
+//
+// 4. Try to keep the error messages short, but informative.
+//
+// 5. Use simple words and terminology, assume the reader of the message
+// doesn't have an advanced degree in math, and that English is not the
+// reader's native language. Do not assume any formal computer science
+// training. For example, do not use Latin abbreviations (prefer "that is" over
+// "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
+// only if" and "iff", that level of precision is unnecessary.
+//
+// 6. Prefer contractions when they are in common use, for example, prefer
+// "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
+// off-putting to people new to programming.
+//
+// 7. Use common terminology, preferably from the Dart Language
+// Specification. This increases the user's chance of finding a good
+// explanation on the web.
+//
+// 8. Do not try to be cute or funny. It is extremely frustrating to work on a
+// product that crashes with a "tongue-in-cheek" message, especially if you did
+// not want to use this product to begin with.
+//
+// 9. Do not lie, that is, do not write error messages containing phrases like
+// "can't happen".  If the user ever saw this message, it would be a
+// lie. Prefer messages like: "Internal error: This function should not be
+// called when 'x' is null.".
+//
+// 10. Prefer to not use imperative tone. That is, the message should not sound
+// accusing or like it is ordering the user around. The computer should
+// describe the problem, not criticize for violating the specification.
+//
+// Other things to keep in mind:
+//
+// Generally, we want to provide messages that consists of three sentences:
+// 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
+// combine the first two in [template] and the last in [howToFix].
+
+final Map<String, Map> MESSAGES = {
+};
diff --git a/pkg/dart_messages/lib/shared_messages.json b/pkg/dart_messages/lib/shared_messages.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/pkg/dart_messages/lib/shared_messages.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/pkg/dart_messages/pubspec.yaml b/pkg/dart_messages/pubspec.yaml
new file mode 100644
index 0000000..2df3361
--- /dev/null
+++ b/pkg/dart_messages/pubspec.yaml
@@ -0,0 +1,4 @@
+# This package is not intended to be published.
+name: dart_messages
+#version: do-not-upload
+dependencies:
diff --git a/pkg/dart_messages/test/dart_messages_test.dart b/pkg/dart_messages/test/dart_messages_test.dart
new file mode 100644
index 0000000..3983773
--- /dev/null
+++ b/pkg/dart_messages/test/dart_messages_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import '../lib/shared_messages.dart';
+
+void testJsonIsUpdated() {
+  var packageRoot = Platform.packageRoot;
+  if (packageRoot == null || packageRoot == "") {
+    throw new UnsupportedError("This test requires a package root.");
+  }
+  var jsonUri =
+      Uri.parse(packageRoot).resolve('dart_messages/shared_messages.json');
+  var jsonPath = jsonUri.toFilePath();
+  var content = new File(jsonPath).readAsStringSync();
+  if (JSON.encode(MESSAGES) != content) {
+    print("The content of the Dart messages and the corresponding JSON file");
+    print("is not the same.");
+    print("Please run bin/json_converter to update the JSON file.");
+    throw "Content is not the same";
+  }
+}
+
+void testIdsAreUnique() {
+  var usedIds = new Set();
+  for (var entry in MESSAGES.values) {
+    var id = entry['id'];
+    if (!usedIds.add(id)) {
+      throw "Id appears twice: $id";
+    }
+  }
+}
+
+void main() {
+  testJsonIsUpdated();
+  testIdsAreUnique();
+}
diff --git a/pkg/fixnum/lib/src/int64.dart b/pkg/fixnum/lib/src/int64.dart
index 7ff28d2..769ef21 100644
--- a/pkg/fixnum/lib/src/int64.dart
+++ b/pkg/fixnum/lib/src/int64.dart
@@ -104,7 +104,7 @@
 
     if (negative) return _negate(d0, d1, d2);
 
-    return new Int64._bits(d0, d1, d2);
+    return Int64._masked(d0, d1, d2);
   }
 
   /**
@@ -131,18 +131,13 @@
       negative = true;
       value = -value - 1;
     }
-    if (_haveBigInts) {
-      v0 = _MASK & value;
-      v1 = _MASK & (value >> _BITS);
-      v2 = _MASK2 & (value >> _BITS01);
-    } else {
-      // Avoid using bitwise operations that coerce their input to 32 bits.
-      v2 = value ~/ 17592186044416; // 2^44
-      value -= v2 * 17592186044416;
-      v1 = value ~/ 4194304; // 2^22
-      value -= v1 * 4194304;
-      v0 = value;
-    }
+    // Avoid using bitwise operations that in JavaScript coerce their input to
+    // 32 bits.
+    v2 = value ~/ 17592186044416; // 2^44
+    value -= v2 * 17592186044416;
+    v1 = value ~/ 4194304; // 2^22
+    value -= v1 * 4194304;
+    v0 = value;
 
     if (negative) {
       v0 = ~v0;
@@ -202,7 +197,7 @@
     int d0 = _MASK & bottom;
     int d1 = ((0xfff & top) << 10) | (0x3ff & (bottom >> _BITS));
     int d2 = _MASK2 & (top >> 12);
-    return new Int64._bits(d0, d1, d2);
+    return  Int64._masked(d0, d1, d2);
   }
 
   // Returns the [Int64] representation of the specified value. Throws
@@ -325,7 +320,7 @@
     int a0 = _l & o._l;
     int a1 = _m & o._m;
     int a2 = _h & o._h;
-    return new Int64._bits(a0, a1, a2);
+    return Int64._masked(a0, a1, a2);
   }
 
   Int64 operator |(other) {
@@ -333,7 +328,7 @@
     int a0 = _l | o._l;
     int a1 = _m | o._m;
     int a2 = _h | o._h;
-    return new Int64._bits(a0, a1, a2);
+    return Int64._masked(a0, a1, a2);
   }
 
   Int64 operator ^(other) {
@@ -629,23 +624,15 @@
     int l = _l;
     int m = _m;
     int h = _h;
-    bool negative = false;
+    // In the sum we add least significant to most significant so that in
+    // JavaScript double arithmetic rounding occurs on only the last addition.
     if ((_h & _SIGN_BIT_MASK) != 0) {
       l = _MASK & ~_l;
       m = _MASK & ~_m;
       h = _MASK2 & ~_h;
-      negative = true;
-    }
-
-    if (_haveBigInts) {
-      int result = (h << _BITS01) | (m << _BITS) | l;
-      return negative ? -result - 1 : result;
+      return -((1 + l) + (4194304 * m) + (17592186044416 * h));
     } else {
-      if (negative) {
-        return -((l + 1) + (m * 4194304) + (h * 17592186044416));
-      } else {
-        return (l + (m * 4194304)) + (h * 17592186044416);
-      }
+      return l + (4194304 * m) + (17592186044416 * h);
     }
   }
 
@@ -671,7 +658,6 @@
     if (isZero) return "0";
     Int64 x = this;
     String hexStr = "";
-    Int64 digit_f = new Int64(0xf);
     while (!x.isZero) {
       int digit = x._l & 0xf;
       hexStr = "${_hexDigit(digit)}$hexStr";
@@ -843,27 +829,8 @@
     return _sub(0, 0, 0, b0, b1, b2);
   }
 
-  // Determine whether the platform supports ints greater than 2^53
-  // without loss of precision.
-  static bool _haveBigIntsCached = null;
-
-  static bool get _haveBigInts {
-    if (_haveBigIntsCached == null) {
-      var x = 9007199254740992;
-      // Defeat compile-time constant folding.
-      if (2 + 2 != 4) {
-        x = 0;
-      }
-      var y = x + 1;
-      var same = y == x;
-      _haveBigIntsCached = !same;
-    }
-    return _haveBigIntsCached;
-  }
-
   String _hexDigit(int digit) => "0123456789ABCDEF"[digit];
 
-
   // Work around dart2js bugs with negative arguments to '>>' operator.
   static int _shiftRight(int x, int n) {
     if (x >= 0) {
diff --git a/pkg/fixnum/pubspec.yaml b/pkg/fixnum/pubspec.yaml
index b657f19..3d3bdaf 100644
--- a/pkg/fixnum/pubspec.yaml
+++ b/pkg/fixnum/pubspec.yaml
@@ -1,5 +1,5 @@
 name: fixnum
-version: 0.10.2
+version: 0.10.3
 author: Dart Team <misc@dartlang.org>
 description: Library for 32- and 64-bit fixed size integers.
 homepage: http://www.dartlang.org
diff --git a/pkg/js/CHANGELOG.md b/pkg/js/CHANGELOG.md
new file mode 100644
index 0000000..4ef2ebc
--- /dev/null
+++ b/pkg/js/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.6.0
+
+ * Version 0.6.0 is a complete rewrite of `package:js`.
diff --git a/pkg/js/README.md b/pkg/js/README.md
index d27b6eb..e1da41e 100644
--- a/pkg/js/README.md
+++ b/pkg/js/README.md
@@ -1,21 +1,8 @@
-Dart-JavaScript Interop
-=======================
+Methods and annotations to specify interoperability with JavaScript APIs.
 
-Status
-------
+*This packages requires Dart SDK 1.13.0.*
 
-Version 0.6.0 is a complete rewrite of package:js 
-
-The package now only contains annotations specifying the shape of the
-JavaScript API to import into Dart.
-The core implementation is defined directly in Dart2Js, Dartium, and DDC.
-
-**Warning: support in Dartium and Dart2Js is still in progress.
-
-#### Example - TODO(jacobr)
-
-Configuration and Initialization
---------------------------------
+*This is beta software. Please files [issues].*
 
 ### Adding the dependency
 
@@ -23,38 +10,98 @@
 
 ```yaml
 dependencies:
-  js: ">=0.6.0 <0.7.0"
+  js: ^0.6.0
 ```
 
-##### main.html
+### Example
 
-```html
-<html>
-  <head>
-  </head>
-  <body>
-    <script type="application/dart" src="main.dart"></script>
-  </body>
-</html>
-```
+See the [Chart.js Dart API](https://github.com/google/chartjs.dart/) for an
+end-to-end example.
 
-##### main.dart
+### Usage
 
-TODO(jacobr): example under construction.
+#### Calling methods
+
 ```dart
-library main;
+// Calls invoke JavaScript `JSON.stringify(obj)`.
+@JS("JSON.stringify")
+external String stringify(obj);
+```
 
-import 'package:js/js.dart';
+#### Classes and Namespaces
 
-main() {
+```dart
+@JS('google.maps')
+library maps;
+
+// Invokes the JavaScript getter `google.maps.map`.
+external Map get map;
+
+// `new Map` invokes JavaScript `new google.maps.Map(location)`
+@JS()
+class Map {
+  external Map(Location location);
+  external Location getLocation();
+}
+
+// `new Location(...)` invokes JavaScript `new google.maps.LatLng(...)`
+//
+// We recommend against using custom JavaScript names whenever
+// possible. It is easier for users if the JavaScript names and Dart names
+// are consistent.
+@JS("LatLng")
+class Location {
+  external Location(num lat, num lng);
 }
 ```
 
-Contributing and Filing Bugs
-----------------------------
+#### JavaScript object literals
 
-Please file bugs and features requests on the Github issue tracker: https://github.com/dart-lang/js-interop/issues
+Many JavaScript APIs take an object literal as an argument. For example:
+```js
+// JavaScript
+printOptions({responsive: true});
+```
 
-We also love and accept community contributions, from API suggestions to pull requests. Please file an issue before beginning work so we can discuss the design and implementation. We are trying to create issues for all current and future work, so if something there intrigues you (or you need it!) join in on the discussion.
+If you want to use `printOptions` from Dart, you cannot simply pass a Dart `Map`
+object – they are "opaque" in JavaScript.
 
-All we require is that you sign the Google Individual Contributor License Agreement https://developers.google.com/open-source/cla/individual?csw=1
+
+Instead, create a Dart class with both the `@JS()` and
+`@anonymous` annotations.
+
+```dart
+// Dart
+void main() {
+  printOptions(new Options(responsive: true));
+}
+
+@JS()
+external printOptions(Options options);
+
+@JS()
+@anonymous
+class Options {
+  external bool get responsive;
+
+  external factory Options({bool responsive});
+}
+```
+
+#### Passing functions to JavaScript.
+
+If you are passing a Dart function to a JavaScript API, you must wrap it using
+`allowInterop` or `allowInteropCaptureThis`.
+
+## Contributing and Filing Bugs
+
+Please file bugs and features requests on the [Github issue tracker][issues].
+
+We also love and accept community contributions, from API suggestions to pull requests.
+Please file an issue before beginning work so we can discuss the design and implementation.
+We are trying to create issues for all current and future work, so if something there intrigues you (or you need it!) join in on the discussion.
+
+Code contributors must sign the
+[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1).
+
+[issues]: https://goo.gl/j3rzs0
diff --git a/pkg/js/example/README.md b/pkg/js/example/README.md
new file mode 100644
index 0000000..6e5403e
--- /dev/null
+++ b/pkg/js/example/README.md
@@ -0,0 +1 @@
+See the [Chart.js Dart API](https://github.com/google/chartjs.dart/) for a usage example.
diff --git a/pkg/js/lib/src/varargs.dart b/pkg/js/lib/src/varargs.dart
new file mode 100644
index 0000000..6d316b3
--- /dev/null
+++ b/pkg/js/lib/src/varargs.dart
@@ -0,0 +1,64 @@
+// 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.
+
+/// Declarations for variable arguments support
+/// (rest params and spread operator).
+///
+/// These are currently *not* supported by dart2js or Dartium.
+library js.varargs;
+
+class _Rest {
+  const _Rest();
+}
+
+/// Annotation to tag ES6 rest parameters (https://goo.gl/r0bJ1K).
+///
+/// This is *not* supported by dart2js or Dartium (yet).
+///
+/// This is meant to be used by the Dart Dev Compiler
+/// when compiling helper functions of its runtime to ES6.
+///
+/// The following function:
+///
+///     foo(a, b, @rest others) { ... }
+///
+/// Will be compiled to ES6 code like the following:
+///
+///     function foo(a, b, ...others) { ... }
+///
+/// Which is roughly equivalent to the following ES5 code:
+///
+///     function foo(a, b/*, ...others*/) {
+///       var others = [].splice.call(arguments, 2);
+///       ...
+///     }
+///
+const _Rest rest = const _Rest();
+
+/// Intrinsic function that maps to the ES6 spread operator
+/// (https://goo.gl/NedHKr).
+///
+/// This is *not* supported by dart2js or Dartium (yet),
+/// and *cannot* be called at runtime.
+///
+/// This is meant to be used by the Dart Dev Compiler when
+/// compiling its runtime to ES6.
+///
+/// The following expression:
+///
+///     foo(a, b, spread(others))
+///
+/// Will be compiled to ES6 code like the following:
+///
+///     foo(a, b, ...others)
+///
+/// Which is roughly equivalent to the following ES5 code:
+///
+///     foo.apply(null, [a, b].concat(others))
+///
+dynamic spread(args) {
+  throw new StateError(
+      'The spread function cannot be called, '
+      'it should be compiled away.');
+}
diff --git a/pkg/js/pubspec.yaml b/pkg/js/pubspec.yaml
index d558126..7555876 100644
--- a/pkg/js/pubspec.yaml
+++ b/pkg/js/pubspec.yaml
@@ -1,9 +1,10 @@
 name: js
-version: 0.6.0-dev.1
+version: 0.6.0
 authors:
 - Dart Team <misc@dartlang.org>
-- Alexandre Ardhuin <alexandre.ardhuin@gmail.com>
 description: Access JavaScript from Dart.
-homepage: https://github.com/dart-lang/js-interop
+homepage: https://github.com/dart-lang/sdk/tree/master/pkg/js
 environment:
-  sdk: '>=1.13.0-dev <2.0.0'
+  sdk: '>=1.13.0 <2.0.0'
+dev_dependencies:
+  browser: '^0.10.0+2'
diff --git a/pkg/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index 67ea25c..5d680f5 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -299,18 +299,19 @@
   }
 
   /// Creates a literal js string from [value].
-  LiteralString escapedString(String value) {
+  LiteralString _legacyEscapedString(String value) {
    // Start by escaping the backslashes.
     String escaped = value.replaceAll('\\', '\\\\');
     // Do not escape unicode characters and ' because they are allowed in the
     // string literal anyway.
-    escaped = escaped.replaceAllMapped(new RegExp('\n|"|\b|\t|\v'), (match) {
+    escaped = escaped.replaceAllMapped(new RegExp('\n|"|\b|\t|\v|\r'), (match) {
       switch (match.group(0)) {
         case "\n" : return r"\n";
         case "\"" : return r'\"';
         case "\b" : return r"\b";
         case "\t" : return r"\t";
         case "\f" : return r"\f";
+        case "\r" : return r"\r";
         case "\v" : return r"\v";
       }
     });
@@ -322,6 +323,105 @@
   }
 
   /// Creates a literal js string from [value].
+  LiteralString escapedString(String value,
+       {bool utf8: false, bool ascii: false}) {
+    if (utf8 == false && ascii == false) return _legacyEscapedString(value);
+    if (utf8 && ascii) throw new ArgumentError('Cannot be both UTF8 and ASCII');
+
+    int singleQuotes = 0;
+    int doubleQuotes = 0;
+    int otherEscapes = 0;
+    int unpairedSurrogates = 0;
+
+    for (int rune in value.runes) {
+      if (rune == charCodes.$BACKSLASH) {
+        ++otherEscapes;
+      } else if (rune == charCodes.$SQ) {
+        ++singleQuotes;
+      } else if (rune == charCodes.$DQ) {
+        ++doubleQuotes;
+      } else if (rune == charCodes.$LF || rune == charCodes.$CR ||
+                 rune == charCodes.$LS || rune == charCodes.$PS) {
+        // Line terminators.
+        ++otherEscapes;
+      } else if (rune == charCodes.$BS || rune == charCodes.$TAB ||
+                 rune == charCodes.$VTAB || rune == charCodes.$FF) {
+        ++otherEscapes;
+      } else if (_isUnpairedSurrogate(rune)) {
+        ++unpairedSurrogates;
+      } else {
+        if (ascii && (rune < charCodes.$SPACE || rune >= charCodes.$DEL)) {
+          ++otherEscapes;
+        }
+      }
+    }
+
+    LiteralString finish(String quote, String contents) {
+      return new LiteralString('$quote$contents$quote');
+    }
+
+    if (otherEscapes == 0 && unpairedSurrogates == 0) {
+      if (doubleQuotes == 0) return finish('"', value);
+      if (singleQuotes == 0) return finish("'", value);
+    }
+
+    bool useSingleQuotes = singleQuotes < doubleQuotes;
+
+    StringBuffer sb = new StringBuffer();
+
+    for (int rune in value.runes) {
+      String escape = _irregularEscape(rune, useSingleQuotes);
+      if (escape != null) {
+        sb.write(escape);
+        continue;
+      }
+      if (rune == charCodes.$LS ||
+          rune == charCodes.$PS ||
+          _isUnpairedSurrogate(rune) ||
+          ascii && (rune < charCodes.$SPACE || rune >= charCodes.$DEL)) {
+        if (rune < 0x100) {
+          sb.write(r'\x');
+          sb.write(rune.toRadixString(16).padLeft(2, '0'));
+        } else if (rune < 0x10000) {
+          sb.write(r'\u');
+          sb.write(rune.toRadixString(16).padLeft(4, '0'));
+        } else {
+          // Not all browsers accept the ES6 \u{zzzzzz} encoding, so emit two
+          // surrogate pairs.
+          var bits = rune - 0x10000;
+          var leading = 0xD800 | (bits >> 10);
+          var trailing = 0xDC00 | (bits & 0x3ff);
+          sb.write(r'\u');
+          sb.write(leading.toRadixString(16));
+          sb.write(r'\u');
+          sb.write(trailing.toRadixString(16));
+        }
+      } else {
+        sb.writeCharCode(rune);
+      }
+    }
+
+    return finish(useSingleQuotes ? "'" : '"', sb.toString());
+  }
+
+  static bool _isUnpairedSurrogate(int code) => (code & 0xFFFFF800) == 0xD800;
+
+  static String _irregularEscape(int code, bool useSingleQuotes) {
+    switch (code) {
+      case charCodes.$SQ: return useSingleQuotes ? r"\'" : r"'";
+      case charCodes.$DQ: return useSingleQuotes ? r'"' : r'\"';
+      case charCodes.$BACKSLASH: return r'\\';
+      case charCodes.$BS: return r'\b';
+      case charCodes.$TAB: return r'\t';
+      case charCodes.$LF: return r'\n';
+      case charCodes.$VTAB: return r'\v';
+      case charCodes.$FF: return r'\f';
+      case charCodes.$CR: return r'\r';
+    }
+    return null;
+  }
+
+  /// Creates a literal js string from [value].
   ///
   /// Note that this function only puts quotes around [value]. It does not do
   /// any escaping, so use only when you can guarantee that [value] does not
@@ -1436,4 +1536,4 @@
   Iterator<Node> get iterator {
     return new _InterleaveIterator(source.iterator, separator);
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
index 95c8819..b6d11aa 100644
--- a/pkg/js_ast/lib/src/nodes.dart
+++ b/pkg/js_ast/lib/src/nodes.dart
@@ -985,7 +985,7 @@
 
   int get value;
 
-  int get precedenceLevel => PRIMARY;
+  int get precedenceLevel => value.isNegative ? UNARY : PRIMARY;
 }
 
 /// Interace for a deferred string value. An implementation has to provide
@@ -1074,6 +1074,8 @@
 
   LiteralNumber(this.value);
 
+  int get precedenceLevel => value.startsWith('-') ? UNARY : PRIMARY;
+  
   accept(NodeVisitor visitor) => visitor.visitLiteralNumber(this);
   LiteralNumber _clone() => new LiteralNumber(value);
 }
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 7a1124f..edd4189 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -920,6 +920,7 @@
     // reserved word.  We don't generate fields with reserved word names except
     // for 'super'.
     if (field == '"super"') return false;
+    if (field == '"catch"') return false;
     return true;
   }
 
@@ -933,7 +934,10 @@
       LiteralString selectorString = selector;
       String fieldWithQuotes = selectorString.value;
       if (isValidJavaScriptId(fieldWithQuotes)) {
-        if (access.receiver is LiteralNumber) out(" ", isWhitespace: true);
+        if (access.receiver is LiteralNumber &&
+            lastCharCode != charCodes.$CLOSE_PAREN) {
+          out(" ", isWhitespace: true);
+        }
         out(".");
         startNode(selector);
         out(fieldWithQuotes.substring(1, fieldWithQuotes.length - 1));
@@ -941,7 +945,10 @@
         return;
       }
     } else if (selector is Name) {
-      if (access.receiver is LiteralNumber) out(" ", isWhitespace: true);
+      if (access.receiver is LiteralNumber &&
+          lastCharCode != charCodes.$CLOSE_PAREN) {
+        out(" ", isWhitespace: true);
+      }
       out(".");
       startNode(selector);
       selector.accept(this);
@@ -1062,22 +1069,31 @@
     // Print all the properties on one line until we see a function-valued
     // property.  Ideally, we would use a proper pretty-printer to make the
     // decision based on layout.
+    bool exitOneLinerMode(Expression value) {
+      return
+          value is Fun ||
+          value is ArrayInitializer && value.elements.any((e) => e is Fun);
+    }
+
+    bool isOneLiner = node.isOneLiner || shouldCompressOutput;
     List<Property> properties = node.properties;
     out("{");
     indentMore();
     for (int i = 0; i < properties.length; i++) {
+      Node value = properties[i].value;
+      if (isOneLiner && exitOneLinerMode(value)) isOneLiner = false;
       if (i != 0) {
         out(",");
-        if (node.isOneLiner) spaceOut();
+        if (isOneLiner) spaceOut();
       }
-      if (!node.isOneLiner) {
+      if (!isOneLiner) {
         forceLine();
         indent();
       }
       visit(properties[i]);
     }
     indentLess();
-    if (!node.isOneLiner && !properties.isEmpty) {
+    if (!isOneLiner && !properties.isEmpty) {
       lineOut();
       indent();
     }
@@ -1487,4 +1503,4 @@
     context.exitNode(node, startPosition, position, closingPosition);
     return parent;
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/js_ast/test/string_escape_test.dart b/pkg/js_ast/test/string_escape_test.dart
new file mode 100644
index 0000000..3811629
--- /dev/null
+++ b/pkg/js_ast/test/string_escape_test.dart
@@ -0,0 +1,149 @@
+// 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 js_ast.string_escape_test;
+
+import 'package:js_ast/js_ast.dart';
+import 'package:js_ast/src/characters.dart';
+import 'package:unittest/unittest.dart';
+
+const int $LCURLY = $OPEN_CURLY_BRACKET;
+const int $RCURLY = $CLOSE_CURLY_BRACKET;
+
+void main() {
+  check(input, expected, {ascii: false, utf8: false}) {
+    if (input is List) input = new String.fromCharCodes(input);
+    String actual = js.escapedString(input, ascii: ascii, utf8: utf8).value;
+    if (expected is List) {
+      expect(actual.codeUnits, expected);
+    } else {
+      expect(actual, expected);
+    }
+  }
+
+  test('simple', () {
+      check('', [$DQ, $DQ]);
+      check('a', [$DQ, $a, $DQ]);
+    });
+
+  test('simple-escapes', () {
+      check([$BS], [$DQ, $BACKSLASH, $b, $DQ]);
+      check([$BS], [$DQ, $BACKSLASH, $b, $DQ], ascii: true);
+      check([$BS], [$DQ, $BACKSLASH, $b, $DQ], utf8: true);
+
+      check([$LF], [$DQ, $BACKSLASH, $n, $DQ]);
+      check([$LF], [$DQ, $BACKSLASH, $n, $DQ], ascii: true);
+      check([$LF], [$DQ, $BACKSLASH, $n, $DQ], utf8: true);
+
+      check([$FF], [$DQ, $FF, $DQ]);
+      check([$FF], [$DQ, $BACKSLASH, $f, $DQ], ascii: true);
+      check([$FF], [$DQ, $BACKSLASH, $f, $DQ], utf8: true);
+
+      check([$CR], [$DQ, $BACKSLASH, $r, $DQ]);
+      check([$CR], [$DQ, $BACKSLASH, $r, $DQ], ascii: true);
+      check([$CR], [$DQ, $BACKSLASH, $r, $DQ], utf8: true);
+
+      check([$TAB], [$DQ, $BACKSLASH, $t, $DQ]);
+      check([$TAB], [$DQ, $BACKSLASH, $t, $DQ], ascii: true);
+      check([$TAB], [$DQ, $BACKSLASH, $t, $DQ], utf8: true);
+
+      check([$VTAB], [$DQ, $BACKSLASH, $v, $DQ]);
+      check([$VTAB], [$DQ, $BACKSLASH, $v, $DQ], ascii: true);
+      check([$VTAB], [$DQ, $BACKSLASH, $v, $DQ], utf8: true);
+    });
+
+  test('unnamed-control-codes-escapes', () {
+      check([0, 1, 2, 3], [$DQ, 0, 1, 2, 3, $DQ]);
+      check([0, 1, 2, 3], r'''"\x00\x01\x02\x03"''', ascii: true);
+      check([0, 1, 2, 3], [$DQ, 0, 1, 2, 3, $DQ], utf8: true);
+    });
+
+
+  test('line-separator', () {
+      // Legacy escaper is broken.
+      // check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ]);
+      check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ], ascii: true);
+      check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ], utf8: true);
+    });
+
+  test('page-separator', () {
+      // Legacy escaper is broken.
+      // check([$PS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $9, $DQ]);
+      check([$PS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $9, $DQ], ascii: true);
+      check([$PS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $9, $DQ], utf8: true);
+    });
+
+  test('legacy-escaper-is-broken', () {
+      check([$LS], [$DQ, 0x2028, $DQ]);
+      check([$PS], [$DQ, 0x2029, $DQ]);
+    });
+
+  test('choose-quotes', () {
+      check('\'', [$DQ, $SQ, $DQ]);
+      check('"', [$SQ, $DQ, $SQ], ascii: true);
+      check("'", [$DQ, $SQ, $DQ], ascii: true);
+      // Legacy always double-quotes
+      check([$DQ, $DQ, $SQ],
+            [$DQ, $BACKSLASH, $DQ, $BACKSLASH, $DQ, $SQ, $DQ]);
+      // Using single quotes saves us one backslash:
+      check([$DQ, $DQ, $SQ],
+            [$SQ, $DQ, $DQ, $BACKSLASH, $SQ, $SQ],
+            ascii: true);
+      check([$DQ, $SQ, $SQ],
+            [$DQ, $BACKSLASH, $DQ, $SQ, $SQ, $DQ],
+            ascii: true);
+    });
+
+  test('u1234', () {
+      check('\u1234', [$DQ, 0x1234, $DQ]);
+      check('\u1234', [$DQ, $BACKSLASH, $u, $1, $2, $3, $4, $DQ], ascii: true);
+      check('\u1234', [$DQ, 0x1234, $DQ], utf8: true);
+    });
+
+  test('u12345', () {
+      check([0x12345], [$DQ, 55304, 57157, $DQ]);
+      // TODO: ES6 option:
+      //check([0x12345],
+      //      [$DQ, $BACKSLASH, $u, $LCURLY, $1, $2, $3, $4, $5, $RCURLY, $DQ],
+      //      ascii: true);
+      check([0x12345], r'''"\ud808\udf45"''', ascii: true);
+      check([0x12345],
+            [$DQ, $BACKSLASH, $u, $d, $8, $0, $8,
+                  $BACKSLASH, $u, $d, $f, $4, $5, $DQ],
+            ascii: true);
+      check([0x12345], [$DQ, 55304, 57157, $DQ], utf8: true);
+    });
+
+  test('unpaired-surrogate', () {
+      // (0xD834, 0xDD1E) = 0x1D11E
+      // Strings containing unpaired surrogates must be encoded to prevent
+      // problems with the utf8 file-level encoding.
+      check([0xD834], [$DQ, 0xD834, $DQ]);  // Legacy escapedString broken.
+      check([0xD834], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $DQ], ascii: true);
+      check([0xD834], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $DQ], utf8: true);
+
+      check([0xDD1E], [$DQ, 0xDD1E, $DQ]);  // Legacy escapedString broken.
+      check([0xDD1E], [$DQ, $BACKSLASH, $u, $d, $d, $1, $e, $DQ], ascii: true);
+      check([0xDD1E], [$DQ, $BACKSLASH, $u, $d, $d, $1, $e, $DQ], utf8: true);
+
+      check([0xD834, $A],
+            [$DQ, 0xD834, $A, $DQ]);  // Legacy escapedString broken.
+      check([0xD834, $A],
+            [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ],
+            ascii: true);
+      check([0xD834, $A],
+            [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ],
+            utf8: true);
+
+      check([0xD834, 0xDD1E], [$DQ, 0xD834, 0xDD1E, $DQ]);  // Legacy ok.
+      check([0xD834, 0xDD1E],
+            [$DQ,
+              $BACKSLASH, $u, $d, $8, $3, $4,
+              $BACKSLASH, $u, $d, $d, $1, $e,
+              $DQ],
+            ascii: true);
+      check([0xD834, 0xDD1E], r'''"\ud834\udd1e"''', ascii: true);
+      check([0xD834, 0xDD1E], [$DQ, 0xD834, 0xDD1E, $DQ], utf8: true);
+    });
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index e9c99b2..8f29f55 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -19,40 +19,77 @@
 unittest/*: Skip # Issue 21949
 lookup_map/*: SkipByDesign
 
-[ $runtime == vm && $mode == debug]
-analysis_server/test/analysis_server_test: SkipSlow  # Times out
-analysis_server/test/completion_test: SkipSlow  # Times out
-analysis_server/test/domain_context_test: SkipSlow  # Times out
-analysis_server/test/domain_server_test: SkipSlow  # Times out
-analysis_server/test/integration/*: SkipSlow # Times out
-analysis_server/tool/spec/check_all_test: SkipSlow # Times out
-analyzer/test/generated/element_test: SkipSlow  # Times out
-analyzer/test/generated/parser_test: SkipSlow  # Times out
+[ $runtime == vm && $mode == debug ]
+analysis_server/test/completion_test: Pass, Slow
 
 [ $runtime == vm && $system == windows]
 analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
+analysis_server/test/integration/analysis/analysis_options_test: RuntimeError # Issue 24796
+analyzer/test/generated/all_the_rest_test: Fail # Issue 21772
 
 [ $compiler == dart2js ]
+analyzer_cli/test/*: SkipByDesign # Only meant to run on vm
+analysis_server/test/*: Skip # Issue 22161
+analysis_server/test/analysis_notification_highlights_test: Pass, Slow # 19756, 21628
+analysis_server/test/analysis_notification_navigation_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/analysis_notification_occurrences_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/analysis_notification_outline_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/domain_analysis_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/domain_completion_test: Pass, Slow
+analysis_server/test/edit/assists_test: Pass, Slow
+analysis_server/test/edit/format_test: Pass, Slow
+analysis_server/test/edit/refactoring_test: Pass, Slow # Issue 19756, 21628
+analysis_server/test/search/element_references_test: Pass, Slow
+analysis_server/test/search/top_level_declarations_test: Pass, Slow # 19756, 21628
+analysis_server/test/services/index/store/codec_test: Pass, Slow
+analysis_server/test/socket_server_test: Pass, Slow # Issue 19756, 21628
+analyzer/test/dart/element/element_test: Pass, Slow # Issue 24914
+analyzer/test/enum_test: Slow, Pass, Fail # Issue 21323
+analyzer/test/generated/all_the_rest_test: Pass, Slow # Issue 21628
+analyzer/test/generated/ast_test: Pass, Slow # Issue 21628
+analyzer/test/generated/compile_time_error_code_test: Pass, Slow
+analyzer/test/generated/compile_time_error_code_test: Pass, Slow # Issue 21628
+analyzer/test/generated/declaration_resolver_test: Pass, Slow # Issue 24914
+analyzer/test/generated/element_test: Pass, Slow # Issue 21628
+analyzer/test/generated/engine_test: SkipSlow
+analyzer/test/generated/incremental_resolver_test: Pass, Slow # Issue 21628
+analyzer/test/generated/incremental_scanner_test: Pass, Slow # Issue 21628
+analyzer/test/generated/non_error_resolver_test: Pass, Slow # Issue 21628
+analyzer/test/generated/parser_test: Pass, Slow # Issue 21628
+analyzer/test/generated/resolver_test: Pass, Slow # Issue 21628
+analyzer/test/generated/scanner_test: Pass, Slow # Issue 21628
+analyzer/test/generated/source_factory_test: Pass, Slow # Issue 21628
+analyzer/test/generated/static_type_warning_code_test: Pass, Slow
+analyzer/test/generated/static_type_warning_code_test: Pass, Slow # Issue 21628
+analyzer/test/generated/static_warning_code_test: Pass, Slow # Issue 21628
+analyzer/test/generated/utilities_test: Pass, Slow # Issue 21628
+analyzer/test/src/context/cache_test: Pass, Slow # Issue 21628
+analyzer/test/src/context/context_test: Pass, Timeout # dartbug.com/23658
+analyzer/test/src/dart/element/element_test: Pass, Slow # Issue 24914
+analyzer/test/src/summary/resynthesize_test: Pass, Slow
+analyzer/test/src/summary/summary_sdk_test: Pass, Slow # Issue 24914
+analyzer/test/src/summary/summary_test: Pass, Slow # Issue 24914
+analyzer/test/src/task/dart_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/dart_work_manager_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/driver_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/general_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/html_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/html_work_manager_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/incremental_element_builder_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/inputs_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/manager_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/model_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/options_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/options_work_manager_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/strong/checker_test: Pass, Slow # Issue 21628
 collection/test/equality_test/01: Fail # Issue 1533
 collection/test/equality_test/02: Fail # Issue 1533
 collection/test/equality_test/03: Fail # Issue 1533
 collection/test/equality_test/04: Fail # Issue 1533
 collection/test/equality_test/05: Fail # Issue 1533
 collection/test/equality_test/none: Pass, Fail # Issue 14348
+lookup_map/test/version_check_test: SkipByDesign # Only meant to run in vm.
 typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
-analyzer/test/generated/engine_test: SkipSlow
-analyzer/test/generated/static_type_warning_code_test: Pass, Slow
-analyzer/test/generated/compile_time_error_code_test: Pass, Slow
-
-analyzer/test/enum_test: Slow, Pass, Fail # Issue 21323
-analyzer/test/src/context/context_test: Pass, Timeout # dartbug.com/23658
-
-analysis_server/test/*: Skip # Issue 22161
-analysis_server/test/search/element_references_test: Pass, Slow
-analysis_server/test/services/index/store/codec_test: Pass, Slow
-analysis_server/test/domain_completion_test: Pass, Slow
-analysis_server/test/edit/assists_test: Pass, Slow
-analysis_server/test/edit/format_test: Pass, Slow
 
 # Analysis server integration tests don't make sense to run under
 # dart2js, since the code under test always runs in the Dart vm as a
@@ -70,41 +107,6 @@
 analysis_server/test/search/element_reference_test: Pass, Slow # Issue 19756
 analysis_server/index/store/codec_test: Pass, Slow # Issue 19756
 
-[ $compiler == dart2js ]
-analysis_server/test/analysis_notification_highlights_test: Pass, Slow # 19756, 21628
-analysis_server/test/analysis_notification_navigation_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/analysis_notification_occurrences_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/analysis_notification_outline_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/domain_analysis_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/edit/refactoring_test: Pass, Slow # Issue 19756, 21628
-analysis_server/test/search/top_level_declarations_test: Pass, Slow # 19756, 21628
-analysis_server/test/socket_server_test: Pass, Slow # Issue 19756, 21628
-analyzer/test/generated/all_the_rest_test: Pass, Slow # Issue 21628
-analyzer/test/generated/ast_test: Pass, Slow # Issue 21628
-analyzer/test/generated/compile_time_error_code_test: Pass, Slow # Issue 21628
-analyzer/test/generated/element_test: Pass, Slow # Issue 21628
-analyzer/test/generated/incremental_resolver_test: Pass, Slow # Issue 21628
-analyzer/test/generated/incremental_scanner_test: Pass, Slow # Issue 21628
-analyzer/test/generated/non_error_resolver_test: Pass, Slow # Issue 21628
-analyzer/test/generated/parser_test: Pass, Slow # Issue 21628
-analyzer/test/generated/resolver_test: Pass, Slow # Issue 21628
-analyzer/test/generated/scanner_test: Pass, Slow # Issue 21628
-analyzer/test/generated/source_factory_test: Pass, Slow # Issue 21628
-analyzer/test/generated/static_type_warning_code_test: Pass, Slow # Issue 21628
-analyzer/test/generated/static_warning_code_test: Pass, Slow # Issue 21628
-analyzer/test/generated/utilities_test: Pass, Slow # Issue 21628
-analyzer/test/src/context/cache_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/dart_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/dart_work_manager_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/driver_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/general_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/html_work_manager_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/incremental_element_builder_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/inputs_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/manager_test: Pass, Slow # Issue 21628
-analyzer/test/src/task/model_test: Pass, Slow # Issue 21628
-lookup_map/test/version_check_test: SkipByDesign # Only meant to run in vm.
-
 [ $runtime == jsshell ]
 async/test/stream_zip_test: RuntimeError, OK # Timers are not supported.
 
@@ -123,11 +125,10 @@
 # Unexplained errors only occuring on Safari 6.1 and earlier.
 typed_data/test/typed_buffers_test: RuntimeError
 
-[ $runtime == vm && $system == windows ]
-analyzer/test/generated/all_the_rest_test: Fail # Issue 21772
-
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 compiler/samples/compile_loop/compile_loop: CompileTimeError  # Issue 16524
+lookup_map/test/version_check_test: StaticWarning # https://github.com/dart-lang/http_parser/issues/6
+lookup_map/test/lookup_map_test: StaticWarning # https://github.com/dart-lang/http_parser/issues/6
 
 [ $compiler == dart2js && $csp ]
 # This test cannot run under CSP because it is injecting a JavaScript polyfill
@@ -144,10 +145,12 @@
 analysis_server/tool/spec/check_all_test: SkipByDesign # Uses dart:io.
 analyzer/test/*: SkipByDesign # Uses dart:io.
 analyzer/tool/task_dependency_graph/check_test: SkipByDesign # Uses dart:io.
+analyzer/tool/summary/check_test: SkipByDesign # Uses dart:io.
 analyzer2dart/*: SkipByDesign # Uses dart:io.
 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.
+dart_messages/test/dart_messages_test: Skip  # 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
@@ -164,8 +167,10 @@
 [ $use_repository_packages ]
 analyzer/test/*: PubGetError
 
-[ $compiler == dart2js && $cps_ir ]
-lookup_map/test/lookup_map_test: RuntimeError # $async$temp1.get$tests is not a function
+[ $compiler == dart2js && $cps_ir && $host_checked == false ]
+analyzer/test/dart/element/element_test: Pass, Slow # Times out due to inlining, but see issue 24485
+analyzer/test/src/summary/resynthesize_test: Pass, Slow # Times out due to inlining, but see issue 24485
+analyzer/test/src/task/strong_mode_test: Pass, Slow # Times out due to inlining, but see issue 24485
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 analyzer/test/enum_test: Crash # Issue 24485
diff --git a/pkg/pkg_files.gyp b/pkg/pkg_files.gyp
index 78a751f..afb09cf 100644
--- a/pkg/pkg_files.gyp
+++ b/pkg/pkg_files.gyp
@@ -4,10 +4,13 @@
 
 {
   'targets': [
-    # Other targets depend on pkg files, but have to many inputs, which causes
+    # Other targets depend on pkg files, but have too many inputs, which causes
     # issues on some platforms.
     # This target lists all the files in pkg and third_party/pkg,
-    # and creates a single pkg_files.stamp
+    # and creates the timestamp pkg_files.stamp, which depends on some
+    # intermediate helper timestamps.
+    # We split third_party/pkg up into three groups, based on the last
+    # character before .dart at the end of the filename.
     {
       'target_name': 'pkg_files_stamp',
       'type': 'none',
@@ -17,7 +20,9 @@
           'inputs': [
             '../tools/create_timestamp_file.py',
             '<!@(["python", "../tools/list_files.py", "\\.dart$", "."])',
-            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files.stamp',
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_1.stamp',
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_2.stamp',
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_3.stamp',
           ],
           'outputs': [
             '<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
@@ -28,15 +33,47 @@
           ],
         },
         {
-          'action_name': 'make_third_party_pkg_files_stamp',
+          'action_name': 'make_third_party_pkg_files_1_stamp',
           'inputs': [
             '../tools/create_timestamp_file.py',
             '<!@(["python", "../tools/list_files.py",'
-                '"^(?!.*_test.dart).*dart$",'
+                '"^(?!.*_test\.dart).*[a-k]\.dart$",'
                 '"../third_party/pkg"])',
           ],
           'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files.stamp',
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_1.stamp',
+          ],
+          'action': [
+            'python', '../tools/create_timestamp_file.py',
+            '<@(_outputs)',
+          ],
+        },
+        {
+          'action_name': 'make_third_party_pkg_files_2_stamp',
+          'inputs': [
+            '../tools/create_timestamp_file.py',
+            '<!@(["python", "../tools/list_files.py",'
+                '"^(?!.*_test\.dart).*[l-r]\.dart$",'
+                '"../third_party/pkg"])',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_2.stamp',
+          ],
+          'action': [
+            'python', '../tools/create_timestamp_file.py',
+            '<@(_outputs)',
+          ],
+        },
+        {
+          'action_name': 'make_third_party_pkg_files_3_stamp',
+          'inputs': [
+            '../tools/create_timestamp_file.py',
+            '<!@(["python", "../tools/list_files.py",'
+                '"^(?!.*_test\.dart).*[^a-r]\.dart$",'
+                '"../third_party/pkg"])',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_3.stamp',
           ],
           'action': [
             'python', '../tools/create_timestamp_file.py',
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
index 2404f3e..1366f47 100644
--- a/pkg/pkgbuild.status
+++ b/pkg/pkgbuild.status
@@ -2,22 +2,15 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-samples/third_party/dromaeo: Pass, Slow
 samples/searchable_list: Pass, Slow
 
 [ $use_repository_packages ]
 pkg/analyzer: PubGetError
 samples/third_party/angular_todo: Fail # angular needs to be updated
-samples/third_party/todomvc_performance: Skip # dependencies are not in the repo
 
 [ $use_public_packages ]
 pkg/compiler: SkipByDesign # js_ast is not published
 samples/third_party/angular_todo: Pass, Slow
-samples/third_party/todomvc_performance: Pass, Slow
 
 [ $builder_tag == russian ]
 samples/third_party/angular_todo: Fail # Issue 16356
-samples/third_party/dromaeo: Fail # Issue 23760
-
-[ $use_public_packages && $system == windows ]
-samples/third_party/todomvc_performance: Fail # Issue 18086
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index cbc0643..94de113 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -11,6 +11,11 @@
   # Debug build of Dart so that clients can still use a Release build of Dart
   # while themselves doing a Debug build.
   dart_debug = false
+
+  # Explicitly set the target architecture in case of precompilation. Leaving
+  # this unspecified results in automatic target architecture detection.
+  # Available options are: arm, arm64, mips, x64 and ia32
+  dart_target_arch = ""
 }
 
 config("dart_public_config") {
@@ -21,6 +26,24 @@
 
 config("dart_config") {
   defines = []
+
+  if (dart_target_arch != "") {
+    if (dart_target_arch == "arm") {
+      defines += [ "TARGET_ARCH_ARM" ]
+    } else if (dart_target_arch == "arm64") {
+      defines += [ "TARGET_ARCH_ARM64" ]
+    } else if (dart_target_arch == "mips") {
+      defines += [ "TARGET_ARCH_MIPS" ]
+    } else if (dart_target_arch == "x64") {
+      defines += [ "TARGET_ARCH_X64" ]
+    } else if (dart_target_arch == "ia32") {
+      defines += [ "TARGET_ARCH_IA32" ]
+    } else  {
+      print("Invalid |dart_target_arch|")
+      assert(false)
+    }
+  }
+
   if (dart_debug) {
     defines += ["DEBUG"]
   } else {
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 1185ee4..b6d6ac1 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -8,6 +8,32 @@
 }
 
 
+resources_sources_gypi =
+    exec_script("../../tools/gypi_to_gn.py",
+                [rebase_path("resources_sources.gypi")],
+                "scope",
+                ["resources_sources.gypi"])
+
+# Generate a resources.cc file for the service isolate without Observatory.
+action("gen_resources_cc") {
+  visibility = [ ":*" ] # Only targets in this file can see this.
+  script = "../tools/create_resources.py"
+  inputs = [
+    "../tools/create_resources.py",
+  ]
+  sources = resources_sources_gypi.sources
+  outputs = [ "$target_gen_dir/resources_gen.cc" ]
+  args = [
+    "--output",
+    rebase_path("$target_gen_dir/resources_gen.cc", root_build_dir),
+    "--outer_namespace", "dart",
+    "--inner_namespace", "bin",
+    "--table_name", "service_bin",
+    "--root_prefix", rebase_path(".", root_build_dir) + "/",
+  ] + rebase_path(sources, root_build_dir)
+}
+
+
 template("gen_library_src_path") {
   assert(defined(invoker.sources), "Need sources in $target_name")
   assert(defined(invoker.output), "Need output in $target_name")
@@ -143,6 +169,8 @@
 executable("gen_snapshot") {
   configs += ["..:dart_config"]
   deps = [
+    ":gen_resources_cc",
+    ":gen_snapshot_dart_io",
     ":generate_builtin_cc_file",
     ":generate_io_cc_file",
     ":generate_io_patch_cc_file",
@@ -163,10 +191,13 @@
     "platform_macos.cc",
     "platform_win.cc",
     "platform.h",
+    "vmservice_impl.cc",
+    "vmservice_impl.h",
     # Include generated source files.
     "$target_gen_dir/builtin_gen.cc",
     "$target_gen_dir/io_gen.cc",
     "$target_gen_dir/io_patch_gen.cc",
+    "$target_gen_dir/resources_gen.cc",
   ]
 
   include_dirs = [
@@ -189,6 +220,61 @@
                 "scope",
                 [ "io_impl_sources.gypi" ])
 
+
+# A source set for the implementation of 'dart:io' library
+# (without secure sockets) suitable for linking with gen_snapshot.
+source_set("gen_snapshot_dart_io") {
+  configs += ["..:dart_config",]
+
+  # Set custom sources assignment filter. The custom filters does three things:
+  # 1) Filters out unnecessary files pulled in from the gypi files.
+  # 2) Filters out secure socket support.
+  # 3) Enables dart:io by filtering out _unsupported.cc implementations.
+  custom_sources_filter = [
+    "*net/nss_memio.cc",
+    "*net/nss_memio.h",
+    "*secure_socket.cc",
+    "*secure_socket.h",
+    "filter.cc",
+    "*io_service_unsupported.cc",
+    "platform_*.cc",
+    "*io_service.cc",
+    "*io_service.h",
+    "*_test.cc",
+    "*_test.h",
+    "*dbg*",
+    "builtin.cc",
+    "builtin_common.cc",
+    "builtin_gen_snapshot.cc",
+  ]
+  if (!is_mac && !is_ios) {
+    # Dart tree uses *_macos.* instead of *_mac.*
+    custom_sources_filter += [
+      "*_macos.h",
+      "*_macos.cc",
+    ]
+  }
+  set_sources_assignment_filter(custom_sources_filter)
+
+  defines = [ "DART_IO_SECURE_SOCKET_DISABLED" ]
+
+  sources = io_impl_sources_gypi.sources + builtin_impl_sources_gypi.sources
+  sources += [
+    "io_natives.cc",
+    "io_natives.h",
+    "log_android.cc",
+    "log_linux.cc",
+    "log_macos.cc",
+    "log_win.cc",
+    "log.h",
+  ]
+
+  include_dirs = [
+    "..",
+    "//third_party"
+  ]
+}
+
 # A source set for the implementation of 'dart:io' library
 # (without secure sockets).
 source_set("embedded_dart_io") {
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 1777513..78c5a58 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -18,6 +18,8 @@
     'bootstrap_resources_cc_file':
         '<(gen_source_dir)/bootstrap_resources_gen.cc',
     'snapshot_cc_file': '<(gen_source_dir)/snapshot_gen.cc',
+    'observatory_assets_cc_file': '<(gen_source_dir)/observatory_assets.cc',
+    'observatory_assets_tar_file': '<(gen_source_dir)/observatory_assets.tar',
   },
   'targets': [
     {
@@ -137,9 +139,6 @@
         'log_macos.cc',
         'log_win.cc',
       ],
-      'defines': [
-        'LEGACY_DEBUG_PROTOCOL_ENABLED',
-      ],
       'includes': [
         'builtin_impl_sources.gypi',
         '../platform/platform_sources.gypi',
@@ -202,6 +201,7 @@
         'generate_io_patch_cc_file#host',
         'generate_snapshot_file#host',
         'generate_resources_cc_file#host',
+        'generate_observatory_assets_cc_file#host',
       ],
       'sources': [
         'builtin_common.cc',
@@ -221,6 +221,7 @@
         'vmservice_impl.cc',
         'vmservice_impl.h',
         '<(resources_cc_file)',
+        '<(observatory_assets_cc_file)',
       ],
       'sources/': [
         ['exclude', '_test\\.(cc|h)$'],
@@ -373,8 +374,11 @@
       'type': 'executable',
       'toolsets':['host'],
       'dependencies': [
+        'generate_resources_cc_file#host',
+        'generate_observatory_assets_cc_file#host',
         'libdart_nosnapshot',
         'libdart_builtin',
+        'libdart_io',
       ],
       'include_dirs': [
         '..',
@@ -392,13 +396,16 @@
         'platform_macos.cc',
         'platform_win.cc',
         'platform.h',
+        'vmservice_impl.cc',
+        'vmservice_impl.h',
         # Include generated source files.
         '<(builtin_cc_file)',
         '<(io_cc_file)',
         '<(io_patch_cc_file)',
+        '<(resources_cc_file)',
       ],
       'defines': [
-        'PLATFORM_DISABLE_SOCKET'
+        'PLATFORM_DISABLE_SOCKET',
       ],
       'conditions': [
         ['OS=="win"', {
@@ -472,12 +479,41 @@
       ]
     },
     {
-      'target_name': 'generate_resources_cc_file',
+      'target_name': 'generate_observatory_assets_cc_file',
       'type': 'none',
       'toolsets':['host'],
       'dependencies': [
         'build_observatory#host',
       ],
+      'actions': [
+        {
+          'action_name': 'generate_observatory_assets_cc_file',
+          'inputs': [
+            '../tools/create_archive.py',
+            '<(PRODUCT_DIR)/observatory/deployed/web/index.html'
+          ],
+          'outputs': [
+            '<(observatory_assets_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/create_archive.py',
+            '--output', '<(observatory_assets_cc_file)',
+            '--tar_output', '<(observatory_assets_tar_file)',
+            '--outer_namespace', 'dart',
+            '--inner_namespace', 'bin',
+            '--name', 'observatory_assets_archive',
+            '--compress',
+            '--client_root', '<(PRODUCT_DIR)/observatory/deployed/web/',
+          ],
+          'message': 'Generating ''<(observatory_assets_cc_file)'' file.'
+        },
+      ]
+    },
+    {
+      'target_name': 'generate_resources_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
       'includes': [
         'resources_sources.gypi',
       ],
@@ -486,8 +522,6 @@
           'action_name': 'generate_resources_cc',
           'inputs': [
             '../tools/create_resources.py',
-            # The following two files are used to trigger a rebuild.
-            '<(PRODUCT_DIR)/observatory/deployed/web/index.html',
             '<@(_sources)',
           ],
           'outputs': [
@@ -496,13 +530,11 @@
           'action': [
             'python',
             'tools/create_resources.py',
-            '--compress',
             '--output', '<(resources_cc_file)',
             '--outer_namespace', 'dart',
             '--inner_namespace', 'bin',
             '--table_name', 'service_bin',
             '--root_prefix', 'bin/',
-            '--client_root', '<(PRODUCT_DIR)/observatory/deployed/web/',
             '<@(_sources)'
           ],
           'message': 'Generating ''<(resources_cc_file)'' file.'
@@ -552,9 +584,11 @@
         'build_observatory#host',
         'generate_snapshot_file#host',
         'generate_resources_cc_file#host',
+        'generate_observatory_assets_cc_file#host',
       ],
       'include_dirs': [
         '..',
+        '../../third_party/', # Zlib
       ],
       'sources': [
         'main.cc',
@@ -567,6 +601,7 @@
         'vmservice_impl.h',
         '<(snapshot_cc_file)',
         '<(resources_cc_file)',
+        '<(observatory_assets_cc_file)',
       ],
       'conditions': [
         ['OS=="win"', {
@@ -593,6 +628,50 @@
       },
     },
     {
+      # dart binary for running precompiled snapshots without the compiler.
+      'target_name': 'dart_precompiled',
+      'type': 'executable',
+      'dependencies': [
+        'libdart_precompiled',
+        'libdart_builtin',
+        'libdart_io',
+        'build_observatory#host',
+        'generate_resources_cc_file#host',
+        'generate_observatory_assets_cc_file#host',
+      ],
+      'include_dirs': [
+        '..',
+        '../../third_party/', # Zlib
+      ],
+      'sources': [
+        'main.cc',
+        'builtin_common.cc',
+        'builtin_natives.cc',
+        'builtin_nolib.cc',
+        'builtin.h',
+        'io_natives.h',
+        'vmservice_impl.cc',
+        'vmservice_impl.h',
+        'snapshot_empty.cc',
+        '<(resources_cc_file)',
+        '<(observatory_assets_cc_file)',
+      ],
+      'conditions': [
+        ['OS=="win"', {
+          'link_settings': {
+            'libraries': [ '-lws2_32.lib', '-lRpcrt4.lib', '-lwinmm.lib' ],
+          },
+          # Generate an import library on Windows, by exporting a function.
+          # Extensions use this import library to link to the API in dart.exe.
+          'msvs_settings': {
+            'VCLinkerTool': {
+              'AdditionalOptions': [ '/EXPORT:Dart_True' ],
+            },
+          },
+        }],
+      ],
+    },
+    {
       # dart binary built for the host. It does not use a snapshot
       # and does not include Observatory.
       'target_name': 'dart_bootstrap',
@@ -606,6 +685,7 @@
       ],
       'include_dirs': [
         '..',
+        '../../third_party/', # Zlib
       ],
       'sources': [
         'main.cc',
@@ -621,6 +701,7 @@
         '<(io_cc_file)',
         '<(io_patch_cc_file)',
         '<(bootstrap_resources_cc_file)',
+        'observatory_assets_empty.cc',
         'snapshot_empty.cc',
       ],
       'conditions': [
@@ -656,9 +737,11 @@
         'libdart_builtin',
         'libdart_io',
         'generate_resources_cc_file#host',
+        'generate_observatory_assets_cc_file#host',
       ],
       'include_dirs': [
         '..',
+        '../../third_party/', # Zlib
       ],
       'sources': [
         'main.cc',
@@ -674,6 +757,7 @@
         '<(io_cc_file)',
         '<(io_patch_cc_file)',
         '<(resources_cc_file)',
+        '<(observatory_assets_cc_file)',
         'snapshot_empty.cc',
       ],
       'conditions': [
@@ -740,7 +824,6 @@
         '../vm/vm_sources.gypi',
       ],
       'defines': [
-        'LEGACY_DEBUG_PROTOCOL_ENABLED',
         'TESTING',
       ],
       # Only include _test.[cc|h] files.
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index c52f314..021140b 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -27,8 +27,14 @@
 static void LoadPatchFiles(Dart_Handle library,
                            const char* patch_uri,
                            const char** patch_files) {
-  for (intptr_t j = 0; patch_files[j] != NULL; j += 2) {
+  for (intptr_t j = 0; patch_files[j] != NULL; j += 3) {
     Dart_Handle patch_src = DartUtils::ReadStringFromFile(patch_files[j + 1]);
+    if (!Dart_IsString(patch_src)) {
+      // In case reading the file caused an error, use the sources directly.
+      const char* source = patch_files[j + 2];
+      patch_src = Dart_NewStringFromUTF8(
+          reinterpret_cast<const uint8_t*>(source), strlen(source));
+    }
 
     // Prepend the patch library URI to form a unique script URI for the patch.
     intptr_t len = snprintf(NULL, 0, "%s/%s", patch_uri, patch_files[j]);
@@ -69,17 +75,20 @@
   if (source_paths == NULL) {
     return Dart_Null();  // No path mapping information exists for library.
   }
-  const char* source_path = NULL;
-  for (intptr_t i = 0; source_paths[i] != NULL; i += 2) {
+  for (intptr_t i = 0; source_paths[i] != NULL; i += 3) {
     if (!strcmp(uri, source_paths[i])) {
-      source_path = source_paths[i + 1];
-      break;
+      const char* source_path = source_paths[i + 1];
+      Dart_Handle src = DartUtils::ReadStringFromFile(source_path);
+      if (!Dart_IsString(src)) {
+        // In case reading the file caused an error, use the sources directly.
+        const char* source = source_paths[i + 2];
+        src = Dart_NewStringFromUTF8(
+            reinterpret_cast<const uint8_t*>(source), strlen(source));
+      }
+      return src;
     }
   }
-  if (source_path == NULL) {
-    return Dart_Null();  // Uri does not exist in path mapping information.
-  }
-  return DartUtils::ReadStringFromFile(source_path);
+  return Dart_Null();  // Uri does not exist in path mapping information.
 }
 
 
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index d6d945e..f162bcb 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -44,9 +44,9 @@
 Uri _uriBase() {
   // We are not using Dircetory.current here to limit the dependency
   // on dart:io. This code is the same as:
-  //   return new Uri.file(Directory.current.path + "/");
-  var result = _getCurrentDirectoryPath();
-  return new Uri.file("$result/");
+  //   return new Uri.directory(Directory.current.path);
+  var path = _getCurrentDirectoryPath();
+  return new Uri.directory(path);
 }
 
 
@@ -89,12 +89,19 @@
 
 // Packages are either resolved looking up in a map or resolved from within a
 // package root.
-bool _packagesReady() => (_packageRoot != null) || (_packageMap != null);
+bool get _packagesReady =>
+    (_packageRoot != null) || (_packageMap != null) || (_packageError != null);
+// Error string set if there was an error resolving package configuration.
+// For example not finding a .packages file or packages/ directory, malformed
+// .packages file or any other related error.
+String _packageError = null;
 // The directory to look in to resolve "package:" scheme URIs. By detault it is
 // the 'packages' directory right next to the script.
 Uri _packageRoot = null; // Used to be _rootScript.resolve('packages/');
 // The map describing how certain package names are mapped to Uris.
+Uri _packageConfig = null;
 Map<String, Uri> _packageMap = null;
+
 // A list of pending packags which have been requested while resolving the
 // location of the package root or the contents of the package map.
 List<_LoadRequest> _pendingPackageLoads = [];
@@ -109,8 +116,9 @@
 bool _isWindows = false;
 
 // Logging from builtin.dart is prefixed with a '*'.
+String _logId = (Isolate.current.hashCode % 0x100000).toRadixString(16);
 _log(msg) {
-  _print("* $msg");
+  _print("* $_logId $msg");
 }
 
 // A class wrapping the load error message in an Error object.
@@ -234,6 +242,11 @@
     packageRoot = _trimWindowsPath(packageRoot);
     _packageRoot = _workingDirectory.resolveUri(new Uri.file(packageRoot));
   }
+  // Now that we have determined the packageRoot value being used, set it
+  // up for use in Platform.packageRoot. This is only set when the embedder
+  // sets up the package root. Automatically discovered package root will
+  // not update the VMLibraryHooks value.
+  VMLibraryHooks.packageRootString = _packageRoot.toString();
   if (_traceLoading) {
     _log('Package root URI: $_packageRoot');
   }
@@ -243,6 +256,9 @@
 // Given a uri with a 'package' scheme, return a Uri that is prefixed with
 // the package root.
 Uri _resolvePackageUri(Uri uri) {
+  assert(uri.scheme == "package");
+  assert(_packagesReady);
+
   if (!uri.host.isEmpty) {
     var path = '${uri.host}${uri.path}';
     var right = 'package:$path';
@@ -256,7 +272,12 @@
     _log('Resolving package with uri path: ${uri.path}');
   }
   var resolvedUri;
-  if (_packageRoot != null) {
+  if (_packageError != null) {
+    if (_traceLoading) {
+      _log("Resolving package with pending resolution error: $_packageError");
+    }
+    throw _packageError;
+  } else if (_packageRoot != null) {
     resolvedUri = _packageRoot.resolve(uri.path);
   } else {
     var packageName = uri.pathSegments[0];
@@ -396,6 +417,7 @@
 void _handlePackagesReply(msg) {
   // Make sure to close the _packagePort before any other action.
   _packagesPort.close();
+  _packagesPort = null;
 
   if (_traceLoading) {
     _log("Got packages reply: $msg");
@@ -404,22 +426,33 @@
     if (_traceLoading) {
       _log("Got failure response on package port: '$msg'");
     }
-    throw msg;
-  }
-  if (msg.length == 1) {
-    if (_traceLoading) {
-      _log("Received package root: '${msg[0]}'");
+    // Remember the error message.
+    _packageError = msg;
+  } else if (msg is List) {
+    if (msg.length == 1) {
+      if (_traceLoading) {
+        _log("Received package root: '${msg[0]}'");
+      }
+      _packageRoot = Uri.parse(msg[0]);
+    } else {
+      // First entry contains the location of the loaded .packages file.
+      assert((msg.length % 2) == 0);
+      assert(msg.length >= 2);
+      assert(msg[1] == null);
+      _packageConfig = Uri.parse(msg[0]);
+      _packageMap = new Map<String, Uri>();
+      for (var i = 2; i < msg.length; i+=2) {
+        // TODO(iposva): Complain about duplicate entries.
+        _packageMap[msg[i]] = Uri.parse(msg[i+1]);
+      }
+      if (_traceLoading) {
+        _log("Setup package map: $_packageMap");
+      }
     }
-    _packageRoot = Uri.parse(msg[0]);
   } else {
-    assert((msg.length % 2) == 0);
-    _packageMap = new Map<String, Uri>();
-    for (var i = 0; i < msg.length; i+=2) {
-      // TODO(iposva): Complain about duplicate entries.
-      _packageMap[msg[i]] = Uri.parse(msg[i+1]);
-    }
+    _packageError = "Bad type of packages reply: ${msg.runtimeType}";
     if (_traceLoading) {
-      _log("Setup package map: $_packageMap");
+      _log(_packageError);
     }
   }
 
@@ -481,6 +514,8 @@
     // resolve it against the working directory.
     packagesUri = _workingDirectory.resolveUri(packagesUri);
   }
+  var packagesUriStr = packagesUri.toString();
+  VMLibraryHooks.packageConfigString = packagesUriStr;
   if (_traceLoading) {
     _log('Resolved packages map to: $packagesUri');
   }
@@ -495,7 +530,7 @@
   msg[0] = sp;
   msg[1] = _traceLoading;
   msg[2] = -2;
-  msg[3] = packagesUri.toString();
+  msg[3] = packagesUriStr;
   _loadPort.send(msg);
 
   // Signal that the resolution of the packages map has started. But in this
@@ -514,34 +549,6 @@
 }
 
 
-// Embedder Entrypoint:
-// Add mapping from package name to URI.
-void _addPackageMapEntry(String key, String value) {
-  if (!_setupCompleted) {
-    _setupHooks();
-  }
-  if (_traceLoading) {
-    _log("Adding packages map entry: $key -> $value");
-  }
-  if (_packageRoot != null) {
-    if (_traceLoading) {
-      _log("_packageRoot already set: $_packageRoot");
-    }
-    throw "Cannot add package map entry to an exisiting package root.";
-  }
-  if (_packagesPort != null) {
-    if (_traceLoading) {
-      _log("Package map load request already pending.");
-    }
-    throw "Cannot add package map entry during package map resolution.";
-  }
-  if (_packageMap == null) {
-    _packageMap = new Map<String, Uri>();
-  }
-  _packageMap[key] = _workingDirectory.resolve(value);
-}
-
-
 void _asyncLoadError(_LoadRequest req, _LoadError error, StackTrace stack) {
   if (_traceLoading) {
     _log("_asyncLoadError(${req._uri}), error: $error\nstack: $stack");
@@ -582,8 +589,22 @@
 // Loading a package URI needs to first map the package name to a loadable
 // URI.
 _loadPackage(int tag, String uri, Uri resourceUri, context) {
-  if (_packagesReady()) {
-    _loadData(tag, uri, _resolvePackageUri(resourceUri), context);
+  if (_packagesReady) {
+    var resolvedUri;
+    try {
+      resolvedUri = _resolvePackageUri(resourceUri);
+    } catch (e, s) {
+      if (_traceLoading) {
+        _log("Exception ($e) when resolving package URI: $resourceUri");
+      }
+      // Wrap inside a _LoadError unless we are already propagating a previously
+      // seen _LoadError.
+      var error = (e is _LoadError) ? e : new _LoadError(uri, e.toString());
+      // Register a dummy load request and fail to load it.
+      var req = new _LoadRequest(tag, uri, resourceUri, context);
+      _asyncLoadError(req, error, s);
+    }
+    _loadData(tag, uri, resolvedUri, context);
   } else {
     if (_pendingPackageLoads.isEmpty) {
       // Package resolution has not been setup yet, and this is the first
@@ -601,7 +622,7 @@
     });
     if (_traceLoading) {
       _log("Pending package load of '$uri': "
-      "${_pendingPackageLoads.length} pending");
+           "${_pendingPackageLoads.length} pending");
     }
   }
 }
@@ -664,7 +685,7 @@
 
 // Handling of access to the package root or package map from user code.
 _triggerPackageResolution(action) {
-  if (_packagesReady()) {
+  if (_packagesReady) {
     // Packages are ready. Execute the action now.
     action();
   } else {
@@ -679,7 +700,7 @@
 }
 
 
-Future<Uri> _getPackageRoot() {
+Future<Uri> _getPackageRootFuture() {
   if (_traceLoading) {
     _log("Request for package root from user code.");
   }
@@ -691,19 +712,47 @@
 }
 
 
-Future<Map<String, Uri>> _getPackageMap() {
+Future<Uri> _getPackageConfigFuture() {
   if (_traceLoading) {
-    _log("Request for package map from user code.");
+    _log("Request for package config from user code.");
   }
-  var completer = new Completer<Map<String, Uri>>();
+  var completer = new Completer<Uri>();
   _triggerPackageResolution(() {
-    var result = (_packageMap != null) ? new Map.from(_packageMap) : {};
-    completer.complete(result);
+    completer.complete(_packageConfig);
   });
   return completer.future;
 }
 
 
+Future<Uri> _resolvePackageUriFuture(Uri packageUri) async {
+  if (_traceLoading) {
+    _log("Request for package Uri resolution from user code: $packageUri");
+  }
+  if (packageUri.scheme != "package") {
+    if (_traceLoading) {
+      _log("Non-package Uri, returning unmodified: $packageUri");
+    }
+    // Return the incoming parameter if not passed a package: URI.
+    return packageUri;
+  }
+
+  if (!_packagesReady) {
+    if (_traceLoading) {
+      _log("Trigger loading by requesting the package config.");
+    }
+    // Make sure to trigger package resolution.
+    var dummy = await _getPackageConfigFuture();
+  }
+  assert(_packagesReady);
+
+  var result = _resolvePackageUri(packageUri);
+  if (_traceLoading) {
+    _log("Resolved '$packageUri' to '$result'");
+  }
+  return result;
+}
+
+
 // Handling of Resource class by dispatching to the load port.
 Future<List<int>> _resourceReadAsBytes(Uri uri) {
   var completer = new Completer<List<int>>();
@@ -831,6 +880,8 @@
 _setupHooks() {
   _setupCompleted = true;
   VMLibraryHooks.resourceReadAsBytes = _resourceReadAsBytes;
-  VMLibraryHooks.getPackageRoot = _getPackageRoot;
-  VMLibraryHooks.getPackageMap = _getPackageMap;
+
+  VMLibraryHooks.packageRootUriFuture = _getPackageRootFuture;
+  VMLibraryHooks.packageConfigUriFuture = _getPackageConfigFuture;
+  VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture;
 }
diff --git a/runtime/bin/builtin_gen_snapshot.cc b/runtime/bin/builtin_gen_snapshot.cc
index 2852464..c1263bd 100644
--- a/runtime/bin/builtin_gen_snapshot.cc
+++ b/runtime/bin/builtin_gen_snapshot.cc
@@ -9,6 +9,7 @@
 #include "include/dart_api.h"
 
 #include "bin/builtin.h"
+#include "bin/io_natives.h"
 
 namespace dart {
 namespace bin {
@@ -45,7 +46,7 @@
       return reinterpret_cast<Dart_NativeFunction>(entry->function_);
     }
   }
-  return NULL;
+  return IONativeLookup(name, argument_count, auto_setup_scope);
 }
 
 
@@ -57,7 +58,7 @@
       return reinterpret_cast<const uint8_t*>(entry->name_);
     }
   }
-  return NULL;
+  return IONativeSymbol(nf);
 }
 
 
diff --git a/runtime/bin/builtin_impl_sources.gypi b/runtime/bin/builtin_impl_sources.gypi
index 8fcb007..054ec9b 100644
--- a/runtime/bin/builtin_impl_sources.gypi
+++ b/runtime/bin/builtin_impl_sources.gypi
@@ -16,17 +16,6 @@
     'builtin_common.cc',
     'dartutils.cc',
     'dartutils.h',
-    'dbg_connection.cc',
-    'dbg_connection.h',
-    'dbg_connection_android.cc',
-    'dbg_connection_linux.cc',
-    'dbg_connection_linux.h',
-    'dbg_connection_macos.cc',
-    'dbg_connection_macos.h',
-    'dbg_connection_win.cc',
-    'dbg_connection_win.h',
-    'dbg_message.h',
-    'dbg_message.cc',
     'directory.cc',
     'directory.h',
     'directory_android.cc',
diff --git a/runtime/bin/builtin_in.cc b/runtime/bin/builtin_in.cc
index 2f30aad..45b2cbf 100644
--- a/runtime/bin/builtin_in.cc
+++ b/runtime/bin/builtin_in.cc
@@ -9,5 +9,5 @@
 const char* {{VAR_NAME}}[] = {
 {{LIBRARY_SOURCE_MAP}}
 {{PART_SOURCE_MAP}}
-  NULL, NULL
+  NULL, NULL, NULL
 };
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index ad7f6e1..5ba5637 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -13,6 +13,8 @@
 
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
+#include "bin/embedded_dart_io.h"
+#include "bin/file.h"
 #include "bin/io_natives.h"
 #include "bin/platform.h"
 
@@ -79,9 +81,6 @@
 }
 
 
-extern bool capture_stdout;
-
-
 // Implementation of native functions which are used for some
 // test/debug functionality in standalone dart mode.
 void FUNCTION_NAME(Builtin_PrintString)(Dart_NativeArguments args) {
@@ -92,10 +91,11 @@
   if (Dart_IsError(result)) Dart_PropagateError(result);
 
   // Uses fwrite to support printing NUL bytes.
-  fwrite(chars, 1, length, stdout);
+  intptr_t res = fwrite(chars, 1, length, stdout);
+  ASSERT(res == length);
   fputs("\n", stdout);
   fflush(stdout);
-  if (capture_stdout) {
+  if (ShouldCaptureStdout()) {
     // For now we report print output on the Stdout stream.
     uint8_t newline[] = { '\n' };
     Dart_ServiceSendDataEvent("Stdout", "WriteEvent", chars, length);
diff --git a/runtime/bin/common_patch.dart b/runtime/bin/common_patch.dart
index d794cb6..feaf552 100644
--- a/runtime/bin/common_patch.dart
+++ b/runtime/bin/common_patch.dart
@@ -9,4 +9,5 @@
 
 _setupHooks() {
   VMLibraryHooks.eventHandlerSendData = _EventHandler._sendData;
+  VMLibraryHooks.timerMillisecondClock = _EventHandler._timerMillisecondClock;
 }
\ No newline at end of file
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 3c01e64..8915011 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -34,20 +34,20 @@
 namespace bin {
 
 const char* DartUtils::original_working_directory = NULL;
-const char* DartUtils::kDartScheme = "dart:";
-const char* DartUtils::kDartExtensionScheme = "dart-ext:";
-const char* DartUtils::kAsyncLibURL = "dart:async";
-const char* DartUtils::kBuiltinLibURL = "dart:_builtin";
-const char* DartUtils::kCoreLibURL = "dart:core";
-const char* DartUtils::kInternalLibURL = "dart:_internal";
-const char* DartUtils::kIsolateLibURL = "dart:isolate";
-const char* DartUtils::kIOLibURL = "dart:io";
-const char* DartUtils::kIOLibPatchURL = "dart:io-patch";
-const char* DartUtils::kUriLibURL = "dart:uri";
-const char* DartUtils::kHttpScheme = "http:";
-const char* DartUtils::kVMServiceLibURL = "dart:vmservice";
+const char* const DartUtils::kDartScheme = "dart:";
+const char* const DartUtils::kDartExtensionScheme = "dart-ext:";
+const char* const DartUtils::kAsyncLibURL = "dart:async";
+const char* const DartUtils::kBuiltinLibURL = "dart:_builtin";
+const char* const DartUtils::kCoreLibURL = "dart:core";
+const char* const DartUtils::kInternalLibURL = "dart:_internal";
+const char* const DartUtils::kIsolateLibURL = "dart:isolate";
+const char* const DartUtils::kIOLibURL = "dart:io";
+const char* const DartUtils::kIOLibPatchURL = "dart:io-patch";
+const char* const DartUtils::kUriLibURL = "dart:uri";
+const char* const DartUtils::kHttpScheme = "http:";
+const char* const DartUtils::kVMServiceLibURL = "dart:vmservice";
 
-uint8_t DartUtils::magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc };
+const uint8_t DartUtils::magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc };
 
 static bool IsWindowsHost() {
 #if defined(TARGET_OS_WINDOWS)
@@ -284,6 +284,27 @@
 }
 
 
+Dart_Handle DartUtils::MakeUint8Array(const uint8_t* buffer, intptr_t len) {
+  Dart_Handle array = Dart_NewTypedData(Dart_TypedData_kUint8, len);
+  RETURN_IF_ERROR(array);
+  {
+    Dart_TypedData_Type td_type;
+    void* td_data;
+    intptr_t td_len;
+    Dart_Handle result =
+        Dart_TypedDataAcquireData(array, &td_type, &td_data, &td_len);
+    RETURN_IF_ERROR(result);
+    ASSERT(td_type == Dart_TypedData_kUint8);
+    ASSERT(td_len == len);
+    ASSERT(td_data != NULL);
+    memmove(td_data, buffer, td_len);
+    result = Dart_TypedDataReleaseData(array);
+    RETURN_IF_ERROR(result);
+  }
+  return array;
+}
+
+
 Dart_Handle DartUtils::SetWorkingDirectory(Dart_Handle builtin_lib) {
   Dart_Handle directory = NewString(original_working_directory);
   return SingleArgDart_Invoke(builtin_lib, "_setWorkingDirectory", directory);
@@ -587,7 +608,7 @@
   }
 
   if (buffer_copy != NULL) {
-    free(const_cast<uint8_t *>(buffer_copy));
+    free(buffer_copy);
   }
 
   if (Dart_IsError(result)) {
@@ -637,8 +658,7 @@
                                              bool is_service_isolate,
                                              bool trace_loading,
                                              const char* package_root,
-                                             const char** package_map,
-                                             const char* packages_file) {
+                                             const char* packages_config) {
   // Setup the internal library's 'internalPrint' function.
   Dart_Handle print = Dart_Invoke(
       builtin_lib, NewString("_getPrintClosure"), 0, NULL);
@@ -663,7 +683,8 @@
     // Wait for the service isolate to initialize the load port.
     Dart_Port load_port = Dart_ServiceWaitForLoadPort();
     if (load_port == ILLEGAL_PORT) {
-      return NewDartUnsupportedError("Service did not return load port.");
+      return Dart_NewUnhandledExceptionError(
+          NewDartUnsupportedError("Service did not return load port."));
     }
     result = Builtin::SetLoadPort(load_port);
     RETURN_IF_ERROR(result);
@@ -671,8 +692,7 @@
 
   // Set up package root if specified.
   if (package_root != NULL) {
-    ASSERT(package_map == NULL);
-    ASSERT(packages_file == NULL);
+    ASSERT(packages_config == NULL);
     result = NewString(package_root);
     RETURN_IF_ERROR(result);
     const int kNumArgs = 1;
@@ -683,35 +703,8 @@
                          kNumArgs,
                          dart_args);
     RETURN_IF_ERROR(result);
-  } else if (package_map != NULL) {
-    ASSERT(packages_file == NULL);
-    Dart_Handle func_name = NewString("_addPackageMapEntry");
-    RETURN_IF_ERROR(func_name);
-
-    for (int i = 0; package_map[i] != NULL; i +=2) {
-      const int kNumArgs = 2;
-      Dart_Handle dart_args[kNumArgs];
-      // Get the key.
-      result = NewString(package_map[i]);
-      RETURN_IF_ERROR(result);
-      dart_args[0] = result;
-      if (package_map[i + 1] == NULL) {
-        return Dart_NewUnhandledExceptionError(
-            NewDartArgumentError("Adding package map entry without value."));
-      }
-      // Get the value.
-      result = NewString(package_map[i + 1]);
-      RETURN_IF_ERROR(result);
-      dart_args[1] = result;
-      // Setup the next package map entry.
-      result = Dart_Invoke(builtin_lib,
-                           func_name,
-                           kNumArgs,
-                           dart_args);
-      RETURN_IF_ERROR(result);
-    }
-  } else if (packages_file != NULL) {
-    result = NewString(packages_file);
+  } else if (packages_config != NULL) {
+    result = NewString(packages_config);
     RETURN_IF_ERROR(result);
     const int kNumArgs = 1;
     Dart_Handle dart_args[kNumArgs];
@@ -767,8 +760,7 @@
 
 
 Dart_Handle DartUtils::PrepareForScriptLoading(const char* package_root,
-                                               const char** package_map,
-                                               const char* packages_file,
+                                               const char* packages_config,
                                                bool is_service_isolate,
                                                bool trace_loading,
                                                Dart_Handle builtin_lib) {
@@ -802,8 +794,7 @@
                                  is_service_isolate,
                                  trace_loading,
                                  package_root,
-                                 package_map,
-                                 packages_file);
+                                 packages_config);
   RETURN_IF_ERROR(result);
 
   RETURN_IF_ERROR(PrepareAsyncLibrary(async_lib, isolate_lib));
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index d337a10..68ad7ed 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -119,6 +119,7 @@
   static void CloseFile(void* stream);
   static bool EntropySource(uint8_t* buffer, intptr_t length);
   static Dart_Handle ReadStringFromFile(const char* filename);
+  static Dart_Handle MakeUint8Array(const uint8_t* buffer, intptr_t length);
   static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
                                        Dart_Handle library,
                                        Dart_Handle url);
@@ -129,7 +130,6 @@
                                            bool is_service_isolate,
                                            bool trace_loading,
                                            const char* package_root,
-                                           const char** package_map,
                                            const char* packages_file);
   static Dart_Handle PrepareCoreLibrary(Dart_Handle core_lib,
                                  Dart_Handle builtin_lib,
@@ -139,7 +139,6 @@
   static Dart_Handle PrepareIOLibrary(Dart_Handle io_lib);
   static Dart_Handle PrepareIsolateLibrary(Dart_Handle isolate_lib);
   static Dart_Handle PrepareForScriptLoading(const char* package_root,
-                                             const char** package_map,
                                              const char* packages_file,
                                              bool is_service_isolate,
                                              bool trace_loading,
@@ -215,20 +214,20 @@
   // Global state that stores the original working directory..
   static const char* original_working_directory;
 
-  static const char* kDartScheme;
-  static const char* kDartExtensionScheme;
-  static const char* kAsyncLibURL;
-  static const char* kBuiltinLibURL;
-  static const char* kCoreLibURL;
-  static const char* kInternalLibURL;
-  static const char* kIsolateLibURL;
-  static const char* kIOLibURL;
-  static const char* kIOLibPatchURL;
-  static const char* kUriLibURL;
-  static const char* kHttpScheme;
-  static const char* kVMServiceLibURL;
+  static const char* const kDartScheme;
+  static const char* const kDartExtensionScheme;
+  static const char* const kAsyncLibURL;
+  static const char* const kBuiltinLibURL;
+  static const char* const kCoreLibURL;
+  static const char* const kInternalLibURL;
+  static const char* const kIsolateLibURL;
+  static const char* const kIOLibURL;
+  static const char* const kIOLibPatchURL;
+  static const char* const kUriLibURL;
+  static const char* const kHttpScheme;
+  static const char* const kVMServiceLibURL;
 
-  static uint8_t magic_number[];
+  static const uint8_t magic_number[];
 
  private:
   DISALLOW_ALLOCATION();
@@ -580,11 +579,11 @@
 class ScopedBlockingCall {
  public:
   ScopedBlockingCall() {
-    Dart_IsolateBlocked();
+    Dart_ThreadDisableProfiling();
   }
 
   ~ScopedBlockingCall() {
-    Dart_IsolateUnblocked();
+    Dart_ThreadEnableProfiling();
   }
 };
 
diff --git a/runtime/bin/dbg_connection.cc b/runtime/bin/dbg_connection.cc
deleted file mode 100644
index 6bd0cda..0000000
--- a/runtime/bin/dbg_connection.cc
+++ /dev/null
@@ -1,526 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "bin/dbg_connection.h"
-#include "bin/dbg_message.h"
-#include "bin/dartutils.h"
-#include "bin/lockers.h"
-#include "bin/log.h"
-#include "bin/socket.h"
-#include "bin/thread.h"
-#include "bin/utils.h"
-
-#include "platform/globals.h"
-#include "platform/json.h"
-#include "platform/utils.h"
-
-#include "include/dart_api.h"
-
-
-namespace dart {
-namespace bin {
-
-bool trace_debug_protocol = false;
-
-intptr_t DebuggerConnectionHandler::listener_fd_ = -1;
-Monitor* DebuggerConnectionHandler::handler_lock_ = new Monitor();
-
-// TODO(asiva): Remove this once we have support for multiple debugger
-// connections. For now we just store the single debugger connection
-// handler in a static variable.
-static DebuggerConnectionHandler* singleton_handler = NULL;
-
-// The maximum message length to print when --trace_debug_protocol is
-// specified.
-static const int kMaxPrintMessageLen = 1024;
-
-class MessageBuffer {
- public:
-  explicit MessageBuffer(intptr_t fd);
-  ~MessageBuffer();
-  void ReadData();
-  bool IsValidMessage() const;
-  void PopMessage();
-  int MessageId() const;
-  char* buf() const { return buf_; }
-  bool Alive() const { return connection_is_alive_; }
-
- private:
-  static const int kInitialBufferSize = 256;
-  char* buf_;
-  int buf_length_;
-  intptr_t fd_;
-  int data_length_;
-  bool connection_is_alive_;
-
-  DISALLOW_COPY_AND_ASSIGN(MessageBuffer);
-};
-
-
-MessageBuffer::MessageBuffer(intptr_t fd)
-    :  buf_(NULL),
-       buf_length_(0),
-       fd_(fd),
-       data_length_(0),
-       connection_is_alive_(true) {
-  buf_ = reinterpret_cast<char*>(malloc(kInitialBufferSize));
-  if (buf_ == NULL) {
-    FATAL("Failed to allocate message buffer\n");
-  }
-  buf_length_ = kInitialBufferSize;
-  buf_[0] = '\0';
-  data_length_ = 0;
-}
-
-
-MessageBuffer::~MessageBuffer() {
-  free(buf_);
-  buf_ = NULL;
-  fd_ = -1;
-}
-
-
-bool MessageBuffer::IsValidMessage() const {
-  if (data_length_ == 0) {
-    return false;
-  }
-  dart::JSONReader msg_reader(buf_);
-  return msg_reader.EndOfObject() != NULL;
-}
-
-
-int MessageBuffer::MessageId() const {
-  dart::JSONReader r(buf_);
-  r.Seek("id");
-  if (r.Type() == dart::JSONReader::kInteger) {
-    return atoi(r.ValueChars());
-  } else {
-    return -1;
-  }
-}
-
-
-void MessageBuffer::ReadData() {
-  ASSERT(data_length_ >= 0);
-  ASSERT(data_length_ < buf_length_);
-  int max_read = buf_length_ - data_length_ - 1;
-  if (max_read == 0) {
-    // TODO(hausner):
-    // Buffer is full. What should we do if there is no valid message
-    // in the buffer? This might be possible if the client sends a message
-    // that's larger than the buffer, of if the client sends malformed
-    // messages that keep piling up.
-    ASSERT(IsValidMessage());
-    return;
-  }
-  // TODO(hausner): Handle error conditions returned by Read. We may
-  // want to close the debugger connection if we get any errors.
-  int bytes_read =
-      DebuggerConnectionImpl::Receive(fd_, buf_ + data_length_, max_read);
-  if (bytes_read == 0) {
-    connection_is_alive_ = false;
-    return;
-  }
-  ASSERT(bytes_read > 0);
-  data_length_ += bytes_read;
-  ASSERT(data_length_ < buf_length_);
-  buf_[data_length_] = '\0';
-}
-
-
-void MessageBuffer::PopMessage() {
-  dart::JSONReader msg_reader(buf_);
-  const char* end = msg_reader.EndOfObject();
-  if (end != NULL) {
-    ASSERT(*end == '}');
-    end++;
-    data_length_ = 0;
-    while (*end != '\0') {
-      buf_[data_length_] = *end++;
-      data_length_++;
-    }
-    buf_[data_length_] = '\0';
-    ASSERT(data_length_ < buf_length_);
-  }
-}
-
-
-static bool IsValidJSON(const char* msg) {
-  dart::JSONReader r(msg);
-  return r.CheckMessage();
-}
-
-
-DebuggerConnectionHandler::DebuggerConnectionHandler(intptr_t debug_fd)
-    : debug_fd_(debug_fd), msgbuf_(NULL) {
-  msgbuf_ = new MessageBuffer(debug_fd_);
-}
-
-
-DebuggerConnectionHandler::~DebuggerConnectionHandler() {
-  CloseDbgConnection();
-  DebuggerConnectionHandler::RemoveDebuggerConnection(debug_fd_);
-}
-
-
-int DebuggerConnectionHandler::MessageId() {
-  ASSERT(msgbuf_ != NULL);
-  return msgbuf_->MessageId();
-}
-
-
-void DebuggerConnectionHandler::HandleUnknownMsg() {
-  int msg_id = msgbuf_->MessageId();
-  ASSERT(msg_id >= 0);
-  SendError(debug_fd_, msg_id, "unknown debugger command");
-}
-
-
-typedef void (*CommandHandler)(DbgMessage* msg);
-
-struct JSONDebuggerCommand {
-  const char* cmd_string;
-  CommandHandler handler_function;
-};
-
-
-void DebuggerConnectionHandler::HandleMessages() {
-  static JSONDebuggerCommand generic_debugger_commands[] = {
-    { "interrupt", HandleInterruptCmd },
-    { "getIsolateIds", HandleIsolatesListCmd },
-    { NULL, NULL }
-  };
-
-  for (;;) {
-    // Read a message.
-    while (!msgbuf_->IsValidMessage() && msgbuf_->Alive()) {
-      msgbuf_->ReadData();
-    }
-    if (!msgbuf_->Alive()) {
-      if (trace_debug_protocol) {
-        Log::Print("Debugger is exiting HandleMessages loop.\n");
-      }
-      return;
-    }
-
-    if (trace_debug_protocol) {
-      dart::JSONReader r(msgbuf_->buf());
-      const char* msg_end = r.EndOfObject();
-      if (msg_end != NULL) {
-        intptr_t msg_len = msg_end - msgbuf_->buf();
-        int print_len = ((msg_len > kMaxPrintMessageLen)
-                         ? kMaxPrintMessageLen : msg_len);
-        Log::Print("[<<<] Receiving message from debug fd %" Pd ":\n%.*s%s\n",
-                   debug_fd_, print_len, msgbuf_->buf(),
-                   ((msg_len > print_len) ? "..." : ""));
-      }
-    }
-
-    // Parse out the command portion from the message.
-    dart::JSONReader r(msgbuf_->buf());
-    bool found = r.Seek("command");
-    if (r.Error()) {
-      FATAL("Illegal JSON message received");
-    }
-    if (!found) {
-      Log::Print("'command' not found in JSON message: '%s'\n",
-                      msgbuf_->buf());
-      msgbuf_->PopMessage();
-    }
-
-    // Check if this is a generic command (not isolate specific).
-    int i = 0;
-    bool is_handled = false;
-    while (generic_debugger_commands[i].cmd_string != NULL) {
-      if (r.IsStringLiteral(generic_debugger_commands[i].cmd_string)) {
-        DbgMessage* msg = new DbgMessage(i,
-                                         msgbuf_->buf(),
-                                         r.EndOfObject(),
-                                         debug_fd_);
-        (*generic_debugger_commands[i].handler_function)(msg);
-        is_handled = true;
-        msgbuf_->PopMessage();
-        delete msg;
-        break;
-      }
-      i++;
-    }
-    if (!is_handled) {
-      // Check if this is an isolate specific command.
-      int32_t cmd_idx = DbgMsgQueueList::LookupIsolateCommand(r.ValueChars(),
-                                                              r.ValueLen());
-      if (cmd_idx != DbgMsgQueueList::kInvalidCommand) {
-        const char* start = msgbuf_->buf();
-        const char* end = r.EndOfObject();
-        // Get debug message queue corresponding to isolate.
-        MessageParser msg_parser(start, (end - start));
-        Dart_IsolateId isolate_id = msg_parser.GetInt64Param("isolateId");
-        if (!DbgMsgQueueList::AddIsolateMessage(isolate_id,
-                                                cmd_idx,
-                                                msgbuf_->buf(),
-                                                r.EndOfObject(),
-                                                debug_fd_)) {
-          SendError(debug_fd_, MessageId(), "Invalid isolate specified");
-        }
-        msgbuf_->PopMessage();
-        continue;
-      }
-
-      // This is an unrecognized command, report error and move on to next.
-      Log::Print("unrecognized command received: '%s'\n", msgbuf_->buf());
-      HandleUnknownMsg();
-      msgbuf_->PopMessage();
-    }
-  }
-}
-
-
-void DebuggerConnectionHandler::SendError(intptr_t debug_fd,
-                                          int msg_id,
-                                          const char* err_msg) {
-  dart::TextBuffer msg(64);
-  msg.Printf("{\"id\": %d, \"error\": \"Error: ", msg_id);
-  msg.AddEscapedString(err_msg);
-  msg.Printf("\"}");
-  SendMsg(debug_fd, &msg);
-}
-
-
-void DebuggerConnectionHandler::CloseDbgConnection() {
-  if (debug_fd_ >= 0) {
-    Socket::Close(debug_fd_);
-  }
-  if (msgbuf_ != NULL) {
-    delete msgbuf_;
-    msgbuf_ = NULL;
-  }
-  // TODO(hausner): Need to tell the VM debugger object to remove all
-  // breakpoints.
-}
-
-
-// The vm service relies on certain debugger functionality.
-void DebuggerConnectionHandler::InitForVmService() {
-  MonitorLocker ml(handler_lock_);
-  DbgMsgQueueList::Initialize();
-}
-
-
-int DebuggerConnectionHandler::StartHandler(const char* address,
-                                            int port_number) {
-  ASSERT(handler_lock_ != NULL);
-  MonitorLocker ml(handler_lock_);
-  if (IsListening()) {
-    // The debugger connection handler was already started.
-    return Socket::GetPort(listener_fd_);
-  }
-
-  // First setup breakpoint, exception and delayed breakpoint handlers.
-  DbgMsgQueueList::Initialize();
-
-  // Initialize the socket implementation.
-  if (!Socket::Initialize()) {
-    FATAL("Failed initializing socket implementation.");
-  }
-
-  // Now setup a listener socket and start a thread which will
-  // listen, accept connections from debuggers, read and handle/dispatch
-  // debugger commands received on these connections.
-  ASSERT(listener_fd_ == -1);
-  OSError *os_error;
-  AddressList<SocketAddress>* addresses =
-      Socket::LookupAddress(address, -1, &os_error);
-  RawAddr addr = addresses->GetAt(0)->addr();
-  SocketAddress::SetAddrPort(&addr, port_number);
-  listener_fd_ = ServerSocket::CreateBindListen(addr, 1);
-  delete addresses;
-  if (listener_fd_ < 0) {
-    fprintf(stderr, "%s", "Could not initialize debug socket\n");
-    fflush(stderr);
-    exit(255);
-  }
-
-  port_number = Socket::GetPort(listener_fd_);
-  DebuggerConnectionImpl::StartHandler(port_number);
-  return port_number;
-}
-
-
-void DebuggerConnectionHandler::StopHandler() {
-  if (IsConnected()) {
-    DebuggerConnectionImpl::StopHandler(singleton_handler->debug_fd());
-  }
-}
-
-
-void DebuggerConnectionHandler::WaitForConnection() {
-  ASSERT(handler_lock_ != NULL);
-  MonitorLocker ml(handler_lock_);
-  if (!IsListening()) {
-    // If we are only running the vm service, don't wait for
-    // connections.
-    return;
-  }
-  while (!IsConnected()) {
-    Monitor::WaitResult res = ml.Wait();
-    ASSERT(res == Monitor::kNotified);
-  }
-}
-
-
-void DebuggerConnectionHandler::SendMsg(intptr_t debug_fd,
-                                        dart::TextBuffer* msg) {
-  ASSERT(handler_lock_ != NULL);
-  MonitorLocker ml(handler_lock_);
-  SendMsgHelper(debug_fd, msg);
-}
-
-
-void DebuggerConnectionHandler::BroadcastMsg(dart::TextBuffer* msg) {
-  ASSERT(handler_lock_ != NULL);
-  MonitorLocker ml(handler_lock_);
-  if (!IsListening()) {
-    // If we are only running the vm service, don't try to broadcast
-    // to debugger clients.
-    return;
-  }
-  // TODO(asiva): Once we support connection to multiple debuggers
-  // we need to send the message to all of them.
-  ASSERT(singleton_handler != NULL);
-  SendMsgHelper(singleton_handler->debug_fd(), msg);
-}
-
-
-void DebuggerConnectionHandler::SendMsgHelper(intptr_t debug_fd,
-                                              dart::TextBuffer* msg) {
-  ASSERT(debug_fd >= 0);
-  ASSERT(IsValidJSON(msg->buf()));
-
-  if (trace_debug_protocol) {
-    int print_len = ((msg->length() > kMaxPrintMessageLen)
-                     ? kMaxPrintMessageLen : msg->length());
-    Log::Print("[>>>] Sending message to debug fd %" Pd ":\n%.*s%s\n",
-               debug_fd, print_len, msg->buf(),
-               ((msg->length() > print_len) ? "..." : ""));
-  }
-
-  // Sending messages in short pieces can be used to stress test the
-  // debugger front-end's message handling code.
-  const bool send_in_pieces = false;
-  if (send_in_pieces) {
-    intptr_t remaining = msg->length();
-    intptr_t sent = 0;
-    const intptr_t max_piece_len = 122;  // Pretty arbitrary, not a power of 2.
-    Monitor sleep;
-    while (remaining > 0) {
-      intptr_t piece_len = remaining;
-      if (piece_len > max_piece_len) {
-        piece_len = max_piece_len;
-      }
-      intptr_t written =
-          DebuggerConnectionImpl::Send(debug_fd, msg->buf() + sent, piece_len);
-      ASSERT(written == piece_len);
-      sent += written;
-      remaining -= written;
-      // Wait briefly so the OS does not coalesce message fragments.
-      {
-        MonitorLocker ml(&sleep);
-        ml.Wait(10);
-      }
-    }
-    return;
-  }
-  intptr_t bytes_written =
-      DebuggerConnectionImpl::Send(debug_fd, msg->buf(), msg->length());
-  ASSERT(msg->length() == bytes_written);
-  // TODO(hausner): Error checking. Probably just shut down the debugger
-  // session if we there is an error while writing.
-}
-
-
-void DebuggerConnectionHandler::AcceptDbgConnection(intptr_t debug_fd) {
-  Socket::SetNoDelay(debug_fd, true);
-  AddNewDebuggerConnection(debug_fd);
-  {
-    ASSERT(handler_lock_ != NULL);
-    MonitorLocker ml(handler_lock_);
-    ml.NotifyAll();
-  }
-  // TODO(asiva): Once we implement support for multiple connections
-  // we should have a different callback for wakeups on fds which
-  // are not the listener_fd_.
-  // In that callback we would lookup the handler object
-  // corresponding to that fd and invoke HandleMessages on it.
-  // For now we run that code here.
-  DebuggerConnectionHandler* handler = GetDebuggerConnectionHandler(debug_fd);
-  if (handler != NULL) {
-    handler->HandleMessages();
-    delete handler;
-  }
-}
-
-
-void DebuggerConnectionHandler::HandleInterruptCmd(DbgMessage* in_msg) {
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  Dart_IsolateId isolate_id = msg_parser.GetInt64Param("isolateId");
-  if (isolate_id == ILLEGAL_ISOLATE_ID || Dart_GetIsolate(isolate_id) == NULL) {
-    in_msg->SendErrorReply(msg_id, "Invalid isolate specified");
-    return;
-  }
-  if (!DbgMsgQueueList::InterruptIsolate(isolate_id)) {
-    in_msg->SendErrorReply(msg_id, "Invalid isolate specified");
-    return;
-  }
-  dart::TextBuffer msg(64);
-  msg.Printf("{ \"id\": %d }", msg_id);
-  in_msg->SendReply(&msg);
-}
-
-
-void DebuggerConnectionHandler::HandleIsolatesListCmd(DbgMessage* in_msg) {
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  ASSERT(msg_id >= 0);
-  dart::TextBuffer msg(64);
-  msg.Printf("{ \"id\": %d, \"result\": { \"isolateIds\": [", msg_id);
-  DbgMsgQueueList::ListIsolateIds(&msg);
-  msg.Printf("]}}");
-  in_msg->SendReply(&msg);
-}
-
-
-void DebuggerConnectionHandler::AddNewDebuggerConnection(intptr_t debug_fd) {
-  // TODO(asiva): Support multiple debugger connections, for now we just
-  // create one handler, store it in a static variable and use it.
-  ASSERT(singleton_handler == NULL);
-  singleton_handler = new DebuggerConnectionHandler(debug_fd);
-}
-
-
-void DebuggerConnectionHandler::RemoveDebuggerConnection(intptr_t debug_fd) {
-  // TODO(asiva): Support multiple debugger connections, for now we just
-  // set the static handler back to NULL.
-  ASSERT(singleton_handler != NULL);
-  singleton_handler = NULL;
-}
-
-
-DebuggerConnectionHandler*
-DebuggerConnectionHandler::GetDebuggerConnectionHandler(intptr_t debug_fd) {
-  // TODO(asiva): Support multiple debugger connections, for now we just
-  // return the one static handler that was created.
-  ASSERT(singleton_handler != NULL);
-  return singleton_handler;
-}
-
-
-bool DebuggerConnectionHandler::IsConnected() {
-  // TODO(asiva): Support multiple debugger connections.
-  // Return true if a connection has been established.
-  return singleton_handler != NULL;
-}
-
-}  // namespace bin
-}  // namespace dart
diff --git a/runtime/bin/dbg_connection.h b/runtime/bin/dbg_connection.h
deleted file mode 100644
index 577c30a..0000000
--- a/runtime/bin/dbg_connection.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef BIN_DBG_CONNECTION_H_
-#define BIN_DBG_CONNECTION_H_
-
-#include "bin/builtin.h"
-#include "bin/utils.h"
-
-#include "include/dart_tools_api.h"
-
-#include "platform/globals.h"
-#include "platform/json.h"
-#include "bin/thread.h"
-// Declare the OS-specific types ahead of defining the generic class.
-#if defined(TARGET_OS_ANDROID)
-#include "bin/dbg_connection_android.h"
-#elif defined(TARGET_OS_LINUX)
-#include "bin/dbg_connection_linux.h"
-#elif defined(TARGET_OS_MACOS)
-#include "bin/dbg_connection_macos.h"
-#elif defined(TARGET_OS_WINDOWS)
-#include "bin/dbg_connection_win.h"
-#else
-#error Unknown target os.
-#endif
-
-
-namespace dart {
-namespace bin {
-
-// Forward declarations.
-class DbgMessage;
-class MessageBuffer;
-
-
-class DebuggerConnectionHandler {
- public:
-  explicit DebuggerConnectionHandler(intptr_t debug_fd);
-  ~DebuggerConnectionHandler();
-
-  // Accessors.
-  intptr_t debug_fd() const { return debug_fd_; }
-
-  // Return message id of current debug command message.
-  int MessageId();
-
-  // Starts the native thread which listens for connections from
-  // debugger clients, reads and dispatches debug command messages
-  // from the client.
-  static int StartHandler(const char* address, int port_number);
-
-  // Stops the native thread.
-  static void StopHandler();
-
-  // Initializes the parts of the debugger which are needed by the vm
-  // service.  This function should only be called when StartHandler
-  // is not called.
-  static void InitForVmService();
-
-  // Called by Isolates when they need to wait for a connection
-  // from debugger clients.
-  static void WaitForConnection();
-
-  // Sends a reply or an error message to a specific debugger client.
-  static void SendMsg(intptr_t debug_fd, dart::TextBuffer* msg);
-  static void SendError(intptr_t debug_fd, int msg_id, const char* err_msg);
-
-  // Sends an event message to all debugger clients that are connected.
-  static void BroadcastMsg(dart::TextBuffer* msg);
-
- private:
-  void HandleUnknownMsg();
-  void HandleMessages();
-
-  void CloseDbgConnection();
-
-  // The socket that connects with the debugger client.
-  // The descriptor is created and closed by the debugger connection thread.
-  intptr_t debug_fd_;
-
-  // Buffer holding the messages received over the wire from the debugger
-  // front end..
-  MessageBuffer* msgbuf_;
-
-  // Accepts connection requests from debugger client and sets up a
-  // connection handler object to read and handle messages from the client.
-  static void AcceptDbgConnection(intptr_t debug_fd);
-
-  // Handlers for generic debug command messages which are not specific to
-  // an isolate.
-  static void HandleInterruptCmd(DbgMessage* msg);
-  static void HandleIsolatesListCmd(DbgMessage* msg);
-
-  // Helper methods to manage debugger client connections.
-  static void AddNewDebuggerConnection(intptr_t debug_fd);
-  static void RemoveDebuggerConnection(intptr_t debug_fd);
-  static DebuggerConnectionHandler* GetDebuggerConnectionHandler(
-                                       intptr_t debug_fd);
-  static bool IsConnected();
-
-  // Helper method for sending messages back to a debugger client.
-  static void SendMsgHelper(intptr_t debug_fd, dart::TextBuffer* msg);
-
-  // mutex/condition variable used by isolates when writing back to the
-  // debugger. This is also used to ensure that the isolate waits for
-  // a debugger to be attached when that is requested on the command line.
-  static Monitor* handler_lock_;
-
-  static bool IsListening() {
-    return listener_fd_ != -1;
-  }
-
-  // The socket that is listening for incoming debugger connections.
-  // This descriptor is created and closed by a native thread.
-  static intptr_t listener_fd_;
-
-  friend class DebuggerConnectionImpl;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(DebuggerConnectionHandler);
-};
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // BIN_DBG_CONNECTION_H_
diff --git a/runtime/bin/dbg_connection_android.cc b/runtime/bin/dbg_connection_android.cc
deleted file mode 100644
index 77c7a20..0000000
--- a/runtime/bin/dbg_connection_android.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/globals.h"
-#if defined(TARGET_OS_ANDROID)
-
-#include <errno.h>  // NOLINT
-#include <stdio.h>  // NOLINT
-#include <stdlib.h>  // NOLINT
-#include <sys/epoll.h>  // NOLINT
-
-#include "bin/dbg_connection.h"
-#include "bin/fdutils.h"
-#include "bin/log.h"
-#include "bin/socket.h"
-
-#include "platform/signal_blocker.h"
-
-
-namespace dart {
-namespace bin {
-
-intptr_t DebuggerConnectionImpl::epoll_fd_ = -1;
-int DebuggerConnectionImpl::wakeup_fds_[2] = {-1, -1};
-
-
-void DebuggerConnectionImpl::HandleEvent(struct epoll_event* event) {
-  if (event->data.fd == DebuggerConnectionHandler::listener_fd_) {
-    if (DebuggerConnectionHandler::IsConnected()) {
-      FATAL("Cannot connect to more than one debugger.\n");
-    }
-    intptr_t fd = ServerSocket::Accept(event->data.fd);
-    if (fd < 0) {
-      FATAL("Accepting new debugger connection failed.\n");
-    }
-    FDUtils::SetBlocking(fd);
-    DebuggerConnectionHandler::AcceptDbgConnection(fd);
-    // TODO(hausner): add the debugger wire socket fd to the event poll queue
-    // once we poll the debugger connection.
-  } else if (event->data.fd == wakeup_fds_[0]) {
-    // Sync message. Not yet implemented.
-    UNIMPLEMENTED();
-  } else {
-    Log::Print("unexpected: receiving debugger connection event.\n");
-    UNIMPLEMENTED();
-  }
-}
-
-
-void DebuggerConnectionImpl::Handler(uword args) {
-  static const int kMaxEvents = 4;
-  struct epoll_event events[kMaxEvents];
-  while (1) {
-    const int no_timeout = -1;
-    intptr_t result = TEMP_FAILURE_RETRY(
-        epoll_wait(epoll_fd_, events, kMaxEvents, no_timeout));
-    ASSERT(EAGAIN == EWOULDBLOCK);
-    if (result == -1) {
-      if (errno != EWOULDBLOCK) {
-        perror("epoll_wait failed");
-      }
-    } else {
-      ASSERT(result <= kMaxEvents);
-      for (int i = 0; i < result; i++) {
-        HandleEvent(&events[i]);
-      }
-    }
-  }
-}
-
-
-void DebuggerConnectionImpl::SetupPollQueue() {
-  int result = NO_RETRY_EXPECTED(pipe(wakeup_fds_));
-  if (result != 0) {
-    FATAL1("Pipe creation failed with error %d\n", result);
-  }
-  FDUtils::SetNonBlocking(wakeup_fds_[0]);
-
-  static const int kEpollInitialSize = 16;
-  epoll_fd_ = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize));
-  if (epoll_fd_ == -1) {
-    FATAL("Failed creating epoll file descriptor");
-  }
-
-  // Register the wakeup _fd with the epoll instance.
-  struct epoll_event event;
-  event.events = EPOLLIN;
-  event.data.fd = wakeup_fds_[0];
-  int status = NO_RETRY_EXPECTED(epoll_ctl(
-                   epoll_fd_, EPOLL_CTL_ADD, wakeup_fds_[0], &event));
-  if (status == -1) {
-    FATAL("Failed adding wakeup fd to epoll instance");
-  }
-
-  // Register the listener_fd with the epoll instance.
-  event.events = EPOLLIN;
-  event.data.fd = DebuggerConnectionHandler::listener_fd_;
-  status = NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD,
-               DebuggerConnectionHandler::listener_fd_, &event));
-  if (status == -1) {
-    FATAL("Failed adding listener fd to epoll instance");
-  }
-}
-
-
-void DebuggerConnectionImpl::StartHandler(int port_number) {
-  ASSERT(DebuggerConnectionHandler::listener_fd_ != -1);
-  SetupPollQueue();
-  int result = Thread::Start(&DebuggerConnectionImpl::Handler, 0);
-  if (result != 0) {
-    FATAL1("Failed to start debugger connection handler thread: %d\n", result);
-  }
-}
-
-
-intptr_t DebuggerConnectionImpl::Send(intptr_t socket,
-                                      const char* buf,
-                                      int len) {
-  return TEMP_FAILURE_RETRY(write(socket, buf, len));
-}
-
-
-intptr_t DebuggerConnectionImpl::Receive(intptr_t socket, char* buf, int len) {
-  return TEMP_FAILURE_RETRY(read(socket, buf, len));
-}
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/dbg_connection_android.h b/runtime/bin/dbg_connection_android.h
deleted file mode 100644
index 8975294..0000000
--- a/runtime/bin/dbg_connection_android.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef BIN_DBG_CONNECTION_ANDROID_H_
-#define BIN_DBG_CONNECTION_ANDROID_H_
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/socket.h>
-
-
-namespace dart {
-namespace bin {
-
-class DebuggerConnectionImpl {
- public:
-  static void StartHandler(int port_number);
-  static void StopHandler(intptr_t debug_fd) {}
-  static intptr_t Send(intptr_t socket, const char* buf, int len);
-  static intptr_t Receive(intptr_t socket, char* buf, int len);
-
- private:
-  static void SetupPollQueue();
-  static void HandleEvent(struct epoll_event* event);
-  static void Handler(uword args);
-
-  // File descriptors for pipes used to communicate with the debugger thread.
-  static int wakeup_fds_[2];
-
-  // File descriptor for the polling queue.
-  static intptr_t epoll_fd_;
-};
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // BIN_DBG_CONNECTION_ANDROID_H_
diff --git a/runtime/bin/dbg_connection_linux.cc b/runtime/bin/dbg_connection_linux.cc
deleted file mode 100644
index a55557d..0000000
--- a/runtime/bin/dbg_connection_linux.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/globals.h"
-#if defined(TARGET_OS_LINUX)
-
-#include <errno.h>  // NOLINT
-#include <stdio.h>  // NOLINT
-#include <stdlib.h>  // NOLINT
-#include <sys/epoll.h>  // NOLINT
-
-#include "platform/signal_blocker.h"
-#include "bin/dbg_connection.h"
-#include "bin/fdutils.h"
-#include "bin/log.h"
-#include "bin/socket.h"
-
-
-namespace dart {
-namespace bin {
-
-int DebuggerConnectionImpl::epoll_fd_ = -1;
-int DebuggerConnectionImpl::wakeup_fds_[2] = {-1, -1};
-
-
-void DebuggerConnectionImpl::HandleEvent(struct epoll_event* event) {
-  if (event->data.fd == DebuggerConnectionHandler::listener_fd_) {
-    if (DebuggerConnectionHandler::IsConnected()) {
-      FATAL("Cannot connect to more than one debugger.\n");
-    }
-    intptr_t fd = ServerSocket::Accept(event->data.fd);
-    if (fd < 0) {
-      FATAL("Accepting new debugger connection failed.\n");
-    }
-    FDUtils::SetBlocking(fd);
-    DebuggerConnectionHandler::AcceptDbgConnection(fd);
-    // TODO(hausner): add the debugger wire socket fd to the event poll queue
-    // once we poll the debugger connection.
-  } else if (event->data.fd == wakeup_fds_[0]) {
-    // Sync message. Not yet implemented.
-    UNIMPLEMENTED();
-  } else {
-    Log::Print("unexpected: receiving debugger connection event.\n");
-    UNIMPLEMENTED();
-  }
-}
-
-
-void DebuggerConnectionImpl::Handler(uword args) {
-  static const int kMaxEvents = 4;
-  struct epoll_event events[kMaxEvents];
-  while (1) {
-    const int no_timeout = -1;
-    intptr_t result = TEMP_FAILURE_RETRY(
-        epoll_wait(epoll_fd_, events, kMaxEvents, no_timeout));
-    ASSERT(EAGAIN == EWOULDBLOCK);
-    if (result == -1) {
-      if (errno != EWOULDBLOCK) {
-        perror("epoll_wait failed");
-      }
-    } else {
-      ASSERT(result <= kMaxEvents);
-      for (int i = 0; i < result; i++) {
-        HandleEvent(&events[i]);
-      }
-    }
-  }
-}
-
-
-void DebuggerConnectionImpl::SetupPollQueue() {
-  int result = NO_RETRY_EXPECTED(pipe(wakeup_fds_));
-  if (result != 0) {
-    FATAL1("Pipe creation failed with error %d\n", result);
-  }
-  FDUtils::SetNonBlocking(wakeup_fds_[0]);
-
-  static const int kEpollInitialSize = 16;
-  epoll_fd_ = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize));
-  if (epoll_fd_ == -1) {
-    FATAL("Failed creating epoll file descriptor");
-  }
-
-  // Register the wakeup _fd with the epoll instance.
-  struct epoll_event event;
-  event.events = EPOLLIN;
-  event.data.fd = wakeup_fds_[0];
-  int status = NO_RETRY_EXPECTED(epoll_ctl(
-      epoll_fd_, EPOLL_CTL_ADD, wakeup_fds_[0], &event));
-  if (status == -1) {
-    FATAL("Failed adding wakeup fd to epoll instance");
-  }
-
-  // Register the listener_fd with the epoll instance.
-  event.events = EPOLLIN;
-  event.data.fd = DebuggerConnectionHandler::listener_fd_;
-  status = NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD,
-      DebuggerConnectionHandler::listener_fd_, &event));
-  if (status == -1) {
-    FATAL("Failed adding listener fd to epoll instance");
-  }
-}
-
-
-void DebuggerConnectionImpl::StartHandler(int port_number) {
-  ASSERT(DebuggerConnectionHandler::listener_fd_ != -1);
-  SetupPollQueue();
-  int result = Thread::Start(&DebuggerConnectionImpl::Handler, 0);
-  if (result != 0) {
-    FATAL1("Failed to start debugger connection handler thread: %d\n", result);
-  }
-}
-
-
-intptr_t DebuggerConnectionImpl::Send(intptr_t socket,
-                                      const char* buf,
-                                      int len) {
-  return TEMP_FAILURE_RETRY(write(socket, buf, len));
-}
-
-
-intptr_t DebuggerConnectionImpl::Receive(intptr_t socket, char* buf, int len) {
-  return TEMP_FAILURE_RETRY(read(socket, buf, len));
-}
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/dbg_connection_linux.h b/runtime/bin/dbg_connection_linux.h
deleted file mode 100644
index fcbd16e..0000000
--- a/runtime/bin/dbg_connection_linux.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef BIN_DBG_CONNECTION_LINUX_H_
-#define BIN_DBG_CONNECTION_LINUX_H_
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/socket.h>
-
-
-namespace dart {
-namespace bin {
-
-class DebuggerConnectionImpl {
- public:
-  static void StartHandler(int port_number);
-  static void StopHandler(intptr_t debug_fd) {}
-  static intptr_t Send(intptr_t socket, const char* buf, int len);
-  static intptr_t Receive(intptr_t socket, char* buf, int len);
-
- private:
-  static void SetupPollQueue();
-  static void HandleEvent(struct epoll_event* event);
-  static void Handler(uword args);
-
-  // File descriptors for pipes used to communicate with the debugger thread.
-  static int wakeup_fds_[2];
-
-  // File descriptor for the polling queue.
-  static int epoll_fd_;
-};
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // BIN_DBG_CONNECTION_LINUX_H_
diff --git a/runtime/bin/dbg_connection_macos.cc b/runtime/bin/dbg_connection_macos.cc
deleted file mode 100644
index 4da21cd..0000000
--- a/runtime/bin/dbg_connection_macos.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/globals.h"
-#if defined(TARGET_OS_MACOS)
-
-#include <errno.h>  // NOLINT
-#include <stdio.h>  // NOLINT
-#include <stdlib.h>  // NOLINT
-#include <string.h>  // NOLINT
-#include <sys/event.h>  // NOLINT
-#include <unistd.h>  // NOLINT
-
-#include "bin/dartutils.h"
-#include "bin/dbg_connection.h"
-#include "bin/fdutils.h"
-#include "bin/log.h"
-#include "bin/socket.h"
-#include "platform/signal_blocker.h"
-#include "platform/utils.h"
-
-
-namespace dart {
-namespace bin {
-
-#define INVALID_FD -1
-
-int DebuggerConnectionImpl::kqueue_fd_ = INVALID_FD;
-int DebuggerConnectionImpl::wakeup_fds_[2] = {INVALID_FD, INVALID_FD};
-
-
-// Used by VM threads to send a message to the debugger connetion
-// handler thread.
-void DebuggerConnectionImpl::SendMessage(MessageType id) {
-  ASSERT(wakeup_fds_[1] != INVALID_FD);
-  struct Message msg;
-  msg.msg_id = id;
-  int result = FDUtils::WriteToBlocking(wakeup_fds_[1], &msg, sizeof(msg));
-  if (result != sizeof(msg)) {
-    if (result == -1) {
-      perror("Wakeup message failure: ");
-    }
-    FATAL1("Wakeup message failure. Wrote %d bytes.", result);
-  }
-}
-
-
-// Used by the debugger connection handler to read the messages sent
-// by the VM.
-bool DebuggerConnectionImpl::ReceiveMessage(Message* msg) {
-  int total_read = 0;
-  int bytes_read = 0;
-  int remaining = sizeof(Message);
-  uint8_t* buf = reinterpret_cast<uint8_t*>(msg);
-  while (remaining > 0) {
-    bytes_read =
-        TEMP_FAILURE_RETRY(read(wakeup_fds_[0], buf + total_read, remaining));
-    if ((bytes_read < 0) && (total_read == 0)) {
-      return false;
-    }
-    if (bytes_read > 0) {
-      total_read += bytes_read;
-      remaining -= bytes_read;
-    }
-  }
-  ASSERT(remaining >= 0);
-  return remaining == 0;
-}
-
-
-void DebuggerConnectionImpl::HandleEvent(struct kevent* event) {
-  intptr_t ident = event->ident;
-  if (ident == DebuggerConnectionHandler::listener_fd_) {
-    if (DebuggerConnectionHandler::IsConnected()) {
-      FATAL("Cannot connect to more than one debugger.\n");
-    }
-    intptr_t fd = ServerSocket::Accept(ident);
-    if (fd < 0) {
-      FATAL("Accepting new debugger connection failed.\n");
-    }
-    FDUtils::SetBlocking(fd);
-    DebuggerConnectionHandler::AcceptDbgConnection(fd);
-
-    /* For now, don't poll the debugger connection.
-    struct kevent ev_add;
-    EV_SET(&ev_add, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
-    int status =
-        TEMP_FAILURE_RETRY(kevent(kqueue_fd_, &ev_add, 1, NULL, 0, NULL));
-    if (status == -1) {
-      const int kBufferSize = 1024;
-      char error_message[kBufferSize];
-      strerror_r(errno, error_message, kBufferSize);
-      FATAL1("Failed adding debugger socket to kqueue: %s\n", error_message);
-    }
-    */
-  } else if (ident == wakeup_fds_[0]) {
-    Message msg;
-    if (ReceiveMessage(&msg)) {
-      Log::Print("Received sync message id %d.\n", msg.msg_id);
-    }
-  } else {
-    Log::Print("unexpected: receiving debugger connection event.\n");
-    UNIMPLEMENTED();
-  }
-}
-
-
-void DebuggerConnectionImpl::Handler(uword args) {
-  static const int kMaxEvents = 4;
-  struct kevent events[kMaxEvents];
-
-  while (1) {
-    // Wait indefinitely for an event.
-    int result = TEMP_FAILURE_RETRY(
-        kevent(kqueue_fd_, NULL, 0, events, kMaxEvents, NULL));
-    if (result == -1) {
-      const int kBufferSize = 1024;
-      char error_message[kBufferSize];
-      strerror_r(errno, error_message, kBufferSize);
-      FATAL1("kevent failed %s\n", error_message);
-    } else {
-      ASSERT(result <= kMaxEvents);
-      for (int i = 0; i < result; i++) {
-        HandleEvent(&events[i]);
-      }
-    }
-  }
-  Log::Print("shutting down debugger thread\n");
-}
-
-
-void DebuggerConnectionImpl::SetupPollQueue() {
-  int result;
-  result = NO_RETRY_EXPECTED(pipe(wakeup_fds_));
-  if (result != 0) {
-    FATAL1("Pipe creation failed with error %d\n", result);
-  }
-  FDUtils::SetNonBlocking(wakeup_fds_[0]);
-
-  kqueue_fd_ = NO_RETRY_EXPECTED(kqueue());
-  if (kqueue_fd_ == -1) {
-    FATAL("Failed creating kqueue\n");
-  }
-  // Register the wakeup_fd_ with the kqueue.
-  struct kevent event;
-  EV_SET(&event, wakeup_fds_[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
-  int status = NO_RETRY_EXPECTED(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL));
-  if (status == -1) {
-    const int kBufferSize = 1024;
-    char error_message[kBufferSize];
-    strerror_r(errno, error_message, kBufferSize);
-    FATAL1("Failed adding wakeup pipe fd to kqueue: %s\n", error_message);
-  }
-
-  // Register the listening socket.
-  EV_SET(&event, DebuggerConnectionHandler::listener_fd_,
-         EVFILT_READ, EV_ADD, 0, 0, NULL);
-  status = NO_RETRY_EXPECTED(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL));
-  if (status == -1) {
-    const int kBufferSize = 1024;
-    char error_message[kBufferSize];
-    strerror_r(errno, error_message, kBufferSize);
-    FATAL1("Failed adding listener socket to kqueue: %s\n", error_message);
-  }
-}
-
-
-void DebuggerConnectionImpl::StartHandler(int port_number) {
-  ASSERT(DebuggerConnectionHandler::listener_fd_ != -1);
-  SetupPollQueue();
-  int result = Thread::Start(&DebuggerConnectionImpl::Handler, 0);
-  if (result != 0) {
-    FATAL1("Failed to start debugger connection handler thread: %d\n", result);
-  }
-}
-
-
-intptr_t DebuggerConnectionImpl::Send(intptr_t socket,
-                                      const char* buf,
-                                      int len) {
-  return TEMP_FAILURE_RETRY(write(socket, buf, len));
-}
-
-
-intptr_t DebuggerConnectionImpl::Receive(intptr_t socket, char* buf, int len) {
-  return TEMP_FAILURE_RETRY(read(socket, buf, len));
-}
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/dbg_connection_macos.h b/runtime/bin/dbg_connection_macos.h
deleted file mode 100644
index 064238e..0000000
--- a/runtime/bin/dbg_connection_macos.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef BIN_DBG_CONNECTION_MACOS_H_
-#define BIN_DBG_CONNECTION_MACOS_H_
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/socket.h>
-
-
-namespace dart {
-namespace bin {
-
-class DebuggerConnectionImpl {
- public:
-  static void StartHandler(int port_number);
-  static void StopHandler(intptr_t debug_fd) {}
-  static intptr_t Send(intptr_t socket, const char* buf, int len);
-  static intptr_t Receive(intptr_t socket, char* buf, int len);
-
- private:
-  enum MessageType {
-    kAddDbgFd = 1,
-    kRemoveDbgFd,
-    kQuit
-  };
-
-  struct Message {
-    MessageType msg_id;
-  };
-
-  static void SendMessage(MessageType id);
-  static bool ReceiveMessage(Message* msg);
-
-  static void SetupPollQueue();
-  static void HandleEvent(struct kevent* event);
-  static void Handler(uword args);
-
-
-
-  // File descriptors for pipes used to communicate with the debugger thread.
-  static int wakeup_fds_[2];
-  // File descriptor for the polling queue.
-  static int kqueue_fd_;
-};
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // BIN_DBG_CONNECTION_MACOS_H_
diff --git a/runtime/bin/dbg_connection_win.cc b/runtime/bin/dbg_connection_win.cc
deleted file mode 100644
index 49bc4a9..0000000
--- a/runtime/bin/dbg_connection_win.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/globals.h"
-#if defined(TARGET_OS_WINDOWS)
-
-#include "bin/dbg_connection.h"
-
-#include "bin/eventhandler.h"
-#include "bin/lockers.h"
-#include "bin/log.h"
-#include "bin/thread.h"
-
-namespace dart {
-namespace bin {
-
-Monitor* DebuggerConnectionImpl::handler_monitor_ = new Monitor();
-ThreadId DebuggerConnectionImpl::handler_thread_id_ = Thread::kInvalidThreadId;
-bool DebuggerConnectionImpl::handler_thread_running_ = false;
-
-
-void DebuggerConnectionImpl::NotifyThreadStarted() {
-  MonitorLocker ml(handler_monitor_);
-  ASSERT(!handler_thread_running_);
-  ASSERT(handler_thread_id_ == Thread::kInvalidThreadId);
-  handler_thread_running_ = true;
-  handler_thread_id_ = Thread::GetCurrentThreadId();
-  ml.Notify();
-}
-
-
-void DebuggerConnectionImpl::WaitForThreadStarted() {
-  MonitorLocker ml(handler_monitor_);
-  while (!handler_thread_running_) {
-    ml.Wait();
-  }
-  ASSERT(handler_thread_id_ != Thread::kInvalidThreadId);
-}
-
-
-void DebuggerConnectionImpl::NotifyThreadFinished() {
-  MonitorLocker ml(handler_monitor_);
-  ASSERT(handler_thread_running_);
-  ASSERT(handler_thread_id_ != Thread::kInvalidThreadId);
-  handler_thread_running_ = false;
-  ml.Notify();
-}
-
-
-void DebuggerConnectionImpl::WaitForThreadFinished() {
-  MonitorLocker ml(handler_monitor_);
-  while (handler_thread_running_) {
-    ml.Wait();
-  }
-  ASSERT(handler_thread_id_ != Thread::kInvalidThreadId);
-  Thread::Join(handler_thread_id_);
-  handler_thread_id_ = Thread::kInvalidThreadId;
-}
-
-
-void DebuggerConnectionImpl::ThreadEntry(uword args) {
-  NotifyThreadStarted();
-  ListenSocket* listen_socket =
-      reinterpret_cast<ListenSocket*>(DebuggerConnectionHandler::listener_fd_);
-  SOCKET client_socket = accept(listen_socket->socket(), NULL, NULL);
-  if (client_socket == INVALID_SOCKET) {
-    FATAL("Accepting new debugger connection failed.\n");
-  }
-  ClientSocket* socket = new ClientSocket(client_socket);
-  DebuggerConnectionHandler::AcceptDbgConnection(
-      reinterpret_cast<intptr_t>(socket));
-  NotifyThreadFinished();
-}
-
-
-void DebuggerConnectionImpl::StartHandler(int port_number) {
-  ASSERT(DebuggerConnectionHandler::listener_fd_ != -1);
-  int result = Thread::Start(&DebuggerConnectionImpl::ThreadEntry, 0);
-  if (result != 0) {
-    FATAL1("Failed to start debugger connection handler thread: %d\n", result);
-  }
-  WaitForThreadStarted();
-}
-
-
-void DebuggerConnectionImpl::StopHandler(intptr_t debug_fd) {
-  Send(debug_fd, NULL, 0);
-  WaitForThreadFinished();
-}
-
-
-intptr_t DebuggerConnectionImpl::Send(intptr_t socket,
-                                      const char* buf,
-                                      int len) {
-  ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(socket);
-  return send(client_socket->socket(), buf, len, 0);
-}
-
-
-intptr_t DebuggerConnectionImpl::Receive(intptr_t socket, char* buf, int len) {
-  ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(socket);
-  return recv(client_socket->socket(), buf, len, 0);
-}
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/dbg_connection_win.h b/runtime/bin/dbg_connection_win.h
deleted file mode 100644
index 8f5d0c6..0000000
--- a/runtime/bin/dbg_connection_win.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef BIN_DBG_CONNECTION_WIN_H_
-#define BIN_DBG_CONNECTION_WIN_H_
-
-#include "bin/lockers.h"
-#include "bin/thread.h"
-
-namespace dart {
-namespace bin {
-
-class DebuggerConnectionImpl {
- public:
-  static void StartHandler(int port_number);
-  static void StopHandler(intptr_t debug_fd);
-  static intptr_t Send(intptr_t socket, const char* buf, int len);
-  static intptr_t Receive(intptr_t socket, char* buf, int len);
-
- private:
-  static void ThreadEntry(uword args);
-  static void NotifyThreadStarted();
-  static void WaitForThreadStarted();
-  static void NotifyThreadFinished();
-  static void WaitForThreadFinished();
-
-  static Monitor* handler_monitor_;
-  static ThreadId handler_thread_id_;
-  static bool handler_thread_running_;
-};
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // BIN_DBG_CONNECTION_WIN_H_
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
deleted file mode 100644
index d0f13d7..0000000
--- a/runtime/bin/dbg_message.cc
+++ /dev/null
@@ -1,1431 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "bin/dbg_connection.h"
-#include "bin/dbg_message.h"
-#include "bin/dartutils.h"
-#include "bin/lockers.h"
-#include "bin/thread.h"
-#include "bin/utils.h"
-
-#include "platform/globals.h"
-#include "platform/json.h"
-#include "platform/utils.h"
-
-#include "include/dart_api.h"
-
-
-namespace dart {
-namespace bin {
-
-bool MessageParser::IsValidMessage() const {
-  if (buf_length_ == 0) {
-    return false;
-  }
-  dart::JSONReader msg_reader(buf_);
-  return msg_reader.EndOfObject() != NULL;
-}
-
-
-int MessageParser::MessageId() const {
-  dart::JSONReader r(buf_);
-  r.Seek("id");
-  if (r.Type() == dart::JSONReader::kInteger) {
-    return atoi(r.ValueChars());
-  } else {
-    return -1;
-  }
-}
-
-
-const char* MessageParser::Params() const {
-  dart::JSONReader r(buf_);
-  r.Seek("params");
-  if (r.Type() == dart::JSONReader::kObject) {
-    return r.ValueChars();
-  } else {
-    return NULL;
-  }
-}
-
-
-bool MessageParser::HasParam(const char* name) const {
-  const char* params = Params();
-  ASSERT(params != NULL);
-  dart::JSONReader r(params);
-  return r.Seek(name);
-}
-
-
-intptr_t MessageParser::GetIntParam(const char* name) const {
-  const char* params = Params();
-  ASSERT(params != NULL);
-  dart::JSONReader r(params);
-  r.Seek(name);
-  ASSERT(r.Type() == dart::JSONReader::kInteger);
-  return strtol(r.ValueChars(), NULL, 10);
-}
-
-
-int64_t MessageParser::GetInt64Param(const char* name) const {
-  const char* params = Params();
-  ASSERT(params != NULL);
-  dart::JSONReader r(params);
-  r.Seek(name);
-  ASSERT(r.Type() == dart::JSONReader::kInteger);
-  return strtoll(r.ValueChars(), NULL, 10);
-}
-
-
-intptr_t MessageParser::GetOptIntParam(const char* name,
-                                       intptr_t default_val) const {
-  const char* params = Params();
-  ASSERT(params != NULL);
-  dart::JSONReader r(params);
-  r.Seek(name);
-  if (r.Type() == dart::JSONReader::kInteger) {
-    return strtol(r.ValueChars(), NULL, 10);
-  } else {
-    return default_val;
-  }
-}
-
-
-static const char* GetStringChars(Dart_Handle str) {
-  ASSERT(Dart_IsString(str));
-  const char* chars;
-  Dart_Handle res = Dart_StringToCString(str, &chars);
-  ASSERT(!Dart_IsError(res));
-  return chars;
-}
-
-
-static int64_t GetIntValue(Dart_Handle int_handle) {
-  int64_t int64_val = -1;
-  ASSERT(Dart_IsInteger(int_handle));
-  Dart_Handle res = Dart_IntegerToInt64(int_handle, &int64_val);
-  ASSERT_NOT_ERROR(res);
-  return int64_val;
-}
-
-
-char* MessageParser::GetStringParam(const char* name) const {
-  const char* params = Params();
-  ASSERT(params != NULL);
-  dart::JSONReader pr(params);
-  pr.Seek(name);
-  if (pr.Type() != dart::JSONReader::kString) {
-    return NULL;
-  }
-  intptr_t buflen = pr.ValueLen() + 1;
-  char* param_chars = reinterpret_cast<char*>(malloc(buflen));
-  pr.GetDecodedValueChars(param_chars, buflen);
-  return param_chars;
-}
-
-
-static void FormatEncodedCharsTrunc(dart::TextBuffer* buf,
-                                    Dart_Handle str,
-                                    intptr_t max_chars) {
-  intptr_t str_len = 0;
-  Dart_Handle res = Dart_StringLength(str, &str_len);
-  ASSERT_NOT_ERROR(res);
-  intptr_t num_chars = (str_len > max_chars) ? max_chars : str_len;
-  uint16_t* codeunits =
-      reinterpret_cast<uint16_t*>(malloc(num_chars * sizeof(uint16_t)));
-  ASSERT(codeunits != NULL);
-  intptr_t actual_len = num_chars;
-  res = Dart_StringToUTF16(str, codeunits, &actual_len);
-  ASSERT_NOT_ERROR(res);
-  ASSERT(num_chars == actual_len);
-  for (int i = 0; i < num_chars; i++) {
-    buf->EscapeAndAddCodeUnit(codeunits[i]);
-  }
-  if (str_len > max_chars) {
-    buf->Printf("...");
-  }
-  free(codeunits);
-}
-
-
-static void FormatEncodedChars(dart::TextBuffer* buf, Dart_Handle str) {
-  intptr_t str_len = 0;
-  Dart_Handle res = Dart_StringLength(str, &str_len);
-  ASSERT_NOT_ERROR(res);
-  uint16_t* codeunits =
-      reinterpret_cast<uint16_t*>(malloc(str_len * sizeof(uint16_t)));
-  ASSERT(codeunits != NULL);
-  intptr_t actual_len = str_len;
-  res = Dart_StringToUTF16(str, codeunits, &actual_len);
-  ASSERT_NOT_ERROR(res);
-  ASSERT(str_len == actual_len);
-  for (int i = 0; i < str_len; i++) {
-    buf->EscapeAndAddCodeUnit(codeunits[i]);
-  }
-  free(codeunits);
-}
-
-
-static void FormatEncodedString(dart::TextBuffer* buf, Dart_Handle str) {
-  buf->AddChar('\"');
-  FormatEncodedChars(buf, str);
-  buf->AddChar('\"');
-}
-
-
-static void FormatTextualValue(dart::TextBuffer* buf,
-                               Dart_Handle object,
-                               intptr_t max_chars,
-                               bool expand_list);
-
-
-static void FormatTextualListValue(dart::TextBuffer* buf,
-                                   Dart_Handle list,
-                                   intptr_t max_chars) {
-  intptr_t len = 0;
-  Dart_Handle res = Dart_ListLength(list, &len);
-  ASSERT_NOT_ERROR(res);
-  const intptr_t initial_buffer_length = buf->length();
-  // Maximum number of characters we print for array elements.
-  const intptr_t max_buffer_length = initial_buffer_length + max_chars;
-  buf->Printf("[");
-  for (int i = 0; i < len; i++) {
-    if (i > 0) {
-      buf->Printf(", ");
-    }
-    Dart_Handle elem = Dart_ListGetAt(list, i);
-    const intptr_t max_element_chars = 50;
-    FormatTextualValue(buf, elem, max_element_chars, false);
-    if (buf->length() > max_buffer_length) {
-      buf->Printf(", ...");
-      break;
-    }
-  }
-  buf->Printf("]");
-}
-
-
-static void FormatTextualValue(dart::TextBuffer* buf,
-                               Dart_Handle object,
-                               intptr_t max_chars,
-                               bool expand_list) {
-  ASSERT(!Dart_IsError(object));
-  if (Dart_IsList(object)) {
-    if (expand_list) {
-      FormatTextualListValue(buf, object, max_chars);
-    } else {
-      buf->Printf("[...]");
-    }
-  } else if (Dart_IsNull(object)) {
-    buf->Printf("null");
-  } else if (Dart_IsString(object)) {
-    buf->Printf("\\\"");
-    FormatEncodedCharsTrunc(buf, object, max_chars);
-    buf->Printf("\\\"");
-  } else if (Dart_IsNumber(object) || Dart_IsBoolean(object)) {
-    Dart_Handle text = Dart_ToString(object);
-    ASSERT(!Dart_IsNull(text) && !Dart_IsError(text));
-    FormatEncodedCharsTrunc(buf, text, max_chars);
-  } else {
-    Dart_Handle type = Dart_InstanceGetType(object);
-    ASSERT_NOT_ERROR(type);
-    type = Dart_ToString(type);
-    ASSERT_NOT_ERROR(type);
-    buf->Printf("object of type ");
-    FormatEncodedCharsTrunc(buf, type, max_chars);
-  }
-}
-
-
-static void FormatValue(dart::TextBuffer* buf, Dart_Handle object) {
-  bool print_text_field = true;
-  if (Dart_IsNumber(object)) {
-    buf->Printf("\"kind\":\"number\"");
-  } else if (Dart_IsString(object)) {
-    buf->Printf("\"kind\":\"string\"");
-  } else if (Dart_IsBoolean(object)) {
-    buf->Printf("\"kind\":\"boolean\"");
-  } else if (Dart_IsList(object)) {
-    intptr_t len = 0;
-    Dart_Handle res = Dart_ListLength(object, &len);
-    ASSERT_NOT_ERROR(res);
-    buf->Printf("\"kind\":\"list\",\"length\":%" Pd "", len);
-  } else if (Dart_IsClosure(object)) {
-    Dart_Handle name, signature;
-    Dart_CodeLocation location;
-    Dart_Handle res = Dart_GetClosureInfo(object, &name, &signature, &location);
-    ASSERT_NOT_ERROR(res);
-    buf->Printf("\"kind\":\"function\",\"name\":\"%s\"", GetStringChars(name));
-    buf->Printf(",\"signature\":\"%s\"", GetStringChars(signature));
-    if (!Dart_IsNull(location.script_url)) {
-      ASSERT(Dart_IsString(location.script_url));
-      buf->Printf(",\"location\": { \"url\":");
-      FormatEncodedString(buf, location.script_url);
-      buf->Printf(",\"libraryId\":%d,", location.library_id);
-      buf->Printf("\"tokenOffset\":%d}", location.token_pos);
-    }
-    print_text_field = false;
-  } else {
-    buf->Printf("\"kind\":\"object\"");
-    intptr_t class_id = 0;
-    Dart_Handle res = Dart_GetObjClassId(object, &class_id);
-    if (!Dart_IsError(res)) {
-      buf->Printf(",\"classId\":%" Pd "", class_id);
-    }
-  }
-  if (print_text_field) {
-    buf->Printf(",\"text\":\"");
-    const intptr_t max_chars = 1024;
-    FormatTextualValue(buf, object, max_chars, true);
-    buf->Printf("\"");
-  }
-}
-
-
-static void FormatValueObj(dart::TextBuffer* buf, Dart_Handle object) {
-  buf->Printf("{");
-  FormatValue(buf, object);
-  buf->Printf("}");
-}
-
-
-static void FormatRemoteObj(dart::TextBuffer* buf, Dart_Handle object) {
-  intptr_t obj_id = Dart_CacheObject(object);
-  ASSERT(obj_id >= 0);
-  buf->Printf("{\"objectId\":%" Pd ",", obj_id);
-  FormatValue(buf, object);
-  buf->Printf("}");
-}
-
-
-static void FormatNamedValue(dart::TextBuffer* buf,
-                             Dart_Handle object_name,
-                             Dart_Handle object) {
-  ASSERT(Dart_IsString(object_name));
-  buf->Printf("{\"name\":\"%s\",", GetStringChars(object_name));
-  buf->Printf("\"value\":");
-  FormatRemoteObj(buf, object);
-  buf->Printf("}");
-}
-
-
-static void FormatNamedValueList(dart::TextBuffer* buf,
-                                 Dart_Handle obj_list) {
-  ASSERT(Dart_IsList(obj_list));
-  intptr_t list_length = 0;
-  Dart_Handle res = Dart_ListLength(obj_list, &list_length);
-  ASSERT_NOT_ERROR(res);
-  ASSERT(list_length % 2 == 0);
-  buf->Printf("[");
-  for (int i = 0; i + 1 < list_length; i += 2) {
-    Dart_Handle name_handle = Dart_ListGetAt(obj_list, i);
-    ASSERT_NOT_ERROR(name_handle);
-    Dart_Handle value_handle = Dart_ListGetAt(obj_list, i + 1);
-    ASSERT_NOT_ERROR(value_handle);
-    if (i > 0) {
-      buf->Printf(",");
-    }
-    FormatNamedValue(buf, name_handle, value_handle);
-  }
-  buf->Printf("]");
-}
-
-
-static const char* FormatClassProps(dart::TextBuffer* buf,
-                                    intptr_t cls_id) {
-  Dart_Handle name, static_fields;
-  intptr_t super_id = -1;
-  intptr_t library_id = -1;
-  Dart_Handle res =
-      Dart_GetClassInfo(cls_id, &name, &library_id, &super_id, &static_fields);
-  RETURN_IF_ERROR(res);
-  RETURN_IF_ERROR(name);
-  buf->Printf("{\"name\":\"%s\",", GetStringChars(name));
-  if (super_id > 0) {
-    buf->Printf("\"superclassId\":%" Pd ",", super_id);
-  }
-  buf->Printf("\"libraryId\":%" Pd ",", library_id);
-  RETURN_IF_ERROR(static_fields);
-  buf->Printf("\"fields\":");
-  FormatNamedValueList(buf, static_fields);
-  buf->Printf("}");
-  return NULL;
-}
-
-
-static const char* FormatLibraryProps(dart::TextBuffer* buf,
-                                      intptr_t lib_id) {
-  Dart_Handle url = Dart_GetLibraryURL(lib_id);
-  RETURN_IF_ERROR(url);
-  buf->Printf("{\"url\":");
-  FormatEncodedString(buf, url);
-
-  // Whether debugging is enabled.
-  bool is_debuggable = false;
-  Dart_Handle res = Dart_GetLibraryDebuggable(lib_id, &is_debuggable);
-  RETURN_IF_ERROR(res);
-  buf->Printf(",\"debuggingEnabled\":%s",
-              is_debuggable ? "\"true\"" : "\"false\"");
-
-  // Imports and prefixes.
-  Dart_Handle import_list = Dart_GetLibraryImports(lib_id);
-  RETURN_IF_ERROR(import_list);
-  ASSERT(Dart_IsList(import_list));
-  intptr_t list_length = 0;
-  res = Dart_ListLength(import_list, &list_length);
-  RETURN_IF_ERROR(res);
-  buf->Printf(",\"imports\":[");
-  for (intptr_t i = 0; i + 1 < list_length; i += 2) {
-    Dart_Handle lib_id = Dart_ListGetAt(import_list, i + 1);
-    ASSERT_NOT_ERROR(lib_id);
-    buf->Printf("%s{\"libraryId\":%" Pd64 ",",
-                (i > 0) ? ",": "",
-                GetIntValue(lib_id));
-
-    Dart_Handle name = Dart_ListGetAt(import_list, i);
-    ASSERT_NOT_ERROR(name);
-    buf->Printf("\"prefix\":\"%s\"}",
-                Dart_IsNull(name) ? "" : GetStringChars(name));
-  }
-  buf->Printf("],");
-
-  // Global variables in the library.
-  Dart_Handle global_vars = Dart_GetLibraryFields(lib_id);
-  RETURN_IF_ERROR(global_vars);
-  buf->Printf("\"globals\":");
-  FormatNamedValueList(buf, global_vars);
-  buf->Printf("}");
-  return NULL;
-}
-
-
-static const char* FormatObjProps(dart::TextBuffer* buf,
-                                  Dart_Handle object) {
-  intptr_t class_id;
-  if (Dart_IsNull(object)) {
-    buf->Printf("{\"classId\":-1,\"fields\":[]}");
-    return NULL;
-  }
-  Dart_Handle res = Dart_GetObjClassId(object, &class_id);
-  RETURN_IF_ERROR(res);
-  buf->Printf("{\"classId\": %" Pd ",", class_id);
-  buf->Printf("\"kind\":\"object\",\"fields\":");
-  Dart_Handle fields = Dart_GetInstanceFields(object);
-  RETURN_IF_ERROR(fields);
-  FormatNamedValueList(buf, fields);
-  buf->Printf("}");
-  return NULL;
-}
-
-
-static const char* FormatListSlice(dart::TextBuffer* buf,
-                                   Dart_Handle list,
-                                   intptr_t list_length,
-                                   intptr_t index,
-                                   intptr_t slice_length) {
-  intptr_t end_index = index + slice_length;
-  ASSERT(end_index <= list_length);
-  buf->Printf("{\"index\":%" Pd ",", index);
-  buf->Printf("\"length\":%" Pd ",", slice_length);
-  buf->Printf("\"elements\":[");
-  for (intptr_t i = index; i < end_index; i++) {
-    Dart_Handle value = Dart_ListGetAt(list, i);
-    if (i > index) {
-      buf->Printf(",");
-    }
-    FormatValueObj(buf, value);
-  }
-  buf->Printf("]}");
-  return NULL;
-}
-
-
-static void FormatLocationFromTrace(dart::TextBuffer* msg,
-                                    Dart_StackTrace trace,
-                                    const char* prefix) {
-  intptr_t trace_len = 0;
-  Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
-  ASSERT_NOT_ERROR(res);
-  if (trace_len == 0) {
-    return;
-  }
-  Dart_ActivationFrame frame;
-  res = Dart_GetActivationFrame(trace, 0, &frame);
-  ASSERT_NOT_ERROR(res);
-  Dart_CodeLocation location;
-  res = Dart_ActivationFrameGetLocation(frame, NULL, NULL, &location);
-  ASSERT_NOT_ERROR(res);
-  if (!Dart_IsNull(location.script_url)) {
-    ASSERT(Dart_IsString(location.script_url));
-    msg->Printf("%s\"location\": { \"url\":", prefix);
-    FormatEncodedString(msg, location.script_url);
-    msg->Printf(",\"libraryId\":%d,", location.library_id);
-    msg->Printf("\"tokenOffset\":%d}", location.token_pos);
-  }
-}
-
-
-static void FormatCallFrames(dart::TextBuffer* msg, Dart_StackTrace trace) {
-  intptr_t trace_len = 0;
-  Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
-  ASSERT_NOT_ERROR(res);
-  msg->Printf("\"callFrames\" : [ ");
-  for (int i = 0; i < trace_len; i++) {
-    Dart_ActivationFrame frame;
-    res = Dart_GetActivationFrame(trace, i, &frame);
-    ASSERT_NOT_ERROR(res);
-    Dart_Handle func_name;
-    Dart_Handle func;
-    Dart_CodeLocation location;
-    res = Dart_ActivationFrameGetLocation(frame, &func_name, &func, &location);
-    ASSERT_NOT_ERROR(res);
-    ASSERT(Dart_IsString(func_name));
-    msg->Printf("%s{\"functionName\":", (i > 0) ? "," : "");
-    FormatEncodedString(msg, func_name);
-    if (!Dart_IsNull(location.script_url)) {
-      ASSERT(Dart_IsString(location.script_url));
-      msg->Printf(",\"location\": { \"url\":");
-      FormatEncodedString(msg, location.script_url);
-      msg->Printf(",\"libraryId\":%d,", location.library_id);
-      msg->Printf("\"tokenOffset\":%d}", location.token_pos);
-    }
-    ASSERT_NOT_ERROR(func);
-    Dart_Handle origin = Dart_GetFunctionOrigin(func);
-    ASSERT_NOT_ERROR(origin);
-    if (Dart_IsInteger(origin)) {
-      int64_t class_id = GetIntValue(origin);
-      msg->Printf(",\"classId\":%" Pd64 "", class_id);
-    }
-    Dart_Handle locals = Dart_GetLocalVariables(frame);
-    ASSERT_NOT_ERROR(locals);
-    msg->Printf(",\"locals\":");
-    FormatNamedValueList(msg, locals);
-    msg->Printf("}");
-  }
-  msg->Printf("]");
-}
-
-
-typedef bool (*CommandHandler)(DbgMessage* msg);
-
-struct JSONDebuggerCommand {
-  const char* cmd_string;
-  CommandHandler handler_function;
-};
-
-
-static JSONDebuggerCommand debugger_commands[] = {
-  { "resume", DbgMessage::HandleResumeCmd },
-  { "stepInto", DbgMessage::HandleStepIntoCmd },
-  { "stepOut", DbgMessage::HandleStepOutCmd },
-  { "stepOver", DbgMessage::HandleStepOverCmd },
-  { "getLibraries", DbgMessage::HandleGetLibrariesCmd },
-  { "getClassProperties", DbgMessage::HandleGetClassPropsCmd },
-  { "getLibraryProperties", DbgMessage::HandleGetLibPropsCmd },
-  { "setLibraryProperties", DbgMessage::HandleSetLibPropsCmd },
-  { "evaluateExpr", DbgMessage::HandleEvaluateExprCmd },
-  { "getObjectProperties", DbgMessage::HandleGetObjPropsCmd },
-  { "getListElements", DbgMessage::HandleGetListCmd },
-  { "getGlobalVariables", DbgMessage::HandleGetGlobalsCmd },
-  { "getScriptURLs", DbgMessage::HandleGetScriptURLsCmd },
-  { "getScriptSource", DbgMessage::HandleGetSourceCmd },
-  { "getLineNumberTable", DbgMessage::HandleGetLineNumbersCmd },
-  { "getStackTrace", DbgMessage::HandleGetStackTraceCmd },
-  { "setBreakpoint", DbgMessage::HandleSetBpCmd },
-  { "setPauseOnException", DbgMessage::HandlePauseOnExcCmd },
-  { "removeBreakpoint", DbgMessage::HandleRemBpCmd },
-  { NULL, NULL }
-};
-
-
-bool DbgMessage::HandleMessage() {
-  // Dispatch to the appropriate handler for the command.
-  int max_index = (sizeof(debugger_commands) / sizeof(JSONDebuggerCommand));
-  ASSERT(cmd_idx_ < max_index);
-  return (*debugger_commands[cmd_idx_].handler_function)(this);
-}
-
-
-void DbgMessage::SendReply(dart::TextBuffer* reply) {
-  DebuggerConnectionHandler::SendMsg(debug_fd(), reply);
-}
-
-
-void DbgMessage::SendErrorReply(int msg_id, const char* err_msg) {
-  DebuggerConnectionHandler::SendError(debug_fd(), msg_id, err_msg);
-}
-
-
-bool DbgMessage::HandleResumeCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  dart::TextBuffer msg(64);
-  msg.Printf("{ \"id\": %d }", msg_id);
-  in_msg->SendReply(&msg);
-  return true;
-}
-
-
-bool DbgMessage::HandleStepIntoCmd(DbgMessage* in_msg) {
-  Dart_Handle res = Dart_SetStepInto();
-  ASSERT_NOT_ERROR(res);
-  return HandleResumeCmd(in_msg);
-}
-
-
-bool DbgMessage::HandleStepOutCmd(DbgMessage* in_msg) {
-  Dart_Handle res = Dart_SetStepOut();
-  ASSERT_NOT_ERROR(res);
-  return HandleResumeCmd(in_msg);
-}
-
-
-bool DbgMessage::HandleStepOverCmd(DbgMessage* in_msg) {
-  Dart_Handle res = Dart_SetStepOver();
-  ASSERT_NOT_ERROR(res);
-  return HandleResumeCmd(in_msg);
-}
-
-
-bool DbgMessage::HandleGetLibrariesCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  dart::TextBuffer msg(64);
-  msg.Printf("{ \"id\": %d, \"result\": { \"libraries\": [", msg_id);
-  Dart_Handle lib_ids = Dart_GetLibraryIds();
-  ASSERT_NOT_ERROR(lib_ids);
-  intptr_t num_libs;
-  Dart_Handle res = Dart_ListLength(lib_ids, &num_libs);
-  ASSERT_NOT_ERROR(res);
-  for (intptr_t i = 0; i < num_libs; i++) {
-    Dart_Handle lib_id_handle = Dart_ListGetAt(lib_ids, i);
-    ASSERT(Dart_IsInteger(lib_id_handle));
-    int64_t lib_id = GetIntValue(lib_id_handle);
-    ASSERT((lib_id >= kIntptrMin) && (lib_id <= kIntptrMax));
-    Dart_Handle lib_url = Dart_GetLibraryURL(static_cast<intptr_t>(lib_id));
-    ASSERT_NOT_ERROR(lib_url);
-    ASSERT(Dart_IsString(lib_url));
-    msg.Printf("%s{\"id\":%" Pd64 ",\"url\":", (i == 0) ? "" : ", ", lib_id);
-    FormatEncodedString(&msg, lib_url);
-    msg.Printf("}");
-  }
-  msg.Printf("]}}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleGetClassPropsCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  intptr_t cls_id = msg_parser.GetIntParam("classId");
-  dart::TextBuffer msg(64);
-  msg.Printf("{\"id\":%d, \"result\":", msg_id);
-  const char* err = FormatClassProps(&msg, cls_id);
-  if (err != NULL) {
-    in_msg->SendErrorReply(msg_id, err);
-    return false;
-  }
-  msg.Printf("}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleGetLibPropsCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
-  dart::TextBuffer msg(64);
-  msg.Printf("{\"id\":%d, \"result\":", msg_id);
-  const char* err = FormatLibraryProps(&msg, lib_id);
-  if (err != NULL) {
-    in_msg->SendErrorReply(msg_id, err);
-    return false;
-  }
-  msg.Printf("}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleSetLibPropsCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
-  const char* enable_request = msg_parser.GetStringParam("debuggingEnabled");
-  bool enable;
-  if (strcmp(enable_request, "true") == 0) {
-    enable = true;
-  } else if (strcmp(enable_request, "false") == 0) {
-    enable = false;
-  } else {
-    in_msg->SendErrorReply(msg_id, "illegal argument for 'debuggingEnabled'");
-    return false;
-  }
-  Dart_Handle res = Dart_SetLibraryDebuggable(lib_id, enable);
-  if (Dart_IsError(res)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(res));
-    return false;
-  }
-  bool enabled = false;
-  res = Dart_GetLibraryDebuggable(lib_id, &enabled);
-  if (Dart_IsError(res)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(res));
-    return false;
-  }
-  dart::TextBuffer msg(64);
-  msg.Printf("{\"id\":%d, \"result\": {\"debuggingEnabled\": \"%s\"}}",
-             msg_id,
-             enabled ? "true" : "false");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleEvaluateExprCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  Dart_Handle target = Dart_Null();
-  Dart_ActivationFrame frame = NULL;
-
-  if (msg_parser.HasParam("libraryId")) {
-    intptr_t lib_id = msg_parser.GetIntParam("libraryId");
-    target = Dart_GetLibraryFromId(lib_id);
-  } else if (msg_parser.HasParam("classId")) {
-    intptr_t cls_id = msg_parser.GetIntParam("classId");
-    target = Dart_GetClassFromId(cls_id);
-  } else if (msg_parser.HasParam("objectId")) {
-    intptr_t obj_id = msg_parser.GetIntParam("objectId");
-    target = Dart_GetCachedObject(obj_id);
-  } else if (msg_parser.HasParam("frameId")) {
-    intptr_t frame_index = msg_parser.GetIntParam("frameId");
-    Dart_Handle res;
-    Dart_StackTrace stack_trace;
-    res = Dart_GetStackTrace(&stack_trace);
-    ASSERT_NOT_ERROR(res);
-    intptr_t trace_length = 0;
-    res = Dart_StackTraceLength(stack_trace, &trace_length);
-    ASSERT_NOT_ERROR(res);
-    if (frame_index >= trace_length) {
-      in_msg->SendErrorReply(msg_id, "illegal frame index");
-      return false;
-    }
-    res = Dart_GetActivationFrame(stack_trace, frame_index, &frame);
-    ASSERT_NOT_ERROR(res);
-  } else {
-    in_msg->SendErrorReply(msg_id, "illegal evaluation target");
-    return false;
-  }
-
-  char* expr_chars = msg_parser.GetStringParam("expression");
-  Dart_Handle expr = Dart_NewStringFromCString(expr_chars);
-  if (Dart_IsError(expr)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(expr));
-    return false;
-  }
-
-  Dart_Handle eval_result = Dart_Null();
-  if (frame != NULL) {
-    eval_result = Dart_ActivationFrameEvaluate(frame, expr);
-  } else {
-    if (Dart_IsError(target)) {
-      in_msg->SendErrorReply(msg_id, Dart_GetError(target));
-      return false;
-    }
-    eval_result = Dart_EvaluateExpr(target, expr);
-  }
-  if (Dart_IsError(eval_result)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(eval_result));
-    return false;
-  }
-
-  dart::TextBuffer msg(64);
-  msg.Printf("{\"id\":%d, \"result\":", msg_id);
-  FormatRemoteObj(&msg, eval_result);
-  msg.Printf("}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleGetObjPropsCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  intptr_t obj_id = msg_parser.GetIntParam("objectId");
-  Dart_Handle obj = Dart_GetCachedObject(obj_id);
-  if (Dart_IsError(obj)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(obj));
-    return false;
-  }
-  dart::TextBuffer msg(64);
-  msg.Printf("{\"id\":%d, \"result\":", msg_id);
-  const char* err = FormatObjProps(&msg, obj);
-  if (err != NULL) {
-    in_msg->SendErrorReply(msg_id, err);
-    return false;
-  }
-  msg.Printf("}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleGetListCmd(DbgMessage* in_msg) {
-  const intptr_t kDefaultSliceLength = 100;
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  intptr_t obj_id = msg_parser.GetIntParam("objectId");
-  Dart_Handle list = Dart_GetCachedObject(obj_id);
-  if (Dart_IsError(list)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(list));
-    return false;
-  }
-  if (!Dart_IsList(list)) {
-    in_msg->SendErrorReply(msg_id, "object is not a list");
-    return false;
-  }
-  intptr_t list_length = 0;
-  Dart_Handle res = Dart_ListLength(list, &list_length);
-  if (Dart_IsError(res)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(res));
-    return false;
-  }
-
-  intptr_t index = msg_parser.GetIntParam("index");
-  if (index < 0) {
-    index = 0;
-  } else if (index > list_length) {
-    index = list_length;
-  }
-
-  // If no slice length is given, get only one element. If slice length
-  // is given as 0, get entire list.
-  intptr_t slice_length = msg_parser.GetOptIntParam("length", 1);
-  if (slice_length == 0) {
-    slice_length = list_length - index;
-  }
-  if ((index + slice_length) > list_length) {
-    slice_length = list_length - index;
-  }
-  ASSERT(slice_length >= 0);
-  if (slice_length > kDefaultSliceLength) {
-    slice_length = kDefaultSliceLength;
-  }
-  dart::TextBuffer msg(64);
-  msg.Printf("{\"id\":%d, \"result\":", msg_id);
-  if (slice_length == 1) {
-    Dart_Handle value = Dart_ListGetAt(list, index);
-    FormatRemoteObj(&msg, value);
-  } else {
-    FormatListSlice(&msg, list, list_length, index, slice_length);
-  }
-  msg.Printf("}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleGetGlobalsCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
-  dart::TextBuffer msg(64);
-  msg.Printf("{\"id\":%d, \"result\": { \"globals\":", msg_id);
-  Dart_Handle globals = Dart_GetGlobalVariables(lib_id);
-  ASSERT_NOT_ERROR(globals);
-  FormatNamedValueList(&msg, globals);
-  msg.Printf("}}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleGetScriptURLsCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  dart::TextBuffer msg(64);
-  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
-  Dart_Handle lib_url = Dart_GetLibraryURL(lib_id);
-  ASSERT_NOT_ERROR(lib_url);
-  Dart_Handle urls = Dart_GetScriptURLs(lib_url);
-  if (Dart_IsError(urls)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(urls));
-    return false;
-  }
-  ASSERT(Dart_IsList(urls));
-  intptr_t num_urls = 0;
-  Dart_ListLength(urls, &num_urls);
-  msg.Printf("{ \"id\": %d, ", msg_id);
-  msg.Printf("\"result\": { \"urls\": [");
-  for (int i = 0; i < num_urls; i++) {
-    Dart_Handle script_url = Dart_ListGetAt(urls, i);
-    if (i > 0) {
-      msg.Printf(",");
-    }
-    FormatEncodedString(&msg, script_url);
-  }
-  msg.Printf("]}}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleGetSourceCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  dart::TextBuffer msg(64);
-  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
-  char* url_chars = msg_parser.GetStringParam("url");
-  ASSERT(url_chars != NULL);
-  Dart_Handle url = DartUtils::NewString(url_chars);
-  ASSERT_NOT_ERROR(url);
-  free(url_chars);
-  url_chars = NULL;
-  Dart_Handle source = Dart_ScriptGetSource(lib_id, url);
-  if (Dart_IsError(source)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(source));
-    return false;
-  }
-  msg.Printf("{ \"id\": %d, ", msg_id);
-  msg.Printf("\"result\": { \"text\": ");
-  FormatEncodedString(&msg, source);
-  msg.Printf("}}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleGetLineNumbersCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  dart::TextBuffer msg(64);
-  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
-  char* url_chars = msg_parser.GetStringParam("url");
-  ASSERT(url_chars != NULL);
-  Dart_Handle url = DartUtils::NewString(url_chars);
-  ASSERT_NOT_ERROR(url);
-  free(url_chars);
-  url_chars = NULL;
-  Dart_Handle info = Dart_ScriptGetTokenInfo(lib_id, url);
-  if (Dart_IsError(info)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(info));
-    return false;
-  }
-  ASSERT(Dart_IsList(info));
-  intptr_t info_len = 0;
-  Dart_Handle res = Dart_ListLength(info, &info_len);
-  ASSERT_NOT_ERROR(res);
-  msg.Printf("{ \"id\": %d, ", msg_id);
-  msg.Printf("\"result\": { \"lines\": [");
-  Dart_Handle elem;
-  intptr_t num_elems = 0;
-  for (intptr_t i = 0; i < info_len; i++) {
-    elem = Dart_ListGetAt(info, i);
-    if (Dart_IsNull(elem)) {
-      msg.Printf((i == 0) ? "[" : "], [");
-      num_elems = 0;
-    } else {
-      ASSERT(Dart_IsInteger(elem));
-      int64_t value = GetIntValue(elem);
-      if (num_elems == 0) {
-        msg.Printf("%" Pd64 "", value);
-      } else {
-        msg.Printf(",%" Pd64 "", value);
-      }
-      num_elems++;
-    }
-  }
-  msg.Printf("]]}}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleGetStackTraceCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  Dart_StackTrace trace;
-  Dart_Handle res = Dart_GetStackTrace(&trace);
-  ASSERT_NOT_ERROR(res);
-  dart::TextBuffer msg(128);
-  msg.Printf("{ \"id\": %d, \"result\": {", msg_id);
-  FormatCallFrames(&msg, trace);
-  msg.Printf("}}");
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleSetBpCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  char* url_chars = msg_parser.GetStringParam("url");
-  ASSERT(url_chars != NULL);
-  Dart_Handle url = DartUtils::NewString(url_chars);
-  ASSERT_NOT_ERROR(url);
-  free(url_chars);
-  url_chars = NULL;
-  intptr_t line_number = msg_parser.GetIntParam("line");
-  Dart_Handle bp_id = Dart_SetBreakpoint(url, line_number);
-  if (Dart_IsError(bp_id)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(bp_id));
-    return false;
-  }
-  ASSERT(Dart_IsInteger(bp_id));
-  uint64_t bp_id_value;
-  Dart_Handle res = Dart_IntegerToUint64(bp_id, &bp_id_value);
-  ASSERT_NOT_ERROR(res);
-  dart::TextBuffer msg(64);
-  msg.Printf("{ \"id\": %d, \"result\": { \"breakpointId\": %" Pu64 " }}",
-             msg_id, bp_id_value);
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandlePauseOnExcCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  char* exc_chars = msg_parser.GetStringParam("exceptions");
-  Dart_ExceptionPauseInfo info = kNoPauseOnExceptions;
-  if (strcmp(exc_chars, "none") == 0) {
-    info = kNoPauseOnExceptions;
-  } else if (strcmp(exc_chars, "all") == 0) {
-    info = kPauseOnAllExceptions;
-  } else if (strcmp(exc_chars, "unhandled") == 0) {
-    info = kPauseOnUnhandledExceptions;
-  } else {
-    in_msg->SendErrorReply(msg_id, "illegal value for parameter 'exceptions'");
-    return false;
-  }
-  Dart_Handle res = Dart_SetExceptionPauseInfo(info);
-  ASSERT_NOT_ERROR(res);
-  dart::TextBuffer msg(32);
-  msg.Printf("{ \"id\": %d }", msg_id);
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-bool DbgMessage::HandleRemBpCmd(DbgMessage* in_msg) {
-  ASSERT(in_msg != NULL);
-  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
-  int msg_id = msg_parser.MessageId();
-  int bpt_id = msg_parser.GetIntParam("breakpointId");
-  Dart_Handle res = Dart_RemoveBreakpoint(bpt_id);
-  if (Dart_IsError(res)) {
-    in_msg->SendErrorReply(msg_id, Dart_GetError(res));
-    return false;
-  }
-  dart::TextBuffer msg(32);
-  msg.Printf("{ \"id\": %d }", msg_id);
-  in_msg->SendReply(&msg);
-  return false;
-}
-
-
-void DbgMsgQueue::AddMessage(int32_t cmd_idx,
-                             const char* start,
-                             const char* end,
-                             intptr_t debug_fd) {
-  if ((end > start) && ((end - start) < kMaxInt32)) {
-    MonitorLocker ml(&msg_queue_lock_);
-    DbgMessage* msg = new DbgMessage(cmd_idx, start, end, debug_fd);
-    if (msglist_head_ == NULL) {
-      ASSERT(msglist_tail_ == NULL);
-      msglist_head_ = msg;
-      msglist_tail_ = msg;
-      ml.Notify();
-    } else {
-      ASSERT(msglist_tail_ != NULL);
-      msglist_tail_->set_next(msg);
-      msglist_tail_ = msg;
-    }
-  }
-}
-
-
-void DbgMsgQueue::Notify() {
-  MonitorLocker ml(&msg_queue_lock_);
-  ml.Notify();
-}
-
-
-bool DbgMsgQueue::HandlePendingMessages() {
-  // Handle all available debug messages, up to a resume request.
-  bool resume_requested = false;
-  while (msglist_head_ != NULL && !resume_requested) {
-    ASSERT(msglist_tail_ != NULL);
-    DbgMessage* msg = msglist_head_;
-    msglist_head_ = msglist_head_->next();
-    if (msglist_head_ == NULL) {
-      msglist_tail_ = NULL;
-    }
-    resume_requested = msg->HandleMessage();
-    delete msg;
-  }
-  return resume_requested;
-}
-
-
-void DbgMsgQueue::MessageLoop() {
-  MonitorLocker ml(&msg_queue_lock_);
-  is_running_ = false;
-
-  // Request notification on isolate messages.  This allows us to
-  // respond to vm service messages while at breakpoint.
-  Dart_SetMessageNotifyCallback(DbgMsgQueueList::NotifyIsolate);
-
-  while (true) {
-    // Handle all available vm service messages, up to a resume
-    // request.
-    bool resume = false;
-    while (!resume && Dart_HasServiceMessages()) {
-      msg_queue_lock_.Exit();
-      resume = Dart_HandleServiceMessages();
-      msg_queue_lock_.Enter();
-    }
-    if (resume) {
-      break;
-    }
-
-    // Handle all available debug messages, up to a resume request.
-    if (HandlePendingMessages()) {
-      break;
-    }
-
-    // Wait for more debug or vm service messages.
-    Monitor::WaitResult res = ml.Wait();
-    ASSERT(res == Monitor::kNotified);
-  }
-  Dart_SetMessageNotifyCallback(NULL);
-  is_interrupted_ = false;
-  is_running_ = true;
-}
-
-
-void DbgMsgQueue::InterruptIsolate() {
-  Dart_Isolate isolate = Dart_GetIsolate(isolate_id_);
-  MonitorLocker ml(&msg_queue_lock_);
-  if (is_running_ && !is_interrupted_) {
-    is_interrupted_ = true;
-    Dart_InterruptIsolate(isolate);
-  }
-}
-
-
-void DbgMsgQueue::QueueOutputMsg(dart::TextBuffer* msg) {
-  queued_output_messages_.Printf("%s", msg->buf());
-}
-
-
-void DbgMsgQueue::SendQueuedMsgs() {
-  if (queued_output_messages_.length() > 0) {
-    DebuggerConnectionHandler::BroadcastMsg(&queued_output_messages_);
-    queued_output_messages_.Clear();
-  }
-}
-
-
-void DbgMsgQueue::SendBreakpointEvent(intptr_t bp_id,
-                                      const Dart_CodeLocation& location) {
-  dart::TextBuffer msg(128);
-  msg.Printf("{ \"event\": \"paused\", \"params\": { ");
-  msg.Printf("\"reason\": \"breakpoint\", ");
-  msg.Printf("\"isolateId\": %" Pd64 "", isolate_id_);
-  if (bp_id != ILLEGAL_BREAKPOINT_ID) {
-    msg.Printf(",\"breakpointId\": %" Pd "", bp_id);
-  }
-  if (!Dart_IsNull(location.script_url)) {
-    ASSERT(Dart_IsString(location.script_url));
-    msg.Printf(",\"location\": { \"url\":");
-    FormatEncodedString(&msg, location.script_url);
-    msg.Printf(",\"libraryId\":%d,", location.library_id);
-    msg.Printf("\"tokenOffset\":%d}", location.token_pos);
-  }
-  msg.Printf("}}");
-  DebuggerConnectionHandler::BroadcastMsg(&msg);
-}
-
-
-// TODO(hausner): Remove stack trace parameter once we remove the stack
-// trace from the paused event in the wire protocol.
-void DbgMsgQueue::SendExceptionEvent(Dart_Handle exception,
-                                     Dart_StackTrace stack_trace) {
-  intptr_t exception_id = Dart_CacheObject(exception);
-  ASSERT(exception_id >= 0);
-  dart::TextBuffer msg(128);
-  msg.Printf("{ \"event\": \"paused\", \"params\": {");
-  msg.Printf("\"reason\": \"exception\", ");
-  msg.Printf("\"isolateId\": %" Pd64 ", ", isolate_id_);
-  msg.Printf("\"exception\":");
-  FormatRemoteObj(&msg, exception);
-  FormatLocationFromTrace(&msg, stack_trace, ", ");
-  msg.Printf("}}");
-  DebuggerConnectionHandler::BroadcastMsg(&msg);
-}
-
-
-// TODO(hausner): Remove stack trace parameter once we remove the stack
-// trace from the interrupted event in the wire protocol.
-void DbgMsgQueue::SendIsolateEvent(Dart_IsolateId isolate_id,
-                                   Dart_IsolateEvent kind) {
-  dart::TextBuffer msg(128);
-  if (kind == kInterrupted) {
-    Dart_StackTrace trace;
-    Dart_Handle res = Dart_GetStackTrace(&trace);
-    ASSERT_NOT_ERROR(res);
-    msg.Printf("{ \"event\": \"paused\", \"params\": { ");
-    msg.Printf("\"reason\": \"interrupted\", ");
-    msg.Printf("\"isolateId\": %" Pd64 "", isolate_id);
-    FormatLocationFromTrace(&msg, trace, ", ");
-    msg.Printf("}}");
-  } else {
-    msg.Printf("{ \"event\": \"isolate\", \"params\": { ");
-    if (kind == kCreated) {
-      msg.Printf("\"reason\": \"created\", ");
-    } else {
-      ASSERT(kind == kShutdown);
-      msg.Printf("\"reason\": \"shutdown\", ");
-    }
-    msg.Printf("\"id\": %" Pd64 " ", isolate_id);
-    msg.Printf("}}");
-  }
-  DebuggerConnectionHandler::BroadcastMsg(&msg);
-}
-
-
-DbgMsgQueue* DbgMsgQueueList::list_ = NULL;
-Mutex* DbgMsgQueueList::msg_queue_list_lock_ = new Mutex();
-
-
-void DbgMsgQueueList::Initialize() {
-  // Setup handlers for isolate events, breakpoints, exceptions and
-  // delayed breakpoints.
-  Dart_SetIsolateEventHandler(IsolateEventHandler);
-  Dart_SetPausedEventHandler(PausedEventHandler);
-  Dart_SetBreakpointResolvedHandler(BptResolvedHandler);
-  Dart_SetExceptionThrownHandler(ExceptionThrownHandler);
-}
-
-
-int32_t DbgMsgQueueList::LookupIsolateCommand(const char* buf,
-                                              int32_t buflen) {
-  // Check if we have a isolate specific debugger command.
-  int32_t i = 0;
-  while (debugger_commands[i].cmd_string != NULL) {
-    if (strncmp(buf, debugger_commands[i].cmd_string, buflen) == 0) {
-      return i;
-    }
-    i++;
-  }
-  return kInvalidCommand;
-}
-
-
-bool DbgMsgQueueList::AddIsolateMessage(Dart_IsolateId isolate_id,
-                                        int32_t cmd_idx,
-                                        const char* start,
-                                        const char* end,
-                                        intptr_t debug_fd) {
-  MutexLocker ml(msg_queue_list_lock_);
-  DbgMsgQueue* queue = DbgMsgQueueList::GetIsolateMsgQueueLocked(isolate_id);
-  if (queue != NULL) {
-    queue->AddMessage(cmd_idx, start, end, debug_fd);
-    return true;
-  }
-  return false;
-}
-
-
-void DbgMsgQueueList::NotifyIsolate(Dart_Isolate isolate) {
-  MutexLocker ml(msg_queue_list_lock_);
-  Dart_IsolateId isolate_id = Dart_GetIsolateId(isolate);
-  DbgMsgQueue* queue = DbgMsgQueueList::GetIsolateMsgQueueLocked(isolate_id);
-  if (queue != NULL) {
-    queue->Notify();
-  }
-}
-
-
-bool DbgMsgQueueList::InterruptIsolate(Dart_IsolateId isolate_id) {
-  MutexLocker ml(msg_queue_list_lock_);
-  DbgMsgQueue* queue = DbgMsgQueueList::GetIsolateMsgQueueLocked(isolate_id);
-  if (queue != NULL) {
-    queue->InterruptIsolate();
-    return true;
-  }
-  return false;
-}
-
-
-DbgMsgQueue* DbgMsgQueueList::AddIsolateMsgQueue(Dart_IsolateId isolate_id) {
-  MutexLocker ml(msg_queue_list_lock_);
-
-  DbgMsgQueue* queue = new DbgMsgQueue(isolate_id, list_);
-  ASSERT(queue != NULL);
-  list_ = queue;
-  return queue;
-}
-
-
-DbgMsgQueue* DbgMsgQueueList::GetIsolateMsgQueue(Dart_IsolateId isolate_id) {
-  MutexLocker ml(msg_queue_list_lock_);
-  ASSERT(Dart_GetIsolate(isolate_id) == Dart_CurrentIsolate());
-  return GetIsolateMsgQueueLocked(isolate_id);
-}
-
-
-DbgMsgQueue* DbgMsgQueueList::GetIsolateMsgQueueLocked(Dart_IsolateId id) {
-  if (list_ == NULL) {
-    return NULL;  // No items in the list.
-  }
-
-  // Find message queue corresponding to isolate id.
-  DbgMsgQueue* iterator = list_;
-  while (iterator != NULL && iterator->isolate_id() != id) {
-    iterator = iterator->next();
-  }
-  return iterator;
-}
-
-
-void DbgMsgQueueList::RemoveIsolateMsgQueue(Dart_IsolateId isolate_id) {
-  MutexLocker ml(msg_queue_list_lock_);
-  if (list_ == NULL) {
-    return;  // No items in the list.
-  }
-  DbgMsgQueue* queue = list_;
-  if (queue->isolate_id() == isolate_id) {
-    list_ = queue->next();  // Remove from list.
-    delete queue;  // Delete the message queue.
-    return;
-  } else {
-    DbgMsgQueue* iterator = queue;
-    queue = queue->next();
-    while (queue != NULL) {
-      if (queue->isolate_id() == isolate_id) {
-        iterator->set_next(queue->next());  // Remove from list.
-        delete queue;  // Delete the message queue.
-        return;
-      }
-      iterator = queue;
-      queue = queue->next();
-    }
-  }
-  UNREACHABLE();
-}
-
-
-void DbgMsgQueueList::ListIsolateIds(dart::TextBuffer* msg) {
-  MutexLocker ml(msg_queue_list_lock_);
-  if (list_ == NULL) {
-    return;  // No items in the list.
-  }
-  DbgMsgQueue* queue = list_;
-  msg->Printf("%" Pd64 "", queue->isolate_id());
-  queue = queue->next();
-  while (queue != NULL) {
-    msg->Printf(",%" Pd64 "", queue->isolate_id());
-    queue = queue->next();
-  }
-}
-
-
-void DbgMsgQueueList::BptResolvedHandler(Dart_IsolateId isolate_id,
-                                         intptr_t bp_id,
-                                         const Dart_CodeLocation& location) {
-  Dart_EnterScope();
-  dart::TextBuffer msg(128);
-  msg.Printf("{ \"event\": \"breakpointResolved\", \"params\": {");
-  msg.Printf("\"breakpointId\": %" Pd "", bp_id);
-
-  msg.Printf(", \"isolateId\":%" Pd64 "", isolate_id);
-  ASSERT(!Dart_IsNull(location.script_url));
-  ASSERT(Dart_IsString(location.script_url));
-  msg.Printf(", \"location\":{\"url\":");
-  FormatEncodedString(&msg, location.script_url);
-  msg.Printf(",\"libraryId\":%d", location.library_id);
-  msg.Printf(",\"tokenOffset\":%d}}}", location.token_pos);
-
-  DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id);
-  ASSERT(msg_queue != NULL);
-  msg_queue->QueueOutputMsg(&msg);
-  Dart_ExitScope();
-}
-
-
-void DbgMsgQueueList::PausedEventHandler(Dart_IsolateId isolate_id,
-                                         intptr_t bp_id,
-                                         const Dart_CodeLocation& loc) {
-  DebuggerConnectionHandler::WaitForConnection();
-  Dart_EnterScope();
-  DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id);
-  ASSERT(msg_queue != NULL);
-  msg_queue->SendQueuedMsgs();
-  msg_queue->SendBreakpointEvent(bp_id, loc);
-  msg_queue->MessageLoop();
-  Dart_ExitScope();
-}
-
-
-void DbgMsgQueueList::ExceptionThrownHandler(Dart_IsolateId isolate_id,
-                                             Dart_Handle exception,
-                                             Dart_StackTrace stack_trace) {
-  DebuggerConnectionHandler::WaitForConnection();
-  Dart_EnterScope();
-  DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id);
-  ASSERT(msg_queue != NULL);
-  msg_queue->SendQueuedMsgs();
-  msg_queue->SendExceptionEvent(exception, stack_trace);
-  msg_queue->MessageLoop();
-  Dart_ExitScope();
-}
-
-
-void DbgMsgQueueList::IsolateEventHandler(Dart_IsolateId isolate_id,
-                                          Dart_IsolateEvent kind) {
-  if (kind == kCreated) {
-    DebuggerConnectionHandler::WaitForConnection();
-    Dart_EnterScope();
-    DbgMsgQueue* msg_queue = AddIsolateMsgQueue(isolate_id);
-    msg_queue->SendIsolateEvent(isolate_id, kind);
-    Dart_ExitScope();
-  } else {
-    DebuggerConnectionHandler::WaitForConnection();
-    DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id);
-    ASSERT(msg_queue != NULL);
-    Dart_EnterScope();
-    msg_queue->SendQueuedMsgs();
-    msg_queue->SendIsolateEvent(isolate_id, kind);
-    if (kind == kInterrupted) {
-      msg_queue->MessageLoop();
-    } else {
-      ASSERT(kind == kShutdown);
-      RemoveIsolateMsgQueue(isolate_id);
-    }
-    Dart_ExitScope();
-    // If there is no receive message queue, do not wait for a connection, and
-    // ignore the message.
-  }
-}
-
-}  // namespace bin
-}  // namespace dart
diff --git a/runtime/bin/dbg_message.h b/runtime/bin/dbg_message.h
deleted file mode 100644
index 0714174..0000000
--- a/runtime/bin/dbg_message.h
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef BIN_DBG_MESSAGE_H_
-#define BIN_DBG_MESSAGE_H_
-
-#include "bin/builtin.h"
-#include "bin/thread.h"
-#include "bin/utils.h"
-
-#include "include/dart_tools_api.h"
-
-#include "platform/globals.h"
-#include "platform/json.h"
-
-
-namespace dart {
-namespace bin {
-
-// TODO(hausner): Need better error handling.
-#define ASSERT_NOT_ERROR(handle)          \
-  ASSERT(!Dart_IsError(handle))
-
-#define RETURN_IF_ERROR(handle)           \
-  if (Dart_IsError(handle)) {             \
-    return Dart_GetError(handle);         \
-  }
-
-
-// Class to parse a JSON debug command message.
-class MessageParser {
- public:
-  MessageParser(const char* buf, int buf_length)
-      : buf_(buf), buf_length_(buf_length) {
-  }
-  ~MessageParser() { }
-
-  // Accessors.
-  const char* buf() const { return buf_; }
-
-  bool IsValidMessage() const;
-  int MessageId() const;
-
-  const char* Params() const;
-  bool HasParam(const char* name) const;
-  intptr_t GetIntParam(const char* name) const;
-  int64_t GetInt64Param(const char* name) const;
-  intptr_t GetOptIntParam(const char* name, intptr_t default_val) const;
-
-  // GetStringParam mallocs the buffer that it returns. Caller must free.
-  char* GetStringParam(const char* name) const;
-
- private:
-  const char* buf_;
-  int buf_length_;
-
-  DISALLOW_COPY_AND_ASSIGN(MessageParser);
-};
-
-
-// Class which represents a debug command message and handles it.
-class DbgMessage {
- public:
-  DbgMessage(int32_t cmd_idx, const char* start,
-             const char* end, intptr_t debug_fd)
-      : next_(NULL), cmd_idx_(cmd_idx),
-        buffer_(NULL), buffer_len_(end - start),
-        debug_fd_(debug_fd) {
-    buffer_ = reinterpret_cast<char*>(malloc(buffer_len_));
-    ASSERT(buffer_ != NULL);
-    memmove(buffer_, start, buffer_len_);
-  }
-  ~DbgMessage() {
-    next_ = NULL;
-    free(buffer_);
-  }
-
-  // Accessors.
-  DbgMessage* next() const { return next_; }
-  void set_next(DbgMessage* next) { next_ = next; }
-  char* buffer() const { return buffer_; }
-  int32_t buffer_len() const { return buffer_len_; }
-  intptr_t debug_fd() const { return debug_fd_; }
-
-  // Handle debugger command message.
-  // Returns true if the execution needs to resume after this message is
-  // handled, false otherwise.
-  bool HandleMessage();
-
-  // Send reply after successful handling of command.
-  void SendReply(dart::TextBuffer* msg);
-
-  // Reply error returned by the command handler.
-  void SendErrorReply(int msg_id, const char* err_msg);
-
-  // Handlers for specific commands, they are static because these
-  // functions are populated as function pointers into a dispatch table.
-  static bool HandleResumeCmd(DbgMessage* msg);
-  static bool HandleStepIntoCmd(DbgMessage* msg);
-  static bool HandleStepOverCmd(DbgMessage* msg);
-  static bool HandleStepOutCmd(DbgMessage* msg);
-  static bool HandleGetLibrariesCmd(DbgMessage* msg);
-  static bool HandleGetClassPropsCmd(DbgMessage* msg);
-  static bool HandleGetLibPropsCmd(DbgMessage* msg);
-  static bool HandleSetLibPropsCmd(DbgMessage* msg);
-  static bool HandleGetGlobalsCmd(DbgMessage* msg);
-  static bool HandleEvaluateExprCmd(DbgMessage* msg);
-  static bool HandleGetObjPropsCmd(DbgMessage* msg);
-  static bool HandleGetListCmd(DbgMessage* msg);
-  static bool HandleGetScriptURLsCmd(DbgMessage* msg);
-  static bool HandleGetSourceCmd(DbgMessage* msg);
-  static bool HandleGetLineNumbersCmd(DbgMessage* msg);
-  static bool HandleGetStackTraceCmd(DbgMessage* msg);
-  static bool HandlePauseOnExcCmd(DbgMessage* msg);
-  static bool HandleSetBpCmd(DbgMessage* msg);
-  static bool HandleRemBpCmd(DbgMessage* msg);
-
- private:
-  DbgMessage* next_;  // Next message in the queue.
-  int32_t cmd_idx_;  // Isolate specific debugger command index.
-  char* buffer_;  // Debugger command message.
-  int32_t buffer_len_;  // Length of the debugger command message.
-  intptr_t debug_fd_;  // Debugger connection on which replies are to be sent.
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(DbgMessage);
-};
-
-
-// Class which represents a queue of debug command messages sent to an isolate.
-class DbgMsgQueue {
- public:
-  DbgMsgQueue(Dart_IsolateId isolate_id, DbgMsgQueue* next)
-      : is_running_(true),
-        is_interrupted_(false),
-        msglist_head_(NULL),
-        msglist_tail_(NULL),
-        queued_output_messages_(64),
-        isolate_id_(isolate_id),
-        next_(next) {
-  }
-  ~DbgMsgQueue() {
-    DbgMessage* msg = msglist_head_;
-    while (msglist_head_ != NULL) {
-      msglist_head_ = msglist_head_->next();
-      delete msg;
-      msg = msglist_head_;
-    }
-    msglist_tail_ = NULL;
-    isolate_id_ = ILLEGAL_ISOLATE_ID;
-    next_ = NULL;
-  }
-
-  // Accessors.
-  Dart_IsolateId isolate_id() const { return isolate_id_; }
-  DbgMsgQueue* next() const { return next_; }
-  void set_next(DbgMsgQueue* next) { next_ = next; }
-
-  // Add specified debug command message to the queue.
-  void AddMessage(int32_t cmd_idx,
-                  const char* start,
-                  const char* end,
-                  intptr_t debug_fd);
-
-  // Notify an isolate of a pending vmservice message.
-  void Notify();
-
-  // Run a message loop which handles messages as they arrive until
-  // normal program execution resumes.
-  void MessageLoop();
-
-  // Handle any pending debug command messages in the queue.  Return
-  // value indicates whether a resume has been requested.
-  bool HandlePendingMessages();
-
-  // Interrupt Isolate.
-  void InterruptIsolate();
-
-  // Queue output messages, these are sent out when we hit an event.
-  void QueueOutputMsg(dart::TextBuffer* msg);
-
-  // Send all queued messages over to the debugger.
-  void SendQueuedMsgs();
-
-  // Send breakpoint event message over to the debugger.
-  void SendBreakpointEvent(intptr_t bp_id, const Dart_CodeLocation& location);
-
-  // Send Exception event message over to the debugger.
-  void SendExceptionEvent(Dart_Handle exception, Dart_StackTrace trace);
-
-  // Send Isolate event message over to the debugger.
-  void SendIsolateEvent(Dart_IsolateId isolate_id, Dart_IsolateEvent kind);
-
- private:
-  bool is_running_;  // True if isolate is running and not in the debugger loop.
-  bool is_interrupted_;  // True if interrupt command is pending.
-
-  DbgMessage* msglist_head_;  // Start of debugger messages list.
-  DbgMessage* msglist_tail_;  // End of debugger messages list.
-
-  // Text buffer that accumulates messages to be output.
-  dart::TextBuffer queued_output_messages_;
-
-  Dart_IsolateId isolate_id_;  // Id of the isolate tied to this queue.
-
-  DbgMsgQueue* next_;  // Used for creating a list of message queues.
-
-  // The isolate waits on this condition variable when it needs to process
-  // debug messages.
-  Monitor msg_queue_lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(DbgMsgQueue);
-};
-
-
-// Maintains a list of message queues.
-class DbgMsgQueueList {
- public:
-  static const int32_t kInvalidCommand = -1;
-
-  // Initialize the message queue processing by setting up the appropriate
-  // handlers.
-  static void Initialize();
-
-  // Parses the input message and returns the command index if the message
-  // contains a valid isolate specific command.
-  // It returns kInvalidCommand otherwise.
-  static int32_t LookupIsolateCommand(const char* buf, int32_t buflen);
-
-  // Queue debugger message targetted for the isolate.
-  static bool AddIsolateMessage(Dart_IsolateId isolate_id,
-                                int32_t cmd_idx,
-                                const char* start,
-                                const char* end,
-                                intptr_t debug_fd);
-
-  // Notify an isolate of a pending vmservice message.
-  static void NotifyIsolate(Dart_Isolate isolate);
-
-  // Interrupt isolate.
-  static bool InterruptIsolate(Dart_IsolateId isolate_id);
-
-  // Add Debugger Message Queue corresponding to the Isolate.
-  static DbgMsgQueue* AddIsolateMsgQueue(Dart_IsolateId isolate_id);
-
-  // Get Debugger Message Queue corresponding to the Isolate.
-  static DbgMsgQueue* GetIsolateMsgQueue(Dart_IsolateId isolate_id);
-
-  // Remove Debugger Message Queue corresponding to the Isolate.
-  static void RemoveIsolateMsgQueue(Dart_IsolateId isolate_id);
-
-  // Generic handlers for breakpoints, exceptions and delayed breakpoint
-  // resolution.
-  static void BptResolvedHandler(Dart_IsolateId isolate_id,
-                                 intptr_t bp_id,
-                                 const Dart_CodeLocation& location);
-  static void PausedEventHandler(Dart_IsolateId isolate_id,
-                                 intptr_t bp_id,
-                                 const Dart_CodeLocation& loc);
-  static void ExceptionThrownHandler(Dart_IsolateId isolate_id,
-                                     Dart_Handle exception,
-                                     Dart_StackTrace stack_trace);
-  static void IsolateEventHandler(Dart_IsolateId isolate_id,
-                                  Dart_IsolateEvent kind);
-
-  // Print list of isolate ids of all message queues into text buffer.
-  static void ListIsolateIds(dart::TextBuffer* msg);
-
- private:
-  static DbgMsgQueue* GetIsolateMsgQueueLocked(Dart_IsolateId isolate_id);
-
-  static DbgMsgQueue* list_;
-  static Mutex* msg_queue_list_lock_;
-
-  DISALLOW_ALLOCATION();
-  DISALLOW_IMPLICIT_CONSTRUCTORS(DbgMsgQueueList);
-};
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // BIN_DBG_MESSAGE_H_
diff --git a/runtime/bin/embedded_dart_io.cc b/runtime/bin/embedded_dart_io.cc
index 1b3f40b..9e38f02 100644
--- a/runtime/bin/embedded_dart_io.cc
+++ b/runtime/bin/embedded_dart_io.cc
@@ -5,6 +5,7 @@
 #include "bin/embedded_dart_io.h"
 
 #include "bin/eventhandler.h"
+#include "bin/utils.h"
 #include "bin/thread.h"
 
 namespace dart {
@@ -13,6 +14,7 @@
 void BootstrapDartIo() {
   // Bootstrap 'dart:io' event handler.
   Thread::InitOnce();
+  TimerUtils::InitOnce();
   EventHandler::Start();
 }
 
diff --git a/runtime/bin/embedded_dart_io.h b/runtime/bin/embedded_dart_io.h
index e19b21a..4d7dbae 100644
--- a/runtime/bin/embedded_dart_io.h
+++ b/runtime/bin/embedded_dart_io.h
@@ -11,6 +11,19 @@
 // Bootstraps 'dart:io'.
 void BootstrapDartIo();
 
+// Tells the system whether to capture Stdout events.
+void SetCaptureStdout(bool value);
+
+// Tells the system whether to capture Stderr events.
+void SetCaptureStderr(bool value);
+
+// Should Stdout events be captured?
+bool ShouldCaptureStdout();
+
+// Should Stderr events be captured?
+bool ShouldCaptureStderr();
+
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/eventhandler.cc b/runtime/bin/eventhandler.cc
index 9e53d5f..bb9a7fe 100644
--- a/runtime/bin/eventhandler.cc
+++ b/runtime/bin/eventhandler.cc
@@ -131,5 +131,12 @@
   event_handler->SendData(id, dart_port, data);
 }
 
+
+void FUNCTION_NAME(EventHandler_TimerMillisecondClock)(
+    Dart_NativeArguments args) {
+  int64_t now = TimerUtils::GetCurrentMonotonicMillis();
+  Dart_SetReturnValue(args, Dart_NewInteger(now));
+}
+
 }  // namespace bin
 }  // namespace dart
diff --git a/runtime/bin/eventhandler_android.cc b/runtime/bin/eventhandler_android.cc
index 14cddc1..6fdabfb 100644
--- a/runtime/bin/eventhandler_android.cc
+++ b/runtime/bin/eventhandler_android.cc
@@ -333,7 +333,7 @@
     return kInfinityTimeout;
   }
   int64_t millis = timeout_queue_.CurrentTimeout() -
-      TimerUtils::GetCurrentTimeMilliseconds();
+      TimerUtils::GetCurrentMonotonicMillis();
   return (millis < 0) ? 0 : millis;
 }
 
@@ -341,7 +341,7 @@
 void EventHandlerImplementation::HandleTimeout() {
   if (timeout_queue_.HasTimeout()) {
     int64_t millis = timeout_queue_.CurrentTimeout() -
-        TimerUtils::GetCurrentTimeMilliseconds();
+        TimerUtils::GetCurrentMonotonicMillis();
     if (millis <= 0) {
       DartUtils::PostNull(timeout_queue_.CurrentPort());
       timeout_queue_.RemoveCurrent();
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index f28481f..4c605ce 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -109,7 +109,7 @@
   if (status == -1) {
     FATAL("Failed adding interrupt fd to epoll instance");
   }
-  timer_fd_ = NO_RETRY_EXPECTED(timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC));
+  timer_fd_ = NO_RETRY_EXPECTED(timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC));
   if (timer_fd_ == -1) {
     FATAL1("Failed creating timerfd file descriptor: %i", errno);
   }
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index fa2dbf6..faf471b 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -132,7 +132,7 @@
   if (status == -1) {
     const int kBufferSize = 1024;
     char error_message[kBufferSize];
-    strerror_r(errno, error_message, kBufferSize);
+    Utils::StrError(errno, error_message, kBufferSize);
     FATAL1("Failed adding interrupt fd to kqueue: %s\n", error_message);
   }
 }
@@ -358,7 +358,7 @@
     if ((events[i].flags & EV_ERROR) != 0) {
       const int kBufferSize = 1024;
       char error_message[kBufferSize];
-      strerror_r(events[i].data, error_message, kBufferSize);
+      Utils::StrError(events[i].data, error_message, kBufferSize);
       FATAL1("kevent failed %s\n", error_message);
     }
     if (events[i].udata == NULL) {
@@ -394,7 +394,7 @@
     return kInfinityTimeout;
   }
   int64_t millis = timeout_queue_.CurrentTimeout() -
-      TimerUtils::GetCurrentTimeMilliseconds();
+      TimerUtils::GetCurrentMonotonicMillis();
   return (millis < 0) ? 0 : millis;
 }
 
@@ -402,7 +402,7 @@
 void EventHandlerImplementation::HandleTimeout() {
   if (timeout_queue_.HasTimeout()) {
     int64_t millis = timeout_queue_.CurrentTimeout() -
-        TimerUtils::GetCurrentTimeMilliseconds();
+        TimerUtils::GetCurrentMonotonicMillis();
     if (millis <= 0) {
       DartUtils::PostNull(timeout_queue_.CurrentPort());
       timeout_queue_.RemoveCurrent();
@@ -440,7 +440,7 @@
     if (result == -1) {
       const int kBufferSize = 1024;
       char error_message[kBufferSize];
-      strerror_r(errno, error_message, kBufferSize);
+      Utils::StrError(errno, error_message, kBufferSize);
       FATAL1("kevent failed %s\n", error_message);
     } else {
       handler_impl->HandleTimeout();
diff --git a/runtime/bin/eventhandler_patch.dart b/runtime/bin/eventhandler_patch.dart
index 3dcce2d..d92271b 100644
--- a/runtime/bin/eventhandler_patch.dart
+++ b/runtime/bin/eventhandler_patch.dart
@@ -9,5 +9,8 @@
                                     SendPort sendPort,
                                     int data)
       native "EventHandler_SendData";
+
+  static int _timerMillisecondClock()
+      native "EventHandler_TimerMillisecondClock";
 }
 
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 33f59d6..8e0adc5 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -1352,7 +1352,7 @@
     return kInfinityTimeout;
   }
   int64_t millis = timeout_queue_.CurrentTimeout() -
-      TimerUtils::GetCurrentTimeMilliseconds();
+      TimerUtils::GetCurrentMonotonicMillis();
   return (millis < 0) ? 0 : millis;
 }
 
diff --git a/runtime/bin/extensions.cc b/runtime/bin/extensions.cc
index 3b02971..eaed7bb 100644
--- a/runtime/bin/extensions.cc
+++ b/runtime/bin/extensions.cc
@@ -29,19 +29,20 @@
   void* library_handle = LoadExtensionLibrary(library_file);
   free(library_file);
   if (library_handle == NULL) {
-    return Dart_NewApiError("Cannot find extension library");
+    return GetError();
   }
 
   const char* strings[] = { extension_name, "_Init", NULL };
   char* init_function_name = Concatenate(strings);
-  typedef Dart_Handle (*InitFunctionType)(Dart_Handle import_map);
-  InitFunctionType fn = reinterpret_cast<InitFunctionType>(
-      ResolveSymbol(library_handle, init_function_name));
+  void* init_function = ResolveSymbol(library_handle, init_function_name);
   free(init_function_name);
-
-  if (fn == NULL) {
-    return Dart_NewApiError("Cannot find initialization function in extension");
+  Dart_Handle result = GetError();
+  if (Dart_IsError(result)) {
+    return result;
   }
+  ASSERT(init_function != NULL);
+  typedef Dart_Handle (*InitFunctionType)(Dart_Handle import_map);
+  InitFunctionType fn = reinterpret_cast<InitFunctionType>(init_function);
   return (*fn)(parent_library);
 }
 
diff --git a/runtime/bin/extensions.h b/runtime/bin/extensions.h
index 25dbfeb..8c172b8 100644
--- a/runtime/bin/extensions.h
+++ b/runtime/bin/extensions.h
@@ -26,6 +26,8 @@
   static void* ResolveSymbol(void* lib_handle, const char* symbol);
 
  private:
+  static Dart_Handle GetError();
+
   // The returned string must be freed.
   static char* Concatenate(const char** strings);
 
diff --git a/runtime/bin/extensions_android.cc b/runtime/bin/extensions_android.cc
index 1b79991..0c79bff 100644
--- a/runtime/bin/extensions_android.cc
+++ b/runtime/bin/extensions_android.cc
@@ -21,9 +21,15 @@
 
 void* Extensions::ResolveSymbol(void* lib_handle, const char* symbol) {
   dlerror();
-  void* result = dlsym(lib_handle, symbol);
-  if (dlerror() != NULL) return NULL;
-  return result;
+  return dlsym(lib_handle, symbol);
+}
+
+Dart_Handle Extensions::GetError() {
+  const char* err_str = dlerror();
+  if (err_str != NULL) {
+    return Dart_NewApiError(err_str);
+  }
+  return Dart_Null();
 }
 
 }  // namespace bin
diff --git a/runtime/bin/extensions_linux.cc b/runtime/bin/extensions_linux.cc
index 23ee6ed..e172f0d 100644
--- a/runtime/bin/extensions_linux.cc
+++ b/runtime/bin/extensions_linux.cc
@@ -21,9 +21,15 @@
 
 void* Extensions::ResolveSymbol(void* lib_handle, const char* symbol) {
   dlerror();
-  void* result = dlsym(lib_handle, symbol);
-  if (dlerror() != NULL) return NULL;
-  return result;
+  return dlsym(lib_handle, symbol);
+}
+
+Dart_Handle Extensions::GetError() {
+  const char* err_str = dlerror();
+  if (err_str != NULL) {
+    return Dart_NewApiError(err_str);
+  }
+  return Dart_Null();
 }
 
 }  // namespace bin
diff --git a/runtime/bin/extensions_macos.cc b/runtime/bin/extensions_macos.cc
index 92a5e98..e248a47 100644
--- a/runtime/bin/extensions_macos.cc
+++ b/runtime/bin/extensions_macos.cc
@@ -21,9 +21,15 @@
 
 void* Extensions::ResolveSymbol(void* lib_handle, const char* symbol) {
   dlerror();
-  void* result = dlsym(lib_handle, symbol);
-  if (dlerror() != NULL) return NULL;
-  return result;
+  return dlsym(lib_handle, symbol);
+}
+
+Dart_Handle Extensions::GetError() {
+  const char* err_str = dlerror();
+  if (err_str != NULL) {
+    return Dart_NewApiError(err_str);
+  }
+  return Dart_Null();
 }
 
 }  // namespace bin
diff --git a/runtime/bin/extensions_win.cc b/runtime/bin/extensions_win.cc
index 8c0a15f..d3b49f2 100644
--- a/runtime/bin/extensions_win.cc
+++ b/runtime/bin/extensions_win.cc
@@ -17,13 +17,24 @@
 const char* kPrecompiledSymbolName = "_kInstructionsSnapshot";
 
 void* Extensions::LoadExtensionLibrary(const char* library_file) {
+  SetLastError(0);
   return LoadLibraryW(StringUtilsWin::Utf8ToWide(library_file));
 }
 
 void* Extensions::ResolveSymbol(void* lib_handle, const char* symbol) {
+  SetLastError(0);
   return GetProcAddress(reinterpret_cast<HMODULE>(lib_handle), symbol);
 }
 
+Dart_Handle Extensions::GetError() {
+  int last_error = GetLastError();
+  if (last_error != 0) {
+    OSError err;
+    return Dart_NewApiError(err.message());
+  }
+  return Dart_Null();
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 8175d9b..1face6b 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -6,6 +6,7 @@
 
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
+#include "bin/embedded_dart_io.h"
 #include "bin/io_buffer.h"
 #include "bin/utils.h"
 
@@ -17,14 +18,32 @@
 
 static const int kMSPerSecond = 1000;
 
-// Are we capturing output from either stdout or stderr for the VM Service?
-bool capture_stdio = false;
-
 // Are we capturing output from stdout for the VM service?
-bool capture_stdout = false;
+static bool capture_stdout = false;
 
 // Are we capturing output from stderr for the VM service?
-bool capture_stderr = false;
+static bool capture_stderr = false;
+
+
+void SetCaptureStdout(bool value) {
+  capture_stdout = value;
+}
+
+
+void SetCaptureStderr(bool value) {
+  capture_stderr = value;
+}
+
+
+bool ShouldCaptureStdout() {
+  return capture_stdout;
+}
+
+
+bool ShouldCaptureStderr() {
+  return capture_stderr;
+}
+
 
 
 // The file pointer has been passed into Dart as an intptr_t and it is safe
@@ -62,7 +81,7 @@
     remaining -= bytes_written;  // Reduce the number of remaining bytes.
     current_buffer += bytes_written;  // Move the buffer forward.
   }
-  if (capture_stdio) {
+  if (capture_stdout || capture_stderr) {
     intptr_t fd = GetFD();
     if (fd == STDOUT_FILENO && capture_stdout) {
       Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 35b6388..cc29740 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -19,6 +19,7 @@
 #include "bin/log.h"
 
 #include "platform/signal_blocker.h"
+#include "platform/utils.h"
 
 
 namespace dart {
@@ -57,7 +58,7 @@
     if (err != 0) {
       const int kBufferSize = 1024;
       char error_message[kBufferSize];
-      strerror_r(errno, error_message, kBufferSize);
+      Utils::StrError(errno, error_message, kBufferSize);
       Log::PrintErr("%s\n", error_message);
     }
   }
@@ -422,7 +423,7 @@
   if (result == -1) {
     const int kBufferSize = 1024;
     char error_message[kBufferSize];
-    strerror_r(errno, error_message, kBufferSize);
+    Utils::StrError(errno, error_message, kBufferSize);
     FATAL2("Failed stat on file descriptor %d: %s", fd, error_message);
   }
   if (S_ISCHR(buf.st_mode)) return kTerminal;
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index ff801ad..d289c21 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -15,9 +15,10 @@
 #include <unistd.h>  // NOLINT
 #include <libgen.h>  // NOLINT
 
-#include "platform/signal_blocker.h"
 #include "bin/builtin.h"
 #include "bin/log.h"
+#include "platform/signal_blocker.h"
+#include "platform/utils.h"
 
 
 namespace dart {
@@ -56,7 +57,7 @@
     if (err != 0) {
       const int kBufferSize = 1024;
       char error_buf[kBufferSize];
-      Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize));
+      Log::PrintErr("%s\n", Utils::StrError(errno, error_buf, kBufferSize));
     }
   }
   handle_->set_fd(kClosedFd);
@@ -429,7 +430,7 @@
     const int kBufferSize = 1024;
     char error_buf[kBufferSize];
     FATAL2("Failed stat on file descriptor %d: %s", fd,
-           strerror_r(errno, error_buf, kBufferSize));
+           Utils::StrError(errno, error_buf, kBufferSize));
   }
   if (S_ISCHR(buf.st_mode)) return kTerminal;
   if (S_ISFIFO(buf.st_mode)) return kPipe;
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index ddc19cc..6187e94 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -20,6 +20,7 @@
 #include "bin/log.h"
 
 #include "platform/signal_blocker.h"
+#include "platform/utils.h"
 
 namespace dart {
 namespace bin {
@@ -57,7 +58,7 @@
     if (err != 0) {
       const int kBufferSize = 1024;
       char error_message[kBufferSize];
-      strerror_r(errno, error_message, kBufferSize);
+      Utils::StrError(errno, error_message, kBufferSize);
       Log::PrintErr("%s\n", error_message);
     }
   }
@@ -394,7 +395,7 @@
   if (result == -1) {
     const int kBufferSize = 1024;
     char error_message[kBufferSize];
-    strerror_r(errno, error_message, kBufferSize);
+    Utils::StrError(errno, error_message, kBufferSize);
     FATAL2("Failed stat on file descriptor %d: %s", fd, error_message);
   }
   if (S_ISCHR(buf.st_mode)) return kTerminal;
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 72ee0f1..0e12574 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -9,13 +9,18 @@
 #include <string.h>
 #include <stdio.h>
 
+#include <cstdarg>
+
 #include "include/dart_api.h"
 
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
+#include "bin/eventhandler.h"
 #include "bin/file.h"
 #include "bin/log.h"
 #include "bin/thread.h"
+#include "bin/utils.h"
+#include "bin/vmservice_impl.h"
 
 #include "platform/globals.h"
 
@@ -36,6 +41,8 @@
 // if so which file to write the snapshot into.
 static const char* vm_isolate_snapshot_filename = NULL;
 static const char* isolate_snapshot_filename = NULL;
+static const char* instructions_snapshot_filename = NULL;
+static const char* embedder_entry_points_manifest = NULL;
 static const char* package_root = NULL;
 
 
@@ -86,6 +93,26 @@
 }
 
 
+static bool ProcessInstructionsSnapshotOption(const char* option) {
+  const char* name = ProcessOption(option, "--instructions_snapshot=");
+  if (name != NULL) {
+    instructions_snapshot_filename = name;
+    return true;
+  }
+  return false;
+}
+
+
+static bool ProcessEmbedderEntryPointsManifestOption(const char* option) {
+  const char* name = ProcessOption(option, "--embedder_entry_points_manifest=");
+  if (name != NULL) {
+    embedder_entry_points_manifest = name;
+    return true;
+  }
+  return false;
+}
+
+
 static bool ProcessPackageRootOption(const char* option) {
   const char* name = ProcessOption(option, "--package_root=");
   if (name != NULL) {
@@ -125,6 +152,8 @@
   while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
     if (ProcessVmIsolateSnapshotOption(argv[i]) ||
         ProcessIsolateSnapshotOption(argv[i]) ||
+        ProcessInstructionsSnapshotOption(argv[i]) ||
+        ProcessEmbedderEntryPointsManifestOption(argv[i]) ||
         ProcessURLmappingOption(argv[i]) ||
         ProcessPackageRootOption(argv[i])) {
       i += 1;
@@ -152,10 +181,32 @@
     return -1;
   }
 
+  if (instructions_snapshot_filename != NULL &&
+      embedder_entry_points_manifest == NULL) {
+    Log::PrintErr(
+        "Specifying an instructions snapshot filename indicates precompilation"
+        ". But no embedder entry points manifest was specified.\n\n");
+    return -1;
+  }
+
+  if (embedder_entry_points_manifest != NULL &&
+      instructions_snapshot_filename == NULL) {
+    Log::PrintErr(
+        "Specifying the embedder entry points manifest indicates "
+        "precompilation. But no instuctions snapshot was specified.\n\n");
+    return -1;
+  }
+
   return 0;
 }
 
 
+static bool IsSnapshottingForPrecompilation(void) {
+  return embedder_entry_points_manifest != NULL &&
+         instructions_snapshot_filename != NULL;
+}
+
+
 static void WriteSnapshotFile(const char* filename,
                               const uint8_t* buffer,
                               const intptr_t size) {
@@ -419,26 +470,50 @@
 
 static void PrintUsage() {
   Log::PrintErr(
-"Usage:\n"
-"\n"
-"  gen_snapshot [<vm-flags>] [<options>] \\\n"
-"               --snapshot=<out-file> [<dart-script-file>]\n"
-"\n"
-"  Writes a snapshot of <dart-script-file> to <out-file>. If no\n"
-"  <dart-script-file> is passed, a generic snapshot of all the corelibs is\n"
-"  created. It is required to specify an output file name:\n"
-"\n"
-"    --snapshot=<file>          Generates a complete snapshot. Uses the url\n"
-"                               mapping specified on the command line to load\n"
-"                               the libraries.\n"
-"Supported options:\n"
-"\n"
-"--package_root=<path>\n"
-"  Where to find packages, that is, \"package:...\" imports.\n"
-"\n"
-"--url_mapping=<mapping>\n"
-"  Uses the URL mapping(s) specified on the command line to load the\n"
-"  libraries. For use only with --snapshot=.\n");
+"Usage:                                                                      \n"
+" gen_snapshot [<vm-flags>] [<options>] [<dart-script-file>]                 \n"
+"                                                                            \n"
+"  Writes a snapshot of <dart-script-file> to the specified snapshot files.  \n"
+"  If no <dart-script-file> is passed, a generic snapshot of all the corelibs\n"
+"  is created. It is required to specify the VM isolate snapshot and the     \n"
+"  isolate snapshot. The other flags are related to precompilation and are   \n"
+"  optional.                                                                 \n"
+"                                                                            \n"
+"  Precompilation:                                                           \n"
+"  In order to configure the snapshotter for precompilation, both the        \n"
+"  instructions snapshot and embedder entry points manifest must be          \n"
+"  specified. Assembly for the target architecture will be dumped into the   \n"
+"  instructions snapshot. This must be linked into the target binary in a    \n"
+"  separate step. The embedder entry points manifest lists the standalone    \n"
+"  entry points into the VM. Not specifying these will cause the tree shaker \n"
+"  to disregard the same as being used. The format of this manifest is as    \n"
+"  follows. Each line in the manifest is a comma separated list of three     \n"
+"  elements. The first entry is the library URI, the second entry is the     \n"
+"  class name and the final entry the function name. The file must be        \n"
+"  terminated with a newline charater.                                       \n"
+"                                                                            \n"
+"    Example:                                                                \n"
+"      dart:something,SomeClass,doSomething                                  \n"
+"                                                                            \n"
+"  Supported options:                                                        \n"
+"    --vm_isolate_snapshot=<file>      A full snapshot is a compact          \n"
+"    --isolate_snapshot=<file>         representation of the dart vm isolate \n"
+"                                      heap and dart isolate heap states.    \n"
+"                                      Both these options are required       \n"
+"                                                                            \n"
+"    --package_root=<path>             Where to find packages, that is,      \n"
+"                                      package:...  imports.                 \n"
+"                                                                            \n"
+"    --url_mapping=<mapping>           Uses the URL mapping(s) specified on  \n"
+"                                      the command line to load the          \n"
+"                                      libraries.                            \n"
+"                                                                            \n"
+"    --instructions_snapshot=<file>    (Precompilation only) Contains the    \n"
+"                                      assembly that must be linked into     \n"
+"                                      the target binary                     \n"
+"                                                                            \n"
+"    --embedder_entry_points_manifest=<file> (Precompilation only) Contains  \n"
+"                                      the stanalone embedder entry points\n");
 }
 
 
@@ -454,7 +529,326 @@
 }
 
 
+static const char StubNativeFunctionName[] = "StubNativeFunction";
+
+
+void StubNativeFunction(Dart_NativeArguments arguments) {
+  // This is a stub function for the resolver
+  UNREACHABLE();
+}
+
+
+static Dart_NativeFunction StubNativeLookup(Dart_Handle name,
+                                            int argument_count,
+                                            bool* auto_setup_scope) {
+  return &StubNativeFunction;
+}
+
+
+static const uint8_t* StubNativeSymbol(Dart_NativeFunction nf) {
+  return reinterpret_cast<const uint8_t *>(StubNativeFunctionName);
+}
+
+
+static void SetupStubNativeResolver(size_t lib_index,
+                                    const Dart_QualifiedFunctionName* entry) {
+  // TODO(24686): Remove this.
+  Dart_Handle library_string = Dart_NewStringFromCString(entry->library_uri);
+  DART_CHECK_VALID(library_string);
+  Dart_Handle library = Dart_LookupLibrary(library_string);
+  // Embedder entry points may be setup in libraries that have not been
+  // explicitly loaded by the application script. In such cases, library lookup
+  // will fail. Manually load those libraries.
+  if (Dart_IsError(library)) {
+    static const uint32_t kLoadBufferMaxSize = 128;
+    char* load_buffer =
+        reinterpret_cast<char*>(calloc(kLoadBufferMaxSize, sizeof(char)));
+    snprintf(load_buffer,
+             kLoadBufferMaxSize,
+             "import '%s';",
+             DartUtils::GetStringValue(library_string));
+    Dart_Handle script_handle = Dart_NewStringFromCString(load_buffer);
+    memset(load_buffer, 0, kLoadBufferMaxSize);
+    snprintf(load_buffer,
+             kLoadBufferMaxSize,
+             "dart:_snapshot_%zu",
+             lib_index);
+    Dart_Handle script_url = Dart_NewStringFromCString(load_buffer);
+    free(load_buffer);
+    Dart_Handle loaded = Dart_LoadLibrary(script_url, script_handle, 0, 0);
+    DART_CHECK_VALID(loaded);
+
+    // Do a fresh lookup
+    library = Dart_LookupLibrary(library_string);
+  }
+
+  DART_CHECK_VALID(library);
+  Dart_Handle result =  Dart_SetNativeResolver(library,
+                                               &StubNativeLookup,
+                                               &StubNativeSymbol);
+  DART_CHECK_VALID(result);
+}
+
+
+static void ImportNativeEntryPointLibrariesIntoRoot(
+    const Dart_QualifiedFunctionName* entries) {
+  if (entries == NULL) {
+    return;
+  }
+
+  size_t index = 0;
+  while (true) {
+    Dart_QualifiedFunctionName entry = entries[index++];
+    if (entry.library_uri == NULL) {
+      // The termination sentinel has null members.
+      break;
+    }
+    Dart_Handle entry_library =
+        Dart_LookupLibrary(Dart_NewStringFromCString(entry.library_uri));
+    DART_CHECK_VALID(entry_library);
+    Dart_Handle import_result = Dart_LibraryImportLibrary(
+        entry_library, Dart_RootLibrary(), Dart_EmptyString());
+    DART_CHECK_VALID(import_result);
+  }
+}
+
+
+static void SetupStubNativeResolversForPrecompilation(
+    const Dart_QualifiedFunctionName* entries) {
+
+  if (entries == NULL) {
+    return;
+  }
+
+  // Setup native resolvers for all libraries found in the manifest.
+  size_t index = 0;
+  while (true) {
+    Dart_QualifiedFunctionName entry = entries[index++];
+    if (entry.library_uri == NULL) {
+      // The termination sentinel has null members.
+      break;
+    }
+    // Setup stub resolvers on loaded libraries
+    SetupStubNativeResolver(index, &entry);
+  }
+}
+
+
+static void CleanupEntryPointItem(const Dart_QualifiedFunctionName *entry) {
+  if (entry == NULL) {
+    return;
+  }
+  // The allocation used for these entries is zero'ed. So even in error cases,
+  // references to some entries will be null. Calling this on an already cleaned
+  // up entry is programmer error.
+  free(const_cast<char*>(entry->library_uri));
+  free(const_cast<char*>(entry->class_name));
+  free(const_cast<char*>(entry->function_name));
+}
+
+
+static void CleanupEntryPointsCollection(Dart_QualifiedFunctionName* entries) {
+  if (entries == NULL) {
+    return;
+  }
+
+  size_t index = 0;
+  while (true) {
+    Dart_QualifiedFunctionName entry = entries[index++];
+    if (entry.library_uri == NULL) {
+      break;
+    }
+    CleanupEntryPointItem(&entry);
+  }
+  free(entries);
+}
+
+
+char* ParserErrorStringCreate(const char* format, ...) {
+  static const size_t kErrorBufferSize = 256;
+
+  char* error_buffer =
+      reinterpret_cast<char*>(calloc(kErrorBufferSize, sizeof(char)));
+  va_list args;
+  va_start(args, format);
+  vsnprintf(error_buffer, kErrorBufferSize, format, args);
+  va_end(args);
+
+  // In case of error, the buffer is released by the caller
+  return error_buffer;
+}
+
+
+const char* ParseEntryNameForIndex(uint8_t index) {
+  switch (index) {
+    case 0:
+      return "Library";
+    case 1:
+      return "Class";
+    case 2:
+      return "Function";
+    default:
+      return "Unknown";
+  }
+  return NULL;
+}
+
+
+static bool ParseEntryPointsManifestSingleLine(
+    const char* line, Dart_QualifiedFunctionName* entry, char** error) {
+  bool success = true;
+  size_t offset = 0;
+  for (uint8_t i = 0; i < 3; i++) {
+    const char* component = strchr(line + offset, i == 2 ? '\n' : ',');
+    if (component == NULL) {
+      success = false;
+      *error = ParserErrorStringCreate(
+          "Manifest entries must be comma separated and newline terminated. "
+          "Could not parse '%s' on line '%s'",
+          ParseEntryNameForIndex(i), line);
+      break;
+    }
+
+    int64_t chars_read = component - (line + offset);
+    if (chars_read <= 0) {
+      success = false;
+      *error =
+          ParserErrorStringCreate("There is no '%s' specified on line '%s'",
+                                  ParseEntryNameForIndex(i), line);
+      break;
+    }
+
+    if (entry != NULL) {
+      // These allocations are collected in |CleanupEntryPointsCollection|.
+      char* entry_item =
+          reinterpret_cast<char*>(calloc(chars_read + 1, sizeof(char)));
+      memmove(entry_item, line + offset, chars_read);
+
+      switch (i) {
+        case 0:  // library
+          entry->library_uri = entry_item;
+          break;
+        case 1:  // class
+          entry->class_name = entry_item;
+          break;
+        case 2:  // function
+          entry->function_name = entry_item;
+          break;
+        default:
+          free(entry_item);
+          success = false;
+          *error = ParserErrorStringCreate("Internal parser error\n");
+          break;
+      }
+    }
+
+    offset += chars_read + 1;
+  }
+  return success;
+}
+
+
+int64_t ParseEntryPointsManifestLines(FILE* file,
+                                      Dart_QualifiedFunctionName* collection) {
+  int64_t entries = 0;
+
+  static const int kManifestMaxLineLength = 1024;
+  char* line = reinterpret_cast<char*>(malloc(kManifestMaxLineLength));
+  size_t line_number = 0;
+  while (true) {
+    line_number++;
+    char* read_line = fgets(line, kManifestMaxLineLength, file);
+
+    if (read_line == NULL) {
+      if ((feof(file) != 0) && (ferror(file) != 0)) {
+        Log::PrintErr(
+            "Error while reading line number %zu. The manifest must be "
+            "terminated by a newline\n",
+            line_number);
+        entries = -1;
+      }
+      break;
+    }
+
+    Dart_QualifiedFunctionName* entry =
+        collection != NULL ? collection + entries : NULL;
+
+    char* error_buffer = NULL;
+    if (!ParseEntryPointsManifestSingleLine(read_line, entry, &error_buffer)) {
+      CleanupEntryPointItem(entry);
+      Log::PrintErr("Parser error on line %zu: %s\n", line_number,
+                    error_buffer);
+      free(error_buffer);
+      entries = -1;
+      break;
+    }
+
+    entries++;
+  }
+
+  free(line);
+
+  return entries;
+}
+
+
+static Dart_QualifiedFunctionName* ParseEntryPointsManifestFile(
+    const char* path) {
+  if (path == NULL) {
+    return NULL;
+  }
+
+  FILE* file = fopen(path, "r");
+
+  if (file == NULL) {
+    Log::PrintErr("Could not open entry points manifest file\n");
+    return NULL;
+  }
+
+  // Parse the file once but don't store the results. This is done to first
+  // determine the number of entries in the manifest
+  int64_t entry_count = ParseEntryPointsManifestLines(file, NULL);
+
+  if (entry_count <= 0) {
+    Log::PrintErr(
+        "Manifest file specified is invalid or contained no entries\n");
+    fclose(file);
+    return NULL;
+  }
+
+  rewind(file);
+
+  // Allocate enough storage for the entries in the file plus a termination
+  // sentinel and parse it again to populate the allocation
+  Dart_QualifiedFunctionName* entries =
+      reinterpret_cast<Dart_QualifiedFunctionName*>(
+          calloc(entry_count + 1, sizeof(Dart_QualifiedFunctionName)));
+
+  int64_t parsed_entry_count = ParseEntryPointsManifestLines(file, entries);
+  ASSERT(parsed_entry_count == entry_count);
+
+  fclose(file);
+
+  // The entries allocation must be explicitly cleaned up via
+  // |CleanupEntryPointsCollection|
+  return entries;
+}
+
+
+static Dart_QualifiedFunctionName* ParseEntryPointsManifestIfPresent() {
+  Dart_QualifiedFunctionName* entries =
+      ParseEntryPointsManifestFile(embedder_entry_points_manifest);
+  if (entries == NULL && IsSnapshottingForPrecompilation()) {
+    Log::PrintErr(
+        "Could not find native embedder entry points during precompilation\n");
+    exit(255);
+  }
+  return entries;
+}
+
+
 static void CreateAndWriteSnapshot() {
+  ASSERT(!IsSnapshottingForPrecompilation());
   Dart_Handle result;
   uint8_t* vm_isolate_buffer = NULL;
   intptr_t vm_isolate_size = 0;
@@ -483,6 +877,49 @@
 }
 
 
+static void CreateAndWritePrecompiledSnapshot(
+    Dart_QualifiedFunctionName* standalone_entry_points) {
+  ASSERT(IsSnapshottingForPrecompilation());
+  Dart_Handle result;
+  uint8_t* vm_isolate_buffer = NULL;
+  intptr_t vm_isolate_size = 0;
+  uint8_t* isolate_buffer = NULL;
+  intptr_t isolate_size = 0;
+  uint8_t* instructions_buffer = NULL;
+  intptr_t instructions_size = 0;
+
+  // Precompile with specified embedder entry points
+  result = Dart_Precompile(standalone_entry_points, true);
+  CHECK_RESULT(result);
+
+  // Create a precompiled snapshot. This gives us an instruction buffer with
+  // machine code
+  result = Dart_CreatePrecompiledSnapshot(&vm_isolate_buffer,
+                                          &vm_isolate_size,
+                                          &isolate_buffer,
+                                          &isolate_size,
+                                          &instructions_buffer,
+                                          &instructions_size);
+  CHECK_RESULT(result);
+
+  // Now write the vm isolate, isolate and instructions snapshots out to the
+  // specified files and exit.
+  WriteSnapshotFile(vm_isolate_snapshot_filename,
+                    vm_isolate_buffer,
+                    vm_isolate_size);
+  WriteSnapshotFile(isolate_snapshot_filename,
+                    isolate_buffer,
+                    isolate_size);
+  WriteSnapshotFile(instructions_snapshot_filename,
+                    instructions_buffer,
+                    instructions_size);
+  Dart_ExitScope();
+
+  // Shutdown the isolate.
+  Dart_ShutdownIsolate();
+}
+
+
 static void SetupForUriResolution() {
   // Set up the library tag handler for this isolate.
   Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
@@ -515,6 +952,52 @@
 }
 
 
+static Dart_Isolate CreateServiceIsolate(const char* script_uri,
+                                         const char* main,
+                                         const char* package_root,
+                                         const char* package_config,
+                                         Dart_IsolateFlags* flags,
+                                         void* data,
+                                         char** error) {
+  Dart_Isolate isolate = NULL;
+  isolate = Dart_CreateIsolate(script_uri,
+                               main,
+                               NULL,
+                               NULL,
+                               NULL,
+                               error);
+
+  if (isolate == NULL) {
+    Log::PrintErr("Error: Could not create service isolate");
+    return NULL;
+  }
+
+  Dart_EnterScope();
+  if (!Dart_IsServiceIsolate(isolate)) {
+    Log::PrintErr("Error: We only expect to create the service isolate");
+    return NULL;
+  }
+  Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
+  // Setup the native resolver.
+  Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
+  Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
+  if (Dart_IsError(result)) {
+    Log::PrintErr("Error: Could not set tag handler for service isolate");
+    return NULL;
+  }
+  CHECK_RESULT(result);
+  ASSERT(Dart_IsServiceIsolate(isolate));
+  // Load embedder specific bits and return. Will not start http server.
+  if (!VmService::Setup("127.0.0.1", -1, false /* running_precompiled */)) {
+    *error = strdup(VmService::GetErrorMessage());
+    return NULL;
+  }
+  Dart_ExitScope();
+  Dart_ExitIsolate();
+  return isolate;
+}
+
+
 int main(int argc, char** argv) {
   const int EXTRA_VM_ARGUMENTS = 2;
   CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
@@ -534,23 +1017,41 @@
 
   Thread::InitOnce();
   DartUtils::SetOriginalWorkingDirectory();
+  // Start event handler.
+  TimerUtils::InitOnce();
+  EventHandler::Start();
 
   vm_options.AddArgument("--load_deferred_eagerly");
   // Workaround until issue 21620 is fixed.
   // (https://github.com/dart-lang/sdk/issues/21620)
   vm_options.AddArgument("--no-concurrent_sweep");
+
+  if (IsSnapshottingForPrecompilation()) {
+    vm_options.AddArgument("--precompilation");
+#if TARGET_ARCH_ARM
+    // This is for the iPod Touch 5th Generation (and maybe other older devices)
+    vm_options.AddArgument("--no-use_integer_division");
+#endif
+  }
+
   Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
 
   // Initialize the Dart VM.
   // Note: We don't expect isolates to be created from dart code during
   // snapshot generation.
-  char* error = Dart_Initialize(NULL, NULL,
-      NULL, NULL, NULL, NULL,
+  char* error = Dart_Initialize(
+      NULL,
+      NULL,
+      CreateServiceIsolate,
+      NULL,
+      NULL,
+      NULL,
       DartUtils::OpenFile,
       DartUtils::ReadFile,
       DartUtils::WriteFile,
       DartUtils::CloseFile,
-      DartUtils::EntropySource);
+      DartUtils::EntropySource,
+      NULL);
   if (error != NULL) {
     Log::PrintErr("VM initialization failed: %s\n", error);
     free(error);
@@ -594,7 +1095,6 @@
     result =
         DartUtils::PrepareForScriptLoading(package_root,
                                            NULL,
-                                           NULL,
                                            false,
                                            false,
                                            builtin_lib);
@@ -617,13 +1117,30 @@
     // URL mapping specified on the command line to load the libraries.
     result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
     CHECK_RESULT(result);
+
+    Dart_QualifiedFunctionName* entry_points =
+        ParseEntryPointsManifestIfPresent();
+
+    SetupStubNativeResolversForPrecompilation(entry_points);
+
     // Load the specified script.
     library = LoadSnapshotCreationScript(app_script_name);
     VerifyLoaded(library);
+
+    ImportNativeEntryPointLibrariesIntoRoot(entry_points);
+
     // Ensure that we mark all libraries as loaded.
     result = Dart_FinalizeLoading(false);
     CHECK_RESULT(result);
-    CreateAndWriteSnapshot();
+
+    if (entry_points == NULL) {
+      ASSERT(!IsSnapshottingForPrecompilation());
+      CreateAndWriteSnapshot();
+    } else {
+      CreateAndWritePrecompiledSnapshot(entry_points);
+    }
+
+    CleanupEntryPointsCollection(entry_points);
 
     Dart_EnterIsolate(UriResolverIsolateScope::isolate);
     Dart_ShutdownIsolate();
@@ -631,6 +1148,7 @@
     SetupForGenericSnapshotCreation();
     CreateAndWriteSnapshot();
   }
+  EventHandler::Stop();
   return 0;
 }
 
diff --git a/runtime/bin/io_impl_sources.gypi b/runtime/bin/io_impl_sources.gypi
index 611b458..03d20d4 100644
--- a/runtime/bin/io_impl_sources.gypi
+++ b/runtime/bin/io_impl_sources.gypi
@@ -9,6 +9,7 @@
     'eventhandler.cc',
     'eventhandler.h',
     'eventhandler_android.cc',
+    'eventhandler_android.h',
     'eventhandler_linux.cc',
     'eventhandler_linux.h',
     'eventhandler_macos.cc',
@@ -48,9 +49,13 @@
     'socket.cc',
     'socket.h',
     'socket_android.cc',
+    'socket_android.h',
     'socket_linux.cc',
+    'socket_linux.h',
     'socket_macos.cc',
+    'socket_macos.h',
     'socket_win.cc',
+    'socket_win.h',
     'stdio.cc',
     'stdio.h',
     'stdio_android.cc',
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 011e792..ec70232 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -31,6 +31,7 @@
   V(Directory_Rename, 2)                                                       \
   V(Directory_List, 3)                                                         \
   V(EventHandler_SendData, 3)                                                  \
+  V(EventHandler_TimerMillisecondClock, 0)                                     \
   V(File_Open, 2)                                                              \
   V(File_Exists, 1)                                                            \
   V(File_GetFD, 1)                                                             \
@@ -84,7 +85,6 @@
   V(Platform_ResolvedExecutableName, 0)                                        \
   V(Platform_Environment, 0)                                                   \
   V(Platform_ExecutableArguments, 0)                                           \
-  V(Platform_PackageRoot, 0)                                                   \
   V(Platform_GetVersion, 0)                                                    \
   V(Process_Start, 11)                                                         \
   V(Process_Wait, 5)                                                           \
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index 49a993f..29d2884 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -36,12 +36,14 @@
       this->packages_file = strdup(packages_file);
     }
   }
+#if 0
   ~IsolateData() {
     free(script_url);
     free(package_root);
     free(packages_file);
     free(udp_receive_buffer);
   }
+#endif
 
   char* script_url;
   char* package_root;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 1429ff4e..5e57327 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -11,8 +11,8 @@
 
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
-#include "bin/dbg_connection.h"
 #include "bin/directory.h"
+#include "bin/embedded_dart_io.h"
 #include "bin/eventhandler.h"
 #include "bin/extensions.h"
 #include "bin/file.h"
@@ -21,9 +21,12 @@
 #include "bin/platform.h"
 #include "bin/process.h"
 #include "bin/thread.h"
+#include "bin/utils.h"
 #include "bin/vmservice_impl.h"
 #include "platform/globals.h"
 #include "platform/hashmap.h"
+#include "platform/text_buffer.h"
+#include "zlib/zlib.h"
 
 namespace dart {
 namespace bin {
@@ -38,23 +41,10 @@
 
 // Global state that stores a pointer to the application script snapshot.
 static bool generate_script_snapshot = false;
+static bool generate_script_snapshot_after_run = false;
 static const char* snapshot_filename = NULL;
 
 
-// Global state that indicates whether there is a debug breakpoint.
-// This pointer points into an argv buffer and does not need to be
-// free'd.
-static const char* breakpoint_at = NULL;
-
-
-// Global state that indicates whether we should open a connection
-// and listen for a debugger to connect.
-static bool start_debugger = false;
-static const char* debug_ip = NULL;
-static int debug_port = -1;
-static const char* DEFAULT_DEBUG_IP = "127.0.0.1";
-static const int DEFAULT_DEBUG_PORT = 5858;
-
 // Value of the --package-root flag.
 // (This pointer points into an argv buffer and does not need to be
 // free'd.)
@@ -81,6 +71,12 @@
 static bool has_run_precompiled_snapshot = false;
 
 
+// Value of the --gen/run_precompiled_snapshot flag.
+// (This pointer points into an argv buffer and does not need to be
+// free'd.)
+static const char* precompiled_snapshot_directory = NULL;
+
+
 // Global flag that is used to indicate that we want to compile everything in
 // the same way as precompilation before main, then continue running in the
 // same process.
@@ -117,7 +113,10 @@
 // Exit code indicating a vm restart request.  Never returned to the user.
 static const int kRestartRequestExitCode = 1000;
 
-extern bool do_vm_shutdown;  // Defined in bin/process.cc
+// Global flag that is used to indicate that the VM should do a clean
+// shutdown.
+static bool do_vm_shutdown = true;
+
 static void ErrorExit(int exit_code, const char* format, ...) {
   va_list arguments;
   va_start(arguments, format);
@@ -138,10 +137,9 @@
   }
 
   if (do_vm_shutdown) {
-    DebuggerConnectionHandler::StopHandler();
     EventHandler::Stop();
   }
-  exit(exit_code);
+  Platform::Exit(exit_code);
 }
 
 
@@ -189,17 +187,6 @@
 }
 
 
-static bool ProcessBreakpointOption(const char* funcname,
-                                    CommandLineOptions* vm_options) {
-  ASSERT(funcname != NULL);
-  if (*funcname == '\0') {
-    return false;
-  }
-  breakpoint_at = funcname;
-  return true;
-}
-
-
 static bool ProcessPackageRootOption(const char* arg,
                                      CommandLineOptions* vm_options) {
   ASSERT(arg != NULL);
@@ -323,16 +310,18 @@
 static bool ProcessGenPrecompiledSnapshotOption(
     const char* arg,
     CommandLineOptions* vm_options) {
-  ASSERT(arg != NULL);
-  if (*arg != '\0') {
-    return false;
-  }
   // Ensure that we are not already running using a full snapshot.
   if (isolate_snapshot_buffer != NULL) {
     Log::PrintErr("Precompiled snapshots must be generated with"
                   " dart_no_snapshot.\n");
     return false;
   }
+  ASSERT(arg != NULL);
+  if ((arg[0] == '=') || (arg[0] == ':')) {
+    precompiled_snapshot_directory = &arg[1];
+  } else {
+    precompiled_snapshot_directory = arg;
+  }
   has_gen_precompiled_snapshot = true;
   vm_options->AddArgument("--precompilation");
   return true;
@@ -343,8 +332,10 @@
     const char* arg,
     CommandLineOptions* vm_options) {
   ASSERT(arg != NULL);
-  if (*arg != '\0') {
-    return false;
+  precompiled_snapshot_directory = arg;
+  if ((precompiled_snapshot_directory[0] == '=') ||
+      (precompiled_snapshot_directory[0] == ':')) {
+    precompiled_snapshot_directory = &precompiled_snapshot_directory[1];
   }
   has_run_precompiled_snapshot = true;
   vm_options->AddArgument("--precompilation");
@@ -365,25 +356,10 @@
 }
 
 
-static bool ProcessDebugOption(const char* option_value,
-                               CommandLineOptions* vm_options) {
-  ASSERT(option_value != NULL);
-  if (!ExtractPortAndIP(option_value, &debug_port, &debug_ip,
-                        DEFAULT_DEBUG_PORT, DEFAULT_DEBUG_IP)) {
-    Log::PrintErr("unrecognized --debug option syntax. "
-                  "Use --debug[:<port number>[/<IPv4 address>]]\n");
-    return false;
-  }
-
-  breakpoint_at = "main";
-  start_debugger = true;
-  return true;
-}
-
-
-static bool ProcessGenScriptSnapshotOption(const char* filename,
-                                           CommandLineOptions* vm_options) {
-  if (filename != NULL && strlen(filename) != 0) {
+static bool ProcessScriptSnapshotOptionHelper(const char* filename,
+                                              bool* snapshot_option) {
+  *snapshot_option = false;
+  if ((filename != NULL) && (strlen(filename) != 0)) {
     // Ensure that we are already running using a full snapshot.
     if (isolate_snapshot_buffer == NULL) {
       Log::PrintErr("Script snapshots cannot be generated in this version of"
@@ -391,13 +367,31 @@
       return false;
     }
     snapshot_filename = filename;
-    generate_script_snapshot = true;
+    *snapshot_option = true;
+    if (generate_script_snapshot && generate_script_snapshot_after_run) {
+      Log::PrintErr("--snapshot and --snapshot-after-run options"
+                    " cannot be specified at the same time\n");
+      return false;
+    }
     return true;
   }
   return false;
 }
 
 
+static bool ProcessScriptSnapshotOption(const char* filename,
+                                        CommandLineOptions* vm_options) {
+  return ProcessScriptSnapshotOptionHelper(filename, &generate_script_snapshot);
+}
+
+
+static bool ProcessScriptSnapshotAfterRunOption(
+    const char* filename, CommandLineOptions* vm_options) {
+  return ProcessScriptSnapshotOptionHelper(filename,
+                                           &generate_script_snapshot_after_run);
+}
+
+
 static bool ProcessEnableVmServiceOption(const char* option_value,
                                          CommandLineOptions* vm_options) {
   ASSERT(option_value != NULL);
@@ -435,17 +429,6 @@
 }
 
 
-extern bool trace_debug_protocol;
-static bool ProcessTraceDebugProtocolOption(const char* arg,
-                                            CommandLineOptions* vm_options) {
-  if (*arg != '\0') {
-    return false;
-  }
-  trace_debug_protocol = true;
-  return true;
-}
-
-
 static bool ProcessTraceLoadingOption(const char* arg,
                                       CommandLineOptions* vm_options) {
   if (*arg != '\0') {
@@ -499,17 +482,15 @@
   { "--version", ProcessVersionOption },
 
   // VM specific options to the standalone dart program.
-  { "--break-at=", ProcessBreakpointOption },
   { "--compile_all", ProcessCompileAllOption },
-  { "--debug", ProcessDebugOption },
   { "--enable-vm-service", ProcessEnableVmServiceOption },
   { "--gen-precompiled-snapshot", ProcessGenPrecompiledSnapshotOption },
   { "--noopt", ProcessNooptOption },
   { "--observe", ProcessObserveOption },
   { "--run-precompiled-snapshot", ProcessRunPrecompiledSnapshotOption },
   { "--shutdown", ProcessShutdownOption },
-  { "--snapshot=", ProcessGenScriptSnapshotOption },
-  { "--trace-debug-protocol", ProcessTraceDebugProtocolOption },
+  { "--snapshot=", ProcessScriptSnapshotOption },
+  { "--snapshot-after-run=", ProcessScriptSnapshotAfterRunOption },
   { "--trace-loading", ProcessTraceLoadingOption },
   { NULL, NULL }
 };
@@ -623,7 +604,24 @@
   if ((commandline_package_root != NULL) &&
       (commandline_packages_file != NULL)) {
     Log::PrintErr("Specifying both a packages directory and a packages "
-                  "file is invalid.");
+                  "file is invalid.\n");
+    return -1;
+  }
+  if (has_noopt) {
+    if (has_gen_precompiled_snapshot) {
+      Log::PrintErr("Specifying --noopt and --gen_precompiled_snapshot"
+                    " is invalid.\n");
+      return -1;
+    }
+    if (has_run_precompiled_snapshot) {
+      Log::PrintErr("Specifying --noopt and --run_precompiled_snapshot"
+                    " is invalid.\n");
+      return -1;
+    }
+  }
+  if (has_gen_precompiled_snapshot && has_run_precompiled_snapshot) {
+    Log::PrintErr("Specifying --gen_precompiled_snapshot and"
+                  " --run_precompiled_snapshot is invalid.\n");
     return -1;
   }
 
@@ -706,15 +704,14 @@
 static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
                                                 const char* main,
                                                 const char* package_root,
-                                                const char** package_map,
-                                                const char* packages_file,
+                                                const char* packages_config,
                                                 Dart_IsolateFlags* flags,
                                                 char** error,
                                                 int* exit_code) {
   ASSERT(script_uri != NULL);
   IsolateData* isolate_data = new IsolateData(script_uri,
                                               package_root,
-                                              packages_file);
+                                              packages_config);
   Dart_Isolate isolate = NULL;
 
   isolate = Dart_CreateIsolate(script_uri,
@@ -743,7 +740,9 @@
 
   if (Dart_IsServiceIsolate(isolate)) {
     // If this is the service isolate, load embedder specific bits and return.
-    if (!VmService::Setup(vm_service_server_ip, vm_service_server_port)) {
+    if (!VmService::Setup(vm_service_server_ip,
+                          vm_service_server_port,
+                          has_run_precompiled_snapshot)) {
       *error = strdup(VmService::GetErrorMessage());
       return NULL;
     }
@@ -768,8 +767,7 @@
   // Prepare for script loading by setting up the 'print' and 'timer'
   // closures and setting up 'package root' for URI resolution.
   result = DartUtils::PrepareForScriptLoading(package_root,
-                                              package_map,
-                                              packages_file,
+                                              packages_config,
                                               false,
                                               has_trace_loading,
                                               builtin_lib);
@@ -791,8 +789,6 @@
       Dart_TimelineAsyncEnd("LoadScript", isolate_data->load_async_id);
     }
 
-    Platform::SetPackageRoot(package_root);
-
     result = DartUtils::SetupIOLibrary(script_uri);
     CHECK_RESULT(result);
   }
@@ -817,45 +813,23 @@
 static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
                                           const char* main,
                                           const char* package_root,
-                                          const char** package_map,
+                                          const char* package_config,
                                           Dart_IsolateFlags* flags,
                                           void* data, char** error) {
   // The VM should never call the isolate helper with a NULL flags.
   ASSERT(flags != NULL);
   ASSERT(flags->version == DART_FLAGS_CURRENT_VERSION);
-  if ((package_root != NULL) && (package_map != NULL)) {
+  if ((package_root != NULL) && (package_config != NULL)) {
     *error = strdup("Invalid arguments - Cannot simultaneously specify "
                     "package root and package map.");
     return NULL;
   }
-  IsolateData* parent_isolate_data = reinterpret_cast<IsolateData*>(data);
-  if (script_uri == NULL) {
-    if (data == NULL) {
-      *error = strdup("Invalid 'callback_data' - Unable to spawn new isolate");
-      return NULL;
-    }
-    script_uri = parent_isolate_data->script_url;
-    if (script_uri == NULL) {
-      *error = strdup("Invalid 'callback_data' - Unable to spawn new isolate");
-      return NULL;
-    }
-  }
-  const char* packages_file = NULL;
-  // If neither a package root nor a package map are requested pass on the
-  // inherited values.
-  if ((package_root == NULL) && (package_map == NULL)) {
-    if (parent_isolate_data != NULL) {
-      package_root = parent_isolate_data->package_root;
-      packages_file = parent_isolate_data->packages_file;
-    }
-  }
 
   int exit_code = 0;
   return CreateIsolateAndSetupHelper(script_uri,
                                      main,
                                      package_root,
-                                     package_map,
-                                     packages_file,
+                                     package_config,
                                      flags,
                                      error,
                                      &exit_code);
@@ -910,15 +884,6 @@
 "--version\n"
 "  Print the VM version.\n"
 "\n"
-"--debug[:<port number>]\n"
-"  enables debugging and listens on specified port for debugger connections\n"
-"  (default port number is 5858)\n"
-"\n"
-"--break-at=<location>\n"
-"  sets a breakpoint at specified location where <location> is one of :\n"
-"  url:<line_num> e.g. test.dart:10\n"
-"  [<class_name>.]<function_name> e.g. B.foo\n"
-"\n"
 "--snapshot=<file_name>\n"
 "  loads Dart script and generates a snapshot in the specified file\n"
 "\n"
@@ -937,25 +902,6 @@
 }
 
 
-static Dart_Handle SetBreakpoint(const char* breakpoint_at,
-                                 Dart_Handle library) {
-  char* bpt_function = strdup(breakpoint_at);
-  Dart_Handle class_name;
-  Dart_Handle function_name;
-  char* dot = strchr(bpt_function, '.');
-  if (dot == NULL) {
-    class_name = DartUtils::NewString("");
-    function_name = DartUtils::NewString(breakpoint_at);
-  } else {
-    *dot = '\0';
-    class_name = DartUtils::NewString(bpt_function);
-    function_name = DartUtils::NewString(dot + 1);
-  }
-  free(bpt_function);
-  return Dart_OneTimeBreakAtEntry(library, class_name, function_name);
-}
-
-
 char* BuildIsolateName(const char* script_name,
                        const char* func_name) {
   // Skip past any slashes in the script name.
@@ -1002,14 +948,21 @@
   DartScope scope;
   // TODO(ajohnsen): Store the library/function in isolate data or user_data.
   Dart_Handle dart_io_str = Dart_NewStringFromCString("dart:io");
-  if (Dart_IsError(dart_io_str)) return ServiceRequestError(dart_io_str);
+  if (Dart_IsError(dart_io_str)) {
+    return ServiceRequestError(dart_io_str);
+  }
+
   Dart_Handle io_lib = Dart_LookupLibrary(dart_io_str);
-  if (Dart_IsError(io_lib)) return ServiceRequestError(io_lib);
+  if (Dart_IsError(io_lib)) {
+    return ServiceRequestError(io_lib);
+  }
+
   Dart_Handle handler_function_name =
       Dart_NewStringFromCString("_serviceObjectHandler");
   if (Dart_IsError(handler_function_name)) {
     return ServiceRequestError(handler_function_name);
   }
+
   // TODO(johnmccutchan): paths is no longer used.  Update the io
   // _serviceObjectHandler function to use json rpc.
   Dart_Handle paths = Dart_NewList(0);
@@ -1021,29 +974,29 @@
   }
   Dart_Handle args[] = {paths, keys, values};
   Dart_Handle result = Dart_Invoke(io_lib, handler_function_name, 3, args);
-  if (Dart_IsError(result)) return ServiceRequestError(result);
+  if (Dart_IsError(result)) {
+    return ServiceRequestError(result);
+  }
+
   const char *json;
   result = Dart_StringToCString(result, &json);
-  if (Dart_IsError(result)) return ServiceRequestError(result);
+  if (Dart_IsError(result)) {
+    return ServiceRequestError(result);
+  }
   return strdup(json);
 }
 
 
-extern bool capture_stdio;
-extern bool capture_stdout;
-extern bool capture_stderr;
 static const char* kStdoutStreamId = "Stdout";
 static const char* kStderrStreamId = "Stderr";
 
 
 static bool ServiceStreamListenCallback(const char* stream_id) {
   if (strcmp(stream_id, kStdoutStreamId) == 0) {
-    capture_stdio = true;
-    capture_stdout = true;
+    SetCaptureStdout(true);
     return true;
   } else if (strcmp(stream_id, kStderrStreamId) == 0) {
-    capture_stdio = true;
-    capture_stderr = true;
+    SetCaptureStderr(true);
     return true;
   }
   return false;
@@ -1052,42 +1005,74 @@
 
 static void ServiceStreamCancelCallback(const char* stream_id) {
   if (strcmp(stream_id, kStdoutStreamId) == 0) {
-    capture_stdout = false;
+    SetCaptureStdout(false);
   } else if (strcmp(stream_id, kStderrStreamId) == 0) {
-    capture_stderr = false;
+    SetCaptureStderr(false);
   }
-  capture_stdio = (capture_stdout || capture_stderr);
 }
 
 
-static void WriteSnapshotFile(const char* filename,
-                              const uint8_t* buffer,
-                              const intptr_t size) {
-  File* file = File::Open(filename, File::kWriteTruncate);
+static void WritePrecompiledSnapshotFile(const char* filename,
+                                         const uint8_t* buffer,
+                                         const intptr_t size) {
+  char* concat = NULL;
+  const char* qualified_filename;
+  if (strlen(precompiled_snapshot_directory) > 0) {
+    intptr_t len = snprintf(NULL, 0, "%s/%s",
+                            precompiled_snapshot_directory, filename);
+    concat = new char[len + 1];
+    snprintf(concat, len + 1, "%s/%s",
+             precompiled_snapshot_directory, filename);
+    qualified_filename = concat;
+  } else {
+    qualified_filename = filename;
+  }
+
+  File* file = File::Open(qualified_filename, File::kWriteTruncate);
   ASSERT(file != NULL);
   if (!file->WriteFully(buffer, size)) {
     ErrorExit(kErrorExitCode,
               "Unable to open file %s for writing snapshot\n",
-              filename);
+              qualified_filename);
   }
   delete file;
+  if (concat != NULL) {
+    delete concat;
+  }
 }
 
 
-static void ReadSnapshotFile(const char* filename,
-                             const uint8_t** buffer) {
-  void* file = DartUtils::OpenFile(filename, false);
+static void ReadPrecompiledSnapshotFile(const char* filename,
+                                        const uint8_t** buffer) {
+  char* concat = NULL;
+  const char* qualified_filename;
+  if (strlen(precompiled_snapshot_directory) > 0) {
+    intptr_t len = snprintf(NULL, 0, "%s/%s",
+                            precompiled_snapshot_directory, filename);
+    concat = new char[len + 1];
+    snprintf(concat, len + 1, "%s/%s",
+             precompiled_snapshot_directory, filename);
+    qualified_filename = concat;
+  } else {
+    qualified_filename = filename;
+  }
+
+  void* file = DartUtils::OpenFile(qualified_filename, false);
   if (file == NULL) {
     ErrorExit(kErrorExitCode,
-              "Error: Unable to open file %s for reading snapshot\n", filename);
+              "Error: Unable to open file %s for reading snapshot\n",
+              qualified_filename);
   }
   intptr_t len = -1;
   DartUtils::ReadFile(buffer, &len, file);
   if (*buffer == NULL || len == -1) {
     ErrorExit(kErrorExitCode,
-              "Error: Unable to read snapshot file %s\n", filename);
+              "Error: Unable to read snapshot file %s\n", qualified_filename);
   }
   DartUtils::CloseFile(file);
+  if (concat != NULL) {
+    delete concat;
+  }
 }
 
 
@@ -1095,17 +1080,45 @@
   void* library = Extensions::LoadExtensionLibrary(libname);
   if (library == NULL) {
     Log::PrintErr("Error: Failed to load library '%s'\n", libname);
-    exit(kErrorExitCode);
+    Platform::Exit(kErrorExitCode);
   }
   void* symbol = Extensions::ResolveSymbol(library, symname);
   if (symbol == NULL) {
     Log::PrintErr("Error: Failed to load symbol '%s'\n", symname);
-    exit(kErrorExitCode);
+    Platform::Exit(kErrorExitCode);
   }
   return symbol;
 }
 
 
+static void GenerateScriptSnapshot() {
+  // First create a snapshot.
+  uint8_t* buffer = NULL;
+  intptr_t size = 0;
+  Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size);
+  if (Dart_IsError(result)) {
+    ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
+  }
+
+  // Open the snapshot file.
+  File* snapshot_file = File::Open(snapshot_filename, File::kWriteTruncate);
+  if (snapshot_file == NULL) {
+    ErrorExit(kErrorExitCode,
+              "Unable to open file %s for writing the snapshot\n",
+              snapshot_filename);
+  }
+
+  // Write the magic number to indicate file is a script snapshot.
+  DartUtils::WriteMagicNumber(snapshot_file);
+
+  // Now write the snapshot out to specified file.
+  bool bytes_written = snapshot_file->WriteFully(buffer, size);
+  ASSERT(bytes_written);
+  delete snapshot_file;
+  snapshot_file = NULL;
+}
+
+
 #define CHECK_RESULT(result)                                                   \
   if (Dart_IsError(result)) {                                                  \
     if (Dart_IsVMRestartRequest(result)) {                                     \
@@ -1118,6 +1131,7 @@
     ErrorExit(exit_code, "%s\n", Dart_GetError(result));                       \
   }
 
+
 bool RunMainIsolate(const char* script_name,
                     CommandLineOptions* dart_options) {
   // Call CreateIsolateAndSetup which creates an isolate and loads up
@@ -1128,7 +1142,6 @@
   Dart_Isolate isolate = CreateIsolateAndSetupHelper(script_name,
                                                      "main",
                                                      commandline_package_root,
-                                                     NULL,
                                                      commandline_packages_file,
                                                      NULL,
                                                      &error,
@@ -1149,10 +1162,9 @@
       free(error);
     }
     if (do_vm_shutdown) {
-      DebuggerConnectionHandler::StopHandler();
       EventHandler::Stop();
     }
-    exit((exit_code != 0) ? exit_code : kErrorExitCode);
+    Platform::Exit((exit_code != 0) ? exit_code : kErrorExitCode);
   }
   delete [] isolate_name;
 
@@ -1164,29 +1176,7 @@
   Dart_EnterScope();
 
   if (generate_script_snapshot) {
-    // First create a snapshot.
-    Dart_Handle result;
-    uint8_t* buffer = NULL;
-    intptr_t size = 0;
-    result = Dart_CreateScriptSnapshot(&buffer, &size);
-    CHECK_RESULT(result);
-
-    // Open the snapshot file.
-    File* snapshot_file = File::Open(snapshot_filename, File::kWriteTruncate);
-    if (snapshot_file == NULL) {
-      ErrorExit(kErrorExitCode,
-                "Unable to open file %s for writing the snapshot\n",
-                snapshot_filename);
-    }
-
-    // Write the magic number to indicate file is a script snapshot.
-    DartUtils::WriteMagicNumber(snapshot_file);
-
-    // Now write the snapshot out to specified file.
-    bool bytes_written = snapshot_file->WriteFully(buffer, size);
-    ASSERT(bytes_written);
-    delete snapshot_file;
-    snapshot_file = NULL;
+    GenerateScriptSnapshot();
   } else {
     // Lookup the library of the root script.
     Dart_Handle root_lib = Dart_RootLibrary();
@@ -1197,6 +1187,23 @@
     ASSERT(!Dart_IsError(builtin_lib));
     result = Dart_LibraryImportLibrary(builtin_lib, root_lib, Dart_Null());
 
+    if (has_gen_precompiled_snapshot) {
+      // Load the embedder's portion of the VM service's Dart code so it will
+      // be included in the precompiled snapshot.
+      if (!VmService::LoadForGenPrecompiled()) {
+        fprintf(stderr,
+                "VM service loading failed: %s\n",
+                VmService::GetErrorMessage());
+        fflush(stderr);
+        exit(kErrorExitCode);
+      }
+    }
+
+    if (has_compile_all) {
+      result = Dart_CompileAll();
+      CHECK_RESULT(result);
+    }
+
     if (has_noopt || has_gen_precompiled_snapshot) {
       Dart_QualifiedFunctionName standalone_entry_points[] = {
         { "dart:_builtin", "::", "_getMainClosure" },
@@ -1204,22 +1211,30 @@
         { "dart:_builtin", "::", "_getUriBaseClosure" },
         { "dart:_builtin", "::", "_resolveUri" },
         { "dart:_builtin", "::", "_setWorkingDirectory" },
+        { "dart:_builtin", "::", "_setPackageRoot" },
+        { "dart:_builtin", "::", "_loadPackagesMap" },
         { "dart:_builtin", "::", "_loadDataAsync" },
         { "dart:io", "::", "_makeUint8ListView" },
         { "dart:io", "::", "_makeDatagram" },
         { "dart:io", "::", "_setupHooks" },
+        { "dart:io", "::", "_getWatchSignalInternal" },
         { "dart:io", "CertificateException", "CertificateException." },
+        { "dart:io", "Directory", "Directory." },
+        { "dart:io", "File", "File." },
+        { "dart:io", "FileSystemException", "FileSystemException." },
         { "dart:io", "HandshakeException", "HandshakeException." },
+        { "dart:io", "Link", "Link." },
+        { "dart:io", "OSError", "OSError." },
         { "dart:io", "TlsException", "TlsException." },
-        { "dart:io", "X509Certificate", "X509Certificate." },
+        { "dart:io", "X509Certificate", "X509Certificate._" },
         { "dart:io", "_ExternalBuffer", "set:data" },
         { "dart:io", "_Platform", "set:_nativeScript" },
         { "dart:io", "_ProcessStartStatus", "set:_errorCode" },
         { "dart:io", "_ProcessStartStatus", "set:_errorMessage" },
         { "dart:io", "_SecureFilterImpl", "get:ENCRYPTED_SIZE" },
         { "dart:io", "_SecureFilterImpl", "get:SIZE" },
-        { "dart:vmservice_io", "::", "_addResource" },
         { "dart:vmservice_io", "::", "main" },
+        { "dart:vmservice_io", "::", "boot" },
         { NULL, NULL, NULL }  // Must be terminated with NULL entries.
       };
 
@@ -1242,21 +1257,16 @@
                                               &instructions_buffer,
                                               &instructions_size);
       CHECK_RESULT(result);
-      WriteSnapshotFile(kPrecompiledVmIsolateName,
-                        vm_isolate_buffer,
-                        vm_isolate_size);
-      WriteSnapshotFile(kPrecompiledIsolateName,
-                        isolate_buffer,
-                        isolate_size);
-      WriteSnapshotFile(kPrecompiledInstructionsName,
-                        instructions_buffer,
-                        instructions_size);
+      WritePrecompiledSnapshotFile(kPrecompiledVmIsolateName,
+                                   vm_isolate_buffer,
+                                   vm_isolate_size);
+      WritePrecompiledSnapshotFile(kPrecompiledIsolateName,
+                                   isolate_buffer,
+                                   isolate_size);
+      WritePrecompiledSnapshotFile(kPrecompiledInstructionsName,
+                                   instructions_buffer,
+                                   instructions_size);
     } else {
-      if (has_compile_all) {
-        result = Dart_CompileAll();
-        CHECK_RESULT(result);
-      }
-
       if (Dart_IsNull(root_lib)) {
         ErrorExit(kErrorExitCode,
                   "Unable to find root library for '%s'\n",
@@ -1270,18 +1280,6 @@
           Dart_NewStringFromCString("_getMainClosure"), 0, NULL);
       CHECK_RESULT(main_closure);
 
-      // Set debug breakpoint if specified on the command line before calling
-      // the main function.
-      if (breakpoint_at != NULL) {
-        result = SetBreakpoint(breakpoint_at, root_lib);
-        if (Dart_IsError(result)) {
-          ErrorExit(kErrorExitCode,
-                    "Error setting breakpoint at '%s': %s\n",
-                    breakpoint_at,
-                    Dart_GetError(result));
-        }
-      }
-
       // Call _startIsolate in the isolate library to enable dispatching the
       // initial startup message.
       const intptr_t kNumIsolateArgs = 2;
@@ -1299,6 +1297,11 @@
       // Keep handling messages until the last active receive port is closed.
       result = Dart_RunLoop();
       CHECK_RESULT(result);
+
+      // Generate a script snapshot after execution if specified.
+      if (generate_script_snapshot_after_run) {
+        GenerateScriptSnapshot();
+      }
     }
   }
 
@@ -1312,6 +1315,88 @@
 
 #undef CHECK_RESULT
 
+extern unsigned int observatory_assets_archive_len;
+extern const uint8_t* observatory_assets_archive;
+
+
+// |input| is assumed to be a gzipped stream.
+// This function allocates the output buffer in the C heap and the caller
+// is responsible for freeing it.
+void Decompress(const uint8_t* input, unsigned int input_len,
+                uint8_t** output, unsigned int* output_length) {
+  ASSERT(input != NULL);
+  ASSERT(input_len > 0);
+  ASSERT(output != NULL);
+  ASSERT(output_length != NULL);
+
+  // Initialize output.
+  *output = NULL;
+  *output_length = 0;
+
+  const unsigned int kChunkSize = 256 * 1024;
+  uint8_t chunk_out[kChunkSize];
+  z_stream strm;
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+  strm.opaque = Z_NULL;
+  strm.avail_in = 0;
+  strm.next_in = 0;
+  int ret = inflateInit2(&strm, 32 + MAX_WBITS);
+  ASSERT(ret == Z_OK);
+
+  unsigned int input_cursor = 0;
+  unsigned int output_cursor = 0;
+  do {
+    // Setup input.
+    unsigned int size_in = input_len - input_cursor;
+    if (size_in > kChunkSize) {
+      size_in = kChunkSize;
+    }
+    strm.avail_in = size_in;
+    strm.next_in = const_cast<uint8_t*>(&input[input_cursor]);
+
+    // Inflate until we've exhausted the current input chunk.
+    do {
+      // Setup output.
+      strm.avail_out = kChunkSize;
+      strm.next_out = &chunk_out[0];
+      // Inflate.
+      ret = inflate(&strm, Z_SYNC_FLUSH);
+      // We either hit the end of the stream or made forward progress.
+      ASSERT((ret == Z_STREAM_END) || (ret == Z_OK));
+      // Grow output buffer size.
+      unsigned int size_out = kChunkSize - strm.avail_out;
+      *output_length += size_out;
+      *output = reinterpret_cast<uint8_t*>(realloc(*output, *output_length));
+      // Copy output.
+      memmove(&((*output)[output_cursor]), &chunk_out[0], size_out);
+      output_cursor += size_out;
+    } while (strm.avail_out == 0);
+
+    // We've processed size_in bytes.
+    input_cursor += size_in;
+
+    // We're finished decompressing when zlib tells us.
+  } while (ret != Z_STREAM_END);
+
+  inflateEnd(&strm);
+}
+
+
+Dart_Handle GetVMServiceAssetsArchiveCallback() {
+  uint8_t* decompressed = NULL;
+  unsigned int decompressed_len = 0;
+  Decompress(observatory_assets_archive,
+             observatory_assets_archive_len,
+             &decompressed,
+             &decompressed_len);
+  Dart_Handle tar_file = DartUtils::MakeUint8Array(decompressed,
+                                                   decompressed_len);
+  // Free decompressed memory as it has been copied into a Dart array.
+  free(decompressed);
+  return tar_file;
+}
+
 
 void main(int argc, char** argv) {
   char* script_name;
@@ -1341,18 +1426,18 @@
                      &verbose_debug_seen) < 0) {
     if (has_help_option) {
       PrintUsage();
-      exit(0);
+      Platform::Exit(0);
     } else if (has_version_option) {
       PrintVersion();
-      exit(0);
+      Platform::Exit(0);
     } else if (print_flags_seen) {
       // Will set the VM flags, print them out and then we exit as no
       // script was specified on the command line.
       Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
-      exit(0);
+      Platform::Exit(0);
     } else {
       PrintUsage();
-      exit(kErrorExitCode);
+      Platform::Exit(kErrorExitCode);
     }
   }
 
@@ -1362,7 +1447,7 @@
     OSError err;
     fprintf(stderr, "Error determining current directory: %s\n", err.message());
     fflush(stderr);
-    exit(kErrorExitCode);
+    Platform::Exit(kErrorExitCode);
   }
 
   if (generate_script_snapshot) {
@@ -1372,26 +1457,17 @@
   Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
 
   // Start event handler.
+  TimerUtils::InitOnce();
   EventHandler::Start();
 
-  // Start the debugger wire protocol handler if necessary.
-  if (start_debugger) {
-    ASSERT(debug_port >= 0);
-    bool print_msg = verbose_debug_seen || (debug_port == 0);
-    debug_port = DebuggerConnectionHandler::StartHandler(debug_ip, debug_port);
-    if (print_msg) {
-      Log::Print("Debugger listening on port %d\n", debug_port);
-    }
-  } else {
-    DebuggerConnectionHandler::InitForVmService();
-  }
-
   const uint8_t* instructions_snapshot = NULL;
   if (has_run_precompiled_snapshot) {
     instructions_snapshot = reinterpret_cast<const uint8_t*>(
         LoadLibrarySymbol(kPrecompiledLibraryName, kPrecompiledSymbolName));
-    ReadSnapshotFile(kPrecompiledVmIsolateName, &vm_isolate_snapshot_buffer);
-    ReadSnapshotFile(kPrecompiledIsolateName, &isolate_snapshot_buffer);
+    ReadPrecompiledSnapshotFile(kPrecompiledVmIsolateName,
+                                &vm_isolate_snapshot_buffer);
+    ReadPrecompiledSnapshotFile(kPrecompiledIsolateName,
+                                &isolate_snapshot_buffer);
   }
 
   // Initialize the Dart VM.
@@ -1402,16 +1478,16 @@
       DartUtils::ReadFile,
       DartUtils::WriteFile,
       DartUtils::CloseFile,
-      DartUtils::EntropySource);
+      DartUtils::EntropySource,
+      GetVMServiceAssetsArchiveCallback);
   if (error != NULL) {
     if (do_vm_shutdown) {
-      DebuggerConnectionHandler::StopHandler();
       EventHandler::Stop();
     }
     fprintf(stderr, "VM initialization failed: %s\n", error);
     fflush(stderr);
     free(error);
-    exit(kErrorExitCode);
+    Platform::Exit(kErrorExitCode);
   }
 
   Dart_RegisterIsolateServiceRequestCallback(
@@ -1433,7 +1509,6 @@
     free(error);
   }
   if (do_vm_shutdown) {
-    DebuggerConnectionHandler::StopHandler();
     EventHandler::Stop();
   }
 
@@ -1453,7 +1528,7 @@
     delete environment;
   }
 
-  exit(Process::GlobalExitCode());
+  Platform::Exit(Process::GlobalExitCode());
 }
 
 }  // namespace bin
diff --git a/runtime/bin/observatory_assets_empty.cc b/runtime/bin/observatory_assets_empty.cc
new file mode 100644
index 0000000..80d5fe1
--- /dev/null
+++ b/runtime/bin/observatory_assets_empty.cc
@@ -0,0 +1,24 @@
+// 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 file is linked into the dart executable when it does not have
+// Observatory baked in.
+
+#if defined(_WIN32)
+typedef unsigned __int8 uint8_t;
+#else
+#include <inttypes.h>
+#include <stdint.h>
+#endif
+#include <stddef.h>
+
+namespace dart {
+namespace bin {
+
+static const uint8_t observatory_assets_archive_[] = { '\0' };
+unsigned int observatory_assets_archive_len = 0;
+const uint8_t* observatory_assets_archive = observatory_assets_archive_;
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index 0ed2bd3..f2f16be 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -14,7 +14,6 @@
 
 const char* Platform::executable_name_ = NULL;
 const char* Platform::resolved_executable_name_ = NULL;
-const char* Platform::package_root_ = NULL;
 int Platform::script_index_ = 1;
 char** Platform::argv_ = NULL;
 
@@ -46,12 +45,28 @@
 
 void FUNCTION_NAME(Platform_ExecutableName)(Dart_NativeArguments args) {
   ASSERT(Platform::GetExecutableName() != NULL);
+  if (Dart_IsRunningPrecompiledCode()) {
+    // This is a work-around to be able to use most of the existing test suite
+    // for precompilation. Many tests do something like Process.run(
+    // Platform.executable, some_other_script.dart). But with precompilation
+    // the script is already fixed, so the spawned process runs the same script
+    // again and we have a fork-bomb.
+    Dart_ThrowException(Dart_NewStringFromCString(
+        "Platform.executable not supported under precompilation"));
+    UNREACHABLE();
+  }
   Dart_SetReturnValue(
       args, Dart_NewStringFromCString(Platform::GetExecutableName()));
 }
 
 
 void FUNCTION_NAME(Platform_ResolvedExecutableName)(Dart_NativeArguments args) {
+  if (Dart_IsRunningPrecompiledCode()) {
+    Dart_ThrowException(Dart_NewStringFromCString(
+        "Platform.resolvedExecutable not supported under precompilation"));
+    UNREACHABLE();
+  }
+
   if (Platform::GetResolvedExecutableName() != NULL) {
     Dart_SetReturnValue(
         args, Dart_NewStringFromCString(Platform::GetResolvedExecutableName()));
@@ -76,15 +91,6 @@
 }
 
 
-void FUNCTION_NAME(Platform_PackageRoot)(Dart_NativeArguments args) {
-  const char* package_root = Platform::GetPackageRoot();
-  if (package_root == NULL) {
-    package_root = "";
-  }
-  Dart_SetReturnValue(args, Dart_NewStringFromCString(package_root));
-}
-
-
 void FUNCTION_NAME(Platform_Environment)(Dart_NativeArguments args) {
   intptr_t count = 0;
   char** env = Platform::Environment(&count);
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 3d3c0f3..4dec601 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -56,14 +56,6 @@
     return resolved_executable_name_;
   }
 
-  // Stores and gets the package root.
-  static void SetPackageRoot(const char* package_root) {
-    package_root_ = package_root;
-  }
-  static const char* GetPackageRoot() {
-    return package_root_;
-  }
-
   // Stores and gets the flags passed to the executable.
   static void SetExecutableArguments(int script_index, char** argv) {
     script_index_ = script_index;
@@ -76,13 +68,14 @@
     return argv_;
   }
 
+  static DART_NORETURN void Exit(int exit_code);
+
  private:
   // The path to the executable.
   static const char* executable_name_;
   // The path to the resolved executable.
   static const char* resolved_executable_name_;
 
-  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 dddb4e1..3c44c04 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -77,6 +77,10 @@
   return File::LinkTarget("/proc/self/exe");
 }
 
+void Platform::Exit(int exit_code) {
+  exit(exit_code);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index 8469a21..24cbfd3 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -77,6 +77,10 @@
   return File::LinkTarget("/proc/self/exe");
 }
 
+void Platform::Exit(int exit_code) {
+  exit(exit_code);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 54b48d6..0f7c629 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -53,7 +53,11 @@
 
 
 const char* Platform::OperatingSystem() {
+#if TARGET_OS_IOS
+  return "ios";
+#else
   return "macos";
+#endif
 }
 
 
@@ -120,6 +124,10 @@
   return canon_path;
 }
 
+void Platform::Exit(int exit_code) {
+  exit(exit_code);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_patch.dart b/runtime/bin/platform_patch.dart
index c917b54..577bbb6 100644
--- a/runtime/bin/platform_patch.dart
+++ b/runtime/bin/platform_patch.dart
@@ -5,16 +5,40 @@
 patch class _Platform {
   /* patch */ static int _numberOfProcessors()
       native "Platform_NumberOfProcessors";
-  /* patch */ static String _pathSeparator() native "Platform_PathSeparator";
+  /* patch */ static String _pathSeparator()
+      native "Platform_PathSeparator";
   /* patch */ static String _operatingSystem()
       native "Platform_OperatingSystem";
-  /* patch */ static _localHostname() native "Platform_LocalHostname";
-  /* patch */ static _executable() native "Platform_ExecutableName";
+  /* patch */ static _localHostname()
+      native "Platform_LocalHostname";
+  /* patch */ static _executable()
+      native "Platform_ExecutableName";
   /* patch */ static _resolvedExecutable()
       native "Platform_ResolvedExecutableName";
-  /* patch */ static _environment() native "Platform_Environment";
+  /* patch */ static _environment()
+      native "Platform_Environment";
   /* patch */ static List<String> _executableArguments()
-       native "Platform_ExecutableArguments";
-  /* patch */ static String _packageRoot() native "Platform_PackageRoot";
-  /* patch */ static String _version() native "Platform_GetVersion";
+      native "Platform_ExecutableArguments";
+  /* patch */ static String _version()
+      native "Platform_GetVersion";
+
+  /* patch */ static String _packageRoot()
+      => VMLibraryHooks.packageRootString;
+  /* patch */ static String _packageConfig()
+      => VMLibraryHooks.packageConfigString;
+
+  // This script singleton is written to by the embedder if applicable.
+  /* patch */ static void set _nativeScript(String path) {
+    if (path.startsWith('http:') ||
+        path.startsWith('https:') ||
+        path.startsWith('package:') ||
+        path.startsWith('dart:') ||
+        path.startsWith('data:') ||
+        path.startsWith('file:')) {
+      script = Uri.parse(path);
+    } else {
+      script = Uri.base.resolveUri(new Uri.file(path));
+    }
+    VMLibraryHooks.platformScript = script;
+  }
 }
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index 9830db2..9b29cb7 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -14,6 +14,10 @@
 
 
 namespace dart {
+
+// Defined in vm/os_thread_win.cc
+extern bool private_flag_windows_run_tls_destructors;
+
 namespace bin {
 
 bool Platform::Initialize() {
@@ -105,6 +109,14 @@
   return canon_path;
 }
 
+void Platform::Exit(int exit_code) {
+  // TODO(zra): Remove once VM shuts down cleanly.
+  ::dart::private_flag_windows_run_tls_destructors = false;
+  // On Windows we use ExitProcess so that threads can't clobber the exit_code.
+  // See: https://code.google.com/p/nativeclient/issues/detail?id=2870
+  ::ExitProcess(exit_code);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index 47e2ff5..f9d3457 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -3,8 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "bin/dartutils.h"
-#include "bin/dbg_connection.h"
-#include "bin/eventhandler.h"
 #include "bin/io_buffer.h"
 #include "bin/log.h"
 #include "bin/platform.h"
@@ -17,10 +15,6 @@
 namespace dart {
 namespace bin {
 
-// Global flag that is used to indicate that the VM should do a clean
-// shutdown.
-bool do_vm_shutdown = false;
-
 static const int kProcessIdNativeField = 0;
 
 int Process::global_exit_code_ = 0;
@@ -254,26 +248,8 @@
   int64_t status = 0;
   // Ignore result if passing invalid argument and just exit 0.
   DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status);
-  Dart_ShutdownIsolate();
-  Process::TerminateExitCodeHandler();
-  char* error = Dart_Cleanup();
-  if (error != NULL) {
-    Log::PrintErr("VM cleanup failed: %s\n", error);
-    free(error);
-  }
-  if (do_vm_shutdown) {
-#ifdef LEGACY_DEBUG_PROTOCOL_ENABLED
-    // Note that this dependency crosses logical project boundaries by making
-    // the dart:io implementation depend upon the standalone VM's legacy debug
-    // protocol. This breaks projects which want to use our dart:io
-    // implementation. Because the protocol is going away shortly, it's
-    // reasonable to leave it behind a #ifdef that is only enabled for the
-    // standalone VM for now.
-    DebuggerConnectionHandler::StopHandler();
-#endif
-    EventHandler::Stop();
-  }
-  exit(static_cast<int>(status));
+  Dart_ExitIsolate();
+  Platform::Exit(static_cast<int>(status));
 }
 
 
diff --git a/runtime/bin/process.h b/runtime/bin/process.h
index b6babd3..bd40086 100644
--- a/runtime/bin/process.h
+++ b/runtime/bin/process.h
@@ -148,7 +148,7 @@
 
 class SignalInfo {
  public:
-  SignalInfo(int fd, int signal, SignalInfo* next)
+  SignalInfo(intptr_t fd, intptr_t signal, SignalInfo* next)
       : fd_(fd),
         signal_(signal),
         // SignalInfo is expected to be created when in a isolate.
@@ -171,14 +171,14 @@
     }
   }
 
-  int fd() const { return fd_; }
-  int signal() const { return signal_; }
+  intptr_t fd() const { return fd_; }
+  intptr_t signal() const { return signal_; }
   Dart_Port port() const { return port_; }
   SignalInfo* next() const { return next_; }
 
  private:
-  int fd_;
-  int signal_;
+  intptr_t fd_;
+  intptr_t signal_;
   // The port_ is used to identify what isolate the signal-info belongs to.
   Dart_Port port_;
   SignalInfo* next_;
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc
index 9265531..b9d245b 100644
--- a/runtime/bin/process_android.cc
+++ b/runtime/bin/process_android.cc
@@ -22,6 +22,7 @@
 #include "bin/thread.h"
 
 #include "platform/signal_blocker.h"
+#include "platform/utils.h"
 
 
 extern char **environ;
@@ -644,7 +645,7 @@
   void SetChildOsErrorMessage() {
     const int kBufferSize = 1024;
     char error_message[kBufferSize];
-    strerror_r(errno, error_message, kBufferSize);
+    Utils::StrError(errno, error_message, kBufferSize);
     *os_error_message_ = strdup(error_message);
   }
 
@@ -655,7 +656,7 @@
     int child_errno = errno;
     const int kBufferSize = 1024;
     char os_error_message[kBufferSize];
-    strerror_r(errno, os_error_message, kBufferSize);
+    Utils::StrError(errno, os_error_message, kBufferSize);
     int bytes_written =
         FDUtils::WriteToBlocking(
             exec_control_[1], &child_errno, sizeof(child_errno));
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index cd9c639..30f188f 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -16,11 +16,12 @@
 #include <sys/wait.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 
-#include "platform/signal_blocker.h"
 #include "bin/fdutils.h"
 #include "bin/lockers.h"
 #include "bin/log.h"
 #include "bin/thread.h"
+#include "platform/signal_blocker.h"
+#include "platform/utils.h"
 
 
 extern char **environ;
@@ -643,7 +644,7 @@
   void SetChildOsErrorMessage() {
     const int kBufferSize = 1024;
     char error_buf[kBufferSize];
-    *os_error_message_ = strdup(strerror_r(errno, error_buf, kBufferSize));
+    *os_error_message_ = strdup(Utils::StrError(errno, error_buf, kBufferSize));
   }
 
 
@@ -653,7 +654,7 @@
     int child_errno = errno;
     const int kBufferSize = 1024;
     char error_buf[kBufferSize];
-    char* os_error_message = strerror_r(errno, error_buf, kBufferSize);
+    char* os_error_message = Utils::StrError(errno, error_buf, kBufferSize);
     int bytes_written =
         FDUtils::WriteToBlocking(
             exec_control_[1], &child_errno, sizeof(child_errno));
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index f694958..1ce34f9 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -25,6 +25,7 @@
 #include "bin/thread.h"
 
 #include "platform/signal_blocker.h"
+#include "platform/utils.h"
 
 
 
@@ -660,7 +661,7 @@
   void SetChildOsErrorMessage() {
     const int kBufferSize = 1024;
     char error_message[kBufferSize];
-    strerror_r(errno, error_message, kBufferSize);
+    Utils::StrError(errno, error_message, kBufferSize);
     *os_error_message_ = strdup(error_message);
   }
 
@@ -671,7 +672,7 @@
     int child_errno = errno;
     const int kBufferSize = 1024;
     char os_error_message[kBufferSize];
-    strerror_r(errno, os_error_message, kBufferSize);
+    Utils::StrError(errno, os_error_message, kBufferSize);
     int bytes_written =
         FDUtils::WriteToBlocking(
             exec_control_[1], &child_errno, sizeof(child_errno));
diff --git a/runtime/bin/resources_sources.gypi b/runtime/bin/resources_sources.gypi
index 1469d82..91e0255 100644
--- a/runtime/bin/resources_sources.gypi
+++ b/runtime/bin/resources_sources.gypi
@@ -7,11 +7,8 @@
   'sources': [
 # Standalone VM service sources.
     'vmservice/loader.dart',
-    'vmservice/resources.dart',
     'vmservice/server.dart',
     'vmservice/vmservice_io.dart',
-# We no longer list client sources explicitly and instead include all deployed
-# files.
   ],
 }
 
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index c45a2a0..bfb597b 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -5,16 +5,20 @@
 #include <stdio.h>
 
 #include "bin/file.h"
+#include "bin/dartutils.h"
+#include "bin/platform.h"
 
 #include "vm/benchmark_test.h"
 #include "vm/dart.h"
-#include "bin/dartutils.h"
 #include "vm/unit_test.h"
 
 
 // TODO(iposva, asiva): This is a placeholder for the real unittest framework.
 namespace dart {
 
+// Defined in vm/os_thread_win.cc
+extern bool private_flag_windows_run_tls_destructors;
+
 // vm_isolate_snapshot_buffer points to a snapshot for the vm isolate if we
 // link in a snapshot otherwise it is initialized to NULL.
 extern const uint8_t* bin::vm_isolate_snapshot_buffer;
@@ -103,11 +107,12 @@
   ASSERT(set_vm_flags_success);
   const char* err_msg = Dart::InitOnce(dart::bin::vm_isolate_snapshot_buffer,
                                        NULL,
-                                       NULL, NULL, NULL, NULL,
+                                       NULL, NULL,
                                        dart::bin::DartUtils::OpenFile,
                                        dart::bin::DartUtils::ReadFile,
                                        dart::bin::DartUtils::WriteFile,
                                        dart::bin::DartUtils::CloseFile,
+                                       NULL,
                                        NULL);
   ASSERT(err_msg == NULL);
   // Apply the filter to all registered tests.
@@ -120,6 +125,11 @@
     ASSERT(err_msg == NULL);
   }
 
+#if defined(TARGET_OS_WINDOWS)
+  // TODO(zra): Remove once VM shuts down cleanly.
+  private_flag_windows_run_tls_destructors = false;
+#endif
+
   // Print a warning message if no tests or benchmarks were matched.
   if (run_matches == 0) {
     fprintf(stderr, "No tests matched: %s\n", run_filter);
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index c5bdae9..b1be87c 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -81,6 +81,7 @@
   Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
   Dart_Handle exception =
       DartUtils::NewDartIOException(exception_type, message, os_error);
+  ASSERT(!Dart_IsError(exception));
   if (free_message) {
     free(const_cast<char*>(message));
   }
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index 1910f86..e7646da 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -145,13 +145,13 @@
     Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len);
     if (Dart_IsError(result)) Dart_PropagateError(result);
     Dart_Handle err;
-    RawAddr& raw = const_cast<RawAddr&>(addr);
     if (addr.addr.sa_family == AF_INET6) {
       err = Dart_ListSetAsBytes(
-          result, 0, reinterpret_cast<uint8_t*>(&raw.in6.sin6_addr), len);
+          result, 0,
+          reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr), len);
     } else {
       err = Dart_ListSetAsBytes(
-          result, 0, reinterpret_cast<uint8_t*>(&raw.in.sin_addr), len);
+          result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len);
     }
     if (Dart_IsError(err)) Dart_PropagateError(err);
     return result;
@@ -159,14 +159,13 @@
 
   static CObjectUint8Array* ToCObject(const RawAddr& addr) {
     int in_addr_len = SocketAddress::GetInAddrLength(addr);
-    void* in_addr;
-    RawAddr& raw = const_cast<RawAddr&>(addr);
+    const void* in_addr;
     CObjectUint8Array* data =
         new CObjectUint8Array(CObject::NewUint8Array(in_addr_len));
     if (addr.addr.sa_family == AF_INET6) {
-      in_addr = reinterpret_cast<void*>(&raw.in6.sin6_addr);
+      in_addr = reinterpret_cast<const void*>(&addr.in6.sin6_addr);
     } else {
-      in_addr = reinterpret_cast<void*>(&raw.in.sin_addr);
+      in_addr = reinterpret_cast<const void*>(&addr.in.sin_addr);
     }
     memmove(data->Buffer(), in_addr, in_addr_len);
     return data;
diff --git a/runtime/bin/thread.h b/runtime/bin/thread.h
index 60dc75f2..d4a67bc 100644
--- a/runtime/bin/thread.h
+++ b/runtime/bin/thread.h
@@ -33,8 +33,8 @@
 
 class Thread {
  public:
-  static ThreadLocalKey kUnsetThreadLocalKey;
-  static ThreadId kInvalidThreadId;
+  static const ThreadLocalKey kUnsetThreadLocalKey;
+  static const ThreadId kInvalidThreadId;
 
   typedef void (*ThreadStartFunction) (uword parameter);
 
diff --git a/runtime/bin/thread_android.cc b/runtime/bin/thread_android.cc
index 62143ef..f84a988 100644
--- a/runtime/bin/thread_android.cc
+++ b/runtime/bin/thread_android.cc
@@ -11,6 +11,7 @@
 #include <sys/time.h>  // NOLINT
 
 #include "platform/assert.h"
+#include "platform/utils.h"
 
 namespace dart {
 namespace bin {
@@ -19,7 +20,7 @@
   if (result != 0) { \
     const int kBufferSize = 1024; \
     char error_message[kBufferSize]; \
-    strerror_r(result, error_message, kBufferSize); \
+    Utils::StrError(result, error_message, kBufferSize); \
     FATAL2("pthread error: %d (%s)", result, error_message); \
   }
 
@@ -29,7 +30,7 @@
   if (result != 0) { \
     const int kBufferSize = 1024; \
     char error_message[kBufferSize]; \
-    strerror_r(result, error_message, kBufferSize); \
+    Utils::StrError(result, error_message, kBufferSize); \
     fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
             __FILE__, __LINE__, result, error_message); \
     return result; \
@@ -113,8 +114,9 @@
 }
 
 
-ThreadLocalKey Thread::kUnsetThreadLocalKey = static_cast<pthread_key_t>(-1);
-ThreadId Thread::kInvalidThreadId = static_cast<ThreadId>(0);
+const ThreadLocalKey Thread::kUnsetThreadLocalKey =
+    static_cast<pthread_key_t>(-1);
+const ThreadId Thread::kInvalidThreadId = static_cast<ThreadId>(0);
 
 ThreadLocalKey Thread::CreateThreadLocal() {
   pthread_key_t key = kUnsetThreadLocalKey;
diff --git a/runtime/bin/thread_linux.cc b/runtime/bin/thread_linux.cc
index eaa4f2a..1e01a77 100644
--- a/runtime/bin/thread_linux.cc
+++ b/runtime/bin/thread_linux.cc
@@ -12,6 +12,7 @@
 #include <sys/time.h>  // NOLINT
 
 #include "platform/assert.h"
+#include "platform/utils.h"
 
 namespace dart {
 namespace bin {
@@ -21,7 +22,7 @@
     const int kBufferSize = 1024; \
     char error_buf[kBufferSize]; \
     FATAL2("pthread error: %d (%s)", result, \
-           strerror_r(result, error_buf, kBufferSize)); \
+           Utils::StrError(result, error_buf, kBufferSize)); \
   }
 
 
@@ -32,7 +33,7 @@
     char error_buf[kBufferSize]; \
     fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
             __FILE__, __LINE__, result, \
-            strerror_r(result, error_buf, kBufferSize)); \
+            Utils::StrError(result, error_buf, kBufferSize)); \
     return result; \
   }
 #else
@@ -114,8 +115,9 @@
 }
 
 
-ThreadLocalKey Thread::kUnsetThreadLocalKey = static_cast<pthread_key_t>(-1);
-ThreadId Thread::kInvalidThreadId = static_cast<ThreadId>(0);
+const ThreadLocalKey Thread::kUnsetThreadLocalKey =
+    static_cast<pthread_key_t>(-1);
+const ThreadId Thread::kInvalidThreadId = static_cast<ThreadId>(0);
 
 ThreadLocalKey Thread::CreateThreadLocal() {
   pthread_key_t key = kUnsetThreadLocalKey;
diff --git a/runtime/bin/thread_macos.cc b/runtime/bin/thread_macos.cc
index 52ac76c..28c747d 100644
--- a/runtime/bin/thread_macos.cc
+++ b/runtime/bin/thread_macos.cc
@@ -19,6 +19,7 @@
 #include <mach/thread_act.h>  // NOLINT
 
 #include "platform/assert.h"
+#include "platform/utils.h"
 
 namespace dart {
 namespace bin {
@@ -27,7 +28,7 @@
   if (result != 0) { \
     const int kBufferSize = 1024; \
     char error_message[kBufferSize]; \
-    strerror_r(result, error_message, kBufferSize); \
+    Utils::StrError(result, error_message, kBufferSize); \
     FATAL2("pthread error: %d (%s)", result, error_message); \
   }
 
@@ -37,7 +38,7 @@
   if (result != 0) { \
     const int kBufferSize = 1024; \
     char error_message[kBufferSize]; \
-    strerror_r(result, error_message, kBufferSize); \
+    Utils::StrError(result, error_message, kBufferSize); \
     fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
             __FILE__, __LINE__, result, error_message); \
     return result; \
@@ -106,8 +107,9 @@
 }
 
 
-ThreadLocalKey Thread::kUnsetThreadLocalKey = static_cast<pthread_key_t>(-1);
-ThreadId Thread::kInvalidThreadId = reinterpret_cast<ThreadId>(NULL);
+const ThreadLocalKey Thread::kUnsetThreadLocalKey =
+    static_cast<pthread_key_t>(-1);
+const ThreadId Thread::kInvalidThreadId = reinterpret_cast<ThreadId>(NULL);
 
 ThreadLocalKey Thread::CreateThreadLocal() {
   pthread_key_t key = kUnsetThreadLocalKey;
diff --git a/runtime/bin/thread_win.cc b/runtime/bin/thread_win.cc
index a69f82c..44941bb 100644
--- a/runtime/bin/thread_win.cc
+++ b/runtime/bin/thread_win.cc
@@ -70,8 +70,8 @@
   return 0;
 }
 
-ThreadLocalKey Thread::kUnsetThreadLocalKey = TLS_OUT_OF_INDEXES;
-ThreadId Thread::kInvalidThreadId = 0;
+const ThreadLocalKey Thread::kUnsetThreadLocalKey = TLS_OUT_OF_INDEXES;
+const ThreadId Thread::kInvalidThreadId = 0;
 
 ThreadLocalKey Thread::CreateThreadLocal() {
   ThreadLocalKey key = TlsAlloc();
@@ -104,12 +104,22 @@
 
 bool Thread::Join(ThreadId id) {
   HANDLE handle = OpenThread(SYNCHRONIZE, false, id);
-  if (handle == INVALID_HANDLE_VALUE) {
+
+  // TODO(zra): OSThread::Start() closes the handle to the thread. Thus, by the
+  // time we try to join the thread, its resources may have already been
+  // reclaimed, and joining will fail. This can be avoided in a couple of ways.
+  // First, GetCurrentThreadJoinId could call OpenThread and return a handle.
+  // This is bad, because each of those handles would have to be closed.
+  // Second OSThread could be refactored to no longer be AllStatic. Then the
+  // handle could be cached in the object by the Start method.
+  if (handle == NULL) {
     return false;
   }
+
   DWORD res = WaitForSingleObject(handle, INFINITE);
   CloseHandle(handle);
-  return res == WAIT_OBJECT_0;
+  ASSERT(res == WAIT_OBJECT_0);
+  return true;
 }
 
 
diff --git a/runtime/bin/thread_win.h b/runtime/bin/thread_win.h
index e500b16..5e1dba51 100644
--- a/runtime/bin/thread_win.h
+++ b/runtime/bin/thread_win.h
@@ -18,7 +18,6 @@
 typedef DWORD ThreadLocalKey;
 typedef DWORD ThreadId;
 
-
 class ThreadInlineImpl {
  private:
   ThreadInlineImpl() {}
diff --git a/runtime/bin/utils.h b/runtime/bin/utils.h
index 2c3f1fc..cbc2bab 100644
--- a/runtime/bin/utils.h
+++ b/runtime/bin/utils.h
@@ -98,8 +98,9 @@
 
 class TimerUtils {
  public:
-  static int64_t GetCurrentTimeMicros();
-  static int64_t GetCurrentTimeMilliseconds();
+  static void InitOnce();
+  static int64_t GetCurrentMonotonicMicros();
+  static int64_t GetCurrentMonotonicMillis();
   static void Sleep(int64_t millis);
 };
 
diff --git a/runtime/bin/utils_android.cc b/runtime/bin/utils_android.cc
index 00cf93d..e36ac11 100644
--- a/runtime/bin/utils_android.cc
+++ b/runtime/bin/utils_android.cc
@@ -12,6 +12,7 @@
 
 #include "bin/utils.h"
 #include "platform/assert.h"
+#include "platform/utils.h"
 
 
 namespace dart {
@@ -22,7 +23,7 @@
   set_code(errno);
   const int kBufferSize = 1024;
   char error_message[kBufferSize];
-  strerror_r(errno, error_message, kBufferSize);
+  Utils::StrError(errno, error_message, kBufferSize);
   SetMessage(error_message);
 }
 
@@ -33,7 +34,7 @@
   if (sub_system == kSystem) {
     const int kBufferSize = 1024;
     char error_message[kBufferSize];
-    strerror_r(code, error_message, kBufferSize);
+    Utils::StrError(code, error_message, kBufferSize);
     SetMessage(error_message);
   } else if (sub_system == kGetAddressInfo) {
     SetMessage(gai_strerror(code));
@@ -70,17 +71,24 @@
   return false;
 }
 
-int64_t TimerUtils::GetCurrentTimeMilliseconds() {
-  return GetCurrentTimeMicros() / 1000;
+void TimerUtils::InitOnce() {
 }
 
-int64_t TimerUtils::GetCurrentTimeMicros() {
-  struct timeval tv;
-  if (gettimeofday(&tv, NULL) < 0) {
+int64_t TimerUtils::GetCurrentMonotonicMillis() {
+  return GetCurrentMonotonicMicros() / 1000;
+}
+
+int64_t TimerUtils::GetCurrentMonotonicMicros() {
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
     UNREACHABLE();
     return 0;
   }
-  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
+  // Convert to microseconds.
+  int64_t result = ts.tv_sec;
+  result *= kMicrosecondsPerSecond;
+  result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+  return result;
 }
 
 void TimerUtils::Sleep(int64_t millis) {
diff --git a/runtime/bin/utils_linux.cc b/runtime/bin/utils_linux.cc
index f3d8654..ea6ef8c 100644
--- a/runtime/bin/utils_linux.cc
+++ b/runtime/bin/utils_linux.cc
@@ -12,6 +12,7 @@
 
 #include "bin/utils.h"
 #include "platform/assert.h"
+#include "platform/utils.h"
 
 
 namespace dart {
@@ -22,7 +23,7 @@
   set_code(errno);
   const int kBufferSize = 1024;
   char error_buf[kBufferSize];
-  SetMessage(strerror_r(errno, error_buf, kBufferSize));
+  SetMessage(Utils::StrError(errno, error_buf, kBufferSize));
 }
 
 
@@ -32,7 +33,7 @@
   if (sub_system == kSystem) {
     const int kBufferSize = 1024;
     char error_buf[kBufferSize];
-    SetMessage(strerror_r(code, error_buf, kBufferSize));
+    SetMessage(Utils::StrError(code, error_buf, kBufferSize));
   } else if (sub_system == kGetAddressInfo) {
     SetMessage(gai_strerror(code));
   } else {
@@ -68,17 +69,24 @@
   return false;
 }
 
-int64_t TimerUtils::GetCurrentTimeMilliseconds() {
-  return GetCurrentTimeMicros() / 1000;
+void TimerUtils::InitOnce() {
 }
 
-int64_t TimerUtils::GetCurrentTimeMicros() {
-  struct timeval tv;
-  if (gettimeofday(&tv, NULL) < 0) {
+int64_t TimerUtils::GetCurrentMonotonicMillis() {
+  return GetCurrentMonotonicMicros() / 1000;
+}
+
+int64_t TimerUtils::GetCurrentMonotonicMicros() {
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
     UNREACHABLE();
     return 0;
   }
-  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
+  // Convert to microseconds.
+  int64_t result = ts.tv_sec;
+  result *= kMicrosecondsPerSecond;
+  result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+  return result;
 }
 
 void TimerUtils::Sleep(int64_t millis) {
diff --git a/runtime/bin/utils_macos.cc b/runtime/bin/utils_macos.cc
index 4004f38..eea4cb7 100644
--- a/runtime/bin/utils_macos.cc
+++ b/runtime/bin/utils_macos.cc
@@ -7,11 +7,19 @@
 
 #include <errno.h>  // NOLINT
 #include <netdb.h>  // NOLINT
+#include <mach/mach.h>  // NOLINT
+#include <mach/clock.h>  // NOLINT
+#include <mach/mach_time.h>  // NOLINT
 #include <sys/time.h>  // NOLINT
 #include <time.h>  // NOLINT
 
+#if TARGET_OS_IOS
+#include <sys/sysctl.h>  // NOLINT
+#endif
+
 #include "bin/utils.h"
 #include "platform/assert.h"
+#include "platform/utils.h"
 
 
 namespace dart {
@@ -22,7 +30,7 @@
   set_code(errno);
   const int kBufferSize = 1024;
   char error_message[kBufferSize];
-  strerror_r(errno, error_message, kBufferSize);
+  Utils::StrError(errno, error_message, kBufferSize);
   SetMessage(error_message);
 }
 
@@ -33,7 +41,7 @@
   if (sub_system == kSystem) {
     const int kBufferSize = 1024;
     char error_message[kBufferSize];
-    strerror_r(code, error_message, kBufferSize);
+    Utils::StrError(code, error_message, kBufferSize);
     SetMessage(error_message);
   } else if (sub_system == kGetAddressInfo) {
     SetMessage(gai_strerror(code));
@@ -70,11 +78,21 @@
   return false;
 }
 
-int64_t TimerUtils::GetCurrentTimeMilliseconds() {
-  return GetCurrentTimeMicros() / 1000;
+static mach_timebase_info_data_t timebase_info;
+
+void TimerUtils::InitOnce() {
+  kern_return_t kr = mach_timebase_info(&timebase_info);
+  ASSERT(KERN_SUCCESS == kr);
 }
 
-int64_t TimerUtils::GetCurrentTimeMicros() {
+int64_t TimerUtils::GetCurrentMonotonicMillis() {
+  return GetCurrentMonotonicMicros() / 1000;
+}
+
+#if TARGET_OS_IOS
+
+static int64_t GetCurrentTimeMicros() {
+  // gettimeofday has microsecond resolution.
   struct timeval tv;
   if (gettimeofday(&tv, NULL) < 0) {
     UNREACHABLE();
@@ -83,6 +101,34 @@
   return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
 }
 
+#endif  // TARGET_OS_IOS
+
+int64_t TimerUtils::GetCurrentMonotonicMicros() {
+#if TARGET_OS_IOS
+  // On iOS mach_absolute_time stops while the device is sleeping. Instead use
+  // now - KERN_BOOTTIME to get a time difference that is not impacted by clock
+  // changes. KERN_BOOTTIME will be updated by the system whenever the system
+  // clock change.
+  struct timeval boottime;
+  int mib[2] = {CTL_KERN, KERN_BOOTTIME};
+  size_t size = sizeof(boottime);
+  int kr = sysctl(mib, sizeof(mib) / sizeof(mib[0]), &boottime, &size, NULL, 0);
+  ASSERT(KERN_SUCCESS == kr);
+  int64_t now = GetCurrentTimeMicros();
+  int64_t origin = boottime.tv_sec * kMicrosecondsPerSecond;
+  origin += boottime.tv_usec;
+  return now - origin;
+#else
+  ASSERT(timebase_info.denom != 0);
+  // timebase_info converts absolute time tick units into nanoseconds.  Convert
+  // to microseconds.
+  int64_t result = mach_absolute_time() / kNanosecondsPerMicrosecond;
+  result *= timebase_info.numer;
+  result /= timebase_info.denom;
+  return result;
+#endif  // TARGET_OS_IOS
+}
+
 void TimerUtils::Sleep(int64_t millis) {
   struct timespec req;  // requested.
   struct timespec rem;  // remainder.
diff --git a/runtime/bin/utils_win.cc b/runtime/bin/utils_win.cc
index 65d4c65..116ae56 100644
--- a/runtime/bin/utils_win.cc
+++ b/runtime/bin/utils_win.cc
@@ -168,11 +168,7 @@
   return true;
 }
 
-int64_t TimerUtils::GetCurrentTimeMilliseconds() {
-  return GetCurrentTimeMicros() / 1000;
-}
-
-int64_t TimerUtils::GetCurrentTimeMicros() {
+static int64_t GetCurrentTimeMicros() {
   static const int64_t kTimeEpoc = 116444736000000000LL;
   static const int64_t kTimeScaler = 10;  // 100 ns to us.
 
@@ -191,6 +187,38 @@
   return (time.t_ - kTimeEpoc) / kTimeScaler;
 }
 
+static int64_t qpc_ticks_per_second = 0;
+
+void TimerUtils::InitOnce() {
+  LARGE_INTEGER ticks_per_sec;
+  if (!QueryPerformanceFrequency(&ticks_per_sec)) {
+    qpc_ticks_per_second = 0;
+  } else {
+    qpc_ticks_per_second = static_cast<int64_t>(ticks_per_sec.QuadPart);
+  }
+}
+
+int64_t TimerUtils::GetCurrentMonotonicMillis() {
+  return GetCurrentMonotonicMicros() / 1000;
+}
+
+int64_t TimerUtils::GetCurrentMonotonicMicros() {
+  if (qpc_ticks_per_second == 0) {
+    // QueryPerformanceCounter not supported, fallback.
+    return GetCurrentTimeMicros();
+  }
+  // Grab performance counter value.
+  LARGE_INTEGER now;
+  QueryPerformanceCounter(&now);
+  int64_t qpc_value = static_cast<int64_t>(now.QuadPart);
+  // Convert to microseconds.
+  int64_t seconds = qpc_value / qpc_ticks_per_second;
+  int64_t leftover_ticks = qpc_value - (seconds * qpc_ticks_per_second);
+  int64_t result = seconds * kMicrosecondsPerSecond;
+  result += ((leftover_ticks * kMicrosecondsPerSecond) / qpc_ticks_per_second);
+  return result;
+}
+
 void TimerUtils::Sleep(int64_t millis) {
   ::Sleep(millis);
 }
diff --git a/runtime/bin/vmservice/loader.dart b/runtime/bin/vmservice/loader.dart
index cd94f57..9b7355e 100644
--- a/runtime/bin/vmservice/loader.dart
+++ b/runtime/bin/vmservice/loader.dart
@@ -62,32 +62,20 @@
   });
 }
 
-var dataUriRegex = new RegExp(
-    r"data:([\w-]+/[\w-]+)?(;charset=([\w-]+))?(;base64)?,(.*)");
-
 void _loadDataUri(SendPort sp, int id, Uri uri) {
   try {
-    var match = dataUriRegex.firstMatch(uri.toString());
-    if (match == null) throw "Malformed data uri";
-
-    var mimeType = match.group(1);
-    var encoding = match.group(3);
-    var maybeBase64 = match.group(4);
-    var encodedData = match.group(5);
-
-    if (mimeType != "application/dart") {
-      throw "MIME-type must be application/dart";
+    var mime = uri.data.mimeType;
+    if ((mime != "application/dart") &&
+        (mime != "text/plain")) {
+      throw "MIME-type must be application/dart or text/plain: $mime given.";
     }
-    if (encoding != "utf-8") {
-      // Default is ASCII. The C++ portion of the embedder assumes UTF-8.
-      throw "Only utf-8 encoding is supported";
+    var charset = uri.data.charset;
+    if ((charset != "utf-8") &&
+        (charset != "US-ASCII")) {
+      // The C++ portion of the embedder assumes UTF-8.
+      throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
     }
-    if (maybeBase64 != null) {
-      throw "Only percent encoding is supported";
-    }
-
-    var data = UTF8.encode(Uri.decodeComponent(encodedData));
-    _sendResourceResponse(sp, id, data);
+    _sendResourceResponse(sp, id, uri.data.contentAsBytes());
   } catch (e) {
     _sendResourceResponse(sp, id, "Invalid data uri ($uri):\n  $e");
   }
@@ -148,7 +136,9 @@
                    bool traceLoading,
                    Uri packagesFile,
                    List<int> data) {
-  var result = [];
+  // The first entry contains the location of the identified .packages file
+  // instead of a mapping.
+  var result = [packagesFile.toString(), null];
   var index = 0;
   var len = data.length;
   while (index < len) {
@@ -276,7 +266,7 @@
     if (traceLoading) {
       _log("Error loading packages: $e\n$s");
     }
-    sp.send("Uncaught error ($e) loading packags file.");
+    sp.send("Uncaught error ($e) loading packages file.");
   }
 }
 
@@ -378,6 +368,26 @@
   return false;
 }
 
+_loadPackagesData(sp, traceLoading, resource){
+  try {
+    var data = resource.data;
+    var mime = data.mimeType;
+    if (mime != "text/plain") {
+      throw "MIME-type must be text/plain: $mime given.";
+    }
+    var charset = data.charset;
+    if ((charset != "utf-8") &&
+        (charset != "US-ASCII")) {
+      // The C++ portion of the embedder assumes UTF-8.
+      throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
+    }
+    _parsePackagesFile(sp, traceLoading, resource, data.contentAsBytes());
+  } catch (e) {
+    sp.send("Uncaught error ($e) loading packages data.");
+  }
+}
+
+
 _handlePackagesRequest(SendPort sp,
                        bool traceLoading,
                        int id,
@@ -416,6 +426,8 @@
         if (!exists) {
           sp.send("Packages file '$resource' not found.");
         }
+      } else if (resource.scheme == 'data') {
+        _loadPackagesData(sp, traceLoading, resource);
       } else {
         sp.send("Unknown scheme (${resource.scheme}) for package file at "
                 "'$resource'.");
diff --git a/runtime/bin/vmservice/resources.dart b/runtime/bin/vmservice/resources.dart
deleted file mode 100644
index 9153455..0000000
--- a/runtime/bin/vmservice/resources.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of vmservice_io;
-
-String detectMimeType(String name) {
-  var extensionStart = name.lastIndexOf('.');
-  var extension = name.substring(extensionStart+1);
-  switch (extension) {
-    case 'html':
-      return 'text/html; charset=UTF-8';
-    case 'dart':
-      return 'application/dart; charset=UTF-8';
-    case 'js':
-      return 'application/javascript; charset=UTF-8';
-    case 'css':
-      return 'text/css; charset=UTF-8';
-    case 'gif':
-      return 'image/gif';
-    case 'png':
-      return 'image/png';
-    case 'jpg':
-      return 'image/jpeg';
-    case 'jpeg':
-      return 'image/jpeg';
-    case 'svg':
-      return 'image/svg+xml';
-    default:
-      return 'text/plain';
-  }
-}
-
-
-class Resource {
-  final String name;
-  final String mimeType;
-  final List<int> data;
-  Resource(this.name, this.mimeType, this.data);
-  static final Map<String, Resource> resources = new Map<String, Resource>();
-}
-
-ZLibCodec _zlib;
-
-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;
-}
-
-void _triggerResourceLoad() native "VMServiceIO_TriggerResourceLoad";
\ No newline at end of file
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index 8697e65..69e9b2e 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -130,18 +130,20 @@
           request.uri.path == '/' ? ROOT_REDIRECT_PATH : request.uri.path;
 
     if (path == WEBSOCKET_PATH) {
-      WebSocketTransformer.upgrade(request).then((WebSocket webSocket) {
+      WebSocketTransformer.upgrade(request,
+                                   compression: CompressionOptions.OFF).then(
+                                   (WebSocket webSocket) {
         new WebSocketClient(webSocket, _service);
       });
       return;
     }
 
-    var resource = Resource.resources[path];
-    if (resource != null) {
-      // Serving up a static resource (e.g. .css, .html, .png).
+    Asset asset = assets[path];
+    if (asset != null) {
+      // Serving up a static asset (e.g. .css, .html, .png).
       request.response.headers.contentType =
-          ContentType.parse(resource.mimeType);
-      request.response.add(resource.data);
+          ContentType.parse(asset.mimeType);
+      request.response.add(asset.data);
       request.response.close();
       return;
     }
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index eb44a6c..3816aa2 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -5,13 +5,13 @@
 library vmservice_io;
 
 import 'dart:async';
+import 'dart:collection';
 import 'dart:convert';
 import 'dart:io';
 import 'dart:isolate';
 import 'dart:_vmservice';
 
 part 'loader.dart';
-part 'resources.dart';
 part 'server.dart';
 
 // The TCP ip/port that the HTTP server listens on.
@@ -25,9 +25,20 @@
 var _signalWatch;
 var _signalSubscription;
 
-// HTTP servr.
+// HTTP server.
 Server server;
 Future<Server> serverFuture;
+HashMap<String, Asset> _assets;
+HashMap<String, Asset> get assets {
+  if (_assets == null) {
+    try {
+      _assets = Asset.request();
+    } catch (e) {
+      print('Could not load Observatory assets: $e');
+    }
+  }
+  return _assets;
+}
 
 _onShutdown() {
   if (server != null) {
@@ -42,8 +53,6 @@
 }
 
 _bootServer() {
-  // Load resources.
-  _triggerResourceLoad();
   // Lazily create service.
   var service = new VMService();
   service.onShutdown = _onShutdown;
diff --git a/runtime/bin/vmservice_dartium.cc b/runtime/bin/vmservice_dartium.cc
index 40e61ef..cd2c87f 100644
--- a/runtime/bin/vmservice_dartium.cc
+++ b/runtime/bin/vmservice_dartium.cc
@@ -9,7 +9,9 @@
 #include "bin/eventhandler.h"
 #include "bin/platform.h"
 #include "bin/thread.h"
+#include "bin/utils.h"
 #include "bin/vmservice_impl.h"
+#include "zlib/zlib.h"
 
 namespace dart {
 namespace bin {
@@ -33,6 +35,7 @@
   }
   DartUtils::SetOriginalWorkingDirectory();
   Thread::InitOnce();
+  TimerUtils::InitOnce();
   EventHandler::Start();
 }
 
@@ -65,12 +68,13 @@
   // Prepare for script loading by setting up the 'print' and 'timer'
   // closures and setting up 'package root' for URI resolution.
   result = DartUtils::PrepareForScriptLoading(
-      NULL, NULL, NULL, true, false, builtin_lib);
+      NULL, NULL, true, false, builtin_lib);
   CHECK_RESULT(result);
 
   ASSERT(Dart_IsServiceIsolate(isolate));
   if (!VmService::Setup(DEFAULT_VM_SERVICE_SERVER_IP,
-                        DEFAULT_VM_SERVICE_SERVER_PORT)) {
+                        DEFAULT_VM_SERVICE_SERVER_PORT,
+                        false /* running_precompiled */)) {
     fprintf(stderr,
             "Vmservice::Setup failed: %s\n", VmService::GetErrorMessage());
     isolate = NULL;
@@ -91,6 +95,68 @@
 }
 
 
+void VmServiceServer::DecompressAssets(const uint8_t* input,
+                                       unsigned int input_len,
+                                       uint8_t** output,
+                                       unsigned int* output_length) {
+  ASSERT(input != NULL);
+  ASSERT(input_len > 0);
+  ASSERT(output != NULL);
+  ASSERT(output_length != NULL);
+
+  // Initialize output.
+  *output = NULL;
+  *output_length = 0;
+
+  const unsigned int kChunkSize = 256 * 1024;
+  uint8_t chunk_out[kChunkSize];
+  z_stream strm;
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+  strm.opaque = Z_NULL;
+  strm.avail_in = 0;
+  strm.next_in = 0;
+  int ret = inflateInit2(&strm, 32 + MAX_WBITS);
+  ASSERT(ret == Z_OK);
+
+  unsigned int input_cursor = 0;
+  unsigned int output_cursor = 0;
+  do {
+    // Setup input.
+    unsigned int size_in = input_len - input_cursor;
+    if (size_in > kChunkSize) {
+      size_in = kChunkSize;
+    }
+    strm.avail_in = size_in;
+    strm.next_in = const_cast<uint8_t*>(&input[input_cursor]);
+
+    // Inflate until we've exhausted the current input chunk.
+    do {
+      // Setup output.
+      strm.avail_out = kChunkSize;
+      strm.next_out = &chunk_out[0];
+      // Inflate.
+      ret = inflate(&strm, Z_SYNC_FLUSH);
+      // We either hit the end of the stream or made forward progress.
+      ASSERT((ret == Z_STREAM_END) || (ret == Z_OK));
+      // Grow output buffer size.
+      unsigned int size_out = kChunkSize - strm.avail_out;
+      *output_length += size_out;
+      *output = reinterpret_cast<uint8_t*>(realloc(*output, *output_length));
+      // Copy output.
+      memmove(&((*output)[output_cursor]), &chunk_out[0], size_out);
+      output_cursor += size_out;
+    } while (strm.avail_out == 0);
+
+    // We've processed size_in bytes.
+    input_cursor += size_in;
+
+    // We're finished decompressing when zlib tells us.
+  } while (ret != Z_STREAM_END);
+
+  inflateEnd(&strm);
+}
+
 /* DISALLOW_ALLOCATION */
 void VmServiceServer::operator delete(void* pointer)  {
   fprintf(stderr, "unreachable code\n");
diff --git a/runtime/bin/vmservice_dartium.h b/runtime/bin/vmservice_dartium.h
index 9064f73..11067ee 100644
--- a/runtime/bin/vmservice_dartium.h
+++ b/runtime/bin/vmservice_dartium.h
@@ -21,6 +21,9 @@
   static const char* GetServerIP();
   static intptr_t GetServerPort();
 
+  static void DecompressAssets(const uint8_t* input, unsigned int input_len,
+                               uint8_t** output, unsigned int* output_length);
+
 /* DISALLOW_ALLOCATION */
   void operator delete(void* pointer);
  private:
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 6ffe61e..0c0a63c 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -12,7 +12,7 @@
 #include "bin/platform.h"
 #include "bin/thread.h"
 #include "bin/utils.h"
-#include "platform/json.h"
+#include "platform/text_buffer.h"
 
 namespace dart {
 namespace bin {
@@ -31,7 +31,9 @@
   }
 
 #define kLibrarySourceNamePrefix "/vmservice"
-static const char* kVMServiceIOLibraryScriptResourceName = "vmservice_io.dart";
+static const char* const kVMServiceIOLibraryUri = "dart:vmservice_io";
+static const char* const kVMServiceIOLibraryScriptResourceName =
+    "vmservice_io.dart";
 
 struct ResourcesEntry {
   const char* path_;
@@ -87,14 +89,6 @@
 };
 
 
-void TriggerResourceLoad(Dart_NativeArguments args) {
-  Dart_Handle library = Dart_RootLibrary();
-  ASSERT(!Dart_IsError(library));
-  Dart_Handle result = VmService::LoadResources(library);
-  ASSERT(!Dart_IsError(result));
-}
-
-
 void NotifyServerState(Dart_NativeArguments args) {
   Dart_EnterScope();
   const char* ip_chars;
@@ -129,7 +123,6 @@
 
 
 static VmServiceIONativeEntry _VmServiceIONativeEntries[] = {
-  {"VMServiceIO_TriggerResourceLoad", 0, TriggerResourceLoad},
   {"VMServiceIO_NotifyServerState", 2, NotifyServerState},
 };
 
@@ -160,7 +153,23 @@
 intptr_t VmService::server_port_ = 0;
 
 
-bool VmService::Setup(const char* server_ip, intptr_t server_port) {
+bool VmService::LoadForGenPrecompiled() {
+  Dart_Handle result;
+  Dart_SetLibraryTagHandler(LibraryTagHandler);
+  Dart_Handle library = LoadLibrary(kVMServiceIOLibraryScriptResourceName);
+  ASSERT(library != Dart_Null());
+  SHUTDOWN_ON_ERROR(library);
+  result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
+  SHUTDOWN_ON_ERROR(result);
+  result = Dart_FinalizeLoading(false);
+  SHUTDOWN_ON_ERROR(result);
+  return true;
+}
+
+
+bool VmService::Setup(const char* server_ip,
+                      intptr_t server_port,
+                      bool running_precompiled) {
   Dart_Isolate isolate = Dart_CurrentIsolate();
   ASSERT(isolate != NULL);
   SetServerIPAndPort("", 0);
@@ -174,18 +183,28 @@
   // Prepare for script loading by setting up the 'print' and 'timer'
   // closures and setting up 'package root' for URI resolution.
   result = DartUtils::PrepareForScriptLoading(
-      NULL, NULL, NULL, true, false, builtin_lib);
+      NULL, NULL, true, false, builtin_lib);
   SHUTDOWN_ON_ERROR(result);
 
-  // Load main script.
-  Dart_SetLibraryTagHandler(LibraryTagHandler);
-  Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
-  ASSERT(library != Dart_Null());
-  SHUTDOWN_ON_ERROR(library);
-  result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
-  SHUTDOWN_ON_ERROR(result);
-  result = Dart_FinalizeLoading(false);
-  SHUTDOWN_ON_ERROR(result);
+  if (running_precompiled) {
+    Dart_Handle url = DartUtils::NewString(kVMServiceIOLibraryUri);
+    Dart_Handle library = Dart_LookupLibrary(url);
+    SHUTDOWN_ON_ERROR(library);
+    result = Dart_SetRootLibrary(library);
+    SHUTDOWN_ON_ERROR(library);
+    result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
+    SHUTDOWN_ON_ERROR(result);
+  } else {
+    // Load main script.
+    Dart_SetLibraryTagHandler(LibraryTagHandler);
+    Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
+    ASSERT(library != Dart_Null());
+    SHUTDOWN_ON_ERROR(library);
+    result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
+    SHUTDOWN_ON_ERROR(result);
+    result = Dart_FinalizeLoading(false);
+    SHUTDOWN_ON_ERROR(result);
+  }
 
   // Make runnable.
   Dart_ExitScope();
@@ -200,7 +219,7 @@
   Dart_EnterIsolate(isolate);
   Dart_EnterScope();
 
-  library = Dart_RootLibrary();
+  Dart_Handle library = Dart_RootLibrary();
   SHUTDOWN_ON_ERROR(library);
 
   // Set HTTP server state.
@@ -279,73 +298,23 @@
 
 
 Dart_Handle VmService::LoadScript(const char* name) {
-  Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_io");
+  Dart_Handle uri = Dart_NewStringFromCString(kVMServiceIOLibraryUri);
   Dart_Handle source = GetSource(name);
-  return Dart_LoadScript(url, source, 0, 0);
+  return Dart_LoadScript(uri, source, 0, 0);
+}
+
+
+Dart_Handle VmService::LoadLibrary(const char* name) {
+  Dart_Handle uri = Dart_NewStringFromCString(kVMServiceIOLibraryUri);
+  Dart_Handle source = GetSource(name);
+  return Dart_LoadLibrary(uri, source, 0, 0);
 }
 
 
 Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) {
-  Dart_Handle url = Dart_NewStringFromCString(name);
+  Dart_Handle uri = Dart_NewStringFromCString(name);
   Dart_Handle source = GetSource(name);
-  return Dart_LoadSource(library, url, source, 0, 0);
-}
-
-
-Dart_Handle VmService::LoadResource(Dart_Handle library,
-                                    const char* resource_name) {
-  // Prepare for invoke call.
-  Dart_Handle name = Dart_NewStringFromCString(resource_name);
-  RETURN_ERROR_HANDLE(name);
-  const char* data_buffer = NULL;
-  int data_buffer_length = Resources::ResourceLookup(resource_name,
-                                                     &data_buffer);
-  if (data_buffer_length == Resources::kNoSuchInstance) {
-    printf("Could not find %s %s\n", resource_name, resource_name);
-  }
-  ASSERT(data_buffer_length != Resources::kNoSuchInstance);
-  Dart_Handle data_list = Dart_NewTypedData(Dart_TypedData_kUint8,
-                                            data_buffer_length);
-  RETURN_ERROR_HANDLE(data_list);
-  Dart_TypedData_Type type = Dart_TypedData_kInvalid;
-  void* data_list_buffer = NULL;
-  intptr_t data_list_buffer_length = 0;
-  Dart_Handle result = Dart_TypedDataAcquireData(data_list, &type,
-                                                 &data_list_buffer,
-                                                 &data_list_buffer_length);
-  RETURN_ERROR_HANDLE(result);
-  ASSERT(data_buffer_length == data_list_buffer_length);
-  ASSERT(data_list_buffer != NULL);
-  ASSERT(type == Dart_TypedData_kUint8);
-  memmove(data_list_buffer, &data_buffer[0], data_buffer_length);
-  result = Dart_TypedDataReleaseData(data_list);
-  RETURN_ERROR_HANDLE(result);
-
-  // Make invoke call.
-  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;
-}
-
-
-Dart_Handle VmService::LoadResources(Dart_Handle library) {
-  Dart_Handle result = Dart_Null();
-  intptr_t prefixLen = strlen(kLibrarySourceNamePrefix);
-  for (intptr_t i = 0; Resources::Path(i) != NULL; i++) {
-    const char* path = Resources::Path(i);
-    // If it doesn't begin with kLibrarySourceNamePrefix it is a frontend
-    // resource.
-    if (strncmp(path, kLibrarySourceNamePrefix, prefixLen) != 0) {
-      result = LoadResource(library, path);
-      if (Dart_IsError(result)) {
-        break;
-      }
-    }
-  }
-  return result;
+  return Dart_LoadSource(library, uri, source, 0, 0);
 }
 
 
diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h
index e53c752..1780013 100644
--- a/runtime/bin/vmservice_impl.h
+++ b/runtime/bin/vmservice_impl.h
@@ -14,7 +14,11 @@
 
 class VmService {
  public:
-  static bool Setup(const char* server_ip, intptr_t server_port);
+  static bool LoadForGenPrecompiled();
+
+  static bool Setup(const char* server_ip,
+                    intptr_t server_port,
+                    bool running_precompiled);
 
   // Error message if startup failed.
   static const char* GetErrorMessage();
@@ -31,12 +35,12 @@
 
  private:
   static const intptr_t kServerIpStringBufferSize = 256;
-  friend void TriggerResourceLoad(Dart_NativeArguments args);
   friend void NotifyServerState(Dart_NativeArguments args);
 
   static void SetServerIPAndPort(const char* ip, intptr_t port);
   static Dart_Handle GetSource(const char* name);
   static Dart_Handle LoadScript(const char* name);
+  static Dart_Handle LoadLibrary(const char* name);
   static Dart_Handle LoadSource(Dart_Handle library, const char* name);
   static Dart_Handle LoadResources(Dart_Handle library);
   static Dart_Handle LoadResource(Dart_Handle library, const char* name);
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index e5c8805..707686f 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -55,6 +55,41 @@
       },
     },
     {
+      'target_name': 'libdart_precompiled',
+      'type': 'static_library',
+      'dependencies': [
+        'libdart_lib',
+        'libdart_vm_precompiled',
+        'libdouble_conversion',
+        'generate_version_cc_file#host',
+      ],
+      'include_dirs': [
+        '.',
+      ],
+      'sources': [
+        'include/dart_api.h',
+        'include/dart_mirrors_api.h',
+        'include/dart_native_api.h',
+        'include/dart_tools_api.h',
+        'vm/dart_api_impl.cc',
+        'vm/debugger_api_impl.cc',
+        'vm/mirrors_api_impl.cc',
+        'vm/native_api_impl.cc',
+        'vm/version.h',
+        '<(version_cc_file)',
+      ],
+      'defines': [
+        # The only effect of DART_SHARED_LIB is to export the Dart API entries.
+        'DART_SHARED_LIB',
+        'DART_PRECOMPILED',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          'include',
+        ],
+      },
+    },
+    {
       'target_name': 'generate_version_cc_file',
       'type': 'none',
       'toolsets':['host'],
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index e6f643c..4249382 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -501,140 +501,6 @@
     Dart_Isolate isolate,
     Dart_WeakPersistentHandle object);
 
-/**
- * Allocates a prologue weak persistent handle for an object.
- *
- * Prologue weak persistent handles are similar to weak persistent
- * handles but exhibit different behavior during garbage collections
- * that invoke the prologue and epilogue callbacks.  While weak
- * persistent handles always weakly reference their referents,
- * prologue weak persistent handles weakly reference their referents
- * only during a garbage collection that invokes the prologue and
- * epilogue callbacks.  During all other garbage collections, prologue
- * weak persistent handles strongly reference their referents.
- *
- * This handle has the lifetime of the current isolate unless the object
- * pointed to by the handle is garbage collected, in this case the VM
- * automatically deletes the handle after invoking the callback associated
- * with the handle. The handle can also be explicitly deallocated by
- * calling Dart_DeleteWeakPersistentHandle.
- *
- * If the object becomes unreachable the callback is invoked with the weak
- * persistent handle and the peer as arguments. This gives the native code the
- * ability to cleanup data associated with the object and clear out any cached
- * references to the handle. All references to this handle after the callback
- * will be invalid. It is illegal to call into the VM from the callback.
- * If the handle is deleted before the object becomes unreachable,
- * the callback is never invoked.
- *
- * Requires there to be a current isolate.
- *
- * \param object An object.
- * \param peer A pointer to a native object or NULL.  This value is
- *   provided to callback when it is invoked.
- * \param external_allocation_size The number of externally allocated
- *   bytes for peer. Used to inform the garbage collector.
- * \param callback A function pointer that will be invoked sometime
- *   after the object is garbage collected, unless the handle has been deleted.
- *   A valid callback needs to be specified it cannot be NULL.
- *
- * \return Success if the prologue weak persistent handle was created.
- *   Otherwise, returns an error.
- */
-DART_EXPORT Dart_WeakPersistentHandle Dart_NewPrologueWeakPersistentHandle(
-    Dart_Handle object,
-    void* peer,
-    intptr_t external_allocation_size,
-    Dart_WeakPersistentHandleFinalizer callback);
-
-/**
- * Is this object a prologue weak persistent handle?
- *
- * Requires there to be a current isolate.
- */
-DART_EXPORT bool Dart_IsPrologueWeakPersistentHandle(
-    Dart_WeakPersistentHandle object);
-
-typedef struct _Dart_WeakReferenceSetBuilder* Dart_WeakReferenceSetBuilder;
-typedef struct _Dart_WeakReferenceSet* Dart_WeakReferenceSet;
-
-/**
- * Constructs a weak references set builder.
- *
- * \returns a pointer to the weak reference set builder if successful.
- *   Otherwise, returns NULL.
- */
-DART_EXPORT Dart_WeakReferenceSetBuilder Dart_NewWeakReferenceSetBuilder();
-
-/**
- * Constructs a set of weak references from the Cartesian product of
- * the objects in the key set and the objects in values set.
- *
- * \param set_builder The weak references set builder which was created
- *   using Dart_NewWeakReferenceSetBuilder().
- * \param key An object reference.  This references will be
- *   considered weak by the garbage collector.
- * \param value An object reference.  This reference will be
- *   considered weak by garbage collector unless any object reference
- *   in 'keys' is found to be strong.
- *
- * \return a pointer to the weak reference set if successful.
- *   Otherwise, returns NULL.
- */
-DART_EXPORT Dart_WeakReferenceSet Dart_NewWeakReferenceSet(
-    Dart_WeakReferenceSetBuilder set_builder,
-    Dart_WeakPersistentHandle key,
-    Dart_WeakPersistentHandle value);
-
-/**
- * Append the pair of key/value object references to the weak references set.
- *
- * \param reference_set A weak references set into which the pair of key/value
- *   needs to be added.
- * \param key An object reference.  This references will be
- *   considered weak by the garbage collector.
- * \param value An object reference.  This reference will be
- *   considered weak by garbage collector unless any object reference
- *   in 'keys' is found to be strong.
- *
- * \return Success if the prologue weak persistent handle was created.
- *   Otherwise, returns an error.
- */
-DART_EXPORT Dart_Handle Dart_AppendToWeakReferenceSet(
-    Dart_WeakReferenceSet reference_set,
-    Dart_WeakPersistentHandle key,
-    Dart_WeakPersistentHandle value);
-
-/**
- * Append the key object reference to the weak references set.
- *
- * \param reference_set A weak references set into which the key
- *   needs to be added.
- * \param key An object reference.  This references will be
- *   considered weak by the garbage collector.
- *
- * \return Success if the prologue weak persistent handle was created.
- *   Otherwise, returns an error.
- */
-DART_EXPORT Dart_Handle Dart_AppendKeyToWeakReferenceSet(
-    Dart_WeakReferenceSet reference_set,
-    Dart_WeakPersistentHandle key);
-
-/**
- * Append the value object reference to the weak references set.
- *
- * \param reference_set A weak references set into which the key
- *   needs to be added.
- * \param value An object reference.  This references will be
- *   considered weak by the garbage collector.
- *
- * \return Success if the prologue weak persistent handle was created.
- *   Otherwise, returns an error.
- */
-DART_EXPORT Dart_Handle Dart_AppendValueToWeakReferenceSet(
-    Dart_WeakReferenceSet reference_set,
-    Dart_WeakPersistentHandle value);
-
 
 /*
  * ============================
@@ -717,6 +583,8 @@
   int32_t version;
   bool enable_type_checks;
   bool enable_asserts;
+  bool enable_error_on_bad_type;
+  bool enable_error_on_bad_override;
 } Dart_IsolateFlags;
 
 /**
@@ -777,7 +645,7 @@
 typedef Dart_Isolate (*Dart_IsolateCreateCallback)(const char* script_uri,
                                                    const char* main,
                                                    const char* package_root,
-                                                   const char** package_map,
+                                                   const char* package_config,
                                                    Dart_IsolateFlags* flags,
                                                    void* callback_data,
                                                    char** error);
@@ -785,28 +653,14 @@
 /**
  * An isolate interrupt callback function.
  *
- * This callback, provided by the embedder, is called when an isolate
- * is interrupted as a result of a call to Dart_InterruptIsolate().
- * When the callback is called, Dart_CurrentIsolate can be used to
- * figure out which isolate is being interrupted.
- *
- * \return The embedder returns true if the isolate should continue
- *   execution. If the embedder returns false, the isolate will be
- *   unwound (currently unimplemented).
+ * This callback has been DEPRECATED.
  */
 typedef bool (*Dart_IsolateInterruptCallback)();
-/* TODO(turnidge): Define and implement unwinding. */
 
 /**
  * An isolate unhandled exception callback function.
  *
- * This callback, provided by the embedder, is called when an unhandled
- * exception or internal error is thrown during isolate execution. When the
- * callback is invoked, Dart_CurrentIsolate can be used to figure out which
- * isolate was running when the exception was thrown.
- *
- * \param error The unhandled exception or error.  This handle's scope is
- *   only valid until the embedder returns from this callback.
+ * This callback has been DEPRECATED.
  */
 typedef void (*Dart_IsolateUnhandledExceptionCallback)(Dart_Handle error);
 
@@ -868,6 +722,18 @@
 typedef bool (*Dart_EntropySource)(uint8_t* buffer, intptr_t length);
 
 /**
+ * Callback provided by the embedder that is used by the vmservice isolate
+ * to request the asset archive. The asset archive must be an uncompressed tar
+ * archive that is stored in a Uint8List.
+ *
+ * If the embedder has no vmservice isolate assets, the callback can be NULL.
+ *
+ * \return The embedder must return a handle to a Uint8List containing an
+ *   uncompressed tar archive or null.
+ */
+typedef Dart_Handle (*Dart_GetVMServiceAssetsArchive)();
+
+/**
  * Initializes the VM.
  *
  * \param vm_isolate_snapshot A buffer containing a snapshot of the VM isolate
@@ -876,13 +742,15 @@
  *   instructions, or NULL if no snapshot is provided.
  * \param create A function to be called during isolate creation.
  *   See Dart_IsolateCreateCallback.
- * \param interrupt A function to be called when an isolate is interrupted.
- *   See Dart_IsolateInterruptCallback.
- * \param unhandled_exception A function to be called if an isolate has an
- *   unhandled exception.  Set Dart_IsolateUnhandledExceptionCallback.
+ * \param interrupt This parameter has been DEPRECATED.
+ * \param unhandled_exception This parameter has been DEPRECATED.
  * \param shutdown A function to be called when an isolate is shutdown.
  *   See Dart_IsolateShutdownCallback.
  *
+ * \param get_service_assets A function to be called by the service isolate when
+ *    it requires the vmservice assets archive.
+ *    See Dart_GetVMServiceAssetsArchive.
+ *
  * \return NULL if initialization is successful. Returns an error message
  *   otherwise. The caller is responsible for freeing the error message.
  */
@@ -897,7 +765,8 @@
     Dart_FileReadCallback file_read,
     Dart_FileWriteCallback file_write,
     Dart_FileCloseCallback file_close,
-    Dart_EntropySource entropy_source);
+    Dart_EntropySource entropy_source,
+    Dart_GetVMServiceAssetsArchive get_service_assets);
 
 /**
  * Cleanup state in the VM before process termination.
@@ -1010,14 +879,25 @@
 DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate);
 
 /**
- * Notifies the VM that the current isolate is about to make a blocking call.
+ * Notifies the VM that the current thread should not be profiled until a
+ * matching call to Dart_ThreadEnableProfiling is made.
+ *
+ * NOTE: By default, if a thread has entered an isolate it will be profiled.
+ * This function should be used when an embedder knows a thread is about
+ * to make a blocking call and wants to avoid unnecessary interrupts by
+ * the profiler.
  */
-DART_EXPORT void Dart_IsolateBlocked();
+DART_EXPORT void Dart_ThreadDisableProfiling();
 
 /**
- * Notifies the VM that the current isolate is no longer blocked.
+ * Notifies the VM that the current thread should be profiled.
+ *
+ * NOTE: It is only legal to call this function *after* calling
+ *   Dart_ThreadDisableProfiling.
+ *
+ * NOTE: By default, if a thread has entered an isolate it will be profiled.
  */
-DART_EXPORT void Dart_IsolateUnblocked();
+DART_EXPORT void Dart_ThreadEnableProfiling();
 
 /**
  * Exits an isolate. After this call, Dart_CurrentIsolate will
@@ -1030,19 +910,6 @@
  * "pure" dart isolate. Implement and document. */
 
 /**
- * Enables/Disables strict compilation for the current Isolate.
- * Strict compilation includes:
- * - type-checking
- * - asserts
- * - errors on bad types
- * - errors on bad overrides
- *
- * This call requires there to be a current isolate, and requires that there has
- * not yet been any compilation for the current Isolate.
- */
-DART_EXPORT Dart_Handle Dart_IsolateSetStrictCompilation(bool value);
-
-/**
  * Creates a full snapshot of the current isolate heap.
  *
  * A full snapshot is a compact representation of the dart vm isolate heap
@@ -1914,7 +1781,7 @@
  */
 DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list,
                                             intptr_t offset,
-                                            uint8_t* native_array,
+                                            const uint8_t* native_array,
                                             intptr_t length);
 
 
@@ -2103,8 +1970,8 @@
  *
  * \param type Type of object to be constructed.
  * \param constructor_name The name of the constructor to invoke.  Use
- *   Dart_Null() to invoke the unnamed constructor.  This name should
- *   not include the name of the class.
+ *   Dart_Null() or Dart_EmptyString() to invoke the unnamed constructor.
+ *   This name should not include the name of the class.
  * \param number_of_arguments Size of the arguments array.
  * \param arguments An array of arguments to the constructor.
  *
@@ -2197,6 +2064,7 @@
  *
  * \param target An object.
  * \param name The name of the constructor to invoke.
+ *   Use Dart_Null() or Dart_EmptyString() to invoke the unnamed constructor.
  * \param number_of_arguments Size of the arguments array.
  * \param arguments An array of arguments to the function.
  *
@@ -2697,6 +2565,15 @@
  */
 DART_EXPORT Dart_Handle Dart_RootLibrary();
 
+
+/**
+ * Sets the root library for the current isolate.
+ *
+ * \return Returns an error handle if `library` is not a library handle.
+ */
+DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library);
+
+
 /**
  * Lookup or instantiate a type by name and type arguments from a Library.
  *
@@ -2931,4 +2808,7 @@
     uint8_t** instructions_snapshot_buffer,
     intptr_t* instructions_snapshot_size);
 
+
+DART_EXPORT bool Dart_IsRunningPrecompiledCode();
+
 #endif  /* INCLUDE_DART_API_H_ */  /* NOLINT */
diff --git a/runtime/include/dart_native_api.h b/runtime/include/dart_native_api.h
index ea7900d..7dce495 100644
--- a/runtime/include/dart_native_api.h
+++ b/runtime/include/dart_native_api.h
@@ -102,6 +102,16 @@
 DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message);
 
 /**
+ * Posts a message on some port. The message will contain the integer 'message'.
+ *
+ * \param port_id The destination port.
+ * \param message The message to send.
+ *
+ * \return True if the message was posted.
+ */
+DART_EXPORT bool Dart_PostInteger(Dart_Port port_id, int64_t message);
+
+/**
  * A native message handler.
  *
  * This handler is associated with a native port by calling
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index 88c2616..13be4f9 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -894,20 +894,23 @@
 #define DART_TIMELINE_STREAM_COMPILER (1 << 1)
 /** Timeline stream for Dart provided events */
 #define DART_TIMELINE_STREAM_DART (1 << 2)
+/** Timeline stream for debugger provided events */
+#define DART_TIMELINE_STREAM_DEBUGGER (1 << 3)
 /** Timeline stream for embedder provided events */
-#define DART_TIMELINE_STREAM_EMBEDDER (1 << 3)
+#define DART_TIMELINE_STREAM_EMBEDDER (1 << 4)
 /** Timeline stream for GC events */
-#define DART_TIMELINE_STREAM_GC (1 << 4)
+#define DART_TIMELINE_STREAM_GC (1 << 5)
 /** Timeline stream for isolate events */
-#define DART_TIMELINE_STREAM_ISOLATE (1 << 5)
+#define DART_TIMELINE_STREAM_ISOLATE (1 << 6)
 
 /** Timeline stream for VM events */
-#define DART_TIMELINE_STREAM_VM (1 << 6)
+#define DART_TIMELINE_STREAM_VM (1 << 7)
 
 /** Enable all timeline stream recording for an isolate */
 #define DART_TIMELINE_STREAM_ALL (DART_TIMELINE_STREAM_API |                   \
                                   DART_TIMELINE_STREAM_COMPILER |              \
                                   DART_TIMELINE_STREAM_DART |                  \
+                                  DART_TIMELINE_STREAM_DEBUGGER |              \
                                   DART_TIMELINE_STREAM_EMBEDDER |              \
                                   DART_TIMELINE_STREAM_GC |                    \
                                   DART_TIMELINE_STREAM_ISOLATE)
diff --git a/runtime/lib/array_patch.dart b/runtime/lib/array_patch.dart
index abe5a19..c0ddfee 100644
--- a/runtime/lib/array_patch.dart
+++ b/runtime/lib/array_patch.dart
@@ -20,10 +20,10 @@
     return new _List<E>(length);
   }
 
-  /* patch */ factory List.filled(int length, E fill) {
+  /* patch */ factory List.filled(int length, E fill, {bool growable: false}) {
     // All error handling on the length parameter is done at the implementation
     // of new _List.
-    var result = new _List<E>(length);
+    var result = growable ? new _GrowableList<E>(length) : new _List<E>(length);
     if (fill != null) {
       for (int i = 0; i < length; i++) {
         result[i] = fill;
diff --git a/runtime/lib/bool.cc b/runtime/lib/bool.cc
index 83d370f..b536ccf 100644
--- a/runtime/lib/bool.cc
+++ b/runtime/lib/bool.cc
@@ -21,7 +21,7 @@
   GET_NATIVE_ARGUMENT(Bool, default_value, arguments->NativeArgAt(2));
   // Call the embedder to supply us with the environment.
   const String& env_value =
-      String::Handle(Api::CallEnvironmentCallback(isolate, name));
+      String::Handle(Api::CallEnvironmentCallback(thread, name));
   if (!env_value.IsNull()) {
     if (Symbols::True().Equals(env_value)) {
       return Bool::True().raw();
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index 79749fd..224d532 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -73,3 +73,7 @@
     }
   }
 }
+
+patch class StackTrace {
+  /* patch */ static StackTrace get current native "StackTrace_current";
+}
diff --git a/runtime/lib/date.cc b/runtime/lib/date.cc
index 67891b9..cf92809 100644
--- a/runtime/lib/date.cc
+++ b/runtime/lib/date.cc
@@ -14,7 +14,7 @@
 
 static int32_t kMaxAllowedSeconds = 2100000000;
 
-DEFINE_NATIVE_ENTRY(DateNatives_timeZoneName, 1) {
+DEFINE_NATIVE_ENTRY(DateTime_timeZoneName, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(
       Integer, dart_seconds, arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
@@ -26,7 +26,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(DateNatives_timeZoneOffsetInSeconds, 1) {
+DEFINE_NATIVE_ENTRY(DateTime_timeZoneOffsetInSeconds, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(
       Integer, dart_seconds, arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
@@ -38,14 +38,14 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(DateNatives_localTimeZoneAdjustmentInSeconds, 0) {
+DEFINE_NATIVE_ENTRY(DateTime_localTimeZoneAdjustmentInSeconds, 0) {
   int adjustment = OS::GetLocalTimeZoneAdjustmentInSeconds();
   return Integer::New(adjustment);
 }
 
 
-DEFINE_NATIVE_ENTRY(DateNatives_currentTimeMillis, 0) {
-  return Integer::New(OS::GetCurrentTimeMillis());
+DEFINE_NATIVE_ENTRY(DateTime_currentTimeMicros, 0) {
+  return Integer::New(OS::GetCurrentTimeMicros());
 }
 
 }  // namespace dart
diff --git a/runtime/lib/date_patch.dart b/runtime/lib/date_patch.dart
index 6c5c0c2..4697901 100644
--- a/runtime/lib/date_patch.dart
+++ b/runtime/lib/date_patch.dart
@@ -7,28 +7,39 @@
 patch class DateTime {
   // Natives.
   // The natives have been moved up here to work around Issue 10401.
-  static int _getCurrentMs() native "DateNatives_currentTimeMillis";
+  static int _getCurrentMicros() native "DateTime_currentTimeMicros";
 
   static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch)
-      native "DateNatives_timeZoneName";
+      native "DateTime_timeZoneName";
 
   static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch)
-      native "DateNatives_timeZoneOffsetInSeconds";
+      native "DateTime_timeZoneOffsetInSeconds";
 
   static int _localTimeZoneAdjustmentInSeconds()
-      native "DateNatives_localTimeZoneAdjustmentInSeconds";
+      native "DateTime_localTimeZoneAdjustmentInSeconds";
 
-  static const _MILLISECOND_INDEX = 0;
-  static const _SECOND_INDEX = 1;
-  static const _MINUTE_INDEX = 2;
-  static const _HOUR_INDEX = 3;
-  static const _DAY_INDEX = 4;
-  static const _WEEKDAY_INDEX = 5;
-  static const _MONTH_INDEX = 6;
-  static const _YEAR_INDEX = 7;
+  static const _MICROSECOND_INDEX = 0;
+  static const _MILLISECOND_INDEX = 1;
+  static const _SECOND_INDEX = 2;
+  static const _MINUTE_INDEX = 3;
+  static const _HOUR_INDEX = 4;
+  static const _DAY_INDEX = 5;
+  static const _WEEKDAY_INDEX = 6;
+  static const _MONTH_INDEX = 7;
+  static const _YEAR_INDEX = 8;
 
   List __parts;
 
+  /* patch */ DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+                                                  {bool isUtc: false})
+      : this._withValue(
+          millisecondsSinceEpoch * Duration.MICROSECONDS_PER_MILLISECOND,
+          isUtc: isUtc);
+
+  /* patch */ DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+                                                  {bool isUtc: false})
+      : this._withValue(microsecondsSinceEpoch, isUtc: isUtc);
+
   /* patch */ DateTime._internal(int year,
                                  int month,
                                  int day,
@@ -36,27 +47,29 @@
                                  int minute,
                                  int second,
                                  int millisecond,
+                                 int microsecond,
                                  bool isUtc)
       : this.isUtc = isUtc,
-        this.millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
-            year, month, day, hour, minute, second, millisecond, isUtc) {
-    if (millisecondsSinceEpoch == null) throw new ArgumentError();
+        this._value = _brokenDownDateToValue(
+            year, month, day, hour, minute, second, millisecond, microsecond,
+            isUtc) {
+    if (_value == null) throw new ArgumentError();
     if (isUtc == null) throw new ArgumentError();
   }
 
   /* patch */ DateTime._now()
       : isUtc = false,
-        millisecondsSinceEpoch = _getCurrentMs() {
+        _value = _getCurrentMicros() {
   }
 
   /* patch */ String get timeZoneName {
     if (isUtc) return "UTC";
-    return _timeZoneName(millisecondsSinceEpoch);
+    return _timeZoneName(microsecondsSinceEpoch);
   }
 
   /* patch */ Duration get timeZoneOffset {
     if (isUtc) return new Duration();
-    int offsetInSeconds = _timeZoneOffsetInSeconds(millisecondsSinceEpoch);
+    int offsetInSeconds = _timeZoneOffsetInSeconds(microsecondsSinceEpoch);
     return new Duration(seconds: offsetInSeconds);
   }
 
@@ -66,7 +79,7 @@
       const [const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
              const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]];
 
-  static List _computeUpperPart(int localMs) {
+  static List _computeUpperPart(int localMicros) {
     const int DAYS_IN_4_YEARS = 4 * 365 + 1;
     const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
     const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1;
@@ -80,8 +93,8 @@
     int resultDay = 0;
 
     // Always round down.
-    final int daysSince1970 = _flooredDivision(localMs,
-                                               Duration.MILLISECONDS_PER_DAY);
+    final int daysSince1970 = _flooredDivision(localMicros,
+                                               Duration.MICROSECONDS_PER_DAY);
     int days = daysSince1970;
     days += DAYS_OFFSET;
     resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET;
@@ -110,16 +123,20 @@
     }
     resultDay = days - daysUntilMonth[resultMonth - 1] + 1;
 
-    int resultMillisecond = localMs % Duration.MILLISECONDS_PER_SECOND;
+    int resultMicrosecond = localMicros % Duration.MICROSECONDS_PER_MILLISECOND;
+    int resultMillisecond =
+        _flooredDivision(localMicros, Duration.MICROSECONDS_PER_MILLISECOND) %
+            Duration.MILLISECONDS_PER_SECOND;
     int resultSecond =
-        _flooredDivision(localMs, Duration.MILLISECONDS_PER_SECOND) %
+        _flooredDivision(localMicros, Duration.MICROSECONDS_PER_SECOND) %
             Duration.SECONDS_PER_MINUTE;
 
-    int resultMinute = _flooredDivision(localMs,
-                                        Duration.MILLISECONDS_PER_MINUTE);
+    int resultMinute = _flooredDivision(localMicros,
+                                        Duration.MICROSECONDS_PER_MINUTE);
     resultMinute %= Duration.MINUTES_PER_HOUR;
 
-    int resultHour = _flooredDivision(localMs, Duration.MILLISECONDS_PER_HOUR);
+    int resultHour =
+        _flooredDivision(localMicros, Duration.MICROSECONDS_PER_HOUR);
     resultHour %= Duration.HOURS_PER_DAY;
 
     // In accordance with ISO 8601 a week
@@ -129,6 +146,7 @@
           DateTime.DAYS_PER_WEEK) + DateTime.MONDAY;
 
     List list = new List(_YEAR_INDEX + 1);
+    list[_MICROSECOND_INDEX] = resultMicrosecond;
     list[_MILLISECOND_INDEX] = resultMillisecond;
     list[_SECOND_INDEX] = resultSecond;
     list[_MINUTE_INDEX] = resultMinute;
@@ -142,11 +160,32 @@
 
   get _parts {
     if (__parts == null) {
-      __parts = _computeUpperPart(_localDateInUtcMs);
+      __parts = _computeUpperPart(_localDateInUtcMicros);
     }
     return __parts;
   }
 
+  /* patch */ DateTime add(Duration duration) {
+    return new DateTime._withValue(
+        _value + duration.inMicroseconds, isUtc: isUtc);
+  }
+
+  /* patch */ DateTime subtract(Duration duration) {
+    return new DateTime._withValue(
+        _value - duration.inMicroseconds, isUtc: isUtc);
+  }
+
+  /* patch */ Duration difference(DateTime other) {
+    return new Duration(microseconds: _value - other._value);
+  }
+
+  /* patch */ int get millisecondsSinceEpoch =>
+      _value ~/ Duration.MICROSECONDS_PER_MILLISECOND;
+
+  /* patch */ int get microsecondsSinceEpoch => _value;
+
+  /* patch */ int get microsecond => _parts[_MICROSECOND_INDEX];
+
   /* patch */ int get millisecond => _parts[_MILLISECOND_INDEX];
 
   /* patch */ int get second => _parts[_SECOND_INDEX];
@@ -164,26 +203,26 @@
   /* patch */ int get year => _parts[_YEAR_INDEX];
 
   /**
-   * Returns the amount of milliseconds in UTC that represent the same values
+   * Returns the amount of microseconds in UTC that represent the same values
    * as [this].
    *
-   * Say [:t:] is the result of this function, then
-   * * [:this.year == new DateTime.fromMillisecondsSinceEpoch(t, true).year:],
-   * * [:this.month == new DateTime.fromMillisecondsSinceEpoch(t, true).month:],
-   * * [:this.day == new DateTime.fromMillisecondsSinceEpoch(t, true).day:],
-   * * [:this.hour == new DateTime.fromMillisecondsSinceEpoch(t, true).hour:],
+   * Say `t` is the result of this function, then
+   * * `this.year == new DateTime.fromMicrosecondsSinceEpoch(t, true).year`,
+   * * `this.month == new DateTime.fromMicrosecondsSinceEpoch(t, true).month`,
+   * * `this.day == new DateTime.fromMicrosecondsSinceEpoch(t, true).day`,
+   * * `this.hour == new DateTime.fromMicrosecondsSinceEpoch(t, true).hour`,
    * * ...
    *
    * Daylight savings is computed as if the date was computed in [1970..2037].
    * If [this] lies outside this range then it is a year with similar
    * properties (leap year, weekdays) is used instead.
    */
-  int get _localDateInUtcMs {
-    int ms = millisecondsSinceEpoch;
-    if (isUtc) return ms;
+  int get _localDateInUtcMicros {
+    int micros = _value;
+    if (isUtc) return micros;
     int offset =
-        _timeZoneOffsetInSeconds(ms) * Duration.MILLISECONDS_PER_SECOND;
-    return ms + offset;
+        _timeZoneOffsetInSeconds(micros) * Duration.MICROSECONDS_PER_SECOND;
+    return micros + offset;
   }
 
   static int _flooredDivision(int a, int b) {
@@ -204,9 +243,10 @@
     return (y % 4 == 0) && ((y % 16 == 0) || (y % 100 != 0));
   }
 
-  /* patch */ static int _brokenDownDateToMillisecondsSinceEpoch(
+  /// Converts the given broken down date to microseconds.
+  /* patch */ static int _brokenDownDateToValue(
       int year, int month, int day,
-      int hour, int minute, int second, int millisecond,
+      int hour, int minute, int second, int millisecond, int microsecond,
       bool isUtc) {
     // Simplify calculations by working with zero-based month.
     --month;
@@ -225,20 +265,21 @@
     int days = day - 1;
     days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month];
     days += _dayFromYear(year);
-    int millisecondsSinceEpoch =
-        days   * Duration.MILLISECONDS_PER_DAY    +
-        hour   * Duration.MILLISECONDS_PER_HOUR   +
-        minute * Duration.MILLISECONDS_PER_MINUTE +
-        second * Duration.MILLISECONDS_PER_SECOND +
-        millisecond;
+    int microsecondsSinceEpoch =
+        days   * Duration.MICROSECONDS_PER_DAY    +
+        hour   * Duration.MICROSECONDS_PER_HOUR   +
+        minute * Duration.MICROSECONDS_PER_MINUTE +
+        second * Duration.MICROSECONDS_PER_SECOND +
+        millisecond * Duration.MICROSECONDS_PER_MILLISECOND +
+        microsecond;
 
     // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of
     // the valid range we do a preliminary test that weeds out values that can
     // not become valid even with timezone adjustments.
     // The timezone adjustment is always less than a day, so adding a security
     // margin of one day should be enough.
-    if (millisecondsSinceEpoch.abs() >
-        (_MAX_MILLISECONDS_SINCE_EPOCH + Duration.MILLISECONDS_PER_DAY)) {
+    if (microsecondsSinceEpoch.abs() >
+        _MAX_MILLISECONDS_SINCE_EPOCH * 1000 + Duration.MICROSECONDS_PER_DAY) {
       return null;
     }
 
@@ -246,15 +287,17 @@
       // Note that we need to remove the local timezone adjustement before
       // asking for the correct zone offset.
       int adjustment = _localTimeZoneAdjustmentInSeconds() *
-          Duration.MILLISECONDS_PER_SECOND;
+          Duration.MICROSECONDS_PER_SECOND;
+
       int zoneOffset =
-          _timeZoneOffsetInSeconds(millisecondsSinceEpoch - adjustment);
-      millisecondsSinceEpoch -= zoneOffset * Duration.MILLISECONDS_PER_SECOND;
+          _timeZoneOffsetInSeconds(microsecondsSinceEpoch - adjustment);
+      microsecondsSinceEpoch -= zoneOffset * Duration.MICROSECONDS_PER_SECOND;
     }
-    if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) {
+    if (microsecondsSinceEpoch.abs() >
+        _MAX_MILLISECONDS_SINCE_EPOCH * Duration.MICROSECONDS_PER_MILLISECOND) {
       return null;
     }
-    return millisecondsSinceEpoch;
+    return microsecondsSinceEpoch;
   }
 
   static int _weekDay(y) {
@@ -304,25 +347,25 @@
       // According to V8 this fast case works for dates from 1970 to 2099.
       return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS;
     }
-    int ms = secondsSinceEpoch * Duration.MILLISECONDS_PER_SECOND;
-    return _computeUpperPart(ms)[_YEAR_INDEX];
+    int micros = secondsSinceEpoch * Duration.MICROSECONDS_PER_SECOND;
+    return _computeUpperPart(micros)[_YEAR_INDEX];
   }
 
   /**
    * Returns a date in seconds that is equivalent to the current date. An
-   * equivalent date has the same fields ([:month:], [:day:], etc.) as the
-   * [this], but the [:year:] is in the range [1970..2037].
+   * equivalent date has the same fields (`month`, `day`, etc.) as the
+   * [this], but the `year` is in the range [1970..2037].
    *
    * * The time since the beginning of the year is the same.
    * * If [this] is in a leap year then the returned seconds are in a leap
    *   year, too.
    * * The week day of [this] is the same as the one for the returned date.
    */
-  static int _equivalentSeconds(int millisecondsSinceEpoch) {
+  static int _equivalentSeconds(int microsecondsSinceEpoch) {
     const int CUT_OFF_SECONDS = 2100000000;
 
-    int secondsSinceEpoch = _flooredDivision(millisecondsSinceEpoch,
-                                             Duration.MILLISECONDS_PER_SECOND);
+    int secondsSinceEpoch = _flooredDivision(microsecondsSinceEpoch,
+                                             Duration.MICROSECONDS_PER_SECOND);
 
     if (secondsSinceEpoch < 0 || secondsSinceEpoch >= CUT_OFF_SECONDS) {
       int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch);
@@ -335,13 +378,13 @@
     return secondsSinceEpoch;
   }
 
-  static int _timeZoneOffsetInSeconds(int millisecondsSinceEpoch) {
-    int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch);
+  static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) {
+    int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
     return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds);
   }
 
-  static String _timeZoneName(int millisecondsSinceEpoch) {
-    int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch);
+  static String _timeZoneName(int microsecondsSinceEpoch) {
+    int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
     return _timeZoneNameForClampedSeconds(equivalentSeconds);
   }
 }
diff --git a/runtime/lib/developer.cc b/runtime/lib/developer.cc
index d2466af..ead1de1 100644
--- a/runtime/lib/developer.cc
+++ b/runtime/lib/developer.cc
@@ -60,6 +60,14 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Developer_postEvent, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(String, event_kind, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, event_data, arguments->NativeArgAt(1));
+  Service::SendExtensionEvent(isolate, event_kind, event_data);
+  return Object::null();
+}
+
+
 DEFINE_NATIVE_ENTRY(Developer_lookupExtension, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(0));
   return isolate->LookupServiceExtensionHandler(name);
diff --git a/runtime/lib/developer.dart b/runtime/lib/developer.dart
index 71b1f5c..af505ff 100644
--- a/runtime/lib/developer.dart
+++ b/runtime/lib/developer.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:isolate';
+
 patch bool debugger({bool when: true,
                      String message}) native "Developer_debugger";
 
@@ -50,8 +52,88 @@
      Object error,
      StackTrace stackTrace) native "Developer_log";
 
+patch void _postEvent(String eventKind, String eventData)
+    native "Developer_postEvent";
+
 patch ServiceExtensionHandler _lookupExtension(String method)
     native "Developer_lookupExtension";
 
 patch _registerExtension(String method, ServiceExtensionHandler handler)
     native "Developer_registerExtension";
+
+// This code is only invoked when there is no other Dart code on the stack.
+_runExtension(ServiceExtensionHandler handler,
+              String method,
+              List<String> parameterKeys,
+              List<String> parameterValues,
+              SendPort replyPort,
+              Object id) {
+  var parameters = {};
+  for (var i = 0; i < parameterKeys.length; i++) {
+    parameters[parameterKeys[i]] = parameterValues[i];
+  }
+  var response;
+  try {
+    response = handler(method, parameters);
+  } catch (e, st) {
+    var errorDetails = (st == null) ? '$e' : '$e\n$st';
+    response = new ServiceExtensionResponse.error(
+        ServiceExtensionResponse.kExtensionError,
+        errorDetails);
+    _postResponse(replyPort, id, response);
+    return;
+  }
+  if (response is! Future) {
+    response = new ServiceExtensionResponse.error(
+          ServiceExtensionResponse.kExtensionError,
+          "Extension handler must return a Future");
+    _postResponse(replyPort, id, response);
+    return;
+  }
+  response.catchError((e, st) {
+    // Catch any errors eagerly and wrap them in a ServiceExtensionResponse.
+    var errorDetails = (st == null) ? '$e' : '$e\n$st';
+    return new ServiceExtensionResponse.error(
+        ServiceExtensionResponse.kExtensionError,
+        errorDetails);
+  }).then((response) {
+    // Post the valid response or the wrapped error after verifying that
+    // the response is a ServiceExtensionResponse.
+    if (response is! ServiceExtensionResponse) {
+      response = new ServiceExtensionResponse.error(
+          ServiceExtensionResponse.kExtensionError,
+          "Extension handler must complete to a ServiceExtensionResponse");
+    }
+    _postResponse(replyPort, id, response);
+  }).catchError((e, st) {
+    // We do not expect any errors to occur in the .then or .catchError blocks
+    // but, suppress them just in case.
+  });
+}
+
+// This code is only invoked by _runExtension.
+_postResponse(SendPort replyPort,
+              Object id,
+              ServiceExtensionResponse response) {
+  assert(replyPort != null);
+  if (id == null) {
+    // No id -> no response.
+    replyPort.send(null);
+    return;
+  }
+  assert(id != null);
+  StringBuffer sb = new StringBuffer();
+  sb.write('{"jsonrpc":"2.0",');
+  if (response._isError()) {
+    sb.write('"error":');
+  } else {
+    sb.write('"result":');
+  }
+  sb.write('${response._toString()},');
+  if (id is String) {
+    sb.write('"id":"$id"}');
+  } else {
+    sb.write('"id":$id}');
+  }
+  replyPort.send(sb.toString());
+}
diff --git a/runtime/lib/double.dart b/runtime/lib/double.dart
index ea7c1cf..87d8046 100644
--- a/runtime/lib/double.dart
+++ b/runtime/lib/double.dart
@@ -46,17 +46,14 @@
     return _remainder(other.toDouble());
   }
   double _remainder(double other) native "Double_remainder";
-  double operator -() {
-    // Handles properly 0.0, NAN, and other doubles.
-    return this._flipSignBit;
-  }
-  double get _flipSignBit native "Double_flipSignBit";
+
+  double operator -() native "Double_flipSignBit";
 
   bool operator ==(other) {
     if (!(other is num)) return false;
     return _equal(other.toDouble());
   }
-  bool _equal(double other)native "Double_equal";
+  bool _equal(double other) native "Double_equal";
   bool _equalToInteger(int other) native "Double_equalToInteger";
   bool operator <(num other) {
     return other > this;
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index e8d655c..8deeee4 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -237,7 +237,7 @@
   GET_NATIVE_ARGUMENT(Integer, default_value, arguments->NativeArgAt(2));
   // Call the embedder to supply us with the environment.
   const String& env_value =
-      String::Handle(Api::CallEnvironmentCallback(isolate, name));
+      String::Handle(Api::CallEnvironmentCallback(thread, name));
   if (!env_value.IsNull()) {
     const Integer& result = Integer::Handle(ParseInteger(env_value));
     if (!result.IsNull()) {
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index 8e95506..3089830 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -11,13 +11,25 @@
 class VMLibraryHooks {
   // Example: "dart:isolate _Timer._factory"
   static var timerFactory;
+
   // Example: "dart:io _EventHandler._sendData"
   static var eventHandlerSendData;
+
+  // A nullary closure that answers the current clock value in milliseconds.
+  // Example: "dart:io _EventHandler._timerMillisecondClock"
+  static var timerMillisecondClock;
+
   // Implementation of Resource.readAsBytes.
   static var resourceReadAsBytes;
+
   // Implementation of package root/map provision.
-  static var getPackageRoot;
-  static var getPackageMap;
+  static var packageRootString;
+  static var packageConfigString;
+  static var packageRootUriFuture;
+  static var packageConfigUriFuture;
+  static var resolvePackageUriFuture;
+
+  static var platformScript;
 }
 
 patch class CodeUnits {
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 349788c..773bac4 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -2,11 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+#include "include/dart_native_api.h"
 #include "platform/assert.h"
 #include "vm/bootstrap_natives.h"
 #include "vm/class_finalizer.h"
 #include "vm/dart.h"
 #include "vm/dart_api_impl.h"
+#include "vm/dart_api_message.h"
 #include "vm/dart_entry.h"
 #include "vm/exceptions.h"
 #include "vm/lockers.h"
@@ -23,6 +25,9 @@
 
 namespace dart {
 
+DEFINE_FLAG(bool, i_like_slow_isolate_spawn, false,
+            "Block the parent thread when loading spawned isolates.");
+
 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
   void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
   return reinterpret_cast<uint8_t*>(new_ptr);
@@ -102,18 +107,22 @@
   // TODO(iposva): Allow for arbitrary messages to be sent.
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
 
-  uint8_t* data = NULL;
-
   const Dart_Port destination_port_id = port.Id();
   const bool can_send_any_object = isolate->origin_id() == port.origin_id();
 
-  MessageWriter writer(&data, &allocator, can_send_any_object);
-  writer.WriteMessage(obj);
+  if (ApiObjectConverter::CanConvert(obj.raw())) {
+    PortMap::PostMessage(new Message(
+        destination_port_id, obj.raw(), Message::kNormalPriority));
+  } else {
+    uint8_t* data = NULL;
+    MessageWriter writer(&data, &allocator, can_send_any_object);
+    writer.WriteMessage(obj);
 
-  // TODO(turnidge): Throw an exception when the return value is false?
-  PortMap::PostMessage(new Message(destination_port_id,
-                                   data, writer.BytesWritten(),
-                                   Message::kNormalPriority));
+    // TODO(turnidge): Throw an exception when the return value is false?
+    PortMap::PostMessage(new Message(destination_port_id,
+                                     data, writer.BytesWritten(),
+                                     Message::kNormalPriority));
+  }
   return Object::null();
 }
 
@@ -125,70 +134,95 @@
 }
 
 
-static bool CreateIsolate(Isolate* parent_isolate,
-                          IsolateSpawnState* state,
-                          char** error) {
-  Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
-  if (callback == NULL) {
-    *error = strdup("Null callback specified for isolate creation\n");
-    return false;
+class SpawnIsolateTask : public ThreadPool::Task {
+ public:
+  explicit SpawnIsolateTask(IsolateSpawnState* state) : state_(state) {}
+
+  virtual void Run() {
+    // Create a new isolate.
+    char* error = NULL;
+    Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
+    if (callback == NULL) {
+      state_->DecrementSpawnCount();
+      ReportError(
+          "Isolate spawn is not supported by this Dart implementation\n");
+      delete state_;
+      state_ = NULL;
+      return;
+    }
+
+    Dart_IsolateFlags api_flags;
+    state_->isolate_flags()->CopyTo(&api_flags);
+
+    Isolate* isolate = reinterpret_cast<Isolate*>(
+        (callback)(state_->script_url(),
+                   state_->function_name(),
+                   state_->package_root(),
+                   state_->package_config(),
+                   &api_flags,
+                   state_->init_data(),
+                   &error));
+    state_->DecrementSpawnCount();
+    if (isolate == NULL) {
+      ReportError(error);
+      delete state_;
+      state_ = NULL;
+      free(error);
+      return;
+    }
+
+    if (state_->origin_id() != ILLEGAL_PORT) {
+      // For isolates spawned using spawnFunction we set the origin_id
+      // to the origin_id of the parent isolate.
+      isolate->set_origin_id(state_->origin_id());
+    }
+    MutexLocker ml(isolate->mutex());
+    state_->set_isolate(reinterpret_cast<Isolate*>(isolate));
+    isolate->set_spawn_state(state_);
+    state_ = NULL;
+    if (isolate->is_runnable()) {
+      isolate->Run();
+    }
   }
 
-  Dart_IsolateFlags api_flags;
-  state->isolate_flags()->CopyTo(&api_flags);
+ private:
+  void ReportError(const char* error) {
+    Dart_CObject error_cobj;
+    error_cobj.type = Dart_CObject_kString;
+    error_cobj.value.as_string = const_cast<char*>(error);
+    if (!Dart_PostCObject(state_->parent_port(), &error_cobj)) {
+      // Perhaps the parent isolate died or closed the port before we
+      // could report the error.  Ignore.
+    }
+  }
 
-  void* init_data = parent_isolate->init_callback_data();
-  Isolate* child_isolate = reinterpret_cast<Isolate*>(
-      (callback)(state->script_url(),
-                 state->function_name(),
-                 state->package_root(),
-                 state->package_map(),
-                 &api_flags,
-                 init_data,
-                 error));
-  if (child_isolate == NULL) {
-    return false;
-  }
-  if (!state->is_spawn_uri()) {
-    // For isolates spawned using the spawn semantics we set
-    // the origin_id to the origin_id of the parent isolate.
-    child_isolate->set_origin_id(parent_isolate->origin_id());
-  }
-  state->set_isolate(reinterpret_cast<Isolate*>(child_isolate));
-  return true;
+  IsolateSpawnState* state_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask);
+};
+
+
+static const char* String2UTF8(const String& str) {
+  intptr_t len = Utf8::Length(str);
+  char* result = new char[len + 1];
+  str.ToUTF8(reinterpret_cast<uint8_t*>(result), len);
+  result[len] = 0;
+
+  return result;
 }
 
 
-static void Spawn(Isolate* parent_isolate, IsolateSpawnState* state) {
-  Thread::ExitIsolate();
-  // Create a new isolate.
-  char* error = NULL;
-  if (!CreateIsolate(parent_isolate, state, &error)) {
-    Thread::EnterIsolate(parent_isolate);
-    delete state;
-    const String& msg = String::Handle(String::New(error));
-    free(error);
-    ThrowIsolateSpawnException(msg);
-  }
-  Thread::EnterIsolate(parent_isolate);
-  // Start the new isolate if it is already marked as runnable.
-  Isolate* spawned_isolate = state->isolate();
-  MutexLocker ml(spawned_isolate->mutex());
-  spawned_isolate->set_spawn_state(state);
-  if (spawned_isolate->is_runnable()) {
-    spawned_isolate->Run();
-  }
-}
-
-
-DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 7) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 10) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(1));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(2));
-  GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(3));
-  GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(4));
-  GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5));
-  GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, script_uri, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(2));
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
+  GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
+  GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(5));
+  GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(6));
+  GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(7));
+  GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(8));
+  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(9));
 
   if (closure.IsClosure()) {
     Function& func = Function::Handle();
@@ -202,17 +236,49 @@
       // Get the parent function so that we get the right function name.
       func = func.parent_function();
 
+      const char* utf8_package_root =
+          packageRoot.IsNull() ? NULL : String2UTF8(packageRoot);
+      const char* utf8_package_config =
+          packageConfig.IsNull() ? NULL : String2UTF8(packageConfig);
+
       bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value();
       Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id();
       Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id();
 
-      Spawn(isolate, new IsolateSpawnState(port.Id(),
-                                           func,
-                                           message,
-                                           paused.value(),
-                                           fatal_errors,
-                                           on_exit_port,
-                                           on_error_port));
+      IsolateSpawnState* state =
+          new IsolateSpawnState(port.Id(),
+                                isolate->origin_id(),
+                                isolate->init_callback_data(),
+                                String2UTF8(script_uri),
+                                func,
+                                message,
+                                isolate->spawn_count_monitor(),
+                                isolate->spawn_count(),
+                                utf8_package_root,
+                                utf8_package_config,
+                                paused.value(),
+                                fatal_errors,
+                                on_exit_port,
+                                on_error_port);
+      ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);
+
+      isolate->IncrementSpawnCount();
+      if (FLAG_i_like_slow_isolate_spawn) {
+        // We block the parent isolate while the child isolate loads.
+        Isolate* saved = Isolate::Current();
+        Thread::ExitIsolate();
+        spawn_task->Run();
+        delete spawn_task;
+        spawn_task = NULL;
+        Thread::EnterIsolate(saved);
+      } else if (!Dart::thread_pool()->Run(spawn_task)) {
+        // Running on the thread pool failed. Clean up everything.
+        state->DecrementSpawnCount();
+        delete state;
+        state = NULL;
+        delete spawn_task;
+        spawn_task = NULL;
+      }
       return Object::null();
     }
   }
@@ -223,28 +289,19 @@
 }
 
 
-static char* String2UTF8(const String& str) {
-  intptr_t len = Utf8::Length(str);
-  char* result = new char[len + 1];
-  str.ToUTF8(reinterpret_cast<uint8_t*>(result), len);
-  result[len] = 0;
-
-  return result;
-}
-
-
-static char* CanonicalizeUri(Isolate* isolate,
-                             const Library& library,
-                             const String& uri,
-                             char** error) {
-  char* result = NULL;
-  Zone* zone = isolate->current_zone();
+static const char* CanonicalizeUri(Thread* thread,
+                                   const Library& library,
+                                   const String& uri,
+                                   char** error) {
+  const char* result = NULL;
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
   Dart_LibraryTagHandler handler = isolate->library_tag_handler();
   if (handler != NULL) {
     Dart_EnterScope();
     Dart_Handle handle = handler(Dart_kCanonicalizeUrl,
-                                 Api::NewHandle(isolate, library.raw()),
-                                 Api::NewHandle(isolate, uri.raw()));
+                                 Api::NewHandle(thread, library.raw()),
+                                 Api::NewHandle(thread, uri.raw()));
     const Object& obj = Object::Handle(Api::UnwrapHandle(handle));
     if (obj.IsString()) {
       result = String2UTF8(String::Cast(obj));
@@ -284,64 +341,77 @@
 
   GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9));
 
-  GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(10));
-  GET_NATIVE_ARGUMENT(Array, packages, arguments->NativeArgAt(11));
+  GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(10));
+  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(11));
 
+  if (Dart::IsRunningPrecompiledCode()) {
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, String::Handle(String::New(
+        "Isolate.spawnUri not supported under precompilation")));
+    Exceptions::ThrowByType(Exceptions::kUnsupported, args);
+    UNREACHABLE();
+  }
 
   // Canonicalize the uri with respect to the current isolate.
   const Library& root_lib =
       Library::Handle(isolate->object_store()->root_library());
   char* error = NULL;
-  char* canonical_uri = CanonicalizeUri(isolate, root_lib, uri, &error);
+  const char* canonical_uri = CanonicalizeUri(thread, root_lib, uri, &error);
   if (canonical_uri == NULL) {
     const String& msg = String::Handle(String::New(error));
     ThrowIsolateSpawnException(msg);
   }
 
-  char* utf8_package_root =
-      package_root.IsNull() ? NULL : String2UTF8(package_root);
-
-  char** utf8_package_map = NULL;
-  if (!packages.IsNull()) {
-    intptr_t len = packages.Length();
-    utf8_package_map = new char*[len + 1];
-
-    Object& entry = Object::Handle();
-    for (intptr_t i = 0; i < len; i++) {
-      entry = packages.At(i);
-      if (!entry.IsString()) {
-        const String& msg = String::Handle(String::NewFormatted(
-            "Bad value in package map: %s", entry.ToCString()));
-        ThrowIsolateSpawnException(msg);
-      }
-      utf8_package_map[i] = String2UTF8(String::Cast(entry));
-    }
-    // NULL terminated array.
-    utf8_package_map[len] = NULL;
-  }
+  const char* utf8_package_root =
+      packageRoot.IsNull() ? NULL : String2UTF8(packageRoot);
+  const char* utf8_package_config =
+      packageConfig.IsNull() ? NULL : String2UTF8(packageConfig);
 
   bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value();
   Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id();
   Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id();
 
-  IsolateSpawnState* state = new IsolateSpawnState(
-      port.Id(),
-      canonical_uri,
-      utf8_package_root,
-      const_cast<const char**>(utf8_package_map),
-      args,
-      message,
-      paused.value(),
-      fatal_errors,
-      on_exit_port,
-      on_error_port);
+  IsolateSpawnState* state =
+      new IsolateSpawnState(
+          port.Id(),
+          isolate->init_callback_data(),
+          canonical_uri,
+          utf8_package_root,
+          utf8_package_config,
+          args,
+          message,
+          isolate->spawn_count_monitor(),
+          isolate->spawn_count(),
+          paused.value(),
+          fatal_errors,
+          on_exit_port,
+          on_error_port);
+
   // If we were passed a value then override the default flags state for
   // checked mode.
   if (!checked.IsNull()) {
     state->isolate_flags()->set_checked(checked.value());
   }
 
-  Spawn(isolate, state);
+  ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);
+
+  isolate->IncrementSpawnCount();
+  if (FLAG_i_like_slow_isolate_spawn) {
+    // We block the parent isolate while the child isolate loads.
+    Isolate* saved = Isolate::Current();
+    Thread::ExitIsolate();
+    spawn_task->Run();
+    delete spawn_task;
+    spawn_task = NULL;
+    Thread::EnterIsolate(saved);
+  } else if (!Dart::thread_pool()->Run(spawn_task)) {
+    // Running on the thread pool failed. Clean up everything.
+    state->DecrementSpawnCount();
+    delete state;
+    state = NULL;
+    delete spawn_task;
+    spawn_task = NULL;
+  }
   return Object::null();
 }
 
@@ -357,6 +427,13 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Isolate_getCurrentRootUriStr, 0) {
+  const Library& root_lib = Library::Handle(zone,
+      isolate->object_store()->root_library());
+  return root_lib.url();
+}
+
+
 DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1));
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 41389a5..09ae531 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -130,8 +130,6 @@
     return sendPort.hashCode;
   }
 
-  Uri get remotePortUri => new Uri.https('localhost', '55');
-
   /**** Internal implementation details ****/
   _get_id() native "RawReceivePortImpl_get_id";
   _get_sendport() native "RawReceivePortImpl_get_sendport";
@@ -272,37 +270,74 @@
 
 patch class Isolate {
   static final _currentIsolate = _getCurrentIsolate();
+  static final _rootUri = _getCurrentRootUri();
 
   /* patch */ static Isolate get current => _currentIsolate;
 
+  /* patch */ static Future<Uri> get packageRoot {
+    var hook = VMLibraryHooks.packageRootUriFuture;
+    if (hook == null) {
+      throw new UnsupportedError("Isolate.packageRoot");
+    }
+    return hook();
+  }
+
+  /* patch */ static Future<Uri> get packageConfig {
+    var hook = VMLibraryHooks.packageConfigUriFuture;
+    if (hook == null) {
+      throw new UnsupportedError("Isolate.packageConfig");
+    }
+    return hook();
+  }
+
+  /* patch */ static Future<Uri> resolvePackageUri(Uri packageUri) {
+    var hook = VMLibraryHooks.resolvePackageUriFuture;
+    if (hook == null) {
+      throw new UnsupportedError("Isolate.resolvePackageUri");
+    }
+    return hook(packageUri);
+  }
+
+  static bool _packageSupported() =>
+      (VMLibraryHooks.packageRootUriFuture != null) &&
+      (VMLibraryHooks.packageConfigUriFuture != null) &&
+      (VMLibraryHooks.resolvePackageUriFuture != null);
+
   /* patch */ static Future<Isolate> spawn(
       void entryPoint(message), var message,
       {bool paused: false, bool errorsAreFatal,
-       SendPort onExit, SendPort onError}) {
+       SendPort onExit, SendPort onError}) async {
     // `paused` isn't handled yet.
     RawReceivePort readyPort;
     try {
       // The VM will invoke [_startIsolate] with entryPoint as argument.
       readyPort = new RawReceivePort();
-      _spawnFunction(readyPort.sendPort, entryPoint, message,
-                     paused, errorsAreFatal, onExit, onError);
-      Completer completer = new Completer<Isolate>.sync();
-      readyPort.handler = (readyMessage) {
-        readyPort.close();
-        assert(readyMessage is List);
-        assert(readyMessage.length == 2);
-        SendPort controlPort = readyMessage[0];
-        List capabilities = readyMessage[1];
-        completer.complete(new Isolate(controlPort,
-                                       pauseCapability: capabilities[0],
-                                       terminateCapability: capabilities[1]));
-      };
-      return completer.future;
+      var packageRoot = null;
+      var packageConfig = null;
+      if (Isolate._packageSupported()) {
+        packageRoot = (await Isolate.packageRoot)?.toString();
+        packageConfig = (await Isolate.packageConfig)?.toString();
+      }
+
+      var script = VMLibraryHooks.platformScript;
+      if (script == null) {
+        // We do not have enough information to support spawning the new
+        // isolate.
+        throw new UnsupportedError("Isolate.spawn");
+      }
+      if (script.scheme == "package") {
+        script = await Isolate.resolvePackageUri(script);
+      }
+
+      _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message,
+                     paused, errorsAreFatal, onExit, onError,
+                     packageRoot, packageConfig);
+      return await _spawnCommon(readyPort);
     } catch (e, st) {
       if (readyPort != null) {
         readyPort.close();
       }
-      return new Future<Isolate>.error(e, st);
+      return await new Future<Isolate>.error(e, st);
     }
   }
 
@@ -314,40 +349,102 @@
        bool errorsAreFatal,
        bool checked,
        Map<String, String> environment,
-       Uri packageRoot}) {
+       Uri packageRoot,
+       Uri packageConfig,
+       bool automaticPackageResolution: false}) async {
     RawReceivePort readyPort;
-    if (environment != null) throw new UnimplementedError("environment");
+    if (environment != null) {
+      throw new UnimplementedError("environment");
+    }
+
+    // Verify that no mutually exclusive arguments have been passed.
+    if (automaticPackageResolution) {
+      if (packageRoot != null) {
+        throw new ArgumentError("Cannot simultaneously request "
+                                "automaticPackageResolution and specify a"
+                                "packageRoot.");
+      }
+      if (packageConfig != null) {
+        throw new ArgumentError("Cannot simultaneously request "
+                                "automaticPackageResolution and specify a"
+                                "packageConfig.");
+      }
+    } else {
+      if ((packageRoot != null) && (packageConfig != null)) {
+        throw new ArgumentError("Cannot simultaneously specify a "
+                                "packageRoot and a packageConfig.");
+      }
+    }
     try {
+      // Resolve the uri against the current isolate's root Uri first.
+      var spawnedUri = _rootUri.resolveUri(uri);
+
+      // Inherit this isolate's package resolution setup if not overridden.
+      if (!automaticPackageResolution &&
+          (packageRoot == null) &&
+          (packageConfig == null)) {
+        if (Isolate._packageSupported()) {
+          packageRoot = await Isolate.packageRoot;
+          packageConfig = await Isolate.packageConfig;
+        }
+      }
+
+      // Ensure to resolve package: URIs being handed in as parameters.
+      if (packageRoot != null) {
+        // Avoid calling resolvePackageUri if not stricly necessary in case
+        // the API is not supported.
+        if (packageRoot.scheme == "package") {
+          packageRoot = await Isolate.resolvePackageUri(packageRoot);
+        }
+      } else if (packageConfig != null) {
+        // Avoid calling resolvePackageUri if not strictly necessary in case
+        // the API is not supported.
+        if (packageConfig.scheme == "package") {
+          packageConfig = await Isolate.resolvePackageUri(packageConfig);
+        }
+      }
+
       // The VM will invoke [_startIsolate] and not `main`.
       readyPort = new RawReceivePort();
-      var packageRootString =
-          (packageRoot == null) ? null : packageRoot.toString();
-      var packagesList = null;
+      var packageRootString = packageRoot?.toString();
+      var packageConfigString = packageConfig?.toString();
 
-      _spawnUri(readyPort.sendPort, uri.toString(),
+      _spawnUri(readyPort.sendPort, spawnedUri.toString(),
                 args, message,
                 paused, onExit, onError,
                 errorsAreFatal, checked,
                 null, /* environment */
-                packageRootString, packagesList);
-      Completer completer = new Completer<Isolate>.sync();
-      readyPort.handler = (readyMessage) {
+                packageRootString, packageConfigString);
+      return await _spawnCommon(readyPort);
+    } catch (e, st) {
+      if (readyPort != null) {
         readyPort.close();
-        assert(readyMessage is List);
-        assert(readyMessage.length == 2);
+      }
+      rethrow;
+    }
+  }
+
+  static Future<Isolate> _spawnCommon(RawReceivePort readyPort) {
+    Completer completer = new Completer<Isolate>.sync();
+    readyPort.handler = (readyMessage) {
+      readyPort.close();
+      if (readyMessage is List && readyMessage.length == 2) {
         SendPort controlPort = readyMessage[0];
         List capabilities = readyMessage[1];
         completer.complete(new Isolate(controlPort,
                                        pauseCapability: capabilities[0],
                                        terminateCapability: capabilities[1]));
-      };
-      return completer.future;
-    } catch (e, st) {
-      if (readyPort != null) {
-        readyPort.close();
+      } else if (readyMessage is String) {
+        // We encountered an error while starting the new isolate.
+        completer.completeError(new IsolateSpawnException(
+            'Unable to spawn isolate: ${readyMessage}'));
+      } else {
+        // This shouldn't happen.
+        completer.completeError(new IsolateSpawnException(
+            "Internal error: unexpected format for ready message: "
+            "'${readyMessage}'"));
       }
-      return new Future<Isolate>.error(e, st);
-    }
+    };
     return completer.future;
   }
 
@@ -365,9 +462,11 @@
   static const _ERROR_FATAL = 9;
 
 
-  static void _spawnFunction(SendPort readyPort, Function topLevelFunction,
+  static void _spawnFunction(SendPort readyPort, String uri,
+                             Function topLevelFunction,
                              var message, bool paused, bool errorsAreFatal,
-                             SendPort onExit, SendPort onError)
+                             SendPort onExit, SendPort onError,
+                             String packageRoot, String packageConfig)
       native "Isolate_spawnFunction";
 
   static void _spawnUri(SendPort readyPort, String uri,
@@ -375,7 +474,7 @@
                         bool paused, SendPort onExit, SendPort onError,
                         bool errorsAreFatal, bool checked,
                         List environment,
-                        String packageRoot, List packages)
+                        String packageRoot, String packageConfig)
       native "Isolate_spawnUri";
 
   static void _sendOOB(port, msg) native "Isolate_sendOOB";
@@ -470,4 +569,15 @@
 
   static List _getPortAndCapabilitiesOfCurrentIsolate()
       native "Isolate_getPortAndCapabilitiesOfCurrentIsolate";
+
+  static Uri _getCurrentRootUri() {
+    try {
+      return Uri.parse(_getCurrentRootUriStr());
+    } catch (e, s) {
+      return null;
+    }
+  }
+
+  static String _getCurrentRootUriStr()
+      native "Isolate_getCurrentRootUriStr";
 }
diff --git a/runtime/lib/lib_prefix.dart b/runtime/lib/lib_prefix.dart
index fb9fe81..4f509da 100644
--- a/runtime/lib/lib_prefix.dart
+++ b/runtime/lib/lib_prefix.dart
@@ -7,21 +7,24 @@
 
 // This type corresponds to the VM-internal class LibraryPrefix.
 class _LibraryPrefix {
-
   bool _load() native "LibraryPrefix_load";
   Error _loadError() native "LibraryPrefix_loadError";
   bool isLoaded() native "LibraryPrefix_isLoaded";
-
   bool _invalidateDependentCode()
       native "LibraryPrefix_invalidateDependentCode";
 
   loadLibrary() {
-    var completer = _outstandingLoadRequests[this];
-    if (completer != null) {
-      return completer.future;
+    for (int i = 0; i < _outstandingLoadRequests.length; i++) {
+      if (_outstandingLoadRequests[i][0] == this) {
+        return _outstandingLoadRequests[i][1].future;
+      }
     }
-    completer = new Completer<bool>();
-    _outstandingLoadRequests[this] = completer;
+
+    var completer = new Completer<bool>();
+    var pair = new List();
+    pair.add(this);
+    pair.add(completer);
+    _outstandingLoadRequests.add(pair);
     Timer.run(() {
       var hasCompleted = this._load();
       // Loading can complete immediately, for example when the same
@@ -32,20 +35,23 @@
       if (hasCompleted) {
         _invalidateDependentCode();
         completer.complete(true);
-        _outstandingLoadRequests.remove(this);
+        _outstandingLoadRequests.remove(pair);
       }
     });
     return completer.future;
   }
 }
 
-var _outstandingLoadRequests = new Map<_LibraryPrefix, Completer>();
-
+// A list of two element lists. The first element is the _LibraryPrefix. The
+// second element is the Completer for the load request.
+var _outstandingLoadRequests = new List<List>();
 
 // Called from the VM when all outstanding load requests have
 // finished.
 _completeDeferredLoads() {
-  _outstandingLoadRequests.forEach((prefix, completer) {
+  for (int i = 0; i < _outstandingLoadRequests.length; i++) {
+    var prefix = _outstandingLoadRequests[i][0];
+    var completer = _outstandingLoadRequests[i][1];
     var error = prefix._loadError();
     if (error != null) {
       completer.completeError(error);
@@ -53,6 +59,6 @@
       prefix._invalidateDependentCode();
       completer.complete(true);
     }
-  });
+  }
   _outstandingLoadRequests.clear();
 }
diff --git a/runtime/lib/libgen_in.cc b/runtime/lib/libgen_in.cc
index 03dedf8..4e10df6 100644
--- a/runtime/lib/libgen_in.cc
+++ b/runtime/lib/libgen_in.cc
@@ -9,5 +9,5 @@
 const char* {{VAR_NAME}}[] = {
 {{LIBRARY_SOURCE_MAP}}
 {{PART_SOURCE_MAP}}
-  NULL, NULL
+  NULL, NULL, NULL
 };
diff --git a/runtime/lib/math.cc b/runtime/lib/math.cc
index f4b4626..d383471 100644
--- a/runtime/lib/math.cc
+++ b/runtime/lib/math.cc
@@ -93,9 +93,10 @@
 
 
 // Implements:
-//   var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
-//   _state[kSTATE_LO] = state & _MASK_32;
-//   _state[kSTATE_HI] = state >> 32;
+//   var state =
+//       ((_A * (_state[_kSTATE_LO])) + _state[_kSTATE_HI]) & (1 << 64) - 1);
+//   _state[_kSTATE_LO] = state & (1 << 32) - 1);
+//   _state[_kSTATE_HI] = state >> 32;
 DEFINE_NATIVE_ENTRY(Random_nextState, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, receiver, arguments->NativeArgAt(0));
   const TypedData& array = TypedData::Handle(GetRandomStateArray(receiver));
@@ -145,8 +146,8 @@
 //     hash = 0x5A17;
 //   }
 //   var result = new Uint32List(2);
-//   result[kSTATE_LO] = seed & _MASK_32;
-//   result[kSTATE_HI] = seed >> 32;
+//   result[_kSTATE_LO] = seed & ((1 << 32) - 1);
+//   result[_kSTATE_HI] = seed >> 32;
 //   return result;
 DEFINE_NATIVE_ENTRY(Random_setupSeed, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, seed_int, arguments->NativeArgAt(0));
@@ -198,4 +199,25 @@
   return CreateRandomState(zone, seed);
 }
 
+
+DEFINE_NATIVE_ENTRY(SecureRandom_getBytes, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, count, arguments->NativeArgAt(0));
+  const intptr_t n = count.Value();
+  ASSERT((n > 0) && (n <= 8));
+  uint8_t buffer[8];
+  Dart_EntropySource entropy_source = isolate->entropy_source_callback();
+  if ((entropy_source == NULL) || !entropy_source(buffer, n)) {
+    const String& error = String::Handle(String::New(
+        "No source of cryptographically secure random numbers available."));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
+    Exceptions::ThrowByType(Exceptions::kUnsupported, args);
+  }
+  uint64_t result = 0;
+  for (intptr_t i = 0; i < n; i++) {
+    result = (result << 8) | buffer[i];
+  }
+  return Integer::New(result);
+}
+
 }  // namespace dart
diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart
index e9cc083..667174c 100644
--- a/runtime/lib/math_patch.dart
+++ b/runtime/lib/math_patch.dart
@@ -90,14 +90,18 @@
                                         .._nextState()
                                         .._nextState();
   }
+
+  /*patch*/ factory Random.secure() {
+    return new _SecureRandom();
+  }
 }
 
 
 class _Random implements Random {
   // Internal state of the random number generator.
   final _state;
-  static const kSTATE_LO = 0;
-  static const kSTATE_HI = 1;
+  static const _kSTATE_LO = 0;
+  static const _kSTATE_HI = 1;  // Unused in Dart code.
 
   _Random._withState(Uint32List this._state);
 
@@ -106,32 +110,33 @@
   // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1.
 
   // Implements:
-  //   var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
-  //   _state[kSTATE_LO] = state & _MASK_32;
-  //   _state[kSTATE_HI] = state >> 32;
+  //   var state =
+  //       ((_A * (_state[_kSTATE_LO])) + _state[_kSTATE_HI]) & ((1 << 64) - 1);
+  //   _state[_kSTATE_LO] = state & ((1 << 32) - 1);
+  //   _state[_kSTATE_HI] = state >> 32;
   // This is a native to prevent 64-bit operations in Dart, which
   // fail with --throw_on_javascript_int_overflow.
   void _nextState() native "Random_nextState";
 
   int nextInt(int max) {
     const limit = 0x3FFFFFFF;
-    if (max <= 0 || ((max > limit) && (max > _POW2_32))) {
-      throw new ArgumentError("max must be positive and < 2^32:"
-                                         " $max");
+    if ((max <= 0) || ((max > limit) && (max > _POW2_32))) {
+      throw new RangeError.range(max, 1, _POW2_32, "max",
+                                 "Must be positive and <= 2^32");
     }
     if ((max & -max) == max) {
       // Fast case for powers of two.
       _nextState();
-      return _state[kSTATE_LO] & (max - 1);
+      return _state[_kSTATE_LO] & (max - 1);
     }
 
     var rnd32;
     var result;
     do {
       _nextState();
-      rnd32 = _state[kSTATE_LO];
+      rnd32 = _state[_kSTATE_LO];
       result = rnd32 % max;
-    } while ((rnd32 - result + max) >= _POW2_32);
+    } while ((rnd32 - result + max) > _POW2_32);
     return result;
   }
 
@@ -143,9 +148,7 @@
     return nextInt(2) == 0;
   }
 
-  // Constants used by the algorithm or masking.
-  static const _MASK_32 = (1 << 32) - 1;
-  static const _MASK_64 = (1 << 64) - 1;
+  // Constants used by the algorithm.
   static const _POW2_32 = 1 << 32;
   static const _POW2_53_D = 1.0 * (1 << 53);
   static const _POW2_27_D = 1.0 * (1 << 27);
@@ -164,6 +167,46 @@
   static int _nextSeed() {
     // Trigger the PRNG once to change the internal state.
     _prng._nextState();
-    return _prng._state[kSTATE_LO];
+    return _prng._state[_kSTATE_LO];
   }
 }
+
+
+class _SecureRandom implements Random {
+  _SecureRandom() {
+    // Throw early in constructor if entropy source is not hooked up.
+    _getBytes(1);
+  }
+
+  // Return count bytes of entropy as a positive integer; count <= 8.
+  static int _getBytes(int count) native "SecureRandom_getBytes";
+
+  int nextInt(int max) {
+    RangeError.checkValueInInterval(
+        max, 1, _POW2_32, "max", "Must be positive and <= 2^32");
+    final byteCount = ((max - 1).bitLength + 7) >> 3;
+    if (byteCount == 0) {
+      return 0;  // Not random if max == 1.
+    }
+    var rnd;
+    var result;
+    do {
+      rnd = _getBytes(byteCount);
+      result = rnd % max;
+    } while ((rnd - result + max) > (1 << (byteCount << 3)));
+    return result;
+  }
+
+  double nextDouble() {
+    return (_getBytes(7) >> 3) / _POW2_53_D;
+  }
+
+  bool nextBool() {
+    return _getBytes(1).isEven;
+  }
+
+  // Constants used by the algorithm.
+  static const _POW2_32 = 1 << 32;
+  static const _POW2_53_D = 1.0 * (1 << 53);
+}
+
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index d33b754..05453f8 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1206,6 +1206,11 @@
 DEFINE_NATIVE_ENTRY(ClassMirror_type_variables, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Class& klass = Class::Handle(ref.GetClassReferent());
+  const Error& error = Error::Handle(zone, klass.EnsureIsFinalized(thread));
+  if (!error.IsNull()) {
+    Exceptions::PropagateError(error);
+    UNREACHABLE();
+  }
   return CreateTypeVariableList(klass);
 }
 
@@ -1229,7 +1234,7 @@
   // arguments have been provided, or all arguments are dynamic. Return a list
   // of typemirrors on dynamic in this case.
   if (args.IsNull()) {
-    arg_type ^= Object::dynamic_type();
+    arg_type ^= Object::dynamic_type().raw();
     type_mirror ^= CreateTypeMirror(arg_type);
     for (intptr_t i = 0; i < num_params; i++) {
       result.SetAt(i, type_mirror);
@@ -1721,8 +1726,7 @@
   }
 
   const intptr_t num_explicit_args = explicit_args.Length();
-  const intptr_t num_implicit_args =
-      redirected_constructor.IsGenerativeConstructor() ? 2 : 1;
+  const intptr_t num_implicit_args = 1;
   const Array& args =
       Array::Handle(Array::New(num_implicit_args + num_explicit_args));
 
@@ -1753,9 +1757,9 @@
 
   Instance& new_object = Instance::Handle();
   if (redirected_constructor.IsGenerativeConstructor()) {
-    // Constructors get the uninitialized object and a constructor phase. Note
-    // we have delayed allocation until after the function type and argument
-    // matching checks.
+    // Constructors get the uninitialized object.
+    // Note we have delayed allocation until after the function
+    // type and argument matching checks.
     new_object = Instance::New(redirected_klass);
     if (!type_arguments.IsNull()) {
       // The type arguments will be null if the class has no type parameters, in
@@ -1764,7 +1768,6 @@
       new_object.SetTypeArguments(type_arguments);
     }
     args.SetAt(0, new_object);
-    args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
   } else {
     // Factories get type arguments.
     args.SetAt(0, type_arguments);
@@ -2024,8 +2027,7 @@
     token_pos = cls.token_pos();
   } else if (decl.IsField()) {
     const Field& field = Field::Cast(decl);
-    const Class& owner = Class::Handle(field.owner());
-    script = owner.script();
+    script = field.script();
     token_pos = field.token_pos();
   } else if (decl.IsTypeParameter()) {
     const TypeParameter& type_var = TypeParameter::Cast(decl);
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 8b099c9..0a839fb 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -293,6 +293,7 @@
   bool get isConstConstructor => false;
   bool get isGenerativeConstructor => false;
   bool get isFactoryConstructor => false;
+  bool get isExternal => false;
   bool get isRedirectingConstructor => false;
   bool get isAbstract => false;
 
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index d8693a1..72fcc3e 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -155,17 +155,14 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(Object_instanceOf, 5) {
+DEFINE_NATIVE_ENTRY(Object_instanceOf, 4) {
   const Instance& instance =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
-  // Instantiator at position 1 is not used. It is passed along so that the call
-  // can be easily converted to an optimized implementation. Instantiator is
-  // used to populate the subtype cache.
   const TypeArguments& instantiator_type_arguments =
-      TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(2));
+      TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(1));
   const AbstractType& type =
-      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(3));
-  const Bool& negate = Bool::CheckedHandle(zone, arguments->NativeArgAt(4));
+      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(2));
+  const Bool& negate = Bool::CheckedHandle(zone, arguments->NativeArgAt(3));
   ASSERT(type.IsFinalized());
   ASSERT(!type.IsMalformed());
   ASSERT(!type.IsMalbounded());
@@ -267,15 +264,12 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(Object_as, 4) {
+DEFINE_NATIVE_ENTRY(Object_as, 3) {
   const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0));
-  // Instantiator at position 1 is not used. It is passed along so that the call
-  // can be easily converted to an optimized implementation. Instantiator is
-  // used to populate the subtype cache.
   const TypeArguments& instantiator_type_arguments =
-      TypeArguments::CheckedHandle(arguments->NativeArgAt(2));
+      TypeArguments::CheckedHandle(arguments->NativeArgAt(1));
   const AbstractType& type =
-      AbstractType::CheckedHandle(arguments->NativeArgAt(3));
+      AbstractType::CheckedHandle(arguments->NativeArgAt(2));
   ASSERT(type.IsFinalized());
   ASSERT(!type.IsMalformed());
   ASSERT(!type.IsMalbounded());
diff --git a/runtime/lib/object_patch.dart b/runtime/lib/object_patch.dart
index be42a57..b61b6a6 100644
--- a/runtime/lib/object_patch.dart
+++ b/runtime/lib/object_patch.dart
@@ -53,10 +53,7 @@
 
   // Call this function instead of inlining instanceof, thus collecting
   // type feedback and reducing code size of unoptimized code.
-  bool _instanceOf(instantiator,
-                   instantiator_type_arguments,
-                   type,
-                   bool negate)
+  bool _instanceOf(instantiator_type_arguments, type, bool negate)
       native "Object_instanceOf";
 
   bool _instanceOfDouble(bool negate) native "Object_instanceOfDouble";
@@ -67,7 +64,7 @@
 
   // Call this function instead of inlining 'as', thus collecting type
   // feedback. Returns receiver.
-  _as(instantiator, instantiator_type_arguments, type) native "Object_as";
+  _as(instantiator_type_arguments, type) native "Object_as";
 
   static _symbolMapToStringMap(Map<Symbol, dynamic> map) {
     var result = new Map<String, dynamic>();
diff --git a/runtime/lib/stacktrace.cc b/runtime/lib/stacktrace.cc
index 6175b24..7b79314 100644
--- a/runtime/lib/stacktrace.cc
+++ b/runtime/lib/stacktrace.cc
@@ -11,7 +11,8 @@
 namespace dart {
 
 static void IterateFrames(const GrowableObjectArray& code_list,
-                          const GrowableObjectArray& pc_offset_list) {
+                          const GrowableObjectArray& pc_offset_list,
+                          int skip_frames) {
   StackFrameIterator frames(StackFrameIterator::kDontValidateFrames);
   StackFrame* frame = frames.NextFrame();
   ASSERT(frame != NULL);  // We expect to find a dart invocation frame.
@@ -19,15 +20,35 @@
   Smi& offset = Smi::Handle();
   while (frame != NULL) {
     if (frame->IsDartFrame()) {
-      code = frame->LookupDartCode();
-      offset = Smi::New(frame->pc() - code.EntryPoint());
-      code_list.Add(code);
-      pc_offset_list.Add(offset);
+      if (skip_frames > 0) {
+        skip_frames--;
+      } else {
+        code = frame->LookupDartCode();
+        offset = Smi::New(frame->pc() - code.EntryPoint());
+        code_list.Add(code);
+        pc_offset_list.Add(offset);
+      }
     }
     frame = frames.NextFrame();
   }
 }
 
+// Creates a Stacktrace object from the current stack.
+//
+// Skips the first skip_frames Dart frames.
+static const Stacktrace& GetCurrentStacktrace(int skip_frames) {
+  const GrowableObjectArray& code_list =
+      GrowableObjectArray::Handle(GrowableObjectArray::New());
+  const GrowableObjectArray& pc_offset_list =
+      GrowableObjectArray::Handle(GrowableObjectArray::New());
+  IterateFrames(code_list, pc_offset_list, skip_frames);
+  const Array& code_array = Array::Handle(Array::MakeArray(code_list));
+  const Array& pc_offset_array =
+      Array::Handle(Array::MakeArray(pc_offset_list));
+  const Stacktrace& stacktrace = Stacktrace::Handle(
+      Stacktrace::New(code_array, pc_offset_array));
+  return stacktrace;
+}
 
 // An utility method for convenient printing of dart stack traces when
 // inside 'gdb'. Note: This function will only work when there is a
@@ -35,17 +56,13 @@
 // set in dart code and control is got inside 'gdb' without going through
 // the runtime or native transition stub.
 void _printCurrentStacktrace() {
-  const GrowableObjectArray& code_list =
-      GrowableObjectArray::Handle(GrowableObjectArray::New());
-  const GrowableObjectArray& pc_offset_list =
-      GrowableObjectArray::Handle(GrowableObjectArray::New());
-  IterateFrames(code_list, pc_offset_list);
-  const Array& code_array = Array::Handle(Array::MakeArray(code_list));
-  const Array& pc_offset_array =
-      Array::Handle(Array::MakeArray(pc_offset_list));
-  const Stacktrace& stacktrace = Stacktrace::Handle(
-      Stacktrace::New(code_array, pc_offset_array));
+  const Stacktrace& stacktrace = GetCurrentStacktrace(0);
   OS::PrintErr("=== Current Trace:\n%s===\n", stacktrace.ToCString());
 }
 
+DEFINE_NATIVE_ENTRY(StackTrace_current, 0) {
+  const Stacktrace& stacktrace = GetCurrentStacktrace(1);
+  return stacktrace.raw();
+}
+
 }  // namespace dart
diff --git a/runtime/lib/stopwatch.cc b/runtime/lib/stopwatch.cc
index 7d8464a..934aba5 100644
--- a/runtime/lib/stopwatch.cc
+++ b/runtime/lib/stopwatch.cc
@@ -10,14 +10,12 @@
 namespace dart {
 
 DEFINE_NATIVE_ENTRY(Stopwatch_now, 0) {
-  // TODO(iposva): investigate other hi-res time sources such as cycle count.
-  return Integer::New(OS::GetCurrentTimeMicros());
+  return Integer::New(OS::GetCurrentMonotonicTicks());
 }
 
 
 DEFINE_NATIVE_ENTRY(Stopwatch_frequency, 0) {
-  // TODO(iposva): investigate other hi-res time sources such as cycle count.
-  return Integer::New(1000000);
+  return Integer::New(OS::GetCurrentMonotonicFrequency());
 }
 
 }  // namespace dart
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 2eae245..62e5aac 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -20,7 +20,7 @@
   GET_NATIVE_ARGUMENT(String, default_value, arguments->NativeArgAt(2));
   // Call the embedder to supply us with the environment.
   const String& env_value =
-      String::Handle(Api::CallEnvironmentCallback(isolate, name));
+      String::Handle(Api::CallEnvironmentCallback(thread, name));
   if (!env_value.IsNull()) {
     return Symbols::New(env_value);
   }
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index 32f5896..3d307da 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -14,8 +14,11 @@
 namespace dart {
 
 // Native implementations for the dart:developer library.
-DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0) {
-  return Integer::New(OS::GetCurrentTraceMicros(), Heap::kNew, true);
+
+DEFINE_NATIVE_ENTRY(Timeline_getIsolateNum, 0) {
+  return Integer::New(static_cast<int64_t>(isolate->main_port()),
+                      Heap::kOld,
+                      true);
 }
 
 
@@ -28,6 +31,11 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0) {
+  return Integer::New(OS::GetCurrentMonotonicMicros(), Heap::kNew, true);
+}
+
+
 DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 6) {
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, id, arguments->NativeArgAt(1));
@@ -41,16 +49,24 @@
     return Object::null();
   }
 
-  if (!isolate->GetDartStream()->Enabled()) {
-    // Dart stream is not enabled for this isolate, do nothing.
+  TimelineEvent* event = isolate->GetDartStream()->StartEvent();
+  if (event == NULL) {
+    // Stream was turned off.
     return Object::null();
   }
 
-
   int64_t pid = OS::ProcessId();
-  int64_t tid = OSThread::ThreadIdToIntPtr(OSThread::GetCurrentThreadTraceId());
-
-  char* event = OS::SCreate(zone,
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
+  int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id());
+  // Convert phase to a C string and perform a sanity check.
+  const char* phase_string = phase.ToCString();
+  ASSERT(phase_string != NULL);
+  ASSERT((phase_string[0] == 'n') ||
+         (phase_string[0] == 'b') ||
+         (phase_string[0] == 'e'));
+  ASSERT(phase_string[1] == '\0');
+  char* json = OS::SCreate(zone,
       "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
       "\"ts\":%" Pd64 ",\"ph\":\"%s\",\"id\":%" Pd64 ", \"args\":%s}",
       name.ToCString(),
@@ -58,12 +74,26 @@
       tid,
       pid,
       start.AsInt64Value(),
-      phase.ToCString(),
+      phase_string,
       id.AsInt64Value(),
       args.ToCString());
 
-  // event was allocated in the zone and will be copied by AppendDartEvent.
-  recorder->AppendDartEvent(isolate, event);
+  switch (phase_string[0]) {
+    case 'n':
+      event->AsyncInstant("", id.AsInt64Value(), start.AsInt64Value());
+    break;
+    case 'b':
+      event->AsyncBegin("", id.AsInt64Value(), start.AsInt64Value());
+    break;
+    case 'e':
+      event->AsyncEnd("", id.AsInt64Value(), start.AsInt64Value());
+    break;
+    default:
+      UNREACHABLE();
+  }
+
+  // json was allocated in the zone and a copy will be stored in event.
+  event->CompleteWithPreSerializedJSON(json);
 
   return Object::null();
 }
@@ -81,16 +111,19 @@
     return Object::null();
   }
 
-  if (!isolate->GetDartStream()->Enabled()) {
-    // Dart stream is not enabled for this isolate, do nothing.
+  TimelineEvent* event = isolate->GetDartStream()->StartEvent();
+  if (event == NULL) {
+    // Stream was turned off.
     return Object::null();
   }
 
   int64_t duration = end.AsInt64Value() - start.AsInt64Value();
   int64_t pid = OS::ProcessId();
-  int64_t tid = OSThread::ThreadIdToIntPtr(OSThread::GetCurrentThreadTraceId());
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
+  int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id());
 
-  char* event = OS::SCreate(zone,
+  char* json = OS::SCreate(zone,
       "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
       "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ",\"args\":%s}",
       name.ToCString(),
@@ -101,8 +134,49 @@
       duration,
       args.ToCString());
 
-  // event was allocated in the zone and will be copied by AppendDartEvent.
-  recorder->AppendDartEvent(isolate, event);
+  event->Duration("", start.AsInt64Value(), end.AsInt64Value());
+  // json was allocated in the zone and a copy will be stored in event.
+  event->CompleteWithPreSerializedJSON(json);
+
+  return Object::null();
+}
+
+
+DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 4) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(3));
+
+  TimelineEventRecorder* recorder = Timeline::recorder();
+  if (recorder == NULL) {
+    return Object::null();
+  }
+
+  TimelineEvent* event = isolate->GetDartStream()->StartEvent();
+  if (event == NULL) {
+    // Stream was turned off.
+    return Object::null();
+  }
+
+  int64_t pid = OS::ProcessId();
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
+  int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id());
+
+  char* json = OS::SCreate(zone,
+      "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
+      "\"ts\":%" Pd64 ",\"ph\":\"I\",\"args\":%s}",
+      name.ToCString(),
+      category.ToCString(),
+      tid,
+      pid,
+      start.AsInt64Value(),
+      args.ToCString());
+
+  event->Instant("", start.AsInt64Value());
+  // json was allocated in the zone and a copy will be stored in event.
+  event->CompleteWithPreSerializedJSON(json);
 
   return Object::null();
 }
diff --git a/runtime/lib/timeline.dart b/runtime/lib/timeline.dart
index 12b9278..3a336e2 100644
--- a/runtime/lib/timeline.dart
+++ b/runtime/lib/timeline.dart
@@ -8,6 +8,8 @@
 
 patch int _getNextAsyncId() native "Timeline_getNextAsyncId";
 
+patch int _getIsolateNum() native "Timeline_getIsolateNum";
+
 patch void _reportTaskEvent(
     int start,
     int taskId,
@@ -22,3 +24,9 @@
     String category,
     String name,
     String argumentsAsJson) native "Timeline_reportCompleteEvent";
+
+patch void _reportInstantEvent(
+    int start,
+    String category,
+    String name,
+    String argumentsAsJson) native "Timeline_reportInstantEvent";
diff --git a/runtime/lib/timer_impl.dart b/runtime/lib/timer_impl.dart
index d4a8160..a0660e1 100644
--- a/runtime/lib/timer_impl.dart
+++ b/runtime/lib/timer_impl.dart
@@ -172,7 +172,7 @@
     // to nearest millisecond, not up, so that time + duration is before
     // duration milliseconds from now. Using microsecond timers like
     // Stopwatch allows detecting that the timer fires early.
-    int now = new DateTime.now().millisecondsSinceEpoch;
+    int now = VMLibraryHooks.timerMillisecondClock();
     int wakeupTime = (milliSeconds == 0) ? now : (now + 1 + milliSeconds);
 
     _Timer timer = new _Timer._internal(callback,
@@ -232,7 +232,7 @@
     if (_milliSeconds > 0) {
       _wakeupTime += _milliSeconds;
     } else {
-      _wakeupTime = new DateTime.now().millisecondsSinceEpoch;
+      _wakeupTime = VMLibraryHooks.timerMillisecondClock();
     }
   }
 
@@ -340,7 +340,7 @@
     } else {
       // Collect pending timers from the timer heap which have expired at this
       // time.
-      var currentTime = new DateTime.now().millisecondsSinceEpoch;
+      var currentTime = VMLibraryHooks.timerMillisecondClock();
       var timer;
       while (!_heap.isEmpty && (_heap.first._wakeupTime <= currentTime)) {
         timer = _heap.removeFirst();
diff --git a/runtime/lib/uri_patch.dart b/runtime/lib/uri_patch.dart
index 93abe0d..2664b9b 100644
--- a/runtime/lib/uri_patch.dart
+++ b/runtime/lib/uri_patch.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import "dart:convert" show ASCII;
+
 // VM implementation of Uri.
 typedef Uri _UriBaseClosure();
 
@@ -21,4 +23,51 @@
   /* patch */ static Uri get base => _uriBaseClosure();
 
   static bool get _isWindowsPlatform native "Uri_isWindowsPlatform";
+
+  /* patch */ static String _uriEncode(List<int> canonicalTable,
+                                       String text,
+                                       Encoding encoding,
+                                       bool spaceToPlus) {
+    // First check if the text will be changed by encoding.
+    int i = 0;
+    if (identical(encoding, UTF8) ||
+        identical(encoding, LATIN1) ||
+        identical(encoding, ASCII)) {
+      // Encoding is compatible with the original string.
+      // Find first character that needs encoding.
+      for (; i < text.length; i++) {
+        var char = text.codeUnitAt(i);
+        if (char >= 128 ||
+            canonicalTable[char >> 4] & (1 << (char & 0x0f)) == 0) {
+          break;
+        }
+      }
+    }
+    if (i == text.length) return text;
+
+    // Encode the string into bytes then generate an ASCII only string
+    // by percent encoding selected bytes.
+    StringBuffer result = new StringBuffer();
+    for (int j = 0; j < i; j++) {
+      result.writeCharCode(text.codeUnitAt(j));
+    }
+
+    // TODO(lrn): Is there a way to only encode from index i and forwards.
+    var bytes = encoding.encode(text);
+    for (; i < bytes.length; i++) {
+      int byte = bytes[i];
+      if (byte < 128 &&
+          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+        result.writeCharCode(byte);
+      } else if (spaceToPlus && byte == _SPACE) {
+        result.writeCharCode(_PLUS);
+      } else {
+        const String hexDigits = '0123456789ABCDEF';
+        result..writeCharCode(_PERCENT)
+              ..writeCharCode(hexDigits.codeUnitAt(byte >> 4))
+              ..writeCharCode(hexDigits.codeUnitAt(byte & 0x0f));
+      }
+    }
+    return result.toString();
+  }
 }
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 9a2cb2a..83a25e1 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -3,9 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/bootstrap_natives.h"
-
 #include "vm/dart_api_impl.h"
+#include "vm/datastream.h"
 #include "vm/exceptions.h"
+#include "vm/growable_array.h"
 #include "vm/message.h"
 #include "vm/native_entry.h"
 #include "vm/object.h"
@@ -63,8 +64,8 @@
     args.SetAt(0, port_int);
     args.SetAt(1, send_port);
     args.SetAt(2, name);
-    Object& r = Object::Handle(service_isolate_->current_zone());
-    r = DartEntry::InvokeFunction(register_function_, args);
+    const Object& r = Object::Handle(
+        DartEntry::InvokeFunction(register_function_, args));
     if (FLAG_trace_service) {
       OS::Print("vm-service: Isolate %s %" Pd64 " registered.\n",
                 name.ToCString(),
@@ -146,4 +147,250 @@
   return Object::null();
 }
 
+
+DEFINE_NATIVE_ENTRY(VMService_RequestAssets, 0) {
+  return Service::RequestAssets();
+}
+
+
+// TODO(25041): When reading, this class copies out the filenames and contents
+// into new buffers. It does this because the lifetime of |bytes| is uncertain.
+// If |bytes| is pinned in memory, then we could instead load up
+// |filenames_| and |contents_| with pointers into |bytes| without making
+// copies.
+class TarArchive {
+ public:
+  TarArchive(uint8_t* bytes, intptr_t bytes_length)
+      : rs_(bytes, bytes_length) {}
+
+  void Read() {
+    while (HasNext()) {
+      char* filename;
+      uint8_t* data;
+      intptr_t data_length;
+      if (Next(&filename, &data, &data_length)) {
+        filenames_.Add(filename);
+        contents_.Add(data);
+        content_lengths_.Add(data_length);
+      }
+    }
+  }
+
+  char* NextFilename() {
+    return filenames_.RemoveLast();
+  }
+
+  uint8_t* NextContent() {
+    return contents_.RemoveLast();
+  }
+
+  intptr_t NextContentLength() {
+    return content_lengths_.RemoveLast();
+  }
+
+  bool HasMore() const {
+    return filenames_.length() > 0;
+  }
+
+  intptr_t Length() const { return filenames_.length(); }
+
+ private:
+  enum TarHeaderFields {
+    kTarHeaderFilenameOffset = 0,
+    kTarHeaderFilenameSize = 100,
+    kTarHeaderSizeOffset = 124,
+    kTarHeaderSizeSize = 12,
+    kTarHeaderTypeOffset = 156,
+    kTarHeaderTypeSize = 1,
+    kTarHeaderSize = 512,
+  };
+
+  enum TarType {
+    kTarAregType = '\0',
+    kTarRegType = '0',
+    kTarLnkType = '1',
+    kTarSymType = '2',
+    kTarChrType = '3',
+    kTarBlkType = '4',
+    kTarDirType = '5',
+    kTarFifoType = '6',
+    kTarContType = '7',
+    kTarXhdType = 'x',
+    kTarXglType = 'g',
+  };
+
+  bool HasNext() const {
+    return !EndOfArchive();
+  }
+
+  bool Next(char** filename, uint8_t** data, intptr_t* data_length) {
+    intptr_t startOfBlock = rs_.Position();
+    *filename = ReadFilename();
+    rs_.SetPosition(startOfBlock + kTarHeaderSizeOffset);
+    intptr_t size = ReadSize();
+    rs_.SetPosition(startOfBlock + kTarHeaderTypeOffset);
+    TarType type = ReadType();
+    SeekToNextBlock(kTarHeaderSize);
+    if ((type != kTarRegType) && (type != kTarAregType)) {
+      SkipContents(size);
+      return false;
+    }
+    ReadContents(data, size);
+    *data_length = size;
+    return true;
+  }
+
+  void SeekToNextBlock(intptr_t blockSize) {
+    intptr_t remainder = blockSize - (rs_.Position() % blockSize);
+    rs_.Advance(remainder);
+  }
+
+  uint8_t PeekByte(intptr_t i) const {
+    return *(rs_.AddressOfCurrentPosition() + i);
+  }
+
+  bool EndOfArchive() const {
+    if (rs_.PendingBytes() < (kTarHeaderSize * 2)) {
+      return true;
+    }
+    for (intptr_t i = 0; i < (kTarHeaderSize * 2); i++) {
+      if (PeekByte(i) != 0) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  TarType ReadType() {
+    return static_cast<TarType>(ReadStream::Raw<1, uint8_t>::Read(&rs_));
+  }
+
+  void SkipContents(intptr_t size) {
+    rs_.Advance(size);
+    SeekToNextBlock(kTarHeaderSize);
+  }
+
+  intptr_t ReadCString(char** s, intptr_t length) {
+    intptr_t to_read = Utils::Minimum(length, rs_.PendingBytes());
+    char* result = new char[to_read + 1];
+    strncpy(result,
+            reinterpret_cast<const char*>(rs_.AddressOfCurrentPosition()),
+            to_read);
+    result[to_read] = '\0';
+    rs_.SetPosition(rs_.Position() + to_read);
+    *s = result;
+    return to_read;
+  }
+
+  intptr_t ReadSize() {
+    char* octalSize;
+    unsigned int size;
+
+    ReadCString(&octalSize, kTarHeaderSizeSize);
+    int result = sscanf(octalSize, "%o", &size);
+    delete[] octalSize;
+
+    if (result != 1) {
+      return 0;
+    }
+    return size;
+  }
+
+  char* ReadFilename() {
+    char* result;
+    intptr_t result_length = ReadCString(&result, kTarHeaderFilenameSize);
+    if (result[0] == '/') {
+      return result;
+    }
+    char* fixed_result = new char[result_length + 2];  // '/' + '\0'.
+    fixed_result[0] = '/';
+    strncpy(&fixed_result[1], result, result_length);
+    fixed_result[result_length + 1] = '\0';
+    delete[] result;
+    return fixed_result;
+  }
+
+  void ReadContents(uint8_t** data, intptr_t size) {
+    uint8_t* result = new uint8_t[size];
+    rs_.ReadBytes(result, size);
+    SeekToNextBlock(kTarHeaderSize);
+    *data = result;
+  }
+
+  ReadStream rs_;
+  GrowableArray<char*> filenames_;
+  GrowableArray<uint8_t*> contents_;
+  GrowableArray<intptr_t> content_lengths_;
+
+  DISALLOW_COPY_AND_ASSIGN(TarArchive);
+};
+
+
+static void ContentsFinalizer(void* isolate_callback_data,
+                              Dart_WeakPersistentHandle handle,
+                              void* peer) {
+  uint8_t* data = reinterpret_cast<uint8_t*>(peer);
+  delete[] data;
+}
+
+
+static void FilenameFinalizer(void* peer) {
+  char* filename = reinterpret_cast<char*>(peer);
+  delete[] filename;
+}
+
+
+DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(TypedData, data, arguments->NativeArgAt(0));
+  Api::Scope scope(thread);
+
+  Dart_Handle data_handle = Api::NewHandle(thread, data.raw());
+
+  Dart_TypedData_Type typ;
+  void* bytes;
+  intptr_t length;
+  Dart_Handle err = Dart_TypedDataAcquireData(
+      data_handle, &typ, &bytes, &length);
+  ASSERT(!Dart_IsError(err));
+
+  TarArchive archive(reinterpret_cast<uint8_t*>(bytes), length);
+  archive.Read();
+
+  err = Dart_TypedDataReleaseData(data_handle);
+  ASSERT(!Dart_IsError(err));
+
+  intptr_t archive_size = archive.Length();
+
+  const Array& result_list = Array::Handle(thread->zone(),
+    Array::New(2 * archive_size));
+
+  intptr_t idx = 0;
+  while (archive.HasMore()) {
+    char* filename = archive.NextFilename();
+    uint8_t* contents = archive.NextContent();
+    intptr_t contents_length = archive.NextContentLength();
+
+    Dart_Handle dart_filename = Dart_NewExternalLatin1String(
+        reinterpret_cast<uint8_t*>(filename),
+        strlen(filename),
+        filename,
+        FilenameFinalizer);
+    ASSERT(!Dart_IsError(dart_filename));
+
+    Dart_Handle dart_contents = Dart_NewExternalTypedData(
+        Dart_TypedData_kUint8, contents, contents_length);
+    ASSERT(!Dart_IsError(dart_contents));
+    Dart_NewWeakPersistentHandle(
+        dart_contents, contents, contents_length, ContentsFinalizer);
+
+    result_list.SetAt(idx, Api::UnwrapStringHandle(
+        thread->zone(), dart_filename));
+    result_list.SetAt(idx + 1, Api::UnwrapExternalTypedDataHandle(
+        thread->zone(), dart_contents));
+    idx += 2;
+  }
+
+  return result_list.raw();
+}
+
 }  // namespace dart
diff --git a/runtime/lib/vmservice_patch.dart b/runtime/lib/vmservice_patch.dart
index e9b4da7..3db7bca 100644
--- a/runtime/lib/vmservice_patch.dart
+++ b/runtime/lib/vmservice_patch.dart
@@ -2,6 +2,25 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+patch class Asset {
+  /// Call to request assets from the embedder.
+  /* patch */ static HashMap<String, Asset> request() {
+    HashMap<String, Asset> assets = new HashMap<String, Asset>();
+    Uint8List tarBytes = _requestAssets();
+    if (tarBytes == null) {
+      return assets;
+    }
+    List assetList = _decodeAssets(tarBytes);
+    for (int i = 0; i < assetList.length; i += 2) {
+      var a = new Asset(assetList[i], assetList[i + 1]);
+      assets[a.name] = a;
+    }
+    return assets;
+  }
+}
+
+List _decodeAssets(Uint8List data) native "VMService_DecodeAssets";
+
 patch bool sendIsolateServiceMessage(SendPort sp, List m)
     native "VMService_SendIsolateServiceMessage";
 patch void sendRootServiceMessage(List m)
@@ -10,3 +29,4 @@
 patch void _onExit() native "VMService_OnExit";
 patch bool _vmListenStream(String streamId) native "VMService_ListenStream";
 patch void _vmCancelStream(String streamId) native "VMService_CancelStream";
+patch Uint8List _requestAssets() native "VMService_RequestAssets";
diff --git a/runtime/observatory/BUILD.gn b/runtime/observatory/BUILD.gn
new file mode 100644
index 0000000..a4a76ee
--- /dev/null
+++ b/runtime/observatory/BUILD.gn
@@ -0,0 +1,193 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Currently paths here are hard coded for convenience in building Mojo/Flutter.
+declare_args() {
+  # Specify the path to a host compatible version of the Dart SDK.
+  # This SDK is used to compile the Observatory frontend sources.
+  dart_host_sdk = rebase_path("//third_party/dart-sdk/dart-sdk")
+
+  # Specify the path to a host compatible version of pub.
+  # This is used to compile the Observatory frontend sources.
+  dart_host_pub_exe = rebase_path("$dart_host_sdk/bin/pub")
+}
+
+# Helper build rules for packaging the Dart observatory resources.
+observatory_sources_gypi =
+    exec_script("../../tools/gypi_to_gn.py",
+                [ rebase_path(
+                    "//dart/runtime/observatory/observatory_sources.gypi") ],
+                "scope",
+                [ "//dart/runtime/observatory/observatory_sources.gypi" ])
+
+copy("copy_observatory") {
+  sources = rebase_path(observatory_sources_gypi.sources,
+                        "",
+                        ".")
+  outputs = [
+    "$root_gen_dir/observatory_copy/{{source_root_relative_dir}}/{{source_file_part}}",
+  ]
+}
+
+action("write_observatory_pubspec_yaml") {
+  deps = [
+    ":copy_observatory",
+  ]
+
+  script = "../../tools/observatory_tool.py"
+
+  inputs = [
+    rebase_path("pubspec.yaml"),
+  ]
+
+  args = [
+    "--silent=True",
+    "--pub-executable",
+    dart_host_pub_exe,
+    "--directory",
+    rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/"),
+    "--command",
+    "rewrite",
+    rebase_path("//dart/runtime/observatory/pubspec.yaml"),
+    rebase_path(
+        "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.yaml"),
+    "../../third_party/",
+    rebase_path("../../../dart/third_party/"),
+  ]
+
+  outputs = [
+    "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.yaml",
+  ]
+}
+
+action("copy_observatory_deps") {
+  deps = [
+    ":write_observatory_pubspec_yaml",
+  ]
+
+  script = "//dart/tools/observatory_tool.py"
+
+  inputs = [
+    script,
+    "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.yaml",
+  ]
+
+  args = [
+    "--silent=True",
+    "--pub-executable",
+    dart_host_pub_exe,
+    "--directory",
+    rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/"),
+    "--command",
+    "get",
+  ]
+
+  outputs = [
+    "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.lock",
+  ]
+}
+
+action("pub_build_observatory") {
+  sources =
+      rebase_path(observatory_sources_gypi.sources,
+                  "",
+                  "$root_gen_dir/observatory_copy/dart/runtime/observatory")
+
+  deps = [
+    ":copy_observatory",
+    ":copy_observatory_deps",
+  ]
+
+  script = "//dart/tools/observatory_tool.py"
+
+  inputs = [
+    script,
+  ]
+  inputs += sources
+
+  args = [
+    "--silent=True",
+    "--pub-executable",
+    dart_host_pub_exe,
+    "--directory",
+    rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/"),
+    "--command",
+    "build",
+    rebase_path("$root_out_dir/observatory/build"),
+  ]
+
+  outputs = [
+    "$root_out_dir/observatory/build/web/index.html",
+    "$root_out_dir/observatory/build/web/index.html.polymer.bootstrap.dart.js",
+  ]
+}
+
+action("deploy_observatory") {
+  deps = [
+    ":pub_build_observatory",
+  ]
+
+  script = "//dart/tools/observatory_tool.py"
+
+  inputs = [
+    script,
+    "$root_out_dir/observatory/build/web/index.html",
+    "$root_out_dir/observatory/build/web/index.html.polymer.bootstrap.dart.js",
+  ]
+
+  args = [
+    "--silent=True",
+    "--pub-executable",
+    dart_host_pub_exe,
+    "--directory",
+    rebase_path("$root_out_dir/observatory"),
+    "--command",
+    "deploy",
+  ]
+
+  outputs = [
+    "$root_out_dir/observatory/deployed/web/index.html",
+    "$root_out_dir/observatory/deployed/web/index.html.polymer.bootstrap.dart.js",
+  ]
+}
+
+action("archive_observatory") {
+  deps = [
+    ":deploy_observatory",
+  ]
+
+  script = "//dart/runtime/tools/create_archive.py"
+
+  inputs = [
+    script,
+    "$root_out_dir/observatory/deployed/web/index.html",
+    "$root_out_dir/observatory/deployed/web/index.html.polymer.bootstrap.dart.js",
+  ]
+
+  args = [
+    "--output",
+    rebase_path("$root_gen_dir/observatory/observatory_archive.cc"),
+    "--tar_output",
+    rebase_path("$root_gen_dir/observatory/observatory_archive.tar"),
+    "--outer_namespace", "dart",
+    "--inner_namespace", "observatory",
+    "--name", "observatory_assets_archive",
+    "--client_root", rebase_path("$root_out_dir/observatory/deployed/web/"),
+  ]
+
+  outputs = [
+    "$root_gen_dir/observatory/observatory_archive.cc",
+    "$root_gen_dir/observatory/observatory_archive.tar",
+  ]
+}
+
+source_set("embedded_observatory_archive") {
+  deps = [
+    ":archive_observatory",
+  ]
+
+  sources = [
+    rebase_path("$root_gen_dir/observatory/observatory_archive.cc"),
+  ]
+}
diff --git a/runtime/observatory/README_android b/runtime/observatory/README_android
deleted file mode 100644
index 0372732..0000000
--- a/runtime/observatory/README_android
+++ /dev/null
@@ -1,20 +0,0 @@
-Running Observatory against content_shell:
-
-0) Open your mobile web application in Dart Editor and launch it on mobile.
-
-1) Forward localhost:9222 to the content_shell's remote debugging protocol:
-
-$ adb forward tcp:9222 localabstract:content_shell_devtools_remote
-
-2) Start the Observatory servers:
-
-$ ./run.sh
-
-By default Observatory will be available on localhost:9090
-
-3) Release the content_shell's remote debugging protocol by clicking the 'Stop'
-button in the Dart Editor's debugger. By releasing the debugging protocol,
-Observatory can communicate with the content_shell.
-
-4) On Observatory's connect to VM page you should see the name of your app 
-on the right hand side of the page.
diff --git a/runtime/observatory/bin/server.dart b/runtime/observatory/bin/server.dart
deleted file mode 100644
index 4df5a85..0000000
--- a/runtime/observatory/bin/server.dart
+++ /dev/null
@@ -1,159 +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 observatory_server;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:logging/logging.dart';
-
-final Logger logger = new Logger('ObsServe');
-
-class ObservatoryServer {
-  static const _CHROME_PREFIX = '/crdptargets/';
-
-  // Is logging enabled?
-  bool log;
-
-  // Host to listen on.
-  String host;
-  // Port to listen on.
-  int port;
-
-  // Host that pub is listening on.
-  String pubHost;
-  // Port that pub is listening on.
-  int pubPort;
-
-  HttpServer _server;
-  final HttpClient _client = new HttpClient();
-
-  ObservatoryServer(List<String> args) {
-    var parser = new ArgParser();
-    parser.addFlag('log', help: 'Log activity.', defaultsTo: true);
-    parser.addOption('port', help: 'Specify port listen on',
-                     defaultsTo: '9090');
-    parser.addOption('host',
-                     help: 'Specify host to listen on',
-                     defaultsTo: '127.0.0.1');
-    parser.addOption('pub-port', help: 'Specify port that pub is listening on',
-                     defaultsTo: '9191');
-    parser.addOption('pub-host', help: 'Specify host that pub is listening on',
-                     defaultsTo: '127.0.0.1');
-    var results = parser.parse(args);
-    host = results['host'];
-    port = int.parse(results['port']);
-    log = results['log'];
-    pubHost = results['pub-host'];
-    pubPort = int.parse(results['pub-port']);
-  }
-
-  List<Map> _makeTargetList(List<Map> tabs) {
-    var r = <Map>[];
-    tabs.forEach((tab) {
-      var uri = Uri.parse(tab['url']);
-      if (uri.host == 'devtools') {
-        // Ignore.
-        return;
-      }
-      var target = {
-        'lastConnectionTime': 0,
-        'chrome': true,
-        'name': tab['title'],
-        'networkAddress': tab['webSocketDebuggerUrl'],
-      };
-      r.add(target);
-    });
-    return r;
-  }
-
-  void _getChromeTabs(HttpRequest request) {
-    var path = request.uri.path;
-    var method = request.method;
-    if (method != 'GET') {
-      return;
-    }
-    assert(path.startsWith(_CHROME_PREFIX));
-    var networkAddress = path.substring(_CHROME_PREFIX.length);
-    if ((networkAddress == '') || (networkAddress == null)) {
-      request.response.write('[]');
-      request.response.close();
-      return;
-    }
-    networkAddress = Uri.decodeComponent(networkAddress);
-    var chunks = networkAddress.split(':');
-    var chromeAddress = chunks[0];
-    var chromePort =
-        (chunks[1] == null) || (chunks[1] == '') ? 9222 : int.parse(chunks[1]);
-    logger.info('tabs from $chromeAddress:$chromePort');
-    _client.open(method, chromeAddress, chromePort, 'json')
-        .then((HttpClientRequest pubRequest) {
-          // Calling .close() on an HttpClientRequest sends the request to the
-          // server. The future completes to an HttpClientResponse when the
-          // server has responded.
-          return pubRequest.close();
-        }).then((HttpClientResponse response) {
-          var respond = (contents) {
-            var tabs = JSON.decode(contents);
-            var targets = _makeTargetList(tabs);
-            request.response.write(JSON.encode(targets));
-            request.response.close().catchError((e) {
-              logger.severe('tabs from $chromeAddress:$chromePort failed');
-              logger.severe(e.toString());
-            });
-          };
-          response.transform(UTF8.decoder).listen(respond);
-        }).catchError((e) {
-          logger.severe('tabs from $chromeAddress:$chromePort failed');
-          logger.severe(e.toString());
-        });
-  }
-
-  /// Forward [request] to pub.
-  void _forwardToPub(HttpRequest request) {
-    var path = request.uri.path;
-    var method = request.method;
-    logger.info('pub $method $path');
-    _client.open(method, pubHost, pubPort, path)
-        .then((HttpClientRequest pubRequest) {
-          return pubRequest.close();
-        }).then((HttpClientResponse response) {
-          return request.response.addStream(response);
-        }).then((_) => request.response.close())
-        .catchError((e) {
-          logger.severe('pub $method $path failed.');
-          logger.severe(e.toString());
-        });
-  }
-
-  void _onHttpRequest(HttpRequest request) {
-    // Allow cross origin requests.
-    request.response.headers.add('Access-Control-Allow-Origin', '*');
-    if (request.uri.path.startsWith(_CHROME_PREFIX)) {
-      _getChromeTabs(request);
-    } else {
-      _forwardToPub(request);
-    }
-  }
-
-  /// Future completes to [this] on successful startup.
-  Future start() {
-    return HttpServer.bind(host,  port).then((s) {
-      _server = s;
-      _server.listen(_onHttpRequest);
-      print('ObsServe is running on ${_server.address}:${_server.port}');
-    });
-  }
-}
-
-main(List<String> args) {
-  hierarchicalLoggingEnabled = true;
-  logger.level = Level.ALL;
-  logger.onRecord.listen(print);
-  new ObservatoryServer(args)..start();
-}
-
diff --git a/runtime/observatory/lib/base64.dart b/runtime/observatory/lib/base64.dart
deleted file mode 100644
index 4bb0f70..0000000
--- a/runtime/observatory/lib/base64.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library base64;
-
-import 'dart:typed_data';
-
-const _decodeTable =
-    const [null, null, null, null, null, null, null, null,
-           null, null, null, null, null, null, null, null,
-           null, null, null, null, null, null, null, null,
-           null, null, null, null, null, null, null, null,
-           null, null, null, null, null, null, null, null,
-           null, null, null, 62, null, null, null, 63,
-           52, 53, 54, 55, 56, 57, 58, 59,
-           60, 61, null, null, null, 0, null, null,
-           null, 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, null, null, null, null, null,
-           null, 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];
-
-Uint8List decodeBase64(String s) {
-  if (s.length % 4 != 0) throw "Malformed Base64: $s";
-
-  var odd_bits = 0;
-  if (s[s.length - 1] == '=') {
-    if (s[s.length - 2] == '=') {
-      odd_bits = 2;
-    } else {
-      odd_bits = 1;
-    }
-  }
-
-  var decodedByteLength = s.length ~/ 4 * 3 - odd_bits;
-  var result = new Uint8List(decodedByteLength);
-  var limit = s.length;
-  if (odd_bits != 0) {
-    limit = limit - 4;
-  }
-
-  var i = 0, j = 0;
-  while (i < limit) {
-    var triple = _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    result[j++] = triple >> 16;
-    result[j++] = (triple >> 8) & 255;
-    result[j++] = triple & 255;
-  }
-
-  if (odd_bits != 0) {
-    var triple = _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    triple = (triple << 6) | _decodeTable[s.codeUnitAt(i++)];
-    result[j++] = triple >> 16;
-    if (odd_bits == 1) {
-      result[j++] = (triple >> 8) & 255;
-    }
-  }
-  assert(j == decodedByteLength);
-  return result;
-}
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index 51309f5..e485407 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -52,6 +52,7 @@
 export 'package:observatory/src/elements/service_ref.dart';
 export 'package:observatory/src/elements/service_view.dart';
 export 'package:observatory/src/elements/sliding_checkbox.dart';
+export 'package:observatory/src/elements/timeline_page.dart';
 export 'package:observatory/src/elements/view_footer.dart';
 export 'package:observatory/src/elements/vm_connect.dart';
 export 'package:observatory/src/elements/vm_ref.dart';
diff --git a/runtime/observatory/lib/elements.html b/runtime/observatory/lib/elements.html
index 87376f0..1f89cbd 100644
--- a/runtime/observatory/lib/elements.html
+++ b/runtime/observatory/lib/elements.html
@@ -44,6 +44,7 @@
 <link rel="import" href="src/elements/script_view.html">
 <link rel="import" href="src/elements/service_ref.html">
 <link rel="import" href="src/elements/sliding_checkbox.html">
+<link rel="import" href="src/elements/timeline_page.html">
 <link rel="import" href="src/elements/view_footer.html">
 <link rel="import" href="src/elements/vm_connect.html">
 <link rel="import" href="src/elements/vm_ref.html">
diff --git a/runtime/observatory/lib/object_graph.dart b/runtime/observatory/lib/object_graph.dart
index 2a5e2b7..e70570e 100644
--- a/runtime/observatory/lib/object_graph.dart
+++ b/runtime/observatory/lib/object_graph.dart
@@ -377,8 +377,8 @@
     _addrToId = null;
     _chunks = null;
 
-    statusReporter.add("Finding post order...");
-    await new Future(() => _buildPostOrder());
+    statusReporter.add("Finding depth-first order...");
+    await new Future(() => _dfs());
 
     statusReporter.add("Finding predecessors...");
     await new Future(() => _buildPredecessors());
@@ -388,12 +388,14 @@
 
     _firstPreds = null;
     _preds = null;
-    _postOrderIndices = null;
+
+    _semi = null;
+    _parent = null;
 
     statusReporter.add("Finding retained sizes...");
     await new Future(() => _calculateRetainedSizes());
 
-    _postOrderOrdinals = null;
+    _vertex = null;
 
     statusReporter.add("Loaded");
     return this;
@@ -417,8 +419,9 @@
 
   // Intermediates.
   AddressMapper _addrToId;
-  Uint32List _postOrderOrdinals; // post-order index -> id
-  Uint32List _postOrderIndices; // id -> post-order index
+  Uint32List _vertex;
+  Uint32List _parent;
+  Uint32List _semi;
   Uint32List _firstPreds; // Offset into preds.
   Uint32List _preds;
 
@@ -514,56 +517,70 @@
     _succs = succs;
   }
 
-  void _buildPostOrder() {
+  void _dfs() {
     var N = _N;
     var E = _E;
     var firstSuccs = _firstSuccs;
     var succs = _succs;
 
-    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 vertex = new Uint32List(N + 1);
+    var semi = new Uint32List(N + 1);
+    var parent = new Uint32List(N + 1);
+    var dfsNumber = 0;
+
+    var dfsCount = 0;
     var stackTop = 0;
     var root = 1;
 
+    // Push root.
     stackNodes[0] = root;
     stackCurrentEdgePos[0] = firstSuccs[root];
-    visited[root] = 1;
 
     while (stackTop >= 0) {
-      var n = stackNodes[stackTop];
+      var v = stackNodes[stackTop];
       var edgePos = stackCurrentEdgePos[stackTop];
 
-      if (edgePos < firstSuccs[n + 1]) {
+      if (semi[v] == 0) {
+        // First visit.
+        dfsNumber++;
+        semi[v] = dfsNumber;
+        vertex[dfsNumber] = v;
+      }
+
+      if (edgePos < firstSuccs[v + 1]) {
         var childId = succs[edgePos];
         edgePos++;
         stackCurrentEdgePos[stackTop] = edgePos;
-        if (visited[childId] == 1) continue;
 
-        // Push child.
-        stackTop++;
-        stackNodes[stackTop] = childId;
-        edgePos = firstSuccs[childId];
-        stackCurrentEdgePos[stackTop] = edgePos;
-        visited[childId] = 1;
+        if (semi[childId] == 0) {
+          parent[childId] = v;
+
+          // Push child.
+          stackTop++;
+          stackNodes[stackTop] = childId;
+          stackCurrentEdgePos[stackTop] = firstSuccs[childId];
+        }
       } else {
         // Done with all children.
-        postOrderIndices[n] = postOrderIndex;
-        postOrderOrdinals[postOrderIndex++] = n;
         stackTop--;
       }
     }
 
-    assert(postOrderIndex == N);
-    assert(postOrderOrdinals[N - 1] == root);
+    assert(dfsNumber == N);
+    for (var i = 1; i <= N; i++) {
+      assert(semi[i] != 0);
+    }
+    assert(parent[1] == 0);
+    for (var i = 2; i <= N; i++) {
+      assert(parent[i] != 0);
+    }
 
-    _postOrderOrdinals = postOrderOrdinals;
-    _postOrderIndices = postOrderIndices;
-    _E = E;
+    _vertex = vertex;
+    _semi = semi;
+    _parent = parent;
   }
 
   void _buildPredecessors() {
@@ -616,86 +633,166 @@
     _preds = preds;
   }
 
-  // "A Simple, Fast Dominance Algorithm"
-  // Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
+  static int _eval(int v,
+                   Uint32List ancestor,
+                   Uint32List semi,
+                   Uint32List label,
+                   Uint32List stackNode,
+                   Uint8List stackState) {
+    if (ancestor[v] == 0) {
+      return label[v];
+    } else {
+      {
+        // Inlined 'compress' with an explicit stack to prevent JS stack
+        // overflow.
+        var top = 0;
+        stackNode[top] = v;
+        stackState[top] = 0;
+        while (top >= 0) {
+          var v = stackNode[top];
+          var state = stackState[top];
+          if (state == 0) {
+            assert(ancestor[v] != 0);
+            if (ancestor[ancestor[v]] != 0) {
+              stackState[top] = 1;
+              // Recurse with ancestor[v]
+              top++;
+              stackNode[top] = ancestor[v];
+              stackState[top] = 0;
+            } else {
+              top--;
+            }
+          } else {
+            assert(state == 1);
+            if (semi[label[ancestor[v]]] < semi[label[v]]) {
+              label[v] = label[ancestor[v]];
+            }
+            ancestor[v] = ancestor[ancestor[v]];
+            top--;
+          }
+        }
+      }
+
+      if (semi[label[ancestor[v]]] >= semi[label[v]]) {
+        return label[v];
+      } else {
+        return label[ancestor[v]];
+      }
+    }
+  }
+
+  // Note the version in the main text of Lengauer & Tarjan incorrectly
+  // uses parent instead of ancestor. The correct version is in Appendix B.
+  static void _link(int v,
+                    int w,
+                    Uint32List size,
+                    Uint32List label,
+                    Uint32List semi,
+                    Uint32List child,
+                    Uint32List ancestor) {
+    assert(size[0] == 0);
+    assert(label[0] == 0);
+    assert(semi[0] == 0);
+    var s = w;
+    while (semi[label[w]] < semi[label[child[s]]]) {
+      if (size[s] + size[child[child[s]]] >= 2 * size[child[s]]) {
+        ancestor[child[s]] = s;
+        child[s] = child[child[s]];
+      } else {
+        size[child[s]] = size[s];
+        s = ancestor[s] = child[s];
+      }
+    }
+    label[s] = label[w];
+    size[v] = size[v] + size[w];
+    if (size[v] < 2 * size[w]) {
+      var tmp = s;
+      s = child[v];
+      child[v] = tmp;
+    }
+    while (s != 0) {
+      ancestor[s] = v;
+      s = child[s];
+    }
+  }
+
+  // T. Lengauer and R. E. Tarjan. "A Fast Algorithm for Finding Dominators
+  // in a Flowgraph."
   void _buildDominators() {
     var N = _N;
 
-    var postOrder = _postOrderOrdinals;
-    var postOrderIndex = _postOrderIndices;
+    var vertex = _vertex;
+    var semi = _semi;
+    var parent = _parent;
     var firstPreds = _firstPreds;
     var preds = _preds;
 
     var root = 1;
-    var rootPostOrderIndex = postOrderIndex[root];
-    var domByPOI = new Uint32List(N + 1);
+    var dom = new Uint32List(N + 1);
 
-    domByPOI[rootPostOrderIndex] = rootPostOrderIndex;
+    var ancestor = new Uint32List(N + 1);
+    var label = new Uint32List(N + 1);
+    for (var i = 1; i <= N; i++) {
+      label[i] = i;
+    }
+    var buckets = new List(N + 1);
+    var child = new Uint32List(N + 1);
+    var size = new Uint32List(N + 1);
+    for (var i = 1; i <= N; i++) {
+      size[i] = 1;
+    }
+    var stackNode = new Uint32List(N + 1);
+    var stackState = new Uint8List(N + 1);
 
-    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.
+    for (var i = N; i > 1; i--) {
+      var w = vertex[i];
+      assert(w != root);
 
-      // 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;
-            }
-          }
+      // Lengauer & Tarjan Step 2.
+      var startPred = firstPreds[w];
+      var limitPred = firstPreds[w + 1];
+      for (var predIndex = startPred;
+           predIndex < limitPred;
+           predIndex++) {
+        var v = preds[predIndex];
+        var u = _eval(v, ancestor, semi, label, stackNode, stackState);
+        if (semi[u] < semi[w]) {
+          semi[w] = semi[u];
         }
-        if (newDomIndex != 0 && domByPOI[curPostOrderIndex] != newDomIndex) {
-          domByPOI[curPostOrderIndex] = newDomIndex;
-          changed = true;
+      }
+
+      // w.semi.bucket.add(w);
+      var tmp = vertex[semi[w]];
+      if (buckets[tmp] == null) {
+        buckets[tmp] = new List();
+      }
+      buckets[tmp].add(w);
+
+      _link(parent[w], w, size, label, semi, child, ancestor);
+
+      // Lengauer & Tarjan Step 3.
+      tmp = parent[w];
+      var bucket = buckets[tmp];
+      buckets[tmp] = null;
+      if (bucket != null) {
+        for (var v in bucket) {
+          var u = _eval(v, ancestor, semi, label, stackNode, stackState);
+          dom[v] = semi[u] < semi[v] ? u : parent[w];
         }
       }
     }
-
-    Logger.root.info("Start remap dominators");
-
-    // 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]]];
+    for (var i = 1; i <= N; i++) {
+      assert(buckets[i] == null);
+    }
+    // Lengauer & Tarjan Step 4.
+    for (var i = 2; i <= N; i++) {
+      var w = vertex[i];
+      if (dom[w] != vertex[semi[w]]) {
+        dom[w] = dom[dom[w]];
+      }
     }
 
-    Logger.root.info("End remap dominators");
-
-    domById[root] = 0;
-
-    _doms = domById;
+    _doms = dom;
   }
 
   void _calculateRetainedSizes() {
@@ -703,7 +800,7 @@
 
     var size = 0;
     var shallowSizes = _shallowSizes;
-    var postOrderOrdinals = _postOrderOrdinals;
+    var vertex = _vertex;
     var doms = _doms;
 
     // Sum shallow sizes.
@@ -716,9 +813,9 @@
 
     // 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);
+    for (var i = N; i > 1; i--) {
+      var v = vertex[i];
+      assert(v != 1);
       retainedSizes[doms[i]] += retainedSizes[i];
     }
 
diff --git a/runtime/observatory/lib/service.dart b/runtime/observatory/lib/service.dart
index d72af88..cb6f317 100644
--- a/runtime/observatory/lib/service.dart
+++ b/runtime/observatory/lib/service.dart
@@ -13,7 +13,6 @@
 import 'package:observatory/cpu_profile.dart';
 import 'package:observatory/object_graph.dart';
 import 'package:observatory/tracer.dart';
-import 'package:observatory/base64.dart';
 import 'package:observe/observe.dart';
 
 part 'src/service/object.dart';
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
index c4050e5..bda98c0 100644
--- a/runtime/observatory/lib/src/app/application.dart
+++ b/runtime/observatory/lib/src/app/application.dart
@@ -141,6 +141,7 @@
     _pageRegistry.add(new MetricsPage(this));
     _pageRegistry.add(new PortsPage(this));
     _pageRegistry.add(new LoggingPage(this));
+    _pageRegistry.add(new TimelinePage(this));
     // Note that ErrorPage must be the last entry in the list as it is
     // the catch all.
     _pageRegistry.add(new ErrorPage(this));
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index bc2bb43..21305e1 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -425,3 +425,21 @@
 
   bool canVisit(Uri uri) => uri.path == 'metrics';
 }
+
+class TimelinePage extends Page {
+  TimelinePage(app) : super(app);
+
+  void onInstall() {
+    if (element == null) {
+      element = new Element.tag('timeline-page');
+    }
+    assert(element != null);
+  }
+
+  void _visit(Uri uri) {
+    assert(element != null);
+    assert(canVisit(uri));
+  }
+
+  bool canVisit(Uri uri) => uri.path == 'timeline';
+}
diff --git a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
index c71a41e..d3e0252 100644
--- a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
+++ b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
@@ -370,15 +370,22 @@
 
     code.profile = this;
 
-    if (code.isDartCode) {
+    if (code.kind == CodeKind.Stub) {
+      attributes.add('stub');
+    } else if (code.kind == CodeKind.Dart) {
+      if (code.isNative) {
+        attributes.add('ffi');  // Not to be confused with a C function.
+      } else {
+        attributes.add('dart');
+      }
+      if (code.hasIntrinsic) {
+        attributes.add('intrinsic');
+      }
       if (code.isOptimized) {
         attributes.add('optimized');
       } else {
         attributes.add('unoptimized');
       }
-    }
-    if (code.isDartCode) {
-      attributes.add('dart');
     } else if (code.kind == CodeKind.Tag) {
       attributes.add('tag');
     } else if (code.kind == CodeKind.Native) {
@@ -516,15 +523,19 @@
     if (function.kind == FunctionKind.kTag) {
       attribs.add('tag');
     } else if (function.kind == FunctionKind.kStub) {
-      attribs.add('dart');
       attribs.add('stub');
     } else if (function.kind == FunctionKind.kNative) {
       attribs.add('native');
     } else if (function.kind.isSynthetic()) {
       attribs.add('synthetic');
+    } else if (function.isNative) {
+      attribs.add('ffi');  // Not to be confused with a C function.
     } else {
       attribs.add('dart');
     }
+    if (function.hasIntrinsic == true) {
+      attribs.add('intrinsic');
+    }
   }
 
   ProfileFunction.fromMap(this.profile, this.function, Map data) {
diff --git a/runtime/observatory/lib/src/debugger/debugger_location.dart b/runtime/observatory/lib/src/debugger/debugger_location.dart
index 31facf2..caf5f57 100644
--- a/runtime/observatory/lib/src/debugger/debugger_location.dart
+++ b/runtime/observatory/lib/src/debugger/debugger_location.dart
@@ -97,7 +97,8 @@
         return new DebuggerLocation.file(scripts[0], line, col);
       } else {
         // TODO(turnidge): Allow the user to disambiguate.
-        return new DebuggerLocation.error("Script '${scriptName}' is ambigous");
+        return
+            new DebuggerLocation.error("Script '${scriptName}' is ambiguous");
       }
     } else {
       // No script provided.  Default to top of stack for now.
@@ -253,7 +254,7 @@
       } else {
         // TODO(turnidge): Allow the user to disambiguate.
         return new DebuggerLocation.error(
-            "Function '${match.group(0)}' is ambigous");
+            "Function '${match.group(0)}' is ambiguous");
       }
       return new DebuggerLocation.error('foo');
     });
diff --git a/runtime/observatory/lib/src/elements/class_ref.dart b/runtime/observatory/lib/src/elements/class_ref.dart
index 5eebe73..b8895c6 100644
--- a/runtime/observatory/lib/src/elements/class_ref.dart
+++ b/runtime/observatory/lib/src/elements/class_ref.dart
@@ -4,23 +4,33 @@
 
 library class_ref_element;
 
+import 'package:observatory/service.dart';
 import 'package:polymer/polymer.dart';
 import 'service_ref.dart';
+import 'dart:async';
 
 @CustomTag('class-ref')
 class ClassRefElement extends ServiceRefElement {
+  @observable bool asValue = false;
+
   ClassRefElement.created() : super.created();
 
-  refChanged(oldValue) {
-    super.refChanged(oldValue);
-    _updateShadowDom();
+  String makeExpandKey(String key) {
+    return '${expandKey}/${key}';
   }
 
-  void _updateShadowDom() {
-    clearShadowRoot();
-    if (ref == null) {
-      return;
+  dynamic expander() {
+    return expandEvent;
+  }
+
+  void expandEvent(bool expand, Function onDone) {
+    if (expand) {
+      Class cls = ref;
+      cls.reload().then((result) {
+        return Future.wait(cls.fields.map((field) => field.reload()));
+      }).whenComplete(onDone);
+    } else {
+      onDone();
     }
-    insertLinkIntoShadowRoot(name, url, hoverText);
   }
 }
\ No newline at end of file
diff --git a/runtime/observatory/lib/src/elements/class_ref.html b/runtime/observatory/lib/src/elements/class_ref.html
index e3f908a..c3ddec7 100644
--- a/runtime/observatory/lib/src/elements/class_ref.html
+++ b/runtime/observatory/lib/src/elements/class_ref.html
@@ -1,8 +1,34 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="curly_block.html">
+<link rel="import" href="observatory_element.html">
 <link rel="import" href="service_ref.html">
 
 <polymer-element name="class-ref" extends="service-ref">
-  <template><link rel="stylesheet" href="css/shared.css"></template>
+  <template>
+    <link rel="stylesheet" href="css/shared.css">
+    <style>
+      .indented {
+        margin-left: 1.5em;
+        font: 400 14px 'Montserrat', sans-serif;
+        line-height: 150%;
+      }
+    </style><!--
+    --><a on-click="{{ goto }}" _href="{{ url }}">{{ ref.name }}</a><!--
+    --><template if="{{ asValue }}">
+      <curly-block callback="{{ expander() }}" expandKey="{{ expandKey }}">
+        <div class="indented">
+          <template repeat="{{ field in ref.fields }}">
+            <template if="{{ field.isStatic }}">
+              {{ field.name }}&nbsp;:&nbsp;
+              <any-service-ref ref="{{ field.staticValue }}"
+                               expandKey="{{ makeExpandKey(field.name) }}">
+              </any-service-ref><br>
+            </template>
+          </template>
+        </div>
+      </curly-block>
+    </template><!--
+  --></template>
 </polymer-element>
 
 <script type="application/dart" src="class_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/class_tree.html b/runtime/observatory/lib/src/elements/class_tree.html
index 7f40600..c1e9635 100644
--- a/runtime/observatory/lib/src/elements/class_tree.html
+++ b/runtime/observatory/lib/src/elements/class_tree.html
@@ -27,16 +27,14 @@
       }
     </style>
     <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
+      <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('/class-tree', isolate) }}" anchor="class hierarchy" last="{{ true }}"></nav-menu>
     </nav-bar>
     <div class="content-centered">
       <h1>Class Hierarchy</h1>
       <table id="tableTree" class="table">
-        <thead id="tableTreeHeader">
-          <tr>
-            <th>Class</th>
-          </tr>
-        </thead>
         <tbody id="tableTreeBody"></tbody>
       </table>
     </div>
diff --git a/runtime/observatory/lib/src/elements/class_view.dart b/runtime/observatory/lib/src/elements/class_view.dart
index 998f82d..8c67ebc 100644
--- a/runtime/observatory/lib/src/elements/class_view.dart
+++ b/runtime/observatory/lib/src/elements/class_view.dart
@@ -15,6 +15,7 @@
 class ClassViewElement extends ObservatoryElement {
   @published Class cls;
   @observable ServiceMap instances;
+  @observable int reachableBytes;
   @observable int retainedBytes;
   @observable ObservableList mostRetained;
   SampleBufferControlElement sampleBufferControlElement;
@@ -44,6 +45,12 @@
   }
 
   // TODO(koda): Add no-arg "calculate-link" instead of reusing "eval-link".
+  Future<ServiceObject> reachableSize(var dummy) {
+    return cls.isolate.getReachableSize(cls).then((Instance obj) {
+      reachableBytes = int.parse(obj.valueAsString);
+    });
+  }
+
   Future<ServiceObject> retainedSize(var dummy) {
     return cls.isolate.getRetainedSize(cls).then((Instance obj) {
       retainedBytes = int.parse(obj.valueAsString);
diff --git a/runtime/observatory/lib/src/elements/class_view.html b/runtime/observatory/lib/src/elements/class_view.html
index 5dadba6..6e59887 100644
--- a/runtime/observatory/lib/src/elements/class_view.html
+++ b/runtime/observatory/lib/src/elements/class_view.html
@@ -181,6 +181,19 @@
             </div>
           </div>
           <div class="memberItem">
+            <div class="memberName">total reachable memory size</div>
+            <div class="memberValue">
+              <template if="{{ reachableBytes == null }}">
+                <eval-link callback="{{ reachableSize }}"
+                           label="[calculate]">
+                </eval-link>
+              </template>
+              <template if="{{ reachableBytes != null }}">
+                {{ reachableBytes | formatSize }}
+              </template>
+            </div>
+          </div>
+          <div class="memberItem">
             <div class="memberName">total retained memory size</div>
             <div class="memberValue">
               <template if="{{ retainedBytes == null }}">
diff --git a/runtime/observatory/lib/src/elements/code_view.dart b/runtime/observatory/lib/src/elements/code_view.dart
index 7c6ddef..9234164 100644
--- a/runtime/observatory/lib/src/elements/code_view.dart
+++ b/runtime/observatory/lib/src/elements/code_view.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 import 'dart:html';
 import 'observatory_element.dart';
+import 'service_ref.dart';
 import 'package:observatory/app.dart';
 import 'package:observatory/service.dart';
 import 'package:observatory/cpu_profile.dart';
@@ -34,6 +35,7 @@
         new SortedTableColumn('Inclusive'),
         new SortedTableColumn('Exclusive'),
         new SortedTableColumn('Disassembly'),
+        new SortedTableColumn('Objects'),
     ];
     disassemblyTable = new DisassemblyTable(columns);
     columns = [
@@ -171,7 +173,8 @@
       var row = [formattedAddress(instruction),
                  formattedInclusive(instruction),
                  formattedExclusive(instruction),
-                 instruction.human];
+                 instruction.human,
+                 instruction.object];
       disassemblyTable.addRow(new SortedTableRow(row));
     }
   }
@@ -192,6 +195,8 @@
     cell.classes.add('monospace');
     cell = tr.insertCell(-1);
     cell.classes.add('monospace');
+    cell = tr.insertCell(-1);
+    cell.classes.add('monospace');
 
     tableBody.children.add(tr);
   }
@@ -201,8 +206,14 @@
     final n = row.values.length;
     for (var i = 0; i < n; i++) {
       final cell = tr.children[i];
-      cell.title = row.values[i].toString();
-      cell.text = row.values[i].toString();
+      final content = row.values[i];
+      if (content is ServiceObject) {
+        ServiceRefElement element = new Element.tag('any-service-ref');
+        element.ref = content;
+        cell.append(element);
+      } else if (content != null) {
+        cell.text = content.toString();
+      }
     }
   }
 
@@ -294,7 +305,6 @@
 
     for (var i = addressRangeColumn + 1; i < columns - 1; i++) {
       var cell = tr.children[i];
-      cell.title = row.values[i].toString();
       cell.text = row.values[i].toString();
     }
     var functions = row.values[functionsColumn];
diff --git a/runtime/observatory/lib/src/elements/code_view.html b/runtime/observatory/lib/src/elements/code_view.html
index 7b1c057..ba4cac0 100644
--- a/runtime/observatory/lib/src/elements/code_view.html
+++ b/runtime/observatory/lib/src/elements/code_view.html
@@ -20,19 +20,25 @@
       }
 
       th:nth-of-type(2), td:nth-of-type(2) {
-        min-width: 10em;
+        min-width: 8em;
         text-align: left;
       }
 
       th:nth-of-type(3), td:nth-of-type(3) {
-        padding-right: 3em;
+        min-width: 8em;
+        text-align: left;
       }
 
       th:nth-of-type(4), td:nth-of-type(4) {
-        padding-left: 3em;
+        text-align: left;
         overflow: visible;
         white-space: pre;
-        display: block;
+        padding-right: 1em;
+      }
+
+      th:nth-of-type(5), td:nth-of-type(5) {
+        text-align: left;
+        overflow: visible;
       }
 
       tr:hover > td {
@@ -86,7 +92,7 @@
           <div class="memberValue">{{ code.profile.formattedExclusiveTicks }}</div>
         </div>
         <div class="memberItem">
-          <div class="memberName">Constant object pool</div>
+          <div class="memberName">Object pool</div>
           <div class="memberValue">
             <any-service-ref ref="{{ code.objectPool }}"></any-service-ref>
           </div>
@@ -116,10 +122,10 @@
       <table id="inlineRangeTable" class="table">
         <thead id="inlineRangeTableHead">
           <tr>
-            <th class="address" title="Address range">Address Range</th>
-            <th class="tick" title="Inclusive">Inclusive</th>
-            <th class="tick" title="Exclusive">Exclusive</th>
-            <th title="Functions">Functions</th>
+            <th class="address">Address Range</th>
+            <th class="tick">Inclusive</th>
+            <th class="tick">Exclusive</th>
+            <th>Functions</th>
           </tr>
         </thead>
         <tbody class="monospace" id="inlineRangeTableBody">
@@ -129,10 +135,11 @@
       <table id="disassemblyTable" class="table">
         <thead id="disassemblyTableHead">
           <tr>
-            <th class="address" title="Address">Address</th>
-            <th class="tick" title="Inclusive">Inclusive</th>
-            <th class="tick" title="Exclusive">Exclusive</th>
-            <th class="disassembly" title="Disassembly">Disassembly</th>
+            <th class="address">Address</th>
+            <th class="tick" title="Ticks with PC on the stack">Inclusive</th>
+            <th class="tick" title="Ticks with PC at top of stack">Exclusive</th>
+            <th class="disassembly">Disassembly</th>
+            <th class="object">Object</th>
           </tr>
         </thead>
         <tbody class="monospace" id="disassemblyTableBody">
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.dart b/runtime/observatory/lib/src/elements/cpu_profile.dart
index 087daa5..c026d7c 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile.dart
@@ -76,6 +76,8 @@
     'optimized' : const ['O', null, 'Optimized'],
     'unoptimized' : const ['U', null, 'Unoptimized'],
     'inlined' : const ['I', null, 'Inlined'],
+    'intrinsic' : const ['It', null, 'Intrinsic'],
+    'ffi' : const ['F', null, 'FFI'],
     'dart' : const ['D', null, 'Dart'],
     'tag' : const ['T', null, 'Tag'],
     'native' : const ['N', null, 'Native'],
diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart
index 4310075..cf78a26 100644
--- a/runtime/observatory/lib/src/elements/debugger.dart
+++ b/runtime/observatory/lib/src/elements/debugger.dart
@@ -1724,7 +1724,7 @@
         // Unambiguous completion.
         return completions[0];
       } else {
-        // Ambigous completion.
+        // Ambiguous completion.
         completions = completions.map((s) => s.trimRight()).toList();
         console.printBold(completions.toString());
         return _foldCompletions(completions);
@@ -1914,6 +1914,7 @@
       // TODO(turnidge): How do we want to handle this in general?
       _stdoutSubscriptionFuture.catchError((e, st) {
         Logger.root.info('Failed to subscribe to stdout: $e\n$st\n');
+        _stdoutSubscriptionFuture = null;
       });
     }
     _stderrSubscriptionFuture =
@@ -1922,6 +1923,7 @@
       // TODO(turnidge): How do we want to handle this in general?
       _stderrSubscriptionFuture.catchError((e, st) {
         Logger.root.info('Failed to subscribe to stderr: $e\n$st\n');
+        _stderrSubscriptionFuture = null;
       });
     }
     _logSubscriptionFuture =
@@ -2229,6 +2231,23 @@
         busy = false;
       });
   }
+
+  @observable
+  get properLocals {
+    var locals = new List();
+    var homeMethod = frame.function.homeMethod;
+    if (homeMethod.dartOwner is Class && homeMethod.isStatic) {
+      locals.add(
+          {'name' : '<class>',
+           'value' : homeMethod.dartOwner});
+    } else if (homeMethod.dartOwner is Library) {
+      locals.add(
+          {'name' : '<library>',
+           'value' : homeMethod.dartOwner});
+    }
+    locals.addAll(frame.variables);
+    return locals;
+  }
 }
 
 @CustomTag('debugger-message')
diff --git a/runtime/observatory/lib/src/elements/debugger.html b/runtime/observatory/lib/src/elements/debugger.html
index 5b74667..981f260 100644
--- a/runtime/observatory/lib/src/elements/debugger.html
+++ b/runtime/observatory/lib/src/elements/debugger.html
@@ -267,16 +267,13 @@
               </source-inset>
             </div>
             <div class="flex-item-vars">
-              <div style="padding:10px;" class="memberList">
-                <template repeat="{{ v in frame.variables }}">
-                  <div class="memberItem">
-                    <div class="memberName">{{ v['name']}}</div>
-                    <div class="memberValue">
-                      <any-service-ref ref="{{ v['value'] }}"
-                                       expandKey="{{ makeExpandKey(v['name']) }}">
-                      </any-service-ref>
-                    </div>
-                  </div>
+              <div style="padding-left:2em;" class="memberList">
+                <template repeat="{{ v in properLocals }}">
+                  {{ v['name']}}&nbsp;:&nbsp;
+                  <any-service-ref ref="{{ v['value'] }}"
+                                   expandKey="{{ makeExpandKey(v['name']) }}"
+                                   asValue="{{ true }}">
+                  </any-service-ref><br>
                 </template>
               </div>
             </div>
diff --git a/runtime/observatory/lib/src/elements/flag_list.html b/runtime/observatory/lib/src/elements/flag_list.html
index 017e28d..9a39cbb 100644
--- a/runtime/observatory/lib/src/elements/flag_list.html
+++ b/runtime/observatory/lib/src/elements/flag_list.html
@@ -8,6 +8,7 @@
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
       <top-nav-menu></top-nav-menu>
+      <vm-nav-menu vm="{{ app.vm }}"></vm-nav-menu>
       <nav-menu link="{{ makeLink('/flags') }}" anchor="flags" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
     </nav-bar>
diff --git a/runtime/observatory/lib/src/elements/function_view.html b/runtime/observatory/lib/src/elements/function_view.html
index 2119fa8..57e2c8c 100644
--- a/runtime/observatory/lib/src/elements/function_view.html
+++ b/runtime/observatory/lib/src/elements/function_view.html
@@ -46,6 +46,14 @@
             <any-service-ref ref="{{ function.dartOwner }}"></any-service-ref>
           </div>
         </div>
+        <template if="{{ function.field != null }}">
+          <div class="memberItem">
+            <div class="memberName">field</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ function.field }}"></any-service-ref>
+            </div>
+          </div>
+        </template>
         <div class="memberItem">
           <div class="memberName">script</div>
           <div class="memberValue">
@@ -94,6 +102,18 @@
            <div class="memberName">inlinable</div>
            <div class="memberValue">{{ function.isInlinable }}</div>
          </div>
+         <div class="memberItem">
+           <div class="memberName">intrinsic</div>
+           <div class="memberValue">{{ function.hasIntrinsic }}</div>
+         </div>
+         <div class="memberItem">
+           <div class="memberName">recognized</div>
+           <div class="memberValue">{{ function.isRecognized }}</div>
+         </div>
+         <div class="memberItem">
+           <div class="memberName">native</div>
+           <div class="memberValue">{{ function.isNative }}</div>
+         </div>
          <template if="{{ function.name != function.vmName }}">
            <div class="memberItem">
              <div class="memberName">vm name</div>
diff --git a/runtime/observatory/lib/src/elements/instance_ref.html b/runtime/observatory/lib/src/elements/instance_ref.html
index 57dcec9..385727b 100644
--- a/runtime/observatory/lib/src/elements/instance_ref.html
+++ b/runtime/observatory/lib/src/elements/instance_ref.html
@@ -87,6 +87,9 @@
                                expandKey="{{ makeExpandKey(index.toString()) }}">
               </any-service-ref><br>
             </template>
+            <template if="{{ ref.length != ref.elements.length }}">
+              <div><em>{{ ref.length - ref.elements.length }} omitted elements</em></div>
+            </template>
           </div>
         </curly-block>
       </template>
@@ -103,6 +106,9 @@
                                  expandKey="{{ makeExpandKey('value') }}">
               </any-service-ref><br>
             </template>
+            <template if="{{ ref.length != ref.associations.length }}">
+              <div><em>{{ ref.length - ref.associations.length }} omitted associations</em></div>
+            </template>
           </div>
         </curly-block>
       </template>
@@ -115,6 +121,9 @@
               [ {{ index }} ]&nbsp;&nbsp;
               {{ ref.typedElements[index].toString() }}<br>
             </template>
+            <template if="{{ ref.length != ref.typedElements.length }}">
+              <div><em>{{ ref.length - ref.typedElements.length }} omitted elements</em></div>
+            </template>
           </div>
         </curly-block>
       </template>
diff --git a/runtime/observatory/lib/src/elements/instance_view.html b/runtime/observatory/lib/src/elements/instance_view.html
index 28f093f..f54059f 100644
--- a/runtime/observatory/lib/src/elements/instance_view.html
+++ b/runtime/observatory/lib/src/elements/instance_view.html
@@ -154,7 +154,7 @@
         </template>
 
         <template if="{{ instance.elements.isNotEmpty }}">
-          elements ({{ instance.elements.length }})
+          elements ({{ instance.length }})
           <curly-block expand="{{ instance.elements.length <= 100 }}">
             <div class="memberList">
               <template repeat="{{ index in instance.elements.asMap().keys }}">
@@ -166,12 +166,20 @@
                   </div>
                 </div>
               </template>
+	      <template if="{{ instance.length != instance.elements.length }}">
+                <div class="memberItem">
+                  <div class="memberName">...</div>
+                  <div class="memberValue">
+                    <em>{{ instance.length - instance.elements.length }} omitted elements</em>
+                  </div>
+                </div>
+              </template>
             </div>
           </curly-block><br><br>
         </template>
 
         <template if="{{ instance.associations.isNotEmpty }}">
-          associations ({{ instance.elements.length }})
+          associations ({{ instance.length }})
           <curly-block expand="{{ instance.associations.length <= 100 }}">
             <div class="memberList">
               <template repeat="{{ association in instance.associations }}">
@@ -184,12 +192,20 @@
                   </div>
                 </div>
               </template>
+	      <template if="{{ instance.length != instance.associations.length }}">
+                <div class="memberItem">
+                  <div class="memberName">...</div>
+                  <div class="memberValue">
+                    <em>{{ instance.length - instance.associations.length }} omitted associations</em>
+                  </div>
+                </div>
+              </template>
             </div>
           </curly-block><br><br>
         </template>
 
         <template if="{{ instance.typedElements.isNotEmpty }}">
-          elements ({{ instance.typedElements.length }})
+          elements ({{ instance.length }})
           <curly-block expand="{{ instance.typedElements.length <= 100 }}">
             <div class="memberList">
               <template repeat="{{ index in instance.typedElements.asMap().keys }}">
@@ -198,6 +214,14 @@
                   <div class="memberValue">{{ instance.typedElements[index].toString() }}</div>
                 </div>
               </template>
+	      <template if="{{ instance.length != instance.typedElements.length }}">
+                <div class="memberItem">
+                  <div class="memberName">...</div>
+                  <div class="memberValue">
+                    <em>{{ instance.length - instance.elements.length }} omitted elements</em>
+                  </div>
+                </div>
+              </template>
             </div>
           </curly-block><br><br>
         </template>
diff --git a/runtime/observatory/lib/src/elements/library_ref.dart b/runtime/observatory/lib/src/elements/library_ref.dart
index cbe7d4b..4f65a39 100644
--- a/runtime/observatory/lib/src/elements/library_ref.dart
+++ b/runtime/observatory/lib/src/elements/library_ref.dart
@@ -4,10 +4,33 @@
 
 library library_ref_element;
 
+import 'package:observatory/service.dart';
 import 'package:polymer/polymer.dart';
 import 'service_ref.dart';
+import 'dart:async';
 
 @CustomTag('library-ref')
 class LibraryRefElement extends ServiceRefElement {
+  @observable bool asValue = false;
+
   LibraryRefElement.created() : super.created();
+
+  String makeExpandKey(String key) {
+    return '${expandKey}/${key}';
+  }
+
+  dynamic expander() {
+    return expandEvent;
+  }
+
+  void expandEvent(bool expand, Function onDone) {
+    if (expand) {
+      Library lib = ref;
+      lib.reload().then((result) {
+        return Future.wait(lib.variables.map((field) => field.reload()));
+      }).whenComplete(onDone);
+    } else {
+      onDone();
+    }
+  }
 }
diff --git a/runtime/observatory/lib/src/elements/library_ref.html b/runtime/observatory/lib/src/elements/library_ref.html
index 30272a4..a4313c1 100644
--- a/runtime/observatory/lib/src/elements/library_ref.html
+++ b/runtime/observatory/lib/src/elements/library_ref.html
@@ -1,15 +1,39 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="curly_block.html">
+<link rel="import" href="observatory_element.html">
 <link rel="import" href="service_ref.html">
 
 <polymer-element name="library-ref" extends="service-ref">
-  <template><link rel="stylesheet" href="css/shared.css"><!--
-    --><template if="{{ nameIsEmpty }}"><!--
-      --><a on-click="{{ goto }}" _href="{{ url }}">unnamed</a><!--
-    --></template><!--
-    --><template if="{{ !nameIsEmpty }}"><!--
-      --><a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a><!--
-    --></template><!--
-  --></template>
+  <template>
+    <link rel="stylesheet" href="css/shared.css">
+    <style>
+      .indented {
+      margin-left: 1.5em;
+      font: 400 14px 'Montserrat', sans-serif;
+      line-height: 150%;
+      }
+    </style>
+    <template if="{{ nameIsEmpty }}">
+      <a on-click="{{ goto }}" _href="{{ url }}">unnamed</a>
+    </template>
+    <template if="{{ !nameIsEmpty }}">
+      <a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
+    </template>
+    <template if="{{ asValue }}">
+      <curly-block callback="{{ expander() }}" expandKey="{{ expandKey }}">
+        <div class="indented">
+          <template repeat="{{ field in ref.variables }}">
+            <template if="{{ field.isStatic }}">
+              {{ field.name }}&nbsp;:&nbsp;
+              <any-service-ref ref="{{ field.staticValue }}"
+                               expandKey="{{ makeExpandKey(field.name) }}">
+              </any-service-ref><br>
+            </template>
+          </template>
+        </div>
+      </curly-block>
+    </template>
+  </template>
 </polymer-element>
 
 <script type="application/dart" src="library_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_view.html b/runtime/observatory/lib/src/elements/megamorphiccache_view.html
index db073e6..0454e0d 100644
--- a/runtime/observatory/lib/src/elements/megamorphiccache_view.html
+++ b/runtime/observatory/lib/src/elements/megamorphiccache_view.html
@@ -28,6 +28,18 @@
 
       <div class="memberList">
         <div class="memberItem">
+          <div class="memberName">selector</div>
+          <div class="memberValue">
+            {{ megamorphicCache.selector }}
+          </div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">argumentsDescriptor</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ megamorphicCache.argumentsDescriptor }}"></any-service-ref>
+          </div>
+        </div>
+        <div class="memberItem">
           <div class="memberName">mask</div>
           <div class="memberValue"> 
             {{ megamorphicCache.mask }}
diff --git a/runtime/observatory/lib/src/elements/object_common.dart b/runtime/observatory/lib/src/elements/object_common.dart
index eea85ff..1deb5d6 100644
--- a/runtime/observatory/lib/src/elements/object_common.dart
+++ b/runtime/observatory/lib/src/elements/object_common.dart
@@ -15,10 +15,18 @@
   @published ServiceMap path;
   @published ServiceMap inboundReferences;
   @observable int retainedBytes = null;
+  @observable int reachableBytes = null;
 
   ObjectCommonElement.created() : super.created();
 
   // TODO(koda): Add no-arg "calculate-link" instead of reusing "eval-link".
+  Future<ServiceObject> reachableSize(var dummy) {
+    return object.isolate.getReachableSize(object).then((Instance obj) {
+      // TODO(turnidge): Handle collected/expired objects gracefully.
+      reachableBytes = int.parse(obj.valueAsString);
+    });
+  }
+
   Future<ServiceObject> retainedSize(var dummy) {
     return object.isolate.getRetainedSize(object).then((Instance obj) {
       // TODO(turnidge): Handle collected/expired objects gracefully.
diff --git a/runtime/observatory/lib/src/elements/object_common.html b/runtime/observatory/lib/src/elements/object_common.html
index 7cad87a..14311e0 100644
--- a/runtime/observatory/lib/src/elements/object_common.html
+++ b/runtime/observatory/lib/src/elements/object_common.html
@@ -26,6 +26,20 @@
         <div class="memberValue">{{ object.size | formatSize }}</div>
       </div>
 
+      <div class="memberItem" title="Space reachable from this object, excluding class references">
+        <div class="memberName">reachable size</div>
+        <div class="memberValue">
+          <template if="{{ reachableBytes == null }}">
+            <eval-link callback="{{ reachableSize }}"
+                       label="[calculate]">
+            </eval-link>
+          </template>
+          <template if="{{ reachableBytes != null }}">
+            {{ reachableBytes | formatSize }}
+          </template>
+        </div>
+      </div>
+
       <div class="memberItem" title="Space that would be reclaimed if references to this object were replaced with null">
         <div class="memberName">retained size</div>
         <div class="memberValue">
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 92930a9..47bbff7 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -429,7 +429,7 @@
           if (loc.tokenPos != null) {
             line = script.tokenToLine(loc.tokenPos);
           } else {
-            line = script.tokenToLine(loc.line);
+            line = loc.line;
           }
           if ((line >= _startLine) && (line <= _endLine)) {
             _updateTask.queue();
@@ -663,12 +663,24 @@
   }
 
   Library resolveDependency(String relativeUri) {
+    // This isn't really correct: we need to ask the embedder to do the
+    // uri canonicalization for us, but Observatory isn't in a position
+    // to invoke the library tag handler. Handle the most common cases.
     var targetUri = Uri.parse(script.library.uri).resolve(relativeUri);
     for (Library l in script.isolate.libraries) {
       if (targetUri.toString() == l.uri) {
         return l;
       }
     }
+    if (targetUri.scheme == 'package') {
+      targetUri = "packages/${targetUri.path}";
+      for (Library l in script.isolate.libraries) {
+        if (targetUri.toString() == l.uri) {
+          return l;
+        }
+      }
+    }
+
     Logger.root.info("Could not resolve library dependency: $relativeUri");
     return null;
   }
@@ -824,6 +836,11 @@
       return table;
     }
 
+    var endLine = (endPos != null
+                   ? script.tokenToLine(endPos)
+                   : script.lines.length + script.lineOffset);
+    var lineNumPad = endLine.toString().length;
+
     annotationsCursor = 0;
 
     int blankLineCount = 0;
@@ -840,17 +857,17 @@
           if (blankLineCount < 4) {
             // Too few blank lines for an elipsis.
             for (int j = firstBlank; j  <= lastBlank; j++) {
-              table.append(lineElement(script.getLine(j)));
+              table.append(lineElement(script.getLine(j), lineNumPad));
             }
           } else {
             // Add an elipsis for the skipped region.
-            table.append(lineElement(script.getLine(firstBlank)));
-            table.append(lineElement(null));
-            table.append(lineElement(script.getLine(lastBlank)));
+            table.append(lineElement(script.getLine(firstBlank), lineNumPad));
+            table.append(lineElement(null, lineNumPad));
+            table.append(lineElement(script.getLine(lastBlank), lineNumPad));
           }
           blankLineCount = 0;
         }
-        table.append(lineElement(line));
+        table.append(lineElement(line, lineNumPad));
       }
     }
 
@@ -876,11 +893,11 @@
     return annotation;
   }
 
-  Element lineElement(ScriptLine line) {
+  Element lineElement(ScriptLine line, int lineNumPad) {
     var e = new DivElement();
     e.classes.add("sourceRow");
     e.append(lineBreakpointElement(line));
-    e.append(lineNumberElement(line));
+    e.append(lineNumberElement(line, lineNumPad));
     e.append(lineSourceElement(line));
     return e;
   }
@@ -952,9 +969,9 @@
     return e;
   }
 
-  Element lineNumberElement(ScriptLine line) {
+  Element lineNumberElement(ScriptLine line, int lineNumPad) {
     var lineNumber = line == null ? "..." : line.line;
-    var e = span("$nbsp$lineNumber$nbsp");
+    var e = span("$nbsp${lineNumber.toString().padLeft(lineNumPad,nbsp)}$nbsp");
     e.classes.add('noCopy');
 
     if (lineNumber == _currentLine) {
diff --git a/runtime/observatory/lib/src/elements/service_ref.dart b/runtime/observatory/lib/src/elements/service_ref.dart
index d823b86..e9aad6d 100644
--- a/runtime/observatory/lib/src/elements/service_ref.dart
+++ b/runtime/observatory/lib/src/elements/service_ref.dart
@@ -5,10 +5,14 @@
 library service_ref_element;
 
 import 'dart:html';
+
 import 'package:logging/logging.dart';
-import 'package:polymer/polymer.dart';
-import 'observatory_element.dart';
 import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+
+import 'class_ref.dart';
+import 'library_ref.dart';
+import 'observatory_element.dart';
 
 @CustomTag('service-ref')
 class ServiceRefElement extends ObservatoryElement {
@@ -56,6 +60,24 @@
   bool get nameIsEmpty {
     return (name == null) || name.isEmpty;
   }
+
+
+  @published bool expanded = false;
+  dynamic expander() {
+    return expandEvent;
+  }
+  void expandEvent(bool expand, Function onDone) {
+    if (expand) {
+      ref.reload().then((result) {
+        ref = result;
+        notifyPropertyChange(#ref, 0, 1);
+        expanded = true;
+      }).whenComplete(onDone);
+    } else {
+      expanded = false;
+      onDone();
+    }
+  }
 }
 
 
@@ -63,14 +85,16 @@
 class AnyServiceRefElement extends ObservatoryElement {
   @published ServiceObject ref;
   @published String expandKey;
+  @published bool asValue = false;
   AnyServiceRefElement.created() : super.created();
 
   Element _constructElementForRef() {
     var type = ref.type;
     switch (type) {
      case 'Class':
-        ServiceRefElement element = new Element.tag('class-ref');
+        ClassRefElement element = new Element.tag('class-ref');
         element.ref = ref;
+        element.asValue = asValue;
         return element;
       case 'Code':
         ServiceRefElement element = new Element.tag('code-ref');
@@ -93,8 +117,9 @@
         element.ref = ref;
         return element;
       case 'Library':
-        ServiceRefElement element = new Element.tag('library-ref');
+        LibraryRefElement element = new Element.tag('library-ref');
         element.ref = ref;
+        element.asValue = asValue;
         return element;
       case 'Object':
         ServiceRefElement element = new Element.tag('object-ref');
diff --git a/runtime/observatory/lib/src/elements/service_ref.html b/runtime/observatory/lib/src/elements/service_ref.html
index 839b4c5..17ce4c5 100644
--- a/runtime/observatory/lib/src/elements/service_ref.html
+++ b/runtime/observatory/lib/src/elements/service_ref.html
@@ -14,8 +14,31 @@
       <a on-click="{{ goto }}" _href="{{ url }}">
         <em>{{ ref.vmType }}</em> ({{ ref.length }})
       </a>
+      <curly-block callback="{{ expander() }}" expandKey="{{ expandKey }}">
+        <template if="{{ expanded }}">
+        <div class="indented">
+          <template repeat="{{ entry in ref.entries }}">
+            <div class="memberItem">
+              <div class="memberName">[PP+0x{{ entry['offset'].toRadixString(16) }}]</div>
+              <div class="memberValue">
+                <template if="{{ entry['kind'] == 'Object' }}">
+                  <any-service-ref ref="{{ entry['value'] }}">
+                  </any-service-ref>
+                </template>
+                <template if="{{ entry['kind'] == 'Immediate' }}">
+                  Immediate 0x{{ entry['value'].toRadixString(16) }}
+                </template>
+                <template if="{{ entry['kind'] == 'NativeEntry' }}">
+                  NativeEntry 0x{{ entry['value'].toRadixString(16) }}
+                </template>
+              </div>
+            </div>
+          </template>
+        </div>
+        </template>
+      </curly-block>
     </template>
-    <template if="{{ ref.isICData }}">
+    <template if="{{ ref.isICData || ref.isMegamorphicCache }}">
       <a on-click="{{ goto }}" _href="{{ url }}">
         <em>{{ ref.vmType }}</em> ({{ ref.selector }})
       </a>
@@ -25,7 +48,7 @@
         <em>{{ ref.vmType }}</em> ({{ ref.code.name }})
       </a>
     </template>
-    <template if="{{ !(ref.isObjectPool || ref.isICData || ref.isInstructions) }}">
+    <template if="{{ !(ref.isObjectPool || ref.isICData || ref.isMegamorphicCache || ref.isInstructions) }}">
       <template if="{{ nameIsEmpty }}">
         <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.vmType }}</em></a>
       </template>
diff --git a/runtime/observatory/lib/src/elements/timeline_page.dart b/runtime/observatory/lib/src/elements/timeline_page.dart
new file mode 100644
index 0000000..04a7376
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/timeline_page.dart
@@ -0,0 +1,83 @@
+// 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 timeline_page_element;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:html';
+import 'observatory_element.dart';
+import 'package:observatory/app.dart';
+import 'package:observatory/service_html.dart';
+import 'package:polymer/polymer.dart';
+
+
+@CustomTag('timeline-page')
+class TimelinePageElement extends ObservatoryElement {
+  TimelinePageElement.created() : super.created();
+
+  attached() {
+    super.attached();
+    _resizeSubscription = window.onResize.listen((_) => _updateSize());
+    _updateSize();
+  }
+
+  detached() {
+    super.detached();
+    if (_resizeSubscription != null) {
+      _resizeSubscription.cancel();
+    }
+  }
+
+  Future postMessage(String method) {
+    IFrameElement e = $['root'];
+    var isolateIds = new List();
+    for (var isolate in app.vm.isolates) {
+      isolateIds.add(isolate.id);
+    }
+    var message = {
+      'method': method,
+      'params': {
+        'vmAddress': (app.vm as WebSocketVM).target.networkAddress,
+        'isolateIds': isolateIds
+      }
+    };
+    e.contentWindow.postMessage(JSON.encode(message), window.location.href);
+    return null;
+  }
+
+  Future refresh() async {
+    return postMessage('refresh');
+  }
+
+  Future clear() async {
+    await app.vm.invokeRpc('_clearVMTimeline', {});
+    return postMessage('clear');
+  }
+
+  Future recordOn() async {
+    return app.vm.invokeRpc('_setVMTimelineFlag', {
+      '_record': 'all',
+    });
+  }
+
+  Future recordOff() async {
+    return app.vm.invokeRpc('_setVMTimelineFlag', {
+      '_record': 'none',
+    });
+  }
+
+  _updateSize() {
+    IFrameElement e = $['root'];
+    final totalHeight = window.innerHeight;
+    final top = e.offset.top;
+    final bottomMargin = 32;
+    final mainHeight = totalHeight - top - bottomMargin;
+    e.style.setProperty('height', '${mainHeight}px');
+    e.style.setProperty('width', '100%');
+  }
+
+
+  StreamSubscription _resizeSubscription;
+}
diff --git a/runtime/observatory/lib/src/elements/timeline_page.html b/runtime/observatory/lib/src/elements/timeline_page.html
new file mode 100644
index 0000000..50b063d
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/timeline_page.html
@@ -0,0 +1,23 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="observatory_element.html">
+
+<polymer-element name="timeline-page" extends="observatory-element">
+  <template>
+    <link rel="stylesheet" href="css/shared.css">
+    <style>
+    </style>
+    <nav-bar>
+      <top-nav-menu></top-nav-menu>
+      <vm-nav-menu vm="{{ app.vm }}"></vm-nav-menu>
+      <nav-menu link="{{ makeLink('/timeline') }}" anchor="timeline" last="{{ true }}"></nav-menu>
+      <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-refresh callback="{{ clear }}" label="Clear"></nav-refresh>
+      <nav-refresh callback="{{ recordOn }}" label="Start recording"></nav-refresh>
+      <nav-refresh callback="{{ recordOff }}" label="Stop recording"></nav-refresh>
+    </nav-bar>
+    <iframe id="root" frameborder="0" src="../../../../timeline.html">
+    </iframe>
+  </template>
+</polymer-element>
+<script type="application/dart" src="timeline_page.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/vm_view.html b/runtime/observatory/lib/src/elements/vm_view.html
index 55fc712..2934009 100644
--- a/runtime/observatory/lib/src/elements/vm_view.html
+++ b/runtime/observatory/lib/src/elements/vm_view.html
@@ -56,6 +56,9 @@
           <div class="memberValue">
             See <a on-click="{{ goto }}" _href="{{ gotoLink('/flags') }}">flags</a>
           </div>
+          <div class="memberValue">
+            View <a on-click="{{ goto }}" _href="{{ gotoLink('/timeline') }}">timeline</a>
+          </div>
         </div>
       </div>
       <br>
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index acb3edf..e45cb8d 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -4,6 +4,11 @@
 
 part of service;
 
+// Some value smaller than the object ring, so requesting a large array
+// doesn't result in an expired ref because the elements lapped it in the
+// object ring.
+const int kDefaultFieldLimit = 100;
+
 /// Helper function for canceling a Future<StreamSubscription>.
 Future cancelFutureSubscription(
     Future<StreamSubscription> subscriptionFuture) async {
@@ -114,6 +119,7 @@
   String _vmType;
 
   bool get isICData => vmType == 'ICData';
+  bool get isMegamorphicCache => vmType == 'MegamorphicCache';
   bool get isInstructions => vmType == 'Instructions';
   bool get isObjectPool => vmType == 'ObjectPool';
   bool get isContext => type == 'Context';
@@ -283,6 +289,7 @@
   Future<ObservableMap> _fetchDirect() {
     Map params = {
       'objectId': id,
+      'count': kDefaultFieldLimit,
     };
     return isolate.invokeRpcNoUpgrade('getObject', params);
   }
@@ -828,10 +835,14 @@
     if (!loaded) {
       // The vm service relies on these events to keep the VM and
       // Isolate types up to date.
-      await listenEventStream(kVMStream, _dispatchEventToIsolate);
-      await listenEventStream(kIsolateStream, _dispatchEventToIsolate);
-      await listenEventStream(kDebugStream, _dispatchEventToIsolate);
-      await listenEventStream(_kGraphStream, _dispatchEventToIsolate);
+      try {
+        await listenEventStream(kVMStream, _dispatchEventToIsolate);
+        await listenEventStream(kIsolateStream, _dispatchEventToIsolate);
+        await listenEventStream(kDebugStream, _dispatchEventToIsolate);
+        await listenEventStream(_kGraphStream, _dispatchEventToIsolate);
+      } on FakeVMRpcException catch (_) {
+        // ignore FakeVMRpcExceptions here.
+      }
     }
     return await invokeRpcNoUpgrade('getVM', {});
   }
@@ -1126,6 +1137,8 @@
 /// State for a running isolate.
 class Isolate extends ServiceObjectOwner with Coverage {
   static const kLoggingStream = '_Logging';
+  static const kExtensionStream = 'Extension';
+
   @reflectable VM get vm => owner;
   @reflectable Isolate get isolate => this;
   @observable int number;
@@ -1160,6 +1173,8 @@
 
   @observable bool ioEnabled = false;
 
+  final List<String> extensionRPCs = new List<String>();
+
   Map<String,ServiceObject> _cache = new Map<String,ServiceObject>();
   final TagProfile tagProfile = new TagProfile(20);
 
@@ -1283,6 +1298,7 @@
     }
     Map params = {
       'objectId': objectId,
+      'count': kDefaultFieldLimit,
     };
     return isolate.invokeRpc('getObject', params);
   }
@@ -1424,6 +1440,11 @@
     if (savedStartTime == null) {
       vm._buildIsolateList();
     }
+
+    extensionRPCs.clear();
+    if (map['extensionRPCs'] != null) {
+      extensionRPCs.addAll(map['extensionRPCs']);
+    }
   }
 
   Future<TagProfile> updateTagProfile() {
@@ -1683,6 +1704,13 @@
     return invokeRpc('evaluateInFrame', params);
   }
 
+  Future<ServiceObject> getReachableSize(ServiceObject target) {
+    Map params = {
+      'targetId': target.id,
+    };
+    return invokeRpc('_getReachableSize', params);
+  }
+
   Future<ServiceObject> getRetainedSize(ServiceObject target) {
     Map params = {
       'targetId': target.id,
@@ -1865,6 +1893,7 @@
   static const kIsolateRunnable        = 'IsolateRunnable';
   static const kIsolateExit            = 'IsolateExit';
   static const kIsolateUpdate          = 'IsolateUpdate';
+  static const kServiceExtensionAdded  = 'ServiceExtensionAdded';
   static const kPauseStart             = 'PauseStart';
   static const kPauseExit              = 'PauseExit';
   static const kPauseBreakpoint        = 'PauseBreakpoint';
@@ -1880,6 +1909,7 @@
   static const kDebuggerSettingsUpdate = '_DebuggerSettingsUpdate';
   static const kConnectionClosed       = 'ConnectionClosed';
   static const kLogging                = '_Logging';
+  static const kExtension              = 'Extension';
 
   ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner);
 
@@ -1891,6 +1921,7 @@
   @observable DateTime timestamp;
   @observable Breakpoint breakpoint;
   @observable Frame topFrame;
+  @observable String extensionRPC;
   @observable Instance exception;
   @observable Instance asyncContinuation;
   @observable bool atAsyncJump;
@@ -1901,6 +1932,8 @@
   @observable String exceptions;
   @observable String bytesAsString;
   @observable Map logRecord;
+  @observable String extensionKind;
+  @observable Map extensionData;
 
   int chunkIndex, chunkCount, nodeCount;
 
@@ -1933,6 +1966,9 @@
         breakpoint = pauseBpts[0];
       }
     }
+    if (map['extensionRPC'] != null) {
+      extensionRPC = map['extensionRPC'];
+    }
     topFrame = map['topFrame'];
     if (map['exception'] != null) {
       exception = map['exception'];
@@ -1966,7 +2002,7 @@
       exceptions = map['_debuggerSettings']['_exceptions'];
     }
     if (map['bytes'] != null) {
-      var bytes = decodeBase64(map['bytes']);
+      var bytes = BASE64.decode(map['bytes']);
       bytesAsString = UTF8.decode(bytes);
     }
     if (map['logRecord'] != null) {
@@ -1975,6 +2011,10 @@
           new DateTime.fromMillisecondsSinceEpoch(logRecord['time']);
       logRecord['level'] = _findLogLevel(logRecord['level']);
     }
+    if (map['extensionKind'] != null) {
+      extensionKind = map['extensionKind'];
+      extensionData = map['extensionData'];
+    }
   }
 
   String toString() {
@@ -2408,7 +2448,7 @@
     elements = map['elements'];
     associations = map['associations'];
     if (map['bytes'] != null) {
-      var bytes = decodeBase64(map['bytes']);
+      var bytes = BASE64.decode(map['bytes']);
       switch (map['kind']) {
         case "Uint8ClampedList":
           typedElements = bytes.buffer.asUint8ClampedList(); break;
@@ -2563,6 +2603,9 @@
   @observable Code unoptimizedCode;
   @observable bool isOptimizable;
   @observable bool isInlinable;
+  @observable bool hasIntrinsic;
+  @observable bool isRecognized;
+  @observable bool isNative;
   @observable FunctionKind kind;
   @observable int deoptimizations;
   @observable String qualifiedName;
@@ -2570,6 +2613,7 @@
   @observable bool isDart;
   @observable ProfileFunction profile;
   @observable Instance icDataArray;
+  @observable Field field;
 
   bool get canCache => true;
   bool get immutable => false;
@@ -2602,6 +2646,9 @@
       qualifiedName = name;
     }
 
+    hasIntrinsic = map['_intrinsic'];
+    isNative = map['_native'];
+
     if (mapIsRef) {
       return;
     }
@@ -2613,10 +2660,20 @@
     code = map['code'];
     isOptimizable = map['_optimizable'];
     isInlinable = map['_inlinable'];
+    isRecognized = map['_recognized'];
     unoptimizedCode = map['_unoptimizedCode'];
     deoptimizations = map['_deoptimizations'];
     usageCounter = map['_usageCounter'];
     icDataArray = map['_icDataArray'];
+    field = map['_field'];
+  }
+
+  ServiceFunction get homeMethod {
+    var m = this;
+    while (m.dartOwner is ServiceFunction) {
+      m = m.dartOwner;
+    }
+    return m;
   }
 }
 
@@ -3338,6 +3395,8 @@
 class MegamorphicCache extends HeapObject {
   @observable int mask;
   @observable Instance buckets;
+  @observable String selector;
+  @observable Instance argumentsDescriptor;
 
   bool get canCache => false;
   bool get immutable => false;
@@ -3348,12 +3407,14 @@
     _upgradeCollection(map, isolate);
     super._update(map, mapIsRef);
 
+    selector = map['_selector'];
     if (mapIsRef) {
       return;
     }
 
     mask = map['_mask'];
     buckets = map['_buckets'];
+    argumentsDescriptor = map['_argumentsDescriptor'];
   }
 }
 
@@ -3402,11 +3463,16 @@
   @observable final int pcOffset;
   @observable final String machine;
   @observable final String human;
+  @observable final ServiceObject object;
   @observable CodeInstruction jumpTarget;
   @reflectable List<PcDescriptor> descriptors =
       new ObservableList<PcDescriptor>();
 
-  CodeInstruction(this.address, this.pcOffset, this.machine, this.human);
+  CodeInstruction(this.address,
+                  this.pcOffset,
+                  this.machine,
+                  this.human,
+                  this.object);
 
   @reflectable bool get isComment => address == 0;
   @reflectable bool get hasDescriptors => descriptors.length > 0;
@@ -3497,7 +3563,10 @@
   @observable ServiceObject objectPool;
   @observable ServiceFunction function;
   @observable Script script;
-  @observable bool isOptimized = false;
+  @observable bool isOptimized;
+  @observable bool hasIntrinsic;
+  @observable bool isNative;
+
   @reflectable int startAddress = 0;
   @reflectable int endAddress = 0;
   @reflectable final instructions = new ObservableList<CodeInstruction>();
@@ -3567,6 +3636,8 @@
     vmName = (m.containsKey('_vmName') ? m['_vmName'] : name);
     isOptimized = m['_optimized'];
     kind = CodeKind.fromString(m['kind']);
+    hasIntrinsic = m['_intrinsic'];
+    isNative = m['_native'];
     if (mapIsRef) {
       return;
     }
@@ -3646,20 +3717,25 @@
     instructions.clear();
     instructionsByAddressOffset = new List(endAddress - startAddress);
 
-    assert((disassembly.length % 3) == 0);
-    for (var i = 0; i < disassembly.length; i += 3) {
+    assert((disassembly.length % 4) == 0);
+    for (var i = 0; i < disassembly.length; i += 4) {
       var address = 0;  // Assume code comment.
       var machine = disassembly[i + 1];
       var human = disassembly[i + 2];
+      var object = disassembly[i + 3];
+      if (object != null) {
+        object = new ServiceObject._fromMap(owner, object);
+      }
       var pcOffset = 0;
-      if (disassembly[i] != '') {
+      if (disassembly[i] != null) {
         // Not a code comment, extract address.
         address = int.parse(disassembly[i], radix:16);
         pcOffset = address - startAddress;
       }
-      var instruction = new CodeInstruction(address, pcOffset, machine, human);
+      var instruction =
+          new CodeInstruction(address, pcOffset, machine, human, object);
       instructions.add(instruction);
-      if (disassembly[i] != '') {
+      if (disassembly[i] != null) {
         // Not a code comment.
         instructionsByAddressOffset[pcOffset] = instruction;
       }
diff --git a/runtime/observatory/observatory.gypi b/runtime/observatory/observatory.gypi
index 4971524..5d282ac 100644
--- a/runtime/observatory/observatory.gypi
+++ b/runtime/observatory/observatory.gypi
@@ -44,6 +44,7 @@
       'target_name': 'build_observatory',
       'type': 'none',
       'dependencies': [
+        'dart_bootstrap#host',
         'fetch_observatory_deps#host',
       ],
       'toolsets': ['host'],
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index 630ca4c..865f140 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -6,7 +6,6 @@
 {
   'sources': [
     'lib/app.dart',
-    'lib/base64.dart',
     'lib/cli.dart',
     'lib/cpu_profile.dart',
     'lib/debugger.dart',
@@ -134,6 +133,8 @@
     'lib/src/elements/service_view.html',
     'lib/src/elements/sliding_checkbox.dart',
     'lib/src/elements/sliding_checkbox.html',
+    'lib/src/elements/timeline_page.dart',
+    'lib/src/elements/timeline_page.html',
     'lib/src/elements/view_footer.dart',
     'lib/src/elements/view_footer.html',
     'lib/src/elements/vm_connect.dart',
@@ -152,5 +153,8 @@
     'web/index.html',
     'web/main.dart',
     'web/favicon.ico',
+    'web/third_party/trace_viewer_full.html',
+    'web/timeline.js',
+    'web/timeline.html',
   ],
 }
diff --git a/runtime/observatory/pubspec.yaml b/runtime/observatory/pubspec.yaml
index ade59b1..b00ab07 100644
--- a/runtime/observatory/pubspec.yaml
+++ b/runtime/observatory/pubspec.yaml
@@ -8,13 +8,14 @@
     inline_stylesheets:
       lib/src/elements/css/shared.css: false
       packages/charted/charts/themes/quantum_theme.css: false
+    $exclude: [web/third_party/*.html, web/timeline.html]
 - $dart2js:
     $include: "**/*.polymer.bootstrap.dart"
     suppressWarnings: false
     commandLineOptions: [--show-package-warnings]
 dependencies:
   args: any
-  charted: ^0.2.9
+  charted: ^0.3.0
   polymer: ^0.16.3
   unittest: < 0.12.0
   usage: any
diff --git a/runtime/observatory/run.sh b/runtime/observatory/run.sh
deleted file mode 100755
index 35fecbb..0000000
--- a/runtime/observatory/run.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh -e
-
-if [ ! -d "web" ]; then
-  echo "Error: you must run this script from the client directory."
-  exit
-fi
-
-PUB_PATH=pub
-PUB_ARGS="serve --hostname 127.0.0.1 --port 9191"
-DART_PATH=dart
-DART_ARGS="bin/server.dart --host 127.0.0.1 --port 9090"
-DART_ARGS="$DART_ARGS --pub-host 127.0.0.1 --pub-port 9191"
-
-# Kill any child processes on exit.
-trap 'kill $(jobs -pr)' SIGINT SIGTERM EXIT
-
-echo "This script assumes that both *pub* and *dart* are in your PATH."
-echo "Launching Observatory server."
-echo "Launching pub."
-echo ""
-echo ""
-echo ""
-$DART_PATH $DART_ARGS &
-$PUB_PATH $PUB_ARGS
-
diff --git a/runtime/observatory/tests/service/async_next_test.dart b/runtime/observatory/tests/service/async_next_test.dart
index 9e298f7..f3c64d9 100644
--- a/runtime/observatory/tests/service/async_next_test.dart
+++ b/runtime/observatory/tests/service/async_next_test.dart
@@ -25,6 +25,7 @@
 }
 
 asyncNext(Isolate isolate) async {
+  print('asyncNext');
   return isolate.asyncStepOver()[Isolate.kSecondResume];
 }
 
diff --git a/runtime/observatory/tests/service/coverage_test.dart b/runtime/observatory/tests/service/coverage_test.dart
index 5223092..0255687 100644
--- a/runtime/observatory/tests/service/coverage_test.dart
+++ b/runtime/observatory/tests/service/coverage_test.dart
@@ -11,7 +11,7 @@
 int globalVar = 100;
 
 class MyClass {
-       static       void myFunction(int value) {
+  static void myFunction(int value) {
     if (value < 0) {
       print("negative");
     } else {
@@ -75,7 +75,7 @@
   coverage = await isolate.invokeRpcNoUpgrade('_getCoverage',
                                               { 'targetId': lib.id });
   expect(coverage['type'], equals('CodeCoverage'));
-  expect(coverage['coverage'].length, equals(3));
+  expect(coverage['coverage'].length, equals(4));
   expect(coverage['coverage'][0]['hits'],
          equals([15, 1, 16, 0, 18, 1, 20, 1,
                  24, 1, 25, 1, 27, 0]));
@@ -87,7 +87,7 @@
   coverage = await isolate.invokeRpcNoUpgrade('_getCoverage',
                                        { 'targetId': cls.location.script.id });
   expect(coverage['type'], equals('CodeCoverage'));
-  expect(coverage['coverage'].length, equals(3));
+  expect(coverage['coverage'].length, equals(4));
   expect(coverage['coverage'][0]['hits'],
          equals([15, 1, 16, 0, 18, 1, 20, 1,
                  24, 1, 25, 1, 27, 0]));
diff --git a/runtime/observatory/tests/service/developer_extension_test.dart b/runtime/observatory/tests/service/developer_extension_test.dart
index f134606..e29686b 100644
--- a/runtime/observatory/tests/service/developer_extension_test.dart
+++ b/runtime/observatory/tests/service/developer_extension_test.dart
@@ -55,6 +55,11 @@
 
 void test() {
   registerExtension('__delay', Handler);
+  debugger();
+  postEvent('ALPHA', {
+    'cat': 'dog'
+  });
+  debugger();
   registerExtension('__error', Handler);
   registerExtension('__exception', Handler);
   registerExtension('__null', Handler);
@@ -71,6 +76,24 @@
 }
 
 var tests = [
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    await isolate.load();
+    expect(isolate.extensionRPCs.length, 1);
+    expect(isolate.extensionRPCs[0], equals('__delay'));
+  },
+  resumeIsolateAndAwaitEvent(Isolate.kExtensionStream, (ServiceEvent event) {
+    expect(event.kind, equals(ServiceEvent.kExtension));
+    expect(event.extensionKind, equals('ALPHA'));
+    expect(event.extensionData, new isInstanceOf<Map>());
+    expect(event.extensionData['cat'], equals('dog'));
+  }),
+  hasStoppedAtBreakpoint,
+  resumeIsolateAndAwaitEvent(VM.kIsolateStream, (ServiceEvent event) {
+    // Check that we received an event when '__error' was registered.
+    expect(event.kind, equals(ServiceEvent.kServiceExtensionAdded));
+    expect(event.extensionRPC, equals('__error'));
+  }),
   // Initial.
   (Isolate isolate) async {
     var result;
@@ -130,4 +153,4 @@
   },
 ];
 
-main(args) async => runIsolateTests(args, tests, testeeBefore:test);
+main(args) async => runIsolateTests(args, tests, testeeConcurrent:test);
diff --git a/runtime/observatory/tests/service/get_cpu_profile_timeline_rpc_test.dart b/runtime/observatory/tests/service/get_cpu_profile_timeline_rpc_test.dart
new file mode 100644
index 0000000..4a6a88d
--- /dev/null
+++ b/runtime/observatory/tests/service/get_cpu_profile_timeline_rpc_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+fib(n) {
+  if (n < 0) return 0;
+  if (n == 0) return 1;
+  return fib(n - 1) + fib(n - 2);
+}
+
+testeeDo() {
+  print("Testee doing something.");
+  fib(25);
+  print("Testee did something.");
+}
+
+var tests = [
+  (Isolate isolate) async {
+    var params = {
+      'tags': 'VMUser'
+    };
+    var result = await isolate.invokeRpcNoUpgrade(
+        '_getCpuProfileTimeline', params);
+    print(result);
+    expect(result['type'], equals('_CpuProfileTimeline'));
+
+    var isString = new isInstanceOf<String>();
+    var isInt = new isInstanceOf<int>();
+
+    Map frames = result['stackFrames'];
+    for (Map frame in frames.values) {
+      expect(frame['category'], isString);
+      expect(frame['name'], isString);
+      if (frame['parent'] != null) {
+        expect(frames.containsKey(frame['parent']), isTrue);
+      }
+    }
+
+    List events = result['traceEvents'];
+    for (Map event in events) {
+      expect(event['ph'], equals('P'));
+      expect(event['pid'], isInt);
+      expect(event['tid'], isInt);
+      expect(event['ts'], isInt);
+      expect(event['cat'], equals("Dart"));
+      expect(frames.containsKey(event['sf']), isTrue);
+    }
+  },
+];
+
+main(args) async => runIsolateTests(args, tests, testeeBefore: testeeDo);
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart
index fdcbaa1..6bfa71f 100644
--- a/runtime/observatory/tests/service/get_object_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -5,9 +5,10 @@
 
 library get_object_rpc_test;
 
+import 'dart:typed_data';
+import 'dart:convert' show BASE64;
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
-
 import 'test_helper.dart';
 
 class _DummyClass {
@@ -33,6 +34,9 @@
   return await isolate.invokeRpcNoUpgrade('evaluate', params);
 }
 
+var uint8List = new Uint8List.fromList([3, 2, 1]);
+var uint64List = new Uint64List.fromList([3, 2, 1]);
+
 var tests = [
   // null object.
   (Isolate isolate) async {
@@ -99,16 +103,108 @@
     expect(result['class']['name'], equals('_GrowableList'));
     expect(result['size'], isPositive);
     expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], isNull);
     expect(result['elements'].length, equals(3));
     expect(result['elements'][0]['type'], equals('@Instance'));
     expect(result['elements'][0]['kind'], equals('Int'));
     expect(result['elements'][0]['valueAsString'], equals('3'));
+    expect(result['elements'][1]['type'], equals('@Instance'));
+    expect(result['elements'][1]['kind'], equals('Int'));
+    expect(result['elements'][1]['valueAsString'], equals('2'));
+    expect(result['elements'][2]['type'], equals('@Instance'));
+    expect(result['elements'][2]['kind'], equals('Int'));
+    expect(result['elements'][2]['valueAsString'], equals('1'));
+  },
+
+  // List prefix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var params = {
+      'objectId': evalResult['id'],
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('List'));
+    expect(result['_vmType'], equals('GrowableObjectArray'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_GrowableList'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], equals(2));
+    expect(result['elements'].length, equals(2));
+    expect(result['elements'][0]['type'], equals('@Instance'));
+    expect(result['elements'][0]['kind'], equals('Int'));
+    expect(result['elements'][0]['valueAsString'], equals('3'));
+    expect(result['elements'][1]['type'], equals('@Instance'));
+    expect(result['elements'][1]['kind'], equals('Int'));
+    expect(result['elements'][1]['valueAsString'], equals('2'));
+  },
+
+  // List suffix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 2,
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('List'));
+    expect(result['_vmType'], equals('GrowableObjectArray'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_GrowableList'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(2));
+    expect(result['count'], equals(1));
+    expect(result['elements'].length, equals(1));
+    expect(result['elements'][0]['type'], equals('@Instance'));
+    expect(result['elements'][0]['kind'], equals('Int'));
+    expect(result['elements'][0]['valueAsString'], equals('1'));
+  },
+
+  // List with wacky offset.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 100,
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('List'));
+    expect(result['_vmType'], equals('GrowableObjectArray'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_GrowableList'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(3));
+    expect(result['count'], equals(0));
+    expect(result['elements'], isEmpty);
   },
 
   // A built-in Map.
   (Isolate isolate) async {
     // Call eval to get a Dart map.
-    var evalResult = await eval(isolate, '{"x": 3, "y": 4}');
+    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
     var params = {
       'objectId': evalResult['id'],
     };
@@ -122,6 +218,51 @@
     expect(result['class']['name'], equals('_InternalLinkedHashMap'));
     expect(result['size'], isPositive);
     expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], isNull);
+    expect(result['associations'].length, equals(3));
+    expect(result['associations'][0]['key']['type'], equals('@Instance'));
+    expect(result['associations'][0]['key']['kind'], equals('String'));
+    expect(result['associations'][0]['key']['valueAsString'], equals('x'));
+    expect(result['associations'][0]['value']['type'], equals('@Instance'));
+    expect(result['associations'][0]['value']['kind'], equals('Int'));
+    expect(result['associations'][0]['value']['valueAsString'], equals('3'));
+    expect(result['associations'][1]['key']['type'], equals('@Instance'));
+    expect(result['associations'][1]['key']['kind'], equals('String'));
+    expect(result['associations'][1]['key']['valueAsString'], equals('y'));
+    expect(result['associations'][1]['value']['type'], equals('@Instance'));
+    expect(result['associations'][1]['value']['kind'], equals('Int'));
+    expect(result['associations'][1]['value']['valueAsString'], equals('4'));
+    expect(result['associations'][2]['key']['type'], equals('@Instance'));
+    expect(result['associations'][2]['key']['kind'], equals('String'));
+    expect(result['associations'][2]['key']['valueAsString'], equals('z'));
+    expect(result['associations'][2]['value']['type'], equals('@Instance'));
+    expect(result['associations'][2]['value']['kind'], equals('Int'));
+    expect(result['associations'][2]['value']['valueAsString'], equals('5'));
+  },
+
+  // Map prefix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart map.
+    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var params = {
+      'objectId': evalResult['id'],
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Map'));
+    expect(result['_vmType'], equals('LinkedHashMap'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_InternalLinkedHashMap'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], equals(2));
     expect(result['associations'].length, equals(2));
     expect(result['associations'][0]['key']['type'], equals('@Instance'));
     expect(result['associations'][0]['key']['kind'], equals('String'));
@@ -137,6 +278,268 @@
     expect(result['associations'][1]['value']['valueAsString'], equals('4'));
   },
 
+  // Map suffix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart map.
+    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 2,
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Map'));
+    expect(result['_vmType'], equals('LinkedHashMap'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_InternalLinkedHashMap'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(2));
+    expect(result['count'], equals(1));
+    expect(result['associations'].length, equals(1));
+    expect(result['associations'][0]['key']['type'], equals('@Instance'));
+    expect(result['associations'][0]['key']['kind'], equals('String'));
+    expect(result['associations'][0]['key']['valueAsString'], equals('z'));
+    expect(result['associations'][0]['value']['type'], equals('@Instance'));
+    expect(result['associations'][0]['value']['kind'], equals('Int'));
+    expect(result['associations'][0]['value']['valueAsString'], equals('5'));
+  },
+
+  // Map with wacky offset
+  (Isolate isolate) async {
+    // Call eval to get a Dart map.
+    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 100,
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Map'));
+    expect(result['_vmType'], equals('LinkedHashMap'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_InternalLinkedHashMap'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(3));
+    expect(result['count'], equals(0));
+    expect(result['associations'], isEmpty);
+  },
+
+  // Uint8List.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint8List');
+    var params = {
+      'objectId': evalResult['id'],
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint8List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint8Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], isNull);
+    expect(result['bytes'], equals('AwIB'));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint8List().toString(), equals('[3, 2, 1]'));
+  },
+
+  // Uint8List prefix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint8List');
+    var params = {
+      'objectId': evalResult['id'],
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint8List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint8Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], equals(2));
+    expect(result['bytes'], equals('AwI='));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint8List().toString(), equals('[3, 2]'));
+  },
+
+  // Uint8List suffix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint8List');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset' : 2,
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint8List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint8Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(2));
+    expect(result['count'], equals(1));
+    expect(result['bytes'], equals('AQ=='));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint8List().toString(), equals('[1]'));
+  },
+
+  // Uint8List with wacky offset.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint8List');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset' : 100,
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint8List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint8Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(3));
+    expect(result['count'], equals(0));
+    expect(result['bytes'], equals(''));
+  },
+
+  // Uint64List.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint64List');
+    var params = {
+      'objectId': evalResult['id'],
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint64List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint64Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], isNull);
+    expect(result['bytes'], equals('AwAAAAAAAAACAAAAAAAAAAEAAAAAAAAA'));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint64List().toString(), equals('[3, 2, 1]'));
+  },
+
+  // Uint64List prefix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint64List');
+    var params = {
+      'objectId': evalResult['id'],
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint64List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint64Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], isNull);
+    expect(result['count'], equals(2));
+    expect(result['bytes'], equals('AwAAAAAAAAACAAAAAAAAAA=='));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint64List().toString(), equals('[3, 2]'));
+  },
+
+  // Uint64List suffix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint64List');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset' : 2,
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint64List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint64Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(2));
+    expect(result['count'], equals(1));
+    expect(result['bytes'], equals('AQAAAAAAAAA='));
+    var bytes = BASE64.decode(result['bytes']);
+    expect(bytes.buffer.asUint64List().toString(), equals('[1]'));
+  },
+
+  // Uint64List with wacky offset.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, 'uint64List');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset' : 100,
+      'count' : 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('Uint64List'));
+    expect(result['_vmType'], equals('TypedData'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], isNull);
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_Uint64Array'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(3));
+    expect(result['offset'], equals(3));
+    expect(result['count'], equals(0));
+    expect(result['bytes'], equals(''));
+  },
+
   // An expired object.
   (Isolate isolate) async {
     var params = {
@@ -371,7 +774,7 @@
   (Isolate isolate) async {
     // Call eval to get a class id.
     var evalResult = await eval(isolate, 'new _DummyClass()');
-    var id = "${evalResult['class']['id']}/fields/0";
+    var id = "${evalResult['class']['id']}/fields/dummyVar";
     var params = {
       'objectId': id,
     };
@@ -393,7 +796,7 @@
   (Isolate isolate) async {
     // Call eval to get a class id.
     var evalResult = await eval(isolate, 'new _DummyClass()');
-    var id = "${evalResult['class']['id']}/fields/9999";
+    var id = "${evalResult['class']['id']}/fields/mythicalField";
     var params = {
       'objectId': id,
     };
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
new file mode 100644
index 0000000..71345ee
--- /dev/null
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'dart:developer';
+
+int globalVar = 100;
+
+class MyClass {
+  static void myFunction(int value) {
+    if (value < 0) {
+      print("negative");
+    } else {
+      print("positive");
+    }
+    debugger();
+  }
+
+  static void otherFunction(int value) {
+    if (value < 0) {
+      print("otherFunction <");
+    } else {
+      print("otherFunction >=");
+    }
+  }
+}
+
+void testFunction() {
+  MyClass.otherFunction(-100);
+  MyClass.myFunction(10000);
+}
+
+bool allRangesCompiled(coverage) {
+  for (int i = 0; i < coverage['ranges'].length; i++) {
+    if (!coverage['ranges'][i]['compiled']) {
+      return false;
+    }
+  }
+  return true;
+}
+
+var tests = [
+
+hasStoppedAtBreakpoint,
+
+(Isolate isolate) async {
+  var stack = await isolate.getStack();
+
+  // Make sure we are in the right place.
+  expect(stack.type, equals('Stack'));
+  expect(stack['frames'].length, greaterThanOrEqualTo(2));
+  expect(stack['frames'][0].function.name, equals('myFunction'));
+  expect(stack['frames'][0].function.dartOwner.name, equals('MyClass'));
+
+  var func = stack['frames'][0].function;
+  expect(func.name, equals('myFunction'));
+  await func.load();
+
+  var expectedRange = {
+    'scriptIndex': 0,
+    'startPos': 33,
+    'endPos': 82,
+    'compiled': true,
+    'coverage': {'hits': [48, 66, 76], 'misses': [54]}
+  };
+
+  // Full script
+  var params = { 'reports' : ['Coverage'],
+                 'scriptId' : func.location.script.id };
+  var coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, 6);
+  expect(coverage['ranges'][0], equals(expectedRange));
+  expect(coverage['scripts'].length, 1);
+  expect(coverage['scripts'][0]['uri'],
+         endsWith('get_source_report_test.dart'));
+  expect(allRangesCompiled(coverage), isFalse);
+
+  // Force compilation.
+  params = { 'reports' : ['Coverage'],
+             'scriptId' : func.location.script.id,
+             'forceCompile' : true };
+  coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, 6);
+  expect(allRangesCompiled(coverage), isTrue);
+
+  // One function
+  params = { 'reports' : ['Coverage'],
+             'scriptId' : func.location.script.id,
+             'tokenPos' : func.location.tokenPos,
+             'endTokenPos' : func.location.endTokenPos };
+  coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, 1);
+  expect(coverage['ranges'][0], equals(expectedRange));
+  expect(coverage['scripts'].length, 1);
+  expect(coverage['scripts'][0]['uri'],
+         endsWith('get_source_report_test.dart'));
+
+  // Full isolate
+  params = { 'reports' : ['Coverage'] };
+  coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, greaterThan(1));
+  expect(coverage['scripts'].length, greaterThan(1));
+
+  // Multiple reports (make sure enum list parameter parsing works).
+  params = { 'reports' : ['CallSites', 'Coverage'],
+             'scriptId' : func.location.script.id,
+             'tokenPos' : func.location.tokenPos,
+             'endTokenPos' : func.location.endTokenPos };
+  coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  expect(coverage['type'], equals('SourceReport'));
+  expect(coverage['ranges'].length, 1);
+  var range = coverage['ranges'][0];
+  expect(range.containsKey('callSites'), isTrue);
+  expect(range.containsKey('coverage'), isTrue);
+
+  // missing scriptId with tokenPos.
+  bool caughtException = false;
+  try {
+    params = { 'reports' : ['Coverage'],
+               'tokenPos' : func.location.tokenPos };
+    coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  } on ServerRpcException catch(e) {
+    caughtException = true;
+    expect(e.code, equals(ServerRpcException.kInvalidParams));
+    expect(e.message,
+           "_getSourceReport: the 'tokenPos' parameter requires the "
+           "\'scriptId\' parameter");
+  }
+  expect(caughtException, isTrue);
+
+  // missing scriptId with endTokenPos.
+  caughtException = false;
+  try {
+    params = { 'reports' : ['Coverage'],
+               'endTokenPos' : func.location.endTokenPos };
+    coverage = await isolate.invokeRpcNoUpgrade('_getSourceReport', params);
+  } on ServerRpcException catch(e) {
+    caughtException = true;
+    expect(e.code, equals(ServerRpcException.kInvalidParams));
+    expect(e.message,
+           "_getSourceReport: the 'endTokenPos' parameter requires the "
+           "\'scriptId\' parameter");
+  }
+  expect(caughtException, isTrue);
+},
+
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/get_stack_rpc_test.dart b/runtime/observatory/tests/service/get_stack_rpc_test.dart
index 2bf7c3a..7757819 100644
--- a/runtime/observatory/tests/service/get_stack_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_stack_rpc_test.dart
@@ -74,7 +74,7 @@
   for (var message in stack['messages']) {
     print('checking message $messageDepth');
     expect(message.index, equals(messageDepth++));
-    expect(message.size, greaterThanOrEqualTo(1));
+    expect(message.size, greaterThanOrEqualTo(0));
     expect(message.handler.type, equals('Function'));
     expect(message.location.type, equals('SourceLocation'));
     if (message.handler.name.contains('msgHandler')) {
diff --git a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
new file mode 100644
index 0000000..63277b7
--- /dev/null
+++ b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--error_on_bad_type --error_on_bad_override --complete_timeline
+
+import 'dart:developer';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+primeTimeline() {
+  Timeline.startSync('apple');
+  Timeline.instantSync('ISYNC', arguments: {'fruit': 'banana'});
+  Timeline.finishSync();
+  TimelineTask task = new TimelineTask();
+  task.start('TASK1');
+  task.instant('ITASK');
+  task.finish();
+}
+
+List<Map> filterForDartEvents(List<Map> events) {
+  return events.where((event) => event['cat'] == 'Dart').toList();
+}
+
+bool eventsContains(List<Map> events, String phase, String name) {
+  for (Map event in events) {
+    if ((event['ph'] == phase) && (event['name'] == name)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+int timeOrigin(List<Map> events) {
+  if (events.length == 0) {
+    return 0;
+  }
+  int smallest = events[0]['ts'];
+  for (var i = 0; i < events.length; i++) {
+    Map event = events[i];
+    if (event['ts'] < smallest) {
+      smallest = event['ts'];
+    }
+  }
+  return smallest;
+}
+
+int timeDuration(List<Map> events, int timeOrigin) {
+  if (events.length == 0) {
+    return 0;
+  }
+  int biggestDuration = events[0]['ts'] - timeOrigin;
+  for (var i = 0; i < events.length; i++) {
+    Map event = events[i];
+    int duration = event['ts'] - timeOrigin;
+    if (duration > biggestDuration) {
+      biggestDuration = duration;
+    }
+  }
+  return biggestDuration;
+}
+
+void allEventsHaveIsolateNumber(List<Map> events) {
+  for (Map event in events) {
+    if (event['ph'] == 'M') {
+      // Skip meta-data events.
+      continue;
+    }
+    if (event['name'] == 'Runnable' && event['ph'] == 'i') {
+      // Skip Runnable events which don't have an isolate.
+      continue;
+    }
+    if (event['cat'] == 'VM') {
+      // Skip VM category events which don't have an isolate.
+      continue;
+    }
+    if (event['cat'] == 'API') {
+      // Skip API category events which sometimes don't have an isolate.
+      continue;
+    }
+    Map arguments = event['args'];
+    expect(arguments, new isInstanceOf<Map>());
+    expect(arguments['isolateNumber'], new isInstanceOf<String>());
+  }
+}
+
+var tests = [
+  (VM vm) async {
+    Map result = await vm.invokeRpcNoUpgrade('_getVMTimeline', {});
+    expect(result['type'], equals('_Timeline'));
+    expect(result['traceEvents'], new isInstanceOf<List>());
+    final int numEvents = result['traceEvents'].length;
+    List<Map> dartEvents = filterForDartEvents(result['traceEvents']);
+    expect(dartEvents.length, equals(5));
+    allEventsHaveIsolateNumber(dartEvents);
+    allEventsHaveIsolateNumber(result['traceEvents']);
+    expect(eventsContains(dartEvents, 'I', 'ISYNC'), isTrue);
+    expect(eventsContains(dartEvents, 'X', 'apple'), isTrue);
+    expect(eventsContains(dartEvents, 'b', 'TASK1'), isTrue);
+    expect(eventsContains(dartEvents, 'e', 'TASK1'), isTrue);
+    expect(eventsContains(dartEvents, 'n', 'ITASK'), isTrue);
+    expect(eventsContains(dartEvents, 'q', 'ITASK'), isFalse);
+    // Calculate the time Window of Dart events.
+    int origin = timeOrigin(dartEvents);
+    int extent = timeDuration(dartEvents, origin);
+    // Query for the timeline with the time window for Dart events.
+    result = await vm.invokeRpcNoUpgrade('_getVMTimeline', {
+      'timeOriginMicros': origin,
+      'timeExtentMicros': extent
+    });
+    // Verify that we received fewer events than before.
+    expect(result['traceEvents'].length, lessThan(numEvents));
+    // Verify that we have the same number of Dart events.
+    List<Map> dartEvents2 = filterForDartEvents(result['traceEvents']);
+    expect(dartEvents2.length, dartEvents.length);
+  },
+];
+
+main(args) async => runVMTests(args, tests, testeeBefore: primeTimeline);
diff --git a/runtime/observatory/tests/service/implicit_getter_setter_test.dart b/runtime/observatory/tests/service/implicit_getter_setter_test.dart
new file mode 100644
index 0000000..dbf4487
--- /dev/null
+++ b/runtime/observatory/tests/service/implicit_getter_setter_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library implicit_getter_setter_test;
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+
+class A {
+  double field = 0.0;
+}
+
+script() {
+  for (int i = 0; i < 10; i++) {
+    new A();
+  }
+}
+
+testGetter(Isolate isolate) async {
+  Library rootLibrary = await isolate.rootLibrary.load();
+  expect(rootLibrary.classes.length, equals(1));
+  Class classA = await rootLibrary.classes[0].load();
+  expect(classA.name, equals('A'));
+  // Find getter.
+  ServiceFunction getterFunc;
+  for (ServiceFunction function in classA.functions) {
+    if (function.name == 'field') {
+      getterFunc = function;
+      break;
+    }
+  }
+  expect(getterFunc, isNotNull);
+  await getterFunc.load();
+  Field field = await getterFunc.field.load();
+  expect(field, isNotNull);
+  expect(field.name, equals('field'));
+  Class classDouble = await field.guardClass.load();
+  expect(classDouble.name, equals('_Double'));
+}
+
+
+testSetter(Isolate isolate) async {
+  Library rootLibrary = await isolate.rootLibrary.load();
+  expect(rootLibrary.classes.length, equals(1));
+  Class classA = await rootLibrary.classes[0].load();
+  expect(classA.name, equals('A'));
+  // Find setter.
+  ServiceFunction setterFunc;
+  for (ServiceFunction function in classA.functions) {
+    if (function.name == 'field=') {
+      setterFunc = function;
+      break;
+    }
+  }
+  expect(setterFunc, isNotNull);
+  await setterFunc.load();
+  Field field = await setterFunc.field.load();
+  expect(field, isNotNull);
+  expect(field.name, equals('field'));
+  Class classDouble = await field.guardClass.load();
+  expect(classDouble.name, equals('_Double'));
+}
+
+
+var tests = [testGetter, testSetter];
+
+main(args) => runIsolateTests(args, tests, testeeBefore: script);
diff --git a/runtime/observatory/tests/service/observatory_assets_test.dart b/runtime/observatory/tests/service/observatory_assets_test.dart
new file mode 100644
index 0000000..bd3befb
--- /dev/null
+++ b/runtime/observatory/tests/service/observatory_assets_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+var tests = [
+  (VM vm) async {
+    // Simple heartbeat test to ensure we can fetch Observatory resources.
+    var heartBeatUrl =
+        serviceHttpAddress + '/third_party/trace_viewer_full.html';
+    print('Trying to fetch $heartBeatUrl');
+    HttpClient client = new HttpClient();
+    HttpClientRequest request = await client.getUrl(Uri.parse(heartBeatUrl));
+    HttpClientResponse response = await request.close();
+    expect(response.statusCode, 200);
+    await response.drain();
+  }
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/reachable_size_test.dart b/runtime/observatory/tests/service/reachable_size_test.dart
new file mode 100644
index 0000000..5c346e3
--- /dev/null
+++ b/runtime/observatory/tests/service/reachable_size_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+
+class Pair {
+  var x, y;
+}
+
+var p1;
+var p2;
+
+buildGraph() {
+  p1 = new Pair();
+  p2 = new Pair();
+
+  // Adds to both reachable and retained size.
+  p1.x = new List();
+  p2.x = new List();
+
+  // Adds to reachable size only.
+  p1.y = p2.y = new List();
+}
+
+getReachableSize(ServiceObject obj) {
+  return obj.isolate.getReachableSize(obj).then((Instance obj) {
+    return int.parse(obj.valueAsString);
+  });
+}
+
+getRetainedSize(ServiceObject obj) {
+  return obj.isolate.getRetainedSize(obj).then((Instance obj) {
+    return int.parse(obj.valueAsString);
+  });
+}
+
+var tests = [
+(Isolate isolate) async {
+  Instance p1 = await rootLibraryFieldValue(isolate, "p1");
+  Instance p2 = await rootLibraryFieldValue(isolate, "p2");
+
+  // In general, shallow <= retained <= reachable. In this program,
+  // 0 < shallow < retained < reachable.
+
+  int p1_shallow = p1.size;
+  int p1_retained = await getRetainedSize(p1);
+  int p1_reachable = await getReachableSize(p1);
+
+  expect(0, lessThan(p1_shallow));
+  expect(p1_shallow, lessThan(p1_retained));
+  expect(p1_retained, lessThan(p1_reachable));
+
+  int p2_shallow = p2.size;
+  int p2_retained = await getRetainedSize(p2);
+  int p2_reachable = await getReachableSize(p2);
+
+  expect(0, lessThan(p2_shallow));
+  expect(p2_shallow, lessThan(p2_retained));
+  expect(p2_retained, lessThan(p2_reachable));
+
+  expect(p1_shallow, equals(p2_shallow));
+  expect(p1_retained, equals(p2_retained));
+  expect(p1_reachable, equals(p2_reachable));
+},
+];
+
+main(args) => runIsolateTests(args, tests, testeeBefore: buildGraph);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 1aeac65..7562cf4 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -2,7 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $compiler == none && $runtime == vm ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
 evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
 evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
 
@@ -15,8 +15,11 @@
 *: SkipByDesign
 
 # Tests with known analyzer issues
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 developer_extension_test: SkipByDesign
 
 [ $arch == arm ]
 process_service_test: Pass, Fail # Issue 24344
+
+[ ($noopt || $compiler == precompiler) ]
+*: Skip # Issue 24651
\ No newline at end of file
diff --git a/runtime/observatory/tests/service/tcp_socket_service_test.dart b/runtime/observatory/tests/service/tcp_socket_service_test.dart
index f8dff03..c80cad5 100644
--- a/runtime/observatory/tests/service/tcp_socket_service_test.dart
+++ b/runtime/observatory/tests/service/tcp_socket_service_test.dart
@@ -36,6 +36,9 @@
     //   The server socket accepting connections, on port X
     //   The accepted connection on the client, on port Y
     //   The client connection, on port X
+    if (result['data'].length != 5) {
+      print(result['data']);
+    }
     expect(result['data'].length, equals(5));
     // The first socket will have a name like listening:127.0.0.1:X
     // The second will have a name like 127.0.0.1:Y
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 6248b43..58de4e6 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -319,6 +319,17 @@
 }
 
 
+Future<Instance> rootLibraryFieldValue(Isolate isolate,
+                                       String fieldName) async {
+  Library rootLib = await isolate.rootLibrary.load();
+  Field field = rootLib.variables.singleWhere((v) => v.name == fieldName);
+  await field.load();
+  Instance value = field.staticValue;
+  await value.load();
+  return value;
+}
+
+
 /// Runs [tests] in sequence, each of which should take an [Isolate] and
 /// return a [Future]. Code for setting up state can run before and/or
 /// concurrently with the tests. Uses [mainArgs] to determine whether
diff --git a/runtime/observatory/tests/ui/inspector.dart b/runtime/observatory/tests/ui/inspector.dart
index fd6d0c3..c34f2d9 100644
--- a/runtime/observatory/tests/ui/inspector.dart
+++ b/runtime/observatory/tests/ui/inspector.dart
@@ -24,6 +24,10 @@
 class A <T> {}
 class B <S extends num> {}
 
+class S {}
+class M {}
+class MA extends S with M {}
+
 class Node {
   static var classField;
 
@@ -112,6 +116,10 @@
     return x;
   }
 
+  static staticMain() {
+    node.main();
+  }
+
   main() {
     print("Started main");
 
@@ -240,7 +248,7 @@
   Node.classField = 'Class field value';
   typed = new Typed();
   node = new Node();
-  node.main();
+  Node.staticMain();
 }
 
 class C {
diff --git a/runtime/observatory/web/third_party/README.md b/runtime/observatory/web/third_party/README.md
new file mode 100644
index 0000000..ba94574
--- /dev/null
+++ b/runtime/observatory/web/third_party/README.md
@@ -0,0 +1,4 @@
+This directory contains a vulcanized version of trace-viewer:
+
+https://github.com/catapult-project/catapult/wiki/Embedding-Trace-Viewer
+
diff --git a/runtime/observatory/web/third_party/trace_viewer_full.html b/runtime/observatory/web/third_party/trace_viewer_full.html
new file mode 100644
index 0000000..930312b
--- /dev/null
+++ b/runtime/observatory/web/third_party/trace_viewer_full.html
@@ -0,0 +1,7113 @@
+<!DOCTYPE html>
+<html>
+  <head i18n-values="dir:textdirection;">
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+<template id="overlay-template">
+  <style>
+    overlay-mask {
+      left: 0;
+      padding: 8px;
+      position: absolute;
+      top: 0;
+      z-index: 1000;
+      font-family: sans-serif;
+      -webkit-justify-content: center;
+      background: rgba(0, 0, 0, 0.8);
+      display: -webkit-flex;
+      height: 100%;
+      left: 0;
+      position: fixed;
+      top: 0;
+      width: 100%;
+    }
+    overlay-mask:focus {
+      outline: none;
+    }
+    overlay-vertical-centering-container {
+      -webkit-justify-content: center;
+      -webkit-flex-direction: column;
+      display: -webkit-flex;
+    }
+    overlay-frame {
+      z-index: 1100;
+      background: rgb(255, 255, 255);
+      border: 1px solid #ccc;
+      margin: 75px;
+      display: -webkit-flex;
+      -webkit-flex-direction: column;
+      min-height: 0;
+    }
+    title-bar {
+      -webkit-align-items: center;
+      -webkit-flex-direction: row;
+      border-bottom: 1px solid #ccc;
+      background-color: #ddd;
+      display: -webkit-flex;
+      padding: 5px;
+      -webkit-flex: 0 0 auto;
+    }
+    title {
+      display: inline;
+      font-weight: bold;
+      -webkit-box-flex: 1;
+      -webkit-flex: 1 1 auto;
+    }
+    close-button {
+      -webkit-align-self: flex-end;
+      border: 1px solid #eee;
+      background-color: #999;
+      font-size: 10pt;
+      font-weight: bold;
+      padding: 2px;
+      text-align: center;
+      width: 16px;
+    }
+    close-button:hover {
+      background-color: #ddd;
+      border-color: black;
+      cursor: pointer;
+    }
+    overlay-content {
+      display: -webkit-flex;
+      -webkit-flex: 1 1 auto;
+      -webkit-flex-direction: column;
+      overflow-y: auto;
+      padding: 10px;
+      min-width: 300px;
+      min-height: 0;
+    }
+    button-bar {
+      -webkit-align-items: baseline;
+      border-top: 1px solid #ccc;
+      display: -webkit-flex;
+      -webkit-flex: 0 0 auto;
+      -webkit-flex-direction: row-reverse;
+      padding: 4px;
+    }
+  </style>
+
+  <overlay-mask>
+    <overlay-vertical-centering-container>
+      <overlay-frame>
+        <title-bar>
+          <title></title>
+          <close-button>✕</close-button>
+        </title-bar>
+        <overlay-content>
+          <content></content>
+        </overlay-content>
+        <button-bar></button-bar>
+      </overlay-frame>
+    </overlay-vertical-centering-container>
+  </overlay-mask>
+</template><polymer-element constructor="TracingAnalysisTabView" name="tr-ui-a-tab-view">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-flow: column nowrap;
+        overflow: hidden;
+        box-sizing: border-box;
+      }
+
+      tab-strip[tabs-hidden] {
+        display: none;
+      }
+
+      tab-strip {
+        background-color: rgb(236, 236, 236);
+        border-bottom: 1px solid #8e8e8e;
+        display: flex;
+        flex: 0 0 auto;
+        flex-flow: row;
+        overflow-x: auto;
+        padding: 0 10px 0 10px;
+        font-size: 12px;
+      }
+
+      tab-button {
+        display: block;
+        flex: 0 0 auto;
+        padding: 4px 15px 1px 15px;
+        margin-top: 2px;
+      }
+
+      tab-button[selected=true] {
+        background-color: white;
+        border: 1px solid rgb(163, 163, 163);
+        border-bottom: none;
+        padding: 3px 14px 1px 14px;
+      }
+
+      tabs-content-container {
+        display: flex;
+        flex: 1 1 auto;
+        overflow: auto;
+        width: 100%;
+      }
+
+      ::content > * {
+        flex: 1 1 auto;
+      }
+
+      ::content > *:not([selected]) {
+        display: none;
+      }
+
+      button-label {
+        display: inline;
+      }
+
+      tab-strip-heading {
+        display: block;
+        flex: 0 0 auto;
+        padding: 4px 15px 1px 15px;
+        margin-top: 2px;
+        margin-before: 20px;
+        margin-after: 10px;
+      }
+      #tsh {
+        display: inline;
+        font-weight: bold;
+      }
+    </style>
+
+    <tab-strip>
+      <tab-strip-heading id="tshh">
+        <span id="tsh"></span>
+      </tab-strip-heading>
+      <template repeat="{{tab in tabs_}}">
+        <tab-button button-id="{{ tab.id }}" on-click="{{ tabButtonSelectHandler_ }}" selected="{{ selectedTab_.id === tab.id }}">
+          <button-label>{{ tab.label ? tab.label : 'No Label'}}</button-label>
+        </tab-button>
+      </template>
+    </tab-strip>
+
+    <tabs-content-container id="content-container">
+        <content></content>
+    </tabs-content-container>
+
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-a-sub-view">
+  
+</polymer-element><style>
+* /deep/ .labeled-checkbox {
+  display: flex;
+  white-space: nowrap;
+}
+</style><polymer-element is="a" name="tr-ui-a-analysis-link" on-click="{{onClicked_}}" on-mouseenter="{{onMouseEnter_}}" on-mouseleave="{{onMouseLeave_}}">
+  <template>
+    <style>
+    :host {
+      display: inline;
+      color: -webkit-link;
+      cursor: pointer;
+      text-decoration: underline;
+      cursor: pointer;
+    }
+    </style>
+    <content></content>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-b-table">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      table {
+        font-size: 12px;
+
+        flex: 1 1 auto;
+        align-self: stretch;
+        border-collapse: separate;
+        border-spacing: 0;
+        border-width: 0;
+        -webkit-user-select: initial;
+      }
+
+      tr > td {
+        padding: 2px 4px 2px 4px;
+        vertical-align: text-top;
+      }
+
+      tr:focus,
+      td:focus {
+        outline: 1px dotted rgba(0,0,0,0.1);
+        outline-offset: 0;
+      }
+
+      button.toggle-button {
+        height: 15px;
+        line-height: 60%;
+        vertical-align: middle;
+        width: 100%;
+      }
+
+      button > * {
+        height: 15px;
+        vertical-align: middle;
+      }
+
+      td.button-column {
+        width: 30px;
+      }
+
+      table > thead > tr > td.sensitive:hover {
+        background-color: #fcfcfc;
+      }
+
+      table > thead > tr > td {
+        font-weight: bold;
+        text-align: left;
+
+        background-color: #eee;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+
+        border-top: 1px solid #ffffff;
+        border-bottom: 1px solid #aaa;
+      }
+
+      table > tfoot {
+        background-color: #eee;
+        font-weight: bold;
+      }
+
+      /* Light row and cell highlight. */
+      table > tbody[row-highlight-style="light"] > tr[selected],
+      table > tbody[cell-highlight-style="light"] > tr > td[selected] {
+        background-color: rgb(213, 236, 229);  /* light turquoise */
+      }
+      table > tbody[row-highlight-style="light"] >
+          tr:not(.empty-row):not([selected]):hover,
+      table > tbody[cell-highlight-style="light"] >
+          tr:not(.empty-row):not([selected]) > td:hover {
+        background-color: #f6f6f6;  /* light grey */
+      }
+
+      /* Dark row and cell highlight. */
+      table > tbody[row-highlight-style="dark"] > tr[selected],
+      table > tbody[cell-highlight-style="dark"] > tr > td[selected] {
+        background-color: rgb(103, 199, 165);  /* turquoise */
+      }
+      table > tbody[row-highlight-style="dark"] >
+          tr:not(.empty-row):not([selected]):hover,
+      table > tbody[cell-highlight-style="dark"] >
+          tr:not(.empty-row):not([selected]) > td:hover {
+        background-color: #e6e6e6;  /* grey */
+      }
+      table > tbody[row-highlight-style="dark"] > tr:hover[selected],
+      table > tbody[cell-highlight-style="dark"] > tr[selected] > td:hover {
+        background-color: rgb(171, 217, 202);  /* semi-light turquoise */
+      }
+
+      table > tbody > tr.empty-row > td {
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      table > tbody.has-footer > tr:last-child > td {
+        border-bottom: 1px solid #aaa;
+      }
+
+      table > tfoot > tr:first-child > td {
+        border-top: 1px solid #ffffff;
+      }
+
+      expand-button {
+        -webkit-user-select: none;
+        display: inline-block;
+        cursor: pointer;
+        font-size: 9px;
+        min-width: 8px;
+        max-width: 8px;
+      }
+
+      .button-expanded {
+        transform: rotate(90deg);
+      }
+    </style>
+    <table>
+      <thead id="head">
+      </thead>
+      <tbody id="body">
+      </tbody>
+      <tfoot id="foot">
+      </tfoot>
+    </table>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-b-table-header-cell" on-tap="onTap_">
+  <template>
+  <style>
+    :host {
+      -webkit-user-select: none;
+      display: flex;
+    }
+
+    span {
+      flex: 0 1 auto;
+    }
+
+    side-element {
+      -webkit-user-select: none;
+      flex: 1 0 auto;
+      padding-left: 4px;
+      vertical-align: top;
+      font-size: 15px;
+      font-family: sans-serif;
+      display: inline;
+      line-height: 85%;
+    }
+  </style>
+
+    <span id="title"></span><side-element id="side"></side-element>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-u-scalar-span">
+  <template>
+    <style>
+    :host {
+      display: block;
+      position: relative;
+    }
+    #content.right-align {
+      text-align: right;
+      position: relative;
+      display: block;
+    }
+    #sparkline {
+      width: 0%;
+      position: absolute;
+      bottom: 0;
+      right: 0;
+      display: none;
+      height: 100%;
+      background-color: hsla(216, 100%, 94.5%, .75);
+      border-left: 1px solid hsl(216, 100%, 89%);
+      box-sizing: border-box;
+    }
+    #warning {
+      margin-left: 4px;
+      font-size: 66%;
+    }
+    </style>
+    <span id="sparkline"></span>
+    <span id="content"></span>
+    <span id="warning" style="display:none">⚠</span>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-u-scalar-span" name="tr-ui-u-time-duration-span">
+  
+</polymer-element><polymer-element extends="tr-ui-u-scalar-span" name="tr-ui-u-time-stamp-span">
+  
+</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-a-generic-object-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+      font-family: monospace;
+    }
+    </style>
+    <div id="content">
+    </div>
+  </template>
+
+  
+</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-a-generic-object-view-with-label">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-a-stack-frame">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-related-events">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #events {
+      display: flex;
+      flex-direction: column;
+    }
+
+    </style>
+    <tr-ui-a-single-event-sub-view id="content"></tr-ui-a-single-event-sub-view>
+    <div id="events">
+      <tr-ui-a-related-events id="relatedEvents">
+      </tr-ui-a-related-events>
+    </div>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-a-selection-summary-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+    
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-multi-event-summary-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+    
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-a-multi-event-details-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+
+    #titletable {
+      font-weight: bold;
+    }
+
+    #title-info {
+      font-size: 12px;
+    }
+    </style>
+    <tr-ui-b-table id="titletable">
+    </tr-ui-b-table>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      overflow: auto;
+    }
+    #content {
+      display: flex;
+      flex-direction: column;
+      flex: 0 1 auto;
+      align-self: stretch;
+    }
+    #content > * {
+      flex: 0 0 auto;
+      align-self: stretch;
+    }
+    tr-ui-a-multi-event-summary-table {
+      border-bottom: 1px solid #aaa;
+    }
+
+    tr-ui-a-selection-summary-table  {
+      margin-top: 1.25em;
+      border-top: 1px solid #aaa;
+      background-color: #eee;
+      font-weight: bold;
+      margin-bottom: 1.25em;
+      border-bottom: 1px solid #aaa;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      display: flex;
+      flex: 1 1 auto;
+    }
+    #content > tr-ui-a-related-events {
+      margin-left: 8px;
+      flex: 0 1 200px;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-single-event-sub-view" name="tr-ui-a-single-async-slice-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-async-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-cpu-slice-sub-view">
+  <template>
+    <style>
+    table {
+      border-collapse: collapse;
+      border-width: 0;
+      margin-bottom: 25px;
+      width: 100%;
+    }
+
+    table tr > td:first-child {
+      padding-left: 2px;
+    }
+
+    table tr > td {
+      padding: 2px 4px 2px 4px;
+      vertical-align: text-top;
+      width: 150px;
+    }
+
+    table td td {
+      padding: 0 0 0 0;
+      width: auto;
+    }
+    tr {
+      vertical-align: top;
+    }
+
+    tr:nth-child(2n+0) {
+      background-color: #e2e2e2;
+    }
+    </style>
+    <table>
+      <tbody><tr>
+        <td>Running process:</td><td id="process-name"></td>
+      </tr>
+      <tr>
+        <td>Running thread:</td><td id="thread-name"></td>
+      </tr>
+      <tr>
+        <td>Start:</td>
+        <td>
+          <tr-ui-u-time-stamp-span id="start">
+          </tr-ui-u-time-stamp-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Duration:</td>
+        <td>
+          <tr-ui-u-time-duration-span id="duration">
+          </tr-ui-u-time-duration-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Active slices:</td><td id="running-thread"></td>
+      </tr>
+      <tr>
+        <td>Args:</td>
+        <td>
+          <tr-ui-a-generic-object-view id="args">
+          </tr-ui-a-generic-object-view>
+        </td>
+      </tr>
+    </tbody></table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-cpu-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      flex: 1 1 auto;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-thread-time-slice-sub-view">
+  <template>
+    <style>
+    table {
+      border-collapse: collapse;
+      border-width: 0;
+      margin-bottom: 25px;
+      width: 100%;
+    }
+
+    table tr > td:first-child {
+      padding-left: 2px;
+    }
+
+    table tr > td {
+      padding: 2px 4px 2px 4px;
+      vertical-align: text-top;
+      width: 150px;
+    }
+
+    table td td {
+      padding: 0 0 0 0;
+      width: auto;
+    }
+    tr {
+      vertical-align: top;
+    }
+
+    tr:nth-child(2n+0) {
+      background-color: #e2e2e2;
+    }
+    </style>
+    <table>
+      <tbody><tr>
+        <td>Running process:</td><td id="process-name"></td>
+      </tr>
+      <tr>
+        <td>Running thread:</td><td id="thread-name"></td>
+      </tr>
+      <tr>
+        <td>State:</td>
+        <td><b><span id="state"></span></b></td>
+      </tr>
+      <tr>
+        <td>Start:</td>
+        <td>
+          <tr-ui-u-time-stamp-span id="start">
+          </tr-ui-u-time-stamp-span>
+        </td>
+      </tr>
+      <tr>
+        <td>Duration:</td>
+        <td>
+          <tr-ui-u-time-duration-span id="duration">
+          </tr-ui-u-time-duration-span>
+        </td>
+      </tr>
+
+      <tr>
+        <td>On CPU:</td><td id="on-cpu"></td>
+      </tr>
+
+      <tr>
+        <td>Running instead:</td><td id="running-instead"></td>
+      </tr>
+
+      <tr>
+        <td>Args:</td><td id="args"></td>
+      </tr>
+    </tbody></table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-thread-time-slice-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    #content {
+      flex: 1 1 auto;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-instant-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-instant-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-counter-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-single-event-sub-view" name="tr-ui-a-single-flow-event-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-flow-event-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-a-multi-event-sub-view id="content"></tr-ui-a-multi-event-sub-view>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-instance-sub-view">
+  <template>
+    <style>
+    :host {
+      display: block;
+    }
+
+    #snapshots > * {
+      display: block;
+    }
+
+    :host {
+      overflow: auto;
+      display: block;
+    }
+
+    * {
+      -webkit-user-select: text;
+    }
+
+    .title {
+      border-bottom: 1px solid rgb(128, 128, 128);
+      font-size: 110%;
+      font-weight: bold;
+    }
+
+    td, th {
+      font-family: monospace;
+      vertical-align: top;
+    }
+    </style>
+    <div id="content"></div>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-object-snapshot-sub-view">
+  <template>
+    <style>
+    #args {
+      white-space: pre;
+    }
+
+    :host {
+      overflow: auto;
+      display: flex;
+    }
+
+    ::content * {
+      -webkit-user-select: text;
+    }
+
+    ::content .title {
+      border-bottom: 1px solid rgb(128, 128, 128);
+      font-size: 110%;
+      font-weight: bold;
+    }
+
+    ::content td, th {
+      font-family: monospace;
+      vertical-align: top;
+    }
+    </style>
+    <content></content>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-object-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-sample-sub-view">
+  <template>
+    <style>
+    :host { display: block; }
+    #control {
+      background-color: #e6e6e6;
+      background-image: -webkit-gradient(linear, 0 0, 0 100%,
+                                         from(#E5E5E5), to(#D1D1D1));
+      flex: 0 0 auto;
+      overflow-x: auto;
+    }
+    #control::-webkit-scrollbar { height: 0px; }
+    #control {
+      font-size: 12px;
+      display: flex;
+      flex-direction: row;
+      align-items: stretch;
+      margin: 1px;
+      margin-right: 2px;
+    }
+    </style>
+    <div id="control">
+      Sample View Option
+      <select id="view_selector">
+        <option value="TOPDOWNVIEW">Tree (Top Down)</option>
+        <option value="BOTTOMUPVIEW">Heavy (Bottom Up)</option>
+      </select>
+    </div>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-interaction-record-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-interaction-record-sub-view">
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-alert-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table">
+    </tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-frame-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #asv {
+      flex: 0 0 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-a-alert-sub-view id="asv">
+    </tr-ui-a-alert-sub-view>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-frame-sub-view">
+  
+</polymer-element><polymer-element name="tr-ui-a-stacked-pane">
+  
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-heap-details-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #header {
+        flex: 0 0 auto;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+      }
+
+      #label {
+        flex: 1 1 auto;
+        padding: 8px;
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #view_mode_container {
+        display: none;
+        flex: 0 0 auto;
+        padding: 5px;
+        font-size: 15px;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory allocator dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+      }
+    </style>
+    <div id="header">
+      <div id="label">Heap details</div>
+      <div id="view_mode_container">
+        <span>View mode:</span>
+        
+      </div>
+    </div>
+    <div id="contents">
+      <div id="info_text">No heap dump selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-allocator-details-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #label {
+        flex: 0 0 auto;
+        padding: 8px;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory allocator dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+      }
+    </style>
+    <div id="label">Component details</div>
+    <div id="contents">
+      <div id="info_text">No memory allocator dump selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-vm-regions-details-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #label {
+        flex: 0 0 auto;
+        padding: 8px;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+      }
+    </style>
+    <div id="label">Memory maps</div>
+    <div id="contents">
+      <div id="info_text">No memory maps selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-b-color-legend">
+  <template>
+    <style>
+    :host {
+      display: inline-block;
+    }
+
+    #square {
+      font-size: 150%;  /* Make the square bigger. */
+      line-height: 0%;  /* Prevent the square from increasing legend height. */
+    }
+    </style>
+    <span id="square"></span>
+    <span id="label"></span>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-b-view-specific-brushing-state">
+  
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-overview-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: column;
+      }
+
+      #label {
+        flex: 0 0 auto;
+        padding: 8px;
+
+        background-color: #eee;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+
+        font-size:  15px;
+        font-weight: bold;
+      }
+
+      #contents {
+        flex: 1 0 auto;
+        align-self: stretch;
+        font-size: 12px;
+      }
+
+      #info_text {
+        padding: 8px;
+        color: #666;
+        font-style: italic;
+        text-align: center;
+      }
+
+      #table {
+        display: none;  /* Hide until memory dumps are set. */
+        flex: 1 0 auto;
+        align-self: stretch;
+      }
+    </style>
+    <tr-ui-b-view-specific-brushing-state id="state" view-id="analysis.memory_dump_overview_pane">
+    </tr-ui-b-view-specific-brushing-state>
+    <div id="label">Overview</div>
+    <div id="contents">
+      <div id="info_text">No memory memory dumps selected</div>
+      <tr-ui-b-table id="table"></tr-ui-b-table>
+    </div>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-stacked-pane" name="tr-ui-a-memory-dump-header-pane">
+  <template>
+    <style>
+      :host {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+
+        background-color: #d0d0d0;
+        border-bottom: 1px solid #8e8e8e;
+        border-top: 1px solid white;
+      }
+
+      #label {
+        flex: 1 1 auto;
+        padding: 6px;
+        font-size: 15px;
+      }
+
+      #aggregation_mode_container {
+        display: none;
+        flex: 0 0 auto;
+        padding: 5px;
+        font-size: 15px;
+      }
+    </style>
+    
+    <div id="label"></div>
+    <div id="aggregation_mode_container">
+      <span>Metric aggregation:</span>
+      
+    </div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-stacked-pane-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+
+    #pane_container > * {
+      flex: 0 0 auto;
+    }
+    </style>
+    <div id="pane_container">
+    </div>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-container-memory-dump-sub-view">
+  <template>
+    <div id="content"></div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-power-sample-table">
+  <template>
+    <style>
+    :host {
+      display: flex;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-single-power-sample-sub-view">
+  <template>
+    <style>
+    :host { display: block; }
+    </style>
+    <tr-ui-a-power-sample-table id="samplesTable">
+    </tr-ui-a-power-sample-table>
+  </template>
+
+  
+</polymer-element><style>
+  * /deep/ .chart-base #title {
+    font-size: 16pt;
+  }
+
+  * /deep/ .chart-base {
+    font-size: 12pt;
+    -webkit-user-select: none;
+    cursor: default;
+  }
+
+  * /deep/ .chart-base .axis path,
+  * /deep/ .chart-base .axis line {
+    fill: none;
+    shape-rendering: crispEdges;
+    stroke: #000;
+  }
+</style><template id="chart-base-template">
+  <svg> 
+    <g id="chart-area" xmlns="http://www.w3.org/2000/svg">
+      <g class="x axis"></g>
+      <g class="y axis"></g>
+      <text id="title"></text>
+    </g>
+  </svg>
+</template><style>
+  * /deep/ .chart-base-2d.updating-brushing-state #brushes > * {
+    fill: rgb(103, 199, 165)
+  }
+
+  * /deep/ .chart-base-2d #brushes {
+    fill: rgb(213, 236, 229)
+  }
+</style><style>
+* /deep/ .line-chart .line{fill:none;stroke-width:1.5px}* /deep/ .line-chart #brushes>rect{fill:rgb(192,192,192)}
+</style><polymer-element name="tr-ui-a-frame-power-usage-chart">
+  <template>
+    <div id="content"></div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-power-sample-summary-table">
+  <template>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-a-sub-view" name="tr-ui-a-multi-power-sample-sub-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: row;
+    }
+    #tables {
+      display: flex;
+      flex-direction: column;
+      width: 50%;
+    }
+    #chart {
+      width: 50%;
+    }
+    </style>
+    <div id="tables">
+      <tr-ui-a-power-sample-summary-table id="summaryTable">
+      </tr-ui-a-power-sample-summary-table>
+      <tr-ui-a-power-sample-table id="samplesTable">
+      </tr-ui-a-power-sample-table>
+    </div>
+    <tr-ui-a-frame-power-usage-chart id="chart">
+    </tr-ui-a-frame-power-usage-chart>
+  </template>
+</polymer-element><polymer-element name="tr-ui-a-analysis-view">
+  <template>
+    <style>
+      :host {
+        background-color: white;
+        display: flex;
+        flex-direction: column;
+        height: 275px;
+        overflow: auto;
+      }
+
+      :host(.tall-mode) {
+        height: 525px;
+      }
+
+      ::content > * {
+        flex: 1 0 auto;
+      }
+    </style>
+    <content></content>
+  </template>
+  
+</polymer-element><style>
+* /deep/ x-drag-handle{-webkit-user-select:none;box-sizing:border-box;display:block}* /deep/ x-drag-handle.horizontal-drag-handle{background-image:-webkit-gradient(linear,0 0,0 100%,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;cursor:ns-resize;height:7px;position:relative;z-index:10}* /deep/ x-drag-handle.vertical-drag-handle{background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-left:1px solid white;border-right:1px solid #8e8e8e;cursor:ew-resize;position:relative;width:7px;z-index:10}
+</style><polymer-element name="tr-ui-b-dropdown">
+  <template>
+    <style>
+    :host {
+      position: relative;
+      display: flex;
+    }
+    #outer {
+      display: flex;
+      flex: 0 0 auto;
+      padding: 1px 4px 1px 4px;
+      -webkit-user-select: none;
+      cursor: default;
+    }
+
+    #state {
+      display: flex;
+      flex: 0 0 auto;
+      margin-left: 2px;
+      margin-right: 0px;
+      flex: 0 0 auto;
+    }
+
+    #icon {
+      display: flex;
+      flex: 0 0 auto;
+      flex: 0 0 auto;
+    }
+    dialog {
+      position: absolute;
+      padding: 0;
+      border: 0;
+      margin: 0;
+    }
+    dialog::backdrop {
+      background: rgba(0,0,0,.05);
+    }
+
+    #dialog-frame {
+      background-color: #fff;
+      display: flex;
+      flex-direction: column;
+      flex: 1 1 auto;
+      padding: 6px;
+      border: 1px solid black;
+      -webkit-user-select: none;
+      cursor: default;
+    }
+    </style>
+    <tr-ui-b-toolbar-button id="outer" on-click="{{ onOuterClick_ }}" on-keydown="{{ onOuterKeyDown_ }}">
+      <div id="icon">⚙</div>
+      <div id="state">▾</div>
+    </tr-ui-b-toolbar-button>
+    <dialog id="dialog" on-cancel="{{ onDialogCancel_ }}" on-click="{{ onDialogClick_ }}">
+      <div id="dialog-frame">
+        <content></content>
+      </div>
+    </dialog>
+  </template>
+  
+</polymer-element><polymer-element name="tv-ui-b-hotkey-controller">
+  
+</polymer-element><polymer-element is="HTMLDivElement" name="tr-ui-b-info-bar">
+  <template>
+    <style>
+    :host {
+      align-items: center;
+      flex: 0 0 auto;
+      background-color: rgb(252, 235, 162);
+      border-bottom: 1px solid #A3A3A3;
+      border-left: 1px solid white;
+      border-right: 1px solid #A3A3A3;
+      border-top: 1px solid white;
+      display: flex;
+      height: 26px;
+      padding: 0 3px 0 3px;
+    }
+
+    :host(.info-bar-hidden) {
+      display: none;
+    }
+
+    #message { flex: 1 1 auto; }
+    </style>
+
+    <span id="message"></span>
+    <span id="buttons"></span>
+  </template>
+
+  
+</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-b-info-bar-group">
+  <template>
+    <style>
+    :host {
+      flex: 0 0 auto;
+      flex-direction: column;
+      display: flex;
+    }
+    </style>
+    <div id="messages"></div>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-b-toolbar-button" noscript="">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      background-color: #f8f8f8;
+      border: 1px solid rgba(0, 0, 0, 0.5);
+      color: rgba(0,0,0,0.8);
+      justify-content: center;
+      align-self: stretch;
+      min-width: 23px;
+    }
+
+    :host(:hover) {
+      background-color: rgba(255, 255, 255, 1.0);
+      border-color: rgba(0, 0, 0, 0.8);
+      box-shadow: 0 0 .05em rgba(0, 0, 0, 0.4);
+      color: rgba(0, 0, 0, 1);
+    }
+
+    #aligner {
+      display: flex;
+      flex: 0 0 auto;
+      align-self: center;
+    }
+    </style>
+    <div id="aligner">
+      <content></content>
+    </div>
+  </template>
+</polymer-element><polymer-element name="tr-ui-b-mouse-mode-icon">
+  <template>
+    <style>
+    :host {
+      display: block;
+      background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=);
+      width: 27px;
+      height: 30px;
+    }
+    :host.active {
+      cursor: auto;
+    }
+    </style>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-b-mouse-mode-selector">
+  <template>
+    <style>
+    :host {
+
+      -webkit-user-drag: element;
+      -webkit-user-select: none;
+
+      background: #DDD;
+      border: 1px solid #BBB;
+      border-radius: 4px;
+      box-shadow: 0 1px 2px rgba(0,0,0,0.2);
+      left: calc(100% - 120px);
+      position: absolute;
+      top: 100px;
+      user-select: none;
+      width: 29px;
+      z-index: 20;
+    }
+
+    .drag-handle {
+      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAChCAYAAACbBNzvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABV0RVh0Q3JlYXRpb24gVGltZQA3LzE2LzEzRNEKUwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAA9aSURBVHic7V1rTFvl//+UrgUmZWMpbLa6cLErwpYxkqLGkjAG88WSbmumGUllvlmAJctMRtybvlHrLXiJUekMIZuYSCL5gS+EuLIXGEGjqCsllCEW6xQECgzWG7S05/+C/zkp9LTn0gsL6ych9JzznOdzPj19Luf5PN/nCN59913ixRdfRFdXFxLx/2GDgCAIYmpqCoWFhUjE/4cNae+99x4AIFH/Hzak7nDqDu+wOyyw2WzEdl9EMpG23ReQbKQE73Q8coJ3bfcFWK1W/Pbbb/D7/UhLi/37DwaDEIvFKC8vR0lJSdjxbRVstVoxPDyMxx9/HAUFBcjMzIRAIOCdXzAYhNvtht1ux/DwMACEid5WwSMjI3jyySdRXFwMsVgMoVAYk2CCIJCZmYns7GyMjo5iZGQkPoKXl5exd+9e3hdGIhgMIj8/H5mZmRCJRIyCyQ5NJBAEgUAgAKFQiIKCAiwsLISl4VxoHA4H+vv74Xa7uZ4aBqFQiOzsbIhEIojFYojFYohEItq/8fFxXLlyBUtLSxHThOaxZ88eCIXC2AWPj48DAH799deYBaelpUEoFLL6++qrrwAAH3zwAav0YrGYthLkJHh6ehpzc3MAgPn5eUxPT8csWiAQMJbboaEhmM1mAIDFYsHQ0BDvPDkJtlgsYdt+v59LFrxw/fr1sG2Xy8UrL06C6+vrw7bFYjEvYi747rvvwrYlEgmvvDjV0g6HI+p2ohBP3qh32OFwoLe3l1VGvb29sNvtvC8kFCMjI9DpdKzS6nQ6mEwm1nnTPg/7/X6MjY1hcnKS/VX+P/bu3YuysjLk5uYypv36669x8uRJZGRkQCQSwev1oqOjAz09PZx5CwsLcenSJRw+fBh+vx+rq6swmUx46aWXNqWjvcMDAwO8xAIbnZKBgQFeNXhzczMvscBGp6S5uRk//vhj1HS0grVaLYqLi3kRy+Vy1NXVRe0RRcKNGzeg0Wh48apUKnR1daG6ujpqOtpKy+VyQa1Wo6SkBLdv38aFCxeoY5988gn1+fLly9TnL774ApWVlXjiiSfgdDqxtrbG+aJ9Ph/0ej3OnDkDvV6PW7duUceOHDlCfR4dHaU+v/DCC7h27RrUajWcTidWV1ejctAKJggCKysryMzMhE6nw+zsLO3Joft1Oh0ePHiApaUlduqi8BYVFaGvr48Vb19fHyfeqM2Sz+dj3QTEs4lKJC+njsfWJoptkxUrtjZRbJssOnASXFtbG3U7UXjrrbeibnMBJ8FZWVkoKysDABQUFCArK4s3MRcoFArqrlZXV0OhUPDOi5Ngn8+Hw4cPQyqV4tlnn4XP5+NNTIIgmH0An8+HV155BUqlEq+++ior3kAgQLuf84jH2toajh8/jvX1da6n0sLj8SAjI4MxHUEQ+PTTT1nlSRAEHjx4QHtsW8e0RCIR7HY79uzZE/GOcEUgEEAgEMDff/8NkUgUdnxbBR85cgRmsxkCgQD5+fkRh2XYIhAI4P79+5iamoLD4cCxY8fC0myr4KeeegoCgQBWqxVzc3NIS0uLedQyGAxi165dKC8vR1FRUVialHu405ESvNPxyAlOuYfJRMo9fFjdw3iBq3vIBDbu4bYK3uoextKtJEH2yWNyD8nyEG8wuYcffvgha3cxru6h3W5Hf39/QoyzaE6fyWRCQ0MDZ+MsLu7h8vIyent7sby8zIk8VkxNTUGn08Fms8UlP04Nn9/vR39/f9w8JLZwu91obGzk5CFFAq+Wfnh4mDKok4mWlha0trbGlAfvrs3k5CQGBgaSYoiHoqenB1evXk2OIb4VDocDJpMp6eXaYrGgsbGRV7mOufPq8XgwMDCQ9HI9NzeHq1evci7XvDseUqkUWq0W6enpCAaDcDqd8Hq9fLNjDaVSiRs3bkAikfDi5XSHxWIxampqAAALCwsYGhrC7Ows5ufnEypWIpHAYDAAACYmJnD9+nXevJwEnzp1CjKZDBUVFQCAsbGxpJTfjz76CFVVVWhqagIAdHR08G6XWQuuqanB7t274fV6UVpaiuzsbAAbTzyJhMFggEKhgNfrRX19PWQyGQDAaDTyyo+V4JqaGshkMsricLlcOH78OICNCWp8p0cwwWAwoKqqahPvG2+8AWDji+7u7uacJyvBMpksrKxkZWVR0yLGxsY4E7NBVVVVGK9CoaCmRXR0dHDOk5VguorB5/OhoqICYrE4YZ2PSLxXrlyBRCLhNcE1pufh1dVVXLx4EWlpaRGnJzCBjXtId87g4GBU3ri5h1uJ5+fnY8mCtXvIhTflHoYg5R4mEyn3MAl45KyWlOCdjkdOcMo9TCZS7mHKPeSGhLmH5LBOrAGXXN1DcliHrgdFgsk95CzYbrfDbDbD7/ejrKwstpmtNO5hJJhMJrS2tsLtdqOpqQlarTZi2mjuIWvBfr8fZrN50/iz2WzG9PQ0nn/+edonEzZgij10uVwwGo2bxp+NRiOGhobw+uuv005hjtk9JENz6AbbyWCuRESp2Ww2NDc30w62WywW6HQ6zoOIrO5wbm4uzp8/j5WVFXR2dm46VldXh3379mF5eTku86dDUVxcjK6uLthstrClqrq6unDo0CHOvKwE+/1+LC4uUqG0oZiYmIhaicQCkvfu3bthxwYGBnhVmpy6NnSD7kxxQvEA3Zo+fIsQJ8F040j379/nRcwFdF4037FwToLphkUXFxd5EXMB3chkUgQ7nc6wfT6fL+Gm+H///Re2z+Vy8TLFGSut/v5+RsPsm2++AbDR84pXLFNDQwPjelxnz54FsBFK+/nnn7PKl/EOa7VaVmHvYrE4au+HK27evMkq7F0ikeDmzZus82UU7HK5qG8yGs6ePct73gUdfD4f2tvbGdO1t7dzaocZBRMEAaFQSBnhdKipqYFQKORlm0TjzcvLo4xwOhgMBuTl5XHiZVVp+f1+yGQy2iDq4uJiyGSyhFRcfr8fVVVVtEHUGo0GVVVVnHlZ19JerxdqtRpSqZTaJ5VKoVarEzrdwev1Qq/XQ6lUUvuUSiX0ej0vXk7N0srKCjQaDbXmjUajwcrKCmfSULD5Oa6srKCtrQ0SiQQSiQRtbW2MvHFzD0MrsXhUUmzdw9BKjKmSiqt7SBBE3Conru4hOa8kWqBnyj3cgl0EQcQ0cMYWW3kIgkiKe7iVV2C1Won09PSYxLCB1+tFZmYmtb22tobt4E1LBimATaQAkiKWjveR85ZSgnc6Uu5hMpFyD1PuITekYg/ZxB52dXXFTMo2n1D38NSpU7zjDEP/yHzisnJpIsBm5dJ45rntgpONuITTJirctqWlJabjdGAUvNUEp0NouxcvtLa2MgZhmUwmzqKjCrbb7aw9HC5pmWAymVivb2kymTgFe0RslrbeNTa1rtlshkgkQn5+PusL2Iqtd42NdWM0GpGVlYWTJ08ypo14h/nGI8Uax8Q3XJbteREFV1ZW8iLmex6Ja9euJfS8iD9puVyOmpoa3L59G8DmVUq3glzNlAzoimVgvrq6GmlpadDr9QA2r1K6FeRqpmRAFxveiIK9Xi8VZ/jLL78whulUVFTELJbkJeMMjUYjI29TUxNrsQBDX5qMM4w0qE2iuLgYpaWlcXMPyThDphWMNRoN6uvrOfGyskvVanXUNGq1Oq5WKclL/qwjQa/Xc+Zl1dNi8nFi9ZeSyZvqS0erjbmAbT6kT7X1lQp8QeYTyasKE8w3aJJvPh6PBwRBYGZmJi68MzMzqdjDUDx67mEsFxwrUrGHSUCqWdrpSAne6dix7uFzzz1HW0s/FO7h/v37UVBQgMceeyxm99DlcsFut2NwcBACgSDsnTHb7h4ePHgQxcXFcTPTMjIyIJFIcOfOHfz+++8Pl2DSPSTftxQv93DXrl0oKirCnTt3wtIwFhq62aputxtms5maCR8pHROEQiEkEgntew/X1tbC3mu4tLSE9vZ2nD9/njZd6Pn79u3jHoo3OTmJsbExnDlzBsDGWLXdbqcNoent7YVCocChQ4dYh+VFij3s7u5GR0cH9YWaTCbcunVr0yMkmfbChQvQarXQarVUWF4wGER6ejp7wdPT0zCbzfB4PJv2R7NT/H4/rFYrJicnUVZWxnowPtTpGxoagtFoDAsIi2anuN1ufPnll+ju7salS5dw4sQJKk+64hH2FTgcDgwPD4eJZQu/3w+bzcZ5JSSLxYL333+fNvqNDdxuN3p6ehjPDxMsl8tjjkw5ceIENfOVLVQqFd58882YeA0GA7WiWiSECfb5fPjpp58AbKyBx/bCpVIp6urqAADff/895wf6tbU1fPbZZwCAjz/+mPHCSSiVSsr3eueddxh5aWtpMrwuJyeH9cuczp07R5UZvktO/fnnnwCAY8eOoa+vj9U5nZ2d1CsH2fhaUZulwcFB1kGNi4uLjK/gYwuDwcCJ9+2332add9RmyW63w+12Q6FQIC8vD5cvX8bCwgI19VcqlcJms8HhcGBycjJuSz6aTCbMzs5Cq9Xi6NGjGB0dxcTEBJxOJyQSCZRKJUZGRjAyMoL//e9/jBFsoaAVLJfLKZvD4XBQ37ZEItlUph0OB238gVwu5ySQhEqlopo+i8VCtbsymWxTmb579y6t46BSqRg5aAXX1tbi22+/DZvY5XQ6aQMuQyGVSlFbW8trgb6WlhY0NDRgYmJi0/6ZmRnGYVylUomWlhbGeGbaMuzxeKDRaKhVDdkgOzsblZWVOHfuHO82fH19HW1tbWhqamL9ul2ZTIbXXnsNnZ2drN7yFfFFjy6XC6WlpVCpVFhaWsK///5LVfnz8/PIy8sDAOzevRu5ubnIycmBx+OJKZ6YIAj4fD7U19ejsbERf/zxB4aHhykrdHx8HE8//TQAYP/+/VAqlVAoFJx4I1ZapGiyrBw4cAD37t2DXC7HgQMHAGx0QXNycrC+vh63VR5Cecnw3J6eHqhUKpSXlwPY6OI+88wzALiHxnN6PPz555/D9h08eJATIR/Qzd9gE/FKh9SYFlvI5XKqPMUCrlFuKpUKp0+fZkwXDAZp93MSLBaLUVJSgqNHjyIjIwNerzfmOR0ul4sx9lAikeD06dN4+eWXIZVKGXnj5h5evHgRXq8XHo+Hd9MTCpFIhHv37iEnJydqp/+HH36A1+uFy+VirKTi6h7Gug7tVpDuIUEQKCwsjOge/vPPP6zyCwQCWF5exl9//YX5+Xla93DbzTSbzQar1Yr19fW4uoclJSUp9xB4BJullOCdjkdO8P8BGCQ0hnF1DxUAAAAASUVORK5CYII=) 2px 3px no-repeat;
+      background-repeat: no-repeat;
+      border-bottom: 1px solid #BCBCBC;
+      cursor: move;
+      display: block;
+      height: 13px;
+      width: 27px;
+    }
+
+    .tool-button {
+      background-position: center center;
+      background-repeat: no-repeat;
+      border-bottom: 1px solid #BCBCBC;
+      border-top: 1px solid #F1F1F1;
+      cursor: pointer;
+    }
+
+    .buttons > .tool-button:last-child {
+      border-bottom: none;
+    }
+
+    </style>
+    <div class="drag-handle"></div>
+    <div class="buttons">
+    </div>
+  </template>
+</polymer-element><style>
+.track-button{background-color:rgba(255,255,255,0.5);border:1px solid rgba(0,0,0,0.1);color:rgba(0,0,0,0.2);font-size:10px;height:12px;text-align:center;width:12px}.track-button:hover{background-color:rgba(255,255,255,1.0);border:1px solid rgba(0,0,0,0.5);box-shadow:0 0 .05em rgba(0,0,0,0.4);color:rgba(0,0,0,1)}.track-close-button{left:2px;position:absolute;top:2px}.track-collapse-button{left:3px;position:absolute;top:2px}
+</style><style>
+.drawing-container{-webkit-box-flex:1;display:inline;overflow:auto;overflow-x:hidden;position:relative}.drawing-container-canvas{-webkit-box-flex:1;display:block;pointer-events:none;position:absolute;top:0}
+</style><polymer-element name="tr-ui-heading">
+  <template>
+    <style>
+    :host {
+      background-color: rgb(243, 245, 247);
+      border-right: 1px solid #8e8e8e;
+      display: block;
+      height: 100%;
+      margin: 0;
+      padding: 0 5px 0 0;
+    }
+
+    heading {
+      display: block;
+      overflow-x: hidden;
+      text-align: left;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+
+    #arrow {
+      -webkit-flex: 0 0 auto;
+      font-family: sans-serif;
+      margin-left: 5px;
+      margin-right: 5px;
+      width: 8px;
+    }
+
+    #link, #heading_content {
+      display: none;
+    }
+    </style>
+    <heading id="heading" on-click="{{onHeadingDivClicked_}}">
+      <span id="arrow"></span>
+      <span id="heading_content"></span>
+      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    </heading>
+  </template>
+
+  
+</polymer-element><style>
+.letter-dot-track {
+  height: 18px;
+}
+</style><style>
+.chart-track {
+  height: 30px;
+  position: relative;
+}
+</style><style>
+.power-series-track {
+  height: 90px;
+}
+</style><style>
+.spacing-track{height:4px}
+</style><style>
+.object-instance-track{height:18px}
+</style><style>
+.rect-track{height:18px}
+</style><style>
+.thread-track{-webkit-box-orient:vertical;display:-webkit-box;position:relative}
+</style><style>
+.process-track-header{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;font-size:75%}.process-track-name:before{content:'\25B8';padding:0 5px}.process-track-base.expanded .process-track-name:before{content:'\25BE'}
+</style><style>
+.model-track {
+  -webkit-box-flex: 1;
+}
+</style><style>
+.ruler-track{height:12px}.ruler-track.tall-mode{height:30px}
+</style><polymer-element name="tr-ui-timeline-track-view">
+  <template>
+    <style>
+    :host {
+      -webkit-box-orient: vertical;
+      display: -webkit-box;
+      position: relative;
+    }
+
+    :host ::content * {
+      -webkit-user-select: none;
+      cursor: default;
+    }
+
+    #drag_box {
+      background-color: rgba(0, 0, 255, 0.25);
+      border: 1px solid rgb(0, 0, 96);
+      font-size: 75%;
+      position: fixed;
+    }
+
+    #hint_text {
+      position: absolute;
+      bottom: 6px;
+      right: 6px;
+      font-size: 8pt;
+    }
+    </style>
+    <content></content>
+
+    <div id="drag_box"></div>
+    <div id="hint_text"></div>
+
+    <tv-ui-b-hotkey-controller id="hotkey_controller">
+    </tv-ui-b-hotkey-controller>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-find-control">
+  <template>
+    <style>
+      :host {
+        -webkit-user-select: none;
+        display: -webkit-flex;
+        position: relative;
+      }
+      input {
+        -webkit-user-select: auto;
+        background-color: #f8f8f8;
+        border: 1px solid rgba(0, 0, 0, 0.5);
+        box-sizing: border-box;
+        margin: 0;
+        padding: 0;
+        width: 170px;
+      }
+      input:focus {
+        background-color: white;
+      }
+      tr-ui-b-toolbar-button {
+        border-left: none;
+        margin: 0;
+      }
+      #hitCount {
+        left: 0;
+        opacity: 0.25;
+        pointer-events: none;
+        position: absolute;
+        text-align: right;
+        top: 2px;
+        width: 167px;
+        z-index: 1;
+      }
+      #spinner {
+        visibility: hidden;
+        width: 8px;
+        height: 8px;
+        left: 154px;
+        pointer-events: none;
+        position: absolute;
+        top: 4px;
+        z-index: 1;
+
+        border: 2px solid transparent;
+        border-bottom: 2px solid rgba(0, 0, 0, 0.5);
+        border-right: 2px solid rgba(0, 0, 0, 0.5);
+        border-radius: 50%;
+
+        animation: spin 1s linear infinite;
+      }
+      @keyframes spin { 100% { transform: rotate(360deg); } }
+    </style>
+
+    <input id="filter" on-blur="{{ filterBlur }}" on-focus="{{ filterFocus }}" on-input="{{ filterTextChanged }}" on-keydown="{{ filterKeyDown }}" on-mouseup="{{ filterMouseUp }}" type="text"/>
+    <div id="spinner"></div>
+    <tr-ui-b-toolbar-button on-click="{{ findPrevious }}">
+      ←
+    </tr-ui-b-toolbar-button>
+    <tr-ui-b-toolbar-button on-click="{{ findNext }}">
+      →
+    </tr-ui-b-toolbar-button>
+    <div id="hitCount">0 of 0</div>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-scripting-control">
+  <template>
+    <style>
+      :host {
+        flex: 1 1 auto;
+      }
+      .root {
+        font-family: monospace;
+        cursor: text;
+
+        padding: 2px;
+        margin: 2px;
+        border: 1px solid rgba(0, 0, 0, 0.5);
+        background: white;
+
+        height: 100px;
+        overflow-y: auto;
+
+        transition-property: opacity, height, padding, margin;
+        transition-duration: .2s;
+        transition-timing-function: ease-out;
+      }
+      .hidden {
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding-top: 0px;
+        padding-bottom: 0px;
+        height: 0px;
+        opacity: 0;
+      }
+      .focused {
+        outline: auto 5px -webkit-focus-ring-color;
+      }
+      #history {
+        -webkit-user-select: text;
+        color: #777;
+      }
+      #prompt {
+        -webkit-user-select: text;
+        -webkit-user-modify: read-write-plaintext-only;
+        text-overflow: clip !important;
+        text-decoration: none !important;
+      }
+      #prompt:focus {
+        outline: none;
+      }
+      #prompt br {
+        display: none;
+      }
+      #prompt ::before {
+        content: ">";
+        color: #468;
+      }
+    </style>
+
+    <div class="root hidden" id="root" on-focus="{{ onConsoleFocus }}" tabindex="0">
+      <div id="history"></div>
+      <div id="prompt" on-blur="{{ onConsoleBlur }}" on-keydown="{{ promptKeyDown }}" on-keypress="{{ promptKeyPress }}">
+  
+
+  
+
+</div></div></template></polymer-element><polymer-element name="tr-ui-side-panel">
+  
+</polymer-element><polymer-element is="HTMLUnknownElement" name="tr-ui-side-panel-container">
+  <template>
+    <style>
+    :host {
+      align-items: stretch;
+      display: -webkit-flex;
+    }
+
+    :host([expanded]) > active-panel-container {
+      -webkit-flex: 1 1 auto;
+      border-left: 1px solid black;
+      display: -webkit-flex;
+    }
+
+    :host(:not([expanded])) > active-panel-container {
+      display: none;
+    }
+
+    active-panel-container {
+      display: flex;
+    }
+
+    tab-strip {
+      -webkit-flex: 0 0 auto;
+      -webkit-flex-direction: column;
+      -webkit-user-select: none;
+      background-color: rgb(236, 236, 236);
+      border-left: 1px solid black;
+      cursor: default;
+      display: -webkit-flex;
+      min-width: 18px; /* workaround for flexbox and writing-mode mixing bug */
+      padding: 10px 0 10px 0;
+      font-size: 12px;
+    }
+
+    tab-strip > tab-strip-label {
+      -webkit-writing-mode: vertical-rl;
+      display: inline;
+      margin-right: 1px;
+      min-height: 20px;
+      padding: 15px 3px 15px 1px;
+    }
+
+    tab-strip >
+        tab-strip-label:not([enabled]) {
+      color: rgb(128, 128, 128);
+    }
+
+    tab-strip > tab-strip-label[selected] {
+      background-color: white;
+      border: 1px solid rgb(163, 163, 163);
+      border-left: none;
+      padding: 14px 2px 14px 1px;
+    }
+    </style>
+
+    <active-panel-container id="active_panel_container">
+    </active-panel-container>
+    <tab-strip id="tab_strip"></tab-strip>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-timeline-view-help-overlay">
+  <template>
+    <style>
+    :host {
+      -webkit-flex: 1 1 auto;
+      -webkit-flex-direction: row;
+      display: -webkit-flex;
+      width: 700px;
+    }
+    .column {
+      width: 50%;
+    }
+    h2 {
+      font-size: 1.2em;
+      margin: 0;
+      margin-top: 5px;
+      text-align: center;
+    }
+    h3 {
+      margin: 0;
+      margin-left: 126px;
+      margin-top: 10px;
+    }
+    .pair {
+      -webkit-flex: 1 1 auto;
+      -webkit-flex-direction: row;
+      display: -webkit-flex;
+    }
+    .command {
+      font-family: monospace;
+      margin-right: 5px;
+      text-align: right;
+      width: 150px;
+    }
+    .action {
+      font-size: 0.9em;
+      text-align: left;
+      width: 200px;
+    }
+    tr-ui-b-mouse-mode-icon {
+      border: 1px solid #888;
+      border-radius: 3px;
+      box-shadow: inset 0 0 2px rgba(0,0,0,0.3);
+      display: inline-block;
+      margin-right: 1px;
+      position: relative;
+      top: 4px;
+    }
+    .mouse-mode-icon.pan-mode {
+      background-position: -1px -11px;
+    }
+    .mouse-mode-icon.select-mode {
+      background-position: -1px -41px;
+    }
+    .mouse-mode-icon.zoom-mode {
+      background-position: -1px -71px;
+    }
+    .mouse-mode-icon.timing-mode {
+      background-position: -1px -101px;
+    }
+    </style>
+    <div class="column left">
+      <h2>Navigation</h2>
+      <div class="pair">
+        <div class="command">w/s</div>
+        <div class="action">Zoom in/out (+shift: faster)</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">a/d</div>
+        <div class="action">Pan left/right (+shift: faster)</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">→/shift-TAB</div>
+        <div class="action">Select previous event</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">←/TAB</div>
+        <div class="action">Select next event</div>
+      </div>
+
+      <h2>Mouse Controls</h2>
+      <div class="pair">
+        <div class="command">click</div>
+        <div class="action">Select event</div>
+      </div>
+      <div class="pair">
+        <div class="command">alt-mousewheel</div>
+        <div class="action">Zoom in/out</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon modename="SELECTION"></tr-ui-b-mouse-mode-icon>
+        Select mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Box select</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">double click</div>
+        <div class="action">Select all events with same title</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon modename="PANSCAN"></tr-ui-b-mouse-mode-icon>
+        Pan mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Pan the view</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon modename="ZOOM"></tr-ui-b-mouse-mode-icon>
+        Zoom mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Zoom in/out by dragging up/down</div>
+      </div>
+
+      <h3>
+        <tr-ui-b-mouse-mode-icon modename="TIMING"></tr-ui-b-mouse-mode-icon>
+        Timing mode
+      </h3>
+      <div class="pair">
+        <div class="command">drag</div>
+        <div class="action">Create or move markers</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">double click</div>
+        <div class="action">Set marker range to slice</div>
+      </div>
+    </div>
+
+    <div class="column right">
+      <h2>General</h2>
+      <div class="pair">
+        <div class="command">1-4</div>
+        <div class="action">Switch mouse mode</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">shift</div>
+        <div class="action">Hold for temporary select</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">space</div>
+        <div class="action">Hold for temporary pan</div>
+      </div>
+
+      <div class="pair">
+        <div class="command"><span class="mod"></span></div>
+        <div class="action">Hold for temporary zoom</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">/</div>
+        <div class="action">Search</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">enter</div>
+        <div class="action">Step through search results</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">f</div>
+        <div class="action">Zoom into selection</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">z/0</div>
+        <div class="action">Reset zoom and pan</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">g/G</div>
+        <div class="action">Toggle 60hz grid</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">v</div>
+        <div class="action">Highlight VSync</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">h</div>
+        <div class="action">Toggle low/high details</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">m</div>
+        <div class="action">Mark current selection</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">`</div>
+        <div class="action">Show or hide the scripting console</div>
+      </div>
+
+      <div class="pair">
+        <div class="command">?</div>
+        <div class="action">Show help</div>
+      </div>
+    </div>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-u-array-of-numbers-span">
+  <template>
+  </template>
+  
+</polymer-element><polymer-element name="tr-ui-u-generic-table-view">
+  <template>
+    <style>
+    :host {
+    display: flex;
+    }
+    #table {
+      flex: 1 1 auto;
+      align-self: stretch;
+    }
+    </style>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+</polymer-element><polymer-element name="tr-ui-timeline-view-metadata-overlay">
+  <template>
+    <style>
+    :host {
+      width: 700px;
+
+      overflow: auto;
+    }
+    </style>
+    <tr-ui-u-generic-table-view id="gtv"></tr-ui-u-generic-table-view>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-u-preferred-display-unit">
+  
+</polymer-element><polymer-element name="tr-ui-timeline-view">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      cursor: default;
+      display: flex;
+      font-family: sans-serif;
+      padding: 0;
+    }
+
+    #control {
+      background-color: #e6e6e6;
+      background-image: -webkit-gradient(linear, 0 0, 0 100%,
+          from(#E5E5E5), to(#D1D1D1));
+      flex: 0 0 auto;
+      overflow-x: auto;
+    }
+
+    #control::-webkit-scrollbar { height: 0px; }
+
+    #control > #bar {
+      font-size: 12px;
+      display: flex;
+      flex-direction: row;
+      margin: 1px;
+    }
+
+    #control > #bar > #title {
+      display: flex;
+      align-items: center;
+      padding-left: 8px;
+      padding-right: 8px;
+      flex: 1 1 auto;
+    }
+
+    #control > #bar > #left_controls,
+    #control > #bar > #right_controls {
+      display: flex;
+      flex-direction: row;
+      align-items: stretch;
+    }
+
+    #control > #bar > #left_controls > * { margin-right: 2px; }
+    #control > #bar > #right_controls > * { margin-left: 2px; }
+    #control > #collapsing_controls { display: flex; }
+
+    middle-container {
+      flex: 1 1 auto;
+      flex-direction: row;
+      border-bottom: 1px solid #8e8e8e;
+      display: flex;
+      min-height: 0;
+    }
+
+    middle-container ::content track-view-container {
+      flex: 1 1 auto;
+      display: flex;
+      min-height: 0;
+      min-width: 0;
+    }
+
+    middle-container ::content track-view-container > * { flex: 1 1 auto; }
+    middle-container > x-timeline-view-side-panel-container { flex: 0 0 auto; }
+    x-drag-handle { flex: 0 0 auto; }
+    tr-ui-a-analysis-view { flex: 0 0 auto; }
+    </style>
+
+    <tv-ui-b-hotkey-controller id="hkc"></tv-ui-b-hotkey-controller>
+    <div id="control">
+      <div id="bar">
+        <div id="left_controls"></div>
+        <div id="title">^_^</div>
+        <div id="right_controls">
+          <tr-ui-b-toolbar-button id="view_metadata_button">
+            M
+          </tr-ui-b-toolbar-button>
+          <tr-ui-b-dropdown id="view_options_dropdown"></tr-ui-b-dropdown>
+          <tr-ui-find-control id="view_find_control"></tr-ui-find-control>
+          <tr-ui-b-toolbar-button id="view_console_button">
+            »
+          </tr-ui-b-toolbar-button>
+          <tr-ui-b-toolbar-button id="view_help_button">
+            ?
+          </tr-ui-b-toolbar-button>
+        </div>
+      </div>
+      <div id="collapsing_controls"></div>
+      <tr-ui-b-info-bar-group id="import-warnings">
+      </tr-ui-b-info-bar-group>
+    </div>
+    <middle-container>
+      <content></content>
+
+      <tr-ui-side-panel-container id="side_panel_container">
+      </tr-ui-side-panel-container>
+    </middle-container>
+    <x-drag-handle id="drag_handle"></x-drag-handle>
+    <tr-ui-a-analysis-view id="analysis"></tr-ui-a-analysis-view>
+
+    <tr-ui-u-preferred-display-unit id="display_unit">
+    </tr-ui-u-preferred-display-unit>
+  </template>
+
+  
+</polymer-element><style>
+* /deep/ .x-list-view{-webkit-user-select:none;display:block}* /deep/ .x-list-view:focus{outline:none}* /deep/ .x-list-view *{-webkit-user-select:none}* /deep/ .x-list-view>.list-item{padding:2px 4px 2px 4px}* /deep/ .x-list-view:focus>.list-item[selected]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ .x-list-view>.list-item[selected]{background-color:rgb(103,199,165)}
+</style><style>
+* * /deep/ tr-ui-e-chrome-cc-picture-ops-list-view{-webkit-flex-direction:column;border-top:1px solid grey;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view{-webkit-flex:1 1 auto;overflow:auto}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item{border-bottom:1px solid #555;font-size:small;font-weight:bold;padding-bottom:5px;padding-left:5px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item:hover{background-color:#f0f0f0;cursor:pointer}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>*{color:#777;font-size:x-small;font-weight:normal;margin-left:1em;max-width:300px}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.elementInfo{color:purple;font-size:small;font-weight:bold}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view>.x-list-view .list-item>.time{color:rgb(136,0,0)}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view:focus>.list-item[beforeSelection]{background-color:rgb(171,217,202);outline:1px dotted rgba(0,0,0,0.1);outline-offset:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-list-view .x-list-view>.list-item[beforeSelection]{background-color:rgb(103,199,165)}
+</style><template id="tr-ui-e-chrome-cc-display-item-debugger-template">
+  <style>
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger {
+    -webkit-flex: 1 1 auto;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel {
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+    min-width: 300px;
+    overflow-y: auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info {
+    -webkit-flex: 1 1 auto;
+    padding-top: 2px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info .title {
+    font-weight: bold;
+    margin-left: 5px;
+    margin-right: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+        display-item-info .export {
+    margin: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > x-drag-handle {
+    -webkit-flex: 0 0 auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel {
+    -webkit-flex: 1 1 auto;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+      display-item-info > header {
+    border-bottom: 1px solid #555;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+      display-item-info > .x-list-view > div {
+    border-bottom: 1px solid #555;
+    padding-top: 3px;
+    padding-bottom: 3px;
+    padding-left: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > left-panel >
+      display-item-info > .x-list-view > div:hover {
+    background-color: #f0f0f0;
+    cursor: pointer;
+  }
+
+  /*************************************************/
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+      tr-ui-e-chrome-cc-picture-ops-list-view.hasPictureOps {
+    display: block;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        x-drag-handle.hasPictureOps {
+    display: block;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        tr-ui-e-chrome-cc-picture-ops-list-view {
+    display: none;
+    overflow-y: auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger > right-panel >
+        x-drag-handle {
+    display: none;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-display-item-debugger raster-area {
+    -webkit-flex: 1 1 auto;
+    background-color: #ddd;
+    min-height: 200px;
+    min-width: 200px;
+    overflow-y: auto;
+    padding-left: 5px;
+  }
+  </style>
+
+  <left-panel>
+    <display-item-info>
+      <header>
+        <span class="title">Display Item List</span>
+        <span class="size"></span>
+        <div class="export">
+          <input class="dlfilename" type="text" value="displayitemlist.json"/>
+          <button class="dlexport">Export display item list</button>
+        </div>
+        <div class="export">
+          <input class="skpfilename" type="text" value="skpicture.skp"/>
+          <button class="skpexport">Export list as SkPicture</button>
+        </div>
+      </header>
+    </display-item-info>
+  </left-panel>
+  <right-panel>
+    <raster-area><canvas></canvas></raster-area>
+  </right-panel>
+</template><style>
+* /deep/ .tr-ui-e-chrome-cc-display-item-list-view{-webkit-flex:1 1 auto!important;display:-webkit-flex}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-layer-picker{-webkit-flex-direction:column;display:-webkit-flex}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls{-webkit-flex:0 0 auto;background-image:-webkit-gradient(linear,0 0,100% 0,from(#E5E5E5),to(#D1D1D1));border-bottom:1px solid #8e8e8e;border-top:1px solid white;display:inline;font-size:14px;padding-left:2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>top-controls input[type='checkbox']{vertical-align:-2px}* /deep/ tr-ui-e-chrome-cc-layer-picker>.x-list-view{-webkit-flex:1 1 auto;font-family:monospace;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view{-webkit-flex:0 0 auto;height:200px;overflow:auto}* /deep/ tr-ui-e-chrome-cc-layer-picker>tr-ui-a-generic-object-view *{-webkit-user-select:text!important;cursor:text}
+</style><style>
+* /deep/ quad-stack-view {
+  display: block;
+  float: left;
+  height: 100%;
+  overflow: hidden;
+  position: relative; /* For the absolute positioned mouse-mode-selector */
+  width: 100%;
+}
+
+* /deep/ quad-stack-view > #header {
+  position: absolute;
+  font-size: 70%;
+  top: 10px;
+  left: 10px;
+  width: 800px;
+}
+* /deep/ quad-stack-view > #stacking-distance-slider {
+  position: absolute;
+  font-size: 70%;
+  top: 10px;
+  right: 10px;
+}
+
+* /deep/ quad-stack-view > #chrome-left {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABICAYAAABC4+HLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyMmV/Pm9QAAIABJREFUeNrtvXmwXdd13vlbe9/7BgzEQAIcQAIEQYKjSAokLVlOW5Fk2nLKmqx0J2Wp0k652h13uiy5XYqdwU7sSnckpZ1yV3U75apU4kos27Elu9NlyRXZjiiRomSTIiWZs0hwHsABJIY33rPX6j/W2ueed3DvAyDKKoGFW0UCeO/ec/fZZ+29v7XWt74lAIuLi7tXV1f/raq+zcy2AogIZsbpvrqfMzNE5IS/1/fVn5sZKaUTrtX9/v7nT+fn9e/1e052X/3r1THWa3R/37+miKCq7c+mjW/a+F/P57vj6/45bayn+wzXs4n+794Q9nP8+PHdS0tL31LVmfpGVQU4YSInGUb/YfZvpn+zp/LQu4Y27X31d933nurkq+qaa08yotO55npG0v2O+r1/XZ9fb2FMWoD9Oe5+pju//e+fdP3u83+j2I+89NJLn11dXf1bdSCTJnnSSpz2+/VWZ/8m+w+g/zD616yT2P9733BOZ5f4dhbCevPQHet63zVtV3y9n1/v/k9nZ562SNY7Gd5o9iPPP//8qxVKrQdL+hOy3qqdNEnTjv1JA+vuRpMGvd7kn8oCqded9B2THuJ6u/Kk7+vuiNOgQH8OX+/np813/376O/CkU2EavDwVWPiGsp9nn33WJt3ItF2ne2xOe2jTHuTJMOS0He1UcG33791JmWQYkzB6dyfp7tynsktPG8/Jdv2TGcLpfH7Sc5m0EKZBsPV+tp4PMe39bwj7efrpp229G5u2O3WPplN1cE/XQZsENybtnNN2pv4x3N1Fpu2S/SO6j6fXgz6n4gRPGmMfR7/ez/cXd/1798Tsfr4PMU52Oq4Hp95I9jPor7ZJ+G7STlEnvN7gesfXpB2tH5lZzynrO07Txtb92aQTY9rv+3i1v4jqv5umOSEq0r9O3/iqEUx6MPXnqjpxrk73812oMQmP968zyUj68zPp+U1bxG80+5GnnnrKpkVxTiWUuN4q7+96/YFXp6pvANN8hD7MmRbF6O7200KR9ed9CDbpSF4v6jIJtnQjQdPGOylK9p34/HowaFL0Z73IUNex7Z5Gk3bkN6L9yBNPPGHdY3fayu3uSP0dqH62uyP0w4XrDWo957gPEfqf78e4p4U8+0Y86R6711pvAUyL3vTvd9ou238Q/Xn4dj4/Cd6d7BlMC532534S9OnO8xvVfuTxxx+39RJlk/DtpAGc6k6hquScp+7EkyIn0+LV60Ufpu2q05zN/sOYFIfvP8CT5VEmGWN/h5w0zm/38+sl7/r3drLntt58rzdXbyT7kccee8z6O2b3JnLO6zpjk47nkyVg1pu07muas9b3CaZh4f5uPMn4Sikn7Jj9RTEJMnQfVHdck4x3Wt5i0qL6dj8/6WQ5GcSYBiEn+STrhT/fqPYzmJYxrRcopax5eH18Oi38WI2ulLImYTPNMavv716z/93rRXUmOZXVgZ5kePX7+hPeN5xJTmx3MdXf9zHyM888w8LCwgn30IUQ0xzWSYvhVD4/LarTzpWBpOl+zqRQ9lqjE2DCtbH2x9MW3XA45JxzzmHnzp0njYp9r9jPoH75Gkekc8SZ2ZpjrH/Ez8wMSSmHMY4YjZp2MDnniVGT/sPvRhxmZ2fJOWHmxj0ajU7AtvV6k4727gSklMg5M4jdq6iyuro69bv799fNptYF0X3vJKjz8MMPMz+/gWuvuYatW7eScgIEwTADEwEUAZDkBgtuYONlCCJgAuZ/N5QkCcP8avFzUH8fsZgNEoJJLAakc+2TjENi90RQjGSCJm1/hwlmgmRFFIwEYoiNxyPxvYZ07gVKUzh8+DD333cfRZXLLrvsBLxfjbl76pyO/ZRS1thq325O137k4YcftvUSOf1Ufdco/uwLX+LOv7ibZ194EYBdF+zkB956C+98+99ARE64ue6XqyqDwaDdGZqm4Qtf/DK3f+UveO7QS2uu944f/IH2WpNwdp2U/oT8+W23c8dX7+K5GN9FF+zkb7zlZt71jh9cswNPw8uTsPU0h19VeeSRR7j55lvYumUzK6MCpqTs9p2AAiRLmChWBBIIiqZEMkVUMAQTJZtQSCCKkDE0/h+7twkKpCSYxrhVMTGyCYogohRLCGvHoYD0xyGKScIUpC5AVSQl/0ACaxeCkJJhakDCTJEEiKAmDMx8XSdAY6lZQjHmZoa89NLL3Pv1r3PVVVeesDH3T+FTtZ/uguhu8v3o36naj4ggjzzyiPXhwtRjOf6+tLjEP//4r3HOuRfw5psPsOeSXQA8+dQz3Pu1ezl2+BC//I9+jvn5uXWjDfW1uLjIr37y19m8/fzJ13vlBf75L/48c3Oza3aWadSP5eUVfuUT/2bd6/3yL/xvbNgwv2Y3qbtOF0J2MfN6ka7nnnuOvZfuZcfO8xitKnloFBXEBHGLc4MTQwVEDeIkyAqa/Pdh9z5vaqgkUuz8akYGVATEHOYYiCSUQtJqkCDJsJJIvXFYNRIzLGWQQqqLEiOhqKS6gnzhqJ9cJplsiiXBSnfBJF957TEoJBKYYskwFUSgWCKnBkmZp59+mpdfepmdO3eu2USn+V/r2c/JWAX9CN/J7KdNiD744IO2nqM0Cff+01/9P7js6gP8d29/C5detJNtmzYC8OrxBZ547kVu/+JfcPDBe/iXv/xPkCnkvHalm/HPTvV6v/SP25vs3mB3fKurI37pX36cfdesf73HHriH//2X/3Fr/NOSTZMyzn0n0sx47LHH+JEf+REWFhd8pzcliRtyBVbFYlcTN0bfpoWEYiaxENTtjOQwByOZ7+r+b/zacY5YICvH/iDmBurjmzQOKMlIWkPThpohkuN0iwWI+YrNGkdeQswwcbhlWEAzw8wXazZDJfsYMP84ghXzxSHip5rB/IY5/sv/+0dc96Y3rdmA2uz0YDA1EHIqDNv1KDAVvk2yn64vOujHlqdlJ+vv/+wLX2JuywVcfOkeXj2ywGtHn0C1Hov+uUsu3cNzzz/Hf7vtdm5959snRknq6wtfvOOUr/fnX7yDH37n29fccBdG5Zy57fYvs2HrqV7vdm59x9vXJeqtx6WqD+T555/nyiv3s7y8TMLhSgLMElkURx+KENi+7uzi0EgtIUCi+OmSwIpjmYTSAIN6uiSDkkAKQgp/IgON+yaGnxIBz/rjcPckj30LU5I5rCsJsiYsafgjCbXEUIwiiqq4e1J9FjVfNCioYMlPC/eJIFuisTiN0oBkhllBcmJlaYnL9+/n0KFD7Nixg5xza6hPP/00S0tLzM7Mho/lfpGicW/hyyCQAv75Nuw+UOwi/o7WmXLfClhYOMaWLVvZtWtXG7TpRibrMx/0V1j34XcdT4DBYMA933yQnRdeymhUOHZsCZFEqrurORRZHRV2XrCLr33jft596zsZjUbtiuzGqQeDAXd//T52Xrj3lK53zzce4G/d+k6WlpfXOF5jSAhf+8YD7DjF8d3zjQf50VvfRdM0LYzqv/pHcH9napqGF154gb/59rdz7PhxTPCdNSliisYuK5rjIRsWPyeJQyGhWhyNCEn9sbrPIGRJmBRfeCb+kEXQwDZG49AFIYmh4kvmhHGYISTEGl9YBimPoZypvx8VJA3R5IurMcdrSTrjLuGjGJCNpJnGlCwWp6CRMLIoMCBhFJPYIAxNxjVXX83v//7vs337dnLONE1DzpmXX36Zt73tB1g8fhwzh3OIObyrp60IWp9XNlBfRtkCPqWIM9T5x+GhDIQN8/O88srLfPWrX+WWW245IeLVPvvubt49biZRMTDj6MISGzdt9i81YTjIzM/OMjc7w3AwANwp27hpM0cWln0iOt9RowruSAlHFpZP43pLJxAB68lnZuSUOXJa41tCIuQ7jYBWf9fnP5kZo9GIlZUVLrzwQpaXVzxihGHJEE1ucdlIkgOwKMncj5Ds0SjfZd2R9re7AeWkGOFUhuOrrd+jFDPMEkJ1XGPhxdY+cRzZARPJfR9Jiqm/P2wONKHJwJRs6jt0Su5nWHJfQj2IYBQIp14xBkI47OE/BVyUFI6/KCk5zJOSGY1W2bFjB03TrOGtzQyHNKNRnTGQghWjWInxGI0phvtyNOZg0GAU86hmlMYw9c9qMYyCjgpHjx9ndmYD3//Wt3LPPfdM9FtUlYGqUko5IbzVdUi7WHw4M8vc3CxzczNsmnejq6HSphSWVlYBWF2ZY2Z2tt2tuwuw/ruUwszs6V2vuxi6TlYd48zM6V+vC8/qYqgnZT861Y+dP/bYo/zoj/4Yo3o8u1PgoVRJiPqJBRkRo6C+oxchSaGIxC5uJHEfwDdqN3xTg+wRKXd2EyRIBppjy/fLY02CWCzTxuHX91MAEfdPNJESqBopFcwyJurAqg3jWpx6DqkExVIiNwIDQa1BAWRAQiE5XExJ/URCyQgFIZlB9rk8cOAAt912G/v3728jiMOZGVQDEShoSUhuEM2U5CecFHWIGbAzlwZJghRDs0AJ2FVdu2wUMxI+XyqFpjF27drF0aNH2bRpU7txt455fcjVuCrE6Ds6DkdW2bF9C1lg49wsG+ZmOWfjHNu3bGL7lk1s2TjPpvlZNszOkMTYsW0LWvSEHbhraDu2nfr1ztu6haa3uLqn0qhpOO+0rncOTWcy+vmMesLVxVgXdimFpmligWbmZgZtLN8vFmFZbbBGHfdSwo9whxot8ZAdMydzTG9aUDGKGlZ8QaiGU6wGVtDSUChIY6j6gqOBTHPScZj5qVHUoAg0DaYlIIWhlj2qFUhBDUwLNH4tMCgKZqRSGMwO+PM//VOGgznPe2jDYGbIvfd8g5mZAapCMcEEv6cK8RpFLLFp06Z2Lqvt7dmzh4cfeRBTQ1E04GXBEG187pLSqNKYbyBm0IQda6MoDUbB1DwQUvyE1tJgKFqM1dJw6Z5Lefzxx1vb7B4EqbtSJjmmXYjVNIXrr7mCI68dZmaQmJ8dsu2cTezYtpkd2zaz9ZyNzM8OmRlkjr52mBuu2c/qaHRCZGcMSxpuuGb/qV/v2isYxfW6GdFqtE3TcMNpjq8mGbs+xyRSX520GhMvpfDC889z7XXXsdKsYMV8t7fA3ChYJmWgGKkIlh3SWeQEwJDkp0UJKKIioGNXW9R3PnKKEK+E32BYDlxvUMTQzEnHIREQSCQaMSRn9+dlvKOmMUr3aFRKcco43JIUicWU+G+3fYHf/c+/x6c+9R+ZGQ6ZmZ3jtz/1Kf7PX/vX3HPvvTHaQsYgKUnFo9C5oBirKytcdeVVvPjii+1zEBGOHTvGxk0bfXGabyxGQ1GHmaYB4YqRLDYIIXyw4vDQ/HoJQ61BTHyPKeZ3aMbxhQXm5+dPSDCaGamPt7pQZRJL8qYbrmP56KscPnwYEZgZJAbZ/5sZZMA4fPgVlo++yoEbrqXCtq4Bdv2bm9/8JpaPvXZq17v+2hNgTXcxN03DzQeuP+Xx3XLg+hNoGN1Togsxu4umnijPv/AC+6/YTxlZZIo1YJIf5yLmBpeFMhCwEg67J8QkVacyRe66eLg1aRtcUVFSgmzFsx3uWSKSkWIUibiSpcD1648DMU/ggTvP6r5PskhrmEMfRFEJKBcZfJPkjq4nQTA13vk338mHfuJDfOXOr/J7v/t7/M7v/A53fvlOfuqnfoqbbjhA8di1/2nZr5kU0YQlhz7XvukannrqqTW2snXrVpYXFrBmBH5+OBnA/CRxP0NJVjySZoo2DrLcbhu0eDTORONnxde3FUQLqoVmtMreS/fwzDPPnOBe5J/+6Z/+F/1dvZ9V7BqHiHDDtVdy51f/ktVRw9ZzNpMkMRo1HD16jAce/hbPPv0k/+N//941Wcr1CoNuvO4q7vjKetd7gr/3t98zkXJ8QpTJjBuuu5IvTxnf/Q9/i+effpIPf/DHJiqO9EPX/Yhd9UuWl5fZMD/ProsupJhDBEniOzaCWMakuNMsjp0znhzTSv0wRbL4yYCQyWgliJhTMzKZRty3cNhDJNgMY0ACz66H333ScRSHVSnCrZbdfzFpc4okFLHsvkEkBE0E6YSPfXxQrHDF/suZnZ3jttu+wHPPPcv73vdefuiHfpiVZrlNbLYJy4Hfm9uSn4jaFF47coScUuvnbd26lccOPsa27eehxXd/JO7LQAZgJRZ84+epZM8JeYwtIaKIRZpGxXNFLTvMIuye2LRxE48++ig7d+5c48/KPffcY5O4+11nvOsj1N/Pz2/ggYe/xaNPPUcTGHc4GLBvz0Vcc8U+VlZXpkrgTCrPrNf71pPPnnC9a6+8gqWlxTUOUx1T/VmfGbphw0buf+gRHn3yudavaMe3/3JWVpZPYOXW+6vX7CYcu9GUpmm47777+OAHP+h4NxYlSdr8gOGOY45TwCpIsRQwxkjqxi7iECCJY3MBj91L8viXKSlFrN7iG6SyrOp1OaVxEAlB1EPFyTzSVCkjmgSp2XGNPALBO2kMy0JW8YhW8VNpODvLp//g03zjG/diCDfeeAN/+8c/yOrqClgOLpZgA8NGKU6vOI0QhMzK8iL/9fOf58orr2QwGJBz5v777+etb/l+jh096rAzCNApbhMqRItTRVKHGBmcF6CYkSUjWlr+pNNrIodiwlNPP8WuXbvWJKoHXew+GAwYjUYnxPS78d9q3EtLi+zfdym3HLiBuVlP1qyurPLakSMsryxPrNfuhnL7hLKFhePs33cpN9/4Jubm58BgeWWFI0eOsLBwfM3i7BrytLrlhYXjXL1/H993043MzsyAwMrKKseOHWNxcWEq6a3PzO0nSFWV0WjE7OwsMzOzLC8teagTQ5w8FVljZ8B6bD/Ig2YkUaz4I1Tx06Sh+E4cxuIZcHdAU8Ak0+T2ihtWzYSj1NThScfhYM4dbne6fVcV8bCx5zpicanvvO2qix+bepSrFMgizM7O8h8/9Z/46p1f4f0f+HEA/ugP/5CVpRU+/KEPsTxa8XAxhpRUM6C+IFViDgqbNp3Tnso153HhhRfyyuGXyGmGOjtJxfliqYbFPX+hpiQKWIoNB1CFQYrTsqGIRLTKT+xk0ChA4Yr9+3ng/vvZu3dvaw+D7mmxsrLCYDBY44TWf3eNsJsPeeWVV9aVdekvvm7Uql88tLq6yksvvzy1sH+aSkh9NU3T+k0iwuLiIouLi+0J2K8zmERP7+Z2qvPdz3EcOnSI6667jtXVZTQZ0pgf81KZrNWgAuNWrlJSSolEWPL9WqWGOt2eJSlaguJhvusnEc/yV0ygRkkpiH+QRSnCScfhnCl1smM44BVIdVnBnnFOEfpMiBVUnMxYeWFZ3FP6/z77x9x5x528//0f4F3vfAdigpbCZ/7wM1yyezdveetbnL8lCbNC5cAUJ7d4SFoSS6Nlrrnmap555ll27tzJcDjk3HPP5eDBg1x2+RU0qytgQol5dNaDopactoLFCVyQLKhCSua+hQTzWD33YwKpcUaA/8ztbBRRs/bk6OPsLkTRoHj3C/Yn1Rv0/ZJJBSarq6troEr3c/XPmvnuQ7FJmfu+sMAkI+/WpPQTndMURGqCr8/6rD8/dOgQ73nPezh27HhEYzzk6Md6pX8bFbAIhonDJKhoxWLXTwFp1NdPY8EgFzT8Dv+AOwbOrjWPgKXKbfLo1CmNo15HPHFmUhgTVQh+lOOWLM641aCFWEtbj+cgyo/+yLvZtnUb3//Wt7G6OkIwfviHb2Xnzgu48c3Xs7K86idNzTGUoLlLxUdOiMwI1159NX/5l3exbdu29jkuLi4yPzvL8dUVSoNDtDjJLKBRI0YmkqXOcEQSFI2cShKkLowSSUlLkU+CZMbi4iLnbt/O8vIyMzMzbkt33nmnTaqK6lZx1aOuX7vcx+yTanq7MKpbfNR1quvu3F8wfQp5d7ev4+v6Al3o0/eX1hMHm1aLPEl8YWFhgZWVZd7+gz/IatOEPzDwya8bdXLoQwnqglR6OBFNcqhDOLbq22dEIiM513iUR8woyZ32XJ3sFDukuPtSKhnxFMbRJgZjx0ymIIM2CWkBO6xS4FNk7cVQC1jia6UNh1rOfgKotgnLFGOWDkFRTZyuUmodSaX1BNoYCF+548vMDGeYn59nZmYGVeXwK4fZef4FqFkEH2owISElnil+X77Ak/PQLBYzYNKQbNDys2rEziJQkFDO2bKVu+6+i71797q9dxNp/d247yfUnMC00Gw3kdNNltXPTitb7VZ91YRQn6zY/96+L1TDq30nvY6l+2fNldSxdU/Mfji3C+1WVlZ45JFHeOtb3sZodTWIbL4raTAKa8UFxTlOTlfxZJRU34DkcXuLRG6p4VdAszu+QZZTBSkOY6zu/MUJWaYRTTuNcfhxlaIOQ+Ik8ARhqZBNPOyMJFLkFDTGX0wpJUCYiI+ztaHY7ASsGRuemS+iZCCqEbiKMKv6ovRxKbccuIWDBw+2lBIR4YVDLzAzHJLQCF1bhzZSPKnZEjiDvqLmi5sCyfMeJpU640466uPT5Pe4PFohDTLD4dARQ3e3rYbdzRB3F0mfqj0pD9CFL12sXiM+1ZDrd9WfdSejv+C6pMWukXezmv3/uhCpe63uoqvjrYuq6WHOetp1v3N+fp65+TnMMpTShjOt3QE9ROvYPI5/83oKlRL1FIrzNSRyAJXFamBNLexzjJ78mqq+YFJxACZ4dvB0xqFBFycpUMhmlBw0k6CxWnJDdlqKnwR+gezcrmD+WkR+tN1/jUJARRM/tSg+1mSU8K80KCGkgiEeoFAfkqkyt2kD8/PzLVlVVbn22mu57YtfYLUUNm7cgBYfmgUb2BduHJfFKBRnAqRIXBZnKIuCNMWTirFo0eKUEwEdGcuLy2MbuP32260LfU6m0zRNm3Q9XdZazDIajRgOh+2C6Auk9X2e9dQpJtU+96HSYDA4IYk5TVh4Te1w+Br9U+PFF1/kyquuYu/eS50KkiQoHtLmCHJEhGosnRrPD6IgOaIl5rAJ8YSYJoWSUSnk5Bwqq5gjJUyLR4tybhm8vkA4rXFIMmiEkqSlswseyclSTxL3XzyRCGLF5QaiZLZSw2t+JuHObaJuAuo8KLF6i/V/Dgu1pk+C1hEOcRLP8D/1zFM89NBDnH/++QyHQy91Hgx44IEHKKUwPz9PaZq4txpVq5WINZIXLoJGwZa4RyZtrNzvQVGSed3LzOwsKQm7du0aEw+7jmyfaDiJRtENuU2Td+z/vMvd6i6++u8uhOpHlyoEqousr3LXvYd+sq7eU9c3miSjWRdJ9WO6i7DuYIcOHeLHP/B+ji0skSWyA6kWKKU2x13LUn3HcuydUoSjgk6NJqwUkNziYMtK1hTwSONKvggk+WJJgbFNGswyScopj6MN+yZjkEAbQwYNlMwwfKKSPN8S9u9JNcmIRj1HkByliEfGRoKm5KzxONMkxpCjTEDw7L1FWUESpWgIX2SLkoKoGMzC/iuu4Mtf/jI7duxobWJ5eZnLLrusjXh2Swb69tO3iYpQuqWw1fftRkyHw+GaIM2gL0ZQv7juntN0nLoZ9a5D3GXdttTfyHr2F0QdcH8xdk+P6kt0F0w3RNyv0OtH37rXn8TA7YsorK6unlBPXEphYWGByy+7jMWlZa+YK8kd5sDqKejfRkNmgBaPubvwgNKUQYxRIZnvxil2VC3+WREnFOILysSDrKoCNAgShU/J687l9MeRygCNYqriTA7PyquzcX0z953fiIRMtnEJbQ7elnrQQHMhaaIBp8cHLPOKkUqV0VYvQsy8ZiVqQ8Tpu2OonmBlZYX9+/dz5MgRtmzZsqaMtm8bw+FwzabaZ23X1+zs7Bok008kT5JYSl0j74ZtR6PRGojV3fFreLOLxfs+S5f+XXfe6mtMKputi6DrVPfpIX1fon5n15/o+g2T9GHrOJaXl9fkbUoprTJJHWddwE3T8MQTT/COH3oXpSmRqnP6tyexvKRUUMQG7luY1GgqiSF5UDynkSzwdZSamkQxj4dXsyWyQE7uvFrUwWrKEIVPOqgV36c/Do3TS6VGsiLWr2PlkAxYKo5zaiYcozHncGlAGEsgJUUdObhn4ZAmp2Acx2JHpBO50tZvMrE2ny1RHKXA277/bRw8eHCNXX237Sd1C4e6cKceMd2sdI3ydJ31SYXsdYDd1djdyfuwqgt3BoPBCSJjNRFZrzccDtes+vWUUvqJwvr+4XC4Jsxcd4+6+6SUGI1GHD16lAcffJD/4e/8HZaPL3nVWXCSPLTpLB1LbqopZGsQT4aliB5pyaTAtwWQQfAhtJCDqaqRlCtBabBhwnKJIiOLTDfQSOQrTn8czsNIHhUL6J0HOGwzJxUWEZJKsDIEy4ZJ9ipDrUojGg67JwuCKxwejuc1LIfJB8YXEY9WRZGXImQN1i+GpuSnWTGWV5b48Ic/zNfvvZejR4+uQTffLfuR27/0pdhCiAL6MUmM4J7Uyq5WmiU0kmqEo2oj1Z9JyLVU3GqRFfU5Cp+ge52uDx+7UJ3kVgFJWPO++pska+Vqqq+FdcbT+S4i4tJqRdXQUCSU3JeTljM1HA64+qorWS4N2VJ8jQYBLpMoQUWHAUKDix9U+ptj/cBI4nymAEvxQBwe+XXjHlJBtdIQ05hwh6JZSPo6xtFm68f3i4IFnZycQhBhnJF3H1yD4hIlsCpjxq6M6+NpqTIhAySKFKfiD5K11A93xI0qFlRTqV42HLkhEyQJDz74wASxD9pn1SGutQteqM+acRBhLBI2wZ7Hw2+t6/lDh2woQhG8drkaazUUBI00ewpqDClR1EXGqiZRq2IR0jE5HM+avZWITzsTMqInEb2oC0BDoCxJ8IoiopCCy+OsS6c1iPiR7xFFI6dQvqhiCjHlLfwQN6Lx/Xssp5iQrBpK5JJbdqrXSYiF1kegDM8ZBDkvplIl5igHLSMoH9XZFIOSa2WdeXVbZGpdWMfxuVRHH39fLFvPVai87nH4JsDaZ6WG5SBFVl6X1PmHsV5QhEQcCZcsAAAWiUlEQVTN/3S+VfIipBosE0FLzWRnf1Z4Vtp9J/WAXcpRvBVUrprIi/vGxpG2yOWf5FkJRdx+Bh6DeN32nCRKFyV2No1Yd12ViguMpZRiB/AEVor4u0VM2+LYN/Hj2LO6cXhGFVjoVDjetnqsBMUnDuVURS1IpOw7TqP12K8Lw5Nm7vA5dUDVs8MSnl8hwpKhzKfqIgWu3RScHgtjSw4l6s6SgtWKuhqHU9OkzbYWMyx1ggPm7FZJyZ1UBIsyToschguG+HcXxZN+kdmuQVdNJRJw1jlVtS2W+k6MQ8W8bDcMMhWjSfgmY8Vza6o+P8Hd0wjFWlQG1mNc8OfqGWev2WgipKzqBuf+T4kyFB9f0TzOktdEqLoWlpl4HQaN86LsVJ+VeaTvO2jPg6B6erRDIIdR13oD/02s+uQTSJvrdfwpUTBjA2sTR9IINlCkyWiuzM/sD0DMSS0mTkqzhKbiANpo2aClEXLc2LhYP7Kfgb/rSSvWtMk2y7G7hbSHVUigtcjIKMUX60iEQQOWa/DU0BIs2ahRdqLOd2aOihZee+UwRYsbQ3a2qmbIxb1hC1U3oQ1ZjRm7GnkFEXKLIYmEn4zRRYp6kXofFYIEydHLB4OK0RmHf5eChOYVY2q81edWhdrCc3B4GBC3as3Fs0rFoaDXllQYowEVfcMiiJh10Yt2TqzkTGE/GeS7OkeDFD5CSfFnOFxSAjRKwKIUxklGvC4TGRSk8aIXk8bLO1NyxuQgao6roYaRWlSEWZhiIlFaAw+tpMANKeHx8Ip5Ww5NPDj1YnpPPDmFuoqMWRz1VfAMgvgnhpVwxIrn5Er2IqEkvjMnySjFT6SUnX/0HZij44tHWVkdccnu3Zx9fe+/Btr4DuvUBW1hjiTfL1IpNAKDyNiqFefN+Kbv8Wp1LaVKoSdi89Iq7/lRlc0jKJqsfW9JNi7cJ3mMPRwlrUzTtoYldokorjZxcKniO4e6DIWvfMVLSXODufU7wcE8yVZq2FDHO3xj1SeSVr0jWUE1ofL65shILC6tsG/fZW3M/ezre/uVkBJVZo5HCacxyDruuJkTzqzSHrK4WFqFKWLkyOWk6kTWLHllZhYP3UXZekRliFj4uHorBSFMzOPdFllaB8w4F0Y8sqJVXdzEaxnCaTXxMkpxBVn/uqSh9FcimuEOutQQRUrOdkU8vBo+kNcCvP45SiI0zejswjiTFodLODaUCJ21YbzgpKSICnn9rbSliCYRprOE5OTOoLg2kJHIUQYq2aMKOVVpRtpoeKoymVLpy0FbSA66UjinxRLJ7RfLGUWcyyMOzCLC6pg4uUaTmKDZa4fropFU2miNk3BaXgdSwqlLige1amVdcvr2654j9zfOvs4gWEVxVW2rNc2iHg7P7qiJiDujppTqtBSw1CDmcXRWidqA8LOtuAYTTlOQKOUZkwIrv8ZFugbqWqzSOulxZBQNOU+HLSkcNi3GAEHzyIPDGkxRF0cKCqpiKaT7i7rwWBX6ipNINbtoQHJGJjmFbEsVFNOWkWq8zjkadRzDs68zBVa5wQ2DgpAkObOsRFSiCsdJxdgZyKHm4OFbBhG4SZW373FzHUR7lKBGWIT2UieLOtTIaUQtmvsblT7txDUlkzRXIqUnk5LnHyQWBknIqDvFklxVQ2sCLBYdCcmGWnJJTvFQoRYhDYKBKhGxyQRPKLVhz29njlxMwDVaObs2zjBYFUmdxqzF3yI1l5DaTKSiaEkgrhhHEmaGmc2bNjM7mHF4o5HOi2qvXEJu3/DC/uAQEU53FokkWxDGUtVX9TLHpDkUx+tWPBYTm8kDl6jJngjy/GotAfUQclRTen11VMah47BdUUgpBJ6DFaCUEAwzJGVmN8yxYdM8m+Y3QM7Vg4kkkTE7nJ06R5VHZHEAnV0bZxysiqysefioiDCIWmQstbyYZMllKkMndX5mA//3b/w//MnnPsett97K//qz/wuriwbZd+IaXUo11m8pdFIjc12MJJGbiOIUzFzvtR1P01bOEUS9lDOPPPQQr7z6Kju2n8cVV1zuSStxaUxyiCfXa5iHgEuQ5VxCMORhUE/IVapQUGFTSqwsL/E7v/uf+eY3v86RI0eYGQ65/PLLee973su1N1xPWVnh2OICn/+jz/P+D3wgAgedOTJXRS8mDCIjXSkjZ19nCqyKrKMUT+J5mt4CK9MamAZRKhnMzczyG//2N3jowQe56aab+PrX7yUxJCWLCJLDnMoZwlwNIqc4naQySR1Mlcp5CQl8SSn8F2lT+W5YnpRqSmHvnktJOfHoY4+ShkFYyzkSSNYqjbcyXuKEEq1Z+6iuz4RAcpw6szNz/Pmf/lf+3k/+JN969GG2bd/Gvn37uPiSSzh+fIGPf/IT/Itf+iWOHDvGRz/yc+Q8OHGOYuJUPNTbWGkTY2dfZ9DiKADFG5aIppYe4KJi2qrsIQ2iwuzcLP/+t/4D9993H9u2bUO1cPPNN6Ml5F5qWNZLgl260Wruo6qMp7arllrxgFHtHyFgxeVUUggwN5W8KL7INm3eiKJs2LQRBQ5+63FyErSx4PxUiFfpGR4CdqFwRTUFT6j4Yo6SycEg8cd//F/49Gf+kBuuvx5B2LZ1G9deey2X7N5N0YZ9+/axuLTEz/7sz7Jnz+4WgnbnyKNmrhiokS23s7DqzINViaalbZQcNGXR0AbKThxIgllhbm6WT/32b3P3XXezY8cOzIwtW7byD3/mH7K4shzdiYxG8IRfKzwfLMiiYeAaxfnFI0ollMilbY4HRaNqLXnmXDJWCkVgzyWX8sSTjzOcmWPzhs0cOX6EJ558kt2790TysJCCJtBUVTypQoBGyRp98ELmrHgTl8OHD/MHf/Bp9u3bx2g04qMf/Qh7du9meWWZLENKafh3/+Hf8/xzz3HFFVcE6zeoJDFHLvDhVBlVF1FGcoSlzxrcmeVz2ABSoYTSRAlYoCl7D4eggc8Mh3zmM3/A7bffwfnnnw/Azp07+djHPkajDefMDUNhI1rwBllNVVlcWvRdNFid3quCwP7aGo5ZioYr3gekcnA8cqWklMMHSly+7woee+IgOQ3YumULh189zLPPPsPFF+9qWxRr66iH6oc60SxriBCrO82ShJQGfPozf8TevXs5duwYv/iLv8imTedw7PhxhEQjixxfXOa+b/4V5+04b1xGGwVHqXK7teZSSnTZqnUTejaSe+YtDu82mkU6HYEyYh5gFVNSHvC5P/kTPv/5P+Oiiy5sDeOhhx7i3e9+d0igyLgntYybtm/cuJFf/79+nXM2nxPKEwnJ2tJKUu0BIerZZIWmKdx11x1ITuOWXLjgGSHfLyS2bN3Cls3nUFTZunUbrx0+zPPPvsCFF1zoY8rR6kqcqGgaogiR6fYwrUfWBnOzPPLwg2zffi6X7buM7du2szJaDSq28OLLr/LRj3yEiy++mKNHj3p8S4RmtQkWLeHZV3GxqvAXGFNbZvnZ15myOEwsIq+1j0EmpdKqSKDG7Pw8n/7MZ9izZ8+a6r9zzz2X8847b90vKKXhi1/8Eu99z4+5+28lEhgS7EpXscgpuzyKKK+8dIiLd+9hkMQ1YtMIs2FIygS1pOo6hR9hZLZu386hFw6x6+JdjJrGe3lHEZEnxx37ayTzarPHJmU2JGNpyWVZLrrgQlaa1SBOehRr1wUX8NnPfg60RPbeN4Dl0QrLxxfbXuKo530oNm4qGYIHdhZXnWGLwxVhnJEq4lDDosREjZShrK5y1VVXsbS0dNpfsLo6YveuXWhxDySJdy8ySSRV1LIr1WlpT565jZs5fuwIaWbW9Y0sk5JGHsPFYES974KKMDDH+0X9NGmaEs0nvejHlFbqsu19h4euNdiBRYW5uVnX2F1aIqsXz2jxSpOl0SrLr7ziaRJlXAVnRm6VA6tgW/FkYuuE51pOefZ1Ri0OCrkMKGmsnySB2ZNAo0JZXuEjH/kon/zkJ9bUY59//vlcffVV3tpM2sLTtrZPzNiydQs33ngTy6tLkSj0uolkng/IOHFPa2mjGlu3biJnf2+tx0gdSYFg/XPs+AJZ1DsUkVhZXuDSSy9DKYg5M9ijYt4FqaiQcnFNpWxYyd5ZVYSiDeeffz5NU7j77rv50E98iIWlBVqhm5JdtsYysxtmKKPG+wCKK3VX9JSTM38tNFqrOksKn+fs68x5ydPPPF116sPochSF+C5emyFIRGQ+8YmPt7W8zz77HH//7/8kb37zAe+akw1TbwxZBbUV7yCkVW81HOycDG0kmh5KW8stVVM1VUHxCO9aFMvgnKnXXn2Nlw4dYtu554IVFldX2Lt7D6Vx/ydngvIuURIqQYyM8leSJzsju52ScMcdt/OlL93O4uIiBw68mb/7d3+C5ZXlqGly3+uVl17iV37lV7nxxhv4n/7B/8xoZTWKZizyi937SO6UR4vjFw49z00HbjprdWdKnsOakFUxjQ6exYnehdDmHtdooIWPfexjlJDc2bXrIn7zN3+Tv/rmN5zuPYrrFHXcrRaG6Ht+MYNSEFXKyHMSpp4LMNShkXmyT83afm+VKFi1/I6+eoRnn3uGrdu3oRiLSyvsufgSmlGlo9decNCkWn9hjKJGo4QAcqNOFUmmFFPe8a53ISJs3ryZ2277Iv/q4/+Kl156iY0bNoHC5z77x/yjX/gFzr/gfP7irr9kNg+pnQHaA7VoKwEKhjVB3bez2fEz7uR48qknLJNbdQ9LtaC4qkDUckZvmSXJM9Sf/OQnWxmUgwcP8lu/9VssLi4g5CASWtCVkq+TWmgURfFAiHpVXaZg9YpHtCza9bbyjeIwaSYP+NrXv8auCy6ClFg8vsieS/d4F9bIp2RxkWLNtLXX0Zpi3M8uKPBaO8DEybi0uMSv/ZtfY252luXlZR5//HEWFhYYDAZccsklbN++nYWFBd73vvdx0803U7Q5YY6INsaVGZ+Sy8+8+PwhDhw4cNbqzqSTo2BRqFOiFtuL8FMIFFA0+jQ03p8tZX7+536e5RWP7uw4b4d/Pqjpg2gmoqqIGk2IhlkqFINGjSZOBFXvEJpKQa2BQqhIBPtcFGu8GaIUb86+aX4TBeP48aPs3rMbbUY0USCF+omgRKticzHjohpL1JeHJqUpTl+36HmtpmyY38A/+6f/hAsvuojRaMT+/fu5+aabuf6GG5ifn2eQB/zMz/wDvu+W76OUZuIcWaijazFUCqWRXlHX2dcZcXI88eTjZpJoJYTa5iJjwYFKwo7MhwscZKGMCnd/7S7edMONbJyb94hTkii2DwVwAaxBZNCWt0rkARSviZBilARZw1hTLcgfh4UsKvEkpPEXFo6zcdNm12K1VjmrrfKr2lOefmg1WECdS+b6JjZuqFgpLHhgYn7DPMeOH+eRRx7m6NGjzM7NcsnFl7D3sr0cO7rg2XCxqXOU1JuqJFwsLQ0yh154nptuOutznDmL44knDPHqORt4Ew/VHPUXIeyg4pSLUK3TkHMPcaiqTeFwJVH14d2g1ZyqHmL1Xq0aelUaurBZooVCrdgLmJNrfTmtTlGKL9boA6HiDUwkh8SPiod9XUCD1EQ31VSbqsQCiSYsYhJtvdplBGY0SRhaFc2JTqbqQoGCYqc4RzUhmtOAF188C6vOLFhFzYr7jq5BIdeooZBUQg3PXD+1lOiyGBhe3dFurGqQatvpE6JKLjXeQ6HVEKoOdpwQxXMY3qXHG40UDGk80lTEe+URkvtaqScWPSrCnyBgVJXsMUtobtqGj973O8iUNCGr0zj3KciNqr7gBhqkkLZ3hYXBW0uzP5U5MhOn47SaT2dfZ8zi0Ej21cahRLzes9niESh1yEEJdZCIHCW1tr2UiF+H6Nmg0RWxrbQTV6zTKmxEkPQ6X1xlHNUKAwnZzuR1TqUEEz3V0m9DdeCD01Atz3jVYTSalOLYvwRd3YoLOlSVESxakdnIGzhqRJWiM5IFrUXR1z1HVb3x7OsMSgIGEhmTG6L/AsGXkoznMGosn+QVdC01PYWyRwqZ+mjxS9u1xHddBMvFdYdLaRuyCDky8jXWFO1QrLiUTklRo+Rqikkt1MktZEejM1UIK9RbkFQV1r1iRC17UZVEaxcpURUYcEqhiPsz0nj0rKr6IfK650gH5ezaONNODqnE1xAIIKIsVVXDosmIR1b94edsnUIoGxtRLm1OoVXwVWtVDnNTF03VeM1eUpqsbdjYRKKvsg0zDmUkKSKlI1Zcuw+NW+VWX8ePIRdSbheLjFwNBD8NBiWa1BOOe/gG5rMShUoBM78Dc+Slv+msxZ1RPkfoQbmYQY3qgI4E1QYzx+Zq3uAU9SyzVawfjd2LetMUxXtEW/SK8B50OT4T6iMaHY5QShVIEPH6h+TizVWlRIMoWFTRIjTi/kkJyCYWbFtTirijXlXNVUucHrX/t2vrWiNOlykuueNhZ1opTO/zEi20NNqhvc450qawYX4Df3XffWsoOGdf38PRqscOPmYpFG1ShlSyc5kyUQvurXSlNBGFicBU1F20WlPquk2VLlLFvzUUsVPrRIdvUCKqU6nudY83acNg1tK9MySvIHRIpeTk6iWErGfkMaM/orcPQ1rdbvdtShrXkVeyjCilqrkXVzqR6NtXhcorn+t1z1HxnNIrr77KyspS9LUIXtkayFUZPbV1g7WdWaPXfCsKYViwVySawXTeYIzJjq3av7Tq7bWPNxEKr+OQWrIs2p6I1umjN+011oSvrSfCyOrvpBaGhSp7R4e3+px0tXbbga+9le/WHMljjx70pHg4qSqCyMhLSU1c87XqzVpoCIbUjSuXgKYQcDbI4vKZskauvmrcgmhGJSRzglflSt/RtsBcMsc0t4TDksbibN4ZKSrwxJCiHnatRVFt96DIrkdttySX1K+ZE4v0dTXmFCdUFonmMcEOiJyMiLbq79+xOZJOo4ToAe6+j7WLX6r5mDe7SUGt8QaQHgk0Fd94skb9irR+XKp6KTIOr0t0lR1InKhrxkGba5LiRNRstZeGz1OTooePpjVtjMfPKuar6kNXKqq6ovugfVZEi4BoU2AaWsUhB0vQ1uJ5EJWX3605annVIkKREp1Ds3cBjRZZIeCHiIuU1V3FzBscinn72kQJ/K2RSIwFIJVHFUVNRNutCN820SvDdbAij5E1yIdGrhQMIWTjSyvCTU7MRqjUhZ4tdi6NZF9oZsVNSLZxf47sLYNTZMyl+hrRMyKpRueMyHN8p+coKqBU1GnuGCWVttNq7R8jql6LbnGaRu9AojamCm1HcUtUZDZutBqSQeoVj2hBtbgGcJETx4GXAljxZ+bs6WjtXIxRSLYq6gvDAqKGwkpSIoEM0gQnwSo1SZgp3tO8RBsJgnemMVduG+NnpbUeJ/Fdn6OBVme0hmKJTp9tljlk4iWq8qLfRirxuTJuQqPRJqgemVrPqugYlELbqf62WHSASuIdf1o2cNDMq9+SQqbexp2anKBo0fsiGMSR3EvW0ERfDRkYTSPef1oEHakLrJVEoYE09Aw+CVd/tKCwZ3IqSBn4Qygh+fnXNEeSBt8T4zj7rMZzNPjKV75KbbLT9idogVhIeNZjrdvaqsrsmESuo9Mjq6NCMq61DvwvXdzr35GihUBtKmNRm60hNh05OMfHMZQkqdN2rYtvg9LRJiSqhm0kO10BoZUBSiYtDBtLhNSuFFVwOnlo+K9xjhLfG+M4+6zGc/T/A8/G/snZpSWJAAAAAElFTkSuQmCC);
+  display: none;
+}
+
+* /deep/ quad-stack-view > #chrome-mid {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAABICAYAAADRa1RpAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFycE5v9iFQAAAQtJREFUOMvtkjGSWzEMQx/0eYrM3v8k3vgqycalSwlI8Ufyl3OBFMtGIgUCIEd6PB6RBEASqvfONSrJXrDNbNkQ8ywA2y/SmayW+ZIESTsiyQsxo40xmMS2aUmYbheHpCVd0+UqJGGMsey3mUyldoUvlY3D9rIN0K7Wbe/WbZ+y1yWtaVtrp3VJzAEX6ZVjc2p7b2mtnYhNdl6m05rwtfV/ltx7XypJTpXeO7Y5juOlchzHaWxyrJmuhLapqgIJONv05+srThBgiQpBTSRwGOr3rwccgWHUhJ7P5/YNlbd/2XiL78L/WajP240AQUihfnx84EDJjCHKHjTAbkimQDgBjAJ1/3kHAgEk/gL71AHEWVXPGQAAAABJRU5ErkJggg==);
+  display: none;
+}
+
+* /deep/ quad-stack-view > #chrome-right {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAABICAYAAACaw4eEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH3QcNFyghKmOqnQAADE1JREFUaN6dmsuyZsdRhb/M2uf07bREYDykPeIleAMibNx92i9BgEPBgyB5xlvgtgI8VDNBI41xhGkpQowERgqw3H0ue1cuBlm1T/3Vu4XNiWj9l12XrMyVK1fWL/v6668lCXdHEt/1Z2YnnyUhCTPbX8dn45pmRkR81z7/XUr59Pz8/K8ePnz47/bVV19pnDhu0t+Pmx0Z+Pv8zWv1/eZnZ2dntw8ePPizZXw4bj5/P3vq6G/eePZiX9fd9/Xng6/reg78/dInzxPG9+/auH83GjEbPUahj6m1Hoa6v1/X9c+XPrlP7INqrfuru7+10WzUkUHvOtTojPF1mPdHSzdqPPXo5vm046bdq0fhGr+bvXZk6OgAM2OZBx7hZD7hnCzbtp149Wid0YOjx+eE6t8tMzb659Ebkg5PPY8ZvXpEQWNCzck2M4H3BWeM1Fr31/6+GziPmTefM3tcYzQoIt4a3+cso2EzhsYTzAAdw9M9M3rviPv683dl/Oi9pdZKKeVk4piVRyDu1NI3mCtARFBKeWeGbtt2yHV9HXdnGUMyGjSfZq4K42ajYbPXx836XjO+jsj3rawcFx5dPgK8bzJ6eGbzI8yO3j4yaMToiWF98fl0c4bNSXBEJ/Ozd1HSEY8BLGOIxlONeCqlnHyWtGNoxteRMX38uP44fkyyPnfpp58zqy/s7jsGj0rOEcvPVaMD/sj4I/zWWllmMB/VviOwHumv+dkRGc9EOtOUu6fHZteOGBtDN/+NeJwPNRsxl54RU3PIO4x827a3wNwfdr45kib92WhAf9+fHem1I7FZa31rr+WIr45kzrjZsixvZWHHYcfqXFHGctM9ta7ridcigmVZWNf1DvyllN2wkatmHIxCby7kYzbPOD2qFCN39efrut55rE8YM3I+8VENHPFVa2VZlkOSdXe2bTuhmHdl+W5ox8T8YCbD/l2t9YQqRiNGjx8l1JEamVXKri56doyTuzfGhWd+OyLJjsNRlo+eHaX63Iy8ldnjQn3hbmA/yagGusfG7JwrxZytcxMyjpnH77VyPEEP65iVs5tntp4ldp8zlrG+x8z2Y9L1f91Jy+zeccGZn0Zv9nFHTH500BGbM6HOojMiWEZQf1cN7Aut68qyLCdeGFN+xuRYJ7tXu5fetU9EZCiPOp8xm8bTzLqpe2jkoDnzxjCOa8/VZByzzG7t8gQ4eT+GdO4Be0kZDTgq5kea/0g0RgS+rushNkbg93o6aqeejUeNR/fcUWmaqWLbtn39MdGWGcRHUrcb17E1jhszq3tvxNCsJuaE6VGZMbeMKTrL6LGelVL2k41jx6zuRbknSS9BI7WMdDRTxLi3z+VkDl3/7vb29oS3xhoZESdZOm4whrW/7/NHT83UtNze3u6c1I06Ozs7wdjc7PaQzsV8JNSOp7k97IDvtDPDYTdsvts6Pz8/MXCsm2PD2g/Tm+Vx0bHZHTNvjMyRyh2pajk/P0cIZEAHLLgXQLg5ckDCAFsKCwtIeHHAQGAmSnEkMAyZMBkin4lc3jBEM4a7MZgo7mBGhLD/+M1/qiCqDJflIjICYbknjlEtQEl81cBDYIaUi3aDwoEQ7mABuFMjcHOMQHLMRLSDhhlFQk4+k9IhLggZBREeVLN+NNwNCAhRwjGMimGyPJlA3owyIwiKEltWjTBHNchIGpLleIS5ITNKQHVDYRiBGUQI/83X/0XUyorhm2EKAsvT1IqFgwusgglCWARV3SuGmdNchwgiRHWQagcHIqCNJ7whJ6AI20AeUJ3A0ilP/vQJ33zzDdvNDbWkO91oAwphrah7wVGG1cHMqSHkggiwDJthmAcgjIIVg5rfWc1h2AZ7AgBLpMElMpQCUyOSX/3rr/j+9/+EGoEQTgKxKnDADRROmCiWySJBeILbMCxENVhwBISCnldm4EBEeiQRk1AJs/Y5ER2q7BX03v17SQnumDeXRqXgDaSA1cSdIExQDM+UgtoArTyMIjABJUPt4S2hRHEIgbdstV5LI4OusDvDMgMNqw3sHqi0HPcMotyRNqp5ArnmRrkLuBm4kHmjDAeEDMICk2PFMwomqjI2xYSHsJIUUnxoeBO7rdQUJ2qeJk8SLfdLGtgWCouEVzFUG7NXMAXVG1YqyDdMhSDgFuTpabUEiUguUw3AiAafbhoR4EtmpJknKArgytMaBHBmIozEIQ41M1dK7ySGEvxQ8NoI1w2WFh0XlsUaFYilJ5zhpuGKwBxXeygIqxlrE6Ih1wKPgi8L799/QGcJo4M5o9oYDfcKUZJmEFdX12zrikh2xwwrQA2KOeqETRlCGaKaUFXLpjQwy5Elu4dzflb4uw8/5MXP/wEsE6ORVX8hbVRzTVcN4ic/ec4HH3zA7XaTC1sQtZUXAm98Z7I7uvjii8+5ePw4pUiwu7TXuogM3cX7j/jhX/yIJz948gf/NPjll1/yy1/+E//z299RCGrL+AxI8krQfhk5Ab+6LmrGyDA1dvfkqOvXNzy7fMonn7w8umjafabmsDuowPPnz3nz5joLiN9VCwIqJDGHweixV59/weNHF4itZSMJbGq61kg3h3N2fs7D9x7jIdTwIzw3tCxrZo560U5U8frNFdu6URWJS8RmRukto3smv07uxwJrMa9uLDJCG1ZKI87AWJBvhEOsG9WEhSVcWBtu1A615da2kboiPaRW4hSRcBGEClhg0cTDycWdJR1XgUdkrN2hRqslGapydo+fffgRL37+Ir1opzrrJHZDAiB49vySv/3gp9zcRiqLCpsrjSLrnpQ27KH8/ItXPHz4PtRbRMoTajrBw6Hk4o8vLvjhj/6SH/w/wf/xx//I629/u9fPjkxLIZfVwmLwWBhQqUqgU1NZlCrkQVRwGW9urrl89pRPXr78gw27vHzO9dVVI2cIOYVIGHkrYXVDUQaPvXrFo4tHbFV7dnkjzGT+5BjXwnK/cPHovcRLI9hME3ZeM2+HtRwQAVdXb1ivr6ldzfYC3sSnPFAUZHW+HE7WtqamZL07avrcnYgKKtR6m/VKQTR9n0JQjZj7KqD2LCLY2h4quqsKNUWA5BQPatjAY1hTpuAO2iqlGLV1EQJ8C87vnfOzjz7ixS8+5vf93y+sFeZnl5f89K//htttw1bAW5d05rAK90awjOD//BUPHtynblmInXStyUHJR3jw3sV7/PjpU548eXJArvZ/gv/Fx7/g9bfftug4NfVKa7byd8pN9ZT5I9rFSM/wSPFXrOn5Tby5vubp0x/z8uU/t1Jx5/H9v3b3/q4YGJfPLrl+c0Pde8lgEWxN0znG1jG6e+zfXnHvwQNETdmMINqlSEeZJ1Dvn93j4uJiL+6jv8TQO9L6lya9f/fta26228wodVwZboFU2gLbqbqglZLarzTbdpvBEhWxNJI1bq5uuV6/SRCHt35AyAwPo5aKZzlIHRb5SqTR1nRSnitQtC4phNlyqvlTppRUlmZEQJizhCErbYSa57J8SNkLRm3s7RV54AHymjK9cYjUyg+wqV8XRCtfdzea+IZiFIoSsFKBEm1SE26SpXZCeDh7g9P64R4SrU2ZkC1btea5TMDsqCJ5UfUuZwO1BlnZ6tkgrWWWqjOgqhJmsLWa2dowsKZK0nuKlMWokWWBoBIeiJpZF6CqhtnMdHSHW6PdZLfijjISu2HX11dEjURrTza3BtymzaLV5NZwEGQYW4ekaLdCkXSDRCkidr2n/XKGUlOKjxc6oXZN0H4ZefXrVxQ3atTsjD1lkJpIDNEwlSCRZ53rp4zViNiQtqwEStHT1YoUOaclSY1MmmjXCelNz2Q1T5L/7LPPYDEePXqYNa0ENHnd7xeKKUFiAO2HBM97DZMoS1prMmQLrqCE8uZHIgVDNAFpFEW7BnGKWQtnYJ6GOmL54+99D0JEzfT1alRzikHtda+1/4nsxk/VqQZmlXXzJMUiqFu7nrJMe8v2LhteteuAvEcrVqk1m+Owdn9h7ZYSE6WAIrkjPCVIFua8s0jhWHfhZ5YZZ6rZNxoplZp3clg2uUSKAcmwYpgqUs1iFI5Z4rr3mliq3IVqVDbwM9CGkao1rN1IR6F4xepCEFht1wAhIKjRNH0Dv6ym5lHrEQw8JSlUtapghHJ+qiK13OyZ6yyf/sunSYqyVuPavVVq3bvSgrKxcKVGU7/s1U5ovXz1W5v9ftPVet68cbSehRo65ZNfUuB/AWHLchVUWJtFAAAAAElFTkSuQmCC);
+  display: none;
+}
+</style><template id="quad-stack-view-template">
+  <div id="header"></div>
+  <input id="stacking-distance-slider" max="400" min="1" step="1" type="range"/>
+  
+  <canvas id="canvas"></canvas>
+  <img id="chrome-left"/>
+  <img id="chrome-mid"/>
+  <img id="chrome-right"/>
+</template><style>
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view {
+  position: relative;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > top-controls {
+  -webkit-flex: 0 0 auto;
+  background-image: -webkit-gradient(linear,
+                                     0 0, 100% 0,
+                                     from(#E5E5E5),
+                                     to(#D1D1D1));
+  border-bottom: 1px solid #8e8e8e;
+  border-top: 1px solid white;
+  display: flex;
+  flex-flow: row wrap;
+  flex-direction: row;
+  font-size:  14px;
+  padding-left: 2px;
+  overflow: hidden;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view >
+      top-controls input[type='checkbox'] {
+  vertical-align: -2px;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > .what-rasterized {
+  color: -webkit-link;
+  cursor: pointer;
+  text-decoration: underline;
+  position: absolute;
+  bottom: 10px;
+  left: 10px;
+}
+
+* /deep/ tr-ui-e-chrome-cc-layer-tree-quad-stack-view > #input-event {
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMnwAADJ8BPja39wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAyNSURBVHic7Z1PTCPXHcc/4wWWVbJN2cJSLVqiQJuGpoIGEVWReoBNIlIF5RCRSysOK9EbksUeOHLIIQcULbLEEYk7oqduD6gSRoqUEyK7dCOabOHghCiAE/JntQtesHt4fuM3z2+MZzy2x8ZfaTTjN+Px4/fh9/7Pb6xMJkND4VGk2hloyKkGkJCpASRkagAJmRpAQqYGkJCpASRkaqp2BvzKsizf3w1z38sKc+ZUaQCuAFeB57P7q4AF/Kxsj4GnLrfL+6PDYofQAskCaAJ6gJeB6+QAFOvZpwgwPwOHwCNgN5uu/+H252raJHRALMu6ggDwCtALNAf8E88QUL5AAHqSTVcNUTU4oQBiWVYzMIiA0E3lGhtp4CsEnPtACgFDGqXiYKoKxLKsCPAaMIwojlzV1tZGV1cXHR0ddHR00N7ebh93dHQAcHh4aG/JZNI+3tvb4+jo6LzsPAY+QYA5Ix9KBsoPpmpALMt6BXgTaHe7pre3l5GREUZGRujv7/fdsspkMmxtbRGPx4nH4+zs7BS6/HtgHfgvOW9xeE05bVZxIJZldQNvATf1c5FIhMHBQYaHh7l16xbd3d1lyUMikWBtbY319XU2NzdJp9Omy74B1oAEAoa8yIZTDttVDIhlWZeB94Dfm86Pjo4SjUbLBsFNiUSCWCzG6uqq2yVfAv9CNKHTlNlbKgLEsqxrwF+BX+nnhoaGuHPnDv39/WXPRyFtbW1x9+5dNjY2TKePgBXgOwQUFUyg3lJ2IJZl9QAfAK1qek9PD9PT04yMjJT1970qHo8zPz/P7u6ufuoE+CewQw6Kw2OCsGVZgViW9SdgFNGLBqC1tZWZmRnGx8eJRMI5lJZOp1lZWWFubo7j42P1VAZR4W8gWmJn5KBAAEVYWYBkm7PvIvoWtjo7O1lYWKCvry/w3yyHtre3mZqaYn9/Xz/1EPg3ot+iQslQIpTAgWRh/A0x5GFrYGCAWCxGe7trKzeUSiaTRKNRHjx4oJ/6CvgHoigLDEo5yox30WCMjY2xtLRUczAA2tvbWVpaYmxsTD91E3gbMbTTBFxCFM0WYPntMwXqIdk64x3lM9FolMnJycB+o5paXFwkFovplfcniDrlNLvJXr4vTwnMQ7KtqVE1rZ5gAExOThKNRvXkPyMGQaWXlOQpgQDJ9jM+QGlNjY2N1RUMqcnJSb34shClwnVE8aVCAY9QSi6ysj3wv6N0+gYGBlhaWqKlpaWke4dVqVSK27dv6xX9j8AyYpDyGaL4svsqxdo5CA95DwVGZ2cnsVisbmEAtLS0EIvF6OzsVJNfQIzRlVTJlwQkO1Boj021traysLBQk60pr2pvb2dhYYHWVscAxEuI1pcKJYIHKKV6yFvqh5mZmZrp9AWhvr4+ZmZm9OQ3MAMpSr6BZOcz7CH0np4exsfH/d6uZjU+Pk5Pj6PbdR34LT69xBeQbG/8TTVteno6tGNT5VQkEmF6elpPfh24TK7VFaFIKH4t+BrKTN/Q0FDoRm0rqZGREYaGhtSkXyDqVs9Fl2cg2QUJw2ranTt3vN6m7mSwwR8R68dULzm31eXHQwZRFiSMjo5WfXIpDOrv72d01DFQcQXoQ3hI0V7iB8gr9pcjEdNQwoVVNBrV69EXcanccfEST0Cyi9jsSe/BwcGKz4GHWd3d3QwOOqaAOoDnMFfuRnn1kJfV7wwPD3v8ev1Ls4mF+Ac2FVsW5C8aLxpI9ou/U9Nu3brlOcP1LoNNbuJej+R5ihcPaQJ+Iz/09vY2iiuDuru76e3tVZN+jeiTyFHggsWWFyA9KAufL3K/4zxptrkE3MClYkcDUxQQU3HVAOIug226yHlIXvNXrUe8eEiHPGhra2v0PQqov7+ftrY2NekFzEVWSXWI3Rns6uoq6ZGyepdlWXR1dalJrRTwEFVegFyVB3L5f0Pu0mzUirC1CsPoJcUCuYLyGFkDyPnSbBQhB8VUZNm99nOBZC+8qqZdhBnBUmWw0RXMQHx5iOPpprB5yMbGBp999lm1s+GQwUZXKFBUSRULxOEhYQNy//59Hj58WO1sOOQCpGAfBOoESBhVwENMm61in/cOXRt3f3+f09NTAH766SdaWlrY29sDoLm5mevXr1cze25y9QypYoH8rH44PDwsIU/B6KOPPrLzcXBwQCQS4dNPPwXgxo0bfPzxx9XMnslGJ7h7hkX2GZOaBRKLxezjxcVFLl++zMTERBVz5JTBRseGy3zXIaEDEna5eAgENIX7WP2QTCaL/NrFlcFG0kMKLvIttsh6ilg83ATh85D3338/dGNrmo3SiAXYuvLgeImX9Rj4peHHqq5r165VOwt50mx0gjkqhJT92cvgol2P7O3thSa+VBiVyWTsJnhWsv4wBrZR5QWIjfzo6IitrS0vebxQ2tra0oPdPCbfQ4ze4gXII/VDPB73k9cLIYNtDnACUJ9td8gLkF2UiqkBxF2abc6AJOboD3lQzgWi1BWnCCgA7OzskEgk/Oa5bpVIJPTwT9+RCymoe4jvIkt+8Qs1cW1tzVem61kGm8jiKk1+gIE8eV25+Ihc3CjW19c9fr3+pdkkgwCiwsiL+oDyUKhXIE8QISUA2NzcbBRbihKJBJubm2rSD4h4KLLuOMMQRUiVn9XvdrGVTqcdg3wXXbFYTI9Op3qHuqlQHCoKSNadJNH7KGNbq6urjT4Jou+hRaVLIUoTE4zA6hD5Q5+oCXfv3vVxm/qSwQY7iG6C9BAZByWv6auOevgBIr3ke5mwsbFxofsl8XhcDw34BPgaYXg1KI0p6JlDRQPRiq0zRGQ1W/Pz827RPeta6XSa+fl5Pfl/5LxC3QrCAP9P4WYQcW2/kQm7u7usrKz4vF3tamVlRY/P+CPwLTlvcANiDN/kCYjiJXLv6AXNzc2xvb3t5ZY1re3tbebm5vRk2Vc7JReExgTDqFI8JIMIMvylTDw+PmZqaupCzCgmk0mmpqb0IJkHiLpV9Ypn5MA4oJimMDwD0eqSDCLIsD3WvL+/TzQaJZVKeb11zSiVShGNRvXgmE+Az8kVU8+UrSjvgNKCz8jxmaeIIMNyEoYHDx4wOztbwq3DrdnZWT1W1imi5XmCE0YKlyLLbYLPFxDlZhLKd4ggw/aJe/fusbi46Of2odbi4iL37t1TkzLAfxAzqmc4PcPkIQVVqofIfRrREVpXL4jFYnUFRQbB1PQIMZsqYaSUraiWlaqSQvxlV3rIFd2XEIsm/gL8Qb1ubGyMDz/8sGajzKVSKWZnZ3XPANHs/xxh+BSiyDrObifkirCiiisIDogK5TIwjvY6ijoMpHwEbCJAPCMHQIWhxl4sKmxsEEEwwQmlCQHlbeBV9do6CjX+DbBNDobqHSYYRQfCLDnimKEZfJbN0CpiENLOxf7+PhMTEywvL4d6mCWdTrO8vMzExIQOI4Pod31OPowTzHWHpz80kMjWyqpB6SXSU5oRQYbfARwVSA2+ruIU0ZrSK/ATnEBky8oxqlusnQMLNa4VXRa5Sr4JEYdwDPG8tkM18kKXJ+TmgWQ/Q3qDDsNTJa4r6NjvkA/lEsJTnkdEMX3J9N0Qv/LoAFFEyRaTbFFJGPK4ZBhQntdVgDuUZkTr6w2E1zgUspeC/YjoY3yPczgkZdhk568kGFC+F7qAE4qsU2S90owIpfo6ImCkUVV6bd4TxHzGtzgnmNThEN0rHK0pSngFUtleeeQCRa1XmhHN41eBAcRDka6qwIslU4jRhq/Jn8tQh0HUitttWtb3YvRyv4MKck8MyUeCZRGmeosMGPkiIshNpR72yCCW6hwgFiTI1pE0tDS6abDQ87BIMarEW9rAGUFNNot1MHL/HCIs3k1E8K9LAWfpDDEYepDd5Lopdc5b9Qx9r14nx/EgABhQASCQ109RizAdjApH9vhvIOJNvYCIFyJjhhSjNLlm6WMEgCS5tbbqAjbTlKsKwwTCHmCtmfcY2j/khCL3auwPNXyRGqOwifzQRq2IYk7dwDl8cYwwpjoqrRrSDYYKpdCaqpLrC5Oq8S5c+xCzx+hwTJtbEBdT3aMbUBpVXWvrtsnz+op1CNArVFXlbdEu3mICowJS9+cBsR/Exx2IaQG0af1tHggI1itUVft96vahsi/kOabPxQCRe93IaW3TAVQMhFRVgdiZMIORexOgQiDkXv3DdAObPMYIgAqBkAoFECmtJ+4Gp9Ax2rEORe51w+sQ7OOK17FhAqLKBY567AbBTSY4rsfVsktogagqACfvUpd0tz/SkR4GW9QEEFVBhtAI499ec0DqXf8H8f4X10jf2YAAAAAASUVORK5CYII=);
+  display: none;
+}
+</style><template id="tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template">
+  <img id="input-event"/>
+</template><style>
+* /deep/ tr-ui-e-chrome-cc-layer-view{-webkit-flex-direction:column;display:-webkit-flex;left:0;position:relative;top:0}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-tree-quad-stack-view{-webkit-flex:1 1 100%;-webkit-flex-direction:column;min-height:0;display:-webkit-flex;width:100%}* /deep/tr-ui-e-chrome-cc- layer-view>tr-ui-e-chrome-cc-layer-view-analysis{height:150px;overflow-y:auto}* /deep/ tr-ui-e-chrome-cc-layer-view>tr-ui-e-chrome-cc-layer-view-analysis *{-webkit-user-select:text}
+</style><style>
+* /deep/ .tr-ui-e-chrome-cc-lthi-s-view{-webkit-flex:1 1 auto!important;-webkit-flex-direction:row;display:-webkit-flex}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>tr-ui-e-chrome-cc-layer-picker{-webkit-flex:1 1 auto}* /deep/ .tr-ui-e-chrome-cc-lthi-s-view>x-drag-handle{-webkit-flex:0 0 auto}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view{-webkit-flex:0 0 auto;font-size:0;margin:0;min-height:200px;min-width:200px;overflow:hidden;padding:0}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-summary-view.hidden{display:none}
+</style><style>
+* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view{display:block;height:180px;margin:0;padding:0;position:relative}* /deep/ tr-ui-e-chrome-cc-picture-ops-chart-view>.use-percentile-scale{left:0;position:absolute;top:0}
+</style><template id="tr-ui-e-chrome-cc-picture-debugger-template">
+  <style>
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger {
+    -webkit-flex: 1 1 auto;
+    -webkit-flex-direction: row;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > tr-ui-a-generic-object-view {
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+    width: 400px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel {
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+    min-width: 300px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel > picture-info {
+    -webkit-flex: 0 0 auto;
+    padding-top: 2px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > left-panel >
+        picture-info .title {
+    font-weight: bold;
+    margin-left: 5px;
+    margin-right: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > x-drag-handle {
+    -webkit-flex: 0 0 auto;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger .filename {
+    -webkit-user-select: text;
+    margin-left: 5px;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel {
+    -webkit-flex: 1 1 auto;
+    -webkit-flex-direction: column;
+    display: -webkit-flex;
+  }
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger > right-panel >
+        tr-ui-e-chrome-cc-picture-ops-chart-view {
+    min-height: 150px;
+    min-width : 0;
+    overflow-x: auto;
+    overflow-y: hidden;
+  }
+
+  /*************************************************/
+
+  * /deep/ tr-ui-e-chrome-cc-picture-debugger raster-area {
+    background-color: #ddd;
+    min-height: 200px;
+    min-width: 200px;
+    overflow-y: auto;
+    padding-left: 5px;
+  }
+  </style>
+
+  <left-panel>
+    <picture-info>
+      <div>
+        <span class="title">Skia Picture</span>
+        <span class="size"></span>
+      </div>
+      <div>
+        <input class="filename" type="text" value="skpicture.skp"/>
+        <button class="export">Export</button>
+      </div>
+    </picture-info>
+  </left-panel>
+  <right-panel>
+    <tr-ui-e-chrome-cc-picture-ops-chart-view>
+    </tr-ui-e-chrome-cc-picture-ops-chart-view>
+    <raster-area><canvas></canvas></raster-area>
+  </right-panel>
+</template><style>
+* /deep/ .tr-ui-e-chrome-cc-picture-snapshot-view{-webkit-flex:0 1 auto!important;display:-webkit-flex}
+</style><polymer-element name="tr-ui-e-chrome-cc-raster-task-view">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+    }
+    #heading {
+      flex: 0 0 auto;
+    }
+    </style>
+
+    <div id="heading">
+      Rasterization costs in
+      <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link>
+    </div>
+    <tr-ui-b-table id="content"></tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><style>
+.tr-ui-e-chrome-gpu-state-snapshot-view{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAEwATABMYqp3KAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90JCQsBMCH7ZqYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAUElEQVRYw+3WwQkAIAiF4Vc0hTO5/wiuURvYIcQOv1cRPhDlDXffSsrMsrYiQi/zU80FAACAVX3nt3lWAABA/x+ovnPyAAAA5AHyAAAA3wMOd34Xd+lsglgAAAAASUVORK5CYII=);display:-webkit-flex;overflow:auto}.tr-ui-e-chrome-gpu-state-snapshot-view img{display:block;margin:16px auto 16px auto}
+</style><style>
+.tr-ui-e-system-stats-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-system-stats-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-system-stats-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}
+</style><style>
+.tr-ui-e-system-stats-instance-track{height:500px}.tr-ui-e-system-stats-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
+</style><style>
+.tr-ui-e-tcmalloc-instance-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-tcmalloc-instance-view #args{white-space:pre}.tr-ui-e-tcmalloc-instance-view #snapshots>*{display:block}.tr-ui-e-tcmalloc-instance-view{overflow:auto}.tr-ui-e-tcmalloc-instance-view *{-webkit-user-select:text}.tr-ui-e-tcmalloc-instance-view .title{border-bottom:1px solid rgb(128,128,128);font-size:110%;font-weight:bold}.tr-ui-e-tcmalloc-instance-view td,.tr-ui-e-tcmalloc-instance-view th{font-size:small;text-align:right}
+</style><style>
+.tr-ui-e-tcmalloc-heap-snapshot-view .subhead{font-size:small;padding-bottom:10px}.tr-ui-e-tcmalloc-heap-snapshot-view ul{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;font-family:monospace;list-style:none;margin:0;padding-left:15px}.tr-ui-e-tcmalloc-heap-snapshot-view li{background-position:0 5px;background-repeat:no-repeat;cursor:pointer;list-style:none;margin:0;padding-left:15px}.tr-ui-e-tcmalloc-heap-snapshot-view .collapsed{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAMAAADz0U65AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAwBQTFRFAAAAVVVVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASd3+7gAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjbQg61aAAAAGklEQVQYV2P4//8/IyOQYMBkMEIBA5yBWzEAD3Mj+VR5R78AAAAASUVORK5CYII=)}.tr-ui-e-tcmalloc-heap-snapshot-view .expanded{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuNtCDrVoAAAAoSURBVChTY2CgKggNDVUHYnsUQ4EC//FhBoIKkI0DKlYAYhmqupsBAMwgJH8K5nKoAAAAAElFTkSuQmCC)}.tr-ui-e-tcmalloc-heap-snapshot-view .trace-bytes{display:inline-block;padding-right:10px;text-align:right;width:80px}.tr-ui-e-tcmalloc-heap-snapshot-view .trace-allocs{display:inline-block;padding-right:10px;text-align:right;width:120px}.tr-ui-e-tcmalloc-heap-snapshot-view .trace-name{display:inline-block}
+</style><style>
+.tr-ui-e-tcmalloc-heap-instance-track{height:150px}.tr-ui-e-tcmalloc-heap-instance-track ul{list-style:none;list-style-position:outside;margin:0;overflow:hidden}
+</style><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-category-summary-side-panel">
+  <template>
+    <style>
+    :host {
+      display: block;
+      width: 450px;
+      overflow-x: auto;
+    }
+    </style>
+
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+  </template>
+
+  
+</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-input-latency-side-panel">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      display: flex;
+    }
+    toolbar {
+      flex: 0 0 auto;
+      border-bottom: 1px solid black;
+      display: flex;
+    }
+    result-area {
+      flex: 1 1 auto;
+      display: block;
+      min-height: 0;
+      overflow-y: auto;
+    }
+    </style>
+
+    <toolbar id="toolbar"></toolbar>
+    <result-area id="result_area"></result-area>
+  </template>
+
+  
+</polymer-element><style>
+* /deep/ .pie-chart .arc-text{font-size:8pt}* /deep/ .pie-chart .label{font-size:10pt}* /deep/ .pie-chart polyline{fill:none;stroke:black}
+</style><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-time-summary-side-panel">
+  <template>
+    <style>
+    :host {
+      flex-direction: column;
+      display: flex;
+    }
+    toolbar {
+      flex: 0 0 auto;
+      border-bottom: 1px solid black;
+      display: flex;
+    }
+    result-area {
+      flex: 1 1 auto;
+      display: block;
+      min-height: 0;
+      overflow-y: auto;
+    }
+    </style>
+
+    <toolbar id="toolbar"></toolbar>
+    <result-area id="result_area"></result-area>
+  </template>
+
+  
+</polymer-element><polymer-element name="tr-ui-e-rail-rail-score-span">
+  <template>
+  <style>
+    :host {
+      display: span;
+    }
+  </style>
+  <span id="content">
+    <span>RAIL Score: </span><span id="score"></span>
+  </span>
+  </template>
+  
+</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-rail-rail-score-side-panel">
+  <template>
+    <style>
+    :host {
+      display: flex;
+      flex-direction: column;
+      width: 450px;
+      overflow-x: auto;
+    }
+
+    #score {
+      background-color: rgb(236, 236, 236)
+      flex: 0 0 auto;
+    }
+
+    #content {
+      min-width: 0;
+      flex-direction: column;
+      display: flex;
+      flex: 1 1 auto;
+    }
+
+    #coverage {
+      font-size: 10px;
+    }
+    </style>
+
+    <tr-ui-e-rail-rail-score-span id="score"></tr-ui-e-rail-rail-score-span>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
+
+    <div id="coverage">
+      <b>Coverage:</b><br/>
+      <tr-ui-a-analysis-link id="associated-events"></tr-ui-a-analysis-link><br/>
+      <tr-ui-a-analysis-link id="unassociated-events"></tr-ui-a-analysis-link>
+    </div>
+    <button id="test">Create Test</button>
+  </template>
+</polymer-element><polymer-element extends="tr-ui-side-panel" name="tr-ui-e-s-alerts-side-panel">
+  <template>
+    <style>
+    :host {
+      display: block;
+      width: 250px;
+    }
+    #content {
+      flex-direction: column;
+      display: flex;
+    }
+    </style>
+
+    <div id="content">
+      <toolbar id="toolbar"></toolbar>
+      <result-area id="result_area"></result-area>
+    </div>
+  </template>
+
+  
+</polymer-element><script>
+
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/* WARNING: This file is auto generated.
+ *
+ * Do not edit directly.
+ */
+
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+window.PolymerGestures={},function(a){var b=!1,c=document.createElement("meta");if(c.createShadowRoot){var d=c.createShadowRoot(),e=document.createElement("span");d.appendChild(e),c.addEventListener("testpath",function(a){a.path&&(b=a.path[0]===e),a.stopPropagation()});var f=new CustomEvent("testpath",{bubbles:!0});document.head.appendChild(c),e.dispatchEvent(f),c.parentNode.removeChild(c),d=e=null}c=null;var g={shadow:function(a){return a?a.shadowRoot||a.webkitShadowRoot:void 0},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);return this.canTarget(b)?b:void 0},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){var d,e;return a?(d=a.elementFromPoint(b,c),d?e=this.targetingShadow(d):a!==document&&(e=this.olderShadow(a)),this.searchRoot(e,b,c)||d):void 0},owner:function(a){if(!a)return document;for(var b=a;b.parentNode;)b=b.parentNode;return b.nodeType!=Node.DOCUMENT_NODE&&b.nodeType!=Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){if(b&&a.path&&a.path.length)return a.path[0];var c=a.clientX,d=a.clientY,e=this.owner(a.target);return e.elementFromPoint(c,d)||(e=document),this.searchRoot(e,c,d)},findTouchAction:function(a){var c;if(b&&a.path&&a.path.length){for(var d=a.path,e=0;e<d.length;e++)if(c=d[e],c.nodeType===Node.ELEMENT_NODE&&c.hasAttribute("touch-action"))return c.getAttribute("touch-action")}else for(c=a.target;c;){if(c.nodeType===Node.ELEMENT_NODE&&c.hasAttribute("touch-action"))return c.getAttribute("touch-action");c=c.parentNode||c.host}return"auto"},LCA:function(a,b){if(a===b)return a;if(a&&!b)return a;if(b&&!a)return b;if(!b&&!a)return document;if(a.contains&&a.contains(b))return a;if(b.contains&&b.contains(a))return b;var c=this.depth(a),d=this.depth(b),e=c-d;for(e>=0?a=this.walk(a,e):b=this.walk(b,-e);a&&b&&a!==b;)a=a.parentNode||a.host,b=b.parentNode||b.host;return a},walk:function(a,b){for(var c=0;a&&b>c;c++)a=a.parentNode||a.host;return a},depth:function(a){for(var b=0;a;)b++,a=a.parentNode||a.host;return b},deepContains:function(a,b){var c=this.LCA(a,b);return c===a},insideNode:function(a,b,c){var d=a.getBoundingClientRect();return d.left<=b&&b<=d.right&&d.top<=c&&c<=d.bottom},path:function(a){var c;if(b&&a.path&&a.path.length)c=a.path;else{c=[];for(var d=this.findTarget(a);d;)c.push(d),d=d.parentNode||d.host}return c}};a.targetFinding=g,a.findTarget=g.findTarget.bind(g),a.deepContains=g.deepContains.bind(g),a.insideNode=g.insideNode}(window.PolymerGestures),function(){function a(a){return"html /deep/ "+b(a)}function b(a){return'[touch-action="'+a+'"]'}function c(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+";}"}var d=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]},"manipulation"],e="",f="string"==typeof document.head.style.touchAction,g=!window.ShadowDOMPolyfill&&document.head.createShadowRoot;if(f){d.forEach(function(d){String(d)===d?(e+=b(d)+c(d)+"\n",g&&(e+=a(d)+c(d)+"\n")):(e+=d.selectors.map(b)+c(d.rule)+"\n",g&&(e+=d.selectors.map(a)+c(d.rule)+"\n"))});var h=document.createElement("style");h.textContent=e,document.head.appendChild(h)}}(),function(a){var b=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","pageX","pageY"],c=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0],d=function(){return function(){}},e={preventTap:d,makeBaseEvent:function(a,b){var c=document.createEvent("Event");return c.initEvent(a,b.bubbles||!1,b.cancelable||!1),c.preventTap=e.preventTap(c),c},makeGestureEvent:function(a,b){b=b||Object.create(null);for(var c,d=this.makeBaseEvent(a,b),e=0,f=Object.keys(b);e<f.length;e++)c=f[e],"bubbles"!==c&&"cancelable"!==c&&(d[c]=b[c]);return d},makePointerEvent:function(a,d){d=d||Object.create(null);for(var e,f=this.makeBaseEvent(a,d),g=2;g<b.length;g++)e=b[g],f[e]=d[e]||c[g];f.buttons=d.buttons||0;var h=0;return h=d.pressure?d.pressure:f.buttons?.5:0,f.x=f.clientX,f.y=f.clientY,f.pointerId=d.pointerId||0,f.width=d.width||0,f.height=d.height||0,f.pressure=h,f.tiltX=d.tiltX||0,f.tiltY=d.tiltY||0,f.pointerType=d.pointerType||"",f.hwTimestamp=d.hwTimestamp||0,f.isPrimary=d.isPrimary||!1,f._source=d._source||"",f}};a.eventFactory=e}(window.PolymerGestures),function(a){function b(){if(c){var a=new Map;return a.pointers=d,a}this.keys=[],this.values=[]}var c=window.Map&&window.Map.prototype.forEach,d=function(){return this.size};b.prototype={set:function(a,b){var c=this.keys.indexOf(a);c>-1?this.values[c]=b:(this.keys.push(a),this.values.push(b))},has:function(a){return this.keys.indexOf(a)>-1},"delete":function(a){var b=this.keys.indexOf(a);b>-1&&(this.keys.splice(b,1),this.values.splice(b,1))},get:function(a){var b=this.keys.indexOf(a);return this.values[b]},clear:function(){this.keys.length=0,this.values.length=0},forEach:function(a,b){this.values.forEach(function(c,d){a.call(b,c,this.keys[d],this)},this)},pointers:function(){return this.keys.length}},a.PointerMap=b}(window.PolymerGestures),function(a){var b,c=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which","pageX","pageY","timeStamp","preventTap","tapPrevented","_source"],d=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0,function(){},!1],e="undefined"!=typeof SVGElementInstance,f=a.eventFactory,g={IS_IOS:!1,pointermap:new a.PointerMap,requiredGestures:new a.PointerMap,eventMap:Object.create(null),eventSources:Object.create(null),eventSourceList:[],gestures:[],dependencyMap:{down:{listeners:0,index:-1},up:{listeners:0,index:-1}},gestureQueue:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},registerGesture:function(a,b){var c=Object.create(null);c.listeners=0,c.index=this.gestures.length;for(var d,e=0;e<b.exposes.length;e++)d=b.exposes[e].toLowerCase(),this.dependencyMap[d]=c;this.gestures.push(b)},register:function(a,b){for(var c,d=this.eventSourceList.length,e=0;d>e&&(c=this.eventSourceList[e]);e++)c.register.call(c,a,b)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;c>d&&(b=this.eventSourceList[d]);d++)b.unregister.call(b,a)},down:function(a){this.requiredGestures.set(a.pointerId,b),this.fireEvent("down",a)},move:function(a){a.type="move",this.fillGestureQueue(a)},up:function(a){this.fireEvent("up",a),this.requiredGestures["delete"](a.pointerId)},cancel:function(a){a.tapPrevented=!0,this.fireEvent("up",a),this.requiredGestures["delete"](a.pointerId)},addGestureDependency:function(a,b){var c=a._pgEvents;if(c&&b)for(var d,e,f,g=Object.keys(c),h=0;h<g.length;h++)f=g[h],c[f]>0&&(d=this.dependencyMap[f],e=d?d.index:-1,b[e]=!0)},eventHandler:function(c){var d=c.type;if("touchstart"===d||"mousedown"===d||"pointerdown"===d||"MSPointerDown"===d)if(c._handledByPG||(b={}),this.IS_IOS){var e=c;if("touchstart"===d){var f=c.changedTouches[0];e={target:c.target,clientX:f.clientX,clientY:f.clientY,path:c.path}}for(var g,h=c.path||a.targetFinding.path(e),i=0;i<h.length;i++)g=h[i],this.addGestureDependency(g,b)}else this.addGestureDependency(c.currentTarget,b);if(!c._handledByPG){var j=this.eventMap&&this.eventMap[d];j&&j(c),c._handledByPG=!0}},listen:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.addEvent(a,c)},unlisten:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.removeEvent(a,c)},addEvent:function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(a,b){var c=f.makePointerEvent(a,b);return c.preventDefault=b.preventDefault,c.tapPrevented=b.tapPrevented,c._target=c._target||b.target,c},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var b,f=Object.create(null),g=0;g<c.length;g++)b=c[g],f[b]=a[b]||d[g],("target"===b||"relatedTarget"===b)&&e&&f[b]instanceof SVGElementInstance&&(f[b]=f[b].correspondingUseElement);return f.preventDefault=function(){a.preventDefault()},f},dispatchEvent:function(a){var b=a._target;if(b){b.dispatchEvent(a);var c=this.cloneEvent(a);c.target=b,this.fillGestureQueue(c)}},gestureTrigger:function(){for(var a,b,c=0;c<this.gestureQueue.length;c++)if(a=this.gestureQueue[c],b=a._requiredGestures)for(var d,e,f=0;f<this.gestures.length;f++)b[f]&&(d=this.gestures[f],e=d[a.type],e&&e.call(d,a));this.gestureQueue.length=0},fillGestureQueue:function(a){this.gestureQueue.length||requestAnimationFrame(this.boundGestureTrigger),a._requiredGestures=this.requiredGestures.get(a.pointerId),this.gestureQueue.push(a)}};g.boundHandler=g.eventHandler.bind(g),g.boundGestureTrigger=g.gestureTrigger.bind(g),a.dispatcher=g,a.activateGesture=function(a,b){var c=b.toLowerCase(),d=g.dependencyMap[c];if(d){var e=g.gestures[d.index];if(a._pgListeners||(g.register(a),a._pgListeners=0),e){var f,h=e.defaultActions&&e.defaultActions[c];switch(a.nodeType){case Node.ELEMENT_NODE:f=a;break;case Node.DOCUMENT_FRAGMENT_NODE:f=a.host;break;default:f=null}h&&f&&!f.hasAttribute("touch-action")&&f.setAttribute("touch-action",h)}a._pgEvents||(a._pgEvents={}),a._pgEvents[c]=(a._pgEvents[c]||0)+1,a._pgListeners++}return Boolean(d)},a.addEventListener=function(b,c,d,e){d&&(a.activateGesture(b,c),b.addEventListener(c,d,e))},a.deactivateGesture=function(a,b){var c=b.toLowerCase(),d=g.dependencyMap[c];return d&&(a._pgListeners>0&&a._pgListeners--,0===a._pgListeners&&g.unregister(a),a._pgEvents&&(a._pgEvents[c]>0?a._pgEvents[c]--:a._pgEvents[c]=0)),Boolean(d)},a.removeEventListener=function(b,c,d,e){d&&(a.deactivateGesture(b,c),b.removeEventListener(c,d,e))}}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d=25,e=[0,1,4,2],f=0,g=/Linux.*Firefox\//i,h=function(){if(g.test(navigator.userAgent))return!1;try{return 1===new MouseEvent("test",{buttons:1}).buttons}catch(a){return!1}}(),i={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup"],exposes:["down","up","move"],register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},lastTouches:[],isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,e=a.clientX,f=a.clientY,g=0,h=c.length;h>g&&(b=c[g]);g++){var i=Math.abs(e-b.x),j=Math.abs(f-b.y);if(d>=i&&d>=j)return!0}},prepareEvent:function(a){var c=b.cloneEvent(a);if(c.pointerId=this.POINTER_ID,c.isPrimary=!0,c.pointerType=this.POINTER_TYPE,c._source="mouse",!h){var d=a.type,g=e[a.which]||0;"mousedown"===d?f|=g:"mouseup"===d&&(f&=~g),c.buttons=f}return c},mousedown:function(d){if(!this.isEventSimulatedFromTouch(d)){var e=(c.has(this.POINTER_ID),this.prepareEvent(d));e.target=a.findTarget(d),c.set(this.POINTER_ID,e.target),b.down(e)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var d=c.get(this.POINTER_ID);if(d){var e=this.prepareEvent(a);e.target=d,0===(h?e.buttons:e.which)?(h||(f=e.buttons=0),b.cancel(e),this.cleanupMouse(e.buttons)):b.move(e)}}},mouseup:function(d){if(!this.isEventSimulatedFromTouch(d)){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(this.POINTER_ID),b.up(e),this.cleanupMouse(e.buttons)}},cleanupMouse:function(a){0===a&&c["delete"](this.POINTER_ID)}};a.mouseEvents=i}(window.PolymerGestures),function(a){var b=a.dispatcher,c=(a.targetFinding.allShadows.bind(a.targetFinding),b.pointermap),d=(Array.prototype.map.call.bind(Array.prototype.map),2500),e=25,f=200,g=20,h=!1,i={IS_IOS:!1,events:["touchstart","touchmove","touchend","touchcancel"],exposes:["down","up","move"],register:function(a,c){(this.IS_IOS?c:!c)&&b.listen(a,this.events)},unregister:function(a){this.IS_IOS||b.unlisten(a,this.events)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y"},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return b===c.EMITTER?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":"XY"},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){(0===c.pointers()||1===c.pointers()&&c.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.firstTarget=a.target,this.scrolling=null,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,f)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return("touchstart"===a||"touchmove"===a)&&(b=1),b},findTarget:function(b,d){if("touchstart"===this.currentTouchEvent.type){if(this.isPrimaryTouch(b)){var e={clientX:b.clientX,clientY:b.clientY,path:this.currentTouchEvent.path,target:this.currentTouchEvent.target};return a.findTarget(e)}return a.findTarget(b)}return c.get(d)},touchToPointer:function(a){var c=this.currentTouchEvent,d=b.cloneEvent(a),e=d.pointerId=a.identifier+2;d.target=this.findTarget(a,e),d.bubbles=!0,d.cancelable=!0,d.detail=this.clickCount,d.buttons=this.typeToButtons(c.type),d.width=a.webkitRadiusX||a.radiusX||0,d.height=a.webkitRadiusY||a.radiusY||0,d.pressure=a.webkitForce||a.force||.5,d.isPrimary=this.isPrimaryTouch(a),d.pointerType=this.POINTER_TYPE,d._source="touch";var f=this;return d.preventDefault=function(){f.scrolling=!1,f.firstXY=null,c.preventDefault()},d},processTouches:function(a,b){var d=a.changedTouches;this.currentTouchEvent=a;for(var e,f,g=0;g<d.length;g++)e=d[g],f=this.touchToPointer(e),"touchstart"===a.type&&c.set(f.pointerId,f.target),c.has(f.pointerId)&&b.call(this,f),("touchend"===a.type||a._cancel)&&this.cleanUpPointer(f)},shouldScroll:function(b){if(this.firstXY){var c,d=a.targetFinding.findTouchAction(b),e=this.touchActionToScrollType(d);if("none"===e)c=!1;else if("XY"===e)c=!0;else{var f=b.changedTouches[0],g=e,h="Y"===e?"X":"Y",i=Math.abs(f["client"+g]-this.firstXY[g]),j=Math.abs(f["client"+h]-this.firstXY[h]);c=i>=j}return c}},findTouch:function(a,b){for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)if(c.identifier===b)return!0},vacuumTouches:function(a){var b=a.touches;if(c.pointers()>=b.length){var d=[];c.forEach(function(a,c){if(1!==c&&!this.findTouch(b,c-2)){var e=a;d.push(e)}},this),d.forEach(function(a){this.cancel(a),c["delete"](a.pointerId)},this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.down))},down:function(a){b.down(a)},touchmove:function(a){if(h)a.cancelable&&this.processTouches(a,this.move);else if(this.scrolling){if(this.firstXY){var b=a.changedTouches[0],c=b.clientX-this.firstXY.X,d=b.clientY-this.firstXY.Y,e=Math.sqrt(c*c+d*d);e>=g&&(this.touchcancel(a),this.scrolling=!0,this.firstXY=null)}}else null===this.scrolling&&this.shouldScroll(a)?this.scrolling=!0:(this.scrolling=!1,a.preventDefault(),this.processTouches(a,this.move))},move:function(a){b.move(a)},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.up)},up:function(c){c.relatedTarget=a.findTarget(c),b.up(c)},cancel:function(a){b.cancel(a)},touchcancel:function(a){a._cancel=!0,this.processTouches(a,this.cancel)},cleanUpPointer:function(a){c["delete"](a.pointerId),this.removePrimaryPointer(a)},dedupSynthMouse:function(b){var c=a.mouseEvents.lastTouches,e=b.changedTouches[0];if(this.isPrimaryTouch(e)){var f={x:e.clientX,y:e.clientY};c.push(f);var g=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,c,f);setTimeout(g,d)}}},j=Event.prototype.stopImmediatePropagation||Event.prototype.stopPropagation;document.addEventListener("click",function(b){var c=b.clientX,d=b.clientY,f=function(a){var b=Math.abs(c-a.x),f=Math.abs(d-a.y);return e>=b&&e>=f},g=a.mouseEvents.lastTouches.some(f),h=a.targetFinding.path(b);if(g){for(var k=0;k<h.length;k++)if(h[k]===i.firstTarget)return;b.preventDefault(),j.call(b)}},!0),a.touchEvents=i}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,e={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerCancel"],register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var c=a;return c=b.cloneEvent(a),d&&(c.pointerType=this.POINTER_TYPES[a.pointerType]),c._source="ms",c},cleanup:function(a){c["delete"](a)},MSPointerDown:function(d){var e=this.prepareEvent(d);e.target=a.findTarget(d),c.set(d.pointerId,e.target),b.down(e)},MSPointerMove:function(a){var d=c.get(a.pointerId);if(d){var e=this.prepareEvent(a);e.target=d,b.move(e)}},MSPointerUp:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.up(e),this.cleanup(d.pointerId)},MSPointerCancel:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.cancel(e),this.cleanup(d.pointerId)}};a.msEvents=e}(window.PolymerGestures),function(a){var b=a.dispatcher,c=b.pointermap,d={events:["pointerdown","pointermove","pointerup","pointercancel"],prepareEvent:function(a){var c=b.cloneEvent(a);return c._source="pointer",c},register:function(a){b.listen(a,this.events)},unregister:function(a){a.nodeType!==Node.DOCUMENT_NODE&&b.unlisten(a,this.events)},cleanup:function(a){c["delete"](a)},pointerdown:function(d){var e=this.prepareEvent(d);e.target=a.findTarget(d),c.set(e.pointerId,e.target),b.down(e)},pointermove:function(a){var d=c.get(a.pointerId);if(d){var e=this.prepareEvent(a);e.target=d,b.move(e)}},pointerup:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.up(e),this.cleanup(d.pointerId)},pointercancel:function(d){var e=this.prepareEvent(d);e.relatedTarget=a.findTarget(d),e.target=c.get(e.pointerId),b.cancel(e),this.cleanup(d.pointerId)}};a.pointerEvents=d}(window.PolymerGestures),function(a){var b=a.dispatcher,c=window.navigator;window.PointerEvent?b.registerSource("pointer",a.pointerEvents):c.msPointerEnabled?b.registerSource("ms",a.msEvents):(b.registerSource("mouse",a.mouseEvents),void 0!==window.ontouchstart&&b.registerSource("touch",a.touchEvents));var d=navigator.userAgent,e=d.match(/iPad|iPhone|iPod/)&&"ontouchstart"in window;b.IS_IOS=e,a.touchEvents.IS_IOS=e,b.register(document,!0)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e={events:["down","move","up"],exposes:["trackstart","track","trackx","tracky","trackend"],defaultActions:{track:"none",trackx:"pan-y",tracky:"pan-x"},WIGGLE_THRESHOLD:4,clampDir:function(a){return a>0?1:-1},calcPositionDelta:function(a,b){var c=0,d=0;return a&&b&&(c=b.pageX-a.pageX,d=b.pageY-a.pageY),{x:c,y:d}},fireTrack:function(a,b,d){var e=d,f=this.calcPositionDelta(e.downEvent,b),g=this.calcPositionDelta(e.lastMoveEvent,b);if(g.x)e.xDirection=this.clampDir(g.x);else if("trackx"===a)return;if(g.y)e.yDirection=this.clampDir(g.y);else if("tracky"===a)return;var h={bubbles:!0,cancelable:!0,trackInfo:e.trackInfo,relatedTarget:b.relatedTarget,pointerType:b.pointerType,pointerId:b.pointerId,_source:"track"};"tracky"!==a&&(h.x=b.x,h.dx=f.x,h.ddx=g.x,h.clientX=b.clientX,h.pageX=b.pageX,h.screenX=b.screenX,h.xDirection=e.xDirection),"trackx"!==a&&(h.dy=f.y,h.ddy=g.y,h.y=b.y,h.clientY=b.clientY,h.pageY=b.pageY,h.screenY=b.screenY,h.yDirection=e.yDirection);var i=c.makeGestureEvent(a,h);e.downTarget.dispatchEvent(i)},down:function(a){if(a.isPrimary&&("mouse"===a.pointerType?1===a.buttons:!0)){var b={downEvent:a,downTarget:a.target,trackInfo:{},lastMoveEvent:null,xDirection:0,yDirection:0,tracking:!1};d.set(a.pointerId,b)}},move:function(a){var b=d.get(a.pointerId);if(b){if(!b.tracking){var c=this.calcPositionDelta(b.downEvent,a),e=c.x*c.x+c.y*c.y;e>this.WIGGLE_THRESHOLD&&(b.tracking=!0,b.lastMoveEvent=b.downEvent,this.fireTrack("trackstart",a,b))}b.tracking&&(this.fireTrack("track",a,b),this.fireTrack("trackx",a,b),this.fireTrack("tracky",a,b)),b.lastMoveEvent=a}},up:function(a){var b=d.get(a.pointerId);b&&(b.tracking&&this.fireTrack("trackend",a,b),d["delete"](a.pointerId))}};b.registerGesture("track",e)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d={HOLD_DELAY:200,WIGGLE_THRESHOLD:16,events:["down","move","up"],exposes:["hold","holdpulse","release"],heldPointer:null,holdJob:null,pulse:function(){var a=Date.now()-this.heldPointer.timeStamp,b=this.held?"holdpulse":"hold";this.fireHold(b,a),this.held=!0},cancel:function(){clearInterval(this.holdJob),this.held&&this.fireHold("release"),this.held=!1,this.heldPointer=null,this.target=null,this.holdJob=null},down:function(a){a.isPrimary&&!this.heldPointer&&(this.heldPointer=a,this.target=a.target,this.holdJob=setInterval(this.pulse.bind(this),this.HOLD_DELAY))},up:function(a){this.heldPointer&&this.heldPointer.pointerId===a.pointerId&&this.cancel()},move:function(a){if(this.heldPointer&&this.heldPointer.pointerId===a.pointerId){var b=a.clientX-this.heldPointer.clientX,c=a.clientY-this.heldPointer.clientY;b*b+c*c>this.WIGGLE_THRESHOLD&&this.cancel()}},fireHold:function(a,b){var d={bubbles:!0,cancelable:!0,pointerType:this.heldPointer.pointerType,pointerId:this.heldPointer.pointerId,x:this.heldPointer.clientX,y:this.heldPointer.clientY,_source:"hold"};b&&(d.holdTime=b);var e=c.makeGestureEvent(a,d);this.target.dispatchEvent(e)}};b.registerGesture("hold",d)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e={events:["down","up"],exposes:["tap"],down:function(a){a.isPrimary&&!a.tapPrevented&&d.set(a.pointerId,{target:a.target,buttons:a.buttons,x:a.clientX,y:a.clientY})},shouldTap:function(a,b){var c=!0;return"mouse"===a.pointerType&&(c=1^a.buttons&&1&b.buttons),c&&!a.tapPrevented},up:function(b){var e=d.get(b.pointerId);if(e&&this.shouldTap(b,e)){var f=a.targetFinding.LCA(e.target,b.relatedTarget);if(f){var g=c.makeGestureEvent("tap",{bubbles:!0,cancelable:!0,x:b.clientX,y:b.clientY,detail:b.detail,pointerType:b.pointerType,pointerId:b.pointerId,altKey:b.altKey,ctrlKey:b.ctrlKey,metaKey:b.metaKey,shiftKey:b.shiftKey,_source:"tap"});f.dispatchEvent(g)}}d["delete"](b.pointerId)}};c.preventTap=function(a){return function(){a.tapPrevented=!0,d["delete"](a.pointerId)}},b.registerGesture("tap",e)}(window.PolymerGestures),function(a){var b=a.dispatcher,c=a.eventFactory,d=new a.PointerMap,e=180/Math.PI,f={events:["down","up","move","cancel"],exposes:["pinchstart","pinch","pinchend","rotate"],defaultActions:{pinch:"none",rotate:"none"},reference:{},down:function(b){if(d.set(b.pointerId,b),2==d.pointers()){var c=this.calcChord(),e=this.calcAngle(c);this.reference={angle:e,diameter:c.diameter,target:a.targetFinding.LCA(c.a.target,c.b.target)},this.firePinch("pinchstart",c.diameter,c)}},up:function(a){var b=d.get(a.pointerId),c=d.pointers();if(b){if(2===c){var e=this.calcChord();this.firePinch("pinchend",e.diameter,e)}d["delete"](a.pointerId)}},move:function(a){d.has(a.pointerId)&&(d.set(a.pointerId,a),d.pointers()>1&&this.calcPinchRotate())},cancel:function(a){this.up(a)},firePinch:function(a,b,d){var e=b/this.reference.diameter,f=c.makeGestureEvent(a,{bubbles:!0,cancelable:!0,scale:e,centerX:d.center.x,centerY:d.center.y,_source:"pinch"});this.reference.target.dispatchEvent(f)},fireRotate:function(a,b){var d=Math.round((a-this.reference.angle)%360),e=c.makeGestureEvent("rotate",{bubbles:!0,cancelable:!0,angle:d,centerX:b.center.x,centerY:b.center.y,_source:"pinch"});this.reference.target.dispatchEvent(e)},calcPinchRotate:function(){var a=this.calcChord(),b=a.diameter,c=this.calcAngle(a);b!=this.reference.diameter&&this.firePinch("pinch",b,a),c!=this.reference.angle&&this.fireRotate(c,a)},calcChord:function(){var a=[];d.forEach(function(b){a.push(b)});for(var b,c,e,f=0,g={a:a[0],b:a[1]},h=0;h<a.length;h++)for(var i=a[h],j=h+1;j<a.length;j++){var k=a[j];b=Math.abs(i.clientX-k.clientX),c=Math.abs(i.clientY-k.clientY),e=b+c,e>f&&(f=e,g={a:i,b:k})}return b=Math.abs(g.a.clientX+g.b.clientX)/2,c=Math.abs(g.a.clientY+g.b.clientY)/2,g.center={x:b,y:c},g.diameter=f,g},calcAngle:function(a){var b=a.a.clientX-a.b.clientX,c=a.a.clientY-a.b.clientY;return(360+Math.atan2(c,b)*e)%360}};b.registerGesture("pinch",f)}(window.PolymerGestures),function(a){"use strict";function b(a,b){if(!a)throw new Error("ASSERT: "+b)}function c(a){return a>=48&&57>=a}function d(a){return 32===a||9===a||11===a||12===a||160===a||a>=5760&&" ᠎              ".indexOf(String.fromCharCode(a))>0}function e(a){return 10===a||13===a||8232===a||8233===a}function f(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a}function g(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a||a>=48&&57>=a}function h(a){return"this"===a}function i(){for(;Y>X&&d(W.charCodeAt(X));)++X}function j(){var a,b;for(a=X++;Y>X&&(b=W.charCodeAt(X),g(b));)++X;return W.slice(a,X)}function k(){var a,b,c;return a=X,b=j(),c=1===b.length?S.Identifier:h(b)?S.Keyword:"null"===b?S.NullLiteral:"true"===b||"false"===b?S.BooleanLiteral:S.Identifier,{type:c,value:b,range:[a,X]}}function l(){var a,b,c=X,d=W.charCodeAt(X),e=W[X];switch(d){case 46:case 40:case 41:case 59:case 44:case 123:case 125:case 91:case 93:case 58:case 63:return++X,{type:S.Punctuator,value:String.fromCharCode(d),range:[c,X]};default:if(a=W.charCodeAt(X+1),61===a)switch(d){case 37:case 38:case 42:case 43:case 45:case 47:case 60:case 62:case 124:return X+=2,{type:S.Punctuator,value:String.fromCharCode(d)+String.fromCharCode(a),range:[c,X]};case 33:case 61:return X+=2,61===W.charCodeAt(X)&&++X,{type:S.Punctuator,value:W.slice(c,X),range:[c,X]}}}return b=W[X+1],e===b&&"&|".indexOf(e)>=0?(X+=2,{type:S.Punctuator,value:e+b,range:[c,X]}):"<>=!+-*%&|^/".indexOf(e)>=0?(++X,{type:S.Punctuator,value:e,range:[c,X]}):void s({},V.UnexpectedToken,"ILLEGAL")}function m(){var a,d,e;if(e=W[X],b(c(e.charCodeAt(0))||"."===e,"Numeric literal must start with a decimal digit or a decimal point"),d=X,a="","."!==e){for(a=W[X++],e=W[X],"0"===a&&e&&c(e.charCodeAt(0))&&s({},V.UnexpectedToken,"ILLEGAL");c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("."===e){for(a+=W[X++];c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("e"===e||"E"===e)if(a+=W[X++],e=W[X],("+"===e||"-"===e)&&(a+=W[X++]),c(W.charCodeAt(X)))for(;c(W.charCodeAt(X));)a+=W[X++];else s({},V.UnexpectedToken,"ILLEGAL");return f(W.charCodeAt(X))&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.NumericLiteral,value:parseFloat(a),range:[d,X]}}function n(){var a,c,d,f="",g=!1;for(a=W[X],b("'"===a||'"'===a,"String literal must starts with a quote"),c=X,++X;Y>X;){if(d=W[X++],d===a){a="";break}if("\\"===d)if(d=W[X++],d&&e(d.charCodeAt(0)))"\r"===d&&"\n"===W[X]&&++X;else switch(d){case"n":f+="\n";break;case"r":f+="\r";break;case"t":f+="	";break;case"b":f+="\b";break;case"f":f+="\f";break;case"v":f+="";break;default:f+=d}else{if(e(d.charCodeAt(0)))break;f+=d}}return""!==a&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.StringLiteral,value:f,octal:g,range:[c,X]}}function o(a){return a.type===S.Identifier||a.type===S.Keyword||a.type===S.BooleanLiteral||a.type===S.NullLiteral}function p(){var a;return i(),X>=Y?{type:S.EOF,range:[X,X]}:(a=W.charCodeAt(X),40===a||41===a||58===a?l():39===a||34===a?n():f(a)?k():46===a?c(W.charCodeAt(X+1))?m():l():c(a)?m():l())}function q(){var a;return a=$,X=a.range[1],$=p(),X=a.range[1],a}function r(){var a;a=X,$=p(),X=a}function s(a,c){var d,e=Array.prototype.slice.call(arguments,2),f=c.replace(/%(\d)/g,function(a,c){return b(c<e.length,"Message reference must be in range"),e[c]});throw d=new Error(f),d.index=X,d.description=f,d}function t(a){s(a,V.UnexpectedToken,a.value)}function u(a){var b=q();(b.type!==S.Punctuator||b.value!==a)&&t(b)}function v(a){return $.type===S.Punctuator&&$.value===a}function w(a){return $.type===S.Keyword&&$.value===a}function x(){var a=[];for(u("[");!v("]");)v(",")?(q(),a.push(null)):(a.push(bb()),v("]")||u(","));return u("]"),Z.createArrayExpression(a)}function y(){var a;return i(),a=q(),a.type===S.StringLiteral||a.type===S.NumericLiteral?Z.createLiteral(a):Z.createIdentifier(a.value)}function z(){var a,b;return a=$,i(),(a.type===S.EOF||a.type===S.Punctuator)&&t(a),b=y(),u(":"),Z.createProperty("init",b,bb())}function A(){var a=[];for(u("{");!v("}");)a.push(z()),v("}")||u(",");return u("}"),Z.createObjectExpression(a)}function B(){var a;return u("("),a=bb(),u(")"),a}function C(){var a,b,c;return v("(")?B():(a=$.type,a===S.Identifier?c=Z.createIdentifier(q().value):a===S.StringLiteral||a===S.NumericLiteral?c=Z.createLiteral(q()):a===S.Keyword?w("this")&&(q(),c=Z.createThisExpression()):a===S.BooleanLiteral?(b=q(),b.value="true"===b.value,c=Z.createLiteral(b)):a===S.NullLiteral?(b=q(),b.value=null,c=Z.createLiteral(b)):v("[")?c=x():v("{")&&(c=A()),c?c:void t(q()))}function D(){var a=[];if(u("("),!v(")"))for(;Y>X&&(a.push(bb()),!v(")"));)u(",");return u(")"),a}function E(){var a;return a=q(),o(a)||t(a),Z.createIdentifier(a.value)}function F(){return u("."),E()}function G(){var a;return u("["),a=bb(),u("]"),a}function H(){var a,b,c;for(a=C();;)if(v("["))c=G(),a=Z.createMemberExpression("[",a,c);else if(v("."))c=F(),a=Z.createMemberExpression(".",a,c);else{if(!v("("))break;b=D(),a=Z.createCallExpression(a,b)}return a}function I(){var a,b;return $.type!==S.Punctuator&&$.type!==S.Keyword?b=ab():v("+")||v("-")||v("!")?(a=q(),b=I(),b=Z.createUnaryExpression(a.value,b)):w("delete")||w("void")||w("typeof")?s({},V.UnexpectedToken):b=ab(),b}function J(a){var b=0;if(a.type!==S.Punctuator&&a.type!==S.Keyword)return 0;switch(a.value){case"||":b=1;break;case"&&":b=2;break;case"==":case"!=":case"===":case"!==":b=6;break;case"<":case">":case"<=":case">=":case"instanceof":b=7;break;case"in":b=7;break;case"+":case"-":b=9;break;case"*":case"/":case"%":b=11}return b}function K(){var a,b,c,d,e,f,g,h;if(g=I(),b=$,c=J(b),0===c)return g;for(b.prec=c,q(),e=I(),d=[g,b,e];(c=J($))>0;){for(;d.length>2&&c<=d[d.length-2].prec;)e=d.pop(),f=d.pop().value,g=d.pop(),a=Z.createBinaryExpression(f,g,e),d.push(a);b=q(),b.prec=c,d.push(b),a=I(),d.push(a)}for(h=d.length-1,a=d[h];h>1;)a=Z.createBinaryExpression(d[h-1].value,d[h-2],a),h-=2;return a}function L(){var a,b,c;return a=K(),v("?")&&(q(),b=L(),u(":"),c=L(),a=Z.createConditionalExpression(a,b,c)),a}function M(){var a,b;return a=q(),a.type!==S.Identifier&&t(a),b=v("(")?D():[],Z.createFilter(a.value,b)}function N(){for(;v("|");)q(),M()}function O(){i(),r();var a=bb();a&&(","===$.value||"in"==$.value&&a.type===U.Identifier?Q(a):(N(),"as"===$.value?P(a):Z.createTopLevel(a))),$.type!==S.EOF&&t($)}function P(a){q();var b=q().value;Z.createAsExpression(a,b)}function Q(a){var b;","===$.value&&(q(),$.type!==S.Identifier&&t($),b=q().value),q();var c=bb();N(),Z.createInExpression(a.name,b,c)}function R(a,b){return Z=b,W=a,X=0,Y=W.length,$=null,_={labelSet:{}},O()}var S,T,U,V,W,X,Y,Z,$,_;S={BooleanLiteral:1,EOF:2,Identifier:3,Keyword:4,NullLiteral:5,NumericLiteral:6,Punctuator:7,StringLiteral:8},T={},T[S.BooleanLiteral]="Boolean",T[S.EOF]="<end>",T[S.Identifier]="Identifier",T[S.Keyword]="Keyword",T[S.NullLiteral]="Null",T[S.NumericLiteral]="Numeric",T[S.Punctuator]="Punctuator",T[S.StringLiteral]="String",U={ArrayExpression:"ArrayExpression",BinaryExpression:"BinaryExpression",CallExpression:"CallExpression",ConditionalExpression:"ConditionalExpression",EmptyStatement:"EmptyStatement",ExpressionStatement:"ExpressionStatement",Identifier:"Identifier",Literal:"Literal",LabeledStatement:"LabeledStatement",LogicalExpression:"LogicalExpression",MemberExpression:"MemberExpression",ObjectExpression:"ObjectExpression",Program:"Program",Property:"Property",ThisExpression:"ThisExpression",UnaryExpression:"UnaryExpression"},V={UnexpectedToken:"Unexpected token %0",UnknownLabel:"Undefined label '%0'",Redeclaration:"%0 '%1' has already been declared"};
+var ab=H,bb=L;a.esprima={parse:R}}(this),function(a){"use strict";function b(a,b,d,e){var f;try{if(f=c(a),f.scopeIdent&&(d.nodeType!==Node.ELEMENT_NODE||"TEMPLATE"!==d.tagName||"bind"!==b&&"repeat"!==b))throw Error("as and in can only be used within <template bind/repeat>")}catch(g){return void console.error("Invalid expression syntax: "+a,g)}return function(a,b,c){var d=f.getBinding(a,e,c);return f.scopeIdent&&d&&(b.polymerExpressionScopeIdent_=f.scopeIdent,f.indexIdent&&(b.polymerExpressionIndexIdent_=f.indexIdent)),d}}function c(a){var b=q[a];if(!b){var c=new j;esprima.parse(a,c),b=new l(c),q[a]=b}return b}function d(a){this.value=a,this.valueFn_=void 0}function e(a){this.name=a,this.path=Path.get(a)}function f(a,b,c){this.computed="["==c,this.dynamicDeps="function"==typeof a||a.dynamicDeps||this.computed&&!(b instanceof d),this.simplePath=!this.dynamicDeps&&(b instanceof e||b instanceof d)&&(a instanceof f||a instanceof e),this.object=this.simplePath?a:i(a),this.property=!this.computed||this.simplePath?b:i(b)}function g(a,b){this.name=a,this.args=[];for(var c=0;c<b.length;c++)this.args[c]=i(b[c])}function h(){throw Error("Not Implemented")}function i(a){return"function"==typeof a?a:a.valueFn()}function j(){this.expression=null,this.filters=[],this.deps={},this.currentPath=void 0,this.scopeIdent=void 0,this.indexIdent=void 0,this.dynamicDeps=!1}function k(a){this.value_=a}function l(a){if(this.scopeIdent=a.scopeIdent,this.indexIdent=a.indexIdent,!a.expression)throw Error("No expression found.");this.expression=a.expression,i(this.expression),this.filters=a.filters,this.dynamicDeps=a.dynamicDeps}function m(a){return String(a).replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}function n(a,b){for(;a[t]&&!Object.prototype.hasOwnProperty.call(a,b);)a=a[t];return a}function o(a){switch(a){case"":return!1;case"false":case"null":case"true":return!0}return isNaN(Number(a))?!1:!0}function p(){}var q=Object.create(null);d.prototype={valueFn:function(){if(!this.valueFn_){var a=this.value;this.valueFn_=function(){return a}}return this.valueFn_}},e.prototype={valueFn:function(){if(!this.valueFn_){var a=(this.name,this.path);this.valueFn_=function(b,c){return c&&c.addPath(b,a),a.getValueFrom(b)}}return this.valueFn_},setValue:function(a,b){return 1==this.path.length&&(a=n(a,this.path[0])),this.path.setValueFrom(a,b)}},f.prototype={get fullPath(){if(!this.fullPath_){var a=this.object instanceof f?this.object.fullPath.slice():[this.object.name];a.push(this.property instanceof e?this.property.name:this.property.value),this.fullPath_=Path.get(a)}return this.fullPath_},valueFn:function(){if(!this.valueFn_){var a=this.object;if(this.simplePath){var b=this.fullPath;this.valueFn_=function(a,c){return c&&c.addPath(a,b),b.getValueFrom(a)}}else if(this.computed){var c=this.property;this.valueFn_=function(b,d,e){var f=a(b,d,e),g=c(b,d,e);return d&&d.addPath(f,[g]),f?f[g]:void 0}}else{var b=Path.get(this.property.name);this.valueFn_=function(c,d,e){var f=a(c,d,e);return d&&d.addPath(f,b),b.getValueFrom(f)}}}return this.valueFn_},setValue:function(a,b){if(this.simplePath)return this.fullPath.setValueFrom(a,b),b;var c=this.object(a),d=this.property instanceof e?this.property.name:this.property(a);return c[d]=b}},g.prototype={transform:function(a,b,c,d,e){var f=a,g=f[this.name];if(!g&&(g=c[this.name],!g))return void console.error("Cannot find function or filter: "+this.name);if(d?g=g.toModel:"function"==typeof g.toDOM&&(g=g.toDOM),"function"!=typeof g)return void console.error("Cannot find function or filter: "+this.name);for(var h=e||[],j=0;j<this.args.length;j++)h.push(i(this.args[j])(a,b,c));return g.apply(f,h)}};var r={"+":function(a){return+a},"-":function(a){return-a},"!":function(a){return!a}},s={"+":function(a,b){return a+b},"-":function(a,b){return a-b},"*":function(a,b){return a*b},"/":function(a,b){return a/b},"%":function(a,b){return a%b},"<":function(a,b){return b>a},">":function(a,b){return a>b},"<=":function(a,b){return b>=a},">=":function(a,b){return a>=b},"==":function(a,b){return a==b},"!=":function(a,b){return a!=b},"===":function(a,b){return a===b},"!==":function(a,b){return a!==b},"&&":function(a,b){return a&&b},"||":function(a,b){return a||b}};j.prototype={createUnaryExpression:function(a,b){if(!r[a])throw Error("Disallowed operator: "+a);return b=i(b),function(c,d,e){return r[a](b(c,d,e))}},createBinaryExpression:function(a,b,c){if(!s[a])throw Error("Disallowed operator: "+a);switch(b=i(b),c=i(c),a){case"||":return this.dynamicDeps=!0,function(a,d,e){return b(a,d,e)||c(a,d,e)};case"&&":return this.dynamicDeps=!0,function(a,d,e){return b(a,d,e)&&c(a,d,e)}}return function(d,e,f){return s[a](b(d,e,f),c(d,e,f))}},createConditionalExpression:function(a,b,c){return a=i(a),b=i(b),c=i(c),this.dynamicDeps=!0,function(d,e,f){return a(d,e,f)?b(d,e,f):c(d,e,f)}},createIdentifier:function(a){var b=new e(a);return b.type="Identifier",b},createMemberExpression:function(a,b,c){var d=new f(b,c,a);return d.dynamicDeps&&(this.dynamicDeps=!0),d},createCallExpression:function(a,b){if(!(a instanceof e))throw Error("Only identifier function invocations are allowed");var c=new g(a.name,b);return function(a,b,d){return c.transform(a,b,d,!1)}},createLiteral:function(a){return new d(a.value)},createArrayExpression:function(a){for(var b=0;b<a.length;b++)a[b]=i(a[b]);return function(b,c,d){for(var e=[],f=0;f<a.length;f++)e.push(a[f](b,c,d));return e}},createProperty:function(a,b,c){return{key:b instanceof e?b.name:b.value,value:c}},createObjectExpression:function(a){for(var b=0;b<a.length;b++)a[b].value=i(a[b].value);return function(b,c,d){for(var e={},f=0;f<a.length;f++)e[a[f].key]=a[f].value(b,c,d);return e}},createFilter:function(a,b){this.filters.push(new g(a,b))},createAsExpression:function(a,b){this.expression=a,this.scopeIdent=b},createInExpression:function(a,b,c){this.expression=c,this.scopeIdent=a,this.indexIdent=b},createTopLevel:function(a){this.expression=a},createThisExpression:h},k.prototype={open:function(){return this.value_},discardChanges:function(){return this.value_},deliver:function(){},close:function(){}},l.prototype={getBinding:function(a,b,c){function d(){if(h)return h=!1,g;i.dynamicDeps&&f.startReset();var c=i.getValue(a,i.dynamicDeps?f:void 0,b);return i.dynamicDeps&&f.finishReset(),c}function e(c){return i.setValue(a,c,b),c}if(c)return this.getValue(a,void 0,b);var f=new CompoundObserver,g=this.getValue(a,f,b),h=!0,i=this;return new ObserverTransform(f,d,e,!0)},getValue:function(a,b,c){for(var d=i(this.expression)(a,b,c),e=0;e<this.filters.length;e++)d=this.filters[e].transform(a,b,c,!1,[d]);return d},setValue:function(a,b,c){for(var d=this.filters?this.filters.length:0;d-->0;)b=this.filters[d].transform(a,void 0,c,!0,[b]);return this.expression.setValue?this.expression.setValue(a,b):void 0}};var t="@"+Math.random().toString(36).slice(2);p.prototype={styleObject:function(a){var b=[];for(var c in a)b.push(m(c)+": "+a[c]);return b.join("; ")},tokenList:function(a){var b=[];for(var c in a)a[c]&&b.push(c);return b.join(" ")},prepareInstancePositionChanged:function(a){var b=a.polymerExpressionIndexIdent_;if(b)return function(a,c){a.model[b]=c}},prepareBinding:function(a,c,d){var e=Path.get(a);{if(o(a)||!e.valid)return b(a,c,d,this);if(1==e.length)return function(a,b,c){if(c)return e.getValueFrom(a);var d=n(a,e[0]);return new PathObserver(d,e)}}},prepareInstanceModel:function(a){var b=a.polymerExpressionScopeIdent_;if(b){var c=a.templateInstance?a.templateInstance.model:a.model,d=a.polymerExpressionIndexIdent_;return function(a){return u(c,a,b,d)}}}};var u="__proto__"in{}?function(a,b,c,d){var e={};return e[c]=b,e[d]=void 0,e[t]=a,e.__proto__=a,e}:function(a,b,c,d){var e=Object.create(a);return Object.defineProperty(e,c,{value:b,configurable:!0,writable:!0}),Object.defineProperty(e,d,{value:void 0,configurable:!0,writable:!0}),Object.defineProperty(e,t,{value:a,configurable:!0,writable:!0}),e};a.PolymerExpressions=p,p.getExpression=c}(this),Polymer={version:"0.5.5"},"function"==typeof window.Polymer&&(Polymer={}),function(a){function b(a,b){return b=b||[],b.map||(b=[b]),a.apply(this,b.map(d))}function c(a,c,d){var e;switch(arguments.length){case 0:return;case 1:e=null;break;case 2:e=c.apply(this);break;default:e=b(d,c)}f[a]=e}function d(a){return f[a]}function e(a,c){HTMLImports.whenImportsReady(function(){b(c,a)})}var f={};a.marshal=d,a.modularize=c,a.using=e}(window),window.WebComponents||(window.WebComponents||(WebComponents={flush:function(){},flags:{log:{}}},Platform=WebComponents,CustomElements={useNative:!0,ready:!0,takeRecords:function(){},"instanceof":function(a,b){return a instanceof b}},HTMLImports={useNative:!0},addEventListener("HTMLImportsLoaded",function(){document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))}),ShadowDOMPolyfill=null,wrap=unwrap=function(a){return a}),window.HTMLImports=window.HTMLImports||{flags:{}},function(a){function b(a,b){b=b||o,d(function(){f(a,b)},b)}function c(a){return"complete"===a.readyState||a.readyState===r}function d(a,b){if(c(b))a&&a();else{var e=function(){("complete"===b.readyState||b.readyState===r)&&(b.removeEventListener(s,e),d(a,b))};b.addEventListener(s,e)}}function e(a){a.target.__loaded=!0}function f(a,b){function c(){h==i&&a&&a()}function d(a){e(a),h++,c()}var f=b.querySelectorAll("link[rel=import]"),h=0,i=f.length;if(i)for(var j,k=0;i>k&&(j=f[k]);k++)g(j)?d.call(j,{target:j}):(j.addEventListener("load",d),j.addEventListener("error",d));else c()}function g(a){return l?a.__loaded||a["import"]&&"loading"!==a["import"].readyState:a.__importParsed}function h(a){for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)i(b)&&j(b)}function i(a){return"link"===a.localName&&"import"===a.rel}function j(a){var b=a["import"];b?e({target:a}):(a.addEventListener("load",e),a.addEventListener("error",e))}var k="import",l=Boolean(k in document.createElement("link")),m=Boolean(window.ShadowDOMPolyfill),n=function(a){return m?ShadowDOMPolyfill.wrapIfNeeded(a):a},o=n(document),p={get:function(){var a=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return n(a)},configurable:!0};Object.defineProperty(document,"_currentScript",p),Object.defineProperty(o,"_currentScript",p);var q=/Trident/.test(navigator.userAgent),r=q?"complete":"interactive",s="readystatechange";l&&(new MutationObserver(function(a){for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)b.addedNodes&&h(b.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var a,b=document.querySelectorAll("link[rel=import]"),c=0,d=b.length;d>c&&(a=b[c]);c++)j(a)}()),b(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime(),o.dispatchEvent(new CustomEvent("HTMLImportsLoaded",{bubbles:!0}))}),a.IMPORT_LINK_TYPE=k,a.useNative=l,a.rootDocument=o,a.whenReady=b,a.isIE=q}(HTMLImports),function(){var a=document.createElement("style");a.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; } \n";var b=document.querySelector("head");b.insertBefore(a,b.firstChild)}(Platform)),function(a){"use strict";function b(){function a(a){b=a}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=[],c={},d=[];return Object.observe(c,a),Array.observe(d,a),c.id=1,c.id=2,delete c.id,d.push(1,2),d.length=0,Object.deliverChangeRecords(a),5!==b.length?!1:"add"!=b[0].type||"update"!=b[1].type||"delete"!=b[2].type||"splice"!=b[3].type||"splice"!=b[4].type?!1:(Object.unobserve(c,a),Array.unobserve(d,a),!0)}function c(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if("undefined"!=typeof navigator&&navigator.getDeviceStorage)return!1;try{var a=new Function("","return true;");return a()}catch(b){return!1}}function d(a){return+a===a>>>0&&""!==a}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:R(a)&&R(b)?!0:a!==a&&b!==b}function h(a){if(void 0===a)return"eof";var b=a.charCodeAt(0);switch(b){case 91:case 93:case 46:case 34:case 39:case 48:return a;case 95:case 36:return"ident";case 32:case 9:case 10:case 13:case 160:case 65279:case 8232:case 8233:return"ws"}return b>=97&&122>=b||b>=65&&90>=b?"ident":b>=49&&57>=b?"number":"else"}function i(){}function j(a){function b(){if(!(m>=a.length)){var b=a[m+1];return"inSingleQuote"==n&&"'"==b||"inDoubleQuote"==n&&'"'==b?(m++,d=b,o.append(),!0):void 0}}for(var c,d,e,f,g,j,k,l=[],m=-1,n="beforePath",o={push:function(){void 0!==e&&(l.push(e),e=void 0)},append:function(){void 0===e?e=d:e+=d}};n;)if(m++,c=a[m],"\\"!=c||!b(n)){if(f=h(c),k=W[n],g=k[f]||k["else"]||"error","error"==g)return;if(n=g[0],j=o[g[1]]||i,d=void 0===g[2]?c:g[2],j(),"afterPath"===n)return l}}function k(a){return V.test(a)}function l(a,b){if(b!==X)throw Error("Use Path.get to retrieve path objects");for(var c=0;c<a.length;c++)this.push(String(a[c]));Q&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn())}function m(a){if(a instanceof l)return a;if((null==a||0==a.length)&&(a=""),"string"!=typeof a){if(d(a.length))return new l(a,X);a=String(a)}var b=Y[a];if(b)return b;var c=j(a);if(!c)return Z;var b=new l(c,X);return Y[a]=b,b}function n(a){return d(a)?"["+a+"]":'["'+a.replace(/"/g,'\\"')+'"]'}function o(b){for(var c=0;_>c&&b.check_();)c++;return O&&(a.dirtyCheckCycleCount=c),c>0}function p(a){for(var b in a)return!1;return!0}function q(a){return p(a.added)&&p(a.removed)&&p(a.changed)}function r(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function s(){if(!ab.length)return!1;for(var a=0;a<ab.length;a++)ab[a]();return ab.length=0,!0}function t(){function a(a){b&&b.state_===fb&&!d&&b.check_(a)}var b,c,d=!1,e=!0;return{open:function(c){if(b)throw Error("ObservedObject in use");e||Object.deliverChangeRecords(a),b=c,e=!1},observe:function(b,d){c=b,d?Array.observe(c,a):Object.observe(c,a)},deliver:function(b){d=b,Object.deliverChangeRecords(a),d=!1},close:function(){b=void 0,Object.unobserve(c,a),cb.push(this)}}}function u(a,b,c){var d=cb.pop()||t();return d.open(a),d.observe(b,c),d}function v(){function a(b,f){b&&(b===d&&(e[f]=!0),h.indexOf(b)<0&&(h.push(b),Object.observe(b,c)),a(Object.getPrototypeOf(b),f))}function b(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.object!==d||e[c.name]||"setPrototype"===c.type)return!1}return!0}function c(c){if(!b(c)){for(var d,e=0;e<g.length;e++)d=g[e],d.state_==fb&&d.iterateObjects_(a);for(var e=0;e<g.length;e++)d=g[e],d.state_==fb&&d.check_()}}var d,e,f=0,g=[],h=[],i={objects:h,get rootObject(){return d},set rootObject(a){d=a,e={}},open:function(b){g.push(b),f++,b.iterateObjects_(a)},close:function(){if(f--,!(f>0)){for(var a=0;a<h.length;a++)Object.unobserve(h[a],c),x.unobservedCount++;g.length=0,h.length=0,d=void 0,e=void 0,db.push(this),$===this&&($=null)}}};return i}function w(a,b){return $&&$.rootObject===b||($=db.pop()||v(),$.rootObject=b),$.open(a,b),$}function x(){this.state_=eb,this.callback_=void 0,this.target_=void 0,this.directObserver_=void 0,this.value_=void 0,this.id_=ib++}function y(a){x._allObserversCount++,kb&&jb.push(a)}function z(){x._allObserversCount--}function A(a){x.call(this),this.value_=a,this.oldObject_=void 0}function B(a){if(!Array.isArray(a))throw Error("Provided object is not an Array");A.call(this,a)}function C(a,b){x.call(this),this.object_=a,this.path_=m(b),this.directObserver_=void 0}function D(a){x.call(this),this.reportChangesOnOpen_=a,this.value_=[],this.directObserver_=void 0,this.observed_=[]}function E(a){return a}function F(a,b,c,d){this.callback_=void 0,this.target_=void 0,this.value_=void 0,this.observable_=a,this.getValueFn_=b||E,this.setValueFn_=c||E,this.dontPassThroughSet_=d}function G(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];nb[g.type]?(g.name in c||(c[g.name]=g.oldValue),"update"!=g.type&&("add"!=g.type?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function H(a,b,c){return{index:a,removed:b,addedCount:c}}function I(){}function J(a,b,c,d,e,f){return sb.calcSplices(a,b,c,d,e,f)}function K(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function L(a,b,c,d){for(var e=H(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=K(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function M(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case"splice":L(c,g.index,g.removed.slice(),g.addedCount);break;case"add":case"update":case"delete":if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;L(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function N(a,b){var c=[];return M(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?void(b.removed[0]!==a[b.index]&&c.push(b)):void(c=c.concat(J(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)))}),c}var O=a.testingExposeCycleCount,P=b(),Q=c(),R=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},S="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},T="[$_a-zA-Z]",U="[$_a-zA-Z0-9]",V=new RegExp("^"+T+"+"+U+"*$"),W={beforePath:{ws:["beforePath"],ident:["inIdent","append"],"[":["beforeElement"],eof:["afterPath"]},inPath:{ws:["inPath"],".":["beforeIdent"],"[":["beforeElement"],eof:["afterPath"]},beforeIdent:{ws:["beforeIdent"],ident:["inIdent","append"]},inIdent:{ident:["inIdent","append"],0:["inIdent","append"],number:["inIdent","append"],ws:["inPath","push"],".":["beforeIdent","push"],"[":["beforeElement","push"],eof:["afterPath","push"]},beforeElement:{ws:["beforeElement"],0:["afterZero","append"],number:["inIndex","append"],"'":["inSingleQuote","append",""],'"':["inDoubleQuote","append",""]},afterZero:{ws:["afterElement","push"],"]":["inPath","push"]},inIndex:{0:["inIndex","append"],number:["inIndex","append"],ws:["afterElement"],"]":["inPath","push"]},inSingleQuote:{"'":["afterElement"],eof:["error"],"else":["inSingleQuote","append"]},inDoubleQuote:{'"':["afterElement"],eof:["error"],"else":["inDoubleQuote","append"]},afterElement:{ws:["afterElement"],"]":["inPath","push"]}},X={},Y={};l.get=m,l.prototype=S({__proto__:[],valid:!0,toString:function(){for(var a="",b=0;b<this.length;b++){var c=this[b];a+=k(c)?b?"."+c:c:n(c)}return a},getValueFrom:function(a){for(var b=0;b<this.length;b++){if(null==a)return;a=a[this[b]]}return a},iterateObjects:function(a,b){for(var c=0;c<this.length;c++){if(c&&(a=a[this[c-1]]),!f(a))return;b(a,this[c])}},compiledGetValueFromFn:function(){var a="",b="obj";a+="if (obj != null";for(var c,d=0;d<this.length-1;d++)c=this[d],b+=k(c)?"."+c:n(c),a+=" &&\n     "+b+" != null";a+=")\n";var c=this[d];return b+=k(c)?"."+c:n(c),a+="  return "+b+";\nelse\n  return undefined;",new Function("obj",a)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var Z=new l("",X);Z.valid=!1,Z.getValueFrom=Z.setValueFrom=function(){};var $,_=1e3,ab=[],bb=P?function(){return function(a){return Promise.resolve().then(a)}}():function(){return function(a){ab.push(a)}}(),cb=[],db=[],eb=0,fb=1,gb=2,hb=3,ib=1;x.prototype={open:function(a,b){if(this.state_!=eb)throw Error("Observer has already been opened.");return y(this),this.callback_=a,this.target_=b,this.connect_(),this.state_=fb,this.value_},close:function(){this.state_==fb&&(z(this),this.disconnect_(),this.value_=void 0,this.callback_=void 0,this.target_=void 0,this.state_=gb)},deliver:function(){this.state_==fb&&o(this)},report_:function(a){try{this.callback_.apply(this.target_,a)}catch(b){x._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},discardChanges:function(){return this.check_(void 0,!0),this.value_}};var jb,kb=!P;x._allObserversCount=0,kb&&(jb=[]);var lb=!1;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!lb&&kb){lb=!0;var b,c,d=0;do{d++,c=jb,jb=[],b=!1;for(var e=0;e<c.length;e++){var f=c[e];f.state_==fb&&(f.check_()&&(b=!0),jb.push(f))}s()&&(b=!0)}while(_>d&&b);O&&(a.dirtyCheckCycleCount=d),lb=!1}},kb&&(a.Platform.clearObservers=function(){jb=[]}),A.prototype=S({__proto__:x.prototype,arrayObserve:!1,connect_:function(){P?this.directObserver_=u(this,this.value_,this.arrayObserve):this.oldObject_=this.copyObject(this.value_)},copyObject:function(a){var b=Array.isArray(a)?[]:{};for(var c in a)b[c]=a[c];return Array.isArray(a)&&(b.length=a.length),b},check_:function(a){var b,c;if(P){if(!a)return!1;c={},b=G(this.value_,a,c)}else c=this.oldObject_,b=r(this.value_,this.oldObject_);return q(b)?!1:(P||(this.oldObject_=this.copyObject(this.value_)),this.report_([b.added||{},b.removed||{},b.changed||{},function(a){return c[a]}]),!0)},disconnect_:function(){P?(this.directObserver_.close(),this.directObserver_=void 0):this.oldObject_=void 0},deliver:function(){this.state_==fb&&(P?this.directObserver_.deliver(!1):o(this))},discardChanges:function(){return this.directObserver_?this.directObserver_.deliver(!0):this.oldObject_=this.copyObject(this.value_),this.value_}}),B.prototype=S({__proto__:A.prototype,arrayObserve:!0,copyObject:function(a){return a.slice()},check_:function(a){var b;if(P){if(!a)return!1;b=N(this.value_,a)}else b=J(this.value_,0,this.value_.length,this.oldObject_,0,this.oldObject_.length);return b&&b.length?(P||(this.oldObject_=this.copyObject(this.value_)),this.report_([b]),!0):!1}}),B.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})},C.prototype=S({__proto__:x.prototype,get path(){return this.path_},connect_:function(){P&&(this.directObserver_=w(this,this.object_)),this.check_(void 0,!0)},disconnect_:function(){this.value_=void 0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},iterateObjects_:function(a){this.path_.iterateObjects(this.object_,a)},check_:function(a,b){var c=this.value_;return this.value_=this.path_.getValueFrom(this.object_),b||g(this.value_,c)?!1:(this.report_([this.value_,c,this]),!0)},setValue:function(a){this.path_&&this.path_.setValueFrom(this.object_,a)}});var mb={};D.prototype=S({__proto__:x.prototype,connect_:function(){if(P){for(var a,b=!1,c=0;c<this.observed_.length;c+=2)if(a=this.observed_[c],a!==mb){b=!0;break}b&&(this.directObserver_=w(this,a))}this.check_(void 0,!this.reportChangesOnOpen_)},disconnect_:function(){for(var a=0;a<this.observed_.length;a+=2)this.observed_[a]===mb&&this.observed_[a+1].close();this.observed_.length=0,this.value_.length=0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},addPath:function(a,b){if(this.state_!=eb&&this.state_!=hb)throw Error("Cannot add paths once started.");var b=m(b);if(this.observed_.push(a,b),this.reportChangesOnOpen_){var c=this.observed_.length/2-1;this.value_[c]=b.getValueFrom(a)}},addObserver:function(a){if(this.state_!=eb&&this.state_!=hb)throw Error("Cannot add observers once started.");if(this.observed_.push(mb,a),this.reportChangesOnOpen_){var b=this.observed_.length/2-1;this.value_[b]=a.open(this.deliver,this)}},startReset:function(){if(this.state_!=fb)throw Error("Can only reset while open");this.state_=hb,this.disconnect_()},finishReset:function(){if(this.state_!=hb)throw Error("Can only finishReset after startReset");return this.state_=fb,this.connect_(),this.value_},iterateObjects_:function(a){for(var b,c=0;c<this.observed_.length;c+=2)b=this.observed_[c],b!==mb&&this.observed_[c+1].iterateObjects(b,a)},check_:function(a,b){for(var c,d=0;d<this.observed_.length;d+=2){var e,f=this.observed_[d],h=this.observed_[d+1];if(f===mb){var i=h;e=this.state_===eb?i.open(this.deliver,this):i.discardChanges()}else e=h.getValueFrom(f);b?this.value_[d/2]=e:g(e,this.value_[d/2])||(c=c||[],c[d/2]=this.value_[d/2],this.value_[d/2]=e)}return c?(this.report_([this.value_,c,this.observed_]),!0):!1}}),F.prototype={open:function(a,b){return this.callback_=a,this.target_=b,this.value_=this.getValueFn_(this.observable_.open(this.observedCallback_,this)),this.value_},observedCallback_:function(a){if(a=this.getValueFn_(a),!g(a,this.value_)){var b=this.value_;this.value_=a,this.callback_.call(this.target_,this.value_,b)}},discardChanges:function(){return this.value_=this.getValueFn_(this.observable_.discardChanges()),this.value_},deliver:function(){return this.observable_.deliver()},setValue:function(a){return a=this.setValueFn_(a),!this.dontPassThroughSet_&&this.observable_.setValue?this.observable_.setValue(a):void 0},close:function(){this.observable_&&this.observable_.close(),this.callback_=void 0,this.target_=void 0,this.observable_=void 0,this.value_=void 0,this.getValueFn_=void 0,this.setValueFn_=void 0}};var nb={add:!0,update:!0,"delete":!0},ob=0,pb=1,qb=2,rb=3;I.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(ob):(e.push(pb),d=g),b--,c--):f==h?(e.push(rb),b--,d=h):(e.push(qb),c--,d=i)}else e.push(rb),b--;else e.push(qb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,c-b==0&&f-e==0)return[];if(b==c){for(var j=H(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[H(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case ob:j&&(l.push(j),j=void 0),m++,n++;break;case pb:j||(j=H(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case qb:j||(j=H(m,[],0)),j.addedCount++,m++;break;case rb:j||(j=H(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var sb=new I,tb=a;"undefined"==typeof exports||exports.nodeType||("undefined"!=typeof module&&module.exports&&(exports=module.exports),tb=exports),tb.Observer=x,tb.Observer.runEOM_=bb,tb.Observer.observerSentinel_=mb,tb.Observer.hasObjectObserve=P,tb.ArrayObserver=B,tb.ArrayObserver.calculateSplices=function(a,b){return sb.calculateSplices(a,b)},tb.ArraySplice=I,tb.ObjectObserver=A,tb.PathObserver=C,tb.CompoundObserver=D,tb.Path=l,tb.ObserverTransform=F}("undefined"!=typeof global&&global&&"undefined"!=typeof module&&module?global:this||window),function(){"use strict";function a(a){for(;a.parentNode;)a=a.parentNode;return"function"==typeof a.getElementById?a:null}function b(a,b,c){var d=a.bindings_;return d||(d=a.bindings_={}),d[b]&&c[b].close(),d[b]=c}function c(a,b,c){return c}function d(a){return null==a?"":a}function e(a,b){a.data=d(b)}function f(a){return function(b){return e(a,b)}}function g(a,b,c,e){return c?void(e?a.setAttribute(b,""):a.removeAttribute(b)):void a.setAttribute(b,d(e))}function h(a,b,c){return function(d){g(a,b,c,d)}}function i(a){switch(a.type){case"checkbox":return u;case"radio":case"select-multiple":case"select-one":return"change";case"range":if(/Trident|MSIE/.test(navigator.userAgent))return"change";default:return"input"}}function j(a,b,c,e){a[b]=(e||d)(c)}function k(a,b,c){return function(d){return j(a,b,d,c)}}function l(){}function m(a,b,c,d){function e(){var e="value"==b&&"number"==a.type;c.setValue(e?a.valueAsNumber:a[b]),c.discardChanges(),(d||l)(a),Platform.performMicrotaskCheckpoint()}var f=i(a);return a.addEventListener(f,e),{close:function(){a.removeEventListener(f,e),c.close()},observable_:c}}function n(a){return Boolean(a)}function o(b){if(b.form)return s(b.form.elements,function(a){return a!=b&&"INPUT"==a.tagName&&"radio"==a.type&&a.name==b.name});var c=a(b);if(!c)return[];var d=c.querySelectorAll('input[type="radio"][name="'+b.name+'"]');return s(d,function(a){return a!=b&&!a.form})}function p(a){"INPUT"===a.tagName&&"radio"===a.type&&o(a).forEach(function(a){var b=a.bindings_.checked;b&&b.observable_.setValue(!1)})}function q(a,b){var c,e,f,g=a.parentNode;g instanceof HTMLSelectElement&&g.bindings_&&g.bindings_.value&&(c=g,e=c.bindings_.value,f=c.value),a.value=d(b),c&&c.value!=f&&(e.observable_.setValue(c.value),e.observable_.discardChanges(),Platform.performMicrotaskCheckpoint())}function r(a){return function(b){q(a,b)}}var s=Array.prototype.filter.call.bind(Array.prototype.filter);Node.prototype.bind=function(a,b){console.error("Unhandled binding to Node: ",this,a,b)},Node.prototype.bindFinished=function(){};var t=c;Object.defineProperty(Platform,"enableBindingsReflection",{get:function(){return t===b},set:function(a){return t=a?b:c,a},configurable:!0}),Text.prototype.bind=function(a,b,c){if("textContent"!==a)return Node.prototype.bind.call(this,a,b,c);if(c)return e(this,b);var d=b;return e(this,d.open(f(this))),t(this,a,d)},Element.prototype.bind=function(a,b,c){var d="?"==a[a.length-1];if(d&&(this.removeAttribute(a),a=a.slice(0,-1)),c)return g(this,a,d,b);var e=b;return g(this,a,d,e.open(h(this,a,d))),t(this,a,e)};var u;!function(){var a=document.createElement("div"),b=a.appendChild(document.createElement("input"));b.setAttribute("type","checkbox");var c,d=0;b.addEventListener("click",function(){d++,c=c||"click"}),b.addEventListener("change",function(){d++,c=c||"change"});var e=document.createEvent("MouseEvent");e.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),b.dispatchEvent(e),u=1==d?"change":c}(),HTMLInputElement.prototype.bind=function(a,c,e){if("value"!==a&&"checked"!==a)return HTMLElement.prototype.bind.call(this,a,c,e);this.removeAttribute(a);var f="checked"==a?n:d,g="checked"==a?p:l;if(e)return j(this,a,c,f);var h=c,i=m(this,a,h,g);return j(this,a,h.open(k(this,a,f)),f),b(this,a,i)},HTMLTextAreaElement.prototype.bind=function(a,b,c){if("value"!==a)return HTMLElement.prototype.bind.call(this,a,b,c);if(this.removeAttribute("value"),c)return j(this,"value",b);var e=b,f=m(this,"value",e);return j(this,"value",e.open(k(this,"value",d))),t(this,a,f)},HTMLOptionElement.prototype.bind=function(a,b,c){if("value"!==a)return HTMLElement.prototype.bind.call(this,a,b,c);if(this.removeAttribute("value"),c)return q(this,b);var d=b,e=m(this,"value",d);
+return q(this,d.open(r(this))),t(this,a,e)},HTMLSelectElement.prototype.bind=function(a,c,d){if("selectedindex"===a&&(a="selectedIndex"),"selectedIndex"!==a&&"value"!==a)return HTMLElement.prototype.bind.call(this,a,c,d);if(this.removeAttribute(a),d)return j(this,a,c);var e=c,f=m(this,a,e);return j(this,a,e.open(k(this,a))),b(this,a,f)}}(this),function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a){for(var b;b=a.parentNode;)a=b;return a}function d(a,b){if(b){for(var d,e="#"+b;!d&&(a=c(a),a.protoContent_?d=a.protoContent_.querySelector(e):a.getElementById&&(d=a.getElementById(b)),!d&&a.templateCreator_);)a=a.templateCreator_;return d}}function e(a){return"template"==a.tagName&&"http://www.w3.org/2000/svg"==a.namespaceURI}function f(a){return"TEMPLATE"==a.tagName&&"http://www.w3.org/1999/xhtml"==a.namespaceURI}function g(a){return Boolean(L[a.tagName]&&a.hasAttribute("template"))}function h(a){return void 0===a.isTemplate_&&(a.isTemplate_="TEMPLATE"==a.tagName||g(a)),a.isTemplate_}function i(a,b){var c=a.querySelectorAll(N);h(a)&&b(a),G(c,b)}function j(a){function b(a){HTMLTemplateElement.decorate(a)||j(a.content)}i(a,b)}function k(a,b){Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))})}function l(a){var b=a.ownerDocument;if(!b.defaultView)return b;var c=b.templateContentsOwner_;if(!c){for(c=b.implementation.createHTMLDocument("");c.lastChild;)c.removeChild(c.lastChild);b.templateContentsOwner_=c}return c}function m(a){if(!a.stagingDocument_){var b=a.ownerDocument;if(!b.stagingDocument_){b.stagingDocument_=b.implementation.createHTMLDocument(""),b.stagingDocument_.isStagingDocument=!0;var c=b.stagingDocument_.createElement("base");c.href=document.baseURI,b.stagingDocument_.head.appendChild(c),b.stagingDocument_.stagingDocument_=b.stagingDocument_}a.stagingDocument_=b.stagingDocument_}return a.stagingDocument_}function n(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];K[e.name]&&("template"!==e.name&&b.setAttribute(e.name,e.value),a.removeAttribute(e.name))}return b}function o(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];b.setAttribute(e.name,e.value),a.removeAttribute(e.name)}return a.parentNode.removeChild(a),b}function p(a,b,c){var d=a.content;if(c)return void d.appendChild(b);for(var e;e=b.firstChild;)d.appendChild(e)}function q(a){P?a.__proto__=HTMLTemplateElement.prototype:k(a,HTMLTemplateElement.prototype)}function r(a){a.setModelFn_||(a.setModelFn_=function(){a.setModelFnScheduled_=!1;var b=z(a,a.delegate_&&a.delegate_.prepareBinding);w(a,b,a.model_)}),a.setModelFnScheduled_||(a.setModelFnScheduled_=!0,Observer.runEOM_(a.setModelFn_))}function s(a,b,c,d){if(a&&a.length){for(var e,f=a.length,g=0,h=0,i=0,j=!0;f>h;){var g=a.indexOf("{{",h),k=a.indexOf("[[",h),l=!1,m="}}";if(k>=0&&(0>g||g>k)&&(g=k,l=!0,m="]]"),i=0>g?-1:a.indexOf(m,g+2),0>i){if(!e)return;e.push(a.slice(h));break}e=e||[],e.push(a.slice(h,g));var n=a.slice(g+2,i).trim();e.push(l),j=j&&l;var o=d&&d(n,b,c);e.push(null==o?Path.get(n):null),e.push(o),h=i+2}return h===f&&e.push(""),e.hasOnePath=5===e.length,e.isSimplePath=e.hasOnePath&&""==e[0]&&""==e[4],e.onlyOneTime=j,e.combinator=function(a){for(var b=e[0],c=1;c<e.length;c+=4){var d=e.hasOnePath?a:a[(c-1)/4];void 0!==d&&(b+=d),b+=e[c+3]}return b},e}}function t(a,b,c,d){if(b.hasOnePath){var e=b[3],f=e?e(d,c,!0):b[2].getValueFrom(d);return b.isSimplePath?f:b.combinator(f)}for(var g=[],h=1;h<b.length;h+=4){var e=b[h+2];g[(h-1)/4]=e?e(d,c):b[h+1].getValueFrom(d)}return b.combinator(g)}function u(a,b,c,d){var e=b[3],f=e?e(d,c,!1):new PathObserver(d,b[2]);return b.isSimplePath?f:new ObserverTransform(f,b.combinator)}function v(a,b,c,d){if(b.onlyOneTime)return t(a,b,c,d);if(b.hasOnePath)return u(a,b,c,d);for(var e=new CompoundObserver,f=1;f<b.length;f+=4){var g=b[f],h=b[f+2];if(h){var i=h(d,c,g);g?e.addPath(i):e.addObserver(i)}else{var j=b[f+1];g?e.addPath(j.getValueFrom(d)):e.addPath(d,j)}}return new ObserverTransform(e,b.combinator)}function w(a,b,c,d){for(var e=0;e<b.length;e+=2){var f=b[e],g=b[e+1],h=v(f,g,a,c),i=a.bind(f,h,g.onlyOneTime);i&&d&&d.push(i)}if(a.bindFinished(),b.isTemplate){a.model_=c;var j=a.processBindingDirectives_(b);d&&j&&d.push(j)}}function x(a,b,c){var d=a.getAttribute(b);return s(""==d?"{{}}":d,b,a,c)}function y(a,c){b(a);for(var d=[],e=0;e<a.attributes.length;e++){for(var f=a.attributes[e],g=f.name,i=f.value;"_"===g[0];)g=g.substring(1);if(!h(a)||g!==J&&g!==H&&g!==I){var j=s(i,g,a,c);j&&d.push(g,j)}}return h(a)&&(d.isTemplate=!0,d["if"]=x(a,J,c),d.bind=x(a,H,c),d.repeat=x(a,I,c),!d["if"]||d.bind||d.repeat||(d.bind=s("{{}}",H,a,c))),d}function z(a,b){if(a.nodeType===Node.ELEMENT_NODE)return y(a,b);if(a.nodeType===Node.TEXT_NODE){var c=s(a.data,"textContent",a,b);if(c)return["textContent",c]}return[]}function A(a,b,c,d,e,f,g){for(var h=b.appendChild(c.importNode(a,!1)),i=0,j=a.firstChild;j;j=j.nextSibling)A(j,h,c,d.children[i++],e,f,g);return d.isTemplate&&(HTMLTemplateElement.decorate(h,a),f&&h.setDelegate_(f)),w(h,d,e,g),h}function B(a,b){var c=z(a,b);c.children={};for(var d=0,e=a.firstChild;e;e=e.nextSibling)c.children[d++]=B(e,b);return c}function C(a){var b=a.id_;return b||(b=a.id_=S++),b}function D(a,b){var c=C(a);if(b){var d=b.bindingMaps[c];return d||(d=b.bindingMaps[c]=B(a,b.prepareBinding)||[]),d}var d=a.bindingMap_;return d||(d=a.bindingMap_=B(a,void 0)||[]),d}function E(a){this.closed=!1,this.templateElement_=a,this.instances=[],this.deps=void 0,this.iteratedValue=[],this.presentValue=void 0,this.arrayObserver=void 0}var F,G=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.Map&&"function"==typeof a.Map.prototype.forEach?F=a.Map:(F=function(){this.keys=[],this.values=[]},F.prototype={set:function(a,b){var c=this.keys.indexOf(a);0>c?(this.keys.push(a),this.values.push(b)):this.values[c]=b},get:function(a){var b=this.keys.indexOf(a);if(!(0>b))return this.values[b]},"delete":function(a){var b=this.keys.indexOf(a);return 0>b?!1:(this.keys.splice(b,1),this.values.splice(b,1),!0)},forEach:function(a,b){for(var c=0;c<this.keys.length;c++)a.call(b||this,this.values[c],this.keys[c],this)}});"function"!=typeof document.contains&&(Document.prototype.contains=function(a){return a===this||a.parentNode===this?!0:this.documentElement.contains(a)});var H="bind",I="repeat",J="if",K={template:!0,repeat:!0,bind:!0,ref:!0,"if":!0},L={THEAD:!0,TBODY:!0,TFOOT:!0,TH:!0,TR:!0,TD:!0,COLGROUP:!0,COL:!0,CAPTION:!0,OPTION:!0,OPTGROUP:!0},M="undefined"!=typeof HTMLTemplateElement;M&&!function(){var a=document.createElement("template"),b=a.content.ownerDocument,c=b.appendChild(b.createElement("html")),d=c.appendChild(b.createElement("head")),e=b.createElement("base");e.href=document.baseURI,d.appendChild(e)}();var N="template, "+Object.keys(L).map(function(a){return a.toLowerCase()+"[template]"}).join(", ");document.addEventListener("DOMContentLoaded",function(){j(document),Platform.performMicrotaskCheckpoint()},!1),M||(a.HTMLTemplateElement=function(){throw TypeError("Illegal constructor")});var O,P="__proto__"in{};"function"==typeof MutationObserver&&(O=new MutationObserver(function(a){for(var b=0;b<a.length;b++)a[b].target.refChanged_()})),HTMLTemplateElement.decorate=function(a,c){if(a.templateIsDecorated_)return!1;var d=a;d.templateIsDecorated_=!0;var h=f(d)&&M,i=h,k=!h,m=!1;if(h||(g(d)?(b(!c),d=n(a),d.templateIsDecorated_=!0,h=M,m=!0):e(d)&&(d=o(a),d.templateIsDecorated_=!0,h=M)),!h){q(d);var r=l(d);d.content_=r.createDocumentFragment()}return c?d.instanceRef_=c:k?p(d,a,m):i&&j(d.content),!0},HTMLTemplateElement.bootstrap=j;var Q=a.HTMLUnknownElement||HTMLElement,R={get:function(){return this.content_},enumerable:!0,configurable:!0};M||(HTMLTemplateElement.prototype=Object.create(Q.prototype),Object.defineProperty(HTMLTemplateElement.prototype,"content",R)),k(HTMLTemplateElement.prototype,{bind:function(a,b,c){if("ref"!=a)return Element.prototype.bind.call(this,a,b,c);var d=this,e=c?b:b.open(function(a){d.setAttribute("ref",a),d.refChanged_()});return this.setAttribute("ref",e),this.refChanged_(),c?void 0:(this.bindings_?this.bindings_.ref=b:this.bindings_={ref:b},b)},processBindingDirectives_:function(a){return this.iterator_&&this.iterator_.closeDeps(),a["if"]||a.bind||a.repeat?(this.iterator_||(this.iterator_=new E(this)),this.iterator_.updateDependencies(a,this.model_),O&&O.observe(this,{attributes:!0,attributeFilter:["ref"]}),this.iterator_):void(this.iterator_&&(this.iterator_.close(),this.iterator_=void 0))},createInstance:function(a,b,c){b?c=this.newDelegate_(b):c||(c=this.delegate_),this.refContent_||(this.refContent_=this.ref_.content);var d=this.refContent_;if(null===d.firstChild)return T;var e=D(d,c),f=m(this),g=f.createDocumentFragment();g.templateCreator_=this,g.protoContent_=d,g.bindings_=[],g.terminator_=null;for(var h=g.templateInstance_={firstNode:null,lastNode:null,model:a},i=0,j=!1,k=d.firstChild;k;k=k.nextSibling){null===k.nextSibling&&(j=!0);var l=A(k,g,f,e.children[i++],a,c,g.bindings_);l.templateInstance_=h,j&&(g.terminator_=l)}return h.firstNode=g.firstChild,h.lastNode=g.lastChild,g.templateCreator_=void 0,g.protoContent_=void 0,g},get model(){return this.model_},set model(a){this.model_=a,r(this)},get bindingDelegate(){return this.delegate_&&this.delegate_.raw},refChanged_:function(){this.iterator_&&this.refContent_!==this.ref_.content&&(this.refContent_=void 0,this.iterator_.valueChanged(),this.iterator_.updateIteratedValue(this.iterator_.getUpdatedValue()))},clear:function(){this.model_=void 0,this.delegate_=void 0,this.bindings_&&this.bindings_.ref&&this.bindings_.ref.close(),this.refContent_=void 0,this.iterator_&&(this.iterator_.valueChanged(),this.iterator_.close(),this.iterator_=void 0)},setDelegate_:function(a){this.delegate_=a,this.bindingMap_=void 0,this.iterator_&&(this.iterator_.instancePositionChangedFn_=void 0,this.iterator_.instanceModelFn_=void 0)},newDelegate_:function(a){function b(b){var c=a&&a[b];if("function"==typeof c)return function(){return c.apply(a,arguments)}}if(a)return{bindingMaps:{},raw:a,prepareBinding:b("prepareBinding"),prepareInstanceModel:b("prepareInstanceModel"),prepareInstancePositionChanged:b("prepareInstancePositionChanged")}},set bindingDelegate(a){if(this.delegate_)throw Error("Template must be cleared before a new bindingDelegate can be assigned");this.setDelegate_(this.newDelegate_(a))},get ref_(){var a=d(this,this.getAttribute("ref"));if(a||(a=this.instanceRef_),!a)return this;var b=a.ref_;return b?b:a}});var S=1;Object.defineProperty(Node.prototype,"templateInstance",{get:function(){var a=this.templateInstance_;return a?a:this.parentNode?this.parentNode.templateInstance:void 0}});var T=document.createDocumentFragment();T.bindings_=[],T.terminator_=null,E.prototype={closeDeps:function(){var a=this.deps;a&&(a.ifOneTime===!1&&a.ifValue.close(),a.oneTime===!1&&a.value.close())},updateDependencies:function(a,b){this.closeDeps();var c=this.deps={},d=this.templateElement_,e=!0;if(a["if"]){if(c.hasIf=!0,c.ifOneTime=a["if"].onlyOneTime,c.ifValue=v(J,a["if"],d,b),e=c.ifValue,c.ifOneTime&&!e)return void this.valueChanged();c.ifOneTime||(e=e.open(this.updateIfValue,this))}a.repeat?(c.repeat=!0,c.oneTime=a.repeat.onlyOneTime,c.value=v(I,a.repeat,d,b)):(c.repeat=!1,c.oneTime=a.bind.onlyOneTime,c.value=v(H,a.bind,d,b));var f=c.value;return c.oneTime||(f=f.open(this.updateIteratedValue,this)),e?void this.updateValue(f):void this.valueChanged()},getUpdatedValue:function(){var a=this.deps.value;return this.deps.oneTime||(a=a.discardChanges()),a},updateIfValue:function(a){return a?void this.updateValue(this.getUpdatedValue()):void this.valueChanged()},updateIteratedValue:function(a){if(this.deps.hasIf){var b=this.deps.ifValue;if(this.deps.ifOneTime||(b=b.discardChanges()),!b)return void this.valueChanged()}this.updateValue(a)},updateValue:function(a){this.deps.repeat||(a=[a]);var b=this.deps.repeat&&!this.deps.oneTime&&Array.isArray(a);this.valueChanged(a,b)},valueChanged:function(a,b){Array.isArray(a)||(a=[]),a!==this.iteratedValue&&(this.unobserve(),this.presentValue=a,b&&(this.arrayObserver=new ArrayObserver(this.presentValue),this.arrayObserver.open(this.handleSplices,this)),this.handleSplices(ArrayObserver.calculateSplices(this.presentValue,this.iteratedValue)))},getLastInstanceNode:function(a){if(-1==a)return this.templateElement_;var b=this.instances[a],c=b.terminator_;if(!c)return this.getLastInstanceNode(a-1);if(c.nodeType!==Node.ELEMENT_NODE||this.templateElement_===c)return c;var d=c.iterator_;return d?d.getLastTemplateNode():c},getLastTemplateNode:function(){return this.getLastInstanceNode(this.instances.length-1)},insertInstanceAt:function(a,b){var c=this.getLastInstanceNode(a-1),d=this.templateElement_.parentNode;this.instances.splice(a,0,b),d.insertBefore(b,c.nextSibling)},extractInstanceAt:function(a){for(var b=this.getLastInstanceNode(a-1),c=this.getLastInstanceNode(a),d=this.templateElement_.parentNode,e=this.instances.splice(a,1)[0];c!==b;){var f=b.nextSibling;f==c&&(c=b),e.appendChild(d.removeChild(f))}return e},getDelegateFn:function(a){return a=a&&a(this.templateElement_),"function"==typeof a?a:null},handleSplices:function(a){if(!this.closed&&a.length){var b=this.templateElement_;if(!b.parentNode)return void this.close();ArrayObserver.applySplices(this.iteratedValue,this.presentValue,a);var c=b.delegate_;void 0===this.instanceModelFn_&&(this.instanceModelFn_=this.getDelegateFn(c&&c.prepareInstanceModel)),void 0===this.instancePositionChangedFn_&&(this.instancePositionChangedFn_=this.getDelegateFn(c&&c.prepareInstancePositionChanged));for(var d=new F,e=0,f=0;f<a.length;f++){for(var g=a[f],h=g.removed,i=0;i<h.length;i++){var j=h[i],k=this.extractInstanceAt(g.index+e);k!==T&&d.set(j,k)}e-=g.addedCount}for(var f=0;f<a.length;f++)for(var g=a[f],l=g.index;l<g.index+g.addedCount;l++){var j=this.iteratedValue[l],k=d.get(j);k?d["delete"](j):(this.instanceModelFn_&&(j=this.instanceModelFn_(j)),k=void 0===j?T:b.createInstance(j,void 0,c)),this.insertInstanceAt(l,k)}d.forEach(function(a){this.closeInstanceBindings(a)},this),this.instancePositionChangedFn_&&this.reportInstancesMoved(a)}},reportInstanceMoved:function(a){var b=this.instances[a];b!==T&&this.instancePositionChangedFn_(b.templateInstance_,a)},reportInstancesMoved:function(a){for(var b=0,c=0,d=0;d<a.length;d++){var e=a[d];if(0!=c)for(;b<e.index;)this.reportInstanceMoved(b),b++;else b=e.index;for(;b<e.index+e.addedCount;)this.reportInstanceMoved(b),b++;c+=e.addedCount-e.removed.length}if(0!=c)for(var f=this.instances.length;f>b;)this.reportInstanceMoved(b),b++},closeInstanceBindings:function(a){for(var b=a.bindings_,c=0;c<b.length;c++)b[c].close()},unobserve:function(){this.arrayObserver&&(this.arrayObserver.close(),this.arrayObserver=void 0)},close:function(){if(!this.closed){this.unobserve();for(var a=0;a<this.instances.length;a++)this.closeInstanceBindings(this.instances[a]);this.instances.length=0,this.closeDeps(),this.templateElement_.iterator_=void 0,this.closed=!0}}},HTMLTemplateElement.forAllTemplatesFrom_=i}(this),function(a){"use strict";function b(a){return void 0!==m[a]}function c(){h.call(this),this._isInvalid=!0}function d(a){return""==a&&c.call(this),a.toLowerCase()}function e(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,63,96].indexOf(b)?a:encodeURIComponent(a)}function f(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,96].indexOf(b)?a:encodeURIComponent(a)}function g(a,g,h){function i(a){t.push(a)}var j=g||"scheme start",k=0,l="",r=!1,s=!1,t=[];a:for(;(a[k-1]!=o||0==k)&&!this._isInvalid;){var u=a[k];switch(j){case"scheme start":if(!u||!p.test(u)){if(g){i("Invalid scheme.");break a}l="",j="no scheme";continue}l+=u.toLowerCase(),j="scheme";break;case"scheme":if(u&&q.test(u))l+=u.toLowerCase();else{if(":"!=u){if(g){if(o==u)break a;i("Code point not allowed in scheme: "+u);break a}l="",k=0,j="no scheme";continue}if(this._scheme=l,l="",g)break a;b(this._scheme)&&(this._isRelative=!0),j="file"==this._scheme?"relative":this._isRelative&&h&&h._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==u?(query="?",j="query"):"#"==u?(this._fragment="#",j="fragment"):o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._schemeData+=e(u));break;case"no scheme":if(h&&b(h._scheme)){j="relative";continue}i("Missing scheme."),c.call(this);break;case"relative or authority":if("/"!=u||"/"!=a[k+1]){i("Expected /, got: "+u),j="relative";continue}j="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=h._scheme),o==u){this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query;break a}if("/"==u||"\\"==u)"\\"==u&&i("\\ is an invalid code point."),j="relative slash";else if("?"==u)this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query="?",j="query";else{if("#"!=u){var v=a[k+1],w=a[k+2];("file"!=this._scheme||!p.test(u)||":"!=v&&"|"!=v||o!=w&&"/"!=w&&"\\"!=w&&"?"!=w&&"#"!=w)&&(this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._path.pop()),j="relative path";continue}this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query,this._fragment="#",j="fragment"}break;case"relative slash":if("/"!=u&&"\\"!=u){"file"!=this._scheme&&(this._host=h._host,this._port=h._port),j="relative path";continue}"\\"==u&&i("\\ is an invalid code point."),j="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=u){i("Expected '/', got: "+u),j="authority ignore slashes";continue}j="authority second slash";break;case"authority second slash":if(j="authority ignore slashes","/"!=u){i("Expected '/', got: "+u);continue}break;case"authority ignore slashes":if("/"!=u&&"\\"!=u){j="authority";continue}i("Expected authority, got: "+u);break;case"authority":if("@"==u){r&&(i("@ already seen."),l+="%40"),r=!0;for(var x=0;x<l.length;x++){var y=l[x];if("	"!=y&&"\n"!=y&&"\r"!=y)if(":"!=y||null!==this._password){var z=e(y);null!==this._password?this._password+=z:this._username+=z}else this._password="";else i("Invalid whitespace in authority.")}l=""}else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){k-=l.length,l="",j="host";continue}l+=u}break;case"file host":if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){2!=l.length||!p.test(l[0])||":"!=l[1]&&"|"!=l[1]?0==l.length?j="relative path start":(this._host=d.call(this,l),l="",j="relative path start"):j="relative path";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid whitespace in file host."):l+=u;break;case"host":case"hostname":if(":"!=u||s){if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){if(this._host=d.call(this,l),l="",j="relative path start",g)break a;continue}"	"!=u&&"\n"!=u&&"\r"!=u?("["==u?s=!0:"]"==u&&(s=!1),l+=u):i("Invalid code point in host/hostname: "+u)}else if(this._host=d.call(this,l),l="",j="port","hostname"==g)break a;break;case"port":if(/[0-9]/.test(u))l+=u;else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u||g){if(""!=l){var A=parseInt(l,10);A!=m[this._scheme]&&(this._port=A+""),l=""}if(g)break a;j="relative path start";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid code point in port: "+u):c.call(this)}break;case"relative path start":if("\\"==u&&i("'\\' not allowed in path."),j="relative path","/"!=u&&"\\"!=u)continue;break;case"relative path":if(o!=u&&"/"!=u&&"\\"!=u&&(g||"?"!=u&&"#"!=u))"	"!=u&&"\n"!=u&&"\r"!=u&&(l+=e(u));else{"\\"==u&&i("\\ not allowed in relative path.");var B;(B=n[l.toLowerCase()])&&(l=B),".."==l?(this._path.pop(),"/"!=u&&"\\"!=u&&this._path.push("")):"."==l&&"/"!=u&&"\\"!=u?this._path.push(""):"."!=l&&("file"==this._scheme&&0==this._path.length&&2==l.length&&p.test(l[0])&&"|"==l[1]&&(l=l[0]+":"),this._path.push(l)),l="","?"==u?(this._query="?",j="query"):"#"==u&&(this._fragment="#",j="fragment")}break;case"query":g||"#"!=u?o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._query+=f(u)):(this._fragment="#",j="fragment");break;case"fragment":o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._fragment+=u)}k++}}function h(){this._scheme="",this._schemeData="",this._username="",this._password=null,this._host="",this._port="",this._path=[],this._query="",this._fragment="",this._isInvalid=!1,this._isRelative=!1}function i(a,b){void 0===b||b instanceof i||(b=new i(String(b))),this._url=a,h.call(this);var c=a.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g,"");g.call(this,c,null,b)}var j=!1;if(!a.forceJURL)try{var k=new URL("b","http://a");k.pathname="c%20d",j="http://a/c%20d"===k.href}catch(l){}if(!j){var m=Object.create(null);m.ftp=21,m.file=0,m.gopher=70,m.http=80,m.https=443,m.ws=80,m.wss=443;var n=Object.create(null);n["%2e"]=".",n[".%2e"]="..",n["%2e."]="..",n["%2e%2e"]="..";var o=void 0,p=/[a-zA-Z]/,q=/[a-zA-Z0-9\+\-\.]/;i.prototype={get href(){if(this._isInvalid)return this._url;var a="";return(""!=this._username||null!=this._password)&&(a=this._username+(null!=this._password?":"+this._password:"")+"@"),this.protocol+(this._isRelative?"//"+a+this.host:"")+this.pathname+this._query+this._fragment},set href(a){h.call(this),g.call(this,a)},get protocol(){return this._scheme+":"},set protocol(a){this._isInvalid||g.call(this,a+":","scheme start")},get host(){return this._isInvalid?"":this._port?this._host+":"+this._port:this._host},set host(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"host")},get hostname(){return this._host},set hostname(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"hostname")},get port(){return this._port},set port(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"port")},get pathname(){return this._isInvalid?"":this._isRelative?"/"+this._path.join("/"):this._schemeData},set pathname(a){!this._isInvalid&&this._isRelative&&(this._path=[],g.call(this,a,"relative path start"))},get search(){return this._isInvalid||!this._query||"?"==this._query?"":this._query},set search(a){!this._isInvalid&&this._isRelative&&(this._query="?","?"==a[0]&&(a=a.slice(1)),g.call(this,a,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fragment},set hash(a){this._isInvalid||(this._fragment="#","#"==a[0]&&(a=a.slice(1)),g.call(this,a,"fragment"))},get origin(){var a;if(this._isInvalid||!this._scheme)return"";switch(this._scheme){case"data":case"file":case"javascript":case"mailto":return"null"}return a=this.host,a?this._scheme+"://"+a:""}};var r=a.URL;r&&(i.createObjectURL=function(){return r.createObjectURL.apply(r,arguments)},i.revokeObjectURL=function(a){r.revokeObjectURL(a)}),a.URL=i}}(this),function(a){function b(a){f.textContent=d++,e.push(a)}function c(){for(;e.length;)e.shift()()}var d=0,e=[],f=document.createTextNode("");new(window.MutationObserver||JsMutationObserver)(c).observe(f,{characterData:!0}),a.endOfMicrotask=b,Platform.endOfMicrotask=b}(Polymer),function(a){function b(){g||(g=!0,c(function(){g=!1,d.data&&console.group("flush"),Platform.performMicrotaskCheckpoint(),d.data&&console.groupEnd()}))}var c=a.endOfMicrotask,d=window.WebComponents?WebComponents.flags.log:{},e=document.createElement("style");e.textContent="template {display: none !important;} /* injected by platform.js */";var f=document.querySelector("head");f.insertBefore(e,f.firstChild);var g;if(Observer.hasObjectObserve)b=function(){};else{var h=125;window.addEventListener("WebComponentsReady",function(){b();var c=function(){"hidden"===document.visibilityState?a.flushPoll&&clearInterval(a.flushPoll):a.flushPoll=setInterval(b,h)};"string"==typeof document.visibilityState&&document.addEventListener("visibilitychange",c),c()})}if(window.CustomElements&&!CustomElements.useNative){var i=Document.prototype.importNode;Document.prototype.importNode=function(a,b){var c=i.call(this,a,b);return CustomElements.upgradeAll(c),c}}a.flush=b,Platform.flush=b}(window.Polymer),function(a){function b(a){var b=new URL(a.ownerDocument.baseURI);return b.search="",b.hash="",b}function c(a,b,c,e){return a.replace(e,function(a,e,f,g){var h=f.replace(/["']/g,"");return h=d(b,h,c),e+"'"+h+"'"+g})}function d(a,b,c){if(b&&"/"===b[0])return b;if(b&&"#"===b[0])return b;var d=new URL(b,a);return c?d.href:e(d.href)}function e(a){var c=b(document.documentElement),d=new URL(a,c);return d.host===c.host&&d.port===c.port&&d.protocol===c.protocol?f(c,d):a}function f(a,b){for(var c=a.pathname,d=b.pathname,e=c.split("/"),f=d.split("/");e.length&&e[0]===f[0];)e.shift(),f.shift();for(var g=0,h=e.length-1;h>g;g++)f.unshift("..");var i=b.href.slice(-1)===m?m:b.hash;return f.join("/")+b.search+i}var g={resolveDom:function(a,c){c=c||b(a),this.resolveAttributes(a,c),this.resolveStyles(a,c);var d=a.querySelectorAll("template");if(d)for(var e,f=0,g=d.length;g>f&&(e=d[f]);f++)e.content&&this.resolveDom(e.content,c)},resolveTemplate:function(a){this.resolveDom(a.content,b(a))},resolveStyles:function(a,b){var c=a.querySelectorAll("style");if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveStyle(d,b)},resolveStyle:function(a,c){c=c||b(a),a.textContent=this.resolveCssText(a.textContent,c)},resolveCssText:function(a,b,d){return a=c(a,b,d,h),c(a,b,d,i)},resolveAttributes:function(a,b){a.hasAttributes&&a.hasAttributes()&&this.resolveElementAttributes(a,b);var c=a&&a.querySelectorAll(k);if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveElementAttributes(d,b)},resolveElementAttributes:function(a,e){e=e||b(a),j.forEach(function(b){var f,g=a.attributes[b],i=g&&g.value;i&&i.search(l)<0&&(f="style"===b?c(i,e,!1,h):d(e,i),g.value=f)})}},h=/(url\()([^)]*)(\))/g,i=/(@import[\s]+(?!url\())([^;]*)(;)/g,j=["href","src","action","style","url"],k="["+j.join("],[")+"]",l="{{.*}}",m="#";a.urlResolver=g}(Polymer),function(a){function b(a){this.cache=Object.create(null),this.map=Object.create(null),this.requests=0,this.regex=a}var c=Polymer.endOfMicrotask;b.prototype={extractUrls:function(a,b){for(var c,d,e=[];c=this.regex.exec(a);)d=new URL(c[1],b),e.push({matched:c[0],url:d.href});return e},process:function(a,b,c){var d=this.extractUrls(a,b),e=c.bind(null,this.map);this.fetch(d,e)},fetch:function(a,b){var c=a.length;if(!c)return b();for(var d,e,f,g=function(){0===--c&&b()},h=0;c>h;h++)d=a[h],f=d.url,e=this.cache[f],e||(e=this.xhr(f),e.match=d,this.cache[f]=e),e.wait(g)},handleXhr:function(a){var b=a.match,c=b.url,d=a.response||a.responseText||"";this.map[c]=d,this.fetch(this.extractUrls(d,c),a.resolve)},xhr:function(a){this.requests++;var b=new XMLHttpRequest;return b.open("GET",a,!0),b.send(),b.onerror=b.onload=this.handleXhr.bind(this,b),b.pending=[],b.resolve=function(){for(var a=b.pending,c=0;c<a.length;c++)a[c]();b.pending=null},b.wait=function(a){b.pending?b.pending.push(a):c(a)},b}},a.Loader=b}(Polymer),function(a){function b(){this.loader=new d(this.regex)}var c=a.urlResolver,d=a.Loader;b.prototype={regex:/@import\s+(?:url)?["'\(]*([^'"\)]*)['"\)]*;/g,resolve:function(a,b,c){var d=function(d){c(this.flatten(a,b,d))}.bind(this);this.loader.process(a,b,d)},resolveNode:function(a,b,c){var d=a.textContent,e=function(b){a.textContent=b,c(a)};this.resolve(d,b,e)},flatten:function(a,b,d){for(var e,f,g,h=this.loader.extractUrls(a,b),i=0;i<h.length;i++)e=h[i],f=e.url,g=c.resolveCssText(d[f],f,!0),g=this.flatten(g,b,d),a=a.replace(e.matched,g);return a},loadStyles:function(a,b,c){function d(){f++,f===g&&c&&c()}for(var e,f=0,g=a.length,h=0;g>h&&(e=a[h]);h++)this.resolveNode(e,b,d)}};var e=new b;a.styleResolver=e}(Polymer),function(a){function b(a,b){return a&&b&&Object.getOwnPropertyNames(b).forEach(function(c){var d=Object.getOwnPropertyDescriptor(b,c);d&&(Object.defineProperty(a,c,d),"function"==typeof d.value&&(d.value.nom=c))}),a}function c(a){for(var b=a||{},c=1;c<arguments.length;c++){var e=arguments[c];try{for(var f in e)d(f,e,b)}catch(g){}}return b}function d(a,b,c){var d=e(b,a);Object.defineProperty(c,a,d)}function e(a,b){if(a){var c=Object.getOwnPropertyDescriptor(a,b);return c||e(Object.getPrototypeOf(a),b)}}a.extend=b,a.mixin=c,Platform.mixin=c}(Polymer),function(a){function b(a,b,d){return a?a.stop():a=new c(this),a.go(b,d),a}var c=function(a){this.context=a,this.boundComplete=this.complete.bind(this)};c.prototype={go:function(a,b){this.callback=a;var c;b?(c=setTimeout(this.boundComplete,b),this.handle=function(){clearTimeout(c)}):(c=requestAnimationFrame(this.boundComplete),this.handle=function(){cancelAnimationFrame(c)})},stop:function(){this.handle&&(this.handle(),this.handle=null)},complete:function(){this.handle&&(this.stop(),this.callback.call(this.context))}},a.job=b}(Polymer),function(a){function b(a,b,c){var d="string"==typeof a?document.createElement(a):a.cloneNode(!0);if(d.innerHTML=b,c)for(var e in c)d.setAttribute(e,c[e]);return d}var c={};HTMLElement.register=function(a,b){c[a]=b},HTMLElement.getPrototypeForTag=function(a){var b=a?c[a]:HTMLElement.prototype;return b||Object.getPrototypeOf(document.createElement(a))};var d=Event.prototype.stopPropagation;Event.prototype.stopPropagation=function(){this.cancelBubble=!0,d.apply(this,arguments)};var e=DOMTokenList.prototype.add,f=DOMTokenList.prototype.remove;DOMTokenList.prototype.add=function(){for(var a=0;a<arguments.length;a++)e.call(this,arguments[a])},DOMTokenList.prototype.remove=function(){for(var a=0;a<arguments.length;a++)f.call(this,arguments[a])},DOMTokenList.prototype.toggle=function(a,b){1==arguments.length&&(b=!this.contains(a)),b?this.add(a):this.remove(a)},DOMTokenList.prototype["switch"]=function(a,b){a&&this.remove(a),b&&this.add(b)};var g=function(){return Array.prototype.slice.call(this)},h=window.NamedNodeMap||window.MozNamedAttrMap||{};NodeList.prototype.array=g,h.prototype.array=g,HTMLCollection.prototype.array=g,a.createDOM=b}(Polymer),function(a){function b(a){var e=b.caller,g=e.nom,h=e._super;h||(g||(g=e.nom=c.call(this,e)),g||console.warn("called super() on a method not installed declaratively (has no .nom property)"),h=d(e,g,f(this)));var i=h[g];return i?(i._super||d(i,g,h),i.apply(this,a||[])):void 0}function c(a){for(var b=this.__proto__;b&&b!==HTMLElement.prototype;){for(var c,d=Object.getOwnPropertyNames(b),e=0,f=d.length;f>e&&(c=d[e]);e++){var g=Object.getOwnPropertyDescriptor(b,c);if("function"==typeof g.value&&g.value===a)return c}b=b.__proto__}}function d(a,b,c){var d=e(c,b,a);return d[b]&&(d[b].nom=b),a._super=d}function e(a,b,c){for(;a;){if(a[b]!==c&&a[b])return a;a=f(a)}return Object}function f(a){return a.__proto__}a["super"]=b}(Polymer),function(a){function b(a){return a}function c(a,b){var c=typeof b;return b instanceof Date&&(c="date"),d[c](a,b)}var d={string:b,undefined:b,date:function(a){return new Date(Date.parse(a)||Date.now())},"boolean":function(a){return""===a?!0:"false"===a?!1:!!a},number:function(a){var b=parseFloat(a);return 0===b&&(b=parseInt(a)),isNaN(b)?a:b},object:function(a,b){if(null===b)return a;try{return JSON.parse(a.replace(/'/g,'"'))}catch(c){return a}},"function":function(a,b){return b}};a.deserializeValue=c}(Polymer),function(a){var b=a.extend,c={};c.declaration={},c.instance={},c.publish=function(a,c){for(var d in a)b(c,a[d])},a.api=c}(Polymer),function(a){var b={async:function(a,b,c){Polymer.flush(),b=b&&b.length?b:[b];var d=function(){(this[a]||a).apply(this,b)}.bind(this),e=c?setTimeout(d,c):requestAnimationFrame(d);return c?e:~e},cancelAsync:function(a){0>a?cancelAnimationFrame(~a):clearTimeout(a)},fire:function(a,b,c,d,e){var f=c||this,b=null===b||void 0===b?{}:b,g=new CustomEvent(a,{bubbles:void 0!==d?d:!0,cancelable:void 0!==e?e:!0,detail:b});return f.dispatchEvent(g),g},asyncFire:function(){this.async("fire",arguments)},classFollows:function(a,b,c){b&&b.classList.remove(c),a&&a.classList.add(c)},injectBoundHTML:function(a,b){var c=document.createElement("template");c.innerHTML=a;var d=this.instanceTemplate(c);return b&&(b.textContent="",b.appendChild(d)),d}},c=function(){},d={};b.asyncMethod=b.async,a.api.instance.utils=b,a.nop=c,a.nob=d}(Polymer),function(a){var b=window.WebComponents?WebComponents.flags.log:{},c="on-",d={EVENT_PREFIX:c,addHostListeners:function(){var a=this.eventDelegates;
+b.events&&Object.keys(a).length>0&&console.log("[%s] addHostListeners:",this.localName,a);for(var c in a){var d=a[c];PolymerGestures.addEventListener(this,c,this.element.getEventHandler(this,this,d))}},dispatchMethod:function(a,c,d){if(a){b.events&&console.group("[%s] dispatch [%s]",a.localName,c);var e="function"==typeof c?c:a[c];e&&e[d?"apply":"call"](a,d),b.events&&console.groupEnd(),Polymer.flush()}}};a.api.instance.events=d,a.addEventListener=function(a,b,c,d){PolymerGestures.addEventListener(wrap(a),b,c,d)},a.removeEventListener=function(a,b,c,d){PolymerGestures.removeEventListener(wrap(a),b,c,d)}}(Polymer),function(a){var b={copyInstanceAttributes:function(){var a=this._instanceAttributes;for(var b in a)this.hasAttribute(b)||this.setAttribute(b,a[b])},takeAttributes:function(){if(this._publishLC)for(var a,b=0,c=this.attributes,d=c.length;(a=c[b])&&d>b;b++)this.attributeToProperty(a.name,a.value)},attributeToProperty:function(b,c){var b=this.propertyForAttribute(b);if(b){if(c&&c.search(a.bindPattern)>=0)return;var d=this[b],c=this.deserializeValue(c,d);c!==d&&(this[b]=c)}},propertyForAttribute:function(a){var b=this._publishLC&&this._publishLC[a];return b},deserializeValue:function(b,c){return a.deserializeValue(b,c)},serializeValue:function(a,b){return"boolean"===b?a?"":void 0:"object"!==b&&"function"!==b&&void 0!==a?a:void 0},reflectPropertyToAttribute:function(a){var b=typeof this[a],c=this.serializeValue(this[a],b);void 0!==c?this.setAttribute(a,c):"boolean"===b&&this.removeAttribute(a)}};a.api.instance.attributes=b}(Polymer),function(a){function b(a,b){return a===b?0!==a||1/a===1/b:f(a)&&f(b)?!0:a!==a&&b!==b}function c(a,b){return void 0===b&&null===a?b:null===b||void 0===b?a:b}var d=window.WebComponents?WebComponents.flags.log:{},e={object:void 0,type:"update",name:void 0,oldValue:void 0},f=Number.isNaN||function(a){return"number"==typeof a&&isNaN(a)},g={createPropertyObserver:function(){var a=this._observeNames;if(a&&a.length){var b=this._propertyObserver=new CompoundObserver(!0);this.registerObserver(b);for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)b.addPath(this,c),this.observeArrayValue(c,this[c],null)}},openPropertyObserver:function(){this._propertyObserver&&this._propertyObserver.open(this.notifyPropertyChanges,this)},notifyPropertyChanges:function(a,b,c){var d,e,f={};for(var g in b)if(d=c[2*g+1],e=this.observe[d]){var h=b[g],i=a[g];this.observeArrayValue(d,i,h),f[e]||(void 0!==h&&null!==h||void 0!==i&&null!==i)&&(f[e]=!0,this.invokeMethod(e,[h,i,arguments]))}},invokeMethod:function(a,b){var c=this[a]||a;"function"==typeof c&&c.apply(this,b)},deliverChanges:function(){this._propertyObserver&&this._propertyObserver.deliver()},observeArrayValue:function(a,b,c){var e=this.observe[a];if(e&&(Array.isArray(c)&&(d.observe&&console.log("[%s] observeArrayValue: unregister observer [%s]",this.localName,a),this.closeNamedObserver(a+"__array")),Array.isArray(b))){d.observe&&console.log("[%s] observeArrayValue: register observer [%s]",this.localName,a,b);var f=new ArrayObserver(b);f.open(function(a){this.invokeMethod(e,[a])},this),this.registerNamedObserver(a+"__array",f)}},emitPropertyChangeRecord:function(a,c,d){if(!b(c,d)&&(this._propertyChanged(a,c,d),Observer.hasObjectObserve)){var f=this._objectNotifier;f||(f=this._objectNotifier=Object.getNotifier(this)),e.object=this,e.name=a,e.oldValue=d,f.notify(e)}},_propertyChanged:function(a){this.reflect[a]&&this.reflectPropertyToAttribute(a)},bindProperty:function(a,b,d){if(d)return void(this[a]=b);var e=this.element.prototype.computed;if(e&&e[a]){var f=a+"ComputedBoundObservable_";return void(this[f]=b)}return this.bindToAccessor(a,b,c)},bindToAccessor:function(a,c,d){function e(b,c){j[f]=b;var d=j[h];d&&"function"==typeof d.setValue&&d.setValue(b),j.emitPropertyChangeRecord(a,b,c)}var f=a+"_",g=a+"Observable_",h=a+"ComputedBoundObservable_";this[g]=c;var i=this[f],j=this,k=c.open(e);if(d&&!b(i,k)){var l=d(i,k);b(k,l)||(k=l,c.setValue&&c.setValue(k))}e(k,i);var m={close:function(){c.close(),j[g]=void 0,j[h]=void 0}};return this.registerObserver(m),m},createComputedProperties:function(){if(this._computedNames)for(var a=0;a<this._computedNames.length;a++){var b=this._computedNames[a],c=this.computed[b];try{var d=PolymerExpressions.getExpression(c),e=d.getBinding(this,this.element.syntax);this.bindToAccessor(b,e)}catch(f){console.error("Failed to create computed property",f)}}},registerObserver:function(a){return this._observers?void this._observers.push(a):void(this._observers=[a])},closeObservers:function(){if(this._observers){for(var a=this._observers,b=0;b<a.length;b++){var c=a[b];c&&"function"==typeof c.close&&c.close()}this._observers=[]}},registerNamedObserver:function(a,b){var c=this._namedObservers||(this._namedObservers={});c[a]=b},closeNamedObserver:function(a){var b=this._namedObservers;return b&&b[a]?(b[a].close(),b[a]=null,!0):void 0},closeNamedObservers:function(){if(this._namedObservers){for(var a in this._namedObservers)this.closeNamedObserver(a);this._namedObservers={}}}};a.api.instance.properties=g}(Polymer),function(a){var b=window.WebComponents?WebComponents.flags.log:{},c={instanceTemplate:function(a){HTMLTemplateElement.decorate(a);for(var b=this.syntax||!a.bindingDelegate&&this.element.syntax,c=a.createInstance(this,b),d=c.bindings_,e=0;e<d.length;e++)this.registerObserver(d[e]);return c},bind:function(a,b,c){var d=this.propertyForAttribute(a);if(d){var e=this.bindProperty(d,b,c);return Platform.enableBindingsReflection&&e&&(e.path=b.path_,this._recordBinding(d,e)),this.reflect[d]&&this.reflectPropertyToAttribute(d),e}return this.mixinSuper(arguments)},_recordBinding:function(a,b){this.bindings_=this.bindings_||{},this.bindings_[a]=b},bindFinished:function(){this.makeElementReady()},asyncUnbindAll:function(){this._unbound||(b.unbind&&console.log("[%s] asyncUnbindAll",this.localName),this._unbindAllJob=this.job(this._unbindAllJob,this.unbindAll,0))},unbindAll:function(){this._unbound||(this.closeObservers(),this.closeNamedObservers(),this._unbound=!0)},cancelUnbindAll:function(){return this._unbound?void(b.unbind&&console.warn("[%s] already unbound, cannot cancel unbindAll",this.localName)):(b.unbind&&console.log("[%s] cancelUnbindAll",this.localName),void(this._unbindAllJob&&(this._unbindAllJob=this._unbindAllJob.stop())))}},d=/\{\{([^{}]*)}}/;a.bindPattern=d,a.api.instance.mdv=c}(Polymer),function(a){function b(a){return a.hasOwnProperty("PolymerBase")}function c(){}var d={PolymerBase:!0,job:function(a,b,c){if("string"!=typeof a)return Polymer.job.call(this,a,b,c);var d="___"+a;this[d]=Polymer.job.call(this,this[d],b,c)},"super":Polymer["super"],created:function(){},ready:function(){},createdCallback:function(){this.templateInstance&&this.templateInstance.model&&console.warn("Attributes on "+this.localName+" were data bound prior to Polymer upgrading the element. This may result in incorrect binding types."),this.created(),this.prepareElement(),this.ownerDocument.isStagingDocument||this.makeElementReady()},prepareElement:function(){return this._elementPrepared?void console.warn("Element already prepared",this.localName):(this._elementPrepared=!0,this.shadowRoots={},this.createPropertyObserver(),this.openPropertyObserver(),this.copyInstanceAttributes(),this.takeAttributes(),void this.addHostListeners())},makeElementReady:function(){this._readied||(this._readied=!0,this.createComputedProperties(),this.parseDeclarations(this.__proto__),this.removeAttribute("unresolved"),this.ready())},attributeChangedCallback:function(a){"class"!==a&&"style"!==a&&this.attributeToProperty(a,this.getAttribute(a)),this.attributeChanged&&this.attributeChanged.apply(this,arguments)},attachedCallback:function(){this.cancelUnbindAll(),this.attached&&this.attached(),this.hasBeenAttached||(this.hasBeenAttached=!0,this.domReady&&this.async("domReady"))},detachedCallback:function(){this.preventDispose||this.asyncUnbindAll(),this.detached&&this.detached(),this.leftView&&this.leftView()},parseDeclarations:function(a){a&&a.element&&(this.parseDeclarations(a.__proto__),a.parseDeclaration.call(this,a.element))},parseDeclaration:function(a){var b=this.fetchTemplate(a);if(b){var c=this.shadowFromTemplate(b);this.shadowRoots[a.name]=c}},fetchTemplate:function(a){return a.querySelector("template")},shadowFromTemplate:function(a){if(a){var b=this.createShadowRoot(),c=this.instanceTemplate(a);return b.appendChild(c),this.shadowRootReady(b,a),b}},lightFromTemplate:function(a,b){if(a){this.eventController=this;var c=this.instanceTemplate(a);return b?this.insertBefore(c,b):this.appendChild(c),this.shadowRootReady(this),c}},shadowRootReady:function(a){this.marshalNodeReferences(a)},marshalNodeReferences:function(a){var b=this.$=this.$||{};if(a)for(var c,d=a.querySelectorAll("[id]"),e=0,f=d.length;f>e&&(c=d[e]);e++)b[c.id]=c},onMutation:function(a,b){var c=new MutationObserver(function(a){b.call(this,c,a),c.disconnect()}.bind(this));c.observe(a,{childList:!0,subtree:!0})}};c.prototype=d,d.constructor=c,a.Base=c,a.isBase=b,a.api.instance.base=d}(Polymer),function(a){function b(a){return a.__proto__}function c(a,b){var c="",d=!1;b&&(c=b.localName,d=b.hasAttribute("is"));var e=WebComponents.ShadowCSS.makeScopeSelector(c,d);return WebComponents.ShadowCSS.shimCssText(a,e)}var d=(window.WebComponents?WebComponents.flags.log:{},window.ShadowDOMPolyfill),e="element",f="controller",g={STYLE_SCOPE_ATTRIBUTE:e,installControllerStyles:function(){var a=this.findStyleScope();if(a&&!this.scopeHasNamedStyle(a,this.localName)){for(var c=b(this),d="";c&&c.element;)d+=c.element.cssTextForScope(f),c=b(c);d&&this.installScopeCssText(d,a)}},installScopeStyle:function(a,b,c){var c=c||this.findStyleScope(),b=b||"";if(c&&!this.scopeHasNamedStyle(c,this.localName+b)){var d="";if(a instanceof Array)for(var e,f=0,g=a.length;g>f&&(e=a[f]);f++)d+=e.textContent+"\n\n";else d=a.textContent;this.installScopeCssText(d,c,b)}},installScopeCssText:function(a,b,e){if(b=b||this.findStyleScope(),e=e||"",b){d&&(a=c(a,b.host));var g=this.element.cssTextToScopeStyle(a,f);Polymer.applyStyleToScope(g,b),this.styleCacheForScope(b)[this.localName+e]=!0}},findStyleScope:function(a){for(var b=a||this;b.parentNode;)b=b.parentNode;return b},scopeHasNamedStyle:function(a,b){var c=this.styleCacheForScope(a);return c[b]},styleCacheForScope:function(a){if(d){var b=a.host?a.host.localName:a.localName;return h[b]||(h[b]={})}return a._scopeStyles=a._scopeStyles||{}}},h={};a.api.instance.styles=g}(Polymer),function(a){function b(a,b){if("string"!=typeof a){var c=b||document._currentScript;if(b=a,a=c&&c.parentNode&&c.parentNode.getAttribute?c.parentNode.getAttribute("name"):"",!a)throw"Element name could not be inferred."}if(f(a))throw"Already registered (Polymer) prototype for element "+a;e(a,b),d(a)}function c(a,b){i[a]=b}function d(a){i[a]&&(i[a].registerWhenReady(),delete i[a])}function e(a,b){return j[a]=b||{}}function f(a){return j[a]}function g(a,b){if("string"!=typeof b)return!1;var c=HTMLElement.getPrototypeForTag(b),d=c&&c.constructor;return d?CustomElements["instanceof"]?CustomElements["instanceof"](a,d):a instanceof d:!1}var h=a.extend,i=(a.api,{}),j={};a.getRegisteredPrototype=f,a.waitingForPrototype=c,a.instanceOfType=g,window.Polymer=b,h(Polymer,a),WebComponents.consumeDeclarations&&WebComponents.consumeDeclarations(function(a){if(a)for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)b.apply(null,c)})}(Polymer),function(a){var b={resolveElementPaths:function(a){Polymer.urlResolver.resolveDom(a)},addResolvePathApi:function(){var a=this.getAttribute("assetpath")||"",b=new URL(a,this.ownerDocument.baseURI);this.prototype.resolvePath=function(a,c){var d=new URL(a,c||b);return d.href}}};a.api.declaration.path=b}(Polymer),function(a){function b(a,b){var c=new URL(a.getAttribute("href"),b).href;return"@import '"+c+"';"}function c(a,b){if(a){b===document&&(b=document.head),i&&(b=document.head);var c=d(a.textContent),e=a.getAttribute(h);e&&c.setAttribute(h,e);var f=b.firstElementChild;if(b===document.head){var g="style["+h+"]",j=document.head.querySelectorAll(g);j.length&&(f=j[j.length-1].nextElementSibling)}b.insertBefore(c,f)}}function d(a,b){b=b||document,b=b.createElement?b:b.ownerDocument;var c=b.createElement("style");return c.textContent=a,c}function e(a){return a&&a.__resource||""}function f(a,b){return q?q.call(a,b):void 0}var g=(window.WebComponents?WebComponents.flags.log:{},a.api.instance.styles),h=g.STYLE_SCOPE_ATTRIBUTE,i=window.ShadowDOMPolyfill,j="style",k="@import",l="link[rel=stylesheet]",m="global",n="polymer-scope",o={loadStyles:function(a){var b=this.fetchTemplate(),c=b&&this.templateContent();if(c){this.convertSheetsToStyles(c);var d=this.findLoadableStyles(c);if(d.length){var e=b.ownerDocument.baseURI;return Polymer.styleResolver.loadStyles(d,e,a)}}a&&a()},convertSheetsToStyles:function(a){for(var c,e,f=a.querySelectorAll(l),g=0,h=f.length;h>g&&(c=f[g]);g++)e=d(b(c,this.ownerDocument.baseURI),this.ownerDocument),this.copySheetAttributes(e,c),c.parentNode.replaceChild(e,c)},copySheetAttributes:function(a,b){for(var c,d=0,e=b.attributes,f=e.length;(c=e[d])&&f>d;d++)"rel"!==c.name&&"href"!==c.name&&a.setAttribute(c.name,c.value)},findLoadableStyles:function(a){var b=[];if(a)for(var c,d=a.querySelectorAll(j),e=0,f=d.length;f>e&&(c=d[e]);e++)c.textContent.match(k)&&b.push(c);return b},installSheets:function(){this.cacheSheets(),this.cacheStyles(),this.installLocalSheets(),this.installGlobalStyles()},cacheSheets:function(){this.sheets=this.findNodes(l),this.sheets.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},cacheStyles:function(){this.styles=this.findNodes(j+"["+n+"]"),this.styles.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},installLocalSheets:function(){var a=this.sheets.filter(function(a){return!a.hasAttribute(n)}),b=this.templateContent();if(b){var c="";if(a.forEach(function(a){c+=e(a)+"\n"}),c){var f=d(c,this.ownerDocument);b.insertBefore(f,b.firstChild)}}},findNodes:function(a,b){var c=this.querySelectorAll(a).array(),d=this.templateContent();if(d){var e=d.querySelectorAll(a).array();c=c.concat(e)}return b?c.filter(b):c},installGlobalStyles:function(){var a=this.styleForScope(m);c(a,document.head)},cssTextForScope:function(a){var b="",c="["+n+"="+a+"]",d=function(a){return f(a,c)},g=this.sheets.filter(d);g.forEach(function(a){b+=e(a)+"\n\n"});var h=this.styles.filter(d);return h.forEach(function(a){b+=a.textContent+"\n\n"}),b},styleForScope:function(a){var b=this.cssTextForScope(a);return this.cssTextToScopeStyle(b,a)},cssTextToScopeStyle:function(a,b){if(a){var c=d(a);return c.setAttribute(h,this.getAttribute("name")+"-"+b),c}}},p=HTMLElement.prototype,q=p.matches||p.matchesSelector||p.webkitMatchesSelector||p.mozMatchesSelector;a.api.declaration.styles=o,a.applyStyleToScope=c}(Polymer),function(a){var b=(window.WebComponents?WebComponents.flags.log:{},a.api.instance.events),c=b.EVENT_PREFIX,d={};["webkitAnimationStart","webkitAnimationEnd","webkitTransitionEnd","DOMFocusOut","DOMFocusIn","DOMMouseScroll"].forEach(function(a){d[a.toLowerCase()]=a});var e={parseHostEvents:function(){var a=this.prototype.eventDelegates;this.addAttributeDelegates(a)},addAttributeDelegates:function(a){for(var b,c=0;b=this.attributes[c];c++)this.hasEventPrefix(b.name)&&(a[this.removeEventPrefix(b.name)]=b.value.replace("{{","").replace("}}","").trim())},hasEventPrefix:function(a){return a&&"o"===a[0]&&"n"===a[1]&&"-"===a[2]},removeEventPrefix:function(a){return a.slice(f)},findController:function(a){for(;a.parentNode;){if(a.eventController)return a.eventController;a=a.parentNode}return a.host},getEventHandler:function(a,b,c){var d=this;return function(e){a&&a.PolymerBase||(a=d.findController(b));var f=[e,e.detail,e.currentTarget];a.dispatchMethod(a,c,f)}},prepareEventBinding:function(a,b){if(this.hasEventPrefix(b)){var c=this.removeEventPrefix(b);c=d[c]||c;var e=this;return function(b,d,f){function g(){return"{{ "+a+" }}"}var h=e.getEventHandler(void 0,d,a);return PolymerGestures.addEventListener(d,c,h),f?void 0:{open:g,discardChanges:g,close:function(){PolymerGestures.removeEventListener(d,c,h)}}}}}},f=c.length;a.api.declaration.events=e}(Polymer),function(a){var b=["attribute"],c={inferObservers:function(a){var b,c=a.observe;for(var d in a)"Changed"===d.slice(-7)&&(b=d.slice(0,-7),this.canObserveProperty(b)&&(c||(c=a.observe={}),c[b]=c[b]||d))},canObserveProperty:function(a){return b.indexOf(a)<0},explodeObservers:function(a){var b=a.observe;if(b){var c={};for(var d in b)for(var e,f=d.split(" "),g=0;e=f[g];g++)c[e]=b[d];a.observe=c}},optimizePropertyMaps:function(a){if(a.observe){var b=a._observeNames=[];for(var c in a.observe)for(var d,e=c.split(" "),f=0;d=e[f];f++)b.push(d)}if(a.publish){var b=a._publishNames=[];for(var c in a.publish)b.push(c)}if(a.computed){var b=a._computedNames=[];for(var c in a.computed)b.push(c)}},publishProperties:function(a,b){var c=a.publish;c&&(this.requireProperties(c,a,b),this.filterInvalidAccessorNames(c),a._publishLC=this.lowerCaseMap(c));var d=a.computed;d&&this.filterInvalidAccessorNames(d)},filterInvalidAccessorNames:function(a){for(var b in a)this.propertyNameBlacklist[b]&&(console.warn('Cannot define property "'+b+'" for element "'+this.name+'" because it has the same name as an HTMLElement property, and not all browsers support overriding that. Consider giving it a different name.'),delete a[b])},requireProperties:function(a,b){b.reflect=b.reflect||{};for(var c in a){var d=a[c];d&&void 0!==d.reflect&&(b.reflect[c]=Boolean(d.reflect),d=d.value),void 0!==d&&(b[c]=d)}},lowerCaseMap:function(a){var b={};for(var c in a)b[c.toLowerCase()]=c;return b},createPropertyAccessor:function(a,b){var c=this.prototype,d=a+"_",e=a+"Observable_";c[d]=c[a],Object.defineProperty(c,a,{get:function(){var a=this[e];return a&&a.deliver(),this[d]},set:function(c){if(b)return this[d];var f=this[e];if(f)return void f.setValue(c);var g=this[d];return this[d]=c,this.emitPropertyChangeRecord(a,c,g),c},configurable:!0})},createPropertyAccessors:function(a){var b=a._computedNames;if(b&&b.length)for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)this.createPropertyAccessor(c,!0);var b=a._publishNames;if(b&&b.length)for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)a.computed&&a.computed[c]||this.createPropertyAccessor(c)},propertyNameBlacklist:{children:1,"class":1,id:1,hidden:1,style:1,title:1}};a.api.declaration.properties=c}(Polymer),function(a){var b="attributes",c=/\s|,/,d={inheritAttributesObjects:function(a){this.inheritObject(a,"publishLC"),this.inheritObject(a,"_instanceAttributes")},publishAttributes:function(a){var d=this.getAttribute(b);if(d)for(var e,f=a.publish||(a.publish={}),g=d.split(c),h=0,i=g.length;i>h;h++)e=g[h].trim(),e&&void 0===f[e]&&(f[e]=void 0)},accumulateInstanceAttributes:function(){for(var a,b=this.prototype._instanceAttributes,c=this.attributes,d=0,e=c.length;e>d&&(a=c[d]);d++)this.isInstanceAttribute(a.name)&&(b[a.name]=a.value)},isInstanceAttribute:function(a){return!this.blackList[a]&&"on-"!==a.slice(0,3)},blackList:{name:1,"extends":1,constructor:1,noscript:1,assetpath:1,"cache-csstext":1}};d.blackList[b]=1,a.api.declaration.attributes=d}(Polymer),function(a){var b=a.api.declaration.events,c=new PolymerExpressions,d=c.prepareBinding;c.prepareBinding=function(a,e,f){return b.prepareEventBinding(a,e,f)||d.call(c,a,e,f)};var e={syntax:c,fetchTemplate:function(){return this.querySelector("template")},templateContent:function(){var a=this.fetchTemplate();return a&&a.content},installBindingDelegate:function(a){a&&(a.bindingDelegate=this.syntax)}};a.api.declaration.mdv=e}(Polymer),function(a){function b(a){if(!Object.__proto__){var b=Object.getPrototypeOf(a);a.__proto__=b,d(b)&&(b.__proto__=Object.getPrototypeOf(b))}}var c=a.api,d=a.isBase,e=a.extend,f=window.ShadowDOMPolyfill,g={register:function(a,b){this.buildPrototype(a,b),this.registerPrototype(a,b),this.publishConstructor()},buildPrototype:function(b,c){var d=a.getRegisteredPrototype(b),e=this.generateBasePrototype(c);this.desugarBeforeChaining(d,e),this.prototype=this.chainPrototypes(d,e),this.desugarAfterChaining(b,c)},desugarBeforeChaining:function(a,b){a.element=this,this.publishAttributes(a,b),this.publishProperties(a,b),this.inferObservers(a),this.explodeObservers(a)},chainPrototypes:function(a,c){this.inheritMetaData(a,c);var d=this.chainObject(a,c);return b(d),d},inheritMetaData:function(a,b){this.inheritObject("observe",a,b),this.inheritObject("publish",a,b),this.inheritObject("reflect",a,b),this.inheritObject("_publishLC",a,b),this.inheritObject("_instanceAttributes",a,b),this.inheritObject("eventDelegates",a,b)},desugarAfterChaining:function(a,b){this.optimizePropertyMaps(this.prototype),this.createPropertyAccessors(this.prototype),this.installBindingDelegate(this.fetchTemplate()),this.installSheets(),this.resolveElementPaths(this),this.accumulateInstanceAttributes(),this.parseHostEvents(),this.addResolvePathApi(),f&&WebComponents.ShadowCSS.shimStyling(this.templateContent(),a,b),this.prototype.registerCallback&&this.prototype.registerCallback(this)},publishConstructor:function(){var a=this.getAttribute("constructor");a&&(window[a]=this.ctor)},generateBasePrototype:function(a){var b=this.findBasePrototype(a);if(!b){var b=HTMLElement.getPrototypeForTag(a);b=this.ensureBaseApi(b),h[a]=b}return b},findBasePrototype:function(a){return h[a]},ensureBaseApi:function(a){if(a.PolymerBase)return a;var b=Object.create(a);return c.publish(c.instance,b),this.mixinMethod(b,a,c.instance.mdv,"bind"),b},mixinMethod:function(a,b,c,d){var e=function(a){return b[d].apply(this,a)};a[d]=function(){return this.mixinSuper=e,c[d].apply(this,arguments)}},inheritObject:function(a,b,c){var d=b[a]||{};b[a]=this.chainObject(d,c[a])},registerPrototype:function(a,b){var c={prototype:this.prototype},d=this.findTypeExtension(b);d&&(c["extends"]=d),HTMLElement.register(a,this.prototype),this.ctor=document.registerElement(a,c)},findTypeExtension:function(a){if(a&&a.indexOf("-")<0)return a;var b=this.findBasePrototype(a);return b.element?this.findTypeExtension(b.element["extends"]):void 0}},h={};g.chainObject=Object.__proto__?function(a,b){return a&&b&&a!==b&&(a.__proto__=b),a}:function(a,b){if(a&&b&&a!==b){var c=Object.create(b);a=e(c,a)}return a},c.declaration.prototype=g}(Polymer),function(a){function b(a){return document.contains(a)?j:i}function c(){return i.length?i[0]:j[0]}function d(a){f.waitToReady=!0,Polymer.endOfMicrotask(function(){HTMLImports.whenReady(function(){f.addReadyCallback(a),f.waitToReady=!1,f.check()})})}function e(a){if(void 0===a)return void f.ready();var b=setTimeout(function(){f.ready()},a);Polymer.whenReady(function(){clearTimeout(b)})}var f={wait:function(a){a.__queue||(a.__queue={},g.push(a))},enqueue:function(a,c,d){var e=a.__queue&&!a.__queue.check;return e&&(b(a).push(a),a.__queue.check=c,a.__queue.go=d),0!==this.indexOf(a)},indexOf:function(a){var c=b(a).indexOf(a);return c>=0&&document.contains(a)&&(c+=HTMLImports.useNative||HTMLImports.ready?i.length:1e9),c},go:function(a){var b=this.remove(a);b&&(a.__queue.flushable=!0,this.addToFlushQueue(b),this.check())},remove:function(a){var c=this.indexOf(a);if(0===c)return b(a).shift()},check:function(){var a=this.nextElement();return a&&a.__queue.check.call(a),this.canReady()?(this.ready(),!0):void 0},nextElement:function(){return c()},canReady:function(){return!this.waitToReady&&this.isEmpty()},isEmpty:function(){for(var a,b=0,c=g.length;c>b&&(a=g[b]);b++)if(a.__queue&&!a.__queue.flushable)return;return!0},addToFlushQueue:function(a){h.push(a)},flush:function(){if(!this.flushing){this.flushing=!0;for(var a;h.length;)a=h.shift(),a.__queue.go.call(a),a.__queue=null;this.flushing=!1}},ready:function(){var a=CustomElements.ready;CustomElements.ready=!1,this.flush(),CustomElements.useNative||CustomElements.upgradeDocumentTree(document),CustomElements.ready=a,Polymer.flush(),requestAnimationFrame(this.flushReadyCallbacks)},addReadyCallback:function(a){a&&k.push(a)},flushReadyCallbacks:function(){if(k)for(var a;k.length;)(a=k.shift())()},waitingFor:function(){for(var a,b=[],c=0,d=g.length;d>c&&(a=g[c]);c++)a.__queue&&!a.__queue.flushable&&b.push(a);return b},waitToReady:!0},g=[],h=[],i=[],j=[],k=[];a.elements=g,a.waitingFor=f.waitingFor.bind(f),a.forceReady=e,a.queue=f,a.whenReady=a.whenPolymerReady=d}(Polymer),function(a){function b(a){return Boolean(HTMLElement.getPrototypeForTag(a))}function c(a){return a&&a.indexOf("-")>=0}var d=a.extend,e=a.api,f=a.queue,g=a.whenReady,h=a.getRegisteredPrototype,i=a.waitingForPrototype,j=d(Object.create(HTMLElement.prototype),{createdCallback:function(){this.getAttribute("name")&&this.init()},init:function(){this.name=this.getAttribute("name"),this["extends"]=this.getAttribute("extends"),f.wait(this),this.loadResources(),this.registerWhenReady()},registerWhenReady:function(){this.registered||this.waitingForPrototype(this.name)||this.waitingForQueue()||this.waitingForResources()||f.go(this)},_register:function(){c(this["extends"])&&!b(this["extends"])&&console.warn("%s is attempting to extend %s, an unregistered element or one that was not registered with Polymer.",this.name,this["extends"]),this.register(this.name,this["extends"]),this.registered=!0},waitingForPrototype:function(a){return h(a)?void 0:(i(a,this),this.handleNoScript(a),!0)},handleNoScript:function(a){this.hasAttribute("noscript")&&!this.noscript&&(this.noscript=!0,Polymer(a))},waitingForResources:function(){return this._needsResources},waitingForQueue:function(){return f.enqueue(this,this.registerWhenReady,this._register)},loadResources:function(){this._needsResources=!0,this.loadStyles(function(){this._needsResources=!1,this.registerWhenReady()}.bind(this))}});e.publish(e.declaration,j),g(function(){document.body.removeAttribute("unresolved"),document.dispatchEvent(new CustomEvent("polymer-ready",{bubbles:!0}))}),document.registerElement("polymer-element",{prototype:j})}(Polymer),function(a){function b(a,b){a?(document.head.appendChild(a),d(b)):b&&b()}function c(a,c){if(a&&a.length){for(var d,e,f=document.createDocumentFragment(),g=0,h=a.length;h>g&&(d=a[g]);g++)e=document.createElement("link"),e.rel="import",e.href=d,f.appendChild(e);b(f,c)}else c&&c()}var d=a.whenReady;a["import"]=c,a.importElements=b}(Polymer),function(){var a=document.createElement("polymer-element");a.setAttribute("name","auto-binding"),a.setAttribute("extends","template"),a.init(),Polymer("auto-binding",{createdCallback:function(){this.syntax=this.bindingDelegate=this.makeSyntax(),Polymer.whenPolymerReady(function(){this.model=this,this.setAttribute("bind",""),this.async(function(){this.marshalNodeReferences(this.parentNode),this.fire("template-bound")})}.bind(this))},makeSyntax:function(){var a=Object.create(Polymer.api.declaration.events),b=this;a.findController=function(){return b.model};var c=new PolymerExpressions,d=c.prepareBinding;return c.prepareBinding=function(b,e,f){return a.prepareEventBinding(b,e,f)||d.call(c,b,e,f)},c}})}();'use strict';var global=this;this.tr=(function(){if(global.tr){console.warn('Base was multiply initialized. First init wins.');return global.tr;}
+function exportPath(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
+return cur;};function isExported(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
+return true;}
+function isDefined(name){var parts=name.split('.');var curObject=global;for(var i=0;i<parts.length;i++){var partName=parts[i];var nextObject=curObject[partName];if(nextObject===undefined)
+return false;curObject=nextObject;}
+return true;}
+var panicElement=undefined;var rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)
+return;var panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='-webkit-flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
+function showPanic(panicTitle,panicDetails){if(tr.isHeadless){if(panicDetails instanceof Error)
+throw panicDetails;throw new Error('Panic: '+panicTitle+':\n'+panicDetails);}
+if(panicDetails instanceof Error)
+panicDetails=panicDetails.stack;showPanicElementIfNeeded();var panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
+function hasPanic(){return rawPanicMessages.length!==0;}
+function getPanicText(){return rawPanicMessages.map(function(msg){return msg.title;}).join(', ');}
+function exportTo(namespace,fn){var obj=exportPath(namespace);var exports=fn();for(var propertyName in exports){var propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor)
+Object.defineProperty(obj,propertyName,propertyDescriptor);}};function initialize(){if(global.isVinn){tr.isVinn=true;}else if(global.process&&global.process.versions.node){tr.isNode=true;}else{tr.isVinn=false;tr.isNode=false;tr.doc=document;tr.isMac=/Mac/.test(navigator.platform);tr.isWindows=/Win/.test(navigator.platform);tr.isChromeOS=/CrOS/.test(navigator.userAgent);tr.isLinux=/Linux/.test(navigator.userAgent);}
+tr.isHeadless=tr.isVinn||tr.isNode;}
+return{initialize:initialize,exportTo:exportTo,isExported:isExported,isDefined:isDefined,showPanic:showPanic,hasPanic:hasPanic,getPanicText:getPanicText};})();tr.initialize();'use strict';tr.exportTo('tr.b',function(){function asArray(arrayish){var values=[];for(var i=0;i<arrayish.length;i++)
+values.push(arrayish[i]);return values;}
+function compareArrays(x,y,elementCmp){var minLength=Math.min(x.length,y.length);for(var i=0;i<minLength;i++){var tmp=elementCmp(x[i],y[i]);if(tmp)
+return tmp;}
+if(x.length==y.length)
+return 0;if(x[i]===undefined)
+return-1;return 1;}
+function comparePossiblyUndefinedValues(x,y,cmp,opt_this){if(x!==undefined&&y!==undefined)
+return cmp.call(opt_this,x,y);if(x!==undefined)
+return-1;if(y!==undefined)
+return 1;return 0;}
+function compareNumericWithNaNs(x,y){if(!isNaN(x)&&!isNaN(y))
+return x-y;if(isNaN(x))
+return 1;if(isNaN(y))
+return-1;return 0;}
+function concatenateArrays(){var values=[];for(var i=0;i<arguments.length;i++){if(!(arguments[i]instanceof Array))
+throw new Error('Arguments '+i+'is not an array');values.push.apply(values,arguments[i]);}
+return values;}
+function concatenateObjects(){var result={};for(var i=0;i<arguments.length;i++){var object=arguments[i];for(var j in object){result[j]=object[j];}}
+return result;}
+function dictionaryKeys(dict){var keys=[];for(var key in dict)
+keys.push(key);return keys;}
+function dictionaryValues(dict){var values=[];for(var key in dict)
+values.push(dict[key]);return values;}
+function dictionaryLength(dict){var n=0;for(var key in dict)
+n++;return n;}
+function dictionaryContainsValue(dict,value){for(var key in dict)
+if(dict[key]===value)
+return true;return false;}
+function group(ary,fn){return ary.reduce(function(accumulator,curr){var key=fn(curr);if(key in accumulator)
+accumulator[key].push(curr);else
+accumulator[key]=[curr];return accumulator;},{});}
+function iterItems(dict,fn,opt_this){opt_this=opt_this||this;var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];fn.call(opt_this,key,dict[key]);}}
+function mapItems(dict,fn,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];result[key]=fn.call(opt_this,key,dict[key]);}
+return result;}
+function filterItems(dict,predicate,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];var value=dict[key];if(predicate.call(opt_this,key,value))
+result[key]=value;}
+return result;}
+function iterObjectFieldsRecursively(object,func){if(!(object instanceof Object))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++){func(object,i,object[i]);iterObjectFieldsRecursively(object[i],func);}
+return;}
+for(var key in object){var value=object[key];func(object,key,value);iterObjectFieldsRecursively(value,func);}}
+function invertArrayOfDicts(array,opt_dictGetter,opt_this){opt_this=opt_this||this;var result={};for(var i=0;i<array.length;i++){var item=array[i];if(item===undefined)
+continue;var dict=opt_dictGetter?opt_dictGetter.call(opt_this,item):item;if(dict===undefined)
+continue;for(var key in dict){var valueList=result[key];if(valueList===undefined)
+result[key]=valueList=new Array(array.length);valueList[i]=dict[key];}}
+return result;}
+function arrayToDict(array,valueToKeyFn,opt_this){opt_this=opt_this||this;var result={};var length=array.length;for(var i=0;i<length;i++){var value=array[i];var key=valueToKeyFn.call(opt_this,value);result[key]=value;}
+return result;}
+function identity(d){return d;}
+function findFirstIndexInArray(ary,opt_func,opt_this){var func=opt_func||identity;for(var i=0;i<ary.length;i++){if(func.call(opt_this,ary[i],i))
+return i;}
+return-1;}
+function findFirstInArray(ary,opt_func,opt_this){var i=findFirstIndexInArray(ary,opt_func,opt_func);if(i===-1)
+return undefined;return ary[i];}
+function findFirstKeyInDictMatching(dict,opt_func,opt_this){var func=opt_func||identity;for(var key in dict){if(func.call(opt_this,key,dict[key]))
+return key;}
+return undefined;}
+return{asArray:asArray,concatenateArrays:concatenateArrays,concatenateObjects:concatenateObjects,compareArrays:compareArrays,comparePossiblyUndefinedValues:comparePossiblyUndefinedValues,compareNumericWithNaNs:compareNumericWithNaNs,dictionaryLength:dictionaryLength,dictionaryKeys:dictionaryKeys,dictionaryValues:dictionaryValues,dictionaryContainsValue:dictionaryContainsValue,group:group,iterItems:iterItems,mapItems:mapItems,filterItems:filterItems,iterObjectFieldsRecursively:iterObjectFieldsRecursively,invertArrayOfDicts:invertArrayOfDicts,arrayToDict:arrayToDict,identity:identity,findFirstIndexInArray:findFirstIndexInArray,findFirstInArray:findFirstInArray,findFirstKeyInDictMatching:findFirstKeyInDictMatching};});'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
+EventTarget.decorate=function(target){for(var k in EventTarget.prototype){if(k=='decorate')
+continue;var v=EventTarget.prototype[k];if(typeof v!=='function')
+continue;target[k]=v;}};EventTarget.prototype={addEventListener:function(type,handler){if(!this.listeners_)
+this.listeners_=Object.create(null);if(!(type in this.listeners_)){this.listeners_[type]=[handler];}else{var handlers=this.listeners_[type];if(handlers.indexOf(handler)<0)
+handlers.push(handler);}},removeEventListener:function(type,handler){if(!this.listeners_)
+return;if(type in this.listeners_){var handlers=this.listeners_[type];var index=handlers.indexOf(handler);if(index>=0){if(handlers.length==1)
+delete this.listeners_[type];else
+handlers.splice(index,1);}}},dispatchEvent:function(event){if(!this.listeners_)
+return true;var self=this;event.__defineGetter__('target',function(){return self;});var realPreventDefault=event.preventDefault;event.preventDefault=function(){realPreventDefault.call(this);this.rawReturnValue=false;};var type=event.type;var prevented=0;if(type in this.listeners_){var handlers=this.listeners_[type].concat();for(var i=0,handler;handler=handlers[i];i++){if(handler.handleEvent)
+prevented|=handler.handleEvent.call(handler,event)===false;else
+prevented|=handler.call(this,event)===false;}}
+return!prevented&&event.rawReturnValue;},hasEventListener:function(type){return this.listeners_[type]!==undefined;}};var EventTargetHelper={decorate:function(target){for(var k in EventTargetHelper){if(k=='decorate')
+continue;var v=EventTargetHelper[k];if(typeof v!=='function')
+continue;target[k]=v;}
+target.listenerCounts_={};},addEventListener:function(type,listener,useCapture){this.__proto__.addEventListener.call(this,type,listener,useCapture);if(this.listenerCounts_[type]===undefined)
+this.listenerCounts_[type]=0;this.listenerCounts_[type]++;},removeEventListener:function(type,listener,useCapture){this.__proto__.removeEventListener.call(this,type,listener,useCapture);this.listenerCounts_[type]--;},hasEventListener:function(type){return this.listenerCounts_[type]>0;}};return{EventTarget:EventTarget,EventTargetHelper:EventTargetHelper};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;};var BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';var TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';var ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined)
+throw new Error('Mode is required');if(!ALL_MODES[mode])
+throw new Error('Not a mode.');this.mode_=mode;this.defaultMetadata_={};this.defaultConstructor_=undefined;this.mandatoryBaseClass_=undefined;this.defaultTypeInfo_=undefined;this.frozen_=false;}
+ExtensionRegistryOptions.prototype={freeze:function(){if(this.frozen_)
+throw new Error('Frozen');this.frozen_=true;},get mode(){return this.mode_;},get defaultMetadata(){return this.defaultMetadata_;},set defaultMetadata(defaultMetadata){if(this.frozen_)
+throw new Error('Frozen');this.defaultMetadata_=defaultMetadata;this.defaultTypeInfo_=undefined;},get defaultConstructor(){return this.defaultConstructor_;},set defaultConstructor(defaultConstructor){if(this.frozen_)
+throw new Error('Frozen');this.defaultConstructor_=defaultConstructor;this.defaultTypeInfo_=undefined;},get defaultTypeInfo(){if(this.defaultTypeInfo_===undefined&&this.defaultConstructor_){this.defaultTypeInfo_=new RegisteredTypeInfo(this.defaultConstructor,this.defaultMetadata);}
+return this.defaultTypeInfo_;},validateConstructor:function(constructor){if(!this.mandatoryBaseClass)
+return;var curProto=constructor.prototype.__proto__;var ok=false;while(curProto){if(curProto===this.mandatoryBaseClass.prototype){ok=true;break;}
+curProto=curProto.__proto__;}
+if(!ok)
+throw new Error(constructor+'must be subclass of '+registry);}};return{BASIC_REGISTRY_MODE:BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE:TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions:ExtensionRegistryOptions,RegisteredTypeInfo:RegisteredTypeInfo};});'use strict';tr.exportTo('tr.b',function(){var Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;};HeadlessEvent.prototype={preventDefault:function(){this.defaultPrevented=true;},stopPropagation:function(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){var e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;};TrEvent.prototype={__proto__:global.Event.prototype};Event=TrEvent;}
+function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable){var e=new tr.b.Event(type,opt_bubbles,opt_cancelable);return target.dispatchEvent(e);}
+return{Event:Event,dispatchSimpleEvent:dispatchSimpleEvent};});'use strict';tr.exportTo('tr.b',function(){var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined)
+throw new Error('Handler already registered for '+constructor);extensionRegistryOptions.validateConstructor(constructor);var metadata={};for(var k in extensionRegistryOptions.defaultMetadata)
+metadata[k]=extensionRegistryOptions.defaultMetadata[k];if(opt_metadata){for(var k in opt_metadata)
+metadata[k]=opt_metadata[k];}
+var typeInfo=new RegisteredTypeInfo(constructor,metadata);var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push(registry.registeredTypeInfos_);registry.registeredTypeInfos_=[];var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){registry.registeredTypeInfos_=savedStateStack[0];savedStateStack.splice(0,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.findIndexOfRegisteredConstructor=function(constructor){for(var i=0;i<registry.registeredTypeInfos_.length;i++)
+if(registry.registeredTypeInfos_[i].constructor==constructor)
+return i;return undefined;};registry.unregister=function(constructor){var foundIndex=registry.findIndexOfRegisteredConstructor(constructor);if(foundIndex===undefined)
+throw new Error(constructor+' not registered');registry.registeredTypeInfos_.splice(foundIndex,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getAllRegisteredTypeInfos=function(){return registry.registeredTypeInfos_;};registry.findTypeInfo=function(constructor){var foundIndex=this.findIndexOfRegisteredConstructor(constructor);if(foundIndex!==undefined)
+return this.registeredTypeInfos_[foundIndex];return undefined;};registry.findTypeInfoMatching=function(predicate,opt_this){opt_this=opt_this?opt_this:undefined;for(var i=0;i<registry.registeredTypeInfos_.length;++i){var typeInfo=registry.registeredTypeInfos_[i];if(predicate.call(opt_this,typeInfo))
+return typeInfo;}
+return extensionRegistryOptions.defaultTypeInfo;};}
+return{_decorateBasicExtensionRegistry:decorateBasicExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){var categoryPartsFor={};function getCategoryParts(category){var parts=categoryPartsFor[category];if(parts!==undefined)
+return parts;parts=category.split(',');categoryPartsFor[category]=parts;return parts;}
+return{getCategoryParts:getCategoryParts};});'use strict';tr.exportTo('tr.b',function(){var getCategoryParts=tr.b.getCategoryParts;var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateTypeBasedExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.categoryPartToTypeInfoMap_={};registry.typeNameToTypeInfoMap_={};registry.register=function(constructor,metadata){extensionRegistryOptions.validateConstructor(constructor);var typeInfo=new RegisteredTypeInfo(constructor,metadata||extensionRegistryOptions.defaultMetadata);typeInfo.typeNames=[];typeInfo.categoryParts=[];if(metadata&&metadata.typeName)
+typeInfo.typeNames.push(metadata.typeName);if(metadata&&metadata.typeNames){typeInfo.typeNames.push.apply(typeInfo.typeNames,metadata.typeNames);}
+if(metadata&&metadata.categoryParts){typeInfo.categoryParts.push.apply(typeInfo.categoryParts,metadata.categoryParts);}
+if(typeInfo.typeNames.length===0&&typeInfo.categoryParts.length===0)
+throw new Error('typeName or typeNames must be provided');typeInfo.typeNames.forEach(function(typeName){if(registry.typeNameToTypeInfoMap_[typeName])
+throw new Error('typeName '+typeName+' already registered');});typeInfo.categoryParts.forEach(function(categoryPart){if(registry.categoryPartToTypeInfoMap_[categoryPart]){throw new Error('categoryPart '+categoryPart+' already registered');}});var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_[typeName]=typeInfo;});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_[categoryPart]=typeInfo;});registry.registeredTypeInfos_.push(typeInfo);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push({registeredTypeInfos:registry.registeredTypeInfos_,typeNameToTypeInfoMap:registry.typeNameToTypeInfoMap_,categoryPartToTypeInfoMap:registry.categoryPartToTypeInfoMap_});registry.registeredTypeInfos_=[];registry.typeNameToTypeInfoMap_={};registry.categoryPartToTypeInfoMap_={};var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){var state=savedStateStack[0];savedStateStack.splice(0,1);registry.registeredTypeInfos_=state.registeredTypeInfos;registry.typeNameToTypeInfoMap_=state.typeNameToTypeInfoMap;registry.categoryPartToTypeInfoMap_=state.categoryPartToTypeInfoMap;var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.unregister=function(constructor){var typeInfoIndex=-1;for(var i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor==constructor){typeInfoIndex=i;break;}}
+if(typeInfoIndex===-1)
+throw new Error(constructor+' not registered');var typeInfo=registry.registeredTypeInfos_[typeInfoIndex];registry.registeredTypeInfos_.splice(typeInfoIndex,1);typeInfo.typeNames.forEach(function(typeName){delete registry.typeNameToTypeInfoMap_[typeName];});typeInfo.categoryParts.forEach(function(categoryPart){delete registry.categoryPartToTypeInfoMap_[categoryPart];});var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getTypeInfo=function(category,typeName){if(category){var categoryParts=getCategoryParts(category);for(var i=0;i<categoryParts.length;i++){var categoryPart=categoryParts[i];if(registry.categoryPartToTypeInfoMap_[categoryPart])
+return registry.categoryPartToTypeInfoMap_[categoryPart];}}
+if(registry.typeNameToTypeInfoMap_[typeName])
+return registry.typeNameToTypeInfoMap_[typeName];return extensionRegistryOptions.defaultTypeInfo;};registry.getConstructor=function(category,typeName){var typeInfo=registry.getTypeInfo(category,typeName);if(typeInfo)
+return typeInfo.constructor;return undefined;};}
+return{_decorateTypeBasedExtensionRegistry:decorateTypeBasedExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){function decorateExtensionRegistry(registry,registryOptions){if(registry.register)
+throw new Error('Already has registry');registryOptions.freeze();if(registryOptions.mode==tr.b.BASIC_REGISTRY_MODE){tr.b._decorateBasicExtensionRegistry(registry,registryOptions);}else if(registryOptions.mode==tr.b.TYPE_BASED_REGISTRY_MODE){tr.b._decorateTypeBasedExtensionRegistry(registry,registryOptions);}else{throw new Error('Unrecognized mode');}
+if(registry.addEventListener===undefined)
+tr.b.EventTarget.decorate(registry);}
+return{decorateExtensionRegistry:decorateExtensionRegistry};});'use strict';tr.exportTo('tr.importer',function(){function Importer(){}
+Importer.prototype={__proto__:Object.prototype,isTraceDataContainer:function(){return false;},extractSubtraces:function(){return[];},importEvents:function(){},importSampleData:function(){},finalizeImport:function(){},joinRefs:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){var typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo)
+return typeInfo.constructor;return undefined;};return{Importer:Importer};});'use strict';tr.exportTo('tr.e.importer.gcloud_trace',function(){function GcloudTraceImporter(model,eventData){this.importPriority=2;this.eventData_=eventData;}
+GcloudTraceImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
+return false;var normalizedEventData=eventData.slice(0,20).replace(/\s/g,'');if(normalizedEventData.length<14)
+return false;return normalizedEventData.slice(0,14)=='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,extractSubtraces:function(){var traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace:function(){var events=[];var trace=JSON.parse(this.eventData_);var spanLength=trace.spans.length;for(var i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
+return{'traceEvents':events};},createEventForSpan:function(traceId,span){var newArgs={};if(span.labels){newArgs=JSON.parse(JSON.stringify(span.labels));}
+newArgs['Span ID']=span.spanId;newArgs['Start Time']=span.startTime;newArgs['End Time']=span.endTime;if(span.parentSpanId){newArgs['Parent Span ID']=span.parentSpanId;}
+return{name:span.name,args:newArgs,pid:traceId,ts:Date.parse(span.startTime)*1000,dur:(Date.parse(span.endTime)-Date.parse(span.startTime))*1000,cat:'tracespan',tid:traceId,ph:'X'};}};tr.importer.Importer.register(GcloudTraceImporter);return{GcloudTraceImporter:GcloudTraceImporter};});'use strict';tr.exportTo('tr.b',function(){function max(a,b){if(a===undefined)
+return b;if(b===undefined)
+return a;return Math.max(a,b);}
+function IntervalTree(beginPositionCb,endPositionCb){this.beginPositionCb_=beginPositionCb;this.endPositionCb_=endPositionCb;this.root_=undefined;this.size_=0;}
+IntervalTree.prototype={insert:function(datum){var startPosition=this.beginPositionCb_(datum);var endPosition=this.endPositionCb_(datum);var node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_:function(root,node){if(root===undefined)
+return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed)
+this.flipNodeColour_(root);if(node.key<root.key)
+root.leftNode=this.insertNode_(root.leftNode,node);else if(node.key===root.key)
+root.merge(node);else
+root.rightNode=this.insertNode_(root.rightNode,node);if(root.rightNode&&root.rightNode.isRed&&(root.leftNode===undefined||!root.leftNode.isRed))
+root=this.rotateLeft_(root);if(root.leftNode&&root.leftNode.isRed&&root.leftNode.leftNode&&root.leftNode.leftNode.isRed)
+root=this.rotateRight_(root);return root;},rotateRight_:function(node){var sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_:function(node){var sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_:function(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_:function(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues:function(){this.updateHighValues_(this.root_);},updateHighValues_:function(node){if(node===undefined)
+return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_:function(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined)
+throw new Error('queryLow and queryHigh must be defined');if((typeof queryLow!=='number')||(typeof queryHigh!=='number'))
+throw new Error('queryLow and queryHigh must be numbers');},findIntersection:function(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)
+return[];var ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_:function(){if(this.root_===undefined)
+return[];return this.root_.dump();}};var Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum:datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
+IntervalTreeNode.prototype={appendIntersectionsInto_:function(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)
+return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.maxHighLeft_>queryLow){this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+if(this.highValue>queryLow){for(var i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)
+break;ret.push(this.data[i].datum);}}
+if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge:function(node){for(var i=0;i<node.data.length;i++)
+this.data_.push(node.data[i]);this.data_.sort(function(a,b){return a.high-b.high;});},dump:function(){var ret={};if(this.leftNode_)
+ret['left']=this.leftNode_.dump();ret['data']=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_)
+ret['right']=this.rightNode_.dump();return ret;}};return{IntervalTree:IntervalTree};});'use strict';tr.exportTo('tr.b',function(){function Range(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};Range.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange:function(range){if(range.isEmpty)
+return;this.addValue(range.min);this.addValue(range.max);},addValue:function(value){if(this.isEmpty_){this.max_=value;this.min_=value;this.isEmpty_=false;return;}
+this.max_=Math.max(this.max_,value);this.min_=Math.min(this.min_,value);},set min(min){this.isEmpty_=false;this.min_=min;},get min(){if(this.isEmpty_)
+return undefined;return this.min_;},get max(){if(this.isEmpty_)
+return undefined;return this.max_;},set max(max){this.isEmpty_=false;this.max_=max;},get range(){if(this.isEmpty_)
+return undefined;return this.max_-this.min_;},get center(){return(this.min_+this.max_)*0.5;},get duration(){if(this.isEmpty_)
+return 0;return this.max_-this.min_;},equals:function(that){if(this.isEmpty&&that.isEmpty)
+return true;if(this.isEmpty!=that.isEmpty)
+return false;return this.min===that.min&&this.max===that.max;},containsRange:function(range){if(this.isEmpty||range.isEmpty)
+return false;return this.findIntersection(range).duration==range.duration;},containsExplicitRange:function(min,max){return this.containsRange(Range.fromExplicitRange(min,max));},intersectsRange:function(range){if(this.isEmpty||range.isEmpty)
+return false;return!this.findIntersection(range).isEmpty;},intersectsExplicitRange:function(min,max){return this.intersectsRange(Range.fromExplicitRange(min,max));},findIntersection:function(range){if(this.isEmpty||range.isEmpty)
+return new Range();var min=Math.max(this.min,range.min);var max=Math.min(this.max,range.max);if(max<min)
+return new Range();return Range.fromExplicitRange(min,max);},toJSON:function(){if(this.isEmpty_)
+return{isEmpty:true};return{isEmpty:false,max:this.max,min:this.min};},filterArray:function(array,opt_keyFunc,opt_this){if(this.isEmpty_)
+return[];function binSearch(test){var i0=0;var i1=array.length;while(i0<i1-1){var i=Math.trunc((i0+i1)/2);if(test(i))
+i1=i;else
+i0=i;}
+return i1;}
+var keyFunc=opt_keyFunc||tr.b.identity;function getValue(index){return keyFunc.call(opt_this,array[index]);}
+var first=binSearch(function(i){return this.min_===undefined||this.min_<=getValue(i);}.bind(this));var last=binSearch(function(i){return this.max_!==undefined&&this.max_<getValue(i);}.bind(this));return array.slice(first,last);}};Range.fromDict=function(d){if(d.isEmpty===true){return new Range();}else if(d.isEmpty===false){var range=new Range();range.min=d.min;range.max=d.max;return range;}else{throw new Error('Not a range');}};Range.fromExplicitRange=function(min,max){var range=new Range();range.min=min;range.max=max;return range;};Range.compareByMinTimes=function(a,b){if(!a.isEmpty&&!b.isEmpty)
+return a.min_-b.min_;if(a.isEmpty&&!b.isEmpty)
+return-1;if(!a.isEmpty&&b.isEmpty)
+return 1;return 0;};return{Range:Range};});'use strict';tr.exportTo('tr.b',function(){function addSingletonGetter(ctor){ctor.getInstance=function(){return ctor.instance_||(ctor.instance_=new ctor());};}
+function deepCopy(value){if(!(value instanceof Object)){if(value===undefined||value===null)
+return value;if(typeof value=='string')
+return value.substring();if(typeof value=='boolean')
+return value;if(typeof value=='number')
+return value;throw new Error('Unrecognized: '+typeof value);}
+var object=value;if(object instanceof Array){var res=new Array(object.length);for(var i=0;i<object.length;i++)
+res[i]=deepCopy(object[i]);return res;}
+if(object.__proto__!=Object.prototype)
+throw new Error('Can only clone simple types');var res={};for(var key in object){res[key]=deepCopy(object[key]);}
+return res;}
+function normalizeException(e){if(e===undefined||e===null){return{typeName:'UndefinedError',message:'Unknown: null or undefined exception',stack:'Unknown'};}
+if(typeof(e)=='string'){return{typeName:'StringError',message:e,stack:[e]};}
+var typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
+var msg=e.message?e.message:'Unknown';return{typeName:typeName,message:msg,stack:e.stack?e.stack:[msg]};}
+function stackTraceAsString(){return new Error().stack+'';}
+function stackTrace(){var stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
+function getUsingPath(path,from_dict){var parts=path.split('.');var cur=from_dict;for(var part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
+return undefined;}
+return{addSingletonGetter:addSingletonGetter,deepCopy:deepCopy,normalizeException:normalizeException,stackTrace:stackTrace,stackTraceAsString:stackTraceAsString,getUsingPath:getUsingPath};});'use strict';tr.exportTo('tr.b',function(){var recordRAFStacks=false;var pendingPreAFs=[];var pendingRAFs=[];var pendingIdleCallbacks=[];var currentRAFDispatchList=undefined;var rafScheduled=false;function scheduleRAF(){if(rafScheduled)
+return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(0);},function(e){console.log(e.stack);throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests);}else{var delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(domTimeStamp-delta);});}}}
+function onAnimationFrameError(e,opt_stack){console.log(e.stack);if(tr.isHeadless)
+throw e;if(opt_stack)
+console.log(opt_stack);if(e.message)
+console.error(e.message,e.stack);else
+console.error(e);}
+function runTask(task,frameBeginTime){try{task.callback.call(task.context,frameBeginTime);}catch(e){tr.b.onAnimationFrameError(e,task.stack);}}
+function processRequests(frameBeginTime){var rafCompletionDeadline=frameBeginTime+10;rafScheduled=false;var currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];var hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(var i=0;i<currentPreAFs.length;i++)
+runTask(currentPreAFs[i],frameBeginTime);while(currentRAFDispatchList.length>0)
+runTask(currentRAFDispatchList.shift(),frameBeginTime);currentRAFDispatchList=undefined;if(!hasRAFTasks){while(pendingIdleCallbacks.length>0){runTask(pendingIdleCallbacks.shift());if(tr.isHeadless||window.performance.now()>=rafCompletionDeadline)
+break;}}
+if(pendingIdleCallbacks.length>0)
+scheduleRAF();}
+function getStack_(){if(!recordRAFStacks)
+return'';var stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
+function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback:callback,context:opt_this||window,stack:getStack_()});scheduleRAF();}
+function requestAnimationFrameInThisFrameIfPossible(callback,opt_this){if(!currentRAFDispatchList){requestAnimationFrame(callback,opt_this);return;}
+currentRAFDispatchList.push({callback:callback,context:opt_this||window,stack:getStack_()});return;}
+function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback:callback,context:opt_this||window,stack:getStack_()});scheduleRAF();}
+function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback:callback,context:opt_this||window,stack:getStack_()});scheduleRAF();}
+function forcePendingRAFTasksToRun(frameBeginTime){if(!rafScheduled)
+return;processRequests(frameBeginTime);}
+return{onAnimationFrameError:onAnimationFrameError,requestPreAnimationFrame:requestPreAnimationFrame,requestAnimationFrame:requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible:requestAnimationFrameInThisFrameIfPossible,requestIdleCallback:requestIdleCallback,forcePendingRAFTasksToRun:forcePendingRAFTasksToRun};});'use strict';tr.exportTo('tr.b',function(){function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined)
+throw new Error('Almost certainly, you meant to pass a thisArg.');this.runCb_=runCb;this.thisArg_=thisArg;this.afterTask_=undefined;this.subTasks_=[];}
+Task.prototype={subTask:function(cb,thisArg){if(cb instanceof Task)
+this.subTasks_.push(cb);else
+this.subTasks_.push(new Task(cb,thisArg));return this.subTasks_[this.subTasks_.length-1];},run:function(){if(this.runCb_!==undefined)
+this.runCb_.call(this.thisArg_,this);var subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)
+return this.afterTask_;for(var i=1;i<subTasks.length;i++)
+subTasks[i-1].afterTask_=subTasks[i];subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after:function(cb,thisArg){if(this.afterTask_)
+throw new Error('Has an after task already');if(cb instanceof Task)
+this.afterTask_=cb;else
+this.afterTask_=new Task(cb,thisArg);return this.afterTask_;},enqueue:function(cb,thisArg){var lastTask=this;while(lastTask.afterTask_)
+lastTask=lastTask.afterTask_;return lastTask.after(cb,thisArg);}};Task.RunSynchronously=function(task){var curTask=task;while(curTask)
+curTask=curTask.run();}
+Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){var curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);console.error(e.stack);return;}
+if(curTask){tr.b.requestIdleCallback(runAnother);return;}
+resolve();}
+tr.b.requestIdleCallback(runAnother);});}
+return{Task:Task};});'use strict';tr.exportTo('tr.b',function(){function _iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement){if(cb.call(thisArg,element))
+return true;}
+if(element.shadowRoot){if(_iterateElementDeeplyImpl(element.shadowRoot,cb,thisArg,false))
+return true;}
+for(var i=0;i<element.children.length;i++){if(_iterateElementDeeplyImpl(element.children[i],cb,thisArg,true))
+return true;}}
+function iterateElementDeeply(element,cb,thisArg){_iterateElementDeeplyImpl(element,cb,thisArg,false);}
+function findDeepElementMatchingPredicate(element,predicate){var foundElement=undefined;function matches(element){var match=predicate(element);if(!match)
+return false;foundElement=element;return true;}
+iterateElementDeeply(element,matches);return foundElement;}
+function findDeepElementsMatchingPredicate(element,predicate){var foundElements=[];function matches(element){var match=predicate(element);if(match){foundElements.push(element);}
+return false;}
+iterateElementDeeply(element,matches);return foundElements;}
+function findDeepElementMatching(element,selector){return findDeepElementMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementsMatching(element,selector){return findDeepElementsMatchingPredicate(element,function(element){return element.matches(selector);});}
+function findDeepElementWithTextContent(element,re){return findDeepElementMatchingPredicate(element,function(element){if(element.children.length!==0)
+return false;return re.test(element.textContent);});}
+return{iterateElementDeeply:iterateElementDeeply,findDeepElementMatching:findDeepElementMatching,findDeepElementsMatching:findDeepElementsMatching,findDeepElementMatchingPredicate:findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate:findDeepElementsMatchingPredicate,findDeepElementWithTextContent:findDeepElementWithTextContent};});'use strict';tr.exportTo('tr.b.u',function(){var msDisplayMode={scale:1e-3,suffix:'ms',roundedLess:function(a,b){return Math.round(a*1000)<Math.round(b*1000);},format:function(ts){return new Number(ts).toLocaleString(undefined,{minimumFractionDigits:3})+' ms';}};var nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess:function(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},format:function(ts){return new Number(ts*1000000).toLocaleString(undefined,{maximumFractionDigits:0})+' ns';}};var TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes:TimeDisplayModes};});'use strict';tr.exportTo('tr.b.u',function(){var TimeDisplayModes=tr.b.u.TimeDisplayModes;function max(a,b){if(a===undefined)
+return b;if(b===undefined)
+return a;return a.scale>b.scale?a:b;}
+var Units={reset:function(){this.currentTimeDisplayMode=TimeDisplayModes.ms;},timestampFromUs:function(us){return us/1000;},maybeTimestampFromUs:function(us){return us===undefined?undefined:us/1000;},get currentTimeDisplayMode(){return this.currentTimeDisplayMode_;},set currentTimeDisplayMode(value){if(this.currentTimeDisplayMode_==value)
+return;this.currentTimeDisplayMode_=value;this.dispatchEvent(new tr.b.Event('display-mode-changed'));},didPreferredTimeDisplayUnitChange:function(){var largest=undefined;var els=tr.b.findDeepElementsMatching(document.body,'tr-ui-u-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});this.currentDisplayUnit=largest===undefined?TimeDisplayModes.ms:largest;},unitsByJSONName:{},fromJSON:function(object){var u=this.unitsByJSONName[object];if(u){return u;}
+throw new Error('Unrecognized unit');}};tr.b.EventTarget.decorate(Units);Units.reset();Units.timeDurationInMs={asJSON:function(){return'ms';},format:function(value){return Units.currentTimeDisplayMode_.format(value);}};Units.unitsByJSONName['ms']=Units.timeDurationInMs;Units.timeStampInMs={asJSON:function(){return'tsMs';},format:function(value){return Units.currentTimeDisplayMode_.format(value);}};Units.unitsByJSONName['tsMs']=Units.timeStampInMs;Units.normalizedPercentage={asJSON:function(){return'n%';},format:function(value){var tmp=new Number(Math.round(value*100000)/1000);return tmp.toLocaleString(undefined,{minimumFractionDigits:3})+'%';}};Units.unitsByJSONName['n%']=Units.normalizedPercentage;var SIZE_UNIT_PREFIXES=['','Ki','Mi','Gi','Ti'];Units.sizeInBytes={asJSON:function(){return'sizeInBytes';},format:function(value){var signPrefix='';if(value<0){signPrefix='-';value=-value;}
+var i=0;while(value>=1024&&i<SIZE_UNIT_PREFIXES.length-1){value/=1024;i++;}
+return signPrefix+value.toFixed(1)+' '+SIZE_UNIT_PREFIXES[i]+'B';}};Units.unitsByJSONName['sizeInBytes']=Units.sizeInBytes;Units.energyInJoules={asJSON:function(){return'J';},format:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3})+' J';}};Units.unitsByJSONName['J']=Units.energyInJoules;Units.powerInWatts={asJSON:function(){return'W';},format:function(value){return(value*1000.0).toLocaleString(undefined,{minimumFractionDigits:3})+' mW';}};Units.unitsByJSONName['W']=Units.powerInWatts;Units.unitlessNumber={asJSON:function(){return'unitless';},format:function(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}};Units.unitsByJSONName['unitless']=Units.unitlessNumber;return{Units:Units};});'use strict';tr.exportTo('tr.c',function(){function Auditor(model){this.model_=model;}
+Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate:function(){},runAudit:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor:Auditor};});'use strict';tr.exportTo('tr.c',function(){function makeCaseInsensitiveRegex(pattern){pattern=pattern.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return new RegExp(pattern,'i');}
+function Filter(){}
+Filter.prototype={__proto__:Object.prototype,matchCounter:function(counter){return true;},matchCpu:function(cpu){return true;},matchProcess:function(process){return true;},matchSlice:function(slice){return true;},matchThread:function(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length)
+throw new Error('Filter text is empty.');}
+TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){if(slice.title===undefined&&slice.category===undefined)
+return false;return this.regex_.test(slice.title)||(!!slice.category&&this.regex_.test(slice.category));}};function ExactTitleFilter(text){Filter.call(this);this.text_=text;if(!text.length)
+throw new Error('Filter text is empty.');}
+ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
+FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_:function(obj){for(var key in obj){if(!obj.hasOwnProperty(key))
+continue;if(this.regex_.test(key))
+return true;if(this.regex_.test(obj[key]))
+return true;}
+return false;},matchSlice:function(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))
+return true;return this.matchObject_(slice.args);}};return{Filter:Filter,TitleOrCategoryFilter:TitleOrCategoryFilter,ExactTitleFilter:ExactTitleFilter,FullTextFilter:FullTextFilter};});'use strict';tr.exportTo('tr.b.u',function(){function Scalar(value,unit){this.value=value;this.unit=unit;};Scalar.prototype={toString:function(){return this.unit.format(this.value);}};return{Scalar:Scalar};});'use strict';tr.exportTo('tr.b.u',function(){function TimeStamp(timestamp){tr.b.u.Scalar.call(this,timestamp,tr.b.u.Units.timeStampInMs);};TimeStamp.prototype={__proto__:tr.b.u.Scalar.prototype,get timestamp(){return this.value;}};TimeStamp.format=function(timestamp){return tr.b.u.Units.timeStampInMs.format(timestamp);};return{TimeStamp:TimeStamp};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
+function Color(opt_r,opt_g,opt_b,opt_a){this.r=Math.floor(opt_r)||0;this.g=Math.floor(opt_g)||0;this.b=Math.floor(opt_b)||0;this.a=opt_a;}
+Color.fromString=function(str){var tmp;var values;if(str.substr(0,4)=='rgb('){tmp=str.substr(4,str.length-5);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=3)
+throw new Error('Malformatted rgb-expression');return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]));}else if(str.substr(0,5)=='rgba('){tmp=str.substr(5,str.length-6);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!=4)
+throw new Error('Malformatted rgb-expression');return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]),parseFloat(values[3]));}else if(str[0]=='#'&&str.length==7){return new Color(parseInt(str.substr(1,2),16),parseInt(str.substr(3,2),16),parseInt(str.substr(5,2),16));}else{throw new Error('Unrecognized string format.');}};Color.lerp=function(a,b,percent){if(a.a!==undefined&&b.a!==undefined)
+return Color.lerpRGBA(a,b,percent);return Color.lerpRGB(a,b,percent);};Color.lerpRGB=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b);};Color.lerpRGBA=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b,((b.a-a.a)*percent)+a.a);};Color.fromDict=function(dict){return new Color(dict.r,dict.g,dict.b,dict.a);};Color.fromHSLExplicit=function(h,s,l,a){var r,g,b;function hue2rgb(p,q,t){if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p;}
+if(s===0){r=g=b=l;}else{var q=l<0.5?l*(1+s):l+s-l*s;var p=2*l-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);}
+return new Color(Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a);}
+Color.fromHSL=function(hsl){return Color.fromHSLExplicit(hsl.h,hsl.s,hsl.l,hsl.a);}
+Color.prototype={clone:function(){var c=new Color();c.r=this.r;c.g=this.g;c.b=this.b;c.a=this.a;return c;},blendOver:function(bgColor){var oneMinusThisAlpha=1-this.a;var outA=this.a+bgColor.a*oneMinusThisAlpha;var bgBlend=(bgColor.a*oneMinusThisAlpha)/bgColor.a;return new Color(this.r*this.a+bgColor.r*bgBlend,this.g*this.a+bgColor.g*bgBlend,this.b*this.a+bgColor.b*bgBlend,outA);},brighten:function(opt_k){var k;k=opt_k||0.45;return new Color(Math.min(255,this.r+Math.floor(this.r*k)),Math.min(255,this.g+Math.floor(this.g*k)),Math.min(255,this.b+Math.floor(this.b*k)),this.a);},lighten:function(k,opt_max_l){var max_l=opt_max_l!==undefined?opt_max_l:1.0;var hsl=this.toHSL();hsl.l=clamp01(hsl.l+k);return Color.fromHSL(hsl);},darken:function(opt_k){var k;if(opt_k!==undefined)
+k=opt_k;else
+k=0.45;return new Color(Math.min(255,this.r-Math.floor(this.r*k)),Math.min(255,this.g-Math.floor(this.g*k)),Math.min(255,this.b-Math.floor(this.b*k)),this.a);},desaturate:function(opt_desaturateFactor){var desaturateFactor;if(opt_desaturateFactor!==undefined)
+desaturateFactor=opt_desaturateFactor;else
+desaturateFactor=1;var hsl=this.toHSL();hsl.s=clamp01(hsl.s*(1-desaturateFactor));return Color.fromHSL(hsl);},withAlpha:function(a){return new Color(this.r,this.g,this.b,a);},toString:function(){if(this.a!==undefined){return'rgba('+
+this.r+','+this.g+','+
+this.b+','+this.a+')';}
+return'rgb('+this.r+','+this.g+','+this.b+')';},toHSL:function(){var r=this.r/255;var g=this.g/255;var b=this.b/255;var max=Math.max(r,g,b);var min=Math.min(r,g,b);var h,s;var l=(max+min)/2;if(min===max){h=0;s=0;}else{var delta=max-min;if(l>0.5)
+s=delta/(2-max-min);else
+s=delta/(max+min);if(r===max){h=(g-b)/delta;if(g<b)
+h+=6;}else if(g===max){h=2+((b-r)/delta);}else{h=4+((r-g)/delta);}
+h/=6;}
+return{h:h,s:s,l:l,a:this.a};},toStringWithAlphaOverride:function(alpha){return'rgba('+
+this.r+','+this.g+','+
+this.b+','+alpha+')';}};return{Color:Color};});'use strict';tr.exportTo('tr.b',function(){var generalPurposeColors=[new tr.b.Color(122,98,135),new tr.b.Color(150,83,105),new tr.b.Color(44,56,189),new tr.b.Color(99,86,147),new tr.b.Color(104,129,107),new tr.b.Color(130,178,55),new tr.b.Color(87,109,147),new tr.b.Color(111,145,88),new tr.b.Color(81,152,131),new tr.b.Color(142,91,111),new tr.b.Color(81,163,70),new tr.b.Color(148,94,86),new tr.b.Color(144,89,118),new tr.b.Color(83,150,97),new tr.b.Color(105,94,139),new tr.b.Color(89,144,122),new tr.b.Color(105,119,128),new tr.b.Color(96,128,137),new tr.b.Color(145,88,145),new tr.b.Color(88,145,144),new tr.b.Color(90,100,143),new tr.b.Color(121,97,136),new tr.b.Color(111,160,73),new tr.b.Color(112,91,142),new tr.b.Color(86,147,86),new tr.b.Color(63,100,170),new tr.b.Color(81,152,107),new tr.b.Color(60,164,173),new tr.b.Color(143,72,161),new tr.b.Color(159,74,86)];var reservedColorsByName={thread_state_iowait:new tr.b.Color(182,125,143),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),rail_response:new tr.b.Color(67,135,253),rail_animate:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),used_memory_column:new tr.b.Color(0,0,255),older_used_memory_column:new tr.b.Color(153,204,255),tracing_memory_column:new tr.b.Color(153,153,153),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};var numGeneralPurposeColorIds=generalPurposeColors.length;var numReservedColorIds=tr.b.dictionaryLength(reservedColorsByName);var numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
+var paletteBase=[];paletteBase.push.apply(paletteBase,generalPurposeColors);paletteBase.push.apply(paletteBase,tr.b.dictionaryValues(reservedColorsByName));ColorScheme.colors=[];ColorScheme.properties={};ColorScheme.properties={numColorsPerVariant:numColorsPerVariant};function pushVariant(func){var variantColors=paletteBase.map(func);ColorScheme.colors.push.apply(ColorScheme.colors,variantColors);}
+pushVariant(function(c){return c;});ColorScheme.properties.brightenedOffsets=[];ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.3,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.48,0.9);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.65,0.9);});ColorScheme.properties.dimmedOffsets=[];ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate();});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.5);});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.3);});ColorScheme.colorsAsStrings=ColorScheme.colors.map(function(c){return c.toString();});var reservedColorNameToIdMap=(function(){var m={};var i=generalPurposeColors.length;tr.b.iterItems(reservedColorsByName,function(key,value){m[key]=i++;});return m;})();ColorScheme.getColorIdForReservedName=function(name){var id=reservedColorNameToIdMap[name];if(id===undefined)
+throw new Error('Unrecognized color ')+name;return id;};ColorScheme.getColorForReservedNameAsString=function(reservedName){var id=ColorScheme.getColorIdForReservedName(reservedName);return ColorScheme.colorsAsStrings[id];};ColorScheme.getStringHash=function(name){var hash=0;for(var i=0;i<name.length;++i)
+hash=(hash+37*hash+11*name.charCodeAt(i))%0xFFFFFFFF;return hash;};var stringColorIdCache={};ColorScheme.getColorIdForGeneralPurposeString=function(string){if(stringColorIdCache[string]===undefined){var hash=ColorScheme.getStringHash(string);stringColorIdCache[string]=hash%numGeneralPurposeColorIds;}
+return stringColorIdCache[string];};return{ColorScheme:ColorScheme};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function EventInfo(title,description,docLinks){this.title=title;this.description=description;this.docLinks=docLinks;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(title);}
+return{EventInfo:EventInfo};});'use strict';tr.exportTo('tr.b',function(){var nextGUID=1;var GUID={allocate:function(){return nextGUID++;},getLastGuid:function(){return nextGUID-1;}};return{GUID:GUID};});'use strict';tr.exportTo('tr.model',function(){function EventRegistry(){}
+var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(EventRegistry,options);EventRegistry.addEventListener('will-register',function(e){var metadata=e.typeInfo.metadata;if(metadata.name===undefined)
+throw new Error('Registered events must provide name metadata');var i=tr.b.findFirstInArray(EventRegistry.getAllRegisteredTypeInfos(),function(x){return x.metadata.name===metadata.name;});if(i!==undefined)
+throw new Error('Event type with that name already registered');if(metadata.pluralName===undefined)
+throw new Error('Registered events must provide pluralName metadata');if(metadata.singleViewElementName===undefined){throw new Error('Registered events must provide '+'singleViewElementName metadata');}
+if(metadata.multiViewElementName===undefined){throw new Error('Registered events must provide '+'multiViewElementName metadata');}});var eventsByTypeName=undefined;EventRegistry.getEventTypeInfoByTypeName=function(typeName){if(eventsByTypeName===undefined){eventsByTypeName={};EventRegistry.getAllRegisteredTypeInfos().forEach(function(typeInfo){eventsByTypeName[typeInfo.metadata.name]=typeInfo;});}
+return eventsByTypeName[typeName];}
+EventRegistry.addEventListener('registry-changed',function(){eventsByTypeName=undefined;});function convertCamelCaseToTitleCase(name){var result=name.replace(/[A-Z]/g,' $&');result=result.charAt(0).toUpperCase()+result.slice(1);return result;}
+EventRegistry.getUserFriendlySingularName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.name;return convertCamelCaseToTitleCase(str);};EventRegistry.getUserFriendlyPluralName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.pluralName;return convertCamelCaseToTitleCase(str);};return{EventRegistry:EventRegistry};});'use strict';tr.exportTo('tr.model',function(){var EventRegistry=tr.model.EventRegistry;var RequestSelectionChangeEvent=tr.b.Event.bind(undefined,'requestSelectionChange',true,false);function EventSet(opt_events){this.bounds_dirty_=true;this.bounds_=new tr.b.Range();this.length_=0;this.guid_=tr.b.GUID.allocate();this.pushed_guids_={};if(opt_events){if(opt_events instanceof Array){for(var i=0;i<opt_events.length;i++)
+this.push(opt_events[i]);}else if(opt_events instanceof EventSet){this.addEventSet(opt_events);}else{this.push(opt_events);}}}
+EventSet.prototype={__proto__:Object.prototype,get bounds(){if(this.bounds_dirty_){this.bounds_.reset();for(var i=0;i<this.length_;i++)
+this[i].addBoundsToRange(this.bounds_);this.bounds_dirty_=false;}
+return this.bounds_;},get duration(){if(this.bounds_.isEmpty)
+return 0;return this.bounds_.max-this.bounds_.min;},get length(){return this.length_;},get guid(){return this.guid_;},clear:function(){for(var i=0;i<this.length_;++i)
+delete this[i];this.length_=0;this.bounds_dirty_=true;},push:function(event){if(event.guid==undefined)
+throw new Error('Event must have a GUID');if(this.contains(event))
+return event;this.pushed_guids_[event.guid]=true;this[this.length_++]=event;this.bounds_dirty_=true;return event;},contains:function(event){return this.pushed_guids_[event.guid];},addEventSet:function(eventSet){for(var i=0;i<eventSet.length;i++)
+this.push(eventSet[i]);},subEventSet:function(index,count){count=count||1;var eventSet=new EventSet();eventSet.bounds_dirty_=true;if(index<0||index+count>this.length_)
+throw new Error('Index out of bounds');for(var i=index;i<index+count;i++)
+eventSet.push(this[i]);return eventSet;},intersectionIsEmpty:function(otherEventSet){return!this.some(function(event){return otherEventSet.contains(event);});},equals:function(that){if(this.length!==that.length)
+return false;for(var i=0;i<this.length;i++){var event=this[i];if(that.pushed_guids_[event.guid]===undefined)
+return false;}
+return true;},getEventsOrganizedByBaseType:function(opt_pruneEmpty){var allTypeInfos=EventRegistry.getAllRegisteredTypeInfos();var events=this.getEventsOrganizedByCallback(function(event){var maxEventIndex=-1;var maxEventTypeInfo=undefined;allTypeInfos.forEach(function(eventTypeInfo,eventIndex){if(!(event instanceof eventTypeInfo.constructor))
+return;if(eventIndex>maxEventIndex){maxEventIndex=eventIndex;maxEventTypeInfo=eventTypeInfo;}});if(maxEventIndex==-1){console.log(event);throw new Error('Unrecognized event type');}
+return maxEventTypeInfo.metadata.name;});if(!opt_pruneEmpty){allTypeInfos.forEach(function(eventTypeInfo){if(events[eventTypeInfo.metadata.name]===undefined)
+events[eventTypeInfo.metadata.name]=new EventSet();});}
+return events;},getEventsOrganizedByTitle:function(){return this.getEventsOrganizedByCallback(function(event){if(event.title===undefined)
+throw new Error('An event didn\'t have a title!');return event.title;});},getEventsOrganizedByCallback:function(cb){var eventsByCallback={};for(var i=0;i<this.length;i++){var event=this[i];var key=cb(event);if(key===undefined)
+throw new Error('An event could not be organized');if(eventsByCallback[key]===undefined)
+eventsByCallback[key]=new EventSet();eventsByCallback[key].push(event);}
+return eventsByCallback;},enumEventsOfType:function(type,func){for(var i=0;i<this.length_;i++)
+if(this[i]instanceof type)
+func(this[i]);},get userFriendlyName(){if(this.length===0){throw new Error('Empty event set');}
+var eventsByBaseType=this.getEventsOrganizedByBaseType(true);var eventTypeName=tr.b.dictionaryKeys(eventsByBaseType)[0];if(this.length===1){var tmp=EventRegistry.getUserFriendlySingularName(eventTypeName);return this[0].userFriendlyName;}
+var numEventTypes=tr.b.dictionaryLength(eventsByBaseType);if(numEventTypes!==1){return this.length+' events of various types';}
+var tmp=EventRegistry.getUserFriendlyPluralName(eventTypeName);return this.length+' '+tmp;},filter:function(fn,opt_this){var res=new EventSet();this.forEach(function(slice){if(fn.call(this,slice))
+res.push(slice);},opt_this);return res;},toArray:function(){var ary=[];for(var i=0;i<this.length;i++)
+ary.push(this[i]);return ary;},forEach:function(fn,opt_this){for(var i=0;i<this.length;i++)
+fn.call(opt_this,this[i],i);},map:function(fn,opt_this){var res=[];for(var i=0;i<this.length;i++)
+res.push(fn.call(opt_this,this[i],i));return res;},every:function(fn,opt_this){for(var i=0;i<this.length;i++)
+if(!fn.call(opt_this,this[i],i))
+return false;return true;},some:function(fn,opt_this){for(var i=0;i<this.length;i++)
+if(fn.call(opt_this,this[i],i))
+return true;return false;},asDict:function(){var stable_ids=[];this.forEach(function(event){stable_ids.push(event.stableId);});return{'events':stable_ids};}};return{EventSet:EventSet,RequestSelectionChangeEvent:RequestSelectionChangeEvent};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};var brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];}
+var dimmingLevels=[SelectionState.DIMMED0,SelectionState.DIMMED1,SelectionState.DIMMED2];SelectionState.getFromDimmingLevel=function(level){return dimmingLevels[level];}
+return{SelectionState:SelectionState};});'use strict';tr.exportTo('tr.model',function(){var SelectionState=tr.model.SelectionState;function SelectableItem(modelItem){this.modelItem_=modelItem;}
+SelectableItem.prototype={get modelItem(){return this.modelItem_;},get selected(){return this.selectionState===SelectionState.SELECTED;},addToSelection:function(selection){var modelItem=this.modelItem_;if(!modelItem)
+return;selection.push(modelItem);},addToTrackMap:function(eventToTrackMap,track){var modelItem=this.modelItem_;if(!modelItem)
+return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem:SelectableItem};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocate();this.selectionState=SelectionState.NONE;this.associatedAlerts=new tr.model.EventSet();this.info=undefined;}
+Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},addBoundsToRange:function(range){throw new Error('Not implemented');}};return{Event:Event};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;}
+TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);},bounds:function(that,precisionUnit){if(precisionUnit===undefined){precisionUnit=tr.b.u.TimeDisplayModes.ms;}
+var startsBefore=precisionUnit.roundedLess(that.start,this.start);var endsAfter=precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent:TimedEvent};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.associatedAlerts.push(this);},this);}
+Alert.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.info.title;},get colorId(){return this.info.colorId;},get userFriendlyName(){return'Alert '+this.title+' at '+
+tr.b.u.TimeStamp.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts',singleViewElementName:'tr-ui-a-alert-sub-view',multiViewElementName:'tr-ui-a-alert-sub-view'});return{Alert:Alert};});'use strict';tr.exportTo('tr.model',function(){function EventContainer(){this.guid_=tr.b.GUID.allocate();this.important=true;this.bounds_=new tr.b.Range();}
+EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds:function(){throw new Error('Not implemented');},shiftTimestampsForward:function(amount){throw new Error('Not implemented');},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){throw new Error('Not implemented');},iterateAllChildEventContainers:function(callback,opt_this){throw new Error('Not implemented');},iterateAllEvents:function(callback,opt_this){this.iterateAllEventContainers(function(ec){ec.iterateAllEventsInThisContainer(function(eventType){return true;},callback,opt_this);});},iterateAllEventContainers:function(callback,opt_this){function visit(ec){callback.call(opt_this,ec);ec.iterateAllChildEventContainers(visit);}
+visit(this);}};return{EventContainer:EventContainer};});'use strict';tr.exportTo('tr.model',function(){var Event=tr.model.Event;var EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,power){Event.call(this);this.series_=series;this.start_=start;this.power_=power;}
+PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get power(){return this.power_;},set power(value){this.power_=value;},addBoundsToRange:function(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples',singleViewElementName:'tr-ui-a-single-power-sample-sub-view',multiViewElementName:'tr-ui-a-multi-power-sample-sub-view'});return{PowerSample:PowerSample};});'use strict';tr.exportTo('tr.model',function(){var PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
+PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample:function(ts,val){var sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumed:function(start,end){var measurementRange=tr.b.Range.fromExplicitRange(start,end);var energyConsumed=0;for(var i=0;i<this.samples.length;i++){var sample=this.samples[i];var nextSample=this.samples[i+1];var sampleRange=new tr.b.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:Infinity);var timeIntersection=measurementRange.findIntersection(sampleRange);energyConsumed+=timeIntersection.duration/1000*sample.power;}
+return energyConsumed;},shiftTimestampsForward:function(amount){for(var i=0;i<this.samples_.length;++i)
+this.samples_[i].start+=amount;},updateBounds:function(){this.bounds.reset();if(this.samples_.length===0)
+return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,PowerSample))
+this.samples_.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){}};return{PowerSeries:PowerSeries};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model)
+throw new Error('Must provide a model.');tr.model.EventContainer.call(this);this.powerSeries_=undefined;this.vSyncTimestamps_=[];};Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo:function(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey:function(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds:function(){this.bounds.reset();this.iterateAllChildEventContainers(function(child){child.updateBounds();this.bounds.addRange(child.bounds);},this);},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});for(var i=0;i<this.vSyncTimestamps_.length;i++)
+this.vSyncTimestamps_[i]+=amount;},addCategoriesToDict:function(categoriesDict){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){if(this.powerSeries_)
+callback.call(opt_this,this.powerSeries_);}};return{Device:Device};});'use strict';tr.exportTo('tr.model',function(){function FlowEvent(category,id,title,colorId,start,args,opt_duration){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.id=id;this.startSlice=undefined;this.endSlice=undefined;this.startStackFrame=undefined;this.endStackFrame=undefined;if(opt_duration!==undefined)
+this.duration=opt_duration;}
+FlowEvent.prototype={__proto__:tr.model.TimedEvent.prototype,get userFriendlyName(){return'Flow event named '+this.title+' at '+
+tr.b.u.TimeStamp.format(this.timestamp);}};tr.model.EventRegistry.register(FlowEvent,{name:'flowEvent',pluralName:'flowEvents',singleViewElementName:'tr-ui-a-single-flow-event-sub-view',multiViewElementName:'tr-ui-a-multi-flow-event-sub-view'});return{FlowEvent:FlowEvent};});'use strict';tr.exportTo('tr.b',function(){function identity(d){return d;}
+function Statistics(){}
+Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)
+return 0;return numerator/denominator;}
+Statistics.sum=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=0;for(var i=0;i<ary.length;i++)
+ret+=func.call(opt_this,ary[i],i);return ret;};Statistics.mean=function(ary,opt_func,opt_this){return Statistics.sum(ary,opt_func,opt_this)/ary.length;};Statistics.variance=function(ary,opt_func,opt_this){var func=opt_func||identity;var mean=Statistics.mean(ary,func,opt_this);var sumOfSquaredDistances=Statistics.sum(ary,function(d,i){var v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=-Infinity;for(var i=0;i<ary.length;i++)
+ret=Math.max(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.min=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=Infinity;for(var i=0;i<ary.length;i++)
+ret=Math.min(ret,func.call(opt_this,ary[i],i));return ret;};Statistics.range=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=new tr.b.Range();for(var i=0;i<ary.length;i++)
+ret.addValue(func.call(opt_this,ary[i],i));return ret;}
+Statistics.percentile=function(ary,percent,opt_func,opt_this){if(!(percent>=0&&percent<=1))
+throw new Error('percent must be [0,1]');var func=opt_func||identity;var tmp=new Array(ary.length);for(var i=0;i<ary.length;i++)
+tmp[i]=func.call(opt_this,ary[i],i);tmp.sort();var idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.clamp=function(value,opt_low,opt_high){opt_low=opt_low||0.0;opt_high=opt_high||1.0;return Math.min(Math.max(value,opt_low),opt_high);}
+Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
+samples=samples.slice().sort(function(a,b){return a-b;});var low=Math.min.apply(null,samples);var high=Math.max.apply(null,samples);var new_low=0.5/samples.length;var new_high=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
+var scale=(new_high-new_low)/(high-low);for(var i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+new_low;}
+return{normalized_samples:samples,scale:scale};}
+Statistics.discrepancy=function(samples,opt_location_count){if(samples.length===0)
+return 0.0;var max_local_discrepancy=0;var inv_sample_count=1.0/samples.length;var locations=[];var count_less=[];var count_less_equal=[];if(opt_location_count!==undefined){var sample_index=0;for(var i=0;i<opt_location_count;i++){var location=i/(opt_location_count-1);locations.push(location);while(sample_index<samples.length&&samples[sample_index]<location){sample_index+=1;}
+count_less.push(sample_index);while(sample_index<samples.length&&samples[sample_index]<=location){sample_index+=1;}
+count_less_equal.push(sample_index);}}else{if(samples[0]>0.0){locations.push(0.0);count_less.push(0);count_less_equal.push(0);}
+for(var i=0;i<samples.length;i++){locations.push(samples[i]);count_less.push(i);count_less_equal.push(i+1);}
+if(samples[-1]<1.0){locations.push(1.0);count_less.push(samples.length);count_less_equal.push(samples.length);}}
+for(var i=0;i<locations.length;i++){for(var j=i+1;j<locations.length;j++){var length=locations[j]-locations[i];var count_closed=count_less_equal[j]-count_less[i];var local_discrepancy_closed=Math.abs(count_closed*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_closed,max_local_discrepancy);var count_open=count_less[j]-count_less_equal[i];var local_discrepancy_open=Math.abs(count_open*inv_sample_count-length);var max_local_discrepancy=Math.max(local_discrepancy_open,max_local_discrepancy);}}
+return max_local_discrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_location_count){if(timestamps.length===0)
+return 0.0;if(opt_absolute===undefined)
+opt_absolute=true;if(Array.isArray(timestamps[0])){var range_discrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,range_discrepancies);}
+var s=Statistics.normalizeSamples(timestamps);var samples=s.normalized_samples;var sample_scale=s.scale;var discrepancy=Statistics.discrepancy(samples,opt_location_count);var inv_sample_count=1.0/samples.length;if(opt_absolute===true){discrepancy/=sample_scale;}else{discrepancy=Statistics.clamp((discrepancy-inv_sample_count)/(1.0-inv_sample_count));}
+return discrepancy;};Statistics.durationsDiscrepancy=function(durations,opt_absolute,opt_location_count){if(durations.length===0)
+return 0.0;var timestamps=durations.reduce(function(prev,curr,index,array){prev.push(prev[prev.length-1]+curr);return prev;},[0]);return Statistics.timestampsDiscrepancy(timestamps,opt_absolute,opt_location_count);};Statistics.uniformlySampleStream=function(samples,streamLength,newElement,numSamples){if(streamLength<=numSamples){if(samples.length>=streamLength)
+samples[streamLength-1]=newElement;else
+samples.push(newElement);return;}
+var probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)
+return;var index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){var nbElements=Math.min(streamLengthB,samplesB.length);for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
+return;}
+if(streamLengthA<numSamples){var nbElements=Math.min(streamLengthA,samplesA.length);var tempSamples=samplesB.slice();for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
+for(var i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
+return;}
+var nbElements=Math.min(numSamples,samplesB.length);var probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(var i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}}
+return{Statistics:Statistics};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;};Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward:function(amount){this.start+=amount;this.end+=amount;for(var i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames',singleViewElementName:'tr-ui-a-single-frame-sub-view',multiViewElementName:'tr-ui-a-multi-frame-sub-view'});return{Frame:Frame,FRAME_PERF_CLASS:FRAME_PERF_CLASS};});'use strict';tr.exportTo('tr.model',function(){function Attribute(units){this.units=units;this.infos=[];}
+Attribute.fromDictIfPossible=function(dict,opt_model){var typeInfo=Attribute.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.type===dict.type;});if(typeInfo===undefined){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Unknown attribute type \''+dict.type+'\'.'});}
+return UnknownAttribute.fromDict(dict,opt_model);}
+return typeInfo.constructor.fromDict(dict,opt_model);};Attribute.findCommonTraits=function(attributes,opt_model){var commonTraits;for(var i=0;i<attributes.length;i++){var attribute=attributes[i];if(attribute===undefined)
+continue;var attributeConstructor=attribute.constructor;var attributeUnits=attribute.units;if(commonTraits===undefined){commonTraits={constructor:attributeConstructor,units:attributeUnits};}else if(attributeConstructor!==commonTraits.constructor){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different types: '+
+commonTraits.constructor+' and '+attributeConstructor+'.'});}
+commonTraits={constructor:UnknownAttribute,units:undefined};break;}else if(attributeUnits!==commonTraits.units){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different units: '+commonTraits.units+' and '+attributeUnits+'.'});}
+commonTraits={constructor:UnknownAttribute,units:undefined};break;}}
+return commonTraits;};Attribute.aggregate=function(childAttributes,existingParentAttribute,opt_model){var definedChildAttributes=childAttributes.filter(function(childAttribute){return childAttribute!==undefined;});var traits=Attribute.findCommonTraits(definedChildAttributes,opt_model);if(traits===undefined)
+return existingParentAttribute;var constructor=traits.constructor;if(constructor.merge===undefined)
+return existingParentAttribute;var mergedAttribute=constructor.merge(definedChildAttributes,traits.units,opt_model);if(existingParentAttribute===undefined)
+return mergedAttribute;existingParentAttribute.useMergedAttribute(mergedAttribute,opt_model);return existingParentAttribute;}
+Attribute.fromTraceValue=function(dict,opt_model){throw new Error('Not implemented');};Attribute.prototype.useMergedAttribute=function(mergedAttribute,opt_model){if(mergedAttribute.constructor!==this.constructor){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different types: '+this.constructor+' and '+mergedAttribute.constructor+'.'});}}else if(mergedAttribute.units!==this.units){if(opt_model){opt_model.importWarning({type:'attribute_parse_error',message:'Attribute with different units: '+this.units+' and '+mergedAttribute.units+'.'});}}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Attribute,options);Attribute.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict'))
+throw new Error('Attributes must have fromDict method');if(!e.typeInfo.metadata.type)
+throw new Error('Attributes must provide type');if(e.typeInfo.constructor.prototype.constructor!==e.typeInfo.constructor)
+throw new Error('Attribute prototypes must provide constructor.');});function ScalarAttribute(units,value){Attribute.call(this,units);this.value=value;}
+ScalarAttribute.fromDict=function(dict){return new ScalarAttribute(dict.units,parseInt(dict.value,16));};ScalarAttribute.merge=function(childAttributes,units){var sum=0;childAttributes.forEach(function(childAttribute){sum+=childAttribute.value;});return new ScalarAttribute(units,sum);}
+ScalarAttribute.prototype.__proto__=Attribute.prototype;Attribute.register(ScalarAttribute,{type:'scalar'});function StringAttribute(units,value){Attribute.call(this,units);this.value=value;}
+StringAttribute.fromDict=function(dict){return new StringAttribute(dict.units,dict.value);};Attribute.register(StringAttribute,{type:'string'});function UnknownAttribute(units,opt_value){Attribute.call(this,units,opt_value);this.value=opt_value;}
+UnknownAttribute.fromDict=function(dict){return new UnknownAttribute(dict.units);};UnknownAttribute.prototype.__proto__=Attribute.prototype;function AttributeInfo(type,message){this.type=type;this.message=message;}
+var AttributeInfoType={INFORMATION:0,WARNING:1,LINK:2,MEMORY_OWNER:3,MEMORY_OWNED:4,OVERALL_VALUE:5,RECENT_VALUE:6,HAS_HEAP_DUMP:7};return{Attribute:Attribute,ScalarAttribute:ScalarAttribute,StringAttribute:StringAttribute,UnknownAttribute:UnknownAttribute,AttributeInfo:AttributeInfo,AttributeInfoType:AttributeInfoType};});'use strict';tr.exportTo('tr.model',function(){function ContainerMemoryDump(start){tr.model.TimedEvent.call(this,start);this.levelOfDetail=undefined;this.memoryAllocatorDumps_=undefined;this.memoryAllocatorDumpsByFullName_=undefined;};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.memoryAllocatorDumpsByFullName_=undefined;},getMemoryAllocatorDumpByFullName:function(fullName){if(this.memoryAllocatorDumps_===undefined)
+return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){var index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});};addDumpsToIndex(this.memoryAllocatorDumps_);this.memoryAllocatorDumpsByFullName_=index;}
+return this.memoryAllocatorDumpsByFullName_[fullName];},iterateRootAllocatorDumps:function(fn,opt_this){if(this.memoryAllocatorDumps===undefined)
+return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump:ContainerMemoryDump};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.attributes={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.retains=[];this.retainedBy=[];this.guid=opt_guid;};MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME='size';MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME='effective_size';MemoryAllocatorDump.DISPLAYED_SIZE_ATTRIBUTE_NAME=MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME;MemoryAllocatorDump.prototype={get name(){return this.fullName.substring(this.fullName.lastIndexOf('/')+1);},get quantifiedName(){return'\''+this.fullName+'\' in '+
+this.containerMemoryDump.containerName;},isDescendantOf:function(otherDump){var dump=this;while(dump!==undefined){if(dump===otherDump)
+return true;dump=dump.parent;}
+return false;},addAttribute:function(name,value){if(name in this.attributes)
+throw new Error('Duplicate attribute name: '+name+'.');this.attributes[name]=value;},aggregateAttributes:function(opt_model){var attributes={};this.children.forEach(function(child){child.aggregateAttributes(opt_model);tr.b.iterItems(child.attributes,function(name){attributes[name]=true;},this);},this);tr.b.iterItems(attributes,function(name){var childAttributes=this.children.map(function(child){return child.attributes[name];},this);var currentAttribute=this.attributes[name];this.attributes[name]=tr.model.Attribute.aggregate(childAttributes,currentAttribute,opt_model);},this);},getValidSizeAttributeOrUndefined:function(sizeAttrName,opt_model){var sizeAttr=this.attributes[sizeAttrName];if(sizeAttr===undefined)
+return undefined;if(!(sizeAttr instanceof tr.model.ScalarAttribute)){if(opt_model!==undefined){opt_model.importWarning({type:'memory_dump_parse_error',message:'\''+sizeAttrName+'\' attribute of memory allocator '+'dump \''+memoryAllocatorDump.fullName+'\' is not a scalar.'});}
+return undefined;}
+return sizeAttr;}};function MemoryAllocatorDumpLink(source,target,opt_importance){this.source=source;this.target=target;this.importance=opt_importance;}
+return{MemoryAllocatorDump:MemoryAllocatorDump,MemoryAllocatorDumpLink:MemoryAllocatorDumpLink};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
+var SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME;var EFFECTIVE_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME;function getSize(dump){var attr=dump.attributes[SIZE_ATTRIBUTE_NAME];if(attr===undefined)
+return 0;return attr.value;}
+function hasSize(dump){return dump.attributes[SIZE_ATTRIBUTE_NAME]!==undefined;}
+function optional(value,defaultValue){if(value===undefined)
+return defaultValue;return value;}
+function ownershipToUserFriendlyString(dump,importance){return dump.quantifiedName+' (importance: '+
+optional(importance,0)+')';}
+GlobalMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Global memory dump at '+tr.b.u.TimeStamp.format(this.start);},get containerName(){return'global space';},calculateGraphAttributes:function(){this.calculateSizes();this.calculateEffectiveSizes();this.aggregateAttributes();this.discountTracingOverhead();},calculateSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_:function(dump){var shouldDefineSize=false;function getDependencySize(dependencyDump){var attr=dependencyDump.attributes[SIZE_ATTRIBUTE_NAME];if(attr===undefined)
+return 0;shouldDefineSize=true;return attr.value;}
+var sizeAttribute=dump.getValidSizeAttributeOrUndefined(SIZE_ATTRIBUTE_NAME,this.model);var size=0;var infos=[];var checkDependentSizeIsConsistent=function(){};if(sizeAttribute!==undefined){size=sizeAttribute.value;shouldDefineSize=true;checkDependentSizeIsConsistent=function(dependentSize,dependentName){if(size>=dependentSize)
+return;var messageSuffix=' ('+tr.b.u.Units.sizeInBytes.format(size)+') is less than '+dependentName+' ('+
+tr.b.u.Units.sizeInBytes.format(dependentSize)+').';this.model.importWarning({type:'memory_dump_parse_error',message:'Size provided by memory allocator dump \''+
+dump.fullName+'\''+messageSuffix});infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.WARNING,'Size provided by this memory allocator dump'+messageSuffix));}.bind(this);}
+var aggregatedChildrenSize=0;var allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){var ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){var ownedDescendantDump=ownedDumpLink.target;var ownedChildDump=ownedDescendantDump;while(ownedChildDump.parent!==dump)
+ownedChildDump=ownedChildDump.parent;if(childDump!==ownedChildDump){var overlap=getDependencySize(descendantDump);if(overlap>0){var ownedChildOverlaps=allOverlaps[ownedChildDump.name];if(ownedChildOverlaps===undefined)
+allOverlaps[ownedChildDump.name]=ownedChildOverlaps={};var previousTotalOverlap=ownedChildOverlaps[childDump.name]||0;var updatedTotalOverlap=previousTotalOverlap+overlap;ownedChildOverlaps[childDump.name]=updatedTotalOverlap;}}
+return;}
+if(descendantDump.children.length===0){aggregatedChildrenSize+=getDependencySize(descendantDump);return;}
+descendantDump.children.forEach(aggregateDescendantDump);}
+aggregateDescendantDump(childDump);});dump.children.forEach(function(childDump){var childOverlaps=allOverlaps[childDump.name];if(childOverlaps===undefined)
+return;var message=tr.b.dictionaryValues(tr.b.mapItems(childOverlaps,function(ownerChildName,overlap){return'overlaps with its sibling \''+ownerChildName+'\' ('+
+tr.b.u.Units.sizeInBytes.format(overlap)+')';})).join(' ');childDump.attributes[SIZE_ATTRIBUTE_NAME].infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.INFORMATION,message));});checkDependentSizeIsConsistent(aggregatedChildrenSize,'the aggregated size of its children');var largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){var owner=ownershipLink.source;var ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependentSizeIsConsistent(largestOwnerSize,'the size of its largest owner');if(!shouldDefineSize){dump.attributes[SIZE_ATTRIBUTE_NAME]=undefined;return;}
+size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);var sizeAttribute=new tr.model.ScalarAttribute('bytes',size);sizeAttribute.infos=infos;dump.attributes[SIZE_ATTRIBUTE_NAME]=sizeAttribute;if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){var virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.attributes[SIZE_ATTRIBUTE_NAME]=new tr.model.ScalarAttribute('bytes',size-aggregatedChildrenSize);}},calculateEffectiveSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_:function(dump){if(!hasSize(dump))
+return;if(dump.children===undefined||dump.children.length===0){var size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
+var notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)
+return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;var notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
+var largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_:function(dump){if(!hasSize(dump))
+return;if(dump.ownedBy.length===0)
+return;var owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance)
+return a.notOwningSubSize-b.notOwningSubSize;return b.importance-a.importance;});var currentImportanceStartPos=0;var alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){var currentImportance=owners[currentImportanceStartPos].importance;var nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
+var attributedNotOwningSubSize=0;for(var pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){var owner=owners[pos];var notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
+var owningCoefficient=0;if(notOwningSubSize!==0)
+owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;owner.dump.owningCoefficient_=owningCoefficient;}
+currentImportanceStartPos=nextImportanceStartPos;}
+var notOwnedSubSize=optional(dump.notOwnedSubSize_,0);var remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;var ownedCoefficient=0;if(notOwnedSubSize!==0)
+ownedCoefficient=remainderSubSize/notOwnedSubSize;dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_:function(dump){if(!hasSize(dump))
+return;var cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);var parent=dump.parent;if(dump.parent!==undefined)
+cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;var cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
+dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_:function(dump){if(!hasSize(dump)){dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME]=undefined;return;}
+var effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))
+return;effectiveSize+=childDump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME].value;});}
+var attribute=new tr.model.ScalarAttribute('bytes',effectiveSize);dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME]=attribute;if(dump.ownedBy.length>0){var message='shared by:'+
+dump.ownedBy.map(function(ownershipLink){return'\n  - '+ownershipToUserFriendlyString(ownershipLink.source,ownershipLink.importance);}).join();attribute.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.MEMORY_OWNED,message));}
+if(dump.owns!==undefined){var target=dump.owns.target;var message='shares '+
+ownershipToUserFriendlyString(target,dump.owns.importance)+' with';var otherOwnershipLinks=target.ownedBy.filter(function(ownershipLink){return ownershipLink.source!==dump;});if(otherOwnershipLinks.length>0){message+=':';message+=otherOwnershipLinks.map(function(ownershipLink){return'\n  - '+ownershipToUserFriendlyString(ownershipLink.source,ownershipLink.importance);}).join();}else{message+=' no other dumps';}
+attribute.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.MEMORY_OWNER,message));}},aggregateAttributes:function(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateAttributes(this.model);});this.iterateRootAllocatorDumps(this.propagateAttributesRecursively);tr.b.iterItems(this.processMemoryDumps,function(pid,processMemoryDump){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateAttributes(this.model);},this);},this);},propagateAttributesRecursively:function(globalAllocatorDump){tr.b.iterItems(globalAllocatorDump.attributes,function(attrName,attr){if(attrName===SIZE_ATTRIBUTE_NAME||attrName===EFFECTIVE_SIZE_ATTRIBUTE_NAME){return;}
+globalAllocatorDump.ownedBy.forEach(function(ownershipLink){var processAllocatorDump=ownershipLink.source;if(processAllocatorDump.attributes[attrName]!==undefined){return;}
+processAllocatorDump.attributes[attrName]=attr;});});globalAllocatorDump.children.forEach(this.propagateAttributesRecursively,this);},discountTracingOverhead:function(){tr.b.iterItems(this.processMemoryDumps,function(pid,dump){dump.discountTracingOverhead(this.model);},this);},iterateContainerDumps:function(fn){fn.call(this,this);tr.b.iterItems(this.processMemoryDumps,function(pid,processDump){fn.call(this,processDump);},this);},iterateAllRootAllocatorDumps:function(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder:function(fn){var visitedDumps=new WeakSet();var openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
+return;if(openDumps.has(dump))
+throw new Error(dump.userFriendlyName+' contains a cycle');openDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);fn.call(this,dump);visitedDumps.add(dump);openDumps.delete(dump);}
+this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder:function(fn){var visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))
+return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target))
+return;if(dump.parent!==undefined&&!visitedDumps.has(dump.parent))
+return;fn.call(this,dump);visitedDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);}
+this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{GlobalMemoryDump:GlobalMemoryDump};});'use strict';tr.exportTo('tr.model',function(){var InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args){tr.model.TimedEvent.call(this);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.type=undefined;};InstantEvent.prototype={__proto__:tr.model.TimedEvent.prototype};function GlobalInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.GLOBAL;};GlobalInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Global instant event '+this.title+' @ '+
+tr.b.u.TimeStamp.format(start);}};function ProcessInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.PROCESS;};ProcessInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Process-level instant event '+this.title+' @ '+
+tr.b.u.TimeStamp.format(start);}};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents',singleViewElementName:'tr-ui-a-single-instant-event-sub-view',multiViewElementName:'tr-ui-a-multi-instant-event-sub-view'});return{GlobalInstantEvent:GlobalInstantEvent,ProcessInstantEvent:ProcessInstantEvent,InstantEventType:InstantEventType,InstantEvent:InstantEvent};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState:CompoundEventSelectionState};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function InteractionRecord(parentModel,title,colorId,start,duration){tr.model.TimedEvent.call(this,start);this.title=title;this.colorId=colorId;this.duration=duration;this.args={};this.associatedEvents=new tr.model.EventSet();this.parentModel=parentModel;this.sourceEvents=new tr.model.EventSet();}
+InteractionRecord.prototype={__proto__:tr.model.TimedEvent.prototype,get subSlices(){return[];},get userFriendlyName(){return this.title+' interaction at '+
+tr.b.u.TimeStamp.format(this.start);},get stableId(){return'IR.'+this.parentModel.interactionRecords.indexOf(this);},computeCompoundEvenSelectionState:function(selection){var cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this))
+cess|=CompoundEventSelectionState.EVENT_SELECTED;if(this.associatedEvents.intersectionIsEmpty(selection))
+return cess;var allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained)
+cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;else
+cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;return cess;}};tr.model.EventRegistry.register(InteractionRecord,{name:'interaction',pluralName:'interactions',singleViewElementName:'tr-ui-a-single-interaction-record-sub-view',multiViewElementName:'tr-ui-a-multi-interaction-record-sub-view'});return{InteractionRecord:InteractionRecord};});'use strict';tr.exportTo('tr.b',function(){function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length==0)
+return 1;var low=0;var high=ary.length-1;var i,comparison;var hitPos=-1;while(low<=high){i=Math.floor((low+high)/2);comparison=mapFn(ary[i])-loVal;if(comparison<0){low=i+1;continue;}else if(comparison>0){high=i-1;continue;}else{hitPos=i;high=i-1;}}
+return hitPos!=-1?hitPos:low;}
+function findHighIndexInSortedArray(ary,mapFn,loVal,hiVal){var lo=loVal||0;var hi=hiVal!==undefined?hiVal:ary.length;while(lo<hi){var mid=(lo+hi)>>1;if(mapFn(ary[mid])>=0)
+lo=mid+1;else
+hi=mid;}
+return hi;}
+function findIndexInSortedIntervals(ary,mapLoFn,mapWidthFn,loVal){var first=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(first==0){if(loVal>=mapLoFn(ary[0])&&loVal<mapLoFn(ary[0])+mapWidthFn(ary[0],0)){return 0;}else{return-1;}}else if(first<ary.length){if(loVal>=mapLoFn(ary[first])&&loVal<mapLoFn(ary[first])+mapWidthFn(ary[first],first)){return first;}else if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
+mapWidthFn(ary[first-1],first-1)){return first-1;}else{return ary.length;}}else if(first==ary.length){if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
+mapWidthFn(ary[first-1],first-1)){return first-1;}else{return ary.length;}}else{return ary.length;}}
+function findIndexInSortedClosedIntervals(ary,mapLoFn,mapHiFn,val){var i=findLowIndexInSortedArray(ary,mapLoFn,val);if(i===0){if(val>=mapLoFn(ary[0],0)&&val<=mapHiFn(ary[0],0)){return 0;}else{return-1;}}else if(i<ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}else if(val>=mapLoFn(ary[i],i)&&val<=mapHiFn(ary[i],i)){return i;}else{return ary.length;}}else if(i==ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}else{return ary.length;}}else{return ary.length;}}
+function iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,cb){if(ary.length==0)
+return;if(loVal>hiVal)return;var i=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(i==-1){return;}
+if(i>0){var hi=mapLoFn(ary[i-1])+mapWidthFn(ary[i-1],i-1);if(hi>=loVal){cb(ary[i-1],i-1);}}
+if(i==ary.length){return;}
+for(var n=ary.length;i<n;i++){var lo=mapLoFn(ary[i]);if(lo>=hiVal)
+break;cb(ary[i],i);}}
+function getIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal){var tmp=[];iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,function(d){tmp.push(d);});return tmp;}
+function findClosestElementInSortedArray(ary,mapFn,val,maxDiff){if(ary.length===0)
+return null;var aftIdx=findLowIndexInSortedArray(ary,mapFn,val);var befIdx=aftIdx>0?aftIdx-1:0;if(aftIdx===ary.length)
+aftIdx-=1;var befDiff=Math.abs(val-mapFn(ary[befIdx]));var aftDiff=Math.abs(val-mapFn(ary[aftIdx]));if(befDiff>maxDiff&&aftDiff>maxDiff)
+return null;var idx=befDiff<aftDiff?befIdx:aftIdx;return ary[idx];}
+function findClosestIntervalInSortedIntervals(ary,mapLoFn,mapHiFn,val,maxDiff){if(ary.length===0)
+return null;var idx=findLowIndexInSortedArray(ary,mapLoFn,val);if(idx>0)
+idx-=1;var hiInt=ary[idx];var loInt=hiInt;if(val>mapHiFn(hiInt)&&idx+1<ary.length)
+loInt=ary[idx+1];var loDiff=Math.abs(val-mapLoFn(loInt));var hiDiff=Math.abs(val-mapHiFn(hiInt));if(loDiff>maxDiff&&hiDiff>maxDiff)
+return null;if(loDiff<hiDiff)
+return loInt;else
+return hiInt;}
+return{findLowIndexInSortedArray:findLowIndexInSortedArray,findHighIndexInSortedArray:findHighIndexInSortedArray,findIndexInSortedIntervals:findIndexInSortedIntervals,findIndexInSortedClosedIntervals:findIndexInSortedClosedIntervals,iterateOverIntersectingIntervals:iterateOverIntersectingIntervals,getIntersectingIntervals:getIntersectingIntervals,findClosestElementInSortedArray:findClosestElementInSortedArray,findClosestIntervalInSortedIntervals:findClosestIntervalInSortedIntervals};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
+CounterSample.groupByTimestamp=function(samples){var samplesByTimestamp=tr.b.group(samples,function(sample){return sample.timestamp;});var timestamps=tr.b.dictionaryKeys(samplesByTimestamp);timestamps.sort();var groups=[];for(var i=0;i<timestamps.length;i++){var ts=timestamps[i];var group=samplesByTimestamp[ts];group.sort(function(x,y){return x.series.seriesIndex-y.series.seriesIndex;});groups.push(group);}
+return groups;}
+CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange:function(range){range.addValue(this.timestamp);},getSampleIndex:function(){return tr.b.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
+tr.b.u.TimeStamp.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples',singleViewElementName:'tr-ui-a-counter-sample-sub-view',multiViewElementName:'tr-ui-a-counter-sample-sub-view'});return{CounterSample:CounterSample};});'use strict';tr.exportTo('tr.model',function(){var CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
+CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample:function(idx){return this.samples_[idx];},getTimestamp:function(idx){return this.timestamps_[idx];},addCounterSample:function(ts,val){var sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample:function(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics:function(sampleIndices){var sum=0;var min=Number.MAX_VALUE;var max=-Number.MAX_VALUE;for(var i=0;i<sampleIndices.length;++i){var sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
+return{min:min,max:max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward:function(amount){for(var i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CounterSample)){this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){}};return{CounterSeries:CounterSeries};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
+Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllChildEventContainers:function(callback,opt_this){for(var i=0;i<this.series_.length;i++)
+callback.call(opt_this,this.series_[i]);},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries:function(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries:function(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)
+return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)
+return[];return this.series_[0].timestamps;},getSampleStatistics:function(sampleIndices){sampleIndices.sort();var ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward:function(amount){for(var i=0;i<this.series_.length;++i)
+this.series_[i].shiftTimestampsForward(amount);},updateBounds:function(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)
+return;var firstSeries=this.series_[0];var lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));var numSeries=this.numSeries;this.maxTotal=-Infinity;for(var i=0;i<firstSeries.length;++i){var total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){var tmp=x.parent.compareTo(y);if(tmp!=0)
+return tmp;var tmp=x.name.localeCompare(y.name);if(tmp==0)
+return x.tid-y.tid;return tmp;};return{Counter:Counter};});'use strict';tr.exportTo('tr.model',function(){function Slice(category,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.inFlowEvents=[];this.outFlowEvents=[];this.subSlices=[];this.selfTime=undefined;this.cpuSelfTime=undefined;this.important=false;this.parentContainer=undefined;this.argsStripped=false;this.bind_id_=opt_bind_id;this.parentSlice=undefined;this.isTopLevel=false;if(opt_duration!==undefined)
+this.duration=opt_duration;if(opt_cpuStart!==undefined)
+this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
+this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
+this.argsStripped=true;}
+Slice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get userFriendlyName(){return'Slice '+this.title+' at '+
+tr.b.u.TimeStamp.format(this.start);},get stableId(){var parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
+parentSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
+return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
+return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},get mostTopLevelSlice(){var curSlice=this;while(curSlice.parentSlice)
+curSlice=curSlice.parentSlice;return curSlice;},iterateAllSubsequentSlices:function(callback,opt_this){var parentStack=[];var started=false;var topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){var curSlice=parentStack.pop();if(started)
+callback.call(opt_this,curSlice);else
+started=(curSlice.guid===this.guid);for(var i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){var res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},iterateAllAncestors:function(callback,opt_this){var curSlice=this;while(curSlice.parentSlice){curSlice=curSlice.parentSlice;callback.call(opt_this,curSlice);}},get ancestorSlices(){var res=[];this.iterateAllAncestors(function(ancestor){res.push(ancestor);});return res;},iterateEntireHierarchy:function(callback,opt_this){var mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){var res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){var res=[];res.push(this);this.iterateAllAncestors(function(aSlice){res.push(aSlice);});this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},get descendentSlices(){var res=[];this.iterateAllDescendents(function(des){res.push(des);});return res;}};return{Slice:Slice};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;var SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
+ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_:function(state){var getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice:function(){if(!this.cpuOnWhichThreadWasRunning)
+return undefined;var cpuSlices=this.cpuOnWhichThreadWasRunning.slices;for(var i=0;i<cpuSlices.length;i++){var cpuSlice=cpuSlices[i];if(cpuSlice.start!==this.start)
+continue;if(cpuSlice.duration!==this.duration)
+continue;return cpuSlice;}
+return undefined;},getCpuSliceThatTookCpu:function(){if(this.cpuOnWhichThreadWasRunning)
+return undefined;var curIndex=this.thread.indexOfTimeSlice(this);var cpuSliceWhenLastRunning;while(curIndex>=0){var curSlice=this.thread.timeSlices[curIndex];if(!curSlice.cpuOnWhichThreadWasRunning){curIndex--;continue;}
+cpuSliceWhenLastRunning=curSlice.getAssociatedCpuSlice();break;}
+if(!cpuSliceWhenLastRunning)
+return undefined;var cpu=cpuSliceWhenLastRunning.cpu;var indexOfSliceOnCpuWhenLastRunning=cpu.indexOf(cpuSliceWhenLastRunning);var nextRunningSlice=cpu.slices[indexOfSliceOnCpuWhenLastRunning+1];if(!nextRunningSlice)
+return undefined;if(Math.abs(nextRunningSlice.start-cpuSliceWhenLastRunning.end)<0.00001)
+return nextRunningSlice;return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices',singleViewElementName:'tr-ui-a-single-thread-time-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-time-slice-sub-view'});return{ThreadTimeSlice:ThreadTimeSlice,SCHEDULING_STATE:SCHEDULING_STATE};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
+CpuSlice.prototype={__proto__:Slice.prototype,get analysisTypeName(){return'tr.ui.analysis.CpuSlice';},getAssociatedTimeslice:function(){if(!this.threadThatWasRunning)
+return undefined;var timeSlices=this.threadThatWasRunning.timeSlices;for(var i=0;i<timeSlices.length;i++){var timeSlice=timeSlices[i];if(timeSlice.start!==this.start)
+continue;if(timeSlice.duration!==this.duration)
+continue;return timeSlice;}
+return undefined;}};tr.model.EventRegistry.register(CpuSlice,{name:'cpuSlice',pluralName:'cpuSlices',singleViewElementName:'tr-ui-a-single-cpu-slice-sub-view',multiViewElementName:'tr-ui-a-multi-cpu-slice-sub-view'});return{CpuSlice:CpuSlice};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Counter=tr.model.Counter;var CpuSlice=tr.model.CpuSlice;var Slice=tr.model.Slice;function Cpu(kernel,number){if(kernel===undefined||number===undefined)
+throw new Error('Missing arguments');this.kernel=kernel;this.cpuNumber=number;this.slices=[];this.counters={};this.bounds=new tr.b.Range();this.samples_=undefined;this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;};Cpu.prototype={get samples(){return this.samples_;},get userFriendlyName(){return'CPU '+this.cpuNumber;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.CpuSlice))
+this.slices.forEach(callback,opt_this);if(this.samples_){if(eventTypePredicate.call(opt_this,tr.model.Sample))
+this.samples_.forEach(callback,opt_this);}},iterateAllChildEventContainers:function(callback,opt_this){for(var id in this.counters)
+callback.call(opt_this,this.counters[id]);},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
+this.counters[id]=new Counter(this,id,cat,name);return this.counters[id];},getCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
+return undefined;return this.counters[id];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++)
+this.slices[sI].start=(this.slices[sI].start+amount);for(var id in this.counters)
+this.counters[id].shiftTimestampsForward(amount);},updateBounds:function(){this.bounds.reset();if(this.slices.length){this.bounds.addValue(this.slices[0].start);this.bounds.addValue(this.slices[this.slices.length-1].end);}
+for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
+if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},createSubSlices:function(){this.samples_=this.kernel.model.samples.filter(function(sample){return sample.cpu==this;},this);},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.slices.length;i++)
+categoriesDict[this.slices[i].category]=true;for(var id in this.counters)
+categoriesDict[this.counters[id].category]=true;for(var i=0;i<this.samples_.length;i++)
+categoriesDict[this.samples_[i].category]=true;},indexOf:function(cpuSlice){var i=tr.b.findLowIndexInSortedArray(this.slices,function(slice){return slice.start;},cpuSlice.start);if(this.slices[i]!==cpuSlice)
+return undefined;return i;},closeActiveThread:function(end_timestamp,args){if(this.lastActiveThread_==undefined||this.lastActiveThread_==0)
+return;if(end_timestamp<this.lastActiveTimestamp_){throw new Error('The end timestamp of a thread running on CPU '+
+this.cpuNumber+' is before its start timestamp.');}
+for(var key in args){this.lastActiveArgs_[key]=args[key];}
+var duration=end_timestamp-this.lastActiveTimestamp_;var slice=new tr.model.CpuSlice('',this.lastActiveName_,ColorScheme.getColorIdForGeneralPurposeString(this.lastActiveName_),this.lastActiveTimestamp_,this.lastActiveArgs_,duration);slice.cpu=this;this.slices.push(slice);this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;},switchActiveThread:function(timestamp,old_thread_args,new_thread_id,new_thread_name,new_thread_args){this.closeActiveThread(timestamp,old_thread_args);this.lastActiveTimestamp_=timestamp;this.lastActiveThread_=new_thread_id;this.lastActiveName_=new_thread_name;this.lastActiveArgs_=new_thread_args;},getFreqStatsForRange:function(range){var stats={};function addStatsForFreq(freqSample,index){var freqEnd=(index<freqSample.series_.length-1)?freqSample.series_.samples_[index+1].timestamp:range.max;var freqRange=tr.b.Range.fromExplicitRange(freqSample.timestamp,freqEnd);var intersection=freqRange.findIntersection(range);if(!(freqSample.value in stats))
+stats[freqSample.value]=0;stats[freqSample.value]+=intersection.duration;}
+var freqCounter=this.getCounter('','Clock Frequency');if(freqCounter!==undefined){var freqSeries=freqCounter.getSeries(0);if(!freqSeries)
+return;tr.b.iterateOverIntersectingIntervals(freqSeries.samples_,function(x){return x.timestamp;},function(x,index){return index<freqSeries.length-1?freqSeries.samples_[index+1].timestamp:range.max;},range.min,range.max,addStatsForFreq);}
+return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu:Cpu};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
+ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize:function(){},initialize:function(){},addBoundsToRange:function(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+
+this.objectInstance.typeName+' '+
+this.objectInstance.id+' @ '+
+tr.b.u.TimeStamp.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots',singleViewElementName:'tr-ui-a-single-object-snapshot-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshot;options.defaultConstructor=ObjectSnapshot;tr.b.decorateExtensionRegistry(ObjectSnapshot,options);return{ObjectSnapshot:ObjectSnapshot};});'use strict';tr.exportTo('tr.model',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,id,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.id=id;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
+ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange:function(range){range.addRange(this.bounds);},addSnapshot:function(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs)
+throw new Error('Snapshots must be >= instance.creationTs');if(ts>=this.deletionTs)
+throw new Error('Snapshots cannot be added after '+'an objects deletion timestamp.');var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts==ts)
+throw new Error('Snapshots already exists at this time!');if(ts<lastSnapshot.ts){throw new Error('Snapshots must be added in increasing timestamp order');}}
+if(opt_name&&(this.name!=opt_name)){if(!opt_baseTypeName)
+throw new Error('Must provide base type name for name update');if(this.baseTypeName!=opt_baseTypeName)
+throw new Error('Cannot update type name: base types dont match');this.name=opt_name;}
+var snapshotConstructor=tr.model.ObjectSnapshot.getConstructor(this.category,this.name);var snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted:function(ts){var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts)
+throw new Error('Instance cannot be deleted at ts='+
+ts+'. A snapshot exists that is older.');}
+this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize:function(){for(var i=0;i<this.snapshots.length;i++)
+this.snapshots[i].preInitialize();},initialize:function(){for(var i=0;i<this.snapshots.length;i++)
+this.snapshots[i].initialize();},getSnapshotAt:function(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit)
+throw new Error('ts must be within lifetime of this instance');return this.snapshots[0];}
+if(ts>this.deletionTs)
+throw new Error('ts must be within lifetime of this instance');var snapshots=this.snapshots;var i=tr.b.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i==snapshots.length-1)
+return snapshots[i].objectInstance.deletionTs;return snapshots[i+1].ts-snapshots[i].ts;},ts);if(i<0){return this.snapshots[0];}
+if(i>=this.snapshots.length)
+return this.snapshots[this.snapshots.length-1];return this.snapshots[i];},updateBounds:function(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!=Number.MAX_VALUE)
+this.bounds.addValue(this.deletionTs);else if(this.snapshots.length>0)
+this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);},shiftTimestampsForward:function(amount){this.creationTs+=amount;if(this.deletionTs!=Number.MAX_VALUE)
+this.deletionTs+=amount;this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.id;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances',singleViewElementName:'tr-ui-a-single-object-instance-sub-view',multiViewElementName:'tr-ui-a-multi-object-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstance;options.defaultConstructor=ObjectInstance;tr.b.decorateExtensionRegistry(ObjectInstance,options);return{ObjectInstance:ObjectInstance};});'use strict';tr.exportTo('tr.model',function(){function TimeToObjectInstanceMap(createObjectInstanceFunction,parent,id){this.createObjectInstanceFunction_=createObjectInstanceFunction;this.parent=parent;this.id=id;this.instances=[];}
+TimeToObjectInstanceMap.prototype={idWasCreated:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
+var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.deletionTs){throw new Error('Mutation of the TimeToObjectInstanceMap must be '+'done in ascending timestamp order.');}
+lastInstance=this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot:function(category,name,ts,args,opt_baseTypeName){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts,opt_baseTypeName));}
+var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);var instance;if(i<0){instance=this.instances[0];if(ts>instance.deletionTs||instance.creationTsWasExplicit){throw new Error('At the provided timestamp, no instance was still alive');}
+if(instance.snapshots.length!=0){throw new Error('Cannot shift creationTs forward, '+'snapshots have been added. First snap was at ts='+
+instance.snapshots[0].ts+' and creationTs was '+
+instance.creationTs);}
+instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{var lastValidIndex;for(var i=this.instances.length-1;i>=0;i--){var tmp=this.instances[i];if(ts>=tmp.deletionTs)
+break;if(tmp.creationTsWasExplicit==false&&tmp.snapshots.length==0)
+lastValidIndex=i;}
+if(lastValidIndex===undefined){throw new Error('Cannot add snapshot. No instance was alive that was mutable.');}
+instance=this.instances[lastValidIndex];instance.creationTs=ts;}}else{instance=this.instances[i];}
+return instance.addSnapshot(ts,args,name,opt_baseTypeName);},get lastInstance(){if(this.instances.length==0)
+return undefined;return this.instances[this.instances.length-1];},idWasDeleted:function(category,name,ts){if(this.instances.length==0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts));}
+var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.creationTs)
+throw new Error('Cannot delete a id before it was crated');if(lastInstance.deletionTs==Number.MAX_VALUE){lastInstance.wasDeleted(ts);return lastInstance;}
+if(ts<lastInstance.deletionTs)
+throw new Error('id was already deleted earlier.');lastInstance=this.createObjectInstanceFunction_(this.parent,this.id,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt:function(ts){var i=tr.b.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit)
+return undefined;return this.instances[0];}else if(i>=this.instances.length){return undefined;}
+return this.instances[i];},logToConsole:function(){for(var i=0;i<this.instances.length;i++){var instance=this.instances[i];var cEF='';var dEF='';if(instance.creationTsWasExplicit)
+cEF='(explicitC)';if(instance.deletionTsWasExplicit)
+dEF='(explicit)';console.log(instance.creationTs,cEF,instance.deletionTs,dEF,instance.category,instance.name,instance.snapshots.length+' snapshots');}}};return{TimeToObjectInstanceMap:TimeToObjectInstanceMap};});'use strict';tr.exportTo('tr.model',function(){var ObjectInstance=tr.model.ObjectInstance;var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsById_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
+ObjectCollection.prototype={__proto__:tr.model.EventContainer.prototype,iterateAllChildEventContainers:function(callback,opt_this){},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){var bI=!!eventTypePredicate.call(opt_this,ObjectInstance);var bS=!!eventTypePredicate.call(opt_this,ObjectSnapshot);if(bI===false&&bS===false)
+return;this.iterObjectInstances(function(instance){if(bI)
+callback.call(opt_this,instance);if(bS)
+instance.snapshots.forEach(callback,opt_this);},opt_this);},createObjectInstance_:function(parent,id,category,name,creationTs,opt_baseTypeName){var constructor=tr.model.ObjectInstance.getConstructor(category,name);var instance=new constructor(parent,id,category,name,creationTs,opt_baseTypeName);var typeName=instance.typeName;var instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
+instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_:function(id){var instanceMap=this.instanceMapsById_[id];if(instanceMap)
+return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,id);this.instanceMapsById_[id]=instanceMap;return instanceMap;},idWasCreated:function(id,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(id);return instanceMap.idWasCreated(category,name,ts);},addSnapshot:function(id,category,name,ts,args,opt_baseTypeName){var instanceMap=this.getOrCreateInstanceMap_(id);var snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!=category){var msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
+snapshot.objectInstance.category+' name='+
+snapshot.objectInstance.name;throw new Error(msg);}
+if(opt_baseTypeName&&snapshot.objectInstance.baseTypeName!=opt_baseTypeName){throw new Error('Could not add snapshot with baseTypeName='+
+opt_baseTypeName+'. It '+'was previously created with name='+
+snapshot.objectInstance.baseTypeName);}
+if(snapshot.objectInstance.name!=name){throw new Error('Could not add snapshot with name='+name+'. It '+'was previously created with name='+
+snapshot.objectInstance.name);}
+return snapshot;},idWasDeleted:function(id,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(id);var deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)
+return;if(deletedInstance.category!=category){var msg='Deleting object '+deletedInstance.name+' with a different category '+'than when it was created. It previous had cat='+
+deletedInstance.category+' but the delete command '+'had cat='+category;throw new Error(msg);}
+if(deletedInstance.baseTypeName!=name){throw new Error('Deletion requested for name='+
+name+' could not proceed: '+'An existing object with baseTypeName='+
+deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects:function(maxTimestamp){tr.b.iterItems(this.instanceMapsById_,function(id,i2imap){var lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!=Number.MAX_VALUE)
+return;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;});},getObjectInstanceAt:function(id,ts){var instanceMap=this.instanceMapsById_[id];if(!instanceMap)
+return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt:function(id,ts){var instance=this.getObjectInstanceAt(id,ts);if(!instance)
+return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances:function(iter,opt_this){opt_this=opt_this||this;tr.b.iterItems(this.instanceMapsById_,function(id,i2imap){i2imap.instances.forEach(iter,opt_this);});},getAllObjectInstances:function(){var instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed:function(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName:function(){return this.instancesByTypeName_;},preInitializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances:function(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds:function(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward:function(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict:function(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection:ObjectCollection};});'use strict';tr.exportTo('tr.model',function(){function AsyncSlice(category,title,colorId,start,args,duration,opt_isTopLevel,opt_cpuStart,opt_cpuDuration,opt_argsStripped){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.important=false;this.subSlices=[];this.parentContainer=undefined;this.id=undefined;this.startThread=undefined;this.endThread=undefined;this.cpuStart=undefined;this.cpuDuration=undefined;this.argsStripped=false;this.startStackFrame=undefined;this.endStackFrame=undefined;this.duration=duration;this.isTopLevel=(opt_isTopLevel===true);if(opt_cpuStart!==undefined)
+this.cpuStart=opt_cpuStart;if(opt_cpuDuration!==undefined)
+this.cpuDuration=opt_cpuDuration;if(opt_argsStripped!==undefined)
+this.argsStripped=opt_argsStripped;};AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get viewSubGroupTitle(){return this.title;},get userFriendlyName(){return'Async slice '+this.title+' at '+
+tr.b.u.TimeStamp.format(this.start);},get stableId(){var parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
+parentAsyncSliceGroup.slices.indexOf(this);},findDescendentSlice:function(targetTitle){if(!this.subSlices)
+return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title==targetTitle)
+return this.subSlices[i];var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},iterateAllDescendents:function(callback,opt_this){this.subSlices.forEach(callback,opt_this);this.subSlices.forEach(function(subSlice){subSlice.iterateAllDescendents(callback,opt_this);},opt_this);},compareTo:function(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices',singleViewElementName:'tr-ui-a-single-async-slice-sub-view',multiViewElementName:'tr-ui-a-multi-async-slice-sub-view'});var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=AsyncSlice;options.defaultConstructor=AsyncSlice;tr.b.decorateExtensionRegistry(AsyncSlice,options);return{AsyncSlice:AsyncSlice};});'use strict';tr.exportTo('tr.model',function(){function AsyncSliceGroup(parentContainer,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;this.slices=[];this.name_=opt_name;this.viewSubGroups_=undefined;}
+AsyncSliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.parent.model;},get stableId(){return this.parentContainer_.stableId+'.AsyncSliceGroup';},getSettingsKey:function(){if(!this.name_)
+return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)
+return undefined;return parentKey+'.'+this.name_;},push:function(slice){slice.parentContainer=this.parentContainer;this.slices.push(slice);return slice;},get length(){return this.slices.length;},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);var shiftSubSlices=function(subSlices){if(subSlices===undefined||subSlices.length===0)
+return;for(var sJ=0;sJ<subSlices.length;sJ++){subSlices[sJ].start+=amount;shiftSubSlices(subSlices[sJ].subSlices);}};shiftSubSlices(slice.subSlices);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},get viewSubGroups(){if(this.viewSubGroups_===undefined){var prefix='';if(this.name!==undefined)
+prefix=this.name+'.';else
+prefix='';var subGroupsByTitle={};for(var i=0;i<this.slices.length;++i){var slice=this.slices[i];var subGroupTitle=slice.viewSubGroupTitle;if(!subGroupsByTitle[subGroupTitle]){subGroupsByTitle[subGroupTitle]=new AsyncSliceGroup(this.parentContainer_,prefix+subGroupTitle);}
+subGroupsByTitle[subGroupTitle].push(slice);}
+this.viewSubGroups_=tr.b.dictionaryValues(subGroupsByTitle);this.viewSubGroups_.sort(function(a,b){return a.slices[0].compareTo(b.slices[0]);});}
+return this.viewSubGroups_;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,tr.model.AsyncSlice)){for(var i=0;i<this.slices.length;i++){var slice=this.slices[i];callback.call(opt_this,slice);if(slice.subSlices)
+slice.subSlices.forEach(callback,opt_this);}}},iterateAllChildEventContainers:function(callback,opt_this){}};return{AsyncSliceGroup:AsyncSliceGroup};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Slice=tr.model.Slice;function getSliceLo(s){return s.start;}
+function getSliceHi(s){return s.end;}
+function SliceGroup(parentContainer,opt_sliceConstructor,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;var sliceConstructor=opt_sliceConstructor||Slice;this.sliceConstructor=sliceConstructor;this.openPartialSlices_=[];this.slices=[];this.topLevelSlices=[];this.haveTopLevelSlicesBeenBuilt=false;this.name_=opt_name;if(this.model===undefined)
+throw new Error('SliceGroup must have model defined.');}
+SliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.model;},get stableId(){return this.parentContainer_.stableId+'.SliceGroup';},getSettingsKey:function(){if(!this.name_)
+return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)
+return undefined;return parentKey+'.'+this.name;},get length(){return this.slices.length;},pushSlice:function(slice){this.haveTopLevelSlicesBeenBuilt=false;slice.parentContainer=this.parentContainer_;this.slices.push(slice);return slice;},pushSlices:function(slices){this.haveTopLevelSlicesBeenBuilt=false;slices.forEach(function(slice){slice.parentContainer=this.parentContainer_;this.slices.push(slice);},this);},beginSlice:function(category,title,ts,opt_args,opt_tts,opt_argsStripped,opt_colorId){if(this.openPartialSlices_.length){var prevSlice=this.openPartialSlices_[this.openPartialSlices_.length-1];if(ts<prevSlice.start)
+throw new Error('Slices must be added in increasing timestamp order');}
+var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var slice=new this.sliceConstructor(category,title,colorId,ts,opt_args?opt_args:{},null,opt_tts,undefined,opt_argsStripped);this.openPartialSlices_.push(slice);slice.didNotFinish=true;this.pushSlice(slice);return slice;},isTimestampValidForBeginOrEnd:function(ts){if(!this.openPartialSlices_.length)
+return true;var top=this.openPartialSlices_[this.openPartialSlices_.length-1];return ts>=top.start;},get openSliceCount(){return this.openPartialSlices_.length;},get mostRecentlyOpenedPartialSlice(){if(!this.openPartialSlices_.length)
+return undefined;return this.openPartialSlices_[this.openPartialSlices_.length-1];},endSlice:function(ts,opt_tts,opt_colorId){if(!this.openSliceCount)
+throw new Error('endSlice called without an open slice');var slice=this.openPartialSlices_[this.openSliceCount-1];this.openPartialSlices_.splice(this.openSliceCount-1,1);if(ts<slice.start)
+throw new Error('Slice '+slice.title+' end time is before its start.');slice.duration=ts-slice.start;slice.didNotFinish=false;slice.colorId=opt_colorId||slice.colorId;if(opt_tts&&slice.cpuStart!==undefined)
+slice.cpuDuration=opt_tts-slice.cpuStart;return slice;},pushCompleteSlice:function(category,title,ts,duration,tts,cpuDuration,opt_args,opt_argsStripped,opt_colorId,opt_bind_id){var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var slice=new this.sliceConstructor(category,title,colorId,ts,opt_args?opt_args:{},duration,tts,cpuDuration,opt_argsStripped,opt_bind_id);if(duration===undefined)
+slice.didNotFinish=true;this.pushSlice(slice);return slice;},autoCloseOpenSlices:function(opt_maxTimestamp){if(!opt_maxTimestamp){this.updateBounds();opt_maxTimestamp=this.bounds.max;}
+for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];if(slice.didNotFinish)
+slice.duration=opt_maxTimestamp-slice.start;}
+this.openPartialSlices_=[];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},copySlice:function(slice){var newSlice=new this.sliceConstructor(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration,slice.cpuStart,slice.cpuDuration);newSlice.didNotFinish=slice.didNotFinish;return newSlice;},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,this.sliceConstructor))
+this.slices.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){},getSlicesOfName:function(title){var slices=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].title==title){slices.push(this.slices[i]);}}
+return slices;},iterSlicesInTimeRange:function(callback,start,end){var ret=[];tr.b.iterateOverIntersectingIntervals(this.topLevelSlices,function(s){return s.start;},function(s){return s.duration;},start,end,function(topLevelSlice){callback(topLevelSlice);topLevelSlice.iterateAllDescendents(callback);});return ret;},findFirstSlice:function(){if(!this.haveTopLevelSlicesBeenBuilt)
+throw new Error('Nope');if(0===this.slices.length)
+return undefined;return this.slices[0];},findSliceAtTs:function(ts){if(!this.haveTopLevelSlicesBeenBuilt)
+throw new Error('Nope');var i=tr.b.findIndexInSortedClosedIntervals(this.topLevelSlices,getSliceLo,getSliceHi,ts);if(i==-1||i==this.topLevelSlices.length)
+return undefined;var curSlice=this.topLevelSlices[i];while(true){var i=tr.b.findIndexInSortedClosedIntervals(curSlice.subSlices,getSliceLo,getSliceHi,ts);if(i==-1||i==curSlice.subSlices.length)
+return curSlice;curSlice=curSlice.subSlices[i];}},findNextSliceAfter:function(ts,refGuid){var i=tr.b.findLowIndexInSortedArray(this.slices,getSliceLo,ts);if(i===this.slices.length)
+return undefined;for(;i<this.slices.length;i++){var slice=this.slices[i];if(slice.start>ts)
+return slice;if(slice.guid<=refGuid)
+continue;return slice;}
+return undefined;},createSubSlices:function(){this.haveTopLevelSlicesBeenBuilt=true;this.createSubSlicesImpl_();if(this.parentContainer.timeSlices)
+this.addCpuTimeToSubslices_(this.parentContainer.timeSlices);this.slices.forEach(function(slice){var selfTime=slice.duration;for(var i=0;i<slice.subSlices.length;i++)
+selfTime-=slice.subSlices[i].duration;slice.selfTime=selfTime;if(slice.cpuDuration===undefined)
+return;var cpuSelfTime=slice.cpuDuration;for(var i=0;i<slice.subSlices.length;i++){if(slice.subSlices[i].cpuDuration!==undefined)
+cpuSelfTime-=slice.subSlices[i].cpuDuration;}
+slice.cpuSelfTime=cpuSelfTime;});},createSubSlicesImpl_:function(){var precisionUnit=this.model.intrinsicTimeUnit;function addSliceIfBounds(root,child){if(root.bounds(child,precisionUnit)){if(root.subSlices&&root.subSlices.length>0){if(addSliceIfBounds(root.subSlices[root.subSlices.length-1],child))
+return true;}
+child.parentSlice=root;if(root.subSlices===undefined)
+root.subSlices=[];root.subSlices.push(child);return true;}
+return false;}
+if(!this.slices.length)
+return;var ops=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].subSlices)
+this.slices[i].subSlices.splice(0,this.slices[i].subSlices.length);ops.push(i);}
+var originalSlices=this.slices;ops.sort(function(ix,iy){var x=originalSlices[ix];var y=originalSlices[iy];if(x.start!=y.start)
+return x.start-y.start;return ix-iy;});var slices=new Array(this.slices.length);for(var i=0;i<ops.length;i++){slices[i]=originalSlices[ops[i]];}
+var rootSlice=slices[0];this.topLevelSlices=[];this.topLevelSlices.push(rootSlice);rootSlice.isTopLevel=true;for(var i=1;i<slices.length;i++){var slice=slices[i];if(!addSliceIfBounds(rootSlice,slice)){rootSlice=slice;rootSlice.isTopLevel=true;this.topLevelSlices.push(rootSlice);}}
+this.slices=slices;},addCpuTimeToSubslices_:function(timeSlices){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var sliceIdx=0;timeSlices.forEach(function(timeSlice){if(timeSlice.schedulingState==SCHEDULING_STATE.RUNNING){while(sliceIdx<this.topLevelSlices.length){if(this.addCpuTimeToSubslice_(this.topLevelSlices[sliceIdx],timeSlice)){sliceIdx++;}else{break;}}}},this);},addCpuTimeToSubslice_:function(slice,timeSlice){if(slice.start>timeSlice.end||slice.end<timeSlice.start)
+return slice.end<=timeSlice.end;var duration=timeSlice.duration;if(slice.start>timeSlice.start)
+duration-=slice.start-timeSlice.start;if(timeSlice.end>slice.end)
+duration-=timeSlice.end-slice.end;if(slice.cpuDuration){slice.cpuDuration+=duration;}else{slice.cpuDuration=duration;}
+for(var i=0;i<slice.subSlices.length;i++){this.addCpuTimeToSubslice_(slice.subSlices[i],timeSlice);}
+return slice.end<=timeSlice.end;}};SliceGroup.merge=function(groupA,groupB){if(groupA.openPartialSlices_.length>0)
+throw new Error('groupA has open partial slices');if(groupB.openPartialSlices_.length>0)
+throw new Error('groupB has open partial slices');if(groupA.parentContainer!=groupB.parentContainer)
+throw new Error('Different parent threads. Cannot merge');if(groupA.sliceConstructor!=groupB.sliceConstructor)
+throw new Error('Different slice constructors. Cannot merge');var result=new SliceGroup(groupA.parentContainer,groupA.sliceConstructor,groupA.name_);var slicesA=groupA.slices;var slicesB=groupB.slices;var idxA=0;var idxB=0;var openA=[];var openB=[];var splitOpenSlices=function(when){for(var i=0;i<openB.length;i++){var oldSlice=openB[i];var oldEnd=oldSlice.end;if(when<oldSlice.start||oldEnd<when){throw new Error('slice should not be split');}
+var newSlice=result.copySlice(oldSlice);newSlice.start=when;newSlice.duration=oldEnd-when;if(newSlice.title.indexOf(' (cont.)')==-1)
+newSlice.title+=' (cont.)';oldSlice.duration=when-oldSlice.start;openB[i]=newSlice;result.pushSlice(newSlice);}};var closeOpenSlices=function(upTo){while(openA.length>0||openB.length>0){var nextA=openA[openA.length-1];var nextB=openB[openB.length-1];var endA=nextA&&nextA.end;var endB=nextB&&nextB.end;if((endA===undefined||endA>upTo)&&(endB===undefined||endB>upTo)){return;}
+if(endB===undefined||endA<endB){splitOpenSlices(endA);openA.pop();}else{openB.pop();}}};while(idxA<slicesA.length||idxB<slicesB.length){var sA=slicesA[idxA];var sB=slicesB[idxB];var nextSlice,isFromB;if(sA===undefined||(sB!==undefined&&sA.start>sB.start)){nextSlice=result.copySlice(sB);isFromB=true;idxB++;}else{nextSlice=result.copySlice(sA);isFromB=false;idxA++;}
+closeOpenSlices(nextSlice.start);result.pushSlice(nextSlice);if(isFromB){openB.push(nextSlice);}else{splitOpenSlices(nextSlice.start);openA.push(nextSlice);}}
+closeOpenSlices();return result;};return{SliceGroup:SliceGroup};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function ThreadSlice(cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id){Slice.call(this,cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bind_id);this.subSlices=[];}
+ThreadSlice.prototype={__proto__:Slice.prototype,getProcess:function(){var thread=this.parentContainer;if(thread&&thread.getProcess)
+return thread.getProcess();return undefined;}};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices',singleViewElementName:'tr-ui-a-single-thread-slice-sub-view',multiViewElementName:'tr-ui-a-multi-thread-slice-sub-view'});return{ThreadSlice:ThreadSlice};});'use strict';tr.exportTo('tr.model',function(){var AsyncSlice=tr.model.AsyncSlice;var AsyncSliceGroup=tr.model.AsyncSliceGroup;var Slice=tr.model.Slice;var SliceGroup=tr.model.SliceGroup;var ThreadSlice=tr.model.ThreadSlice;var ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent)
+throw new Error('Parent must be provided.');tr.model.EventContainer.call(this);this.parent=parent;this.sortIndex=0;this.tid=tid;this.name=undefined;this.samples_=undefined;var that=this;this.sliceGroup=new SliceGroup(this,ThreadSlice,'slices');this.timeSlices=undefined;this.kernelSliceGroup=new SliceGroup(this,ThreadSlice,'kernel-slices');this.asyncSliceGroup=new AsyncSliceGroup(this,'async-slices');}
+Thread.prototype={__proto__:tr.model.EventContainer.prototype,get model(){return this.parent.model;},get stableId(){return this.parent.stableId+'.'+this.tid;},compareTo:function(that){return Thread.compare(this,that);},iterateAllChildEventContainers:function(callback,opt_this){if(this.sliceGroup.length)
+callback.call(opt_this,this.sliceGroup);if(this.kernelSliceGroup.length)
+callback.call(opt_this,this.kernelSliceGroup);if(this.asyncSliceGroup.length)
+callback.call(opt_this,this.asyncSliceGroup);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(this.timeSlices&&this.timeSlices.length){if(eventTypePredicate.call(opt_this,ThreadTimeSlice))
+this.timeSlices.forEach(callback,opt_this);}},iterateAllPersistableObjects:function(cb){cb(this);if(this.sliceGroup.length)
+cb(this.sliceGroup);this.asyncSliceGroup.viewSubGroups.forEach(cb);},shiftTimestampsForward:function(amount){this.sliceGroup.shiftTimestampsForward(amount);if(this.timeSlices){for(var i=0;i<this.timeSlices.length;i++){var slice=this.timeSlices[i];slice.start+=amount;}}
+this.kernelSliceGroup.shiftTimestampsForward(amount);this.asyncSliceGroup.shiftTimestampsForward(amount);},get isEmpty(){if(this.sliceGroup.length)
+return false;if(this.sliceGroup.openSliceCount)
+return false;if(this.timeSlices&&this.timeSlices.length)
+return false;if(this.kernelSliceGroup.length)
+return false;if(this.asyncSliceGroup.length)
+return false;if(this.samples_.length)
+return false;return true;},updateBounds:function(){this.bounds.reset();this.sliceGroup.updateBounds();this.bounds.addRange(this.sliceGroup.bounds);this.kernelSliceGroup.updateBounds();this.bounds.addRange(this.kernelSliceGroup.bounds);this.asyncSliceGroup.updateBounds();this.bounds.addRange(this.asyncSliceGroup.bounds);if(this.timeSlices&&this.timeSlices.length){this.bounds.addValue(this.timeSlices[0].start);this.bounds.addValue(this.timeSlices[this.timeSlices.length-1].end);}
+if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.sliceGroup.length;i++)
+categoriesDict[this.sliceGroup.slices[i].category]=true;for(var i=0;i<this.kernelSliceGroup.length;i++)
+categoriesDict[this.kernelSliceGroup.slices[i].category]=true;for(var i=0;i<this.asyncSliceGroup.length;i++)
+categoriesDict[this.asyncSliceGroup.slices[i].category]=true;if(this.samples_){for(var i=0;i<this.samples_.length;i++)
+categoriesDict[this.samples_[i].category]=true;}},autoCloseOpenSlices:function(opt_maxTimestamp){this.sliceGroup.autoCloseOpenSlices(opt_maxTimestamp);this.kernelSliceGroup.autoCloseOpenSlices(opt_maxTimestamp);},mergeKernelWithUserland:function(){if(this.kernelSliceGroup.length>0){var newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices:function(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(function(sample){return sample.thread==this;},this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
+(this.name?', name: '+this.name:'');},getSettingsKey:function(){if(!this.name)
+return undefined;var parentKey=this.parent.getSettingsKey();if(!parentKey)
+return undefined;return parentKey+'.'+this.name;},getProcess:function(){return this.parent;},indexOfTimeSlice:function(timeSlice){var i=tr.b.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)
+return undefined;return i;},getCpuStatsForRange:function(range){var stats={};stats.total=0;if(!this.timeSlices)
+return stats;function addStatsForSlice(threadTimeSlice){var freqRange=tr.b.Range.fromExplicitRange(threadTimeSlice.start,threadTimeSlice.end);var intersection=freqRange.findIntersection(range);if(threadTimeSlice.schedulingState==tr.model.SCHEDULING_STATE.RUNNING){var cpu=threadTimeSlice.cpuOnWhichThreadWasRunning;if(!(cpu.cpuNumber in stats))
+stats[cpu.cpuNumber]=0;stats[cpu.cpuNumber]+=intersection.duration;stats.total+=intersection.duration;}}
+tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},range.min,range.max,addStatsForSlice);return stats;},getSchedulingStatsForRange:function(start,end){var stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){var overlapStart=Math.max(threadTimeSlice.start,start);var overlapEnd=Math.min(threadTimeSlice.end,end);var schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))
+stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
+tr.b.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},start,end,addStatsForSlice);return stats;},get samples(){return this.samples_;}};Thread.compare=function(x,y){var tmp=x.parent.compareTo(y.parent);if(tmp)
+return tmp;tmp=x.sortIndex-y.sortIndex;if(tmp)
+return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)
+return tmp;return x.tid-y.tid;};return{Thread:Thread};});'use strict';tr.exportTo('tr.model',function(){var Thread=tr.model.Thread;var Counter=tr.model.Counter;function ProcessBase(model){if(!model)
+throw new Error('Must provide a model');tr.model.EventContainer.call(this);this.model=model;this.threads={};this.counters={};this.objects=new tr.model.ObjectCollection(this);this.sortIndex=0;};ProcessBase.compare=function(x,y){return x.sortIndex-y.sortIndex;};ProcessBase.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){throw new Error('Not implemented');},iterateAllChildEventContainers:function(callback,opt_this){for(var tid in this.threads)
+callback.call(opt_this,this.threads[tid]);for(var id in this.counters)
+callback.call(opt_this,this.counters[id]);callback.call(opt_this,this.objects);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){},iterateAllPersistableObjects:function(cb){cb(this);for(var tid in this.threads)
+this.threads[tid].iterateAllPersistableObjects(cb);},get numThreads(){var n=0;for(var p in this.threads){n++;}
+return n;},shiftTimestampsForward:function(amount){this.iterateAllChildEventContainers(function(child){child.shiftTimestampsForward(amount);});},autoCloseOpenSlices:function(opt_maxTimestamp){for(var tid in this.threads){var thread=this.threads[tid];thread.autoCloseOpenSlices(opt_maxTimestamp);}},autoDeleteObjects:function(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects:function(){this.objects.preInitializeAllObjects();},initializeObjects:function(){this.objects.initializeAllObjects();},mergeKernelWithUserland:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds:function(){this.bounds.reset();for(var tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
+for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
+this.objects.updateBounds();this.bounds.addRange(this.objects.bounds);},addCategoriesToDict:function(categoriesDict){for(var tid in this.threads)
+this.threads[tid].addCategoriesToDict(categoriesDict);for(var id in this.counters)
+categoriesDict[this.counters[id].category]=true;this.objects.addCategoriesToDict(categoriesDict);},findAllThreadsMatching:function(predicate,opt_this){var threads=[];for(var tid in this.threads){var thread=this.threads[tid];if(predicate.call(opt_this,thread))
+threads.push(thread);}
+return threads;},findAllThreadsNamed:function(name){var threads=this.findAllThreadsMatching(function(thread){if(!thread.name)
+return false;return thread.name===name;});return threads;},findAtMostOneThreadNamed:function(name){var threads=this.findAllThreadsNamed(name);if(threads.length===0)
+return undefined;if(threads.length>1)
+throw new Error('Expected no more than one '+name);return threads[0];},pruneEmptyContainers:function(){var threadsToKeep={};for(var tid in this.threads){var thread=this.threads[tid];if(!thread.isEmpty)
+threadsToKeep[tid]=thread;}
+this.threads=threadsToKeep;},getThread:function(tid){return this.threads[tid];},getOrCreateThread:function(tid){if(!this.threads[tid])
+this.threads[tid]=new Thread(this,tid);return this.threads[tid];},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id])
+this.counters[id]=new Counter(this,id,cat,name);return this.counters[id];},getSettingsKey:function(){throw new Error('Not implemented');},createSubSlices:function(){for(var tid in this.threads)
+this.threads[tid].createSubSlices();}};return{ProcessBase:ProcessBase};});'use strict';tr.exportTo('tr.model',function(){var Cpu=tr.model.Cpu;var ProcessBase=tr.model.ProcessBase;function Kernel(model){ProcessBase.call(this,model);this.cpus={};this.softwareMeasuredCpuCount_=undefined;};Kernel.compare=function(x,y){return 0;};Kernel.prototype={__proto__:ProcessBase.prototype,compareTo:function(that){return Kernel.compare(this,that);},get userFriendlyName(){return'Kernel';},get userFriendlyDetails(){return'Kernel';},get stableId(){return'Kernel';},getOrCreateCpu:function(cpuNumber){if(!this.cpus[cpuNumber])
+this.cpus[cpuNumber]=new Cpu(this,cpuNumber);return this.cpus[cpuNumber];},get softwareMeasuredCpuCount(){return this.softwareMeasuredCpuCount_;},set softwareMeasuredCpuCount(softwareMeasuredCpuCount){if(this.softwareMeasuredCpuCount_!==undefined&&this.softwareMeasuredCpuCount_!==softwareMeasuredCpuCount){throw new Error('Cannot change the softwareMeasuredCpuCount once it is set');}
+this.softwareMeasuredCpuCount_=softwareMeasuredCpuCount;},get bestGuessAtCpuCount(){var realCpuCount=tr.b.dictionaryLength(this.cpus);if(realCpuCount!==0)
+return realCpuCount;return this.softwareMeasuredCpuCount;},updateBounds:function(){ProcessBase.prototype.updateBounds.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.updateBounds();this.bounds.addRange(cpu.bounds);}},createSubSlices:function(){ProcessBase.prototype.createSubSlices.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.createSubSlices();}},addCategoriesToDict:function(categoriesDict){ProcessBase.prototype.addCategoriesToDict.call(this,categoriesDict);for(var cpuNumber in this.cpus)
+this.cpus[cpuNumber].addCategoriesToDict(categoriesDict);},getSettingsKey:function(){return'kernel';},iterateAllChildEventContainers:function(callback,opt_this){ProcessBase.prototype.iterateAllChildEventContainers.call(this,callback,opt_this);for(var cpuId in this.cpus)
+callback.call(opt_this,this.cpus[cpuId]);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){ProcessBase.prototype.iterateAllEventsInThisContainer.call(this,eventTypePredicate,callback,opt_this);}};return{Kernel:Kernel};});'use strict';tr.exportTo('tr.model',function(){function ModelIndices(model){this.flowEventsById_={};model.flowEvents.forEach(function(fe){if(fe.id!==undefined){if(!this.flowEventsById_.hasOwnProperty(fe.id)){this.flowEventsById_[fe.id]=new Array();}
+this.flowEventsById_[fe.id].push(fe);}},this);}
+ModelIndices.prototype={addEventWithId:function(id,event){if(!this.flowEventsById_.hasOwnProperty(id)){this.flowEventsById_[id]=new Array();}
+this.flowEventsById_[id].push(event);},getFlowEventsWithId:function(id){if(!this.flowEventsById_.hasOwnProperty(id))
+return[];return this.flowEventsById_[id];}};return{ModelIndices:ModelIndices};});'use strict';tr.exportTo('tr.model',function(){var DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];var SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME;var EFFECTIVE_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME;function ProcessMemoryDump(globalMemoryDump,process,start){tr.model.ContainerMemoryDump.call(this,start);this.process=process;this.globalMemoryDump=globalMemoryDump;this.totals=undefined;this.vmRegions_=undefined;this.heapDumps=undefined;this.tracingMemoryDiscounted_=false;};ProcessMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Process memory dump at '+
+tr.b.u.TimeStamp.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){var dumps={};dumps[this.process.pid]=this;return dumps;},get vmRegions(){throw new Error('VM regions must be accessed through the mostRecentVmRegions field');},set vmRegions(vmRegions){this.vmRegions_=vmRegions;},get hasOwnVmRegions(){return this.vmRegions_!==undefined;},getMostRecentTotalVmRegionStat:function(statName){if(this.mostRecentVmRegions===undefined)
+return undefined;var total=0;this.mostRecentVmRegions.forEach(function(vmRegion){var statValue=vmRegion.byteStats[statName];if(statValue===undefined)
+return;total+=statValue;});return total;},discountTracingOverhead:function(opt_model){if(this.tracingMemoryDiscounted_)
+return;this.tracingMemoryDiscounted_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)
+return;function getDiscountedSize(sizeAttrName){var sizeAttr=tracingDump.getValidSizeAttributeOrUndefined(sizeAttrName,opt_model);if(sizeAttr===undefined)
+return 0;return sizeAttr.value;}
+var discountedSize=getDiscountedSize(SIZE_ATTRIBUTE_NAME);var discountedEffectiveSize=getDiscountedSize(EFFECTIVE_SIZE_ATTRIBUTE_NAME);var discountedResidentSize=getDiscountedSize('resident_size');if(discountedResidentSize>0){if(this.totals!==undefined){if(this.totals.residentBytes!==undefined)
+this.totals.residentBytes-=discountedResidentSize;if(this.totals.peakResidentBytes!==undefined)
+this.totals.peakResidentBytes-=discountedResidentSize;}
+if(this.vmRegions_!==undefined){var hasPrivateDirtyResident=false;var hasProportionalResident=false;for(var i=0;i<this.vmRegions_.length;i++){var byteStats=this.vmRegions_[i].byteStats;if(byteStats.privateDirtyResident!==undefined)
+hasPrivateDirtyResident=true;if(byteStats.proportionalResident!==undefined)
+hasProportionalResident=true;if(hasPrivateDirtyResident&&hasProportionalResident)
+break;}
+if(hasPrivateDirtyResident||hasProportionalResident){this.vmRegions_.push(VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',byteStats:{privateDirtyResident:hasPrivateDirtyResident?-discountedResidentSize:undefined,proportionalResident:hasProportionalResident?-discountedResidentSize:undefined}}));}}}
+if(discountedSize>0||discountedEffectiveSize>0){function discountSizeAndEffectiveSize(dump){var dumpSizeAttr=dump.getValidSizeAttributeOrUndefined(SIZE_ATTRIBUTE_NAME,opt_model);if(dumpSizeAttr!==undefined)
+dumpSizeAttr.value-=discountedSize;var dumpEffectiveSizeAttr=dump.getValidSizeAttributeOrUndefined(EFFECTIVE_SIZE_ATTRIBUTE_NAME,opt_model);if(dumpEffectiveSizeAttr!==undefined)
+dumpEffectiveSizeAttr.value-=discountedEffectiveSize;}
+var hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){var allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined)
+return false;discountSizeAndEffectiveSize(allocatorDump);var allocatedObjectsDumpName=allocatorName+'/allocated_objects';var allocatedObjectsDump=this.getMemoryAllocatorDumpByFullName(allocatedObjectsDumpName);if(allocatedObjectsDump===undefined)
+return true;discountSizeAndEffectiveSize(allocatedObjectsDump);var discountDumpName=allocatedObjectsDumpName+'/discounted_tracing_overhead';var discountDump=new tr.model.MemoryAllocatorDump(this,discountDumpName);discountDump.parent=allocatedObjectsDump;discountDump.addAttribute(SIZE_ATTRIBUTE_NAME,new tr.model.ScalarAttribute('bytes',-discountedSize));discountDump.addAttribute(EFFECTIVE_SIZE_ATTRIBUTE_NAME,new tr.model.ScalarAttribute('bytes',-discountedEffectiveSize));allocatedObjectsDump.children.push(discountDump);return true;},this);if(hasDiscountedFromAllocatorDumps)
+this.memoryAllocatorDumps=this.memoryAllocatorDumps;}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){var mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions_!==undefined)
+mostRecentVmRegions=processDump.vmRegions_;processDump.mostRecentVmRegions=mostRecentVmRegions;});};function VMRegion(startAddress,sizeInBytes,protectionFlags,mappedFile,byteStats){this.startAddress=startAddress;this.sizeInBytes=sizeInBytes;this.protectionFlags=protectionFlags;this.mappedFile=mappedFile;this.byteStats=byteStats;};VMRegion.PROTECTION_FLAG_READ=4;VMRegion.PROTECTION_FLAG_WRITE=2;VMRegion.PROTECTION_FLAG_EXECUTE=1;VMRegion.prototype={get protectionFlagsToString(){if(this.protectionFlags===undefined)
+return undefined;return((this.protectionFlags&VMRegion.PROTECTION_FLAG_READ?'r':'-')+
+(this.protectionFlags&VMRegion.PROTECTION_FLAG_WRITE?'w':'-')+
+(this.protectionFlags&VMRegion.PROTECTION_FLAG_EXECUTE?'x':'-'));}};VMRegion.fromDict=function(dict){return new VMRegion(dict.startAddress,dict.sizeInBytes,dict.protectionFlags,dict.mappedFile,VMRegionByteStats.fromDict(dict.byteStats));};function VMRegionByteStats(privateCleanResident,privateDirtyResident,sharedCleanResident,sharedDirtyResident,proportionalResident,swapped){this.privateCleanResident=privateCleanResident;this.privateDirtyResident=privateDirtyResident;this.sharedCleanResident=sharedCleanResident;this.sharedDirtyResident=sharedDirtyResident;this.proportionalResident=proportionalResident;this.swapped=swapped;}
+VMRegionByteStats.fromDict=function(dict){return new VMRegionByteStats(dict.privateCleanResident,dict.privateDirtyResident,dict.sharedCleanResident,dict.sharedDirtyResident,dict.proportionalResident,dict.swapped);}
+tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps',singleViewElementName:'tr-ui-a-container-memory-dump-sub-view',multiViewElementName:'tr-ui-a-container-memory-dump-sub-view'});return{ProcessMemoryDump:ProcessMemoryDump,VMRegion:VMRegion,VMRegionByteStats:VMRegionByteStats};});'use strict';tr.exportTo('tr.model',function(){var ProcessBase=tr.model.ProcessBase;var ProcessInstantEvent=tr.model.ProcessInstantEvent;var Frame=tr.model.Frame;var ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined)
+throw new Error('model must be provided');if(pid===undefined)
+throw new Error('pid must be provided');tr.model.ProcessBase.call(this,model);this.pid=pid;this.name=undefined;this.labels=[];this.instantEvents=[];this.memoryDumps=[];this.frames=[];this.activities=[];};Process.compare=function(x,y){var tmp=tr.model.ProcessBase.compare(x,y);if(tmp)
+return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)
+return tmp;tmp=tr.b.compareArrays(x.labels,y.labels,function(x,y){return x.localeCompare(y);});if(tmp)
+return tmp;return x.pid-y.pid;};Process.prototype={__proto__:tr.model.ProcessBase.prototype,get stableId(){return this.pid;},compareTo:function(that){return Process.compare(this,that);},iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){ProcessBase.prototype.iterateAllEventsInThisContainer.call(this,eventTypePredicate,callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessInstantEvent))
+this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Frame))
+this.frames.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,ProcessMemoryDump))
+this.memoryDumps.forEach(callback,opt_this);},pushInstantEvent:function(instantEvent){this.instantEvents.push(instantEvent);},addLabelIfNeeded:function(labelName){for(var i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)
+return;}
+this.labels.push(labelName);},get userFriendlyName(){var res;if(this.name)
+res=this.name+' (pid '+this.pid+')';else
+res='Process '+this.pid;if(this.labels.length)
+res+=': '+this.labels.join(', ');return res;},get userFriendlyDetails(){if(this.name)
+return this.name+' (pid '+this.pid+')';return'pid: '+this.pid;},getSettingsKey:function(){if(!this.name)
+return undefined;if(!this.labels.length)
+return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward:function(amount){for(var id in this.instantEvents)
+this.instantEvents[id].start+=amount;for(var i=0;i<this.frames.length;i++)
+this.frames[i].shiftTimestampsForward(amount);for(var i=0;i<this.memoryDumps.length;i++)
+this.memoryDumps[i].shiftTimestampsForward(amount);for(var i=0;i<this.activities.length;i++)
+this.activities[i].shiftTimestampsForward(amount);tr.model.ProcessBase.prototype.shiftTimestampsForward.apply(this,arguments);},updateBounds:function(){tr.model.ProcessBase.prototype.updateBounds.apply(this);for(var i=0;i<this.frames.length;i++)
+this.frames[i].addBoundsToRange(this.bounds);for(var i=0;i<this.memoryDumps.length;i++)
+this.memoryDumps[i].addBoundsToRange(this.bounds);for(var i=0;i<this.activities.length;i++)
+this.activities[i].addBoundsToRange(this.bounds);},sortMemoryDumps:function(){this.memoryDumps.sort(function(x,y){return x.start-y.start;});tr.model.ProcessMemoryDump.hookUpMostRecentVmRegionsLinks(this.memoryDumps);}};return{Process:Process};});'use strict';tr.exportTo('tr.model',function(){function Sample(cpu,thread,title,start,leafStackFrame,opt_weight,opt_args){tr.model.TimedEvent.call(this,start);this.title=title;this.cpu=cpu;this.thread=thread;this.leafStackFrame=leafStackFrame;this.weight=opt_weight;this.args=opt_args||{};}
+Sample.prototype={__proto__:tr.model.TimedEvent.prototype,get colorId(){return this.leafStackFrame.colorId;},get stackTrace(){return this.leafStackFrame.stackTrace;},getUserFriendlyStackTrace:function(){return this.leafStackFrame.getUserFriendlyStackTrace();},get userFriendlyName(){return'Sample at '+tr.b.u.TimeStamp.format(this.start);}};tr.model.EventRegistry.register(Sample,{name:'sample',pluralName:'samples',singleViewElementName:'tr-ui-a-single-sample-sub-view',multiViewElementName:'tr-ui-a-multi-sample-sub-view'});return{Sample:Sample};});'use strict';tr.exportTo('tr.model',function(){function StackFrame(parentFrame,id,title,colorId,opt_sourceInfo){if(id===undefined)
+throw new Error('id must be given');this.parentFrame_=parentFrame;this.id=id;this.title_=title;this.colorId=colorId;this.children=[];this.sourceInfo_=opt_sourceInfo;if(this.parentFrame_)
+this.parentFrame_.addChild(this);}
+StackFrame.prototype={get parentFrame(){return this.parentFrame_;},get title(){if(this.sourceInfo_){var src=this.sourceInfo_.toString();return this.title_+(src===''?'':' '+src);}
+return this.title_;},get domain(){var result='unknown';if(this.sourceInfo_&&this.sourceInfo_.domain)
+result=this.sourceInfo_.domain;if(result==='unknown'&&this.parentFrame)
+result=this.parentFrame.domain;return result;},get sourceInfo(){return this.sourceInfo_;},set parentFrame(parentFrame){if(this.parentFrame_)
+this.parentFrame_.removeChild(this);this.parentFrame_=parentFrame;if(this.parentFrame_)
+this.parentFrame_.addChild(this);},addChild:function(child){this.children.push(child);},removeChild:function(child){var i=this.children.indexOf(child.id);if(i==-1)
+throw new Error('omg');this.children.splice(i,1);},removeAllChildren:function(){for(var i=0;i<this.children.length;i++)
+this.children[i].parentFrame_=undefined;this.children.splice(0,this.children.length);},get stackTrace(){var stack=[];var cur=this;while(cur){stack.push(cur);cur=cur.parentFrame;}
+return stack;},getUserFriendlyStackTrace:function(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame:StackFrame};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){var elements;if(typeof source=='string')
+elements=tr.doc.querySelectorAll(source);else
+elements=[source];for(var i=0,el;el=elements[i];i++){if(!(el instanceof constr))
+constr.decorate(el);}}
+function define(className,opt_parentConstructor,opt_tagNS){if(typeof className=='function'){throw new Error('Passing functions as className is deprecated. Please '+'use (className, opt_parentConstructor) to subclass');}
+var className=className.toLowerCase();if(opt_parentConstructor&&!opt_parentConstructor.tagName)
+throw new Error('opt_parentConstructor was not '+'created by tr.ui.b.define');var tagName=className;var tagNS=undefined;if(opt_parentConstructor){if(opt_tagNS)
+throw new Error('Must not specify tagNS if parentConstructor is given');var parent=opt_parentConstructor;while(parent&&parent.tagName){tagName=parent.tagName;tagNS=parent.tagNS;parent=parent.parentConstructor;}}else{tagNS=opt_tagNS;}
+function f(){if(opt_parentConstructor&&f.prototype.__proto__!=opt_parentConstructor.prototype){throw new Error(className+' prototye\'s __proto__ field is messed up. '+'It MUST be the prototype of '+opt_parentConstructor.tagName);}
+var el;if(tagNS===undefined)
+el=tr.doc.createElement(tagName);else
+el=tr.doc.createElementNS(tagNS,tagName);f.decorate.call(this,el,arguments);return el;}
+f.decorate=function(el){el.__proto__=f.prototype;el.decorate.apply(el,arguments[1]);el.constructor=f;};f.className=className;f.tagName=tagName;f.tagNS=tagNS;f.parentConstructor=(opt_parentConstructor?opt_parentConstructor:undefined);f.toString=function(){if(!f.parentConstructor)
+return f.tagName;return f.parentConstructor.toString()+'::'+f.className;};return f;}
+function elementIsChildOf(el,potentialParent){if(el==potentialParent)
+return false;var cur=el;while(cur.parentNode){if(cur==potentialParent)
+return true;cur=cur.parentNode;}
+return false;};return{decorate:decorate,define:define,elementIsChildOf:elementIsChildOf};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';tr.exportTo('tr.b',function(){function clamp(x,lo,hi){return Math.min(Math.max(x,lo),hi);}
+function lerp(percentage,lo,hi){var range=hi-lo;return lo+percentage*range;}
+function normalize(value,lo,hi){return(value-lo)/(hi-lo);}
+function deg2rad(deg){return(Math.PI*deg)/180.0;}
+var tmp_vec2=vec2.create();var tmp_vec2b=vec2.create();var tmp_vec4=vec4.create();var tmp_mat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!=2)
+throw new Error('Should be length 2');var v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){var v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmp_vec2,u1,scale1);vec2.scale(tmp_vec2b,u2,scale2);vec2.add(out,tmp_vec2,tmp_vec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])
+return points[0][1];for(var i=1;i<points.length;++i){if(x<points[i][0]){var percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
+return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){var v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';}
+mat2d.translateXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.translate(out,out,tmp_vec2);}
+mat2d.scaleXY=function(out,x,y){vec2.set(tmp_vec2,x,y);mat2d.scale(out,out,tmp_vec2);}
+vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;}
+vec2.copyFromVec4=function(out,a){vec4.unitize(tmp_vec4,a);vec2.copy(out,tmp_vec4);}
+return{clamp:clamp,lerp:lerp,normalize:normalize,deg2rad:deg2rad};});'use strict';tr.exportTo('tr.b',function(){function Rect(){this.x=0;this.y=0;this.width=0;this.height=0;};Rect.fromXYWH=function(x,y,w,h){var rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;}
+Rect.fromArray=function(ary){if(ary.length!=4)
+throw new Error('ary.length must be 4');var rect=new Rect();rect.x=ary[0];rect.y=ary[1];rect.width=ary[2];rect.height=ary[3];return rect;}
+Rect.prototype={__proto__:Object.prototype,get left(){return this.x;},get top(){return this.y;},get right(){return this.x+this.width;},get bottom(){return this.y+this.height;},toString:function(){return'Rect('+this.x+', '+this.y+', '+
+this.width+', '+this.height+')';},toArray:function(){return[this.x,this.y,this.width,this.height];},clone:function(){var rect=new Rect();rect.x=this.x;rect.y=this.y;rect.width=this.width;rect.height=this.height;return rect;},enlarge:function(pad){var rect=new Rect();this.enlargeFast(rect,pad);return rect;},enlargeFast:function(out,pad){out.x=this.x-pad;out.y=this.y-pad;out.width=this.width+2*pad;out.height=this.height+2*pad;return out;},size:function(){return{width:this.width,height:this.height};},scale:function(s){var rect=new Rect();this.scaleFast(rect,s);return rect;},scaleSize:function(s){return Rect.fromXYWH(this.x,this.y,this.width*s,this.height*s);},scaleFast:function(out,s){out.x=this.x*s;out.y=this.y*s;out.width=this.width*s;out.height=this.height*s;return out;},translate:function(v){var rect=new Rect();this.translateFast(rect,v);return rect;},translateFast:function(out,v){out.x=this.x+v[0];out.y=this.x+v[1];out.width=this.width;out.height=this.height;return out;},asUVRectInside:function(containingRect){var rect=new Rect();rect.x=(this.x-containingRect.x)/containingRect.width;rect.y=(this.y-containingRect.y)/containingRect.height;rect.width=this.width/containingRect.width;rect.height=this.height/containingRect.height;return rect;},intersects:function(that){var ok=true;ok&=this.x<that.right;ok&=this.right>that.x;ok&=this.y<that.bottom;ok&=this.bottom>that.y;return ok;},equalTo:function(rect){return rect&&(this.x===rect.x)&&(this.y===rect.y)&&(this.width===rect.width)&&(this.height===rect.height);}};return{Rect:Rect};});'use strict';tr.exportTo('tr.ui.b',function(){function instantiateTemplate(selector,doc){doc=doc||document;var el=doc.querySelector(selector);if(!el)
+throw new Error('Element not found');return el.createInstance();}
+function windowRectForElement(element){var position=[element.offsetLeft,element.offsetTop];var size=[element.offsetWidth,element.offsetHeight];var node=element.offsetParent;while(node){position[0]+=node.offsetLeft;position[1]+=node.offsetTop;node=node.offsetParent;}
+return tr.b.Rect.fromXYWH(position[0],position[1],size[0],size[1]);}
+function scrollIntoViewIfNeeded(el){var pr=el.parentElement.getBoundingClientRect();var cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
+return{instantiateTemplate:instantiateTemplate,windowRectForElement:windowRectForElement,scrollIntoViewIfNeeded:scrollIntoViewIfNeeded};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)
+return{};var THIS_DOC=document.currentScript.ownerDocument;var Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);var createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);this.shadow_.appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=this.shadow_.querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);this.shadow_.querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new WebKitMutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(this.shadow_.querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get:function(){return this.shadow_.querySelector('title').textContent;},set:function(title){this.shadow_.querySelector('title').textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return this.shadow_.querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)
+return;this.visible_=newValue;var e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_:function(){this.visible_?this.show_():this.hide_();},show_:function(){this.parentEl_.appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));}
+this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;var focusEl=undefined;var elList=this.querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)
+focusEl=elList[1];}else{focusEl=elList[0];}}
+if(focusEl===undefined)
+focusEl=this;focusEl.focus();},hide_:function(){this.parentEl_.removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_)
+this.closeBtn_.removeEventListener(this.onClose_);document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_:function(e){this.visible=false;if((e.type!='keydown')||(e.type==='keydown'&&e.keyCode===27))
+e.stopPropagation();e.preventDefault();tr.b.dispatchSimpleEvent(this,'closeclick');},onFocusIn_:function(e){if(e.target===this)
+return;window.setTimeout(function(){this.focus();},0);e.preventDefault();e.stopPropagation();},didButtonBarMutate_:function(e){var hasButtons=this.buttons.children.length>0;if(hasButtons)
+this.shadow_.querySelector('button-bar').style.display=undefined;else
+this.shadow_.querySelector('button-bar').style.display='none';},onKeyDown_:function(e){if(e.keyCode===9&&e.shiftKey&&e.target===this){e.preventDefault();return;}
+if(e.keyCode!==27)
+return;this.onClose_(e);},onClick_:function(e){e.stopPropagation();},onDocumentClick_:function(e){if(!this.userCanClose_)
+return;this.onClose_(e);}};Overlay.showError=function(msg,opt_err){var o=new Overlay();o.title='Error';o.textContent=msg;if(opt_err){var e=tr.b.normalizeException(opt_err);var stackDiv=document.createElement('pre');stackDiv.textContent=e.stack;stackDiv.style.paddingLeft='8px';stackDiv.style.margin=0;o.appendChild(stackDiv);}
+var b=document.createElement('button');b.textContent='OK';b.addEventListener('click',function(){o.visible=false;});o.buttons.appendChild(b);o.visible=true;return o;}
+return{Overlay:Overlay};});'use strict';tr.exportTo('tr',function(){var Process=tr.model.Process;var Device=tr.model.Device;var Kernel=tr.model.Kernel;var GlobalMemoryDump=tr.model.GlobalMemoryDump;var GlobalInstantEvent=tr.model.GlobalInstantEvent;var FlowEvent=tr.model.FlowEvent;var Alert=tr.model.Alert;var InteractionRecord=tr.model.InteractionRecord;var Sample=tr.model.Sample;function ClockSyncRecord(name,ts,args){this.name=name;this.ts=ts;this.args=args;}
+function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncRecords=[];this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.interactionRecords=[];this.flowIntervalTree=new tr.b.IntervalTree(function(f){return f.start;},function(f){return f.end;});this.globalMemoryDumps=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.importWarnings_=[];this.reportedImportWarnings_={};}
+Model.prototype={__proto__:tr.model.EventContainer.prototype,iterateAllEventsInThisContainer:function(eventTypePredicate,callback,opt_this){if(eventTypePredicate.call(opt_this,GlobalMemoryDump))
+this.globalMemoryDumps.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,GlobalInstantEvent))
+this.instantEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,FlowEvent))
+this.flowEvents.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Alert))
+this.alerts.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,InteractionRecord))
+this.interactionRecords.forEach(callback,opt_this);if(eventTypePredicate.call(opt_this,Sample))
+this.samples.forEach(callback,opt_this);},iterateAllChildEventContainers:function(callback,opt_this){callback.call(opt_this,this.device);callback.call(opt_this,this.kernel);for(var pid in this.processes)
+callback.call(opt_this,this.processes[pid]);},iterateAllPersistableObjects:function(callback){this.kernel.iterateAllPersistableObjects(callback);for(var pid in this.processes)
+this.processes[pid].iterateAllPersistableObjects(callback);},updateBounds:function(){this.bounds.reset();var bounds=this.bounds;this.iterateAllChildEventContainers(function(ec){ec.updateBounds();bounds.addRange(ec.bounds);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.addBoundsToRange(bounds);});},shiftWorldToZero:function(){var shiftAmount=-this.bounds.min;this.timestampShiftToZeroAmount_=shiftAmount;this.iterateAllChildEventContainers(function(ec){ec.shiftTimestampsForward(shiftAmount);});this.iterateAllEventsInThisContainer(function(eventConstructor){return true;},function(event){event.start+=shiftAmount;});this.updateBounds();},convertTimestampToModelTime:function(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock')
+throw new Error('Only traceEventClock is supported.');return tr.b.u.Units.timestampFromUs(ts)+
+this.timestampShiftToZeroAmount_;},get numProcesses(){var n=0;for(var p in this.processes)
+n++;return n;},getProcess:function(pid){return this.processes[pid];},getOrCreateProcess:function(pid){if(!this.processes[pid])
+this.processes[pid]=new Process(this,pid);return this.processes[pid];},pushInstantEvent:function(instantEvent){this.instantEvents.push(instantEvent);},addStackFrame:function(stackFrame){if(this.stackFrames[stackFrame.id])
+throw new Error('Stack frame already exists');this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},addInteractionRecord:function(ir){this.interactionRecords.push(ir);return ir;},getClockSyncRecordsNamed:function(name){return this.clockSyncRecords.filter(function(x){return x.name===name;});},updateCategories_:function(){var categoriesDict={};this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(var pid in this.processes)
+this.processes[pid].addCategoriesToDict(categoriesDict);this.categories=[];for(var category in categoriesDict)
+if(category!='')
+this.categories.push(category);},getAllThreads:function(){var threads=[];for(var tid in this.kernel.threads){threads.push(process.threads[tid]);}
+for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.threads){threads.push(process.threads[tid]);}}
+return threads;},getAllProcesses:function(){var processes=[];for(var pid in this.processes)
+processes.push(this.processes[pid]);return processes;},getAllCounters:function(){var counters=[];counters.push.apply(counters,tr.b.dictionaryValues(this.device.counters));counters.push.apply(counters,tr.b.dictionaryValues(this.kernel.counters));for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.counters){counters.push(process.counters[tid]);}}
+return counters;},getAnnotationByGUID:function(guid){return this.annotationsByGuid_[guid];},addAnnotation:function(annotation){if(!annotation.guid)
+throw new Error('Annotation with undefined guid given');this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation:function(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations:function(){return tr.b.dictionaryValues(this.annotationsByGuid_);},findAllThreadsNamed:function(name){var namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(var pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
+return namedThreads;},set importOptions(options){this.importOptions_=options;},get intrinsicTimeUnit(){if(this.intrinsicTimeUnit_===undefined)
+return tr.b.u.TimeDisplayModes.ms;return this.intrinsicTimeUnit_;},set intrinsicTimeUnit(value){if(this.intrinsicTimeUnit_===value)
+return;if(this.intrinsicTimeUnit_!==undefined)
+throw new Error('Intrinsic time unit already set');this.intrinsicTimeUnit_=value;},importWarning:function(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)
+return;if(this.importOptions_.showImportWarnings)
+console.warn(data.message);this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices:function(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices(this.bounds.max);for(var pid in this.processes)
+this.processes[pid].autoCloseOpenSlices(this.bounds.max);},createSubSlices:function(){this.kernel.createSubSlices();for(var pid in this.processes)
+this.processes[pid].createSubSlices();},preInitializeObjects:function(){for(var pid in this.processes)
+this.processes[pid].preInitializeObjects();},initializeObjects:function(){for(var pid in this.processes)
+this.processes[pid].initializeObjects();},pruneEmptyContainers:function(){this.kernel.pruneEmptyContainers();for(var pid in this.processes)
+this.processes[pid].pruneEmptyContainers();},mergeKernelWithUserland:function(){for(var pid in this.processes)
+this.processes[pid].mergeKernelWithUserland();},computeWorldBounds:function(shiftWorldToZero){this.updateBounds();this.updateCategories_();if(shiftWorldToZero)
+this.shiftWorldToZero();},buildFlowEventIntervalTree:function(){for(var i=0;i<this.flowEvents.length;++i){var flowEvent=this.flowEvents[i];this.flowIntervalTree.insert(flowEvent);}
+this.flowIntervalTree.updateHighValues();},cleanupUndeletedObjects:function(){for(var pid in this.processes)
+this.processes[pid].autoDeleteObjects(this.bounds.max);},sortMemoryDumps:function(){this.globalMemoryDumps.sort(function(x,y){return x.start-y.start;});for(var pid in this.processes)
+this.processes[pid].sortMemoryDumps();},calculateMemoryGraphAttributes:function(){this.globalMemoryDumps.forEach(function(dump){dump.calculateGraphAttributes();});},buildEventIndices:function(){this.modelIndices=new tr.model.ModelIndices(this);},sortInteractionRecords:function(){this.interactionRecords.sort(function(x,y){return x.start-y.start;});},sortAlerts:function(){this.alerts.sort(function(x,y){return x.start-y.start;});}};return{ClockSyncRecord:ClockSyncRecord,Model:Model};});'use strict';tr.exportTo('tr.importer',function(){function EmptyImporter(events){this.importPriority=0;};EmptyImporter.canImport=function(eventData){if(eventData instanceof Array&&eventData.length==0)
+return true;if(typeof(eventData)==='string'||eventData instanceof String){return eventData.length==0;}
+return false;};EmptyImporter.prototype={__proto__:tr.importer.Importer.prototype};tr.importer.Importer.register(EmptyImporter);return{EmptyImporter:EmptyImporter};});'use strict';tr.exportTo('tr.importer',function(){function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.customizeModelCallback=undefined;var auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
+function Import(model,opt_options){if(model===undefined)
+throw new Error('Must provide model to import into.');this.importing_=false;this.importOptions_=opt_options||new ImportOptions();this.model_=model;this.model_.importOptions=this.importOptions_;}
+Import.prototype={__proto__:Object.prototype,importTraces:function(traces){var progressMeter={update:function(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog:function(traces){if(tr.isHeadless)
+throw new Error('Cannot use this method in headless mode.');var overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');overlay.appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){this.msgEl.textContent=msg;}
+overlay.visible=true;var promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask:function(progressMeter,traces){if(this.importing_)
+throw new Error('Already importing.');this.importing_=true;var importTask=new tr.b.Task(function(){progressMeter.update('I will now import your traces for you...');},this);var lastTask=importTask;var importers=[];lastTask=lastTask.after(function(){traces=traces.slice(0);progressMeter.update('Creating importers...');for(var i=0;i<traces.length;++i)
+importers.push(this.createImporter_(traces[i]));for(var i=0;i<importers.length;i++){var subtraces=importers[i].extractSubtraces();for(var j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){console.warn(error.name+': '+error.message);continue;}}}
+if(traces.length&&!this.hasEventDataDecoder_(importers)){throw new Error('Could not find an importer for the provided eventData.');}
+importers.sort(function(x,y){return x.importPriority-y.importPriority;});},this);lastTask=lastTask.after(function(task){importers.forEach(function(importer,index){task.subTask(function(){progressMeter.update('Importing '+(index+1)+' of '+importers.length);importer.importEvents();},this);},this);},this);if(this.importOptions_.customizeModelCallback){lastTask=lastTask.after(function(task){this.importOptions_.customizeModelCallback(this.model_);},this);}
+lastTask=lastTask.after(function(task){importers.forEach(function(importer,index){progressMeter.update('Importing sample data '+(index+1)+'/'+importers.length);importer.importSampleData();},this);},this);lastTask=lastTask.after(function(){progressMeter.update('Autoclosing open slices...');this.model_.autoCloseOpenSlices();this.model_.createSubSlices();},this);lastTask=lastTask.after(function(task){importers.forEach(function(importer,index){progressMeter.update('Finalizing import '+(index+1)+'/'+importers.length);importer.finalizeImport();},this);},this);lastTask=lastTask.after(function(){progressMeter.update('Initializing objects (step 1/2)...');this.model_.preInitializeObjects();},this);if(this.importOptions_.pruneEmptyContainers){lastTask=lastTask.after(function(){progressMeter.update('Pruning empty containers...');this.model_.pruneEmptyContainers();},this);}
+lastTask=lastTask.after(function(){progressMeter.update('Merging kernel with userland...');this.model_.mergeKernelWithUserland();},this);var auditors=[];lastTask=lastTask.after(function(){progressMeter.update('Adding arbitrary data to model...');auditors=this.importOptions_.auditorConstructors.map(function(auditorConstructor){return new auditorConstructor(this.model_);},this);auditors.forEach(function(auditor){auditor.runAnnotate();});},this);lastTask=lastTask.after(function(){progressMeter.update('Computing final world bounds...');this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);},this);lastTask=lastTask.after(function(){progressMeter.update('Building flow event map...');this.model_.buildFlowEventIntervalTree();},this);lastTask=lastTask.after(function(){progressMeter.update('Joining object refs...');for(var i=0;i<importers.length;i++)
+importers[i].joinRefs();},this);lastTask=lastTask.after(function(){progressMeter.update('Cleaning up undeleted objects...');this.model_.cleanupUndeletedObjects();},this);lastTask=lastTask.after(function(){progressMeter.update('Sorting memory dumps...');this.model_.sortMemoryDumps();},this);lastTask=lastTask.after(function(){progressMeter.update('Calculating memory dump graph attributes...');this.model_.calculateMemoryGraphAttributes();},this);lastTask=lastTask.after(function(){progressMeter.update('Initializing objects (step 2/2)...');this.model_.initializeObjects();},this);lastTask=lastTask.after(function(){progressMeter.update('Building flow event indices...');this.model_.buildEventIndices();},this);lastTask=lastTask.after(function(){progressMeter.update('Running auditors...');auditors.forEach(function(auditor){auditor.runAudit();});},this);lastTask=lastTask.after(function(){progressMeter.update('Updating interaction records...');this.model_.sortInteractionRecords();},this);lastTask=lastTask.after(function(){progressMeter.update('Updating alerts...');this.model_.sortAlerts();},this);lastTask=lastTask.after(function(){progressMeter.update('Update bounds...');this.model_.updateBounds();},this);lastTask.after(function(){this.importing_=false;},this);return importTask;},createImporter_:function(eventData){var importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
+return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_:function(importers){if(importers.length===0)
+return false;for(var i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())
+return true;}
+return false;}};return{ImportOptions:ImportOptions,Import:Import};});'use strict';tr.exportTo('tr.importer',function(){function SimpleLineReader(text){this.lines_=text.split('\n');this.curLine_=0;this.savedLines_=undefined;}
+SimpleLineReader.prototype={advanceToLineMatching:function(regex){for(;this.curLine_<this.lines_.length;this.curLine_++){var line=this.lines_[this.curLine_];if(this.savedLines_!==undefined)
+this.savedLines_.push(line);if(regex.test(line))
+return true;}
+return false;},get curLineNumber(){return this.curLine_;},beginSavingLines:function(){this.savedLines_=[];},endSavingLinesAndGetResult:function(){var tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}};return{SimpleLineReader:SimpleLineReader};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;};Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity:Activity};});'use strict';tr.exportTo('tr.e.importer.android',function(){var Importer=tr.importer.Importer;var ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};var activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
+var eventLogActivityRE=new RegExp('(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)'+'\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*'+'(am_\\w+)\\s*:(.*)');var amCreateRE=new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]');var amFocusedRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amProcStartRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]');var amOnResumeRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amOnPauseRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amLaunchTimeRE=new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)');var amDestroyRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]');EventLogImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
+return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get model(){return this.model_;},getFullActivityName:function(component){var componentSplit=component.split('/');if(componentSplit[1].startsWith('.'))
+return componentSplit[0]+componentSplit[1];return componentSplit[1];},getProcName:function(component){var componentSplit=component.split('/');return componentSplit[0];},findOrCreateActivity:function(activityName){if(activityName in activityMap)
+return activityMap[activityName];var activity={state:ACTIVITY_STATE.NONE,name:activityName};activityMap[activityName]=activity;return activity;},deleteActivity:function(activityName){delete activityMap[activityName];},handleCreateActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.CREATED;activity.createdTs=ts;},handleFocusActivity:function(ts,procName,activityName){var activity=this.findOrCreateActivity(activityName);activity.lastFocusedTs=ts;},handleProcStartForActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.procStartTs=ts;},handleOnResumeCalled:function(ts,pid,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.RESUMED;activity.lastResumeTs=ts;activity.pid=pid;},handleOnPauseCalled:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.PAUSED;activity.lastPauseTs=ts;if(ts>this.model_.bounds.min&&ts<this.model_.bounds.max)
+this.addActivityToProcess(activity);},handleLaunchTime:function(ts,activityName,launchTime){var activity=this.findOrCreateActivity(activityName);activity.launchTime=launchTime;},handleDestroyActivity:function(ts,activityName){this.deleteActivity(activityName);},addActivityToProcess:function(activity){if(activity.pid===undefined)
+return;var process=this.model_.getOrCreateProcess(activity.pid);var range=tr.b.Range.fromExplicitRange(Math.max(this.model_.bounds.min,activity.lastResumeTs),activity.lastPauseTs);var newActivity=new tr.model.Activity(activity.name,'Android Activity',range,{created:activity.createdTs,procstart:activity.procStartTs,lastfocus:activity.lastFocusedTs});process.activities.push(newActivity);},parseAmLine_:function(line){var match=eventLogActivityRE.exec(line);if(!match)
+return;var first_realtime_ts=this.model_.bounds.min-
+this.model_.realtime_to_monotonic_offset_ms;var year=new Date(first_realtime_ts).getFullYear();var ts=match[1].substring(0,5)+'-'+year+' '+
+match[1].substring(5,match[1].length);var monotonic_ts=Date.parse(ts)+
+this.model_.realtime_to_monotonic_offset_ms;var pid=match[2];var action=match[5];var data=match[6];if(action==='am_create_activity'){match=amCreateRE.exec(data);if(match&&match.length>=2){this.handleCreateActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_focused_activity'){match=amFocusedRE.exec(data);if(match&&match.length>=2){this.handleFocusActivity(monotonic_ts,this.getProcName(match[1]),this.getFullActivityName(match[1]));}}else if(action==='am_proc_start'){match=amProcStartRE.exec(data);if(match&&match.length>=2){this.handleProcStartForActivity(monotonic_ts,this.getFullActivityName(match[1]));}}else if(action==='am_on_resume_called'){match=amOnResumeRE.exec(data);if(match&&match.length>=2)
+this.handleOnResumeCalled(monotonic_ts,pid,match[1]);}else if(action==='am_on_paused_called'){match=amOnPauseRE.exec(data);if(match&&match.length>=2)
+this.handleOnPauseCalled(monotonic_ts,match[1]);}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonic_ts,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length==2){this.handleDestroyActivity(monotonic_ts,this.getFullActivityName(match[1]));}}},importEvents:function(isSecondaryImport){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
+this.model_.updateBounds();var lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(var activityName in activityMap){var activity=activityMap[activityName];if(activity.state==ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter:EventLogImporter};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.sampleRate_=undefined;this.model_=model;this.events_=events;}
+var TestExports={};var battorDataLineRE=/^(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)$/;var battorHeaderLineRE=/^# BattOr/;var sampleRateLineRE=/^# sample_rate=(\d+)Hz/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
+return false;return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},importEvents:function(isSecondaryImport){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
+var name='power';var series=new tr.model.PowerSeries(this.model_.device);this.importPowerSamples(series);var syncMarks=this.model_.getClockSyncRecordsNamed('battor');if(syncMarks.length<1){this.model_.importWarning({type:'clock_sync',message:'Cannot import BattOr power trace without a sync signal.'});return;}
+var shiftTs=this.correlationClockSync(syncMarks,series);if(shiftTs===undefined){this.model_.importWarning({type:'clock_sync',message:'All of the BattOr power trace clock sync techinques failed.'});return;}
+series.shiftTimestampsForward(shiftTs);this.model_.device.powerSeries=series;},importPowerSamples:function(series){var lines=this.events_.split('\n');this.model_.updateBounds();var minTs=0;if(this.model_.bounds.min!==undefined)
+minTs=this.model_.bounds.min;lines.forEach(function(line){line=line.trim();if(line.length===0)
+return;if(/^#/.test(line)){groups=sampleRateLineRE.exec(line);if(!groups)
+return;this.sampleRate_=parseInt(groups[1]);}else{var groups=battorDataLineRE.exec(line);if(!groups){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});return;}
+var time=parseFloat(groups[1])+minTs;var voltage_mV=parseFloat(groups[2]);var current_mA=parseFloat(groups[3]);series.addPowerSample(time,(voltage_mV*current_mA)/1000);}},this);},correlationClockSync:function(syncMarks,series){var syncCtr=this.model_.kernel.counters['null.vreg '+syncMarks[0].args['regulator']+' enabled'];if(syncCtr===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot correlate BattOr power trace without sync vreg.'});return undefined;}
+var syncEvents=[];var firstSyncEventTs=undefined;syncCtr.series[0].iterateAllEvents(function(event){if(event.timestamp>=syncMarks[0].ts&&event.timestamp<=syncMarks[1].ts){if(firstSyncEventTs===undefined)
+firstSyncEventTs=event.timestamp;var newEvent={'ts':(event.timestamp-firstSyncEventTs)/1000,'val':event.value};syncEvents.push(newEvent);}});var syncSamples=[];var syncNumSamples=Math.ceil(syncEvents[syncEvents.length-1].ts*this.sampleRate_);for(var i=1;i<syncEvents.length;i++){var sampleStartIdx=Math.ceil(syncEvents[i-1].ts*this.sampleRate_);var sampleEndIdx=Math.ceil(syncEvents[i].ts*this.sampleRate_);for(var j=sampleStartIdx;j<sampleEndIdx;j++){syncSamples[j]=syncEvents[i-1].val;}}
+var powerSamples=series.samples;if(powerSamples.length<syncSamples.length){this.model_.importWarning({type:'not_enough_samples',message:'Not enough power samples to correlate with sync signal.'});return undefined;}
+var maxShift=powerSamples.length-syncSamples.length;var minShift=0;var corrNumSamples=this.sampleRate_*5.0;if(powerSamples.length>corrNumSamples)
+minShift=powerSamples.length-corrNumSamples;var corr=[];for(var shift=minShift;shift<=maxShift;shift++){var corrSum=0;var powerAvg=0;for(var i=0;i<syncSamples.length;i++){corrSum+=(powerSamples[i+shift].power*syncSamples[i]);powerAvg+=powerSamples[i+shift].power;}
+powerAvg=powerAvg/syncSamples.length;corr.push(corrSum/powerAvg);}
+var corrPeakIdx=0;var corrPeak=0;for(var i=0;i<powerSamples.length;i++){if(corr[i]>corrPeak){corrPeak=corr[i];corrPeakIdx=i;}}
+var corrPeakTs=((minShift+corrPeakIdx)/this.sampleRate_);corrPeakTs*=1000;var syncStartTs=firstSyncEventTs-this.model_.bounds.min;var shiftTs=syncStartTs-corrPeakTs;return shiftTs;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter:BattorImporter,_BattorImporterTestExports:TestExports};});!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isHeadless){global.window={};}'use strict';if(tr.isHeadless){global.JSZip=global.window.JSZip;global.window=undefined;}'use strict';tr.exportTo('tr.e.importer.ddms',function(){var kPid=0;var kCategory='java';var kMethodLutEndMarker='\n*end\n';var kThreadsStart='\n*threads\n';var kMethodsStart='\n*methods\n';var kTraceMethodEnter=0x00;var kTraceMethodExit=0x01;var kTraceUnroll=0x02;var kTraceMethodActionMask=0x03;var kTraceHeaderLength=32;var kTraceMagicValue=0x574f4c53;var kTraceVersionSingleClock=2;var kTraceVersionDualClock=3;var kTraceRecordSizeSingleClock=10;var kTraceRecordSizeDualClock=14;function Reader(string_payload){this.position_=0;this.data_=JSZip.utils.transformTo('uint8array',string_payload);}
+Reader.prototype={__proto__:Object.prototype,uint8:function(){var result=this.data_[this.position_];this.position_+=1;return result;},uint16:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;return result;},uint32:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;result+=this.uint8()<<16;result+=this.uint8()<<24;return result;},uint64:function(){var low=this.uint32();var high=this.uint32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},seekTo:function(position){this.position_=position;},hasMore:function(){return this.position_<this.data_.length;}};function DdmsImporter(model,data){this.importPriority=3;this.model_=model;this.data_=data;}
+DdmsImporter.canImport=function(data){if(typeof(data)==='string'||data instanceof String){var header=data.slice(0,1000);return header.startsWith('*version\n')&&header.indexOf('\nvm=')>=0&&header.indexOf(kThreadsStart)>=0;}
+return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},importEvents:function(isSecondaryImport){var divider=this.data_.indexOf(kMethodLutEndMarker)+
+kMethodLutEndMarker.length;this.metadata_=this.data_.slice(0,divider);this.methods_={};this.parseThreads();this.parseMethods();var traceReader=new Reader(this.data_.slice(divider));var magic=traceReader.uint32();if(magic!=kTraceMagicValue){throw Error('Failed to match magic value');}
+this.version_=traceReader.uint16();if(this.version_!=kTraceVersionDualClock){throw Error('Unknown version');}
+var dataOffest=traceReader.uint16();var startDateTime=traceReader.uint64();var recordSize=traceReader.uint16();traceReader.seekTo(dataOffest);while(traceReader.hasMore()){this.parseTraceEntry(traceReader);}},parseTraceEntry:function(reader){var tid=reader.uint16();var methodPacked=reader.uint32();var cpuSinceStart=reader.uint32();var wallClockSinceStart=reader.uint32();var method=methodPacked&~kTraceMethodActionMask;var action=methodPacked&kTraceMethodActionMask;var thread=this.getTid(tid);method=this.getMethodName(method);if(action==kTraceMethodEnter){thread.sliceGroup.beginSlice(kCategory,method,wallClockSinceStart,undefined,cpuSinceStart);}else if(thread.sliceGroup.openSliceCount){thread.sliceGroup.endSlice(wallClockSinceStart,cpuSinceStart);}},parseThreads:function(){var threads=this.metadata_.slice(this.metadata_.indexOf(kThreadsStart)+
+kThreadsStart.length);threads=threads.slice(0,threads.indexOf('\n*'));threads=threads.split('\n');threads.forEach(this.parseThread.bind(this));},parseThread:function(thread_line){var tid=thread_line.slice(0,thread_line.indexOf('\t'));var thread=this.getTid(parseInt(tid));thread.name=thread_line.slice(thread_line.indexOf('\t')+1);},getTid:function(tid){return this.model_.getOrCreateProcess(kPid).getOrCreateThread(tid);},parseMethods:function(){var methods=this.metadata_.slice(this.metadata_.indexOf(kMethodsStart)+
+kMethodsStart.length);methods=methods.slice(0,methods.indexOf('\n*'));methods=methods.split('\n');methods.forEach(this.parseMethod.bind(this));},parseMethod:function(method_line){var data=method_line.split('\t');var methodId=parseInt(data[0]);var methodName=data[1]+'.'+data[2]+data[3];this.addMethod(methodId,methodName);},addMethod:function(methodId,methodName){this.methods_[methodId]=methodName;},getMethodName:function(methodId){return this.methods_[methodId];}};tr.importer.Importer.register(DdmsImporter);return{DdmsImporter:DdmsImporter};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function AndroidParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));importer.registerEventHandler('0:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+function parseArgs(argsString){var args={};if(argsString){var argsArray=argsString.split(';');for(var i=0;i<argsArray.length;++i){var parts=argsArray[i].split('=');if(parts[0])
+args[parts.shift()]=parts.join('=');}}
+return args;}
+AndroidParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(thread,category,name,cookie,ts,args){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts,args);var key=category+':'+name+':'+cookie;slice.id=cookie;slice.startThread=thread;if(!this.openAsyncSlices){this.openAsyncSlices={};}
+this.openAsyncSlices[key]=slice;},closeAsyncSlice:function(thread,category,name,cookie,ts,args){if(!this.openAsyncSlices){return;}
+var key=category+':'+name+':'+cookie;var slice=this.openAsyncSlices[key];if(!slice){return;}
+for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the S and F events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the F event will be used.'});}
+slice.args[arg]=args[arg];}
+slice.endThread=thread;slice.duration=ts-slice.start;slice.startThread.asyncSliceGroup.push(slice);slice.subSlices=[new tr.model.AsyncSlice(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];delete this.openAsyncSlices[key];},traceMarkWriteAndroidEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=eventBase.details.split('|');switch(eventData[0]){case'B':var ppid=parseInt(eventData[1]);var title=eventData[2];var args=parseArgs(eventData[3]);var category=eventData[4];if(category===undefined)
+category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+this.ppids_[pid]=ppid;thread.sliceGroup.beginSlice(category,title,ts,args);break;case'E':var ppid=this.ppids_[pid];if(ppid===undefined){break;}
+var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);if(!thread.sliceGroup.openSliceCount){break;}
+var slice=thread.sliceGroup.endSlice(ts);var args=parseArgs(eventData[3]);for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the B and E events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the E event will be used.'});}
+slice.args[arg]=args[arg];}
+break;case'C':var ppid=parseInt(eventData[1]);var name=eventData[2];var value=parseInt(eventData[3]);var category=eventData[4];if(category===undefined)
+category='android';var ctr=this.model_.getOrCreateProcess(ppid).getOrCreateCounter(category,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries(value,ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,value);});break;case'S':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)
+category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.openAsyncSlice(thread,category,name,cookie,ts,args);break;case'F':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)
+category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.closeAsyncSlice(thread,category,name,cookie,ts,args);break;default:return false;}
+return true;}};Parser.register(AndroidParser);return{AndroidParser:AndroidParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;var binderTransRE=new RegExp('transaction=(\\d+) dest_node=(\\d+) '+'dest_proc=(\\d+) dest_thread=(\\d+) '+'reply=(\\d+) flags=(0x[0-9a-fA-F]+) '+'code=(0x[0-9a-fA-F]+)');var binderTransReceivedRE=/transaction=(\d+)/;function isBinderThread(name){return(name.indexOf('Binder')>-1);}
+var TF_ONE_WAY=0x01;var TF_ROOT_OBJECT=0x04;var TF_STATUS_CODE=0x08;var TF_ACCEPT_FDS=0x10;var NO_FLAGS=0;function binderFlagsToHuman(num){var flag=parseInt(num,16);var str='';if(flag&TF_ONE_WAY)
+str+='this is a one-way call: async, no return; ';if(flag&TF_ROOT_OBJECT)
+str+='contents are the components root object; ';if(flag&TF_STATUS_CODE)
+str+='contents are a 32-bit status code; ';if(flag&TF_ACCEPT_FDS)
+str+='allow replies with file descriptors; ';if(flag===NO_FLAGS)
+str+='No Flags Set';return str;}
+function isReplyToOrigin(calling,called){return(called.dest_proc===calling.calling_pid||called.dest_thread===calling.calling_pid);}
+function binderCodeToHuman(code){return'Java Layer Dependent';}
+function doInternalSlice(trans,slice,ts){if(slice.subSlices.length!==0){slice.subSlices[0].start=ts;return slice.subSlices[0];}
+var kthread=trans.calling_kthread.thread;var internal_slice=kthread.sliceGroup.pushCompleteSlice('binder',slice.title,ts,.001,0,0,slice.args);internal_slice.title=slice.title;internal_slice.id=slice.id;internal_slice.colorId=slice.colorId;slice.subSlices.push(internal_slice);return internal_slice;}
+function generateBinderArgsForSlice(trans,c_threadName){return{'Transaction Id':trans.transaction_key,'Destination Node':trans.dest_node,'Destination Process':trans.dest_proc,'Destination Thread':trans.dest_thread,'Destination Name':c_threadName,'Reply transaction?':trans.is_reply_transaction,'Flags':trans.flags+' '+
+binderFlagsToHuman(trans.flags),'Code':trans.code+' '+
+binderCodeToHuman(trans.code),'Calling PID':trans.calling_pid,'Calling tgid':trans.calling_kthread.thread.parent.pid};}
+function BinderTransaction(events,calling_pid,calling_ts,calling_kthread){this.transaction_key=parseInt(events[1]);this.dest_node=parseInt(events[2]);this.dest_proc=parseInt(events[3]);this.dest_thread=parseInt(events[4]);this.is_reply_transaction=parseInt(events[5])===1?true:false;this.expect_reply=((this.is_reply_transaction===false)&&(parseInt(events[6],16)&TF_ONE_WAY)===0);this.flags=events[6];this.code=events[7];this.calling_pid=calling_pid;this.calling_ts=calling_ts;this.calling_kthread=calling_kthread;}
+function BinderParser(importer){Parser.call(this,importer);importer.registerEventHandler('binder_locked',BinderParser.prototype.binderLocked.bind(this));importer.registerEventHandler('binder_unlock',BinderParser.prototype.binderUnlock.bind(this));importer.registerEventHandler('binder_lock',BinderParser.prototype.binderLock.bind(this));importer.registerEventHandler('binder_transaction',BinderParser.prototype.binderTransaction.bind(this));importer.registerEventHandler('binder_transaction_received',BinderParser.prototype.binderTransactionReceived.bind(this));this.model_=importer.model;this.kthreadlookup={};this.importer_=importer;this.transWaitingRecv={};this.syncTransWaitingCompletion={};this.recursiveSyncTransWaitingCompletion_ByPID={};this.receivedTransWaitingConversion={};}
+BinderParser.prototype={__proto__:Parser.prototype,binderLock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventName.threadName);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);kthread.binderAttemptLockTS=ts;kthread.binderOpenTsA=ts;return true;},binderLocked:function(eventName,cpuNumber,pid,ts,eventBase){var binder_thread=isBinderThread(eventBase.threadName);var tgid,name;var as_slice;var need_push=false;var kthread,rthread;tgid=parseInt(eventBase.tgid);name=eventBase.threadName;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);this.doNameMappings(pid,tgid,name);rthread=kthread.thread;kthread.binderLockAquiredTS=ts;if(kthread.binderAttemptLockTS===undefined)
+return false;var args=this.generateArgsForSlice(tgid,pid,name,kthread);rthread.sliceGroup.pushCompleteSlice('binder','binder lock waiting',kthread.binderAttemptLockTS,ts-kthread.binderAttemptLockTS,0,0,args);kthread.binderAttemptLockTS=undefined;return true;},binderUnlock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);if(kthread.binderLockAquiredTS===undefined)
+return false;args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransRE.exec(eventBase.details);if(event===undefined)
+return false;var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventBase.threadName);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var trans=new BinderTransaction(event,pid,ts,kthread);var args=generateBinderArgsForSlice(trans,eventBase.threadName);var prior_receive=this.getPriorReceiveOnPID(pid);if(prior_receive!==false){return this.modelPriorReceive(prior_receive,ts,pid,tgid,kthread,trans,args,event);}
+var recursive_trans=this.getRecursiveTransactionNeedingCompletion(pid);if(recursive_trans!==false)
+return this.modelRecursiveTransactions(recursive_trans,ts,pid,kthread,trans,args);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);slice.colorId=ColorScheme.getColorIdForGeneralPurposeString(ts.toString());trans.slice=slice;if(trans.expect_reply)
+slice.title='binder transaction';else
+slice.title='binder transaction async';this.addTransactionWaitingForRecv(trans.transaction_key,trans);return true;},binderTransactionReceived:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransReceivedRE.exec(eventBase.details);if(event===undefined)
+return false;var transactionkey=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var syncComplete=this.getSyncTransNeedsCompletion(transactionkey);if(syncComplete!==false){var sync_trans=syncComplete[0];var sync_slice=sync_trans.slice;var response_trans=syncComplete[1];var response_slice=response_trans.slice;sync_slice.duration=ts-sync_slice.start;var sync_internal=doInternalSlice(sync_trans,sync_slice,ts);var response_ts=response_slice.start+response_slice.duration;var response_internal=doInternalSlice(response_trans,response_slice,response_ts);if(response_slice.outFlowEvents.length===0||sync_slice.inFlowEvents.length===0){var flow=this.generateFlow(response_internal,sync_internal,response_trans,sync_trans);sync_slice.inFlowEvents.push(flow);response_slice.outFlowEvents.push(flow);this.model_.flowEvents.push(flow);}
+for(var i=1;i<sync_slice.inFlowEvents.length;i++){sync_slice.inFlowEvents[i].duration=ts-sync_slice.inFlowEvents[i].start;}
+return true;}
+var tr_for_recv=this.getTransactionWaitingForRecv(transactionkey);if(tr_for_recv!==false){if(!tr_for_recv.expect_reply){var args=generateBinderArgsForSlice(tr_for_recv,eventBase.threadName);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder Async recv',ts,.03,0,0,args);var fake_event=[0,0,0,0,0,0,0];var fake_trans=new BinderTransaction(fake_event,pid,ts,kthread);var flow=this.generateFlow(tr_for_recv.slice,slice,tr_for_recv,fake_trans);this.model_.flowEvents.push(flow);tr_for_recv.slice.title='binder transaction async';tr_for_recv.slice.duration=.03;return true;}
+tr_for_recv.slice.title='binder transaction';this.setCurrentReceiveOnPID(pid,[ts,tr_for_recv]);return true;}
+return false;},modelRecursiveTransactions:function(recursive_trans,ts,pid,kthread,trans,args){var recursive_slice=recursive_trans[1].slice;var orig_slice=recursive_trans[0].slice;recursive_slice.duration=ts-recursive_slice.start;trans.slice=recursive_slice;if(trans.is_reply_transaction){orig_slice.duration=ts-orig_slice.start;this.addSyncTransNeedingCompletion(trans.transaction_key,recursive_trans);if(isReplyToOrigin(recursive_trans[0],trans))
+this.removeRecursiveTransaction(pid);}else{var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);trans.slice=slice;this.addTransactionWaitingForRecv(trans.transaction_key,trans);}
+return true;},modelPriorReceive:function(prior_receive,ts,pid,tgid,kthread,trans,args,event){var callee_slice=prior_receive[1].slice;var callee_trans=prior_receive[1];var recv_ts=prior_receive[0];var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',recv_ts,ts-recv_ts,0,0,args);var flow=this.generateFlow(callee_slice,slice,callee_trans,trans);this.model_.flowEvents.push(flow);trans.slice=slice;if(trans.is_reply_transaction){slice.title='binder reply';this.addSyncTransNeedingCompletion(trans.transaction_key,[callee_trans,trans]);}else{slice.title='binder reply';var trans1=new BinderTransaction(event,pid,ts,kthread);slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder transaction',recv_ts,(ts-recv_ts),0,0,args);if(!trans.expect_reply){slice.title='binder transaction async';slice.duration=.03;}else{}
+trans1.slice=slice;this.addRecursiveSyncTransNeedingCompletion(pid,[callee_trans,trans]);this.addTransactionWaitingForRecv(trans.transaction_key,trans1);}
+return true;},getRecursiveTransactionNeedingCompletion:function(pid){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined)
+return false;var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0)
+return false;return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len-1];},addRecursiveSyncTransNeedingCompletion:function(pid,tuple){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined)
+this.recursiveSyncTransWaitingCompletion_ByPID[pid]=[];this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple);},removeRecursiveTransaction:function(pid){var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0){delete this.recursiveSyncTransWaitingCompletion_ByPID[pid];return;}
+this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len-1,1);},setCurrentReceiveOnPID:function(pid,tuple){if(this.receivedTransWaitingConversion[pid]===undefined){this.receivedTransWaitingConversion[pid]=[];}
+this.receivedTransWaitingConversion[pid].push(tuple);},getPriorReceiveOnPID:function(pid){if(this.receivedTransWaitingConversion[pid]===undefined)
+return false;var len=this.receivedTransWaitingConversion[pid].length;if(len===0)
+return false;return this.receivedTransWaitingConversion[pid].splice(len-1,1)[0];},addSyncTransNeedingCompletion:function(transactionkey,tuple){var dict=this.syncTransWaitingCompletion;dict[transactionkey]=tuple;},getSyncTransNeedsCompletion:function(transactionkey){var ret=this.syncTransWaitingCompletion[transactionkey];if(ret===undefined)
+return false;delete this.syncTransWaitingCompletion[transactionkey];return ret;},getTransactionWaitingForRecv:function(transactionkey){var ret=this.transWaitingRecv[transactionkey];if(ret===undefined)
+return false;delete this.transWaitingRecv[transactionkey];return ret;},addTransactionWaitingForRecv:function(transactionkey,transaction){this.transWaitingRecv[transactionkey]=transaction;},generateFlow:function(from,to,from_trans,to_trans){var title='Transaction from : '+
+this.pid2name(from_trans.calling_pid)+' From PID: '+from_trans.calling_pid+' to pid: '+
+to_trans.calling_pid+' Thread Name: '+this.pid2name(to_trans.calling_pid);var ts=from.start;var flow=new tr.model.FlowEvent('binder','binder',title,1,ts,[]);flow.startSlice=from;flow.endSlice=to;flow.start=from.start;flow.duration=to.start-ts;from.outFlowEvents.push(flow);to.inFlowEvents.push(flow);return flow;},generateArgsForSlice:function(tgid,pid,name,kthread){return{'Thread Name':name,'pid':pid,'gid':tgid};},pid2name:function(pid){return this.kthreadlookup[pid];},doNameMappings:function(pid,tgid,name){this.registerPidName(pid,name);this.registerPidName(tgid,name);},registerPidName:function(pid,name){if(this.pid2name(pid)===undefined)
+this.kthreadlookup[pid]=name;}};Parser.register(BinderParser);return{BinderParser:BinderParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function BusParser(importer){Parser.call(this,importer);importer.registerEventHandler('memory_bus_usage',BusParser.prototype.traceMarkWriteBusEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+BusParser.prototype={__proto__:Parser.prototype,traceMarkWriteBusEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var re=new RegExp('bus=(\\S+) rw_bytes=(\\d+) r_bytes=(\\d+) '+'w_bytes=(\\d+) cycles=(\\d+) ns=(\\d+)');var event=re.exec(eventBase.details);var name=event[1];var rw_bytes=parseInt(event[2]);var r_bytes=parseInt(event[3]);var w_bytes=parseInt(event[4]);var cycles=parseInt(event[5]);var ns=parseInt(event[6]);var r_bw=r_bytes*1000000000/ns;r_bw/=1024*1024;var w_bw=w_bytes*1000000000/ns;w_bw/=1024*1024;var ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' read');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,r_bw);});ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' write');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,r_bw);});return true;}};Parser.register(BusParser);return{BusParser:BusParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ClockParser(importer){Parser.call(this,importer);importer.registerEventHandler('clock_set_rate',ClockParser.prototype.traceMarkWriteClockEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+ClockParser.prototype={__proto__:Parser.prototype,traceMarkWriteClockEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var event=/(\S+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);var name=event[1];var rate=parseInt(event[2]);var ctr=this.model_.kernel.getOrCreateCounter(null,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,rate);});return true;}};Parser.register(ClockParser);return{ClockParser:ClockParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function CpufreqParser(importer){Parser.call(this,importer);importer.registerEventHandler('cpufreq_interactive_up',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_down',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_already',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_notyet',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_setspeed',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_target',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_boost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_unboost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));}
+function splitData(input){var data={};var args=input.split(/\s+/);var len=args.length;for(var i=0;i<len;i++){var item=args[i].split('=');data[item[0]]=parseInt(item[1]);}
+return data;}
+CpufreqParser.prototype={__proto__:Parser.prototype,cpufreqSlice:function(ts,eventName,cpu,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqBoostSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq_boost');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqUpDownEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqTargetEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqBoostUnboostEvent:function(eventName,cpuNumber,pid,ts,eventBase){this.cpufreqBoostSlice(ts,eventName,{type:eventBase.details});return true;}};Parser.register(CpufreqParser);return{CpufreqParser:CpufreqParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DiskParser(importer){Parser.call(this,importer);importer.registerEventHandler('f2fs_write_begin',DiskParser.prototype.f2fsWriteBeginEvent.bind(this));importer.registerEventHandler('f2fs_write_end',DiskParser.prototype.f2fsWriteEndEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_enter',DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_exit',DiskParser.prototype.f2fsSyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_sync_file_enter',DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));importer.registerEventHandler('ext4_sync_file_exit',DiskParser.prototype.ext4SyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_da_write_begin',DiskParser.prototype.ext4WriteBeginEvent.bind(this));importer.registerEventHandler('ext4_da_write_end',DiskParser.prototype.ext4WriteEndEvent.bind(this));importer.registerEventHandler('block_rq_issue',DiskParser.prototype.blockRqIssueEvent.bind(this));importer.registerEventHandler('block_rq_complete',DiskParser.prototype.blockRqCompleteEvent.bind(this));}
+DiskParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(ts,category,threadName,pid,key,name){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts);slice.startThread=kthread.thread;if(!kthread.openAsyncSlices){kthread.openAsyncSlices={};}
+kthread.openAsyncSlices[key]=slice;},closeAsyncSlice:function(ts,category,threadName,pid,key,args){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);if(kthread.openAsyncSlices){var slice=kthread.openAsyncSlices[key];if(slice){slice.duration=ts-slice.start;slice.args=args;slice.endThread=kthread.thread;slice.subSlices=[new tr.model.AsyncSlice(category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];kthread.thread.asyncSliceGroup.push(slice);delete kthread.openAsyncSlices[key];}}},f2fsWriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), flags = (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'f2fs_write');return true;},f2fsWriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), copied = (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4WriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,'ext4_write');return true;},ext4WriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},f2fsSyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), '+'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)').exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var key=device+'-'+inode;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'fsync');return true;},f2fsSyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), '+'datasync = (\\d+), ret = (\\d+)').exec(eventBase.details.replace('not needed','not_needed'));if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[5]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4SyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var datasync=event[4]==1;var key=device+'-'+inode;var action=datasync?'fdatasync':'fsync';this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,action);return true;},ext4SyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);if(!event)
+return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[3]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},blockRqIssueEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);if(!event)
+return false;var action;switch(event[3]){case'D':action='discard';break;case'W':action='write';break;case'R':action='read';break;case'N':action='none';break;default:action='unknown';break;}
+if(event[2]){action+=' flush';}
+if(event[4]=='F'){action+=' fua';}
+if(event[5]=='A'){action+=' ahead';}
+if(event[6]=='S'){action+=' sync';}
+if(event[7]=='M'){action+=' meta';}
+var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var key=device+'-'+sector+'-'+numSectors;this.openAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,action);return true;},blockRqCompleteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);if(!event)
+return false;var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var error=parseInt(event[10]);var key=device+'-'+sector+'-'+numSectors;this.closeAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,{device:device,sector:sector,numSectors:numSectors,error:error});return true;}};Parser.register(DiskParser);return{DiskParser:DiskParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DrmParser(importer){Parser.call(this,importer);importer.registerEventHandler('drm_vblank_event',DrmParser.prototype.vblankEvent.bind(this));}
+DrmParser.prototype={__proto__:Parser.prototype,drmVblankSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('drm_vblank');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},vblankEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/crtc=(\d+), seq=(\d+)/.exec(eventBase.details);if(!event)
+return false;var crtc=parseInt(event[1]);var seq=parseInt(event[2]);this.drmVblankSlice(ts,'vblank:'+crtc,{crtc:crtc,seq:seq});return true;}};Parser.register(DrmParser);return{DrmParser:DrmParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ExynosParser(importer){Parser.call(this,importer);importer.registerEventHandler('exynos_busfreq_target_int',ExynosParser.prototype.busfreqTargetIntEvent.bind(this));importer.registerEventHandler('exynos_busfreq_target_mif',ExynosParser.prototype.busfreqTargetMifEvent.bind(this));importer.registerEventHandler('exynos_page_flip_state',ExynosParser.prototype.pageFlipStateEvent.bind(this));}
+ExynosParser.prototype={__proto__:Parser.prototype,exynosBusfreqSample:function(name,ts,frequency){var targetCpu=this.importer.getOrCreateCpu(0);var counter=targetCpu.getOrCreateCounter('',name);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries('frequency',ColorScheme.getColorIdForGeneralPurposeString(counter.name+'.'+'frequency')));}
+counter.series.forEach(function(series){series.addCounterSample(ts,frequency);});},busfreqTargetIntEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.exynosBusfreqSample('INT Frequency',ts,parseInt(event[1]));return true;},busfreqTargetMifEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.exynosBusfreqSample('MIF Frequency',ts,parseInt(event[1]));return true;},exynosPageFlipStateOpenSlice:function(ts,pipe,fb,state){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');kthread.openSliceTS=ts;kthread.openSlice=state;},exynosPageFlipStateCloseSlice:function(ts,pipe,fb,args){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},pageFlipStateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/pipe=(\d+), fb=(\d+), state=(.*)/.exec(eventBase.details);if(!event)
+return false;var pipe=parseInt(event[1]);var fb=parseInt(event[2]);var state=event[3];this.exynosPageFlipStateCloseSlice(ts,pipe,fb,{pipe:pipe,fb:fb});if(state!=='flipped')
+this.exynosPageFlipStateOpenSlice(ts,pipe,fb,state);return true;}};Parser.register(ExynosParser);return{ExynosParser:ExynosParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function GestureParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:log',GestureParser.prototype.logEvent.bind(this));importer.registerEventHandler('tracing_mark_write:SyncInterpret',GestureParser.prototype.syncEvent.bind(this));importer.registerEventHandler('tracing_mark_write:HandleTimer',GestureParser.prototype.timerEvent.bind(this));}
+GestureParser.prototype={__proto__:Parser.prototype,gestureOpenSlice:function(title,ts,opt_args){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;thread.sliceGroup.beginSlice('touchpad_gesture',title,ts,opt_args);},gestureCloseSlice:function(title,ts){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;if(thread.sliceGroup.openSliceCount){var slice=thread.sliceGroup.mostRecentlyOpenedPartialSlice;if(slice.title!=title){this.importer.model.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+slice.title+' in openSlice, and is '+
+title+' in endSlice'});}else{thread.sliceGroup.endSlice(ts);}}},logEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('GestureLog',ts,{name:innerEvent[2]});break;case'end':this.gestureCloseSlice('GestureLog',ts);}
+return true;},syncEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('SyncInterpret',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('SyncInterpret',ts);}
+return true;},timerEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('HandleTimer',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('HandleTimer',ts);}
+return true;}};Parser.register(GestureParser);return{GestureParser:GestureParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function I915Parser(importer){Parser.call(this,importer);importer.registerEventHandler('i915_gem_object_create',I915Parser.prototype.gemObjectCreateEvent.bind(this));importer.registerEventHandler('i915_gem_object_bind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_unbind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_change_domain',I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));importer.registerEventHandler('i915_gem_object_pread',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_pwrite',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_fault',I915Parser.prototype.gemObjectFaultEvent.bind(this));importer.registerEventHandler('i915_gem_object_clflush',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_object_destroy',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_ring_dispatch',I915Parser.prototype.gemRingDispatchEvent.bind(this));importer.registerEventHandler('i915_gem_ring_flush',I915Parser.prototype.gemRingFlushEvent.bind(this));importer.registerEventHandler('i915_gem_request',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_add',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_complete',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_retire',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_begin',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_end',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_begin',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_end',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_reg_rw',I915Parser.prototype.regRWEvent.bind(this));importer.registerEventHandler('i915_flip_request',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('i915_flip_complete',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('intel_gpu_freq_change',I915Parser.prototype.gpuFrequency.bind(this));}
+I915Parser.prototype={__proto__:Parser.prototype,i915FlipOpenSlice:function(ts,obj,plane){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');kthread.openSliceTS=ts;kthread.openSlice='flip:'+obj+'/'+plane;},i915FlipCloseSlice:function(ts,args){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},i915GemObjectSlice:function(ts,eventName,obj,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem');kthread.openSlice=eventName+':'+obj;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915GemRingSlice:function(ts,eventName,dev,ring,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem_ring');kthread.openSlice=eventName+':'+dev+'.'+ring;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915RegSlice:function(ts,eventName,reg,args){var kthread=this.importer.getOrCreatePseudoThread('i915_reg');kthread.openSlice=eventName+':'+reg;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915FreqChangeSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gpu_freq');kthread.openSlice=eventName;var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},gemObjectCreateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var size=parseInt(event[2]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,size:size});return true;},gemObjectBindEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var offset=event[2];var size=parseInt(event[3]);this.i915ObjectGemSlice(ts,eventName+':'+obj,{obj:obj,offset:offset,size:size});return true;},gemObjectChangeDomainEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var read=event[2];var write=event[3];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,read:read,write:write});return true;},gemObjectPreadWriteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var offset=parseInt(event[2]);var len=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,offset:offset,len:len});return true;},gemObjectFaultEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];var type=event[2];var index=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,type:type,index:index});return true;},gemObjectDestroyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+)/.exec(eventBase.details);if(!event)
+return false;var obj=event[1];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj});return true;},gemRingDispatchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)
+return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingFlushEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/.exec(eventBase.details);if(!event)
+return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var invalidate=event[3];var flush=event[4];this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,invalidate:invalidate,flush:flush});return true;},gemRequestEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)
+return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+)/.exec(eventBase.details);if(!event)
+return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring});return true;},regRWEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/.exec(eventBase.details);if(!event)
+return false;var rw=event[1];var reg=event[2];var len=event[3];var data=event[3];this.i915RegSlice(ts,rw,reg,{rw:rw,reg:reg,len:len,data:data});return true;},flipEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/plane=(\d+), obj=(\w+)/.exec(eventBase.details);if(!event)
+return false;var plane=parseInt(event[1]);var obj=event[2];if(eventName=='i915_flip_request')
+this.i915FlipOpenSlice(ts,obj,plane);else
+this.i915FlipCloseSlice(ts,{obj:obj,plane:plane});return true;},gpuFrequency:function(eventName,cpuNumver,pid,ts,eventBase){var event=/new_freq=(\d+)/.exec(eventBase.details);if(!event)
+return false;var freq=parseInt(event[1]);this.i915FreqChangeSlice(ts,eventName,{freq:freq});return true;}};Parser.register(I915Parser);return{I915Parser:I915Parser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function IrqParser(importer){Parser.call(this,importer);importer.registerEventHandler('irq_handler_entry',IrqParser.prototype.irqHandlerEntryEvent.bind(this));importer.registerEventHandler('irq_handler_exit',IrqParser.prototype.irqHandlerExitEvent.bind(this));importer.registerEventHandler('softirq_raise',IrqParser.prototype.softirqRaiseEvent.bind(this));importer.registerEventHandler('softirq_entry',IrqParser.prototype.softirqEntryEvent.bind(this));importer.registerEventHandler('softirq_exit',IrqParser.prototype.softirqExitEvent.bind(this));importer.registerEventHandler('ipi_entry',IrqParser.prototype.ipiEntryEvent.bind(this));importer.registerEventHandler('ipi_exit',IrqParser.prototype.ipiExitEvent.bind(this));}
+var irqHandlerEntryRE=/irq=(\d+) name=(.+)/;var irqHandlerExitRE=/irq=(\d+) ret=(.+)/;var softirqRE=/vec=(\d+) \[action=(.+)\]/;var ipiHandlerExitRE=/\((.+)\)/;IrqParser.prototype={__proto__:Parser.prototype,irqHandlerEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerEntryRE.exec(eventBase.details);if(!event)
+return false;var irq=parseInt(event[1]);var name=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;thread.irqName=name;return true;},irqHandlerExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerExitRE.exec(eventBase.details);if(!event)
+return false;var irq=parseInt(event[1]);var ret=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('','IRQ ('+thread.irqName+')',ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{ret:ret},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;thread.irqName=undefined;return true;},softirqRaiseEvent:function(eventName,cpuNumber,pid,ts,eventBase){return true;},softirqEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)
+return false;var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},softirqExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)
+return false;var vec=parseInt(event[1]);var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('',action,ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{vec:vec},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;},ipiEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},ipiExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=ipiHandlerExitRE.exec(eventBase.details);if(!event)
+return false;var ipiName=event[1];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.Slice('','IPI ('+ipiName+')',ColorScheme.getColorIdForGeneralPurposeString(ipiName),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;}};Parser.register(IrqParser);return{IrqParser:IrqParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var LinuxPerfParser=tr.e.importer.linux_perf.Parser;function KernelFuncParser(importer){LinuxPerfParser.call(this,importer);importer.registerEventHandler('graph_ent',KernelFuncParser.prototype.traceKernelFuncEnterEvent.bind(this));importer.registerEventHandler('graph_ret',KernelFuncParser.prototype.traceKernelFuncReturnEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+var TestExports={};var funcEnterRE=new RegExp('func=(.+)');TestExports.funcEnterRE=funcEnterRE;KernelFuncParser.prototype={__proto__:LinuxPerfParser.prototype,traceKernelFuncEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=funcEnterRE.exec(eventBase.details);if(!eventData)
+return false;if(eventBase.tgid===undefined){return false;}
+var tgid=parseInt(eventBase.tgid);var name=eventData[1];var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+var slice=slices.beginSlice(null,name,ts,{});return true;},traceKernelFuncReturnEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(eventBase.tgid===undefined){return false;}
+var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+if(slices.openSliceCount>0){slices.endSlice(ts);}
+return true;}};LinuxPerfParser.register(KernelFuncParser);return{KernelFuncParser:KernelFuncParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function MaliParser(importer){Parser.call(this,importer);importer.registerEventHandler('mali_dvfs_event',MaliParser.prototype.dvfsEventEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_clock',MaliParser.prototype.dvfsSetClockEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_voltage',MaliParser.prototype.dvfsSetVoltageEvent.bind(this));this.addJMCounter('mali_hwc_MESSAGES_SENT','Messages Sent');this.addJMCounter('mali_hwc_MESSAGES_RECEIVED','Messages Received');this.addJMCycles('mali_hwc_GPU_ACTIVE','GPU Active');this.addJMCycles('mali_hwc_IRQ_ACTIVE','IRQ Active');for(var i=0;i<7;i++){var jobStr='JS'+i;var jobHWCStr='mali_hwc_'+jobStr;this.addJMCounter(jobHWCStr+'_JOBS',jobStr+' Jobs');this.addJMCounter(jobHWCStr+'_TASKS',jobStr+' Tasks');this.addJMCycles(jobHWCStr+'_ACTIVE',jobStr+' Active');this.addJMCycles(jobHWCStr+'_WAIT_READ',jobStr+' Wait Read');this.addJMCycles(jobHWCStr+'_WAIT_ISSUE',jobStr+' Wait Issue');this.addJMCycles(jobHWCStr+'_WAIT_DEPEND',jobStr+' Wait Depend');this.addJMCycles(jobHWCStr+'_WAIT_FINISH',jobStr+' Wait Finish');}
+this.addTilerCounter('mali_hwc_TRIANGLES','Triangles');this.addTilerCounter('mali_hwc_QUADS','Quads');this.addTilerCounter('mali_hwc_POLYGONS','Polygons');this.addTilerCounter('mali_hwc_POINTS','Points');this.addTilerCounter('mali_hwc_LINES','Lines');this.addTilerCounter('mali_hwc_VCACHE_HIT','VCache Hit');this.addTilerCounter('mali_hwc_VCACHE_MISS','VCache Miss');this.addTilerCounter('mali_hwc_FRONT_FACING','Front Facing');this.addTilerCounter('mali_hwc_BACK_FACING','Back Facing');this.addTilerCounter('mali_hwc_PRIM_VISIBLE','Prim Visible');this.addTilerCounter('mali_hwc_PRIM_CULLED','Prim Culled');this.addTilerCounter('mali_hwc_PRIM_CLIPPED','Prim Clipped');this.addTilerCounter('mali_hwc_WRBUF_HIT','Wrbuf Hit');this.addTilerCounter('mali_hwc_WRBUF_MISS','Wrbuf Miss');this.addTilerCounter('mali_hwc_WRBUF_LINE','Wrbuf Line');this.addTilerCounter('mali_hwc_WRBUF_PARTIAL','Wrbuf Partial');this.addTilerCounter('mali_hwc_WRBUF_STALL','Wrbuf Stall');this.addTilerCycles('mali_hwc_ACTIVE','Tiler Active');this.addTilerCycles('mali_hwc_INDEX_WAIT','Index Wait');this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT','Index Range Wait');this.addTilerCycles('mali_hwc_VERTEX_WAIT','Vertex Wait');this.addTilerCycles('mali_hwc_PCACHE_WAIT','Pcache Wait');this.addTilerCycles('mali_hwc_WRBUF_WAIT','Wrbuf Wait');this.addTilerCycles('mali_hwc_BUS_READ','Bus Read');this.addTilerCycles('mali_hwc_BUS_WRITE','Bus Write');this.addTilerCycles('mali_hwc_TILER_UTLB_STALL','Tiler UTLB Stall');this.addTilerCycles('mali_hwc_TILER_UTLB_HIT','Tiler UTLB Hit');this.addFragCycles('mali_hwc_FRAG_ACTIVE','Active');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES','Primitives');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED','Primitives Dropped');this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC','Descriptor Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR','PLR Processing??');this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT','Vertex Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP','Triangle Setup');this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST','Rasterization???');this.addFragCounter('mali_hwc_FRAG_THREADS','Threads');this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS','Dummy Threads');this.addFragCounter('mali_hwc_FRAG_QUADS_RAST','Quads Rast');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST','Quads EZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED','Quads EZS Killed');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST','Quads LZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED','Quads LZS Killed');this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE','No Tiles');this.addFragCounter('mali_hwc_FRAG_NUM_TILES','Tiles');this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM','Transactions Eliminated');this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE','Active');this.addComputeCounter('mali_hwc_COMPUTE_TASKS','Tasks');this.addComputeCounter('mali_hwc_COMPUTE_THREADS','Threads Started');this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC','Waiting for Descriptors');this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE','Active');this.addArithCounter('mali_hwc_ARITH_WORDS','Instructions (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_REG','Reg scheduling stalls (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_L0','L0 cache miss stalls (/Pipes)');this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND','Frag dep check failures (/Pipes)');this.addLSCounter('mali_hwc_LS_WORDS','Instruction Words Completed');this.addLSCounter('mali_hwc_LS_ISSUES','Full Pipeline Issues');this.addLSCounter('mali_hwc_LS_RESTARTS','Restarts (unpairable insts)');this.addLSCounter('mali_hwc_LS_REISSUES_MISS','Pipeline reissue (cache miss/uTLB)');this.addLSCounter('mali_hwc_LS_REISSUES_VD','Pipeline reissue (varying data)');this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS','Pipeline reissue (attribute cache miss)');this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB','Writeback not used');this.addTexCounter('mali_hwc_TEX_WORDS','Words');this.addTexCounter('mali_hwc_TEX_BUBBLES','Bubbles');this.addTexCounter('mali_hwc_TEX_WORDS_L0','Words L0');this.addTexCounter('mali_hwc_TEX_WORDS_DESC','Words Desc');this.addTexCounter('mali_hwc_TEX_THREADS','Threads');this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS','Recirc due to Full Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_DESC','Recirc due to Desc Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI','Recirc due to Multipass');this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS','Recirc due to Partial Cache Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_CONF','Recirc due to Cache Conflict');this.addLSCCounter('mali_hwc_LSC_READ_HITS','Read Hits');this.addLSCCounter('mali_hwc_LSC_READ_MISSES','Read Misses');this.addLSCCounter('mali_hwc_LSC_WRITE_HITS','Write Hits');this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES','Write Misses');this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS','Atomic Hits');this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES','Atomic Misses');this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES','Line Fetches');this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE','Dirty Lines');this.addLSCCounter('mali_hwc_LSC_SNOOPS','Snoops');this.addAXICounter('mali_hwc_AXI_TLB_STALL','Address channel stall');this.addAXICounter('mali_hwc_AXI_TLB_MISS','Cache Miss');this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION','Transactions');this.addAXICounter('mali_hwc_LS_TLB_MISS','LS Cache Miss');this.addAXICounter('mali_hwc_LS_TLB_HIT','LS Cache Hit');this.addAXICounter('mali_hwc_AXI_BEATS_READ','Read Beats');this.addAXICounter('mali_hwc_AXI_BEATS_WRITE','Write Beats');this.addMMUCounter('mali_hwc_MMU_TABLE_WALK','Page Table Walks');this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS','Cache Miss from Replay Buffer');this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL','Replay Buffer Full');this.addMMUCounter('mali_hwc_MMU_NEW_MISS','Cache Miss on New Request');this.addMMUCounter('mali_hwc_MMU_HIT','Cache Hit');this.addMMUCycles('mali_hwc_UTLB_STALL','UTLB Stalled');this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS','UTLB Replay Miss');this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL','UTLB Replay Full');this.addMMUCycles('mali_hwc_UTLB_NEW_MISS','UTLB New Miss');this.addMMUCycles('mali_hwc_UTLB_HIT','UTLB Hit');this.addL2Counter('mali_hwc_L2_READ_BEATS','Read Beats');this.addL2Counter('mali_hwc_L2_WRITE_BEATS','Write Beats');this.addL2Counter('mali_hwc_L2_ANY_LOOKUP','Any Lookup');this.addL2Counter('mali_hwc_L2_READ_LOOKUP','Read Lookup');this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP','Shareable Read Lookup');this.addL2Counter('mali_hwc_L2_READ_REPLAY','Read Replayed');this.addL2Counter('mali_hwc_L2_READ_SNOOP','Read Snoop');this.addL2Counter('mali_hwc_L2_READ_HIT','Read Cache Hit');this.addL2Counter('mali_hwc_L2_CLEAN_MISS','CleanUnique Miss');this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP','Write Lookup');this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP','Shareable Write Lookup');this.addL2Counter('mali_hwc_L2_WRITE_REPLAY','Write Replayed');this.addL2Counter('mali_hwc_L2_WRITE_SNOOP','Write Snoop');this.addL2Counter('mali_hwc_L2_WRITE_HIT','Write Cache Hit');this.addL2Counter('mali_hwc_L2_EXT_READ_FULL','ExtRD with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_READ_HALF','ExtRD with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL','ExtWR with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF','ExtWR with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_READ','External Read (ExtRD)');this.addL2Counter('mali_hwc_L2_EXT_READ_LINE','ExtRD (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE','External Write (ExtWR)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE','ExtWR (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL','ExtWR (burst size <64B)');this.addL2Counter('mali_hwc_L2_EXT_BARRIER','External Barrier');this.addL2Counter('mali_hwc_L2_EXT_AR_STALL','Address Read stalls');this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL','Response Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL','Read Data Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_R_RAW','RAW hazard stalls');this.addL2Counter('mali_hwc_L2_EXT_W_STALL','Write Data stalls');this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL','Write Data Buffer full');this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD','WAW or WAR hazard stalls');this.addL2Counter('mali_hwc_L2_TAG_HAZARD','Tag hazard replays');this.addL2Cycles('mali_hwc_L2_SNOOP_FULL','Snoop buffer full');this.addL2Cycles('mali_hwc_L2_REPLAY_FULL','Replay buffer full');importer.registerEventHandler('tracing_mark_write:mali_driver',MaliParser.prototype.maliDDKEvent.bind(this));this.model_=importer.model_;}
+MaliParser.prototype={__proto__:Parser.prototype,maliDDKOpenSlice:function(pid,tid,ts,func,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);var funcArgs=/^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func);thread.sliceGroup.beginSlice('gpu-driver',funcArgs[1],ts,{'args':funcArgs[2],'blockinfo':blockinfo});},maliDDKCloseSlice:function(pid,tid,ts,args,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);if(!thread.sliceGroup.openSliceCount){return;}
+thread.sliceGroup.endSlice(ts);},autoDetectLineRE:function(line){var lineREWithThread=/^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/;if(lineREWithThread.test(line))
+return lineREWithThread;var lineRENoThread=/^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/;if(lineRENoThread.test(line))
+return lineRENoThread;return null;},lineRE:null,maliDDKEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(this.lineRE==null){this.lineRE=this.autoDetectLineRE(eventBase.details);if(this.lineRE==null)
+return false;}
+var maliEvent=this.lineRE.exec(eventBase.details);var tid=(maliEvent[1]===''?'mali':maliEvent[1]);switch(maliEvent[2]){case'cros_trace_print_enter':this.maliDDKOpenSlice(pid,tid,ts,maliEvent[4],maliEvent[3]);break;case'cros_trace_print_exit':this.maliDDKCloseSlice(pid,tid,ts,[],maliEvent[3]);}
+return true;},dvfsSample:function(counterName,seriesName,ts,s){var value=parseInt(s);var counter=this.model_.kernel.getOrCreateCounter('DVFS',counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});},dvfsEventEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/utilization=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.dvfsSample('DVFS Utilization','utilization',ts,event[1]);return true;},dvfsSetClockEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.dvfsSample('DVFS Frequency','frequency',ts,event[1]);return true;},dvfsSetVoltageEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/voltage=(\d+)/.exec(eventBase.details);if(!event)
+return false;this.dvfsSample('DVFS Voltage','voltage',ts,event[1]);return true;},hwcSample:function(cat,counterName,seriesName,ts,eventBase){var event=/val=(\d+)/.exec(eventBase.details);if(!event)
+return false;var value=parseInt(event[1]);var counter=this.model_.kernel.getOrCreateCounter(cat,counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});return true;},jmSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:jm','JM: '+ctrName,seriesName,ts,eventBase);},addJMCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addJMCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},tilerSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:tiler','Tiler: '+ctrName,seriesName,ts,eventBase);},addTilerCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTilerCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},fragSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:fragment','Fragment: '+ctrName,seriesName,ts,eventBase);},addFragCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addFragCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},computeSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:compute','Compute: '+ctrName,seriesName,ts,eventBase);},addComputeCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addComputeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTripipeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:shader','Tripipe: '+hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},arithSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:arith','Arith: '+ctrName,seriesName,ts,eventBase);},addArithCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addArithCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:ls','LS: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},textureSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:texture','Texture: '+ctrName,seriesName,ts,eventBase);},addTexCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.textureSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:lsc','LSC: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addAXICounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:axi','AXI: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},mmuSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:mmu','MMU: '+ctrName,seriesName,ts,eventBase);},addMMUCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addMMUCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},l2Sample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:l2','L2: '+ctrName,seriesName,ts,eventBase);},addL2Counter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addL2Cycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));}};Parser.register(MaliParser);return{MaliParser:MaliParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function MemReclaimParser(importer){Parser.call(this,importer);importer.registerEventHandler('mm_vmscan_kswapd_wake',MemReclaimParser.prototype.kswapdWake.bind(this));importer.registerEventHandler('mm_vmscan_kswapd_sleep',MemReclaimParser.prototype.kswapdSleep.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_begin',MemReclaimParser.prototype.reclaimBegin.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_end',MemReclaimParser.prototype.reclaimEnd.bind(this));}
+var kswapdWakeRE=/nid=(\d+) order=(\d+)/;var kswapdSleepRE=/nid=(\d+)/;var reclaimBeginRE=/order=(\d+) may_writepage=\d+ gfp_flags=(.+)/;var reclaimEndRE=/nr_reclaimed=(\d+)/;MemReclaimParser.prototype={__proto__:Parser.prototype,kswapdWake:function(eventName,cpuNumber,pid,ts,eventBase){var event=kswapdWakeRE.exec(eventBase.details);if(!event)
+return false;var tgid=parseInt(eventBase.tgid);var nid=parseInt(event[1]);var order=parseInt(event[2]);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){if(order>kthread.order){kthread.order=order;}}else{kthread.openSliceTS=ts;kthread.order=order;}
+return true;},kswapdSleep:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim',eventBase.threadName,kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order});}
+kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimBeginRE.exec(eventBase.details);if(!event)
+return false;var order=parseInt(event[1]);var gfp=event[2];var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openSliceTS=ts;kthread.order=order;kthread.gfp=gfp;return true;},reclaimEnd:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimEndRE.exec(eventBase.details);if(!event)
+return false;var nr_reclaimed=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nr_reclaimed});}
+kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser:MemReclaimParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
+PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice:function(ts,targetCpuNumber,eventType,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter;if(eventType!='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
+powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice:function(ts,targetCpuNumber,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
+var val=(cpuState!=4294967295?cpuState+1:0);powerCounter.series.forEach(function(series){series.addCounterSample(ts,val);});},cpuFrequencySlice:function(ts,targetCpuNumber,powerState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},powerStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[3]);var cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d+) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[3]);var powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[2]);var powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuIdleEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d)+/.exec(eventBase.details);if(!event)
+return false;var targetCpuNumber=parseInt(event[2]);var cpuState=parseInt(event[1]);this.cpuIdleSlice(ts,targetCpuNumber,cpuState);return true;}};Parser.register(PowerParser);return{PowerParser:PowerParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function RegulatorParser(importer){Parser.call(this,importer);importer.registerEventHandler('regulator_enable',RegulatorParser.prototype.regulatorEnableEvent.bind(this));importer.registerEventHandler('regulator_enable_delay',RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this));importer.registerEventHandler('regulator_enable_complete',RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this));importer.registerEventHandler('regulator_disable',RegulatorParser.prototype.regulatorDisableEvent.bind(this));importer.registerEventHandler('regulator_disable_complete',RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this));importer.registerEventHandler('regulator_set_voltage',RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this));importer.registerEventHandler('regulator_set_voltage_complete',RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this));this.model_=importer.model_;}
+var regulatorEnableRE=/name=(.+)/;var regulatorDisableRE=/name=(.+)/;var regulatorSetVoltageCompleteRE=/name=(\S+), val=(\d+)/;RegulatorParser.prototype={__proto__:Parser.prototype,getCtr_:function(ctrName,valueName){var ctr=this.model_.kernel.getOrCreateCounter(null,'vreg '+ctrName+' '+valueName);if(ctr.series[0]===undefined){ctr.addSeries(new tr.model.CounterSeries(valueName,ColorScheme.getColorIdForGeneralPurposeString(ctrName+'.'+valueName)));}
+return ctr;},regulatorEnableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorEnableRE.exec(eventBase.details);if(!event)
+return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,1);return true;},regulatorEnableDelayEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorEnableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorDisableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorDisableRE.exec(eventBase.details);if(!event)
+return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,0);return true;},regulatorDisableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorSetVoltageCompleteRE.exec(eventBase.details);if(!event)
+return false;var name=event[1];var voltage=parseInt(event[2]);var ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser:RegulatorParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));}
+var TestExports={};var schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');TestExports.schedSwitchRE=schedSwitchRE;var schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+) success=(\d+) target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedSwitchRE.exec(eventBase.details);if(!event)
+return false;var prevState=event[4];var nextComm=event[5];var nextPid=parseInt(event[6]);var nextPrio=parseInt(event[7]);var nextThread=this.importer.threadsByLinuxPid[nextPid];var nextName;if(nextThread)
+nextName=nextThread.userFriendlyName;else
+nextName=nextComm;var cpu=this.importer.getOrCreateCpu(cpuNumber);cpu.switchActiveThread(ts,{stateWhenDescheduled:prevState},nextPid,nextName,{comm:nextComm,tid:nextPid,prio:nextPrio});return true;},schedWakeupEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedWakeupRE.exec(eventBase.details);if(!event)
+return false;var fromPid=pid;var comm=event[1];var pid=parseInt(event[2]);var prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;}};Parser.register(SchedParser);return{SchedParser:SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
+var syncTimelineRE=/name=(\S+) value=(\S*)/;var syncWaitRE=/(\S+) name=(\S+) state=(\d+)/;var syncPtRE=/name=(\S+) value=(\S*)/;SyncParser.prototype={__proto__:Parser.prototype,timelineEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncTimelineRE.exec(eventBase.details);if(!event)
+return false;var thread=this.importer.getOrCreatePseudoThread(event[1]);if(thread.lastActiveTs!==undefined){var duration=ts-thread.lastActiveTs;var value=thread.lastActiveValue;if(value==undefined)
+value=' ';var slice=new tr.model.Slice('',value,ColorScheme.getColorIdForGeneralPurposeString(value),thread.lastActiveTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastActiveTs=ts;thread.lastActiveValue=event[2];return true;},syncWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncWaitRE.exec(eventBase.details);if(!event)
+return false;if(eventBase.tgid===undefined){return false;}
+var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+var name='fence_wait("'+event[2]+'")';if(event[1]=='begin'){var slice=slices.beginSlice(null,name,ts,{'Start state':event[3]});}else if(event[1]=='end'){if(slices.openSliceCount>0){slices.endSlice(ts);}}else{return false;}
+return true;},syncPtEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncPtRE.exec(eventBase.details);if(!event)
+return false;return true;var thread=this.importer.getOrCreateKernelThread(eventBase[1]).thread;thread.syncWaitSyncPts[event[1]]=event[2];return true;}};Parser.register(SyncParser);return{SyncParser:SyncParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function WorkqueueParser(importer){Parser.call(this,importer);importer.registerEventHandler('workqueue_execute_start',WorkqueueParser.prototype.executeStartEvent.bind(this));importer.registerEventHandler('workqueue_execute_end',WorkqueueParser.prototype.executeEndEvent.bind(this));importer.registerEventHandler('workqueue_queue_work',WorkqueueParser.prototype.executeQueueWork.bind(this));importer.registerEventHandler('workqueue_activate_work',WorkqueueParser.prototype.executeActivateWork.bind(this));}
+var workqueueExecuteStartRE=/work struct (.+): function (\S+)/;var workqueueExecuteEndRE=/work struct (.+)/;WorkqueueParser.prototype={__proto__:Parser.prototype,executeStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteStartRE.exec(eventBase.details);if(!event)
+return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);kthread.openSliceTS=ts;kthread.openSlice=event[2];return true;},executeEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteEndRE.exec(eventBase.details);if(!event)
+return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);if(kthread.openSlice){var slice=new tr.model.Slice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,{},ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;return true;},executeQueueWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser:WorkqueueParser};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ClockSyncRecord=tr.ClockSyncRecord;function LinuxPerfImporter(model,events){this.importPriority=2;this.model_=model;this.events_=events;this.newlyAddedClockSyncRecords_=[];this.wakeups_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};}
+var TestExports={};var lineREWithTGID=new RegExp('^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithTGID=function(line){var groups=lineREWithTGID.exec(line);if(!groups){return groups;}
+var tgid=groups[3];if(tgid[0]==='-')
+tgid=undefined;return{threadName:groups[1],pid:groups[2],tgid:tgid,cpuNumber:groups[4],timestamp:groups[5],eventName:groups[6],details:groups[7]};};TestExports.lineParserWithTGID=lineParserWithTGID;var lineREWithIRQInfo=new RegExp('^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithIRQInfo=function(line){var groups=lineREWithIRQInfo.exec(line);if(!groups){return groups;}
+return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithIRQInfo=lineParserWithIRQInfo;var lineREWithLegacyFmt=/^\s*(.+)-(\d+)\s+\[(\d+)\]\s*(\d+\.\d+):\s+(\S+):\s(.*)$/;var lineParserWithLegacyFmt=function(line){var groups=lineREWithLegacyFmt.exec(line);if(!groups){return groups;}
+return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithLegacyFmt=lineParserWithLegacyFmt;var traceEventClockSyncRE=/trace_event_clock_sync: parent_ts=(\d+\.?\d*)/;TestExports.traceEventClockSyncRE=traceEventClockSyncRE;var realTimeClockSyncRE=/trace_event_clock_sync: realtime_ts=(\d+)/;var genericClockSyncRE=/trace_event_clock_sync: name=(\w+)/;var pseudoKernelPID=0;function autoDetectLineParser(line){if(line[0]=='{')
+return false;if(lineREWithTGID.test(line))
+return lineParserWithTGID;if(lineREWithIRQInfo.test(line))
+return lineParserWithIRQInfo;if(lineREWithLegacyFmt.test(line))
+return lineParserWithLegacyFmt;return null;};TestExports.autoDetectLineParser=autoDetectLineParser;LinuxPerfImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String))
+return false;if(LinuxPerfImporter._extractEventsFromSystraceHTML(events,false).ok)
+return true;if(LinuxPerfImporter._extractEventsFromSystraceMultiHTML(events,false).ok)
+return true;if(/^# tracer:/.test(events))
+return true;var lineBreakIndex=events.indexOf('\n');if(lineBreakIndex>-1)
+events=events.substring(0,lineBreakIndex);if(autoDetectLineParser(events))
+return true;return false;};LinuxPerfImporter._extractEventsFromSystraceHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
+produce_result=true;if(/^<!DOCTYPE html>/.test(incoming_events)==false)
+return failure;var r=new tr.importer.SimpleLineReader(incoming_events);if(!r.advanceToLineMatching(/^  <script>$/))
+return failure;if(!r.advanceToLineMatching(/^  var linuxPerfData = "\\$/))
+return failure;var events_begin_at_line=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))
+return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);if(!r.advanceToLineMatching(/^<\/body>$/))
+return failure;if(!r.advanceToLineMatching(/^<\/html>$/))
+return failure;function endsWith(str,suffix){return str.indexOf(suffix,str.length-suffix.length)!==-1;}
+function stripSuffix(str,suffix){if(!endsWith(str,suffix))
+return str;return str.substring(str,str.length-suffix.length);}
+var events=[];if(produce_result){for(var i=0;i<raw_events.length;i++){var event=raw_events[i];event=stripSuffix(event,'\\n\\');events.push(event);}}else{events=[raw_events[raw_events.length-1]];}
+var oldLastEvent=events[events.length-1];var newLastEvent=stripSuffix(oldLastEvent,'\\n";');if(newLastEvent==oldLastEvent)
+return failure;events[events.length-1]=newLastEvent;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};LinuxPerfImporter._extractEventsFromSystraceMultiHTML=function(incoming_events,produce_result){var failure={ok:false};if(produce_result===undefined)
+produce_result=true;if(new RegExp('^<!DOCTYPE HTML>','i').test(incoming_events)==false)
+return failure;var r=new tr.importer.SimpleLineReader(incoming_events);var events=[];while(!/^# tracer:/.test(events)){if(!r.advanceToLineMatching(/^  <script class="trace-data" type="application\/text">$/))
+return failure;var events_begin_at_line=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))
+return failure;events=r.endSavingLinesAndGetResult();events=events.slice(1,events.length-1);}
+if(!r.advanceToLineMatching(/^<\/body>$/))
+return failure;if(!r.advanceToLineMatching(/^<\/html>$/))
+return failure;return{ok:true,lines:produce_result?events:undefined,events_begin_at_line:events_begin_at_line};};LinuxPerfImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},buildMapFromLinuxPidsToThreads:function(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},getOrCreateCpu:function(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread:function(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
+return this.kernelThreadStates_[kernelThreadName];},getOrCreateBinderKernelThread:function(kernelThreadName,pid,tid){var key=kernelThreadName+pid+tid;if(!this.kernelThreadStates_[key]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[key]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
+return this.kernelThreadStates_[key];},getOrCreatePseudoThread:function(threadName){var thread=this.kernelThreadStates_[threadName];if(!thread){thread=this.getOrCreateKernelThread(threadName,pseudoKernelPID,this.pseudoThreadCounter);this.pseudoThreadCounter++;}
+return thread;},importEvents:function(isSecondaryImport){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines();this.importClockSyncRecords();var timeShift=this.computeTimeTransform();if(timeShift===undefined){this.model_.importWarning({type:'clock_sync',message:'Cannot import kernel trace without a clock sync.'});return;}
+this.shiftNewlyAddedClockSyncRecords(timeShift);this.importCpuData(timeShift);this.buildMapFromLinuxPidsToThreads();this.buildPerThreadCpuSlicesFromCpuState();this.computeCpuTimestampsForSlicesAsNeeded();},buildPerThreadCpuSlicesFromCpuState:function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(var cpuNumber in this.model_.kernel.cpus){var cpu=this.model_.kernel.cpus[cpuNumber];for(var i=0;i<cpu.slices.length;i++){var cpuSlice=cpu.slices[i];var thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)
+continue;cpuSlice.threadThatWasRunning=thread;if(!thread.tempCpuSlices)
+thread.tempCpuSlices=[];thread.tempCpuSlices.push(cpuSlice);}}
+for(var i in this.wakeups_){var wakeup=this.wakeups_[i];var thread=this.threadsByLinuxPid[wakeup.tid];if(!thread)
+continue;thread.tempWakeups=thread.tempWakeups||[];thread.tempWakeups.push(wakeup);}
+this.model_.getAllThreads().forEach(function(thread){if(thread.tempCpuSlices===undefined)
+return;var origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});var wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});var slices=[];if(origSlices.length){var slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){var wakeup=wakeups.shift();var wakeupDuration=slice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
+var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',slice.start,{},slice.duration);runningSlice.cpuOnWhichThreadWasRunning=slice.cpu;slices.push(runningSlice);}
+var wakeup=undefined;for(var i=1;i<origSlices.length;i++){var prevSlice=origSlices[i-1];var nextSlice=origSlices[i];var midDuration=nextSlice.start-prevSlice.end;while(wakeups.length&&wakeups[0].ts<nextSlice.start){var w=wakeups.shift();if(wakeup===undefined&&w.ts>prevSlice.end){wakeup=w;}}
+var pushSleep=function(state){if(wakeup!==undefined){midDuration=wakeup.ts-prevSlice.end;}
+slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,{},midDuration));if(wakeup!==undefined){var wakeupDuration=nextSlice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled=='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled=='R'||prevSlice.args.stateWhenDescheduled=='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled=='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',ioWaitId,prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled=='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled=='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
+prevSlice.args.stateWhenDescheduled});}
+var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',nextSlice.start,{},nextSlice.duration);runningSlice.cpuOnWhichThreadWasRunning=prevSlice.cpu;slices.push(runningSlice);}
+thread.timeSlices=slices;},this);},computeCpuTimestampsForSlicesAsNeeded:function(){},computeTimeTransform:function(){var isSecondaryImport=this.model.getClockSyncRecordsNamed('ftrace_importer').length!==0;var mSyncs=this.model_.getClockSyncRecordsNamed('monotonic');if(mSyncs.length==0)
+return isSecondaryImport?undefined:0;var sync=mSyncs[0].args;if(sync.parentTS==0||sync.parentTS==sync.perfTS)
+return 0;return sync.parentTS-sync.perfTS;},createParsers_:function(){var allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();var parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_:function(){this.registerEventHandler('tracing_mark_write',LinuxPerfImporter.prototype.traceMarkingWriteEvent.bind(this));this.registerEventHandler('0',LinuxPerfImporter.prototype.traceMarkingWriteEvent.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},registerEventHandler:function(eventName,handler){this.eventHandlers_[eventName]=handler;},markPidRunnable:function(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts:ts,tid:pid,fromTid:fromPid});},traceClockSyncEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){var name=event[1];var pieces=event[2].split(' ');var args={perfTS:ts};for(var i=0;i<pieces.length;i++){var parts=pieces[i].split('=');if(parts.length!=2)
+throw new Error('omgbbq');args[parts[0]]=parts[1];}
+this.addClockSyncRecord(new ClockSyncRecord(name,ts,args));return true;}
+event=/parent_ts=(\d+\.?\d*)/.exec(eventBase.details);if(!event)
+return false;this.addClockSyncRecord(new ClockSyncRecord('monotonic',ts,{perfTS:ts,parentTS:event[1]*1000}));return true;},traceMarkingWriteEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');var event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){var tag=eventBase.details.substring(0,2);if(tag=='B|'||tag=='E'||tag=='E|'||tag=='X|'||tag=='C|'||tag=='S|'||tag=='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
+var writeEventName=eventName+':'+eventBase.subEventName;var handler=this.eventHandlers_[writeEventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown trace_marking_write event '+writeEventName});return true;}
+return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importClockSyncRecords:function(){this.forEachLine(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0')
+return;if(traceEventClockSyncRE.exec(eventBase.details))
+this.traceClockSyncEvent(eventName,cpuNumber,pid,ts,eventBase);if(realTimeClockSyncRE.exec(eventBase.details)){var match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}
+if(genericClockSyncRE.exec(eventBase.details))
+this.traceClockSyncEvent(eventName,cpuNumber,pid,ts,eventBase);}.bind(this));},addClockSyncRecord:function(csr){this.newlyAddedClockSyncRecords_.push(csr);this.model_.clockSyncRecords.push(csr);},shiftNewlyAddedClockSyncRecords:function(timeShift){this.newlyAddedClockSyncRecords_.forEach(function(csr){csr.ts+=timeShift;});},importCpuData:function(timeShift){this.forEachLine(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;var handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
+ts+=timeShift;if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines:function(){var lines=[];var extractResult=LinuxPerfImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok)
+extractResult=LinuxPerfImporter._extractEventsFromSystraceMultiHTML(this.events_,true);var lines=extractResult.ok?extractResult.lines:this.events_.split('\n');var lineParser=null;for(var lineNumber=0;lineNumber<lines.length;++lineNumber){var line=lines[lineNumber].trim();if(line.length==0||/^#/.test(line))
+continue;if(lineParser==null){lineParser=autoDetectLineParser(line);if(lineParser==null){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});continue;}}
+var eventBase=lineParser(line);if(!eventBase){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});continue;}
+this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);}},forEachLine:function(handler){for(var i=0;i<this.lines_.length;++i){var line=this.lines_[i];handler.apply(this,line);}}};tr.importer.Importer.register(LinuxPerfImporter);return{LinuxPerfImporter:LinuxPerfImporter,_LinuxPerfImporterTestExports:TestExports};});'use strict';tr.exportTo('tr.b.u',function(){function TimeDuration(duration){tr.b.u.Scalar.call(this,duration,tr.b.u.Units.timeDurationInMs);};TimeDuration.prototype={__proto__:tr.b.u.Scalar.prototype,get duration(){return this.value;}};TimeDuration.format=function(duration){return tr.b.u.Units.timeDurationInMs.format(duration);};return{TimeDuration:TimeDuration};});'use strict';tr.exportTo('tr.b',function(){function convertEventsToRanges(events){return events.map(function(event){return tr.b.Range.fromExplicitRange(event.start,event.end);});}
+function mergeRanges(inRanges,mergeThreshold,mergeFunction){var remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){var merged=[];if(remainingEvents.length==1){merged.push(mergeFunction(remainingEvents));}
+return merged;}
+var mergedEvents=[];var currentMergeBuffer=[];var rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
+function flushCurrentMergeBuffer(){if(currentMergeBuffer.length==0)
+return;mergedEvents.push(mergeFunction(currentMergeBuffer));currentMergeBuffer=[];if(remainingEvents.length!=0)
+beginMerging();}
+beginMerging();while(remainingEvents.length){var currentEvent=remainingEvents[0];var distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
+flushCurrentMergeBuffer();}
+flushCurrentMergeBuffer();return mergedEvents;}
+function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)
+opt_totalRange=undefined;var emptyRanges=[];if(!inRanges.length){if(opt_totalRange)
+emptyRanges.push(opt_totalRange);return emptyRanges;}
+inRanges=inRanges.slice();inRanges.sort(function(x,y){return x.min-y.min;});if(opt_totalRange&&(opt_totalRange.min<inRanges[0].min)){emptyRanges.push(tr.b.Range.fromExplicitRange(opt_totalRange.min,inRanges[0].min));}
+inRanges.forEach(function(range,index){for(var otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)
+continue;var other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,other.min));return;}
+if(other.max>range.max){return;}}
+if(opt_totalRange&&(range.max<opt_totalRange.max)){emptyRanges.push(tr.b.Range.fromExplicitRange(range.max,opt_totalRange.max));}});return emptyRanges;}
+return{convertEventsToRanges:convertEventsToRanges,findEmptyRangesBetweenRanges:findEmptyRangesBetweenRanges,mergeRanges:mergeRanges};});'use strict';tr.exportTo('tr.e.audits',function(){var Frame=tr.model.Frame;var Statistics=tr.b.Statistics;var UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};var UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};var RENDER_THREAD_DRAW_NAME='DrawFrame';var RENDER_THREAD_INDEP_DRAW_NAME='doFrame';var THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){var ret=[];threadTimeRanges.forEach(function(threadTimeRange){var slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
+function makeFrame(threadTimeRanges,surfaceFlinger){var args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){var start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args['deadline']=surfaceFlinger.getFrameDeadline(start);args['frameKickoff']=surfaceFlinger.getFrameKickoff(start);}
+var events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
+function findOverlappingDrawFrame(renderThread,time){if(!renderThread)
+return undefined;var slices=renderThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){var slice=slices[i];if(slice.title==RENDER_THREAD_DRAW_NAME&&slice.start<=time&&time<=slice.end){return slice;}}
+return undefined;}
+function getPreTraversalWorkRanges(uiThread){if(!uiThread)
+return[];var preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title=='obtainView'||slice.title=='setupListItem'||slice.title=='deliverInputEvent'||slice.title=='RV Scroll')
+preFrameEvents.push(slice);});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title=='deliverInputEvent')
+preFrameEvents.push(slice);});return tr.b.mergeRanges(tr.b.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
+function getFrameStartTime(traversalStart,preTraversalWorkRanges){var preTraversalWorkRange=tr.b.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start},function(range){return range.end},traversalStart,3);if(preTraversalWorkRange)
+return preTraversalWorkRange.start;return traversalStart;}
+function getUiThreadDrivenFrames(app){if(!app.uiThread)
+return[];var preTraversalWorkRanges=[];if(app.uiDrawType==UI_DRAW_TYPE.LEGACY)
+preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);var frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
+var threadTimeRanges=[];var uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);var rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice.end);if(rtDrawSlice){var rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
+threadTimeRanges.push({thread:app.renderThread,start:rtDrawSlice.start,end:rtDrawSlice.end});}
+frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getRenderThreadDrivenFrames(app){if(!app.renderThread)
+return[];var frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){var threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getUiDrawType(uiThread){if(!uiThread)
+return UI_DRAW_TYPE.NONE;var slices=uiThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
+return UI_DRAW_TYPE.NONE;}
+function getInputSamples(process){var samples=undefined;for(var counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries==1){samples=process.counters[counterName].series[0].samples;break;}}
+if(!samples)
+return[];var inputSamples=[];var lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
+lastValue=sample.value;});return inputSamples;}
+function getAnimationAsyncSlices(uiThread){if(!uiThread)
+return[];var slices=[];uiThread.asyncSliceGroup.iterateAllEvents(function(slice){if(/^animator\:/.test(slice.title))
+slices.push(slice);});return slices;}
+function AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType){this.process=process;this.uiThread=uiThread;this.renderThread=renderThread;this.surfaceFlinger=surfaceFlinger;this.uiDrawType=uiDrawType;this.frames_=undefined;this.inputs_=undefined;};AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){var uiThread=process.getThread(process.pid);var uiDrawType=getUiDrawType(uiThread);if(uiDrawType==UI_DRAW_TYPE.NONE){uiThread=undefined;}
+var renderThreads=process.findAllThreadsNamed('RenderThread');var renderThread=renderThreads.length==1?renderThreads[0]:undefined;if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}}
+AndroidApp.prototype={getFrames:function(){if(!this.frames_){var uiFrames=getUiThreadDrivenFrames(this);var rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end});}
+return this.frames_;},getInputSamples:function(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
+return this.inputs_;},getAnimationAsyncSlices:function(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
+return this.animations_;}};return{AndroidApp:AndroidApp};});'use strict';tr.exportTo('tr.e.audits',function(){var findLowIndexInSortedArray=tr.b.findLowIndexInSortedArray;var VSYNC_SF_NAME='android.VSYNC-sf';var VSYNC_APP_NAME='android.VSYNC-app';var VSYNC_FALLBACK_NAME='android.VSYNC';var TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){var vsync=process.counters[counterName];if(!vsync)
+vsync=process.counters[VSYNC_FALLBACK_NAME];if(vsync&&vsync.numSeries==1&&vsync.numSamples>1)
+return vsync.series[0].timestamps;return undefined;}
+function AndroidSurfaceFlinger(process,thread){this.process=process;this.thread=thread;this.appVsync_=undefined;this.sfVsync_=undefined;this.appVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_APP_NAME);this.sfVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_SF_NAME);};AndroidSurfaceFlinger.createForProcessIfPossible=function(process){var mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name))
+return new AndroidSurfaceFlinger(process,mainThread);var primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length==1)
+return new AndroidSurfaceFlinger(process,primaryThreads[0]);return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff:function(timestamp){if(!this.hasVsyncs)
+throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)
+return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline:function(timestamp){if(!this.hasVsyncs)
+throw new Error('cannot query vsync info without vsyncs');var firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length)
+return undefined;return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger:AndroidSurfaceFlinger};});'use strict';tr.exportTo('tr.e.audits',function(){var AndroidApp=tr.e.audits.AndroidApp;var AndroidSurfaceFlinger=tr.e.audits.AndroidSurfaceFlinger;var IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};var IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};var IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)
+return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important)
+callback(slice);});}
+function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;var processes=model.getAllProcesses();for(var i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
+model.getAllProcesses().forEach(function(process){var app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app)
+this.apps.push(app);},this);};AndroidModelHelper.prototype={iterateImportantSlices:function(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
+this.apps.forEach(function(app){iterateImportantThreadSlices(app.uiThread,IMPORTANT_UI_THREAD_SLICES,callback);iterateImportantThreadSlices(app.renderThread,IMPORTANT_RENDER_THREAD_SLICES,callback);});}};return{AndroidModelHelper:AndroidModelHelper};});'use strict';tr.exportTo('tr.e.audits',function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.e.audits.AndroidModelHelper;var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.Statistics;var FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;var InteractionRecord=tr.model.InteractionRecord;var Alert=tr.model.Alert;var EventInfo=tr.model.EventInfo;var TimeDuration=tr.b.u.TimeDuration;var EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
+function getDuration(e){return e.duration;}
+function getCpuDuration(e){return(e.cpuDuration!==undefined)?e.cpuDuration:e.duration;}
+function frameIsActivityStart(frame){for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='activityStart')
+return true;}
+return false;}
+var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.e.audits.AndroidModelHelper;function frameMissedDeadline(frame){return frame.args['deadline']&&frame.args['deadline']<frame.end;}
+function DocLinkBuilder(){this.docLinks=[];}
+DocLinkBuilder.prototype={addAppVideo:function(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef:function(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build:function(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);var helper=new AndroidModelHelper(model);if(helper.apps.length||helper.surfaceFlinger)
+this.helper=helper;};AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){var badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;var saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;var ret=[];var events=[];frame.associatedEvents.forEach(function(slice){var match=badAlphaRegEx.exec(slice.title);if(match){var args={'view name':match[1],width:parseInt(match[3]),height:parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title))
+events.push(slice);},this);if(events.length>ret.length){var unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});var clippedSeen=events.length-unclippedSeen;var earliestStart=Statistics.min(events,function(slice){return slice.start;});var args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
+return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){var uploadRegEx=/^Generate Path Texture$/;var events=frame.associatedEvents.filter(function(event){return event.title=='Generate Path Texture';});var start=Statistics.min(events,getStart);var duration=Statistics.sum(events,getDuration);if(duration<3)
+return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new TimeDuration(duration)});}
+AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){var uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;var events=[];var start=Number.POSITIVE_INFINITY;var duration=0;var pixelsUploaded=0;frame.associatedEvents.forEach(function(event){var match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length==0||duration<3)
+return undefined;var mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';var args={'Pixels uploaded':mPixels,'Time spent':new TimeDuration(duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);}
+AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='obtainView'||event.title=='setupListItem';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
+return undefined;var hasInflation=false;for(var i=0;i<events.length;i++){if(events[i]instanceof tr.model.Slice&&events[i].findDescendentSlice('inflate')){hasInflation=true;break;}}
+var start=Statistics.min(events,getStart);var args={'Time spent':new TimeDuration(duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;var eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);}
+AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='measure'||event.title=='layout';});var duration=Statistics.sum(events,getCpuDuration);if(events.length==0||duration<3)
+return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new TimeDuration(duration)});}
+AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){var slice=undefined;for(var i=0;i<frame.associatedEvents.length;i++){if(frame.associatedEvents[i].title=='getDisplayList'||frame.associatedEvents[i].title=='Record View#draw()'){slice=frame.associatedEvents[i];break;}}
+if(!slice||getCpuDuration(slice)<3)
+return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new TimeDuration(getCpuDuration(slice))});}
+AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title=='DVM Suspend'||event.title=='GC: Wait For Concurrent';});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)
+return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new TimeDuration(blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)
+return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new TimeDuration(blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){var totalDuration=0;var totalStats={};frame.threadTimeRanges.forEach(function(ttr){var stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);tr.b.iterItems(stats,function(key,value){if(!(key in totalStats))
+totalStats[key]=0;totalStats[key]+=value;totalDuration+=value;});});if(!(SCHEDULING_STATE.RUNNING in totalStats)||totalDuration==0||totalDuration-totalStats[SCHEDULING_STATE.RUNNING]<3)
+return;var args={};tr.b.iterItems(totalStats,function(key,value){if(key===SCHEDULING_STATE.RUNNABLE)
+key='Not scheduled, but runnable';else if(key===SCHEDULING_STATE.UNINTR_SLEEP)
+key='Blocking I/O delay';args[key]=new TimeDuration(value);});return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_:function(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process==this.helper.surfaceFlinger.process){if(!process.name)
+process.name='SurfaceFlinger';process.sortIndex=Number.NEGATIVE_INFINITY;process.important=false;return;}
+var uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name))
+uiThread.name='a'+uiThread.name;process.name=uiThread.name;uiThread.name='UI Thread';}
+process.sortIndex=0;for(var tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid==thread.parent.pid)
+thread.sortIndex=-3;if(thread.name=='RenderThread')
+thread.sortIndex=-2;if(/^hwuiTask/.test(thread.name))
+thread.sortIndex=-1;});},pushFramesAndJudgeJank_:function(){var badFramesObserved=0;var framesObserved=0;var surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){var portionBad=badFramesObserved/framesObserved;if(portionBad>0.3)
+this.model.faviconHue='red';else if(portionBad>0.05)
+this.model.faviconHue='yellow';else
+this.model.faviconHue='green';}},pushEventInfo_:function(){var appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread)
+appAnnotator.applyEventInfos(app.uiThread.sliceGroup);if(app.renderThread)
+appAnnotator.applyEventInfos(app.renderThread.sliceGroup);});},runAnnotate:function(){if(!this.helper)
+return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit:function(){if(!this.helper)
+return;var alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass==FRAME_PERF_CLASS.NEUTRAL||frame.perfClass==FRAME_PERF_CLASS.GOOD)
+return;var alert=AndroidAuditor.getPathAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getUploadAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getListViewAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)
+alerts.push(alert);var alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)
+alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords:function(){var events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});var mergerFunction=function(events){var ir=new InteractionRecord(this.model,'Rendering',ColorScheme.getColorIdForGeneralPurposeString('mt_rendering'),events[0].min,events[events.length-1].max-events[0].min);this.model.addInteractionRecord(ir);}.bind(this);tr.b.mergeRanges(tr.b.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords:function(){var inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});var mergerFunction=function(events){var ir=new InteractionRecord(this.model,'Input',ColorScheme.getColorIdForGeneralPurposeString('mt_input'),events[0].min,events[events.length-1].max-events[0].min);this.model.addInteractionRecord(ir);}.bind(this);var inputRanges=inputSamples.map(function(sample){return tr.b.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup={};this.titleParentLookup={};this.build_();}
+AppAnnotator.prototype={build_:function(){var registerEventInfo=function(dict){this.titleInfoLookup[dict.title]=new EventInfo(dict.title,dict.description,dict.docLinks);if(dict.parents)
+this.titleParentLookup[dict.title]=dict.parents;}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});var choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});var traversalParents=['Choreographer#doFrame','performTraversals'];var layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});var drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});var recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_:function(parentNames,slice){var checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)
+return true;return expectedParentNames.some(function(name){return name in parentNames;});}
+if(slice.title in this.titleInfoLookup){if(checkExpectedParentNames(this.titleParentLookup[slice.title]))
+slice.info=this.titleInfoLookup[slice.title];}
+if(slice.subSlices.length>0){if(!(slice.title in parentNames))
+parentNames[slice.title]=0;parentNames[slice.title]++;slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames[slice.title]--;if(parentNames[slice.title]==0)
+delete parentNames[slice.title];}},applyEventInfos:function(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_({},slice);},this);}};return{AndroidAuditor:AndroidAuditor};});'use strict';tr.exportTo('tr.e.audits',function(){var VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};var VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};var BEGIN_FRAME_SLICE_PRECISION={'Scheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);};VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate:function(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps:function(model){var times=[];var maxPrecision=Number.NEGATIVE_INFINITY;var maxTitle=undefined;function useInstead(title,precisions){var precision=precisions[title];if(precision===undefined)
+return false;if(title===maxTitle)
+return true;if(precision<=maxPrecision){if(precision===maxPrecision){console.warn('Encountered two different VSync events ('+
+maxTitle+', '+title+') with the same precision, '+'ignoring the newer one ('+title+')');}
+return false;}
+maxPrecision=precision;maxTitle=title;times=[];return true;}
+for(var pid in model.processes){var process=model.processes[pid];for(var cid in process.counters){if(useInstead(cid,VSYNC_COUNTER_PRECISIONS)){var counter=process.counters[cid];for(var i=0;i<counter.series.length;i++){var series=counter.series[i];Array.prototype.push.apply(times,series.timestamps);}}}
+for(var tid in process.threads){var thread=process.threads[tid];for(var i=0;i<thread.sliceGroup.slices.length;i++){var slice=thread.sliceGroup.slices[i];if(useInstead(slice.title,VSYNC_SLICE_PRECISIONS))
+times.push(slice.start);else if(useInstead(slice.title,BEGIN_FRAME_SLICE_PRECISION)&&slice.args.args&&slice.args.args.frame_time_us)
+times.push(slice.args.args.frame_time_us/1000.0);}}}
+times.sort(function(x,y){return x-y;});return times;}};tr.c.Auditor.register(VSyncAuditor);return{VSyncAuditor:VSyncAuditor};});'use strict';tr.exportTo('tr.b',function(){var tmpVec2s=[];for(var i=0;i<8;i++)
+tmpVec2s[i]=vec2.create();var tmpVec2a=vec4.create();var tmpVec4a=vec4.create();var tmpVec4b=vec4.create();var tmpMat4=mat4.create();var tmpMat4b=mat4.create();var p00=vec2.createXY(0,0);var p10=vec2.createXY(1,0);var p01=vec2.createXY(0,1);var p11=vec2.createXY(1,1);var lerpingVecA=vec2.create();var lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
+function Quad(){this.p1=vec2.create();this.p2=vec2.create();this.p3=vec2.create();this.p4=vec2.create();}
+Quad.fromXYWH=function(x,y,w,h){var q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;}
+Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);}
+Quad.from4Vecs=function(p1,p2,p3,p4){var q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;}
+Quad.from8Array=function(arr){if(arr.length!=8)
+throw new Error('Array must be 8 long');var q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside:function(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect:function(){var x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);var x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone:function(){var q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale:function(s){var q=new Quad();this.scaleFast(q,s);return q;},scaleFast:function(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle:function(){var bounds=this.boundingRect();return(bounds.x==this.p1[0]&&bounds.y==this.p1[1]&&bounds.width==this.p2[0]-this.p1[0]&&bounds.y==this.p2[1]&&bounds.width==this.p3[0]-this.p1[0]&&bounds.height==this.p3[1]-this.p2[1]&&bounds.x==this.p4[0]&&bounds.height==this.p4[1]-this.p2[1]);},projectUnitRect:function(rect){var q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast:function(dstQuad,rect){var v12=tmpVec2s[0];var v14=tmpVec2s[1];var v23=tmpVec2s[2];var v43=tmpVec2s[3];var l12,l14,l23,l43;vec2.sub(v12,this.p2,this.p1);l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);var b12=tmpVec2s[0];var b14=tmpVec2s[1];var b23=tmpVec2s[2];var b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString:function(){return'Quad('+
+vec2.toString(this.p1)+', '+
+vec2.toString(this.p2)+', '+
+vec2.toString(this.p3)+', '+
+vec2.toString(this.p4)+')';}};function sign(p1,p2,p3){return(p1[0]-p3[0])*(p2[1]-p3[1])-
+(p2[0]-p3[0])*(p1[1]-p3[1]);}
+function pointInTriangle2(pt,p1,p2,p3){var b1=sign(pt,p1,p2)<0.0;var b2=sign(pt,p2,p3)<0.0;var b3=sign(pt,p3,p1)<0.0;return((b1==b2)&&(b2==b3));}
+function pointInImplicitQuad(point,p1,p2,p3,p4){return pointInTriangle2(point,p1,p2,p3)||pointInTriangle2(point,p1,p3,p4);}
+return{pointInTriangle2:pointInTriangle2,pointInImplicitQuad:pointInImplicitQuad,Quad:Quad};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
+SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)
+return undefined;var domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString:function(){var str='';if(this.file_)
+str+=this.file_;if(this.line_>0)
+str+=':'+this.line_;if(this.column_>0)
+str+=':'+this.column_;return str;}};return{SourceInfo:SourceInfo};});'use strict';tr.exportTo('tr.model.source_info',function(){function JSSourceInfo(file,line,column,isNative,scriptId,state){tr.model.source_info.SourceInfo.call(this,file,line,column);this.isNative_=isNative;this.scriptId_=scriptId;this.state_=state;}
+JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString:function(){var str=this.isNative_?'[native v8] ':'';return str+
+tr.model.source_info.SourceInfo.prototype.toString.call(this);}};return{JSSourceInfo:JSSourceInfo,JSSourceState:{COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown'}};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocate();this.address_=address;this.size_=size;var rePrefix=/^(\w*:)?([*~]?)(.*)$/m;var tokens=rePrefix.exec(name);var prefix=tokens[1];var state=tokens[2];var body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{console.warning('Unknown v8 code state '+state);state=tr.model.source_info.JSSourceState.UNKNOWN;}
+var rawName;var rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{var spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
+function splitLineAndColumn(url){var lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;var lineColumnMatch=lineColumnRegEx.exec(url);var lineNumber;var columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
+if(typeof(lineColumnMatch[2])==='string'){columnNumber=parseInt(lineColumnMatch[2],10);columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;}
+return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber:lineNumber,columnNumber:columnNumber};}
+var nativeSuffix=' native';var isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;var urlData=splitLineAndColumn(rawUrl);var url=urlData.url||'';var line=urlData.lineNumber||0;var column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);};TraceCodeEntry.prototype={get id(){return this.id_;},get sourceInfo(){return this.sourceInfo_;},get name(){return this.name_;},set address(address){this.address_=address;},get address(){return this.address_;},set size(size){this.size_=size;},get size(){return this.size_;}};return{TraceCodeEntry:TraceCodeEntry};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeMap(){this.banks_=new Map();}
+TraceCodeMap.prototype={addEntry:function(addressHex,size,name,scriptId){var entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry:function(oldAddressHex,newAddressHex,size){var entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)
+return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry:function(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_:function(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_:function(addressHex){var bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_:function(addressHex){addressHex=addressHex.slice(2);var bankSizeHexDigits=13;var maxHexDigits=16;var bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);var bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
+return bank;}};function TraceCodeBank(){this.entries_=[];}
+TraceCodeBank.prototype={removeEntry:function(address){if(this.entries_.length===0)
+return undefined;var index=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);var entry=this.entries_[index];if(!entry||entry.address!==address)
+return undefined;this.entries_.splice(index,1);return entry;},lookupEntry:function(address){var index=tr.b.findHighIndexInSortedArray(this.entries_,function(e){return address-e.address;})-1;var entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry:function(newEntry){if(this.entries_.length===0)
+this.entries_.push(newEntry);var endAddress=newEntry.address+newEntry.size;var lastIndex=tr.b.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);var index;for(index=lastIndex-1;index>=0;--index){var entry=this.entries_[index];var entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)
+break;}
+++index;this.entries_.splice(index,lastIndex-index,newEntry);}};return{TraceCodeMap:TraceCodeMap};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){};SplayTree.prototype.root_=null;SplayTree.prototype.isEmpty=function(){return!this.root_;};SplayTree.prototype.insert=function(key,value){if(this.isEmpty()){this.root_=new SplayTree.Node(key,value);return;}
+this.splay_(key);if(this.root_.key==key){return;}
+var node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
+this.root_=node;};SplayTree.prototype.remove=function(key){if(this.isEmpty()){throw Error('Key not found: '+key);}
+this.splay_(key);if(this.root_.key!=key){throw Error('Key not found: '+key);}
+var removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{var right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
+return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty()){return null;}
+this.splay_(key);return this.root_.key==key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty()){return null;}
+var current=this.root_;while(current.left){current=current.left;}
+return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty()){return null;}
+var current=opt_startNode||this.root_;while(current.right){current=current.right;}
+return current;};SplayTree.prototype.findGreatestLessThan=function(key){if(this.isEmpty()){return null;}
+this.splay_(key);if(this.root_.key<=key){return this.root_;}else if(this.root_.left){return this.findMax(this.root_.left);}else{return null;}};SplayTree.prototype.exportKeysAndValues=function(){var result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){var result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty()){return;}
+var dummy,left,right;dummy=left=right=new SplayTree.Node(null,null);var current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
+if(key<current.left.key){var tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
+right.left=current;right=current;current=current.left;}else if(key>current.key){if(!current.right){break;}
+if(key>current.right.key){var tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
+left.right=current;left=current;current=current.right;}else{break;}}
+left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){var nodesToVisit=[this.root_];while(nodesToVisit.length>0){var node=nodesToVisit.shift();if(node==null){continue;}
+f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree:SplayTree};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];};CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){var removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){var removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(var addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){var to_delete=[];var addr=end-1;while(addr>=start){var node=tree.findGreatestLessThan(addr);if(!node)break;var start2=node.key,end2=start2+node.value.size;if(start2<end&&start<end2)to_delete.push(start2);addr=start2-1;}
+for(var i=0,l=to_delete.length;i<l;++i)tree.remove(to_delete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){var node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntry=function(addr){var pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
+var min=this.dynamics_.findMin();var max=this.dynamics_.findMax();if(max!=null&&addr<(max.key+max.value.size)&&addr>=min.key){var dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry==null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
+return dynaEntry;}
+return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){var node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeEntry=function(size,opt_name){this.id=tr.b.GUID.allocate();this.size=size;this.name=opt_name||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype.getName=function(){return this.name;};CodeMap.CodeEntry.prototype.toString=function(){return this.name+': '+this.size.toString(16);};CodeMap.NameGenerator=function(){this.knownNames_={};};CodeMap.NameGenerator.prototype.getName=function(name){if(!(name in this.knownNames_)){this.knownNames_[name]=0;return name;}
+var count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap:CodeMap};});'use strict';tr.exportTo('tr.model',function(){function YComponent(stableId,yPercentOffset){this.stableId=stableId;this.yPercentOffset=yPercentOffset;}
+YComponent.prototype={toDict:function(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;};Location.fromViewCoordinates=function(viewport,viewX,viewY){var dt=viewport.currentDisplayTransform;var xWorld=dt.xViewToWorld(viewX);var yComponents=[];var elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+elem=elem.parentElement;}
+if(yComponents.length==0)
+return;return new Location(xWorld,yComponents);}
+Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){var xWorld=ts;var yComponents=[];var containerToTrack=viewport.containerToTrackMap;var elem=containerToTrack.getTrackByStableId(stableId);if(!elem)
+return;var firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+elem=elem.parentElement;}
+if(yComponents.length==0)
+return;return new Location(xWorld,yComponents);}
+Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack:function(viewport){var containerToTrack=viewport.containerToTrackMap;for(var i in this.yComponents_){var yComponent=this.yComponents_[i];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)
+return track;}},toViewCoordinates:function(viewport){var dt=viewport.currentDisplayTransform;var containerToTrack=viewport.containerToTrackMap;var viewX=dt.xWorldToView(this.xWorld_);var viewY=-1;for(var index in this.yComponents_){var yComponent=this.yComponents_[index];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){var boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
+return{viewX:viewX,viewY:viewY};},toDict:function(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location:Location};});'use strict';tr.exportTo('tr.model',function(){function Annotation(){this.guid_=tr.b.GUID.allocate();this.view_=undefined;};Annotation.fromDictIfPossible=function(args){if(args.typeName===undefined)
+throw new Error('Missing typeName argument');var typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)
+return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');}
+Annotation.prototype={get guid(){return this.guid_;},onRemove:function(){},toDict:function(){throw new Error('Not implemented');},getOrCreateView:function(viewport){if(!this.view_)
+this.view_=this.createView_(viewport);return this.view_;},createView_:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict'))
+throw new Error('Must have fromDict method');if(!e.typeInfo.metadata.typeName)
+throw new Error('Registered Annotations must provide typeName');});return{Annotation:Annotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
+AnnotationView.prototype={draw:function(ctx){throw new Error('Not implemented');}};return{AnnotationView:AnnotationView};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);var endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);var startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;var sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
+ctx.fillStyle=this.annotation_.fillStyle;ctx.fillRect(startCoords.viewX,startY,endCoords.viewX-startCoords.viewX,sizeY);}};return{RectAnnotationView:RectAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function RectAnnotation(start,end){tr.model.Annotation.apply(this,arguments);this.startLocation_=start;this.endLocation_=end;this.fillStyle='rgba(255, 180, 0, 0.3)';}
+RectAnnotation.fromDict=function(dict){var args=dict.args;var startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);var endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);}
+RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict:function(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation:RectAnnotation};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
+CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea:function(){this.textArea_.parentNode.removeChild(this.textArea_);},draw:function(ctx){var coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_)
+this.textArea_.style.visibility='hidden';return;}
+if(!this.textArea_){this.textArea_=document.createElement('textarea');this.textArea_.style.position='absolute';this.textArea_.readOnly=true;this.textArea_.value=this.annotation_.text;this.textArea_.style.zIndex=1;ctx.canvas.parentNode.appendChild(this.textArea_);}
+this.textArea_.style.width=this.styleWidth+'px';this.textArea_.style.height=this.styleHeight+'px';this.textArea_.style.fontSize=this.fontSize+'px';this.textArea_.style.visibility='visible';this.textArea_.style.left=coords.viewX+ctx.canvas.getBoundingClientRect().left+
+this.rightOffset+'px';this.textArea_.style.top=coords.viewY-ctx.canvas.getBoundingClientRect().top-
+this.topOffset+'px';ctx.strokeStyle='rgb(0, 0, 0)';ctx.lineWidth=2;ctx.beginPath();tr.ui.b.drawLine(ctx,coords.viewX,coords.viewY-ctx.canvas.getBoundingClientRect().top,coords.viewX+this.rightOffset,coords.viewY-this.topOffset-
+ctx.canvas.getBoundingClientRect().top);ctx.stroke();}};return{CommentBoxAnnotationView:CommentBoxAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function CommentBoxAnnotation(location,text){tr.model.Annotation.apply(this,arguments);this.location=location;this.text=text;}
+CommentBoxAnnotation.fromDict=function(dict){var args=dict.args;var location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove:function(){this.view_.removeTextArea();},toDict:function(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation:CommentBoxAnnotation};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,size){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.size=size;}
+function HeapDump(processMemoryDump,allocatorName){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.entries=[];}
+HeapDump.prototype={addEntry:function(leafStackFrame,size){var entry=new HeapEntry(this,leafStackFrame,size);this.entries.push(entry);return entry;}};return{HeapEntry:HeapEntry,HeapDump:HeapDump};});'use strict';tr.exportTo('tr.ui.annotations',function(){function XMarkerAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView:XMarkerAnnotationView};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
+XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);}
+XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict:function(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_:function(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation:XMarkerAnnotation};});'use strict';tr.exportTo('tr.e.importer',function(){var deepCopy=tr.b.deepCopy;var ColorScheme=tr.b.ColorScheme;function getEventColor(event,opt_customName){if(event.cname)
+return ColorScheme.getColorIdForReservedName(event.cname);else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
+var timestampFromUs=tr.b.u.Units.timestampFromUs;var maybeTimestampFromUs=tr.b.u.Units.maybeTimestampFromUs;var PRODUCER='producer';var CONSUMER='consumer';var STEP='step';function TraceEventImporter(model,eventData){this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.systemTraceEvents_=undefined;this.battorData_=undefined;this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.allMemoryDumpEvents_={};if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']')
+eventData=eventData+']';}
+this.events_=JSON.parse(eventData);this.eventsWereFromString_=true;}else{this.events_=eventData;}
+this.traceAnnotations_=this.events_.traceAnnotations;if(this.events_.traceEvents){var container=this.events_;this.events_=this.events_.traceEvents;this.systemTraceEvents_=container.systemTraceEvents;this.battorData_=container.battorLogAsString;this.sampleEvents_=container.samples;this.stackFrameEvents_=container.stackFrames;if(container.displayTimeUnit){var unitName=container.displayTimeUnit;var unit=tr.b.u.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
+this.model_.intrinsicTimeUnit=unit;}
+var knownFieldNames={battorLogAsString:true,samples:true,stackFrames:true,systemTraceEvents:true,traceAnnotations:true,traceEvents:true};for(var fieldName in container){if(fieldName in knownFieldNames)
+continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});}}}
+TraceEventImporter.canImport=function(eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
+if(eventData instanceof Array&&eventData.length&&eventData[0].ph)
+return true;if(eventData.traceEvents){if(eventData.traceEvents instanceof Array){if(eventData.traceEvents.length&&eventData.traceEvents[0].ph)
+return true;if(eventData.samples.length&&eventData.stackFrames!==undefined)
+return true;}}
+return false;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,extractSubtraces:function(){var systemEventsTmp=this.systemTraceEvents_;var battorDataTmp=this.battorData_;this.systemTraceEvents_=undefined;this.battorData_=undefined;var subTraces=systemEventsTmp?[systemEventsTmp]:[];if(battorDataTmp)
+subTraces.push(battorDataTmp);return subTraces;},deepCopyIfNeeded_:function(obj){if(obj===undefined)
+obj={};if(this.eventsWereFromString_)
+return obj;return deepCopy(obj);},deepCopyAlways_:function(obj){if(obj===undefined)
+obj={};return deepCopy(obj);},processAsyncEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event:event,thread:thread});},processFlowEvent:function(event,opt_slice){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastGuid(),sequenceNumber:this.allFlowEvents_.length,event:event,slice:opt_slice,thread:thread});},processCounterEvent:function(event){var ctr_name;if(event.id!==undefined)
+ctr_name=event.name+'['+event.id+']';else
+ctr_name=event.name;var ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctr_name);var reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(var seriesName in event.args){var colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
+if(ctr.numSeries===0){this.model_.importWarning({type:'counter_parse_error',message:'Expected counter '+event.name+' to have at least one argument to use as a value.'});delete ctr.parent.counters[ctr.name];return;}}
+var ts=timestampFromUs(event.ts);ctr.series.forEach(function(series){var val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event:event,thread:thread});},processDurationEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var ts=timestampFromUs(event.ts);if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
+if(event.ph==='B'){var slice=thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));slice.startStackFrame=this.getStackFrameForEvent_(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t')
+throw new Error('This should never happen');thread.sliceGroup.beginSlice(event.cat,event.name,timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args),timestampFromUs(event.tts),event.argsStripped,getEventColor(event));var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
+var slice=thread.sliceGroup.endSlice(timestampFromUs(event.ts),timestampFromUs(event.tts),getEventColor(event));if(event.name&&slice.title!=event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+slice.title+' in openSlice, and is '+
+event.name+' in endSlice'});}
+slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_:function(dstArgs,srcArgs,eventName){for(var arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
+dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent:function(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1)
+return undefined;var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in)
+event.flowPhase=STEP;else
+event.flowPhase=PRODUCER;}else if(event.flow_in){event.flowPhase=CONSUMER;}
+var slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,timestampFromUs(event.ts),maybeTimestampFromUs(event.dur),maybeTimestampFromUs(event.tts),maybeTimestampFromUs(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);return slice;},processMetadataEvent:function(event){if(event.argsStripped)
+return;if(event.name==='process_name'){var process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){var process=this.model_.getOrCreateProcess(event.pid);var labels=event.args.labels.split(',');for(var i=0;i<labels.length;i++)
+process.addLabelIfNeeded(labels[i]);}else if(event.name==='process_sort_index'){var process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){var n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined)
+n=Math.max(n,this.softwareMeasuredCpuCount_);this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){var stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':',true);}}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processJitCodeEvent:function(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined)
+this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();var map=this.v8ProcessCodeMaps_[event.pid];var data=event.args.data;if(event.name==='JitCodeMoved')
+map.moveEntry(data.code_start,data.new_code_start,data.code_len);else
+map.addEntry(data.code_start,data.code_len,data.name,data.script_id);},processInstantEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.processJitCodeEvent(event);return;}
+if(event.s==='t'||event.s===undefined){this.processDurationEvent(event);return;}
+var constructor;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;break;case'p':constructor=tr.model.ProcessInstantEvent;break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
+var instantEvent=new constructor(event.cat,event.name,getEventColor(event),timestampFromUs(event.ts),this.deepCopyIfNeeded_(event.args));switch(instantEvent.type){case tr.model.InstantEventType.GLOBAL:this.model_.pushInstantEvent(instantEvent);break;case tr.model.InstantEventType.PROCESS:var process=this.model_.getOrCreateProcess(event.pid);process.pushInstantEvent(instantEvent);break;default:throw new Error('Unknown instant event type: '+event.s);}},processV8Sample:function(event){var data=event.args.data;if(data.vm_state==='js'&&!data.stack.length)
+return;var rootStackFrame=this.v8ProcessRootStackFrame_[event.pid];if(!rootStackFrame){rootStackFrame=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8ProcessRootStackFrame_[event.pid]=rootStackFrame;}
+function findChildWithEntryID(stackFrame,entryID){return tr.b.findFirstInArray(stackFrame.children,function(child){return child.entryID===entryID;});}
+var model=this.model_;function addStackFrame(lastStackFrame,entry){var childFrame=findChildWithEntryID(lastStackFrame,entry.id);if(childFrame)
+return childFrame;var frame=new tr.model.StackFrame(lastStackFrame,tr.b.GUID.allocate(),entry.name,ColorScheme.getColorIdForGeneralPurposeString(entry.name),entry.sourceInfo);frame.entryID=entry.id;model.addStackFrame(frame);return frame;}
+var lastStackFrame=rootStackFrame;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){var map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();for(var i=0;i<data.stack.length;i++){var entry=map.lookupEntry(data.stack[i]);if(entry===undefined){entry={id:'unknown',name:'unknown',sourceInfo:undefined};}
+lastStackFrame=addStackFrame(lastStackFrame,entry);}}else{var entry={id:data.vm_state,name:data.vm_state,sourceInfo:undefined};lastStackFrame=addStackFrame(lastStackFrame,entry);}
+var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'V8 Sample',timestampFromUs(event.ts),lastStackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},processTraceSampleEvent:function(event){if(event.name==='V8Sample'){this.processV8Sample(event);return;}
+var stackFrame=this.getStackFrameForEvent_(event);if(stackFrame===undefined){stackFrame=this.traceEventSampleStackFramesByName_[event.name];}
+if(stackFrame===undefined){var id='te-'+tr.b.GUID.allocate();stackFrame=new tr.model.StackFrame(undefined,id,event.name,ColorScheme.getColorIdForGeneralPurposeString(event.name));this.model_.addStackFrame(stackFrame);this.traceEventSampleStackFramesByName_[event.name]=stackFrame;}
+var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(undefined,thread,'Trace Event Sample',timestampFromUs(event.ts),stackFrame,1,this.deepCopyIfNeeded_(event.args));this.model_.samples.push(sample);},getOrCreateMemoryDumpEvents_:function(dumpId){if(this.allMemoryDumpEvents_[dumpId]===undefined){this.allMemoryDumpEvents_[dumpId]={global:undefined,process:[]};}
+return this.allMemoryDumpEvents_[dumpId];},processMemoryDumpEvent:function(event){if(event.id===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:event.ph+' phase event without a dump ID.'});return;}
+var events=this.getOrCreateMemoryDumpEvents_(event.id);if(event.ph==='v'){events.process.push(event);}else if(event.ph==='V'){if(events.global!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple V phase events with the same dump ID.'});return;}
+events.global=event;}else{throw new Error('Invalid memory dump event phase "'+event.ph+'".');}},importEvents:function(){var csr=new tr.ClockSyncRecord('ftrace_importer',0,{});this.model_.clockSyncRecords.push(csr);if(this.stackFrameEvents_){this.importStackFrames_(this.stackFrameEvents_,'g',false);}
+if(this.traceAnnotations_)
+this.importAnnotations_();var events=this.events_;for(var eI=0;eI<events.length;eI++){var event=events[eI];if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
+if(event.ph==='B'||event.ph==='E'){this.processDurationEvent(event);}else if(event.ph==='X'){var slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined)
+this.processFlowEvent(event,slice);}else if(event.ph==='b'||event.ph==='e'||event.ph==='n'||event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){this.processAsyncEvent(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){this.processInstantEvent(event);}else if(event.ph==='P'){this.processTraceSampleEvent(event);}else if(event.ph==='C'){this.processCounterEvent(event);}else if(event.ph==='M'){this.processMetadataEvent(event);}else if(event.ph==='N'||event.ph==='D'||event.ph==='O'){this.processObjectEvent(event);}else if(event.ph==='s'||event.ph==='t'||event.ph==='f'){this.processFlowEvent(event);}else if(event.ph==='v'||event.ph==='V'){this.processMemoryDumpEvent(event);}else{this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
+event.ph+' ('+event.name+')'});}}
+tr.b.iterItems(this.v8ProcessRootStackFrame_,function(name,frame){frame.removeAllChildren();});},importStackFrames_:function(rawStackFrames,idPrefix,addRootFrame){var model=this.model_;var rootStackFrame;if(addRootFrame){rootStackFrame=new tr.model.StackFrame(undefined,idPrefix,undefined,undefined);model.addStackFrame(rootStackFrame);}else{rootStackFrame=undefined;}
+for(var id in rawStackFrames){var rawStackFrame=rawStackFrames[id];var fullId=idPrefix+id;var textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;var stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
+for(var id in rawStackFrames){var fullId=idPrefix+id;var stackFrame=model.stackFrames[fullId];if(stackFrame===undefined)
+throw new Error('Internal error');var rawStackFrame=rawStackFrames[id];var parentId=rawStackFrame.parent;var parentStackFrame;if(parentId===undefined){parentStackFrame=rootStackFrame;}else{var parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});parentStackFrame=rootStackFrame;}}
+stackFrame.parentFrame=parentStackFrame;}},importAnnotations_:function(){for(var id in this.traceAnnotations_){var annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
+this.traceAnnotations_[id].typeName+'\"'});continue;}
+this.model_.addAnnotation(annotation);}},finalizeImport:function(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
+this.createAsyncSlices_();this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_:function(event,opt_lookForEndEvent){var sf;var stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
+if(stack!==undefined&&sf!==undefined){this.model_.importWarning({type:'stack_frame_and_stack_error',message:'Event at '+event.ts+' cannot have both a stack and a stackframe.'});return undefined;}
+if(stack!==undefined)
+return this.model_.resolveStackToStackFrame_(event.pid,stack);if(sf===undefined)
+return undefined;var stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
+return stackFrame;},resolveStackToStackFrame_:function(pid,stack){return undefined;},importSampleData:function(){if(!this.sampleEvents_)
+return;var m=this.model_;var events=this.sampleEvents_;if(this.events_.length===0){for(var i=0;i<events.length;i++){var event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
+var threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(var i=0;i<events.length;i++){var event=events[i];var thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
+var cpu;if(event.cpu!==undefined)
+cpu=m.kernel.getOrCreateCpu(event.cpu);var stackFrame=this.getStackFrameForEvent_(event);var sample=new tr.model.Sample(cpu,thread,event.name,timestampFromUs(event.ts),stackFrame,event.weight);m.samples.push(sample);}},joinRefs:function(){this.joinObjectRefs_();},createAsyncSlices_:function(){if(this.allAsyncEvents_.length===0)
+return;this.allAsyncEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var legacyEvents=[];var nestableAsyncEventsByKey={};for(var i=0;i<this.allAsyncEvents_.length;i++){var asyncEventState=this.allAsyncEvents_[i];var event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
+if(event.cat===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'cat parameter.'});continue;}
+if(event.name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'name parameter.'});continue;}
+if(event.id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
+var key=event.cat+':'+event.id;if(nestableAsyncEventsByKey[key]===undefined)
+nestableAsyncEventsByKey[key]=[];nestableAsyncEventsByKey[key].push(asyncEventState);}
+this.createLegacyAsyncSlices_(legacyEvents);for(var key in nestableAsyncEventsByKey){var eventStateEntries=nestableAsyncEventsByKey[key];var parentStack=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){var parentIndex=-1;for(var k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
+if(parentIndex===-1){eventStateEntry.finished=false;}else{parentStack[parentIndex].end=eventStateEntry;while(parentIndex<parentStack.length){parentStack.pop();}}}
+if(parentStack.length>0)
+eventStateEntry.parentEntry=parentStack[parentStack.length-1];if(eventStateEntry.event.ph==='b')
+parentStack.push(eventStateEntry);}
+var topLevelSlices=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
+var startState=undefined;var endState=undefined;var sliceArgs=eventStateEntry.event.args||{};var sliceError=undefined;if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
+eventStateEntry.event.ts+' with name='+
+eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});}else{function concatenateArguments(args1,args2){if(args1.params===undefined||args2.params===undefined)
+return tr.b.concatenateObjects(args1,args2);var args3={};args3.params=tr.b.concatenateObjects(args1.params,args2.params);return tr.b.concatenateObjects(args1,args2,args3);}
+var endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
+startState=eventStateEntry;endState=eventStateEntry.end;}else{sliceError='Slice has no matching BEGIN. Start time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async END event at '+
+eventStateEntry.event.ts+' with name='+
+eventStateEntry.event.name+' and id='+eventStateEntry.event.id+' was unmatched.'});startState=eventStateEntries[0];endState=eventStateEntry;}
+var isTopLevel=(eventStateEntry.parentEntry===undefined);var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);var thread_start=undefined;var thread_duration=undefined;if(startState.event.tts&&startState.event.use_async_tts){thread_start=timestampFromUs(startState.event.tts);if(endState.event.tts){var thread_end=timestampFromUs(endState.event.tts);thread_duration=thread_end-thread_start;}}
+var slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),timestampFromUs(startState.event.ts),sliceArgs,timestampFromUs(endState.event.ts-startState.event.ts),isTopLevel,thread_start,thread_duration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined)
+slice.error=sliceError;eventStateEntry.slice=slice;if(isTopLevel){topLevelSlices.push(slice);}else if(eventStateEntry.parentEntry.slice!==undefined){eventStateEntry.parentEntry.slice.subSlices.push(slice);}}
+for(var si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},createLegacyAsyncSlices_:function(legacyEvents){if(legacyEvents.length===0)
+return;legacyEvents.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var asyncEventStatesByNameThenID={};for(var i=0;i<legacyEvents.length;i++){var asyncEventState=legacyEvents[i];var event=asyncEventState.event;var name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
+var id=event.id;if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
+if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined)
+asyncEventStatesByNameThenID[name]={};if(asyncEventStatesByNameThenID[name][id]){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', a slice of the same id '+id+' was alrady open.'});continue;}
+asyncEventStatesByNameThenID[name][id]=[];asyncEventStatesByNameThenID[name][id].push(asyncEventState);}else{if(asyncEventStatesByNameThenID[name]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' was open.'});continue;}
+if(asyncEventStatesByNameThenID[name][id]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' with id='+id+' was open.'});continue;}
+var events=asyncEventStatesByNameThenID[name][id];events.push(asyncEventState);if(event.ph==='F'){var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,name);var slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),timestampFromUs(events[0].event.ts),tr.b.concatenateObjects(events[0].event.args,events[events.length-1].event.args),timestampFromUs(event.ts-events[0].event.ts),true,undefined,undefined,events[0].event.argsStripped);slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=id;var stepType=events[1].event.ph;var isValid=true;for(var j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)
+break;}
+if(events[j].event.ph==='S'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+event.event.id+' had a step before the start event.'});continue;}
+if(events[j].event.ph==='F'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+event.event.id+' had a step after the finish event.'});continue;}
+var startIndex=j+(stepType==='T'?0:-1);var endIndex=startIndex+1;var subName=events[j].event.name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p'))
+subName=subName+':'+events[j].event.args.step;var asyncSliceConstructor=tr.model.AsyncSlice.getConstructor(events[0].event.cat,subName);var subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(event,subName+j),timestampFromUs(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),timestampFromUs(events[endIndex].event.ts-events[startIndex].event.ts),undefined,undefined,events[startIndex].event.argsStripped);subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=id;slice.subSlices.push(subSlice);}
+if(isValid){slice.startThread.asyncSliceGroup.push(slice);}
+delete asyncEventStatesByNameThenID[name][id];}}}},assertStepTypeMatches_:function(stepType,event){if(stepType!=event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+event.event.name+' with id='+event.event.id+' had both begin and end steps, which is not allowed.'});return false;}
+return true;},createFlowSlices_:function(){if(this.allFlowEvents_.length===0)
+return;var that=this;function validateFlowEvent(){if(event.name===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require a name parameter.'});return false;}
+if(event.ph==='s'||event.ph==='f'||event.ph==='t'){if(event.id===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require an id parameter.'});return false;}
+return true;}
+if(event.bind_id){if(event.flow_in===undefined&&event.flow_out===undefined){that.model_.importWarning({type:'flow_slice_parse_error',message:'Flow producer or consumer require flow_in or flow_out.'});return false;}
+return true;}
+return false;}
+function createFlowEvent(thread,event,opt_slice){var startSlice,flowId,flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=timestampFromUs(event.ts+event.dur);}else{var ts=timestampFromUs(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)
+return undefined;flowId=event.id;flowStartTs=ts;}
+var flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,that.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=that.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}
+function finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent,opt_slice){var endSlice;if(event.bind_id){endSlice=opt_slice;}else{var ts=timestampFromUs(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
+if(endSlice===undefined)
+return false;}
+endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=timestampFromUs(event.ts)-flowEvent.start;flowEvent.endStackFrame=that.getStackFrameForEvent_(event);that.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}
+function processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice){var flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){that.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){var flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
+var ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){that.model_.flowEvents.push(flowEvent);}else{that.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
+return true;}
+function processFlowProducer(flowIdToEvent,flowStatus,event,slice){if(flowIdToEvent[event.bind_id]&&flowStatus[event.bind_id]){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' already seen'});return false;}
+var flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){that.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
+flowIdToEvent[event.bind_id]=flowEvent;return;}
+this.allFlowEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var flowIdToEvent={};var sliceGuidToEvent={};var flowStatus={};for(var i=0;i<this.allFlowEvents_.length;++i){var data=this.allFlowEvents_[i];var refGuid=data.refGuid;var event=data.event;var thread=data.thread;if(!validateFlowEvent(event))
+continue;if(event.bind_id){var slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
+continue;flowStatus[event.bind_id]=true;}
+else{if(!processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice))
+continue;flowStatus[event.bind_id]=false;if(event.flowPhase===STEP){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice))
+continue;flowStatus[event.bind_id]=true;}}
+continue;}
+var flowEvent;if(event.ph==='s'){if(flowIdToEvent[event.id]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
+flowEvent=createFlowEvent(thread,event);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' does not start '+'at an actual slice, so cannot be created.'});continue;}
+flowIdToEvent[event.id]=flowEvent;}else if(event.ph==='t'||event.ph==='f'){flowEvent=flowIdToEvent[event.id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Found flow phase '+event.ph+' for id: '+event.id+' but no flow start found.'});continue;}
+var bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1)
+bindToParent=true;else if(event.cat.indexOf('ipc.flow')>-1)
+bindToParent=true;}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
+bindToParent=true;}}
+var ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){that.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
+flowIdToEvent[event.id]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[event.id]=flowEvent;}}}},createExplicitObjects_:function(){if(this.allObjectEvents_.length===0)
+return;function processEvent(objectEventState){var event=objectEventState.event;var thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
+if(event.id===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an id parameter.'});}
+var process=thread.parent;var ts=timestampFromUs(event.ts);var instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(event.id,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
+event.id+' at ts='+ts+': '+e});return;}}else if(event.ph==='O'){if(event.args.snapshot===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+event.id+' at ts='+ts+': '+'Snapshots must have args: {snapshot: ...}'});return;}
+var snapshot;try{var args=this.deepCopyIfNeeded_(event.args.snapshot);var cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
+var baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
+snapshot=process.objects.addSnapshot(event.id,cat,event.name,ts,args,baseTypename);snapshot.snapshottedOnThread=thread;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing snapshot of '+
+event.id+' at ts='+ts+': '+e});return;}
+instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(event.id,event.cat,event.name,ts);var instanceMap=process.objects.getOrCreateInstanceMap_(event.id);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
+event.id+' at ts='+ts+': '+e});return;}}
+if(instance)
+instance.colorId=getEventColor(event,instance.typeName);}
+this.allObjectEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!=0)
+return d;return x.sequenceNumber-y.sequenceNumber;});var allObjectEvents=this.allObjectEvents_;for(var i=0;i<allObjectEvents.length;i++){var objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_:function(){tr.b.iterItems(this.model_.processes,function(pid,process){this.createImplicitObjectsForProcess_(process);},this);},createImplicitObjectsForProcess_:function(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)
+return;if(referencingObjectFieldValue instanceof
+tr.model.ObjectSnapshot)
+return null;if(referencingObjectFieldValue.id===undefined)
+return;var implicitSnapshot=referencingObjectFieldValue;var rawId=implicitSnapshot.id;var m=/(.+)\/(.+)/.exec(rawId);if(!m)
+throw new Error('Implicit snapshots must have names.');delete implicitSnapshot.id;var name=m[1];var id=m[2];var res;var cat;if(implicitSnapshot.cat!==undefined)
+cat=implicitSnapshot.cat;else
+cat=containingSnapshot.objectInstance.category;var baseTypename;if(implicitSnapshot.base_type)
+baseTypename=implicitSnapshot.base_type;else
+baseTypename=undefined;try{res=process.objects.addSnapshot(id,cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
+rawId+' at ts='+containingSnapshot.ts+': '+e});return;}
+res.objectInstance.hasImplicitSnapshots=true;res.containingSnapshot=containingSnapshot;res.snapshottedOnThread=containingSnapshot.snapshottedOnThread;referencingObject[referencingObjectFieldName]=res;if(!(res instanceof tr.model.ObjectSnapshot))
+throw new Error('Created object must be instanceof snapshot');return res.args;}
+function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++){var res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)
+continue;if(res)
+iterObject(res,func,containingSnapshot,thisArg);else
+iterObject(object[i],func,containingSnapshot,thisArg);}
+return;}
+for(var key in object){var res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)
+continue;if(res)
+iterObject(res,func,containingSnapshot,thisArg);else
+iterObject(object[key],func,containingSnapshot,thisArg);}}
+process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(snapshot){if(snapshot.args.id!==undefined)
+throw new Error('args cannot have an id field inside it');iterObject(snapshot.args,processField,snapshot,this);},this);},this);},createMemoryDumps_:function(){tr.b.iterItems(this.allMemoryDumpEvents_,function(id,events){var range=new tr.b.Range();if(events.global!==undefined)
+range.addValue(timestampFromUs(events.global.ts));for(var i=0;i<events.process.length;i++)
+range.addValue(timestampFromUs(events.process[i].ts));var globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,range.min);globalMemoryDump.duration=range.range;this.model_.globalMemoryDumps.push(globalMemoryDump);if(events.process.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No process memory dumps associated with global memory'+' dump '+id+'.'});}
+var allMemoryAllocatorDumpsByGuid={};var globalMemoryAllocatorDumpsByFullName={};var LEVELS_OF_DETAIL=[undefined,'light','detailed'];var globalLevelOfDetailIndex=undefined;events.process.forEach(function(processEvent){var pid=processEvent.pid;if(pid in globalMemoryDump.processMemoryDumps){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple process memory dumps with pid='+pid+' for dump id '+id+'.'});return;}
+var dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'dumps not found in process memory dump for '+'pid='+pid+' and dump id='+id+'.'});return;}
+var process=this.model_.getOrCreateProcess(pid);var processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,timestampFromUs(processEvent.ts));var processLevelOfDetail=dumps.level_of_detail;var processLevelOfDetailIndex=LEVELS_OF_DETAIL.indexOf(processLevelOfDetail);if(processLevelOfDetailIndex<0){this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown level of detail \''+processLevelOfDetail+'\' of process memory dump for pid='+pid+' and dump id='+id+'.'});}else{processMemoryDump.levelOfDetail=processLevelOfDetail;if(globalLevelOfDetailIndex===undefined){globalLevelOfDetailIndex=processLevelOfDetailIndex;}else if(globalLevelOfDetailIndex!==processLevelOfDetailIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail of process memory dumps '+'for dump id='+id+'.'});globalLevelOfDetailIndex=Math.max(globalLevelOfDetailIndex,processLevelOfDetailIndex);}}
+var rawTotals=dumps.process_totals;if(rawTotals!==undefined){processMemoryDump.totals={};if(rawTotals.resident_set_bytes!==undefined){processMemoryDump.totals.residentBytes=parseInt(rawTotals.resident_set_bytes,16);}
+if(rawTotals.peak_resident_set_bytes!==undefined){if(rawTotals.is_peak_rss_resetable===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field peak_resident_set_bytes found'+' but is_peak_rss_resetable not found in'+' process memory dump for pid='+pid+' and dump id='+id+'.'});}
+processMemoryDump.totals.peakResidentBytes=parseInt(rawTotals.peak_resident_set_bytes,16);}
+if(rawTotals.is_peak_rss_resetable!==undefined){if(rawTotals.peak_resident_set_bytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field is_peak_rss_resetable found'+' but peak_resident_set_bytes not found in'+' process memory dump for pid='+pid+' and dump id='+id+'.'});}
+processMemoryDump.totals.arePeakResidentBytesResettable=!!rawTotals.is_peak_rss_resetable;}}
+if(processMemoryDump.totals===undefined||processMemoryDump.totals.residentBytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Mandatory field resident_set_bytes not found in'+' process memory dump for pid='+pid+' and dump id='+id+'.'});}
+if(dumps.process_mmaps&&dumps.process_mmaps.vm_regions){function parseByteStat(rawValue){if(rawValue===undefined)
+return undefined;return parseInt(rawValue,16);}
+processMemoryDump.vmRegions=dumps.process_mmaps.vm_regions.map(function(rawRegion){var byteStats=new tr.model.VMRegionByteStats(parseByteStat(rawRegion.bs.pc),parseByteStat(rawRegion.bs.pd),parseByteStat(rawRegion.bs.sc),parseByteStat(rawRegion.bs.sd),parseByteStat(rawRegion.bs.pss),parseByteStat(rawRegion.bs.sw));return new tr.model.VMRegion(parseInt(rawRegion.sa,16),parseInt(rawRegion.sz,16),rawRegion.pf,rawRegion.mf,byteStats);});}
+var processMemoryAllocatorDumpsByFullName={};if(dumps.allocators!==undefined){tr.b.iterItems(dumps.allocators,function(fullName,rawAllocatorDump){var guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' from pid='+pid+' does not have a GUID.'});}
+var GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';var containerMemoryDump;var dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
+var allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
+dstIndex[fullName].guid+', '+guid+' (ignored).'});return;}
+allocatorDump=new tr.model.MemoryAllocatorDump(containerMemoryDump,fullName,guid);dstIndex[fullName]=allocatorDump;if(guid!==undefined)
+allMemoryAllocatorDumpsByGuid[guid]=allocatorDump;}else{if(allocatorDump.containerMemoryDump!==containerMemoryDump){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') dumped in different contexts.'});return;}
+if(allocatorDump.fullName!==fullName){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump with GUID='+guid+' has multiple names: '+allocatorDump.fullName+', '+fullName+' (ignored).'});return;}}
+var attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' from pid='+pid+' (GUID='+guid+') does not'+' have attributes.'});attributes={};}
+tr.b.iterItems(attributes,function(attrName,attrArgs){if(attrName in allocatorDump.attributes){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for attribute '+
+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+').'});return;}
+var attrValue=tr.model.Attribute.fromDictIfPossible(attrArgs);allocatorDump.addAttribute(attrName,attrValue);},this);},this);}
+processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);if(dumps.heaps!==undefined){processMemoryDump.heapDumps=tr.b.mapItems(dumps.heaps,this.parseHeapDump_.bind(this,processMemoryDump));}
+process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;},this);globalMemoryDump.levelOfDetail=LEVELS_OF_DETAIL[globalLevelOfDetailIndex];globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);events.process.forEach(function(processEvent){var dumps=processEvent.args.dumps;if(dumps===undefined)
+return;var edges=dumps.allocators_graph;if(edges===undefined)
+return;edges.forEach(function(rawEdge){var sourceGuid=rawEdge.source;var sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge is missing source memory allocator dump (GUID='+
+sourceGuid+')'});return;}
+var targetGuid=rawEdge.target;var targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge is missing target memory allocator dump (GUID='+
+targetGuid+')'});return;}
+var importance=rawEdge.importance;var edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
+sourceDump.owns.target.fullName+').'});return;}
+sourceDump.owns=edge;targetDump.ownedBy.push(edge);break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}},this);},this);},this);},inferMemoryAllocatorDumpTree_:function(memoryAllocatorDumpsByFullName){var rootAllocatorDumps=[];var fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();fullNames.forEach(function(fullName){var allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){var lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
+var parentFullName=fullName.substring(0,lastSlashIndex);var parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];var parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);memoryAllocatorDumpsByFullName[parentFullName]=parentAllocatorDump;}
+allocatorDump.parent=parentAllocatorDump;parentAllocatorDump.children.push(allocatorDump);if(parentAlreadyExisted)
+break;fullName=parentFullName;allocatorDump=parentAllocatorDump;}},this);return rootAllocatorDumps;},parseHeapDump_:function(processMemoryDump,allocatorName,rawHeapDump){var pid=processMemoryDump.process.pid;var entries=rawHeapDump.entries;if(entries===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing heap entries in a '+allocatorName+' heap dump for pid='+pid+'.'});return undefined;}
+var model=this.model_;var heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);var idPrefix='p'+pid+':';for(var i=0;i<entries.length;i++){var entry=entries[i];var size=parseInt(entry.size,16);var leafStackFrameIndex=entry.bt;var leafStackFrame;if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{var leafStackFrameId=idPrefix+leafStackFrameIndex;leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
+allocatorName+' heap dump for pid='+pid+'.'});continue;}}
+heapDump.addEntry(leafStackFrame,size);}
+return heapDump;},joinObjectRefs_:function(){tr.b.iterItems(this.model_.processes,function(pid,process){this.joinObjectRefsForProcess_(process);},this);},joinObjectRefsForProcess_:function(process){var patchupsToApply=[];tr.b.iterItems(process.threads,function(tid,thread){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(patchupsToApply,process.objects,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(patchupsToApply,process.objects,'start',item);},this);},this);process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(patchupsToApply,process.objects,'ts',item);},this);},this);patchupsToApply.forEach(function(patchup){patchup.object[patchup.field]=patchup.value;});},searchItemForIDRefs_:function(patchupsToApply,objectCollection,itemTimestampField,item){if(!item.args)
+throw new Error('item is missing its args');function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef))
+return;var id=fieldValue.id_ref||fieldValue.idRef;var ts=item[itemTimestampField];var snapshot=objectCollection.getSnapshotAt(id,ts);if(!snapshot)
+return;patchupsToApply.push({object:object,field:fieldName,value:snapshot});}
+function iterObjectFieldsRecursively(object){if(!(object instanceof Object))
+return;if((object instanceof tr.model.ObjectSnapshot)||(object instanceof Float32Array)||(object instanceof tr.b.Quad))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
+return;}
+for(var key in object){var value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
+iterObjectFieldsRecursively(item.args);}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter:TraceEventImporter};});'use strict';tr.exportTo('tr.e.importer',function(){var GZIP_MEMBER_HEADER_ID_SIZE=3;var GZIP_HEADER_ID1=0x1f;var GZIP_HEADER_ID2=0x8b;var GZIP_DEFLATE_COMPRESSION=8;function GzipImporter(model,eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=JSZip.utils.transformTo('uint8array',eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else
+throw new Error('Unknown gzip data format');this.model_=model;this.gzipData_=eventData;}
+GzipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
+header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=JSZip.utils.transformTo('uint8array',header);}else
+return false;return header[0]==GZIP_HEADER_ID1&&header[1]==GZIP_HEADER_ID2&&header[2]==GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){var position=0;function getByte(){if(position>=data.length)
+throw new Error('Unexpected end of gzip data');return data[position++];}
+function getWord(){var low=getByte();var high=getByte();return(high<<8)+low;}
+function skipBytes(amount){position+=amount;}
+function skipZeroTerminatedString(){while(getByte()!=0){}}
+var id1=getByte();var id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2)
+throw new Error('Not gzip data');var compression_method=getByte();if(compression_method!==GZIP_DEFLATE_COMPRESSION)
+throw new Error('Unsupported compression method: '+compression_method);var flags=getByte();var have_header_crc=flags&(1<<1);var have_extra_fields=flags&(1<<2);var have_file_name=flags&(1<<3);var have_comment=flags&(1<<4);skipBytes(4+1+1);if(have_extra_fields){var bytes_to_skip=getWord();skipBytes(bytes_to_skip);}
+if(have_file_name)
+skipZeroTerminatedString();if(have_comment)
+skipZeroTerminatedString();if(have_header_crc)
+getWord();var inflated_data=JSZip.compressions['DEFLATE'].uncompress(data.subarray(position));return JSZip.utils.transformTo('string',inflated_data);},GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,isTraceDataContainer:function(){return true;},extractSubtraces:function(){var eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter:GzipImporter};});'use strict';tr.exportTo('tr.e.importer',function(){function ZipImporter(model,eventData){if(eventData instanceof ArrayBuffer)
+eventData=new Uint8Array(eventData);this.model_=model;this.eventData_=eventData;}
+ZipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer)
+header=new Uint8Array(eventData.slice(0,2));else if(typeof(eventData)==='string'||eventData instanceof String)
+header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];else
+return false;return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,isTraceDataContainer:function(){return true;},extractSubtraces:function(){var zip=new JSZip(this.eventData_);var subtraces=[];for(var idx in zip.files)
+subtraces.push(zip.files[idx].asBinary());return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter:ZipImporter};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){};CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){var fieldRe=CsvParser.CSV_FIELD_RE_;var doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;var pos=0;var endPos=line.length;var fields=[];if(endPos>0){do{var fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){var field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{var field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
+return fields;};function LogReader(dispatchTable){this.dispatchTable_=dispatchTable;this.lineNum_=0;this.csvParser_=new CsvParser();};LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){var fullStack=func?[pc,func]:[pc];var prevFrame=pc;for(var i=0,n=stack.length;i<n;++i){var frame=stack[i];var firstChar=frame.charAt(0);if(firstChar=='+'||firstChar=='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!='o'){fullStack.push(parseInt(frame,16));}}
+return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){var command=fields[0];if(!(command in this.dispatchTable_))return;var dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
+var parsedFields=[];for(var i=0;i<dispatch.parsers.length;++i){var parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser=='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
+dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(var i=0,n=lines.length;i<n;++i,++this.lineNum_){var line=lines[i];if(!line){continue;}
+try{var fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
+(e.message||e));}}};return{LogReader:LogReader};});'use strict';tr.exportTo('tr.e.importer.v8',function(){var ColorScheme=tr.b.ColorScheme;function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new tr.e.importer.v8.CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.root_stack_frame_=new tr.model.StackFrame(undefined,'v8-root-stack-frame','v8-root-stack-frame',0);this.v8_stack_timeline_=new Array();}
+var kV8BinarySuffixes=['/d8','/libv8.so'];var TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String))
+return false;return eventData.substring(0,11)=='v8-version,'||eventData.substring(0,12)=='timer-event,'||eventData.substring(0,5)=='tick,'||eventData.substring(0,15)=='shared-library,'||eventData.substring(0,9)=='profiler,'||eventData.substring(0,14)=='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,processTimerEvent_:function(name,start,length){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;length/=1000;var colorId=ColorScheme.getColorIdForGeneralPurposeString(name);var slice=new tr.model.Slice('v8',name,colorId,start,args,length);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_:function(name,start){var args=TimerEventDefaultArgs[name];if(args===undefined)return;start/=1000;this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,start,args);},processTimerEventEnd_:function(name,end){end/=1000;this.v8_timer_thread_.sliceGroup.endSlice(end);},processCodeCreateEvent_:function(type,kind,address,size,name){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(size,name);code_entry.kind=kind;this.code_map_.addCode(address,code_entry);},processCodeMoveEvent_:function(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_:function(address){this.code_map_.deleteCode(address);},processSharedLibrary_:function(name,start,end){var code_entry=new tr.e.importer.v8.CodeMap.CodeEntry(end-start,name);code_entry.kind=-3;for(var i=0;i<kV8BinarySuffixes.length;i++){var suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){code_entry.kind=-1;break;}}
+this.code_map_.addLibrary(start,code_entry);},findCodeKind_:function(kind){for(name in CodeKinds){if(CodeKinds[name].kinds.indexOf(kind)>=0){return CodeKinds[name];}}},processTickEvent_:function(pc,start,unused_x,unused_y,vmstate,stack){start/=1000;function findChildWithEntryID(stackFrame,entryID){for(var i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID==entryID)
+return stackFrame.children[i];}
+return undefined;}
+var lastStackFrame;if(stack&&stack.length){lastStackFrame=this.root_stack_frame_;stack=stack.reverse();for(var i=0;i<stack.length;i++){if(!stack[i])
+break;var entry=this.code_map_.findEntry(stack[i]);var entryID=entry?entry.id:'Unknown';var childFrame=findChildWithEntryID(lastStackFrame,entryID);if(childFrame===undefined){var entryName=entry?entry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(lastStackFrame,'v8sf-'+tr.b.GUID.allocate(),entryName,ColorScheme.getColorIdForGeneralPurposeString(entryName));lastStackFrame.entryID=entryID;this.model_.addStackFrame(lastStackFrame);}else{lastStackFrame=childFrame;}}}else{var pcEntry=this.code_map_.findEntry(pc);var pcEntryID='v8pc-'+(pcEntry?pcEntry.id:'Unknown');if(this.model_.stackFrames[pcEntryID]===undefined){var pcEntryName=pcEntry?pcEntry.name:'Unknown';lastStackFrame=new tr.model.StackFrame(undefined,pcEntryID,pcEntryName,ColorScheme.getColorIdForGeneralPurposeString(pcEntryName));this.model_.addStackFrame(lastStackFrame);}
+lastStackFrame=this.model_.stackFrames[pcEntryID];}
+var sample=new tr.model.Sample(undefined,this.v8_thread_,'V8 PC',start,lastStackFrame,1);this.model_.samples.push(sample);},processDistortion_:function(distortion_in_picoseconds){distortion_per_entry=distortion_in_picoseconds/1000000;},processPlotRange_:function(start,end){xrange_start_override=start;xrange_end_override=end;},processV8Version_:function(major,minor,build,patch,candidate){},importEvents:function(){var logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'tick':{parsers:[parseInt,parseInt,null,null,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';var lines=this.logData_.split('\n');for(var i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
+this.root_stack_frame_.removeAllChildren();function addSlices(slices,thread){for(var i=0;i<slices.length;i++){var duration=slices[i].end-slices[i].start;var slice=new tr.model.Slice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
+addSlices(this.v8_stack_timeline_,this.v8_thread_);}};tr.importer.Importer.register(V8LogImporter);return{V8LogImporter:V8LogImporter};});'use strict';tr.exportTo('tr.e.importer.etw',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser:Parser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';var kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
+EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version!=2)
+throw new Error('Incompatible EventTrace event version.');var bufferSize=decoder.decodeUInt32();var version=decoder.decodeUInt32();var providerVersion=decoder.decodeUInt32();var numberOfProcessors=decoder.decodeUInt32();var endTime=decoder.decodeUInt64ToString();var timerResolution=decoder.decodeUInt32();var maxFileSize=decoder.decodeUInt32();var logFileMode=decoder.decodeUInt32();var buffersWritten=decoder.decodeUInt32();var startBuffers=decoder.decodeUInt32();var pointerSize=decoder.decodeUInt32();var eventsLost=decoder.decodeUInt32();var cpuSpeed=decoder.decodeUInt32();var loggerName=decoder.decodeUInteger(header.is64);var logFileName=decoder.decodeUInteger(header.is64);var timeZoneInformation=decoder.decodeTimeZoneInformation();var padding=decoder.decodeUInt32();var bootTime=decoder.decodeUInt64ToString();var perfFreq=decoder.decodeUInt64ToString();var startTime=decoder.decodeUInt64ToString();var reservedFlags=decoder.decodeUInt32();var buffersLost=decoder.decodeUInt32();var sessionNameString=decoder.decodeW16String();var logFileNameString=decoder.decodeW16String();return{bufferSize:bufferSize,version:version,providerVersion:providerVersion,numberOfProcessors:numberOfProcessors,endTime:endTime,timerResolution:timerResolution,maxFileSize:maxFileSize,logFileMode:logFileMode,buffersWritten:buffersWritten,startBuffers:startBuffers,pointerSize:pointerSize,eventsLost:eventsLost,cpuSpeed:cpuSpeed,loggerName:loggerName,logFileName:logFileName,timeZoneInformation:timeZoneInformation,bootTime:bootTime,perfFreq:perfFreq,startTime:startTime,reservedFlags:reservedFlags,buffersLost:buffersLost,sessionNameString:sessionNameString,logFileNameString:logFileNameString};},decodeHeader:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser:EventTraceParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';var kProcessStartOpcode=1;var kProcessEndOpcode=2;var kProcessDCStartOpcode=3;var kProcessDCEndOpcode=4;var kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
+ProcessParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>5)
+throw new Error('Incompatible Process event version.');var pageDirectoryBase;if(header.version==1)
+pageDirectoryBase=decoder.decodeUInteger(header.is64);var uniqueProcessKey;if(header.version>=2)
+uniqueProcessKey=decoder.decodeUInteger(header.is64);var processId=decoder.decodeUInt32();var parentId=decoder.decodeUInt32();var sessionId;var exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
+var directoryTableBase;if(header.version>=3)
+directoryTableBase=decoder.decodeUInteger(header.is64);var flags;if(header.version>=4)
+flags=decoder.decodeUInt32();var userSID=decoder.decodeSID(header.is64);var imageFileName;if(header.version>=1)
+imageFileName=decoder.decodeString();var commandLine;if(header.version>=2)
+commandLine=decoder.decodeW16String();var packageFullName;var applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
+var exitTime;if(header.version==5&&header.opcode==kProcessDefunctOpcode)
+exitTime=decoder.decodeUInt64ToString();return{pageDirectoryBase:pageDirectoryBase,uniqueProcessKey:uniqueProcessKey,processId:processId,parentId:parentId,sessionId:sessionId,exitStatus:exitStatus,directoryTableBase:directoryTableBase,flags:flags,userSID:userSID,imageFileName:imageFileName,commandLine:commandLine,packageFullName:packageFullName,applicationId:applicationId,exitTime:exitTime};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
+process.name=fields.imageFileName;return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended'))
+throw new Error('Process clash detected.');process.name=fields.imageFileName;return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser:ProcessParser};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadStartOpcode=1;var kThreadEndOpcode=2;var kThreadDCStartOpcode=3;var kThreadDCEndOpcode=4;var kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
+ThreadParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>3)
+throw new Error('Incompatible Thread event version.');var processId=decoder.decodeUInt32();var threadId=decoder.decodeUInt32();var stackBase;var stackLimit;var userStackBase;var userStackLimit;var affinity;var startAddr;var win32StartAddr;var tebBase;var subProcessTag;var basePriority;var pagePriority;var ioPriority;var threadFlags;var waitMode;if(header.version==1){if(header.opcode==kThreadStartOpcode||header.opcode==kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version==2)
+startAddr=decoder.decodeUInteger(header.is64);else
+affinity=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);tebBase=decoder.decodeUInteger(header.is64);subProcessTag=decoder.decodeUInt32();if(header.version==3){basePriority=decoder.decodeUInt8();pagePriority=decoder.decodeUInt8();ioPriority=decoder.decodeUInt8();threadFlags=decoder.decodeUInt8();}}
+return{processId:processId,threadId:threadId,stackBase:stackBase,stackLimit:stackLimit,userStackBase:userStackBase,userStackLimit:userStackLimit,affinity:affinity,startAddr:startAddr,win32StartAddr:win32StartAddr,tebBase:tebBase,subProcessTag:subProcessTag,waitMode:waitMode,basePriority:basePriority,pagePriority:pagePriority,ioPriority:ioPriority,threadFlags:threadFlags};},decodeCSwitchFields:function(header,decoder){if(header.version!=2)
+throw new Error('Incompatible Thread event version.');var newThreadId=decoder.decodeUInt32();var oldThreadId=decoder.decodeUInt32();var newThreadPriority=decoder.decodeInt8();var oldThreadPriority=decoder.decodeInt8();var previousCState=decoder.decodeUInt8();var spareByte=decoder.decodeInt8();var oldThreadWaitReason=decoder.decodeInt8();var oldThreadWaitMode=decoder.decodeInt8();var oldThreadState=decoder.decodeInt8();var oldThreadWaitIdealProcessor=decoder.decodeInt8();var newThreadWaitTime=decoder.decodeUInt32();var reserved=decoder.decodeUInt32();return{newThreadId:newThreadId,oldThreadId:oldThreadId,newThreadPriority:newThreadPriority,oldThreadPriority:oldThreadPriority,previousCState:previousCState,spareByte:spareByte,oldThreadWaitReason:oldThreadWaitReason,oldThreadWaitMode:oldThreadWaitMode,oldThreadState:oldThreadState,oldThreadWaitIdealProcessor:oldThreadWaitIdealProcessor,newThreadWaitTime:newThreadWaitTime,reserved:reserved};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch:function(header,decoder){var fields=this.decodeCSwitchFields(header,decoder);var cpu=this.importer.getOrCreateCpu(header.cpu);var new_thread=this.importer.getThreadFromWindowsTid(fields.newThreadId);var new_thread_name;if(new_thread&&new_thread.userFriendlyName){new_thread_name=new_thread.userFriendlyName;}else{var new_process_id=this.importer.getPidFromWindowsTid(fields.newThreadId);var new_process=this.model.getProcess(new_process_id);var new_process_name;if(new_process)
+new_process_name=new_process.name;else
+new_process_name='Unknown process';new_thread_name=new_process_name+' (tid '+fields.newThreadId+')';}
+cpu.switchActiveThread(header.timestamp,{},fields.newThreadId,new_thread_name,fields);return true;}};Parser.register(ThreadParser);return{ThreadParser:ThreadParser};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
+function b64ToUint6(nChr){if(nChr>64&&nChr<91)
+return nChr-65;if(nChr>96&&nChr<123)
+return nChr-71;if(nChr>47&&nChr<58)
+return nChr+4;if(nChr===43)
+return 62;if(nChr===47)
+return 63;return 0;}
+Base64.getDecodedBufferLength=function(input){return input.length*3+1>>2;}
+Base64.EncodeArrayBufferToString=function(input){var binary='';var bytes=new Uint8Array(input);var len=bytes.byteLength;for(var i=0;i<len;i++)
+binary+=String.fromCharCode(bytes[i]);return btoa(binary);}
+Base64.DecodeToTypedArray=function(input,output){var nInLen=input.length;var nOutLen=nInLen*3+1>>2;var nMod3=0;var nMod4=0;var nUint24=0;var nOutIdx=0;if(nOutLen>output.byteLength)
+throw new Error('Output buffer too small to decode.');for(var nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
+nUint24=0;}}
+return nOutIdx-1;}
+return{Base64:Base64};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));};Decoder.prototype={__proto__:Object.prototype,reset:function(base64_payload){var decoded_size=tr.b.Base64.getDecodedBufferLength(base64_payload);if(decoded_size>this.payload_.byteLength)
+this.payload_=new DataView(new ArrayBuffer(decoded_size));tr.b.Base64.DecodeToTypedArray(base64_payload,this.payload_);this.position_=0;},skip:function(length){this.position_+=length;},decodeUInt8:function(){var result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16:function(){var result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32:function(){var result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString:function(){var low=this.decodeUInt32();var high=this.decodeUInt32();var low_str=('0000000'+low.toString(16)).substr(-8);var high_str=('0000000'+high.toString(16)).substr(-8);var result=high_str+low_str;return result;},decodeInt8:function(){var result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16:function(){var result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32:function(){var result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString:function(){return this.decodeUInt64ToString();},decodeUInteger:function(is64){if(is64)
+return this.decodeUInt64ToString();return this.decodeUInt32();},decodeString:function(){var str='';while(true){var c=this.decodeUInt8();if(!c)
+return str;str=str+String.fromCharCode(c);}},decodeW16String:function(){var str='';while(true){var c=this.decodeUInt16();if(!c)
+return str;str=str+String.fromCharCode(c);}},decodeFixedW16String:function(length){var old_position=this.position_;var str='';for(var i=0;i<length;i++){var c=this.decodeUInt16();if(!c)
+break;str=str+String.fromCharCode(c);}
+this.position_=old_position+2*length;return str;},decodeBytes:function(length){var bytes=[];for(var i=0;i<length;++i){var c=this.decodeUInt8();bytes.push(c);}
+return bytes;},decodeSID:function(is64){var pSid=this.decodeUInteger(is64);var attributes=this.decodeUInt32();if(is64)
+this.decodeUInt32();var revision=this.decodeUInt8();var subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!=1)
+throw'Invalid SID revision: could not decode the SID structure.';var sid=this.decodeBytes(4*subAuthorityCount);return{pSid:pSid,attributes:attributes,sid:sid};},decodeSystemTime:function(){var wYear=this.decodeInt16();var wMonth=this.decodeInt16();var wDayOfWeek=this.decodeInt16();var wDay=this.decodeInt16();var wHour=this.decodeInt16();var wMinute=this.decodeInt16();var wSecond=this.decodeInt16();var wMilliseconds=this.decodeInt16();return{wYear:wYear,wMonth:wMonth,wDayOfWeek:wDayOfWeek,wDay:wDay,wHour:wHour,wMinute:wMinute,wSecond:wSecond,wMilliseconds:wMilliseconds};},decodeTimeZoneInformation:function(){var bias=this.decodeUInt32();var standardName=this.decodeFixedW16String(32);var standardDate=this.decodeSystemTime();var standardBias=this.decodeUInt32();var daylightName=this.decodeFixedW16String(32);var daylightDate=this.decodeSystemTime();var daylightBias=this.decodeUInt32();return{bias:bias,standardName:standardName,standardDate:standardDate,standardBias:standardBias,daylightName:daylightName,daylightDate:daylightDate,daylightBias:daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};var allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
+EtwImporter.canImport=function(events){if(!events.hasOwnProperty('name')||!events.hasOwnProperty('content')||events.name!=='ETW'){return false;}
+return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get model(){return this.model_;},createThreadIfNeeded:function(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent:function(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid:function(tid){if(tid==0)
+return 0;var pid=this.tidsToPid_[tid];if(pid==undefined){return 0;}
+return pid;},getThreadFromWindowsTid:function(tid){var pid=this.getPidFromWindowsTid(tid);var process=this.model_.getProcess(pid);if(!process)
+return undefined;return process.getThread(tid);},getOrCreateCpu:function(cpuNumber){var cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents:function(isSecondaryImport){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_==undefined||this.ticks_==undefined)
+throw Error('Cannot find clock sync information in the system trace.');if(this.is64bit_==undefined)
+throw Error('Cannot determine pointer size of the system trace.');this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp:function(timestamp){var ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo:function(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
+if(this.is64bit_==undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op==kThreadDCStartOpcode){var decoded_size=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver==1){if(decoded_size>=52)
+this.is64bit_=true;else
+this.is64bit_=false;}else if(event.ver==2){if(decoded_size>=64)
+this.is64bit_=true;else
+this.is64bit_=false;}else if(event.ver==3){if(decoded_size>=60)
+this.is64bit_=true;else
+this.is64bit_=false;}}
+return true;},parseEvent:function(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
+var timestamp=this.importTimestamp(event.ts);var header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp:timestamp,is64:this.is64bit_};var decoder=this.decoder_;decoder.reset(event.payload);var handler=this.getEventHandler(header.guid,header.opcode);if(!handler)
+return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+text+')'});return false;}
+return true;},registerEventHandler:function(guid,opcode,handler){if(this.handlers_[guid]==undefined)
+this.handlers_[guid]=[];this.handlers_[guid][opcode]=handler;},getEventHandler:function(guid,opcode){if(this.handlers_[guid]==undefined)
+return undefined;return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter:EtwImporter};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
+Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];var r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">$')))
+break;r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>$/))
+return failure;var raw_events=r.endSavingLinesAndGetResult();raw_events=raw_events.slice(1,raw_events.length-1);var data64=raw_events.join('\n');var buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));var len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
+function _canImportFromHTML(text){if(/^<!DOCTYPE html>/.test(text)===false)
+return false;_extractEventsFromHTML(text);if(Trace2HTMLImporter.subtraces_.length===0)
+return false;return true;}
+Trace2HTMLImporter.canImport=function(events){return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,isTraceDataContainer:function(){return true;},extractSubtraces:function(){return Trace2HTMLImporter.subtraces_;},importEvents:function(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter:Trace2HTMLImporter};});'use strict';tr.exportTo('tr.e.net',function(){var AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.isTitleComputed_=false;}
+NetAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return'NetLog';},get title(){if(this.isTitleComputed_||!this.isTopLevel){return this.title_;}
+var getUrl=function(slice){if(slice.args!==undefined&&slice.args.params!==undefined&&slice.args.params.url!==undefined){return slice.args.params.url;}
+if(slice.subSlices===undefined||slice.subSlices.length===0)
+return undefined;for(var i=0;i<slice.subSlices.length;i++){var result=getUrl(slice.subSlices[i]);if(result!==undefined)
+return result;}
+return undefined;};var url=getUrl(this);if(url!==undefined&&url.length>0){this.title_=url;}else if(this.args!==undefined&&this.args.source_type!==undefined){this.title_=this.args.source_type;}
+this.isTitleComputed_=true;return this.title_;},set title(title){this.title_=title;}};AsyncSlice.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice:NetAsyncSlice};});'use strict';tr.exportTo('tr.e.chrome',function(){var KNOWN_PROPERTIES={children:1,name:1,address:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};if(args.children){args.children.forEach(function(child){this.childLayoutObjects_.push(new LayoutObject(snapshot,child));}.bind(this));}
+for(var property in args){if(!KNOWN_PROPERTIES[property])
+this.otherProperties_[property]=args[property];}}
+LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree:function(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)
+return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){var names=[];for(var name in this.otherProperties_){names.push(name);}
+return names;},getProperty:function(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)
+return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)
+return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject:LayoutObject};});'use strict';tr.exportTo('tr.e.audits',function(){var MAIN_FRAMETIME_TYPE='main_frametime_type';var IMPL_FRAMETIME_TYPE='impl_frametime_type';var MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';var IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRange(slice.start,slice.end))
+slicesInFilterRange.push(slice);}
+return slicesInFilterRange;}
+function ChromeProcessHelper(modelHelper,process){this.modelHelper=modelHelper;this.process=process;}
+ChromeProcessHelper.prototype={get pid(){return this.process.pid;},getFrameEventsInRange:function(frametimeType,range){var titleToGet;if(frametimeType==MAIN_FRAMETIME_TYPE)
+titleToGet=MAIN_RENDERING_STATS;else
+titleToGet=IMPL_RENDERING_STATS;var frameEvents=[];this.process.iterateAllEvents(function(event){if(event.title!==titleToGet)
+return;if(range.intersectsExplicitRange(event.start,event.end))
+frameEvents.push(event);});frameEvents.sort(function(a,b){return a.start-b.start});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){var frametimeData=[];for(var i=1;i<frameEvents.length;i++){var diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
+return frametimeData;}
+return{ChromeProcessHelper:ChromeProcessHelper,MAIN_FRAMETIME_TYPE:MAIN_FRAMETIME_TYPE,IMPL_FRAMETIME_TYPE:IMPL_FRAMETIME_TYPE,MAIN_RENDERING_STATS:MAIN_RENDERING_STATS,IMPL_RENDERING_STATS:IMPL_RENDERING_STATS,getSlicesIntersectingRange:getSlicesIntersectingRange,getFrametimeDataFromEvents:getFrametimeDataFromEvents};});'use strict';tr.exportTo('tr.e.audits',function(){function ChromeBrowserHelper(modelHelper,process){tr.e.audits.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrBrowserMain');}
+ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.e.audits.ChromeProcessHelper.prototype,get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRange(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRange(slice.start,slice.end);});},get hasLatencyEvents(){var hasLatency=false;this.modelHelper.model.getAllThreads().some(function(thread){thread.iterateAllEvents(function(event){if(!event.isTopLevel)
+return;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice))
+return;hasLatency=true;});return hasLatency;});return hasLatency;},getLatencyEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRange(slice.start,slice.end);});},getAllAsyncSlicesMatching:function(pred,opt_this){var events=[];this.iterAllThreads(function(thread){thread.iterateAllEvents(function(slice){if(pred.call(opt_this,slice))
+events.push(slice);});});return events;},getAllNetworkEventsInRange:function(rangeOfInterest){var networkEvents=[];this.modelHelper.model.getAllThreads().forEach(function(thread){thread.asyncSliceGroup.slices.forEach(function(slice){var match=false;if(slice.category=='net'||slice.category=='disabled-by-default-netlog'||slice.category=='netlog'){match=true;}
+if(!match)
+return;if(rangeOfInterest.intersectsExplicitRange(slice.start,slice.end))
+networkEvents.push(slice);});});return networkEvents;},iterAllThreads:function(func,opt_this){tr.b.iterItems(this.process.threads,function(tid,thread){func.call(opt_this,thread);});tr.b.iterItems(this.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;tr.b.iterItems(rendererProcess.threads,function(tid,thread){func.call(opt_this,thread);});},this);}};return{ChromeBrowserHelper:ChromeBrowserHelper};});'use strict';tr.exportTo('tr.e.audits',function(){function ChromeGpuHelper(modelHelper,process){tr.e.audits.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.isGpuProcess=function(process){if(process.findAtMostOneThreadNamed('CrBrowserMain')||process.findAtMostOneThreadNamed('CrRendererMain'))
+return false;return process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.prototype={__proto__:tr.e.audits.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;}};return{ChromeGpuHelper:ChromeGpuHelper};});'use strict';tr.exportTo('tr.e.audits',function(){function ChromeRendererHelper(modelHelper,process){tr.e.audits.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)
+return false;if(t.name.indexOf('CompositorTileWorker')===0)
+return true;if(t.name.indexOf('CompositorRasterWorker')===0)
+return true;return false;});};ChromeRendererHelper.isRenderProcess=function(process){if(!process.findAtMostOneThreadNamed('CrRendererMain'))
+return false;if(!process.findAtMostOneThreadNamed('Compositor'))
+return false;return true;};ChromeRendererHelper.prototype={__proto__:tr.e.audits.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;}};return{ChromeRendererHelper:ChromeRendererHelper};});'use strict';tr.exportTo('tr.e.audits',function(){function findChromeBrowserProcess(model){var browserProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.e.audits.ChromeBrowserHelper.isBrowserProcess(process))
+return;browserProcesses.push(process);},this);if(browserProcesses.length===0)
+return undefined;if(browserProcesses.length>1)
+return undefined;return browserProcesses[0];}
+function findChromeRenderProcesses(model){var rendererProcesses=[];model.getAllProcesses().forEach(function(process){if(!tr.e.audits.ChromeRendererHelper.isRenderProcess(process))
+return;rendererProcesses.push(process);});return rendererProcesses;}
+function findChromeGpuProcess(model){var gpuProcesses=model.getAllProcesses().filter(tr.e.audits.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!=1)
+return undefined;return gpuProcesses[0];}
+function ChromeModelHelper(model){this.model_=model;this.browserProcess_=findChromeBrowserProcess(model);if(this.browserProcess_){this.browserHelper_=new tr.e.audits.ChromeBrowserHelper(this,this.browserProcess_);}else{this.browserHelper_=undefined;}
+var gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.e.audits.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
+var rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){var rendererHelper=new tr.e.audits.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);}
+ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcess(model)!==undefined)
+return true;if(findChromeRenderProcesses(model).length)
+return true;return false;}
+ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){return this.browserProcess_;},get browserHelper(){return this.browserHelper_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;}};return{ChromeModelHelper:ChromeModelHelper};});'use strict';tr.exportTo('tr.e.cc',function(){var AsyncSlice=tr.model.AsyncSlice;var EventSet=tr.model.EventSet;var UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';var ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';var BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';var END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';var MAIN_RENDERER_THREAD_NAME='CrRendererMain';var COMPOSITOR_THREAD_NAME='Compositor';var POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';var IPC_FLOW_EVENT='disabled-by-default-ipc.flow';var INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent)
+this.determineModernTypeName_();}
+InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_)
+this.determineLegacyTypeName_();return this.typeName_;},checkTypeName_:function(){if(!this.typeName_)
+throw'Unable to determine typeName';var found=false;for(var type_name in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[type_name]){found=true;break;}}
+if(!found)
+this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;},determineModernTypeName_:function(){var lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)
+return;var characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_:function(){this.iterateAllDescendents(function(subSlice){var subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)
+return;if(!subSlice.typeName)
+return;if(this.typeName_&&subSlice.typeName_){var subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw'InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames';}}
+this.typeName_=subSlice.typeName_;},this);if(!this.typeName_)
+throw'InputLatencyAsyncSlice.determineLegacyTypeName_() failed';this.checkTypeName_();},getRendererHelper:function(sourceSlices){var traceModel=this.startThread.parent.model;if(!tr.e.audits.ChromeModelHelper.supportsModel(traceModel))
+return undefined;var mainThread=undefined;var compositorThread=undefined;for(var i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME)
+mainThread=sourceSlices[i].parentContainer;else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME)
+compositorThread=sourceSlices[i].parentContainer;if(mainThread&&compositorThread)
+break;}
+var modelHelper=new tr.e.audits.ChromeModelHelper(traceModel);var rendererHelpers=modelHelper.rendererHelpers;var pids=Object.keys(rendererHelpers);for(var i=0;i<pids.length;i++){var pid=pids[i];var rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread)
+return rendererHelper;}
+return undefined;},addEntireSliceHierarchy:function(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents:function(flowEvents){var slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);var newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1)
+slices.push(newSource);},this);var lastFlowEvent=flowEvents[flowEvents.length-1];var lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1)
+slices.push(lastSource);return slices;},addScrollUpdateEvents:function(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread)
+return;var compositorThread=rendererHelper.compositorThread;var gestureScrollUpdateStart=this.start;var gestureScrollUpdateEnd=this.end;var allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(var i in allCompositorAsyncSlices){var slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')
+continue;var parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd)
+continue;}else{if(parseInt(parentId)!==parseInt(this.id))
+continue;}
+slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs:function(slice,flowEvents){var fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)
+return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)
+return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1)
+fromOtherInputs=true;}},this);},this);return fromOtherInputs;},triggerOtherInputs:function(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0)
+return false;var flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice)
+return false;var endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents))
+return true;return false;},followSubsequentSlices:function(event,queue,visited,flowEvents){var stopFollowing=false;var inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)
+return;if(slice.title==='TaskQueueManager::RunTask')
+return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame')
+return;if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))
+return;}
+if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))
+return;}
+if(slice.title==='InputRouterImpl::ProcessInputEventAck')
+inputAck=true;if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent')
+stopFollowing=true;this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice:function(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);var nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw:function(beginImplFrame,visited){var pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){var nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices:function(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start)
+return a.start-b.start;return a.guid-b.guid;});},addRasterizationEvents:function(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)
+return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads)
+return;var rasterWorkerThreads=rendererHelper.rasterWorkerThreads;var prepare_tile_id=prepareTiles.args.prepare_tiles_id;var pendingEventQueue=[];if(sortedRasterizerSlices.length===0)
+this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);var numFinishedTasks=0;var RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';var IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';var FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(var i=0;i<sortedRasterizerSlices.length;i++){var task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepare_tile_id)
+this.addEntireSliceHierarchy(task.mostTopLevelSlice);}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)
+break;}}}
+while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents:function(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){var pendingEventQueue=[];var visitedEvents=new EventSet();var beginImplFrame=undefined;var prepareTiles=undefined;var sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!=0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);var COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles)
+this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);var COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame)
+this.backtraceFromDraw(beginImplFrame,visitedEvents);}
+var INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU)
+this.addScrollUpdateEvents(rendererHelper);},get associatedEvents(){if(this.associatedEvents_.length!==0)
+return this.associatedEvents_;var modelIndices=this.startThread.parent.model.modelIndices;var flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0)
+return this.associatedEvents_;var sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);var rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))
+return undefined;var data=this.args.data;if(!(END_COMP_NAME in data))
+return undefined;var latency=0;var endTime=data[END_COMP_NAME].time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
+return latency;}};var eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];var allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice:InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES:INPUT_EVENT_TYPE_NAMES};});'use strict';tr.exportTo('tr.e.rail',function(){var ColorScheme=tr.b.ColorScheme;var COMFORT_IMPORTANCE=2;var ALL_RAIL_TYPE_NAMES=['rail_response','rail_animate','rail_idle','rail_load'];var DOES_RAIL_TYPE_NAME_EXIST={};ALL_RAIL_TYPE_NAMES.forEach(function(railTypeName){DOES_RAIL_TYPE_NAME_EXIST[railTypeName]=true;});var RAIL_ORDER=[];ALL_RAIL_TYPE_NAMES.forEach(function(railTypeName){RAIL_ORDER.push(railTypeName.toUpperCase());RAIL_ORDER.push(userFriendlyRailTypeName(railTypeName).toUpperCase());});function RAILInteractionRecord(parentModel,title,railTypeName,start,duration){if(!DOES_RAIL_TYPE_NAME_EXIST[railTypeName])
+throw new Error(railTypeName+' is not listed in ALL_RAIL_TYPE_NAMES');var colorId=ColorScheme.getColorIdForReservedName(railTypeName);this.railTypeName_=railTypeName;this.name='';tr.model.InteractionRecord.call(this,parentModel,title,colorId,start,duration);}
+RAILInteractionRecord.prototype={__proto__:tr.model.InteractionRecord.prototype,updateArgs:function(){var args={};var layoutSlices=this.associatedEvents.filter(function(event){return event.title==='FrameView::layout';});var timeInLayout=tr.b.Statistics.sum(layoutSlices,function(event){return event.duration;});args['layoutInfo']={'timeInLayout':timeInLayout};this.args=args;},get railTypeName(){return this.railTypeName_;},get railScore(){var comfort=this.normalizedUserComfort;var efficiency=this.normalizedEfficiency;return weightedAverage2(comfort,efficiency,COMFORT_IMPORTANCE);},get normalizedUserComfort(){throw new Error('Not implemented');},get rawCpuMs(){var cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime)
+cpuMs+=event.cpuSelfTime;});return cpuMs;},get normalizedCpuEfficiency(){var minCpuMs=this.duration*this.minCpuFraction;var maxCpuMs=this.duration*this.maxCpuFraction;var normalizedCpu=tr.b.normalize(this.rawCpuMs,minCpuMs,maxCpuMs);return 1-tr.b.clamp(normalizedCpu,0,1);},get minCpuFraction(){return 0.5;},get maxCpuFraction(){return 1.5;},get normalizedEfficiency(){return this.normalizedCpuEfficiency;}};function computeNormalizedComfort(value,opts){if(typeof value!=='number')
+throw new Error('value must be a number');opts.exponentialBase=opts.exponentialBase||10;if(opts.exponentialBase<=1)
+throw new Error('exponentialBase must be greater than 1');opts.minComfortLinear=opts.minComfortLinear||0.2;if(opts.minComfortLinear<=0||opts.minComfortLinear>=1)
+throw new Error('minComfortLinear must be between 0 and 1 exclusive');opts.maxComfortLinear=opts.maxComfortLinear||0.9;if(opts.maxComfortLinear<=0||opts.maxComfortLinear>=1)
+throw new Error('maxComfortLinear must be between 0 and 1 exclusive');opts.logarithmicScale=opts.logarithmicScale||100;if(opts.logarithmicScale<=0)
+throw new Error('logarithmicScale must be positive');if(opts.minValueExponential>=opts.minValueLinear)
+throw new Error('minValueExponential must be less than minValueLinear');if(opts.minValueLinear>=opts.minValueLogarithmic)
+throw new Error('minValueLinear must be less than minValueLogarithmic');if(opts.minValueLogarithmic>=opts.maxValue)
+throw new Error('minValueLogarithmic must be less than maxValue');['minValueLinear','minValueExponential','minValueLogarithmic','maxValue','exponentialBase','minComfortLinear','maxComfortLinear','logarithmicScale'].forEach(function(opt){if(typeof opts[opt]!=='number')
+throw new Error(opt+' must be a number');});if(value<opts.minValueExponential)
+return 0;if(value<opts.minValueLinear){function computeRawComfort(value){return Math.pow(opts.exponentialBase,value);}
+return computeNormalizedComfortInternal(value,opts.minValueExponential,opts.minValueLinear,0,opts.minComfortLinear,computeRawComfort);}
+if(value<opts.minValueLogarithmic){function computeRawComfort(value){return value;}
+return computeNormalizedComfortInternal(value,opts.minValueLinear,opts.minValueLogarithmic,opts.minComfortLinear,opts.maxComfortLinear,computeRawComfort);}
+if(value<opts.maxValue){function computeRawComfort(value){return Math.log1p(opts.logarithmicScale*value);}
+return computeNormalizedComfortInternal(value,opts.minValueLogarithmic,opts.maxValue,opts.maxComfortLinear,1,computeRawComfort);}
+return 1;}
+function computeNormalizedComfortInternal(value,minValue,maxValue,minScore,maxScore,computeRawComfort){var normalizedValue=tr.b.normalize(value,minValue,maxValue);var rawComfort=computeRawComfort(normalizedValue);var minComfort=computeRawComfort(0);var maxComfort=computeRawComfort(1);var normalizedComfort=tr.b.normalize(rawComfort,minComfort,maxComfort);normalizedComfort=tr.b.lerp(normalizedComfort,minScore,maxScore);return tr.b.clamp(normalizedComfort,minScore,maxScore);}
+function weightedAverage2(x,y,opt_apriori){var numerator=0;var denominator=0;var xWeight=(opt_apriori||1)*Math.exp(1-x);numerator+=xWeight*x;denominator+=xWeight;var yWeight=Math.exp(1-y);numerator+=yWeight*y;denominator+=yWeight;return numerator/denominator;}
+function userFriendlyRailTypeName(railTypeName){if(railTypeName.length<6||railTypeName.indexOf('rail_')!=0)
+return railTypeName;return railTypeName[5].toUpperCase()+railTypeName.slice(6);}
+function railCompare(name1,name2){var i1=RAIL_ORDER.indexOf(name1.toUpperCase());var i2=RAIL_ORDER.indexOf(name2.toUpperCase());if(i1==-1&&i2==-1)
+return name1.localeCompare(name2);if(i1==-1)
+return 1;if(i2==-1)
+return-1;return i1-i2;}
+return{RAILInteractionRecord:RAILInteractionRecord,computeNormalizedComfort:computeNormalizedComfort,weightedAverage2:weightedAverage2,userFriendlyRailTypeName:userFriendlyRailTypeName,railCompare:railCompare,ALL_RAIL_TYPE_NAMES:ALL_RAIL_TYPE_NAMES};});'use strict';tr.exportTo('tr.e.rail',function(){function IdleInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Idle','rail_idle',start,duration);}
+IdleInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get normalizedUserComfort(){return 1;},get minCpuFraction(){return 0.1;},get maxCpuFraction(){return 1;}};return{IdleInteractionRecord:IdleInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){var COMFORT_LATENCY_REGIONS=[1000,5000,20000,60000];function LoadInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Load','rail_load',start,duration);this.renderProcessId=undefined;this.routingId=undefined;this.parentRoutingId=undefined;}
+LoadInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get normalizedUserComfort(){return 1-tr.e.rail.computeNormalizedComfort(this.duration,{minValueExponential:COMFORT_LATENCY_REGIONS[0],minValueLinear:COMFORT_LATENCY_REGIONS[1],minValueLogarithmic:COMFORT_LATENCY_REGIONS[2],maxValue:COMFORT_LATENCY_REGIONS[3]});}};return{LoadInteractionRecord:LoadInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){var COMFORT_FPS_REGIONS=[60,40,30,10];var LONG_FRAME_MS=50;var COMFORT_JANK_REGIONS=[0.05,0.1,0.2,0.3];function AnimationInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Animation','rail_animate',start,duration);this.frameEvents_=undefined;}
+AnimationInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get frameEvents(){if(this.frameEvents_)
+return this.frameEvents_;this.frameEvents_=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event.title===tr.e.audits.IMPL_RENDERING_STATS)
+this.frameEvents_.push(event);},this);return this.frameEvents_;},get normalizedUserComfort(){return tr.e.rail.weightedAverage2(this.normalizedJankComfort,this.normalizedFPSComfort);},get normalizedFPSComfort(){var durationSeconds=this.duration/1000;var avgSpf=durationSeconds/this.frameEvents.length;return 1-tr.e.rail.computeNormalizedComfort(avgSpf,{minValueExponential:1/COMFORT_FPS_REGIONS[0],minValueLinear:1/COMFORT_FPS_REGIONS[1],minValueLogarithmic:1/COMFORT_FPS_REGIONS[2],maxValue:1/COMFORT_FPS_REGIONS[3]});},get normalizedJankComfort(){var frameTimestamps=this.frameEvents.toArray().map(function(event){return event.start;});var absolute=false;var discrepancy=tr.b.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);return 1-tr.e.rail.computeNormalizedComfort(discrepancy,{minValueExponential:COMFORT_JANK_REGIONS[0],minValueLinear:COMFORT_JANK_REGIONS[1],minValueLogarithmic:COMFORT_JANK_REGIONS[2],maxValue:COMFORT_JANK_REGIONS[3]});}};return{AnimationInteractionRecord:AnimationInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){var COMFORT_LATENCY_REGIONS=[150,300,1000,5000];function ResponseInteractionRecord(parentModel,start,duration){tr.e.rail.RAILInteractionRecord.call(this,parentModel,'Response','rail_response',start,duration);}
+ResponseInteractionRecord.prototype={__proto__:tr.e.rail.RAILInteractionRecord.prototype,get normalizedUserComfort(){return 1-tr.e.rail.computeNormalizedComfort(this.duration,{minValueExponential:COMFORT_LATENCY_REGIONS[0],minValueLinear:COMFORT_LATENCY_REGIONS[1],minValueLogarithmic:COMFORT_LATENCY_REGIONS[2],maxValue:COMFORT_LATENCY_REGIONS[3]});}};return{ResponseInteractionRecord:ResponseInteractionRecord};});'use strict';tr.exportTo('tr.e.rail',function(){function ProtoIR(irType,name){this.irType=irType;this.names=new Set(name?[name]:undefined);this.start=Infinity;this.end=-Infinity;this.associatedEvents=new tr.model.EventSet();}
+ProtoIR.RESPONSE_TYPE='r';ProtoIR.ANIMATION_TYPE='a';ProtoIR.IGNORED_TYPE='ignored';ProtoIR.prototype={get isValid(){return this.end>this.start;},containsTypeNames:function(typeNames){for(var i=0;i<this.associatedEvents.length;++i){if(typeNames.indexOf(this.associatedEvents[i].typeName)>=0)
+return true;}
+return false;},containsSliceTitle:function(title){for(var i=0;i<this.associatedEvents.length;++i){if(title===this.associatedEvents[i].title)
+return true;}
+return false;},getIRConstructor:function(){switch(this.irType){case ProtoIR.RESPONSE_TYPE:return tr.e.rail.ResponseInteractionRecord;case ProtoIR.ANIMATION_TYPE:return tr.e.rail.AnimationInteractionRecord;}
+return undefined;},createInteractionRecord:function(model){if(!this.isValid){console.error('Invalid ProtoIR: '+this.debug()+' File a bug with this trace!');return undefined;}
+var constructor=this.getIRConstructor();if(constructor===undefined)
+return undefined;var ir=new constructor(model,this.start,this.end-this.start);var names=[];this.names.forEach(function(name){names.push(name);});ir.name=names.sort().join(',');ir.sourceEvents.addEventSet(this.associatedEvents);function pushAssociatedEvents(event){ir.associatedEvents.push(event);if(event.associatedEvents)
+ir.associatedEvents.addEventSet(event.associatedEvents);}
+this.associatedEvents.forEach(function(event){pushAssociatedEvents(event);if(event.subSlices)
+event.subSlices.forEach(pushAssociatedEvents);});return ir;},merge:function(other){other.names.forEach(function(name){this.names.add(name);}.bind(this));this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);},pushEvent:function(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},containsTimestampInclusive:function(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects:function(other){return(other.start<this.end)&&(other.end>this.start);},isNear:function(event,threshold){return(this.end+threshold)>event.start;},debug:function(){var debugString=this.irType+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoIR:ProtoIR};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){var allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)
+return;allAssociatedEvents.push(event);});});return allAssociatedEvents;}
+function getUnassociatedEvents(model,associatedEvents){var unassociatedEvents=new tr.model.EventSet();model.getAllProcesses().forEach(function(process){for(var tid in process.threads){var thread=process.threads[tid];thread.sliceGroup.iterateAllEvents(function(event){if(!associatedEvents.contains(event))
+unassociatedEvents.push(event);});}});return unassociatedEvents;}
+function getTotalCpuDuration(events){var cpuMs=0;events.forEach(function(event){if(event.cpuSelfTime)
+cpuMs+=event.cpuSelfTime;});return cpuMs;}
+function getIRCoverageFromModel(model){var associatedEvents=getAssociatedEvents(model.interactionRecords);if(!associatedEvents.length)
+return undefined;var unassociatedEvents=getUnassociatedEvents(model,associatedEvents);var associatedCpuMs=getTotalCpuDuration(associatedEvents);var unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);var totalEventCount=associatedEvents.length+unassociatedEvents.length;var totalCpuMs=associatedCpuMs+unassociatedCpuMs;return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio:associatedCpuMs/totalCpuMs};}
+return{getIRCoverageFromModel:getIRCoverageFromModel,getAssociatedEvents:getAssociatedEvents,getUnassociatedEvents:getUnassociatedEvents};});'use strict';tr.exportTo('tr.e.rail',function(){var INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;var ProtoIR=tr.e.rail.ProtoIR;function compareEvents(x,y){if(x.start!==y.start)
+return x.start-y.start;if(x.end!==y.end)
+return x.end-y.end;if(x.guid&&y.guid)
+return x.guid-y.guid;return 0;}
+function causedFrame(event){for(var i=0;i<event.associatedEvents.length;++i){if(event.associatedEvents[i].title===tr.e.audits.IMPL_RENDERING_STATS)
+return true;}
+return false;}
+function forEventTypesIn(events,typeNames,cb,opt_this){events.forEach(function(event){if(typeNames.indexOf(event.typeName)>=0){cb.call(opt_this,event);}});}
+var RENDER_FRAME_IMPL_PREFIX='RenderFrameImpl::';var CREATE_CHILD_TITLE=RENDER_FRAME_IMPL_PREFIX+'createChildFrame';var START_LOAD_TITLE=RENDER_FRAME_IMPL_PREFIX+'didStartProvisionalLoad';var FAIL_LOAD_TITLE=RENDER_FRAME_IMPL_PREFIX+'didFailProvisionalLoad';function isRenderFrameImplEvent(event){return event.title.indexOf(RENDER_FRAME_IMPL_PREFIX)===0;}
+var INPUT_MERGE_THRESHOLD_MS=200;var ANIMATION_MERGE_THRESHOLD_MS=1;var MOUSE_WHEEL_THRESHOLD_MS=40;var MOUSE_MOVE_THRESHOLD_MS=40;var INSIGNIFICANT_MS=1;var KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];var MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];var MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];var MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];var TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];var PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];var FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];var TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];var SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];var ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);var RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';var CSS_ANIMATION_TITLE='Animation';var LOAD_STARTUP_IR_NAME='Startup';var LOAD_SUCCEEDED_IR_NAME='Succeeded';var LOAD_FAILED_IR_NAME='Failed';var KEYBOARD_IR_NAME='Keyboard';var MOUSE_IR_NAME='Mouse';var MOUSEWHEEL_IR_NAME='MouseWheel';var TAP_IR_NAME='Tap';var PINCH_IR_NAME='Pinch';var FLING_IR_NAME='Fling';var TOUCH_IR_NAME='Touch';var SCROLL_IR_NAME='Scroll';var CSS_IR_NAME='CSS';function RAILIRFinder(model,modelHelper){this.model=model;this.modelHelper=modelHelper;};RAILIRFinder.supportsModelHelper=function(modelHelper){return modelHelper.browserHelper!==undefined;};RAILIRFinder.prototype={findAllInteractionRecords:function(){var rirs=[];rirs.push.apply(rirs,this.findLoadInteractionRecords());rirs.push.apply(rirs,this.findInputInteractionRecords());rirs.push.apply(rirs,this.findIdleInteractionRecords(rirs));this.collectUnassociatedEvents_(rirs);return rirs;},setIRNames_:function(name,irs){irs.forEach(function(ir){ir.name=name;});},collectUnassociatedEvents_:function(rirs){var vacuumIRs=[];rirs.forEach(function(ir){if(ir instanceof tr.e.rail.LoadInteractionRecord||ir instanceof tr.e.rail.IdleInteractionRecord)
+vacuumIRs.push(ir);});if(vacuumIRs.length===0)
+return;var allAssociatedEvents=tr.model.getAssociatedEvents(rirs);var unassociatedEvents=tr.model.getUnassociatedEvents(this.model,allAssociatedEvents);unassociatedEvents.forEach(function(event){if(!(event instanceof tr.model.ThreadSlice))
+return;if(!event.isTopLevel)
+return;for(var iri=0;iri<vacuumIRs.length;++iri){var ir=vacuumIRs[iri];if((event.start>=ir.start)&&(event.start<ir.end)){ir.associatedEvents.addEventSet(event.entireHierarchy);return;}}});},findIdleInteractionRecords:function(otherIRs){if(this.model.bounds.isEmpty)
+return;var emptyRanges=tr.b.findEmptyRangesBetweenRanges(tr.b.convertEventsToRanges(otherIRs),this.model.bounds);var irs=[];var model=this.model;emptyRanges.forEach(function(range){if(range.max<(range.min+INSIGNIFICANT_MS))
+return;irs.push(new tr.e.rail.IdleInteractionRecord(model,range.min,range.max-range.min));});return irs;},getAllFrameEvents:function(){var frameEvents=[];frameEvents.push.apply(frameEvents,this.modelHelper.browserHelper.getFrameEventsInRange(tr.e.audits.IMPL_FRAMETIME_TYPE,this.model.bounds));tr.b.iterItems(this.modelHelper.rendererHelpers,function(pid,renderer){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.e.audits.IMPL_FRAMETIME_TYPE,this.model.bounds));},this);return frameEvents.sort(compareEvents);},getStartLoadEvents:function(){function isStartLoadSlice(slice){return slice.title===START_LOAD_TITLE;}
+return this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartLoadSlice).sort(compareEvents);},getFailLoadEvents:function(){function isFailLoadSlice(slice){return slice.title===FAIL_LOAD_TITLE;}
+return this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isFailLoadSlice).sort(compareEvents);},getStartupEvents:function(){function isStartupSlice(slice){return slice.title==='BrowserMainLoop::CreateThreads';}
+var events=this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);var deduper=new tr.model.EventSet();events.forEach(function(event){var sliceGroup=event.parentContainer.sliceGroup;var slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice)
+deduper.push(slice);});return deduper.toArray();},findLoadInteractionRecords_:function(openingEvents,closingEvents){var lirs=[];var model=this.model;openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)
+return;if(closingEvent.openingEvent)
+return;if(closingEvent.start<=openingEvent.start)
+return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid)
+return;openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;var lir=new tr.e.rail.LoadInteractionRecord(model,openingEvent.start,closingEvent.end-openingEvent.start);lir.associatedEvents.push(openingEvent);lir.associatedEvents.push(closingEvent);if(isRenderFrameImplEvent(openingEvent)){lir.renderProcessId=openingEvent.parentContainer.parent.pid;lir.routingId=openingEvent.args.id;lir.parentRoutingId=this.findLoadParentRoutingId_(lir);}
+lirs.push(lir);},this);},this);return lirs;},findLoadParentRoutingId_:function(lir){function isCreateChildEvent(event){return((event.title===CREATE_CHILD_TITLE)&&(event.parentContainer.parent.pid===lir.renderProcessId)&&(event.args.child===lir.routingId));}
+var parentRoutingId=undefined;this.modelHelper.browserHelper.getAllAsyncSlicesMatching(isCreateChildEvent).forEach(function(event){parentRoutingId=event.args.id;});return parentRoutingId;},findLoadInteractionRecords:function(){var startupEvents=this.getStartupEvents();var commitLoadEvents=this.modelHelper.browserHelper.getCommitProvisionalLoadEventsInRange(this.model.bounds);var frameEvents=this.getAllFrameEvents();var startLoadEvents=this.getStartLoadEvents();var failLoadEvents=this.getFailLoadEvents();var lirs=[];var startupLIRs=this.findLoadInteractionRecords_(startupEvents,frameEvents);this.setIRNames_(LOAD_STARTUP_IR_NAME,startupLIRs);lirs.push.apply(lirs,startupLIRs);var successfulLIRs=this.findLoadInteractionRecords_(commitLoadEvents,frameEvents);this.setIRNames_(LOAD_SUCCEEDED_IR_NAME,successfulLIRs);var renderLIRs=successfulLIRs;var failedLIRs=this.findLoadInteractionRecords_(startLoadEvents,failLoadEvents);this.setIRNames_(LOAD_FAILED_IR_NAME,failedLIRs);renderLIRs.push.apply(renderLIRs,failedLIRs);renderLIRs.forEach(function(lir){if(lir.parentRoutingId===undefined){lirs.push(lir);}},this);return lirs;},findInputInteractionRecords:function(){var sortedInputEvents=this.getSortedInputEvents();var protoIRs=this.findProtoIRs(sortedInputEvents);protoIRs=this.postProcessProtoIRs(protoIRs);this.checkAllInputEventsHandled(sortedInputEvents,protoIRs);var irs=[];var model=this.model;protoIRs.forEach(function(protoIR){var ir=protoIR.createInteractionRecord(model);if(ir)
+irs.push(ir);});return irs;},findProtoIRs:function(sortedInputEvents){var protoIRs=[];var handlers=[this.handleKeyboardEvents,this.handleMouseResponseEvents,this.handleMouseWheelEvents,this.handleMouseDragEvents,this.handleTapResponseEvents,this.handlePinchEvents,this.handleFlingEvents,this.handleTouchEvents,this.handleScrollEvents,this.handleCSSAnimations];handlers.forEach(function(handler){protoIRs.push.apply(protoIRs,handler.call(this,sortedInputEvents));},this);protoIRs.sort(compareEvents);return protoIRs;},getSortedInputEvents:function(){var inputEvents=[];var browserProcess=this.modelHelper.browserHelper.process;var mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');mainThread.asyncSliceGroup.iterateAllEvents(function(slice){if(!slice.isTopLevel)
+return;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))
+return;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end))
+return;inputEvents.push(slice);},this);return inputEvents.sort(compareEvents);},handleKeyboardEvents:function(sortedInputEvents){var protoIRs=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){var pir=new ProtoIR(ProtoIR.RESPONSE_TYPE,KEYBOARD_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);});return protoIRs;},handleMouseResponseEvents:function(sortedInputEvents){var protoIRs=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){var pir=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);});return protoIRs;},handleMouseWheelEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){var prevEvent=prevEvent_;prevEvent_=event;if(currentPIR&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPIR.irType===ProtoIR.ANIMATION_TYPE){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,MOUSEWHEEL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+return;}
+currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSEWHEEL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);});return protoIRs;},handleMouseDragEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){var pir=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);}else{mouseDownEvent=event;}
+break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}else if(!currentPIR||!currentPIR.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);currentPIR.pushEvent(event);if(mouseDownEvent){currentPIR.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
+protoIRs.push(currentPIR);}else{if(currentPIR.irType===ProtoIR.ANIMATION_TYPE){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,MOUSE_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}}
+break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){var pir=new ProtoIR(causedFrame(event)?ProtoIR.RESPONSE_TYPE:ProtoIR.IGNORED_TYPE,MOUSE_IR_NAME);pir.pushEvent(event);protoIRs.push(pir);break;}
+if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,MOUSE_IR_NAME);if(mouseDownEvent)
+currentPIR.associatedEvents.push(mouseDownEvent);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+mouseDownEvent=undefined;currentPIR=undefined;break;}});if(mouseDownEvent){currentPIR=new ProtoIR(ProtoIR.IGNORED_TYPE);currentPIR.pushEvent(mouseDownEvent);protoIRs.push(currentPIR);}
+return protoIRs;},handleTapResponseEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TAP_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);break;case INPUT_TYPE.TAP:if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TAP_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+currentPIR=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPIR){var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);break;}
+if(currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TAP_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+currentPIR=undefined;break;}});return protoIRs;},handlePinchEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var sawFirstUpdate=false;var modelBounds=this.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPIR&&currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR.pushEvent(event);break;}
+currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,PINCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);sawFirstUpdate=false;break;case INPUT_TYPE.PINCH_UPDATE:if(!currentPIR||((currentPIR.irType===ProtoIR.RESPONSE_TYPE)&&sawFirstUpdate)||!currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,PINCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}else{currentPIR.pushEvent(event);sawFirstUpdate=true;}
+break;case INPUT_TYPE.PINCH_END:if(currentPIR){currentPIR.pushEvent(event);}else{var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}
+currentPIR=undefined;break;}});return protoIRs;},handleFlingEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
+var browserHelper=this.modelHelper.browserHelper;var flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,FLING_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+return;}
+switch(event.typeName){case INPUT_TYPE.FLING_START:if(currentPIR){console.error('Another FlingStart? File a bug with this trace!');currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,FLING_IR_NAME);currentPIR.pushEvent(event);currentPIR.end=0;protoIRs.push(currentPIR);}
+break;case INPUT_TYPE.FLING_CANCEL:if(currentPIR){currentPIR.pushEvent(event);currentPIR.end=event.start;currentPIR=undefined;}else{var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}
+break;}});if(currentPIR&&!currentPIR.end)
+currentPIR.end=this.model.bounds.max;return protoIRs;},handleTouchEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPIR){currentPIR.pushEvent(event);}else{currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,TOUCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);sawFirstMove=false;}
+break;case INPUT_TYPE.TOUCH_MOVE:if(!currentPIR){currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,TOUCH_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);break;}
+if((sawFirstMove&&(currentPIR.irType===ProtoIR.RESPONSE_TYPE))||!currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){var prevEnd=currentPIR.end;currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,TOUCH_IR_NAME);currentPIR.pushEvent(event);currentPIR.start=prevEnd;protoIRs.push(currentPIR);}else{currentPIR.pushEvent(event);sawFirstMove=true;}
+break;case INPUT_TYPE.TOUCH_END:if(!currentPIR){var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);break;}
+if(currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPIR.pushEvent(event);}else{var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);}
+currentPIR=undefined;break;}});return protoIRs;},handleScrollEvents:function(sortedInputEvents){var protoIRs=[];var currentPIR=undefined;var sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPIR=new ProtoIR(ProtoIR.RESPONSE_TYPE,SCROLL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPIR){if(currentPIR.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPIR.irType===ProtoIR.ANIMATION_TYPE)||!sawFirstUpdate)){currentPIR.pushEvent(event);sawFirstUpdate=true;}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,SCROLL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}}else{currentPIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,SCROLL_IR_NAME);currentPIR.pushEvent(event);protoIRs.push(currentPIR);}
+break;case INPUT_TYPE.SCROLL_END:if(!currentPIR){console.error('ScrollEnd without ScrollUpdate? '+'File a bug with this trace!');var pir=new ProtoIR(ProtoIR.IGNORED_TYPE);pir.pushEvent(event);protoIRs.push(pir);break;}
+currentPIR.pushEvent(event);break;}});return protoIRs;},handleCSSAnimations:function(sortedInputEvents){var animationEvents=this.modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&(event.duration>0));});var animationRanges=[];animationEvents.forEach(function(event){animationRanges.push({min:event.start,max:event.end,event:event});});function merge(ranges){var protoIR=new ProtoIR(ProtoIR.ANIMATION_TYPE,CSS_IR_NAME);ranges.forEach(function(range){protoIR.pushEvent(range.event);});return protoIR;}
+return tr.b.mergeRanges(animationRanges,ANIMATION_MERGE_THRESHOLD_MS,merge);},postProcessProtoIRs:function(protoIRs){protoIRs=this.mergeIntersectingResponses(protoIRs);protoIRs=this.mergeIntersectingAnimations(protoIRs);protoIRs=this.fixResponseAnimationStarts(protoIRs);protoIRs=this.fixTapResponseTouchAnimations(protoIRs);return protoIRs;},mergeIntersectingResponses:function(protoIRs){var newPIRs=[];while(protoIRs.length){var pir=protoIRs.shift();newPIRs.push(pir);if(pir.irType!==ProtoIR.RESPONSE_TYPE)
+continue;for(var i=0;i<protoIRs.length;++i){var otherPIR=protoIRs[i];if(otherPIR.irType!==pir.irType)
+continue;if(!otherPIR.intersects(pir))
+continue;var typeNames=pir.associatedEvents.map(function(event){return event.typeName;});if(otherPIR.containsTypeNames(typeNames))
+continue;pir.merge(otherPIR);protoIRs.splice(i,1);--i;}}
+return newPIRs;},mergeIntersectingAnimations:function(protoIRs){var newPIRs=[];while(protoIRs.length){var pir=protoIRs.shift();newPIRs.push(pir);if(pir.irType!==ProtoIR.ANIMATION_TYPE)
+continue;var isCSS=pir.containsSliceTitle(CSS_ANIMATION_TITLE);var isFling=pir.containsTypeNames([INPUT_TYPE.FLING_START]);for(var i=0;i<protoIRs.length;++i){var otherPIR=protoIRs[i];if(otherPIR.irType!==pir.irType)
+continue;if(isCSS!=otherPIR.containsSliceTitle(CSS_ANIMATION_TITLE))
+continue;if(!otherPIR.intersects(pir))
+continue;if(isFling!=otherPIR.containsTypeNames([INPUT_TYPE.FLING_START]))
+continue;pir.merge(otherPIR);protoIRs.splice(i,1);--i;}}
+return newPIRs;},fixResponseAnimationStarts:function(protoIRs){protoIRs.forEach(function(apir){if(apir.irType!==ProtoIR.ANIMATION_TYPE)
+return;protoIRs.forEach(function(rpir){if(rpir.irType!==ProtoIR.RESPONSE_TYPE)
+return;if(!apir.containsTimestampInclusive(rpir.end))
+return;if(apir.containsTimestampInclusive(rpir.start))
+return;apir.start=rpir.end;});});return protoIRs;},fixTapResponseTouchAnimations:function(protoIRs){function isTapResponse(pir){return(pir.irType===ProtoIR.RESPONSE_TYPE)&&pir.containsTypeNames([INPUT_TYPE.TAP]);}
+function isTouchAnimation(pir){return(pir.irType===ProtoIR.ANIMATION_TYPE)&&pir.containsTypeNames([INPUT_TYPE.TOUCH_MOVE])&&!pir.containsTypeNames([INPUT_TYPE.SCROLL_UPDATE,INPUT_TYPE.PINCH_UPDATE]);}
+var newPIRs=[];while(protoIRs.length){var pir=protoIRs.shift();newPIRs.push(pir);var pirIsTapResponse=isTapResponse(pir);var pirIsTouchAnimation=isTouchAnimation(pir);if(!pirIsTapResponse&&!pirIsTouchAnimation)
+continue;for(var i=0;i<protoIRs.length;++i){var otherPIR=protoIRs[i];if(!otherPIR.intersects(pir))
+continue;if(pirIsTapResponse&&!isTouchAnimation(otherPIR))
+continue;if(pirIsTouchAnimation&&!isTapResponse(otherPIR))
+continue;pir.irType=ProtoIR.RESPONSE_TYPE;pir.merge(otherPIR);protoIRs.splice(i,1);--i;}}
+return newPIRs;},checkAllInputEventsHandled:function(sortedInputEvents,protoIRs){var handledEvents=[];protoIRs.forEach(function(protoIR){protoIR.associatedEvents.forEach(function(event){if(handledEvents.indexOf(event)>=0){console.error('double-handled event',event.typeName,parseInt(event.start),parseInt(event.end),protoIR);return;}
+handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){console.error('UNHANDLED INPUT EVENT!',event.typeName,parseInt(event.start),parseInt(event.end));}});}};function createCustomizeModelLinesFromModel(model){var modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');var typeNames={};for(var typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
+var modelEvents=new tr.model.EventSet();model.interactionRecords.forEach(function(ir,index){modelEvents.addEventSet(ir.sourceEvents);});modelEvents=modelEvents.toArray();modelEvents.sort(compareEvents);modelEvents.forEach(function(event){var startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
+typeNames[event.typeName]+',');}else if(event.title==='RenderFrameImpl::didCommitProvisionalLoad'){modelLines.push('      audits.addCommitLoadEvent(model,');}else if(event.title==='InputHandlerProxy::HandleGestureFling::started'){modelLines.push('      audits.addFlingAnimationEvent(model,');}else if(event.title===tr.e.audits.IMPL_RENDERING_STATS){modelLines.push('      audits.addFrameEvent(model,');}else if(event.title===CSS_ANIMATION_TITLE){modelLines.push('      audits.addEvent(model.rendererMain, {');modelLines.push('        title: \'Animation\', '+startAndEnd);return;}else{throw('You must extend createCustomizeModelLinesFromModel()'+'to support this event:\n'+event.title+'\n');}
+modelLines.push('          {'+startAndEnd);});modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {'+'title: \'model end\', '+'start: '+(parseInt(model.bounds.max)-1)+', '+'end: '+parseInt(model.bounds.max)+'});');return modelLines;}
+function createExpectedIRLinesFromModel(model){var expectedLines=[];var irCount=model.interactionRecords.length;model.interactionRecords.forEach(function(ir,index){var irString='      {';irString+='title: \''+ir.title+'\', ';irString+='start: '+parseInt(ir.start)+', ';irString+='end: '+parseInt(ir.end)+', ';irString+='eventCount: '+ir.sourceEvents.length;irString+='}';if(index<(irCount-1))
+irString+=',';expectedLines.push(irString);});return expectedLines;}
+function createIRFinderTestCaseStringFromModel(model){var filename=window.location.hash.substr(1);var testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{var testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    var verifier = new IRVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedIRs = [');testLines.push.apply(testLines,createExpectedIRLinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
+return{RAILIRFinder:RAILIRFinder,createIRFinderTestCaseStringFromModel:createIRFinderTestCaseStringFromModel};});'use strict';tr.exportTo('tr.e.audits',function(){var Auditor=tr.c.Auditor;function ChromeAuditor(model){Auditor.call(this,model);if(tr.e.audits.ChromeModelHelper.supportsModel(this.model)){var modelHelper=new tr.e.audits.ChromeModelHelper(this.model);if(modelHelper.browserHelper===undefined)
+this.modelHelper=undefined;else
+this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}};ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate:function(){if(!this.modelHelper)
+return;this.model.getAllProcesses().forEach(function(process){if(process.labels!==undefined&&process.labels.length==1&&process.labels[0]=='chrome://tracing')
+process.important=false;});},runAudit:function(){if(!this.modelHelper)
+return;if(!tr.e.rail.RAILIRFinder.supportsModelHelper(this.modelHelper))
+return;var rirf=new tr.e.rail.RAILIRFinder(this.model,this.modelHelper);var rirs=undefined;try{rirs=rirf.findAllInteractionRecords();}catch(error){this.model.importWarning({type:'RAILIRFinder',message:error,showToUser:true});return;}
+rirs.forEach(function(ir){this.model.addInteractionRecord(ir);},this);}};Auditor.register(ChromeAuditor);return{ChromeAuditor:ChromeAuditor};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;};if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless)
+Settings.setAlternativeStorageInstance(new HeadlessStorage());else
+Settings.setAlternativeStorageInstance(global.sessionStorage);});}
+function SessionSettings(){return SessionSettings;}
+function AddStaticStorageFunctionsToClass_(input_class,storage){input_class.storage_=storage;input_class.get=function(key,opt_default,opt_namespace){key=input_class.namespace_(key,opt_namespace);var rawVal=input_class.storage_.getItem(key);if(rawVal===null||rawVal===undefined)
+return opt_default;try{return JSON.parse(rawVal).value;}catch(e){input_class.storage_.removeItem(key);return opt_default;}};input_class.set=function(key,value,opt_namespace){if(value===undefined)
+throw new Error('Settings.set: value must not be undefined');var v=JSON.stringify({value:value});input_class.storage_.setItem(input_class.namespace_(key,opt_namespace),v);};input_class.keys=function(opt_namespace){var result=[];opt_namespace=opt_namespace||'';for(var i=0;i<input_class.storage_.length;i++){var key=input_class.storage_.key(i);if(input_class.isnamespaced_(key,opt_namespace))
+result.push(input_class.unnamespace_(key,opt_namespace));}
+return result;};input_class.isnamespaced_=function(key,opt_namespace){return key.indexOf(input_class.normalize_(opt_namespace))==0;};input_class.namespace_=function(key,opt_namespace){return input_class.normalize_(opt_namespace)+key;};input_class.unnamespace_=function(key,opt_namespace){return key.replace(input_class.normalize_(opt_namespace),'');};input_class.normalize_=function(opt_namespace){return input_class.NAMESPACE+(opt_namespace?opt_namespace+'.':'');};input_class.setAlternativeStorageInstance=function(instance){input_class.storage_=instance;};input_class.getAlternativeStorageInstance=function(){if(!tr.isHeadless&&input_class.storage_===localStorage)
+return undefined;return input_class.storage_;};input_class.NAMESPACE='trace-viewer';};function HeadlessStorage(){this.length=0;this.hasItem_={};this.items_={};this.itemsAsArray_=undefined;}
+HeadlessStorage.prototype={key:function(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined)
+return this.itemsAsArray_;var itemsAsArray=[];for(var k in this.items_)
+itemsAsArray.push(k);this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem:function(key){if(!this.hasItem_[key])
+return null;return this.items_[key];},removeItem:function(key){if(!this.hasItem_[key])
+return;var value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem:function(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
+this.items_[key]=value;this.hasItem_[key]=true;this.length++;this.itemsAsArray_=undefined;return value;}};if(tr.isHeadless){AddStaticStorageFunctionsToClass_(Settings,new HeadlessStorage());AddStaticStorageFunctionsToClass_(SessionSettings,new HeadlessStorage());}else{AddStaticStorageFunctionsToClass_(Settings,localStorage);AddStaticStorageFunctionsToClass_(SessionSettings,sessionStorage);}
+return{Settings:Settings,SessionSettings:SessionSettings};});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
+ScriptingObject.prototype={onModelChanged:function(model){}};return{ScriptingObject:ScriptingObject};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));var typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
+function ScriptingObjectRegistry(){}
+var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_:function(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged)
+v.onModelChanged(this.brushingStateController.model);},this);},addScriptObject:function(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand:function(command){var f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController:ScriptingController,ScriptingObjectRegistry:ScriptingObjectRegistry};});'use strict';Polymer('tr-ui-a-tab-view',{ready:function(){this.$.tshh.style.display='none';this.tabs_=[];this.selectedTab_=undefined;for(var i=0;i<this.children.length;i++)
+this.processAddedChild_(this.children[i]);this.childrenObserver_=new MutationObserver(this.childrenUpdated_.bind(this));this.childrenObserver_.observe(this,{childList:'true'});},get tabStripHeadingText(){return this.$.tsh.textContent;},set tabStripHeadingText(tabStripHeadingText){this.$.tsh.textContent=tabStripHeadingText;if(!!tabStripHeadingText)
+this.$.tshh.style.display='';else
+this.$.tshh.style.display='none';},get selectedTab(){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(this.selectedTab_)
+return this.selectedTab_.content;return undefined;},set selectedTab(content){this.childrenUpdated_(this.childrenObserver_.takeRecords(),this.childrenObserver_);if(content===undefined||content===null){this.changeSelectedTabById_(undefined);return;}
+var contentTabId=undefined;for(var i=0;i<this.tabs_.length;i++)
+if(this.tabs_[i].content===content){contentTabId=this.tabs_[i].id;break;}
+if(contentTabId===undefined)
+return;this.changeSelectedTabById_(contentTabId);},get tabsHidden(){var ts=this.shadowRoot.querySelector('tab-strip');return ts.hasAttribute('tabs-hidden');},set tabsHidden(tabsHidden){tabsHidden=!!tabsHidden;var ts=this.shadowRoot.querySelector('tab-strip');if(tabsHidden)
+ts.setAttribute('tabs-hidden',true);else
+ts.removeAttribute('tabs-hidden');},get tabs(){return this.tabs_.map(function(tabObject){return tabObject.content;});},processAddedChild_:function(child){var observerAttributeSelected=new MutationObserver(this.childAttributesChanged_.bind(this));var observerAttributeTabLabel=new MutationObserver(this.childAttributesChanged_.bind(this));var tabObject={id:this.tabs_.length,content:child,label:child.getAttribute('tab-label'),observers:{forAttributeSelected:observerAttributeSelected,forAttributeTabLabel:observerAttributeTabLabel}};this.tabs_.push(tabObject);if(child.hasAttribute('selected')){if(this.selectedTab_)
+child.removeAttribute('selected');else
+this.setSelectedTabById_(tabObject.id);}
+var previousSelected=child.selected;var tabView=this;Object.defineProperty(child,'selected',{configurable:true,set:function(value){if(value){tabView.changeSelectedTabById_(tabObject.id);return;}
+var wasSelected=tabView.selectedTab_===tabObject;if(wasSelected)
+tabView.changeSelectedTabById_(undefined);},get:function(){return this.hasAttribute('selected');}});if(previousSelected)
+child.selected=previousSelected;observerAttributeSelected.observe(child,{attributeFilter:['selected']});observerAttributeTabLabel.observe(child,{attributeFilter:['tab-label']});},processRemovedChild_:function(child){for(var i=0;i<this.tabs_.length;i++){this.tabs_[i].id=i;if(this.tabs_[i].content===child){this.tabs_[i].observers.forAttributeSelected.disconnect();this.tabs_[i].observers.forAttributeTabLabel.disconnect();if(this.tabs_[i]===this.selectedTab_){this.clearSelectedTab_();this.fire('selected-tab-change');}
+child.removeAttribute('selected');delete child.selected;this.tabs_.splice(i,1);i--;}}},childAttributesChanged_:function(mutations,observer){var tabObject=undefined;for(var i=0;i<this.tabs_.length;i++){var observers=this.tabs_[i].observers;if(observers.forAttributeSelected===observer||observers.forAttributeTabLabel===observer){tabObject=this.tabs_[i];break;}}
+if(!tabObject)
+return;for(var i=0;i<mutations.length;i++){var node=tabObject.content;if(mutations[i].attributeName==='tab-label')
+tabObject.label=node.getAttribute('tab-label');if(mutations[i].attributeName==='selected'){var nodeIsSelected=node.hasAttribute('selected');if(nodeIsSelected)
+this.changeSelectedTabById_(tabObject.id);else
+this.changeSelectedTabById_(undefined);}}},childrenUpdated_:function(mutations,observer){mutations.forEach(function(mutation){for(var i=0;i<mutation.removedNodes.length;i++)
+this.processRemovedChild_(mutation.removedNodes[i]);for(var i=0;i<mutation.addedNodes.length;i++)
+this.processAddedChild_(mutation.addedNodes[i]);},this);},tabButtonSelectHandler_:function(event,detail,sender){this.changeSelectedTabById_(sender.getAttribute('button-id'));},changeSelectedTabById_:function(id){var newTab=id!==undefined?this.tabs_[id]:undefined;var changed=this.selectedTab_!==newTab;this.saveCurrentTabScrollPosition_();this.clearSelectedTab_();if(id!==undefined){this.setSelectedTabById_(id);this.restoreCurrentTabScrollPosition_();}
+if(changed)
+this.fire('selected-tab-change');},setSelectedTabById_:function(id){this.selectedTab_=this.tabs_[id];this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.setAttribute('selected','selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});},saveTabStates:function(){this.saveCurrentTabScrollPosition_();},saveCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.selectedTab_.content._savedScrollTop=this.$['content-container'].scrollTop;this.selectedTab_.content._savedScrollLeft=this.$['content-container'].scrollLeft;}},restoreCurrentTabScrollPosition_:function(){if(this.selectedTab_){this.$['content-container'].scrollTop=this.selectedTab_.content._savedScrollTop||0;this.$['content-container'].scrollLeft=this.selectedTab_.content._savedScrollLeft||0;}},clearSelectedTab_:function(){if(this.selectedTab_){this.selectedTab_.observers.forAttributeSelected.disconnect();this.selectedTab_.content.removeAttribute('selected');this.selectedTab_.observers.forAttributeSelected.observe(this.selectedTab_.content,{attributeFilter:['selected']});this.selectedTab_=undefined;}}});'use strict';Polymer('tr-ui-a-sub-view',{set tabLabel(label){return this.setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}});'use strict';tr.exportTo('tr.ui.b',function(){var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocate();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
+BrushingState.prototype={get guid(){return this.guid_;},clone:function(){var that=new BrushingState();that.selection_=this.selection_;that.findMatches_=this.findMatches_;that.analysisViewRelatedEvents_=this.analysisViewRelatedEvents_;that.analysisLinkHoveredEvents_=this.analysisLinkHoveredEvents_;that.viewSpecificBrushingStates_=this.viewSpecificBrushingStates_;return that;},equals:function(that){if(!this.selection_.equals(that.selection_))
+return false;if(!this.findMatches_.equals(that.findMatches_))
+return false;if(!this.analysisViewRelatedEvents_.equals(that.analysisViewRelatedEvents_)){return false;}
+if(!this.analysisLinkHoveredEvents_.equals(that.analysisLinkHoveredEvents_)){return false;}
+return true;},get selectionOfInterest(){if(this.selection_.length)
+return this.selection_;if(this.highlight_.length)
+return this.highlight_;if(this.analysisViewRelatedEvents_.length)
+return this.analysisViewRelatedEvents_;if(this.analysisLinkHoveredEvents_.length)
+return this.analysisLinkHoveredEvents_;return this.selection_;},get selection(){return this.selection_;},set selection(selection){if(this.appliedToModel_)
+throw new Error('Cannot mutate this state right now');if(selection===undefined)
+selection=new EventSet();this.selection_=selection;},get findMatches(){return this.findMatches_;},set findMatches(findMatches){if(this.appliedToModel_)
+throw new Error('Cannot mutate this state right now');if(findMatches===undefined)
+findMatches=new EventSet();this.findMatches_=findMatches;},get analysisViewRelatedEvents(){return this.analysisViewRelatedEvents_;},set analysisViewRelatedEvents(analysisViewRelatedEvents){if(this.appliedToModel_)
+throw new Error('Cannot mutate this state right now');if(analysisViewRelatedEvents===undefined)
+analysisViewRelatedEvents=new EventSet();this.analysisViewRelatedEvents_=analysisViewRelatedEvents;},get analysisLinkHoveredEvents(){return this.analysisLinkHoveredEvents_;},set analysisLinkHoveredEvents(analysisLinkHoveredEvents){if(this.appliedToModel_)
+throw new Error('Cannot mutate this state right now');if(analysisLinkHoveredEvents===undefined)
+analysisLinkHoveredEvents=new EventSet();this.analysisLinkHoveredEvents_=analysisLinkHoveredEvents;},get isAppliedToModel(){return this.appliedToModel_!==undefined;},get viewSpecificBrushingStates(){return this.viewSpecificBrushingStates_;},set viewSpecificBrushingStates(viewSpecificBrushingStates){this.viewSpecificBrushingStates_=viewSpecificBrushingStates;},get causesDimming_(){return this.findMatches_.length>0||this.analysisViewRelatedEvents_.length>0;},get brightenedEvents_(){var brightenedEvents=new EventSet();brightenedEvents.addEventSet(this.selection_);brightenedEvents.addEventSet(this.analysisLinkHoveredEvents_);return brightenedEvents;},applyToModelSelectionState:function(model){this.appliedToModel_=model;if(!this.causesDimming_){this.brightenedEvents_.forEach(function(e){var score;score=0;if(this.selection_.contains(e))
+score++;if(this.analysisLinkHoveredEvents_.contains(e))
+score++;e.selectionState=SelectionState.getFromBrighteningLevel(score);},this);return;}
+var brightenedEvents=this.brightenedEvents_;model.iterateAllEvents(function(e){var score;if(brightenedEvents.contains(e)){score=0;if(this.selection_.contains(e))
+score++;if(this.analysisLinkHoveredEvents_.contains(e))
+score++;e.selectionState=SelectionState.getFromBrighteningLevel(score);}else{score=0;if(this.findMatches_.contains(e))
+score++;if(this.analysisViewRelatedEvents_.contains(e))
+score++;e.selectionState=SelectionState.getFromDimmingLevel(score);}}.bind(this));},transferModelOwnershipToClone:function(that){if(!this.appliedToModel_)
+throw new Error('Not applied');that.appliedToModel_=this.appliedToModel_;this.appliedToModel_=undefined;},unapplyFromModelSelectionState:function(){if(!this.appliedToModel_)
+throw new Error('Not applied');var model=this.appliedToModel_;this.appliedToModel_=undefined;if(!this.causesDimming_){this.brightenedEvents_.forEach(function(e){e.selectionState=SelectionState.NONE;});return;}
+model.iterateAllEvents(function(e){e.selectionState=SelectionState.NONE;});}};return{BrushingState:BrushingState};});'use strict';tr.exportTo('tr.ui.b',function(){function Animation(){}
+Animation.prototype={canTakeOverFor:function(existingAnimation){throw new Error('Not implemented');},takeOverFor:function(existingAnimation,newStartTimestamp,target){throw new Error('Not implemented');},start:function(timestamp,target){throw new Error('Not implemented');},didStopEarly:function(timestamp,target,willBeTakenOverByAnotherAnimation){},tick:function(timestamp,target){throw new Error('Not implemented');}};return{Animation:Animation};});'use strict';tr.exportTo('tr.ui.b',function(){function AnimationController(){tr.b.EventTarget.call(this);this.target_=undefined;this.activeAnimation_=undefined;this.tickScheduled_=false;}
+AnimationController.prototype={__proto__:tr.b.EventTarget.prototype,get target(){return this.target_;},set target(target){if(this.activeAnimation_)
+throw new Error('Cannot change target while animation is running.');if(target.cloneAnimationState===undefined||typeof target.cloneAnimationState!=='function')
+throw new Error('target must have a cloneAnimationState function');this.target_=target;},get activeAnimation(){return this.activeAnimation_;},get hasActiveAnimation(){return!!this.activeAnimation_;},queueAnimation:function(animation,opt_now){if(this.target_===undefined)
+throw new Error('Cannot queue animations without a target');var now;if(opt_now!==undefined)
+now=opt_now;else
+now=window.performance.now();if(this.activeAnimation_){var done=this.activeAnimation_.tick(now,this.target_);if(done)
+this.activeAnimation_=undefined;}
+if(this.activeAnimation_){if(animation.canTakeOverFor(this.activeAnimation_)){this.activeAnimation_.didStopEarly(now,this.target_,true);animation.takeOverFor(this.activeAnimation_,now,this.target_);}else{this.activeAnimation_.didStopEarly(now,this.target_,false);}}
+this.activeAnimation_=animation;this.activeAnimation_.start(now,this.target_);if(this.tickScheduled_)
+return;this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);},cancelActiveAnimation:function(opt_now){if(!this.activeAnimation_)
+return;var now;if(opt_now!==undefined)
+now=opt_now;else
+now=window.performance.now();this.activeAnimation_.didStopEarly(now,this.target_,false);this.activeAnimation_=undefined;},tickActiveAnimation_:function(frameBeginTime){this.tickScheduled_=false;if(!this.activeAnimation_)
+return;if(this.target_===undefined){this.activeAnimation_.didStopEarly(frameBeginTime,this.target_,false);return;}
+var oldTargetState=this.target_.cloneAnimationState();var done=this.activeAnimation_.tick(frameBeginTime,this.target_);if(done)
+this.activeAnimation_=undefined;if(this.activeAnimation_){this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);}
+if(oldTargetState){var e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController:AnimationController};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){var ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument)
+ownerDocument=opt_dictionary.ownerDocument;var spanEl=ownerDocument.createElement('span');if(opt_dictionary){if(opt_dictionary.className)
+spanEl.className=opt_dictionary.className;if(opt_dictionary.textContent)
+spanEl.textContent=opt_dictionary.textContent;if(opt_dictionary.tooltip)
+spanEl.title=opt_dictionary.tooltip;if(opt_dictionary.parent)
+opt_dictionary.parent.appendChild(spanEl);if(opt_dictionary.bold)
+spanEl.style.fontWeight='bold';if(opt_dictionary.italic)
+spanEl.style.fontStyle='italic';if(opt_dictionary.marginLeft)
+spanEl.style.marginLeft=opt_dictionary.marginLeft;if(opt_dictionary.marginRight)
+spanEl.style.marginRight=opt_dictionary.marginRight;if(opt_dictionary.backgroundColor)
+spanEl.style.backgroundColor=opt_dictionary.backgroundColor;if(opt_dictionary.color)
+spanEl.style.color=opt_dictionary.color;}
+return spanEl;};function createDiv(opt_dictionary){var divEl=document.createElement('div');if(opt_dictionary){if(opt_dictionary.className)
+divEl.className=opt_dictionary.className;if(opt_dictionary.parent)
+opt_dictionary.parent.appendChild(divEl);if(opt_dictionary.textContent)
+divEl.textContent=opt_dictionary.textContent;if(opt_dictionary.maxWidth)
+divEl.style.maxWidth=opt_dictionary.maxWidth;}
+return divEl;};function createScopedStyle(styleContent){var styleEl=document.createElement('style');styleEl.scoped=true;styleEl.innerHTML=styleContent;return styleEl;}
+function valuesEqual(a,b){if(a instanceof Array&&b instanceof Array)
+return a.length===b.length&&JSON.stringify(a)===JSON.stringify(b);return a===b;}
+function createSelector(targetEl,targetElProperty,settingsKey,defaultValue,items,opt_namespace){var defaultValueIndex;for(var i=0;i<items.length;i++){var item=items[i];if(valuesEqual(item.value,defaultValue)){defaultValueIndex=i;break;}}
+if(defaultValueIndex===undefined)
+throw new Error('defaultValue must be in the items list');var selectorEl=document.createElement('select');selectorEl.addEventListener('change',onChange);for(var i=0;i<items.length;i++){var item=items[i];var optionEl=document.createElement('option');optionEl.textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;selectorEl.appendChild(optionEl);}
+function onChange(e){var value=selectorEl.selectedOptions[0].targetPropertyValue;tr.b.Settings.set(settingsKey,value,opt_namespace);targetEl[targetElProperty]=value;}
+var oldSetter=targetEl.__lookupSetter__('selectedIndex');selectorEl.__defineGetter__('selectedValue',function(v){return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(var i=0;i<selectorEl.children.length;i++){var value=selectorEl.children[i].targetPropertyValue;if(valuesEqual(value,v)){var changed=selectorEl.selectedIndex!=i;if(changed){selectorEl.selectedIndex=i;onChange();}
+return;}}
+throw new Error('Not a valid value');});var initialValue=tr.b.Settings.get(settingsKey,defaultValue,opt_namespace);var didSet=false;for(var i=0;i<selectorEl.children.length;i++){if(valuesEqual(selectorEl.children[i].targetPropertyValue,initialValue)){didSet=true;targetEl[targetElProperty]=initialValue;selectorEl.selectedIndex=i;break;}}
+if(!didSet){selectorEl.selectedIndex=defaultValueIndex;targetEl[targetElProperty]=defaultValue;}
+return selectorEl;}
+function createEditCategorySpan(optionGroupEl,targetEl){var spanEl=createSpan({className:'edit-categories'});spanEl.textContent='Edit categories';spanEl.classList.add('labeled-option');spanEl.addEventListener('click',function(){targetEl.onClickEditCategories();});return spanEl;}
+function createOptionGroup(targetEl,targetElProperty,settingsKey,defaultValue,items){function onChange(){var value=[];if(this.value.length)
+value=this.value.split(',');tr.b.Settings.set(settingsKey,value);targetEl[targetElProperty]=value;}
+var optionGroupEl=createSpan({className:'labeled-option-group'});var initialValue=tr.b.Settings.get(settingsKey,defaultValue);for(var i=0;i<items.length;++i){var item=items[i];var id='category-preset-'+item.label.replace(/ /g,'-');var radioEl=document.createElement('input');radioEl.type='radio';radioEl.setAttribute('id',id);radioEl.setAttribute('name','category-presets-group');radioEl.setAttribute('value',item.value);radioEl.addEventListener('change',onChange.bind(radioEl,targetEl,targetElProperty,settingsKey));if(valuesEqual(initialValue,item.value))
+radioEl.checked=true;var labelEl=document.createElement('label');labelEl.textContent=item.label;labelEl.setAttribute('for',id);var spanEl=createSpan({className:'labeled-option'});spanEl.appendChild(radioEl);spanEl.appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=radioEl.checked!==(!!opt_bool);if(!changed)
+return;radioEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return radioEl.checked;});optionGroupEl.appendChild(spanEl);}
+optionGroupEl.appendChild(createEditCategorySpan(optionGroupEl,targetEl));if(!initialValue.length)
+optionGroupEl.classList.add('categories-expanded');targetEl[targetElProperty]=initialValue;return optionGroupEl;}
+var nextCheckboxId=1;function createCheckBox(targetEl,targetElProperty,settingsKey,defaultValue,label,opt_changeCb){var buttonEl=document.createElement('input');buttonEl.type='checkbox';var initialValue=tr.b.Settings.get(settingsKey,defaultValue);buttonEl.checked=!!initialValue;if(targetEl)
+targetEl[targetElProperty]=initialValue;function onChange(){tr.b.Settings.set(settingsKey,buttonEl.checked);if(targetEl)
+targetEl[targetElProperty]=buttonEl.checked;if(opt_changeCb)
+opt_changeCb.call();}
+buttonEl.addEventListener('change',onChange);var id='#checkbox-'+nextCheckboxId++;var spanEl=createSpan({className:'labeled-checkbox'});buttonEl.setAttribute('id',id);var labelEl=document.createElement('label');labelEl.textContent=label;labelEl.setAttribute('for',id);spanEl.appendChild(buttonEl);spanEl.appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=buttonEl.checked!==(!!opt_bool);if(!changed)
+return;buttonEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return buttonEl.checked;});return spanEl;}
+function isElementAttachedToDocument(el){var cur=el;while(cur.parentNode)
+cur=cur.parentNode;return(cur===el.ownerDocument||cur.nodeName==='#document-fragment');}
+function asHTMLOrTextNode(value,opt_ownerDocument){if(value instanceof Node)
+return value;var ownerDocument=opt_ownerDocument||document;return ownerDocument.createTextNode(value);}
+return{createSpan:createSpan,createDiv:createDiv,createScopedStyle:createScopedStyle,createSelector:createSelector,createOptionGroup:createOptionGroup,createCheckBox:createCheckBox,isElementAttachedToDocument:isElementAttachedToDocument,asHTMLOrTextNode:asHTMLOrTextNode};});'use strict';tr.exportTo('tr.ui.b',function(){var ColorScheme=tr.b.ColorScheme;var colors=ColorScheme.colors;var colorsAsStrings=ColorScheme.colorsAsStrings;var numColorsPerVariant=ColorScheme.properties.numColorsPerVariant;var SelectionState=tr.model.SelectionState;var EventPresenter={getSelectableItemColorAsString:function(item){var colorId=item.colorId+this.getColorIdOffset_(item);return colorsAsStrings[colorId];},getColorIdOffset_:function(event){return event.selectionState;},getTextColor:function(event){if(event.selectionState===SelectionState.DIMMED)
+return'rgb(60,60,60)';return'rgb(0,0,0)';},getSliceColorId:function(slice){return slice.colorId+this.getColorIdOffset_(slice);},getSliceAlpha:function(slice,async){var alpha=1;if(async)
+alpha*=0.3;return alpha;},getInstantSliceColor:function(instant){var colorId=instant.colorId+this.getColorIdOffset_(instant);return colors[colorId].toStringWithAlphaOverride(1.0);},getObjectInstanceColor:function(instance){var colorId=instance.colorId+this.getColorIdOffset_(instance);return colors[colorId].toStringWithAlphaOverride(0.25);},getObjectSnapshotColor:function(snapshot){var colorId=snapshot.objectInstance.colorId+this.getColorIdOffset_(snapshot);return colors[colorId];},getCounterSeriesColor:function(colorId,selectionState,opt_alphaMultiplier){var event={selectionState:selectionState};var c=colors[colorId+this.getColorIdOffset_(event)];return c.toStringWithAlphaOverride(opt_alphaMultiplier!==undefined?opt_alphaMultiplier:1.0);},getBarSnapshotColor:function(snapshot,offset){var colorId=(snapshot.objectInstance.colorId+offset)%numColorsPerVariant;colorId+=this.getColorIdOffset_(snapshot);return colors[colorId].toStringWithAlphaOverride(1.0);}};return{EventPresenter:EventPresenter};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCacheDict={};var elidedTitleCache=new ElidedTitleCache();function ElidedTitleCache(){this.textWidthMap={};}
+ElidedTitleCache.prototype={get:function(ctx,pixWidth,title,width,sliceDuration){var elidedDict=elidedTitleCacheDict[title];if(!elidedDict){elidedDict={};elidedTitleCacheDict[title]=elidedDict;}
+var elidedDictForPixWidth=elidedDict[pixWidth];if(!elidedDictForPixWidth){elidedDict[pixWidth]={};elidedDictForPixWidth=elidedDict[pixWidth];}
+var stringWidthPair=elidedDictForPixWidth[sliceDuration];if(stringWidthPair===undefined){var newtitle=title;var elided=false;while(this.labelWidthWorld(ctx,newtitle,pixWidth)>sliceDuration){if(newtitle.length*0.75<1)
+break;newtitle=newtitle.substring(0,newtitle.length*0.75);elided=true;}
+if(elided&&newtitle.length>3)
+newtitle=newtitle.substring(0,newtitle.length-3)+'...';stringWidthPair=new ElidedStringWidthPair(newtitle,this.labelWidth(ctx,newtitle));elidedDictForPixWidth[sliceDuration]=stringWidthPair;}
+return stringWidthPair;},quickMeasureText_:function(ctx,text){var w=this.textWidthMap[text];if(!w){w=ctx.measureText(text).width;this.textWidthMap[text]=w;}
+return w;},labelWidth:function(ctx,title){return this.quickMeasureText_(ctx,title)+2;},labelWidthWorld:function(ctx,title,pixWidth){return this.labelWidth(ctx,title)*pixWidth;}};function ElidedStringWidthPair(string,width){this.string=string;this.width=width;}
+return{ElidedTitleCache:ElidedTitleCache};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCache=new tr.ui.b.ElidedTitleCache();var ColorScheme=tr.b.ColorScheme;var colorsAsStrings=ColorScheme.colorsAsStrings;var EventPresenter=tr.ui.b.EventPresenter;var blackColorId=ColorScheme.getColorIdForReservedName('black');var THIN_SLICE_HEIGHT=4;var SLICE_WAITING_WIDTH_DRAW_THRESHOLD=3;var SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD=1;var SHOULD_ELIDE_TEXT=true;function drawLine(ctx,x1,y1,x2,y2){ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);}
+function drawTriangle(ctx,x1,y1,x2,y2,x3,y3){ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.lineTo(x3,y3);ctx.closePath();}
+function drawArrow(ctx,x1,y1,x2,y2,arrowLength,arrowWidth){var dx=x2-x1;var dy=y2-y1;var len=Math.sqrt(dx*dx+dy*dy);var perc=(len-arrowLength)/len;var bx=x1+perc*dx;var by=y1+perc*dy;var ux=dx/len;var uy=dy/len;var ax=uy*arrowWidth;var ay=-ux*arrowWidth;ctx.beginPath();drawLine(ctx,x1,y1,x2,y2);ctx.stroke();drawTriangle(ctx,bx+ax,by+ay,x2,y2,bx-ax,by-ay);ctx.fill();}
+function drawSlices(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,async){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);var height=viewHeight*pixelRatio;var darkRectHeight=THIN_SLICE_HEIGHT*pixelRatio;if(height<darkRectHeight)
+darkRectHeight=0;var lightRectHeight=height-darkRectHeight;ctx.save();dt.applyTransformToCanvas(ctx);var rect=new tr.ui.b.FastRectRenderer(ctx,2*pixWidth,2*pixWidth,colorsAsStrings);rect.setYandH(0,height);var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var hadTopLevel=false;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
+break;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth)
+w=pixWidth;}
+var colorId=EventPresenter.getSliceColorId(slice);var alpha=EventPresenter.getSliceAlpha(slice,async);var lightAlpha=alpha*0.70;if(async&&slice.isTopLevel){rect.setYandH(3,height-3);hadTopLevel=true;}else{rect.setYandH(0,height);}
+if(!slice.cpuDuration){rect.fillRect(x,w,colorId,alpha);continue;}
+var activeWidth=w*(slice.cpuDuration/slice.duration);var waitingWidth=w-activeWidth;if(activeWidth<SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=0;waitingWidth=w;}
+if(waitingWidth<SLICE_WAITING_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=w;waitingWidth=0;}
+if(activeWidth>0){rect.fillRect(x,activeWidth,colorId,alpha);}
+if(waitingWidth>0){rect.setYandH(0,lightRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,lightAlpha);rect.setYandH(lightRectHeight,darkRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,alpha);rect.setYandH(0,height);}}
+rect.flush();if(async&&hadTopLevel){rect.setYandH(2,1);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
+break;if(!slice.isTopLevel)
+continue;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth)
+w=pixWidth;}
+rect.fillRect(x,w,blackColorId,0.7);}
+rect.flush();}
+ctx.restore();}
+function drawInstantSlicesAsLines(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,lineWidthInPixels){var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.lineWidth=pixWidth*lineWidthInPixels*pixelRatio;dt.applyTransformToCanvas(ctx);ctx.beginPath();var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start;},viewLWorld);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)
+break;ctx.strokeStyle=EventPresenter.getInstantSliceColor(slice);ctx.beginPath();ctx.moveTo(x,0);ctx.lineTo(x,height);ctx.stroke();}
+ctx.restore();}
+function drawLabels(ctx,dt,viewLWorld,viewRWorld,slices,async,fontSize,yOffset){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.textAlign='center';ctx.textBaseline='top';ctx.font=(fontSize*pixelRatio)+'px sans-serif';if(async)
+ctx.font='italic '+ctx.font;var cY=yOffset*pixelRatio;var lowSlice=tr.b.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var quickDiscardThresshold=pixWidth*20;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];if(slice.start>viewRWorld)
+break;if(slice.duration<=quickDiscardThresshold)
+continue;var title=slice.title+
+(slice.didNotFinish?' (Did Not Finish)':'');var drawnTitle=title;var drawnWidth=elidedTitleCache.labelWidth(ctx,drawnTitle);var fullLabelWidth=elidedTitleCache.labelWidthWorld(ctx,drawnTitle,pixWidth);if(SHOULD_ELIDE_TEXT&&fullLabelWidth>slice.duration){var elidedValues=elidedTitleCache.get(ctx,pixWidth,drawnTitle,drawnWidth,slice.duration);drawnTitle=elidedValues.string;drawnWidth=elidedValues.width;}
+if(drawnWidth*pixWidth<slice.duration){ctx.fillStyle=EventPresenter.getTextColor(slice);var cX=dt.xWorldToView(slice.start+0.5*slice.duration);ctx.fillText(drawnTitle,cX,cY,drawnWidth);}}
+ctx.restore();}
+return{drawSlices:drawSlices,drawInstantSlicesAsLines:drawInstantSlicesAsLines,drawLabels:drawLabels,drawLine:drawLine,drawTriangle:drawTriangle,drawArrow:drawArrow,elidedTitleCache_:elidedTitleCache,THIN_SLICE_HEIGHT:THIN_SLICE_HEIGHT};});'use strict';tr.exportTo('tr.ui',function(){function SnapIndicator(y,height){this.y=y;this.height=height;}
+function TimelineInterestRange(vp){this.viewport_=vp;this.range_=new tr.b.Range();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;}
+TimelineInterestRange.prototype={get isEmpty(){return this.range_.isEmpty;},reset:function(){this.range_.reset();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;this.viewport_.dispatchChangeEvent();},get min(){return this.range_.min;},set min(min){this.range_.min=min;this.viewport_.dispatchChangeEvent();},get max(){return this.range_.max;},set max(max){this.range_.max=max;this.viewport_.dispatchChangeEvent();},set:function(range){this.range_.reset();this.range_.addRange(range);this.viewport_.dispatchChangeEvent();},setMinAndMax:function(min,max){this.range_.min=min;this.range_.max=max;this.viewport_.dispatchChangeEvent();},get range(){return this.range_.range;},asRangeObject:function(){var range=new tr.b.Range();range.addRange(this.range_);return range;},get leftSelected(){return this.leftSelected_;},set leftSelected(leftSelected){if(this.leftSelected_==leftSelected)
+return;this.leftSelected_=leftSelected;this.viewport_.dispatchChangeEvent();},get rightSelected(){return this.rightSelected_;},set rightSelected(rightSelected){if(this.rightSelected_==rightSelected)
+return;this.rightSelected_=rightSelected;this.viewport_.dispatchChangeEvent();},get leftSnapIndicator(){return this.leftSnapIndicator_;},set leftSnapIndicator(leftSnapIndicator){this.leftSnapIndicator_=leftSnapIndicator;this.viewport_.dispatchChangeEvent();},get rightSnapIndicator(){return this.rightSnapIndicator_;},set rightSnapIndicator(rightSnapIndicator){this.rightSnapIndicator_=rightSnapIndicator;this.viewport_.dispatchChangeEvent();},draw:function(ctx,viewLWorld,viewRWorld){if(this.range_.isEmpty)
+return;var dt=this.viewport_.currentDisplayTransform;var markerLWorld=this.min;var markerRWorld=this.max;var markerLView=Math.round(dt.xWorldToView(markerLWorld));var markerRView=Math.round(dt.xWorldToView(markerRWorld));ctx.fillStyle='rgba(0, 0, 0, 0.2)';if(markerLWorld>viewLWorld){ctx.fillRect(dt.xWorldToView(viewLWorld),0,markerLView,ctx.canvas.height);}
+if(markerRWorld<viewRWorld){ctx.fillRect(markerRView,0,dt.xWorldToView(viewRWorld),ctx.canvas.height);}
+var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);if(this.range_.range>0){this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_);this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.max,this.rightSelected_);}else{this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_||this.rightSelected_);}
+ctx.lineWidth=1;},drawLine_:function(ctx,viewLWorld,viewRWorld,height,ts,selected){if(ts<viewLWorld||ts>=viewRWorld)
+return;var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(ts));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,height);if(selected)
+ctx.strokeStyle='rgb(255, 0, 0)';else
+ctx.strokeStyle='rgb(0, 0, 0)';ctx.stroke();ctx.restore();},drawIndicators:function(ctx,viewLWorld,viewRWorld){if(this.leftSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.min,this.leftSnapIndicator_,this.leftSelected_);}
+if(this.rightSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.max,this.rightSnapIndicator_,this.rightSelected_);}},drawIndicator_:function(ctx,viewLWorld,viewRWorld,xWorld,si,selected){var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(xWorld));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);var pixelRatio=window.devicePixelRatio||1;var viewY=si.y*devicePixelRatio;var viewHeight=si.height*devicePixelRatio;var arrowSize=4*pixelRatio;if(selected)
+ctx.fillStyle='rgb(255, 0, 0)';else
+ctx.fillStyle='rgb(0, 0, 0)';tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY,viewX+arrowSize*0.75,viewY,viewX,viewY+arrowSize);ctx.fill();tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY+viewHeight,viewX+arrowSize*0.75,viewY+viewHeight,viewX,viewY+viewHeight-arrowSize);ctx.fill();ctx.restore();}};return{SnapIndicator:SnapIndicator,TimelineInterestRange:TimelineInterestRange};});'use strict';tr.exportTo('tr.ui',function(){function TimelineDisplayTransform(opt_that){if(opt_that){this.set(opt_that);return;}
+this.scaleX=1;this.panX=0;this.panY=0;}
+TimelineDisplayTransform.prototype={set:function(that){this.scaleX=that.scaleX;this.panX=that.panX;this.panY=that.panY;},clone:function(){return new TimelineDisplayTransform(this);},equals:function(that){var eq=true;if(that===undefined||that===null)
+return false;eq&=this.panX===that.panX;eq&=this.panY===that.panY;eq&=this.scaleX===that.scaleX;return!!eq;},almostEquals:function(that){var eq=true;if(that===undefined||that===null)
+return false;eq&=Math.abs(this.panX-that.panX)<0.001;eq&=Math.abs(this.panY-that.panY)<0.001;eq&=Math.abs(this.scaleX-that.scaleX)<0.001;return!!eq;},incrementPanXInViewUnits:function(xDeltaView){this.panX+=this.xViewVectorToWorld(xDeltaView);},xPanWorldPosToViewPos:function(worldX,viewX,viewWidth){if(typeof viewX=='string'){if(viewX==='left'){viewX=0;}else if(viewX==='center'){viewX=viewWidth/2;}else if(viewX==='right'){viewX=viewWidth-1;}else{throw new Error('viewX must be left|center|right or number.');}}
+this.panX=(viewX/this.scaleX)-worldX;},xPanWorldBoundsIntoView:function(worldMin,worldMax,viewWidth){if(this.xWorldToView(worldMin)<0)
+this.xPanWorldPosToViewPos(worldMin,'left',viewWidth);else if(this.xWorldToView(worldMax)>viewWidth)
+this.xPanWorldPosToViewPos(worldMax,'right',viewWidth);},xSetWorldBounds:function(worldMin,worldMax,viewWidth){var worldWidth=worldMax-worldMin;var scaleX=viewWidth/worldWidth;var panX=-worldMin;this.setPanAndScale(panX,scaleX);},setPanAndScale:function(p,s){this.scaleX=s;this.panX=p;},xWorldToView:function(x){return(x+this.panX)*this.scaleX;},xWorldVectorToView:function(x){return x*this.scaleX;},xViewToWorld:function(x){return(x/this.scaleX)-this.panX;},xViewVectorToWorld:function(x){return x/this.scaleX;},applyTransformToCanvas:function(ctx){ctx.transform(this.scaleX,0,0,1,this.panX*this.scaleX,0);}};return{TimelineDisplayTransform:TimelineDisplayTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ContainerToTrackMap(){this.stableIdToTrackMap_={};}
+ContainerToTrackMap.prototype={addContainer:function(container,track){if(!track)
+throw new Error('Must provide a track.');this.stableIdToTrackMap_[container.stableId]=track;},clear:function(){this.stableIdToTrackMap_={};},getTrackByStableId:function(stableId){return this.stableIdToTrackMap_[stableId];}};return{ContainerToTrackMap:ContainerToTrackMap};});'use strict';tr.exportTo('tr.ui.tracks',function(){function EventToTrackMap(){}
+EventToTrackMap.prototype={addEvent:function(event,track){if(!track)
+throw new Error('Must provide a track.');this[event.guid]=track;}};return{EventToTrackMap:EventToTrackMap};});'use strict';tr.exportTo('tr.ui',function(){var TimelineDisplayTransform=tr.ui.TimelineDisplayTransform;var TimelineInterestRange=tr.ui.TimelineInterestRange;function TimelineViewport(parentEl){this.parentEl_=parentEl;this.modelTrackContainer_=undefined;this.currentDisplayTransform_=new TimelineDisplayTransform();this.initAnimationController_();this.showFlowEvents_=false;this.highlightVSync_=false;this.highDetails_=false;this.gridTimebase_=0;this.gridStep_=1000/60;this.gridEnabled_=false;this.hasCalledSetupFunction_=false;this.onResize_=this.onResize_.bind(this);this.onModelTrackControllerScroll_=this.onModelTrackControllerScroll_.bind(this);this.checkForAttachInterval_=setInterval(this.checkForAttach_.bind(this),250);this.majorMarkPositions=[];this.interestRange_=new TimelineInterestRange(this);this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.containerToTrackMap=new tr.ui.tracks.ContainerToTrackMap();}
+TimelineViewport.prototype={__proto__:tr.b.EventTarget.prototype,setWhenPossible:function(fn){this.pendingSetFunction_=fn;},get isAttachedToDocumentOrInTestMode(){if(this.parentEl_===undefined)
+return;return tr.ui.b.isElementAttachedToDocument(this.parentEl_);},onResize_:function(){this.dispatchChangeEvent();},checkForAttach_:function(){if(!this.isAttachedToDocumentOrInTestMode||this.clientWidth==0)
+return;if(!this.iframe_){this.iframe_=document.createElement('iframe');this.iframe_.style.cssText='position:absolute;width:100%;height:0;border:0;visibility:hidden;';this.parentEl_.appendChild(this.iframe_);this.iframe_.contentWindow.addEventListener('resize',this.onResize_);}
+var curSize=this.parentEl_.clientWidth+'x'+
+this.parentEl_.clientHeight;if(this.pendingSetFunction_){this.lastSize_=curSize;try{this.pendingSetFunction_();}catch(ex){console.log('While running setWhenPossible:',ex.message?ex.message+'\n'+ex.stack:ex.stack);}
+this.pendingSetFunction_=undefined;}
+window.clearInterval(this.checkForAttachInterval_);this.checkForAttachInterval_=undefined;},dispatchChangeEvent:function(){tr.b.dispatchSimpleEvent(this,'change');},detach:function(){if(this.checkForAttachInterval_){window.clearInterval(this.checkForAttachInterval_);this.checkForAttachInterval_=undefined;}
+if(this.iframe_){this.iframe_.removeEventListener('resize',this.onResize_);this.parentEl_.removeChild(this.iframe_);}},initAnimationController_:function(){this.dtAnimationController_=new tr.ui.b.AnimationController();this.dtAnimationController_.addEventListener('didtick',function(e){this.onCurentDisplayTransformChange_(e.oldTargetState);}.bind(this));var that=this;this.dtAnimationController_.target={get panX(){return that.currentDisplayTransform_.panX;},set panX(panX){that.currentDisplayTransform_.panX=panX;},get panY(){return that.currentDisplayTransform_.panY;},set panY(panY){that.currentDisplayTransform_.panY=panY;},get scaleX(){return that.currentDisplayTransform_.scaleX;},set scaleX(scaleX){that.currentDisplayTransform_.scaleX=scaleX;},cloneAnimationState:function(){return that.currentDisplayTransform_.clone();},xPanWorldPosToViewPos:function(xWorld,xView){that.currentDisplayTransform_.xPanWorldPosToViewPos(xWorld,xView,that.modelTrackContainer_.canvas.clientWidth);}};},get currentDisplayTransform(){return this.currentDisplayTransform_;},setDisplayTransformImmediately:function(displayTransform){this.dtAnimationController_.cancelActiveAnimation();var oldDisplayTransform=this.dtAnimationController_.target.cloneAnimationState();this.currentDisplayTransform_.set(displayTransform);this.onCurentDisplayTransformChange_(oldDisplayTransform);},queueDisplayTransformAnimation:function(animation){if(!(animation instanceof tr.ui.b.Animation))
+throw new Error('animation must be instanceof tr.ui.b.Animation');this.dtAnimationController_.queueAnimation(animation);},onCurentDisplayTransformChange_:function(oldDisplayTransform){if(this.modelTrackContainer_){this.currentDisplayTransform.panY=tr.b.clamp(this.currentDisplayTransform.panY,0,this.modelTrackContainer_.scrollHeight-
+this.modelTrackContainer_.clientHeight);}
+var changed=!this.currentDisplayTransform.equals(oldDisplayTransform);var yChanged=this.currentDisplayTransform.panY!==oldDisplayTransform.panY;if(yChanged)
+this.modelTrackContainer_.scrollTop=this.currentDisplayTransform.panY;if(changed)
+this.dispatchChangeEvent();},onModelTrackControllerScroll_:function(e){if(this.dtAnimationController_.activeAnimation&&this.dtAnimationController_.activeAnimation.affectsPanY)
+this.dtAnimationController_.cancelActiveAnimation();var panY=this.modelTrackContainer_.scrollTop;this.currentDisplayTransform_.panY=panY;},get modelTrackContainer(){return this.modelTrackContainer_;},set modelTrackContainer(m){if(this.modelTrackContainer_)
+this.modelTrackContainer_.removeEventListener('scroll',this.onModelTrackControllerScroll_);this.modelTrackContainer_=m;this.modelTrackContainer_.addEventListener('scroll',this.onModelTrackControllerScroll_);},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;this.dispatchChangeEvent();},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;this.dispatchChangeEvent();},get highDetails(){return this.highDetails_;},set highDetails(highDetails){this.highDetails_=highDetails;this.dispatchChangeEvent();},get gridEnabled(){return this.gridEnabled_;},set gridEnabled(enabled){if(this.gridEnabled_==enabled)
+return;this.gridEnabled_=enabled&&true;this.dispatchChangeEvent();},get gridTimebase(){return this.gridTimebase_;},set gridTimebase(timebase){if(this.gridTimebase_==timebase)
+return;this.gridTimebase_=timebase;this.dispatchChangeEvent();},get gridStep(){return this.gridStep_;},get interestRange(){return this.interestRange_;},drawMajorMarkLines:function(ctx){ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();for(var idx in this.majorMarkPositions){var x=Math.floor(this.majorMarkPositions[idx]);tr.ui.b.drawLine(ctx,x,0,x,ctx.canvas.height);}
+ctx.strokeStyle='#ddd';ctx.stroke();ctx.restore();},drawGridLines:function(ctx,viewLWorld,viewRWorld){if(!this.gridEnabled)
+return;var dt=this.currentDisplayTransform;var x=this.gridTimebase;ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();while(x<viewRWorld){if(x>=viewLWorld){var vx=Math.floor(dt.xWorldToView(x));tr.ui.b.drawLine(ctx,vx,0,vx,ctx.canvas.height);}
+x+=this.gridStep;}
+ctx.strokeStyle='rgba(255, 0, 0, 0.25)';ctx.stroke();ctx.restore();},getShiftedSelection:function(selection,offset){var newSelection=new tr.model.EventSet();for(var i=0;i<selection.length;i++){var event=selection[i];if(event instanceof tr.model.FlowEvent){if(offset>0){newSelection.push(event.endSlice);}else if(offset<0){newSelection.push(event.startSlice);}else{}
+continue;}
+var track=this.trackForEvent(event);track.addEventNearToProvidedEventToSelection(event,offset,newSelection);}
+if(newSelection.length==0)
+return undefined;return newSelection;},rebuildEventToTrackMap:function(){this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.modelTrackContainer_.addEventsToTrackMap(this.eventToTrackMap_);},rebuildContainerToTrackMap:function(){this.containerToTrackMap.clear();this.modelTrackContainer_.addContainersToTrackMap(this.containerToTrackMap);},trackForEvent:function(event){return this.eventToTrackMap_[event.guid];}};return{TimelineViewport:TimelineViewport};});'use strict';tr.exportTo('tr.ui.b',function(){var Location=tr.model.Location;function UIState(location,scaleX){this.location_=location;this.scaleX_=scaleX;};UIState.fromUserFriendlyString=function(model,viewport,stateString){var navByFinderPattern=/^(-?\d+(\.\d+)?)@(.+)x(\d+(\.\d+)?)$/g;var match=navByFinderPattern.exec(stateString);if(!match)
+return;var timestamp=parseFloat(match[1]);var stableId=match[3];var scaleX=parseFloat(match[4]);if(scaleX<=0)
+throw new Error('Invalid ScaleX value in UI State string.');if(!viewport.containerToTrackMap.getTrackByStableId(stableId))
+throw new Error('Invalid StableID given in UI State String.');var loc=tr.model.Location.fromStableIdAndTimestamp(viewport,stableId,timestamp);return new UIState(loc,scaleX);}
+UIState.prototype={get location(){return this.location_;},get scaleX(){return this.scaleX_;},toUserFriendlyString:function(viewport){var timestamp=this.location_.xWorld;var stableId=this.location_.getContainingTrack(viewport).eventContainer.stableId;var scaleX=this.scaleX_;return timestamp.toFixed(5)+'@'+stableId+'x'+scaleX.toFixed(5);},toDict:function(){return{location:this.location_.toDict(),scaleX:this.scaleX_};}};return{UIState:UIState};});'use strict';tr.exportTo('tr.c',function(){var BrushingState=tr.ui.b.BrushingState;var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;var Viewport=tr.ui.TimelineViewport;function BrushingStateController(timelineView){tr.b.EventTarget.call(this);this.timelineView_=timelineView;this.currentBrushingState_=new BrushingState();this.onPopState_=this.onPopState_.bind(this);this.historyEnabled_=false;this.selections_={};}
+BrushingStateController.prototype={__proto__:tr.b.EventTarget.prototype,dispatchChangeEvent_:function(){var e=new tr.b.Event('change',false,false);this.dispatchEvent(e);},get model(){if(!this.timelineView_)
+return undefined;return this.timelineView_.model;},get trackView(){if(!this.timelineView_)
+return undefined;return this.timelineView_.trackView;},get viewport(){if(!this.timelineView_)
+return undefined;if(!this.timelineView_.trackView)
+return undefined;return this.timelineView_.trackView.viewport;},get historyEnabled(){return this.historyEnabled_;},set historyEnabled(historyEnabled){this.historyEnabled_=!!historyEnabled;if(historyEnabled)
+window.addEventListener('popstate',this.onPopState_);else
+window.removeEventListener('popstate',this.onPopState_);},modelWillChange:function(){if(this.currentBrushingState_.isAppliedToModel)
+this.currentBrushingState_.unapplyFromModelSelectionState();},modelDidChange:function(){this.selections_={};this.currentBrushingState_=new BrushingState();this.currentBrushingState_.applyToModelSelectionState(this.model);var e=new tr.b.Event('model-changed',false,false);this.dispatchEvent(e);this.dispatchChangeEvent_();},onUserInitiatedSelectionChange_:function(){var selection=this.selection;if(this.historyEnabled){this.selections_[selection.guid]=selection;var state={selection_guid:selection.guid};window.history.pushState(state,document.title);}},onPopState_:function(e){if(e.state===null)
+return;var selection=this.selections_[e.state.selection_guid];if(selection){var newState=this.currentBrushingState_.clone();newState.selection=selection;this.currentBrushingState=newState;}
+e.stopPropagation();},get selection(){return this.currentBrushingState_.selection;},get findMatches(){return this.currentBrushingState_.findMatches;},get selectionOfInterest(){return this.currentBrushingState_.selectionOfInterest;},get currentBrushingState(){return this.currentBrushingState_;},set currentBrushingState(newBrushingState){if(newBrushingState.isAppliedToModel)
+throw new Error('Cannot apply this state, it is applied');var hasValueChanged=!this.currentBrushingState_.equals(newBrushingState);if(newBrushingState!==this.currentBrushingState_&&!hasValueChanged){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.transferModelOwnershipToClone(newBrushingState);}
+this.currentBrushingState_=newBrushingState;return;}
+if(this.currentBrushingState_.isAppliedToModel)
+this.currentBrushingState_.unapplyFromModelSelectionState();this.currentBrushingState_=newBrushingState;if(this.model)
+this.currentBrushingState_.applyToModelSelectionState(this.model);this.dispatchChangeEvent_();},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var timelineView=this.timelineView_.trackView;if(!timelineView)
+return new tr.b.Task();return timelineView.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);},findTextChangedTo:function(allPossibleMatches){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.findMatches=allPossibleMatches;this.currentBrushingState=newBrushingState;},findFocusChangedTo:function(currentFocus){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=currentFocus;this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},findTextCleared:function(){if(this.xNavStringMarker_!==undefined){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+if(this.guideLineAnnotation_!==undefined){this.model.removeAnnotation(this.guideLineAnnotation_);this.guideLineAnnotation_=undefined;}
+var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=new EventSet();newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},uiStateFromString:function(string){return tr.ui.b.UIState.fromUserFriendlyString(this.model,this.viewport,string);},navToPosition:function(uiState,showNavLine){this.trackView.navToPosition(uiState,showNavLine);},changeSelectionFromTimeline:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},showScriptControlSelection:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;},changeSelectionFromRequestSelectionChangeEvent:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},changeAnalysisViewRelatedEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisViewRelatedEvents=eventSet;this.currentBrushingState=newBrushingState;},changeAnalysisLinkHoveredEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisLinkHoveredEvents=eventSet;this.currentBrushingState=newBrushingState;},getViewSpecificBrushingState:function(viewId){return this.currentBrushingState.viewSpecificBrushingStates[viewId];},changeViewSpecificBrushingState:function(viewId,newState){var oldStates=this.currentBrushingState_.viewSpecificBrushingStates;var newStates={};for(var id in oldStates)
+newStates[id]=oldStates[id];if(newState===undefined)
+delete newStates[viewId];else
+newStates[viewId]=newState;var newBrushingState=this.currentBrushingState_.clone();newBrushingState.viewSpecificBrushingStates=newStates;this.currentBrushingState=newBrushingState;}};BrushingStateController.getControllerForElement=function(element){if(tr.isHeadless)
+throw new Error('Unsupported');var currentElement=element;while(currentElement){if(currentElement.brushingStateController)
+return currentElement.brushingStateController;if(currentElement.parentElement){currentElement=currentElement.parentElement;continue;}
+var currentNode=currentElement;while(currentNode.parentNode)
+currentNode=currentNode.parentNode;currentElement=currentNode.host;}
+return undefined;};return{BrushingStateController:BrushingStateController};});'use strict';Polymer('tr-ui-a-analysis-link',{ready:function(){this.selection_=undefined;},attached:function(){this.controller_=tr.c.BrushingStateController.getControllerForElement(this);},detached:function(){this.clearHighlight_();this.controller_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.textContent=selection.userFriendlyName;},setSelectionAndContent:function(selection,opt_textContent){this.selection_=selection;if(opt_textContent)
+this.textContent=opt_textContent;},getCurrentSelection_:function(){if(typeof this.selection_==='function')
+return this.selection_();return this.selection_;},setHighlight_:function(opt_eventSet){if(this.controller_)
+this.controller_.changeAnalysisLinkHoveredEvents(opt_eventSet);},clearHighlight_:function(opt_eventSet){this.setHighlight_();},onClicked_:function(){if(!this.selection_)
+return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_:function(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_:function(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){var TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};return{TableFormat:TableFormat};});'use strict';(function(){var RIGHT_ARROW=String.fromCharCode(0x25b6);var UNSORTED_ARROW=String.fromCharCode(0x25BF);var ASCENDING_ARROW=String.fromCharCode(0x25B4);var DESCENDING_ARROW=String.fromCharCode(0x25BE);var BASIC_INDENTATION=8;var SelectionMode=tr.ui.b.TableFormat.SelectionMode;var HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;Polymer('tr-ui-b-table',{created:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;},ready:function(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);},clear:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.subRowsPropertyName_='subRows';},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){var previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue)
+this.scheduleRebuildBody_();},set tableColumns(columns){var columnsWithExpandButtons=[];for(var i=0;i<columns.length;i++){if(columns[i].showExpandButtons)
+columnsWithExpandButtons.push(i);}
+if(columnsWithExpandButtons.length===0){columnsWithExpandButtons=[0];}
+for(var i=0;i<columns.length;i++){var colInfo=columns[i];if(colInfo.width===undefined)
+continue;var hasExpandButton=columnsWithExpandButtons.indexOf(i)!==-1;var w=colInfo.width;if(w){if(/\d+px/.test(w)){continue;}else if(/\d+%/.test(w)){if(hasExpandButton){throw new Error('Columns cannot be %-sized and host '+' an expand button');}}else{throw new Error('Unrecognized width string');}}}
+this.tableColumns_=columns;this.headerCells_=[];this.columnsWithExpandButtons_=columnsWithExpandButtons;this.sortColumnIndex=undefined;this.scheduleRebuildHeaders_();this.tableRows=this.tableRows_;},get tableColumns(){return this.tableColumns_;},set tableRows(rows){this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.maybeUpdateSelectedRow_();this.tableRows_=rows;this.tableRowsInfo_=new WeakMap();this.scheduleRebuildBody_();},get tableRows(){return this.tableRows_;},set footerRows(rows){this.tableFooterRows_=rows;this.tableFooterRowsInfo_=new WeakMap();this.scheduleRebuildFooter_();},get footerRows(){return this.tableFooterRows_;},set sortColumnIndex(number){if(number===this.sortColumnIndex_)
+return;if(number===undefined){this.sortColumnIndex_=undefined;this.updateHeaderArrows_();this.dispatchSortingChangedEvent_();return;}
+if(this.tableColumns_.length<=number)
+throw new Error('Column number '+number+' is out of bounds.');if(!this.tableColumns_[number].cmp)
+throw new Error('Column '+number+' does not have a comparator.');this.sortColumnIndex_=number;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();},get sortColumnIndex(){return this.sortColumnIndex_;},set sortDescending(value){var newValue=!!value;if(newValue!==this.sortDescending_){this.sortDescending_=newValue;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();}},get sortDescending(){return this.sortDescending_;},updateHeaderArrows_:function(){for(var i=0;i<this.headerCells_.length;i++){if(!this.tableColumns_[i].cmp){this.headerCells_[i].sideContent='';continue;}
+if(i!==this.sortColumnIndex_){this.headerCells_[i].sideContent=UNSORTED_ARROW;continue;}
+this.headerCells_[i].sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;}},sortRows_:function(rows){rows.sort(function(rowA,rowB){if(this.sortDescending_)
+return this.tableColumns_[this.sortColumnIndex_].cmp(rowB.userRow,rowA.userRow);return this.tableColumns_[this.sortColumnIndex_].cmp(rowA.userRow,rowB.userRow);}.bind(this));for(var i=0;i<rows.length;i++){if(rows[i].isExpanded)
+this.sortRows_(rows[i][this.subRowsPropertyName_]);}},generateHeaderColumns_:function(){this.headerCells_=[];this.$.head.textContent='';if(!this.showHeader_)
+return;var tr=this.appendNewElement_(this.$.head,'tr');for(var i=0;i<this.tableColumns_.length;i++){var td=this.appendNewElement_(tr,'td');var headerCell=document.createElement('tr-ui-b-table-header-cell');if(this.showHeader)
+headerCell.cellTitle=this.tableColumns_[i].title;else
+headerCell.cellTitle='';if(this.tableColumns_[i].cmp){td.classList.add('sensitive');headerCell.tapCallback=this.createSortCallback_(i);if(this.sortColumnIndex_===i)
+headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;else
+headerCell.sideContent=UNSORTED_ARROW;}
+td.appendChild(headerCell);this.headerCells_.push(headerCell);}},applySizes_:function(){if(this.tableRows_.length===0&&!this.showHeader)
+return;var rowToRemoveSizing;var rowToSize;if(this.showHeader){rowToSize=this.$.head.children[0];rowToRemoveSizing=this.$.body.children[0];}else{rowToSize=this.$.body.children[0];rowToRemoveSizing=this.$.head.children[0];}
+for(var i=0;i<this.tableColumns_.length;i++){if(rowToRemoveSizing&&rowToRemoveSizing.children[i]){var tdToRemoveSizing=rowToRemoveSizing.children[i];tdToRemoveSizing.style.minWidth='';tdToRemoveSizing.style.width='';}
+var td=rowToSize.children[i];var delta;if(this.columnsWithExpandButtons_.indexOf(i)!==-1){td.style.paddingLeft=BASIC_INDENTATION+'px';delta=BASIC_INDENTATION+'px';}else{delta=undefined;}
+function calc(base,delta){if(delta)
+return'calc('+base+' - '+delta+')';else
+return base;}
+var w=this.tableColumns_[i].width;if(w){if(/\d+px/.test(w)){td.style.minWidth=calc(w,delta);}else if(/\d+%/.test(w)){td.style.width=w;}else{throw new Error('Unrecognized width string: '+w);}}}},createSortCallback_:function(columnNumber){return function(){var previousIndex=this.sortColumnIndex;this.sortColumnIndex=columnNumber;if(previousIndex!==columnNumber)
+this.sortDescending=false;else
+this.sortDescending=!this.sortDescending;}.bind(this);},generateTableRowNodes_:function(tableSection,userRows,rowInfoMap,indentation,lastAddedRow,parentRowInfo){if(this.sortColumnIndex_!==undefined&&tableSection===this.$.body){userRows=userRows.slice();userRows.sort(function(rowA,rowB){var c=this.tableColumns_[this.sortColumnIndex_].cmp(rowA,rowB);if(this.sortDescending_)
+c=-c;return c;}.bind(this));}
+for(var i=0;i<userRows.length;i++){var userRow=userRows[i];var rowInfo=this.getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo);var htmlNode=this.getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation);if(lastAddedRow===undefined){tableSection.insertBefore(htmlNode,tableSection.firstChild);}else{var nextSiblingOfLastAdded=lastAddedRow.nextSibling;tableSection.insertBefore(htmlNode,nextSiblingOfLastAdded);}
+this.updateTabIndexForTableRowNode_(htmlNode);lastAddedRow=htmlNode;if(!rowInfo.isExpanded)
+continue;lastAddedRow=this.generateTableRowNodes_(tableSection,userRow[this.subRowsPropertyName_],rowInfoMap,indentation+1,lastAddedRow,rowInfo);}
+return lastAddedRow;},getOrCreateRowInfoFor_:function(rowInfoMap,userRow,parentRowInfo){if(rowInfoMap.has(userRow))
+return rowInfoMap.get(userRow);var rowInfo={userRow:userRow,htmlNode:undefined,isExpanded:userRow.isExpanded||false,parentRowInfo:parentRowInfo};rowInfoMap.set(userRow,rowInfo);return rowInfo;},customizeTableRow_:function(userRow,trElement){if(!this.customizeTableRowCallback_)
+return;this.customizeTableRowCallback_(userRow,trElement);},getHTMLNodeForRowInfo_:function(tableSection,rowInfo,rowInfoMap,indentation){if(rowInfo.htmlNode){this.customizeTableRow_(rowInfo.userRow,rowInfo.htmlNode);return rowInfo.htmlNode;}
+var INDENT_SPACE=indentation*16;var INDENT_SPACE_NO_BUTTON=indentation*16+BASIC_INDENTATION;var trElement=this.ownerDocument.createElement('tr');rowInfo.htmlNode=trElement;rowInfo.indentation=indentation;trElement.rowInfo=rowInfo;this.customizeTableRow_(rowInfo.userRow,trElement);for(var i=0;i<this.tableColumns_.length;){var td=this.appendNewElement_(trElement,'td');td.columnIndex=i;var column=this.tableColumns_[i];var value=column.value(rowInfo.userRow);var colSpan=column.colSpan?column.colSpan:1;td.style.colSpan=colSpan;if(column.textAlign){td.style.textAlign=column.textAlign;}
+if(this.doesColumnIndexSupportSelection(i))
+td.classList.add('supports-selection');if(this.columnsWithExpandButtons_.indexOf(i)!=-1){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length>0){td.style.paddingLeft=INDENT_SPACE+'px';var expandButton=this.appendNewElement_(td,'expand-button');expandButton.textContent=RIGHT_ARROW;if(rowInfo.isExpanded)
+expandButton.classList.add('button-expanded');}else{td.style.paddingLeft=INDENT_SPACE_NO_BUTTON+'px';}}
+if(value!==undefined)
+td.appendChild(tr.ui.b.asHTMLOrTextNode(value,this.ownerDocument));i+=colSpan;}
+var needsClickListener=false;if(this.columnsWithExpandButtons_.length)
+needsClickListener=true;else if(tableSection==this.$.body)
+needsClickListener=true;if(needsClickListener){trElement.addEventListener('click',function(e){e.stopPropagation();if(e.target.tagName=='EXPAND-BUTTON'){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);return;}
+function getTD(cur){if(cur===trElement)
+throw new Error('woah');if(cur.parentElement===trElement)
+return cur;return getTD(cur.parentElement);}
+if(this.selectionMode_!==SelectionMode.NONE){var isAlreadySelected=false;var tdThatWasClicked=getTD(e.target);switch(this.selectionMode_){case SelectionMode.ROW:isAlreadySelected=this.selectedTableRowInfo_===rowInfo;break;case SelectionMode.CELL:isAlreadySelected=this.selectedTableRowInfo_===rowInfo;isAlreadySelected&=(this.selectedColumnIndex_===tdThatWasClicked.columnIndex);break;default:throw new Error('Invalid selection mode '+
+this.selectionMode_);}
+if(isAlreadySelected){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}else{this.didTableRowInfoGetClicked_(rowInfo,tdThatWasClicked.columnIndex);}}else{if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}}.bind(this));}
+return rowInfo.htmlNode;},removeSubNodes_:function(tableSection,rowInfo,rowInfoMap){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
+return;for(var i=0;i<rowInfo.userRow[this.subRowsPropertyName_].length;i++){var subRow=rowInfo.userRow[this.subRowsPropertyName_][i];var subRowInfo=rowInfoMap.get(subRow);if(!subRowInfo)
+continue;var subNode=subRowInfo.htmlNode;if(subNode&&subNode.parentNode===tableSection){tableSection.removeChild(subNode);this.removeSubNodes_(tableSection,subRowInfo,rowInfoMap);}}},scheduleRebuildHeaders_:function(){this.headerDirty_=true;this.scheduleRebuild_();},scheduleRebuildBody_:function(){this.bodyDirty_=true;this.scheduleRebuild_();},scheduleRebuildFooter_:function(){this.footerDirty_=true;this.scheduleRebuild_();},scheduleRebuild_:function(){if(this.rebuildPending_)
+return;this.rebuildPending_=true;setTimeout(function(){this.rebuildPending_=false;this.rebuild();}.bind(this),0);},rebuildIfNeeded_:function(){this.rebuild();},rebuild:function(){var wasBodyOrHeaderDirty=this.headerDirty_||this.bodyDirty_;if(this.headerDirty_){this.generateHeaderColumns_();this.headerDirty_=false;}
+if(this.bodyDirty_){this.$.body.textContent='';this.generateTableRowNodes_(this.$.body,this.tableRows_,this.tableRowsInfo_,0,undefined,undefined);if(this.tableRows_.length===0&&this.emptyValue_!==undefined){var trElement=this.ownerDocument.createElement('tr');this.$.body.appendChild(trElement);trElement.classList.add('empty-row');var td=this.ownerDocument.createElement('td');trElement.appendChild(td);td.colSpan=this.tableColumns_.length;var emptyValue=this.emptyValue_;td.appendChild(tr.ui.b.asHTMLOrTextNode(emptyValue,this.ownerDocument));}
+this.bodyDirty_=false;}
+if(wasBodyOrHeaderDirty)
+this.applySizes_();if(this.footerDirty_){this.$.foot.textContent='';this.generateTableRowNodes_(this.$.foot,this.tableFooterRows_,this.tableFooterRowsInfo_,0,undefined,undefined);if(this.tableFooterRowsInfo_.length){this.$.body.classList.add('has-footer');}else{this.$.body.classList.remove('has-footer');}
+this.footerDirty_=false;}},appendNewElement_:function(parent,tagName){var element=parent.ownerDocument.createElement(tagName);parent.appendChild(element);return element;},getExpandedForTableRow:function(userRow){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
+throw new Error('Row has not been seen, must expand its parents');return rowInfo.isExpanded;},setExpandedForTableRow:function(userRow,expanded){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined)
+throw new Error('Row has not been seen, must expand its parents');return this.setExpandedForUserRow_(this.$.body,this.tableRowsInfo_,userRow,expanded);},setExpandedForUserRow_:function(tableSection,rowInfoMap,userRow,expanded){this.rebuildIfNeeded_();var rowInfo=rowInfoMap.get(userRow);if(rowInfo===undefined)
+throw new Error('Row has not been seen, must expand its parents');rowInfo.isExpanded=!!expanded;if(rowInfo.htmlNode===undefined)
+return;if(rowInfo.htmlNode.parentElement!==tableSection)
+return;var expandButton=rowInfo.htmlNode.querySelector('expand-button');if(rowInfo.isExpanded){expandButton.classList.add('button-expanded');var lastAddedRow=rowInfo.htmlNode;if(rowInfo.userRow[this.subRowsPropertyName_]){this.generateTableRowNodes_(tableSection,rowInfo.userRow[this.subRowsPropertyName_],rowInfoMap,rowInfo.indentation+1,lastAddedRow,rowInfo);}}else{expandButton.classList.remove('button-expanded');this.removeSubNodes_(tableSection,rowInfo,rowInfoMap);}
+this.maybeUpdateSelectedRow_();},get selectionMode(){return this.selectionMode_;},set selectionMode(selectionMode){if(!tr.b.dictionaryContainsValue(SelectionMode,selectionMode))
+throw new Error('Invalid selection mode '+selectionMode);this.rebuildIfNeeded_();this.selectionMode_=selectionMode;this.didSelectionStateChange_();},get rowHighlightStyle(){return this.rowHighlightStyle_;},set rowHighlightStyle(rowHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,rowHighlightStyle))
+throw new Error('Invalid row highlight style '+rowHighlightStyle);this.rebuildIfNeeded_();this.rowHighlightStyle_=rowHighlightStyle;this.didSelectionStateChange_();},get resolvedRowHighlightStyle(){if(this.rowHighlightStyle_!==HighlightStyle.DEFAULT)
+return this.rowHighlightStyle_;switch(this.selectionMode_){case SelectionMode.NONE:return HighlightStyle.NONE;case SelectionMode.ROW:return HighlightStyle.DARK;case SelectionMode.CELL:return HighlightStyle.LIGHT;default:throw new Error('Invalid selection mode '+selectionMode);}},get cellHighlightStyle(){return this.cellHighlightStyle_;},set cellHighlightStyle(cellHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,cellHighlightStyle))
+throw new Error('Invalid cell highlight style '+cellHighlightStyle);this.rebuildIfNeeded_();this.cellHighlightStyle_=cellHighlightStyle;this.didSelectionStateChange_();},get resolvedCellHighlightStyle(){if(this.cellHighlightStyle_!==HighlightStyle.DEFAULT)
+return this.cellHighlightStyle_;switch(this.selectionMode_){case SelectionMode.NONE:case SelectionMode.ROW:return HighlightStyle.NONE;case SelectionMode.CELL:return HighlightStyle.DARK;default:throw new Error('Invalid selection mode '+selectionMode);}},setHighlightStyle_:function(highlightAttribute,resolvedHighlightStyle){switch(resolvedHighlightStyle){case HighlightStyle.NONE:this.$.body.removeAttribute(highlightAttribute);break;case HighlightStyle.LIGHT:this.$.body.setAttribute(highlightAttribute,'light');break;case HighlightStyle.DARK:this.$.body.setAttribute(highlightAttribute,'dark');break;default:throw new Error('Invalid resolved highlight style '+
+resolvedHighlightStyle);}},didSelectionStateChange_:function(){this.setHighlightStyle_('row-highlight-style',this.resolvedRowHighlightStyle);this.setHighlightStyle_('cell-highlight-style',this.resolvedCellHighlightStyle);for(var i=0;i<this.$.body.children.length;i++)
+this.updateTabIndexForTableRowNode_(this.$.body.children[i]);this.maybeUpdateSelectedRow_();},maybeUpdateSelectedRow_:function(){if(this.selectedTableRowInfo_===undefined)
+return;if(this.selectionMode_===SelectionMode.NONE){this.removeSelectedState_();this.selectedTableRowInfo_=undefined;return;}
+function isVisible(rowInfo){if(!rowInfo.htmlNode)
+return false;return!!rowInfo.htmlNode.parentElement;}
+if(isVisible(this.selectedTableRowInfo_)){this.updateSelectedState_();return;}
+this.removeSelectedState_();var curRowInfo=this.selectedTableRowInfo_;while(curRowInfo&&!isVisible(curRowInfo))
+curRowInfo=curRowInfo.parentRowInfo;this.selectedTableRowInfo_=curRowInfo;if(this.selectedTableRowInfo_)
+this.updateSelectedState_();},didTableRowInfoGetClicked_:function(rowInfo,columnIndex){switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.CELL:if(!this.doesColumnIndexSupportSelection(columnIndex))
+return;case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo)
+this.selectedTableRow=rowInfo.userRow;if(this.selectedColumnIndex!==columnIndex)
+this.selectedColumnIndex=columnIndex;}},get selectedTableRow(){if(!this.selectedTableRowInfo_)
+return undefined;return this.selectedTableRowInfo_.userRow;},set selectedTableRow(userRow){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE)
+throw new Error('Selection is off.');var rowInfo;if(userRow===undefined){rowInfo=undefined;}else{rowInfo=this.tableRowsInfo_.get(userRow);if(!rowInfo)
+throw new Error('Row has not been seen, must expand its parents.');}
+var e=this.prepareToChangeSelection_();this.selectedTableRowInfo_=rowInfo;if(this.selectedTableRowInfo_===undefined){this.selectedColumnIndex_=undefined;this.removeSelectedState_();}else{switch(this.selectionMode_){case SelectionMode.ROW:this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:if(this.selectedColumnIndex_===undefined){var i=this.getFirstSelectableColumnIndex_();if(i==-1)
+throw new Error('Cannot find a selectable column.');this.selectedColumnIndex_=i;}
+break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
+this.updateSelectedState_();}
+this.dispatchEvent(e);},updateTabIndexForTableRowNode_:function(row){if(this.selectionMode_===SelectionMode.ROW)
+row.tabIndex=0;else
+row.removeAttribute('tabIndex');var enableCellTab=this.selectionMode_===SelectionMode.CELL;for(var i=0;i<this.tableColumns_.length;i++){var cell=row.children[i];if(enableCellTab&&this.doesColumnIndexSupportSelection(i))
+cell.tabIndex=0;else
+cell.removeAttribute('tabIndex');}},prepareToChangeSelection_:function(){var e=new tr.b.Event('selection-changed');var previousSelectedRowInfo=this.selectedTableRowInfo_;if(previousSelectedRowInfo)
+e.previousSelectedTableRow=previousSelectedRowInfo.userRow;else
+e.previousSelectedTableRow=undefined;this.removeSelectedState_();return e;},removeSelectedState_:function(){this.setSelectedState_(false);},updateSelectedState_:function(){this.setSelectedState_(true);},setSelectedState_:function(select){if(this.selectedTableRowInfo_===undefined)
+return;var rowNode=this.selectedTableRowInfo_.htmlNode;if(select)
+rowNode.setAttribute('selected',true);else
+rowNode.removeAttribute('selected');var cellNode=rowNode.children[this.selectedColumnIndex_];if(!cellNode)
+return;if(select)
+cellNode.setAttribute('selected',true);else
+cellNode.removeAttribute('selected');},doesColumnIndexSupportSelection:function(columnIndex){var columnInfo=this.tableColumns_[columnIndex];var scs=columnInfo.supportsCellSelection;if(scs===false)
+return false;return true;},getFirstSelectableColumnIndex_:function(){for(var i=0;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i))
+return i;}
+return-1;},getSelectableNodeGivenTableRowNode_:function(htmlNode){switch(this.selectionMode_){case SelectionMode.ROW:return htmlNode;case SelectionMode.CELL:return htmlNode.children[this.selectedColumnIndex_];default:throw new Error('Invalid selection mode '+this.selectionMode_);}},get selectedColumnIndex(){if(this.selectionMode_!==SelectionMode.CELL)
+return undefined;return this.selectedColumnIndex_;},set selectedColumnIndex(selectedColumnIndex){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE)
+throw new Error('Selection is off.');if(selectedColumnIndex<0||selectedColumnIndex>=this.tableColumns_.length)
+throw new Error('Invalid index');if(!this.doesColumnIndexSupportSelection(selectedColumnIndex))
+throw new Error('Selection is not supported on this column');var e=this.prepareToChangeSelection_();this.selectedColumnIndex_=selectedColumnIndex;if(this.selectedColumnIndex_===undefined)
+this.selectedTableRowInfo_=undefined;this.updateSelectedState_();this.dispatchEvent(e);},onKeyDown_:function(e){if(this.selectionMode_===SelectionMode.NONE)
+return;if(this.selectedTableRowInfo_===undefined)
+return;var code_to_command_names={37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};var cmdName=code_to_command_names[e.keyCode];if(cmdName===undefined)
+return;e.stopPropagation();e.preventDefault();this.performKeyCommand_(cmdName);},performKeyCommand_:function(cmdName){this.rebuildIfNeeded_();var rowInfo=this.selectedTableRowInfo_;var htmlNode=rowInfo.htmlNode;if(cmdName==='ARROW_UP'){var prev=htmlNode.previousElementSibling;if(prev){tr.ui.b.scrollIntoViewIfNeeded(prev);this.selectedTableRow=prev.rowInfo.userRow;this.focusSelected_();return;}
+return;}
+if(cmdName==='ARROW_DOWN'){var next=htmlNode.nextElementSibling;if(next){tr.ui.b.scrollIntoViewIfNeeded(next);this.selectedTableRow=next.rowInfo.userRow;this.focusSelected_();return;}
+return;}
+if(cmdName==='ARROW_RIGHT'){switch(this.selectionMode_){case SelectionMode.ROW:if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)
+return;if(rowInfo.userRow[this.subRowsPropertyName_].length===0)
+return;if(!rowInfo.isExpanded)
+this.setExpandedForTableRow(rowInfo.userRow,true);this.selectedTableRow=rowInfo.userRow[this.subRowsPropertyName_][0];this.focusSelected_();return;case SelectionMode.CELL:var newIndex=this.selectedColumnIndex_+1;if(newIndex>=this.tableColumns_.length)
+return;if(!this.doesColumnIndexSupportSelection(newIndex))
+return;this.selectedColumnIndex=newIndex;this.focusSelected_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
+if(cmdName==='ARROW_LEFT'){switch(this.selectionMode_){case SelectionMode.ROW:if(rowInfo.isExpanded){this.setExpandedForTableRow(rowInfo.userRow,false);this.focusSelected_();return;}
+var parentRowInfo=rowInfo.parentRowInfo;if(parentRowInfo){this.selectedTableRow=parentRowInfo.userRow;this.focusSelected_();return;}
+return;case SelectionMode.CELL:var newIndex=this.selectedColumnIndex_-1;if(newIndex<0)
+return;if(!this.doesColumnIndexSupportSelection(newIndex))
+return;this.selectedColumnIndex=newIndex;this.focusSelected_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
+throw new Error('Unrecognized command '+cmdName);},focusSelected_:function(){if(!this.selectedTableRowInfo_)
+return;var node=this.getSelectableNodeGivenTableRowNode_(this.selectedTableRowInfo_.htmlNode);node.focus();},dispatchSortingChangedEvent_:function(){var e=new tr.b.Event('sort-column-changed');e.sortColumnIndex=this.sortColumnIndex_;e.sortDescending=this.sortDescending_;this.dispatchEvent(e);}});})();'use strict';Polymer('tr-ui-b-table-header-cell',{created:function(){this.tapCallback_=undefined;this.cellTitle_='';},set cellTitle(value){this.cellTitle_=value;var titleNode=tr.ui.b.asHTMLOrTextNode(this.cellTitle_,this.ownerDocument);this.$.title.innerText='';this.$.title.appendChild(titleNode);},get cellTitle(){return this.cellTitle_;},clearSideContent:function(){this.$.side.textContent='';},set sideContent(content){this.$.side.textContent=content;},get sideContent(){return this.$.side.textContent;},set tapCallback(callback){this.style.cursor='pointer';this.tapCallback_=callback;},get tapCallback(){return this.tapCallback_;},onTap_:function(){if(this.tapCallback_)
+this.tapCallback_();}});'use strict';tr.exportTo('tr.ui.b',function(){Object.observe(Polymer.elements,clearPolymerElementCaches);var elementsByName=undefined;var elementsThatExtend=undefined;var elementSubclasses=undefined;function clearPolymerElementCaches(){elementsByName={};elementsThatExtend=undefined;elementSubclasses={};}
+function buildElementMapsIfNeeded(){if(elementsThatExtend!==undefined&&elementsByName!==undefined)
+return;elementsByName={};elementsThatExtend={};Polymer.elements.forEach(function(element){if(elementsByName[element.name])
+throw new Error('Something is strange: dupe polymer element names');elementsByName[element.name]=element;if(element.extends){if(elementsThatExtend[element.extends]===undefined)
+elementsThatExtend[element.extends]=[];elementsThatExtend[element.extends].push(element.name);}});}
+function getPolymerElementNamed(tagName){buildElementMapsIfNeeded();return elementsByName[tagName];}
+function getPolymerElementsThatSubclass(tagName){if(Polymer.waitingFor().length){throw new Error('There are unresolved polymer elements. '+'Wait until Polymer.whenReady');}
+buildElementMapsIfNeeded();var element=getPolymerElementNamed(tagName);if(!element)
+throw new Error(tagName+' is not a polymer element');if(elementSubclasses===undefined)
+elementSubclasses={};if(elementSubclasses[tagName]===undefined){var immediateSubElements=elementsThatExtend[element.name];var allSubElements=[];if(immediateSubElements!==undefined&&immediateSubElements.length){immediateSubElements.forEach(function(subElement){allSubElements.push(subElement);allSubElements.push.apply(allSubElements,getPolymerElementsThatSubclass(subElement));});}
+elementSubclasses[tagName]=allSubElements;}
+return elementSubclasses[tagName];}
+return{getPolymerElementNamed:getPolymerElementNamed,getPolymerElementsThatSubclass:getPolymerElementsThatSubclass};});'use strict';tr.exportTo('tr.ui.units',function(){function createScalarSpan(value,opt_config){if(value===undefined)
+return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-ui-u-scalar-span');span.value=value;return span;}
+tr.b.u.Units.addEventListener('display-mode-changed',function(e){var subclassNames=tr.ui.b.getPolymerElementsThatSubclass('tr-ui-u-scalar-span');var isSubclass={};subclassNames.forEach(function(n){isSubclass[n.toUpperCase()]=true;});var m=tr.b.findDeepElementsMatchingPredicate(document.body,function(el){return isSubclass[el.tagName];});m.forEach(function(el){el.updateContent_();});});return{createScalarSpan:createScalarSpan};});'use strict';Polymer('tr-ui-u-scalar-span',{ready:function(){this.value_=undefined;this.unit_=undefined;this.warning_=undefined;this.percentage_=undefined;this.isDelta_=false;},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.b.u.Scalar){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
+this.updateContent_();},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContent_();},setValueAndUnit:function(value,unit){this.value_=value;this.unit_=unit;this.updateContent_();},get percentage(){return this.percentage_;},set percentage(percentage){this.percentage_=percentage;this.updateSparkline_();},get rightAlign(){return this.$.content.classList.contains('right-align');},set rightAlign(rightAlign){if(rightAlign)
+this.$.content.classList.add('right-align');else
+this.$.content.classList.remove('right-align');},get isDelta(){return this.isDelta_;},set isDelta(isDelta){this.isDelta_=isDelta;this.updateContent_();},updateSparkline_:function(){if(this.percentage_===undefined){this.$.sparkline.style.display='none';this.$.sparkline.style.width='0';}else{this.$.sparkline.style.display='block';this.$.sparkline.style.width=(this.percentage_*100)+'%';}},updateContent_:function(){if(this.unit_===undefined){this.$.content.textContent='';return;}
+var content=this.unit_.format(this.value);if(this.isDelta_){if(this.value>0){content='+'+content;}else if(this.value===0){var PLUS_MINUS_SIGN=String.fromCharCode(177);content=PLUS_MINUS_SIGN+content;}}
+this.$.content.textContent=content;},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;var warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='';}else{warningEl.title='';warningEl.style.display='none';}}});'use strict';tr.exportTo('tr.ui.units',function(){function createTimeDurationSpan(duration,opt_config){if(duration===undefined)
+return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-ui-u-time-duration-span');span.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);if(config.total)
+span.percentage=duration/config.total;span.duration=duration;if(config.rightAlign)
+span.rightAlign=true;return span;}
+return{createTimeDurationSpan:createTimeDurationSpan};});'use strict';Polymer('tr-ui-u-time-duration-span',{get duration(){return this.value;},set duration(duration){if(duration instanceof tr.b.u.TimeDuration){this.value=duration;return;}
+this.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);}});'use strict';tr.exportTo('tr.ui.units',function(){function createTimeStampSpan(timestamp,opt_config){if(timestamp===undefined)
+return'';var config=opt_config||{};var ownerDocument=config.ownerDocument||document;var span=ownerDocument.createElement('tr-ui-u-time-stamp-span');span.timestamp=timestamp;return span;}
+return{createTimeStampSpan:createTimeStampSpan};});'use strict';Polymer('tr-ui-u-time-stamp-span',{get timestamp(){return this.value;},set timestamp(timestamp){if(timestamp instanceof tr.b.u.TimeStamp){this.value=timestamp;return;}
+this.setValueAndUnit(timestamp,tr.b.u.Units.timeStampInMs);}});'use strict';function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(var colName in object[0]){if(typeof colName!=='string')return false;}
+for(var i=0;i<object.length;++i){if(!(object[i]instanceof Object))return false;for(var colName in object[i]){if(i&&(object[0][colName]===undefined))return false;var cellType=typeof object[i][colName];if(cellType!=='string'&&cellType!='number')return false;}
+if(i){for(var colName in object[0]){if(object[i][colName]===undefined)return false;}}}
+return true;}
+Polymer('tr-ui-a-generic-object-view',{ready:function(){this.object_=undefined;},get object(){return this.object_;},set object(object){this.object_=object;this.updateContents_();},updateContents_:function(){this.$.content.textContent='';this.appendElementsForType_('',this.object_,0,0,5,'');},appendElementsForType_:function(label,object,indent,depth,maxDepth,suffix){if(depth>maxDepth){this.appendSimpleText_(label,indent,'<recursion limit reached>',suffix);return;}
+if(object===undefined){this.appendSimpleText_(label,indent,'undefined',suffix);return;}
+if(object===null){this.appendSimpleText_(label,indent,'null',suffix);return;}
+if(!(object instanceof Object)){var type=typeof object;if(type=='string'){var objectReplaced=false;if((object[0]=='{'&&object[object.length-1]=='}')||(object[0]=='['&&object[object.length-1]==']')){try{object=JSON.parse(object);objectReplaced=true;}catch(e){}}
+if(!objectReplaced){if(object.indexOf('\n')!==-1){var lines=object.split('\n');lines.forEach(function(line,i){var text,ioff,ll,ss;if(i==0){text='"'+line;ioff=0;ll=label;ss='';}else if(i<lines.length-1){text=line;ioff=1;ll='';ss='';}else{text=line+'"';ioff=1;ll='';ss=suffix;}
+var el=this.appendSimpleText_(ll,indent+ioff*label.length+ioff,text,ss);el.style.whiteSpace='pre';return el;},this);return;}else{this.appendSimpleText_(label,indent,'"'+object+'"',suffix);return;}}
+else{}}else{return this.appendSimpleText_(label,indent,object,suffix);}}
+if(object instanceof tr.model.ObjectSnapshot){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.model.ObjectInstance){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.b.Rect){this.appendSimpleText_(label,indent,object.toString(),suffix);return;}
+if(object instanceof tr.b.u.Scalar){var el=this.ownerDocument.createElement('tr-ui-u-scalar-span');el.value=object;this.appendElementWithLabel_(label,indent,el,suffix);return;}
+if(object instanceof Array){this.appendElementsForArray_(label,object,indent,depth,maxDepth,suffix);return;}
+this.appendElementsForObject_(label,object,indent,depth,maxDepth,suffix);},appendElementsForArray_:function(label,object,indent,depth,maxDepth,suffix){if(object.length==0){this.appendSimpleText_(label,indent,'[]',suffix);return;}
+if(isTable(object)){var table=document.createElement('tr-ui-b-table');var columns=[];tr.b.iterItems(object[0],function(colName){columns.push({title:colName,value:function(row){return row[colName];}});});table.tableColumns=columns;table.tableRows=object;this.appendElementWithLabel_(label,indent,table,suffix);table.rebuild();return;}
+this.appendElementsForType_(label+'[',object[0],indent,depth+1,maxDepth,object.length>1?',':']'+suffix);for(var i=1;i<object.length;i++){this.appendElementsForType_('',object[i],indent+label.length+1,depth+1,maxDepth,i<object.length-1?',':']'+suffix);}
+return;},appendElementsForObject_:function(label,object,indent,depth,maxDepth,suffix){var keys=tr.b.dictionaryKeys(object);if(keys.length==0){this.appendSimpleText_(label,indent,'{}',suffix);return;}
+this.appendElementsForType_(label+'{'+keys[0]+': ',object[keys[0]],indent,depth,maxDepth,keys.length>1?',':'}'+suffix);for(var i=1;i<keys.length;i++){this.appendElementsForType_(keys[i]+': ',object[keys[i]],indent+label.length+1,depth+1,maxDepth,i<keys.length-1?',':'}'+suffix);}},appendElementWithLabel_:function(label,indent,dataElement,suffix){var row=document.createElement('div');var indentSpan=document.createElement('span');indentSpan.style.whiteSpace='pre';for(var i=0;i<indent;i++)
+indentSpan.textContent+=' ';row.appendChild(indentSpan);var labelSpan=document.createElement('span');labelSpan.textContent=label;row.appendChild(labelSpan);row.appendChild(dataElement);var suffixSpan=document.createElement('span');suffixSpan.textContent=suffix;row.appendChild(suffixSpan);row.dataElement=dataElement;this.$.content.appendChild(row);},appendSimpleText_:function(label,indent,text,suffix){var el=this.ownerDocument.createElement('span');el.textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer('tr-ui-a-generic-object-view-with-label',{ready:function(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');this.shadowRoot.appendChild(this.labelEl_);this.shadowRoot.appendChild(this.genericObjectView_);},get label(){return this.labelEl_.textContent;},set label(label){this.labelEl_.textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';Polymer('tr-ui-a-stack-frame',{ready:function(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){var table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
+var hasName=false;var hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});var cols=[];if(hasName){cols.push({title:'Name',value:function(row){return row.name;}});}
+if(hasTitle){cols.push({title:'Title',value:function(row){return row.title;}});}
+table.tableColumns=cols;table.rebuild();},tableForTesting:function(){return this.$.table;}});'use strict';Polymer('tr-ui-a-single-event-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},getEventRows_:function(event){var rows=[];if(event.error)
+rows.push({name:'Error',value:event.error});if(event.title)
+rows.push({name:'Title',value:event.title});if(event.category)
+rows.push({name:'Category',value:event.category});if(event.name)
+rows.push({name:'Name',value:event.name});var startEl=document.createElement('tr-ui-u-time-stamp-span');startEl.timestamp=event.start;rows.push({name:'Start',value:startEl});if(event.duration){var wallDurationEl=document.createElement('tr-ui-u-time-duration-span');wallDurationEl.duration=event.duration;rows.push({name:'Wall Duration',value:wallDurationEl});}
+if(event.cpuDuration){var cpuDurationEl=document.createElement('tr-ui-u-time-duration-span');cpuDurationEl.duration=event.cpuDuration;rows.push({name:'CPU Duration',value:cpuDurationEl});}
+if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){var selfTimeEl=document.createElement('tr-ui-u-time-duration-span');selfTimeEl.duration=event.selfTime;rows.push({name:'Self Time',value:selfTimeEl});}
+if(event.cpuSelfTime){var cpuSelfTimeEl=document.createElement('tr-ui-u-time-duration-span');cpuSelfTimeEl.duration=event.cpuSelfTime;if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
+rows.push({name:'CPU Self Time',value:cpuSelfTimeEl});}}
+if(event.durationInUserTime){var durationInUserTimeEl=document.createElement('tr-ui-u-time-duration-span');durationInUserTimeEl.duration=event.durationInUserTime;rows.push({name:'Duration (U)',value:durationInUserTimeEl});}
+function createStackFrameEl(sf){var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
+if(event.startStackFrame&&event.endStackFrame){if(event.startStackFrame===event.endStackFrame){rows.push({name:'Start+End Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else{rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}}else if(event.startStackFrame){rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else if(event.endStackFrame){rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}
+if(event.info){var descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}}
+if(event.associatedAlerts.length){var alertSubRows=[];event.associatedAlerts.forEach(function(alert){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
+return rows;},addArgsToRows_:function(rows,args){var n=0;for(var argName in args){n+=1;}
+if(n>0){var subRows=[];for(var argName in args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
+rows.push({name:'Args',value:'',isExpanded:true,subRows:subRows});}
+return rows;},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+var event=this.currentSelection_[0];var rows=this.getEventRows_(event);if(event.argsStripped)
+rows.push({name:'Args',value:'Stripped'});else
+this.addArgsToRows_(rows,event.args);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){var FLOW_IN=0x1;var FLOW_OUT=0x2;var FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
+FlowClassifier.prototype={getFS_:function(event){var fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event:event};this.eventsByGUID_[event.guid]=fs;}
+return fs;},addInFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents:function(){return this.numEvents_>0;},get inFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN)
+selection.push(fs.event);}
+return selection;},get outFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT)
+selection.push(fs.event);}
+return selection;},get internalFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT)
+selection.push(fs.event);}
+return selection;}};return{FlowClassifier:FlowClassifier};});'use strict';Polymer('tr-ui-a-related-events',{ready:function(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip)
+typeEl.title=row.tooltip;return typeEl;},width:'150px'},{title:'Link',width:'100%',value:function(row){var linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name)
+linkEl.setSelectionAndContent(row.selection,row.name);else
+linkEl.selection=row.selection;return linkEl;}}];},hasRelatedEvents:function(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents:function(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_:function(eventSet){var classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
+if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())
+return;var addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type:type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_:function(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_:function(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addAncestors_(event,events);if(event.startSlice)
+events.push(event.startSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function(event,events){this.addOutFlowEvents_(event,events);this.addDescendents_(event,events);if(event.endSlice)
+events.push(event.endSlice);}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function(event,events){this.addInFlowEvents_(event,events);this.addOutFlowEvents_(event,events);this.addAncestors_(event,events);this.addDescendents_(event,events);if(event.startSlice)
+events.push(event.startSlice);if(event.endSlice)
+events.push(event.endSlice);}.bind(this)));},createEventsLinkIfNeeded_:function(title,tooltip,events,addFunction){events=new tr.model.EventSet(events);var lengthBefore=events.length;var task;var isCanceled=false;function addEventsUntilTimeout(startingIndex){if(isCanceled)
+return;var startingTime=window.performance.now();while(startingIndex<events.length){addFunction(events[startingIndex],events);startingIndex++;if(window.performance.now()-startingTime>8){var newTask=new tr.b.Task(addEventsUntilTimeout.bind(this,startingIndex),this);task.after(newTask);task=newTask;return;}}
+if(lengthBefore===events.length)
+return;this.eventGroups_.push({type:title,tooltip:tooltip,selection:events});this.updateContents_();};function cancelTask(){isCanceled=true;}
+task=new tr.b.Task(addEventsUntilTimeout.bind(this,0),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addInFlowEvents_:function(event,eventSet){if(!event.inFlowEvents)
+return;event.inFlowEvents.forEach(function(e){eventSet.push(e);});},addOutFlowEvents_:function(event,eventSet){if(!event.outFlowEvents)
+return;event.outFlowEvents.forEach(function(e){eventSet.push(e);});},addAncestors_:function(event,eventSet){if(!event.iterateAllAncestors)
+return;event.iterateAllAncestors(function(e){eventSet.push(e);});},addDescendents_:function(event,eventSet){if(!event.iterateAllDescendents)
+return;event.iterateAllDescendents(function(e){eventSet.push(e);});},addOverlappingSamples_:function(eventSet){var samples=new tr.model.EventSet;eventSet.forEach(function(slice){if(!slice.parentContainer||!slice.parentContainer.samples)
+return;var candidates=slice.parentContainer.samples;var range=tr.b.Range.fromExplicitRange(slice.start,slice.start+slice.duration);var filteredSamples=range.filterArray(candidates,function(value){return value.start;});filteredSamples.forEach(function(sample){samples.push(sample);});}.bind(this));if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},updateContents_:function(){var table=this.$.table;if(this.eventGroups_===undefined)
+table.tableRows=[];else
+table.tableRows=this.eventGroups_.slice();table.rebuild();}});'use strict';Polymer('tr-ui-a-single-thread-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents())
+this.$.relatedEvents.style.display='';else
+this.$.relatedEvents.style.display='none';}});'use strict';Polymer('tr-ui-a-selection-summary-table',{created:function(){this.selection_=new tr.b.Range();},ready:function(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;var rows=[];var hasRange;if(this.selection_&&(!selection.bounds.isEmpty))
+hasRange=true;else
+hasRange=false;var timeSpanConfig={ownerDocument:this.ownerDocument};rows.push({title:'Selection start',value:hasRange?tr.ui.units.createTimeStampSpan(selection.bounds.min,timeSpanConfig):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.ui.units.createTimeDurationSpan(selection.bounds.range,timeSpanConfig):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;};MultiEventSummary.prototype={set title(title){if(title=='Totals')
+this.totalsRow=true;this.title_=title;},get title(){return this.title_;},get duration(){if(this.duration_===undefined){this.duration_=tr.b.Statistics.sum(this.events_,function(event){return event.duration;});}
+return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_:function(){if(this.cpuTimesComputed_)
+return;this.cpuTimesComputed_=true;var cpuSelfTime=0;var cpuDuration=0;var hasCpuData=false;for(var i=0;i<this.events_.length;i++){var event=this.events_[i];if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
+if(event.cpuSelfTime!==undefined){cpuSelfTime+=event.cpuSelfTime;hasCpuData=true;}}
+if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(var i=0;i<this.events_.length;i++){if(this.events_[i].selfTime!==undefined)
+this.selfTime_+=this.events[i].selfTime;}}
+return this.selfTime_;},get events(){return this.events_;},get numEvents(){return this.events_.length;},get numAlerts(){if(this.numAlerts_===undefined){this.numAlerts_=tr.b.Statistics.sum(this.events_,function(event){return event.associatedAlerts.length;});}
+return this.numAlerts_;},get untotallableArgs(){this.updateArgsIfNeeded_();return this.untotallableArgs_;},get totalledArgs(){this.updateArgsIfNeeded_();return this.totalledArgs_;},get maxDuration(){if(this.maxDuration_===undefined){this.maxDuration_=tr.b.Statistics.max(this.events_,function(event){return event.duration;});}
+return this.maxDuration_;},get maxCpuDuration(){if(this.maxCpuDuration_===undefined){this.maxCpuDuration_=tr.b.Statistics.max(this.events_,function(event){return event.cpuDuration;});}
+return this.maxCpuDuration_;},get maxSelfTime(){if(this.maxSelfTime_===undefined){this.maxSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.selfTime;});}
+return this.maxSelfTime_;},get maxCpuSelfTime(){if(this.maxCpuSelfTime_===undefined){this.maxCpuSelfTime_=tr.b.Statistics.max(this.events_,function(event){return event.cpuSelfTime;});}
+return this.maxCpuSelfTime_;},updateArgsIfNeeded_:function(){if(this.totalledArgs_!==undefined)
+return;var untotallableArgs={};var totalledArgs={};for(var i=0;i<this.events_.length;i++){var event=this.events_[i];for(var argName in event.args){var argVal=event.args[argName];var type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
+if(untotallableArgs[argName]){continue;}
+if(totalledArgs[argName]===undefined)
+totalledArgs[argName]=0;totalledArgs[argName]+=argVal;}}
+this.untotallableArgs_=tr.b.dictionaryKeys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary:MultiEventSummary};});'use strict';Polymer('tr-ui-a-multi-event-summary-table',{ready:function(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_:function(rows,maxValues){var hasCpuData=false;var hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined)
+hasCpuData=true;if(row.cpuSelfTime!==undefined)
+hasCpuData=true;if(row.numAlerts)
+hasAlerts=true;});var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Name',value:function(row){if(row.title==='Totals')
+return'Totals';var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,{total:row.totalsRow?undefined:maxValues.duration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
+if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuDuration,{total:row.totalsRow?undefined:maxValues.cpuDuration,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value:function(row){return tr.ui.units.createTimeDurationSpan(row.selfTime,{total:row.totalsRow?undefined:maxValues.selfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuSelfTime,{total:row.totalsRow?undefined:maxValues.cpuSelfTime,ownerDocument:ownerDocument,rightAlign:true});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
+columns.push({title:'Occurrences',value:function(row){return row.numEvents;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});var alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value:function(row){return row.numAlerts;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
+var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure:function(config){if(config.eventsByTitle===undefined)
+throw new Error('Required: eventsByTitle');if(config.showTotals!==undefined)
+this.showTotals_=config.showTotals;else
+this.showTotals_=true;if(config.eventsHaveDuration!==undefined)
+this.eventsHaveDuration_=config.eventsHaveDuration;else
+this.eventsHaveDuration_=true;if(config.eventsHaveSubRows!==undefined)
+this.eventsHaveSubRows_=config.eventsHaveSubRows;else
+this.eventsHaveSubRows_=true;this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_:function(){var eventsByTitle;if(this.eventsByTitle_!==undefined)
+eventsByTitle=this.eventsByTitle_;else
+eventsByTitle=[];var allEvents=[];var rows=[];tr.b.iterItems(eventsByTitle,function(title,eventsOfSingleTitle){allEvents.push.apply(allEvents,eventsOfSingleTitle);var row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);});this.updateTableColumns_(rows);this.$.table.tableRows=rows;var maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(var column in maxValues){maxValues[column]=tr.b.Statistics.max(rows,function(event){return event[column];});}}
+var footerRows=[];if(this.showTotals_){var multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
+this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-multi-event-details-table',{created:function(){this.selection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},ready:function(){this.initTitleTable_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;this.updateTitleTable_();if(this.selection_===undefined){this.$.table.tableRows=[];this.$.table.tableFooterRows=[];this.$.table.rebuild();return;}
+var summary=new tr.ui.analysis.MultiEventSummary('Totals',this.selection_);this.updateColumns_(summary);this.updateRows_(summary);this.$.table.rebuild();},initTitleTable_:function(){var table=this.$.titletable;table.showHeader=false;table.tableColumns=[{title:'Title',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},updateTitleTable_:function(){var title;if(this.selection_&&this.selection_.length)
+title=this.selection_[0].title;else
+title='<No selection>';var table=this.$.titletable;table.tableRows=[{title:'Title',value:title}];},updateColumns_:function(summary){var hasCpuData;if(summary.cpuDuration!==undefined)
+hasCpuData=true;if(summary.cpuSelfTime!==undefined)
+hasCpuData=true;var colWidthPercentage;if(hasCpuData)
+colWidthPercentage='20%';else
+colWidthPercentage='33.3333%';var timeSpanConfig={ownerDocument:this.ownerDocument};var columns=[];columns.push({title:'Start',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype){return row.title;}
+var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.event);});linkEl.appendChild(tr.ui.units.createTimeStampSpan(row.start,timeSpanConfig));return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.start-rowB.start;}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
+if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuDuration,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.selfTime,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.cpuSelfTime,timeSpanConfig);},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
+var argKeys=tr.b.dictionaryKeys(summary.totalledArgs);argKeys.sort();var otherKeys=summary.untotallableArgs.slice(0);otherKeys.sort();argKeys.push.apply(argKeys,otherKeys);var keysWithColumns=argKeys.slice(0,4);var keysInOtherColumn=argKeys.slice(4);keysWithColumns.forEach(function(argKey){var hasTotal=summary.totalledArgs[argKey];var colDesc={title:'Arg: '+argKey,value:function(row){if(row.__proto__!==tr.ui.analysis.MultiEventSummary.prototype){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=row.args[argKey];return argView;}
+if(hasTotal)
+return row.totalledArgs[argKey];return'';},width:'<upated further down>'};if(hasTotal){colDesc.cmp=function(rowA,rowB){return rowA.args[argKey]-rowB.args[argKey];}}
+columns.push(colDesc);});if(keysInOtherColumn.length){columns.push({title:'Other Args',value:function(row){if(row.__proto__===tr.ui.analysis.MultiEventSummary.prototype)
+return'';var argView=document.createElement('tr-ui-a-generic-object-view');var obj={};for(var i=0;i<keysInOtherColumn.length;i++)
+obj[keysInOtherColumn[i]]=row.args[keysInOtherColumn[i]];argView.object=obj;return argView;},width:'<upated further down>'});}
+var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;this.$.table.tableColumns=columns;},updateRows_:function(summary){this.$.table.sortColumnIndex=0;function Row(event){this.event=event;}
+Row.prototype={get start(){return this.event.start;},get duration(){return this.event.duration;},get cpuDuration(){return this.event.cpuDuration;},get selfTime(){return this.event.selfTime;},get cpuSelfTime(){return this.event.cpuSelfTime;},get args(){return this.event.args;}};this.$.table.tableRows=this.selection_.map(function(event){return new Row(event);});this.$.table.footerRows=[summary];}});'use strict';Polymer('tr-ui-a-multi-event-sub-view',{created:function(){this.currentSelection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},set selection(selection){if(selection.length<=1)
+throw new Error('Only supports multiple items');this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},updateContents_:function(){var selection=this.currentSelection_;this.$.content.textContent='';if(!selection)
+return;var eventsByTitle=selection.getEventsOrganizedByTitle();var numTitles=tr.b.dictionaryLength(eventsByTitle);var summaryTableEl=document.createElement('tr-ui-a-multi-event-summary-table');summaryTableEl.configure({showTotals:numTitles>1,eventsByTitle:eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.content.appendChild(summaryTableEl);var selectionSummaryTableEl=document.createElement('tr-ui-a-selection-summary-table');selectionSummaryTableEl.selection=this.currentSelection_;this.$.content.appendChild(selectionSummaryTableEl);if(numTitles===1){var detailsTableEl=document.createElement('tr-ui-a-multi-event-details-table');detailsTableEl.eventsHaveDuration=this.eventsHaveDuration_;detailsTableEl.eventsHaveSubRows=this.eventsHaveSubRows_;detailsTableEl.selection=selection;this.$.content.appendChild(detailsTableEl);}}});'use strict';Polymer('tr-ui-a-multi-thread-slice-sub-view',{created:function(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){var ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);var ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;this.$.content.textContent='';this.$.content.appendChild(ltv);this.requiresTallView_=true;return;}}
+this.$.content.textContent='';var mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;this.$.content.appendChild(mesv);var relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){this.$.content.appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)
+return false;var childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW')
+return false;return true;}});'use strict';Polymer('tr-ui-a-single-async-slice-sub-view',{getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-multi-async-slice-sub-view',{get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;},get relatedEventsToHighlight(){if(!this.$.content.selection)
+return undefined;var selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)
+return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)
+return selection;return undefined;}});'use strict';Polymer('tr-ui-a-single-cpu-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.CpuSlice))
+throw new Error('Only supports thread time slices');this.currentSelection_=selection;var cpuSlice=selection[0];var thread=cpuSlice.threadThatWasRunning;var shadowRoot=this.shadowRoot;if(thread){shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;}else{shadowRoot.querySelector('#process-name').parentElement.style.display='none';shadowRoot.querySelector('#thread-name').textContent=cpuSlice.title;}
+shadowRoot.querySelector('#start').timestamp=cpuSlice.start;shadowRoot.querySelector('#duration').duration=cpuSlice.duration;var runningThreadEl=shadowRoot.querySelector('#running-thread');var timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{var threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);threadLink.textContent='Click to select';runningThreadEl.parentElement.style.display='';runningThreadEl.textContent='';runningThreadEl.appendChild(threadLink);}
+shadowRoot.querySelector('#args').object=cpuSlice.args;}});'use strict';Polymer('tr-ui-a-multi-cpu-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-single-thread-time-slice-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single slices');if(!(selection[0]instanceof tr.model.ThreadTimeSlice))
+throw new Error('Only supports thread time slices');this.currentSelection_=selection;var timeSlice=selection[0];var thread=timeSlice.thread;var shadowRoot=this.shadowRoot;shadowRoot.querySelector('#state').textContent=timeSlice.title;var stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];shadowRoot.querySelector('#state').style.backgroundColor=stateColor;shadowRoot.querySelector('#process-name').textContent=thread.parent.userFriendlyName;shadowRoot.querySelector('#thread-name').textContent=thread.userFriendlyName;shadowRoot.querySelector('#start').timestamp=timeSlice.start;shadowRoot.querySelector('#duration').duration=timeSlice.duration;var onCpuEl=shadowRoot.querySelector('#on-cpu');onCpuEl.textContent='';var runningInsteadEl=shadowRoot.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){runningInsteadEl.parentElement.removeChild(runningInsteadEl);var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());cpuLink.textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;onCpuEl.appendChild(cpuLink);}else{onCpuEl.parentElement.removeChild(onCpuEl);var cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread)
+cpuLink.textContent=cpuSliceThatTookCpu.thread.userFriendlyName;else
+cpuLink.textContent=cpuSliceThatTookCpu.title;runningInsteadEl.appendChild(cpuLink);}else{runningInsteadEl.parentElement.removeChild(runningInsteadEl);}}
+var argsEl=shadowRoot.querySelector('#args');if(tr.b.dictionaryKeys(timeSlice.args).length>0){var argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';argsEl.textContent='';argsEl.appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});'use strict';Polymer('tr-ui-a-multi-thread-time-slice-sub-view',{ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});'use strict';Polymer('tr-ui-a-single-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);this.$.content.appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer('tr-ui-a-multi-instant-event-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.$.content.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.$.content.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';(function(){var COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value:function(row){return row.counter;}},{title:'Series',width:'150px',value:function(row){return row.series;}},{title:'Time',width:'150px',value:function(row){return row.start;}},{title:'Value',width:'100%',value:function(row){return row.value;}}];Polymer('tr-ui-a-counter-sample-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_:function(samples){var samplesByCounter=tr.b.group(samples,function(sample){return sample.series.counter.guid;});var rows=[];tr.b.iterItems(samplesByCounter,function(unused,counterSamples){var samplesBySeries=tr.b.group(counterSamples,function(sample){return sample.series.guid;});tr.b.iterItems(samplesBySeries,function(unused,seriesSamples){var seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
+rows.push(seriesRows[0]);},this);},this);return rows;},getRowsForSamples_:function(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});})();'use strict';Polymer('tr-ui-a-single-flow-event-sub-view',{getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});linkEl.textContent=slice.userFriendlyName;return linkEl;}
+rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;}});'use strict';Polymer('tr-ui-a-multi-flow-event-sub-view',{ready:function(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView:ObjectInstanceView};});'use strict';Polymer('tr-ui-a-single-object-instance-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0)
+return false;if(this.$.content.children[0]instanceof
+tr.ui.analysis.ObjectInstanceView)
+return this.$.content.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectInstance))
+throw new Error('Only supports object instances');this.$.content.textContent='';this.currentSelection_=selection;var instance=selection[0];var typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.$.content.appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_:function(instance){var html='';html+='<div class="title">'+
+instance.typeName+' '+
+instance.id+'</div>\n';html+='<table>';html+='<tr>';html+='<tr><td>creationTs:</td><td>'+
+instance.creationTs+'</td></tr>\n';if(instance.deletionTs!=Number.MAX_VALUE){html+='<tr><td>deletionTs:</td><td>'+
+instance.deletionTs+'</td></tr>\n';}else{html+='<tr><td>deletionTs:</td><td>not deleted</td></tr>\n';}
+html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';this.$.content.innerHTML=html;var snapshotsEl=this.$.content.querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);snapshotsEl.appendChild(snapshotLink);});}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView:ObjectSnapshotView};});'use strict';Polymer('tr-ui-a-single-object-snapshot-sub-view',{created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0)
+return false;if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView)
+return this.children[0].requiresTallView;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1)
+throw new Error('Only supports single item selections');if(!(selection[0]instanceof tr.model.ObjectSnapshot))
+throw new Error('Only supports object instances');this.textContent='';this.currentSelection_=selection;var snapshot=selection[0];var typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){var customView=new typeInfo.constructor();this.appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_:function(snapshot){var instance=snapshot.objectInstance;this.textContent='';var titleEl=document.createElement('div');titleEl.classList.add('title');titleEl.appendChild(document.createTextNode('Snapshot of '));this.appendChild(titleEl);var instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);titleEl.appendChild(instanceLinkEl);titleEl.appendChild(document.createTextNode(' @ '));titleEl.appendChild(tr.ui.units.createTimeStampSpan(snapshot.ts,{ownerDocument:this.ownerDocument}));var tableEl=document.createElement('table');this.appendChild(tableEl);var rowEl=document.createElement('tr');tableEl.appendChild(rowEl);var labelEl=document.createElement('td');labelEl.textContent='args:';rowEl.appendChild(labelEl);var argsEl=document.createElement('td');argsEl.id='args';rowEl.appendChild(argsEl);var objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;argsEl.appendChild(objectViewEl);}});'use strict';Polymer('tr-ui-a-multi-object-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;var objectEvents=tr.b.asArray(selection).sort(tr.b.Range.compareByMinTimes);var timeSpanConfig={ownerDocument:this.ownerDocument};var table=this.$.content;table.tableColumns=[{title:'First',value:function(event){if(event instanceof tr.model.ObjectSnapshot)
+return tr.ui.units.createTimeStampSpan(event.ts,timeSpanConfig);var spanEl=document.createElement('span');spanEl.appendChild(tr.ui.units.createTimeStampSpan(event.creationTs,timeSpanConfig));spanEl.appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!=Number.MAX_VALUE){spanEl.appendChild(tr.ui.units.createTimeStampSpan(event.deletionTs,timeSpanConfig));}
+return spanEl;},width:'200px'},{title:'Second',value:function(event){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});'use strict';Polymer('tr-ui-a-single-sample-sub-view',{created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.tableColumns=[{title:'FirstColumn',value:function(row){return row.title;},width:'250px'},{title:'SecondColumn',value:function(row){return row.value;},width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
+var sample=this.currentSelection_[0];var table=this.$.content;var rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.ui.units.createTimeStampSpan(sample.start,{ownerDocument:this.ownerDocument})});var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sample.leafStackFrame;rows.push({title:'Stack trace',value:sfEl});table.tableRows=rows;table.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){function zFunction(list){var n=list.length;if(n===0)
+return[];var z=new Array(n);z[0]=0;for(var i=1,left=0,right=0;i<n;++i){var maxLength;if(i<=right)
+maxLength=Math.min(right-i+1,z[i-left]);else
+maxLength=0;while(i+maxLength<n&&list[maxLength]===list[i+maxLength])
+++maxLength;if(i+maxLength-1>right){left=i;right=i+maxLength-1;}
+z[i]=maxLength;}
+return z;}
+function StackFrameTreeNode(title,opt_frame){this.title=title;this.frame=opt_frame;this.parent=undefined;this.children=[];this.childMap={};this.total=0;this.self=0;}
+StackFrameTreeNode.prototype={get subRows(){return this.children;},get stackTraceTitles(){var titles=[];for(var currentNode=this;currentNode!==undefined;currentNode=currentNode.parent){titles.push(currentNode.title);}
+return titles;},getOrCreateChild:function(title,opt_frame){var childNode=this.childMap[title];if(childNode!==undefined)
+return childNode;childNode=new StackFrameTreeNode(title,opt_frame);childNode.parent=this;this.children.push(childNode);this.childMap[title]=childNode;return childNode;},addStackTrace:function(trace,value,opt_traceContainsRootFrame){var currentNode=this;var startIndex=trace.length-(opt_traceContainsRootFrame?2:1);for(var i=startIndex;i>=0;i--){currentNode.total+=value;var stackFrame=trace[i];currentNode=currentNode.getOrCreateChild(stackFrame.title,stackFrame);}
+currentNode.total+=value;currentNode.self+=value;},convertToBottomUpView:function(){var bottomUpViewRoot=new StackFrameTreeNode(this.title,this.frame);bottomUpViewRoot.total=this.total;bottomUpViewRoot.self=this.self;this.addChildrenToBottomUpViewRecursively_(bottomUpViewRoot);return bottomUpViewRoot;},addChildrenToBottomUpViewRecursively_:function(bottomUpViewRoot){this.children.forEach(function(child){child.addToBottomUpViewRecursively_(bottomUpViewRoot);});},addToBottomUpViewRecursively_:function(bottomUpViewRoot){var remainingRecursiveSuffixLength=this.calculateRecursiveSuffixLength_();var bottomUpParentNode=bottomUpViewRoot;for(var topDownNode=this;topDownNode.parent!==undefined;topDownNode=topDownNode.parent){var bottomUpChildNode=bottomUpParentNode.getOrCreateChild(topDownNode.title,topDownNode.frame);bottomUpChildNode.self+=this.self;if(remainingRecursiveSuffixLength>0)
+remainingRecursiveSuffixLength--;else
+bottomUpChildNode.total+=this.total;bottomUpParentNode=bottomUpChildNode;}
+this.addChildrenToBottomUpViewRecursively_(bottomUpViewRoot);},calculateRecursiveSuffixLength_:function(){var maxLengths=zFunction(this.stackTraceTitles);var recursiveSuffixLength=0;for(var i=0;i<maxLengths.length;i++)
+recursiveSuffixLength=Math.max(recursiveSuffixLength,maxLengths[i]);return recursiveSuffixLength;}};return{StackFrameTreeNode:StackFrameTreeNode,zFunction:zFunction};});'use strict';(function(){Polymer('tr-ui-a-multi-sample-sub-view',{ready:function(){this.viewSelector_=this.$.view_selector;this.selection_=undefined;this.viewSelector_.addEventListener('change',this.viewSelectorChanged_.bind(this));},viewSelectorChanged_:function(){this.samplingData_=this.createSamplingSummary_(this.selection_,this.viewSelector_.value);this.updateContents_();},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.samplingData_=this.createSamplingSummary_(selection,this.viewSelector_.value);this.updateContents_();},createSamplingSummary_:function(selection,viewOption){var root=new tr.ui.analysis.StackFrameTreeNode('(root)',undefined);var samples=selection.getEventsOrganizedByBaseType().sample;samples.forEach(function(sample){root.addStackTrace(sample.stackTrace,1);});switch(viewOption){case'TOPDOWNVIEW':return root;case'BOTTOMUPVIEW':return root.convertToBottomUpView();default:throw new Error('Unknown sampling summary view option: \''+viewOption+'\'');}},updateContents_:function(){var columns=[this.createPercentColumn_('Total'),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self'),this.createSamplesColumn_('Self'),{title:'Symbol',value:function(row){return row.title;},width:'250px',cmp:function(a,b){return a.title.localeCompare(b.title);},showExpandButtons:true}];this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=this.samplingData_.subRows;this.$.table.rebuild();},createPercentColumn_:function(title){var field=title.toLowerCase();return{title:title+' percent',value:function(row){var percent=row[field]/this.samplingData_.total;var span=document.createElement('tr-ui-u-scalar-span');span.value=(percent*100).toFixed(2);span.percentage=percent;span.unit=tr.b.u.Units.unitlessNumber;return span;}.bind(this),width:'60px',cmp:function(a,b){return a[field]-b[field];}};},createSamplesColumn_:function(title){var field=title.toLowerCase();return{title:title+' samples',value:function(row){return row[field];},width:'60px',cmp:function(a,b){return a[field]-b[field];}};}});})();'use strict';Polymer('tr-ui-a-single-interaction-record-sub-view',{created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-multi-interaction-record-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';Polymer('tr-ui-a-alert-sub-view',{ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_:function(alert){var rows=[];for(var argName in alert.args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
+if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return event;},event.title);var valueString='';if(event instanceof tr.model.TimedEvent)
+valueString='took '+event.duration.toFixed(2)+'ms';rows.push({name:linkEl,value:valueString});});}
+var descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;linkEl.textContent=linkObject.textContent;rows.push({name:linkObject.label,value:linkEl});});}
+return rows;},getRowsForAlerts_:function(alerts){if(alerts.length==1){var rows=[{name:'Alert',value:alerts[0].title}];var detailRows=this.getRowsForSingleAlert_(alerts[0]);rows.push.apply(rows,detailRows);return rows;}else{return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);}},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+var alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-single-frame-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!=1)
+throw new Error('Only supports single frame!');this.currentSelection_=selection;this.$.asv.selection=selection[0].associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;return this.currentSelection_[0].associatedEvents;}});'use strict';Polymer('tr-ui-a-multi-frame-sub-view',{created:function(){this.currentSelection_=undefined;},set selection(selection){this.textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;this.appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)
+return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var NO_BREAK_SPACE=String.fromCharCode(160);var COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
+TitleColumn.prototype={supportsCellSelection:false,value:function(row){var formattedTitle=this.formatTitle(row);var defined=row.defined;if(defined===undefined||defined.length===0)
+return formattedTitle;var firstDefined=defined[0];var lastDefined=defined[defined.length-1];var changeDefinedCount=0;for(var i=1;i<defined.length;i++){if(defined[i]!==defined[i-1])
+changeDefinedCount++;}
+var color=undefined;var prefix=undefined;if(!firstDefined&&lastDefined){color='red';prefix='+++';}else if(firstDefined&&!lastDefined){color='green';prefix='---';}
+if(changeDefinedCount>1){color='purple';}
+if(color===undefined&&prefix===undefined)
+return formattedTitle;var titleEl=document.createElement('span');if(prefix!==undefined){var prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';titleEl.appendChild(prefixEl);titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
+if(color!==undefined)
+titleEl.style.color=color;titleEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle:function(row){return row.title;},cmp:function(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,title,units,cellGetter,aggregationMode){this.name=name;this.title=title;this.units=units;this.cell=cellGetter;this.aggregationMode=aggregationMode;this.color=undefined;}
+MemoryColumn.fromRows=function(rows,cellKey,aggregationMode,opt_titleBuilder){var columnTraits={};function gatherTraits(row){if(row===undefined)
+return;var attrCells=row[cellKey];if(attrCells===undefined)
+return;tr.b.iterItems(attrCells,function(attrName,attrCell){if(attrCell===undefined)
+return;var attrValues=attrCell.attrs;if(attrValues===undefined)
+return;var existingTraits=columnTraits[attrName];attrValues.forEach(function(attrValue){if(attrValue===undefined)
+return;if(existingTraits===undefined){columnTraits[attrName]=existingTraits={constructor:attrValue.constructor,units:attrValue.units};return;}
+if(existingTraits.constructor!==attrValue.constructor||existingTraits.units!==attrValue.units){existingTraits.constructor=tr.model.UnknownAttribute;existingTraits.units=undefined;}});});if(row.subRows!==undefined)
+row.subRows.forEach(gatherTraits);};rows.forEach(gatherTraits);var titleBuilder=opt_titleBuilder||tr.b.identity;var columns=[];tr.b.iterItems(columnTraits,function(columnName,columnTraits){var cellGetter=fieldGetter(cellKey,columnName);var title=titleBuilder(columnName);columns.push(MemoryColumn.fromAttributeTraits(columnName,title,columnTraits,cellGetter,aggregationMode));});return columns;};MemoryColumn.fromAttributeTraits=function(name,title,traits,cellGetter,aggregationMode){var constructor;if(traits.constructor===tr.model.ScalarAttribute)
+constructor=ScalarMemoryColumn;else
+constructor=MemoryColumn;return new constructor(name,title,traits.units,cellGetter,aggregationMode);};MemoryColumn.spaceEqually=function(columns){var columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.sortByImportance=function(columns,importanceRules){var positions=columns.map(function(column,srcIndex){return{importance:column.getImportance(importanceRules),column:column};});positions.sort(function(a,b){if(a.importance===b.importance)
+return COLLATOR.compare(a.column.name,b.column.name);return b.importance-a.importance;});positions.forEach(function(position,dstIndex){columns[dstIndex]=position.column;});};MemoryColumn.columnNamesToImportanceRules=function(columnNames){return columnNames.map(function(columnName,columnIndex){return{condition:columnName,importance:columnNames.length-columnIndex};});};MemoryColumn.iconFromAttributeInfoType=function(type){switch(type){case tr.model.AttributeInfoType.WARNING:return{symbol:String.fromCharCode(9888),color:'red'};case tr.model.AttributeInfoType.LINK:return{symbol:String.fromCharCode(9903)};case tr.model.AttributeInfoType.MEMORY_OWNER:return{symbol:String.fromCharCode(8702),color:'green'};case tr.model.AttributeInfoType.MEMORY_OWNED:return{symbol:String.fromCharCode(8701),color:'green'};case tr.model.AttributeInfoType.OVERALL_VALUE:return{symbol:String.fromCharCode(8614)};case tr.model.AttributeInfoType.RECENT_VALUE:return{symbol:String.fromCharCode(8618)};case tr.model.AttributeInfoType.HAS_HEAP_DUMP:return{symbol:String.fromCharCode(9283)};default:return{symbol:String.fromCharCode(9432),color:'blue'};}
+throw new Error('Unreachable');};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.prototype={attrs:function(row){var cell=this.cell(row);if(cell===undefined)
+return undefined;return cell.attrs;},value:function(row){var attrs=this.attrs(row);if(this.hasAllAttrsUndefined(attrs))
+return'';return this.formatAttributes(attrs);},hasAllAttrsUndefined:function(attrs){if(attrs===undefined)
+return true;return attrs.every(function(attr){return attr===undefined;});},formatAttributes:function(attrs){var formattedValue=this.formatAttributeValues(attrs);var color;if(typeof this.color==='function')
+color=this.color(attrs);else
+color=this.color;var infos=this.getInfos(attrs);if((color===undefined||formattedValue==='')&&infos.length===0)
+return formattedValue;var attrEl=document.createElement('span');attrEl.style.display='flex';attrEl.style.alignItems='center';attrEl.appendChild(tr.ui.b.asHTMLOrTextNode(formattedValue));infos.forEach(function(info){var infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';var icon=MemoryColumn.iconFromAttributeInfoType(info.type);infoEl.textContent=icon.symbol;if(icon.color!==undefined)
+infoEl.style.color=icon.color;infoEl.title=info.message;attrEl.appendChild(infoEl);},this);if(color!==undefined)
+attrEl.style.color=color;return attrEl;},formatAttributeValues:function(attrs){if(attrs.length===1)
+return this.formatSingleAttributeValue(attrs[0]);else
+return this.formatMultipleAttributeValues(attrs);},formatSingleAttributeValue:function(attr){return String(attr.value);},formatMultipleAttributeValues:function(attrs){var commonAttr=this.getCommonAttributeOrUndefined(attrs);if(commonAttr===undefined){return tr.ui.b.createSpan({textContent:'(multiple values)',italic:true});}
+return this.formatSingleAttributeValue(commonAttr);},cmp:function(rowA,rowB){var attrsA=this.attrs(rowA);var attrsB=this.attrs(rowB);if(attrsA!==undefined&&attrsB!==undefined&&attrsA.length!==attrsB.length)
+throw new Error('Different number of attributes');var undefinedA=this.hasAllAttrsUndefined(attrsA);var undefinedB=this.hasAllAttrsUndefined(attrsB);if(undefinedA&&undefinedB)
+return 0;if(undefinedA)
+return-1;if(undefinedB)
+return 1;return this.compareAttributes(attrsA,attrsB);},compareAttributes:function(attrsA,attrsB){if(attrsA.length===1)
+return this.compareSingleAttributes(attrsA[0],attrsB[0]);else
+return this.compareMultipleAttributes(attrsA,attrsB);},compareSingleAttributes:function(attrA,attrB){var strA=String(attrA.value);var strB=String(attrB.value);return COLLATOR.compare(strA,strB);},compareMultipleAttributes:function(attrsA,attrsB){var commonAttrA=this.getCommonAttributeOrUndefined(attrsA);var commonAttrB=this.getCommonAttributeOrUndefined(attrsB);var hasMultipleValuesA=commonAttrA===undefined;var hasMultipleValuesB=commonAttrB===undefined;if(hasMultipleValuesA&&hasMultipleValuesB)
+return 0;if(hasMultipleValuesA)
+return 1;if(hasMultipleValuesB)
+return-1;return this.compareSingleAttributes(commonAttrA,commonAttrB);},getCommonAttributeOrUndefined:function(attrs){var firstDefinedAttribute=undefined;for(var i=0;i<attrs.length;i++){var attr=attrs[i];if(attr===undefined)
+continue;if(firstDefinedAttribute===undefined){firstDefinedAttribute=attr;continue;}
+if(firstDefinedAttribute.value!==attr.value||firstDefinedAttribute.units!==attr.units){return undefined;}}
+return firstDefinedAttribute;},getInfos:function(attrs){if(attrs.length!==1){var hasDumpInfo=undefined;attrs.some(function(attr){if(attr===undefined)
+return false;return attr.infos.some(function(info){if(info.type!==tr.model.AttributeInfoType.HAS_HEAP_DUMP)
+return false;hasDumpInfo=info;return true;});});if(hasDumpInfo)
+return[hasDumpInfo];else
+return[];}
+return attrs[0].infos;},getImportance:function(importanceRules){if(importanceRules.length===0)
+return 0;for(var i=0;i<importanceRules.length;i++){var importanceRule=importanceRules[i];if(this.matchesNameCondition(importanceRule.condition))
+return importanceRule.importance;}
+var minImportance=importanceRules[0].importance;for(var i=1;i<importanceRules.length;i++){minImportance=Math.min(minImportance,importanceRules[i].importance);}
+return minImportance-1;},matchesNameCondition:function(condition){if(condition===undefined)
+return true;if(typeof(condition)==='string')
+return this.name===condition;return condition.test(this.name);}};function ScalarMemoryColumn(name,title,units,cellGetter,aggregationMode){MemoryColumn.call(this,name,title,units,cellGetter,aggregationMode);}
+ScalarMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleAttributeValue:function(attr){return this.formatUnits(attr.value,false);},formatMultipleAttributeValues:function(attrs){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatUnits(this.getDiffAttrValue(attrs),true);case MemoryColumn.AggregationMode.MAX:return this.formatUnits(this.getMaxAttrValue(attrs),false);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatUnits:function(value,isDelta){if(value===undefined)
+return'';var sizeEl=document.createElement('tr-ui-u-scalar-span');sizeEl.value=value;if(this.units==='bytes')
+sizeEl.unit=tr.b.u.Units.sizeInBytes;else
+sizeEl.unit=tr.b.u.Units.unitlessNumber;if(!isDelta)
+return sizeEl;sizeEl.isDelta=true;if(value===0)
+return sizeEl;var wrapperEl=document.createElement('span');wrapperEl.style.color=value>0?'red':'green';wrapperEl.appendChild(sizeEl);return wrapperEl;},compareSingleAttributes:function(attrA,attrB){return attrA.value-attrB.value;},compareMultipleAttributes:function(attrA,attrB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:var diffA=this.getDiffAttrValue(attrA)||0;var diffB=this.getDiffAttrValue(attrB)||0;return diffA-diffB;case MemoryColumn.AggregationMode.MAX:return this.getMaxAttrValue(attrA)-this.getMaxAttrValue(attrB);default:return 0;}},getDiffAttrValue:function(attrs){var firstAttr=attrs[0];var lastAttr=attrs[attrs.length-1];if(firstAttr===undefined&&lastAttr===undefined)
+return undefined;var firstValue=firstAttr===undefined?0:firstAttr.value;var lastValue=lastAttr===undefined?0:lastAttr.value;return lastValue-firstValue;},getMaxAttrValue:function(attrs){return attrs.reduce(function(accumulator,attr){if(attr===undefined)
+return accumulator;if(accumulator===undefined||attr.value>accumulator)
+accumulator=attr.value;return accumulator;},undefined);}};function MemoryCell(attrs){this.attrs=attrs;}
+MemoryCell.extractAttributes=function(cell){if(cell===undefined)
+return undefined;return cell.attrs;};function fieldGetter(){var fields=tr.b.asArray(arguments);return function(row){var value=row;for(var i=0;i<fields.length;i++)
+value=value[fields[i]];return value;};}
+var RECURSIVE_EXPANSION_MAX_SUB_ROW_COUNT=10;function expandTableRowsRecursively(table){function expandRowRecursively(row){if(row.subRows===undefined||row.subRows.length===0)
+return;if(row.subRows.length>RECURSIVE_EXPANSION_MAX_SUB_ROW_COUNT)
+return;table.setExpandedForTableRow(row,true);row.subRows.forEach(expandRowRecursively);}
+table.tableRows.forEach(expandRowRecursively);}
+function aggregateTableRowCellsRecursively(row,cellKey){var subRows=row.subRows;if(subRows===undefined)
+return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,cellKey);});aggregateTableRowCells(row,subRows,cellKey);}
+function aggregateTableRowCells(row,subRows,cellKey){var rowCells=row[cellKey];if(rowCells===undefined)
+row[cellKey]=rowCells={};var subRowCellNames={};subRows.forEach(function(subRow){var subRowCells=subRow[cellKey];if(subRowCells===undefined)
+return;tr.b.iterItems(subRowCells,function(columnName){subRowCellNames[columnName]=true;});});tr.b.iterItems(subRowCellNames,function(cellName){var existingRowCell=rowCells[cellName];var existingRowAttributes=MemoryCell.extractAttributes(existingRowCell);var timestampCount=undefined;if(existingRowAttributes!==undefined)
+timestampCount=existingRowAttributes.length;subRows.forEach(function(subRow){var subRowCells=subRow[cellKey];if(subRowCells===undefined)
+return;var subRowCellAttributes=MemoryCell.extractAttributes(subRowCells[cellName]);if(subRowCellAttributes===undefined)
+return;if(timestampCount===undefined)
+timestampCount=subRowCellAttributes.length;else if(timestampCount!==subRowCellAttributes.length)
+throw new Error('Rows have different number of timestamps');});if(timestampCount===undefined)
+throw new Error('Handling non-existent cell name \''+cellName+'\'');var aggregatedAttributes=new Array(timestampCount);for(var i=0;i<timestampCount;i++){var existingRowAttribute=undefined;if(existingRowAttributes!==undefined)
+existingRowAttribute=existingRowAttributes[i];var subRowAttributes=subRows.map(function(subRow){var subRowCells=subRow[cellKey];if(subRowCells===undefined)
+return undefined;var subRowCellAttributes=MemoryCell.extractAttributes(subRowCells[cellName]);if(subRowCellAttributes===undefined)
+return;return subRowCellAttributes[i];});aggregatedAttributes[i]=tr.model.Attribute.aggregate(subRowAttributes,existingRowAttribute);}
+if(existingRowCell!==undefined){existingRowCell.attrs=aggregatedAttributes;}else{rowCells[cellName]=new MemoryCell(aggregatedAttributes);}});}
+function createCells(timeToValues,valueAttrsGetter,opt_cellAddedCallback){var attrNameToAttrs=tr.b.invertArrayOfDicts(timeToValues,valueAttrsGetter);return tr.b.mapItems(attrNameToAttrs,function(attrName,attrs){var cell=new tr.ui.analysis.MemoryCell(attrs);if(opt_cellAddedCallback!==undefined)
+opt_cellAddedCallback(attrName,cell);return cell;});}
+function addAttributeIfDefined(dstDict,attrName,attrClass,units,value,opt_addedCallback){if(value===undefined)
+return;var attr=new attrClass(units,value);dstDict[attrName]=attr;if(opt_addedCallback!==undefined)
+opt_addedCallback(attr);}
+return{TitleColumn:TitleColumn,MemoryColumn:MemoryColumn,ScalarMemoryColumn:ScalarMemoryColumn,MemoryCell:MemoryCell,fieldGetter:fieldGetter,expandTableRowsRecursively:expandTableRowsRecursively,aggregateTableRowCellsRecursively:aggregateTableRowCellsRecursively,aggregateTableRowCells:aggregateTableRowCells,createCells:createCells,addAttributeIfDefined:addAttributeIfDefined};});'use strict';Polymer('tr-ui-a-stacked-pane',{rebuild:function(){if(!this.paneDirty_){return;}
+this.paneDirty_=false;this.rebuildPane_();},scheduleRebuildPane_:function(){if(this.paneDirty_)
+return;this.paneDirty_=true;setTimeout(this.rebuild.bind(this),0);},rebuildPane_:function(){},set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended:function(){this.rebuild();}});'use strict';tr.exportTo('tr.ui.analysis',function(){var COLUMN_IMPORTANCE_RULES=tr.ui.analysis.MemoryColumn.columnNamesToImportanceRules(['Total size','Self size']);Polymer('tr-ui-a-memory-dump-heap-details-pane',{created:function(){this.heapDumps_=undefined;this.aggregationMode_=undefined;this.bottomUpView_=false;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.view_mode_container.appendChild(tr.ui.b.createSelector(this,'bottomUpView','memoryDumpHeapDetailsPane.bottomUpView',false,[{label:'Tree (top down)',value:false},{label:'Heavy (bottom up)',value:true}]));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},set bottomUpView(bottomUpView){this.bottomUpView_=bottomUpView;this.scheduleRebuildPane_();},get bottomUpView(){return this.bottomUpView_;},rebuildPane_:function(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.view_mode_container.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';this.$.view_mode_container.style.display='block';var stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);var rows=this.createRows_(stackFrameTrees);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createStackFrameTrees_:function(heapDumps){return heapDumps.map(function(heapDump){if(heapDump===undefined)
+return undefined;var rootNode=new tr.ui.analysis.StackFrameTreeNode(heapDump.allocatorName);var sumSize=undefined;heapDump.entries.forEach(function(entry){var size=entry.size;var leafStackFrame=entry.leafStackFrame;if(leafStackFrame===undefined){if(sumSize!==undefined)
+throw new Error('Multiple sum stack frames');sumSize=size;return;}
+rootNode.addStackTrace(leafStackFrame.stackTrace,size,true);},this);if(sumSize!==undefined&&sumSize>rootNode.total){var unspecifiedSize=sumSize-rootNode.total;rootNode.total=sumSize;var unspecifiedNode=rootNode.getOrCreateChild('<unspecified>');unspecifiedNode.total+=unspecifiedSize;unspecifiedNode.self+=unspecifiedSize;}
+if(this.bottomUpView)
+return rootNode.convertToBottomUpView();else
+return rootNode;},this);},createRows_:function(stackFrameTrees){return[this.createHeapRowRecursively_(stackFrameTrees)];},createHeapRowRecursively_:function(nodes){var title=tr.b.findFirstInArray(nodes).title;var defined=nodes.map(function(node){return node!==undefined;});var cells=tr.ui.analysis.createCells(nodes,function(node){return{'Total size':new tr.model.ScalarAttribute('bytes',node.total),'Self size':new tr.model.ScalarAttribute('bytes',node.self)};});var groupedChildNodes=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(nodes,function(node){return node.children;}));var row={title:title,defined:defined,cells:cells};if(groupedChildNodes.length>0){row.subRows=groupedChildNodes.map(this.createHeapRowRecursively_,this);}
+return row;},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Stack frame');titleColumn.width='500px';var attributeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'cells',this.aggregationMode_);tr.ui.analysis.MemoryColumn.sortByImportance(attributeColumns,COLUMN_IMPORTANCE_RULES);tr.ui.analysis.MemoryColumn.spaceEqually(attributeColumns);var columns=[titleColumn].concat(attributeColumns);return columns;}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var IMPORTANCE_RULES=[{condition:tr.model.MemoryAllocatorDump.SIZE_ATTRIBUTE_NAME,importance:10},{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_ATTRIBUTE_NAME,importance:9},{condition:'page_size',importance:0},{condition:/size/,importance:5},{importance:0}];function AllocatorDumpNameColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
+AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(!row.suballocation)
+return row.title;return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullName});}};Polymer('tr-ui-a-memory-dump-allocator-details-pane',{created:function(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuildPane_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuildPane_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){var pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_:function(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_:function(dumps){var definedDump=tr.b.findFirstInArray(dumps);var title=definedDump.name;var fullName=definedDump.fullName;var defined=dumps.map(function(dump){return dump!==undefined;});var cells=tr.ui.analysis.createCells(dumps,function(dump){return dump.attributes;});var suballocatedBy=undefined;if(title.startsWith('__')){for(var i=0;i<dumps.length;i++){var dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
+var ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
+if(suballocatedBy===undefined){suballocatedBy=ownerDump.fullName;}else if(suballocatedBy!==ownerDump.fullName){suballocatedBy=undefined;break;}}}
+var row={title:title,fullName:fullName,defined:defined,cells:cells,suballocatedBy:suballocatedBy};var childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){return tr.b.arrayToDict(dump.children,function(child){return child.name;});});var subRows=[];var suballocationClassificationRootNode=undefined;tr.b.iterItems(childDumpNameToDumps,function(childName,childDumps){var childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}},this);if(suballocationClassificationRootNode!==undefined){var suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);tr.ui.analysis.aggregateTableRowCellsRecursively(suballocationRow,'cells');subRows.push(suballocationRow);}
+if(subRows.length>0)
+row.subRows=subRows;return row;},classifySuballocationRow_:function(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
+var suballocationLevels=suballocationRow.suballocatedBy.split('/');var currentNode=rootNode;for(var i=0;i<suballocationLevels.length;i++){var suballocationLevel=suballocationLevels[i];var nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
+var currentNode=nextNode;}
+if(currentNode.row!==undefined)
+throw new Error('Multiple suballocations with the same owner name');currentNode.row=suballocationRow;return rootNode;},createSuballocationRowRecursively_:function(name,node){var childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined)
+throw new Error('Suballocation node must have a row or children');var row=node.row;row.title=name;row.suballocation=true;return row;}
+var subRows=tr.b.dictionaryValues(tr.b.mapItems(node.children,this.createSuballocationRowRecursively_,this));if(node.row!==undefined){var row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
+var defined=new Array(subRows[0].defined.length);for(var i=0;i<subRows.length;i++){subRows[i].defined.forEach(function(definedValue,index){defined[index]=defined[index]||definedValue;});}
+return{title:name,suballocation:true,defined:defined,cells:{},subRows:subRows};},createColumns_:function(rows){var titleColumn=new AllocatorDumpNameColumn('Component');titleColumn.width='200px';var attributeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'cells',this.aggregationMode_);tr.ui.analysis.MemoryColumn.spaceEqually(attributeColumns);tr.ui.analysis.MemoryColumn.sortByImportance(attributeColumns,IMPORTANCE_RULES);var columns=[titleColumn].concat(attributeColumns);return columns;}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var COLUMN_IMPORTANCE_RULES=tr.ui.analysis.MemoryColumn.columnNamesToImportanceRules(['Start address','Virtual size','Protection flags','PSS','Private dirty','Private clean','Shared dirty','Shared clean','Swapped']);var CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(arg))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};function createEmptyRuleRow(rule){var row={title:rule.name,rule:rule,subRows:[]};if(rule.children!==undefined)
+row.subRows=rule.children.map(createEmptyRuleRow);return row;}
+function hexString(address,is64BitAddress){if(address===undefined)
+return undefined;var hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
+function classifyRegionRow(ruleRow,regionRow){var rule=ruleRow.rule;if(rule===undefined||rule.children===undefined||rule.children.length===0){ruleRow.subRows.push(regionRow);return;}
+function regionRowMatchesChildRule(childRule){var fileRegExp=childRule.file;if(fileRegExp===undefined)
+return true;return fileRegExp.test(regionRow.title);}
+var matchedChildRuleIndex=tr.b.findFirstIndexInArray(rule.children,regionRowMatchesChildRule);if(matchedChildRuleIndex===-1){matchedChildRuleIndex=rule.children.length;if(matchedChildRuleIndex>=ruleRow.subRows.length){ruleRow.subRows.push({title:'Other',subRows:[]});}}
+classifyRegionRow(ruleRow.subRows[matchedChildRuleIndex],regionRow);}
+function pruneEmptyRuleRows(row){if(row.subRows===undefined||row.subRows.length===0)
+return;if(row.subRows[0].rule===undefined){return;}
+row.subRows.forEach(pruneEmptyRuleRows);row.subRows=row.subRows.filter(function(subRow){return subRow.subRows.length>0;});}
+Polymer('tr-ui-a-memory-dump-vm-regions-details-pane',{created:function(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuildPane_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){var unclassifiedRows=[];if(this.vmRegions_!==undefined)
+unclassifiedRows=this.createUnclassifiedRows_(this.vmRegions_);if(unclassifiedRows.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.classifyRows_(unclassifiedRows);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},joinRegions_:function(timeToRegionIdToRegion){return tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToRegionIdToRegion,function(regionIdToRegion){return tr.b.arrayToDict(regionIdToRegion,function(region){return[region.mappedFile,region.startAddress].join('#');});}));},createUnclassifiedRows_:function(timeToRegionIdToRegion){var is64BitAddress=timeToRegionIdToRegion.some(function(regionIdToRegion){if(regionIdToRegion===undefined)
+return false;return regionIdToRegion.some(function(region){if(region.startAddress===undefined)
+return false;return region.startAddress>=4294967296;});});var regionIdToTimeToRegion=this.joinRegions_(timeToRegionIdToRegion);return regionIdToTimeToRegion.map(function(timeToRegion){var definedRegion=tr.b.findFirstInArray(timeToRegion);var defined=timeToRegion.map(function(region){return region!==undefined;});var constantCells=tr.ui.analysis.createCells([definedRegion],function(region){var attrs={};tr.ui.analysis.addAttributeIfDefined(attrs,'Start address',tr.model.StringAttribute,'',hexString(region.startAddress,is64BitAddress));return attrs;});var variableCells=tr.ui.analysis.createCells(timeToRegion,function(region){var attrs={};tr.ui.analysis.addAttributeIfDefined(attrs,'Virtual size',tr.model.ScalarAttribute,'bytes',region.sizeInBytes);tr.ui.analysis.addAttributeIfDefined(attrs,'Protection flags',tr.model.StringAttribute,'',region.protectionFlagsToString);tr.ui.analysis.addAttributeIfDefined(attrs,'PSS',tr.model.ScalarAttribute,'bytes',region.byteStats.proportionalResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Private dirty',tr.model.ScalarAttribute,'bytes',region.byteStats.privateDirtyResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Private clean',tr.model.ScalarAttribute,'bytes',region.byteStats.privateCleanResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Shared dirty',tr.model.ScalarAttribute,'bytes',region.byteStats.sharedDirtyResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Shared clean',tr.model.ScalarAttribute,'bytes',region.byteStats.sharedCleanResident);tr.ui.analysis.addAttributeIfDefined(attrs,'Swapped',tr.model.ScalarAttribute,'bytes',region.byteStats.swapped);return attrs;});return{title:definedRegion.mappedFile||'',defined:defined,constantCells:constantCells,variableCells:variableCells};});},classifyRows_:function(unclassifiedRows){var rootRow=createEmptyRuleRow(CLASSIFICATION_RULES);unclassifiedRows.map(classifyRegionRow.bind(undefined,rootRow));pruneEmptyRuleRows(rootRow);tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,'constantCells');tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,'variableCells');return[rootRow];},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';var constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'constantCells');var variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'variableCells',this.aggregationMode_);var attributeColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.sortByImportance(attributeColumns,COLUMN_IMPORTANCE_RULES);tr.ui.analysis.MemoryColumn.spaceEqually(attributeColumns);var columns=[titleColumn].concat(attributeColumns);return columns;}});return{};});'use strict';Polymer('tr-ui-b-color-legend',{ready:function(){var blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
+var colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId:function(label,colorId){this.label_=label;this.$.label.textContent='';this.$.label.appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined)
+this.$.square.style.color='initial';else
+this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}});'use strict';Polymer('tr-ui-b-view-specific-brushing-state',{get viewId(){return this.getAttribute('view-id');},set viewId(viewId){this.setAttribute('view-id',viewId);},get:function(){var viewId=this.viewId;if(!viewId)
+throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
+return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set:function(state){var viewId=this.viewId;if(!viewId)
+throw new Error('Element must have a view-id attribute!');var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)
+return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ColorScheme=tr.b.ColorScheme;var USED_MEMORY_SIZE_COLUMNS_IMPORTANCE_RULES=tr.ui.analysis.MemoryColumn.columnNamesToImportanceRules(['Total resident','Peak total resident','PSS','Private dirty','Swapped']);var ALLOCATOR_SIZE_COLUMNS_IMPORTANCE_RULES=[{condition:'tracing',importance:0},{importance:1}];var DISPLAYED_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_ATTRIBUTE_NAME;var LINK_SYMBOL=String.fromCharCode(9903);var GREATER_THAN_OR_EQUAL_TO_SYMBOL=String.fromCharCode(8805);function ProcessNameColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
+ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(row.noLegend)
+return row.title;var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};Polymer('tr-ui-a-memory-dump-overview-pane',{created:function(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuildPane_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)
+return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)
+return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];var selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_:function(){this.storeSelection_();var builder=undefined;if(this.selectedMemoryCell!==undefined)
+builder=this.selectedMemoryCell.buildDetailsPane;this.childPaneBuilder=builder;},rebuildPane_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var footerRows=this.createFooterRows_(rows);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_:function(){var timeToPidToProcessMemoryDump=this.processMemoryDumps_;var pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);var rows=[];var aggregationMode=this.aggregationMode_;return tr.b.dictionaryValues(tr.b.mapItems(pidToTimeToProcessMemoryDump,function(pid,timeToDump){var process=tr.b.findFirstInArray(timeToDump).process;var defined=timeToDump.map(function(dump){return dump!==undefined;});var timeToVmRegions=timeToDump.map(function(dump){if(dump===undefined)
+return undefined;return dump.mostRecentVmRegions;});function buildVmRegionsPane(){var pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=timeToVmRegions;pane.aggregationMode=aggregationMode;return pane;}
+var usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){var sizes={};if(dump.totals!==undefined){tr.ui.analysis.addAttributeIfDefined(sizes,'Total resident',tr.model.ScalarAttribute,'bytes',dump.totals.residentBytes);tr.ui.analysis.addAttributeIfDefined(sizes,'Peak total resident',tr.model.ScalarAttribute,'bytes',dump.totals.peakResidentBytes,function(attr){if(dump.totals.arePeakResidentBytesResettable){attr.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.RECENT_VALUE,'Peak RSS since previous memory dump.'));}else{attr.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.OVERALL_VALUE,'Peak RSS since process startup. Finer grained '+'peaks require a Linux kernel version '+
+GREATER_THAN_OR_EQUAL_TO_SYMBOL+' 4.0.'));}});}
+var vmRegionAttributeAddedCallback=undefined;if(!dump.hasOwnVmRegions){vmRegionAttributeAddedCallback=function(attr){attr.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.LINK,'Older value (process did not dump memory maps).'));attr.isOlderValue=true;};}
+tr.ui.analysis.addAttributeIfDefined(sizes,'PSS',tr.model.ScalarAttribute,'bytes',dump.getMostRecentTotalVmRegionStat('proportionalResident'),vmRegionAttributeAddedCallback);tr.ui.analysis.addAttributeIfDefined(sizes,'Private dirty',tr.model.ScalarAttribute,'bytes',dump.getMostRecentTotalVmRegionStat('privateDirtyResident'),vmRegionAttributeAddedCallback);tr.ui.analysis.addAttributeIfDefined(sizes,'Swapped',tr.model.ScalarAttribute,'bytes',dump.getMostRecentTotalVmRegionStat('swapped'),vmRegionAttributeAddedCallback);return sizes;},function(attrName,cell){cell.buildDetailsPane=buildVmRegionsPane;});var allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){if(dump.memoryAllocatorDumps===undefined)
+return undefined;var sizes={};dump.memoryAllocatorDumps.forEach(function(allocatorDump){var rootAttribute=allocatorDump.attributes[DISPLAYED_SIZE_ATTRIBUTE_NAME];if(rootAttribute===undefined)
+return;var allocatorName=allocatorDump.fullName;var overviewAttribute=new rootAttribute.constructor(rootAttribute.units,rootAttribute.value);if(dump.heapDumps!==undefined&&dump.heapDumps[allocatorName]!==undefined){overviewAttribute.infos.push(new tr.model.AttributeInfo(tr.model.AttributeInfoType.HAS_HEAP_DUMP,'Heap dump provided'));}
+sizes[allocatorName]=overviewAttribute;});return sizes;},function(allocatorName,cell){var memoryAllocatorDumps=timeToDump.map(function(dump){if(dump===undefined)
+return undefined;return dump.getMemoryAllocatorDumpByFullName(allocatorName);});var heapDumps=undefined;timeToDump.forEach(function(dump,index){if(dump===undefined||dump.heapDumps===undefined)
+return;if(heapDumps===undefined)
+heapDumps=new Array(timeToDump.length);heapDumps[index]=dump.heapDumps[allocatorName];});cell.buildDetailsPane=function(){var pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=aggregationMode;return pane;};});return{title:process.userFriendlyName,defined:defined,usedMemoryCells:usedMemoryCells,allocatorCells:allocatorCells};}));},createFooterRows_:function(rows){if(rows.length<=1)
+return[];var totalRow={title:'Total',noLegend:true};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,'usedMemoryCells');tr.ui.analysis.aggregateTableRowCells(totalRow,rows,'allocatorCells');return[totalRow];},createColumns_:function(rows){var titleColumn=new ProcessNameColumn('Process');titleColumn.width='200px';var usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'usedMemoryCells',this.aggregationMode_);tr.ui.analysis.MemoryColumn.sortByImportance(usedMemorySizeColumns,USED_MEMORY_SIZE_COLUMNS_IMPORTANCE_RULES);var allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,'allocatorCells',this.aggregationMode_,function(allocatorName){var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=allocatorName;return titleEl;});tr.ui.analysis.MemoryColumn.sortByImportance(allocatorSizeColumns,ALLOCATOR_SIZE_COLUMNS_IMPORTANCE_RULES);var tracingColumn=tr.b.findFirstInArray(allocatorSizeColumns,function(column){return column.name==='tracing';});if(tracingColumn!==undefined){var tracingColumnColor=ColorScheme.getColorForReservedNameAsString('tracing_memory_column');tracingColumn.title=tr.ui.b.createSpan({textContent:'tracing',color:tracingColumnColor});tracingColumn.color=tracingColumnColor;}
+usedMemorySizeColumns.forEach(function(column){var olderUsedMCC=ColorScheme.getColorForReservedNameAsString('older_used_memory_column');var usedMCC=ColorScheme.getColorForReservedNameAsString('used_memory_column');column.title=tr.ui.b.createSpan({textContent:column.title,color:usedMCC});column.color=function(attrs){return attrs.length===1&&attrs[0].isOlderValue?olderUsedMCC:usedMCC;}});var sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);var columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_:function(){var selectedRowTitle;var selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined)
+selectedRowTitle=selectedRow.title;var selectedColumnName;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
+this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_:function(){var settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined)
+return;var selectedColumnName=settings.columnName;var selectedColumnIndex=tr.b.findFirstIndexInArray(this.$.table.tableColumns,function(column){return column.name===selectedColumnName;});if(selectedColumnIndex<0)
+return;var selectedRowTitle=settings.rowTitle;var selectedRow=tr.b.findFirstInArray(this.$.table.tableRows,function(row){return row.title===selectedRowTitle;});if(selectedRow===undefined)
+return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-memory-dump-header-pane',{created:function(){this.containerMemoryDumps_=undefined;},ready:function(){this.$.aggregation_mode_container.appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuildPane_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuildPane_();},get aggregationMode(){return this.aggregationMode_;},rebuildPane_:function(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_:function(){this.$.label.textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){this.$.label.textContent='No memory dumps selected';return;}
+var containerDumpCount=this.containerMemoryDumps_.length;var isMultiSelection=containerDumpCount>1;this.$.label.appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
+(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));this.$.label.appendChild(document.createTextNode(tr.b.u.TimeStamp.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){var ELLIPSIS=String.fromCharCode(8230);this.$.label.appendChild(document.createTextNode(ELLIPSIS));this.$.label.appendChild(document.createTextNode(tr.b.u.TimeStamp.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_:function(){var displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1)
+displayStyle='none';else
+displayStyle='initial';this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_:function(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0)
+return undefined;var overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer('tr-ui-a-stacked-pane-view',{setPaneBuilder:function(paneBuilder,opt_parentPane){var paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement))
+throw new Error('Parent pane must be an HTML element');if(opt_parentPane.parentElement!==paneContainer)
+throw new Error('Parent pane must be a child of the pane container');}
+while(paneContainer.lastElementChild!==null&&paneContainer.lastElementChild!==opt_parentPane){var removedPane=this.$.pane_container.lastElementChild;var listener=this.listeners_.get(removedPane);if(listener===undefined)
+throw new Error('No listener associated with pane');this.listeners_.delete(removedPane);removedPane.removeEventListener('request-child-pane-change',listener);paneContainer.removeChild(removedPane);}
+if(opt_parentPane&&opt_parentPane.parentElement!==paneContainer)
+throw new Error('Parent pane was removed from the pane container');if(!paneBuilder)
+return;var pane=paneBuilder();if(!pane)
+return;if(!(pane instanceof HTMLElement))
+throw new Error('Pane must be an HTML element');var listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
+this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);paneContainer.appendChild(pane);pane.appended();},rebuild:function(){var currentPane=this.$.pane_container.firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){var panes=[];var currentChild=this.$.pane_container.firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
+return panes;}});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer('tr-ui-a-container-memory-dump-sub-view',{set selection(selection){if(selection===undefined){this.currentSelection_=undefined;this.dumpsByContainerName_=undefined;this.updateContents_();return;}
+selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.group(this.currentSelection_.toArray(),function(dump){return dump.containerName;});tr.b.iterItems(this.dumpsByContainerName_,function(containerName,dumps){dumps.sort(function(a,b){return a.start-b.start;});});this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_:function(){this.$.content.textContent='';if(this.dumpsByContainerName_===undefined)
+return;var containerNames=Object.keys(this.dumpsByContainerName_);if(containerNames.length===0)
+return;if(containerNames.length>1)
+this.buildViewForMultipleContainerNames_();else
+this.buildViewForSingleContainerName_();},buildViewForSingleContainerName_:function(){var containerMemoryDumps=this.currentSelection_;var dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');this.$.content.appendChild(dumpView);dumpView.setPaneBuilder(function(){var headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_:function(){var ownerDocument=this.ownerDocument;var rows=tr.b.dictionaryValues(tr.b.mapItems(this.dumpsByContainerName_,function(containerName,dumps){return{containerName:containerName,subRows:dumps,isExpanded:true};}));rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});var columns=[{title:'Dump',value:function(row){if(row.subRows===undefined)
+return this.singleDumpValue_(row);else
+return this.groupedDumpValue_(row);},singleDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));linkEl.appendChild(tr.ui.units.createTimeStampSpan(row.start,{ownerDocument:ownerDocument}));return linkEl;},groupedDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.subRows.length+' memory dump'+
+(row.subRows.length===1?'':'s')+' in '}));linkEl.appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();this.$.content.appendChild(table);}});return{};});'use strict';var EventSet=tr.model.EventSet;Polymer('tr-ui-a-power-sample-table',{ready:function(){this.$.table.tableColumns=[{title:'Time',width:'100px',value:function(row){return tr.ui.units.createTimeStampSpan(row.start);}},{title:'Power (mW)',width:'100%',value:function(row){return row.power;}}];this.samples=new EventSet();},get samples(){return this.samples_;},set samples(samples){this.samples_=(samples===undefined)?new EventSet():samples;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.samples.toArray();this.$.table.rebuild();}});'use strict';Polymer('tr-ui-a-single-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.samplesTable.samples=this.selection;}});!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var svgNS='http://www.w3.org/2000/svg';var ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){var id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected)
+id+=ColorScheme.properties.brightenedOffsets[0];return ColorScheme.colorsAsStrings[id];}
+var ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.classList.add('chart-base');this.chartTitle_=undefined;this.seriesKeys_=undefined;this.width_=400;this.height_=300;var template=THIS_DOC.querySelector('#chart-base-template');var svgEl=template.content.querySelector('svg');for(var i=0;i<svgEl.children.length;i++)
+this.appendChild(svgEl.children[i].cloneNode(true));Object.defineProperty(this,'width',{get:function(){return this.width_;},set:function(width){this.width_=width;this.updateContents_();}});Object.defineProperty(this,'height',{get:function(){return this.height_;},set:function(height){this.height_=height;this.updateContents_();}});},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return this.querySelector('#chart-area');},setSize:function(size){this.width_=size.width;this.height_=size.height;this.updateContents_();},getMargin_:function(){var margin={top:20,right:20,bottom:30,left:50};if(this.chartTitle_)
+margin.top+=20;return margin;},get margin(){return this.getMargin_();},get chartAreaSize(){var margin=this.margin;return{width:this.width_-margin.left-margin.right,height:this.height_-margin.top-margin.bottom};},getLegendKeys_:function(){throw new Error('Not implemented');},updateScales_:function(){throw new Error('Not implemented');},updateContents_:function(){var margin=this.margin;var thisSel=d3.select(this);thisSel.attr('width',this.width_);thisSel.attr('height',this.height_);var chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.attr('transform','translate('+margin.left+','+margin.top+')');this.updateScales_();this.updateTitle_(chartAreaSel);this.updateLegend_();},updateTitle_:function(chartAreaSel){var titleSel=chartAreaSel.select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
+var width=this.chartAreaSize.width;titleSel.attr('transform','translate('+width*0.5+',-5)').style('display',undefined).style('text-anchor','middle').attr('class','title').attr('width',width).text(this.chartTitle_);},updateLegend_:function(){var keys=this.getLegendKeys_();if(keys===undefined)
+return;var chartAreaSel=d3.select(this.chartAreaElement);var chartAreaSize=this.chartAreaSize;var legendEntriesSel=chartAreaSel.selectAll('.legend').data(keys.slice().reverse());legendEntriesSel.enter().append('g').attr('class','legend').attr('transform',function(d,i){return'translate(0,'+i*20+')';}).append('text').text(function(key){return key;});legendEntriesSel.exit().remove();legendEntriesSel.attr('x',chartAreaSize.width-18).attr('width',18).attr('height',18).style('fill',function(key){var selected=this.currentHighlightedLegendKey===key;return getColorOfKey(key,selected);}.bind(this));legendEntriesSel.selectAll('text').attr('x',chartAreaSize.width-24).attr('y',9).attr('dy','.35em').style('text-anchor','end').text(function(d){return d;});},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_)
+return this.tempHighlightedLegendKey_;return this.highlightedLegendKey_;},pushTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_)
+throw new Error('push cannot nest');this.tempHighlightedLegendKey_=key;this.updateHighlight_();},popTempHighlightedLegendKey:function(key){if(this.tempHighlightedLegendKey_!=key)
+throw new Error('pop cannot happen');this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_:function(){var chartAreaSel=d3.select(this.chartAreaElement);var legendEntriesSel=chartAreaSel.selectAll('.legend');var that=this;legendEntriesSel.each(function(key){var highlighted=key==that.currentHighlightedLegendKey;var color=getColorOfKey(key,highlighted);this.style.fill=color;if(highlighted)
+this.style.fontWeight='bold';else
+this.style.fontWeight='';});}};return{getColorOfKey:getColorOfKey,ChartBase:ChartBase};});'use strict';tr.exportTo('tr.ui.b',function(){function MouseTracker(opt_targetElement){this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.targetElement=opt_targetElement;}
+MouseTracker.prototype={get targetElement(){return this.targetElement_;},set targetElement(targetElement){if(this.targetElement_)
+this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=targetElement;if(this.targetElement_)
+this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},onMouseDown_:function(e){if(e.button!==0)
+return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_:function(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_:function(e,newType){var remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
+document.removeEventListener('keyup',opt_keyUpHandler);document.removeEventListener('mouseup',cleanupAndDispatchToMouseUp);if(opt_mouseUpHandler)
+opt_mouseUpHandler(e);}
+document.addEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler)
+document.addEventListener('keyup',opt_keyUpHandler);document.addEventListener('mouseup',cleanupAndDispatchToMouseUp);}
+return{MouseTracker:MouseTracker,trackMouseMovesUntilMouseUp:trackMouseMovesUntilMouseUp};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var ChartBase2D=tr.ui.b.define('chart-base-2d',ChartBase);ChartBase2D.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.data_=[];this.seriesKeys_=[];this.leftMargin_=50;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get data(){return this.data_;},set data(data){if(data===undefined)
+throw new Error('data must be an Array');this.data_=data;this.updateSeriesKeys_();this.updateContents_();},getSampleWidth_:function(data,index,leftSide){var leftIndex,rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
+var leftWidth=this.getXForDatum_(data[index],index)-
+this.getXForDatum_(data[leftIndex],leftIndex);var rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
+this.getXForDatum_(data[index],index);return leftWidth*0.5+rightWidth*0.5;},getLegendKeys_:function(){if(this.seriesKeys_&&this.seriesKeys_.length>1)
+return this.seriesKeys_.slice();return[];},updateSeriesKeys_:function(){var keySet={};this.data_.forEach(function(datum){Object.keys(datum).forEach(function(key){if(this.isDatumFieldSeries_(key))
+keySet[key]=true;},this);},this);this.seriesKeys_=Object.keys(keySet);},isDatumFieldSeries_:function(fieldName){throw new Error('Not implemented');},getXForDatum_:function(datum,index){throw new Error('Not implemented');},updateScales_:function(){if(this.data_.length===0)
+return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;this.xScale_.range([0,width]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));var yRange=new tr.b.Range();this.data_.forEach(function(datum){this.seriesKeys_.forEach(function(key){if(datum[key]!==undefined)
+yRange.addValue(datum[key]);});},this);this.yScale_.range([height,0]);this.yScale_.domain([yRange.min,yRange.max]);},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();},updateXAxis_:function(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;xAxis.attr('transform','translate(0,'+this.chartAreaSize.height+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));window.requestAnimationFrame(function(){var previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){var currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){var currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});xAxis[0][0].style.opacity=1;});},getMargin_:function(){var margin=ChartBase.prototype.getMargin_.call(this);margin.left=this.leftMargin_;return margin;},updateYAxis_:function(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;yAxis.call(d3.svg.axis().scale(this.yScale_).orient('left'));window.requestAnimationFrame(function(){var previousTop=undefined;var leftMargin=0;yAxis.selectAll('.tick')[0].forEach(function(tick){var bbox=tick.getBBox();leftMargin=Math.max(leftMargin,bbox.width);var currentTop=tick.transform.baseVal[0].matrix.f;var currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});if(leftMargin>this.leftMargin_){this.leftMargin_=leftMargin;this.updateContents_();}else{yAxis[0][0].style.opacity=1;}}.bind(this));},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);var chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_:function(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_:function(){var dataBySeriesKey={};this.seriesKeys_.forEach(function(seriesKey){dataBySeriesKey[seriesKey]=[];});this.data_.forEach(function(multiSeriesDatum,index){var x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')
+return;if(multiSeriesDatum[seriesKey]===undefined)
+return;var singleSeriesDatum={x:x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);});},this);return dataBySeriesKey;},getDataPointAtClientPoint_:function(clientX,clientY){var rect=this.getBoundingClientRect();var margin=this.margin;var x=clientX-rect.left-margin.left;var y=clientY-rect.top-margin.top;x=this.xScale_.invert(x);y=this.yScale_.invert(y);x=tr.b.clamp(x,this.xScale_.domain()[0],this.xScale_.domain()[1]);y=tr.b.clamp(y,this.yScale_.domain()[0],this.yScale_.domain()[1]);return{x:x,y:y};},prepareDataEvent_:function(mouseEvent,dataEvent){var dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_:function(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;this.classList.add('updating-brushing-state');this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseMove_:function(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
+var dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseUp_:function(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);this.classList.remove('updating-brushing-state');}};return{ChartBase2D:ChartBase2D};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2D=tr.ui.b.ChartBase2D;var ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate:function(){ChartBase2D.prototype.decorate.call(this);this.brushedRange_=new tr.b.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},computeBrushRangeFromIndices:function(indexA,indexB){indexA=tr.b.clamp(indexA,0,this.data_.length-1);indexB=tr.b.clamp(indexB,0,this.data_.length-1);var leftIndex=Math.min(indexA,indexB);var rightIndex=Math.max(indexA,indexB);var r=new tr.b.Range();r.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
+this.getSampleWidth_(this.data_,leftIndex,true));r.addValue(this.getXForDatum_(this.data_[rightIndex],rightIndex)+
+this.getSampleWidth_(this.data_,rightIndex,false));return r;},getDataIndex_:function(dataX){if(!this.data_)
+return undefined;var bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_:function(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined)
+dataEvent.data=this.data_[dataEvent.index];},updateBrushContents_:function(brushSel){brushSel.selectAll('*').remove();var brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];var brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();brushRectsSel.attr('x',function(d){return this.xScale_(d.min);}.bind(this)).attr('y',0).attr('width',function(d){return this.xScale_(d.max)-this.xScale_(d.min);}.bind(this)).attr('height',this.chartAreaSize.height);}};return{ChartBase2DBrushX:ChartBase2DBrushX};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2DBrushX=tr.ui.b.ChartBase2DBrushX;var LineChart=tr.ui.b.define('line-chart',ChartBase2DBrushX);LineChart.prototype={__proto__:ChartBase2DBrushX.prototype,decorate:function(){ChartBase2DBrushX.prototype.decorate.call(this);this.classList.add('line-chart');},isDatumFieldSeries_:function(fieldName){return fieldName!='x';},getXForDatum_:function(datum,index){return datum.x;},updateDataContents_:function(dataSel){dataSel.selectAll('*').remove();var dataBySeriesKey=this.getDataBySeriesKey_();var pathsSel=dataSel.selectAll('path').data(this.seriesKeys_);pathsSel.enter().append('path').attr('class','line').style('stroke',function(key){return tr.ui.b.getColorOfKey(key);}).attr('d',function(key){var line=d3.svg.line().x(function(d){return this.xScale_(d.x);}.bind(this)).y(function(d){return this.yScale_(d[key]);}.bind(this));return line(dataBySeriesKey[key]);}.bind(this));pathsSel.exit().remove();}};return{LineChart:LineChart};});'use strict';var EventSet=tr.model.EventSet;var CHART_TITLE='Power (in mW) by ms since vertical sync';var CHART_WIDTH_FRACTION_OF_BODY=0.5;Polymer('tr-ui-a-frame-power-usage-chart',{ready:function(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData:function(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;this.updateContents_();},updateContents_:function(){this.clearChart_();var data=this.getDataForLineChart_();if(data.length===0)
+return;this.chart_=this.createChart_(data);this.$.content.appendChild(this.chart_);},createChart_:function(data){var chart=new tr.ui.b.LineChart();var width=document.body.clientWidth*CHART_WIDTH_FRACTION_OF_BODY;chart.setSize({width:width,height:chart.height});chart.chartTitle=CHART_TITLE;chart.data=data;return chart;},clearChart_:function(){var content=this.$.content;while(content.firstChild)
+content.removeChild(content.firstChild);this.chart_=undefined;},getDataForLineChart_:function(){var sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);var vSyncTimestamps=this.vSyncTimestamps.slice();var lastVSyncTimestamp=undefined;var points=[];var frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
+if(lastVSyncTimestamp===undefined)
+return;var point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.power;points.push(point);});return points;},sortSamplesByTimestampAscending_:function(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer('tr-ui-a-power-sample-summary-table',{ready:function(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value:function(row){return tr.b.u.Units.powerInWatts.format(row.min/1000.0);}},{title:'Max power',width:'100px',value:function(row){return tr.b.u.Units.powerInWatts.format(row.max/1000.0);}},{title:'Time-weighted average',width:'100px',value:function(row){return tr.b.u.Units.powerInWatts.format(row.timeWeightedAverage/1000.0);}},{title:'Energy consumed',width:'100px',value:function(row){return tr.b.u.Units.energyInJoules.format(row.energyConsumed);}},{title:'Sample count',width:'100%',value:function(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)
+return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_:function(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverage:this.getTimeWeightedAverage(),energyConsumed:this.getEnergyConsumed(),sampleCount:this.samples.length}];}
+this.$.table.rebuild();},getMin:function(){return Math.min.apply(null,this.samples.map(function(sample){return sample.power;}));},getMax:function(){return Math.max.apply(null,this.samples.map(function(sample){return sample.power;}));},getTimeWeightedAverage:function(){var energyConsumed=this.getEnergyConsumed();if(energyConsumed==='N/A')
+return'N/A';return this.getEnergyConsumed()/this.samples.bounds.duration*1000;},getEnergyConsumed:function(){if(this.samples.length<2)
+return'N/A';var bounds=this.samples.bounds;return this.samples[0].series.getEnergyConsumed(bounds.min,bounds.max);}});'use strict';Polymer('tr-ui-a-multi-power-sample-sub-view',{ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){var samples=this.selection;var vSyncTimestamps=(this.selection===undefined)?[]:this.selection[0].series.device.vSyncTimestamps;this.$.summaryTable.samples=samples;this.$.samplesTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});'use strict';(function(){var EventRegistry=tr.model.EventRegistry;Polymer('tr-ui-a-analysis-view',{ready:function(){this.tabView_=document.createElement('tr-ui-a-tab-view');this.tabView_.style.flex='1 1 auto';this.appendChild(this.tabView_);this.brushingStateController_=undefined;this.onSelectedTabChange_=this.onSelectedTabChange_.bind(this);this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.lastSeenSelection_=new tr.model.EventSet();},set tallMode(value){if(value)
+this.classList.add('tall-mode');else
+this.classList.remove('tall-mode');},get tallMode(){return this.classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}
+this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(e){var selection=this.brushingStateController_.selection;var selectionHasSameValue=this.lastSeenSelection_.equals(selection);this.lastSeenSelection_=selection;if(selectionHasSameValue)
+return;var lastSelectedTabTagName;var lastSelectedTabTypeName;if(this.tabView_.selectedTab){lastSelectedTabTagName=this.tabView_.selectedTab.tagName;lastSelectedTabTypeName=this.tabView_.selectedTab._eventTypeName;}
+this.tallMode=false;var previouslySelectedTab=this.tabView_.selectedTab;this.tabView_.removeEventListener('selected-tab-change',this.onSelectedTabChange_);var previousSubViews={};for(var i=0;i<this.tabView_.children.length;i++){var previousSubView=this.tabView_.children[i];previousSubViews[previousSubView._eventTypeName]=previousSubView;}
+this.tabView_.saveTabStates();this.tabView_.textContent='';if(selection.length==0){this.tabView_.tabStripHeadingText='Nothing selected. Tap stuff.';}else if(selection.length==1){this.tabView_.tabStripHeadingText='1 item selected: ';}else{this.tabView_.tabStripHeadingText=selection.length+' items selected: ';}
+var eventsByBaseTypeName=selection.getEventsOrganizedByBaseType(true);var numBaseTypesToAnalyze=tr.b.dictionaryLength(eventsByBaseTypeName);for(var eventTypeName in eventsByBaseTypeName){var subSelection=eventsByBaseTypeName[eventTypeName];var subView=this.createSubViewForSelection_(eventTypeName,subSelection,previousSubViews[eventTypeName]);subView._eventTypeName=eventTypeName;this.tabView_.appendChild(subView);subView.selection=subSelection;}
+var tab;if(lastSelectedTabTagName)
+tab=this.tabView_.querySelector(lastSelectedTabTagName);if(!tab&&lastSelectedTabTypeName){var tab=tr.b.findFirstInArray(this.tabView_.children,function(tab){return tab._eventTypeName===lastSelectedTabTypeName;});}
+if(!tab)
+tab=this.tabView_.firstChild;this.tabView_.selectedTab=tab;this.onSelectedTabChange_();this.tabView_.addEventListener('selected-tab-change',this.onSelectedTabChange_);},createSubViewForSelection_:function(eventTypeName,subSelection,previousSubView){var eventTypeInfo=EventRegistry.getEventTypeInfoByTypeName(eventTypeName);var singleMode=subSelection.length==1;var tagName;if(subSelection.length===1)
+tagName=eventTypeInfo.metadata.singleViewElementName;else
+tagName=eventTypeInfo.metadata.multiViewElementName;if(!tr.ui.b.getPolymerElementNamed(tagName))
+throw new Error('Element not registered: '+tagName);var subView;if(previousSubView&&previousSubView.tagName===tagName.toUpperCase())
+subView=previousSubView;else
+subView=document.createElement(tagName);var camelLabel;if(subSelection.length===1)
+camelLabel=EventRegistry.getUserFriendlySingularName(eventTypeName);else
+camelLabel=EventRegistry.getUserFriendlyPluralName(eventTypeName);subView.tabLabel=camelLabel+' ('+subSelection.length+')';return subView;},onSelectedTabChange_:function(){var brushingStateController=this.brushingStateController_;if(this.tabView_.selectedTab){var selectedTab=this.tabView_.selectedTab;this.tallMode=selectedTab.requiresTallView;if(brushingStateController){var rlth=selectedTab.relatedEventsToHighlight;brushingStateController.changeAnalysisViewRelatedEvents(rlth);}}else{this.tallMode=false;if(brushingStateController)
+brushingStateController.changeAnalysisViewRelatedEvents(undefined);}}});})();'use strict';tr.exportTo('tr.ui.b',function(){var DragHandle=tr.ui.b.define('x-drag-handle');DragHandle.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};},get modeKey_(){return this.target_.className==''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)
+return;this.observer_.observe(this.target_,{attributes:true,attributeFilter:['class']});},get horizontal(){return this.horizontal_;},set horizontal(h){this.horizontal_=h;if(this.horizontal_)
+this.className='horizontal-drag-handle';else
+this.className='vertical-drag-handle';},get vertical(){return!this.horizontal_;},set vertical(v){this.horizontal=!v;},forceMutationObserverFlush_:function(){var records=this.observer_.takeRecords();if(records.length)
+this.didTargetMutate_(records);},didTargetMutate_:function(e){var modeSize=this.targetSizesByModeKey_[this.modeKey_];if(modeSize!==undefined){this.setTargetSize_(modeSize);return;}
+this.target_.style[this.targetStyleKey_]='';},get targetStyleKey_(){return this.horizontal_?'height':'width';},getTargetSize_:function(){var targetStyleKey=this.targetStyleKey_;if(!this.target_.style[targetStyleKey]){this.target_.style[targetStyleKey]=window.getComputedStyle(this.target_)[targetStyleKey];}
+var size=parseInt(this.target_.style[targetStyleKey]);this.targetSizesByModeKey_[this.modeKey_]=size;return size;},setTargetSize_:function(s){this.target_.style[this.targetStyleKey_]=s+'px';this.targetSizesByModeKey_[this.modeKey_]=s;},applyDelta_:function(delta){var curSize=this.getTargetSize_();var newSize;if(this.target_===this.nextElementSibling){newSize=curSize+delta;}else{newSize=curSize-delta;}
+this.setTargetSize_(newSize);},onMouseMove_:function(e){var curMousePos=this.horizontal_?e.clientY:e.clientX;var delta=this.lastMousePos_-curMousePos;this.applyDelta_(delta);this.lastMousePos_=curMousePos;e.preventDefault();return true;},onMouseDown_:function(e){if(!this.target_)
+return;this.forceMutationObserverFlush_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();}};return{DragHandle:DragHandle};});'use strict';Polymer('tr-ui-b-dropdown',{ready:function(){this.$.outer.tabIndex=0;},get iconElement(){return this.$.icon;},onOuterKeyDown_:function(e){if(e.keyCode===' '.charCodeAt(0)){this.toggle_();e.preventDefault();e.stopPropagation();}},onOuterClick_:function(e){var or=this.$.outer.getBoundingClientRect();var inside=true;inside&=e.clientX>=or.left;inside&=e.clientX<or.right;inside&=e.clientY>=or.top;inside&=e.clientY<or.bottom;if(!inside)
+return;e.preventDefault();this.toggle_();},toggle_:function(){if(!this.isOpen)
+this.show();else
+this.close();},show:function(){if(this.isOpen)
+return;this.$.outer.classList.add('open');var ddr=this.$.outer.getBoundingClientRect();var rW=Math.max(ddr.width,150);this.$.dialog.style.minWidth=rW+'px';this.$.dialog.showModal();var ddw=this.$.outer.getBoundingClientRect().width;var w=this.$.dialog.getBoundingClientRect().width;this.$.dialog.style.top=ddr.bottom-1+'px';this.$.dialog.style.left=ddr.left+'px';},onDialogClick_:function(e){if(!this.isOpen)
+return;if(e.srcElement!==this.$.dialog)
+return;e.preventDefault();this.close();},onDialogCancel_:function(e){e.preventDefault();this.close();},close:function(){if(!this.isOpen)
+return;this.$.dialog.close();this.$.outer.classList.remove('open');this.$.outer.focus();},get isOpen(){return this.$.dialog.hasAttribute('open');}});'use strict';tr.exportTo('tr.ui.b',function(){var FaviconsByHue={blue:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjj8xAGArIgqOPzE8nUY3dqJJOJeiSTiXnUY3do4/MTxhKyIKjkAxAAAAAAAAAAAAAAAAAAAAAABQJBwAAAAAAZJBMzSoSzqlsU8+6bRQP/21UT//tVE//7RQP/2wTz3ppko6pY9AMjQAAAABTyMbAAAAAAB7e3sAAP//AKFSRE+wTz3dtVE//7VRP/+1UT//tVE//7VRP/+zUD7/sE89/7BOPf+qTDvdl0M0TwAAAABWJx4A+fn5ANjd3TnIiX7ftVA9/7VRP/+1UT//tVE//7VRP/+xTz3/rE08/6xMO/+sTDv/rE08/6dKOt+SQTM5q0w7ALO0tA3v8fGu05uR/7NMOf+0Tzz/tE88/7RPPv+uTT3/p0o7/6ZJOv+mSTr/pkk6/6ZJOv+mSjr/n0Y4rnIwKg3h4eFK9/j48N2zrP/FeGr/xnps/8Z6bP/AaUv/tlw1/7RbNf+1WzX/tFs1/7RbNf+0WzX/tFs1/7NbNPCqWy1K7e3tjPn5+f/49vX/9vLy//by8v/28vH/8bZv/+6RH//ukyP/7pMj/+6SI//ukiP/7pMj/+2SIv/qjyL/34kfjPHx8bL5+fn/+fn5//n5+f/5+fr/+fn5//W7cP/zlB3/85Yh//OWIf/zliH/85Yh//GVIf/rkR//6ZAf/+KLHrLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f/1unD/85Qd//OWIf/zliH/85Yh//CUIP/mjh//44we/+OMHv/diR628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/9bx0//OXI//zmCb/85gm/++VIv/hjB//3Yoe/92KHv/dih7/2IYdmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5//jo0//33bv/9929//bbtf/euDX/06oJ/9OrC//Tqwv/06oM98yfD1zr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/5+vv/+fv8//n7/f/3+PH/3Ms6/9O8AP/UvQD/1L0A/9K8AMbItAAY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/5+fr/9/bu/9zKOf/TuwD/1LwA/9S8APLQuABW3cQAAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+fn6//f27v/cyTn/07sA/9S8APTRugB4w60ABcmyAAAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/49/H/5Ndu/NjEIdLSugBdybIABsy1AAAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tvX063Lt6MMhOQAAAM+/RAAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCwUEDDgZExxWJx4tYiwiN2IsIjdWJx4tOBkTHAsFBAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAbDAkKZS0jMYs+MWydRjeipko6x6tMO9utTTzjrU0846tMO9umSjrHnUY3oos+MWxlLSMxGwwJCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgZFAAPBwUHcjMoPJtFNpqsTTzhs1A+/LVRP/+2UT//tVE//7VRP/+1UT//tVE//7ZRP/+1UT//s1A+/KxNPOGbRTaacTInPA8HBQc4GRMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yp4AUCQcGZVDNICtTjzktVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+0UT//s1A+/7JQPv+rTDvkkkEzgE8jGxn/xZoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA////AGswJSqiSTivs1A++7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tFA+/7FPPf+xTz3/sU89/7FPPf+vTj37nkc3r2guJCr///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP/DogB/VEwsqE09v7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7NQPv+vTj3/r049/69OPf+vTj3/r049/69OPf+uTjz/oUg4v20xJiz/nnsAAgEBAAAAAAAAAAAAAAAAAAAAAAD19fUAkp2fHdK2sbW5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+yUD7/rU08/6xNPP+tTTz/rU08/61NPP+tTTz/rU08/61NPP+sTTz/nkY3tWAqIR2pSzsAAAAAAAAAAAAAAAAAeXl5ADY2Ngnd39+O6tbT/blbSv+1UD7/tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//slA+/6xNPP+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+rTDv/q0w7/6tMO/+qTDv9lkM0jiUQDQlSJR0AAAAAAAAAAAD///8AxMTES/X29u3s2NX/uVtK/7VQPv+1UT//tVE//7VRP/+1UT//tVE//7VRP/+1UT//tVE//7FPPv+qTDv/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6hLOv+oSzr/qEs6/6lLOv+lSTnthDsuS/+TcgAAAAAAm5ubAHBwcA/o6Oix+vv8/+zY1P+5W0r/tVA+/7VRP/+1UT//tVE//7VRP/+1UT//tVE//7VRP/+xTz3/qEs6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+mSjr/pko6/6ZKOv+bRTaxSiEaD2cuJAD///8AycnJRfX19fD6+/z/69fU/7hYR/+0Tjv/tE48/7ROPP+0Tjz/tE48/7ROPP+0Tz3/r04+/6VJOv+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDn/o0g5/6NIOf+jSDr/o0g5/6NIOf+jSDn/o0g6/6BHOfCCOS9F0FxKAAAAAALk5OSN+fn5//n6+v/y5+X/05uS/9CTiP/QlIn/0JSJ/9CUif/QlIn/0JSK/8yGb//AaDb/vWc0/71nNf+9ZzT/vWc0/71nNP+9ZjT/vWY0/71mNP+9ZjT/vGY0/7xmNP+8ZjT/vGY0/7xmNP+8ZjT/u2U0/7FiLY0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+vr/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//KWI//ylSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//GVIf/xlSH/8ZUh//CUIf/vkyD/5Y0fxY1XExbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/wlCD/7pIg/+6SIP/pjx/lunIZM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/75Mg/+uRH//qkB//6pAf/+iPH/TIfBtQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+6TIP/ojx//548f/+ePH//njx//5o4f+c1/HGHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LL/85cj//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/tkiD/5Y0f/+SNH//ljR//5Y0f/+WNH//kjB/6zn8cZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fv9//fYsv/zlyP/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/65Eg/+KMHv/iix7/4ose/+KLHv/iix7/4ose/+CLHvfLfRta3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+/3/99iy//OXI//zliH/85Yh//OWIf/zliH/85Yh//OWIf/zliH/85Yh/+qRIP/gih7/34oe/9+KHv/fih7/34oe/9+KHv/fih7/3Yge78V6GkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n7/f/32LH/85Yg//OVHv/zlR7/85Ue//OVHv/zlR7/85Ue//OVIf/pjyH/3ogf/92HH//dhx//3Ycf/92HH//dhx//3Ycf/92HH//ahh7ZunMZI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fr7//jr2f/2ypL/9smP//bJkP/2yZD/9smQ//bJkP/2yZD/5rNI/9OeFP/SnhX/0p4V/9KeFf/SnhX/0Z0V/9GdFf/RnRX/0Z0V/8yWFq6KVBcI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn6//n6/P/5+vz/+fr8//n6/P/5+vz/+fr8//n6/P/h013/0rsA/9O8AP/TvAD/07wA/9O8AP/TvAD/07wA/9O8AP/SvAD+yLMAav/mAADr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6ANu/qgAkyLEAALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9S8AP/UvAD/zrYAgQAAAACfjQAAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9S8AP/UvAD/1LwA/9K6AMzCrAAeybIAAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+LSW//TuwD/1LwA/9S8AP/UvAD/1LwA/9S8AP/TuwDsy7QATu7UAACXhQAAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/4tJb/9O7AP/UvAD/1LwA/9S8AP/UvAD/07wA9M63AG6ZiQADtqIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/i0lv/07sA/9S8AP/UvAD/1LwA/9O8APDPuABzuKMABsGrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/+HSW//TugD/1LsA/9S8AP/TuwDazrcAWbejAATBqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/7uas/+bZdv/j1mvt2cYznMu0ACsUFAAAtaEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL4+frS9/j8kPT1/Trs8v8G8PP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',green:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbWJLAEpCMwptYks8eWxTdn1wVpd9cFaXeWxTdm1iSzxKQzMKbWJLAAAAAAAAAAAAAAAAAAAAAAA+OCsAAAAAAXBlTTSBdFmliHpe6Yp8X/2LfWD/i31g/4p8X/2HeV3pf3NYpW5jTDQAAAABPTcqAAAAAAB7e3sAlv//AIB1Xk+HeV3di31g/4t9YP+LfWD/i31g/4t9YP+Je1//h3pd/4d5Xf+DdVrddGhQTwAAAABDPC4A+fn5ANrb3DmupZPfinxf/4t9YP+LfWD/i31g/4t9YP+Iel7/hHdb/4R2W/+Edlv/hHdb/4BzWN9wZU05g3ZaALS0tA3w8PGuu7Sj/4h5W/+Je17/iXte/4t8X/+HeFz/gnNY/4FyWP+Bclj/gXJY/4FyWP+Bclj/fG1Url9NPA3h4eFK9/j48MvFuf+kmoP/ppuF/6abhf+JkHL/c4Rj/3OEY/9zhGP/coNj/3KDY/9yg2P/coNj/3CDYvBgf19K7e3tjPn5+f/39vb/9fTz//X08//09PP/itKw/0m+h/9Mv4n/TL+J/0y/if9Mv4n/TL+J/0y+iP9Lu4b/RrJ/jPHx8bL5+fn/+fn5//n5+f/5+fn/+fn5/4rXtP9Hwon/SsOL/0rDi/9Kw4v/SsOL/0nCiv9HvYb/RruF/0S1gbLz8/O2+fn5//n5+f/5+fn/+fn5//n5+f+K17P/R8KJ/0rDi/9Kw4v/SsOL/0nBif9GuYT/RbaC/0W2gv9Dsn+28vLymfn5+f/5+fn/+fn5//n5+f/5+fn/jdi1/0vDjP9OxI7/TsSO/0rAiv9FtoP/RLKA/0SygP9EsoD/Qq59mfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9rw5v/H6tn/yOra/8Lp2f9e1b7/O8yz/z3MtP89zLT/Pcuy9zzApVzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+vr//Pr7//z6+//z+fn/ZuPY/zbczv853c7/Od3O/zjbzcY10sYY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/8Pj3/2Xj1/823Mz/OdzN/znczfI42MlWO+XWAOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5//D49/9j4tf/NdvM/znczfQ42ct4Ncu9BTbRwgAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/z+Pj/jung/FLf0tI42ctdNdHCBjfUxgAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tu329XLO7+whAFQmAGrUygAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQgGDCsmHRxCOy4tS0M0N0tDNDdCOy4tKyYdHAkIBgwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAVEg4KTUU1MWtgSmx5bVOigHNYx4N2W9uFd1zjhXdc44N2W9uAc1jHeW1TomtgSmxNRjUxFRMOCv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsnHgALCggHWE88PHdrUpqEd1vhiXxf/It9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXxf/IR3W+F3a1KaV048PAsKCAcrJx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///AAPjcqGXJnT4CFeFzki31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+KfWD/iXxf/4l7Xv+DdlrkcGVNgDw2Khn//+sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AFJKOSp9cFavinxf+4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/inxf/4h6Xv+Iel3/iHpd/4h6Xv+GeV37eW1Ur1BINyr///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAP//3gBsZ1osgnVbv4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4l8X/+HeV3/hnlc/4Z5XP+GeVz/hnlc/4Z5XP+GeFz/fG9Vv1RLOiz/9LoAAgIBAAAAAAAAAAAAAAAAAAAAAAD19fUAl5ibHcbCurWShGn/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Je1//hXhc/4R3W/+Fd1v/hXdb/4V3W/+Fd1v/hXdb/4V3W/+Ed1v/eW1TtUlCMh2CdVkAAAAAAAAAAAAAAAAAeXl5ADY2Ngne3t+O4t/Z/ZKFaf+LfV//i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/iXte/4R3W/+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+Ddlr/g3Za/4N2Wv+CdVr9c2dPjhwZEwk/OSsAAAAAAAAAAAD///8AxMTES/X19u3k4dv/koRp/4t9X/+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4h6Xv+CdVr/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf+BdFn/gXRZ/4F0Wf9+clftZVtGS/3jrgAAAAAAm5ubAHBwcA/o6Oix+/v7/+Pg2/+ShGn/i31f/4t9YP+LfWD/i31g/4t9YP+LfWD/i31g/4t9YP+Iel7/gXRZ/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP+Ac1j/gHNY/4BzWP93a1KxOTMnD1BHNwD///8AycnJRfX19fD7+/v/4+Da/5CCZ/+Jel3/iXtd/4l7Xf+Je13/iXtd/4l7Xf+Ke17/iHhd/4BxV/9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/39wVv9/cFb/f3BW/31uVPBnWURFo45tAAAAAALk5OSN+fn5//r6+v/t7Oj/vLSk/7aunP+3rp3/t66d/7eunf+3rp3/uK+e/6Gmjv9vkG3/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmv/bI5r/2yOa/9sjmr/bI1q/2yNav9sjWr/bI1q/2uNav9rjWr/a41q/16GZI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/5+fr/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/wOfV/0vCi/9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0rCiv9Kwor/SsKK/0nAif9Jv4j/RreCxStxUBbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMSM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9JwYn/SL6I/0i+iP9GuoXlOJVqM9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/ScCJ/0e8hv9HvIb/R7yG/0a6hfQ9oXJQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0i/iP9GuoX/RrqE/0a6hP9GuoT/RrmD+T6ldWHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/TMOM/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Ivof/RbiD/0W3gv9FuIP/RbiD/0W4g/9Ft4L6PqZ2ZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pr7/7/n1f9Mw4z/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SL2H/0W2gv9FtYH/RbWB/0W1gf9FtYH/RbWB/0S0gPc+o3Ra3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8+vv/v+fV/0zDjP9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0rDi/9Kw4v/SsOL/0e8hv9EtID/RLOA/0SzgP9Es4D/RLOA/0SzgP9Es4D/Q7F/7zyecULS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z6+/+/59X/SsOL/0jCiv9Iwor/SMKK/0jCiv9Iwor/SMKK/0rCiv9HuoT/RLF+/0Owff9EsH3/RLB9/0Swff9EsH3/RLB9/0Swff9CrnzZOJZrI56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6/9/x6f+l38X/o9/D/6Tfw/+k38P/pN/D/6Tfw/+k38T/a9Kz/0DBof9BwKH/QcCh/0HAof9BwKD/QcCg/0G/oP9Bv6D/Qb+g/0C4mK4tbU4I////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn6//v6+//7+vv/+/r7//v6+//7+vv//Pr7//v6+/+B597/NdvN/znczf853M3/OdzN/znczf853M3/OdzN/znczf85283+NtHDakb/+gDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f823Mz/OdzN/znczf853M3/OdzN/znczf853M3/OdzN/zjay9s0x7kkNs/BALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdzN/znczf853M3/N9XHgQAAAAAspZoAAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znczf853M3/OdzN/zjay8w0yrweNtDCAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/3/n3f8228z/OdzN/znczf853M3/OdzN/znczf8528zsN9PETkD45gAonJEAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/f+fd/zbbzP853M3/OdzN/znczf853M3/OdvM9DjWx24qoJUDMb2wAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9/593/NtvM/znczf853M3/OdzN/znbzPA418hzMr6xBjTIugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/37m3f8z28z/N9zN/znczf8528zaONbIWTK/sgQ0yLsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/vfDr/5Tq4v+L6ODtYODUnDTTxSsAGBsAMrywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+PjS+vf3kPv09Tr/6u4G/+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',red:'data:image/vndmicrosofticon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQxmbAC0RagpDGZs8ShysdkwdspdMHbKXShysdkMZmzwuEWoKQxmcAAAAAAAAAAAAAAAAAAAAAAAmDlgAAAAAAUQanzRPHrilUx/B6VQgxf1VIMb/VSDG/1Qgxf1TH8DpTh22pUMZnDQAAAABJQ5XAAAAAAB7ensA//8AAFUrr09SH8DdVSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/Ux/B/1IfwP9QHrrdRxqlTwAAAAAoD14A+fn5ANzf1zmMatPfVB7G/1Ugxv9VIMb/VSDG/1Ugxv9TH8L/UR68/1AevP9QHrz/UR68/04dt99EGaA5UB67ALS0sw3x8u+unYDd/1AZxP9THcX/Ux3F/1Qexf9THr//Tx23/08ctv9PHbb/Tx22/08dtv9PHbb/SxuurjkSfg3h4eFK+Pj38LWf5P97UtL/fVXS/31V0/9fOcz/SSfC/0knwP9JJ8D/SSfA/0knwP9JJ8D/SSfA/0gnv/A/KLNK7e3tjPn5+f/29fj/8vD3//Px9//y8Pf/fILz/zQ/8P83QvD/N0Lw/zdC8P83QvD/N0Lw/zdB7/82QOz/Mz3gjPHx8bL5+fn/+fn5//n6+f/5+vn/+fn5/36G9v8yQPT/NkP0/zZD9P82Q/T/NkP0/zVC8v80QOz/M0Dq/zI+47Lz8/O2+fn5//n5+f/5+fn/+fn5//n5+f99hvb/MkD0/zZD9P82Q/T/NkP0/zVC8f8zP+f/Mj7k/zI+5P8xPd628vLymfn5+f/5+fn/+fn5//n5+f/5+fn/gYn2/zdE9P87R/T/O0f0/zZF8P8yQOP/MT/e/zE/3v8xP97/Lz3ZmfHx8Vz4+Pj3+fn5//n5+f/5+fn/+fn5/9fZ+P/Bxfj/wsb4/7vD+P87j/X/Dnzx/xF98f8RffH/EXzw9xZv5Vzr6+sY9/f3xvn5+f/5+fn/+fn5//n5+f/7+/n//Pz5//38+f/x+Pn/OrD+/wCY//8Amf//AJn//wCZ/cYAlPMY////APT09Fb4+Pjy+fn5//n5+f/5+fn/+fn5//n5+f/6+fn/7vX5/zmu/v8Al///AJj//wCY/vIAlfpWAJ//AOzs7ADm5uYF9vb2ePn5+fT5+fn/+fn5//n5+f/5+fn/+vn5/+71+f85rf7/AJb//wCY//QAlvx4AIzrBQCQ8gAAAAAA8PDwAOzs7Ab29vZd+Pj40vn5+fz5+fn/+fn5//n5+f/x9vn/bsP8/CGk/tIAlvxdAJDyBgCT9QAAAAAAAAAAAAAAAADn5+cAqKioAPT09CH39/dy+Pj4tvj4+NX4+PjV+Pj4tuvy93LD4fUhAAC7AESo6wAAAAAAAAAAAPAPAADAAwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgIMDBoKPRwoD14tLhFrNy4RazcoD14tGgo9HAYCDAwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+3/wANBR0KLxJuMUEYmGxKHKyiTh22x1Aeu9tRHr3jUR6941Aeu9tOHbbHShysokEYmGwvEm4xDQUeCv+6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoKPgAHAxAHNhR9PEkbqppRHr3hVCDE/FUgxv9VIMf/VSDH/1Ugxv9VIMb/VSDH/1Ugx/9VIMb/VCDE/FEevOFIG6maNRR8PAcDEAcaCj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVUP8AJg5YGUYao4BRH77kVSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMX/VB/E/1Qfw/9QHrvkRRmggCUOVhnQTv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA////ADITdSpMHbKvVCDE+1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VCDE/1Mfwv9TH8H/Ux/B/1Mfwv9SH7/7ShytrzEScSr///8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAMto/wBVPoYsUSC3v1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1QfxP9SHsD/Uh6//1Iev/9SHr//Uh6//1Iev/9SHr//SxywvzMTdyymPf8AAQACAAAAAAAAAAAAAAAAAAAAAAD19fUAnaKQHbep1rVfLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9UH8P/UR6+/1Eevf9RHr3/UR69/1Eevf9RHr3/UR69/1Eevf9RHr3/ShuttS0RaB1PHrkAAAAAAAAAAAAAAAAAeXl5ADY2Ngnf4NyO18zu/V8tyf9UH8b/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VB/D/1EevP9QHrr/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrv/UB67/1Aeu/9QHrr9RhqkjhEGKAknDloAAAAAAAAAAAD///8AxMTES/b39O3Zzu//Xy3J/1Qfxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Mfwv9QHbr/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duP9PHbj/Tx24/08duf9NHLTtPheRS5s5/wAAAAAAm5ubAHBwcA/o6Oix+/z6/9jO7/9fLcn/VB/G/1Ugxv9VIMb/VSDG/1Ugxv9VIMb/VSDG/1Ugxv9TH8H/Tx24/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9OHbb/Th22/04dtv9JG6mxIw1RDzAScQD///8AycnJRfX19fD7/Pr/2M3v/1wqyP9SHMX/UhzF/1Icxf9SHMX/UhzF/1Icxf9THcX/Ux7A/04ctf9NHLL/Thyz/04cs/9NHLP/TRyz/00cs/9OHLP/Thyz/04cs/9OHLP/Thyz/04cs/9NHLP/Thyz/0wcsPA/Fo9FYyTkAAAAAALk5OSN+fn5//r6+f/n4vT/noDd/5Z22v+Wdtr/lnba/5Z22v+Wdtr/mHfb/35g1/9KMMr/SC/H/0gvx/9IL8f/SC/H/0gvx/9IL8b/SC/G/0gvxv9HL8b/Ry/G/0cvxv9HL8b/Ry/G/0cvxv9HL8X/Ry7F/z8tuI0AAAACk5OTFu/v78X5+fn/+fn5//n5+f/6+vn/+fr5//n6+f/5+vn/+fr5//n6+f/9/fn/ub73/zhF8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zZD8v82Q/L/NkPy/zVC8f81QvD/Mz/mxR8njhbDw8Mz9PT05fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P81QvH/NEHv/zRB7/8zQOrlKTO6M9XV1VD39/f0+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NULw/zRA7P80QOv/NEDr/zNA6fQsN8lQ3d3dYfj4+Pn5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zVB7/8zQOn/Mz/o/zM/6P8zQOj/Mz/n+S04zmHh4eFl+Pj4+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+5vff/OEX0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P80Qe7/Mz/m/zM/5f8zP+b/Mz/m/zM/5v8yP+X6LjnPZeDg4Fr4+Pj3+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//Pz5/7m99/84RfT/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NEHs/zI+4/8yPuP/Mj7j/zI+4/8yPuP/Mj7j/zI+4fctOMxa3NzcQvf39+/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/8/Pn/ub33/zhF9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zZD9P82Q/T/NkP0/zRA6/8xPeH/MT3g/zE94P8xPeD/MT3g/zE94P8xPeD/MT3e7ys2xkLS0tIj9fX12fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//z8+f+4vff/NkP0/zNB9P80QfT/NEH0/zRB9P80QfT/NEH0/zZC8/81P+n/Mjze/zI73f8yO93/Mjvd/zI73f8yO93/Mjvd/zI73f8xO9rZKTO7I56engjy8vKu+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/9ze+P+covf/mqD3/5qg9/+aoPf/mqD3/5qg9/+aoPf/UoLz/x1p5/8eaeb/Hmnm/x5p5v8eaeX/Hmnl/x5p5f8eaOX/Hmjl/yBh3a4jJokI////AO3t7Wr5+fn++fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vr5//z8+f/8/Pn//Pz5//z8+f/8/Pn//Pz5//z8+f9dvfz/AJf+/wCZ/v8Amf7/AJn+/wCZ/v8Amf7/AJn+/wCZ/v8AmP7+AJLxagC4/wDr6+sA4eHhJPb29tv5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/NsAieckAI/xALu7uwAAAAAA8vLygfn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJP3gQAAAAAAcr8AAAAAAOzs7ADk5OQe9vb2zPn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY//8AmP//AJj//wCW/MwAi+oeAJDxAAAAAAAAAAAAsLCwAP///wDv7+9O+Pj47Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u8/f8Alv//AJj//wCY//8AmP//AJj//wCY//8Al/7sAJL0TgCr/wAAa7QAAAAAAAAAAAAAAAAA1tbWALS0tAPy8vJv+Pj49Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/W7z9/wCW//8AmP//AJj//wCY//8AmP//AJj+9ACU+G4AbrgDAIPaAAAAAAAAAAAAAAAAAAAAAAAAAAAA4uLiANfX1wbz8/Nz+Pj48Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f9bvP3/AJb//wCY//8AmP//AJj//wCY/vAAlflzAITcBgCK5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+PjANjY2ATy8vJZ+Pj42vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/1u7/f8Alf//AJf//wCY//8Al/7aAJT4WQCE3AQAiucAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NTUAB8fHwDw8PAr9vb2nPj4+O35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/rNv7/3bG/P9rwfztM6r7nACR9SsAER0AAIPZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr6wDj4+MG8vLyOvb29pD4+PjS+fn58vn5+f35+fn/+fn5//n5+f/5+fn/+fn5/fn5+fL6+fjS/Pj2kP338jr/+eIG//fqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADh4eEA1tbWAu/v7xv09PRJ9vb2dvb29pf39/eo9/f3qPb29pf29vZ29PT0Se/v7xvW1tYC4eHhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf/gAAf/8AAP//wAP/',yellow:'data:image/vndmicrosofticon;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAZKhQAOWAiAEV0KgBFdCoAOWAiABkqFAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8ZAAAChAHAEp8JwBvu10AgNeSAInluACN7c4Aj/DXAI/w1wCN7c4AieW4AIDXkgBvu10ASnwnAAoQBwA8ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbLgAAAAAFAFmWMwB/1YwAj/DXAJX7+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJX7+QCP79cAftWMAFmVMwAAAAUAGy4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7v8AAD1mFQB6zXYAkPLdAJf+/gCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP7/AJf+/wCV/P4AjvDdAHjKdgA8ZBUA6f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AABWkCYAh+KoAJb8+QCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJf+/wCV+v8AlPr/AJT6/wCV+v8Akvf5AIPdqABTjCYA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICABb//wAka5wqAozquwCY/v8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCX/f8Ak/j/AJP3/wCT9/8Ak/f/AJP3/wCT9/8Akvb/AIbiuwBZlyoA//8AAAECAAAAAAAAAAAAAAAAAAAAAADz8/MAqJaJHZDD5rQLnP7/AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alvz/AJL2/wCR9P8AkfT/AJH0/wCR9P8AkfT/AJH0/wCR9P8AkfT/AITftABQhh0AjO0AAAAAAAAAAAAAAAAAfX19ADw8PAni3tuPuuD5/Quc//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJb8/wCQ8/8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8Aj/H/AI/x/wCP8f8AjvD9AH7UjwAiOQkASHkAAAAAAAgICAD///8AxcXFT/j19O+94vv/Cpz//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCV+/8Aj/H/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCN7v8Aje7/AI3u/wCO7v8AiunvAHC8TwD//wAABQgAqKioAHp6ehHp6em3/fv5/7zh+v8KnP//AJj//wCY//8AmP//AJj//wCY//8AmP//AJj//wCY//8Alfr/AI7u/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8AjOv/AIzr/wCM6/8Ag9y3AERyEQBenQD///8AzMzMTfb29vP9+/n/vOH6/wqb//8Alv//AJb//wCW//8Alv//AJb//wCW//8Al///AJT5/wCL6/8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCJ6P8Aiej/AIno/wCH5fMAb75NAMP/AAAAAAXl5eWX+fn5//v6+f/T6vr/Wbv9/0+3/f9Qt/3/ULf9/1C3/f9Qt/3/Ubj9/zew+/8InO//B5nr/weZ6/8Hmev/B5nq/weZ6v8Hmer/B5nq/weZ6v8Hmer/B5jq/weY6v8HmOn/B5jp/weY6f8HmOn/Bpjp/weP15cBAAAFpKSkHfDw8M/5+fn/+fn5//n5+f/1+Pn/9Pf5//T3+f/09/n/9Pf5//T3+f/4+Pn/o+T6/wq//f8Hv/3/CL/9/wi//f8Iv/3/CL/9/wi//f8Iv/3/CL/8/wi+/P8Ivvz/CL78/wi+/P8Ivvz/CL78/we9+/8HvPr/BrbxzwR9pR3Ly8tA9fX17Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcL//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hv/3/Br36/wa9+v8GuvbsBZnLQNra2mD39/f4+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B778/wa79/8Guvf/Brr3/wa59fgFo9hg4uLidPj4+P35+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we++/8GufX/Brj0/wa49P8GuPT/Brfz/QWm3XTk5OR6+Pj4/fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+l5vv/CcH//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hvfr/Brfy/wa28f8GtvH/Brbx/wa28f8GtfD9BafdeuXl5W/4+Pj8+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn//fr5/6Xm+/8Jwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B7z5/wa17/8GtO7/BrTu/wa07v8GtO7/BrTu/waz7fwFpdtv4eHhVvj4+Pb5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/9+vn/peb7/wnB//8Hwf//B8H//wfB//8Hwf//B8H//wfB//8Hwf//B8H//we7+P8Gsu3/BrHr/wax6/8Gsev/BrHr/wax6/8Gsev/BrDq9gWh1Vba2toz9vb25vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//36+f+k5fv/BsH//wPA//8DwP//A8D//wPA//8DwP//A8D//wXA//8Guvb/BrDq/wau6P8Gruj/Bq7o/wau6P8Gruj/Bq7o/wau6P8GreXmBZnLM7+/vxH09PTC+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+/r5/83v+v9x2vz/btn9/2/Z/f9v2f3/b9n9/2/Z/f9v2f3/RdL5/yXG7v8mxOz/JsTs/ybE6/8mxOv/JsTr/yXE6/8lw+v/JcPr/yK95cIQirAR////APDw8IH5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+vn5//r5+f/6+fn/+vn5//r5+f/6+fn/+vn5//r5+f+H8Pz/Oer+/zzq/v886v7/POr+/zzq/v886v7/POr+/zzq/v886v3/OuDzgWz//wD09PQA5+fnNPf39+n5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876///O+v//zvp/ek32+00Ouf6AMrKygCzs7MF8/Pzmvn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v//zvr//876///OuX5miqptwUwv88AAAAAAPPz8wDp6eku9/f33fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//876///O+v//zvp/d033O8uOuX5AAAAAAAAAAAAvr6+AP///wDx8fFl+Pj49fn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Xw/f846///O+v//zvr//876///O+v//zvr//876v71OeP2ZY7//wAus8IAAAAAAAAAAAAAAAAA4ODgANPT0wj09PSI+fn5+vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/hfD9/zjr//876///O+v//zvr//876///O+v/+jrm+Ygyx9gINdPlAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOHh4Q309PSM+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f+F8P3/OOv//zvr//876///O+v//zvr//g65/qMNtXnDTjd7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpAOLi4gr09PRw+Pj45/n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5/4Pw/f816///Oev//zvr//876v7nOub5cDbW5wo33O4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ODgANHR0QLx8fE89/f3sfn5+fX5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/t/T7/4Xx/f+A8P31Xez8sTnk9zwuxdUCNtTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAREREAP///wDo6OgM9PT0Tff396T4+Pjf+fn5+Pn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+fj5+Pjf9vf3pPL09E3m6OgM7/3/APtbOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMjIwD19fUA4uLiBvHx8Sn19fVd9vb2jff396739/e99/f3vff396729vaN9fX1XfHx8Snl4uIG9PX1AFEnIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wD///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABgAAAAcAAAAPgAAAH4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/KAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEgsAABILAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABorgAAS34IAHTDNQCC22wAh+OMAIfjjACC22wAdMQ1AEx/CABorwAAAAAAAAAAAAAAAAAAAAAAAEBrAAAAAAAAecswAIzsngCU+OUAl/37AJj+/wCY/v8Al/37AJP35QCL6Z4Ad8gwAAAAAAA+aQAAAAAAcXd6AP8AAAAOiNtNAJP32gCY//8AmP//AJj//wCY//8AmP//AJb8/wCU+f8Ak/j/AI7w2gB+1E0AAAAAAEd4APn7/ADc2NU5T7P33gCX//8AmP//AJj//wCY//8AmP//AJX6/wCR8/8AkPL/AJDz/wCQ8/8AjOzeAHrOOQCR9AC3t7cO8e/vsGnA/f8Alf//AJf//wCX//8Al///AJP4/wCN7v8AjOz/AIzs/wCM7P8AjOz/AIzt/wCG4rAAY6oO4uLiT/j39/GIzfz/Mav+/zSs/v80rP7/FaH5/wOV7f8DlOv/A5Tr/wOU6/8DlOv/A5Tr/wOU6/8Dk+jxBIvVT+3t7ZT5+fn/8fb5/+vz+f/r9Pn/6vP5/1nR+/8EvPz/B738/we9/P8Hvfz/B738/we9/P8HvPv/B7r4/wax7ZTy8vK7+fn5//n5+f/6+fn/+vn5//n5+f9e1f3/A8D//wfB//8Hwf//B8H//wfB//8HwP3/Brv3/wa59f8GtO678/Pzwfn5+f/5+fn/+fn5//n5+f/4+fn/XtX9/wPA//8Hwf//B8H//wfB//8Hv/z/Brfz/wa17/8Gte//BrHqwfPz86X5+fn/+fn5//n5+f/5+fn/+Pn5/2DW/f8Gwf//CsL//wrC//8Jv/v/CLXu/wix6f8Isen/CLHp/wet5KXy8vJo+fn5+vn5+f/5+fn/+fn5//n5+f/I7vr/quf7/6zn+/+m5/v/Tdz5/yzV9P8u1fT/LtX0/y7U8/ooyOpo7OzsH/f399D5+fn/+fn5//n5+f/5+fn//Pr5//36+f/++vn/9fn5/2rv/v857P//POz//zzs//886/3QOuLzH////wD09PRh+fn59vn5+f/5+fn/+fn5//n5+f/5+fn/+fn5//H4+f9o7v7/OOv//zvr//876//2Ouf6YUH//wDu7u4A6enpB/b29oT5+fn3+fn5//n5+f/5+fn/+fn5//n5+f/x+Pn/Zu7+/zfr//876//3Ouj8hDfc7wc44PMAAAAAAPHx8QDu7u4I9vb2aPj4+Nn5+fn9+fn5//n5+f/5+fn/8/n5/4zx/P1S7P7ZO+n8aDfh9Ag55PcAAAAAAAAAAAAAAAAA6+vrAN/f3wH19fUo9/f3fvj4+MH4+Pje+Pj43vj4+MHq9vh+w/H2KADM5wFk4e8AAAAAAAAAAADwDwAA4AcAAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAgAEAAMADAADgBwAA'};return{FaviconsByHue:FaviconsByHue};});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined)
+throw new Error('eventType must be given');if(dict.keyCode===undefined&&dict.keyCodes===undefined)
+throw new Error('keyCode or keyCodes must be given');if(dict.keyCode!==undefined&&dict.keyCodes!==undefined)
+throw new Error('Only keyCode or keyCodes can be given');if(dict.callback===undefined)
+throw new Error('callback must be given');this.eventType_=dict.eventType;this.keyCodes_=[];if(dict.keyCode)
+this.pushKeyCode_(dict.keyCode);else if(dict.keyCodes){dict.keyCodes.forEach(this.pushKeyCode_,this);}
+this.useCapture_=!!dict.useCapture;this.callback_=dict.callback;this.thisArg_=dict.thisArg!==undefined?dict.thisArg:undefined;this.helpText_=dict.helpText!==undefined?dict.helpText:undefined;}
+HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call:function(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_:function(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey:HotKey};});'use strict';Polymer('tv-ui-b-hotkey-controller',{created:function(){this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached:function(){var host=this.findHost_();if(host.__hotkeyController)
+throw new Error('Multiple hotkey controllers attached to this host');host.__hotkeyController=this;this.curHost_=host;var parentElement;if(host.parentElement)
+parentElement=host.parentElement;else
+parentElement=host.parentNode.host;var parentController=tr.b.getHotkeyControllerForElement(parentElement);if(parentController){this.slavedToParentController_=parentController;parentController.addChildController_(this);return;}
+host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached:function(){var host=this.curHost_;if(!host)
+return;delete host.__hotkeyController;this.curHost_=undefined;if(this.slavedToParentController_){this.slavedToParentController_.removeChildController_(this);this.slavedToParentController_=undefined;return;}
+host.removeEventListener('keydown',this.onBubblingKeyDown_,false);host.removeEventListener('keydown',this.onCapturingKeyDown_,true);host.removeEventListener('keypress',this.onBubblingKeyPress_,false);host.removeEventListener('keypress',this.onCapturingKeyPress_,true);},addChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i!==-1)
+throw new Error('Controller already registered');this.childControllers_.push(controller);},removeChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i===-1)
+throw new Error('Controller not registered');this.childControllers_.splice(i,1);return controller;},getKeyMapForEventType_:function(eventType,useCapture){if(eventType==='keydown'){if(!useCapture)
+return this.bubblingKeyDownHotKeys_;else
+return this.capturingKeyDownHotKeys_;}else if(eventType==='keypress'){if(!useCapture)
+return this.bubblingKeyPressHotKeys_;else
+return this.capturingKeyPressHotKeys_;}else{throw new Error('Unsupported key event');}},addHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey))
+throw new Error('hotKey must be a tr.ui.b.HotKey');var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(keyMap[keyCode])
+throw new Error('Key is already bound for keyCode='+keyCode);}
+for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];keyMap[keyCode]=hotKey;}
+return hotKey;},removeHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey))
+throw new Error('hotKey must be a tr.ui.b.HotKey');var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(!keyMap[keyCode])
+throw new Error('Key is not bound for keyCode='+keyCode);keyMap[keyCode]=hotKey;}
+for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];delete keyMap[keyCode];}
+return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){this.detached();this.globalMode_=!!globalMode;this.attached();},get topmostConroller_(){if(this.slavedToParentController_)
+return this.slavedToParentController_.topmostConroller_;return this;},childRequestsGeneralFocus:function(child){var topmost=this.topmostConroller_;if(topmost.curHost_){if(topmost.curHost_.hasAttribute('tabIndex')){topmost.curHost_.focus();}else{if(document.activeElement)
+document.activeElement.blur();}}else{if(document.activeElement)
+document.activeElement.blur();}},childRequestsBlur:function(child){child.blur();var topmost=this.topmostConroller_;if(topmost.curHost_){topmost.curHost_.focus();}},findHost_:function(){if(this.globalMode_){return document.body;}else{if(this.parentElement)
+return this.parentElement;var node=this;while(node.parentNode){node=node.parentNode;}
+return node.host;}},appendMatchingHotKeysTo_:function(matchedHotKeys,useCapture,e){var localKeyMap=this.getKeyMapForEventType_(e.type,useCapture);var localHotKey=localKeyMap[e.keyCode];if(localHotKey)
+matchedHotKeys.push(localHotKey);for(var i=0;i<this.childControllers_.length;i++){var controller=this.childControllers_[i];controller.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);}},onKey_:function(useCapture,e){if(useCapture==false&&e.path[0].tagName=='INPUT')
+return;var sortedControllers;var matchedHotKeys=[];this.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);if(matchedHotKeys.length===0)
+return false;if(matchedHotKeys.length>1){throw new Error('More than one hotKey is currently unsupported');}
+var hotKey=matchedHotKeys[0];var prevented=0;prevented|=hotKey.call(e);return!prevented&&e.defaultPrevented;}});'use strict';tr.exportTo('tr.b',function(){function getHotkeyControllerForElement(refElement){var curElement=refElement;while(curElement){if(curElement.tagName==='tv-ui-b-hotkey-controller')
+return curElement;if(curElement.__hotkeyController)
+return curElement.__hotkeyController;if(curElement.parentElement){curElement=curElement.parentElement;continue;}
+curElement=findHost(curElement);}
+return undefined;}
+function findHost(initialNode){var node=initialNode;while(node.parentNode){node=node.parentNode;}
+return node.host;}
+return{getHotkeyControllerForElement:getHotkeyControllerForElement};});'use strict';Polymer('tr-ui-b-info-bar',{ready:function(){this.messageEl_=this.$.message;this.buttonsEl_=this.$.buttons;this.message='';this.visible=false;},get message(){return this.messageEl_.textContent;},set message(message){this.messageEl_.textContent=message;},get visible(){return!this.classList.contains('info-bar-hidden');},set visible(visible){if(visible)
+this.classList.remove('info-bar-hidden');else
+this.classList.add('info-bar-hidden');},removeAllButtons:function(){this.buttonsEl_.textContent='';},addButton:function(text,clickCallback){var button=document.createElement('button');button.textContent=text;button.addEventListener('click',clickCallback);this.buttonsEl_.appendChild(button);return button;}});'use strict';Polymer('tr-ui-b-info-bar-group',{ready:function(){this.messages_=[];},clearMessages:function(){this.messages_=[];this.updateContents_();},addMessage:function(text,opt_buttons){opt_buttons=opt_buttons||[];for(var i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined)
+throw new Error('buttonText must be provided');if(opt_buttons[i].onClick===undefined)
+throw new Error('onClick must be provided');}
+this.messages_.push({text:text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_:function(){this.$.messages.textContent='';this.messages_.forEach(function(message){var bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);this.$.messages.appendChild(bar);},this);}});'use strict';tr.exportTo('tr.ui',function(){var Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;};FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_:function(operation){var task;if(operation instanceof tr.b.Task)
+task=operation;else
+task=new tr.b.Task(operation,this);if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering:function(filterText){var sc=this.brushingStateController_;if(!sc)
+return;this.enqueueOperation_(function(){this.filterHits_=new tr.model.EventSet();this.currentHitIndex_=-1;}.bind(this));var stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){var overlay=new tr.ui.b.Overlay();overlay.textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
+if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{var filter=new tr.c.FullTextFilter(filterText);var filterHits=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHits));this.enqueueOperation_(function(){this.filterHits_=filterHits;sc.findTextChangedTo(filterHits);}.bind(this));}}
+return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_:function(dir){var firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0)
+this.currentHitIndex_=0;var N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)
+return;this.brushingStateController_.findFocusChangedTo(this.filterHits.subEventSet(this.currentHitIndex_,1));},findNext:function(){this.find_(1);},findPrevious:function(){this.find_(-1);}};return{FindController:FindController};});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;var MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS:MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE:MOUSE_SELECTOR_MODE};});'use strict';Polymer('tr-ui-b-mouse-mode-icon',{publish:{modeName:{value:undefined,reflect:true}},created:function(){this.active_=false;this.acceleratorKey_=undefined;},ready:function(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];var modeName=tr.b.findFirstKeyInDictMatching(tr.ui.b.MOUSE_SELECTOR_MODE,function(modeName,candidateMode){return candidateMode===mode;});if(modeName===undefined)
+throw new Error('Unknown mode');this.modeName=modeName;},modeNameChanged:function(){this.updateContents_();},get active(){return this.active_;},set active(active){this.active_=!!active;if(this.active_)
+this.classList.add('active');else
+this.classList.remove('active');this.updateContents_();},get acceleratorKey(){return this.acceleratorKey_;},set acceleratorKey(acceleratorKey){this.acceleratorKey_=acceleratorKey;this.updateContents_();},updateContents_:function(){if(this.modeName===undefined)
+return;var mode=this.mode;if(mode===undefined)
+throw new Error('Invalid mode');var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(!modeInfo)
+throw new Error('Invalid mode');var title=modeInfo.title;if(this.acceleratorKey_)
+title=title+' ('+this.acceleratorKey_+')';this.title=title;var bp;if(this.active_)
+bp=modeInfo.activeBackgroundPosition;else
+bp=modeInfo.defaultBackgroundPosition;this.style.backgroundPosition=bp;}});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE=tr.ui.b.MOUSE_SELECTOR_MODE;var MOUSE_SELECTOR_MODE_INFOS=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS;var MIN_MOUSE_SELECTION_DISTANCE=4;var MODIFIER={SHIFT:0x1,SPACE:0x2,CMD_OR_CTRL:0x4};function isCmdOrCtrlPressed(event){if(tr.isMac)
+return event.metaKey;else
+return event.ctrlKey;}
+Polymer('tr-ui-b-mouse-mode-selector',{__proto__:HTMLDivElement.prototype,created:function(){this.supportedModeMask_=MOUSE_SELECTOR_MODE.ALL_MODES;this.initialRelativeMouseDownPos_={x:0,y:0};this.defaultMode_=MOUSE_SELECTOR_MODE.PANSCAN;this.settingsKey_=undefined;this.mousePos_={x:0,y:0};this.mouseDownPos_={x:0,y:0};this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.onKeyUp_=this.onKeyUp_.bind(this);this.mode_=undefined;this.modeToKeyCodeMap_={};this.modifierToModeMap_={};this.targetElement_=undefined;this.modeBeforeAlternativeModeActivated_=null;this.isInteracting_=false;this.isClick_=false;},ready:function(){this.buttonsEl_=this.shadowRoot.querySelector('.buttons');this.dragHandleEl_=this.shadowRoot.querySelector('.drag-handle');this.supportedModeMask=MOUSE_SELECTOR_MODE.ALL_MODES;this.dragHandleEl_.addEventListener('mousedown',this.onDragHandleMouseDown_.bind(this));this.buttonsEl_.addEventListener('mouseup',this.onButtonMouseUp_);this.buttonsEl_.addEventListener('mousedown',this.onButtonMouseDown_);this.buttonsEl_.addEventListener('click',this.onButtonPress_.bind(this));},attached:function(){document.addEventListener('keydown',this.onKeyDown_);document.addEventListener('keyup',this.onKeyUp_);},detached:function(){document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('keyup',this.onKeyUp_);},get targetElement(){return this.targetElement_;},set targetElement(target){if(this.targetElement_)
+this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);this.targetElement_=target;if(this.targetElement_)
+this.targetElement_.addEventListener('mousedown',this.onMouseDown_);},get defaultMode(){return this.defaultMode_;},set defaultMode(defaultMode){this.defaultMode_=defaultMode;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(!this.settingsKey_)
+return;var mode=tr.b.Settings.get(this.settingsKey_+'.mode',undefined);if(MOUSE_SELECTOR_MODE_INFOS[mode]===undefined)
+mode=undefined;if((mode&this.supportedModeMask_)===0)
+mode=undefined;if(!mode)
+mode=this.defaultMode_;this.mode=mode;var pos=tr.b.Settings.get(this.settingsKey_+'.pos',undefined);if(pos)
+this.pos=pos;},get supportedModeMask(){return this.supportedModeMask_;},set supportedModeMask(supportedModeMask){if(this.mode&&(supportedModeMask&this.mode)===0)
+throw new Error('supportedModeMask must include current mode.');function createButtonForMode(mode){return button;}
+this.supportedModeMask_=supportedModeMask;this.buttonsEl_.textContent='';for(var modeName in MOUSE_SELECTOR_MODE){if(modeName=='ALL_MODES')
+continue;var mode=MOUSE_SELECTOR_MODE[modeName];if((this.supportedModeMask_&mode)===0)
+continue;var button=document.createElement('tr-ui-b-mouse-mode-icon');button.mode=mode;button.classList.add('tool-button');this.buttonsEl_.appendChild(button);}},getButtonForMode_:function(mode){for(var i=0;i<this.buttonsEl_.children.length;i++){var buttonEl=this.buttonsEl_.children[i];if(buttonEl.mode===mode)
+return buttonEl;}
+return undefined;},get mode(){return this.currentMode_;},set mode(newMode){if(newMode!==undefined){if(typeof newMode!=='number')
+throw new Error('Mode must be a number');if((newMode&this.supportedModeMask_)===0)
+throw new Error('Cannot switch to this mode, it is not supported');if(MOUSE_SELECTOR_MODE_INFOS[newMode]===undefined)
+throw new Error('Unrecognized mode');}
+var modeInfo;if(this.currentMode_===newMode)
+return;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)
+buttonEl.active=false;if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end);this.dispatchEvent(mouseEvent);}
+modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.exit,true);}
+this.currentMode_=newMode;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)
+buttonEl.active=true;this.mouseDownPos_.x=this.mousePos_.x;this.mouseDownPos_.y=this.mousePos_.y;modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];if(!this.isInAlternativeMode_)
+tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.enter,true);if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin);this.dispatchEvent(mouseEvent);}}
+if(this.settingsKey_&&!this.isInAlternativeMode_)
+tr.b.Settings.set(this.settingsKey_+'.mode',this.mode);},setKeyCodeForMode:function(mode,keyCode){if((mode&this.supportedModeMask_)===0)
+throw new Error('Mode not supported');this.modeToKeyCodeMap_[mode]=keyCode;if(!this.buttonsEl_)
+return;var buttonEl=this.getButtonForMode_(mode);if(buttonEl)
+buttonEl.acceleratorKey=String.fromCharCode(keyCode);},setCurrentMousePosFromEvent_:function(e){this.mousePos_.x=e.clientX;this.mousePos_.y=e.clientY;},createEvent_:function(eventName,sourceEvent){var event=new tr.b.Event(eventName,true);event.clientX=this.mousePos_.x;event.clientY=this.mousePos_.y;event.deltaX=this.mousePos_.x-this.mouseDownPos_.x;event.deltaY=this.mousePos_.y-this.mouseDownPos_.y;event.mouseDownX=this.mouseDownPos_.x;event.mouseDownY=this.mouseDownPos_.y;event.didPreventDefault=false;event.preventDefault=function(){event.didPreventDefault=true;if(sourceEvent)
+sourceEvent.preventDefault();};event.stopPropagation=function(){sourceEvent.stopPropagation();};event.stopImmediatePropagation=function(){throw new Error('Not implemented');};return event;},onMouseDown_:function(e){if(e.button!==0)
+return;this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin,e);if(this.mode===MOUSE_SELECTOR_MODE.SELECTION)
+mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);this.isInteracting_=true;this.isClick_=true;tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_,this.onMouseUp_);},onMouseMove_:function(e){this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.update,e);this.dispatchEvent(mouseEvent);if(this.isInteracting_)
+this.checkIsClick_(e);},onMouseUp_:function(e){if(e.button!==0)
+return;var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end,e);mouseEvent.isClick=this.isClick_;this.dispatchEvent(mouseEvent);if(this.isClick_&&!mouseEvent.didPreventDefault)
+this.dispatchClickEvents_(e);this.isInteracting_=false;this.updateAlternativeModeState_(e);},onButtonMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonMouseUp_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonPress_:function(e){this.modeBeforeAlternativeModeActivated_=undefined;this.mode=e.target.mode;e.preventDefault();},onKeyDown_:function(e){if(e.path[0].tagName=='INPUT')
+return;if(e.keyCode===' '.charCodeAt(0))
+this.spacePressed_=true;this.updateAlternativeModeState_(e);},onKeyUp_:function(e){if(e.path[0].tagName=='INPUT')
+return;if(e.keyCode===' '.charCodeAt(0))
+this.spacePressed_=false;var didHandleKey=false;tr.b.iterItems(this.modeToKeyCodeMap_,function(modeStr,keyCode){if(e.keyCode===keyCode){this.modeBeforeAlternativeModeActivated_=undefined;var mode=parseInt(modeStr);this.mode=mode;didHandleKey=true;}},this);if(didHandleKey){e.preventDefault();e.stopPropagation();return;}
+this.updateAlternativeModeState_(e);},updateAlternativeModeState_:function(e){var shiftPressed=e.shiftKey;var spacePressed=this.spacePressed_;var cmdOrCtrlPressed=isCmdOrCtrlPressed(e);var smm=this.supportedModeMask_;var newMode;var isNewModeAnAlternativeMode=false;if(shiftPressed&&(this.modifierToModeMap_[MODIFIER.SHIFT]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SHIFT];isNewModeAnAlternativeMode=true;}else if(spacePressed&&(this.modifierToModeMap_[MODIFIER.SPACE]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SPACE];isNewModeAnAlternativeMode=true;}else if(cmdOrCtrlPressed&&(this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL];isNewModeAnAlternativeMode=true;}else{if(this.isInAlternativeMode_){newMode=this.modeBeforeAlternativeModeActivated_;isNewModeAnAlternativeMode=false;}else{newMode=undefined;}}
+if(this.mode===newMode||newMode===undefined)
+return;if(isNewModeAnAlternativeMode)
+this.modeBeforeAlternativeModeActivated_=this.mode;this.mode=newMode;},get isInAlternativeMode_(){return!!this.modeBeforeAlternativeModeActivated_;},setModifierForAlternateMode:function(mode,modifier){this.modifierToModeMap_[modifier]=mode;},get pos(){return{x:parseInt(this.style.left),y:parseInt(this.style.top)};},set pos(pos){pos=this.constrainPositionToBounds_(pos);this.style.left=pos.x+'px';this.style.top=pos.y+'px';if(this.settingsKey_)
+tr.b.Settings.set(this.settingsKey_+'.pos',this.pos);},constrainPositionToBounds_:function(pos){var parent=this.offsetParent||document.body;var parentRect=tr.ui.b.windowRectForElement(parent);var top=0;var bottom=parentRect.height-this.offsetHeight;var left=0;var right=parentRect.width-this.offsetWidth;var res={};res.x=Math.max(pos.x,left);res.x=Math.min(res.x,right);res.y=Math.max(pos.y,top);res.y=Math.min(res.y,bottom);return res;},onDragHandleMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();var mouseDownPos={x:e.clientX-this.offsetLeft,y:e.clientY-this.offsetTop};tr.ui.b.trackMouseMovesUntilMouseUp(function(e){var pos={};pos.x=e.clientX-mouseDownPos.x;pos.y=e.clientY-mouseDownPos.y;this.pos=pos;}.bind(this));},checkIsClick_:function(e){if(!this.isInteracting_||!this.isClick_)
+return;var deltaX=this.mousePos_.x-this.mouseDownPos_.x;var deltaY=this.mousePos_.y-this.mouseDownPos_.y;var minDist=MIN_MOUSE_SELECTION_DISTANCE;if(deltaX*deltaX+deltaY*deltaY>minDist*minDist)
+this.isClick_=false;},dispatchClickEvents_:function(e){if(!this.isClick_)
+return;var modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];var eventNames=modeInfo.eventNames;var mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE:MIN_MOUSE_SELECTION_DISTANCE,MODIFIER:MODIFIER};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;};TimingTool.prototype={onEnterTiming:function(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming:function(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY))
+return;var pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_:function(pt){if(!pt.snapped)
+return;var ir=this.viewport_.interestRange;if(ir.min===pt.x)
+ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);if(ir.max===pt.x)
+ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);},onUpdateTiming:function(e){var pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming:function(e){this.mouseUp_();},onExitTiming:function(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_:function(e){if(e.button)
+return;var worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_:function(e){console.error('not implemented');},isTouchPointInsideTrackBounds_:function(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas)
+return false;var canvas=this.viewport_.modelTrackContainer.canvas;var canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom)
+return true;return false;},mouseDownAt_:function(worldX,y){var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
+if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.min=worldX;this.isMovingLeftEdge_=true;return;}
+if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.rightSelected=true;ir.max=worldX;this.isMovingLeftEdge_=false;return;}
+ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_:function(worldX,y,mouseDown){var ir=this.viewport_.interestRange;if(mouseDown){this.updateMovingEdge_(worldX);return;}
+var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
+if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.leftSelected=false;ir.rightSelected=true;return;}
+ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_:function(newWorldX){var ir=this.viewport_.interestRange;var a=ir.min;var b=ir.max;if(this.isMovingLeftEdge_)
+a=newWorldX;else
+b=newWorldX;if(a<=b)
+ir.setMinAndMax(a,b);else
+ir.setMinAndMax(b,a);if(ir.min==newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_:function(){var dt=this.viewport_.currentDisplayTransform;var ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;var pixelRatio=window.devicePixelRatio||1;var minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue)
+ir.reset();},getWorldXFromEvent_:function(e){var pixelRatio=window.devicePixelRatio||1;var canvas=this.viewport_.modelTrackContainer.canvas;var worldOffset=canvas.getBoundingClientRect().left;var viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_:function(e){var pixelRatio=window.devicePixelRatio||1;var EVENT_SNAP_RANGE=16*pixelRatio;var modelTrackContainer=this.viewport_.modelTrackContainer;var modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();var viewport=this.viewport_;var dt=viewport.currentDisplayTransform;var worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);var worldX=this.getWorldXFromEvent_(e);var mouseY=e.clientY;var selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
+var minDistX=worldMaxDist;var minDistY=Infinity;var pixWidth=dt.xViewVectorToWorld(1);var result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};var eventBounds=new tr.b.Range();for(var i=0;i<selection.length;i++){var event=selection[i];var track=viewport.trackForEvent(event);var trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);var eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
+var distX=eventX-worldX;var eventY=trackRect.top;var eventHeight=trackRect.height;var distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
+modelTrackContainer.scrollTop-modelTrackContainerRect.top;result.height=eventHeight;result.snapped=true;}}
+return result;}};return{TimingTool:TimingTool};});'use strict';tr.exportTo('tr.ui',function(){var kDefaultPanAnimatoinDurationMs=100.0;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined)
+this.durationMs=kDefaultPanAnimatoinDurationMs;else
+this.durationMs=opt_durationMs;this.startPanX=undefined;this.startPanY=undefined;this.startTimeMs=undefined;}
+TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor:function(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor:function(existing,timestamp,target){var remainingDeltaXOnExisting=existing.goalPanX-target.panX;var remainingDeltaYOnExisting=existing.goalPanY-target.panY;var remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.panX=tr.b.lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY)
+target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalPanY);return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined)
+this.durationMs=kDefaultPanAnimatoinDurationMs;else
+this.durationMs=opt_durationMs;this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
+TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!=this.goalFocalPointY;},canTakeOverFor:function(existingAnimation){return false;},takeOverFor:function(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.clamp(percentDone,0,1);target.scaleX=tr.b.lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=tr.b.lerp(percentDone,this.startPanY,this.goalFocalPointY);}
+target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation:TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation:TimelineDisplayTransformZoomToAnimation};});'use strict';tr.exportTo('tr.ui.b',function(){var ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild:function(x){HTMLUnknownElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore:function(x,y){HTMLUnknownElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild:function(x){HTMLUnknownElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild:function(x,y){HTMLUnknownElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_:function(textContent){if(textContent!='')
+throw new Error('textContent can only be set to \'\'.');this.clear();},clear:function(){while(this.lastChild)
+HTMLUnknownElement.prototype.removeChild.call(this,this.lastChild);this.didMutate_(this.observer_.takeRecords());},didMutate_:function(records){this.beginDecorating_();for(var i=0;i<records.length;i++){var addedNodes=records[i].addedNodes;if(addedNodes){for(var j=0;j<addedNodes.length;j++)
+this.decorateChild_(addedNodes[j]);}
+var removedNodes=records[i].removedNodes;if(removedNodes){for(var j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
+this.doneDecoratingForNow_();},decorateChild_:function(child){throw new Error('Not implemented');},undecorateChild_:function(child){throw new Error('Not implemented');},beginDecorating_:function(){},doneDecoratingForNow_:function(){}};return{ContainerThatDecoratesItsChildren:ContainerThatDecoratesItsChildren};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined)
+throw new Error('viewport is required when creating a Track.');this.viewport_=viewport;this.classList.add('track');},get viewport(){return this.viewport_;},get drawingContainer(){var cur=this;while(cur){if(cur instanceof tr.ui.tracks.DrawingContainer)
+return cur;cur=cur.parentElement;}
+return undefined;},get eventContainer(){},invalidateDrawingContainer:function(){var dc=this.drawingContainer;if(dc)
+dc.invalidate();},context:function(){if(!this.parentNode)
+return undefined;if(!this.parentNode.context)
+throw new Error('Parent container does not support context() method.');return this.parentNode.context();},decorateChild_:function(childTrack){},undecorateChild_:function(childTrack){if(childTrack.detach)
+childTrack.detach();},updateContents_:function(){},drawTrack:function(type){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.draw(type,viewLWorld,viewRWorld);ctx.restore();},draw:function(type,viewLWorld,viewRWorld){},addEventsToTrackMap:function(eventToTrackMap){},addContainersToTrackMap:function(containerToTrackMap){},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loVY,hiVY,selection){var pixelRatio=window.devicePixelRatio||1;var dt=this.viewport.currentDisplayTransform;var viewPixWidthWorld=dt.xViewVectorToWorld(1);var loWX=dt.xViewToWorld(loVX*pixelRatio);var hiWX=dt.xViewToWorld(hiVX*pixelRatio);var clientRect=this.getBoundingClientRect();var a=Math.max(loVY,clientRect.top);var b=Math.min(hiVY,clientRect.bottom);if(a>b)
+return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection:function(instantEvents,worldX,worldMaxDist,selection){var instantEvent=tr.b.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)
+return;selection.push(instantEvent);}};return{Track:Track};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={HEADING_WIDTH:250};return{constants:constants};});'use strict';tr.exportTo('tr.ui.tracks',function(){var DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};var DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';this.appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);},get canvas(){return this.canvas_;},context:function(){return this.ctx_;},viewportChange_:function(){this.invalidate();},invalidate:function(){if(this.rafPending_)
+return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_:function(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_:function(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);var typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(var idx in typesToDraw){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
+continue;this.children[i].drawTrack(typesToDraw[idx]);}}
+var pixelRatio=window.devicePixelRatio||1;var bounds=this.canvas_.getBoundingClientRect();var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld);},updateCanvasSizeIfNeeded_:function(){var visibleChildTracks=tr.b.asArray(this.children).filter(this.visibleFilter_);var thisBounds=this.getBoundingClientRect();var firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();var lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();var innerWidth=firstChildTrackBounds.width-
+tr.ui.b.constants.HEADING_WIDTH;var innerHeight=lastChildTrackBounds.bottom-firstChildTrackBounds.top;var pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!=innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
+if(this.canvas_.height!=innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}},visibleFilter_:function(element){if(!(element instanceof tr.ui.tracks.Track))
+return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
+continue;var trackClientRect=this.children[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track))
+continue;this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer:DrawingContainer,DrawType:DrawType};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);};ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){var modelItem=this.modelItem_;if(modelItem===undefined)
+return SelectionState.NONE;return modelItem.selectionState;}};return{ProxySelectableItem:ProxySelectableItem};});'use strict';Polymer('tr-ui-heading',{DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready:function(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)
+return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)
+return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)
+return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)
+return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_:function(){this.dispatchEvent(new tr.b.Event('heading-clicked',{'bubbles':true}));},updateContents_:function(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
+if(this.arrowVisible_){this.$.arrow.textContent=this.expanded_?this.DOWN_ARROW:this.RIGHT_ARROW;}
+this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;this.$.link.textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';this.$.heading_content.textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){if(this.items_===undefined)
+return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var dumpRadiusView=this.dumpRadiusView;var itemRadiusWorld=dt.xViewVectorToWorld(height);var items=this.items_;var loI=tr.b.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);var oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';var drawItems=function(selected){for(var i=loI;i<items.length;++i){var item=items[i];var x=item.start;if(x-itemRadiusWorld>viewRWorld)
+break;if(item.selected!==selected)
+continue;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
+ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap:function(eventToTrackMap){if(this.items_===undefined)
+return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)
+return;var itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.items_===undefined)
+return;var items=this.items_;var index=tr.b.findFirstIndexInArray(items,function(item){return item.modelItem===event;});if(index===-1)
+return false;var newIndex=index+offset;if(newIndex>=0&&newIndex<items.length){items[newIndex].addToSelection(selection);return true;}
+return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)
+return;var item=tr.b.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)
+return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;};LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack:LetterDotTrack,LetterDot:LetterDot};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
+this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack:AlertTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Task=tr.b.Task;var ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach:function(){this.textContent='';},get tracks_(){var tracks=[];for(var i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track)
+tracks.push(this.children[i]);}
+return tracks;},drawTrack:function(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b)
+this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}
+tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i)
+this.children[i].addEventsToTrackMap(eventToTrackMap);},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.tracks_.length;i++)
+this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var task=new Task();for(var i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}}(i),this);}
+return task;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap:function(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_:function(){this.tracks_.forEach(function(track){this.removeChild(track);},this);}};return{ContainerTrack:ContainerTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocate();this.bounds=new tr.b.Range();if(opt_min!==undefined)
+this.bounds.addValue(opt_min);if(opt_max!==undefined)
+this.bounds.addValue(opt_max);};ChartAxis.prototype={get guid(){return this.guid_;},valueToUnitRange:function(value){if(this.bounds.isEmpty)
+throw new Error('Chart axis bounds are empty');var bounds=this.bounds;if(bounds.range===0)
+return 0;return(value-bounds.min)/bounds.range;},autoSetFromSeries:function(series,opt_config){var range=new tr.b.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange:function(range,opt_config){if(range.isEmpty)
+return;var bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
+if(!opt_config)
+return;var useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);var useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)
+return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
+if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}}};return{ChartAxis:ChartAxis};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.yBase=opt_yBase;};ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{ChartPoint:ChartPoint};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var ChartSeriesType={LINE:0,AREA:1};var DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5};var LAST_POINT_WIDTH=16;var ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,axis,opt_renderingConfig){this.points=points;this.axis=axis;this.useRenderingConfig_(opt_renderingConfig);}
+ChartSeries.prototype={useRenderingConfig_:function(opt_renderingConfig){var config=opt_renderingConfig||{};tr.b.iterItems(DEFAULT_RENDERING_CONFIG,function(key,defaultValue){var value=config[key];if(value===undefined)
+value=defaultValue;this[key+'_']=value;},this);this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){var range=new tr.b.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw:function(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0)
+return;if(this.chartType_===ChartSeriesType.AREA){this.drawComponent_(ctx,transform,ChartSeriesComponent.BACKGROUND,highDetails);}
+if(this.chartType_===ChartSeriesType.LINE||highDetails){this.drawComponent_(ctx,transform,ChartSeriesComponent.LINE,highDetails);}
+this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_:function(ctx,transform,component,highDetails){var extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
+var leftViewX=transform.leftViewX-extraPixels*transform.pixelRatio;var rightViewX=transform.rightViewX+
+extraPixels*transform.pixelRatio;var leftTimestamp=transform.leftTimestamp-extraPixels;var rightTimestamp=transform.rightTimestamp+extraPixels;var firstVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);var lastVisibleIndex=tr.b.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
+var viewSkipDistance=this.skipDistance_*transform.pixelRatio;var circleRadius;var squareSize;var squareHalfSize;var squareOpacity;switch(component){case ChartSeriesComponent.DOTS:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=transform.pixelRatio;circleRadius=(this.selectedPointSize_/2)*transform.pixelRatio;squareSize=this.unselectedPointSize_*transform.pixelRatio;squareHalfSize=squareSize/2;if(!highDetails){squareOpacity=0;break;}
+var visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
+var visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
+transform.worldXToViewX(this.points[firstVisibleIndex].x);if(visibleViewXRange===0){squareOpacity=1;break;}
+var density=visibleIndexRange/visibleViewXRange;var clampedDensity=tr.b.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);var densityRange=this.unselectedPointDensityTransparent_-
+this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*transform.pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
+var previousViewX=undefined;var previousViewY=undefined;var previousViewYBase=undefined;var lastSelectionState=undefined;var baseSteps=undefined;var startIndex=Math.max(firstVisibleIndex-1,0);for(var i=startIndex;i<this.points.length;i++){var currentPoint=this.points[i];var currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
+break;}
+if(i+1<this.points.length){var nextPoint=this.points[i+1];var nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
+if(currentViewX<leftViewX){currentViewX=leftViewX;}}
+if(previousViewX!==undefined&&currentViewX-previousViewX<viewSkipDistance){currentViewX=previousViewX+viewSkipDistance;}
+var currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));var currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
+var currentSelectionState=currentPoint.selectionState;switch(component){case ChartSeriesComponent.DOTS:if(currentSelectionState!==lastSelectionState){if(currentSelectionState===SelectionState.SELECTED){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState);}else if(squareOpacity>0){ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,squareOpacity);}}
+if(currentSelectionState===SelectionState.SELECTED){ctx.beginPath();ctx.arc(currentViewX,currentViewY,circleRadius,0,2*Math.PI);ctx.fill();ctx.stroke();}else if(squareOpacity>0){ctx.fillRect(currentViewX-squareHalfSize,currentViewY-squareHalfSize,squareSize,squareSize);}
+break;case ChartSeriesComponent.LINE:if(previousViewX===undefined){ctx.beginPath();ctx.moveTo(currentViewX,currentViewY);}else{ctx.lineTo(currentViewX,previousViewY);}
+ctx.lineTo(currentViewX,currentViewY);break;case ChartSeriesComponent.BACKGROUND:if(previousViewX!==undefined)
+ctx.lineTo(currentViewX,previousViewY);if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();}
+ctx.beginPath();ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,this.backgroundOpacity_);ctx.moveTo(currentViewX,currentViewYBase);baseSteps=[];}
+if(currentViewYBase!==previousViewYBase||currentSelectionState!==lastSelectionState){baseSteps.push({viewX:currentViewX,viewY:currentViewYBase});}
+ctx.lineTo(currentViewX,currentViewY);break;default:throw new Error('Not reachable');}
+previousViewX=currentViewX;previousViewY=currentViewY;previousViewYBase=currentViewYBase;lastSelectionState=currentSelectionState;}
+if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();break;default:throw new Error('Not reachable');}}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var points=this.points;function getPointWidth(point,i){if(i===points.length-1)
+return LAST_POINT_WIDTH*viewPixWidthWorld;var nextPoint=points[i+1];return nextPoint.x-point.x;}
+function selectPoint(point){point.addToSelection(selection);}
+tr.b.iterateOverIntersectingIntervals(this.points,function(point){return point.x},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.points===undefined)
+return false;var index=tr.b.findFirstIndexInArray(this.points,function(point){return point.modelItem===event;},this);if(index===-1)
+return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)
+return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)
+return;var item=tr.b.findClosestElementInSortedArray(this.points,function(point){return point.x},worldX,worldMaxDist);if(!item)
+return;item.addToSelection(selection);}};return{ChartSeries:ChartSeries,ChartSeriesType:ChartSeriesType};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartTransform(displayTransform,axis,trackWidth,trackHeight,topPadding,bottomPadding,pixelRatio){this.pixelRatio=pixelRatio;this.leftViewX=0;this.rightViewX=trackWidth;this.leftTimestamp=displayTransform.xViewToWorld(this.leftViewX);this.rightTimestamp=displayTransform.xViewToWorld(this.rightViewX);this.displayTransform_=displayTransform;this.outerTopViewY=0;this.innerTopViewY=topPadding;this.innerBottomViewY=trackHeight-bottomPadding;this.outerBottomViewY=trackHeight;this.axis_=axis;this.innerHeight_=this.innerBottomViewY-this.innerTopViewY;};ChartTransform.prototype={worldXToViewX:function(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX:function(viewX){return this.displayTransform_.xViewToWorld(viewX);},worldYToViewY:function(worldY){var innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform:ChartTransform};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('chart-track');this.series_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_:function(){if(!this.series_){this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
+var axisGuidToAxisData={};var topPadding=0;var bottomPadding=0;this.series_.forEach(function(series){var axis=series.axis;var axisGuid=axis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:axis,series:[]};}
+axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_:function(viewLWorld,viewRWorld){if(!this.series_)
+return;var ctx=this.context();var displayTransform=this.viewport.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var highDetails=this.viewport.highDetails;var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var topPadding=this.topPadding_*pixelRatio;var bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();this.series_.forEach(function(series){var chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.axis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);},this);ctx.restore();},addEventsToTrackMap:function(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes:function(opt_config){tr.b.iterItems(this.axisGuidToAxisData_,function(axisGuid,axisData){var axis=axisData.axis;var series=axisData.series;axis.autoSetFromSeries(series,opt_config);},this);},autoSetAxis:function(axis,opt_config){var series=this.axisGuidToAxisData_[axis.guid].series;axis.autoSetFromSeries(series,opt_config);}};return{ChartTrack:ChartTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ChartTrack=tr.ui.tracks.ChartTrack;var PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate:function(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap:function(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_:function(){if(!this.hasVisibleContent)
+return[];var axis=new tr.ui.tracks.ChartAxis(0,undefined);var pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.power);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,axis,renderingConfig)];}};return{PowerSeriesTrack:PowerSeriesTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('spacing-track');this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},draw:function(type,viewLWorld,viewRWorld){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{SpacingTrack:SpacingTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ContainerTrack=tr.ui.tracks.ContainerTrack;var DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate:function(viewport){ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_:function(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){this.appendChild(this.powerSeriesTrack_);this.appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_:function(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack:DeviceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var DISPLAYED_SIZE_ATTRIBUTE_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_ATTRIBUTE_NAME;function addDictionary(dstDict,srcDict){tr.b.iterItems(srcDict,function(key,value){var existingValue=dstDict[key];if(existingValue===undefined)
+existingValue=0;dstDict[key]=existingValue+value;});}
+function getProcessMemoryDumpAllocatorSizes(processMemoryDump){var allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)
+return{};var allocatorSizes={};allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')
+return;var allocatorSize=allocatorDump.attributes[DISPLAYED_SIZE_ATTRIBUTE_NAME];if(allocatorSize===undefined)
+return;var allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)
+return;allocatorSizes[allocatorDump.fullName]=allocatorSizeValue;});return allocatorSizes;};function getGlobalMemoryDumpAllocatorSizes(globalMemoryDump){var globalAllocatorSizes={};tr.b.iterItems(globalMemoryDump.processMemoryDumps,function(pid,processMemoryDump){addDictionary(globalAllocatorSizes,getProcessMemoryDumpAllocatorSizes(processMemoryDump));});return globalAllocatorSizes;}
+function buildAllocatedMemoryChartSeries(memoryDumps,memoryDumpToAllocatorSizesFn){var allocatorNameToPoints={};var dumpsData=memoryDumps.map(function(memoryDump){var allocatorSizes=memoryDumpToAllocatorSizesFn(memoryDump);tr.b.iterItems(allocatorSizes,function(allocatorName){allocatorNameToPoints[allocatorName]=[];});return{dump:memoryDump,sizes:allocatorSizes};});if(Object.keys(allocatorNameToPoints).length===0)
+return undefined;dumpsData.forEach(function(dumpData){var memoryDump=dumpData.dump;var allocatorSizes=dumpData.sizes;tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var allocatorSize=allocatorSizes[allocatorName]||0;points.push(new tr.ui.tracks.ChartPoint(memoryDump,memoryDump.start,allocatorSize));});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(allocatorNameToPoints,function(allocatorName,points){var colorId=ColorScheme.getColorIdForGeneralPurposeString(allocatorName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.LINE,colorId:colorId};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});return series;}
+function buildMemoryLetterDots(memoryDumps){var lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');var detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){var memoryColorId;switch(memoryDump.levelOfDetail){case'detailed':memoryColorId=detailedMemoryColorId;break;case'light':default:memoryColorId=lightMemoryColorId;}
+return new tr.ui.tracks.LetterDot(memoryDump,'M',memoryColorId,memoryDump.start);});}
+function buildGlobalUsedMemoryChartSeries(globalMemoryDumps){var containsVmRegions=globalMemoryDumps.some(function(globalDump){for(var pid in globalDump.processMemoryDumps)
+if(globalDump.processMemoryDumps[pid].mostRecentVmRegions)
+return true;return false;});if(!containsVmRegions)
+return undefined;var pidToProcess={};globalMemoryDumps.forEach(function(globalDump){tr.b.iterItems(globalDump.processMemoryDumps,function(pid,processDump){pidToProcess[pid]=processDump.process;});});var pidToPoints={};tr.b.iterItems(pidToProcess,function(pid,process){pidToPoints[pid]=[];});globalMemoryDumps.forEach(function(globalDump){var pssBase=0;tr.b.iterItems(pidToPoints,function(pid,points){var processMemoryDump=globalDump.processMemoryDumps[pid];var pss;if(processMemoryDump===undefined){pss=0;}else{pss=processMemoryDump.getMostRecentTotalVmRegionStat('proportionalResident');if(pss===undefined){pss=0;}}
+var cumulativePss=pssBase+pss;points.push(new tr.ui.tracks.ChartPoint(globalDump,globalDump.start,cumulativePss,pssBase));pssBase=cumulativePss;});});var axis=new tr.ui.tracks.ChartAxis(0);var series=[];tr.b.iterItems(pidToPoints,function(pid,points){var process=pidToProcess[pid];var colorId=ColorScheme.getColorIdForGeneralPurposeString(process.userFriendlyName);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:colorId,backgroundOpacity:0.8};series.push(new tr.ui.tracks.ChartSeries(points,axis,renderingConfig));});series.reverse();return series;}
+function buildProcessAllocatedMemoryChartSeries(processMemoryDumps){return buildAllocatedMemoryChartSeries(processMemoryDumps,getProcessMemoryDumpAllocatorSizes);}
+function buildGlobalAllocatedMemoryChartSeries(globalMemoryDumps){return buildAllocatedMemoryChartSeries(globalMemoryDumps,getGlobalMemoryDumpAllocatorSizes);}
+return{buildMemoryLetterDots:buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries:buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries:buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries:buildGlobalAllocatedMemoryChartSeries};});'use strict';tr.exportTo('tr.ui.tracks',function(){var USED_MEMORY_TRACK_HEIGHT=50;var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
+return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_:function(){var items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)
+return;var track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;this.appendChild(track);},appendUsedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(!series)
+return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per process';track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
+return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{GlobalMemoryDumpTrack:GlobalMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){function Highlighter(viewport){if(viewport===undefined){throw new Error('viewport must be provided');}
+this.viewport_=viewport;};Highlighter.prototype={__proto__:Object.prototype,processModel:function(model){throw new Error('processModel implementation missing');},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){throw new Error('drawHighlight implementation missing');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Highlighter;tr.b.decorateExtensionRegistry(Highlighter,options);return{Highlighter:Highlighter};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate:function(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem:function(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){var numSeries=counter.series.length;var totals=counter.totals;var chartAxis=new tr.ui.tracks.ChartAxis(0,undefined);var chartSeries=counter.series.map(function(series,seriesIndex){var chartPoints=series.samples.map(function(sample,sampleIndex){var total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,chartAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack:CounterTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var startCompare=function(x,y){return x.start-y.start;}
+var FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)
+return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
+FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack:FrameTrack};});'use strict';tr.exportTo('tr.model',function(){var Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
+ModelSettings.prototype={buildObjectsByKeyMap_:function(){var objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});var objectsByKey={};var NONUNIQUE_KEY='nonuniqueKey';for(var i=0;i<objects.length;i++){var object=objects[i];var objectKey=object.getSettingsKey();if(!objectKey)
+continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
+objectsByKey[objectKey]=NONUNIQUE_KEY;}
+var nonuniqueKeys={};tr.b.dictionaryKeys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY)
+return;delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_:function(){var settings=Settings.get('trace_model_settings',{});var settingsChanged=false;tr.b.dictionaryKeys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey])
+return;settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged)
+Settings.set('trace_model_settings',settings);},hasUniqueSettingKey:function(object){var objectKey=object.getSettingsKey();if(!objectKey)
+return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor:function(object,objectLevelKey,defaultValue){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){var settings=this.getEphemeralSettingsFor_(object);var ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined)
+return ephemeralValue;return defaultValue;}
+var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
+settings[objectKey]={};var value=settings[objectKey][objectLevelKey];if(value!==undefined)
+return value;return defaultValue;},setSettingFor:function(object,objectLevelKey,value){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
+var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey])
+settings[objectKey]={};if(settings[objectKey][objectLevelKey]===value)
+return;settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_:function(object){if(object.guid===undefined)
+throw new Error('Only objects with GUIDs can be persisted');if(this.ephemeralSettingsByGUID_[object.guid]===undefined)
+this.ephemeralSettingsByGUID_[object.guid]={};return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings:ModelSettings};});'use strict';tr.exportTo('tr.ui.tracks',function(){var MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.itemsGroupedOnLastUpdateContents_=undefined;this.currentSubRows_=[];this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup:function(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateContents_();},get subRows(){return this.currentSubRows_;},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_==expanded)
+return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_:function(e){if(this.subRows.length<=1)
+return;this.expanded=!this.expanded;if(this.groupingSource_){var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
+e.stopPropagation();},updateExpandedStateFromGroupingSource_:function(){if(this.groupingSource_){var numSubRows=this.subRows.length;var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){var defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
+this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_:function(){var minH=Math.max(2,Math.ceil(18/this.children.length));var h=(this.expanded_?18:minH)+'px';for(var i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0)
+this.children[i].arrowVisible=true;this.children[i].expanded=this.expanded;}
+if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_:function(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);if(!this.itemsToGroup_){this.updateHeadingAndTooltip_();this.currentSubRows_=[];return;}
+if(this.areArrayContentsSame_(this.itemsGroupedOnLastUpdateContents_,this.itemsToGroup_)){this.updateHeadingAndTooltip_();return;}
+this.itemsGroupedOnLastUpdateContents_=this.itemsToGroup_;this.detach();if(!this.itemsToGroup_.length){this.currentSubRows_=[];return;}
+var subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRows_=subRows;for(var srI=0;srI<subRows.length;srI++){var subRow=subRows[srI];if(!subRow.length)
+continue;var track=this.addSubTrack_(subRow);track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));}
+this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_:function(){if(!this.firstChild)
+return;this.firstChild.heading=this.heading_;this.firstChild.tooltip=this.tooltip_;},buildSubRows_:function(itemsToGroup){throw new Error('Not implemented');},addSubTrack_:function(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_:function(a,b){if(!a||!b)
+return false;if(!a.length||!b.length)
+return false;if(a.length!=b.length)
+return false;for(var i=0;i<a.length;++i){if(a[i]!=b[i])
+return false;}
+return true;}};return{MultiRowTrack:MultiRowTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length==0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
+this.heading=objectInstances[0].typeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=dt.xViewVectorToWorld(height);var loI;ctx.save();dt.applyTransformToCanvas(ctx);var objectInstances=this.objectInstances_;var loI=tr.b.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.strokeStyle='rgb(0,0,0)';for(var i=loI;i<objectInstances.length;++i){var instance=objectInstances[i];var x=instance.creationTs;if(x>viewRWorld)
+break;var right=instance.deletionTs==Number.MAX_VALUE?viewRWorld:instance.deletionTs;ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(x,pixelRatio,right-x,height-2*pixelRatio);}
+ctx.restore();var objectSnapshots=this.objectSnapshots_;loI=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(var i=loI;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)
+break;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
+ctx.lineWidth=1;var selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
+if(selectionState===SelectionState.DIMMED){var width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap:function(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
+if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
+var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)
+return;tr.b.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,selection.push.bind(selection));},addEventNearToProvidedEventToSelection:function(event,offset,selection){var events;if(event instanceof tr.model.ObjectSnapshot)
+events=this.objectSnapshots_;else if(event instanceof tr.model.ObjectInstance)
+events=this.objectInstances_;else
+throw new Error('Unrecognized event');var index=events.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
+return;selection.push(snapshot);}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack:ObjectInstanceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_:function(objectInstances){var hasMultipleRows=this.subRows.length>1;var track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;this.appendChild(track);return track;},buildSubRows_:function(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});var subRows=[];for(var i=0;i<objectInstances.length;i++){var objectInstance=objectInstances[i];var found=false;for(var j=0;j<subRows.length;j++){var subRow=subRows[j];var lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
+if(!found){var subRow=[objectInstance];subRows.push(subRow);}}
+return subRows;},updateHeadingAndTooltip_:function(){}};return{ObjectInstanceGroupTrack:ObjectInstanceGroupTrack};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,minRectSize,maxMergeDist,pallette){this.ctx_=ctx;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.pallette_=pallette;}
+FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH:function(y,h){if(this.y_===y&&this.h_===h)
+return;this.flush();this.y_=y;this.h_=h;},fillRect:function(x,w,colorId,alpha){var r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_)
+this.flush();if(!this.merging_){this.merging_=true;this.mergeStartX_=x;this.mergeCurRight_=r;this.mergedColorId_=colorId;this.mergedAlpha_=alpha;}else{this.mergeCurRight_=r;if(this.mergedAlpha_<alpha||(this.mergedAlpha_===alpha&&this.mergedColorId_<colorId)){this.mergedAlpha_=alpha;this.mergedColorId_=colorId;}}}else{if(this.merging_)
+this.flush();this.ctx_.fillStyle=this.pallette_[colorId];this.ctx_.globalAlpha=alpha;this.ctx_.fillRect(x,this.y_,w,this.h_);}},flush:function(){if(this.merging_){this.ctx_.fillStyle=this.pallette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;this.ctx_.fillRect(this.mergeStartX_,this.y_,this.mergeCurRight_-this.mergeStartX_,this.h_);this.merging_=false;}}};return{FastRectRenderer:FastRectRenderer};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_:function(viewLWorld,viewRWorld){var ctx=this.context();ctx.save();var bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)
+return;var fontSize,yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
+tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap:function(eventToTrackMap){if(this.rects_===undefined||this.rects_===null)
+return;this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
+onRect=onRect.bind(this);var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration==0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var index=tr.b.findFirstIndexInArray(this.rects_,function(rect){return rect.modelItem===event;});if(index===-1)
+return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)
+return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.rects_.length;++i){var modelItem=this.rects_[i].modelItem;if(!modelItem)
+continue;if(filter.matchSlice(modelItem))
+selection.push(modelItem);}},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var rect=tr.b.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)
+return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;};Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack:RectTrack,Rect:Rect};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)
+return[];var ops=[];var pushOp=function(isStart,time,slice){ops.push({isStart:isStart,time:time,slice:slice});};for(var tid in process.threads){var sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
+ops.sort(function(a,b){return a.time-b.time;});var rects=[];var genericColorId=ColorScheme.getColorIdForReservedName('generic_work');var pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));}
+var depth=0;var currentSlice=undefined;var lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice==currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth==1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!=lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
+currentSlice=op.slice;}}else{if(depth==0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack:ProcessSummaryTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack:SliceTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices,opt_skipSort){if(!opt_skipSort){slices.sort(function(x,y){return x.start-y.start;});}
+var findLevel=function(sliceToPut,rows,n){if(n>=rows.length)
+return true;var subRow=rows[n];var lastSliceInSubRow=subRow[subRow.length-1];if(sliceToPut.start>=lastSliceInSubRow.end){if(sliceToPut.subSlices===undefined||sliceToPut.subSlices.length===0){return true;}
+for(var i=0;i<sliceToPut.subSlices.length;i++){if(!findLevel(sliceToPut.subSlices[i],rows,n+1))
+return false;}
+return true;}
+return false;}
+var subRows=[];for(var i=0;i<slices.length;i++){var slice=slices[i];var found=false;var index=subRows.length;for(var j=0;j<subRows.length;j++){if(findLevel(slice,subRows,j)){found=true;index=j;break;}}
+if(!found)
+subRows.push([]);subRows[index].push(slice);var fitSubSlicesRecursively=function(subSlices,level,rows){if(subSlices===undefined||subSlices.length===0)
+return;if(level===rows.length)
+rows.push([]);for(var h=0;h<subSlices.length;h++){rows[level].push(subSlices[h]);fitSubSlicesRecursively(subSlices[h].subSlices,level+1,rows);}}
+fitSubSlicesRecursively(slice.subSlices,index+1,subRows);}
+return subRows;}};return{AsyncSliceGroupTrack:AsyncSliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack:SampleTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices){var precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)
+return[];var ops=[];for(var i=0;i<slices.length;i++){if(slices[i].subSlices)
+slices[i].subSlices.splice(0,slices[i].subSlices.length);ops.push(i);}
+ops.sort(function(ix,iy){var x=slices[ix];var y=slices[iy];if(x.start!=y.start)
+return x.start-y.start;return ix-iy;});var subRows=[[]];this.badSlices_=[];for(var i=0;i<ops.length;i++){var op=ops[i];var slice=slices[op];var inserted=false;for(var j=subRows.length-1;j>=0;j--){if(subRows[j].length==0)
+continue;var insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
+if(insertedSlice.bounds(slice,precisionUnit)){while(subRows.length<=j+1)
+subRows.push([]);subRows[j+1].push(slice);if(insertedSlice.subSlices)
+insertedSlice.subSlices.push(slice);inserted=true;break;}}
+if(inserted)
+continue;subRows[0].push(slice);}
+return subRows;}};return{SliceGroupTrack:SliceGroupTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('thread-track');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get eventContainer(){return this.thread;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_:function(){this.detach();if(!this.thread_)
+return;this.heading=this.thread_.userFriendlyName+': ';this.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length)
+this.appendAsyncSliceTracks_();this.appendThreadSamplesTracks_();if(this.thread_.timeSlices){var timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent)
+this.appendChild(timeSlicesTrack);}
+if(this.thread_.sliceGroup.length){var track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent)
+this.appendChild(track);}},appendAsyncSliceTracks_:function(){var subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){var asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);var title=subGroup.slices[0].viewSubGroupTitle;asyncTrack.group=subGroup;asyncTrack.heading=title;if(asyncTrack.hasVisibleContent)
+this.appendChild(asyncTrack);},this);},appendThreadSamplesTracks_:function(){var threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0)
+return;var samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
+samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
+return selection;};this.appendChild(samplesTrack);},this);},collapsedDidChange:function(collapsed){if(collapsed){var h=parseInt(this.tracks[0].height);for(var i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
+h=h*0.5;}}else{for(var i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack:ThreadTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;var ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;var SpacingTrack=tr.ui.tracks.SpacingTrack;var ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;this.classList.add('process-track-base');this.classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();this.processNameEl_.classList.add('process-track-name');this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});this.headerEl_.appendChild(this.processNameEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));this.appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){var modelSettings=new tr.model.ModelSettings(this.processBase_.model);var defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
+this.updateContents_();},get expanded(){return this.classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)
+return;this.classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)
+return;var modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get hasVisibleContent(){if(this.expanded)
+return this.children.length>1;return true;},onHeaderClick_:function(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},updateContents_:function(){this.clearTracks_();if(!this.processBase_)
+return;this.processNameEl_.textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
+this.didAppendTracks_();},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},willAppendTracks_:function(){},didAppendTracks_:function(){},appendMemoryDumpTrack_:function(){},appendSummaryTrack_:function(){var track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)
+return;this.appendChild(track);},appendFrameTrack_:function(){var frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)
+return;var track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;this.appendChild(track);this.backgroundProvider=track;},appendObjectInstanceTracks_:function(){var instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();var instanceTypeNames=tr.b.dictionaryKeys(instancesByTypeName);instanceTypeNames.sort();var didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){var allInstances=instancesByTypeName[typeName];var instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView)
+instanceViewInfo=undefined;if(snapshotViewInfo&&!snapshotViewInfo.metadata.showInTrackView)
+snapshotViewInfo=undefined;var hasViewInfo=instanceViewInfo||snapshotViewInfo;var visibleInstances=[];for(var i=0;i<allInstances.length;i++){var instance=allInstances[i];if(instance.snapshots.length===0)
+continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)
+continue;visibleInstances.push(instance);}
+if(visibleInstances.length===0)
+return;var trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
+var track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;this.appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack)
+this.appendChild(new SpacingTrack(this.viewport));},appendCounterTracks_:function(){var counters=tr.b.dictionaryValues(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){var track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_:function(){var threads=tr.b.dictionaryValues(this.processBase.threads);threads.sort(tr.model.Thread.compare);threads.forEach(function(thread){var track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)
+return;this.appendChild(track);this.appendChild(new SpacingTrack(this.viewport));}.bind(this));}};return{ProcessTrackBase:ProcessTrackBase};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)
+return false;var cpu=this.cpu_;if(cpu.slices.length)
+return true;if(cpu.samples&&cpu.samples.length)
+return true;if(tr.b.dictionaryLength(cpu.counters)>0)
+return true;return false;},updateContents_:function(){this.detach();if(!this.cpu_)
+return;var slices=this.cpu_.slices;if(slices.length){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';this.appendChild(track);}
+if(this.detailedMode_){this.appendSamplesTracks_();for(var counterName in this.cpu_.counters){var counter=this.cpu_.counters[counterName];track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
+counter.name+':';track.counter=counter;this.appendChild(track);}}},appendSamplesTracks_:function(){var samples=this.cpu_.samples;if(samples===undefined||samples.length===0)
+return;var samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined)
+samplesByTitle[sample.title]=[];samplesByTitle[sample.title].push(sample);});var sampleTitles=tr.b.dictionaryKeys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
+return selection;};this.appendChild(samplesTrack);},this);}};return{CpuTrack:CpuTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Cpu=tr.model.Cpu;var CpuTrack=tr.ui.tracks.cpu_track;var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var SpacingTrack=tr.ui.tracks.SpacingTrack;var KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_:function(){var cpus=tr.b.dictionaryValues(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);var didAppendAtLeastOneTrack=false;for(var i=0;i<cpus.length;++i){var cpu=cpus[i];var track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)
+continue;this.appendChild(track);didAppendAtLeastOneTrack=true;}
+if(didAppendAtLeastOneTrack)
+this.appendChild(new SpacingTrack(this.viewport));}};return{KernelTrack:KernelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.interactionRecords,{guid:tr.b.GUID.allocate(),model:model,getSettingsKey:function(){return undefined;}});},buildSubRows_:function(slices){if(this.subRows_.length)
+return this.subRows_;this.subRows_.push.apply(this.subRows_,tr.ui.tracks.AsyncSliceGroupTrack.prototype.buildSubRows_.call({},slices,true));return this.subRows_;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;this.appendChild(track);return track;}};return{InteractionTrack:InteractionTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)
+return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)
+return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});this.appendChild(track);}};return{ProcessMemoryDumpTrack:ProcessMemoryDumpTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack:function(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0)
+break;var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
+tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_:function(){var ctx=this.context();var canvasBounds=ctx.canvas.getBoundingClientRect();var pixelRatio=window.devicePixelRatio||1;var draw=false;ctx.fillStyle='#eee';for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack))
+continue;draw=!draw;if(!draw)
+continue;var bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_:function(){var processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){var pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;this.appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+var instantEventWidth=2*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack:ProcessTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.classList.add('model-track');var typeInfos=tr.ui.tracks.Highlighter.getAllRegisteredTypeInfos();this.highlighters_=typeInfos.map(function(typeInfo){return new typeInfo.constructor(viewport);});this.upperMode_=false;this.annotationViews_=[];},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach:function(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_:function(){this.textContent='';if(!this.model_)
+return;if(this.upperMode_)
+this.updateContentsForUpperMode_();else
+this.updateContentsForLowerMode_();},updateContentsForUpperMode_:function(){},updateContentsForLowerMode_:function(){if(this.model_.interactionRecords.length){var mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;this.appendChild(mrt);}
+if(this.model_.alerts.length){var at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;this.appendChild(at);}
+if(this.model_.globalMemoryDumps.length){var gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;this.appendChild(gmdt);}
+this.appendDeviceTrack_();this.appendKernelTrack_();var processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(var i=0;i<processes.length;++i){var process=processes[i];var track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)
+continue;this.appendChild(track);}
+this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].processModel(this.model_);}
+this.updateAnnotations_();},updateAnnotations_:function(){this.annotationViews_=[];var annotations=this.model_.getAllAnnotations();for(var i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
+this.invalidateDrawingContainer();},addEventsToTrackMap:function(eventToTrackMap){if(!this.model_)
+return;var tracks=this.children;for(var i=0;i<tracks.length;++i)
+tracks[i].addEventsToTrackMap(eventToTrackMap);if(this.instantEvents===undefined)
+return;var vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_:function(){var device=this.model.device;var track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)
+return;this.appendChild(track);},appendKernelTrack_:function(){var kernel=this.model.kernel;var track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)
+return;this.appendChild(track);},drawTrack:function(type){var ctx=this.context();if(!this.model_)
+return;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
+this.drawFlowArrows_(viewLWorld,viewRWorld);ctx.restore();return;case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.model_.instantEvents||this.model_.instantEvents.length===0)
+break;tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.model_.instantEvents,4);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(ctx,viewLWorld,viewRWorld);this.viewport.interestRange.drawIndicators(ctx,viewLWorld,viewRWorld);}
+ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:for(var i=0;i<this.highlighters_.length;i++){this.highlighters_[i].drawHighlight(ctx,dt,viewLWorld,viewRWorld,bounds.height);}
+ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(var i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
+ctx.restore();return;}
+ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_:function(viewLWorld,viewRWorld){var ctx=this.context();var dt=this.viewport.currentDisplayTransform;dt.applyTransformToCanvas(ctx);var pixWidth=dt.xViewVectorToWorld(1);ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=pixWidth>1.0?1:pixWidth;var events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);var onlyHighlighted=!this.viewport.showFlowEvents;var canvasBounds=ctx.canvas.getBoundingClientRect();for(var i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED)
+continue;this.drawFlowArrow_(ctx,events[i],canvasBounds,pixWidth);}},drawFlowArrow_:function(ctx,flowEvent,canvasBounds,pixWidth){var pixelRatio=window.devicePixelRatio||1;var startTrack=this.viewport.trackForEvent(flowEvent.startSlice);var endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)
+return;var startBounds=startTrack.getBoundingClientRect();var endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState==SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState==SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.2)';}else{var hasBoost=false;var startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;var endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle='rgba(255, 0, 0, 0.4)';}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.4)';}}
+var startSize=startBounds.left+startBounds.top+
+startBounds.bottom+startBounds.right;var endSize=endBounds.left+endBounds.top+
+endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)
+return;var startY=this.calculateTrackY_(startTrack,canvasBounds);var endY=this.calculateTrackY_(endTrack,canvasBounds);var pixelStartY=pixelRatio*startY;var pixelEndY=pixelRatio*endY;var half=(flowEvent.end-flowEvent.start)/2;ctx.beginPath();ctx.moveTo(flowEvent.start,pixelStartY);ctx.bezierCurveTo(flowEvent.start+half,pixelStartY,flowEvent.start+half,pixelEndY,flowEvent.end,pixelEndY);ctx.stroke();var arrowWidth=5*pixWidth*pixelRatio;var distance=flowEvent.end-flowEvent.start;if(distance<=(2*arrowWidth))
+return;var tipX=flowEvent.end;var tipY=pixelEndY;var arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},calculateTrackY_:function(track,canvasBounds){var bounds=track.getBoundingClientRect();var size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0)
+return this.calculateTrackY_(track.parentNode,canvasBounds);return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+var instantEventWidth=3*viewPixWidthWorld;tr.b.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack:ModelTrack};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RulerTrack=tr.ui.b.define('ruler-track',tr.ui.tracks.Track);var logOf10=Math.log(10);function log10(x){return Math.log(x)/logOf10;}
+RulerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('ruler-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);var heading=document.createElement('tr-ui-heading');heading.arrowVisible=false;this.appendChild(heading);},detach:function(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_:function(){if(this.viewport.interestRange.isEmpty)
+this.classList.remove('tall-mode');else
+this.classList.add('tall-mode');},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty)
+this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld);break;}},drawGrid_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var canvasBounds=ctx.canvas.getBoundingClientRect();var trackBounds=this.getBoundingClientRect();var width=canvasBounds.width*pixelRatio;var height=trackBounds.height*pixelRatio;var hasInterestRange=!this.viewport.interestRange.isEmpty;var rulerHeight=hasInterestRange?(height*2)/5:height;var vp=this.viewport;var dt=vp.currentDisplayTransform;var idealMajorMarkDistancePix=150*pixelRatio;var idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);var majorMarkDistanceWorld;var conservativeGuess=Math.pow(10,Math.ceil(log10(idealMajorMarkDistanceWorld)));var divisors=[10,5,2,1];for(var i=0;i<divisors.length;++i){var tightenedGuess=conservativeGuess/divisors[i];if(dt.xWorldVectorToView(tightenedGuess)<idealMajorMarkDistancePix)
+continue;majorMarkDistanceWorld=conservativeGuess/divisors[i-1];break;}
+var unit;var unitDivisor;var tickLabels=undefined;if(majorMarkDistanceWorld<0.0001){unit='ns';unitDivisor=0.000001;tickLabels=this.strings_nsecs_;}else if(majorMarkDistanceWorld<0.1){unit='us';unitDivisor=0.001;tickLabels=this.strings_usecs_;}else if(majorMarkDistanceWorld<100){unit='ms';unitDivisor=1;tickLabels=this.strings_msecs_;}else{unit='s';unitDivisor=1000;tickLabels=this.strings_secs_;}
+var numTicksPerMajor=5;var minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;var minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);var firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;var minorTickH=Math.floor(rulerHeight*0.25);ctx.save();var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);var crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';vp.majorMarkPositions=[];ctx.beginPath();for(var curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){var curXView=Math.floor(dt.xWorldToView(curX));var unitValue=curX/unitDivisor;var roundedUnitValue=Math.round(unitValue*100000)/100000;if(!tickLabels[roundedUnitValue])
+tickLabels[roundedUnitValue]=roundedUnitValue+' '+unit;ctx.fillText(tickLabels[roundedUnitValue],curXView+(2*pixelRatio),0);vp.majorMarkPositions.push(curXView);tr.ui.b.drawLine(ctx,curXView,0,curXView,rulerHeight);for(var i=1;i<numTicksPerMajor;++i){var xView=Math.floor(curXView+minorMarkDistancePx*i);tr.ui.b.drawLine(ctx,xView,rulerHeight-minorTickH,xView,rulerHeight);}}
+ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)
+return;tr.ui.b.drawLine(ctx,0,rulerHeight,width,rulerHeight);ctx.stroke();var displayDistance;var displayTextColor='rgb(0,0,0)';var arrowSpacing=10*pixelRatio;var arrowColor='rgb(128,121,121)';var arrowPosY=rulerHeight*1.75;var arrowWidthView=3*pixelRatio;var arrowLengthView=10*pixelRatio;var spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';var textPosY=arrowPosY;var interestRange=vp.interestRange;if(interestRange.range===0){var markerWorld=interestRange.min;var markerView=dt.xWorldToView(markerWorld);var displayValue=markerWorld/unitDivisor;displayValue=Math.abs((Math.round(displayValue*1000)/1000));var textToDraw=displayValue+' '+unit;var textLeftView=markerView+4*pixelRatio;var textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width)
+textLeftView=markerView-4*pixelRatio-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);return;}
+var leftMarker=interestRange.min;var rightMarker=interestRange.max;var leftMarkerView=dt.xWorldToView(leftMarker);var rightMarkerView=dt.xWorldToView(rightMarker);var distanceBetweenMarkers=interestRange.range;var distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);var positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);if(distanceBetweenMarkers<0.0001){unit='ns';unitDivisor=0.000001;}else if(distanceBetweenMarkers<0.1){unit='us';unitDivisor=0.001;}else if(distanceBetweenMarkers<100){unit='ms';unitDivisor=1;}else{unit='s';unitDivisor=1000;}
+displayDistance=distanceBetweenMarkers/unitDivisor;var roundedDisplayDistance=Math.abs((Math.round(displayDistance*1000)/1000));var textToDraw=roundedDisplayDistance+' '+unit;var textWidthView=ctx.measureText(textToDraw).width;var spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;var textLeftView=positionInMiddleOfMarkersView-textWidthView/2;var textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width)
+textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){var leftArrowStart;var rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
+ctx.strokeStyle=arrowColor;ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftArrowStart,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightArrowStart,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}
+ctx.restore();},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{RulerTrack:RulerTrack};});'use strict';Polymer('tr-ui-timeline-track-view',{ready:function(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrack_=new tr.ui.tracks.RulerTrack(this.viewport_);this.rulerTrackContainer_.appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;this.rulerTrackContainer_.appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);this.appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.modelTrackContainer_.appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));var m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},onSelectionChanged_:function(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach:function(){this.modelTrack_.detach();this.upperModelTrack_.detach();this.viewport_.detach();},get viewport(){return this.viewport_;},get model(){return this.model_;},set model(model){if(!model)
+throw new Error('Model cannot be undefined');var modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged)
+this.viewport_.setWhenPossible(this.setInitialViewport_.bind(this));},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},setInitialViewport_:function(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();var w=this.modelTrackContainer_.canvas.width;var min;var range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
+var boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var modelTrack=this.modelTrack_;var firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);var lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_:function(e){if(this.isZooming_)
+return;this.storeLastMousePos_(e);},onTouchStart_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_:function(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_:function(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKeys_:function(){var addBinding=function(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback:function(e){this.zoomBy_(1.5,true);e.stopPropagation();}});addBinding({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});addBinding({keyCode:'g'.charCodeAt(0),callback:function(e){this.onGridToggle_(true);e.stopPropagation();}});addBinding({keyCode:'G'.charCodeAt(0),callback:function(e){this.onGridToggle_(false);e.stopPropagation();}});addBinding({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback:function(e){this.zoomBy_(10,true);e.stopPropagation();}});addBinding({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/10,true);e.stopPropagation();}});addBinding({keyCode:'a'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});addBinding({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback:function(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});addBinding({keyCode:'A'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});addBinding({keyCode:'D'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});addBinding({keyCode:'0'.charCodeAt(0),callback:function(e){this.setInitialViewport_();e.stopPropagation();}});addBinding({keyCode:'f'.charCodeAt(0),callback:function(e){this.zoomToSelection();e.stopPropagation();}});addBinding({keyCode:'m'.charCodeAt(0),callback:function(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});addBinding({keyCode:'h'.charCodeAt(0),callback:function(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_:function(){var addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});},onDblClick_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
+return;var curSelection=this.brushingStateController_.selection;if(!curSelection.length||!curSelection[0].title)
+return;var selection=new tr.model.EventSet();var filter=new tr.c.ExactTitleFilter(curSelection[0].title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_:function(e){if(!e.altKey)
+return;var delta=e.wheelDelta/120;var zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION)
+return;if(e.target!==this.rulerTrack_)
+return;this.dragBeginEvent_=undefined;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+var dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)
+return;var relativePosition=this.extractRelativeMousePosition_(e);var loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)
+return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
+var state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_:function(viewDeltaX,deltaY){var deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_:function(scale,smooth){if(scale<=0){return;}
+smooth=!!smooth;var vp=this.viewport_;var pixelRatio=window.devicePixelRatio||1;var goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;var goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
+return;var bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)
+return;var worldCenter=bounds.center;var viewCenter=this.modelTrackContainer_.canvas.width/2;var adjustedWorldRange=bounds.range*1.25;var newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;var zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)
+return;var bounds=this.brushingStateController.selectionOfInterest.bounds;var worldCenter=bounds.center;var viewWidth=this.viewWidth_;var dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
+return;}
+this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition:function(uiState,showNavLine){var location=uiState.location;var scaleX=uiState.scaleX;var track=location.getContainingTrack(this.viewport_);var worldCenter=location.xWorld;var viewCenter=this.modelTrackContainer_.canvas.width/5;var zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)
+return;if(this.xNavStringMarker_)
+this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},setCurrentSelectionAsInterestRange_:function(){var selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
+if(this.viewport_.interestRange.min==selectionBounds.min&&this.viewport_.interestRange.max==selectionBounds.max)
+this.viewport_.interestRange.reset();else
+this.viewport_.interestRange.set(selectionBounds);},toggleHighDetails_:function(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_:function(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_:function(xStart,yStart,xEnd,yEnd){var loY=Math.min(yStart,yEnd);var hiY=Math.max(yStart,yEnd);var loX=Math.min(xStart,xEnd);var hiX=Math.max(xStart,xEnd);var modelTrackRect=this.modelTrack_.getBoundingClientRect();var dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;var modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();var clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};var headingWidth=window.getComputedStyle(this.querySelector('tr-ui-heading')).width;var trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;var intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top)
+return false;var results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;}
+var finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';var pixelRatio=window.devicePixelRatio||1;var canv=this.modelTrackContainer_.canvas;var dt=this.viewport_.currentDisplayTransform;var loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);var hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);this.$.drag_box.textContent=tr.b.u.TimeDuration.format(hiWX-loWX);var e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_:function(left){var selection=this.brushingStateController_.selection;var tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
+var numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
+(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_:function(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_:function(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_:function(e){var canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_:function(e){var canv=this.modelTrackContainer_.canvas;var touches=[];for(var i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
+return touches;},storeInitialMouseDownPos_:function(e){var position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_:function(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_:function(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_:function(e){var vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_:function(e){if(!this.isPanningAndScanning_)
+return;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
+this.mouseViewPosAtMouseDown_.x);var yDelta=this.lastMouseViewPos_.y-
+this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_:function(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick)
+e.preventDefault();},onBeginSelection_:function(e){var canv=this.modelTrackContainer_.canvas;var rect=this.modelTrack_.getBoundingClientRect();var canvRect=canv.getBoundingClientRect();var inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)
+return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_:function(e){if(!this.dragBeginEvent_)
+return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_:function(e){e.preventDefault();if(!this.dragBeginEvent_)
+return;this.hideDragBox_();var eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;var loY=Math.min(eDown.clientY,e.clientY);var hiY=Math.max(eDown.clientY,e.clientY);var loX=Math.min(eDown.clientX,e.clientX);var hiX=Math.max(eDown.clientX,e.clientX);var canv=this.modelTrackContainer_.canvas;var worldOffset=canv.getBoundingClientRect().left;var loVX=loX-worldOffset;var hiVX=hiX-worldOffset;var selection=new tr.model.EventSet();if(eDown.appendSelection){var previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined)
+selection.addEventSet(previousSelection);}
+this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_:function(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
+return;var newPosition=this.extractRelativeMousePosition_(e);var zoomScaleValue=1+(this.lastMouseViewPos_.y-
+newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_:function(e){this.isZooming_=false;if(!e.isClick)
+e.preventDefault();},computeTouchCenter_:function(positions){var xSum=0;var ySum=0;for(var i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
+return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_:function(positions){var xMin=Number.MAX_VALUE;var yMin=Number.MAX_VALUE;var xMax=Number.MIN_VALUE;var yMax=Number.MIN_VALUE;for(var i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
+return Math.sqrt((xMin-xMax)*(xMin-xMax)+
+(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_:function(e){var newPositions=this.extractRelativeTouchPositions_(e);var currentPositions=this.lastTouchViewPositions_;var newCenter=this.computeTouchCenter_(newPositions);var currentCenter=this.computeTouchCenter_(currentPositions);var newSpan=this.computeTouchSpan_(newPositions);var currentSpan=this.computeTouchSpan_(currentPositions);var vp=this.viewport_;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDelta=pixelRatio*(newCenter.x-currentCenter.x);var yDelta=newCenter.y-currentCenter.y;var zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;var viewFocus=pixelRatio*newCenter.x;var worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_:function(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_:function(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
+this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);this.$.hint_text.textContent=text;this.$.hint_text.style.display='';},hideHintText_:function(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer('tr-ui-find-control',{filterKeyDown:function(e){if(e.keyCode===27){var hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
+e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey)
+this.findPrevious();else
+this.findNext();}},filterBlur:function(e){this.updateHitCountEl();},filterFocus:function(e){this.$.filter.select();},filterMouseUp:function(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus:function(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged:function(){this.$.hitCount.textContent='';this.$.spinner.style.visibility='visible';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.updateHitCountEl();}.bind(this));},findNext:function(){if(this.controller)
+this.controller.findNext();this.updateHitCountEl();},findPrevious:function(){if(this.controller)
+this.controller.findPrevious();this.updateHitCountEl();},updateHitCountEl:function(){if(!this.controller||!this.hasFocus){this.$.hitCount.textContent='';return;}
+var n=this.controller.filterHits.length;var i=n===0?-1:this.controller.currentHitIndex;this.$.hitCount.textContent=(i+1)+' of '+n;},setText:function(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
+Context.prototype={push:function(event){var ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop:function(event){var ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context:Context};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
+Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)=='string'||filterExpression instanceof RegExp){var filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
+return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate:function(context){throw new Error('Not implemented');},matchValue_:function(value,expected){if(expected instanceof RegExp)
+return expected.test(value);else if(expected instanceof Function)
+return expected(value);return value===expected;}};return{Filter:Filter};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAllOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
+FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
+return true;for(var i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context))
+return false;}
+return true;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
+return new FilterAllOf(exprs);},{name:'allOf'});return{FilterAllOf:FilterAllOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAnyOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];};FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)
+return true;for(var i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))
+return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
+return new FilterAnyOf(exprs);},{name:'anyOf'});return{FilterAnyOf:FilterAnyOf};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;};FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(!this.subExpression)
+return context.ancestors.length>0;while(context.ancestors.length){context=context.pop();if(this.subExpression.evaluate(context))
+return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterHasAncestor(subExpression);},{name:'hasAncestor'});return{FilterHasAncestor:FilterHasAncestor};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasDuration(minValueOrExpected,opt_maxValue){if(minValueOrExpected!==undefined&&opt_maxValue!==undefined){this.minValue=minValueOrExpected;this.maxValue=opt_maxValue;}else{this.expected=minValueOrExpected;}};FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){if(context.event.duration===undefined)
+return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
+return this.matchValue_(context.event.duration,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(minValueOrExpected,opt_maxValue){return new FilterHasDuration(minValueOrExpected,opt_maxValue);},{name:'hasDuration'});return{FilterHasDuration:FilterHasDuration};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasTitle(expected){tr.e.tquery.Filter.call(this);this.expected=expected;}
+FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){var filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle:FilterHasTitle};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
+FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(context.ancestors.length>0)
+return false;if(!this.subExpression)
+return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel:FilterIsTopLevel};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)
+return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
+function TQuery(model){tr.c.ScriptingObject.call(this);this.model_=model;this.parent_=undefined;this.filterExpression_=undefined;this.selection_=undefined;};TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged:function(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter:function(filterExpression){var result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_:function(){var nodes=[];var node=this;while(node!==undefined){nodes.push(node);node=node.parent_;}
+var rootTask=new tr.b.Task();var lastTask=rootTask;for(var i=nodes.length-1;i>=0;i--){var node=nodes[i];if(node.selection_!==undefined)
+continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{var prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
+return{rootTask:rootTask,lastTask:lastTask,lastNode:node};},createFilterTaskForNode_:function(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_:function(inputSelection,outputSelection){var seenEvents={};inputSelection.forEach(function(event){var context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_:function(context,inputSelection,outputSelection,seenEvents){var event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context))
+outputSelection.push(event);}
+if(!event.subSlices)
+return;context=context.push(event);for(var i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_:function(selection){var filterTask=new tr.b.Task();this.model_.iterateAllEventContainers(function(container){filterTask.subTask(function(){container.iterateAllEventsInThisContainer(function(){return true;},addEventTreeToSelection.bind(undefined,selection));},this);},this);return filterTask;},ready:function(){return new Promise(function(resolve,reject){var graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){var graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
+return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery:TQuery};});'use strict';Polymer('tr-ui-scripting-control',{_isEnterKey:function(event){return event.keyCode!==229&&event.keyIdentifier==='Enter';},_setFocused:function(focused){var promptEl=this.$.prompt;if(focused){promptEl.focus();this.$.root.classList.add('focused');if(promptEl.innerText.length>0){var sel=window.getSelection();sel.collapse(promptEl.firstChild,promptEl.innerText.length);}}else{promptEl.blur();this.$.root.classList.remove('focused');var parent=promptEl.parentElement;var nextEl=promptEl.nextSibling;promptEl.remove();parent.insertBefore(promptEl,nextEl);}},onConsoleFocus:function(e){e.stopPropagation();this._setFocused(true);},onConsoleBlur:function(e){e.stopPropagation();this._setFocused(false);},promptKeyDown:function(e){e.stopPropagation();if(!this._isEnterKey(e))
+return;var promptEl=this.$.prompt;var command=promptEl.innerText;if(command.length===0)
+return;promptEl.innerText='';this.addLine_(String.fromCharCode(187)+' '+command);try{var result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
+if(result instanceof tr.e.tquery.TQuery){result.ready().then(function(selection){this.addLine_(selection.length+' matches');this.controller_.brushingStateController.showScriptControlSelection(selection);}.bind(this));}else{this.addLine_(result);}},addLine_:function(line){var historyEl=this.$.history;if(historyEl.innerText.length!==0)
+historyEl.innerText+='\n';historyEl.innerText+=line;},promptKeyPress:function(e){e.stopPropagation();},toggleVisibility:function(){var root=this.$.root;if(!this.visible){root.classList.remove('hidden');this._setFocused(true);}else{root.classList.add('hidden');this._setFocused(false);}},get hasFocus(){return this===document.activeElement;},get visible(){var root=this.$.root;return!root.classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer('tr-ui-side-panel',{ready:function(){},get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},get listeningToKeys(){throw new Error('Not implemented');},supportsModel:function(m){throw new Error('Not implemented');}});'use strict';Polymer('tr-ui-side-panel-container',{ready:function(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.rangeOfInterest_=new tr.b.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);}},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(){if(this.activePanel)
+this.activePanel.selection=this.selection;},get model(){return this.brushingStateController_.model;},onModelChanged_:function(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){if(this.activePanelContainer_.children.length===0)
+return undefined;return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined)
+throw new Error('Cannot activate panel without a model');var panel=undefined;if(panelType)
+panel=document.createElement(panelType);if(panel!==undefined&&!panel.supportsModel(this.model))
+throw new Error('Cannot activate panel: does not support this model');if(this.activePanelType){this.getLabelElementForPanelType_(this.activePanelType).removeAttribute('selected');}
+this.activePanelContainer_.textContent='';if(panelType===undefined){this.removeAttribute('expanded');this.activePanelType_=undefined;return;}
+this.getLabelElementForPanelType_(panelType).setAttribute('selected',true);this.setAttribute('expanded',true);this.activePanelContainer_.appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_:function(constructor){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor==constructor)
+return this.tabStrip_.children[i].panelType;}},getLabelElementForPanelType_:function(panelType){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType==panelType)
+return this.tabStrip_.children[i];}
+return undefined;},updateContents_:function(){var previouslyActivePanelType=this.activePanelType;this.tabStrip_.textContent='';var supportedPanelTypes=[];var panelTypes=tr.ui.b.getPolymerElementsThatSubclass('tr-ui-side-panel');panelTypes.forEach(function(panelType){var labelEl=document.createElement('tab-strip-label');var panel=document.createElement(panelType);labelEl.textContent=panel.textLabel;labelEl.panelType=panelType;var supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);labelEl.setAttribute('enabled',true);labelEl.addEventListener('click',function(){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this));}else{labelEl.title='Not supported for the current trace: '+
+supported.reason;labelEl.style.display='none';}
+this.tabStrip_.appendChild(labelEl);},this);if(previouslyActivePanelType&&supportedPanelTypes.indexOf(previouslyActivePanelType)!=-1){this.activePanelType=previouslyActivePanelType;this.setAttribute('expanded',true);}else{this.activePanelContainer_.textContent='';this.removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range==undefined)
+throw new Error('Must not be undefined');this.rangeOfInterest_=range;if(this.activePanel)
+this.activePanel.rangeOfInterest=range;}});'use strict';Polymer('tr-ui-timeline-view-help-overlay',{ready:function(){var mod=tr.isMac?'cmd ':'ctrl';var spans=this.shadowRoot.querySelectorAll('span.mod');for(var i=0;i<spans.length;i++){spans[i].textContent=mod;}}});'use strict';tr.exportTo('tr.b.u',function(){function GenericTable(items){if(items!==undefined)
+this.items=items;else
+this.items=[];};GenericTable.prototype={};return{GenericTable:GenericTable};});'use strict';tr.exportTo('tr.ui.units',function(){var ArrayOfNumbersSummaryModes={AVERAGE_MODE:'average-mode',TOTAL_MODE:'total-mode'};return{ArrayOfNumbersSummaryModes:ArrayOfNumbersSummaryModes};});'use strict';Polymer('tr-ui-u-array-of-numbers-span',{created:function(){this.numbers_=undefined;this.summaryMode_=tr.ui.units.ArrayOfNumbersSummaryModes.AVERAGE_MODE;},get summaryMode(){return this.summaryMode_;},set summaryMode(summaryMode){this.summaryMode_=summaryMode;this.updateContents_();},get numbers(){return this.numbers_;},set numbers(numbers){if(numbers===undefined){this.numbers_=undefined;this.updateContents_();return;}
+if(!(numbers instanceof Array))
+throw new Error('Must provide an array');this.numbers_=numbers;this.updateContents_();},updateContents_:function(){if(this.numbers_===undefined){this.shadowRoot.textContent='-';return;}
+var ArrayOfNumbersSummaryModes=tr.ui.units.ArrayOfNumbersSummaryModes;var value;if(this.summaryMode_===ArrayOfNumbersSummaryModes.AVERAGE_MODE)
+value=tr.b.Statistics.mean(this.numbers_);else
+value=tr.b.Statistics.sum(this.numbers_);var valueRounded=Math.round(value*1000.0)/1000.0;this.shadowRoot.textContent=valueRounded;}});'use strict';tr.exportTo('tr.ui.units',function(){var TEXT_COLUMN_MODE=1;var NUMERIC_COLUMN_MODE=2;var ELEMENT_COLUMN_MODE=3;function isNumeric(value){if((typeof value)==='number')
+return true;else if(value instanceof Number)
+return true;return false;}
+function GenericTableViewTotalsItem(opt_values){if(opt_values!==undefined)
+this.values=opt_values;else
+this.values=[];}
+function GenericTableViewColumnDescriptor(fieldName,firstFieldValue){this.title=fieldName;this.fieldName=fieldName;this.updateModeGivenValue(firstFieldValue);}
+GenericTableViewColumnDescriptor.prototype={get columnMode(){return this.columnMode_;},get isInNumericMode(){return this.columnMode_===NUMERIC_COLUMN_MODE;},cmp:function(a,b){if(this.columnMode_===ELEMENT_COLUMN_MODE)
+return 0;return tr.b.comparePossiblyUndefinedValues(a,b,function(a,b){var vA=a[this.fieldName];var vB=b[this.fieldName];return tr.b.comparePossiblyUndefinedValues(vA,vB,function(vA,vB){if(vA.localeCompare)
+return vA.localeCompare(vB);return vA-vB;},this);},this);},updateModeGivenValue:function(fieldValue){if(this.columnMode_===undefined){if(fieldValue===undefined||fieldValue===null)
+return;if(isNumeric(fieldValue)){this.columnMode_=NUMERIC_COLUMN_MODE;return;}
+if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
+this.columnMode_=TEXT_COLUMN_MODE;return;}
+if(fieldValue===undefined||fieldValue===null)
+return;if(isNumeric(fieldValue))
+return;if(fieldValue instanceof HTMLElement){this.columnMode_=ELEMENT_COLUMN_MODE;return;}
+if(this.columnMode_===NUMERIC_COLUMN_MODE)
+this.columnMode_=TEXT_COLUMN_MODE;},value:function(item){var fieldValue=item[this.fieldName];if(fieldValue instanceof GenericTableViewTotalsItem){var span=document.createElement('tr-ui-u-array-of-numbers-span');span.summaryMode=tr.ui.units.ArrayOfNumbersSummaryModes.TOTAL_MODE;span.numbers=fieldValue.values;return span;}
+if(fieldValue===undefined)
+return'-';if(fieldValue instanceof HTMLElement)
+return fieldValue;if(fieldValue instanceof Object){var gov=document.createElement('tr-ui-a-generic-object-view');gov.object=fieldValue;return gov;}
+return fieldValue;}};Polymer('tr-ui-u-generic-table-view',{created:function(){this.items_=undefined;this.importantColumNames_=[];},get items(){return this.items_;},set items(itemsOrGenericTable){if(itemsOrGenericTable===undefined){this.items_=undefined;}else if(itemsOrGenericTable instanceof Array){this.items_=itemsOrGenericTable;}else if(itemsOrGenericTable instanceof tr.b.u.GenericTable){this.items_=itemsOrGenericTable.items;}
+this.updateContents_();},get importantColumNames(){return this.importantColumNames_;},set importantColumNames(importantColumNames){this.importantColumNames_=importantColumNames;this.updateContents_();},createColumns_:function(){var columnsByName={};this.items_.forEach(function(item){tr.b.iterItems(item,function(itemFieldName,itemFieldValue){var colDesc=columnsByName[itemFieldName];if(colDesc!==undefined){colDesc.updateModeGivenValue(itemFieldValue);return;}
+colDesc=new GenericTableViewColumnDescriptor(itemFieldName,itemFieldValue);columnsByName[itemFieldName]=colDesc;},this);},this);var columns=tr.b.dictionaryValues(columnsByName);if(columns.length===0)
+return undefined;var isColumnNameImportant={};var importantColumNames=this.importantColumNames||[];importantColumNames.forEach(function(icn){isColumnNameImportant[icn]=true;});columns.sort(function(a,b){var iA=isColumnNameImportant[a.title]?1:0;var iB=isColumnNameImportant[b.title]?1:0;if((iB-iA)!==0)
+return iB-iA;return a.title.localeCompare(b.title);});var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';columns[0].width='250px';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;return columns;},createFooterRowsIfNeeded_:function(columns){var hasColumnThatIsNumeric=columns.some(function(column){return column.isInNumericMode;});if(!hasColumnThatIsNumeric)
+return[];var totalsItems={};columns.forEach(function(column){if(!column.isInNumericMode)
+return;var totalsItem=new GenericTableViewTotalsItem();this.items_.forEach(function(item){var fieldValue=item[column.fieldName];if(fieldValue===undefined||fieldValue===null)
+return;totalsItem.values.push(fieldValue);});totalsItems[column.fieldName]=totalsItem;},this);return[totalsItems];},updateContents_:function(){var columns;if(this.items_!==undefined)
+columns=this.createColumns_();if(!columns){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.footerRows=[];return;}
+this.$.table.tableColumns=columns;this.$.table.tableRows=this.items_;this.$.table.footerRows=this.createFooterRowsIfNeeded_(columns);this.$.table.rebuild();},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;}});return{GenericTableViewTotalsItem:GenericTableViewTotalsItem,GenericTableViewColumnDescriptor:GenericTableViewColumnDescriptor};});'use strict';Polymer('tr-ui-timeline-view-metadata-overlay',{created:function(){this.metadata_=undefined;},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.gtv.items=this.metadata_;}});'use strict';Polymer('tr-ui-u-preferred-display-unit',{ready:function(){this.preferredTimeDisplayMode_=undefined;},attached:function(){tr.b.u.Units.didPreferredTimeDisplayUnitChange();},detached:function(){tr.b.u.Units.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)
+return;this.preferredTimeDisplayMode_=v;tr.b.u.Units.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer('tr-ui-timeline-view',{ready:function(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.e&&window.tr.e.rail&&window.tr.e.rail.RAILScore){this.railScoreSpan_=document.createElement('tr-ui-e-rail-rail-score-span');this.rightControls.appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
+this.optionsDropdown_=this.$.view_options_dropdown;this.optionsDropdown_.iconElement.textContent='View Options';this.showFlowEvents_=false;this.optionsDropdown_.appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');this.optionsDropdown_.appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();this.collapsingControls.appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;tr.ui.b.decorate(this.dragEl_,tr.ui.b.DragHandle);this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){var sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},domReady:function(){this.trackViewContainer_=this.querySelector('#track_view_container');},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon:function(){var hue;if(!this.model)
+hue='blue';else
+hue=this.model.faviconHue;var faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined)
+faviconData=tr.ui.b.FaviconsByHue['blue'];var link=document.head.querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';document.head.appendChild(link);}
+link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)
+return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)
+return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_:function(){var helpButtonEl=this.$.view_help_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));dlg.visible=true;e.stopPropagation();}
+helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_:function(){var toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
+toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_:function(){var showEl=this.$.view_metadata_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';var metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;dlg.appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
+showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_:function(){var showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return this.titleEl_.textContent.substring(this.titleEl_.textContent.length-2);},set viewTitle(text){if(text===undefined){this.titleEl_.textContent='';this.titleEl_.hidden=true;return;}
+this.titleEl_.hidden=false;this.titleEl_.textContent=text;},get model(){if(this.trackView_)
+return this.trackView_.model;return undefined;},set model(model){var modelInstanceChanged=model!=this.model;var modelValid=model&&!model.bounds.isEmpty;var importWarningsEl=this.shadowRoot.querySelector('#import-warnings');importWarningsEl.textContent='';if(modelInstanceChanged){if(this.railScoreSpan_)
+this.railScoreSpan_.railScore=undefined;this.trackViewContainer_.textContent='';if(this.trackView_){this.trackView_.viewport.removeEventListener('change',this.onViewportChanged_);this.trackView_.brushingStateController=undefined;this.trackView_.detach();this.trackView_=undefined;}
+this.brushingStateController_.modelWillChange();}
+if(modelValid&&!this.trackView_){this.trackView_=document.createElement('tr-ui-timeline-track-view');this.trackView_.timelineView=this;this.trackView.brushingStateController=this.brushingStateController_;this.trackViewContainer_.appendChild(this.trackView_);this.trackView_.viewport.addEventListener('change',this.onViewportChanged_);}
+if(modelValid){this.trackView_.model=model;this.trackView_.viewport.showFlowEvents=this.showFlowEvents;this.trackView_.viewport.highlightVSync=this.highlightVSync;if(this.railScoreSpan_){var railScore=tr.e.rail.RAILScore.fromModel(model);this.railScoreSpan_.railScore=railScore;}
+this.$.display_unit.preferredTimeDisplayMode=model.intrinsicTimeUnit;}
+if(model){model.importWarningsThatShouldBeShownToUser.forEach(function(importWarning){importWarningsEl.addMessage('Import Warning: '+importWarning.type+': '+
+importWarning.message);},this);}
+if(modelInstanceChanged){this.updateMetadataButtonVisibility_();this.brushingStateController_.modelDidChange();this.onViewportChanged_();}},get brushingStateController(){return this.brushingStateController_;},get trackView(){return this.trackView_;},get settings(){if(!this.settings_)
+this.settings_=new tr.b.Settings();return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_:function(){var hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus)
+this.focus();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){if(this.scriptingCtl_.hasFocus)
+return;if(this.findCtl_.hasFocus)
+this.focus();else
+this.findCtl_.focus();e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_:function(e){var spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
+var vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr))
+spc.rangeOfInterest=vr;},toggleHighlightVSync_:function(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText:function(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.e.cc',function(){function PictureAsImageData(picture,errorOrImageData){this.picture_=picture;if(errorOrImageData instanceof ImageData){this.error_=undefined;this.imageData_=errorOrImageData;}else{this.error_=errorOrImageData;this.imageData_=undefined;}};PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending:function(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas:function(){if(!this.imageData_)
+return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData:PictureAsImageData};});'use strict';tr.exportTo('tr.e.cc',function(){var convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache)
+return convertedNameCache[name];if(name[0]=='_'||name[name.length-1]=='_'){convertedNameCache[name]=name;return name;}
+var words=name.split('_');if(words.length==1){convertedNameCache[name]=words[0];return words[0];}
+for(var i=1;i<words.length;i++)
+words[i]=words[i][0].toUpperCase()+words[i].substring(1);convertedNameCache[name]=words.join('');return convertedNameCache[name];}
+function convertObjectFieldNamesToJSConventions(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){delete object[fieldName];object[newFieldName]=fieldValue;return newFieldName;});}
+function convertQuadSuffixedTypesToQuads(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){});}
+function convertObject(object){convertObjectFieldNamesToJSConventions(object);convertQuadSuffixedTypesToQuads(object);}
+function moveRequiredFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
+throw Error('Expected field '+key+' not found in args');if(object[key]!==undefined)
+throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
+function moveOptionalFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)
+continue;if(object[key]!==undefined)
+throw Error('Field '+key+' already in object');object[key]=object.args[key];delete object.args[key];}}
+function preInitializeObject(object){preInitializeObjectInner(object.args,false);}
+function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))
+return;if(object instanceof Array){for(var i=0;i<object.length;i++)
+preInitializeObjectInner(object[i],true);return;}
+if(hasRecursed&&(object instanceof tr.model.ObjectSnapshot||object instanceof tr.model.ObjectInstance))
+return;for(var key in object){var newKey=convertNameToJSConvention(key);if(newKey!=key){var value=object[key];delete object[key];object[newKey]=value;key=newKey;}
+if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.Quad)){var q;try{q=tr.b.Quad.from8Array(object[key]);}catch(e){console.log(e);}
+object[key]=q;continue;}
+if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.Rect)){var r;try{r=tr.b.Rect.fromArray(object[key]);}catch(e){console.log(e);}
+object[key]=r;}
+preInitializeObjectInner(object[key],true);}}
+function bytesToRoundedMegabytes(bytes){return Math.round(bytes/100000.0)/10.0;}
+return{preInitializeObject:preInitializeObject,convertNameToJSConvention:convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel:moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel:moveOptionalFieldsFromArgsToToplevel,bytesToRoundedMegabytes:bytesToRoundedMegabytes};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var PictureCount=0;var OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocate();}
+Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){return this.skp64_;},getOps:function(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+var ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops)
+console.error('Failed to get picture ops.');return ops;},getOpTimings:function(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+var opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings)
+console.error('Failed to get picture op timings.');return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
+return ops;if(opTimings[iteration].cmd_times.length!=ops.length)
+return ops;}
+for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
+min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
+return ops;},rasterize:function(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
+var raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;var imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{var error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocate();this.pictures_=pictures;this.layerRect_=undefined;}
+LayeredPicture.prototype={__proto__:Picture.prototype,get canSave(){return false;},get typeName(){return'cc::LayeredPicture';},get layerRect(){if(this.layerRect_!==undefined)
+return this.layerRect_;this.layerRect_={x:0,y:0,width:0,height:0};for(var i=0;i<this.pictures_.length;++i){var rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
+return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){throw new Error('Not available with a LayeredPicture.');},getOps:function(){var ops=[];for(var i=0;i<this.pictures_.length;++i)
+ops=ops.concat(this.pictures_[i].getOps());return ops;},getOpTimings:function(){var opTimings=this.pictures_[0].getOpTimings();for(var i=1;i<this.pictures_.length;++i){var timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
+return opTimings;},tagOpsWithTimings:function(ops){var opTimings=new Array();for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times)
+return ops;}
+for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++)
+min=Math.min(min,opTimings[i].cmd_times[opIndex]);ops[opIndex].cmd_time=min;}
+return ops;},rasterize:function(params,rasterCompleteCallback){this.picturesAsImageData_=[];var rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length)
+return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(var i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
+this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(var i=0;i<this.pictures_.length;++i)
+this.pictures_[i].rasterize(params,rasterCallback);}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
+PictureSnapshot.HasSkiaBenchmarking=function(){return tr.isExported('chrome.skiaBenchmarking');}
+PictureSnapshot.CanRasterize=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.rasterize)
+return false;return true;}
+PictureSnapshot.CanGetOps=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.getOps)
+return false;return true;}
+PictureSnapshot.CanGetOpTimings=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.getOpTimings)
+return false;return true;}
+PictureSnapshot.CanGetInfo=function(){if(!PictureSnapshot.HasSkiaBenchmarking())
+return false;if(!window.chrome.skiaBenchmarking.getInfo)
+return false;return true;}
+PictureSnapshot.HowToEnablePictureDebugging=function(){if(tr.isHeadless)
+return'Pictures only work in chrome';var usualReason=['For pictures to show up, you need to have Chrome running with ','--enable-skia-benchmarking. Please restart chrome with this flag ','and try again.'].join('');if(!tr.isExported('global.chrome.skiaBenchmarking'))
+return usualReason;if(!global.chrome.skiaBenchmarking.rasterize)
+return'Your chrome is old';if(!global.chrome.skiaBenchmarking.getOps)
+return'Your chrome is old: skiaBenchmarking.getOps not found';if(!global.chrome.skiaBenchmarking.getOpTimings)
+return'Your chrome is old: skiaBenchmarking.getOpTimings not found';if(!global.chrome.skiaBenchmarking.getInfo)
+return'Your chrome is old: skiaBenchmarking.getInfo not found';return'Rasterizing is on';}
+PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize:function(){if(this.args.alias)
+this.args=this.args.alias.args;if(!this.args.params.layerRect)
+throw new Error('Missing layer rect');this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData:function(){return this.picture_.getBase64SkpData();},getOps:function(){return this.picture_.getOps();},getOpTimings:function(){return this.picture_.getOpTimings();},tagOpsWithTimings:function(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize:function(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot:PictureSnapshot,Picture:Picture,LayeredPicture:LayeredPicture};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
+DisplayItemList.prototype={__proto__:tr.e.cc.Picture.prototype};function DisplayItemListSnapshot(){tr.e.cc.PictureSnapshot.apply(this,arguments);}
+DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize:function(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot:DisplayItemListSnapshot,DisplayItemList:DisplayItemList};});'use strict';tr.exportTo('tr.e.cc',function(){var constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants:constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
+Region.fromArray=function(array){if(array.length%4!=0)
+throw new Error('Array must consist be a multiple of 4 in length');var r=new Region();for(var i=0;i<array.length;i+=4){r.rects.push(tr.b.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
+return r;}
+Region.fromArrayOrUndefined=function(array){if(array===undefined)
+return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects:function(r){for(var i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))
+return true;}
+return false;},addRect:function(r){this.rects.push(r);}};return{Region:Region};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
+return{TileCoverageRect:TileCoverageRect};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize:function(){this.invalidation=new tr.e.cc.Region();this.annotatedInvalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','children','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
+for(var i=0;i<this.children.length;i++)
+this.children[i].parentLayer=this;if(this.maskLayer)
+this.maskLayer.parentLayer=this;if(this.replicaLayer)
+this.replicaLayer.parentLayer=this;if(!this.geometryContentsScale)
+this.geometryContentsScale=1.0;if(!this.idealContentsScale)
+this.idealContentsScale=1.0;this.touchEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.touchEventHandlerRegion);this.wheelEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.wheelEventHandlerRegion);this.nonFastScrollableRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.nonFastScrollableRegion);},get layerTreeImpl(){if(this.layerTreeImpl_)
+return this.layerTreeImpl_;if(this.parentLayer)
+return this.parentLayer.layerTreeImpl;return undefined;},set layerTreeImpl(layerTreeImpl){this.layerTreeImpl_=layerTreeImpl;},get activeLayer(){if(this.layerTreeImpl.whichTree==constants.ACTIVE_TREE)
+return this;var activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree==constants.PENDING_TREE)
+return this;var pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
+PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize:function(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);delete this.args.invalidation;}
+if(this.args.annotatedInvalidationRects){this.annotatedInvalidation=new tr.e.cc.Region();for(var i=0;i<this.args.annotatedInvalidationRects.length;++i){var annotatedRect=this.args.annotatedInvalidationRects[i];var rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;this.annotatedInvalidation.addRect(rect);}
+delete this.args.annotatedInvalidationRects;}
+if(this.args.unrecordedRegion){this.unrecordedRegion=tr.e.cc.Region.fromArray(this.args.unrecordedRegion);delete this.args.unrecordedRegion;}
+if(this.args.pictures){this.pictures=this.args.pictures;this.pictures.sort(function(a,b){return a.ts-b.ts;});}
+this.tileCoverageRects=[];if(this.args.coverageTiles){for(var i=0;i<this.args.coverageTiles.length;++i){var rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);var tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
+delete this.args.coverageTiles;}}};ObjectSnapshot.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot:LayerImplSnapshot,PictureLayerImplSnapshot:PictureLayerImplSnapshot};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['rootLayer','renderSurfaceLayerList']);if(this.args.sourceFrameNumber)
+this.sourceFrameNumber=this.args.sourceFrameNumber;this.rootLayer.layerTreeImpl=this;if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];var ownProcess=this.objectInstance.parent;var model=ownProcess.model;if(tr.e.audits.ChromeModelHelper.supportsModel(model))
+this._initializeTracedInputLatencies(model);}},_initializeTracedInputLatencies:function(model){var modelHelper=new tr.e.audits.ChromeModelHelper(model);if(!modelHelper.browserHelper)
+return;var latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(model.bounds);latencyEvents.forEach(function(event){for(var i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id)
+continue;if(parseInt(event.args.data.trace_id)===this.args.swapPromiseTraceIds[i])
+this.tracedInputLatencies.push(event);}},this);},get hasSourceFrameBeenDrawnBefore(){if(this.whichTree==tr.e.cc.constants.PENDING_TREE)
+return false;if(this.sourceFrameNumber===undefined)
+return;var thisLTHI=this.layerTreeHostImpl;var thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);var prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length)
+return false;var prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)
+return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)
+return;return prevLTHI.activeTree.sourceFrameNumber==this.sourceFrameNumber;},get otherTree(){var other=this.whichTree==constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){var totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined)
+totalBytes+=layer.gpuMemoryUsageInBytes;});return totalBytes;},iterLayers:function(func,thisArg){var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
+return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(var i=0;i<layer.children.length;i++)
+visitLayer(layer.children[i],depth+1);}
+if(layer.maskLayer)
+visitLayer(layer.maskLayer,depth+1,true,false);if(layer.replicaLayer)
+visitLayer(layer.replicaLayer,depth+1,false,true);}
+visitLayer(this.rootLayer,0,false,false);},findLayerWithId:function(id){var foundLayer=undefined;function visitLayer(layer){if(layer.layerId==id)
+foundLayer=layer;}
+this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot:LayerTreeImplSnapshot};});'use strict';tr.exportTo('tr.b',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;};BBox2.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2:function(bbox2){if(bbox2.isEmpty)
+return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone:function(){var bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY:function(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2:function(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad:function(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)
+return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)
+return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no size');var size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no size');return{width:this.max_[0]-this.min_[0],height:this.max_[1]-this.min_[1]};},get width(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no width');return this.max_[0]-this.min_[0];},get height(){if(this.isEmpty_)
+throw new Error('Empty BBox2 has no width');return this.max_[1]-this.min_[1];},toString:function(){if(this.isEmpty_)
+return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect:function(){return tr.b.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2:BBox2};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
+if(!this.activeTiles)
+this.activeTiles=[];this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames:function(){var scales={};for(var i=0;i<this.activeTiles.length;++i){var tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
+return scales;},getTree:function(whichTree){if(whichTree==constants.ACTIVE_TREE)
+return this.activeTree;if(whichTree==constants.PENDING_TREE)
+return this.pendingTree;throw new Exception('Unknown tree type + '+whichTree);},get tilesHaveGpuMemoryUsageInfo(){if(this.tilesHaveGpuMemoryUsageInfo_!==undefined)
+return this.tilesHaveGpuMemoryUsageInfo_;for(var i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined)
+continue;this.tilesHaveGpuMemoryUsageInfo_=true;return true;}
+this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)
+return;var usage=0;for(var i=0;i<this.activeTiles.length;i++){var u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)
+usage+=u;}
+return usage;},get userFriendlyName(){var frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined)
+frameNumber=this.objectInstance.snapshots.indexOf(this);else
+frameNumber=this.activeTree.sourceFrameNumber;}
+return'cc::LayerTreeHostImpl frame '+frameNumber;}};ObjectSnapshot.register(LayerTreeHostImplSnapshot,{typeName:'cc::LayerTreeHostImpl'});function LayerTreeHostImplInstance(){ObjectInstance.apply(this,arguments);this.allLayersBBox_=undefined;}
+LayerTreeHostImplInstance.prototype={__proto__:ObjectInstance.prototype,get allContentsScales(){if(this.allContentsScales_)
+return this.allContentsScales_;var scales={};for(var tileID in this.allTileHistories_){var tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
+this.allContentsScales_=tr.b.dictionaryKeys(scales);return this.allContentsScales_;},get allLayersBBox(){if(this.allLayersBBox_)
+return this.allLayersBBox_;var bbox=new tr.b.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
+this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree)
+handleTree(lthi.pendingTree);});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot:LayerTreeHostImplSnapshot,LayerTreeHostImplInstance:LayerTreeHostImplInstance};});'use strict';tr.exportTo('tr.e.cc',function(){var tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};var tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes:tileTypes,tileBorder:tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
+TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
+if(this.contentRect)
+this.layerRect=this.contentRect.scale(1.0/this.contentsScale);if(this.isSolidColor)
+this.type_=tr.e.cc.tileTypes.solidColor;else if(!this.hasResource)
+this.type_=tr.e.cc.tileTypes.missing;else if(this.resolution==='HIGH_RESOLUTION')
+this.type_=tr.e.cc.tileTypes.highRes;else if(this.resolution==='LOW_RESOLUTION')
+this.type_=tr.e.cc.tileTypes.lowRes;else
+this.type_=tr.e.cc.tileTypes.unknown;},getTypeForLayer:function(layer){var type=this.type_;if(type==tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale)
+type=tr.e.cc.tileTypes.extraLowRes;else if(this.contentsScale>layer.idealContentsScale)
+type=tr.e.cc.tileTypes.extraHighRes;}
+return type;}};ObjectSnapshot.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot:TileSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);this.classList.add('x-list-view');this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_:function(item){item.classList.add('list-item');item.addEventListener('click',this.onItemClicked_,true);var listView=this;Object.defineProperty(item,'selected',{configurable:true,set:function(value){var oldSelection=listView.selectedElement;if(oldSelection&&oldSelection!=this&&value)
+listView.selectedElement.removeAttribute('selected');if(value)
+this.setAttribute('selected','selected');else
+this.removeAttribute('selected');var newSelection=listView.selectedElement;if(newSelection!=oldSelection)
+tr.b.dispatchSimpleEvent(listView,'selection-changed',false);},get:function(){return this.hasAttribute('selected');}});},undecorateChild_:function(item){this.selectionChanged_|=item.selected;item.classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_:function(){this.selectionChanged_=false;},doneDecoratingForNow_:function(){if(this.selectionChanged_)
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get selectedElement(){var el=this.querySelector('.list-item[selected]');if(!el)
+return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement)
+this.selectedElement.selected=false;return;}
+if(el.parentElement!=this)
+throw new Error('Can only select elements that are children of this list view');el.selected=true;},getElementByIndex:function(index){return this.querySelector('.list-item:nth-child('+index+')');},clear:function(){var changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed)
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onItemClicked_:function(e){var currentSelectedElement=this.selectedElement;if(currentSelectedElement)
+currentSelectedElement.removeAttribute('selected');var element=e.target;while(element.parentElement!=this)
+element=element.parentElement;if(element!==currentSelectedElement)
+element.setAttribute('selected','selected');tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_:function(e){if(this.selectedElement===undefined)
+return;if(e.keyCode==38){var prev=this.selectedElement.previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode==40){var next=this.selectedElement.nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem:function(textContent){var item=document.createElement('div');item.textContent=textContent;this.appendChild(item);return item;}};return{ListView:ListView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;};Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis:function(){throw new Error('Not implemented');},findEquivalent:function(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined))
+throw new Error('Render pass (with id) is required');this.renderPass_=renderPass;this.renderPassId_=renderPassId;}
+RenderPassSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return undefined;},get associatedRenderPassId(){return this.renderPassId_;},get renderPass(){return this.renderPass_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='RenderPass '+this.renderPassId_;dataView.object=this.renderPass_.args;return dataView;},get title(){return this.renderPass_.objectInstance.typeName;}};function LayerSelection(layer){if(!layer)
+throw new Error('Layer is required');this.layer_=layer;}
+LayerSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return this.layer_.layerId;},get associatedRenderPassId(){return undefined;},get layer(){return this.layer_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='Layer '+this.layer_.layerId;if(this.layer_.usingGpuRasterization)
+dataView.label+=' (GPU-rasterized)';dataView.object=this.layer_.args;return dataView;},get title(){return this.layer_.objectInstance.typeName;},findEquivalent:function(lthi){var layer=lthi.activeTree.findLayerWithId(this.layer_.layerId)||lthi.pendingTree.findLayerWithId(this.layer_.layerId);if(!layer)
+return undefined;return new LayerSelection(layer);}};function TileSelection(tile,opt_data){this.tile_=tile;this.data_=opt_data||{};}
+TileSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.tile_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.tile_.layerId]=[{colorKey:this.tile_.objectInstance.typeName,rect:this.tile_.layerRect}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Tile '+this.tile_.objectInstance.id+' on layer '+
+this.tile_.layerId;if(this.data_){analysis.object={moreInfo:this.data_,tileArgs:this.tile_.args};}else{analysis.object=this.tile_.args;}
+return analysis;},findEquivalent:function(lthi){var tileInstance=this.tile_.tileInstance;if(lthi.ts<tileInstance.creationTs||lthi.ts>=tileInstance.deletionTs)
+return undefined;var tileSnapshot=tileInstance.getSnapshotAt(lthi.ts);if(!tileSnapshot)
+return undefined;return new TileSelection(tileSnapshot);}};function LayerRectSelection(layer,rectType,rect,opt_data){this.layer_=layer;this.rectType_=rectType;this.rect_=rect;this.data_=opt_data!==undefined?opt_data:rect;}
+LayerRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.layer_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.layer_.layerId]=[{colorKey:this.rectType_,rect:this.rect_}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label=this.rectType_+' on layer '+this.layer_.layerId;analysis.object=this.data_;return analysis;},findEquivalent:function(lthi){return undefined;}};function AnimationRectSelection(layer,rect){this.layer_=layer;this.rect_=rect;}
+AnimationRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 0;},get associatedLayerId(){return this.layer_.layerId;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Animation Bounds of layer '+this.layer_.layerId;analysis.object=this.rect_;return analysis;}};return{Selection:Selection,RenderPassSelection:RenderPassSelection,LayerSelection:LayerSelection,TileSelection:TileSelection,LayerRectSelection:LayerRectSelection,AnimationRectSelection:AnimationRectSelection};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var ANNOTATION='Comment';var BEGIN_ANNOTATION='BeginCommentGroup';var END_ANNOTATION='EndCommentGroup';var ANNOTATION_ID='ID: ';var ANNOTATION_CLASS='CLASS: ';var ANNOTATION_TAG='TAG: ';var constants=tr.e.cc.constants;var PictureOpsListView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-list-view');PictureOpsListView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.opsList_=new tr.ui.b.ListView();this.appendChild(this.opsList_);this.selectedOp_=undefined;this.selectedOpIndex_=undefined;this.opsList_.addEventListener('selection-changed',this.onSelectionChanged_.bind(this));this.picture_=undefined;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.updateContents_();},updateContents_:function(){this.opsList_.clear();if(!this.picture_)
+return;var ops=this.picture_.getOps();if(!ops)
+return;ops=this.picture_.tagOpsWithTimings(ops);ops=this.opsTaggedWithAnnotations_(ops);for(var i=0;i<ops.length;i++){var op=ops[i];var item=document.createElement('div');item.opIndex=op.opIndex;item.textContent=i+') '+op.cmd_string;if(op.elementInfo.tag||op.elementInfo.id||op.elementInfo.class){var elementInfo=document.createElement('span');elementInfo.classList.add('elementInfo');var tag=op.elementInfo.tag?op.elementInfo.tag:'unknown';var id=op.elementInfo.id?'id='+op.elementInfo.id:undefined;var className=op.elementInfo.class?'class='+
+op.elementInfo.class:undefined;elementInfo.textContent='<'+tag+(id?' ':'')+
+(id?id:'')+(className?' ':'')+
+(className?className:'')+'>';item.appendChild(elementInfo);}
+if(op.info.length>0){var infoItem=document.createElement('div');infoItem.textContent=JSON.stringify(op.info);item.appendChild(infoItem);}
+if(op.cmd_time&&op.cmd_time>=0.0001){var time=document.createElement('span');time.classList.add('time');var rounded=op.cmd_time.toFixed(4);time.textContent='('+rounded+'ms)';item.appendChild(time);}
+this.opsList_.appendChild(item);}},onSelectionChanged_:function(e){var beforeSelectedOp=true;if(this.opsList_.selectedElement===this.selectedOp_){this.opsList_.selectedElement=undefined;beforeSelectedOp=false;this.selectedOpIndex_=undefined;}
+this.selectedOp_=this.opsList_.selectedElement;var ops=this.opsList_.children;for(var i=0;i<ops.length;i++){var op=ops[i];if(op===this.selectedOp_){beforeSelectedOp=false;this.selectedOpIndex_=op.opIndex;}else if(beforeSelectedOp){op.setAttribute('beforeSelection','beforeSelection');}else{op.removeAttribute('beforeSelection');}}
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get numOps(){return this.opsList_.children.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(s){this.selectedOpIndex_=s;if(s===undefined){this.opsList_.selectedElement=this.selectedOp_;this.onSelectionChanged_();}else{if(s<0)throw new Error('Invalid index');if(s>=this.numOps)throw new Error('Invalid index');this.opsList_.selectedElement=this.opsList_.getElementByIndex(s+1);tr.ui.b.scrollIntoViewIfNeeded(this.opsList_.selectedElement);}},opsTaggedWithAnnotations_:function(ops){var annotationGroups=new Array();var opsWithoutAnnotations=new Array();for(var opIndex=0;opIndex<ops.length;opIndex++){var op=ops[opIndex];op.opIndex=opIndex;switch(op.cmd_string){case BEGIN_ANNOTATION:annotationGroups.push(new Array());break;case END_ANNOTATION:annotationGroups.pop();break;case ANNOTATION:annotationGroups[annotationGroups.length-1].push(op);break;default:var annotations=new Array();var elementInfo={};annotationGroups.forEach(function(annotationGroup){elementInfo={};annotationGroup.forEach(function(annotation){annotation.info.forEach(function(info){if(info.indexOf(ANNOTATION_TAG)!=-1)
+elementInfo.tag=info.substring(info.indexOf(ANNOTATION_TAG)+
+ANNOTATION_TAG.length).toLowerCase();else if(info.indexOf(ANNOTATION_ID)!=-1)
+elementInfo.id=info.substring(info.indexOf(ANNOTATION_ID)+
+ANNOTATION_ID.length);else if(info.indexOf(ANNOTATION_CLASS)!=-1)
+elementInfo.class=info.substring(info.indexOf(ANNOTATION_CLASS)+
+ANNOTATION_CLASS.length);annotations.push(info);});});});op.annotations=annotations;op.elementInfo=elementInfo;opsWithoutAnnotations.push(op);}}
+return opsWithoutAnnotations;}};return{PictureOpsListView:PictureOpsListView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.trackMouse_();this.displayItemInfo_=this.querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));this.displayItemInfo_.appendChild(this.displayItemListView_);this.displayListFilename_=this.querySelector('.dlfilename');this.displayListExportButton_=this.querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=this.querySelector('.skpfilename');this.skpExportButton_=this.querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));var leftPanel=this.querySelector('left-panel');var middleDragHandle=new tr.ui.b.DragHandle();middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.insertBefore(this.infoBar_,this.rasterCanvas_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();rightPanel.insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=new tr.ui.b.DragHandle();this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;rightPanel.insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){var newListItem=document.createElement('div');newListItem.innerText=item;var text=item.skp64?item.name:item;this.displayItemListView_.addItem(text);}.bind(this));},set picture(picture){this.picture_=picture;var showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=parseInt(style.width);var height=parseInt(style.height);if(this.picture_){width=Math.max(width,this.picture_.layerRect.width);height=Math.max(height,this.picture_.layerRect.height);}
+return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
+return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
+this.picture_.layerRect.width+' x '+
+this.picture_.layerRect.height+')';}
+if(!this.pictureAsImageData_)
+return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width)
+this.rasterCanvas_.width=size.width;if(size.height!==this.rasterCanvas_.height)
+this.rasterCanvas_.height=size.height;this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.picture_||!this.pictureAsImageData_.imageData)
+return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({showOverdraw:false},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},onDisplayItemListSelection_:function(e){var selected=this.displayItemListView_.selectedElement;if(!selected){this.picture=this.displayItemList_;return;}
+var index=Array.prototype.indexOf.call(this.displayItemListView_.children,selected);var displayItem=this.displayItemList_.items[index];if(displayItem&&displayItem.skp64)
+this.picture=new tr.e.cc.Picture(displayItem.skp64,this.displayItemList_.layerRect);else
+this.picture=undefined;},onDisplayItemInfoClick_:function(e){if(e&&e.target==this.displayItemInfo_){this.displayItemListView_.selectedElement=undefined;}},updateDrawOpsList_:function(showOpsList){if(showOpsList){this.pictureOpsListView_.picture=this.picture_;if(this.pictureOpsListView_.numOps>0){this.pictureOpsListView_.classList.add('hasPictureOps');this.pictureOpsListDragHandle_.classList.add('hasPictureOps');}}else{this.pictureOpsListView_.classList.remove('hasPictureOps');this.pictureOpsListDragHandle_.classList.remove('hasPictureOps');}},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;this.rasterArea_.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
+return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};},saveFile_:function(filename,rawData){if(!rawData)
+return;var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
+uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.URL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_:function(){var rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_:function(){var rawData=atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger:DisplayItemDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-display-item-list-view');this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();this.appendChild(this.displayItemDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.displayItemDebugger_)
+this.displayItemDebugger_.displayItemList=this.objectSnapshot_;}};tr.ui.analysis.ObjectSnapshotView.register(DisplayItemSnapshotView,{typeNames:['cc::DisplayItemList'],showInstances:false});return{DisplayItemSnapshotView:DisplayItemSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var RENDER_PASS_QUADS=Math.max(constants.ACTIVE_TREE,constants.PENDING_TREE)+1;var LayerPicker=tr.ui.b.define('tr-ui-e-chrome-cc-layer-picker');LayerPicker.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.lthi_=undefined;this.controls_=document.createElement('top-controls');this.renderPassQuads_=false;this.itemList_=new tr.ui.b.ListView();this.appendChild(this.controls_);this.appendChild(this.itemList_);this.itemList_.addEventListener('selection-changed',this.onItemSelectionChanged_.bind(this));this.controls_.appendChild(tr.ui.b.createSelector(this,'whichTree','layerPicker.whichTree',constants.ACTIVE_TREE,[{label:'Active tree',value:constants.ACTIVE_TREE},{label:'Pending tree',value:constants.PENDING_TREE},{label:'Render pass quads',value:RENDER_PASS_QUADS}]));this.showPureTransformLayers_=false;var showPureTransformLayers=tr.ui.b.createCheckBox(this,'showPureTransformLayers','layerPicker.showPureTransformLayers',false,'Transform layers');showPureTransformLayers.classList.add('show-transform-layers');showPureTransformLayers.title='When checked, pure transform layers are shown';this.controls_.appendChild(showPureTransformLayers);},get lthiSnapshot(){return this.lthiSnapshot_;},set lthiSnapshot(lthiSnapshot){this.lthiSnapshot_=lthiSnapshot;this.updateContents_();},get whichTree(){return this.renderPassQuads_?constants.ACTIVE_TREE:this.whichTree_;},set whichTree(whichTree){this.whichTree_=whichTree;this.renderPassQuads_=(whichTree==RENDER_PASS_QUADS);this.updateContents_();tr.b.dispatchSimpleEvent(this,'selection-change',false);},get layerTreeImpl(){if(this.lthiSnapshot===undefined)
+return undefined;return this.lthiSnapshot.getTree(this.whichTree);},get isRenderPassQuads(){return this.renderPassQuads_;},get showPureTransformLayers(){return this.showPureTransformLayers_;},set showPureTransformLayers(show){if(this.showPureTransformLayers_===show)
+return;this.showPureTransformLayers_=show;this.updateContents_();},getRenderPassInfos_:function(){if(!this.lthiSnapshot_)
+return[];var renderPassInfo=[];if(!this.lthiSnapshot_.args.frame||!this.lthiSnapshot_.args.frame.renderPasses)
+return renderPassInfo;var renderPasses=this.lthiSnapshot_.args.frame.renderPasses;for(var i=0;i<renderPasses.length;++i){var info={renderPass:renderPasses[i],depth:0,id:i,name:'cc::RenderPass'};renderPassInfo.push(info);}
+return renderPassInfo;},getLayerInfos_:function(){if(!this.lthiSnapshot_)
+return[];var tree=this.lthiSnapshot_.getTree(this.whichTree_);if(!tree)
+return[];var layerInfos=[];var showPureTransformLayers=this.showPureTransformLayers_;function isPureTransformLayer(layer){if(layer.args.compositingReasons&&layer.args.compositingReasons.length!=1&&layer.args.compositingReasons[0]!='No reasons given')
+return false;if(layer.args.drawsContent)
+return false;return true;}
+var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])
+return;visitedLayers[layer.layerId]=true;var info={layer:layer,depth:depth};if(layer.args.drawsContent)
+info.name=layer.objectInstance.name;else
+info.name='cc::LayerImpl';if(layer.usingGpuRasterization)
+info.name+=' (G)';info.isMaskLayer=isMask;info.replicaLayer=isReplica;if(showPureTransformLayers||!isPureTransformLayer(layer))
+layerInfos.push(info);};tree.iterLayers(visitLayer);return layerInfos;},updateContents_:function(){if(this.renderPassQuads_)
+this.updateRenderPassContents_();else
+this.updateLayerContents_();},updateRenderPassContents_:function(){this.itemList_.clear();var selectedRenderPassId;if(this.selection_&&this.selection_.associatedRenderPassId)
+selectedRenderPassId=this.selection_.associatedRenderPassId;var renderPassInfos=this.getRenderPassInfos_();renderPassInfos.forEach(function(renderPassInfo){var renderPass=renderPassInfo.renderPass;var id=renderPassInfo.id;var item=this.createElementWithDepth_(renderPassInfo.depth);var labelEl=item.appendChild(tr.ui.b.createSpan());labelEl.textContent=renderPassInfo.name+' '+id;item.renderPass=renderPass;item.renderPassId=id;this.itemList_.appendChild(item);if(id==selectedRenderPassId){renderPass.selectionState=tr.model.SelectionState.SELECTED;}},this);},updateLayerContents_:function(){this.changingItemSelection_=true;try{this.itemList_.clear();var selectedLayerId;if(this.selection_&&this.selection_.associatedLayerId)
+selectedLayerId=this.selection_.associatedLayerId;var layerInfos=this.getLayerInfos_();layerInfos.forEach(function(layerInfo){var layer=layerInfo.layer;var id=layer.layerId;var item=this.createElementWithDepth_(layerInfo.depth);var labelEl=item.appendChild(tr.ui.b.createSpan());labelEl.textContent=layerInfo.name+' '+id;var notesEl=item.appendChild(tr.ui.b.createSpan());if(layerInfo.isMaskLayer)
+notesEl.textContent+='(mask)';if(layerInfo.isReplicaLayer)
+notesEl.textContent+='(replica)';if(layer.gpuMemoryUsageInBytes!==undefined){var rounded=bytesToRoundedMegabytes(layer.gpuMemoryUsageInBytes);if(rounded!==0)
+notesEl.textContent+=' ('+rounded+' MB)';}
+item.layer=layer;this.itemList_.appendChild(item);if(layer.layerId==selectedLayerId){layer.selectionState=tr.model.SelectionState.SELECTED;item.selected=true;}},this);}finally{this.changingItemSelection_=false;}},createElementWithDepth_:function(depth){var item=document.createElement('div');var indentEl=item.appendChild(tr.ui.b.createSpan());indentEl.style.whiteSpace='pre';for(var i=0;i<depth;i++)
+indentEl.textContent=indentEl.textContent+' ';return item;},onItemSelectionChanged_:function(e){if(this.changingItemSelection_)
+return;if(this.renderPassQuads_)
+this.onRenderPassSelected_(e);else
+this.onLayerSelected_(e);tr.b.dispatchSimpleEvent(this,'selection-change',false);},onRenderPassSelected_:function(e){var selectedRenderPass;var selectedRenderPassId;if(this.itemList_.selectedElement){selectedRenderPass=this.itemList_.selectedElement.renderPass;selectedRenderPassId=this.itemList_.selectedElement.renderPassId;}
+if(selectedRenderPass){this.selection_=new tr.ui.e.chrome.cc.RenderPassSelection(selectedRenderPass,selectedRenderPassId);}else{this.selection_=undefined;}},onLayerSelected_:function(e){var selectedLayer;if(this.itemList_.selectedElement)
+selectedLayer=this.itemList_.selectedElement.layer;if(selectedLayer)
+this.selection_=new tr.ui.e.chrome.cc.LayerSelection(selectedLayer);else
+this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){if(this.selection_==selection)
+return;this.selection_=selection;this.updateContents_();}};return{LayerPicker:LayerPicker};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function RenderPassSnapshot(){ObjectSnapshot.apply(this,arguments);}
+RenderPassSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['quadList']);}};ObjectSnapshot.register(RenderPassSnapshot,{typeName:'cc::RenderPass'});return{RenderPassSnapshot:RenderPassSnapshot};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={DEFAULT_SCALE:0.5,DEFAULT_EYE_DISTANCE:10000,MINIMUM_DISTANCE:1000,MAXIMUM_DISTANCE:100000,FOV:15,RESCALE_TIMEOUT_MS:200,MAXIMUM_TILT:80,SETTINGS_NAMESPACE:'tr.ui_camera'};var Camera=tr.ui.b.define('camera');Camera.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(eventSource){this.eventSource_=eventSource;this.eventSource_.addEventListener('beginpan',this.onPanBegin_.bind(this));this.eventSource_.addEventListener('updatepan',this.onPanUpdate_.bind(this));this.eventSource_.addEventListener('endpan',this.onPanEnd_.bind(this));this.eventSource_.addEventListener('beginzoom',this.onZoomBegin_.bind(this));this.eventSource_.addEventListener('updatezoom',this.onZoomUpdate_.bind(this));this.eventSource_.addEventListener('endzoom',this.onZoomEnd_.bind(this));this.eventSource_.addEventListener('beginrotate',this.onRotateBegin_.bind(this));this.eventSource_.addEventListener('updaterotate',this.onRotateUpdate_.bind(this));this.eventSource_.addEventListener('endrotate',this.onRotateEnd_.bind(this));this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];this.pixelRatio_=window.devicePixelRatio||1;},get modelViewMatrix(){var mvMatrix=mat4.create();mat4.lookAt(mvMatrix,this.eye_,this.gazeTarget_,[0,1,0]);return mvMatrix;},get projectionMatrix(){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var aspectRatio=rect.width/rect.height;var matrix=mat4.create();mat4.perspective(matrix,tr.b.deg2rad(constants.FOV),aspectRatio,1,100000);return matrix;},set canvas(c){this.canvas_=c;},set deviceRect(rect){this.deviceRect_=rect;},get stackingDistanceDampening(){var gazeVector=[this.gazeTarget_[0]-this.eye_[0],this.gazeTarget_[1]-this.eye_[1],this.gazeTarget_[2]-this.eye_[2]];vec3.normalize(gazeVector,gazeVector);return 1+gazeVector[2];},loadCameraFromSettings:function(settings){this.eye_=settings.get('eye',this.eye_,constants.SETTINGS_NAMESPACE);this.gazeTarget_=settings.get('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);this.rotation_=settings.get('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);this.dispatchRenderEvent_();},saveCameraToSettings:function(settings){settings.set('eye',this.eye_,constants.SETTINGS_NAMESPACE);settings.set('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);settings.set('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);},resetCamera:function(){this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];var settings=tr.b.SessionSettings();var keys=settings.keys(constants.SETTINGS_NAMESPACE);if(keys.length!==0){this.loadCameraFromSettings(settings);return;}
+if(this.deviceRect_){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);this.eye_[0]=this.deviceRect_.width/2;this.eye_[1]=this.deviceRect_.height/2;this.gazeTarget_[0]=this.deviceRect_.width/2;this.gazeTarget_[1]=this.deviceRect_.height/2;}
+this.saveCameraToSettings(settings);this.dispatchRenderEvent_();},updatePanByDelta:function(delta){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var eyeVector=[this.eye_[0]-this.gazeTarget_[0],this.eye_[1]-this.gazeTarget_[1],this.eye_[2]-this.gazeTarget_[2]];var length=vec3.length(eyeVector);vec3.normalize(eyeVector,eyeVector);var halfFov=constants.FOV/2;var multiplier=2.0*length*Math.tan(tr.b.deg2rad(halfFov))/rect.height;var up=[0,1,0];var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[0]),[1,0,0]);vec3.transformMat4(up,up,rotMatrix);var right=[0,0,0];vec3.cross(right,eyeVector,up);vec3.normalize(right,right);for(var i=0;i<3;++i){this.gazeTarget_[i]+=delta[0]*multiplier*right[i]-delta[1]*multiplier*up[i];this.eye_[i]=this.gazeTarget_[i]+length*eyeVector[i];}
+if(Math.abs(this.gazeTarget_[2])>1e-6){var gazeVector=[-eyeVector[0],-eyeVector[1],-eyeVector[2]];var newLength=tr.b.clamp(-this.eye_[2]/gazeVector[2],constants.MINIMUM_DISTANCE,constants.MAXIMUM_DISTANCE);for(var i=0;i<3;++i)
+this.gazeTarget_[i]=this.eye_[i]+newLength*gazeVector[i];}
+this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateZoomByDelta:function(delta){var deltaY=delta[1];deltaY=tr.b.clamp(deltaY,-50,50);var scale=1.0-deltaY/100.0;var eyeVector=[0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var length=vec3.length(eyeVector);if(length*scale<constants.MINIMUM_DISTANCE)
+scale=constants.MINIMUM_DISTANCE/length;else if(length*scale>constants.MAXIMUM_DISTANCE)
+scale=constants.MAXIMUM_DISTANCE/length;vec3.scale(eyeVector,eyeVector,scale);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateRotateByDelta:function(delta){delta[0]*=0.5;delta[1]*=0.5;if(Math.abs(this.rotation_[0]+delta[1])>constants.MAXIMUM_TILT)
+return;if(Math.abs(this.rotation_[1]-delta[0])>constants.MAXIMUM_TILT)
+return;var eyeVector=[0,0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,-tr.b.deg2rad(this.rotation_[0]),[1,0,0]);mat4.rotate(rotMatrix,rotMatrix,-tr.b.deg2rad(this.rotation_[1]),[0,1,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);this.rotation_[0]+=delta[1];this.rotation_[1]-=delta[0];mat4.identity(rotMatrix);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,tr.b.deg2rad(this.rotation_[0]),[1,0,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},onPanBegin_:function(e){this.panning_=true;this.lastMousePosition_=this.getMousePosition_(e);},onPanUpdate_:function(e){if(!this.panning_)
+return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updatePanByDelta(delta);},onPanEnd_:function(e){this.panning_=false;},onZoomBegin_:function(e){this.zooming_=true;var p=this.getMousePosition_(e);this.lastMousePosition_=p;this.zoomPoint_=p;},onZoomUpdate_:function(e){if(!this.zooming_)
+return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateZoomByDelta(delta);},onZoomEnd_:function(e){this.zooming_=false;this.zoomPoint_=undefined;},onRotateBegin_:function(e){this.rotating_=true;this.lastMousePosition_=this.getMousePosition_(e);},onRotateUpdate_:function(e){if(!this.rotating_)
+return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateRotateByDelta(delta);},onRotateEnd_:function(e){this.rotating_=false;},getMousePosition_:function(e){var rect=tr.ui.b.windowRectForElement(this.canvas_);return[(e.clientX-rect.x)*this.pixelRatio_,(e.clientY-rect.y)*this.pixelRatio_];},getMouseDelta_:function(e,p){var newP=this.getMousePosition_(e);return[newP[0]-p[0],newP[1]-p[1]];},dispatchRenderEvent_:function(){tr.b.dispatchSimpleEvent(this,'renderrequired',false,false);}};return{Camera:Camera};});'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var constants={};constants.IMAGE_LOAD_RETRY_TIME_MS=500;constants.SUBDIVISION_MINIMUM=1;constants.SUBDIVISION_RECURSION_DEPTH=3;constants.SUBDIVISION_DEPTH_THRESHOLD=100;constants.FAR_PLANE_DISTANCE=10000;function drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2){var tmp_p0=[p0[0],p0[1]];var tmp_p1=[p1[0],p1[1]];var tmp_p2=[p2[0],p2[1]];var tmp_t0=[t0[0],t0[1]];var tmp_t1=[t1[0],t1[1]];var tmp_t2=[t2[0],t2[1]];ctx.beginPath();ctx.moveTo(tmp_p0[0],tmp_p0[1]);ctx.lineTo(tmp_p1[0],tmp_p1[1]);ctx.lineTo(tmp_p2[0],tmp_p2[1]);ctx.closePath();tmp_p1[0]-=tmp_p0[0];tmp_p1[1]-=tmp_p0[1];tmp_p2[0]-=tmp_p0[0];tmp_p2[1]-=tmp_p0[1];tmp_t1[0]-=tmp_t0[0];tmp_t1[1]-=tmp_t0[1];tmp_t2[0]-=tmp_t0[0];tmp_t2[1]-=tmp_t0[1];var det=1/(tmp_t1[0]*tmp_t2[1]-tmp_t2[0]*tmp_t1[1]),a=(tmp_t2[1]*tmp_p1[0]-tmp_t1[1]*tmp_p2[0])*det,b=(tmp_t2[1]*tmp_p1[1]-tmp_t1[1]*tmp_p2[1])*det,c=(tmp_t1[0]*tmp_p2[0]-tmp_t2[0]*tmp_p1[0])*det,d=(tmp_t1[0]*tmp_p2[1]-tmp_t2[0]*tmp_p1[1])*det,e=tmp_p0[0]-a*tmp_t0[0]-c*tmp_t0[1],f=tmp_p0[1]-b*tmp_t0[0]-d*tmp_t0[1];ctx.save();ctx.transform(a,b,c,d,e,f);ctx.clip();ctx.drawImage(img,0,0);ctx.restore();}
+function drawTriangleSub(ctx,img,p0,p1,p2,t0,t1,t2,opt_recursion_depth){var depth=opt_recursion_depth||0;var subdivisionIndex=0;if(depth<constants.SUBDIVISION_MINIMUM){subdivisionIndex=7;}else if(depth<constants.SUBDIVISION_RECURSION_DEPTH){if(Math.abs(p0[2]-p1[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
+subdivisionIndex+=1;if(Math.abs(p0[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
+subdivisionIndex+=2;if(Math.abs(p1[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD)
+subdivisionIndex+=4;}
+var p01=vec4.create();var p02=vec4.create();var p12=vec4.create();var t01=vec2.create();var t02=vec2.create();var t12=vec2.create();for(var i=0;i<2;++i){p0[i]*=p0[2];p1[i]*=p1[2];p2[i]*=p2[2];}
+for(var i=0;i<4;++i){p01[i]=(p0[i]+p1[i])/2;p02[i]=(p0[i]+p2[i])/2;p12[i]=(p1[i]+p2[i])/2;}
+for(var i=0;i<2;++i){p0[i]/=p0[2];p1[i]/=p1[2];p2[i]/=p2[2];p01[i]/=p01[2];p02[i]/=p02[2];p12[i]/=p12[2];}
+for(var i=0;i<2;++i){t01[i]=(t0[i]+t1[i])/2;t02[i]=(t0[i]+t2[i])/2;t12[i]=(t1[i]+t2[i])/2;}
+switch(subdivisionIndex){case 1:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 2:drawTriangleSub(ctx,img,p0,p1,p02,t0,t1,t02,depth+1);drawTriangleSub(ctx,img,p1,p02,p2,t1,t02,t2,depth+1);break;case 3:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p02,p01,p2,t02,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 4:drawTriangleSub(ctx,img,p0,p12,p2,t0,t12,t2,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);break;case 5:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p2,p01,p12,t2,t01,t12,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);break;case 6:drawTriangleSub(ctx,img,p0,p12,p02,t0,t12,t02,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;case 7:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p01,p12,p02,t01,t12,t02,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;default:drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2);break;}}
+var tmp_vec4=vec4.create();function transform(transformed,point,matrix,viewport){vec4.set(tmp_vec4,point[0],point[1],0,1);vec4.transformMat4(tmp_vec4,tmp_vec4,matrix);var w=tmp_vec4[3];if(w<1e-6)w=1e-6;transformed[0]=((tmp_vec4[0]/w)+1)*viewport.width/2;transformed[1]=((tmp_vec4[1]/w)+1)*viewport.height/2;transformed[2]=w;}
+function drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(quad.imageData){quadCanvas.width=quad.imageData.width;quadCanvas.height=quad.imageData.height;quadCanvas.getContext('2d').putImageData(quad.imageData,0,0);var quadBBox=new tr.b.BBox2();quadBBox.addQuad(quad);var iw=quadCanvas.width;var ih=quadCanvas.height;drawTriangleSub(ctx,quadCanvas,p1,p2,p4,[0,0],[iw,0],[0,ih]);drawTriangleSub(ctx,quadCanvas,p2,p3,p4,[iw,0],[iw,ih],[0,ih]);}
+if(quad.backgroundColor){ctx.fillStyle=quad.backgroundColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.fill();}}
+function drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.save();if(quad.borderColor)
+ctx.strokeStyle=quad.borderColor;else
+ctx.strokeStyle='rgb(128,128,128)';if(quad.shadowOffset){ctx.shadowColor='rgb(0, 0, 0)';ctx.shadowOffsetX=quad.shadowOffset[0];ctx.shadowOffsetY=quad.shadowOffset[1];if(quad.shadowBlur)
+ctx.shadowBlur=quad.shadowBlur;}
+if(quad.borderWidth)
+ctx.lineWidth=quad.borderWidth;else
+ctx.lineWidth=1;ctx.stroke();ctx.restore();}
+function drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(!quad.upperBorderColor)
+return;ctx.lineWidth=8;ctx.strokeStyle=quad.upperBorderColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.stroke();}
+function drawProjectedQuadToContext(passNumber,quad,p1,p2,p3,p4,ctx,quadCanvas){if(passNumber===0){drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===1){drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===2){drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else{throw new Error('Invalid pass number');}}
+var tmp_p1=vec3.create();var tmp_p2=vec3.create();var tmp_p3=vec3.create();var tmp_p4=vec3.create();function transformAndProcessQuads(matrix,viewport,quads,numPasses,handleQuadFunc,opt_arg1,opt_arg2){for(var passNumber=0;passNumber<numPasses;passNumber++){for(var i=0;i<quads.length;i++){var quad=quads[i];transform(tmp_p1,quad.p1,matrix,viewport);transform(tmp_p2,quad.p2,matrix,viewport);transform(tmp_p3,quad.p3,matrix,viewport);transform(tmp_p4,quad.p4,matrix,viewport);handleQuadFunc(passNumber,quad,tmp_p1,tmp_p2,tmp_p3,tmp_p4,opt_arg1,opt_arg2);}}}
+var QuadStackView=tr.ui.b.define('quad-stack-view');QuadStackView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.className='quad-stack-view';var node=tr.ui.b.instantiateTemplate('#quad-stack-view-template',THIS_DOC);this.appendChild(node);this.updateHeaderVisibility_();this.canvas_=this.querySelector('#canvas');this.chromeImages_={left:this.querySelector('#chrome-left'),mid:this.querySelector('#chrome-mid'),right:this.querySelector('#chrome-right')};var stackingDistanceSlider=this.querySelector('#stacking-distance-slider');stackingDistanceSlider.value=tr.b.Settings.get('quadStackView.stackingDistance',45);stackingDistanceSlider.addEventListener('change',this.onStackingDistanceChange_.bind(this));stackingDistanceSlider.addEventListener('input',this.onStackingDistanceChange_.bind(this));this.trackMouse_();this.camera_=new tr.ui.b.Camera(this.mouseModeSelector_);this.camera_.addEventListener('renderrequired',this.onRenderRequired_.bind(this));this.cameraWasReset_=false;this.camera_.canvas=this.canvas_;this.viewportRect_=tr.b.Rect.fromXYWH(0,0,0,0);this.pixelRatio_=window.devicePixelRatio||1;},updateHeaderVisibility_:function(){if(this.headerText)
+this.querySelector('#header').style.display='';else
+this.querySelector('#header').style.display='none';},get headerText(){return this.querySelector('#header').textContent;},set headerText(headerText){this.querySelector('#header').textContent=headerText;this.updateHeaderVisibility_();},onStackingDistanceChange_:function(e){tr.b.Settings.set('quadStackView.stackingDistance',this.stackingDistance);this.scheduleRender();e.stopPropagation();},get stackingDistance(){return this.querySelector('#stacking-distance-slider').value;},get mouseModeSelector(){return this.mouseModeSelector_;},get camera(){return this.camera_;},set quads(q){this.quads_=q;this.scheduleRender();},set deviceRect(rect){if(!rect||rect.equalTo(this.deviceRect_))
+return;this.deviceRect_=rect;this.camera_.deviceRect=rect;this.chromeQuad_=undefined;},resize:function(){if(!this.offsetParent)
+return true;var width=parseInt(window.getComputedStyle(this.offsetParent).width);var height=parseInt(window.getComputedStyle(this.offsetParent).height);var rect=tr.b.Rect.fromXYWH(0,0,width,height);if(rect.equalTo(this.viewportRect_))
+return false;this.viewportRect_=rect;this.style.width=width+'px';this.style.height=height+'px';this.canvas_.style.width=width+'px';this.canvas_.style.height=height+'px';this.canvas_.width=this.pixelRatio_*width;this.canvas_.height=this.pixelRatio_*height;if(!this.cameraWasReset_){this.camera_.resetCamera();this.cameraWasReset_=true;}
+return true;},readyToDraw:function(){if(!this.chromeImages_.left.src){var leftContent=window.getComputedStyle(this.chromeImages_.left).content;leftContent=leftContent.replace(/url\((.*)\)/,'$1');var midContent=window.getComputedStyle(this.chromeImages_.mid).content;midContent=midContent.replace(/url\((.*)\)/,'$1');var rightContent=window.getComputedStyle(this.chromeImages_.right).content;rightContent=rightContent.replace(/url\((.*)\)/,'$1');this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
+return(this.chromeImages_.left.height>0)&&(this.chromeImages_.mid.height>0)&&(this.chromeImages_.right.height>0);},get chromeQuad(){if(this.chromeQuad_)
+return this.chromeQuad_;var chromeCanvas=document.createElement('canvas');var offsetY=this.chromeImages_.left.height;chromeCanvas.width=this.deviceRect_.width;chromeCanvas.height=this.deviceRect_.height+offsetY;var leftWidth=this.chromeImages_.left.width;var midWidth=this.chromeImages_.mid.width;var rightWidth=this.chromeImages_.right.width;var chromeCtx=chromeCanvas.getContext('2d');chromeCtx.drawImage(this.chromeImages_.left,0,0);chromeCtx.save();chromeCtx.translate(leftWidth,0);var s=(this.deviceRect_.width-leftWidth-rightWidth)/midWidth;chromeCtx.scale(s,1);chromeCtx.drawImage(this.chromeImages_.mid,0,0);chromeCtx.restore();chromeCtx.drawImage(this.chromeImages_.right,leftWidth+s*midWidth,0);var chromeRect=tr.b.Rect.fromXYWH(this.deviceRect_.x,this.deviceRect_.y-offsetY,this.deviceRect_.width,this.deviceRect_.height+offsetY);var chromeQuad=tr.b.Quad.fromRect(chromeRect);chromeQuad.stackingGroupId=this.maxStackingGroupId_+1;chromeQuad.imageData=chromeCtx.getImageData(0,0,chromeCanvas.width,chromeCanvas.height);chromeQuad.shadowOffset=[0,0];chromeQuad.shadowBlur=5;chromeQuad.borderWidth=3;this.chromeQuad_=chromeQuad;return this.chromeQuad_;},scheduleRender:function(){if(this.redrawScheduled_)
+return false;this.redrawScheduled_=true;tr.b.requestAnimationFrame(this.render,this);},onRenderRequired_:function(e){this.scheduleRender();},stackTransformAndProcessQuads_:function(numPasses,handleQuadFunc,includeChromeQuad,opt_arg1,opt_arg2){var mv=this.camera_.modelViewMatrix;var p=this.camera_.projectionMatrix;var viewport=tr.b.Rect.fromXYWH(0,0,this.canvas_.width,this.canvas_.height);var quadStacks=[];for(var i=0;i<this.quads_.length;++i){var quad=this.quads_[i];var stackingId=quad.stackingGroupId||0;while(stackingId>=quadStacks.length)
+quadStacks.push([]);quadStacks[stackingId].push(quad);}
+var mvp=mat4.create();this.maxStackingGroupId_=quadStacks.length;var effectiveStackingDistance=this.stackingDistance*this.camera_.stackingDistanceDampening;mat4.multiply(mvp,p,mv);for(var i=0;i<quadStacks.length;++i){transformAndProcessQuads(mvp,viewport,quadStacks[i],numPasses,handleQuadFunc,opt_arg1,opt_arg2);mat4.translate(mv,mv,[0,0,effectiveStackingDistance]);mat4.multiply(mvp,p,mv);}
+if(includeChromeQuad&&this.deviceRect_){transformAndProcessQuads(mvp,viewport,[this.chromeQuad],numPasses,drawProjectedQuadToContext,opt_arg1,opt_arg2);}},render:function(){this.redrawScheduled_=false;if(!this.readyToDraw()){setTimeout(this.scheduleRender.bind(this),constants.IMAGE_LOAD_RETRY_TIME_MS);return;}
+if(!this.quads_)
+return;var canvasCtx=this.canvas_.getContext('2d');if(!this.resize())
+canvasCtx.clearRect(0,0,this.canvas_.width,this.canvas_.height);var quadCanvas=document.createElement('canvas');this.stackTransformAndProcessQuads_(3,drawProjectedQuadToContext,true,canvasCtx,quadCanvas);quadCanvas.width=0;},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.canvas_;this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION|tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN|tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM|tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN;this.mouseModeSelector_.pos={x:0,y:100};this.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.settingsKey='quadStackView.mouseModeSelector';this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN,tr.ui.b.MODIFIER.SPACE);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM,tr.ui.b.MODIFIER.CMD_OR_CTRL);this.mouseModeSelector_.addEventListener('updateselection',this.onSelectionUpdate_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onSelectionUpdate_.bind(this));},extractRelativeMousePosition_:function(e){var br=this.canvas_.getBoundingClientRect();return[this.pixelRatio_*(e.clientX-this.canvas_.offsetLeft-br.left),this.pixelRatio_*(e.clientY-this.canvas_.offsetTop-br.top)];},onSelectionUpdate_:function(e){var mousePos=this.extractRelativeMousePosition_(e);var res=[];function handleQuad(passNumber,quad,p1,p2,p3,p4){if(tr.b.pointInImplicitQuad(mousePos,p1,p2,p3,p4))
+res.push(quad);}
+this.stackTransformAndProcessQuads_(1,handleQuad,false);var e=new tr.b.Event('selectionchange');e.quads=res;this.dispatchEvent(e);}};return{QuadStackView:QuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var ColorScheme=tr.b.ColorScheme;var THIS_DOC=document.currentScript.ownerDocument;var TILE_HEATMAP_TYPE={};TILE_HEATMAP_TYPE.NONE='none';TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY='scheduledPriority';TILE_HEATMAP_TYPE.USING_GPU_MEMORY='usingGpuMemory';var cc=tr.ui.e.chrome.cc;function createTileRectsSelectorBaseOptions(){return[{label:'None',value:'none'},{label:'Coverage Rects',value:'coverage'}];}
+var bytesToRoundedMegabytes=tr.e.cc.bytesToRoundedMegabytes;var LayerTreeQuadStackView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-quad-stack-view');LayerTreeQuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.isRenderPassQuads_=false;this.pictureAsImageData_={};this.messages_=[];this.controls_=document.createElement('top-controls');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.quadStackView_=new tr.ui.b.QuadStackView();this.quadStackView_.addEventListener('selectionchange',this.onQuadStackViewSelectionChange_.bind(this));this.extraHighlightsByLayerId_=undefined;this.inputEventImageData_=undefined;var m=tr.ui.b.MOUSE_SELECTOR_MODE;var mms=this.quadStackView_.mouseModeSelector;mms.settingsKey='tr.e.cc.layerTreeQuadStackView.mouseModeSelector';mms.setKeyCodeForMode(m.SELECTION,'Z'.charCodeAt(0));mms.setKeyCodeForMode(m.PANSCAN,'X'.charCodeAt(0));mms.setKeyCodeForMode(m.ZOOM,'C'.charCodeAt(0));mms.setKeyCodeForMode(m.ROTATE,'V'.charCodeAt(0));var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template',THIS_DOC);this.appendChild(node);this.appendChild(this.controls_);this.appendChild(this.infoBar_);this.appendChild(this.quadStackView_);this.tileRectsSelector_=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',createTileRectsSelectorBaseOptions());this.controls_.appendChild(this.tileRectsSelector_);var tileHeatmapText=tr.ui.b.createSpan({textContent:'Tile heatmap:'});this.controls_.appendChild(tileHeatmapText);var tileHeatmapSelector=tr.ui.b.createSelector(this,'tileHeatmapType','layerView.tileHeatmapType',TILE_HEATMAP_TYPE.NONE,[{label:'None',value:TILE_HEATMAP_TYPE.NONE},{label:'Scheduled Priority',value:TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY},{label:'Is using GPU memory',value:TILE_HEATMAP_TYPE.USING_GPU_MEMORY}]);this.controls_.appendChild(tileHeatmapSelector);var showOtherLayersCheckbox=tr.ui.b.createCheckBox(this,'showOtherLayers','layerView.showOtherLayers',true,'Other layers/passes');showOtherLayersCheckbox.title='When checked, show all layers, selected or not.';this.controls_.appendChild(showOtherLayersCheckbox);var showInvalidationsCheckbox=tr.ui.b.createCheckBox(this,'showInvalidations','layerView.showInvalidations',true,'Invalidations');showInvalidationsCheckbox.title='When checked, compositing invalidations are highlighted in red';this.controls_.appendChild(showInvalidationsCheckbox);var showUnrecordedRegionCheckbox=tr.ui.b.createCheckBox(this,'showUnrecordedRegion','layerView.showUnrecordedRegion',true,'Unrecorded area');showUnrecordedRegionCheckbox.title='When checked, unrecorded areas are highlighted in yellow';this.controls_.appendChild(showUnrecordedRegionCheckbox);var showBottlenecksCheckbox=tr.ui.b.createCheckBox(this,'showBottlenecks','layerView.showBottlenecks',true,'Bottlenecks');showBottlenecksCheckbox.title='When checked, scroll bottlenecks are highlighted';this.controls_.appendChild(showBottlenecksCheckbox);var showLayoutRectsCheckbox=tr.ui.b.createCheckBox(this,'showLayoutRects','layerView.showLayoutRects',false,'Layout rects');showLayoutRectsCheckbox.title='When checked, shows rects for regions where layout happened';this.controls_.appendChild(showLayoutRectsCheckbox);var showContentsCheckbox=tr.ui.b.createCheckBox(this,'showContents','layerView.showContents',true,'Contents');showContentsCheckbox.title='When checked, show the rendered contents inside the layer outlines';this.controls_.appendChild(showContentsCheckbox);var showAnimationBoundsCheckbox=tr.ui.b.createCheckBox(this,'showAnimationBounds','layerView.showAnimationBounds',false,'Animation Bounds');showAnimationBoundsCheckbox.title='When checked, show a border around'+' a layer showing the extent of its animation.';this.controls_.appendChild(showAnimationBoundsCheckbox);var showInputEventsCheckbox=tr.ui.b.createCheckBox(this,'showInputEvents','layerView.showInputEvents',true,'Input events');showInputEventsCheckbox.title='When checked, input events are '+'displayed as circles.';this.controls_.appendChild(showInputEventsCheckbox);this.whatRasterizedLink_=document.createElement('a');this.whatRasterizedLink_.classList.add('what-rasterized');this.whatRasterizedLink_.textContent='What rasterized?';this.whatRasterizedLink_.addEventListener('click',this.onWhatRasterizedLinkClicked_.bind(this));this.appendChild(this.whatRasterizedLink_);},get layerTreeImpl(){return this.layerTreeImpl_;},set isRenderPassQuads(newValue){this.isRenderPassQuads_=newValue;},set layerTreeImpl(layerTreeImpl){if(this.layerTreeImpl_===layerTreeImpl)
+return;this.layerTreeImpl_=layerTreeImpl;this.selection=undefined;},get extraHighlightsByLayerId(){return this.extraHighlightsByLayerId_;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.extraHighlightsByLayerId_=extraHighlightsByLayerId;this.scheduleUpdateContents_();},get showOtherLayers(){return this.showOtherLayers_;},set showOtherLayers(show){this.showOtherLayers_=show;this.updateContents_();},get showAnimationBounds(){return this.showAnimationBounds_;},set showAnimationBounds(show){this.showAnimationBounds_=show;this.updateContents_();},get showInputEvents(){return this.showInputEvents_;},set showInputEvents(show){this.showInputEvents_=show;this.updateContents_();},get showContents(){return this.showContents_;},set showContents(show){this.showContents_=show;this.updateContents_();},get showInvalidations(){return this.showInvalidations_;},set showInvalidations(show){this.showInvalidations_=show;this.updateContents_();},get showUnrecordedRegion(){return this.showUnrecordedRegion_;},set showUnrecordedRegion(show){this.showUnrecordedRegion_=show;this.updateContents_();},get showBottlenecks(){return this.showBottlenecks_;},set showBottlenecks(show){this.showBottlenecks_=show;this.updateContents_();},get showLayoutRects(){return this.showLayoutRects_;},set showLayoutRects(show){this.showLayoutRects_=show;this.updateContents_();},get howToShowTiles(){return this.howToShowTiles_;},set howToShowTiles(val){console.assert((val==='none')||(val==='coverage')||!isNaN(parseFloat(val)));this.howToShowTiles_=val;this.updateContents_();},get tileHeatmapType(){return this.tileHeatmapType_;},set tileHeatmapType(val){this.tileHeatmapType_=val;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){if(this.selection===selection)
+return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent:function(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_:function(image,callback){var imageContent=window.getComputedStyle(image).content;image.src=imageContent.replace(/url\((.*)\)/,'$1');image.onload=function(){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);var imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);}},onQuadStackViewSelectionChange_:function(e){var selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length==0){this.selection=undefined;return;}
+selectableQuads.sort(function(x,y){var z=x.stackingGroupId-y.stackingGroupId;if(z!=0)
+return z;return x.selectionToSetIfClicked.specicifity-
+y.selectionToSetIfClicked.specicifity;});var quadToSelect=selectableQuads[selectableQuads.length-1];this.selection=quadToSelect.selectionToSetIfClicked;},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
+return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_,this);},updateContents_:function(){if(!this.layerTreeImpl_){this.quadStackView_.headerText='No tree';this.quadStackView_.quads=[];return;}
+var status=this.computePictureLoadingStatus_();if(!status.picturesComplete)
+return;var lthi=this.layerTreeImpl_.layerTreeHostImpl;var lthiInstance=lthi.objectInstance;var worldViewportRect=tr.b.Rect.fromXYWH(0,0,lthi.deviceViewportSize.width,lthi.deviceViewportSize.height);this.quadStackView_.deviceRect=worldViewportRect;if(this.isRenderPassQuads_)
+this.quadStackView_.quads=this.generateRenderPassQuads();else
+this.quadStackView_.quads=this.generateLayerQuads();this.updateWhatRasterizedLinkState_();var message='';if(lthi.tilesHaveGpuMemoryUsageInfo){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;var otherTreeUsageInBytes=lthi.gpuMemoryUsageInBytes-
+thisTreeUsageInBytes;message+=bytesToRoundedMegabytes(thisTreeUsageInBytes)+'MB on this tree';if(otherTreeUsageInBytes){message+=', '+
+bytesToRoundedMegabytes(otherTreeUsageInBytes)+'MB on the other tree';}}else{if(this.layerTreeImpl_){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;message+=bytesToRoundedMegabytes(thisTreeUsageInBytes)+'MB on this tree';if(this.layerTreeImpl_.otherTree){message+=', ???MB on other tree. ';}}}
+if(lthi.args.tileManagerBasicState){var tmgs=lthi.args.tileManagerBasicState.globalState;message+=' (softMax='+
+bytesToRoundedMegabytes(tmgs.softMemoryLimitInBytes)+'MB, hardMax='+
+bytesToRoundedMegabytes(tmgs.hardMemoryLimitInBytes)+'MB, '+
+tmgs.memoryLimitPolicy+')';}else{var thread=lthi.snapshottedOnThread;var didManageTilesSlices=thread.sliceGroup.slices.filter(function(s){if(s.category!=='tr.e.cc')
+return false;if(s.title!=='DidManage')
+return false;if(s.end>lthi.ts)
+return false;return true;});didManageTilesSlices.sort(function(x,y){return x.end-y.end;});if(didManageTilesSlices.length>0){var newest=didManageTilesSlices[didManageTilesSlices.length-1];var tmgs=newest.args.state.global_state;message+=' (softMax='+
+bytesToRoundedMegabytes(tmgs.soft_memory_limit_in_bytes)+'MB, hardMax='+
+bytesToRoundedMegabytes(tmgs.hard_memory_limit_in_bytes)+'MB, '+
+tmgs.memory_limit_policy+')';}}
+if(this.layerTreeImpl_.otherTree)
+message+=' (Another tree exists)';if(message.length)
+this.quadStackView_.headerText=message;else
+this.quadStackView_.headerText=undefined;this.updateInfoBar_(status.messages);},updateTilesSelector_:function(){var data=createTileRectsSelectorBaseOptions();if(this.layerTreeImpl_){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var scaleNames=lthi.getContentsScaleNames();for(var scale in scaleNames){data.push({label:'Scale '+scale+' ('+scaleNames[scale]+')',value:scale});}}
+var new_selector=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',data);this.controls_.replaceChild(new_selector,this.tileRectsSelector_);this.tileRectsSelector_=new_selector;},computePictureLoadingStatus_:function(){var layers=this.layers;var status={messages:[],picturesComplete:true};if(this.showContents){var hasPendingRasterizeImage=false;var firstPictureError=undefined;var hasMissingLayerRect=false;var hasUnresolvedPictureRef=false;for(var i=0;i<layers.length;i++){var layer=layers[i];for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(picture.idRef){hasUnresolvedPictureRef=true;continue;}
+if(!picture.layerRect){hasMissingLayerRect=true;continue;}
+var pictureAsImageData=this.pictureAsImageData_[picture.guid];if(!pictureAsImageData){hasPendingRasterizeImage=true;this.pictureAsImageData_[picture.guid]=tr.e.cc.PictureAsImageData.Pending(this);picture.rasterize({stopIndex:undefined},function(pictureImageData){var picture_=pictureImageData.picture;this.pictureAsImageData_[picture_.guid]=pictureImageData;this.scheduleUpdateContents_();}.bind(this));continue;}
+if(pictureAsImageData.isPending()){hasPendingRasterizeImage=true;continue;}
+if(pictureAsImageData.error){if(!firstPictureError)
+firstPictureError=pictureAsImageData.error;break;}}}
+if(hasPendingRasterizeImage){status.picturesComplete=false;}else{if(hasUnresolvedPictureRef){status.messages.push({header:'Missing picture',details:'Your trace didnt have pictures for every layer. '+'Old chrome versions had this problem'});}
+if(hasMissingLayerRect){status.messages.push({header:'Missing layer rect',details:'Your trace may be corrupt or from a very old '+'Chrome revision.'});}
+if(firstPictureError){status.messages.push({header:'Cannot rasterize',details:firstPictureError});}}}
+if(this.showInputEvents&&this.layerTreeImpl.tracedInputLatencies&&this.inputEventImageData_===undefined){var image=this.querySelector('#input-event');if(!image.src){this.loadDataForImageElement_(image,function(imageData){this.inputEventImageData_=imageData;this.updateContentsPending_=false;this.scheduleUpdateContents_();}.bind(this));}
+status.picturesComplete=false;}
+return status;},get selectedRenderPass(){if(this.selection)
+return this.selection.renderPass_;},get selectedLayer(){if(this.selection){var selectedLayerId=this.selection.associatedLayerId;return this.layerTreeImpl_.findLayerWithId(selectedLayerId);}},get renderPasses(){var renderPasses=this.layerTreeImpl.layerTreeHostImpl.args.frame.renderPasses;if(!this.showOtherLayers){var selectedRenderPass=this.selectedRenderPass;if(selectedRenderPass)
+renderPasses=[selectedRenderPass];}
+return renderPasses;},get layers(){var layers=this.layerTreeImpl.renderSurfaceLayerList;if(!this.showOtherLayers){var selectedLayer=this.selectedLayer;if(selectedLayer)
+layers=[selectedLayer];}
+return layers;},appendImageQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(!picture.layerRect)
+continue;var unitRect=picture.layerRect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);var pictureData=this.pictureAsImageData_[picture.guid];if(this.showContents&&pictureData&&pictureData.imageData){iq.imageData=pictureData.imageData;iq.borderColor='rgba(0,0,0,0)';}else{iq.imageData=undefined;}
+iq.stackingGroupId=layerQuad.stackingGroupId;quads.push(iq);}},appendAnimationQuads_:function(quads,layer,layerQuad){if(!layer.animationBoundsRect)
+return;var rect=layer.animationBoundsRect;var abq=tr.b.Quad.fromRect(rect);abq.backgroundColor='rgba(164,191,48,0.5)';abq.borderColor='rgba(205,255,0,0.75)';abq.borderWidth=3.0;abq.stackingGroupId=layerQuad.stackingGroupId;abq.selectionToSetIfClicked=new cc.AnimationRectSelection(layer,rect);quads.push(abq);},appendInvalidationQuads_:function(quads,layer,layerQuad){if(layer.layerTreeImpl.hasSourceFrameBeenDrawnBefore)
+return;for(var ir=0;ir<layer.annotatedInvalidation.rects.length;ir++){var rect=layer.annotatedInvalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';if(rect.reason==='renderer insertion')
+iq.backgroundColor='rgba(0, 255, 128, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect ('+rect.reason+')',rect,rect);quads.push(iq);}
+if(layer.annotatedInvalidation.rects.length===0){for(var ir=0;ir<layer.invalidation.rects.length;ir++){var rect=layer.invalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect',rect,rect);quads.push(iq);}}},appendUnrecordedRegionQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.unrecordedRegion.rects.length;ir++){var rect=layer.unrecordedRegion.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(240, 230, 140, 0.3)';iq.borderColor='rgba(240, 230, 140, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Unrecorded area',rect,rect);quads.push(iq);}},appendBottleneckQuads_:function(quads,layer,layerQuad,stackingGroupId){function processRegion(region,label,borderColor){var backgroundColor=borderColor.clone();backgroundColor.a=0.4*(borderColor.a||1.0);if(!region||!region.rects)
+return;for(var ir=0;ir<region.rects.length;ir++){var rect=region.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor=backgroundColor.toString();iq.borderColor=borderColor.toString();iq.borderWidth=4.0;iq.stackingGroupId=stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,rect);quads.push(iq);}}
+processRegion(layer.touchEventHandlerRegion,'Touch listener',tr.b.Color.fromString('rgb(228, 226, 27)'));processRegion(layer.wheelEventHandlerRegion,'Wheel listener',tr.b.Color.fromString('rgb(176, 205, 29)'));processRegion(layer.nonFastScrollableRegion,'Repaints on scroll',tr.b.Color.fromString('rgb(213, 134, 32)'));},appendTileCoverageRectQuads_:function(quads,layer,layerQuad,heatmapType){if(!layer.tileCoverageRects)
+return;var tiles=[];for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var tile=layer.tileCoverageRects[ct].tile;if(tile!==undefined)
+tiles.push(tile);}
+var lthi=this.layerTreeImpl_.layerTreeHostImpl;var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);var heatIndex=0;for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var rect=layer.tileCoverageRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var tile=layer.tileCoverageRects[ct].tile;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tr.e.cc.tileTypes.missing;if(tile){type=tile.getTypeForLayer(layer);quad.backgroundColor=heatmapResult[heatIndex].color;++heatIndex;}
+quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;var label;if(tile)
+label='coverageRect';else
+label='checkerboard coverageRect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,layer.tileCoverageRects[ct]);quads.push(quad);}},appendLayoutRectQuads_:function(quads,layer,layerQuad){if(!layer.layoutRects){return;}
+for(var ct=0;ct<layer.layoutRects.length;++ct){var rect=layer.layoutRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;quad.borderColor='rgba(0, 0, 200, 0.7)';quad.borderWidth=2;var label;label='Layout rect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect);quads.push(quad);}},getValueForHeatmap_:function(tile,heatmapType){if(heatmapType==TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY){return tile.scheduledPriority==0?undefined:tile.scheduledPriority;}else if(heatmapType==TILE_HEATMAP_TYPE.USING_GPU_MEMORY){if(tile.isSolidColor)
+return 0.5;return tile.isUsingGpuMemory?0:1;}},getMinMaxForHeatmap_:function(tiles,heatmapType){var range=new tr.b.Range();if(heatmapType==TILE_HEATMAP_TYPE.USING_GPU_MEMORY){range.addValue(0);range.addValue(1);return range;}
+for(var i=0;i<tiles.length;++i){var value=this.getValueForHeatmap_(tiles[i],heatmapType);if(value===undefined)
+continue;range.addValue(value);}
+if(range.range===0)
+range.addValue(1);return range;},computeHeatmapColors_:function(tiles,minMax,heatmapType){var min=minMax.min;var max=minMax.max;var color=function(value){var hue=120*(1-(value-min)/(max-min));if(hue<0)
+hue=0;return'hsla('+hue+', 100%, 50%, 0.5)';};var values=[];for(var i=0;i<tiles.length;++i){var tile=tiles[i];var value=this.getValueForHeatmap_(tile,heatmapType);var res={value:value,color:value!==undefined?color(value):undefined};values.push(res);}
+return values;},appendTilesWithScaleQuads_:function(quads,layer,layerQuad,scale,heatmapType){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var tiles=[];for(var i=0;i<lthi.activeTiles.length;++i){var tile=lthi.activeTiles[i];if(Math.abs(tile.contentsScale-scale)>1e-6)
+continue;if(layer.layerId!=tile.layerId)
+continue;tiles.push(tile);}
+var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);for(var i=0;i<tiles.length;++i){var tile=tiles[i];var rect=tile.layerRect;if(!tile.layerRect)
+continue;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tile.getTypeForLayer(layer);quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;quad.backgroundColor=heatmapResult[i].color;var data={tileType:type};if(heatmapType!==TILE_HEATMAP_TYPE.NONE)
+data[heatmapType]=heatmapResult[i].value;quad.selectionToSetIfClicked=new cc.TileSelection(tile,data);quads.push(quad);}},appendHighlightQuadsForLayer_:function(quads,layer,layerQuad,highlights){highlights.forEach(function(highlight){var rect=highlight.rect;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);var colorId=ColorScheme.getColorIdForGeneralPurposeString(highlight.colorKey);colorId+=ColorScheme.properties.brightenedOffsets[0];var color=ColorScheme.colors[colorId];var quadForDrawing=quad.clone();quadForDrawing.backgroundColor=color.withAlpha(0.5).toString();quadForDrawing.borderColor=color.withAlpha(1.0).darken().toString();quadForDrawing.stackingGroupId=layerQuad.stackingGroupId;quads.push(quadForDrawing);},this);},generateRenderPassQuads:function(){if(!this.layerTreeImpl.layerTreeHostImpl.args.frame)
+return[];var renderPasses=this.renderPasses;if(!renderPasses)
+return[];var quads=[];for(var i=0;i<renderPasses.length;++i){var quadList=renderPasses[i].quadList;for(var j=0;j<quadList.length;++j){var drawQuad=quadList[j];var quad=drawQuad.rectAsTargetSpaceQuad.clone();quad.borderColor='rgb(170, 204, 238)';quad.borderWidth=2;quad.stackingGroupId=i;quads.push(quad);}}
+return quads;},generateLayerQuads:function(){this.updateContentsPending_=false;var layers=this.layers;var quads=[];var nextStackingGroupId=0;var alreadyVisitedLayerIds={};var selectionHighlightsByLayerId;if(this.selection)
+selectionHighlightsByLayerId=this.selection.highlightsByLayerId;else
+selectionHighlightsByLayerId={};var extraHighlightsByLayerId=this.extraHighlightsByLayerId||{};for(var i=1;i<=layers.length;i++){var layer=layers[layers.length-i];alreadyVisitedLayerIds[layer.layerId]=true;if(layer.objectInstance.name=='cc::NinePatchLayerImpl')
+continue;var layerQuad=layer.layerQuad.clone();if(layer.usingGpuRasterization){var pixelRatio=window.devicePixelRatio||1;layerQuad.borderWidth=2.0*pixelRatio;layerQuad.borderColor='rgba(154,205,50,0.75)';}else{layerQuad.borderColor='rgba(0,0,0,0.75)';}
+layerQuad.stackingGroupId=nextStackingGroupId++;layerQuad.selectionToSetIfClicked=new cc.LayerSelection(layer);layerQuad.layer=layer;if(this.showOtherLayers&&this.selectedLayer==layer)
+layerQuad.upperBorderColor='rgb(156,189,45)';if(this.showAnimationBounds)
+this.appendAnimationQuads_(quads,layer,layerQuad);this.appendImageQuads_(quads,layer,layerQuad);quads.push(layerQuad);if(this.showInvalidations)
+this.appendInvalidationQuads_(quads,layer,layerQuad);if(this.showUnrecordedRegion)
+this.appendUnrecordedRegionQuads_(quads,layer,layerQuad);if(this.showBottlenecks)
+this.appendBottleneckQuads_(quads,layer,layerQuad,layerQuad.stackingGroupId);if(this.showLayoutRects)
+this.appendLayoutRectQuads_(quads,layer,layerQuad);if(this.howToShowTiles==='coverage'){this.appendTileCoverageRectQuads_(quads,layer,layerQuad,this.tileHeatmapType);}else if(this.howToShowTiles!=='none'){this.appendTilesWithScaleQuads_(quads,layer,layerQuad,this.howToShowTiles,this.tileHeatmapType);}
+var highlights;highlights=extraHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}
+highlights=selectionHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}}
+this.layerTreeImpl.iterLayers(function(layer,depth,isMask,isReplica){if(!this.showOtherLayers&&this.selectedLayer!=layer)
+return;if(alreadyVisitedLayerIds[layer.layerId])
+return;var layerQuad=layer.layerQuad;var stackingGroupId=nextStackingGroupId++;if(this.showBottlenecks)
+this.appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId);},this);var tracedInputLatencies=this.layerTreeImpl.tracedInputLatencies;if(this.showInputEvents&&tracedInputLatencies){for(var i=0;i<tracedInputLatencies.length;i++){var coordinatesArray=tracedInputLatencies[i].args.data.coordinates;for(var j=0;j<coordinatesArray.length;j++){var inputQuad=tr.b.Quad.fromXYWH(coordinatesArray[j].x-25,coordinatesArray[j].y-25,50,50);inputQuad.borderColor='rgba(0, 0, 0, 0)';inputQuad.imageData=this.inputEventImageData_;quads.push(inputQuad);}}}
+return quads;},updateInfoBar_:function(infoBarMessages){if(infoBarMessages.length){this.infoBar_.removeAllButtons();this.infoBar_.message='Some problems were encountered...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent='';infoBarMessages.forEach(function(message){var title=document.createElement('h3');title.textContent=message.header;var details=document.createElement('div');details.textContent=message.details;overlay.appendChild(title);overlay.appendChild(details);});overlay.visible=true;e.stopPropagation();return false;});this.infoBar_.visible=true;}else{this.infoBar_.removeAllButtons();this.infoBar_.message='';this.infoBar_.visible=false;}},getWhatRasterized_:function(){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var renderProcess=lthi.objectInstance.parent;var tasks=[];renderProcess.iterateAllEvents(function(event){if(!(event instanceof tr.model.Slice))
+return;var tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined)
+return false;if(tile.containingSnapshot==lthi)
+tasks.push(event);},this);return tasks;},updateWhatRasterizedLinkState_:function(){var tasks=this.getWhatRasterized_();if(tasks.length){this.whatRasterizedLink_.textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{this.whatRasterizedLink_.textContent='';this.whatRasterizedLink_.style.display='none';}},onWhatRasterizedLinkClicked_:function(){var tasks=this.getWhatRasterized_();var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(tasks);this.dispatchEvent(event);}};return{LayerTreeQuadStackView:LayerTreeQuadStackView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=new tr.ui.b.DragHandle();this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;this.appendChild(this.layerTreeQuadStackView_);this.appendChild(this.dragBar_);this.appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent:function(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_:function(){var selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';this.analysisEl_.textContent='';var layer=selection.layer;if(layer&&layer.args&&layer.args.pictures){this.analysisEl_.appendChild(this.createPictureBtn_(layer.args.pictures));}
+var analysis=selection.createAnalysis();this.analysisEl_.appendChild(analysis);}else{this.dragBar_.style.display='none';this.analysisEl_.style.display='none';var analysis=this.analysisEl_.firstChild;if(analysis)
+this.analysisEl_.removeChild(analysis);this.layerTreeQuadStackView_.style.height=window.getComputedStyle(this).height;}
+tr.b.dispatchSimpleEvent(this,'selection-change');},createPictureBtn_:function(pictures){if(!(pictures instanceof Array))
+pictures=[pictures];var link=document.createElement('tr-ui-a-analysis-link');link.selection=function(){var layeredPicture=new tr.e.cc.LayeredPicture(pictures);var snapshot=new tr.e.cc.PictureSnapshot(layeredPicture);snapshot.picture=layeredPicture;var selection=new tr.model.EventSet();selection.push(snapshot);return selection;};link.textContent='View in Picture Debugger';return link;},onRequestSelectionChangeFromAnalysisEl_:function(e){if(!(e.selection instanceof tr.ui.e.chrome.cc.Selection))
+return;e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView:LayerView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.dragHandle_=new tr.ui.b.DragHandle();this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerView_;this.appendChild(this.layerPicker_);this.appendChild(this.dragHandle_);this.appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;var lthi=this.objectSnapshot;var layerTreeImpl;if(lthi)
+layerTreeImpl=lthi.getTree(this.layerPicker_.whichTree);this.layerPicker_.lthiSnapshot=lthi;this.layerView_.layerTreeImpl=layerTreeImpl;this.layerView_.regenerateContent();if(!this.selection_)
+return;this.selection=this.selection_.findEquivalent(lthi);},get selection(){return this.selection_;},set selection(selection){if(this.selection_==selection)
+return;this.selection_=selection;this.layerPicker_.selection=selection;this.layerView_.selection=selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerPickerSelectionChanged_:function(){this.selection_=this.layerPicker_.selection;this.layerView_.selection=this.selection;this.layerView_.layerTreeImpl=this.layerPicker_.layerTreeImpl;this.layerView_.isRenderPassQuads=this.layerPicker_.isRenderPassQuads;this.layerView_.regenerateContent();tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerViewSelectionChanged_:function(){this.selection_=this.layerView_.selection;this.layerPicker_.selection=this.selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},get extraHighlightsByLayerId(){return this.layerView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};tr.ui.analysis.ObjectSnapshotView.register(LayerTreeHostImplSnapshotView,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshotView:LayerTreeHostImplSnapshotView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=40;var AXIS_PADDING_LEFT=60;var AXIS_PADDING_RIGHT=35;var AXIS_PADDING_TOP=25;var AXIS_PADDING_BOTTOM=45;var AXIS_LABEL_PADDING=5;var AXIS_TICK_SIZE=10;var LABEL_PADDING=5;var LABEL_INTERLEAVE_OFFSET=15;var BAR_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartSummaryView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-summary-view');PictureOpsChartSummaryView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.picture_=undefined;this.pictureDataProcessed_=false;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');this.appendChild(this.chart_);this.opsTimingData_=[];this.chartWidth_=0;this.chartHeight_=0;this.requiresRedraw_=true;this.currentBarMouseOverTarget_=null;this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));},get requiresRedraw(){return this.requiresRedraw_;},set requiresRedraw(requiresRedraw){this.requiresRedraw_=requiresRedraw;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureDataProcessed_=false;if(this.classList.contains('hidden'))
+return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},hide:function(){this.classList.add('hidden');},show:function(){this.classList.remove('hidden');if(this.pictureDataProcessed_)
+return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=null;var x=e.offsetX;var y=e.offsetY;var chartLeft=CHART_PADDING_LEFT;var chartRight=this.chartWidth_-CHART_PADDING_RIGHT;var chartTop=AXIS_PADDING_TOP;var chartBottom=this.chartHeight_-AXIS_PADDING_BOTTOM;var chartInnerWidth=chartRight-chartLeft;if(x>chartLeft&&x<chartRight&&y>chartTop&&y<chartBottom){this.currentBarMouseOverTarget_=Math.floor((x-chartLeft)/chartInnerWidth*this.opsTimingData_.length);this.currentBarMouseOverTarget_=tr.b.clamp(this.currentBarMouseOverTarget_,0,this.opsTimingData_.length-1);}
+if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)
+return;this.drawChartContents_();},updateChartContents:function(){if(this.requiresRedraw)
+this.updateChartDimensions_();this.drawChartContents_();},updateChartDimensions_:function(){this.chartWidth_=this.offsetWidth;this.chartHeight_=this.offsetHeight;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);},processPictureData_:function(){this.resetOpsTimingData_();this.pictureDataProcessed_=true;if(!this.picture_)
+return;var ops=this.picture_.getOps();if(!ops)
+return;ops=this.picture_.tagOpsWithTimings(ops);if(ops[0].cmd_time===undefined)
+return;this.collapseOpsToTimingBuckets_(ops);},drawChartContents_:function(){this.clearChartContents_();if(this.opsTimingData_.length===0){this.showNoTimingDataMessage_();return;}
+this.drawChartAxes_();this.drawBars_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===null)
+return;this.drawTooltip_();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();},drawTooltip_:function(){var tooltipData=this.opsTimingData_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var tooltipWidth=110;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;var barWidth=chartInnerWidth/this.opsTimingData_.length;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.textBaseline='top';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText('Total: '+tooltipTime+'ms',left+8,top+22);},drawBars_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-CHART_PADDING_LEFT-CHART_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var barWidth=Math.floor(width/len);var opData;var opTiming;var opHeight;var opLabel;var barLeft;for(var b=0;b<len;b++){opData=this.opsTimingData_[b];opTiming=opData.cmd_time/max;opHeight=Math.round(Math.max(1,opTiming*height));opLabel=opData.cmd_string;barLeft=CHART_PADDING_LEFT+b*barWidth;this.chartCtx_.fillStyle=this.getOpColor_(opLabel);this.chartCtx_.fillRect(barLeft+BAR_PADDING,AXIS_PADDING_TOP+
+height-opHeight,barWidth-2*BAR_PADDING,opHeight);}},getOpColor_:function(opName){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;return'hsl('+hue+', 30%, 50%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},drawChartAxes_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var totalBarWidth=this.chartWidth_-CHART_PADDING_LEFT-
+CHART_PADDING_RIGHT;var barWidth=Math.floor(totalBarWidth/len);var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.moveTo(0,0);this.chartCtx_.lineTo(0,height);this.chartCtx_.lineTo(width,height);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.save();this.chartCtx_.translate(CHART_PADDING_LEFT+Math.round(barWidth*0.5),AXIS_PADDING_TOP+height+LABEL_PADDING);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='top';var labelTickLeft;var labelTickBottom;for(var l=0;l<len;l++){labelTickLeft=Math.round(l*barWidth);labelTickBottom=l%2*LABEL_INTERLEAVE_OFFSET;this.chartCtx_.save();this.chartCtx_.moveTo(labelTickLeft,-LABEL_PADDING);this.chartCtx_.lineTo(labelTickLeft,labelTickBottom);this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.fillText(this.opsTimingData_[l].cmd_string,labelTickLeft,labelTickBottom);}
+this.chartCtx_.restore();this.chartCtx_.restore();},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);},collapseOpsToTimingBuckets_:function(ops){var opsTimingDataIndexHash_={};var timingData=this.opsTimingData_;var op;var opIndex;for(var i=0;i<ops.length;i++){op=ops[i];if(op.cmd_time===undefined)
+continue;opIndex=opsTimingDataIndexHash_[op.cmd_string]||null;if(opIndex===null){timingData.push({cmd_time:0,cmd_string:op.cmd_string});opIndex=timingData.length-1;opsTimingDataIndexHash_[op.cmd_string]=opIndex;}
+timingData[opIndex].cmd_time+=op.cmd_time;}
+timingData.sort(this.sortTimingBucketsByOpTimeDescending_);this.collapseTimingBucketsToOther_(4);},collapseTimingBucketsToOther_:function(count){var timingData=this.opsTimingData_;var otherSource=timingData.splice(count,timingData.length-count);var otherDestination=null;if(!otherSource.length)
+return;timingData.push({cmd_time:0,cmd_string:'Other'});otherDestination=timingData[timingData.length-1];for(var i=0;i<otherSource.length;i++){otherDestination.cmd_time+=otherSource[i].cmd_time;}},sortTimingBucketsByOpTimeDescending_:function(a,b){return b.cmd_time-a.cmd_time;},resetOpsTimingData_:function(){this.opsTimingData_.length=0;}};return{PictureOpsChartSummaryView:PictureOpsChartSummaryView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var BAR_PADDING=1;var BAR_WIDTH=5;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=30;var CHART_PADDING_BOTTOM=35;var CHART_PADDING_TOP=20;var AXIS_PADDING_LEFT=55;var AXIS_PADDING_RIGHT=30;var AXIS_PADDING_BOTTOM=35;var AXIS_PADDING_TOP=20;var AXIS_TICK_SIZE=5;var AXIS_LABEL_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-view');PictureOpsChartView.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.picture_=undefined;this.pictureOps_=undefined;this.opCosts_=undefined;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');this.appendChild(this.chart_);this.selectedOpIndex_=undefined;this.chartWidth_=0;this.chartHeight_=0;this.dimensionsHaveChanged_=true;this.currentBarMouseOverTarget_=undefined;this.ninetyFifthPercentileCost_=0;this.totalOpCost_=0;this.chart_.addEventListener('click',this.onClick_.bind(this));this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));this.usePercentileScale_=false;this.usePercentileScaleCheckbox_=tr.ui.b.createCheckBox(this,'usePercentileScale','PictureOpsChartView.usePercentileScale',false,'Limit to 95%-ile');this.usePercentileScaleCheckbox_.classList.add('use-percentile-scale');this.appendChild(this.usePercentileScaleCheckbox_);},get dimensionsHaveChanged(){return this.dimensionsHaveChanged_;},set dimensionsHaveChanged(dimensionsHaveChanged){this.dimensionsHaveChanged_=dimensionsHaveChanged;},get usePercentileScale(){return this.usePercentileScale_;},set usePercentileScale(usePercentileScale){this.usePercentileScale_=usePercentileScale;this.drawChartContents_();},get numOps(){return this.opCosts_.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(selectedOpIndex){if(selectedOpIndex<0)throw new Error('Invalid index');if(selectedOpIndex>=this.numOps)throw new Error('Invalid index');this.selectedOpIndex_=selectedOpIndex;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureOps_=picture.tagOpsWithTimings(picture.getOps());this.currentBarMouseOverTarget_=undefined;this.processPictureData_();this.dimensionsHaveChanged=true;},processPictureData_:function(){if(this.pictureOps_===undefined)
+return;var totalOpCost=0;this.opCosts_=this.pictureOps_.map(function(op){totalOpCost+=op.cmd_time;return op.cmd_time;});this.opCosts_.sort();var ninetyFifthPercentileCostIndex=Math.floor(this.opCosts_.length*0.95);this.ninetyFifthPercentileCost_=this.opCosts_[ninetyFifthPercentileCostIndex];this.maxCost_=this.opCosts_[this.opCosts_.length-1];this.totalOpCost_=totalOpCost;},extractBarIndex_:function(e){var index=undefined;if(this.pictureOps_===undefined||this.pictureOps_.length===0)
+return index;var x=e.offsetX;var y=e.offsetY;var totalBarWidth=(BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length;var chartLeft=CHART_PADDING_LEFT;var chartTop=0;var chartBottom=this.chartHeight_-CHART_PADDING_BOTTOM;var chartRight=chartLeft+totalBarWidth;if(x<chartLeft||x>chartRight||y<chartTop||y>chartBottom)
+return index;index=Math.floor((x-chartLeft)/totalBarWidth*this.pictureOps_.length);index=tr.b.clamp(index,0,this.pictureOps_.length-1);return index;},onClick_:function(e){var barClicked=this.extractBarIndex_(e);if(barClicked===undefined)
+return;if(barClicked===this.selectedOpIndex)
+this.selectedOpIndex=undefined;else
+this.selectedOpIndex=barClicked;e.preventDefault();tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=this.extractBarIndex_(e);if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)
+return;this.drawChartContents_();},scrollSelectedItemIntoViewIfNecessary:function(){if(this.selectedOpIndex===undefined)
+return;var width=this.offsetWidth;var left=this.scrollLeft;var right=left+width;var targetLeft=CHART_PADDING_LEFT+
+(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;if(targetLeft>left&&targetLeft<right)
+return;this.scrollLeft=(targetLeft-width*0.5);},updateChartContents:function(){if(this.dimensionsHaveChanged)
+this.updateChartDimensions_();this.drawChartContents_();},updateChartDimensions_:function(){if(!this.pictureOps_)
+return;var width=CHART_PADDING_LEFT+CHART_PADDING_RIGHT+
+((BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length);if(width<this.offsetWidth)
+width=this.offsetWidth;this.chartWidth_=width;this.chartHeight_=this.getBoundingClientRect().height;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);this.dimensionsHaveChanged=false;},drawChartContents_:function(){this.clearChartContents_();if(this.pictureOps_===undefined||this.pictureOps_.length===0||this.pictureOps_[0].cmd_time===undefined){this.showNoTimingDataMessage_();return;}
+this.drawSelection_();this.drawBars_();this.drawChartAxes_();this.drawLinesAtTickMarks_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===undefined)
+return;this.drawTooltip_();},drawSelection_:function(){if(this.selectedOpIndex===undefined)
+return;var width=(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;this.chartCtx_.fillStyle='rgb(223, 235, 230)';this.chartCtx_.fillRect(CHART_PADDING_LEFT,CHART_PADDING_TOP,width,this.chartHeight_-CHART_PADDING_TOP-CHART_PADDING_BOTTOM);},drawChartAxes_:function(){var min=this.opCosts_[0];var max=this.opCosts_[this.opCosts_.length-1];var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.beginPath();this.chartCtx_.moveTo(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.lineTo(AXIS_PADDING_LEFT,this.chartHeight_-
+AXIS_PADDING_BOTTOM);this.chartCtx_.lineTo(this.chartWidth_-AXIS_PADDING_RIGHT,this.chartHeight_-AXIS_PADDING_BOTTOM);this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';this.chartCtx_.beginPath();for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.restore();},drawLinesAtTickMarks_:function(){var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT+0.5,AXIS_PADDING_TOP+0.5);this.chartCtx_.beginPath();this.chartCtx_.strokeStyle='rgba(0,0,0,0.05)';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(width,tickYPosition);this.chartCtx_.stroke();}
+this.chartCtx_.restore();this.chartCtx_.closePath();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.beginPath();this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();this.chartCtx_.closePath();},drawTooltip_:function(){var tooltipData=this.pictureOps_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var toolTipTimePercentage=((tooltipData.cmd_time/this.totalOpCost_)*100).toFixed(2);var tooltipWidth=120;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;var barWidth=BAR_WIDTH+BAR_PADDING;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textAlign='left';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText(tooltipTime+'ms ('+
+toolTipTimePercentage+'%)',left+8,top+22);},drawBars_:function(){var op;var opColor=0;var opHeight=0;var opWidth=BAR_WIDTH+BAR_PADDING;var opHover=false;var bottom=this.chartHeight_-CHART_PADDING_BOTTOM;var maxHeight=this.chartHeight_-CHART_PADDING_BOTTOM-
+CHART_PADDING_TOP;var maxValue;if(this.usePercentileScale)
+maxValue=this.ninetyFifthPercentileCost_;else
+maxValue=this.maxCost_;for(var b=0;b<this.pictureOps_.length;b++){op=this.pictureOps_[b];opHeight=Math.round((op.cmd_time/maxValue)*maxHeight);opHeight=Math.max(opHeight,1);opHover=(b===this.currentBarMouseOverTarget_);opColor=this.getOpColor_(op.cmd_string,opHover);if(b===this.selectedOpIndex)
+this.chartCtx_.fillStyle='#FFFF00';else
+this.chartCtx_.fillStyle=opColor;this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_:function(opName,hover){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;var saturation=30;var lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView:PictureOpsChartView};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);this.appendChild(node);this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=this.querySelector('.size');this.rasterArea_=this.querySelector('raster-area');this.rasterCanvas_=this.rasterArea_.querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=this.querySelector('.filename');this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=this.querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();var overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');var chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');var pictureInfo=this.querySelector('picture-info');pictureInfo.appendChild(overdrawCheckbox);pictureInfo.appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));var leftPanel=this.querySelector('left-panel');leftPanel.appendChild(this.drawOpsChartSummaryView_);leftPanel.appendChild(this.drawOpsView_);var middleDragHandle=new tr.ui.b.DragHandle();middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=this.querySelector('right-panel');rightPanel.replaceChild(this.drawOpsChartView_,rightPanel.querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view'));this.infoBar_=document.createElement('tr-ui-b-info-bar');this.rasterArea_.appendChild(this.infoBar_);this.insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;var hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));this.appendChild(hkc);this.mutationObserver_=new MutationObserver(this.onMutation_.bind(this));this.mutationObserver_.observe(leftPanel,{attributes:true});},onMutation_:function(mutations){for(var m=0;m<mutations.length;m++){if(mutations[m].attributeName==='style'){this.drawOpsChartSummaryView_.requiresRedraw=true;this.drawOpsChartSummaryView_.updateChartContents();this.drawOpsChartView_.dimensionsHaveChanged=true;this.drawOpsChartView_.updateChartContents();break;}}},onSaveAsSkPictureClicked_:function(){var rawData=atob(this.picture_.getBase64SkpData());var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++)
+uint8Array[c]=rawData.charCodeAt(c);var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.webkitURL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=this.filename_.value;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},get picture(){return this.picture_;},set picture(picture){this.drawOpsView_.picture=picture;this.drawOpsChartView_.picture=picture;this.drawOpsChartSummaryView_.picture=picture;this.picture_=picture;this.exportButton_.disabled=!this.picture_.canSave;if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=Math.max(parseInt(style.width),this.picture_.layerRect.width);var height=Math.max(parseInt(style.height),this.picture_.layerRect.height);return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)
+return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){this.sizeInfo_.textContent='('+
+this.picture_.layerRect.width+' x '+
+this.picture_.layerRect.height+')';}
+this.drawOpsChartView_.updateChartContents();this.drawOpsChartView_.scrollSelectedItemIntoViewIfNecessary();if(!this.pictureAsImageData_)
+return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();overlay.textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width)
+this.rasterCanvas_.width=size.width;if(size.height!==this.rasterCanvas_.height)
+this.rasterCanvas_.height=size.height;this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.pictureAsImageData_.imageData)
+return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({stopIndex:this.drawOpsView_.selectedOpIndex,showOverdraw:this.showOverdraw_},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},moveSelectedOpBy:function(increment){if(this.selectedOpIndex===undefined){this.selectedOpIndex=0;return;}
+this.selectedOpIndex=tr.b.clamp(this.selectedOpIndex+increment,0,this.numOps);},get numOps(){return this.drawOpsView_.numOps;},get selectedOpIndex(){return this.drawOpsView_.selectedOpIndex;},set selectedOpIndex(index){this.drawOpsView_.selectedOpIndex=index;this.drawOpsChartView_.selectedOpIndex=index;},onChartBarClicked_:function(e){this.drawOpsView_.selectedOpIndex=this.drawOpsChartView_.selectedOpIndex;},onChangeDrawOps_:function(e){this.rasterize_();this.scheduleUpdateContents_();this.drawOpsChartView_.selectedOpIndex=this.drawOpsView_.selectedOpIndex;},set showOverdraw(v){this.showOverdraw_=v;this.rasterize_();},set showSummaryChart(chartShouldBeVisible){if(chartShouldBeVisible)
+this.drawOpsChartSummaryView_.show();else
+this.drawOpsChartSummaryView_.hide();},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;this.rasterArea_.appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)
+return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};}};return{PictureDebugger:PictureDebugger};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var PictureSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-snapshot-view',tr.ui.analysis.ObjectSnapshotView);PictureSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-picture-snapshot-view');this.pictureDebugger_=new tr.ui.e.chrome.cc.PictureDebugger();this.appendChild(this.pictureDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.pictureDebugger_)
+this.pictureDebugger_.picture=this.objectSnapshot_;}};tr.ui.analysis.ObjectSnapshotView.register(PictureSnapshotView,{typeNames:['cc::Picture','cc::LayeredPicture'],showInstances:false});return{PictureSnapshotView:PictureSnapshotView};});'use strict';tr.exportTo('tr.e.cc',function(){var knownRasterTaskNames=['TileManager::RunRasterTask','RasterWorkerPoolTaskImpl::RunRasterOnThread','RasterWorkerPoolTaskImpl::Raster','RasterTaskImpl::Raster','cc::RasterTask','RasterTask'];var knownAnalysisTaskNames=['TileManager::RunAnalyzeTask','RasterWorkerPoolTaskImpl::RunAnalysisOnThread','RasterWorkerPoolTaskImpl::Analyze','RasterTaskImpl::Analyze','cc::AnalyzeTask','AnalyzeTask'];function getTileFromRasterTaskSlice(slice){if(!(isSliceDoingRasterization(slice)||isSliceDoingAnalysis(slice)))
+return undefined;var tileData;if(slice.args.data)
+tileData=slice.args.data;else
+tileData=slice.args.tileData;if(tileData===undefined)
+return undefined;if(tileData.tile_id)
+return tileData.tile_id;var tile=tileData.tileId;if(!(tile instanceof tr.e.cc.TileSnapshot))
+return undefined;return tileData.tileId;}
+function isSliceDoingRasterization(slice){if(knownRasterTaskNames.indexOf(slice.title)!==-1)
+return true;return false;}
+function isSliceDoingAnalysis(slice){if(knownAnalysisTaskNames.indexOf(slice.title)!==-1)
+return true;return false;}
+return{getTileFromRasterTaskSlice:getTileFromRasterTaskSlice,isSliceDoingRasterization:isSliceDoingRasterization,isSliceDoingAnalysis:isSliceDoingAnalysis};});'use strict';Polymer('tr-ui-e-chrome-cc-raster-task-view',{created:function(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_:function(hadCpuDurations){var timeSpanConfig={ownerDocument:this.ownerDocument};var columns=[{title:'Layer',value:function(row){if(row.isTotals)
+return'Totals';if(row.layer){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(costs.layer);},'Layer '+row.layerId);return linkEl;}else{return'Layer '+row.layerId;}},width:'250px'},{title:'Num Tiles',value:function(row){return row.numTiles;},cmp:function(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value:function(row){return row.numAnalysisTasks;},cmp:function(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value:function(row){return row.numRasterTasks;},cmp:function(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.ui.units.createTimeDurationSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.cpuDuration-b.cpuDuration;}});}
+var colWidthPercentage;if(columns.length==1)
+colWidthPercentage='100%';else
+colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';for(var i=1;i<columns.length;i++)
+columns[i].width=colWidthPercentage;this.$.content.tableColumns=columns;this.$.content.sortColumnIndex=columns.length-1;},updateContents_:function(){var table=this.$.content;if(this.selection_.length===0){this.$.link.setSelectionAndContent(undefined,'');table.tableRows=[];table.footerRows=[];table.rebuild();return;}
+var lthi=tr.e.cc.getTileFromRasterTaskSlice(this.selection_[0]).containingSnapshot;this.$.link.setSelectionAndContent(function(){return new tr.model.EventSet(lthi);},lthi.userFriendlyName);var costsByLayerId={};function getCurrentCostsForLayerId(tile){var layerId=tile.layerId;var lthi=tile.containingSnapshot;var layer;if(lthi.activeTree)
+layer=lthi.activeTree.findLayerWithId(layerId);if(layer===undefined&&lthi.pendingTree)
+layer=lthi.pendingTree.findLayerWithId(layerId);if(costsByLayerId[layerId]===undefined){costsByLayerId[layerId]={layerId:layerId,layer:layer,numTiles:0,numAnalysisTasks:0,numRasterTasks:0,duration:0,cpuDuration:0};}
+return costsByLayerId[layerId];}
+var totalDuration=0;var totalCpuDuration=0;var totalNumAnalyzeTasks=0;var totalNumRasterizeTasks=0;var hadCpuDurations=false;var tilesThatWeHaveSeen={};this.selection_.forEach(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);var curCosts=getCurrentCostsForLayerId(tile);if(!tilesThatWeHaveSeen[tile.objectInstance.id]){tilesThatWeHaveSeen[tile.objectInstance.id]=true;curCosts.numTiles+=1;}
+if(tr.e.cc.isSliceDoingAnalysis(slice)){curCosts.numAnalysisTasks+=1;totalNumAnalyzeTasks+=1;}else{curCosts.numRasterTasks+=1;totalNumRasterizeTasks+=1;}
+curCosts.duration+=slice.duration;totalDuration+=slice.duration;if(slice.cpuDuration!==undefined){curCosts.cpuDuration+=slice.cpuDuration;totalCpuDuration+=slice.cpuDuration;hadCpuDurations=true;}});this.updateColumns_(hadCpuDurations);table.tableRows=tr.b.dictionaryValues(costsByLayerId);table.rebuild();table.footerRows=[{isTotals:true,numTiles:tr.b.dictionaryLength(tilesThatWeHaveSeen),numAnalysisTasks:totalNumAnalyzeTasks,numRasterTasks:totalNumRasterizeTasks,duration:totalDuration,cpuDuration:totalCpuDuration}];}});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function RasterTaskSelection(selection){tr.ui.e.chrome.cc.Selection.call(this);var whySupported=RasterTaskSelection.whySuported(selection);if(!whySupported.ok)
+throw new Error('Fail: '+whySupported.why);this.slices_=tr.b.asArray(selection);this.tiles_=this.slices_.map(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);if(tile===undefined)
+throw new Error('This should never happen due to .supports check.');return tile;});}
+RasterTaskSelection.whySuported=function(selection){if(!(selection instanceof tr.model.EventSet))
+return{ok:false,why:'Must be selection'};if(selection.length===0)
+return{ok:false,why:'Selection must be non empty'};var tile0;for(var i=0;i<selection.length;i++){var event=selection[i];if(!(event instanceof tr.model.Slice))
+return{ok:false,why:'Not a slice'};var tile=tr.e.cc.getTileFromRasterTaskSlice(selection[i]);if(tile===undefined)
+return{ok:false,why:'No tile found'};if(i===0){tile0=tile;}else{if(tile.containingSnapshot!=tile0.containingSnapshot){return{ok:false,why:'Raster tasks are from different compositor instances'};}}}
+return{ok:true};}
+RasterTaskSelection.supports=function(selection){return RasterTaskSelection.whySuported(selection).ok;};RasterTaskSelection.prototype={__proto__:tr.ui.e.chrome.cc.Selection.prototype,get specicifity(){return 3;},get associatedLayerId(){var tile0=this.tiles_[0];var allSameLayer=this.tiles_.every(function(tile){tile.layerId==tile0.layerId;});if(allSameLayer)
+return tile0.layerId;return undefined;},get extraHighlightsByLayerId(){var highlights={};this.tiles_.forEach(function(tile,i){if(highlights[tile.layerId]===undefined)
+highlights[tile.layerId]=[];var slice=this.slices_[i];highlights[tile.layerId].push({colorKey:slice.title,rect:tile.layerRect});},this);return highlights;},createAnalysis:function(){var sel=new tr.model.EventSet();this.slices_.forEach(function(slice){sel.push(slice);});var analysis;if(sel.length==1)
+analysis=document.createElement('tr-ui-a-single-event-sub-view');else
+analysis=document.createElement('tr-ui-e-chrome-cc-raster-task-view');analysis.selection=sel;return analysis;},findEquivalent:function(lthi){return undefined;},get containingSnapshot(){return this.tiles_[0].containingSnapshot;}};return{RasterTaskSelection:RasterTaskSelection};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var TileSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-tile-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TileSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-cc-tile-snapshot-view');this.layerTreeView_=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();this.appendChild(this.layerTreeView_);},updateContents:function(){var tile=this.objectSnapshot_;var layerTreeHostImpl=tile.containingSnapshot;if(!layerTreeHostImpl)
+return;this.layerTreeView_.objectSnapshot=layerTreeHostImpl;this.layerTreeView_.selection=new tr.ui.e.chrome.cc.TileSelection(tile);}};tr.ui.analysis.ObjectSnapshotView.register(TileSnapshotView,{typeName:'cc::Tile',showInTrackView:false});return{TileSnapshotView:TileSnapshotView};});'use strict';tr.exportTo('tr.e.gpu',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function StateSnapshot(){ObjectSnapshot.apply(this,arguments);}
+StateSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){this.screenshot_=undefined;},initialize:function(){if(this.args.screenshot)
+this.screenshot_=this.args.screenshot;},get screenshot(){return this.screenshot_;}};ObjectSnapshot.register(StateSnapshot,{typeName:'gpu::State'});return{StateSnapshot:StateSnapshot};});'use strict';tr.exportTo('tr.e.gpu',function(){var AsyncSlice=tr.model.AsyncSlice;function GpuAsyncSlice(){AsyncSlice.apply(this,arguments);}
+GpuAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){if(this.args.channel){if(this.category=='disabled-by-default-gpu.device')
+return'Device.'+this.args.channel;else
+return'Service.'+this.args.channel;}
+return this.title;}};AsyncSlice.register(GpuAsyncSlice,{categoryParts:['disabled-by-default-gpu.device','disabled-by-default-gpu.service']});return{GpuAsyncSlice:GpuAsyncSlice};});'use strict';tr.exportTo('tr.ui.e.chrome.gpu',function(){var StateSnapshotView=tr.ui.b.define('tr-ui-e-chrome-gpu-state-snapshot-view',tr.ui.analysis.ObjectSnapshotView);StateSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-chrome-gpu-state-snapshot-view');this.screenshotImage_=document.createElement('img');this.appendChild(this.screenshotImage_);},updateContents:function(){if(this.objectSnapshot_&&this.objectSnapshot_.screenshot){this.screenshotImage_.src='data:image/png;base64,'+
+this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView:StateSnapshotView};});'use strict';tr.exportTo('tr.e.system_stats',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats=args;}
+SystemStatsSnapshot.prototype={__proto__:ObjectSnapshot.prototype,initialize:function(){if(this.args.length==0)
+throw new Error('No system stats snapshot data.');this.stats_=this.args;},getStats:function(){return this.stats_;},setStats:function(stats){this.stats_=stats;}};ObjectSnapshot.register(SystemStatsSnapshot,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshot:SystemStatsSnapshot};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var SystemStatsSnapshotView=tr.ui.b.define('tr-ui-e-system-stats-snapshot-view',tr.ui.analysis.ObjectSnapshotView);SystemStatsSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-system-stats-snapshot-view');},updateContents:function(){var snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.getStats()){this.textContent='No system stats snapshot found.';return;}
+this.textContent='';var stats=snapshot.getStats();this.appendChild(this.buildList_(stats));},isFloat:function(n){return typeof n==='number'&&n%1!==0;},buildList_:function(stats){var statList=document.createElement('ul');for(var statName in stats){var statText=document.createElement('li');statText.textContent=''+statName+': ';statList.appendChild(statText);if(stats[statName]instanceof Object){statList.appendChild(this.buildList_(stats[statName]));}else{if(this.isFloat(stats[statName]))
+statText.textContent+=stats[statName].toFixed(2);else
+statText.textContent+=stats[statName];}}
+return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView:SystemStatsSnapshotView};});'use strict';tr.exportTo('tr.ui.tracks',function(){var StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);this.classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-heading');this.appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap:function(eventToTrackMap){var objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
+var snapshots=this.objectInstance_.snapshots;var maxBounds=this.objectInstance_.parent.model.bounds.max;tr.b.iterateOverIntersectingIntervals(snapshots,function(x){return x.ts;},function(x,i){if(i==snapshots.length-1){if(snapshots.length==1)
+return maxBounds;return snapshots[i].ts-snapshots[i-1].ts;}
+return snapshots[i+1].ts-snapshots[i].ts;},loWX,hiWX,onSnapshot);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(!(event instanceof tr.model.ObjectSnapshot))
+throw new Error('Unrecognized event');var objectSnapshots=this.objectInstance_.snapshots;var index=objectSnapshots.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<objectSnapshots.length){selection.push(objectSnapshots[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.findClosestElementInSortedArray(this.objectInstance_.snapshots,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)
+return;selection.push(snapshot);}};return{StackedBarsTrack:StackedBarsTrack};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var EventPresenter=tr.ui.b.EventPresenter;var statCount;var excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{}};var SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);this.classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
+if(objectInstances.length!=1)
+throw new Error('Bad object instance count.');this.objectInstance_=objectInstances[0];if(this.objectInstance_!==null){this.computeRates_(this.objectInstance_.snapshots);this.maxStats_=this.computeMaxStats_(this.objectInstance_.snapshots);}},computeRates_:function(snapshots){for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();var prevSnapshot;var prevStats;if(i==0){prevSnapshot=snapshots[0];}else{prevSnapshot=snapshots[i-1];}
+prevStats=prevSnapshot.getStats();var timeIntervalSeconds=(snapshot.ts-prevSnapshot.ts)/1000;if(timeIntervalSeconds==0)
+timeIntervalSeconds=1;this.computeRatesRecursive_(prevStats,stats,timeIntervalSeconds);}},computeRatesRecursive_:function(prevStats,stats,timeIntervalSeconds){for(var statName in stats){if(stats[statName]instanceof Object){this.computeRatesRecursive_(prevStats[statName],stats[statName],timeIntervalSeconds);}else{if(statName=='sectors_read'){stats['bytes_read_per_sec']=(stats['sectors_read']-
+prevStats['sectors_read'])*512/timeIntervalSeconds;}
+if(statName=='sectors_written'){stats['bytes_written_per_sec']=(stats['sectors_written']-
+prevStats['sectors_written'])*512/timeIntervalSeconds;}
+if(statName=='pgmajfault'){stats['pgmajfault_per_sec']=(stats['pgmajfault']-
+prevStats['pgmajfault'])/timeIntervalSeconds;}
+if(statName=='pswpin'){stats['bytes_swpin_per_sec']=(stats['pswpin']-
+prevStats['pswpin'])*1000/timeIntervalSeconds;}
+if(statName=='pswpout'){stats['bytes_swpout_per_sec']=(stats['pswpout']-
+prevStats['pswpout'])*1000/timeIntervalSeconds;}}}},computeMaxStats_:function(snapshots){var maxStats=new Object();statCount=0;for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();this.computeMaxStatsRecursive_(stats,maxStats,excludedStats);}
+return maxStats;},computeMaxStatsRecursive_:function(stats,maxStats,excludedStats){for(var statName in stats){if(stats[statName]instanceof Object){if(!(statName in maxStats))
+maxStats[statName]=new Object();var excludedNested;if(excludedStats&&statName in excludedStats)
+excludedNested=excludedStats[statName];else
+excludedNested=null;this.computeMaxStatsRecursive_(stats[statName],maxStats[statName],excludedNested);}else{if(excludedStats&&statName in excludedStats)
+continue;if(!(statName in maxStats)){maxStats[statName]=0;statCount++;}
+if(stats[statName]>maxStats[statName])
+maxStats[statName]=stats[statName];}}},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawStatBars_(viewLWorld,viewRWorld);break;}},drawStatBars_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var width=bounds.width*pixelRatio;var height=(bounds.height*pixelRatio)/statCount;var vp=this.viewport.currentDisplayTransform;var maxStats=this.maxStats_;var objectSnapshots=this.objectInstance_.snapshots;var lowIndex=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)
+lowIndex-=1;for(var i=lowIndex;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var trace=snapshot.getStats();var currentY=height;var left=snapshot.ts;if(left>viewRWorld)
+break;var leftView=vp.xWorldToView(left);if(leftView<0)
+leftView=0;var right;if(i!=objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1)
+right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
+objectSnapshots[i-1].ts);else
+right=this.objectInstance_.parent.model.bounds.max;}
+var rightView=vp.xWorldToView(right);if(rightView>width)
+rightView=width;leftView=Math.floor(leftView);rightView=Math.floor(rightView);this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,trace,maxStats,currentY);if(i==lowIndex)
+this.drawStatNames_(leftView,height,currentY,'',maxStats);}
+ctx.lineWidth=1;},drawStatBarsRecursive_:function(snapshot,leftView,rightView,height,stats,maxStats,currentY){var ctx=this.context();for(var statName in maxStats){if(stats[statName]instanceof Object){currentY=this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats[statName],maxStats[statName],currentY);}else{var maxStat=maxStats[statName];ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,Math.round(currentY/height));var barHeight;if(maxStat>0){barHeight=height*Math.max(stats[statName],0)/maxStat;}else{barHeight=0;}
+ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY+=height;}}
+return currentY;},drawStatNames_:function(leftView,height,currentY,prefix,maxStats){var ctx=this.context();ctx.textAlign='end';ctx.font='12px Arial';ctx.fillStyle='#000000';for(var statName in maxStats){if(maxStats[statName]instanceof Object){currentY=this.drawStatNames_(leftView,height,currentY,statName,maxStats[statName]);}else{var fullname=statName;if(prefix!='')
+fullname=prefix+' :: '+statName;ctx.fillText(fullname,leftView-10,currentY-height/4);currentY+=height;}}
+return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack:SystemStatsInstanceTrack};});'use strict';tr.exportTo('tr.e.tcmalloc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function HeapSnapshot(){ObjectSnapshot.apply(this,arguments);}
+HeapSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){if(this.args.length==0)
+throw new Error('No heap snapshot data.');this.total_=this.args[0];var allocs=this.args.slice(1);this.heap_={children:{},currentBytes:0,currentAllocs:0,totalBytes:0,totalAllocs:0};for(var i=0;i<allocs.length;i++){var alloc=allocs[i];var traceNames=alloc.trace.split(' ');if(traceNames.indexOf('trace-memory-ignore')!=-1)
+continue;var heapEntry=this.heap_;for(var j=0;j<traceNames.length;j++){var traceName=traceNames[j];if(traceName.length!=0){heapEntry.currentBytes+=alloc.currentBytes;heapEntry.currentAllocs+=alloc.currentAllocs;heapEntry.totalBytes+=alloc.totalBytes;heapEntry.totalAllocs+=alloc.totalAllocs;}
+if(!heapEntry.children[traceName]){heapEntry.children[traceName]={children:{},currentBytes:alloc.currentBytes,currentAllocs:alloc.currentAllocs,totalBytes:alloc.totalBytes,totalAllocs:alloc.totalAllocs};}
+heapEntry=heapEntry.children[traceName];}}}};ObjectSnapshot.register(HeapSnapshot,{typeName:'memory::Heap'});return{HeapSnapshot:HeapSnapshot};});'use strict';tr.exportTo('tr.ui.e.tcmalloc',function(){var TcmallocInstanceView=tr.ui.b.define('tr-ui-e-tcmalloc-instance-view',tr.ui.analysis.ObjectInstanceView);TcmallocInstanceView.prototype={__proto__:tr.ui.analysis.ObjectInstanceView.prototype,decorate:function(){tr.ui.analysis.ObjectInstanceView.prototype.decorate.apply(this);this.classList.add('tr-ui-e-tcmalloc-instance-view');},updateContents:function(){var instance=this.objectInstance_;if(!instance||!instance.snapshots||instance.snapshots.length==0){this.textContent='No data found.';return;}
+this.textContent='';var snapshot=instance.snapshots[0];var heapEntry=snapshot.heap_;var traceNames=Object.keys(heapEntry.children);traceNames.sort(function(a,b){return heapEntry.children[b].currentBytes-
+heapEntry.children[a].currentBytes;});traceNames=traceNames.slice(0,5);var table=document.createElement('table');var titles=['Total'];titles=titles.concat(traceNames);table.appendChild(this.buildRow_(null,titles));var chartArrays=[[],[],[],[],[]];for(var i=0;i<instance.snapshots.length;i++){var snapshot=instance.snapshots[i];var rowData=[snapshot.total_.currentBytes];for(var j=0;j<5;j++){var bytes=snapshot.heap_.children[traceNames[j]].currentBytes;rowData.push(bytes);chartArrays[j].push([Math.round(snapshot.ts/1000),bytes/1024/1024]);}
+var row=this.buildRow_(snapshot,rowData);table.appendChild(row);}
+this.appendChild(table);},buildRow_:function(snapshot,items){var row=document.createElement('tr');var td=document.createElement('td');if(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);td.appendChild(snapshotLink);}
+row.appendChild(td);for(var i=0;i<items.length;i++){var data=document.createElement('td');data.textContent=items[i];row.appendChild(data);}
+return row;},getByteString_:function(bytes){var mb=bytes/1024/1024;return mb.toFixed(1)+' MB';}};tr.ui.analysis.ObjectInstanceView.register(TcmallocInstanceView,{typeName:'memory::Heap'});return{TcmallocInstanceView:TcmallocInstanceView};});'use strict';tr.exportTo('tr.ui.e.tcmalloc',function(){var TcmallocSnapshotView=tr.ui.b.define('tr-ui-e-tcmalloc-heap-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TcmallocSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){this.classList.add('tr-ui-e-tcmalloc-heap-snapshot-view');},updateContents:function(){var snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.heap_){this.textContent='No heap found.';return;}
+this.textContent='';var subhead=document.createElement('div');subhead.textContent='Retaining '+
+this.getByteString_(snapshot.total_.currentBytes)+' in '+
+snapshot.total_.currentAllocs+' allocations. Showing > 0.1 MB.';subhead.className='subhead';this.appendChild(subhead);var myList=this.buildAllocList_(snapshot.heap_,false);this.appendChild(myList);},buildAllocList_:function(heapEntry,hide){var myList=document.createElement('ul');myList.hidden=hide;var keys=Object.keys(heapEntry.children);keys.sort(function(a,b){return heapEntry.children[b].currentBytes-
+heapEntry.children[a].currentBytes;});for(var i=0;i<keys.length;i++){var traceName=keys[i];var trace=heapEntry.children[traceName];if(trace.currentBytes<100*1024)
+continue;var childCount=Object.keys(trace.children).length;var isLeaf=childCount==0;var myItem=this.buildItem_(traceName,isLeaf,trace.currentBytes,trace.currentAllocs);myList.appendChild(myItem);if(childCount>0)
+myItem.appendChild(this.buildAllocList_(trace,true));}
+return myList;},buildItem_:function(traceName,isLeaf,bytes,allocs){var myItem=document.createElement('li');myItem.className='trace-item';myItem.id=traceName;var byteDiv=document.createElement('div');byteDiv.textContent=this.getByteString_(bytes);byteDiv.className='trace-bytes';myItem.appendChild(byteDiv);if(traceName.length==0){traceName='(here)';}else if(traceName.indexOf('..')==0){var lastSlash=traceName.lastIndexOf('/');if(lastSlash!=-1)
+traceName='Task from '+traceName.substr(lastSlash+1);}
+var traceDiv=document.createElement('div');traceDiv.textContent=traceName;traceDiv.className='trace-name';myItem.appendChild(traceDiv);if(isLeaf)
+return myItem;var self=this;myItem.addEventListener('click',function(event){if(this==event.target||this==event.target.parentElement){this.classList.toggle('expanded');var child=this.querySelector('ul');child.hidden=!child.hidden;self.onItemClicked_(this);}});myItem.classList.add('collapsed');return myItem;},onItemClicked_:function(traceItem){var traces=[];while(traceItem.classList.contains('trace-item')){var traceNameDiv=traceItem.firstElementChild.nextElementSibling;traces.unshift(traceNameDiv.textContent);var traceNameUl=traceItem.parentElement;traceItem=traceNameUl.parentElement;}
+var instance=this.objectSnapshot_.objectInstance;instance.selectedTraces=traces;var trackView=document.querySelector('.timeline-track-view');trackView.viewport_.dispatchChangeEvent();},getByteString_:function(bytes){var mb=bytes/1024/1024;return mb.toFixed(1)+' MB';}};tr.ui.analysis.ObjectSnapshotView.register(TcmallocSnapshotView,{typeName:'memory::Heap'});return{TcmallocSnapshotView:TcmallocSnapshotView};});'use strict';tr.exportTo('tr.ui.e.tcmalloc',function(){var EventPresenter=tr.ui.b.EventPresenter;var HeapInstanceTrack=tr.ui.b.define('tr-ui-e-tcmalloc-heap-instance-track',tr.ui.tracks.StackedBarsTrack);HeapInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);this.classList.add('tr-ui-e-tcmalloc-heap-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
+if(objectInstances.length!=1)
+throw new Error('Bad object instance count.');this.objectInstance_=objectInstances[0];this.maxBytes_=this.computeMaxBytes_(this.objectInstance_.snapshots);},computeMaxBytes_:function(snapshots){var maxBytes=0;for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var traceNames=Object.keys(snapshot.heap_.children);var sumBytes=0;for(var j=0;j<traceNames.length;j++){sumBytes+=snapshot.heap_.children[traceNames[j]].currentBytes;}
+if(sumBytes>maxBytes)
+maxBytes=sumBytes;}
+return maxBytes;},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawEvents_(viewLWorld,viewRWorld);break;}},drawEvents_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var dt=this.viewport.currentDisplayTransform;var maxBytes=this.maxBytes_;var objectSnapshots=this.objectInstance_.snapshots;var lowIndex=tr.b.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)
+lowIndex-=1;for(var i=lowIndex;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var left=snapshot.ts;if(left>viewRWorld)
+break;var leftView=dt.xWorldToView(left);if(leftView<0)
+leftView=0;var right;if(i!=objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1)
+right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
+objectSnapshots[i-1].ts);else
+right=this.objectInstance_.parent.model.bounds.max;}
+var rightView=dt.xWorldToView(right);if(rightView>width)
+rightView=width;leftView=Math.floor(leftView);rightView=Math.floor(rightView);var currentY=height;var keys=Object.keys(snapshot.heap_.children);for(var k=keys.length-1;k>=0;k--){var trace=snapshot.heap_.children[keys[k]];if(this.objectInstance_.selectedTraces&&this.objectInstance_.selectedTraces.length>0&&this.objectInstance_.selectedTraces[0]==keys[k]){ctx.fillStyle='rgb(239, 248, 206)';}else
+ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,k);var barHeight=height*trace.currentBytes/maxBytes;ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY-=barHeight;}}
+ctx.lineWidth=1;}};tr.ui.tracks.ObjectInstanceTrack.register(HeapInstanceTrack,{typeName:'memory::Heap'});return{HeapInstanceTrack:HeapInstanceTrack};});'use strict';Polymer('tr-ui-e-s-category-summary-side-panel',{ready:function(){},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get listeningToKeys(){return false;},set selection(selection){},set rangeOfInterest(rangeOfInterest){},updateContents_:function(){this.$.table.tableColumns=[{title:'Category / Title',value:function(row){return row.title;}},{title:'Events',textAlign:'right',value:function(row){return row.count;}}];if(this.model_===undefined){this.$.table.tableRows=[];return;}
+var categories={};this.model_.iterateAllEvents(function handleEvent(event){if(!(event instanceof tr.model.Slice)&&!(event instanceof tr.model.AsyncSlice)&&!(event instanceof tr.model.InstantEvent)&&!(event instanceof tr.model.FlowEvent))
+return;tr.b.getCategoryParts(event.category).forEach(function(category){if(categories[category]===undefined){categories[category]={};}
+var titleCounts=categories[category];if(titleCounts[event.title]===undefined){titleCounts[event.title]=0;}
+titleCounts[event.title]+=1;});});function compareCounts(a,b){return b.count-a.count;}
+var rows=[];for(var category in categories){var categoryRow={title:category,subRows:[],count:0};rows.push(categoryRow);var titleCounts=categories[category];for(var title in titleCounts){var count=titleCounts[title];categoryRow.count+=count;categoryRow.subRows.push({title:title,count:count});}
+categoryRow.subRows.sort(compareCounts);}
+rows.sort(compareCounts);this.$.table.tableRows=rows;},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}
+return{supported:true};},get textLabel(){return'Categories';}});'use strict';Polymer('tr-ui-e-s-input-latency-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.frametimeType_=tr.e.audits.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_)
+this.modelHelper_=new tr.e.audits.ChromeModelHelper(model);else
+this.modelHelper_=undefined;this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)
+return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)
+return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)
+return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices:function(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_:function(){if(this.latencyChart_===undefined)
+return;var r=new tr.b.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
+r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;var latencySlices=[];this.model_.getAllThreads().forEach(function(thread){thread.iterateAllEvents(function(event){if(event.title.indexOf('InputLatency:')===0)
+latencySlices.push(event);});});latencySlices=tr.e.audits.getSlicesIntersectingRange(r,latencySlices);var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_:function(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button==undefined)
+return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_:function(){var browserProcess=this.modelHelper_.browserProcess;var labels=[];if(browserProcess!==undefined){var label_str='Browser: '+browserProcess.pid;labels.push({label:label_str,value:browserProcess.pid});}
+tr.b.iterItems(this.modelHelper_.rendererHelpers,function(pid,rendererHelper){var rendererProcess=rendererHelper.process;var label_str='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:label_str,value:rendererProcess.userFriendlyName});},this);if(labels.length===0)
+return;this.selectedProcessId_=labels[0].value;var toolbarEl=this.$.toolbar;toolbarEl.appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.e.audits.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.e.audits.IMPL_FRAMETIME_TYPE}]));toolbarEl.appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty)
+return this.model_.bounds;else
+return this.rangeOfInterest_;},createLatencyLineChart:function(data,title){var chart=new tr.ui.b.LineChart();var width=600;if(document.body.clientWidth!=undefined)
+width=document.body.clientWidth*0.5;chart.setSize({width:width,height:chart.height});chart.chartTitle=title;chart.data=data;return chart;},updateContents_:function(){var resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;resultArea.textContent='';if(this.modelHelper_===undefined)
+return;var rangeOfInterest=this.currentRangeOfInterest;var chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_])
+chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];else
+chromeProcess=this.modelHelper_.browserHelper;var frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);var frametimeData=tr.e.audits.getFrametimeDataFromEvents(frameEvents);var averageFrametime=tr.b.Statistics.mean(frametimeData,function(d){return d.frametime;});var latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);var latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)
+return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});var averageLatency=tr.b.Statistics.mean(latencyData,function(d){return d.latency;});var latencySummaryText=document.createElement('div');latencySummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));resultArea.appendChild(latencySummaryText);var frametimeSummaryText=document.createElement('div');frametimeSummaryText.appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));resultArea.appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time');this.registerMouseEventForLatencyChart_();resultArea.appendChild(this.latencyChart_);}
+if(frametimeData.length!=0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times');this.frametimeChart_.style.display='block';resultArea.appendChild(this.frametimeChart_);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}
+if(!tr.e.audits.ChromeModelHelper.supportsModel(m)){return{supported:false,reason:'No Chrome browser or renderer process found'};}
+var modelHelper=new tr.e.audits.ChromeModelHelper(m);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
+return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase=tr.ui.b.ChartBase;var getColorOfKey=tr.ui.b.getColorOfKey;var MIN_RADIUS=100;var PieChart=tr.ui.b.define('pie-chart',ChartBase);PieChart.prototype={__proto__:ChartBase.prototype,decorate:function(){ChartBase.prototype.decorate.call(this);this.classList.add('pie-chart');this.data_=undefined;this.seriesKeys_=undefined;var chartAreaSel=d3.select(this.chartAreaElement);var pieGroupSel=chartAreaSel.append('g').attr('class','pie-group');this.pieGroup_=pieGroupSel.node();this.pathsGroup_=pieGroupSel.append('g').attr('class','paths').node();this.labelsGroup_=pieGroupSel.append('g').attr('class','labels').node();this.linesGroup_=pieGroupSel.append('g').attr('class','lines').node();},get data(){return this.data_;},set data(data){if(data!==undefined){var seriesKeys=[];var seenSeriesKeys={};data.forEach(function(d){var k=d.label;if(seenSeriesKeys[k])
+throw new Error('Label '+k+' has been used already');seriesKeys.push(k);seenSeriesKeys[k]=true;},this);this.seriesKeys_=seriesKeys;}else{this.seriesKeys_=undefined;}
+this.data_=data;this.updateContents_();},get margin(){var margin={top:0,right:0,bottom:0,left:0};if(this.chartTitle_)
+margin.top+=40;return margin;},getMinSize:function(){this.updateContents_();var labelSel=d3.select(this.labelsGroup_).selectAll('.label');var maxLabelWidth=-Number.MAX_VALUE;var leftTextHeightSum=0;var rightTextHeightSum=0;labelSel.each(function(l){var r=this.getBoundingClientRect();maxLabelWidth=Math.max(maxLabelWidth,r.width+32);if(this.style.textAnchor=='end'){leftTextHeightSum+=r.height;}else{rightTextHeightSum+=r.height;}});var titleWidth=this.querySelector('#title').getBoundingClientRect().width;var margin=this.margin;var marginWidth=margin.left+margin.right;var marginHeight=margin.top+margin.bottom;return{width:Math.max(2*MIN_RADIUS+2*maxLabelWidth,titleWidth*1.1)+marginWidth,height:marginHeight+Math.max(2*MIN_RADIUS,leftTextHeightSum,rightTextHeightSum)*1.25};},getLegendKeys_:function(){return undefined;},updateScales_:function(width,height){if(this.data_===undefined)
+return;},updateContents_:function(){ChartBase.prototype.updateContents_.call(this);if(!this.data_)
+return;var width=this.chartAreaSize.width;var height=this.chartAreaSize.height;var radius=Math.max(MIN_RADIUS,Math.min(width,height*0.95)/2);d3.select(this.pieGroup_).attr('transform','translate('+width/2+','+height/2+')');var pieLayout=d3.layout.pie().value(function(d){return d.value;}).sort(null);var piePathsSel=d3.select(this.pathsGroup_).datum(this.data_).selectAll('path').data(pieLayout);function midAngle(d){return d.startAngle+(d.endAngle-d.startAngle)/2;}
+var pathsArc=d3.svg.arc().innerRadius(0).outerRadius(radius-30);var valueLabelArc=d3.svg.arc().innerRadius(radius-100).outerRadius(radius-30);var lineBeginArc=d3.svg.arc().innerRadius(radius-50).outerRadius(radius-50);var lineEndArc=d3.svg.arc().innerRadius(radius).outerRadius(radius);piePathsSel.enter().append('path').attr('class','arc').attr('fill',function(d,i){var origData=this.data_[i];var highlighted=(origData.label===this.currentHighlightedLegendKey);return getColorOfKey(origData.label,highlighted);}.bind(this)).attr('d',pathsArc).on('click',function(d,i){var origData=this.data_[i];var event=new tr.b.Event('item-click');event.data=origData;event.index=i;this.dispatchEvent(event);d3.event.stopPropagation();}.bind(this)).on('mouseenter',function(d,i){var origData=this.data_[i];this.pushTempHighlightedLegendKey(origData.label);}.bind(this)).on('mouseleave',function(d,i){var origData=this.data_[i];this.popTempHighlightedLegendKey(origData.label);}.bind(this));piePathsSel.enter().append('text').attr('class','arc-text').attr('transform',function(d){return'translate('+valueLabelArc.centroid(d)+')';}).attr('dy','.35em').style('text-anchor','middle').text(function(d,i){var origData=this.data_[i];if(origData.valueText===undefined)
+return'';if(d.endAngle-d.startAngle<0.4)
+return'';return origData.valueText;}.bind(this));piePathsSel.exit().remove();var labelSel=d3.select(this.labelsGroup_).selectAll('.label').data(pieLayout(this.data_));labelSel.enter().append('text').attr('class','label').attr('dy','.35em');labelSel.text(function(d){if(d.data.label.length>40)
+return d.data.label.substr(0,40)+'...';return d.data.label;});labelSel.attr('transform',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*(midAngle(d)<Math.PI?1:-1);return'translate('+pos+')';});labelSel.style('text-anchor',function(d){return midAngle(d)<Math.PI?'start':'end';});var lineSel=d3.select(this.linesGroup_).selectAll('.line').data(pieLayout(this.data_));lineSel.enter().append('polyline').attr('class','line').attr('dy','.35em');lineSel.attr('points',function(d){var pos=lineEndArc.centroid(d);pos[0]=radius*0.95*(midAngle(d)<Math.PI?1:-1);return[lineBeginArc.centroid(d),lineEndArc.centroid(d),pos];});},updateHighlight_:function(){ChartBase.prototype.updateHighlight_.call(this);var pathsGroupSel=d3.select(this.pathsGroup_);var that=this;pathsGroupSel.selectAll('.arc').each(function(d,i){var origData=that.data_[i];var highlighted=origData.label==that.currentHighlightedLegendKey;var color=getColorOfKey(origData.label,highlighted);this.style.fill=color;});}};return{PieChart:PieChart};});'use strict';(function(){var GROUP_BY_PROCESS_NAME='process';var GROUP_BY_THREAD_NAME='thread';var WALL_TIME_GROUPING_UNIT='Wall time';var CPU_TIME_GROUPING_UNIT='CPU time';function ResultsForGroup(model,name){this.model=model;this.name=name;this.topLevelSlices=[];this.allSlices=[];}
+ResultsForGroup.prototype={get wallTime(){var wallSum=tr.b.Statistics.sum(this.topLevelSlices,function(x){return x.duration;});return wallSum;},get cpuTime(){var cpuDuration=0;for(var i=0;i<this.topLevelSlices.length;i++){var x=this.topLevelSlices[i];if(x.cpuDuration===undefined){if(x.duration===undefined)
+continue;return 0;}
+cpuDuration+=x.cpuDuration;}
+return cpuDuration;},appendGroupContents:function(group){if(group.model!=this.model)
+throw new Error('Models must be the same');group.allSlices.forEach(function(slice){this.allSlices.push(slice);},this);group.topLevelSlices.forEach(function(slice){this.topLevelSlices.push(slice);},this);},appendThreadSlices:function(rangeOfInterest,thread){var tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.slices);tmp.forEach(function(slice){this.allSlices.push(slice);},this);tmp=this.getSlicesIntersectingRange(rangeOfInterest,thread.sliceGroup.topLevelSlices);tmp.forEach(function(slice){this.topLevelSlices.push(slice);},this);},getSlicesIntersectingRange:function(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRange(slice.start,slice.end))
+slicesInFilterRange.push(slice);}
+return slicesInFilterRange;}};Polymer('tr-ui-e-s-time-summary-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;this.groupBy_=GROUP_BY_PROCESS_NAME;this.groupingUnit_=CPU_TIME_GROUPING_UNIT;this.showCpuIdleTime_=true;this.chart_=undefined;var toolbarEl=this.$.toolbar;this.groupBySelector_=tr.ui.b.createSelector(this,'groupBy','timeSummarySidePanel.groupBy',this.groupBy_,[{label:'Group by process',value:GROUP_BY_PROCESS_NAME},{label:'Group by thread',value:GROUP_BY_THREAD_NAME}]);toolbarEl.appendChild(this.groupBySelector_);this.groupingUnitSelector_=tr.ui.b.createSelector(this,'groupingUnit','timeSummarySidePanel.groupingUnit',this.groupingUnit_,[{label:'Wall time',value:WALL_TIME_GROUPING_UNIT},{label:'CPU time',value:CPU_TIME_GROUPING_UNIT}]);toolbarEl.appendChild(this.groupingUnitSelector_);this.showCpuIdleTimeCheckbox_=tr.ui.b.createCheckBox(this,'showCpuIdleTime','timeSummarySidePanel.showCpuIdleTime',this.showCpuIdleTime_,'Show CPU idle time');toolbarEl.appendChild(this.showCpuIdleTimeCheckbox_);this.updateShowCpuIdleTimeCheckboxVisibility_();},trimPieChartData:function(groups,otherGroup,getValue,opt_extraValue){groups=groups.filter(function(d){return getValue(d)!=0;});var sum=tr.b.Statistics.sum(groups,getValue);if(opt_extraValue!==undefined)
+sum+=opt_extraValue;function compareByValue(a,b){return getValue(a)-getValue(b);}
+groups.sort(compareByValue);var thresshold=0.1*sum;while(groups.length>1){var group=groups[0];if(getValue(group)>=thresshold)
+break;var v=getValue(group);if(v+getValue(otherGroup)>thresshold)
+break;groups.splice(0,1);otherGroup.appendGroupContents(group);}
+if(getValue(otherGroup)>0)
+groups.push(otherGroup);groups.sort(compareByValue);return groups;},generateResultsForGroup:function(model,name){return new ResultsForGroup(model,name);},createPieChartFromResultGroups:function(groups,title,getValue,opt_extraData){var chart=new tr.ui.b.PieChart();function pushDataForGroup(data,resultsForGroup,value){data.push({label:resultsForGroup.name,value:value,valueText:tr.b.u.TimeDuration.format(value),resultsForGroup:resultsForGroup});}
+chart.addEventListener('item-click',function(clickEvent){var resultsForGroup=clickEvent.data.resultsForGroup;if(resultsForGroup===undefined)
+return;var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(resultsForGroup.allSlices);event.selection.timeSummaryGroupName=resultsForGroup.name;chart.dispatchEvent(event);});var data=[];groups.forEach(function(resultsForGroup){var value=getValue(resultsForGroup);if(value===0)
+return;pushDataForGroup(data,resultsForGroup,value);});if(opt_extraData)
+data.push.apply(data,opt_extraData);chart.chartTitle=title;chart.data=data;return chart;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get listeningToKeys(){return false;},get groupBy(){return groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;if(this.groupBySelector_)
+this.groupBySelector_.selectedValue=groupBy;this.updateContents_();},get groupingUnit(){return groupingUnit_;},set groupingUnit(groupingUnit){this.groupingUnit_=groupingUnit;if(this.groupingUnitSelector_)
+this.groupingUnitSelector_.selectedValue=groupingUnit;this.updateShowCpuIdleTimeCheckboxVisibility_();this.updateContents_();},get showCpuIdleTime(){return this.showCpuIdleTime_;},set showCpuIdleTime(showCpuIdleTime){this.showCpuIdleTime_=showCpuIdleTime;if(this.showCpuIdleTimeCheckbox_)
+this.showCpuIdleTimeCheckbox_.checked=showCpuIdleTime;this.updateContents_();},updateShowCpuIdleTimeCheckboxVisibility_:function(){if(!this.showCpuIdleTimeCheckbox_)
+return;var visible=this.groupingUnit_==CPU_TIME_GROUPING_UNIT;if(visible)
+this.showCpuIdleTimeCheckbox_.style.display='';else
+this.showCpuIdleTimeCheckbox_.style.display='none';},getGroupNameForThread_:function(thread){if(this.groupBy_==GROUP_BY_THREAD_NAME)
+return thread.name?thread.name:thread.userFriendlyName;if(this.groupBy_==GROUP_BY_PROCESS_NAME)
+return thread.parent.userFriendlyName;},updateContents_:function(){var resultArea=this.$.result_area;this.chart_=undefined;resultArea.textContent='';if(this.model_===undefined)
+return;var rangeOfInterest;if(this.rangeOfInterest_.isEmpty)
+rangeOfInterest=this.model_.bounds;else
+rangeOfInterest=this.rangeOfInterest_;var allGroup=this.generateResultsForGroup(this.model_,'all');var resultsByGroupName={};this.model_.getAllThreads().forEach(function(thread){var groupName=this.getGroupNameForThread_(thread);if(resultsByGroupName[groupName]===undefined){resultsByGroupName[groupName]=this.generateResultsForGroup(this.model_,groupName);}
+resultsByGroupName[groupName].appendThreadSlices(rangeOfInterest,thread);allGroup.appendThreadSlices(rangeOfInterest,thread);},this);var getValueFromGroup=function(group){if(this.groupingUnit_==WALL_TIME_GROUPING_UNIT)
+return group.wallTime;return group.cpuTime;}.bind(this);var summaryText=document.createElement('div');summaryText.appendChild(tr.ui.b.createSpan({textContent:'Total '+this.groupingUnit_+': ',bold:true}));summaryText.appendChild(tr.ui.units.createTimeDurationSpan(getValueFromGroup(allGroup),{ownerDocument:this.ownerDocument}));resultArea.appendChild(summaryText);var extraValue=0;var extraData=[];if(this.showCpuIdleTime_&&this.groupingUnit_===CPU_TIME_GROUPING_UNIT&&this.model.kernel.bestGuessAtCpuCount!==undefined){var maxCpuTime=rangeOfInterest.range*this.model.kernel.bestGuessAtCpuCount;var idleTime=Math.max(0,maxCpuTime-allGroup.cpuTime);extraData.push({label:'CPU Idle',value:idleTime,valueText:tr.b.u.TimeDuration.format(idleTime)});extraValue+=idleTime;}
+var otherGroup=this.generateResultsForGroup(this.model_,'Other');var groups=this.trimPieChartData(tr.b.dictionaryValues(resultsByGroupName),otherGroup,getValueFromGroup,extraValue);if(groups.length==0){resultArea.appendChild(tr.ui.b.createSpan({textContent:'No data'}));return undefined;}
+this.chart_=this.createPieChartFromResultGroups(groups,this.groupingUnit_+' breakdown by '+this.groupBy_,getValueFromGroup,extraData);resultArea.appendChild(this.chart_);this.chart_.addEventListener('click',function(){var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.c.EventSet([]);this.dispatchEvent(event);});this.chart_.setSize(this.chart_.getMinSize());},get selection(){return selection_;},set selection(selection){this.selection_=selection;if(this.chart_===undefined)
+return;if(selection.timeSummaryGroupName)
+this.chart_.highlightedLegendKey=selection.timeSummaryGroupName;else
+this.chart_.highlightedLegendKey=undefined;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(model){return{supported:false};},get textLabel(){return'Time Summary';}});}());'use strict';tr.exportTo('tr.e.rail',function(){function RAILScore(opt_irs){this.interactionRecords_=[];if(opt_irs)
+this.interactionRecords_.push.apply(this.interactionRecords_,opt_irs);};RAILScore.prototype={get interactionRecords(){return this.interactionRecords_;},get overallScore(){if(!this.interactionRecords.length)
+return undefined;var numerator=0;var denominator=0;this.interactionRecords.forEach(function(ir){var score=ir.railScore;var scale=ir.railScoreScale;if(scale===undefined)
+scale=3;var power=ir.railScorePower;if(power===undefined)
+power=0.3;var base=ir.railScoreBase;if(base===undefined)
+base=Math.exp(1);var weight=Math.pow(base,-scale*Math.pow(score,power));numerator+=score*weight;denominator+=weight;});return numerator/denominator;},asDict:function(){return{overallScore:this.overallScore};}};RAILScore.fromModel=function(model){var rirs=model.interactionRecords.filter(function(ir){return ir instanceof tr.e.rail.RAILInteractionRecord;});if(rirs.length===0)
+return undefined;return new RAILScore(rirs);};return{RAILScore:RAILScore};});'use strict';Polymer('tr-ui-e-rail-rail-score-span',{created:function(){this.railScore_=undefined;},ready:function(){this.updateContent_();},get railScore(){return this.railScore_;},set railScore(railScore){this.railScore_=railScore;this.updateContent_();},updateContent_:function(){if(this.railScore_===undefined){this.$.content.style.display='none';return;}
+this.$.content.style.display='';var overallScore=this.railScore_.overallScore;if(overallScore===undefined)
+return;this.$.score.textContent=overallScore.toLocaleString(undefined,{minimumFractionDigits:3});}});'use strict';(function(){function setCoverageLink(link,labelString,events,eventRatio,cpuMs,cpuRatio){link.setSelectionAndContent(events);labelString+=' '+events.length+' events';labelString+=' ('+parseInt(100*eventRatio)+'%)';if(cpuRatio!==undefined)
+labelString+=', ';link.appendChild(document.createTextNode(labelString));if(cpuRatio===undefined)
+return;var cpuMsSpan=document.createElement('tr-ui-u-time-duration-span');cpuMsSpan.style.display='inline';cpuMsSpan.duration=cpuMs;cpuMsSpan.contentTextDecoration='underline';link.appendChild(cpuMsSpan);var cpuString=' ('+parseInt(100*cpuRatio)+'%)';link.appendChild(document.createTextNode(cpuString));}
+Polymer('tr-ui-e-rail-rail-score-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.model_=undefined;this.railScore_=undefined;this.selection_=new tr.model.EventSet();this.$.test.addEventListener('click',this.createTest_.bind(this));},createTest_:function(){var overlay=new tr.ui.b.Overlay();overlay.title='RAILIRFinder test';var textarea=document.createElement('textarea');textarea.textContent=tr.e.rail.createIRFinderTestCaseStringFromModel(this.model_);textarea.rows=textarea.textContent.split('\n').length;textarea.cols=80;overlay.appendChild(textarea);overlay.visible=true;textarea.select();textarea.focus();},get textLabel(){return'RAIL Info';},supportsModel:function(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}
+var railScore=tr.e.rail.RAILScore.fromModel(m);if(railScore===undefined){return{supported:false,reason:'RAIL interactions were not found on the model'};}
+return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.railScore_=tr.e.rail.RAILScore.fromModel(model);this.$.score.railScore=this.railScore_;var coverage=tr.model.getIRCoverageFromModel(model);if(coverage){var associatedEvents=tr.model.getAssociatedEvents(model.interactionRecords);setCoverageLink(this.shadowRoot.querySelector('#associated-events'),'Associated',associatedEvents,coverage.coveredEventsCountRatio,coverage.associatedEventsCpuTimeMs,coverage.coveredEventsCpuTimeRatio);setCoverageLink(this.shadowRoot.querySelector('#unassociated-events'),'Unassociated',tr.model.getUnassociatedEvents(model,associatedEvents),1.0-coverage.coveredEventsCountRatio,coverage.unassociatedEventsCpuTimeMs,1.0-coverage.coveredEventsCpuTimeRatio);}
+this.updateTable_();},get listeningToKeys(){return false;},set rangeOfInterest(rangeOfInterest){},updateTable_:function(){function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
+var columns=[{title:'Type',width:'150px',value:function(ir){var el=document.createElement('tr-ui-b-color-legend');var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([ir]),ir.railTypeName);el.setLabelAndColorId(linkEl,ir.colorId);el.compoundEventSelectionState=ir.computeCompoundEvenSelectionState(this.selection_);return el;}.bind(this),cmp:function(a,b){return a.railTypeName.localeCompare(b.railTypeName);}},{title:'Efficiency',width:'33%',value:function(ir){return toThreeDigitLocaleString(ir.normalizedEfficiency);},textAlign:'right',cmp:function(a,b){return a.normalizedEfficiency-b.normalizedEfficiency;}},{title:'Comfort',width:'33%',value:function(ir){return toThreeDigitLocaleString(ir.normalizedUserComfort);},textAlign:'right',cmp:function(a,b){return a.normalizedUserComfort-b.normalizedUserComfort;}},{title:'Score',width:'33%',value:function(ir){var span=document.createElement('span');span.style.fontWeight='bold';span.textContent=toThreeDigitLocaleString(ir.railScore);return span;},textAlign:'right',cmp:function(a,b){return a.railScore-b.railScore;}}];this.$.table.tableColumns=columns;if(this.railScore_)
+this.$.table.tableRows=this.railScore_.interactionRecords;else
+this.$.table.tableRows=[];this.$.table.rebuild();},onTableSelectionChanged_:function(){var selectedIR=this.$.table.selectedTableRow;var event=new tr.c.RequestSelectionChangeEvent();event.selection=new tr.c.Selection([selectedIR]);this.dispatchEvent(event);},set selection(selection){if(selection===undefined)
+selection=new tr.model.EventSet();if(this.selection_.equals(selection))
+return;this.selection_=selection;this.updateTable_();}});})();'use strict';Polymer('tr-ui-e-s-alerts-side-panel',{ready:function(){this.rangeOfInterest_=new tr.b.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get listeningToKeys(){return false;},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType:function(alertTypeString){var alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_:function(alerts){var alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title])
+alertsByType[alert.title]=[];alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_:function(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_:function(){return[{title:'Alert type',value:function(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value:function(row){return row.count;}}];},createAlertsTable_:function(alerts){var alertsByType=this.alertsByType_(alerts);var table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){var row=table.selectedTableRow;if(row)
+this.selectAlertsOfType(row.alertType);}.bind(this));return table;},updateContents_:function(){this.$.result_area.textContent='';if(this.model_===undefined)
+return;var panel=this.createAlertsTable_(this.model_.alerts);this.$.result_area.appendChild(panel);},supportsModel:function(m){if(m==undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
+return{supported:true};},get textLabel(){return'Alerts';}});'use strict';tr.exportTo('tr.ui.e.highlighter',function(){var Highlighter=tr.ui.tracks.Highlighter;function VSyncHighlighter(viewport){Highlighter.call(this,viewport);this.times_=[];}
+VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR=new tr.b.Color(0,0,255);VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA=0.1;VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT=0.20;VSyncHighlighter.VSYNC_DENSITY_OPAQUE=0.10;VSyncHighlighter.VSYNC_DENSITY_RANGE=VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-
+VSyncHighlighter.VSYNC_DENSITY_OPAQUE;VSyncHighlighter.generateStripes=function(times,minTime,maxTime){if(times.length===0)
+return[];var stripes=[];var lowIndex=tr.b.findLowIndexInSortedArray(times,function(time){return time;},minTime);var highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
+for(var i=lowIndex-(lowIndex%2);i<=highIndex;i+=2){var left=i<lowIndex?minTime:times[i];var right=i+1>highIndex?maxTime:times[i+1];stripes.push([left,right]);}
+return stripes;}
+VSyncHighlighter.prototype={__proto__:Highlighter.prototype,processModel:function(model){this.times_=model.device.vSyncTimestamps;},drawHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){if(!this.viewport_.highlightVSync){return;}
+var stripes=VSyncHighlighter.generateStripes(this.times_,viewLWorld,viewRWorld);if(stripes.length==0){return;}
+var stripeRange=stripes[stripes.length-1][1]-stripes[0][0];var stripeDensity=stripes.length/(dt.scaleX*stripeRange);var clampedStripeDensity=tr.b.clamp(stripeDensity,VSyncHighlighter.VSYNC_DENSITY_OPAQUE,VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT);var opacity=(VSyncHighlighter.VSYNC_DENSITY_TRANSPARENT-clampedStripeDensity)/VSyncHighlighter.VSYNC_DENSITY_RANGE;if(opacity==0){return;}
+var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var c=VSyncHighlighter.VSYNC_HIGHLIGHT_COLOR;ctx.fillStyle=c.toStringWithAlphaOverride(VSyncHighlighter.VSYNC_HIGHLIGHT_ALPHA*opacity);for(var i=0;i<stripes.length;i++){var xLeftView=dt.xWorldToView(stripes[i][0]);var xRightView=dt.xWorldToView(stripes[i][1]);ctx.fillRect(xLeftView,0,xRightView-xLeftView,height);}}};tr.ui.tracks.Highlighter.register(VSyncHighlighter);return{VSyncHighlighter:VSyncHighlighter};});
+</script>
+</head>
+  <body>
+  </body>
+</html>
diff --git a/runtime/observatory/web/timeline.html b/runtime/observatory/web/timeline.html
new file mode 100644
index 0000000..ebcc46e
--- /dev/null
+++ b/runtime/observatory/web/timeline.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html style="height: 100%; width: 100%">
+<head>
+  <meta charset="utf-8">
+  <title>Dart VM Observatory Timeline</title>
+  <script src="timeline.js"></script>
+  <link rel="import" href="third_party/trace_viewer_full.html">
+  <style>
+html, body {
+  box-sizing: border-box;
+  overflow: hidden;
+  margin: 0px;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+#trace-viewer {
+  width: 100%;
+  height: 100%;
+}
+#trace-viewer:focus {
+  outline: none;
+}
+  </style>
+</head>
+<body>
+</body>
+</html>
diff --git a/runtime/observatory/web/timeline.js b/runtime/observatory/web/timeline.js
new file mode 100644
index 0000000..27f572c
--- /dev/null
+++ b/runtime/observatory/web/timeline.js
@@ -0,0 +1,136 @@
+// 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.
+
+function onModelLoaded() {
+  viewer.globalMode = true;
+  viewer.model = model;
+}
+
+function clearTimeline() {
+  viewer.model = undefined;
+}
+
+function onImportFail() {
+  var overlay = new tr.ui.b.Overlay();
+  overlay.textContent = tr.b.normalizeException(err).message;
+  overlay.title = 'Import error';
+  overlay.visible = true;
+  console.log('import failed');
+}
+
+function updateTimeline(events) {
+  model = new tr.Model();
+  var importer = new tr.importer.Import(model);
+  var p = importer.importTracesWithProgressDialog([events]);
+  p.then(onModelLoaded, onImportFail);
+}
+
+function registerForMessages() {
+  window.addEventListener("message", onMessage, false);
+}
+
+function fetchUri(uri, onLoad, onError) {
+  var xhr = new XMLHttpRequest();
+  xhr.open('GET', uri, true);
+  xhr.responseType = 'text';
+  xhr.addEventListener("load", onLoad);
+  xhr.addEventListener("error", onError);
+  xhr.send();
+  console.log('GET ' + uri);
+}
+
+
+var traceObject;
+var pendingRequests;
+
+function gotReponse() {
+  pendingRequests--;
+  if (pendingRequests == 0) {
+    console.log("Got all timeline parts");
+    updateTimeline(traceObject);
+  }
+}
+
+function fetchTimelineOnLoad(event) {
+  var xhr = event.target;
+  var response = JSON.parse(xhr.responseText);
+  var result = response['result'];
+  var newStackFrames = result['stackFrames'];  // Map.
+  var newTraceEvents = result['traceEvents'];  // List.
+
+  // Merge in timeline events.
+  traceObject.traceEvents = traceObject.traceEvents.concat(newTraceEvents);
+  for (var key in newStackFrames) {
+    if (newStackFrames.hasOwnProperty(key)) {
+      traceObject.stackFrames[key] = newStackFrames[key];
+    }
+  }
+
+  gotReponse();
+}
+
+function fetchTimelineOnError(event) {
+  var xhr = event.target;
+  console.log(xhr.statusText);
+  gotReponse();
+}
+
+function fetchTimeline(vmAddress, isolateIds) {
+  // Reset combined timeline.
+  traceObject = {
+    'stackFrames': {},
+    'traceEvents': []
+  };
+  pendingRequests = 1 + isolateIds.length;
+
+  var parser = document.createElement('a');
+  parser.href = vmAddress;
+  var requestUri = 'http://' +
+                   parser.hostname +
+                   ':' +
+                   parser.port +
+                   '/_getVMTimeline';
+  fetchUri(requestUri, fetchTimelineOnLoad, fetchTimelineOnError);
+
+  for (var i = 0; i < isolateIds.length; i++) {
+    var isolateId = isolateIds[i];
+    var requestUri = 'http://' +
+                     parser.hostname +
+                     ':' +
+                     parser.port +
+                     '/_getCpuProfileTimeline?tags=VMUser&isolateId=' +
+                     isolateId;
+    fetchUri(requestUri, fetchTimelineOnLoad, fetchTimelineOnError);
+  }
+}
+
+function onMessage(event) {
+  var request = JSON.parse(event.data);
+  var method = request['method'];
+  var params = request['params'];
+  switch (method) {
+    case 'refresh':
+      fetchTimeline(params['vmAddress'], params['isolateIds']);
+    break;
+    case 'clear':
+      clearTimeline();
+    break;
+    default:
+      console.log('Unknown method:' + method + '.');
+  }
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+  var container = document.createElement('track-view-container');
+  container.id = 'track_view_container';
+  viewer = document.createElement('tr-ui-timeline-view');
+  viewer.track_view_container = container;
+  viewer.appendChild(container);
+  viewer.id = 'trace-viewer';
+  viewer.globalMode = true;
+  document.body.appendChild(viewer);
+  registerForMessages();
+});
+
+console.log('loaded');
diff --git a/runtime/platform/assert.cc b/runtime/platform/assert.cc
index 41f42f4..e9d1c4f 100644
--- a/runtime/platform/assert.cc
+++ b/runtime/platform/assert.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "platform/globals.h"
+#include "vm/os.h"
 
 namespace dart {
 
@@ -38,7 +39,7 @@
   // TODO(5411324): replace std::abort with OS::Abort so that we can handle
   // restoring of signal handlers before aborting.
   if (kind_ == ASSERT) {
-    abort();
+    OS::Abort();
   }
   static bool failed = false;
   if (!failed) {
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index cd7b058..8d3a155 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -94,7 +94,7 @@
 // TODO(iposva): Rename TARGET_OS_MACOS to TARGET_OS_MAC to inherit
 // the value defined in TargetConditionals.h
 #define TARGET_OS_MACOS 1
-#if TARGET_OS_IPHONE && !defined(TARGET_OS_IOS)
+#if TARGET_OS_IPHONE
 #define TARGET_OS_IOS 1
 #endif
 
@@ -233,6 +233,18 @@
 #define DART_UNUSED
 #endif
 
+// DART_NORETURN indicates to the compiler that a function doees not return.
+// It should be used on functions that unconditionally call functions like
+// exit(), which end the program. We use it to avoid compiler warnings in
+// callers of DART_NORETURN functions.
+#ifdef _MSC_VER
+#define DART_NORETURN __declspec(noreturn)
+#elif __GNUC__
+#define DART_NORETURN __attribute__((noreturn))
+#else
+#error Automatic compiler detection failed.
+#endif
+
 #if !defined(TARGET_ARCH_MIPS)
 #if !defined(TARGET_ARCH_ARM)
 #if !defined(TARGET_ARCH_X64)
@@ -279,17 +291,17 @@
 #elif defined(TARGET_ARCH_X64)
   // No simulator used.
 #elif defined(TARGET_ARCH_ARM)
-#if !defined(HOST_ARCH_ARM) || TARGET_OS_IOS
+#if !defined(HOST_ARCH_ARM)
 #define USING_SIMULATOR 1
 #endif
 
 #elif defined(TARGET_ARCH_ARM64)
-#if !defined(HOST_ARCH_ARM64) || TARGET_OS_IOS
+#if !defined(HOST_ARCH_ARM64)
 #define USING_SIMULATOR 1
 #endif
 
 #elif defined(TARGET_ARCH_MIPS)
-#if !defined(HOST_ARCH_MIPS) || TARGET_OS_IOS
+#if !defined(HOST_ARCH_MIPS)
 #define USING_SIMULATOR 1
 #endif
 
diff --git a/runtime/platform/json.cc b/runtime/platform/json.cc
deleted file mode 100644
index 6457a87..0000000
--- a/runtime/platform/json.cc
+++ /dev/null
@@ -1,636 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/json.h"
-
-#include "platform/assert.h"
-#include "platform/globals.h"
-#include "platform/utils.h"
-#include "vm/os.h"
-
-namespace dart {
-
-JSONScanner::JSONScanner(const char* json_text) {
-  SetText(json_text);
-}
-
-
-void JSONScanner::SetText(const char* json_text) {
-  current_pos_ = json_text;
-  token_start_ = json_text;
-  token_length_ = 0;
-  token_ = TokenIllegal;
-}
-
-
-void JSONScanner::Recognize(Token t) {
-  ++current_pos_;
-  token_ = t;
-}
-
-
-bool JSONScanner::IsLetter(char ch) const {
-  return (('A' <= ch) && (ch <= 'Z')) || (('a' <= ch) && (ch <= 'z'));
-}
-
-
-bool JSONScanner::IsDigit(char ch) const {
-  return ('0' <= ch) && (ch <= '9');
-}
-
-
-bool JSONScanner::IsLiteral(const char* literal) {
-  int i = 0;
-  while ((literal[i] != '\0') && (current_pos_[i] == literal[i])) {
-    i++;
-  }
-  if ((literal[i] == '\0') && !IsLetter(current_pos_[i])) {
-    current_pos_ += i;
-    return true;
-  }
-  return false;
-}
-
-
-bool JSONScanner::IsStringLiteral(const char* literal) const {
-  if (token_ != TokenString) {
-    return false;
-  }
-  int i = 0;
-  while ((i < token_length_) && (token_start_[i] == literal[i])) {
-    i++;
-  }
-  return (i == token_length_) && (literal[i] == '\0');
-}
-
-
-void JSONScanner::Skip(Token matching_token) {
-  while (!EOM() && (token_ != TokenIllegal)) {
-    Scan();
-    if (token_ == TokenLBrace) {
-      Skip(TokenRBrace);
-    } else if (token_ == TokenLBrack) {
-      Skip(TokenRBrack);
-    } else if (token_ == matching_token) {
-      return;
-    } else if ((token_ == TokenRBrace) || (token_ == TokenRBrack)) {
-      // Mismatched brace or bracket.
-      token_ = TokenIllegal;
-    }
-  }
-}
-
-
-void JSONScanner::ScanString() {
-  ASSERT(*current_pos_ == '"');
-  ++current_pos_;
-  token_start_ = current_pos_;
-  while (*current_pos_ != '"') {
-    if (*current_pos_ == '\0') {
-      token_length_ = 0;
-      token_ = TokenIllegal;
-      return;
-    } else if (*current_pos_ == '\\') {
-      ++current_pos_;
-      if (*current_pos_ == '"') {
-        // Consume escaped double quote.
-        ++current_pos_;
-      }
-    } else {
-      ++current_pos_;
-    }
-  }
-  token_ = TokenString;
-  token_length_ = current_pos_ - token_start_;
-  ++current_pos_;
-}
-
-
-void JSONScanner::ScanNumber() {
-  if (*current_pos_ == '-') {
-    ++current_pos_;
-  }
-  if (!IsDigit(*current_pos_)) {
-    token_ = TokenIllegal;
-    token_length_ = 0;
-    return;
-  }
-  while (IsDigit(*current_pos_)) {
-    ++current_pos_;
-  }
-  if ((*current_pos_ == '.') ||
-      (*current_pos_ == 'e') ||
-      (*current_pos_ == 'E')) {
-    // Floating point numbers not supported.
-    token_ = TokenIllegal;
-    token_length_ = 0;
-    return;
-  }
-  token_ = TokenInteger;
-  token_length_ = current_pos_ - token_start_;
-}
-
-
-void JSONScanner::Scan() {
-  while ((*current_pos_ == ' ') ||
-         (*current_pos_ == '\t') ||
-         (*current_pos_ == '\n')) {
-    ++current_pos_;
-  }
-  token_start_ = current_pos_;
-  if (*current_pos_ == '\0') {
-    token_length_ = 0;
-    token_ = TokenEOM;
-    return;
-  }
-  switch (*current_pos_) {
-    case '{':
-      Recognize(TokenLBrace);
-      break;
-    case '}':
-      Recognize(TokenRBrace);
-      break;
-    case '[':
-      Recognize(TokenLBrack);
-      break;
-    case ']':
-      Recognize(TokenRBrack);
-      break;
-    case ':':
-      Recognize(TokenColon);
-      break;
-    case ',':
-      Recognize(TokenComma);
-      break;
-    case '"':
-      ScanString();
-      break;
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-    case '-':
-      ScanNumber();
-      break;
-    default:
-      if (IsLiteral("true")) {
-        token_ = TokenTrue;
-        token_length_ = 4;
-      } else if (IsLiteral("false")) {
-        token_ = TokenFalse;
-        token_length_ = 5;
-      } else if (IsLiteral("null")) {
-        token_ = TokenNull;
-        token_length_ = 4;
-      } else {
-        token_length_ = 0;
-        token_ = TokenIllegal;
-      }
-  }
-}
-
-
-JSONReader::JSONReader(const char* json_object)
-: scanner_(json_object) {
-  Set(json_object);
-}
-
-
-void JSONReader::Set(const char* json_object) {
-  scanner_.SetText(json_object);
-  json_object_ = json_object;
-  error_ = false;
-}
-
-
-bool JSONReader::CheckMessage() {
-  scanner_.SetText(json_object_);
-  scanner_.Scan();
-  CheckObject();
-  return true;
-}
-
-
-void JSONReader::CheckValue() {
-  switch (scanner_.CurrentToken()) {
-    case JSONScanner::TokenLBrace:
-      CheckObject();
-      break;
-    case JSONScanner::TokenLBrack:
-      CheckArray();
-      break;
-    case JSONScanner::TokenString: {
-      // Check the encoding.
-      const char* s = ValueChars();
-      int remaining = ValueLen();
-      while (remaining > 0) {
-        if ((*s == '\n') || (*s == '\t')) {
-          OS::Print("Un-escaped character in JSON string: '%s'\n",
-                    ValueChars());
-          FATAL("illegal character in JSON string value");
-        }
-        s++;
-        remaining--;
-      }
-      scanner_.Scan();
-      break;
-    }
-    case JSONScanner::TokenInteger:
-    case JSONScanner::TokenTrue:
-    case JSONScanner::TokenFalse:
-    case JSONScanner::TokenNull:
-      scanner_.Scan();
-      break;
-    default:
-      OS::Print("Malformed JSON: expected a value but got '%s'\n",
-                scanner_.TokenChars());
-      FATAL("illegal JSON value found");
-  }
-}
-
-
-#if defined (DEBUG)
-#define CHECK_TOKEN(token)                                                     \
-  if (scanner_.CurrentToken() != token) {                                      \
-    OS::Print("Malformed JSON: expected %s but got '%s'\n",                    \
-              #token, scanner_.TokenChars());                                  \
-    intptr_t offset = scanner_.TokenChars() - this->json_object_;              \
-    OS::Print("Malformed JSON: expected %s at offset %" Pd "of buffer:\n%s\n", \
-              #token, offset, this->json_object_);                             \
-    ASSERT(scanner_.CurrentToken() == token);                                  \
-  }
-#else
-#define CHECK_TOKEN(token)
-#endif
-
-
-void JSONReader::CheckArray() {
-  CHECK_TOKEN(JSONScanner::TokenLBrack);
-  scanner_.Scan();
-  while (scanner_.CurrentToken() != JSONScanner::TokenRBrack) {
-    CheckValue();
-    if (scanner_.CurrentToken() != JSONScanner::TokenComma) {
-      break;
-    }
-    scanner_.Scan();
-  }
-  CHECK_TOKEN(JSONScanner::TokenRBrack);
-  scanner_.Scan();
-}
-
-
-void JSONReader::CheckObject() {
-  CHECK_TOKEN(JSONScanner::TokenLBrace);
-  scanner_.Scan();
-  while (scanner_.CurrentToken() == JSONScanner::TokenString) {
-    scanner_.Scan();
-    CHECK_TOKEN(JSONScanner::TokenColon);
-    scanner_.Scan();
-    CheckValue();
-    if (scanner_.CurrentToken() != JSONScanner::TokenComma) {
-      break;
-    }
-    scanner_.Scan();
-  }
-  CHECK_TOKEN(JSONScanner::TokenRBrace);
-  scanner_.Scan();
-}
-
-#undef CHECK_TOKEN
-
-
-bool JSONReader::Seek(const char* name) {
-  error_ = false;
-  scanner_.SetText(json_object_);
-  scanner_.Scan();
-  if (scanner_.CurrentToken() != JSONScanner::TokenLBrace) {
-    error_ = true;
-    return false;
-  }
-  scanner_.Scan();
-  if (scanner_.CurrentToken() == JSONScanner::TokenRBrace) {
-    return false;
-  }
-  while (scanner_.CurrentToken() == JSONScanner::TokenString) {
-    bool found = scanner_.IsStringLiteral(name);
-    scanner_.Scan();
-    if (scanner_.CurrentToken() != JSONScanner::TokenColon) {
-      error_ = true;
-      return false;
-    }
-    scanner_.Scan();
-    switch (scanner_.CurrentToken()) {
-      case JSONScanner::TokenString:
-      case JSONScanner::TokenInteger:
-      case JSONScanner::TokenLBrace:
-      case JSONScanner::TokenLBrack:
-      case JSONScanner::TokenTrue:
-      case JSONScanner::TokenFalse:
-      case JSONScanner::TokenNull:
-        // Found a legal value.
-        if (found) {
-          return true;
-        }
-        break;
-      default:
-        error_ = true;
-        return false;
-    }
-    // Skip the value.
-    if (scanner_.CurrentToken() == JSONScanner::TokenLBrace) {
-      scanner_.Skip(JSONScanner::TokenRBrace);
-      if (scanner_.CurrentToken() != JSONScanner::TokenRBrace) {
-        error_ = true;
-        return false;
-      }
-    } else if (scanner_.CurrentToken() == JSONScanner::TokenLBrack) {
-      scanner_.Skip(JSONScanner::TokenRBrack);
-      if (scanner_.CurrentToken() != JSONScanner::TokenRBrack) {
-        error_ = true;
-        return false;
-      }
-    }
-    scanner_.Scan();  // Value or closing brace or bracket.
-    if (scanner_.CurrentToken() == JSONScanner::TokenComma) {
-      scanner_.Scan();
-    } else if (scanner_.CurrentToken() == JSONScanner::TokenRBrace) {
-      return false;
-    } else {
-      error_ = true;
-      return false;
-    }
-  }
-  error_ = true;
-  return false;
-}
-
-
-const char* JSONReader::EndOfObject() {
-  bool found = Seek("***");  // Look for illegally named value.
-  ASSERT(!found);
-  if (!found && !error_) {
-    const char* s = scanner_.TokenChars();
-    ASSERT(*s == '}');
-    return s;
-  }
-  return NULL;
-}
-
-
-JSONReader::JSONType JSONReader::Type() const {
-  if (error_) {
-    return kNone;
-  }
-  switch (scanner_.CurrentToken()) {
-    case JSONScanner::TokenString:
-      return kString;
-    case JSONScanner::TokenInteger:
-      return kInteger;
-    case JSONScanner::TokenLBrace:
-      return kObject;
-    case JSONScanner::TokenLBrack:
-      return kArray;
-    case JSONScanner::TokenTrue:
-    case JSONScanner::TokenFalse:
-    case JSONScanner::TokenNull:
-      return kLiteral;
-    default:
-      return kNone;
-  }
-}
-
-
-void JSONReader::GetRawValueChars(char* buf, intptr_t buflen) const {
-  if (Type() == kNone) {
-    return;
-  }
-  intptr_t max = buflen - 1;
-  if (ValueLen() < max) {
-    max = ValueLen();
-  }
-  const char* val = ValueChars();
-  intptr_t i = 0;
-  for (; i < max; i++) {
-    buf[i] = val[i];
-  }
-  buf[i] = '\0';
-}
-
-
-void JSONReader::GetDecodedValueChars(char* buf, intptr_t buflen) const {
-  if (Type() == kNone) {
-    return;
-  }
-  const intptr_t last_idx = buflen - 1;
-  const intptr_t value_len = ValueLen();
-  const char* val = ValueChars();
-  intptr_t buf_idx = 0;
-  intptr_t val_idx = 0;
-  while ((buf_idx < last_idx) && (val_idx < value_len)) {
-    char ch = val[val_idx];
-    val_idx++;
-    buf[buf_idx] = ch;
-    if ((ch == '\\') && (val_idx < value_len)) {
-      switch (val[val_idx]) {
-        case '"':
-        case '\\':
-        case '/':
-          buf[buf_idx] = val[val_idx];
-          val_idx++;
-          break;
-        case 'b':
-          buf[buf_idx] = '\b';
-          val_idx++;
-          break;
-        case 'f':
-          buf[buf_idx] = '\f';
-          val_idx++;
-          break;
-        case 'n':
-          buf[buf_idx] = '\n';
-          val_idx++;
-          break;
-        case 'r':
-          buf[buf_idx] = '\r';
-          val_idx++;
-          break;
-        case 't':
-          buf[buf_idx] = '\t';
-          val_idx++;
-          break;
-        case 'u':
-          // \u00XX
-          // If the value is malformed or > 255, ignore and copy the
-          // encoded characters.
-          if ((val_idx < value_len - 4) &&
-              (val[val_idx + 1] == '0') && (val[val_idx + 2] == '0') &&
-              Utils::IsHexDigit(val[val_idx + 3]) &&
-              Utils::IsHexDigit(val[val_idx + 4])) {
-            buf[buf_idx] = 16 * Utils::HexDigitToInt(val[val_idx + 3]) +
-                Utils::HexDigitToInt(val[val_idx + 4]);
-            val_idx += 5;
-          }
-          break;
-        default:
-          // Nothing. Copy the character after the backslash
-          // in the next loop iteration.
-          break;
-      }
-    }
-    buf_idx++;
-  }
-  buf[buf_idx] = '\0';
-}
-
-
-TextBuffer::TextBuffer(intptr_t buf_size) {
-  ASSERT(buf_size > 0);
-  buf_ = reinterpret_cast<char*>(malloc(buf_size));
-  buf_size_ = buf_size;
-  Clear();
-}
-
-
-TextBuffer::~TextBuffer() {
-  free(buf_);
-  buf_ = NULL;
-}
-
-
-void TextBuffer::Clear() {
-  msg_len_ = 0;
-  buf_[0] = '\0';
-}
-
-
-const char* TextBuffer::Steal() {
-  const char* r = buf_;
-  buf_ = NULL;
-  buf_size_ = 0;
-  msg_len_ = 0;
-  return r;
-}
-
-
-void TextBuffer::AddChar(char ch) {
-  EnsureCapacity(sizeof(ch));
-  buf_[msg_len_] = ch;
-  msg_len_++;
-  buf_[msg_len_] = '\0';
-}
-
-
-intptr_t TextBuffer::Printf(const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  intptr_t remaining = buf_size_ - msg_len_;
-  ASSERT(remaining >= 0);
-  intptr_t len = OS::VSNPrint(buf_ + msg_len_, remaining, format, args);
-  va_end(args);
-  if (len >= remaining) {
-    EnsureCapacity(len);
-    remaining = buf_size_ - msg_len_;
-    ASSERT(remaining > len);
-    va_list args2;
-    va_start(args2, format);
-    intptr_t len2 = OS::VSNPrint(buf_ + msg_len_, remaining, format, args2);
-    va_end(args2);
-    ASSERT(len == len2);
-  }
-  msg_len_ += len;
-  buf_[msg_len_] = '\0';
-  return len;
-}
-
-
-// Write a UTF-16 code unit so it can be read by a JSON parser in a string
-// literal. Use escape sequences for characters other than printable ASCII.
-void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
-  switch (codeunit) {
-    case '"':
-      Printf("%s", "\\\"");
-      break;
-    case '\\':
-      Printf("%s", "\\\\");
-      break;
-    case '/':
-      Printf("%s", "\\/");
-      break;
-    case '\b':
-      Printf("%s", "\\b");
-      break;
-    case '\f':
-      Printf("%s", "\\f");
-      break;
-    case '\n':
-      Printf("%s", "\\n");
-      break;
-    case '\r':
-      Printf("%s", "\\r");
-      break;
-    case '\t':
-      Printf("%s", "\\t");
-      break;
-    default:
-      if (codeunit < 0x20) {
-        // Encode character as \u00HH.
-        uint32_t digit2 = (codeunit >> 4) & 0xf;
-        uint32_t digit3 = (codeunit & 0xf);
-        Printf("\\u00%c%c",
-               digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
-               digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3);
-      } else if (codeunit > 127) {
-        // Encode character as \uHHHH.
-        uint32_t digit0 = (codeunit >> 12) & 0xf;
-        uint32_t digit1 = (codeunit >> 8) & 0xf;
-        uint32_t digit2 = (codeunit >> 4) & 0xf;
-        uint32_t digit3 = (codeunit & 0xf);
-        Printf("\\u%c%c%c%c",
-               digit0 > 9 ? 'A' + (digit0 - 10) : '0' + digit0,
-               digit1 > 9 ? 'A' + (digit1 - 10) : '0' + digit1,
-               digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
-               digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3);
-      } else {
-        AddChar(codeunit);
-      }
-  }
-}
-
-
-void TextBuffer::AddString(const char* s) {
-  Printf("%s", s);
-}
-
-
-void TextBuffer::AddEscapedString(const char* s) {
-  intptr_t len = strlen(s);
-  for (int i = 0; i < len; i++) {
-    EscapeAndAddCodeUnit(s[i]);
-  }
-}
-
-
-void TextBuffer::EnsureCapacity(intptr_t len) {
-  intptr_t remaining = buf_size_ - msg_len_;
-  if (remaining <= len) {
-    const int kBufferSpareCapacity = 64;  // Somewhat arbitrary.
-    // TODO(turnidge): do we need to guard against overflow or other
-    // security issues here? Text buffers are used by the debugger
-    // to send user-controlled data (e.g. values of string variables) to
-    // the debugger front-end.
-    intptr_t new_size = buf_size_ + len + kBufferSpareCapacity;
-    char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size));
-    ASSERT(new_buf != NULL);
-    buf_ = new_buf;
-    buf_size_ = new_size;
-  }
-}
-
-}  // namespace dart
diff --git a/runtime/platform/json.h b/runtime/platform/json.h
deleted file mode 100644
index 35e975f0..0000000
--- a/runtime/platform/json.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef PLATFORM_JSON_H_
-#define PLATFORM_JSON_H_
-
-#include "vm/allocation.h"
-#include "vm/globals.h"
-
-namespace dart {
-
-
-// A low level interface to tokenize JSON strings.
-class JSONScanner : ValueObject {
- public:
-  enum Token {
-    TokenIllegal = 0,
-    TokenLBrace,
-    TokenRBrace,
-    TokenLBrack,
-    TokenRBrack,
-    TokenColon,
-    TokenComma,
-    TokenString,
-    TokenInteger,
-    TokenTrue,
-    TokenFalse,
-    TokenNull,
-    TokenEOM
-  };
-  explicit JSONScanner(const char* json_text);
-
-  void SetText(const char* json_text);
-  void Scan();
-  Token CurrentToken() const { return token_; }
-  bool EOM() const { return token_ == TokenEOM; }
-  const char* TokenChars() const { return token_start_; }
-  int TokenLen() const { return token_length_; }
-  bool IsStringLiteral(const char* literal) const;
-  void Skip(Token matching_token);
-
- private:
-  bool IsLetter(char ch) const;
-  bool IsDigit(char ch) const;
-  bool IsLiteral(const char* literal);
-  void ScanNumber();
-  void ScanString();
-  void Recognize(Token t);
-
-  const char* current_pos_;
-  const char* token_start_;
-  int token_length_;
-  Token token_;
-};
-
-
-// JSONReader is a higher level interface that allows for lookup of
-// name-value pairs in JSON objects.
-class JSONReader : ValueObject {
- public:
-  enum JSONType {
-    kString,
-    kInteger,
-    kObject,
-    kArray,
-    kLiteral,
-    kNone
-  };
-
-  explicit JSONReader(const char* json_object);
-  void Set(const char* json_object);
-
-  // Returns true if a pair with the given name was found.
-  bool Seek(const char* name);
-
-  // Returns true if a syntax error was found.
-  bool Error() const { return error_; }
-
-  // Returns a pointer to the matching closing brace if the text starts
-  // with a valid JSON object. Returns NULL otherwise.
-  const char* EndOfObject();
-
-  JSONType Type() const;
-  const char* ValueChars() const {
-    return (Type() != kNone) ? scanner_.TokenChars() : NULL;
-  }
-  int ValueLen() const {
-    return (Type() != kNone) ? scanner_.TokenLen() : 0;
-  }
-  void GetRawValueChars(char* buf, intptr_t buflen) const;
-  void GetDecodedValueChars(char* buf, intptr_t buflen) const;
-  bool IsStringLiteral(const char* literal) const {
-    return scanner_.IsStringLiteral(literal);
-  }
-  bool IsTrue() const {
-    return scanner_.CurrentToken() == JSONScanner::TokenTrue;
-  }
-  bool IsFalse() const {
-    return scanner_.CurrentToken() == JSONScanner::TokenFalse;
-  }
-  bool IsNull() const {
-    return scanner_.CurrentToken() == JSONScanner::TokenNull;
-  }
-
-  // Debugging method to check for validity of a JSON message.
-  bool CheckMessage();
-
- private:
-  void CheckObject();
-  void CheckArray();
-  void CheckValue();
-
-  JSONScanner scanner_;
-  const char* json_object_;
-  bool error_;
-};
-
-
-// TextBuffer maintains a dynamic character buffer with a printf-style way to
-// append text.
-class TextBuffer : ValueObject {
- public:
-  explicit TextBuffer(intptr_t buf_size);
-  ~TextBuffer();
-
-  intptr_t Printf(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
-  void AddChar(char ch);
-  void EscapeAndAddCodeUnit(uint32_t cu);
-  void AddString(const char* s);
-  void AddEscapedString(const char* s);
-
-  void Clear();
-
-  char* buf() { return buf_; }
-  intptr_t length() { return msg_len_; }
-
-  // Steal ownership of the buffer pointer.
-  // NOTE: TextBuffer is empty afterwards.
-  const char* Steal();
-
- private:
-  void EnsureCapacity(intptr_t len);
-  char* buf_;
-  intptr_t buf_size_;
-  intptr_t msg_len_;
-};
-
-}  // namespace dart
-
-#endif  // PLATFORM_JSON_H_
diff --git a/runtime/platform/platform_headers.gypi b/runtime/platform/platform_headers.gypi
index bf99985..6619720 100644
--- a/runtime/platform/platform_headers.gypi
+++ b/runtime/platform/platform_headers.gypi
@@ -13,8 +13,8 @@
     'globals.h',
     'hashmap.h',
     'inttypes_support_win.h',
-    'json.h',
     'memory_sanitizer.h',
+    'text_buffer.h',
     'utils.h',
   ],
 }
diff --git a/runtime/platform/platform_sources.gypi b/runtime/platform/platform_sources.gypi
index 5885f73..7327ad3 100644
--- a/runtime/platform/platform_sources.gypi
+++ b/runtime/platform/platform_sources.gypi
@@ -7,9 +7,9 @@
   'sources': [
     'assert.cc',
     'hashmap.cc',
-    'json.cc',
     'floating_point_win.cc',
     'signal_blocker.h',
+    'text_buffer.cc',
     'utils.cc',
   ],
 }
diff --git a/runtime/platform/text_buffer.cc b/runtime/platform/text_buffer.cc
new file mode 100644
index 0000000..b9c6ac7
--- /dev/null
+++ b/runtime/platform/text_buffer.cc
@@ -0,0 +1,157 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "platform/text_buffer.h"
+
+#include "platform/assert.h"
+#include "platform/globals.h"
+#include "platform/utils.h"
+#include "vm/os.h"
+
+namespace dart {
+
+TextBuffer::TextBuffer(intptr_t buf_size) {
+  ASSERT(buf_size > 0);
+  buf_ = reinterpret_cast<char*>(malloc(buf_size));
+  buf_size_ = buf_size;
+  Clear();
+}
+
+
+TextBuffer::~TextBuffer() {
+  free(buf_);
+  buf_ = NULL;
+}
+
+
+void TextBuffer::Clear() {
+  msg_len_ = 0;
+  buf_[0] = '\0';
+}
+
+
+const char* TextBuffer::Steal() {
+  const char* r = buf_;
+  buf_ = NULL;
+  buf_size_ = 0;
+  msg_len_ = 0;
+  return r;
+}
+
+
+void TextBuffer::AddChar(char ch) {
+  EnsureCapacity(sizeof(ch));
+  buf_[msg_len_] = ch;
+  msg_len_++;
+  buf_[msg_len_] = '\0';
+}
+
+
+intptr_t TextBuffer::Printf(const char* format, ...) {
+  va_list args;
+  va_start(args, format);
+  intptr_t remaining = buf_size_ - msg_len_;
+  ASSERT(remaining >= 0);
+  intptr_t len = OS::VSNPrint(buf_ + msg_len_, remaining, format, args);
+  va_end(args);
+  if (len >= remaining) {
+    EnsureCapacity(len);
+    remaining = buf_size_ - msg_len_;
+    ASSERT(remaining > len);
+    va_list args2;
+    va_start(args2, format);
+    intptr_t len2 = OS::VSNPrint(buf_ + msg_len_, remaining, format, args2);
+    va_end(args2);
+    ASSERT(len == len2);
+  }
+  msg_len_ += len;
+  buf_[msg_len_] = '\0';
+  return len;
+}
+
+
+// Write a UTF-16 code unit so it can be read by a JSON parser in a string
+// literal. Use escape sequences for characters other than printable ASCII.
+void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
+  switch (codeunit) {
+    case '"':
+      Printf("%s", "\\\"");
+      break;
+    case '\\':
+      Printf("%s", "\\\\");
+      break;
+    case '/':
+      Printf("%s", "\\/");
+      break;
+    case '\b':
+      Printf("%s", "\\b");
+      break;
+    case '\f':
+      Printf("%s", "\\f");
+      break;
+    case '\n':
+      Printf("%s", "\\n");
+      break;
+    case '\r':
+      Printf("%s", "\\r");
+      break;
+    case '\t':
+      Printf("%s", "\\t");
+      break;
+    default:
+      if (codeunit < 0x20) {
+        // Encode character as \u00HH.
+        uint32_t digit2 = (codeunit >> 4) & 0xf;
+        uint32_t digit3 = (codeunit & 0xf);
+        Printf("\\u00%c%c",
+               digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
+               digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3);
+      } else if (codeunit > 127) {
+        // Encode character as \uHHHH.
+        uint32_t digit0 = (codeunit >> 12) & 0xf;
+        uint32_t digit1 = (codeunit >> 8) & 0xf;
+        uint32_t digit2 = (codeunit >> 4) & 0xf;
+        uint32_t digit3 = (codeunit & 0xf);
+        Printf("\\u%c%c%c%c",
+               digit0 > 9 ? 'A' + (digit0 - 10) : '0' + digit0,
+               digit1 > 9 ? 'A' + (digit1 - 10) : '0' + digit1,
+               digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
+               digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3);
+      } else {
+        AddChar(codeunit);
+      }
+  }
+}
+
+
+void TextBuffer::AddString(const char* s) {
+  Printf("%s", s);
+}
+
+
+void TextBuffer::AddEscapedString(const char* s) {
+  intptr_t len = strlen(s);
+  for (int i = 0; i < len; i++) {
+    EscapeAndAddCodeUnit(s[i]);
+  }
+}
+
+
+void TextBuffer::EnsureCapacity(intptr_t len) {
+  intptr_t remaining = buf_size_ - msg_len_;
+  if (remaining <= len) {
+    const int kBufferSpareCapacity = 64;  // Somewhat arbitrary.
+    // TODO(turnidge): do we need to guard against overflow or other
+    // security issues here? Text buffers are used by the debugger
+    // to send user-controlled data (e.g. values of string variables) to
+    // the debugger front-end.
+    intptr_t new_size = buf_size_ + len + kBufferSpareCapacity;
+    char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size));
+    ASSERT(new_buf != NULL);
+    buf_ = new_buf;
+    buf_size_ = new_size;
+  }
+}
+
+}  // namespace dart
diff --git a/runtime/platform/text_buffer.h b/runtime/platform/text_buffer.h
new file mode 100644
index 0000000..f8f0c2f
--- /dev/null
+++ b/runtime/platform/text_buffer.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef PLATFORM_TEXT_BUFFER_H_
+#define PLATFORM_TEXT_BUFFER_H_
+
+#include "vm/allocation.h"
+#include "vm/globals.h"
+
+namespace dart {
+
+
+// TextBuffer maintains a dynamic character buffer with a printf-style way to
+// append text.
+class TextBuffer : ValueObject {
+ public:
+  explicit TextBuffer(intptr_t buf_size);
+  ~TextBuffer();
+
+  intptr_t Printf(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
+  void AddChar(char ch);
+  void EscapeAndAddCodeUnit(uint32_t cu);
+  void AddString(const char* s);
+  void AddEscapedString(const char* s);
+
+  void Clear();
+
+  char* buf() { return buf_; }
+  intptr_t length() { return msg_len_; }
+
+  // Steal ownership of the buffer pointer.
+  // NOTE: TextBuffer is empty afterwards.
+  const char* Steal();
+
+ private:
+  void EnsureCapacity(intptr_t len);
+  char* buf_;
+  intptr_t buf_size_;
+  intptr_t msg_len_;
+};
+
+}  // namespace dart
+
+#endif  // PLATFORM_TEXT_BUFFER_H_
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index 54ebf4d..9e4a384 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -214,6 +214,8 @@
     return true;
 #endif
   }
+
+  static char* StrError(int err, char* buffer, size_t bufsize);
 };
 
 }  // namespace dart
diff --git a/runtime/platform/utils_android.h b/runtime/platform/utils_android.h
index 904f6f4..7709442 100644
--- a/runtime/platform/utils_android.h
+++ b/runtime/platform/utils_android.h
@@ -60,6 +60,13 @@
   return htole64(value);
 }
 
+inline char* Utils::StrError(int err, char* buffer, size_t bufsize) {
+  if (strerror_r(err, buffer, bufsize) != 0) {
+    snprintf(buffer, bufsize, "%s", "strerror_r failed");
+  }
+  return buffer;
+}
+
 }  // namespace dart
 
 #endif  // PLATFORM_UTILS_ANDROID_H_
diff --git a/runtime/platform/utils_linux.h b/runtime/platform/utils_linux.h
index f2af4d1..bb9594f 100644
--- a/runtime/platform/utils_linux.h
+++ b/runtime/platform/utils_linux.h
@@ -60,6 +60,21 @@
   return htole64(value);
 }
 
+
+inline char* Utils::StrError(int err, char* buffer, size_t bufsize) {
+#if !defined(__GLIBC__) ||                                              \
+((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE)
+  // Use the XSI version.
+  if (strerror_r(err, buffer, bufsize) != 0) {
+    snprintf(buffer, bufsize, "%s", "strerror_r failed");
+  }
+  return buffer;
+#else
+  // Use the GNU specific version.
+  return strerror_r(err, buffer, bufsize);
+#endif
+}
+
 }  // namespace dart
 
 #endif  // PLATFORM_UTILS_LINUX_H_
diff --git a/runtime/platform/utils_macos.h b/runtime/platform/utils_macos.h
index 3fa29849..7c2a966 100644
--- a/runtime/platform/utils_macos.h
+++ b/runtime/platform/utils_macos.h
@@ -60,6 +60,13 @@
   return OSSwapHostToLittleInt64(value);
 }
 
+inline char* Utils::StrError(int err, char* buffer, size_t bufsize) {
+  if (strerror_r(err, buffer, bufsize) != 0) {
+    snprintf(buffer, bufsize, "%s", "strerror_r failed");
+  }
+  return buffer;
+}
+
 }  // namespace dart
 
 #endif  // PLATFORM_UTILS_MACOS_H_
diff --git a/runtime/tests/vm/dart/data_uri_failures_test.dart b/runtime/tests/vm/dart/data_uri_failures_test.dart
deleted file mode 100644
index 2df3195..0000000
--- a/runtime/tests/vm/dart/data_uri_failures_test.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'data:text/plain;charset=utf-8,foo%28%29%20%3D%3E%2042%3B';  /// wrongmime: ok
-import 'data:;charset=utf-8,foo%28%29%20%3D%3E%2042%3B';  /// nomime: ok
-import 'data:application/dart;charset=utf-16,foo%28%29%20%3D%3E%2042%3B';  /// utf16: runtime error
-import 'data:application/dart,foo%28%29%20%3D%3E%2042%3B';  /// nocharset: ok
-import 'data:application/dart;charset=utf-8,foo?%9g';  /// badencodeddate: runtime error
-import 'data:application/dart;charset=utf-8;base64,Zm9vKCkgPT4gNDI7';  /// base64: ok
-
-main() {
-}
\ No newline at end of file
diff --git a/runtime/tests/vm/dart/data_uri_import_test.dart b/runtime/tests/vm/dart/data_uri_import_test.dart
index 2430b95..8ce4e1a 100644
--- a/runtime/tests/vm/dart/data_uri_import_test.dart
+++ b/runtime/tests/vm/dart/data_uri_import_test.dart
@@ -3,7 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // foo() => 42;
-import 'data:application/dart;charset=utf-8,foo%28%29%20%3D%3E%2042%3B';
+import 'data:application/dart;charset=utf-8,foo%28%29%20%3D%3E%2042%3B';  /// percentencoded: ok
+import 'data:text/plain;charset=utf-8,foo%28%29%20%3D%3E%2042%3B';  /// wrongmime: ok
+import 'data:;charset=utf-8,foo%28%29%20%3D%3E%2042%3B';  /// nomime: ok
+import 'data:application/dart;charset=utf-16,foo%28%29%20%3D%3E%2042%3B';  /// utf16: runtime error
+import 'data:application/dart,foo%28%29%20%3D%3E%2042%3B';  /// nocharset: ok
+import 'data:application/dart;charset=utf-8,foo?%9g';  /// badencodeddate: runtime error
+import 'data:application/dart;charset=utf-8;base64,Zm9vKCkgPT4gNDI7';  /// base64: ok
 
 import "package:expect/expect.dart";
 
diff --git a/runtime/tests/vm/dart/spawn_shutdown_test.dart b/runtime/tests/vm/dart/spawn_shutdown_test.dart
index 794e737..13fb2b8e2 100644
--- a/runtime/tests/vm/dart/spawn_shutdown_test.dart
+++ b/runtime/tests/vm/dart/spawn_shutdown_test.dart
@@ -3,30 +3,56 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:io';
 import 'dart:isolate';
 
-// Spawn an isolate |foo| that will continue trying to spawn isolates even after
-// the timer in |main| completes. This test ensures that the VM can shutdown
-// correctly even while an isolate is attempting to spawn more isolates.
+// This test attempts to check that the vm can shutdown cleanly when
+// isolates are starting and stopping.
+//
+// We spawn a set of workers.  Each worker will kill its parent
+// worker (if any) and then spawn a child worker.  We start these
+// workers in a staggered fashion in an attempt to see a variety of
+// isolate states at the time that this program terminates.
 
-isolate1(sendPort) {
-  var receivePort = new ReceivePort();
-  sendPort.send(receivePort.sendPort);
-  receivePort.listen((msg) {});
-}
-
-void foo(_) {
-  while (true) {
-    var receivePort = new ReceivePort();
-    Isolate.spawn(isolate1, receivePort.sendPort);
-    receivePort.listen((sendPort) {
-      Isolate.spawn(isolate1,sendPort);
-      receivePort.close();
-    });
+trySpawn(Function f, Object o) async {
+  try {
+    await Isolate.spawn(f, o);
+  } catch (e) {
+    // Isolate spawning may fail if the program is ending.
+    assert(e is IsolateSpawnException);
   }
 }
 
+void worker(SendPort parentPort) {
+  var port = new RawReceivePort();
+
+  // This worker will exit when it receives any message.
+  port.handler = (_) { port.close(); };
+
+  // Send a message to terminate our parent isolate.
+  if (parentPort != null) {
+    parentPort.send(null);
+  }
+
+  // Spawn a child worker.
+  trySpawn(worker, port.sendPort);
+}
+
 void main() {
-  Isolate.spawn(foo, null);
-  new Timer(const Duration(seconds: 10), () {});
+  const numWorkers = 50;
+  const delay = const Duration(milliseconds:(1000 ~/ numWorkers));
+  const exitDelay = const Duration(seconds: 2);
+
+  // Take about a second to spin up our workers in a staggered
+  // fashion. We want to maximize the chance that they will be in a
+  // variety of states when the vm shuts down.
+  print('Starting ${numWorkers} workers...');
+  for (int i = 0; i < numWorkers; i++) {
+    trySpawn(worker, null);
+    sleep(delay);
+  }
+
+  // Let them spin for a bit before terminating the program.
+  print('Waiting for ${exitDelay} before exit...');
+  sleep(exitDelay);
 }
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 3c0182f..f5163a0 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -3,7 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 # These tests are expected to crash on all platforms.
-cc/ArrayNew_Overflow_Crash: Crash
+cc/ArrayNew_Overflow_Crash: Crash, Timeout
 cc/AllocGeneric_Overflow: Crash, Timeout
 cc/CodeImmutability: Crash
 
@@ -12,42 +12,26 @@
 # Flaky on buildbot. Issue 5133 and 10409.
 cc/Sleep: Pass, Fail
 
+dart/data_uri_import_test/none: SkipByDesign
+
 [ $mode == debug ]
 # This is a benchmark that is not informative in debug mode.
 cc/CorelibIsolateStartup: Skip
 # Negative tests of VerifiedMemory should crash iff in DEBUG mode.
 # TODO(koda): Improve support for negative tests.
-cc/VerifyImplicit_Crash: Crash
-cc/VerifyExplicit_Crash: Crash
+cc/VerifyImplicit_Crash: Crash, Timeout  # Timeout: Issue #24596
+cc/VerifyExplicit_Crash: Crash, Timeout  # Timeout: Issue #24596
 
 # The following section refers to the dart vm tests which live under
 # runtime/tests/vm/dart.
 [ $system == windows ]
 cc/Dart2JSCompileAll: Skip
 cc/ExternalizeConstantStrings: Skip
-cc/ThreadInterrupterHigh: Skip
-cc/ThreadInterrupterMedium: Skip
-cc/ThreadInterrupterLow: Skip
 cc/Service_Profile: Skip
 cc/Dart2JSCompilerStats: Skip
 cc/CorelibCompilerStats: Skip
-cc/ThreadIterator_AddFindRemove: Skip  # Issue 23474
-
-
-[ $system == linux ]
-cc/ThreadInterrupterHigh: Skip
-cc/ThreadInterrupterMedium: Skip
-cc/ThreadInterrupterLow: Skip
-
-[ $system == macos ]
-cc/ThreadInterrupterHigh: Skip
-cc/ThreadInterrupterMedium: Skip
-cc/ThreadInterrupterLow: Skip
 
 [ $arch == simarm || $arch == simarmv5te || $arch == simarm64 || $arch == simmips ]
-cc/ThreadInterrupterHigh: Skip
-cc/ThreadInterrupterMedium: Skip
-cc/ThreadInterrupterLow: Skip
 cc/Service_Profile: Skip
 
 [ $arch == arm ]
@@ -69,16 +53,10 @@
 # minifying they can be renamed, which is issue 7953.
 dart/inline_stack_frame_test: RuntimeError, Pass # Issue 7953
 
-[ $compiler == dart2js || $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2js || $compiler == dart2analyzer ]
 # Data uri's not supported by dart2js or the analyzer.
 dart/data_uri*test: Skip
 
-[ $runtime == vm ]
-dart/data_uri_failures_test/wrongmime: RuntimeError, OK # VM is more restrictive than the browser
-dart/data_uri_failures_test/nomime: RuntimeError, OK
-dart/data_uri_failures_test/nocharset: RuntimeError, OK
-dart/data_uri_failures_test/base64: RuntimeError, OK
-
 [ $arch == mips ]
 cc/StaticNonNullSumCallCodegen: Crash, Pass # Issue 17440
 cc/ArrayLengthMaxElements: Crash  # Issue 23275
@@ -87,7 +65,7 @@
 [ $arch == mips && $mode == debug ]
 cc/FindCodeObject: Skip # Takes more than 8 minutes. Issue 17440
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 dart/optimized_stacktrace_test: StaticWarning
 
 [ $runtime != vm ]
@@ -95,5 +73,16 @@
 dart/spawn_infinite_loop_test: Skip  # VM shutdown test
 dart/spawn_shutdown_test: Skip  # VM Shutdown test
 
-[ $runtime == vm && $mode == debug && $builder_tag == asan ]
+[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $builder_tag == asan ]
 cc/Dart2JSCompileAll: Skip  # Timeout.
+
+[ $noopt ]
+dart/byte_array_test: Crash # Incompatible flag --disable_alloc_stubs_after_gc
+
+[ $noopt || $compiler == precompiler ]
+dart/redirection_type_shuffling_test: CompileTimeError # Imports dart:mirrors
+dart/optimized_stacktrace_test: RuntimeError # Expects line and column numbers
+
+[ $runtime == dart_precompiled ]
+dart/inline_stack_frame_test: Fail  # Issue 24783 - inlined frames missing
+dart/data_uri_spawn_test: RuntimeError # Isolate.spawnUri
diff --git a/runtime/tools/bmu_benchmark_gallery.sh b/runtime/tools/bmu_benchmark_gallery.sh
index 18feef0..3c1d76b 100644
--- a/runtime/tools/bmu_benchmark_gallery.sh
+++ b/runtime/tools/bmu_benchmark_gallery.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # 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
diff --git a/runtime/tools/create_archive.py b/runtime/tools/create_archive.py
new file mode 100644
index 0000000..7b0e99d
--- /dev/null
+++ b/runtime/tools/create_archive.py
@@ -0,0 +1,160 @@
+# 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 python script creates a tar archive and a C++ source file which contains
+# the tar archive as an array of bytes.
+
+import os
+import sys
+from os.path import join, splitext
+import time
+from optparse import OptionParser
+from datetime import date
+import tarfile
+import tempfile
+
+def makeArchive(tar_path, client_root, compress, files):
+  mode_string = 'w'
+  if compress:
+    mode_string = 'w:gz'
+  tar = tarfile.open(tar_path, mode=mode_string)
+  for input_file_name in files:
+    # Chop off client_root.
+    archive_file_name = input_file_name[ len(client_root) : ]
+    # Replace back slash with forward slash. So we do not have Windows paths.
+    archive_file_name = archive_file_name.replace("\\", "/")
+    # Open input file and add it to the archive.
+    with open(input_file_name, 'rb') as input_file:
+      tarInfo = tarfile.TarInfo(name=archive_file_name)
+      input_file.seek(0,2)
+      tarInfo.size = input_file.tell()
+      input_file.seek(0)
+      tar.addfile(tarInfo, fileobj=input_file)
+  tar.close()
+
+def writeCCFile(output_file,
+                outer_namespace,
+                inner_namespace,
+                name,
+                tar_archive,
+                ):
+  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
+// BSD-style license that can be found in the LICENSE file.
+
+''' % date.today().year
+  cc_text += '''
+
+#if defined(_WIN32)
+typedef unsigned __int8 uint8_t;
+#else
+#include <inttypes.h>
+#include <stdint.h>
+#endif
+#include <stddef.h>
+
+'''
+  cc_text += 'namespace %s {\n' % outer_namespace
+  if inner_namespace != None:
+    cc_text += 'namespace %s {\n' % inner_namespace
+  cc_text += '\n\n'
+  # Write the archive.
+  cc_text += 'static const uint8_t %s_[] = {\n   ' % name
+  lineCounter = 0
+  for byte in tar_archive:
+    cc_text += r" %d," % ord(byte)
+    lineCounter += 1
+    if lineCounter == 10:
+      cc_text += '\n   '
+      lineCounter = 0
+  if lineCounter != 0:
+    cc_text += '\n   '
+  cc_text += '\n};\n'
+  cc_text += '\nunsigned int %s_len = %d;\n' % (name, len(tar_archive))
+  cc_text += '\nconst uint8_t* %s = %s_;\n\n' % (name, name)
+  if inner_namespace != None:
+    cc_text += '}  // namespace %s\n' % inner_namespace
+  cc_text += '} // namespace %s\n' % outer_namespace
+
+  open(output_file, 'w').write(cc_text)
+
+def main(args):
+  try:
+    # Parse input.
+    parser = OptionParser()
+    parser.add_option("--output",
+                      action="store", type="string",
+                      help="output file name")
+    parser.add_option("--tar_output",
+                      action="store", type="string",
+                      help="tar output file name")
+    parser.add_option("--outer_namespace",
+                      action="store", type="string",
+                      help="outer C++ namespace",
+                      default="dart")
+    parser.add_option("--inner_namespace",
+                      action="store", type="string",
+                      help="inner C++ namespace",
+                      default="bin")
+    parser.add_option("--name",
+                      action="store", type="string",
+                      help="name of tar archive symbol")
+    parser.add_option("--compress", action="store_true", default=False)
+    parser.add_option("--client_root",
+                      action="store", type="string",
+                      help="root directory client resources")
+
+    (options, args) = parser.parse_args()
+    if not options.output:
+      sys.stderr.write('--output not specified\n')
+      return -1
+    if not options.tar_output:
+      sys.stderr.write('--tar_output not specified\n')
+      return -1
+    if not options.name:
+      sys.stderr.write('--name not specified\n')
+      return -1
+    if not options.client_root:
+      sys.stderr.write('--client_root not specified')
+      return -1
+
+    files = [ ]
+
+    for dirname, dirnames, filenames in os.walk(options.client_root):
+      # strip out all dot files.
+      filenames = [f for f in filenames if not f[0] == '.']
+      dirnames[:] = [d for d in dirnames if not d[0] == '.']
+      for f in filenames:
+        src_path = os.path.join(dirname, f)
+        if (os.path.isdir(src_path)):
+            continue
+        files.append(src_path)
+
+    # Write out archive.
+    makeArchive(options.tar_output,
+                options.client_root,
+                options.compress,
+                files)
+
+    # Read it back in.
+    with open(options.tar_output, 'rb') as tar_file:
+      tar_archive = tar_file.read()
+
+    # Write CC file.
+    writeCCFile(options.output,
+                options.outer_namespace,
+                options.inner_namespace,
+                options.name,
+                tar_archive)
+    return 0
+
+  except Exception, inst:
+    sys.stderr.write('create_resources.py exception\n')
+    sys.stderr.write(str(inst))
+    sys.stderr.write('\n')
+    return -1
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/runtime/tools/create_snapshot_bin.py b/runtime/tools/create_snapshot_bin.py
index b91de38..344c4e3 100755
--- a/runtime/tools/create_snapshot_bin.py
+++ b/runtime/tools/create_snapshot_bin.py
@@ -32,6 +32,13 @@
       action="store", type="string",
       help="output file name into which isolate snapshot in binary form " +
            "is generated")
+  result.add_option("--instructions_bin",
+      action="store", type="string",
+      help="output file name into which instructions snapshot in assembly " +
+           "form is generated")
+  result.add_option("--embedder_entry_points_manifest",
+      action="store", type="string",
+      help="input manifest with the vm entry points in a precompiled snapshot")
   result.add_option("--script",
       action="store", type="string",
       help="Dart script for which snapshot is to be generated")
@@ -108,6 +115,16 @@
                                options.vm_output_bin ]))
   script_args.append(''.join([ "--isolate_snapshot=", options.output_bin ]))
 
+  # Setup the instuctions snapshot output filename
+  if options.instructions_bin:
+    script_args.append(''.join([ "--instructions_snapshot=",
+                                 options.instructions_bin ]))
+
+  # Specify the embedder entry points snapshot
+  if options.embedder_entry_points_manifest:
+    script_args.append(''.join([ "--embedder_entry_points_manifest=",
+                                 options.embedder_entry_points_manifest ]))
+
   # Next setup all url mapping options specified.
   for url_arg in options.url_mapping:
     url_mapping_argument = ''.join(["--url_mapping=", url_arg ])
diff --git a/runtime/tools/gen_library_src_paths.py b/runtime/tools/gen_library_src_paths.py
index 2751215..8a55118 100644
--- a/runtime/tools/gen_library_src_paths.py
+++ b/runtime/tools/gen_library_src_paths.py
@@ -8,10 +8,30 @@
 
 import os
 import sys
+import utils
 
 from os.path import join
 from optparse import OptionParser
 
+HOST_OS = utils.GuessOS()
+
+
+def makeString(input_file):
+  # TODO(iposva): For now avoid creating overly long strings on Windows.
+  if HOST_OS == 'win32':
+    return 'NULL'
+  result = '"'
+  fileHandle = open(input_file, 'rb')
+  lineCounter = 0
+  for byte in fileHandle.read():
+    result += '\\x%02x' % ord(byte)
+    lineCounter += 1
+    if lineCounter == 19:
+      result += '"\n "'
+      lineCounter = 0
+  result += '"'
+  return result
+
 
 def makeFile(output_file, input_cc_file, include, var_name, lib_name, in_files):
   part_index = [ ]
@@ -29,15 +49,17 @@
             main_file_found = True
             bootstrap_cc_text = bootstrap_cc_text.replace(
                  "{{LIBRARY_SOURCE_MAP}}",
-                 ' "' + lib_name + '", "' +
-                 os.path.abspath(string_file).replace('\\', '\\\\') + '", \n')
+                 ' "' + lib_name + '",\n "' +
+                 os.path.abspath(string_file).replace('\\', '\\\\') + '",\n' +
+                 ' ' + makeString(string_file) + ',\n')
         inpt.close()
         if (main_file_found):
           continue
       part_index.append(' "' +
-          os.path.basename(string_file).replace('\\', '\\\\') + '", ')
-      part_index.append('"' +
-          os.path.abspath(string_file).replace('\\', '\\\\') + '", \n')
+          os.path.basename(string_file).replace('\\', '\\\\') + '",\n')
+      part_index.append(' "' +
+          os.path.abspath(string_file).replace('\\', '\\\\') + '",\n')
+      part_index.append(' ' + makeString(string_file) + ',\n\n')
   bootstrap_cc_text = bootstrap_cc_text.replace("{{LIBRARY_SOURCE_MAP}}", '')
   bootstrap_cc_text = bootstrap_cc_text.replace("{{PART_SOURCE_MAP}}",
                                                 ''.join(part_index))
diff --git a/runtime/vm/allocation.h b/runtime/vm/allocation.h
index 468c1ad..af9a74a 100644
--- a/runtime/vm/allocation.h
+++ b/runtime/vm/allocation.h
@@ -37,13 +37,6 @@
 // to a stack frame above the frame where these objects were allocated.
 class StackResource {
  public:
-  // DEPRECATED: Use Thread-based interface. During migration, this defaults
-  // to using the mutator thread (which must also be the current thread).
-  explicit StackResource(Isolate* isolate) : thread_(NULL), previous_(NULL) {
-    Init((isolate == NULL) ?
-        NULL : reinterpret_cast<BaseIsolate*>(isolate)->mutator_thread_);
-  }
-
   explicit StackResource(Thread* thread) : thread_(NULL), previous_(NULL) {
     Init(thread);
   }
diff --git a/runtime/vm/allocation_test.cc b/runtime/vm/allocation_test.cc
index f8fe5a0..63b91f6 100644
--- a/runtime/vm/allocation_test.cc
+++ b/runtime/vm/allocation_test.cc
@@ -32,7 +32,7 @@
 class TestStackResource : public StackResource {
  public:
   explicit TestStackResource(int* ptr)
-      : StackResource(Isolate::Current()), ptr_(ptr) {
+      : StackResource(Thread::Current()), ptr_(ptr) {
     EXPECT_EQ(1, *ptr_);
     *ptr_ = 2;
   }
@@ -53,7 +53,7 @@
 class TestStackedStackResource : public StackResource {
  public:
   explicit TestStackedStackResource(int* ptr)
-      : StackResource(Isolate::Current()), ptr_(ptr) {
+      : StackResource(Thread::Current()), ptr_(ptr) {
     EXPECT_EQ(3, *ptr_);
     *ptr_ = 4;
   }
diff --git a/runtime/vm/assembler.cc b/runtime/vm/assembler.cc
index 4e1eca9..f5358c1 100644
--- a/runtime/vm/assembler.cc
+++ b/runtime/vm/assembler.cc
@@ -13,6 +13,12 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, disassemble);
+DECLARE_FLAG(bool, disassemble_optimized);
+
+DEFINE_FLAG(bool, check_code_pointer, false,
+            "Verify instructions offset in code object."
+            "NOTE: This breaks the profiler.");
 DEFINE_FLAG(bool, code_comments, false,
             "Include comments into code and disassembly");
 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
@@ -20,9 +26,6 @@
             "Enable far branches for ARM and MIPS");
 #endif
 
-DECLARE_FLAG(bool, disassemble);
-DECLARE_FLAG(bool, disassemble_optimized);
-
 static uword NewContents(intptr_t capacity) {
   Zone* zone = Thread::Current()->zone();
   uword result = zone->AllocUnsafe(capacity);
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 12fb7ff..e74a8c8 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -14,16 +14,19 @@
 #include "vm/stub_code.h"
 
 // An extra check since we are assuming the existence of /proc/cpuinfo below.
-#if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID)
+#if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) && \
+    !TARGET_OS_IOS
 #error ARM cross-compile only supported on Linux
 #endif
 
 namespace dart {
 
 DECLARE_FLAG(bool, allow_absolute_addresses);
-DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
+DECLARE_FLAG(bool, check_code_pointer);
 DECLARE_FLAG(bool, inline_alloc);
 
+DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
+
 uint32_t Address::encoding3() const {
   if (kind_ == Immediate) {
     uint32_t offset = encoding_ & kOffset12Mask;
@@ -495,10 +498,11 @@
 }
 
 
-void Assembler::ldrd(Register rd, Register rn, int32_t offset, Condition cond) {
+void Assembler::ldrd(Register rd, Register rd2, Register rn, int32_t offset,
+                     Condition cond) {
   ASSERT((rd % 2) == 0);
+  ASSERT(rd2 == rd + 1);
   if (TargetCPUFeatures::arm_version() == ARMv5TE) {
-    const Register rd2 = static_cast<Register>(static_cast<int32_t>(rd) + 1);
     ldr(rd, Address(rn, offset), cond);
     ldr(rd2, Address(rn, offset + kWordSize), cond);
   } else {
@@ -507,10 +511,11 @@
 }
 
 
-void Assembler::strd(Register rd, Register rn, int32_t offset, Condition cond) {
+void Assembler::strd(Register rd, Register rd2, Register rn, int32_t offset,
+                     Condition cond) {
   ASSERT((rd % 2) == 0);
+  ASSERT(rd2 == rd + 1);
   if (TargetCPUFeatures::arm_version() == ARMv5TE) {
-    const Register rd2 = static_cast<Register>(static_cast<int32_t>(rd) + 1);
     str(rd, Address(rn, offset), cond);
     str(rd2, Address(rn, offset + kWordSize), cond);
   } else {
@@ -1515,6 +1520,10 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  if (!FLAG_check_code_pointer) {
+    return;
+  }
+  Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   Push(R0);
   Push(IP);
@@ -1558,6 +1567,7 @@
 
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   ASSERT(!Thread::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
@@ -1574,6 +1584,7 @@
                                  Condition cond,
                                  bool is_unique,
                                  Register pp) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   // Load common VM constants from the thread. This works also in places where
   // no constant pool is set up (e.g. intrinsic code).
   if (Thread::CanLoadFromThread(object)) {
@@ -1632,12 +1643,14 @@
 
 
 void Assembler::PushObject(const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   LoadObject(IP, object);
   Push(IP);
 }
 
 
 void Assembler::CompareObject(Register rn, const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   ASSERT(rn != IP);
   if (object.IsSmi()) {
     CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw()));
@@ -1709,20 +1722,23 @@
                                        Register value_odd,
                                        Condition cond) {
   ASSERT(value_odd == value_even + 1);
+  ASSERT(value_even % 2 == 0);
   if (VerifiedMemory::enabled()) {
     ASSERT(base != value_even);
     ASSERT(base != value_odd);
     Operand shadow(GetVerifiedMemoryShadow());
     add(base, base, shadow, cond);
-    strd(value_even, base, offset, cond);
+    strd(value_even, value_odd, base, offset, cond);
     sub(base, base, shadow, cond);
   }
-  strd(value_even, base, offset, cond);
+  strd(value_even, value_odd, base, offset, cond);
 }
 
 
 Register UseRegister(Register reg, RegList* used) {
+  ASSERT(reg != THR);
   ASSERT(reg != SP);
+  ASSERT(reg != FP);
   ASSERT(reg != PC);
   ASSERT((*used & (1 << reg)) == 0);
   *used |= (1 << reg);
@@ -1738,7 +1754,8 @@
 }
 
 
-void Assembler::VerifiedWrite(const Address& address,
+void Assembler::VerifiedWrite(Register object,
+                              const Address& address,
                               Register new_value,
                               FieldContent old_content) {
 #if defined(DEBUG)
@@ -1748,6 +1765,9 @@
   RegList used = 0;
   UseRegister(new_value, &used);
   Register base = UseRegister(address.rn(), &used);
+  if ((object != base) && (object != kNoRegister)) {
+    UseRegister(object, &used);
+  }
   if (address.rm() != kNoRegister) {
     UseRegister(address.rm(), &used);
   }
@@ -1816,7 +1836,7 @@
                                 Register value,
                                 bool can_value_be_smi) {
   ASSERT(object != value);
-  VerifiedWrite(dest, value, kHeapObjectOrSmi);
+  VerifiedWrite(object, dest, value, kHeapObjectOrSmi);
   Label done;
   if (can_value_be_smi) {
     StoreIntoObjectFilter(object, value, &done);
@@ -1859,7 +1879,7 @@
                                          const Address& dest,
                                          Register value,
                                          FieldContent old_content) {
-  VerifiedWrite(dest, value, old_content);
+  VerifiedWrite(object, dest, value, old_content);
 #if defined(DEBUG)
   Label done;
   StoreIntoObjectFilter(object, value, &done);
@@ -1889,11 +1909,12 @@
                                          const Address& dest,
                                          const Object& value,
                                          FieldContent old_content) {
+  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
   ASSERT(value.IsSmi() || value.InVMHeap() ||
          (value.IsOld() && value.IsNotTemporaryScopedHandle()));
   // No store buffer update.
   LoadObject(IP, value);
-  VerifiedWrite(dest, IP, old_content);
+  VerifiedWrite(object, dest, IP, old_content);
 }
 
 
@@ -1901,13 +1922,17 @@
                                                int32_t offset,
                                                const Object& value,
                                                FieldContent old_content) {
+  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
   int32_t ignored = 0;
   if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
     StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
                              old_content);
   } else {
-    AddImmediate(IP, object, offset - kHeapObjectTag);
-    StoreIntoObjectNoBarrier(object, Address(IP), value, old_content);
+    Register base = object == R9 ? R8 : R9;
+    Push(base);
+    AddImmediate(base, object, offset - kHeapObjectTag);
+    StoreIntoObjectNoBarrier(object, Address(base), value, old_content);
+    Pop(base);
   }
 }
 
@@ -1971,7 +1996,7 @@
   Stop("New value must be Smi.");
   Bind(&done);
 #endif  // defined(DEBUG)
-  VerifiedWrite(dest, value, kOnlySmi);
+  VerifiedWrite(kNoRegister, dest, value, kOnlySmi);
 }
 
 
@@ -2833,6 +2858,7 @@
                                Register base,
                                int32_t offset,
                                Condition cond) {
+  ASSERT(size != kWordPair);
   int32_t offset_mask = 0;
   if (!Address::CanHoldLoadOffset(size, offset, &offset_mask)) {
     ASSERT(base != IP);
@@ -2856,9 +2882,6 @@
     case kWord:
       ldr(reg, Address(base, offset), cond);
       break;
-    case kWordPair:
-      ldrd(reg, base, offset, cond);
-      break;
     default:
       UNREACHABLE();
   }
@@ -2870,6 +2893,7 @@
                               Register base,
                               int32_t offset,
                               Condition cond) {
+  ASSERT(size != kWordPair);
   int32_t offset_mask = 0;
   if (!Address::CanHoldStoreOffset(size, offset, &offset_mask)) {
     ASSERT(reg != IP);
@@ -2888,9 +2912,6 @@
     case kWord:
       str(reg, Address(base, offset), cond);
       break;
-    case kWordPair:
-      strd(reg, base, offset, cond);
-      break;
     default:
       UNREACHABLE();
   }
@@ -3245,6 +3266,7 @@
 
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
+  Comment("EnterCallRuntimeFrame");
   // Preserve volatile CPU registers and PP.
   EnterFrame(kDartVolatileCpuRegs | (1 << PP) | (1 << FP), 0);
   COMPILE_ASSERT((kDartVolatileCpuRegs & (1 << PP)) == 0);
@@ -3311,7 +3333,10 @@
 void Assembler::EnterDartFrame(intptr_t frame_size) {
   ASSERT(!constant_pool_allowed());
 
-  // Registers are pushed in descending order: R9 | R10 | R11 | R14.
+  // Registers are pushed in descending order: R5 | R6 | R7/R11 | R14.
+  COMPILE_ASSERT(PP < CODE_REG);
+  COMPILE_ASSERT(CODE_REG < FP);
+  COMPILE_ASSERT(FP < LR);
   EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << LR), 0);
 
   // Setup pool pointer for this dart function.
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 78fb22d..80b888b 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -518,8 +518,11 @@
   // ldrd and strd actually support the full range of addressing modes, but
   // we don't use them, and we need to split them up into two instructions for
   // ARMv5TE, so we only support the base + offset mode.
-  void ldrd(Register rd, Register rn, int32_t offset, Condition cond = AL);
-  void strd(Register rd, Register rn, int32_t offset, Condition cond = AL);
+  // rd must be an even register and rd2 must be rd + 1.
+  void ldrd(Register rd, Register rd2, Register rn, int32_t offset,
+            Condition cond = AL);
+  void strd(Register rd, Register rd2, Register rn, int32_t offset,
+            Condition cond = AL);
 
   void ldm(BlockAddressMode am, Register base,
            RegList regs, Condition cond = AL);
@@ -1202,7 +1205,8 @@
                               Condition cond = AL);
   // Writes new_value to address and its shadow location, if enabled, after
   // verifying that its old value matches its shadow.
-  void VerifiedWrite(const Address& address,
+  void VerifiedWrite(Register object,
+                     const Address& address,
                      Register new_value,
                      FieldContent old_content);
 
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 06203d2..59c85c3 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -14,16 +14,19 @@
 #include "vm/stub_code.h"
 
 // An extra check since we are assuming the existence of /proc/cpuinfo below.
-#if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID)
+#if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) && \
+    !TARGET_OS_IOS
 #error ARM64 cross-compile only supported on Linux
 #endif
 
 namespace dart {
 
 DECLARE_FLAG(bool, allow_absolute_addresses);
+DECLARE_FLAG(bool, check_code_pointer);
+DECLARE_FLAG(bool, inline_alloc);
+
 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches");
 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
-DECLARE_FLAG(bool, inline_alloc);
 
 
 Assembler::Assembler(bool use_far_branches)
@@ -366,6 +369,7 @@
 
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   ASSERT(!Thread::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
@@ -400,6 +404,7 @@
 void Assembler::LoadObjectHelper(Register dst,
                                  const Object& object,
                                  bool is_unique) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (Thread::CanLoadFromThread(object)) {
     ldr(dst, Address(THR, Thread::OffsetFromThread(object)));
   } else if (CanLoadFromObjectPool(object)) {
@@ -438,6 +443,7 @@
 
 
 void Assembler::CompareObject(Register reg, const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (Thread::CanLoadFromThread(object)) {
     ldr(TMP, Address(THR, Thread::OffsetFromThread(object)));
     CompareRegisters(reg, TMP);
@@ -932,6 +938,7 @@
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
                                          const Object& value) {
+  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
   ASSERT(value.IsSmi() || value.InVMHeap() ||
          (value.IsOld() && value.IsNotTemporaryScopedHandle()));
   // No store buffer update.
@@ -1076,6 +1083,10 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  if (!FLAG_check_code_pointer) {
+    return;
+  }
+  Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   Push(R0);
   CompareClassId(CODE_REG, kCodeCid);
@@ -1162,6 +1173,7 @@
 
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
+  Comment("EnterCallRuntimeFrame");
   EnterStubFrame();
 
   // Store fpu registers with the lowest register number at the lowest
diff --git a/runtime/vm/assembler_arm64_test.cc b/runtime/vm/assembler_arm64_test.cc
index a187ee8..9320421 100644
--- a/runtime/vm/assembler_arm64_test.cc
+++ b/runtime/vm/assembler_arm64_test.cc
@@ -1625,14 +1625,17 @@
 static void EnterTestFrame(Assembler* assembler) {
   __ EnterFrame(0);
   __ Push(CODE_REG);
+  __ Push(THR);
   __ TagAndPushPP();
   __ ldr(CODE_REG, Address(R0, VMHandles::kOffsetOfRawPtrInHandle));
+  __ mov(THR, R1);
   __ LoadPoolPointer(PP);
 }
 
 
 static void LeaveTestFrame(Assembler* assembler) {
   __ PopAndUntagPP();
+  __ Pop(THR);
   __ Pop(CODE_REG);
   __ LeaveFrame();
 }
@@ -1652,7 +1655,7 @@
 
 
 ASSEMBLER_TEST_RUN(LoadImmediatePPSmall, test) {
-  EXPECT_EQ(42, test->InvokeWithCode<int64_t>());
+  EXPECT_EQ(42, test->InvokeWithCodeAndThread<int64_t>());
 }
 
 
@@ -1667,7 +1670,7 @@
 
 
 ASSEMBLER_TEST_RUN(LoadImmediatePPMed, test) {
-  EXPECT_EQ(0xf1234123, test->InvokeWithCode<int64_t>());
+  EXPECT_EQ(0xf1234123, test->InvokeWithCodeAndThread<int64_t>());
 }
 
 
@@ -1682,7 +1685,7 @@
 
 
 ASSEMBLER_TEST_RUN(LoadImmediatePPMed2, test) {
-  EXPECT_EQ(0x4321f1234124, test->InvokeWithCode<int64_t>());
+  EXPECT_EQ(0x4321f1234124, test->InvokeWithCodeAndThread<int64_t>());
 }
 
 
@@ -1698,23 +1701,15 @@
 
 ASSEMBLER_TEST_RUN(LoadImmediatePPLarge, test) {
   EXPECT_EQ(static_cast<int64_t>(0x9287436598237465),
-            test->InvokeWithCode<int64_t>());
+            test->InvokeWithCodeAndThread<int64_t>());
 }
 
 
-#define ASSEMBLER_TEST_RUN_WITH_THREAD(result_type, var_name) \
-  Thread* thread = Thread::Current(); \
-  result_type var_name = test->InvokeWithCode<result_type>(thread);
-
-
 // LoadObject null.
 ASSEMBLER_TEST_GENERATE(LoadObjectNull, assembler) {
   __ SetupDartSP(kTestStackSpace);
   EnterTestFrame(assembler);
-  __ Push(THR);
-  __ mov(THR, R1);
   __ LoadObject(R0, Object::null_object());
-  __ Pop(THR);
   LeaveTestFrame(assembler);
   __ mov(CSP, SP);
   __ ret();
@@ -1722,18 +1717,14 @@
 
 
 ASSEMBLER_TEST_RUN(LoadObjectNull, test) {
-  ASSEMBLER_TEST_RUN_WITH_THREAD(RawObject*, result);
-  EXPECT_EQ(Object::null(), result);
+  EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<RawObject*>());
 }
 
 
 ASSEMBLER_TEST_GENERATE(LoadObjectTrue, assembler) {
   __ SetupDartSP(kTestStackSpace);
   EnterTestFrame(assembler);
-  __ Push(THR);
-  __ mov(THR, R1);
   __ LoadObject(R0, Bool::True());
-  __ Pop(THR);
   LeaveTestFrame(assembler);
   __ mov(CSP, SP);
   __ ret();
@@ -1741,18 +1732,14 @@
 
 
 ASSEMBLER_TEST_RUN(LoadObjectTrue, test) {
-  ASSEMBLER_TEST_RUN_WITH_THREAD(RawObject*, result);
-  EXPECT_EQ(Bool::True().raw(), result);
+  EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<RawObject*>());
 }
 
 
 ASSEMBLER_TEST_GENERATE(LoadObjectFalse, assembler) {
   __ SetupDartSP(kTestStackSpace);
   EnterTestFrame(assembler);
-  __ Push(THR);
-  __ mov(THR, R1);
   __ LoadObject(R0, Bool::False());
-  __ Pop(THR);
   LeaveTestFrame(assembler);
   __ mov(CSP, SP);
   __ ret();
@@ -1760,8 +1747,7 @@
 
 
 ASSEMBLER_TEST_RUN(LoadObjectFalse, test) {
-  ASSEMBLER_TEST_RUN_WITH_THREAD(RawObject*, result);
-  EXPECT_EQ(Bool::False().raw(), result);
+  EXPECT_EQ(Bool::False().raw(), test->InvokeWithCodeAndThread<RawObject*>());
 }
 
 
@@ -3591,7 +3577,7 @@
   __ SetupDartSP(kTestStackSpace);
   EnterTestFrame(assembler);
   Label miss, done;
-  __ ComputeRange(R0, R1, R2, &miss);
+  __ ComputeRange(R0, R2, R3, &miss);
   __ b(&done);
 
   __ Bind(&miss);
@@ -3605,7 +3591,8 @@
 
 
 ASSEMBLER_TEST_RUN(ComputeRange, test) {
-#define RANGE_OF(arg_type, v) test->InvokeWithCode<intptr_t, arg_type>(v)
+#define RANGE_OF(arg_type, v)                                                  \
+  test->InvokeWithCodeAndThread<intptr_t, arg_type>(v)
 
   EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(RawSmi*, Smi::New(0)));
   EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(RawSmi*, Smi::New(1)));
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index dd53235..12f470a 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -1150,10 +1150,10 @@
 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) {
   __ mov(IP, Operand(SP));
   __ sub(SP, SP, Operand(kWordSize*30));
-  __ strd(R2, SP, 0);
-  __ strd(R0, IP, (-kWordSize*28));
-  __ ldrd(R2, IP, (-kWordSize*28));
-  __ ldrd(R0, SP, 0);
+  __ strd(R2, R3, SP, 0);
+  __ strd(R0, R1, IP, (-kWordSize*28));
+  __ ldrd(R2, R3, IP, (-kWordSize*28));
+  __ ldrd(R0, R1, SP, 0);
   __ add(SP, SP, Operand(kWordSize*30));
   __ sub(R0, R0, Operand(R2));
   __ add(R1, R1, Operand(R3));
@@ -1174,33 +1174,33 @@
   __ mov(R1, Operand(7));
   __ mov(R2, Operand(11));
   __ mov(R3, Operand(31));
-  __ Push(R5);  // We use R5 as accumulator.
-  __ Push(R5);
-  __ Push(R5);
-  __ Push(R5);
-  __ Push(R5);
+  __ Push(R9);  // We use R9 as accumulator.
+  __ Push(R9);
+  __ Push(R9);
+  __ Push(R9);
+  __ Push(R9);
   __ Push(R0);  // Make room, so we can decrement after.
   __ stm(DA_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
   __ str(R2, Address(SP));                 // Should be a free slot.
-  __ ldr(R5, Address(SP, 1 * kWordSize));  // R0.  R5 = +1.
+  __ ldr(R9, Address(SP, 1 * kWordSize));  // R0.  R9 = +1.
   __ ldr(IP, Address(SP, 2 * kWordSize));  // R1.
-  __ sub(R5, R5, Operand(IP));      // -R1. R5 = -6.
+  __ sub(R9, R9, Operand(IP));      // -R1. R9 = -6.
   __ ldr(IP, Address(SP, 3 * kWordSize));  // R2.
-  __ add(R5, R5, Operand(IP));      // +R2. R5 = +5.
+  __ add(R9, R9, Operand(IP));      // +R2. R9 = +5.
   __ ldr(IP, Address(SP, 4 * kWordSize));  // R3.
-  __ sub(R5, R5, Operand(IP));      // -R3. R5 = -26.
+  __ sub(R9, R9, Operand(IP));      // -R3. R9 = -26.
   __ ldm(IB_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
   // Same operations again. But this time from the restore registers.
-  __ add(R5, R5, Operand(R0));
-  __ sub(R5, R5, Operand(R1));
-  __ add(R5, R5, Operand(R2));
-  __ sub(R0, R5, Operand(R3));  // R0 = result = -52.
+  __ add(R9, R9, Operand(R0));
+  __ sub(R9, R9, Operand(R1));
+  __ add(R9, R9, Operand(R2));
+  __ sub(R0, R9, Operand(R3));  // R0 = result = -52.
   __ Pop(R1);  // Remove storage slot.
-  __ Pop(R5);  // Restore R5.
-  __ Pop(R5);  // Restore R5.
-  __ Pop(R5);  // Restore R5.
-  __ Pop(R5);  // Restore R5.
-  __ Pop(R5);  // Restore R5.
+  __ Pop(R9);  // Restore R9.
+  __ Pop(R9);  // Restore R9.
+  __ Pop(R9);  // Restore R9.
+  __ Pop(R9);  // Restore R9.
+  __ Pop(R9);  // Restore R9.
   __ bx(LR);
 }
 
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index 7fe4193..8d3fb09 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -2163,6 +2163,7 @@
 
 
 void Assembler::LoadObject(Register dst, const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (object.IsSmi() || object.InVMHeap()) {
     movl(dst, Immediate(reinterpret_cast<int32_t>(object.raw())));
   } else {
@@ -2176,6 +2177,7 @@
 
 
 void Assembler::LoadObjectSafely(Register dst, const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (Assembler::IsSafe(object)) {
     LoadObject(dst, object);
   } else {
@@ -2187,6 +2189,7 @@
 
 
 void Assembler::PushObject(const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (object.IsSmi() || object.InVMHeap()) {
     pushl(Immediate(reinterpret_cast<int32_t>(object.raw())));
   } else {
@@ -2200,6 +2203,7 @@
 
 
 void Assembler::CompareObject(Register reg, const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (object.IsSmi() || object.InVMHeap()) {
     cmpl(reg, Immediate(reinterpret_cast<int32_t>(object.raw())));
   } else {
@@ -2398,6 +2402,7 @@
 
 void Assembler::UnverifiedStoreOldObject(const Address& dest,
                                          const Object& value) {
+  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
   ASSERT(value.IsOld());
   ASSERT(!value.InVMHeap());
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
@@ -2411,6 +2416,7 @@
                                          const Address& dest,
                                          const Object& value,
                                          FieldContent old_content) {
+  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
   VerifyHeapWord(dest, old_content);
   if (value.IsSmi() || value.InVMHeap()) {
     Immediate imm_value(reinterpret_cast<int32_t>(value.raw()));
@@ -2570,6 +2576,7 @@
 
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
+  Comment("EnterCallRuntimeFrame");
   EnterFrame(0);
 
   // Preserve volatile CPU registers.
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 90a010a..957b549 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -14,12 +14,14 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, allow_absolute_addresses);
+DECLARE_FLAG(bool, check_code_pointer);
+DECLARE_FLAG(bool, inline_alloc);
 #if defined(USING_SIMULATOR)
 DECLARE_FLAG(int, trace_sim_after);
 #endif
-DECLARE_FLAG(bool, allow_absolute_addresses);
+
 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
-DECLARE_FLAG(bool, inline_alloc);
 
 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
   ASSERT(Utils::IsAligned(data, 4));
@@ -461,6 +463,10 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  if (!FLAG_check_code_pointer) {
+    return;
+  }
+  Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   Push(CMPRES1);
   Push(CMPRES2);
@@ -531,6 +537,7 @@
 
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   ASSERT(!Thread::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
@@ -545,6 +552,7 @@
 void Assembler::LoadObjectHelper(Register rd,
                                  const Object& object,
                                  bool is_unique) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   ASSERT(!in_delay_slot_);
   if (Thread::CanLoadFromThread(object)) {
     // Load common VM constants from the thread. This works also in places where
@@ -602,6 +610,7 @@
 
 
 void Assembler::PushObject(const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   ASSERT(!in_delay_slot_);
   LoadObject(TMP, object);
   Push(TMP);
@@ -728,6 +737,7 @@
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
                                          const Object& value) {
+  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
   ASSERT(!in_delay_slot_);
   ASSERT(value.IsSmi() || value.InVMHeap() ||
          (value.IsOld() && value.IsNotTemporaryScopedHandle()));
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 5316110..e075dd3 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -762,6 +762,12 @@
     EmitRType(SPECIAL, rs, rt, R0, 0, MULTU);
   }
 
+  void negd(DRegister dd, DRegister ds) {
+    FRegister fd = static_cast<FRegister>(dd * 2);
+    FRegister fs = static_cast<FRegister>(ds * 2);
+    EmitFpuRType(COP1, FMT_D, F0, fs, fd, COP1_NEG);
+  }
+
   void nop() {
     Emit(Instr::kNopInstruction);
   }
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index 552aa60..f23fe93 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -1639,6 +1639,21 @@
 }
 
 
+ASSEMBLER_TEST_GENERATE(Negd, assembler) {
+  __ LoadImmediate(D1, 1.0);
+  __ negd(D0, D1);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Negd, test) {
+  typedef double (*SimpleCode)() DART_UNUSED;
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(-1.0, res, 0.001);
+}
+
+
 ASSEMBLER_TEST_GENERATE(Sdc1Ldc1, assembler) {
   __ mov(T0, SP);
   __ AddImmediate(SP, -3 * kWordSize);
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 04e82d8..02527fc 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -18,9 +18,11 @@
 namespace dart {
 
 DECLARE_FLAG(bool, allow_absolute_addresses);
-DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
+DECLARE_FLAG(bool, check_code_pointer);
 DECLARE_FLAG(bool, inline_alloc);
 
+DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
+
 
 Assembler::Assembler(bool use_far_branches)
     : buffer_(),
@@ -785,57 +787,29 @@
 }
 
 void Assembler::notps(XmmRegister dst) {
-  static const struct ALIGN16 {
-    uint32_t a;
-    uint32_t b;
-    uint32_t c;
-    uint32_t d;
-  } float_not_constant =
-      { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
-  LoadImmediate(
-      TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant)));
+  // { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+  movq(TMP, Address(THR, Thread::float_not_address_offset()));
   xorps(dst, Address(TMP, 0));
 }
 
 
 void Assembler::negateps(XmmRegister dst) {
-  static const struct ALIGN16 {
-    uint32_t a;
-    uint32_t b;
-    uint32_t c;
-    uint32_t d;
-  } float_negate_constant =
-      { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
-  LoadImmediate(
-      TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant)));
+  // { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }
+  movq(TMP, Address(THR, Thread::float_negate_address_offset()));
   xorps(dst, Address(TMP, 0));
 }
 
 
 void Assembler::absps(XmmRegister dst) {
-  static const struct ALIGN16 {
-    uint32_t a;
-    uint32_t b;
-    uint32_t c;
-    uint32_t d;
-  } float_absolute_constant =
-      { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
-  LoadImmediate(
-      TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant)));
+  // { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }
+  movq(TMP, Address(THR, Thread::float_absolute_address_offset()));
   andps(dst, Address(TMP, 0));
 }
 
 
 void Assembler::zerowps(XmmRegister dst) {
-  static const struct ALIGN16 {
-    uint32_t a;
-    uint32_t b;
-    uint32_t c;
-    uint32_t d;
-  } float_zerow_constant =
-      { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 };
-  LoadImmediate(
-      TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant)));
+  // { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }
+  movq(TMP, Address(THR, Thread::float_zerow_address_offset()));
   andps(dst, Address(TMP, 0));
 }
 
@@ -1017,13 +991,8 @@
 
 
 void Assembler::negatepd(XmmRegister dst) {
-  static const struct ALIGN16 {
-    uint64_t a;
-    uint64_t b;
-  } double_negate_constant =
-      { 0x8000000000000000LL, 0x8000000000000000LL };
-  LoadImmediate(
-      TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)));
+  // { 0x8000000000000000LL, 0x8000000000000000LL }
+  movq(TMP, Address(THR, Thread::double_negate_address_offset()));
   xorpd(dst, Address(TMP, 0));
 }
 
@@ -1065,13 +1034,8 @@
 
 
 void Assembler::abspd(XmmRegister dst) {
-  static const struct ALIGN16 {
-    uint64_t a;
-    uint64_t b;
-  } double_absolute_const =
-      { 0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL };
-  LoadImmediate(
-      TMP, Immediate(reinterpret_cast<intptr_t>(&double_absolute_const)));
+  // { 0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL }
+  movq(TMP, Address(THR, Thread::double_abs_address_offset()));
   andpd(dst, Address(TMP, 0));
 }
 
@@ -1343,13 +1307,6 @@
 }
 
 
-void Assembler::fildl(const Address& src) {
-  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
-  EmitUint8(0xDF);
-  EmitOperand(5, src);
-}
-
-
 void Assembler::fincstp() {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0xD9);
@@ -2782,6 +2739,7 @@
 
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   ASSERT(!Thread::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
@@ -2817,6 +2775,7 @@
 void Assembler::LoadObjectHelper(Register dst,
                                  const Object& object,
                                  bool is_unique) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (Thread::CanLoadFromThread(object)) {
     movq(dst, Address(THR, Thread::OffsetFromThread(object)));
   } else if (CanLoadFromObjectPool(object)) {
@@ -2854,6 +2813,7 @@
 
 
 void Assembler::StoreObject(const Address& dst, const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (Thread::CanLoadFromThread(object)) {
     movq(TMP, Address(THR, Thread::OffsetFromThread(object)));
     movq(dst, TMP);
@@ -2868,6 +2828,7 @@
 
 
 void Assembler::PushObject(const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (Thread::CanLoadFromThread(object)) {
     pushq(Address(THR, Thread::OffsetFromThread(object)));
   } else if (CanLoadFromObjectPool(object)) {
@@ -2881,6 +2842,7 @@
 
 
 void Assembler::CompareObject(Register reg, const Object& object) {
+  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
   if (Thread::CanLoadFromThread(object)) {
     cmpq(reg, Address(THR, Thread::OffsetFromThread(object)));
   } else if (CanLoadFromObjectPool(object)) {
@@ -3107,6 +3069,7 @@
                                          const Address& dest,
                                          const Object& value,
                                          FieldContent old_content) {
+  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
   VerifyHeapWord(dest, old_content);
   if (VerifiedMemory::enabled()) {
     const Register temp = RCX;
@@ -3167,25 +3130,15 @@
 
 
 void Assembler::DoubleNegate(XmmRegister d) {
-  static const struct ALIGN16 {
-    uint64_t a;
-    uint64_t b;
-  } double_negate_constant =
-      {0x8000000000000000LL, 0x8000000000000000LL};
-  LoadImmediate(
-      TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)));
+  // {0x8000000000000000LL, 0x8000000000000000LL}
+  movq(TMP, Address(THR, Thread::double_negate_address_offset()));
   xorpd(d, Address(TMP, 0));
 }
 
 
 void Assembler::DoubleAbs(XmmRegister reg) {
-  static const struct ALIGN16 {
-    uint64_t a;
-    uint64_t b;
-  } double_abs_constant =
-      {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
-  LoadImmediate(TMP,
-      Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)));
+  // {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}
+  movq(TMP, Address(THR, Thread::double_abs_address_offset()));
   andpd(reg, Address(TMP, 0));
 }
 
@@ -3331,6 +3284,7 @@
 
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
+  Comment("EnterCallRuntimeFrame");
   EnterStubFrame();
 
   // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
@@ -3420,6 +3374,10 @@
 
 void Assembler::CheckCodePointer() {
 #ifdef DEBUG
+  if (!FLAG_check_code_pointer) {
+    return;
+  }
+  Comment("CheckCodePointer");
   Label cid_ok, instructions_ok;
   pushq(RAX);
   LoadClassId(RAX, CODE_REG);
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 0a6b694..30feb10 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -671,8 +671,6 @@
   void fldl(const Address& src);
   void fstpl(const Address& dst);
 
-  void fildl(const Address& src);
-
   void fincstp();
   void ffree(intptr_t value);
 
diff --git a/runtime/vm/assembler_x64_test.cc b/runtime/vm/assembler_x64_test.cc
index e404b89..eb8219d 100644
--- a/runtime/vm/assembler_x64_test.cc
+++ b/runtime/vm/assembler_x64_test.cc
@@ -2021,16 +2021,21 @@
 
 
 static void EnterTestFrame(Assembler* assembler) {
+  COMPILE_ASSERT(THR != CallingConventions::kArg1Reg);
+  COMPILE_ASSERT(CODE_REG != CallingConventions::kArg2Reg);
   __ EnterFrame(0);
   __ pushq(CODE_REG);
   __ pushq(PP);
+  __ pushq(THR);
   __ movq(CODE_REG, Address(CallingConventions::kArg1Reg,
                             VMHandles::kOffsetOfRawPtrInHandle));
+  __ movq(THR, CallingConventions::kArg2Reg);
   __ LoadPoolPointer(PP);
 }
 
 
 static void LeaveTestFrame(Assembler* assembler) {
+  __ popq(THR);
   __ popq(PP);
   __ popq(CODE_REG);
   __ LeaveFrame();
@@ -2053,7 +2058,7 @@
 
 
 ASSEMBLER_TEST_RUN(PackedDoubleNegate, test) {
-  double res = test->InvokeWithCode<double>();
+  double res = test->InvokeWithCodeAndThread<double>();
   EXPECT_FLOAT_EQ(-1.0, res, 0.000001f);
 }
 
@@ -2074,7 +2079,7 @@
 
 
 ASSEMBLER_TEST_RUN(PackedDoubleAbsolute, test) {
-  double res = test->InvokeWithCode<double>();
+  double res = test->InvokeWithCodeAndThread<double>();
   EXPECT_FLOAT_EQ(1.0, res, 0.000001f);
 }
 
@@ -2520,7 +2525,7 @@
 
 
 ASSEMBLER_TEST_RUN(PackedNegate, test) {
-  float res = test->InvokeWithCode<float>();
+  float res = test->InvokeWithCodeAndThread<float>();
   EXPECT_FLOAT_EQ(-12.3f, res, 0.001f);
 }
 
@@ -2538,7 +2543,7 @@
 
 
 ASSEMBLER_TEST_RUN(PackedAbsolute, test) {
-  float res = test->InvokeWithCode<float>();
+  float res = test->InvokeWithCodeAndThread<float>();
   EXPECT_FLOAT_EQ(15.3f, res, 0.001f);
 }
 
@@ -2554,7 +2559,7 @@
 
 
 ASSEMBLER_TEST_RUN(PackedSetWZero, test) {
-  float res = test->InvokeWithCode<float>();
+  float res = test->InvokeWithCodeAndThread<float>();
   EXPECT_FLOAT_EQ(0.0f, res, 0.001f);
 }
 
@@ -2678,7 +2683,7 @@
 
 
 ASSEMBLER_TEST_RUN(PackedLogicalNot, test) {
-  uint32_t res = test->InvokeWithCode<uint32_t>();
+  uint32_t res = test->InvokeWithCodeAndThread<uint32_t>();
   EXPECT_EQ(static_cast<uword>(0x0), res);
 }
 
@@ -3092,8 +3097,7 @@
   __ CompareObject(RCX, smi);
   __ j(NOT_EQUAL, &fail);
   __ movl(RAX, Immediate(1));  // OK
-  __ popq(PP);  // Restore caller's pool pointer.
-  __ LeaveFrame();
+  LeaveTestFrame(assembler);
   __ ret();
   __ Bind(&fail);
   __ movl(RAX, Immediate(0));  // Fail.
@@ -3103,7 +3107,7 @@
 
 
 ASSEMBLER_TEST_RUN(TestObjectCompare, test) {
-  bool res = test->InvokeWithCode<bool>();
+  bool res = test->InvokeWithCodeAndThread<bool>();
   EXPECT_EQ(true, res);
 }
 
@@ -3393,22 +3397,6 @@
 }
 
 
-ASSEMBLER_TEST_GENERATE(IntToDoubleConversion2, assembler) {
-  __ pushq(CallingConventions::kArg1Reg);
-  __ fildl(Address(RSP, 0));
-  __ fstpl(Address(RSP, 0));
-  __ movsd(XMM0, Address(RSP, 0));
-  __ popq(RAX);
-  __ ret();
-}
-
-
-ASSEMBLER_TEST_RUN(IntToDoubleConversion2, test) {
-  typedef double (*IntToDoubleConversion2Code)(int i);
-  double res = reinterpret_cast<IntToDoubleConversion2Code>(test->entry())(3);
-  EXPECT_FLOAT_EQ(3.0, res, 0.001);
-}
-
 ASSEMBLER_TEST_GENERATE(DoubleToDoubleTrunc, assembler) {
   __ roundsd(XMM0, XMM0, Assembler::kRoundToZero);
   __ ret();
@@ -3431,10 +3419,13 @@
 ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) {
   EnterTestFrame(assembler);
 #if defined(TARGET_OS_WINDOWS)
-  // First argument is code object, MSVC passes second argument in XMM1.
-  __ DoubleAbs(XMM1);
-  __ movaps(XMM0, XMM1);
+  // First argument is code object, second argument is thread. MSVC passes
+  // third argument in XMM2.
+  __ DoubleAbs(XMM2);
+  __ movaps(XMM0, XMM2);
 #else
+  // SysV ABI allocates integral and double registers for arguments
+  // independently.
   __ DoubleAbs(XMM0);
 #endif
   LeaveTestFrame(assembler);
@@ -3444,10 +3435,10 @@
 
 ASSEMBLER_TEST_RUN(DoubleAbs, test) {
   double val = -12.45;
-  double res =  test->InvokeWithCode<double, double>(val);
+  double res =  test->InvokeWithCodeAndThread<double, double>(val);
   EXPECT_FLOAT_EQ(-val, res, 0.001);
   val = 12.45;
-  res = test->InvokeWithCode<double, double>(val);
+  res = test->InvokeWithCodeAndThread<double, double>(val);
   EXPECT_FLOAT_EQ(val, res, 0.001);
 }
 
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index 48bd053..19542b3 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -6,14 +6,21 @@
 #include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/isolate.h"
+#include "vm/log.h"
 #include "vm/object_store.h"
 #include "vm/resolver.h"
 
 
 namespace dart {
 
+DEFINE_FLAG(bool, trace_ast_visitor, false,
+            "Trace AstVisitor.");
+
 #define DEFINE_VISIT_FUNCTION(BaseName)                                        \
 void BaseName##Node::Visit(AstNodeVisitor* visitor) {                          \
+  if (FLAG_trace_ast_visitor) {                                                \
+    THR_Print("Visiting %s\n", PrettyName());                                  \
+  }                                                                            \
   visitor->Visit##BaseName##Node(this);                                        \
 }
 
@@ -99,7 +106,7 @@
   LocalVariable* temp_var =
       new LocalVariable(token_pos(),
                         String::ZoneHandle(Symbols::New(name)),
-                        Type::ZoneHandle(Type::DynamicType()));
+                        Object::dynamic_type());
   vars_.Add(temp_var);
   return temp_var;
 }
@@ -122,6 +129,16 @@
 }
 
 
+bool StringInterpolateNode::IsPotentiallyConst() const {
+  for (int i = 0; i < value_->length(); i++) {
+    if (!value_->ElementAt(i)->IsPotentiallyConst()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
 bool LiteralNode::IsPotentiallyConst() const {
   return true;
 }
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index c3b6ac1..01ae0cf 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -92,7 +92,6 @@
 #define DECLARE_COMMON_NODE_FUNCTIONS(type)                                    \
   virtual void Visit(AstNodeVisitor* visitor);                                 \
   virtual const char* PrettyName() const;                                      \
-  virtual bool Is##type() const { return true; }                               \
   virtual type* As##type() { return this; }
 
 
@@ -100,14 +99,14 @@
  public:
   explicit AstNode(intptr_t token_pos)
       : token_pos_(token_pos) {
-    ASSERT(token_pos_ >= 0);
+    ASSERT(Scanner::ValidSourcePosition(token_pos_));
   }
   virtual ~AstNode() { }
 
   intptr_t token_pos() const { return token_pos_; }
 
 #define AST_TYPE_CHECK(BaseName)                                               \
-  virtual bool Is##BaseName##Node() const { return false; }                    \
+  bool Is##BaseName##Node() { return As##BaseName##Node() != NULL; }           \
   virtual BaseName##Node* As##BaseName##Node() { return NULL; }
 
   FOR_EACH_NODE(AST_TYPE_CHECK)
@@ -213,8 +212,10 @@
 //   <AwaitMarker> -> ...
 class AwaitMarkerNode : public AstNode {
  public:
-  AwaitMarkerNode(LocalScope* async_scope, LocalScope* await_scope)
-    : AstNode(Scanner::kNoSourcePos),
+  AwaitMarkerNode(LocalScope* async_scope,
+                  LocalScope* await_scope,
+                  intptr_t token_pos)
+    : AstNode(token_pos),
       async_scope_(async_scope),
       await_scope_(await_scope) {
     ASSERT(async_scope != NULL);
@@ -411,6 +412,8 @@
 
   ArrayNode* value() const { return value_; }
 
+  virtual bool IsPotentiallyConst() const;
+
   DECLARE_COMMON_NODE_FUNCTIONS(StringInterpolateNode);
 
  private:
@@ -1814,19 +1817,14 @@
   NativeBodyNode(intptr_t token_pos,
                  const Function& function,
                  const String& native_c_function_name,
-                 NativeFunction native_c_function,
                  LocalScope* scope,
-                 bool is_bootstrap_native,
                  bool link_lazily = false)
       : AstNode(token_pos),
         function_(function),
         native_c_function_name_(native_c_function_name),
-        native_c_function_(native_c_function),
         scope_(scope),
-        is_bootstrap_native_(is_bootstrap_native),
         link_lazily_(link_lazily) {
     ASSERT(function_.IsZoneHandle());
-    ASSERT(native_c_function_ != NULL);
     ASSERT(native_c_function_name_.IsZoneHandle());
     ASSERT(native_c_function_name_.IsSymbol());
   }
@@ -1835,9 +1833,7 @@
   const String& native_c_function_name() const {
     return native_c_function_name_;
   }
-  NativeFunction native_c_function() const { return native_c_function_; }
   LocalScope* scope() const { return scope_; }
-  bool is_bootstrap_native() const { return is_bootstrap_native_; }
 
   bool link_lazily() const { return link_lazily_; }
 
@@ -1848,9 +1844,7 @@
  private:
   const Function& function_;  // Native Dart function.
   const String& native_c_function_name_;
-  NativeFunction native_c_function_;  // Actual non-Dart implementation.
   LocalScope* scope_;
-  const bool is_bootstrap_native_;  // Is a bootstrap native method.
   const bool link_lazily_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(NativeBodyNode);
@@ -1929,13 +1923,15 @@
                const LocalVariable* context_var,
                CatchClauseNode* catch_block,
                SequenceNode* finally_block,
-               intptr_t try_index)
+               intptr_t try_index,
+               SequenceNode* rethrow_clause)
       : AstNode(token_pos),
         try_block_(try_block),
         context_var_(*context_var),
         catch_block_(catch_block),
         finally_block_(finally_block),
-        try_index_(try_index) {
+        try_index_(try_index),
+        rethrow_clause_(rethrow_clause) {
     ASSERT(try_block_ != NULL);
     ASSERT(context_var != NULL);
     ASSERT(catch_block_ != NULL);
@@ -1947,6 +1943,8 @@
   const LocalVariable& context_var() const { return context_var_; }
   intptr_t try_index() const { return try_index_; }
 
+  SequenceNode* rethrow_clause() const { return rethrow_clause_; }
+
   virtual void VisitChildren(AstNodeVisitor* visitor) const {
     try_block_->Visit(visitor);
     if (catch_block_ != NULL) {
@@ -1965,6 +1963,7 @@
   CatchClauseNode* catch_block_;
   SequenceNode* finally_block_;
   const intptr_t try_index_;
+  SequenceNode* rethrow_clause_;
 
   DISALLOW_COPY_AND_ASSIGN(TryCatchNode);
 };
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index 95d8d4f..32ec3f9 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -71,7 +71,7 @@
   if (await_tmp == NULL) {
     // We need a new temp variable; add it to the function's top scope.
     await_tmp = new (Z) LocalVariable(
-        Scanner::kNoSourcePos, symbol, Type::ZoneHandle(Type::DynamicType()));
+        Scanner::kNoSourcePos, symbol, Object::dynamic_type());
     async_temp_scope_->AddVariable(await_tmp);
     // After adding it to the top scope, we can look it up from the preamble.
     // The following call includes an ASSERT check.
@@ -119,6 +119,7 @@
   //   :saved_try_ctx_var = :await_saved_try_ctx_var_y;
   //   :await_temp_var_(X+1) = :result_param;
 
+  const intptr_t token_pos = node->token_pos();
   LocalVariable* async_op = GetVariableInScope(
       preamble_->scope(), Symbols::AsyncOperation());
   LocalVariable* async_then_callback = GetVariableInScope(
@@ -136,7 +137,7 @@
   LocalVariable* await_temp = AddToPreambleNewTempVar(transformed_expr);
 
   AwaitMarkerNode* await_marker =
-      new (Z) AwaitMarkerNode(async_temp_scope_, node->scope());
+      new (Z) AwaitMarkerNode(async_temp_scope_, node->scope(), token_pos);
   preamble_->Add(await_marker);
 
   // :result_param = _awaitHelper(
diff --git a/runtime/vm/atomic.h b/runtime/vm/atomic.h
index 9d1fd13..809548a 100644
--- a/runtime/vm/atomic.h
+++ b/runtime/vm/atomic.h
@@ -33,6 +33,8 @@
   //
   // NOTE: OK to use with memory locations that are accessed by generated code
   static uword CompareAndSwapWord(uword* ptr, uword old_value, uword new_value);
+  static uint32_t CompareAndSwapUint32(
+      uint32_t* ptr, uint32_t old_value, uint32_t new_value);
 
   // Performs a load of a word from 'ptr', but without any guarantees about
   // memory order (i.e., no load barriers/fences).
diff --git a/runtime/vm/atomic_android.h b/runtime/vm/atomic_android.h
index 9f4df90..8d01ae7 100644
--- a/runtime/vm/atomic_android.h
+++ b/runtime/vm/atomic_android.h
@@ -32,6 +32,13 @@
                                                   uword new_value) {
   return __sync_val_compare_and_swap(ptr, old_value, new_value);
 }
+
+
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
 #endif  // !defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/atomic_linux.h b/runtime/vm/atomic_linux.h
index dc57f2d..1150857 100644
--- a/runtime/vm/atomic_linux.h
+++ b/runtime/vm/atomic_linux.h
@@ -32,6 +32,13 @@
                                                   uword new_value) {
   return __sync_val_compare_and_swap(ptr, old_value, new_value);
 }
+
+
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
 #endif  // !defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/atomic_macos.h b/runtime/vm/atomic_macos.h
index b56d2a0..31d219b 100644
--- a/runtime/vm/atomic_macos.h
+++ b/runtime/vm/atomic_macos.h
@@ -32,6 +32,13 @@
                                                   uword new_value) {
   return __sync_val_compare_and_swap(ptr, old_value, new_value);
 }
+
+
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
 #endif  // !defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/atomic_simulator.h b/runtime/vm/atomic_simulator.h
index 26cde3c..2b52a22 100644
--- a/runtime/vm/atomic_simulator.h
+++ b/runtime/vm/atomic_simulator.h
@@ -18,6 +18,13 @@
                                                   uword new_value) {
   return Simulator::CompareExchange(ptr, old_value, new_value);
 }
+
+
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+  return Simulator::CompareExchangeUint32(ptr, old_value, new_value);
+}
 #endif  // defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/atomic_test.cc b/runtime/vm/atomic_test.cc
index 5e22606..2e327a5 100644
--- a/runtime/vm/atomic_test.cc
+++ b/runtime/vm/atomic_test.cc
@@ -31,4 +31,22 @@
   EXPECT_EQ(static_cast<uword>(42), AtomicOperations::LoadRelaxed(&v));
 }
 
+
+TEST_CASE(CompareAndSwapWord) {
+  uword old_value = 42;
+  uword new_value = 100;
+  uword result = AtomicOperations::CompareAndSwapWord(
+      &old_value, old_value, new_value);
+  EXPECT_EQ(static_cast<uword>(42), result);
+}
+
+
+TEST_CASE(CompareAndSwapUint32) {
+  uint32_t old_value = 42;
+  uint32_t new_value = 100;
+  uint32_t result = AtomicOperations::CompareAndSwapUint32(
+      &old_value, old_value, new_value);
+  EXPECT_EQ(static_cast<uint32_t>(42), result);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/atomic_win.h b/runtime/vm/atomic_win.h
index 4ef539c..8e07cd3 100644
--- a/runtime/vm/atomic_win.h
+++ b/runtime/vm/atomic_win.h
@@ -59,6 +59,18 @@
 #error Unsupported host architecture.
 #endif
 }
+inline uint32_t AtomicOperations::CompareAndSwapUint32(uint32_t* ptr,
+                                                       uint32_t old_value,
+                                                       uint32_t new_value) {
+#if (defined(HOST_ARCH_X64) || defined(HOST_ARCH_IA32))
+  return static_cast<uint32_t>(
+      InterlockedCompareExchange(reinterpret_cast<LONG*>(ptr),
+                                 static_cast<LONG>(new_value),
+                                 static_cast<LONG>(old_value)));
+#else
+#error Unsupported host architecture.
+#endif
+}
 #endif  // !defined(USING_SIMULATOR)
 
 }  // namespace dart
diff --git a/runtime/vm/base_isolate.h b/runtime/vm/base_isolate.h
index 833f7e5..b2cc7fc 100644
--- a/runtime/vm/base_isolate.h
+++ b/runtime/vm/base_isolate.h
@@ -42,9 +42,6 @@
   Thread* mutator_thread_;
 
  private:
-  // During migration, some deprecated interfaces will default to using the
-  // mutator_thread_ (can't use accessor in Isolate due to circular deps).
-  friend class StackResource;
   DISALLOW_COPY_AND_ASSIGN(BaseIsolate);
 };
 
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 9fcb4d00..dc2fcdf 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -41,8 +41,7 @@
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
   Timer timer(true, "Compile all of Core lib benchmark");
   timer.Start();
-  const Error& error = Error::Handle(benchmark->isolate()->current_zone(),
-                                     Library::CompileAll());
+  const Error& error = Error::Handle(Library::CompileAll());
   if (!error.IsNull()) {
     OS::PrintErr("Unexpected error in CorelibCompileAll benchmark:\n%s",
                  error.ToErrorCString());
@@ -56,13 +55,12 @@
 BENCHMARK(CorelibCompilerStats) {
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
-  CompilerStats* stats = Isolate::Current()->compiler_stats();
+  CompilerStats* stats = thread->isolate()->compiler_stats();
   ASSERT(stats != NULL);
   stats->EnableBenchmark();
   Timer timer(true, "Compiler stats compiling all of Core lib");
   timer.Start();
-  const Error& error = Error::Handle(benchmark->isolate()->current_zone(),
-                                     Library::CompileAll());
+  const Error& error = Error::Handle(Library::CompileAll());
   if (!error.IsNull()) {
     OS::PrintErr("Unexpected error in CorelibCompileAll benchmark:\n%s",
                  error.ToErrorCString());
@@ -79,7 +77,7 @@
 BENCHMARK(CorelibIsolateStartup) {
   const int kNumIterations = 1000;
   Timer timer(true, "CorelibIsolateStartup");
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
   Thread::ExitIsolate();
   for (int i = 0; i < kNumIterations; i++) {
     timer.Start();
@@ -418,7 +416,7 @@
         reinterpret_cast<Dart_NativeEntryResolver>(NativeResolver));
     EXPECT_VALID(lib);
   }
-  CompilerStats* stats = Isolate::Current()->compiler_stats();
+  CompilerStats* stats = thread->isolate()->compiler_stats();
   ASSERT(stats != NULL);
   stats->EnableBenchmark();
   Timer timer(true, "Compile all of dart2js benchmark");
@@ -547,7 +545,7 @@
   // Need to load the script into the dart: core library due to
   // the import of dart:_internal.
   TestCase::LoadCoreTestScript(kScriptChars, NULL);
-  Api::CheckAndFinalizePendingClasses(Isolate::Current());
+  Api::CheckAndFinalizePendingClasses(thread);
 
   // Write snapshot with object content.
   FullSnapshotWriter writer(&vm_isolate_snapshot_buffer,
@@ -584,7 +582,7 @@
   // Need to load the script into the dart: core library due to
   // the import of dart:_internal.
   TestCase::LoadCoreTestScript(kScriptChars, NULL);
-  Api::CheckAndFinalizePendingClasses(Isolate::Current());
+  Api::CheckAndFinalizePendingClasses(thread);
 
   // Write snapshot with object content.
   FullSnapshotWriter writer(&vm_isolate_snapshot_buffer,
@@ -625,7 +623,7 @@
       "\n";
   const intptr_t kLoopCount = 1000000;
   TestCase::LoadTestScript(kScriptChars, NULL);
-  Api::CheckAndFinalizePendingClasses(Isolate::Current());
+  Api::CheckAndFinalizePendingClasses(thread);
   Dart_Isolate isolate = Dart_CurrentIsolate();
   Timer timer(true, "Enter and Exit isolate");
   timer.Start();
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 85fcf52..7596920 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -30,6 +30,14 @@
 } bootstrap_lib_props;
 
 
+enum {
+  kPathsUriOffset = 0,
+  kPathsFileOffset = 1,
+  kPathsSourceOffset = 2,
+  kPathsEntryLength = 3
+};
+
+
 static bootstrap_lib_props bootstrap_libraries[] = {
   INIT_LIBRARY(ObjectStore::kCore,
                core,
@@ -86,7 +94,7 @@
 static RawString* GetLibrarySource(const Library& lib,
                                    const String& uri,
                                    bool patch) {
-  // First check if this is a valid boot strap library and find it's index
+  // First check if this is a valid bootstrap library and find it's index
   // in the 'bootstrap_libraries' table above.
   intptr_t index;
   const String& lib_uri = String::Handle(lib.url());
@@ -98,7 +106,7 @@
     }
   }
   if (bootstrap_libraries[index].index_ == ObjectStore::kNone) {
-    return String::null();  // Library is not a boot strap library.
+    return String::null();  // Library is not a bootstrap library.
   }
 
   // Try to read the source using the path specified for the uri.
@@ -109,38 +117,42 @@
     return String::null();  // No path mapping information exists for library.
   }
   const char* source_path = NULL;
-  for (intptr_t i = 0; source_paths[i] != NULL; i += 2) {
-    if (uri.Equals(source_paths[i])) {
-      source_path = source_paths[i + 1];
+  const char* source_data = NULL;
+  for (intptr_t i = 0; source_paths[i] != NULL; i += kPathsEntryLength) {
+    if (uri.Equals(source_paths[i + kPathsUriOffset])) {
+      source_path = source_paths[i + kPathsFileOffset];
+      source_data = source_paths[i + kPathsSourceOffset];
       break;
     }
   }
-  if (source_path == NULL) {
+  if ((source_path == NULL) && (source_data == NULL)) {
     return String::null();  // Uri does not exist in path mapping information.
   }
 
-  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
-  Dart_FileReadCallback file_read = Isolate::file_read_callback();
-  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
-  if (file_open == NULL || file_read == NULL || file_close == NULL) {
-    return String::null();  // File operations are not supported.
-  }
-
-  void* stream = (*file_open)(source_path, false);
-  if (stream == NULL) {
-    return String::null();
-  }
-
   const uint8_t* utf8_array = NULL;
   intptr_t file_length = -1;
-  (*file_read)(&utf8_array, &file_length, stream);
+
+  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
+  Dart_FileReadCallback file_read = Isolate::file_read_callback();
+  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
+  if ((file_open != NULL) && (file_read != NULL) && (file_close != NULL)) {
+    // Try to open and read the file.
+    void* stream = (*file_open)(source_path, false);
+    if (stream != NULL) {
+      (*file_read)(&utf8_array, &file_length, stream);
+      (*file_close)(stream);
+    }
+  }
   if (file_length == -1) {
-    return String::null();
+    if (source_data != NULL) {
+      file_length = strlen(source_data);
+      utf8_array = reinterpret_cast<const uint8_t*>(source_data);
+    } else {
+      return String::null();
+    }
   }
   ASSERT(utf8_array != NULL);
-
-  (*file_close)(stream);
-
+  ASSERT(file_length >= 0);
   return String::FromUTF8(utf8_array, file_length);
 }
 
@@ -169,7 +181,6 @@
                                   const Library& lib,
                                   const String& uri) {
   Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
   const String& part_source = String::Handle(
       zone, GetLibrarySource(lib, uri, false));
   const String& lib_uri = String::Handle(zone, lib.url());
@@ -189,7 +200,7 @@
   const Script& part_script = Script::Handle(
       zone, Script::New(part_uri, part_source, RawScript::kSourceTag));
   const Error& error = Error::Handle(zone, Compile(lib, part_script));
-  return Api::NewHandle(isolate, error.raw());
+  return Api::NewHandle(thread, error.raw());
 }
 
 
@@ -237,8 +248,8 @@
   const Array& strings = Array::Handle(zone, Array::New(3));
   strings.SetAt(0, patch_uri);
   strings.SetAt(1, Symbols::Slash());
-  for (intptr_t j = 0; patch_files[j] != NULL; j += 2) {
-    patch_file_uri = String::New(patch_files[j]);
+  for (intptr_t j = 0; patch_files[j] != NULL; j += kPathsEntryLength) {
+    patch_file_uri = String::New(patch_files[j + kPathsUriOffset]);
     source = GetLibrarySource(lib, patch_file_uri, true);
     if (source.IsNull()) {
       const String& message = String::Handle(
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index e416b7f..8803755 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -20,13 +20,13 @@
   V(Object_toString, 1)                                                        \
   V(Object_noSuchMethod, 6)                                                    \
   V(Object_runtimeType, 1)                                                     \
-  V(Object_instanceOf, 5)                                                      \
+  V(Object_instanceOf, 4)                                                      \
   V(Object_instanceOfNum, 2)                                                   \
   V(Object_instanceOfInt, 2)                                                   \
   V(Object_instanceOfSmi, 2)                                                   \
   V(Object_instanceOfDouble, 2)                                                \
   V(Object_instanceOfString, 2)                                                \
-  V(Object_as, 4)                                                              \
+  V(Object_as, 3)                                                              \
   V(Function_apply, 2)                                                         \
   V(FunctionImpl_equals, 2)                                                    \
   V(FunctionImpl_hashCode, 1)                                                  \
@@ -73,6 +73,7 @@
   V(Developer_lookupExtension, 1)                                              \
   V(Developer_registerExtension, 2)                                            \
   V(Developer_log, 8)                                                          \
+  V(Developer_postEvent, 2)                                                    \
   V(Double_getIsNegative, 1)                                                   \
   V(Double_getIsInfinite, 1)                                                   \
   V(Double_getIsNaN, 1)                                                        \
@@ -144,20 +145,24 @@
   V(Random_nextState, 1)                                                       \
   V(Random_setupSeed, 1)                                                       \
   V(Random_initialSeed, 0)                                                     \
-  V(DateNatives_currentTimeMillis, 0)                                          \
-  V(DateNatives_timeZoneName, 1)                                               \
-  V(DateNatives_timeZoneOffsetInSeconds, 1)                                    \
-  V(DateNatives_localTimeZoneAdjustmentInSeconds, 0)                           \
+  V(SecureRandom_getBytes, 1)                                                  \
+  V(DateTime_currentTimeMicros, 0)                                             \
+  V(DateTime_timeZoneName, 1)                                                  \
+  V(DateTime_timeZoneOffsetInSeconds, 1)                                       \
+  V(DateTime_localTimeZoneAdjustmentInSeconds, 0)                              \
   V(AssertionError_throwNew, 2)                                                \
   V(Async_rethrow, 2)                                                          \
+  V(StackTrace_current, 0)                                                     \
   V(TypeError_throwNew, 5)                                                     \
   V(FallThroughError_throwNew, 1)                                              \
   V(AbstractClassInstantiationError_throwNew, 2)                               \
   V(Stopwatch_now, 0)                                                          \
   V(Stopwatch_frequency, 0)                                                    \
+  V(Timeline_getIsolateNum, 0)                                                 \
   V(Timeline_getNextAsyncId, 0)                                                \
   V(Timeline_getTraceClock, 0)                                                 \
   V(Timeline_reportCompleteEvent, 5)                                           \
+  V(Timeline_reportInstantEvent, 4)                                            \
   V(Timeline_reportTaskEvent, 6)                                               \
   V(TypedData_Int8Array_new, 1)                                                \
   V(TypedData_Uint8Array_new, 1)                                               \
@@ -306,9 +311,10 @@
   V(Int32x4_setFlagZ, 2)                                                       \
   V(Int32x4_setFlagW, 2)                                                       \
   V(Int32x4_select, 3)                                                         \
-  V(Isolate_spawnFunction, 7)                                                  \
+  V(Isolate_spawnFunction, 10)                                                 \
   V(Isolate_spawnUri, 12)                                                      \
   V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0)                         \
+  V(Isolate_getCurrentRootUriStr, 0)                                           \
   V(Isolate_sendOOB, 2)                                                        \
   V(Mirrors_evalInLibraryWithPrivateKey, 2)                                    \
   V(Mirrors_makeLocalClassMirror, 1)                                           \
@@ -402,6 +408,8 @@
   V(VMService_OnExit, 0)                                                       \
   V(VMService_ListenStream, 1)                                                 \
   V(VMService_CancelStream, 1)                                                 \
+  V(VMService_RequestAssets, 0)                                                \
+  V(VMService_DecodeAssets, 1)                                                 \
 
 class BootstrapNatives : public AllStatic {
  public:
diff --git a/runtime/vm/cha.cc b/runtime/vm/cha.cc
index a2f50a3..667d598 100644
--- a/runtime/vm/cha.cc
+++ b/runtime/vm/cha.cc
@@ -62,14 +62,20 @@
 
 
 bool CHA::HasOverride(const Class& cls, const String& function_name) {
-  const GrowableObjectArray& cls_direct_subclasses =
-      GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses());
+  // Can't track dependencies for classes on the VM heap since those are
+  // read-only.
+  // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
+  // classes.
+  if (cls.InVMHeap()) return true;
+
   // Subclasses of Object are not tracked by CHA. Safely assume that overrides
   // exist.
   if (cls.IsObjectClass()) {
     return true;
   }
 
+  const GrowableObjectArray& cls_direct_subclasses =
+      GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses());
   if (cls_direct_subclasses.IsNull()) {
     return false;
   }
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 4d8178b..8ef3511 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -35,9 +35,12 @@
 // Only methods which owner classes where subclasses can be invalid.
 // TODO(srdjan): Be even more precise by recording the exact CHA optimization.
 static void RemoveCHAOptimizedCode(
+    const Class& subclass,
     const GrowableArray<intptr_t>& added_subclass_to_cids) {
   ASSERT(FLAG_use_cha_deopt);
-  if (added_subclass_to_cids.is_empty()) return;
+  if (added_subclass_to_cids.is_empty()) {
+    return;
+  }
   // Switch all functions' code to unoptimized.
   const ClassTable& class_table = *Isolate::Current()->class_table();
   Class& cls = Class::Handle();
@@ -45,7 +48,7 @@
     intptr_t cid = added_subclass_to_cids[i];
     cls = class_table.At(cid);
     ASSERT(!cls.IsNull());
-    cls.DisableCHAOptimizedCode();
+    cls.DisableCHAOptimizedCode(subclass);
   }
 }
 
@@ -1269,7 +1272,8 @@
   for (intptr_t i = 0; i < num_type_params; i++) {
     type_param ^= type_params.TypeAt(i);
     bound = type_param.bound();
-    if (bound.IsFinalized() || bound.IsBeingFinalized()) {
+    // Bound may be finalized, but not canonical yet.
+    if (bound.IsCanonical() || bound.IsBeingFinalized()) {
       // A bound involved in F-bounded quantification may form a cycle.
       continue;
     }
@@ -1314,7 +1318,7 @@
     field ^= array.At(i);
     type = field.type();
     type = FinalizeType(cls, type, kCanonicalize);
-    field.set_type(type);
+    field.SetFieldType(type);
     name = field.name();
     if (field.is_static()) {
       getter_name = Field::GetterSymbol(name);
@@ -2068,11 +2072,11 @@
 
 void ClassFinalizer::CreateForwardingConstructors(
     const Class& mixin_app,
+    const Class& mixin_cls,
     const GrowableObjectArray& cloned_funcs) {
   const String& mixin_name = String::Handle(mixin_app.Name());
   const Class& super_class = Class::Handle(mixin_app.SuperClass());
   const String& super_name = String::Handle(super_class.Name());
-  const Type& dynamic_type = Type::Handle(Type::DynamicType());
   const Array& functions = Array::Handle(super_class.functions());
   const intptr_t num_functions = functions.Length();
   Function& func = Function::Handle();
@@ -2091,6 +2095,13 @@
                   ctor_name.ToCString(),
                   clone_name.ToCString());
       }
+
+      // The owner of the forwarding constructor is the mixin application
+      // class. The source is the mixin class. The source may be needed
+      // to parse field initializer expressions in the mixin class.
+      const PatchClass& owner =
+          PatchClass::Handle(PatchClass::New(mixin_app, mixin_cls));
+
       const Function& clone = Function::Handle(
           Function::New(clone_name,
                         func.kind(),
@@ -2099,13 +2110,12 @@
                         false,  // Not abstract.
                         false,  // Not external.
                         false,  // Not native.
-                        mixin_app,
-                        mixin_app.token_pos()));
-
+                        owner,
+                        mixin_cls.token_pos()));
       clone.set_num_fixed_parameters(func.num_fixed_parameters());
       clone.SetNumOptionalParameters(func.NumOptionalParameters(),
                                      func.HasOptionalPositionalParameters());
-      clone.set_result_type(dynamic_type);
+      clone.set_result_type(Object::dynamic_type());
       clone.set_is_debuggable(false);
 
       const intptr_t num_parameters = func.NumParameters();
@@ -2117,7 +2127,7 @@
       // The parameter types of the cloned constructor are 'dynamic'.
       clone.set_parameter_types(Array::Handle(Array::New(num_parameters)));
       for (intptr_t n = 0; n < num_parameters; n++) {
-        clone.SetParameterTypeAt(n, dynamic_type);
+        clone.SetParameterTypeAt(n, Object::dynamic_type());
       }
       cloned_funcs.Add(clone);
     }
@@ -2151,7 +2161,7 @@
   const GrowableObjectArray& cloned_funcs =
       GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
 
-  CreateForwardingConstructors(cls, cloned_funcs);
+  CreateForwardingConstructors(cls, mixin_cls, cloned_funcs);
 
   Array& functions = Array::Handle(zone);
   Function& func = Function::Handle(zone);
@@ -2232,7 +2242,10 @@
   FinalizeTypeParameters(cls);  // May change super type.
   super_class = cls.SuperClass();
   ASSERT(super_class.IsNull() || super_class.is_type_finalized());
-  ResolveUpperBounds(cls);
+  // Only resolving rather than finalizing the upper bounds here would result in
+  // instantiated type parameters of the super type to temporarily have
+  // unfinalized bounds. It is more efficient to finalize them early.
+  FinalizeUpperBounds(cls);
   // Finalize super type.
   AbstractType& super_type = AbstractType::Handle(cls.super_type());
   if (!super_type.IsNull()) {
@@ -2345,6 +2358,7 @@
 void ClassFinalizer::FinalizeClass(const Class& cls) {
   Thread* thread = Thread::Current();
   HANDLESCOPE(thread);
+  ASSERT(cls.is_type_finalized());
   if (cls.is_finalized()) {
     return;
   }
@@ -2377,7 +2391,12 @@
       (cls.functions() == Object::empty_array().raw())) {
     const GrowableObjectArray& cloned_funcs =
         GrowableObjectArray::Handle(GrowableObjectArray::New());
-    CreateForwardingConstructors(cls, cloned_funcs);
+
+    const Class& mixin_app_class = Class::Handle(cls.SuperClass());
+    const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
+    const Class& mixin_cls = Class::Handle(mixin_type.type_class());
+
+    CreateForwardingConstructors(cls, mixin_cls, cloned_funcs);
     const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs));
     cls.SetFunctions(functions);
   }
@@ -2396,7 +2415,7 @@
     GrowableArray<intptr_t> cids;
     CollectFinalizedSuperClasses(cls, &cids);
     CollectImmediateSuperInterfaces(cls, &cids);
-    RemoveCHAOptimizedCode(cids);
+    RemoveCHAOptimizedCode(cls, cids);
   }
   if (cls.is_enum_class()) {
     AllocateEnumValues(cls);
@@ -2438,10 +2457,7 @@
     enum_value.SetField(index_field, ordinal_value);
     const char* error_msg = "";
     enum_value = enum_value.CheckAndCanonicalize(&error_msg);
-    if (enum_value.IsNull()) {
-      ReportError(enum_cls, enum_cls.token_pos(), "Failed finalizing values.");
-      UNREACHABLE();
-    }
+    ASSERT(!enum_value.IsNull());
     ASSERT(enum_value.IsCanonical());
     field.SetStaticValue(enum_value, true);
     field.RecordStore(enum_value);
@@ -2450,6 +2466,9 @@
     values_list.SetAt(ord, enum_value);
   }
   values_list.MakeImmutable();
+  const char* error_msg = NULL;
+  values_list ^= values_list.CheckAndCanonicalize(&error_msg);
+  ASSERT(!values_list.IsNull());
 }
 
 
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 0b8d7c5..3aa7c2c 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -123,6 +123,7 @@
   static void ApplyMixinMembers(const Class& cls);
   static void CreateForwardingConstructors(
       const Class& mixin_app,
+      const Class& mixin_cls,
       const GrowableObjectArray& cloned_funcs);
   static void CollectTypeArguments(const Class& cls,
                                    const Type& type,
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index ea37920..52786ee 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -95,6 +95,7 @@
 
 
 void ClassTable::Register(const Class& cls) {
+  ASSERT(Thread::Current()->IsMutatorThread());
   intptr_t index = cls.id();
   if (index != kIllegalCid) {
     ASSERT(index > 0);
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index ebe15cf..e24e186 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -102,6 +102,7 @@
       AddPlaceHolder();
     }
     list_[try_index].outer_try_index = outer_try_index;
+    ASSERT(list_[try_index].pc_offset == ExceptionHandlers::kInvalidPcOffset);
     list_[try_index].pc_offset = pc_offset;
     ASSERT(handler_types.IsZoneHandle());
     list_[try_index].handler_types = &handler_types;
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 60a3ab3..d7c92d7 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -13,7 +13,6 @@
 #include "vm/debugger.h"
 #include "vm/deopt_instructions.h"
 #include "vm/exceptions.h"
-#include "vm/intermediate_language.h"
 #include "vm/object_store.h"
 #include "vm/message.h"
 #include "vm/message_handler.h"
@@ -58,9 +57,12 @@
 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls");
 DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks.");
 
-DECLARE_FLAG(int, deoptimization_counter_threshold);
+DECLARE_FLAG(int, max_deoptimization_counter_threshold);
+DECLARE_FLAG(bool, enable_inlining_annotations);
 DECLARE_FLAG(bool, trace_compiler);
+DECLARE_FLAG(bool, trace_optimizing_compiler);
 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
+DECLARE_FLAG(int, max_polymorphic_checks);
 
 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement.");
 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement.");
@@ -337,11 +339,9 @@
 // case it contains just the result of the class subtype test, not including
 // the evaluation of type arguments.
 // This operation is currently very slow (lookup of code is not efficient yet).
-// 'instantiator' can be null, in which case inst_targ
 static void UpdateTypeTestCache(
     const Instance& instance,
     const AbstractType& type,
-    const Instance& instantiator,
     const TypeArguments& instantiator_type_arguments,
     const Bool& result,
     const SubtypeTestCache& new_cache) {
@@ -446,18 +446,16 @@
 // Tested instance may not be null, because the null test is inlined.
 // Arg0: instance being checked.
 // Arg1: type.
-// Arg2: instantiator (or null).
-// Arg3: type arguments of the instantiator of the type.
-// Arg4: SubtypeTestCache.
+// Arg2: type arguments of the instantiator of the type.
+// Arg3: SubtypeTestCache.
 // Return value: true or false, or may throw a type error in checked mode.
-DEFINE_RUNTIME_ENTRY(Instanceof, 5) {
+DEFINE_RUNTIME_ENTRY(Instanceof, 4) {
   const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0));
   const AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(1));
-  const Instance& instantiator = Instance::CheckedHandle(arguments.ArgAt(2));
   const TypeArguments& instantiator_type_arguments =
-      TypeArguments::CheckedHandle(arguments.ArgAt(3));
+      TypeArguments::CheckedHandle(arguments.ArgAt(2));
   const SubtypeTestCache& cache =
-      SubtypeTestCache::CheckedHandle(arguments.ArgAt(4));
+      SubtypeTestCache::CheckedHandle(arguments.ArgAt(3));
   ASSERT(type.IsFinalized());
   ASSERT(!type.IsDynamicType());  // No need to check assignment.
   ASSERT(!type.IsMalformed());  // Already checked in code generator.
@@ -481,8 +479,8 @@
         Symbols::Empty(), bound_error_message);
     UNREACHABLE();
   }
-  UpdateTypeTestCache(instance, type, instantiator,
-                      instantiator_type_arguments, result, cache);
+  UpdateTypeTestCache(
+      instance, type, instantiator_type_arguments, result, cache);
   arguments.SetReturn(result);
 }
 
@@ -491,22 +489,19 @@
 // can therefore be assigned.
 // Arg0: instance being assigned.
 // Arg1: type being assigned to.
-// Arg2: instantiator (or null).
-// Arg3: type arguments of the instantiator of the type being assigned to.
-// Arg4: name of variable being assigned to.
-// Arg5: SubtypeTestCache.
+// Arg2: type arguments of the instantiator of the type being assigned to.
+// Arg3: name of variable being assigned to.
+// Arg4: SubtypeTestCache.
 // Return value: instance if a subtype, otherwise throw a TypeError.
-DEFINE_RUNTIME_ENTRY(TypeCheck, 6) {
+DEFINE_RUNTIME_ENTRY(TypeCheck, 5) {
   const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0));
   const AbstractType& dst_type =
       AbstractType::CheckedHandle(arguments.ArgAt(1));
-  const Instance& dst_instantiator =
-      Instance::CheckedHandle(arguments.ArgAt(2));
   const TypeArguments& instantiator_type_arguments =
-      TypeArguments::CheckedHandle(arguments.ArgAt(3));
-  const String& dst_name = String::CheckedHandle(arguments.ArgAt(4));
+      TypeArguments::CheckedHandle(arguments.ArgAt(2));
+  const String& dst_name = String::CheckedHandle(arguments.ArgAt(3));
   const SubtypeTestCache& cache =
-      SubtypeTestCache::CheckedHandle(arguments.ArgAt(5));
+      SubtypeTestCache::CheckedHandle(arguments.ArgAt(4));
   ASSERT(!dst_type.IsDynamicType());  // No need to check assignment.
   ASSERT(!dst_type.IsMalformed());  // Already checked in code generator.
   ASSERT(!dst_type.IsMalbounded());  // Already checked in code generator.
@@ -564,9 +559,8 @@
                                         dst_name, bound_error_message);
     UNREACHABLE();
   }
-  UpdateTypeTestCache(src_instance, dst_type,
-                      dst_instantiator, instantiator_type_arguments,
-                      Bool::True(), cache);
+  UpdateTypeTestCache(
+      src_instance, dst_type, instantiator_type_arguments, Bool::True(), cache);
   arguments.SetReturn(src_instance);
 }
 
@@ -683,7 +677,7 @@
                                  target_code);
   caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code);
   if (FLAG_trace_patching) {
-    OS::PrintErr("PatchStaticCall: patching caller pc %#" Px ""
+    THR_Print("PatchStaticCall: patching caller pc %#" Px ""
         " to '%s' new entry point %#" Px " (%s)\n",
         caller_frame->pc(),
         target_function.ToFullyQualifiedCString(),
@@ -779,11 +773,9 @@
 // Handle other invocations (implicit closures, noSuchMethod).
 RawFunction* InlineCacheMissHelper(
     const Instance& receiver,
-    const ICData& ic_data) {
-  const Array& args_descriptor = Array::Handle(ic_data.arguments_descriptor());
-
+    const Array& args_descriptor,
+    const String& target_name) {
   const Class& receiver_class = Class::Handle(receiver.clazz());
-  const String& target_name = String::Handle(ic_data.target_name());
 
   Function& result = Function::Handle();
   if (!ResolveCallThroughGetter(receiver,
@@ -828,7 +820,12 @@
                    String::Handle(ic_data.target_name()).ToCString(),
                    receiver.ToCString());
     }
-    target_function = InlineCacheMissHelper(receiver, ic_data);
+    const Array& args_descriptor =
+        Array::Handle(ic_data.arguments_descriptor());
+    const String& target_name = String::Handle(ic_data.target_name());
+    target_function = InlineCacheMissHelper(receiver,
+                                            args_descriptor,
+                                            target_name);
   }
   if (target_function.IsNull()) {
     ASSERT(!FLAG_lazy_dispatchers);
@@ -1008,18 +1005,21 @@
 
 // Handle a miss of a megamorphic cache.
 //   Arg0: Receiver.
-//   Arg1: ICData object.
+//   Arg1: ICData or MegamorphicCache.
 //   Arg2: Arguments descriptor array.
-
 //   Returns: target function to call.
 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
-  const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
-  const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
-  const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2));
-  const String& name = String::Handle(ic_data.target_name());
-  const MegamorphicCache& cache = MegamorphicCache::Handle(
-      MegamorphicCacheTable::Lookup(isolate, name, descriptor));
-  Class& cls = Class::Handle(receiver.clazz());
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+  const Object& ic_data_or_cache = Object::Handle(zone, arguments.ArgAt(1));
+  const Array& descriptor = Array::CheckedHandle(zone, arguments.ArgAt(2));
+  String& name = String::Handle(zone);
+  if (ic_data_or_cache.IsICData()) {
+    name = ICData::Cast(ic_data_or_cache).target_name();
+  } else {
+    ASSERT(ic_data_or_cache.IsMegamorphicCache());
+    name = MegamorphicCache::Cast(ic_data_or_cache).target_name();
+  }
+  Class& cls = Class::Handle(zone, receiver.clazz());
   ASSERT(!cls.IsNull());
   if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) {
     OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n",
@@ -1027,41 +1027,70 @@
   }
 
   ArgumentsDescriptor args_desc(descriptor);
-  Function& target_function = Function::Handle(
+  Function& target_function = Function::Handle(zone,
       Resolver::ResolveDynamicForReceiverClass(cls,
                                                name,
                                                args_desc));
   if (target_function.IsNull()) {
-    target_function = InlineCacheMissHelper(receiver, ic_data);
+    target_function = InlineCacheMissHelper(receiver, descriptor, name);
   }
   if (target_function.IsNull()) {
     ASSERT(!FLAG_lazy_dispatchers);
     arguments.SetReturn(target_function);
     return;
   }
-  // Insert function found into cache and return it.
-  cache.EnsureCapacity();
-  const Smi& class_id = Smi::Handle(Smi::New(cls.id()));
-  cache.Insert(class_id, target_function);
+
+  if (ic_data_or_cache.IsICData()) {
+    const ICData& ic_data = ICData::Cast(ic_data_or_cache);
+    ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
+    if (ic_data.NumberOfChecks() > FLAG_max_polymorphic_checks) {
+      // Switch to megamorphic call.
+      const MegamorphicCache& cache = MegamorphicCache::Handle(zone,
+          MegamorphicCacheTable::Lookup(isolate, name, descriptor));
+      DartFrameIterator iterator;
+      StackFrame* miss_function_frame = iterator.NextFrame();
+      ASSERT(miss_function_frame->IsDartFrame());
+      StackFrame* caller_frame = iterator.NextFrame();
+      ASSERT(caller_frame->IsDartFrame());
+      const Code& code = Code::Handle(zone, caller_frame->LookupDartCode());
+      const Code& stub =
+          Code::Handle(zone, StubCode::MegamorphicLookup_entry()->code());
+      CodePatcher::PatchSwitchableCallAt(caller_frame->pc(),
+                                         code, ic_data, cache, stub);
+    }
+  } else {
+    const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache);
+    // Insert function found into cache and return it.
+    cache.EnsureCapacity();
+    const Smi& class_id = Smi::Handle(zone, Smi::New(cls.id()));
+    cache.Insert(class_id, target_function);
+  }
   arguments.SetReturn(target_function);
 }
 
 
 // Invoke appropriate noSuchMethod or closure from getter.
 // Arg0: receiver
-// Arg1: IC data
+// Arg1: ICData or MegamorphicCache
 // Arg2: arguments descriptor array
 // Arg3: arguments array
 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) {
   ASSERT(!FLAG_lazy_dispatchers);
-  const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
-  const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
-  const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(2));
-  const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3));
-  const String& target_name = String::Handle(ic_data.target_name());
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+  const Object& ic_data_or_cache = Object::Handle(zone, arguments.ArgAt(1));
+  const Array& orig_arguments_desc =
+      Array::CheckedHandle(zone, arguments.ArgAt(2));
+  const Array& orig_arguments = Array::CheckedHandle(zone, arguments.ArgAt(3));
+  String& target_name = String::Handle(zone);
+  if (ic_data_or_cache.IsICData()) {
+    target_name = ICData::Cast(ic_data_or_cache).target_name();
+  } else {
+    ASSERT(ic_data_or_cache.IsMegamorphicCache());
+    target_name = MegamorphicCache::Cast(ic_data_or_cache).target_name();
+  }
 
-  Class& cls = Class::Handle(receiver.clazz());
-  Function& function = Function::Handle();
+  Class& cls = Class::Handle(zone, receiver.clazz());
+  Function& function = Function::Handle(zone);
 
   // Dart distinguishes getters and regular methods and allows their calls
   // to mix with conversions, and its selectors are independent of arity. So do
@@ -1069,7 +1098,7 @@
   // need for conversion, or there really is no such method.
 
 #define NO_SUCH_METHOD()                                                       \
-  const Object& result = Object::Handle(                                       \
+  const Object& result = Object::Handle(zone,                                  \
       DartEntry::InvokeNoSuchMethod(receiver,                                  \
                                     target_name,                               \
                                     orig_arguments,                            \
@@ -1079,9 +1108,9 @@
 
 #define CLOSURIZE(some_function)                                               \
   const Function& closure_function =                                           \
-      Function::Handle(some_function.ImplicitClosureFunction());               \
+      Function::Handle(zone, some_function.ImplicitClosureFunction());         \
   const Object& result =                                                       \
-      Object::Handle(closure_function.ImplicitInstanceClosure(receiver));      \
+      Object::Handle(zone, closure_function.ImplicitInstanceClosure(receiver));\
   arguments.SetReturn(result);                                                 \
 
   const bool is_getter = Field::IsGetterName(target_name);
@@ -1091,7 +1120,7 @@
     // encountered first on the inheritance chain. Or,
     // o#foo= (o.get:#set:foo) failed, closurize o.foo= if it exists.
     String& field_name =
-        String::Handle(Field::NameFromGetter(target_name));
+        String::Handle(zone, Field::NameFromGetter(target_name));
 
     const bool is_extractor = field_name.CharAt(0) == '#';
     if (is_extractor) {
@@ -1143,14 +1172,15 @@
       // call method and with lazy dispatchers the field-invocation-dispatcher
       // would perform the closure call.
       const Object& result =
-        Object::Handle(DartEntry::InvokeClosure(orig_arguments,
-                                                orig_arguments_desc));
+        Object::Handle(zone, DartEntry::InvokeClosure(orig_arguments,
+                                                      orig_arguments_desc));
       CheckResultError(result);
       arguments.SetReturn(result);
       return;
     }
 
-    const String& getter_name = String::Handle(Field::GetterName(target_name));
+    const String& getter_name =
+        String::Handle(zone, Field::GetterName(target_name));
     while (!cls.IsNull()) {
       function ^= cls.LookupDynamicFunction(target_name);
       if (!function.IsNull()) {
@@ -1163,15 +1193,15 @@
         const Array& getter_arguments = Array::Handle(Array::New(1));
         getter_arguments.SetAt(0, receiver);
         const Object& getter_result =
-          Object::Handle(DartEntry::InvokeFunction(function,
-                                                   getter_arguments));
+          Object::Handle(zone, DartEntry::InvokeFunction(function,
+                                                         getter_arguments));
         CheckResultError(getter_result);
         ASSERT(getter_result.IsNull() || getter_result.IsInstance());
 
         orig_arguments.SetAt(0, getter_result);
         const Object& call_result =
-          Object::Handle(DartEntry::InvokeClosure(orig_arguments,
-                                                  orig_arguments_desc));
+          Object::Handle(zone, DartEntry::InvokeClosure(orig_arguments,
+                                                        orig_arguments_desc));
         CheckResultError(call_result);
         arguments.SetReturn(call_result);
         return;
@@ -1214,27 +1244,29 @@
 }
 
 
-static bool CanOptimizeFunction(const Function& function, Isolate* isolate) {
-  const intptr_t kLowInvocationCount = -100000000;
+static bool CanOptimizeFunction(const Function& function, Thread* thread) {
+  Isolate* isolate = thread->isolate();
   if (isolate->debugger()->IsStepping() ||
-      isolate->debugger()->HasBreakpoint(function)) {
+      isolate->debugger()->HasBreakpoint(function, thread->zone())) {
     // We cannot set breakpoints and single step in optimized code,
     // so do not optimize the function.
     function.set_usage_counter(0);
     return false;
   }
   if (function.deoptimization_counter() >=
-      FLAG_deoptimization_counter_threshold) {
+      FLAG_max_deoptimization_counter_threshold) {
     if (FLAG_trace_failed_optimization_attempts ||
         FLAG_stop_on_excessive_deoptimization) {
-      OS::PrintErr("Too Many Deoptimizations: %s\n",
+      THR_Print("Too many deoptimizations: %s\n",
           function.ToFullyQualifiedCString());
       if (FLAG_stop_on_excessive_deoptimization) {
         FATAL("Stop on excessive deoptimization");
       }
     }
-    // TODO(srdjan): Investigate excessive deoptimization.
-    function.set_usage_counter(kLowInvocationCount);
+    // The function will not be optimized any longer. This situation can occur
+    // mostly with small optimization counter thresholds.
+    function.SetIsOptimizable(false);
+    function.set_usage_counter(INT_MIN);
     return false;
   }
   if (FLAG_optimization_filter != NULL) {
@@ -1256,16 +1288,17 @@
     }
     delete[] filter;
     if (!found) {
-      function.set_usage_counter(kLowInvocationCount);
+      function.set_usage_counter(INT_MIN);
       return false;
     }
   }
   if (!function.IsOptimizable()) {
+    // Huge methods (code size above --huge_method_cutoff_in_code_size) become
+    // non-optimizable only after the code has been generated.
     if (FLAG_trace_failed_optimization_attempts) {
-      OS::PrintErr("Not Optimizable: %s\n", function.ToFullyQualifiedCString());
+      THR_Print("Not optimizable: %s\n", function.ToFullyQualifiedCString());
     }
-    // TODO(5442338): Abort as this should not happen.
-    function.set_usage_counter(kLowInvocationCount);
+    function.set_usage_counter(INT_MIN);
     return false;
   }
   return true;
@@ -1378,7 +1411,7 @@
     ASSERT(function.HasCode());
     // Don't do OSR on intrinsified functions: The intrinsic code expects to be
     // called like a regular function and can't be entered via OSR.
-    if (!CanOptimizeFunction(function, isolate) || function.is_intrinsic()) {
+    if (!CanOptimizeFunction(function, thread) || function.is_intrinsic()) {
       return;
     }
 
@@ -1387,7 +1420,7 @@
     ASSERT(function.unoptimized_code() != Object::null());
     intptr_t osr_id =
         Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
-    ASSERT(osr_id != Thread::kNoDeoptId);
+    ASSERT(osr_id != Compiler::kNoOSRDeoptId);
     if (FLAG_trace_osr) {
       OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n",
                 function.ToFullyQualifiedCString(),
@@ -1447,19 +1480,28 @@
   ASSERT(!function.IsNull());
   ASSERT(function.HasCode());
 
-  if (CanOptimizeFunction(function, isolate)) {
-    // Reset usage counter for reoptimization before calling optimizer to
-    // prevent recursive triggering of function optimization.
-    function.set_usage_counter(0);
+  if (CanOptimizeFunction(function, thread)) {
     if (FLAG_background_compilation) {
-      BackgroundCompiler::EnsureInit(isolate);
+      if (FLAG_enable_inlining_annotations) {
+        FATAL("Cannot enable inlining annotations and background compilation");
+      }
+      // Reduce the chance of triggering optimization while the function is
+      // being optimized in the background. INT_MIN should ensure that it takes
+      // long time to trigger optimization.
+      // Note that the background compilation queue rejects duplicate entries.
+      function.set_usage_counter(INT_MIN);
+      BackgroundCompiler::EnsureInit(thread);
       ASSERT(isolate->background_compiler() != NULL);
       isolate->background_compiler()->CompileOptimized(function);
       // Continue in the same code.
       arguments.SetReturn(Code::Handle(zone, function.CurrentCode()));
       return;
     }
-    if (FLAG_trace_compiler) {
+
+    // Reset usage counter for reoptimization before calling optimizer to
+    // prevent recursive triggering of function optimization.
+    function.set_usage_counter(0);
+    if (FLAG_trace_compiler || FLAG_trace_optimizing_compiler) {
       if (function.HasOptimizedCode()) {
         THR_Print("ReCompiling function: '%s' \n",
                   function.ToFullyQualifiedCString());
@@ -1667,6 +1709,9 @@
 
 // Copies saved registers and caller's frame into temporary buffers.
 // Returns the stack size of unoptimized frame.
+// The calling code must be optimized, but its function may not have
+// have optimized code if the code is OSR code, or if the code was invalidated
+// through class loading/finalization or field guard.
 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
                           2,
                           uword saved_registers_address,
@@ -1688,6 +1733,16 @@
   ASSERT(caller_frame != NULL);
   const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
   ASSERT(optimized_code.is_optimized());
+  const Function& top_function =
+      Function::Handle(thread->zone(), optimized_code.function());
+  const bool deoptimizing_code = top_function.HasOptimizedCode();
+  if (FLAG_trace_deoptimization) {
+    const Function& function = Function::Handle(optimized_code.function());
+    THR_Print("== Deoptimizing code for '%s', %s, %s\n",
+       function.ToFullyQualifiedCString(),
+       deoptimizing_code ? "code & frame" : "frame",
+       is_lazy_deopt ? "lazy-deopt" : "");
+  }
 
   // Copy the saved registers from the stack.
   fpu_register_t* fpu_registers;
@@ -1701,7 +1756,8 @@
                        DeoptContext::kDestIsOriginalFrame,
                        fpu_registers,
                        cpu_registers,
-                       is_lazy_deopt != 0);
+                       is_lazy_deopt != 0,
+                       deoptimizing_code);
   isolate->set_deopt_context(deopt_context);
 
   // Stack size (FP - SP) in bytes.
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index aac9311..bea6025 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -20,7 +20,7 @@
 
 namespace dart {
 
-static const intptr_t kPos = Scanner::kNoSourcePos;
+static const intptr_t kPos = 0;
 
 
 CODEGEN_TEST_GENERATE(SimpleReturnCodegen, test) {
@@ -192,58 +192,6 @@
 CODEGEN_TEST_RUN(BinaryOpCodegen, Double::New(2.5));
 
 
-// Tested Dart code:
-//   int dec(int a, [int b = 1]) native: "TestSmiSub";
-// The native entry TestSmiSub implements dec natively.
-CODEGEN_TEST_GENERATE(NativeDecCodegen, test) {
-  // A NativeBodyNode, preceded by an EnterNode and followed by a ReturnNode,
-  // implements the body of a native Dart function. Let's take this native
-  // function as an example: int dec(int a, int b = 1) native;
-  // Since this function has an optional parameter, its prologue will copy
-  // incoming parameters to locals.
-  SequenceNode* node_seq = test->node_sequence();
-  const int num_fixed_params = 1;
-  const int num_opt_params = 1;
-  const int num_params = num_fixed_params + num_opt_params;
-  LocalScope* local_scope = node_seq->scope();
-  local_scope->InsertParameterAt(0, NewTestLocalVariable("a"));
-  local_scope->InsertParameterAt(1, NewTestLocalVariable("b"));
-  ASSERT(local_scope->num_variables() == num_params);
-  ZoneGrowableArray<const Instance*>* default_values =
-      new ZoneGrowableArray<const Instance*>(num_opt_params);
-  default_values->Add(&Smi::ZoneHandle(Smi::New(1)));  // b = 1.
-  test->set_default_parameter_values(default_values);
-  const Function& function = test->function();
-  function.set_is_native(true);
-  function.set_num_fixed_parameters(num_fixed_params);
-  function.SetNumOptionalParameters(num_opt_params, true);
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestSmiSub"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestSmiSub);
-  node_seq->Add(
-      new ReturnNode(kPos,
-                     new NativeBodyNode(kPos,
-                                        function,
-                                        native_name,
-                                        native_function,
-                                        local_scope,
-                                        false /* not bootstrap native */)));
-}
-
-
-// Tested Dart code:
-//   return dec(5);
-CODEGEN_TEST2_GENERATE(StaticDecCallCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(StaticDecCallCodegen, NativeDecCodegen, Smi::New(4))
-
-
 CODEGEN_TEST_GENERATE(SmiUnaryOpCodegen, test) {
   SequenceNode* node_seq = test->node_sequence();
   LiteralNode* a = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(12)));
@@ -368,159 +316,6 @@
 CODEGEN_TEST_RUN(InstanceCallCodegen, Smi::New(42))
 
 
-// Tested Dart code:
-//   int sum(int a, int b,
-//           [int c = 10, int d = 21, int e = -32]) native: "TestSmiSum";
-// The native entry TestSmiSum implements sum natively.
-CODEGEN_TEST_GENERATE(NativeSumCodegen, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  const int num_fixed_params = 2;
-  const int num_opt_params = 3;
-  const int num_params = num_fixed_params + num_opt_params;
-  LocalScope* local_scope = node_seq->scope();
-  local_scope->InsertParameterAt(0, NewTestLocalVariable("a"));
-  local_scope->InsertParameterAt(1, NewTestLocalVariable("b"));
-  local_scope->InsertParameterAt(2, NewTestLocalVariable("c"));
-  local_scope->InsertParameterAt(3, NewTestLocalVariable("d"));
-  local_scope->InsertParameterAt(4, NewTestLocalVariable("e"));
-  ASSERT(local_scope->num_variables() == num_params);
-  ZoneGrowableArray<const Instance*>* default_values =
-      new ZoneGrowableArray<const Instance*>(num_opt_params);
-  default_values->Add(&Smi::ZoneHandle(Smi::New(10)));
-  default_values->Add(&Smi::ZoneHandle(Smi::New(21)));
-  default_values->Add(&Smi::ZoneHandle(Smi::New(-32)));
-  test->set_default_parameter_values(default_values);
-  const Function& function = test->function();
-  function.set_is_native(true);
-  function.set_num_fixed_parameters(num_fixed_params);
-  function.SetNumOptionalParameters(num_opt_params, true);
-  function.set_parameter_types(Array::Handle(Array::New(num_params)));
-  function.set_parameter_names(Array::Handle(Array::New(num_params)));
-  const Type& param_type = Type::Handle(Type::DynamicType());
-  for (int i = 0; i < num_params; i++) {
-    function.SetParameterTypeAt(i, param_type);
-  }
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestSmiSum"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestSmiSum);
-  node_seq->Add(
-      new ReturnNode(kPos,
-                     new NativeBodyNode(kPos,
-                                        function,
-                                        native_name,
-                                        native_function,
-                                        local_scope,
-                                        false /* Not bootstrap native */)));
-}
-
-
-// Tested Dart code, calling function sum declared above:
-//   return sum(1, 3);
-// Optional arguments are not passed and hence are set to their default values.
-CODEGEN_TEST2_GENERATE(StaticSumCallNoOptCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(StaticSumCallNoOptCodegen,
-                  NativeSumCodegen,
-                  Smi::New(1 + 3 + 10 + 21 - 32))
-
-
-// Tested Dart code, calling function sum declared above:
-//   return sum(1, 3, 5);
-// Only one out of three optional arguments is passed in; the second and third
-// arguments are hence set to their default values.
-CODEGEN_TEST2_GENERATE(StaticSumCallOneOptCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(StaticSumCallOneOptCodegen,
-                  NativeSumCodegen,
-                  Smi::New(1 + 3 + 5 + 21 - 32))
-
-
-// Tested Dart code, calling function sum declared above:
-//   return sum(0, 1, 1, 2, 3);
-// Optional arguments are passed in.
-CODEGEN_TEST2_GENERATE(StaticSumCallTenFiboCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(0))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2))));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(
-    StaticSumCallTenFiboCodegen,
-    NativeSumCodegen,
-    Smi::New(0 + 1 + 1 + 2 + 3))
-
-
-// Tested Dart code:
-//   int sum(a, b, c) native: "TestNonNullSmiSum";
-// The native entry TestNonNullSmiSum implements sum natively.
-CODEGEN_TEST_GENERATE(NativeNonNullSumCodegen, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  const int num_params = 3;
-  LocalScope* local_scope = node_seq->scope();
-  local_scope->InsertParameterAt(0, NewTestLocalVariable("a"));
-  local_scope->InsertParameterAt(1, NewTestLocalVariable("b"));
-  local_scope->InsertParameterAt(2, NewTestLocalVariable("c"));
-  ASSERT(local_scope->num_variables() == num_params);
-  const Function& function = test->function();
-  function.set_is_native(true);
-  function.set_num_fixed_parameters(num_params);
-  ASSERT(!function.HasOptionalParameters());
-  function.set_parameter_types(Array::Handle(Array::New(num_params)));
-  function.set_parameter_names(Array::Handle(Array::New(num_params)));
-  const Type& param_type = Type::Handle(Type::DynamicType());
-  for (int i = 0; i < num_params; i++) {
-    function.SetParameterTypeAt(i, param_type);
-  }
-  const String& native_name =
-      String::ZoneHandle(Symbols::New("TestNonNullSmiSum"));
-  NativeFunction native_function =
-      reinterpret_cast<NativeFunction>(TestNonNullSmiSum);
-  node_seq->Add(
-      new ReturnNode(kPos,
-                     new NativeBodyNode(kPos,
-                                        function,
-                                        native_name,
-                                        native_function,
-                                        local_scope,
-                                        false /* Not bootstrap native */)));
-}
-
-
-// Tested Dart code, calling function sum declared above:
-//   return sum(1, null, 3);
-CODEGEN_TEST2_GENERATE(StaticNonNullSumCallCodegen, function, test) {
-  SequenceNode* node_seq = test->node_sequence();
-  ArgumentListNode* arguments = new ArgumentListNode(kPos);
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
-  arguments->Add(new LiteralNode(kPos, Instance::ZoneHandle()));
-  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
-  node_seq->Add(new ReturnNode(kPos,
-                               new StaticCallNode(kPos, function, arguments)));
-}
-CODEGEN_TEST2_RUN(StaticNonNullSumCallCodegen,
-                  NativeNonNullSumCodegen,
-                  Smi::New(1 + 3))
-
-
 // Test allocation of dart objects.
 CODEGEN_TEST_GENERATE(AllocateNewObjectCodegen, test) {
   const char* kScriptChars =
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index dc27168..ebcdeaa 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -74,6 +74,12 @@
                                      const Code& code,
                                      const Code& new_target);
 
+  static void PatchSwitchableCallAt(uword return_address,
+                                    const Code& code,
+                                    const ICData& ic_data,
+                                    const MegamorphicCache& new_cache,
+                                    const Code& lookup_stub);
+
   static RawCode* GetNativeCallAt(uword return_address,
                                   const Code& code,
                                   NativeFunction* target);
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index a9d5a10..7e0e8ea 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -69,6 +69,19 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, code);
+  ASSERT(call.cache() == ic_data.raw());
+  call.SetLookupStub(lookup_stub);
+  call.SetCache(cache);
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/code_patcher_arm64.cc b/runtime/vm/code_patcher_arm64.cc
index 4e0bbee..53f26ed 100644
--- a/runtime/vm/code_patcher_arm64.cc
+++ b/runtime/vm/code_patcher_arm64.cc
@@ -109,6 +109,19 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, code);
+  ASSERT(call.cache() == ic_data.raw());
+  call.SetLookupStub(lookup_stub);
+  call.SetCache(cache);
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index 525b3db..f9a3f42 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -42,7 +42,7 @@
   // Code accessing pp is generated, but not executed. Uninitialized pp is OK.
   __ set_constant_pool_allowed(true);
 
-  __ LoadObject(R5, ic_data);
+  __ LoadObject(R9, ic_data);
   __ BranchLinkPatchable(*StubCode::OneArgCheckInlineCache_entry());
   __ Ret();
 }
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index d0a4f07..90f1876 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -211,6 +211,16 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  // Switchable instance calls only generated for precompilation.
+  UNREACHABLE();
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/code_patcher_mips.cc b/runtime/vm/code_patcher_mips.cc
index 09b06a2..4c8ab99 100644
--- a/runtime/vm/code_patcher_mips.cc
+++ b/runtime/vm/code_patcher_mips.cc
@@ -68,6 +68,19 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, code);
+  ASSERT(call.cache() == ic_data.raw());
+  call.SetLookupStub(lookup_stub);
+  call.SetCache(cache);
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index d0ac739..2e6ec02 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -184,6 +184,64 @@
 };
 
 
+// Instance call that can switch from an IC call to a megamorphic call
+//   load ICData             load MegamorphicCache
+//   call ICLookup stub  ->  call MegamorphicLookup stub
+//   call target             call target
+class SwitchableCall : public ValueObject {
+ public:
+  SwitchableCall(uword return_address, const Code& code)
+      : start_(return_address - kCallPatternSize),
+        object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
+    ASSERT(IsValid());
+  }
+
+  static const int kCallPatternSize = 24;
+
+  bool IsValid() const {
+    static int16_t pattern[kCallPatternSize] = {
+      0x49, 0x8b, 0x9f, -1, -1, -1, -1,  // movq rbx, [PP + cache_offs]
+      0x4d, 0x8b, 0xa7, -1, -1, -1, -1,  // movq r12, [PP + code_offs]
+      0x4d, 0x8b, 0x5c, 0x24, 0x07,      // movq r11, [r12 + entrypoint_off]
+      0x41, 0xff, 0xd3,                  // call r11
+      0xff, 0xd1,                        // call rcx
+    };
+    return MatchesPattern(start_, pattern, kCallPatternSize);
+  }
+
+  intptr_t cache_index() const {
+    return IndexFromPPLoad(start_ + 3);
+  }
+  intptr_t lookup_stub_index() const {
+    return IndexFromPPLoad(start_ + 10);
+  }
+
+  RawObject* cache() const {
+    return object_pool_.ObjectAt(cache_index());
+  }
+
+  void SetCache(const MegamorphicCache& cache) const {
+    ASSERT(Object::Handle(object_pool_.ObjectAt(cache_index())).IsICData());
+    object_pool_.SetObjectAt(cache_index(), cache);
+    // No need to flush the instruction cache, since the code is not modified.
+  }
+
+  void SetLookupStub(const Code& lookup_stub) const {
+    ASSERT(Object::Handle(object_pool_.ObjectAt(lookup_stub_index())).IsCode());
+    object_pool_.SetObjectAt(lookup_stub_index(), lookup_stub);
+    // No need to flush the instruction cache, since the code is not modified.
+  }
+
+ protected:
+  uword start_;
+  const ObjectPool& object_pool_;
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(SwitchableCall);
+};
+
+
+
 RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
                                             const Code& code) {
   ASSERT(code.ContainsInstructionAt(return_address));
@@ -248,6 +306,19 @@
 }
 
 
+void CodePatcher::PatchSwitchableCallAt(uword return_address,
+                                        const Code& code,
+                                        const ICData& ic_data,
+                                        const MegamorphicCache& cache,
+                                        const Code& lookup_stub) {
+  ASSERT(code.ContainsInstructionAt(return_address));
+  SwitchableCall call(return_address, code);
+  ASSERT(call.cache() == ic_data.raw());
+  call.SetLookupStub(lookup_stub);
+  call.SetCache(cache);
+}
+
+
 void CodePatcher::PatchNativeCallAt(uword return_address,
                                     const Code& code,
                                     NativeFunction target,
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 5d683ce..70d1ac6 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -35,6 +35,7 @@
 #include "vm/scanner.h"
 #include "vm/symbols.h"
 #include "vm/tags.h"
+#include "vm/thread_registry.h"
 #include "vm/timer.h"
 
 namespace dart {
@@ -45,7 +46,7 @@
     "Do common subexpression elimination.");
 DEFINE_FLAG(bool, constant_propagation, true,
     "Do conditional constant propagation/unreachable code elimination.");
-DEFINE_FLAG(int, deoptimization_counter_threshold, 16,
+DEFINE_FLAG(int, max_deoptimization_counter_threshold, 16,
     "How many times we allow deoptimization before we disallow optimization.");
 DEFINE_FLAG(bool, disassemble, false, "Disassemble dart code.");
 DEFINE_FLAG(bool, disassemble_optimized, false, "Disassemble optimized code.");
@@ -59,12 +60,17 @@
 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis");
 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering.");
 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations.");
+DEFINE_FLAG(bool, trace_optimizing_compiler, false,
+    "Trace only optimizing compiler operations.");
 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler.");
 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining");
 DEFINE_FLAG(bool, verify_compiler, false,
     "Enable compiler verification assertions");
+DEFINE_FLAG(int, max_speculative_inlining_attempts, 1,
+    "Max number of attempts with speculative inlining (precompilation only)");
 
 DECLARE_FLAG(bool, background_compilation);
+DECLARE_FLAG(bool, huge_method_cutoff_in_code_size);
 DECLARE_FLAG(bool, load_deferred_eagerly);
 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
 DECLARE_FLAG(bool, trace_inlining_intervals);
@@ -74,6 +80,7 @@
 bool Compiler::always_optimize_ = false;
 bool Compiler::allow_recompilation_ = true;
 
+#ifndef DART_PRECOMPILED
 
 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove
 // separate helpers functions & `optimizing` args.
@@ -184,6 +191,12 @@
 }
 
 
+bool Compiler::IsBackgroundCompilation() {
+  // For now: compilation in non mutator thread is the background compoilation.
+  return !Thread::Current()->IsMutatorThread();
+}
+
+
 RawError* Compiler::Compile(const Library& library, const Script& script) {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
@@ -249,7 +262,7 @@
   // Add patch classes if they exist to the parse list if they have not already
   // been parsed and patched. Mark the class as parsed so that we don't
   // recursively add it back into the list.
-  parse_class ^= cls.patch_class();
+  parse_class ^= cls.GetPatchClass();
   if (!parse_class.IsNull()) {
     if (!parse_class.is_finalized() && !parse_class.is_marked_for_parsing()) {
       patch_list->Add(parse_class);
@@ -260,6 +273,7 @@
 
 
 RawError* Compiler::CompileClass(const Class& cls) {
+  ASSERT(Thread::Current()->IsMutatorThread());
   // If class is a top level class it is already parsed.
   if (cls.IsTopLevel()) {
     return Error::null();
@@ -298,6 +312,14 @@
   // also allows us to reset the marked_for_parsing state in case we see an
   // error.
   VMTagScope tagScope(thread, VMTag::kCompileClassTagId);
+  TimelineDurationScope tds(thread,
+                            thread->isolate()->GetCompilerStream(),
+                            "CompileClass");
+  if (tds.enabled()) {
+    tds.SetNumArguments(1);
+    tds.CopyArgument(0, "class", cls.ToCString());
+  }
+
   GrowableHandlePtrArray<const Class> parse_list(thread->zone(), 4);
   GrowableHandlePtrArray<const Class> patch_list(thread->zone(), 4);
 
@@ -305,7 +327,7 @@
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     if (FLAG_trace_compiler) {
-      THR_Print("Compiling Class %s '%s'\n", "", cls.ToCString());
+      THR_Print("Compiling Class '%s'\n", cls.ToCString());
     }
 
     // Add the primary class which needs to be parsed to the parse list.
@@ -377,21 +399,216 @@
 }
 
 
+class CompileParsedFunctionHelper : public ValueObject {
+ public:
+  CompileParsedFunctionHelper(ParsedFunction* parsed_function,
+                              bool optimized,
+                              intptr_t osr_id)
+      : parsed_function_(parsed_function),
+        optimized_(optimized),
+        osr_id_(osr_id),
+        thread_(Thread::Current()),
+        cha_invalidation_gen_at_start_(isolate()->cha_invalidation_gen()),
+        field_invalidation_gen_at_start_(isolate()->field_invalidation_gen()),
+        prefix_invalidation_gen_at_start_(
+            isolate()->prefix_invalidation_gen()) {
+  }
+
+  bool Compile(CompilationPipeline* pipeline);
+
+ private:
+  ParsedFunction* parsed_function() const { return parsed_function_; }
+  bool optimized() const { return optimized_; }
+  intptr_t osr_id() const { return osr_id_; }
+  Thread* thread() const { return thread_; }
+  Isolate* isolate() const { return thread_->isolate(); }
+  uint32_t cha_invalidation_gen_at_start() const {
+    return cha_invalidation_gen_at_start_;
+  }
+  uint32_t field_invalidation_gen_at_start() const {
+    return field_invalidation_gen_at_start_;
+  }
+  uint32_t prefix_invalidation_gen_at_start() const {
+    return prefix_invalidation_gen_at_start_;
+  }
+  void FinalizeCompilation(Assembler* assembler,
+                           FlowGraphCompiler* graph_compiler,
+                           FlowGraph* flow_graph);
+
+  ParsedFunction* parsed_function_;
+  const bool optimized_;
+  const intptr_t osr_id_;
+  Thread* const thread_;
+  const uint32_t cha_invalidation_gen_at_start_;
+  const uint32_t field_invalidation_gen_at_start_;
+  const uint32_t prefix_invalidation_gen_at_start_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper);
+};
+
+
+void CompileParsedFunctionHelper::FinalizeCompilation(
+    Assembler* assembler,
+    FlowGraphCompiler* graph_compiler,
+    FlowGraph* flow_graph) {
+  const Function& function = parsed_function()->function();
+  Zone* const zone = thread()->zone();
+
+  CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer);
+  // CreateDeoptInfo uses the object pool and needs to be done before
+  // FinalizeCode.
+  const Array& deopt_info_array =
+      Array::Handle(zone, graph_compiler->CreateDeoptInfo(assembler));
+  INC_STAT(thread(), total_code_size,
+           deopt_info_array.Length() * sizeof(uword));
+  // Allocates instruction object. Since this occurs only at safepoint,
+  // there can be no concurrent access to the instruction page.
+  const Code& code = Code::Handle(
+      Code::FinalizeCode(function, assembler, optimized()));
+  code.set_is_optimized(optimized());
+  code.set_owner(function);
+  if (!function.IsOptimizable()) {
+    // A function with huge unoptimized code can become non-optimizable
+    // after generating unoptimized code.
+    function.set_usage_counter(INT_MIN);
+  }
+
+  const Array& intervals = graph_compiler->inlined_code_intervals();
+  INC_STAT(thread(), total_code_size,
+           intervals.Length() * sizeof(uword));
+  code.SetInlinedIntervals(intervals);
+
+  const Array& inlined_id_array =
+      Array::Handle(zone, graph_compiler->InliningIdToFunction());
+  INC_STAT(thread(), total_code_size,
+           inlined_id_array.Length() * sizeof(uword));
+  code.SetInlinedIdToFunction(inlined_id_array);
+
+  const Array& caller_inlining_id_map_array =
+      Array::Handle(zone, graph_compiler->CallerInliningIdMap());
+  INC_STAT(thread(), total_code_size,
+           caller_inlining_id_map_array.Length() * sizeof(uword));
+  code.SetInlinedCallerIdMap(caller_inlining_id_map_array);
+
+  graph_compiler->FinalizePcDescriptors(code);
+  code.set_deopt_info_array(deopt_info_array);
+
+  graph_compiler->FinalizeStackmaps(code);
+  graph_compiler->FinalizeVarDescriptors(code);
+  graph_compiler->FinalizeExceptionHandlers(code);
+  graph_compiler->FinalizeStaticCallTargetsTable(code);
+
+  if (optimized()) {
+    // Installs code while at safepoint.
+    if (thread()->IsMutatorThread()) {
+      const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId;
+      function.InstallOptimizedCode(code, is_osr);
+    } else {
+      // Background compilation.
+      // Before installing code check generation counts if the code may
+      // have become invalid.
+      const bool trace_compiler =
+          FLAG_trace_compiler || FLAG_trace_optimizing_compiler;
+      bool code_is_valid = true;
+      if (!thread()->cha()->leaf_classes().is_empty()) {
+        if (cha_invalidation_gen_at_start() !=
+            isolate()->cha_invalidation_gen()) {
+          code_is_valid = false;
+          if (trace_compiler) {
+            THR_Print("--> FAIL: CHA invalidation.");
+          }
+        }
+      }
+      if (!flow_graph->guarded_fields()->is_empty()) {
+        if (field_invalidation_gen_at_start() !=
+            isolate()->field_invalidation_gen()) {
+          code_is_valid = false;
+          if (trace_compiler) {
+            THR_Print("--> FAIL: Field invalidation.");
+          }
+        }
+      }
+      if (parsed_function()->HasDeferredPrefixes()) {
+        if (prefix_invalidation_gen_at_start() !=
+            isolate()->prefix_invalidation_gen()) {
+          code_is_valid = false;
+          if (trace_compiler) {
+            THR_Print("--> FAIL: Prefix invalidation.");
+          }
+        }
+      }
+      if (code_is_valid) {
+        const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId;
+        ASSERT(!is_osr);  // OSR is compiled in background.
+        function.InstallOptimizedCode(code, is_osr);
+      }
+      if (function.usage_counter() < 0) {
+        // Reset to 0 so that it can be recompiled if needed.
+        function.set_usage_counter(0);
+      }
+    }
+
+    // Register code with the classes it depends on because of CHA and
+    // fields it depends on because of store guards, unless we cannot
+    // deopt.
+    if (Compiler::allow_recompilation()) {
+      // Deoptimize field dependent code first, before registering
+      // this yet uninstalled code as dependent on a field.
+      // TODO(srdjan): Debugging dart2js crashes;
+      // FlowGraphOptimizer::VisitStoreInstanceField populates
+      // deoptimize_dependent_code() list, currently disabled.
+      for (intptr_t i = 0;
+           i < flow_graph->deoptimize_dependent_code().length();
+           i++) {
+        const Field* field = flow_graph->deoptimize_dependent_code()[i];
+        field->DeoptimizeDependentCode();
+      }
+      for (intptr_t i = 0;
+           i < thread()->cha()->leaf_classes().length();
+           ++i) {
+        thread()->cha()->leaf_classes()[i]->RegisterCHACode(code);
+      }
+      for (intptr_t i = 0;
+           i < flow_graph->guarded_fields()->length();
+           i++) {
+        const Field* field = (*flow_graph->guarded_fields())[i];
+        field->RegisterDependentCode(code);
+      }
+    }
+  } else {  // not optimized.
+    if (!Compiler::always_optimize() &&
+        (function.ic_data_array() == Array::null())) {
+      function.SaveICDataMap(
+          graph_compiler->deopt_id_to_ic_data(),
+          Array::Handle(zone, graph_compiler->edge_counters_array()));
+    }
+    function.set_unoptimized_code(code);
+    function.AttachCode(code);
+  }
+  if (parsed_function()->HasDeferredPrefixes()) {
+    ASSERT(!FLAG_load_deferred_eagerly);
+    ZoneGrowableArray<const LibraryPrefix*>* prefixes =
+        parsed_function()->deferred_prefixes();
+    for (intptr_t i = 0; i < prefixes->length(); i++) {
+      (*prefixes)[i]->RegisterDependentCode(code);
+    }
+  }
+}
+
+
 // Return false if bailed out.
-static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline,
-                                        ParsedFunction* parsed_function,
-                                        bool optimized,
-                                        intptr_t osr_id) {
-  const Function& function = parsed_function->function();
-  if (optimized && !function.IsOptimizable()) {
+// If optimized_result_code is not NULL then it is caller's responsibility
+// to install code.
+bool CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
+  const Function& function = parsed_function()->function();
+  if (optimized() && !function.IsOptimizable()) {
     return false;
   }
   bool is_compiled = false;
-  Thread* const thread = Thread::Current();
-  Zone* const zone = thread->zone();
-  Isolate* const isolate = thread->isolate();
-  CSTAT_TIMER_SCOPE(thread, codegen_timer);
-  HANDLESCOPE(thread);
+  Zone* const zone = thread()->zone();
+  TimelineStream* compiler_timeline = isolate()->GetCompilerStream();
+  CSTAT_TIMER_SCOPE(thread(), codegen_timer);
+  HANDLESCOPE(thread());
 
   // We may reattempt compilation if the function needs to be assembled using
   // far branches on ARM and MIPS. In the else branch of the setjmp call,
@@ -402,29 +619,39 @@
   bool done = false;
   // volatile because the variable may be clobbered by a longjmp.
   volatile bool use_far_branches = false;
+  volatile bool use_speculative_inlining =
+      FLAG_max_speculative_inlining_attempts > 0;
+  GrowableArray<intptr_t> inlining_black_list;
+
   while (!done) {
-    const intptr_t prev_deopt_id = thread->deopt_id();
-    thread->set_deopt_id(0);
+    const intptr_t prev_deopt_id = thread()->deopt_id();
+    thread()->set_deopt_id(0);
     LongJumpScope jump;
-    if (setjmp(*jump.Set()) == 0) {
+    const intptr_t val = setjmp(*jump.Set());
+    if (val == 0) {
       FlowGraph* flow_graph = NULL;
 
       // Class hierarchy analysis is registered with the isolate in the
       // constructor and unregisters itself upon destruction.
-      CHA cha(thread);
+      CHA cha(thread());
 
       // TimerScope needs an isolate to be properly terminated in case of a
       // LongJump.
       {
-        CSTAT_TIMER_SCOPE(thread, graphbuilder_timer);
+        CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer);
         ZoneGrowableArray<const ICData*>* ic_data_array =
             new(zone) ZoneGrowableArray<const ICData*>();
-        if (optimized) {
+        if (optimized()) {
           // Extract type feedback before the graph is built, as the graph
           // builder uses it to attach it to nodes.
           ASSERT(function.deoptimization_counter() <
-                 FLAG_deoptimization_counter_threshold);
-          function.RestoreICDataMap(ic_data_array);
+                 FLAG_max_deoptimization_counter_threshold);
+
+          // 'Freeze' ICData in background compilation so that it does not
+          // change while compiling.
+          const bool clone_descriptors = Compiler::IsBackgroundCompilation();
+          function.RestoreICDataMap(ic_data_array, clone_descriptors);
+
           if (FLAG_print_ic_data_map) {
             for (intptr_t i = 0; i < ic_data_array->length(); i++) {
               if ((*ic_data_array)[i] != NULL) {
@@ -435,19 +662,22 @@
           }
         }
 
+        TimelineDurationScope tds(thread(),
+                                  compiler_timeline,
+                                  "BuildFlowGraph");
         flow_graph = pipeline->BuildFlowGraph(zone,
-                                              parsed_function,
+                                              parsed_function(),
                                               *ic_data_array,
-                                              osr_id);
+                                              osr_id());
       }
 
       const bool print_flow_graph =
           (FLAG_print_flow_graph ||
-          (optimized && FLAG_print_flow_graph_optimized)) &&
+           (optimized() && FLAG_print_flow_graph_optimized)) &&
           FlowGraphPrinter::ShouldPrint(function);
 
       if (print_flow_graph) {
-        if (osr_id == Thread::kNoDeoptId) {
+        if (osr_id() == Compiler::kNoOSRDeoptId) {
           FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
         } else {
           FlowGraphPrinter::PrintGraph("For OSR", flow_graph);
@@ -456,13 +686,19 @@
 
       BlockScheduler block_scheduler(flow_graph);
       const bool reorder_blocks =
-          FlowGraph::ShouldReorderBlocks(function, optimized);
+          FlowGraph::ShouldReorderBlocks(function, optimized());
       if (reorder_blocks) {
+        TimelineDurationScope tds(thread(),
+                                  compiler_timeline,
+                                  "BlockScheduler::AssignEdgeWeights");
         block_scheduler.AssignEdgeWeights();
       }
 
-      if (optimized) {
-        CSTAT_TIMER_SCOPE(thread, ssa_timer);
+      if (optimized()) {
+        TimelineDurationScope tds(thread(),
+                                  compiler_timeline,
+                                  "ComputeSSA");
+        CSTAT_TIMER_SCOPE(thread(), ssa_timer);
         // Transform to SSA (virtual register 0 and no inlining arguments).
         flow_graph->ComputeSSA(0, NULL);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
@@ -479,15 +715,26 @@
       // Collect all instance fields that are loaded in the graph and
       // have non-generic type feedback attached to them that can
       // potentially affect optimizations.
-      if (optimized) {
+      if (optimized()) {
+        TimelineDurationScope tds(thread(),
+                                  compiler_timeline,
+                                  "OptimizationPasses");
         inline_id_to_function.Add(&function);
         // Top scope function has no caller (-1).
         caller_inline_id.Add(-1);
-        CSTAT_TIMER_SCOPE(thread, graphoptimizer_timer);
+        CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer);
 
-        FlowGraphOptimizer optimizer(flow_graph);
+        FlowGraphOptimizer optimizer(flow_graph,
+                                     use_speculative_inlining,
+                                     &inlining_black_list);
         if (Compiler::always_optimize()) {
           optimizer.PopulateWithICData();
+
+          optimizer.ApplyClassIds();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+
+          FlowGraphTypePropagator::Propagate(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
         optimizer.ApplyICData();
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
@@ -501,7 +748,10 @@
 
         // Inlining (mutates the flow graph)
         if (FLAG_use_inlining) {
-          CSTAT_TIMER_SCOPE(thread, graphinliner_timer);
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "Inlining");
+          CSTAT_TIMER_SCOPE(thread(), graphinliner_timer);
           // Propagate types to create more inlining opportunities.
           FlowGraphTypePropagator::Propagate(flow_graph);
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
@@ -512,7 +762,9 @@
 
           FlowGraphInliner inliner(flow_graph,
                                    &inline_id_to_function,
-                                   &caller_inline_id);
+                                   &caller_inline_id,
+                                   use_speculative_inlining,
+                                   &inlining_black_list);
           inliner.Inline();
           // Use lists are maintained and validated by the inliner.
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
@@ -522,9 +774,14 @@
         FlowGraphTypePropagator::Propagate(flow_graph);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        // Use propagated class-ids to optimize further.
-        optimizer.ApplyClassIds();
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "ApplyClassIds");
+          // Use propagated class-ids to optimize further.
+          optimizer.ApplyClassIds();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
 
         // Propagate types for potentially newly added instructions by
         // ApplyClassIds(). Must occur before canonicalization.
@@ -539,13 +796,21 @@
         }
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        BranchSimplifier::Simplify(flow_graph);
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "BranchSimplifier");
+          BranchSimplifier::Simplify(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        IfConverter::Simplify(flow_graph);
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+          IfConverter::Simplify(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
 
         if (FLAG_constant_propagation) {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "ConstantPropagation");
           ConstantPropagator::Optimize(flow_graph);
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
           // A canonicalization pass to remove e.g. smi checks on smi constants.
@@ -571,40 +836,54 @@
         FlowGraphTypePropagator::Propagate(flow_graph);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        // Where beneficial convert Smi operations into Int32 operations.
-        // Only meanigful for 32bit platforms right now.
-        optimizer.WidenSmiToInt32();
+        {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "SelectRepresentations");
+          // Where beneficial convert Smi operations into Int32 operations.
+          // Only meanigful for 32bit platforms right now.
+          optimizer.WidenSmiToInt32();
 
-        // Unbox doubles. Performed after constant propagation to minimize
-        // interference from phis merging double values and tagged
-        // values coming from dead paths.
-        optimizer.SelectRepresentations();
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-
-        if (FLAG_common_subexpression_elimination ||
-            FLAG_loop_invariant_code_motion) {
-          flow_graph->ComputeBlockEffects();
-        }
-
-        if (FLAG_common_subexpression_elimination) {
-          if (DominatorBasedCSE::Optimize(flow_graph)) {
-            DEBUG_ASSERT(flow_graph->VerifyUseLists());
-            // Do another round of CSE to take secondary effects into account:
-            // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
-            // TODO(fschneider): Change to a one-pass optimization pass.
-            DominatorBasedCSE::Optimize(flow_graph);
-            DEBUG_ASSERT(flow_graph->VerifyUseLists());
-          }
-        }
-
-        // Run loop-invariant code motion right after load elimination since it
-        // depends on the numbering of loads from the previous load-elimination.
-        if (FLAG_loop_invariant_code_motion) {
-          LICM licm(flow_graph);
-          licm.Optimize();
+          // Unbox doubles. Performed after constant propagation to minimize
+          // interference from phis merging double values and tagged
+          // values coming from dead paths.
+          optimizer.SelectRepresentations();
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
-        flow_graph->RemoveRedefinitions();
+
+        {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "CommonSubexpressionElinination");
+          if (FLAG_common_subexpression_elimination ||
+              FLAG_loop_invariant_code_motion) {
+            flow_graph->ComputeBlockEffects();
+          }
+
+          if (FLAG_common_subexpression_elimination) {
+            if (DominatorBasedCSE::Optimize(flow_graph)) {
+              DEBUG_ASSERT(flow_graph->VerifyUseLists());
+              optimizer.Canonicalize();
+              // Do another round of CSE to take secondary effects into account:
+              // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
+              // TODO(fschneider): Change to a one-pass optimization pass.
+              if (DominatorBasedCSE::Optimize(flow_graph)) {
+                optimizer.Canonicalize();
+              }
+              DEBUG_ASSERT(flow_graph->VerifyUseLists());
+            }
+          }
+
+          // Run loop-invariant code motion right after load elimination since
+          // it depends on the numbering of loads from the previous
+          // load-elimination.
+          if (FLAG_loop_invariant_code_motion) {
+            LICM licm(flow_graph);
+            licm.Optimize();
+            DEBUG_ASSERT(flow_graph->VerifyUseLists());
+          }
+          flow_graph->RemoveRedefinitions();
+        }
 
         // Optimize (a << b) & c patterns, merge operations.
         // Run after CSE in order to have more opportunity to merge
@@ -612,9 +891,17 @@
         optimizer.TryOptimizePatterns();
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        DeadStoreElimination::Optimize(flow_graph);
+        {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "DeadStoreElimination");
+          DeadStoreElimination::Optimize(flow_graph);
+        }
 
         if (FLAG_range_analysis) {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "RangeAnalysis");
           // Propagate types after store-load-forwarding. Some phis may have
           // become smi phis that can be processed by range analysis.
           FlowGraphTypePropagator::Propagate(flow_graph);
@@ -628,6 +915,9 @@
         }
 
         if (FLAG_constant_propagation) {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "ConstantPropagator::OptimizeBranches");
           // Constant propagation can use information from range analysis to
           // find unreachable branch targets and eliminate branches that have
           // the same true- and false-target.
@@ -640,16 +930,26 @@
         FlowGraphTypePropagator::Propagate(flow_graph);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        // Optimize try-blocks.
-        TryCatchAnalyzer::Optimize(flow_graph);
+        {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "TryCatchAnalyzer::Optimize");
+          // Optimize try-blocks.
+          TryCatchAnalyzer::Optimize(flow_graph);
+        }
 
         // Detach environments from the instructions that can't deoptimize.
         // Do it before we attempt to perform allocation sinking to minimize
         // amount of materializations it has to perform.
         optimizer.EliminateEnvironments();
 
-        DeadCodeElimination::EliminateDeadPhis(flow_graph);
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "EliminateDeadPhis");
+          DeadCodeElimination::EliminateDeadPhis(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
 
         if (optimizer.Canonicalize()) {
           optimizer.Canonicalize();
@@ -660,6 +960,9 @@
         AllocationSinking* sinking = NULL;
         if (FLAG_allocation_sinking &&
             (flow_graph->graph_entry()->SuccessorCount()  == 1)) {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "AllocationSinking::Optimize");
           // TODO(fschneider): Support allocation sinking with try-catch.
           sinking = new AllocationSinking(flow_graph);
           sinking->Optimize();
@@ -672,9 +975,14 @@
         FlowGraphTypePropagator::Propagate(flow_graph);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        // Ensure that all phis inserted by optimization passes have consistent
-        // representations.
-        optimizer.SelectRepresentations();
+        {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "SelectRepresentations");
+          // Ensure that all phis inserted by optimization passes have
+          // consistent representations.
+          optimizer.SelectRepresentations();
+        }
 
         if (optimizer.Canonicalize()) {
           // To fully remove redundant boxing (e.g. BoxDouble used only in
@@ -687,6 +995,10 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         if (sinking != NULL) {
+          TimelineDurationScope tds2(
+              thread(),
+              compiler_timeline,
+              "AllocationSinking::DetachMaterializations");
           // Remove all MaterializeObject instructions inserted by allocation
           // sinking from the flow graph and let them float on the side
           // referenced only from environments. Register allocator will consider
@@ -698,10 +1010,21 @@
         // to be later used by the inliner.
         FlowGraphInliner::CollectGraphInfo(flow_graph, true);
 
-        // Perform register allocation on the SSA graph.
-        FlowGraphAllocator allocator(*flow_graph);
-        allocator.AllocateRegisters();
-        if (reorder_blocks) block_scheduler.ReorderBlocks();
+        {
+          TimelineDurationScope tds2(thread(),
+                                     compiler_timeline,
+                                     "AllocateRegisters");
+          // Perform register allocation on the SSA graph.
+          FlowGraphAllocator allocator(*flow_graph);
+          allocator.AllocateRegisters();
+        }
+
+        if (reorder_blocks) {
+          TimelineDurationScope tds(thread(),
+                                    compiler_timeline,
+                                    "BlockScheduler::ReorderBlocks");
+          block_scheduler.ReorderBlocks();
+        }
 
         if (print_flow_graph) {
           FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
@@ -711,99 +1034,53 @@
       ASSERT(inline_id_to_function.length() == caller_inline_id.length());
       Assembler assembler(use_far_branches);
       FlowGraphCompiler graph_compiler(&assembler, flow_graph,
-                                       *parsed_function, optimized,
+                                       *parsed_function(), optimized(),
                                        inline_id_to_function,
                                        caller_inline_id);
       {
-        CSTAT_TIMER_SCOPE(thread, graphcompiler_timer);
+        CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer);
+        TimelineDurationScope tds(thread(),
+                                  compiler_timeline,
+                                  "CompileGraph");
         graph_compiler.CompileGraph();
         pipeline->FinalizeCompilation();
       }
       {
-        CSTAT_TIMER_SCOPE(thread, codefinalizer_timer);
-        // CreateDeoptInfo uses the object pool and needs to be done before
-        // FinalizeCode.
-        const Array& deopt_info_array =
-            Array::Handle(zone, graph_compiler.CreateDeoptInfo(&assembler));
-        INC_STAT(thread, total_code_size,
-                 deopt_info_array.Length() * sizeof(uword));
-        const Code& code = Code::Handle(
-            Code::FinalizeCode(function, &assembler, optimized));
-        code.set_is_optimized(optimized);
-
-        const Array& intervals = graph_compiler.inlined_code_intervals();
-        INC_STAT(thread, total_code_size,
-                 intervals.Length() * sizeof(uword));
-        code.SetInlinedIntervals(intervals);
-
-        const Array& inlined_id_array =
-            Array::Handle(zone, graph_compiler.InliningIdToFunction());
-        INC_STAT(thread, total_code_size,
-                 inlined_id_array.Length() * sizeof(uword));
-        code.SetInlinedIdToFunction(inlined_id_array);
-
-        const Array& caller_inlining_id_map_array =
-            Array::Handle(zone, graph_compiler.CallerInliningIdMap());
-        INC_STAT(thread, total_code_size,
-                 caller_inlining_id_map_array.Length() * sizeof(uword));
-        code.SetInlinedCallerIdMap(caller_inlining_id_map_array);
-
-        graph_compiler.FinalizePcDescriptors(code);
-        code.set_deopt_info_array(deopt_info_array);
-
-        graph_compiler.FinalizeStackmaps(code);
-        graph_compiler.FinalizeVarDescriptors(code);
-        graph_compiler.FinalizeExceptionHandlers(code);
-        graph_compiler.FinalizeStaticCallTargetsTable(code);
-
-        if (optimized) {
-          // We may not have previous code if 'always_optimize' is set.
-          if ((osr_id == Thread::kNoDeoptId) && function.HasCode()) {
-            Code::Handle(function.CurrentCode()).DisableDartCode();
+        TimelineDurationScope tds(thread(),
+                                  compiler_timeline,
+                                  "FinalizeCompilation");
+        if (thread()->IsMutatorThread()) {
+          FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
+        } else {
+          // This part of compilation must be at a safepoint.
+          // Stop mutator thread before creating the instruction object and
+          // installing code.
+          // Mutator thread may not run code while we are creating the
+          // instruction object, since the creation of instruction object
+          // changes code page access permissions (makes them temporary not
+          // executable).
+          isolate()->thread_registry()->SafepointThreads();
+          {
+            // Do not Garbage collect during this stage and instead allow the
+            // heap to grow.
+            NoHeapGrowthControlScope no_growth_control;
+            FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
           }
-          function.AttachCode(code);
-
-          // Register code with the classes it depends on because of CHA.
-          for (intptr_t i = 0;
-               i < thread->cha()->leaf_classes().length();
-               ++i) {
-            thread->cha()->leaf_classes()[i]->RegisterCHACode(code);
-          }
-
-          for (intptr_t i = 0;
-               i < flow_graph->guarded_fields()->length();
-               i++) {
-            const Field* field = (*flow_graph->guarded_fields())[i];
-            field->RegisterDependentCode(code);
-          }
-        } else {  // not optimized.
-          if (!Compiler::always_optimize() &&
-              (function.ic_data_array() == Array::null())) {
-            function.SaveICDataMap(
-                graph_compiler.deopt_id_to_ic_data(),
-                Array::Handle(zone, graph_compiler.edge_counters_array()));
-          }
-          function.set_unoptimized_code(code);
-          function.AttachCode(code);
-        }
-        if (parsed_function->HasDeferredPrefixes()) {
-          ASSERT(!FLAG_load_deferred_eagerly);
-          ZoneGrowableArray<const LibraryPrefix*>* prefixes =
-              parsed_function->deferred_prefixes();
-          for (intptr_t i = 0; i < prefixes->length(); i++) {
-            (*prefixes)[i]->RegisterDependentCode(code);
+          isolate()->thread_registry()->ResumeAllThreads();
+          if (isolate()->heap()->NeedsGarbageCollection()) {
+            isolate()->heap()->CollectAllGarbage();
           }
         }
       }
       // Mark that this isolate now has compiled code.
-      isolate->set_has_compiled_code(true);
+      isolate()->set_has_compiled_code(true);
       // Exit the loop and the function with the correct result value.
       is_compiled = true;
       done = true;
     } else {
       // We bailed out or we encountered an error.
       const Error& error = Error::Handle(
-          isolate->object_store()->sticky_error());
+          isolate()->object_store()->sticky_error());
 
       if (error.raw() == Object::branch_offset_error().raw()) {
         // Compilation failed due to an out of range branch offset in the
@@ -811,6 +1088,26 @@
         done = false;
         ASSERT(!use_far_branches);
         use_far_branches = true;
+      } else if (error.raw() == Object::speculative_inlining_error().raw()) {
+        // The return value of setjmp is the deopt id of the check instruction
+        // that caused the bailout.
+        done = false;
+#if defined(DEBUG)
+        ASSERT(Compiler::always_optimize());
+        ASSERT(use_speculative_inlining);
+        for (intptr_t i = 0; i < inlining_black_list.length(); ++i) {
+          ASSERT(inlining_black_list[i] != val);
+        }
+#endif
+        inlining_black_list.Add(val);
+        const intptr_t max_attempts = FLAG_max_speculative_inlining_attempts;
+        if (inlining_black_list.length() >= max_attempts) {
+          use_speculative_inlining = false;
+          if (FLAG_trace_compiler || FLAG_trace_optimizing_compiler) {
+            THR_Print("Disabled speculative inlining after %" Pd " attempts.\n",
+                      inlining_black_list.length());
+          }
+        }
       } else {
         // If the error isn't due to an out of range branch offset, we don't
         // try again (done = true), and indicate that we did not finish
@@ -819,18 +1116,17 @@
           THR_Print("%s\n", error.ToErrorCString());
         }
         done = true;
-        ASSERT(optimized);
       }
 
       // Clear the error if it was not a real error, but just a bailout.
       if (error.IsLanguageError() &&
           (LanguageError::Cast(error).kind() == Report::kBailout)) {
-        isolate->object_store()->clear_sticky_error();
+        isolate()->object_store()->clear_sticky_error();
       }
       is_compiled = false;
     }
     // Reset global isolate state.
-    thread->set_deopt_id(prev_deopt_id);
+    thread()->set_deopt_id(prev_deopt_id);
   }
   return is_compiled;
 }
@@ -1012,14 +1308,17 @@
     Isolate* const isolate = thread->isolate();
     StackZone stack_zone(thread);
     Zone* const zone = stack_zone.GetZone();
-    Timer per_compile_timer(FLAG_trace_compiler, "Compilation time");
+    const bool trace_compiler =
+        FLAG_trace_compiler ||
+        (FLAG_trace_optimizing_compiler && optimized);
+    Timer per_compile_timer(trace_compiler, "Compilation time");
     per_compile_timer.Start();
 
     ParsedFunction* parsed_function = new(zone) ParsedFunction(
         thread, Function::ZoneHandle(zone, function.raw()));
-    if (FLAG_trace_compiler) {
+    if (trace_compiler) {
       THR_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n",
-                (osr_id == Thread::kNoDeoptId ? "" : "osr "),
+                (osr_id == Compiler::kNoOSRDeoptId ? "" : "osr "),
                 (optimized ? "optimized " : ""),
                 function.ToFullyQualifiedCString(),
                 function.token_pos(),
@@ -1039,15 +1338,13 @@
                num_tokens_after - num_tokens_before);
     }
 
-    const bool success = CompileParsedFunctionHelper(pipeline,
-                                                     parsed_function,
-                                                     optimized,
-                                                     osr_id);
+    CompileParsedFunctionHelper helper(parsed_function, optimized, osr_id);
+    const bool success = helper.Compile(pipeline);
     if (!success) {
       if (optimized) {
         ASSERT(!Compiler::always_optimize());  // Optimized is the only code.
         // Optimizer bailed out. Disable optimizations and never try again.
-        if (FLAG_trace_compiler) {
+        if (trace_compiler) {
           THR_Print("--> disabling optimizations for '%s'\n",
                     function.ToFullyQualifiedCString());
         } else if (FLAG_trace_failed_optimization_attempts) {
@@ -1056,13 +1353,19 @@
         }
         function.SetIsOptimizable(false);
         return Error::null();
+      } else {
+        // Encountered error.
+        Error& error = Error::Handle();
+        // We got an error during compilation.
+        error = isolate->object_store()->sticky_error();
+        isolate->object_store()->clear_sticky_error();
+        return error.raw();
       }
-      UNREACHABLE();
     }
 
     per_compile_timer.Stop();
 
-    if (FLAG_trace_compiler) {
+    if (trace_compiler && success) {
       THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n",
                 function.ToFullyQualifiedCString(),
                 Code::Handle(function.CurrentCode()).EntryPoint(),
@@ -1094,6 +1397,11 @@
     // We got an error during compilation.
     error = isolate->object_store()->sticky_error();
     isolate->object_store()->clear_sticky_error();
+    // Unoptimized compilation or precompilation may encounter compile-time
+    // errors, but regular optimized compilation should not.
+    ASSERT(!optimized || Compiler::always_optimize());
+    // Do not attempt to optimize functions that can cause errors.
+    function.set_is_optimizable(false);
     return error.raw();
   }
   UNREACHABLE();
@@ -1120,8 +1428,10 @@
   const bool optimized =
       Compiler::always_optimize() && function.IsOptimizable();
 
-  return CompileFunctionHelper(pipeline, function, optimized,
-      Thread::kNoDeoptId);
+  return CompileFunctionHelper(pipeline,
+                               function,
+                               optimized,
+                               kNoOSRDeoptId);
 }
 
 
@@ -1137,7 +1447,10 @@
   CompilationPipeline* pipeline =
       CompilationPipeline::New(thread->zone(), function);
   const Error& error = Error::Handle(
-      CompileFunctionHelper(pipeline, function, false, Thread::kNoDeoptId));
+      CompileFunctionHelper(pipeline,
+                            function,
+                            false,  /* not optimized */
+                            kNoOSRDeoptId));
   if (!error.IsNull()) {
     return error.raw();
   }
@@ -1163,12 +1476,15 @@
                                          "OptimizedFunction", function);
 
   // Optimization must happen in non-mutator/Dart thread if background
-  // compilation is on.
-  ASSERT(!FLAG_background_compilation ||
-         !thread->isolate()->MutatorThreadIsCurrentThread());
+  // compilation is on. OSR compilation still occurs in the main thread.
+  ASSERT((osr_id != kNoOSRDeoptId) || !FLAG_background_compilation ||
+         !thread->IsMutatorThread());
   CompilationPipeline* pipeline =
       CompilationPipeline::New(thread->zone(), function);
-  return CompileFunctionHelper(pipeline, function, true, osr_id);
+  return CompileFunctionHelper(pipeline,
+                               function,
+                               true,  /* optimized */
+                               osr_id);
 }
 
 
@@ -1179,10 +1495,8 @@
   if (setjmp(*jump.Set()) == 0) {
     // Non-optimized code generator.
     DartCompilationPipeline pipeline;
-    CompileParsedFunctionHelper(&pipeline,
-                                parsed_function,
-                                false,
-                                Thread::kNoDeoptId);
+    CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
+    helper.Compile(&pipeline);
     if (FLAG_disassemble) {
       DisassembleCode(parsed_function->function(), false);
     }
@@ -1247,24 +1561,6 @@
       func.ClearCode();
     }
   }
-  // Inner functions get added to the closures array. As part of compilation
-  // more closures can be added to the end of the array. Compile all the
-  // closures until we have reached the end of the "worklist".
-  GrowableObjectArray& closures =
-      GrowableObjectArray::Handle(zone, cls.closures());
-  if (!closures.IsNull()) {
-    for (int i = 0; i < closures.Length(); i++) {
-      func ^= closures.At(i);
-      if (!func.HasCode()) {
-        error = CompileFunction(thread, func);
-        if (!error.IsNull()) {
-          return error.raw();
-        }
-        func.ClearICDataArray();
-        func.ClearCode();
-      }
-    }
-  }
   return error.raw();
 }
 
@@ -1285,11 +1581,8 @@
   parsed_function->AllocateVariables();
   // Non-optimized code generator.
   DartCompilationPipeline pipeline;
-  CompileParsedFunctionHelper(&pipeline,
-                              parsed_function,
-                              false,  // optimized
-                              Thread::kNoDeoptId);
-
+  CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
+  helper.Compile(&pipeline);
   const Function& initializer = parsed_function->function();
   field.SetPrecompiledInitializer(initializer);
 }
@@ -1316,10 +1609,8 @@
       parsed_function->AllocateVariables();
       // Non-optimized code generator.
       DartCompilationPipeline pipeline;
-      CompileParsedFunctionHelper(&pipeline,
-                                  parsed_function,
-                                  false,  // optimized
-                                  Thread::kNoDeoptId);
+      CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
+      helper.Compile(&pipeline);
       initializer = parsed_function->function().raw();
       Code::Handle(initializer.unoptimized_code()).set_var_descriptors(
           Object::empty_var_descriptors());
@@ -1367,7 +1658,7 @@
         Class::Handle(Type::Handle(Type::Function()).type_class()),
         fragment->token_pos()));
 
-    func.set_result_type(Type::Handle(Type::DynamicType()));
+    func.set_result_type(Object::dynamic_type());
     func.set_num_fixed_parameters(0);
     func.SetNumOptionalParameters(0, true);
     // Manually generated AST, do not recompile.
@@ -1386,10 +1677,8 @@
 
     // Non-optimized code generator.
     DartCompilationPipeline pipeline;
-    CompileParsedFunctionHelper(&pipeline,
-                                parsed_function,
-                                false,
-                                Thread::kNoDeoptId);
+    CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
+    helper.Compile(&pipeline);
     Code::Handle(func.unoptimized_code()).set_var_descriptors(
         Object::empty_var_descriptors());
 
@@ -1409,85 +1698,161 @@
 }
 
 
-// A simple work queue containing functions to be optimized. Use
-// PushFront and PopBack to add and read from queue.
-// TODO(srdjan): Write a more efficient implementation.
-class CompilationWorkQueue : public ValueObject {
+// C-heap allocated background compilation queue element.
+class QueueElement {
  public:
-  explicit CompilationWorkQueue(Isolate* isolate) :
-      data_(GrowableObjectArray::Handle()) {
-    data_ = isolate->background_compilation_queue();
+  explicit QueueElement(const Function& function)
+      : next_(NULL),
+        function_(function.raw()) {
+    ASSERT(Thread::Current()->IsMutatorThread());
   }
 
-  intptr_t IsEmpty() const { return data_.Length() == 0; }
-
-  // Adds to the queue only if 'function' is not already in there.
-  void PushFront(const Function& function) {
-    for (intptr_t i = 0; i < data_.Length(); i++) {
-      if (data_.At(i) == function.raw()) {
-        return;
-      }
-    }
-    // Insert new element in front.
-    Object& f = Object::Handle();
-    data_.Add(f);
-    for (intptr_t i = data_.Length() - 1; i > 0; i--) {
-      f = data_.At(i - 1);
-      data_.SetAt(i, f);
-    }
-    data_.SetAt(0, function);
+  ~QueueElement() {
+    function_ = Function::null();
   }
 
-  RawFunction* PopBack() {
-    ASSERT(!IsEmpty());
-    Object& result = Object::Handle();
-    result = data_.At(data_.Length() - 1);
-    data_.SetLength(data_.Length() - 1);
-    return Function::Cast(result).raw();
+  RawFunction* Function() const { return function_; }
+
+
+  void set_next(QueueElement* elem) { next_ = elem; }
+  QueueElement* next() const { return next_; }
+
+  RawObject* function() const { return function_; }
+  RawObject** function_ptr() {
+    return reinterpret_cast<RawObject**>(&function_);
   }
 
  private:
-  GrowableObjectArray& data_;
+  QueueElement* next_;
+  RawFunction* function_;
 
-  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue);
+  DISALLOW_COPY_AND_ASSIGN(QueueElement);
+};
+
+
+// Allocated in C-heap. Handles both input and output of background compilation.
+// It implements a FIFO queue, using Peek, Add, Remove operations.
+class BackgroundCompilationQueue {
+ public:
+  BackgroundCompilationQueue() : first_(NULL), last_(NULL) {}
+  ~BackgroundCompilationQueue() {
+    while (!IsEmpty()) {
+      QueueElement* e = Remove();
+      delete e;
+    }
+    ASSERT((first_ == NULL) && (last_ == NULL));
+  }
+
+  void VisitObjectPointers(ObjectPointerVisitor* visitor) {
+    ASSERT(visitor != NULL);
+    QueueElement* p = first_;
+    while (p != NULL) {
+      visitor->VisitPointer(p->function_ptr());
+      p = p->next();
+    }
+  }
+
+  bool IsEmpty() const { return first_ == NULL; }
+
+  void Add(QueueElement* value) {
+    ASSERT(value != NULL);
+    if (first_ == NULL) {
+      first_ = value;
+    } else {
+      last_->set_next(value);
+    }
+    value->set_next(NULL);
+    last_ = value;
+  }
+
+  QueueElement* Peek() const {
+    return first_;
+  }
+
+  RawFunction* PeekFunction() const {
+    QueueElement* e = Peek();
+    if (e == NULL) {
+      return Function::null();
+    } else {
+      return e->Function();
+    }
+  }
+
+  QueueElement* Remove() {
+    ASSERT(first_ != NULL);
+    QueueElement* result = first_;
+    first_ = first_->next();
+    if (first_ == NULL) {
+      last_ = NULL;
+    }
+    return result;
+  }
+
+  bool ContainsObj(const Object& obj) const {
+    QueueElement* p = first_;
+    while (p != NULL) {
+      if (p->function() == obj.raw()) {
+        return true;
+      }
+      p = p->next();
+    }
+    return false;
+  }
+
+ private:
+  QueueElement* first_;
+  QueueElement* last_;
+
+  DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue);
 };
 
 
 BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
     : isolate_(isolate), running_(true), done_(new bool()),
-      monitor_(new Monitor()), done_monitor_(new Monitor())  {
+      queue_monitor_(new Monitor()), done_monitor_(new Monitor()),
+      function_queue_(new BackgroundCompilationQueue()) {
   *done_ = false;
 }
 
 
 void BackgroundCompiler::Run() {
   while (running_) {
-    {
-      // Wait to be notified when the work queue is not empty.
-      MonitorLocker ml(monitor_);
-      ml.Wait();
-    }
-
-    Thread::EnterIsolateAsHelper(isolate_);
+    // Maybe something is already in the queue, check first before waiting
+    // to be notified.
+    bool result = Thread::EnterIsolateAsHelper(isolate_);
+    ASSERT(result);
     {
       Thread* thread = Thread::Current();
       StackZone stack_zone(thread);
+      Zone* zone = stack_zone.GetZone();
       HANDLESCOPE(thread);
-      Function& function = Function::Handle();
-      function = RemoveOrNull();
-      while (!function.IsNull()) {
-        const Error& error = Error::Handle(
-            Compiler::CompileOptimizedFunction(thread, function));
+      Function& function = Function::Handle(zone);
+      function = function_queue()->PeekFunction();
+      while (running_ && !function.IsNull()) {
+        const Error& error = Error::Handle(zone,
+            Compiler::CompileOptimizedFunction(thread,
+                                               function,
+                                               Compiler::kNoOSRDeoptId));
         // TODO(srdjan): We do not expect errors while compiling optimized
         // code, any errors should have been caught when compiling
-        // unoptimized code.
-        // If it still happens mark function as not optimizable.
+        // unoptimized code. Any issues while optimizing are flagged by
+        // making the result invalid.
         ASSERT(error.IsNull());
-        function = RemoveOrNull();
+        QueueElement* qelem = function_queue()->Remove();
+        delete qelem;
+        function = function_queue()->PeekFunction();
       }
     }
     Thread::ExitIsolateAsHelper();
-  }
+    {
+      // Wait to be notified when the work queue is not empty.
+      MonitorLocker ml(queue_monitor_);
+      while (function_queue()->IsEmpty() && running_) {
+        ml.Wait();
+      }
+    }
+  }  // while running
+
   {
     // Notify that the thread is done.
     MonitorLocker ml_done(done_monitor_);
@@ -1498,62 +1863,75 @@
 
 
 void BackgroundCompiler::CompileOptimized(const Function& function) {
-  Add(function);
-}
-
-
-void BackgroundCompiler::Add(const Function& f) const {
-  MonitorLocker ml(monitor_);
-  CompilationWorkQueue queue(isolate_);
-  queue.PushFront(f);
+  ASSERT(Thread::Current()->IsMutatorThread());
+  MonitorLocker ml(queue_monitor_);
+  if (function_queue()->ContainsObj(function)) {
+    return;
+  }
+  QueueElement* elem = new QueueElement(function);
+  function_queue()->Add(elem);
   ml.Notify();
 }
 
 
-RawFunction* BackgroundCompiler::RemoveOrNull() const {
-  MonitorLocker ml(monitor_);
-  CompilationWorkQueue queue(isolate_);
-  return queue.IsEmpty() ? Function::null() : queue.PopBack();
+void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
+  function_queue_->VisitObjectPointers(visitor);
 }
 
 
 void BackgroundCompiler::Stop(BackgroundCompiler* task) {
-  if (task == NULL) {
-    return;
-  }
-  Monitor* monitor = task->monitor_;
+  ASSERT(Isolate::Current()->background_compiler() == task);
+  ASSERT(task != NULL);
+  BackgroundCompilationQueue* function_queue = task->function_queue();
+
+  Monitor* queue_monitor = task->queue_monitor_;
   Monitor* done_monitor = task->done_monitor_;
   bool* task_done = task->done_;
   // Wake up compiler task and stop it.
   {
-    MonitorLocker ml(task->monitor_);
+    MonitorLocker ml(task->queue_monitor_);
     task->running_ = false;
     // 'task' will be deleted by thread pool.
     task = NULL;
-    ml.Notify();
+    ml.Notify();   // Stop waiting for the queue.
   }
 
   {
     MonitorLocker ml_done(done_monitor);
     while (!(*task_done)) {
-      ml_done.Wait();
+      // In case that the compiler is waiting for safepoint.
+      Isolate::Current()->thread_registry()->CheckSafepoint();
+      ml_done.Wait(1);
     }
   }
   delete task_done;
   delete done_monitor;
-  delete monitor;
+  delete queue_monitor;
+  delete function_queue;
+  Isolate::Current()->set_background_compiler(NULL);
 }
 
 
-void BackgroundCompiler::EnsureInit(Isolate* isolate) {
+void BackgroundCompiler::EnsureInit(Thread* thread) {
+  ASSERT(thread->IsMutatorThread());
+  // Finalize NoSuchMethodError, _Mint; occasionally needed in optimized
+  // compilation.
+  Class& cls = Class::Handle(thread->zone(),
+      Library::LookupCoreClass(Symbols::NoSuchMethodError()));
+  Error& error = Error::Handle(thread->zone(),
+      cls.EnsureIsFinalized(thread));
+  ASSERT(error.IsNull());
+  cls = Library::LookupCoreClass(Symbols::_Mint());
+  error = cls.EnsureIsFinalized(thread);
+  ASSERT(error.IsNull());
+
   bool start_task = false;
+  Isolate* isolate = thread->isolate();
   {
     MutexLocker ml(isolate->mutex());
     if (isolate->background_compiler() == NULL) {
       BackgroundCompiler* task = new BackgroundCompiler(isolate);
       isolate->set_background_compiler(task);
-      isolate->set_background_compilation_queue(GrowableObjectArray::Handle(
-          isolate->current_zone(), GrowableObjectArray::New()));
       start_task = true;
     }
   }
@@ -1562,4 +1940,112 @@
   }
 }
 
+
+#else  // DART_PRECOMPILED
+
+
+DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
+  UNREACHABLE();
+}
+
+
+bool Compiler::IsBackgroundCompilation() {
+  UNREACHABLE();
+  return false;
+}
+
+
+RawError* Compiler::Compile(const Library& library, const Script& script) {
+  UNREACHABLE();
+  return Error::null();
+}
+
+
+RawError* Compiler::CompileClass(const Class& cls) {
+  UNREACHABLE();
+  return Error::null();
+}
+
+
+RawError* Compiler::CompileFunction(Thread* thread,
+                                    const Function& function) {
+  UNREACHABLE();
+  return Error::null();
+}
+
+
+RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
+                                          const Function& function) {
+  UNREACHABLE();
+  return Error::null();
+}
+
+
+RawError* Compiler::CompileOptimizedFunction(Thread* thread,
+                                             const Function& function,
+                                             intptr_t osr_id) {
+  UNREACHABLE();
+  return Error::null();
+}
+
+
+RawError* Compiler::CompileParsedFunction(
+    ParsedFunction* parsed_function) {
+  UNREACHABLE();
+  return Error::null();
+}
+
+
+void Compiler::ComputeLocalVarDescriptors(const Code& code) {
+  UNREACHABLE();
+}
+
+
+RawError* Compiler::CompileAllFunctions(const Class& cls) {
+  UNREACHABLE();
+  return Error::null();
+}
+
+
+void Compiler::CompileStaticInitializer(const Field& field) {
+  UNREACHABLE();
+}
+
+
+RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
+  ASSERT(field.HasPrecompiledInitializer());
+  const Function& initializer =
+      Function::Handle(field.PrecompiledInitializer());
+  return DartEntry::InvokeFunction(initializer, Object::empty_array());
+}
+
+
+
+RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
+  UNREACHABLE();
+  return Object::null();
+}
+
+
+void BackgroundCompiler::CompileOptimized(const Function& function) {
+  UNREACHABLE();
+}
+
+
+void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
+  UNREACHABLE();
+}
+
+
+void BackgroundCompiler::Stop(BackgroundCompiler* task) {
+  UNREACHABLE();
+}
+
+
+void BackgroundCompiler::EnsureInit(Thread* thread) {
+  UNREACHABLE();
+}
+
+#endif  // DART_PRECOMPILED
+
 }  // namespace dart
diff --git a/runtime/vm/compiler.h b/runtime/vm/compiler.h
index 9c3e73f..130567d 100644
--- a/runtime/vm/compiler.h
+++ b/runtime/vm/compiler.h
@@ -13,16 +13,25 @@
 namespace dart {
 
 // Forward declarations.
+class BackgroundCompilationQueue;
 class Class;
+class Code;
+class CompilationWorkQueue;
 class Function;
 class Library;
 class ParsedFunction;
+class QueueElement;
 class RawInstance;
 class Script;
 class SequenceNode;
 
+
 class Compiler : public AllStatic {
  public:
+  static const intptr_t kNoOSRDeoptId = Thread::kNoDeoptId;
+
+  static bool IsBackgroundCompilation();
+
   // Extracts top level entities from the script and populates
   // the class dictionary of the library.
   //
@@ -47,10 +56,12 @@
   // Generates optimized code for function.
   //
   // Returns Error::null() if there is no compilation error.
+  // If 'result_code' is not NULL, then the generated code is returned but
+  // not installed.
   static RawError* CompileOptimizedFunction(
       Thread* thread,
       const Function& function,
-      intptr_t osr_id = Thread::kNoDeoptId);
+      intptr_t osr_id = kNoOSRDeoptId);
 
   // Generates code for given parsed function (without parsing it again) and
   // sets its code field.
@@ -104,27 +115,33 @@
 // Class to run optimizing compilation in a background thread.
 // Current implementation: one task per isolate, it dies with the owning
 // isolate.
+// No OSR compilation in the background compiler.
 class BackgroundCompiler : public ThreadPool::Task {
  public:
-  static void EnsureInit(Isolate* isolate);
+  static void EnsureInit(Thread* thread);
 
   static void Stop(BackgroundCompiler* task);
 
+  // Call to optimize a function in the background, enters the function in the
+  // compilation queue.
   void CompileOptimized(const Function& function);
 
+  void VisitPointers(ObjectPointerVisitor* visitor);
+
+  BackgroundCompilationQueue* function_queue() const { return function_queue_; }
+
  private:
   explicit BackgroundCompiler(Isolate* isolate);
 
   virtual void Run();
 
-  void Add(const Function& f) const;
-  RawFunction* RemoveOrNull() const;
-
   Isolate* isolate_;
-  bool running_;
-  bool* done_;
-  Monitor* monitor_;
-  Monitor* done_monitor_;
+  bool running_;       // While true, will try to read queue and compile.
+  bool* done_;         // True if the thread is done.
+  Monitor* queue_monitor_;  // Controls access to the queue.
+  Monitor* done_monitor_;   // Notify/wait that the thread is done.
+
+  BackgroundCompilationQueue* function_queue_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(BackgroundCompiler);
 };
diff --git a/runtime/vm/compiler_stats.cc b/runtime/vm/compiler_stats.cc
index d3e4b02..d5b20f4 100644
--- a/runtime/vm/compiler_stats.cc
+++ b/runtime/vm/compiler_stats.cc
@@ -7,6 +7,7 @@
 #include "vm/flags.h"
 #include "vm/log.h"
 #include "vm/object_graph.h"
+#include "vm/object_store.h"
 #include "vm/timer.h"
 
 
@@ -37,11 +38,6 @@
       Token::Kind kind = tkit.CurrentTokenKind();
       while (kind != Token::kEOS) {
         ++stats_->num_tokens_total;
-        if (kind == Token::kIDENT) {
-          ++stats_->num_ident_tokens_total;
-        } else if (Token::NeedsLiteralToken(kind)) {
-          ++stats_->num_literal_tokens_total;
-        }
         tkit.Advance();
         kind = tkit.CurrentTokenKind();
       }
@@ -71,8 +67,6 @@
       graphcompiler_timer(true, "flow graph compiler timer"),
       codefinalizer_timer(true, "code finalization timer"),
       num_tokens_total(0),
-      num_literal_tokens_total(0),
-      num_ident_tokens_total(0),
       num_tokens_scanned(0),
       num_tokens_consumed(0),
       num_cached_consts(0),
@@ -117,8 +111,6 @@
   // Traverse the heap and compute number of tokens in all
   // TokenStream objects.
   num_tokens_total = 0;
-  num_literal_tokens_total = 0;
-  num_ident_tokens_total = 0;
   TokenStreamVisitor visitor(isolate_, this);
   isolate_->heap()->IterateObjects(&visitor);
   Dart::vm_isolate()->heap()->IterateObjects(&visitor);
@@ -199,11 +191,12 @@
   log.Print("==== Compiler Stats for isolate '%s' ====\n",
             isolate_->debugger_name());
   log.Print("Number of tokens:        %" Pd64 "\n", num_tokens_total);
-  log.Print("  Literal tokens:        %" Pd64 "\n", num_literal_tokens_total);
-  log.Print("  Ident tokens:          %" Pd64 "\n", num_ident_tokens_total);
   log.Print("Source length:           %" Pd64 " characters\n", src_length);
   log.Print("Number of source tokens: %" Pd64 "\n", num_tokens_scanned);
 
+  int64_t num_local_functions = GrowableObjectArray::Handle(
+      isolate_->object_store()->closure_functions()).Length();
+
   log.Print("==== Parser stats:\n");
   log.Print("Total tokens consumed:   %" Pd64 "\n", num_tokens_consumed);
   log.Print("Classes parsed:          %" Pd64 "\n", num_classes_parsed);
@@ -212,6 +205,7 @@
   log.Print("  Tokens consumed:       %" Pd64 "\n", num_func_tokens_compiled);
   log.Print("Impl getter funcs:       %" Pd64 "\n", num_implicit_final_getters);
   log.Print("Impl method extractors:  %" Pd64 "\n", num_method_extractors);
+  log.Print("Local functions:         %" Pd64 "\n", num_local_functions);
   log.Print("Consts cached:           %" Pd64 "\n", num_cached_consts);
   log.Print("Consts cache hits:       %" Pd64 "\n", num_const_cache_hits);
 
diff --git a/runtime/vm/compiler_stats.h b/runtime/vm/compiler_stats.h
index 4487991..296b2a4 100644
--- a/runtime/vm/compiler_stats.h
+++ b/runtime/vm/compiler_stats.h
@@ -41,8 +41,6 @@
   Timer codefinalizer_timer;   // Included in codegen_timer.
 
   int64_t num_tokens_total;    // Isolate + VM isolate
-  int64_t num_literal_tokens_total;
-  int64_t num_ident_tokens_total;
   int64_t num_tokens_scanned;
   int64_t num_tokens_consumed;
   int64_t num_cached_consts;
@@ -73,10 +71,11 @@
   char* PrintToZone();
 };
 
-// TODO(hausner): make the increment thread-safe.
 #define INC_STAT(thread, counter, incr)                                        \
   if (FLAG_compiler_stats) {                                                   \
-      (thread)->isolate()->compiler_stats()->counter += (incr); }
+    MutexLocker ml((thread)->isolate()->mutex());                              \
+    (thread)->isolate()->compiler_stats()->counter += (incr);                  \
+  }
 
 #define STAT_VALUE(thread, counter)                                            \
   ((FLAG_compiler_stats != false) ?                                            \
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 19e4953..cab1593 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -10,10 +10,13 @@
 #include "vm/object.h"
 #include "vm/symbols.h"
 #include "vm/thread_pool.h"
+#include "vm/thread_registry.h"
 #include "vm/unit_test.h"
 
 namespace dart {
 
+DECLARE_FLAG(bool, background_compilation);
+
 TEST_CASE(CompileScript) {
   const char* kScriptChars =
       "class A {\n"
@@ -70,59 +73,7 @@
 }
 
 
-class CompileFunctionTask : public ThreadPool::Task {
- public:
-  CompileFunctionTask(Isolate* isolate,
-                      const Function& func,
-                      Monitor* done_monitor,
-                      bool* done)
-      : isolate_(isolate),
-        func_(func),
-        done_monitor_(done_monitor),
-        done_(done) {
-  }
-
-  virtual void Run() {
-    Thread::EnterIsolateAsHelper(isolate_);
-    {
-      Thread* thread = Thread::Current();
-      StackZone stack_zone(thread);
-      HANDLESCOPE(thread);
-      EXPECT(func_.HasCode());
-      EXPECT(!func_.HasOptimizedCode());
-      const Error& err =
-          Error::Handle(Compiler::CompileOptimizedFunction(thread, func_));
-      EXPECT(err.IsNull());
-      EXPECT(func_.HasOptimizedCode());
-    }
-    Thread::ExitIsolateAsHelper();
-    // Tell main thread that we are done.
-    {
-      MonitorLocker ml(done_monitor_);
-      ASSERT(!*done_);
-      *done_ = true;
-      ml.Notify();
-    }
-  }
-
- private:
-  Isolate* isolate_;
-  const Function& func_;
-  Monitor* done_monitor_;
-  bool* done_;
-};
-
-
 TEST_CASE(CompileFunctionOnHelperThread) {
-  Monitor done_monitor;
-  bool done = false;
-  Isolate* isolate = Thread::Current()->isolate();
-  // Flush store buffers, etc.
-  // TODO(koda): Currently, the GC only does this for the current thread, (i.e,
-  // the helper, in this test), but it should be done for all *threads*
-  // after/at safepointing.
-  Thread::PrepareForGC();
-
   // Create a simple function and compile it without optimization.
   const char* kScriptChars =
             "class A {\n"
@@ -147,19 +98,18 @@
   CompilerTest::TestCompileFunction(func);
   EXPECT(func.HasCode());
   EXPECT(!func.HasOptimizedCode());
-
-  // Now optimize it on a helper thread.
-  Dart::thread_pool()->Run(
-      new CompileFunctionTask(isolate, func, &done_monitor, &done));
-  {
-    // Manually wait.
-    // TODO(koda): Replace with execution of Dart and/or VM code when GC
-    // actually safepoints everything.
-    MonitorLocker ml(&done_monitor);
-    while (!done) {
-      ml.Wait();
-    }
+  FLAG_background_compilation = true;
+  BackgroundCompiler::EnsureInit(thread);
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate->background_compiler() != NULL);
+  isolate->background_compiler()->CompileOptimized(func);
+  Monitor* m = new Monitor();
+  MonitorLocker ml(m);
+  while (!func.HasOptimizedCode()) {
+    Isolate::Current()->thread_registry()->CheckSafepoint();
+    ml.Wait(1);
   }
+  BackgroundCompiler::Stop(isolate->background_compiler());
 }
 
 
diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc
index 61c09a6..695c23c 100644
--- a/runtime/vm/constant_propagator.cc
+++ b/runtime/vm/constant_propagator.cc
@@ -19,6 +19,8 @@
 DEFINE_FLAG(bool, trace_constant_propagation, false,
     "Print constant propagation and useless code elimination.");
 
+DECLARE_FLAG(bool, fields_may_be_reset);
+
 // Quick access to the current zone and isolate.
 #define I (isolate())
 #define Z (graph_->zone())
@@ -704,14 +706,16 @@
 
 
 void ConstantPropagator::VisitLoadStaticField(LoadStaticFieldInstr* instr) {
-  const Field& field = instr->StaticField();
-  ASSERT(field.is_static());
-  Instance& obj = Instance::Handle(Z, field.StaticValue());
-  if (field.is_final() && (obj.raw() != Object::sentinel().raw()) &&
-      (obj.raw() != Object::transition_sentinel().raw())) {
-    if (obj.IsSmi() || obj.IsOld()) {
-      SetValue(instr, obj);
-      return;
+  if (!FLAG_fields_may_be_reset) {
+    const Field& field = instr->StaticField();
+    ASSERT(field.is_static());
+    Instance& obj = Instance::Handle(Z, field.StaticValue());
+    if (field.is_final() && (obj.raw() != Object::sentinel().raw()) &&
+        (obj.raw() != Object::transition_sentinel().raw())) {
+      if (obj.IsSmi() || obj.IsOld()) {
+        SetValue(instr, obj);
+        return;
+      }
     }
   }
   SetValue(instr, non_constant_);
@@ -739,7 +743,7 @@
   const Object& value = def->constant_value();
   if (IsNonConstant(value)) {
     const AbstractType& checked_type = instr->type();
-    intptr_t value_cid = instr->value()->Type()->ToCid();
+    intptr_t value_cid = instr->value()->definition()->Type()->ToCid();
     Representation rep = def->representation();
     if ((checked_type.IsFloat32x4Type() && (rep == kUnboxedFloat32x4)) ||
         (checked_type.IsInt32x4Type() && (rep == kUnboxedInt32x4)) ||
@@ -760,8 +764,7 @@
     if (value.IsInstance()) {
       const Instance& instance = Instance::Cast(value);
       const AbstractType& checked_type = instr->type();
-      if (instr->instantiator()->BindsToConstantNull() &&
-          instr->instantiator_type_arguments()->BindsToConstantNull()) {
+      if (instr->instantiator_type_arguments()->BindsToConstantNull()) {
         const TypeArguments& checked_type_arguments = TypeArguments::Handle();
         Error& bound_error = Error::Handle();
         bool is_instance = instance.IsInstanceOf(checked_type,
@@ -863,7 +866,7 @@
   if (IsConstant(object)) {
     if (instr->type().IsTypeParameter()) {
       if (object.IsNull()) {
-        SetValue(instr, Type::ZoneHandle(Z, Type::DynamicType()));
+        SetValue(instr, Object::dynamic_type());
         return;
       }
       // We could try to instantiate the type parameter and return it if no
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 9bd7640..24110b4 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -26,31 +26,37 @@
 
 
 enum Register {
-  kNoRegister = -1,
-  kFirstFreeCpuRegister = 0,
   R0  =  0,
   R1  =  1,
   R2  =  2,
   R3  =  3,
   R4  =  4,
-  R5  =  5,
-  R6  =  6,
-  R7  =  7,
+  R5  =  5,  // PP
+  R6  =  6,  // CTX
+  R7  =  7,  // iOS FP
   R8  =  8,
   R9  =  9,
-  R10 = 10,
-  R11 = 11,
-  R12 = 12,
-  R13 = 13,
-  R14 = 14,
-  kLastFreeCpuRegister = 14,
-  R15 = 15,
-  FP  = R11,
+  R10 = 10,  // THR
+  R11 = 11,  // Linux FP
+  R12 = 12,  // IP aka TMP
+  R13 = 13,  // SP
+  R14 = 14,  // LR
+  R15 = 15,  // PC
+  kNumberOfCpuRegisters = 16,
+  kNoRegister = -1,  // Signals an illegal register.
+
+  // Aliases.
+#if defined(TARGET_OS_MACOS)
+  FP   = R7,
+  NOTFP = R11,
+#else
+  FP   = R11,
+  NOTFP = R7,
+#endif
   IP  = R12,
   SP  = R13,
   LR  = R14,
   PC  = R15,
-  kNumberOfCpuRegisters = 16,
 };
 
 
@@ -231,15 +237,15 @@
 // Register aliases.
 const Register TMP = IP;  // Used as scratch register by assembler.
 const Register TMP2 = kNoRegister;  // There is no second assembler temporary.
-const Register CTX = R10;  // Location of current context at method entry.
-const Register PP = R9;  // Caches object pool pointer in generated code.
+const Register CTX = R6;  // Location of current context at method entry.
+const Register PP = R5;  // Caches object pool pointer in generated code.
 const Register SPREG = SP;  // Stack pointer register.
 const Register FPREG = FP;  // Frame pointer register.
 const Register LRREG = LR;  // Link register.
-const Register ICREG = R5;  // IC data register.
+const Register ICREG = R9;  // IC data register.
 const Register ARGS_DESC_REG = R4;
-const Register CODE_REG = R10;
-const Register THR = R8;  // Caches current thread in generated code.
+const Register CODE_REG = R6;
+const Register THR = R10;  // Caches current thread in generated code.
 
 // R15 encodes APSR in the vmrs instruction.
 const Register APSR = R15;
@@ -261,24 +267,39 @@
 // C++ ABI call registers.
 const RegList kAbiArgumentCpuRegs =
     (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3);
+#if defined(TARGET_OS_MACOS)
+const RegList kAbiPreservedCpuRegs =
+    (1 << R4)  | (1 << R5) | (1 << R6) | (1 << R8) |
+    (1 << R10) | (1 << R11);
+const int kAbiPreservedCpuRegCount = 6;
+#else
 const RegList kAbiPreservedCpuRegs =
     (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) |
     (1 << R8) | (1 << R9) | (1 << R10);
 const int kAbiPreservedCpuRegCount = 7;
+#endif
 const QRegister kAbiFirstPreservedFpuReg = Q4;
 const QRegister kAbiLastPreservedFpuReg = Q7;
 const int kAbiPreservedFpuRegCount = 4;
 
+const RegList kReservedCpuRegisters =
+    (1 << SPREG) |
+    (1 << FPREG) |
+    (1 << TMP)   |
+    (1 << PP)    |
+    (1 << THR)   |
+    (1 << PC);
 // CPU registers available to Dart allocator.
 const RegList kDartAvailableCpuRegs =
-    (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
-    (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) |
-    (1 << R8) | (1 << R14);
-
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
 // Registers available to Dart that are not preserved by runtime calls.
 const RegList kDartVolatileCpuRegs =
     kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
+#if defined(TARGET_OS_MACOS)
+const int kDartVolatileCpuRegCount = 6;
+#else
 const int kDartVolatileCpuRegCount = 5;
+#endif
 const QRegister kDartFirstVolatileFpuReg = Q0;
 const QRegister kDartLastVolatileFpuReg = Q3;
 const int kDartVolatileFpuRegCount = 4;
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index ab76fd1..913a69c 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -10,7 +10,6 @@
 namespace dart {
 
 enum Register {
-  kFirstFreeCpuRegister = 0,
   R0  =  0,
   R1  =  1,
   R2  =  2,
@@ -26,10 +25,10 @@
   R12 = 12,
   R13 = 13,
   R14 = 14,
-  R15 = 15,
+  R15 = 15,  // SP in Dart code.
   R16 = 16,  // IP0 aka TMP
   R17 = 17,  // IP1 aka TMP2
-  R18 = 18,  // SP in Dart code.
+  R18 = 18,  // "platform register" on iOS.
   R19 = 19,
   R20 = 20,
   R21 = 21,
@@ -37,8 +36,7 @@
   R23 = 23,
   R24 = 24,
   R25 = 25,
-  R26 = 26,
-  kLastFreeCpuRegister = 26,
+  R26 = 26,  // THR
   R27 = 27,  // PP
   R28 = 28,  // CTX
   R29 = 29,  // FP
@@ -55,11 +53,12 @@
   // Aliases.
   IP0 = R16,
   IP1 = R17,
-  SP = R18,
+  SP = R15,
   FP = R29,
   LR = R30,
 };
 
+
 enum VRegister {
   V0  =  0,
   V1  =  1,
@@ -113,11 +112,12 @@
 const Register PP = R27;  // Caches object pool pointer in generated code.
 const Register CODE_REG = R24;
 const Register FPREG = FP;  // Frame pointer register.
-const Register SPREG = R18;  // Stack pointer register.
+const Register SPREG = R15;  // Stack pointer register.
 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.
+const Register THR = R26;  // Caches current thread in generated code.
+
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
@@ -153,21 +153,27 @@
 const VRegister kAbiLastPreservedFpuReg = V15;
 const int kAbiPreservedFpuRegCount = 8;
 
+const intptr_t kReservedCpuRegisters =
+    (1 << SPREG) |  // Dart SP
+    (1 << FPREG) |
+    (1 << TMP)   |
+    (1 << TMP2)  |
+    (1 << PP)    |
+    (1 << THR)   |
+    (1 << LR)    |
+    (1 << R31)   |  // C++ SP
+    (1 << CTX)   |
+    (1 << R18);     // iOS platform register.
+                    // TODO(rmacnak): Only reserve on Mac & iOS.
 // CPU registers available to Dart allocator.
 const RegList kDartAvailableCpuRegs =
-    (1 << R0)  | (1 << R1)  | (1 << R2)  | (1 << R3)  |
-    (1 << R4)  | (1 << R5)  | (1 << R6)  | (1 << R7)  |
-    (1 << R8)  | (1 << R9)  | (1 << R10) | (1 << R11) |
-    (1 << R12) | (1 << R13) | (1 << R14) | (1 << R15) |
-    (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) |
-    (1 << R23) | (1 << R24) | (1 << R25) | (1 << R26);
-
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
 // Registers available to Dart that are not preserved by runtime calls.
 const RegList kDartVolatileCpuRegs =
     kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
 const Register kDartFirstVolatileCpuReg = R0;
-const Register kDartLastVolatileCpuReg = R15;
-const int kDartVolatileCpuRegCount = 16;
+const Register kDartLastVolatileCpuReg = R14;
+const int kDartVolatileCpuRegCount = 15;
 const int kDartVolatileFpuRegCount = 24;
 
 static inline Register ConcreteRegister(Register r) {
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 0950639..466dd42 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -10,7 +10,6 @@
 namespace dart {
 
 enum Register {
-  kFirstFreeCpuRegister = 0,
   EAX = 0,
   ECX = 1,
   EDX = 2,
@@ -19,9 +18,8 @@
   EBP = 5,
   ESI = 6,
   EDI = 7,
-  kLastFreeCpuRegister = 7,
   kNumberOfCpuRegisters = 8,
-  kNoRegister = -1  // Signals an illegal register.
+  kNoRegister = -1,  // Signals an illegal register.
 };
 
 
@@ -71,6 +69,7 @@
 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.
 const Register kExceptionObjectReg = EAX;
@@ -80,6 +79,18 @@
 const Register kStackTraceObjectReg = EDX;
 
 
+typedef uint32_t RegList;
+const RegList kAllCpuRegistersList = 0xFF;
+
+const intptr_t kReservedCpuRegisters =
+    (1 << SPREG) |
+    (1 << FPREG) |
+    (1 << THR);
+// CPU registers available to Dart allocator.
+const RegList kDartAvailableCpuRegs =
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
+
+
 enum ScaleFactor {
   TIMES_1 = 0,
   TIMES_2 = 1,
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index fed178f..ccf437a 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -11,8 +11,7 @@
 
 enum Register {
   R0  =  0,
-  R1  =  1,
-  kFirstFreeCpuRegister = 2,
+  R1  =  1,  // AT aka TMP
   R2  =  2,
   R3  =  3,
   R4  =  4,
@@ -30,23 +29,23 @@
   R16 = 16,
   R17 = 17,
   R18 = 18,
-  R19 = 19,
+  R19 = 19,  // THR
   R20 = 20,
   R21 = 21,
-  kLastFreeCpuRegister = 21,
-  R22 = 22,
-  R23 = 23,
+  R22 = 22,  // CTX
+  R23 = 23,  // PP
   R24 = 24,
   R25 = 25,
   R26 = 26,
   R27 = 27,
   R28 = 28,
-  R29 = 29,
-  R30 = 30,
-  R31 = 31,
+  R29 = 29,  // SP
+  R30 = 30,  // FP
+  R31 = 31,  // RA
   kNumberOfCpuRegisters = 32,
   IMM = 32,  // Positive value is easier to encode than kNoRegister in bitfield.
-  kNoRegister = -1,
+  kNoRegister = -1,  // Signals an illegal register.
+
 
   // Register aliases.
   ZR = R0,
@@ -188,6 +187,7 @@
 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,
 // CMPRES1 and CMPRES2 are used for the results of the comparison. We need two
@@ -207,7 +207,6 @@
 typedef uint32_t RegList;
 const RegList kAllCpuRegistersList = 0xFFFFFFFF;
 
-
 const RegList kAbiArgumentCpuRegs =
     (1 << A0) | (1 << A1) | (1 << A2) | (1 << A3);
 const RegList kAbiPreservedCpuRegs =
@@ -221,13 +220,24 @@
     static_cast<FRegister>(kNumberOfFRegisters - 1);
 const int kAbiPreservedFpuRegCount = 12;
 
+const RegList kReservedCpuRegisters =
+    (1 << SPREG)   |
+    (1 << FPREG)   |
+    (1 << TMP)     |
+    (1 << PP)      |
+    (1 << THR)     |
+    (1 << CTX)     |
+    (1 << ZR)      |
+    (1 << CMPRES1) |
+    (1 << CMPRES2) |
+    (1 << K0)      |
+    (1 << K1)      |
+    (1 << GP)      |
+    (1 << RA);
 // CPU registers available to Dart allocator.
 const RegList kDartAvailableCpuRegs =
-    (1 << R2) | (1 << R3) | (1 << R4) | (1 << R5) |
-    (1 << R6) | (1 << R7) | (1 << R8) | (1 << R9) |
-    (1 << R10) | (1 << R11) | (1 << R12) | (1 << R13) |
-    (1 << R14) | (1 << R15) | (1 << R16) | (1 << R17) |
-    (1 << R18) | (1 << R19) | (1 << R20) | (1 << R21);
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
+// Registers available to Dart that are not preserved by runtime calls.
 const RegList kDartVolatileCpuRegs =
     kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
 const int kDartVolatileCpuRegCount = 14;
@@ -429,6 +439,7 @@
   COP1_DIV = 0x03,
   COP1_SQRT = 0x04,
   COP1_MOV = 0x06,
+  COP1_NEG = 0x07,
   COP1_CVT_S = 0x20,
   COP1_CVT_D = 0x21,
   COP1_CVT_W = 0x24,
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index c2b48c5..9c92faa 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -8,7 +8,6 @@
 namespace dart {
 
 enum Register {
-  kFirstFreeCpuRegister = 0,
   RAX = 0,
   RCX = 1,
   RDX = 2,
@@ -25,9 +24,8 @@
   R13 = 13,
   R14 = 14,
   R15 = 15,
-  kLastFreeCpuRegister = 15,
   kNumberOfCpuRegisters = 16,
-  kNoRegister = -1  // Signals an illegal register.
+  kNoRegister = -1,  // Signals an illegal register.
 };
 
 
@@ -96,6 +94,7 @@
 const Register CODE_REG = R12;
 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.
 const Register kExceptionObjectReg = RAX;
@@ -105,6 +104,20 @@
 const Register kStackTraceObjectReg = RDX;
 
 
+typedef uint32_t RegList;
+const RegList kAllCpuRegistersList = 0xFFFF;
+
+const RegList kReservedCpuRegisters =
+    (1 << SPREG) |
+    (1 << FPREG) |
+    (1 << TMP)   |
+    (1 << PP)    |
+    (1 << THR);
+// CPU registers available to Dart allocator.
+const RegList kDartAvailableCpuRegs =
+    kAllCpuRegistersList & ~kReservedCpuRegisters;
+
+
 enum ScaleFactor {
   TIMES_1 = 0,
   TIMES_2 = 1,
diff --git a/runtime/vm/coverage.cc b/runtime/vm/coverage.cc
index 73fb5b6..42dff5e 100644
--- a/runtime/vm/coverage.cc
+++ b/runtime/vm/coverage.cc
@@ -83,7 +83,7 @@
   // Print the hit counts for all IC datas.
   ZoneGrowableArray<const ICData*>* ic_data_array =
       new(zone) ZoneGrowableArray<const ICData*>();
-  function.RestoreICDataMap(ic_data_array);
+  function.RestoreICDataMap(ic_data_array, false /* clone descriptors */);
   const PcDescriptors& descriptors = PcDescriptors::Handle(
       zone, code.pc_descriptors());
 
@@ -191,41 +191,44 @@
     }
   }
 
-  GrowableObjectArray& closures =
-      GrowableObjectArray::Handle(cls.closures());
-  if (!closures.IsNull()) {
-    i = 0;
-    pos_to_line.Clear();
-    // We need to keep rechecking the length of the closures array, as handling
-    // a closure potentially adds new entries to the end.
+  // TODO(turnidge): This looks like it prints closures many, many times.
+  const GrowableObjectArray& closures = GrowableObjectArray::Handle(
+      thread->isolate()->object_store()->closure_functions());
+  pos_to_line.Clear();
+  // We need to keep rechecking the length of the closures array, as handling
+  // a closure potentially adds new entries to the end.
+  i = 0;
+  while (i < closures.Length()) {
+    HANDLESCOPE(thread);
+    function ^= closures.At(i);
+    if (function.Owner() != cls.raw()) {
+      i++;
+      continue;
+    }
+    script = function.script();
+    saved_url = script.url();
+    if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
+      i++;
+      continue;
+    }
+    ComputeTokenPosToLineNumberMap(script, &pos_to_line);
+    JSONObject jsobj(&jsarr);
+    jsobj.AddProperty("source", saved_url.ToCString());
+    jsobj.AddProperty("script", script);
+    JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");
+
+    // We stay within this loop while we are seeing functions from the same
+    // source URI.
     while (i < closures.Length()) {
-      HANDLESCOPE(thread);
       function ^= closures.At(i);
       script = function.script();
-      saved_url = script.url();
-      if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) {
-        i++;
-        continue;
+      url = script.url();
+      if (!url.Equals(saved_url)) {
+        pos_to_line.Clear();
+        break;
       }
-      ComputeTokenPosToLineNumberMap(script, &pos_to_line);
-      JSONObject jsobj(&jsarr);
-      jsobj.AddProperty("source", saved_url.ToCString());
-      jsobj.AddProperty("script", script);
-      JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");
-
-      // We stay within this loop while we are seeing functions from the same
-      // source URI.
-      while (i < closures.Length()) {
-        function ^= closures.At(i);
-        script = function.script();
-        url = script.url();
-        if (!url.Equals(saved_url)) {
-          pos_to_line.Clear();
-          break;
-        }
-        CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
-        i++;
-      }
+      CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
+      i++;
     }
   }
 }
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index 44964d2..491468a 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -78,7 +78,12 @@
 #endif
 
 void CPU::FlushICache(uword start, uword size) {
-#if !defined(USING_SIMULATOR)
+#if TARGET_OS_IOS
+  // Precompilation never patches code so there should be no I cache flushes.
+  UNREACHABLE();
+#endif
+
+#if !defined(USING_SIMULATOR) && !TARGET_OS_IOS
   // Nothing to do. Flushing no instructions.
   if (size == 0) {
     return;
@@ -123,6 +128,25 @@
 
 
 #if !defined(USING_SIMULATOR)
+#if TARGET_OS_IOS
+void HostCPUFeatures::InitOnce() {
+  // TODO(24743): Actually check the CPU features and fail if we're missing
+  // something assumed in a precompiled snapshot.
+  hardware_ = "";
+  // When the VM is targetted to ARMv7, pretend that the CPU is ARMv7 even if
+  // the CPU is actually AArch64.
+  arm_version_ = ARMv7;
+  // Always assume we have floating point unit since we dont support ARMv6 in
+  // this path.
+  vfp_supported_ = FLAG_use_vfp;
+  integer_division_supported_ = FLAG_use_integer_division;
+  neon_supported_ = FLAG_use_neon;
+  hardfp_supported_ = true;
+#if defined(DEBUG)
+  initialized_ = true;
+#endif
+}
+#else  // TARGET_OS_IOS
 void HostCPUFeatures::InitOnce() {
   bool is_arm64 = false;
   CpuInfo::InitOnce();
@@ -197,7 +221,7 @@
   initialized_ = true;
 #endif
 }
-
+#endif  // TARGET_OS_IOS
 
 void HostCPUFeatures::Cleanup() {
   DEBUG_ASSERT(initialized_);
diff --git a/runtime/vm/cpu_arm64.cc b/runtime/vm/cpu_arm64.cc
index d9ec03b..881aebc 100644
--- a/runtime/vm/cpu_arm64.cc
+++ b/runtime/vm/cpu_arm64.cc
@@ -18,7 +18,12 @@
 namespace dart {
 
 void CPU::FlushICache(uword start, uword size) {
-#if !defined(USING_SIMULATOR)
+#if TARGET_OS_IOS
+  // Precompilation never patches code so there should be no I cache flushes.
+  UNREACHABLE();
+#endif
+
+#if !defined(USING_SIMULATOR) && !TARGET_OS_IOS
   // Nothing to do. Flushing no instructions.
   if (size == 0) {
     return;
diff --git a/runtime/vm/custom_isolate_test.cc b/runtime/vm/custom_isolate_test.cc
index 2cb2e00..b78ea60 100644
--- a/runtime/vm/custom_isolate_test.cc
+++ b/runtime/vm/custom_isolate_test.cc
@@ -243,7 +243,7 @@
 }
 
 
-const char* saved_echo = NULL;
+char* saved_echo = NULL;
 static void native_echo(Dart_NativeArguments args) {
   Dart_EnterScope();
   Dart_Handle arg = Dart_GetNativeArgument(args, 0);
@@ -252,7 +252,7 @@
   const char* c_str = NULL;
   EXPECT_VALID(Dart_StringToCString(toString, &c_str));
   if (saved_echo) {
-    free(const_cast<char*>(saved_echo));
+    free(saved_echo);
   }
   saved_echo = strdup(c_str);
   OS::Print("-- (isolate=%p) %s\n", Dart_CurrentIsolate(), c_str);
@@ -350,7 +350,7 @@
   }
   OS::Print("-- Finished event loop --\n");
   EXPECT_STREQ("Received: 43", saved_echo);
-  free(const_cast<char*>(saved_echo));
+  free(saved_echo);
 
   delete event_queue;
   event_queue = NULL;
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 8ed714a..a9ddae5 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -38,7 +38,7 @@
 DECLARE_FLAG(bool, trace_time_all);
 DEFINE_FLAG(bool, keep_code, false,
             "Keep deoptimized code for profiling.");
-DEFINE_FLAG(bool, shutdown, false, "Do a clean shutdown of the VM");
+DEFINE_FLAG(bool, shutdown, true, "Do a clean shutdown of the VM");
 
 Isolate* Dart::vm_isolate_ = NULL;
 ThreadPool* Dart::thread_pool_ = NULL;
@@ -73,14 +73,13 @@
 const char* Dart::InitOnce(const uint8_t* vm_isolate_snapshot,
                            const uint8_t* instructions_snapshot,
                            Dart_IsolateCreateCallback create,
-                           Dart_IsolateInterruptCallback interrupt,
-                           Dart_IsolateUnhandledExceptionCallback unhandled,
                            Dart_IsolateShutdownCallback shutdown,
                            Dart_FileOpenCallback file_open,
                            Dart_FileReadCallback file_read,
                            Dart_FileWriteCallback file_write,
                            Dart_FileCloseCallback file_close,
-                           Dart_EntropySource entropy_source) {
+                           Dart_EntropySource entropy_source,
+                           Dart_GetVMServiceAssetsArchive get_service_assets) {
   // TODO(iposva): Fix race condition here.
   if (vm_isolate_ != NULL || !Flags::Initialized()) {
     return "VM already initialized or flags not initialized.";
@@ -89,8 +88,7 @@
   Isolate::SetEntropySourceCallback(entropy_source);
   OS::InitOnce();
   VirtualMemory::InitOnce();
-  Thread::InitOnceBeforeIsolate();
-  Thread::EnsureInit();
+  OSThread::InitOnce();
   Timeline::InitOnce();
   TimelineDurationScope tds(Timeline::GetVMStream(),
                             "Dart::InitOnce");
@@ -105,7 +103,6 @@
   Metric::InitOnce();
   StoreBuffer::InitOnce();
   MarkingStack::InitOnce();
-  Thread::EnsureInit();
 
 #if defined(USING_SIMULATOR)
   Simulator::InitOnce();
@@ -117,8 +114,6 @@
   ASSERT(thread_pool_ == NULL);
   thread_pool_ = new ThreadPool();
   {
-    Thread* T = Thread::Current();
-    ASSERT(T != NULL);
     ASSERT(vm_isolate_ == NULL);
     ASSERT(Flags::Initialized());
     const bool is_vm_isolate = true;
@@ -134,6 +129,8 @@
     ASSERT(vm_isolate_ == Isolate::Current());
     ASSERT(vm_isolate_ == Thread::Current()->isolate());
 
+    Thread* T = Thread::Current();
+    ASSERT(T != NULL);
     StackZone zone(T);
     HandleScope handle_scope(T);
     Object::InitNull(vm_isolate_);
@@ -141,6 +138,7 @@
     TargetCPUFeatures::InitOnce();
     Object::InitOnce(vm_isolate_);
     ArgumentsDescriptor::InitOnce();
+    ICData::InitOnce();
     // When precompiled the stub code is initialized from the snapshot.
     if (!precompiled) {
       StubCode::InitOnce();
@@ -176,9 +174,9 @@
     } else {
       Symbols::InitOnce(vm_isolate_);
     }
-    Thread::InitOnceAfterObjectAndStubCode();
-    // Now that the needed stub has been generated, set the stack limit.
-    vm_isolate_->InitializeStackLimit();
+    // We need to initialize the constants here for the vm isolate thread due to
+    // bootstrapping issues.
+    T->InitVMConstants();
     Scanner::InitOnce();
 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
     // Dart VM requires at least SSE2.
@@ -197,10 +195,9 @@
 
   Thread::ExitIsolate();  // Unregister the VM isolate from this thread.
   Isolate::SetCreateCallback(create);
-  Isolate::SetInterruptCallback(interrupt);
-  Isolate::SetUnhandledExceptionCallback(unhandled);
   Isolate::SetShutdownCallback(shutdown);
 
+  Service::SetGetServiceAssetsCallback(get_service_assets);
   ServiceIsolate::Run();
 
   return NULL;
@@ -228,6 +225,15 @@
   // Shut down profiling.
   Profiler::Shutdown();
 
+  {
+    // Set the VM isolate as current isolate when shutting down
+    // Metrics so that we can use a StackZone.
+    bool result = Thread::EnterIsolate(vm_isolate_);
+    ASSERT(result);
+    Metric::Cleanup();
+    Thread::ExitIsolate();
+  }
+
   if (FLAG_shutdown) {
     // Disable the creation of new isolates.
     Isolate::DisableIsolateCreation();
@@ -246,9 +252,17 @@
     delete thread_pool_;
     thread_pool_ = NULL;
 
+    // Disable creation of any new OSThread structures which means no more new
+    // threads can do an EnterIsolate. This must come after isolate shutdown
+    // because new threads may need to be spawned to shutdown the isolates.
+    // This must come after deletion of the thread pool to avoid a race in which
+    // a thread spawned by the thread pool does not exit through the thread
+    // pool, messing up its bookkeeping.
+    OSThread::DisableOSThreadCreation();
+
     // Set the VM isolate as current isolate.
-    Thread::EnsureInit();
-    Thread::EnterIsolate(vm_isolate_);
+    bool result = Thread::EnterIsolate(vm_isolate_);
+    ASSERT(result);
 
     ShutdownIsolate();
     vm_isolate_ = NULL;
@@ -257,15 +271,22 @@
     TargetCPUFeatures::Cleanup();
     StoreBuffer::ShutDown();
 
-    Thread::Shutdown();
+    // Delete the current thread's TLS and set it's TLS to null.
+    // If it is the last thread then the destructor would call
+    // OSThread::Cleanup.
+    OSThread* os_thread = OSThread::Current();
+    OSThread::SetCurrent(NULL);
+    delete os_thread;
   } else {
     // Shutdown the service isolate.
     ServiceIsolate::Shutdown();
+
+    // Disable thread creation.
+    OSThread::DisableOSThreadCreation();
   }
 
   CodeObservers::DeleteAll();
   Timeline::Shutdown();
-  Metric::Cleanup();
 
   return NULL;
 }
@@ -295,9 +316,6 @@
     ObjectStore::Init(I);
   }
 
-  // Setup for profiling.
-  Profiler::InitProfilingForIsolate(I);
-
   const Error& error = Error::Handle(Object::Init(I));
   if (!error.IsNull()) {
     return error.raw();
@@ -352,6 +370,10 @@
   if (!Dart::IsRunningPrecompiledCode()) {
     MegamorphicCacheTable::InitMissHandler(I);
   }
+  const Code& miss_code =
+      Code::Handle(I->object_store()->megamorphic_miss_code());
+  I->set_ic_miss_code(miss_code);
+
   if (snapshot_buffer == NULL) {
     if (!I->object_store()->PreallocateObjects()) {
       return I->object_store()->sticky_error();
@@ -395,6 +417,18 @@
 }
 
 
+void Dart::ShutdownIsolate(Isolate* isolate) {
+  ASSERT(Isolate::Current() == NULL);
+  // We need to enter the isolate in order to shut it down.
+  bool result = Thread::EnterIsolate(isolate);
+  ASSERT(result);
+  ShutdownIsolate();
+  // Since the isolate is shutdown and deleted, there is no need to
+  // exit the isolate here.
+  ASSERT(Isolate::Current() == NULL);
+}
+
+
 void Dart::ShutdownIsolate() {
   Isolate* isolate = Isolate::Current();
   isolate->Shutdown();
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 5ae0550..412eef2 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -24,20 +24,20 @@
       const uint8_t* vm_isolate_snapshot,
       const uint8_t* instructions_snapshot,
       Dart_IsolateCreateCallback create,
-      Dart_IsolateInterruptCallback interrupt,
-      Dart_IsolateUnhandledExceptionCallback unhandled,
       Dart_IsolateShutdownCallback shutdown,
       Dart_FileOpenCallback file_open,
       Dart_FileReadCallback file_read,
       Dart_FileWriteCallback file_write,
       Dart_FileCloseCallback file_close,
-      Dart_EntropySource entropy_source);
+      Dart_EntropySource entropy_source,
+      Dart_GetVMServiceAssetsArchive get_service_assets);
   static const char* Cleanup();
 
   static Isolate* CreateIsolate(const char* name_prefix,
                                 const Dart_IsolateFlags& api_flags);
   static RawError* InitializeIsolate(const uint8_t* snapshot, void* data);
   static void RunShutdownCallback();
+  static void ShutdownIsolate(Isolate* isolate);
   static void ShutdownIsolate();
 
   static Isolate* vm_isolate() { return vm_isolate_; }
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 55a352f..796aaca 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -52,18 +52,17 @@
 
 
 DECLARE_FLAG(bool, load_deferred_eagerly);
+DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, print_class_table);
 DECLARE_FLAG(bool, verify_handles);
 #if defined(DART_NO_SNAPSHOT)
 DEFINE_FLAG(bool, check_function_fingerprints, true,
             "Check function fingerprints");
 #endif  // defined(DART_NO_SNAPSHOT).
-DEFINE_FLAG(bool, trace_api, false,
-            "Trace invocation of API calls (debug mode only)");
 DEFINE_FLAG(bool, verify_acquired_data, false,
             "Verify correct API acquire/release of typed data.");
 
-ThreadLocalKey Api::api_native_key_ = OSThread::kUnsetThreadLocalKey;
+ThreadLocalKey Api::api_native_key_ = kUnsetThreadLocalKey;
 Dart_Handle Api::true_handle_ = NULL;
 Dart_Handle Api::false_handle_ = NULL;
 Dart_Handle Api::null_handle_ = NULL;
@@ -78,6 +77,20 @@
   }
 }
 
+#if 0
+#define API_TIMELINE_DURATION                                                  \
+  TimelineDurationScope tds(Thread::Current(),                                 \
+                            Timeline::GetVMApiStream(),                        \
+                            CURRENT_FUNC)
+
+#define API_TIMELINE_BEGIN_END                                                 \
+  TimelineBeginEndScope tbes(Thread::Current(),                                \
+                             Timeline::GetVMApiStream(),                       \
+                             CURRENT_FUNC)
+#else
+#define API_TIMELINE_DURATION ASSERT(true)
+#define API_TIMELINE_BEGIN_END ASSERT(true)
+#endif
 
 #if defined(DEBUG)
 // An object visitor which will iterate over all the function objects in the
@@ -173,16 +186,14 @@
     return true;
   }
   Thread* thread = arguments->thread();
-  Isolate* isolate = thread->isolate();
-  ASSERT(isolate == Isolate::Current());
+  ASSERT(thread == Thread::Current());
   *peer = NULL;
   REUSABLE_OBJECT_HANDLESCOPE(thread);
   Object& obj = thread->ObjectHandle();
   obj = arguments->NativeArgAt(arg_index);
   if (RawObject::IsStringClassId(obj.GetClassId())) {
-    ASSERT(isolate->api_state() &&
-           isolate->api_state()->top_scope() != NULL);
-    *str = Api::NewHandle(isolate, obj.raw());
+    ASSERT(thread->api_top_scope() != NULL);
+    *str = Api::NewHandle(thread, obj.raw());
     return true;
   }
   if (obj.IsNull()) {
@@ -300,8 +311,8 @@
 }
 
 
-Heap::Space SpaceForExternal(Isolate* isolate, intptr_t size) {
-  Heap* heap = isolate->heap();
+Heap::Space SpaceForExternal(Thread* thread, intptr_t size) {
+  Heap* heap = thread->heap();
   // If 'size' would be a significant fraction of new space, then use old.
   static const int kExtNewRatio = 16;
   if (size > (heap->CapacityInWords(Heap::kNew) * kWordSize) / kExtNewRatio) {
@@ -346,18 +357,8 @@
 }
 
 
-WeakReferenceSetBuilder* ApiState::NewWeakReferenceSetBuilder() {
-  return new WeakReferenceSetBuilder(this);
-}
-
-
-void ApiState::DelayWeakReferenceSet(WeakReferenceSet* reference_set) {
-  WeakReferenceSet::Push(reference_set, &delayed_weak_reference_sets_);
-}
-
-
-Dart_Handle Api::InitNewHandle(Isolate* isolate, RawObject* raw) {
-  LocalHandles* local_handles = Api::TopScope(isolate)->local_handles();
+Dart_Handle Api::InitNewHandle(Thread* thread, RawObject* raw) {
+  LocalHandles* local_handles = Api::TopScope(thread)->local_handles();
   ASSERT(local_handles != NULL);
   LocalHandle* ref = local_handles->AllocateHandle();
   ref->set_raw(raw);
@@ -365,7 +366,7 @@
 }
 
 
-Dart_Handle Api::NewHandle(Isolate* isolate, RawObject* raw) {
+Dart_Handle Api::NewHandle(Thread* thread, RawObject* raw) {
   if (raw == Object::null()) {
     return Null();
   }
@@ -375,18 +376,17 @@
   if (raw == Bool::False().raw()) {
     return False();
   }
-  return InitNewHandle(isolate, raw);
+  return InitNewHandle(thread, raw);
 }
 
 
 RawObject* Api::UnwrapHandle(Dart_Handle object) {
 #if defined(DEBUG)
-  Isolate* isolate = Isolate::Current();
-  ASSERT(isolate != NULL);
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
+  Thread* thread = Thread::Current();
+  ASSERT(thread->IsMutatorThread());
+  ASSERT(thread->isolate() != NULL);
   ASSERT(!FLAG_verify_handles ||
-         state->IsValidLocalHandle(object) ||
+         thread->IsValidLocalHandle(object) ||
          Dart::IsReadOnlyApiHandle(object));
   ASSERT(FinalizablePersistentHandle::raw_offset() == 0 &&
          PersistentHandle::raw_offset() == 0 &&
@@ -431,7 +431,8 @@
 }
 
 
-Dart_Handle Api::CheckAndFinalizePendingClasses(Isolate* isolate) {
+Dart_Handle Api::CheckAndFinalizePendingClasses(Thread* thread) {
+  Isolate* isolate = thread->isolate();
   if (!isolate->AllowClassFinalization()) {
     // Class finalization is blocked for the isolate. Do nothing.
     return Api::Success();
@@ -440,7 +441,7 @@
     return Api::Success();
   }
   ASSERT(isolate->object_store()->sticky_error() != Object::null());
-  return Api::NewHandle(isolate, isolate->object_store()->sticky_error());
+  return Api::NewHandle(thread, isolate->object_store()->sticky_error());
 }
 
 
@@ -465,7 +466,7 @@
   va_end(args2);
 
   const String& message = String::Handle(Z, String::New(buffer));
-  return Api::NewHandle(I, ApiError::New(message));
+  return Api::NewHandle(T, ApiError::New(message));
 }
 
 
@@ -486,20 +487,18 @@
 }
 
 
-ApiLocalScope* Api::TopScope(Isolate* isolate) {
-  ASSERT(isolate != NULL);
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
-  ApiLocalScope* scope = state->top_scope();
+ApiLocalScope* Api::TopScope(Thread* thread) {
+  ASSERT(thread != NULL);
+  ApiLocalScope* scope = thread->api_top_scope();
   ASSERT(scope != NULL);
   return scope;
 }
 
 
 void Api::InitOnce() {
-  ASSERT(api_native_key_ == OSThread::kUnsetThreadLocalKey);
+  ASSERT(api_native_key_ == kUnsetThreadLocalKey);
   api_native_key_ = OSThread::CreateThreadLocal();
-  ASSERT(api_native_key_ != OSThread::kUnsetThreadLocalKey);
+  ASSERT(api_native_key_ != kUnsetThreadLocalKey);
 }
 
 
@@ -689,8 +688,7 @@
     Dart_WeakPersistentHandle handle) {
 #if defined(DEBUG)
   ApiState* state = Isolate::Current()->api_state();
-  ASSERT(state->IsValidWeakPersistentHandle(handle) ||
-         state->IsValidPrologueWeakPersistentHandle(handle));
+  ASSERT(state->IsValidWeakPersistentHandle(handle));
 #endif
   return reinterpret_cast<FinalizablePersistentHandle*>(handle);
 }
@@ -708,42 +706,33 @@
   (*callback)(isolate->init_callback_data(), object, peer);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
-  if (handle->IsPrologueWeakPersistent()) {
-    state->prologue_weak_persistent_handles().FreeHandle(handle);
-  } else {
-    state->weak_persistent_handles().FreeHandle(handle);
-  }
+  state->weak_persistent_handles().FreeHandle(handle);
 }
 
 
 // --- Handles ---
 
 DART_EXPORT bool Dart_IsError(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsErrorClassId(Api::ClassId(handle));
 }
 
 
 DART_EXPORT bool Dart_IsApiError(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kApiErrorCid;
 }
 
 
 DART_EXPORT bool Dart_IsUnhandledExceptionError(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kUnhandledExceptionCid;
 }
 
 
 DART_EXPORT bool Dart_IsCompilationError(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kLanguageErrorCid;
 }
 
 
 DART_EXPORT bool Dart_IsFatalError(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kUnwindErrorCid;
 }
 
@@ -756,13 +745,14 @@
 
 
 DART_EXPORT const char* Dart_GetError(Dart_Handle handle) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
   if (obj.IsError()) {
     const Error& error = Error::Cast(obj);
     const char* str = error.ToErrorCString();
     intptr_t len = strlen(str) + 1;
-    char* str_copy = Api::TopScope(I)->zone()->Alloc<char>(len);
+    char* str_copy = Api::TopScope(T)->zone()->Alloc<char>(len);
     strncpy(str_copy, str, len);
     // Strip a possible trailing '\n'.
     if ((len > 1) && (str_copy[len - 2] == '\n')) {
@@ -787,7 +777,7 @@
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
   if (obj.IsUnhandledException()) {
     const UnhandledException& error = UnhandledException::Cast(obj);
-    return Api::NewHandle(I, error.exception());
+    return Api::NewHandle(T, error.exception());
   } else if (obj.IsError()) {
     return Api::NewError("This error is not an unhandled exception error.");
   } else {
@@ -801,7 +791,7 @@
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
   if (obj.IsUnhandledException()) {
     const UnhandledException& error = UnhandledException::Cast(obj);
-    return Api::NewHandle(I, error.stacktrace());
+    return Api::NewHandle(T, error.stacktrace());
   } else if (obj.IsError()) {
     return Api::NewError("This error is not an unhandled exception error.");
   } else {
@@ -817,7 +807,7 @@
   CHECK_CALLBACK_STATE(T);
 
   const String& message = String::Handle(Z, String::New(error));
-  return Api::NewHandle(I, ApiError::New(message));
+  return Api::NewHandle(T, ApiError::New(message));
 }
 
 
@@ -836,13 +826,12 @@
     }
   }
   const Stacktrace& stacktrace = Stacktrace::Handle(Z);
-  return Api::NewHandle(I, UnhandledException::New(obj, stacktrace));
+  return Api::NewHandle(T, UnhandledException::New(obj, stacktrace));
 }
 
 
 DART_EXPORT Dart_Handle Dart_PropagateError(Dart_Handle handle) {
   Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
   {
     const Object& obj = Object::Handle(thread->zone(),
         Api::UnwrapHandle(handle));
@@ -853,15 +842,13 @@
           CURRENT_FUNC);
     }
   }
-  if (isolate->top_exit_frame_info() == 0) {
+  if (thread->top_exit_frame_info() == 0) {
     // There are no dart frames on the stack so it would be illegal to
     // propagate an error here.
     return Api::NewError("No Dart frames on stack, cannot propagate error.");
   }
 
   // Unwind all the API scopes till the exit frame before propagating.
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
   const Error* error;
   {
     // We need to preserve the error object across the destruction of zones
@@ -870,7 +857,7 @@
     // handle for it in the surviving zone.
     NoSafepointScope no_safepoint;
     RawError* raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).raw();
-    state->UnwindScopes(isolate->top_exit_frame_info());
+    thread->UnwindScopes(thread->top_exit_frame_info());
     // Note that thread's zone is different here than at the beginning of this
     // function.
     error = &Error::Handle(thread->zone(), raw_error);
@@ -895,15 +882,15 @@
   DARTSCOPE(Thread::Current());
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
   if (obj.IsString()) {
-    return Api::NewHandle(I, obj.raw());
+    return Api::NewHandle(T, obj.raw());
   } else if (obj.IsInstance()) {
     CHECK_CALLBACK_STATE(T);
     const Instance& receiver = Instance::Cast(obj);
-    return Api::NewHandle(I, DartLibraryCalls::ToString(receiver));
+    return Api::NewHandle(T, DartLibraryCalls::ToString(receiver));
   } else {
     CHECK_CALLBACK_STATE(T);
     // This is a VM internal object. Call the C++ method of printing.
-    return Api::NewHandle(I, String::New(obj.ToCString()));
+    return Api::NewHandle(T, String::New(obj.ToCString()));
   }
 }
 
@@ -969,29 +956,32 @@
 
 DART_EXPORT Dart_Handle Dart_HandleFromPersistent(
     Dart_PersistentHandle object) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
   PersistentHandle* ref = PersistentHandle::Cast(object);
-  return Api::NewHandle(isolate, ref->raw());
+  return Api::NewHandle(thread, ref->raw());
 }
 
 
 DART_EXPORT Dart_Handle Dart_HandleFromWeakPersistent(
     Dart_WeakPersistentHandle object) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
   FinalizablePersistentHandle* weak_ref =
       FinalizablePersistentHandle::Cast(object);
-  return Api::NewHandle(isolate, weak_ref->raw());
+  return Api::NewHandle(thread, weak_ref->raw());
 }
 
 
 DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   ApiState* state = I->api_state();
   ASSERT(state != NULL);
   const Object& old_ref = Object::Handle(Z, Api::UnwrapHandle(object));
@@ -1004,6 +994,7 @@
 DART_EXPORT void Dart_SetPersistentHandle(Dart_PersistentHandle obj1,
                                           Dart_Handle obj2) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   ApiState* state = I->api_state();
   ASSERT(state != NULL);
   ASSERT(state->IsValidPersistentHandle(obj1));
@@ -1016,7 +1007,6 @@
 static Dart_WeakPersistentHandle AllocateFinalizableHandle(
     Thread* thread,
     Dart_Handle object,
-    bool is_prologue,
     void* peer,
     intptr_t external_allocation_size,
     Dart_WeakPersistentHandleFinalizer callback) {
@@ -1025,7 +1015,6 @@
   ref = Api::UnwrapHandle(object);
   FinalizablePersistentHandle* finalizable_ref =
       FinalizablePersistentHandle::New(thread->isolate(),
-                                       is_prologue,
                                        ref,
                                        peer,
                                        callback,
@@ -1046,26 +1035,6 @@
   }
   return AllocateFinalizableHandle(thread,
                                    object,
-                                   false,
-                                   peer,
-                                   external_allocation_size,
-                                   callback);
-}
-
-
-DART_EXPORT Dart_WeakPersistentHandle Dart_NewPrologueWeakPersistentHandle(
-    Dart_Handle object,
-    void* peer,
-    intptr_t external_allocation_size,
-    Dart_WeakPersistentHandleFinalizer callback) {
-  Thread* thread = Thread::Current();
-  CHECK_ISOLATE(thread->isolate());
-  if (callback == NULL) {
-    return NULL;
-  }
-  return AllocateFinalizableHandle(thread,
-                                   object,
-                                   true,
                                    peer,
                                    external_allocation_size,
                                    callback);
@@ -1096,81 +1065,7 @@
   FinalizablePersistentHandle* weak_ref =
       FinalizablePersistentHandle::Cast(object);
   weak_ref->EnsureFreeExternal(isolate);
-  if (weak_ref->IsPrologueWeakPersistent()) {
-    ASSERT(state->IsValidPrologueWeakPersistentHandle(object));
-    state->prologue_weak_persistent_handles().FreeHandle(weak_ref);
-  } else {
-    ASSERT(!state->IsValidPrologueWeakPersistentHandle(object));
-    state->weak_persistent_handles().FreeHandle(weak_ref);
-  }
-}
-
-
-DART_EXPORT bool Dart_IsPrologueWeakPersistentHandle(
-    Dart_WeakPersistentHandle object) {
-  FinalizablePersistentHandle* weak_ref =
-      FinalizablePersistentHandle::Cast(object);
-  return weak_ref->IsPrologueWeakPersistent();
-}
-
-
-DART_EXPORT Dart_WeakReferenceSetBuilder Dart_NewWeakReferenceSetBuilder() {
-  Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
-  return reinterpret_cast<Dart_WeakReferenceSetBuilder>(
-      state->NewWeakReferenceSetBuilder());
-}
-
-
-DART_EXPORT Dart_WeakReferenceSet Dart_NewWeakReferenceSet(
-    Dart_WeakReferenceSetBuilder set_builder,
-    Dart_WeakPersistentHandle key,
-    Dart_WeakPersistentHandle value) {
-  ASSERT(set_builder != NULL && key != NULL);
-  WeakReferenceSetBuilder* builder =
-      reinterpret_cast<WeakReferenceSetBuilder*>(set_builder);
-  ApiState* state = builder->api_state();
-  ASSERT(state == Isolate::Current()->api_state());
-  WeakReferenceSet* reference_set = builder->NewWeakReferenceSet();
-  reference_set->AppendKey(key);
-  if (value != NULL) {
-    reference_set->AppendValue(value);
-  }
-  state->DelayWeakReferenceSet(reference_set);
-  return reinterpret_cast<Dart_WeakReferenceSet>(reference_set);
-}
-
-
-DART_EXPORT Dart_Handle Dart_AppendToWeakReferenceSet(
-    Dart_WeakReferenceSet reference_set,
-    Dart_WeakPersistentHandle key,
-    Dart_WeakPersistentHandle value) {
-  ASSERT(reference_set != NULL);
-  WeakReferenceSet* set = reinterpret_cast<WeakReferenceSet*>(reference_set);
-  set->Append(key, value);
-  return Api::Success();
-}
-
-
-DART_EXPORT Dart_Handle Dart_AppendKeyToWeakReferenceSet(
-    Dart_WeakReferenceSet reference_set,
-    Dart_WeakPersistentHandle key) {
-  ASSERT(reference_set != NULL);
-  WeakReferenceSet* set = reinterpret_cast<WeakReferenceSet*>(reference_set);
-  set->AppendKey(key);
-  return Api::Success();
-}
-
-
-DART_EXPORT Dart_Handle Dart_AppendValueToWeakReferenceSet(
-    Dart_WeakReferenceSet reference_set,
-    Dart_WeakPersistentHandle value) {
-  ASSERT(reference_set != NULL);
-  WeakReferenceSet* set = reinterpret_cast<WeakReferenceSet*>(reference_set);
-  set->AppendValue(value);
-  return Api::Success();
+  state->weak_persistent_handles().FreeHandle(weak_ref);
 }
 
 
@@ -1215,53 +1110,6 @@
 }
 
 
-class PrologueWeakVisitor : public HandleVisitor {
- public:
-  PrologueWeakVisitor(Thread* thread,
-                      Dart_GcPrologueWeakHandleCallback callback)
-      :  HandleVisitor(thread),
-         callback_(callback) {
-  }
-
-
-  void VisitHandle(uword addr) {
-    NoSafepointScope no_safepoint;
-    FinalizablePersistentHandle* handle =
-        reinterpret_cast<FinalizablePersistentHandle*>(addr);
-    RawObject* raw_obj = handle->raw();
-    if (raw_obj->IsHeapObject()) {
-      ASSERT(handle->IsPrologueWeakPersistent());
-      ReusableInstanceHandleScope reused_instance_handle(thread());
-      Instance& instance = reused_instance_handle.Handle();
-      instance ^= reinterpret_cast<RawInstance*>(handle->raw());
-      intptr_t num_native_fields = instance.NumNativeFields();
-      intptr_t* native_fields = instance.NativeFieldsDataAddr();
-      if (native_fields != NULL) {
-        callback_(thread()->isolate()->init_callback_data(),
-                  reinterpret_cast<Dart_WeakPersistentHandle>(addr),
-                  num_native_fields,
-                  native_fields);
-      }
-    }
-  }
-
- private:
-  Dart_GcPrologueWeakHandleCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(PrologueWeakVisitor);
-};
-
-
-DART_EXPORT Dart_Handle Dart_VisitPrologueWeakHandles(
-    Dart_GcPrologueWeakHandleCallback callback) {
-  Thread* thread = Thread::Current();
-  CHECK_ISOLATE(thread->isolate());
-  PrologueWeakVisitor visitor(thread, callback);
-  thread->isolate()->VisitPrologueWeakPersistentHandles(&visitor);
-  return Api::Success();
-}
-
-
 // --- Initialization and Globals ---
 
 DART_EXPORT const char* Dart_VersionString() {
@@ -1279,12 +1127,25 @@
     Dart_FileReadCallback file_read,
     Dart_FileWriteCallback file_write,
     Dart_FileCloseCallback file_close,
-    Dart_EntropySource entropy_source) {
+    Dart_EntropySource entropy_source,
+    Dart_GetVMServiceAssetsArchive get_service_assets) {
+  if ((instructions_snapshot != NULL) && !FLAG_precompilation) {
+    return strdup("Flag --precompilation was not specified.");
+  }
+  if (interrupt != NULL) {
+    return strdup("Dart_Initialize: "
+                  "Setting of interrupt callback is not supported.");
+  }
+  if (unhandled != NULL) {
+    return strdup("Dart_Initialize: "
+                  "Setting of unhandled exception callback is not supported.");
+  }
   const char* err_msg = Dart::InitOnce(vm_isolate_snapshot,
                                        instructions_snapshot,
-                                       create, interrupt, unhandled, shutdown,
+                                       create, shutdown,
                                        file_open, file_read, file_write,
-                                       file_close, entropy_source);
+                                       file_close, entropy_source,
+                                       get_service_assets);
   if (err_msg != NULL) {
     return strdup(err_msg);
   }
@@ -1358,7 +1219,6 @@
                                             char** error) {
   CHECK_NO_ISOLATE(Isolate::Current());
   char* isolate_name = BuildIsolateName(script_uri, main);
-  Thread::EnsureInit();
 
   // Setup default flags in case none were passed.
   Dart_IsolateFlags api_flags;
@@ -1406,6 +1266,7 @@
   Thread* T = Thread::Current();
   Isolate* I = T->isolate();
   CHECK_ISOLATE(I);
+  I->WaitForOutstandingSpawns();
   {
     StackZone zone(T);
     HandleScope handle_scope(T);
@@ -1428,7 +1289,6 @@
 
 
 DART_EXPORT void* Dart_IsolateData(Dart_Isolate isolate) {
-  TRACE_API_CALL(CURRENT_FUNC);
   if (isolate == NULL) {
     FATAL1("%s expects argument 'isolate' to be non-null.",  CURRENT_FUNC);
   }
@@ -1440,11 +1300,11 @@
 
 DART_EXPORT Dart_Handle Dart_DebugName() {
   DARTSCOPE(Thread::Current());
-  return Api::NewHandle(I, String::New(I->name()));
+  Isolate* I = T->isolate();
+  return Api::NewHandle(T, String::New(I->name()));
 }
 
 
-
 DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate) {
   CHECK_NO_ISOLATE(Isolate::Current());
   // TODO(16615): Validate isolate parameter.
@@ -1452,30 +1312,27 @@
   if (iso->HasMutatorThread()) {
     FATAL("Multiple mutators within one isolate is not supported.");
   }
-  Thread::EnsureInit();
-  Thread::EnterIsolate(iso);
+  if (!Thread::EnterIsolate(iso)) {
+    FATAL("Unable to Enter Isolate as Dart VM is shutting down");
+  }
 }
 
 
-DART_EXPORT void Dart_IsolateBlocked() {
-  Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
+DART_EXPORT void Dart_ThreadDisableProfiling() {
+  OSThread* os_thread = OSThread::Current();
+  if (os_thread == NULL) {
     return;
   }
-  profiler_data->Block();
+  os_thread->DisableThreadInterrupts();
 }
 
 
-DART_EXPORT void Dart_IsolateUnblocked() {
-  Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
+DART_EXPORT void Dart_ThreadEnableProfiling() {
+  OSThread* os_thread = OSThread::Current();
+  if (os_thread == NULL) {
     return;
   }
-  profiler_data->Unblock();
+  os_thread->EnableThreadInterrupts();
 }
 
 
@@ -1485,27 +1342,10 @@
 }
 
 
-// TODO(iposva): Remove this API and instead expose the underlying flags.
-DART_EXPORT Dart_Handle Dart_IsolateSetStrictCompilation(bool value) {
-  CHECK_ISOLATE(Isolate::Current());
-  Isolate* isolate = Isolate::Current();
-  if (isolate->has_compiled_code()) {
-    return Api::NewError(
-        "%s expects that the isolate has not yet compiled code.", CURRENT_FUNC);
-  }
-  if (!value) {
-    return Api::NewError(
-        "%s expects that the value is set to true only.", CURRENT_FUNC);
-  }
-  Isolate::Current()->set_strict_compilation();
-  return Api::Null();
-}
-
-
 static uint8_t* ApiReallocate(uint8_t* ptr,
                               intptr_t old_size,
                               intptr_t new_size) {
-  return Api::TopScope(Isolate::Current())->zone()->Realloc<uint8_t>(
+  return Api::TopScope(Thread::Current())->zone()->Realloc<uint8_t>(
       ptr, old_size, new_size);
 }
 
@@ -1517,6 +1357,7 @@
     intptr_t* isolate_snapshot_size) {
   ASSERT(FLAG_load_deferred_eagerly);
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   if (vm_isolate_snapshot_buffer != NULL &&
       vm_isolate_snapshot_size == NULL) {
     RETURN_NULL_ERROR(vm_isolate_snapshot_size);
@@ -1528,7 +1369,7 @@
     RETURN_NULL_ERROR(isolate_snapshot_size);
   }
   // Finalize all classes if needed.
-  Dart_Handle state = Api::CheckAndFinalizePendingClasses(I);
+  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
   if (::Dart_IsError(state)) {
     return state;
   }
@@ -1557,6 +1398,7 @@
                                          uint8_t** buffer,
                                          intptr_t* size) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   if (buffer == NULL) {
     RETURN_NULL_ERROR(buffer);
   }
@@ -1564,7 +1406,7 @@
     RETURN_NULL_ERROR(size);
   }
   // Finalize all classes if needed.
-  Dart_Handle state = Api::CheckAndFinalizePendingClasses(I);
+  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
   if (::Dart_IsError(state)) {
     return state;
   }
@@ -1600,7 +1442,6 @@
 
 
 DART_EXPORT void Dart_InterruptIsolate(Dart_Isolate isolate) {
-  TRACE_API_CALL(CURRENT_FUNC);
   if (isolate == NULL) {
     FATAL1("%s expects argument 'isolate' to be non-null.",  CURRENT_FUNC);
   }
@@ -1612,6 +1453,7 @@
 
 DART_EXPORT bool Dart_IsolateMakeRunnable(Dart_Isolate isolate) {
   CHECK_NO_ISOLATE(Isolate::Current());
+  API_TIMELINE_DURATION;
   if (isolate == NULL) {
     FATAL1("%s expects argument 'isolate' to be non-null.",  CURRENT_FUNC);
   }
@@ -1653,13 +1495,15 @@
 DART_EXPORT Dart_Handle Dart_RunLoop() {
   Thread* T = Thread::Current();
   Isolate* I = T->isolate();
-  CHECK_ISOLATE_SCOPE(I);
+  CHECK_API_SCOPE(T);
   CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_BEGIN_END;
   Monitor monitor;
   MonitorLocker ml(&monitor);
   {
-    SwitchIsolateScope switch_scope(NULL);
-
+    // The message handler run loop does not expect to have a current isolate
+    // so we exit the isolate here and enter it again after the runloop is done.
+    Thread::ExitIsolate();
     RunLoopData data;
     data.monitor = &monitor;
     data.done = false;
@@ -1669,9 +1513,12 @@
     while (!data.done) {
       ml.Wait();
     }
+    if (!Thread::EnterIsolate(I)) {
+      FATAL("Inconsistent state, VM shutting down while in run loop.");
+    }
   }
   if (I->object_store()->sticky_error() != Object::null()) {
-    Dart_Handle error = Api::NewHandle(I, I->object_store()->sticky_error());
+    Dart_Handle error = Api::NewHandle(T, I->object_store()->sticky_error());
     I->object_store()->clear_sticky_error();
     return error;
   }
@@ -1684,14 +1531,14 @@
 
 
 DART_EXPORT Dart_Handle Dart_HandleMessage() {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  CHECK_ISOLATE_SCOPE(isolate);
-  CHECK_CALLBACK_STATE(thread);
-  if (isolate->message_handler()->HandleNextMessage() != MessageHandler::kOK) {
-    Dart_Handle error = Api::NewHandle(isolate,
-                                       isolate->object_store()->sticky_error());
-    isolate->object_store()->clear_sticky_error();
+  Thread* T = Thread::Current();
+  Isolate* I = T->isolate();
+  CHECK_API_SCOPE(T);
+  CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_BEGIN_END;
+  if (I->message_handler()->HandleNextMessage() != MessageHandler::kOK) {
+    Dart_Handle error = Api::NewHandle(T, I->object_store()->sticky_error());
+    I->object_store()->clear_sticky_error();
     return error;
   }
   return Api::Success();
@@ -1699,15 +1546,15 @@
 
 
 DART_EXPORT bool Dart_HandleServiceMessages() {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  CHECK_ISOLATE_SCOPE(isolate);
-  CHECK_CALLBACK_STATE(thread);
-
-  ASSERT(isolate->GetAndClearResumeRequest() == false);
+  Thread* T = Thread::Current();
+  Isolate* I = T->isolate();
+  CHECK_API_SCOPE(T);
+  CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_DURATION;
+  ASSERT(I->GetAndClearResumeRequest() == false);
   MessageHandler::MessageStatus status =
-      isolate->message_handler()->HandleOOBMessages();
-  bool resume = isolate->GetAndClearResumeRequest();
+      I->message_handler()->HandleOOBMessages();
+  bool resume = I->GetAndClearResumeRequest();
   return (status != MessageHandler::kOK) || resume;
 }
 
@@ -1734,10 +1581,20 @@
 
 DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) {
   DARTSCOPE(Thread::Current());
+  API_TIMELINE_DURATION;
+  NoSafepointScope no_safepoint_scope;
   if (port_id == ILLEGAL_PORT) {
     return false;
   }
-  const Object& object = Object::Handle(Z, Api::UnwrapHandle(handle));
+
+  // Smis and null can be sent without serialization.
+  RawObject* raw_obj = Api::UnwrapHandle(handle);
+  if (ApiObjectConverter::CanConvert(raw_obj)) {
+    return PortMap::PostMessage(new Message(
+        port_id, raw_obj, Message::kNormalPriority));
+  }
+
+  const Object& object = Object::Handle(Z, raw_obj);
   uint8_t* data = NULL;
   MessageWriter writer(&data, &allocator, false);
   writer.WriteMessage(object);
@@ -1755,7 +1612,7 @@
                          CURRENT_FUNC,
                          port_id);
   }
-  return Api::NewHandle(I, SendPort::New(port_id));
+  return Api::NewHandle(T, SendPort::New(port_id));
 }
 
 
@@ -1763,6 +1620,7 @@
                                            Dart_Port* port_id) {
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_DURATION;
   const SendPort& send_port = Api::UnwrapSendPortHandle(Z, port);
   if (send_port.IsNull()) {
     RETURN_TYPE_ERROR(Z, port, SendPort);
@@ -1788,34 +1646,30 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
-  ApiLocalScope* new_scope = state->reusable_scope();
+  ApiLocalScope* new_scope = thread->api_reusable_scope();
   if (new_scope == NULL) {
-    new_scope = new ApiLocalScope(state->top_scope(),
+    new_scope = new ApiLocalScope(thread->api_top_scope(),
                                   thread->top_exit_frame_info());
     ASSERT(new_scope != NULL);
   } else {
     new_scope->Reinit(thread,
-                      state->top_scope(),
+                      thread->api_top_scope(),
                       thread->top_exit_frame_info());
-    state->set_reusable_scope(NULL);
+    thread->set_api_reusable_scope(NULL);
   }
-  state->set_top_scope(new_scope);  // New scope is now the top scope.
+  thread->set_api_top_scope(new_scope);  // New scope is now the top scope.
 }
 
 
 DART_EXPORT void Dart_ExitScope() {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  CHECK_ISOLATE_SCOPE(isolate);
-  ApiState* state = isolate->api_state();
-  ApiLocalScope* scope = state->top_scope();
-  ApiLocalScope* reusable_scope = state->reusable_scope();
-  state->set_top_scope(scope->previous());  // Reset top scope to previous.
+  Thread* T = Thread::Current();
+  CHECK_API_SCOPE(T);
+  ApiLocalScope* scope = T->api_top_scope();
+  ApiLocalScope* reusable_scope = T->api_reusable_scope();
+  T->set_api_top_scope(scope->previous());  // Reset top scope to previous.
   if (reusable_scope == NULL) {
-    scope->Reset(thread);  // Reset the old scope which we just exited.
-    state->set_reusable_scope(scope);
+    scope->Reset(T);  // Reset the old scope which we just exited.
+    T->set_api_reusable_scope(scope);
   } else {
     ASSERT(reusable_scope != scope);
     delete scope;
@@ -1825,11 +1679,9 @@
 
 DART_EXPORT uint8_t* Dart_ScopeAllocate(intptr_t size) {
   Zone* zone;
-  Isolate* isolate = Isolate::Current();
-  if (isolate != NULL) {
-    ApiState* state = isolate->api_state();
-    if (state == NULL) return NULL;
-    ApiLocalScope* scope = state->top_scope();
+  Thread* thread = Thread::Current();
+  if (thread != NULL) {
+    ApiLocalScope* scope = thread->api_top_scope();
     zone = scope->zone();
   } else {
     ApiNativeScope* scope = ApiNativeScope::Current();
@@ -1873,7 +1725,7 @@
     *value = Bool::Cast(result).value();
     return Api::Success();
   } else if (result.IsError()) {
-    return Api::NewHandle(I, result.raw());
+    return Api::NewHandle(T, result.raw());
   } else {
     return Api::NewError("Expected boolean result from ==");
   }
@@ -1928,50 +1780,42 @@
 
 
 DART_EXPORT bool Dart_IsNumber(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsNumberClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsInteger(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsIntegerClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsDouble(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kDoubleCid;
 }
 
 
 DART_EXPORT bool Dart_IsBoolean(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kBoolCid;
 }
 
 
 DART_EXPORT bool Dart_IsString(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsStringClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsOneByteStringClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsExternalString(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsExternalStringClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsList(Dart_Handle object) {
   if (RawObject::IsBuiltinListClassId(Api::ClassId(object))) {
-    TRACE_API_CALL(CURRENT_FUNC);
     return true;
   }
 
@@ -1989,31 +1833,26 @@
 
 
 DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kLibraryCid;
 }
 
 
 DART_EXPORT bool Dart_IsType(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kTypeCid;
 }
 
 
 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kFunctionCid;
 }
 
 
 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kFieldCid;
 }
 
 
 DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kTypeParameterCid;
 }
 
@@ -2031,7 +1870,6 @@
 
 
 DART_EXPORT bool Dart_IsTypedData(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   intptr_t cid = Api::ClassId(handle);
   return RawObject::IsTypedDataClassId(cid) ||
          RawObject::IsExternalTypedDataClassId(cid) ||
@@ -2040,14 +1878,14 @@
 
 
 DART_EXPORT bool Dart_IsByteBuffer(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kByteBufferCid;
 }
 
 
 DART_EXPORT bool Dart_IsFuture(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
   if (obj.IsInstance()) {
     const Class& future_class =
@@ -2069,16 +1907,18 @@
 // --- Instances ----
 
 DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(instance));
   if (obj.IsNull()) {
-    return Api::NewHandle(I, I->object_store()->null_type());
+    return Api::NewHandle(T, I->object_store()->null_type());
   }
   if (!obj.IsInstance()) {
     RETURN_TYPE_ERROR(Z, instance, Instance);
   }
   const Type& type = Type::Handle(Instance::Cast(obj).GetType());
-  return Api::NewHandle(I, type.Canonicalize());
+  return Api::NewHandle(T, type.Canonicalize());
 }
 
 
@@ -2086,6 +1926,7 @@
 
 DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer,
                                                   bool* fits) {
+  API_TIMELINE_DURATION;
   // Fast path for Smis and Mints.
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
@@ -2113,6 +1954,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
+  API_TIMELINE_DURATION;
   if (Api::IsSmi(integer)) {
     *fits = (Api::SmiValue(integer) >= 0);
     return Api::Success();
@@ -2138,29 +1980,32 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
+  API_TIMELINE_DURATION;
   if (Smi::IsValid(value)) {
     NOHANDLESCOPE(thread);
-    return Api::NewHandle(isolate, Smi::New(static_cast<intptr_t>(value)));
+    return Api::NewHandle(thread, Smi::New(static_cast<intptr_t>(value)));
   }
   // Slow path for Mints and Bigints.
   DARTSCOPE(thread);
   CHECK_CALLBACK_STATE(thread);
-  return Api::NewHandle(isolate, Integer::New(value));
+  return Api::NewHandle(thread, Integer::New(value));
 }
 
 
 DART_EXPORT Dart_Handle Dart_NewIntegerFromUint64(uint64_t value) {
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
-  return Api::NewHandle(I, Integer::NewFromUint64(value));
+  API_TIMELINE_DURATION;
+  return Api::NewHandle(T, Integer::NewFromUint64(value));
 }
 
 
 DART_EXPORT Dart_Handle Dart_NewIntegerFromHexCString(const char* str) {
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_DURATION;
   const String& str_obj = String::Handle(Z, String::New(str));
-  return Api::NewHandle(I, Integer::New(str_obj));
+  return Api::NewHandle(T, Integer::New(str_obj));
 }
 
 
@@ -2170,6 +2015,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
+  API_TIMELINE_DURATION;
   if (Api::IsSmi(integer)) {
     *value = Api::SmiValue(integer);
     return Api::Success();
@@ -2198,6 +2044,7 @@
 
 DART_EXPORT Dart_Handle Dart_IntegerToUint64(Dart_Handle integer,
                                              uint64_t* value) {
+  API_TIMELINE_DURATION;
   // Fast path for Smis.
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
@@ -2233,12 +2080,13 @@
 
 
 static uword BigintAllocate(intptr_t size) {
-  return Api::TopScope(Isolate::Current())->zone()->AllocUnsafe(size);
+  return Api::TopScope(Thread::Current())->zone()->AllocUnsafe(size);
 }
 
 
 DART_EXPORT Dart_Handle Dart_IntegerToHexCString(Dart_Handle integer,
                                                  const char** value) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
   if (int_obj.IsNull()) {
@@ -2256,14 +2104,16 @@
 
 
 DART_EXPORT Dart_Handle Dart_NewDouble(double value) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
-  return Api::NewHandle(I, Double::New(value));
+  return Api::NewHandle(T, Double::New(value));
 }
 
 
 DART_EXPORT Dart_Handle Dart_DoubleValue(Dart_Handle double_obj,
                                          double* value) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   const Double& obj = Api::UnwrapDoubleHandle(Z, double_obj);
   if (obj.IsNull()) {
@@ -2324,17 +2174,19 @@
 
 
 DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char* str) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (str == NULL) {
     RETURN_NULL_ERROR(str);
   }
   CHECK_CALLBACK_STATE(T);
-  return Api::NewHandle(I, String::New(str));
+  return Api::NewHandle(T, String::New(str));
 }
 
 
 DART_EXPORT Dart_Handle Dart_NewStringFromUTF8(const uint8_t* utf8_array,
                                                intptr_t length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (utf8_array == NULL && length != 0) {
     RETURN_NULL_ERROR(utf8_array);
@@ -2345,7 +2197,7 @@
                          CURRENT_FUNC);
   }
   CHECK_CALLBACK_STATE(T);
-  return Api::NewHandle(I, String::FromUTF8(utf8_array, length));
+  return Api::NewHandle(T, String::FromUTF8(utf8_array, length));
 }
 
 
@@ -2357,19 +2209,20 @@
   }
   CHECK_LENGTH(length, String::kMaxElements);
   CHECK_CALLBACK_STATE(T);
-  return Api::NewHandle(I, String::FromUTF16(utf16_array, length));
+  return Api::NewHandle(T, String::FromUTF16(utf16_array, length));
 }
 
 
 DART_EXPORT Dart_Handle Dart_NewStringFromUTF32(const int32_t* utf32_array,
                                                 intptr_t length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (utf32_array == NULL && length != 0) {
     RETURN_NULL_ERROR(utf32_array);
   }
   CHECK_LENGTH(length, String::kMaxElements);
   CHECK_CALLBACK_STATE(T);
-  return Api::NewHandle(I, String::FromUTF32(utf32_array, length));
+  return Api::NewHandle(T, String::FromUTF32(utf32_array, length));
 }
 
 
@@ -2378,18 +2231,18 @@
     intptr_t length,
     void* peer,
     Dart_PeerFinalizer cback) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (latin1_array == NULL && length != 0) {
     RETURN_NULL_ERROR(latin1_array);
   }
   CHECK_LENGTH(length, String::kMaxElements);
   CHECK_CALLBACK_STATE(T);
-  return Api::NewHandle(I,
-                        String::NewExternal(latin1_array,
-                                            length,
-                                            peer,
-                                            cback,
-                                            SpaceForExternal(I, length)));
+  return Api::NewHandle(T, String::NewExternal(latin1_array,
+                                               length,
+                                               peer,
+                                               cback,
+                                               SpaceForExternal(T, length)));
 }
 
 
@@ -2404,17 +2257,17 @@
   CHECK_LENGTH(length, String::kMaxElements);
   CHECK_CALLBACK_STATE(T);
   intptr_t bytes = length * sizeof(*utf16_array);
-  return Api::NewHandle(I,
-                        String::NewExternal(utf16_array,
-                                            length,
-                                            peer,
-                                            cback,
-                                            SpaceForExternal(I, bytes)));
+  return Api::NewHandle(T, String::NewExternal(utf16_array,
+                                               length,
+                                               peer,
+                                               cback,
+                                               SpaceForExternal(T, bytes)));
 }
 
 
 DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle object,
                                              const char** cstr) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (cstr == NULL) {
     RETURN_NULL_ERROR(cstr);
@@ -2424,7 +2277,7 @@
     RETURN_TYPE_ERROR(Z, object, String);
   }
   intptr_t string_length = Utf8::Length(str_obj);
-  char* res = Api::TopScope(I)->zone()->Alloc<char>(string_length + 1);
+  char* res = Api::TopScope(T)->zone()->Alloc<char>(string_length + 1);
   if (res == NULL) {
     return Api::NewError("Unable to allocate memory");
   }
@@ -2439,6 +2292,7 @@
 DART_EXPORT Dart_Handle Dart_StringToUTF8(Dart_Handle str,
                                           uint8_t** utf8_array,
                                           intptr_t* length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (utf8_array == NULL) {
     RETURN_NULL_ERROR(utf8_array);
@@ -2451,7 +2305,7 @@
     RETURN_TYPE_ERROR(Z, str, String);
   }
   intptr_t str_len = Utf8::Length(str_obj);
-  *utf8_array = Api::TopScope(I)->zone()->Alloc<uint8_t>(str_len);
+  *utf8_array = Api::TopScope(T)->zone()->Alloc<uint8_t>(str_len);
   if (*utf8_array == NULL) {
     return Api::NewError("Unable to allocate memory");
   }
@@ -2464,6 +2318,7 @@
 DART_EXPORT Dart_Handle Dart_StringToLatin1(Dart_Handle str,
                                             uint8_t* latin1_array,
                                             intptr_t* length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (latin1_array == NULL) {
     RETURN_NULL_ERROR(latin1_array);
@@ -2491,6 +2346,7 @@
 DART_EXPORT Dart_Handle Dart_StringToUTF16(Dart_Handle str,
                                            uint16_t* utf16_array,
                                            intptr_t* length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   const String& str_obj = Api::UnwrapStringHandle(Z, str);
   if (str_obj.IsNull()) {
@@ -2571,7 +2427,7 @@
     }
     return str;
   }
-  return Api::NewHandle(I, str_obj.MakeExternal(array, length, peer, cback));
+  return Api::NewHandle(T, str_obj.MakeExternal(array, length, peer, cback));
 }
 
 
@@ -2605,7 +2461,7 @@
   DARTSCOPE(Thread::Current());
   CHECK_LENGTH(length, Array::kMaxElements);
   CHECK_CALLBACK_STATE(T);
-  return Api::NewHandle(I, Array::New(length));
+  return Api::NewHandle(T, Array::New(length));
 }
 
 
@@ -2679,17 +2535,17 @@
     return Api::NewError("Length of List object is greater than the "
                          "maximum value that 'len' parameter can hold");
   } else if (retval.IsError()) {
-    return Api::NewHandle(I, retval.raw());
+    return Api::NewHandle(T, retval.raw());
   } else {
     return Api::NewError("Length of List object is not an integer");
   }
 }
 
 
-#define GET_LIST_ELEMENT(isolate, type, obj, index)                            \
+#define GET_LIST_ELEMENT(thread, type, obj, index)                             \
   const type& array_obj = type::Cast(obj);                                     \
   if ((index >= 0) && (index < array_obj.Length())) {                          \
-    return Api::NewHandle(isolate, array_obj.At(index));                       \
+    return Api::NewHandle(thread, array_obj.At(index));                        \
   }                                                                            \
   return Api::NewError("Invalid index passed in to access list element");      \
 
@@ -2698,9 +2554,9 @@
   DARTSCOPE(Thread::Current());
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
   if (obj.IsArray()) {
-    GET_LIST_ELEMENT(I, Array, obj, index);
+    GET_LIST_ELEMENT(T, Array, obj, index);
   } else if (obj.IsGrowableObjectArray()) {
-    GET_LIST_ELEMENT(I, GrowableObjectArray, obj, index);
+    GET_LIST_ELEMENT(T, GrowableObjectArray, obj, index);
   } else if (obj.IsError()) {
     return list;
   } else {
@@ -2708,7 +2564,7 @@
     // Check and handle a dart object that implements the List interface.
     const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
     if (!instance.IsNull()) {
-      return Api::NewHandle(I, Send1Arg(
+      return Api::NewHandle(T, Send1Arg(
           instance,
           Symbols::IndexToken(),
           Instance::Handle(Z, Integer::New(index))));
@@ -2718,11 +2574,11 @@
 }
 
 
-#define GET_LIST_RANGE(isolate, type, obj, offset, length)                     \
+#define GET_LIST_RANGE(thread, type, obj, offset, length)                      \
   const type& array_obj = type::Cast(obj);                                     \
   if ((offset >= 0) && (offset + length <= array_obj.Length())) {              \
     for (intptr_t index = 0; index < length; ++index) {                        \
-      result[index] = Api::NewHandle(isolate, array_obj.At(index + offset));   \
+      result[index] = Api::NewHandle(thread, array_obj.At(index + offset));    \
     }                                                                          \
     return Api::Success();                                                     \
   }                                                                            \
@@ -2739,9 +2595,9 @@
   }
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
   if (obj.IsArray()) {
-    GET_LIST_RANGE(I, Array, obj, offset, length);
+    GET_LIST_RANGE(T, Array, obj, offset, length);
   } else if (obj.IsGrowableObjectArray()) {
-    GET_LIST_RANGE(I, GrowableObjectArray, obj, offset, length);
+    GET_LIST_RANGE(T, GrowableObjectArray, obj, offset, length);
   } else if (obj.IsError()) {
     return list;
   } else {
@@ -2763,8 +2619,8 @@
         for (intptr_t i = 0; i < length; ++i) {
           index = Integer::New(i);
           args.SetAt(1, index);
-          Dart_Handle value = Api::NewHandle(I,
-              DartEntry::InvokeFunction(function, args));
+          Dart_Handle value = Api::NewHandle(
+              T, DartEntry::InvokeFunction(function, args));
           if (::Dart_IsError(value))
             return value;
           result[i] = value;
@@ -2826,8 +2682,8 @@
         args.SetAt(0, instance);
         args.SetAt(1, index_obj);
         args.SetAt(2, value_obj);
-        return Api::NewHandle(I, DartEntry::InvokeFunction(function,
-                                                                 args));
+        return Api::NewHandle(
+            T, DartEntry::InvokeFunction(function, args));
       }
     }
     return Api::NewError("Object does not implement the 'List' interface");
@@ -2844,7 +2700,6 @@
 
 static RawObject* ThrowArgumentError(const char* exception_message) {
   Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
   // Lookup the class ArgumentError in dart:core.
   const String& lib_url = String::Handle(String::New("dart:core"));
@@ -2876,15 +2731,14 @@
   }
   Instance& exception = Instance::Handle(zone);
   exception = Instance::New(cls);
-  const Array& args = Array::Handle(zone, Array::New(3));
+  const Array& args = Array::Handle(zone, Array::New(2));
   args.SetAt(0, exception);
-  args.SetAt(1, Smi::Handle(zone, Smi::New(Function::kCtorPhaseAll)));
-  args.SetAt(2, String::Handle(String::New(exception_message)));
+  args.SetAt(1, String::Handle(String::New(exception_message)));
   result = DartEntry::InvokeFunction(constructor, args);
   if (result.IsError()) return result.raw();
   ASSERT(result.IsNull());
 
-  if (isolate->top_exit_frame_info() == 0) {
+  if (thread->top_exit_frame_info() == 0) {
     // There are no dart frames on the stack so it would be illegal to
     // throw an exception here.
     const String& message = String::Handle(
@@ -2893,13 +2747,11 @@
   }
   // Unwind all the API scopes till the exit frame before throwing an
   // exception.
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
   const Instance* saved_exception;
   {
     NoSafepointScope no_safepoint;
     RawInstance* raw_exception = exception.raw();
-    state->UnwindScopes(isolate->top_exit_frame_info());
+    thread->UnwindScopes(thread->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
   }
   Exceptions::Throw(thread, *saved_exception);
@@ -2916,8 +2768,8 @@
     for (int i = 0; i < length; i++) {                                         \
       element = array.At(offset + i);                                          \
       if (!element.IsInteger()) {                                              \
-        return Api::NewHandle(I,                                               \
-            ThrowArgumentError("List contains non-int elements"));             \
+        return Api::NewHandle(                                                 \
+            T, ThrowArgumentError("List contains non-int elements"));          \
                                                                                \
       }                                                                        \
       const Integer& integer = Integer::Cast(element);                         \
@@ -3021,7 +2873,7 @@
         args.SetAt(1, intobj);
         result = DartEntry::InvokeFunction(function, args);
         if (result.IsError()) {
-          return Api::NewHandle(I, result.raw());
+          return Api::NewHandle(T, result.raw());
         }
         if (!result.IsInteger()) {
           return Api::NewError("%s expects the argument 'list' to be "
@@ -3056,7 +2908,7 @@
 
 DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list,
                                             intptr_t offset,
-                                            uint8_t* native_array,
+                                            const uint8_t* native_array,
                                             intptr_t length) {
   DARTSCOPE(Thread::Current());
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
@@ -3110,7 +2962,7 @@
         const Object& result = Object::Handle(Z,
             DartEntry::InvokeFunction(function, args));
         if (result.IsError()) {
-          return Api::NewHandle(I, result.raw());
+          return Api::NewHandle(T, result.raw());
         }
       }
       return Api::Success();
@@ -3132,8 +2984,8 @@
     if (!(key_obj.IsInstance() || key_obj.IsNull())) {
       return Api::NewError("Key is not an instance");
     }
-    return Api::NewHandle(I,
-        Send1Arg(instance, Symbols::IndexToken(), Instance::Cast(key_obj)));
+    return Api::NewHandle(
+        T, Send1Arg(instance, Symbols::IndexToken(), Instance::Cast(key_obj)));
   }
   return Api::NewError("Object does not implement the 'Map' interface");
 }
@@ -3149,7 +3001,7 @@
     if (!(key_obj.IsInstance() || key_obj.IsNull())) {
       return Api::NewError("Key is not an instance");
     }
-    return Api::NewHandle(I, Send1Arg(
+    return Api::NewHandle(T, Send1Arg(
        instance,
        String::Handle(Z, String::New("containsKey")),
        Instance::Cast(key_obj)));
@@ -3167,9 +3019,9 @@
     const Object& iterator = Object::Handle(Send0Arg(
         instance, String::Handle(Z, String::New("get:keys"))));
     if (!iterator.IsInstance()) {
-      return Api::NewHandle(I, iterator.raw());
+      return Api::NewHandle(T, iterator.raw());
     }
-    return Api::NewHandle(I, Send0Arg(
+    return Api::NewHandle(T, Send0Arg(
         Instance::Cast(iterator),
         String::Handle(String::New("toList"))));
   }
@@ -3255,7 +3107,7 @@
 
 
 DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfTypedData(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   intptr_t class_id = Api::ClassId(object);
   if (RawObject::IsTypedDataClassId(class_id) ||
       RawObject::IsTypedDataViewClassId(class_id)) {
@@ -3267,7 +3119,7 @@
 
 DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfExternalTypedData(
     Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   intptr_t class_id = Api::ClassId(object);
   if (RawObject::IsExternalTypedDataClassId(class_id)) {
     return GetType(class_id);
@@ -3306,7 +3158,6 @@
 
 static Dart_Handle NewByteData(Thread* thread, intptr_t length) {
   CHECK_LENGTH(length, TypedData::MaxElements(kTypedDataInt8ArrayCid));
-  Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
   Object& result = Object::Handle(zone);
   result = GetByteDataConstructor(thread, Symbols::ByteDataDot(), 1);
@@ -3324,22 +3175,21 @@
   // Invoke the constructor and return the new object.
   result = DartEntry::InvokeFunction(factory, args);
   ASSERT(result.IsInstance() || result.IsNull() || result.IsError());
-  return Api::NewHandle(isolate, result.raw());
+  return Api::NewHandle(thread, result.raw());
 }
 
 
-static Dart_Handle NewTypedData(Isolate* isolate,
+static Dart_Handle NewTypedData(Thread* thread,
                                 intptr_t cid,
                                 intptr_t length) {
   CHECK_LENGTH(length, TypedData::MaxElements(cid));
-  return Api::NewHandle(isolate, TypedData::New(cid, length));
+  return Api::NewHandle(thread, TypedData::New(cid, length));
 }
 
 
 static Dart_Handle NewExternalTypedData(
     Thread* thread, intptr_t cid, void* data, intptr_t length) {
   CHECK_LENGTH(length, ExternalTypedData::MaxElements(cid));
-  Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
   intptr_t bytes = length * ExternalTypedData::ElementSizeInBytes(cid);
   const ExternalTypedData& result = ExternalTypedData::Handle(
@@ -3347,15 +3197,14 @@
       ExternalTypedData::New(cid,
                              reinterpret_cast<uint8_t*>(data),
                              length,
-                             SpaceForExternal(isolate, bytes)));
-  return Api::NewHandle(isolate, result.raw());
+                             SpaceForExternal(thread, bytes)));
+  return Api::NewHandle(thread, result.raw());
 }
 
 
 static Dart_Handle NewExternalByteData(
     Thread* thread, void* data, intptr_t length) {
   Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
   Dart_Handle ext_data = NewExternalTypedData(
       thread, kExternalTypedDataUint8ArrayCid, data, length);
   if (::Dart_IsError(ext_data)) {
@@ -3385,7 +3234,7 @@
   // Invoke the constructor and return the new object.
   result = DartEntry::InvokeFunction(factory, args);
   ASSERT(result.IsNull() || result.IsInstance() || result.IsError());
-  return Api::NewHandle(isolate, result.raw());
+  return Api::NewHandle(thread, result.raw());
 }
 
 
@@ -3397,29 +3246,29 @@
     case Dart_TypedData_kByteData :
       return NewByteData(T, length);
     case Dart_TypedData_kInt8 :
-      return NewTypedData(I, kTypedDataInt8ArrayCid, length);
+      return NewTypedData(T, kTypedDataInt8ArrayCid, length);
     case Dart_TypedData_kUint8 :
-      return NewTypedData(I, kTypedDataUint8ArrayCid, length);
+      return NewTypedData(T, kTypedDataUint8ArrayCid, length);
     case Dart_TypedData_kUint8Clamped :
-      return NewTypedData(I, kTypedDataUint8ClampedArrayCid, length);
+      return NewTypedData(T, kTypedDataUint8ClampedArrayCid, length);
     case Dart_TypedData_kInt16 :
-      return NewTypedData(I, kTypedDataInt16ArrayCid, length);
+      return NewTypedData(T, kTypedDataInt16ArrayCid, length);
     case Dart_TypedData_kUint16 :
-      return NewTypedData(I, kTypedDataUint16ArrayCid, length);
+      return NewTypedData(T, kTypedDataUint16ArrayCid, length);
     case Dart_TypedData_kInt32 :
-      return NewTypedData(I, kTypedDataInt32ArrayCid, length);
+      return NewTypedData(T, kTypedDataInt32ArrayCid, length);
     case Dart_TypedData_kUint32 :
-      return NewTypedData(I, kTypedDataUint32ArrayCid, length);
+      return NewTypedData(T, kTypedDataUint32ArrayCid, length);
     case Dart_TypedData_kInt64 :
-      return NewTypedData(I, kTypedDataInt64ArrayCid, length);
+      return NewTypedData(T, kTypedDataInt64ArrayCid, length);
     case Dart_TypedData_kUint64 :
-      return NewTypedData(I, kTypedDataUint64ArrayCid, length);
+      return NewTypedData(T, kTypedDataUint64ArrayCid, length);
     case Dart_TypedData_kFloat32 :
-      return NewTypedData(I, kTypedDataFloat32ArrayCid,  length);
+      return NewTypedData(T, kTypedDataFloat32ArrayCid,  length);
     case Dart_TypedData_kFloat64 :
-      return NewTypedData(I, kTypedDataFloat64ArrayCid, length);
+      return NewTypedData(T, kTypedDataFloat64ArrayCid, length);
     case Dart_TypedData_kFloat32x4:
-      return NewTypedData(I, kTypedDataFloat32x4ArrayCid, length);
+      return NewTypedData(T, kTypedDataFloat32x4ArrayCid, length);
     default:
       return Api::NewError("%s expects argument 'type' to be of 'TypedData'",
                            CURRENT_FUNC);
@@ -3442,41 +3291,41 @@
     case Dart_TypedData_kByteData:
       return NewExternalByteData(T, data, length);
     case Dart_TypedData_kInt8:
-      return NewExternalTypedData(T,
-          kExternalTypedDataInt8ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataInt8ArrayCid, data, length);
     case Dart_TypedData_kUint8:
-      return NewExternalTypedData(T,
-          kExternalTypedDataUint8ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataUint8ArrayCid, data, length);
     case Dart_TypedData_kUint8Clamped:
-      return NewExternalTypedData(T,
-          kExternalTypedDataUint8ClampedArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataUint8ClampedArrayCid, data, length);
     case Dart_TypedData_kInt16:
-      return NewExternalTypedData(T,
-          kExternalTypedDataInt16ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataInt16ArrayCid, data, length);
     case Dart_TypedData_kUint16:
-      return NewExternalTypedData(T,
-          kExternalTypedDataUint16ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataUint16ArrayCid, data, length);
     case Dart_TypedData_kInt32:
-      return NewExternalTypedData(T,
-          kExternalTypedDataInt32ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataInt32ArrayCid, data, length);
     case Dart_TypedData_kUint32:
-      return NewExternalTypedData(T,
-          kExternalTypedDataUint32ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataUint32ArrayCid, data, length);
     case Dart_TypedData_kInt64:
-      return NewExternalTypedData(T,
-          kExternalTypedDataInt64ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataInt64ArrayCid, data, length);
     case Dart_TypedData_kUint64:
-      return NewExternalTypedData(T,
-          kExternalTypedDataUint64ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataUint64ArrayCid, data, length);
     case Dart_TypedData_kFloat32:
-      return NewExternalTypedData(T,
-          kExternalTypedDataFloat32ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataFloat32ArrayCid, data, length);
     case Dart_TypedData_kFloat64:
-      return NewExternalTypedData(T,
-          kExternalTypedDataFloat64ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataFloat64ArrayCid, data, length);
     case Dart_TypedData_kFloat32x4:
-      return NewExternalTypedData(T,
-          kExternalTypedDataFloat32x4ArrayCid, data, length);
+      return NewExternalTypedData(
+          T, kExternalTypedDataFloat32x4ArrayCid, data, length);
     default:
       return Api::NewError("%s expects argument 'type' to be of"
                            " 'external TypedData'", CURRENT_FUNC);
@@ -3532,7 +3381,7 @@
   // Invoke the factory constructor and return the new object.
   result = DartEntry::InvokeFunction(factory, args);
   ASSERT(result.IsInstance() || result.IsNull() || result.IsError());
-  return Api::NewHandle(I, result.raw());
+  return Api::NewHandle(T, result.raw());
 }
 
 
@@ -3574,6 +3423,7 @@
                                                   void** data,
                                                   intptr_t* len) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   intptr_t class_id = Api::ClassId(object);
   if (!RawObject::IsExternalTypedDataClassId(class_id) &&
       !RawObject::IsTypedDataViewClassId(class_id) &&
@@ -3663,6 +3513,7 @@
 
 DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   intptr_t class_id = Api::ClassId(object);
   if (!RawObject::IsExternalTypedDataClassId(class_id) &&
       !RawObject::IsTypedDataViewClassId(class_id) &&
@@ -3699,7 +3550,7 @@
   }
   const Instance& instance = Api::UnwrapInstanceHandle(zone, object);
   ASSERT(!instance.IsNull());
-  return Api::NewHandle(isolate, ByteBuffer::Data(instance));
+  return Api::NewHandle(thread, ByteBuffer::Data(instance));
 }
 
 
@@ -3736,7 +3587,7 @@
       return ApiError::New(message);
     }
   }
-  int extra_args = (constructor.IsGenerativeConstructor() ? 2 : 1);
+  int extra_args = 1;
   String& error_message = String::Handle();
   if (!constructor.AreValidArgumentCounts(num_args + extra_args,
                                           0,
@@ -3805,7 +3656,7 @@
                               constr_name,
                               number_of_arguments);
   if (result.IsError()) {
-    return Api::NewHandle(I, result.raw());
+    return Api::NewHandle(T, result.raw());
   }
   ASSERT(result.IsFunction());
   Function& constructor = Function::Handle(Z);
@@ -3818,7 +3669,7 @@
     constructor = constructor.RedirectionTarget();
     if (constructor.IsNull()) {
       ASSERT(redirect_type.IsMalformed());
-      return Api::NewHandle(I, redirect_type.error());
+      return Api::NewHandle(T, redirect_type.error());
     }
 
     if (!redirect_type.IsInstantiated()) {
@@ -3828,7 +3679,7 @@
       redirect_type ^= redirect_type.InstantiateFrom(type_arguments,
                                                      &bound_error);
       if (!bound_error.IsNull()) {
-        return Api::NewHandle(I, bound_error.raw());
+        return Api::NewHandle(T, bound_error.raw());
       }
       redirect_type ^= redirect_type.Canonicalize();
     }
@@ -3839,17 +3690,22 @@
     cls = type_obj.type_class();
   }
   if (constructor.IsGenerativeConstructor()) {
+#if defined(DEBUG)
+    if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+      return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
+    }
+#endif
     // Create the new object.
     new_object = Instance::New(cls);
   }
 
   // Create the argument list.
   intptr_t arg_index = 0;
-  int extra_args = (constructor.IsGenerativeConstructor() ? 2 : 1);
+  int extra_args = 1;
   const Array& args =
       Array::Handle(Z, Array::New(number_of_arguments + extra_args));
   if (constructor.IsGenerativeConstructor()) {
-    // Constructors get the uninitialized object and a constructor phase.
+    // Constructors get the uninitialized object.
     if (!type_arguments.IsNull()) {
       // The type arguments will be null if the class has no type parameters, in
       // which case the following call would fail because there is no slot
@@ -3857,7 +3713,6 @@
       new_object.SetTypeArguments(type_arguments);
     }
     args.SetAt(arg_index++, new_object);
-    args.SetAt(arg_index++, Smi::Handle(Z, Smi::New(Function::kCtorPhaseAll)));
   } else {
     // Factories get type arguments.
     args.SetAt(arg_index++, type_arguments);
@@ -3867,7 +3722,7 @@
     argument = Api::UnwrapHandle(arguments[i]);
     if (!argument.IsNull() && !argument.IsInstance()) {
       if (argument.IsError()) {
-        return Api::NewHandle(I, argument.raw());
+        return Api::NewHandle(T, argument.raw());
       } else {
         return Api::NewError(
             "%s expects arguments[%d] to be an Instance handle.",
@@ -3880,7 +3735,7 @@
   // Invoke the constructor and return the new object.
   result = DartEntry::InvokeFunction(constructor, args);
   if (result.IsError()) {
-    return Api::NewHandle(I, result.raw());
+    return Api::NewHandle(T, result.raw());
   }
 
   if (constructor.IsGenerativeConstructor()) {
@@ -3889,7 +3744,7 @@
     ASSERT(result.IsNull() || result.IsInstance());
     new_object ^= result.raw();
   }
-  return Api::NewHandle(I, new_object.raw());
+  return Api::NewHandle(T, new_object.raw());
 }
 
 
@@ -3930,12 +3785,17 @@
     RETURN_TYPE_ERROR(Z, type, Type);
   }
   const Class& cls = Class::Handle(Z, type_obj.type_class());
+#if defined(DEBUG)
+  if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+    return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
+  }
+#endif
   const Error& error = Error::Handle(Z, cls.EnsureIsFinalized(T));
   if (!error.IsNull()) {
     // An error occurred, return error object.
-    return Api::NewHandle(I, error.raw());
+    return Api::NewHandle(T, error.raw());
   }
-  return Api::NewHandle(I, AllocateObject(T, cls));
+  return Api::NewHandle(T, AllocateObject(T, cls));
 }
 
 
@@ -3955,10 +3815,15 @@
     RETURN_NULL_ERROR(native_fields);
   }
   const Class& cls = Class::Handle(Z, type_obj.type_class());
+#if defined(DEBUG)
+  if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+    return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
+  }
+#endif
   const Error& error = Error::Handle(Z, cls.EnsureIsFinalized(T));
   if (!error.IsNull()) {
     // An error occurred, return error object.
-    return Api::NewHandle(I, error.raw());
+    return Api::NewHandle(T, error.raw());
   }
   if (num_native_fields != cls.num_native_fields()) {
     return Api::NewError(
@@ -3967,7 +3832,7 @@
   }
   const Instance& instance = Instance::Handle(Z, AllocateObject(T, cls));
   instance.SetNativeFields(num_native_fields, native_fields);
-  return Api::NewHandle(I, instance.raw());
+  return Api::NewHandle(T, instance.raw());
 }
 
 
@@ -3977,7 +3842,6 @@
                                   int extra_args,
                                   Array* args) {
   Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
   // Check for malformed arguments in the arguments list.
   *args = Array::New(num_args + extra_args);
   Object& arg = Object::Handle(zone);
@@ -3986,7 +3850,7 @@
     if (!arg.IsNull() && !arg.IsInstance()) {
       *args = Array::null();
       if (arg.IsError()) {
-        return Api::NewHandle(isolate, arg.raw());
+        return Api::NewHandle(thread, arg.raw());
       } else {
         return Api::NewError(
             "%s expects arguments[%d] to be an Instance handle.",
@@ -4003,6 +3867,7 @@
                                                Dart_Handle name,
                                                int number_of_arguments,
                                                Dart_Handle* arguments) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
 
@@ -4011,10 +3876,6 @@
         "%s expects argument 'number_of_arguments' to be non-negative.",
         CURRENT_FUNC);
   }
-  const String& constructor_name = Api::UnwrapStringHandle(Z, name);
-  if (constructor_name.IsNull()) {
-    RETURN_TYPE_ERROR(Z, name, String);
-  }
   const Instance& instance = Api::UnwrapInstanceHandle(Z, object);
   if (instance.IsNull()) {
     RETURN_TYPE_ERROR(Z, object, Instance);
@@ -4026,26 +3887,31 @@
   // once for the same object.
 
   // Construct name of the constructor to invoke.
+  const String& constructor_name = Api::UnwrapStringHandle(Z, name);
   const Type& type_obj = Type::Handle(Z, instance.GetType());
   const Class& cls = Class::Handle(Z, type_obj.type_class());
   const String& class_name = String::Handle(Z, cls.Name());
   const Array& strings = Array::Handle(Z, Array::New(3));
   strings.SetAt(0, class_name);
   strings.SetAt(1, Symbols::Dot());
-  strings.SetAt(2, constructor_name);
+  if (constructor_name.IsNull()) {
+    strings.SetAt(2, Symbols::Empty());
+  } else {
+    strings.SetAt(2, constructor_name);
+  }
   const String& dot_name = String::Handle(Z, String::ConcatAll(strings));
   const TypeArguments& type_arguments =
       TypeArguments::Handle(Z, type_obj.arguments());
   const Function& constructor =
       Function::Handle(Z, cls.LookupFunctionAllowPrivate(dot_name));
-  const int extra_args = 2;
+  const int extra_args = 1;
   if (!constructor.IsNull() &&
       constructor.IsGenerativeConstructor() &&
       constructor.AreValidArgumentCounts(number_of_arguments + extra_args,
                                          0,
                                          NULL)) {
     // Create the argument list.
-    // Constructors get the uninitialized object and a constructor phase.
+    // Constructors get the uninitialized object.
     if (!type_arguments.IsNull()) {
       // The type arguments will be null if the class has no type
       // parameters, in which case the following call would fail
@@ -4055,17 +3921,16 @@
     }
     Dart_Handle result;
     Array& args = Array::Handle(Z);
-    result = SetupArguments(T,
-        number_of_arguments, arguments, extra_args, &args);
+    result = SetupArguments(
+        T, number_of_arguments, arguments, extra_args, &args);
     if (!::Dart_IsError(result)) {
       args.SetAt(0, instance);
-      args.SetAt(1, Smi::Handle(Z, Smi::New(Function::kCtorPhaseAll)));
       const Object& retval = Object::Handle(Z,
           DartEntry::InvokeFunction(constructor, args));
       if (retval.IsError()) {
-        result = Api::NewHandle(I, retval.raw());
+        result = Api::NewHandle(T, retval.raw());
       } else {
-        result = Api::NewHandle(I, instance.raw());
+        result = Api::NewHandle(T, instance.raw());
       }
     }
     return result;
@@ -4080,6 +3945,7 @@
                                     Dart_Handle name,
                                     int number_of_arguments,
                                     Dart_Handle* arguments) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
 
@@ -4121,7 +3987,7 @@
     // Setup args and check for malformed arguments in the arguments list.
     result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
     if (!::Dart_IsError(result)) {
-      result = Api::NewHandle(I, DartEntry::InvokeFunction(function, args));
+      result = Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
     }
     return result;
   } else if (obj.IsNull() || obj.IsInstance()) {
@@ -4145,7 +4011,7 @@
         args.SetAt(0, instance);
         const Array& args_descriptor =
           Array::Handle(Z, ArgumentsDescriptor::New(args.Length()));
-        result = Api::NewHandle(I,
+        result = Api::NewHandle(T,
                                 DartEntry::InvokeNoSuchMethod(instance,
                                                               function_name,
                                                               args,
@@ -4157,7 +4023,7 @@
     result = SetupArguments(T, number_of_arguments, arguments, 1, &args);
     if (!::Dart_IsError(result)) {
       args.SetAt(0, instance);
-      result = Api::NewHandle(I, DartEntry::InvokeFunction(function, args));
+      result = Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
     }
     return result;
   } else if (obj.IsLibrary()) {
@@ -4192,7 +4058,7 @@
     // Setup args and check for malformed arguments in the arguments list.
     result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
     if (!::Dart_IsError(result)) {
-      result = Api::NewHandle(I, DartEntry::InvokeFunction(function, args));
+      result = Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
     }
     return result;
   } else {
@@ -4206,6 +4072,7 @@
 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure,
                                            int number_of_arguments,
                                            Dart_Handle* arguments) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
   const Instance& closure_obj = Api::UnwrapInstanceHandle(Z, closure);
@@ -4230,11 +4097,12 @@
     args.SetAt(i + 1, obj);
   }
   // Now try to invoke the closure.
-  return Api::NewHandle(I, DartEntry::InvokeClosure(args));
+  return Api::NewHandle(T, DartEntry::InvokeClosure(args));
 }
 
 
 DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
 
@@ -4268,10 +4136,10 @@
 
     if (!getter.IsNull()) {
       // Invoke the getter and return the result.
-      return Api::NewHandle(I,
-          DartEntry::InvokeFunction(getter, Object::empty_array()));
+      return Api::NewHandle(
+          T, DartEntry::InvokeFunction(getter, Object::empty_array()));
     } else if (!field.IsNull()) {
-      return Api::NewHandle(I, field.StaticValue());
+      return Api::NewHandle(T, field.StaticValue());
     } else {
       return Api::NewError("%s: did not find static field '%s'.",
                            CURRENT_FUNC, field_name.ToCString());
@@ -4299,13 +4167,12 @@
     if (getter.IsNull()) {
       const Array& args_descriptor =
           Array::Handle(Z, ArgumentsDescriptor::New(args.Length()));
-      return Api::NewHandle(I,
-                            DartEntry::InvokeNoSuchMethod(instance,
-                                                          getter_name,
-                                                          args,
-                                                          args_descriptor));
+      return Api::NewHandle(T, DartEntry::InvokeNoSuchMethod(instance,
+                                                             getter_name,
+                                                             args,
+                                                             args_descriptor));
     }
-    return Api::NewHandle(I, DartEntry::InvokeFunction(getter, args));
+    return Api::NewHandle(T, DartEntry::InvokeFunction(getter, args));
 
   } else if (obj.IsLibrary()) {
     // To access a top-level we may need to use the Field or the
@@ -4334,11 +4201,11 @@
 
     if (!getter.IsNull()) {
       // Invoke the getter and return the result.
-      return Api::NewHandle(I,
-          DartEntry::InvokeFunction(getter, Object::empty_array()));
+      return Api::NewHandle(
+          T, DartEntry::InvokeFunction(getter, Object::empty_array()));
     }
     if (!field.IsNull()) {
-      return Api::NewHandle(I, field.StaticValue());
+      return Api::NewHandle(T, field.StaticValue());
     }
     return Api::NewError("%s: did not find top-level variable '%s'.",
                          CURRENT_FUNC, field_name.ToCString());
@@ -4356,6 +4223,7 @@
 DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container,
                                       Dart_Handle name,
                                       Dart_Handle value) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
 
@@ -4403,7 +4271,7 @@
       const Object& result = Object::Handle(Z,
           DartEntry::InvokeFunction(setter, args));
       if (result.IsError()) {
-        return Api::NewHandle(I, result.raw());
+        return Api::NewHandle(T, result.raw());
       } else {
         return Api::Success();
       }
@@ -4448,12 +4316,12 @@
     if (setter.IsNull()) {
       const Array& args_descriptor =
           Array::Handle(Z, ArgumentsDescriptor::New(args.Length()));
-      return Api::NewHandle(I, DartEntry::InvokeNoSuchMethod(instance,
+      return Api::NewHandle(T, DartEntry::InvokeNoSuchMethod(instance,
                                                              setter_name,
                                                              args,
                                                              args_descriptor));
     }
-    return Api::NewHandle(I, DartEntry::InvokeFunction(setter, args));
+    return Api::NewHandle(T, DartEntry::InvokeFunction(setter, args));
 
   } else if (obj.IsLibrary()) {
     // To access a top-level we may need to use the Field or the
@@ -4481,7 +4349,7 @@
       const Object& result =
           Object::Handle(Z, DartEntry::InvokeFunction(setter, args));
       if (result.IsError()) {
-        return Api::NewHandle(I, result.raw());
+        return Api::NewHandle(T, result.raw());
       }
       return Api::Success();
     }
@@ -4519,7 +4387,7 @@
       RETURN_TYPE_ERROR(zone, exception, Instance);
     }
   }
-  if (isolate->top_exit_frame_info() == 0) {
+  if (thread->top_exit_frame_info() == 0) {
     // There are no dart frames on the stack so it would be illegal to
     // throw an exception here.
     return Api::NewError("No Dart frames on stack, cannot throw exception");
@@ -4527,14 +4395,12 @@
 
   // Unwind all the API scopes till the exit frame before throwing an
   // exception.
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
   const Instance* saved_exception;
   {
     NoSafepointScope no_safepoint;
     RawInstance* raw_exception =
         Api::UnwrapInstanceHandle(zone, exception).raw();
-    state->UnwindScopes(isolate->top_exit_frame_info());
+    thread->UnwindScopes(thread->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
   }
   Exceptions::Throw(thread, *saved_exception);
@@ -4559,7 +4425,7 @@
       RETURN_TYPE_ERROR(zone, stacktrace, Instance);
     }
   }
-  if (isolate->top_exit_frame_info() == 0) {
+  if (thread->top_exit_frame_info() == 0) {
     // There are no dart frames on the stack so it would be illegal to
     // throw an exception here.
     return Api::NewError("No Dart frames on stack, cannot throw exception");
@@ -4567,8 +4433,6 @@
 
   // Unwind all the API scopes till the exit frame before throwing an
   // exception.
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
   const Instance* saved_exception;
   const Stacktrace* saved_stacktrace;
   {
@@ -4577,7 +4441,7 @@
         Api::UnwrapInstanceHandle(zone, exception).raw();
     RawStacktrace* raw_stacktrace =
         Api::UnwrapStacktraceHandle(zone, stacktrace).raw();
-    state->UnwindScopes(isolate->top_exit_frame_info());
+    thread->UnwindScopes(thread->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
     saved_stacktrace = &Stacktrace::Handle(raw_stacktrace);
   }
@@ -4613,7 +4477,7 @@
     return Api::NewError(
         "Unable to create native wrapper class : already exists");
   }
-  return Api::NewHandle(I, cls.RareType());
+  return Api::NewHandle(T, cls.RareType());
 }
 
 
@@ -4793,12 +4657,10 @@
       }
 
       case Dart_NativeArgument_kInstance: {
-        Isolate* isolate = arguments->thread()->isolate();
-        ASSERT(isolate == Isolate::Current());
-        ASSERT(isolate->api_state() &&
-               isolate->api_state()->top_scope() != NULL);
-        native_value->as_instance =
-            Api::NewHandle(isolate, arguments->NativeArgAt(arg_index));
+        ASSERT(arguments->thread() == Thread::Current());
+        ASSERT(arguments->thread()->api_top_scope() != NULL);
+        native_value->as_instance = Api::NewHandle(
+            arguments->thread(), arguments->NativeArgAt(arg_index));
         break;
       }
 
@@ -4813,20 +4675,20 @@
 
 DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args,
                                                int index) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   if ((index < 0) || (index >= arguments->NativeArgCount())) {
     return Api::NewError(
         "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
         CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
   }
-  return Api::NewHandle(arguments->thread()->isolate(),
+  return Api::NewHandle(arguments->thread(),
                         arguments->NativeArgAt(index));
 }
 
 
 DART_EXPORT int Dart_GetNativeArgumentCount(Dart_NativeArguments args) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   return arguments->NativeArgCount();
 }
@@ -4885,7 +4747,7 @@
 DART_EXPORT Dart_Handle Dart_GetNativeIntegerArgument(Dart_NativeArguments args,
                                                       int index,
                                                       int64_t* value) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   if ((index < 0) || (index >= arguments->NativeArgCount())) {
     return Api::NewError(
@@ -4903,7 +4765,7 @@
 DART_EXPORT Dart_Handle Dart_GetNativeBooleanArgument(Dart_NativeArguments args,
                                                       int index,
                                                       bool* value) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   if ((index < 0) || (index >= arguments->NativeArgCount())) {
     return Api::NewError(
@@ -4921,7 +4783,7 @@
 DART_EXPORT Dart_Handle Dart_GetNativeDoubleArgument(Dart_NativeArguments args,
                                                      int index,
                                                      double* value) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   if ((index < 0) || (index >= arguments->NativeArgCount())) {
     return Api::NewError(
@@ -4957,25 +4819,25 @@
   Isolate* isolate = arguments->thread()->isolate();
   ASSERT(isolate == Isolate::Current());
   ASSERT(isolate->api_state() != NULL &&
-         (isolate->api_state()->IsValidWeakPersistentHandle(rval) ||
-          isolate->api_state()->IsValidPrologueWeakPersistentHandle(rval)));
+         (isolate->api_state()->IsValidWeakPersistentHandle(rval)));
 #endif
   Api::SetWeakHandleReturnValue(arguments, rval);
 }
 
 
 // --- Environment ---
-RawString* Api::CallEnvironmentCallback(Isolate* isolate, const String& name) {
-  Scope api_scope(isolate);
+RawString* Api::CallEnvironmentCallback(Thread* thread, const String& name) {
+  Isolate* isolate = thread->isolate();
+  Scope api_scope(thread);
   Dart_EnvironmentCallback callback = isolate->environment_callback();
-  String& result = String::Handle(isolate->current_zone());
+  String& result = String::Handle(thread->zone());
   if (callback != NULL) {
-    Dart_Handle response = callback(Api::NewHandle(isolate, name.raw()));
+    Dart_Handle response = callback(Api::NewHandle(thread, name.raw()));
     if (::Dart_IsString(response)) {
       result ^= Api::UnwrapHandle(response);
     } else if (::Dart_IsError(response)) {
-      const Object& error =
-          Object::Handle(isolate->current_zone(), Api::UnwrapHandle(response));
+      const Object& error = Object::Handle(
+          thread->zone(), Api::UnwrapHandle(response));
       Exceptions::ThrowArgumentError(
           String::Handle(String::New(Error::Cast(error).ToErrorCString())));
     } else if (!::Dart_IsNull(response)) {
@@ -5009,7 +4871,7 @@
 // --- Scripts and Libraries ---
 DART_EXPORT void Dart_SetBooleanReturnValue(Dart_NativeArguments args,
                                             bool retval) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   arguments->SetReturn(Bool::Get(retval));
 }
@@ -5051,7 +4913,7 @@
 // NOTE: Need to pass 'result' as a parameter here in order to avoid
 // warning: variable 'result' might be clobbered by 'longjmp' or 'vfork'
 // which shows up because of the use of setjmp.
-static void CompileSource(Isolate* isolate,
+static void CompileSource(Thread* thread,
                           const Library& lib,
                           const Script& script,
                           Dart_Handle* result) {
@@ -5060,13 +4922,13 @@
   if (update_lib_status) {
     lib.SetLoadInProgress();
   }
-  ASSERT(isolate != NULL);
+  ASSERT(thread != NULL);
   const Error& error =
-      Error::Handle(isolate->current_zone(), Compiler::Compile(lib, script));
+      Error::Handle(thread->zone(), Compiler::Compile(lib, script));
   if (error.IsNull()) {
-    *result = Api::NewHandle(isolate, lib.raw());
+    *result = Api::NewHandle(thread, lib.raw());
   } else {
-    *result = Api::NewHandle(isolate, error.raw());
+    *result = Api::NewHandle(thread, error.raw());
     // Compilation errors are not Dart instances, so just mark the library
     // as having failed to load without providing an error instance.
     lib.SetLoadError(Object::null_instance());
@@ -5078,7 +4940,9 @@
                                         Dart_Handle source,
                                         intptr_t line_offset,
                                         intptr_t column_offset) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const String& url_str = Api::UnwrapStringHandle(Z, url);
   if (url_str.IsNull()) {
     RETURN_TYPE_ERROR(Z, url, String);
@@ -5115,14 +4979,16 @@
       Script::New(url_str, source_str, RawScript::kScriptTag));
   script.SetLocationOffset(line_offset, column_offset);
   Dart_Handle result;
-  CompileSource(I, library, script, &result);
+  CompileSource(T, library, script, &result);
   return result;
 }
 
 
 DART_EXPORT Dart_Handle Dart_LoadScriptFromSnapshot(const uint8_t* buffer,
                                                     intptr_t buffer_len) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   StackZone zone(T);
   if (buffer == NULL) {
     RETURN_NULL_ERROR(buffer);
@@ -5152,19 +5018,32 @@
   ScriptSnapshotReader reader(snapshot->content(), snapshot->length(), T);
   const Object& tmp = Object::Handle(Z, reader.ReadScriptSnapshot());
   if (tmp.IsError()) {
-    return Api::NewHandle(I, tmp.raw());
+    return Api::NewHandle(T, tmp.raw());
   }
   library ^= tmp.raw();
   library.set_debuggable(true);
   I->object_store()->set_root_library(library);
-  return Api::NewHandle(I, library.raw());
+  return Api::NewHandle(T, library.raw());
 }
 
 
 DART_EXPORT Dart_Handle Dart_RootLibrary() {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
-  return Api::NewHandle(isolate, isolate->object_store()->root_library());
+  return Api::NewHandle(thread, isolate->object_store()->root_library());
+}
+
+
+DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library) {
+  DARTSCOPE(Thread::Current());
+  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
+  if (lib.IsNull()) {
+    RETURN_TYPE_ERROR(Z, library, Library);
+  }
+  Isolate* isolate = Isolate::Current();
+  isolate->object_store()->set_root_library(lib);
+  return library;
 }
 
 
@@ -5186,7 +5065,7 @@
     return Api::NewError("Class '%s' not found in library '%s'.",
                          cls_name.ToCString(), lib_name.ToCString());
   }
-  return Api::NewHandle(I, cls.RareType());
+  return Api::NewHandle(T, cls.RareType());
 }
 
 
@@ -5221,7 +5100,7 @@
       return Api::NewError("Invalid number of type arguments specified, "
                            "got %" Pd " expected 0", number_of_type_arguments);
     }
-    return Api::NewHandle(I, Type::NewNonParameterizedType(cls));
+    return Api::NewHandle(T, Type::NewNonParameterizedType(cls));
   }
   intptr_t num_expected_type_arguments = cls.NumTypeParameters();
   TypeArguments& type_args_obj = TypeArguments::Handle();
@@ -5259,7 +5138,7 @@
       Type::New(cls, type_args_obj, Scanner::kNoSourcePos));
   instantiated_type ^= ClassFinalizer::FinalizeType(
       cls, instantiated_type, ClassFinalizer::kCanonicalize);
-  return Api::NewHandle(I, instantiated_type.raw());
+  return Api::NewHandle(T, instantiated_type.raw());
 }
 
 
@@ -5271,7 +5150,7 @@
   }
   const String& url = String::Handle(Z, lib.url());
   ASSERT(!url.IsNull());
-  return Api::NewHandle(I, url.raw());
+  return Api::NewHandle(T, url.raw());
 }
 
 
@@ -5286,7 +5165,7 @@
     return Api::NewError("%s: library '%s' not found.",
                          CURRENT_FUNC, url_str.ToCString());
   } else {
-    return Api::NewHandle(I, library.raw());
+    return Api::NewHandle(T, library.raw());
   }
 }
 
@@ -5294,6 +5173,7 @@
 DART_EXPORT Dart_Handle Dart_LibraryHandleError(Dart_Handle library_in,
                                                 Dart_Handle error_in) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
 
   const Library& lib = Api::UnwrapLibraryHandle(Z, library_in);
   if (lib.IsNull()) {
@@ -5322,7 +5202,9 @@
                                          Dart_Handle source,
                                          intptr_t line_offset,
                                          intptr_t column_offset) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const String& url_str = Api::UnwrapStringHandle(Z, url);
   if (url_str.IsNull()) {
     RETURN_TYPE_ERROR(Z, url, String);
@@ -5360,7 +5242,7 @@
       Script::New(url_str, source_str, RawScript::kLibraryTag));
   script.SetLocationOffset(line_offset, column_offset);
   Dart_Handle result;
-  CompileSource(I, library, script, &result);
+  CompileSource(T, library, script, &result);
   // Propagate the error out right now.
   if (::Dart_IsError(result)) {
     return result;
@@ -5369,7 +5251,7 @@
   // If this is the dart:_builtin library, register it with the VM.
   if (url_str.Equals("dart:_builtin")) {
     I->object_store()->set_builtin_library(library);
-    Dart_Handle state = Api::CheckAndFinalizePendingClasses(I);
+    Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
     if (::Dart_IsError(state)) {
       return state;
     }
@@ -5382,6 +5264,7 @@
                                                   Dart_Handle import,
                                                   Dart_Handle prefix) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const Library& library_vm = Api::UnwrapLibraryHandle(Z, library);
   if (library_vm.IsNull()) {
     RETURN_TYPE_ERROR(Z, library, Library);
@@ -5425,7 +5308,9 @@
                                         Dart_Handle source,
                                         intptr_t line_offset,
                                         intptr_t column_offset) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const Library& lib = Api::UnwrapLibraryHandle(Z, library);
   if (lib.IsNull()) {
     RETURN_TYPE_ERROR(Z, library, Library);
@@ -5455,7 +5340,7 @@
       Script::New(url_str, source_str, RawScript::kSourceTag));
   script.SetLocationOffset(line_offset, column_offset);
   Dart_Handle result;
-  CompileSource(I, lib, script, &result);
+  CompileSource(T, lib, script, &result);
   return result;
 }
 
@@ -5463,7 +5348,9 @@
 DART_EXPORT Dart_Handle Dart_LibraryLoadPatch(Dart_Handle library,
                                               Dart_Handle url,
                                               Dart_Handle patch_source) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const Library& lib = Api::UnwrapLibraryHandle(Z, library);
   if (lib.IsNull()) {
     RETURN_TYPE_ERROR(Z, library, Library);
@@ -5484,7 +5371,7 @@
   const Script& script = Script::Handle(Z,
       Script::New(url_str, source_str, RawScript::kPatchTag));
   Dart_Handle result;
-  CompileSource(I, lib, script, &result);
+  CompileSource(T, lib, script, &result);
   return result;
 }
 
@@ -5492,7 +5379,9 @@
 // Finalizes classes and invokes Dart core library function that completes
 // futures of loadLibrary calls (deferred library loading).
 DART_EXPORT Dart_Handle Dart_FinalizeLoading(bool complete_futures) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   CHECK_CALLBACK_STATE(T);
 
   I->DoneLoading();
@@ -5501,7 +5390,7 @@
   // invoing of _completeDeferredLoads) into Isolate::DoneLoading().
 
   // Finalize all classes if needed.
-  Dart_Handle state = Api::CheckAndFinalizePendingClasses(I);
+  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
   if (::Dart_IsError(state)) {
     return state;
   }
@@ -5533,7 +5422,7 @@
         Object::Handle(Z, DartEntry::InvokeFunction(function, args));
     I->object_store()->clear_pending_deferred_loads();
     if (res.IsError() || res.IsUnhandledException()) {
-      return Api::NewHandle(I, res.raw());
+      return Api::NewHandle(T, res.raw());
     }
   }
   return Api::Success();
@@ -5670,6 +5559,7 @@
                                                   const uint8_t* bytes,
                                                   intptr_t bytes_length) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   if (stream_id == NULL) {
     RETURN_NULL_ERROR(stream_id);
   }
@@ -5690,7 +5580,7 @@
 
 
 DART_EXPORT int64_t Dart_TimelineGetMicros() {
-  return OS::GetCurrentTraceMicros();
+  return OS::GetCurrentMonotonicMicros();
 }
 
 
@@ -5703,6 +5593,8 @@
       (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0);
   isolate->GetDartStream()->set_enabled(
       (stream_mask & DART_TIMELINE_STREAM_DART) != 0);
+  isolate->GetDebuggerStream()->set_enabled(
+      (stream_mask & DART_TIMELINE_STREAM_DEBUGGER) != 0);
   isolate->GetEmbedderStream()->set_enabled(
       (stream_mask & DART_TIMELINE_STREAM_EMBEDDER) != 0);
   isolate->GetGCStream()->set_enabled(
@@ -5719,6 +5611,8 @@
       (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0;
   const bool dart_enabled =
       (stream_mask & DART_TIMELINE_STREAM_DART) != 0;
+  const bool debugger_enabled =
+      (stream_mask & DART_TIMELINE_STREAM_DEBUGGER) != 0;
   const bool embedder_enabled =
       (stream_mask & DART_TIMELINE_STREAM_EMBEDDER) != 0;
   const bool gc_enabled = (stream_mask & DART_TIMELINE_STREAM_GC) != 0;
@@ -5727,6 +5621,7 @@
   Timeline::SetStreamAPIEnabled(api_enabled);
   Timeline::SetStreamCompilerEnabled(compiler_enabled);
   Timeline::SetStreamDartEnabled(dart_enabled);
+  Timeline::SetStreamDebuggerEnabled(debugger_enabled);
   Timeline::SetStreamEmbedderEnabled(embedder_enabled);
   Timeline::SetStreamGCEnabled(gc_enabled);
   Timeline::SetStreamIsolateEnabled(isolate_enabled);
@@ -5737,35 +5632,6 @@
 }
 
 
-// '[' + ']' + '\0'.
-#define MINIMUM_OUTPUT_LENGTH 3
-
-// Trims the '[' and ']' characters and, depending on whether or not more events
-// will follow, adjusts the last character of the string to either a '\0' or
-// ','.
-static char* TrimOutput(char* output,
-                        intptr_t* output_length,
-                        bool events_will_follow) {
-  ASSERT(output != NULL);
-  ASSERT(output_length != NULL);
-  ASSERT(*output_length > MINIMUM_OUTPUT_LENGTH);
-  // We expect the first character to be the opening of an array.
-  ASSERT(output[0] == '[');
-  // We expect the last character to be the closing of an array.
-  ASSERT(output[*output_length - 2] == ']');
-  if (events_will_follow) {
-    // Replace array closing character (']') with ','.
-    output[*output_length - 2] = ',';
-  } else {
-    // Replace array closing character (']') with '\0'.
-    output[*output_length - 2] = '\0';
-  }
-  // Skip the array opening character ('[').
-  *output_length -= 2;
-  return &output[1];
-}
-
-
 static void StartStreamToConsumer(Dart_StreamConsumer consumer,
                                   void* user_data,
                                   const char* stream_name) {
@@ -5827,45 +5693,38 @@
 
 static bool StreamTraceEvents(Dart_StreamConsumer consumer,
                               void* user_data,
-                              JSONStream* js,
-                              const char* dart_events) {
+                              JSONStream* js) {
   ASSERT(js != NULL);
   // Steal output from JSONStream.
   char* output = NULL;
   intptr_t output_length = 0;
   js->Steal(const_cast<const char**>(&output), &output_length);
-
-  const bool output_vm = output_length > MINIMUM_OUTPUT_LENGTH;
-  const bool output_dart = dart_events != NULL;
-
-  if (!output_vm && !output_dart) {
-    // We stole the JSONStream's output buffer, free it.
+  if (output_length < 3) {
+    // Empty JSON array.
     free(output);
-    // Nothing will be emitted.
     return false;
   }
+  // We want to send the JSON array without the leading '[' or trailing ']'
+  // characters.
+  ASSERT(output[0] == '[');
+  ASSERT(output[output_length - 1] == ']');
+  // Replace the ']' with the null character.
+  output[output_length - 1] = '\0';
+  // We are skipping the '['.
+  output_length -= 1;
 
   // Start the stream.
   StartStreamToConsumer(consumer, user_data, "timeline");
 
-  // Send events from the VM.
-  if (output_vm) {
-    // Add one for the '\0' character.
-    output_length++;
-    char* trimmed_output = TrimOutput(output, &output_length, output_dart);
-    DataStreamToConsumer(consumer, user_data,
-                         trimmed_output, output_length, "timeline");
-  }
+  DataStreamToConsumer(consumer,
+                       user_data,
+                       &output[1],
+                       output_length,
+                       "timeline");
+
   // We stole the JSONStream's output buffer, free it.
   free(output);
 
-  // Send events from dart.
-  if (output_dart) {
-    const intptr_t dart_events_len = strlen(dart_events) + 1;  // +1 for '\0'.
-    DataStreamToConsumer(consumer, user_data,
-                         dart_events, dart_events_len, "timeline");
-  }
-
   // Finish the stream.
   FinishStreamToConsumer(consumer, user_data, "timeline");
   return true;
@@ -5886,21 +5745,20 @@
   }
   Thread* T = Thread::Current();
   StackZone zone(T);
-  // Reclaim all blocks cached by isolate.
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
-  IsolateTimelineEventFilter filter(isolate);
+  IsolateTimelineEventFilter filter(isolate->main_port());
   timeline_recorder->PrintTraceEvent(&js, &filter);
-  const char* dart_events =
-      DartTimelineEventIterator::PrintTraceEvents(timeline_recorder,
-                                                  zone.GetZone(),
-                                                  isolate);
-  return StreamTraceEvents(consumer, user_data, &js, dart_events);
+  return StreamTraceEvents(consumer, user_data, &js);
 }
 
 
 DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer,
                                              void* user_data) {
+  // To support various embedders, it must be possible to call this function
+  // from a thread for which we have not entered an Isolate and set up a Thread
+  // TLS object. Therefore, a Zone may not be available, a StackZone cannot be
+  // created, and no ZoneAllocated objects can be allocated.
   if (consumer == NULL) {
     return false;
   }
@@ -5909,18 +5767,11 @@
     // Nothing has been recorded.
     return false;
   }
-  Thread* T = Thread::Current();
-  StackZone zone(T);
-  // Reclaim all blocks cached in the system.
-  Timeline::ReclaimAllBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
   TimelineEventFilter filter;
   timeline_recorder->PrintTraceEvent(&js, &filter);
-  const char* dart_events =
-      DartTimelineEventIterator::PrintTraceEvents(timeline_recorder,
-                                                  zone.GetZone(),
-                                                  NULL);
-  return StreamTraceEvents(consumer, user_data, &js, dart_events);
+  return StreamTraceEvents(consumer, user_data, &js);
 }
 
 
@@ -6031,11 +5882,38 @@
 }
 
 
+#if defined(DART_PRECOMPILED)
+
 DART_EXPORT Dart_Handle Dart_Precompile(
     Dart_QualifiedFunctionName entry_points[],
     bool reset_fields) {
+  UNREACHABLE();
+  return 0;
+}
+
+
+DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshot(
+    uint8_t** vm_isolate_snapshot_buffer,
+    intptr_t* vm_isolate_snapshot_size,
+    uint8_t** isolate_snapshot_buffer,
+    intptr_t* isolate_snapshot_size,
+    uint8_t** instructions_snapshot_buffer,
+    intptr_t* instructions_snapshot_size) {
+  UNREACHABLE();
+  return 0;
+}
+
+#else  // DART_PRECOMPILED
+
+DART_EXPORT Dart_Handle Dart_Precompile(
+    Dart_QualifiedFunctionName entry_points[],
+    bool reset_fields) {
+  API_TIMELINE_BEGIN_END;
   DARTSCOPE(Thread::Current());
-  Dart_Handle result = Api::CheckAndFinalizePendingClasses(I);
+  if (!FLAG_precompilation) {
+    return Dart_NewApiError("Flag --precompilation was not specified.");
+  }
+  Dart_Handle result = Api::CheckAndFinalizePendingClasses(T);
   if (::Dart_IsError(result)) {
     return result;
   }
@@ -6043,7 +5921,7 @@
   const Error& error = Error::Handle(Precompiler::CompileAll(entry_points,
                                                              reset_fields));
   if (!error.IsNull()) {
-    return Api::NewHandle(I, error.raw());
+    return Api::NewHandle(T, error.raw());
   }
   return Api::Success();
 }
@@ -6057,7 +5935,13 @@
     uint8_t** instructions_snapshot_buffer,
     intptr_t* instructions_snapshot_size) {
   ASSERT(FLAG_load_deferred_eagerly);
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
+  if (I->compilation_allowed()) {
+    return Dart_NewApiError("Isolate is not precompiled. "
+                            "Did you forget to call Dart_Precompile?");
+  }
   if (vm_isolate_snapshot_buffer == NULL) {
     RETURN_NULL_ERROR(vm_isolate_snapshot_buffer);
   }
@@ -6077,7 +5961,7 @@
     RETURN_NULL_ERROR(instructions_snapshot_size);
   }
   // Finalize all classes if needed.
-  Dart_Handle state = Api::CheckAndFinalizePendingClasses(I);
+  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
   if (::Dart_IsError(state)) {
     return state;
   }
@@ -6093,5 +5977,11 @@
 
   return Api::Success();
 }
+#endif  // DART_PRECOMPILED
+
+
+DART_EXPORT bool Dart_IsRunningPrecompiledCode() {
+  return Dart::IsRunningPrecompiledCode();
+}
 
 }  // namespace dart
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 613778a..6172e1a 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -11,8 +11,6 @@
 
 namespace dart {
 
-DECLARE_FLAG(bool, trace_api);
-
 class ApiLocalScope;
 class ApiState;
 class FinalizablePersistentHandle;
@@ -24,20 +22,9 @@
 
 #define CURRENT_FUNC CanonicalFunction(__FUNCTION__)
 
-#if defined(DEBUG)
-#define TRACE_API_CALL(name)                                                   \
-  if (FLAG_trace_api) {                                                        \
-    OS::Print("Calling API func: %s\n", name);                                 \
-  }
-#else
-#define TRACE_API_CALL(name)
-#endif
-
-
 // Checks that the current isolate is not NULL.
 #define CHECK_ISOLATE(isolate)                                                 \
   do {                                                                         \
-    TRACE_API_CALL(CURRENT_FUNC);                                              \
     if ((isolate) == NULL) {                                                   \
       FATAL1("%s expects there to be a current isolate. Did you "              \
              "forget to call Dart_CreateIsolate or Dart_EnterIsolate?",        \
@@ -48,7 +35,6 @@
 // Checks that the current isolate is NULL.
 #define CHECK_NO_ISOLATE(isolate)                                              \
   do {                                                                         \
-    TRACE_API_CALL(CURRENT_FUNC);                                              \
     if ((isolate) != NULL) {                                                   \
       FATAL1("%s expects there to be no current isolate. Did you "             \
              "forget to call Dart_ExitIsolate?", CURRENT_FUNC);                \
@@ -56,13 +42,12 @@
   } while (0)
 
 // Checks that the current isolate is not NULL and that it has an API scope.
-#define CHECK_ISOLATE_SCOPE(isolate)                                           \
+#define CHECK_API_SCOPE(thread)                                                \
   do {                                                                         \
-    Isolate* tmp = (isolate);                                                  \
-    CHECK_ISOLATE(tmp);                                                        \
-    ApiState* state = tmp->api_state();                                        \
-    ASSERT(state);                                                             \
-    if (state->top_scope() == NULL) {                                          \
+    Thread* tmpT = (thread);                                                   \
+    Isolate* tmpI = tmpT->isolate();                                           \
+    CHECK_ISOLATE(tmpI);                                                       \
+    if (tmpT->api_top_scope() == NULL) {                                       \
       FATAL1("%s expects to find a current scope. Did you forget to call "     \
            "Dart_EnterScope?", CURRENT_FUNC);                                  \
     }                                                                          \
@@ -70,8 +55,7 @@
 
 #define DARTSCOPE(thread)                                                      \
   Thread* T = (thread);                                                        \
-  Isolate* I = T->isolate();                                                   \
-  CHECK_ISOLATE_SCOPE(I);                                                      \
+  CHECK_API_SCOPE(T);                                                          \
   HANDLESCOPE(T);
 
 
@@ -112,7 +96,7 @@
   // Create on the stack to provide a new throw-safe api scope.
   class Scope : public StackResource {
    public:
-    explicit Scope(Isolate* isolate) : StackResource(isolate) {
+    explicit Scope(Thread* thread) : StackResource(thread) {
       Dart_EnterScope();
     }
     ~Scope() {
@@ -124,7 +108,7 @@
   };
 
   // Creates a new local handle.
-  static Dart_Handle NewHandle(Isolate* isolate, RawObject* raw);
+  static Dart_Handle NewHandle(Thread* thread, RawObject* raw);
 
   // Unwraps the raw object from the handle.
   static RawObject* UnwrapHandle(Dart_Handle object);
@@ -146,7 +130,7 @@
   // Returns an Error handle if isolate is in an inconsistent state
   // or there was an error while finalizing classes.
   // Returns a Success handle when no error condition exists.
-  static Dart_Handle CheckAndFinalizePendingClasses(Isolate *isolate);
+  static Dart_Handle CheckAndFinalizePendingClasses(Thread *thread);
 
   // Casts the internal Isolate* type to the external Dart_Isolate type.
   static Dart_Isolate CastIsolate(Isolate* isolate);
@@ -216,7 +200,7 @@
   }
 
   // Retrieves the top ApiLocalScope.
-  static ApiLocalScope* TopScope(Isolate* isolate);
+  static ApiLocalScope* TopScope(Thread* thread);
 
   // Performs one-time initialization needed by the API.
   static void InitOnce();
@@ -269,11 +253,11 @@
   static void SetWeakHandleReturnValue(NativeArguments* args,
                                        Dart_WeakPersistentHandle retval);
 
-  static RawString* CallEnvironmentCallback(Isolate* isolate,
+  static RawString* CallEnvironmentCallback(Thread* thread,
                                             const String& name);
 
  private:
-  static Dart_Handle InitNewHandle(Isolate* isolate, RawObject* raw);
+  static Dart_Handle InitNewHandle(Thread* thread, RawObject* raw);
 
   // Thread local key used by the API. Currently holds the current
   // ApiNativeScope if any.
@@ -286,23 +270,6 @@
   friend class ApiNativeScope;
 };
 
-class IsolateSaver {
- public:
-  explicit IsolateSaver(Isolate* current_isolate)
-      : saved_isolate_(current_isolate) {
-  }
-  ~IsolateSaver() {
-    // TODO(koda): Audit users; they should know whether they're in an isolate.
-    if (saved_isolate_ != NULL) {
-      Thread::EnterIsolate(saved_isolate_);
-    }
-  }
- private:
-  Isolate* saved_isolate_;
-
-  DISALLOW_COPY_AND_ASSIGN(IsolateSaver);
-};
-
 // Start a scope in which no Dart API call backs are allowed.
 #define START_NO_CALLBACK_SCOPE(thread)                                        \
   thread->IncrementNoCallbackScopeDepth()
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 6a53ff7..a2cf1d3 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -8,7 +8,7 @@
 #include "include/dart_native_api.h"
 #include "include/dart_tools_api.h"
 #include "platform/assert.h"
-#include "platform/json.h"
+#include "platform/text_buffer.h"
 #include "platform/utils.h"
 #include "vm/class_finalizer.h"
 #include "vm/dart_api_impl.h"
@@ -254,7 +254,7 @@
   Dart_StringToCString(script_url, &cstr);
   EXPECT_STREQ("test-lib", cstr);
   EXPECT_EQ(2, line_number);
-  EXPECT_EQ(3, column_number);
+  EXPECT_EQ(13, column_number);
 
   // Out-of-bounds frames.
   result = Dart_GetActivationFrame(stacktrace, frame_count, &frame);
@@ -397,7 +397,6 @@
 
 
 TEST_CASE(ErrorHandleTypes) {
-  Isolate* isolate = Isolate::Current();
   const String& compile_message = String::Handle(String::New("CompileError"));
   const String& fatal_message = String::Handle(String::New("FatalError"));
 
@@ -406,9 +405,9 @@
   Dart_Handle exception_error =
       Dart_NewUnhandledExceptionError(NewString("ExceptionError"));
   Dart_Handle compile_error =
-      Api::NewHandle(isolate, LanguageError::New(compile_message));
+      Api::NewHandle(thread, LanguageError::New(compile_message));
   Dart_Handle fatal_error =
-      Api::NewHandle(isolate, UnwindError::New(fatal_message));
+      Api::NewHandle(thread, UnwindError::New(fatal_message));
 
   EXPECT_VALID(not_error);
   EXPECT(Dart_IsError(api_error));
@@ -450,13 +449,12 @@
 
 
 TEST_CASE(UnhandleExceptionError) {
-  Isolate* isolate = Isolate::Current();
   const char* exception_cstr = "";
 
   // Test with an API Error.
   const char* kApiError = "Api Error Exception Test.";
   Dart_Handle api_error = Api::NewHandle(
-      isolate,
+      thread,
       ApiError::New(String::Handle(String::New(kApiError))));
   Dart_Handle exception_error = Dart_NewUnhandledExceptionError(api_error);
   EXPECT(!Dart_IsApiError(exception_error));
@@ -471,7 +469,7 @@
   const String& compile_message =
       String::Handle(String::New(kCompileError));
   Dart_Handle compile_error =
-      Api::NewHandle(isolate, LanguageError::New(compile_message));
+      Api::NewHandle(thread, LanguageError::New(compile_message));
   exception_error = Dart_NewUnhandledExceptionError(compile_error);
   EXPECT(!Dart_IsApiError(exception_error));
   EXPECT(Dart_IsUnhandledExceptionError(exception_error));
@@ -484,14 +482,14 @@
   const String& fatal_message =
       String::Handle(String::New("FatalError Exception Test."));
   Dart_Handle fatal_error =
-      Api::NewHandle(isolate, UnwindError::New(fatal_message));
+      Api::NewHandle(thread, UnwindError::New(fatal_message));
   exception_error = Dart_NewUnhandledExceptionError(fatal_error);
   EXPECT(Dart_IsError(exception_error));
   EXPECT(!Dart_IsUnhandledExceptionError(exception_error));
 
   // Test with a Regular object.
   const char* kRegularString = "Regular String Exception Test.";
-  Dart_Handle obj = Api::NewHandle(isolate, String::New(kRegularString));
+  Dart_Handle obj = Api::NewHandle(thread, String::New(kRegularString));
   exception_error = Dart_NewUnhandledExceptionError(obj);
   EXPECT(!Dart_IsApiError(exception_error));
   EXPECT(Dart_IsUnhandledExceptionError(exception_error));
@@ -617,7 +615,7 @@
 
   // Non-instance objects.
   {
-    DARTSCOPE(Thread::Current());
+    DARTSCOPE(thread);
     Dart_Handle lib1 = Dart_LookupLibrary(dart_core);
     Dart_Handle lib2 = Dart_LookupLibrary(dart_mirrors);
 
@@ -662,7 +660,7 @@
 
   // Non-instance objects.
   {
-    DARTSCOPE(Thread::Current());
+    DARTSCOPE(thread);
     Dart_Handle lib1 = Dart_LookupLibrary(dart_core);
     Dart_Handle lib2 = Dart_LookupLibrary(dart_mirrors);
 
@@ -1226,7 +1224,7 @@
         NULL);
     EXPECT_VALID(small16);
     {
-      DARTSCOPE(Thread::Current());
+      DARTSCOPE(thread);
       String& handle = String::Handle();
       handle ^= Api::UnwrapHandle(big8);
       EXPECT(handle.IsOld());
@@ -1260,7 +1258,7 @@
         kSmallLength);
     EXPECT_VALID(small);
     {
-      DARTSCOPE(Thread::Current());
+      DARTSCOPE(thread);
       ExternalTypedData& handle = ExternalTypedData::Handle();
       handle ^= Api::UnwrapHandle(big);
       EXPECT(handle.IsOld());
@@ -2379,23 +2377,21 @@
 UNIT_TEST_CASE(EnterExitScope) {
   TestIsolateScope __test_isolate__;
 
-  Isolate* isolate = Isolate::Current();
-  EXPECT(isolate != NULL);
-  ApiState* state = isolate->api_state();
-  EXPECT(state != NULL);
-  ApiLocalScope* scope = state->top_scope();
+  Thread* thread = Thread::Current();
+  EXPECT(thread != NULL);
+  ApiLocalScope* scope = thread->api_top_scope();
   Dart_EnterScope();
   {
-    EXPECT(state->top_scope() != NULL);
+    EXPECT(thread->api_top_scope() != NULL);
     DARTSCOPE(Thread::Current());
     const String& str1 = String::Handle(String::New("Test String"));
-    Dart_Handle ref = Api::NewHandle(isolate, str1.raw());
+    Dart_Handle ref = Api::NewHandle(thread, str1.raw());
     String& str2 = String::Handle();
     str2 ^= Api::UnwrapHandle(ref);
     EXPECT(str1.Equals(str2));
   }
   Dart_ExitScope();
-  EXPECT(scope == state->top_scope());
+  EXPECT(scope == thread->api_top_scope());
 }
 
 
@@ -2409,17 +2405,17 @@
   EXPECT(isolate != NULL);
   ApiState* state = isolate->api_state();
   EXPECT(state != NULL);
-  ApiLocalScope* scope = state->top_scope();
+  ApiLocalScope* scope = thread->api_top_scope();
   Dart_PersistentHandle handles[2000];
   Dart_EnterScope();
   {
     DARTSCOPE(Thread::Current());
-    Dart_Handle ref1 = Api::NewHandle(isolate, String::New(kTestString1));
+    Dart_Handle ref1 = Api::NewHandle(thread, String::New(kTestString1));
     for (int i = 0; i < 1000; i++) {
       handles[i] = Dart_NewPersistentHandle(ref1);
     }
     Dart_EnterScope();
-    Dart_Handle ref2 = Api::NewHandle(isolate, String::New(kTestString2));
+    Dart_Handle ref2 = Api::NewHandle(thread, String::New(kTestString2));
     for (int i = 1000; i < 2000; i++) {
       handles[i] = Dart_NewPersistentHandle(ref2);
     }
@@ -2460,7 +2456,7 @@
       EXPECT(str.Equals(kTestString2));
     }
   }
-  EXPECT(scope == state->top_scope());
+  EXPECT(scope == thread->api_top_scope());
   EXPECT_EQ(2001, state->CountPersistentHandles());
   Dart_ShutdownIsolate();
 }
@@ -2502,22 +2498,22 @@
   const char* kTestString2 = "Test String2";
   TestIsolateScope __test_isolate__;
 
-  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(Thread::Current());
+  Isolate* isolate = T->isolate();
   EXPECT(isolate != NULL);
   ApiState* state = isolate->api_state();
   EXPECT(state != NULL);
-  DARTSCOPE(Thread::Current());
   String& str = String::Handle();
 
   // Start with a known persistent handle.
-  Dart_Handle ref1 = Api::NewHandle(isolate, String::New(kTestString1));
+  Dart_Handle ref1 = Api::NewHandle(T, String::New(kTestString1));
   Dart_PersistentHandle obj = Dart_NewPersistentHandle(ref1);
   EXPECT(state->IsValidPersistentHandle(obj));
   str ^= PersistentHandle::Cast(obj)->raw();
   EXPECT(str.Equals(kTestString1));
 
   // Now create another local handle and assign it to the persistent handle.
-  Dart_Handle ref2 = Api::NewHandle(isolate, String::New(kTestString2));
+  Dart_Handle ref2 = Api::NewHandle(T, String::New(kTestString2));
   Dart_SetPersistentHandle(obj, ref2);
   str ^= PersistentHandle::Cast(obj)->raw();
   EXPECT(str.Equals(kTestString2));
@@ -2585,9 +2581,8 @@
     // Create an object in old space.
     Dart_Handle old_ref;
     {
-      Isolate* isolate = Isolate::Current();
       DARTSCOPE(Thread::Current());
-      old_ref = Api::NewHandle(isolate, String::New("old string", Heap::kOld));
+      old_ref = Api::NewHandle(thread, String::New("old string", Heap::kOld));
       EXPECT_VALID(old_ref);
     }
 
@@ -2753,7 +2748,6 @@
                                          kWeak1ExternalSize,
                                          NopCallback);
     EXPECT_VALID(AsHandle(weak1));
-    EXPECT(!Dart_IsPrologueWeakPersistentHandle(weak1));
     Dart_ExitScope();
   }
   Dart_PersistentHandle strong_ref = NULL;
@@ -2788,33 +2782,6 @@
 }
 
 
-TEST_CASE(PrologueWeakPersistentHandleExternalAllocationSize) {
-  Heap* heap = Isolate::Current()->heap();
-  EXPECT(heap->ExternalInWords(Heap::kNew) == 0);
-  EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
-  Dart_WeakPersistentHandle pwph = NULL;
-  static const intptr_t kWeakExternalSize = 1 * KB;
-  {
-    Dart_EnterScope();
-    Dart_Handle obj = NewString("a string");
-    EXPECT_VALID(obj);
-    pwph = Dart_NewPrologueWeakPersistentHandle(
-        obj, NULL, kWeakExternalSize, NopCallback);
-    EXPECT_VALID(AsHandle(pwph));
-    Dart_ExitScope();
-  }
-  EXPECT(heap->ExternalInWords(Heap::kNew) == kWeakExternalSize / kWordSize);
-  EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
-  // Promoting the string should transfer the external size to old.
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-  EXPECT(heap->ExternalInWords(Heap::kNew) == 0);
-  EXPECT(heap->ExternalInWords(Heap::kOld) == kWeakExternalSize / kWordSize);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
-}
-
-
 TEST_CASE(WeakPersistentHandleExternalAllocationSizeNewspaceGC) {
   Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
   Heap* heap = Isolate::Current()->heap();
@@ -2860,14 +2827,14 @@
   // Check that external allocation in old space can trigger GC.
   Isolate* isolate = Isolate::Current();
   Dart_EnterScope();
-  Dart_Handle live = Api::NewHandle(isolate, String::New("live", Heap::kOld));
+  Dart_Handle live = Api::NewHandle(thread, String::New("live", Heap::kOld));
   EXPECT_VALID(live);
   Dart_WeakPersistentHandle weak = NULL;
   EXPECT_EQ(0, isolate->heap()->ExternalInWords(Heap::kOld));
   const intptr_t kSmallExternalSize = 1 * KB;
   {
     Dart_EnterScope();
-    Dart_Handle dead = Api::NewHandle(isolate, String::New("dead", Heap::kOld));
+    Dart_Handle dead = Api::NewHandle(thread, String::New("dead", Heap::kOld));
     EXPECT_VALID(dead);
     weak = Dart_NewWeakPersistentHandle(dead,
                                         NULL,
@@ -2927,402 +2894,6 @@
 static Dart_WeakPersistentHandle weak1 = NULL;
 static Dart_WeakPersistentHandle weak2 = NULL;
 static Dart_WeakPersistentHandle weak3 = NULL;
-static Dart_WeakPersistentHandle weak4 = NULL;
-
-
-static void ObjectGroupsCallback(void* isolate_callback_data,
-                                 Dart_WeakPersistentHandle handle,
-                                 void* peer) {
-  if (handle == weak1) {
-    weak1 = NULL;
-  } else if (handle == weak2) {
-    weak2 = NULL;
-  } else if (handle == weak3) {
-    weak3 = NULL;
-  } else if (handle == weak4) {
-    weak4 = NULL;
-  }
-}
-
-
-TEST_CASE(ObjectGroups) {
-  Dart_PersistentHandle strong = NULL;
-  Dart_WeakPersistentHandle strong_weak = NULL;
-
-  Dart_EnterScope();
-  {
-    Isolate* isolate = Isolate::Current();
-    DARTSCOPE(Thread::Current());
-
-    Dart_Handle local = Api::NewHandle(
-        isolate, String::New("strongly reachable", Heap::kOld));
-    strong = Dart_NewPersistentHandle(local);
-    strong_weak = Dart_NewWeakPersistentHandle(local, NULL, 0, NopCallback);
-    EXPECT_VALID(AsHandle(strong));
-    EXPECT(!Dart_IsNull(AsHandle(strong)));
-
-    weak1 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kOld)),
-        NULL, 0, ObjectGroupsCallback);
-    EXPECT_VALID(AsHandle(weak1));
-    EXPECT(!Dart_IsNull(AsHandle(weak1)));
-
-    weak2 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kOld)),
-        NULL, 0, ObjectGroupsCallback);
-    EXPECT_VALID(AsHandle(weak2));
-    EXPECT(!Dart_IsNull(AsHandle(weak2)));
-
-    weak3 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kOld)),
-        NULL, 0, ObjectGroupsCallback);
-    EXPECT_VALID(AsHandle(weak3));
-    EXPECT(!Dart_IsNull(AsHandle(weak3)));
-
-    weak4 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 4", Heap::kOld)),
-        NULL, 0, ObjectGroupsCallback);
-    EXPECT_VALID(AsHandle(weak4));
-    EXPECT(!Dart_IsNull(AsHandle(weak4)));
-  }
-  Dart_ExitScope();
-
-  {
-    Dart_EnterScope();
-    EXPECT_VALID(AsHandle(strong));
-    EXPECT_VALID(AsHandle(weak1));
-    EXPECT_VALID(AsHandle(weak2));
-    EXPECT_VALID(AsHandle(weak3));
-    EXPECT_VALID(AsHandle(weak4));
-    Dart_ExitScope();
-  }
-
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-
-  {
-    Dart_EnterScope();
-    // New space collection should not affect old space objects
-    EXPECT(!Dart_IsNull(AsHandle(weak1)));
-    EXPECT(!Dart_IsNull(AsHandle(weak2)));
-    EXPECT(!Dart_IsNull(AsHandle(weak3)));
-    EXPECT(!Dart_IsNull(AsHandle(weak4)));
-    Dart_ExitScope();
-  }
-
-  {
-    Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder();
-    EXPECT_NOTNULL(builder);
-
-    Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak1, weak1);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, strong_weak, strong_weak));
-
-    set = Dart_NewWeakReferenceSet(builder, weak2, weak2);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak1, weak1));
-
-    set = Dart_NewWeakReferenceSet(builder, weak3, weak3);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak2, weak2));
-
-    set = Dart_NewWeakReferenceSet(builder, weak4, weak4);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak3, weak3));
-
-    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  }
-
-  {
-    Dart_EnterScope();
-    // All weak references should be preserved.
-    EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
-    EXPECT(!Dart_IsNull(AsHandle(weak1)));
-    EXPECT(!Dart_IsNull(AsHandle(weak2)));
-    EXPECT(!Dart_IsNull(AsHandle(weak3)));
-    EXPECT(!Dart_IsNull(AsHandle(weak4)));
-    Dart_ExitScope();
-  }
-
-  {
-    Dart_EnterScope();
-    Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder();
-    EXPECT_NOTNULL(builder);
-
-    Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak1, weak1);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, strong_weak, strong_weak));
-
-    set = Dart_NewWeakReferenceSet(builder, weak2, weak2);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak1, weak1));
-
-    set = Dart_NewWeakReferenceSet(builder, weak2, weak2);
-    EXPECT_NOTNULL(set);
-
-    // Strong reference to weak3 to retain weak3 and weak4.
-    Dart_PersistentHandle weak3_strong_ref =
-        Dart_NewPersistentHandle(AsHandle(weak3));
-    EXPECT_VALID(AsHandle(weak3_strong_ref));
-
-    set = Dart_NewWeakReferenceSet(builder, weak4, weak4);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak3, weak3));
-
-    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-
-    // Delete strong reference to weak3.
-    Dart_DeletePersistentHandle(weak3_strong_ref);
-    Dart_ExitScope();
-  }
-
-  {
-    Dart_EnterScope();
-    // All weak references should be preserved.
-    EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
-    EXPECT(!Dart_IsNull(AsHandle(weak1)));
-    EXPECT(!Dart_IsNull(AsHandle(weak2)));
-    EXPECT(!Dart_IsNull(AsHandle(weak3)));
-    EXPECT(!Dart_IsNull(AsHandle(weak4)));
-    Dart_ExitScope();
-  }
-
-  {
-    Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder();
-    EXPECT_NOTNULL(builder);
-
-    Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak1, weak1);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, strong_weak, strong_weak));
-
-    set = Dart_NewWeakReferenceSet(builder, weak2, weak2);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak1, weak1));
-
-    set = Dart_NewWeakReferenceSet(builder, weak2, weak2);
-    EXPECT_NOTNULL(set);
-
-    set = Dart_NewWeakReferenceSet(builder, weak4, weak4);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak3, weak3));
-
-    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  }
-
-  {
-    Dart_EnterScope();
-    // Only weak1 and weak2 should be preserved.
-    EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
-    EXPECT(!Dart_IsNull(AsHandle(weak1)));
-    EXPECT(!Dart_IsNull(AsHandle(weak2)));
-    EXPECT(weak3 == NULL);
-    EXPECT(weak4 == NULL);
-    Dart_ExitScope();
-  }
-
-  {
-    Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder();
-    EXPECT_NOTNULL(builder);
-
-    Dart_WeakPersistentHandle lweak3 = Dart_NewWeakPersistentHandle(
-        Dart_Null(), NULL, 0, NopCallback);
-
-    Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak1, weak1);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, strong_weak, strong_weak));
-
-    // lweak3 is unreferenced so weak2 is unreferenced and should be cleared
-    set = Dart_NewWeakReferenceSet(builder, weak2, weak2);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, lweak3, lweak3));
-
-    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  }
-
-  {
-    Dart_EnterScope();
-    // Only weak1 should be preserved, weak3 should not preserve weak2.
-    EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
-    EXPECT(!Dart_IsNull(AsHandle(weak1)));
-    EXPECT(weak2 == NULL);
-    EXPECT(weak3 == NULL);  // was cleared, should remain cleared
-    EXPECT(weak4 == NULL);  // was cleared, should remain cleared
-    Dart_ExitScope();
-  }
-
-  {
-    Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder();
-    EXPECT_NOTNULL(builder);
-
-    Dart_WeakPersistentHandle lweak2 = Dart_NewWeakPersistentHandle(
-        Dart_Null(), NULL, 0, NopCallback);
-    Dart_WeakPersistentHandle lweak3 = Dart_NewWeakPersistentHandle(
-        Dart_Null(), NULL, 0, NopCallback);
-    Dart_WeakPersistentHandle lweak4 = Dart_NewWeakPersistentHandle(
-        Dart_Null(), NULL, 0, NopCallback);
-    // lweak{2,3,4} are cleared and should have no effect on weak1
-    Dart_WeakReferenceSet set =
-        Dart_NewWeakReferenceSet(builder, strong_weak, strong_weak);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, lweak2, lweak2));
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, lweak3, lweak3));
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, lweak4, lweak4));
-
-    // weak1 is weakly reachable and should be cleared
-    set = Dart_NewWeakReferenceSet(builder, weak1, weak1);
-    EXPECT_NOTNULL(set);
-
-    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  }
-
-  {
-    Dart_EnterScope();
-    // All weak references should now be cleared.
-    EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
-    EXPECT(weak1 == NULL);
-    EXPECT(weak2 == NULL);
-    EXPECT(weak3 == NULL);
-    EXPECT(weak4 == NULL);
-    Dart_ExitScope();
-  }
-}
-
-
-TEST_CASE(DuplicateWeakReferenceSetEntries) {
-  Isolate* isolate = Isolate::Current();
-  Dart_PersistentHandle strong = NULL;
-  Dart_WeakPersistentHandle weak = NULL;  // A weak handle to strong.
-
-  Dart_EnterScope();
-  {
-    DARTSCOPE(Thread::Current());
-
-    // Strong handle to keep the reference set alive.
-    Dart_Handle local = Api::NewHandle(isolate, String::New("string"));
-    strong = Dart_NewPersistentHandle(local);
-    EXPECT_VALID(AsHandle(strong));
-    EXPECT(!Dart_IsNull(AsHandle(strong)));
-    // Corresponding weak handle to use as key and duplicated value.
-    weak = Dart_NewWeakPersistentHandle(local, NULL, 0, NopCallback);
-    EXPECT_VALID(AsHandle(weak));
-    EXPECT(!Dart_IsNull(AsHandle(weak)));
-  }
-  Dart_ExitScope();
-
-  {
-    Dart_EnterScope();
-    // Create the weak reference set.
-    Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder();
-    EXPECT_NOTNULL(builder);
-    // Register the key and the first copy of the value.
-    Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak, weak);
-    EXPECT_NOTNULL(set);
-    // Add the second copy of the value.
-    Dart_Handle result = Dart_AppendValueToWeakReferenceSet(set, weak);
-    EXPECT_VALID(result);
-
-    // Trigger GC to ensure that we can visit duplicate entries in weak
-    // reference sets.
-    isolate->heap()->CollectGarbage(Heap::kNew);
-    Dart_ExitScope();
-  }
-}
-
-
-static Dart_WeakPersistentHandle old_pwph = NULL;
-static Dart_WeakPersistentHandle new_pwph = NULL;
-
-
-static void PrologueWeakHandleCallback(void* isolate_callback_data,
-                                       Dart_WeakPersistentHandle handle,
-                                       void* peer) {
-  if (handle == old_pwph) {
-    old_pwph = NULL;
-  } else if (handle == new_pwph) {
-    new_pwph = NULL;
-  }
-}
-
-
-TEST_CASE(PrologueWeakPersistentHandles) {
-  Dart_EnterScope();
-  {
-    Isolate* isolate = Isolate::Current();
-    DARTSCOPE(Thread::Current());
-    new_pwph = Dart_NewPrologueWeakPersistentHandle(
-        Api::NewHandle(isolate,
-                       String::New("new space prologue weak", Heap::kNew)),
-        NULL, 0, PrologueWeakHandleCallback);
-    EXPECT_VALID(AsHandle(new_pwph));
-    EXPECT(!Dart_IsNull(AsHandle(new_pwph)));
-    old_pwph = Dart_NewPrologueWeakPersistentHandle(
-        Api::NewHandle(isolate,
-                       String::New("old space prologue weak", Heap::kOld)),
-        NULL, 0, PrologueWeakHandleCallback);
-    EXPECT_VALID(AsHandle(old_pwph));
-    EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
-  }
-  Dart_ExitScope();
-
-  {
-    Dart_EnterScope();
-    EXPECT_VALID(AsHandle(new_pwph));
-    EXPECT(!Dart_IsNull(AsHandle(new_pwph)));
-    EXPECT(Dart_IsPrologueWeakPersistentHandle(new_pwph));
-    EXPECT_VALID(AsHandle(old_pwph));
-    EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
-    EXPECT(Dart_IsPrologueWeakPersistentHandle(old_pwph));
-    Dart_ExitScope();
-  }
-
-  // Garbage collect new space without invoking API callbacks.
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-
-  {
-    Dart_EnterScope();
-    // Both prologue weak handles should be preserved.
-    EXPECT(!Dart_IsNull(AsHandle(new_pwph)));
-    EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
-    Dart_ExitScope();
-  }
-
-  // Garbage collect old space without invoking API callbacks.
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld,
-                                             Heap::kIgnoreApiCallbacks,
-                                             Heap::kGCTestCase);
-
-  {
-    Dart_EnterScope();
-    // Both prologue weak handles should be preserved.
-    EXPECT(!Dart_IsNull(AsHandle(new_pwph)));
-    EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
-    Dart_ExitScope();
-  }
-
-  // Garbage collect new space invoking API callbacks.
-  GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks);
-
-  {
-    Dart_EnterScope();
-    // The prologue weak handle with a new space referent should now be
-    // cleared.  The old space referent should be preserved.
-    EXPECT(new_pwph == NULL);
-    EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
-    Dart_ExitScope();
-  }
-
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld,
-                                             Heap::kInvokeApiCallbacks,
-                                             Heap::kGCTestCase);
-
-  {
-    Dart_EnterScope();
-    // The prologue weak handle with an old space referent should now be
-    // cleared.  The new space referent should remain cleared.
-    EXPECT(new_pwph == NULL);
-    EXPECT(old_pwph == NULL);
-    Dart_ExitScope();
-  }
-}
 
 
 static void ImplicitReferencesCallback(void* isolate_callback_data,
@@ -3344,11 +2915,10 @@
 
   Dart_EnterScope();
   {
-    Isolate* isolate = Isolate::Current();
     DARTSCOPE(Thread::Current());
 
     Dart_Handle local = Api::NewHandle(
-        isolate, String::New("strongly reachable", Heap::kOld));
+        thread, String::New("strongly reachable", Heap::kOld));
     strong = Dart_NewPersistentHandle(local);
     strong_weak = Dart_NewWeakPersistentHandle(local, NULL, 0, NopCallback);
 
@@ -3359,19 +2929,19 @@
     EXPECT(Dart_IdentityEquals(AsHandle(strong), AsHandle(strong_weak)))
 
     weak1 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kOld)),
+        Api::NewHandle(thread, String::New("weakly reachable 1", Heap::kOld)),
         NULL, 0, ImplicitReferencesCallback);
     EXPECT(!Dart_IsNull(AsHandle(weak1)));
     EXPECT_VALID(AsHandle(weak1));
 
     weak2 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kOld)),
+        Api::NewHandle(thread, String::New("weakly reachable 2", Heap::kOld)),
         NULL, 0, ImplicitReferencesCallback);
     EXPECT(!Dart_IsNull(AsHandle(weak2)));
     EXPECT_VALID(AsHandle(weak2));
 
     weak3 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kOld)),
+        Api::NewHandle(thread, String::New("weakly reachable 3", Heap::kOld)),
         NULL, 0, ImplicitReferencesCallback);
     EXPECT(!Dart_IsNull(AsHandle(weak3)));
     EXPECT_VALID(AsHandle(weak3));
@@ -3398,53 +2968,6 @@
     EXPECT(!Dart_IsNull(AsHandle(weak3)));
     Dart_ExitScope();
   }
-
-  // A strongly referenced key should preserve all the values.
-  {
-    Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder();
-    EXPECT_NOTNULL(builder);
-
-    Dart_WeakReferenceSet set =
-        Dart_NewWeakReferenceSet(builder, strong_weak, 0);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak1));
-    EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak2));
-    EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak3));
-
-    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  }
-
-  {
-    Dart_EnterScope();
-    // All weak references should be preserved.
-    EXPECT_VALID(AsHandle(strong_weak));
-    EXPECT(!Dart_IsNull(AsHandle(weak1)));
-    EXPECT(!Dart_IsNull(AsHandle(weak2)));
-    EXPECT(!Dart_IsNull(AsHandle(weak3)));
-    Dart_ExitScope();
-  }
-
-  // Key membership does not imply a strong reference.
-  {
-    Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder();
-    EXPECT_NOTNULL(builder);
-
-    Dart_WeakReferenceSet set =
-        Dart_NewWeakReferenceSet(builder, strong_weak, weak1);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak3, weak2));
-
-    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  }
-
-  {
-    Dart_EnterScope();
-    // All weak references except weak3 should be preserved.
-    EXPECT(!Dart_IsNull(AsHandle(weak1)));
-    EXPECT(!Dart_IsNull(AsHandle(weak2)));
-    EXPECT(weak3 == NULL);
-    Dart_ExitScope();
-  }
 }
 
 
@@ -3455,11 +2978,10 @@
 
   Dart_EnterScope();
   {
-    Isolate* isolate = Isolate::Current();
     DARTSCOPE(Thread::Current());
 
     Dart_Handle local = Api::NewHandle(
-        isolate, String::New("strongly reachable", Heap::kOld));
+        thread, String::New("strongly reachable", Heap::kOld));
     strong = Dart_NewPersistentHandle(local);
     strong_weak = Dart_NewWeakPersistentHandle(local, NULL, 0, NopCallback);
 
@@ -3470,19 +2992,19 @@
     EXPECT(Dart_IdentityEquals(AsHandle(strong), AsHandle(strong_weak)))
 
     weak1 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kNew)),
+        Api::NewHandle(thread, String::New("weakly reachable 1", Heap::kNew)),
         NULL, 0, ImplicitReferencesCallback);
     EXPECT(!Dart_IsNull(AsHandle(weak1)));
     EXPECT_VALID(AsHandle(weak1));
 
     weak2 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kNew)),
+        Api::NewHandle(thread, String::New("weakly reachable 2", Heap::kNew)),
         NULL, 0, ImplicitReferencesCallback);
     EXPECT(!Dart_IsNull(AsHandle(weak2)));
     EXPECT_VALID(AsHandle(weak2));
 
     weak3 = Dart_NewWeakPersistentHandle(
-        Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kNew)),
+        Api::NewHandle(thread, String::New("weakly reachable 3", Heap::kNew)),
         NULL, 0, ImplicitReferencesCallback);
     EXPECT(!Dart_IsNull(AsHandle(weak3)));
     EXPECT_VALID(AsHandle(weak3));
@@ -3508,41 +3030,6 @@
     EXPECT(!Dart_IsNull(AsHandle(weak3)));
     Dart_ExitScope();
   }
-
-  // A strongly referenced key should preserve all the values.
-  {
-    Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder();
-    EXPECT_NOTNULL(builder);
-
-    Dart_WeakReferenceSet set =
-        Dart_NewWeakReferenceSet(builder, strong_weak, 0);
-    EXPECT_NOTNULL(set);
-    EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak1));
-    EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak2));
-    EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak3));
-
-    GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks);
-  }
-
-  {
-    Dart_EnterScope();
-    // All weak references should be preserved.
-    EXPECT(!Dart_IsNull(AsHandle(weak1)));
-    EXPECT(!Dart_IsNull(AsHandle(weak2)));
-    EXPECT(!Dart_IsNull(AsHandle(weak3)));
-    Dart_ExitScope();
-  }
-
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-
-  {
-    Dart_EnterScope();
-    // No weak references should be preserved.
-    EXPECT(weak1 == NULL);
-    EXPECT(weak2 == NULL);
-    EXPECT(weak3 == NULL);
-    Dart_ExitScope();
-  }
 }
 
 
@@ -3715,9 +3202,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   EXPECT(isolate != NULL);
-  ApiState* state = isolate->api_state();
-  EXPECT(state != NULL);
-  ApiLocalScope* scope = state->top_scope();
+  ApiLocalScope* scope = thread->api_top_scope();
   Dart_Handle handles[300];
   {
     StackZone zone(thread);
@@ -3727,9 +3212,9 @@
     // Start a new scope and allocate some local handles.
     Dart_EnterScope();
     for (int i = 0; i < 100; i++) {
-      handles[i] = Api::NewHandle(isolate, Smi::New(i));
+      handles[i] = Api::NewHandle(thread, Smi::New(i));
     }
-    EXPECT_EQ(100, state->CountLocalHandles());
+    EXPECT_EQ(100, thread->CountLocalHandles());
     for (int i = 0; i < 100; i++) {
       val ^= Api::UnwrapHandle(handles[i]);
       EXPECT_EQ(i, val.Value());
@@ -3738,9 +3223,9 @@
     {
       Dart_EnterScope();
       for (int i = 100; i < 200; i++) {
-        handles[i] = Api::NewHandle(isolate, Smi::New(i));
+        handles[i] = Api::NewHandle(thread, Smi::New(i));
       }
-      EXPECT_EQ(200, state->CountLocalHandles());
+      EXPECT_EQ(200, thread->CountLocalHandles());
       for (int i = 100; i < 200; i++) {
         val ^= Api::UnwrapHandle(handles[i]);
         EXPECT_EQ(i, val.Value());
@@ -3750,25 +3235,25 @@
       {
         Dart_EnterScope();
         for (int i = 200; i < 300; i++) {
-          handles[i] = Api::NewHandle(isolate, Smi::New(i));
+          handles[i] = Api::NewHandle(thread, Smi::New(i));
         }
-        EXPECT_EQ(300, state->CountLocalHandles());
+        EXPECT_EQ(300, thread->CountLocalHandles());
         for (int i = 200; i < 300; i++) {
           val ^= Api::UnwrapHandle(handles[i]);
           EXPECT_EQ(i, val.Value());
         }
-        EXPECT_EQ(300, state->CountLocalHandles());
+        EXPECT_EQ(300, thread->CountLocalHandles());
         VERIFY_ON_TRANSITION;
         Dart_ExitScope();
       }
-      EXPECT_EQ(200, state->CountLocalHandles());
+      EXPECT_EQ(200, thread->CountLocalHandles());
       Dart_ExitScope();
     }
-    EXPECT_EQ(100, state->CountLocalHandles());
+    EXPECT_EQ(100, thread->CountLocalHandles());
     Dart_ExitScope();
   }
-  EXPECT_EQ(0, state->CountLocalHandles());
-  EXPECT(scope == state->top_scope());
+  EXPECT_EQ(0, thread->CountLocalHandles());
+  EXPECT(scope == thread->api_top_scope());
   Dart_ShutdownIsolate();
 }
 
@@ -3778,25 +3263,23 @@
 // exits.
 UNIT_TEST_CASE(LocalZoneMemory) {
   TestCase::CreateTestIsolate();
-  Isolate* isolate = Isolate::Current();
-  EXPECT(isolate != NULL);
-  ApiState* state = isolate->api_state();
-  EXPECT(state != NULL);
-  ApiLocalScope* scope = state->top_scope();
+  Thread* thread = Thread::Current();
+  EXPECT(thread != NULL);
+  ApiLocalScope* scope = thread->api_top_scope();
   {
     // Start a new scope and allocate some memory.
     Dart_EnterScope();
     for (int i = 0; i < 100; i++) {
       Dart_ScopeAllocate(16);
     }
-    EXPECT_EQ(1600, state->ZoneSizeInBytes());
+    EXPECT_EQ(1600, thread->ZoneSizeInBytes());
     // Start another scope and allocate some more memory.
     {
       Dart_EnterScope();
       for (int i = 0; i < 100; i++) {
         Dart_ScopeAllocate(16);
       }
-      EXPECT_EQ(3200, state->ZoneSizeInBytes());
+      EXPECT_EQ(3200, thread->ZoneSizeInBytes());
       {
         // Start another scope and allocate some more memory.
         {
@@ -3804,18 +3287,18 @@
           for (int i = 0; i < 200; i++) {
             Dart_ScopeAllocate(16);
           }
-          EXPECT_EQ(6400, state->ZoneSizeInBytes());
+          EXPECT_EQ(6400, thread->ZoneSizeInBytes());
           Dart_ExitScope();
         }
       }
-      EXPECT_EQ(3200, state->ZoneSizeInBytes());
+      EXPECT_EQ(3200, thread->ZoneSizeInBytes());
       Dart_ExitScope();
     }
-    EXPECT_EQ(1600, state->ZoneSizeInBytes());
+    EXPECT_EQ(1600, thread->ZoneSizeInBytes());
     Dart_ExitScope();
   }
-  EXPECT_EQ(0, state->ZoneSizeInBytes());
-  EXPECT(scope == state->top_scope());
+  EXPECT_EQ(0, thread->ZoneSizeInBytes());
+  EXPECT(scope == thread->api_top_scope());
   Dart_ShutdownIsolate();
 }
 
@@ -3858,7 +3341,7 @@
 }
 
 
-TEST_CASE(IsolateSetCheckedMode) {
+UNIT_TEST_CASE(IsolateSetCheckedMode) {
   const char* kScriptChars =
       "int bad1() {\n"
       "  int foo = 'string';\n"
@@ -3869,23 +3352,49 @@
       "  int five = 5;\n"
       "  return five;"
       "}\n";
-  Dart_Handle result;
 
-  // Create a test library and Load up a test script in it.
-  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  result = Dart_IsolateSetStrictCompilation(true);
-  EXPECT_VALID(result);
+  // Create an isolate with checked mode flags.
+  Dart_IsolateFlags api_flags;
+  api_flags.version = DART_FLAGS_CURRENT_VERSION;
+  api_flags.enable_type_checks = true;
+  api_flags.enable_asserts = true;
+  api_flags.enable_error_on_bad_type = true;
+  api_flags.enable_error_on_bad_override = true;
 
-  result = Dart_Invoke(lib, NewString("bad1"), 0, NULL);
-  EXPECT_ERROR(result, "Unhandled exception:\n"
-      "type 'String' is not a subtype of type 'int' of 'foo'");
+  char* err;
+  Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL,
+                                            bin::isolate_snapshot_buffer,
+                                            &api_flags,
+                                            NULL, &err);
+  if (isolate == NULL) {
+    OS::Print("Creation of isolate failed '%s'\n", err);
+    free(err);
+  }
+  EXPECT(isolate != NULL);
 
-  result = Dart_Invoke(lib, NewString("good1"), 0, NULL);
-  EXPECT_VALID(result);
+  {
+    Dart_EnterScope();
+    Dart_Handle url = NewString(TestCase::url());
+    Dart_Handle source = NewString(kScriptChars);
+    Dart_Handle result = Dart_SetLibraryTagHandler(TestCase::library_handler);
+    EXPECT_VALID(result);
+    Dart_Handle lib = Dart_LoadScript(url, source, 0, 0);
+    EXPECT_VALID(lib);
+    result = Dart_FinalizeLoading(false);
+    EXPECT_VALID(result);
+    result = Dart_Invoke(lib, NewString("bad1"), 0, NULL);
+    EXPECT_ERROR(result, "Unhandled exception:\n"
+        "type 'String' is not a subtype of type 'int' of 'foo'");
 
-  result = Dart_IsolateSetStrictCompilation(false);
-  EXPECT_ERROR(result, "Dart_IsolateSetStrictCompilation expects that the "
-                       "isolate has not yet compiled code.");
+    result = Dart_Invoke(lib, NewString("good1"), 0, NULL);
+    EXPECT_VALID(result);
+    Dart_ExitScope();
+  }
+
+  EXPECT(isolate != NULL);
+
+  // Shutdown the isolate.
+  Dart_ShutdownIsolate();
 }
 
 
@@ -4253,7 +3762,7 @@
   Dart_Handle url = NewString("library_url");
   Dart_Handle source = NewString(kImportedScriptChars);
   Dart_Handle imported_lib = Dart_LoadLibrary(url, source, 0, 0);
-  Dart_Handle prefix = NewString("");
+  Dart_Handle prefix = Dart_EmptyString();
   EXPECT_VALID(imported_lib);
   Dart_Handle result = Dart_LibraryImportLibrary(lib, imported_lib, prefix);
   EXPECT_VALID(result);
@@ -5126,7 +4635,7 @@
   Dart_Handle bad_args[1];
   bad_args[0] = Dart_NewApiError("myerror");
 
-  // Invoke the unnamed constructor.
+  // Allocate and Invoke the unnamed constructor passing in Dart_Null.
   Dart_Handle result = Dart_New(type, Dart_Null(), 0, NULL);
   EXPECT_VALID(result);
   bool instanceof = false;
@@ -5146,8 +4655,8 @@
   foo = Dart_GetField(obj, NewString("foo"));
   EXPECT(Dart_IsNull(foo));
 
-  // Invoke the unnamed constructor with an empty string.
-  result = Dart_New(type, NewString(""), 0, NULL);
+  // Allocate and Invoke the unnamed constructor passing in an empty string.
+  result = Dart_New(type, Dart_EmptyString(), 0, NULL);
   EXPECT_VALID(result);
   instanceof = false;
   EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
@@ -5163,7 +4672,15 @@
   instanceof = false;
   EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceof));
   EXPECT(instanceof);
-  result = Dart_InvokeConstructor(obj, NewString(""), 0, NULL);
+  // Use the empty string to invoke the unnamed constructor.
+  result = Dart_InvokeConstructor(obj, Dart_EmptyString(), 0, NULL);
+  EXPECT_VALID(result);
+  int_value = 0;
+  foo = Dart_GetField(result, NewString("foo"));
+  EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
+  EXPECT_EQ(7, int_value);
+  // use Dart_Null to invoke the unnamed constructor.
+  result = Dart_InvokeConstructor(obj, Dart_Null(), 0, NULL);
   EXPECT_VALID(result);
   int_value = 0;
   foo = Dart_GetField(result, NewString("foo"));
@@ -5336,7 +4853,7 @@
   Thread* thread = Thread::Current();
   const Library& library_obj = Api::UnwrapLibraryHandle(thread->zone(), lib);
   const String& name = String::Handle(String::New(str));
-  return Api::NewHandle(thread->isolate(), library_obj.PrivateName(name));
+  return Api::NewHandle(thread, library_obj.PrivateName(name));
 }
 
 
@@ -5747,11 +5264,7 @@
   const char* kScriptChars =
       "int test() native \"ThrowException_native\";";
   Dart_Handle result;
-  Isolate* isolate = Isolate::Current();
-  EXPECT(isolate != NULL);
-  ApiState* state = isolate->api_state();
-  EXPECT(state != NULL);
-  intptr_t size = state->ZoneSizeInBytes();
+  intptr_t size = thread->ZoneSizeInBytes();
   Dart_EnterScope();  // Start a Dart API scope for invoking API functions.
 
   // Load up a test script which extends the native wrapper class.
@@ -5770,7 +5283,7 @@
   EXPECT(Dart_ErrorHasException(result));
 
   Dart_ExitScope();  // Exit the Dart API scope.
-  EXPECT_EQ(size, state->ZoneSizeInBytes());
+  EXPECT_EQ(size, thread->ZoneSizeInBytes());
 }
 
 
@@ -6240,6 +5753,26 @@
   const char* uri_cstr = "";
   EXPECT_VALID(Dart_StringToCString(lib_uri, &uri_cstr));
   EXPECT_STREQ(TestCase::url(), uri_cstr);
+
+
+  Dart_Handle core_uri = Dart_NewStringFromCString("dart:core");
+  Dart_Handle core_lib = Dart_LookupLibrary(core_uri);
+  EXPECT_VALID(core_lib);
+  EXPECT(Dart_IsLibrary(core_lib));
+
+  Dart_Handle result = Dart_SetRootLibrary(core_uri);  // Not a library.
+  EXPECT(Dart_IsError(result));
+  root_lib = Dart_RootLibrary();
+  lib_uri = Dart_LibraryUrl(root_lib);
+  EXPECT_VALID(Dart_StringToCString(lib_uri, &uri_cstr));
+  EXPECT_STREQ(TestCase::url(), uri_cstr);  // Root library didn't change.
+
+  result = Dart_SetRootLibrary(core_lib);
+  EXPECT_VALID(result);
+  root_lib = Dart_RootLibrary();
+  lib_uri = Dart_LibraryUrl(root_lib);
+  EXPECT_VALID(Dart_StringToCString(lib_uri, &uri_cstr));
+  EXPECT_STREQ("dart:core", uri_cstr);  // Root library did change.
 }
 
 
@@ -7473,6 +7006,7 @@
                            Dart_CObject* message) {
   // Gets a null message.
   EXPECT_NOTNULL(message);
+  EXPECT_EQ(Dart_CObject_kArray, message->type);
   EXPECT_EQ(Dart_CObject_kSendPort, message->value.as_array.values[0]->type);
 
   // Post integer value.
@@ -7560,34 +7094,213 @@
 }
 
 
+void NewNativePort_sendInteger123(Dart_Port dest_port_id,
+                                  Dart_CObject *message) {
+  // Gets a send port message.
+  EXPECT_NOTNULL(message);
+  EXPECT_EQ(Dart_CObject_kArray, message->type);
+  EXPECT_EQ(Dart_CObject_kSendPort, message->value.as_array.values[0]->type);
+
+  // Post integer value.
+  Dart_PostInteger(
+      message->value.as_array.values[0]->value.as_send_port.id, 123);
+}
+
+
+void NewNativePort_sendInteger321(Dart_Port dest_port_id,
+                                  Dart_CObject* message) {
+  // Gets a null message.
+  EXPECT_NOTNULL(message);
+  EXPECT_EQ(Dart_CObject_kArray, message->type);
+  EXPECT_EQ(Dart_CObject_kSendPort, message->value.as_array.values[0]->type);
+
+  // Post integer value.
+  Dart_PostInteger(
+      message->value.as_array.values[0]->value.as_send_port.id, 321);
+}
+
+
+TEST_CASE(NativePortPostInteger) {
+  const char* kScriptChars =
+      "import 'dart:isolate';\n"
+      "void callPort(SendPort port) {\n"
+      "  var receivePort = new RawReceivePort();\n"
+      "  var replyPort = receivePort.sendPort;\n"
+      "  port.send([replyPort]);\n"
+      "  receivePort.handler = (message) {\n"
+      "    receivePort.close();\n"
+      "    throw new Exception(message);\n"
+      "  };\n"
+      "}\n";
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  Dart_EnterScope();
+
+  Dart_Port port_id1 =
+      Dart_NewNativePort("Port123", NewNativePort_sendInteger123, true);
+  Dart_Port port_id2 =
+      Dart_NewNativePort("Port321", NewNativePort_sendInteger321, true);
+
+  Dart_Handle send_port1 = Dart_NewSendPort(port_id1);
+  EXPECT_VALID(send_port1);
+  Dart_Handle send_port2 = Dart_NewSendPort(port_id2);
+  EXPECT_VALID(send_port2);
+
+  // Test first port.
+  Dart_Handle dart_args[1];
+  dart_args[0] = send_port1;
+  Dart_Handle result =
+      Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
+  EXPECT_VALID(result);
+  result = Dart_RunLoop();
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_ErrorHasException(result));
+  EXPECT_SUBSTRING("Exception: 123\n", Dart_GetError(result));
+
+  // result second port.
+  dart_args[0] = send_port2;
+  result = Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
+  EXPECT_VALID(result);
+  result = Dart_RunLoop();
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_ErrorHasException(result));
+  EXPECT_SUBSTRING("Exception: 321\n", Dart_GetError(result));
+
+  Dart_ExitScope();
+
+  // Delete the native ports.
+  EXPECT(Dart_CloseNativePort(port_id1));
+  EXPECT(Dart_CloseNativePort(port_id2));
+}
+
+
+void NewNativePort_nativeReceiveNull(Dart_Port dest_port_id,
+                                     Dart_CObject *message) {
+  EXPECT_NOTNULL(message);
+
+  if ((message->type == Dart_CObject_kArray) &&
+      (message->value.as_array.values[0]->type == Dart_CObject_kSendPort)) {
+    // Post integer value.
+    Dart_PostInteger(
+        message->value.as_array.values[0]->value.as_send_port.id, 123);
+  } else {
+    EXPECT_EQ(message->type, Dart_CObject_kNull);
+  }
+}
+
+
+TEST_CASE(NativePortReceiveNull) {
+  const char* kScriptChars =
+      "import 'dart:isolate';\n"
+      "void callPort(SendPort port) {\n"
+      "  var receivePort = new RawReceivePort();\n"
+      "  var replyPort = receivePort.sendPort;\n"
+      "  port.send(null);\n"
+      "  port.send([replyPort]);\n"
+      "  receivePort.handler = (message) {\n"
+      "    receivePort.close();\n"
+      "    throw new Exception(message);\n"
+      "  };\n"
+      "}\n";
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  Dart_EnterScope();
+
+  Dart_Port port_id1 =
+      Dart_NewNativePort("PortNull", NewNativePort_nativeReceiveNull, true);
+  Dart_Handle send_port1 = Dart_NewSendPort(port_id1);
+  EXPECT_VALID(send_port1);
+
+  // Test first port.
+  Dart_Handle dart_args[1];
+  dart_args[0] = send_port1;
+  Dart_Handle result =
+      Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
+  EXPECT_VALID(result);
+  result = Dart_RunLoop();
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_ErrorHasException(result));
+  EXPECT_SUBSTRING("Exception: 123\n", Dart_GetError(result));
+
+  Dart_ExitScope();
+
+  // Delete the native ports.
+  EXPECT(Dart_CloseNativePort(port_id1));
+}
+
+
+void NewNativePort_nativeReceiveInteger(Dart_Port dest_port_id,
+                                        Dart_CObject *message) {
+  EXPECT_NOTNULL(message);
+
+  if ((message->type == Dart_CObject_kArray) &&
+      (message->value.as_array.values[0]->type == Dart_CObject_kSendPort)) {
+    // Post integer value.
+    Dart_PostInteger(
+        message->value.as_array.values[0]->value.as_send_port.id, 123);
+  } else {
+    EXPECT_EQ(message->type, Dart_CObject_kInt32);
+    EXPECT_EQ(message->value.as_int32, 321);
+  }
+}
+
+
+TEST_CASE(NativePortReceiveInteger) {
+  const char* kScriptChars =
+      "import 'dart:isolate';\n"
+      "void callPort(SendPort port) {\n"
+      "  var receivePort = new RawReceivePort();\n"
+      "  var replyPort = receivePort.sendPort;\n"
+      "  port.send(321);\n"
+      "  port.send([replyPort]);\n"
+      "  receivePort.handler = (message) {\n"
+      "    receivePort.close();\n"
+      "    throw new Exception(message);\n"
+      "  };\n"
+      "}\n";
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  Dart_EnterScope();
+
+  Dart_Port port_id1 =
+      Dart_NewNativePort("PortNull", NewNativePort_nativeReceiveInteger, true);
+  Dart_Handle send_port1 = Dart_NewSendPort(port_id1);
+  EXPECT_VALID(send_port1);
+
+  // Test first port.
+  Dart_Handle dart_args[1];
+  dart_args[0] = send_port1;
+  Dart_Handle result =
+      Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
+  EXPECT_VALID(result);
+  result = Dart_RunLoop();
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_ErrorHasException(result));
+  EXPECT_SUBSTRING("Exception: 123\n", Dart_GetError(result));
+
+  Dart_ExitScope();
+
+  // Delete the native ports.
+  EXPECT(Dart_CloseNativePort(port_id1));
+}
+
+
 static Dart_Isolate RunLoopTestCallback(const char* script_name,
                                         const char* main,
                                         const char* package_root,
-                                        const char** package_map,
+                                        const char* package_config,
                                         Dart_IsolateFlags* flags,
                                         void* data,
                                         char** error) {
   const char* kScriptChars =
       "import 'builtin';\n"
       "import 'dart:isolate';\n"
-      "void entry(message) {\n"
-      "  var data = message[0];\n"
-      "  var replyTo = message[1];\n"
-      "  if (data) {\n"
-      "    throw new Exception('MakeChildExit');\n"
-      "  } else {\n"
-      "    replyTo.send('hello');\n"
-      "  }\n"
-      "}\n"
-      "\n"
-      "void main(exc_child, exc_parent) {\n"
-      "  var receivePort = new RawReceivePort();\n"
-      "  Isolate.spawn(entry, [exc_child, receivePort.sendPort]);\n"
-      "  receivePort.handler = (message) {\n"
-      "    receivePort.close();\n"
-      "    if (message != 'hello') throw new Exception('ShouldNotHappen');\n"
-      "    if (exc_parent) throw new Exception('MakeParentExit');\n"
+      "void main(shouldThrowException) {\n"
+      "  var rp = new RawReceivePort();\n"
+      "  rp.handler = (msg) {\n"
+      "    rp.close();\n"
+      "    if (shouldThrowException) {\n"
+      "      throw new Exception('ExceptionFromTimer');\n"
+      "    }\n"
       "  };\n"
+      "  rp.sendPort.send(1);\n"
       "}\n";
 
   if (Dart_CurrentIsolate() != NULL) {
@@ -7615,28 +7328,10 @@
 }
 
 
-// The error string from the last unhandled exception. This value is only
-// valid until the next Dart_ExitScope().
-static char* last_exception = NULL;
-
-
-static void RunLoopUnhandledExceptionCallback(Dart_Handle exception) {
-  Dart_Handle error_string = Dart_ToString(exception);
-  EXPECT_VALID(error_string);
-  const char* error_text;
-  Dart_Handle result = Dart_StringToCString(error_string, &error_text);
-  // Duplicate the string since error text is freed when callback is finished.
-  last_exception = strdup(error_text);
-  EXPECT_VALID(result);
-}
-
-
 // Common code for RunLoop_Success/RunLoop_Failure.
-static void RunLoopTest(bool throw_exception_child,
-                        bool throw_exception_parent) {
+static void RunLoopTest(bool throw_exception) {
   Dart_IsolateCreateCallback saved = Isolate::CreateCallback();
   Isolate::SetCreateCallback(RunLoopTestCallback);
-  Isolate::SetUnhandledExceptionCallback(RunLoopUnhandledExceptionCallback);
   Dart_Isolate isolate = RunLoopTestCallback(
       NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 
@@ -7646,29 +7341,15 @@
   EXPECT_VALID(lib);
 
   Dart_Handle result;
-  Dart_Handle args[2];
-  args[0] = (throw_exception_child ? Dart_True() : Dart_False());
-  args[1] = (throw_exception_parent ? Dart_True() : Dart_False());
-  result = Dart_Invoke(lib, NewString("main"), 2, args);
+  Dart_Handle args[1];
+  args[0] = (throw_exception ? Dart_True() : Dart_False());
+  result = Dart_Invoke(lib, NewString("main"), 1, args);
   EXPECT_VALID(result);
-  if (throw_exception_child) {
-    // TODO(tball): fix race-condition
-    // EXPECT_NOTNULL(last_exception);
-    // EXPECT_STREQ("UnhandledException", last_exception);
+  result = Dart_RunLoop();
+  if (throw_exception) {
+    EXPECT_ERROR(result, "Exception: ExceptionFromTimer");
   } else {
-    result = Dart_RunLoop();
-    if (throw_exception_parent) {
-      EXPECT_ERROR(result, "Exception: MakeParentExit");
-      EXPECT_NOTNULL(last_exception);
-      EXPECT_STREQ("UnhandledException", last_exception);
-    } else {
-      EXPECT_VALID(result);
-      EXPECT(last_exception == NULL);
-    }
-  }
-  if (last_exception != NULL) {
-    free(last_exception);
-    last_exception = NULL;
+    EXPECT_VALID(result);
   }
 
   Dart_ExitScope();
@@ -7679,18 +7360,12 @@
 
 
 UNIT_TEST_CASE(RunLoop_Success) {
-  RunLoopTest(false, false);
+  RunLoopTest(false);
 }
 
 
-// This test exits the vm.  Listed as FAIL in vm.status.
-UNIT_TEST_CASE(RunLoop_ExceptionChild) {
-  RunLoopTest(true, false);
-}
-
-
-UNIT_TEST_CASE(RunLoop_ExceptionParent) {
-  RunLoopTest(false, true);
+UNIT_TEST_CASE(RunLoop_Exception) {
+  RunLoopTest(true);
 }
 
 
@@ -7777,81 +7452,6 @@
 }
 
 
-// This callback handles isolate interrupts for the IsolateInterrupt
-// test.  It ignores the first two interrupts and throws an exception
-// on the third interrupt.
-const int kInterruptCount = 10;
-static int interrupt_count = 0;
-static bool IsolateInterruptTestCallback() {
-  OS::Print(" ========== Interrupt callback called #%d\n", interrupt_count + 1);
-  {
-    MonitorLocker ml(sync);
-    interrupt_count++;
-    ml.Notify();
-  }
-  if (interrupt_count == kInterruptCount) {
-    Dart_EnterScope();
-    Dart_Handle lib = Dart_LookupLibrary(NewString(TestCase::url()));
-    EXPECT_VALID(lib);
-    Dart_Handle exc = NewString("foo");
-    EXPECT_VALID(exc);
-    Dart_Handle result = Dart_ThrowException(exc);
-    EXPECT_VALID(result);
-    UNREACHABLE();  // Dart_ThrowException only returns if it gets an error.
-    return false;
-  }
-  ASSERT(interrupt_count < kInterruptCount);
-  return true;
-}
-
-
-TEST_CASE(IsolateInterrupt) {
-  Dart_IsolateInterruptCallback saved = Isolate::InterruptCallback();
-  Isolate::SetInterruptCallback(IsolateInterruptTestCallback);
-
-  sync = new Monitor();
-  int result = OSThread::Start(BusyLoop_start, 0);
-  EXPECT_EQ(0, result);
-
-  {
-    MonitorLocker ml(sync);
-    // Wait for the other isolate to enter main.
-    while (!main_entered) {
-      ml.Wait();
-    }
-  }
-
-  // Send a number of interrupts to the other isolate. All but the
-  // last allow execution to continue. The last causes an exception in
-  // the isolate.
-  for (int i = 0; i < kInterruptCount; i++) {
-    // Space out the interrupts a bit.
-    OS::Sleep(i + 1);
-    Dart_InterruptIsolate(shared_isolate);
-    {
-      MonitorLocker ml(sync);
-      // Wait for interrupt_count to be increased.
-      while (interrupt_count == i) {
-        ml.Wait();
-      }
-      OS::Print(" ========== Interrupt processed #%d\n", interrupt_count);
-    }
-  }
-
-  {
-    MonitorLocker ml(sync);
-    // Wait for our isolate to finish.
-    while (shared_isolate != NULL) {
-      ml.Wait();
-    }
-  }
-
-  // We should have received the expected number of interrupts.
-  EXPECT_EQ(kInterruptCount, interrupt_count);
-
-  Isolate::SetInterruptCallback(saved);
-}
-
 static void* saved_callback_data;
 static void IsolateShutdownTestCallback(void* callback_data) {
   saved_callback_data = callback_data;
@@ -8572,7 +8172,7 @@
 // by one.
 TEST_CASE(OneOldSpacePeer) {
   Isolate* isolate = Isolate::Current();
-  Dart_Handle str = Api::NewHandle(isolate, String::New("str", Heap::kOld));
+  Dart_Handle str = Api::NewHandle(thread, String::New("str", Heap::kOld));
   EXPECT_VALID(str);
   EXPECT(Dart_IsString(str));
   EXPECT_EQ(0, isolate->heap()->PeerCount());
@@ -8605,7 +8205,7 @@
   Dart_EnterScope();
   {
     DARTSCOPE(Thread::Current());
-    Dart_Handle str = Api::NewHandle(isolate, String::New("str", Heap::kOld));
+    Dart_Handle str = Api::NewHandle(T, String::New("str", Heap::kOld));
     EXPECT_VALID(str);
     EXPECT(Dart_IsString(str));
     EXPECT_EQ(0, isolate->heap()->PeerCount());
@@ -8634,7 +8234,7 @@
 // by two.
 TEST_CASE(TwoOldSpacePeers) {
   Isolate* isolate = Isolate::Current();
-  Dart_Handle s1 = Api::NewHandle(isolate, String::New("s1", Heap::kOld));
+  Dart_Handle s1 = Api::NewHandle(thread, String::New("s1", Heap::kOld));
   EXPECT_VALID(s1);
   EXPECT(Dart_IsString(s1));
   EXPECT_EQ(0, isolate->heap()->PeerCount());
@@ -8647,7 +8247,7 @@
   o1 = &o1;
   EXPECT_VALID(Dart_GetPeer(s1, &o1));
   EXPECT(o1 == reinterpret_cast<void*>(&p1));
-  Dart_Handle s2 = Api::NewHandle(isolate, String::New("s2", Heap::kOld));
+  Dart_Handle s2 = Api::NewHandle(thread, String::New("s2", Heap::kOld));
   EXPECT_VALID(s2);
   EXPECT(Dart_IsString(s2));
   EXPECT_EQ(1, isolate->heap()->PeerCount());
@@ -8681,7 +8281,7 @@
   Dart_EnterScope();
   {
     DARTSCOPE(Thread::Current());
-    Dart_Handle s1 = Api::NewHandle(isolate, String::New("s1", Heap::kOld));
+    Dart_Handle s1 = Api::NewHandle(T, String::New("s1", Heap::kOld));
     EXPECT_VALID(s1);
     EXPECT(Dart_IsString(s1));
     EXPECT_EQ(0, isolate->heap()->PeerCount());
@@ -8694,7 +8294,7 @@
     o1 = &o1;
     EXPECT_VALID(Dart_GetPeer(s1, &o1));
     EXPECT(o1 == reinterpret_cast<void*>(&p1));
-    Dart_Handle s2 = Api::NewHandle(isolate, String::New("s2", Heap::kOld));
+    Dart_Handle s2 = Api::NewHandle(T, String::New("s2", Heap::kOld));
     EXPECT_VALID(s2);
     EXPECT(Dart_IsString(s2));
     EXPECT_EQ(1, isolate->heap()->PeerCount());
@@ -8787,8 +8387,7 @@
 
     // Test with single character canonical string, it should not become
     // external string but the peer should be setup for it.
-    Isolate* isolate = Isolate::Current();
-    Dart_Handle canonical_str = Api::NewHandle(isolate, Symbols::New("*"));
+    Dart_Handle canonical_str = Api::NewHandle(thread, Symbols::New("*"));
     EXPECT(Dart_IsString(canonical_str));
     EXPECT(!Dart_IsExternalString(canonical_str));
     uint8_t ext_canonical_str[kLength];
@@ -8879,7 +8478,7 @@
     const char* symbol_ascii = "?unseen";
     expected_length = strlen(symbol_ascii);
     Dart_Handle symbol_str =
-        Api::NewHandle(isolate, Symbols::New(symbol_ascii, expected_length));
+        Api::NewHandle(thread, Symbols::New(symbol_ascii, expected_length));
     EXPECT_VALID(symbol_str);
     EXPECT(Dart_IsString(symbol_str));
     EXPECT(Dart_IsStringLatin1(symbol_str));
@@ -9418,9 +9017,9 @@
   Dart_TimelineDuration("testDurationEvent", 0, 1);
   // Check that it is in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
-  IsolateTimelineEventFilter filter(isolate);
+  IsolateTimelineEventFilter filter(isolate->main_port());
   recorder->PrintJSON(&js, &filter);
   EXPECT_SUBSTRING("testDurationEvent", js.ToCString());
 }
@@ -9435,9 +9034,9 @@
   Dart_TimelineInstant("testInstantEvent");
   // Check that it is in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
-  IsolateTimelineEventFilter filter(isolate);
+  IsolateTimelineEventFilter filter(isolate->main_port());
   recorder->PrintJSON(&js, &filter);
   EXPECT_SUBSTRING("testInstantEvent", js.ToCString());
 }
@@ -9457,7 +9056,7 @@
   Dart_TimelineAsyncEnd("testAsyncEvent", async_id);
   // Check that testAsync is not in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
   TimelineEventFilter filter;
   recorder->PrintJSON(&js, &filter);
@@ -9480,9 +9079,9 @@
 
   // Check that it is in the output.
   TimelineEventRecorder* recorder = Timeline::recorder();
-  Timeline::ReclaimIsolateBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
   JSONStream js;
-  IsolateTimelineEventFilter filter(isolate);
+  IsolateTimelineEventFilter filter(isolate->main_port());
   recorder->PrintJSON(&js, &filter);
   EXPECT_SUBSTRING("testAsyncEvent", js.ToCString());
 }
@@ -9554,6 +9153,12 @@
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
   EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
@@ -9601,6 +9206,12 @@
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"cat\":\"Dart\"", buffer);
   EXPECT_SUBSTRING("\"name\":\"DART_NAME\"", buffer);
@@ -9646,6 +9257,12 @@
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
   EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
@@ -9689,6 +9306,12 @@
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
   EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
@@ -9730,13 +9353,25 @@
 
   // Grab the global trace.
   AppendData data;
-  success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
-  EXPECT(success);
+  {
+    Thread* T = Thread::Current();
+    StackZone zone(T);
+    success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
+    EXPECT(success);
+    // The call should do no zone allocation.
+    EXPECT(zone.SizeInBytes() == 0);
+  }
   buffer = reinterpret_cast<char*>(data.buffer);
   buffer_length = data.buffer_length;
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
 
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
   // Heartbeat test.
   EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
   EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
@@ -9765,12 +9400,22 @@
   }
 
   // Grab the global trace.
-  success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
-  EXPECT(success);
+  {
+    Thread* T = Thread::Current();
+    StackZone zone(T);
+    success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
+    EXPECT(success);
+    EXPECT(zone.SizeInBytes() == 0);
+  }
   buffer = reinterpret_cast<char*>(data.buffer);
   buffer_length = data.buffer_length;
   EXPECT(buffer_length > 0);
   EXPECT(buffer != NULL);
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
 
   // Heartbeat test for old events.
   EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
@@ -9786,4 +9431,165 @@
   free(data.buffer);
 }
 
+
+class GlobalTimelineThreadData {
+ public:
+  GlobalTimelineThreadData()
+      : monitor_(new Monitor()),
+        data_(new AppendData()),
+        running_(true),
+        join_id_(OSThread::kInvalidThreadJoinId) {
+  }
+
+  ~GlobalTimelineThreadData() {
+    delete monitor_;
+    monitor_ = NULL;
+    free(data_->buffer);
+    data_->buffer = NULL;
+    data_->buffer_length = 0;
+    delete data_;
+    data_ = NULL;
+  }
+
+  Monitor* monitor() const { return monitor_; }
+  bool running() const { return running_; }
+  AppendData* data() const { return data_; }
+  uint8_t* buffer() const { return data_->buffer; }
+  intptr_t buffer_length() const { return data_->buffer_length; }
+  ThreadJoinId join_id() const { return join_id_; }
+
+  void set_running(bool running) { running_ = running; }
+  void set_join_id(ThreadJoinId join_id) { join_id_ = join_id; }
+
+ private:
+  Monitor* monitor_;
+  AppendData* data_;
+  bool running_;
+  ThreadJoinId join_id_;
+};
+
+
+static void GlobalTimelineThread(uword parameter) {
+  GlobalTimelineThreadData* data =
+      reinterpret_cast<GlobalTimelineThreadData*>(parameter);
+  Thread* T = Thread::Current();
+  // When there is no current Thread, then Zone allocation will fail.
+  EXPECT(T == NULL);
+  {
+    MonitorLocker ml(data->monitor());
+    bool success =
+        Dart_GlobalTimelineGetTrace(AppendStreamConsumer, data->data());
+    EXPECT(success);
+    data->set_running(false);
+    data->set_join_id(OSThread::Current()->join_id());
+    ml.Notify();
+  }
+}
+
+
+// This test is the same as the one above except that the calls to
+// Dart_GlobalTimelineGetTrace are made from a fresh thread. This ensures that
+// we can call the function from a thread for which we have not set up a
+// Thread object.
+TEST_CASE(Timeline_Dart_GlobalTimelineGetTrace_Threaded) {
+  const char* kScriptChars =
+    "bar() => 'z';\n"
+    "foo() => 'a';\n"
+    "main() => foo();\n";
+
+  // Enable all streams.
+  Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_ALL |
+                                        DART_TIMELINE_STREAM_VM);
+  Dart_Handle lib;
+  {
+    // Add something to the VM stream.
+    TimelineDurationScope tds(Timeline::GetVMStream(),
+                              "TestVMDuration");
+    lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  }
+
+  // Invoke main, which will be compiled resulting in a compiler event in
+  // the timeline.
+  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT_VALID(result);
+
+  const char* buffer = NULL;
+  intptr_t buffer_length = 0;
+
+  // Run Dart_GlobalTimelineGetTrace on a fresh thread.
+  GlobalTimelineThreadData data;
+  int err = OSThread::Start("Timeline test thread",
+      GlobalTimelineThread, reinterpret_cast<uword>(&data));
+  EXPECT(err == 0);
+  {
+    MonitorLocker ml(data.monitor());
+    while (data.running()) {
+      ml.Wait();
+    }
+    buffer = reinterpret_cast<char*>(data.buffer());
+    buffer_length = data.buffer_length();
+    OSThread::Join(data.join_id());
+  }
+  EXPECT(buffer_length > 0);
+  EXPECT(buffer != NULL);
+
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
+  // Heartbeat test.
+  EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
+  EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
+  EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
+  EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
+  EXPECT_NOTSUBSTRING("\"function\":\"::_bar\"", buffer);
+
+  // Retrieving the global trace resulted in all open blocks being reclaimed.
+  // Add some new events and verify that both sets of events are present
+  // in the resulting trace.
+  {
+    // Add something to the VM stream.
+    TimelineDurationScope tds(Timeline::GetVMStream(),
+                              "TestVMDuration2");
+    // Invoke bar, which will be compiled resulting in a compiler event in
+    // the timeline.
+    result = Dart_Invoke(lib, NewString("bar"), 0, NULL);
+  }
+
+  // Grab the global trace.
+  GlobalTimelineThreadData data2;
+  err = OSThread::Start("Timeline test thread",
+      GlobalTimelineThread, reinterpret_cast<uword>(&data2));
+  EXPECT(err == 0);
+  {
+    MonitorLocker ml(data2.monitor());
+    while (data2.running()) {
+      ml.Wait();
+    }
+    buffer = reinterpret_cast<char*>(data2.buffer());
+    buffer_length = data2.buffer_length();
+    OSThread::Join(data2.join_id());
+  }
+
+  EXPECT(buffer_length > 0);
+  EXPECT(buffer != NULL);
+  // Response starts with a '{' character and not a '['.
+  EXPECT(buffer[0] == '{');
+  // Response ends with a '}' character and not a ']'.
+  EXPECT(buffer[buffer_length - 1] == '\0');
+  EXPECT(buffer[buffer_length - 2] == '}');
+
+  // Heartbeat test for old events.
+  EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
+  EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
+  EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
+  EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
+
+  // Heartbeat test for new events.
+  EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer);
+  EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index a4e47bb..182fc7d 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -18,15 +18,26 @@
       backward_references_(kNumInitialReferences),
       vm_isolate_references_(kNumInitialReferences),
       vm_symbol_references_(NULL) {
-  // We need to have an enclosing ApiNativeScope.
-  ASSERT(ApiNativeScope::Current() != NULL);
-  zone_ = ApiNativeScope::Current()->zone();
-  ASSERT(zone_ != NULL);
-  Init();
+}
+
+
+ApiMessageReader::ApiMessageReader(Message* msg)
+    : BaseReader(msg->IsRaw() ? reinterpret_cast<uint8_t*>(msg->raw_obj())
+                              : msg->data(),
+                 msg->len()),
+      zone_(NULL),
+      backward_references_(kNumInitialReferences),
+      vm_isolate_references_(kNumInitialReferences),
+      vm_symbol_references_(NULL) {
 }
 
 
 void ApiMessageReader::Init() {
+  // We need to have an enclosing ApiNativeScope.
+  ASSERT(ApiNativeScope::Current() != NULL);
+  zone_ = ApiNativeScope::Current()->zone();
+  ASSERT(zone_ != NULL);
+
   // Initialize marker objects used to handle Lists.
   // TODO(sjesse): Remove this when message serialization format is
   // updated.
@@ -40,8 +51,19 @@
 
 
 Dart_CObject* ApiMessageReader::ReadMessage() {
-  // Read the object out of the message.
-  return ReadObject();
+  Init();
+  if (PendingBytes() > 0) {
+    // Read the object out of the message.
+    return ReadObject();
+  } else {
+    const RawObject* raw_obj =
+        reinterpret_cast<const RawObject*>(CurrentBufferAddress());
+    ASSERT(ApiObjectConverter::CanConvert(raw_obj));
+    Dart_CObject* cobj =
+      reinterpret_cast<Dart_CObject*>(allocator(sizeof(Dart_CObject)));
+    ApiObjectConverter::Convert(raw_obj, cobj);
+    return cobj;
+  }
 }
 
 
@@ -210,7 +232,7 @@
       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) {
+          if (strcmp(str, object->value.as_string) == 0) {
             return object;
           }
         }
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index 16a138b..f4675c4 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -6,7 +6,11 @@
 #define VM_DART_API_MESSAGE_H_
 
 #include "include/dart_native_api.h"
+#include "platform/utils.h"
+#include "vm/allocation.h"
 #include "vm/dart_api_state.h"
+#include "vm/message.h"
+#include "vm/raw_object.h"
 #include "vm/snapshot.h"
 
 namespace dart {
@@ -45,6 +49,7 @@
   // Allocation of all C Heap objects is done in the zone associated with
   // the enclosing ApiNativeScope.
   ApiMessageReader(const uint8_t* buffer, intptr_t length);
+  explicit ApiMessageReader(Message* message);
   ~ApiMessageReader() { }
 
   Dart_CObject* ReadMessage();
@@ -201,6 +206,48 @@
   DISALLOW_COPY_AND_ASSIGN(ApiMessageWriter);
 };
 
+
+// This class handles translation of certain RawObjects to CObjects for
+// NativeMessageHandlers.
+//
+// TODO(zra): Expand to support not only null, but also other VM heap objects
+// as well.
+class ApiObjectConverter : public AllStatic {
+ public:
+  static bool CanConvert(const RawObject* raw_obj) {
+    return !raw_obj->IsHeapObject() || (raw_obj == Object::null());
+  }
+
+  static bool Convert(const RawObject* raw_obj, Dart_CObject* c_obj) {
+    if (!raw_obj->IsHeapObject()) {
+      ConvertSmi(reinterpret_cast<const RawSmi*>(raw_obj), c_obj);
+    } else if (raw_obj == Object::null()) {
+      ConvertNull(c_obj);
+    } else {
+      return false;
+    }
+    return true;
+  }
+
+ private:
+  static void ConvertSmi(const RawSmi* raw_smi, Dart_CObject* c_obj) {
+    ASSERT(!raw_smi->IsHeapObject());
+    intptr_t value = Smi::Value(raw_smi);
+    if (Utils::IsInt(31, value)) {
+      c_obj->type = Dart_CObject_kInt32;
+      c_obj->value.as_int32 = static_cast<int32_t>(value);
+    } else {
+      c_obj->type = Dart_CObject_kInt64;
+      c_obj->value.as_int64 = static_cast<int64_t>(value);
+    }
+  }
+
+  static void ConvertNull(Dart_CObject* c_obj) {
+    c_obj->type = Dart_CObject_kNull;
+    c_obj->value.as_int64 = 0;
+  }
+};
+
 }  // namespace dart
 
 #endif  // VM_DART_API_MESSAGE_H_
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index 207aab4..e0f6e00 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -203,7 +203,6 @@
  public:
   static FinalizablePersistentHandle* New(
       Isolate* isolate,
-      bool is_prologue,
       const Object& object,
       void* peer,
       Dart_WeakPersistentHandleFinalizer callback,
@@ -251,22 +250,13 @@
     set_external_size(0);
   }
 
-  bool IsPrologueWeakPersistent() {
-    return PrologueWeakBit::decode(external_data_);
-  }
-
-  void SetPrologueWeakPersistent(bool value) {
-    external_data_ = PrologueWeakBit::update(value, external_data_);
-  }
-
   static FinalizablePersistentHandle* Cast(Dart_WeakPersistentHandle handle);
 
  private:
   enum {
     kExternalNewSpaceBit = 0,
-    kPrologueWeakBit = 1,
-    kExternalSizeBits = 2,
-    kExternalSizeBitsSize = (kBitsPerWord - 2),
+    kExternalSizeBits = 1,
+    kExternalSizeBitsSize = (kBitsPerWord - 1),
   };
 
   // This part of external_data_ is the number of externally allocated bytes.
@@ -277,8 +267,6 @@
   // This bit of external_data_ is true if the referent was created in new
   // space and UpdateRelocated has not yet detected any promotion.
   class ExternalNewSpaceBit : public BitField<bool, kExternalNewSpaceBit, 1> {};
-  // This bit is used to indicate that it is a prologue weak persistent handle.
-  class PrologueWeakBit : public BitField<bool, kPrologueWeakBit, 1> {};
 
   friend class FinalizablePersistentHandles;
 
@@ -673,11 +661,6 @@
 };
 
 
-// Forward declarations.
-class WeakReferenceSetBuilder;
-class WeakReferenceSet;
-
-
 // Implementation of the API State used in dart api for maintaining
 // local scopes, persistent handles etc. These are setup on a per isolate
 // basis and destroyed when the isolate is shutdown.
@@ -685,20 +668,11 @@
  public:
   ApiState() : persistent_handles_(),
                weak_persistent_handles_(),
-               prologue_weak_persistent_handles_(),
-               reusable_scope_(NULL),
-               top_scope_(NULL),
-               delayed_weak_reference_sets_(NULL),
                null_(NULL),
                true_(NULL),
                false_(NULL),
                acquired_error_(NULL) {}
   ~ApiState() {
-    while (top_scope_ != NULL) {
-      ApiLocalScope* scope = top_scope_;
-      top_scope_ = top_scope_->previous();
-      delete scope;
-    }
     if (null_ != NULL) {
       persistent_handles().FreeHandle(null_);
       null_ = NULL;
@@ -718,77 +692,18 @@
   }
 
   // Accessors.
-  ApiLocalScope* reusable_scope() const { return reusable_scope_; }
-  void set_reusable_scope(ApiLocalScope* value) {
-    ASSERT(value == NULL || reusable_scope_ == NULL);
-    reusable_scope_ = value;
-  }
-  ApiLocalScope* top_scope() const { return top_scope_; }
-  void set_top_scope(ApiLocalScope* value) { top_scope_ = value; }
-
   PersistentHandles& persistent_handles() { return persistent_handles_; }
 
   FinalizablePersistentHandles& weak_persistent_handles() {
     return weak_persistent_handles_;
   }
 
-  FinalizablePersistentHandles& prologue_weak_persistent_handles() {
-    return prologue_weak_persistent_handles_;
-  }
-
-  WeakReferenceSet* delayed_weak_reference_sets() {
-    return delayed_weak_reference_sets_;
-  }
-  void set_delayed_weak_reference_sets(WeakReferenceSet* reference_set) {
-    delayed_weak_reference_sets_ = reference_set;
-  }
-
-  void UnwindScopes(uword stack_marker) {
-    // Unwind all scopes using the same stack_marker, i.e. all scopes allocated
-    // under the same top_exit_frame_info.
-    while (top_scope_ != NULL &&
-           top_scope_->stack_marker() != 0 &&
-           top_scope_->stack_marker() == stack_marker) {
-      ApiLocalScope* scope = top_scope_;
-      top_scope_ = top_scope_->previous();
-      delete scope;
-    }
-  }
-
-  void VisitObjectPointers(ObjectPointerVisitor* visitor,
-                           bool visit_prologue_weak_handles) {
-    ApiLocalScope* scope = top_scope_;
-    while (scope != NULL) {
-      scope->local_handles()->VisitObjectPointers(visitor);
-      scope = scope->previous();
-    }
+  void VisitObjectPointers(ObjectPointerVisitor* visitor) {
     persistent_handles().VisitObjectPointers(visitor);
-    if (visit_prologue_weak_handles) {
-      prologue_weak_persistent_handles().VisitObjectPointers(visitor);
-    }
   }
 
-  void VisitWeakHandles(HandleVisitor* visitor,
-                        bool visit_prologue_weak_handles) {
+  void VisitWeakHandles(HandleVisitor* visitor) {
     weak_persistent_handles().VisitHandles(visitor);
-    if (visit_prologue_weak_handles) {
-      prologue_weak_persistent_handles().VisitHandles(visitor);
-    }
-  }
-
-  void VisitPrologueWeakHandles(HandleVisitor* visitor) {
-    prologue_weak_persistent_handles().VisitHandles(visitor);
-  }
-
-  bool IsValidLocalHandle(Dart_Handle object) const {
-    ApiLocalScope* scope = top_scope_;
-    while (scope != NULL) {
-      if (scope->local_handles()->IsValidHandle(object)) {
-        return true;
-      }
-      scope = scope->previous();
-    }
-    return false;
   }
 
   bool IsValidPersistentHandle(Dart_PersistentHandle object) const {
@@ -799,37 +714,14 @@
     return weak_persistent_handles_.IsValidHandle(object);
   }
 
-  bool IsValidPrologueWeakPersistentHandle(
-      Dart_WeakPersistentHandle object) const {
-    return prologue_weak_persistent_handles_.IsValidHandle(object);
-  }
-
   bool IsProtectedHandle(PersistentHandle* object) const {
     if (object == NULL) return false;
     return object == null_ || object == true_ || object == false_;
   }
 
-  int CountLocalHandles() const {
-    int total = 0;
-    ApiLocalScope* scope = top_scope_;
-    while (scope != NULL) {
-      total += scope->local_handles()->CountHandles();
-      scope = scope->previous();
-    }
-    return total;
-  }
   int CountPersistentHandles() const {
     return persistent_handles_.CountHandles();
   }
-  int ZoneSizeInBytes() const {
-    int total = 0;
-    ApiLocalScope* scope = top_scope_;
-    while (scope != NULL) {
-      total += scope->zone()->SizeInBytes();
-      scope = scope->previous();
-    }
-    return total;
-  }
 
   void SetupAcquiredError() {
     ASSERT(acquired_error_ == NULL);
@@ -845,19 +737,11 @@
     return acquired_error_;
   }
 
-  WeakReferenceSetBuilder* NewWeakReferenceSetBuilder();
-
-  void DelayWeakReferenceSet(WeakReferenceSet* reference_set);
-
   WeakTable* acquired_table() { return &acquired_table_; }
 
  private:
   PersistentHandles persistent_handles_;
   FinalizablePersistentHandles weak_persistent_handles_;
-  FinalizablePersistentHandles prologue_weak_persistent_handles_;
-  ApiLocalScope* reusable_scope_;
-  ApiLocalScope* top_scope_;
-  WeakReferenceSet* delayed_weak_reference_sets_;
   WeakTable acquired_table_;
 
   // Persistent handles to important objects.
@@ -870,123 +754,16 @@
 };
 
 
-class WeakReferenceSet {
- public:
-  explicit WeakReferenceSet(Zone* zone)
-      : next_(NULL),
-        keys_(1, zone),
-        values_(1, zone) {
-  }
-  ~WeakReferenceSet() {}
-
-  WeakReferenceSet* next() const { return next_; }
-
-  intptr_t num_keys() const { return keys_.length(); }
-  RawObject** get_key(intptr_t i) {
-    ASSERT(i >= 0);
-    ASSERT(i < num_keys());
-    FinalizablePersistentHandle* ref =
-        FinalizablePersistentHandle::Cast(keys_[i]);
-    return ref->raw_addr();
-  }
-
-  intptr_t num_values() const { return values_.length(); }
-  RawObject** get_value(intptr_t i) {
-    ASSERT(i >= 0);
-    ASSERT(i < num_values());
-    FinalizablePersistentHandle* ref =
-        FinalizablePersistentHandle::Cast(values_[i]);
-    return ref->raw_addr();
-  }
-
-  bool SingletonKeyEqualsValue() const {
-    ASSERT((num_keys() == 1) && (num_values() == 1));
-    return (keys_[0] == values_[0]);
-  }
-
-  void Append(Dart_WeakPersistentHandle key, Dart_WeakPersistentHandle value) {
-    keys_.Add(key);
-    values_.Add(value);
-  }
-
-  void AppendKey(Dart_WeakPersistentHandle key) {
-    keys_.Add(key);
-  }
-
-  void AppendValue(Dart_WeakPersistentHandle value) {
-    values_.Add(value);
-  }
-
-  static WeakReferenceSet* Pop(WeakReferenceSet** queue) {
-    ASSERT(queue != NULL);
-    WeakReferenceSet* head = *queue;
-    if (head != NULL) {
-      *queue = head->next();
-      head->next_ = NULL;
-    }
-    return head;
-  }
-
-  static void Push(WeakReferenceSet* reference_set, WeakReferenceSet** queue) {
-    ASSERT(reference_set != NULL);
-    ASSERT(queue != NULL);
-    reference_set->next_ = *queue;
-    *queue = reference_set;
-  }
-
-  void* operator new(uword size, Zone* zone) {
-    return reinterpret_cast<void*>(zone->AllocUnsafe(size));
-  }
-
-  // Disallow explicit deallocation of WeakReferenceSet.
-  void operator delete(void* pointer) { UNREACHABLE(); }
-
- private:
-  WeakReferenceSet* next_;
-  ApiGrowableArray<Dart_WeakPersistentHandle> keys_;
-  ApiGrowableArray<Dart_WeakPersistentHandle> values_;
-
-  DISALLOW_COPY_AND_ASSIGN(WeakReferenceSet);
-};
-
-
-class WeakReferenceSetBuilder {
- public:
-  ApiState* api_state() const {
-    return api_state_;
-  }
-
-  WeakReferenceSet* NewWeakReferenceSet() {
-    return new (zone_) WeakReferenceSet(zone_);
-  }
-
- private:
-  explicit WeakReferenceSetBuilder(ApiState* api_state)
-      : api_state_(api_state),
-        zone_(api_state->top_scope()->zone()) {
-  }
-
-  ApiState* api_state_;
-  Zone* zone_;
-
-  friend class ApiState;
-  DISALLOW_IMPLICIT_CONSTRUCTORS(WeakReferenceSetBuilder);
-};
-
-
 inline FinalizablePersistentHandle* FinalizablePersistentHandle::New(
     Isolate* isolate,
-    bool is_prologue,
     const Object& object,
     void* peer,
     Dart_WeakPersistentHandleFinalizer callback,
     intptr_t external_size) {
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
-  FinalizablePersistentHandle* ref = is_prologue ?
-      state->prologue_weak_persistent_handles().AllocateHandle() :
+  FinalizablePersistentHandle* ref =
       state->weak_persistent_handles().AllocateHandle();
-  ref->SetPrologueWeakPersistent(is_prologue);
   ref->set_raw(object);
   ref->set_peer(peer);
   ref->set_callback(callback);
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 2f5a79e..abb3e5d 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -24,6 +24,7 @@
 
 RawObject* DartEntry::InvokeFunction(const Function& function,
                                      const Array& arguments) {
+  ASSERT(Thread::Current()->IsMutatorThread());
   const Array& arguments_descriptor =
       Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
   return InvokeFunction(function, arguments, arguments_descriptor);
@@ -32,26 +33,39 @@
 
 class ScopedIsolateStackLimits : public ValueObject {
  public:
-  explicit ScopedIsolateStackLimits(Isolate* isolate)
-      : isolate_(isolate), stack_base_(Isolate::GetCurrentStackPointer()) {
-    ASSERT(isolate_ != NULL);
-    ASSERT(isolate_ == Isolate::Current());
-    if (stack_base_ >= isolate_->stack_base()) {
-      isolate_->SetStackLimitFromStackBase(stack_base_);
+  explicit ScopedIsolateStackLimits(Thread* thread)
+      : thread_(thread), saved_stack_limit_(0) {
+    ASSERT(thread != NULL);
+    // Set the thread's stack_base based on the current
+    // stack pointer, we keep refining this value as we
+    // see higher stack pointers (Note: we assume the stack
+    // grows from high to low addresses).
+    OSThread* os_thread = thread->os_thread();
+    ASSERT(os_thread != NULL);
+    uword current_sp = Isolate::GetCurrentStackPointer();
+    if (current_sp > os_thread->stack_base()) {
+      os_thread->set_stack_base(current_sp);
     }
+    // Save the Isolate's current stack limit and adjust the stack
+    // limit based on the thread's stack_base.
+    Isolate* isolate = thread->isolate();
+    ASSERT(isolate == Isolate::Current());
+    saved_stack_limit_ = isolate->saved_stack_limit();
+    isolate->SetStackLimitFromStackBase(os_thread->stack_base());
   }
 
   ~ScopedIsolateStackLimits() {
-    ASSERT(isolate_ == Isolate::Current());
-    if (isolate_->stack_base() == stack_base_) {
-      // Bottomed out.
-      isolate_->ClearStackLimit();
-    }
+    Isolate* isolate = thread_->isolate();
+    ASSERT(isolate == Isolate::Current());
+    // Since we started with a stack limit of 0 we should be getting back
+    // to a stack limit of 0 when all nested invocations are done and
+    // we have bottomed out.
+    isolate->SetStackLimit(saved_stack_limit_);
   }
 
  private:
-  Isolate* isolate_;
-  uword stack_base_;
+  Thread* thread_;
+  uword saved_stack_limit_;
 };
 
 
@@ -83,8 +97,7 @@
   // compiled.
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
-  ASSERT(isolate->MutatorThreadIsCurrentThread());
+  ASSERT(thread->IsMutatorThread());
   if (!function.HasCode()) {
     const Error& error = Error::Handle(
         zone, Compiler::CompileFunction(thread, function));
@@ -98,7 +111,7 @@
   const Code& code = Code::Handle(zone, function.CurrentCode());
   ASSERT(!code.IsNull());
   ASSERT(thread->no_callback_scope_depth() == 0);
-  ScopedIsolateStackLimits stack_limit(isolate);
+  ScopedIsolateStackLimits stack_limit(thread);
   SuspendLongJumpScope suspend_long_jump_scope(thread);
 #if defined(USING_SIMULATOR)
   return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call(
@@ -154,15 +167,15 @@
     while (!cls.IsNull()) {
       function ^= cls.LookupDynamicFunction(getter_name);
       if (!function.IsNull()) {
-        // Getters don't have a stack overflow check, so do one in C++.
-
         Isolate* isolate = Isolate::Current();
-#if defined(USING_SIMULATOR)
-        uword stack_pos = Simulator::Current()->get_register(SPREG);
-#else
-        uword stack_pos = Isolate::GetCurrentStackPointer();
+        volatile uword c_stack_pos = Isolate::GetCurrentStackPointer();
+        volatile uword c_stack_limit = OSThread::Current()->stack_base() -
+                                       OSThread::GetSpecifiedStackSize();
+#if !defined(USING_SIMULATOR)
+        ASSERT(c_stack_limit == isolate->saved_stack_limit());
 #endif
-        if (stack_pos < isolate->saved_stack_limit()) {
+
+        if (c_stack_pos < c_stack_limit) {
           const Instance& exception =
             Instance::Handle(isolate->object_store()->stack_overflow());
           return UnhandledException::New(exception, Stacktrace::Handle());
@@ -251,12 +264,12 @@
 
 
 intptr_t ArgumentsDescriptor::Count() const {
-  return Smi::CheckedHandle(array_.At(kCountIndex)).Value();
+  return Smi::Cast(Object::Handle(array_.At(kCountIndex))).Value();
 }
 
 
 intptr_t ArgumentsDescriptor::PositionalCount() const {
-  return Smi::CheckedHandle(array_.At(kPositionalCountIndex)).Value();
+  return Smi::Cast(Object::Handle(array_.At(kPositionalCountIndex))).Value();
 }
 
 
@@ -398,13 +411,11 @@
   const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name));
   ASSERT(!cls.IsNull());
   // For now, we only support a non-parameterized or raw type.
-  const int kNumExtraArgs = 2;  // implicit rcvr and construction phase args.
+  const int kNumExtraArgs = 1;  // implicit rcvr arg.
   const Instance& exception_object = Instance::Handle(Instance::New(cls));
   const Array& constructor_arguments =
     Array::Handle(Array::New(arguments.Length() + kNumExtraArgs));
   constructor_arguments.SetAt(0, exception_object);
-  constructor_arguments.SetAt(
-      1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
   Object& obj = Object::Handle();
   for (intptr_t i = 0; i < arguments.Length(); i++) {
     obj = arguments.At(i);
diff --git a/runtime/vm/dart_entry_test.cc b/runtime/vm/dart_entry_test.cc
index 5f939ed..a661d5b 100644
--- a/runtime/vm/dart_entry_test.cc
+++ b/runtime/vm/dart_entry_test.cc
@@ -89,10 +89,8 @@
 
   // Invoke the constructor.
   const Instance& instance = Instance::Handle(Instance::New(cls));
-  const Array& constructor_arguments = Array::Handle(Array::New(2));
+  const Array& constructor_arguments = Array::Handle(Array::New(1));
   constructor_arguments.SetAt(0, instance);
-  constructor_arguments.SetAt(
-      1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
   String& constructor_name = String::Handle(Symbols::New("A."));
   Function& constructor =
     Function::Handle(cls.LookupConstructor(constructor_name));
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 3434e01..c533e3b 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -93,8 +93,8 @@
                                        intptr_t requested_column_number)
     : script_(Script::null()),
       url_(url.raw()),
-      token_pos_(-1),
-      end_token_pos_(-1),
+      token_pos_(Scanner::kNoSourcePos),
+      end_token_pos_(Scanner::kNoSourcePos),
       is_resolved_(false),
       next_(NULL),
       conditions_(NULL),
@@ -239,7 +239,7 @@
       code_(Code::ZoneHandle(code.raw())),
       function_(Function::ZoneHandle(code.function())),
       token_pos_initialized_(false),
-      token_pos_(-1),
+      token_pos_(Scanner::kNoSourcePos),
       try_index_(-1),
       line_number_(-1),
       column_number_(-1),
@@ -258,13 +258,19 @@
 }
 
 
-bool Debugger::HasEventHandler() {
+bool Debugger::HasAnyEventHandler() {
   return ((event_handler_ != NULL) ||
           Service::isolate_stream.enabled() ||
           Service::debug_stream.enabled());
 }
 
 
+bool Debugger::HasDebugEventHandler() {
+  return ((event_handler_ != NULL) ||
+          Service::debug_stream.enabled());
+}
+
+
 static bool ServiceNeedsDebuggerEvent(DebuggerEvent::EventType type) {
   switch (type) {
     case DebuggerEvent::kBreakpointResolved:
@@ -289,8 +295,6 @@
 
 
 void Debugger::InvokeEventHandler(DebuggerEvent* event) {
-  ASSERT(HasEventHandler());
-
   // Give the event to the Service first, as the debugger event handler
   // may go into a message loop and the Service will not.
   //
@@ -301,7 +305,8 @@
     Service::HandleEvent(&service_event);
   }
 
-  if (FLAG_steal_breakpoints && event->IsPauseEvent()) {
+  if ((FLAG_steal_breakpoints || (event_handler_ == NULL)) &&
+      event->IsPauseEvent()) {
     // We allow the embedder's default breakpoint handler to be overridden.
     isolate_->PauseEventHandler();
   } else if (event_handler_ != NULL) {
@@ -310,8 +315,8 @@
 
   if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) {
     // If we were paused, notify the service that we have resumed.
-    const Error& error = Error::Handle(zone(),
-        isolate_->object_store()->sticky_error());
+    const Error& error =
+        Error::Handle(isolate_->object_store()->sticky_error());
     ASSERT(error.IsNull() || error.IsUnwindError());
 
     // Only send a resume event when the isolate is not unwinding.
@@ -325,7 +330,7 @@
 
 
 void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) {
-  if (HasEventHandler()) {
+  if (HasAnyEventHandler()) {
     DebuggerEvent event(isolate_, type);
     ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID);
     if (type == DebuggerEvent::kIsolateInterrupted) {
@@ -347,25 +352,13 @@
 
 
 RawError* Debugger::SignalIsolateInterrupted() {
-  if (HasEventHandler()) {
+  if (HasDebugEventHandler()) {
     SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted);
   }
-  Dart_IsolateInterruptCallback callback = isolate_->InterruptCallback();
-  if (callback != NULL) {
-    if (!(*callback)()) {
-      if (FLAG_trace_isolates) {
-        OS::Print("[!] Embedder api: terminating isolate:\n"
-                  "\tisolate:    %s\n", isolate_->name());
-      }
-      const String& msg =
-          String::Handle(String::New("isolate terminated by embedder"));
-      return UnwindError::New(msg);
-    }
-  }
 
   // If any error occurred while in the debug message loop, return it here.
   const Error& error =
-      Error::Handle(zone(), isolate_->object_store()->sticky_error());
+      Error::Handle(isolate_->object_store()->sticky_error());
   ASSERT(error.IsNull() || error.IsUnwindError());
   isolate_->object_store()->clear_sticky_error();
   return error.raw();
@@ -468,13 +461,13 @@
 }
 
 
-bool Debugger::HasBreakpoint(const Function& func) {
+bool Debugger::HasBreakpoint(const Function& func, Zone* zone) {
   if (!func.HasCode()) {
     // If the function is not compiled yet, just check whether there
     // is a user-defined breakpoint that falls into the token
     // range of the function. This may be a false positive: the breakpoint
     // might be inside a local closure.
-    Script& script = Script::Handle(zone());
+    Script& script = Script::Handle(zone);
     BreakpointLocation* sbpt = breakpoint_locations_;
     while (sbpt != NULL) {
       script = sbpt->script();
@@ -1024,7 +1017,7 @@
       return value.raw();
     }
   }
-  return Object::null();
+  return Symbols::OptimizedOut().raw();
 }
 
 
@@ -1061,8 +1054,8 @@
                         Array::Handle(Array::MakeArray(param_values)));
   } else {
     const Object& receiver = Object::Handle(GetReceiver());
-    ASSERT(receiver.IsInstance());
-    if (!receiver.IsInstance()) {
+    ASSERT(receiver.IsInstance() || receiver.IsNull());
+    if (!(receiver.IsInstance() || receiver.IsNull())) {
       return Object::null();
     }
     const Instance& inst = Instance::Cast(receiver);
@@ -1120,6 +1113,7 @@
       if (var_name.raw() != Symbols::AsyncOperation().raw()) {
         JSONObject jsvar(&jsvars);
         jsvar.AddProperty("type", "BoundVariable");
+        var_name = String::IdentifierPrettyName(var_name);
         jsvar.AddProperty("name", var_name.ToCString());
         jsvar.AddProperty("value", var_value, !full);
         // TODO(turnidge): Do we really want to provide this on every
@@ -1251,6 +1245,7 @@
     : isolate_(NULL),
       isolate_id_(ILLEGAL_ISOLATE_ID),
       initialized_(false),
+      creation_message_sent_(false),
       next_id_(1),
       latent_locations_(NULL),
       breakpoint_locations_(NULL),
@@ -1277,6 +1272,12 @@
 
 
 void Debugger::Shutdown() {
+  // TODO(johnmccutchan): Do not create a debugger for isolates that don't need
+  // them. Then, assert here that isolate_ is not one of those isolates.
+  if ((isolate_ == Dart::vm_isolate()) ||
+      ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
+    return;
+  }
   while (breakpoint_locations_ != NULL) {
     BreakpointLocation* bpt = breakpoint_locations_;
     breakpoint_locations_ = breakpoint_locations_->next();
@@ -1293,8 +1294,9 @@
     bpt->Disable();
     delete bpt;
   }
-  // Signal isolate shutdown event.
-  if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
+  // Signal isolate shutdown event, but only if we previously sent the creation
+  // event.
+  if (creation_message_sent_) {
     SignalIsolateEvent(DebuggerEvent::kIsolateShutdown);
   }
 }
@@ -1385,26 +1387,24 @@
           }
         }
       }
+    }
+  }
 
-      // Disable other optimized closure functions.
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        intptr_t num_closures = closures.Length();
-        for (intptr_t pos = 0; pos < num_closures; pos++) {
-          function ^= closures.At(pos);
-          ASSERT(!function.IsNull());
-          if (function.HasOptimizedCode()) {
-            function.SwitchToUnoptimizedCode();
-          }
-        }
-      }
+  // Disable optimized closure functions.
+  closures = isolate_->object_store()->closure_functions();
+  const intptr_t num_closures = closures.Length();
+  for (intptr_t pos = 0; pos < num_closures; pos++) {
+    function ^= closures.At(pos);
+    ASSERT(!function.IsNull());
+    if (function.HasOptimizedCode()) {
+      function.SwitchToUnoptimizedCode();
     }
   }
 }
 
 
 void Debugger::SignalBpResolved(Breakpoint* bpt) {
-  if (HasEventHandler() && !bpt->IsSingleShot()) {
+  if (HasDebugEventHandler() && !bpt->IsSingleShot()) {
     DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved);
     event.set_breakpoint(bpt);
     InvokeEventHandler(&event);
@@ -1444,7 +1444,8 @@
                        DeoptContext::kDestIsAllocated,
                        NULL,
                        NULL,
-                       true);
+                       true,
+                       false /* deoptimizing_code */);
   isolate->set_deopt_context(deopt_context);
 
   deopt_context->FillDestFrame();
@@ -1520,7 +1521,7 @@
   while ((frame != NULL) && !frame->IsDartFrame()) {
     frame = iterator.NextFrame();
   }
-  Code& code = Code::Handle(zone(), frame->LookupDartCode());
+  Code& code = Code::Handle(frame->LookupDartCode());
   ActivationFrame* activation =
       new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code,
                           Object::null_array(), 0);
@@ -1625,7 +1626,7 @@
   // interested in exception events.
   if (ignore_breakpoints_ ||
       IsPaused() ||
-      (!HasEventHandler()) ||
+      (!HasDebugEventHandler()) ||
       (exc_pause_info_ == kNoPauseOnExceptions)) {
     return;
   }
@@ -1739,7 +1740,7 @@
   PcDescriptors::Iterator iter(desc, kSafepointKind);
   while (iter.MoveNext()) {
     const intptr_t pos = iter.TokenPos();
-    if ((pos == Scanner::kNoSourcePos) ||
+    if ((pos < 0) ||
         (pos < requested_token_pos) ||
         (pos > last_token_pos)) {
       // Token is not in the target range.
@@ -1785,7 +1786,7 @@
     PcDescriptors::Iterator iter(desc, kSafepointKind);
     while (iter.MoveNext()) {
       const intptr_t pos = iter.TokenPos();
-      if ((pos == Scanner::kNoSourcePos) ||
+      if ((pos < 0) ||
           (pos < begin_pos) ||
           (pos > end_of_line_pos)) {
         // Token is not on same line as best fit.
@@ -1826,7 +1827,7 @@
 
 void Debugger::MakeCodeBreakpointAt(const Function& func,
                                     BreakpointLocation* loc) {
-  ASSERT(loc->token_pos_ != Scanner::kNoSourcePos);
+  ASSERT(loc->token_pos_ >= 0);
   ASSERT((loc != NULL) && loc->IsResolved());
   ASSERT(!func.HasOptimizedCode());
   Code& code = Code::Handle(func.unoptimized_code());
@@ -1867,11 +1868,31 @@
                                      intptr_t start_pos,
                                      intptr_t end_pos,
                                      GrowableObjectArray* function_list) {
-  Zone* zn = zone();
-  Class& cls = Class::Handle(zn);
-  Array& functions = Array::Handle(zn);
-  GrowableObjectArray& closures = GrowableObjectArray::Handle(zn);
-  Function& function = Function::Handle(zn);
+  Zone* zone = Thread::Current()->zone();
+  Class& cls = Class::Handle(zone);
+  Array& functions = Array::Handle(zone);
+  GrowableObjectArray& closures = GrowableObjectArray::Handle(zone);
+  Function& function = Function::Handle(zone);
+
+  closures = isolate_->object_store()->closure_functions();
+  const intptr_t num_closures = closures.Length();
+  for (intptr_t pos = 0; pos < num_closures; pos++) {
+    function ^= closures.At(pos);
+    ASSERT(!function.IsNull());
+    if ((function.token_pos() == start_pos)
+        && (function.end_token_pos() == end_pos)
+        && (function.script() == script.raw())) {
+      if (function.HasCode() && function.is_debuggable()) {
+        function_list->Add(function);
+      }
+      if (function.HasImplicitClosureFunction()) {
+        function = function.ImplicitClosureFunction();
+        if (function.HasCode() && function.is_debuggable()) {
+          function_list->Add(function);
+        }
+      }
+    }
+  }
 
   const ClassTable& class_table = *isolate_->class_table();
   const intptr_t num_classes = class_table.NumCids();
@@ -1911,27 +1932,6 @@
           }
         }
       }
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        const intptr_t num_closures = closures.Length();
-        for (intptr_t pos = 0; pos < num_closures; pos++) {
-          function ^= closures.At(pos);
-          ASSERT(!function.IsNull());
-          if ((function.token_pos() == start_pos)
-              && (function.end_token_pos() == end_pos)
-              && (function.script() == script.raw())) {
-            if (function.HasCode() && function.is_debuggable()) {
-              function_list->Add(function);
-            }
-            if (function.HasImplicitClosureFunction()) {
-              function = function.ImplicitClosureFunction();
-              if (function.HasCode() && function.is_debuggable()) {
-                function_list->Add(function);
-              }
-            }
-          }
-        }
-      }
     }
   }
 }
@@ -1951,13 +1951,22 @@
 
 RawFunction* Debugger::FindBestFit(const Script& script,
                                    intptr_t token_pos) {
-  Zone* zn = zone();
-  Class& cls = Class::Handle(zn);
-  Array& functions = Array::Handle(zn);
-  GrowableObjectArray& closures = GrowableObjectArray::Handle(zn);
-  Function& function = Function::Handle(zn);
-  Function& best_fit = Function::Handle(zn);
-  Error& error = Error::Handle(zn);
+  Zone* zone = Thread::Current()->zone();
+  Class& cls = Class::Handle(zone);
+  Array& functions = Array::Handle(zone);
+  GrowableObjectArray& closures = GrowableObjectArray::Handle(zone);
+  Function& function = Function::Handle(zone);
+  Function& best_fit = Function::Handle(zone);
+  Error& error = Error::Handle(zone);
+
+  closures = isolate_->object_store()->closure_functions();
+  const intptr_t num_closures = closures.Length();
+  for (intptr_t i = 0; i < num_closures; i++) {
+    function ^= closures.At(i);
+    if (FunctionContains(function, script, token_pos)) {
+      SelectBestFit(&best_fit, &function);
+    }
+  }
 
   const ClassTable& class_table = *isolate_->class_table();
   const intptr_t num_classes = class_table.NumCids();
@@ -1993,18 +2002,6 @@
           }
         }
       }
-
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        const intptr_t num_closures = closures.Length();
-        for (intptr_t pos = 0; pos < num_closures; pos++) {
-          function ^= closures.At(pos);
-          ASSERT(!function.IsNull());
-          if (FunctionContains(function, script, token_pos)) {
-            SelectBestFit(&best_fit, &function);
-          }
-        }
-      }
     }
   }
   return best_fit.raw();
@@ -2016,7 +2013,7 @@
                                             intptr_t last_token_pos,
                                             intptr_t requested_line,
                                             intptr_t requested_column) {
-  Function& func = Function::Handle(zone());
+  Function& func = Function::Handle();
   func = FindBestFit(script, token_pos);
   if (func.IsNull()) {
     return NULL;
@@ -2208,12 +2205,13 @@
     const String& script_url,
     intptr_t line_number,
     intptr_t column_number) {
-  Library& lib = Library::Handle(zone());
-  Script& script = Script::Handle(zone());
+  Zone* zone = Thread::Current()->zone();
+  Library& lib = Library::Handle(zone);
+  Script& script = Script::Handle(zone);
   const GrowableObjectArray& libs =
       GrowableObjectArray::Handle(isolate_->object_store()->libraries());
   const GrowableObjectArray& scripts =
-    GrowableObjectArray::Handle(zone(), GrowableObjectArray::New());
+    GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
   for (intptr_t i = 0; i < libs.Length(); i++) {
     lib ^= libs.At(i);
     script = lib.LookupScript(script_url);
@@ -2403,10 +2401,11 @@
                                     const String& prefix,
                                     bool include_private_fields) {
   DictionaryIterator it(lib);
-  Object& entry = Object::Handle(isolate_->current_zone());
-  Field& field = Field::Handle(zone());
-  String& field_name = String::Handle(zone());
-  PassiveObject& field_value = PassiveObject::Handle(isolate_->current_zone());
+  Zone* zone = Thread::Current()->zone();
+  Object& entry = Object::Handle(zone);
+  Field& field = Field::Handle(zone);
+  String& field_name = String::Handle(zone);
+  PassiveObject& field_value = PassiveObject::Handle(zone);
   while (it.HasNext()) {
     entry = it.GetNext();
     if (entry.IsField()) {
@@ -2437,26 +2436,28 @@
 
 
 RawArray* Debugger::GetLibraryFields(const Library& lib) {
+  Zone* zone = Thread::Current()->zone();
   const GrowableObjectArray& field_list =
       GrowableObjectArray::Handle(GrowableObjectArray::New(8));
-  CollectLibraryFields(field_list, lib, String::Handle(zone()), true);
+  CollectLibraryFields(field_list, lib, String::Handle(zone), true);
   return Array::MakeArray(field_list);
 }
 
 
 RawArray* Debugger::GetGlobalFields(const Library& lib) {
+  Zone* zone = Thread::Current()->zone();
   const GrowableObjectArray& field_list =
-      GrowableObjectArray::Handle(GrowableObjectArray::New(8));
-  String& prefix_name = String::Handle(zone());
+      GrowableObjectArray::Handle(zone, GrowableObjectArray::New(8));
+  String& prefix_name = String::Handle(zone);
   CollectLibraryFields(field_list, lib, prefix_name, true);
-  Library& imported = Library::Handle(zone());
+  Library& imported = Library::Handle(zone);
   intptr_t num_imports = lib.num_imports();
   for (intptr_t i = 0; i < num_imports; i++) {
     imported = lib.ImportLibraryAt(i);
     ASSERT(!imported.IsNull());
     CollectLibraryFields(field_list, imported, prefix_name, false);
   }
-  LibraryPrefix& prefix = LibraryPrefix::Handle(zone());
+  LibraryPrefix& prefix = LibraryPrefix::Handle(zone);
   LibraryPrefixIterator it(lib);
   while (it.HasNext()) {
     prefix = it.GetNext();
@@ -2507,7 +2508,16 @@
   pause_event_->UpdateTimestamp();
   obj_cache_ = new RemoteObjectCache(64);
 
-  InvokeEventHandler(event);
+  // We are about to invoke the debuggers event handler. Disable interrupts
+  // for this thread while waiting for debug commands over the service protocol.
+  {
+    Thread* thread = Thread::Current();
+    DisableThreadInterruptsScope dtis(thread);
+    TimelineDurationScope tds(thread,
+                              isolate_->GetDebuggerStream(),
+                              "Debugger Pause");
+    InvokeEventHandler(event);
+  }
 
   pause_event_ = NULL;
   obj_cache_ = NULL;    // Zone allocated
@@ -2548,11 +2558,6 @@
       }
     }
   }
-  if (!isolate_->single_step()) {
-    // We are no longer single stepping, make sure that the ThreadInterrupter
-    // is awake.
-    ThreadInterrupter::WakeUp();
-  }
 }
 
 
@@ -2605,9 +2610,6 @@
 
 RawError* Debugger::DebuggerStepCallback() {
   ASSERT(isolate_->single_step());
-  // We can't get here unless the debugger event handler enabled
-  // single stepping.
-  ASSERT(HasEventHandler());
   // Don't pause recursively.
   if (IsPaused()) {
     return Error::null();
@@ -2639,7 +2641,7 @@
   if (!frame->IsDebuggable()) {
     return Error::null();
   }
-  if (frame->TokenPos() == Scanner::kNoSourcePos) {
+  if (frame->TokenPos() < 0) {
     return Error::null();
   }
 
@@ -2665,7 +2667,7 @@
 
   // If any error occurred while in the debug message loop, return it here.
   const Error& error =
-      Error::Handle(zone(), isolate_->object_store()->sticky_error());
+      Error::Handle(isolate_->object_store()->sticky_error());
   isolate_->object_store()->clear_sticky_error();
   return error.raw();
 }
@@ -2675,7 +2677,7 @@
   // We ignore this breakpoint when the VM is executing code invoked
   // by the debugger to evaluate variables values, or when we see a nested
   // breakpoint or exception event.
-  if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) {
+  if (ignore_breakpoints_ || IsPaused()) {
     return Error::null();
   }
   DebuggerStackTrace* stack_trace = CollectStackTrace();
@@ -2754,7 +2756,7 @@
 
   // If any error occurred while in the debug message loop, return it here.
   const Error& error =
-      Error::Handle(zone(), isolate_->object_store()->sticky_error());
+      Error::Handle(isolate_->object_store()->sticky_error());
   isolate_->object_store()->clear_sticky_error();
   return error.raw();
 }
@@ -2764,10 +2766,14 @@
   // We ignore this breakpoint when the VM is executing code invoked
   // by the debugger to evaluate variables values, or when we see a nested
   // breakpoint or exception event.
-  if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) {
+  if (ignore_breakpoints_ || IsPaused()) {
     return;
   }
 
+  if (!HasDebugEventHandler()) {
+    OS::Print("Hit debugger!");
+  }
+
   DebuggerStackTrace* stack_trace = CollectStackTrace();
   ASSERT(stack_trace->Length() > 0);
   ASSERT(stack_trace_ == NULL);
@@ -2801,8 +2807,10 @@
 
 void Debugger::NotifyIsolateCreated() {
   // Signal isolate creation event.
-  if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
+  if ((isolate_ != Dart::vm_isolate()) &&
+      !ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
     SignalIsolateEvent(DebuggerEvent::kIsolateCreated);
+    creation_message_sent_ = true;
   }
 }
 
@@ -2811,20 +2819,14 @@
 // the given token position.
 RawFunction* Debugger::FindInnermostClosure(const Function& function,
                                             intptr_t token_pos) {
-  const Class& owner = Class::Handle(zone(), function.Owner());
-  if (owner.closures() == GrowableObjectArray::null()) {
-    return Function::null();
-  }
-  // Note that we need to check that the closure is in the same
-  // script as the outer function. We could have closures originating
-  // in mixin classes whose source code is contained in a different
-  // script.
-  const Script& outer_origin = Script::Handle(zone(), function.script());
+  Zone* zone = Thread::Current()->zone();
+  const Script& outer_origin = Script::Handle(zone, function.script());
   const GrowableObjectArray& closures =
-     GrowableObjectArray::Handle(zone(), owner.closures());
+     GrowableObjectArray::Handle(zone,
+         Isolate::Current()->object_store()->closure_functions());
   const intptr_t num_closures = closures.Length();
-  Function& closure = Function::Handle(zone());
-  Function& best_fit = Function::Handle(zone());
+  Function& closure = Function::Handle(zone);
+  Function& best_fit = Function::Handle(zone);
   for (intptr_t i = 0; i < num_closures; i++) {
     closure ^= closures.At(i);
     if ((function.token_pos() < closure.token_pos()) &&
@@ -2852,13 +2854,14 @@
   }
   // Iterate over all source breakpoints to check whether breakpoints
   // need to be set in the newly compiled function.
-  Script& script = Script::Handle(zone());
+  Zone* zone = Thread::Current()->zone();
+  Script& script = Script::Handle(zone);
   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(zone());
+      Function& inner_function = Function::Handle(zone);
       inner_function = FindInnermostClosure(func, loc->token_pos());
       if (!inner_function.IsNull()) {
         // The local function of a function we just compiled cannot
@@ -2939,10 +2942,10 @@
     // Common, fast path.
     return;
   }
-  Zone* zn = zone();
-  Library& lib = Library::Handle(zn);
-  Script& script = Script::Handle(zn);
-  String& url = String::Handle(zn);
+  Zone* zone = Thread::Current()->zone();
+  Library& lib = Library::Handle(zone);
+  Script& script = Script::Handle(zone);
+  String& url = String::Handle(zone);
   BreakpointLocation* loc = latent_locations_;
   BreakpointLocation* prev_loc = NULL;
   const GrowableObjectArray& libs =
@@ -3215,7 +3218,7 @@
                                                   intptr_t line,
                                                   intptr_t column) {
   BreakpointLocation* bpt = latent_locations_;
-  String& bpt_url = String::Handle(zone());
+  String& bpt_url = String::Handle();
   while (bpt != NULL) {
     bpt_url = bpt->url();
     if (bpt_url.Equals(url) &&
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index a9d0547..acb69ec 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -515,7 +515,9 @@
 
   // Returns true if there is at least one breakpoint set in func or code.
   // Checks for both user-defined and internal temporary breakpoints.
-  bool HasBreakpoint(const Function& func);
+  // This may be called from different threads, therefore do not use the,
+  // debugger's zone.
+  bool HasBreakpoint(const Function& func, Zone* zone);
   bool HasBreakpoint(const Code& code);
 
   // Returns true if the call at address pc is patched to point to
@@ -582,7 +584,8 @@
     kSingleStep
   };
 
-  static bool HasEventHandler();
+  static bool HasAnyEventHandler();
+  static bool HasDebugEventHandler();
   void InvokeEventHandler(DebuggerEvent* event);
 
   void FindCompiledFunctions(const Script& script,
@@ -650,11 +653,10 @@
 
   void HandleSteppingRequest(DebuggerStackTrace* stack_trace);
 
-  Zone* zone() const { return isolate_->current_zone(); }
-
   Isolate* isolate_;
   Dart_Port isolate_id_;  // A unique ID for the isolate in the debugger.
   bool initialized_;
+  bool creation_message_sent_;  // The creation message has been sent.
 
   // ID number generator.
   intptr_t next_id_;
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index bd6883c..7e1ec45 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -56,6 +56,7 @@
 
 DART_EXPORT intptr_t Dart_CacheObject(Dart_Handle object_in) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object_in));
   if (obj.IsApiError()) {
     return -1;
@@ -66,11 +67,12 @@
 
 DART_EXPORT Dart_Handle Dart_GetCachedObject(intptr_t obj_id) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   if (!I->debugger()->IsValidObjectId(obj_id)) {
     return Api::NewError("%s: object id %" Pd " is invalid",
                          CURRENT_FUNC, obj_id);
   }
-  return Api::NewHandle(I, I->debugger()->GetCachedObject(obj_id));
+  return Api::NewHandle(T, I->debugger()->GetCachedObject(obj_id));
 }
 
 
@@ -117,7 +119,7 @@
     if (paused_event_handler != NULL) {
       Dart_CodeLocation location;
       ActivationFrame* top_frame = event->top_frame();
-      location.script_url = Api::NewHandle(isolate, top_frame->SourceUrl());
+      location.script_url = Api::NewHandle(thread, top_frame->SourceUrl());
       const Library& lib = Library::Handle(top_frame->Library());
       location.library_id = lib.index();
       location.token_pos = top_frame->TokenPos();
@@ -138,7 +140,7 @@
       Script& script = Script::Handle(zone);
       intptr_t token_pos;
       bpt->bpt_location()->GetCodeLocation(&library, &script, &token_pos);
-      location.script_url = Api::NewHandle(isolate, script.url());
+      location.script_url = Api::NewHandle(thread, script.url());
       location.library_id = library.index();
       location.token_pos = token_pos;
       (*bp_resolved_handler)(isolate_id, bpt->id(), location);
@@ -146,7 +148,7 @@
   } else if (event->type() == DebuggerEvent::kExceptionThrown) {
     if (exc_thrown_handler != NULL) {
       Dart_Handle exception =
-          Api::NewHandle(isolate, event->exception()->raw());
+          Api::NewHandle(thread, event->exception()->raw());
       Dart_StackTrace trace =
       reinterpret_cast<Dart_StackTrace>(isolate->debugger()->StackTrace());
       (*exc_thrown_handler)(isolate_id, exception, trace);
@@ -199,6 +201,7 @@
 DART_EXPORT Dart_Handle Dart_SetExceptionPauseInfo(
                             Dart_ExceptionPauseInfo pause_info) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   I->debugger()->SetExceptionPauseInfo(pause_info);
   return Api::Success();
 }
@@ -206,12 +209,14 @@
 
 DART_EXPORT Dart_ExceptionPauseInfo Dart_GetExceptionPauseInfo() {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   return I->debugger()->GetExceptionPauseInfo();
 }
 
 
 DART_EXPORT Dart_Handle Dart_GetStackTrace(Dart_StackTrace* trace) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   CHECK_NOT_NULL(trace);
   *trace = reinterpret_cast<Dart_StackTrace>(
       I->debugger()->CurrentStackTrace());
@@ -231,6 +236,7 @@
     if (dart_stacktrace.IsNull()) {
       *trace = NULL;
     } else {
+      Isolate* I = T->isolate();
       *trace = reinterpret_cast<Dart_StackTrace>(
         I->debugger()->StackTraceFrom(dart_stacktrace));
     }
@@ -251,10 +257,10 @@
   DARTSCOPE(Thread::Current());
   CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
   if (function_name != NULL) {
-    *function_name = Api::NewHandle(I, frame->QualifiedFunctionName());
+    *function_name = Api::NewHandle(T, frame->QualifiedFunctionName());
   }
   if (script_url != NULL) {
-    *script_url = Api::NewHandle(I, frame->SourceUrl());
+    *script_url = Api::NewHandle(T, frame->SourceUrl());
   }
   if (line_number != NULL) {
     *line_number = frame->LineNumber();
@@ -276,14 +282,14 @@
   DARTSCOPE(Thread::Current());
   CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
   if (function_name != NULL) {
-    *function_name = Api::NewHandle(I, frame->QualifiedFunctionName());
+    *function_name = Api::NewHandle(T, frame->QualifiedFunctionName());
   }
   if (function != NULL) {
-    *function = Api::NewHandle(I, frame->function().raw());
+    *function = Api::NewHandle(T, frame->function().raw());
   }
 
   if (location != NULL) {
-    location->script_url = Api::NewHandle(I, frame->SourceUrl());
+    location->script_url = Api::NewHandle(T, frame->SourceUrl());
     const Library& lib = Library::Handle(Z, frame->Library());
     location->library_id = lib.index();
     location->token_pos = frame->TokenPos();
@@ -320,7 +326,7 @@
                             Dart_ActivationFrame activation_frame) {
   DARTSCOPE(Thread::Current());
   CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
-  return Api::NewHandle(I, frame->GetLocalVariables());
+  return Api::NewHandle(T, frame->GetLocalVariables());
 }
 
 
@@ -328,6 +334,7 @@
                             Dart_Handle script_url_in,
                             intptr_t line_number) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
 
   Debugger* debugger = I->debugger();
@@ -343,6 +350,7 @@
 
 DART_EXPORT Dart_Handle Dart_GetBreakpointURL(intptr_t bp_id) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   Debugger* debugger = I->debugger();
 
   Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
@@ -350,12 +358,13 @@
     return Api::NewError("%s: breakpoint with id %" Pd " does not exist",
                            CURRENT_FUNC, bp_id);
   }
-  return Api::NewHandle(I, bpt->bpt_location()->url());
+  return Api::NewHandle(T, bpt->bpt_location()->url());
 }
 
 
 DART_EXPORT Dart_Handle Dart_GetBreakpointLine(intptr_t bp_id) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   Debugger* debugger = I->debugger();
 
   Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
@@ -376,6 +385,7 @@
                             Dart_Handle class_name_in,
                             Dart_Handle function_name_in) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   UNWRAP_AND_CHECK_PARAM(Library, library, library_in);
   UNWRAP_AND_CHECK_PARAM(String, class_name, class_name_in);
   UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in);
@@ -415,6 +425,7 @@
                             Dart_Handle class_name_in,
                             Dart_Handle function_name_in) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   UNWRAP_AND_CHECK_PARAM(Library, library, library_in);
   UNWRAP_AND_CHECK_PARAM(String, class_name, class_name_in);
   UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in);
@@ -442,7 +453,7 @@
   const Error& error = Error::Handle(Z,
       debugger->OneTimeBreakAtEntry(bp_target));
   if (!error.IsNull()) {
-    return Api::NewHandle(I, error.raw());
+    return Api::NewHandle(T, error.raw());
   }
   return Api::Success();
 }
@@ -450,6 +461,7 @@
 
 DART_EXPORT Dart_Handle Dart_RemoveBreakpoint(intptr_t bp_id) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   I->debugger()->RemoveBreakpoint(bp_id);
   return Api::Success();
 }
@@ -457,6 +469,7 @@
 
 DART_EXPORT Dart_Handle Dart_SetStepOver() {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   I->debugger()->SetStepOver();
   return Api::Success();
 }
@@ -464,6 +477,7 @@
 
 DART_EXPORT Dart_Handle Dart_SetStepInto() {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   I->debugger()->SetSingleStep();
   return Api::Success();
 }
@@ -471,6 +485,7 @@
 
 DART_EXPORT Dart_Handle Dart_SetStepOut() {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   I->debugger()->SetStepOut();
   return Api::Success();
 }
@@ -478,44 +493,48 @@
 
 DART_EXPORT Dart_Handle Dart_GetInstanceFields(Dart_Handle object_in) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   UNWRAP_AND_CHECK_PARAM(Instance, obj, object_in);
-  return Api::NewHandle(I, I->debugger()->GetInstanceFields(obj));
+  return Api::NewHandle(T, I->debugger()->GetInstanceFields(obj));
 }
 
 
 DART_EXPORT Dart_Handle Dart_GetStaticFields(Dart_Handle target) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const Type& type_obj = Api::UnwrapTypeHandle(Z, target);
   if (type_obj.IsNull()) {
     return Api::NewError("%s expects argument 'target' to be a type",
                          CURRENT_FUNC);
   }
   const Class& cls = Class::Handle(Z, type_obj.type_class());
-  return Api::NewHandle(I, I->debugger()->GetStaticFields(cls));
+  return Api::NewHandle(T, I->debugger()->GetStaticFields(cls));
 }
 
 
 DART_EXPORT Dart_Handle Dart_GetLibraryFields(intptr_t library_id) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   const Library& lib =
       Library::Handle(Z, Library::GetLibrary(library_id));
   if (lib.IsNull()) {
     return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
-  return Api::NewHandle(I, I->debugger()->GetLibraryFields(lib));
+  return Api::NewHandle(T, I->debugger()->GetLibraryFields(lib));
 }
 
 
 DART_EXPORT Dart_Handle Dart_GetGlobalVariables(intptr_t library_id) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
 
   const Library& lib = Library::Handle(Z, Library::GetLibrary(library_id));
   if (lib.IsNull()) {
     return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
-  return Api::NewHandle(I, I->debugger()->GetGlobalFields(lib));
+  return Api::NewHandle(T, I->debugger()->GetGlobalFields(lib));
 }
 
 
@@ -525,7 +544,7 @@
   DARTSCOPE(Thread::Current());
   CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
   UNWRAP_AND_CHECK_PARAM(String, expr, expr_in);
-  return Api::NewHandle(I, frame->Evaluate(expr));
+  return Api::NewHandle(T, frame->Evaluate(expr));
 }
 
 
@@ -543,22 +562,22 @@
   // Type extends Instance, must check first.
   if (target.IsType()) {
     const Class& cls = Class::Handle(Z, Type::Cast(target).type_class());
-    return Api::NewHandle(I, cls.Evaluate(expr,
+    return Api::NewHandle(T, cls.Evaluate(expr,
                                           Array::empty_array(),
                                           Array::empty_array()));
   } else if (target.IsInstance()) {
     const Instance& inst = Instance::Cast(target);
-    return Api::NewHandle(I, inst.Evaluate(expr,
+    return Api::NewHandle(T, inst.Evaluate(expr,
                                            Array::empty_array(),
                                            Array::empty_array()));
   } else if (target.IsLibrary()) {
     const Library& lib = Library::Cast(target);
-    return Api::NewHandle(I, lib.Evaluate(expr,
+    return Api::NewHandle(T, lib.Evaluate(expr,
                                           Array::empty_array(),
                                           Array::empty_array()));
   } else if (target.IsClass()) {
     const Class& cls = Class::Cast(target);
-    return Api::NewHandle(I, cls.Evaluate(expr,
+    return Api::NewHandle(T, cls.Evaluate(expr,
                                           Array::empty_array(),
                                           Array::empty_array()));
   }
@@ -569,7 +588,7 @@
 DART_EXPORT Dart_Handle Dart_GetObjClass(Dart_Handle object_in) {
   DARTSCOPE(Thread::Current());
   UNWRAP_AND_CHECK_PARAM(Instance, obj, object_in);
-  return Api::NewHandle(I, obj.GetType());
+  return Api::NewHandle(T, obj.GetType());
 }
 
 
@@ -585,11 +604,12 @@
 
 DART_EXPORT Dart_Handle Dart_GetClassFromId(intptr_t class_id) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   if (!I->class_table()->IsValidIndex(class_id)) {
     return Api::NewError("%s: %" Pd " is not a valid class id",
                          CURRENT_FUNC, class_id);
   }
-  return Api::NewHandle(I, I->class_table()->At(class_id));
+  return Api::NewHandle(T, I->class_table()->At(class_id));
 }
 
 
@@ -613,7 +633,7 @@
     if (type.IsNull()) {
       return Dart_Null();
     }
-    return Api::NewHandle(I, type.Canonicalize());
+    return Api::NewHandle(T, type.Canonicalize());
   }
   // Set up the type arguments array for the super class type.
   const Class& super_cls = Class::Handle(cls.SuperClass());
@@ -635,7 +655,7 @@
       Type::New(super_cls, super_type_args_array, Scanner::kNoSourcePos));
   ASSERT(!instantiated_type.IsNull());
   instantiated_type.SetIsFinalized();
-  return Api::NewHandle(I, instantiated_type.Canonicalize());
+  return Api::NewHandle(T, instantiated_type.Canonicalize());
 }
 
 
@@ -654,10 +674,10 @@
   const Function& func = Function::Handle(Closure::function(instance));
   ASSERT(!func.IsNull());
   if (name != NULL) {
-    *name = Api::NewHandle(I, func.QualifiedUserVisibleName());
+    *name = Api::NewHandle(T, func.QualifiedUserVisibleName());
   }
   if (signature != NULL) {
-    *signature = Api::NewHandle(I, func.UserVisibleSignature());
+    *signature = Api::NewHandle(T, func.UserVisibleSignature());
   }
 
   if (location != NULL) {
@@ -669,11 +689,11 @@
       // Note func.script() is not the same as cls.script() for eval functions.
       const Script& script = Script::Handle(Z, func.script());
       ASSERT(!script.IsNull());
-      location->script_url = Api::NewHandle(I, script.url());
+      location->script_url = Api::NewHandle(T, script.url());
       location->library_id = lib.index();
       location->token_pos = func.token_pos();
     } else {
-      location->script_url = Api::NewHandle(I, String::null());
+      location->script_url = Api::NewHandle(T, String::null());
       location->library_id = -1;
       location->token_pos = -1;
     }
@@ -689,13 +709,14 @@
                             intptr_t* super_class_id,
                             Dart_Handle* static_fields) {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
   if (!I->class_table()->IsValidIndex(cls_id)) {
     return Api::NewError("%s: %" Pd " is not a valid class id",
                          CURRENT_FUNC, cls_id);
   }
   Class& cls = Class::Handle(Z, I->class_table()->At(cls_id));
   if (class_name != NULL) {
-    *class_name = Api::NewHandle(I, cls.Name());
+    *class_name = Api::NewHandle(T, cls.Name());
   }
   if (library_id != NULL) {
     const Library& lib = Library::Handle(Z, cls.library());
@@ -710,7 +731,7 @@
   }
   if (static_fields != NULL) {
     *static_fields =
-        Api::NewHandle(I, I->debugger()->GetStaticFields(cls));
+        Api::NewHandle(T, I->debugger()->GetStaticFields(cls));
   }
   return Api::Success();
 }
@@ -732,7 +753,7 @@
                          CURRENT_FUNC, script_url.ToCString(),
                          String::Handle(lib.url()).ToCString());
   }
-  return Api::NewHandle(I, script.Source());
+  return Api::NewHandle(T, script.Source());
 }
 
 
@@ -755,7 +776,7 @@
 
   const GrowableObjectArray& info =
       GrowableObjectArray::Handle(script.GenerateLineNumberArray());
-  return Api::NewHandle(I, Array::MakeArray(info));
+  return Api::NewHandle(T, Array::MakeArray(info));
 }
 
 
@@ -778,7 +799,7 @@
                          library_url.ToCString());
   }
 
-  return Api::NewHandle(I, script.GenerateSource());
+  return Api::NewHandle(T, script.GenerateSource());
 }
 
 
@@ -802,12 +823,13 @@
     url = script.url();
     script_list.SetAt(i, url);
   }
-  return Api::NewHandle(I, script_list.raw());
+  return Api::NewHandle(T, script_list.raw());
 }
 
 
 DART_EXPORT Dart_Handle Dart_GetLibraryIds() {
   DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
 
   const GrowableObjectArray& libs =
       GrowableObjectArray::Handle(Z, I->object_store()->libraries());
@@ -822,7 +844,7 @@
     ASSERT(Smi::IsValid(lib.index()));
     library_id_list.SetAt(i, Smi::Handle(Smi::New(lib.index())));
   }
-  return Api::NewHandle(I, library_id_list.raw());
+  return Api::NewHandle(T, library_id_list.raw());
 }
 
 
@@ -833,7 +855,7 @@
     return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
-  return Api::NewHandle(I, lib.raw());
+  return Api::NewHandle(T, lib.raw());
 }
 
 
@@ -885,7 +907,7 @@
       import_list.Add(Smi::Handle(Smi::New(imported.index())));
     }
   }
-  return Api::NewHandle(I, Array::MakeArray(import_list));
+  return Api::NewHandle(T, Array::MakeArray(import_list));
 }
 
 
@@ -896,7 +918,7 @@
     return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
-  return Api::NewHandle(I, lib.url());
+  return Api::NewHandle(T, lib.url());
 }
 
 
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index ca260f2..8487801 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -11,6 +11,7 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, background_compilation);
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, use_osr);
 
@@ -493,6 +494,8 @@
 
 
 TEST_CASE(Debug_InspectStack_Optimized) {
+  // Ensure code gets optimized.
+  FLAG_background_compilation = false;
   InspectStackTest(true);
 }
 
@@ -589,6 +592,8 @@
 
 
 TEST_CASE(Debug_InspectStackWithClosure_Optimized) {
+  // Ensure code gets optimized.
+  FLAG_background_compilation = false;
   InspectStackWithClosureTest(true);
 }
 
@@ -1506,11 +1511,11 @@
 
 
 TEST_CASE(Debug_InterruptIsolate) {
-  Dart_SetIsolateEventHandler(&TestInterruptIsolate);
   sync = new Monitor();
+  Dart_SetIsolateEventHandler(&TestInterruptIsolate);
   EXPECT(interrupt_isolate_id == ILLEGAL_ISOLATE_ID);
   Dart_SetPausedEventHandler(InterruptIsolateHandler);
-  int result = OSThread::Start(InterruptIsolateRun, 0);
+  int result = OSThread::Start("DebugInterruptIsolate", InterruptIsolateRun, 0);
   EXPECT_EQ(0, result);
 
   // Wait for the test isolate to be created.
@@ -2138,8 +2143,8 @@
       "int main() {\n"
       "}\n";
 
-  Isolate* isolate = Isolate::Current();
-  Zone* zone = isolate->current_zone();
+
+  Zone* zone = thread->zone();
   LoadScript(kScriptChars);
   ASSERT(script_lib != NULL);
   ASSERT(Dart_IsLibrary(script_lib));
diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc
index 3d86592..71a734a 100644
--- a/runtime/vm/deferred_objects.cc
+++ b/runtime/vm/deferred_objects.cc
@@ -173,16 +173,18 @@
   *reinterpret_cast<RawObject**>(dest_addr) = code.raw();
 
   if (FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("materializing pc marker at 0x%" Px ": %s, %s\n",
-                 reinterpret_cast<uword>(slot()), code.ToCString(),
-                 function.ToCString());
+    THR_Print("materializing pc marker at 0x%" Px ": %s, %s\n",
+        reinterpret_cast<uword>(slot()), code.ToCString(),
+        function.ToCString());
   }
 
   // Increment the deoptimization counter. This effectively increments each
   // function occurring in the optimized frame.
-  function.set_deoptimization_counter(function.deoptimization_counter() + 1);
+  if (deopt_context->deoptimizing_code()) {
+    function.set_deoptimization_counter(function.deoptimization_counter() + 1);
+  }
   if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("Deoptimizing %s (count %d)\n",
+    THR_Print("Deoptimizing '%s' (count %d)\n",
         function.ToFullyQualifiedCString(),
         function.deoptimization_counter());
   }
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 134d85c..4970e59 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -27,7 +27,8 @@
                            DestFrameOptions dest_options,
                            fpu_register_t* fpu_registers,
                            intptr_t* cpu_registers,
-                           bool is_lazy_deopt)
+                           bool is_lazy_deopt,
+                           bool deoptimizing_code)
     : code_(code.raw()),
       object_pool_(code.GetObjectPool()),
       deopt_info_(TypedData::null()),
@@ -43,11 +44,12 @@
       deopt_reason_(ICData::kDeoptUnknown),
       deopt_flags_(0),
       thread_(Thread::Current()),
-      timeline_event_(NULL),
+      deopt_start_micros_(0),
       deferred_slots_(NULL),
       deferred_objects_count_(0),
       deferred_objects_(NULL),
-      is_lazy_deopt_(is_lazy_deopt) {
+      is_lazy_deopt_(is_lazy_deopt),
+      deoptimizing_code_(deoptimizing_code) {
   const TypedData& deopt_info = TypedData::Handle(
       code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason_, &deopt_flags_));
   ASSERT(!deopt_info.IsNull());
@@ -99,18 +101,11 @@
   if (dest_options != kDestIsAllocated) {
     // kDestIsAllocated is used by the debugger to generate a stack trace
     // and does not signal a real deopt.
-    Isolate* isolate = Isolate::Current();
-    TimelineStream* compiler_stream = isolate->GetCompilerStream();
-    ASSERT(compiler_stream != NULL);
-    timeline_event_ = compiler_stream->StartEvent();
-    if (timeline_event_ != NULL) {
-      timeline_event_->DurationBegin("Deoptimize");
-      timeline_event_->SetNumArguments(3);
-    }
+    deopt_start_micros_ = OS::GetCurrentMonotonicMicros();
   }
 
   if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr(
+    THR_Print(
         "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n",
         deopt_reason(),
         DeoptReasonToCString(deopt_reason()),
@@ -143,24 +138,28 @@
   delete[] deferred_objects_;
   deferred_objects_ = NULL;
   deferred_objects_count_ = 0;
-  if (timeline_event_ != NULL) {
-    const Code& code = Code::Handle(zone(), code_);
-    const Function& function = Function::Handle(zone(), code.function());
-    timeline_event_->CopyArgument(
-        0,
-        "function",
-        const_cast<char*>(function.QualifiedUserVisibleNameCString()));
-    timeline_event_->CopyArgument(
-        1,
-        "reason",
-        const_cast<char*>(DeoptReasonToCString(deopt_reason())));
-    timeline_event_->FormatArgument(
-        2,
-        "deoptimizationCount",
-        "%d",
-        function.deoptimization_counter());
-    timeline_event_->DurationEnd();
-    timeline_event_->Complete();
+  if (deopt_start_micros_ != 0) {
+    Isolate* isolate = Isolate::Current();
+    TimelineStream* compiler_stream = isolate->GetCompilerStream();
+    ASSERT(compiler_stream != NULL);
+    if (compiler_stream->Enabled()) {
+      const Code& code = Code::Handle(zone(), code_);
+      const Function& function = Function::Handle(zone(), code.function());
+      const char* function_name = function.QualifiedUserVisibleNameCString();
+      const char* reason = DeoptReasonToCString(deopt_reason());
+      int counter = function.deoptimization_counter();
+      TimelineEvent* timeline_event = compiler_stream->StartEvent();
+      if (timeline_event != NULL) {
+        timeline_event->Duration("Deoptimize",
+                                 deopt_start_micros_,
+                                 OS::GetCurrentMonotonicMicros());
+        timeline_event->SetNumArguments(3);
+        timeline_event->CopyArgument(0, "function", function_name);
+        timeline_event->CopyArgument(1, "reason", reason);
+        timeline_event->FormatArgument(2, "deoptimizationCount", "%d", counter);
+        timeline_event->Complete();
+      }
+    }
   }
 }
 
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index cf357d0..acbf92b 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -23,6 +23,7 @@
 class TimelineEvent;
 
 // Holds all data relevant for execution of deoptimization instructions.
+// Structure is allocated in C-heap.
 class DeoptContext {
  public:
   enum DestFrameOptions {
@@ -30,12 +31,14 @@
     kDestIsAllocated        // Write deopt frame to a buffer.
   };
 
+  // If 'deoptimizing_code' is false, only frame is being deoptimized.
   DeoptContext(const StackFrame* frame,
                const Code& code,
                DestFrameOptions dest_options,
                fpu_register_t* fpu_registers,
                intptr_t* cpu_registers,
-               bool is_lazy_deopt);
+               bool is_lazy_deopt,
+               bool deoptimizing_code);
   virtual ~DeoptContext();
 
   // Returns the offset of the dest fp from the dest sp.  Used in
@@ -97,6 +100,8 @@
 
   bool is_lazy_deopt() const { return is_lazy_deopt_; }
 
+  bool deoptimizing_code() const { return deoptimizing_code_; }
+
   ICData::DeoptReasonId deopt_reason() const { return deopt_reason_; }
   bool HasDeoptFlag(ICData::DeoptFlags flag) {
     return (deopt_flags_ & flag) != 0;
@@ -224,7 +229,7 @@
   uint32_t deopt_flags_;
   intptr_t caller_fp_;
   Thread* thread_;
-  TimelineEvent* timeline_event_;
+  int64_t deopt_start_micros_;
 
   DeferredSlot* deferred_slots_;
 
@@ -232,6 +237,7 @@
   DeferredObject** deferred_objects_;
 
   const bool is_lazy_deopt_;
+  const bool deoptimizing_code_;
 
   DISALLOW_COPY_AND_ASSIGN(DeoptContext);
 };
diff --git a/runtime/vm/disassembler.cc b/runtime/vm/disassembler.cc
index 986b9b2..99b13ce 100644
--- a/runtime/vm/disassembler.cc
+++ b/runtime/vm/disassembler.cc
@@ -7,14 +7,17 @@
 #include "vm/assembler.h"
 #include "vm/globals.h"
 #include "vm/il_printer.h"
+#include "vm/instructions.h"
 #include "vm/json_stream.h"
 #include "vm/log.h"
 #include "vm/os.h"
+#include "vm/code_patcher.h"
 
 
 namespace dart {
 
-void DisassembleToStdout::ConsumeInstruction(char* hex_buffer,
+void DisassembleToStdout::ConsumeInstruction(const Code& code,
+                                             char* hex_buffer,
                                              intptr_t hex_size,
                                              char* human_buffer,
                                              intptr_t human_size,
@@ -41,18 +44,26 @@
 }
 
 
-void DisassembleToJSONStream::ConsumeInstruction(char* hex_buffer,
+void DisassembleToJSONStream::ConsumeInstruction(const Code& code,
+                                                 char* hex_buffer,
                                                  intptr_t hex_size,
                                                  char* human_buffer,
                                                  intptr_t human_size,
                                                  uword pc) {
-  // Instructions are represented as three consecutive values in a JSON array.
-  // All three are strings. The first is the address of the instruction,
-  // the second is the hex string of the code, and the final is a human
-  // readable string.
+  // Instructions are represented as four consecutive values in a JSON array.
+  // The first is the address of the instruction, the second is the hex string,
+  // of the code, and the third is a human readable string, and the fourth is
+  // the object loaded by the instruction.
   jsarr_.AddValueF("%" Pp "", pc);
   jsarr_.AddValue(hex_buffer);
   jsarr_.AddValue(human_buffer);
+
+  Object& object = Object::Handle();
+  if (DecodeLoadObjectFromPoolOrThread(pc, code, &object)) {
+    jsarr_.AddValue(object);
+  } else {
+    jsarr_.AddValueNull();  // Not a reference to null.
+  }
 }
 
 
@@ -71,12 +82,12 @@
       p[i] = ' ';
     }
   }
-  // Instructions are represented as three consecutive values in a JSON array.
-  // All three are strings. Comments only use the third slot. See above comment
-  // for more information.
-  jsarr_.AddValue("");
-  jsarr_.AddValue("");
+  // Instructions are represented as four consecutive values in a JSON array.
+  // Comments only use the third slot. See above comment for more information.
+  jsarr_.AddValueNull();
+  jsarr_.AddValueNull();
   jsarr_.AddValue(p);
+  jsarr_.AddValueNull();
   free(p);
 }
 
@@ -158,7 +169,8 @@
                       human_buffer,
                       sizeof(human_buffer),
                       &instruction_length, pc);
-    formatter->ConsumeInstruction(hex_buffer,
+    formatter->ConsumeInstruction(code,
+                                  hex_buffer,
                                   sizeof(hex_buffer),
                                   human_buffer,
                                   sizeof(human_buffer),
diff --git a/runtime/vm/disassembler.h b/runtime/vm/disassembler.h
index 1becc4d..e89ab21 100644
--- a/runtime/vm/disassembler.h
+++ b/runtime/vm/disassembler.h
@@ -24,7 +24,8 @@
   virtual ~DisassemblyFormatter() { }
 
   // Consume the decoded instruction at the given pc.
-  virtual void ConsumeInstruction(char* hex_buffer,
+  virtual void ConsumeInstruction(const Code& code,
+                                  char* hex_buffer,
                                   intptr_t hex_size,
                                   char* human_buffer,
                                   intptr_t human_size,
@@ -42,7 +43,8 @@
   DisassembleToStdout() : DisassemblyFormatter() { }
   ~DisassembleToStdout() { }
 
-  virtual void ConsumeInstruction(char* hex_buffer,
+  virtual void ConsumeInstruction(const Code& code,
+                                  char* hex_buffer,
                                   intptr_t hex_size,
                                   char* human_buffer,
                                   intptr_t human_size,
@@ -63,7 +65,8 @@
       : DisassemblyFormatter(), jsarr_(jsarr) { }
   ~DisassembleToJSONStream() { }
 
-  virtual void ConsumeInstruction(char* hex_buffer,
+  virtual void ConsumeInstruction(const Code& code,
+                                  char* hex_buffer,
                                   intptr_t hex_size,
                                   char* human_buffer,
                                   intptr_t human_size,
diff --git a/runtime/vm/disassembler_arm.cc b/runtime/vm/disassembler_arm.cc
index 93ff293..a544e3c 100644
--- a/runtime/vm/disassembler_arm.cc
+++ b/runtime/vm/disassembler_arm.cc
@@ -109,11 +109,16 @@
 
 
 // These register names are defined in a way to match the native disassembler
-// formatting, except for register alias pp (r9).
+// formatting, except for register alias pp (r5).
 // See for example the command "objdump -d <binary file>".
 static const char* reg_names[kNumberOfCpuRegisters] = {
-  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-  "r8", "pp", "r10", "fp", "ip", "sp", "lr", "pc",
+#if defined(TARGET_OS_MACOS)
+  "r0", "r1", "r2", "r3", "r4", "pp", "r6", "fp",
+  "r8", "r9", "r10", "r11", "ip", "sp", "lr", "pc",
+#else
+  "r0", "r1", "r2", "r3", "r4", "pp", "r6", "r7",
+  "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc",
+#endif
 };
 
 
diff --git a/runtime/vm/disassembler_arm64.cc b/runtime/vm/disassembler_arm64.cc
index 193d5b1..e414221 100644
--- a/runtime/vm/disassembler_arm64.cc
+++ b/runtime/vm/disassembler_arm64.cc
@@ -83,12 +83,12 @@
 
 
 // These register names are defined in a way to match the native disassembler
-// formatting, except for register aliases ctx (r9) and pp (r10).
+// formatting, except for register aliases ctx (r9), pp (r10) and sp (r19).
 // See for example the command "objdump -d <binary file>".
 static const char* reg_names[kNumberOfCpuRegisters] = {
   "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
   "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
-  "ip0", "ip1", "sp", "r19", "r20", "r21", "r22", "r23",
+  "ip0", "ip1", "r18", "sp",  "r20", "r21", "r22", "r23",
   "r24", "r25", "r26", "pp",  "ctx", "fp",  "lr",  "r31",
 };
 
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index af84199..aabaafe 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -543,6 +543,10 @@
         Format(instr, "mov.'fmt 'fd, 'fs");
         break;
       }
+      case COP1_NEG: {
+        Format(instr, "neg.'fmt 'fd, 'fs");
+        break;
+      }
       case COP1_C_F: {
         Format(instr, "c.f.'fmt 'fs, 'ft");
         break;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index d5d4b39..99563bb 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -502,9 +502,8 @@
 
 void Exceptions::PropagateError(const Error& error) {
   Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
-  ASSERT(isolate->top_exit_frame_info() != 0);
+  ASSERT(thread->top_exit_frame_info() != 0);
   if (error.IsUnhandledException()) {
     // If the error object represents an unhandled exception, then
     // rethrow the exception in the normal fashion.
@@ -625,10 +624,6 @@
       library = Library::IsolateLibrary();
       class_name = &Symbols::IsolateSpawnException();
       break;
-    case kIsolateUnhandledException:
-      library = Library::IsolateLibrary();
-      class_name = &Symbols::IsolateUnhandledException();
-      break;
     case kJavascriptIntegerOverflowError:
       library = Library::CoreLibrary();
       class_name = &Symbols::JavascriptIntegerOverflowError();
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 0bd97f8..4282bb5 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -60,7 +60,6 @@
     kOutOfMemory,
     kNullThrown,
     kIsolateSpawn,
-    kIsolateUnhandledException,
     kJavascriptIntegerOverflowError,
     kJavascriptCompatibilityError,
     kAssertion,
diff --git a/runtime/vm/flags.cc b/runtime/vm/flags.cc
index f38639f..c1ec041 100644
--- a/runtime/vm/flags.cc
+++ b/runtime/vm/flags.cc
@@ -288,8 +288,8 @@
   if (*equals != '=') {
     // No explicit option argument. Determine if there is a "no_" prefix
     // preceding the name.
-    const char* kNo1Prefix = "no_";
-    const char* kNo2Prefix = "no-";
+    const char* const kNo1Prefix = "no_";
+    const char* const kNo2Prefix = "no-";
     const intptr_t kNo1PrefixLen = strlen(kNo1Prefix);
     const intptr_t kNo2PrefixLen = strlen(kNo2Prefix);
     if (strncmp(option, kNo1Prefix, kNo1PrefixLen) == 0) {
@@ -359,7 +359,7 @@
 
   qsort(flags_, num_flags_, sizeof flags_[0], CompareFlagNames);
 
-  const char* kPrefix = "--";
+  const char* const kPrefix = "--";
   const intptr_t kPrefixLen = strlen(kPrefix);
 
   int i = 0;
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index a4753f2..4097af5 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -44,6 +44,7 @@
     loop_headers_(NULL),
     loop_invariant_loads_(NULL),
     guarded_fields_(parsed_function.guarded_fields()),
+    deoptimize_dependent_code_(),
     deferred_prefixes_(parsed_function.deferred_prefixes()),
     captured_parameters_(new(zone()) BitVector(zone(), variable_count())),
     inlining_id_(-1) {
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index d962f90..cf62e82 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -279,6 +279,10 @@
     return guarded_fields_;
   }
 
+  GrowableArray<const Field*>& deoptimize_dependent_code() {
+    return deoptimize_dependent_code_;
+  }
+
   ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes() const {
     return deferred_prefixes_;
   }
@@ -363,6 +367,7 @@
   ZoneGrowableArray<BlockEntryInstr*>* loop_headers_;
   ZoneGrowableArray<BitVector*>* loop_invariant_loads_;
   ZoneGrowableArray<const Field*>* guarded_fields_;
+  GrowableArray<const Field*> deoptimize_dependent_code_;
   ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes_;
   DirectChainedHashMap<ConstantPoolTrait> constant_instr_pool_;
   BitVector* captured_parameters_;
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 208a4af..e832212 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -101,24 +101,11 @@
 
   // All registers are marked as "not blocked" (array initialized to false).
   // Mark the unavailable ones as "blocked" (true).
-  for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) {
-    blocked_cpu_registers_[i] = true;
+  for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
+    if ((kDartAvailableCpuRegs & (1 << i)) == 0) {
+      blocked_cpu_registers_[i] = true;
+    }
   }
-  for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) {
-    blocked_cpu_registers_[i] = true;
-  }
-  if (TMP != kNoRegister) {
-    blocked_cpu_registers_[TMP] = true;
-  }
-  if (TMP2 != kNoRegister) {
-    blocked_cpu_registers_[TMP2] = true;
-  }
-  if (PP != kNoRegister) {
-    blocked_cpu_registers_[PP] = true;
-  }
-  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;
@@ -128,6 +115,11 @@
   // generating intrinsic code.
   if (intrinsic_mode) {
     blocked_cpu_registers_[ARGS_DESC_REG] = true;
+#if !defined(TARGET_ARCH_IA32)
+    // Need to preserve CODE_REG to be able to store the PC marker
+    // and load the pool pointer.
+    blocked_cpu_registers_[CODE_REG] = true;
+#endif
   }
 }
 
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index ea31f96..fed89bb 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -7,6 +7,7 @@
 #include "lib/invocation_mirror.h"
 #include "vm/ast_printer.h"
 #include "vm/bit_vector.h"
+#include "vm/compiler.h"
 #include "vm/class_finalizer.h"
 #include "vm/exceptions.h"
 #include "vm/flags.h"
@@ -38,8 +39,6 @@
 DEFINE_FLAG(bool, support_debugger, true, "Emit code needed for debugging");
 DEFINE_FLAG(bool, trace_type_check_elimination, false,
             "Trace type check elimination at compile time.");
-DEFINE_FLAG(bool, precompile_collect_closures, false,
-            "Collect all closure functions referenced from compiled code.");
 
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, profile_vm);
@@ -373,6 +372,8 @@
       instr->AsGoto()->adjust_edge_weight(scale_factor);
     }
   }
+
+  RemoveUnreachableExits(callee_graph);
 }
 
 
@@ -396,6 +397,25 @@
 }
 
 
+void InlineExitCollector::RemoveUnreachableExits(FlowGraph* callee_graph) {
+  const GrowableArray<BlockEntryInstr*>& postorder = callee_graph->postorder();
+  int j = 0;
+  for (int i = 0; i < exits_.length(); ++i) {
+    BlockEntryInstr* block = exits_[i].exit_return->GetBlock();
+    if ((block != NULL) &&
+        (0 <= block->postorder_number()) &&
+        (block->postorder_number() < postorder.length()) &&
+        (postorder[block->postorder_number()] == block)) {
+      if (i != j) {
+        exits_[j] = exits_[i];
+      }
+      j++;
+    }
+  }
+  exits_.TruncateTo(j);
+}
+
+
 void InlineExitCollector::SortExits() {
   // Assign block entries here because we did not necessarily know them when
   // the return exit was added to the array.
@@ -549,6 +569,10 @@
     call_->previous()->AppendInstruction(branch);
     call_block->set_last_instruction(branch);
 
+    // Replace uses of the return value with null to maintain valid
+    // SSA form - even though the rest of the caller is unreachable.
+    call_->ReplaceUsesWith(caller_graph_->constant_null());
+
     // Update dominator tree.
     call_block->AddDominatedBlock(callee_entry);
     call_block->AddDominatedBlock(false_block);
@@ -823,17 +847,18 @@
 
 
 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local,
-                                                Value* value) {
+                                                Value* value,
+                                                intptr_t token_pos) {
   if (local.is_captured()) {
     LocalVariable* tmp_var = EnterTempLocalScope(value);
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
-    Value* context = Bind(BuildCurrentContext());
+    Value* context = Bind(BuildCurrentContext(token_pos));
     while (delta-- > 0) {
       context = Bind(new(Z) LoadFieldInstr(
           context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
-          Scanner::kNoSourcePos));
+          token_pos));
     }
     Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
     StoreInstanceFieldInstr* store =
@@ -841,61 +866,68 @@
                                        context,
                                        tmp_val,
                                        kEmitStoreBarrier,
-                                       Scanner::kNoSourcePos);
+                                       token_pos);
     Do(store);
     return ExitTempLocalScope(tmp_var);
   } else {
-    return new(Z) StoreLocalInstr(local, value);
+    return new(Z) StoreLocalInstr(local, value, token_pos);
   }
 }
 
 
-Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
+Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local,
+                                               intptr_t token_pos) {
   if (local.IsConst()) {
-    return new(Z) ConstantInstr(*local.ConstValue());
+    return new(Z) ConstantInstr(*local.ConstValue(), token_pos);
   } else if (local.is_captured()) {
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
-    Value* context = Bind(BuildCurrentContext());
+    Value* context = Bind(BuildCurrentContext(token_pos));
     while (delta-- > 0) {
       context = Bind(new(Z) LoadFieldInstr(
           context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
-          Scanner::kNoSourcePos));
+          token_pos));
     }
     return new(Z) LoadFieldInstr(context,
-                              Context::variable_offset(local.index()),
-                              local.type(),
-                              Scanner::kNoSourcePos);
+                                 Context::variable_offset(local.index()),
+                                 local.type(),
+                                 token_pos);
   } else {
-    return new(Z) LoadLocalInstr(local);
+    return new(Z) LoadLocalInstr(local, token_pos);
   }
 }
 
 
 // Stores current context into the 'variable'
-void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) {
-  Value* context = Bind(BuildCurrentContext());
-  Do(BuildStoreLocal(variable, context));
+void EffectGraphVisitor::BuildSaveContext(
+    const LocalVariable& variable,
+    intptr_t token_pos) {
+  Value* context = Bind(BuildCurrentContext(token_pos));
+  Do(BuildStoreLocal(variable, context, token_pos));
 }
 
 
 // Loads context saved in 'context_variable' into the current context.
-void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) {
-  Value* load_saved_context = Bind(BuildLoadLocal(variable));
-  Do(BuildStoreContext(load_saved_context));
+void EffectGraphVisitor::BuildRestoreContext(
+    const LocalVariable& variable,
+    intptr_t token_pos) {
+  Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos));
+  Do(BuildStoreContext(load_saved_context, token_pos));
 }
 
 
-Definition* EffectGraphVisitor::BuildStoreContext(Value* value) {
+Definition* EffectGraphVisitor::BuildStoreContext(
+    Value* value, intptr_t token_pos) {
   return new(Z) StoreLocalInstr(
-      *owner()->parsed_function().current_context_var(), value);
+      *owner()->parsed_function().current_context_var(), value, token_pos);
 }
 
 
-Definition* EffectGraphVisitor::BuildCurrentContext() {
+Definition* EffectGraphVisitor::BuildCurrentContext(intptr_t token_pos) {
   return new(Z) LoadLocalInstr(
-      *owner()->parsed_function().current_context_var());
+      *owner()->parsed_function().current_context_var(),
+      token_pos);
 }
 
 
@@ -954,8 +986,7 @@
 
 void TestGraphVisitor::ReturnValue(Value* value) {
   Isolate* isolate = Isolate::Current();
-  if (isolate->flags().type_checks() ||
-      isolate->flags().asserts()) {
+  if (isolate->flags().type_checks() || isolate->flags().asserts()) {
     value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value));
   }
   Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
@@ -1091,7 +1122,7 @@
   // statements for which there is no associated source position.
   const Function& function = owner()->function();
   if (FLAG_support_debugger &&
-      (node->token_pos() != Scanner::kNoSourcePos) && !function.is_native()) {
+      (node->token_pos() >= 0) && !function.is_native()) {
     AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(),
                                               RawPcDescriptors::kRuntimeCall));
   }
@@ -1101,7 +1132,7 @@
   if (node->inlined_finally_list_length() > 0) {
     LocalVariable* temp = owner()->parsed_function().finally_return_temp_var();
     ASSERT(temp != NULL);
-    Do(BuildStoreLocal(*temp, return_value));
+    Do(BuildStoreLocal(*temp, return_value, node->token_pos()));
     for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
       InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)");
       EffectGraphVisitor for_effect(owner());
@@ -1111,7 +1142,7 @@
         return;
       }
     }
-    return_value = Bind(BuildLoadLocal(*temp));
+    return_value = Bind(BuildLoadLocal(*temp, node->token_pos()));
   }
 
   if (Isolate::Current()->flags().type_checks()) {
@@ -1153,12 +1184,12 @@
     ASSERT(rcv_var != NULL && rcv_var->is_captured());
     ZoneGrowableArray<PushArgumentInstr*>* arguments =
         new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
-    Value* rcv_value = Bind(BuildLoadLocal(*rcv_var));
+    Value* rcv_value = Bind(BuildLoadLocal(*rcv_var, node->token_pos()));
     arguments->Add(PushArgument(rcv_value));
     Value* returned_value = Bind(BuildLoadExprTemp());
     arguments->Add(PushArgument(returned_value));
     InstanceCallInstr* call = new(Z) InstanceCallInstr(
-        Scanner::kNoSourcePos,
+        node->token_pos(),
         Symbols::CompleterComplete(),
         Token::kILLEGAL,
         arguments,
@@ -1193,7 +1224,7 @@
 
 // <Expression> ::= Literal { literal: Instance }
 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
-  ReturnDefinition(new(Z) ConstantInstr(node->literal()));
+  ReturnDefinition(new(Z) ConstantInstr(node->literal(), node->token_pos()));
 }
 
 
@@ -1315,8 +1346,7 @@
     node->left()->Visit(&for_left);
     EffectGraphVisitor empty(owner());
     Isolate* isolate = Isolate::Current();
-    if (isolate->flags().type_checks() ||
-        isolate->flags().asserts()) {
+    if (isolate->flags().type_checks() || isolate->flags().asserts()) {
       ValueGraphVisitor for_right(owner());
       node->right()->Visit(&for_right);
       Value* right_value = for_right.value();
@@ -1337,37 +1367,8 @@
       }
     }
     return;
-  } else if (node->kind() == Token::kIFNULL) {
-    // left ?? right. This operation cannot be overloaded.
-    // temp = left; temp === null ? right : temp
-    ValueGraphVisitor for_left_value(owner());
-    node->left()->Visit(&for_left_value);
-    Append(for_left_value);
-    Do(BuildStoreExprTemp(for_left_value.value()));
-
-    LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
-    LoadLocalNode* load_temp =
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
-    LiteralNode* null_constant =
-        new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
-    ComparisonNode* check_is_null =
-        new(Z) ComparisonNode(Scanner::kNoSourcePos,
-                              Token::kEQ_STRICT,
-                              load_temp,
-                              null_constant);
-    TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
-    check_is_null->Visit(&for_test);
-
-    ValueGraphVisitor for_right_value(owner());
-    node->right()->Visit(&for_right_value);
-    for_right_value.Do(BuildStoreExprTemp(for_right_value.value()));
-
-    ValueGraphVisitor for_temp(owner());
-    // Nothing to do, left value is already loaded into temp.
-
-    Join(for_test, for_right_value, for_temp);
-    return;
   }
+  ASSERT(node->kind() != Token::kIFNULL);
   ValueGraphVisitor for_left_value(owner());
   node->left()->Visit(&for_left_value);
   Append(for_left_value);
@@ -1412,8 +1413,7 @@
     node->right()->Visit(&for_right);
     Value* right_value = for_right.value();
     Isolate* isolate = Isolate::Current();
-    if (isolate->flags().type_checks() ||
-        isolate->flags().asserts()) {
+    if (isolate->flags().type_checks() || isolate->flags().asserts()) {
       right_value =
           for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(),
                                                    right_value));
@@ -1442,37 +1442,6 @@
     }
     ReturnDefinition(BuildLoadExprTemp());
     return;
-  } else if (node->kind() == Token::kIFNULL) {
-    // left ?? right. This operation cannot be overloaded.
-    // temp = left; temp === null ? right : temp
-    ValueGraphVisitor for_left_value(owner());
-    node->left()->Visit(&for_left_value);
-    Append(for_left_value);
-    Do(BuildStoreExprTemp(for_left_value.value()));
-
-    LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
-    LoadLocalNode* load_temp =
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
-    LiteralNode* null_constant =
-        new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
-    ComparisonNode* check_is_null =
-        new(Z) ComparisonNode(Scanner::kNoSourcePos,
-                              Token::kEQ_STRICT,
-                              load_temp,
-                              null_constant);
-    TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
-    check_is_null->Visit(&for_test);
-
-    ValueGraphVisitor for_right_value(owner());
-    node->right()->Visit(&for_right_value);
-    for_right_value.Do(BuildStoreExprTemp(for_right_value.value()));
-
-    ValueGraphVisitor for_temp(owner());
-    // Nothing to do, left value is already loaded into temp.
-
-    Join(for_test, for_right_value, for_temp);
-    ReturnDefinition(BuildLoadExprTemp());
-    return;
   }
 
   EffectGraphVisitor::VisitBinaryOpNode(node);
@@ -1529,7 +1498,6 @@
 
 void EffectGraphVisitor::BuildTypecheckPushArguments(
     intptr_t token_pos,
-    PushArgumentInstr** push_instantiator_result,
     PushArgumentInstr** push_instantiator_type_arguments_result) {
   const Class& instantiator_class = Class::Handle(
       Z, owner()->function().Owner());
@@ -1539,15 +1507,11 @@
   Value* instantiator = BuildInstantiator(instantiator_class);
   if (instantiator == NULL) {
     // No instantiator when inside factory.
-    *push_instantiator_result = PushArgument(BuildNullValue());
     instantiator_type_arguments =
         BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
   } else {
-    instantiator = Bind(BuildStoreExprTemp(instantiator));
-    *push_instantiator_result = PushArgument(instantiator);
-    Value* loaded = Bind(BuildLoadExprTemp());
-    instantiator_type_arguments =
-        BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded);
+    instantiator_type_arguments = BuildInstantiatorTypeArguments(
+        token_pos, instantiator_class, instantiator);
   }
   *push_instantiator_type_arguments_result =
       PushArgument(instantiator_type_arguments);
@@ -1557,7 +1521,6 @@
 
 void EffectGraphVisitor::BuildTypecheckArguments(
     intptr_t token_pos,
-    Value** instantiator_result,
     Value** instantiator_type_arguments_result) {
   Value* instantiator = NULL;
   Value* instantiator_type_arguments = NULL;
@@ -1568,17 +1531,12 @@
   instantiator = BuildInstantiator(instantiator_class);
   if (instantiator == NULL) {
     // No instantiator when inside factory.
-    instantiator = BuildNullValue();
     instantiator_type_arguments =
         BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
   } else {
-    // Preserve instantiator.
-    instantiator = Bind(BuildStoreExprTemp(instantiator));
-    Value* loaded = Bind(BuildLoadExprTemp());
-    instantiator_type_arguments =
-        BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded);
+    instantiator_type_arguments = BuildInstantiatorTypeArguments(
+        token_pos, instantiator_class, instantiator);
   }
-  *instantiator_result = instantiator;
   *instantiator_type_arguments_result = instantiator_type_arguments;
 }
 
@@ -1595,21 +1553,16 @@
     const AbstractType& dst_type,
     const String& dst_name) {
   // Build the type check computation.
-  Value* instantiator = NULL;
   Value* instantiator_type_arguments = NULL;
   if (dst_type.IsInstantiated()) {
-    instantiator = BuildNullValue();
     instantiator_type_arguments = BuildNullValue();
   } else {
-    BuildTypecheckArguments(token_pos,
-                            &instantiator,
-                            &instantiator_type_arguments);
+    BuildTypecheckArguments(token_pos, &instantiator_type_arguments);
   }
 
   const intptr_t deopt_id = Thread::Current()->GetNextDeoptId();
   return new(Z) AssertAssignableInstr(token_pos,
                                       value,
-                                      instantiator,
                                       instantiator_type_arguments,
                                       dst_type,
                                       dst_name,
@@ -1711,20 +1664,15 @@
   }
 
   PushArgumentInstr* push_left = PushArgument(for_left_value.value());
-  PushArgumentInstr* push_instantiator = NULL;
   PushArgumentInstr* push_type_args = NULL;
   if (type.IsInstantiated()) {
-    push_instantiator = PushArgument(BuildNullValue());
     push_type_args = PushArgument(BuildNullValue());
   } else {
-    BuildTypecheckPushArguments(node->token_pos(),
-                                &push_instantiator,
-                                &push_type_args);
+    BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
   }
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(Z) ZoneGrowableArray<PushArgumentInstr*>(5);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(4);
   arguments->Add(push_left);
-  arguments->Add(push_instantiator);
   arguments->Add(push_type_args);
   ASSERT(!node->right()->AsTypeNode()->type().IsNull());
   Value* type_const = Bind(new(Z) ConstantInstr(type));
@@ -1768,20 +1716,15 @@
     }
   }
   PushArgumentInstr* push_left = PushArgument(for_value.value());
-  PushArgumentInstr* push_instantiator = NULL;
   PushArgumentInstr* push_type_args = NULL;
   if (type.IsInstantiated()) {
-    push_instantiator = PushArgument(BuildNullValue());
     push_type_args = PushArgument(BuildNullValue());
   } else {
-    BuildTypecheckPushArguments(node->token_pos(),
-                                &push_instantiator,
-                                &push_type_args);
+    BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
   }
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(Z) ZoneGrowableArray<PushArgumentInstr*>(4);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(3);
   arguments->Add(push_left);
-  arguments->Add(push_instantiator);
   arguments->Add(push_type_args);
   Value* type_arg = Bind(new(Z) ConstantInstr(type));
   arguments->Add(PushArgument(type_arg));
@@ -1809,10 +1752,10 @@
   right->Visit(&for_right_value);
   Append(for_right_value);
   StrictCompareInstr* comp = new(Z) StrictCompareInstr(token_pos,
-                                                    kind,
-                                                    for_left_value.value(),
-                                                    for_right_value.value(),
-                                                    true);  // Number check.
+                                                       kind,
+                                                       for_left_value.value(),
+                                                       for_right_value.value(),
+                                                       true);  // Number check.
   return comp;
 }
 
@@ -1878,8 +1821,7 @@
         owner()->ic_data_array());
     if (node->kind() == Token::kNE) {
       Isolate* isolate = Isolate::Current();
-      if (isolate->flags().type_checks() ||
-          isolate->flags().asserts()) {
+      if (isolate->flags().type_checks() || isolate->flags().asserts()) {
         Value* value = Bind(result);
         result = new(Z) AssertBooleanInstr(node->token_pos(), value);
       }
@@ -1926,8 +1868,7 @@
     Append(for_value);
     Value* value = for_value.value();
     Isolate* isolate = Isolate::Current();
-    if (isolate->flags().type_checks() ||
-        isolate->flags().asserts()) {
+    if (isolate->flags().type_checks() || isolate->flags().asserts()) {
       value =
           Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value));
     }
@@ -2350,7 +2291,7 @@
       Smi::ZoneHandle(Z, Smi::New(jump_count))));
   Do(BuildStoreLocal(*jump_var, jump_val));
   // Save the current context for resuming.
-  BuildSaveContext(*ctx_var);
+  BuildSaveContext(*ctx_var, node->token_pos());
 }
 
 
@@ -2372,7 +2313,7 @@
   char name[64];
   OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
   LocalVariable*  var =
-      new(Z) LocalVariable(0,
+      new(Z) LocalVariable(Scanner::kNoSourcePos,
                            String::ZoneHandle(Z, Symbols::New(name)),
                            *value->Type()->ToAbstractType());
   var->set_index(index);
@@ -2525,37 +2466,15 @@
 }
 
 
-// TODO(rmacnak): De-dup closures in inlined-finally and track down other
-// stragglers to use Class::closures instead.
-static void CollectClosureFunction(const Function& function) {
-  if (function.HasCode()) return;
-
-  // Although this is only called when precompiling, this can happen before
-  // Dart_Precompile as part of loading code, so check for a non-null work
-  // list.
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  if (isolate->collected_closures() != GrowableObjectArray::null()) {
-    const GrowableObjectArray& functions =
-        GrowableObjectArray::Handle(thread->zone(),
-                                    isolate->collected_closures());
-    functions.Add(function);
-  }
-}
-
-
 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
   const Function& function = node->function();
-  if (FLAG_precompile_collect_closures) {
-    CollectClosureFunction(function);
-  }
-
   if (function.IsImplicitStaticClosureFunction()) {
     const Instance& closure =
         Instance::ZoneHandle(Z, function.ImplicitStaticClosure());
     ReturnDefinition(new(Z) ConstantInstr(closure));
     return;
   }
+
   const bool is_implicit = function.IsImplicitInstanceClosureFunction();
   ASSERT(is_implicit || function.IsNonImplicitClosureFunction());
   // The context scope may have already been set by the non-optimizing
@@ -2567,25 +2486,18 @@
     ASSERT(!function.HasCode());
     ASSERT(function.context_scope() == ContextScope::null());
     function.set_context_scope(context_scope);
-    const Class& cls = Class::Handle(Z, owner()->function().Owner());
+
     // The closure is now properly setup, add it to the lookup table.
     // It is possible that the compiler creates more than one function
     // object for the same closure, e.g. when inlining nodes from
     // finally clauses. If we already have a function object for the
-    // same closure, do not add a second one. We compare the origin
-    // class, token position, and parent function to detect duplicates.
-    // Note that we can have two different closure object for the same
-    // source text representation of the closure: one with a non-closurized
-    // parent, and one with a closurized parent function.
-
-    const Function& found_func = Function::Handle(
-        Z, cls.LookupClosureFunction(function.token_pos()));
-
-    if (found_func.IsNull() ||
-        (found_func.token_pos() != function.token_pos()) ||
-        (found_func.script() != function.script()) ||
-        (found_func.parent_function() != function.parent_function())) {
-      cls.AddClosureFunction(function);
+    // same closure, do not add a second one. We compare token position,
+    // and parent function to detect duplicates.
+    const Function& parent = Function::Handle(function.parent_function());
+    const Function& found_func = Function::Handle(Z,
+        isolate()->LookupClosureFunction(parent, function.token_pos()));
+    if (found_func.IsNull()) {
+      isolate()->AddClosureFunction(function);
     }
   }
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
@@ -2655,8 +2567,9 @@
       }
     } else {
       // Store current context in closure.
-      closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
-      Value* context = Bind(BuildCurrentContext());
+      closure_tmp_val = Bind(
+          new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
+      Value* context = Bind(BuildCurrentContext(node->token_pos()));
       Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(),
                                         closure_tmp_val,
                                         context,
@@ -2864,9 +2777,9 @@
 
 
 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
-  Value* context = Bind(BuildCurrentContext());
+  Value* context = Bind(BuildCurrentContext(node->token_pos()));
   Value* clone = Bind(new(Z) CloneContextInstr(node->token_pos(), context));
-  Do(BuildStoreContext(clone));
+  Do(BuildStoreContext(clone, node->token_pos()));
 }
 
 
@@ -2895,14 +2808,10 @@
 void EffectGraphVisitor::BuildConstructorCall(
     ConstructorCallNode* node,
     PushArgumentInstr* push_alloc_value) {
-  Value* ctor_arg = Bind(new(Z) ConstantInstr(
-      Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll))));
-  PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg);
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
       new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   arguments->Add(push_alloc_value);
-  arguments->Add(push_ctor_arg);
 
   BuildPushArguments(*node->arguments(), arguments);
   Do(new(Z) StaticCallInstr(node->token_pos(),
@@ -3583,7 +3492,7 @@
         LoadFieldInstr* data_load = new(Z) LoadFieldInstr(
             receiver,
             Array::data_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             node->token_pos());
         data_load->set_result_cid(kArrayCid);
         Value* data = Bind(data_load);
@@ -3611,7 +3520,7 @@
       case MethodRecognizer::kBigint_getDigits: {
         return ReturnDefinition(BuildNativeGetter(
             node, kind, Bigint::digits_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             kTypedDataUint32ArrayCid));
       }
       case MethodRecognizer::kBigint_getUsed: {
@@ -3622,7 +3531,7 @@
       case MethodRecognizer::kLinkedHashMap_getIndex: {
         return ReturnDefinition(BuildNativeGetter(
             node, kind, LinkedHashMap::index_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             kDynamicCid));
       }
       case MethodRecognizer::kLinkedHashMap_setIndex: {
@@ -3632,7 +3541,7 @@
       case MethodRecognizer::kLinkedHashMap_getData: {
         return ReturnDefinition(BuildNativeGetter(
             node, kind, LinkedHashMap::data_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             kArrayCid));
       }
       case MethodRecognizer::kLinkedHashMap_setData: {
@@ -3700,7 +3609,7 @@
 
 
 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
-  Definition* load = BuildLoadLocal(node->local());
+  Definition* load = BuildLoadLocal(node->local(), node->token_pos());
   ReturnDefinition(load);
 }
 
@@ -3718,7 +3627,7 @@
             !node->value()->AsLoadLocalNode()->local().IsInternal()) ||
         node->value()->IsClosureNode()) &&
         !node->local().IsInternal() &&
-        (node->token_pos() != Scanner::kNoSourcePos)) {
+        (node->token_pos() >= 0)) {
       AddInstruction(new(Z) DebugStepCheckInstr(
           node->token_pos(), RawPcDescriptors::kRuntimeCall));
     }
@@ -3734,7 +3643,9 @@
                                        node->local().type(),
                                        node->local().name());
   }
-  Definition* store = BuildStoreLocal(node->local(), store_value);
+  Definition* store = BuildStoreLocal(node->local(),
+                                      store_value,
+                                      node->token_pos());
   ReturnDefinition(store);
 }
 
@@ -3807,22 +3718,26 @@
 
 
 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
+  const intptr_t token_pos = node->token_pos();
   if (node->field().is_const()) {
     ASSERT(node->field().StaticValue() != Object::sentinel().raw());
     ASSERT(node->field().StaticValue() !=
            Object::transition_sentinel().raw());
     Definition* result = new(Z) ConstantInstr(
-        Instance::ZoneHandle(Z, node->field().StaticValue()));
+        Instance::ZoneHandle(Z, node->field().StaticValue()), token_pos);
     return ReturnDefinition(result);
   }
-  Value* field_value = Bind(new(Z) ConstantInstr(node->field()));
-  LoadStaticFieldInstr* load = new(Z) LoadStaticFieldInstr(field_value);
+  Value* field_value = Bind(new(Z) ConstantInstr(node->field(), token_pos));
+  LoadStaticFieldInstr* load =
+      new(Z) LoadStaticFieldInstr(field_value, token_pos);
   ReturnDefinition(load);
 }
 
 
 Definition* EffectGraphVisitor::BuildStoreStaticField(
-  StoreStaticFieldNode* node, bool result_is_needed) {
+    StoreStaticFieldNode* node,
+    bool result_is_needed,
+    intptr_t token_pos) {
   ValueGraphVisitor for_value(owner());
   node->value()->Visit(&for_value);
   Append(for_value);
@@ -3833,7 +3748,7 @@
     store_value = for_value.value();
   }
   StoreStaticFieldInstr* store =
-      new(Z) StoreStaticFieldInstr(node->field(), store_value);
+      new(Z) StoreStaticFieldInstr(node->field(), store_value, token_pos);
 
   if (result_is_needed) {
     Do(store);
@@ -3845,12 +3760,14 @@
 
 
 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
-  ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded));
+  ReturnDefinition(
+      BuildStoreStaticField(node, kResultNotNeeded, node->token_pos()));
 }
 
 
 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
-  ReturnDefinition(BuildStoreStaticField(node, kResultNeeded));
+  ReturnDefinition(
+      BuildStoreStaticField(node, kResultNeeded, node->token_pos()));
 }
 
 
@@ -4026,17 +3943,19 @@
 
 
 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
+  // TODO(johnmccutchan): Pass this in.
+  const intptr_t token_pos = ClassifyingTokenPositions::kContext;
   if (n > 0) {
-    Value* context = Bind(BuildCurrentContext());
+    Value* context = Bind(BuildCurrentContext(token_pos));
     while (n-- > 0) {
       context = Bind(
           new(Z) LoadFieldInstr(context,
                                 Context::parent_offset(),
                                 // Not an instance, no type.
                                 Type::ZoneHandle(Z, Type::null()),
-                                Scanner::kNoSourcePos));
+                                token_pos));
     }
-    Do(BuildStoreContext(context));
+    Do(BuildStoreContext(context, token_pos));
   }
 }
 
@@ -4094,15 +4013,18 @@
         ASSERT(is_top_level_sequence ||
                (nested_block.ContextLevel() ==
                 nested_block.outer()->ContextLevel() + 1));
-        Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
-        Value* parent_context = Bind(BuildCurrentContext());
+        Value* tmp_val = Bind(
+            new(Z) LoadLocalInstr(*tmp_var, node->token_pos()));
+        Value* parent_context = Bind(BuildCurrentContext(node->token_pos()));
         Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(),
                                           tmp_val,
                                           parent_context,
                                           kEmitStoreBarrier,
-                                          Scanner::kNoSourcePos));
+                                          node->token_pos()));
       }
-      Do(BuildStoreContext(Bind(ExitTempLocalScope(tmp_var))));
+      Do(BuildStoreContext(
+          Bind(ExitTempLocalScope(tmp_var)),
+          node->token_pos()));
     }
 
     // If this node_sequence is the body of the function being compiled, copy
@@ -4119,9 +4041,9 @@
           // Create a temporary local describing the original position.
           const String& temp_name = Symbols::TempParam();
           LocalVariable* temp_local = new(Z) LocalVariable(
-              0,  // Token index.
+              Scanner::kNoSourcePos,  // Token index.
               temp_name,
-              Type::ZoneHandle(Z, Type::DynamicType()));  // Type.
+              Object::dynamic_type());  // Type.
           temp_local->set_index(param_frame_index);
 
           // Mark this local as captured parameter so that the optimizer
@@ -4157,9 +4079,10 @@
       const LocalVariable& parameter = *scope->VariableAt(num_params - 1);
       check_pos = parameter.token_pos();
     }
-    if (check_pos == Scanner::kNoSourcePos) {
+    if (check_pos < 0) {
       // No parameters or synthetic parameters.
       check_pos = node->token_pos();
+      ASSERT(check_pos >= 0);
     }
     AddInstruction(new(Z) DebugStepCheckInstr(check_pos,
                                               RawPcDescriptors::kRuntimeCall));
@@ -4173,7 +4096,7 @@
     if (!function.IsImplicitGetterFunction() &&
         !function.IsImplicitSetterFunction()) {
       CheckStackOverflowInstr* check =
-          new(Z) CheckStackOverflowInstr(function.token_pos(), 0);
+          new(Z) CheckStackOverflowInstr(node->token_pos(), 0);
       // If we are inlining don't actually attach the stack check. We must still
       // create the stack check in order to allocate a deopt id.
       if (!owner()->IsInlining()) {
@@ -4185,12 +4108,11 @@
   if (Isolate::Current()->flags().type_checks() && is_top_level_sequence) {
     const int num_params = function.NumParameters();
     int pos = 0;
-    if (function.IsGenerativeConstructor()) {
-      // Skip type checking of receiver and phase for constructor functions.
-      pos = 2;
-    } else if (function.IsFactory() || function.IsDynamicFunction()) {
+    if (function.IsFactory() ||
+        function.IsDynamicFunction() ||
+        function.IsGenerativeConstructor()) {
       // Skip type checking of type arguments for factory functions.
-      // Skip type checking of receiver for instance functions.
+      // Skip type checking of receiver for instance functions and constructors.
       pos = 1;
     }
     while (pos < num_params) {
@@ -4284,7 +4206,7 @@
 
       // Restore the saved continuation context, i.e. the context that was
       // saved into :await_ctx_var before the closure suspended.
-      for_true.BuildRestoreContext(*old_context);
+      for_true.BuildRestoreContext(*old_context, Scanner::kNoSourcePos);
 
       // Goto saved join.
       for_true.Goto((*owner()->await_joins())[i]);
@@ -4326,7 +4248,7 @@
 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
   InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)");
   // Restores current context from local variable ':saved_try_context_var'.
-  BuildRestoreContext(node->context_var());
+  BuildRestoreContext(node->context_var(), node->token_pos());
 
   EffectGraphVisitor for_catch(owner());
   node->VisitChildren(&for_catch);
@@ -4336,13 +4258,13 @@
 
 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
   InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)");
-  intptr_t original_handler_index = owner()->try_index();
+  const intptr_t original_handler_index = owner()->try_index();
   const intptr_t try_handler_index = node->try_index();
   ASSERT(try_handler_index != original_handler_index);
   owner()->set_try_index(try_handler_index);
 
   // Preserve current context into local variable ':saved_try_context_var'.
-  BuildSaveContext(node->context_var());
+  BuildSaveContext(node->context_var(), node->token_pos());
 
   EffectGraphVisitor for_try(owner());
   node->try_block()->Visit(&for_try);
@@ -4408,13 +4330,15 @@
   }
 
   if (finally_block != NULL) {
+    ASSERT(node->rethrow_clause() != NULL);
     // Create a handler for the code in the catch block, containing the
     // code in the finally block.
     owner()->set_try_index(original_handler_index);
     EffectGraphVisitor for_finally(owner());
-    for_finally.BuildRestoreContext(catch_block->context_var());
+    for_finally.BuildRestoreContext(catch_block->context_var(),
+                                    finally_block->token_pos());
 
-    finally_block->Visit(&for_finally);
+    node->rethrow_clause()->Visit(&for_finally);
     if (for_finally.is_open()) {
       // Rethrow the exception.  Manually build the graph for rethrow.
       Value* exception = for_finally.Bind(
@@ -4430,7 +4354,7 @@
     ASSERT(!for_finally.is_open());
 
     const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
-    types.SetAt(0, Type::Handle(Z, Type::DynamicType()));
+    types.SetAt(0, Object::dynamic_type());
     CatchBlockEntryInstr* finally_entry =
         new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(),
                                     original_handler_index,
@@ -4673,7 +4597,7 @@
   // When compiling for OSR, use a depth first search to prune instructions
   // unreachable from the OSR entry. Catch entries are always considered
   // reachable, even if they become unreachable after OSR.
-  if (osr_id_ != Thread::kNoDeoptId) {
+  if (osr_id_ != Compiler::kNoOSRDeoptId) {
     PruneUnreachable();
   }
 
@@ -4684,7 +4608,7 @@
 
 
 void FlowGraphBuilder::PruneUnreachable() {
-  ASSERT(osr_id_ != Thread::kNoDeoptId);
+  ASSERT(osr_id_ != Compiler::kNoOSRDeoptId);
   BitVector* block_marks = new(Z) BitVector(Z, last_used_block_id_ + 1);
   bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_,
                                               block_marks);
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 109a9a1..94c9444 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -28,34 +28,6 @@
 class NestedStatement;
 class TestGraphVisitor;
 
-// List of recognized list factories:
-// (factory-name-symbol, result-cid, fingerprint).
-#define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(_ListFactory, kArrayCid, 850375012)                                        \
-  V(_GrowableListWithData, kGrowableObjectArrayCid, 2094352700)                \
-  V(_GrowableListFactory, kGrowableObjectArrayCid, 1518848600)                 \
-  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.
-class FactoryRecognizer : public AllStatic {
- public:
-  // Return kDynamicCid if factory is not recognized.
-  static intptr_t ResultCid(const Function& factory);
-};
-
-
 // A class to collect the exits from an inlined function during graph
 // construction so they can be plugged into the caller's flow graph.
 class InlineExitCollector: public ZoneAllocated {
@@ -70,6 +42,8 @@
   // Before replacing a call with a graph, the outer environment needs to be
   // attached to each instruction in the callee graph and the caller graph
   // needs to have its block and instruction ID state updated.
+  // Additionally we need to remove all unreachable exits from the list of
+  // collected exits.
   void PrepareGraphs(FlowGraph* callee_graph);
 
   // Inline a graph at a call site.
@@ -106,6 +80,7 @@
 
   static int LowestBlockIdFirst(const Data* a, const Data* b);
   void SortExits();
+  void RemoveUnreachableExits(FlowGraph* callee_graph);
 
   Definition* JoinReturns(BlockEntryInstr** exit_block,
                           Instruction** last_instruction,
@@ -124,7 +99,7 @@
 class FlowGraphBuilder : public ValueObject {
  public:
   // The inlining context is NULL if not inlining.  The osr_id is the deopt
-  // id of the OSR entry or Thread::kNoDeoptId if not compiling for OSR.
+  // id of the OSR entry or Compiler::kNoOSRDeoptId if not compiling for OSR.
   FlowGraphBuilder(const ParsedFunction& parsed_function,
                    const ZoneGrowableArray<const ICData*>& ic_data_array,
                    InlineExitCollector* exit_collector,
@@ -248,7 +223,7 @@
   // A stack of enclosing nested statements.
   NestedStatement* nesting_stack_;
 
-  // The deopt id of the OSR entry or Thread::kNoDeoptId if not compiling
+  // The deopt id of the OSR entry orCompiler::kNoOSRDeoptId if not compiling
   // for OSR.
   const intptr_t osr_id_;
 
@@ -332,8 +307,11 @@
   Definition* BuildStoreExprTemp(Value* value);
   Definition* BuildLoadExprTemp();
 
-  Definition* BuildStoreLocal(const LocalVariable& local, Value* value);
-  Definition* BuildLoadLocal(const LocalVariable& local);
+  Definition* BuildStoreLocal(const LocalVariable& local,
+                              Value* value,
+                              intptr_t token_pos = Scanner::kNoSourcePos);
+  Definition* BuildLoadLocal(const LocalVariable& local,
+                             intptr_t token_pos = Scanner::kNoSourcePos);
   LoadLocalInstr* BuildLoadThisVar(LocalScope* scope);
   LoadFieldInstr* BuildNativeGetter(
       NativeBodyNode* node,
@@ -360,10 +338,8 @@
 
   void BuildTypecheckPushArguments(
       intptr_t token_pos,
-      PushArgumentInstr** push_instantiator,
       PushArgumentInstr** push_instantiator_type_arguments);
   void BuildTypecheckArguments(intptr_t token_pos,
-                               Value** instantiator,
                                Value** instantiator_type_arguments);
   Value* BuildInstantiator(const Class& instantiator_class);
   Value* BuildInstantiatorTypeArguments(intptr_t token_pos,
@@ -420,11 +396,13 @@
   void BuildConstructorCall(ConstructorCallNode* node,
                             PushArgumentInstr* alloc_value);
 
-  void BuildSaveContext(const LocalVariable& variable);
-  void BuildRestoreContext(const LocalVariable& variable);
+  void BuildSaveContext(const LocalVariable& variable,
+                        intptr_t token_pos);
+  void BuildRestoreContext(const LocalVariable& variable,
+                           intptr_t token_pos);
 
-  Definition* BuildStoreContext(Value* value);
-  Definition* BuildCurrentContext();
+  Definition* BuildStoreContext(Value* value, intptr_t token_pos);
+  Definition* BuildCurrentContext(intptr_t token_pos);
 
   void BuildThrowNode(ThrowNode* node);
 
@@ -445,7 +423,8 @@
 
   void BuildStaticSetter(StaticSetterNode* node, bool result_is_needed);
   Definition* BuildStoreStaticField(StoreStaticFieldNode* node,
-                                    bool result_is_needed);
+                                    bool result_is_needed,
+                                    intptr_t token_pos);
 
   void BuildClosureCall(ClosureCallNode* node, bool result_needed);
 
diff --git a/runtime/vm/flow_graph_builder_test.cc b/runtime/vm/flow_graph_builder_test.cc
new file mode 100644
index 0000000..91a13b2
--- /dev/null
+++ b/runtime/vm/flow_graph_builder_test.cc
@@ -0,0 +1,663 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compiler.h"
+#include "vm/dart_api_impl.h"
+#include "vm/dart_entry.h"
+#include "vm/flow_graph_builder.h"
+#include "vm/intermediate_language.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+#define DUMP_ASSERT(condition)                                                 \
+  if (!(condition)) {                                                          \
+    dart::Expect(__FILE__, __LINE__).Fail("expected: %s", #condition);         \
+    THR_Print(">>> BEGIN source position table for `%s`\n", graph_name_);      \
+    Dump();                                                                    \
+    THR_Print("<<< END source position table for `%s`\n", graph_name_);        \
+    OS::Abort();                                                               \
+  }
+
+class SourcePositionTest : public ValueObject {
+ public:
+  SourcePositionTest(Thread* thread,
+                     const char* script)
+      : thread_(thread),
+        isolate_(thread->isolate()),
+        script_(script),
+        root_lib_(Library::Handle()),
+        root_script_(Script::Handle()),
+        graph_(NULL),
+        blocks_(NULL) {
+    EXPECT(thread_ != NULL);
+    EXPECT(isolate_ != NULL);
+    EXPECT(script_ != NULL);
+    Dart_Handle lib = TestCase::LoadTestScript(script, NULL);
+    EXPECT_VALID(lib);
+    root_lib_ ^= Api::UnwrapHandle(lib);
+    EXPECT(!root_lib_.IsNull());
+    root_script_ ^= root_lib_.LookupScript(
+        String::Handle(String::New(USER_TEST_URI)));
+    EXPECT(!root_script_.IsNull());
+  }
+
+  void BuildGraphFor(const char* function_name) {
+    graph_ = NULL;
+    blocks_ = NULL;
+    graph_name_ = NULL;
+
+    // Only support unoptimized code for now.
+    const bool optimized = false;
+
+    const Function& function =
+        Function::Handle(GetFunction(root_lib_, function_name));
+    ZoneGrowableArray<const ICData*>* ic_data_array =
+        new ZoneGrowableArray<const ICData*>();
+    ParsedFunction* parsed_function = new ParsedFunction(
+        thread_, Function::ZoneHandle(function.raw()));
+    Parser::ParseFunction(parsed_function);
+    parsed_function->AllocateVariables();
+    FlowGraphBuilder builder(
+        *parsed_function,
+        *ic_data_array,
+        NULL,
+        Compiler::kNoOSRDeoptId);
+    graph_ = builder.BuildGraph();
+    EXPECT(graph_ != NULL);
+    blocks_ = graph_->CodegenBlockOrder(optimized);
+    EXPECT(blocks_ != NULL);
+    graph_name_ = function_name;
+    EXPECT(graph_name_ != NULL);
+  }
+
+  // Expect to find an instance call at |line| and |column|.
+  void InstanceCallAt(intptr_t line,
+                      intptr_t column = -1,
+                      Token::Kind kind = Token::kNumTokens) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        FindInstructionsAt(line, column);
+    intptr_t count = 0;
+    for (intptr_t i = 0; i < instructions->length(); i++) {
+      Instruction* instr = instructions->At(i);
+      EXPECT(instr != NULL);
+      if (instr->IsInstanceCall()) {
+        if (kind != Token::kNumTokens) {
+          if (instr->AsInstanceCall()->token_kind() == kind) {
+            count++;
+          }
+        } else {
+          count++;
+        }
+      }
+    }
+    DUMP_ASSERT(count > 0);
+  }
+
+  // Expect to find at least one static call at |line| and |column|. The
+  // static call will have |needle| in its |ToCString| representation.
+  void StaticCallAt(const char* needle,
+                    intptr_t line,
+                    intptr_t column = -1) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        FindInstructionsAt(line, column);
+    intptr_t count = 0;
+    for (intptr_t i = 0; i < instructions->length(); i++) {
+      Instruction* instr = instructions->At(i);
+      EXPECT(instr != NULL);
+      if (instr->IsStaticCall()) {
+        const char* haystack = instr->ToCString();
+        if (strstr(haystack, needle) != NULL) {
+          count++;
+        }
+      }
+    }
+    DUMP_ASSERT(count > 0);
+  }
+
+  // Expect that at least one of the instructions found at |line| and |column|
+  // contain |needle| in their |ToCString| representation.
+  void FuzzyInstructionMatchAt(const char* needle,
+                               intptr_t line,
+                               intptr_t column = -1) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        FindInstructionsAt(line, column);
+    intptr_t count = 0;
+    for (intptr_t i = 0; i < instructions->length(); i++) {
+      Instruction* instr = instructions->At(i);
+      const char* haystack = instr->ToCString();
+      if (strstr(haystack, needle) != NULL) {
+        count++;
+      }
+    }
+    DUMP_ASSERT(count > 0);
+  }
+
+  // Utility to dump the instructions with token positions or line numbers.
+  void Dump() {
+    for (intptr_t i = 0; i < blocks_->length(); i++) {
+      BlockEntryInstr* entry = (*blocks_)[i];
+      THR_Print("B%" Pd ":\n", entry->block_id());
+      DumpInstruction(entry);
+      for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+        DumpInstruction(it.Current());
+      }
+    }
+  }
+
+ private:
+  void DumpInstruction(Instruction* instr) {
+    const intptr_t token_pos = instr->token_pos();
+    if (token_pos < 0) {
+      const char* token_pos_string =
+          ClassifyingTokenPositions::ToCString(token_pos);
+      THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString());
+      return;
+    }
+    intptr_t token_line = -1;
+    intptr_t token_column = -1;
+    root_script_.GetTokenLocation(token_pos,
+                                  &token_line,
+                                  &token_column,
+                                  NULL);
+    THR_Print("       %02d:%02d -- %s\n",
+              static_cast<int>(token_line),
+              static_cast<int>(token_column),
+              instr->ToCString());
+  }
+
+  Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        FindInstructionsAt(line, column);
+    if (instructions->length() == 0) {
+      return NULL;
+    }
+    return instructions->At(0);
+  }
+
+  ZoneGrowableArray<Instruction*>* FindInstructionsAt(
+      intptr_t line, intptr_t column) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        new ZoneGrowableArray<Instruction*>();
+    for (intptr_t i = 0; i < blocks_->length(); i++) {
+      BlockEntryInstr* entry = (*blocks_)[i];
+      for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+        Instruction* instr = it.Current();
+        intptr_t token_pos = instr->token_pos();
+        if (token_pos < 0) {
+          continue;
+        }
+        intptr_t token_line = -1;
+        intptr_t token_column = -1;
+        root_script_.GetTokenLocation(token_pos,
+                                      &token_line,
+                                      &token_column,
+                                      NULL);
+        if (token_line == line) {
+          if ((column < 0) || (column == token_column)) {
+            instructions->Add(instr);
+          }
+        }
+      }
+    }
+    return instructions;
+  }
+
+  ZoneGrowableArray<Instruction*>* FindInstructionsAt(intptr_t token_pos) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        new ZoneGrowableArray<Instruction*>();
+    for (intptr_t i = 0; i < blocks_->length(); i++) {
+      BlockEntryInstr* entry = (*blocks_)[i];
+      for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+        Instruction* instr = it.Current();
+        if (instr->token_pos() == token_pos) {
+          instructions->Add(instr);
+        }
+      }
+    }
+    return instructions;
+  }
+
+  RawFunction* GetFunction(const Library& lib, const char* name) {
+    const Function& result = Function::Handle(lib.LookupFunctionAllowPrivate(
+        String::Handle(String::New(name))));
+    EXPECT(!result.IsNull());
+    return result.raw();
+  }
+
+  RawFunction* GetFunction(const Class& cls, const char* name) {
+    const Function& result = Function::Handle(cls.LookupFunctionAllowPrivate(
+        String::Handle(String::New(name))));
+    EXPECT(!result.IsNull());
+    return result.raw();
+  }
+
+  RawClass* GetClass(const Library& lib, const char* name) {
+    const Class& cls = Class::Handle(
+        lib.LookupClass(String::Handle(Symbols::New(name))));
+    EXPECT(!cls.IsNull());  // No ambiguity error expected.
+    return cls.raw();
+  }
+
+  Thread* thread_;
+  Isolate* isolate_;
+  const char* script_;
+  Library& root_lib_;
+  Script& root_script_;
+  const char* graph_name_;
+  FlowGraph* graph_;
+  GrowableArray<BlockEntryInstr*>* blocks_;
+};
+
+
+TEST_CASE(SourcePosition_InstanceCalls) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  var z = x + y;\n"
+      "  return z;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.InstanceCallAt(4, 13, Token::kADD);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 3);
+  spt.FuzzyInstructionMatchAt("Return", 5, 3);
+}
+
+
+TEST_CASE(SourcePosition_If) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  if (x != 0) {\n"
+      "    return x;\n"
+      "  }\n"
+      "  return y;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 7);
+  spt.InstanceCallAt(4, 9, Token::kEQ);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 9);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 12);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 5);
+  spt.FuzzyInstructionMatchAt("Return", 5, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3);
+  spt.FuzzyInstructionMatchAt("Return", 7, 3);
+}
+
+
+TEST_CASE(SourcePosition_ForLoop) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  for (var i = 0; i < 10; i++) {\n"
+      "    x += i;\n"
+      "  }\n"
+      "  return x;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.FuzzyInstructionMatchAt("StoreLocal", 4, 14);
+  spt.FuzzyInstructionMatchAt("LoadLocal", 4, 19);
+  spt.InstanceCallAt(4, 21, Token::kLT);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 21);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 5);
+  spt.FuzzyInstructionMatchAt("StoreStaticField", 5, 5);
+  spt.InstanceCallAt(5, 7, Token::kADD);
+  spt.FuzzyInstructionMatchAt("LoadLocal", 5, 10);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3);
+  spt.FuzzyInstructionMatchAt("Return", 7, 3);
+}
+
+
+TEST_CASE(SourcePosition_While) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  while (x < 10) {\n"
+      "    if (y == 5) {\n"
+      "      return y;\n"
+      "    }\n"
+      "    x++;\n"
+      "  }\n"
+      "  return x;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 4, 3);
+  spt.FuzzyInstructionMatchAt("Constant", 4, 10);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 10);
+  spt.InstanceCallAt(4, 12, Token::kLT);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 12);
+
+  spt.FuzzyInstructionMatchAt("Constant", 5, 9);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 9);
+  spt.InstanceCallAt(5, 11, Token::kEQ);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 5, 11);
+
+  spt.FuzzyInstructionMatchAt("Constant", 6, 14);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 6, 14);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 7);
+  spt.FuzzyInstructionMatchAt("Return", 6, 7);
+
+  spt.FuzzyInstructionMatchAt("Constant", 8, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 8, 5);
+  spt.FuzzyInstructionMatchAt("Constant(#1)", 8, 6);
+  spt.InstanceCallAt(8, 6, Token::kADD);
+  spt.FuzzyInstructionMatchAt("StoreStaticField", 8, 5);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3);
+  spt.FuzzyInstructionMatchAt("Return", 10, 3);
+}
+
+
+TEST_CASE(SourcePosition_WhileContinueBreak) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  while (x < 10) {\n"
+      "    if (y == 5) {\n"
+      "      continue;\n"
+      "    }\n"
+      "    break;\n"
+      "  }\n"
+      "  return x;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 4, 3);
+  spt.FuzzyInstructionMatchAt("Constant(#Field", 4, 10);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 10);
+  spt.FuzzyInstructionMatchAt("Constant(#10", 4, 14);
+  spt.InstanceCallAt(4, 12, Token::kLT);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 12);
+
+  spt.FuzzyInstructionMatchAt("Constant(#Field", 5, 9);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 9);
+  spt.FuzzyInstructionMatchAt("Constant(#5", 5, 14);
+  spt.InstanceCallAt(5, 11, Token::kEQ);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 5, 11);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3);
+  spt.FuzzyInstructionMatchAt("Return", 10, 3);
+}
+
+
+TEST_CASE(SourcePosition_LoadIndexed) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var z = new List(3);\n"
+      "main() {\n"
+      "  z[0];\n"
+      "  var y = z[0] + z[1] + z[2];\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.StaticCallAt("get:z", 4, 3);
+  spt.FuzzyInstructionMatchAt("Constant(#0)", 4, 5);
+  spt.InstanceCallAt(4, 4, Token::kINDEX);
+
+  spt.FuzzyInstructionMatchAt("Constant(#0)", 5, 13);
+  spt.InstanceCallAt(5, 12, Token::kINDEX);
+  spt.FuzzyInstructionMatchAt("Constant(#1)", 5, 20);
+  spt.InstanceCallAt(5, 19, Token::kINDEX);
+
+  spt.InstanceCallAt(5, 16, Token::kADD);
+
+  spt.StaticCallAt("get:z", 5, 25);
+  spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 27);
+  spt.InstanceCallAt(5, 26, Token::kINDEX);
+
+  spt.InstanceCallAt(5, 23, Token::kADD);
+
+  spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1);
+  spt.FuzzyInstructionMatchAt("Return", 6, 1);
+}
+
+
+TEST_CASE(SourcePosition_StoreIndexed) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var z = new List(4);\n"
+      "main() {\n"
+      "  z[0];\n"
+      "  z[3] = z[0] + z[1] + z[2];\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.StaticCallAt("get:z", 4, 3);
+  spt.FuzzyInstructionMatchAt("Constant(#0)", 4, 5);
+  spt.InstanceCallAt(4, 4, Token::kINDEX);
+
+  spt.FuzzyInstructionMatchAt("Constant(#3)", 5, 5);
+
+  spt.StaticCallAt("get:z", 5, 10);
+  spt.FuzzyInstructionMatchAt("Constant(#0)", 5, 12);
+  spt.InstanceCallAt(5, 11, Token::kINDEX);
+
+  spt.InstanceCallAt(5, 15, Token::kADD);
+
+  spt.StaticCallAt("get:z", 5, 17);
+  spt.FuzzyInstructionMatchAt("Constant(#1)", 5, 19);
+  spt.InstanceCallAt(5, 18, Token::kINDEX);
+
+  spt.StaticCallAt("get:z", 5, 24);
+  spt.FuzzyInstructionMatchAt("Constant(#2)", 5, 26);
+  spt.InstanceCallAt(5, 25, Token::kINDEX);
+
+  spt.InstanceCallAt(5, 4, Token::kASSIGN_INDEX);
+
+  spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1);
+  spt.FuzzyInstructionMatchAt("Return", 6, 1);
+}
+
+
+TEST_CASE(SourcePosition_BitwiseOperations) {
+  const char* kScript =
+      "var x = 0;\n"
+      "var y = 1;\n"
+      "main() {\n"
+      "  var z;\n"
+      "  z = x & y;\n"
+      "  z = x | y;\n"
+      "  z = x ^ y;\n"
+      "  z = ~z;\n"
+      "  return z;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 4, 7);
+  spt.FuzzyInstructionMatchAt("Constant(#null", 4, 7);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 4, 7);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 7);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 11);
+  spt.InstanceCallAt(5, 9, Token::kBIT_AND);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 5, 3);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 6, 7);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 6, 11);
+  spt.InstanceCallAt(6, 9, Token::kBIT_OR);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 6, 3);
+
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 7);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 11);
+  spt.InstanceCallAt(7, 9, Token::kBIT_XOR);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 7, 3);
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(z", 8, 8);
+  spt.InstanceCallAt(8, 7, Token::kBIT_NOT);
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 8, 3);
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(z", 9, 10);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3);
+  spt.FuzzyInstructionMatchAt("Return", 9, 3);
+}
+
+
+TEST_CASE(SourcePosition_IfElse) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  if (x != 0) {\n"
+      "    return x;\n"
+      "  } else {\n"
+      "    return y;\n"
+      "  }\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 7);
+  spt.InstanceCallAt(4, 9, Token::kEQ);
+  spt.FuzzyInstructionMatchAt("Branch if StrictCompare", 4, 9);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 5, 12);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 5);
+  spt.FuzzyInstructionMatchAt("Return", 5, 5);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 12);
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 5);
+  spt.FuzzyInstructionMatchAt("Return", 7, 5);
+}
+
+
+TEST_CASE(SourcePosition_Switch) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  switch (x) {\n"
+      "    case 1: return 3;\n"
+      "    case 2: return 4;\n"
+      "    default: return 5;\n"
+      "  }\n"
+      "}\n";
+
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+  spt.FuzzyInstructionMatchAt("Constant(#Field", 4, 11);
+  spt.FuzzyInstructionMatchAt("LoadStaticField", 4, 11);
+  spt.FuzzyInstructionMatchAt("StoreLocal(:switch_expr", 4, 11);
+
+  spt.FuzzyInstructionMatchAt("Constant(#1", 5, 10);
+  spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 5, 5);   // 'c'
+  spt.InstanceCallAt(5, 10, Token::kEQ);                         // '1'
+
+  spt.FuzzyInstructionMatchAt("Constant(#3", 5, 20);             // '3'
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 13);
+  spt.FuzzyInstructionMatchAt("Return", 5, 13);
+
+  spt.FuzzyInstructionMatchAt("Constant(#2", 6, 10);
+  spt.FuzzyInstructionMatchAt("LoadLocal(:switch_expr", 6, 5);   // 'c'
+  spt.InstanceCallAt(6, 10, Token::kEQ);                         // '2'
+
+  spt.FuzzyInstructionMatchAt("Constant(#4", 6, 20);             // '4'
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 13);
+  spt.FuzzyInstructionMatchAt("Return", 6, 13);
+
+  spt.FuzzyInstructionMatchAt("Constant(#5", 7, 21);             // '5'
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 14);
+  spt.FuzzyInstructionMatchAt("Return", 7, 14);
+}
+
+
+TEST_CASE(SourcePosition_TryCatchFinally) {
+  const char* kScript =
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "main() {\n"
+      "  try {\n"
+      "    throw 'A';\n"
+      "  } catch (e) {\n"
+      "    print(e);\n"
+      "    return 77;\n"
+      "  } finally {\n"
+      "    return 99;\n"
+      "  }\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
+  spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(:current_context", 4, 3);     // 't'
+  spt.FuzzyInstructionMatchAt("StoreLocal(:saved_try_context", 4, 3);
+
+  spt.FuzzyInstructionMatchAt("Constant(#A", 5, 11);                   // 'A'
+  spt.FuzzyInstructionMatchAt("Throw", 5, 5);                          // 't'
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 6, 5);   // 'c'
+  spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 6, 5);    // 'c'
+  spt.FuzzyInstructionMatchAt("LoadLocal(:exception_var", 6, 5);       // 'c'
+  spt.FuzzyInstructionMatchAt("StoreLocal(e", 6, 5);                   // 'c'
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(e", 7, 11);                   // 'e'
+
+  spt.FuzzyInstructionMatchAt("StaticCall", 7, 5);                     // 'p'
+
+  spt.FuzzyInstructionMatchAt("Constant(#77", 8, 12);                  // '7'
+  spt.FuzzyInstructionMatchAt("StoreLocal(:finally_ret_val", 8, 5);    // 'r'
+
+  spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12);                 // '9'
+  spt.FuzzyInstructionMatchAt("Return", 10, 5);                        // 'r'
+
+  spt.FuzzyInstructionMatchAt("LoadLocal(:saved_try_context", 9, 13);  // '{'
+  spt.FuzzyInstructionMatchAt("StoreLocal(:current_context", 9, 13);   // '{'
+
+  spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12);                 // '9'
+  spt.FuzzyInstructionMatchAt("Return", 10, 5);                        // 'r'
+}
+
+}  // namespace dart
+
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index dd4adfd..1f02942 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -25,6 +25,7 @@
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
+#include "vm/timeline.h"
 
 namespace dart {
 
@@ -48,6 +49,7 @@
 
 DECLARE_FLAG(bool, background_compilation);
 DECLARE_FLAG(bool, code_comments);
+DECLARE_FLAG(bool, collect_dynamic_function_names);
 DECLARE_FLAG(bool, deoptimize_alot);
 DECLARE_FLAG(int, deoptimize_every);
 DECLARE_FLAG(charp, deoptimize_filter);
@@ -55,7 +57,7 @@
 DECLARE_FLAG(bool, disassemble_optimized);
 DECLARE_FLAG(bool, emit_edge_counters);
 DECLARE_FLAG(bool, fields_may_be_reset);
-DECLARE_FLAG(bool, guess_other_cid);
+DECLARE_FLAG(bool, guess_icdata_cid);
 DECLARE_FLAG(bool, ic_range_profiling);
 DECLARE_FLAG(bool, intrinsify);
 DECLARE_FLAG(bool, load_deferred_eagerly);
@@ -70,18 +72,28 @@
 DECLARE_FLAG(bool, use_cha_deopt);
 DECLARE_FLAG(bool, use_osr);
 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
-DECLARE_FLAG(bool, precompile_collect_closures);
 DECLARE_FLAG(bool, print_stop_message);
 DECLARE_FLAG(bool, lazy_dispatchers);
 DECLARE_FLAG(bool, interpret_irregexp);
 DECLARE_FLAG(bool, enable_mirrors);
 DECLARE_FLAG(bool, link_natives_lazily);
+DECLARE_FLAG(bool, trace_compiler);
+DECLARE_FLAG(int, inlining_hotness);
+DECLARE_FLAG(int, inlining_size_threshold);
+DECLARE_FLAG(int, inlining_callee_size_threshold);
+DECLARE_FLAG(int, inline_getters_setters_smaller_than);
+DECLARE_FLAG(int, inlining_depth_threshold);
+DECLARE_FLAG(int, inlining_caller_size_threshold);
+DECLARE_FLAG(int, inlining_constant_arguments_max_size_threshold);
+DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold);
 
+bool FLAG_precompilation = false;
 static void PrecompilationModeHandler(bool value) {
   if (value) {
 #if defined(TARGET_ARCH_IA32)
     FATAL("Precompilation not supported on IA32");
 #endif
+    FLAG_precompilation = true;
 
     FLAG_always_megamorphic_calls = true;
     FLAG_polymorphic_with_deopt = false;
@@ -95,14 +107,13 @@
     FLAG_load_deferred_eagerly = true;
     FLAG_deoptimize_alot = false;  // Used in some tests.
     FLAG_deoptimize_every = 0;     // Used in some tests.
-    FLAG_guess_other_cid = true;
     Compiler::set_always_optimize(true);
     // Triggers assert if we try to recompile (e.g., because of deferred
     // loading, deoptimization, ...). Noopt mode simulates behavior
     // of precompiled code, therefore do not allow recompilation.
     Compiler::set_allow_recompilation(false);
-    // TODO(srdjan): Enable CHA deoptimization when eager class finalization is
-    // implemented, either with precompilation or as a special pass.
+    // Precompilation finalizes all classes and thus allows CHA optimizations.
+    // Do not require CHA triggered deoptimization.
     FLAG_use_cha_deopt = false;
     // Calling the PrintStopMessage stub is not supported in precompiled code
     // since it is done at places where no pool pointer is loaded.
@@ -111,14 +122,28 @@
     FLAG_lazy_dispatchers = false;
     FLAG_interpret_irregexp = true;
     FLAG_enable_mirrors = false;
-    FLAG_precompile_collect_closures = true;
     FLAG_link_natives_lazily = true;
     FLAG_fields_may_be_reset = true;
     FLAG_allow_absolute_addresses = false;
 
+    // There is no counter feedback in precompilation, so ignore the counter
+    // when making inlining decisions.
+    FLAG_inlining_hotness = 0;
+    // Use smaller thresholds in precompilation as we are compiling everything
+    // with the optimizing compiler instead of only hot functions.
+    FLAG_inlining_size_threshold = 5;
+    FLAG_inline_getters_setters_smaller_than = 5;
+    FLAG_inlining_callee_size_threshold = 20;
+    FLAG_inlining_depth_threshold = 2;
+    FLAG_inlining_caller_size_threshold = 1000;
+
+    FLAG_inlining_constant_arguments_max_size_threshold = 100;
+    FLAG_inlining_constant_arguments_min_size_threshold = 30;
+
     // Background compilation relies on two-stage compilation pipeline,
     // while precompilation has only one.
     FLAG_background_compilation = false;
+    FLAG_collect_dynamic_function_names = true;
   }
 }
 
@@ -166,7 +191,6 @@
     const GrowableArray<const Function*>& inline_id_to_function,
     const GrowableArray<intptr_t>& caller_inline_id)
       : thread_(Thread::Current()),
-        isolate_(Isolate::Current()),
         zone_(Thread::Current()->zone()),
         assembler_(assembler),
         parsed_function_(parsed_function),
@@ -183,15 +207,15 @@
         may_reoptimize_(false),
         intrinsic_mode_(false),
         double_class_(Class::ZoneHandle(
-            isolate_->object_store()->double_class())),
+            isolate()->object_store()->double_class())),
         mint_class_(Class::ZoneHandle(
-            isolate_->object_store()->mint_class())),
+            isolate()->object_store()->mint_class())),
         float32x4_class_(Class::ZoneHandle(
-            isolate_->object_store()->float32x4_class())),
+            isolate()->object_store()->float32x4_class())),
         float64x2_class_(Class::ZoneHandle(
-            isolate_->object_store()->float64x2_class())),
+            isolate()->object_store()->float64x2_class())),
         int32x4_class_(Class::ZoneHandle(
-            isolate_->object_store()->int32x4_class())),
+            isolate()->object_store()->int32x4_class())),
         list_class_(Class::ZoneHandle(
             Library::Handle(Library::CoreLibrary()).
                 LookupClass(Symbols::List()))),
@@ -228,9 +252,33 @@
 }
 
 
+bool FlowGraphCompiler::IsUnboxedField(const Field& field) {
+  bool valid_class = (SupportsUnboxedDoubles() &&
+                      (field.guarded_cid() == kDoubleCid)) ||
+                     (SupportsUnboxedSimd128() &&
+                      (field.guarded_cid() == kFloat32x4Cid)) ||
+                     (SupportsUnboxedSimd128() &&
+                      (field.guarded_cid() == kFloat64x2Cid));
+  return field.is_unboxing_candidate()
+      && !field.is_final()
+      && !field.is_nullable()
+      && valid_class;
+}
+
+
+bool FlowGraphCompiler::IsPotentialUnboxedField(const Field& field) {
+  return field.is_unboxing_candidate() &&
+         (FlowGraphCompiler::IsUnboxedField(field) ||
+          (!field.is_final() && (field.guarded_cid() == kIllegalCid)));
+}
+
+
 void FlowGraphCompiler::InitCompiler() {
+  TimelineDurationScope tds(thread(),
+                            isolate()->GetCompilerStream(),
+                            "InitCompiler");
   pc_descriptors_list_ = new(zone()) DescriptorList(64);
-  exception_handlers_list_ = new(zone())ExceptionHandlerList();
+  exception_handlers_list_ = new(zone()) ExceptionHandlerList();
   block_info_.Clear();
   // Conservative detection of leaf routines used to remove the stack check
   // on function entry.
@@ -401,7 +449,7 @@
 
 
 void FlowGraphCompiler::EmitSourceLine(Instruction* instr) {
-  if ((instr->token_pos() == Scanner::kNoSourcePos) || (instr->env() == NULL)) {
+  if ((instr->token_pos() < 0) || (instr->env() == NULL)) {
     return;
   }
   const Script& script =
@@ -525,11 +573,6 @@
 #endif
   }
 
-  if (inline_id_to_function_.length() > max_inlining_id + 1) {
-    // TODO(srdjan): Some inlined function can disappear,
-    // truncate 'inline_id_to_function_'.
-  }
-
   if (is_optimizing()) {
     LogBlock lb;
     intervals.Add(IntervalStruct(prev_offset, prev_inlining_id));
@@ -896,7 +939,17 @@
   }
 
   // No deoptimization allowed when 'always_optimize' is set.
-  ASSERT(!Compiler::always_optimize());
+  if (Compiler::always_optimize()) {
+    if (FLAG_trace_compiler) {
+      THR_Print(
+          "Retrying compilation %s, suppressing inlining of deopt_id:%" Pd "\n",
+          parsed_function_.function().ToFullyQualifiedCString(), deopt_id);
+    }
+    ASSERT(deopt_id != 0);  // longjmp must return non-zero value.
+    Thread::Current()->long_jump_base()->Jump(
+        deopt_id, Object::speculative_inlining_error());
+  }
+
   ASSERT(is_optimizing_);
   CompilerDeoptInfoWithStub* stub =
       new(zone()) CompilerDeoptInfoWithStub(deopt_id,
@@ -1089,7 +1142,13 @@
     intptr_t token_pos,
     intptr_t argument_count,
     LocationSummary* locs,
-    const ICData& ic_data) {
+    const ICData& ic_data_in) {
+  const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original());
+  if (Compiler::always_optimize()) {
+    EmitSwitchableInstanceCall(ic_data, argument_count,
+                               deopt_id, token_pos, locs);
+    return;
+  }
   if (FLAG_always_megamorphic_calls) {
     EmitMegamorphicInstanceCall(ic_data, argument_count,
                                 deopt_id, token_pos, locs);
@@ -1099,9 +1158,7 @@
   if (is_optimizing() && (ic_data.NumberOfUsedChecks() == 0)) {
     // Emit IC call that will count and thus may need reoptimization at
     // function entry.
-    ASSERT(!is_optimizing()
-           || may_reoptimize()
-           || flow_graph().IsCompiledForOsr());
+    ASSERT(may_reoptimize() || flow_graph().IsCompiledForOsr());
     switch (ic_data.NumArgsTested()) {
       case 1:
         EmitOptimizedInstanceCall(
@@ -1153,7 +1210,8 @@
                                            intptr_t argument_count,
                                            const Array& argument_names,
                                            LocationSummary* locs,
-                                           const ICData& ic_data) {
+                                           const ICData& ic_data_in) {
+  const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original());
   const Array& arguments_descriptor = Array::ZoneHandle(
       ic_data.IsNull() ? ArgumentsDescriptor::New(argument_count,
                                                   argument_names)
@@ -1262,16 +1320,6 @@
 }
 
 
-// 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());
 
@@ -1281,16 +1329,10 @@
 
   bool blocked_registers[kNumberOfCpuRegisters];
 
-  // Mark all available registers free.
+  // Block all registers globally reserved by the assembler, etc and mark
+  // the rest as free.
   for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
-    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;
-    }
+    blocked_registers[i] = (kDartAvailableCpuRegs & (1 << i)) == 0;
   }
 
   // Mark all fixed input, temp and output registers as used.
@@ -1318,14 +1360,6 @@
     blocked_registers[locs->out(0).reg()] = true;
   }
 
-  // Block all non-free registers.
-  for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) {
-    blocked_registers[i] = true;
-  }
-  for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) {
-    blocked_registers[i] = true;
-  }
-
   // Allocate all unallocated input locations.
   const bool should_pop = !instr->IsPushArgument() && !instr->IsPushTemp();
   for (intptr_t i = locs->input_count() - 1; i >= 0; i--) {
@@ -1580,12 +1614,17 @@
   if (resolver->compiler_->intrinsic_mode()) {
     // Block additional registers that must be preserved for intrinsics.
     blocked_mask |= RegMaskBit(ARGS_DESC_REG);
+#if !defined(TARGET_ARCH_IA32)
+    // Need to preserve CODE_REG to be able to store the PC marker
+    // and load the pool pointer.
+    blocked_mask |= RegMaskBit(CODE_REG);
+#endif
   }
   reg_ = static_cast<Register>(
       resolver_->AllocateScratchRegister(Location::kRegister,
                                          blocked_mask,
-                                         kFirstFreeCpuRegister,
-                                         kLastFreeCpuRegister,
+                                         0,
+                                         kNumberOfCpuRegisters - 1,
                                          &spilled_));
 
   if (spilled_) {
@@ -1759,16 +1798,17 @@
   } else {
     // Instead of deoptimizing, do a megamorphic call when no matching
     // cid found.
-    Label megamorphic, ok;
+    Label ok;
+    MegamorphicSlowPath* slow_path =
+        new MegamorphicSlowPath(ic_data, argument_count, deopt_id,
+                                token_pos, locs, CurrentTryIndex());
+    AddSlowPathCode(slow_path);
     EmitTestAndCall(ic_data, argument_count, argument_names,
-                    &megamorphic,  // No cid match.
-                    &ok,           // Found cid.
+                    slow_path->entry_label(),  // No cid match.
+                    &ok,                       // Found cid.
                     deopt_id, token_pos, locs);
-    // Fall through if last test is match.
-    assembler()->Jump(&ok);
-    assembler()->Bind(&megamorphic);
-    EmitMegamorphicInstanceCall(ic_data, argument_count, deopt_id,
-                                token_pos, locs);
+
+    assembler()->Bind(slow_path->exit_label());
     assembler()->Bind(&ok);
   }
 }
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index df9f7e4..b6d4c4c 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -214,6 +214,37 @@
 };
 
 
+class MegamorphicSlowPath : public SlowPathCode {
+ public:
+  MegamorphicSlowPath(const ICData& ic_data,
+                      intptr_t argument_count,
+                      intptr_t deopt_id,
+                      intptr_t token_pos,
+                      LocationSummary* locs,
+                      intptr_t try_index)
+    : SlowPathCode(),
+      ic_data_(ic_data),
+      argument_count_(argument_count),
+      deopt_id_(deopt_id),
+      token_pos_(token_pos),
+      locs_(locs),
+      try_index_(try_index) {}
+  virtual ~MegamorphicSlowPath() {}
+
+ private:
+  virtual void EmitNativeCode(FlowGraphCompiler* comp);
+
+  const ICData& ic_data_;
+  intptr_t argument_count_;
+  intptr_t deopt_id_;
+  intptr_t token_pos_;
+  LocationSummary* locs_;
+  const intptr_t try_index_;  // For try/catch ranges.
+
+  DISALLOW_COPY_AND_ASSIGN(MegamorphicSlowPath);
+};
+
+
 struct CidTarget {
   intptr_t cid;
   Function* target;
@@ -281,6 +312,9 @@
   static bool SupportsUnboxedSimd128();
   static bool SupportsHardwareDivision();
 
+  static bool IsUnboxedField(const Field& field);
+  static bool IsPotentialUnboxedField(const Field& field);
+
   // Accessors.
   Assembler* assembler() const { return assembler_; }
   const ParsedFunction& parsed_function() const { return parsed_function_; }
@@ -411,11 +445,20 @@
                                    intptr_t token_pos,
                                    LocationSummary* locs);
 
-  void EmitMegamorphicInstanceCall(const ICData& ic_data,
-                                   intptr_t argument_count,
-                                   intptr_t deopt_id,
-                                   intptr_t token_pos,
-                                   LocationSummary* locs);
+  // Pass a value for try-index where block is not available (e.g. slow path).
+  void EmitMegamorphicInstanceCall(
+      const ICData& ic_data,
+      intptr_t argument_count,
+      intptr_t deopt_id,
+      intptr_t token_pos,
+      LocationSummary* locs,
+      intptr_t try_index = CatchClauseNode::kInvalidTryIndex);
+
+  void EmitSwitchableInstanceCall(const ICData& ic_data,
+                                  intptr_t argument_count,
+                                  intptr_t deopt_id,
+                                  intptr_t token_pos,
+                                  LocationSummary* locs);
 
   void EmitTestAndCall(const ICData& ic_data,
                        intptr_t arg_count,
@@ -526,7 +569,7 @@
   }
 
   Thread* thread() const { return thread_; }
-  Isolate* isolate() const { return isolate_; }
+  Isolate* isolate() const { return thread_->isolate(); }
   Zone* zone() const { return zone_; }
 
   void AddStubCallTarget(const Code& code);
@@ -683,7 +726,6 @@
   };
 
   Thread* thread_;
-  Isolate* isolate_;
   Zone* zone_;
   Assembler* assembler_;
   const ParsedFunction& parsed_function_;
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 444a0d8..abd8b65 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -31,6 +31,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ b(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -175,8 +187,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -191,7 +203,7 @@
   __ Push(CODE_REG);
   __ mov(IP, Operand(LR));
   __ BranchLink(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
 #undef __
 }
 
@@ -263,12 +275,11 @@
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
   ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
   const Register kInstanceReg = R0;
-  Error& malformed_error = Error::Handle(zone());
+  Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
-  const bool smi_is_ok =
-      int_type.IsSubtypeOf(type, &malformed_error, Heap::kOld);
+  const bool smi_is_ok = int_type.IsSubtypeOf(type, &bound_error, Heap::kOld);
   // Malformed type should have been handled at graph construction time.
-  ASSERT(smi_is_ok || malformed_error.IsNull());
+  ASSERT(smi_is_ok || bound_error.IsNull());
   __ tst(kInstanceReg, Operand(kSmiTagMask));
   if (smi_is_ok) {
     __ b(is_instance_lbl, EQ);
@@ -407,7 +418,7 @@
 
 // Uses SubtypeTestCache to store instance class and result.
 // R0: instance to test.
-// Clobbers R1-R5.
+// Clobbers R1-R4,R9.
 // Immediate class test already done.
 // TODO(srdjan): Implement a quicker subtype check, as type test
 // arrays can grow too high, but they may be useful when optimizing
@@ -450,7 +461,7 @@
   // Skip check if destination is a dynamic type.
   if (type.IsTypeParameter()) {
     const TypeParameter& type_param = TypeParameter::Cast(type);
-    // Load instantiator (or null) and instantiator type arguments on stack.
+    // Load instantiator type arguments on stack.
     __ ldr(R1, Address(SP, 0));  // Get instantiator type arguments.
     // R1: instantiator type arguments.
     // Check if type arguments are null, i.e. equivalent to vector of dynamic.
@@ -460,7 +471,7 @@
         FieldAddress(R1, TypeArguments::type_at_offset(type_param.index())));
     // R2: concrete type of type.
     // Check if type argument is dynamic.
-    __ CompareObject(R2, Type::ZoneHandle(zone(), Type::DynamicType()));
+    __ CompareObject(R2, Object::dynamic_type());
     __ b(is_instance_lbl, EQ);
     __ CompareObject(R2, Type::ZoneHandle(zone(), Type::ObjectType()));
     __ b(is_instance_lbl, EQ);
@@ -575,7 +586,6 @@
 // Inputs:
 // - R0: object.
 // - R1: instantiator type arguments or raw_null.
-// - R2: instantiator or raw_null.
 // Returns:
 // - true or false in R0.
 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
@@ -585,8 +595,8 @@
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
 
-  // Preserve instantiator (R2) and its type arguments (R1).
-  __ PushList((1 << R1) | (1 << R2));
+  // Preserve instantiator type arguments (R1).
+  __ Push(R1);
 
   Label is_instance, is_not_instance;
   // If type is instantiated and non-parameterized, we can inline code
@@ -612,19 +622,18 @@
   Label done;
   if (!test_cache.IsNull()) {
     // Generate runtime call.
-    // Load instantiator (R2) and its type arguments (R1).
-    __ ldm(IA, SP,  (1 << R1) | (1 << R2));
+    // Load instantiator type arguments (R1).
+    __ ldr(R1, Address(SP, 0 * kWordSize));
     __ PushObject(Object::null_object());  // Make room for the result.
     __ Push(R0);  // Push the instance.
     __ PushObject(type);  // Push the type.
-    // Push instantiator (R2) and its type arguments (R1).
-    __ PushList((1 << R1) | (1 << R2));
+    __ Push(R1);  // Push instantiator type arguments (R1).
     __ LoadUniqueObject(R0, test_cache);
     __ Push(R0);
-    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
+    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 4, locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
-    __ Drop(5);
+    __ Drop(4);
     if (negate_result) {
       __ Pop(R1);
       __ LoadObject(R0, Bool::True());
@@ -643,8 +652,8 @@
   __ Bind(&is_instance);
   __ LoadObject(R0, Bool::Get(!negate_result));
   __ Bind(&done);
-  // Remove instantiator (R2) and its type arguments (R1).
-  __ Drop(2);
+  // Remove instantiator type arguments (R1).
+  __ Drop(1);
 }
 
 
@@ -655,7 +664,6 @@
 // Inputs:
 // - R0: instance being type checked.
 // - R1: instantiator type arguments or raw_null.
-// - R2: instantiator or raw_null.
 // Returns:
 // - object in R0 for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
@@ -665,14 +673,14 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
   ASSERT(dst_type.IsMalformedOrMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
-  // Preserve instantiator (R2) and its type arguments (R1).
-  __ PushList((1 << R1) | (1 << R2));
+  // Preserve instantiator type arguments (R1).
+  __ Push(R1);
   // A null object is always assignable and is returned as result.
   Label is_assignable, runtime_call;
   __ CompareObject(R0, Object::null_object());
@@ -693,8 +701,8 @@
     __ bkpt(0);
 
     __ Bind(&is_assignable);  // For a null object.
-    // Restore instantiator (R2) and its type arguments (R1).
-    __ PopList((1 << R1) | (1 << R2));
+    // Restore instantiator type arguments (R1).
+    __ Pop(R1);
     return;
   }
 
@@ -704,25 +712,24 @@
                                         &is_assignable, &runtime_call);
 
   __ Bind(&runtime_call);
-  // Load instantiator (R2) and its type arguments (R1).
-  __ ldm(IA, SP,  (1 << R1) | (1 << R2));
+  // Load instantiator type arguments (R1).
+  __ ldr(R1, Address(SP, 0 * kWordSize));
   __ PushObject(Object::null_object());  // Make room for the result.
   __ Push(R0);  // Push the source object.
   __ PushObject(dst_type);  // Push the type of the destination.
-  // Push instantiator (R2) and its type arguments (R1).
-  __ PushList((1 << R1) | (1 << R2));
+  __ Push(R1);  // Push instantiator type arguments (R1).
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadUniqueObject(R0, test_cache);
   __ Push(R0);
-  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 5, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
-  __ Drop(6);
+  __ Drop(5);
   __ Pop(R0);
 
   __ Bind(&is_assignable);
-  // Restore instantiator (R2) and its type arguments (R1).
-  __ PopList((1 << R1) | (1 << R2));
+  // Restore instantiator type arguments (R1).
+  __ Pop(R1);
 }
 
 
@@ -756,44 +763,44 @@
   const int min_num_pos_args = num_fixed_params;
   const int max_num_pos_args = num_fixed_params + num_opt_pos_params;
 
-  __ ldr(R10, FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
+  __ ldr(R6, FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
   // Check that min_num_pos_args <= num_pos_args.
   Label wrong_num_arguments;
-  __ CompareImmediate(R10, Smi::RawValue(min_num_pos_args));
+  __ CompareImmediate(R6, Smi::RawValue(min_num_pos_args));
   __ b(&wrong_num_arguments, LT);
   // Check that num_pos_args <= max_num_pos_args.
-  __ CompareImmediate(R10, Smi::RawValue(max_num_pos_args));
+  __ CompareImmediate(R6, Smi::RawValue(max_num_pos_args));
   __ b(&wrong_num_arguments, GT);
 
   // Copy positional arguments.
   // Argument i passed at fp[kParamEndSlotFromFp + num_args - i] is copied
   // to fp[kFirstLocalSlotFromFp - i].
 
-  __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  // Since R7 and R10 are Smi, use LSL 1 instead of LSL 2.
-  // Let R7 point to the last passed positional argument, i.e. to
+  __ ldr(NOTFP, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+  // Since NOTFP and R6 are Smi, use LSL 1 instead of LSL 2.
+  // Let NOTFP point to the last passed positional argument, i.e. to
   // fp[kParamEndSlotFromFp + num_args - (num_pos_args - 1)].
-  __ sub(R7, R7, Operand(R10));
-  __ add(R7, FP, Operand(R7, LSL, 1));
-  __ add(R7, R7, Operand((kParamEndSlotFromFp + 1) * kWordSize));
+  __ sub(NOTFP, NOTFP, Operand(R6));
+  __ add(NOTFP, FP, Operand(NOTFP, LSL, 1));
+  __ add(NOTFP, NOTFP, Operand((kParamEndSlotFromFp + 1) * kWordSize));
 
-  // Let R6 point to the last copied positional argument, i.e. to
+  // Let R8 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(R10, LSL, 1));  // R10 is a Smi.
-  __ SmiUntag(R10);
+  __ AddImmediate(R8, FP, (kFirstLocalSlotFromFp + 1) * kWordSize);
+  __ sub(R8, R8, Operand(R6, LSL, 1));  // R6 is a Smi.
+  __ SmiUntag(R6);
   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, R10, LSL, 2);
-  const Address copy_addr(R6, R10, LSL, 2);
+  const Address argument_addr(NOTFP, R6, LSL, 2);
+  const Address copy_addr(R8, R6, LSL, 2);
   __ Bind(&loop);
   __ ldr(IP, argument_addr);
   __ str(IP, copy_addr);
   __ Bind(&loop_condition);
-  __ subs(R10, R10, Operand(1));
+  __ subs(R6, R6, Operand(1));
   __ b(&loop, PL);
 
   // Copy or initialize optional named arguments.
@@ -823,89 +830,89 @@
       opt_param_position[i + 1] = pos;
     }
     // Generate code handling each optional parameter in alphabetical order.
-    __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-    __ ldr(R10,
+    __ ldr(NOTFP, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+    __ ldr(R6,
            FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
-    __ SmiUntag(R10);
-    // 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));
-    __ AddImmediate(R7, R7, kParamEndSlotFromFp * kWordSize);
-    // Let R6 point to the entry of the first named argument.
-    __ add(R6, R4, Operand(
+    __ SmiUntag(R6);
+    // Let NOTFP point to the first passed argument, i.e. to
+    // fp[kParamEndSlotFromFp + num_args - 0]; num_args (NOTFP) is Smi.
+    __ add(NOTFP, FP, Operand(NOTFP, LSL, 1));
+    __ AddImmediate(NOTFP, NOTFP, kParamEndSlotFromFp * kWordSize);
+    // Let R8 point to the entry of the first named argument.
+    __ add(R8, R4, Operand(
         ArgumentsDescriptor::first_named_entry_offset() - kHeapObjectTag));
     for (int i = 0; i < num_opt_named_params; i++) {
       Label load_default_value, assign_optional_parameter;
       const int param_pos = opt_param_position[i];
       // Check if this named parameter was passed in.
-      // Load R5 with the name of the argument.
-      __ ldr(R5, Address(R6, ArgumentsDescriptor::name_offset()));
+      // Load R9 with the name of the argument.
+      __ ldr(R9, Address(R8, ArgumentsDescriptor::name_offset()));
       ASSERT(opt_param[i]->name().IsSymbol());
-      __ CompareObject(R5, opt_param[i]->name());
+      __ CompareObject(R9, opt_param[i]->name());
       __ b(&load_default_value, NE);
-      // Load R5 with passed-in argument at provided arg_pos, i.e. at
+      // Load R9 with passed-in argument at provided arg_pos, i.e. at
       // fp[kParamEndSlotFromFp + num_args - arg_pos].
-      __ ldr(R5, Address(R6, ArgumentsDescriptor::position_offset()));
-      // R5 is arg_pos as Smi.
+      __ ldr(R9, Address(R8, ArgumentsDescriptor::position_offset()));
+      // R9 is arg_pos as Smi.
       // Point to next named entry.
-      __ add(R6, R6, Operand(ArgumentsDescriptor::named_entry_size()));
-      __ rsb(R5, R5, Operand(0));
-      Address argument_addr(R7, R5, LSL, 1);  // R5 is a negative Smi.
-      __ ldr(R5, argument_addr);
+      __ add(R8, R8, Operand(ArgumentsDescriptor::named_entry_size()));
+      __ rsb(R9, R9, Operand(0));
+      Address argument_addr(NOTFP, R9, LSL, 1);  // R9 is a negative Smi.
+      __ ldr(R9, argument_addr);
       __ b(&assign_optional_parameter);
       __ Bind(&load_default_value);
-      // Load R5 with default argument.
+      // Load R9 with default argument.
       const Instance& value = parsed_function().DefaultParameterValueAt(
           param_pos - num_fixed_params);
-      __ LoadObject(R5, value);
+      __ LoadObject(R9, value);
       __ Bind(&assign_optional_parameter);
-      // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
+      // Assign R9 to fp[kFirstLocalSlotFromFp - param_pos].
       // 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 intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
       const Address param_addr(FP, computed_param_pos * kWordSize);
-      __ str(R5, param_addr);
+      __ str(R9, param_addr);
     }
     delete[] opt_param;
     delete[] opt_param_position;
     if (check_correct_named_args) {
-      // Check that R6 now points to the null terminator in the arguments
+      // Check that R8 now points to the null terminator in the arguments
       // descriptor.
-      __ ldr(R5, Address(R6, 0));
-      __ CompareObject(R5, Object::null_object());
+      __ ldr(R9, Address(R8, 0));
+      __ CompareObject(R9, Object::null_object());
       __ b(&all_arguments_processed, EQ);
     }
   } else {
     ASSERT(num_opt_pos_params > 0);
-    __ ldr(R10,
+    __ ldr(R6,
            FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
-    __ SmiUntag(R10);
+    __ SmiUntag(R6);
     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(R10, param_pos);
+      __ CompareImmediate(R6, param_pos);
       __ b(&next_parameter, GT);
-      // Load R5 with default argument.
+      // Load R9 with default argument.
       const Object& value = parsed_function().DefaultParameterValueAt(i);
-      __ LoadObject(R5, value);
-      // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
+      __ LoadObject(R9, value);
+      // Assign R9 to fp[kFirstLocalSlotFromFp - param_pos].
       // 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 intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
       const Address param_addr(FP, computed_param_pos * kWordSize);
-      __ str(R5, param_addr);
+      __ str(R9, param_addr);
       __ Bind(&next_parameter);
     }
     if (check_correct_named_args) {
-      __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-      __ SmiUntag(R7);
-      // Check that R10 equals R7, i.e. no named arguments passed.
-      __ cmp(R10, Operand(R7));
+      __ ldr(NOTFP, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+      __ SmiUntag(NOTFP);
+      // Check that R6 equals NOTFP, i.e. no named arguments passed.
+      __ cmp(R6, Operand(NOTFP));
       __ b(&all_arguments_processed, EQ);
     }
   }
@@ -927,17 +934,17 @@
   // an issue anymore.
 
   // R4 : arguments descriptor array.
-  __ ldr(R10, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R10);
-  __ add(R7, FP, Operand((kParamEndSlotFromFp + 1) * kWordSize));
-  const Address original_argument_addr(R7, R10, LSL, 2);
+  __ ldr(R6, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+  __ SmiUntag(R6);
+  __ add(NOTFP, FP, Operand((kParamEndSlotFromFp + 1) * kWordSize));
+  const Address original_argument_addr(NOTFP, R6, LSL, 2);
   __ LoadObject(IP, Object::null_object());
   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(R10, R10, Operand(1));
+  __ subs(R6, R6, Operand(1));
   __ b(&null_args_loop, PL);
 }
 
@@ -948,7 +955,7 @@
   // Sequence node has one return node, its input is load field node.
   __ Comment("Inlined Getter");
   __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadFromOffset(kWord, R0, R0, offset - kHeapObjectTag);
+  __ LoadFieldFromOffset(kWord, R0, R0, offset);
   __ Ret();
 }
 
@@ -967,7 +974,7 @@
 }
 
 
-static const Register new_pp = R7;
+static const Register new_pp = NOTFP;
 
 
 void FlowGraphCompiler::EmitFrameEntry() {
@@ -975,8 +982,8 @@
   if (CanOptimizeFunction() &&
       function.IsOptimizable() &&
       (!is_optimizing() || may_reoptimize())) {
-    const Register function_reg = R6;
-
+    __ Comment("Invocation Count Check");
+    const Register function_reg = R8;
     // The pool pointer is not setup before entering the Dart frame.
     // Temporarily setup pool pointer for this dart function.
     __ LoadPoolPointer(new_pp);
@@ -993,7 +1000,7 @@
                               Function::usage_counter_offset()));
     }
     __ CompareImmediate(R3, GetOptimizationThreshold());
-    ASSERT(function_reg == R6);
+    ASSERT(function_reg == R8);
     __ Branch(*StubCode::OptimizeFunction_entry(), kNotPatchable, new_pp, GE);
   }
   __ Comment("Enter frame");
@@ -1015,7 +1022,7 @@
 //   SP: address of last argument.
 //   FP: caller's frame pointer.
 //   PP: caller's pool pointer.
-//   R5: ic-data.
+//   R9: ic-data.
 //   R4: arguments descriptor array.
 void FlowGraphCompiler::CompileGraph() {
   InitCompiler();
@@ -1225,8 +1232,8 @@
   // reoptimized and which counter needs to be incremented.
   // Pass the function explicitly, it is used in IC stub.
 
-  __ LoadObject(R6, parsed_function().function());
-  __ LoadUniqueObject(R5, ic_data);
+  __ LoadObject(R8, parsed_function().function());
+  __ LoadUniqueObject(R9, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
                    stub_entry,
@@ -1243,7 +1250,7 @@
                                          intptr_t token_pos,
                                          LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
-  __ LoadUniqueObject(R5, ic_data);
+  __ LoadUniqueObject(R9, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
                    stub_entry,
@@ -1258,27 +1265,79 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  const Register receiverR = R0;
-  const Register cacheR = R1;
-  const Register targetR = R1;
-  __ LoadFromOffset(kWord, receiverR, SP, (argument_count - 1) * kWordSize);
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
+  __ LoadObject(R9, cache);
   if (FLAG_use_megamorphic_stub) {
     __ BranchLink(*StubCode::MegamorphicLookup_entry());
-  } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+  } else {
+    StubCode::EmitMegamorphicLookup(assembler());
   }
-  __ LoadObject(R5, ic_data);
-  __ LoadObject(R4, arguments_descriptor);
-  __ blx(targetR);
+  __ blx(R1);
+
+  RecordSafepoint(locs);
+  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  if (Compiler::always_optimize()) {
+    // Megamorphic calls may occur in slow path stubs.
+    // If valid use try_index argument.
+    if (try_index == CatchClauseNode::kInvalidTryIndex) {
+      try_index = CurrentTryIndex();
+    }
+    pc_descriptors_list()->AddDescriptor(RawPcDescriptors::kOther,
+                                         assembler()->CodeSize(),
+                                         Thread::kNoDeoptId,
+                                         token_pos,
+                                         try_index);
+  } else if (is_optimizing()) {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+                         Thread::kNoDeoptId, token_pos);
+    AddDeoptIndexAtCall(deopt_id_after, token_pos);
+  } else {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
+    // Add deoptimization continuation point after the call and before the
+    // arguments are removed.
+    AddCurrentDescriptor(RawPcDescriptors::kDeopt,
+        deopt_id_after, token_pos);
+  }
+  __ Drop(argument_count);
+}
+
+
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  __ Comment("SwitchableCall");
+  __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
+  if (ic_data.NumArgsTested() == 1) {
+    __ LoadUniqueObject(R9, ic_data);
+    __ BranchLinkPatchable(*StubCode::ICLookup_entry());
+  } else {
+    const String& name = String::Handle(zone(), ic_data.target_name());
+    const Array& arguments_descriptor =
+        Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
+    ASSERT(!arguments_descriptor.IsNull() &&
+           (arguments_descriptor.Length() > 0));
+    const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
+        MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
+
+    __ LoadUniqueObject(R9, cache);
+    __ BranchLinkPatchable(*StubCode::MegamorphicLookup_entry());
+  }
+  __ blx(R1);
+
   AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
@@ -1302,7 +1361,7 @@
     const ICData& ic_data) {
   const StubEntry* stub_entry =
       StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
-  __ LoadObject(R5, ic_data);
+  __ LoadObject(R9, ic_data);
   GenerateDartCall(deopt_id,
                    token_pos,
                    *stub_entry,
@@ -1348,7 +1407,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1377,7 +1436,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 2c9a717..359c89c 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -28,6 +28,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ b(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -172,8 +184,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -183,7 +195,7 @@
   ASSERT(deopt_env() != NULL);
   __ Push(CODE_REG);
   __ BranchLink(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
 #undef __
 }
 
@@ -255,12 +267,11 @@
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
   ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
   const Register kInstanceReg = R0;
-  Error& malformed_error = Error::Handle(zone());
+  Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
-  const bool smi_is_ok =
-      int_type.IsSubtypeOf(type, &malformed_error, Heap::kOld);
+  const bool smi_is_ok = int_type.IsSubtypeOf(type, &bound_error, Heap::kOld);
   // Malformed type should have been handled at graph construction time.
-  ASSERT(smi_is_ok || malformed_error.IsNull());
+  ASSERT(smi_is_ok || bound_error.IsNull());
   __ tsti(kInstanceReg, Immediate(kSmiTagMask));
   if (smi_is_ok) {
     __ b(is_instance_lbl, EQ);
@@ -442,7 +453,7 @@
   // Skip check if destination is a dynamic type.
   if (type.IsTypeParameter()) {
     const TypeParameter& type_param = TypeParameter::Cast(type);
-    // Load instantiator (or null) and instantiator type arguments on stack.
+    // Load instantiator type arguments on stack.
     __ ldr(R1, Address(SP));  // Get instantiator type arguments.
     // R1: instantiator type arguments.
     // Check if type arguments are null, i.e. equivalent to vector of dynamic.
@@ -452,7 +463,7 @@
         R2, R1, TypeArguments::type_at_offset(type_param.index()));
     // R2: concrete type of type.
     // Check if type argument is dynamic.
-    __ CompareObject(R2, Type::ZoneHandle(zone(), Type::DynamicType()));
+    __ CompareObject(R2, Object::dynamic_type());
     __ b(is_instance_lbl, EQ);
     __ CompareObject(R2, Type::ZoneHandle(zone(), Type::ObjectType()));
     __ b(is_instance_lbl, EQ);
@@ -567,7 +578,6 @@
 // Inputs:
 // - R0: object.
 // - R1: instantiator type arguments or raw_null.
-// - R2: instantiator or raw_null.
 // Returns:
 // - true or false in R0.
 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
@@ -577,8 +587,7 @@
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
 
-  // Preserve instantiator (R2) and its type arguments (R1).
-  __ Push(R2);
+  // Preserve instantiator type arguments (R1).
   __ Push(R1);
 
   Label is_instance, is_not_instance;
@@ -607,19 +616,16 @@
     // Generate runtime call.
     // Load instantiator (R2) and its type arguments (R1).
     __ ldr(R1, Address(SP, 0 * kWordSize));
-    __ ldr(R2, Address(SP, 1 * kWordSize));
     __ PushObject(Object::null_object());  // Make room for the result.
     __ Push(R0);  // Push the instance.
     __ PushObject(type);  // Push the type.
-    // Push instantiator (R2) and its type arguments (R1).
-    __ Push(R2);
-    __ Push(R1);
+    __ Push(R1);  // Push instantiator type arguments (R1).
     __ LoadUniqueObject(R0, test_cache);
     __ Push(R0);
-    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
+    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 4, locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
-    __ Drop(5);
+    __ Drop(4);
     if (negate_result) {
       __ Pop(R1);
       __ LoadObject(R0, Bool::True());
@@ -638,8 +644,8 @@
   __ Bind(&is_instance);
   __ LoadObject(R0, Bool::Get(!negate_result));
   __ Bind(&done);
-  // Remove instantiator (R2) and its type arguments (R1).
-  __ Drop(2);
+  // Remove instantiator type arguments (R1).
+  __ Drop(1);
 }
 
 
@@ -650,7 +656,6 @@
 // Inputs:
 // - R0: instance being type checked.
 // - R1: instantiator type arguments or raw_null.
-// - R2: instantiator or raw_null.
 // Returns:
 // - object in R0 for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
@@ -660,14 +665,13 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
   ASSERT(dst_type.IsMalformedOrMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
-  // Preserve instantiator (R2) and its type arguments (R1).
-  __ Push(R2);
+  // Preserve instantiator type arguments (R1).
   __ Push(R1);
   // A null object is always assignable and is returned as result.
   Label is_assignable, runtime_call;
@@ -689,9 +693,8 @@
     __ brk(0);
 
     __ Bind(&is_assignable);  // For a null object.
-    // Restore instantiator (R2) and its type arguments (R1).
+    // Restore instantiator type arguments (R1).
     __ Pop(R1);
-    __ Pop(R2);
     return;
   }
 
@@ -701,28 +704,23 @@
                                         &is_assignable, &runtime_call);
 
   __ Bind(&runtime_call);
-  // Load instantiator (R2) and its type arguments (R1).
-  __ ldr(R1, Address(SP));
-  __ ldr(R2, Address(SP, 1 * kWordSize));
+  __ ldr(R1, Address(SP));  // Load instantiator type arguments (R1).
   __ PushObject(Object::null_object());  // Make room for the result.
   __ Push(R0);  // Push the source object.
   __ PushObject(dst_type);  // Push the type of the destination.
-  // Push instantiator (R2) and its type arguments (R1).
-  __ Push(R2);
-  __ Push(R1);
+  __ Push(R1);  // Push instantiator type arguments (R1).
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadUniqueObject(R0, test_cache);
   __ Push(R0);
-  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 5, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
-  __ Drop(6);
+  __ Drop(5);
   __ Pop(R0);
 
   __ Bind(&is_assignable);
-  // Restore instantiator (R2) and its type arguments (R1).
+  // Restore instantiator type arguments (R1).
   __ Pop(R1);
-  __ Pop(R2);
 }
 
 
@@ -948,7 +946,7 @@
   // Sequence node has one return node, its input is load field node.
   __ Comment("Inlined Getter");
   __ LoadFromOffset(R0, SP, 0 * kWordSize);
-  __ LoadFromOffset(R0, R0, offset - kHeapObjectTag);
+  __ LoadFieldFromOffset(R0, R0, offset);
   __ ret();
 }
 
@@ -973,6 +971,7 @@
   if (CanOptimizeFunction() &&
       function.IsOptimizable() &&
       (!is_optimizing() || may_reoptimize())) {
+    __ Comment("Invocation Count Check");
     const Register function_reg = R6;
     new_pp = R13;
     // The pool pointer is not setup before entering the Dart frame.
@@ -1248,27 +1247,78 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  const Register receiverR = R0;
-  const Register cacheR = R1;
-  const Register targetR = R1;
-  __ LoadFromOffset(receiverR, SP, (argument_count - 1) * kWordSize);
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
+  __ LoadObject(R5, cache);
   if (FLAG_use_megamorphic_stub) {
     __ BranchLink(*StubCode::MegamorphicLookup_entry());
   } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+    StubCode::EmitMegamorphicLookup(assembler());
   }
-  __ LoadObject(R5, ic_data);
-  __ LoadObject(R4, arguments_descriptor);
-  __ blr(targetR);
+  __ blr(R1);
+
+  RecordSafepoint(locs);
+  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  if (Compiler::always_optimize()) {
+    // Megamorphic calls may occur in slow path stubs.
+    // If valid use try_index argument.
+    if (try_index == CatchClauseNode::kInvalidTryIndex) {
+      try_index = CurrentTryIndex();
+    }
+    pc_descriptors_list()->AddDescriptor(RawPcDescriptors::kOther,
+                                         assembler()->CodeSize(),
+                                         Thread::kNoDeoptId,
+                                         token_pos,
+                                         try_index);
+  } else if (is_optimizing()) {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
+    AddDeoptIndexAtCall(deopt_id_after, token_pos);
+  } else {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
+    // Add deoptimization continuation point after the call and before the
+    // arguments are removed.
+    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+  }
+  __ Drop(argument_count);
+}
+
+
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  __ Comment("SwitchableCall");
+  __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
+  if (ic_data.NumArgsTested() == 1) {
+    __ LoadUniqueObject(R5, ic_data);
+    __ BranchLinkPatchable(*StubCode::ICLookup_entry());
+  } else {
+    const String& name = String::Handle(zone(), ic_data.target_name());
+    const Array& arguments_descriptor =
+        Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
+    ASSERT(!arguments_descriptor.IsNull() &&
+           (arguments_descriptor.Length() > 0));
+    const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
+        MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
+
+    __ LoadUniqueObject(R5, cache);
+    __ BranchLinkPatchable(*StubCode::MegamorphicLookup_entry());
+  }
+  __ blr(R1);
+
   AddCurrentDescriptor(RawPcDescriptors::kOther,
       Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
@@ -1338,7 +1388,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1367,7 +1417,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 72dda0a..b2272fe9 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -33,6 +33,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ jmp(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -175,8 +187,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -186,7 +198,7 @@
   ASSERT(deopt_env() != NULL);
   __ pushl(CODE_REG);
   __ Call(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
   __ int3();
 #undef __
 }
@@ -267,12 +279,11 @@
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
   ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
   const Register kInstanceReg = EAX;
-  Error& malformed_error = Error::Handle(zone());
+  Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
-  const bool smi_is_ok =
-      int_type.IsSubtypeOf(type, &malformed_error, Heap::kOld);
+  const bool smi_is_ok = int_type.IsSubtypeOf(type, &bound_error, Heap::kOld);
   // Malformed type should have been handled at graph construction time.
-  ASSERT(smi_is_ok || malformed_error.IsNull());
+  ASSERT(smi_is_ok || bound_error.IsNull());
   __ testl(kInstanceReg, Immediate(kSmiTagMask));
   if (smi_is_ok) {
     __ j(ZERO, is_instance_lbl);
@@ -458,7 +469,7 @@
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   if (type.IsTypeParameter()) {
     const TypeParameter& type_param = TypeParameter::Cast(type);
-    // Load instantiator (or null) and instantiator type arguments on stack.
+    // Load instantiator type arguments on stack.
     __ movl(EDX, Address(ESP, 0));  // Get instantiator type arguments.
     // EDX: instantiator type arguments.
     // Check if type arguments are null, i.e. equivalent to vector of dynamic.
@@ -468,7 +479,7 @@
         FieldAddress(EDX, TypeArguments::type_at_offset(type_param.index())));
     // EDI: concrete type of type.
     // Check if type argument is dynamic.
-    __ CompareObject(EDI, Type::ZoneHandle(zone(), Type::DynamicType()));
+    __ CompareObject(EDI, Object::dynamic_type());
     __ j(EQUAL,  is_instance_lbl);
     __ CompareObject(EDI, Type::ZoneHandle(zone(), Type::ObjectType()));
     __ j(EQUAL,  is_instance_lbl);
@@ -583,8 +594,7 @@
 // Inputs:
 // - EAX: object.
 // - EDX: instantiator type arguments or raw_null.
-// - ECX: instantiator or raw_null.
-// Clobbers ECX and EDX.
+// Clobbers EDX.
 // Returns:
 // - true or false in EAX.
 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
@@ -597,7 +607,6 @@
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   Label is_instance, is_not_instance;
-  __ pushl(ECX);  // Store instantiator on stack.
   __ pushl(EDX);  // Store instantiator type arguments.
   // If type is instantiated and non-parameterized, we can inline code
   // checking whether the tested instance is a Smi.
@@ -623,22 +632,20 @@
   if (!test_cache.IsNull()) {
     // Generate runtime call.
     __ movl(EDX, Address(ESP, 0));  // Get instantiator type arguments.
-    __ movl(ECX, Address(ESP, kWordSize));  // Get instantiator.
     __ PushObject(Object::null_object());  // Make room for the result.
     __ pushl(EAX);  // Push the instance.
     __ PushObject(type);  // Push the type.
-    __ pushl(ECX);  // Instantiator.
     __ pushl(EDX);  // Instantiator type arguments.
     __ LoadObject(EAX, test_cache);
     __ pushl(EAX);
     GenerateRuntimeCall(token_pos,
                         deopt_id,
                         kInstanceofRuntimeEntry,
-                        5,
+                        4,
                         locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
-    __ Drop(5);
+    __ Drop(4);
     if (negate_result) {
       __ popl(EDX);
       __ LoadObject(EAX, Bool::True());
@@ -658,7 +665,6 @@
   __ LoadObject(EAX, Bool::Get(!negate_result));
   __ Bind(&done);
   __ popl(EDX);  // Remove pushed instantiator type arguments.
-  __ popl(ECX);  // Remove pushed instantiator.
 }
 
 
@@ -669,7 +675,6 @@
 // Inputs:
 // - EAX: object.
 // - EDX: instantiator type arguments or raw_null.
-// - ECX: instantiator or raw_null.
 // Returns:
 // - object in EAX for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
@@ -679,13 +684,12 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
   ASSERT(dst_type.IsMalformedOrMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
-  __ pushl(ECX);  // Store instantiator.
   __ pushl(EDX);  // Store instantiator type arguments.
   // A null object is always assignable and is returned as result.
   const Immediate& raw_null =
@@ -710,7 +714,6 @@
 
     __ Bind(&is_assignable);  // For a null object.
     __ popl(EDX);  // Remove pushed instantiator type arguments.
-    __ popl(ECX);  // Remove pushed instantiator.
     return;
   }
 
@@ -721,24 +724,21 @@
 
   __ Bind(&runtime_call);
   __ movl(EDX, Address(ESP, 0));  // Get instantiator type arguments.
-  __ movl(ECX, Address(ESP, kWordSize));  // Get instantiator.
   __ PushObject(Object::null_object());  // Make room for the result.
   __ pushl(EAX);  // Push the source object.
   __ PushObject(dst_type);  // Push the type of the destination.
-  __ pushl(ECX);  // Instantiator.
   __ pushl(EDX);  // Instantiator type arguments.
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadObject(EAX, test_cache);
   __ pushl(EAX);
-  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 5, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
-  __ Drop(6);
+  __ Drop(5);
   __ popl(EAX);
 
   __ Bind(&is_assignable);
   __ popl(EDX);  // Remove pushed instantiator type arguments.
-  __ popl(ECX);  // Remove pushed instantiator.
 }
 
 
@@ -1000,6 +1000,7 @@
   if (CanOptimizeFunction() &&
       function.IsOptimizable() &&
       (!is_optimizing() || may_reoptimize())) {
+    __ Comment("Invocation Count Check");
     const Register function_reg = EBX;
     __ LoadObject(function_reg, function);
 
@@ -1278,32 +1279,31 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  const Register receiverR = ECX;
-  const Register cacheR = EBX;
-  const Register targetR = EBX;
-  __ movl(receiverR, Address(ESP, (argument_count - 1) * kWordSize));
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ movl(EBX, Address(ESP, (argument_count - 1) * kWordSize));
+  __ LoadObject(ECX, cache);
   if (FLAG_use_megamorphic_stub) {
     __ Call(*StubCode::MegamorphicLookup_entry());
   } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+    StubCode::EmitMegamorphicLookup(assembler());
   }
+  __ call(EBX);
 
-  __ LoadObject(ECX, ic_data);
-  __ LoadObject(EDX, arguments_descriptor);
-  __ call(targetR);
   AddCurrentDescriptor(RawPcDescriptors::kOther,
       Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  // Precompilation not implemented on ia32 platform.
+  ASSERT(!Compiler::always_optimize());
   if (is_optimizing()) {
     AddDeoptIndexAtCall(deopt_id_after, token_pos);
   } else {
@@ -1315,6 +1315,17 @@
 }
 
 
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  // Only generated with precompilation.
+  UNREACHABLE();
+}
+
+
 void FlowGraphCompiler::EmitOptimizedStaticCall(
     const Function& function,
     const Array& arguments_descriptor,
@@ -1357,7 +1368,7 @@
     } else {
       __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1384,7 +1395,7 @@
     } else {
       __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index d2670eb..f98bb67 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -26,6 +26,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ b(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -172,8 +184,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -183,7 +195,7 @@
   ASSERT(deopt_env() != NULL);
   __ Push(CODE_REG);
   __ BranchLink(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
 #undef __
 }
 
@@ -255,12 +267,11 @@
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
   ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
   const Register kInstanceReg = A0;
-  Error& malformed_error = Error::Handle(zone());
+  Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
-  const bool smi_is_ok =
-      int_type.IsSubtypeOf(type, &malformed_error, Heap::kOld);
+  const bool smi_is_ok = int_type.IsSubtypeOf(type, &bound_error, Heap::kOld);
   // Malformed type should have been handled at graph construction time.
-  ASSERT(smi_is_ok || malformed_error.IsNull());
+  ASSERT(smi_is_ok || bound_error.IsNull());
   __ andi(CMPRES1, kInstanceReg, Immediate(kSmiTagMask));
   if (smi_is_ok) {
     __ beq(CMPRES1, ZR, is_instance_lbl);
@@ -438,7 +449,7 @@
   // Skip check if destination is a dynamic type.
   if (type.IsTypeParameter()) {
     const TypeParameter& type_param = TypeParameter::Cast(type);
-    // Load instantiator (or null) and instantiator type arguments on stack.
+    // Load instantiator type arguments on stack.
     __ lw(A1, Address(SP, 0));  // Get instantiator type arguments.
     // A1: instantiator type arguments.
     // Check if type arguments are null, i.e. equivalent to vector of dynamic.
@@ -449,7 +460,7 @@
     // R2: concrete type of type.
     // Check if type argument is dynamic.
     __ BranchEqual(T2,
-        Type::ZoneHandle(zone(), Type::DynamicType()), is_instance_lbl);
+        Object::dynamic_type(), is_instance_lbl);
     __ BranchEqual(T2,
         Type::ZoneHandle(zone(), Type::ObjectType()), is_instance_lbl);
 
@@ -563,7 +574,6 @@
 // Inputs:
 // - A0: object.
 // - A1: instantiator type arguments or raw_null.
-// - A2: instantiator or raw_null.
 // Returns:
 // - true or false in V0.
 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
@@ -573,9 +583,8 @@
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
 
-  // Preserve instantiator (A2) and its type arguments (A1).
-  __ addiu(SP, SP, Immediate(-2 * kWordSize));
-  __ sw(A2, Address(SP, 1 * kWordSize));
+  // Preserve instantiator type arguments (A1).
+  __ addiu(SP, SP, Immediate(-1 * kWordSize));
   __ sw(A1, Address(SP, 0 * kWordSize));
 
   Label is_instance, is_not_instance;
@@ -602,25 +611,23 @@
   Label done;
   if (!test_cache.IsNull()) {
     // Generate runtime call.
-    // Load instantiator (A2) and its type arguments (A1).
+    // Load instantiator type arguments (A1).
     __ lw(A1, Address(SP, 0 * kWordSize));
-    __ lw(A2, Address(SP, 1 * kWordSize));
 
-    __ addiu(SP, SP, Immediate(-6 * kWordSize));
+    __ addiu(SP, SP, Immediate(-5 * kWordSize));
     __ LoadObject(TMP, Object::null_object());
-    __ sw(TMP, Address(SP, 5 * kWordSize));  // Make room for the result.
-    __ sw(A0, Address(SP, 4 * kWordSize));  // Push the instance.
+    __ sw(TMP, Address(SP, 4 * kWordSize));  // Make room for the result.
+    __ sw(A0, Address(SP, 3 * kWordSize));  // Push the instance.
     __ LoadObject(TMP, type);
-    __ sw(TMP, Address(SP, 3 * kWordSize));  // Push the type.
-    __ sw(A2, Address(SP, 2 * kWordSize));  // Push instantiator.
+    __ sw(TMP, Address(SP, 2 * kWordSize));  // Push the type.
     __ sw(A1, Address(SP, 1 * kWordSize));  // Push type arguments.
     __ LoadUniqueObject(A0, test_cache);
     __ sw(A0, Address(SP, 0 * kWordSize));
-    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
+    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 4, locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
-    __ lw(T0, Address(SP, 5 * kWordSize));
-    __ addiu(SP, SP, Immediate(6 * kWordSize));
+    __ lw(T0, Address(SP, 4 * kWordSize));
+    __ addiu(SP, SP, Immediate(5 * kWordSize));
     if (negate_result) {
       __ LoadObject(V0, Bool::True());
       __ bne(T0, V0, &done);
@@ -637,8 +644,8 @@
   __ Bind(&is_instance);
   __ LoadObject(V0, Bool::Get(!negate_result));
   __ Bind(&done);
-  // Remove instantiator (A2) and its type arguments (A1).
-  __ Drop(2);
+  // Remove instantiator type arguments (A1).
+  __ Drop(1);
 }
 
 
@@ -649,7 +656,6 @@
 // Inputs:
 // - A0: instance being type checked.
 // - A1: instantiator type arguments or raw_null.
-// - A2: instantiator or raw_null.
 // Returns:
 // - object in A0 for successful assignable check (or throws TypeError).
 // Clobbers: T0, T1, T2
@@ -661,15 +667,15 @@
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
   __ Comment("AssertAssignable");
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
   ASSERT(dst_type.IsMalformedOrMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
-  // Preserve instantiator and its type arguments.
-  __ addiu(SP, SP, Immediate(-2 * kWordSize));
-  __ sw(A2, Address(SP, 1 * kWordSize));
+  // Preserve instantiator type arguments.
+  __ addiu(SP, SP, Immediate(-1 * kWordSize));
+  __ sw(A1, Address(SP, 0 * kWordSize));
 
   // A null object is always assignable and is returned as result.
   Label is_assignable, runtime_call;
@@ -697,10 +703,9 @@
     __ break_(0);
 
     __ Bind(&is_assignable);  // For a null object.
-    // Restore instantiator and its type arguments.
+    // Restore instantiator type arguments.
     __ lw(A1, Address(SP, 0 * kWordSize));
-    __ lw(A2, Address(SP, 1 * kWordSize));
-    __ addiu(SP, SP, Immediate(2 * kWordSize));
+    __ addiu(SP, SP, Immediate(1 * kWordSize));
     return;
   }
 
@@ -710,34 +715,31 @@
                                         &is_assignable, &runtime_call);
 
   __ Bind(&runtime_call);
-  // Load instantiator (A2) and its type arguments (A1).
+  // Load instantiator type arguments (A1).
   __ lw(A1, Address(SP, 0 * kWordSize));
-  __ lw(A2, Address(SP, 1 * kWordSize));
 
-  __ addiu(SP, SP, Immediate(-7 * kWordSize));
+  __ addiu(SP, SP, Immediate(-6 * kWordSize));
   __ LoadObject(TMP, Object::null_object());
-  __ sw(TMP, Address(SP, 6 * kWordSize));  // Make room for the result.
-  __ sw(A0, Address(SP, 5 * kWordSize));  // Push the source object.
+  __ sw(TMP, Address(SP, 5 * kWordSize));  // Make room for the result.
+  __ sw(A0, Address(SP, 4 * kWordSize));  // Push the source object.
   __ LoadObject(TMP, dst_type);
-  __ sw(TMP, Address(SP, 4 * kWordSize));  // Push the type of the destination.
-  __ sw(A2, Address(SP, 3 * kWordSize));  // Push instantiator.
+  __ sw(TMP, Address(SP, 3 * kWordSize));  // Push the type of the destination.
   __ sw(A1, Address(SP, 2 * kWordSize));  // Push type arguments.
   __ LoadObject(TMP, dst_name);
   __ sw(TMP, Address(SP, 1 * kWordSize));  // Push the name of the destination.
   __ LoadUniqueObject(T0, test_cache);
   __ sw(T0, Address(SP, 0 * kWordSize));
 
-  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 5, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
-  __ lw(A0, Address(SP, 6 * kWordSize));
-  __ addiu(SP, SP, Immediate(7 * kWordSize));
+  __ lw(A0, Address(SP, 5 * kWordSize));
+  __ addiu(SP, SP, Immediate(6 * kWordSize));
 
   __ Bind(&is_assignable);
-  // Restore instantiator and its type arguments.
+  // Restore instantiator type arguments.
   __ lw(A1, Address(SP, 0 * kWordSize));
-  __ lw(A2, Address(SP, 1 * kWordSize));
-  __ addiu(SP, SP, Immediate(2 * kWordSize));
+  __ addiu(SP, SP, Immediate(1 * kWordSize));
 }
 
 
@@ -964,7 +966,7 @@
   // Sequence node has one return node, its input is load field node.
   __ Comment("Inlined Getter");
   __ lw(V0, Address(SP, 0 * kWordSize));
-  __ lw(V0, Address(V0, offset - kHeapObjectTag));
+  __ LoadFieldFromOffset(V0, V0, offset);
   __ Ret();
 }
 
@@ -991,6 +993,7 @@
   if (CanOptimizeFunction() &&
       function.IsOptimizable() &&
       (!is_optimizing() || may_reoptimize())) {
+    __ Comment("Invocation Count Check");
     const Register function_reg = T0;
 
     // Temporarily setup pool pointer for this dart function.
@@ -1269,28 +1272,78 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  __ Comment("MegamorphicInstanceCall");
-  const Register receiverR = T0;
-  const Register cacheR = T1;
-  const Register targetR = T1;
-  __ lw(receiverR, Address(SP, (argument_count - 1) * kWordSize));
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
+  __ LoadObject(S5, cache);
   if (FLAG_use_megamorphic_stub) {
     __ BranchLink(*StubCode::MegamorphicLookup_entry());
   } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+    StubCode::EmitMegamorphicLookup(assembler());
   }
-  __ LoadObject(S5, ic_data);
-  __ LoadObject(S4, arguments_descriptor);
-  __ jalr(targetR);
+  __ jalr(T1);
+
+  RecordSafepoint(locs);
+  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  if (Compiler::always_optimize()) {
+    // Megamorphic calls may occur in slow path stubs.
+    // If valid use try_index argument.
+    if (try_index == CatchClauseNode::kInvalidTryIndex) {
+      try_index = CurrentTryIndex();
+    }
+    pc_descriptors_list()->AddDescriptor(RawPcDescriptors::kOther,
+                                         assembler()->CodeSize(),
+                                         Thread::kNoDeoptId,
+                                         token_pos,
+                                         try_index);
+  } else if (is_optimizing()) {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
+    AddDeoptIndexAtCall(deopt_id_after, token_pos);
+  } else {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
+    // Add deoptimization continuation point after the call and before the
+    // arguments are removed.
+    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+  }
+  __ Drop(argument_count);
+}
+
+
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  __ Comment("SwitchableCall");
+  __ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
+  if (ic_data.NumArgsTested() == 1) {
+    __ LoadUniqueObject(S5, ic_data);
+    __ BranchLinkPatchable(*StubCode::ICLookup_entry());
+  } else {
+    const String& name = String::Handle(zone(), ic_data.target_name());
+    const Array& arguments_descriptor =
+        Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
+    ASSERT(!arguments_descriptor.IsNull() &&
+           (arguments_descriptor.Length() > 0));
+    const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
+        MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
+
+    __ LoadUniqueObject(S5, cache);
+    __ BranchLinkPatchable(*StubCode::MegamorphicLookup_entry());
+  }
+  __ jalr(T1);
+
   AddCurrentDescriptor(RawPcDescriptors::kOther,
       Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
@@ -1366,7 +1419,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1400,7 +1453,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 2a80633..e54b1eb 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -29,6 +29,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ jmp(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -175,8 +187,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -187,7 +199,7 @@
 
   __ pushq(CODE_REG);
   __ Call(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
   __ int3();
 #undef __
 }
@@ -264,12 +276,11 @@
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
   ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
   const Register kInstanceReg = RAX;
-  Error& malformed_error = Error::Handle(zone());
+  Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
-  const bool smi_is_ok =
-      int_type.IsSubtypeOf(type, &malformed_error, Heap::kOld);
+  const bool smi_is_ok = int_type.IsSubtypeOf(type, &bound_error, Heap::kOld);
   // Malformed type should have been handled at graph construction time.
-  ASSERT(smi_is_ok || malformed_error.IsNull());
+  ASSERT(smi_is_ok || bound_error.IsNull());
   __ testq(kInstanceReg, Immediate(kSmiTagMask));
   if (smi_is_ok) {
     __ j(ZERO, is_instance_lbl);
@@ -451,7 +462,7 @@
   // Skip check if destination is a dynamic type.
   if (type.IsTypeParameter()) {
     const TypeParameter& type_param = TypeParameter::Cast(type);
-    // Load instantiator (or null) and instantiator type arguments on stack.
+    // Load instantiator type arguments on stack.
     __ movq(RDX, Address(RSP, 0));  // Get instantiator type arguments.
     // RDX: instantiator type arguments.
     // Check if type arguments are null, i.e. equivalent to vector of dynamic.
@@ -461,7 +472,7 @@
         FieldAddress(RDX, TypeArguments::type_at_offset(type_param.index())));
     // RDI: Concrete type of type.
     // Check if type argument is dynamic.
-    __ CompareObject(RDI, Type::ZoneHandle(zone(), Type::DynamicType()));
+    __ CompareObject(RDI, Object::dynamic_type());
     __ j(EQUAL,  is_instance_lbl);
     const Type& object_type = Type::ZoneHandle(zone(), Type::ObjectType());
     __ CompareObject(RDI, object_type);
@@ -577,8 +588,7 @@
 // Inputs:
 // - RAX: object.
 // - RDX: instantiator type arguments or raw_null.
-// - RCX: instantiator or raw_null.
-// Clobbers RCX and RDX.
+// Clobbers RDX.
 // Returns:
 // - true or false in RAX.
 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
@@ -589,7 +599,6 @@
   ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
 
   Label is_instance, is_not_instance;
-  __ pushq(RCX);  // Store instantiator on stack.
   __ pushq(RDX);  // Store instantiator type arguments.
   // If type is instantiated and non-parameterized, we can inline code
   // checking whether the tested instance is a Smi.
@@ -615,22 +624,20 @@
   if (!test_cache.IsNull()) {
     // Generate runtime call.
     __ movq(RDX, Address(RSP, 0));  // Get instantiator type arguments.
-    __ movq(RCX, Address(RSP, kWordSize));  // Get instantiator.
     __ PushObject(Object::null_object());  // Make room for the result.
     __ pushq(RAX);  // Push the instance.
     __ PushObject(type);  // Push the type.
-    __ pushq(RCX);  // TODO(srdjan): Pass instantiator instead of null.
     __ pushq(RDX);  // Instantiator type arguments.
     __ LoadUniqueObject(RAX, test_cache);
     __ pushq(RAX);
     GenerateRuntimeCall(token_pos,
                         deopt_id,
                         kInstanceofRuntimeEntry,
-                        5,
+                        4,
                         locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
-    __ Drop(5);
+    __ Drop(4);
     if (negate_result) {
       __ popq(RDX);
       __ LoadObject(RAX, Bool::True());
@@ -650,7 +657,6 @@
   __ LoadObject(RAX, Bool::Get(!negate_result));
   __ Bind(&done);
   __ popq(RDX);  // Remove pushed instantiator type arguments.
-  __ popq(RCX);  // Remove pushed instantiator.
 }
 
 
@@ -661,7 +667,6 @@
 // Inputs:
 // - RAX: object.
 // - RDX: instantiator type arguments or raw_null.
-// - RCX: instantiator or raw_null.
 // Returns:
 // - object in RAX for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
@@ -671,13 +676,12 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
   ASSERT(dst_type.IsMalformedOrMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
-  __ pushq(RCX);  // Store instantiator.
   __ pushq(RDX);  // Store instantiator type arguments.
   // A null object is always assignable and is returned as result.
   Label is_assignable, runtime_call;
@@ -700,7 +704,6 @@
 
     __ Bind(&is_assignable);  // For a null object.
     __ popq(RDX);  // Remove pushed instantiator type arguments.
-    __ popq(RCX);  // Remove pushed instantiator.
     return;
   }
 
@@ -711,24 +714,21 @@
 
   __ Bind(&runtime_call);
   __ movq(RDX, Address(RSP, 0));  // Get instantiator type arguments.
-  __ movq(RCX, Address(RSP, kWordSize));  // Get instantiator.
   __ PushObject(Object::null_object());  // Make room for the result.
   __ pushq(RAX);  // Push the source object.
   __ PushObject(dst_type);  // Push the type of the destination.
-  __ pushq(RCX);  // Instantiator.
   __ pushq(RDX);  // Instantiator type arguments.
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadUniqueObject(RAX, test_cache);
   __ pushq(RAX);
-  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 5, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
-  __ Drop(6);
+  __ Drop(5);
   __ popq(RAX);
 
   __ Bind(&is_assignable);
   __ popq(RDX);  // Remove pushed instantiator type arguments.
-  __ popq(RCX);  // Remove pushed instantiator.
 }
 
 
@@ -1003,6 +1003,7 @@
     if (CanOptimizeFunction() &&
         function.IsOptimizable() &&
         (!is_optimizing() || may_reoptimize())) {
+      __ Comment("Invocation Count Check");
       const Register function_reg = RDI;
       // Load function object using the callee's pool pointer.
       __ LoadFunctionFromCalleePool(function_reg, function, new_pp);
@@ -1279,29 +1280,80 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
   ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
   const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
       MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
-  const Register receiverR = RDI;
-  const Register cacheR = RBX;
-  const Register targetR = RCX;
-  __ movq(receiverR, Address(RSP, (argument_count - 1) * kWordSize));
-  __ LoadObject(cacheR, cache);
 
+  __ Comment("MegamorphicCall");
+  __ movq(RDI, Address(RSP, (argument_count - 1) * kWordSize));
+  __ LoadObject(RBX, cache);
   if (FLAG_use_megamorphic_stub) {
     __ Call(*StubCode::MegamorphicLookup_entry());
   } else  {
-    StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
+    StubCode::EmitMegamorphicLookup(assembler());
   }
-  __ LoadObject(RBX, ic_data);
-  __ LoadObject(R10, arguments_descriptor);
-  __ call(targetR);
+  __ call(RCX);
+
+  RecordSafepoint(locs);
+  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  if (Compiler::always_optimize()) {
+    // Megamorphic calls may occur in slow path stubs.
+    // If valid use try_index argument.
+    if (try_index == CatchClauseNode::kInvalidTryIndex) {
+      try_index = CurrentTryIndex();
+    }
+    pc_descriptors_list()->AddDescriptor(RawPcDescriptors::kOther,
+                                         assembler()->CodeSize(),
+                                         Thread::kNoDeoptId,
+                                         token_pos,
+                                         try_index);
+  } else if (is_optimizing()) {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
+    AddDeoptIndexAtCall(deopt_id_after, token_pos);
+  } else {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
+    // Add deoptimization continuation point after the call and before the
+    // arguments are removed.
+    AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
+  }
+  __ Drop(argument_count, RCX);
+}
+
+
+void FlowGraphCompiler::EmitSwitchableInstanceCall(
+    const ICData& ic_data,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  __ Comment("SwitchableCall");
+  __ movq(RDI, Address(RSP, (argument_count - 1) * kWordSize));
+  if (ic_data.NumArgsTested() == 1) {
+    __ LoadUniqueObject(RBX, ic_data);
+    __ CallPatchable(*StubCode::ICLookup_entry());
+  } else {
+    const String& name = String::Handle(zone(), ic_data.target_name());
+    const Array& arguments_descriptor =
+        Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
+    ASSERT(!arguments_descriptor.IsNull() &&
+           (arguments_descriptor.Length() > 0));
+    const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
+        MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
+
+    __ LoadUniqueObject(RBX, cache);
+    __ CallPatchable(*StubCode::MegamorphicLookup_entry());
+  }
+  __ call(RCX);
+
   AddCurrentDescriptor(RawPcDescriptors::kOther,
-      Thread::kNoDeoptId, token_pos);
+                       Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
   if (is_optimizing()) {
@@ -1357,7 +1409,7 @@
     } else {
       __ CallPatchable(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1384,7 +1436,7 @@
     } else {
       __ CallPatchable(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos != Scanner::kNoSourcePos) {
+    if (token_pos >= 0) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index f8bcb22..bc5d7bc 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -11,6 +11,7 @@
 #include "vm/flow_graph_builder.h"
 #include "vm/flow_graph_compiler.h"
 #include "vm/flow_graph_optimizer.h"
+#include "vm/flow_graph_type_propagator.h"
 #include "vm/il_printer.h"
 #include "vm/intrinsifier.h"
 #include "vm/longjump.h"
@@ -58,7 +59,7 @@
             "Enable inlining annotations");
 
 DECLARE_FLAG(bool, compiler_stats);
-DECLARE_FLAG(int, deoptimization_counter_threshold);
+DECLARE_FLAG(int, max_deoptimization_counter_threshold);
 DECLARE_FLAG(bool, polymorphic_with_deopt);
 DECLARE_FLAG(bool, print_flow_graph);
 DECLARE_FLAG(bool, print_flow_graph_optimized);
@@ -618,9 +619,6 @@
                              function.ToCString(),
                              function.deoptimization_counter()));
 
-    // Make a handle for the unoptimized code so that it is not disconnected
-    // from the function while we are trying to inline it.
-    const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
     // Abort if the inlinable bit on the function is low.
     if (!function.CanBeInlined()) {
       TRACE_INLINING(THR_Print("     Bailout: not inlinable\n"));
@@ -629,9 +627,19 @@
       return false;
     }
 
+    // Function has no type feedback. With precompilation we don't rely on
+    // type feedback.
+    if (!Compiler::always_optimize() &&
+        function.ic_data_array() == Object::null()) {
+      TRACE_INLINING(THR_Print("     Bailout: not compiled yet\n"));
+      PRINT_INLINING_TREE("Not compiled",
+          &call_data->caller, &function, call_data->call);
+      return false;
+    }
+
     // Abort if this function has deoptimized too much.
     if (function.deoptimization_counter() >=
-        FLAG_deoptimization_counter_threshold) {
+        FLAG_max_deoptimization_counter_threshold) {
       function.set_is_inlinable(false);
       TRACE_INLINING(THR_Print("     Bailout: deoptimization threshold\n"));
       PRINT_INLINING_TREE("Deoptimization threshold exceeded",
@@ -693,7 +701,8 @@
       // Load IC data for the callee.
       ZoneGrowableArray<const ICData*>* ic_data_array =
             new(Z) ZoneGrowableArray<const ICData*>();
-      function.RestoreICDataMap(ic_data_array);
+      const bool clone_descriptors = Compiler::IsBackgroundCompilation();
+      function.RestoreICDataMap(ic_data_array, clone_descriptors);
 
       // Build the callee graph.
       InlineExitCollector* exit_collector =
@@ -701,7 +710,7 @@
       FlowGraphBuilder builder(*parsed_function,
                                *ic_data_array,
                                exit_collector,
-                               Thread::kNoDeoptId);
+                               Compiler::kNoOSRDeoptId);
       builder.SetInitialBlockId(caller_graph_->max_block_id());
       FlowGraph* callee_graph;
       {
@@ -768,10 +777,19 @@
 
       {
         CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer);
-        // TODO(zerny): Do more optimization passes on the callee graph.
-        FlowGraphOptimizer optimizer(callee_graph);
+        // TODO(fschneider): Improve suppression of speculative inlining.
+        // Deopt-ids overlap between caller and callee.
+        FlowGraphOptimizer optimizer(callee_graph,
+                                     inliner_->use_speculative_inlining_,
+                                     inliner_->inlining_black_list_);
         if (Compiler::always_optimize()) {
           optimizer.PopulateWithICData();
+
+          optimizer.ApplyClassIds();
+          DEBUG_ASSERT(callee_graph->VerifyUseLists());
+
+          FlowGraphTypePropagator::Propagate(callee_graph);
+          DEBUG_ASSERT(callee_graph->VerifyUseLists());
         }
         optimizer.ApplyICData();
         DEBUG_ASSERT(callee_graph->VerifyUseLists());
@@ -862,9 +880,6 @@
       FlowGraphInliner::SetInliningId(callee_graph,
           inliner_->NextInlineId(callee_graph->function(),
                                  call_data->caller_inlining_id_));
-      // We allocate a ZoneHandle for the unoptimized code so that it cannot be
-      // disconnected from its function during the rest of compilation.
-      Code::ZoneHandle(unoptimized_code.raw());
       TRACE_INLINING(THR_Print("     Success\n"));
       PRINT_INLINING_TREE(NULL,
           &call_data->caller, &function, call);
@@ -1128,7 +1143,12 @@
       PolymorphicInstanceCallInstr* call = call_info[call_idx].call;
       if (call->with_checks()) {
         // PolymorphicInliner introduces deoptimization paths.
-        if (!FLAG_polymorphic_with_deopt) return;
+        if (!FLAG_polymorphic_with_deopt) {
+          TRACE_INLINING(THR_Print(
+              "  => %s\n     Bailout: call with checks\n",
+              call->instance_call()->function_name().ToCString()));
+          continue;
+        }
         const Function& cl = call_info[call_idx].caller();
         intptr_t caller_inlining_id =
             call_info[call_idx].caller_graph->inlining_id();
@@ -1459,7 +1479,9 @@
 
 bool PolymorphicInliner::TryInlineRecognizedMethod(intptr_t receiver_cid,
                                                    const Function& target) {
-  FlowGraphOptimizer optimizer(owner_->caller_graph());
+  FlowGraphOptimizer optimizer(owner_->caller_graph(),
+                               false,  // Speculative inlining not applicable.
+                               NULL);
   TargetEntryInstr* entry;
   Definition* last;
   // Replace the receiver argument with a redefinition to prevent code from
@@ -1497,7 +1519,7 @@
     GraphEntryInstr* graph_entry =
         new(Z) GraphEntryInstr(*temp_parsed_function,
                                entry,
-                               Thread::kNoDeoptId);  // No OSR id.
+                               Compiler::kNoOSRDeoptId);
     // Update polymorphic inliner state.
     inlined_entries_.Add(graph_entry);
     exit_collector_->Union(exit_collector);
@@ -1670,7 +1692,7 @@
     }
     const ICData& old_checks = call_->ic_data();
     const ICData& new_checks = ICData::ZoneHandle(
-        ICData::New(Function::Handle(old_checks.owner()),
+        ICData::New(Function::Handle(old_checks.Owner()),
                     String::Handle(old_checks.target_name()),
                     Array::Handle(old_checks.arguments_descriptor()),
                     old_checks.deopt_id(),
@@ -1765,11 +1787,16 @@
 FlowGraphInliner::FlowGraphInliner(
     FlowGraph* flow_graph,
     GrowableArray<const Function*>* inline_id_to_function,
-    GrowableArray<intptr_t>* caller_inline_id)
+    GrowableArray<intptr_t>* caller_inline_id,
+    bool use_speculative_inlining,
+    GrowableArray<intptr_t>* inlining_black_list)
     : flow_graph_(flow_graph),
       inline_id_to_function_(inline_id_to_function),
       caller_inline_id_(caller_inline_id),
-      trace_inlining_(ShouldTraceInlining(flow_graph)) {
+      trace_inlining_(ShouldTraceInlining(flow_graph)),
+      use_speculative_inlining_(use_speculative_inlining),
+      inlining_black_list_(inlining_black_list) {
+  ASSERT(!use_speculative_inlining || (inlining_black_list != NULL));
 }
 
 
@@ -1809,7 +1836,7 @@
 
 
 // Use function name to determine if inlineable operator.
-// TODO(srdjan): add names as necessary
+// Add names as necessary.
 static bool IsInlineableOperator(const Function& function) {
   return (function.name() == Symbols::IndexToken().raw()) ||
          (function.name() == Symbols::AssignIndexToken().raw()) ||
@@ -1829,7 +1856,8 @@
 
   if (function.IsImplicitGetterFunction() || function.IsGetterFunction() ||
       function.IsImplicitSetterFunction() || function.IsSetterFunction() ||
-      IsInlineableOperator(function)) {
+      IsInlineableOperator(function) ||
+      (function.kind() == RawFunction::kConstructor)) {
     const intptr_t count = function.optimized_instruction_count();
     if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) {
       return true;
diff --git a/runtime/vm/flow_graph_inliner.h b/runtime/vm/flow_graph_inliner.h
index 114348b..6e3ce09 100644
--- a/runtime/vm/flow_graph_inliner.h
+++ b/runtime/vm/flow_graph_inliner.h
@@ -18,7 +18,9 @@
  public:
   FlowGraphInliner(FlowGraph* flow_graph,
                    GrowableArray<const Function*>* inline_id_to_function,
-                   GrowableArray<intptr_t>* caller_inline_id);
+                   GrowableArray<intptr_t>* caller_inline_id,
+                   bool use_speculative_inlining,
+                   GrowableArray<intptr_t>* inlining_black_list);
 
   // The flow graph is destructively updated upon inlining.
   void Inline();
@@ -41,6 +43,8 @@
   GrowableArray<const Function*>* inline_id_to_function_;
   GrowableArray<intptr_t>* caller_inline_id_;
   const bool trace_inlining_;
+  const bool use_speculative_inlining_;
+  GrowableArray<intptr_t>* inlining_black_list_;
 
   DISALLOW_COPY_AND_ASSIGN(FlowGraphInliner);
 };
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 4a1aa37..c36bf53 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -18,6 +18,7 @@
 #include "vm/intermediate_language.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
+#include "vm/precompiler.h"
 #include "vm/resolver.h"
 #include "vm/scopes.h"
 #include "vm/stack_frame.h"
@@ -27,7 +28,7 @@
 
 DEFINE_FLAG(int, getter_setter_ratio, 13,
     "Ratio of getter/setter usage used for double field unboxing heuristics");
-DEFINE_FLAG(bool, guess_other_cid, true,
+DEFINE_FLAG(bool, guess_icdata_cid, true,
     "Artificially create type feedback for arithmetic etc. operations"
     " by guessing the other unknown argument cid");
 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
@@ -49,12 +50,14 @@
 DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass.");
 #endif
 
+DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, polymorphic_with_deopt);
 DECLARE_FLAG(bool, source_lines);
 DECLARE_FLAG(bool, trace_cha);
 DECLARE_FLAG(bool, trace_field_guards);
 DECLARE_FLAG(bool, trace_type_check_elimination);
 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
+DECLARE_FLAG(bool, fields_may_be_reset);
 
 // Quick access to the current isolate and zone.
 #define I (isolate())
@@ -177,9 +180,6 @@
     // Do not make the instance call megamorphic if the callee needs to decode
     // the calling code sequence to lookup the ic data and verify if a warning
     // has already been issued or not.
-    // TryCreateICData is only invoked if the ic_data target has not been called
-    // yet, so no warning can possibly have been issued.
-    ASSERT(!call->ic_data()->IssuedJSWarning());
     if (call->ic_data()->MayCheckForJSWarning()) {
       return false;
     }
@@ -187,8 +187,7 @@
   GrowableArray<intptr_t> class_ids(call->ic_data()->NumArgsTested());
   ASSERT(call->ic_data()->NumArgsTested() <= call->ArgumentCount());
   for (intptr_t i = 0; i < call->ic_data()->NumArgsTested(); i++) {
-    const intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid();
-    class_ids.Add(cid);
+    class_ids.Add(call->PushArgumentAt(i)->value()->Type()->ToCid());
   }
 
   const Token::Kind op_kind = call->token_kind();
@@ -197,7 +196,7 @@
       Token::IsBinaryOperator(op_kind)) {
     // Guess cid: if one of the inputs is a number assume that the other
     // is a number of same type.
-    if (FLAG_guess_other_cid) {
+    if (FLAG_guess_icdata_cid) {
       const intptr_t cid_0 = class_ids[0];
       const intptr_t cid_1 = class_ids[1];
       if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) {
@@ -218,10 +217,6 @@
   }
 
   if (all_cids_known) {
-    const Array& args_desc_array = Array::Handle(Z,
-        ArgumentsDescriptor::New(call->ArgumentCount(),
-                                 call->argument_names()));
-    ArgumentsDescriptor args_desc(args_desc_array);
     const Class& receiver_class = Class::Handle(Z,
         isolate()->class_table()->At(class_ids[0]));
     if (!receiver_class.is_finalized()) {
@@ -230,6 +225,18 @@
       // finalized yet.
       return false;
     }
+    // Do not run the optimization below if in background compilation since
+    // resolution of method extractor functions may create new signature
+    // classes.
+    // TODO(regis): Remove test for background compilation once signature
+    // classes are not generated any longer.
+    if (!thread()->IsMutatorThread()) {
+      return false;
+    }
+    const Array& args_desc_array = Array::Handle(Z,
+        ArgumentsDescriptor::New(call->ArgumentCount(),
+                                 call->argument_names()));
+    ArgumentsDescriptor args_desc(args_desc_array);
     const Function& function = Function::Handle(Z,
         Resolver::ResolveDynamicForReceiverClass(
             receiver_class,
@@ -255,9 +262,36 @@
     return true;
   }
 
+  if (Compiler::always_optimize() &&
+      (isolate()->object_store()->unique_dynamic_targets() != Array::null())) {
+    // Check if the target is unique.
+    Function& target_function = Function::Handle(Z);
+    Precompiler::GetUniqueDynamicTarget(
+        isolate(), call->function_name(), &target_function);
+    // Calls with named arguments must be resolved/checked at runtime.
+    String& error_message = String::Handle(Z);
+    if (!target_function.IsNull() &&
+        !target_function.HasOptionalNamedParameters() &&
+        target_function.AreValidArgumentCounts(call->ArgumentCount(), 0,
+                                               &error_message)) {
+      const intptr_t cid = Class::Handle(Z, target_function.Owner()).id();
+      const ICData& ic_data = ICData::ZoneHandle(Z,
+          ICData::NewFrom(*call->ic_data(), 1));
+      ic_data.AddReceiverCheck(cid, target_function);
+      call->set_ic_data(&ic_data);
+      return true;
+    }
+  }
+
   // Check if getter or setter in function's class and class is currently leaf.
-  if ((call->token_kind() == Token::kGET) ||
-      (call->token_kind() == Token::kSET)) {
+  // Do not run the optimization below if in background compilation since
+  // resolution of getter functions may create new signature classes.
+  // TODO(regis): Remove test for background compilation once signature classes
+  // are not generated any longer.
+  if (thread()->IsMutatorThread() &&
+      FLAG_guess_icdata_cid &&
+      ((call->token_kind() == Token::kGET) ||
+          (call->token_kind() == Token::kSET))) {
     const Class& owner_class = Class::Handle(Z, function().Owner());
     if (!owner_class.is_abstract() &&
         !CHA::HasSubclasses(owner_class) &&
@@ -270,14 +304,13 @@
           Resolver::ResolveDynamicForReceiverClass(owner_class,
                                                    call->function_name(),
                                                    args_desc));
-      if (function.IsNull()) {
-        return false;
+      if (!function.IsNull()) {
+        const ICData& ic_data = ICData::ZoneHandle(Z,
+            ICData::NewFrom(*call->ic_data(), class_ids.length()));
+        ic_data.AddReceiverCheck(owner_class.id(), function);
+        call->set_ic_data(&ic_data);
+        return true;
       }
-      const ICData& ic_data = ICData::ZoneHandle(Z,
-          ICData::NewFrom(*call->ic_data(), class_ids.length()));
-      ic_data.AddReceiverCheck(owner_class.id(), function);
-      call->set_ic_data(&ic_data);
-      return true;
     }
   }
 
@@ -299,7 +332,7 @@
   // not found in the ICData.
   if (!function.IsNull()) {
     const ICData& new_ic_data = ICData::ZoneHandle(Z, ICData::New(
-        Function::Handle(Z, ic_data.owner()),
+        Function::Handle(Z, ic_data.Owner()),
         String::Handle(Z, ic_data.target_name()),
         Object::empty_array(),  // Dummy argument descriptor.
         ic_data.deopt_id(),
@@ -724,12 +757,12 @@
              (to == kUnboxedDouble) &&
              CanConvertUnboxedMintToDouble()) {
     const intptr_t deopt_id = (deopt_target != NULL) ?
-      deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
     ASSERT(CanUnboxDouble());
     converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id);
   } else if ((from == kTagged) && Boxing::Supports(to)) {
     const intptr_t deopt_id = (deopt_target != NULL) ?
-      deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
     converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id);
   } else if ((to == kTagged) && Boxing::Supports(from)) {
     converted = BoxInstr::Create(from, use->CopyWithType());
@@ -739,7 +772,7 @@
     // "from" and "to" representation. The inserted instructions will
     // trigger a deoptimization if executed. See #12417 for a discussion.
     const intptr_t deopt_id = (deopt_target != NULL) ?
-      deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
     ASSERT(Boxing::Supports(from));
     ASSERT(Boxing::Supports(to));
     Definition* boxed = BoxInstr::Create(from, use->CopyWithType());
@@ -963,12 +996,11 @@
   if (ic_data.NumArgsTested() != 2) {
     return false;
   }
-  Function& target = Function::Handle();
   const intptr_t len = ic_data.NumberOfChecks();
   GrowableArray<intptr_t> class_ids;
   for (intptr_t i = 0; i < len; i++) {
     if (ic_data.IsUsedAt(i)) {
-      ic_data.GetCheckAt(i, &class_ids, &target);
+      ic_data.GetClassIdsAt(i, &class_ids);
       ASSERT(class_ids.length() == 2);
       if (!ClassIdIsOneOf(class_ids[0], receiver_class_ids) ||
           !ClassIdIsOneOf(class_ids[1], argument_class_ids)) {
@@ -986,12 +1018,11 @@
   if (ic_data.NumArgsTested() != 2) {
     return false;
   }
-  Function& target = Function::Handle();
   const intptr_t len = ic_data.NumberOfChecks();
   for (intptr_t i = 0; i < len; i++) {
     if (ic_data.IsUsedAt(i)) {
       GrowableArray<intptr_t> class_ids;
-      ic_data.GetCheckAt(i, &class_ids, &target);
+      ic_data.GetClassIdsAt(i, &class_ids);
       ASSERT(class_ids.length() == 2);
       if ((class_ids[0] == receiver_class_id) &&
           (class_ids[1] == argument_class_id)) {
@@ -1285,7 +1316,6 @@
     // the index is not a smi.
     const AbstractType& value_type =
         AbstractType::ZoneHandle(Z, target.ParameterTypeAt(2));
-    Definition* instantiator = NULL;
     Definition* type_args = NULL;
     switch (array_cid) {
       case kArrayCid:
@@ -1303,7 +1333,6 @@
                                         NULL,
                                         FlowGraph::kValue);
 
-        instantiator = array;
         type_args = load_type_args;
         break;
       }
@@ -1321,7 +1350,7 @@
         // Fall through.
       case kTypedDataFloat32ArrayCid:
       case kTypedDataFloat64ArrayCid: {
-        type_args = instantiator = flow_graph_->constant_null();
+        type_args = flow_graph_->constant_null();
         ASSERT((array_cid != kTypedDataFloat32ArrayCid &&
                 array_cid != kTypedDataFloat64ArrayCid) ||
                value_type.IsDoubleType());
@@ -1329,14 +1358,14 @@
         break;
       }
       case kTypedDataFloat32x4ArrayCid: {
-        type_args = instantiator = flow_graph_->constant_null();
+        type_args = flow_graph_->constant_null();
         ASSERT((array_cid != kTypedDataFloat32x4ArrayCid) ||
                value_type.IsFloat32x4Type());
         ASSERT(value_type.IsInstantiated());
         break;
       }
       case kTypedDataFloat64x2ArrayCid: {
-        type_args = instantiator = flow_graph_->constant_null();
+        type_args = flow_graph_->constant_null();
         ASSERT((array_cid != kTypedDataFloat64x2ArrayCid) ||
                value_type.IsFloat64x2Type());
         ASSERT(value_type.IsInstantiated());
@@ -1349,7 +1378,6 @@
     AssertAssignableInstr* assert_value =
         new(Z) AssertAssignableInstr(token_pos,
                                      new(Z) Value(stored_value),
-                                     new(Z) Value(instantiator),
                                      new(Z) Value(type_args),
                                      value_type,
                                      Symbols::Value(),
@@ -1709,7 +1737,7 @@
         new(Z) LoadFieldInstr(
             new(Z) Value(*array),
             GrowableObjectArray::data_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             call->token_pos());
     elements->set_result_cid(kArrayCid);
     *cursor = flow_graph()->AppendTo(*cursor,
@@ -2328,7 +2356,7 @@
 // callee functions, then no class check is needed.
 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck(
     InstanceCallInstr* call, RawFunction::Kind kind) const {
-  if (!FLAG_use_cha_deopt) {
+  if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) {
     // Even if class or function are private, lazy class finalization
     // may later add overriding methods.
     return true;
@@ -2362,9 +2390,8 @@
   ASSERT(call->HasICData());
   const ICData& ic_data = *call->ic_data();
   ASSERT(ic_data.HasOneTarget());
-  Function& target = Function::Handle(Z);
   GrowableArray<intptr_t> class_ids;
-  ic_data.GetCheckAt(0, &class_ids, &target);
+  ic_data.GetClassIdsAt(0, &class_ids);
   ASSERT(class_ids.length() == 1);
   // Inline implicit instance getter.
   const String& field_name =
@@ -3072,74 +3099,7 @@
 
   if (IsSupportedByteArrayViewCid(class_ids[0]) &&
       (ic_data.NumberOfChecks() == 1)) {
-    // For elements that may not fit into a smi on all platforms, check if
-    // elements fit into a smi or the platform supports unboxed mints.
-    if ((recognized_kind == MethodRecognizer::kByteArrayBaseGetInt32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseGetUint32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseSetInt32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseSetUint32)) {
-      if (!CanUnboxInt32()) {
-        return false;
-      }
-    }
-
-    if ((recognized_kind == MethodRecognizer::kByteArrayBaseGetFloat32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseGetFloat64) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseSetFloat32) ||
-        (recognized_kind == MethodRecognizer::kByteArrayBaseSetFloat64)) {
-      if (!CanUnboxDouble()) {
-        return false;
-      }
-    }
-
-    switch (recognized_kind) {
-      // ByteArray getters.
-      case MethodRecognizer::kByteArrayBaseGetInt8:
-        return BuildByteArrayBaseLoad(call, kTypedDataInt8ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetUint8:
-        return BuildByteArrayBaseLoad(call, kTypedDataUint8ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetInt16:
-        return BuildByteArrayBaseLoad(call, kTypedDataInt16ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetUint16:
-        return BuildByteArrayBaseLoad(call, kTypedDataUint16ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetInt32:
-        return BuildByteArrayBaseLoad(call, kTypedDataInt32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetUint32:
-        return BuildByteArrayBaseLoad(call, kTypedDataUint32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetFloat32:
-        return BuildByteArrayBaseLoad(call, kTypedDataFloat32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetFloat64:
-        return BuildByteArrayBaseLoad(call, kTypedDataFloat64ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetFloat32x4:
-        return BuildByteArrayBaseLoad(call, kTypedDataFloat32x4ArrayCid);
-      case MethodRecognizer::kByteArrayBaseGetInt32x4:
-        return BuildByteArrayBaseLoad(call, kTypedDataInt32x4ArrayCid);
-
-      // ByteArray setters.
-      case MethodRecognizer::kByteArrayBaseSetInt8:
-        return BuildByteArrayBaseStore(call, kTypedDataInt8ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetUint8:
-        return BuildByteArrayBaseStore(call, kTypedDataUint8ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetInt16:
-        return BuildByteArrayBaseStore(call, kTypedDataInt16ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetUint16:
-        return BuildByteArrayBaseStore(call, kTypedDataUint16ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetInt32:
-        return BuildByteArrayBaseStore(call, kTypedDataInt32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetUint32:
-        return BuildByteArrayBaseStore(call, kTypedDataUint32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetFloat32:
-        return BuildByteArrayBaseStore(call, kTypedDataFloat32ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetFloat64:
-        return BuildByteArrayBaseStore(call, kTypedDataFloat64ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetFloat32x4:
-        return BuildByteArrayBaseStore(call, kTypedDataFloat32x4ArrayCid);
-      case MethodRecognizer::kByteArrayBaseSetInt32x4:
-        return BuildByteArrayBaseStore(call, kTypedDataInt32x4ArrayCid);
-      default:
-        // Unsupported method.
-        return false;
-    }
+    return TryReplaceInstanceCallWithInline(call);
   }
 
   if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
@@ -3932,38 +3892,6 @@
 }
 
 
-bool FlowGraphOptimizer::BuildByteArrayBaseLoad(InstanceCallInstr* call,
-                                                intptr_t view_cid) {
-  const bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
-                         (view_cid == kTypedDataInt32x4ArrayCid);
-  const bool float_view = (view_cid == kTypedDataFloat32ArrayCid) ||
-                          (view_cid == kTypedDataFloat64ArrayCid);
-  if (float_view && !CanUnboxDouble()) {
-    return false;
-  }
-  if (simd_view && !ShouldInlineSimd()) {
-    return false;
-  }
-  return TryReplaceInstanceCallWithInline(call);
-}
-
-
-bool FlowGraphOptimizer::BuildByteArrayBaseStore(InstanceCallInstr* call,
-                                                 intptr_t view_cid) {
-  const bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
-                         (view_cid == kTypedDataInt32x4ArrayCid);
-  const bool float_view = (view_cid == kTypedDataFloat32ArrayCid) ||
-                          (view_cid == kTypedDataFloat64ArrayCid);
-  if (float_view && !CanUnboxDouble()) {
-    return false;
-  }
-  if (simd_view && !ShouldInlineSimd()) {
-    return false;
-  }
-  return TryReplaceInstanceCallWithInline(call);
-}
-
-
 // If type tests specified by 'ic_data' do not depend on type arguments,
 // return mapping cid->result in 'results' (i : cid; i + 1: result).
 // If all tests yield the same result, return it otherwise return Bool::null.
@@ -4043,13 +3971,15 @@
 
   // Private classes cannot be subclassed by later loaded libs.
   if (!type_class.IsPrivate()) {
-    if (FLAG_use_cha_deopt) {
+    if (FLAG_use_cha_deopt || isolate()->all_classes_finalized()) {
       if (FLAG_trace_cha) {
         THR_Print("  **(CHA) Typecheck as class equality since no "
             "subclasses: %s\n",
             type_class.ToCString());
       }
-      thread()->cha()->AddToLeafClasses(type_class);
+      if (FLAG_use_cha_deopt) {
+        thread()->cha()->AddToLeafClasses(type_class);
+      }
     } else {
       return false;
     }
@@ -4131,12 +4061,10 @@
 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
   ASSERT(Token::IsTypeTestOperator(call->token_kind()));
   Definition* left = call->ArgumentAt(0);
-  Definition* instantiator = NULL;
   Definition* type_args = NULL;
   AbstractType& type = AbstractType::ZoneHandle(Z);
   bool negate = false;
   if (call->ArgumentCount() == 2) {
-    instantiator = flow_graph()->constant_null();
     type_args = flow_graph()->constant_null();
     if (call->function_name().raw() ==
         Library::PrivateCoreLibName(Symbols::_instanceOfNum()).raw()) {
@@ -4159,10 +4087,9 @@
     negate = Bool::Cast(call->ArgumentAt(1)->OriginalDefinition()
         ->AsConstant()->value()).value();
   } else {
-    instantiator = call->ArgumentAt(1);
-    type_args = call->ArgumentAt(2);
-    type = AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()).raw();
-    negate = Bool::Cast(call->ArgumentAt(4)->OriginalDefinition()
+    type_args = call->ArgumentAt(1);
+    type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw();
+    negate = Bool::Cast(call->ArgumentAt(3)->OriginalDefinition()
         ->AsConstant()->value()).value();
   }
   const ICData& unary_checks =
@@ -4239,7 +4166,6 @@
   InstanceOfInstr* instance_of =
       new(Z) InstanceOfInstr(call->token_pos(),
                              new(Z) Value(left),
-                             new(Z) Value(instantiator),
                              new(Z) Value(type_args),
                              type,
                              negate,
@@ -4252,10 +4178,9 @@
 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) {
   ASSERT(Token::IsTypeCastOperator(call->token_kind()));
   Definition* left = call->ArgumentAt(0);
-  Definition* instantiator = call->ArgumentAt(1);
-  Definition* type_args = call->ArgumentAt(2);
+  Definition* type_args = call->ArgumentAt(1);
   const AbstractType& type =
-      AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value());
+      AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value());
   ASSERT(!type.IsMalformedOrMalbounded());
   const ICData& unary_checks =
       ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks());
@@ -4294,7 +4219,6 @@
   AssertAssignableInstr* assert_as =
       new(Z) AssertAssignableInstr(call->token_pos(),
                                    new(Z) Value(left),
-                                   new(Z) Value(instantiator),
                                    new(Z) Value(type_args),
                                    type,
                                    dst_name,
@@ -4303,23 +4227,20 @@
 }
 
 
+bool FlowGraphOptimizer::IsBlackListedForInlining(intptr_t call_deopt_id) {
+  for (intptr_t i = 0; i < inlining_black_list_->length(); ++i) {
+    if ((*inlining_black_list_)[i] == call_deopt_id) return true;
+  }
+  return false;
+}
+
 // Special optimizations when running in --noopt mode.
 void FlowGraphOptimizer::InstanceCallNoopt(InstanceCallInstr* instr) {
   // TODO(srdjan): Investigate other attempts, as they are not allowed to
   // deoptimize.
-  const Token::Kind op_kind = instr->token_kind();
-  if (instr->HasICData() && (instr->ic_data()->NumberOfUsedChecks() > 0)) {
-    const ICData& unary_checks =
-        ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
-
-    PolymorphicInstanceCallInstr* call =
-        new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
-                                            true /* call_with_checks*/);
-    instr->ReplaceWith(call, current_iterator());
-    return;
-  }
 
   // Type test is special as it always gets converted into inlined code.
+  const Token::Kind op_kind = instr->token_kind();
   if (Token::IsTypeTestOperator(op_kind)) {
     ReplaceWithInstanceOf(instr);
     return;
@@ -4328,6 +4249,126 @@
     ReplaceWithTypeCast(instr);
     return;
   }
+
+  if ((op_kind == Token::kGET) &&
+      TryInlineInstanceGetter(instr, false /* no checks allowed */)) {
+    return;
+  }
+  const ICData& unary_checks =
+      ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
+  if ((unary_checks.NumberOfChecks() > 0) &&
+      (op_kind == Token::kSET) &&
+      TryInlineInstanceSetter(instr, unary_checks, false /* no checks */)) {
+    return;
+  }
+
+  if (use_speculative_inlining_ &&
+      !IsBlackListedForInlining(instr->deopt_id()) &&
+      (unary_checks.NumberOfChecks() > 0)) {
+    if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) {
+      return;
+    }
+    if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) {
+      return;
+    }
+    if ((op_kind == Token::kEQ) && TryReplaceWithEqualityOp(instr, op_kind)) {
+      return;
+    }
+
+    if (Token::IsRelationalOperator(op_kind) &&
+        TryReplaceWithRelationalOp(instr, op_kind)) {
+      return;
+    }
+
+    if (Token::IsBinaryOperator(op_kind) &&
+        TryReplaceWithBinaryOp(instr, op_kind)) {
+      return;
+    }
+    if (Token::IsUnaryOperator(op_kind) &&
+        TryReplaceWithUnaryOp(instr, op_kind)) {
+      return;
+    }
+  }
+
+  bool has_one_target =
+      (unary_checks.NumberOfChecks() > 0) && unary_checks.HasOneTarget();
+  if (has_one_target) {
+    // Check if the single target is a polymorphic target, if it is,
+    // we don't have one target.
+    const Function& target =
+        Function::Handle(Z, unary_checks.GetTargetAt(0));
+    const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target);
+    has_one_target = !polymorphic_target;
+  }
+
+  if (has_one_target) {
+    RawFunction::Kind function_kind =
+        Function::Handle(Z, unary_checks.GetTargetAt(0)).kind();
+    if (!InstanceCallNeedsClassCheck(instr, function_kind)) {
+      PolymorphicInstanceCallInstr* call =
+          new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
+                                              /* with_checks = */ false);
+      instr->ReplaceWith(call, current_iterator());
+      return;
+    }
+  }
+
+  // More than one targets. Generate generic polymorphic call without
+  // deoptimization.
+  if (instr->ic_data()->NumberOfUsedChecks() > 0) {
+    ASSERT(!FLAG_polymorphic_with_deopt);
+    // OK to use checks with PolymorphicInstanceCallInstr since no
+    // deoptimization is allowed.
+    PolymorphicInstanceCallInstr* call =
+        new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
+                                            /* with_checks = */ true);
+    instr->ReplaceWith(call, current_iterator());
+    return;
+  }
+
+  // No IC data checks. Try resolve target using the propagated type.
+  // If the propagated type has a method with the target name and there are
+  // no overrides with that name according to CHA, call the method directly.
+  const intptr_t receiver_cid =
+      instr->PushArgumentAt(0)->value()->Type()->ToCid();
+  if (receiver_cid == kDynamicCid) return;
+  const Class& receiver_class = Class::Handle(Z,
+      isolate()->class_table()->At(receiver_cid));
+
+  const Array& args_desc_array = Array::Handle(Z,
+      ArgumentsDescriptor::New(instr->ArgumentCount(),
+                               instr->argument_names()));
+  ArgumentsDescriptor args_desc(args_desc_array);
+  const Function& function = Function::Handle(Z,
+      Resolver::ResolveDynamicForReceiverClass(
+          receiver_class,
+          instr->function_name(),
+          args_desc));
+  if (function.IsNull()) {
+    return;
+  }
+  if (!thread()->cha()->HasOverride(receiver_class, instr->function_name())) {
+    if (FLAG_trace_cha) {
+      THR_Print("  **(CHA) Instance call needs no check, "
+          "no overrides of '%s' '%s'\n",
+          instr->function_name().ToCString(), receiver_class.ToCString());
+    }
+    thread()->cha()->AddToLeafClasses(receiver_class);
+
+    // Create fake IC data with the resolved target.
+    const ICData& ic_data = ICData::Handle(
+        ICData::New(flow_graph_->function(),
+                    instr->function_name(),
+                    args_desc_array,
+                    Thread::kNoDeoptId,
+                    /* args_tested = */ 1));
+    ic_data.AddReceiverCheck(receiver_class.id(), function);
+    PolymorphicInstanceCallInstr* call =
+        new(Z) PolymorphicInstanceCallInstr(instr, ic_data,
+                                            /* with_checks = */ false);
+    instr->ReplaceWith(call, current_iterator());
+    return;
+  }
 }
 
 
@@ -4418,10 +4459,9 @@
     RawFunction::Kind function_kind =
         Function::Handle(Z, unary_checks.GetTargetAt(0)).kind();
     if (!InstanceCallNeedsClassCheck(instr, function_kind)) {
-      const bool call_with_checks = false;
       PolymorphicInstanceCallInstr* call =
           new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
-                                              call_with_checks);
+                                              /* call_with_checks = */ false);
       instr->ReplaceWith(call, current_iterator());
       return;
     }
@@ -4639,7 +4679,14 @@
         }
       }
       field.set_is_unboxing_candidate(false);
-      field.DeoptimizeDependentCode();
+      if (Compiler::IsBackgroundCompilation()) {
+        // Delay deoptimization of dependent code to the code installation time.
+        // The invalidation of the background compilation result occurs only
+        // when the deoptimization is triggered at code installation.
+        flow_graph()->deoptimize_dependent_code().Add(&field);
+      } else {
+        field.DeoptimizeDependentCode();
+      }
     } else {
       FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
     }
@@ -4692,7 +4739,8 @@
 
 
 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr,
-                                                 const ICData& unary_ic_data) {
+                                                 const ICData& unary_ic_data,
+                                                 bool allow_checks) {
   ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
       (unary_ic_data.NumArgsTested() == 1));
   if (I->flags().type_checks()) {
@@ -4726,9 +4774,15 @@
   ASSERT(!field.IsNull());
 
   if (InstanceCallNeedsClassCheck(instr, RawFunction::kImplicitSetter)) {
+    if (!allow_checks) {
+      return false;
+    }
     AddReceiverCheck(instr);
   }
   if (field.guarded_cid() != kDynamicCid) {
+    if (!allow_checks) {
+      return false;
+    }
     InsertBefore(instr,
                  new(Z) GuardFieldClassInstr(
                      new(Z) Value(instr->ArgumentAt(1)),
@@ -4739,6 +4793,9 @@
   }
 
   if (field.needs_length_check()) {
+    if (!allow_checks) {
+      return false;
+    }
     InsertBefore(instr,
                  new(Z) GuardFieldLengthInstr(
                      new(Z) Value(instr->ArgumentAt(1)),
@@ -4807,6 +4864,7 @@
          instr_it.Advance()) {
       BinarySmiOpInstr* smi_op = instr_it.Current()->AsBinarySmiOp();
       if ((smi_op != NULL) &&
+          smi_op->HasSSATemp() &&
           BenefitsFromWidening(smi_op) &&
           CanBeWidened(smi_op)) {
         candidates.Add(smi_op);
@@ -5179,8 +5237,11 @@
 
 
 void LICM::OptimisticallySpecializeSmiPhis() {
-  if (!flow_graph()->function().allows_hoisting_check_class()) {
-    // Do not hoist any.
+  if (!flow_graph()->function().allows_hoisting_check_class() ||
+      Compiler::always_optimize()) {
+    // Do not hoist any: Either deoptimized on a hoisted check,
+    // or compiling precompiled code where we can't do optimistic
+    // hoisting of checks.
     return;
   }
 
@@ -5620,8 +5681,13 @@
     return "<?>";
   }
 
-  bool IsFinalField() const {
-    return (kind() == kField) && field().is_final();
+  // Fields that are considered immutable by load optimization.
+  // Handle static finals as non-final with precompilation because
+  // they may be reset to uninitialized after compilation.
+  bool IsImmutableField() const {
+    return (kind() == kField)
+        && field().is_final()
+        && (!field().is_static() || !FLAG_fields_may_be_reset);
   }
 
   intptr_t Hashcode() const {
@@ -5958,7 +6024,7 @@
 
   // Compute least generic alias for the place and assign alias id to it.
   void AddRepresentative(Place* place) {
-    if (!place->IsFinalField()) {
+    if (!place->IsImmutableField()) {
       const Place* alias = CanonicalizeAlias(place->ToAlias());
       EnsureSet(&representatives_, alias->id())->Add(place->id());
 
@@ -6164,7 +6230,7 @@
   // This essentially means that no stores to the same location can
   // occur in other functions.
   bool IsIndependentFromEffects(Place* place) {
-    if (place->IsFinalField()) {
+    if (place->IsImmutableField()) {
       // Note that we can't use LoadField's is_immutable attribute here because
       // some VM-fields (those that have no corresponding Field object and
       // accessed through offset alone) can share offset but have different
@@ -6598,7 +6664,7 @@
               aliased_set_->LookupAliasId(place.ToAlias());
           if (alias_id != AliasedSet::kNoAlias) {
             killed = aliased_set_->GetKilledSet(alias_id);
-          } else if (!place.IsFinalField()) {
+          } else if (!place.IsImmutableField()) {
             // We encountered unknown alias: this means intrablock load
             // forwarding refined parameter of this store, for example
             //
@@ -7502,7 +7568,7 @@
         bool is_load = false;
         bool is_store = false;
         Place place(instr, &is_load, &is_store);
-        if (place.IsFinalField()) {
+        if (place.IsImmutableField()) {
           // Loads/stores of final fields do not participate.
           continue;
         }
@@ -7591,7 +7657,7 @@
         bool is_store = false;
         Place place(instr, &is_load, &is_store);
         ASSERT(!is_load && is_store);
-        if (place.IsFinalField()) {
+        if (place.IsImmutableField()) {
           // Final field do not participate in dead store elimination.
           continue;
         }
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index d0ae717..9d500aa 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -16,9 +16,16 @@
 
 class FlowGraphOptimizer : public FlowGraphVisitor {
  public:
-  explicit FlowGraphOptimizer(FlowGraph* flow_graph)
+  FlowGraphOptimizer(
+      FlowGraph* flow_graph,
+      bool use_speculative_inlining,
+      GrowableArray<intptr_t>* inlining_black_list)
       : FlowGraphVisitor(flow_graph->reverse_postorder()),
-        flow_graph_(flow_graph) { }
+        flow_graph_(flow_graph),
+        use_speculative_inlining_(use_speculative_inlining),
+        inlining_black_list_(inlining_black_list) {
+    ASSERT(!use_speculative_inlining || (inlining_black_list != NULL));
+  }
   virtual ~FlowGraphOptimizer() {}
 
   FlowGraph* flow_graph() const { return flow_graph_; }
@@ -115,7 +122,8 @@
   bool TryInlineInstanceGetter(InstanceCallInstr* call,
                                bool allow_check = true);
   bool TryInlineInstanceSetter(InstanceCallInstr* call,
-                               const ICData& unary_ic_data);
+                               const ICData& unary_ic_data,
+                               bool allow_check = true);
 
   bool TryInlineInstanceMethod(InstanceCallInstr* call);
   bool TryInlineFloat32x4Constructor(StaticCallInstr* call,
@@ -181,11 +189,6 @@
                                         Definition* index,
                                         Instruction** cursor);
 
-  bool BuildByteArrayBaseLoad(InstanceCallInstr* call,
-                              intptr_t view_cid);
-  bool BuildByteArrayBaseStore(InstanceCallInstr* call,
-                               intptr_t view_cid);
-
   // Insert a check of 'to_check' determined by 'unary_checks'.  If the
   // check fails it will deoptimize to 'deopt_id' using the deoptimization
   // environment 'deopt_environment'.  The check is inserted immediately
@@ -268,8 +271,14 @@
 
   const Function& function() const { return flow_graph_->function(); }
 
+  bool IsBlackListedForInlining(intptr_t deopt_id);
+
   FlowGraph* flow_graph_;
 
+  const bool use_speculative_inlining_;
+
+  GrowableArray<intptr_t>* inlining_black_list_;
+
   DISALLOW_COPY_AND_ASSIGN(FlowGraphOptimizer);
 };
 
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 35a7a5d..16cf90c 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -5,6 +5,7 @@
 #include "vm/flow_graph_range_analysis.h"
 
 #include "vm/bit_vector.h"
+#include "vm/compiler.h"
 #include "vm/il_printer.h"
 
 namespace dart {
@@ -1528,8 +1529,12 @@
 void RangeAnalysis::EliminateRedundantBoundsChecks() {
   if (FLAG_array_bounds_check_elimination) {
     const Function& function = flow_graph_->function();
+    // Generalization only if we have not deoptimized on a generalized
+    // check earlier, or we're compiling precompiled code (no
+    // optimistic hoisting of checks possible)
     const bool try_generalization =
-        function.allows_bounds_check_generalization();
+        function.allows_bounds_check_generalization() &&
+        !Compiler::always_optimize();
 
     BoundsCheckGeneralizer generalizer(this, flow_graph_);
 
@@ -3126,14 +3131,7 @@
     return false;
   }
 
-  RangeBoundary max = CanonicalizeBoundary(
-      RangeBoundary::FromDefinition(index()->definition()),
-      RangeBoundary::PositiveInfinity());
-
-  if (max.OverflowedSmi()) {
-    return false;
-  }
-
+  RangeBoundary max = RangeBoundary::FromDefinition(index()->definition());
 
   RangeBoundary max_upper = max.UpperBound();
   RangeBoundary length_lower = length.LowerBound();
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 29ec735..7ea528a 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -17,9 +17,16 @@
 DECLARE_FLAG(bool, propagate_types);
 DECLARE_FLAG(bool, trace_cha);
 DECLARE_FLAG(bool, use_cha_deopt);
+DECLARE_FLAG(bool, fields_may_be_reset);
 
 
 void FlowGraphTypePropagator::Propagate(FlowGraph* flow_graph) {
+  Thread* thread = flow_graph->thread();
+  Isolate* const isolate = flow_graph->isolate();
+  TimelineStream* compiler_timeline = isolate->GetCompilerStream();
+  TimelineDurationScope tds2(thread,
+                             compiler_timeline,
+                             "FlowGraphTypePropagator");
   FlowGraphTypePropagator propagator(flow_graph);
   propagator.Propagate();
 }
@@ -412,7 +419,7 @@
   // Nothing to do.
   } else {
   // Can't unify.
-  type_ = &Type::ZoneHandle(Type::DynamicType());
+  type_ = &Object::dynamic_type();
   }
 }
 
@@ -440,7 +447,7 @@
 
 
 CompileType CompileType::Dynamic() {
-  return Create(kDynamicCid, Type::ZoneHandle(Type::DynamicType()));
+  return Create(kDynamicCid, Object::dynamic_type());
 }
 
 
@@ -484,7 +491,8 @@
       cid_ = kNullCid;
     } else if (type_->HasResolvedTypeClass()) {
       const Class& type_class = Class::Handle(type_->type_class());
-      CHA* cha = Thread::Current()->cha();
+      Thread* thread = Thread::Current();
+      CHA* cha = thread->cha();
       // Don't infer a cid from an abstract type for signature classes since
       // there can be multiple compatible classes with different cids.
       if (!type_class.IsSignatureClass() &&
@@ -493,12 +501,15 @@
         if (type_class.IsPrivate()) {
           // Type of a private class cannot change through later loaded libs.
           cid_ = type_class.id();
-        } else if (FLAG_use_cha_deopt) {
+        } else if (FLAG_use_cha_deopt ||
+                   thread->isolate()->all_classes_finalized()) {
           if (FLAG_trace_cha) {
             THR_Print("  **(CHA) Compile type not subclassed: %s\n",
                 type_class.ToCString());
           }
-          cha->AddToLeafClasses(type_class);
+          if (FLAG_use_cha_deopt) {
+            cha->AddToLeafClasses(type_class);
+          }
           cid_ = type_class.id();
         } else {
           cid_ = kDynamicCid;
@@ -527,12 +538,16 @@
 
 const AbstractType* CompileType::ToAbstractType() {
   if (type_ == NULL) {
-    ASSERT(cid_ != kIllegalCid);
+    // Type propagation has not run. Return dynamic-type.
+    if (cid_ == kIllegalCid) {
+      type_ = &Object::dynamic_type();
+      return type_;
+    }
 
     // VM-internal objects don't have a compile-type. Return dynamic-type
     // in this case.
     if (cid_ < kInstanceCid) {
-      type_ = &Type::ZoneHandle(Type::DynamicType());
+      type_ = &Object::dynamic_type();
       return type_;
     }
 
@@ -540,7 +555,7 @@
         Class::Handle(Isolate::Current()->class_table()->At(cid_));
 
     if (type_class.NumTypeArguments() > 0) {
-      type_ = &Type::ZoneHandle(Type::DynamicType());
+      type_ = &Object::dynamic_type();
       return type_;
     }
 
@@ -680,7 +695,7 @@
   // verifying the run time type of the passed-in parameter and this check would
   // always be wrongly eliminated.
   // However there are parameters that are known to match their declared type:
-  // for example receiver and construction phase.
+  // for example receiver.
   GraphEntryInstr* graph_entry = block_->AsGraphEntry();
   // Parameters at catch blocks and OSR entries have type dynamic.
   //
@@ -712,11 +727,6 @@
   LocalScope* scope = graph_entry->parsed_function().node_sequence()->scope();
   const AbstractType& type = scope->VariableAt(index())->type();
 
-  // Parameter is the constructor phase.
-  if ((index() == 1) && function.IsGenerativeConstructor()) {
-    return CompileType::FromAbstractType(type, CompileType::kNonNullable);
-  }
-
   // Parameter is the receiver.
   if ((index() == 0) &&
       (function.IsDynamicFunction() || function.IsGenerativeConstructor())) {
@@ -736,13 +746,16 @@
           // Private classes can never be subclassed by later loaded libs.
           cid = type_class.id();
         } else {
-          if (FLAG_use_cha_deopt) {
+          if (FLAG_use_cha_deopt ||
+              thread->isolate()->all_classes_finalized()) {
             if (FLAG_trace_cha) {
-              THR_Print("  **(CHA) Computing exact type of parameters, "
+              THR_Print("  **(CHA) Computing exact type of receiver, "
                   "no subclasses: %s\n",
                   type_class.ToCString());
             }
-            thread->cha()->AddToLeafClasses(type_class);
+            if (FLAG_use_cha_deopt) {
+              thread->cha()->AddToLeafClasses(type_class);
+            }
             cid = type_class.id();
           }
         }
@@ -847,28 +860,28 @@
 CompileType CurrentContextInstr::ComputeType() const {
   return CompileType(CompileType::kNonNullable,
                      kContextCid,
-                     &AbstractType::ZoneHandle(Type::DynamicType()));
+                     &Object::dynamic_type());
 }
 
 
 CompileType CloneContextInstr::ComputeType() const {
   return CompileType(CompileType::kNonNullable,
                      kContextCid,
-                     &AbstractType::ZoneHandle(Type::DynamicType()));
+                     &Object::dynamic_type());
 }
 
 
 CompileType AllocateContextInstr::ComputeType() const {
   return CompileType(CompileType::kNonNullable,
                      kContextCid,
-                     &AbstractType::ZoneHandle(Type::DynamicType()));
+                     &Object::dynamic_type());
 }
 
 
 CompileType AllocateUninitializedContextInstr::ComputeType() const {
   return CompileType(CompileType::kNonNullable,
                      kContextCid,
-                     &AbstractType::ZoneHandle(Type::DynamicType()));
+                     &Object::dynamic_type());
 }
 
 
@@ -941,7 +954,7 @@
     abstract_type = &AbstractType::ZoneHandle(field.type());
   }
   ASSERT(field.is_static());
-  if (field.is_final()) {
+  if (field.is_final() && !FLAG_fields_may_be_reset) {
     const Instance& obj = Instance::Handle(field.StaticValue());
     if ((obj.raw() != Object::sentinel().raw()) &&
         (obj.raw() != Object::transition_sentinel().raw()) &&
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index 2e63be3..1638b3d 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -18,6 +18,7 @@
 #include "vm/store_buffer.h"
 #include "vm/thread_barrier.h"
 #include "vm/thread_pool.h"
+#include "vm/thread_registry.h"
 #include "vm/visitor.h"
 #include "vm/object_id_ring.h"
 
@@ -484,7 +485,7 @@
   if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
     (isolate->gc_prologue_callback())();
   }
-  Thread::PrepareForGC();
+  isolate->thread_registry()->PrepareForGC();
   // The store buffers will be rebuilt as part of marking, reset them now.
   isolate->store_buffer()->Reset();
 }
@@ -499,12 +500,10 @@
 
 void GCMarker::IterateRoots(Isolate* isolate,
                             ObjectPointerVisitor* visitor,
-                            bool visit_prologue_weak_persistent_handles,
                             intptr_t slice_index, intptr_t num_slices) {
   ASSERT(0 <= slice_index && slice_index < num_slices);
   if ((slice_index == 0) || (num_slices <= 1)) {
     isolate->VisitObjectPointers(visitor,
-                                 visit_prologue_weak_persistent_handles,
                                  StackFrameIterator::kDontValidateFrames);
   }
   if ((slice_index == 1) || (num_slices <= 1)) {
@@ -516,73 +515,10 @@
 }
 
 
-void GCMarker::IterateWeakRoots(Isolate* isolate,
-                                HandleVisitor* visitor,
-                                bool visit_prologue_weak_persistent_handles) {
+void GCMarker::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) {
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
-  isolate->VisitWeakPersistentHandles(visitor,
-                                      visit_prologue_weak_persistent_handles);
-}
-
-
-template<class MarkingVisitorType>
-void GCMarker::IterateWeakReferences(Isolate* isolate,
-                                     MarkingVisitorType* visitor) {
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
-  while (true) {
-    WeakReferenceSet* queue = state->delayed_weak_reference_sets();
-    if (queue == NULL) {
-      // The delay queue is empty therefore no clean-up is required.
-      return;
-    }
-    state->set_delayed_weak_reference_sets(NULL);
-    while (queue != NULL) {
-      WeakReferenceSet* reference_set = WeakReferenceSet::Pop(&queue);
-      ASSERT(reference_set != NULL);
-      intptr_t num_keys = reference_set->num_keys();
-      intptr_t num_values = reference_set->num_values();
-      if ((num_keys == 1) && (num_values == 1) &&
-          reference_set->SingletonKeyEqualsValue()) {
-        // We do not have to process sets that have just one key/value pair
-        // and the key and value are identical.
-        continue;
-      }
-      bool is_unreachable = true;
-      // Test each key object for reachability.  If a key object is
-      // reachable, all value objects should be marked.
-      for (intptr_t k = 0; k < num_keys; ++k) {
-        if (!IsUnreachable(*reference_set->get_key(k))) {
-          for (intptr_t v = 0; v < num_values; ++v) {
-            visitor->VisitPointer(reference_set->get_value(v));
-          }
-          is_unreachable = false;
-          // Since we have found a key object that is reachable and all
-          // value objects have been marked we can break out of iterating
-          // this set and move on to the next set.
-          break;
-        }
-      }
-      // If all key objects are unreachable put the reference on a
-      // delay queue.  This reference will be revisited if another
-      // reference is marked.
-      if (is_unreachable) {
-        state->DelayWeakReferenceSet(reference_set);
-      }
-    }
-    if (!visitor->DrainMarkingStack()) {
-      // Break out of the loop if there has been no forward process.
-      // All key objects in the weak reference sets are unreachable
-      // so we reset the weak reference sets queue.
-      state->set_delayed_weak_reference_sets(NULL);
-      break;
-    }
-  }
-  ASSERT(state->delayed_weak_reference_sets() == NULL);
-  // All weak reference sets are zone allocated and unmarked references which
-  // were on the delay queue will be freed when the zone is released in the
-  // epilog callback.
+  isolate->VisitWeakPersistentHandles(visitor);
 }
 
 
@@ -643,7 +579,6 @@
            DelaySet* delay_set,
            ThreadBarrier* barrier,
            bool collect_code,
-           bool visit_prologue_weak_persistent_handles,
            intptr_t task_index,
            intptr_t num_tasks,
            uintptr_t* num_busy)
@@ -655,15 +590,14 @@
         delay_set_(delay_set),
         barrier_(barrier),
         collect_code_(collect_code),
-        visit_prologue_weak_persistent_handles_(
-            visit_prologue_weak_persistent_handles),
         task_index_(task_index),
         num_tasks_(num_tasks),
         num_busy_(num_busy) {
   }
 
   virtual void Run() {
-    Thread::EnterIsolateAsHelper(isolate_, true);
+    bool result = Thread::EnterIsolateAsHelper(isolate_, true);
+    ASSERT(result);
     {
       StackZone stack_zone(Thread::Current());
       Zone* zone = stack_zone.GetZone();
@@ -672,9 +606,7 @@
       SyncMarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_,
                                  delay_set_, skipped_code_functions);
       // Phase 1: Iterate over roots and drain marking stack in tasks.
-      marker_->IterateRoots(isolate_, &visitor,
-                            visit_prologue_weak_persistent_handles_,
-                            task_index_, num_tasks_);
+      marker_->IterateRoots(isolate_, &visitor, task_index_, num_tasks_);
       do {
         visitor.DrainMarkingStack();
 
@@ -723,7 +655,6 @@
   DelaySet* delay_set_;
   ThreadBarrier* barrier_;
   bool collect_code_;
-  bool visit_prologue_weak_persistent_handles_;
   const intptr_t task_index_;
   const intptr_t num_tasks_;
   uintptr_t* num_busy_;
@@ -764,7 +695,6 @@
     Zone* zone = stack_zone.GetZone();
     MarkingStack marking_stack;
     DelaySet delay_set;
-    const bool visit_prologue_weak_persistent_handles = !invoke_api_callbacks;
     marked_bytes_ = 0;
     const int num_tasks = FLAG_marker_tasks;
     if (num_tasks == 0) {
@@ -773,13 +703,10 @@
           collect_code ? new(zone) SkippedCodeFunctions() : NULL;
       UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
                                 &delay_set, skipped_code_functions);
-      IterateRoots(isolate, &mark, visit_prologue_weak_persistent_handles,
-                   0, 1);
+      IterateRoots(isolate, &mark, 0, 1);
       mark.DrainMarkingStack();
-      IterateWeakReferences(isolate, &mark);
       MarkingWeakVisitor mark_weak;
-      IterateWeakRoots(isolate, &mark_weak,
-                       !visit_prologue_weak_persistent_handles);
+      IterateWeakRoots(isolate, &mark_weak);
       // All marking done; detach code, etc.
       FinalizeResultsFrom(&mark);
     } else {
@@ -791,7 +718,6 @@
         MarkTask* mark_task =
             new MarkTask(this, isolate, heap_, page_space, &marking_stack,
                          &delay_set, &barrier, collect_code,
-                         visit_prologue_weak_persistent_handles,
                          i, num_tasks, &num_busy);
         ThreadPool* pool = Dart::thread_pool();
         pool->Run(mark_task);
@@ -803,10 +729,8 @@
           collect_code ? new(zone) SkippedCodeFunctions() : NULL;
       SyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
                               &delay_set, skipped_code_functions);
-      IterateWeakReferences(isolate, &mark);
       MarkingWeakVisitor mark_weak;
-      IterateWeakRoots(isolate, &mark_weak,
-                       !visit_prologue_weak_persistent_handles);
+      IterateWeakRoots(isolate, &mark_weak);
       barrier.Sync();
 
       // Phase 3: Finalize results from all markers (detach code, etc.).
diff --git a/runtime/vm/gc_marker.h b/runtime/vm/gc_marker.h
index 93b209a..f1e473a 100644
--- a/runtime/vm/gc_marker.h
+++ b/runtime/vm/gc_marker.h
@@ -38,11 +38,8 @@
   void Epilogue(Isolate* isolate, bool invoke_api_callbacks);
   void IterateRoots(Isolate* isolate,
                     ObjectPointerVisitor* visitor,
-                    bool visit_prologue_weak_persistent_handles,
                     intptr_t slice_index, intptr_t num_slices);
-  void IterateWeakRoots(Isolate* isolate,
-                        HandleVisitor* visitor,
-                        bool visit_prologue_weak_persistent_handles);
+  void IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor);
   template<class MarkingVisitorType>
   void IterateWeakReferences(Isolate* isolate, MarkingVisitorType* visitor);
   void ProcessWeakTables(PageSpace* page_space);
diff --git a/runtime/vm/gc_sweeper.cc b/runtime/vm/gc_sweeper.cc
index 6332dee..a192138 100644
--- a/runtime/vm/gc_sweeper.cc
+++ b/runtime/vm/gc_sweeper.cc
@@ -114,7 +114,8 @@
   }
 
   virtual void Run() {
-    Thread::EnterIsolateAsHelper(task_isolate_);
+    bool result = Thread::EnterIsolateAsHelper(task_isolate_);
+    ASSERT(result);
     GCSweeper sweeper;
 
     HeapPage* page = first_;
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index dc7932e..f5eef18 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -27,8 +27,8 @@
 const intptr_t kSmiMax = (static_cast<intptr_t>(1) << kSmiBits) - 1;
 const intptr_t kSmiMin =  -(static_cast<intptr_t>(1) << kSmiBits);
 
-const double kPosInfinity = bit_cast<double>(DART_UINT64_C(0x7ff0000000000000));
-const double kNegInfinity = bit_cast<double>(DART_UINT64_C(0xfff0000000000000));
+#define kPosInfinity bit_cast<double>(DART_UINT64_C(0x7ff0000000000000))
+#define kNegInfinity bit_cast<double>(DART_UINT64_C(0xfff0000000000000))
 
 // The expression ARRAY_SIZE(array) is a compile-time constant of type
 // size_t which represents the number of elements of the given
@@ -109,7 +109,11 @@
 #elif defined(HOST_ARCH_X64)
 #define COPY_FP_REGISTER(fp) asm volatile ("movq %%rbp, %0" : "=r" (fp) );
 #elif defined(HOST_ARCH_ARM)
+#  if defined(TARGET_OS_MAC)
+#define COPY_FP_REGISTER(fp) asm volatile ("mov %0, r7" : "=r" (fp) );
+#  else
 #define COPY_FP_REGISTER(fp) asm volatile ("mov %0, r11" : "=r" (fp) );
+#  endif
 #elif defined(HOST_ARCH_ARM64)
 #define COPY_FP_REGISTER(fp) asm volatile ("mov %0, x29" : "=r" (fp) );
 #elif defined(HOST_ARCH_MIPS)
diff --git a/runtime/vm/growable_array.h b/runtime/vm/growable_array.h
index 9023948..42b787b 100644
--- a/runtime/vm/growable_array.h
+++ b/runtime/vm/growable_array.h
@@ -110,6 +110,17 @@
     data_[j] = temp;
   }
 
+  // NOTE: Does not preserve array order.
+  void RemoveAt(intptr_t i) {
+    ASSERT(i >= 0);
+    ASSERT(i < length_);
+    intptr_t last = length_ - 1;
+    if (i < last) {
+      Swap(i, last);
+    }
+    RemoveLast();
+  }
+
   // The content is uninitialized after calling it.
   void SetLength(intptr_t new_length);
 
diff --git a/runtime/vm/guard_field_test.cc b/runtime/vm/guard_field_test.cc
index 193d4b7..d0ecb6e 100644
--- a/runtime/vm/guard_field_test.cc
+++ b/runtime/vm/guard_field_test.cc
@@ -4,7 +4,6 @@
 
 #include "vm/dart_api_impl.h"
 #include "vm/dart_api_state.h"
-#include "vm/intermediate_language.h"
 #include "vm/object.h"
 #include "vm/unit_test.h"
 
@@ -54,8 +53,10 @@
       "  }\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -103,8 +104,10 @@
       "  }\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -154,8 +157,10 @@
       "  }\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -209,8 +214,10 @@
       "  }\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -256,8 +263,10 @@
       "  var a = new A(l);\n"
       "}\n"
       "main() {\n"
-      "  runFoo();\n"
-      "  runBar();\n"
+      "  for (int i = 0; i < 100; i++) {\n"
+      "    runFoo();\n"
+      "    runBar();\n"
+      "  }\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
diff --git a/runtime/vm/handles.cc b/runtime/vm/handles.cc
index 7057739..311bd98 100644
--- a/runtime/vm/handles.cc
+++ b/runtime/vm/handles.cc
@@ -8,7 +8,6 @@
 #include "platform/utils.h"
 #include "vm/dart_api_state.h"
 #include "vm/flags.h"
-#include "vm/isolate.h"
 #include "vm/os.h"
 #include "vm/raw_object.h"
 #include "vm/visitor.h"
diff --git a/runtime/vm/handles.h b/runtime/vm/handles.h
index c5bcac7..5e07d6e 100644
--- a/runtime/vm/handles.h
+++ b/runtime/vm/handles.h
@@ -22,12 +22,12 @@
 // - allocation of handles in the current zone (Handle::AllocateZoneHandle).
 //   Handles allocated in this manner are destroyed when the zone is destroyed.
 // - allocation of handles in a scoped manner (Handle::AllocateHandle).
-//   A new scope can be started using HANDLESCOPE(isolate).
+//   A new scope can be started using HANDLESCOPE(thread).
 //   Handles allocated in this manner are destroyed when the HandleScope
 //   object is destroyed.
 // Code that uses scoped handles typically looks as follows:
 //   {
-//     HANDLESCOPE(isolate);
+//     HANDLESCOPE(thread);
 //     const String& str = String::Handle(String::New("abc"));
 //     .....
 //     .....
@@ -50,7 +50,7 @@
 // raw dart objects directly. We use NOHANDLESCOPE to assert that we do not
 // add code that will allocate new handles during this critical area.
 // {
-//   NOHANDLESCOPE(isolate);
+//   NOHANDLESCOPE(thread);
 //   ....
 //   ....
 // }
@@ -316,8 +316,8 @@
 };
 
 // Macro to start a new Handle scope.
-#define HANDLESCOPE(isolate_or_thread)                                         \
-    dart::HandleScope vm_internal_handles_scope_(isolate_or_thread);
+#define HANDLESCOPE(thread)                                                    \
+    dart::HandleScope vm_internal_handles_scope_(thread);
 
 
 // The class NoHandleScope is used in critical regions of the virtual machine
@@ -345,7 +345,6 @@
 class NoHandleScope : public ValueObject {
  public:
   explicit NoHandleScope(Thread* thread) { }
-  explicit NoHandleScope(Isolate* isolate) { }
   NoHandleScope() { }
   ~NoHandleScope() { }
 
@@ -355,8 +354,8 @@
 #endif  // defined(DEBUG)
 
 // Macro to start a no handles scope in the code.
-#define NOHANDLESCOPE(isolate_or_thread)                                       \
-    dart::NoHandleScope no_vm_internal_handles_scope_(isolate_or_thread);
+#define NOHANDLESCOPE(thread)                                                  \
+    dart::NoHandleScope no_vm_internal_handles_scope_(thread);
 
 }  // namespace dart
 
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 2b319fd..10586bd 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -51,7 +51,8 @@
       new_space_(this, max_new_gen_semi_words, kNewObjectAlignmentOffset),
       old_space_(this, max_old_gen_words, max_external_words),
       read_only_(false),
-      gc_in_progress_(false),
+      gc_new_space_in_progress_(false),
+      gc_old_space_in_progress_(false),
       pretenure_policy_(0) {
   for (int sel = 0;
        sel < kNumWeakSelectors;
@@ -79,6 +80,9 @@
   isolate()->AssertCurrentThreadIsMutator();
   uword addr = new_space_.TryAllocate(size);
   if (addr == 0) {
+    // This call to CollectGarbage might end up "reusing" a collection spawned
+    // from a different thread and will be racing to allocate the requested
+    // memory with other threads being released after the collection.
     CollectGarbage(kNew);
     addr = new_space_.TryAllocate(size);
     if (addr == 0) {
@@ -108,35 +112,38 @@
   if (addr != 0) {
     return addr;
   }
-  // All GC tasks finished without allocating successfully. Run a full GC.
-  CollectAllGarbage();
-  addr = old_space_.TryAllocate(size, type);
-  if (addr != 0) {
-    return addr;
-  }
-  // Wait for all of the concurrent tasks to finish before giving up.
-  {
-    MonitorLocker ml(old_space_.tasks_lock());
+  Thread* thread = Thread::Current();
+  if (thread->CanCollectGarbage()) {
+    // All GC tasks finished without allocating successfully. Run a full GC.
+    CollectAllGarbage();
     addr = old_space_.TryAllocate(size, type);
-    while ((addr == 0) && (old_space_.tasks() > 0)) {
-      ml.Wait();
-      addr = old_space_.TryAllocate(size, type);
+    if (addr != 0) {
+      return addr;
     }
-  }
-  if (addr != 0) {
-    return addr;
-  }
-  // Force growth before attempting a synchronous GC.
-  addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
-  if (addr != 0) {
-    return addr;
-  }
-  // Before throwing an out-of-memory error try a synchronous GC.
-  CollectAllGarbage();
-  {
-    MonitorLocker ml(old_space_.tasks_lock());
-    while (old_space_.tasks() > 0) {
-      ml.Wait();
+    // Wait for all of the concurrent tasks to finish before giving up.
+    {
+      MonitorLocker ml(old_space_.tasks_lock());
+      addr = old_space_.TryAllocate(size, type);
+      while ((addr == 0) && (old_space_.tasks() > 0)) {
+        ml.Wait();
+        addr = old_space_.TryAllocate(size, type);
+      }
+    }
+    if (addr != 0) {
+      return addr;
+    }
+    // Force growth before attempting another synchronous GC.
+    addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
+    if (addr != 0) {
+      return addr;
+    }
+    // Before throwing an out-of-memory error try a synchronous GC.
+    CollectAllGarbage();
+    {
+      MonitorLocker ml(old_space_.tasks_lock());
+      while (old_space_.tasks() > 0) {
+        ml.Wait();
+      }
     }
   }
   addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
@@ -161,6 +168,7 @@
 void Heap::AllocateExternal(intptr_t size, Space space) {
   ASSERT(Thread::Current()->no_safepoint_scope_depth() == 0);
   if (space == kNew) {
+    isolate()->AssertCurrentThreadIsMutator();
     new_space_.AllocateExternal(size);
     if (new_space_.ExternalInWords() > (FLAG_new_gen_ext_limit * MBInWords)) {
       // Attempt to free some external allocation by a scavenge. (If the total
@@ -306,66 +314,51 @@
 }
 
 
-bool Heap::gc_in_progress() {
-  MutexLocker ml(&gc_in_progress_mutex_);
-  return gc_in_progress_;
-}
-
-
-void Heap::BeginGC() {
-  MutexLocker ml(&gc_in_progress_mutex_);
-  ASSERT(!gc_in_progress_);
-  gc_in_progress_ = true;
-}
-
-
-void Heap::EndGC() {
-  MutexLocker ml(&gc_in_progress_mutex_);
-  ASSERT(gc_in_progress_);
-  gc_in_progress_ = false;
-}
-
-
-void Heap::CollectGarbage(Space space,
-                          ApiCallbacks api_callbacks,
-                          GCReason reason) {
-  Thread* thread = Thread::Current();
-  bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
-  switch (space) {
-    case kNew: {
-      RecordBeforeGC(kNew, reason);
-      VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId);
-      TimelineDurationScope tds(thread,
-                                isolate()->GetGCStream(),
-                                "CollectNewGeneration");
-      UpdateClassHeapStatsBeforeGC(kNew);
-      new_space_.Scavenge(invoke_api_callbacks);
-      isolate()->class_table()->UpdatePromoted();
-      UpdatePretenurePolicy();
-      RecordAfterGC();
-      PrintStats();
-      if (old_space_.NeedsGarbageCollection()) {
-        // Old collections should call the API callbacks.
-        CollectGarbage(kOld, kInvokeApiCallbacks, kPromotion);
-      }
-      break;
-    }
-    case kOld:
-    case kCode: {
-      RecordBeforeGC(kOld, reason);
-      VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId);
-      TimelineDurationScope tds(thread,
-                                isolate()->GetGCStream(),
-                                "CollectOldGeneration");
-      UpdateClassHeapStatsBeforeGC(kOld);
-      old_space_.MarkSweep(invoke_api_callbacks);
-      RecordAfterGC();
-      PrintStats();
-      break;
-    }
-    default:
-      UNREACHABLE();
+bool Heap::BeginNewSpaceGC() {
+  MonitorLocker ml(&gc_in_progress_monitor_);
+  bool start_gc_on_thread = true;
+  while (gc_new_space_in_progress_ ||
+         gc_old_space_in_progress_) {
+    start_gc_on_thread = !gc_new_space_in_progress_;
+    ml.Wait();
   }
+  if (start_gc_on_thread) {
+    gc_new_space_in_progress_ = true;
+    return true;
+  }
+  return false;
+}
+
+
+void Heap::EndNewSpaceGC() {
+  MonitorLocker ml(&gc_in_progress_monitor_);
+  ASSERT(gc_new_space_in_progress_);
+  gc_new_space_in_progress_ = false;
+  ml.NotifyAll();
+}
+
+
+bool Heap::BeginOldSpaceGC() {
+  MonitorLocker ml(&gc_in_progress_monitor_);
+  bool start_gc_on_thread = true;
+  while (gc_new_space_in_progress_ ||
+         gc_old_space_in_progress_) {
+    start_gc_on_thread = !gc_old_space_in_progress_;
+    ml.Wait();
+  }
+  if (start_gc_on_thread) {
+    gc_old_space_in_progress_ = true;
+    return true;
+  }
+  return false;
+}
+
+
+void Heap::EndOldSpaceGC() {
+  MonitorLocker ml(&gc_in_progress_monitor_);
+  ASSERT(gc_old_space_in_progress_);
+  gc_old_space_in_progress_ = false;
+  ml.NotifyAll();
 }
 
 
@@ -379,42 +372,85 @@
 }
 
 
+void Heap::CollectNewSpaceGarbage(Thread* thread,
+                                  ApiCallbacks api_callbacks,
+                                  GCReason reason) {
+  if (BeginNewSpaceGC()) {
+    bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
+    RecordBeforeGC(kNew, reason);
+    VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId);
+    TimelineDurationScope tds(thread,
+                              isolate()->GetGCStream(),
+                              "CollectNewGeneration");
+    UpdateClassHeapStatsBeforeGC(kNew);
+    new_space_.Scavenge(invoke_api_callbacks);
+    isolate()->class_table()->UpdatePromoted();
+    UpdatePretenurePolicy();
+    RecordAfterGC(kNew);
+    PrintStats();
+    EndNewSpaceGC();
+    if (old_space_.NeedsGarbageCollection()) {
+      // Old collections should call the API callbacks.
+      CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kPromotion);
+    }
+  }
+}
+
+
+void Heap::CollectOldSpaceGarbage(Thread* thread,
+                                  ApiCallbacks api_callbacks,
+                                  GCReason reason) {
+  if (BeginOldSpaceGC()) {
+    bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
+    RecordBeforeGC(kOld, reason);
+    VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId);
+    TimelineDurationScope tds(thread,
+                              isolate()->GetGCStream(),
+                              "CollectOldGeneration");
+    UpdateClassHeapStatsBeforeGC(kOld);
+    old_space_.MarkSweep(invoke_api_callbacks);
+    RecordAfterGC(kOld);
+    PrintStats();
+    EndOldSpaceGC();
+  }
+}
+
+
+void Heap::CollectGarbage(Space space,
+                          ApiCallbacks api_callbacks,
+                          GCReason reason) {
+  Thread* thread = Thread::Current();
+  switch (space) {
+    case kNew: {
+      CollectNewSpaceGarbage(thread, api_callbacks, reason);
+      break;
+    }
+    case kOld:
+    case kCode: {
+      CollectOldSpaceGarbage(thread, api_callbacks, reason);
+      break;
+    }
+    default:
+      UNREACHABLE();
+  }
+}
+
+
 void Heap::CollectGarbage(Space space) {
+  Thread* thread = Thread::Current();
   if (space == kOld) {
-    CollectGarbage(space, kInvokeApiCallbacks, kOldSpace);
+    CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kOldSpace);
   } else {
     ASSERT(space == kNew);
-    CollectGarbage(space, kInvokeApiCallbacks, kNewSpace);
+    CollectNewSpaceGarbage(thread, kInvokeApiCallbacks, kNewSpace);
   }
 }
 
 
 void Heap::CollectAllGarbage() {
   Thread* thread = Thread::Current();
-  {
-    RecordBeforeGC(kNew, kFull);
-    VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId);
-    TimelineDurationScope tds(thread,
-                              isolate()->GetGCStream(),
-                              "CollectNewGeneration");
-    UpdateClassHeapStatsBeforeGC(kNew);
-    new_space_.Scavenge(kInvokeApiCallbacks);
-    isolate()->class_table()->UpdatePromoted();
-    UpdatePretenurePolicy();
-    RecordAfterGC();
-    PrintStats();
-  }
-  {
-    RecordBeforeGC(kOld, kFull);
-    VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId);
-    TimelineDurationScope tds(thread,
-                              isolate()->GetGCStream(),
-                              "CollectOldGeneration");
-    UpdateClassHeapStatsBeforeGC(kOld);
-    old_space_.MarkSweep(kInvokeApiCallbacks);
-    RecordAfterGC();
-    PrintStats();
-  }
+  CollectNewSpaceGarbage(thread, kInvokeApiCallbacks, kFull);
+  CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kFull);
 }
 
 
@@ -473,10 +509,10 @@
 }
 
 
-void Heap::WriteProtect(bool read_only) {
+void Heap::WriteProtect(bool read_only, bool include_code_pages) {
   read_only_ = read_only;
   new_space_.WriteProtect(read_only);
-  old_space_.WriteProtect(read_only);
+  old_space_.WriteProtect(read_only, include_code_pages);
 }
 
 
@@ -693,7 +729,8 @@
 
 
 void Heap::RecordBeforeGC(Space space, GCReason reason) {
-  BeginGC();
+  ASSERT((space == kNew && gc_new_space_in_progress_) ||
+         (space == kOld && gc_old_space_in_progress_));
   stats_.num_++;
   stats_.space_ = space;
   stats_.reason_ = reason;
@@ -711,7 +748,7 @@
 }
 
 
-void Heap::RecordAfterGC() {
+void Heap::RecordAfterGC(Space space) {
   stats_.after_.micros_ = OS::GetCurrentTimeMicros();
   int64_t delta = stats_.after_.micros_ - stats_.before_.micros_;
   if (stats_.space_ == kNew) {
@@ -723,7 +760,8 @@
   }
   stats_.after_.new_ = new_space_.GetCurrentUsage();
   stats_.after_.old_ = old_space_.GetCurrentUsage();
-  EndGC();
+  ASSERT((space == kNew && gc_new_space_in_progress_) ||
+         (space == kOld && gc_old_space_in_progress_));
   if (Service::gc_stream.enabled()) {
     ServiceEvent event(Isolate::Current(), ServiceEvent::kGC);
     event.set_gc_stats(&stats_);
@@ -787,7 +825,7 @@
 
 
 NoHeapGrowthControlScope::NoHeapGrowthControlScope()
-    : StackResource(Isolate::Current()) {
+    : StackResource(Thread::Current()) {
     Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap();
     current_growth_controller_state_ = heap->GrowthControlState();
     heap->DisableGrowthControl();
@@ -800,15 +838,16 @@
 }
 
 
-WritableVMIsolateScope::WritableVMIsolateScope(Thread* thread)
-    : StackResource(thread) {
-  Dart::vm_isolate()->heap()->WriteProtect(false);
+WritableVMIsolateScope::WritableVMIsolateScope(Thread* thread,
+                                               bool include_code_pages)
+    : StackResource(thread), include_code_pages_(include_code_pages) {
+  Dart::vm_isolate()->heap()->WriteProtect(false, include_code_pages_);
 }
 
 
 WritableVMIsolateScope::~WritableVMIsolateScope() {
   ASSERT(Dart::vm_isolate()->heap()->UsedInWords(Heap::kNew) == 0);
-  Dart::vm_isolate()->heap()->WriteProtect(true);
+  Dart::vm_isolate()->heap()->WriteProtect(true, include_code_pages_);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 22a109e..4a8ae93 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -104,7 +104,6 @@
   bool NewContains(uword addr) const;
   bool OldContains(uword addr) const;
   bool CodeContains(uword addr) const;
-  bool StubCodeContains(uword addr) const;
 
   void IterateObjects(ObjectVisitor* visitor) const;
   void IterateOldObjects(ObjectVisitor* visitor) const;
@@ -126,6 +125,9 @@
   void CollectGarbage(Space space);
   void CollectGarbage(Space space, ApiCallbacks api_callbacks, GCReason reason);
   void CollectAllGarbage();
+  bool NeedsGarbageCollection() const {
+    return old_space_.NeedsGarbageCollection();
+  }
 
   // Enables growth control on the page space heaps.  This should be
   // called before any user code is executed.
@@ -136,7 +138,7 @@
 
   // Protect access to the heap. Note: Code pages are made
   // executable/non-executable when 'read_only' is true/false, respectively.
-  void WriteProtect(bool read_only);
+  void WriteProtect(bool read_only, bool include_code_pages);
   void WriteProtectCode(bool read_only) {
     old_space_.WriteProtectCode(read_only);
   }
@@ -232,8 +234,6 @@
     stats_.data_[id] = value;
   }
 
-  bool gc_in_progress();
-
   void UpdateGlobalMaxUsed();
 
   static bool IsAllocatableInNewSpace(intptr_t size) {
@@ -309,16 +309,24 @@
   // ensure thread-safety.
   bool VerifyGC(MarkExpectation mark_expectation = kForbidMarked) const;
 
+  // Helper functions for garbage collection.
+  void CollectNewSpaceGarbage(
+      Thread* thread, ApiCallbacks api_callbacks, GCReason reason);
+  void CollectOldSpaceGarbage(
+      Thread* thread, ApiCallbacks api_callbacks, GCReason reason);
+
   // GC stats collection.
   void RecordBeforeGC(Space space, GCReason reason);
-  void RecordAfterGC();
+  void RecordAfterGC(Space space);
   void PrintStats();
   void UpdateClassHeapStatsBeforeGC(Heap::Space space);
   void UpdatePretenurePolicy();
 
-  // Updates gc_in_progress.
-  void BeginGC();
-  void EndGC();
+  // Updates gc in progress flags.
+  bool BeginNewSpaceGC();
+  void EndNewSpaceGC();
+  bool BeginOldSpaceGC();
+  void EndOldSpaceGC();
 
   // If this heap is non-empty, updates start and end to the smallest range that
   // contains both the original [start, end) and the [lowest, highest) addresses
@@ -341,8 +349,9 @@
   bool read_only_;
 
   // GC on the heap is in progress.
-  Mutex gc_in_progress_mutex_;
-  bool gc_in_progress_;
+  Monitor gc_in_progress_monitor_;
+  bool gc_new_space_in_progress_;
+  bool gc_old_space_in_progress_;
 
   int pretenure_policy_;
 
@@ -377,8 +386,11 @@
 // Note: During this scope, the code pages are non-executable.
 class WritableVMIsolateScope : StackResource {
  public:
-  explicit WritableVMIsolateScope(Thread* thread);
+  explicit WritableVMIsolateScope(Thread* thread, bool include_code_pages);
   ~WritableVMIsolateScope();
+
+ private:
+  bool include_code_pages_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/heap_test.cc b/runtime/vm/heap_test.cc
index e609901..f52a81c 100644
--- a/runtime/vm/heap_test.cc
+++ b/runtime/vm/heap_test.cc
@@ -280,9 +280,9 @@
   const String& obj = String::Handle(String::New("x", Heap::kOld));
   Heap* heap = Thread::Current()->isolate()->heap();
   EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
-  heap->WriteProtect(true);
+  heap->WriteProtect(true, true /* include_code_pages */);
   EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
-  heap->WriteProtect(false);
+  heap->WriteProtect(false, true /* include_code_pages */);
   EXPECT(heap->Contains(RawObject::ToAddr(obj.raw())));
 }
 
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index 30c4a6f..97de0b1 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -405,9 +405,6 @@
   f->Print(", %s, '%s'",
            dst_type().ToCString(),
            dst_name().ToCString());
-  f->Print(" instantiator(");
-  instantiator()->PrintTo(f);
-  f->Print(")");
   f->Print(" instantiator_type_arguments(");
   instantiator_type_arguments()->PrintTo(f);
   f->Print(")");
@@ -551,9 +548,6 @@
   f->Print(" %s %s",
             negate_result() ? "ISNOT" : "IS",
             String::Handle(type().Name()).ToCString());
-  f->Print(" instantiator(");
-  instantiator()->PrintTo(f);
-  f->Print(")");
   f->Print(" type-arg(");
   instantiator_type_arguments()->PrintTo(f);
   f->Print(")");
diff --git a/runtime/vm/instructions.h b/runtime/vm/instructions.h
index 0f5b8a5..a271672 100644
--- a/runtime/vm/instructions.h
+++ b/runtime/vm/instructions.h
@@ -21,4 +21,15 @@
 #error Unknown architecture.
 #endif
 
+namespace dart {
+
+class Object;
+class Code;
+
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj);
+
+}  // namespace dart
+
 #endif  // VM_INSTRUCTIONS_H_
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index eec6cfe..36281df 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -65,7 +65,7 @@
   InstructionPattern::DecodeLoadWordFromPool(native_function_load_end,
                                              &reg,
                                              &native_function_pool_index_);
-  ASSERT(reg == R5);
+  ASSERT(reg == R9);
 }
 
 
@@ -169,6 +169,18 @@
 }
 
 
+static bool IsLoadWithOffset(int32_t instr, Register base,
+                             intptr_t* offset, Register* dst) {
+  if ((instr & 0xffff0000) == (0xe5900000 | (base << 16))) {
+    // ldr reg, [base, #+offset]
+    *offset = instr & 0xfff;
+    *dst = static_cast<Register>((instr & 0xf000) >> 12);
+    return true;
+  }
+  return false;
+}
+
+
 // Decodes a load sequence ending at 'end' (the last instruction of the load
 // sequence is the instruction before the one at end).  Returns a pointer to
 // the first instruction in the sequence.  Returns the register being loaded
@@ -180,21 +192,22 @@
   uword start = end - Instr::kInstrSize;
   int32_t instr = Instr::At(start)->InstructionBits();
   intptr_t offset = 0;
-  if ((instr & 0xffff0000) == 0xe5990000) {  // ldr reg, [pp, #+offset]
-    offset = instr & 0xfff;
-    *reg = static_cast<Register>((instr & 0xf000) >> 12);
+  if (IsLoadWithOffset(instr, PP, &offset, reg)) {
+    // ldr reg, [PP, #+offset]
   } else {
     ASSERT((instr & 0xfff00000) == 0xe5900000);  // ldr reg, [reg, #+offset]
     offset = instr & 0xfff;
     start -= Instr::kInstrSize;
     instr = Instr::At(start)->InstructionBits();
-    if ((instr & 0xffff0000) == 0xe2890000) {  // add reg, pp, operand
+    if ((instr & 0xffff0000) == (0xe2850000 | (PP << 16))) {
+      // add reg, pp, operand
       const intptr_t rot = (instr & 0xf00) >> 7;
       const intptr_t imm8 = instr & 0xff;
       offset += (imm8 >> rot) | (imm8 << (32 - rot));
       *reg = static_cast<Register>((instr & 0xf000) >> 12);
     } else {
-      ASSERT((instr & 0xffff0000) == 0xe0890000);  // add reg, pp, reg
+      ASSERT((instr & 0xffff0000) == (0xe0800000 | (PP << 16)));
+      // add reg, pp, reg
       end = DecodeLoadWordImmediate(end, reg, &offset);
     }
   }
@@ -203,6 +216,30 @@
 }
 
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+
+  int32_t instr = Instr::At(pc)->InstructionBits();
+  intptr_t offset;
+  Register dst;
+  if (IsLoadWithOffset(instr, PP, &offset, &dst)) {
+    intptr_t index = ObjectPool::IndexFromOffset(offset);
+    const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+    if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+      *obj = pool.ObjectAt(index);
+      return true;
+    }
+  } else if (IsLoadWithOffset(instr, THR, &offset, &dst)) {
+    return Thread::ObjectAtOffset(offset, obj);
+  }
+  // TODO(rmacnak): Sequence for loads beyond 12 bits.
+
+  return false;
+}
+
+
 RawICData* CallPattern::IcData() {
   if (ic_data_.IsNull()) {
     Register reg;
@@ -210,7 +247,7 @@
                                          object_pool_,
                                          &reg,
                                          &ic_data_);
-    ASSERT(reg == R5);
+    ASSERT(reg == R9);
   }
   return ic_data_.raw();
 }
@@ -270,6 +307,45 @@
 }
 
 
+SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
+    : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
+      cache_pool_index_(-1),
+      stub_pool_index_(-1) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  // Last instruction: blx r1.
+  ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff31);
+
+  Register reg;
+  uword stub_load_end =
+      InstructionPattern::DecodeLoadWordFromPool(pc - 3 * Instr::kInstrSize,
+                                                 &reg,
+                                                 &stub_pool_index_);
+  ASSERT(reg == CODE_REG);
+  InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
+                                             &reg,
+                                             &cache_pool_index_);
+  ASSERT(reg == R9);
+}
+
+
+RawObject* SwitchableCallPattern::cache() const {
+  return reinterpret_cast<RawCode*>(
+      object_pool_.ObjectAt(cache_pool_index_));
+}
+
+
+void SwitchableCallPattern::SetCache(const MegamorphicCache& cache) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(cache_pool_index_)).IsICData());
+  object_pool_.SetObjectAt(cache_pool_index_, cache);
+}
+
+
+void SwitchableCallPattern::SetLookupStub(const Code& lookup_stub) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(stub_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(stub_pool_index_, lookup_stub);
+}
+
+
 ReturnPattern::ReturnPattern(uword pc)
     : pc_(pc) {
 }
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index ad82da1..57d4824 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -98,6 +98,27 @@
 };
 
 
+// Instance call that can switch from an IC call to a megamorphic call
+//   load ICData             load MegamorphicCache
+//   call ICLookup stub  ->  call MegamorphicLookup stub
+//   call target             call target
+class SwitchableCallPattern : public ValueObject {
+ public:
+  SwitchableCallPattern(uword pc, const Code& code);
+
+  RawObject* cache() const;
+  void SetCache(const MegamorphicCache& cache) const;
+  void SetLookupStub(const Code& stub) const;
+
+ private:
+  const ObjectPool& object_pool_;
+  intptr_t cache_pool_index_;
+  intptr_t stub_pool_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
+};
+
+
 class ReturnPattern : public ValueObject {
  public:
   explicit ReturnPattern(uword pc);
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index 62b3ff2..99c57ba 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -259,6 +259,34 @@
 }
 
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+
+  Instr* instr = Instr::At(pc);
+  if (instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) &&
+      (instr->Bits(30, 2) == 3) && instr->Bit(24) == 1) {
+    intptr_t offset = (instr->Imm12Field() << 3);
+    if (instr->RnField() == PP) {
+      // PP is untagged on ARM64.
+      ASSERT(Utils::IsAligned(offset, 8));
+      intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
+      const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+      if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+        *obj = pool.ObjectAt(index);
+        return true;
+      }
+    } else if (instr->RnField() == THR) {
+      return Thread::ObjectAtOffset(offset, obj);
+    }
+  }
+  // TODO(rmacnak): Loads with offsets beyond 12 bits.
+
+  return false;
+}
+
+
 // Encodes a load sequence ending at 'end'. Encodes a fixed length two
 // instruction load from the pool pointer in PP using the destination
 // register reg as a temporary for the base address.
@@ -329,6 +357,45 @@
 }
 
 
+SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
+    : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
+      cache_pool_index_(-1),
+      stub_pool_index_(-1) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  // Last instruction: blr r1.
+  ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0020);
+
+  Register reg;
+  uword stub_load_end =
+      InstructionPattern::DecodeLoadWordFromPool(pc - 3 * Instr::kInstrSize,
+                                                 &reg,
+                                                 &stub_pool_index_);
+  ASSERT(reg == CODE_REG);
+  InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
+                                             &reg,
+                                             &cache_pool_index_);
+  ASSERT(reg == R5);
+}
+
+
+RawObject* SwitchableCallPattern::cache() const {
+  return reinterpret_cast<RawCode*>(
+      object_pool_.ObjectAt(cache_pool_index_));
+}
+
+
+void SwitchableCallPattern::SetCache(const MegamorphicCache& cache) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(cache_pool_index_)).IsICData());
+  object_pool_.SetObjectAt(cache_pool_index_, cache);
+}
+
+
+void SwitchableCallPattern::SetLookupStub(const Code& lookup_stub) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(stub_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(stub_pool_index_, lookup_stub);
+}
+
+
 ReturnPattern::ReturnPattern(uword pc)
     : pc_(pc) {
 }
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index 0d2c96d..6195d52 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -106,6 +106,27 @@
 };
 
 
+// Instance call that can switch from an IC call to a megamorphic call
+//   load ICData             load MegamorphicCache
+//   call ICLookup stub  ->  call MegamorphicLookup stub
+//   call target             call target
+class SwitchableCallPattern : public ValueObject {
+ public:
+  SwitchableCallPattern(uword pc, const Code& code);
+
+  RawObject* cache() const;
+  void SetCache(const MegamorphicCache& cache) const;
+  void SetLookupStub(const Code& stub) const;
+
+ private:
+  const ObjectPool& object_pool_;
+  intptr_t cache_pool_index_;
+  intptr_t stub_pool_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
+};
+
+
 class ReturnPattern : public ValueObject {
  public:
   explicit ReturnPattern(uword pc);
diff --git a/runtime/vm/instructions_ia32.cc b/runtime/vm/instructions_ia32.cc
index 84ba433..2b9f638 100644
--- a/runtime/vm/instructions_ia32.cc
+++ b/runtime/vm/instructions_ia32.cc
@@ -11,6 +11,13 @@
 
 namespace dart {
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  return false;
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index dcca54f..cdb2cbe 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -121,6 +121,31 @@
 }
 
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+
+  Instr* instr = Instr::At(pc);
+  if ((instr->OpcodeField() == LW)) {
+    intptr_t offset = instr->SImmField();
+    if (instr->RsField() == PP) {
+      intptr_t index = ObjectPool::IndexFromOffset(offset);
+      const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+      if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+        *obj = pool.ObjectAt(index);
+        return true;
+      }
+    } else if (instr->RsField() == THR) {
+      return Thread::ObjectAtOffset(offset, obj);
+    }
+  }
+  // TODO(rmacnak): Sequence for loads beyond 16 bits.
+
+  return false;
+}
+
+
 RawICData* CallPattern::IcData() {
   if (ic_data_.IsNull()) {
     Register reg;
@@ -210,6 +235,46 @@
 }
 
 
+SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
+    : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
+      cache_pool_index_(-1),
+      stub_pool_index_(-1) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  // Last instruction: jalr t1.
+  ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0);  // Delay slot.
+  ASSERT(*(reinterpret_cast<uword*>(pc) - 2) == 0x0120f809);
+
+  Register reg;
+  uword stub_load_end =
+      InstructionPattern::DecodeLoadWordFromPool(pc - 5 * Instr::kInstrSize,
+                                                 &reg,
+                                                 &stub_pool_index_);
+  ASSERT(reg == CODE_REG);
+  InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
+                                             &reg,
+                                             &cache_pool_index_);
+  ASSERT(reg == S5);
+}
+
+
+RawObject* SwitchableCallPattern::cache() const {
+  return reinterpret_cast<RawCode*>(
+      object_pool_.ObjectAt(cache_pool_index_));
+}
+
+
+void SwitchableCallPattern::SetCache(const MegamorphicCache& cache) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(cache_pool_index_)).IsICData());
+  object_pool_.SetObjectAt(cache_pool_index_, cache);
+}
+
+
+void SwitchableCallPattern::SetLookupStub(const Code& lookup_stub) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(stub_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(stub_pool_index_, lookup_stub);
+}
+
+
 ReturnPattern::ReturnPattern(uword pc)
     : pc_(pc) {
 }
diff --git a/runtime/vm/instructions_mips.h b/runtime/vm/instructions_mips.h
index fb2e22b..607e835 100644
--- a/runtime/vm/instructions_mips.h
+++ b/runtime/vm/instructions_mips.h
@@ -97,6 +97,27 @@
 };
 
 
+// Instance call that can switch from an IC call to a megamorphic call
+//   load ICData             load MegamorphicCache
+//   call ICLookup stub  ->  call MegamorphicLookup stub
+//   call target             call target
+class SwitchableCallPattern : public ValueObject {
+ public:
+  SwitchableCallPattern(uword pc, const Code& code);
+
+  RawObject* cache() const;
+  void SetCache(const MegamorphicCache& cache) const;
+  void SetLookupStub(const Code& stub) const;
+
+ private:
+  const ObjectPool& object_pool_;
+  intptr_t cache_pool_index_;
+  intptr_t stub_pool_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
+};
+
+
 class ReturnPattern : public ValueObject {
  public:
   explicit ReturnPattern(uword pc);
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index dc691a4..2dc98bc 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_X64)
 
 #include "vm/cpu.h"
+#include "vm/constants_x64.h"
 #include "vm/instructions.h"
 #include "vm/object.h"
 
@@ -18,6 +19,44 @@
 }
 
 
+bool DecodeLoadObjectFromPoolOrThread(uword pc,
+                                      const Code& code,
+                                      Object* obj) {
+  ASSERT(code.ContainsInstructionAt(pc));
+
+  uint8_t* bytes = reinterpret_cast<uint8_t*>(pc);
+  COMPILE_ASSERT(PP == R15);
+  if (((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x9f)) ||
+      ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x87)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0xa7)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x9f)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x97))) {
+    intptr_t index = IndexFromPPLoad(pc + 3);
+    const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+    if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+      *obj = pool.ObjectAt(index);
+      return true;
+    }
+  }
+  COMPILE_ASSERT(THR == R14);
+  if (((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x86)) ||
+      ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0xb6)) ||
+      ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x96)) ||
+      ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x9e)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x9e)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0xa6))) {
+    int32_t offset = *reinterpret_cast<int32_t*>(pc + 3);
+    return Thread::ObjectAtOffset(offset, obj);
+  }
+  if (((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x5e)) ||
+      ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x6e))) {
+    uint8_t offset = *reinterpret_cast<uint8_t*>(pc + 3);
+    return Thread::ObjectAtOffset(offset, obj);
+  }
+
+  return false;
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 2389dfc..15635bc 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -5,6 +5,8 @@
 #include "vm/intermediate_language.h"
 
 #include "vm/bit_vector.h"
+#include "vm/bootstrap.h"
+#include "vm/compiler.h"
 #include "vm/constant_propagator.h"
 #include "vm/cpu.h"
 #include "vm/dart_entry.h"
@@ -259,14 +261,14 @@
 bool LoadFieldInstr::IsUnboxedLoad() const {
   return FLAG_unbox_numeric_fields
       && (field() != NULL)
-      && field()->IsUnboxedField();
+      && FlowGraphCompiler::IsUnboxedField(*field());
 }
 
 
 bool LoadFieldInstr::IsPotentialUnboxedLoad() const {
   return FLAG_unbox_numeric_fields
       && (field() != NULL)
-      && field()->IsPotentialUnboxedField();
+      && FlowGraphCompiler::IsPotentialUnboxedField(*field());
 }
 
 
@@ -291,14 +293,14 @@
 bool StoreInstanceFieldInstr::IsUnboxedStore() const {
   return FLAG_unbox_numeric_fields
       && !field().IsNull()
-      && field().IsUnboxedField();
+      && FlowGraphCompiler::IsUnboxedField(field());
 }
 
 
 bool StoreInstanceFieldInstr::IsPotentialUnboxedStore() const {
   return FLAG_unbox_numeric_fields
       && !field().IsNull()
-      && field().IsPotentialUnboxedField();
+      && FlowGraphCompiler::IsPotentialUnboxedField(field());
 }
 
 
@@ -396,7 +398,8 @@
 
 
 EffectSet LoadStaticFieldInstr::Dependencies() const {
-  return StaticField().is_final() ? EffectSet::None() : EffectSet::All();
+  return (StaticField().is_final() && !FLAG_fields_may_be_reset)
+      ? EffectSet::None() : EffectSet::All();
 }
 
 
@@ -417,7 +420,9 @@
 }
 
 
-ConstantInstr::ConstantInstr(const Object& value) : value_(value) {
+ConstantInstr::ConstantInstr(const Object& value, intptr_t token_pos)
+    : value_(value),
+      token_pos_(token_pos) {
   // Check that the value is not an incorrect Integer representation.
   ASSERT(!value.IsBigint() || !Bigint::Cast(value).FitsIntoSmi());
   ASSERT(!value.IsBigint() || !Bigint::Cast(value).FitsIntoInt64());
@@ -537,6 +542,11 @@
 }
 
 
+bool GraphEntryInstr::IsCompiledForOsr() const {
+  return osr_id_ != Compiler::kNoOSRDeoptId;
+}
+
+
 // ==== Support for visiting flow graphs.
 
 #define DEFINE_ACCEPT(ShortName)                                               \
@@ -622,7 +632,7 @@
 }
 
 
-BlockEntryInstr* Instruction::GetBlock() const {
+BlockEntryInstr* Instruction::GetBlock() {
   // TODO(fschneider): Implement a faster way to get the block of an
   // instruction.
   ASSERT(previous() != NULL);
@@ -1727,6 +1737,19 @@
 }
 
 
+Definition* BinaryIntegerOpInstr::CreateConstantResult(FlowGraph* flow_graph,
+                                                       const Integer& result) {
+  Definition* result_defn = flow_graph->GetConstant(result);
+  if (representation() != kTagged) {
+    result_defn = UnboxInstr::Create(representation(),
+                                     new Value(result_defn),
+                                     GetDeoptId());
+    flow_graph->InsertBefore(this, result_defn, env(), FlowGraph::kValue);
+  }
+  return result_defn;
+}
+
+
 Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) {
   // If both operands are constants evaluate this expression. Might
   // occur due to load forwarding after constant propagation pass
@@ -1739,7 +1762,7 @@
         Evaluate(Integer::Cast(left()->BoundConstant()),
                  Integer::Cast(right()->BoundConstant())));
     if (!result.IsNull()) {
-      return flow_graph->GetConstant(result);
+      return CreateConstantResult(flow_graph, result);
     }
   }
 
@@ -1864,7 +1887,7 @@
         DeoptimizeInstr* deopt =
             new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, GetDeoptId());
         flow_graph->InsertBefore(this, deopt, env(), FlowGraph::kEffect);
-        return flow_graph->GetConstant(Smi::Handle(Smi::New(0)));
+        return CreateConstantResult(flow_graph, Integer::Handle(Smi::New(0)));
       }
       break;
 
@@ -1878,7 +1901,7 @@
               new DeoptimizeInstr(ICData::kDeoptBinarySmiOp, GetDeoptId());
           flow_graph->InsertBefore(this, deopt, env(), FlowGraph::kEffect);
         }
-        return flow_graph->GetConstant(Smi::Handle(Smi::New(0)));
+        return CreateConstantResult(flow_graph, Integer::Handle(Smi::New(0)));
       }
       break;
     }
@@ -2194,11 +2217,13 @@
   // Fold away UnboxInteger<rep_to>(BoxInteger<rep_from>(v)).
   BoxIntegerInstr* box_defn = value()->definition()->AsBoxInteger();
   if (box_defn != NULL) {
-    if (box_defn->value()->definition()->representation() == representation()) {
+    Representation from_representation =
+        box_defn->value()->definition()->representation();
+    if (from_representation == representation()) {
       return box_defn->value()->definition();
     } else {
       UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr(
-          box_defn->value()->definition()->representation(),
+          from_representation,
           representation(),
           box_defn->value()->CopyWithType(),
           (representation() == kUnboxedInt32) ?
@@ -2514,6 +2539,7 @@
 
 
 Definition* StrictCompareInstr::Canonicalize(FlowGraph* flow_graph) {
+  if (!HasUses()) return NULL;
   bool negated = false;
   Definition* replacement = CanonicalizeStrictCompare(this, &negated);
   if (negated && replacement->IsComparison()) {
@@ -3650,6 +3676,30 @@
 }
 
 
+void NativeCallInstr::SetupNative() {
+  Zone* Z = Thread::Current()->zone();
+  const Class& cls = Class::Handle(Z, function().Owner());
+  const Library& library = Library::Handle(Z, cls.library());
+  const int num_params =
+      NativeArguments::ParameterCountForResolution(function());
+  bool auto_setup_scope = true;
+  NativeFunction native_function = NativeEntry::ResolveNative(
+      library, native_name(), num_params, &auto_setup_scope);
+  if (native_function == NULL) {
+    Report::MessageF(Report::kError,
+                     Script::Handle(function().script()),
+                     function().token_pos(),
+                     "native function '%s' (%" Pd " arguments) cannot be found",
+                     native_name().ToCString(),
+                     function().NumParameters());
+  }
+  set_native_c_function(native_function);
+  function().SetIsNativeAutoSetupScope(auto_setup_scope);
+  Dart_NativeEntryResolver resolver = library.native_entry_resolver();
+  bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver);
+  set_is_bootstrap_native(is_bootstrap_native);
+}
+
 #undef __
 
 }  // namespace dart
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 7f01ecc..0a40848 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -38,6 +38,47 @@
 class RangeBoundary;
 class UnboxIntegerInstr;
 
+// These token positions are used to classify instructions that can't be
+// directly tied to an actual source position.
+#define CLASSIFYING_TOKEN_POSITIONS(V)                                         \
+    V(Private, -2)                                                             \
+    V(Box, -3)                                                                 \
+    V(ParallelMove, -4)                                                        \
+    V(TempMove, -5)                                                            \
+    V(Constant, -6)                                                            \
+    V(PushArgument, -7)                                                        \
+    V(ControlFlow, -8)                                                         \
+    V(Context, -9)
+
+// COMPILE_ASSERT that all CLASSIFYING_TOKEN_POSITIONS are less than
+// Scanner::kNoSourcePos.
+#define SANITY_CHECK_VALUES(name, value)                                       \
+  COMPILE_ASSERT(value < Scanner::kNoSourcePos);
+  CLASSIFYING_TOKEN_POSITIONS(SANITY_CHECK_VALUES);
+#undef SANITY_CHECK_VALUES
+
+class ClassifyingTokenPositions : public AllStatic {
+ public:
+#define DEFINE_VALUES(name, value)                                             \
+  static const intptr_t k##name = value;
+  CLASSIFYING_TOKEN_POSITIONS(DEFINE_VALUES);
+#undef DEFINE_VALUES
+
+  static const char* ToCString(intptr_t token_pos) {
+    ASSERT(token_pos < 0);
+    switch (token_pos) {
+      case Scanner::kNoSourcePos: return "NoSource";
+#define DEFINE_CASE(name, value)                                               \
+      case value: return #name;
+      CLASSIFYING_TOKEN_POSITIONS(DEFINE_CASE);
+#undef DEFINE_CASE
+      default:
+        UNIMPLEMENTED();
+        return NULL;
+    }
+  }
+};
+
 // CompileType describes type of the value produced by the definition.
 //
 // It captures the following properties:
@@ -337,8 +378,6 @@
 
   const char* ToCString() const;
 
-  const char* DebugName() const { return "Value"; }
-
   bool IsSmiValue() { return Type()->ToCid() == kSmiCid; }
 
   // Returns true if this value binds to the constant: 0xFFFFFFFF.
@@ -812,7 +851,7 @@
   }
 
   // Get the block entry for this instruction.
-  virtual BlockEntryInstr* GetBlock() const;
+  virtual BlockEntryInstr* GetBlock();
 
   // Place identifiers used by the load optimization pass.
   intptr_t place_id() const { return place_id_; }
@@ -1055,6 +1094,10 @@
 
   virtual void PrintTo(BufferFormatter* f) const;
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kParallelMove;
+  }
+
  private:
   GrowableArray<MoveOperands*> moves_;   // Elements cannot be null.
 
@@ -1183,8 +1226,12 @@
     loop_info_ = loop_info;
   }
 
-  virtual BlockEntryInstr* GetBlock() const {
-    return const_cast<BlockEntryInstr*>(this);
+  virtual BlockEntryInstr* GetBlock() {
+    return this;
+  }
+
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kControlFlow;
   }
 
   // Helper to mutate the graph during inlining. This block should be
@@ -1331,7 +1378,7 @@
   }
   ConstantInstr* constant_null();
 
-  bool IsCompiledForOsr() const { return osr_id_ != Thread::kNoDeoptId; }
+  bool IsCompiledForOsr() const;
 
   intptr_t entry_count() const { return entry_count_; }
   void set_entry_count(intptr_t count) { entry_count_ = count; }
@@ -1888,7 +1935,7 @@
   }
 
   // Get the block entry for that instruction.
-  virtual BlockEntryInstr* GetBlock() const { return block(); }
+  virtual BlockEntryInstr* GetBlock() { return block(); }
   JoinEntryInstr* block() const { return block_; }
 
   virtual CompileType ComputeType() const;
@@ -1983,7 +2030,7 @@
   Register base_reg() const { return base_reg_; }
 
   // Get the block entry for that instruction.
-  virtual BlockEntryInstr* GetBlock() const { return block_; }
+  virtual BlockEntryInstr* GetBlock() { return block_; }
 
   intptr_t InputCount() const { return 0; }
   Value* InputAt(intptr_t i) const {
@@ -2036,6 +2083,10 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kPushArgument;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr);
 };
@@ -2210,6 +2261,10 @@
 
   virtual void PrintTo(BufferFormatter* f) const;
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kControlFlow;
+  }
+
  private:
   BlockEntryInstr* block_;
   JoinEntryInstr* successor_;
@@ -2543,7 +2598,8 @@
 
 class ConstantInstr : public TemplateDefinition<0, NoThrow, Pure> {
  public:
-  explicit ConstantInstr(const Object& value);
+  ConstantInstr(const Object& value,
+                intptr_t token_pos = ClassifyingTokenPositions::kConstant);
 
   DECLARE_INSTRUCTION(Constant)
   virtual CompileType ComputeType() const;
@@ -2560,8 +2616,11 @@
 
   virtual bool AttributesEqual(Instruction* other) const;
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
   const Object& value_;
+  const intptr_t token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(ConstantInstr);
 };
@@ -2592,11 +2651,10 @@
 };
 
 
-class AssertAssignableInstr : public TemplateDefinition<3, Throws, Pure> {
+class AssertAssignableInstr : public TemplateDefinition<2, Throws, Pure> {
  public:
   AssertAssignableInstr(intptr_t token_pos,
                         Value* value,
-                        Value* instantiator,
                         Value* instantiator_type_arguments,
                         const AbstractType& dst_type,
                         const String& dst_name,
@@ -2608,8 +2666,7 @@
     ASSERT(!dst_type.IsNull());
     ASSERT(!dst_name.IsNull());
     SetInputAt(0, value);
-    SetInputAt(1, instantiator);
-    SetInputAt(2, instantiator_type_arguments);
+    SetInputAt(1, instantiator_type_arguments);
   }
 
   DECLARE_INSTRUCTION(AssertAssignable)
@@ -2617,8 +2674,7 @@
   virtual bool RecomputeType();
 
   Value* value() const { return inputs_[0]; }
-  Value* instantiator() const { return inputs_[1]; }
-  Value* instantiator_type_arguments() const { return inputs_[2]; }
+  Value* instantiator_type_arguments() const { return inputs_[1]; }
 
   virtual intptr_t token_pos() const { return token_pos_; }
   const AbstractType& dst_type() const { return dst_type_; }
@@ -3138,7 +3194,8 @@
   }
   virtual bool AttributesEqual(Instruction* other) const {
     IfThenElseInstr* other_if_then_else = other->AsIfThenElse();
-    return comparison()->AttributesEqual(other_if_then_else->comparison()) &&
+    return (comparison()->tag() == other_if_then_else->comparison()->tag()) &&
+           comparison()->AttributesEqual(other_if_then_else->comparison()) &&
            (if_true_ == other_if_then_else->if_true_) &&
            (if_false_ == other_if_then_else->if_false_);
   }
@@ -3254,8 +3311,9 @@
 
 class LoadLocalInstr : public TemplateDefinition<0, NoThrow> {
  public:
-  explicit LoadLocalInstr(const LocalVariable& local)
-      : local_(local), is_last_(false) { }
+  LoadLocalInstr(const LocalVariable& local,
+                 intptr_t token_pos = Scanner::kNoSourcePos)
+      : local_(local), is_last_(false), token_pos_(token_pos) { }
 
   DECLARE_INSTRUCTION(LoadLocal)
   virtual CompileType ComputeType() const;
@@ -3274,9 +3332,12 @@
   void mark_last() { is_last_ = true; }
   bool is_last() const { return is_last_; }
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
   const LocalVariable& local_;
   bool is_last_;
+  const intptr_t token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr);
 };
@@ -3301,6 +3362,10 @@
     return EffectSet::None();
   }
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kTempMove;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(PushTempInstr);
 };
@@ -3343,6 +3408,10 @@
     return false;
   }
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kTempMove;
+  }
+
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) {
     value_ = value;
@@ -3357,8 +3426,10 @@
 
 class StoreLocalInstr : public TemplateDefinition<1, NoThrow> {
  public:
-  StoreLocalInstr(const LocalVariable& local, Value* value)
-      : local_(local), is_dead_(false), is_last_(false) {
+  StoreLocalInstr(const LocalVariable& local,
+                  Value* value,
+                  intptr_t token_pos = Scanner::kNoSourcePos)
+      : local_(local), is_dead_(false), is_last_(false), token_pos_(token_pos) {
     SetInputAt(0, value);
   }
 
@@ -3383,10 +3454,13 @@
     return EffectSet::None();
   }
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
   const LocalVariable& local_;
   bool is_dead_;
   bool is_last_;
+  const intptr_t token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr);
 };
@@ -3395,7 +3469,9 @@
 class NativeCallInstr : public TemplateDefinition<0, Throws> {
  public:
   explicit NativeCallInstr(NativeBodyNode* node)
-      : ast_node_(*node) {}
+      : ast_node_(*node),
+        native_c_function_(NULL),
+        is_bootstrap_native_(false) { }
 
   DECLARE_INSTRUCTION(NativeCall)
 
@@ -3408,11 +3484,11 @@
   }
 
   NativeFunction native_c_function() const {
-    return ast_node_.native_c_function();
+    return native_c_function_;
   }
 
   bool is_bootstrap_native() const {
-    return ast_node_.is_bootstrap_native();
+    return is_bootstrap_native_;
   }
 
   bool link_lazily() const {
@@ -3425,8 +3501,18 @@
 
   virtual EffectSet Effects() const { return EffectSet::All(); }
 
+  void SetupNative();
+
  private:
+  void set_native_c_function(NativeFunction value) {
+    native_c_function_ = value;
+  }
+
+  void set_is_bootstrap_native(bool value) { is_bootstrap_native_ = value; }
+
   const NativeBodyNode& ast_node_;
+  NativeFunction native_c_function_;
+  bool is_bootstrap_native_;
 
   DISALLOW_COPY_AND_ASSIGN(NativeCallInstr);
 };
@@ -3636,7 +3722,8 @@
 
 class LoadStaticFieldInstr : public TemplateDefinition<1, NoThrow> {
  public:
-  explicit LoadStaticFieldInstr(Value* field_value) {
+  LoadStaticFieldInstr(Value* field_value, intptr_t token_pos)
+      : token_pos_(token_pos) {
     ASSERT(field_value->BindsToConstant());
     SetInputAt(0, field_value);
   }
@@ -3657,15 +3744,22 @@
   virtual EffectSet Dependencies() const;
   virtual bool AttributesEqual(Instruction* other) const;
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
+  const intptr_t token_pos_;
+
   DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr);
 };
 
 
 class StoreStaticFieldInstr : public TemplateDefinition<1, NoThrow> {
  public:
-  StoreStaticFieldInstr(const Field& field, Value* value)
-      : field_(field) {
+  StoreStaticFieldInstr(const Field& field,
+                        Value* value,
+                        intptr_t token_pos = Scanner::kNoSourcePos)
+      : field_(field),
+        token_pos_(token_pos) {
     ASSERT(field.IsZoneHandle());
     SetInputAt(kValuePos, value);
   }
@@ -3688,6 +3782,8 @@
   // are marked as having no side-effects.
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
+  virtual intptr_t token_pos() const { return token_pos_; }
+
  private:
   bool CanValueBeSmi() const {
     const intptr_t cid = value()->Type()->ToNullableCid();
@@ -3697,6 +3793,7 @@
   }
 
   const Field& field_;
+  const intptr_t token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldInstr);
 };
@@ -4000,11 +4097,10 @@
 };
 
 
-class InstanceOfInstr : public TemplateDefinition<3, Throws> {
+class InstanceOfInstr : public TemplateDefinition<2, Throws> {
  public:
   InstanceOfInstr(intptr_t token_pos,
                   Value* value,
-                  Value* instantiator,
                   Value* instantiator_type_arguments,
                   const AbstractType& type,
                   bool negate_result,
@@ -4015,16 +4111,14 @@
         negate_result_(negate_result) {
     ASSERT(!type.IsNull());
     SetInputAt(0, value);
-    SetInputAt(1, instantiator);
-    SetInputAt(2, instantiator_type_arguments);
+    SetInputAt(1, instantiator_type_arguments);
   }
 
   DECLARE_INSTRUCTION(InstanceOf)
   virtual CompileType ComputeType() const;
 
   Value* value() const { return inputs_[0]; }
-  Value* instantiator() const { return inputs_[1]; }
-  Value* instantiator_type_arguments() const { return inputs_[2]; }
+  Value* instantiator_type_arguments() const { return inputs_[1]; }
 
   bool negate_result() const { return negate_result_; }
   const AbstractType& type() const { return type_; }
@@ -4039,7 +4133,6 @@
  private:
   const intptr_t token_pos_;
   Value* value_;
-  Value* instantiator_;
   Value* type_arguments_;
   const AbstractType& type_;
   const bool negate_result_;
@@ -4366,7 +4459,8 @@
         field_(NULL),
         token_pos_(token_pos) {
     ASSERT(offset_in_bytes >= 0);
-    ASSERT(type.IsZoneHandle());  // May be null if field is not an instance.
+    // May be null if field is not an instance.
+    ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
     SetInputAt(0, instance);
   }
 
@@ -4382,7 +4476,8 @@
         field_(field),
         token_pos_(token_pos) {
     ASSERT(field->IsZoneHandle());
-    ASSERT(type.IsZoneHandle());  // May be null if field is not an instance.
+    // May be null if field is not an instance.
+    ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
     SetInputAt(0, instance);
   }
 
@@ -4457,7 +4552,7 @@
         token_pos_(token_pos),
         type_(type),
         instantiator_class_(instantiator_class) {
-    ASSERT(type.IsZoneHandle());
+    ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
     SetInputAt(0, instantiator);
   }
 
@@ -4714,6 +4809,10 @@
 
   Definition* Canonicalize(FlowGraph* flow_graph);
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kBox;
+  }
+
  protected:
   BoxInstr(Representation from_representation, Value* value)
       : from_representation_(from_representation) {
@@ -4836,6 +4935,10 @@
     return GetDeoptId();
   }
 
+  virtual intptr_t token_pos() const {
+    return ClassifyingTokenPositions::kBox;
+  }
+
  protected:
   UnboxInstr(Representation representation,
              Value* value,
@@ -6837,6 +6940,8 @@
                         Range* range);
 
  private:
+  Definition* CreateConstantResult(FlowGraph* graph, const Integer& result);
+
   const Token::Kind op_kind_;
 
   bool can_overflow_;
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index f7030f8..9120195 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -8,6 +8,7 @@
 #include "vm/intermediate_language.h"
 
 #include "vm/cpu.h"
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -227,8 +228,8 @@
   __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
 
   // R2: instructions entry point.
-  // R5: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value).
-  __ LoadImmediate(R5, 0);
+  // R9: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value).
+  __ LoadImmediate(R9, 0);
   __ blx(R2);
   compiler->RecordSafepoint(locs());
   // Marks either the continuation point in unoptimized code or the
@@ -344,13 +345,12 @@
 
 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(R0));  // Value.
-  summary->set_in(1, Location::RegisterLocation(R2));  // Instantiator.
-  summary->set_in(2, Location::RegisterLocation(R1));  // Type arguments.
+  summary->set_in(1, Location::RegisterLocation(R1));  // Type arguments.
   summary->set_out(0, Location::RegisterLocation(R0));
   return summary;
 }
@@ -925,6 +925,7 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   const Register result = locs()->out(0).reg();
 
   // Push the result place holder initialized to NULL.
@@ -942,7 +943,7 @@
   uword entry;
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
-    (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
   const StubEntry* stub_entry;
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapCFunction_entry();
@@ -970,7 +971,7 @@
   }
   __ LoadImmediate(R1, argc_tag);
   ExternalLabel label(entry);
-  __ LoadNativeEntry(R5, &label, link_lazily() ? kPatchable : kNotPatchable);
+  __ LoadNativeEntry(R9, &label, link_lazily() ? kPatchable : kNotPatchable);
   compiler->GenerateCall(token_pos(),
                          *stub_entry,
                          RawPcDescriptors::kOther,
@@ -2008,7 +2009,7 @@
   } else if (IsPotentialUnboxedStore()) {
     summary->set_in(1, ShouldEmitStoreBarrier()
         ? Location::WritableRegister()
-        :  Location::RequiresRegister());
+        : Location::RequiresRegister());
     summary->set_temp(0, Location::RequiresRegister());
     summary->set_temp(1, Location::RequiresRegister());
     summary->set_temp(2, opt ? Location::RequiresFpuRegister()
@@ -2273,13 +2274,12 @@
 
 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(R0));
-  summary->set_in(1, Location::RegisterLocation(R2));
-  summary->set_in(2, Location::RegisterLocation(R1));
+  summary->set_in(1, Location::RegisterLocation(R1));
   summary->set_out(0, Location::RegisterLocation(R0));
   return summary;
 }
@@ -2287,8 +2287,7 @@
 
 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(locs()->in(0).reg() == R0);  // Value.
-  ASSERT(locs()->in(1).reg() == R2);  // Instantiator.
-  ASSERT(locs()->in(2).reg() == R1);  // Instantiator type arguments.
+  ASSERT(locs()->in(1).reg() == R1);  // Instantiator type arguments.
 
   compiler->GenerateInstanceOf(token_pos(),
                                deopt_id(),
@@ -2325,8 +2324,8 @@
   __ TryAllocateArray(kArrayCid, instance_size, slow_path,
                       R0,  // instance
                       R3,  // end address
-                      R6,
-                      R10);
+                      R8,
+                      R6);
   // R0: new object start as a tagged pointer.
   // R3: new object end address.
 
@@ -2343,26 +2342,26 @@
   // Initialize all array elements to raw_null.
   // R0: new object start as a tagged pointer.
   // R3: new object end address.
-  // R10: iterator which initially points to the start of the variable
+  // R6: iterator which initially points to the start of the variable
   // data area to be initialized.
-  // R6: null
+  // R8: null
   if (num_elements > 0) {
     const intptr_t array_size = instance_size - sizeof(RawArray);
-    __ LoadObject(R6, Object::null_object());
+    __ LoadObject(R8, Object::null_object());
     if (num_elements >= 2) {
-      __ mov(R7, Operand(R6));
+      __ mov(R9, Operand(R8));
     } else {
 #if defined(DEBUG)
-      // Clobber R7 with an invalid pointer.
-      __ LoadImmediate(R7, 0x1);
+      // Clobber R9 with an invalid pointer.
+      __ LoadImmediate(R9, 0x1);
 #endif  // DEBUG
     }
-    __ AddImmediate(R10, R0, sizeof(RawArray) - kHeapObjectTag);
+    __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag);
     if (array_size < (kInlineArraySize * kWordSize)) {
-      __ InitializeFieldsNoBarrierUnrolled(R0, R10, 0, num_elements * kWordSize,
-                                           R6, R7);
+      __ InitializeFieldsNoBarrierUnrolled(R0, R6, 0, num_elements * kWordSize,
+                                           R8, R9);
     } else {
-      __ InitializeFieldsNoBarrier(R0, R10, R3, R6, R7);
+      __ InitializeFieldsNoBarrier(R0, R6, R3, R8, R9);
     }
   }
   __ b(done);
@@ -2378,6 +2377,7 @@
   ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
 
   if (compiler->is_optimizing() &&
+      !Compiler::always_optimize() &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
@@ -2445,7 +2445,7 @@
   if (IsUnboxedLoad() && compiler->is_optimizing()) {
     const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
     const Register temp = locs()->temp(0).reg();
-    __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
+    __ LoadFieldFromOffset(kWord, temp, instance_reg, offset_in_bytes());
     const intptr_t cid = field()->UnboxedFieldCid();
     switch (cid) {
       case kDoubleCid:
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 892a296..05ce132 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -7,6 +7,7 @@
 
 #include "vm/intermediate_language.h"
 
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -332,13 +333,12 @@
 
 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(R0));  // Value.
-  summary->set_in(1, Location::RegisterLocation(R2));  // Instantiator.
-  summary->set_in(2, Location::RegisterLocation(R1));  // Type arguments.
+  summary->set_in(1, Location::RegisterLocation(R1));  // Type arguments.
   summary->set_out(0, Location::RegisterLocation(R0));
   return summary;
 }
@@ -779,6 +779,7 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   const Register result = locs()->out(0).reg();
 
   // Push the result place holder initialized to NULL.
@@ -796,7 +797,7 @@
   uword entry;
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
-    (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
   const StubEntry* stub_entry;
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapCFunction_entry();
@@ -1993,13 +1994,12 @@
 
 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(R0));
-  summary->set_in(1, Location::RegisterLocation(R2));
-  summary->set_in(2, Location::RegisterLocation(R1));
+  summary->set_in(1, Location::RegisterLocation(R1));
   summary->set_out(0, Location::RegisterLocation(R0));
   return summary;
 }
@@ -2007,8 +2007,7 @@
 
 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(locs()->in(0).reg() == R0);  // Value.
-  ASSERT(locs()->in(1).reg() == R2);  // Instantiator.
-  ASSERT(locs()->in(2).reg() == R1);  // Instantiator type arguments.
+  ASSERT(locs()->in(1).reg() == R1);  // Instantiator type arguments.
 
   compiler->GenerateInstanceOf(token_pos(),
                                deopt_id(),
@@ -2101,6 +2100,7 @@
   ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
 
   if (compiler->is_optimizing() &&
+      !Compiler::always_optimize() &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index eab55fb..0c2f782 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -218,13 +218,12 @@
 
 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(EAX));  // Value.
-  summary->set_in(1, Location::RegisterLocation(ECX));  // Instantiator.
-  summary->set_in(2, Location::RegisterLocation(EDX));  // Type arguments.
+  summary->set_in(1, Location::RegisterLocation(EDX));  // Type arguments.
   summary->set_out(0, Location::RegisterLocation(EAX));
   return summary;
 }
@@ -818,6 +817,7 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   Register result = locs()->out(0).reg();
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
@@ -2009,13 +2009,12 @@
 
 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(EAX));
-  summary->set_in(1, Location::RegisterLocation(ECX));
-  summary->set_in(2, Location::RegisterLocation(EDX));
+  summary->set_in(1, Location::RegisterLocation(EDX));
   summary->set_out(0, Location::RegisterLocation(EAX));
   return summary;
 }
@@ -2023,8 +2022,7 @@
 
 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(locs()->in(0).reg() == EAX);  // Value.
-  ASSERT(locs()->in(1).reg() == ECX);  // Instantiator.
-  ASSERT(locs()->in(2).reg() == EDX);  // Instantiator type arguments.
+  ASSERT(locs()->in(1).reg() == EDX);  // Instantiator type arguments.
 
   compiler->GenerateInstanceOf(token_pos(),
                                deopt_id(),
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 8c07b90..e403445 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -7,6 +7,7 @@
 
 #include "vm/intermediate_language.h"
 
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -393,13 +394,12 @@
 
 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(A0));  // Value.
-  summary->set_in(1, Location::RegisterLocation(A2));  // Instantiator.
-  summary->set_in(2, Location::RegisterLocation(A1));  // Type arguments.
+  summary->set_in(1, Location::RegisterLocation(A1));  // Type arguments.
   summary->set_out(0, Location::RegisterLocation(A0));
   return summary;
 }
@@ -975,6 +975,7 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   __ Comment("NativeCallInstr");
   Register result = locs()->out(0).reg();
 
@@ -993,7 +994,7 @@
   uword entry;
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
-    (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
   const StubEntry* stub_entry;
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapCFunction_entry();
@@ -2126,13 +2127,12 @@
 
 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(A0));
-  summary->set_in(1, Location::RegisterLocation(A2));
-  summary->set_in(2, Location::RegisterLocation(A1));
+  summary->set_in(1, Location::RegisterLocation(A1));
   summary->set_out(0, Location::RegisterLocation(V0));
   return summary;
 }
@@ -2140,8 +2140,7 @@
 
 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(locs()->in(0).reg() == A0);  // Value.
-  ASSERT(locs()->in(1).reg() == A2);  // Instantiator.
-  ASSERT(locs()->in(2).reg() == A1);  // Instantiator type arguments.
+  ASSERT(locs()->in(1).reg() == A1);  // Instantiator type arguments.
 
   __ Comment("InstanceOfInstr");
   compiler->GenerateInstanceOf(token_pos(),
@@ -2232,6 +2231,7 @@
 
   Label slow_path, done;
   if (compiler->is_optimizing() &&
+      !Compiler::always_optimize() &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
@@ -2300,7 +2300,7 @@
   if (IsUnboxedLoad() && compiler->is_optimizing()) {
     DRegister result = locs()->out(0).fpu_reg();
     Register temp = locs()->temp(0).reg();
-    __ lw(temp, FieldAddress(instance_reg, offset_in_bytes()));
+    __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes());
     intptr_t cid = field()->UnboxedFieldCid();
     switch (cid) {
       case kDoubleCid:
@@ -4118,25 +4118,19 @@
 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(Zone* zone,
                                                          bool opt) const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresFpuRegister());
   summary->set_out(0, Location::RequiresFpuRegister());
-  summary->set_temp(0, Location::RequiresFpuRegister());
   return summary;
 }
 
 
 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // TODO(zra): Implement vneg.
-  const Double& minus_one = Double::ZoneHandle(Double::NewCanonical(-1));
-  __ LoadObject(TMP, minus_one);
   FpuRegister result = locs()->out(0).fpu_reg();
   FpuRegister value = locs()->in(0).fpu_reg();
-  FpuRegister temp_fp = locs()->temp(0).fpu_reg();
-  __ LoadDFromOffset(temp_fp, TMP, Double::value_offset() - kHeapObjectTag);
-  __ muld(result, value, temp_fp);
+  __ negd(result, value);
 }
 
 
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index cc19675..7ca52de 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -7,6 +7,7 @@
 
 #include "vm/intermediate_language.h"
 
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -304,13 +305,12 @@
 
 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(RAX));  // Value.
-  summary->set_in(1, Location::RegisterLocation(RCX));  // Instantiator.
-  summary->set_in(2, Location::RegisterLocation(RDX));  // Type arguments.
+  summary->set_in(1, Location::RegisterLocation(RDX));  // Type arguments.
   summary->set_out(0, Location::RegisterLocation(RAX));
   return summary;
 }
@@ -772,10 +772,11 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  SetupNative();
   Register result = locs()->out(0).reg();
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
-    (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
 
   // Push the result place holder initialized to NULL.
   __ PushObject(Object::null_object());
@@ -2011,13 +2012,12 @@
 
 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 3;
+  const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(zone) LocationSummary(
       zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(RAX));
-  summary->set_in(1, Location::RegisterLocation(RCX));
-  summary->set_in(2, Location::RegisterLocation(RDX));
+  summary->set_in(1, Location::RegisterLocation(RDX));
   summary->set_out(0, Location::RegisterLocation(RAX));
   return summary;
 }
@@ -2025,8 +2025,7 @@
 
 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(locs()->in(0).reg() == RAX);  // Value.
-  ASSERT(locs()->in(1).reg() == RCX);  // Instantiator.
-  ASSERT(locs()->in(2).reg() == RDX);  // Instantiator type arguments.
+  ASSERT(locs()->in(1).reg() == RDX);  // Instantiator type arguments.
 
   compiler->GenerateInstanceOf(token_pos(),
                                deopt_id(),
@@ -2116,6 +2115,7 @@
 
   Label slow_path, done;
   if (compiler->is_optimizing() &&
+      !Compiler::always_optimize() &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 83681cd..c3356b3 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -4,18 +4,19 @@
 // Class for intrinsifying functions.
 
 #include "vm/assembler.h"
-#include "vm/intrinsifier.h"
+#include "vm/compiler.h"
 #include "vm/flags.h"
-#include "vm/object.h"
-#include "vm/symbols.h"
-
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
 #include "vm/flow_graph_allocator.h"
 #include "vm/flow_graph_builder.h"
 #include "vm/il_printer.h"
 #include "vm/intermediate_language.h"
+#include "vm/intrinsifier.h"
+#include "vm/object.h"
 #include "vm/parser.h"
+#include "vm/symbols.h"
+
 
 namespace dart {
 
@@ -133,14 +134,14 @@
   FlowGraphBuilder builder(parsed_function,
                            *ic_data_array,
                            NULL,  // NULL = not inlining.
-                           Thread::kNoDeoptId);  // No OSR id.
+                           Compiler::kNoOSRDeoptId);
 
   intptr_t block_id = builder.AllocateBlockId();
   TargetEntryInstr* normal_entry =
       new TargetEntryInstr(block_id,
                            CatchClauseNode::kInvalidTryIndex);
   GraphEntryInstr* graph_entry = new GraphEntryInstr(
-      parsed_function, normal_entry, Thread::kNoDeoptId);  // No OSR id.
+      parsed_function, normal_entry, Compiler::kNoOSRDeoptId);
   FlowGraph* graph = new FlowGraph(parsed_function, graph_entry, block_id);
   const Function& function = parsed_function.function();
   switch (function.recognized_kind()) {
@@ -867,4 +868,23 @@
   return true;
 }
 
+
+bool Intrinsifier::Build_DoubleFlipSignBit(FlowGraph* flow_graph) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* receiver = builder.AddParameter(1);
+  Definition* unboxed_value =
+      builder.AddUnboxInstr(kUnboxedDouble, new Value(receiver));
+  Definition* unboxed_result = builder.AddDefinition(
+      new UnaryDoubleOpInstr(Token::kNEGATE,
+                             new Value(unboxed_value),
+                             Thread::kNoDeoptId));
+  Definition* result = builder.AddDefinition(
+      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index dd6d509..bb3121f 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -21,13 +21,12 @@
 DECLARE_FLAG(bool, interpret_irregexp);
 
 // When entering intrinsics code:
-// R5: IC Data
 // R4: Arguments descriptor
 // LR: Return address
-// The R5, R4 registers can be destroyed only if there is no slow-path, i.e.
+// The R4 register can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The FP register should not be modified, because it is used by the profiler.
-// The THR register (see constants_arm.h) must be preserved.
+// The PP and THR registers (see constants_arm.h) must be preserved.
 
 #define __ assembler->
 
@@ -216,18 +215,18 @@
   /* R2: allocation size. */                                                   \
   /* R3: iterator which initially points to the start of the variable */       \
   /* R4: allocation stats address */                                           \
-  /* R6, R7: zero. */                                                          \
+  /* R8, R9: zero. */                                                          \
   /* data area to be initialized. */                                           \
-  __ LoadImmediate(R6, 0);                                                     \
-  __ mov(R7, Operand(R6));                                                     \
+  __ LoadImmediate(R8, 0);                                                     \
+  __ mov(R9, Operand(R8));                                                     \
   __ AddImmediate(R3, R0, sizeof(Raw##type_name) - 1);                         \
   Label init_loop;                                                             \
   __ Bind(&init_loop);                                                         \
   __ AddImmediate(R3, 2 * kWordSize);                                          \
   __ cmp(R3, Operand(R1));                                                     \
-  __ strd(R6, R3, -2 * kWordSize, LS);                                         \
+  __ strd(R8, R9, R3, -2 * kWordSize, LS);                                     \
   __ b(&init_loop, CC);                                                        \
-  __ str(R6, Address(R3, -2 * kWordSize), HI);                                 \
+  __ str(R8, Address(R3, -2 * kWordSize), HI);                                 \
                                                                                \
   __ IncrementAllocationStatsWithSize(R4, R2, space);                          \
   __ Ret();                                                                    \
@@ -314,7 +313,7 @@
 void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
-  __ SmiUntag(R0);  // Untags R6. We only want result shifted by one.
+  __ SmiUntag(R0);  // Untags R0. We only want result shifted by one.
   __ smull(R0, IP, R0, R1);  // IP:R0 <- R0 * R1.
   __ cmp(IP, Operand(R0, ASR, 31));
   __ bx(LR, EQ);
@@ -507,7 +506,7 @@
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
   Label fall_through;
-  __ Push(R10);
+  __ Push(R6);
   TestBothArgumentsSmis(assembler, &fall_through);
   __ CompareImmediate(R0, Smi::RawValue(Smi::kBits));
   __ b(&fall_through, HI);
@@ -532,14 +531,14 @@
   // ((1 << R0) - 1), shifting it to the left, masking R1, then shifting back.
   // high bits = (((1 << R0) - 1) << (32 - R0)) & R1) >> (32 - R0)
   // lo bits = R1 << R0
-  __ LoadImmediate(R7, 1);
-  __ mov(R7, Operand(R7, LSL, R0));  // R7 <- 1 << R0
-  __ sub(R7, R7, Operand(1));  // R7 <- R7 - 1
-  __ rsb(R10, R0, Operand(32));  // R10 <- 32 - R0
-  __ mov(R7, Operand(R7, LSL, R10));  // R7 <- R7 << R10
-  __ and_(R7, R1, Operand(R7));  // R7 <- R7 & R1
-  __ mov(R7, Operand(R7, LSR, R10));  // R7 <- R7 >> R10
-  // Now R7 has the bits that fall off of R1 on a left shift.
+  __ LoadImmediate(NOTFP, 1);
+  __ mov(NOTFP, Operand(NOTFP, LSL, R0));  // NOTFP <- 1 << R0
+  __ sub(NOTFP, NOTFP, Operand(1));  // NOTFP <- NOTFP - 1
+  __ rsb(R6, R0, Operand(32));  // R6 <- 32 - R0
+  __ mov(NOTFP, Operand(NOTFP, LSL, R6));  // NOTFP <- NOTFP << R6
+  __ and_(NOTFP, R1, Operand(NOTFP));  // NOTFP <- NOTFP & R1
+  __ mov(NOTFP, Operand(NOTFP, LSR, R6));  // NOTFP <- NOTFP >> R6
+  // Now NOTFP has the bits that fall off of R1 on a left shift.
   __ mov(R1, Operand(R1, LSL, R0));  // R1 gets the low bits.
 
   const Class& mint_class = Class::Handle(
@@ -548,12 +547,12 @@
 
 
   __ str(R1, FieldAddress(R0, Mint::value_offset()));
-  __ str(R7, FieldAddress(R0, Mint::value_offset() + kWordSize));
-  __ Pop(R10);
+  __ str(NOTFP, FieldAddress(R0, Mint::value_offset() + kWordSize));
+  __ Pop(R6);
   __ Ret();
   __ Bind(&fall_through);
-  ASSERT(CODE_REG == R10);
-  __ Pop(R10);
+  ASSERT(CODE_REG == R6);
+  __ Pop(R6);
 }
 
 
@@ -622,16 +621,16 @@
   // Get left as 64 bit integer.
   Get64SmiOrMint(assembler, R3, R2, R1, &fall_through);
   // Get right as 64 bit integer.
-  Get64SmiOrMint(assembler, R7, R6, R0, &fall_through);
+  Get64SmiOrMint(assembler, NOTFP, R8, R0, &fall_through);
   // R3: left high.
   // R2: left low.
-  // R7: right high.
-  // R6: right low.
+  // NOTFP: right high.
+  // R8: right low.
 
-  __ cmp(R3, Operand(R7));  // Compare left hi, right high.
+  __ cmp(R3, Operand(NOTFP));  // Compare left hi, right high.
   __ b(&is_false, hi_false_cond);
   __ b(&is_true, hi_true_cond);
-  __ cmp(R2, Operand(R6));  // Compare left lo, right lo.
+  __ cmp(R2, Operand(R8));  // Compare left lo, right lo.
   __ b(&is_false, lo_false_cond);
   // Else is true.
   __ b(&is_true);
@@ -768,37 +767,37 @@
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
-  // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
-  __ ldrd(R2, SP, 2 * kWordSize);
-  // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
-  __ ldrd(R4, SP, 0 * kWordSize);
-  __ SmiUntag(R5);
-  // R0 = n ~/ _DIGIT_BITS
-  __ Asr(R0, R5, Operand(5));
-  // R6 = &x_digits[0]
-  __ add(R6, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-  // R7 = &x_digits[x_used]
-  __ add(R7, R6, Operand(R2, LSL, 1));
-  // R10 = &r_digits[1]
-  __ add(R10, R4, Operand(TypedData::data_offset() - kHeapObjectTag +
+  // R0 = x_used, R1 = x_digits, x_used > 0, x_used is Smi.
+  __ ldrd(R0, R1, SP, 2 * kWordSize);
+  // R2 = r_digits, R3 = n, n is Smi, n % _DIGIT_BITS != 0.
+  __ ldrd(R2, R3, SP, 0 * kWordSize);
+  __ SmiUntag(R3);
+  // R4 = n ~/ _DIGIT_BITS
+  __ Asr(R4, R3, Operand(5));
+  // R8 = &x_digits[0]
+  __ add(R8, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &x_digits[x_used]
+  __ add(NOTFP, R8, Operand(R0, LSL, 1));
+  // R6 = &r_digits[1]
+  __ add(R6, R2, Operand(TypedData::data_offset() - kHeapObjectTag +
                          Bigint::kBytesPerDigit));
-  // R10 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
-  __ add(R0, R0, Operand(R2, ASR, 1));
-  __ add(R10, R10, Operand(R0, LSL, 2));
-  // R3 = n % _DIGIT_BITS
-  __ and_(R3, R5, Operand(31));
-  // R2 = 32 - R3
-  __ rsb(R2, R3, Operand(32));
-  __ mov(R1, Operand(0));
+  // R6 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
+  __ add(R4, R4, Operand(R0, ASR, 1));
+  __ add(R6, R6, Operand(R4, LSL, 2));
+  // R1 = n % _DIGIT_BITS
+  __ and_(R1, R3, Operand(31));
+  // R0 = 32 - R1
+  __ rsb(R0, R1, Operand(32));
+  __ mov(R9, Operand(0));
   Label loop;
   __ Bind(&loop);
-  __ ldr(R0, Address(R7, -Bigint::kBytesPerDigit, Address::PreIndex));
-  __ orr(R1, R1, Operand(R0, LSR, R2));
-  __ str(R1, Address(R10, -Bigint::kBytesPerDigit, Address::PreIndex));
-  __ mov(R1, Operand(R0, LSL, R3));
-  __ teq(R7, Operand(R6));
+  __ ldr(R4, Address(NOTFP, -Bigint::kBytesPerDigit, Address::PreIndex));
+  __ orr(R9, R9, Operand(R4, LSR, R0));
+  __ str(R9, Address(R6, -Bigint::kBytesPerDigit, Address::PreIndex));
+  __ mov(R9, Operand(R4, LSL, R1));
+  __ teq(NOTFP, Operand(R8));
   __ b(&loop, NE);
-  __ str(R1, Address(R10, -Bigint::kBytesPerDigit, Address::PreIndex));
+  __ str(R9, Address(R6, -Bigint::kBytesPerDigit, Address::PreIndex));
   // Returning Object::null() is not required, since this method is private.
   __ Ret();
 }
@@ -808,41 +807,41 @@
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
-  // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
-  __ ldrd(R2, SP, 2 * kWordSize);
-  // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
-  __ ldrd(R4, SP, 0 * kWordSize);
-  __ SmiUntag(R5);
-  // R0 = n ~/ _DIGIT_BITS
-  __ Asr(R0, R5, Operand(5));
-  // R10 = &r_digits[0]
-  __ add(R10, 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, R10, Operand(R0, LSL, 2));
-  // R3 = n % _DIGIT_BITS
-  __ and_(R3, R5, Operand(31));
-  // R2 = 32 - R3
-  __ rsb(R2, R3, Operand(32));
-  // R1 = x_digits[n ~/ _DIGIT_BITS] >> (n % _DIGIT_BITS)
-  __ ldr(R1, Address(R7, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ mov(R1, Operand(R1, LSR, R3));
+  // R0 = x_used, R1 = x_digits, x_used > 0, x_used is Smi.
+  __ ldrd(R0, R1, SP, 2 * kWordSize);
+  // R2 = r_digits, R3 = n, n is Smi, n % _DIGIT_BITS != 0.
+  __ ldrd(R2, R3, SP, 0 * kWordSize);
+  __ SmiUntag(R3);
+  // R4 = n ~/ _DIGIT_BITS
+  __ Asr(R4, R3, Operand(5));
+  // R6 = &r_digits[0]
+  __ add(R6, R2, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &x_digits[n ~/ _DIGIT_BITS]
+  __ add(NOTFP, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+  __ add(NOTFP, NOTFP, Operand(R4, LSL, 2));
+  // R8 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1]
+  __ add(R4, R4, Operand(1));
+  __ rsb(R4, R4, Operand(R0, ASR, 1));
+  __ add(R8, R6, Operand(R4, LSL, 2));
+  // R1 = n % _DIGIT_BITS
+  __ and_(R1, R3, Operand(31));
+  // R0 = 32 - R1
+  __ rsb(R0, R1, Operand(32));
+  // R9 = x_digits[n ~/ _DIGIT_BITS] >> (n % _DIGIT_BITS)
+  __ ldr(R9, Address(NOTFP, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ mov(R9, Operand(R9, LSR, R1));
   Label loop_entry;
   __ b(&loop_entry);
   Label loop;
   __ Bind(&loop);
-  __ ldr(R0, Address(R7, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ orr(R1, R1, Operand(R0, LSL, R2));
-  __ str(R1, Address(R10, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ mov(R1, Operand(R0, LSR, R3));
+  __ ldr(R4, Address(NOTFP, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ orr(R9, R9, Operand(R4, LSL, R0));
+  __ str(R9, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ mov(R9, Operand(R4, LSR, R1));
   __ Bind(&loop_entry);
-  __ teq(R10, Operand(R6));
+  __ teq(R6, Operand(R8));
   __ b(&loop, NE);
-  __ str(R1, Address(R10, 0));
+  __ str(R9, Address(R6, 0));
   // Returning Object::null() is not required, since this method is private.
   __ Ret();
 }
@@ -853,55 +852,55 @@
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
 
-  // R2 = used, R3 = digits
-  __ ldrd(R2, SP, 3 * kWordSize);
-  // R3 = &digits[0]
+  // R0 = used, R1 = digits
+  __ ldrd(R0, R1, SP, 3 * kWordSize);
+  // R1 = &digits[0]
+  __ add(R1, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+
+  // R2 = a_used, R3 = a_digits
+  __ ldrd(R2, R3, SP, 1 * kWordSize);
+  // R3 = &a_digits[0]
   __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R4 = a_used, R5 = a_digits
-  __ ldrd(R4, SP, 1 * kWordSize);
-  // R5 = &a_digits[0]
-  __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // R8 = r_digits
+  __ ldr(R8, Address(SP, 0 * kWordSize));
+  // R8 = &r_digits[0]
+  __ add(R8, R8, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R6 = r_digits
-  __ ldr(R6, Address(SP, 0 * kWordSize));
-  // R6 = &r_digits[0]
-  __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &digits[a_used >> 1], a_used is Smi.
+  __ add(NOTFP, R1, Operand(R2, LSL, 1));
 
-  // R7 = &digits[a_used >> 1], a_used is Smi.
-  __ add(R7, R3, Operand(R4, LSL, 1));
+  // R6 = &digits[used >> 1], used is Smi.
+  __ add(R6, R1, Operand(R0, LSL, 1));
 
-  // R10 = &digits[used >> 1], used is Smi.
-  __ add(R10, R3, Operand(R2, LSL, 1));
-
-  __ adds(R0, R0, Operand(0));  // carry flag = 0
+  __ adds(R4, R4, Operand(0));  // carry flag = 0
   Label add_loop;
   __ Bind(&add_loop);
   // Loop a_used times, a_used > 0.
-  __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ ldr(R1, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ adcs(R0, R0, Operand(R1));
-  __ teq(R3, Operand(R7));  // Does not affect carry flag.
-  __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R4, Address(R1, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R9, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ adcs(R4, R4, Operand(R9));
+  __ teq(R1, Operand(NOTFP));  // Does not affect carry flag.
+  __ str(R4, Address(R8, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&add_loop, NE);
 
   Label last_carry;
-  __ teq(R3, Operand(R10));  // Does not affect carry flag.
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
   __ b(&last_carry, EQ);  // If used - a_used == 0.
 
   Label carry_loop;
   __ Bind(&carry_loop);
   // Loop used - a_used times, used - a_used > 0.
-  __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ adcs(R0, R0, Operand(0));
-  __ teq(R3, Operand(R10));  // Does not affect carry flag.
-  __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R4, Address(R1, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ adcs(R4, R4, Operand(0));
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
+  __ str(R4, Address(R8, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&carry_loop, NE);
 
   __ Bind(&last_carry);
-  __ mov(R0, Operand(0));
-  __ adc(R0, R0, Operand(0));
-  __ str(R0, Address(R6, 0));
+  __ mov(R4, Operand(0));
+  __ adc(R4, R4, Operand(0));
+  __ str(R4, Address(R8, 0));
 
   // Returning Object::null() is not required, since this method is private.
   __ Ret();
@@ -913,49 +912,49 @@
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
 
-  // R2 = used, R3 = digits
-  __ ldrd(R2, SP, 3 * kWordSize);
-  // R3 = &digits[0]
+  // R0 = used, R1 = digits
+  __ ldrd(R0, R1, SP, 3 * kWordSize);
+  // R1 = &digits[0]
+  __ add(R1, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+
+  // R2 = a_used, R3 = a_digits
+  __ ldrd(R2, R3, SP, 1 * kWordSize);
+  // R3 = &a_digits[0]
   __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R4 = a_used, R5 = a_digits
-  __ ldrd(R4, SP, 1 * kWordSize);
-  // R5 = &a_digits[0]
-  __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // R8 = r_digits
+  __ ldr(R8, Address(SP, 0 * kWordSize));
+  // R8 = &r_digits[0]
+  __ add(R8, R8, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R6 = r_digits
-  __ ldr(R6, Address(SP, 0 * kWordSize));
-  // R6 = &r_digits[0]
-  __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &digits[a_used >> 1], a_used is Smi.
+  __ add(NOTFP, R1, Operand(R2, LSL, 1));
 
-  // R7 = &digits[a_used >> 1], a_used is Smi.
-  __ add(R7, R3, Operand(R4, LSL, 1));
+  // R6 = &digits[used >> 1], used is Smi.
+  __ add(R6, R1, Operand(R0, LSL, 1));
 
-  // R10 = &digits[used >> 1], used is Smi.
-  __ add(R10, R3, Operand(R2, LSL, 1));
-
-  __ subs(R0, R0, Operand(0));  // carry flag = 1
+  __ subs(R4, R4, Operand(0));  // carry flag = 1
   Label sub_loop;
   __ Bind(&sub_loop);
   // Loop a_used times, a_used > 0.
-  __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ ldr(R1, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ sbcs(R0, R0, Operand(R1));
-  __ teq(R3, Operand(R7));  // Does not affect carry flag.
-  __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R4, Address(R1, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R9, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ sbcs(R4, R4, Operand(R9));
+  __ teq(R1, Operand(NOTFP));  // Does not affect carry flag.
+  __ str(R4, Address(R8, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&sub_loop, NE);
 
   Label done;
-  __ teq(R3, Operand(R10));  // Does not affect carry flag.
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
   __ b(&done, EQ);  // If used - a_used == 0.
 
   Label carry_loop;
   __ Bind(&carry_loop);
   // Loop used - a_used times, used - a_used > 0.
-  __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
-  __ sbcs(R0, R0, Operand(0));
-  __ teq(R3, Operand(R10));  // Does not affect carry flag.
-  __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ ldr(R4, Address(R1, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ sbcs(R4, R4, Operand(0));
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
+  __ str(R4, Address(R8, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&carry_loop, NE);
 
   __ Bind(&done);
@@ -994,26 +993,26 @@
 
   Label done;
   // R3 = x, no_op if x == 0
-  __ ldrd(R0, SP, 5 * kWordSize);  // R0 = xi as Smi, R1 = x_digits.
+  __ ldrd(R0, R1, SP, 5 * kWordSize);  // R0 = xi as Smi, R1 = x_digits.
   __ add(R1, R1, Operand(R0, LSL, 1));
   __ ldr(R3, FieldAddress(R1, TypedData::data_offset()));
   __ tst(R3, Operand(R3));
   __ b(&done, EQ);
 
-  // R6 = SmiUntag(n), no_op if n == 0
-  __ ldr(R6, Address(SP, 0 * kWordSize));
-  __ Asrs(R6, R6, Operand(kSmiTagSize));
+  // R8 = SmiUntag(n), no_op if n == 0
+  __ ldr(R8, Address(SP, 0 * kWordSize));
+  __ Asrs(R8, R8, Operand(kSmiTagSize));
   __ b(&done, EQ);
 
   // R4 = mip = &m_digits[i >> 1]
-  __ ldrd(R0, SP, 3 * kWordSize);  // R0 = i as Smi, R1 = m_digits.
+  __ ldrd(R0, R1, SP, 3 * kWordSize);  // R0 = i as Smi, R1 = m_digits.
   __ add(R1, R1, Operand(R0, LSL, 1));
   __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R5 = ajp = &a_digits[j >> 1]
-  __ ldrd(R0, SP, 1 * kWordSize);  // R0 = j as Smi, R1 = a_digits.
+  // R9 = ajp = &a_digits[j >> 1]
+  __ ldrd(R0, R1, SP, 1 * kWordSize);  // R0 = j as Smi, R1 = a_digits.
   __ add(R1, R1, Operand(R0, LSL, 1));
-  __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+  __ add(R9, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
 
   // R1 = c = 0
   __ mov(R1, Operand(0));
@@ -1022,42 +1021,42 @@
   __ Bind(&muladd_loop);
   // x:   R3
   // mip: R4
-  // ajp: R5
+  // ajp: R9
   // c:   R1
-  // n:   R6
+  // n:   R8
 
   // uint32_t mi = *mip++
   __ ldr(R2, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex));
 
   // uint32_t aj = *ajp
-  __ ldr(R0, Address(R5, 0));
+  __ ldr(R0, Address(R9, 0));
 
   // uint64_t t = x*mi + aj + c
   __ umaal(R0, R1, R2, R3);  // R1:R0 = R2*R3 + R1 + R0.
 
   // *ajp++ = low32(t) = R0
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(R9, Bigint::kBytesPerDigit, Address::PostIndex));
 
   // c = high32(t) = R1
 
   // while (--n > 0)
-  __ subs(R6, R6, Operand(1));  // --n
+  __ subs(R8, R8, Operand(1));  // --n
   __ b(&muladd_loop, NE);
 
   __ tst(R1, Operand(R1));
   __ b(&done, EQ);
 
   // *ajp++ += c
-  __ ldr(R0, Address(R5, 0));
+  __ ldr(R0, Address(R9, 0));
   __ adds(R0, R0, Operand(R1));
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(R9, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&done, CC);
 
   Label propagate_carry_loop;
   __ Bind(&propagate_carry_loop);
-  __ ldr(R0, Address(R5, 0));
+  __ ldr(R0, Address(R9, 0));
   __ adds(R0, R0, Operand(1));
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(R9, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&propagate_carry_loop, CS);
 
   __ Bind(&done);
@@ -1094,7 +1093,7 @@
   // }
 
   // R4 = xip = &x_digits[i >> 1]
-  __ ldrd(R2, SP, 2 * kWordSize);  // R2 = i as Smi, R3 = x_digits
+  __ ldrd(R2, R3, SP, 2 * kWordSize);  // R2 = i as Smi, R3 = x_digits
   __ add(R3, R3, Operand(R2, LSL, 1));
   __ add(R4, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
 
@@ -1104,28 +1103,28 @@
   __ tst(R3, Operand(R3));
   __ b(&x_zero, EQ);
 
-  // R5 = ajp = &a_digits[i]
+  // NOTFP = ajp = &a_digits[i]
   __ ldr(R1, Address(SP, 1 * kWordSize));  // a_digits
   __ add(R1, R1, Operand(R2, LSL, 2));  // j == 2*i, i is Smi.
-  __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
+  __ add(NOTFP, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
 
-  // R6:R0 = t = x*x + *ajp
-  __ ldr(R0, Address(R5, 0));
-  __ mov(R6, Operand(0));
-  __ umaal(R0, R6, R3, R3);  // R6:R0 = R3*R3 + R6 + R0.
+  // R8:R0 = t = x*x + *ajp
+  __ ldr(R0, Address(NOTFP, 0));
+  __ mov(R8, Operand(0));
+  __ umaal(R0, R8, R3, R3);  // R8:R0 = R3*R3 + R8 + R0.
 
   // *ajp++ = low32(t) = R0
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(NOTFP, Bigint::kBytesPerDigit, Address::PostIndex));
 
-  // R6 = low32(c) = high32(t)
-  // R7 = high32(c) = 0
-  __ mov(R7, Operand(0));
+  // R8 = low32(c) = high32(t)
+  // R9 = high32(c) = 0
+  __ mov(R9, Operand(0));
 
   // int n = used - i - 1; while (--n >= 0) ...
   __ ldr(R0, Address(SP, 0 * kWordSize));  // used is Smi
-  __ sub(R10, R0, Operand(R2));
+  __ sub(R6, R0, Operand(R2));
   __ mov(R0, Operand(2));  // n = used - i - 2; if (n >= 0) ... while (--n >= 0)
-  __ rsbs(R10, R0, Operand(R10, ASR, kSmiTagSize));
+  __ rsbs(R6, R0, Operand(R6, ASR, kSmiTagSize));
 
   Label loop, done;
   __ b(&done, MI);
@@ -1133,46 +1132,46 @@
   __ Bind(&loop);
   // x:   R3
   // xip: R4
-  // ajp: R5
-  // c:   R7:R6
+  // ajp: NOTFP
+  // c:   R9:R8
   // t:   R2:R1:R0 (not live at loop entry)
-  // n:   R10
+  // n:   R6
 
   // uint32_t xi = *xip++
   __ ldr(R2, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex));
 
-  // uint96_t t = R7:R6:R0 = 2*x*xi + aj + c
+  // uint96_t t = R9:R8:R0 = 2*x*xi + aj + c
   __ umull(R0, R1, R2, R3);  // R1:R0 = R2*R3.
   __ adds(R0, R0, Operand(R0));
   __ adcs(R1, R1, Operand(R1));
   __ mov(R2, Operand(0));
   __ adc(R2, R2, Operand(0));  // R2:R1:R0 = 2*x*xi.
-  __ adds(R0, R0, Operand(R6));
-  __ adcs(R1, R1, Operand(R7));
+  __ adds(R0, R0, Operand(R8));
+  __ adcs(R1, R1, Operand(R9));
   __ adc(R2, R2, Operand(0));  // R2:R1:R0 = 2*x*xi + c.
-  __ ldr(R6, Address(R5, 0));  // R6 = aj = *ajp.
-  __ adds(R0, R0, Operand(R6));
-  __ adcs(R6, R1, Operand(0));
-  __ adc(R7, R2, Operand(0));  // R7:R6:R0 = 2*x*xi + c + aj.
+  __ ldr(R8, Address(NOTFP, 0));  // R8 = aj = *ajp.
+  __ adds(R0, R0, Operand(R8));
+  __ adcs(R8, R1, Operand(0));
+  __ adc(R9, R2, Operand(0));  // R9:R8:R0 = 2*x*xi + c + aj.
 
   // *ajp++ = low32(t) = R0
-  __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R0, Address(NOTFP, Bigint::kBytesPerDigit, Address::PostIndex));
 
   // while (--n >= 0)
-  __ subs(R10, R10, Operand(1));  // --n
+  __ subs(R6, R6, Operand(1));  // --n
   __ b(&loop, PL);
 
   __ Bind(&done);
   // uint32_t aj = *ajp
-  __ ldr(R0, Address(R5, 0));
+  __ ldr(R0, Address(NOTFP, 0));
 
   // uint64_t t = aj + c
-  __ adds(R6, R6, Operand(R0));
-  __ adc(R7, R7, Operand(0));
+  __ adds(R8, R8, Operand(R0));
+  __ adc(R9, R9, Operand(0));
 
-  // *ajp = low32(t) = R6
-  // *(ajp + 1) = high32(t) = R7
-  __ strd(R6, R5, 0);
+  // *ajp = low32(t) = R8
+  // *(ajp + 1) = high32(t) = R9
+  __ strd(R8, R9, NOTFP, 0);
 
   __ Bind(&x_zero);
   __ mov(R0, Operand(Smi::RawValue(1)));  // One digit processed.
@@ -1203,7 +1202,7 @@
                           TypedData::data_offset() + 2*Bigint::kBytesPerDigit));
 
   // R2 = digits[i >> 1]
-  __ ldrd(R0, SP, 0 * kWordSize);  // R0 = i as Smi, R1 = digits
+  __ ldrd(R0, R1, SP, 0 * kWordSize);  // R0 = i as Smi, R1 = digits
   __ add(R1, R1, Operand(R0, LSL, 1));
   __ ldr(R2, FieldAddress(R1, TypedData::data_offset()));
 
@@ -1514,11 +1513,11 @@
   __ LoadImmediate(R0, a_int32_value);
   __ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag);
   __ LoadFromOffset(kWord, R3, R1, disp_1 - kHeapObjectTag);
-  __ mov(R6, Operand(0));  // Zero extend unsigned _state[kSTATE_HI].
-  // Unsigned 32-bit multiply and 64-bit accumulate into R6:R3.
-  __ umlal(R3, R6, R0, R2);  // R6:R3 <- R6:R3 + R0 * R2.
+  __ mov(R8, Operand(0));  // Zero extend unsigned _state[kSTATE_HI].
+  // Unsigned 32-bit multiply and 64-bit accumulate into R8:R3.
+  __ umlal(R3, R8, R0, R2);  // R8:R3 <- R8:R3 + R0 * R2.
   __ StoreToOffset(kWord, R3, R1, disp_0 - kHeapObjectTag);
-  __ StoreToOffset(kWord, R6, R1, disp_1 - kHeapObjectTag);
+  __ StoreToOffset(kWord, R8, R1, disp_1 - kHeapObjectTag);
   __ Ret();
 }
 
@@ -1598,6 +1597,127 @@
 }
 
 
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ SmiUntag(R1);
+  __ ldr(R8, FieldAddress(R0, String::length_offset()));  // this.length
+  __ SmiUntag(R8);
+  __ ldr(R9, FieldAddress(R2, String::length_offset()));  // other.length
+  __ SmiUntag(R9);
+
+  // if (other.length == 0) return true;
+  __ cmp(R9, Operand(0));
+  __ b(return_true, EQ);
+
+  // if (start < 0) return false;
+  __ cmp(R1, Operand(0));
+  __ b(return_false, LT);
+
+  // if (start + other.length > this.length) return false;
+  __ add(R3, R1, Operand(R9));
+  __ cmp(R3, Operand(R8));
+  __ b(return_false, GT);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+    __ add(R0, R0, Operand(R1));
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ AddImmediate(R2, R2, OneByteString::data_offset() - kHeapObjectTag);
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ AddImmediate(R2, R2, TwoByteString::data_offset() - kHeapObjectTag);
+  }
+
+  // i = 0
+  __ LoadImmediate(R3, 0);
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ ldrb(R4, Address(R0, 0));     // this.codeUnitAt(i + start)
+  } else {
+    __ ldrh(R4, Address(R0, 0));     // this.codeUnitAt(i + start)
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ ldrb(NOTFP, Address(R2, 0));  // other.codeUnitAt(i)
+  } else {
+    __ ldrh(NOTFP, Address(R2, 0));  // other.codeUnitAt(i)
+  }
+  __ cmp(R4, Operand(NOTFP));
+  __ b(return_false, NE);
+
+  // i++, while (i < len)
+  __ AddImmediate(R3, R3, 1);
+  __ AddImmediate(R0, R0, receiver_cid == kOneByteStringCid ? 1 : 2);
+  __ AddImmediate(R2, R2, other_cid == kOneByteStringCid ? 1 : 2);
+  __ cmp(R3, Operand(R9));
+  __ b(&loop, LT);
+
+  __ b(return_true);
+}
+
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  Label fall_through, return_true, return_false, try_two_byte;
+  __ ldr(R0, Address(SP, 2 * kWordSize));  // this
+  __ ldr(R1, Address(SP, 1 * kWordSize));  // start
+  __ ldr(R2, Address(SP, 0 * kWordSize));  // other
+  __ Push(R4);  // Make ARGS_DESC_REG available.
+
+  __ tst(R1, Operand(kSmiTagMask));
+  __ b(&fall_through, NE);  // 'start' is not a Smi.
+
+  __ CompareClassId(R2, kOneByteStringCid, R3);
+  __ b(&fall_through, NE);
+
+  __ CompareClassId(R0, kOneByteStringCid, R3);
+  __ b(&try_two_byte, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kOneByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ CompareClassId(R0, kTwoByteStringCid, R3);
+  __ b(&fall_through, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kTwoByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ Pop(R4);
+  __ LoadObject(R0, Bool::True());
+  __ Ret();
+
+  __ Bind(&return_false);
+  __ Pop(R4);
+  __ LoadObject(R0, Bool::False());
+  __ Ret();
+
+  __ Bind(&fall_through);
+  __ Pop(R4);
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
 
@@ -1664,11 +1784,11 @@
 
   __ SmiUntag(R2);
   __ mov(R3, Operand(0));
-  __ AddImmediate(R6, R1, OneByteString::data_offset() - kHeapObjectTag);
+  __ AddImmediate(R8, R1, OneByteString::data_offset() - kHeapObjectTag);
   // R1: Instance of OneByteString.
   // R2: String length, untagged integer.
   // R3: Loop counter, untagged integer.
-  // R6: String data.
+  // R8: String data.
   // R0: Hash code, untagged integer.
 
   Label loop;
@@ -1678,11 +1798,11 @@
   // hash_ ^= hash_ >> 6;
   // Get one characters (ch).
   __ Bind(&loop);
-  __ ldrb(R7, Address(R6, 0));
-  // R7: ch.
+  __ ldrb(NOTFP, Address(R8, 0));
+  // NOTFP: ch.
   __ add(R3, R3, Operand(1));
-  __ add(R6, R6, Operand(1));
-  __ add(R0, R0, Operand(R7));
+  __ add(R8, R8, Operand(1));
+  __ add(R0, R0, Operand(NOTFP));
   __ add(R0, R0, Operand(R0, LSL, 10));
   __ eor(R0, R0, Operand(R0, LSR, 6));
   __ cmp(R3, Operand(R2));
@@ -1719,7 +1839,7 @@
   Label fail;
   __ MaybeTraceAllocation(kOneByteStringCid, R0, failure,
                           /* inline_isolate = */ false);
-  __ mov(R6, Operand(length_reg));  // Save the length register.
+  __ mov(R8, Operand(length_reg));  // Save the length register.
   // TODO(koda): Protect against negative length and overflow here.
   __ SmiUntag(length_reg);
   const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
@@ -1740,8 +1860,8 @@
   // R1: potential next object start.
   // R2: allocation size.
   // R3: heap.
-  __ ldr(R7, Address(R3, Heap::EndOffset(space)));
-  __ cmp(R1, Operand(R7));
+  __ ldr(NOTFP, Address(R3, Heap::EndOffset(space)));
+  __ cmp(R1, Operand(NOTFP));
   __ b(&fail, CS);
 
   // Successfully allocated the object(s), now update top to point to
@@ -1769,10 +1889,10 @@
     __ str(R3, FieldAddress(R0, String::tags_offset()));  // Store tags.
   }
 
-  // Set the length field using the saved length (R6).
+  // Set the length field using the saved length (R8).
   __ InitializeFieldNoBarrier(R0,
                               FieldAddress(R0, String::length_offset()),
-                              R6);
+                              R8);
   // Clear hash.
   __ LoadImmediate(TMP, 0);
   __ InitializeFieldNoBarrier(R0,
@@ -1824,21 +1944,21 @@
   // R3: Start address to copy from (untagged).
   // R2: Untagged number of bytes to copy.
   // R0: Tagged result string.
-  // R6: Pointer into R3.
-  // R7: Pointer into R0.
+  // R8: Pointer into R3.
+  // NOTFP: Pointer into R0.
   // R1: Scratch register.
   Label loop, done;
   __ cmp(R2, Operand(0));
   __ b(&done, LE);
-  __ mov(R6, Operand(R3));
-  __ mov(R7, Operand(R0));
+  __ mov(R8, Operand(R3));
+  __ mov(NOTFP, Operand(R0));
   __ Bind(&loop);
-  __ ldrb(R1, Address(R6, 0));
-  __ AddImmediate(R6, 1);
+  __ ldrb(R1, Address(R8, 0));
+  __ AddImmediate(R8, 1);
   __ sub(R2, R2, Operand(1));
   __ cmp(R2, Operand(0));
-  __ strb(R1, FieldAddress(R7, OneByteString::data_offset()));
-  __ AddImmediate(R7, 1);
+  __ strb(R1, FieldAddress(NOTFP, OneByteString::data_offset()));
+  __ AddImmediate(NOTFP, 1);
   __ b(&loop, GT);
 
   __ Bind(&done);
@@ -1955,7 +2075,7 @@
   // Incoming registers:
   // R0: Function. (Will be reloaded with the specialized matcher function.)
   // R4: Arguments descriptor. (Will be preserved.)
-  // R5: Unknown. (Must be GC safe on tail call.)
+  // R9: Unknown. (Must be GC safe on tail call.)
 
   // Load the specialized function pointer into R0. Leverage the fact the
   // string CIDs as well as stored function pointers are in sequence.
@@ -1967,8 +2087,8 @@
   __ ldr(R0, FieldAddress(R1, JSRegExp::function_offset(kOneByteStringCid)));
 
   // Registers are now set up for the lazy compile stub. It expects the function
-  // in R0, the argument descriptor in R4, and IC-Data in R5.
-  __ eor(R5, R5, Operand(R5));
+  // in R0, the argument descriptor in R4, and IC-Data in R9.
+  __ eor(R9, R9, Operand(R9));
 
   // Tail-call the function.
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc
index 4441fe2..265d5d4 100644
--- a/runtime/vm/intrinsifier_arm64.cc
+++ b/runtime/vm/intrinsifier_arm64.cc
@@ -20,12 +20,12 @@
 DECLARE_FLAG(bool, interpret_irregexp);
 
 // When entering intrinsics code:
-// R5: IC Data
 // R4: Arguments descriptor
 // LR: Return address
-// The R5, R4 registers can be destroyed only if there is no slow-path, i.e.
+// The R4 register can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The FP register should not be modified, because it is used by the profiler.
+// The PP and THR registers (see constants_arm64.h) must be preserved.
 
 #define __ assembler->
 
@@ -1677,6 +1677,119 @@
 }
 
 
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ SmiUntag(R1);
+  __ ldr(R8, FieldAddress(R0, String::length_offset()));  // this.length
+  __ SmiUntag(R8);
+  __ ldr(R9, FieldAddress(R2, String::length_offset()));  // other.length
+  __ SmiUntag(R9);
+
+  // if (other.length == 0) return true;
+  __ cmp(R9, Operand(0));
+  __ b(return_true, EQ);
+
+  // if (start < 0) return false;
+  __ cmp(R1, Operand(0));
+  __ b(return_false, LT);
+
+  // if (start + other.length > this.length) return false;
+  __ add(R3, R1, Operand(R9));
+  __ cmp(R3, Operand(R8));
+  __ b(return_false, GT);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+    __ add(R0, R0, Operand(R1));
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ AddImmediate(R2, R2, OneByteString::data_offset() - kHeapObjectTag);
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ AddImmediate(R2, R2, TwoByteString::data_offset() - kHeapObjectTag);
+  }
+
+  // i = 0
+  __ LoadImmediate(R3, 0);
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  // this.codeUnitAt(i + start)
+  __ ldr(R10, Address(R0, 0),
+         receiver_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
+  // other.codeUnitAt(i)
+  __ ldr(R11, Address(R2, 0),
+         other_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
+  __ cmp(R10, Operand(R11));
+  __ b(return_false, NE);
+
+  // i++, while (i < len)
+  __ add(R3, R3, Operand(1));
+  __ add(R0, R0, Operand(receiver_cid == kOneByteStringCid ? 1 : 2));
+  __ add(R2, R2, Operand(other_cid == kOneByteStringCid ? 1 : 2));
+  __ cmp(R3, Operand(R9));
+  __ b(&loop, LT);
+
+  __ b(return_true);
+}
+
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  Label fall_through, return_true, return_false, try_two_byte;
+  __ ldr(R0, Address(SP, 2 * kWordSize));  // this
+  __ ldr(R1, Address(SP, 1 * kWordSize));  // start
+  __ ldr(R2, Address(SP, 0 * kWordSize));  // other
+
+  __ tsti(R1, Immediate(kSmiTagMask));
+  __ b(&fall_through, NE);  // 'start' is not a Smi.
+
+  __ CompareClassId(R2, kOneByteStringCid);
+  __ b(&fall_through, NE);
+
+  __ CompareClassId(R0, kOneByteStringCid);
+  __ b(&fall_through, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kOneByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ CompareClassId(R0, kTwoByteStringCid);
+  __ b(&fall_through, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kTwoByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ LoadObject(R0, Bool::True());
+  __ ret();
+
+  __ Bind(&return_false);
+  __ LoadObject(R0, Bool::False());
+  __ ret();
+
+  __ Bind(&fall_through);
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
 
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index d39f3b6..61620c8 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -33,6 +33,7 @@
 // The ECX, EDX registers can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The EBP register should not be modified, because it is used by the profiler.
+// The THR register (see constants_ia32.h) must be preserved.
 
 #define __ assembler->
 
@@ -76,7 +77,7 @@
     // Check if it's dynamic.
     // Get type at index 0.
     __ movl(EAX, FieldAddress(EBX, TypeArguments::type_at_offset(0)));
-    __ CompareObject(EAX, Type::ZoneHandle(Type::DynamicType()));
+    __ CompareObject(EAX, Object::dynamic_type());
     __ j(EQUAL,  &checked_ok, Assembler::kNearJump);
     // Check for int and num.
     __ testl(EDI, Immediate(kSmiTagMask));  // Value is Smi?
@@ -1740,6 +1741,12 @@
 }
 
 
+// bool _substringMatches(int start, String other)
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  // For precompilation, not implemented on IA32.
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Index.
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index 7349e85..2be1114 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -20,12 +20,12 @@
 DECLARE_FLAG(bool, interpret_irregexp);
 
 // When entering intrinsics code:
-// S5: IC Data
 // S4: Arguments descriptor
 // RA: Return address
-// The S5, S4 registers can be destroyed only if there is no slow-path, i.e.
+// The S4 register can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The FP register should not be modified, because it is used by the profiler.
+// The PP and THR registers (see constants_mips.h) must be preserved.
 
 #define __ assembler->
 
@@ -1470,7 +1470,7 @@
 
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
-  __ bne(T0, ZR, &fall_through);
+  __ bne(CMPRES1, ZR, &fall_through);
 
   // Is Smi.
   __ SmiUntag(T0);
@@ -1681,7 +1681,7 @@
 
   // Checks.
   __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
-  __ bne(T1, ZR, &fall_through);  // Index is not a Smi.
+  __ bne(CMPRES1, ZR, &fall_through);  // Index is not a Smi.
   __ lw(T2, FieldAddress(T0, String::length_offset()));  // Range check.
   // Runtime throws exception.
   __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
@@ -1708,6 +1708,118 @@
 }
 
 
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ SmiUntag(A1);
+  __ lw(T1, FieldAddress(A0, String::length_offset()));  // this.length
+  __ SmiUntag(T1);
+  __ lw(T2, FieldAddress(A2, String::length_offset()));  // other.length
+  __ SmiUntag(T2);
+
+  // if (other.length == 0) return true;
+  __ beq(T2, ZR, return_true);
+
+  // if (start < 0) return false;
+  __ bltz(A1, return_false);
+
+  // if (start + other.length > this.length) return false;
+  __ addu(T0, A1, T2);
+  __ BranchSignedGreater(T0, T1, return_false);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ AddImmediate(A0, A0, OneByteString::data_offset() - kHeapObjectTag);
+    __ addu(A0, A0, A1);
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ AddImmediate(A0, A0, TwoByteString::data_offset() - kHeapObjectTag);
+    __ addu(A0, A0, A1);
+    __ addu(A0, A0, A1);
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ AddImmediate(A2, A2, OneByteString::data_offset() - kHeapObjectTag);
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ AddImmediate(A2, A2, TwoByteString::data_offset() - kHeapObjectTag);
+  }
+
+  // i = 0
+  __ LoadImmediate(T0, 0);
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ lbu(T3, Address(A0, 0));  // this.codeUnitAt(i + start)
+  } else {
+    __ lhu(T3, Address(A0, 0));  // this.codeUnitAt(i + start)
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ lbu(T4, Address(A2, 0));  // other.codeUnitAt(i)
+  } else {
+    __ lhu(T4, Address(A2, 0));  // other.codeUnitAt(i)
+  }
+  __ bne(T3, T4, return_false);
+
+  // i++, while (i < len)
+  __ AddImmediate(T0, T0, 1);
+  __ AddImmediate(A0, A0, receiver_cid == kOneByteStringCid ? 1 : 2);
+  __ AddImmediate(A2, A2, other_cid == kOneByteStringCid ? 1 : 2);
+  __ BranchSignedLess(T0, T2, &loop);
+
+  __ b(return_true);
+}
+
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  Label fall_through, return_true, return_false, try_two_byte;
+  __ lw(A0, Address(SP, 2 * kWordSize));  // this
+  __ lw(A1, Address(SP, 1 * kWordSize));  // start
+  __ lw(A2, Address(SP, 0 * kWordSize));  // other
+
+  __ andi(CMPRES1, A1, Immediate(kSmiTagMask));
+  __ bne(CMPRES1, ZR, &fall_through);  // 'start' is not a Smi.
+
+  __ LoadClassId(CMPRES1, A2);
+  __ BranchNotEqual(CMPRES1, Immediate(kOneByteStringCid), &fall_through);
+
+  __ LoadClassId(CMPRES1, A0);
+  __ BranchNotEqual(CMPRES1, Immediate(kOneByteStringCid), &try_two_byte);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kOneByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ LoadClassId(CMPRES1, A0);
+  __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kTwoByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ LoadObject(V0, Bool::True());
+  __ Ret();
+
+  __ Bind(&return_false);
+  __ LoadObject(V0, Bool::False());
+  __ Ret();
+
+  __ Bind(&fall_through);
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
 
@@ -1716,7 +1828,7 @@
 
   // Checks.
   __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
-  __ bne(T1, ZR, &fall_through);  // Index is not a Smi.
+  __ bne(CMPRES1, ZR, &fall_through);  // Index is not a Smi.
   __ lw(T2, FieldAddress(T0, String::length_offset()));  // Range check.
   // Runtime throws exception.
   __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 4598ddd..e3f2ca4 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -20,12 +20,12 @@
 DECLARE_FLAG(bool, interpret_irregexp);
 
 // When entering intrinsics code:
-// RBX: IC Data
 // R10: Arguments descriptor
 // TOS: Return address
-// The RBX, R10 registers can be destroyed only if there is no slow-path, i.e.
+// The R10 registers can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The RBP register should not be modified, because it is used by the profiler.
+// The PP and THR registers (see constants_x64.h) must be preserved.
 
 #define __ assembler->
 
@@ -1595,6 +1595,115 @@
 }
 
 
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ movq(R8, FieldAddress(RAX, String::length_offset()));
+  __ movq(R9, FieldAddress(RCX, String::length_offset()));
+
+  // if (other.length == 0) return true;
+  __ testq(R9, R9);
+  __ j(ZERO, return_true);
+
+  // if (start < 0) return false;
+  __ testq(RBX, RBX);
+  __ j(SIGN, return_false);
+
+  // if (start + other.length > this.length) return false;
+  __ movq(R11, RBX);
+  __ addq(R11, R9);
+  __ cmpq(R11, R8);
+  __ j(GREATER, return_false);
+
+  __ SmiUntag(RBX);  // start
+  __ SmiUntag(R9);   // other.length
+  __ movq(R11, Immediate(0));  // i = 0
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  // this.codeUnitAt(i + start)
+  // clobbering this.length
+  __ movq(R8, R11);
+  __ addq(R8, RBX);
+  if (receiver_cid == kOneByteStringCid) {
+    __ movzxb(R12,
+              FieldAddress(RAX, R8, TIMES_1, OneByteString::data_offset()));
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ movzxw(R12,
+              FieldAddress(RAX, R8, TIMES_2, TwoByteString::data_offset()));
+  }
+  // other.codeUnitAt(i)
+  if (other_cid == kOneByteStringCid) {
+    __ movzxb(R13,
+              FieldAddress(RCX, R11, TIMES_1, OneByteString::data_offset()));
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ movzxw(R13,
+              FieldAddress(RCX, R11, TIMES_2, TwoByteString::data_offset()));
+  }
+  __ cmpq(R12, R13);
+  __ j(NOT_EQUAL, return_false);
+
+  // i++, while (i < len)
+  __ addq(R11, Immediate(1));
+  __ cmpq(R11, R9);
+  __ j(LESS, &loop, Assembler::kNearJump);
+
+  __ jmp(return_true);
+}
+
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+  Label fall_through, return_true, return_false, try_two_byte;
+  __ movq(RAX, Address(RSP, + 3 * kWordSize));  // receiver
+  __ movq(RBX, Address(RSP, + 2 * kWordSize));  // start
+  __ movq(RCX, Address(RSP, + 1 * kWordSize));  // other
+
+  __ testq(RBX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &fall_through);  // 'start' is not Smi.
+
+  __ CompareClassId(RCX, kOneByteStringCid);
+  __ j(NOT_EQUAL, &fall_through);
+
+  __ CompareClassId(RAX, kOneByteStringCid);
+  __ j(NOT_EQUAL, &try_two_byte);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kOneByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ CompareClassId(RAX, kTwoByteStringCid);
+  __ j(NOT_EQUAL, &fall_through);
+
+  GenerateSubstringMatchesSpecialization(assembler,
+                                         kTwoByteStringCid,
+                                         kOneByteStringCid,
+                                         &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ LoadObject(RAX, Bool::True());
+  __ ret();
+
+  __ Bind(&return_false);
+  __ LoadObject(RAX, Bool::False());
+  __ ret();
+
+  __ Bind(&fall_through);
+}
+
+
 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Index.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index f7caee1..5c764df 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -7,7 +7,7 @@
 #include "include/dart_api.h"
 #include "include/dart_native_api.h"
 #include "platform/assert.h"
-#include "platform/json.h"
+#include "platform/text_buffer.h"
 #include "vm/class_finalizer.h"
 #include "vm/code_observers.h"
 #include "vm/compiler.h"
@@ -134,6 +134,19 @@
   *obj_len = writer.BytesWritten();
 }
 
+// TODO(zra): Allocation of Message objects should be centralized.
+static Message* SerializeMessage(
+    Dart_Port dest_port, const Instance& obj) {
+  if (ApiObjectConverter::CanConvert(obj.raw())) {
+    return new Message(dest_port, obj.raw(), Message::kNormalPriority);
+  } else {
+    uint8_t* obj_data;
+    intptr_t obj_len;
+    SerializeObject(obj, &obj_data, &obj_len, false);
+    return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority);
+  }
+}
+
 
 void Isolate::RegisterClass(const Class& cls) {
   class_table()->Register(cls);
@@ -217,7 +230,7 @@
 // [ OOB dispatch, Isolate library dispatch, <message specific data> ]
 RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) {
   if (message.Length() < 2) return Error::null();
-  Zone* zone = I->current_zone();
+  Zone* zone = T->zone();
   const Object& type = Object::Handle(zone, message.At(1));
   if (!type.IsSmi()) return Error::null();
   const intptr_t msg_type = Smi::Cast(type).Value();
@@ -260,12 +273,8 @@
       const Instance& response =
           obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4);
       if (priority == Isolate::kImmediateAction) {
-        uint8_t* data = NULL;
-        intptr_t len = 0;
-        SerializeObject(response, &data, &len, false);
-        PortMap::PostMessage(new Message(send_port.Id(),
-                                         data, len,
-                                         Message::kNormalPriority));
+        PortMap::PostMessage(SerializeMessage(
+            send_port.Id(), response));
       } else {
         ASSERT((priority == Isolate::kBeforeNextEventAction) ||
                (priority == Isolate::kAsEventAction));
@@ -275,13 +284,8 @@
             Smi::New(Message::kDelayedIsolateLibOOBMsg)));
         message.SetAt(3, Smi::Handle(zone,
             Smi::New(Isolate::kImmediateAction)));
-        uint8_t* data = NULL;
-        intptr_t len = 0;
-        SerializeObject(message, &data, &len, false);
-        this->PostMessage(
-            new Message(Message::kIllegalPort,
-                        data, len,
-                        Message::kNormalPriority),
+        this->PostMessage(SerializeMessage(
+            Message::kIllegalPort, message),
             priority == Isolate::kBeforeNextEventAction /* at_head */);
       }
       break;
@@ -334,13 +338,8 @@
             Smi::New(Message::kDelayedIsolateLibOOBMsg)));
         message.SetAt(3, Smi::Handle(zone,
             Smi::New(Isolate::kImmediateAction)));
-        uint8_t* data = NULL;
-        intptr_t len = 0;
-        SerializeObject(message, &data, &len, false);
-        this->PostMessage(
-            new Message(Message::kIllegalPort,
-                        data, len,
-                        Message::kNormalPriority),
+        this->PostMessage(SerializeMessage(
+            Message::kIllegalPort, message),
             priority == Isolate::kBeforeNextEventAction /* at_head */);
       }
       break;
@@ -468,8 +467,15 @@
   }
 
   // Parse the message.
-  MessageSnapshotReader reader(message->data(), message->len(), thread);
-  const Object& msg_obj = Object::Handle(zone, reader.ReadObject());
+  Object& msg_obj = Object::Handle(zone);
+  if (message->IsRaw()) {
+    msg_obj = message->raw_obj();
+    // We should only be sending RawObjects that can be converted to CObjects.
+    ASSERT(ApiObjectConverter::CanConvert(msg_obj.raw()));
+  } else {
+    MessageSnapshotReader reader(message->data(), message->len(), thread);
+    msg_obj = reader.ReadObject();
+  }
   if (msg_obj.IsError()) {
     // An error occurred while reading the message.
     delete message;
@@ -483,7 +489,6 @@
     // always true for now, then this should never occur.
     UNREACHABLE();
   }
-
   Instance& msg = Instance::Handle(zone);
   msg ^= msg_obj.raw();  // Can't use Instance::Cast because may be null.
 
@@ -631,19 +636,11 @@
     }
   }
 
-  // Invoke the isolate's unhandled exception callback if there is one.
-  if (Isolate::UnhandledExceptionCallback() != NULL) {
-    Dart_EnterScope();
-    Dart_Handle error = Api::NewHandle(I, result.raw());
-    (Isolate::UnhandledExceptionCallback())(error);
-    Dart_ExitScope();
-  }
-
   // Generate the error and stacktrace strings for the error message.
-  String& exc_str = String::Handle(I->current_zone());
-  String& stacktrace_str = String::Handle(I->current_zone());
+  String& exc_str = String::Handle(T->zone());
+  String& stacktrace_str = String::Handle(T->zone());
   if (result.IsUnhandledException()) {
-    Zone* zone = I->current_zone();
+    Zone* zone = T->zone();
     const UnhandledException& uhe = UnhandledException::Cast(result);
     const Instance& exception = Instance::Handle(zone, uhe.exception());
     Object& tmp = Object::Handle(zone);
@@ -699,6 +696,8 @@
 void Isolate::Flags::CopyFrom(const Dart_IsolateFlags& api_flags) {
   type_checks_ = api_flags.enable_type_checks;
   asserts_ = api_flags.enable_asserts;
+  error_on_bad_type_ = api_flags.enable_error_on_bad_type;
+  error_on_bad_override_ = api_flags.enable_error_on_bad_override;
   // Leave others at defaults.
 }
 
@@ -707,6 +706,8 @@
   api_flags->version = DART_FLAGS_CURRENT_VERSION;
   api_flags->enable_type_checks = type_checks();
   api_flags->enable_asserts = asserts();
+  api_flags->enable_error_on_bad_type = error_on_bad_type();
+  api_flags->enable_error_on_bad_override = error_on_bad_override();
 }
 
 
@@ -718,7 +719,7 @@
 
 void BaseIsolate::AssertCurrentThreadIsMutator() const {
   ASSERT(Isolate::Current() == this);
-  ASSERT(Isolate::Current()->MutatorThreadIsCurrentThread());
+  ASSERT(Thread::Current()->IsMutatorThread());
 }
 #endif  // defined(DEBUG)
 
@@ -736,7 +737,6 @@
   :   stack_limit_(0),
       store_buffer_(new StoreBuffer()),
       heap_(NULL),
-      vm_tag_(0),
       user_tag_(0),
       current_tag_(UserTag::null()),
       default_tag_(UserTag::null()),
@@ -767,7 +767,6 @@
       simulator_(NULL),
       mutex_(new Mutex()),
       saved_stack_limit_(0),
-      stack_base_(0),
       stack_overflow_flags_(0),
       stack_overflow_count_(0),
       message_handler_(NULL),
@@ -777,7 +776,6 @@
       gc_epilogue_callback_(NULL),
       defer_finalization_count_(0),
       deopt_context_(NULL),
-      background_compiler_(NULL),
       compiler_stats_(NULL),
       is_service_isolate_(false),
       stacktrace_(NULL),
@@ -786,19 +784,25 @@
       last_allocationprofile_gc_timestamp_(0),
       object_id_ring_(NULL),
       trace_buffer_(NULL),
-      profiler_data_(NULL),
       tag_table_(GrowableObjectArray::null()),
-      collected_closures_(GrowableObjectArray::null()),
       deoptimized_code_array_(GrowableObjectArray::null()),
-      background_compilation_queue_(GrowableObjectArray::null()),
+      background_compiler_(NULL),
       pending_service_extension_calls_(GrowableObjectArray::null()),
       registered_service_extension_handlers_(GrowableObjectArray::null()),
       metrics_list_head_(NULL),
       compilation_allowed_(true),
+      all_classes_finalized_(false),
       next_(NULL),
-      pause_loop_monitor_(NULL) {
+      pause_loop_monitor_(NULL),
+      cha_invalidation_gen_(kInvalidGen),
+      field_invalidation_gen_(kInvalidGen),
+      prefix_invalidation_gen_(kInvalidGen),
+      spawn_count_monitor_(new Monitor()),
+      spawn_count_(0) {
   flags_.CopyFrom(api_flags);
-  Thread::Current()->set_vm_tag(VMTag::kEmbedderTagId);
+  // TODO(asiva): A Thread is not available here, need to figure out
+  // how the vm_tag (kEmbedderTagId) can be set, these tags need to
+  // move to the OSThread structure.
   set_user_tag(UserTags::kDefaultUserTag);
 }
 
@@ -826,6 +830,8 @@
   object_id_ring_ = NULL;
   delete pause_loop_monitor_;
   pause_loop_monitor_ = NULL;
+  ASSERT(spawn_count_ == 0);
+  delete spawn_count_monitor_;
   if (compiler_stats_ != NULL) {
     delete compiler_stats_;
     compiler_stats_ = NULL;
@@ -864,7 +870,6 @@
   // Initialize Timeline streams.
 #define ISOLATE_TIMELINE_STREAM_INIT(name, enabled_by_default)                 \
   result->stream_##name##_.Init(#name,                                         \
-                                Timeline::EnableStreamByDefault(#name) ||      \
                                 enabled_by_default,                            \
                                 Timeline::Stream##name##EnabledFlag());
   ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_INIT);
@@ -879,7 +884,12 @@
 
   // TODO(5411455): For now just set the recently created isolate as
   // the current isolate.
-  Thread::EnterIsolate(result);
+  if (!Thread::EnterIsolate(result)) {
+    // We failed to enter the isolate, it is possible the VM is shutting down,
+    // return back a NULL so that CreateIsolate reports back an error.
+    delete result;
+    return NULL;
+  }
 
   // Setup the isolate message handler.
   MessageHandler* handler = new IsolateMessageHandler(result);
@@ -891,11 +901,6 @@
   ASSERT(state != NULL);
   result->set_api_state(state);
 
-  // Initialize stack limit (wait until later for the VM isolate, since the
-  // needed GetStackPointer stub has not yet been generated in that case).
-  if (!is_vm_isolate) {
-    result->InitializeStackLimit();
-  }
   result->set_main_port(PortMap::CreatePort(result->message_handler()));
 #if defined(DEBUG)
   // Verify that we are never reusing a live origin id.
@@ -935,11 +940,6 @@
 }
 
 
-void Isolate::InitializeStackLimit() {
-  SetStackLimitFromStackBase(Isolate::GetCurrentStackPointer());
-}
-
-
 /* static */
 uword Isolate::GetCurrentStackPointer() {
   // Since AddressSanitizer's detect_stack_use_after_return instruments the
@@ -998,19 +998,7 @@
 }
 
 
-// TODO(5411455): Use flag to override default value and Validate the
-// stack size by querying OS.
-uword Isolate::GetSpecifiedStackSize() {
-  ASSERT(Isolate::kStackSizeBuffer < OSThread::GetMaxStackSize());
-  uword stack_size = OSThread::GetMaxStackSize() - Isolate::kStackSizeBuffer;
-  return stack_size;
-}
-
-
 void Isolate::SetStackLimitFromStackBase(uword stack_base) {
-  // Set stack base.
-  stack_base_ = stack_base;
-
   // Set stack limit.
 #if defined(USING_SIMULATOR)
   // Ignore passed-in native stack top and use Simulator stack top.
@@ -1019,7 +1007,7 @@
   stack_base = sim->StackTop();
   // The overflow area is accounted for by the simulator.
 #endif
-  SetStackLimit(stack_base - GetSpecifiedStackSize());
+  SetStackLimit(stack_base - OSThread::GetSpecifiedStackSize());
 }
 
 
@@ -1037,19 +1025,6 @@
 
 void Isolate::ClearStackLimit() {
   SetStackLimit(~static_cast<uword>(0));
-  stack_base_ = 0;
-}
-
-
-bool Isolate::GetProfilerStackBounds(uword* lower, uword* upper) const {
-  uword stack_upper = stack_base_;
-  if (stack_upper == 0) {
-    return false;
-  }
-  uword stack_lower = stack_upper - GetSpecifiedStackSize();
-  *lower = stack_lower;
-  *upper = stack_upper;
-  return true;
 }
 
 
@@ -1076,6 +1051,7 @@
       lib.SetLoaded();
     }
   }
+  TokenStream::CloseSharedTokenList(this);
 }
 
 
@@ -1245,12 +1221,8 @@
     listener ^= listeners.At(i);
     if (!listener.IsNull()) {
       Dart_Port port_id = listener.Id();
-      uint8_t* data = NULL;
-      intptr_t len = 0;
       response ^= listeners.At(i + 1);
-      SerializeObject(response, &data, &len, false);
-      Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
-      PortMap::PostMessage(msg);
+      PortMap::PostMessage(SerializeMessage(port_id, response));
     }
   }
 }
@@ -1318,11 +1290,7 @@
     listener ^= listeners.At(i);
     if (!listener.IsNull()) {
       Dart_Port port_id = listener.Id();
-      uint8_t* data = NULL;
-      intptr_t len = 0;
-      SerializeObject(arr, &data, &len, false);
-      Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
-      PortMap::PostMessage(msg);
+      PortMap::PostMessage(SerializeMessage(port_id, arr));
     }
   }
   return listeners.Length() > 0;
@@ -1332,7 +1300,6 @@
 static MessageHandler::MessageStatus RunIsolate(uword parameter) {
   Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
   IsolateSpawnState* state = NULL;
-  Thread* thread = Thread::Current();
   {
     // TODO(turnidge): Is this locking required here at all anymore?
     MutexLocker ml(isolate->mutex());
@@ -1340,6 +1307,7 @@
   }
   {
     StartIsolateScope start_scope(isolate);
+    Thread* thread = Thread::Current();
     ASSERT(thread->isolate() == isolate);
     StackZone zone(thread);
     HandleScope handle_scope(thread);
@@ -1439,11 +1407,14 @@
 
 static void ShutdownIsolate(uword parameter) {
   Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
+  // We must wait for any outstanding spawn calls to complete before
+  // running the shutdown callback.
+  isolate->WaitForOutstandingSpawns();
   {
     // Print the error if there is one.  This may execute dart code to
     // print the exception object, so we need to use a StartIsolateScope.
-    Thread* thread = Thread::Current();
     StartIsolateScope start_scope(isolate);
+    Thread* thread = Thread::Current();
     ASSERT(thread->isolate() == isolate);
     StackZone zone(thread);
     HandleScope handle_scope(thread);
@@ -1453,11 +1424,8 @@
     }
     Dart::RunShutdownCallback();
   }
-  {
-    // Shut the isolate down.
-    SwitchIsolateScope switch_scope(isolate);
-    Dart::ShutdownIsolate();
-  }
+  // Shut the isolate down.
+  Dart::ShutdownIsolate(isolate);
 }
 
 
@@ -1518,56 +1486,59 @@
 }
 
 
-static int MostUsedFunctionFirst(const Function* const* a,
-                                 const Function* const* b) {
-  if ((*a)->usage_counter() > (*b)->usage_counter()) {
-    return -1;
-  } else if ((*a)->usage_counter() < (*b)->usage_counter()) {
-    return 1;
-  } else {
-    return 0;
-  }
+void Isolate::AddClosureFunction(const Function& function) const {
+  GrowableObjectArray& closures =
+      GrowableObjectArray::Handle(object_store()->closure_functions());
+  ASSERT(!closures.IsNull());
+  ASSERT(function.IsNonImplicitClosureFunction());
+  closures.Add(function, Heap::kOld);
 }
 
 
-static void AddFunctionsFromClass(const Class& cls,
-                                  GrowableArray<const Function*>* functions) {
-  const Array& class_functions = Array::Handle(cls.functions());
-  // Class 'dynamic' is allocated/initialized in a special way, leaving
-  // the functions field NULL instead of empty.
-  const int func_len = class_functions.IsNull() ? 0 : class_functions.Length();
-  for (int j = 0; j < func_len; j++) {
-    Function& function = Function::Handle();
-    function ^= class_functions.At(j);
-    if (function.usage_counter() > 0) {
-      functions->Add(&function);
+// If the linear lookup turns out to be too expensive, the list
+// of closures could be maintained in a hash map, with the key
+// being the token position of the closure. There are almost no
+// collisions with this simple hash value. However, iterating over
+// all closure functions becomes more difficult, especially when
+// the list/map changes while iterating over it.
+RawFunction* Isolate::LookupClosureFunction(const Function& parent,
+                                            intptr_t token_pos) const {
+  const GrowableObjectArray& closures =
+      GrowableObjectArray::Handle(object_store()->closure_functions());
+  ASSERT(!closures.IsNull());
+  Function& closure = Function::Handle();
+  intptr_t num_closures = closures.Length();
+  for (intptr_t i = 0; i < num_closures; i++) {
+    closure ^= closures.At(i);
+    if ((closure.token_pos() == token_pos) &&
+        (closure.parent_function() == parent.raw())) {
+      return closure.raw();
     }
   }
+  return Function::null();
 }
 
 
-void Isolate::PrintInvokedFunctions() {
-  ASSERT(this == Isolate::Current());
-  const GrowableObjectArray& libraries =
-      GrowableObjectArray::Handle(object_store()->libraries());
-  Library& library = Library::Handle();
-  GrowableArray<const Function*> invoked_functions;
-  for (int i = 0; i < libraries.Length(); i++) {
-    library ^= libraries.At(i);
-    Class& cls = Class::Handle();
-    ClassDictionaryIterator iter(library,
-                                 ClassDictionaryIterator::kIteratePrivate);
-    while (iter.HasNext()) {
-      cls = iter.GetNextClass();
-      AddFunctionsFromClass(cls, &invoked_functions);
+intptr_t Isolate::FindClosureIndex(const Function& needle) const {
+  const GrowableObjectArray& closures_array =
+      GrowableObjectArray::Handle(object_store()->closure_functions());
+  intptr_t num_closures = closures_array.Length();
+  for (intptr_t i = 0; i < num_closures; i++) {
+    if (closures_array.At(i) == needle.raw()) {
+      return i;
     }
   }
-  invoked_functions.Sort(MostUsedFunctionFirst);
-  for (int i = 0; i < invoked_functions.length(); i++) {
-    OS::Print("%10" Pd " x %s\n",
-        invoked_functions[i]->usage_counter(),
-        invoked_functions[i]->ToFullyQualifiedCString());
+  return -1;
+}
+
+
+RawFunction* Isolate::ClosureFunctionFromIndex(intptr_t idx) const {
+  const GrowableObjectArray& closures_array =
+      GrowableObjectArray::Handle(object_store()->closure_functions());
+  if ((idx < 0) || (idx >= closures_array.Length())) {
+    return Function::null();
   }
+  return Function::RawCast(closures_array.At(idx));
 }
 
 
@@ -1616,7 +1587,7 @@
   set_message_handler(NULL);
 
   // Before analyzing the isolate's timeline blocks- reclaim all cached blocks.
-  ReclaimTimelineBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
 
   // Dump all timing data for the isolate.
   if (FLAG_timing) {
@@ -1627,7 +1598,6 @@
   // Finalize any weak persistent handles with a non-null referent.
   FinalizeWeakPersistentHandlesVisitor visitor;
   api_state()->weak_persistent_handles().VisitHandles(&visitor);
-  api_state()->prologue_weak_persistent_handles().VisitHandles(&visitor);
 
   if (FLAG_trace_isolates) {
     heap()->PrintSizes();
@@ -1651,7 +1621,11 @@
 
 void Isolate::Shutdown() {
   ASSERT(this == Isolate::Current());
-  ASSERT(top_resource() == NULL);
+  // Wait until all background compilation has finished.
+  if (background_compiler_ != NULL) {
+    BackgroundCompiler::Stop(background_compiler_);
+  }
+
 #if defined(DEBUG)
   if (heap_ != NULL) {
     // The VM isolate keeps all objects marked.
@@ -1661,6 +1635,9 @@
 
   Thread* thread = Thread::Current();
 
+  // Don't allow anymore dart code to execution on this isolate.
+  ClearStackLimit();
+
   // First, perform higher-level cleanup that may need to allocate.
   {
     // Ensure we have a zone and handle scope so that we can call VM functions.
@@ -1707,30 +1684,13 @@
   }
 #endif
 
-  BackgroundCompiler::Stop(background_compiler_);
-
   // TODO(5411455): For now just make sure there are no current isolates
   // as we are shutting down the isolate.
   Thread::ExitIsolate();
-  // All threads should have exited by now.
-  thread_registry()->CheckNotScheduled(this);
-  Profiler::ShutdownProfilingForIsolate(this);
-}
-
-
-void Isolate::ReclaimTimelineBlocks() {
-  TimelineEventRecorder* recorder = Timeline::recorder();
-  if (recorder == NULL) {
-    return;
-  }
-  thread_registry_->ReclaimTimelineBlocks();
 }
 
 
 Dart_IsolateCreateCallback Isolate::create_callback_ = NULL;
-Dart_IsolateInterruptCallback Isolate::interrupt_callback_ = NULL;
-Dart_IsolateUnhandledExceptionCallback
-    Isolate::unhandled_exception_callback_ = NULL;
 Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL;
 Dart_FileOpenCallback Isolate::file_open_callback_ = NULL;
 Dart_FileReadCallback Isolate::file_read_callback_ = NULL;
@@ -1743,15 +1703,13 @@
 bool Isolate::creation_enabled_ = false;
 
 void Isolate::IterateObjectPointers(ObjectPointerVisitor* visitor,
-                                    bool visit_prologue_weak_handles,
                                     bool validate_frames) {
   HeapIterationScope heap_iteration_scope;
-  VisitObjectPointers(visitor, visit_prologue_weak_handles, validate_frames);
+  VisitObjectPointers(visitor, validate_frames);
 }
 
 
 void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
-                                  bool visit_prologue_weak_handles,
                                   bool validate_frames) {
   ASSERT(visitor != NULL);
 
@@ -1766,7 +1724,7 @@
 
   // Visit the dart api state for all local and persistent handles.
   if (api_state() != NULL) {
-    api_state()->VisitObjectPointers(visitor, visit_prologue_weak_handles);
+    api_state()->VisitObjectPointers(visitor);
   }
 
   // Visit the current tag which is stored in the isolate.
@@ -1778,11 +1736,9 @@
   // Visit the tag table which is stored in the isolate.
   visitor->VisitPointer(reinterpret_cast<RawObject**>(&tag_table_));
 
-  // Visit array of closures pending precompilation.
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&collected_closures_));
-
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(
-      &background_compilation_queue_));
+  if (background_compiler() != NULL) {
+    background_compiler()->VisitPointers(visitor);
+  }
 
   // Visit the deoptimized code array which is stored in the isolate.
   visitor->VisitPointer(
@@ -1809,17 +1765,9 @@
 }
 
 
-void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor,
-                                         bool visit_prologue_weak_handles) {
+void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) {
   if (api_state() != NULL) {
-    api_state()->VisitWeakHandles(visitor, visit_prologue_weak_handles);
-  }
-}
-
-
-void Isolate::VisitPrologueWeakPersistentHandles(HandleVisitor* visitor) {
-  if (api_state() != NULL) {
-    api_state()->VisitPrologueWeakHandles(visitor);
+    api_state()->VisitWeakHandles(visitor);
   }
 }
 
@@ -1842,17 +1790,17 @@
 void Isolate::PrintJSON(JSONStream* stream, bool ref) {
   JSONObject jsobj(stream);
   jsobj.AddProperty("type", (ref ? "@Isolate" : "Isolate"));
-  jsobj.AddFixedServiceId("isolates/%" Pd "",
-                          static_cast<intptr_t>(main_port()));
+  jsobj.AddFixedServiceId("isolates/%" Pd64 "",
+                          static_cast<int64_t>(main_port()));
 
   jsobj.AddProperty("name", debugger_name());
-  jsobj.AddPropertyF("number", "%" Pd "",
-                     static_cast<intptr_t>(main_port()));
+  jsobj.AddPropertyF("number", "%" Pd64 "",
+                     static_cast<int64_t>(main_port()));
   if (ref) {
     return;
   }
-  jsobj.AddPropertyF("_originNumber", "%" Pd "",
-                     static_cast<intptr_t>(origin_id()));
+  jsobj.AddPropertyF("_originNumber", "%" Pd64 "",
+                     static_cast<int64_t>(origin_id()));
   int64_t start_time_millis = start_time() / kMicrosecondsPerMillisecond;
   jsobj.AddPropertyTimeMillis("startTime", start_time_millis);
   {
@@ -1900,8 +1848,7 @@
     vm_tag_counters()->PrintToJSONObject(&tagCounters);
   }
   if (object_store()->sticky_error() != Object::null()) {
-    Error& error = Error::Handle(current_zone(),
-        object_store()->sticky_error());
+    Error& error = Error::Handle(object_store()->sticky_error());
     ASSERT(!error.IsNull());
     jsobj.AddProperty("error", error, false);
   }
@@ -1928,62 +1875,19 @@
     JSONObject jssettings(&jsobj, "_debuggerSettings");
     debugger()->PrintSettingsToJSONObject(&jssettings);
   }
-}
 
-
-intptr_t Isolate::ProfileInterrupt() {
-  // Other threads might be modifying these fields. Save them in locals so that
-  // we can at least trust the NULL check.
-  IsolateProfilerData* prof_data = profiler_data();
-  if (prof_data == NULL) {
-    // Profiler not setup for isolate.
-    return 0;
-  }
-  if (prof_data->blocked()) {
-    // Profiler blocked for this isolate.
-    return 0;
-  }
-  Debugger* debug = debugger();
-  if ((debug != NULL) && debug->IsPaused()) {
-    // Paused at breakpoint. Don't tick.
-    return 0;
-  }
-  MessageHandler* msg_handler = message_handler();
-  if ((msg_handler != NULL) &&
-      (msg_handler->paused_on_start() ||
-       msg_handler->paused_on_exit())) {
-    // Paused at start / exit . Don't tick.
-    return 0;
-  }
-  // Make sure that the isolate's mutator thread does not change behind our
-  // backs. Otherwise we find the entry in the registry and end up reading
-  // the field again. Only by that time it has been reset to NULL because the
-  // thread was in process of exiting the isolate.
-  Thread* mutator = mutator_thread_;
-  if (mutator == NULL) {
-    // No active mutator.
-    ProfileIdle();
-    return 1;
-  }
-
-  // TODO(johnmccutchan): Sample all threads, not just the mutator thread.
-  // TODO(johnmccutchan): Keep a global list of threads and use that
-  // instead of Isolate.
-  ThreadRegistry::EntryIterator it(thread_registry());
-  while (it.HasNext()) {
-    const ThreadRegistry::Entry& entry = it.Next();
-    if (entry.thread == mutator) {
-      ThreadInterrupter::InterruptThread(mutator);
-      break;
+  {
+    GrowableObjectArray& handlers =
+        GrowableObjectArray::Handle(registered_service_extension_handlers());
+    if (!handlers.IsNull()) {
+      JSONArray extensions(&jsobj, "extensionRPCs");
+      String& handler_name = String::Handle();
+      for (intptr_t i = 0; i < handlers.Length(); i += kRegisteredEntrySize) {
+        handler_name ^= handlers.At(i + kRegisteredNameIndex);
+        extensions.AddValue(handler_name.ToCString());
+      }
     }
   }
-  return 1;
-}
-
-
-void Isolate::ProfileIdle() {
-  // Currently we are only sampling the mutator thread.
-  vm_tag_counters_.Increment(VMTag::kIdleTagId);
 }
 
 
@@ -2004,23 +1908,17 @@
   default_tag_ = tag.raw();
 }
 
-
-void Isolate::set_collected_closures(const GrowableObjectArray& value) {
-  collected_closures_ = value.raw();
+void Isolate::set_ic_miss_code(const Code& code) {
+  ic_miss_code_ = code.raw();
 }
 
 
 void Isolate::set_deoptimized_code_array(const GrowableObjectArray& value) {
+  ASSERT(Thread::Current()->IsMutatorThread());
   deoptimized_code_array_ = value.raw();
 }
 
 
-void Isolate::set_background_compilation_queue(
-    const GrowableObjectArray& value) {
-  background_compilation_queue_ = value.raw();
-}
-
-
 void Isolate::TrackDeoptimizedCode(const Code& code) {
   ASSERT(!code.IsNull());
   const GrowableObjectArray& deoptimized_code =
@@ -2173,6 +2071,12 @@
   handlers.Add(name, Heap::kOld);
   ASSERT(kRegisteredHandlerIndex == 1);
   handlers.Add(closure, Heap::kOld);
+  {
+    // Fire off an event.
+    ServiceEvent event(this, ServiceEvent::kServiceExtensionAdded);
+    event.set_extension_rpc(&name);
+    Service::HandleEvent(&event);
+  }
 }
 
 
@@ -2411,6 +2315,20 @@
 }
 
 
+void Isolate::IncrementSpawnCount() {
+  MonitorLocker ml(spawn_count_monitor_);
+  spawn_count_++;
+}
+
+
+void Isolate::WaitForOutstandingSpawns() {
+  MonitorLocker ml(spawn_count_monitor_);
+  while (spawn_count_ > 0) {
+    ml.Wait();
+  }
+}
+
+
 static RawInstance* DeserializeObject(Thread* thread,
                                       uint8_t* obj_data,
                                       intptr_t obj_len) {
@@ -2436,19 +2354,28 @@
 
 
 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
+                                     Dart_Port origin_id,
+                                     void* init_data,
+                                     const char* script_url,
                                      const Function& func,
                                      const Instance& message,
+                                     Monitor* spawn_count_monitor,
+                                     intptr_t* spawn_count,
+                                     const char* package_root,
+                                     const char* package_config,
                                      bool paused,
                                      bool errors_are_fatal,
                                      Dart_Port on_exit_port,
                                      Dart_Port on_error_port)
     : isolate_(NULL),
       parent_port_(parent_port),
+      origin_id_(origin_id),
+      init_data_(init_data),
       on_exit_port_(on_exit_port),
       on_error_port_(on_error_port),
-      script_url_(NULL),
-      package_root_(NULL),
-      package_map_(NULL),
+      script_url_(script_url),
+      package_root_(package_root),
+      package_config_(package_config),
       library_url_(NULL),
       class_name_(NULL),
       function_name_(NULL),
@@ -2456,6 +2383,8 @@
       serialized_args_len_(0),
       serialized_message_(NULL),
       serialized_message_len_(0),
+      spawn_count_monitor_(spawn_count_monitor),
+      spawn_count_(spawn_count),
       isolate_flags_(),
       paused_(paused),
       errors_are_fatal_(errors_are_fatal) {
@@ -2481,22 +2410,27 @@
 
 
 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
+                                     void* init_data,
                                      const char* script_url,
                                      const char* package_root,
-                                     const char** package_map,
+                                     const char* package_config,
                                      const Instance& args,
                                      const Instance& message,
+                                     Monitor* spawn_count_monitor,
+                                     intptr_t* spawn_count,
                                      bool paused,
                                      bool errors_are_fatal,
                                      Dart_Port on_exit_port,
                                      Dart_Port on_error_port)
     : isolate_(NULL),
       parent_port_(parent_port),
+      origin_id_(ILLEGAL_PORT),
+      init_data_(init_data),
       on_exit_port_(on_exit_port),
       on_error_port_(on_error_port),
       script_url_(script_url),
       package_root_(package_root),
-      package_map_(package_map),
+      package_config_(package_config),
       library_url_(NULL),
       class_name_(NULL),
       function_name_(NULL),
@@ -2504,6 +2438,8 @@
       serialized_args_len_(0),
       serialized_message_(NULL),
       serialized_message_len_(0),
+      spawn_count_monitor_(spawn_count_monitor),
+      spawn_count_(spawn_count),
       isolate_flags_(),
       paused_(paused),
       errors_are_fatal_(errors_are_fatal) {
@@ -2526,14 +2462,7 @@
 IsolateSpawnState::~IsolateSpawnState() {
   delete[] script_url_;
   delete[] package_root_;
-  for (int i = 0; package_map_ != NULL; i++) {
-    if (package_map_[i] != NULL) {
-      delete[] package_map_[i];
-    } else {
-      delete[] package_map_;
-      package_map_ = NULL;
-    }
-  }
+  delete[] package_config_;
   delete[] library_url_;
   delete[] class_name_;
   delete[] function_name_;
@@ -2566,7 +2495,7 @@
     return func.raw();
   }
 
-  ASSERT(script_url() == NULL);
+  // Lookup the to be spawned function for the Isolate.spawn implementation.
   // Resolve the library.
   const String& lib_url = String::Handle(String::New(library_url()));
   const Library& lib = Library::Handle(Library::LookupLibrary(lib_url));
@@ -2621,9 +2550,13 @@
 }
 
 
-void IsolateSpawnState::Cleanup() {
-  SwitchIsolateScope switch_scope(I);
-  Dart::ShutdownIsolate();
+void IsolateSpawnState::DecrementSpawnCount() {
+  ASSERT(spawn_count_monitor_ != NULL);
+  ASSERT(spawn_count_ != NULL);
+  MonitorLocker ml(spawn_count_monitor_);
+  ASSERT(*spawn_count_ > 0);
+  *spawn_count_ = *spawn_count_ - 1;
+  ml.Notify();
 }
 
 }  // namespace dart
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 00abb13..8e84d00 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -121,13 +121,10 @@
 
   // Visit all object pointers.
   void IterateObjectPointers(ObjectPointerVisitor* visitor,
-                             bool visit_prologue_weak_persistent_handles,
                              bool validate_frames);
 
   // Visits weak object pointers.
-  void VisitWeakPersistentHandles(HandleVisitor* visitor,
-                                  bool visit_prologue_weak_persistent_handles);
-  void VisitPrologueWeakPersistentHandles(HandleVisitor* visitor);
+  void VisitWeakPersistentHandles(HandleVisitor* visitor);
 
   StoreBuffer* store_buffer() { return store_buffer_; }
 
@@ -138,6 +135,10 @@
     return OFFSET_OF(Isolate, class_table_);
   }
 
+  static intptr_t ic_miss_code_offset() {
+    return OFFSET_OF(Isolate, ic_miss_code_);
+  }
+
   Dart_MessageNotifyCallback message_notify_callback() const {
     return message_notify_callback_;
   }
@@ -151,8 +152,8 @@
   bool HasMutatorThread() {
     return mutator_thread_ != NULL;
   }
-  bool MutatorThreadIsCurrentThread() {
-    return mutator_thread_ == Thread::Current();
+  Thread* mutator_thread() const {
+    return mutator_thread_;
   }
 
   const char* name() const { return name_; }
@@ -188,26 +189,6 @@
   ObjectStore* object_store() const { return object_store_; }
   void set_object_store(ObjectStore* value) { object_store_ = value; }
 
-  // DEPRECATED: Use Thread's methods instead. During migration, these default
-  // to using the mutator thread (which must also be the current thread).
-  StackResource* top_resource() const {
-    ASSERT(Thread::Current() == mutator_thread_);
-    return mutator_thread_->top_resource();
-  }
-  void set_top_resource(StackResource* value) {
-    ASSERT(Thread::Current() == mutator_thread_);
-    mutator_thread_->set_top_resource(value);
-  }
-  // DEPRECATED: Use Thread's methods instead. During migration, these default
-  // to using the mutator thread.
-  // NOTE: These are also used by the profiler.
-  uword top_exit_frame_info() const {
-    return mutator_thread_->top_exit_frame_info();
-  }
-  void set_top_exit_frame_info(uword value) {
-    mutator_thread_->set_top_exit_frame_info(value);
-  }
-
   ApiState* api_state() const { return api_state_; }
   void set_api_state(ApiState* value) { api_state_ = value; }
 
@@ -232,7 +213,6 @@
     library_tag_handler_ = value;
   }
 
-  void InitializeStackLimit();
   void SetStackLimit(uword value);
   void SetStackLimitFromStackBase(uword stack_base);
   void ClearStackLimit();
@@ -271,8 +251,6 @@
   // The true stack limit for this isolate.
   uword saved_stack_limit() const { return saved_stack_limit_; }
 
-  uword stack_base() const { return stack_base_; }
-
   // Stack overflow flags
   enum {
     kOsrRequest = 0x1,  // Current stack overflow caused by OSR request.
@@ -291,13 +269,6 @@
   // stack overflow is called.
   uword GetAndClearStackOverflowFlags();
 
-  // Retrieve the stack address bounds for profiler.
-  bool GetProfilerStackBounds(uword* lower, uword* upper) const;
-
-  static uword GetSpecifiedStackSize();
-
-  static const intptr_t kStackSizeBuffer = (4 * KB * kWordSize);
-
   // Interrupt bits.
   enum {
     kVMInterrupt = 0x1,  // Internal VM checks: safepoints, store buffers, etc.
@@ -377,17 +348,6 @@
 
   const Flags& flags() const { return flags_; }
 
-  // Set the checks in the compiler to the highest level. Statically and when
-  // executing generated code. Needs to be called before any code has been
-  // compiled.
-  void set_strict_compilation() {
-    ASSERT(!has_compiled_code());
-    flags_.type_checks_ = true;
-    flags_.asserts_ = true;
-    flags_.error_on_bad_type_ = true;
-    flags_.error_on_bad_override_ = true;
-  }
-
   // Requests that the debugger resume execution.
   void Resume() {
     resume_request_ = true;
@@ -452,6 +412,12 @@
     gc_epilogue_callback_ = callback;
   }
 
+  Monitor* spawn_count_monitor() const { return spawn_count_monitor_; }
+  intptr_t* spawn_count() { return &spawn_count_; }
+
+  void IncrementSpawnCount();
+  void WaitForOutstandingSpawns();
+
   static void SetCreateCallback(Dart_IsolateCreateCallback cb) {
     create_callback_ = cb;
   }
@@ -459,21 +425,6 @@
     return create_callback_;
   }
 
-  static void SetInterruptCallback(Dart_IsolateInterruptCallback cb) {
-    interrupt_callback_ = cb;
-  }
-  static Dart_IsolateInterruptCallback InterruptCallback() {
-    return interrupt_callback_;
-  }
-
-  static void SetUnhandledExceptionCallback(
-      Dart_IsolateUnhandledExceptionCallback cb) {
-    unhandled_exception_callback_ = cb;
-  }
-  static Dart_IsolateUnhandledExceptionCallback UnhandledExceptionCallback() {
-    return unhandled_exception_callback_;
-  }
-
   static void SetShutdownCallback(Dart_IsolateShutdownCallback cb) {
     shutdown_callback_ = cb;
   }
@@ -570,27 +521,12 @@
     return defer_finalization_count_ == 0;
   }
 
-  Mutex* profiler_data_mutex() {
-    return &profiler_data_mutex_;
-  }
-
-  void set_profiler_data(IsolateProfilerData* profiler_data) {
-    profiler_data_ = profiler_data;
-  }
-
-  IsolateProfilerData* profiler_data() const {
-    return profiler_data_;
-  }
-
   void PrintJSON(JSONStream* stream, bool ref = true);
 
   CompilerStats* compiler_stats() {
     return compiler_stats_;
   }
 
-  // Returns the number of sampled threads.
-  intptr_t ProfileInterrupt();
-
   VMTagCounters* vm_tag_counters() {
     return &vm_tag_counters_;
   }
@@ -629,15 +565,7 @@
   RawUserTag* default_tag() const { return default_tag_; }
   void set_default_tag(const UserTag& tag);
 
-  RawGrowableObjectArray* collected_closures() const {
-    return collected_closures_;
-  }
-  void set_collected_closures(const GrowableObjectArray& value);
-
-  RawGrowableObjectArray* background_compilation_queue() const {
-    return background_compilation_queue_;
-  }
-  void set_background_compilation_queue(const GrowableObjectArray& value);
+  void set_ic_miss_code(const Code& code);
 
   Metric* metrics_list_head() {
     return metrics_list_head_;
@@ -658,6 +586,37 @@
     compilation_allowed_ = allowed;
   }
 
+  // In precompilation we finalize all regular classes before compiling.
+  bool all_classes_finalized() const { return all_classes_finalized_; }
+  void set_all_classes_finalized(bool value) {
+    all_classes_finalized_ = value;
+  }
+
+  static const uint32_t kInvalidGen = 0;
+
+  void IncrCHAInvalidationGen() {
+    cha_invalidation_gen_++;
+    if (cha_invalidation_gen_ == kInvalidGen) cha_invalidation_gen_++;
+  }
+  void ResetCHAInvalidationGen() { cha_invalidation_gen_ = kInvalidGen; }
+  uint32_t cha_invalidation_gen() const { return cha_invalidation_gen_; }
+
+
+  void IncrFieldInvalidationGen() {
+    field_invalidation_gen_++;
+    if (field_invalidation_gen_ == kInvalidGen) field_invalidation_gen_++;
+  }
+
+  void ResetFieldInvalidationGen() { field_invalidation_gen_ = kInvalidGen; }
+  uint32_t field_invalidation_gen() const { return field_invalidation_gen_; }
+
+  void IncrPrefixInvalidationGen() {
+    prefix_invalidation_gen_++;
+    if (prefix_invalidation_gen_ == kInvalidGen) prefix_invalidation_gen_++;
+  }
+  void ResetPrefixInvalidationGen() { prefix_invalidation_gen_ = kInvalidGen; }
+  uint32_t prefix_invalidation_gen() const { return prefix_invalidation_gen_; }
+
   RawObject* InvokePendingServiceExtensionCalls();
   void AppendServiceExtensionCall(const Instance& closure,
                            const String& method_name,
@@ -674,16 +633,11 @@
   // Handle service messages until we are told to resume execution.
   void PauseEventHandler();
 
-  // DEPRECATED: Use Thread's methods instead. During migration, these default
-  // to using the mutator thread (which must also be the current thread).
-  Zone* current_zone() const {
-    ASSERT(Thread::Current() == mutator_thread_);
-    return mutator_thread_->zone();
-  }
-  void set_current_zone(Zone* zone) {
-    ASSERT(Thread::Current() == mutator_thread_);
-    mutator_thread_->set_zone(zone);
-  }
+  void AddClosureFunction(const Function& function) const;
+  RawFunction* LookupClosureFunction(const Function& parent,
+                                     intptr_t token_pos) const;
+  intptr_t FindClosureIndex(const Function& needle) const;
+  RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;
 
   bool is_service_isolate() const { return is_service_isolate_; }
 
@@ -709,18 +663,14 @@
 
   void LowLevelShutdown();
   void Shutdown();
-  void ReclaimTimelineBlocks();
 
   void BuildName(const char* name_prefix);
-  void PrintInvokedFunctions();
 
   void ProfileIdle();
 
   // Visit all object pointers. Caller must ensure concurrent sweeper is not
   // running, and the visitor must not allocate.
-  void VisitObjectPointers(ObjectPointerVisitor* visitor,
-                           bool visit_prologue_weak_persistent_handles,
-                           bool validate_frames);
+  void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames);
 
   void set_user_tag(uword tag) {
     user_tag_ = tag;
@@ -749,14 +699,23 @@
   bool IsIsolateOf(Thread* thread);
 #endif  // DEBUG
 
+  // DEPRECATED: Use Thread's methods instead. During migration, these default
+  // to using the mutator thread (which must also be the current thread).
+  Zone* current_zone() const {
+    ASSERT(Thread::Current() == mutator_thread_);
+    return mutator_thread_->zone();
+  }
+
   // Accessed from generated code:
+  // TODO(asiva): Need to consider moving the stack_limit_ from isolate to
+  // being thread specific.
   uword stack_limit_;
   StoreBuffer* store_buffer_;
   Heap* heap_;
-  uword vm_tag_;
   uword user_tag_;
   RawUserTag* current_tag_;
   RawUserTag* default_tag_;
+  RawCode* ic_miss_code_;
   ClassTable class_table_;
   bool single_step_;
 
@@ -783,9 +742,8 @@
   Flags flags_;
   Random random_;
   Simulator* simulator_;
-  Mutex* mutex_;  // protects stack_limit_ and saved_stack_limit_.
+  Mutex* mutex_;  // protects stack_limit_, saved_stack_limit_, compiler stats.
   uword saved_stack_limit_;
-  uword stack_base_;
   uword stack_overflow_flags_;
   int32_t stack_overflow_count_;
   MessageHandler* message_handler_;
@@ -795,7 +753,6 @@
   Dart_GcEpilogueCallback gc_epilogue_callback_;
   intptr_t defer_finalization_count_;
   DeoptContext* deopt_context_;
-  BackgroundCompiler* background_compiler_;
 
   CompilerStats* compiler_stats_;
 
@@ -815,16 +772,13 @@
   // Trace buffer support.
   TraceBuffer* trace_buffer_;
 
-  IsolateProfilerData* profiler_data_;
-  Mutex profiler_data_mutex_;
-
   VMTagCounters vm_tag_counters_;
   RawGrowableObjectArray* tag_table_;
 
-
-  RawGrowableObjectArray* collected_closures_;
   RawGrowableObjectArray* deoptimized_code_array_;
-  RawGrowableObjectArray* background_compilation_queue_;
+
+  // Background compilation.
+  BackgroundCompiler* background_compiler_;
 
   // We use 6 list entries for each pending service extension calls.
   enum {
@@ -849,6 +803,7 @@
   Metric* metrics_list_head_;
 
   bool compilation_allowed_;
+  bool all_classes_finalized_;
 
   // Isolate list next pointer.
   Isolate* next_;
@@ -856,6 +811,18 @@
   // Used to wake the isolate when it is in the pause event loop.
   Monitor* pause_loop_monitor_;
 
+  // Invalidation generations; used to track events occuring in parallel
+  // to background compilation. The counters may overflow, which is OK
+  // since we check for equality to detect if an event occured.
+  uint32_t cha_invalidation_gen_;
+  uint32_t field_invalidation_gen_;
+  uint32_t prefix_invalidation_gen_;
+
+  // This guards spawn_count_. An isolate cannot complete shutdown and be
+  // destroyed while there are child isolates in the midst of a spawn.
+  Monitor* spawn_count_monitor_;
+  intptr_t spawn_count_;
+
 #define ISOLATE_METRIC_VARIABLE(type, variable, name, unit)                    \
   type metric_##variable##_;
   ISOLATE_METRIC_LIST(ISOLATE_METRIC_VARIABLE);
@@ -867,8 +834,6 @@
 #undef ISOLATE_TIMELINE_STREAM_VARIABLE
 
   static Dart_IsolateCreateCallback create_callback_;
-  static Dart_IsolateInterruptCallback interrupt_callback_;
-  static Dart_IsolateUnhandledExceptionCallback unhandled_exception_callback_;
   static Dart_IsolateShutdownCallback shutdown_callback_;
   static Dart_FileOpenCallback file_open_callback_;
   static Dart_FileReadCallback file_read_callback_;
@@ -911,28 +876,29 @@
       : new_isolate_(new_isolate), saved_isolate_(Isolate::Current()) {
     // TODO(koda): Audit users; passing NULL goes against naming of this class.
     if (new_isolate_ == NULL) {
+      ASSERT(Isolate::Current() == NULL);
       // Do nothing.
       return;
     }
     if (saved_isolate_ != new_isolate_) {
       ASSERT(Isolate::Current() == NULL);
+      // Ensure this is not a nested 'isolate enter' with prior state.
+      ASSERT(new_isolate_->saved_stack_limit() == 0);
       Thread::EnterIsolate(new_isolate_);
-      new_isolate_->SetStackLimitFromStackBase(
-          Isolate::GetCurrentStackPointer());
     }
   }
 
   ~StartIsolateScope() {
     if (new_isolate_ == NULL) {
+      ASSERT(Isolate::Current() == NULL);
       // Do nothing.
       return;
     }
     if (saved_isolate_ != new_isolate_) {
-      new_isolate_->ClearStackLimit();
+      ASSERT(saved_isolate_ == NULL);
+      // ASSERT that we have bottomed out of all Dart invocations.
+      ASSERT(new_isolate_->saved_stack_limit() == 0);
       Thread::ExitIsolate();
-      if (saved_isolate_ != NULL) {
-        Thread::EnterIsolate(saved_isolate_);
-      }
     }
   }
 
@@ -943,64 +909,32 @@
   DISALLOW_COPY_AND_ASSIGN(StartIsolateScope);
 };
 
-// When we need to temporarily become another isolate, we use the
-// SwitchIsolateScope.  It is not permitted to run dart code while in
-// a SwitchIsolateScope.
-class SwitchIsolateScope {
- public:
-  explicit SwitchIsolateScope(Isolate* new_isolate)
-      : new_isolate_(new_isolate),
-        saved_isolate_(Isolate::Current()),
-        saved_stack_limit_(saved_isolate_
-                           ? saved_isolate_->saved_stack_limit() : 0) {
-    // TODO(koda): Audit users; why would these two ever be equal?
-    if (saved_isolate_ != new_isolate_) {
-      if (new_isolate_ == NULL) {
-        Thread::ExitIsolate();
-      } else {
-        Thread::EnterIsolate(new_isolate_);
-        // Don't allow dart code to execute.
-        new_isolate_->SetStackLimit(~static_cast<uword>(0));
-      }
-    }
-  }
-
-  ~SwitchIsolateScope() {
-    if (saved_isolate_ != new_isolate_) {
-      if (new_isolate_ != NULL) {
-        Thread::ExitIsolate();
-      }
-      if (saved_isolate_ != NULL) {
-        Thread::EnterIsolate(saved_isolate_);
-        saved_isolate_->SetStackLimit(saved_stack_limit_);
-      }
-    }
-  }
-
- private:
-  Isolate* new_isolate_;
-  Isolate* saved_isolate_;
-  uword saved_stack_limit_;
-
-  DISALLOW_COPY_AND_ASSIGN(SwitchIsolateScope);
-};
-
 
 class IsolateSpawnState {
  public:
   IsolateSpawnState(Dart_Port parent_port,
+                    Dart_Port origin_id,
+                    void* init_data,
+                    const char* script_url,
                     const Function& func,
                     const Instance& message,
+                    Monitor* spawn_count_monitor,
+                    intptr_t* spawn_count,
+                    const char* package_root,
+                    const char* package_config,
                     bool paused,
                     bool errorsAreFatal,
                     Dart_Port onExit,
                     Dart_Port onError);
   IsolateSpawnState(Dart_Port parent_port,
+                    void* init_data,
                     const char* script_url,
                     const char* package_root,
-                    const char** package_map,
+                    const char* package_config,
                     const Instance& args,
                     const Instance& message,
+                    Monitor* spawn_count_monitor,
+                    intptr_t* spawn_count,
                     bool paused,
                     bool errorsAreFatal,
                     Dart_Port onExit,
@@ -1011,11 +945,13 @@
   void set_isolate(Isolate* value) { isolate_ = value; }
 
   Dart_Port parent_port() const { return parent_port_; }
+  Dart_Port origin_id() const { return origin_id_; }
+  void* init_data() const { return init_data_; }
   Dart_Port on_exit_port() const { return on_exit_port_; }
   Dart_Port on_error_port() const { return on_error_port_; }
   const char* script_url() const { return script_url_; }
   const char* package_root() const { return package_root_; }
-  const char** package_map() const { return package_map_; }
+  const char* package_config() const { return package_config_; }
   const char* library_url() const { return library_url_; }
   const char* class_name() const { return class_name_; }
   const char* function_name() const { return function_name_; }
@@ -1027,16 +963,19 @@
   RawObject* ResolveFunction();
   RawInstance* BuildArgs(Thread* thread);
   RawInstance* BuildMessage(Thread* thread);
-  void Cleanup();
+
+  void DecrementSpawnCount();
 
  private:
   Isolate* isolate_;
   Dart_Port parent_port_;
+  Dart_Port origin_id_;
+  void* init_data_;
   Dart_Port on_exit_port_;
   Dart_Port on_error_port_;
   const char* script_url_;
   const char* package_root_;
-  const char** package_map_;
+  const char* package_config_;
   const char* library_url_;
   const char* class_name_;
   const char* function_name_;
@@ -1044,6 +983,12 @@
   intptr_t serialized_args_len_;
   uint8_t* serialized_message_;
   intptr_t serialized_message_len_;
+
+  // This counter tracks the number of outstanding calls to spawn by the parent
+  // isolate.
+  Monitor* spawn_count_monitor_;
+  intptr_t* spawn_count_;
+
   Isolate::Flags isolate_flags_;
   bool paused_;
   bool errors_are_fatal_;
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index 8dcc14e..4bf156d 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -74,10 +74,10 @@
 
 
   result = Dart_Invoke(test_lib, NewString("testMain"), 0, NULL);
-  EXPECT(!Dart_IsError(result));
+  EXPECT_VALID(result);
   // Run until all ports to isolate are closed.
   result = Dart_RunLoop();
-  EXPECT_ERROR(result, "Null callback specified for isolate creation");
+  EXPECT_ERROR(result, "Unsupported operation: Isolate.spawn");
   EXPECT(Dart_ErrorHasException(result));
   Dart_Handle exception_result = Dart_ErrorGetException(result);
   EXPECT_VALID(exception_result);
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 0f4f3a6..4851875 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -30,7 +30,9 @@
       method_(""),
       param_keys_(NULL),
       param_values_(NULL),
-      num_params_(0) {
+      num_params_(0),
+      offset_(0),
+      count_(-1) {
   ObjectIdRing* ring = NULL;
   Isolate* isolate = Isolate::Current();
   if (isolate != NULL) {
@@ -159,16 +161,8 @@
 
 
 void JSONStream::PostNullReply(Dart_Port port) {
-  const Object& reply = Object::Handle(Object::null());
-  ASSERT(reply.IsNull());
-
-  uint8_t* data = NULL;
-  MessageWriter writer(&data, &allocator, false);
-  writer.WriteMessage(reply);
-  PortMap::PostMessage(new Message(port,
-                                   data,
-                                   writer.BytesWritten(),
-                                   Message::kNormalPriority));
+  PortMap::PostMessage(new Message(
+      port, Object::null(), Message::kNormalPriority));
 }
 
 
@@ -245,6 +239,36 @@
 }
 
 
+void JSONStream::ComputeOffsetAndCount(intptr_t length,
+                                       intptr_t* offset,
+                                       intptr_t* count) {
+  // This function is written to avoid adding (count + offset) in case
+  // that triggers an integer overflow.
+  *offset = offset_;
+  if (*offset > length) {
+    *offset = length;
+  }
+  intptr_t remaining = length - *offset;
+  *count = count_;
+  if (*count < 0 || *count > remaining) {
+    *count = remaining;
+  }
+}
+
+
+void JSONStream::AppendSerializedObject(const char* serialized_object) {
+  PrintCommaIfNeeded();
+  buffer_.AddString(serialized_object);
+}
+
+
+void JSONStream::AppendSerializedObject(const char* property_name,
+                                        const char* serialized_object) {
+  PrintCommaIfNeeded();
+  PrintPropertyName(property_name);
+  buffer_.AddString(serialized_object);
+}
+
 void JSONStream::Clear() {
   buffer_.Clear();
   open_objects_ = 0;
@@ -285,6 +309,11 @@
 }
 
 
+void JSONStream::PrintValueNull() {
+  PrintCommaIfNeeded();
+  buffer_.Printf("null");
+}
+
 void JSONStream::PrintValueBool(bool b) {
   PrintCommaIfNeeded();
   buffer_.Printf("%s", b ? "true" : "false");
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index cd8fe62..239c4e7 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -6,7 +6,7 @@
 #define VM_JSON_STREAM_H_
 
 #include "include/dart_api.h"  // for Dart_Port
-#include "platform/json.h"
+#include "platform/text_buffer.h"
 #include "vm/allocation.h"
 #include "vm/service.h"
 
@@ -109,6 +109,27 @@
   const char** param_keys() const { return param_keys_; }
   const char** param_values() const { return param_values_; }
 
+  void set_offset(intptr_t value) {
+    ASSERT(value > 0);
+    offset_ = value;
+  }
+
+  void set_count(intptr_t value) {
+    ASSERT(value > 0);
+    count_ = value;
+  }
+
+  void ComputeOffsetAndCount(intptr_t length,
+                             intptr_t* offset,
+                             intptr_t* count);
+
+  // Append |serialized_object| to the stream.
+  void AppendSerializedObject(const char* serialized_object);
+
+  // Append |serialized_object| to the stream with |property_name|.
+  void AppendSerializedObject(const char* property_name,
+                              const char* serialized_object);
+
  private:
   void Clear();
   void PostNullReply(Dart_Port port);
@@ -119,6 +140,7 @@
   void OpenArray(const char* property_name = NULL);
   void CloseArray();
 
+  void PrintValueNull();
   void PrintValueBool(bool b);
   void PrintValue(intptr_t i);
   void PrintValue64(int64_t i);
@@ -188,6 +210,8 @@
   const char** param_keys_;
   const char** param_values_;
   intptr_t num_params_;
+  intptr_t offset_;
+  intptr_t count_;
   int64_t setup_time_micros_;
 
   friend class JSONObject;
@@ -309,6 +333,7 @@
     stream_->CloseArray();
   }
 
+  void AddValueNull() const { stream_->PrintValueNull(); }
   void AddValue(bool b) const { stream_->PrintValueBool(b); }
   void AddValue(intptr_t i) const { stream_->PrintValue(i); }
   void AddValue64(int64_t i) const { stream_->PrintValue64(i); }
diff --git a/runtime/vm/json_test.cc b/runtime/vm/json_test.cc
index 6ca6760..245bdd6 100644
--- a/runtime/vm/json_test.cc
+++ b/runtime/vm/json_test.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "platform/assert.h"
-#include "platform/json.h"
+#include "platform/text_buffer.h"
 #include "vm/json_stream.h"
 #include "vm/unit_test.h"
 #include "vm/dart_api_impl.h"
@@ -11,131 +11,12 @@
 namespace dart {
 
 
-TEST_CASE(JSON_ScanJSON) {
-  const char* msg = "{ \"id\": 5, \"command\" : \"Debugger.pause\" }";
-
-  JSONScanner scanner(msg);
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenIllegal);
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenLBrace);
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenString);
-  EXPECT(scanner.IsStringLiteral("id"));
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenColon);
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenInteger);
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenComma);
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenString);
-  EXPECT(scanner.IsStringLiteral("command"));
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenColon);
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenString);
-  EXPECT(scanner.IsStringLiteral("Debugger.pause"));
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenRBrace);
-  scanner.Scan();
-  EXPECT_EQ(scanner.CurrentToken(), JSONScanner::TokenEOM);
-}
-
-
-TEST_CASE(JSON_SyntaxError) {
-    const char* jobj = "{ \"id\": 5, "
-                     "  \"command\" : \"Debugger.stop\""  // Missing comma.
-                     "  \"params\" : { "
-                     "    \"url\" : \"blah.dart\", "  // Missing comma.
-                     "    \"line\": 111, "
-                     "  },"
-                     "  \"foo\": \"outer foo\", "
-                     "}";
-  JSONReader reader(jobj);
-  bool found;
-
-  found = reader.Seek("id");
-  EXPECT(found);
-  EXPECT_EQ(reader.Type(), JSONReader::kInteger);
-  found = reader.Seek("params");
-  EXPECT(!found);
-  EXPECT(reader.Error());
-  EXPECT_EQ(reader.Type(), JSONReader::kNone);
-  EXPECT_EQ(0, reader.ValueLen());
-  EXPECT(reader.ValueChars() == NULL);
-}
-
-
-TEST_CASE(JSON_JSONReader) {
-  const char* jobj = "{ \"id\": 5, "
-                     "  \"command\" : \"Debugger.setBreakpoint\","
-                     "  \"params\" : { "
-                     "    \"url\" : \"blah.dart\", "
-                     "    \"foo\" : [null, 1, { }, \"bar\", true, false],"
-                     "    \"line\": 111, "
-                     "  },"
-                     "  \"foo\": \"outer foo\",     "
-                     "  \"quote\": \"\\\"\",        "
-                     "  \"white\": \"\\t \\n\",     "
-                     "}";
-
-  JSONReader reader(jobj);
-  bool found;
-  char s[128];
-
-  found = reader.Seek("id");
-  EXPECT(found);
-  EXPECT_EQ(reader.Type(), JSONReader::kInteger);
-  found = reader.Seek("foo");
-  EXPECT(found);
-  EXPECT_EQ(reader.Type(), JSONReader::kString);
-  EXPECT(reader.IsStringLiteral("outer foo"));
-
-  found = reader.Seek("quote");
-  EXPECT(found);
-  EXPECT_EQ(reader.Type(), JSONReader::kString);
-  reader.GetRawValueChars(s, sizeof s);
-  EXPECT_STREQ("\\\"", s);
-  reader.GetDecodedValueChars(s, sizeof s);
-  EXPECT_STREQ("\"", s);
-
-  found = reader.Seek("white");
-  EXPECT(found);
-  EXPECT_EQ(reader.Type(), JSONReader::kString);
-  reader.GetRawValueChars(s, sizeof s);
-  EXPECT_STREQ("\\t \\n", s);
-  reader.GetDecodedValueChars(s, sizeof s);
-  EXPECT_STREQ("\t \n", s);
-
-  found = reader.Seek("line");
-  EXPECT(!found);
-  found = reader.Seek("params");
-  EXPECT(found);
-  EXPECT_EQ(reader.Type(), JSONReader::kObject);
-  reader.Set(reader.ValueChars());
-  found = reader.Seek("foo");
-  EXPECT(found);
-  EXPECT_EQ(reader.Type(), JSONReader::kArray);
-  found = reader.Seek("non-existing");
-  EXPECT(!found);
-  found = reader.Seek("line");
-  EXPECT(found);
-  EXPECT_EQ(reader.Type(), JSONReader::kInteger);
-}
-
-
 TEST_CASE(JSON_TextBuffer) {
   TextBuffer w(5);  // Small enough to make buffer grow at least once.
   w.Printf("{ \"%s\" : %d", "length", 175);
   EXPECT_STREQ("{ \"length\" : 175", w.buf());
   w.Printf(", \"%s\" : \"%s\" }", "command", "stopIt");
   EXPECT_STREQ("{ \"length\" : 175, \"command\" : \"stopIt\" }", w.buf());
-
-  JSONReader r(w.buf());
-  bool found = r.Seek("command");
-  EXPECT(found);
-  EXPECT_EQ(r.Type(), JSONReader::kString);
-  EXPECT(r.IsStringLiteral("stopIt"));
 }
 
 
diff --git a/runtime/vm/locations.cc b/runtime/vm/locations.cc
index e460a2d..de4f773 100644
--- a/runtime/vm/locations.cc
+++ b/runtime/vm/locations.cc
@@ -6,8 +6,6 @@
 
 #include "vm/assembler.h"
 #include "vm/il_printer.h"
-#include "vm/intermediate_language.h"
-#include "vm/flow_graph_compiler.h"
 #include "vm/log.h"
 #include "vm/stack_frame.h"
 
diff --git a/runtime/vm/log.cc b/runtime/vm/log.cc
index e29432f..d576beb 100644
--- a/runtime/vm/log.cc
+++ b/runtime/vm/log.cc
@@ -32,7 +32,9 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   if (isolate != NULL && Log::ShouldLogForIsolate(isolate)) {
-    return thread->log();
+    OSThread* os_thread = thread->os_thread();
+    ASSERT(os_thread != NULL);
+    return os_thread->log();
   } else {
     return Log::NoOpLog();
   }
diff --git a/runtime/vm/longjump.cc b/runtime/vm/longjump.cc
index e2cf726..5820a47 100644
--- a/runtime/vm/longjump.cc
+++ b/runtime/vm/longjump.cc
@@ -26,14 +26,14 @@
   // We do not want to jump past Dart frames.  Note that this code
   // assumes the stack grows from high to low.
   Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
   uword jumpbuf_addr = Isolate::GetCurrentStackPointer();
 #if defined(USING_SIMULATOR)
-  uword top_exit_frame_info = isolate->simulator()->top_exit_frame_info();
+  Simulator* sim = Simulator::Current();
+  uword top_exit_frame_info = sim->top_exit_frame_info();
 #else
   uword top_exit_frame_info = thread->top_exit_frame_info();
 #endif
-  if (!isolate->MutatorThreadIsCurrentThread()) {
+  if (!thread->IsMutatorThread()) {
     // A helper thread does not execute Dart code, so it's safe to jump.
     ASSERT(top_exit_frame_info == 0);
     return true;
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 7f98d3b..7f4bbec 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -15,31 +15,30 @@
 RawMegamorphicCache* MegamorphicCacheTable::Lookup(Isolate* isolate,
                                                    const String& name,
                                                    const Array& descriptor) {
+  // Multiple compilation threads could access this lookup.
+  MutexLocker ml(isolate->mutex());
   ASSERT(name.IsSymbol());
   // TODO(rmacnak): ASSERT(descriptor.IsCanonical());
 
   // TODO(rmacnak): Make a proper hashtable a la symbol table.
   GrowableObjectArray& table = GrowableObjectArray::Handle(
       isolate->object_store()->megamorphic_cache_table());
+  MegamorphicCache& cache = MegamorphicCache::Handle();
   if (table.IsNull()) {
     table = GrowableObjectArray::New(Heap::kOld);
-    ASSERT((table.Length() % kEntrySize) == 0);
     isolate->object_store()->set_megamorphic_cache_table(table);
   } else {
-    for (intptr_t i = 0; i < table.Length(); i += kEntrySize) {
-      if ((table.At(i + kEntryNameOffset) == name.raw()) &&
-          (table.At(i + kEntryDescriptorOffset) == descriptor.raw())) {
-        return MegamorphicCache::RawCast(table.At(i + kEntryCacheOffset));
+    for (intptr_t i = 0; i < table.Length(); i++) {
+      cache ^= table.At(i);
+      if ((cache.target_name() == name.raw()) &&
+          (cache.arguments_descriptor() == descriptor.raw())) {
+        return cache.raw();
       }
     }
   }
 
-  const MegamorphicCache& cache =
-      MegamorphicCache::Handle(MegamorphicCache::New());
-  table.Add(name, Heap::kOld);
-  table.Add(descriptor, Heap::kOld);
+  cache = MegamorphicCache::New(name, descriptor);
   table.Add(cache, Heap::kOld);
-  ASSERT((table.Length() % kEntrySize) == 0);
   return cache.raw();
 }
 
@@ -89,14 +88,14 @@
   const GrowableObjectArray& table = GrowableObjectArray::Handle(
       isolate->object_store()->megamorphic_cache_table());
   if (table.IsNull()) return;
-  for (intptr_t i = 0; i < table.Length(); i += kEntrySize) {
-    cache ^= table.At(i + kEntryCacheOffset);
+  for (intptr_t i = 0; i < table.Length(); i++) {
+    cache ^= table.At(i);
     buckets = cache.buckets();
     size += MegamorphicCache::InstanceSize();
     size += Array::InstanceSize(buckets.Length());
   }
   OS::Print("%" Pd " megamorphic caches using %" Pd "KB.\n",
-            table.Length() / kEntrySize, size / 1024);
+            table.Length(), size / 1024);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/megamorphic_cache_table.h b/runtime/vm/megamorphic_cache_table.h
index c47d4d8..4c7242a 100644
--- a/runtime/vm/megamorphic_cache_table.h
+++ b/runtime/vm/megamorphic_cache_table.h
@@ -30,14 +30,6 @@
                                      const Array& descriptor);
 
   static void PrintSizes(Isolate* isolate);
-
- private:
-  enum {
-    kEntryNameOffset = 0,
-    kEntryDescriptorOffset,
-    kEntryCacheOffset,
-    kEntrySize
-  };
 };
 
 }  // namespace dart
diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
index dc638b2..54f40b4 100644
--- a/runtime/vm/message.cc
+++ b/runtime/vm/message.cc
@@ -196,8 +196,8 @@
                          current->Id());
     message.AddProperty("size", current->len());
     message.AddProperty("index", depth++);
-    message.AddProperty("_destinationPort",
-        static_cast<intptr_t>(current->dest_port()));
+    message.AddPropertyF("_destinationPort", "%" Pd64 "",
+        static_cast<int64_t>(current->dest_port()));
     message.AddProperty("_priority",
         Message::PriorityAsString(current->priority()));
     // TODO(johnmccutchan): Move port -> handler map out of Dart and into the
diff --git a/runtime/vm/message.h b/runtime/vm/message.h
index 42a1eb1..aaa14c7 100644
--- a/runtime/vm/message.h
+++ b/runtime/vm/message.h
@@ -8,6 +8,7 @@
 #include "platform/assert.h"
 #include "vm/allocation.h"
 #include "vm/globals.h"
+#include "vm/raw_object.h"
 
 // Duplicated from dart_api.h to avoid including the whole header.
 typedef int64_t Dart_Port;
@@ -57,17 +58,46 @@
     ASSERT((priority == kNormalPriority) ||
            (delivery_failure_port == kIllegalPort));
   }
+
+  // Message objects can also carry RawObject pointers for Smis and objects in
+  // the VM heap. This is indicated by setting the len_ field to 0.
+  Message(Dart_Port dest_port,
+          RawObject* raw_obj,
+          Priority priority,
+          Dart_Port delivery_failure_port = kIllegalPort)
+      : next_(NULL),
+        dest_port_(dest_port),
+        delivery_failure_port_(delivery_failure_port),
+        data_(reinterpret_cast<uint8_t*>(raw_obj)),
+        len_(0),
+        priority_(priority) {
+    ASSERT(!raw_obj->IsHeapObject() || raw_obj->IsVMHeapObject());
+    ASSERT((priority == kNormalPriority) ||
+           (delivery_failure_port == kIllegalPort));
+  }
   ~Message() {
     ASSERT(delivery_failure_port_ == kIllegalPort);
-    free(data_);
+    if (len_ > 0) {
+      free(data_);
+    }
   }
 
   Dart_Port dest_port() const { return dest_port_; }
-  uint8_t* data() const { return data_; }
-  intptr_t len() const { return len_; }
+  uint8_t* data() const {
+    ASSERT(len_ > 0);
+    return data_;
+  }
+  intptr_t len() const {
+    return len_;
+  }
+  RawObject* raw_obj() const {
+    ASSERT(len_ == 0);
+    return reinterpret_cast<RawObject*>(data_);
+  }
   Priority priority() const { return priority_; }
 
   bool IsOOB() const { return priority_ == Message::kOOBPriority; }
+  bool IsRaw() const { return len_ == 0; }
 
   bool RedirectToDeliveryFailurePort();
 
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index 47ab4b9..30194cd 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -183,10 +183,6 @@
   // If isolate() returns NULL StartIsolateScope does nothing.
   StartIsolateScope start_isolate(isolate());
 
-  // ThreadInterrupter may have gone to sleep while waiting for
-  // an isolate to start handling messages.
-  ThreadInterrupter::WakeUp();
-
   MessageStatus max_status = kOK;
   Message::Priority min_priority = ((allow_normal_messages && !paused())
                                     ? Message::kNormalPriority
diff --git a/runtime/vm/message_handler_test.cc b/runtime/vm/message_handler_test.cc
index ae7edab..314eb7c 100644
--- a/runtime/vm/message_handler_test.cc
+++ b/runtime/vm/message_handler_test.cc
@@ -399,7 +399,7 @@
   info.handler = &handler;
   info.ports = ports;
   info.count = 10;
-  OSThread::Start(SendMessages, reinterpret_cast<uword>(&info));
+  OSThread::Start("SendMessages", SendMessages, reinterpret_cast<uword>(&info));
   while (sleep < kMaxSleep && handler.message_count() < 11) {
     OS::Sleep(10);
     sleep += 10;
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index 5e8e576..c878847 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -15,7 +15,7 @@
 #define OTHER_RECOGNIZED_LIST(V)                                               \
   V(::, identical, ObjectIdentical, 554128144)                                 \
   V(ClassID, getID, ClassIDgetID, 535124072)                                   \
-  V(Object, Object., ObjectConstructor, 1066759160)                            \
+  V(Object, Object., ObjectConstructor, 1852396454)                            \
   V(_List, ., ObjectArrayAllocate, 850375012)                                  \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1541411498)                    \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 1032404349)                  \
@@ -188,6 +188,7 @@
   V(_StringBase, get:hashCode, String_getHashCode, 2103025405)                 \
   V(_StringBase, get:isEmpty, StringBaseIsEmpty, 780870414)                    \
   V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 397735324)                  \
+  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 347814979)     \
   V(_StringBase, [], StringBaseCharAt, 408544820)                              \
   V(_OneByteString, get:hashCode, OneByteString_getHashCode, 1111957093)       \
   V(_OneByteString, _substringUncheckedNative,                                 \
@@ -301,6 +302,7 @@
   V(_GrowableList, [], GrowableArrayGetIndexed, 1962926024)                    \
   V(_GrowableList, []=, GrowableArraySetIndexed, 457344024)                    \
   V(_StringBase, get:length, StringBaseLength, 784518792)                      \
+  V(_Double, unary-, DoubleFlipSignBit, 2107492213)
 
 #define GRAPH_INTRINSICS_LIST(V)                                               \
   GRAPH_CORE_INTRINSICS_LIST(V)                                                \
@@ -422,6 +424,19 @@
   V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 1781420082)         \
   V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 63633039)     \
   V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 2079107858)   \
+  V(Uint8List, ., Uint8ListFactory, 1844890525)                                \
+  V(Int8List, ., Int8ListFactory, 1802068996)                                  \
+  V(Uint16List, ., Uint16ListFactory, 1923962567)                              \
+  V(Int16List, ., Int16ListFactory, 2000007495)                                \
+  V(Uint32List, ., Uint32ListFactory, 1836019363)                              \
+  V(Int32List, ., Int32ListFactory, 442847136)                                 \
+  V(Uint64List, ., Uint64ListFactory, 196248223)                               \
+  V(Int64List, ., Int64ListFactory, 1668869084)                                \
+  V(Float32List, ., Float32ListFactory, 1367032554)                            \
+  V(Float64List, ., Float64ListFactory, 1886443347)                            \
+  V(Int32x4List, ., Int32x4ListFactory, 1409401969)                            \
+  V(Float32x4List, ., Float32x4ListFactory, 556438009)                         \
+  V(Float64x2List, ., Float64x2ListFactory, 1269752759)
 
 
 // A list of core function that should never be inlined.
@@ -495,6 +510,33 @@
 #endif  // defined(DART_NO_SNAPSHOT).
 
 
+// List of recognized list factories:
+// (factory-name-symbol, result-cid, fingerprint).
+#define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
+  V(_ListFactory, kArrayCid, 850375012)                                        \
+  V(_GrowableListWithData, kGrowableObjectArrayCid, 2094352700)                \
+  V(_GrowableListFactory, kGrowableObjectArrayCid, 1518848600)                 \
+  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.
+class FactoryRecognizer : public AllStatic {
+ public:
+  // Return kDynamicCid if factory is not recognized.
+  static intptr_t ResultCid(const Function& factory);
+};
+
 }  // namespace dart
 
 #endif  // VM_METHOD_RECOGNIZER_H_
diff --git a/runtime/vm/mirrors_api_impl.cc b/runtime/vm/mirrors_api_impl.cc
index 13b896c..4d0a348 100644
--- a/runtime/vm/mirrors_api_impl.cc
+++ b/runtime/vm/mirrors_api_impl.cc
@@ -30,7 +30,7 @@
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
   if (obj.IsType()) {
     const Class& cls = Class::Handle(Type::Cast(obj).type_class());
-    return Api::NewHandle(I, cls.UserVisibleName());
+    return Api::NewHandle(T, cls.UserVisibleName());
   } else {
     RETURN_TYPE_ERROR(Z, object, Class/Type);
   }
@@ -48,7 +48,7 @@
       RETURN_NULL_ERROR(str);
     }
     CHECK_CALLBACK_STATE(T);
-    return Api::NewHandle(I, String::New(str));
+    return Api::NewHandle(T, String::New(str));
   } else {
     RETURN_TYPE_ERROR(Z, object, Class/Type);
   }
@@ -85,7 +85,7 @@
     const Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());
     const Error& error = Error::Handle(Z, cls.EnsureIsFinalized(T));
     if (!error.IsNull()) {
-      return Api::NewHandle(I, error.raw());
+      return Api::NewHandle(T, error.raw());
     }
     const Array& func_array = Array::Handle(Z, cls.functions());
 
@@ -124,7 +124,7 @@
         "%s expects argument 'target' to be a class or library.",
         CURRENT_FUNC);
   }
-  return Api::NewHandle(I, Array::MakeArray(names));
+  return Api::NewHandle(T, Array::MakeArray(names));
 }
 
 
@@ -205,7 +205,7 @@
            func_kind == RawFunction::kConstructor);
   }
 #endif
-  return Api::NewHandle(I, func.raw());
+  return Api::NewHandle(T, func.raw());
 }
 
 
@@ -215,7 +215,7 @@
   if (func.IsNull()) {
     RETURN_TYPE_ERROR(Z, function, Function);
   }
-  return Api::NewHandle(I, func.UserVisibleName());
+  return Api::NewHandle(T, func.UserVisibleName());
 }
 
 
@@ -227,7 +227,7 @@
   }
   if (func.IsNonImplicitClosureFunction()) {
     RawFunction* parent_function = func.parent_function();
-    return Api::NewHandle(I, parent_function);
+    return Api::NewHandle(T, parent_function);
   }
   const Class& owner = Class::Handle(Z, func.Owner());
   ASSERT(!owner.IsNull());
@@ -240,9 +240,9 @@
       ASSERT(owner.IsDynamicClass() || owner.IsVoidClass());
     }
 #endif
-    return Api::NewHandle(I, owner.library());
+    return Api::NewHandle(T, owner.library());
   } else {
-    return Api::NewHandle(I, owner.RareType());
+    return Api::NewHandle(T, owner.RareType());
   }
 }
 
@@ -317,7 +317,7 @@
   }
   const String& name = String::Handle(Z, lib.name());
   ASSERT(!name.IsNull());
-  return Api::NewHandle(I, name.raw());
+  return Api::NewHandle(T, name.raw());
 }
 
 DART_EXPORT Dart_Handle Dart_LibraryGetClassNames(Dart_Handle library) {
@@ -347,7 +347,7 @@
       names.Add(name);
     }
   }
-  return Api::NewHandle(I, Array::MakeArray(names));
+  return Api::NewHandle(T, Array::MakeArray(names));
 }
 
 
@@ -363,7 +363,7 @@
   ASSERT(ClassFinalizer::AllClassesFinalized());
 
   RawFunction* rf = Closure::function(closure_obj);
-  return Api::NewHandle(I, rf);
+  return Api::NewHandle(T, rf);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index ce05529..8a546e4 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -22,7 +22,28 @@
 }
 
 
-DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) {
+class IsolateSaver {
+ public:
+  explicit IsolateSaver(Isolate* current_isolate)
+      : saved_isolate_(current_isolate) {
+    if (current_isolate != NULL) {
+      ASSERT(current_isolate == Isolate::Current());
+      Thread::ExitIsolate();
+    }
+  }
+  ~IsolateSaver() {
+    if (saved_isolate_ != NULL) {
+      Thread::EnterIsolate(saved_isolate_);
+    }
+  }
+ private:
+  Isolate* saved_isolate_;
+
+  DISALLOW_COPY_AND_ASSIGN(IsolateSaver);
+};
+
+
+static bool PostCObjectHelper(Dart_Port port_id, Dart_CObject* message) {
   uint8_t* buffer = NULL;
   ApiMessageWriter writer(&buffer, allocator);
   bool success = writer.WriteCMessage(message);
@@ -35,6 +56,23 @@
 }
 
 
+DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) {
+  return PostCObjectHelper(port_id, message);
+}
+
+
+DART_EXPORT bool Dart_PostInteger(Dart_Port port_id, int64_t message) {
+  if (Smi::IsValid(message)) {
+    return PortMap::PostMessage(new Message(
+        port_id, Smi::New(message), Message::kNormalPriority));
+  }
+  Dart_CObject cobj;
+  cobj.type = Dart_CObject_kInt64;
+  cobj.value.as_int64 = message;
+  return PostCObjectHelper(port_id, &cobj);
+}
+
+
 DART_EXPORT Dart_Port Dart_NewNativePort(const char* name,
                                          Dart_NativeMessageHandler handler,
                                          bool handle_concurrently) {
@@ -48,7 +86,6 @@
   }
   // Start the native port without a current isolate.
   IsolateSaver saver(Isolate::Current());
-  Thread::ExitIsolate();
 
   NativeMessageHandler* nmh = new NativeMessageHandler(name, handler);
   Dart_Port port_id = PortMap::CreatePort(nmh);
@@ -60,7 +97,6 @@
 DART_EXPORT bool Dart_CloseNativePort(Dart_Port native_port_id) {
   // Close the native port without a current isolate.
   IsolateSaver saver(Isolate::Current());
-  Thread::ExitIsolate();
 
   // TODO(turnidge): Check that the port is native before trying to close.
   return PortMap::ClosePort(native_port_id);
@@ -69,26 +105,25 @@
 
 // --- Verification tools ---
 
-static void CompileAll(Isolate* isolate, Dart_Handle* result) {
-  ASSERT(isolate != NULL);
-  const Error& error =
-      Error::Handle(isolate->current_zone(), Library::CompileAll());
+static void CompileAll(Thread* thread, Dart_Handle* result) {
+  ASSERT(thread != NULL);
+  const Error& error = Error::Handle(thread->zone(), Library::CompileAll());
   if (error.IsNull()) {
     *result = Api::Success();
   } else {
-    *result = Api::NewHandle(isolate, error.raw());
+    *result = Api::NewHandle(thread, error.raw());
   }
 }
 
 
 DART_EXPORT Dart_Handle Dart_CompileAll() {
   DARTSCOPE(Thread::Current());
-  Dart_Handle result = Api::CheckAndFinalizePendingClasses(I);
+  Dart_Handle result = Api::CheckAndFinalizePendingClasses(T);
   if (::Dart_IsError(result)) {
     return result;
   }
   CHECK_CALLBACK_STATE(T);
-  CompileAll(I, &result);
+  CompileAll(T, &result);
   return result;
 }
 
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index 5d5a596..92a99e8 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -36,7 +36,7 @@
   Dart_EnterScope();  // Enter a new Dart API scope as we invoke API entries.
   Dart_NativeEntryResolver resolver = library.native_entry_resolver();
   Dart_NativeFunction native_function =
-      resolver(Api::NewHandle(Isolate::Current(), function_name.raw()),
+      resolver(Api::NewHandle(Thread::Current(), function_name.raw()),
                number_of_arguments, auto_setup_scope);
   Dart_ExitScope();  // Exit the Dart API scope.
   return reinterpret_cast<NativeFunction>(native_function);
@@ -98,8 +98,8 @@
 
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
-  ApiLocalScope* current_top_scope = state->top_scope();
-  ApiLocalScope* scope = state->reusable_scope();
+  ApiLocalScope* current_top_scope = thread->api_top_scope();
+  ApiLocalScope* scope = thread->api_reusable_scope();
   TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func));
   if (scope == NULL) {
     scope = new ApiLocalScope(current_top_scope,
@@ -109,19 +109,19 @@
     scope->Reinit(thread,
                   current_top_scope,
                   thread->top_exit_frame_info());
-    state->set_reusable_scope(NULL);
+    thread->set_api_reusable_scope(NULL);
   }
-  state->set_top_scope(scope);  // New scope is now the top scope.
+  thread->set_api_top_scope(scope);  // New scope is now the top scope.
 
   func(args);
 
   ASSERT(current_top_scope == scope->previous());
-  state->set_top_scope(current_top_scope);  // Reset top scope to previous.
-  if (state->reusable_scope() == NULL) {
+  thread->set_api_top_scope(current_top_scope);  // Reset top scope to previous.
+  if (thread->api_reusable_scope() == NULL) {
     scope->Reset(thread);  // Reset the old scope which we just exited.
-    state->set_reusable_scope(scope);
+    thread->set_api_reusable_scope(scope);
   } else {
-    ASSERT(state->reusable_scope() != scope);
+    ASSERT(thread->api_reusable_scope() != scope);
     delete scope;
   }
   DEOPTIMIZE_ALOT;
@@ -129,33 +129,17 @@
 }
 
 
-static bool IsNativeKeyword(const TokenStream::Iterator& it) {
-  return Token::IsIdentifier(it.CurrentTokenKind()) &&
-      (it.CurrentLiteral() == Symbols::Native().raw());
-}
-
-
 static NativeFunction ResolveNativeFunction(Zone* zone,
                                             const Function& func,
                                             bool* is_bootstrap_native) {
-  const Script& script = Script::Handle(zone, func.script());
   const Class& cls = Class::Handle(zone, func.Owner());
   const Library& library = Library::Handle(zone, cls.library());
 
   *is_bootstrap_native =
       Bootstrap::IsBootstapResolver(library.native_entry_resolver());
 
-  TokenStream::Iterator it(TokenStream::Handle(zone, script.tokens()),
-                           func.token_pos());
-
-  const intptr_t end_pos = func.end_token_pos();
-  while (!IsNativeKeyword(it) && it.CurrentPosition() <= end_pos) {
-    it.Advance();
-  }
-  ASSERT(IsNativeKeyword(it));
-  it.Advance();
-  ASSERT(it.CurrentTokenKind() == Token::kSTRING);
-  const String& native_name = String::Handle(it.CurrentLiteral());
+  const String& native_name = String::Handle(zone, func.native_name());
+  ASSERT(!native_name.IsNull());
 
   const int num_params = NativeArguments::ParameterCountForResolution(func);
   bool auto_setup_scope = true;
@@ -234,7 +218,7 @@
 
     const intptr_t argc_tag = NativeArguments::ComputeArgcTag(func);
     const bool is_leaf_call =
-      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
+        (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
 
     call_through_wrapper = !is_bootstrap_native && !is_leaf_call;
 
diff --git a/runtime/vm/native_message_handler.cc b/runtime/vm/native_message_handler.cc
index 8f8d7a6..7779e95 100644
--- a/runtime/vm/native_message_handler.cc
+++ b/runtime/vm/native_message_handler.cc
@@ -42,8 +42,9 @@
   // All allocation of objects for decoding the message is done in the
   // zone associated with this scope.
   ApiNativeScope scope;
-  ApiMessageReader reader(message->data(), message->len());
-  Dart_CObject* object = reader.ReadMessage();
+  Dart_CObject* object;
+  ApiMessageReader reader(message);
+  object = reader.ReadMessage();
   (*func())(message->dest_port(), object);
   delete message;
   return kOK;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index e0247e6..730d560 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -11,9 +11,7 @@
 #include "vm/bit_vector.h"
 #include "vm/bootstrap.h"
 #include "vm/class_finalizer.h"
-#include "vm/code_generator.h"
 #include "vm/code_observers.h"
-#include "vm/code_patcher.h"
 #include "vm/compiler.h"
 #include "vm/compiler_stats.h"
 #include "vm/dart.h"
@@ -25,12 +23,9 @@
 #include "vm/disassembler.h"
 #include "vm/double_conversion.h"
 #include "vm/exceptions.h"
-#include "vm/flow_graph_builder.h"
-#include "vm/flow_graph_compiler.h"
 #include "vm/growable_array.h"
 #include "vm/hash_table.h"
 #include "vm/heap.h"
-#include "vm/intermediate_language.h"
 #include "vm/intrinsifier.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
@@ -42,6 +37,7 @@
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
 #include "vm/tags.h"
+#include "vm/thread_registry.h"
 #include "vm/timer.h"
 #include "vm/unicode.h"
 #include "vm/verified_memory.h"
@@ -72,17 +68,19 @@
 DECLARE_FLAG(charp, coverage_dir);
 DECLARE_FLAG(bool, load_deferred_eagerly);
 DECLARE_FLAG(bool, show_invisible_frames);
-DECLARE_FLAG(bool, trace_compiler);
 DECLARE_FLAG(bool, trace_deoptimization);
 DECLARE_FLAG(bool, trace_deoptimization_verbose);
 DECLARE_FLAG(bool, write_protect_code);
 
 
-static const char* kGetterPrefix = "get:";
+static const char* const kGetterPrefix = "get:";
 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix);
-static const char* kSetterPrefix = "set:";
+static const char* const kSetterPrefix = "set:";
 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix);
 
+// A cache of VM heap allocated preinitialized empty ic data entry arrays.
+RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount];
+
 cpp_vtable Object::handle_vtable_ = 0;
 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 };
 cpp_vtable Smi::handle_vtable_ = 0;
@@ -116,14 +114,15 @@
 Smi* Object::smi_illegal_cid_ = NULL;
 LanguageError* Object::snapshot_writer_error_ = NULL;
 LanguageError* Object::branch_offset_error_ = NULL;
+LanguageError* Object::speculative_inlining_error_ = NULL;
 Array* Object::vm_isolate_snapshot_object_table_ = NULL;
+Type* Object::dynamic_type_ = NULL;
+Type* Object::void_type_ = NULL;
 
 RawObject* Object::null_ = reinterpret_cast<RawObject*>(RAW_NULL);
 RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::void_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
-RawType* Object::dynamic_type_ = reinterpret_cast<RawType*>(RAW_NULL);
-RawType* Object::void_type_ = reinterpret_cast<RawType*>(RAW_NULL);
 RawClass* Object::unresolved_class_class_ =
     reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
@@ -489,7 +488,10 @@
   smi_illegal_cid_ = Smi::ReadOnlyHandle();
   snapshot_writer_error_ = LanguageError::ReadOnlyHandle();
   branch_offset_error_ = LanguageError::ReadOnlyHandle();
+  speculative_inlining_error_ = LanguageError::ReadOnlyHandle();
   vm_isolate_snapshot_object_table_ = Array::ReadOnlyHandle();
+  dynamic_type_ = Type::ReadOnlyHandle();
+  void_type_ = Type::ReadOnlyHandle();
 
   *null_object_ = Object::null();
   *null_array_ = Array::null();
@@ -661,6 +663,11 @@
   cls.set_type_arguments_field_offset(Array::type_arguments_offset());
   cls.set_num_type_arguments(1);
   cls.set_num_own_type_arguments(1);
+  cls = Class::New<GrowableObjectArray>();
+  isolate->object_store()->set_growable_object_array_class(cls);
+  cls.set_type_arguments_field_offset(
+      GrowableObjectArray::type_arguments_offset());
+  cls.set_num_type_arguments(1);
   cls = Class::NewStringClass(kOneByteStringCid);
   isolate->object_store()->set_one_byte_string_class(cls);
   cls = Class::NewStringClass(kTwoByteStringCid);
@@ -803,10 +810,10 @@
   cls.set_is_finalized();
 
   cls = dynamic_class_;
-  dynamic_type_ = Type::NewNonParameterizedType(cls);
+  *dynamic_type_ = Type::NewNonParameterizedType(cls);
 
   cls = void_class_;
-  void_type_ = Type::NewNonParameterizedType(cls);
+  *void_type_ = Type::NewNonParameterizedType(cls);
 
   // Allocate and initialize singleton true and false boolean objects.
   cls = Class::New<Bool>();
@@ -825,6 +832,10 @@
   *branch_offset_error_ = LanguageError::New(error_str,
                                              Report::kBailout,
                                              Heap::kOld);
+  error_str = String::New("Speculative inlining failed", Heap::kOld);
+  *speculative_inlining_error_ = LanguageError::New(error_str,
+                                                    Report::kBailout,
+                                                    Heap::kOld);
 
   ASSERT(!null_object_->IsSmi());
   ASSERT(!null_array_->IsSmi());
@@ -864,6 +875,8 @@
   ASSERT(snapshot_writer_error_->IsLanguageError());
   ASSERT(!branch_offset_error_->IsSmi());
   ASSERT(branch_offset_error_->IsLanguageError());
+  ASSERT(!speculative_inlining_error_->IsSmi());
+  ASSERT(speculative_inlining_error_->IsLanguageError());
   ASSERT(!vm_isolate_snapshot_object_table_->IsSmi());
   ASSERT(vm_isolate_snapshot_object_table_->IsArray());
 }
@@ -901,7 +914,7 @@
 
   // Allocate the parameter arrays for method extractor types and names.
   *extractor_parameter_types_ = Array::New(1, Heap::kOld);
-  extractor_parameter_types_->SetAt(0, Type::Handle(Type::DynamicType()));
+  extractor_parameter_types_->SetAt(0, Object::dynamic_type());
   *extractor_parameter_names_ = Array::New(1, Heap::kOld);
   extractor_parameter_names_->SetAt(0, Symbols::This());
 
@@ -955,7 +968,8 @@
 
   {
     ASSERT(isolate == Dart::vm_isolate());
-    WritableVMIsolateScope scope(Thread::Current());
+    bool include_code_pages = !Dart::IsRunningPrecompiledCode();
+    WritableVMIsolateScope scope(Thread::Current(), include_code_pages);
     PremarkingVisitor premarker(isolate);
     ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0);
     isolate->heap()->IterateOldObjects(&premarker);
@@ -1560,10 +1574,10 @@
 
 #define ADD_SET_FIELD(clazz)                                                   \
   field_name = Symbols::New("cid"#clazz);                                      \
-  field = Field::New(field_name, true, false, true, false, cls, 0);            \
+  field = Field::New(field_name, true, false, true, false, cls,                \
+      Type::Handle(Type::IntType()), 0);                                       \
   value = Smi::New(k##clazz##Cid);                                             \
   field.SetStaticValue(value, true);                                           \
-  field.set_type(Type::Handle(Type::IntType()));                               \
   cls.AddField(field);                                                         \
 
   CLASS_LIST_WITH_NULL(ADD_SET_FIELD)
@@ -1765,22 +1779,10 @@
                               intptr_t class_id,
                               intptr_t size,
                               bool is_vm_object) {
-  const uword break_instruction_value = Assembler::GetBreakInstructionFiller();
-  const uword null_value = reinterpret_cast<uword>(null_);
-  const bool is_instructions = class_id == kInstructionsCid;
-  uword initial_value =
-      is_instructions ? break_instruction_value : null_value;
+  uword initial_value = (class_id == kInstructionsCid)
+      ? Assembler::GetBreakInstructionFiller() : reinterpret_cast<uword>(null_);
   uword cur = address;
   uword end = address + size;
-  if (is_instructions) {
-    // Fill the header with null. The remainder of the Instructions object will
-    // be filled with the break_instruction_value.
-    uword header_end = address + Instructions::HeaderSize();
-    while (cur < header_end) {
-      *reinterpret_cast<uword*>(cur) = null_value;
-      cur += kWordSize;
-    }
-  }
   while (cur < end) {
     *reinterpret_cast<uword*>(cur) = initial_value;
     cur += kWordSize;
@@ -1827,7 +1829,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   // New space allocation allowed only in mutator thread (Dart thread);
-  ASSERT(isolate->MutatorThreadIsCurrentThread() || (space != Heap::kNew));
+  ASSERT(thread->IsMutatorThread() || (space != Heap::kNew));
   ASSERT(thread->no_callback_scope_depth() == 0);
   Heap* heap = isolate->heap();
 
@@ -1848,7 +1850,7 @@
   }
   const Class& cls = Class::Handle(class_table->At(cls_id));
   if (cls.TraceAllocation(isolate)) {
-    Profiler::RecordAllocation(thread, cls_id);
+    Profiler::SampleAllocation(thread, cls_id);
   }
   NoSafepointScope no_safepoint;
   InitializeObject(address, cls_id, size, (isolate == Dart::vm_isolate()));
@@ -2168,8 +2170,8 @@
   ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->functions_, value.raw());
   const intptr_t len = value.Length();
-  ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld));
   if (len >= kFunctionLookupHashTreshold) {
+    ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld));
     Function& func = Function::Handle();
     for (intptr_t i = 0; i < len; ++i) {
       func ^= value.At(i);
@@ -2177,8 +2179,8 @@
       ASSERT(func.Owner() == raw());
       set.Insert(func);
     }
+    StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
   }
-  StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
 }
 
 
@@ -2204,6 +2206,7 @@
 void Class::RemoveFunction(const Function& function) const {
   const Array& arr = Array::Handle(functions());
   StorePointer(&raw_ptr()->functions_, Object::empty_array().raw());
+  StorePointer(&raw_ptr()->functions_hash_table_, Array::null());
   Function& entry = Function::Handle();
   for (intptr_t i = 0; i < arr.Length(); i++) {
     entry ^= arr.At(i);
@@ -2214,29 +2217,6 @@
 }
 
 
-intptr_t Class::FindFunctionIndex(const Function& needle) const {
-  Thread* thread = Thread::Current();
-  if (EnsureIsFinalized(thread) != Error::null()) {
-    return -1;
-  }
-  REUSABLE_ARRAY_HANDLESCOPE(thread);
-  REUSABLE_FUNCTION_HANDLESCOPE(thread);
-  Array& funcs = thread->ArrayHandle();
-  Function& function = thread->FunctionHandle();
-  funcs ^= functions();
-  ASSERT(!funcs.IsNull());
-  const intptr_t len = funcs.Length();
-  for (intptr_t i = 0; i < len; i++) {
-    function ^= funcs.At(i);
-    if (function.raw() == needle.raw()) {
-      return i;
-    }
-  }
-  // No function found.
-  return -1;
-}
-
-
 RawFunction* Class::FunctionFromIndex(intptr_t idx) const {
   const Array& funcs = Array::Handle(functions());
   if ((idx < 0) || (idx >= funcs.Length())) {
@@ -2325,7 +2305,6 @@
 }
 
 
-
 RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const {
   Thread* thread = Thread::Current();
   REUSABLE_ARRAY_HANDLESCOPE(thread);
@@ -2341,86 +2320,6 @@
 }
 
 
-void Class::set_closures(const GrowableObjectArray& value) const {
-  StorePointer(&raw_ptr()->closure_functions_, value.raw());
-}
-
-
-void Class::AddClosureFunction(const Function& function) const {
-  GrowableObjectArray& closures =
-      GrowableObjectArray::Handle(raw_ptr()->closure_functions_);
-  if (closures.IsNull()) {
-    closures = GrowableObjectArray::New(4, Heap::kOld);
-    StorePointer(&raw_ptr()->closure_functions_, closures.raw());
-  }
-  ASSERT(function.IsNonImplicitClosureFunction());
-  ASSERT(function.Owner() == this->raw());
-  closures.Add(function, Heap::kOld);
-}
-
-
-// Lookup the innermost closure function that contains token at token_pos.
-RawFunction* Class::LookupClosureFunction(intptr_t token_pos) const {
-  if (raw_ptr()->closure_functions_ == GrowableObjectArray::null()) {
-    return Function::null();
-  }
-  const GrowableObjectArray& closures =
-      GrowableObjectArray::Handle(raw_ptr()->closure_functions_);
-  Function& closure = Function::Handle();
-  intptr_t num_closures = closures.Length();
-  intptr_t best_fit_token_pos = -1;
-  intptr_t best_fit_index = -1;
-  for (intptr_t i = 0; i < num_closures; i++) {
-    closure ^= closures.At(i);
-    ASSERT(!closure.IsNull());
-    if ((closure.token_pos() <= token_pos) &&
-        (token_pos <= closure.end_token_pos()) &&
-        (best_fit_token_pos < closure.token_pos())) {
-      best_fit_index = i;
-      best_fit_token_pos = closure.token_pos();
-    }
-  }
-  closure = Function::null();
-  if (best_fit_index >= 0) {
-    closure ^= closures.At(best_fit_index);
-  }
-  return closure.raw();
-}
-
-intptr_t Class::FindClosureIndex(const Function& needle) const {
-  if (closures() == GrowableObjectArray::null()) {
-    return -1;
-  }
-  Thread* thread = Thread::Current();
-  const GrowableObjectArray& closures_array =
-      GrowableObjectArray::Handle(thread->zone(), closures());
-  REUSABLE_FUNCTION_HANDLESCOPE(thread);
-  Function& closure = thread->FunctionHandle();
-  intptr_t num_closures = closures_array.Length();
-  for (intptr_t i = 0; i < num_closures; i++) {
-    closure ^= closures_array.At(i);
-    ASSERT(!closure.IsNull());
-    if (closure.raw() == needle.raw()) {
-      return i;
-    }
-  }
-  return -1;
-}
-
-
-RawFunction* Class::ClosureFunctionFromIndex(intptr_t idx) const {
-  const GrowableObjectArray& closures_array =
-      GrowableObjectArray::Handle(closures());
-  if ((idx < 0) || (idx >= closures_array.Length())) {
-    return Function::null();
-  }
-  Function& func = Function::Handle();
-  func ^= closures_array.At(idx);
-  ASSERT(!func.IsNull());
-  return func.raw();
-}
-
-
 void Class::set_signature_function(const Function& value) const {
   ASSERT(value.IsClosureFunction() || value.IsSignatureFunction());
   StorePointer(&raw_ptr()->signature_function_, value.raw());
@@ -2447,6 +2346,12 @@
     ClassFinalizer::ApplyMixinType(*this);
   }
   if (type_parameters() == TypeArguments::null()) {
+    const intptr_t cid = id();
+    if ((cid == kArrayCid) ||
+        (cid == kImmutableArrayCid) ||
+        (cid == kGrowableObjectArrayCid)) {
+      return 1;  // List's type parameter may not have been parsed yet.
+    }
     return 0;
   }
   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread);
@@ -2732,7 +2637,7 @@
                     false,  // Not external.
                     false,  // Not native.
                     *this,
-                    0));  // No token position.
+                    0));    // token_pos
   ArgumentsDescriptor desc(args_desc);
   invocation.set_num_fixed_parameters(desc.PositionalCount());
   invocation.SetNumOptionalParameters(desc.NamedCount(),
@@ -2742,12 +2647,12 @@
   invocation.set_parameter_names(Array::Handle(Array::New(desc.Count(),
                                                           Heap::kOld)));
   // Receiver.
-  invocation.SetParameterTypeAt(0, Type::Handle(Type::DynamicType()));
+  invocation.SetParameterTypeAt(0, Object::dynamic_type());
   invocation.SetParameterNameAt(0, Symbols::This());
   // Remaining positional parameters.
   intptr_t i = 1;
   for (; i < desc.PositionalCount(); i++) {
-    invocation.SetParameterTypeAt(i, Type::Handle(Type::DynamicType()));
+    invocation.SetParameterTypeAt(i, Object::dynamic_type());
     char name[64];
     OS::SNPrint(name, 64, ":p%" Pd, i);
     invocation.SetParameterNameAt(i, String::Handle(Symbols::New(name)));
@@ -2755,11 +2660,11 @@
 
   // Named parameters.
   for (; i < desc.Count(); i++) {
-    invocation.SetParameterTypeAt(i, Type::Handle(Type::DynamicType()));
+    invocation.SetParameterTypeAt(i, Object::dynamic_type());
     intptr_t index = i - desc.PositionalCount();
     invocation.SetParameterNameAt(i, String::Handle(desc.NameAt(index)));
   }
-  invocation.set_result_type(Type::Handle(Type::DynamicType()));
+  invocation.set_result_type(Object::dynamic_type());
   invocation.set_is_debuggable(false);
   invocation.set_is_visible(false);
   invocation.set_is_reflectable(false);
@@ -2769,6 +2674,60 @@
 }
 
 
+// Method extractors are used to create implicit closures from methods.
+// When an expression obj.M is evaluated for the first time and receiver obj
+// does not have a getter called M but has a method called M then an extractor
+// is created and injected as a getter (under the name get:M) into the class
+// owning method M.
+RawFunction* Function::CreateMethodExtractor(const String& getter_name) const {
+  ASSERT(Field::IsGetterName(getter_name));
+  const Function& closure_function =
+      Function::Handle(ImplicitClosureFunction());
+
+  const Class& owner = Class::Handle(closure_function.Owner());
+  Function& extractor = Function::Handle(
+    Function::New(String::Handle(Symbols::New(getter_name)),
+                  RawFunction::kMethodExtractor,
+                  false,  // Not static.
+                  false,  // Not const.
+                  false,  // Not abstract.
+                  false,  // Not external.
+                  false,  // Not native.
+                  owner,
+                  0));    // token_pos
+
+  // Initialize signature: receiver is a single fixed parameter.
+  const intptr_t kNumParameters = 1;
+  extractor.set_num_fixed_parameters(kNumParameters);
+  extractor.SetNumOptionalParameters(0, 0);
+  extractor.set_parameter_types(Object::extractor_parameter_types());
+  extractor.set_parameter_names(Object::extractor_parameter_names());
+  extractor.set_result_type(Object::dynamic_type());
+
+  extractor.set_extracted_method_closure(closure_function);
+  extractor.set_is_debuggable(false);
+  extractor.set_is_visible(false);
+
+  owner.AddFunction(extractor);
+
+  return extractor.raw();
+}
+
+
+RawFunction* Function::GetMethodExtractor(const String& getter_name) const {
+  ASSERT(Field::IsGetterName(getter_name));
+  const Function& closure_function =
+      Function::Handle(ImplicitClosureFunction());
+  const Class& owner = Class::Handle(closure_function.Owner());
+  Function& result = Function::Handle(owner.LookupDynamicFunction(getter_name));
+  if (result.IsNull()) {
+    result ^= CreateMethodExtractor(getter_name);
+  }
+  ASSERT(result.kind() == RawFunction::kMethodExtractor);
+  return result.raw();
+}
+
+
 RawArray* Class::invocation_dispatcher_cache() const {
   return raw_ptr()->invocation_dispatcher_cache_;
 }
@@ -2780,6 +2739,10 @@
 
 
 void Class::Finalize() const {
+  ASSERT(Thread::Current()->IsMutatorThread());
+  // Even if all regular classes are prefinalized (precompilation), signature
+  // classes may be added later when we encounter local functions.
+  ASSERT(IsSignatureClass() || !Isolate::Current()->all_classes_finalized());
   ASSERT(!is_finalized());
   // Prefinalized classes have a VM internal representation and no Dart fields.
   // Their instance size  is precomputed and field offsets are known.
@@ -2821,25 +2784,43 @@
     }
   }
 
+  virtual void IncrementInvalidationGen() {
+    Isolate::Current()->IncrCHAInvalidationGen();
+  }
+
  private:
   const Class& cls_;
   DISALLOW_COPY_AND_ASSIGN(CHACodeArray);
 };
 
 
+#if defined(DEBUG)
+static bool IsMutatorOrAtSafepoint() {
+  Thread* thread = Thread::Current();
+  return thread->IsMutatorThread() ||
+         thread->isolate()->thread_registry()->AtSafepoint();
+}
+#endif
+
+
 void Class::RegisterCHACode(const Code& code) {
   if (FLAG_trace_cha) {
-    THR_Print("RegisterCHACode %s class %s\n",
+    THR_Print("RegisterCHACode '%s' depends on class '%s'\n",
         Function::Handle(code.function()).ToQualifiedCString(), ToCString());
   }
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   ASSERT(code.is_optimized());
   CHACodeArray a(*this);
   a.Register(code);
 }
 
 
-void Class::DisableCHAOptimizedCode() {
+void Class::DisableCHAOptimizedCode(const Class& subclass) {
+  ASSERT(Thread::Current()->IsMutatorThread());
   CHACodeArray a(*this);
+  if (FLAG_trace_deoptimization && a.HasCodes()) {
+    THR_Print("Adding subclass %s\n", subclass.ToCString());
+  }
   a.DisableCode();
 }
 
@@ -2873,8 +2854,8 @@
   // Shared handles used during the iteration.
   String& member_name = String::Handle();
 
-  const PatchClass& patch_class =
-      PatchClass::Handle(PatchClass::New(*this, patch));
+  const PatchClass& patch_class = PatchClass::Handle(
+      PatchClass::New(*this, Script::Handle(patch.script())));
 
   Array& orig_list = Array::Handle(functions());
   intptr_t orig_len = orig_list.Length();
@@ -2976,8 +2957,10 @@
   SetFields(new_list);
 
   // The functions and fields in the patch class are no longer needed.
+  // The patch class itself is also no longer needed.
   patch.SetFunctions(Object::empty_array());
   patch.SetFields(Object::empty_array());
+  Library::Handle(patch.library()).RemovePatchClass(patch);
   return true;
 }
 
@@ -3019,11 +3002,11 @@
   const Library& lib = Library::Handle(cls.library());
   ASSERT(!lib.IsNull());
   const String& lib_key = String::Handle(lib.private_key());
-  script.Tokenize(lib_key);
+  script.Tokenize(lib_key, false);
 
   const Function& func = Function::Handle(
        Function::NewEvalFunction(cls, script, is_static));
-  func.set_result_type(Type::Handle(Type::DynamicType()));
+  func.set_result_type(Object::dynamic_type());
   const intptr_t num_implicit_params = is_static ? 0 : 1;
   func.set_num_fixed_parameters(num_implicit_params + param_names.Length());
   func.SetNumOptionalParameters(0, true);
@@ -3044,12 +3027,12 @@
 
 
 // Ensure that top level parsing of the class has been done.
-// TODO(24109): Migrate interface to Thread*.
 RawError* Class::EnsureIsFinalized(Thread* thread) const {
   // Finalized classes have already been parsed.
   if (is_finalized()) {
     return Error::null();
   }
+  ASSERT(thread->IsMutatorThread());
   ASSERT(thread != NULL);
   const Error& error = Error::Handle(
       thread->zone(), Compiler::CompileClass(*this));
@@ -3102,46 +3085,6 @@
 }
 
 
-intptr_t Class::FindFieldIndex(const Field& needle) const {
-  Thread* thread = Thread::Current();
-  if (EnsureIsFinalized(thread) != Error::null()) {
-    return -1;
-  }
-  REUSABLE_ARRAY_HANDLESCOPE(thread);
-  REUSABLE_FIELD_HANDLESCOPE(thread);
-  REUSABLE_STRING_HANDLESCOPE(thread);
-  Array& fields_array = thread->ArrayHandle();
-  Field& field = thread->FieldHandle();
-  String& field_name = thread->StringHandle();
-  fields_array ^= fields();
-  ASSERT(!fields_array.IsNull());
-  String& needle_name = String::Handle(thread->zone());
-  needle_name ^= needle.name();
-  const intptr_t len = fields_array.Length();
-  for (intptr_t i = 0; i < len; i++) {
-    field ^= fields_array.At(i);
-    field_name ^= field.name();
-    if (field_name.Equals(needle_name)) {
-      return i;
-    }
-  }
-  // No field found.
-  return -1;
-}
-
-
-RawField* Class::FieldFromIndex(intptr_t idx) const {
-  const Array& flds = Array::Handle(fields());
-  if ((idx < 0) || (idx >= flds.Length())) {
-    return Field::null();
-  }
-  Field& field = Field::Handle();
-  field ^= flds.At(idx);
-  ASSERT(!field.IsNull());
-  return field.raw();
-}
-
-
 template <class FakeInstance>
 RawClass* Class::New(intptr_t index) {
   ASSERT(Object::class_class() != Class::null());
@@ -3506,7 +3449,7 @@
 
 
 void Class::set_token_pos(intptr_t token_pos) const {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -3593,8 +3536,8 @@
 }
 
 
-void Class::set_is_allocated() const {
-  set_state_bits(IsAllocatedBit::update(true, raw_ptr()->state_bits_));
+void Class::set_is_allocated(bool value) const {
+  set_state_bits(IsAllocatedBit::update(value, raw_ptr()->state_bits_));
 }
 
 
@@ -3605,6 +3548,14 @@
 }
 
 
+void Class::ResetFinalization() const {
+  ASSERT(IsTopLevel());
+  set_state_bits(ClassFinalizedBits::update(RawClass::kAllocated,
+                                            raw_ptr()->state_bits_));
+  set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_));
+}
+
+
 void Class::set_is_prefinalized() const {
   ASSERT(!is_finalized());
   set_state_bits(ClassFinalizedBits::update(RawClass::kPreFinalized,
@@ -3639,9 +3590,9 @@
 }
 
 
-void Class::set_patch_class(const Class& cls) const {
-  ASSERT(patch_class() == Class::null());
-  StorePointer(&raw_ptr()->patch_class_, cls.raw());
+RawClass* Class::GetPatchClass() const {
+  const Library& lib = Library::Handle(library());
+  return lib.GetPatchClass(String::Handle(Name()));
 }
 
 
@@ -3688,7 +3639,7 @@
 
 
 RawType* Class::CanonicalType() const {
-  if (NumTypeArguments() == 0) {
+  if (!IsGeneric()) {
     return reinterpret_cast<RawType*>(raw_ptr()->canonical_types_);
   }
   Array& types = Array::Handle();
@@ -3702,7 +3653,7 @@
 
 void Class::SetCanonicalType(const Type& type) const {
   ASSERT(type.IsCanonical());
-  if (NumTypeArguments() == 0) {
+  if (!IsGeneric()) {
     ASSERT((canonical_types() == Object::null()) ||
            (canonical_types() == type.raw()));  // Set during own finalization.
     set_canonical_types(type);
@@ -3845,11 +3796,11 @@
     }
     // Check for reflexivity.
     if (thsi.raw() == other.raw()) {
-      const intptr_t num_type_args = thsi.NumTypeArguments();
-      if (num_type_args == 0) {
+      const intptr_t num_type_params = thsi.NumTypeParameters();
+      if (num_type_params == 0) {
         return true;
       }
-      const intptr_t num_type_params = thsi.NumTypeParameters();
+      const intptr_t num_type_args = thsi.NumTypeArguments();
       const intptr_t from_index = num_type_args - num_type_params;
       // Since we do not truncate the type argument vector of a subclass (see
       // below), we only check a subvector of the proper length.
@@ -3925,6 +3876,12 @@
       if (!interface.IsFinalized()) {
         // We may be checking bounds at finalization time and can encounter
         // a still unfinalized interface.
+        if (interface.IsBeingFinalized()) {
+          // Interface is part of a still unfinalized recursive type graph.
+          // Skip it. The caller will create a bounded type to be checked at
+          // runtime if this type test returns false at compile time.
+          continue;
+        }
         ClassFinalizer::FinalizeType(
             thsi, interface, ClassFinalizer::kCanonicalize);
         interfaces.SetAt(i, interface);
@@ -4223,33 +4180,6 @@
 }
 
 
-RawFunction* Class::LookupFunctionAtToken(intptr_t token_pos) const {
-  // TODO(hausner): we can shortcut the negative case if we knew the
-  // beginning and end token position of the class.
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  if (EnsureIsFinalized(thread) != Error::null()) {
-    return Function::null();
-  }
-  Function& func = Function::Handle(zone);
-  func = LookupClosureFunction(token_pos);
-  if (!func.IsNull()) {
-    return func.raw();
-  }
-  Array& funcs = Array::Handle(zone, functions());
-  intptr_t len = funcs.Length();
-  for (intptr_t i = 0; i < len; i++) {
-    func ^= funcs.At(i);
-    if ((func.token_pos() <= token_pos) &&
-        (token_pos <= func.end_token_pos())) {
-      return func.raw();
-    }
-  }
-  // No function found.
-  return Function::null();
-}
-
-
 RawField* Class::LookupInstanceField(const String& name) const {
   return LookupField(name, kInstance);
 }
@@ -4455,7 +4385,7 @@
 
 
 void UnresolvedClass::set_token_pos(intptr_t token_pos) const {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -5268,10 +5198,21 @@
 
 
 RawPatchClass* PatchClass::New(const Class& patched_class,
-                               const Class& source_class) {
+                               const Class& origin_class) {
   const PatchClass& result = PatchClass::Handle(PatchClass::New());
   result.set_patched_class(patched_class);
-  result.set_source_class(source_class);
+  result.set_origin_class(origin_class);
+  result.set_script(Script::Handle(origin_class.script()));
+  return result.raw();
+}
+
+
+RawPatchClass* PatchClass::New(const Class& patched_class,
+                               const Script& script) {
+  const PatchClass& result = PatchClass::Handle(PatchClass::New());
+  result.set_patched_class(patched_class);
+  result.set_origin_class(patched_class);
+  result.set_script(script);
   return result.raw();
 }
 
@@ -5285,37 +5226,56 @@
 }
 
 
-RawScript* PatchClass::Script() const {
-  const Class& source_class = Class::Handle(this->source_class());
-  return source_class.script();
-}
-
-
 void PatchClass::set_patched_class(const Class& value) const {
   StorePointer(&raw_ptr()->patched_class_, value.raw());
 }
 
 
-void PatchClass::set_source_class(const Class& value) const {
-  StorePointer(&raw_ptr()->source_class_, value.raw());
+void PatchClass::set_origin_class(const Class& value) const {
+  StorePointer(&raw_ptr()->origin_class_, value.raw());
+}
+
+
+void PatchClass::set_script(const Script& value) const {
+  StorePointer(&raw_ptr()->script_, value.raw());
 }
 
 
 bool Function::HasBreakpoint() const {
-  return Isolate::Current()->debugger()->HasBreakpoint(*this);
+  Thread* thread = Thread::Current();
+  return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone());
+}
+
+
+void Function::InstallOptimizedCode(const Code& code, bool is_osr) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
+  // We may not have previous code if 'always_optimize' is set.
+  if (!is_osr && HasCode()) {
+    Code::Handle(CurrentCode()).DisableDartCode();
+  }
+  AttachCode(code);
 }
 
 
 void Function::SetInstructions(const Code& value) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
+  SetInstructionsSafe(value);
+}
+
+
+void Function::SetInstructionsSafe(const Code& value) const {
   StorePointer(&raw_ptr()->code_, value.raw());
   StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint());
 }
 
+
 void Function::AttachCode(const Code& value) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
+  // Finish setting up code before activating it.
+  value.set_owner(*this);
   SetInstructions(value);
   ASSERT(Function::Handle(value.function()).IsNull() ||
-    (value.function() == this->raw()));
-  value.set_owner(*this);
+      (value.function() == this->raw()));
 }
 
 
@@ -5326,6 +5286,7 @@
 
 
 void Function::ClearCode() const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT((usage_counter() != 0) || (ic_data_array() == Array::null()));
   StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
   SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code()));
@@ -5337,6 +5298,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
+  ASSERT(thread->IsMutatorThread());
   const Code& current_code = Code::Handle(zone, CurrentCode());
 
   if (FLAG_trace_deoptimization_verbose) {
@@ -5358,6 +5320,7 @@
 
 
 void Function::set_unoptimized_code(const Code& value) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(value.IsNull() || !value.is_optimized());
   StorePointer(&raw_ptr()->unoptimized_code_, value.raw());
 }
@@ -5453,6 +5416,27 @@
 }
 
 
+RawField* Function::LookupImplicitGetterSetterField() const {
+  ASSERT((kind() == RawFunction::kImplicitGetter) ||
+         (kind() == RawFunction::kImplicitSetter) ||
+         (kind() == RawFunction::kImplicitStaticFinalGetter));
+  const Class& owner = Class::Handle(Owner());
+  ASSERT(!owner.IsNull());
+  const Array& fields = Array::Handle(owner.fields());
+  ASSERT(!fields.IsNull());
+  Field& field = Field::Handle();
+  for (intptr_t i = 0; i < fields.Length(); i++) {
+    field ^= fields.At(i);
+    ASSERT(!field.IsNull());
+    if (field.token_pos() == token_pos()) {
+      return field.raw();
+    }
+  }
+  return Field::null();
+}
+
+
+
 RawFunction* Function::parent_function() const {
   if (IsClosureFunction()) {
     const Object& obj = Object::Handle(raw_ptr()->data_);
@@ -5481,16 +5465,31 @@
     return Function::null();
   }
   const Object& obj = Object::Handle(raw_ptr()->data_);
-  ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction());
-  return (obj.IsNull() || obj.IsScript()) ? Function::null()
-                                          : Function::Cast(obj).raw();
+  ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction() || obj.IsArray());
+  if (obj.IsNull() || obj.IsScript()) {
+    return Function::null();
+  }
+  if (obj.IsFunction()) {
+    return Function::Cast(obj).raw();
+  }
+  ASSERT(is_native());
+  ASSERT(obj.IsArray());
+  const Object& res = Object::Handle(Array::Cast(obj).At(1));
+  return res.IsNull() ? Function::null() : Function::Cast(res).raw();
 }
 
 
 void Function::set_implicit_closure_function(const Function& value) const {
   ASSERT(!IsClosureFunction() && !IsSignatureFunction());
-  ASSERT(raw_ptr()->data_ == Object::null());
-  set_data(value);
+  if (is_native()) {
+    const Object& obj = Object::Handle(raw_ptr()->data_);
+    ASSERT(obj.IsArray());
+    ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull());
+    Array::Cast(obj).SetAt(1, value);
+  } else {
+    ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull());
+    set_data(value);
+  }
 }
 
 
@@ -5525,7 +5524,7 @@
 
 
 bool Function::IsRedirectingFactory() const {
-  if (!IsFactory() || (raw_ptr()->data_ == Object::null())) {
+  if (!IsFactory() || !is_redirecting()) {
     return false;
   }
   ASSERT(!IsClosureFunction());  // A factory cannot also be a closure.
@@ -5535,6 +5534,7 @@
 
 RawType* Function::RedirectionType() const {
   ASSERT(IsRedirectingFactory());
+  ASSERT(!is_native());
   const Object& obj = Object::Handle(raw_ptr()->data_);
   ASSERT(!obj.IsNull());
   return RedirectionData::Cast(obj).type();
@@ -5638,6 +5638,19 @@
 }
 
 
+// This field is heavily overloaded:
+//   eval function:           Script expression source
+//   signature function:      Class signature class
+//   method extractor:        Function extracted closure function
+//   noSuchMethod dispatcher: Array arguments descriptor
+//   invoke-field dispatcher: Array arguments descriptor
+//   redirecting constructor: RedirectionData
+//   closure function:        ClosureData
+//   irregexp function:       Array[0] = JSRegExp
+//                            Array[1] = Smi string specialization cid
+//   native function:         Array[0] = String native name
+//                            Array[1] = Function implicit closure function
+//   regular function:        Function for implicit closure function
 void Function::set_data(const Object& value) const {
   StorePointer(&raw_ptr()->data_, value.raw());
 }
@@ -5693,6 +5706,24 @@
 }
 
 
+RawString* Function::native_name() const {
+  ASSERT(is_native());
+  const Object& obj = Object::Handle(raw_ptr()->data_);
+  ASSERT(obj.IsArray());
+  return String::RawCast(Array::Cast(obj).At(0));
+}
+
+
+void Function::set_native_name(const String& value) const {
+  ASSERT(is_native());
+  ASSERT(raw_ptr()->data_ == Object::null());
+  const Array& pair = Array::Handle(Array::New(2, Heap::kOld));
+  pair.SetAt(0, value);
+  // pair[1] will be the implicit closure function if needed.
+  set_data(pair);
+}
+
+
 void Function::set_result_type(const AbstractType& value) const {
   ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->result_type_, value.raw());
@@ -5755,9 +5786,9 @@
 }
 
 
-void Function::set_token_pos(intptr_t value) const {
-  ASSERT(value >= 0);
-  StoreNonPointer(&raw_ptr()->token_pos_, value);
+void Function::set_token_pos(intptr_t token_pos) const {
+  ASSERT(token_pos >= 0);
+  StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
 
@@ -5804,7 +5835,7 @@
       ((end_token_pos() - token_pos()) < FLAG_huge_method_cutoff_in_tokens)) {
     // Additional check needed for implicit getters.
     return (unoptimized_code() == Object::null()) ||
-           (Code::Handle(unoptimized_code()).Size() <
+        (Code::Handle(unoptimized_code()).Size() <
             FLAG_huge_method_cutoff_in_code_size);
   }
   return false;
@@ -5821,6 +5852,7 @@
   set_is_optimizable(value);
   if (!value) {
     set_is_inlinable(false);
+    set_usage_counter(INT_MIN);
   }
 }
 
@@ -5832,10 +5864,10 @@
 
 
 bool Function::CanBeInlined() const {
+  Thread* thread = Thread::Current();
   return is_inlinable() &&
          !is_generated_body() &&
-         HasCode() &&
-         !Isolate::Current()->debugger()->HasBreakpoint(*this);
+         !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone());
 }
 
 
@@ -5846,13 +5878,8 @@
 
 intptr_t Function::NumImplicitParameters() const {
   if (kind() == RawFunction::kConstructor) {
-    if (is_static()) {
-      ASSERT(IsFactory());
-      return 1;  // Type arguments.
-    } else {
-      ASSERT(IsGenerativeConstructor());
-      return 2;  // Instance, phase.
-    }
+    // Type arguments for factory; instance for generative constructor.
+    return 1;
   }
   if ((kind() == RawFunction::kClosureFunction) ||
       (kind() == RawFunction::kSignatureFunction)) {
@@ -6231,10 +6258,7 @@
   const intptr_t other_num_opt_named_params =
       other.NumOptionalNamedParameters();
   // This function requires the same arguments or less and accepts the same
-  // arguments or more.
-  // A generative constructor may be compared to a redirecting factory and be
-  // compatible although it has an additional phase parameter.
-  // More generally, we can ignore implicit parameters.
+  // arguments or more. We can ignore implicit parameters.
   const intptr_t num_ignored_params = NumImplicitParameters();
   const intptr_t other_num_ignored_params = other.NumImplicitParameters();
   if (((num_fixed_params - num_ignored_params) >
@@ -6416,7 +6440,8 @@
   result.set_is_inlinable(true);
   result.set_allows_hoisting_check_class(true);
   result.set_allows_bounds_check_generalization(true);
-  result.SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code()));
+  result.SetInstructionsSafe(
+      Code::Handle(StubCode::LazyCompile_entry()->code()));
   if (kind == RawFunction::kClosureFunction) {
     const ClosureData& data = ClosureData::Handle(ClosureData::New());
     result.set_data(data);
@@ -6492,7 +6517,7 @@
                     /* is_external = */ false,
                     /* is_native = */ false,
                     owner,
-                    0));
+                    /* token_pos = */ 0));
   ASSERT(!script.IsNull());
   result.set_is_debuggable(false);
   result.set_is_visible(true);
@@ -6593,6 +6618,16 @@
 }
 
 
+void Function::DropUncompiledImplicitClosureFunction() const {
+  if (implicit_closure_function() != Function::null()) {
+    const Function& func = Function::Handle(implicit_closure_function());
+    if (!func.HasCode()) {
+      set_implicit_closure_function(Function::Handle());
+    }
+  }
+}
+
+
 RawString* Function::UserVisibleFormalParameters() const {
   // Typically 3, 5,.. elements in 'pieces', e.g.:
   // '_LoadRequest', CommaSpace, '_LoadError'.
@@ -6794,7 +6829,7 @@
     return Class::Cast(obj).raw();
   }
   ASSERT(obj.IsPatchClass());
-  return PatchClass::Cast(obj).source_class();
+  return PatchClass::Cast(obj).origin_class();
 }
 
 
@@ -6815,7 +6850,7 @@
     return Class::Cast(obj).script();
   }
   ASSERT(obj.IsPatchClass());
-  return PatchClass::Cast(obj).Script();
+  return PatchClass::Cast(obj).script();
 }
 
 
@@ -6985,7 +7020,8 @@
 
 
 void Function::RestoreICDataMap(
-    ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data) const {
+    ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
+    bool clone_descriptors) const {
   ASSERT(deopt_id_to_ic_data->is_empty());
   Zone* zone = Thread::Current()->zone();
   const Array& saved_ic_data = Array::Handle(zone, ic_data_array());
@@ -7004,6 +7040,11 @@
     for (intptr_t i = 1; i < saved_length; i++) {
       ICData& ic_data = ICData::ZoneHandle(zone);
       ic_data ^= saved_ic_data.At(i);
+      if (clone_descriptors) {
+        ICData& original_ic_data = ICData::Handle(zone, ic_data.raw());
+        ic_data = ICData::CloneDescriptor(ic_data);
+        ic_data.SetOriginal(original_ic_data);
+      }
       (*deopt_id_to_ic_data)[ic_data.deopt_id()] = &ic_data;
     }
   }
@@ -7117,7 +7158,7 @@
   intptr_t id = -1;
   const char* selector = NULL;
   if (f.IsNonImplicitClosureFunction()) {
-    id = cls.FindClosureIndex(f);
+    id = Isolate::Current()->FindClosureIndex(f);
     selector = "closures";
   } else if (f.IsImplicitClosureFunction()) {
     id = cls.FindImplicitClosureFunctionIndex(f);
@@ -7173,6 +7214,8 @@
   jsobj.AddProperty("_kind", kind_string);
   jsobj.AddProperty("static", is_static());
   jsobj.AddProperty("const", is_const());
+  jsobj.AddProperty("_intrinsic", is_intrinsic());
+  jsobj.AddProperty("_native", is_native());
   if (ref) {
     return;
   }
@@ -7186,6 +7229,7 @@
   }
   jsobj.AddProperty("_optimizable", is_optimizable());
   jsobj.AddProperty("_inlinable", is_inlinable());
+  jsobj.AddProperty("_recognized", IsRecognized());
   code = unoptimized_code();
   if (!code.IsNull()) {
     jsobj.AddProperty("_unoptimizedCode", code);
@@ -7194,6 +7238,14 @@
   jsobj.AddProperty("_optimizedCallSiteCount", optimized_call_site_count());
   jsobj.AddProperty("_deoptimizations",
                     static_cast<intptr_t>(deoptimization_counter()));
+  if ((kind() == RawFunction::kImplicitGetter) ||
+      (kind() == RawFunction::kImplicitSetter) ||
+      (kind() == RawFunction::kImplicitStaticFinalGetter)) {
+    const Field& field = Field::Handle(LookupImplicitGetterSetterField());
+    if (!field.IsNull()) {
+      jsobj.AddProperty("_field", field);
+    }
+  }
 
   const Script& script = Script::Handle(this->script());
   if (!script.IsNull()) {
@@ -7352,13 +7404,27 @@
     return Class::Cast(obj).raw();
   }
   ASSERT(obj.IsPatchClass());
-  return PatchClass::Cast(obj).source_class();
+  return PatchClass::Cast(obj).origin_class();
 }
 
 
-void Field::set_type(const AbstractType& value) const {
+RawScript* Field::script() const {
+  const Object& obj = Object::Handle(raw_ptr()->owner_);
+  if (obj.IsClass()) {
+    return Class::Cast(obj).script();
+  }
+  ASSERT(obj.IsPatchClass());
+  return PatchClass::Cast(obj).script();
+}
+
+
+// Called at finalization time
+void Field::SetFieldType(const AbstractType& value) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->type_, value.raw());
+  if (value.raw() != type()) {
+    StorePointer(&raw_ptr()->type_, value.raw());
+  }
 }
 
 
@@ -7377,6 +7443,7 @@
                      bool is_const,
                      bool is_reflectable,
                      const Class& owner,
+                     const AbstractType& type,
                      intptr_t token_pos) {
   ASSERT(!owner.IsNull());
   const Field& result = Field::Handle(Field::New());
@@ -7390,6 +7457,37 @@
   result.set_is_reflectable(is_reflectable);
   result.set_is_double_initialized(false);
   result.set_owner(owner);
+  result.SetFieldType(type);
+  result.set_token_pos(token_pos);
+  result.set_has_initializer(false);
+  result.set_is_unboxing_candidate(true);
+  result.set_guarded_cid(FLAG_use_field_guards ? kIllegalCid : kDynamicCid);
+  result.set_is_nullable(FLAG_use_field_guards ? false : true);
+  result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
+  // Presently, we only attempt to remember the list length for final fields.
+  if (is_final && FLAG_use_field_guards) {
+    result.set_guarded_list_length(Field::kUnknownFixedLength);
+  } else {
+    result.set_guarded_list_length(Field::kNoFixedLength);
+  }
+  return result.raw();
+}
+
+
+RawField* Field::NewTopLevel(const String& name,
+                             bool is_final,
+                             bool is_const,
+                             const Object& owner,
+                             intptr_t token_pos) {
+  ASSERT(!owner.IsNull());
+  const Field& result = Field::Handle(Field::New());
+  result.set_name(name);
+  result.set_is_static(true);
+  result.set_is_final(is_final);
+  result.set_is_const(is_const);
+  result.set_is_reflectable(true);
+  result.set_is_double_initialized(false);
+  result.set_owner(owner);
   result.set_token_pos(token_pos);
   result.set_has_initializer(false);
   result.set_is_unboxing_candidate(true);
@@ -7406,7 +7504,6 @@
 }
 
 
-
 RawField* Field::Clone(const Class& new_owner) const {
   Field& clone = Field::Handle();
   clone ^= Object::Clone(*this, Heap::kOld);
@@ -7421,7 +7518,7 @@
     // Adjust the field type to refer to type parameters of the new owner.
     AbstractType& type = AbstractType::Handle(clone.type());
     type ^= type.CloneUninstantiated(new_owner);
-    clone.set_type(type);
+    clone.SetFieldType(type);
   }
   return clone.raw();
 }
@@ -7444,6 +7541,7 @@
 
 
 void Field::set_guarded_list_length(intptr_t list_length) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   StoreSmi(&raw_ptr()->guarded_list_length_, Smi::New(list_length));
 }
 
@@ -7455,30 +7553,13 @@
 
 void Field::set_guarded_list_length_in_object_offset(
     intptr_t list_length_offset) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   StoreNonPointer(&raw_ptr()->guarded_list_length_in_object_offset_,
                   static_cast<int8_t>(list_length_offset - kHeapObjectTag));
   ASSERT(guarded_list_length_in_object_offset() == list_length_offset);
 }
 
 
-bool Field::IsUnboxedField() const {
-  bool valid_class = (FlowGraphCompiler::SupportsUnboxedDoubles() &&
-                      (guarded_cid() == kDoubleCid)) ||
-                     (FlowGraphCompiler::SupportsUnboxedSimd128() &&
-                      (guarded_cid() == kFloat32x4Cid)) ||
-                     (FlowGraphCompiler::SupportsUnboxedSimd128() &&
-                      (guarded_cid() == kFloat64x2Cid));
-  return is_unboxing_candidate() && !is_final() && !is_nullable() &&
-         valid_class;
-}
-
-
-bool Field::IsPotentialUnboxedField() const {
-  return is_unboxing_candidate() &&
-         (IsUnboxedField() || (!is_final() && (guarded_cid() == kIllegalCid)));
-}
-
-
 const char* Field::ToCString() const {
   if (IsNull()) {
     return "Field::null";
@@ -7493,14 +7574,16 @@
       "Field <%s.%s>:%s%s%s", cls_name, field_name, kF0, kF1, kF2);
 }
 
+
 void Field::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   Class& cls = Class::Handle(owner());
-  intptr_t id = cls.FindFieldIndex(*this);
-  ASSERT(id >= 0);
-  intptr_t cid = cls.id();
+  String& field_name = String::Handle(name());
+  field_name = String::EncodeIRI(field_name);
   AddCommonObjectProperties(&jsobj, "Field", ref);
-  jsobj.AddFixedServiceId("classes/%" Pd "/fields/%" Pd "", cid, id);
+  jsobj.AddFixedServiceId("classes/%" Pd "/fields/%s",
+                          cls.id(), field_name.ToCString());
+
   const String& user_name = String::Handle(PrettyName());
   const String& vm_name = String::Handle(name());
   AddNameProperties(&jsobj, user_name, vm_name);
@@ -7600,9 +7683,9 @@
                              true,  // is_const
                              false,  // is_reflectable
                              field_owner,
+                             Object::dynamic_type(),
                              this->token_pos());
   closure_field.SetStaticValue(Instance::Cast(result), true);
-  closure_field.set_type(Type::Handle(Type::DynamicType()));
   field_owner.AddField(closure_field);
 
   return Instance::RawCast(result.raw());
@@ -7650,13 +7733,17 @@
   virtual void ReportSwitchingCode(const Code& code) {
     if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
       Function& function = Function::Handle(code.function());
-      THR_Print("Switching %s to unoptimized code because guard"
-                " on field %s was violated.\n",
+      THR_Print("Switching '%s' to unoptimized code because guard"
+                " on field '%s' was violated.\n",
                 function.ToFullyQualifiedCString(),
                 field_.ToCString());
     }
   }
 
+  virtual void IncrementInvalidationGen() {
+    Isolate::Current()->IncrFieldInvalidationGen();
+  }
+
  private:
   const Field& field_;
   DISALLOW_COPY_AND_ASSIGN(FieldDependentArray);
@@ -7664,6 +7751,7 @@
 
 
 void Field::RegisterDependentCode(const Code& code) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   ASSERT(code.is_optimized());
   FieldDependentArray a(*this);
   a.Register(code);
@@ -7671,6 +7759,7 @@
 
 
 void Field::DeoptimizeDependentCode() const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   FieldDependentArray a(*this);
   a.DisableCode();
 }
@@ -7950,12 +8039,12 @@
 }
 
 
-RawArray* TokenStream::TokenObjects() const {
+RawGrowableObjectArray* TokenStream::TokenObjects() const {
   return raw_ptr()->token_objects_;
 }
 
 
-void TokenStream::SetTokenObjects(const Array& value) const {
+void TokenStream::SetTokenObjects(const GrowableObjectArray& value) const {
   StorePointer(&raw_ptr()->token_objects_, value.raw());
 }
 
@@ -8237,10 +8326,6 @@
       return String::Cast(key).Hash();
     }
   }
-
-  static RawObject* NewKey(const Scanner::TokenDescriptor& descriptor) {
-    return LiteralToken::New(descriptor.kind, *descriptor.literal);
-  }
 };
 typedef UnorderedHashMap<CompressedTokenTraits> CompressedTokenMap;
 
@@ -8249,33 +8334,60 @@
 class CompressedTokenStreamData : public ValueObject {
  public:
   static const intptr_t kInitialBufferSize = 16 * KB;
-  CompressedTokenStreamData() :
+  static const bool kPrintTokenObjects = false;
+
+  CompressedTokenStreamData(const GrowableObjectArray& ta,
+                            CompressedTokenMap* map) :
       buffer_(NULL),
       stream_(&buffer_, Reallocate, kInitialBufferSize),
-      tokens_(HashTables::New<CompressedTokenMap>(kInitialTableSize)) {
-  }
-  ~CompressedTokenStreamData() {
-    // Safe to discard the hash table now.
-    tokens_.Release();
+      token_objects_(ta),
+      tokens_(map),
+      value_(Object::Handle()),
+      fresh_index_smi_(Smi::Handle()) {
   }
 
   // Add an IDENT token into the stream and the token hash map.
-  void AddIdentToken(const String* ident) {
-    ASSERT(ident->IsSymbol());
-    const intptr_t fresh_index = tokens_.NumOccupied();
+  void AddIdentToken(const String& ident) {
+    ASSERT(ident.IsSymbol());
+    const intptr_t fresh_index = token_objects_.Length();
+    fresh_index_smi_ = Smi::New(fresh_index);
     intptr_t index = Smi::Value(Smi::RawCast(
-        tokens_.InsertOrGetValue(*ident,
-                                 Smi::Handle(Smi::New(fresh_index)))));
+        tokens_->InsertOrGetValue(ident, fresh_index_smi_)));
+    if (index == fresh_index) {
+      token_objects_.Add(ident);
+      if (kPrintTokenObjects) {
+        int iid = Isolate::Current()->main_port() % 1024;
+        OS::Print("ident  %03x  %p <%s>\n",
+                  iid, ident.raw(), ident.ToCString());
+      }
+    }
     WriteIndex(index);
   }
 
   // Add a LITERAL token into the stream and the token hash map.
   void AddLiteralToken(const Scanner::TokenDescriptor& descriptor) {
     ASSERT(descriptor.literal->IsSymbol());
-    const intptr_t fresh_index = tokens_.NumOccupied();
-    intptr_t index = Smi::Value(Smi::RawCast(
-        tokens_.InsertNewOrGetValue(descriptor,
-                                    Smi::Handle(Smi::New(fresh_index)))));
+    bool is_present = false;
+    value_ = tokens_->GetOrNull(descriptor, &is_present);
+    intptr_t index = -1;
+    if (is_present) {
+      ASSERT(value_.IsSmi());
+      index = Smi::Cast(value_).Value();
+    } else {
+      const intptr_t fresh_index = token_objects_.Length();
+      fresh_index_smi_ = Smi::New(fresh_index);
+      const LiteralToken& lit = LiteralToken::Handle(
+          LiteralToken::New(descriptor.kind, *descriptor.literal));
+      index = Smi::Value(Smi::RawCast(
+          tokens_->InsertOrGetValue(lit, fresh_index_smi_)));
+      token_objects_.Add(lit);
+      if (kPrintTokenObjects) {
+        int iid = Isolate::Current()->main_port() % 1024;
+        printf("lit    %03x  %p  %p  %p  <%s>\n",
+               iid, token_objects_.raw(), lit.literal(), lit.value(),
+               String::Handle(lit.literal()).ToCString());
+      }
+    }
     WriteIndex(index);
   }
 
@@ -8290,20 +8402,6 @@
   // Return the compressed token stream length.
   intptr_t Length() const { return stream_.bytes_written(); }
 
-  // Generate and return the token objects array.
-  RawArray* MakeTokenObjectsArray() const {
-    Array& result = Array::Handle(
-        Array::New(tokens_.NumOccupied(), Heap::kOld));
-    CompressedTokenMap::Iterator it(&tokens_);
-    Object& key = Object::Handle();
-    while (it.MoveNext()) {
-      intptr_t entry = it.Current();
-      key = tokens_.GetKey(entry);
-      result.SetAt(Smi::Value(Smi::RawCast(tokens_.GetPayload(entry, 0))), key);
-    }
-    return result.raw();
-  }
-
  private:
   void WriteIndex(intptr_t value) {
     stream_.WriteUnsigned(value + Token::kNumTokens);
@@ -8316,27 +8414,53 @@
     return reinterpret_cast<uint8_t*>(new_ptr);
   }
 
-  static const intptr_t kInitialTableSize = 32;
-
   uint8_t* buffer_;
   WriteStream stream_;
-  CompressedTokenMap tokens_;
+  const GrowableObjectArray& token_objects_;
+  CompressedTokenMap* tokens_;
+  Object& value_;
+  Smi& fresh_index_smi_;
 
   DISALLOW_COPY_AND_ASSIGN(CompressedTokenStreamData);
 };
 
 
 RawTokenStream* TokenStream::New(const Scanner::GrowableTokenStream& tokens,
-                                 const String& private_key) {
-  Zone* zone = Thread::Current()->zone();
+                                 const String& private_key,
+                                 bool use_shared_tokens) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
   // Copy the relevant data out of the scanner into a compressed stream of
   // tokens.
-  CompressedTokenStreamData data;
+
+  GrowableObjectArray& token_objects = GrowableObjectArray::Handle(zone);
+  Array& token_objects_map = Array::Handle(zone);
+  if (use_shared_tokens) {
+    // Use the shared token objects array in the object store. Allocate
+    // a new array if necessary.
+    ObjectStore* store = thread->isolate()->object_store();
+    if (store->token_objects() == GrowableObjectArray::null()) {
+      OpenSharedTokenList(thread->isolate());
+    }
+    token_objects = store->token_objects();
+    token_objects_map = store->token_objects_map();
+  } else {
+    // Use new, non-shared token array.
+    const int kInitialPrivateCapacity = 256;
+    token_objects =
+        GrowableObjectArray::New(kInitialPrivateCapacity, Heap::kOld);
+    token_objects_map =
+        HashTables::New<CompressedTokenMap>(kInitialPrivateCapacity,
+                                            Heap::kOld);
+  }
+  CompressedTokenMap map(token_objects_map.raw());
+  CompressedTokenStreamData data(token_objects, &map);
+
   intptr_t len = tokens.length();
   for (intptr_t i = 0; i < len; i++) {
     Scanner::TokenDescriptor token = tokens[i];
     if (token.kind == Token::kIDENT) {  // Identifier token.
-      data.AddIdentToken(token.literal);
+      data.AddIdentToken(*token.literal);
     } else if (Token::NeedsLiteralToken(token.kind)) {  // Literal token.
       data.AddLiteralToken(token);
     } else {  // Keyword, pseudo keyword etc.
@@ -8354,17 +8478,40 @@
   stream.AddFinalizer(data.GetStream(), DataFinalizer);
   const TokenStream& result = TokenStream::Handle(zone, New());
   result.SetPrivateKey(private_key);
-  const Array& token_objects =
-      Array::Handle(zone, data.MakeTokenObjectsArray());
   {
     NoSafepointScope no_safepoint;
     result.SetStream(stream);
     result.SetTokenObjects(token_objects);
   }
+
+  token_objects_map = map.Release().raw();
+  if (use_shared_tokens) {
+    thread->isolate()->object_store()->set_token_objects_map(token_objects_map);
+  }
   return result.raw();
 }
 
 
+void TokenStream::OpenSharedTokenList(Isolate* isolate) {
+  const int kInitialSharedCapacity = 5*1024;
+  ObjectStore* store = isolate->object_store();
+  ASSERT(store->token_objects() == GrowableObjectArray::null());
+  const GrowableObjectArray& token_objects = GrowableObjectArray::Handle(
+      GrowableObjectArray::New(kInitialSharedCapacity, Heap::kOld));
+  store->set_token_objects(token_objects);
+  const Array& token_objects_map = Array::Handle(
+      HashTables::New<CompressedTokenMap>(kInitialSharedCapacity,
+                                          Heap::kOld));
+  store->set_token_objects_map(token_objects_map);
+}
+
+
+void TokenStream::CloseSharedTokenList(Isolate* isolate) {
+  isolate->object_store()->set_token_objects(GrowableObjectArray::Handle());
+  isolate->object_store()->set_token_objects_map(Array::null_array());
+}
+
+
 const char* TokenStream::ToCString() const {
   return "TokenStream";
 }
@@ -8393,7 +8540,8 @@
     : tokens_(TokenStream::Handle(tokens.raw())),
       data_(ExternalTypedData::Handle(tokens.GetStream())),
       stream_(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), data_.Length()),
-      token_objects_(Array::Handle(tokens.TokenObjects())),
+      token_objects_(Array::Handle(
+          GrowableObjectArray::Handle(tokens.TokenObjects()).data())),
       obj_(Object::Handle()),
       cur_token_pos_(token_pos),
       cur_token_kind_(Token::kILLEGAL),
@@ -8409,7 +8557,7 @@
   data_ = tokens.GetStream();
   stream_.SetStream(reinterpret_cast<uint8_t*>(data_.DataAddr(0)),
                     data_.Length());
-  token_objects_ = tokens.TokenObjects();
+  token_objects_ = GrowableObjectArray::Handle(tokens.TokenObjects()).data();
   obj_ = Object::null();
   cur_token_pos_ = token_pos;
   cur_token_kind_ = Token::kILLEGAL;
@@ -8538,6 +8686,10 @@
 
 RawString* Script::GenerateSource() const {
   const TokenStream& token_stream = TokenStream::Handle(tokens());
+  if (token_stream.IsNull()) {
+    ASSERT(Dart::IsRunningPrecompiledCode());
+    return String::null();
+  }
   return token_stream.GenerateSource();
 }
 
@@ -8664,7 +8816,8 @@
 }
 
 
-void Script::Tokenize(const String& private_key) const {
+void Script::Tokenize(const String& private_key,
+                      bool use_shared_tokens) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const TokenStream& tkns = TokenStream::Handle(zone, tokens());
@@ -8679,7 +8832,8 @@
   Scanner scanner(src, private_key);
   const Scanner::GrowableTokenStream& ts = scanner.GetStream();
   INC_STAT(thread, num_tokens_scanned, ts.length());
-  set_tokens(TokenStream::Handle(zone, TokenStream::New(ts, private_key)));
+  set_tokens(TokenStream::Handle(zone,
+      TokenStream::New(ts, private_key, use_shared_tokens)));
   INC_STAT(thread, src_length, src.Length());
 }
 
@@ -8699,6 +8853,17 @@
                               intptr_t* token_len) const {
   ASSERT(line != NULL);
   const TokenStream& tkns = TokenStream::Handle(tokens());
+  if (tkns.IsNull()) {
+    ASSERT(Dart::IsRunningPrecompiledCode());
+    *line = -1;
+    if (column != NULL) {
+      *column = -1;
+    }
+    if (token_len != NULL) {
+      *token_len = 1;
+    }
+    return;
+  }
   if (column == NULL) {
     TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
     intptr_t cur_line = line_offset() + 1;
@@ -8821,6 +8986,10 @@
                               intptr_t to_line,
                               intptr_t to_column) const {
   const String& src = String::Handle(Source());
+  if (src.IsNull()) {
+    ASSERT(Dart::IsRunningPrecompiledCode());
+    return Symbols::OptimizedOut().raw();
+  }
   intptr_t length = src.Length();
   intptr_t line = 1 + line_offset();
   intptr_t column = 1;
@@ -8941,10 +9110,12 @@
   const String& source = String::Handle(Source());
   jsobj.AddProperty("lineOffset", line_offset());
   jsobj.AddProperty("columnOffset", col_offset());
-  jsobj.AddPropertyStr("source", source);
+  if (!source.IsNull()) {
+    jsobj.AddPropertyStr("source", source);
+  }
 
   // Print the line number table
-  {
+  if (!source.IsNull()) {
     JSONArray tokenPosTable(&jsobj, "tokenPosTable");
 
     const GrowableObjectArray& lineNumberArray =
@@ -9004,11 +9175,10 @@
 ClassDictionaryIterator::ClassDictionaryIterator(const Library& library,
                                                  IterationKind kind)
     : DictionaryIterator(library),
-      anon_array_((kind == kIteratePrivate) ?
-          Array::Handle(library.anonymous_classes()) : Object::empty_array()),
-      anon_size_((kind == kIteratePrivate) ?
-                 library.num_anonymous_classes() : 0),
-      anon_ix_(0) {
+      toplevel_class_(Class::Handle(
+          (kind == kIteratePrivate)
+              ? library.toplevel_class()
+              : Class::null())) {
   MoveToNextClass();
 }
 
@@ -9022,8 +9192,9 @@
     MoveToNextClass();
     return cls.raw();
   }
-  ASSERT(anon_ix_ < anon_size_);
-  cls ^= anon_array_.At(anon_ix_++);
+  ASSERT(!toplevel_class_.IsNull());
+  cls = toplevel_class_.raw();
+  toplevel_class_ = Class::null();
   return cls.raw();
 }
 
@@ -9170,6 +9341,50 @@
 }
 
 
+void Library::AddPatchClass(const Class& cls) const {
+  ASSERT(cls.is_patch());
+  ASSERT(GetPatchClass(String::Handle(cls.Name())) == Class::null());
+  const GrowableObjectArray& patch_classes =
+      GrowableObjectArray::Handle(this->patch_classes());
+  patch_classes.Add(cls);
+}
+
+
+RawClass* Library::GetPatchClass(const String& name) const {
+  const GrowableObjectArray& patch_classes =
+      GrowableObjectArray::Handle(this->patch_classes());
+  Object& obj = Object::Handle();
+  for (intptr_t i = 0; i < patch_classes.Length(); i++) {
+    obj = patch_classes.At(i);
+    if (obj.IsClass() &&
+        (Class::Cast(obj).Name() == name.raw())) {  // Names are canonicalized.
+      return Class::RawCast(obj.raw());
+    }
+  }
+  return Class::null();
+}
+
+
+void Library::RemovePatchClass(const Class& cls) const {
+  ASSERT(cls.is_patch());
+  const GrowableObjectArray& patch_classes =
+      GrowableObjectArray::Handle(this->patch_classes());
+  const intptr_t num_classes = patch_classes.Length();
+  intptr_t i = 0;
+  while (i < num_classes) {
+    if (cls.raw() == patch_classes.At(i)) break;
+    i++;
+  }
+  if (i == num_classes) return;
+  // Replace the entry with the script. We keep the script so that
+  // Library::LoadedScripts() can find it without having to iterate
+  // over the members of each class.
+  ASSERT(i < num_classes);  // We must have found a class.
+  const Script& patch_script = Script::Handle(cls.script());
+  patch_classes.SetAt(i, patch_script);
+}
+
+
 static RawString* MakeClassMetaName(const Class& cls) {
   return Symbols::FromConcat(Symbols::At(), String::Handle(cls.Name()));
 }
@@ -9208,32 +9423,31 @@
 }
 
 
-void Library::AddMetadata(const Class& cls,
+void Library::AddMetadata(const Object& owner,
                           const String& name,
                           intptr_t token_pos) const {
   const String& metaname = String::Handle(Symbols::New(name));
-  Field& field = Field::Handle(Field::New(metaname,
-                                          true,   // is_static
-                                          false,  // is_final
-                                          false,  // is_const
-                                          false,  // is_reflectable
-                                          cls,
-                                          token_pos));
-  field.set_type(Type::Handle(Type::DynamicType()));
+  const Field& field = Field::Handle(
+      Field::NewTopLevel(metaname,
+                         false,  // is_final
+                         false,  // is_const
+                         owner,
+                         token_pos));
+  field.SetFieldType(Object::dynamic_type());
+  field.set_is_reflectable(false);
   field.SetStaticValue(Array::empty_array(), true);
   GrowableObjectArray& metadata =
       GrowableObjectArray::Handle(this->metadata());
   metadata.Add(field, Heap::kOld);
-  cls.AddField(field);
 }
 
 
 void Library::AddClassMetadata(const Class& cls,
-                               const Class& toplevel_class,
+                               const Object& tl_owner,
                                intptr_t token_pos) const {
   // We use the toplevel class as the owner of a class's metadata field because
   // a class's metadata is in scope of the library, not the class.
-  AddMetadata(toplevel_class,
+  AddMetadata(tl_owner,
               String::Handle(MakeClassMetaName(cls)),
               token_pos);
 }
@@ -9241,7 +9455,7 @@
 
 void Library::AddFieldMetadata(const Field& field,
                                intptr_t token_pos) const {
-  AddMetadata(Class::Handle(field.origin()),
+  AddMetadata(Object::Handle(field.RawOwner()),
               String::Handle(MakeFieldMetaName(field)),
               token_pos);
 }
@@ -9249,7 +9463,7 @@
 
 void Library::AddFunctionMetadata(const Function& func,
                                   intptr_t token_pos) const {
-  AddMetadata(Class::Handle(func.origin()),
+  AddMetadata(Object::Handle(func.RawOwner()),
               String::Handle(MakeFunctionMetaName(func)),
               token_pos);
 }
@@ -9263,8 +9477,9 @@
 }
 
 
-void Library::AddLibraryMetadata(const Class& cls, intptr_t token_pos) const {
-  AddMetadata(cls, Symbols::TopLevel(), token_pos);
+void Library::AddLibraryMetadata(const Object& tl_owner,
+                                 intptr_t token_pos) const {
+  AddMetadata(tl_owner, Symbols::TopLevel(), token_pos);
 }
 
 
@@ -9316,8 +9531,7 @@
   Object& metadata = Object::Handle();
   metadata = field.StaticValue();
   if (field.StaticValue() == Object::empty_array().raw()) {
-    metadata = Parser::ParseMetadata(Class::Handle(field.owner()),
-                                     field.token_pos());
+    metadata = Parser::ParseMetadata(field);
     if (metadata.IsArray()) {
       ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw());
       field.SetStaticValue(Array::Cast(metadata), true);
@@ -9385,7 +9599,10 @@
   ResolvedNamesMap cache(resolved_names());
   bool present = false;
   *obj = cache.GetOrNull(name, &present);
-  ASSERT(cache.Release().raw() == resolved_names());
+  // Mutator compiler thread may add entries and therefore
+  // change 'resolved_names()' while running a background compilation;
+  // do not ASSERT that 'resolved_names()' has not changed.
+  cache.Release();
   return present;
 }
 
@@ -9586,46 +9803,50 @@
         GrowableObjectArray::Handle(GrowableObjectArray::New(8));
     Object& entry = Object::Handle();
     Class& cls = Class::Handle();
-    Class& patch_cls = Class::Handle();
     Script& owner_script = Script::Handle();
-    Script& patch_script = Script::Handle();
     DictionaryIterator it(*this);
     while (it.HasNext()) {
       entry = it.GetNext();
       if (entry.IsClass()) {
         owner_script = Class::Cast(entry).script();
-        patch_cls = Class::Cast(entry).patch_class();
-        if (!patch_cls.IsNull()) {
-          patch_script = patch_cls.script();
-          AddScriptIfUnique(scripts, patch_script);
-        }
       } else if (entry.IsFunction()) {
         owner_script = Function::Cast(entry).script();
       } else if (entry.IsField()) {
-        cls = Field::Cast(entry).owner();
-        owner_script = cls.script();
+        owner_script = Field::Cast(entry).script();
       } else {
         continue;
       }
       AddScriptIfUnique(scripts, owner_script);
     }
 
-    // Special case: Scripts that only contain external top-level functions are
-    // not included above, but can be referenced through a library's anonymous
-    // classes. Example: dart-core:identical.dart.
-    Array& anon_classes = Array::Handle(anonymous_classes());
-    Function& func = Function::Handle();
-    Array& functions = Array::Handle();
-    for (intptr_t i = 0; i < anon_classes.Length(); i++) {
-      cls ^= anon_classes.At(i);
-      if (cls.IsNull()) continue;
+    // Add all scripts from patch classes.
+    GrowableObjectArray& patches = GrowableObjectArray::Handle(patch_classes());
+    for (intptr_t i = 0; i < patches.Length(); i++) {
+      entry = patches.At(i);
+      if (entry.IsClass()) {
+        owner_script = Class::Cast(entry).script();
+      }  else {
+        ASSERT(entry.IsScript());
+        owner_script = Script::Cast(entry).raw();
+      }
+      AddScriptIfUnique(scripts, owner_script);
+    }
+
+    cls ^= toplevel_class();
+    if (!cls.IsNull()) {
       owner_script = cls.script();
       AddScriptIfUnique(scripts, owner_script);
-      functions = cls.functions();
+      // Special case: Scripts that only contain external top-level functions
+      // are not included above, but can be referenced through a library's
+      // anonymous classes. Example: dart-core:identical.dart.
+      Function& func = Function::Handle();
+      Array& functions = Array::Handle(cls.functions());
       for (intptr_t j = 0; j < functions.Length(); j++) {
         func ^= functions.At(j);
-        owner_script = func.script();
-        AddScriptIfUnique(scripts, owner_script);
+        if (func.is_external()) {
+          owner_script = func.script();
+          AddScriptIfUnique(scripts, owner_script);
+        }
       }
     }
 
@@ -9668,24 +9889,6 @@
 }
 
 
-RawFunction* Library::LookupFunctionInScript(const Script& script,
-                                             intptr_t token_pos) const {
-  Class& cls = Class::Handle();
-  Function& func = Function::Handle();
-  ClassDictionaryIterator it(*this, ClassDictionaryIterator::kIteratePrivate);
-  while (it.HasNext()) {
-    cls = it.GetNextClass();
-    if (script.raw() == cls.script()) {
-      func = cls.LookupFunctionAtToken(token_pos);
-      if (!func.IsNull()) {
-        return func.raw();
-      }
-    }
-  }
-  return Function::null();
-}
-
-
 RawObject* Library::LookupLocalObject(const String& name) const {
   intptr_t index;
   return LookupEntry(name, &index);
@@ -9861,17 +10064,9 @@
 }
 
 
-void Library::AddAnonymousClass(const Class& cls) const {
-  intptr_t num_anonymous = this->raw_ptr()->num_anonymous_;
-  Array& anon_array = Array::Handle(this->raw_ptr()->anonymous_classes_);
-  if (num_anonymous == anon_array.Length()) {
-    intptr_t new_len = (num_anonymous == 0) ? 4 : num_anonymous * 2;
-    anon_array = Array::Grow(anon_array, new_len);
-    StorePointer(&raw_ptr()->anonymous_classes_, anon_array.raw());
-  }
-  anon_array.SetAt(num_anonymous, cls);
-  num_anonymous++;
-  StoreNonPointer(&raw_ptr()->num_anonymous_, num_anonymous);
+void Library::set_toplevel_class(const Class& value) const {
+  ASSERT(raw_ptr()->toplevel_class_ == Class::null());
+  StorePointer(&raw_ptr()->toplevel_class_, value.raw());
 }
 
 
@@ -10001,9 +10196,10 @@
                       Object::empty_array().raw());
   result.StorePointer(&result.raw_ptr()->metadata_,
                       GrowableObjectArray::New(4, Heap::kOld));
-  result.StorePointer(&result.raw_ptr()->anonymous_classes_,
-                      Object::empty_array().raw());
-  result.StoreNonPointer(&result.raw_ptr()->num_anonymous_, 0);
+  result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null());
+  result.StorePointer(&result.raw_ptr()->patch_classes_,
+                      GrowableObjectArray::New(Object::empty_array(),
+                                               Heap::kOld));
   result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw());
   result.StorePointer(&result.raw_ptr()->exports_, Object::empty_array().raw());
   result.StorePointer(&result.raw_ptr()->loaded_scripts_, Array::null());
@@ -10058,12 +10254,8 @@
 RawObject* Library::Evaluate(const String& expr,
                              const Array& param_names,
                              const Array& param_values) const {
-  // Take or make a fake top-level class and evaluate the expression
-  // as a static function of the class.
-  Class& top_level_class = Class::Handle();
-  Array& top_level_classes = Array::Handle(anonymous_classes());
-  ASSERT(top_level_classes.Length() > 0);
-  top_level_class ^= top_level_classes.At(0);
+  // Evaluate the expression as a static function of the toplevel class.
+  Class& top_level_class = Class::Handle(toplevel_class());
   ASSERT(top_level_class.is_finalized());
   return top_level_class.Evaluate(expr, param_names, param_values);
 }
@@ -10580,7 +10772,7 @@
   } else if (deferred_lib.LoadNotStarted()) {
     Thread* thread = Thread::Current();
     Isolate* isolate = thread->isolate();
-    Api::Scope api_scope(isolate);
+    Api::Scope api_scope(thread);
     Zone* zone = thread->zone();
     deferred_lib.SetLoadRequested();
     const GrowableObjectArray& pending_deferred_loads =
@@ -10590,8 +10782,8 @@
     const String& lib_url = String::Handle(zone, deferred_lib.url());
     Dart_LibraryTagHandler handler = isolate->library_tag_handler();
     handler(Dart_kImportTag,
-            Api::NewHandle(isolate, importer()),
-            Api::NewHandle(isolate, lib_url.raw()));
+            Api::NewHandle(thread, importer()),
+            Api::NewHandle(thread, lib_url.raw()));
   } else {
     // Another load request is in flight.
     ASSERT(deferred_lib.LoadRequested());
@@ -10638,6 +10830,10 @@
     }
   }
 
+  virtual void IncrementInvalidationGen() {
+    Isolate::Current()->IncrPrefixInvalidationGen();
+  }
+
  private:
   const LibraryPrefix& prefix_;
   DISALLOW_COPY_AND_ASSIGN(PrefixDependentArray);
@@ -10724,19 +10920,17 @@
 }
 
 
-void Namespace::AddMetadata(intptr_t token_pos, const Class& owner_class) {
+void Namespace::AddMetadata(const Object& owner, intptr_t token_pos) {
   ASSERT(Field::Handle(metadata_field()).IsNull());
-  Field& field = Field::Handle(Field::New(Symbols::TopLevel(),
-                                          true,   // is_static
+  Field& field = Field::Handle(Field::NewTopLevel(Symbols::TopLevel(),
                                           false,  // is_final
                                           false,  // is_const
-                                          false,  // is_reflectable
-                                          owner_class,
+                                          owner,
                                           token_pos));
-  field.set_type(Type::Handle(Type::DynamicType()));
+  field.set_is_reflectable(false);
+  field.SetFieldType(Object::dynamic_type());
   field.SetStaticValue(Array::empty_array(), true);
   set_metadata_field(field);
-  owner_class.AddField(field);
 }
 
 
@@ -10749,8 +10943,7 @@
   Object& metadata = Object::Handle();
   metadata = field.StaticValue();
   if (field.StaticValue() == Object::empty_array().raw()) {
-    metadata = Parser::ParseMetadata(Class::Handle(field.owner()),
-                                     field.token_pos());
+    metadata = Parser::ParseMetadata(field);
     if (metadata.IsArray()) {
       ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw());
       field.SetStaticValue(Array::Cast(metadata), true);
@@ -10877,17 +11070,19 @@
 
 
 RawError* Library::CompileAll() {
-  Error& error = Error::Handle();
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Error& error = Error::Handle(zone);
   const GrowableObjectArray& libs = GrowableObjectArray::Handle(
       Isolate::Current()->object_store()->libraries());
-  Library& lib = Library::Handle();
-  Class& cls = Class::Handle();
+  Library& lib = Library::Handle(zone);
+  Class& cls = Class::Handle(zone);
   for (int i = 0; i < libs.Length(); i++) {
     lib ^= libs.At(i);
     ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
     while (it.HasNext()) {
       cls = it.GetNextClass();
-      error = cls.EnsureIsFinalized(Thread::Current());
+      error = cls.EnsureIsFinalized(thread);
       if (!error.IsNull()) {
         return error.raw();
       }
@@ -10897,6 +11092,24 @@
       }
     }
   }
+
+  // Inner functions get added to the closures array. As part of compilation
+  // more closures can be added to the end of the array. Compile all the
+  // closures until we have reached the end of the "worklist".
+  const GrowableObjectArray& closures = GrowableObjectArray::Handle(zone,
+      Isolate::Current()->object_store()->closure_functions());
+  Function& func = Function::Handle(zone);
+  for (int i = 0; i < closures.Length(); i++) {
+    func ^= closures.At(i);
+    if (!func.HasCode()) {
+      error = Compiler::CompileFunction(thread, func);
+      if (!error.IsNull()) {
+        return error.raw();
+      }
+      func.ClearICDataArray();
+      func.ClearCode();
+    }
+  }
   return error.raw();
 }
 
@@ -11333,18 +11546,22 @@
 // finally blocks).
 void PcDescriptors::Verify(const Function& function) const {
 #if defined(DEBUG)
-  // TODO(srdjan): Implement a more efficient way to check, currently drop
-  // the check for too large number of descriptors.
-  if (Length() > 3000) {
-    if (FLAG_trace_compiler) {
-      OS::Print("Not checking pc decriptors, length %" Pd "\n", Length());
-    }
-    return;
-  }
   // Only check ids for unoptimized code that is optimizable.
   if (!function.IsOptimizable()) {
     return;
   }
+  intptr_t max_deopt_id = 0;
+  Iterator max_iter(*this,
+                    RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall);
+  while (max_iter.MoveNext()) {
+    if (max_iter.DeoptId() > max_deopt_id) {
+      max_deopt_id = max_iter.DeoptId();
+    }
+  }
+
+  Zone* zone = Thread::Current()->zone();
+  BitVector* deopt_ids = new(zone) BitVector(zone, max_deopt_id + 1);
+  BitVector* iccall_ids = new(zone) BitVector(zone, max_deopt_id + 1);
   Iterator iter(*this, RawPcDescriptors::kDeopt | RawPcDescriptors::kIcCall);
   while (iter.MoveNext()) {
     // 'deopt_id' is set for kDeopt and kIcCall and must be unique for one kind.
@@ -11354,12 +11571,12 @@
       // lead to issues in the future. Fix that and enable verification.
       continue;
     }
-
-    Iterator nested(iter);
-    while (nested.MoveNext()) {
-      if (iter.Kind() == nested.Kind()) {
-        ASSERT(nested.DeoptId() != iter.DeoptId());
-      }
+    if (iter.Kind() == RawPcDescriptors::kDeopt) {
+      ASSERT(!deopt_ids->Contains(iter.DeoptId()));
+      deopt_ids->Add(iter.DeoptId());
+    } else {
+      ASSERT(!iccall_ids->Contains(iter.DeoptId()));
+      iccall_ids->Add(iter.DeoptId());
     }
   }
 #endif  // DEBUG
@@ -11972,9 +12189,41 @@
 }
 
 
+RawFunction* ICData::Owner() const {
+  Object& obj = Object::Handle(raw_ptr()->owner_);
+  if (obj.IsFunction()) {
+    return Function::Cast(obj).raw();
+  } else {
+    ICData& original = ICData::Handle();
+    original ^= obj.raw();
+    return original.Owner();
+  }
+}
+
+
+RawICData* ICData::Original() const {
+  if (IsNull()) {
+    return ICData::null();
+  }
+  Object& obj = Object::Handle(raw_ptr()->owner_);
+  if (obj.IsFunction()) {
+    return this->raw();
+  } else {
+    return ICData::RawCast(obj.raw());
+  }
+}
+
+
+void ICData::SetOriginal(const ICData& value) const {
+  ASSERT(value.IsOriginal());
+  ASSERT(!value.IsNull());
+  StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw()));
+}
+
+
 void ICData::set_owner(const Function& value) const {
   ASSERT(!value.IsNull());
-  StorePointer(&raw_ptr()->owner_, value.raw());
+  StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw()));
 }
 
 
@@ -11995,7 +12244,7 @@
 }
 
 
-void ICData::set_ic_data(const Array& value) const {
+void ICData::set_ic_data_array(const Array& value) const {
   ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->ic_data_, value.raw());
 }
@@ -12103,9 +12352,9 @@
 }
 
 
-void ICData::WriteSentinel(const Array& data) const {
+void ICData::WriteSentinel(const Array& data, intptr_t test_entry_length) {
   ASSERT(!data.IsNull());
-  for (intptr_t i = 1; i <= TestEntryLength(); i++) {
+  for (intptr_t i = 1; i <= test_entry_length; i++) {
     data.SetAt(data.Length() - i, smi_illegal_cid());
   }
 }
@@ -12117,8 +12366,7 @@
   const intptr_t len = NumberOfChecks();
   for (intptr_t i = 0; i < len; i++) {
     GrowableArray<intptr_t> class_ids;
-    Function& target = Function::Handle();
-    GetCheckAt(i, &class_ids, &target);
+    GetClassIdsAt(i, &class_ids);
     bool matches = true;
     for (intptr_t k = 0; k < class_ids.length(); k++) {
       if (class_ids[k] != cids[k]) {
@@ -12158,8 +12406,7 @@
   Array& data = Array::Handle(ic_data());
   const intptr_t new_len = data.Length() + TestEntryLength();
   data = Array::Grow(data, new_len, Heap::kOld);
-  set_ic_data(data);
-  WriteSentinel(data);
+  WriteSentinel(data, TestEntryLength());
   intptr_t data_pos = old_num * TestEntryLength();
   ASSERT(!target.IsNull());
   data.SetAt(data_pos++, target);
@@ -12167,6 +12414,9 @@
   // call has been executed.
   const Smi& value = Smi::Handle(Smi::New(0));
   data.SetAt(data_pos, value);
+  // Multithreaded access to ICData requires setting of array to be the last
+  // operation.
+  set_ic_data_array(data);
 }
 
 
@@ -12204,8 +12454,7 @@
   }
   const intptr_t new_len = data.Length() + TestEntryLength();
   data = Array::Grow(data, new_len, Heap::kOld);
-  set_ic_data(data);
-  WriteSentinel(data);
+  WriteSentinel(data, TestEntryLength());
   intptr_t data_pos = old_num * TestEntryLength();
   Smi& value = Smi::Handle();
   for (intptr_t i = 0; i < class_ids.length(); i++) {
@@ -12218,6 +12467,9 @@
   data.SetAt(data_pos++, target);
   value = Smi::New(1);
   data.SetAt(data_pos, value);
+  // Multithreaded access to ICData requires setting of array to be the last
+  // operation.
+  set_ic_data_array(data);
 }
 
 
@@ -12237,8 +12489,7 @@
   Array& data = Array::Handle(ic_data());
   const intptr_t new_len = data.Length() + TestEntryLength();
   data = Array::Grow(data, new_len, Heap::kOld);
-  set_ic_data(data);
-  WriteSentinel(data);
+  WriteSentinel(data, TestEntryLength());
   intptr_t data_pos = old_num * TestEntryLength();
   if ((receiver_class_id == kSmiCid) && (data_pos > 0)) {
     ASSERT(GetReceiverClassIdAt(0) != kSmiCid);
@@ -12252,6 +12503,9 @@
   data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
   data.SetAt(data_pos + 1, target);
   data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count)));
+  // Multithreaded access to ICData requires setting of array to be the last
+  // operation.
+  set_ic_data_array(data);
 }
 
 
@@ -12271,6 +12525,19 @@
 }
 
 
+void ICData::GetClassIdsAt(intptr_t index,
+                           GrowableArray<intptr_t>* class_ids) const {
+  ASSERT(index < NumberOfChecks());
+  ASSERT(class_ids != NULL);
+  class_ids->Clear();
+  const Array& data = Array::Handle(ic_data());
+  intptr_t data_pos = index * TestEntryLength();
+  for (intptr_t i = 0; i < NumArgsTested(); i++) {
+    class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
+  }
+}
+
+
 void ICData::GetOneClassCheckAt(intptr_t index,
                                 intptr_t* class_id,
                                 Function* target) const {
@@ -12294,8 +12561,7 @@
 
 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const {
   GrowableArray<intptr_t> class_ids;
-  Function& target = Function::Handle();
-  GetCheckAt(index, &class_ids, &target);
+  GetClassIdsAt(index, &class_ids);
   return class_ids[arg_nr];
 }
 
@@ -12471,12 +12737,11 @@
   ASSERT(NumArgsTested() == 2);
   first->Clear();
   second->Clear();
-  Function& target = Function::Handle();
   GrowableArray<intptr_t> class_ids;
   const intptr_t len = NumberOfChecks();
   for (intptr_t i = 0; i < len; i++) {
     if (GetCountAt(i) > 0) {
-      GetCheckAt(i, &class_ids, &target);
+      GetClassIdsAt(i, &class_ids);
       ASSERT(class_ids.length() == 2);
       first->Add(class_ids[0]);
       second->Add(class_ids[1]);
@@ -12502,6 +12767,64 @@
 }
 
 
+void ICData::InitOnce() {
+  for (int i = 0; i < kCachedICDataArrayCount; i++) {
+    cached_icdata_arrays_[i] = ICData::NewNonCachedEmptyICDataArray(i);
+  }
+}
+
+
+RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested) {
+  // IC data array must be null terminated (sentinel entry).
+  const intptr_t len = TestEntryLengthFor(num_args_tested);
+  const Array& array = Array::Handle(Array::New(len, Heap::kOld));
+  WriteSentinel(array, len);
+  array.MakeImmutable();
+  return array.raw();
+}
+
+
+RawArray* ICData::NewEmptyICDataArray(intptr_t num_args_tested) {
+  ASSERT(num_args_tested >= 0);
+  if (num_args_tested < kCachedICDataArrayCount) {
+    return cached_icdata_arrays_[num_args_tested];
+  }
+  return NewNonCachedEmptyICDataArray(num_args_tested);
+}
+
+
+
+// Does not initialize ICData array.
+RawICData* ICData::NewDescriptor(Zone* zone,
+                                 const Function& owner,
+                                 const String& target_name,
+                                 const Array& arguments_descriptor,
+                                 intptr_t deopt_id,
+                                 intptr_t num_args_tested) {
+  ASSERT(!owner.IsNull());
+  ASSERT(!target_name.IsNull());
+  ASSERT(!arguments_descriptor.IsNull());
+  ASSERT(Object::icdata_class() != Class::null());
+  ASSERT(num_args_tested >= 0);
+  ICData& result = ICData::Handle(zone);
+  {
+    // IC data objects are long living objects, allocate them in old generation.
+    RawObject* raw = Object::Allocate(ICData::kClassId,
+                                      ICData::InstanceSize(),
+                                      Heap::kOld);
+    NoSafepointScope no_safepoint;
+    result ^= raw;
+  }
+  result.set_owner(owner);
+  result.set_target_name(target_name);
+  result.set_arguments_descriptor(arguments_descriptor);
+  result.set_deopt_id(deopt_id);
+  result.set_state_bits(0);
+  result.SetNumArgsTested(num_args_tested);
+  return result.raw();
+}
+
+
 RawICData* ICData::New() {
   ICData& result = ICData::Handle();
   {
@@ -12523,39 +12846,23 @@
                        const Array& arguments_descriptor,
                        intptr_t deopt_id,
                        intptr_t num_args_tested) {
-  ASSERT(!owner.IsNull());
-  ASSERT(!target_name.IsNull());
-  ASSERT(!arguments_descriptor.IsNull());
-  ASSERT(Object::icdata_class() != Class::null());
-  ASSERT(num_args_tested >= 0);
-  ICData& result = ICData::Handle();
-  {
-    // IC data objects are long living objects, allocate them in old generation.
-    RawObject* raw = Object::Allocate(ICData::kClassId,
-                                      ICData::InstanceSize(),
-                                      Heap::kOld);
-    NoSafepointScope no_safepoint;
-    result ^= raw;
-  }
-  result.set_owner(owner);
-  result.set_target_name(target_name);
-  result.set_arguments_descriptor(arguments_descriptor);
-  result.set_deopt_id(deopt_id);
-  result.set_state_bits(0);
-  result.SetNumArgsTested(num_args_tested);
-  // Number of array elements in one test entry.
-  intptr_t len = result.TestEntryLength();
-  // IC data array must be null terminated (sentinel entry).
-  const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld));
-  result.set_ic_data(ic_data);
-  result.WriteSentinel(ic_data);
+  Zone* zone = Thread::Current()->zone();
+  const ICData& result = ICData::Handle(zone,
+                                        NewDescriptor(zone,
+                                                      owner,
+                                                      target_name,
+                                                      arguments_descriptor,
+                                                      deopt_id,
+                                                      num_args_tested));
+  result.set_ic_data_array(
+      Array::Handle(zone, NewEmptyICDataArray(num_args_tested)));
   return result.raw();
 }
 
 
 RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) {
   const ICData& result = ICData::Handle(ICData::New(
-      Function::Handle(from.owner()),
+      Function::Handle(from.Owner()),
       String::Handle(from.target_name()),
       Array::Handle(from.arguments_descriptor()),
       from.deopt_id(),
@@ -12566,11 +12873,28 @@
 }
 
 
+RawICData* ICData::CloneDescriptor(const ICData& from) {
+  Zone* zone = Thread::Current()->zone();
+  const ICData& result = ICData::Handle(ICData::NewDescriptor(
+      zone,
+      Function::Handle(zone, from.Owner()),
+      String::Handle(zone, from.target_name()),
+      Array::Handle(zone, from.arguments_descriptor()),
+      from.deopt_id(),
+      from.NumArgsTested()));
+  // Preserve entry array.
+  result.set_ic_data_array(Array::Handle(zone, from.ic_data()));
+  // Copy deoptimization reasons.
+  result.SetDeoptReasons(from.DeoptReasons());
+  return result.raw();
+}
+
+
 void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   AddCommonObjectProperties(&jsobj, "Object", ref);
   jsobj.AddServiceId(*this);
-  jsobj.AddProperty("_owner", Object::Handle(owner()));
+  jsobj.AddProperty("_owner", Object::Handle(Owner()));
   jsobj.AddProperty("_selector", String::Handle(target_name()).ToCString());
   if (ref) {
     return;
@@ -12590,7 +12914,6 @@
 
   JSONObject jsobj(&jsarray);
   jsobj.AddProperty("name", String::Handle(target_name()).ToCString());
-  // TODO(turnidge): Use AddLocation instead.
   jsobj.AddProperty("tokenPos", token_pos);
   // TODO(rmacnak): Figure out how to stringify DeoptReasons().
   // jsobj.AddProperty("deoptReasons", ...);
@@ -12618,6 +12941,35 @@
 }
 
 
+void ICData::PrintToJSONArrayNew(const JSONArray& jsarray,
+                                 intptr_t token_pos,
+                                 bool is_static_call) const {
+  Isolate* isolate = Isolate::Current();
+  Class& cls = Class::Handle();
+  Function& func = Function::Handle();
+
+  JSONObject jsobj(&jsarray);
+  jsobj.AddProperty("name", String::Handle(target_name()).ToCString());
+  jsobj.AddProperty("tokenPos", token_pos);
+  // TODO(rmacnak): Figure out how to stringify DeoptReasons().
+  // jsobj.AddProperty("deoptReasons", ...);
+
+  JSONArray cache_entries(&jsobj, "cacheEntries");
+  for (intptr_t i = 0; i < NumberOfChecks(); i++) {
+    JSONObject cache_entry(&cache_entries);
+    func = GetTargetAt(i);
+    intptr_t count = GetCountAt(i);
+    if (!is_static_call) {
+      intptr_t cid = GetReceiverClassIdAt(i);
+      cls ^= isolate->class_table()->At(cid);
+      cache_entry.AddProperty("receiver", cls);
+    }
+    cache_entry.AddProperty("target", func);
+    cache_entry.AddProperty("count", count);
+  }
+}
+
+
 static Token::Kind RecognizeArithmeticOp(const String& name) {
   ASSERT(name.IsSymbol());
   if (name.raw() == Symbols::Plus().raw()) {
@@ -12660,13 +13012,12 @@
   }
 
   bool initialized = false;
-  Function& t = Function::Handle();
   const intptr_t len = NumberOfChecks();
   GrowableArray<intptr_t> class_ids;
   for (intptr_t i = 0; i < len; i++) {
     if (IsUsedAt(i)) {
       initialized = true;
-      GetCheckAt(i, &class_ids, &t);
+      GetClassIdsAt(i, &class_ids);
       for (intptr_t j = 0; j < class_ids.length(); j++) {
         const intptr_t cid = class_ids[j];
         if ((cid != kSmiCid) && (cid != kMintCid)) {
@@ -12831,7 +13182,10 @@
   const Instructions& instrs = Instructions::Handle(instructions());
   uword code_entry = instrs.EntryPoint();
   const Array& table = Array::Handle(deopt_info_array());
-  ASSERT(!table.IsNull());
+  if (table.IsNull()) {
+    ASSERT(Dart::IsRunningPrecompiledCode());
+    return TypedData::null();
+  }
   // Linear search for the PC offset matching the target PC.
   intptr_t length = DeoptTable::GetLength(table);
   Smi& offset = Smi::Handle();
@@ -13088,7 +13442,6 @@
   INC_STAT(Thread::Current(), total_instr_size, assembler->CodeSize());
   INC_STAT(Thread::Current(), total_code_size, assembler->CodeSize());
 
-  instrs.set_code(code.raw());
   // Copy the instructions into the instruction area and apply all fixups.
   // Embedded pointers are still in handles at this point.
   MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()),
@@ -13097,7 +13450,7 @@
   VerifiedMemory::Accept(region.start(), region.size());
   CPU::FlushICache(instrs.EntryPoint(), instrs.size());
 
-  code.set_compile_timestamp(OS::GetCurrentTimeMicros());
+  code.set_compile_timestamp(OS::GetCurrentMonotonicMicros());
   CodeObservers::NotifyAll(name,
                            instrs.EntryPoint(),
                            assembler->prologue_offset(),
@@ -13122,7 +13475,7 @@
     }
 
     // Hook up Code and Instructions objects.
-    code.set_active_instructions(instrs.raw());
+    code.SetActiveInstructions(instrs.raw());
     code.set_instructions(instrs.raw());
     code.set_is_alive(true);
 
@@ -13164,38 +13517,26 @@
                         assembler,
                         optimized);
   } else {
-    return FinalizeCode("", assembler);
+    return FinalizeCode("", assembler, optimized);
   }
 }
 
 
-// Check if object matches find condition.
-bool Code::FindRawCodeVisitor::FindObject(RawObject* raw_obj) const {
-  uword tags = raw_obj->ptr()->tags_;
-  if (RawObject::ClassIdTag::decode(tags) == kInstructionsCid) {
-    RawInstructions* raw_insts = reinterpret_cast<RawInstructions*>(raw_obj);
-    return RawInstructions::ContainsPC(raw_insts, pc_);
-  }
-  return false;
+bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const {
+  return RawCode::ContainsPC(raw_obj, pc_);
 }
 
 
 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) {
   ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate()));
-  NoSafepointScope no_safepoint;
-  FindRawCodeVisitor visitor(pc);
-  RawInstructions* instr;
-  if (Dart::IsRunningPrecompiledCode()) {
-    // TODO(johnmccutchan): Make code lookup work when running precompiled.
-    UNIMPLEMENTED();
-    return Code::null();
-  }
   if (isolate->heap() == NULL) {
     return Code::null();
   }
-  instr = isolate->heap()->FindObjectInCodeSpace(&visitor);
-  if (instr != Instructions::null()) {
-    return Instructions::Handle(instr).code();
+  NoSafepointScope no_safepoint;
+  SlowFindRawCodeVisitor visitor(pc);
+  RawObject* needle = isolate->heap()->FindOldObject(&visitor);
+  if (needle != Code::null()) {
+    return static_cast<RawCode*>(needle);
   }
   return Code::null();
 }
@@ -13282,20 +13623,21 @@
 }
 
 
+// Called by disassembler.
 RawString* Code::Name() const {
   const Object& obj = Object::Handle(owner());
   if (obj.IsNull()) {
     // Regular stub.
     const char* name = StubCode::NameOfStub(EntryPoint());
     ASSERT(name != NULL);
-    const String& stub_name = String::Handle(String::New(name));
-    return String::Concat(Symbols::StubPrefix(), stub_name);
+    const String& stub_name = String::Handle(Symbols::New(name));
+    return Symbols::FromConcat(Symbols::StubPrefix(), stub_name);
   } else if (obj.IsClass()) {
     // Allocation stub.
     const Class& cls = Class::Cast(obj);
     String& cls_name = String::Handle(cls.Name());
     ASSERT(!cls_name.IsNull());
-    return String::Concat(Symbols::AllocationStubFor(), cls_name);
+    return Symbols::FromConcat(Symbols::AllocationStubFor(), cls_name);
   } else {
     ASSERT(obj.IsFunction());
     // Dart function.
@@ -13345,20 +13687,33 @@
 
 
 void Code::DisableDartCode() const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   ASSERT(IsFunctionCode());
   ASSERT(instructions() == active_instructions());
   const Code& new_code =
       Code::Handle(StubCode::FixCallersTarget_entry()->code());
-  set_active_instructions(new_code.instructions());
+  SetActiveInstructions(new_code.instructions());
 }
 
 
 void Code::DisableStubCode() const {
-ASSERT(IsAllocationStubCode());
+  ASSERT(Thread::Current()->IsMutatorThread());
+  ASSERT(IsAllocationStubCode());
   ASSERT(instructions() == active_instructions());
   const Code& new_code =
       Code::Handle(StubCode::FixAllocationStubTarget_entry()->code());
-  set_active_instructions(new_code.instructions());
+  SetActiveInstructions(new_code.instructions());
+}
+
+
+void Code::SetActiveInstructions(RawInstructions* instructions) const {
+  DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive());
+  // RawInstructions are never allocated in New space and hence a
+  // store buffer update is not needed here.
+  StorePointer(&raw_ptr()->active_instructions_, instructions);
+  StoreNonPointer(&raw_ptr()->entry_point_,
+                  reinterpret_cast<uword>(instructions->ptr()) +
+                  Instructions::HeaderSize());
 }
 
 
@@ -13378,10 +13733,18 @@
     jsobj.AddProperty("kind", "Dart");
   }
   jsobj.AddProperty("_optimized", is_optimized());
+  const Object& obj = Object::Handle(owner());
+  if (obj.IsFunction()) {
+    const Function& func = Function::Cast(obj);
+    jsobj.AddProperty("_intrinsic", func.is_intrinsic());
+    jsobj.AddProperty("_native", func.is_native());
+  } else {
+    jsobj.AddProperty("_intrinsic", false);
+    jsobj.AddProperty("_native", false);
+  }
   if (ref) {
     return;
   }
-  const Object& obj = Object::Handle(owner());
   if (obj.IsFunction()) {
     jsobj.AddProperty("function", obj);
   } else {
@@ -13621,13 +13984,13 @@
   Zone* zone = Thread::Current()->zone();
   const Context& parent_ctx = Context::Handle(parent());
   if (parent_ctx.IsNull()) {
-    return zone->PrintToString("Context@%p num_variables:% " Pd "",
-                               this->raw(), num_variables());
+    return zone->PrintToString("Context num_variables: %" Pd "",
+                               num_variables());
   } else {
     const char* parent_str = parent_ctx.ToCString();
     return zone->PrintToString(
-        "Context@%p num_variables:% " Pd " parent:{ %s }",
-        this->raw(), num_variables(), parent_str);
+        "Context num_variables: %" Pd " parent:{ %s }",
+        num_variables(), parent_str);
   }
 }
 
@@ -13863,6 +14226,16 @@
 }
 
 
+void MegamorphicCache::set_target_name(const String& value) const {
+  StorePointer(&raw_ptr()->target_name_, value.raw());
+}
+
+
+void MegamorphicCache::set_arguments_descriptor(const Array& value) const {
+  StorePointer(&raw_ptr()->args_descriptor_, value.raw());
+}
+
+
 RawMegamorphicCache* MegamorphicCache::New() {
   MegamorphicCache& result = MegamorphicCache::Handle();
   { RawObject* raw = Object::Allocate(MegamorphicCache::kClassId,
@@ -13871,6 +14244,20 @@
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
+  result.set_filled_entry_count(0);
+  return result.raw();
+}
+
+
+RawMegamorphicCache* MegamorphicCache::New(const String& target_name,
+                                           const Array& arguments_descriptor) {
+  MegamorphicCache& result = MegamorphicCache::Handle();
+  { RawObject* raw = Object::Allocate(MegamorphicCache::kClassId,
+                                      MegamorphicCache::InstanceSize(),
+                                      Heap::kOld);
+    NoSafepointScope no_safepoint;
+    result ^= raw;
+  }
   const intptr_t capacity = kInitialCapacity;
   const Array& buckets = Array::Handle(
       Array::New(kEntryLength * capacity, Heap::kOld));
@@ -13881,6 +14268,8 @@
   }
   result.set_buckets(buckets);
   result.set_mask(capacity - 1);
+  result.set_target_name(target_name);
+  result.set_arguments_descriptor(arguments_descriptor);
   result.set_filled_entry_count(0);
   return result.raw();
 }
@@ -13938,7 +14327,9 @@
 
 
 const char* MegamorphicCache::ToCString() const {
-  return "MegamorphicCache";
+  const String& name = String::Handle(target_name());
+  return OS::SCreate(Thread::Current()->zone(),
+                     "MegamorphicCache(%s)", name.ToCString());
 }
 
 
@@ -13946,11 +14337,14 @@
   JSONObject jsobj(stream);
   AddCommonObjectProperties(&jsobj, "Object", ref);
   jsobj.AddServiceId(*this);
+  jsobj.AddProperty("_selector", String::Handle(target_name()).ToCString());
   if (ref) {
     return;
   }
   jsobj.AddProperty("_buckets", Object::Handle(buckets()));
   jsobj.AddProperty("_mask", mask());
+  jsobj.AddProperty("_argumentsDescriptor",
+                    Object::Handle(arguments_descriptor()));
 }
 
 
@@ -14176,9 +14570,9 @@
 }
 
 
-void LanguageError::set_token_pos(intptr_t value) const {
-  ASSERT(value >= 0);
-  StoreNonPointer(&raw_ptr()->token_pos_, value);
+void LanguageError::set_token_pos(intptr_t token_pos) const {
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
 
@@ -14567,7 +14961,7 @@
   }
   const Class& cls = Class::Handle(clazz());
   Type& type = Type::Handle();
-  if (cls.NumTypeArguments() == 0) {
+  if (!cls.IsGeneric()) {
     type = cls.CanonicalType();
   }
   if (type.IsNull()) {
@@ -14711,7 +15105,8 @@
 
 
 bool Instance::IsClosure() const {
-  return Class::IsSignatureClass(clazz());
+  const Class& cls = Class::Handle(clazz());
+  return cls.IsSignatureClass();
 }
 
 
@@ -15124,8 +15519,8 @@
     } else if (bound.IsType()) {
       const Class& cls = Class::Handle(zone, Type::Cast(bound).type_class());
       bound_name = cls.Name();
+      pieces.Add(bound_name);
       if (Type::Cast(bound).arguments() != TypeArguments::null()) {
-        pieces.Add(bound_name);
         pieces.Add(Symbols::OptimizedOut());
       }
     } else {
@@ -15306,8 +15701,8 @@
                             const AbstractType& other,
                             Error* bound_error,
                             Heap::Space space) const {
-  ASSERT(IsResolved());
-  ASSERT(other.IsResolved());
+  ASSERT(IsFinalized());
+  ASSERT(other.IsFinalized());
   if (IsMalformed() || other.IsMalformed()) {
     // Malformed types involved in subtype tests should be handled specially
     // by the caller. Malformed types should only be encountered here in a
@@ -15338,6 +15733,11 @@
     if (Equals(other)) {
       return true;
     }
+    // Redundant check if other type is equal to the upper bound of this type.
+    if (IsBoundedType() &&
+        AbstractType::Handle(BoundedType::Cast(*this).bound()).Equals(other)) {
+      return true;
+    }
     return false;  // TODO(regis): We should return "maybe after instantiation".
   }
   // Type parameters cannot be handled by Class::TypeTest().
@@ -15361,6 +15761,11 @@
       }
     }
     const AbstractType& bound = AbstractType::Handle(type_param.bound());
+    // We may be checking bounds at finalization time and can encounter
+    // a still unfinalized bound. Finalizing the bound here may lead to cycles.
+    if (!bound.IsFinalized()) {
+      return false;    // TODO(regis): Return "maybe after instantiation".
+    }
     if (bound.IsMoreSpecificThan(other, bound_error)) {
       return true;
     }
@@ -15404,12 +15809,12 @@
 
 
 RawType* Type::DynamicType() {
-  return Object::dynamic_type();
+  return Object::dynamic_type().raw();
 }
 
 
 RawType* Type::VoidType() {
-  return Object::void_type();
+  return Object::void_type().raw();
 }
 
 
@@ -15480,15 +15885,6 @@
 
 RawType* Type::NewNonParameterizedType(const Class& type_class) {
   ASSERT(type_class.NumTypeArguments() == 0);
-  if (type_class.raw() == Object::dynamic_class()) {
-    // If the dynamic type has not been setup in the VM isolate, then we need
-    // to allocate it here.
-    if (Object::dynamic_type() != reinterpret_cast<RawType*>(RAW_NULL)) {
-      ASSERT(Type::Handle(Object::dynamic_type()).IsFinalized());
-      return Object::dynamic_type();
-    }
-    ASSERT(Isolate::Current() == Dart::vm_isolate());
-  }
   Type& type = Type::Handle(type_class.CanonicalType());
   if (type.IsNull()) {
     const TypeArguments& no_type_arguments = TypeArguments::Handle();
@@ -15759,6 +16155,13 @@
     for (intptr_t i = 0; i < from_index; i++) {
       type_arg = type_args.TypeAt(i);
       other_type_arg = other_type_args.TypeAt(i);
+      // Ignore bounds of bounded types.
+      while (type_arg.IsBoundedType()) {
+        type_arg = BoundedType::Cast(type_arg).type();
+      }
+      while (other_type_arg.IsBoundedType()) {
+        other_type_arg = BoundedType::Cast(other_type_arg).type();
+      }
       ASSERT(type_arg.IsEquivalent(other_type_arg, trail));
     }
   }
@@ -15828,16 +16231,23 @@
   Type& type = Type::Handle(zone);
   const Class& cls = Class::Handle(zone, type_class());
   if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) {
-    return Object::dynamic_type();
+    return Object::dynamic_type().raw();
   }
   // Fast canonical lookup/registry for simple types.
-  if (cls.NumTypeArguments() == 0) {
+  if (!cls.IsGeneric()) {
     type = cls.CanonicalType();
     if (type.IsNull()) {
       ASSERT(!cls.raw()->IsVMHeapObject() || (isolate == Dart::vm_isolate()));
-      cls.set_canonical_types(*this);
-      SetCanonical();
-      return this->raw();
+      // Canonicalize the type arguments of the supertype, if any.
+      TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
+      type_args = type_args.Canonicalize(trail);
+      set_arguments(type_args);
+      type = cls.CanonicalType();  // May be set while canonicalizing type args.
+      if (type.IsNull()) {
+        cls.set_canonical_types(*this);
+        SetCanonical();
+        return this->raw();
+      }
     }
     ASSERT(this->Equals(type));
     ASSERT(type.IsCanonical());
@@ -15989,7 +16399,7 @@
 
 
 void Type::set_token_pos(intptr_t token_pos) const {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -16420,7 +16830,7 @@
 
 
 void TypeParameter::set_token_pos(intptr_t token_pos) const {
-  ASSERT(token_pos >= 0);
+  ASSERT(Scanner::ValidSourcePosition(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -16581,13 +16991,20 @@
       // Instantiated upper_bound may not be finalized. See comment above.
     }
     if (bound_error->IsNull()) {
-      if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) &&
-          bound_error->IsNull()) {
+      if (bounded_type.IsBeingFinalized() ||
+          upper_bound.IsBeingFinalized() ||
+          (!type_param.CheckBound(bounded_type, upper_bound, bound_error) &&
+           bound_error->IsNull())) {
         // We cannot determine yet whether the bounded_type is below the
-        // upper_bound, because one or both of them is still uninstantiated.
-        ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated());
-        // Postpone bound check by returning a new BoundedType with partially
-        // instantiated bounded_type and upper_bound, but keeping type_param.
+        // upper_bound, because one or both of them is still being finalized or
+        // uninstantiated.
+        ASSERT(bounded_type.IsBeingFinalized() ||
+               upper_bound.IsBeingFinalized() ||
+               !bounded_type.IsInstantiated() ||
+               !upper_bound.IsInstantiated());
+        // Postpone bound check by returning a new BoundedType with unfinalized
+        // or partially instantiated bounded_type and upper_bound, but keeping
+        // type_param.
         bounded_type = BoundedType::New(bounded_type, upper_bound, type_param);
       }
     }
@@ -16771,9 +17188,9 @@
 
 
 const char* Integer::ToCString() const {
-  // Integer is an interface. No instances of Integer should exist.
-  UNREACHABLE();
-  return "Integer";
+  // Integer is an interface. No instances of Integer should exist except null.
+  ASSERT(IsNull());
+  return "NULL Integer";
 }
 
 
@@ -17023,15 +17440,13 @@
     const int64_t right_value = other.AsInt64Value();
     switch (operation) {
       case Token::kADD: {
-        if (((left_value < 0) != (right_value < 0)) ||
-            ((left_value + right_value) < 0) == (left_value < 0)) {
+        if (!Utils::WillAddOverflow(left_value, right_value)) {
           return Integer::New(left_value + right_value, space);
         }
         break;
       }
       case Token::kSUB: {
-        if (((left_value < 0) == (right_value < 0)) ||
-            ((left_value - right_value) < 0) == (left_value < 0)) {
+        if (!Utils::WillSubOverflow(left_value, right_value)) {
           return Integer::New(left_value - right_value, space);
         }
         break;
@@ -17565,7 +17980,7 @@
     ASSERT(!digits_.IsNull());
     set_digits(digits_);
   } else {
-    ASSERT(digits() == TypedData::EmptyUint32Array(Isolate::Current()));
+    ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current()));
   }
   return true;
 }
@@ -17587,7 +18002,7 @@
   result.SetNeg(false);
   result.SetUsed(0);
   result.set_digits(
-      TypedData::Handle(zone, TypedData::EmptyUint32Array(isolate)));
+      TypedData::Handle(zone, TypedData::EmptyUint32Array(thread)));
   return result.raw();
 }
 
@@ -17621,7 +18036,7 @@
   } else {
     neg = false;
     result.set_digits(
-        TypedData::Handle(zone, TypedData::EmptyUint32Array(isolate)));
+        TypedData::Handle(zone, TypedData::EmptyUint32Array(thread)));
   }
   result.SetNeg(neg);
   result.SetUsed(used);
@@ -19092,11 +19507,9 @@
     Dart_WeakPersistentHandleFinalizer callback) {
   ASSERT((callback != NULL && peer != NULL) ||
          (callback == NULL && peer == NULL));
-  const bool is_prologue = false;
   // TODO(19482): Make API consistent for external size of strings/typed data.
   const intptr_t external_size = 0;
   return FinalizablePersistentHandle::New(Isolate::Current(),
-                                          is_prologue,
                                           referent,
                                           peer,
                                           callback,
@@ -20092,10 +20505,21 @@
   if (ref) {
     return;
   }
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  intptr_t limit = offset + count;
+  ASSERT(limit <= Length());
   {
     JSONArray jsarr(&jsobj, "elements");
     Object& element = Object::Handle();
-    for (intptr_t index = 0; index < Length(); index++) {
+    for (intptr_t index = offset; index < limit; index++) {
       element = At(index);
       jsarr.AddValue(element);
     }
@@ -20330,10 +20754,21 @@
   if (ref) {
     return;
   }
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  intptr_t limit = offset + count;
+  ASSERT(limit <= Length());
   {
     JSONArray jsarr(&jsobj, "elements");
     Object& element = Object::Handle();
-    for (intptr_t index = 0; index < Length(); index++) {
+    for (intptr_t index = offset; index < limit; index++) {
       element = At(index);
       jsarr.AddValue(element);
     }
@@ -20436,16 +20871,31 @@
   if (ref) {
     return;
   }
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  intptr_t limit = offset + count;
+  ASSERT(limit <= Length());
   {
     JSONArray jsarr(&jsobj, "associations");
     Object& object = Object::Handle();
     LinkedHashMap::Iterator iterator(*this);
-    while (iterator.MoveNext()) {
-      JSONObject jsassoc(&jsarr);
-      object = iterator.CurrentKey();
-      jsassoc.AddProperty("key", object);
-      object = iterator.CurrentValue();
-      jsassoc.AddProperty("value", object);
+    int i = 0;
+    while (iterator.MoveNext() && i < limit) {
+      if (i >= offset) {
+        JSONObject jsassoc(&jsarr);
+        object = iterator.CurrentKey();
+        jsassoc.AddProperty("key", object);
+        object = iterator.CurrentValue();
+        jsassoc.AddProperty("value", object);
+      }
+      i++;
     }
   }
 }
@@ -20807,14 +21257,16 @@
 }
 
 
-RawTypedData* TypedData::EmptyUint32Array(Isolate* isolate) {
+RawTypedData* TypedData::EmptyUint32Array(Thread* thread) {
+  ASSERT(thread != NULL);
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   ASSERT(isolate->object_store() != NULL);
   if (isolate->object_store()->empty_uint32_array() != TypedData::null()) {
     // Already created.
     return isolate->object_store()->empty_uint32_array();
   }
-  const TypedData& array = TypedData::Handle(isolate->current_zone(),
+  const TypedData& array = TypedData::Handle(thread->zone(),
       TypedData::New(kTypedDataUint32ArrayCid, 0, Heap::kOld));
   isolate->object_store()->set_empty_uint32_array(array);
   return array.raw();
@@ -20837,12 +21289,23 @@
   if (ref) {
     return;
   }
-
-  {
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  if (count == 0) {
+    jsobj.AddProperty("bytes", "");
+  } else {
     NoSafepointScope no_safepoint;
     jsobj.AddPropertyBase64("bytes",
-                            reinterpret_cast<const uint8_t*>(DataAddr(0)),
-                            LengthInBytes());
+                            reinterpret_cast<const uint8_t*>(
+                                DataAddr(offset * ElementSizeInBytes())),
+                            count * ElementSizeInBytes());
   }
 }
 
@@ -20888,12 +21351,23 @@
   if (ref) {
     return;
   }
-
-  {
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  if (count == 0) {
+    jsobj.AddProperty("bytes", "");
+  } else {
     NoSafepointScope no_safepoint;
     jsobj.AddPropertyBase64("bytes",
-                            reinterpret_cast<const uint8_t*>(DataAddr(0)),
-                            LengthInBytes());
+                            reinterpret_cast<const uint8_t*>(
+                                DataAddr(offset * ElementSizeInBytes())),
+                            count * ElementSizeInBytes());
   }
 }
 
@@ -21125,7 +21599,7 @@
   const String& url = String::Handle(zone, script.url());
   intptr_t line = -1;
   intptr_t column = -1;
-  if (token_pos > 0) {
+  if (token_pos >= 0) {
     if (script.HasSource()) {
       script.GetTokenLocation(token_pos, &line, &column);
     } else {
@@ -21151,6 +21625,23 @@
 }
 
 
+static intptr_t PrintOneStacktraceNoCode(Zone* zone,
+                                         GrowableArray<char*>* frame_strings,
+                                         const Function& function,
+                                         intptr_t frame_index) {
+  const Script& script = Script::Handle(zone, function.script());
+  const String& function_name =
+      String::Handle(zone, function.QualifiedUserVisibleName());
+  const String& url = String::Handle(zone, script.url());
+  char* chars = NULL;
+  chars = OS::SCreate(zone,
+      "#%-6" Pd " %s (%s)\n",
+      frame_index, function_name.ToCString(), url.ToCString());
+  frame_strings->Add(chars);
+  return strlen(chars);
+}
+
+
 const char* Stacktrace::ToCStringInternal(intptr_t* frame_index,
                                           intptr_t max_frames) const {
   Zone* zone = Thread::Current()->zone();
@@ -21163,7 +21654,8 @@
   for (intptr_t i = 0; (i < Length()) && (*frame_index < max_frames); i++) {
     function = FunctionAtFrame(i);
     if (function.IsNull()) {
-      // Check if null function object indicates a stack trace overflow.
+      // Check if null function object indicates a gap in a StackOverflow or
+      // OutOfMemory trace.
       if ((i < (Length() - 1)) &&
           (FunctionAtFrame(i + 1) != Function::null())) {
         const char* kTruncated = "...\n...\n";
@@ -21173,31 +21665,55 @@
         frame_strings.Add(chars);
         total_len += truncated_len;
       }
-    } else if (function.is_visible() || FLAG_show_invisible_frames) {
+    } else {
       code = CodeAtFrame(i);
       ASSERT(function.raw() == code.function());
       uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i));
       if (code.is_optimized() && expand_inlined()) {
         // Traverse inlined frames.
-        for (InlinedFunctionsIterator it(code, pc);
-             !it.Done() && (*frame_index < max_frames); it.Advance()) {
-          function = it.function();
-          if (function.is_visible() || FLAG_show_invisible_frames) {
-            code = it.code();
-            ASSERT(function.raw() == code.function());
-            uword pc = it.pc();
-            ASSERT(pc != 0);
-            ASSERT(code.EntryPoint() <= pc);
-            ASSERT(pc < (code.EntryPoint() + code.Size()));
-            total_len += PrintOneStacktrace(
-                zone, &frame_strings, pc, function, code, *frame_index);
-            (*frame_index)++;  // To account for inlined frames.
+        if (Compiler::allow_recompilation()) {
+          for (InlinedFunctionsIterator it(code, pc);
+               !it.Done() && (*frame_index < max_frames); it.Advance()) {
+            function = it.function();
+            if (function.is_visible() || FLAG_show_invisible_frames) {
+              code = it.code();
+              ASSERT(function.raw() == code.function());
+              uword pc = it.pc();
+              ASSERT(pc != 0);
+              ASSERT(code.EntryPoint() <= pc);
+              ASSERT(pc < (code.EntryPoint() + code.Size()));
+              total_len += PrintOneStacktrace(
+                  zone, &frame_strings, pc, function, code, *frame_index);
+              (*frame_index)++;  // To account for inlined frames.
+            }
+          }
+        } else {
+          // Precompilation: we don't have deopt info, so we don't know the
+          // source position of inlined functions, but we can still name them.
+          intptr_t offset = Smi::Value(PcOffsetAtFrame(i));
+          // The PC of frames below the top frame is a call's return address,
+          // which can belong to a different inlining interval than the call.
+          intptr_t effective_offset = offset - 1;
+          GrowableArray<Function*> inlined_functions;
+          code.GetInlinedFunctionsAt(effective_offset, &inlined_functions);
+          ASSERT(inlined_functions.length() >= 1);  // At least the inliner.
+          for (intptr_t j = 0; j < inlined_functions.length(); j++) {
+            Function* inlined_function = inlined_functions[j];
+            ASSERT(inlined_function != NULL);
+            ASSERT(!inlined_function->IsNull());
+            if (inlined_function->is_visible() || FLAG_show_invisible_frames) {
+              total_len += PrintOneStacktraceNoCode(
+                  zone, &frame_strings, *inlined_function, *frame_index);
+              (*frame_index)++;
+            }
           }
         }
       } else {
-        total_len += PrintOneStacktrace(
-            zone, &frame_strings, pc, function, code, *frame_index);
-        (*frame_index)++;
+        if (function.is_visible() || FLAG_show_invisible_frames) {
+          total_len += PrintOneStacktrace(
+              zone, &frame_strings, pc, function, code, *frame_index);
+          (*frame_index)++;
+        }
       }
     }
   }
@@ -21455,15 +21971,16 @@
 
 
 RawUserTag* UserTag::New(const String& label, Heap::Space space) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
   // Canonicalize by name.
-  UserTag& result = UserTag::Handle(FindTagInIsolate(isolate, label));
+  UserTag& result = UserTag::Handle(FindTagInIsolate(thread, label));
   if (!result.IsNull()) {
     // Tag already exists, return existing instance.
     return result.raw();
   }
-  if (TagTableIsFull(isolate)) {
+  if (TagTableIsFull(thread)) {
     const String& error = String::Handle(
         String::NewFormatted("UserTag instance limit (%" Pd ") reached.",
                              UserTags::kMaxUserTags));
@@ -21480,7 +21997,7 @@
     result ^= raw;
   }
   result.set_label(label);
-  AddTagToIsolate(isolate, result);
+  AddTagToIsolate(thread, result);
   return result.raw();
 }
 
@@ -21503,12 +22020,14 @@
 }
 
 
-RawUserTag* UserTag::FindTagInIsolate(Isolate* isolate, const String& label) {
+RawUserTag* UserTag::FindTagInIsolate(Thread* thread, const String& label) {
+  Isolate* isolate = thread->isolate();
+  Zone* zone = thread->zone();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
   const GrowableObjectArray& tag_table = GrowableObjectArray::Handle(
-      isolate->current_zone(), isolate->tag_table());
-  UserTag& other = UserTag::Handle(isolate->current_zone());
-  String& tag_label = String::Handle(isolate->current_zone());
+      zone, isolate->tag_table());
+  UserTag& other = UserTag::Handle(zone);
+  String& tag_label = String::Handle(zone);
   for (intptr_t i = 0; i < tag_table.Length(); i++) {
     other ^= tag_table.At(i);
     ASSERT(!other.IsNull());
@@ -21522,14 +22041,16 @@
 }
 
 
-void UserTag::AddTagToIsolate(Isolate* isolate, const UserTag& tag) {
+void UserTag::AddTagToIsolate(Thread* thread, const UserTag& tag) {
+  Isolate* isolate = thread->isolate();
+  Zone* zone = thread->zone();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
   const GrowableObjectArray& tag_table = GrowableObjectArray::Handle(
-      isolate->current_zone(), isolate->tag_table());
-  ASSERT(!TagTableIsFull(isolate));
+      zone, isolate->tag_table());
+  ASSERT(!TagTableIsFull(thread));
 #if defined(DEBUG)
   // Verify that no existing tag has the same tag id.
-  UserTag& other = UserTag::Handle(isolate->current_zone());
+  UserTag& other = UserTag::Handle(thread->zone());
   for (intptr_t i = 0; i < tag_table.Length(); i++) {
     other ^= tag_table.At(i);
     ASSERT(!other.IsNull());
@@ -21546,10 +22067,11 @@
 }
 
 
-bool UserTag::TagTableIsFull(Isolate* isolate) {
+bool UserTag::TagTableIsFull(Thread* thread) {
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate->tag_table() != GrowableObjectArray::null());
   const GrowableObjectArray& tag_table = GrowableObjectArray::Handle(
-      isolate->current_zone(), isolate->tag_table());
+      thread->zone(), isolate->tag_table());
   ASSERT(tag_table.Length() <= UserTags::kMaxUserTags);
   return tag_table.Length() == UserTags::kMaxUserTags;
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 1193686..d67b06a 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -468,17 +468,29 @@
     return *branch_offset_error_;
   }
 
+  static const LanguageError& speculative_inlining_error() {
+    ASSERT(speculative_inlining_error_ != NULL);
+    return *speculative_inlining_error_;
+  }
+
   static const Array& vm_isolate_snapshot_object_table() {
     ASSERT(vm_isolate_snapshot_object_table_ != NULL);
     return *vm_isolate_snapshot_object_table_;
   }
+  static const Type& dynamic_type() {
+    ASSERT(dynamic_type_ != NULL);
+    return *dynamic_type_;
+  }
+  static const Type& void_type() {
+    ASSERT(void_type_ != NULL);
+    return *void_type_;
+  }
+
   static void InitVmIsolateSnapshotObjectTable(intptr_t len);
 
   static RawClass* class_class() { return class_class_; }
   static RawClass* dynamic_class() { return dynamic_class_; }
   static RawClass* void_class() { return void_class_; }
-  static RawType* dynamic_type() { return dynamic_type_; }
-  static RawType* void_type() { return void_type_; }
   static RawClass* unresolved_class_class() { return unresolved_class_class_; }
   static RawClass* type_arguments_class() { return type_arguments_class_; }
   static RawClass* patch_class_class() { return patch_class_class_; }
@@ -740,8 +752,6 @@
   static RawClass* class_class_;  // Class of the Class vm object.
   static RawClass* dynamic_class_;  // Class of the 'dynamic' type.
   static RawClass* void_class_;  // Class of the 'void' type.
-  static RawType* dynamic_type_;  // Class of the 'dynamic' type.
-  static RawType* void_type_;  // Class of the 'void' type.
   static RawClass* unresolved_class_class_;  // Class of UnresolvedClass.
   static RawClass* type_arguments_class_;  // Class of TypeArguments vm object.
   static RawClass* patch_class_class_;  // Class of the PatchClass vm object.
@@ -797,7 +807,10 @@
   static Smi* smi_illegal_cid_;
   static LanguageError* snapshot_writer_error_;
   static LanguageError* branch_offset_error_;
+  static LanguageError* speculative_inlining_error_;
   static Array* vm_isolate_snapshot_object_table_;
+  static Type* dynamic_type_;
+  static Type* void_type_;
 
   friend void ClassTable::Register(const Class& cls);
   friend void RawObject::Validate(Isolate* isolate) const;
@@ -1051,10 +1064,7 @@
   // Note this returns false for mixin application aliases.
   bool IsMixinApplication() const;
 
-  RawClass* patch_class() const {
-    return raw_ptr()->patch_class_;
-  }
-  void set_patch_class(const Class& patch_class) const;
+  RawClass* GetPatchClass() const;
 
   // Interfaces is an array of Types.
   RawArray* interfaces() const { return raw_ptr()->interfaces_; }
@@ -1137,8 +1147,6 @@
   void SetFields(const Array& value) const;
   void AddField(const Field& field) const;
   void AddFields(const GrowableArray<const Field*>& fields) const;
-  intptr_t FindFieldIndex(const Field& field) const;
-  RawField* FieldFromIndex(intptr_t idx) const;
 
   // Returns an array of all fields of this class and its superclasses indexed
   // by offset in words.
@@ -1152,20 +1160,10 @@
   void SetFunctions(const Array& value) const;
   void AddFunction(const Function& function) const;
   void RemoveFunction(const Function& function) const;
-  intptr_t FindFunctionIndex(const Function& function) const;
   RawFunction* FunctionFromIndex(intptr_t idx) const;
   intptr_t FindImplicitClosureFunctionIndex(const Function& needle) const;
   RawFunction* ImplicitClosureFunctionFromIndex(intptr_t idx) const;
 
-  RawGrowableObjectArray* closures() const {
-    return raw_ptr()->closure_functions_;
-  }
-  void set_closures(const GrowableObjectArray& value) const;
-  void AddClosureFunction(const Function& function) const;
-  RawFunction* LookupClosureFunction(intptr_t token_pos) const;
-  intptr_t FindClosureIndex(const Function& function) const;
-  RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;
-
   RawFunction* LookupDynamicFunction(const String& name) const;
   RawFunction* LookupDynamicFunctionAllowPrivate(const String& name) const;
   RawFunction* LookupStaticFunction(const String& name) const;
@@ -1178,7 +1176,6 @@
   RawFunction* LookupFunctionAllowPrivate(const String& name) const;
   RawFunction* LookupGetterFunction(const String& name) const;
   RawFunction* LookupSetterFunction(const String& name) const;
-  RawFunction* LookupFunctionAtToken(intptr_t token_pos) const;
   RawField* LookupInstanceField(const String& name) const;
   RawField* LookupStaticField(const String& name) const;
   RawField* LookupField(const String& name) const;
@@ -1237,6 +1234,8 @@
 
   void set_is_prefinalized() const;
 
+  void ResetFinalization() const;
+
   bool is_marked_for_parsing() const {
     return MarkedForParsingBit::decode(raw_ptr()->state_bits_);
   }
@@ -1269,7 +1268,7 @@
   bool is_allocated() const {
     return IsAllocatedBit::decode(raw_ptr()->state_bits_);
   }
-  void set_is_allocated() const;
+  void set_is_allocated(bool value) const;
 
   uint16_t num_native_fields() const {
     return raw_ptr()->num_native_fields_;
@@ -1355,7 +1354,7 @@
   // leaf method, ...).
   void RegisterCHACode(const Code& code);
 
-  void DisableCHAOptimizedCode();
+  void DisableCHAOptimizedCode(const Class& subclass);
 
   RawArray* cha_codes() const { return raw_ptr()->cha_codes_; }
   void set_cha_codes(const Array& value) const;
@@ -1485,6 +1484,7 @@
   friend class Object;
   friend class Type;
   friend class Intrinsifier;
+  friend class Precompiler;
 };
 
 
@@ -1718,8 +1718,8 @@
 class PatchClass : public Object {
  public:
   RawClass* patched_class() const { return raw_ptr()->patched_class_; }
-  RawClass* source_class() const { return raw_ptr()->source_class_; }
-  RawScript* Script() const;
+  RawClass* origin_class() const { return raw_ptr()->origin_class_; }
+  RawScript* script() const { return raw_ptr()->script_; }
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawPatchClass));
@@ -1730,11 +1730,15 @@
   }
 
   static RawPatchClass* New(const Class& patched_class,
-                            const Class& source_class);
+                            const Class& origin_class);
+
+  static RawPatchClass* New(const Class& patched_class,
+                            const Script& source);
 
  private:
   void set_patched_class(const Class& value) const;
-  void set_source_class(const Class& value) const;
+  void set_origin_class(const Class& value) const;
+  void set_script(const Script& value) const;
 
   static RawPatchClass* New();
 
@@ -1744,11 +1748,20 @@
 
 
 // Object holding information about an IC: test classes and their
-// corresponding targets.
+// corresponding targets. The owner of the ICData can be either the function
+// or the original ICData object. In case of background compilation we
+// copy the ICData in a child object, thus freezing it during background
+// compilation. Code may contain only original ICData objects.
 class ICData : public Object {
  public:
-  RawFunction* owner() const {
-    return raw_ptr()->owner_;
+  RawFunction* Owner() const;
+
+  RawICData* Original() const;
+
+  void SetOriginal(const ICData& value) const;
+
+  bool IsOriginal() const {
+    return Original() == this->raw();
   }
 
   RawString* target_name() const {
@@ -1871,10 +1884,11 @@
 
   // Retrieving checks.
 
-  // TODO(srdjan): GetCheckAt without target.
   void GetCheckAt(intptr_t index,
                   GrowableArray<intptr_t>* class_ids,
                   Function* target) const;
+  void GetClassIdsAt(intptr_t index, GrowableArray<intptr_t>* class_ids) const;
+
   // Only for 'num_args_checked == 1'.
   void GetOneClassCheckAt(intptr_t index,
                           intptr_t* class_id,
@@ -1916,6 +1930,12 @@
                         intptr_t num_args_tested);
   static RawICData* NewFrom(const ICData& from, intptr_t num_args_tested);
 
+  // Generates a new ICData with descriptor data copied (shallow clone).
+  // Entry array of the result is the same as in 'from'. Once entry array is
+  // created, it can only change the 'count', all other properties are invariant
+  // (target, cids, number of checks).
+  static RawICData* CloneDescriptor(const ICData& from);
+
   static intptr_t TestEntryLengthFor(intptr_t num_args);
 
   static intptr_t TargetIndexFor(intptr_t num_args) {
@@ -2006,6 +2026,16 @@
   void PrintToJSONArray(const JSONArray& jsarray,
                         intptr_t token_pos,
                         bool is_static_call) const;
+  void PrintToJSONArrayNew(const JSONArray& jsarray,
+                           intptr_t token_pos,
+                           bool is_static_call) const;
+
+  // Initialize the preallocated empty ICData entry arrays.
+  static void InitOnce();
+
+  enum {
+    kCachedICDataArrayCount = 4
+  };
 
  private:
   static RawICData* New();
@@ -2019,7 +2049,7 @@
   void set_arguments_descriptor(const Array& value) const;
   void set_deopt_id(intptr_t value) const;
   void SetNumArgsTested(intptr_t value) const;
-  void set_ic_data(const Array& value) const;
+  void set_ic_data_array(const Array& value) const;
   void set_state_bits(uint32_t bits) const;
 
   enum {
@@ -2046,10 +2076,23 @@
 #endif  // DEBUG
 
   intptr_t TestEntryLength() const;
-  void WriteSentinel(const Array& data) const;
+  static RawArray* NewNonCachedEmptyICDataArray(intptr_t num_args_tested);
+  static RawArray* NewEmptyICDataArray(intptr_t num_args_tested);
+  static RawICData* NewDescriptor(Zone* zone,
+                                  const Function& owner,
+                                  const String& target_name,
+                                  const Array& arguments_descriptor,
+                                  intptr_t deopt_id,
+                                  intptr_t num_args_tested);
+
+  static void WriteSentinel(const Array& data, intptr_t test_entry_length);
+
+  // A cache of VM heap allocated preinitialized empty ic data entry arrays.
+  static RawArray* cached_icdata_arrays_[kCachedICDataArrayCount];
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, Object);
   friend class Class;
+  friend class SnapshotWriter;
 };
 
 
@@ -2111,12 +2154,16 @@
   RawClass* Owner() const;
   RawClass* origin() const;
   RawScript* script() const;
+  RawObject* RawOwner() const { return raw_ptr()->owner_; }
 
   RawJSRegExp* regexp() const;
   intptr_t string_specialization_cid() const;
   void SetRegExpData(const JSRegExp& regexp,
                      intptr_t string_specialization_cid) const;
 
+  RawString* native_name() const;
+  void set_native_name(const String& name) const;
+
   RawAbstractType* result_type() const { return raw_ptr()->result_type_; }
   void set_result_type(const AbstractType& value) const;
 
@@ -2132,7 +2179,9 @@
   RawArray* parameter_names() const { return raw_ptr()->parameter_names_; }
   void set_parameter_names(const Array& value) const;
 
+  // Not thread-safe; must be called in the main thread.
   // Sets function's code and code's function.
+  void InstallOptimizedCode(const Code& code, bool is_osr) const;
   void AttachCode(const Code& value) const;
   void SetInstructions(const Code& value) const;
   void ClearCode() const;
@@ -2165,6 +2214,8 @@
   RawContextScope* context_scope() const;
   void set_context_scope(const ContextScope& value) const;
 
+  RawField* LookupImplicitGetterSetterField() const;
+
   // Enclosing function of this local function.
   RawFunction* parent_function() const;
 
@@ -2199,6 +2250,7 @@
   // Return the closure function implicitly created for this function.
   // If none exists yet, create one and remember it.
   RawFunction* ImplicitClosureFunction() const;
+  void DropUncompiledImplicitClosureFunction() const;
 
   // Return the closure implicitly created for this function.
   // If none exists yet, create one and remember it.
@@ -2328,6 +2380,8 @@
     return raw_ptr()->usage_counter_;
   }
   void set_usage_counter(intptr_t value) const {
+    // TODO(Srdjan): Assert that this is thread-safe, i.e., only
+    // set from mutator-thread or while at a safepoint (e.g., during marking).
     StoreNonPointer(&raw_ptr()->usage_counter_, value);
   }
 
@@ -2570,6 +2624,9 @@
                                       const Script& script,
                                       bool is_static);
 
+  RawFunction* CreateMethodExtractor(const String& getter_name) const;
+  RawFunction* GetMethodExtractor(const String& getter_name) const;
+
   // Allocate new function object, clone values from this function. The
   // owner of the clone is new_owner.
   RawFunction* Clone(const Class& new_owner) const;
@@ -2585,8 +2642,11 @@
   void SaveICDataMap(
       const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data,
       const Array& edge_counters_array) const;
+  // Uses saved ICData to populate the table 'deopt_id_to_ic_data'. Clone
+  // descriptors if 'clone_descriptors' true.
   void RestoreICDataMap(
-      ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data) const;
+      ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
+      bool clone_descriptors) const;
 
   RawArray* ic_data_array() const;
   void ClearICDataArray() const;
@@ -2594,10 +2654,6 @@
   // Sets deopt reason in all ICData-s with given deopt_id.
   void SetDeoptReasonForAll(intptr_t deopt_id, ICData::DeoptReasonId reason);
 
-  static const int kCtorPhaseInit = 1 << 0;
-  static const int kCtorPhaseBody = 1 << 1;
-  static const int kCtorPhaseAll = (kCtorPhaseInit | kCtorPhaseBody);
-
   void set_modifier(RawFunction::AsyncModifier value) const;
 
   // static: Considered during class-side or top-level resolution rather than
@@ -2655,6 +2711,7 @@
 
  private:
   void set_ic_data_array(const Array& value) const;
+  void SetInstructionsSafe(const Code& value) const;
 
   enum KindTagBits {
     kKindTagPos = 0,
@@ -2821,14 +2878,21 @@
   bool is_reflectable() const {
     return ReflectableBit::decode(raw_ptr()->kind_bits_);
   }
+  void set_is_reflectable(bool value) const {
+    set_kind_bits(ReflectableBit::update(value, raw_ptr()->kind_bits_));
+  }
   bool is_double_initialized() const {
     return DoubleInitializedBit::decode(raw_ptr()->kind_bits_);
   }
+  // Called in parser after allocating field, immutable property otherwise.
+  // Marks fields that are initialized with a simple double constant.
   void set_is_double_initialized(bool value) const {
+    ASSERT(Thread::Current()->IsMutatorThread());
     set_kind_bits(DoubleInitializedBit::update(value, raw_ptr()->kind_bits_));
   }
 
   inline intptr_t Offset() const;
+  // Called during class finalization.
   inline void SetOffset(intptr_t offset_in_bytes) const;
 
   inline RawInstance* StaticValue() const;
@@ -2837,9 +2901,12 @@
 
   RawClass* owner() const;
   RawClass* origin() const;  // Either mixin class, or same as owner().
+  RawScript* script() const;
+  RawObject* RawOwner() const { return raw_ptr()->owner_; }
 
   RawAbstractType* type() const  { return raw_ptr()->type_; }
-  void set_type(const AbstractType& value) const;
+  // Used by class finalizer, otherwise initialized in constructor.
+  void SetFieldType(const AbstractType& value) const;
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawField));
@@ -2851,8 +2918,15 @@
                        bool is_const,
                        bool is_reflectable,
                        const Class& owner,
+                       const AbstractType& type,
                        intptr_t token_pos);
 
+  static RawField* NewTopLevel(const String& name,
+                               bool is_final,
+                               bool is_const,
+                               const Object& owner,
+                               intptr_t token_pos);
+
   // Allocate new field object, clone values from this field. The
   // owner of the clone is new_owner.
   RawField* Clone(const Class& new_owner) const;
@@ -2871,7 +2945,9 @@
   bool has_initializer() const {
     return HasInitializerBit::decode(raw_ptr()->kind_bits_);
   }
+  // Called by parser after allocating field.
   void set_has_initializer(bool has_initializer) const {
+    ASSERT(Thread::Current()->IsMutatorThread());
     set_kind_bits(HasInitializerBit::update(has_initializer,
                                             raw_ptr()->kind_bits_));
   }
@@ -2882,6 +2958,7 @@
   intptr_t guarded_cid() const { return raw_ptr()->guarded_cid_; }
 
   void set_guarded_cid(intptr_t cid) const {
+    ASSERT(Thread::Current()->IsMutatorThread());
     StoreNonPointer(&raw_ptr()->guarded_cid_, cid);
   }
   static intptr_t guarded_cid_offset() {
@@ -2911,17 +2988,14 @@
   const char* GuardedPropertiesAsCString() const;
 
   intptr_t UnboxedFieldCid() const {
-    ASSERT(IsUnboxedField());
     return guarded_cid();
   }
 
-  bool IsUnboxedField() const;
-
-  bool IsPotentialUnboxedField() const;
-
   bool is_unboxing_candidate() const {
     return UnboxingCandidateBit::decode(raw_ptr()->kind_bits_);
   }
+  // Default 'true', set to false once optimizing compiler determines it should
+  // be boxed.
   void set_is_unboxing_candidate(bool b) const {
     set_kind_bits(UnboxingCandidateBit::update(b, raw_ptr()->kind_bits_));
   }
@@ -2944,6 +3018,7 @@
     return raw_ptr()->is_nullable_ == kNullCid;
   }
   void set_is_nullable(bool val) const {
+    ASSERT(Thread::Current()->IsMutatorThread());
     StoreNonPointer(&raw_ptr()->is_nullable_, val ? kNullCid : kIllegalCid);
   }
   static intptr_t is_nullable_offset() {
@@ -3040,9 +3115,6 @@
   void set_is_const(bool value) const {
     set_kind_bits(ConstBit::update(value, raw_ptr()->kind_bits_));
   }
-  void set_is_reflectable(bool value) const {
-    set_kind_bits(ReflectableBit::update(value, raw_ptr()->kind_bits_));
-  }
   void set_owner(const Object& value) const {
     StorePointer(&raw_ptr()->owner_, value.raw());
   }
@@ -3089,8 +3161,8 @@
 
 class TokenStream : public Object {
  public:
-  RawArray* TokenObjects() const;
-  void SetTokenObjects(const Array& value) const;
+  RawGrowableObjectArray* TokenObjects() const;
+  void SetTokenObjects(const GrowableObjectArray& value) const;
 
   RawExternalTypedData* GetStream() const;
   void SetStream(const ExternalTypedData& stream) const;
@@ -3110,7 +3182,11 @@
 
   static RawTokenStream* New(intptr_t length);
   static RawTokenStream* New(const Scanner::GrowableTokenStream& tokens,
-                             const String& private_key);
+                             const String& private_key,
+                             bool use_shared_tokens);
+
+  static void OpenSharedTokenList(Isolate* isolate);
+  static void CloseSharedTokenList(Isolate* isolate);
 
   // The class Iterator encapsulates iteration over the tokens
   // in a TokenStream object.
@@ -3192,7 +3268,8 @@
 
   RawTokenStream* tokens() const { return raw_ptr()->tokens_; }
 
-  void Tokenize(const String& private_key) const;
+  void Tokenize(const String& private_key,
+                bool use_shared_tokens = true) const;
 
   RawLibrary* FindLibrary() const;
   RawString* GetLine(intptr_t line_number,
@@ -3263,6 +3340,8 @@
 class ClassDictionaryIterator : public DictionaryIterator {
  public:
   enum IterationKind {
+    // TODO(hausner): fix call sites that use kIteratePrivate. There is only
+    // one top-level class per library left, not an array to iterate over.
     kIteratePrivate,
     kNoIteratePrivate
   };
@@ -3270,7 +3349,9 @@
   ClassDictionaryIterator(const Library& library,
                           IterationKind kind = kNoIteratePrivate);
 
-  bool HasNext() const { return (next_ix_ < size_) || (anon_ix_ < anon_size_); }
+  bool HasNext() const {
+      return (next_ix_ < size_) || !toplevel_class_.IsNull();
+  }
 
   // Returns a non-null raw class.
   RawClass* GetNextClass();
@@ -3278,9 +3359,7 @@
  private:
   void MoveToNextClass();
 
-  const Array& anon_array_;
-  const int anon_size_;  // Number of anonymous classes to iterate over.
-  int anon_ix_;  // Index of next anonymous class.
+  Class& toplevel_class_;
 
   DISALLOW_COPY_AND_ASSIGN(ClassDictionaryIterator);
 };
@@ -3323,6 +3402,10 @@
   void SetLoadError(const Instance& error) const;
   RawInstance* TransitiveLoadError() const;
 
+  void AddPatchClass(const Class& cls) const;
+  RawClass* GetPatchClass(const String& name) const;
+  void RemovePatchClass(const Class& cls) const;
+
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawLibrary));
   }
@@ -3376,17 +3459,23 @@
   void AddExport(const Namespace& ns) const;
 
   void AddClassMetadata(const Class& cls,
-                        const Class& toplevel_class,
+                        const Object& tl_owner,
                         intptr_t token_pos) const;
   void AddFieldMetadata(const Field& field, intptr_t token_pos) const;
   void AddFunctionMetadata(const Function& func, intptr_t token_pos) const;
-  void AddLibraryMetadata(const Class& cls, intptr_t token_pos) const;
+  void AddLibraryMetadata(const Object& tl_owner, intptr_t token_pos) const;
   void AddTypeParameterMetadata(const TypeParameter& param,
                                 intptr_t token_pos) const;
   RawObject* GetMetadata(const Object& obj) const;
 
-  intptr_t num_anonymous_classes() const { return raw_ptr()->num_anonymous_; }
-  RawArray* anonymous_classes() const { return raw_ptr()->anonymous_classes_; }
+  RawClass* toplevel_class() const {
+    return raw_ptr()->toplevel_class_;
+  }
+  void set_toplevel_class(const Class& value) const;
+
+  RawGrowableObjectArray* patch_classes() const {
+    return raw_ptr()->patch_classes_;
+  }
 
   // Library imports.
   RawArray* imports() const { return raw_ptr()->imports_; }
@@ -3397,9 +3486,6 @@
   RawLibrary* ImportLibraryAt(intptr_t index) const;
   bool ImportsCorelib() const;
 
-  RawFunction* LookupFunctionInScript(const Script& script,
-                                      intptr_t token_pos) const;
-
   // Resolving native methods for script loaded in the library.
   Dart_NativeEntryResolver native_entry_resolver() const {
     return raw_ptr()->native_entry_resolver_;
@@ -3533,7 +3619,7 @@
 
   RawString* MakeMetadataName(const Object& obj) const;
   RawField* GetMetadataField(const String& metaname) const;
-  void AddMetadata(const Class& cls,
+  void AddMetadata(const Object& owner,
                    const String& name,
                    intptr_t token_pos) const;
 
@@ -3556,7 +3642,7 @@
   RawArray* show_names() const { return raw_ptr()->show_names_; }
   RawArray* hide_names() const { return raw_ptr()->hide_names_; }
 
-  void AddMetadata(intptr_t token_pos, const Class& owner_class);
+  void AddMetadata(const Object& owner, intptr_t token_pos);
   RawObject* GetMetadata() const;
 
   static intptr_t InstanceSize() {
@@ -3694,13 +3780,6 @@
  public:
   intptr_t size() const { return raw_ptr()->size_; }  // Excludes HeaderSize().
 
-  RawCode* code() const {
-    // This should only be accessed when jitting.
-    // TODO(johnmccutchan): Remove code back pointer.
-    ASSERT(!Dart::IsRunningPrecompiledCode());
-    return raw_ptr()->code_;
-  }
-
   uword EntryPoint() const {
     return reinterpret_cast<uword>(raw_ptr()) + HeaderSize();
   }
@@ -3739,10 +3818,6 @@
     StoreNonPointer(&raw_ptr()->size_, size);
   }
 
-  void set_code(RawCode* code) const {
-    StorePointer(&raw_ptr()->code_, code);
-  }
-
   // New is a private method as RawInstruction and RawCode objects should
   // only be created using the Code::FinalizeCode method. This method creates
   // the RawInstruction and RawCode objects, sets up the pointer offsets
@@ -4302,7 +4377,7 @@
                                bool optimized = false);
   static RawCode* FinalizeCode(const char* name,
                                Assembler* assembler,
-                               bool optimized = false);
+                               bool optimized);
   static RawCode* LookupCode(uword pc);
   static RawCode* LookupCodeInVmIsolate(uword pc);
   static RawCode* FindCode(uword pc, int64_t timestamp);
@@ -4347,8 +4422,9 @@
 
   void Enable() const {
     if (!IsDisabled()) return;
+    ASSERT(Thread::Current()->IsMutatorThread());
     ASSERT(instructions() != active_instructions());
-    set_active_instructions(instructions());
+    SetActiveInstructions(instructions());
   }
 
   bool IsDisabled() const {
@@ -4375,12 +4451,11 @@
   class AliveBit : public BitField<bool, kAliveBit, 1> {};
   class PtrOffBits : public BitField<intptr_t, kPtrOffBit, kPtrOffSize> {};
 
-  // An object finder visitor interface.
-  class FindRawCodeVisitor : public FindObjectVisitor {
+  class SlowFindRawCodeVisitor : public FindObjectVisitor {
    public:
-    explicit FindRawCodeVisitor(uword pc)
+    explicit SlowFindRawCodeVisitor(uword pc)
         : FindObjectVisitor(Isolate::Current()), pc_(pc) { }
-    virtual ~FindRawCodeVisitor() { }
+    virtual ~SlowFindRawCodeVisitor() { }
 
     // Check if object matches find condition.
     virtual bool FindObject(RawObject* obj) const;
@@ -4388,7 +4463,7 @@
    private:
     const uword pc_;
 
-    DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor);
+    DISALLOW_COPY_AND_ASSIGN(SlowFindRawCodeVisitor);
   };
 
   static bool IsOptimized(RawCode* code) {
@@ -4401,16 +4476,10 @@
     StoreNonPointer(&raw_ptr()->compile_timestamp_, timestamp);
   }
 
-  void set_active_instructions(RawInstructions* instructions) const {
-    // RawInstructions are never allocated in New space and hence a
-    // store buffer update is not needed here.
-    StorePointer(&raw_ptr()->active_instructions_, instructions);
-    StoreNonPointer(&raw_ptr()->entry_point_,
-                    reinterpret_cast<uword>(instructions->ptr()) +
-                    Instructions::HeaderSize());
-  }
+  void SetActiveInstructions(RawInstructions* instructions) const;
 
   void set_instructions(RawInstructions* instructions) const {
+    ASSERT(Thread::Current()->IsMutatorThread() || !is_alive());
     StorePointer(&raw_ptr()->instructions_, instructions);
   }
 
@@ -4595,6 +4664,14 @@
   intptr_t mask() const;
   void set_mask(intptr_t mask) const;
 
+  RawString* target_name() const {
+    return raw_ptr()->target_name_;
+  }
+
+  RawArray* arguments_descriptor() const {
+    return raw_ptr()->args_descriptor_;
+  }
+
   intptr_t filled_entry_count() const;
   void set_filled_entry_count(intptr_t num) const;
 
@@ -4604,8 +4681,12 @@
   static intptr_t mask_offset() {
     return OFFSET_OF(RawMegamorphicCache, mask_);
   }
+  static intptr_t arguments_descriptor_offset() {
+    return OFFSET_OF(RawMegamorphicCache, args_descriptor_);
+  }
 
-  static RawMegamorphicCache* New();
+  static RawMegamorphicCache* New(const String& target_name,
+                                  const Array& arguments_descriptor);
 
   void EnsureCapacity() const;
 
@@ -4618,6 +4699,11 @@
  private:
   friend class Class;
 
+  static RawMegamorphicCache* New();
+
+  void set_target_name(const String& value) const;
+  void set_arguments_descriptor(const Array& value) const;
+
   enum {
     kClassIdIndex,
     kTargetFunctionIndex,
@@ -5232,7 +5318,7 @@
   virtual bool IsRecursive() const;
   virtual RawAbstractType* InstantiateFrom(
       const TypeArguments& instantiator_type_arguments,
-      Error* malformed_error,
+      Error* bound_error,
       TrailPtr trail = NULL,
       Heap::Space space = Heap::kNew) const;
   virtual RawAbstractType* CloneUnfinalized() const;
@@ -6739,7 +6825,11 @@
     // An Array is raw or takes one type argument. However, its type argument
     // vector may be longer than 1 due to a type optimization reusing the type
     // argument vector of the instantiator.
-    ASSERT(value.IsNull() || ((value.Length() >= 1) && value.IsInstantiated()));
+    ASSERT(value.IsNull() ||
+           ((value.Length() >= 1) &&
+            value.IsInstantiated() /*&& value.IsCanonical()*/));
+    // TODO(asiva): Values read from a message snapshot are not properly marked
+    // as canonical. See for example tests/isolate/mandel_isolate_test.dart.
     StorePointer(&raw_ptr()->type_arguments_, value.raw());
   }
 
@@ -6902,7 +6992,10 @@
     // A GrowableObjectArray is raw or takes one type argument. However, its
     // type argument vector may be longer than 1 due to a type optimization
     // reusing the type argument vector of the instantiator.
-    ASSERT(value.IsNull() || ((value.Length() >= 1) && value.IsInstantiated()));
+    ASSERT(value.IsNull() ||
+           ((value.Length() >= 1) &&
+            value.IsInstantiated() &&
+            value.IsCanonical()));
     const Array& contents = Array::Handle(data());
     contents.SetTypeArguments(value);
     StorePointer(&raw_ptr()->type_arguments_, value.raw());
@@ -7204,7 +7297,7 @@
     return RawObject::IsTypedDataClassId(cid);
   }
 
-  static RawTypedData* EmptyUint32Array(Isolate* isolate);
+  static RawTypedData* EmptyUint32Array(Thread* thread);
 
  protected:
   void SetLength(intptr_t value) const {
@@ -7450,7 +7543,11 @@
     return raw_ptr()->type_arguments_;
   }
   virtual void SetTypeArguments(const TypeArguments& value) const {
-    ASSERT(value.IsNull() || ((value.Length() >= 2) && value.IsInstantiated()));
+    ASSERT(value.IsNull() ||
+           ((value.Length() >= 2) &&
+            value.IsInstantiated() /*&& value.IsCanonical()*/));
+    // TODO(asiva): Values read from a message snapshot are not properly marked
+    // as canonical. See for example tests/isolate/message3_test.dart.
     StorePointer(&raw_ptr()->type_arguments_, value.raw());
   }
   static intptr_t type_arguments_offset() {
@@ -7591,6 +7688,7 @@
   }
   static void SetTypeArguments(const Instance& closure,
                                const TypeArguments& value) {
+    ASSERT(value.IsNull() || value.IsCanonical());
     closure.StorePointer(TypeArgumentsAddr(closure), value.raw());
   }
   static intptr_t type_arguments_offset() {
@@ -7970,12 +8068,12 @@
                          Heap::Space space = Heap::kOld);
   static RawUserTag* DefaultTag();
 
-  static bool TagTableIsFull(Isolate* isolate);
+  static bool TagTableIsFull(Thread* thread);
   static RawUserTag* FindTagById(uword tag_id);
 
  private:
-  static RawUserTag* FindTagInIsolate(Isolate* isolate, const String& label);
-  static void AddTagToIsolate(Isolate* isolate, const UserTag& tag);
+  static RawUserTag* FindTagInIsolate(Thread* thread, const String& label);
+  static void AddTagToIsolate(Thread* thread, const UserTag& tag);
 
   void set_label(const String& tag_label) const {
     StorePointer(&raw_ptr()->label_, tag_label.raw());
@@ -8047,6 +8145,7 @@
 
 void Field::SetStaticValue(const Instance& value,
                            bool save_initial_value) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(is_static());  // Valid only for static dart fields.
   StorePointer(&raw_ptr()->value_.static_value_, value.raw());
   if (save_initial_value) {
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 3a56dc9..6c46997 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -156,12 +156,12 @@
 };
 
 
-ObjectGraph::ObjectGraph(Isolate* isolate)
-    : StackResource(isolate) {
+ObjectGraph::ObjectGraph(Thread* thread)
+    : StackResource(thread) {
   // The VM isolate has all its objects pre-marked, so iterating over it
   // would be a no-op.
-  ASSERT(isolate != Dart::vm_isolate());
-  isolate->heap()->WriteProtectCode(false);
+  ASSERT(thread->isolate() != Dart::vm_isolate());
+  thread->isolate()->heap()->WriteProtectCode(false);
 }
 
 
@@ -173,7 +173,7 @@
 void ObjectGraph::IterateObjects(ObjectGraph::Visitor* visitor) {
   NoSafepointScope no_safepoint_scope_;
   Stack stack(isolate());
-  isolate()->IterateObjectPointers(&stack, false, false);
+  isolate()->IterateObjectPointers(&stack, false);
   stack.TraverseGraph(visitor);
   Unmarker::UnmarkAll(isolate());
 }
@@ -186,7 +186,41 @@
   RawObject* root_raw = root.raw();
   stack.VisitPointer(&root_raw);
   stack.TraverseGraph(visitor);
-  // TODO(koda): Optimize if we only visited a small subgraph.
+  Unmarker::UnmarkAll(isolate());
+}
+
+
+class InstanceAccumulator : public ObjectVisitor {
+ public:
+  explicit InstanceAccumulator(ObjectGraph::Stack* stack,
+                               intptr_t class_id,
+                               Isolate* isolate)
+    : ObjectVisitor(isolate), stack_(stack), class_id_(class_id) { }
+
+  void VisitObject(RawObject* obj) {
+    if (obj->GetClassId() == class_id_) {
+      RawObject* rawobj = obj;
+      stack_->VisitPointer(&rawobj);
+    }
+  }
+
+ private:
+  ObjectGraph::Stack* stack_;
+  const intptr_t class_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(InstanceAccumulator);
+};
+
+
+void ObjectGraph::IterateObjectsFrom(intptr_t class_id,
+                                     ObjectGraph::Visitor* visitor) {
+  NoSafepointScope no_safepoint_scope_;
+  Stack stack(isolate());
+
+  InstanceAccumulator accumulator(&stack, class_id, isolate());
+  isolate()->heap()->IterateObjects(&accumulator);
+
+  stack.TraverseGraph(visitor);
   Unmarker::UnmarkAll(isolate());
 }
 
@@ -240,6 +274,13 @@
 }
 
 
+intptr_t ObjectGraph::SizeReachableByInstance(const Object& obj) {
+  SizeVisitor total;
+  IterateObjectsFrom(obj, &total);
+  return total.size();
+}
+
+
 intptr_t ObjectGraph::SizeRetainedByClass(intptr_t class_id) {
   SizeVisitor total;
   IterateObjects(&total);
@@ -251,6 +292,13 @@
 }
 
 
+intptr_t ObjectGraph::SizeReachableByClass(intptr_t class_id) {
+  SizeVisitor total;
+  IterateObjectsFrom(class_id, &total);
+  return total.size();
+}
+
+
 class RetainingPathVisitor : public ObjectGraph::Visitor {
  public:
   // We cannot use a GrowableObjectArray, since we must not trigger GC.
@@ -473,7 +521,7 @@
   stream->WriteUnsigned(0);
   {
     WritePointerVisitor ptr_writer(isolate(), stream);
-    isolate()->IterateObjectPointers(&ptr_writer, false, false);
+    isolate()->IterateObjectPointers(&ptr_writer, false);
   }
   stream->WriteUnsigned(0);
   IterateObjects(&visitor);
diff --git a/runtime/vm/object_graph.h b/runtime/vm/object_graph.h
index 3163597..5187d5e 100644
--- a/runtime/vm/object_graph.h
+++ b/runtime/vm/object_graph.h
@@ -53,7 +53,7 @@
     virtual Direction VisitObject(StackIterator* it) = 0;
   };
 
-  explicit ObjectGraph(Isolate* isolate);
+  explicit ObjectGraph(Thread* thread);
   ~ObjectGraph();
 
   // Visits all strongly reachable objects in the isolate's heap, in a
@@ -63,12 +63,15 @@
   // Like 'IterateObjects', but restricted to objects reachable from 'root'
   // (including 'root' itself).
   void IterateObjectsFrom(const Object& root, Visitor* visitor);
+  void IterateObjectsFrom(intptr_t class_id, Visitor* visitor);
 
   // The number of bytes retained by 'obj'.
   intptr_t SizeRetainedByInstance(const Object& obj);
+  intptr_t SizeReachableByInstance(const Object& obj);
 
   // The number of bytes retained by the set of all objects of the given class.
   intptr_t SizeRetainedByClass(intptr_t class_id);
+  intptr_t SizeReachableByClass(intptr_t class_id);
 
   // Finds some retaining path from the isolate roots to 'obj'. Populates the
   // provided array with pairs of (object, offset from parent in words),
diff --git a/runtime/vm/object_graph_test.cc b/runtime/vm/object_graph_test.cc
index 3e0259a..1afcc44 100644
--- a/runtime/vm/object_graph_test.cc
+++ b/runtime/vm/object_graph_test.cc
@@ -65,7 +65,7 @@
     b = Array::null();
     c = Array::null();
     d = Array::null();
-    ObjectGraph graph(isolate);
+    ObjectGraph graph(thread);
     {
       // Compare count and size when 'b' is/isn't skipped.
       CounterVisitor with(Object::null(), Object::null());
@@ -96,7 +96,7 @@
     b ^= a.At(10);
     c ^= b.At(0);
     b = Array::null();
-    ObjectGraph graph(isolate);
+    ObjectGraph graph(thread);
     // A retaining path should end like this: c <- b <- a <- ...
     {
       HANDLESCOPE(thread);
diff --git a/runtime/vm/object_id_ring_test.cc b/runtime/vm/object_id_ring_test.cc
index 986757a..27347ea 100644
--- a/runtime/vm/object_id_ring_test.cc
+++ b/runtime/vm/object_id_ring_test.cc
@@ -133,7 +133,7 @@
   EXPECT(Dart_IsList(result));
   EXPECT_VALID(Dart_ListLength(result, &list_length));
   EXPECT_EQ(3, list_length);
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
   Heap* heap = isolate->heap();
   ObjectIdRing* ring = isolate->object_id_ring();
   ObjectIdRing::LookupResult kind = ObjectIdRing::kInvalid;
@@ -174,7 +174,7 @@
   EXPECT_NE(RawObject::ToAddr(raw_obj1), RawObject::ToAddr(raw_object_moved1));
   EXPECT_NE(RawObject::ToAddr(raw_obj2), RawObject::ToAddr(raw_object_moved2));
   // Test that we still point at the same list.
-  Dart_Handle moved_handle = Api::NewHandle(isolate, raw_object_moved1);
+  Dart_Handle moved_handle = Api::NewHandle(thread, raw_object_moved1);
   EXPECT_VALID(moved_handle);
   EXPECT(!Dart_IsNull(moved_handle));
   EXPECT(Dart_IsList(moved_handle));
@@ -188,7 +188,7 @@
 
 // Test that the ring table is updated with nulls when the old GC collects.
 TEST_CASE(ObjectIdRingOldGCTest) {
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
   Heap* heap = isolate->heap();
   ObjectIdRing* ring = isolate->object_id_ring();
 
@@ -199,7 +199,7 @@
     Dart_EnterScope();
     Dart_Handle result;
     // Create a string in the old heap.
-    result = Api::NewHandle(isolate, String::New("old", Heap::kOld));
+    result = Api::NewHandle(thread, String::New("old", Heap::kOld));
     EXPECT_VALID(result);
     intptr_t string_length = 0;
     // Inspect string.
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index d8f2f6c..624e1fe 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -73,8 +73,8 @@
     typed_data_library_(Library::null()),
     vmservice_library_(Library::null()),
     libraries_(GrowableObjectArray::null()),
+    closure_functions_(GrowableObjectArray::null()),
     pending_classes_(GrowableObjectArray::null()),
-    pending_functions_(GrowableObjectArray::null()),
     pending_deferred_loads_(GrowableObjectArray::null()),
     resume_capabilities_(GrowableObjectArray::null()),
     exit_listeners_(GrowableObjectArray::null()),
@@ -90,6 +90,9 @@
     handle_message_function_(Function::null()),
     library_load_error_table_(Array::null()),
     compile_time_constants_(Array::null()),
+    unique_dynamic_targets_(Array::null()),
+    token_objects_(GrowableObjectArray::null()),
+    token_objects_map_(Array::null()),
     megamorphic_cache_table_(GrowableObjectArray::null()),
     megamorphic_miss_code_(Code::null()),
     megamorphic_miss_function_(Function::null()) {
@@ -130,10 +133,9 @@
   ASSERT(this->out_of_memory() == Instance::null());
   ASSERT(this->preallocated_stack_trace() == Stacktrace::null());
 
-  ASSERT(this->pending_functions() == GrowableObjectArray::null());
-  this->pending_functions_ = GrowableObjectArray::New();
   this->pending_deferred_loads_ = GrowableObjectArray::New();
 
+  this->closure_functions_ = GrowableObjectArray::New();
   this->resume_capabilities_ = GrowableObjectArray::New();
   this->exit_listeners_ = GrowableObjectArray::New();
   this->error_listeners_ = GrowableObjectArray::New();
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 805b9b1..db57663 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -332,16 +332,20 @@
     libraries_ = value.raw();
   }
 
+  RawGrowableObjectArray* closure_functions() const {
+    return closure_functions_;
+  }
+  void set_closure_functions(const GrowableObjectArray& value) {
+    ASSERT(!value.IsNull());
+    closure_functions_ = value.raw();
+  }
+
   RawGrowableObjectArray* pending_classes() const { return pending_classes_; }
   void set_pending_classes(const GrowableObjectArray& value) {
     ASSERT(!value.IsNull());
     pending_classes_ = value.raw();
   }
 
-  RawGrowableObjectArray* pending_functions() const {
-    return pending_functions_;
-  }
-
   RawGrowableObjectArray* pending_deferred_loads() const {
     return pending_deferred_loads_;
   }
@@ -363,6 +367,8 @@
 
   RawError* sticky_error() const { return sticky_error_; }
   void set_sticky_error(const Error& value) {
+    // TODO(asiva): Move sticky_error_ into thread specific area.
+    ASSERT(Thread::Current()->IsMutatorThread());
     ASSERT(!value.IsNull());
     sticky_error_ = value.raw();
   }
@@ -438,12 +444,36 @@
     compile_time_constants_ = value.raw();
   }
 
+  RawArray* unique_dynamic_targets() const {
+    return unique_dynamic_targets_;
+  }
+  void set_unique_dynamic_targets(const Array& value) {
+    unique_dynamic_targets_ = value.raw();
+  }
+
+  RawGrowableObjectArray* token_objects() const {
+    return token_objects_;
+  }
+  void set_token_objects(const GrowableObjectArray& value) {
+    token_objects_ = value.raw();
+  }
+
+  RawArray* token_objects_map() const {
+    return token_objects_map_;
+  }
+  void set_token_objects_map(const Array& value) {
+    token_objects_map_ = value.raw();
+  }
+
   RawGrowableObjectArray* megamorphic_cache_table() const {
     return megamorphic_cache_table_;
   }
   void set_megamorphic_cache_table(const GrowableObjectArray& value) {
     megamorphic_cache_table_ = value.raw();
   }
+  RawCode* megamorphic_miss_code() const {
+    return megamorphic_miss_code_;
+  }
   RawFunction* megamorphic_miss_function() const {
     return megamorphic_miss_function_;
   }
@@ -527,8 +557,8 @@
   RawLibrary* typed_data_library_;
   RawLibrary* vmservice_library_;
   RawGrowableObjectArray* libraries_;
+  RawGrowableObjectArray* closure_functions_;
   RawGrowableObjectArray* pending_classes_;
-  RawGrowableObjectArray* pending_functions_;
   RawGrowableObjectArray* pending_deferred_loads_;
   RawGrowableObjectArray* resume_capabilities_;
   RawGrowableObjectArray* exit_listeners_;
@@ -547,6 +577,9 @@
   RawObject** to_snapshot() {
     return reinterpret_cast<RawObject**>(&compile_time_constants_);
   }
+  RawArray* unique_dynamic_targets_;
+  RawGrowableObjectArray* token_objects_;
+  RawArray* token_objects_map_;
   RawGrowableObjectArray* megamorphic_cache_table_;
   RawCode* megamorphic_miss_code_;
   RawFunction* megamorphic_miss_function_;
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index e186ea0..422121e 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -173,7 +173,7 @@
   EXPECT_EQ(6, ts.length());
   EXPECT_EQ(Token::kLPAREN, ts[1].kind);
   const TokenStream& token_stream = TokenStream::Handle(
-      TokenStream::New(ts, private_key));
+      TokenStream::New(ts, private_key, false));
   TokenStream::Iterator iterator(token_stream, 0);
   // EXPECT_EQ(6, token_stream.Length());
   iterator.Advance();  // Advance to '(' token.
@@ -281,7 +281,8 @@
   const Array& one_fields = Array::Handle(Array::New(1));
   const String& field_name = String::Handle(Symbols::New("the_field"));
   const Field& field = Field::Handle(
-      Field::New(field_name, false, false, false, true, one_field_class, 0));
+      Field::New(field_name, false, false, false, true, one_field_class,
+                 Object::dynamic_type(), 0));
   one_fields.SetAt(0, field);
   one_field_class.SetFields(one_fields);
   one_field_class.Finalize();
@@ -2783,7 +2784,7 @@
 // Test for Embedded Smi object in the instructions.
 TEST_CASE(EmbedSmiIn64BitCode) {
   extern void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value);
-  const intptr_t kSmiTestValue = 5L << 32;
+  const intptr_t kSmiTestValue = DART_INT64_C(5) << 32;
   Assembler _assembler_;
   GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue);
   const Function& function =
@@ -2961,7 +2962,8 @@
   const Class& cls = Class::Handle(CreateTestClass("global:"));
   const String& field_name = String::Handle(Symbols::New(name));
   const Field& field =
-      Field::Handle(Field::New(field_name, true, false, false, true, cls, 0));
+      Field::Handle(Field::New(field_name, true, false, false, true, cls,
+          Object::dynamic_type(), 0));
   return field.raw();
 }
 
@@ -3021,7 +3023,7 @@
   o1 = ICData::New(function, target_name, args_descriptor, id, num_args_tested);
   EXPECT_EQ(1, o1.NumArgsTested());
   EXPECT_EQ(id, o1.deopt_id());
-  EXPECT_EQ(function.raw(), o1.owner());
+  EXPECT_EQ(function.raw(), o1.Owner());
   EXPECT_EQ(0, o1.NumberOfChecks());
   EXPECT_EQ(target_name.raw(), o1.target_name());
   EXPECT_EQ(args_descriptor.raw(), o1.arguments_descriptor());
@@ -3060,7 +3062,7 @@
   o2 = ICData::New(function, target_name, args_descriptor, 57, 2);
   EXPECT_EQ(2, o2.NumArgsTested());
   EXPECT_EQ(57, o2.deopt_id());
-  EXPECT_EQ(function.raw(), o2.owner());
+  EXPECT_EQ(function.raw(), o2.Owner());
   EXPECT_EQ(0, o2.NumberOfChecks());
   GrowableArray<intptr_t> classes;
   classes.Add(kSmiCid);
@@ -3767,120 +3769,13 @@
 }
 
 
-TEST_CASE(FindFieldIndex) {
-  const char* kScriptChars =
-      "class A {\n"
-      "  var a;\n"
-      "  var b;\n"
-      "}\n"
-      "class B {\n"
-      "  var d;\n"
-      "}\n"
-      "test() {\n"
-      "  new A();\n"
-      "  new B();\n"
-      "}";
-  Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  EXPECT_VALID(h_lib);
-  Dart_Handle result = Dart_Invoke(h_lib, NewString("test"), 0, NULL);
-  EXPECT_VALID(result);
-  Library& lib = Library::Handle();
-  lib ^= Api::UnwrapHandle(h_lib);
-  EXPECT(!lib.IsNull());
-  const Class& class_a = Class::Handle(GetClass(lib, "A"));
-  const Array& class_a_fields = Array::Handle(class_a.fields());
-  const Class& class_b = Class::Handle(GetClass(lib, "B"));
-  const Field& field_a = Field::Handle(GetField(class_a, "a"));
-  const Field& field_b = Field::Handle(GetField(class_a, "b"));
-  const Field& field_d = Field::Handle(GetField(class_b, "d"));
-  intptr_t field_a_index = class_a.FindFieldIndex(field_a);
-  intptr_t field_b_index = class_a.FindFieldIndex(field_b);
-  intptr_t field_d_index = class_a.FindFieldIndex(field_d);
-  // Valid index.
-  EXPECT_GE(field_a_index, 0);
-  // Valid index.
-  EXPECT_GE(field_b_index, 0);
-  // Invalid index.
-  EXPECT_EQ(field_d_index, -1);
-  Field& field_a_from_index = Field::Handle();
-  field_a_from_index ^= class_a_fields.At(field_a_index);
-  ASSERT(!field_a_from_index.IsNull());
-  // Same field.
-  EXPECT_EQ(field_a.raw(), field_a_from_index.raw());
-  Field& field_b_from_index = Field::Handle();
-  field_b_from_index ^= class_a_fields.At(field_b_index);
-  ASSERT(!field_b_from_index.IsNull());
-  // Same field.
-  EXPECT_EQ(field_b.raw(), field_b_from_index.raw());
-}
-
-
-TEST_CASE(FindFunctionIndex) {
-  // Tests both FindFunctionIndex and FindImplicitClosureFunctionIndex.
-  const char* kScriptChars =
-      "class A {\n"
-      "  void a() {}\n"
-      "  Function b() { return a; }\n"
-      "}\n"
-      "class B {\n"
-      "  dynamic d() {}\n"
-      "}\n"
-      "var x;\n"
-      "test() {\n"
-      "  x = new A().b();\n"
-      "  x();\n"
-      "  new B();\n"
-      "  return x;\n"
-      "}";
-  Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  EXPECT_VALID(h_lib);
-  Dart_Handle result = Dart_Invoke(h_lib, NewString("test"), 0, NULL);
-  EXPECT_VALID(result);
-  Library& lib = Library::Handle();
-  lib ^= Api::UnwrapHandle(h_lib);
-  EXPECT(!lib.IsNull());
-  const Class& class_a = Class::Handle(GetClass(lib, "A"));
-  const Class& class_b = Class::Handle(GetClass(lib, "B"));
-  const Function& func_a = Function::Handle(GetFunction(class_a, "a"));
-  const Function& func_b = Function::Handle(GetFunction(class_a, "b"));
-  const Function& func_d = Function::Handle(GetFunction(class_b, "d"));
-  EXPECT(func_a.HasImplicitClosureFunction());
-  const Function& func_x = Function::Handle(func_a.ImplicitClosureFunction());
-  intptr_t func_a_index = class_a.FindFunctionIndex(func_a);
-  intptr_t func_b_index = class_a.FindFunctionIndex(func_b);
-  intptr_t func_d_index = class_a.FindFunctionIndex(func_d);
-  intptr_t func_x_index = class_a.FindImplicitClosureFunctionIndex(func_x);
-  // Valid index.
-  EXPECT_GE(func_a_index, 0);
-  // Valid index.
-  EXPECT_GE(func_b_index, 0);
-  // Invalid index.
-  EXPECT_EQ(func_d_index, -1);
-  // Valid index.
-  EXPECT_GE(func_x_index, 0);
-  Function& func_a_from_index = Function::Handle();
-  func_a_from_index ^= class_a.FunctionFromIndex(func_a_index);
-  EXPECT(!func_a_from_index.IsNull());
-  // Same function.
-  EXPECT_EQ(func_a.raw(), func_a_from_index.raw());
-  Function& func_b_from_index = Function::Handle();
-  func_b_from_index ^= class_a.FunctionFromIndex(func_b_index);
-  EXPECT(!func_b_from_index.IsNull());
-  // Same function.
-  EXPECT_EQ(func_b.raw(), func_b_from_index.raw());
-  // Retrieve implicit closure function.
-  Function& func_x_from_index = Function::Handle();
-  func_x_from_index ^= class_a.ImplicitClosureFunctionFromIndex(func_x_index);
-  EXPECT_EQ(func_x.raw(), func_x_from_index.raw());
-}
-
-
 TEST_CASE(FindClosureIndex) {
   // Allocate the class first.
   const String& class_name = String::Handle(Symbols::New("MyClass"));
   const Script& script = Script::Handle();
   const Class& cls = Class::Handle(CreateDummyClass(class_name, script));
   const Array& functions = Array::Handle(Array::New(1));
+  const Isolate* iso = Isolate::Current();
 
   Function& parent = Function::Handle();
   const String& parent_name = String::Handle(Symbols::New("foo_papa"));
@@ -3893,18 +3788,18 @@
   const String& function_name = String::Handle(Symbols::New("foo"));
   function = Function::NewClosureFunction(function_name, parent, 0);
   // Add closure function to class.
-  cls.AddClosureFunction(function);
+  iso->AddClosureFunction(function);
 
   // The closure should return a valid index.
-  intptr_t good_closure_index = cls.FindClosureIndex(function);
+  intptr_t good_closure_index = iso->FindClosureIndex(function);
   EXPECT_GE(good_closure_index, 0);
   // The parent function should return an invalid index.
-  intptr_t bad_closure_index = cls.FindClosureIndex(parent);
+  intptr_t bad_closure_index = iso->FindClosureIndex(parent);
   EXPECT_EQ(bad_closure_index, -1);
 
   // Retrieve closure function via index.
   Function& func_from_index = Function::Handle();
-  func_from_index ^= cls.ClosureFunctionFromIndex(good_closure_index);
+  func_from_index ^= iso->ClosureFunctionFromIndex(good_closure_index);
   // Same closure function.
   EXPECT_EQ(func_from_index.raw(), function.raw());
 }
@@ -4259,7 +4154,8 @@
         "\"owner\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"bool\"},"
         "\"_kind\":\"RegularFunction\","
-        "\"static\":false,\"const\":false}",
+        "\"static\":false,\"const\":false,"
+        "\"_intrinsic\":false,\"_native\":false}",
         buffer);
   }
   // Library reference
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index 5285ec8..cd570c4 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -48,7 +48,13 @@
   static int64_t GetCurrentTimeMicros();
 
   // Returns the current time used by the tracing infrastructure.
-  static int64_t GetCurrentTraceMicros();
+  static int64_t GetCurrentMonotonicMicros();
+
+  // Returns the raw clock value from the monotonic clock.
+  static int64_t GetCurrentMonotonicTicks();
+
+  // Returns the frequency of the monotonic clock.
+  static int64_t GetCurrentMonotonicFrequency();
 
   // Returns a cleared aligned array of type T with n entries.
   // Alignment must be >= 16 and a power of two.
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 1d448d0..9dcd09e 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -179,20 +179,32 @@
 }
 
 
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicTicks() {
   struct timespec ts;
   if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
     UNREACHABLE();
     return 0;
   }
-  // Convert to microseconds.
+  // Convert to nanoseconds.
   int64_t result = ts.tv_sec;
-  result *= kMicrosecondsPerSecond;
-  result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+  result *= kNanosecondsPerSecond;
+  result += ts.tv_nsec;
   return result;
 }
 
 
+int64_t OS::GetCurrentMonotonicFrequency() {
+  return kNanosecondsPerSecond;
+}
+
+
+int64_t OS::GetCurrentMonotonicMicros() {
+  int64_t ticks = GetCurrentMonotonicTicks();
+  ASSERT(GetCurrentMonotonicFrequency() == kNanosecondsPerSecond);
+  return ticks / kNanosecondsPerMicrosecond;
+}
+
+
 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
   const int kMinimumAlignment = 16;
   ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 25c64b7..244e9b7 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -396,20 +396,32 @@
 }
 
 
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicTicks() {
   struct timespec ts;
   if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
     UNREACHABLE();
     return 0;
   }
-  // Convert to microseconds.
+  // Convert to nanoseconds.
   int64_t result = ts.tv_sec;
-  result *= kMicrosecondsPerSecond;
-  result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+  result *= kNanosecondsPerSecond;
+  result += ts.tv_nsec;
   return result;
 }
 
 
+int64_t OS::GetCurrentMonotonicFrequency() {
+  return kNanosecondsPerSecond;
+}
+
+
+int64_t OS::GetCurrentMonotonicMicros() {
+  int64_t ticks = GetCurrentMonotonicTicks();
+  ASSERT(GetCurrentMonotonicFrequency() == kNanosecondsPerSecond);
+  return ticks / kNanosecondsPerMicrosecond;
+}
+
+
 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
   const int kMinimumAlignment = 16;
   ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index aed5d33..3393cb0 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -16,7 +16,8 @@
 #include <sys/resource.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 #if TARGET_OS_IOS
-#include <sys/sysctl.h>
+#include <sys/sysctl.h>  // NOLINT
+#include <syslog.h>  // NOLINT
 #endif
 
 #include "platform/utils.h"
@@ -26,7 +27,11 @@
 namespace dart {
 
 const char* OS::Name() {
+#if TARGET_OS_IOS
+  return "ios";
+#else
   return "macos";
+#endif
 }
 
 
@@ -85,7 +90,10 @@
 }
 
 
-int64_t OS::GetCurrentTraceMicros() {
+static mach_timebase_info_data_t timebase_info;
+
+
+int64_t OS::GetCurrentMonotonicTicks() {
 #if TARGET_OS_IOS
   // On iOS mach_absolute_time stops while the device is sleeping. Instead use
   // now - KERN_BOOTTIME to get a time difference that is not impacted by clock
@@ -101,20 +109,9 @@
   origin += boottime.tv_usec;
   return now - origin;
 #else
-  static mach_timebase_info_data_t timebase_info;
-  if (timebase_info.denom == 0) {
-    // Zero-initialization of statics guarantees that denom will be 0 before
-    // calling mach_timebase_info.  mach_timebase_info will never set denom to
-    // 0 as that would be invalid, so the zero-check can be used to determine
-    // whether mach_timebase_info has already been called.  This is
-    // recommended by Apple's QA1398.
-    kern_return_t kr = mach_timebase_info(&timebase_info);
-    ASSERT(KERN_SUCCESS == kr);
-  }
-
-  // timebase_info converts absolute time tick units into nanoseconds.  Convert
-  // to microseconds.
-  int64_t result = mach_absolute_time() / kNanosecondsPerMicrosecond;
+  ASSERT(timebase_info.denom != 0);
+  // timebase_info converts absolute time tick units into nanoseconds.
+  int64_t result = mach_absolute_time();
   result *= timebase_info.numer;
   result /= timebase_info.denom;
   return result;
@@ -122,6 +119,26 @@
 }
 
 
+int64_t OS::GetCurrentMonotonicFrequency() {
+#if TARGET_OS_IOS
+  return kMicrosecondsPerSecond;
+#else
+  return kNanosecondsPerSecond;
+#endif  // TARGET_OS_IOS
+}
+
+
+int64_t OS::GetCurrentMonotonicMicros() {
+#if TARGET_OS_IOS
+  ASSERT(GetCurrentMonotonicFrequency() == kMicrosecondsPerSecond);
+  return GetCurrentMonotonicTicks();
+#else
+  ASSERT(GetCurrentMonotonicFrequency() == kNanosecondsPerSecond);
+  return GetCurrentMonotonicTicks() / kNanosecondsPerMicrosecond;
+#endif  // TARGET_OS_IOS
+}
+
+
 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
   const int kMinimumAlignment = 16;
   ASSERT(Utils::IsPowerOfTwo(alignment));
@@ -141,9 +158,25 @@
 
 
 intptr_t OS::ActivationFrameAlignment() {
+#if TARGET_OS_IOS
+#if TARGET_ARCH_ARM
+  // Even if we generate code that maintains a stronger alignment, we cannot
+  // assert the stronger stack alignment because C++ code will not maintain it.
+  return 8;
+#elif TARGET_ARCH_ARM64
+  return 16;
+#elif TARGET_ARCH_IA32
+  return 16;  // iOS simulator
+#elif TARGET_ARCH_X64
+  return 16;  // iOS simulator
+#else
+#error Unimplemented
+#endif
+#else  // TARGET_OS_IOS
   // OS X activation frames must be 16 byte-aligned; see "Mac OS X ABI
   // Function Call Guide".
   return 16;
+#endif  // TARGET_OS_IOS
 }
 
 
@@ -224,10 +257,17 @@
 
 
 void OS::Print(const char* format, ...) {
+#if TARGET_OS_IOS
+  va_list args;
+  va_start(args, format);
+  vsyslog(LOG_INFO, format, args);
+  va_end(args);
+#else
   va_list args;
   va_start(args, format);
   VFPrint(stdout, format, args);
   va_end(args);
+#endif
 }
 
 
@@ -312,10 +352,17 @@
 
 
 void OS::PrintErr(const char* format, ...) {
+#if TARGET_OS_IOS
+  va_list args;
+  va_start(args, format);
+  vsyslog(LOG_ERR, format, args);
+  va_end(args);
+#else
   va_list args;
   va_start(args, format);
   VFPrint(stderr, format, args);
   va_end(args);
+#endif
 }
 
 
@@ -326,6 +373,8 @@
   static bool init_once_called = false;
   ASSERT(init_once_called == false);
   init_once_called = true;
+  kern_return_t kr = mach_timebase_info(&timebase_info);
+  ASSERT(KERN_SUCCESS == kr);
 }
 
 
diff --git a/runtime/vm/os_thread.cc b/runtime/vm/os_thread.cc
new file mode 100644
index 0000000..0dcd506
--- /dev/null
+++ b/runtime/vm/os_thread.cc
@@ -0,0 +1,277 @@
+// 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.
+
+#include "vm/os_thread.h"
+
+#include "vm/atomic.h"
+#include "vm/lockers.h"
+#include "vm/log.h"
+#include "vm/thread_interrupter.h"
+
+namespace dart {
+
+// The single thread local key which stores all the thread local data
+// for a thread.
+ThreadLocalKey OSThread::thread_key_ = kUnsetThreadLocalKey;
+OSThread* OSThread::thread_list_head_ = NULL;
+Mutex* OSThread::thread_list_lock_ = NULL;
+bool OSThread::creation_enabled_ = false;
+
+
+OSThread::OSThread() :
+    BaseThread(true),
+    id_(OSThread::GetCurrentThreadId()),
+    join_id_(OSThread::GetCurrentThreadJoinId()),
+    trace_id_(OSThread::GetCurrentThreadTraceId()),
+    name_(NULL),
+    timeline_block_lock_(new Mutex()),
+    timeline_block_(NULL),
+    thread_list_next_(NULL),
+    thread_interrupt_disabled_(1),  // Thread interrupts disabled by default.
+    log_(new class Log()),
+    stack_base_(0),
+    thread_(NULL) {
+}
+
+
+OSThread* OSThread::CreateOSThread() {
+  ASSERT(thread_list_lock_ != NULL);
+  MutexLocker ml(thread_list_lock_);
+  if (!creation_enabled_) {
+    return NULL;
+  }
+  OSThread* os_thread = new OSThread();
+  AddThreadToListLocked(os_thread);
+  return os_thread;
+}
+
+
+OSThread::~OSThread() {
+  RemoveThreadFromList(this);
+  delete log_;
+  log_ = NULL;
+  if (Timeline::recorder() != NULL) {
+    Timeline::recorder()->FinishBlock(timeline_block_);
+  }
+  timeline_block_ = NULL;
+  delete timeline_block_lock_;
+  free(name_);
+}
+
+
+void OSThread::DisableThreadInterrupts() {
+  ASSERT(OSThread::Current() == this);
+  AtomicOperations::FetchAndIncrement(&thread_interrupt_disabled_);
+}
+
+
+void OSThread::EnableThreadInterrupts() {
+  ASSERT(OSThread::Current() == this);
+  uintptr_t old =
+      AtomicOperations::FetchAndDecrement(&thread_interrupt_disabled_);
+  if (old == 1) {
+    // We just decremented from 1 to 0.
+    // Make sure the thread interrupter is awake.
+    ThreadInterrupter::WakeUp();
+  }
+  if (old == 0) {
+    // We just decremented from 0, this means we've got a mismatched pair
+    // of calls to EnableThreadInterrupts and DisableThreadInterrupts.
+    FATAL("Invalid call to OSThread::EnableThreadInterrupts()");
+  }
+}
+
+
+bool OSThread::ThreadInterruptsEnabled() {
+  return AtomicOperations::LoadRelaxed(&thread_interrupt_disabled_) == 0;
+}
+
+
+static void DeleteThread(void* thread) {
+  delete reinterpret_cast<OSThread*>(thread);
+}
+
+
+void OSThread::InitOnce() {
+  // Allocate the global OSThread lock.
+  ASSERT(thread_list_lock_ == NULL);
+  thread_list_lock_ = new Mutex();
+  ASSERT(thread_list_lock_ != NULL);
+
+  // Create the thread local key.
+  ASSERT(thread_key_ == kUnsetThreadLocalKey);
+  thread_key_ = CreateThreadLocal(DeleteThread);
+  ASSERT(thread_key_ != kUnsetThreadLocalKey);
+
+  // Enable creation of OSThread structures in the VM.
+  EnableOSThreadCreation();
+
+  // Create a new OSThread strcture and set it as the TLS.
+  OSThread* os_thread = CreateOSThread();
+  ASSERT(os_thread != NULL);
+  OSThread::SetCurrent(os_thread);
+  os_thread->set_name("Dart_Initialize");
+}
+
+
+void OSThread::Cleanup() {
+  // We cannot delete the thread local key and thread list lock,  yet.
+  // See the note on thread_list_lock_ in os_thread.h.
+#if 0
+  if (thread_list_lock_ != NULL) {
+    // Delete the thread local key.
+    ASSERT(thread_key_ != kUnsetThreadLocalKey);
+    DeleteThreadLocal(thread_key_);
+    thread_key_ = kUnsetThreadLocalKey;
+
+    // Delete the global OSThread lock.
+    ASSERT(thread_list_lock_ != NULL);
+    delete thread_list_lock_;
+    thread_list_lock_ = NULL;
+  }
+#endif
+}
+
+
+OSThread* OSThread::CreateAndSetUnknownThread() {
+  ASSERT(OSThread::GetCurrentTLS() == NULL);
+  OSThread* os_thread = CreateOSThread();
+  if (os_thread != NULL) {
+    OSThread::SetCurrent(os_thread);
+    os_thread->set_name("Unknown");
+  }
+  return os_thread;
+}
+
+
+bool OSThread::IsThreadInList(ThreadJoinId join_id) {
+  if (join_id == OSThread::kInvalidThreadJoinId) {
+    return false;
+  }
+  OSThreadIterator it;
+  while (it.HasNext()) {
+    ASSERT(OSThread::thread_list_lock_->IsOwnedByCurrentThread());
+    OSThread* t = it.Next();
+    // An address test is not sufficient because the allocator may recycle
+    // the address for another Thread. Test against the thread's join id.
+    if (t->join_id() == join_id) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+void OSThread::DisableOSThreadCreation() {
+  MutexLocker ml(thread_list_lock_);
+  creation_enabled_ = false;
+}
+
+
+void OSThread::EnableOSThreadCreation() {
+  MutexLocker ml(thread_list_lock_);
+  creation_enabled_ = true;
+}
+
+
+OSThread* OSThread::GetOSThreadFromThread(Thread* thread) {
+  ASSERT(thread->os_thread() != NULL);
+  return thread->os_thread();
+}
+
+
+void OSThread::AddThreadToListLocked(OSThread* thread) {
+  ASSERT(thread != NULL);
+  ASSERT(thread_list_lock_ != NULL);
+  ASSERT(OSThread::thread_list_lock_->IsOwnedByCurrentThread());
+  ASSERT(creation_enabled_);
+  ASSERT(thread->thread_list_next_ == NULL);
+
+#if defined(DEBUG)
+  {
+    // Ensure that we aren't already in the list.
+    OSThread* current = thread_list_head_;
+    while (current != NULL) {
+      ASSERT(current != thread);
+      current = current->thread_list_next_;
+    }
+  }
+#endif
+
+  // Insert at head of list.
+  thread->thread_list_next_ = thread_list_head_;
+  thread_list_head_ = thread;
+}
+
+
+void OSThread::RemoveThreadFromList(OSThread* thread) {
+  bool final_thread = false;
+  {
+    ASSERT(thread != NULL);
+    ASSERT(thread_list_lock_ != NULL);
+    MutexLocker ml(thread_list_lock_);
+    OSThread* current = thread_list_head_;
+    OSThread* previous = NULL;
+
+    // Scan across list and remove |thread|.
+    while (current != NULL) {
+      if (current == thread) {
+        // We found |thread|, remove from list.
+        if (previous == NULL) {
+          thread_list_head_ = thread->thread_list_next_;
+        } else {
+          previous->thread_list_next_ = current->thread_list_next_;
+        }
+        thread->thread_list_next_ = NULL;
+        final_thread = !creation_enabled_  && (thread_list_head_ == NULL);
+        break;
+      }
+      previous = current;
+      current = current->thread_list_next_;
+    }
+  }
+  // Check if this is the last thread. The last thread does a cleanup
+  // which removes the thread local key and the associated mutex.
+  if (final_thread) {
+    Cleanup();
+  }
+}
+
+
+void OSThread::SetCurrent(OSThread* current) {
+  OSThread::SetThreadLocal(thread_key_, reinterpret_cast<uword>(current));
+}
+
+
+OSThreadIterator::OSThreadIterator() {
+  ASSERT(OSThread::thread_list_lock_ != NULL);
+  // Lock the thread list while iterating.
+  OSThread::thread_list_lock_->Lock();
+  next_ = OSThread::thread_list_head_;
+}
+
+
+OSThreadIterator::~OSThreadIterator() {
+  ASSERT(OSThread::thread_list_lock_ != NULL);
+  // Unlock the thread list when done.
+  OSThread::thread_list_lock_->Unlock();
+}
+
+
+bool OSThreadIterator::HasNext() const {
+  ASSERT(OSThread::thread_list_lock_ != NULL);
+  ASSERT(OSThread::thread_list_lock_->IsOwnedByCurrentThread());
+  return next_ != NULL;
+}
+
+
+OSThread* OSThreadIterator::Next() {
+  ASSERT(OSThread::thread_list_lock_ != NULL);
+  ASSERT(OSThread::thread_list_lock_->IsOwnedByCurrentThread());
+  OSThread* current = next_;
+  next_ = next_->thread_list_next_;
+  return current;
+}
+
+}  // namespace dart
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index d6ae2b5..84f11b6a 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -6,6 +6,7 @@
 #define VM_OS_THREAD_H_
 
 #include "platform/globals.h"
+#include "vm/allocation.h"
 #include "vm/globals.h"
 
 // Declare the OS-specific types ahead of defining the generic classes.
@@ -23,13 +24,131 @@
 
 namespace dart {
 
-// Low-level operations on OS platform threads.
-// TODO(koda): Move to runtime/platform.
-class OSThread {
+// Forward declarations.
+class Log;
+class Mutex;
+class Thread;
+class TimelineEventBlock;
+
+class BaseThread {
  public:
-  static ThreadLocalKey kUnsetThreadLocalKey;
-  static ThreadId kInvalidThreadId;
-  static ThreadJoinId kInvalidThreadJoinId;
+  bool is_os_thread() const { return is_os_thread_; }
+
+ private:
+  explicit BaseThread(bool is_os_thread) : is_os_thread_(is_os_thread) {}
+  ~BaseThread() {}
+
+  bool is_os_thread_;
+
+  friend class Thread;
+  friend class OSThread;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(BaseThread);
+};
+
+
+// Low-level operations on OS platform threads.
+class OSThread : public BaseThread {
+ public:
+  // The constructor of OSThread is never called directly, instead we call
+  // this factory style method 'CreateOSThread' to create OSThread structures.
+  // The method can return a NULL if the Dart VM is in shutdown mode.
+  static OSThread* CreateOSThread();
+  ~OSThread();
+
+  ThreadId id() const {
+    ASSERT(id_ != OSThread::kInvalidThreadId);
+    return id_;
+  }
+
+  ThreadJoinId join_id() const {
+    ASSERT(join_id_ != OSThread::kInvalidThreadJoinId);
+    return join_id_;
+  }
+
+  ThreadId trace_id() const {
+    ASSERT(trace_id_ != OSThread::kInvalidThreadJoinId);
+    return trace_id_;
+  }
+
+  const char* name() const {
+    return name_;
+  }
+
+  void set_name(const char* name) {
+    ASSERT(OSThread::Current() == this);
+    ASSERT(name_ == NULL);
+    ASSERT(name != NULL);
+    name_ = strdup(name);
+  }
+
+  Mutex* timeline_block_lock() const {
+    return timeline_block_lock_;
+  }
+
+  // Only safe to access when holding |timeline_block_lock_|.
+  TimelineEventBlock* timeline_block() const {
+    return timeline_block_;
+  }
+
+  // Only safe to access when holding |timeline_block_lock_|.
+  void set_timeline_block(TimelineEventBlock* block) {
+    timeline_block_ = block;
+  }
+
+  Log* log() const { return log_; }
+
+  uword stack_base() const { return stack_base_; }
+  void set_stack_base(uword stack_base) { stack_base_ = stack_base; }
+
+  // Retrieve the stack address bounds for profiler.
+  bool GetProfilerStackBounds(uword* lower, uword* upper) const {
+    uword stack_upper = stack_base_;
+    if (stack_upper == 0) {
+      return false;
+    }
+    uword stack_lower = stack_upper - GetSpecifiedStackSize();
+    *lower = stack_lower;
+    *upper = stack_upper;
+    return true;
+  }
+
+  // Used to temporarily disable or enable thread interrupts.
+  void DisableThreadInterrupts();
+  void EnableThreadInterrupts();
+  bool ThreadInterruptsEnabled();
+
+  // The currently executing thread, or NULL if not yet initialized.
+  static OSThread* Current() {
+    BaseThread* thread = GetCurrentTLS();
+    OSThread* os_thread = NULL;
+    if (thread != NULL) {
+      if (thread->is_os_thread()) {
+        os_thread = reinterpret_cast<OSThread*>(thread);
+      } else {
+        Thread* vm_thread = reinterpret_cast<Thread*>(thread);
+        os_thread = GetOSThreadFromThread(vm_thread);
+      }
+    } else {
+      os_thread = CreateAndSetUnknownThread();
+    }
+    return os_thread;
+  }
+  static void SetCurrent(OSThread* current);
+
+  // TODO(5411455): Use flag to override default value and Validate the
+  // stack size by querying OS.
+  static uword GetSpecifiedStackSize() {
+    ASSERT(OSThread::kStackSizeBuffer < OSThread::GetMaxStackSize());
+    uword stack_size = OSThread::GetMaxStackSize() - OSThread::kStackSizeBuffer;
+    return stack_size;
+  }
+  static BaseThread* GetCurrentTLS() {
+    return reinterpret_cast<BaseThread*>(OSThread::GetThreadLocal(thread_key_));
+  }
+  static void SetCurrentTLS(uword value) {
+    SetThreadLocal(thread_key_, value);
+  }
 
   typedef void (*ThreadStartFunction) (uword parameter);
   typedef void (*ThreadDestructor) (void* parameter);
@@ -37,27 +156,108 @@
   // Start a thread running the specified function. Returns 0 if the
   // thread started successfuly and a system specific error code if
   // the thread failed to start.
-  static int Start(ThreadStartFunction function, uword parameters);
+  static int Start(
+      const char* name, ThreadStartFunction function, uword parameter);
 
-  // NOTE: Destructor currently ignored on Windows (issue 23474).
   static ThreadLocalKey CreateThreadLocal(ThreadDestructor destructor = NULL);
   static void DeleteThreadLocal(ThreadLocalKey key);
   static uword GetThreadLocal(ThreadLocalKey key) {
     return ThreadInlineImpl::GetThreadLocal(key);
   }
+  static ThreadId GetCurrentThreadId();
   static void SetThreadLocal(ThreadLocalKey key, uword value);
   static intptr_t GetMaxStackSize();
-  static ThreadId GetCurrentThreadId();
-  static ThreadId GetCurrentThreadTraceId();
-  static intptr_t CurrentCurrentThreadIdAsIntPtr() {
-    return ThreadIdToIntPtr(GetCurrentThreadId());
-  }
-  static ThreadJoinId GetCurrentThreadJoinId();
   static void Join(ThreadJoinId id);
   static intptr_t ThreadIdToIntPtr(ThreadId id);
   static ThreadId ThreadIdFromIntPtr(intptr_t id);
   static bool Compare(ThreadId a, ThreadId b);
   static void GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage);
+
+  // Called at VM startup and shutdown.
+  static void InitOnce();
+
+  static bool IsThreadInList(ThreadJoinId join_id);
+
+  static void DisableOSThreadCreation();
+  static void EnableOSThreadCreation();
+
+  static const intptr_t kStackSizeBuffer = (4 * KB * kWordSize);
+
+  static const ThreadId kInvalidThreadId;
+  static const ThreadJoinId kInvalidThreadJoinId;
+
+ private:
+  // The constructor is private as CreateOSThread should be used
+  // to create a new OSThread structure.
+  OSThread();
+
+  // These methods should not be used in a generic way and hence
+  // are private, they have been added to solve the problem of
+  // accessing the VM thread structure from an OSThread object
+  // in the windows thread interrupter which is used for profiling.
+  // We could eliminate this requirement if the windows thread interrupter
+  // is implemented differently.
+  Thread* thread() const { return thread_; }
+  void set_thread(Thread* value) {
+    thread_ = value;
+  }
+
+  static void Cleanup();
+  static ThreadId GetCurrentThreadTraceId();
+  static ThreadJoinId GetCurrentThreadJoinId();
+  static OSThread* GetOSThreadFromThread(Thread* thread);
+  static void AddThreadToListLocked(OSThread* thread);
+  static void RemoveThreadFromList(OSThread* thread);
+  static OSThread* CreateAndSetUnknownThread();
+
+  static ThreadLocalKey thread_key_;
+
+  const ThreadId id_;
+  const ThreadJoinId join_id_;
+  const ThreadId trace_id_;  // Used to interface with tracing tools.
+  char* name_;  // A name for this thread.
+
+  Mutex* timeline_block_lock_;
+  TimelineEventBlock* timeline_block_;
+
+  // All |Thread|s are registered in the thread list.
+  OSThread* thread_list_next_;
+
+  uintptr_t thread_interrupt_disabled_;
+  Log* log_;
+  uword stack_base_;
+  Thread* thread_;
+
+  // thread_list_lock_ cannot have a static lifetime because the order in which
+  // destructors run is undefined. At the moment this lock cannot be deleted
+  // either since otherwise, if a thread only begins to run after we have
+  // started to run TLS destructors for a call to exit(), there will be a race
+  // on its deletion in CreateOSThread().
+  static Mutex* thread_list_lock_;
+  static OSThread* thread_list_head_;
+  static bool creation_enabled_;
+
+  friend class OSThreadIterator;
+  friend class ThreadInterrupterWin;
+  friend class ThreadRegistry;
+};
+
+
+// Note that this takes the thread list lock, prohibiting threads from coming
+// on- or off-line.
+class OSThreadIterator : public ValueObject {
+ public:
+  OSThreadIterator();
+  ~OSThreadIterator();
+
+  // Returns false when there are no more threads left.
+  bool HasNext() const;
+
+  // Returns the current thread and moves forward.
+  OSThread* Next();
+
+ private:
+  OSThread* next_;
 };
 
 
@@ -114,8 +314,22 @@
   void Notify();
   void NotifyAll();
 
+#if defined(DEBUG)
+  bool IsOwnedByCurrentThread() const {
+    return owner_ == OSThread::GetCurrentThreadId();
+  }
+#else
+  bool IsOwnedByCurrentThread() const {
+    UNREACHABLE();
+    return false;
+  }
+#endif
+
  private:
   MonitorData data_;  // OS-specific data.
+#if defined(DEBUG)
+  ThreadId owner_;
+#endif  // defined(DEBUG)
 
   DISALLOW_COPY_AND_ASSIGN(Monitor);
 };
diff --git a/runtime/vm/os_thread_android.cc b/runtime/vm/os_thread_android.cc
index fa87896..c02fd9a 100644
--- a/runtime/vm/os_thread_android.cc
+++ b/runtime/vm/os_thread_android.cc
@@ -11,6 +11,7 @@
 #include <sys/time.h>  // NOLINT
 
 #include "platform/assert.h"
+#include "platform/utils.h"
 
 namespace dart {
 
@@ -18,7 +19,7 @@
   if (result != 0) { \
     const int kBufferSize = 1024; \
     char error_message[kBufferSize]; \
-    strerror_r(result, error_message, kBufferSize); \
+    Utils::StrError(result, error_message, kBufferSize); \
     FATAL2("pthread error: %d (%s)", result, error_message); \
   }
 
@@ -36,7 +37,7 @@
   if (result != 0) { \
     const int kBufferSize = 1024; \
     char error_message[kBufferSize]; \
-    strerror_r(result, error_message, kBufferSize); \
+    Utils::StrError(result, error_message, kBufferSize); \
     fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
             __FILE__, __LINE__, result, error_message); \
     return result; \
@@ -64,14 +65,17 @@
 
 class ThreadStartData {
  public:
-  ThreadStartData(OSThread::ThreadStartFunction function,
+  ThreadStartData(const char* name,
+                  OSThread::ThreadStartFunction function,
                   uword parameter)
-      : function_(function), parameter_(parameter) {}
+      : name_(name), function_(function), parameter_(parameter) {}
 
+  const char* name() const { return name_; }
   OSThread::ThreadStartFunction function() const { return function_; }
   uword parameter() const { return parameter_; }
 
  private:
+  const char* name_;
   OSThread::ThreadStartFunction function_;
   uword parameter_;
 
@@ -85,18 +89,28 @@
 static void* ThreadStart(void* data_ptr) {
   ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
 
+  const char* name = data->name();
   OSThread::ThreadStartFunction function = data->function();
   uword parameter = data->parameter();
   delete data;
 
-  // Call the supplied thread start function handing it its parameters.
-  function(parameter);
+  // Create new OSThread object and set as TLS for new thread.
+  OSThread* thread = OSThread::CreateOSThread();
+  if (thread != NULL) {
+    OSThread::SetCurrent(thread);
+    thread->set_name(name);
+
+    // Call the supplied thread start function handing it its parameters.
+    function(parameter);
+  }
 
   return NULL;
 }
 
 
-int OSThread::Start(ThreadStartFunction function, uword parameter) {
+int OSThread::Start(const char* name,
+                    ThreadStartFunction function,
+                    uword parameter) {
   pthread_attr_t attr;
   int result = pthread_attr_init(&attr);
   RETURN_ON_PTHREAD_FAILURE(result);
@@ -104,7 +118,7 @@
   result = pthread_attr_setstacksize(&attr, OSThread::GetMaxStackSize());
   RETURN_ON_PTHREAD_FAILURE(result);
 
-  ThreadStartData* data = new ThreadStartData(function, parameter);
+  ThreadStartData* data = new ThreadStartData(name, function, parameter);
 
   pthread_t tid;
   result = pthread_create(&tid, &attr, ThreadStart, data);
@@ -117,10 +131,10 @@
 }
 
 
-ThreadLocalKey OSThread::kUnsetThreadLocalKey =
-    static_cast<pthread_key_t>(-1);
-ThreadId OSThread::kInvalidThreadId = static_cast<ThreadId>(0);
-ThreadJoinId OSThread::kInvalidThreadJoinId = static_cast<ThreadJoinId>(0);
+const ThreadId OSThread::kInvalidThreadId = static_cast<ThreadId>(0);
+const ThreadJoinId OSThread::kInvalidThreadJoinId =
+    static_cast<ThreadJoinId>(0);
+
 
 ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) {
   pthread_key_t key = kUnsetThreadLocalKey;
@@ -216,8 +230,8 @@
   result = pthread_mutexattr_destroy(&attr);
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
 }
@@ -228,8 +242,8 @@
   // Verify that the pthread_mutex was destroyed.
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(owner_ == OSThread::kInvalidThreadId);
 #endif  // defined(DEBUG)
 }
@@ -240,8 +254,8 @@
   // Specifically check for dead lock to help debugging.
   ASSERT(result != EDEADLK);
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
 }
@@ -254,8 +268,8 @@
     return false;
   }
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
   return true;
@@ -263,8 +277,8 @@
 
 
 void Mutex::Unlock() {
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(IsOwnedByCurrentThread());
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
@@ -300,10 +314,20 @@
 
   result = pthread_condattr_destroy(&cond_attr);
   VALIDATE_PTHREAD_RESULT(result);
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
 }
 
 
 Monitor::~Monitor() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_destroy(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 
@@ -315,12 +339,22 @@
 void Monitor::Enter() {
   int result = pthread_mutex_lock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
-  // TODO(iposva): Do we need to track lock owners?
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+#endif  // defined(DEBUG)
 }
 
 
 void Monitor::Exit() {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_unlock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 }
@@ -332,7 +366,13 @@
 
 
 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  ThreadId saved_owner = owner_;
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   Monitor::WaitResult retval = kNotified;
   if (micros == kNoTimeout) {
     // Wait forever.
@@ -347,19 +387,28 @@
       retval = kTimedOut;
     }
   }
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+  ASSERT(owner_ == saved_owner);
+#endif  // defined(DEBUG)
   return retval;
 }
 
 
 void Monitor::Notify() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_signal(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
 
 
 void Monitor::NotifyAll() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_broadcast(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
diff --git a/runtime/vm/os_thread_android.h b/runtime/vm/os_thread_android.h
index 061066e..c4f3981 100644
--- a/runtime/vm/os_thread_android.h
+++ b/runtime/vm/os_thread_android.h
@@ -20,13 +20,17 @@
 typedef pid_t ThreadId;
 typedef pthread_t ThreadJoinId;
 
+
+static const ThreadLocalKey kUnsetThreadLocalKey =
+    static_cast<pthread_key_t>(-1);
+
+
 class ThreadInlineImpl {
  private:
   ThreadInlineImpl() {}
   ~ThreadInlineImpl() {}
 
   static uword GetThreadLocal(ThreadLocalKey key) {
-    static ThreadLocalKey kUnsetThreadLocalKey = static_cast<pthread_key_t>(-1);
     ASSERT(key != kUnsetThreadLocalKey);
     return reinterpret_cast<uword>(pthread_getspecific(key));
   }
diff --git a/runtime/vm/os_thread_linux.cc b/runtime/vm/os_thread_linux.cc
index 9fb0b23..f821233 100644
--- a/runtime/vm/os_thread_linux.cc
+++ b/runtime/vm/os_thread_linux.cc
@@ -13,6 +13,7 @@
 #include <sys/time.h>  // NOLINT
 
 #include "platform/assert.h"
+#include "platform/utils.h"
 
 namespace dart {
 
@@ -21,7 +22,7 @@
     const int kBufferSize = 1024; \
     char error_buf[kBufferSize]; \
     FATAL2("pthread error: %d (%s)", result, \
-           strerror_r(result, error_buf, kBufferSize)); \
+           Utils::StrError(result, error_buf, kBufferSize)); \
   }
 
 
@@ -40,7 +41,7 @@
     char error_buf[kBufferSize]; \
     fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
             __FILE__, __LINE__, result, \
-            strerror_r(result, error_buf, kBufferSize)); \
+            Utils::StrError(result, error_buf, kBufferSize)); \
     return result; \
   }
 #else
@@ -66,14 +67,17 @@
 
 class ThreadStartData {
  public:
-  ThreadStartData(OSThread::ThreadStartFunction function,
+  ThreadStartData(const char* name,
+                  OSThread::ThreadStartFunction function,
                   uword parameter)
-      : function_(function), parameter_(parameter) {}
+      : name_(name), function_(function), parameter_(parameter) {}
 
+  const char* name() const { return name_; }
   OSThread::ThreadStartFunction function() const { return function_; }
   uword parameter() const { return parameter_; }
 
  private:
+  const char* name_;
   OSThread::ThreadStartFunction function_;
   uword parameter_;
 
@@ -87,18 +91,28 @@
 static void* ThreadStart(void* data_ptr) {
   ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
 
+  const char* name = data->name();
   OSThread::ThreadStartFunction function = data->function();
   uword parameter = data->parameter();
   delete data;
 
-  // Call the supplied thread start function handing it its parameters.
-  function(parameter);
+  // Create new OSThread object and set as TLS for new thread.
+  OSThread* thread = OSThread::CreateOSThread();
+  if (thread != NULL) {
+    OSThread::SetCurrent(thread);
+    thread->set_name(name);
+
+    // Call the supplied thread start function handing it its parameters.
+    function(parameter);
+  }
 
   return NULL;
 }
 
 
-int OSThread::Start(ThreadStartFunction function, uword parameter) {
+int OSThread::Start(const char* name,
+                    ThreadStartFunction function,
+                    uword parameter) {
   pthread_attr_t attr;
   int result = pthread_attr_init(&attr);
   RETURN_ON_PTHREAD_FAILURE(result);
@@ -106,7 +120,7 @@
   result = pthread_attr_setstacksize(&attr, OSThread::GetMaxStackSize());
   RETURN_ON_PTHREAD_FAILURE(result);
 
-  ThreadStartData* data = new ThreadStartData(function, parameter);
+  ThreadStartData* data = new ThreadStartData(name, function, parameter);
 
   pthread_t tid;
   result = pthread_create(&tid, &attr, ThreadStart, data);
@@ -119,10 +133,10 @@
 }
 
 
-ThreadLocalKey OSThread::kUnsetThreadLocalKey =
-    static_cast<pthread_key_t>(-1);
-ThreadId OSThread::kInvalidThreadId = static_cast<ThreadId>(0);
-ThreadJoinId OSThread::kInvalidThreadJoinId = static_cast<ThreadJoinId>(0);
+const ThreadId OSThread::kInvalidThreadId = static_cast<ThreadId>(0);
+const ThreadJoinId OSThread::kInvalidThreadJoinId =
+    static_cast<ThreadJoinId>(0);
+
 
 ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) {
   pthread_key_t key = kUnsetThreadLocalKey;
@@ -218,8 +232,8 @@
   result = pthread_mutexattr_destroy(&attr);
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
 }
@@ -230,8 +244,8 @@
   // Verify that the pthread_mutex was destroyed.
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   ASSERT(owner_ == OSThread::kInvalidThreadId);
 #endif  // defined(DEBUG)
 }
@@ -242,8 +256,8 @@
   // Specifically check for dead lock to help debugging.
   ASSERT(result != EDEADLK);
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
 }
@@ -256,8 +270,8 @@
     return false;
   }
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
   return true;
@@ -265,8 +279,8 @@
 
 
 void Mutex::Unlock() {
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
   ASSERT(IsOwnedByCurrentThread());
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
@@ -305,10 +319,20 @@
 
   result = pthread_condattr_destroy(&cond_attr);
   VALIDATE_PTHREAD_RESULT(result);
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
 }
 
 
 Monitor::~Monitor() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_destroy(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 
@@ -320,24 +344,41 @@
 void Monitor::Enter() {
   int result = pthread_mutex_lock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
-  // TODO(iposva): Do we need to track lock owners?
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+#endif  // defined(DEBUG)
 }
 
 
 void Monitor::Exit() {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_unlock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 }
 
 
 Monitor::WaitResult Monitor::Wait(int64_t millis) {
-  return WaitMicros(millis * kMicrosecondsPerMillisecond);
+  Monitor::WaitResult retval = WaitMicros(millis * kMicrosecondsPerMillisecond);
+  return retval;
 }
 
 
 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  ThreadId saved_owner = owner_;
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   Monitor::WaitResult retval = kNotified;
   if (micros == kNoTimeout) {
     // Wait forever.
@@ -352,19 +393,28 @@
       retval = kTimedOut;
     }
   }
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+  ASSERT(owner_ == saved_owner);
+#endif  // defined(DEBUG)
   return retval;
 }
 
 
 void Monitor::Notify() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_signal(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
 
 
 void Monitor::NotifyAll() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_broadcast(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
diff --git a/runtime/vm/os_thread_linux.h b/runtime/vm/os_thread_linux.h
index 5901214..306229b 100644
--- a/runtime/vm/os_thread_linux.h
+++ b/runtime/vm/os_thread_linux.h
@@ -20,13 +20,17 @@
 typedef pthread_t ThreadId;
 typedef pthread_t ThreadJoinId;
 
+
+static const ThreadLocalKey kUnsetThreadLocalKey =
+    static_cast<pthread_key_t>(-1);
+
+
 class ThreadInlineImpl {
  private:
   ThreadInlineImpl() {}
   ~ThreadInlineImpl() {}
 
   static uword GetThreadLocal(ThreadLocalKey key) {
-    static ThreadLocalKey kUnsetThreadLocalKey = static_cast<pthread_key_t>(-1);
     ASSERT(key != kUnsetThreadLocalKey);
     return reinterpret_cast<uword>(pthread_getspecific(key));
   }
diff --git a/runtime/vm/os_thread_macos.cc b/runtime/vm/os_thread_macos.cc
index e7c7c90..1964f64 100644
--- a/runtime/vm/os_thread_macos.cc
+++ b/runtime/vm/os_thread_macos.cc
@@ -19,6 +19,7 @@
 #include <mach/thread_act.h>  // NOLINT
 
 #include "platform/assert.h"
+#include "platform/utils.h"
 
 namespace dart {
 
@@ -26,7 +27,7 @@
   if (result != 0) { \
     const int kBufferSize = 1024; \
     char error_message[kBufferSize]; \
-    strerror_r(result, error_message, kBufferSize); \
+    Utils::StrError(result, error_message, kBufferSize); \
     FATAL2("pthread error: %d (%s)", result, error_message); \
   }
 
@@ -44,7 +45,7 @@
   if (result != 0) { \
     const int kBufferSize = 1024; \
     char error_message[kBufferSize]; \
-    strerror_r(result, error_message, kBufferSize); \
+    Utils::StrError(result, error_message, kBufferSize); \
     fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
             __FILE__, __LINE__, result, error_message); \
     return result; \
@@ -57,14 +58,17 @@
 
 class ThreadStartData {
  public:
-  ThreadStartData(OSThread::ThreadStartFunction function,
+  ThreadStartData(const char* name,
+                  OSThread::ThreadStartFunction function,
                   uword parameter)
-      : function_(function), parameter_(parameter) {}
+      : name_(name), function_(function), parameter_(parameter) {}
 
+  const char* name() const { return name_; }
   OSThread::ThreadStartFunction function() const { return function_; }
   uword parameter() const { return parameter_; }
 
  private:
+  const char* name_;
   OSThread::ThreadStartFunction function_;
   uword parameter_;
 
@@ -78,18 +82,28 @@
 static void* ThreadStart(void* data_ptr) {
   ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
 
+  const char* name = data->name();
   OSThread::ThreadStartFunction function = data->function();
   uword parameter = data->parameter();
   delete data;
 
-  // Call the supplied thread start function handing it its parameters.
-  function(parameter);
+  // Create new OSThread object and set as TLS for new thread.
+  OSThread* thread = OSThread::CreateOSThread();
+  if (thread != NULL) {
+    OSThread::SetCurrent(thread);
+    thread->set_name(name);
+
+    // Call the supplied thread start function handing it its parameters.
+    function(parameter);
+  }
 
   return NULL;
 }
 
 
-int OSThread::Start(ThreadStartFunction function, uword parameter) {
+int OSThread::Start(const char* name,
+                    ThreadStartFunction function,
+                    uword parameter) {
   pthread_attr_t attr;
   int result = pthread_attr_init(&attr);
   RETURN_ON_PTHREAD_FAILURE(result);
@@ -97,7 +111,7 @@
   result = pthread_attr_setstacksize(&attr, OSThread::GetMaxStackSize());
   RETURN_ON_PTHREAD_FAILURE(result);
 
-  ThreadStartData* data = new ThreadStartData(function, parameter);
+  ThreadStartData* data = new ThreadStartData(name, function, parameter);
 
   pthread_t tid;
   result = pthread_create(&tid, &attr, ThreadStart, data);
@@ -110,12 +124,11 @@
 }
 
 
-ThreadLocalKey OSThread::kUnsetThreadLocalKey =
-    static_cast<pthread_key_t>(-1);
-ThreadId OSThread::kInvalidThreadId = reinterpret_cast<ThreadId>(NULL);
-ThreadJoinId OSThread::kInvalidThreadJoinId =
+const ThreadId OSThread::kInvalidThreadId = reinterpret_cast<ThreadId>(NULL);
+const ThreadJoinId OSThread::kInvalidThreadJoinId =
     reinterpret_cast<ThreadJoinId>(NULL);
 
+
 ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) {
   pthread_key_t key = kUnsetThreadLocalKey;
   int result = pthread_key_create(&key, destructor);
@@ -223,8 +236,8 @@
   result = pthread_mutexattr_destroy(&attr);
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
 }
@@ -235,8 +248,8 @@
   // Verify that the pthread_mutex was destroyed.
   VALIDATE_PTHREAD_RESULT(result);
 
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(owner_ == OSThread::kInvalidThreadId);
 #endif  // defined(DEBUG)
 }
@@ -247,8 +260,8 @@
   // Specifically check for dead lock to help debugging.
   ASSERT(result != EDEADLK);
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
 }
@@ -261,8 +274,8 @@
     return false;
   }
   ASSERT_PTHREAD_SUCCESS(result);  // Verify no other errors.
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
   return true;
@@ -270,8 +283,8 @@
 
 
 void Mutex::Unlock() {
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(IsOwnedByCurrentThread());
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
@@ -300,10 +313,20 @@
 
   result = pthread_cond_init(data_.cond(), NULL);
   VALIDATE_PTHREAD_RESULT(result);
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
 }
 
 
 Monitor::~Monitor() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_destroy(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 
@@ -315,12 +338,22 @@
 void Monitor::Enter() {
   int result = pthread_mutex_lock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
-  // TODO(iposva): Do we need to track lock owners?
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+#endif  // defined(DEBUG)
 }
 
 
 void Monitor::Exit() {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   int result = pthread_mutex_unlock(data_.mutex());
   VALIDATE_PTHREAD_RESULT(result);
 }
@@ -332,7 +365,13 @@
 
 
 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) {
-  // TODO(iposva): Do we need to track lock owners?
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  ThreadId saved_owner = owner_;
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   Monitor::WaitResult retval = kNotified;
   if (micros == kNoTimeout) {
     // Wait forever.
@@ -357,19 +396,28 @@
       retval = kTimedOut;
     }
   }
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+  ASSERT(owner_ == saved_owner);
+#endif  // defined(DEBUG)
   return retval;
 }
 
 
 void Monitor::Notify() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_signal(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
 
 
 void Monitor::NotifyAll() {
-  // TODO(iposva): Do we need to track lock owners?
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   int result = pthread_cond_broadcast(data_.cond());
   VALIDATE_PTHREAD_RESULT(result);
 }
diff --git a/runtime/vm/os_thread_macos.h b/runtime/vm/os_thread_macos.h
index 63b4f02..4909edf 100644
--- a/runtime/vm/os_thread_macos.h
+++ b/runtime/vm/os_thread_macos.h
@@ -20,6 +20,11 @@
 typedef pthread_t ThreadId;
 typedef pthread_t ThreadJoinId;
 
+
+static const ThreadLocalKey kUnsetThreadLocalKey =
+    static_cast<pthread_key_t>(-1);
+
+
 class ThreadInlineImpl {
  private:
   ThreadInlineImpl() {}
diff --git a/runtime/vm/os_thread_win.cc b/runtime/vm/os_thread_win.cc
index a71d4b6..7a29d0d 100644
--- a/runtime/vm/os_thread_win.cc
+++ b/runtime/vm/os_thread_win.cc
@@ -5,6 +5,7 @@
 #include "platform/globals.h"  // NOLINT
 #if defined(TARGET_OS_WINDOWS)
 
+#include "vm/growable_array.h"
 #include "vm/os_thread.h"
 
 #include <process.h>  // NOLINT
@@ -13,15 +14,23 @@
 
 namespace dart {
 
+// This flag is flipped by platform_win.cc when the process is exiting.
+// TODO(zra): Remove once VM shuts down cleanly.
+bool private_flag_windows_run_tls_destructors = true;
+
 class ThreadStartData {
  public:
-  ThreadStartData(OSThread::ThreadStartFunction function, uword parameter)
-      : function_(function), parameter_(parameter) {}
+  ThreadStartData(const char* name,
+                  OSThread::ThreadStartFunction function,
+                  uword parameter)
+      : name_(name), function_(function), parameter_(parameter) {}
 
+  const char* name() const { return name_; }
   OSThread::ThreadStartFunction function() const { return function_; }
   uword parameter() const { return parameter_; }
 
  private:
+  const char* name_;
   OSThread::ThreadStartFunction function_;
   uword parameter_;
 
@@ -35,14 +44,22 @@
 static unsigned int __stdcall ThreadEntry(void* data_ptr) {
   ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
 
+  const char* name = data->name();
   OSThread::ThreadStartFunction function = data->function();
   uword parameter = data->parameter();
   delete data;
 
   MonitorData::GetMonitorWaitDataForThread();
 
-  // Call the supplied thread start function handing it its parameters.
-  function(parameter);
+  // Create new OSThread object and set as TLS for new thread.
+  OSThread* thread = OSThread::CreateOSThread();
+  if (thread != NULL) {
+    OSThread::SetCurrent(thread);
+    thread->set_name(name);
+
+    // Call the supplied thread start function handing it its parameters.
+    function(parameter);
+  }
 
   // Clean up the monitor wait data for this thread.
   MonitorWaitData::ThreadExit();
@@ -51,8 +68,10 @@
 }
 
 
-int OSThread::Start(ThreadStartFunction function, uword parameter) {
-  ThreadStartData* start_data = new ThreadStartData(function, parameter);
+int OSThread::Start(const char* name,
+                    ThreadStartFunction function,
+                    uword parameter) {
+  ThreadStartData* start_data = new ThreadStartData(name, function, parameter);
   uint32_t tid;
   uintptr_t thread = _beginthreadex(NULL, OSThread::GetMaxStackSize(),
                                     ThreadEntry, start_data, 0, &tid);
@@ -69,15 +88,17 @@
   return 0;
 }
 
-ThreadLocalKey OSThread::kUnsetThreadLocalKey = TLS_OUT_OF_INDEXES;
-ThreadId OSThread::kInvalidThreadId = 0;
-ThreadJoinId OSThread::kInvalidThreadJoinId = 0;
 
-ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor unused) {
+const ThreadId OSThread::kInvalidThreadId = 0;
+const ThreadJoinId OSThread::kInvalidThreadJoinId = 0;
+
+
+ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) {
   ThreadLocalKey key = TlsAlloc();
   if (key == kUnsetThreadLocalKey) {
     FATAL1("TlsAlloc failed %d", GetLastError());
   }
+  ThreadLocalData::AddThreadLocal(key, destructor);
   return key;
 }
 
@@ -88,6 +109,7 @@
   if (!result) {
     FATAL1("TlsFree failed %d", GetLastError());
   }
+  ThreadLocalData::RemoveThreadLocal(key);
 }
 
 
@@ -108,6 +130,8 @@
 
 
 ThreadJoinId OSThread::GetCurrentThreadJoinId() {
+  // TODO(zra): Use the thread handle as the join id in order to have a more
+  // reliable join on windows.
   return ::GetCurrentThreadId();
 }
 
@@ -195,8 +219,8 @@
   if (data_.semaphore_ == NULL) {
     FATAL1("Mutex allocation failed %d", GetLastError());
   }
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
 }
@@ -204,8 +228,8 @@
 
 Mutex::~Mutex() {
   CloseHandle(data_.semaphore_);
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(owner_ == OSThread::kInvalidThreadId);
 #endif  // defined(DEBUG)
 }
@@ -216,8 +240,8 @@
   if (result != WAIT_OBJECT_0) {
     FATAL1("Mutex lock failed %d", GetLastError());
   }
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
 }
@@ -227,8 +251,8 @@
   // Attempt to pass the semaphore but return immediately.
   DWORD result = WaitForSingleObject(data_.semaphore_, 0);
   if (result == WAIT_OBJECT_0) {
-    // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+    // When running with assertions enabled we do track the owner.
     owner_ = OSThread::GetCurrentThreadId();
 #endif  // defined(DEBUG)
     return true;
@@ -242,8 +266,8 @@
 
 
 void Mutex::Unlock() {
-  // When running with assertions enabled we do track the owner.
 #if defined(DEBUG)
+  // When running with assertions enabled we do track the owner.
   ASSERT(IsOwnedByCurrentThread());
   owner_ = OSThread::kInvalidThreadId;
 #endif  // defined(DEBUG)
@@ -254,8 +278,7 @@
 }
 
 
-ThreadLocalKey MonitorWaitData::monitor_wait_data_key_ =
-    OSThread::kUnsetThreadLocalKey;
+ThreadLocalKey MonitorWaitData::monitor_wait_data_key_ = kUnsetThreadLocalKey;
 
 
 Monitor::Monitor() {
@@ -263,10 +286,20 @@
   InitializeCriticalSection(&data_.waiters_cs_);
   data_.waiters_head_ = NULL;
   data_.waiters_tail_ = NULL;
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
 }
 
 
 Monitor::~Monitor() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+#endif  // defined(DEBUG)
+
   DeleteCriticalSection(&data_.cs_);
   DeleteCriticalSection(&data_.waiters_cs_);
 }
@@ -274,19 +307,32 @@
 
 void Monitor::Enter() {
   EnterCriticalSection(&data_.cs_);
+
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+#endif  // defined(DEBUG)
 }
 
 
 void Monitor::Exit() {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   LeaveCriticalSection(&data_.cs_);
 }
 
 
 void MonitorWaitData::ThreadExit() {
-  if (MonitorWaitData::monitor_wait_data_key_ !=
-      OSThread::kUnsetThreadLocalKey) {
+  if (MonitorWaitData::monitor_wait_data_key_ != kUnsetThreadLocalKey) {
     uword raw_wait_data =
       OSThread::GetThreadLocal(MonitorWaitData::monitor_wait_data_key_);
+    // Clear in case this is called a second time.
+    OSThread::SetThreadLocal(MonitorWaitData::monitor_wait_data_key_, 0);
     if (raw_wait_data != 0) {
       MonitorWaitData* wait_data =
           reinterpret_cast<MonitorWaitData*>(raw_wait_data);
@@ -390,8 +436,7 @@
 MonitorWaitData* MonitorData::GetMonitorWaitDataForThread() {
   // Ensure that the thread local key for monitor wait data objects is
   // initialized.
-  ASSERT(MonitorWaitData::monitor_wait_data_key_ !=
-         OSThread::kUnsetThreadLocalKey);
+  ASSERT(MonitorWaitData::monitor_wait_data_key_ != kUnsetThreadLocalKey);
 
   // Get the MonitorWaitData object containing the event for this
   // thread from thread local storage. Create it if it does not exist.
@@ -402,7 +447,7 @@
     HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
     wait_data = new MonitorWaitData(event);
     OSThread::SetThreadLocal(MonitorWaitData::monitor_wait_data_key_,
-                           reinterpret_cast<uword>(wait_data));
+                             reinterpret_cast<uword>(wait_data));
   } else {
     wait_data = reinterpret_cast<MonitorWaitData*>(raw_wait_data);
     wait_data->next_ = NULL;
@@ -412,6 +457,13 @@
 
 
 Monitor::WaitResult Monitor::Wait(int64_t millis) {
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
+  ThreadId saved_owner = owner_;
+  owner_ = OSThread::kInvalidThreadId;
+#endif  // defined(DEBUG)
+
   Monitor::WaitResult retval = kNotified;
 
   // Get the wait data object containing the event to wait for.
@@ -449,6 +501,12 @@
   // Reacquire the monitor critical section before continuing.
   EnterCriticalSection(&data_.cs_);
 
+#if defined(DEBUG)
+  // When running with assertions enabled we track the owner.
+  ASSERT(owner_ == OSThread::kInvalidThreadId);
+  owner_ = OSThread::GetCurrentThreadId();
+  ASSERT(owner_ == saved_owner);
+#endif  // defined(DEBUG)
   return retval;
 }
 
@@ -467,11 +525,15 @@
 
 
 void Monitor::Notify() {
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   data_.SignalAndRemoveFirstWaiter();
 }
 
 
 void Monitor::NotifyAll() {
+  // When running with assertions enabled we track the owner.
+  ASSERT(IsOwnedByCurrentThread());
   // If one of the objects in the list of waiters wakes because of a
   // timeout before we signal it, that object will get an extra
   // signal. This will be treated as a spurious wake-up and is OK
@@ -480,6 +542,166 @@
   data_.SignalAndRemoveAllWaiters();
 }
 
+
+void ThreadLocalData::AddThreadLocal(ThreadLocalKey key,
+                                     ThreadDestructor destructor) {
+  ASSERT(thread_locals_ != NULL);
+  if (destructor == NULL) {
+    // We only care about thread locals with destructors.
+    return;
+  }
+  mutex_->Lock();
+#if defined(DEBUG)
+  // Verify that we aren't added twice.
+  for (intptr_t i = 0; i < thread_locals_->length(); i++) {
+    const ThreadLocalEntry& entry = thread_locals_->At(i);
+    ASSERT(entry.key() != key);
+  }
+#endif
+  // Add to list.
+  thread_locals_->Add(ThreadLocalEntry(key, destructor));
+  mutex_->Unlock();
+}
+
+
+void ThreadLocalData::RemoveThreadLocal(ThreadLocalKey key) {
+  ASSERT(thread_locals_ != NULL);  mutex_->Lock();
+  intptr_t i = 0;
+  for (; i < thread_locals_->length(); i++) {
+    const ThreadLocalEntry& entry = thread_locals_->At(i);
+    if (entry.key() == key) {
+      break;
+    }
+  }
+  if (i == thread_locals_->length()) {
+    // Not found.
+    mutex_->Unlock();
+    return;
+  }
+  thread_locals_->RemoveAt(i);
+  mutex_->Unlock();
+}
+
+
+// This function is executed on the thread that is exiting. It is invoked
+// by |OnDartThreadExit| (see below for notes on TLS destructors on Windows).
+void ThreadLocalData::RunDestructors() {
+  ASSERT(thread_locals_ != NULL);
+  ASSERT(mutex_ != NULL);
+  mutex_->Lock();
+  for (intptr_t i = 0; i < thread_locals_->length(); i++) {
+    const ThreadLocalEntry& entry = thread_locals_->At(i);
+    // We access the exiting thread's TLS variable here.
+    void* p = reinterpret_cast<void*>(OSThread::GetThreadLocal(entry.key()));
+    // We invoke the constructor here.
+    entry.destructor()(p);
+  }
+  mutex_->Unlock();
+}
+
+
+Mutex* ThreadLocalData::mutex_ = NULL;
+MallocGrowableArray<ThreadLocalEntry>* ThreadLocalData::thread_locals_ = NULL;
+
+
+void ThreadLocalData::InitOnce() {
+  mutex_ = new Mutex();
+  thread_locals_ = new MallocGrowableArray<ThreadLocalEntry>();
+}
+
+
+void ThreadLocalData::Shutdown() {
+  if (mutex_ != NULL) {
+    delete mutex_;
+    mutex_ = NULL;
+  }
+  if (thread_locals_ != NULL) {
+    delete thread_locals_;
+    thread_locals_ = NULL;
+  }
+}
+
+
 }  // namespace dart
 
+// The following was adapted from Chromium:
+// src/base/threading/thread_local_storage_win.cc
+
+// Thread Termination Callbacks.
+// Windows doesn't support a per-thread destructor with its
+// TLS primitives.  So, we build it manually by inserting a
+// function to be called on each thread's exit.
+// This magic is from http://www.codeproject.com/threads/tls.asp
+// and it works for VC++ 7.0 and later.
+
+// Force a reference to _tls_used to make the linker create the TLS directory
+// if it's not already there.  (e.g. if __declspec(thread) is not used).
+// Force a reference to p_thread_callback_dart to prevent whole program
+// optimization from discarding the variable.
+#ifdef _WIN64
+
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:p_thread_callback_dart")
+
+#else  // _WIN64
+
+#pragma comment(linker, "/INCLUDE:__tls_used")
+#pragma comment(linker, "/INCLUDE:_p_thread_callback_dart")
+
+#endif  // _WIN64
+
+// Static callback function to call with each thread termination.
+void NTAPI OnDartThreadExit(PVOID module, DWORD reason, PVOID reserved) {
+  if (!dart::private_flag_windows_run_tls_destructors) {
+    return;
+  }
+  // On XP SP0 & SP1, the DLL_PROCESS_ATTACH is never seen. It is sent on SP2+
+  // and on W2K and W2K3. So don't assume it is sent.
+  if (DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason) {
+    dart::ThreadLocalData::RunDestructors();
+    dart::MonitorWaitData::ThreadExit();
+  }
+}
+
+// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are
+// called automatically by the OS loader code (not the CRT) when the module is
+// loaded and on thread creation. They are NOT called if the module has been
+// loaded by a LoadLibrary() call. It must have implicitly been loaded at
+// process startup.
+// By implicitly loaded, I mean that it is directly referenced by the main EXE
+// or by one of its dependent DLLs. Delay-loaded DLL doesn't count as being
+// implicitly loaded.
+//
+// See VC\crt\src\tlssup.c for reference.
+
+// extern "C" suppresses C++ name mangling so we know the symbol name for the
+// linker /INCLUDE:symbol pragma above.
+extern "C" {
+// The linker must not discard p_thread_callback_dart.  (We force a reference
+// to this variable with a linker /INCLUDE:symbol pragma to ensure that.) If
+// this variable is discarded, the OnDartThreadExit function will never be
+// called.
+#ifdef _WIN64
+
+// .CRT section is merged with .rdata on x64 so it must be constant data.
+#pragma const_seg(".CRT$XLB")
+// When defining a const variable, it must have external linkage to be sure the
+// linker doesn't discard it.
+extern const PIMAGE_TLS_CALLBACK p_thread_callback_dart;
+const PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit;
+
+// Reset the default section.
+#pragma const_seg()
+
+#else  // _WIN64
+
+#pragma data_seg(".CRT$XLB")
+PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit;
+
+// Reset the default section.
+#pragma data_seg()
+
+#endif  // _WIN64
+}  // extern "C"
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/vm/os_thread_win.h b/runtime/vm/os_thread_win.h
index 5dc9b18..790306d 100644
--- a/runtime/vm/os_thread_win.h
+++ b/runtime/vm/os_thread_win.h
@@ -12,19 +12,24 @@
 #include "platform/assert.h"
 #include "platform/globals.h"
 
+#include "vm/allocation.h"
+
 namespace dart {
 
 typedef DWORD ThreadLocalKey;
 typedef DWORD ThreadId;
 typedef DWORD ThreadJoinId;
 
+
+static const ThreadLocalKey kUnsetThreadLocalKey = TLS_OUT_OF_INDEXES;
+
+
 class ThreadInlineImpl {
  private:
   ThreadInlineImpl() {}
   ~ThreadInlineImpl() {}
 
   static uword GetThreadLocal(ThreadLocalKey key) {
-    static ThreadLocalKey kUnsetThreadLocalKey = TLS_OUT_OF_INDEXES;
     ASSERT(key != kUnsetThreadLocalKey);
     return reinterpret_cast<uword>(TlsGetValue(key));
   }
@@ -116,6 +121,56 @@
   DISALLOW_COPY_AND_ASSIGN(MonitorData);
 };
 
+
+typedef void (*ThreadDestructor) (void* parameter);
+
+
+class ThreadLocalEntry {
+ public:
+  ThreadLocalEntry(ThreadLocalKey key, ThreadDestructor destructor)
+      : key_(key),
+        destructor_(destructor) {
+  }
+
+  ThreadLocalKey key() const {
+    return key_;
+  }
+
+
+  ThreadDestructor destructor() const {
+    return destructor_;
+  }
+
+ private:
+  ThreadLocalKey key_;
+  ThreadDestructor destructor_;
+
+  DISALLOW_ALLOCATION();
+};
+
+
+template<typename T>
+class MallocGrowableArray;
+
+
+class ThreadLocalData : public AllStatic {
+ public:
+  static void RunDestructors();
+
+ private:
+  static void AddThreadLocal(ThreadLocalKey key, ThreadDestructor destructor);
+  static void RemoveThreadLocal(ThreadLocalKey key);
+
+  static Mutex* mutex_;
+  static MallocGrowableArray<ThreadLocalEntry>* thread_locals_;
+
+  static void InitOnce();
+  static void Shutdown();
+
+  friend class OS;
+  friend class OSThread;
+};
+
 }  // namespace dart
 
 #endif  // VM_OS_THREAD_WIN_H_
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 0e07cdf..603ade6 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -19,6 +19,9 @@
 
 namespace dart {
 
+// Defined in vm/os_thread_win.cc
+extern bool private_flag_windows_run_tls_destructors;
+
 const char* OS::Name() {
   return "windows";
 }
@@ -123,7 +126,8 @@
 
 static int64_t qpc_ticks_per_second = 0;
 
-int64_t OS::GetCurrentTraceMicros() {
+
+int64_t OS::GetCurrentMonotonicTicks() {
   if (qpc_ticks_per_second == 0) {
     // QueryPerformanceCounter not supported, fallback.
     return GetCurrentTimeMicros();
@@ -131,12 +135,28 @@
   // Grab performance counter value.
   LARGE_INTEGER now;
   QueryPerformanceCounter(&now);
-  int64_t qpc_value = static_cast<int64_t>(now.QuadPart);
+  return static_cast<int64_t>(now.QuadPart);
+}
+
+
+int64_t OS::GetCurrentMonotonicFrequency() {
+  if (qpc_ticks_per_second == 0) {
+    // QueryPerformanceCounter not supported, fallback.
+    return kMicrosecondsPerSecond;
+  }
+  return qpc_ticks_per_second;
+}
+
+
+int64_t OS::GetCurrentMonotonicMicros() {
+  int64_t ticks = GetCurrentMonotonicTicks();
+  int64_t frequency = GetCurrentMonotonicFrequency();
+
   // Convert to microseconds.
-  int64_t seconds = qpc_value / qpc_ticks_per_second;
-  int64_t leftover_ticks = qpc_value - (seconds * qpc_ticks_per_second);
+  int64_t seconds = ticks / frequency;
+  int64_t leftover_ticks = ticks - (seconds * frequency);
   int64_t result = seconds * kMicrosecondsPerSecond;
-  result += ((leftover_ticks * kMicrosecondsPerSecond) / qpc_ticks_per_second);
+  result += ((leftover_ticks * kMicrosecondsPerSecond) / frequency);
   return result;
 }
 
@@ -368,6 +388,7 @@
   init_once_called = true;
   // Do not pop up a message box when abort is called.
   _set_abort_behavior(0, _WRITE_ABORT_MSG);
+  ThreadLocalData::InitOnce();
   MonitorWaitData::monitor_wait_data_key_ = OSThread::CreateThreadLocal();
   MonitorData::GetMonitorWaitDataForThread();
   LARGE_INTEGER ticks_per_sec;
@@ -380,16 +401,24 @@
 
 
 void OS::Shutdown() {
+  // TODO(zra): Enable once VM can shutdown cleanly.
+  // ThreadLocalData::Shutdown();
 }
 
 
 void OS::Abort() {
+  // TODO(zra): Remove once VM shuts down cleanly.
+  private_flag_windows_run_tls_destructors = false;
   abort();
 }
 
 
 void OS::Exit(int code) {
-  exit(code);
+  // TODO(zra): Remove once VM shuts down cleanly.
+  private_flag_windows_run_tls_destructors = false;
+  // On Windows we use ExitProcess so that threads can't clobber the exit_code.
+  // See: https://code.google.com/p/nativeclient/issues/detail?id=2870
+  ::ExitProcess(code);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index da7ec80..5d5df0e 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -361,10 +361,10 @@
 
 
 uword PageSpace::TryAllocateInternal(intptr_t size,
-                            HeapPage::PageType type,
-                            GrowthPolicy growth_policy,
-                            bool is_protected,
-                            bool is_locked) {
+                                     HeapPage::PageType type,
+                                     GrowthPolicy growth_policy,
+                                     bool is_protected,
+                                     bool is_locked) {
   ASSERT(size >= kObjectAlignment);
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
 #ifdef DEBUG
@@ -657,13 +657,15 @@
 }
 
 
-void PageSpace::WriteProtect(bool read_only) {
+void PageSpace::WriteProtect(bool read_only, bool include_code_pages) {
   if (read_only) {
     // Avoid MakeIterable trying to write to the heap.
     AbandonBumpAllocation();
   }
   for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
-    it.page()->WriteProtect(read_only);
+    if ((it.page()->type() != HeapPage::kExecutable) || include_code_pages) {
+      it.page()->WriteProtect(read_only);
+    }
   }
 }
 
diff --git a/runtime/vm/pages.h b/runtime/vm/pages.h
index 39ef84e..17d1674 100644
--- a/runtime/vm/pages.h
+++ b/runtime/vm/pages.h
@@ -284,7 +284,7 @@
 
   // Note: Code pages are made executable/non-executable when 'read_only' is
   // true/false, respectively.
-  void WriteProtect(bool read_only);
+  void WriteProtect(bool read_only, bool include_code_pages);
   void WriteProtectCode(bool read_only);
 
   void AddGCTime(int64_t micros) {
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index ec199ea..47cb001 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -3,6 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/parser.h"
+#include "vm/flags.h"
+
+#ifndef DART_PRECOMPILED
 
 #include "lib/invocation_mirror.h"
 #include "platform/utils.h"
@@ -13,7 +16,6 @@
 #include "vm/compiler_stats.h"
 #include "vm/dart_api_impl.h"
 #include "vm/dart_entry.h"
-#include "vm/flags.h"
 #include "vm/growable_array.h"
 #include "vm/handles.h"
 #include "vm/hash_table.h"
@@ -46,7 +48,12 @@
 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef.");
 DEFINE_FLAG(bool, link_natives_lazily, false, "Link native calls lazily");
-DEFINE_FLAG(bool, move_super, false, "Move super initializer to end of list");
+DEFINE_FLAG(bool, conditional_directives, false,
+    "Enable conditional directives");
+DEFINE_FLAG(bool, warn_super, false,
+    "Warning if super initializer not last in initializer list.");
+DEFINE_FLAG(bool, await_is_keyword, false,
+    "await and yield are treated as proper keywords in synchronous code.");
 
 DECLARE_FLAG(bool, lazy_dispatchers);
 DECLARE_FLAG(bool, load_deferred_eagerly);
@@ -136,7 +143,7 @@
     LocalVariable* temp =
         new (Z) LocalVariable(function_.token_pos(),
                               Symbols::ExprTemp(),
-                              Type::ZoneHandle(Type::DynamicType()));
+                              Object::dynamic_type());
     ASSERT(temp != NULL);
     set_expression_temp_var(temp);
   }
@@ -150,7 +157,7 @@
     LocalVariable* temp = new(Z) LocalVariable(
         function_.token_pos(),
         String::ZoneHandle(Z, Symbols::New(":finally_ret_val")),
-        Type::ZoneHandle(Z, Type::DynamicType()));
+        Object::dynamic_type());
     ASSERT(temp != NULL);
     temp->set_is_final();
     if (is_async) {
@@ -232,7 +239,7 @@
 
 struct CatchParamDesc {
   CatchParamDesc()
-      : token_pos(0), type(NULL), name(NULL), var(NULL) { }
+      : token_pos(Scanner::kNoSourcePos), type(NULL), name(NULL), var(NULL) { }
   intptr_t token_pos;
   const AbstractType* type;
   const String* name;
@@ -384,9 +391,9 @@
 Parser::~Parser() {
   if (unregister_pending_function_) {
     const GrowableObjectArray& pending_functions =
-        GrowableObjectArray::Handle(I->object_store()->pending_functions());
+        GrowableObjectArray::Handle(T->pending_functions());
     ASSERT(pending_functions.Length() > 0);
-    ASSERT(pending_functions.At(pending_functions.Length()-1) ==
+    ASSERT(pending_functions.At(pending_functions.Length() - 1) ==
         current_function().raw());
     pending_functions.RemoveLast();
   }
@@ -451,6 +458,14 @@
   ASSERT(thread->long_jump_base()->IsSafeToJump());
   CSTAT_TIMER_SCOPE(thread, parser_timer);
   VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId);
+  TimelineDurationScope tds(thread,
+                            thread->isolate()->GetCompilerStream(),
+                            "CompileTopLevel");
+  if (tds.enabled()) {
+    tds.SetNumArguments(1);
+    tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString());
+  }
+
   Parser parser(script, library, 0);
   parser.ParseTopLevel();
 }
@@ -503,7 +518,7 @@
 struct ParamDesc {
   ParamDesc()
       : type(NULL),
-        name_pos(0),
+        name_pos(Scanner::kNoSourcePos),
         name(NULL),
         default_value(NULL),
         metadata(NULL),
@@ -558,10 +573,9 @@
   }
 
   void EraseParameterTypes() {
-    const Type& dynamic_type = Type::ZoneHandle(Type::DynamicType());
     const int num_parameters = parameters->length();
     for (int i = 0; i < num_parameters; i++) {
-      (*parameters)[i].type = &dynamic_type;
+      (*parameters)[i].type = &Object::dynamic_type();
     }
   }
 
@@ -598,6 +612,7 @@
   MemberDesc() {
     Clear();
   }
+
   void Clear() {
     has_abstract = false;
     has_external = false;
@@ -608,10 +623,10 @@
     has_factory = false;
     has_operator = false;
     has_native = false;
-    metadata_pos = -1;
+    metadata_pos = Scanner::kNoSourcePos;
     operator_token = Token::kILLEGAL;
     type = NULL;
-    name_pos = 0;
+    name_pos = Scanner::kNoSourcePos;
     name = NULL;
     redirect_name = NULL;
     dict_name = NULL;
@@ -619,6 +634,7 @@
     kind = RawFunction::kRegularFunction;
     field_ = NULL;
   }
+
   bool IsConstructor() const {
     return (kind == RawFunction::kConstructor) && !has_static;
   }
@@ -805,6 +821,13 @@
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const int64_t num_tokes_before = STAT_VALUE(thread, num_tokens_consumed);
+  TimelineDurationScope tds(thread,
+                            thread->isolate()->GetCompilerStream(),
+                            "ParseClass");
+  if (tds.enabled()) {
+    tds.SetNumArguments(1);
+    tds.CopyArgument(0, "class", String::Handle(cls.Name()).ToCString());
+  }
   if (!cls.is_synthesized_class()) {
     ASSERT(thread->long_jump_base()->IsSafeToJump());
     CSTAT_TIMER_SCOPE(thread, parser_timer);
@@ -827,12 +850,11 @@
 
 RawObject* Parser::ParseFunctionParameters(const Function& func) {
   ASSERT(!func.IsNull());
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  StackZone stack_zone(thread);
-  Zone* zone = stack_zone.GetZone();
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
+    Thread* thread = Thread::Current();
+    StackZone stack_zone(thread);
+    Zone* zone = stack_zone.GetZone();
     const Script& script = Script::Handle(zone, func.script());
     const Class& owner = Class::Handle(zone, func.Owner());
     ASSERT(!owner.IsNull());
@@ -863,6 +885,8 @@
     }
     return param_descriptor.raw();
   } else {
+    Thread* thread = Thread::Current();
+    Isolate* isolate = thread->isolate();
     Error& error = Error::Handle();
     error = isolate->object_store()->sticky_error();
     isolate->object_store()->clear_sticky_error();
@@ -913,23 +937,27 @@
   INC_STAT(thread, num_functions_parsed, 1);
   VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId,
                       FLAG_profile_vm);
-
+  TimelineDurationScope tds(thread,
+                            thread->isolate()->GetCompilerStream(),
+                            "ParseFunction");
   ASSERT(thread->long_jump_base()->IsSafeToJump());
   ASSERT(parsed_function != NULL);
   const Function& func = parsed_function->function();
   const Script& script = Script::Handle(zone, func.script());
   Parser parser(script, parsed_function, func.token_pos());
+  if (tds.enabled()) {
+    tds.SetNumArguments(1);
+    tds.CopyArgument(0, "function", String::Handle(func.name()).ToCString());
+  }
   SequenceNode* node_sequence = NULL;
   switch (func.kind()) {
     case RawFunction::kClosureFunction:
       if (func.IsImplicitClosureFunction()) {
-        node_sequence =
-            parser.ParseImplicitClosure(func);
+        node_sequence = parser.ParseImplicitClosure(func);
         break;
       }
       if (func.IsConstructorClosureFunction()) {
-        node_sequence =
-            parser.ParseConstructorClosure(func);
+        node_sequence = parser.ParseConstructorClosure(func);
         break;
       }
       // Fall-through: Handle non-implicit closures.
@@ -1006,14 +1034,15 @@
 }
 
 
-RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  StackZone stack_zone(thread);
-  Zone* zone = stack_zone.GetZone();
+RawObject* Parser::ParseMetadata(const Field& meta_data) {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
-    const Script& script = Script::Handle(zone, cls.script());
+    Thread* thread = Thread::Current();
+    StackZone stack_zone(thread);
+    Zone* zone = stack_zone.GetZone();
+    const Class& owner_class = Class::Handle(zone, meta_data.owner());
+    const Script& script = Script::Handle(zone, meta_data.script());
+    const intptr_t token_pos = meta_data.token_pos();
     // Parsing metadata can involve following paths in the parser that are
     // normally used for expressions and assume current_function is non-null,
     // so we create a fake function to use as the current_function rather than
@@ -1026,17 +1055,22 @@
         false,  // is_abstract
         false,  // is_external
         false,  // is_native
-        cls,
+        Object::Handle(zone, meta_data.RawOwner()),
         token_pos));
     fake_function.set_is_debuggable(false);
     ParsedFunction* parsed_function =
         new ParsedFunction(thread, fake_function);
     Parser parser(script, parsed_function, token_pos);
-    parser.set_current_class(cls);
+    parser.set_current_class(owner_class);
+    parser.OpenFunctionBlock(fake_function);
 
     RawObject* metadata = parser.EvaluateMetadata();
     return metadata;
   } else {
+    Thread* thread = Thread::Current();
+    Isolate* isolate = thread->isolate();
+    StackZone stack_zone(thread);
+    Zone* zone = stack_zone.GetZone();
     Error& error = Error::Handle(zone);
     error = isolate->object_store()->sticky_error();
     isolate->object_store()->clear_sticky_error();
@@ -1144,18 +1178,14 @@
   // TODO(koda): Should there be a StackZone here?
   Zone* zone = thread->zone();
 
-  const Class& script_cls = Class::Handle(zone, field.origin());
-  const Script& script = Script::Handle(zone, script_cls.script());
-
   const String& field_name = String::Handle(zone, field.name());
   String& init_name = String::Handle(zone,
       Symbols::FromConcat(Symbols::InitPrefix(), field_name));
 
+  const Script& script = Script::Handle(zone, field.script());
   Object& initializer_owner = Object::Handle(field.owner());
-  if (field.owner() != field.origin()) {
-    initializer_owner =
-        PatchClass::New(Class::Handle(field.owner()), script_cls);
-  }
+  initializer_owner =
+      PatchClass::New(Class::Handle(field.owner()), script);
 
   const Function& initializer = Function::ZoneHandle(zone,
       Function::New(init_name,
@@ -1340,11 +1370,11 @@
   ASSERT(!constructor.IsNull());
 
   ParamList params;
-  // The first parameter of the closure function is the implicit closure
-  // argument.
+  // The first parameter of the closure function is the
+  // implicit closure argument.
   params.AddFinalParameter(token_pos,
                            &Symbols::ClosureParameter(),
-                           &Type::ZoneHandle(Z, Type::DynamicType()));
+                           &Object::dynamic_type());
   bool params_ok = ParseFormalParameters(constructor, &params);
   USE(params_ok);
   ASSERT(params_ok);
@@ -1394,7 +1424,7 @@
   params.AddFinalParameter(
       token_pos,
       &Symbols::ClosureParameter(),
-      &Type::ZoneHandle(Type::DynamicType()));
+      &Object::dynamic_type());
 
   const Function& parent = Function::ZoneHandle(func.parent_function());
   if (parent.IsImplicitSetterFunction()) {
@@ -1430,8 +1460,10 @@
   }
 
   if (func.HasOptionalNamedParameters()) {
+    // TODO(srdjan): Must allocate array in old space, since it
+    // runs in background compiler. Find a better way.
     const Array& arg_names =
-        Array::ZoneHandle(Array::New(func.NumOptionalParameters()));
+        Array::ZoneHandle(Array::New(func.NumOptionalParameters(), Heap::kOld));
     for (intptr_t i = 0; i < arg_names.Length(); ++i) {
       intptr_t index = func.num_fixed_parameters() + i;
       arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index)));
@@ -1447,7 +1479,6 @@
 
 SequenceNode* Parser::ParseMethodExtractor(const Function& func) {
   TRACE_PARSER("ParseMethodExtractor");
-  ASSERT(FLAG_lazy_dispatchers);
 
   ParamList params;
 
@@ -1491,7 +1522,7 @@
     char name[64];
     OS::SNPrint(name, 64, ":p%" Pd, i);
     p.name = &String::ZoneHandle(Z, Symbols::New(name));
-    p.type = &Type::ZoneHandle(Z, Type::DynamicType());
+    p.type = &Object::dynamic_type();
     params.parameters->Add(p);
     params.num_fixed_parameters++;
   }
@@ -1502,7 +1533,7 @@
     ParamDesc p;
     intptr_t index = i - desc.PositionalCount();
     p.name = &String::ZoneHandle(Z, desc.NameAt(index));
-    p.type = &Type::ZoneHandle(Z, Type::DynamicType());
+    p.type = &Object::dynamic_type();
     p.default_value = &Object::null_instance();
     params.parameters->Add(p);
     params.num_optional_parameters++;
@@ -1692,6 +1723,8 @@
         is_match = opening_token == Token::kLBRACK;
         break;
       case Token::kEOS:
+        opening_token = token_stack.RemoveLast();
+        opening_pos = token_pos_stack.RemoveLast();
         unexpected_token_found = true;
         break;
       default:
@@ -1751,7 +1784,7 @@
     // The parameter type is the 'dynamic' type.
     // If this is an initializing formal, its type will be set to the type of
     // the respective field when the constructor is fully parsed.
-    parameter.type = &Type::ZoneHandle(Z, Type::DynamicType());
+    parameter.type = &Object::dynamic_type();
   }
   if (CurrentToken() == Token::kTHIS) {
     ConsumeToken();
@@ -1764,7 +1797,7 @@
     // This must later be changed to a closure type if we recognize
     // a closure/function type parameter. We check this at the end
     // of ParseFormalParameter.
-    parameter.type = &Type::ZoneHandle(Z, Type::VoidType());
+    parameter.type = &Object::void_type();
   }
   if (parameter.type == NULL) {
     // At this point, we must see an identifier for the type or the
@@ -1791,7 +1824,7 @@
     } else {
       // If this is an initializing formal, its type will be set to the type of
       // the respective field when the constructor is fully parsed.
-      parameter.type = &Type::ZoneHandle(Z, Type::DynamicType());
+      parameter.type = &Object::dynamic_type();
     }
   }
   if (!this_seen && (CurrentToken() == Token::kTHIS)) {
@@ -1840,11 +1873,18 @@
       func_params.AddFinalParameter(
           TokenPos(),
           &Symbols::ClosureParameter(),
-          &Type::ZoneHandle(Z, Type::DynamicType()));
+          &Object::dynamic_type());
 
       const bool no_explicit_default_values = false;
       ParseFormalParameterList(no_explicit_default_values, false, &func_params);
 
+      // In top-level and mixin functions, the source may be in a different
+      // script than the script of the current class.
+      Object& sig_func_owner = Object::Handle(Z, current_class().raw());
+      if (current_class().script() != script_.raw()) {
+        sig_func_owner = PatchClass::New(current_class(), script_);
+      }
+
       // The field 'is_static' has no meaning for signature functions.
       const Function& signature_function = Function::Handle(Z,
           Function::New(*parameter.name,
@@ -1854,18 +1894,18 @@
                         /* is_abstract = */ false,
                         /* is_external = */ false,
                         /* is_native = */ false,
-                        current_class(),
+                        sig_func_owner,
                         parameter.name_pos));
       signature_function.set_result_type(result_type);
       signature_function.set_is_debuggable(false);
       AddFormalParamsToFunction(&func_params, signature_function);
-      const String& signature = String::Handle(Z,
-                                               signature_function.Signature());
+      const String& signature =
+          String::Handle(Z, signature_function.Signature());
       // Lookup the signature class, i.e. the class whose name is the signature.
       // We only lookup in the current library, but not in its imports, and only
       // create a new canonical signature class if it does not exist yet.
-      Class& signature_class = Class::ZoneHandle(Z,
-          library_.LookupLocalClass(signature));
+      Class& signature_class =
+          Class::ZoneHandle(Z, library_.LookupLocalClass(signature));
       if (signature_class.IsNull()) {
         signature_class = Class::NewSignatureClass(signature,
                                                    signature_function,
@@ -2333,7 +2373,6 @@
       const Class& cls,
       intptr_t supercall_pos,
       LocalVariable* receiver,
-      AstNode* phase_parameter,
       ArgumentListNode* forwarding_args) {
   const Class& super_class = Class::Handle(Z, cls.SuperClass());
   // Omit the implicit super() if there is no super class (i.e.
@@ -2351,8 +2390,6 @@
   // Implicit 'this' parameter is the first argument.
   AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
   arguments->Add(implicit_argument);
-  // Implicit construction phase parameter is second argument.
-  arguments->Add(phase_parameter);
 
   // If this is a super call in a forwarding constructor, add the user-
   // defined arguments to the super call and adjust the the super
@@ -2418,14 +2455,7 @@
   // 'this' parameter is the first argument to super class constructor.
   AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
   arguments->Add(implicit_argument);
-  // Second implicit parameter is the construction phase. We optimistically
-  // assume that we can execute both the super initializer and the super
-  // constructor body. We may later change this to only execute the
-  // super initializer.
-  AstNode* phase_parameter =
-      new LiteralNode(supercall_pos,
-                      Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll)));
-  arguments->Add(phase_parameter);
+
   // 'this' parameter must not be accessible to the other super call arguments.
   receiver->set_invisible(true);
   ParseActualParameters(arguments, kAllowConst);
@@ -2522,7 +2552,7 @@
 
     if (found) continue;
 
-    field.RecordStore(Object::Handle(Z));
+    field.RecordStore(Object::null_object());
   }
 }
 
@@ -2539,8 +2569,7 @@
 
   set_current_class(Class::Handle(Z, field.origin()));
   set_library(Library::Handle(Z, current_class().library()));
-  SetScript(Script::Handle(Z, current_class().script()),
-            field.token_pos());
+  SetScript(Script::Handle(Z, current_class().script()), field.token_pos());
 
   ASSERT(IsIdentifier());
   ConsumeToken();
@@ -2689,12 +2718,12 @@
 
       // List argumentNames.
       // The missing implicit setter of the field has no argument names.
-      nsm_args->Add(new(Z) LiteralNode(init_pos, Array::ZoneHandle(Z)));
+      nsm_args->Add(new(Z) LiteralNode(init_pos, Object::null_array()));
 
       // List existingArgumentNames.
       // There is no setter for the final field, thus there are
       // no existing names.
-      nsm_args->Add(new(Z) LiteralNode(init_pos, Array::ZoneHandle(Z)));
+      nsm_args->Add(new(Z) LiteralNode(init_pos, Object::null_array()));
 
       AstNode* nsm_call =
           MakeStaticCall(Symbols::NoSuchMethodError(),
@@ -2754,17 +2783,15 @@
   if (super_init_call == NULL) {
     // Generate implicit super() if we haven't seen an explicit super call
     // or constructor redirection.
-    AstNode* phase_parameter = new LiteralNode(
-        TokenPos(), Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll)));
-    super_init_call = GenerateSuperConstructorCall(
-        cls, TokenPos(), receiver, phase_parameter, NULL);
+    super_init_call =
+        GenerateSuperConstructorCall(cls, TokenPos(), receiver, NULL);
     if (super_init_call != NULL) {
       super_init_index = current_block_->statements->length();
       current_block_->statements->Add(super_init_call);
       super_init_is_last = true;
     }
   }
-  if (FLAG_move_super && (super_init_call != NULL) && !super_init_is_last) {
+  if ((super_init_call != NULL) && !super_init_is_last) {
     // If the super initializer call is not at the end of the initializer
     // list, implicitly move it to the end. The actual parameter values
     // are evaluated at the original position in the list and preserved
@@ -2774,14 +2801,16 @@
     // A(x) : super(x), f = x++ { ... }
     // is transformed to:
     // A(x) : temp = x, f = x++, super(temp) { ... }
-    ReportWarning("Super initizlizer not at end");
+    if (FLAG_warn_super) {
+      ReportWarning("Super initializer not at end");
+    }
     ASSERT(super_init_index >= 0);
     ArgumentListNode* ctor_args = super_init_call->arguments();
     LetNode* saved_args = new(Z) LetNode(super_init_call->token_pos());
-    // The super initializer call has at least 2 arguments: the
-    // implicit receiver, and the hidden construction phase.
-    ASSERT(ctor_args->length() >= 2);
-    for (int i = 2; i < ctor_args->length(); i++) {
+    // The super initializer call has at least 1 arguments: the
+    // implicit receiver.
+    ASSERT(ctor_args->length() >= 1);
+    for (int i = 1; i < ctor_args->length(); i++) {
       AstNode* arg = ctor_args->NodeAt(i);
       LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca");
       AstNode* save_temp = new(Z) StoreLocalNode(arg->token_pos(), temp, arg);
@@ -2817,11 +2846,7 @@
   // 'this' parameter is the first argument to constructor.
   AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver);
   arguments->Add(implicit_argument);
-  // Construction phase parameter is second argument.
-  LocalVariable* phase_param = LookupPhaseParameter();
-  ASSERT(phase_param != NULL);
-  AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param);
-  arguments->Add(phase_argument);
+
   receiver->set_invisible(true);
   ParseActualParameters(arguments, kAllowConst);
   receiver->set_invisible(false);
@@ -2855,12 +2880,6 @@
       Scanner::kNoSourcePos, Symbols::This(), *ReceiverType(current_class()));
   current_block_->scope->InsertParameterAt(0, receiver);
 
-  LocalVariable* phase_parameter =
-      new LocalVariable(Scanner::kNoSourcePos,
-                        Symbols::PhaseParameter(),
-                        Type::ZoneHandle(Z, Type::SmiType()));
-  current_block_->scope->InsertParameterAt(1, phase_parameter);
-
   // Parse expressions of instance fields that have an explicit
   // initializer expression.
   // The receiver must not be visible to field initializer expressions.
@@ -2900,13 +2919,13 @@
     }
 
     // Prepare user-defined arguments to be forwarded to super call.
-    // The first user-defined argument is at position 2.
+    // The first user-defined argument is at position 1.
     forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos);
-    for (int i = 2; i < func.NumParameters(); i++) {
+    for (int i = 1; i < func.NumParameters(); i++) {
       LocalVariable* param = new LocalVariable(
           Scanner::kNoSourcePos,
           String::ZoneHandle(Z, func.ParameterNameAt(i)),
-          Type::ZoneHandle(Z, Type::DynamicType()));
+          Object::dynamic_type());
       current_block_->scope->InsertParameterAt(i, param);
       forwarding_args->Add(new LoadLocalNode(Scanner::kNoSourcePos, param));
     }
@@ -2916,7 +2935,6 @@
       current_class(),
       Scanner::kNoSourcePos,
       receiver,
-      new LoadLocalNode(Scanner::kNoSourcePos, phase_parameter),
       forwarding_args);
   if (super_call != NULL) {
     current_block_->statements->Add(super_call);
@@ -2932,8 +2950,7 @@
 
 void Parser::CheckRecursiveInvocation() {
   const GrowableObjectArray& pending_functions =
-      GrowableObjectArray::Handle(Z,
-          I->object_store()->pending_functions());
+      GrowableObjectArray::Handle(Z, T->pending_functions());
   for (int i = 0; i < pending_functions.Length(); i++) {
     if (pending_functions.At(i) == current_function().raw()) {
       const String& fname =
@@ -2980,12 +2997,6 @@
   ASSERT(current_class().raw() == func.Owner());
   params.AddReceiver(ReceiverType(current_class()), func.token_pos());
 
-  // Add implicit parameter for construction phase.
-  params.AddFinalParameter(
-      TokenPos(),
-      &Symbols::PhaseParameter(),
-      &Type::ZoneHandle(Z, Type::SmiType()));
-
   if (func.is_const()) {
     params.SetImplicitlyFinal();
   }
@@ -3025,9 +3036,9 @@
 
   // Turn formal field parameters into field initializers.
   if (params.has_field_initializer) {
-    // First two parameters are implicit receiver and phase.
-    ASSERT(params.parameters->length() >= 2);
-    for (int i = 2; i < params.parameters->length(); i++) {
+    // The first parameter is the implicit receiver.
+    ASSERT(params.parameters->length() >= 1);
+    for (int i = 1; i < params.parameters->length(); i++) {
       ParamDesc& param = (*params.parameters)[i];
       if (param.is_field_initializer) {
         const String& field_name = *param.name;
@@ -3084,121 +3095,10 @@
   }
 
   SequenceNode* init_statements = CloseBlock();
-  if (is_redirecting_constructor) {
-    // A redirecting super constructor simply passes the phase parameter on to
-    // the target which executes the corresponding phase.
-    current_block_->statements->Add(init_statements);
-  } else if (init_statements->length() > 0) {
-    // Generate guard around the initializer code.
-    LocalVariable* phase_param = LookupPhaseParameter();
-    AstNode* phase_value = new
-        LoadLocalNode(Scanner::kNoSourcePos, phase_param);
-    AstNode* phase_check = new BinaryOpNode(
-        Scanner::kNoSourcePos, Token::kBIT_AND, phase_value,
-        new LiteralNode(Scanner::kNoSourcePos,
-            Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseInit))));
-    AstNode* comparison =
-        new ComparisonNode(Scanner::kNoSourcePos,
-                           Token::kNE_STRICT,
-                           phase_check,
-                           new LiteralNode(TokenPos(),
-                                           Smi::ZoneHandle(Z, Smi::New(0))));
-    AstNode* guarded_init_statements =
-        new IfNode(Scanner::kNoSourcePos,
-                   comparison,
-                   init_statements,
-                   NULL);
-    current_block_->statements->Add(guarded_init_statements);
-  }
+  current_block_->statements->Add(init_statements);
 
-  // Parsing of initializers done. Now we parse the constructor body
-  // and add the implicit super call to the super constructor's body
-  // if necessary.
-  StaticCallNode* super_call = NULL;
-  // Look for the super initializer call in the sequence of initializer
-  // statements. If it exists and is not the last initializer statement,
-  // we need to create an implicit super call to the super constructor's
-  // body.
-  // Thus, iterate over all but the last initializer to see whether
-  // it's a super constructor call.
-  for (int i = 0; i < init_statements->length() - 1; i++) {
-    if (init_statements->NodeAt(i)->IsStaticCallNode()) {
-      StaticCallNode* static_call =
-      init_statements->NodeAt(i)->AsStaticCallNode();
-      if (static_call->function().IsGenerativeConstructor()) {
-        super_call = static_call;
-        break;
-      }
-    }
-  }
-  if (super_call != NULL) {
-    ASSERT(!FLAG_move_super);
-    // Generate an implicit call to the super constructor's body.
-    // We need to patch the super _initializer_ call so that it
-    // saves the evaluated actual arguments in temporary variables.
-    // The temporary variables are necessary so that the argument
-    // expressions are not evaluated twice.
-    // Note: we should never get here in the case of a redirecting
-    // constructor. In that case, the call to the target constructor
-    // is the "super call" and is implicitly at the end of the
-    // initializer list.
-    ASSERT(!is_redirecting_constructor);
-    ArgumentListNode* ctor_args = super_call->arguments();
-    // The super initializer call has at least 2 arguments: the
-    // implicit receiver, and the hidden construction phase.
-    ASSERT(ctor_args->length() >= 2);
-    for (int i = 2; i < ctor_args->length(); i++) {
-      AstNode* arg = ctor_args->NodeAt(i);
-      if (!IsSimpleLocalOrLiteralNode(arg)) {
-        LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca");
-        AstNode* save_temp = new StoreLocalNode(arg->token_pos(), temp, arg);
-        ctor_args->SetNodeAt(i, save_temp);
-      }
-    }
-  }
+  // Parsing of initializers done. Now we parse the constructor body.
   OpenBlock();  // Block to collect constructor body nodes.
-  intptr_t body_pos = TokenPos();
-
-  // Insert the implicit super call to the super constructor body.
-  if (super_call != NULL) {
-    ASSERT(!FLAG_move_super);
-    ArgumentListNode* initializer_args = super_call->arguments();
-    const Function& super_ctor = super_call->function();
-    // Patch the initializer call so it only executes the super initializer.
-    initializer_args->SetNodeAt(1, new LiteralNode(
-        body_pos, Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseInit))));
-
-    ArgumentListNode* super_call_args = new ArgumentListNode(body_pos);
-    // First argument is the receiver.
-    super_call_args->Add(new LoadLocalNode(body_pos, receiver));
-    // Second argument is the construction phase argument.
-    AstNode* phase_parameter = new(Z) LiteralNode(
-        body_pos, Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseBody)));
-    super_call_args->Add(phase_parameter);
-    super_call_args->set_names(initializer_args->names());
-    for (int i = 2; i < initializer_args->length(); i++) {
-      AstNode* arg = initializer_args->NodeAt(i);
-      if (arg->IsLiteralNode()) {
-        LiteralNode* lit = arg->AsLiteralNode();
-        super_call_args->Add(new LiteralNode(body_pos, lit->literal()));
-      } else {
-        ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode());
-        if (arg->IsLoadLocalNode()) {
-          const LocalVariable& temp = arg->AsLoadLocalNode()->local();
-          super_call_args->Add(new LoadLocalNode(body_pos, &temp));
-        } else if (arg->IsStoreLocalNode()) {
-          const LocalVariable& temp = arg->AsStoreLocalNode()->local();
-          super_call_args->Add(new LoadLocalNode(body_pos, &temp));
-        }
-      }
-    }
-    ASSERT(super_ctor.AreValidArguments(super_call_args->length(),
-                                        super_call_args->names(),
-                                        NULL));
-    current_block_->statements->Add(
-        new StaticCallNode(body_pos, super_ctor, super_call_args));
-  }
-
   if (CurrentToken() == Token::kLBRACE) {
     // We checked in the top-level parse phase that a redirecting
     // constructor does not have a body.
@@ -3231,24 +3131,7 @@
 
   SequenceNode* ctor_block = CloseBlock();
   if (ctor_block->length() > 0) {
-    // Generate guard around the constructor body code.
-    LocalVariable* phase_param = LookupPhaseParameter();
-    AstNode* phase_value =
-        new LoadLocalNode(Scanner::kNoSourcePos, phase_param);
-    AstNode* phase_check =
-        new BinaryOpNode(Scanner::kNoSourcePos, Token::kBIT_AND,
-            phase_value,
-            new LiteralNode(Scanner::kNoSourcePos,
-                Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))));
-    AstNode* comparison =
-        new ComparisonNode(Scanner::kNoSourcePos,
-                           Token::kNE_STRICT,
-                           phase_check,
-                           new LiteralNode(body_pos,
-                                           Smi::ZoneHandle(Smi::New(0))));
-    AstNode* guarded_block_statements =
-        new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL);
-    current_block_->statements->Add(guarded_block_statements);
+    current_block_->statements->Add(ctor_block);
   }
   current_block_->statements->Add(new ReturnNode(func.end_token_pos()));
   SequenceNode* statements = CloseBlock();
@@ -3292,7 +3175,7 @@
     params.AddFinalParameter(
         TokenPos(),
         &Symbols::ClosureParameter(),
-        &Type::ZoneHandle(Z, Type::DynamicType()));
+        &Object::dynamic_type());
   } else if (!func.is_static()) {
     // Static functions do not have a receiver.
     ASSERT(current_class().raw() == func.Owner());
@@ -3303,7 +3186,7 @@
     params.AddFinalParameter(
         TokenPos(),
         &Symbols::TypeArgumentsParameter(),
-        &Type::ZoneHandle(Z, Type::DynamicType()));
+        &Object::dynamic_type());
   }
   // Expect the parameter list unless this is a getter function, or the
   // body closure of an async or generator getter function.
@@ -3436,7 +3319,7 @@
 
   BoolScope allow_await(&this->await_is_keyword_,
                         func.IsAsyncOrGenerator() || func.is_generated_body());
-  intptr_t end_token_pos = 0;
+  intptr_t end_token_pos = Scanner::kNoSourcePos;
   if (CurrentToken() == Token::kLBRACE) {
     ConsumeToken();
     if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) {
@@ -3666,14 +3549,7 @@
     method->params.AddFinalParameter(
         formal_param_pos,
         &Symbols::TypeArgumentsParameter(),
-        &Type::ZoneHandle(Z, Type::DynamicType()));
-  }
-  // Constructors have an implicit parameter for the construction phase.
-  if (method->IsConstructor()) {
-    method->params.AddFinalParameter(
-        TokenPos(),
-        &Symbols::PhaseParameter(),
-        &Type::ZoneHandle(Z, Type::SmiType()));
+        &Object::dynamic_type());
   }
   if (are_implicitly_final) {
     method->params.SetImplicitlyFinal();
@@ -3826,6 +3702,7 @@
   }
 
   intptr_t method_end_pos = TokenPos();
+  String* native_name = NULL;
   if ((CurrentToken() == Token::kLBRACE) ||
       (CurrentToken() == Token::kARROW)) {
     if (method->has_abstract) {
@@ -3881,7 +3758,7 @@
       ReportError(method->name_pos,
                   "Constructor with redirection may not have a function body");
     }
-    ParseNativeDeclaration();
+    native_name = &ParseNativeDeclaration();
     method_end_pos = TokenPos();
     ExpectSemicolon();
     method->has_native = true;
@@ -3956,9 +3833,12 @@
   if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) {
     func.set_is_reflectable(false);
   }
-  if (method->metadata_pos > 0) {
+  if (FLAG_enable_mirrors && (method->metadata_pos >= 0)) {
     library_.AddFunctionMetadata(func, method->metadata_pos);
   }
+  if (method->has_native) {
+    func.set_native_name(*native_name);
+  }
 
   // If this method is a redirecting factory, set the redirection information.
   if (!redirection_type.IsNull()) {
@@ -3984,7 +3864,7 @@
          CurrentToken() == Token::kCOMMA ||
          CurrentToken() == Token::kASSIGN);
   ASSERT(field->type != NULL);
-  ASSERT(field->name_pos > 0);
+  ASSERT(field->name_pos >= 0);
   ASSERT(current_member_ == field);
   // All const fields are also final.
   ASSERT(!field->has_const || field->has_final);
@@ -4048,12 +3928,12 @@
                              field->has_const,
                              is_reflectable,
                              current_class(),
+                             *field->type,
                              field->name_pos);
-    class_field.set_type(*field->type);
     class_field.set_has_initializer(has_initializer);
     members->AddField(class_field);
     field->field_ = &class_field;
-    if (field->metadata_pos >= 0) {
+    if (FLAG_enable_mirrors && (field->metadata_pos >= 0)) {
       library_.AddFieldMetadata(class_field, field->metadata_pos);
     }
 
@@ -4129,7 +4009,7 @@
         params.AddFinalParameter(TokenPos(),
                                  &Symbols::Value(),
                                  field->type);
-        setter.set_result_type(Type::Handle(Z, Type::VoidType()));
+        setter.set_result_type(Object::void_type());
         setter.set_is_debuggable(false);
         if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) {
           setter.set_is_reflectable(false);
@@ -4233,7 +4113,7 @@
     ConsumeToken();
     member.has_var = true;
     // The member type is the 'dynamic' type.
-    member.type = &Type::ZoneHandle(Z, Type::DynamicType());
+    member.type = &Object::dynamic_type();
   } else if (CurrentToken() == Token::kFACTORY) {
     ConsumeToken();
     if (member.has_static) {
@@ -4250,7 +4130,7 @@
     }
     ConsumeToken();
     ASSERT(member.type == NULL);
-    member.type = &Type::ZoneHandle(Z, Type::VoidType());
+    member.type = &Object::void_type();
   } else if (CurrentToken() == Token::kIDENT) {
     // This is either a type name or the name of a method/constructor/field.
     if ((member.type == NULL) && !member.has_factory) {
@@ -4345,7 +4225,7 @@
     // The grammar allows a return type, so member.type is not always NULL here.
     // If no return type is specified, the return type of the setter is dynamic.
     if (member.type == NULL) {
-      member.type = &Type::ZoneHandle(Z, Type::DynamicType());
+      member.type = &Object::dynamic_type();
     }
   } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var &&
              (LookaheadToken(1) != Token::kLPAREN) &&
@@ -4378,7 +4258,7 @@
   if (CurrentToken() == Token::kLPAREN || member.IsGetter()) {
     // Constructor or method.
     if (member.type == NULL) {
-      member.type = &Type::ZoneHandle(Z, Type::DynamicType());
+      member.type = &Object::dynamic_type();
     }
     ASSERT(member.IsFactory() == member.has_factory);
     ParseMethodOrConstructor(members, &member);
@@ -4392,7 +4272,7 @@
     }
     if (member.type == NULL) {
       if (member.has_final) {
-        member.type = &Type::ZoneHandle(Z, Type::DynamicType());
+        member.type = &Object::dynamic_type();
       } else {
         ReportError("missing 'var', 'final', 'const' or type"
                     " in field declaration");
@@ -4409,11 +4289,11 @@
 
 
 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes,
-                                  const Class& toplevel_class,
+                                  const Object& tl_owner,
                                   intptr_t metadata_pos) {
   TRACE_PARSER("ParseEnumDeclaration");
-  const intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos
-                                                      : TokenPos();
+  const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos
+                                                       : TokenPos();
   ConsumeToken();
   const intptr_t name_pos = TokenPos();
   String* enum_name =
@@ -4450,8 +4330,8 @@
   library_.AddClass(cls);
   cls.set_is_synthesized_class();
   cls.set_is_enum_class();
-  if (metadata_pos >= 0) {
-    library_.AddClassMetadata(cls, toplevel_class, metadata_pos);
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+    library_.AddClassMetadata(cls, tl_owner, metadata_pos);
   }
   cls.set_super_type(Type::Handle(Z, Type::ObjectType()));
   pending_classes.Add(cls, Heap::kOld);
@@ -4459,12 +4339,12 @@
 
 
 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes,
-                                   const Class& toplevel_class,
+                                   const Object& tl_owner,
                                    intptr_t metadata_pos) {
   TRACE_PARSER("ParseClassDeclaration");
   bool is_patch = false;
   bool is_abstract = false;
-  intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos : TokenPos();
+  intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos();
   if (is_patch_source() &&
       (CurrentToken() == Token::kIDENT) &&
       CurrentLiteral()->Equals("patch")) {
@@ -4573,8 +4453,8 @@
   if (is_abstract) {
     cls.set_is_abstract();
   }
-  if (metadata_pos >= 0) {
-    library_.AddClassMetadata(cls, toplevel_class, metadata_pos);
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+    library_.AddClassMetadata(cls, tl_owner, metadata_pos);
   }
 
   const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN);
@@ -4630,13 +4510,12 @@
   }
 
   if (is_patch) {
+    cls.set_is_patch();
     // Apply the changes to the patched class looked up above.
     ASSERT(obj.raw() == library_.LookupLocalObject(class_name));
     // The patched class must not be finalized yet.
-    const Class& orig_class = Class::Cast(obj);
-    ASSERT(!orig_class.is_finalized());
-    orig_class.set_patch_class(cls);
-    cls.set_is_patch();
+    ASSERT(!Class::Cast(obj).is_finalized());
+    library_.AddPatchClass(cls);
   }
   pending_classes.Add(cls, Heap::kOld);
 
@@ -4717,21 +4596,20 @@
   SkipMetadata();
   ExpectToken(Token::kENUM);
 
-  const String& enum_name = String::Handle(Z, cls.Name());
+  const String& enum_name = String::Handle(Z, cls.PrettyName());
   ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos());
 
   // Add instance field 'final int index'.
   Field& index_field = Field::ZoneHandle(Z);
   const Type& int_type = Type::Handle(Z, Type::IntType());
-  const Type& dynamic_type = Type::Handle(Type::DynamicType());
   index_field = Field::New(Symbols::Index(),
                            false,  // Not static.
                            true,  // Field is final.
                            false,  // Not const.
                            true,  // Is reflectable.
                            cls,
+                           int_type,
                            cls.token_pos());
-  index_field.set_type(int_type);
   enum_members.AddField(index_field);
 
   // Add implicit getter for index field.
@@ -4750,7 +4628,7 @@
   getter.set_result_type(int_type);
   getter.set_is_debuggable(false);
   ParamList params;
-  params.AddReceiver(&dynamic_type, cls.token_pos());
+  params.AddReceiver(&Object::dynamic_type(), cls.token_pos());
   AddFormalParamsToFunction(&params, getter);
   enum_members.AddFunction(getter);
 
@@ -4802,8 +4680,8 @@
                             /* is_const = */ true,
                             /* is_reflectable = */ true,
                             cls,
+                            Object::dynamic_type(),
                             cls.token_pos());
-    enum_value.set_type(dynamic_type);
     enum_value.set_has_initializer(false);
     enum_members.AddField(enum_value);
     // Initialize the field with the ordinal value. It will be patched
@@ -4840,8 +4718,8 @@
                             /* is_const = */ true,
                             /* is_reflectable = */ true,
                             cls,
+                            Type::Handle(Z, Type::ArrayType()),
                             cls.token_pos());
-  values_field.set_type(Type::Handle(Z, Type::ArrayType()));
   enum_members.AddField(values_field);
 
   // Allocate the immutable array containing the enumeration values.
@@ -4909,10 +4787,6 @@
   // Add implicit 'this' parameter.
   const AbstractType* receiver_type = ReceiverType(cls);
   params.AddReceiver(receiver_type, cls.token_pos());
-  // Add implicit parameter for construction phase.
-  params.AddFinalParameter(cls.token_pos(),
-                           &Symbols::PhaseParameter(),
-                           &Type::ZoneHandle(Z, Type::SmiType()));
 
   AddFormalParamsToFunction(&params, ctor);
   // The body of the constructor cannot modify the type of the constructed
@@ -4955,7 +4829,7 @@
 
 void Parser::ParseMixinAppAlias(
     const GrowableObjectArray& pending_classes,
-    const Class& toplevel_class,
+    const Object& tl_owner,
     intptr_t metadata_pos) {
   TRACE_PARSER("ParseMixinAppAlias");
   const intptr_t classname_pos = TokenPos();
@@ -5008,8 +4882,8 @@
   }
   ExpectSemicolon();
   pending_classes.Add(mixin_application, Heap::kOld);
-  if (metadata_pos >= 0) {
-    library_.AddClassMetadata(mixin_application, toplevel_class, metadata_pos);
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+    library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos);
   }
 }
 
@@ -5055,17 +4929,17 @@
 
 
 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes,
-                          const Class& toplevel_class,
+                          const Object& tl_owner,
                           intptr_t metadata_pos) {
   TRACE_PARSER("ParseTypedef");
-  intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos : TokenPos();
+  intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos();
   ExpectToken(Token::kTYPEDEF);
 
   if (IsMixinAppAlias()) {
     if (FLAG_warn_mixin_typedef) {
       ReportWarning(TokenPos(), "deprecated mixin application typedef");
     }
-    ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos);
+    ParseMixinAppAlias(pending_classes, tl_owner, metadata_pos);
     return;
   }
 
@@ -5121,7 +4995,7 @@
   func_params.AddFinalParameter(
       TokenPos(),
       &Symbols::ClosureParameter(),
-      &Type::ZoneHandle(Z, Type::DynamicType()));
+      &Object::dynamic_type());
 
   const bool no_explicit_default_values = false;
   ParseFormalParameterList(no_explicit_default_values, false, &func_params);
@@ -5174,9 +5048,9 @@
   ASSERT(!function_type_alias.IsCanonicalSignatureClass());
   ASSERT(!function_type_alias.is_finalized());
   pending_classes.Add(function_type_alias, Heap::kOld);
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     library_.AddClassMetadata(function_type_alias,
-                              toplevel_class,
+                              tl_owner,
                               metadata_pos);
   }
 }
@@ -5199,7 +5073,7 @@
 
 intptr_t Parser::SkipMetadata() {
   if (CurrentToken() != Token::kAT) {
-    return -1;
+    return Scanner::kNoSourcePos;
   }
   intptr_t metadata_pos = TokenPos();
   while (CurrentToken() == Token::kAT) {
@@ -5267,8 +5141,8 @@
       ConsumeToken();
       const intptr_t metadata_pos = SkipMetadata();
       const intptr_t type_parameter_pos = TokenPos();
-      const intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos
-                                                          : type_parameter_pos;
+      const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos
+                                                           : type_parameter_pos;
       String& type_parameter_name =
           *ExpectUserDefinedTypeIdentifier("type parameter expected");
       // Check for duplicate type parameters.
@@ -5297,7 +5171,7 @@
                                           declaration_pos);
       type_parameters_array.Add(
           &AbstractType::ZoneHandle(Z, type_parameter.raw()));
-      if (metadata_pos >= 0) {
+      if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
         library_.AddTypeParameterMetadata(type_parameter, metadata_pos);
       }
       index++;
@@ -5413,6 +5287,7 @@
 
 
 void Parser::ParseTopLevelVariable(TopLevel* top_level,
+                                   const Object& owner,
                                    intptr_t metadata_pos) {
   TRACE_PARSER("ParseTopLevelVariable");
   const bool is_const = (CurrentToken() == Token::kCONST);
@@ -5448,13 +5323,14 @@
 
     const bool is_reflectable =
         !(library_.is_dart_scheme() && library_.IsPrivate(var_name));
-    field = Field::New(var_name, is_static, is_final, is_const, is_reflectable,
-                       current_class(), name_pos);
-    field.set_type(type);
+
+    field = Field::NewTopLevel(var_name, is_final, is_const, owner, name_pos);
+    field.SetFieldType(type);
+    field.set_is_reflectable(is_reflectable);
     field.SetStaticValue(Object::null_instance(), true);
     top_level->AddField(field);
     library_.AddObject(field, var_name);
-    if (metadata_pos >= 0) {
+    if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
       library_.AddFieldMetadata(field, metadata_pos);
     }
     if (CurrentToken() == Token::kASSIGN) {
@@ -5478,13 +5354,11 @@
                                /* is_abstract = */ false,
                                /* is_external = */ false,
                                /* is_native = */ false,
-                               current_class(),
+                               owner,
                                name_pos);
         getter.set_result_type(type);
         getter.set_is_debuggable(false);
-        if (library_.is_dart_scheme() && library_.IsPrivate(var_name)) {
-          getter.set_is_reflectable(false);
-        }
+        getter.set_is_reflectable(is_reflectable);
         top_level->AddFunction(getter);
       }
     } else if (is_final) {
@@ -5531,6 +5405,7 @@
 
 
 void Parser::ParseTopLevelFunction(TopLevel* top_level,
+                                   const Object& owner,
                                    intptr_t metadata_pos) {
   TRACE_PARSER("ParseTopLevelFunction");
   const intptr_t decl_begin_pos = TokenPos();
@@ -5587,6 +5462,7 @@
 
   intptr_t function_end_pos = function_pos;
   bool is_native = false;
+  String* native_name = NULL;
   if (is_external) {
     function_end_pos = TokenPos();
     ExpectSemicolon();
@@ -5606,7 +5482,7 @@
     function_end_pos = TokenPos();
     ExpectSemicolon();
   } else if (IsSymbol(Symbols::Native())) {
-    ParseNativeDeclaration();
+    native_name = &ParseNativeDeclaration();
     function_end_pos = TokenPos();
     ExpectSemicolon();
     is_native = true;
@@ -5621,7 +5497,7 @@
                     /* is_abstract = */ false,
                     is_external,
                     is_native,
-                    current_class(),
+                    owner,
                     decl_begin_pos));
   func.set_result_type(result_type);
   func.set_end_token_pos(function_end_pos);
@@ -5629,20 +5505,30 @@
   if (library_.is_dart_scheme() && library_.IsPrivate(func_name)) {
     func.set_is_reflectable(false);
   }
+  if (is_native) {
+    func.set_native_name(*native_name);
+  }
   AddFormalParamsToFunction(&params, func);
   top_level->AddFunction(func);
   if (!is_patch) {
     library_.AddObject(func, func_name);
   } else {
+    // Need to remove the previously added function that is being patched.
+    const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class());
+    const Function& replaced_func =
+        Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name));
+    ASSERT(!replaced_func.IsNull());
+    toplevel_cls.RemoveFunction(replaced_func);
     library_.ReplaceObject(func, func_name);
   }
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     library_.AddFunctionMetadata(func, metadata_pos);
   }
 }
 
 
 void Parser::ParseTopLevelAccessor(TopLevel* top_level,
+                                   const Object& owner,
                                    intptr_t metadata_pos) {
   TRACE_PARSER("ParseTopLevelAccessor");
   const intptr_t decl_begin_pos = TokenPos();
@@ -5737,6 +5623,7 @@
 
   intptr_t accessor_end_pos = accessor_pos;
   bool is_native = false;
+  String* native_name = NULL;
   if (is_external) {
     accessor_end_pos = TokenPos();
     ExpectSemicolon();
@@ -5756,7 +5643,7 @@
     accessor_end_pos = TokenPos();
     ExpectSemicolon();
   } else if (IsSymbol(Symbols::Native())) {
-    ParseNativeDeclaration();
+    native_name = &ParseNativeDeclaration();
     accessor_end_pos = TokenPos();
     ExpectSemicolon();
     is_native = true;
@@ -5772,13 +5659,14 @@
                     /* is_abstract = */ false,
                     is_external,
                     is_native,
-                    current_class(),
+                    owner,
                     decl_begin_pos));
   func.set_result_type(result_type);
   func.set_end_token_pos(accessor_end_pos);
   func.set_modifier(func_modifier);
   if (is_native) {
     func.set_is_debuggable(false);
+    func.set_native_name(*native_name);
   }
   if (library_.is_dart_scheme() && library_.IsPrivate(accessor_name)) {
     func.set_is_reflectable(false);
@@ -5788,9 +5676,17 @@
   if (!is_patch) {
     library_.AddObject(func, accessor_name);
   } else {
+    // Need to remove the previously added accessor that is being patched.
+    const Class& toplevel_cls = Class::Handle(Z,
+        owner.IsClass() ? Class::Cast(owner).raw()
+                        : PatchClass::Cast(owner).patched_class());
+    const Function& replaced_func =
+        Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name));
+    ASSERT(!replaced_func.IsNull());
+    toplevel_cls.RemoveFunction(replaced_func);
     library_.ReplaceObject(func, accessor_name);
   }
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     library_.AddFunctionMetadata(func, metadata_pos);
   }
 }
@@ -5812,10 +5708,10 @@
   // Block class finalization attempts when calling into the library
   // tag handler.
   I->BlockClassFinalization();
-  Api::Scope api_scope(I);
+  Api::Scope api_scope(T);
   Dart_Handle result = handler(tag,
-                               Api::NewHandle(I, library_.raw()),
-                               Api::NewHandle(I, url.raw()));
+                               Api::NewHandle(T, library_.raw()),
+                               Api::NewHandle(T, url.raw()));
   I->UnblockClassFinalization();
   if (Dart_IsError(result)) {
     // In case of an error we append an explanatory error message to the
@@ -5867,7 +5763,8 @@
 }
 
 
-void Parser::ParseLibraryImportExport(intptr_t metadata_pos) {
+void Parser::ParseLibraryImportExport(const Object& tl_owner,
+                                      intptr_t metadata_pos) {
   bool is_import = (CurrentToken() == Token::kIMPORT);
   bool is_export = (CurrentToken() == Token::kEXPORT);
   ASSERT(is_import || is_export);
@@ -5875,6 +5772,53 @@
   ConsumeToken();
   CheckToken(Token::kSTRING, "library url expected");
   AstNode* url_literal = ParseStringLiteral(false);
+  if (FLAG_conditional_directives) {
+    bool condition_triggered = false;
+    while (CurrentToken() == Token::kIF) {
+      // Conditional import: if (env == val) uri.
+      ConsumeToken();
+      ExpectToken(Token::kLPAREN);
+      // Parse dotted name.
+      const GrowableObjectArray& pieces =
+          GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+      pieces.Add(*ExpectIdentifier("identifier expected"));
+      while (CurrentToken() == Token::kPERIOD) {
+        pieces.Add(Symbols::Dot());
+        ConsumeToken();
+        pieces.Add(*ExpectIdentifier("identifier expected"));
+      }
+      AstNode* valueNode = NULL;
+      if (CurrentToken() == Token::kEQ) {
+        ConsumeToken();
+        CheckToken(Token::kSTRING, "string literal expected");
+        valueNode = ParseStringLiteral(false);
+        ASSERT(valueNode->IsLiteralNode());
+        ASSERT(valueNode->AsLiteralNode()->literal().IsString());
+      }
+      ExpectToken(Token::kRPAREN);
+      CheckToken(Token::kSTRING, "library url expected");
+      AstNode* conditional_url_literal = ParseStringLiteral(false);
+
+      // If there was already a condition that triggered, don't try to match
+      // again.
+      if (condition_triggered) {
+        continue;
+      }
+      // Check if this conditional line overrides the default import.
+      const String& key = String::Handle(
+          String::ConcatAll(Array::Handle(Array::MakeArray(pieces))));
+      const String& value = (valueNode == NULL)
+          ? Symbols::True()
+          : String::Cast(valueNode->AsLiteralNode()->literal());
+      // Call the embedder to supply us with the environment.
+      const String& env_value =
+          String::Handle(Api::CallEnvironmentCallback(T, key));
+      if (!env_value.IsNull() && env_value.Equals(value)) {
+        condition_triggered = true;
+        url_literal = conditional_url_literal;
+      }
+    }
+  }
   ASSERT(url_literal->IsLiteralNode());
   ASSERT(url_literal->AsLiteralNode()->literal().IsString());
   const String& url = String::Cast(url_literal->AsLiteralNode()->literal());
@@ -5888,7 +5832,7 @@
     CheckToken(Token::kAS, "'as' expected");
   }
   String& prefix = String::Handle(Z);
-  intptr_t prefix_pos = 0;
+  intptr_t prefix_pos = Scanner::kNoSourcePos;
   if (is_import && (CurrentToken() == Token::kAS)) {
     ConsumeToken();
     prefix_pos = TokenPos();
@@ -5951,8 +5895,8 @@
 
   Namespace& ns = Namespace::Handle(Z,
       Namespace::New(library, show_names, hide_names));
-  if (metadata_pos >= 0) {
-    ns.AddMetadata(metadata_pos, current_class());
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+    ns.AddMetadata(tl_owner, metadata_pos);
   }
 
   // Ensure that private dart:_ libraries are only imported into dart:
@@ -6015,7 +5959,7 @@
 }
 
 
-void Parser::ParseLibraryDefinition() {
+void Parser::ParseLibraryDefinition(const Object& tl_owner) {
   TRACE_PARSER("ParseLibraryDefinition");
 
   // Handle the script tag.
@@ -6037,15 +5981,15 @@
       ReportError("patch cannot override library name");
     }
     ParseLibraryName();
-    if (metadata_pos >= 0) {
-      library_.AddLibraryMetadata(current_class(), metadata_pos);
+    if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+      library_.AddLibraryMetadata(tl_owner, metadata_pos);
     }
     rewind_pos = TokenPos();
     metadata_pos = SkipMetadata();
   }
   while ((CurrentToken() == Token::kIMPORT) ||
       (CurrentToken() == Token::kEXPORT)) {
-    ParseLibraryImportExport(metadata_pos);
+    ParseLibraryImportExport(tl_owner, metadata_pos);
     rewind_pos = TokenPos();
     metadata_pos = SkipMetadata();
   }
@@ -6097,13 +6041,21 @@
   SetPosition(0);
   is_top_level_ = true;
   TopLevel top_level(Z);
-  Class& toplevel_class = Class::Handle(Z,
-      Class::New(Symbols::TopLevel(), script_, TokenPos()));
-  toplevel_class.set_library(library_);
+
+  Object& tl_owner = Object::Handle(Z);
+  Class& toplevel_class = Class::Handle(Z, library_.toplevel_class());
+  if (toplevel_class.IsNull()) {
+    toplevel_class = Class::New(Symbols::TopLevel(), script_, TokenPos());
+    toplevel_class.set_library(library_);
+    library_.set_toplevel_class(toplevel_class);
+    tl_owner = toplevel_class.raw();
+  } else {
+    tl_owner = PatchClass::New(toplevel_class, script_);
+  }
 
   if (is_library_source() || is_patch_source()) {
     set_current_class(toplevel_class);
-    ParseLibraryDefinition();
+    ParseLibraryDefinition(tl_owner);
   } else if (is_part_source()) {
     ParsePartHeader();
   }
@@ -6113,27 +6065,27 @@
     set_current_class(cls);  // No current class.
     intptr_t metadata_pos = SkipMetadata();
     if (CurrentToken() == Token::kCLASS) {
-      ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos);
+      ParseClassDeclaration(pending_classes, tl_owner, metadata_pos);
     } else if (CurrentToken() == Token::kENUM) {
-      ParseEnumDeclaration(pending_classes, toplevel_class, metadata_pos);
+      ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos);
     } else if ((CurrentToken() == Token::kTYPEDEF) &&
                (LookaheadToken(1) != Token::kLPAREN)) {
       set_current_class(toplevel_class);
-      ParseTypedef(pending_classes, toplevel_class, metadata_pos);
+      ParseTypedef(pending_classes, tl_owner, metadata_pos);
     } else if ((CurrentToken() == Token::kABSTRACT) &&
         (LookaheadToken(1) == Token::kCLASS)) {
-      ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos);
+      ParseClassDeclaration(pending_classes, tl_owner, metadata_pos);
     } else if (is_patch_source() && IsSymbol(Symbols::Patch()) &&
                (LookaheadToken(1) == Token::kCLASS)) {
-      ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos);
+      ParseClassDeclaration(pending_classes, tl_owner, metadata_pos);
     } else {
       set_current_class(toplevel_class);
       if (IsVariableDeclaration()) {
-        ParseTopLevelVariable(&top_level, metadata_pos);
+        ParseTopLevelVariable(&top_level, tl_owner, metadata_pos);
       } else if (IsFunctionDeclaration()) {
-        ParseTopLevelFunction(&top_level, metadata_pos);
+        ParseTopLevelFunction(&top_level, tl_owner, metadata_pos);
       } else if (IsTopLevelAccessor()) {
-        ParseTopLevelAccessor(&top_level, metadata_pos);
+        ParseTopLevelAccessor(&top_level, tl_owner, metadata_pos);
       } else if (CurrentToken() == Token::kEOS) {
         break;
       } else {
@@ -6142,19 +6094,16 @@
     }
   }
 
-  if ((library_.num_anonymous_classes() == 0) ||
-      (top_level.fields().length() > 0) ||
-      (top_level.functions().length() > 0)) {
+  if (top_level.fields().length() > 0) {
     toplevel_class.AddFields(top_level.fields());
-    const intptr_t len = top_level.functions().length();
-    const Array& array = Array::Handle(Z, Array::New(len, Heap::kOld));
-    for (intptr_t i = 0; i < len; i++) {
-      array.SetAt(i, *top_level.functions()[i]);
-    }
-    toplevel_class.SetFunctions(array);
-    library_.AddAnonymousClass(toplevel_class);
-    pending_classes.Add(toplevel_class, Heap::kOld);
   }
+  for (intptr_t i = 0; i < top_level.functions().length(); i++) {
+    toplevel_class.AddFunction(*top_level.functions()[i]);
+  }
+  if (toplevel_class.is_finalized()) {
+    toplevel_class.ResetFinalization();
+  }
+  pending_classes.Add(toplevel_class, Heap::kOld);
 }
 
 
@@ -6213,9 +6162,7 @@
 
 void Parser::OpenAsyncClosure() {
   TRACE_PARSER("OpenAsyncClosure");
-
   async_temp_scope_ = current_block_->scope;
-
   OpenAsyncTryBlock();
 }
 
@@ -6239,15 +6186,13 @@
   OpenBlock();  // Catch block.
 
   // Add the exception and stack trace parameters to the scope.
-  const AbstractType& dynamic_type =
-      AbstractType::ZoneHandle(Z, Type::DynamicType());
   CatchParamDesc exception_param;
   CatchParamDesc stack_trace_param;
   exception_param.token_pos = Scanner::kNoSourcePos;
-  exception_param.type = &dynamic_type;
+  exception_param.type = &Object::dynamic_type();
   exception_param.name = &Symbols::ExceptionParameter();
   stack_trace_param.token_pos = Scanner::kNoSourcePos;
-  stack_trace_param.type = &dynamic_type;
+  stack_trace_param.type = &Object::dynamic_type();
   stack_trace_param.name = &Symbols::StackTraceParameter();
 
   AddCatchParamsToScope(
@@ -6342,7 +6287,9 @@
 
     // Suspend after the close.
     AwaitMarkerNode* await_marker =
-        new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
+        new(Z) AwaitMarkerNode(async_temp_scope_,
+                               current_block_->scope,
+                               Scanner::kNoSourcePos);
     current_block_->statements->Add(await_marker);
     ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos);
     continuation_ret->set_return_type(ReturnNode::kContinuationTarget);
@@ -6369,7 +6316,8 @@
 
   const GrowableObjectArray& handler_types =
       GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld));
-  handler_types.Add(dynamic_type);  // Catch block handles all exceptions.
+  // Catch block handles all exceptions.
+  handler_types.Add(Object::dynamic_type());
 
   CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
       Scanner::kNoSourcePos,
@@ -6391,7 +6339,8 @@
                           context_var,
                           catch_clause,
                           finally_clause,
-                          try_index);
+                          try_index,
+                          finally_clause);
   current_block_->statements->Add(try_catch_node);
   return CloseBlock();
 }
@@ -6408,15 +6357,13 @@
 
   OpenBlock();  // Catch handler list.
   OpenBlock();  // Catch block.
-  const AbstractType& dynamic_type =
-      AbstractType::ZoneHandle(Z, Type::DynamicType());
   CatchParamDesc exception_param;
   CatchParamDesc stack_trace_param;
   exception_param.token_pos = Scanner::kNoSourcePos;
-  exception_param.type = &dynamic_type;
+  exception_param.type = &Object::dynamic_type();
   exception_param.name = &Symbols::ExceptionParameter();
   stack_trace_param.token_pos = Scanner::kNoSourcePos;
-  stack_trace_param.type = &dynamic_type;
+  stack_trace_param.type = &Object::dynamic_type();
   stack_trace_param.name = &Symbols::StackTraceParameter();
 
   AddCatchParamsToScope(
@@ -6509,7 +6456,8 @@
       context_var,
       catch_clause,
       NULL,  // No finally clause.
-      try_index);
+      try_index,
+      NULL);  // No rethrow-finally clause.
   current_block_->statements->Add(try_catch_node);
   return CloseBlock();
 }
@@ -6546,14 +6494,14 @@
   // Create the parameter list for the body closure of a sync generator:
   // 1) Implicit closure parameter;
   // 2) Iterator
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   // Add implicit closure parameter if not already present.
   if (params->parameters->length() == 0) {
-    params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
+    params->AddFinalParameter(
+        0, &Symbols::ClosureParameter(), &Object::dynamic_type());
   }
   ParamDesc iterator_param;
   iterator_param.name = &Symbols::IteratorParameter();
-  iterator_param.type = &dynamic_type;
+  iterator_param.type = &Object::dynamic_type();
   params->parameters->Add(iterator_param);
   params->num_fixed_parameters++;
 }
@@ -6577,11 +6525,8 @@
   // function has already been created by a previous
   // compilation.
   const Function& found_func = Function::Handle(
-      Z, current_class().LookupClosureFunction(func_pos));
-  if (!found_func.IsNull() &&
-      (found_func.token_pos() == func_pos) &&
-      (found_func.script() == innermost_function().script()) &&
-      (found_func.parent_function() == innermost_function().raw())) {
+      Z, I->LookupClosureFunction(innermost_function(), func_pos));
+  if (!found_func.IsNull()) {
     ASSERT(found_func.IsSyncGenClosure());
     body = found_func.raw();
     body_closure_name = body.name();
@@ -6589,13 +6534,13 @@
     // Create the closure containing the body of this generator function.
     String& generator_name = String::Handle(Z, innermost_function().name());
     body_closure_name =
-        String::NewFormatted("<%s_sync_body>", generator_name.ToCString());
+        Symbols::NewFormatted("<%s_sync_body>", generator_name.ToCString());
     body_closure_name = Symbols::New(body_closure_name);
     body = Function::NewClosureFunction(body_closure_name,
                                         innermost_function(),
                                         func_pos);
     body.set_is_generated_body(true);
-    body.set_result_type(AbstractType::Handle(Type::DynamicType()));
+    body.set_result_type(Object::dynamic_type());
     is_new_closure = true;
   }
 
@@ -6681,26 +6626,26 @@
   // * A continuation result.
   // * A continuation error.
   // * A continuation stack trace.
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   ASSERT(params->parameters->length() <= 1);
   // Add implicit closure parameter if not yet present.
   if (params->parameters->length() == 0) {
-    params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
+    params->AddFinalParameter(
+        0, &Symbols::ClosureParameter(), &Object::dynamic_type());
   }
   ParamDesc result_param;
   result_param.name = &Symbols::AsyncOperationParam();
   result_param.default_value = &Object::null_instance();
-  result_param.type = &dynamic_type;
+  result_param.type = &Object::dynamic_type();
   params->parameters->Add(result_param);
   ParamDesc error_param;
   error_param.name = &Symbols::AsyncOperationErrorParam();
   error_param.default_value = &Object::null_instance();
-  error_param.type = &dynamic_type;
+  error_param.type = &Object::dynamic_type();
   params->parameters->Add(error_param);
   ParamDesc stack_trace_param;
   stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam();
   stack_trace_param.default_value = &Object::null_instance();
-  stack_trace_param.type = &dynamic_type;
+  stack_trace_param.type = &Object::dynamic_type();
   params->parameters->Add(stack_trace_param);
   params->has_optional_positional_parameters = true;
   params->num_optional_parameters += 3;
@@ -6718,11 +6663,8 @@
   // this async function has already been created by a previous
   // compilation of this function.
   const Function& found_func = Function::Handle(
-      Z, current_class().LookupClosureFunction(async_func_pos));
-  if (!found_func.IsNull() &&
-      (found_func.token_pos() == async_func_pos) &&
-      (found_func.script() == innermost_function().script()) &&
-      (found_func.parent_function() == innermost_function().raw())) {
+      Z, I->LookupClosureFunction(innermost_function(), async_func_pos));
+  if (!found_func.IsNull()) {
     ASSERT(found_func.IsAsyncClosure());
     closure = found_func.raw();
   } else {
@@ -6736,7 +6678,7 @@
         innermost_function(),
         async_func_pos);
     closure.set_is_generated_body(true);
-    closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
+    closure.set_result_type(Object::dynamic_type());
     is_new_closure = true;
   }
   // Create the parameter list for the async body closure.
@@ -6774,12 +6716,13 @@
   // Add to current block's scope:
   //   var :await_jump_var;
   //   var :await_ctx_var;
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* await_jump_var = new (Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type);
+      Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type());
   current_block_->scope->AddVariable(await_jump_var);
   LocalVariable* await_ctx_var = new (Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AwaitContextVar(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(await_ctx_var);
 }
 
@@ -6790,18 +6733,23 @@
   //   var :async_then_callback;
   //   var :async_catch_error_callback;
   //   var :async_completer;
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* async_op_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
+      Scanner::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
   current_block_->scope->AddVariable(async_op_var);
   LocalVariable* async_then_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncThenCallback(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_then_callback_var);
   LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncCatchErrorCallback(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_catch_error_callback_var);
   LocalVariable* async_completer = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncCompleter(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_completer);
 }
 
@@ -6817,18 +6765,21 @@
   //   var :async_catch_error_callback;
   // These variables are used to store the async generator closure containing
   // the body of the async* function. They are used by the await operator.
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* controller_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type);
+      Scanner::kNoSourcePos, Symbols::Controller(), Object::dynamic_type());
   current_block_->scope->AddVariable(controller_var);
   LocalVariable* async_op_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
+      Scanner::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
   current_block_->scope->AddVariable(async_op_var);
   LocalVariable* async_then_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncThenCallback(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_then_callback_var);
   LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
+      Scanner::kNoSourcePos,
+      Symbols::AsyncCatchErrorCallback(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_catch_error_callback_var);
 }
 
@@ -6845,11 +6796,8 @@
   // this async generator has already been created by a previous
   // compilation of this function.
   const Function& found_func = Function::Handle(
-      Z, current_class().LookupClosureFunction(async_func_pos));
-  if (!found_func.IsNull() &&
-      (found_func.token_pos() == async_func_pos) &&
-      (found_func.script() == innermost_function().script()) &&
-      (found_func.parent_function() == innermost_function().raw())) {
+      Z, I->LookupClosureFunction(innermost_function(), async_func_pos));
+  if (!found_func.IsNull()) {
     ASSERT(found_func.IsAsyncGenClosure());
     closure = found_func.raw();
   } else {
@@ -6857,14 +6805,14 @@
     const String& async_generator_name =
         String::Handle(Z, innermost_function().name());
     String& closure_name = String::Handle(Z,
-        String::NewFormatted("<%s_async_gen_body>",
-                             async_generator_name.ToCString()));
+        Symbols::NewFormatted("<%s_async_gen_body>",
+                              async_generator_name.ToCString()));
     closure = Function::NewClosureFunction(
         String::Handle(Z, Symbols::New(closure_name)),
         innermost_function(),
         async_func_pos);
     closure.set_is_generated_body(true);
-    closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
+    closure.set_result_type(Object::dynamic_type());
     is_new_closure = true;
   }
 
@@ -7335,39 +7283,20 @@
 void Parser::ParseNativeFunctionBlock(const ParamList* params,
                                       const Function& func) {
   ASSERT(func.is_native());
-  TRACE_PARSER("ParseNativeFunctionBlock");
-  const Class& cls = Class::Handle(Z, func.Owner());
-  const Library& library = Library::Handle(Z, cls.library());
   ASSERT(func.NumParameters() == params->parameters->length());
+  TRACE_PARSER("ParseNativeFunctionBlock");
 
   // Parse the function name out.
-  const intptr_t native_pos = TokenPos();
   const String& native_name = ParseNativeDeclaration();
 
-  // Now resolve the native function to the corresponding native entrypoint.
-  const int num_params = NativeArguments::ParameterCountForResolution(func);
-  bool auto_setup_scope = true;
-  NativeFunction native_function = NativeEntry::ResolveNative(
-      library, native_name, num_params, &auto_setup_scope);
-  if (native_function == NULL) {
-    ReportError(native_pos,
-                "native function '%s' (%" Pd " arguments) cannot be found",
-                native_name.ToCString(), func.NumParameters());
-  }
-  func.SetIsNativeAutoSetupScope(auto_setup_scope);
-
   // Now add the NativeBodyNode and return statement.
-  Dart_NativeEntryResolver resolver = library.native_entry_resolver();
-  bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver);
   current_block_->statements->Add(new(Z) ReturnNode(
       TokenPos(),
       new(Z) NativeBodyNode(
           TokenPos(),
           Function::ZoneHandle(Z, func.raw()),
           native_name,
-          native_function,
           current_block_->scope,
-          is_bootstrap_native,
           FLAG_link_natives_lazily)));
 }
 
@@ -7386,13 +7315,6 @@
 }
 
 
-LocalVariable* Parser::LookupPhaseParameter() {
-  const bool kTestOnly = false;
-  return current_block_->scope->LookupVariable(Symbols::PhaseParameter(),
-                                               kTestOnly);
-}
-
-
 void Parser::CaptureInstantiator() {
   ASSERT(current_block_->scope->function_level() > 0);
   const String* variable_name = current_function().IsInFactoryScope() ?
@@ -7455,7 +7377,7 @@
     // Initialize variable with null.
     variable = new(Z) LocalVariable(
         assign_pos, ident, type);
-    AstNode* null_expr = new(Z) LiteralNode(ident_pos, Instance::ZoneHandle(Z));
+    AstNode* null_expr = new(Z) LiteralNode(ident_pos, Object::null_instance());
     initialization = new(Z) StoreLocalNode(
         ident_pos, variable, null_expr);
   }
@@ -7591,7 +7513,7 @@
   result_type = Type::DynamicType();
 
   const intptr_t function_pos = TokenPos();
-  intptr_t metadata_pos = -1;
+  intptr_t metadata_pos = Scanner::kNoSourcePos;
   if (is_literal) {
     ASSERT(CurrentToken() == Token::kLPAREN);
     function_name = &Symbols::AnonymousClosure();
@@ -7635,9 +7557,8 @@
   // TODO(hausner): There could be two different closures at the given
   // function_pos, one enclosed in a closurized function and one enclosed in the
   // non-closurized version of this same function.
-  function = current_class().LookupClosureFunction(function_pos);
-  if (function.IsNull() || (function.token_pos() != function_pos) ||
-      (function.parent_function() != innermost_function().raw())) {
+  function = I->LookupClosureFunction(innermost_function(), function_pos);
+  if (function.IsNull()) {
     // The function will be registered in the lookup table by the
     // EffectGraphVisitor::VisitClosureNode when the newly allocated closure
     // function has been properly setup.
@@ -7646,7 +7567,7 @@
                                             innermost_function(),
                                             function_pos);
     function.set_result_type(result_type);
-    if (metadata_pos >= 0) {
+    if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
       library_.AddFunctionMetadata(function, metadata_pos);
     }
   }
@@ -8640,7 +8561,7 @@
 
   // Parse stream expression.
   ExpectToken(Token::kIN);
-  const intptr_t stream_pos = TokenPos();
+  const intptr_t stream_expr_pos = TokenPos();
   AstNode* stream_expr =
       ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
   ExpectToken(Token::kRPAREN);
@@ -8659,19 +8580,19 @@
       Function::ZoneHandle(Z, stream_iterator_cls.LookupFunction(
           Symbols::StreamIteratorConstructor()));
   ASSERT(!iterator_ctor.IsNull());
-  ArgumentListNode* ctor_args = new (Z) ArgumentListNode(Scanner::kNoSourcePos);
+  ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos);
   ctor_args->Add(stream_expr);
   ConstructorCallNode* ctor_call =
-      new (Z) ConstructorCallNode(Scanner::kNoSourcePos,
+      new (Z) ConstructorCallNode(stream_expr_pos,
                               TypeArguments::ZoneHandle(Z),
                               iterator_ctor,
                               ctor_args);
-  const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType());
+  const AbstractType& iterator_type = Object::dynamic_type();
   LocalVariable* iterator_var = new(Z) LocalVariable(
-      stream_pos, Symbols::ForInIter(), iterator_type);
+      stream_expr_pos, Symbols::ForInIter(), iterator_type);
   current_block_->scope->AddVariable(iterator_var);
   AstNode* iterator_init =
-      new(Z) StoreLocalNode(stream_pos, iterator_var, ctor_call);
+      new(Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call);
   current_block_->statements->Add(iterator_init);
 
   // We need to ensure that the stream is cancelled after the loop.
@@ -8709,15 +8630,15 @@
                          &async_saved_try_ctx,
                          &outer_saved_try_ctx,
                          &outer_async_saved_try_ctx);
-  ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_pos);
+  ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_expr_pos);
   AstNode* iterator_moveNext = new(Z) InstanceCallNode(
-      stream_pos,
-      new(Z) LoadLocalNode(stream_pos, iterator_var),
+      stream_expr_pos,
+      new(Z) LoadLocalNode(stream_expr_pos, iterator_var),
                            Symbols::MoveNext(),
                            no_args);
   OpenBlock();
   AstNode* await_moveNext =
-      new(Z) AwaitNode(stream_pos,
+      new(Z) AwaitNode(stream_expr_pos,
                        iterator_moveNext,
                        saved_try_ctx,
                        async_saved_try_ctx,
@@ -8863,9 +8784,9 @@
   // Create the try-statement and add to the current sequence, which is
   // the block around the loop statement.
 
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
-  handler_types.SetAt(0, dynamic_type);  // Catch block handles all exceptions.
+  // Catch block handles all exceptions.
+  handler_types.SetAt(0, Object::dynamic_type());
 
   CatchClauseNode* catch_clause = new(Z) CatchClauseNode(await_for_pos,
       catch_block,
@@ -8884,7 +8805,8 @@
                          context_var,
                          catch_clause,
                          finally_clause,
-                         try_index);
+                         try_index,
+                         finally_clause);
 
   ASSERT(current_block_ == loop_block);
   loop_block->statements->Add(try_catch_node);
@@ -8901,7 +8823,7 @@
     ReportError("Loop variable cannot be 'const'");
   }
   const String* loop_var_name = NULL;
-  intptr_t loop_var_pos = 0;
+  intptr_t loop_var_pos = Scanner::kNoSourcePos;
   bool new_loop_var = false;
   AbstractType& loop_var_type =  AbstractType::ZoneHandle(Z);
   if (LookaheadToken(1) == Token::kIN) {
@@ -8931,7 +8853,7 @@
   // would refer to the compiler generated iterator and could confuse the user.
   // It is better to leave the iterator untyped and postpone the type error
   // until the loop variable is assigned to.
-  const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType());
+  const AbstractType& iterator_type = Object::dynamic_type();
   LocalVariable* iterator_var = new(Z) LocalVariable(
       collection_pos, Symbols::ForInIter(), iterator_type);
   current_block_->scope->AddVariable(iterator_var);
@@ -9360,7 +9282,7 @@
       exception_param.type = &AbstractType::ZoneHandle(Z,
           ParseType(ClassFinalizer::kCanonicalize));
     } else {
-      exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType());
+      exception_param.type = &Object::dynamic_type();
     }
     if (CurrentToken() == Token::kCATCH) {
       ConsumeToken();  // Consume the 'catch'.
@@ -9369,8 +9291,7 @@
       exception_param.name = ExpectIdentifier("identifier expected");
       if (CurrentToken() == Token::kCOMMA) {
         ConsumeToken();
-        stack_trace_param.type =
-            &AbstractType::ZoneHandle(Z, Type::DynamicType());
+        stack_trace_param.type = &Object::dynamic_type();
         stack_trace_param.token_pos = TokenPos();
         stack_trace_param.name = ExpectIdentifier("identifier expected");
       }
@@ -9551,7 +9472,7 @@
   LocalVariable* async_saved_try_ctx = new (Z) LocalVariable(
       Scanner::kNoSourcePos,
       async_saved_try_ctx_name,
-      Type::ZoneHandle(Z, Type::DynamicType()));
+      Object::dynamic_type());
   ASSERT(async_temp_scope_ != NULL);
   async_temp_scope_->AddVariable(async_saved_try_ctx);
   ASSERT(saved_try_context != NULL);
@@ -9586,14 +9507,13 @@
                                      LocalVariable** stack_trace_var,
                                      LocalVariable** saved_exception_var,
                                      LocalVariable** saved_stack_trace_var) {
-  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
   // Consecutive try statements share the same set of variables.
   *context_var = try_scope->LocalLookupVariable(Symbols::SavedTryContextVar());
   if (*context_var == NULL) {
     *context_var = new(Z) LocalVariable(
         TokenPos(),
         Symbols::SavedTryContextVar(),
-        dynamic_type);
+        Object::dynamic_type());
     try_scope->AddVariable(*context_var);
   }
   *exception_var = try_scope->LocalLookupVariable(Symbols::ExceptionVar());
@@ -9601,7 +9521,7 @@
     *exception_var = new(Z) LocalVariable(
         TokenPos(),
         Symbols::ExceptionVar(),
-        dynamic_type);
+        Object::dynamic_type());
     try_scope->AddVariable(*exception_var);
   }
   *stack_trace_var = try_scope->LocalLookupVariable(Symbols::StackTraceVar());
@@ -9609,7 +9529,7 @@
     *stack_trace_var = new(Z) LocalVariable(
         TokenPos(),
         Symbols::StackTraceVar(),
-        dynamic_type);
+        Object::dynamic_type());
     try_scope->AddVariable(*stack_trace_var);
   }
   if (is_async) {
@@ -9619,7 +9539,7 @@
       *saved_exception_var = new(Z) LocalVariable(
           TokenPos(),
           Symbols::SavedExceptionVar(),
-          dynamic_type);
+          Object::dynamic_type());
       try_scope->AddVariable(*saved_exception_var);
     }
     *saved_stack_trace_var = try_scope->LocalLookupVariable(
@@ -9628,7 +9548,7 @@
       *saved_stack_trace_var = new(Z) LocalVariable(
           TokenPos(),
           Symbols::SavedStackTraceVar(),
-          dynamic_type);
+          Object::dynamic_type());
       try_scope->AddVariable(*saved_stack_trace_var);
     }
   }
@@ -9712,6 +9632,7 @@
   // of an existing outer try. Generate a finally clause to this purpose if it
   // is not declared.
   SequenceNode* finally_clause = NULL;
+  SequenceNode* rethrow_clause = NULL;
   const bool parse = CurrentToken() == Token::kFINALLY;
   if (parse || (is_async && (try_stack_ != NULL))) {
     if (parse) {
@@ -9745,6 +9666,21 @@
         stack_trace_var,
         is_async ? saved_exception_var : exception_var,
         is_async ? saved_stack_trace_var : stack_trace_var);
+    if (finally_clause != NULL) {
+      // Re-parse to create a duplicate of finally clause to avoid unintended
+      // sharing of try-indices if the finally-block contains a try-catch.
+      // The flow graph builder emits two copies of the finally-block if the
+      // try-block has a normal exit: one for the exception- and one for the
+      // non-exception case (see EffectGraphVisitor::VisitTryCatchNode)
+      tokens_iterator_.SetCurrentPosition(finally_pos);
+      rethrow_clause = EnsureFinallyClause(
+          parse,
+          is_async,
+          exception_var,
+          stack_trace_var,
+          is_async ? saved_exception_var : exception_var,
+          is_async ? saved_stack_trace_var : stack_trace_var);
+    }
   }
 
   CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
@@ -9764,7 +9700,8 @@
   // on the try/catch, close the block that's embedding the try statement
   // and attach the label to it.
   AstNode* try_catch_node = new(Z) TryCatchNode(
-      try_pos, try_block, context_var, catch_clause, finally_clause, try_index);
+      try_pos, try_block, context_var, catch_clause, finally_clause, try_index,
+      rethrow_clause);
 
   if (try_label != NULL) {
     current_block_->statements->Add(try_catch_node);
@@ -9888,7 +9825,9 @@
       yield->AddNode(set_is_yield_each);
     }
     AwaitMarkerNode* await_marker =
-        new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
+        new(Z) AwaitMarkerNode(async_temp_scope_,
+                               current_block_->scope,
+                               Scanner::kNoSourcePos);
     yield->AddNode(await_marker);
     // Return true to indicate that a value has been generated.
     ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
@@ -9956,7 +9895,9 @@
     yield->AddNode(if_is_cancelled);
 
     AwaitMarkerNode* await_marker =
-        new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
+        new(Z) AwaitMarkerNode(async_temp_scope_,
+                               current_block_->scope,
+                               Scanner::kNoSourcePos);
     yield->AddNode(await_marker);
     ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
     continuation_return->set_return_type(ReturnNode::kContinuationTarget);
@@ -9997,14 +9938,14 @@
 AstNode* Parser::ParseStatement() {
   TRACE_PARSER("ParseStatement");
   AstNode* statement = NULL;
-  intptr_t label_pos = 0;
+  intptr_t label_pos = Scanner::kNoSourcePos;
   String* label_name = NULL;
   if (IsIdentifier()) {
     if (LookaheadToken(1) == Token::kCOLON) {
       // Statement starts with a label.
       label_name = CurrentLiteral();
       label_pos = TokenPos();
-      ASSERT(label_pos > 0);
+      ASSERT(label_pos >= 0);
       ConsumeToken();  // Consume identifier.
       ConsumeToken();  // Consume colon.
     }
@@ -10247,12 +10188,14 @@
 
 
 bool Parser::IsAwaitKeyword() {
-  return await_is_keyword_ && IsSymbol(Symbols::Await());
+  return (FLAG_await_is_keyword || await_is_keyword_) &&
+      IsSymbol(Symbols::Await());
 }
 
 
 bool Parser::IsYieldKeyword() {
-  return await_is_keyword_ && IsSymbol(Symbols::YieldKw());
+  return (FLAG_await_is_keyword || await_is_keyword_) &&
+      IsSymbol(Symbols::YieldKw());
 }
 
 
@@ -10299,7 +10242,7 @@
   arguments->Add(new(Z) LiteralNode(
       type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos))));
   // Src value argument.
-  arguments->Add(new(Z) LiteralNode(type_pos, Instance::ZoneHandle(Z)));
+  arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance()));
   // Dst type name argument.
   arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Malformed()));
   // Dst name argument.
@@ -10358,7 +10301,7 @@
       Smi::New(InvocationMirror::EncodeType(im_call, im_type)))));
   // List arguments.
   if (function_arguments == NULL) {
-    arguments->Add(new(Z) LiteralNode(call_pos, Array::ZoneHandle(Z)));
+    arguments->Add(new(Z) LiteralNode(call_pos, Object::null_array()));
   } else {
     ArrayNode* array = new(Z) ArrayNode(
         call_pos,
@@ -10368,7 +10311,7 @@
   }
   // List argumentNames.
   if (function_arguments == NULL) {
-    arguments->Add(new(Z) LiteralNode(call_pos, Array::ZoneHandle(Z)));
+    arguments->Add(new(Z) LiteralNode(call_pos, Object::null_array()));
   } else {
     arguments->Add(new(Z) LiteralNode(call_pos, function_arguments->names()));
   }
@@ -10516,7 +10459,7 @@
   LocalVariable* temp = new(Z) LocalVariable(
       token_pos,
       String::ZoneHandle(Z, Symbols::New(name)),
-      Type::ZoneHandle(Z, Type::DynamicType()));
+      Object::dynamic_type());
   temp->set_is_final();
   current_block_->scope->AddVariable(temp);
   return temp;
@@ -10565,6 +10508,25 @@
       }
     }
   }
+  if (binary_op == Token::kIFNULL) {
+    // Handle a ?? b.
+    LetNode* result = new(Z) LetNode(op_pos);
+    LocalVariable* left_temp = result->AddInitializer(lhs);
+    const intptr_t no_pos = Scanner::kNoSourcePos;
+    LiteralNode* null_operand =
+        new(Z) LiteralNode(no_pos, Object::null_instance());
+    LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp);
+    ComparisonNode* null_compare =
+        new(Z) ComparisonNode(no_pos,
+                              Token::kNE_STRICT,
+                              load_left_temp,
+                              null_operand);
+    result->AddNode(new(Z) ConditionalExprNode(op_pos,
+                                               null_compare,
+                                               load_left_temp,
+                                               rhs));
+    return result;
+  }
   return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs);
 }
 
@@ -10736,10 +10698,10 @@
                              ifnull->right(),
                              left_ident,
                              left_pos);
-    result = new(Z) BinaryOpNode(rhs->token_pos(),
-                                 Token::kIFNULL,
-                                 ifnull->left(),
-                                 modified_assign);
+    result = OptimizeBinaryOpNode(ifnull->token_pos(),
+                                  ifnull->kind(),
+                                  ifnull->left(),
+                                  modified_assign);
   }
   return result;
 }
@@ -11133,6 +11095,26 @@
     // source.
     if (!FLAG_warn_on_javascript_compatibility || is_patch_source()) {
       ASSERT(num_arguments == 2);
+
+      // If both arguments are constant expressions of type string,
+      // evaluate and canonicalize them.
+      // This guarantees that identical("ab", "a"+"b") is true.
+      // An alternative way to guarantee this would be to introduce
+      // an AST node that canonicalizes a value.
+      AstNode* arg0 = arguments->NodeAt(0);
+      const Instance* val0 = arg0->EvalConstExpr();
+      if ((val0 != NULL) && (val0->IsString())) {
+        AstNode* arg1 = arguments->NodeAt(1);
+        const Instance* val1 = arg1->EvalConstExpr();
+        if ((val1 != NULL) && (val1->IsString())) {
+          arguments->SetNodeAt(0,
+              new(Z) LiteralNode(arg0->token_pos(),
+                                 EvaluateConstExpr(arg0->token_pos(), arg0)));
+          arguments->SetNodeAt(1,
+              new(Z) LiteralNode(arg1->token_pos(),
+                                 EvaluateConstExpr(arg1->token_pos(), arg1)));
+        }
+      }
       return new(Z) ComparisonNode(ident_pos,
                                    Token::kEQ_STRICT,
                                    arguments->NodeAt(0),
@@ -11251,7 +11233,8 @@
     // NoSuchMethodError to be thrown.
     // In an instance method, we convert this into a getter call
     // for a field (which may be defined in a subclass.)
-    String& name = String::CheckedZoneHandle(primary->primary().raw());
+    const String& name =
+        String::Cast(Object::ZoneHandle(primary->primary().raw()));
     if (current_function().is_static() ||
         current_function().IsInFactoryScope()) {
       StaticGetterNode* getter = new(Z) StaticGetterNode(
@@ -11273,7 +11256,7 @@
 AstNode* Parser::LoadClosure(PrimaryNode* primary) {
   ASSERT(primary->primary().IsFunction());
   const Function& func =
-      Function::CheckedZoneHandle(primary->primary().raw());
+      Function::Cast(Object::ZoneHandle(primary->primary().raw()));
   const String& funcname = String::ZoneHandle(Z, func.name());
   if (func.is_static()) {
     // Static function access.
@@ -11462,8 +11445,8 @@
           if (primary_node->IsSuper()) {
             ReportError(primary_pos, "illegal use of super");
           }
-          String& name =
-              String::CheckedZoneHandle(primary_node->primary().raw());
+          const String& name =
+              String::Cast(Object::ZoneHandle(primary_node->primary().raw()));
           if (current_function().is_static()) {
             // The static call will be converted to throwing a NSM error.
             selector = ParseStaticCall(current_class(), name, primary_pos);
@@ -11720,6 +11703,7 @@
       ReportError(expr_pos, "expression is not assignable");
     }
     Token::Kind incr_op = CurrentToken();
+    const intptr_t op_pos = TokenPos();
     ConsumeToken();
     // Not prefix.
     LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
@@ -11727,17 +11711,17 @@
     Token::Kind binary_op =
         (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
     BinaryOpNode* add = new(Z) BinaryOpNode(
-        expr_pos,
+        op_pos,
         binary_op,
-        new(Z) LoadLocalNode(expr_pos, temp),
-        new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1))));
+        new(Z) LoadLocalNode(op_pos, temp),
+        new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1))));
     AstNode* store =
         CreateAssignmentNode(expr, add, expr_ident, expr_pos, true);
     ASSERT(store != NULL);
     // The result is a pair of the (side effects of the) store followed by
     // the (value of the) initial value temp variable load.
     let_expr->AddNode(store);
-    let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp));
+    let_expr->AddNode(new(Z) LoadLocalNode(op_pos, temp));
     return let_expr;
   }
   return expr;
@@ -11906,30 +11890,65 @@
   return current_class().NumTypeParameters() > 0;
 }
 
+// We cache computed compile-time constants in a map so we can look them
+// up when the same code gets compiled again. The map key is a pair
+// (script url, token position) which is encoded in an array with 2
+// elements:
+// - key[0] contains the canonicalized url of the script.
+// - key[1] contains the token position of the constant in the script.
+
+// ConstantPosKey allows us to look up a constant in the map without
+// allocating a key pair (array).
+struct ConstantPosKey : ValueObject {
+  ConstantPosKey(const String& url, intptr_t pos)
+      : script_url(url), token_pos(pos) { }
+  const String& script_url;
+  intptr_t token_pos;
+};
+
 
 class ConstMapKeyEqualsTraits {
  public:
   static bool IsMatch(const Object& a, const Object& b) {
-    return String::Cast(a).Equals(String::Cast(b));
+    const Array& key1 = Array::Cast(a);
+    const Array& key2 = Array::Cast(b);
+    // Compare raw strings of script url symbol and raw smi of token positon.
+    return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1));
   }
-  static bool IsMatch(const char* key, const Object& b) {
-    return String::Cast(b).Equals(key);
+  static bool IsMatch(const ConstantPosKey& key1, const Object& b) {
+    const Array& key2 = Array::Cast(b);
+    // Compare raw strings of script url symbol and token positon.
+    return (key1.script_url.raw() == key2.At(0))
+        && (key1.token_pos == Smi::Value(Smi::RawCast(key2.At(1))));
   }
   static uword Hash(const Object& obj) {
-    return String::Cast(obj).Hash();
+    const Array& key = Array::Cast(obj);
+    intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0)));
+    intptr_t pos = Smi::Value(Smi::RawCast(key.At(1)));
+    return HashValue(url_hash, pos);
   }
-  static uword Hash(const char* key) {
-    return String::Hash(key, strlen(key));
+  static uword Hash(const ConstantPosKey& key) {
+    return HashValue(String::HashRawSymbol(key.script_url.raw()),
+                     key.token_pos);
+  }
+  // Used by CachConstantValue if a new constant is added to the map.
+  static RawObject* NewKey(const ConstantPosKey& key) {
+    const Array& key_obj = Array::Handle(Array::New(2));
+    key_obj.SetAt(0, key.script_url);
+    key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos)));
+    return key_obj.raw();;
+  }
+
+ private:
+  static uword HashValue(intptr_t url_hash, intptr_t pos) {
+    return url_hash * pos % (Smi::kMaxValue - 13);
   }
 };
 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap;
 
 
 void Parser::CacheConstantValue(intptr_t token_pos, const Instance& value) {
-  String& key = String::Handle(Z, script_.url());
-  String& suffix =
-      String::Handle(Z, String::NewFormatted("_%" Pd "", token_pos));
-  key = Symbols::FromConcat(key, suffix);
+  ConstantPosKey key(String::Handle(Z, script_.url()), token_pos);
   if (isolate()->object_store()->compile_time_constants() == Array::null()) {
     const intptr_t kInitialConstMapSize = 16;
     isolate()->object_store()->set_compile_time_constants(
@@ -11937,7 +11956,7 @@
                                                        Heap::kNew)));
   }
   ConstantsMap constants(isolate()->object_store()->compile_time_constants());
-  constants.UpdateOrInsert(key, value);
+  constants.InsertNewOrGetValue(key, value);
   if (FLAG_compiler_stats) {
     isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied();
   }
@@ -11949,22 +11968,14 @@
   if (isolate()->object_store()->compile_time_constants() == Array::null()) {
     return false;
   }
-  // We don't want to allocate anything in the heap here since this code
-  // is called from the optimizing compiler in the background thread. Allocate
-  // the key value in the zone instead.
-  // const char* key = Z->PrintToString("%s_%" Pd "",
-  //     String::Handle(Z, script_.url()).ToCString(),
-  //    token_pos);
-
-  const String& key = String::Handle(Z,
-      Symbols::NewFormatted("%s_%" Pd "",
-          String::Handle(Z, script_.url()).ToCString(),
-          token_pos));
+  ConstantPosKey key(String::Handle(Z, script_.url()), token_pos);
   ConstantsMap constants(isolate()->object_store()->compile_time_constants());
   bool is_present = false;
   *value ^= constants.GetOrNull(key, &is_present);
-  ASSERT(constants.Release().raw() ==
-      isolate()->object_store()->compile_time_constants());
+  // Mutator compiler thread may add constants while background compiler
+  // is running , and thus change the value of 'compile_time_constants';
+  // do not assert that 'compile_time_constants' has not changed.
+  constants.Release();
   if (FLAG_compiler_stats && is_present) {
     isolate_->compiler_stats()->num_const_cache_hits++;
   }
@@ -12072,8 +12083,8 @@
     const Function& constructor,
     ArgumentListNode* arguments) {
   // Factories have one extra argument: the type arguments.
-  // Constructors have 2 extra arguments: rcvr and construction phase.
-  const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2;
+  // Constructors have 1 extra arguments: receiver.
+  const int kNumExtraArgs = 1;
   const int num_arguments = arguments->length() + kNumExtraArgs;
   const Array& arg_values =
       Array::Handle(Z, Array::New(num_arguments, Heap::kOld));
@@ -12088,7 +12099,6 @@
           TypeArguments::Handle(Z, type_arguments.Canonicalize()));
     }
     arg_values.SetAt(0, instance);
-    arg_values.SetAt(1, Smi::Handle(Z, Smi::New(Function::kCtorPhaseAll)));
   } else {
     // Prepend type_arguments to list of arguments to factory.
     ASSERT(type_arguments.IsZoneHandle());
@@ -12102,8 +12112,8 @@
   }
   const Array& args_descriptor = Array::Handle(Z,
       ArgumentsDescriptor::New(num_arguments, arguments->names()));
-  Object& result = Object::Handle(Z);
-  result = DartEntry::InvokeFunction(constructor, arg_values, args_descriptor);
+  const Object& result = Object::Handle(Z,
+      DartEntry::InvokeFunction(constructor, arg_values, args_descriptor));
   if (result.IsError()) {
       // An exception may not occur in every parse attempt, i.e., the
       // generated AST is not deterministic. Therefore mark the function as
@@ -12669,7 +12679,7 @@
         Array::New(element_list.length(), Heap::kOld));
     const_list.SetTypeArguments(
         TypeArguments::Handle(Z, list_type_arguments.Canonicalize()));
-    Error& malformed_error = Error::Handle(Z);
+    Error& bound_error = Error::Handle(Z);
     for (int i = 0; i < element_list.length(); i++) {
       AstNode* elem = element_list[i];
       // Arguments have been evaluated to a literal value already.
@@ -12681,10 +12691,10 @@
            !elem->AsLiteralNode()->literal().IsInstanceOf(
                element_type,
                TypeArguments::Handle(Z),
-               &malformed_error))) {
-        // If the failure is due to a malformed type error, display it instead.
-        if (!malformed_error.IsNull()) {
-          ReportError(malformed_error);
+               &bound_error))) {
+        // If the failure is due to a bound error, display it instead.
+        if (!bound_error.IsNull()) {
+          ReportError(bound_error);
         } else {
           ReportError(elem->AsLiteralNode()->token_pos(),
                       "list literal element at index %d must be "
@@ -12895,7 +12905,7 @@
     Array& key_value_array =
         Array::ZoneHandle(Z, Array::New(kv_pairs_list.length(), Heap::kOld));
     AbstractType& arg_type = Type::Handle(Z);
-    Error& malformed_error = Error::Handle(Z);
+    Error& bound_error = Error::Handle(Z);
     for (int i = 0; i < kv_pairs_list.length(); i++) {
       AstNode* arg = kv_pairs_list[i];
       // Arguments have been evaluated to a literal value already.
@@ -12914,10 +12924,10 @@
              !arg->AsLiteralNode()->literal().IsInstanceOf(
                  arg_type,
                  Object::null_type_arguments(),
-                 &malformed_error))) {
-          // If the failure is due to a malformed type error, display it.
-          if (!malformed_error.IsNull()) {
-            ReportError(malformed_error);
+                 &bound_error))) {
+          // If the failure is due to a bound error, display it.
+          if (!bound_error.IsNull()) {
+            ReportError(bound_error);
           } else {
             ReportError(arg->AsLiteralNode()->token_pos(),
                         "map literal %s at index %d must be "
@@ -13093,7 +13103,7 @@
                                                      intptr_t token_pos) {
   ASSERT(ctr.kind() == RawFunction::kConstructor);
   Function& closure = Function::Handle(Z);
-  closure = current_class().LookupClosureFunction(token_pos);
+  closure = I->LookupClosureFunction(innermost_function(), token_pos);
   if (!closure.IsNull()) {
     ASSERT(closure.IsConstructorClosureFunction());
     return closure.raw();
@@ -13106,7 +13116,7 @@
   ParamList params;
   params.AddFinalParameter(token_pos,
                            &Symbols::ClosureParameter(),
-                           &Type::ZoneHandle(Z, Type::DynamicType()));
+                           &Object::dynamic_type());
 
   ParseFormalParameters(ctr, &params);
   // Per language spec, the type of the closure parameters is dynamic.
@@ -13119,7 +13129,7 @@
   closure.set_is_generated_body(true);
   closure.set_is_debuggable(false);
   closure.set_is_visible(false);
-  closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
+  closure.set_result_type(Object::dynamic_type());
   AddFormalParamsToFunction(&params, closure);
 
   // Create and set the signature class of the closure.
@@ -13320,8 +13330,7 @@
 
   // A constructor has an implicit 'this' parameter (instance to construct)
   // and a factory has an implicit 'this' parameter (type_arguments).
-  // A constructor has a second implicit 'phase' parameter.
-  intptr_t arguments_length = arguments->length() + 2;
+  intptr_t arguments_length = arguments->length() + 1;
 
   // An additional type check of the result of a redirecting factory may be
   // required.
@@ -13419,10 +13428,6 @@
       constructor_name = constructor.name();
       ASSERT(!constructor.IsNull());
     }
-    if (constructor.IsFactory()) {
-      // A factory does not have the implicit 'phase' parameter.
-      arguments_length -= 1;
-    }
   }
   ASSERT(!constructor.IsNull());
 
@@ -13536,13 +13541,13 @@
     new_object = new(Z) LiteralNode(new_pos, const_instance);
     if (!type_bound.IsNull()) {
       ASSERT(!type_bound.IsMalformed());
-      Error& malformed_error = Error::Handle(Z);
+      Error& bound_error = Error::Handle(Z);
       ASSERT(!is_top_level_);  // We cannot check unresolved types.
       if (!const_instance.IsInstanceOf(type_bound,
                                        TypeArguments::Handle(Z),
-                                       &malformed_error)) {
+                                       &bound_error)) {
         type_bound = ClassFinalizer::NewFinalizedMalformedType(
-            malformed_error,
+            bound_error,
             script_,
             new_pos,
             "const factory result is not an instance of '%s'",
@@ -13840,7 +13845,7 @@
     primary = new(Z) LiteralNode(TokenPos(), Bool::False());
     ConsumeToken();
   } else if (token == Token::kNULL) {
-    primary = new(Z) LiteralNode(TokenPos(), Instance::ZoneHandle(Z));
+    primary = new(Z) LiteralNode(TokenPos(), Object::null_instance());
     ConsumeToken();
   } else if (token == Token::kLPAREN) {
     ConsumeToken();
@@ -13849,7 +13854,7 @@
     SetAllowFunctionLiterals(saved_mode);
     ExpectToken(Token::kRPAREN);
   } else if (token == Token::kDOUBLE) {
-    Double& double_value = Double::ZoneHandle(Z, CurrentDoubleLiteral());
+    const Double& double_value = Double::ZoneHandle(Z, CurrentDoubleLiteral());
     if (double_value.IsNull()) {
       ReportError("invalid double literal");
     }
@@ -14311,3 +14316,90 @@
 }
 
 }  // namespace dart
+
+
+#else  // DART_PRECOMPILED
+
+
+namespace dart {
+
+DEFINE_FLAG(bool, enable_mirrors, true,
+    "Disable to make importing dart:mirrors an error.");
+DEFINE_FLAG(bool, load_deferred_eagerly, false,
+    "Load deferred libraries eagerly.");
+DEFINE_FLAG(bool, link_natives_lazily, false, "Link native calls lazily");
+
+LocalVariable* ParsedFunction::EnsureExpressionTemp() {
+  UNREACHABLE();
+  return NULL;
+}
+
+
+void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) {
+  UNREACHABLE();
+}
+
+
+void ParsedFunction::SetRegExpCompileData(
+    RegExpCompileData* regexp_compile_data) {
+  UNREACHABLE();
+}
+
+
+void ParsedFunction::AllocateVariables() {
+  UNREACHABLE();
+}
+
+
+void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) {
+  UNREACHABLE();
+}
+
+
+void Parser::ParseCompilationUnit(const Library& library,
+                                  const Script& script) {
+  UNREACHABLE();
+}
+
+
+void Parser::ParseClass(const Class& cls) {
+  UNREACHABLE();
+}
+
+
+RawObject* Parser::ParseFunctionParameters(const Function& func) {
+  UNREACHABLE();
+  return Object::null();
+}
+
+
+void Parser::ParseFunction(ParsedFunction* parsed_function) {
+  UNREACHABLE();
+}
+
+
+RawObject* Parser::ParseMetadata(const Field& meta_data) {
+  UNREACHABLE();
+  return Object::null();
+}
+
+
+ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) {
+  UNREACHABLE();
+  return NULL;
+}
+
+
+ArgumentListNode* Parser::BuildNoSuchMethodArguments(
+    intptr_t call_pos,
+    const String& function_name,
+    const ArgumentListNode& function_args,
+    const LocalVariable* temp_for_last_arg,
+    bool is_super_invocation) {
+  UNREACHABLE();
+  return NULL;
+}
+
+}  // namespace dart
+
+#endif  // DART_PRECOMPILED
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 433a0c4..1be0f50 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -63,7 +63,7 @@
     LocalVariable* temp = new(zone()) LocalVariable(
         function.token_pos(),
         Symbols::CurrentContextVar(),
-        Type::ZoneHandle(zone(), Type::DynamicType()));
+        Object::dynamic_type());
     ASSERT(temp != NULL);
     current_context_var_ = temp;
   }
@@ -205,7 +205,7 @@
   // Parse and evaluate the metadata expressions at token_pos in the
   // class namespace of class cls (which can be the implicit toplevel
   // class if the metadata is at the top-level).
-  static RawObject* ParseMetadata(const Class& cls, intptr_t token_pos);
+  static RawObject* ParseMetadata(const Field& meta_data);
 
   // Build a function containing the initializer expression of the
   // given static field.
@@ -399,22 +399,25 @@
   // Support for parsing of scripts.
   void ParseTopLevel();
   void ParseEnumDeclaration(const GrowableObjectArray& pending_classes,
-                            const Class& toplevel_class,
+                            const Object& tl_owner,
                             intptr_t metadata_pos);
   void ParseEnumDefinition(const Class& cls);
   void ParseClassDeclaration(const GrowableObjectArray& pending_classes,
-                             const Class& toplevel_class,
+                             const Object& tl_owner,
                              intptr_t metadata_pos);
   void ParseClassDefinition(const Class& cls);
   void ParseMixinAppAlias(const GrowableObjectArray& pending_classes,
-                          const Class& toplevel_class,
+                          const Object& tl_owner,
                           intptr_t metadata_pos);
   void ParseTypedef(const GrowableObjectArray& pending_classes,
-                    const Class& toplevel_class,
+                    const Object& tl_owner,
                     intptr_t metadata_pos);
-  void ParseTopLevelVariable(TopLevel* top_level, intptr_t metadata_pos);
-  void ParseTopLevelFunction(TopLevel* top_level, intptr_t metadata_pos);
-  void ParseTopLevelAccessor(TopLevel* top_level, intptr_t metadata_pos);
+  void ParseTopLevelVariable(TopLevel* top_level,
+                             const Object& owner, intptr_t metadata_pos);
+  void ParseTopLevelFunction(TopLevel* top_level,
+                             const Object& owner, intptr_t metadata_pos);
+  void ParseTopLevelAccessor(TopLevel* top_level,
+                             const Object& owner, intptr_t metadata_pos);
   RawArray* EvaluateMetadata();
 
   RawFunction::AsyncModifier ParseFunctionModifier();
@@ -424,9 +427,10 @@
                                    intptr_t token_pos,
                                    const String& url);
   void ParseIdentList(GrowableObjectArray* names);
-  void ParseLibraryDefinition();
+  void ParseLibraryDefinition(const Object& tl_owner);
   void ParseLibraryName();
-  void ParseLibraryImportExport(intptr_t metadata_pos);
+  void ParseLibraryImportExport(const Object& tl_owner,
+                                intptr_t metadata_pos);
   void ParseLibraryPart();
   void ParsePartHeader();
   void ParseLibraryNameObsoleteSyntax();
@@ -480,7 +484,6 @@
       const Class& cls,
       intptr_t supercall_pos,
       LocalVariable* receiver,
-      AstNode* phase_parameter,
       ArgumentListNode* forwarding_args);
   StaticCallNode* ParseSuperInitializer(
       const Class& cls,
@@ -581,7 +584,6 @@
   void AddAsyncClosureVariables();
   void AddAsyncGeneratorVariables();
 
-  LocalVariable* LookupPhaseParameter();
   LocalVariable* LookupReceiver(LocalScope* from_scope, bool test_only);
   LocalVariable* LookupTypeArgumentsParameter(LocalScope* from_scope,
                                               bool test_only);
diff --git a/runtime/vm/port_test.cc b/runtime/vm/port_test.cc
index 165d19c..ee443cd 100644
--- a/runtime/vm/port_test.cc
+++ b/runtime/vm/port_test.cc
@@ -151,6 +151,34 @@
 }
 
 
+TEST_CASE(PortMap_PostIntegerMessage) {
+  PortTestMessageHandler handler;
+  Dart_Port port = PortMap::CreatePort(&handler);
+  EXPECT_EQ(0, handler.notify_count);
+
+  EXPECT(PortMap::PostMessage(new Message(
+      port, Smi::New(42), Message::kNormalPriority)));
+
+  // Check that the message notify callback was called.
+  EXPECT_EQ(1, handler.notify_count);
+  PortMap::ClosePorts(&handler);
+}
+
+
+TEST_CASE(PortMap_PostNullMessage) {
+  PortTestMessageHandler handler;
+  Dart_Port port = PortMap::CreatePort(&handler);
+  EXPECT_EQ(0, handler.notify_count);
+
+  EXPECT(PortMap::PostMessage(new Message(
+      port, Object::null(), Message::kNormalPriority)));
+
+  // Check that the message notify callback was called.
+  EXPECT_EQ(1, handler.notify_count);
+  PortMap::ClosePorts(&handler);
+}
+
+
 TEST_CASE(PortMap_PostMessageClosedPort) {
   // Create a port id and make it invalid.
   PortTestMessageHandler handler;
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index f061da0..97f90c3 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -4,8 +4,10 @@
 
 #include "vm/precompiler.h"
 
+#include "vm/cha.h"
 #include "vm/code_patcher.h"
 #include "vm/compiler.h"
+#include "vm/hash_table.h"
 #include "vm/isolate.h"
 #include "vm/log.h"
 #include "vm/longjump.h"
@@ -17,10 +19,15 @@
 namespace dart {
 
 
+#define T (thread())
 #define I (isolate())
 #define Z (zone())
 
 
+DEFINE_FLAG(bool, collect_dynamic_function_names, false,
+    "In precompilation collects all dynamic function names in order to"
+    " identify unique targets");
+DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets");
 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler.");
 
 
@@ -59,31 +66,57 @@
     libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())),
     pending_functions_(
         GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
-    collected_closures_(
-        GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
     sent_selectors_(),
+    enqueued_functions_(),
     error_(Error::Handle(Z)) {
-  I->set_collected_closures(collected_closures_);
 }
 
 
 void Precompiler::DoCompileAll(
     Dart_QualifiedFunctionName embedder_entry_points[]) {
-  // Drop all existing code so we can use the presence of code as an indicator
-  // that we have already looked for the function's callees.
-  ClearAllCode();
+  ASSERT(I->compilation_allowed());
 
-  // Start with the allocations and invocations that happen from C++.
-  AddRoots(embedder_entry_points);
+  // Make sure class hierarchy is stable before compilation so that CHA
+  // can be used. Also ensures lookup of entry points won't miss functions
+  // because their class hasn't been finalized yet.
+  FinalizeAllClasses();
 
-  // TODO(rmacnak): Eagerly add field-invocation functions to all signature
-  // classes so closure calls don't go through the runtime.
+  const intptr_t kPrecompilerRounds = 1;
+  for (intptr_t round = 0; round < kPrecompilerRounds; round++) {
+    if (FLAG_trace_precompiler) {
+      OS::Print("Precompiler round %" Pd "\n", round);
+    }
 
-  // Compile newly found targets and add their callees until we reach a fixed
-  // point.
-  Iterate();
+    if (round > 0) {
+      ResetPrecompilerState();
+    }
 
-  CleanUp();
+    // TODO(rmacnak): We should be able to do a more thorough job and drop some
+    //  - implicit static closures
+    //  - field initializers
+    //  - invoke-field-dispatchers
+    //  - method-extractors
+    // that are needed in early iterations but optimized away in later
+    // iterations.
+    ClearAllCode();
+
+    CollectDynamicFunctionNames();
+
+    // Start with the allocations and invocations that happen from C++.
+    AddRoots(embedder_entry_points);
+
+    // Compile newly found targets and add their callees until we reach a fixed
+    // point.
+    Iterate();
+  }
+
+  DropUncompiledFunctions();
+
+  // TODO(rmacnak): DropEmptyClasses();
+
+  BindStaticCalls();
+
+  DedupStackmaps();
 
   if (FLAG_trace_precompiler) {
     THR_Print("Precompiled %" Pd " functions, %" Pd " dynamic types,"
@@ -99,12 +132,12 @@
 
 
 void Precompiler::ClearAllCode() {
-  class CodeCodeFunctionVisitor : public FunctionVisitor {
+  class ClearCodeFunctionVisitor : public FunctionVisitor {
     void VisitFunction(const Function& function) {
       function.ClearCode();
     }
   };
-  CodeCodeFunctionVisitor visitor;
+  ClearCodeFunctionVisitor visitor;
   VisitFunctions(&visitor);
 }
 
@@ -142,13 +175,19 @@
     kTypedDataUint16ArrayCid,
     kTypedDataUint32ArrayCid,
     kTypedDataUint64ArrayCid,
-
     kTypedDataInt8ArrayCid,
     kTypedDataInt16ArrayCid,
     kTypedDataInt32ArrayCid,
     kTypedDataInt64ArrayCid,
 
     kExternalTypedDataUint8ArrayCid,
+    kExternalTypedDataUint16ArrayCid,
+    kExternalTypedDataUint32ArrayCid,
+    kExternalTypedDataUint64ArrayCid,
+    kExternalTypedDataInt8ArrayCid,
+    kExternalTypedDataInt16ArrayCid,
+    kExternalTypedDataInt32ArrayCid,
+    kExternalTypedDataInt64ArrayCid,
 
     kTypedDataFloat32ArrayCid,
     kTypedDataFloat64ArrayCid,
@@ -181,15 +220,15 @@
   Class& cls = Class::Handle(Z);
   for (intptr_t i = 0; kExternallyAllocatedCids[i] != kIllegalCid; i++) {
     cls = isolate()->class_table()->At(kExternallyAllocatedCids[i]);
-    AddClass(cls);
+    AddInstantiatedClass(cls);
   }
 
   Dart_QualifiedFunctionName vm_entry_points[] = {
     { "dart:async", "::", "_setScheduleImmediateClosure" },
+    { "dart:core", "::", "_completeDeferredLoads"},
     { "dart:core", "AbstractClassInstantiationError",
                    "AbstractClassInstantiationError._create" },
     { "dart:core", "ArgumentError", "ArgumentError." },
-    { "dart:core", "AssertionError", "AssertionError." },
     { "dart:core", "CyclicInitializationError",
                    "CyclicInitializationError." },
     { "dart:core", "FallThroughError", "FallThroughError._create" },
@@ -201,6 +240,7 @@
     { "dart:core", "RangeError", "RangeError.range" },
     { "dart:core", "StackOverflowError", "StackOverflowError." },
     { "dart:core", "UnsupportedError", "UnsupportedError." },
+    { "dart:core", "_AssertionError", "_AssertionError._create" },
     { "dart:core", "_CastError", "_CastError._create" },
     { "dart:core", "_InternalError", "_InternalError." },
     { "dart:core", "_InvocationMirror", "_allocateInvocationMirror" },
@@ -210,15 +250,18 @@
                    "_JavascriptIntegerOverflowError." },
     { "dart:core", "_TypeError", "_TypeError._create" },
     { "dart:isolate", "IsolateSpawnException", "IsolateSpawnException." },
-    { "dart:isolate", "_IsolateUnhandledException",
-                      "_IsolateUnhandledException." },
     { "dart:isolate", "::", "_getIsolateScheduleImmediateClosure" },
     { "dart:isolate", "::", "_setupHooks" },
     { "dart:isolate", "::", "_startMainIsolate" },
     { "dart:isolate", "_RawReceivePortImpl", "_handleMessage" },
     { "dart:isolate", "_RawReceivePortImpl", "_lookupHandler" },
-    { "dart:vmservice", "::", "_registerIsolate" },
-    { "dart:vmservice", "::", "boot" },
+    { "dart:isolate", "_SendPortImpl", "send" },
+    { "dart:typed_data", "ByteData", "ByteData." },
+    { "dart:typed_data", "ByteData", "ByteData._view" },
+    { "dart:typed_data", "_ByteBuffer", "_ByteBuffer._New" },
+    { "dart:_vmservice", "::", "_registerIsolate" },
+    { "dart:_vmservice", "::", "boot" },
+    { "dart:developer", "Metrics", "_printMetrics" },
     { NULL, NULL, NULL }  // Must be terminated with NULL entries.
   };
 
@@ -276,6 +319,13 @@
     }
 
     AddFunction(func);
+    if (func.IsGenerativeConstructor()) {
+      // Allocation stubs are referenced from the call site of the constructor,
+      // not in the constructor itself. So compiling the constructor isn't
+      // enough for us to discover the class is instantiated if the class isn't
+      // otherwise instantiated from Dart code and only instantiated from C++.
+      AddInstantiatedClass(cls);
+    }
   }
 }
 
@@ -292,30 +342,10 @@
     }
 
     CheckForNewDynamicFunctions();
-
-    // Drain collected_closures last because additions to this list come from
-    // outside the Precompiler and so do not flip our changed_ flag.
-    while (collected_closures_.Length() > 0) {
-      function ^= collected_closures_.RemoveLast();
-      ProcessFunction(function);
-    }
   }
 }
 
 
-void Precompiler::CleanUp() {
-  I->set_collected_closures(GrowableObjectArray::Handle(Z));
-
-  DropUncompiledFunctions();
-
-  // TODO(rmacnak): DropEmptyClasses();
-
-  BindStaticCalls();
-
-  DedupStackmaps();
-}
-
-
 void Precompiler::ProcessFunction(const Function& function) {
   if (!function.HasCode()) {
     function_count_++;
@@ -335,6 +365,15 @@
     if (!error_.IsNull()) {
       Jump(error_);
     }
+  } else {
+    if (FLAG_trace_precompiler) {
+      // This function was compiled from somewhere other than Precompiler,
+      // such as const constructors compiled by the parser.
+      THR_Print("Already has code: %s (%" Pd ", %s)\n",
+                function.ToLibNamePrefixedQualifiedCString(),
+                function.token_pos(),
+                Function::KindToCString(function.kind()));
+    }
   }
 
   ASSERT(function.HasCode());
@@ -364,9 +403,12 @@
 
   const ObjectPool& pool = ObjectPool::Handle(Z, code.GetObjectPool());
   ICData& call_site = ICData::Handle(Z);
+  MegamorphicCache& cache = MegamorphicCache::Handle(Z);
   String& selector = String::Handle(Z);
   Field& field = Field::Handle(Z);
   Class& cls = Class::Handle(Z);
+  Instance& instance = Instance::Handle(Z);
+  Code& target_code = Code::Handle(Z);
   for (intptr_t i = 0; i < pool.Length(); i++) {
     if (pool.InfoAt(i) == ObjectPool::kTaggedObject) {
       entry = pool.ObjectAt(i);
@@ -391,20 +433,81 @@
             AddClosureCall(call_site);
           }
         }
+      } else if (entry.IsMegamorphicCache()) {
+        // A dynamic call.
+        cache ^= entry.raw();
+        selector = cache.target_name();
+        AddSelector(selector);
       } else if (entry.IsField()) {
         // Potential need for field initializer.
         field ^= entry.raw();
         AddField(field);
       } else if (entry.IsInstance()) {
-        // Potential const object.
-        cls = entry.clazz();
-        AddClass(cls);
+        // Const object, literal or args descriptor.
+        instance ^= entry.raw();
+        AddConstObject(instance);
+      } else if (entry.IsFunction()) {
+        // Local closure function.
+        target ^= entry.raw();
+        AddFunction(target);
+      } else if (entry.IsCode()) {
+        target_code ^= entry.raw();
+        if (target_code.IsAllocationStubCode()) {
+          cls ^= target_code.owner();
+          AddInstantiatedClass(cls);
+        }
       }
     }
   }
 }
 
 
+void Precompiler::AddConstObject(const Instance& instance) {
+  const Class& cls = Class::Handle(Z, instance.clazz());
+  AddInstantiatedClass(cls);
+
+  if (instance.IsClosure()) {
+    // An implicit static closure.
+    const Function& func = Function::Handle(Z, Closure::function(instance));
+    ASSERT(func.is_static());
+    AddFunction(func);
+    return;
+  }
+
+  // Can't ask immediate objects if they're canoncial.
+  if (instance.IsSmi()) return;
+
+  // Some Instances in the ObjectPool aren't const objects, such as
+  // argument descriptors.
+  if (!instance.IsCanonical()) return;
+
+  class ConstObjectVisitor : public ObjectPointerVisitor {
+   public:
+    ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) :
+        ObjectPointerVisitor(isolate),
+        precompiler_(precompiler),
+        subinstance_(Object::Handle()) {}
+
+    virtual void VisitPointers(RawObject** first, RawObject** last) {
+      for (RawObject** current = first; current <= last; current++) {
+        subinstance_ = *current;
+        if (subinstance_.IsInstance()) {
+          precompiler_->AddConstObject(Instance::Cast(subinstance_));
+        }
+      }
+      subinstance_ = Object::null();
+    }
+
+   private:
+    Precompiler* precompiler_;
+    Object& subinstance_;
+  };
+
+  ConstObjectVisitor visitor(this, I);
+  instance.raw()->VisitPointers(&visitor);
+}
+
+
 void Precompiler::AddClosureCall(const ICData& call_site) {
   const Array& arguments_descriptor =
       Array::Handle(Z, call_site.arguments_descriptor());
@@ -423,11 +526,10 @@
 
 void Precompiler::AddField(const Field& field) {
   if (field.is_static()) {
-    // Potential const object. Uninitialized field will harmlessly do a
-    // redundant add of the Null class.
     const Object& value = Object::Handle(Z, field.StaticValue());
-    const Class& cls = Class::Handle(Z, value.clazz());
-    AddClass(cls);
+    if (value.IsInstance()) {
+      AddConstObject(Instance::Cast(value));
+    }
 
     if (field.has_initializer()) {
       // Should not be in the middle of initialization while precompiling.
@@ -436,14 +538,14 @@
       const bool is_initialized = value.raw() != Object::sentinel().raw();
       if (is_initialized && !reset_fields_) return;
 
-      if (field.HasPrecompiledInitializer()) return;
-
-      if (FLAG_trace_precompiler) {
-        THR_Print("Precompiling initializer for %s\n", field.ToCString());
+      if (!field.HasPrecompiledInitializer()) {
+        if (FLAG_trace_precompiler) {
+          THR_Print("Precompiling initializer for %s\n", field.ToCString());
+        }
+        ASSERT(!Dart::IsRunningPrecompiledCode());
+        field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue()));
+        Compiler::CompileStaticInitializer(field);
       }
-      ASSERT(!Dart::IsRunningPrecompiledCode());
-      field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue()));
-      Compiler::CompileStaticInitializer(field);
 
       const Function& function =
           Function::Handle(Z, field.PrecompiledInitializer());
@@ -454,8 +556,9 @@
 
 
 void Precompiler::AddFunction(const Function& function) {
-  if (function.HasCode()) return;
+  if (enqueued_functions_.Lookup(&function) != NULL) return;
 
+  enqueued_functions_.Insert(&Function::ZoneHandle(Z, function.raw()));
   pending_functions_.Add(function);
   changed_ = true;
 }
@@ -486,11 +589,16 @@
 }
 
 
-void Precompiler::AddClass(const Class& cls) {
+void Precompiler::AddInstantiatedClass(const Class& cls) {
   if (cls.is_allocated()) return;
 
   class_count_++;
-  cls.set_is_allocated();
+  cls.set_is_allocated(true);
+  error_ = cls.EnsureIsFinalized(T);
+  if (!error_.IsNull()) {
+    Jump(error_);
+  }
+
   changed_ = true;
 
   if (FLAG_trace_precompiler) {
@@ -499,7 +607,7 @@
 
   const Class& superclass = Class::Handle(cls.SuperClass());
   if (!superclass.IsNull()) {
-    AddClass(superclass);
+    AddInstantiatedClass(superclass);
   }
 }
 
@@ -520,43 +628,7 @@
     while (it.HasNext()) {
       cls = it.GetNextClass();
 
-      if (!cls.is_allocated()) {
-        bool has_compiled_constructor = false;
-        if (cls.allocation_stub() != Code::null()) {
-          // Regular objects.
-          has_compiled_constructor = true;
-        } else if (cls.is_synthesized_class()) {
-          // Enums.
-          has_compiled_constructor = true;
-        } else {
-          // Objects only allocated via const constructors, and not stored in a
-          // static field or code.
-          // E.g. A in
-          //   class A {
-          //     const A();
-          //     toString() => "Don't drop me!";
-          //   }
-          //   class B {
-          //     const a = const A();
-          //     const B();
-          //     static const theB = const B();
-          //   }
-          //   main() => print(B.theB.a);
-          functions = cls.functions();
-          for (intptr_t k = 0; k < functions.Length(); k++) {
-            function ^= functions.At(k);
-            if (function.IsGenerativeConstructor() &&
-                function.HasCode()) {
-              has_compiled_constructor = true;
-              break;
-            }
-          }
-        }
-        if (!has_compiled_constructor) {
-          continue;
-        }
-        AddClass(cls);
-      }
+      if (!cls.is_allocated()) continue;
 
       functions = cls.functions();
       for (intptr_t k = 0; k < functions.Length(); k++) {
@@ -591,6 +663,10 @@
 
             function2 = function.ImplicitClosureFunction();
             AddFunction(function2);
+
+            // Add corresponding method extractor get:#foo.
+            function2 = function.GetMethodExtractor(selector3);
+            AddFunction(function2);
           }
         } else if (Field::IsSetterName(selector)) {
           selector2 = Symbols::LookupFromConcat(Symbols::ClosurizePrefix(),
@@ -602,6 +678,10 @@
 
             function2 = function.ImplicitClosureFunction();
             AddFunction(function2);
+
+            // Add corresponding method extractor get:#set:foo.
+            function2 = function.GetMethodExtractor(selector2);
+            AddFunction(function2);
           }
         } else if (function.kind() == RawFunction::kRegularFunction) {
           selector2 = Field::LookupGetterSymbol(selector);
@@ -610,6 +690,10 @@
             // Function is foo and somewhere get:foo is called.
             function2 = function.ImplicitClosureFunction();
             AddFunction(function2);
+
+            // Add corresponding method extractor.
+            function2 = function.GetMethodExtractor(selector2);
+            AddFunction(function2);
           }
           selector2 = Symbols::LookupFromConcat(Symbols::ClosurizePrefix(),
                                                 selector);
@@ -618,6 +702,10 @@
             // Function is foo and somewhere get:#foo is called.
             function2 = function.ImplicitClosureFunction();
             AddFunction(function2);
+
+            // Add corresponding method extractor get:#foo
+            function2 = function.GetMethodExtractor(selector2);
+            AddFunction(function2);
           }
         }
       }
@@ -626,11 +714,161 @@
 }
 
 
+class NameFunctionsTraits {
+ public:
+  static bool IsMatch(const Object& a, const Object& b) {
+    return a.IsString() && b.IsString() &&
+        String::Cast(a).Equals(String::Cast(b));
+  }
+  static uword Hash(const Object& obj) {
+    return String::Cast(obj).Hash();
+  }
+  static RawObject* NewKey(const String& str) {
+    return str.raw();
+  }
+};
+
+typedef UnorderedHashMap<NameFunctionsTraits> Table;
+
+
+class FunctionsTraits {
+ public:
+  static bool IsMatch(const Object& a, const Object& b) {
+    Zone* zone = Thread::Current()->zone();
+    String& a_s = String::Handle(zone);
+    String& b_s = String::Handle(zone);
+    a_s = a.IsFunction() ? Function::Cast(a).name() : String::Cast(a).raw();
+    b_s = b.IsFunction() ? Function::Cast(b).name() : String::Cast(b).raw();
+    ASSERT(a_s.IsSymbol() && b_s.IsSymbol());
+    return a_s.raw() == b_s.raw();
+  }
+  static uword Hash(const Object& obj) {
+    if (obj.IsFunction()) {
+      return String::Handle(Function::Cast(obj).name()).Hash();
+    } else {
+      ASSERT(String::Cast(obj).IsSymbol());
+      return String::Cast(obj).Hash();
+    }
+  }
+  static RawObject* NewKey(const Function& function) {
+    return function.raw();
+  }
+};
+
+typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet;
+
+
+static void AddNameToFunctionsTable(Zone* zone,
+                                    Table* table,
+                                    const String& fname,
+                                    const Function& function) {
+  Array& farray = Array::Handle(zone);
+  farray ^= table->InsertNewOrGetValue(fname, Array::empty_array());
+  farray = Array::Grow(farray, farray.Length() + 1);
+  farray.SetAt(farray.Length() - 1, function);
+  table->UpdateValue(fname, farray);
+}
+
+
+void Precompiler::CollectDynamicFunctionNames() {
+  if (!FLAG_collect_dynamic_function_names) {
+    return;
+  }
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+  Array& functions = Array::Handle(Z);
+  Function& function = Function::Handle(Z);
+  String& fname = String::Handle(Z);
+  Array& farray = Array::Handle(Z);
+
+  Table table(HashTables::New<Table>(100));
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+    while (it.HasNext()) {
+      cls = it.GetNextClass();
+      if (cls.IsDynamicClass()) {
+        continue;  // class 'dynamic' is in the read-only VM isolate.
+      }
+      functions = cls.functions();
+      for (intptr_t j = 0; j < functions.Length(); j++) {
+        function ^= functions.At(j);
+        if (function.IsDynamicFunction()) {
+          fname = function.name();
+          if (function.IsSetterFunction() ||
+              function.IsImplicitSetterFunction()) {
+            AddNameToFunctionsTable(zone(), &table, fname, function);
+          } else if (function.IsGetterFunction() ||
+                     function.IsImplicitGetterFunction()) {
+            // Enter both getter and non getter name.
+            AddNameToFunctionsTable(zone(), &table, fname, function);
+            fname = Field::NameFromGetter(fname);
+            AddNameToFunctionsTable(zone(), &table, fname, function);
+          } else {
+            // Regular function. Enter both getter and non getter name.
+            AddNameToFunctionsTable(zone(), &table, fname, function);
+            fname = Field::GetterName(fname);
+            AddNameToFunctionsTable(zone(), &table, fname, function);
+          }
+        }
+      }
+    }
+  }
+
+  // Locate all entries with one function only, and whose owner is neither
+  // subclassed nor implemented.
+  Table::Iterator iter(&table);
+  String& key = String::Handle(Z);
+  UniqueFunctionsSet functions_set(HashTables::New<UniqueFunctionsSet>(20));
+  while (iter.MoveNext()) {
+    intptr_t curr_key = iter.Current();
+    key ^= table.GetKey(curr_key);
+    farray ^= table.GetOrNull(key);
+    ASSERT(!farray.IsNull());
+    if (farray.Length() == 1) {
+      function ^= farray.At(0);
+      cls = function.Owner();
+      if (!CHA::IsImplemented(cls) && !CHA::HasSubclasses(cls)) {
+        functions_set.Insert(function);
+      }
+    }
+  }
+
+  if (FLAG_print_unique_targets) {
+    UniqueFunctionsSet::Iterator unique_iter(&functions_set);
+    while (unique_iter.MoveNext()) {
+      intptr_t curr_key = unique_iter.Current();
+      function ^= functions_set.GetKey(curr_key);
+      THR_Print("* %s\n", function.ToQualifiedCString());
+    }
+    THR_Print("%" Pd " of %" Pd " dynamic selectors are unique\n",
+        functions_set.NumOccupied(), table.NumOccupied());
+  }
+
+  isolate()->object_store()->set_unique_dynamic_targets(
+      functions_set.Release());
+  table.Release();
+}
+
+
+void Precompiler::GetUniqueDynamicTarget(Isolate* isolate,
+                                         const String& fname,
+                                         Object* function) {
+  UniqueFunctionsSet functions_set(
+      isolate->object_store()->unique_dynamic_targets());
+  ASSERT(fname.IsSymbol());
+  *function = functions_set.GetOrNull(fname);
+  ASSERT(functions_set.Release().raw() ==
+      isolate->object_store()->unique_dynamic_targets());
+}
+
+
 void Precompiler::DropUncompiledFunctions() {
   Library& lib = Library::Handle(Z);
   Class& cls = Class::Handle(Z);
   Array& functions = Array::Handle(Z);
   Function& function = Function::Handle(Z);
+  Function& function2 = Function::Handle(Z);
   GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z);
   GrowableObjectArray& closures = GrowableObjectArray::Handle(Z);
 
@@ -647,8 +885,18 @@
       retained_functions = GrowableObjectArray::New();
       for (intptr_t j = 0; j < functions.Length(); j++) {
         function ^= functions.At(j);
-        if (function.HasCode()) {
+        bool retain = function.HasCode();
+        if (!retain && function.HasImplicitClosureFunction()) {
+          // It can happen that all uses of an implicit closure inline their
+          // target function, leaving the target function uncompiled. Keep
+          // the target function anyway so we can enumerate it to bind its
+          // static calls, etc.
+          function2 = function.ImplicitClosureFunction();
+          retain = function2.HasCode();
+        }
+        if (retain) {
           retained_functions.Add(function);
+          function.DropUncompiledImplicitClosureFunction();
         } else {
           dropped_function_count_++;
           if (FLAG_trace_precompiler) {
@@ -664,26 +912,24 @@
         functions.SetAt(j, function);
       }
       cls.SetFunctions(functions);
+    }
+  }
 
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        retained_functions = GrowableObjectArray::New();
-        for (intptr_t j = 0; j < closures.Length(); j++) {
-          function ^= closures.At(j);
-          if (function.HasCode()) {
-            retained_functions.Add(function);
-          } else {
-            dropped_function_count_++;
-            if (FLAG_trace_precompiler) {
-              THR_Print("Precompilation dropping %s\n",
-                        function.ToLibNamePrefixedQualifiedCString());
-            }
-          }
-        }
-        cls.set_closures(retained_functions);
+  closures = isolate()->object_store()->closure_functions();
+  retained_functions = GrowableObjectArray::New();
+  for (intptr_t j = 0; j < closures.Length(); j++) {
+    function ^= closures.At(j);
+    if (function.HasCode()) {
+      retained_functions.Add(function);
+    } else {
+      dropped_function_count_++;
+      if (FLAG_trace_precompiler) {
+        THR_Print("Precompilation dropping %s\n",
+                  function.ToLibNamePrefixedQualifiedCString());
       }
     }
   }
+  isolate()->object_store()->set_closure_functions(retained_functions);
 }
 
 
@@ -699,7 +945,10 @@
     }
 
     void VisitFunction(const Function& function) {
-      ASSERT(function.HasCode());
+      if (!function.HasCode()) {
+        ASSERT(function.HasImplicitClosureFunction());
+        return;
+      }
       code_ = function.CurrentCode();
       table_ = code_.static_calls_target_table();
 
@@ -756,6 +1005,10 @@
     }
 
     void VisitFunction(const Function& function) {
+      if (!function.HasCode()) {
+        ASSERT(function.HasImplicitClosureFunction());
+        return;
+      }
       code_ = function.CurrentCode();
       stackmaps_ = code_.stackmaps();
       if (stackmaps_.IsNull()) return;
@@ -795,6 +1048,7 @@
   Library& lib = Library::Handle(Z);
   Class& cls = Class::Handle(Z);
   Array& functions = Array::Handle(Z);
+  Object& object = Object::Handle(Z);
   Function& function = Function::Handle(Z);
   GrowableObjectArray& closures = GrowableObjectArray::Handle(Z);
 
@@ -811,15 +1065,83 @@
       for (intptr_t j = 0; j < functions.Length(); j++) {
         function ^= functions.At(j);
         visitor->VisitFunction(function);
-      }
-
-      closures = cls.closures();
-      if (!closures.IsNull()) {
-        for (intptr_t j = 0; j < closures.Length(); j++) {
-          function ^= closures.At(j);
+        if (function.HasImplicitClosureFunction()) {
+          function = function.ImplicitClosureFunction();
           visitor->VisitFunction(function);
         }
       }
+
+      functions = cls.invocation_dispatcher_cache();
+      for (intptr_t j = 0; j < functions.Length(); j++) {
+        object = functions.At(j);
+        if (object.IsFunction()) {
+          function ^= functions.At(j);
+          visitor->VisitFunction(function);
+        }
+      }
+    }
+  }
+  closures = isolate()->object_store()->closure_functions();
+  for (intptr_t j = 0; j < closures.Length(); j++) {
+    function ^= closures.At(j);
+    visitor->VisitFunction(function);
+    ASSERT(!function.HasImplicitClosureFunction());
+  }
+}
+
+
+void Precompiler::FinalizeAllClasses() {
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    if (!lib.Loaded()) {
+      String& uri = String::Handle(Z, lib.url());
+      String& msg = String::Handle(Z, String::NewFormatted(
+          "Library '%s' is not loaded. "
+          "Did you forget to call Dart_FinalizeLoading?", uri.ToCString()));
+      Jump(Error::Handle(Z, ApiError::New(msg)));
+    }
+
+    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+    while (it.HasNext()) {
+      cls = it.GetNextClass();
+      if (cls.IsDynamicClass()) {
+        continue;  // class 'dynamic' is in the read-only VM isolate.
+      }
+      error_ = cls.EnsureIsFinalized(T);
+      if (!error_.IsNull()) {
+        Jump(error_);
+      }
+    }
+  }
+  I->set_all_classes_finalized(true);
+}
+
+
+void Precompiler::ResetPrecompilerState() {
+  changed_ = false;
+  function_count_ = 0;
+  class_count_ = 0;
+  selector_count_ = 0;
+  dropped_function_count_ = 0;
+  ASSERT(pending_functions_.Length() == 0);
+  sent_selectors_.Clear();
+  enqueued_functions_.Clear();
+
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+    while (it.HasNext()) {
+      cls = it.GetNextClass();
+      if (cls.IsDynamicClass()) {
+        continue;  // class 'dynamic' is in the read-only VM isolate.
+      }
+      cls.set_is_allocated(false);
     }
   }
 }
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index 5051ead..50f9551 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -64,6 +64,28 @@
 
 typedef DirectChainedHashMap<StackmapKeyValueTrait> StackmapSet;
 
+class FunctionKeyValueTrait {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef const Function* Key;
+  typedef const Function* Value;
+  typedef const Function* Pair;
+
+  static Key KeyOf(Pair kv) { return kv; }
+
+  static Value ValueOf(Pair kv) { return kv; }
+
+  static inline intptr_t Hashcode(Key key) {
+    return key->token_pos();
+  }
+
+  static inline bool IsKeyEqual(Pair pair, Key key) {
+    return pair->raw() == key->raw();
+  }
+};
+
+typedef DirectChainedHashMap<FunctionKeyValueTrait> FunctionSet;
+
 
 class Precompiler : public ValueObject {
  public:
@@ -71,6 +93,16 @@
       Dart_QualifiedFunctionName embedder_entry_points[],
       bool reset_fields);
 
+  // Returns named function that is a unique dynamic target, i.e.,
+  // - the target is identified by its name alone, since it occurs only once.
+  // - target's class has no subclasses, and neither is subclassed, i.e.,
+  //   the receiver type can be only the function's class.
+  // Returns Function::null() if there is no unique dynamic target for
+  // given 'fname'. 'fname' must be a symbol.
+  static void GetUniqueDynamicTarget(Isolate* isolate,
+                                     const String& fname,
+                                     Object* function);
+
  private:
   Precompiler(Thread* thread, bool reset_fields);
 
@@ -79,13 +111,13 @@
   void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]);
   void AddEntryPoints(Dart_QualifiedFunctionName entry_points[]);
   void Iterate();
-  void CleanUp();
 
   void AddCalleesOf(const Function& function);
+  void AddConstObject(const Instance& instance);
   void AddClosureCall(const ICData& call_site);
   void AddField(const Field& field);
   void AddFunction(const Function& function);
-  void AddClass(const Class& cls);
+  void AddInstantiatedClass(const Class& cls);
   void AddSelector(const String& selector);
   bool IsSent(const String& selector);
 
@@ -93,8 +125,10 @@
   void CheckForNewDynamicFunctions();
 
   void DropUncompiledFunctions();
+  void CollectDynamicFunctionNames();
   void BindStaticCalls();
   void DedupStackmaps();
+  void ResetPrecompilerState();
 
   class FunctionVisitor : public ValueObject {
    public:
@@ -104,6 +138,8 @@
 
   void VisitFunctions(FunctionVisitor* visitor);
 
+  void FinalizeAllClasses();
+
   Thread* thread() const { return thread_; }
   Zone* zone() const { return zone_; }
   Isolate* isolate() const { return isolate_; }
@@ -122,8 +158,8 @@
 
   const GrowableObjectArray& libraries_;
   const GrowableObjectArray& pending_functions_;
-  const GrowableObjectArray& collected_closures_;
   SymbolSet sent_selectors_;
+  FunctionSet enqueued_functions_;
   Error& error_;
 };
 
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 1515eed..53f04b6 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -9,10 +9,12 @@
 #include "vm/allocation.h"
 #include "vm/atomic.h"
 #include "vm/code_patcher.h"
+#include "vm/debugger.h"
 #include "vm/instructions.h"
 #include "vm/isolate.h"
 #include "vm/json_stream.h"
 #include "vm/lockers.h"
+#include "vm/message_handler.h"
 #include "vm/native_symbol.h"
 #include "vm/object.h"
 #include "vm/os.h"
@@ -104,120 +106,6 @@
 }
 
 
-void Profiler::InitProfilingForIsolate(Isolate* isolate, bool shared_buffer) {
-  if (!FLAG_profile) {
-    return;
-  }
-  ASSERT(isolate == Isolate::Current());
-  ASSERT(isolate != NULL);
-  ASSERT(sample_buffer_ != NULL);
-  {
-    MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
-    SampleBuffer* sample_buffer = sample_buffer_;
-    if (!shared_buffer) {
-      sample_buffer = new SampleBuffer();
-    }
-    IsolateProfilerData* profiler_data =
-        new IsolateProfilerData(sample_buffer, !shared_buffer);
-    ASSERT(profiler_data != NULL);
-    isolate->set_profiler_data(profiler_data);
-    if (FLAG_trace_profiled_isolates) {
-      OS::Print("Profiler Setup %p %s\n", isolate, isolate->name());
-    }
-  }
-  BeginExecution(isolate);
-}
-
-
-void Profiler::ShutdownProfilingForIsolate(Isolate* isolate) {
-  ASSERT(isolate != NULL);
-  if (!FLAG_profile) {
-    return;
-  }
-  // We do not have a current isolate.
-  ASSERT(Isolate::Current() == NULL);
-  {
-    MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
-    IsolateProfilerData* profiler_data = isolate->profiler_data();
-    if (profiler_data == NULL) {
-      // Already freed.
-      return;
-    }
-    isolate->set_profiler_data(NULL);
-    delete profiler_data;
-    if (FLAG_trace_profiled_isolates) {
-      OS::Print("Profiler Shutdown %p %s\n", isolate, isolate->name());
-    }
-  }
-}
-
-
-void Profiler::BeginExecution(Isolate* isolate) {
-  if (isolate == NULL) {
-    return;
-  }
-  if (!FLAG_profile) {
-    return;
-  }
-  ASSERT(initialized_);
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    return;
-  }
-  Thread* thread = Thread::Current();
-  thread->SetThreadInterrupter(RecordSampleInterruptCallback, thread);
-  ThreadInterrupter::WakeUp();
-}
-
-
-void Profiler::EndExecution(Isolate* isolate) {
-  if (isolate == NULL) {
-    return;
-  }
-  if (!FLAG_profile) {
-    return;
-  }
-  ASSERT(initialized_);
-  Thread* thread = Thread::Current();
-  thread->SetThreadInterrupter(NULL, NULL);
-}
-
-
-IsolateProfilerData::IsolateProfilerData(SampleBuffer* sample_buffer,
-                                         bool own_sample_buffer) {
-  ASSERT(sample_buffer != NULL);
-  sample_buffer_ = sample_buffer;
-  own_sample_buffer_ = own_sample_buffer;
-  block_count_ = 0;
-}
-
-
-IsolateProfilerData::~IsolateProfilerData() {
-  if (own_sample_buffer_) {
-    delete sample_buffer_;
-    sample_buffer_ = NULL;
-    own_sample_buffer_ = false;
-  }
-}
-
-
-void IsolateProfilerData::Block() {
-  block_count_++;
-}
-
-
-void IsolateProfilerData::Unblock() {
-  block_count_--;
-  if (block_count_ < 0) {
-    FATAL("Too many calls to Dart_IsolateUnblocked.");
-  }
-  if (!blocked()) {
-    // We just unblocked this isolate, wake up the thread interrupter.
-    ThreadInterrupter::WakeUp();
-  }
-}
-
-
 intptr_t Sample::pcs_length_ = 0;
 intptr_t Sample::instance_size_ = 0;
 
@@ -408,6 +296,18 @@
 #endif
 
 
+bool SampleFilter::TimeFilterSample(Sample* sample) {
+  if ((time_origin_micros_ == -1) ||
+      (time_extent_micros_ == -1)) {
+    // No time filter passed in, always pass.
+    return true;
+  }
+  const int64_t timestamp = sample->timestamp();
+  int64_t delta = timestamp - time_origin_micros_;
+  return (delta >= 0) && (delta <= time_extent_micros_);
+}
+
+
 ClearProfileVisitor::ClearProfileVisitor(Isolate* isolate)
     : SampleVisitor(isolate) {
 }
@@ -469,11 +369,12 @@
 // Given an exit frame, walk the Dart stack.
 class ProfilerDartExitStackWalker : public ProfilerStackWalker {
  public:
-  ProfilerDartExitStackWalker(Isolate* isolate,
+  ProfilerDartExitStackWalker(Thread* thread,
+                              Isolate* isolate,
                               Sample* sample,
                               SampleBuffer* sample_buffer)
       : ProfilerStackWalker(isolate, sample, sample_buffer),
-        frame_iterator_(isolate) {
+        frame_iterator_(thread) {
   }
 
   void walk() {
@@ -816,14 +717,13 @@
   if (FLAG_profile_vm) {
     // Always walk the native stack collecting both native and Dart frames.
     native_stack_walker->walk();
-  } else if (exited_dart_code) {
+  } else if (StubCode::HasBeenInitialized() && exited_dart_code) {
     // We have a valid exit frame info, use the Dart stack walker.
     dart_exit_stack_walker->walk();
-  } else if (in_dart_code) {
+  } else if (StubCode::HasBeenInitialized() && in_dart_code) {
     // We are executing Dart code. We have frame pointers.
     dart_stack_walker->walk();
   } else {
-    sample->set_vm_tag(VMTag::kEmbedderTagId);
     sample->SetAt(0, pc);
   }
 
@@ -850,40 +750,27 @@
 }
 
 
-// Is |thread| executing Dart code?
-static bool ExecutingDart(Thread* thread) {
-  ASSERT(thread != NULL);
-  return (thread->top_exit_frame_info() == 0) &&
-         (thread->vm_tag() == VMTag::kDartTagId);
-}
-
-
-// Has |thread| exited Dart code?
-static bool ExitedDart(Thread* thread) {
-  return (thread->top_exit_frame_info() != 0) &&
-         (thread->vm_tag() != VMTag::kDartTagId);
-}
-
-
 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within
 // it. Return |false| if anything looks suspicious.
 static bool GetAndValidateIsolateStackBounds(Thread* thread,
-                                             uintptr_t sp,
                                              uintptr_t fp,
+                                             uintptr_t sp,
                                              uword* stack_lower,
                                              uword* stack_upper) {
   ASSERT(thread != NULL);
-  Isolate* isolate = thread->isolate();
-  ASSERT(isolate != NULL);
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
   ASSERT(stack_lower != NULL);
   ASSERT(stack_upper != NULL);
 #if defined(USING_SIMULATOR)
-  const bool in_dart_code = ExecutingDart(thread);
+  const bool in_dart_code = thread->IsExecutingDartCode();
   if (in_dart_code) {
+    Isolate* isolate = thread->isolate();
+    ASSERT(isolate != NULL);
     Simulator* simulator = isolate->simulator();
     *stack_lower = simulator->StackBase();
     *stack_upper = simulator->StackTop();
-  } else if (!isolate->GetProfilerStackBounds(stack_lower, stack_upper)) {
+  } else if (!os_thread->GetProfilerStackBounds(stack_lower, stack_upper)) {
     // Could not get stack boundary.
     return false;
   }
@@ -891,7 +778,7 @@
     return false;
   }
 #else
-  if (!isolate->GetProfilerStackBounds(stack_lower, stack_upper) ||
+  if (!os_thread->GetProfilerStackBounds(stack_lower, stack_upper) ||
       (*stack_lower == 0) || (*stack_upper == 0)) {
     // Could not get stack boundary.
     return false;
@@ -908,12 +795,12 @@
   }
 
   if ((sp < *stack_lower) || (sp >= *stack_upper)) {
-    // Stack pointer is outside isolate stack boundary.
+    // Stack pointer is outside thread's stack boundary.
     return false;
   }
 
   if ((fp < *stack_lower) || (fp >= *stack_upper)) {
-    // Frame pointer is outside isolate stack boundary.
+    // Frame pointer is outside threads's stack boundary.
     return false;
   }
 
@@ -921,8 +808,8 @@
 }
 
 
-// Some simple sanity checking of |pc|, |sp|, and |fp|.
-static bool InitialRegisterCheck(uintptr_t pc, uintptr_t sp, uintptr_t fp) {
+// Some simple sanity checking of |pc|, |fp|, and |sp|.
+static bool InitialRegisterCheck(uintptr_t pc, uintptr_t fp, uintptr_t sp) {
   if ((sp == 0) || (fp == 0) || (pc == 0)) {
     // None of these registers should be zero.
     return false;
@@ -938,18 +825,6 @@
 }
 
 
-// Return |isolate|'s sample buffer.
-static SampleBuffer* GetSampleBuffer(Isolate* isolate) {
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    // Profiler not initialized.
-    return NULL;
-  }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  return sample_buffer;
-}
-
-
 static Sample* SetupSample(Thread* thread,
                            SampleBuffer* sample_buffer,
                            ThreadId tid) {
@@ -957,7 +832,7 @@
   Isolate* isolate = thread->isolate();
   ASSERT(sample_buffer != NULL);
   Sample* sample = sample_buffer->ReserveSample();
-  sample->Init(isolate, OS::GetCurrentTimeMicros(), tid);
+  sample->Init(isolate, OS::GetCurrentMonotonicMicros(), tid);
   uword vm_tag = thread->vm_tag();
 #if defined(USING_SIMULATOR)
   // When running in the simulator, the runtime entry function address
@@ -979,8 +854,7 @@
     // No isolate.
     return false;
   }
-  ASSERT(isolate != Dart::vm_isolate());
-  return true;
+  return isolate != Dart::vm_isolate();
 }
 
 
@@ -996,16 +870,18 @@
 }
 #endif
 
-void Profiler::RecordAllocation(Thread* thread, intptr_t cid) {
+void Profiler::SampleAllocation(Thread* thread, intptr_t cid) {
   ASSERT(thread != NULL);
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
   Isolate* isolate = thread->isolate();
   if (!CheckIsolate(isolate)) {
     return;
   }
 
-  const bool exited_dart_code = ExitedDart(thread);
+  const bool exited_dart_code = thread->HasExitedDartCode();
 
-  SampleBuffer* sample_buffer = GetSampleBuffer(isolate);
+  SampleBuffer* sample_buffer = Profiler::sample_buffer();
   if (sample_buffer == NULL) {
     // Profiler not initialized.
     return;
@@ -1021,22 +897,20 @@
     uword stack_lower = 0;
     uword stack_upper = 0;
 
-    if (!InitialRegisterCheck(pc, sp, fp)) {
+    if (!InitialRegisterCheck(pc, fp, sp)) {
       return;
     }
 
     if (!GetAndValidateIsolateStackBounds(thread,
-                                          sp,
                                           fp,
+                                          sp,
                                           &stack_lower,
                                           &stack_upper)) {
       // Could not get stack boundary.
       return;
     }
 
-    Sample* sample = SetupSample(thread,
-                                 sample_buffer,
-                                 OSThread::GetCurrentThreadId());
+    Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
     sample->SetAllocationCid(cid);
     ProfilerNativeStackWalker native_stack_walker(isolate,
                                                   sample,
@@ -1048,46 +922,39 @@
                                                   sp);
     native_stack_walker.walk();
   } else if (exited_dart_code) {
-    Sample* sample = SetupSample(thread,
-                                 sample_buffer,
-                                 OSThread::GetCurrentThreadId());
+    Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
     sample->SetAllocationCid(cid);
-    ProfilerDartExitStackWalker dart_exit_stack_walker(isolate,
+    ProfilerDartExitStackWalker dart_exit_stack_walker(thread,
+                                                       isolate,
                                                        sample,
                                                        sample_buffer);
     dart_exit_stack_walker.walk();
   } else {
     // Fall back.
     uintptr_t pc = GetProgramCounter();
-    Sample* sample = SetupSample(thread,
-                                 sample_buffer,
-                                 OSThread::GetCurrentThreadId());
+    Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
     sample->SetAllocationCid(cid);
-    sample->set_vm_tag(VMTag::kEmbedderTagId);
     sample->SetAt(0, pc);
   }
 }
 
 
-void Profiler::RecordSampleInterruptCallback(
-    const InterruptedThreadState& state,
-    void* data) {
-  Thread* thread = reinterpret_cast<Thread*>(data);
+void Profiler::SampleThread(Thread* thread,
+                            const InterruptedThreadState& state) {
+  ASSERT(thread != NULL);
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
   Isolate* isolate = thread->isolate();
-  if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) {
-    // No isolate.
-    return;
-  }
-  ASSERT(isolate != Dart::vm_isolate());
 
-  SampleBuffer* sample_buffer = GetSampleBuffer(isolate);
-  if (sample_buffer == NULL) {
-    // Profiler not initialized.
+  if (StubCode::HasBeenInitialized() &&
+      StubCode::InJumpToExceptionHandlerStub(state.pc)) {
+    // The JumpToExceptionHandler stub manually adjusts the stack pointer,
+    // frame pointer, and some isolate state before jumping to a catch entry.
+    // It is not safe to walk the stack when executing this stub.
     return;
   }
 
-  const bool exited_dart_code = ExitedDart(thread);
-  const bool in_dart_code = ExecutingDart(thread);
+  const bool in_dart_code = thread->IsExecutingDartCode();
 
   uintptr_t sp = 0;
   uintptr_t fp = state.fp;
@@ -1111,22 +978,25 @@
     sp = state.csp;
   }
 
-  if (!InitialRegisterCheck(pc, sp, fp)) {
+  if (!InitialRegisterCheck(pc, fp, sp)) {
     return;
   }
 
-  if (StubCode::InJumpToExceptionHandlerStub(pc)) {
-    // The JumpToExceptionHandler stub manually adjusts the stack pointer,
-    // frame pointer, and some isolate state before jumping to a catch entry.
-    // It is not safe to walk the stack when executing this stub.
+  if (!CheckIsolate(isolate)) {
+    return;
+  }
+
+  if (!thread->IsMutatorThread()) {
+    // Not a mutator thread.
+    // TODO(johnmccutchan): Profile all threads with an isolate.
     return;
   }
 
   uword stack_lower = 0;
   uword stack_upper = 0;
   if (!GetAndValidateIsolateStackBounds(thread,
-                                        sp,
                                         fp,
+                                        sp,
                                         &stack_lower,
                                         &stack_upper)) {
     // Could not get stack boundary.
@@ -1135,11 +1005,14 @@
 
   // At this point we have a valid stack boundary for this isolate and
   // know that our initial stack and frame pointers are within the boundary.
+  SampleBuffer* sample_buffer = Profiler::sample_buffer();
+  if (sample_buffer == NULL) {
+    // Profiler not initialized.
+    return;
+  }
 
   // Setup sample.
-  Sample* sample = SetupSample(thread,
-                               sample_buffer,
-                               OSThread::GetCurrentThreadId());
+  Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
   // Increment counter for vm tag.
   VMTagCounters* counters = isolate->vm_tag_counters();
   ASSERT(counters != NULL);
@@ -1154,7 +1027,8 @@
                                                 fp,
                                                 sp);
 
-  ProfilerDartExitStackWalker dart_exit_stack_walker(isolate,
+  ProfilerDartExitStackWalker dart_exit_stack_walker(thread,
+                                                     isolate,
                                                      sample,
                                                      sample_buffer);
 
@@ -1167,6 +1041,8 @@
                                             fp,
                                             sp);
 
+  const bool exited_dart_code = thread->HasExitedDartCode();
+
   // All memory access is done inside CollectSample.
   CollectSample(isolate,
                 exited_dart_code,
@@ -1181,6 +1057,138 @@
 }
 
 
+
+CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) {
+  ASSERT(!code_.IsNull());
+}
+
+
+uword CodeDescriptor::Entry() const {
+  return code_.EntryPoint();
+}
+
+
+uword CodeDescriptor::Size() const {
+  return code_.Size();
+}
+
+
+int64_t CodeDescriptor::CompileTimestamp() const {
+  return code_.compile_timestamp();
+}
+
+
+CodeLookupTable::CodeLookupTable(Thread* thread) {
+  Build(thread);
+}
+
+
+class CodeLookupTableBuilder : public ObjectVisitor {
+ public:
+  CodeLookupTableBuilder(Isolate* isolate, CodeLookupTable* table)
+      : ObjectVisitor(isolate),
+        table_(table) {
+    ASSERT(table_ != NULL);
+  }
+
+  ~CodeLookupTableBuilder() {
+  }
+
+  void VisitObject(RawObject* raw_obj) {
+    uword tags = raw_obj->ptr()->tags_;
+    if (RawObject::ClassIdTag::decode(tags) == kCodeCid) {
+      RawCode* raw_code = reinterpret_cast<RawCode*>(raw_obj);
+      const Code& code = Code::Handle(raw_code);
+      ASSERT(!code.IsNull());
+      const Instructions& instructions =
+          Instructions::Handle(code.instructions());
+      ASSERT(!instructions.IsNull());
+      table_->Add(code);
+    }
+  }
+
+ private:
+  CodeLookupTable* table_;
+};
+
+
+void CodeLookupTable::Build(Thread* thread) {
+  ASSERT(thread != NULL);
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  Isolate* vm_isolate = Dart::vm_isolate();
+  ASSERT(vm_isolate != NULL);
+
+  // Clear.
+  code_objects_.Clear();
+
+  // Add all found Code objects.
+  CodeLookupTableBuilder cltb(isolate, this);
+  vm_isolate->heap()->IterateOldObjects(&cltb);
+  isolate->heap()->IterateOldObjects(&cltb);
+
+  // Sort by entry.
+  code_objects_.Sort(CodeDescriptor::Compare);
+
+#if defined(DEBUG)
+  if (length() <= 1) {
+    return;
+  }
+  ASSERT(FindCode(0) == NULL);
+  ASSERT(FindCode(~0) == NULL);
+  // Sanity check that we don't have duplicate entries and that the entries
+  // are sorted.
+  for (intptr_t i = 0; i < length() - 1; i++) {
+    const CodeDescriptor* a = At(i);
+    const CodeDescriptor* b = At(i + 1);
+    ASSERT(a->Entry() < b->Entry());
+    ASSERT(FindCode(a->Entry()) == a);
+    ASSERT(FindCode(b->Entry()) == b);
+    ASSERT(FindCode(a->Entry() + a->Size() - 1) == a);
+    ASSERT(FindCode(b->Entry() + b->Size() - 1) == b);
+  }
+#endif
+}
+
+
+void CodeLookupTable::Add(const Code& code) {
+  ASSERT(!code.IsNull());
+  CodeDescriptor* cd = new CodeDescriptor(code);
+  code_objects_.Add(cd);
+}
+
+
+const CodeDescriptor* CodeLookupTable::FindCode(uword pc) const {
+  intptr_t first = 0;
+  intptr_t count = length();
+  while (count > 0) {
+    intptr_t current = first;
+    intptr_t step = count / 2;
+    current += step;
+    const CodeDescriptor* cd = At(current);
+    if (pc >= cd->Entry()) {
+      first = ++current;
+      count -= step + 1;
+    } else {
+      count = step;
+    }
+  }
+  // First points to the first code object whose entry is greater than PC.
+  // That means the code object we need to check is first - 1.
+  if (first == 0) {
+    return NULL;
+  }
+  first--;
+  ASSERT(first >= 0);
+  ASSERT(first < length());
+  const CodeDescriptor* cd = At(first);
+  if (cd->Contains(pc)) {
+    return cd;
+  }
+  return NULL;
+}
+
+
 ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer(
     SampleFilter* filter) {
   ASSERT(filter != NULL);
@@ -1197,9 +1205,9 @@
       continue;
     }
     if (!sample->head_sample()) {
-        // An inner sample in a chain of samples.
-        continue;
-      }
+      // An inner sample in a chain of samples.
+      continue;
+    }
     if (sample->isolate() != filter->isolate()) {
       // Another isolate.
       continue;
@@ -1212,17 +1220,23 @@
       // No frames.
       continue;
     }
+    if (!filter->TimeFilterSample(sample)) {
+      // Did not pass time filter.
+      continue;
+    }
     if (!filter->FilterSample(sample)) {
       // Did not pass filter.
       continue;
     }
-    buffer->Add(BuildProcessedSample(sample));
+    buffer->Add(BuildProcessedSample(sample, buffer->code_lookup_table()));
   }
   return buffer;
 }
 
 
-ProcessedSample* SampleBuffer::BuildProcessedSample(Sample* sample) {
+ProcessedSample* SampleBuffer::BuildProcessedSample(
+    Sample* sample,
+    const CodeLookupTable& clt) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -1230,6 +1244,7 @@
 
   // Copy state bits from sample.
   processed_sample->set_timestamp(sample->timestamp());
+  processed_sample->set_tid(sample->tid());
   processed_sample->set_vm_tag(sample->vm_tag());
   processed_sample->set_user_tag(sample->user_tag());
   if (sample->is_allocation_sample()) {
@@ -1253,9 +1268,7 @@
   }
 
   if (!sample->exit_frame_sample()) {
-    Isolate* vm_isolate = Dart::vm_isolate();
-    processed_sample->FixupCaller(thread,
-                                  vm_isolate,
+    processed_sample->FixupCaller(clt,
                                   sample->pc_marker(),
                                   sample->GetStackBuffer());
   }
@@ -1291,35 +1304,34 @@
       vm_tag_(0),
       user_tag_(0),
       allocation_cid_(-1),
-      truncated_(false) {
+      truncated_(false),
+      timeline_trie_(NULL) {
 }
 
 
-void ProcessedSample::FixupCaller(Thread* thread,
-                                  Isolate* vm_isolate,
+void ProcessedSample::FixupCaller(const CodeLookupTable& clt,
                                   uword pc_marker,
                                   uword* stack_buffer) {
-  REUSABLE_CODE_HANDLESCOPE(thread);
-  // Lookup code object for leaf frame.
-  Code& code = reused_code_handle.Handle();
-  code = FindCodeForPC(thread->isolate(), vm_isolate, At(0));
-  if (code.IsNull()) {
+  const CodeDescriptor* cd = clt.FindCode(At(0));
+  if (cd == NULL) {
+    // No Dart code.
     return;
   }
-  if (code.compile_timestamp() > timestamp()) {
+  if (cd->CompileTimestamp() > timestamp()) {
     // Code compiled after sample. Ignore.
     return;
   }
-  CheckForMissingDartFrame(
-      thread->isolate(), vm_isolate, code, pc_marker, stack_buffer);
+  CheckForMissingDartFrame(clt, cd, pc_marker, stack_buffer);
 }
 
 
-void ProcessedSample::CheckForMissingDartFrame(Isolate* isolate,
-                                               Isolate* vm_isolate,
-                                               const Code& code,
+void ProcessedSample::CheckForMissingDartFrame(const CodeLookupTable& clt,
+                                               const CodeDescriptor* cd,
                                                uword pc_marker,
                                                uword* stack_buffer) {
+  ASSERT(cd != NULL);
+  const Code& code = Code::Handle(cd->code());
+  ASSERT(!code.IsNull());
   // Some stubs (and intrinsics) do not push a frame onto the stack leaving
   // the frame pointer in the caller.
   //
@@ -1336,7 +1348,6 @@
   // the PC marker. We can use the PC marker to insert DART3 into the stack
   // so that it will correctly be: STUB, DART3, DART2, DART1. Note the
   // inserted PC may not accurately reflect the true return address into DART3.
-  ASSERT(!code.IsNull());
 
   // The pc marker is our current best guess of a return address.
   uword return_address = pc_marker;
@@ -1358,8 +1369,8 @@
     }
   }
 
-  if (!ContainedInDartCodeHeaps(isolate, vm_isolate, return_address)) {
-    // return address is not from the Dart heap. Do not insert.
+  if (clt.FindCode(return_address) == NULL) {
+    // Return address is not from a Dart code object. Do not insert.
     return;
   }
 
@@ -1369,32 +1380,9 @@
 }
 
 
-RawCode* ProcessedSample::FindCodeForPC(Isolate* isolate,
-                                        Isolate* vm_isolate,
-                                        uword pc) {
-  // Check current isolate for pc.
-  if (isolate->heap()->CodeContains(pc)) {
-    return Code::LookupCode(pc);
-  }
-
-  // Check VM isolate for pc.
-  if (vm_isolate->heap()->CodeContains(pc)) {
-    return Code::LookupCodeInVmIsolate(pc);
-  }
-
-  return Code::null();
-}
-
-
-bool ProcessedSample::ContainedInDartCodeHeaps(Isolate* isolate,
-                                               Isolate* vm_isolate,
-                                               uword pc) {
-  return vm_isolate->heap()->CodeContains(pc)
-         || isolate->heap()->CodeContains(pc);
-}
-
-
-ProcessedSampleBuffer::ProcessedSampleBuffer() {
+ProcessedSampleBuffer::ProcessedSampleBuffer()
+    : code_lookup_table_(new CodeLookupTable(Thread::Current())) {
+  ASSERT(code_lookup_table_ != NULL);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index ff8e148..c755890 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -10,6 +10,7 @@
 #include "vm/code_observers.h"
 #include "vm/globals.h"
 #include "vm/growable_array.h"
+#include "vm/object.h"
 #include "vm/tags.h"
 #include "vm/thread_interrupter.h"
 
@@ -24,6 +25,7 @@
 
 class Sample;
 class SampleBuffer;
+class ProfileTrieNode;
 
 class Profiler : public AllStatic {
  public:
@@ -33,55 +35,30 @@
   static void SetSampleDepth(intptr_t depth);
   static void SetSamplePeriod(intptr_t period);
 
-  static void InitProfilingForIsolate(Isolate* isolate,
-                                      bool shared_buffer = true);
-  static void ShutdownProfilingForIsolate(Isolate* isolate);
-
-  static void BeginExecution(Isolate* isolate);
-  static void EndExecution(Isolate* isolate);
-
   static SampleBuffer* sample_buffer() {
     return sample_buffer_;
   }
 
-  static void RecordAllocation(Thread* thread, intptr_t cid);
+  static void SampleAllocation(Thread* thread, intptr_t cid);
+
+  // SampleThread is called from inside the signal handler and hence it is very
+  // critical that the implementation of SampleThread does not do any of the
+  // following:
+  //   * Accessing TLS -- Because on Windows the callback will be running in a
+  //                      different thread.
+  //   * Allocating memory -- Because this takes locks which may already be
+  //                          held, resulting in a dead lock.
+  //   * Taking a lock -- See above.
+  static void SampleThread(Thread* thread,
+                           const InterruptedThreadState& state);
 
  private:
   static bool initialized_;
   static Monitor* monitor_;
 
-  static void RecordSampleInterruptCallback(const InterruptedThreadState& state,
-                                            void* data);
-
   static SampleBuffer* sample_buffer_;
-};
 
-
-class IsolateProfilerData {
- public:
-  IsolateProfilerData(SampleBuffer* sample_buffer, bool own_sample_buffer);
-  ~IsolateProfilerData();
-
-  SampleBuffer* sample_buffer() const { return sample_buffer_; }
-
-  void set_sample_buffer(SampleBuffer* sample_buffer) {
-    sample_buffer_ = sample_buffer;
-  }
-
-  bool blocked() const {
-    return block_count_ > 0;
-  }
-
-  void Block();
-
-  void Unblock();
-
- private:
-  SampleBuffer* sample_buffer_;
-  bool own_sample_buffer_;
-  intptr_t block_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(IsolateProfilerData);
+  friend class Thread;
 };
 
 
@@ -114,7 +91,15 @@
 
 class SampleFilter : public ValueObject {
  public:
-  explicit SampleFilter(Isolate* isolate) : isolate_(isolate) { }
+  SampleFilter(Isolate* isolate,
+               int64_t time_origin_micros,
+               int64_t time_extent_micros)
+      : isolate_(isolate),
+        time_origin_micros_(time_origin_micros),
+        time_extent_micros_(time_extent_micros) {
+    ASSERT(time_origin_micros_ >= -1);
+    ASSERT(time_extent_micros_ >= -1);
+  }
   virtual ~SampleFilter() { }
 
   // Override this function.
@@ -127,8 +112,14 @@
     return isolate_;
   }
 
+  // Returns |true| if |sample| passes the time filter.
+  bool TimeFilterSample(Sample* sample);
+
  private:
   Isolate* isolate_;
+
+  int64_t time_origin_micros_;
+  int64_t time_extent_micros_;
 };
 
 
@@ -380,6 +371,84 @@
 };
 
 
+// A Code object descriptor.
+class CodeDescriptor : public ZoneAllocated {
+ public:
+  explicit CodeDescriptor(const Code& code);
+
+  uword Entry() const;
+
+  uword Size() const;
+
+  int64_t CompileTimestamp() const;
+
+  RawCode* code() const {
+    return code_.raw();
+  }
+
+  const char* Name() const {
+    const String& name = String::Handle(code_.Name());
+    return name.ToCString();
+  }
+
+  bool Contains(uword pc) const {
+    uword end = Entry() + Size();
+    return (pc >= Entry()) && (pc < end);
+  }
+
+  static int Compare(CodeDescriptor* const* a,
+                     CodeDescriptor* const* b) {
+    ASSERT(a != NULL);
+    ASSERT(b != NULL);
+
+    uword a_entry = (*a)->Entry();
+    uword b_entry = (*b)->Entry();
+
+    if (a_entry < b_entry) {
+      return -1;
+    } else if (a_entry > b_entry) {
+      return 1;
+    } else {
+      return 0;
+    }
+  }
+
+ private:
+  const Code& code_;
+
+  DISALLOW_COPY_AND_ASSIGN(CodeDescriptor);
+};
+
+
+// Fast lookup of Dart code objects.
+class CodeLookupTable : public ZoneAllocated {
+ public:
+  explicit CodeLookupTable(Thread* thread);
+
+  intptr_t length() const {
+    return code_objects_.length();
+  }
+
+  const CodeDescriptor* At(intptr_t index) const {
+    return code_objects_.At(index);
+  }
+
+  const CodeDescriptor* FindCode(uword pc) const;
+
+ private:
+  void Build(Thread* thread);
+
+  void Add(const Code& code);
+
+  // Code objects sorted by entry.
+  ZoneGrowableArray<CodeDescriptor*> code_objects_;
+
+  friend class CodeLookupTableBuilder;
+
+  DISALLOW_COPY_AND_ASSIGN(CodeLookupTable);
+};
+
+
 // Ring buffer of Samples that is (usually) shared by many isolates.
 class SampleBuffer {
  public:
@@ -436,7 +505,8 @@
   ProcessedSampleBuffer* BuildProcessedSampleBuffer(SampleFilter* filter);
 
  private:
-  ProcessedSample* BuildProcessedSample(Sample* sample);
+  ProcessedSample* BuildProcessedSample(Sample* sample,
+                                        const CodeLookupTable& clt);
   Sample* Next(Sample* sample);
 
   Sample* samples_;
@@ -478,6 +548,9 @@
   int64_t timestamp() const { return timestamp_; }
   void set_timestamp(int64_t timestamp) { timestamp_ = timestamp; }
 
+  ThreadId tid() const { return tid_; }
+  void set_tid(ThreadId tid) { tid_ = tid; }
+
   // The VM tag.
   uword vm_tag() const { return vm_tag_; }
   void set_vm_tag(uword tag) { vm_tag_ = tag; }
@@ -504,33 +577,31 @@
     first_frame_executing_ = first_frame_executing;
   }
 
+  ProfileTrieNode* timeline_trie() const { return timeline_trie_; }
+  void set_timeline_trie(ProfileTrieNode* trie) {
+    ASSERT(timeline_trie_ == NULL);
+    timeline_trie_ = trie;
+  }
+
  private:
-  void FixupCaller(Thread* thread,
-                   Isolate* vm_isolate,
+  void FixupCaller(const CodeLookupTable& clt,
                    uword pc_marker,
                    uword* stack_buffer);
 
-  void CheckForMissingDartFrame(Isolate* isolate,
-                                Isolate* vm_isolate,
-                                const Code& code,
+  void CheckForMissingDartFrame(const CodeLookupTable& clt,
+                                const CodeDescriptor* code,
                                 uword pc_marker,
                                 uword* stack_buffer);
 
-  static RawCode* FindCodeForPC(Isolate* isolate,
-                                Isolate* vm_isolate,
-                                uword pc);
-
-  static bool ContainedInDartCodeHeaps(Isolate* isolate,
-                                       Isolate* vm_isolate,
-                                       uword pc);
-
   ZoneGrowableArray<uword> pcs_;
   int64_t timestamp_;
+  ThreadId tid_;
   uword vm_tag_;
   uword user_tag_;
   intptr_t allocation_cid_;
   bool truncated_;
   bool first_frame_executing_;
+  ProfileTrieNode* timeline_trie_;
 
   friend class SampleBuffer;
   DISALLOW_COPY_AND_ASSIGN(ProcessedSample);
@@ -554,8 +625,13 @@
     return samples_.At(index);
   }
 
+  const CodeLookupTable& code_lookup_table() const {
+    return *code_lookup_table_;
+  }
+
  private:
   ZoneGrowableArray<ProcessedSample*> samples_;
+  CodeLookupTable* code_lookup_table_;
 
   DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer);
 };
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 6419707..17a8a73 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -253,9 +253,9 @@
     name_ = NULL;
   }
   intptr_t len = strlen(name);
-  name_ = Thread::Current()->zone()->Alloc<const char>(len + 1);
-  strncpy(const_cast<char*>(name_), name, len);
-  const_cast<char*>(name_)[len] = '\0';
+  name_ = Thread::Current()->zone()->Alloc<char>(len + 1);
+  strncpy(name_, name, len);
+  name_[len] = '\0';
 }
 
 
@@ -797,7 +797,8 @@
 ProfileTrieNode::ProfileTrieNode(intptr_t table_index)
     : table_index_(table_index),
       count_(0),
-      children_(0) {
+      children_(0),
+      frame_id_(-1) {
   ASSERT(table_index_ >= 0);
 }
 
@@ -984,18 +985,18 @@
     kNumProfileInfoKind,
   };
 
-  ProfileBuilder(Isolate* isolate,
+  ProfileBuilder(Thread* thread,
                  SampleFilter* filter,
                  Profile::TagOrder tag_order,
                  intptr_t extra_tags,
                  Profile* profile)
-      : isolate_(isolate),
+      : thread_(thread),
         vm_isolate_(Dart::vm_isolate()),
         filter_(filter),
         tag_order_(tag_order),
         extra_tags_(extra_tags),
         profile_(profile),
-        deoptimized_code_(new DeoptimizedCodeSet(isolate)),
+        deoptimized_code_(new DeoptimizedCodeSet(thread->isolate())),
         null_code_(Code::ZoneHandle()),
         null_function_(Function::ZoneHandle()),
         tick_functions_(false),
@@ -1051,16 +1052,12 @@
 
   void FilterSamples() {
     ScopeTimer sw("ProfileBuilder::FilterSamples", FLAG_trace_profiler);
-    MutexLocker profiler_data_lock(isolate_->profiler_data_mutex());
-    IsolateProfilerData* profiler_data = isolate_->profiler_data();
-    if (profiler_data == NULL) {
-      return;
-    }
-    SampleBuffer* sample_buffer = profiler_data->sample_buffer();
+    SampleBuffer* sample_buffer = Profiler::sample_buffer();
     if (sample_buffer == NULL) {
       return;
     }
     samples_ = sample_buffer->BuildProcessedSampleBuffer(filter_);
+    profile_->samples_ = samples_;
     profile_->sample_count_ = samples_->length();
   }
 
@@ -1080,6 +1077,27 @@
 
   void BuildCodeTable() {
     ScopeTimer sw("ProfileBuilder::BuildCodeTable", FLAG_trace_profiler);
+
+    Isolate* isolate = thread_->isolate();
+    ASSERT(isolate != NULL);
+
+    // Build the live code table eagerly by populating it with code objects
+    // from the processed sample buffer.
+    const CodeLookupTable& code_lookup_table = samples_->code_lookup_table();
+    for (intptr_t i = 0; i < code_lookup_table.length(); i++) {
+      const CodeDescriptor* descriptor = code_lookup_table.At(i);
+      ASSERT(descriptor != NULL);
+      const Code& code = Code::Handle(descriptor->code());
+      ASSERT(!code.IsNull());
+      RegisterLiveProfileCode(
+          new ProfileCode(ProfileCode::kDartCode,
+                          code.EntryPoint(),
+                          code.EntryPoint() + code.Size(),
+                          code.compile_timestamp(),
+                          code));
+    }
+
+    // Iterate over samples.
     for (intptr_t sample_index = 0;
          sample_index < samples_->length();
          sample_index++) {
@@ -1107,7 +1125,7 @@
            frame_index++) {
         const uword pc = sample->At(frame_index);
         ASSERT(pc != 0);
-        ProfileCode* code = RegisterProfileCode(pc, timestamp);
+        ProfileCode* code = FindOrRegisterProfileCode(pc, timestamp);
         ASSERT(code != NULL);
         code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index);
       }
@@ -1317,6 +1335,8 @@
         ASSERT(sample->At(frame_index) != 0);
         current = ProcessFrame(current, sample_index, sample, frame_index);
       }
+
+      sample->set_timeline_trie(current);
     }
   }
 
@@ -1370,6 +1390,11 @@
     GrowableArray<Function*> inlined_functions;
     if (!code.IsNull()) {
       intptr_t offset = pc - code.EntryPoint();
+      if (frame_index != 0) {
+        // The PC of frames below the top frame is a call's return address,
+        // which can belong to a different inlining interval than the call.
+        offset--;
+      }
       code.GetInlinedFunctionsAt(offset, &inlined_functions);
     }
     if (code.IsNull() || (inlined_functions.length() == 0)) {
@@ -1842,107 +1867,88 @@
     return code;
   }
 
-  ProfileCode* CreateProfileCode(uword pc) {
-    const intptr_t kDartCodeAlignment = OS::PreferredCodeAlignment();
-    const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
-    Code& code = Code::Handle(isolate_->current_zone());
+  bool IsPCInDartHeap(uword pc) {
+    return vm_isolate_->heap()->CodeContains(pc) ||
+           thread_->isolate()->heap()->CodeContains(pc);
+  }
 
-    // Check current isolate for pc.
-    if (isolate_->heap()->CodeContains(pc)) {
-      code ^= Code::LookupCode(pc);
-      if (!code.IsNull()) {
-        deoptimized_code_->Add(code);
-        return new ProfileCode(ProfileCode::kDartCode,
-                              code.EntryPoint(),
-                              code.EntryPoint() + code.Size(),
-                              code.compile_timestamp(),
-                              code);
-      }
-      return new ProfileCode(ProfileCode::kCollectedCode,
-                            pc,
-                            (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
-                            0,
-                            code);
+
+  ProfileCode* FindOrRegisterNativeProfileCode(uword pc) {
+    // Check if |pc| is already known in the live code table.
+    ProfileCodeTable* live_table = profile_->live_code_;
+    ProfileCode* profile_code = live_table->FindCodeForPC(pc);
+    if (profile_code != NULL) {
+      return profile_code;
     }
 
-    // Check VM isolate for pc.
-    if (vm_isolate_->heap()->CodeContains(pc)) {
-      code ^= Code::LookupCodeInVmIsolate(pc);
-      if (!code.IsNull()) {
-        return new ProfileCode(ProfileCode::kDartCode,
-                              code.EntryPoint(),
-                              code.EntryPoint() + code.Size(),
-                              code.compile_timestamp(),
-                              code);
-      }
-      return new ProfileCode(ProfileCode::kCollectedCode,
-                            pc,
-                            (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
-                            0,
-                            code);
-    }
+    // We haven't seen this pc yet.
+    Code& code = Code::Handle(thread_->zone());
 
     // Check NativeSymbolResolver for pc.
     uintptr_t native_start = 0;
     char* native_name = NativeSymbolResolver::LookupSymbolName(pc,
                                                                &native_start);
     if (native_name == NULL) {
-      // No native name found.
-      return new ProfileCode(ProfileCode::kNativeCode,
-                            pc,
-                            pc + 1,
-                            0,
-                            code);
+      // Failed to find a native symbol for pc.
+      native_start = pc;
     }
+
+#if defined(HOST_ARCH_ARM)
+    // The symbol for a Thumb function will be xxx1, but we may have samples
+    // at function entry which will have pc xxx0.
+    native_start &= ~1;
+#endif
+
     ASSERT(pc >= native_start);
-    ProfileCode* profile_code =
-        new ProfileCode(ProfileCode::kNativeCode,
-                       native_start,
-                       pc + 1,
-                       0,
-                       code);
-    profile_code->SetName(native_name);
-    free(native_name);
+    profile_code = new ProfileCode(ProfileCode::kNativeCode,
+                                   native_start,
+                                   pc + 1,
+                                   0,
+                                   code);
+    if (native_name != NULL) {
+      profile_code->SetName(native_name);
+      NativeSymbolResolver::FreeSymbolName(native_name);
+    }
+
+    RegisterLiveProfileCode(profile_code);
     return profile_code;
   }
 
-  ProfileCode* RegisterProfileCode(uword pc, int64_t timestamp) {
+  void RegisterLiveProfileCode(ProfileCode* code) {
     ProfileCodeTable* live_table = profile_->live_code_;
+    intptr_t index = live_table->InsertCode(code);
+    ASSERT(index >= 0);
+  }
+
+  ProfileCode* FindOrRegisterDeadProfileCode(uword pc) {
     ProfileCodeTable* dead_table = profile_->dead_code_;
 
-    ProfileCode* code = live_table->FindCodeForPC(pc);
-    if (code == NULL) {
-      // Code not found.
-      intptr_t index = live_table->InsertCode(CreateProfileCode(pc));
-      ASSERT(index >= 0);
-      code = live_table->At(index);
-      if (code->compile_timestamp() <= timestamp) {
-        // Code was compiled before sample was taken.
-        return code;
-      }
-      // Code was compiled after the sample was taken. Insert code object into
-      // the dead code table.
-      index = dead_table->InsertCode(CreateProfileCodeReused(pc));
-      ASSERT(index >= 0);
-      return dead_table->At(index);
-    }
-    // Existing code found.
-    if (code->compile_timestamp() <= timestamp) {
-      // Code was compiled before sample was taken.
-      return code;
-    }
-    // Code was compiled after the sample was taken. Check if we have an entry
-    // in the dead code table.
-    code = dead_table->FindCodeForPC(pc);
+    ProfileCode* code = dead_table->FindCodeForPC(pc);
     if (code != NULL) {
       return code;
     }
+
     // Create a new dead code entry.
     intptr_t index = dead_table->InsertCode(CreateProfileCodeReused(pc));
     ASSERT(index >= 0);
     return dead_table->At(index);
   }
 
+  ProfileCode* FindOrRegisterProfileCode(uword pc, int64_t timestamp) {
+    ProfileCodeTable* live_table = profile_->live_code_;
+    ProfileCode* code = live_table->FindCodeForPC(pc);
+    if ((code != NULL) && (code->compile_timestamp() <= timestamp)) {
+      // Code was compiled before sample was taken.
+      return code;
+    }
+    if ((code == NULL) && !IsPCInDartHeap(pc)) {
+      // Not a PC from Dart code. Check with native code.
+      return FindOrRegisterNativeProfileCode(pc);
+    }
+    // We either didn't find the code or it was compiled after the sample.
+    return FindOrRegisterDeadProfileCode(pc);
+  }
+
   Profile::TagOrder tag_order() const {
     return tag_order_;
   }
@@ -1957,7 +1963,7 @@
     return (extra_tags_ & extra_tags_bits) != 0;
   }
 
-  Isolate* isolate_;
+  Thread* thread_;
   Isolate* vm_isolate_;
   SampleFilter* filter_;
   Profile::TagOrder tag_order_;
@@ -1971,11 +1977,13 @@
 
   ProcessedSampleBuffer* samples_;
   ProfileInfoKind info_kind_;
-};
+};  // ProfileBuilder.
 
 
 Profile::Profile(Isolate* isolate)
     : isolate_(isolate),
+      zone_(Thread::Current()->zone()),
+      samples_(NULL),
       live_code_(NULL),
       dead_code_(NULL),
       tag_code_(NULL),
@@ -1991,10 +1999,11 @@
 }
 
 
-void Profile::Build(SampleFilter* filter,
+void Profile::Build(Thread* thread,
+                    SampleFilter* filter,
                     TagOrder tag_order,
                     intptr_t extra_tags) {
-  ProfileBuilder builder(isolate_, filter, tag_order, extra_tags, this);
+  ProfileBuilder builder(thread, filter, tag_order, extra_tags, this);
   builder.Build();
 }
 
@@ -2036,16 +2045,90 @@
 }
 
 
-void Profile::PrintJSON(JSONStream* stream) {
-  ScopeTimer sw("Profile::PrintJSON", FLAG_trace_profiler);
+void Profile::PrintHeaderJSON(JSONObject* obj) {
+  obj->AddProperty("samplePeriod",
+                   static_cast<intptr_t>(FLAG_profile_period));
+  obj->AddProperty("stackDepth",
+                   static_cast<intptr_t>(FLAG_max_profile_depth));
+  obj->AddProperty("sampleCount", sample_count());
+  obj->AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
+}
+
+
+void Profile::PrintTimelineFrameJSON(JSONObject* frames,
+                                     ProfileTrieNode* current,
+                                     ProfileTrieNode* parent,
+                                     intptr_t* next_id) {
+  ASSERT(current->frame_id() == -1);
+  const intptr_t id = *next_id;
+  *next_id = id + 1;
+  current->set_frame_id(id);
+  ASSERT(current->frame_id() != -1);
+
+  {
+    // The samples from many isolates may be merged into a single timeline,
+    // so prefix frames id with the isolate.
+    intptr_t isolate_id = reinterpret_cast<intptr_t>(isolate_);
+    const char* key = zone_->PrintToString("%" Pd "-%" Pd,
+                                           isolate_id, current->frame_id());
+    JSONObject frame(frames, key);
+    frame.AddProperty("category", "Dart");
+    ProfileFunction* func = GetFunction(current->table_index());
+    frame.AddProperty("name", func->Name());
+    if (parent != NULL) {
+      ASSERT(parent->frame_id() != -1);
+      frame.AddPropertyF("parent", "%" Pd "-%" Pd,
+                         isolate_id, parent->frame_id());
+    }
+  }
+
+  for (intptr_t i = 0; i < current->NumChildren(); i++) {
+    ProfileTrieNode* child = current->At(i);
+    PrintTimelineFrameJSON(frames, child, current, next_id);
+  }
+}
+
+
+void Profile::PrintTimelineJSON(JSONStream* stream) {
+  ScopeTimer sw("Profile::PrintTimelineJSON", FLAG_trace_profiler);
+  JSONObject obj(stream);
+  obj.AddProperty("type", "_CpuProfileTimeline");
+  PrintHeaderJSON(&obj);
+  {
+    JSONObject frames(&obj, "stackFrames");
+    ProfileTrieNode* root = GetTrieRoot(kInclusiveFunction);
+    intptr_t next_id = 0;
+    PrintTimelineFrameJSON(&frames, root, NULL, &next_id);
+  }
+  {
+    JSONArray events(&obj, "traceEvents");
+    intptr_t pid = OS::ProcessId();
+    intptr_t isolate_id = reinterpret_cast<intptr_t>(isolate_);
+    for (intptr_t sample_index = 0;
+         sample_index < samples_->length();
+         sample_index++) {
+      ProcessedSample* sample = samples_->At(sample_index);
+      JSONObject event(&events);
+      event.AddProperty("ph", "P");  // kind = sample event
+      event.AddProperty64("pid", pid);
+      event.AddProperty64("tid", OSThread::ThreadIdToIntPtr(sample->tid()));
+      event.AddPropertyTimeMicros("ts", sample->timestamp());
+      event.AddProperty("cat", "Dart");
+
+      ProfileTrieNode* trie = sample->timeline_trie();
+      ASSERT(trie->frame_id() != -1);
+      event.AddPropertyF("sf", "%" Pd "-%" Pd,
+                         isolate_id, trie->frame_id());
+    }
+  }
+}
+
+
+void Profile::PrintProfileJSON(JSONStream* stream) {
+  ScopeTimer sw("Profile::PrintProfileJSON", FLAG_trace_profiler);
   JSONObject obj(stream);
   obj.AddProperty("type", "_CpuProfile");
-  obj.AddProperty("samplePeriod",
-                  static_cast<intptr_t>(FLAG_profile_period));
-  obj.AddProperty("stackDepth",
-                  static_cast<intptr_t>(FLAG_max_profile_depth));
-  obj.AddProperty("sampleCount", sample_count());
-  obj.AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
+  PrintHeaderJSON(&obj);
   {
     JSONArray codes(&obj, "codes");
     for (intptr_t i = 0; i < live_code_->length(); i++) {
@@ -2198,37 +2281,40 @@
                                     JSONStream* stream,
                                     Profile::TagOrder tag_order,
                                     intptr_t extra_tags,
-                                    SampleFilter* filter) {
+                                    SampleFilter* filter,
+                                    bool as_timeline) {
   Isolate* isolate = thread->isolate();
-  // Disable profile interrupts while processing the buffer.
-  Profiler::EndExecution(isolate);
+  // Disable thread interrupts while processing the buffer.
+  DisableThreadInterruptsScope dtis(thread);
 
-  {
-    MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
-    IsolateProfilerData* profiler_data = isolate->profiler_data();
-    if (profiler_data == NULL) {
-      stream->PrintError(kFeatureDisabled, NULL);
-      return;
-    }
+  SampleBuffer* sample_buffer = Profiler::sample_buffer();
+  if (sample_buffer == NULL) {
+    stream->PrintError(kFeatureDisabled, NULL);
+    return;
   }
 
   {
     StackZone zone(thread);
     HANDLESCOPE(thread);
     Profile profile(isolate);
-    profile.Build(filter, tag_order, extra_tags);
-    profile.PrintJSON(stream);
+    profile.Build(thread, filter, tag_order, extra_tags);
+    if (as_timeline) {
+      profile.PrintTimelineJSON(stream);
+    } else {
+      profile.PrintProfileJSON(stream);
+    }
   }
-
-  // Enable profile interrupts.
-  Profiler::BeginExecution(isolate);
 }
 
 
 class NoAllocationSampleFilter : public SampleFilter {
  public:
-  explicit NoAllocationSampleFilter(Isolate* isolate)
-      : SampleFilter(isolate) {
+  NoAllocationSampleFilter(Isolate* isolate,
+                           int64_t time_origin_micros,
+                           int64_t time_extent_micros)
+      : SampleFilter(isolate,
+                     time_origin_micros,
+                     time_extent_micros) {
   }
 
   bool FilterSample(Sample* sample) {
@@ -2239,18 +2325,28 @@
 
 void ProfilerService::PrintJSON(JSONStream* stream,
                                 Profile::TagOrder tag_order,
-                                intptr_t extra_tags) {
+                                intptr_t extra_tags,
+                                int64_t time_origin_micros,
+                                int64_t time_extent_micros) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
-  NoAllocationSampleFilter filter(isolate);
-  PrintJSONImpl(thread, stream, tag_order, extra_tags, &filter);
+  NoAllocationSampleFilter filter(isolate,
+                                  time_origin_micros,
+                                  time_extent_micros);
+  const bool as_timeline = false;
+  PrintJSONImpl(thread, stream, tag_order, extra_tags, &filter, as_timeline);
 }
 
 
 class ClassAllocationSampleFilter : public SampleFilter {
  public:
-  ClassAllocationSampleFilter(Isolate* isolate, const Class& cls)
-      : SampleFilter(isolate),
+  ClassAllocationSampleFilter(Isolate* isolate,
+                              const Class& cls,
+                              int64_t time_origin_micros,
+                              int64_t time_extent_micros)
+      : SampleFilter(isolate,
+                     time_origin_micros,
+                     time_extent_micros),
         cls_(Class::Handle(cls.raw())) {
     ASSERT(!cls_.IsNull());
   }
@@ -2267,33 +2363,48 @@
 
 void ProfilerService::PrintAllocationJSON(JSONStream* stream,
                                           Profile::TagOrder tag_order,
-                                          const Class& cls) {
+                                          const Class& cls,
+                                          int64_t time_origin_micros,
+                                          int64_t time_extent_micros) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
-  ClassAllocationSampleFilter filter(isolate, cls);
-  PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter);
+  ClassAllocationSampleFilter filter(isolate,
+                                     cls,
+                                     time_origin_micros,
+                                     time_extent_micros);
+  const bool as_timeline = false;
+  PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline);
+}
+
+
+void ProfilerService::PrintTimelineJSON(JSONStream* stream,
+                                        Profile::TagOrder tag_order,
+                                        int64_t time_origin_micros,
+                                        int64_t time_extent_micros) {
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
+  NoAllocationSampleFilter filter(isolate,
+                                  time_origin_micros,
+                                  time_extent_micros);
+  const bool as_timeline = true;
+  PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline);
 }
 
 
 void ProfilerService::ClearSamples() {
-  Isolate* isolate = Isolate::Current();
-
-  // Disable profile interrupts while processing the buffer.
-  Profiler::EndExecution(isolate);
-
-  MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
+  SampleBuffer* sample_buffer = Profiler::sample_buffer();
+  if (sample_buffer == NULL) {
     return;
   }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  ASSERT(sample_buffer != NULL);
+
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
+
+  // Disable thread interrupts while processing the buffer.
+  DisableThreadInterruptsScope dtis(thread);
 
   ClearProfileVisitor clear_profile(isolate);
   sample_buffer->VisitSamples(&clear_profile);
-
-  // Enable profile interrupts.
-  Profiler::BeginExecution(isolate);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/profiler_service.h b/runtime/vm/profiler_service.h
index 621db01..15f3f7d 100644
--- a/runtime/vm/profiler_service.h
+++ b/runtime/vm/profiler_service.h
@@ -28,6 +28,7 @@
 class RawCode;
 class RawFunction;
 class SampleFilter;
+class ProcessedSampleBuffer;
 
 // Profile data related to a |Function|.
 class ProfileFunction : public ZoneAllocated {
@@ -207,7 +208,7 @@
   intptr_t inclusive_serial_;
 
   const Code& code_;
-  const char* name_;
+  char* name_;
   int64_t compile_timestamp_;
   ProfileFunction* function_;
   intptr_t code_table_index_;
@@ -250,6 +251,12 @@
 
   intptr_t IndexOf(ProfileTrieNode* node);
 
+  intptr_t frame_id() const { return frame_id_; }
+  void set_frame_id(intptr_t id) {
+    ASSERT(frame_id_ == -1);
+    frame_id_ = id;
+  }
+
  protected:
   void SortChildren();
 
@@ -264,6 +271,7 @@
   intptr_t table_index_;
   intptr_t count_;
   ZoneGrowableArray<ProfileTrieNode*> children_;
+  intptr_t frame_id_;
 
   friend class ProfileBuilder;
 };
@@ -300,7 +308,8 @@
   explicit Profile(Isolate* isolate);
 
   // Build a filtered model using |filter| with the specified |tag_order|.
-  void Build(SampleFilter* filter, TagOrder tag_order, intptr_t extra_tags = 0);
+  void Build(Thread* thread,
+             SampleFilter* filter, TagOrder tag_order, intptr_t extra_tags = 0);
 
   // After building:
   int64_t min_time() const { return min_time_; }
@@ -314,10 +323,19 @@
   ProfileCode* GetCode(intptr_t index);
   ProfileTrieNode* GetTrieRoot(TrieKind trie_kind);
 
-  void PrintJSON(JSONStream* stream);
+  void PrintProfileJSON(JSONStream* stream);
+  void PrintTimelineJSON(JSONStream* stream);
 
  private:
+  void PrintHeaderJSON(JSONObject* obj);
+  void PrintTimelineFrameJSON(JSONObject* frames,
+                              ProfileTrieNode* current,
+                              ProfileTrieNode* parent,
+                              intptr_t* next_id);
+
   Isolate* isolate_;
+  Zone* zone_;
+  ProcessedSampleBuffer* samples_;
   ProfileCodeTable* live_code_;
   ProfileCodeTable* dead_code_;
   ProfileCodeTable* tag_code_;
@@ -378,11 +396,20 @@
 
   static void PrintJSON(JSONStream* stream,
                         Profile::TagOrder tag_order,
-                        intptr_t extra_tags);
+                        intptr_t extra_tags,
+                        int64_t time_origin_micros,
+                        int64_t time_extent_micros);
 
   static void PrintAllocationJSON(JSONStream* stream,
                                   Profile::TagOrder tag_order,
-                                  const Class& cls);
+                                  const Class& cls,
+                                  int64_t time_origin_micros,
+                                  int64_t time_extent_micros);
+
+  static void PrintTimelineJSON(JSONStream* stream,
+                                Profile::TagOrder tag_order,
+                                int64_t time_origin_micros,
+                                int64_t time_extent_micros);
 
   static void ClearSamples();
 
@@ -391,7 +418,8 @@
                             JSONStream* stream,
                             Profile::TagOrder tag_order,
                             intptr_t extra_tags,
-                            SampleFilter* filter);
+                            SampleFilter* filter,
+                            bool as_timline);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index bc43d5f..63ac759 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -13,6 +13,7 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, background_compilation);
 DECLARE_FLAG(bool, profile_vm);
 DECLARE_FLAG(int, max_profile_depth);
 
@@ -33,6 +34,22 @@
 };
 
 
+class DisableBackgroundCompilationScope : public ValueObject {
+ public:
+  DisableBackgroundCompilationScope()
+      : FLAG_background_compilation_(FLAG_background_compilation) {
+    FLAG_background_compilation = false;
+  }
+
+  ~DisableBackgroundCompilationScope() {
+    FLAG_background_compilation = FLAG_background_compilation_;
+  }
+
+ private:
+  const bool FLAG_background_compilation_;
+};
+
+
 // Temporarily adjust the maximum profile depth.
 class MaxProfileDepthScope : public ValueObject {
  public:
@@ -138,6 +155,7 @@
   delete sample_buffer;
 }
 
+
 static RawClass* GetClass(const Library& lib, const char* name) {
   const Class& cls = Class::Handle(
       lib.LookupClassAllowPrivate(String::Handle(Symbols::New(name))));
@@ -146,17 +164,30 @@
 }
 
 
+static RawFunction* GetFunction(const Library& lib, const char* name) {
+  const Function& func = Function::Handle(
+      lib.LookupFunctionAllowPrivate(String::Handle(Symbols::New(name))));
+  EXPECT(!func.IsNull());  // No ambiguity error expected.
+  return func.raw();
+}
+
+
 class AllocationFilter : public SampleFilter {
  public:
-  explicit AllocationFilter(Isolate* isolate, intptr_t cid)
-      : SampleFilter(isolate),
+  AllocationFilter(Isolate* isolate,
+                   intptr_t cid,
+                   int64_t time_origin_micros = -1,
+                   int64_t time_extent_micros = -1)
+      : SampleFilter(isolate,
+                     time_origin_micros,
+                     time_extent_micros),
         cid_(cid),
-        enable_embedder_ticks_(false) {
+        enable_vm_ticks_(false) {
   }
 
   bool FilterSample(Sample* sample) {
-    if (!enable_embedder_ticks_ &&
-        (sample->vm_tag() == VMTag::kEmbedderTagId)) {
+    if (!enable_vm_ticks_ &&
+        (sample->vm_tag() == VMTag::kVMTagId)) {
       // We don't want to see embedder ticks in the test.
       return false;
     }
@@ -164,13 +195,13 @@
            (sample->allocation_cid() == cid_);
   }
 
-  void set_enable_embedder_ticks(bool enable) {
-    enable_embedder_ticks_ = enable;
+  void set_enable_vm_ticks(bool enable) {
+    enable_vm_ticks_ = enable;
   }
 
  private:
   intptr_t cid_;
-  bool enable_embedder_ticks_;
+  bool enable_vm_ticks_;
 };
 
 
@@ -195,6 +226,7 @@
   Library& root_library = Library::Handle();
   root_library ^= Api::UnwrapHandle(lib);
 
+  const int64_t before_allocations_micros = Dart_TimelineGetMicros();
   const Class& class_a = Class::Handle(GetClass(root_library, "A"));
   EXPECT(!class_a.IsNull());
   class_a.SetTraceAllocation(true);
@@ -202,15 +234,21 @@
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
   EXPECT_VALID(result);
 
-
+  const int64_t after_allocations_micros = Dart_TimelineGetMicros();
+  const int64_t allocation_extent_micros =
+      after_allocations_micros - before_allocations_micros;
   {
     Thread* thread = Thread::Current();
     Isolate* isolate = thread->isolate();
     StackZone zone(thread);
     HANDLESCOPE(thread);
     Profile profile(isolate);
-    AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    // Filter for the class in the time range.
+    AllocationFilter filter(isolate,
+                            class_a.id(),
+                            before_allocations_micros,
+                            allocation_extent_micros);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have 1 allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -251,6 +289,23 @@
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(!walker.Down());
   }
+
+  // Query with a time filter where no allocations occurred.
+  {
+    Thread* thread = Thread::Current();
+    Isolate* isolate = thread->isolate();
+    StackZone zone(thread);
+    HANDLESCOPE(thread);
+    Profile profile(isolate);
+    AllocationFilter filter(isolate,
+                            class_a.id(),
+                            Dart_TimelineGetMicros(),
+                            16000);
+    profile.Build(thread, &filter, Profile::kNoTags);
+    // We should have no allocation samples because none occured within
+    // the specified time range.
+    EXPECT_EQ(0, profile.sample_count());
+  }
 }
 
 
@@ -289,7 +344,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -307,7 +362,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -362,7 +417,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -403,7 +458,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -426,7 +481,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have three allocation samples.
     EXPECT_EQ(3, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -498,7 +553,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -521,7 +576,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have three allocation samples.
     EXPECT_EQ(3, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -582,7 +637,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, double_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -596,7 +651,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, double_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -620,7 +675,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, double_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -650,7 +705,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, array_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -664,7 +719,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, array_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -688,7 +743,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, array_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -712,7 +767,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, array_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -757,7 +812,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, context_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -771,7 +826,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, context_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -791,7 +846,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, context_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -834,8 +889,8 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_class.id());
-    filter.set_enable_embedder_ticks(true);
-    profile.Build(&filter, Profile::kNoTags);
+    filter.set_enable_vm_ticks(true);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -846,7 +901,7 @@
     // TODO(johnmccutchan): Hookup native symbol resolver on Windows.
     EXPECT_SUBSTRING("[Native]", walker.CurrentName());
 #else
-    EXPECT_SUBSTRING("dart::Profiler::RecordAllocation", walker.CurrentName());
+    EXPECT_SUBSTRING("dart::Profiler::SampleAllocation", walker.CurrentName());
 #endif
     EXPECT(!walker.Down());
   }
@@ -863,8 +918,8 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_class.id());
-    filter.set_enable_embedder_ticks(true);
-    profile.Build(&filter, Profile::kNoTags);
+    filter.set_enable_vm_ticks(true);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -897,7 +952,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, float32_list_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -911,7 +966,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, float32_list_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -937,7 +992,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, float32_list_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -951,7 +1006,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, float32_list_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should now have two allocation samples.
     EXPECT_EQ(2, profile.sample_count());
   }
@@ -981,7 +1036,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -995,7 +1050,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -1017,7 +1072,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -1031,7 +1086,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should now have two allocation samples.
     EXPECT_EQ(2, profile.sample_count());
   }
@@ -1061,7 +1116,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -1075,7 +1130,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -1101,7 +1156,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
     EXPECT_EQ(1, profile.sample_count());
   }
@@ -1115,7 +1170,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, one_byte_string_class.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should now have two allocation samples.
     EXPECT_EQ(2, profile.sample_count());
   }
@@ -1124,6 +1179,8 @@
 
 TEST_CASE(Profiler_FunctionInline) {
   DisableNativeProfileScope dnps;
+  DisableBackgroundCompilationScope dbcs;
+
   const char* kScript =
       "class A {\n"
       "  var a;\n"
@@ -1173,7 +1230,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have no allocation samples.
     EXPECT_EQ(0, profile.sample_count());
   }
@@ -1192,7 +1249,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have 50,000 allocation samples.
     EXPECT_EQ(50000, profile.sample_count());
     ProfileTrieWalker walker(&profile);
@@ -1294,7 +1351,8 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter,
+    profile.Build(thread,
+                  &filter,
                   Profile::kNoTags,
                   ProfilerService::kCodeTransitionTagsBit);
     // We should have 50,000 allocation samples.
@@ -1368,6 +1426,133 @@
 }
 
 
+TEST_CASE(Profiler_InliningIntervalBoundry) {
+  // The PC of frames below the top frame is a call's return address,
+  // which can belong to a different inlining interval than the call.
+  // This test checks the profiler service takes this into account; see
+  // ProfileBuilder::ProcessFrame.
+
+  DisableNativeProfileScope dnps;
+  DisableBackgroundCompilationScope dbcs;
+  const char* kScript =
+      "class A {\n"
+      "}\n"
+      "bool alloc = false;"
+      "maybeAlloc() {\n"
+      "  try {\n"
+      "    if (alloc) new A();\n"
+      "  } catch (e) {\n"
+      "  }\n"
+      "}\n"
+      "right() => maybeAlloc();\n"
+      "doNothing() {\n"
+      "  try {\n"
+      "  } catch (e) {\n"
+      "  }\n"
+      "}\n"
+      "wrong() => doNothing();\n"
+      "a() {\n"
+      "  try {\n"
+      "    right();\n"
+      "    wrong();\n"
+      "  } catch (e) {\n"
+      "  }\n"
+      "}\n"
+      "mainNoAlloc() {\n"
+      "  for (var i = 0; i < 20000; i++) {\n"
+      "    a();\n"
+      "  }\n"
+      "}\n"
+      "mainAlloc() {\n"
+      "  alloc = true;\n"
+      "  a();\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  Library& root_library = Library::Handle();
+  root_library ^= Api::UnwrapHandle(lib);
+
+  const Class& class_a = Class::Handle(GetClass(root_library, "A"));
+  EXPECT(!class_a.IsNull());
+
+  // Compile and optimize.
+  Dart_Handle result = Dart_Invoke(lib, NewString("mainNoAlloc"), 0, NULL);
+  EXPECT_VALID(result);
+  result = Dart_Invoke(lib, NewString("mainAlloc"), 0, NULL);
+  EXPECT_VALID(result);
+
+  // At this point a should be optimized and have inlined both right and wrong,
+  // but not maybeAllocate or doNothing.
+  Function& func = Function::Handle();
+  func = GetFunction(root_library, "a");
+  EXPECT(!func.is_inlinable());
+  EXPECT(func.HasOptimizedCode());
+  func = GetFunction(root_library, "right");
+  EXPECT(func.is_inlinable());
+  func = GetFunction(root_library, "wrong");
+  EXPECT(func.is_inlinable());
+  func = GetFunction(root_library, "doNothing");
+  EXPECT(!func.is_inlinable());
+  func = GetFunction(root_library, "maybeAlloc");
+  EXPECT(!func.is_inlinable());
+
+  {
+    Thread* thread = Thread::Current();
+    Isolate* isolate = thread->isolate();
+    StackZone zone(thread);
+    HANDLESCOPE(thread);
+    Profile profile(isolate);
+    AllocationFilter filter(isolate, class_a.id());
+    profile.Build(thread, &filter, Profile::kNoTags);
+    // We should have no allocation samples.
+    EXPECT_EQ(0, profile.sample_count());
+  }
+
+  // Turn on allocation tracing for A.
+  class_a.SetTraceAllocation(true);
+
+  result = Dart_Invoke(lib, NewString("mainAlloc"), 0, NULL);
+  EXPECT_VALID(result);
+
+  {
+    Thread* thread = Thread::Current();
+    Isolate* isolate = thread->isolate();
+    StackZone zone(thread);
+    HANDLESCOPE(thread);
+    Profile profile(isolate);
+    AllocationFilter filter(isolate, class_a.id());
+    profile.Build(thread, &filter, Profile::kNoTags);
+    EXPECT_EQ(1, profile.sample_count());
+    ProfileTrieWalker walker(&profile);
+
+    // Inline expansion should show us the complete call chain:
+    walker.Reset(Profile::kExclusiveFunction);
+    EXPECT(walker.Down());
+    EXPECT_STREQ("maybeAlloc", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("right", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("a", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("mainAlloc", walker.CurrentName());
+    EXPECT(!walker.Down());
+
+    // Inline expansion should show us the complete call chain:
+    walker.Reset(Profile::kInclusiveFunction);
+    EXPECT(walker.Down());
+    EXPECT_STREQ("mainAlloc", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("a", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("right", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("maybeAlloc", walker.CurrentName());
+    EXPECT(!walker.Down());
+  }
+}
+
+
 TEST_CASE(Profiler_ChainedSamples) {
   MaxProfileDepthScope mpds(32);
   DisableNativeProfileScope dnps;
@@ -1426,7 +1611,7 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     AllocationFilter filter(isolate, class_a.id());
-    profile.Build(&filter, Profile::kNoTags);
+    profile.Build(thread, &filter, Profile::kNoTags);
     // We should have 1 allocation sample.
     EXPECT_EQ(1, profile.sample_count());
     ProfileTrieWalker walker(&profile);
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 47fa009..ba53d37 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -165,7 +165,7 @@
       break;
     }
     case kFreeListElement: {
-      uword addr = RawObject::ToAddr(const_cast<RawObject*>(this));
+      uword addr = RawObject::ToAddr(this);
       FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
       instance_size = element->Size();
       break;
@@ -277,7 +277,7 @@
       }
 #undef RAW_VISITPOINTERS
       case kFreeListElement: {
-        uword addr = RawObject::ToAddr(const_cast<RawObject*>(this));
+        uword addr = RawObject::ToAddr(this);
         FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
         size = element->Size();
         break;
@@ -303,7 +303,7 @@
 
 bool RawObject::FindObject(FindObjectVisitor* visitor) {
   ASSERT(visitor != NULL);
-  return visitor->FindObject(const_cast<RawObject*>(this));
+  return visitor->FindObject(this);
 }
 
 
@@ -556,9 +556,6 @@
 intptr_t RawInstructions::VisitInstructionsPointers(
     RawInstructions* raw_obj, ObjectPointerVisitor* visitor) {
   RawInstructions* obj = raw_obj->ptr();
-  if (!Dart::IsRunningPrecompiledCode()) {
-    visitor->VisitPointers(raw_obj->from(), raw_obj->to());
-  }
   return Instructions::InstanceSize(obj->size_);
 }
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index bc68552..ee5450d 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -614,6 +614,7 @@
   friend class Scavenger;
   friend class ScavengerVisitor;
   friend class SizeExcludingClassVisitor;  // GetClassId
+  friend class InstanceAccumulator;  // GetClassId
   friend class RetainingPathVisitor;  // GetClassId
   friend class SkippedCodeFunctions;  // StorePointer
   friend class InstructionsReader;  // tags_ check
@@ -626,6 +627,7 @@
   friend class WeakProperty;  // StorePointer
   friend class Instance;  // StorePointer
   friend class StackFrame;  // GetCodeObject assertion.
+  friend class CodeLookupTableBuilder;  // profiler
 
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(RawObject);
@@ -650,7 +652,6 @@
   RawArray* functions_hash_table_;
   RawArray* fields_;
   RawArray* offset_in_words_to_field_;
-  RawGrowableObjectArray* closure_functions_;  // Local functions and literals.
   RawArray* interfaces_;  // Array of AbstractType.
   RawGrowableObjectArray* direct_subclasses_;  // Array of Class.
   RawScript* script_;
@@ -658,7 +659,6 @@
   RawTypeArguments* type_parameters_;  // Array of TypeParameter.
   RawAbstractType* super_type_;
   RawType* mixin_;  // Generic mixin type, e.g. M<T>, not M<int>.
-  RawClass* patch_class_;
   RawFunction* signature_function_;  // Associated function for signature class.
   RawArray* constants_;  // Canonicalized values of this class.
   RawObject* canonical_types_;  // An array of canonicalized types of this class
@@ -741,9 +741,10 @@
     return reinterpret_cast<RawObject**>(&ptr()->patched_class_);
   }
   RawClass* patched_class_;
-  RawClass* source_class_;
+  RawClass* origin_class_;
+  RawScript* script_;
   RawObject** to() {
-    return reinterpret_cast<RawObject**>(&ptr()->source_class_);
+    return reinterpret_cast<RawObject**>(&ptr()->script_);
   }
 
   friend class Function;
@@ -867,7 +868,6 @@
     RawInstance* static_value_;  // Value for static fields.
     RawSmi* offset_;  // Offset in words for instance fields.
   } value_;
-  RawArray* dependent_code_;
   union {
     // When precompiling we need to save the static initializer function here
     // so that code for it can be generated.
@@ -877,6 +877,10 @@
     // restore the value back to the original initial value.
     RawInstance* saved_value_;  // Saved initial value - static fields.
   } initializer_;
+  RawObject** to_precompiled_snapshot() {
+    return reinterpret_cast<RawObject**>(&ptr()->initializer_);
+  }
+  RawArray* dependent_code_;
   RawSmi* guarded_list_length_;
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->guarded_list_length_);
@@ -919,7 +923,7 @@
     return reinterpret_cast<RawObject**>(&ptr()->private_key_);
   }
   RawString* private_key_;  // Key used for private identifiers.
-  RawArray* token_objects_;
+  RawGrowableObjectArray* token_objects_;
   RawExternalTypedData* stream_;
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->stream_);
@@ -944,6 +948,9 @@
 
   RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->url_); }
   RawString* url_;
+  RawObject** to_precompiled_snapshot() {
+    return reinterpret_cast<RawObject**>(&ptr()->url_);
+  }
   RawTokenStream* tokens_;
   RawObject** to_snapshot() {
     return reinterpret_cast<RawObject**>(&ptr()->tokens_);
@@ -975,7 +982,8 @@
   RawString* private_key_;
   RawArray* dictionary_;         // Top-level names in this library.
   RawGrowableObjectArray* metadata_;  // Metadata on classes, methods etc.
-  RawArray* anonymous_classes_;  // Classes containing top-level elements.
+  RawClass* toplevel_class_;  // Class containing top-level elements.
+  RawGrowableObjectArray* patch_classes_;
   RawArray* imports_;            // List of Namespaces imported without prefix.
   RawArray* exports_;            // List of re-exported Namespaces.
   RawInstance* load_error_;      // Error iff load_state_ == kLoadError.
@@ -991,7 +999,6 @@
   Dart_NativeEntryResolver native_entry_resolver_;  // Resolves natives.
   Dart_NativeEntrySymbol native_entry_symbol_resolver_;
   classid_t index_;             // Library id number.
-  classid_t num_anonymous_;     // Number of entries in anonymous_classes_.
   uint16_t num_imports_;        // Number of entries in imports_.
   int8_t load_state_;           // Of type LibraryState.
   bool corelib_imported_;
@@ -1045,9 +1052,12 @@
   RawObject* owner_;  // Function, Null, or a Class.
   RawExceptionHandlers* exception_handlers_;
   RawPcDescriptors* pc_descriptors_;
+  RawArray* stackmaps_;
+  RawObject** to_snapshot() {
+    return reinterpret_cast<RawObject**>(&ptr()->stackmaps_);
+  }
   RawArray* deopt_info_array_;
   RawArray* static_calls_target_table_;  // (code-offset, function, code).
-  RawArray* stackmaps_;
   RawLocalVarDescriptors* var_descriptors_;
   RawArray* inlined_metadata_;
   RawArray* comments_;
@@ -1109,14 +1119,6 @@
 class RawInstructions : public RawObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Instructions);
 
-  RawObject** from() {
-    return reinterpret_cast<RawObject**>(&ptr()->code_);
-  }
-  RawCode* code_;
-  RawObject** to() {
-    return reinterpret_cast<RawObject**>(&ptr()->code_);
-  }
-
   int32_t size_;
 
   // Variable length data follows here.
@@ -1400,10 +1402,10 @@
   RawObject** from() {
     return reinterpret_cast<RawObject**>(&ptr()->owner_);
   }
-  RawFunction* owner_;         // Parent/calling function of this IC.
-  RawString* target_name_;     // Name of target function.
+  RawObject* owner_;  // Parent/calling function or original IC of cloned IC.
+  RawString* target_name_;  // Name of target function.
   RawArray* args_descriptor_;  // Arguments descriptor.
-  RawArray* ic_data_;          // Contains class-ids, target and count.
+  RawArray* ic_data_;  // Contains class-ids, target and count.
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->ic_data_);
   }
@@ -1421,8 +1423,10 @@
   }
   RawArray* buckets_;
   RawSmi* mask_;
+  RawString* target_name_;     // Name of target function.
+  RawArray* args_descriptor_;  // Arguments descriptor.
   RawObject** to() {
-    return reinterpret_cast<RawObject**>(&ptr()->mask_);
+    return reinterpret_cast<RawObject**>(&ptr()->args_descriptor_);
   }
 
   int32_t filled_entry_count_;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 8a65fdb..87305ba 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -13,6 +13,7 @@
 namespace dart {
 
 DECLARE_FLAG(int, optimization_counter_threshold);
+DECLARE_FLAG(bool, use_field_guards);
 
 #define NEW_OBJECT(type)                                                       \
   ((kind == Snapshot::kFull) ? reader->New##type() : type::New())
@@ -81,7 +82,6 @@
 
     // Set all the object fields.
     READ_OBJECT_FIELDS(cls, cls.raw()->from(), cls.raw()->to(), kAsReference);
-
     ASSERT(!cls.IsInFullSnapshot() || (kind == Snapshot::kFull));
   } else {
     cls ^= reader->ReadClassId(object_id);
@@ -668,13 +668,20 @@
     // Set all the non object fields.
     func.set_token_pos(reader->Read<int32_t>());
     func.set_end_token_pos(reader->Read<int32_t>());
-    func.set_usage_counter(reader->Read<int32_t>());
     func.set_num_fixed_parameters(reader->Read<int16_t>());
     func.set_num_optional_parameters(reader->Read<int16_t>());
-    func.set_deoptimization_counter(reader->Read<int16_t>());
     func.set_kind_tag(reader->Read<uint32_t>());
-    func.set_optimized_instruction_count(reader->Read<uint16_t>());
-    func.set_optimized_call_site_count(reader->Read<uint16_t>());
+    if (reader->snapshot_code()) {
+      func.set_usage_counter(0);
+      func.set_deoptimization_counter(0);
+      func.set_optimized_instruction_count(0);
+      func.set_optimized_call_site_count(0);
+    } else {
+      func.set_usage_counter(reader->Read<int32_t>());
+      func.set_deoptimization_counter(reader->Read<int16_t>());
+      func.set_optimized_instruction_count(reader->Read<uint16_t>());
+      func.set_optimized_call_site_count(reader->Read<uint16_t>());
+    }
 
     // Set all the object fields.
     READ_OBJECT_FIELDS(func,
@@ -741,17 +748,21 @@
     // Write out all the non object fields.
     writer->Write<int32_t>(ptr()->token_pos_);
     writer->Write<int32_t>(ptr()->end_token_pos_);
-    if (is_optimized) {
-      writer->Write<int32_t>(FLAG_optimization_counter_threshold);
-    } else {
-      writer->Write<int32_t>(0);
-    }
     writer->Write<int16_t>(ptr()->num_fixed_parameters_);
     writer->Write<int16_t>(ptr()->num_optional_parameters_);
-    writer->Write<int16_t>(ptr()->deoptimization_counter_);
     writer->Write<uint32_t>(ptr()->kind_tag_);
-    writer->Write<uint16_t>(ptr()->optimized_instruction_count_);
-    writer->Write<uint16_t>(ptr()->optimized_call_site_count_);
+    if (writer->snapshot_code()) {
+      // Omit fields used to support de/reoptimization.
+    } else {
+      if (is_optimized) {
+        writer->Write<int32_t>(FLAG_optimization_counter_threshold);
+      } else {
+        writer->Write<int32_t>(0);
+      }
+      writer->Write<int16_t>(ptr()->deoptimization_counter_);
+      writer->Write<uint16_t>(ptr()->optimized_instruction_count_);
+      writer->Write<uint16_t>(ptr()->optimized_call_site_count_);
+    }
 
     // Write out all the object pointer fields.
     SnapshotWriterVisitor visitor(writer, kAsReference);
@@ -786,17 +797,33 @@
   reader->AddBackRef(object_id, &field, kIsDeserialized);
 
   // Set all non object fields.
-  field.set_token_pos(reader->Read<int32_t>());
-  field.set_guarded_cid(reader->Read<int32_t>());
-  field.set_is_nullable(reader->Read<int32_t>());
+  if (reader->snapshot_code()) {
+    field.set_token_pos(0);
+    ASSERT(!FLAG_use_field_guards);
+    field.set_guarded_cid(kDynamicCid);
+    field.set_is_nullable(true);
+  } else {
+    field.set_token_pos(reader->Read<int32_t>());
+    field.set_guarded_cid(reader->Read<int32_t>());
+    field.set_is_nullable(reader->Read<int32_t>());
+  }
   field.set_kind_bits(reader->Read<uint8_t>());
 
   // Set all the object fields.
+  RawObject** toobj = reader->snapshot_code()
+      ? field.raw()->to_precompiled_snapshot()
+      : field.raw()->to();
   READ_OBJECT_FIELDS(field,
-                     field.raw()->from(), field.raw()->to(),
+                     field.raw()->from(), toobj,
                      kAsReference);
 
-  field.InitializeGuardedListLengthInObjectOffset();
+  if (reader->snapshot_code()) {
+    ASSERT(!FLAG_use_field_guards);
+    field.set_guarded_list_length(Field::kNoFixedLength);
+    field.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
+  } else {
+    field.InitializeGuardedListLengthInObjectOffset();
+  }
 
   return field.raw();
 }
@@ -817,9 +844,11 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object fields.
-  writer->Write<int32_t>(ptr()->token_pos_);
-  writer->Write<int32_t>(ptr()->guarded_cid_);
-  writer->Write<int32_t>(ptr()->is_nullable_);
+  if (!writer->snapshot_code()) {
+    writer->Write<int32_t>(ptr()->token_pos_);
+    writer->Write<int32_t>(ptr()->guarded_cid_);
+    writer->Write<int32_t>(ptr()->is_nullable_);
+  }
   writer->Write<uint8_t>(ptr()->kind_bits_);
 
   // Write out the name.
@@ -841,16 +870,18 @@
   } else {
     writer->WriteObjectImpl(ptr()->value_.offset_, kAsReference);
   }
-  // Write out the dependent code.
-  writer->WriteObjectImpl(ptr()->dependent_code_, kAsReference);
   // Write out the initializer function or saved initial value.
   if (writer->snapshot_code()) {
     writer->WriteObjectImpl(ptr()->initializer_.precompiled_, kAsReference);
   } else {
     writer->WriteObjectImpl(ptr()->initializer_.saved_value_, kAsReference);
   }
-  // Write out the guarded list length.
-  writer->WriteObjectImpl(ptr()->guarded_list_length_, kAsReference);
+  if (!writer->snapshot_code()) {
+    // Write out the dependent code.
+    writer->WriteObjectImpl(ptr()->dependent_code_, kAsReference);
+    // Write out the guarded list length.
+    writer->WriteObjectImpl(ptr()->guarded_list_length_, kAsReference);
+  }
 }
 
 
@@ -984,18 +1015,23 @@
   script.StoreNonPointer(&script.raw_ptr()->kind_,
                          reader->Read<int8_t>());
 
+  *reader->StringHandle() ^= String::null();
+  script.set_source(*reader->StringHandle());
+  *reader->StreamHandle() ^= TokenStream::null();
+  script.set_tokens(*reader->StreamHandle());
+
   // Set all the object fields.
   // TODO(5411462): Need to assert No GC can happen here, even though
   // allocations may happen.
-  intptr_t num_flds = (script.raw()->to_snapshot() - script.raw()->from());
+  RawObject** toobj = reader->snapshot_code()
+      ? script.raw()->to_precompiled_snapshot()
+      : script.raw()->to_snapshot();
+  intptr_t num_flds = (toobj - script.raw()->from());
   for (intptr_t i = 0; i <= num_flds; i++) {
     (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
     script.StorePointer((script.raw()->from() + i),
                         reader->PassiveObjectHandle()->raw());
   }
-  // Script wasn't allocated with nulls?
-  *reader->StringHandle() ^= String::null();
-  script.set_source(*reader->StringHandle());
 
   return script.raw();
 }
@@ -1023,7 +1059,9 @@
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to_snapshot());
+  RawObject** toobj = writer->snapshot_code() ? to_precompiled_snapshot()
+                                              : to_snapshot();
+  visitor.VisitPointers(from(), toobj);
 }
 
 
@@ -1051,8 +1089,6 @@
     // Set all non object fields.
     library.StoreNonPointer(&library.raw_ptr()->index_,
                             reader->ReadClassIDValue());
-    library.StoreNonPointer(&library.raw_ptr()->num_anonymous_,
-                            reader->ReadClassIDValue());
     library.StoreNonPointer(&library.raw_ptr()->num_imports_,
                             reader->Read<uint16_t>());
     library.StoreNonPointer(&library.raw_ptr()->load_state_,
@@ -1122,7 +1158,6 @@
     ASSERT((kind == Snapshot::kFull) || !ptr()->is_in_fullsnapshot_);
     // Write out all non object fields.
     writer->WriteClassIDValue(ptr()->index_);
-    writer->WriteClassIDValue(ptr()->num_anonymous_);
     writer->Write<uint16_t>(ptr()->num_imports_);
     writer->Write<int8_t>(ptr()->load_state_);
     writer->Write<bool>(ptr()->corelib_imported_);
@@ -1247,14 +1282,19 @@
   Code& result = Code::ZoneHandle(reader->zone(), NEW_OBJECT_WITH_LEN(Code, 0));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
 
-  result.set_compile_timestamp(reader->Read<int64_t>());
+  result.set_compile_timestamp(0);
   result.set_state_bits(reader->Read<int32_t>());
-  result.set_lazy_deopt_pc_offset(reader->Read<int32_t>());
+  result.set_lazy_deopt_pc_offset(-1);
 
   // Set all the object fields.
   READ_OBJECT_FIELDS(result,
-                     result.raw()->from(), result.raw()->to(),
+                     result.raw()->from(), result.raw()->to_snapshot(),
                      kAsReference);
+  for (RawObject** ptr = result.raw()->to();
+       ptr > result.raw()->to_snapshot();
+       ptr--) {
+    result.StorePointer(ptr, Object::null());
+  }
 
   // Fix entry point.
   uword new_entry = result.EntryPoint();
@@ -1276,7 +1316,7 @@
       Code::PtrOffBits::decode(ptr()->state_bits_);
   if (pointer_offsets_length != 0) {
     // Should only be IA32.
-    FATAL("Serializing embedded pointer offsets unimplemented");
+    FATAL("Cannot serialize code with embedded pointers");
   }
 
   // Write out the serialization header value for this object.
@@ -1287,13 +1327,11 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object fields.
-  writer->Write<int64_t>(ptr()->compile_timestamp_);
   writer->Write<int32_t>(ptr()->state_bits_);
-  writer->Write<int32_t>(ptr()->lazy_deopt_pc_offset_);
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
+  visitor.VisitPointers(from(), to_snapshot());
 
   writer->SetInstructionsCode(ptr()->instructions_, this);
 }
@@ -1349,49 +1387,54 @@
   ASSERT(reader->snapshot_code());
   ASSERT(kind == Snapshot::kFull);
 
-  intptr_t length = reader->Read<intptr_t>();
-
-  ObjectPool* result =
-      reinterpret_cast<ObjectPool*>(reader->GetBackRef(object_id));
-  if (result == NULL) {
-    result =
-        &(ObjectPool::ZoneHandle(reader->zone(),
-                                 NEW_OBJECT_WITH_LEN(ObjectPool, length)));
-    reader->AddBackRef(object_id, result, kIsDeserialized);
+  intptr_t len = reader->Read<intptr_t>();
+  ObjectPool* result = NULL;
+  DeserializeState state;
+  if (!as_reference) {
+    result = reinterpret_cast<ObjectPool*>(reader->GetBackRef(object_id));
+    state = kIsDeserialized;
+  } else {
+    state = kIsNotDeserialized;
   }
+  if (result == NULL) {
+    result = &(ObjectPool::ZoneHandle(
+        reader->zone(), NEW_OBJECT_WITH_LEN(ObjectPool, len)));
+    reader->AddBackRef(object_id, result, state);
+  }
+  if (!as_reference) {
+    // Read all the individual elements for inlined objects.
+    const TypedData& info_array =
+        TypedData::Handle(reader->NewTypedData(kTypedDataInt8ArrayCid, len));
+    result->set_info_array(info_array);
 
-  const TypedData& info_array =
-      TypedData::Handle(reader->NewTypedData(kTypedDataInt8ArrayCid, length));
-  result->set_info_array(info_array);
-
-  NoSafepointScope no_safepoint;
-  for (intptr_t i = 0; i < length; i++) {
-    ObjectPool::EntryType entry_type =
-        static_cast<ObjectPool::EntryType>(reader->Read<int8_t>());
-    *reinterpret_cast<int8_t*>(info_array.DataAddr(i)) = entry_type;
-    switch (entry_type) {
-      case ObjectPool::kTaggedObject: {
-        (*reader->PassiveObjectHandle()) =
-            reader->ReadObjectImpl(kAsReference);
-        result->SetObjectAt(i, *(reader->PassiveObjectHandle()));
-        break;
+    NoSafepointScope no_safepoint;
+    for (intptr_t i = 0; i < len; i++) {
+      ObjectPool::EntryType entry_type =
+          static_cast<ObjectPool::EntryType>(reader->Read<int8_t>());
+      *reinterpret_cast<int8_t*>(info_array.DataAddr(i)) = entry_type;
+      switch (entry_type) {
+        case ObjectPool::kTaggedObject: {
+          (*reader->PassiveObjectHandle()) =
+              reader->ReadObjectImpl(kAsReference);
+          result->SetObjectAt(i, *(reader->PassiveObjectHandle()));
+          break;
+        }
+        case ObjectPool::kImmediate: {
+          intptr_t raw_value = reader->Read<intptr_t>();
+          result->SetRawValueAt(i, raw_value);
+          break;
+        }
+        case ObjectPool::kNativeEntry: {
+          // Read nothing. Initialize with the lazy link entry.
+          uword new_entry = NativeEntry::LinkNativeCallEntry();
+          result->SetRawValueAt(i, static_cast<intptr_t>(new_entry));
+          break;
+        }
+        default:
+          UNREACHABLE();
       }
-      case ObjectPool::kImmediate: {
-        intptr_t raw_value = reader->Read<intptr_t>();
-        result->SetRawValueAt(i, raw_value);
-        break;
-      }
-      case ObjectPool::kNativeEntry: {
-        // Read nothing. Initialize with the lazy link entry.
-        uword new_entry = NativeEntry::LinkNativeCallEntry();
-        result->SetRawValueAt(i, static_cast<intptr_t>(new_entry));
-        break;
-      }
-      default:
-        UNREACHABLE();
     }
   }
-
   return result->raw();
 }
 
@@ -2563,15 +2606,24 @@
 
   // Read the length so that we can determine instance size to allocate.
   intptr_t len = reader->ReadSmiValue();
-  Array* array = reinterpret_cast<Array*>(
-      reader->GetBackRef(object_id));
+  Array* array = NULL;
+  DeserializeState state;
+  if (!as_reference) {
+    array = reinterpret_cast<Array*>(reader->GetBackRef(object_id));
+    state = kIsDeserialized;
+  } else {
+    state = kIsNotDeserialized;
+  }
   if (array == NULL) {
     array = &(Array::ZoneHandle(reader->zone(),
                                 NEW_OBJECT_WITH_LEN_SPACE(Array, len, kind)));
-    reader->AddBackRef(object_id, array, kIsDeserialized);
+    reader->AddBackRef(object_id, array, state);
   }
-  ASSERT(!RawObject::IsCanonical(tags));
-  reader->ArrayReadFrom(object_id, *array, len, tags);
+  if (!as_reference) {
+    // Read all the individual elements for inlined objects.
+    ASSERT(!RawObject::IsCanonical(tags));
+    reader->ArrayReadFrom(object_id, *array, len, tags);
+  }
   return array->raw();
 }
 
@@ -2585,19 +2637,29 @@
 
   // Read the length so that we can determine instance size to allocate.
   intptr_t len = reader->ReadSmiValue();
-  Array* array = reinterpret_cast<Array*>(reader->GetBackRef(object_id));
+  Array* array = NULL;
+  DeserializeState state;
+  if (!as_reference) {
+    array = reinterpret_cast<Array*>(reader->GetBackRef(object_id));
+    state = kIsDeserialized;
+  } else {
+    state = kIsNotDeserialized;
+  }
   if (array == NULL) {
     array = &(Array::ZoneHandle(
         reader->zone(),
         NEW_OBJECT_WITH_LEN_SPACE(ImmutableArray, len, kind)));
-    reader->AddBackRef(object_id, array, kIsDeserialized);
+    reader->AddBackRef(object_id, array, state);
   }
-  reader->ArrayReadFrom(object_id, *array, len, tags);
-  if (RawObject::IsCanonical(tags)) {
-    if (kind == Snapshot::kFull) {
-      array->SetCanonical();
-    } else {
-      *array ^= array->CheckAndCanonicalize(NULL);
+  if (!as_reference) {
+    // Read all the individual elements for inlined objects.
+    reader->ArrayReadFrom(object_id, *array, len, tags);
+    if (RawObject::IsCanonical(tags)) {
+      if (kind == Snapshot::kFull) {
+        array->SetCanonical();
+      } else {
+        *array ^= array->CheckAndCanonicalize(NULL);
+      }
     }
   }
   return raw(*array);
@@ -3316,11 +3378,9 @@
                                 Snapshot::Kind kind,
                                 bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT(kind == Snapshot::kMessage);
 
   // Allocate JSRegExp object.
-  JSRegExp& regex = JSRegExp::ZoneHandle(
-      reader->zone(), JSRegExp::New(HEAP_SPACE(kind)));
+  JSRegExp& regex = JSRegExp::ZoneHandle(reader->zone(), NEW_OBJECT(JSRegExp));
   reader->AddBackRef(object_id, &regex, kIsDeserialized);
 
   // Read and Set all the other fields.
@@ -3334,6 +3394,16 @@
                         reader->Read<int8_t>());
 
   // TODO(18854): Need to implement a way of recreating the irrexp functions.
+  const Function& no_function = Function::Handle(reader->zone());
+  regex.set_function(kOneByteStringCid, no_function);
+  regex.set_function(kTwoByteStringCid, no_function);
+  regex.set_function(kExternalOneByteStringCid, no_function);
+  regex.set_function(kExternalTwoByteStringCid, no_function);
+
+  const TypedData& no_bytecode = TypedData::Handle(reader->zone());
+  regex.set_bytecode(true, no_bytecode);
+  regex.set_bytecode(false, no_bytecode);
+
   return regex.raw();
 }
 
@@ -3343,7 +3413,6 @@
                           Snapshot::Kind kind,
                           bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT(kind == Snapshot::kMessage);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -3369,7 +3438,7 @@
 
   // Allocate the weak property object.
   WeakProperty& weak_property = WeakProperty::ZoneHandle(
-      reader->zone(), WeakProperty::New(HEAP_SPACE(kind)));
+      reader->zone(), NEW_OBJECT(WeakProperty));
   reader->AddBackRef(object_id, &weak_property, kIsDeserialized);
 
   // Set all the object fields.
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index f58137c..46122bd 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -5276,15 +5276,15 @@
   fn.set_parameter_names(Array::Handle(zone, Array::New(kParamCount,
                                                            Heap::kOld)));
   fn.SetParameterTypeAt(RegExpMacroAssembler::kParamRegExpIndex,
-                        Type::Handle(zone, Type::DynamicType()));
+                        Object::dynamic_type());
   fn.SetParameterNameAt(RegExpMacroAssembler::kParamRegExpIndex,
                         Symbols::This());
   fn.SetParameterTypeAt(RegExpMacroAssembler::kParamStringIndex,
-                        Type::Handle(zone, Type::DynamicType()));
+                        Object::dynamic_type());
   fn.SetParameterNameAt(RegExpMacroAssembler::kParamStringIndex,
                         Symbols::string_param());
   fn.SetParameterTypeAt(RegExpMacroAssembler::kParamStartOffsetIndex,
-                        Type::Handle(zone, Type::DynamicType()));
+                        Object::dynamic_type());
   fn.SetParameterNameAt(RegExpMacroAssembler::kParamStartOffsetIndex,
                         Symbols::start_index_param());
   fn.set_result_type(Type::Handle(zone, Type::ArrayType()));
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 82c314f..a41db46 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -112,7 +112,7 @@
       new(zone) GraphEntryInstr(
         *parsed_function_,
         new(zone) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex),
-        Thread::kNoDeoptId);
+        Compiler::kNoOSRDeoptId);
   start_block_ =
       new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
   success_block_ =
@@ -382,9 +382,8 @@
 
 LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name,
                                                  intptr_t index) const {
-  const Type& local_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* local =
-      new(Z) LocalVariable(kNoSourcePos, name, local_type);
+      new(Z) LocalVariable(kNoSourcePos, name, Object::dynamic_type());
 
   intptr_t param_frame_index = kParamEndSlotFromFp + kParamCount - index;
   local->set_index(param_frame_index);
@@ -394,9 +393,8 @@
 
 
 LocalVariable* IRRegExpMacroAssembler::Local(const String& name) {
-  const Type& local_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* local =
-      new(Z) LocalVariable(kNoSourcePos, name, local_type);
+      new(Z) LocalVariable(kNoSourcePos, name, Object::dynamic_type());
   local->set_index(GetNextLocalIndex());
 
   return local;
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index e65391d..d09d2a9 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -152,7 +152,7 @@
       if (kind == kJSWarning) {
         TraceJSWarning(script, token_pos, msg);
         // Do not print stacktrace if we have not executed Dart code yet.
-        if (Isolate::Current()->top_exit_frame_info() != 0) {
+        if (Thread::Current()->top_exit_frame_info() != 0) {
           const Stacktrace& stacktrace =
               Stacktrace::Handle(Exceptions::CurrentStacktrace());
           intptr_t idx = 0;
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index d9fe847..b0ae79b 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -59,47 +59,6 @@
 }
 
 
-// Method extractors are used to create implicit closures from methods.
-// When an expression obj.M is evaluated for the first time and receiver obj
-// does not have a getter called M but has a method called M then an extractor
-// is created and injected as a getter (under the name get:M) into the class
-// owning method M.
-static RawFunction* CreateMethodExtractor(const String& getter_name,
-                                          const Function& method) {
-  ASSERT(FLAG_lazy_dispatchers);
-  const Function& closure_function =
-      Function::Handle(method.ImplicitClosureFunction());
-
-  const Class& owner = Class::Handle(closure_function.Owner());
-  Function& extractor = Function::Handle(
-    Function::New(String::Handle(Symbols::New(getter_name)),
-                  RawFunction::kMethodExtractor,
-                  false,  // Not static.
-                  false,  // Not const.
-                  false,  // Not abstract.
-                  false,  // Not external.
-                  false,  // Not native.
-                  owner,
-                  0));  // No token position.
-
-  // Initialize signature: receiver is a single fixed parameter.
-  const intptr_t kNumParameters = 1;
-  extractor.set_num_fixed_parameters(kNumParameters);
-  extractor.SetNumOptionalParameters(0, 0);
-  extractor.set_parameter_types(Object::extractor_parameter_types());
-  extractor.set_parameter_names(Object::extractor_parameter_names());
-  extractor.set_result_type(Type::Handle(Type::DynamicType()));
-
-  extractor.set_extracted_method_closure(closure_function);
-  extractor.set_is_debuggable(false);
-  extractor.set_is_visible(false);
-
-  owner.AddFunction(extractor);
-
-  return extractor.raw();
-}
-
-
 RawFunction* Resolver::ResolveDynamicAnyArgs(
     const Class& receiver_class,
     const String& function_name) {
@@ -116,10 +75,6 @@
     field_name ^= Field::NameFromGetter(function_name);
 
     if (field_name.CharAt(0) == '#') {
-      if (!FLAG_lazy_dispatchers) {
-        return Function::null();
-      }
-
       // Resolving a getter "get:#..." is a request to closurize an instance
       // property of the receiver object. It can be of the form:
       //  - get:#id, which closurizes a method or getter id
@@ -127,28 +82,28 @@
       //  - get:#operator, eg. get:#<<, which closurizes an operator method.
       // If the property can be resolved, a method extractor function
       // "get:#..." is created and injected into the receiver's class.
-      String& property_name = String::Handle(String::SubString(field_name, 1));
-      ASSERT(!Field::IsGetterName(property_name));
+      field_name = String::SubString(field_name, 1);
+      ASSERT(!Field::IsGetterName(field_name));
 
       String& property_getter_name = String::Handle();
-      if (!Field::IsSetterName(property_name)) {
+      if (!Field::IsSetterName(field_name)) {
         // If this is not a setter, we need to look for both the regular
         // name and the getter name. (In the case of an operator, this
         // code will also try to resolve for example get:<< and will fail,
         // but that's harmless.)
-        property_getter_name = Field::GetterName(property_name);
+        property_getter_name = Field::GetterName(field_name);
       }
 
       Function& function = Function::Handle();
       while (!cls.IsNull()) {
-        function = cls.LookupDynamicFunction(property_name);
+        function = cls.LookupDynamicFunction(field_name);
         if (!function.IsNull()) {
-          return CreateMethodExtractor(function_name, function);
+          return function.GetMethodExtractor(function_name);
         }
         if (!property_getter_name.IsNull()) {
           function = cls.LookupDynamicFunction(property_getter_name);
           if (!function.IsNull()) {
-            return CreateMethodExtractor(function_name, function);
+            return function.GetMethodExtractor(function_name);
           }
         }
         cls = cls.SuperClass();
@@ -172,7 +127,9 @@
         if (!function.IsNull()) {
           // We were looking for the getter but found a method with the same
           // name. Create a method extractor and return it.
-          function ^= CreateMethodExtractor(function_name, function);
+          // The extractor does not exist yet, so using GetMethodExtractor is
+          // not necessary here.
+          function ^= function.CreateMethodExtractor(function_name);
           return function.raw();
         }
       }
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index 97b5623..fe8d2898 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -45,10 +45,8 @@
         is_leaf_(is_leaf),
         is_float_(is_float),
         next_(NULL) {
-    // Strip off const for registration.
-    VMTag::RegisterRuntimeEntry(const_cast<RuntimeEntry*>(this));
+    VMTag::RegisterRuntimeEntry(this);
   }
-  ~RuntimeEntry() {}
 
   const char* name() const { return name_; }
   RuntimeFunction function() const { return function_; }
diff --git a/runtime/vm/runtime_entry_arm.cc b/runtime/vm/runtime_entry_arm.cc
index a2c9d49..35e15ea 100644
--- a/runtime/vm/runtime_entry_arm.cc
+++ b/runtime/vm/runtime_entry_arm.cc
@@ -42,7 +42,7 @@
 // Generate code to call into the stub which will call the runtime
 // function. Input for the stub is as follows:
 //   SP : points to the arguments and return value array.
-//   R5 : address of the runtime function to call.
+//   R9 : address of the runtime function to call.
 //   R4 : number of arguments to the call.
 void RuntimeEntry::Call(Assembler* assembler, intptr_t argument_count) const {
   if (is_leaf()) {
@@ -51,7 +51,7 @@
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
-    __ LoadFromOffset(kWord, R5, THR, Thread::OffsetFromThread(this));
+    __ LoadFromOffset(kWord, R9, THR, Thread::OffsetFromThread(this));
     __ LoadImmediate(R4, argument_count);
     __ BranchLink(*StubCode::CallToRuntime_entry(), kNotPatchable);
   }
diff --git a/runtime/vm/runtime_entry_arm64.cc b/runtime/vm/runtime_entry_arm64.cc
index 626d940..5b1605a 100644
--- a/runtime/vm/runtime_entry_arm64.cc
+++ b/runtime/vm/runtime_entry_arm64.cc
@@ -52,14 +52,14 @@
     // We cache the Dart stack pointer and the stack limit in callee-saved
     // registers, then align and call, restoring CSP and SP on return from the
     // call.
-    __ mov(R25, CSP);
-    __ mov(R26, SP);
+    __ mov(R24, CSP);
+    __ mov(R25, SP);
     __ ReserveAlignedFrameSpace(0);
     __ mov(CSP, SP);
     __ ldr(TMP, Address(THR, Thread::OffsetFromThread(this)));
     __ blr(TMP);
-    __ mov(SP, R26);
-    __ mov(CSP, R25);
+    __ mov(SP, R25);
+    __ mov(CSP, R24);
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
diff --git a/runtime/vm/scanner.h b/runtime/vm/scanner.h
index 7558a1d..7a81040 100644
--- a/runtime/vm/scanner.h
+++ b/runtime/vm/scanner.h
@@ -45,7 +45,11 @@
   };
 
   // Dummy token index reflecting an unknown source position.
-  static const intptr_t kNoSourcePos = 0;
+  static const intptr_t kNoSourcePos = -1;
+
+  static bool ValidSourcePosition(intptr_t token_pos) {
+    return (token_pos >= 0) || (token_pos == kNoSourcePos);
+  }
 
   typedef ZoneGrowableArray<TokenDescriptor> GrowableTokenStream;
 
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index c2822b5..60478d3 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -255,12 +255,9 @@
 
 class ScavengerWeakVisitor : public HandleVisitor {
  public:
-  // 'prologue_weak_were_strong' is currently only used for sanity checking.
-  explicit ScavengerWeakVisitor(Scavenger* scavenger,
-                                bool prologue_weak_were_strong)
+  explicit ScavengerWeakVisitor(Scavenger* scavenger)
       :  HandleVisitor(Thread::Current()),
-         scavenger_(scavenger),
-         prologue_weak_were_strong_(prologue_weak_were_strong) {
+         scavenger_(scavenger) {
     ASSERT(scavenger->heap_->isolate() == Thread::Current()->isolate());
   }
 
@@ -269,8 +266,6 @@
       reinterpret_cast<FinalizablePersistentHandle*>(addr);
     RawObject** p = handle->raw_addr();
     if (scavenger_->IsUnreachable(p)) {
-      ASSERT(!handle->IsPrologueWeakPersistent() ||
-             !prologue_weak_were_strong_);
       handle->UpdateUnreachable(thread()->isolate());
     } else {
       handle->UpdateRelocated(thread()->isolate());
@@ -279,7 +274,6 @@
 
  private:
   Scavenger* scavenger_;
-  bool prologue_weak_were_strong_;
 
   DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor);
 };
@@ -455,7 +449,7 @@
   if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
     (isolate->gc_prologue_callback())();
   }
-  Thread::PrepareForGC();
+  isolate->thread_registry()->PrepareForGC();
   // Flip the two semi-spaces so that to_ is always the space for allocating
   // objects.
   SemiSpace* from = to_;
@@ -561,12 +555,9 @@
 }
 
 
-void Scavenger::IterateRoots(Isolate* isolate,
-                             ScavengerVisitor* visitor,
-                             bool visit_prologue_weak_persistent_handles) {
+void Scavenger::IterateRoots(Isolate* isolate, ScavengerVisitor* visitor) {
   int64_t start = OS::GetCurrentTimeMicros();
   isolate->VisitObjectPointers(visitor,
-                               visit_prologue_weak_persistent_handles,
                                StackFrameIterator::kDontValidateFrames);
   int64_t middle = OS::GetCurrentTimeMicros();
   IterateStoreBuffers(isolate, visitor);
@@ -600,81 +591,8 @@
 }
 
 
-void Scavenger::IterateWeakReferences(Isolate* isolate,
-                                      ScavengerVisitor* visitor) {
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
-  while (true) {
-    WeakReferenceSet* queue = state->delayed_weak_reference_sets();
-    if (queue == NULL) {
-      // The delay queue is empty therefore no clean-up is required.
-      return;
-    }
-    state->set_delayed_weak_reference_sets(NULL);
-    while (queue != NULL) {
-      WeakReferenceSet* reference_set = WeakReferenceSet::Pop(&queue);
-      ASSERT(reference_set != NULL);
-      intptr_t num_keys = reference_set->num_keys();
-      intptr_t num_values = reference_set->num_values();
-      if ((num_keys == 1) && (num_values == 1) &&
-          reference_set->SingletonKeyEqualsValue()) {
-        // We do not have to process sets that have just one key/value pair
-        // and the key and value are identical.
-        continue;
-      }
-      bool is_unreachable = true;
-      // Test each key object for reachability.  If a key object is
-      // reachable, all value objects should be scavenged.
-      for (intptr_t k = 0; k < num_keys; ++k) {
-        if (!IsUnreachable(reference_set->get_key(k))) {
-          for (intptr_t v = 0; v < num_values; ++v) {
-            RawObject** raw_obj_addr = reference_set->get_value(v);
-            RawObject* raw_obj = *raw_obj_addr;
-            // Only visit heap objects which are in from space, aka new objects
-            // not in to space. This avoids visiting a value multiple times
-            // during a scavenge.
-            if (raw_obj->IsHeapObject() &&
-                raw_obj->IsNewObject() &&
-                !to_->Contains(RawObject::ToAddr(raw_obj))) {
-              visitor->VisitPointer(raw_obj_addr);
-            }
-          }
-          is_unreachable = false;
-          // Since we have found a key object that is reachable and all
-          // value objects have been marked we can break out of iterating
-          // this set and move on to the next set.
-          break;
-        }
-      }
-      // If all key objects are unreachable put the reference on a
-      // delay queue.  This reference will be revisited if another
-      // reference is scavenged.
-      if (is_unreachable) {
-        state->DelayWeakReferenceSet(reference_set);
-      }
-    }
-    if ((resolved_top_ < top_) || PromotedStackHasMore()) {
-      ProcessToSpace(visitor);
-    } else {
-      // Break out of the loop if there has been no forward process.
-      // All key objects in the weak reference sets are unreachable
-      // so we reset the weak reference sets queue.
-      state->set_delayed_weak_reference_sets(NULL);
-      break;
-    }
-  }
-  ASSERT(state->delayed_weak_reference_sets() == NULL);
-  // All weak reference sets are zone allocated and unmarked references which
-  // were on the delay queue will be freed when the zone is released in the
-  // epilog callback.
-}
-
-
-void Scavenger::IterateWeakRoots(Isolate* isolate,
-                                 HandleVisitor* visitor,
-                                 bool visit_prologue_weak_persistent_handles) {
-  isolate->VisitWeakPersistentHandles(visitor,
-                                      visit_prologue_weak_persistent_handles);
+void Scavenger::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) {
+  isolate->VisitWeakPersistentHandles(visitor);
 }
 
 
@@ -873,16 +791,12 @@
     // Setup the visitor and run the scavenge.
     ScavengerVisitor visitor(isolate, this, from);
     page_space->AcquireDataLock();
-    const bool prologue_weak_are_strong = !invoke_api_callbacks;
-    IterateRoots(isolate, &visitor, prologue_weak_are_strong);
+    IterateRoots(isolate, &visitor);
     int64_t start = OS::GetCurrentTimeMicros();
     ProcessToSpace(&visitor);
     int64_t middle = OS::GetCurrentTimeMicros();
-    IterateWeakReferences(isolate, &visitor);
-    ScavengerWeakVisitor weak_visitor(this, prologue_weak_are_strong);
-    // Include the prologue weak handles, since we must process any promotion.
-    const bool visit_prologue_weak_handles = true;
-    IterateWeakRoots(isolate, &weak_visitor, visit_prologue_weak_handles);
+    ScavengerWeakVisitor weak_visitor(this);
+    IterateWeakRoots(isolate, &weak_visitor);
     visitor.Finalize();
     ProcessWeakTables();
     page_space->ReleaseDataLock();
diff --git a/runtime/vm/scavenger.h b/runtime/vm/scavenger.h
index af3f129..11a0aa1 100644
--- a/runtime/vm/scavenger.h
+++ b/runtime/vm/scavenger.h
@@ -231,14 +231,10 @@
   SemiSpace* Prologue(Isolate* isolate, bool invoke_api_callbacks);
   void IterateStoreBuffers(Isolate* isolate, ScavengerVisitor* visitor);
   void IterateObjectIdTable(Isolate* isolate, ScavengerVisitor* visitor);
-  void IterateRoots(Isolate* isolate,
-                    ScavengerVisitor* visitor,
-                    bool visit_prologue_weak_persistent_handles);
+  void IterateRoots(Isolate* isolate, ScavengerVisitor* visitor);
   void IterateWeakProperties(Isolate* isolate, ScavengerVisitor* visitor);
   void IterateWeakReferences(Isolate* isolate, ScavengerVisitor* visitor);
-  void IterateWeakRoots(Isolate* isolate,
-                        HandleVisitor* visitor,
-                        bool visit_prologue_weak_persistent_handles);
+  void IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor);
   void ProcessToSpace(ScavengerVisitor* visitor);
   uword ProcessWeakProperty(RawWeakProperty* raw_weak,
                             ScavengerVisitor* visitor);
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 0881b87..4c52227 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -29,8 +29,8 @@
       loop_level_(loop_level),
       context_level_(LocalScope::kUnitializedContextLevel),
       num_context_variables_(0),
-      begin_token_pos_(0),
-      end_token_pos_(0),
+      begin_token_pos_(Scanner::kNoSourcePos),
+      end_token_pos_(Scanner::kNoSourcePos),
       variables_(),
       labels_(),
       referenced_() {
@@ -576,7 +576,7 @@
     if (context_scope.IsConstAt(i)) {
       variable = new LocalVariable(context_scope.TokenIndexAt(i),
           String::ZoneHandle(context_scope.NameAt(i)),
-          AbstractType::ZoneHandle(Type::DynamicType()));
+          Object::dynamic_type());
       variable->SetConstValue(
           Instance::ZoneHandle(context_scope.ConstValueAt(i)));
     } else {
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index 5faf502..e68a244 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -34,7 +34,7 @@
       is_invisible_(false),
       is_captured_parameter_(false),
       index_(LocalVariable::kUninitializedIndex) {
-    ASSERT(type.IsZoneHandle());
+    ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
     ASSERT(type.IsFinalized());
     ASSERT(name.IsSymbol());
   }
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 450aadc..631a4ec 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -30,6 +30,7 @@
 #include "vm/reusable_handles.h"
 #include "vm/service_event.h"
 #include "vm/service_isolate.h"
+#include "vm/source_report.h"
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
 #include "vm/unicode.h"
@@ -97,13 +98,13 @@
 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL;
 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL;
 struct ServiceMethodDescriptor;
-ServiceMethodDescriptor* FindMethod(const char* method_name);
+const ServiceMethodDescriptor* FindMethod(const char* method_name);
 
 
 // Support for streams defined in embedders.
 Dart_ServiceStreamListenCallback Service::stream_listen_callback_ = NULL;
 Dart_ServiceStreamCancelCallback Service::stream_cancel_callback_ = NULL;
-
+Dart_GetVMServiceAssetsArchive Service::get_service_assets_callback_ = NULL;
 
 // These are the set of streams known to the core VM.
 StreamInfo Service::vm_stream("VM");
@@ -113,6 +114,7 @@
 StreamInfo Service::echo_stream("_Echo");
 StreamInfo Service::graph_stream("_Graph");
 StreamInfo Service::logging_stream("_Logging");
+StreamInfo Service::extension_stream("Extension");
 
 static StreamInfo* streams_[] = {
   &Service::vm_stream,
@@ -122,6 +124,7 @@
   &Service::echo_stream,
   &Service::graph_stream,
   &Service::logging_stream,
+  &Service::extension_stream,
 };
 
 
@@ -144,6 +147,7 @@
   return false;
 }
 
+
 void Service::CancelStream(const char* stream_id) {
   if (FLAG_trace_service) {
     OS::Print("vm-service: stopping stream '%s'\n",
@@ -162,11 +166,49 @@
   }
 }
 
+RawObject* Service::RequestAssets() {
+  Thread* T = Thread::Current();
+  Api::Scope api_scope(T);
+  if (get_service_assets_callback_ == NULL) {
+    return Object::null();
+  }
+  Dart_Handle handle = get_service_assets_callback_();
+  if (Dart_IsError(handle)) {
+    Dart_PropagateError(handle);
+  }
+  const Object& object = Object::Handle(Api::UnwrapHandle(handle));
+  if (object.IsNull()) {
+    return Object::null();
+  }
+  if (!object.IsTypedData()) {
+    const String& error_message =
+        String::Handle(
+            String::New("An implementation of Dart_GetVMServiceAssetsArchive "
+                        "should return a Uint8Array or null."));
+    const Error& error = Error::Handle(ApiError::New(error_message));
+    Exceptions::PropagateError(error);
+    return Object::null();
+  }
+  const TypedData& typed_data = TypedData::Cast(object);
+  if (typed_data.ElementSizeInBytes() != 1) {
+    const String& error_message =
+        String::Handle(
+            String::New("An implementation of Dart_GetVMServiceAssetsArchive "
+                        "should return a Uint8Array or null."));
+    const Error& error = Error::Handle(ApiError::New(error_message));
+    Exceptions::PropagateError(error);
+    return Object::null();
+  }
+  return Api::UnwrapHandle(handle);
+}
+
+
 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
   void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
   return reinterpret_cast<uint8_t*>(new_ptr);
 }
 
+
 static void PrintMissingParamError(JSONStream* js,
                                    const char* param) {
   js->PrintError(kInvalidParams,
@@ -435,6 +477,36 @@
 };
 
 
+class Int64Parameter : public MethodParameter {
+ public:
+  Int64Parameter(const char* name, bool required)
+      : MethodParameter(name, required) {
+  }
+
+  virtual bool Validate(const char* value) const {
+    if (value == NULL) {
+      return false;
+    }
+    for (const char* cp = value; *cp != '\0'; cp++) {
+      if ((*cp < '0' || *cp > '9') && (*cp != '-')) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  static int64_t Parse(const char* value, int64_t default_value = -1) {
+    if ((value == NULL) || (*value == '\0')) {
+      return default_value;
+    }
+    char* end_ptr = NULL;
+    int64_t result = strtoll(value, &end_ptr, 10);
+    ASSERT(*end_ptr == '\0');  // Parsed full string
+    return result;
+  }
+};
+
+
 class IdParameter : public MethodParameter {
  public:
   IdParameter(const char* name, bool required)
@@ -452,7 +524,7 @@
 
 class EnumParameter : public MethodParameter {
  public:
-  EnumParameter(const char* name, bool required, const char** enums)
+  EnumParameter(const char* name, bool required, const char* const* enums)
       : MethodParameter(name, required),
         enums_(enums) {
   }
@@ -470,14 +542,14 @@
   }
 
  private:
-  const char** enums_;
+  const char* const* enums_;
 };
 
 
 // If the key is not found, this function returns the last element in the
 // values array. This can be used to encode the default value.
 template<typename T>
-T EnumMapper(const char* value, const char** enums, T* values) {
+T EnumMapper(const char* value, const char* const* enums, T* values) {
   ASSERT(value != NULL);
   intptr_t i = 0;
   for (i = 0; enums[i] != NULL; i++) {
@@ -490,7 +562,126 @@
 }
 
 
-typedef bool (*ServiceMethodEntry)(Isolate* isolate, JSONStream* js);
+class EnumListParameter : public MethodParameter {
+ public:
+  EnumListParameter(const char* name, bool required, const char* const* enums)
+      : MethodParameter(name, required),
+        enums_(enums) {
+  }
+
+  virtual bool Validate(const char* value) const {
+    return ElementCount(value) >= 0;
+  }
+
+  const char** Parse(Zone* zone, const char* value_in) const {
+    const char* kJsonChars = " \t\r\n[,]";
+
+    // Make a writeable copy of the value.
+    char* value = zone->MakeCopyOfString(value_in);
+    intptr_t element_count = ElementCount(value);
+    intptr_t element_pos = 0;
+
+    // Allocate our element array.  +1 for NULL terminator.
+    char** elements = zone->Alloc<char*>(element_count + 1);
+    elements[element_count] = NULL;
+
+    // Parse the string destructively.  Build the list of elements.
+    while (element_pos < element_count) {
+      // Skip to the next element.
+      value += strspn(value, kJsonChars);
+
+      intptr_t len = strcspn(value, kJsonChars);
+      ASSERT(len > 0);  // We rely on the parameter being validated already.
+      value[len] = '\0';
+      elements[element_pos++] = value;
+
+      // Advance.  +1 for null terminator.
+      value += (len + 1);
+    }
+    return const_cast<const char**>(elements);
+  }
+
+ private:
+  // For now observatory enums are ascii letters plus underscore.
+  static bool IsEnumChar(char c) {
+    return (((c >= 'a') && (c <= 'z')) ||
+            ((c >= 'A') && (c <= 'Z')) ||
+            (c == '_'));
+  }
+
+  // Returns number of elements in the list.  -1 on parse error.
+  intptr_t ElementCount(const char* value) const {
+    const char* kJsonWhitespaceChars = " \t\r\n";
+
+    if (value == NULL) {
+      return -1;
+    }
+    const char* cp = value;
+    cp += strspn(cp, kJsonWhitespaceChars);
+    if (*cp++ != '[') {
+      // Missing initial [.
+      return -1;
+    }
+    bool closed = false;
+    bool element_allowed = true;
+    intptr_t element_count = 0;
+    while (true) {
+      // Skip json whitespace.
+      cp += strspn(cp, kJsonWhitespaceChars);
+      switch (*cp) {
+        case '\0':
+          return closed ? element_count : -1;
+        case ']':
+          closed = true;
+          cp++;
+          break;
+        case ',':
+          if (element_allowed) {
+            return -1;
+          }
+          element_allowed = true;
+          cp++;
+          break;
+        default:
+          if (!element_allowed) {
+            return -1;
+          }
+          bool valid_enum = false;
+          if (enums_ != NULL) {
+            for (intptr_t i = 0; enums_[i] != NULL; i++) {
+              intptr_t len = strlen(enums_[i]);
+              if (strncmp(cp, enums_[i], len) == 0) {
+                element_count++;
+                valid_enum = true;
+                cp += len;
+                element_allowed = false;  // we need a comma first.
+                break;
+              }
+            }
+          } else {
+            // Allow any identifiers
+            const char* id_start = cp;
+            while (IsEnumChar(*cp)) {
+              cp++;
+            }
+            if (cp == id_start) {
+              // Empty identifier, something like this [,].
+              return -1;
+            }
+          }
+          if (!valid_enum) {
+            return -1;
+          }
+          break;
+      }
+    }
+  }
+
+  const char* const* enums_;
+};
+
+
+typedef bool (*ServiceMethodEntry)(Thread* thread, JSONStream* js);
 
 
 struct ServiceMethodDescriptor {
@@ -605,13 +796,13 @@
     }
     const char* c_method_name = method_name.ToCString();
 
-    ServiceMethodDescriptor* method = FindMethod(c_method_name);
+    const ServiceMethodDescriptor* method = FindMethod(c_method_name);
     if (method != NULL) {
       if (!ValidateParameters(method->parameters, &js)) {
         js.PostReply();
         return;
       }
-      if (method->entry(I, &js)) {
+      if (method->entry(T, &js)) {
         js.PostReply();
       } else {
         // NOTE(turnidge): All message handlers currently return true,
@@ -925,6 +1116,12 @@
 }
 
 
+void Service::SetGetServiceAssetsCallback(
+    Dart_GetVMServiceAssetsArchive get_service_assets) {
+  get_service_assets_callback_ = get_service_assets;
+}
+
+
 EmbedderServiceHandler* Service::FindRootEmbedderHandler(
     const char* name) {
   EmbedderServiceHandler* current = root_service_handler_head_;
@@ -966,8 +1163,8 @@
 };
 
 
-static bool GetIsolate(Isolate* isolate, JSONStream* js) {
-  isolate->PrintJSON(js, false);
+static bool GetIsolate(Thread* thread, JSONStream* js) {
+  thread->isolate()->PrintJSON(js, false);
   return true;
 }
 
@@ -979,7 +1176,13 @@
 };
 
 
-static bool GetStack(Isolate* isolate, JSONStream* js) {
+static bool GetStack(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot get stack when running a precompiled program.");
+    return true;
+  }
+  Isolate* isolate = thread->isolate();
   DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
   // Do we want the complete script object and complete local variable objects?
   // This is true for dump requests.
@@ -1044,20 +1247,20 @@
 }
 
 
-static bool TriggerEchoEvent(Isolate* isolate, JSONStream* js) {
+static bool TriggerEchoEvent(Thread* thread, JSONStream* js) {
   if (Service::echo_stream.enabled()) {
-    Service::SendEchoEvent(isolate, js->LookupParam("text"));
+    Service::SendEchoEvent(thread->isolate(), js->LookupParam("text"));
   }
   JSONObject jsobj(js);
   return HandleCommonEcho(&jsobj, js);
 }
 
 
-static bool DumpIdZone(Isolate* isolate, JSONStream* js) {
+static bool DumpIdZone(Thread* thread, JSONStream* js) {
   // TODO(johnmccutchan): Respect _idZone parameter passed to RPC. For now,
   // always send the ObjectIdRing.
   //
-  ObjectIdRing* ring = isolate->object_id_ring();
+  ObjectIdRing* ring = thread->isolate()->object_id_ring();
   ASSERT(ring != NULL);
   // When printing the ObjectIdRing, force object id reuse policy.
   RingServiceIdZone reuse_zone;
@@ -1068,7 +1271,7 @@
 }
 
 
-static bool Echo(Isolate* isolate, JSONStream* js) {
+static bool Echo(Thread* thread, JSONStream* js) {
   JSONObject jsobj(js);
   return HandleCommonEcho(&jsobj, js);
 }
@@ -1101,7 +1304,7 @@
 }
 
 
-static RawObject* LookupObjectId(Isolate* isolate,
+static RawObject* LookupObjectId(Thread* thread,
                                  const char* arg,
                                  ObjectIdRing::LookupResult* kind) {
   *kind = ObjectIdRing::kValid;
@@ -1113,7 +1316,7 @@
       *kind = ObjectIdRing::kInvalid;
       return Object::null();
     }
-    const Integer& obj = Integer::Handle(isolate->current_zone(),
+    const Integer& obj = Integer::Handle(thread->zone(),
         Smi::New(static_cast<intptr_t>(value)));
     return obj.raw();
   } else if (strcmp(arg, "bool-true") == 0) {
@@ -1124,7 +1327,7 @@
     return Object::null();
   }
 
-  ObjectIdRing* ring = isolate->object_id_ring();
+  ObjectIdRing* ring = thread->isolate()->object_id_ring();
   ASSERT(ring != NULL);
   intptr_t id = -1;
   if (!GetIntegerId(arg, &id)) {
@@ -1185,19 +1388,21 @@
   return Object::sentinel().raw();
 }
 
-static RawObject* LookupHeapObjectClasses(Isolate* isolate,
+static RawObject* LookupHeapObjectClasses(Thread* thread,
                                           char** parts, int num_parts) {
   // Class ids look like: "classes/17"
   if (num_parts < 2) {
     return Object::sentinel().raw();
   }
+  Isolate* isolate = thread->isolate();
+  Zone* zone = thread->zone();
   ClassTable* table = isolate->class_table();
   intptr_t id;
   if (!GetIntegerId(parts[1], &id) ||
       !table->IsValidIndex(id)) {
     return Object::sentinel().raw();
   }
-  Class& cls = Class::Handle(table->At(id));
+  Class& cls = Class::Handle(zone, table->At(id));
   if (num_parts == 2) {
     return cls.raw();
   }
@@ -1210,41 +1415,42 @@
     if (!GetIntegerId(parts[3], &id)) {
       return Object::sentinel().raw();
     }
-    Function& func = Function::Handle();
-    func ^= cls.ClosureFunctionFromIndex(id);
+    Function& func = Function::Handle(zone);
+    func ^= isolate->ClosureFunctionFromIndex(id);
     if (func.IsNull()) {
       return Object::sentinel().raw();
     }
     return func.raw();
 
   } else if (strcmp(parts[2], "fields") == 0) {
-    // Field ids look like: "classes/17/fields/11"
+    // Field ids look like: "classes/17/fields/name"
     if (num_parts != 4) {
       return Object::sentinel().raw();
     }
-    intptr_t id;
-    if (!GetIntegerId(parts[3], &id)) {
+    const char* encoded_id = parts[3];
+    String& id = String::Handle(zone, String::New(encoded_id));
+    id = String::DecodeIRI(id);
+    if (id.IsNull()) {
       return Object::sentinel().raw();
     }
-    Field& field = Field::Handle(cls.FieldFromIndex(id));
+    Field& field = Field::Handle(zone, cls.LookupField(id));
     if (field.IsNull()) {
       return Object::sentinel().raw();
     }
     return field.raw();
 
   } else if (strcmp(parts[2], "functions") == 0) {
-    // Function ids look like: "classes/17/functions/11"
+    // Function ids look like: "classes/17/functions/name"
     if (num_parts != 4) {
       return Object::sentinel().raw();
     }
     const char* encoded_id = parts[3];
-    String& id = String::Handle(isolate->current_zone(),
-        String::New(encoded_id));
+    String& id = String::Handle(zone, String::New(encoded_id));
     id = String::DecodeIRI(id);
     if (id.IsNull()) {
       return Object::sentinel().raw();
     }
-    Function& func = Function::Handle(cls.LookupFunction(id));
+    Function& func = Function::Handle(zone, cls.LookupFunction(id));
     if (func.IsNull()) {
       return Object::sentinel().raw();
     }
@@ -1259,7 +1465,7 @@
     if (!GetIntegerId(parts[3], &id)) {
       return Object::sentinel().raw();
     }
-    Function& func = Function::Handle();
+    Function& func = Function::Handle(zone);
     func ^= cls.ImplicitClosureFunctionFromIndex(id);
     if (func.IsNull()) {
       return Object::sentinel().raw();
@@ -1275,7 +1481,7 @@
     if (!GetIntegerId(parts[3], &id)) {
       return Object::sentinel().raw();
     }
-    Function& func = Function::Handle();
+    Function& func = Function::Handle(zone);
     func ^= cls.InvocationDispatcherFunctionFromIndex(id);
     if (func.IsNull()) {
       return Object::sentinel().raw();
@@ -1291,7 +1497,7 @@
     if (!GetIntegerId(parts[3], &id)) {
       return Object::sentinel().raw();
     }
-    Type& type = Type::Handle();
+    Type& type = Type::Handle(zone);
     type ^= cls.CanonicalTypeFromIndex(id);
     if (type.IsNull()) {
       return Object::sentinel().raw();
@@ -1304,8 +1510,9 @@
 }
 
 
-static RawObject* LookupHeapObjectTypeArguments(Isolate* isolate,
-                                          char** parts, int num_parts) {
+static RawObject* LookupHeapObjectTypeArguments(Thread* thread,
+                                                char** parts, int num_parts) {
+  Isolate* isolate = thread->isolate();
   // TypeArguments ids look like: "typearguments/17"
   if (num_parts < 2) {
     return Object::sentinel().raw();
@@ -1315,7 +1522,8 @@
     return Object::sentinel().raw();
   }
   ObjectStore* object_store = isolate->object_store();
-  const Array& table = Array::Handle(object_store->canonical_type_arguments());
+  const Array& table = Array::Handle(thread->zone(),
+                                     object_store->canonical_type_arguments());
   ASSERT(table.Length() > 0);
   const intptr_t table_size = table.Length() - 1;
   if ((id < 0) || (id >= table_size) || (table.At(id) == Object::null())) {
@@ -1331,12 +1539,12 @@
     return Object::sentinel().raw();
   }
   uword pc;
-  static const char* kCollectedPrefix = "collected-";
+  static const char* const kCollectedPrefix = "collected-";
   static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix);
-  static const char* kNativePrefix = "native-";
-  static intptr_t kNativePrefixLen = strlen(kNativePrefix);
-  static const char* kReusedPrefix = "reused-";
-  static intptr_t kReusedPrefixLen = strlen(kReusedPrefix);
+  static const char* const kNativePrefix = "native-";
+  static const intptr_t kNativePrefixLen = strlen(kNativePrefix);
+  static const char* const kReusedPrefix = "reused-";
+  static const intptr_t kReusedPrefixLen = strlen(kReusedPrefix);
   const char* id = parts[1];
   if (strncmp(kCollectedPrefix, id, kCollectedPrefixLen) == 0) {
     if (!GetUnsignedIntegerId(&id[kCollectedPrefixLen], &pc, 16)) {
@@ -1373,7 +1581,7 @@
 }
 
 
-static RawObject* LookupHeapObjectMessage(Isolate* isolate,
+static RawObject* LookupHeapObjectMessage(Thread* thread,
                                           char** parts, int num_parts) {
   if (num_parts != 2) {
     return Object::sentinel().raw();
@@ -1383,23 +1591,27 @@
     return Object::sentinel().raw();
   }
   MessageHandler::AcquiredQueues aq;
-  isolate->message_handler()->AcquireQueues(&aq);
+  thread->isolate()->message_handler()->AcquireQueues(&aq);
   Message* message = aq.queue()->FindMessageById(message_id);
   if (message == NULL) {
     // The user may try to load an expired message.
     return Object::sentinel().raw();
   }
-  MessageSnapshotReader reader(message->data(),
-                               message->len(),
-                               Thread::Current());
-  return reader.ReadObject();
+  if (message->len() > 0) {
+    MessageSnapshotReader reader(message->data(),
+                                 message->len(),
+                                 thread);
+    return reader.ReadObject();
+  } else {
+    return message->raw_obj();
+  }
 }
 
 
-static RawObject* LookupHeapObject(Isolate* isolate,
+static RawObject* LookupHeapObject(Thread* thread,
                                    const char* id_original,
                                    ObjectIdRing::LookupResult* result) {
-  char* id = Thread::Current()->zone()->MakeCopyOfString(id_original);
+  char* id = thread->zone()->MakeCopyOfString(id_original);
 
   // Parse the id by splitting at each '/'.
   const int MAX_PARTS = 8;
@@ -1427,11 +1639,12 @@
     *result = ObjectIdRing::kValid;
   }
 
+  Isolate* isolate = thread->isolate();
   if (strcmp(parts[0], "objects") == 0) {
     // Object ids look like "objects/1123"
-    Object& obj = Object::Handle(isolate->current_zone());
+    Object& obj = Object::Handle(thread->zone());
     ObjectIdRing::LookupResult lookup_result;
-    obj = LookupObjectId(isolate, parts[1], &lookup_result);
+    obj = LookupObjectId(thread, parts[1], &lookup_result);
     if (lookup_result != ObjectIdRing::kValid) {
       if (result != NULL) {
         *result = lookup_result;
@@ -1443,13 +1656,13 @@
   } else if (strcmp(parts[0], "libraries") == 0) {
     return LookupHeapObjectLibraries(isolate, parts, num_parts);
   } else if (strcmp(parts[0], "classes") == 0) {
-    return LookupHeapObjectClasses(isolate, parts, num_parts);
+    return LookupHeapObjectClasses(thread, parts, num_parts);
   } else if (strcmp(parts[0], "typearguments") == 0) {
-    return LookupHeapObjectTypeArguments(isolate, parts, num_parts);
+    return LookupHeapObjectTypeArguments(thread, parts, num_parts);
   } else if (strcmp(parts[0], "code") == 0) {
     return LookupHeapObjectCode(isolate, parts, num_parts);
   } else if (strcmp(parts[0], "messages") == 0) {
-    return LookupHeapObjectMessage(isolate, parts, num_parts);
+    return LookupHeapObjectMessage(thread, parts, num_parts);
   }
 
   // Not found.
@@ -1515,11 +1728,11 @@
 }
 
 
-static bool PrintInboundReferences(Isolate* isolate,
+static bool PrintInboundReferences(Thread* thread,
                                    Object* target,
                                    intptr_t limit,
                                    JSONStream* js) {
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   Array& path = Array::Handle(Array::New(limit * 2));
   intptr_t length = graph.InboundReferences(target, path);
   JSONObject jsobj(js);
@@ -1571,10 +1784,7 @@
 };
 
 
-static bool GetInboundReferences(Isolate* isolate, JSONStream* js) {
-  Thread* thread = Thread::Current();
-  ASSERT(isolate == thread->isolate());
-
+static bool GetInboundReferences(Thread* thread, JSONStream* js) {
   const char* target_id = js->LookupParam("targetId");
   if (target_id == NULL) {
     PrintMissingParamError(js, "targetId");
@@ -1595,7 +1805,7 @@
   ObjectIdRing::LookupResult lookup_result;
   {
     HANDLESCOPE(thread);
-    obj = LookupHeapObject(isolate, target_id, &lookup_result);
+    obj = LookupHeapObject(thread, target_id, &lookup_result);
   }
   if (obj.raw() == Object::sentinel().raw()) {
     if (lookup_result == ObjectIdRing::kCollected) {
@@ -1607,15 +1817,15 @@
     }
     return true;
   }
-  return PrintInboundReferences(isolate, &obj, limit, js);
+  return PrintInboundReferences(thread, &obj, limit, js);
 }
 
 
-static bool PrintRetainingPath(Isolate* isolate,
+static bool PrintRetainingPath(Thread* thread,
                                Object* obj,
                                intptr_t limit,
                                JSONStream* js) {
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   Array& path = Array::Handle(Array::New(limit * 2));
   intptr_t length = graph.RetainingPath(obj, path);
   JSONObject jsobj(js);
@@ -1673,10 +1883,7 @@
 };
 
 
-static bool GetRetainingPath(Isolate* isolate, JSONStream* js) {
-  Thread* thread = Thread::Current();
-  ASSERT(isolate == thread->isolate());
-
+static bool GetRetainingPath(Thread* thread, JSONStream* js) {
   const char* target_id = js->LookupParam("targetId");
   if (target_id == NULL) {
     PrintMissingParamError(js, "targetId");
@@ -1697,7 +1904,7 @@
   ObjectIdRing::LookupResult lookup_result;
   {
     HANDLESCOPE(thread);
-    obj = LookupHeapObject(isolate, target_id, &lookup_result);
+    obj = LookupHeapObject(thread, target_id, &lookup_result);
   }
   if (obj.raw() == Object::sentinel().raw()) {
     if (lookup_result == ObjectIdRing::kCollected) {
@@ -1709,24 +1916,22 @@
     }
     return true;
   }
-  return PrintRetainingPath(isolate, &obj, limit, js);
+  return PrintRetainingPath(thread, &obj, limit, js);
 }
 
 
 static const MethodParameter* get_retained_size_params[] = {
   ISOLATE_PARAMETER,
+  new IdParameter("targetId", true),
   NULL,
 };
 
 
-static bool GetRetainedSize(Isolate* isolate, JSONStream* js) {
+static bool GetRetainedSize(Thread* thread, JSONStream* js) {
   const char* target_id = js->LookupParam("targetId");
-  if (target_id == NULL) {
-    PrintMissingParamError(js, "targetId");
-    return true;
-  }
+  ASSERT(target_id != NULL);
   ObjectIdRing::LookupResult lookup_result;
-  Object& obj = Object::Handle(LookupHeapObject(isolate, target_id,
+  Object& obj = Object::Handle(LookupHeapObject(thread, target_id,
                                                 &lookup_result));
   if (obj.raw() == Object::sentinel().raw()) {
     if (lookup_result == ObjectIdRing::kCollected) {
@@ -1742,14 +1947,14 @@
   // SizeRetainedByClass should be a separate RPC.
   if (obj.IsClass()) {
     const Class& cls = Class::Cast(obj);
-    ObjectGraph graph(isolate);
+    ObjectGraph graph(thread);
     intptr_t retained_size = graph.SizeRetainedByClass(cls.id());
     const Object& result = Object::Handle(Integer::New(retained_size));
     result.PrintJSON(js, true);
     return true;
   }
 
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   intptr_t retained_size = graph.SizeRetainedByInstance(obj);
   const Object& result = Object::Handle(Integer::New(retained_size));
   result.PrintJSON(js, true);
@@ -1757,14 +1962,56 @@
 }
 
 
+static const MethodParameter* get_reachable_size_params[] = {
+  ISOLATE_PARAMETER,
+  new IdParameter("targetId", true),
+  NULL,
+};
+
+
+static bool GetReachableSize(Thread* thread, JSONStream* js) {
+  const char* target_id = js->LookupParam("targetId");
+  ASSERT(target_id != NULL);
+  ObjectIdRing::LookupResult lookup_result;
+  Object& obj = Object::Handle(LookupHeapObject(thread, target_id,
+                                                &lookup_result));
+  if (obj.raw() == Object::sentinel().raw()) {
+    if (lookup_result == ObjectIdRing::kCollected) {
+      PrintSentinel(js, kCollectedSentinel);
+    } else if (lookup_result == ObjectIdRing::kExpired) {
+      PrintSentinel(js, kExpiredSentinel);
+    } else {
+      PrintInvalidParamError(js, "targetId");
+    }
+    return true;
+  }
+  // TODO(rmacnak): There is no way to get the size retained by a class object.
+  // SizeRetainedByClass should be a separate RPC.
+  if (obj.IsClass()) {
+    const Class& cls = Class::Cast(obj);
+    ObjectGraph graph(thread);
+    intptr_t retained_size = graph.SizeReachableByClass(cls.id());
+    const Object& result = Object::Handle(Integer::New(retained_size));
+    result.PrintJSON(js, true);
+    return true;
+  }
+
+  ObjectGraph graph(thread);
+  intptr_t retained_size = graph.SizeReachableByInstance(obj);
+  const Object& result = Object::Handle(Integer::New(retained_size));
+  result.PrintJSON(js, true);
+  return true;
+}
+
+
 static const MethodParameter* evaluate_params[] = {
   ISOLATE_PARAMETER,
   NULL,
 };
 
 
-static bool Evaluate(Isolate* isolate, JSONStream* js) {
-  if (!isolate->compilation_allowed()) {
+static bool Evaluate(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
     js->PrintError(kFeatureDisabled,
                    "Cannot evaluate when running a precompiled program.");
     return true;
@@ -1779,11 +2026,11 @@
     PrintMissingParamError(js, "expression");
     return true;
   }
-  const String& expr_str =
-      String::Handle(isolate->current_zone(), String::New(expr));
+  Zone* zone = thread->zone();
+  const String& expr_str = String::Handle(zone, String::New(expr));
   ObjectIdRing::LookupResult lookup_result;
-  Object& obj = Object::Handle(LookupHeapObject(isolate, target_id,
-                                                &lookup_result));
+  Object& obj = Object::Handle(zone, LookupHeapObject(thread, target_id,
+                                                      &lookup_result));
   if (obj.raw() == Object::sentinel().raw()) {
     if (lookup_result == ObjectIdRing::kCollected) {
       PrintSentinel(js, kCollectedSentinel);
@@ -1796,29 +2043,27 @@
   }
   if (obj.IsLibrary()) {
     const Library& lib = Library::Cast(obj);
-    const Object& result = Object::Handle(lib.Evaluate(expr_str,
-                                                       Array::empty_array(),
-                                                       Array::empty_array()));
+    const Object& result = Object::Handle(zone,
+        lib.Evaluate(expr_str, Array::empty_array(), Array::empty_array()));
     result.PrintJSON(js, true);
     return true;
   }
   if (obj.IsClass()) {
     const Class& cls = Class::Cast(obj);
-    const Object& result = Object::Handle(cls.Evaluate(expr_str,
-                                                       Array::empty_array(),
-                                                       Array::empty_array()));
+    const Object& result = Object::Handle(zone,
+        cls.Evaluate(expr_str, Array::empty_array(), Array::empty_array()));
     result.PrintJSON(js, true);
     return true;
   }
   if ((obj.IsInstance() || obj.IsNull()) &&
       !ContainsNonInstance(obj)) {
     // We don't use Instance::Cast here because it doesn't allow null.
-    Instance& instance = Instance::Handle(isolate->current_zone());
+    Instance& instance = Instance::Handle(zone);
     instance ^= obj.raw();
     const Object& result =
-        Object::Handle(instance.Evaluate(expr_str,
-                                         Array::empty_array(),
-                                         Array::empty_array()));
+        Object::Handle(zone, instance.Evaluate(expr_str,
+                                               Array::empty_array(),
+                                               Array::empty_array()));
     result.PrintJSON(js, true);
     return true;
   }
@@ -1838,7 +2083,8 @@
 };
 
 
-static bool EvaluateInFrame(Isolate* isolate, JSONStream* js) {
+static bool EvaluateInFrame(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
   if (!isolate->compilation_allowed()) {
     js->PrintError(kFeatureDisabled,
                    "Cannot evaluate when running a precompiled program.");
@@ -1852,11 +2098,11 @@
   }
   ActivationFrame* frame = stack->FrameAt(framePos);
 
+  Zone* zone = thread->zone();
   const char* expr = js->LookupParam("expression");
-  const String& expr_str = String::Handle(isolate->current_zone(),
-      String::New(expr));
+  const String& expr_str = String::Handle(zone, String::New(expr));
 
-  const Object& result = Object::Handle(frame->Evaluate(expr_str));
+  const Object& result = Object::Handle(zone, frame->Evaluate(expr_str));
   result.PrintJSON(js, true);
   return true;
 }
@@ -1900,7 +2146,7 @@
 };
 
 
-static bool GetInstances(Isolate* isolate, JSONStream* js) {
+static bool GetInstances(Thread* thread, JSONStream* js) {
   const char* target_id = js->LookupParam("classId");
   if (target_id == NULL) {
     PrintMissingParamError(js, "classId");
@@ -1917,7 +2163,7 @@
     return true;
   }
   const Object& obj =
-      Object::Handle(LookupHeapObject(isolate, target_id, NULL));
+      Object::Handle(LookupHeapObject(thread, target_id, NULL));
   if (obj.raw() == Object::sentinel().raw() ||
       !obj.IsClass()) {
     PrintInvalidParamError(js, "classId");
@@ -1926,7 +2172,7 @@
   const Class& cls = Class::Cast(obj);
   Array& storage = Array::Handle(Array::New(limit));
   GetInstancesVisitor visitor(cls, storage);
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   graph.IterateObjects(&visitor);
   intptr_t count = visitor.count();
   if (count < limit) {
@@ -2007,14 +2253,18 @@
 };
 
 
-static bool GetHitsOrSites(Isolate* isolate, JSONStream* js, bool as_sites) {
-  Thread* thread = Thread::Current();
+static bool GetHitsOrSites(Thread* thread, JSONStream* js, bool as_sites) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot get coverage data when running a precompiled program.");
+    return true;
+  }
   if (!js->HasParam("targetId")) {
     CodeCoverage::PrintJSON(thread, js, NULL, as_sites);
     return true;
   }
   const char* target_id = js->LookupParam("targetId");
-  Object& obj = Object::Handle(LookupHeapObject(isolate, target_id, NULL));
+  Object& obj = Object::Handle(LookupHeapObject(thread, target_id, NULL));
   if (obj.raw() == Object::sentinel().raw()) {
     PrintInvalidParamError(js, "targetId");
     return true;
@@ -2055,9 +2305,89 @@
 };
 
 
-static bool GetCoverage(Isolate* isolate, JSONStream* js) {
+static bool GetCoverage(Thread* thread, JSONStream* js) {
   // TODO(rmacnak): Remove this response; it is subsumed by GetCallSiteData.
-  return GetHitsOrSites(isolate, js, false);
+  return GetHitsOrSites(thread, js, false);
+}
+
+
+static const char* kCallSitesStr = "CallSites";
+static const char* kCoverageStr = "Coverage";
+
+
+static const char* const report_enum_names[] = {
+  kCallSitesStr,
+  kCoverageStr,
+  NULL,
+};
+
+
+static const EnumListParameter* reports_parameter =
+    new EnumListParameter("reports", true, report_enum_names);
+
+
+static const MethodParameter* get_source_report_params[] = {
+  ISOLATE_PARAMETER,
+  reports_parameter,
+  new IdParameter("scriptId", false),
+  new UIntParameter("tokenPos", false),
+  new UIntParameter("endTokenPos", false),
+  new BoolParameter("forceCompile", false),
+  NULL,
+};
+
+
+static bool GetSourceReport(Thread* thread, JSONStream* js) {
+  const char* reports_str = js->LookupParam("reports");
+  const char** reports = reports_parameter->Parse(thread->zone(), reports_str);
+  intptr_t report_set = 0;
+  while (*reports != NULL) {
+    if (strcmp(*reports, kCallSitesStr) == 0) {
+      report_set |= SourceReport::kCallSites;
+    } else if (strcmp(*reports, kCoverageStr) == 0) {
+      report_set |= SourceReport::kCoverage;
+    }
+    reports++;
+  }
+
+  SourceReport::CompileMode compile_mode = SourceReport::kNoCompile;
+  if (BoolParameter::Parse(js->LookupParam("forceCompile"), false)) {
+    compile_mode = SourceReport::kForceCompile;
+  }
+
+  Script& script = Script::Handle();
+  intptr_t start_pos = UIntParameter::Parse(js->LookupParam("tokenPos"));
+  intptr_t end_pos = UIntParameter::Parse(js->LookupParam("endTokenPos"));
+
+  if (js->HasParam("scriptId")) {
+    // Get the target script.
+    const char* script_id_param = js->LookupParam("scriptId");
+    const Object& obj =
+        Object::Handle(LookupHeapObject(thread, script_id_param, NULL));
+    if (obj.raw() == Object::sentinel().raw() || !obj.IsScript()) {
+      PrintInvalidParamError(js, "scriptId");
+      return true;
+    }
+    script ^= obj.raw();
+  } else {
+    if (js->HasParam("tokenPos")) {
+      js->PrintError(
+          kInvalidParams,
+          "%s: the 'tokenPos' parameter requires the 'scriptId' parameter",
+          js->method());
+      return true;
+    }
+    if (js->HasParam("endTokenPos")) {
+      js->PrintError(
+          kInvalidParams,
+          "%s: the 'endTokenPos' parameter requires the 'scriptId' parameter",
+          js->method());
+      return true;
+    }
+  }
+  SourceReport report(report_set, compile_mode);
+  report.PrintJSON(js, script, start_pos, end_pos);
+  return true;
 }
 
 
@@ -2068,14 +2398,19 @@
 };
 
 
-static bool GetCallSiteData(Isolate* isolate, JSONStream* js) {
-  return GetHitsOrSites(isolate, js, true);
+static bool GetCallSiteData(Thread* thread, JSONStream* js) {
+  return GetHitsOrSites(thread, js, true);
 }
 
 
-static bool AddBreakpointCommon(Isolate* isolate,
+static bool AddBreakpointCommon(Thread* thread,
                                 JSONStream* js,
                                 const String& script_uri) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* line_param = js->LookupParam("line");
   intptr_t line = UIntParameter::Parse(line_param);
   const char* col_param = js->LookupParam("column");
@@ -2090,7 +2425,8 @@
   }
   ASSERT(!script_uri.IsNull());
   Breakpoint* bpt = NULL;
-  bpt = isolate->debugger()->SetBreakpointAtLineCol(script_uri, line, col);
+  bpt = thread->isolate()->debugger()->
+      SetBreakpointAtLineCol(script_uri, line, col);
   if (bpt == NULL) {
     js->PrintError(kCannotAddBreakpoint,
                    "%s: Cannot add breakpoint at line '%s'",
@@ -2111,10 +2447,14 @@
 };
 
 
-static bool AddBreakpoint(Isolate* isolate, JSONStream* js) {
+static bool AddBreakpoint(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* script_id_param = js->LookupParam("scriptId");
-  Object& obj =
-      Object::Handle(LookupHeapObject(isolate, script_id_param, NULL));
+  Object& obj = Object::Handle(LookupHeapObject(thread, script_id_param, NULL));
   if (obj.raw() == Object::sentinel().raw() || !obj.IsScript()) {
     PrintInvalidParamError(js, "scriptId");
     return true;
@@ -2122,7 +2462,7 @@
   const Script& script = Script::Cast(obj);
   const String& script_uri = String::Handle(script.url());
   ASSERT(!script_uri.IsNull());
-  return AddBreakpointCommon(isolate, js, script_uri);
+  return AddBreakpointCommon(thread, js, script_uri);
 }
 
 
@@ -2135,10 +2475,15 @@
 };
 
 
-static bool AddBreakpointWithScriptUri(Isolate* isolate, JSONStream* js) {
+static bool AddBreakpointWithScriptUri(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* script_uri_param = js->LookupParam("scriptUri");
   const String& script_uri = String::Handle(String::New(script_uri_param));
-  return AddBreakpointCommon(isolate, js, script_uri);
+  return AddBreakpointCommon(thread, js, script_uri);
 }
 
 
@@ -2149,16 +2494,21 @@
 };
 
 
-static bool AddBreakpointAtEntry(Isolate* isolate, JSONStream* js) {
+static bool AddBreakpointAtEntry(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* function_id = js->LookupParam("functionId");
-  Object& obj = Object::Handle(LookupHeapObject(isolate, function_id, NULL));
+  Object& obj = Object::Handle(LookupHeapObject(thread, function_id, NULL));
   if (obj.raw() == Object::sentinel().raw() || !obj.IsFunction()) {
     PrintInvalidParamError(js, "functionId");
     return true;
   }
   const Function& function = Function::Cast(obj);
   Breakpoint* bpt =
-      isolate->debugger()->SetBreakpointAtEntry(function, false);
+      thread->isolate()->debugger()->SetBreakpointAtEntry(function, false);
   if (bpt == NULL) {
     js->PrintError(kCannotAddBreakpoint,
                    "%s: Cannot add breakpoint at function '%s'",
@@ -2177,16 +2527,21 @@
 };
 
 
-static bool AddBreakpointAtActivation(Isolate* isolate, JSONStream* js) {
+static bool AddBreakpointAtActivation(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   const char* object_id = js->LookupParam("objectId");
-  Object& obj = Object::Handle(LookupHeapObject(isolate, object_id, NULL));
+  Object& obj = Object::Handle(LookupHeapObject(thread, 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);
+      thread->isolate()->debugger()->SetBreakpointAtActivation(closure);
   if (bpt == NULL) {
     js->PrintError(kCannotAddBreakpoint,
                    "%s: Cannot add breakpoint at activation",
@@ -2204,13 +2559,19 @@
 };
 
 
-static bool RemoveBreakpoint(Isolate* isolate, JSONStream* js) {
+static bool RemoveBreakpoint(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot use breakpoints when running a precompiled program.");
+    return true;
+  }
   if (!js->HasParam("breakpointId")) {
     PrintMissingParamError(js, "breakpointId");
     return true;
   }
   const char* bpt_id = js->LookupParam("breakpointId");
   ObjectIdRing::LookupResult lookup_result;
+  Isolate* isolate = thread->isolate();
   Breakpoint* bpt = LookupBreakpoint(isolate, bpt_id, &lookup_result);
   // TODO(turnidge): Should we return a different error for bpts whic
   // have been already removed?
@@ -2224,8 +2585,8 @@
 }
 
 
-static RawClass* GetMetricsClass(Isolate* isolate) {
-  Zone* zone = isolate->current_zone();
+static RawClass* GetMetricsClass(Thread* thread) {
+  Zone* zone = thread->zone();
   const Library& prof_lib =
       Library::Handle(zone, Library::DeveloperLibrary());
   ASSERT(!prof_lib.IsNull());
@@ -2240,12 +2601,12 @@
 
 
 
-static bool HandleNativeMetricsList(Isolate* isolate, JSONStream* js) {
+static bool HandleNativeMetricsList(Thread* thread, JSONStream* js) {
   JSONObject obj(js);
   obj.AddProperty("type", "MetricList");
   {
     JSONArray metrics(&obj, "metrics");
-    Metric* current = isolate->metrics_list_head();
+    Metric* current = thread->isolate()->metrics_list_head();
     while (current != NULL) {
       metrics.AddValue(current);
       current = current->next();
@@ -2255,10 +2616,8 @@
 }
 
 
-static bool HandleNativeMetric(Isolate* isolate,
-                                JSONStream* js,
-                                const char* id) {
-  Metric* current = isolate->metrics_list_head();
+static bool HandleNativeMetric(Thread* thread, JSONStream* js, const char* id) {
+  Metric* current = thread->isolate()->metrics_list_head();
   while (current != NULL) {
     const char* name = current->name();
     ASSERT(name != NULL);
@@ -2273,9 +2632,10 @@
 }
 
 
-static bool HandleDartMetricsList(Isolate* isolate, JSONStream* js) {
-  Zone* zone = isolate->current_zone();
-  const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(isolate));
+static bool HandleDartMetricsList(Thread* thread, JSONStream* js) {
+  Zone* zone = thread->zone();
+  const Class& metrics_cls =
+      Class::Handle(zone, GetMetricsClass(thread));
   const String& print_metrics_name =
       String::Handle(String::New("_printMetrics"));
   ASSERT(!print_metrics_name.IsNull());
@@ -2294,9 +2654,10 @@
 }
 
 
-static bool HandleDartMetric(Isolate* isolate, JSONStream* js, const char* id) {
-  Zone* zone = isolate->current_zone();
-  const Class& metrics_cls = Class::Handle(zone, GetMetricsClass(isolate));
+static bool HandleDartMetric(Thread* thread, JSONStream* js, const char* id) {
+  Zone* zone = thread->zone();
+  const Class& metrics_cls =
+      Class::Handle(zone, GetMetricsClass(thread));
   const String& print_metric_name =
       String::Handle(String::New("_printMetric"));
   ASSERT(!print_metric_name.IsNull());
@@ -2328,7 +2689,7 @@
 };
 
 
-static bool GetIsolateMetricList(Isolate* isolate, JSONStream* js) {
+static bool GetIsolateMetricList(Thread* thread, JSONStream* js) {
   bool native_metrics = false;
   if (js->HasParam("type")) {
     if (js->ParamIs("type", "Native")) {
@@ -2344,9 +2705,9 @@
     return true;
   }
   if (native_metrics) {
-    return HandleNativeMetricsList(isolate, js);
+    return HandleNativeMetricsList(thread, js);
   }
-  return HandleDartMetricsList(isolate, js);
+  return HandleDartMetricsList(thread, js);
 }
 
 
@@ -2356,30 +2717,30 @@
 };
 
 
-static bool GetIsolateMetric(Isolate* isolate, JSONStream* js) {
+static bool GetIsolateMetric(Thread* thread, JSONStream* js) {
   const char* metric_id = js->LookupParam("metricId");
   if (metric_id == NULL) {
     PrintMissingParamError(js, "metricId");
     return true;
   }
   // Verify id begins with "metrics/".
-  static const char* kMetricIdPrefix = "metrics/";
+  static const char* const kMetricIdPrefix = "metrics/";
   static intptr_t kMetricIdPrefixLen = strlen(kMetricIdPrefix);
   if (strncmp(metric_id, kMetricIdPrefix, kMetricIdPrefixLen) != 0) {
     PrintInvalidParamError(js, "metricId");
     return true;
   }
   // Check if id begins with "metrics/native/".
-  static const char* kNativeMetricIdPrefix = "metrics/native/";
+  static const char* const kNativeMetricIdPrefix = "metrics/native/";
   static intptr_t kNativeMetricIdPrefixLen = strlen(kNativeMetricIdPrefix);
   const bool native_metric =
       strncmp(metric_id, kNativeMetricIdPrefix, kNativeMetricIdPrefixLen) == 0;
   if (native_metric) {
     const char* id = metric_id + kNativeMetricIdPrefixLen;
-    return HandleNativeMetric(isolate, js, id);
+    return HandleNativeMetric(thread, js, id);
   }
   const char* id = metric_id + kMetricIdPrefixLen;
-  return HandleDartMetric(isolate, js, id);
+  return HandleDartMetric(thread, js, id);
 }
 
 
@@ -2389,7 +2750,7 @@
 };
 
 
-static bool GetVMMetricList(Isolate* isolate, JSONStream* js) {
+static bool GetVMMetricList(Thread* thread, JSONStream* js) {
   return false;
 }
 
@@ -2400,7 +2761,7 @@
 };
 
 
-static bool GetVMMetric(Isolate* isolate, JSONStream* js) {
+static bool GetVMMetric(Thread* thread, JSONStream* js) {
   const char* metric_id = js->LookupParam("metricId");
   if (metric_id == NULL) {
     PrintMissingParamError(js, "metricId");
@@ -2409,14 +2770,104 @@
 }
 
 
+static const MethodParameter* set_vm_timeline_flag_params[] = {
+  NO_ISOLATE_PARAMETER,
+  new MethodParameter("_record", true),
+  NULL,
+};
+
+
+static bool SetVMTimelineFlag(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  StackZone zone(thread);
+
+  bool recording = strcmp(js->LookupParam("_record"), "all") == 0;
+  Timeline::SetStreamAPIEnabled(recording);
+  Timeline::SetStreamCompilerEnabled(recording);
+  Timeline::SetStreamDartEnabled(recording);
+  Timeline::SetStreamDebuggerEnabled(recording);
+  Timeline::SetStreamEmbedderEnabled(recording);
+  Timeline::SetStreamGCEnabled(recording);
+  Timeline::SetStreamIsolateEnabled(recording);
+
+  PrintSuccess(js);
+
+  return true;
+}
+
+
+static const MethodParameter* get_vm_timeline_flag_params[] = {
+  NO_ISOLATE_PARAMETER,
+  new MethodParameter("_record", false),
+  NULL,
+};
+
+
+static bool GetVMTimelineFlag(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  StackZone zone(thread);
+
+  js->PrintError(kFeatureDisabled, "TODO(johnmccutchan)");
+  return true;
+}
+
+
+static const MethodParameter* clear_vm_timeline_params[] = {
+  NO_ISOLATE_PARAMETER,
+  NULL,
+};
+
+
+static bool ClearVMTimeline(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  StackZone zone(thread);
+
+  Timeline::Clear();
+
+  PrintSuccess(js);
+
+  return true;
+}
+
+
+static const MethodParameter* get_vm_timeline_params[] = {
+  NO_ISOLATE_PARAMETER,
+  new Int64Parameter("timeOriginMicros", false),
+  new Int64Parameter("timeExtentMicros", false),
+  NULL,
+};
+
+
+static bool GetVMTimeline(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  StackZone zone(thread);
+  Timeline::ReclaimCachedBlocksFromThreads();
+  TimelineEventRecorder* timeline_recorder = Timeline::recorder();
+  // TODO(johnmccutchan): Return an error.
+  ASSERT(timeline_recorder != NULL);
+  int64_t time_origin_micros =
+      Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
+  int64_t time_extent_micros =
+      Int64Parameter::Parse(js->LookupParam("timeExtentMicros"));
+  TimelineEventFilter filter(time_origin_micros, time_extent_micros);
+  timeline_recorder->PrintJSON(js, &filter);
+  return true;
+}
+
+
 static const MethodParameter* resume_params[] = {
   ISOLATE_PARAMETER,
   NULL,
 };
 
 
-static bool Resume(Isolate* isolate, JSONStream* js) {
+static bool Resume(Thread* thread, JSONStream* js) {
   const char* step_param = js->LookupParam("step");
+  Isolate* isolate = thread->isolate();
   if (isolate->message_handler()->paused_on_start()) {
     // If the user is issuing a 'Over' or an 'Out' step, that is the
     // same as a regular resume request.
@@ -2467,11 +2918,12 @@
 };
 
 
-static bool Pause(Isolate* isolate, JSONStream* js) {
+static bool Pause(Thread* thread, JSONStream* js) {
   // TODO(turnidge): This interrupt message could have been sent from
   // the service isolate directly, but would require some special case
   // code.  That would prevent this isolate getting double-interrupted
   // with OOB messages.
+  Isolate* isolate = thread->isolate();
   isolate->SendInternalLibMessage(Isolate::kInterruptMsg,
                                   isolate->pause_capability());
   PrintSuccess(js);
@@ -2485,15 +2937,15 @@
 };
 
 
-static bool GetTagProfile(Isolate* isolate, JSONStream* js) {
+static bool GetTagProfile(Thread* thread, JSONStream* js) {
   JSONObject miniProfile(js);
   miniProfile.AddProperty("type", "TagProfile");
-  isolate->vm_tag_counters()->PrintToJSONObject(&miniProfile);
+  thread->isolate()->vm_tag_counters()->PrintToJSONObject(&miniProfile);
   return true;
 }
 
 
-static const char* tags_enum_names[] = {
+static const char* const tags_enum_names[] = {
   "None",
   "UserVM",
   "UserOnly",
@@ -2503,7 +2955,7 @@
 };
 
 
-static Profile::TagOrder tags_enum_values[] = {
+static const Profile::TagOrder tags_enum_values[] = {
   Profile::kNoTags,
   Profile::kUserVM,
   Profile::kUser,
@@ -2517,19 +2969,53 @@
   ISOLATE_PARAMETER,
   new EnumParameter("tags", true, tags_enum_names),
   new BoolParameter("_codeTransitionTags", false),
+  new Int64Parameter("timeOriginMicros", false),
+  new Int64Parameter("timeExtentMicros", false),
   NULL,
 };
 
 
 // TODO(johnmccutchan): Rename this to GetCpuSamples.
-static bool GetCpuProfile(Isolate* isolate, JSONStream* js) {
+static bool GetCpuProfile(Thread* thread, JSONStream* js) {
   Profile::TagOrder tag_order =
       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
   intptr_t extra_tags = 0;
   if (BoolParameter::Parse(js->LookupParam("_codeTransitionTags"))) {
     extra_tags |= ProfilerService::kCodeTransitionTagsBit;
   }
-  ProfilerService::PrintJSON(js, tag_order, extra_tags);
+  int64_t time_origin_micros =
+      Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
+  int64_t time_extent_micros =
+      Int64Parameter::Parse(js->LookupParam("timeExtentMicros"));
+  ProfilerService::PrintJSON(js,
+                             tag_order,
+                             extra_tags,
+                             time_origin_micros,
+                             time_extent_micros);
+  return true;
+}
+
+
+static const MethodParameter* get_cpu_profile_timeline_params[] = {
+  ISOLATE_PARAMETER,
+  new EnumParameter("tags", true, tags_enum_names),
+  new Int64Parameter("timeOriginMicros", false),
+  new Int64Parameter("timeExtentMicros", false),
+  NULL,
+};
+
+
+static bool GetCpuProfileTimeline(Thread* thread, JSONStream* js) {
+  Profile::TagOrder tag_order =
+      EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
+  int64_t time_origin_micros =
+      UIntParameter::Parse(js->LookupParam("timeOriginMicros"));
+  int64_t time_extent_micros =
+      UIntParameter::Parse(js->LookupParam("timeExtentMicros"));
+  ProfilerService::PrintTimelineJSON(js,
+                                     tag_order,
+                                     time_origin_micros,
+                                     time_extent_micros);
   return true;
 }
 
@@ -2538,19 +3024,30 @@
   ISOLATE_PARAMETER,
   new EnumParameter("tags", true, tags_enum_names),
   new IdParameter("classId", false),
+  new Int64Parameter("timeOriginMicros", false),
+  new Int64Parameter("timeExtentMicros", false),
   NULL,
 };
 
 
-static bool GetAllocationSamples(Isolate* isolate, JSONStream* js) {
+static bool GetAllocationSamples(Thread* thread, JSONStream* js) {
   Profile::TagOrder tag_order =
       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
+  int64_t time_origin_micros =
+      Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
+  int64_t time_extent_micros =
+      Int64Parameter::Parse(js->LookupParam("timeExtentMicros"));
   const char* class_id = js->LookupParam("classId");
   intptr_t cid = -1;
   GetPrefixedIntegerId(class_id, "classes/", &cid);
+  Isolate* isolate = thread->isolate();
   if (IsValidClassId(isolate, cid)) {
     const Class& cls = Class::Handle(GetClassForId(isolate, cid));
-    ProfilerService::PrintAllocationJSON(js, tag_order, cls);
+    ProfilerService::PrintAllocationJSON(js,
+                                         tag_order,
+                                         cls,
+                                         time_origin_micros,
+                                         time_extent_micros);
   } else {
     PrintInvalidParamError(js, "classId");
   }
@@ -2564,7 +3061,7 @@
 };
 
 
-static bool ClearCpuProfile(Isolate* isolate, JSONStream* js) {
+static bool ClearCpuProfile(Thread* thread, JSONStream* js) {
   ProfilerService::ClearSamples();
   PrintSuccess(js);
   return true;
@@ -2577,7 +3074,7 @@
 };
 
 
-static bool GetAllocationProfile(Isolate* isolate, JSONStream* js) {
+static bool GetAllocationProfile(Thread* thread, JSONStream* js) {
   bool should_reset_accumulator = false;
   bool should_collect = false;
   if (js->HasParam("reset")) {
@@ -2596,6 +3093,7 @@
       return true;
     }
   }
+  Isolate* isolate = thread->isolate();
   if (should_reset_accumulator) {
     isolate->UpdateLastAllocationProfileAccumulatorResetTimestamp();
     isolate->class_table()->ResetAllocationAccumulators();
@@ -2615,7 +3113,8 @@
 };
 
 
-static bool GetHeapMap(Isolate* isolate, JSONStream* js) {
+static bool GetHeapMap(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
   isolate->heap()->PrintHeapMapToJSONStream(isolate, js);
   return true;
 }
@@ -2627,9 +3126,9 @@
 };
 
 
-static bool RequestHeapSnapshot(Isolate* isolate, JSONStream* js) {
+static bool RequestHeapSnapshot(Thread* thread, JSONStream* js) {
   if (Service::graph_stream.enabled()) {
-    Service::SendGraphEvent(isolate);
+    Service::SendGraphEvent(thread);
   }
   // TODO(koda): Provide some id that ties this request to async response(s).
   JSONObject jsobj(js);
@@ -2638,10 +3137,10 @@
 }
 
 
-void Service::SendGraphEvent(Isolate* isolate) {
+void Service::SendGraphEvent(Thread* thread) {
   uint8_t* buffer = NULL;
   WriteStream stream(&buffer, &allocator, 1 * MB);
-  ObjectGraph graph(isolate);
+  ObjectGraph graph(thread);
   intptr_t node_count = graph.Serialize(&stream);
 
   // Chrome crashes receiving a single tens-of-megabytes blob, so send the
@@ -2662,7 +3161,7 @@
           JSONObject event(&params, "event");
           event.AddProperty("type", "Event");
           event.AddProperty("kind", "_Graph");
-          event.AddProperty("isolate", isolate);
+          event.AddProperty("isolate", thread->isolate());
           event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis());
 
           event.AddProperty("chunkIndex", i);
@@ -2720,6 +3219,9 @@
                            const Instance& zone,
                            const Object& error,
                            const Instance& stack_trace) {
+  if (!Service::logging_stream.enabled()) {
+    return;
+  }
   ServiceEvent::LogRecord log_record;
   log_record.sequence_number = sequence_number;
   log_record.timestamp = timestamp;
@@ -2735,6 +3237,21 @@
 }
 
 
+void Service::SendExtensionEvent(Isolate* isolate,
+                                 const String& event_kind,
+                                 const String& event_data) {
+  if (!Service::extension_stream.enabled()) {
+    return;
+  }
+  ServiceEvent::ExtensionEvent extension_event;
+  extension_event.event_kind = &event_kind;
+  extension_event.event_data = &event_data;
+  ServiceEvent event(isolate, ServiceEvent::kExtension);
+  event.set_extension_event(extension_event);
+  Service::HandleEvent(&event);
+}
+
+
 class ContainsAddressVisitor : public FindObjectVisitor {
  public:
   ContainsAddressVisitor(Isolate* isolate, uword addr)
@@ -2763,11 +3280,12 @@
 };
 
 
-static RawObject* GetObjectHelper(Isolate* isolate, uword addr) {
-  Object& object = Object::Handle(isolate->current_zone());
+static RawObject* GetObjectHelper(Thread* thread, uword addr) {
+  Object& object = Object::Handle(thread->zone());
 
   {
     NoSafepointScope no_safepoint;
+    Isolate* isolate = thread->isolate();
     ContainsAddressVisitor visitor(isolate, addr);
     object = isolate->heap()->FindObject(&visitor);
   }
@@ -2786,7 +3304,7 @@
 }
 
 
-static bool GetObjectByAddress(Isolate* isolate, JSONStream* js) {
+static bool GetObjectByAddress(Thread* thread, JSONStream* js) {
   const char* addr_str = js->LookupParam("address");
   if (addr_str == NULL) {
     PrintMissingParamError(js, "address");
@@ -2800,8 +3318,8 @@
     return true;
   }
   bool ref = js->HasParam("ref") && js->ParamIs("ref", "true");
-  const Object& obj = Object::Handle(isolate->current_zone(),
-      GetObjectHelper(isolate, addr));
+  const Object& obj = Object::Handle(thread->zone(),
+      GetObjectHelper(thread, addr));
   if (obj.IsNull()) {
     PrintSentinel(js, kFreeSentinel);
   } else {
@@ -2817,15 +3335,14 @@
 };
 
 
-static bool GetPorts(Isolate* isolate, JSONStream* js) {
-  MessageHandler* message_handler = isolate->message_handler();
+static bool GetPorts(Thread* thread, JSONStream* js) {
+  MessageHandler* message_handler = thread->isolate()->message_handler();
   PortMap::PrintPortsForMessageHandler(message_handler, js);
   return true;
 }
 
 
-static bool RespondWithMalformedJson(Isolate* isolate,
-                                      JSONStream* js) {
+static bool RespondWithMalformedJson(Thread* thread, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("a", "a");
   JSONObject jsobj1(js);
@@ -2838,8 +3355,7 @@
 }
 
 
-static bool RespondWithMalformedObject(Isolate* isolate,
-                                        JSONStream* js) {
+static bool RespondWithMalformedObject(Thread* thread, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("bart", "simpson");
   return true;
@@ -2848,21 +3364,39 @@
 
 static const MethodParameter* get_object_params[] = {
   ISOLATE_PARAMETER,
+  new UIntParameter("offset", false),
+  new UIntParameter("count", false),
   NULL,
 };
 
 
-static bool GetObject(Isolate* isolate, JSONStream* js) {
+static bool GetObject(Thread* thread, JSONStream* js) {
   const char* id = js->LookupParam("objectId");
   if (id == NULL) {
     PrintMissingParamError(js, "objectId");
     return true;
   }
+  if (js->HasParam("offset")) {
+    intptr_t value = UIntParameter::Parse(js->LookupParam("offset"));
+    if (value < 0) {
+      PrintInvalidParamError(js, "offset");
+      return true;
+    }
+    js->set_offset(value);
+  }
+  if (js->HasParam("count")) {
+    intptr_t value = UIntParameter::Parse(js->LookupParam("count"));
+    if (value < 0) {
+      PrintInvalidParamError(js, "count");
+      return true;
+    }
+    js->set_count(value);
+  }
 
   // Handle heap objects.
   ObjectIdRing::LookupResult lookup_result;
   const Object& obj =
-      Object::Handle(LookupHeapObject(isolate, id, &lookup_result));
+      Object::Handle(LookupHeapObject(thread, id, &lookup_result));
   if (obj.raw() != Object::sentinel().raw()) {
     // We found a heap object for this id.  Return it.
     obj.PrintJSON(js, false);
@@ -2876,7 +3410,7 @@
   }
 
   // Handle non-heap objects.
-  Breakpoint* bpt = LookupBreakpoint(isolate, id, &lookup_result);
+  Breakpoint* bpt = LookupBreakpoint(thread->isolate(), id, &lookup_result);
   if (bpt != NULL) {
     bpt->PrintJSON(js);
     return true;
@@ -2896,8 +3430,8 @@
 };
 
 
-static bool GetClassList(Isolate* isolate, JSONStream* js) {
-  ClassTable* table = isolate->class_table();
+static bool GetClassList(Thread* thread, JSONStream* js) {
+  ClassTable* table = thread->isolate()->class_table();
   JSONObject jsobj(js);
   table->PrintToJSONObject(&jsobj);
   return true;
@@ -2910,12 +3444,12 @@
 };
 
 
-static bool GetTypeArgumentsList(Isolate* isolate, JSONStream* js) {
+static bool GetTypeArgumentsList(Thread* thread, JSONStream* js) {
   bool only_with_instantiations = false;
   if (js->ParamIs("onlyWithInstantiations", "true")) {
     only_with_instantiations = true;
   }
-  ObjectStore* object_store = isolate->object_store();
+  ObjectStore* object_store = thread->isolate()->object_store();
   const Array& table = Array::Handle(object_store->canonical_type_arguments());
   ASSERT(table.Length() > 0);
   TypeArguments& type_args = TypeArguments::Handle();
@@ -2944,7 +3478,7 @@
 };
 
 
-static bool GetVersion(Isolate* isolate, JSONStream* js) {
+static bool GetVersion(Thread* thread, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "Version");
   jsobj.AddProperty("major", static_cast<intptr_t>(3));
@@ -2993,7 +3527,7 @@
   jsobj.AddProperty("targetCPU", CPU::Id());
   jsobj.AddProperty("hostCPU", HostCPUFeatures::hardware());
   jsobj.AddProperty("version", Version::String());
-  jsobj.AddProperty("pid", OS::ProcessId());
+  jsobj.AddProperty64("pid", OS::ProcessId());
   int64_t start_time_millis = (vm_isolate->start_time() /
                                kMicrosecondsPerMillisecond);
   jsobj.AddPropertyTimeMillis("startTime", start_time_millis);
@@ -3006,7 +3540,7 @@
 }
 
 
-static bool GetVM(Isolate* isolate, JSONStream* js) {
+static bool GetVM(Thread* thread, JSONStream* js) {
   Service::PrintJSONForVM(js, false);
   return true;
 }
@@ -3018,7 +3552,7 @@
 };
 
 
-static bool RestartVM(Isolate* isolate, JSONStream* js) {
+static bool RestartVM(Thread* thread, JSONStream* js) {
   Isolate::KillAllIsolates(Isolate::kVMRestartMsg);
   PrintSuccess(js);
   return true;
@@ -3048,7 +3582,7 @@
 };
 
 
-static bool SetExceptionPauseMode(Isolate* isolate, JSONStream* js) {
+static bool SetExceptionPauseMode(Thread* thread, JSONStream* js) {
   const char* mode = js->LookupParam("mode");
   if (mode == NULL) {
     PrintMissingParamError(js, "mode");
@@ -3060,6 +3594,7 @@
     PrintInvalidParamError(js, "mode");
     return true;
   }
+  Isolate* isolate = thread->isolate();
   isolate->debugger()->SetExceptionPauseInfo(info);
   if (Service::debug_stream.enabled()) {
     ServiceEvent event(isolate, ServiceEvent::kDebuggerSettingsUpdate);
@@ -3076,7 +3611,7 @@
 };
 
 
-static bool GetFlagList(Isolate* isolate, JSONStream* js) {
+static bool GetFlagList(Thread* thread, JSONStream* js) {
   Flags::PrintJSON(js);
   return true;
 }
@@ -3088,7 +3623,7 @@
 };
 
 
-static bool SetFlag(Isolate* isolate, JSONStream* js) {
+static bool SetFlag(Thread* thread, JSONStream* js) {
   const char* flag_name = js->LookupParam("name");
   if (flag_name == NULL) {
     PrintMissingParamError(js, "name");
@@ -3120,10 +3655,10 @@
 };
 
 
-static bool SetLibraryDebuggable(Isolate* isolate, JSONStream* js) {
+static bool SetLibraryDebuggable(Thread* thread, JSONStream* js) {
   const char* lib_id = js->LookupParam("libraryId");
   ObjectIdRing::LookupResult lookup_result;
-  Object& obj = Object::Handle(LookupHeapObject(isolate, lib_id,
+  Object& obj = Object::Handle(LookupHeapObject(thread, lib_id,
                                                 &lookup_result));
   const bool is_debuggable =
       BoolParameter::Parse(js->LookupParam("isDebuggable"), false);
@@ -3145,7 +3680,8 @@
 };
 
 
-static bool SetName(Isolate* isolate, JSONStream* js) {
+static bool SetName(Thread* thread, JSONStream* js) {
+  Isolate* isolate = thread->isolate();
   isolate->set_debugger_name(js->LookupParam("name"));
   if (Service::isolate_stream.enabled()) {
     ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate);
@@ -3162,7 +3698,7 @@
 };
 
 
-static bool SetVMName(Isolate* isolate, JSONStream* js) {
+static bool SetVMName(Thread* thread, JSONStream* js) {
   const char* name_param = js->LookupParam("name");
   free(vm_name);
   vm_name = strdup(name_param);
@@ -3183,11 +3719,17 @@
 };
 
 
-static bool SetTraceClassAllocation(Isolate* isolate, JSONStream* js) {
+static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot trace allocation when running a precompiled program.");
+    return true;
+  }
   const char* class_id = js->LookupParam("classId");
   const bool enable = BoolParameter::Parse(js->LookupParam("enable"));
   intptr_t cid = -1;
   GetPrefixedIntegerId(class_id, "classes/", &cid);
+  Isolate* isolate = thread->isolate();
   if (!IsValidClassId(isolate, cid)) {
     PrintInvalidParamError(js, "classId");
     return true;
@@ -3200,7 +3742,7 @@
 }
 
 
-static ServiceMethodDescriptor service_methods_[] = {
+static const ServiceMethodDescriptor service_methods_[] = {
   { "_dumpIdZone", DumpIdZone, NULL },
   { "_echo", Echo,
     NULL },
@@ -3220,6 +3762,8 @@
     add_breakpoint_at_activation_params },
   { "_clearCpuProfile", ClearCpuProfile,
     clear_cpu_profile_params },
+  { "_clearVMTimeline", ClearVMTimeline,
+    clear_vm_timeline_params, },
   { "evaluate", Evaluate,
     evaluate_params },
   { "evaluateInFrame", EvaluateInFrame,
@@ -3236,6 +3780,8 @@
     get_coverage_params },
   { "_getCpuProfile", GetCpuProfile,
     get_cpu_profile_params },
+  { "_getCpuProfileTimeline", GetCpuProfileTimeline,
+    get_cpu_profile_timeline_params },
   { "getFlagList", GetFlagList,
     get_flag_list_params },
   { "_getHeapMap", GetHeapMap,
@@ -3256,10 +3802,14 @@
     get_object_by_address_params },
   { "_getPorts", GetPorts,
     get_ports_params },
+  { "_getReachableSize", GetReachableSize,
+    get_reachable_size_params },
   { "_getRetainedSize", GetRetainedSize,
     get_retained_size_params },
   { "_getRetainingPath", GetRetainingPath,
     get_retaining_path_params },
+  { "_getSourceReport", GetSourceReport,
+    get_source_report_params },
   { "getStack", GetStack,
     get_stack_params },
   { "_getTagProfile", GetTagProfile,
@@ -3274,6 +3824,10 @@
     get_vm_metric_params },
   { "_getVMMetricList", GetVMMetricList,
     get_vm_metric_list_params },
+  { "_getVMTimeline", GetVMTimeline,
+    get_vm_timeline_params },
+  { "_getVMTimelineFlag", GetVMTimelineFlag,
+    get_vm_timeline_flag_params },
   { "pause", Pause,
     pause_params },
   { "removeBreakpoint", RemoveBreakpoint,
@@ -3296,14 +3850,16 @@
     set_trace_class_allocation_params },
   { "setVMName", SetVMName,
     set_vm_name_params },
+  { "_setVMTimelineFlag", SetVMTimelineFlag,
+    set_vm_timeline_flag_params },
 };
 
 
-ServiceMethodDescriptor* FindMethod(const char* method_name) {
+const ServiceMethodDescriptor* FindMethod(const char* method_name) {
   intptr_t num_methods = sizeof(service_methods_) /
                          sizeof(service_methods_[0]);
   for (intptr_t i = 0; i < num_methods; i++) {
-    ServiceMethodDescriptor& method = service_methods_[i];
+    const ServiceMethodDescriptor& method = service_methods_[i];
     if (strcmp(method_name, method.name) == 0) {
       return &method;
     }
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 3fe90fe..164a94f 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -101,8 +101,11 @@
       Dart_ServiceStreamListenCallback listen_callback,
       Dart_ServiceStreamCancelCallback cancel_callback);
 
+  static void SetGetServiceAssetsCallback(
+      Dart_GetVMServiceAssetsArchive get_service_assets);
+
   static void SendEchoEvent(Isolate* isolate, const char* text);
-  static void SendGraphEvent(Isolate* isolate);
+  static void SendGraphEvent(Thread* thread);
   static void SendInspectEvent(Isolate* isolate, const Object& inspectee);
 
   static void SendEmbedderEvent(Isolate* isolate,
@@ -121,6 +124,10 @@
                            const Object& error,
                            const Instance& stack_trace);
 
+  static void SendExtensionEvent(Isolate* isolate,
+                                 const String& event_kind,
+                                 const String& event_data);
+
   static void PostError(const String& method_name,
                         const Array& parameter_keys,
                         const Array& parameter_values,
@@ -136,10 +143,13 @@
   static StreamInfo echo_stream;
   static StreamInfo graph_stream;
   static StreamInfo logging_stream;
+  static StreamInfo extension_stream;
 
   static bool ListenStream(const char* stream_id);
   static void CancelStream(const char* stream_id);
 
+  static RawObject* RequestAssets();
+
   static Dart_ServiceStreamListenCallback stream_listen_callback() {
     return stream_listen_callback_;
   }
@@ -182,6 +192,7 @@
   static EmbedderServiceHandler* root_service_handler_head_;
   static Dart_ServiceStreamListenCallback stream_listen_callback_;
   static Dart_ServiceStreamCancelCallback stream_cancel_callback_;
+  static Dart_GetVMServiceAssetsArchive get_service_assets_callback_;
 
   static bool needs_isolate_events_;
   static bool needs_debug_events_;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index d0466ef..6d2d894 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -58,6 +58,7 @@
 	- [ErrorKind](#errorkind)
 	- [Event](#event)
 	- [EventKind](#eventkind)
+	- [ExtensionData](#extensiondata)
 	- [Field](#field)
 	- [Flag](#flag)
 	- [FlagList](#flaglist)
@@ -467,7 +468,7 @@
 _targetId_ may refer to a [Library](#library), [Class](#class), or
 [Instance](#instance).
 
-If _targetId_ is a temporary id which has expired, then then _Expired_
+If _targetId_ is a temporary id which has expired, then the _Expired_
 [Sentinel](#sentinel) is returned.
 
 If _targetId_ refers to an object which has been collected by the VM's
@@ -527,13 +528,15 @@
 
 ```
 Object|Sentinel getObject(string isolateId,
-                          string objectId)
+                          string objectId,
+                          int offset [optional],
+                          int count [optional])
 ```
 
 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_
+If _objectId_ is a temporary id which has expired, then the _Expired_
 [Sentinel](#sentinel) is returned.
 
 If _objectId_ refers to a heap object which has been collected by the VM's
@@ -546,6 +549,13 @@
 If the object handle has not expired and the object has not been
 collected, then an [Object](#object) will be returned.
 
+The _offset_ and _count_ parameters are used to request subranges of
+Instance objects with the kinds: List, Map, Uint8ClampedList,
+Uint8List, Uint16List, Uint32List, Uint64List, Int8List, Int16List,
+Int32List, Int64List, Flooat32List, Float64List, Inst32x3List,
+Float32x4List, and Float64x2List.  These parameters are otherwise
+ignored.
+
 ### getStack
 
 ```
@@ -706,9 +716,10 @@
 streamId | event types provided
 -------- | -----------
 VM | VMUpdate
-Isolate | IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate
+Isolate | IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate, ServiceExtensionAdded
 Debug | PauseStart, PauseExit, PauseBreakpoint, PauseInterrupted, PauseException, Resume, BreakpointAdded, BreakpointResolved, BreakpointRemoved, Inspect
 GC | GC
+Extension | Extension
 
 Additionally, some embedders provide the _Stdout_ and _Stderr_
 streams.  These streams allow the client to subscribe to writes to
@@ -1125,6 +1136,26 @@
   //
   // This is provided for the WriteEvent event.
   string bytes [optional];
+
+  // The argument passed to dart:developer.inspect.
+  //
+  // This is provided for the Inspect event.
+  @Instance inspectee [optional];
+
+  // The RPC name of the extension that was added.
+  //
+  // This is provided for the ServiceExtensionAdded event.
+  string extensionRPC [optional];
+
+  // The extension event kind.
+  //
+  // This is provided for the Extension event.
+  string extensionKind [optional];
+
+  // The extension event data.
+  //
+  // This is provided for the Extension event.
+  ExtensionData extensionData [optional];
 }
 ```
 
@@ -1156,6 +1187,9 @@
   // via setName.
   IsolateUpdate,
 
+  // Notification that an extension RPC was registered on an isolate.
+  ServiceExtensionAdded,
+
   // An isolate has paused at start, before executing code.
   PauseStart,
 
@@ -1187,13 +1221,28 @@
   GC,
 
   // Notification of bytes written, for example, to stdout/stderr.
-  WriteEvent
+  WriteEvent,
+
+  // Notification from dart:developer.inspect.
+  Inspect,
+
+  // Event from dart:developer.postEvent.
+  Extension
 }
 ```
 
 Adding new values to _EventKind_ is considered a backwards compatible
 change. Clients should ignore unrecognized events.
 
+### ExtensionData
+
+```
+class ExtensionData {
+}
+```
+
+An _ExtensionData_ is an arbitrary map that can have any contents.
+
 ### Field
 
 ```
@@ -1312,8 +1361,7 @@
   // The name of this function.
   string name;
 
-  // The owner of this field, which can be a Library, Class, or a
-  // Function.
+  // The owner of this function, which can be a Library, Class, or a Function.
   @Library|@Class|@Function owner;
 
   // Is this function static?
@@ -1332,8 +1380,7 @@
   // The name of this function.
   string name;
 
-  // The owner of this field, which can be a Library, Class, or a
-  // Function.
+  // The owner of this function, which can be a Library, Class, or a Function.
   @Library|@Class|@Function owner;
 
   // The location of this function in the source code.
@@ -1374,7 +1421,7 @@
   // this property is added with the value 'true'.
   bool valueAsStringIsTruncated [optional];
 
-  // The length of a List instance.
+  // The length of a List or the number of associations in a Map.
   //
   // Provided for instance kinds:
   //   List
@@ -1447,7 +1494,7 @@
   // this property is added with the value 'true'.
   bool valueAsStringIsTruncated [optional];
 
-  // The length of a List instance.
+  // The length of a List or the number of associations in a Map.
   //
   // Provided for instance kinds:
   //   List
@@ -1468,6 +1515,50 @@
   //   Float64x2List
   int length [optional];
 
+  // The index of the first element or association returned.
+  // This is only provided when it is non-zero.
+  //
+  // Provided for instance kinds:
+  //   List
+  //   Map
+  //   Uint8ClampedList
+  //   Uint8List
+  //   Uint16List
+  //   Uint32List
+  //   Uint64List
+  //   Int8List
+  //   Int16List
+  //   Int32List
+  //   Int64List
+  //   Float32List
+  //   Float64List
+  //   Int32x4List
+  //   Float32x4List
+  //   Float64x2List
+  int offset [optional];
+
+  // The number of elements or associations returned.
+  // This is only provided when it is less than length.
+  //
+  // Provided for instance kinds:
+  //   List
+  //   Map
+  //   Uint8ClampedList
+  //   Uint8List
+  //   Uint16List
+  //   Uint32List
+  //   Uint64List
+  //   Int8List
+  //   Int16List
+  //   Int32List
+  //   Int64List
+  //   Float32List
+  //   Float64List
+  //   Int32x4List
+  //   Float32x4List
+  //   Float64x2List
+  int count [optional];
+
   // The name of a Type instance.
   //
   // Provided for instance kinds:
@@ -1495,7 +1586,7 @@
   //   List
   (@Instance|Sentinel)[] elements [optional];
 
-  // The elements of a List instance.
+  // The elements of a Map instance.
   //
   // Provided for instance kinds:
   //   Map
@@ -1643,7 +1734,7 @@
   Float64x2,
   Int32x4
 
-  // An instance of the built-in VM TypedData implementations.  User-defined
+  // An instance of the built-in VM TypedData implementations. User-defined
   // TypedDatas will be PlainInstance.
   Uint8ClampedList,
   Uint8List,
@@ -1676,16 +1767,16 @@
   // An instance of the Dart class WeakProperty.
   WeakProperty,
 
-  // An instance of the Dart class Type
+  // An instance of the Dart class Type.
   Type,
 
-  // An instance of the Dart class TypeParamer
+  // An instance of the Dart class TypeParameter.
   TypeParameter,
 
-  // An instance of the Dart class TypeRef
+  // An instance of the Dart class TypeRef.
   TypeRef,
 
-  // An instance of the Dart class BoundedType
+  // An instance of the Dart class BoundedType.
   BoundedType,
 }
 ```
@@ -1753,6 +1844,12 @@
 
   // The error that is causing this isolate to exit, if applicable.
   Error error [optional];
+
+  // The current pause on exception mode for this isolate.
+  ExceptionPauseMode exceptionPauseMode;
+
+  // The list of service extension RPCs that are registered for this isolate.
+  string[] extensionRPCs;
 }
 ```
 
@@ -1780,7 +1877,7 @@
   // The uri of this library.
   string uri;
 
-  // Is this library debuggable?  Default true.
+  // Is this library debuggable? Default true.
   bool debuggable;
 
   // A list of the imports for this library.
@@ -2133,15 +2230,15 @@
   // has yet to be loaded.
   string scriptUri [optional];
 
-  // An approximate token position for the source location.  This may
+  // An approximate token position for the source location. This may
   // change when the location is resolved.
   int tokenPos [optional];
 
-  // An approximate line number for the source location.  This may
+  // An approximate line number for the source location. This may
   // change when the location is resolved.
   int line [optional];
 
-  // An approximate column number for the source location.  This may
+  // An approximate column number for the source location. This may
   // change when the location is resolved.
   int column [optional];
 
@@ -2219,7 +2316,7 @@
 ------- | --------
 1.0 | initial revision
 2.0 | Describe protocol version 2.0.
-3.0 | Describe protocol version 3.0.  Added UnresolvedSourceLocation.  Added Sentinel return to getIsolate.  Add AddedBreakpointWithScriptUri.  Removed Isolate.entry. The type of VM.pid was changed from string to int.  Added VMUpdate events.
+3.0 | Describe protocol version 3.0.  Added UnresolvedSourceLocation.  Added Sentinel return to getIsolate.  Add AddedBreakpointWithScriptUri.  Removed Isolate.entry. The type of VM.pid was changed from string to int.  Added VMUpdate events.  Add offset and count parameters to getObject() and offset and count fields to Instance. Added ServiceExtensionAdded event.
 
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 1023043..92b6f43 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -40,6 +40,7 @@
       embedder_stream_id_(NULL),
       breakpoint_(NULL),
       top_frame_(NULL),
+      extension_rpc_(NULL),
       exception_(NULL),
       async_continuation_(NULL),
       at_async_jump_(false),
@@ -62,6 +63,7 @@
       kind_(TranslateEventKind(debugger_event->type())),
       breakpoint_(NULL),
       top_frame_(NULL),
+      extension_rpc_(NULL),
       exception_(NULL),
       async_continuation_(NULL),
       inspectee_(NULL),
@@ -101,6 +103,8 @@
       return "IsolateExit";
     case kIsolateUpdate:
       return "IsolateUpdate";
+    case kServiceExtensionAdded:
+      return "ServiceExtensionAdded";
     case kPauseStart:
       return "PauseStart";
     case kPauseExit:
@@ -131,6 +135,8 @@
       return "_DebuggerSettingsUpdate";
     case kIllegal:
       return "Illegal";
+    case kExtension:
+      return "Extension";
     default:
       UNREACHABLE();
       return "Unknown";
@@ -147,6 +153,7 @@
     case kIsolateRunnable:
     case kIsolateExit:
     case kIsolateUpdate:
+    case kServiceExtensionAdded:
       return Service::isolate_stream.id();
 
     case kPauseStart:
@@ -171,6 +178,9 @@
     case kLogging:
       return Service::logging_stream.id();
 
+    case kExtension:
+      return Service::extension_stream.id();
+
     default:
       UNREACHABLE();
       return NULL;
@@ -181,6 +191,10 @@
 void ServiceEvent::PrintJSON(JSONStream* js) const {
   JSONObject jsobj(js);
   PrintJSONHeader(&jsobj);
+  if (kind() == kServiceExtensionAdded) {
+    ASSERT(extension_rpc_ != NULL);
+    jsobj.AddProperty("extensionRPC", extension_rpc_->ToCString());
+  }
   if (kind() == kPauseBreakpoint) {
     JSONArray jsarr(&jsobj, "pauseBreakpoints");
     // TODO(rmacnak): If we are paused at more than one breakpoint,
@@ -197,7 +211,7 @@
     JSONObject jssettings(&jsobj, "_debuggerSettings");
     isolate()->debugger()->PrintSettingsToJSONObject(&jssettings);
   }
-  if (top_frame() != NULL) {
+  if ((top_frame() != NULL) && Isolate::Current()->compilation_allowed()) {
     JSONObject jsFrame(&jsobj, "topFrame");
     top_frame()->PrintToJSONObject(&jsFrame);
     intptr_t index = 0;  // Avoid ambiguity in call to AddProperty.
@@ -232,6 +246,10 @@
     logRecord.AddProperty("error", *(log_record_.error));
     logRecord.AddProperty("stackTrace", *(log_record_.stack_trace));
   }
+  if (kind() == kExtension) {
+    js->AppendSerializedObject("extensionData",
+                               extension_event_.event_data->ToCString());
+  }
 }
 
 
@@ -239,6 +257,11 @@
   ASSERT(jsobj != NULL);
   jsobj->AddProperty("type", "Event");
   jsobj->AddProperty("kind", KindAsCString());
+  if (kind() == kExtension) {
+    ASSERT(extension_event_.event_kind != NULL);
+    jsobj->AddProperty("extensionKind",
+                       extension_event_.event_kind->ToCString());
+  }
   if (kind() == kVMUpdate) {
     jsobj->AddPropertyVM("vm");
   } else {
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index 71516a6..ed4153b 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -21,6 +21,8 @@
     kIsolateExit,        // Isolate has exited
     kIsolateUpdate,      // Isolate identity information has changed
 
+    kServiceExtensionAdded,  // A service extension was registered
+
     kPauseStart,         // --pause-isolates-on-start
     kPauseExit,          // --pause-isolates-on-exit
     kPauseBreakpoint,
@@ -39,6 +41,8 @@
 
     kLogging,
 
+    kExtension,
+
     kIllegal,
   };
 
@@ -53,6 +57,11 @@
     const Instance* stack_trace;
   };
 
+  struct ExtensionEvent {
+    const String* event_kind;
+    const String* event_data;
+  };
+
   ServiceEvent(Isolate* isolate, EventKind event_kind);
 
   explicit ServiceEvent(const DebuggerEvent* debugger_event);
@@ -97,6 +106,13 @@
     top_frame_ = frame;
   }
 
+  const String* extension_rpc() const {
+    return extension_rpc_;
+  }
+  void set_extension_rpc(const String* extension_rpc) {
+    extension_rpc_ = extension_rpc;
+  }
+
   const Object* exception() const {
     return exception_;
   }
@@ -153,6 +169,10 @@
     log_record_ = log_record;
   }
 
+  void set_extension_event(const ExtensionEvent& extension_event) {
+    extension_event_ = extension_event;
+  }
+
   int64_t timestamp() const {
     return timestamp_;
   }
@@ -168,6 +188,7 @@
   const char* embedder_stream_id_;
   Breakpoint* breakpoint_;
   ActivationFrame* top_frame_;
+  const String* extension_rpc_;
   const Object* exception_;
   const Object* async_continuation_;
   bool at_async_jump_;
@@ -176,6 +197,7 @@
   const uint8_t* bytes_;
   intptr_t bytes_length_;
   LogRecord log_record_;
+  ExtensionEvent extension_event_;
   int64_t timestamp_;
 };
 
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index cb92d3a..a316c6c 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -255,7 +255,6 @@
 void ServiceIsolate::ConstructExitMessageAndCache(Isolate* I) {
   // Construct and cache exit message here so we can send it without needing an
   // isolate.
-  StartIsolateScope iso_scope(I);
   Thread* T = Thread::Current();
   ASSERT(I == T->isolate());
   ASSERT(I != NULL);
@@ -319,16 +318,17 @@
                                                    &error));
     if (isolate == NULL) {
       OS::PrintErr("vm-service: Isolate creation error: %s\n", error);
+      ServiceIsolate::SetServiceIsolate(NULL);
       ServiceIsolate::FinishedInitializing();
       return;
     }
 
-
-    Thread::ExitIsolate();
-
-    ServiceIsolate::ConstructExitMessageAndCache(isolate);
-
-    RunMain(isolate);
+    {
+      ASSERT(Isolate::Current() == NULL);
+      StartIsolateScope start_scope(isolate);
+      ServiceIsolate::ConstructExitMessageAndCache(isolate);
+      RunMain(isolate);
+    }
 
     ServiceIsolate::FinishedInitializing();
 
@@ -344,9 +344,11 @@
     ASSERT(ServiceIsolate::IsServiceIsolate(I));
     ServiceIsolate::SetServiceIsolate(NULL);
     ServiceIsolate::SetServicePort(ILLEGAL_PORT);
+    I->WaitForOutstandingSpawns();
     {
       // Print the error if there is one.  This may execute dart code to
       // print the exception object, so we need to use a StartIsolateScope.
+      ASSERT(Isolate::Current() == NULL);
       StartIsolateScope start_scope(I);
       Thread* T = Thread::Current();
       ASSERT(I == T->isolate());
@@ -359,11 +361,8 @@
       }
       Dart::RunShutdownCallback();
     }
-    {
-      // Shut the isolate down.
-      SwitchIsolateScope switch_scope(I);
-      Dart::ShutdownIsolate();
-    }
+    // Shut the isolate down.
+    Dart::ShutdownIsolate(I);
     if (FLAG_trace_service) {
       OS::Print("vm-service: Shutdown.\n");
     }
@@ -371,7 +370,6 @@
   }
 
   void RunMain(Isolate* I) {
-    StartIsolateScope iso_scope(I);
     Thread* T = Thread::Current();
     ASSERT(I == T->isolate());
     StackZone zone(T);
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index de6a0d8..d55fe3b 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -35,10 +35,15 @@
     }
 
     // Parse the message.
-    Thread* thread = Thread::Current();
-    MessageSnapshotReader reader(message->data(), message->len(), thread);
-    const Object& response_obj = Object::Handle(reader.ReadObject());
     String& response = String::Handle();
+    Object& response_obj = Object::Handle();
+    if (message->IsRaw()) {
+      response_obj = message->raw_obj();
+    } else {
+      Thread* thread = Thread::Current();
+      MessageSnapshotReader reader(message->data(), message->len(), thread);
+      response_obj = reader.ReadObject();
+    }
     response ^= response_obj.raw();
     _msg = strdup(response.ToCString());
     return kOK;
@@ -46,6 +51,8 @@
 
   const char* msg() const { return _msg; }
 
+  virtual Isolate* isolate() const { return Isolate::Current(); }
+
  private:
   char* _msg;
 };
@@ -159,7 +166,7 @@
       "  x();\n"
       "}";
 
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Library& vmlib = Library::Handle();
@@ -182,7 +189,7 @@
   // Build a mock message handler and wrap it in a dart port.
   ServiceTestMessageHandler handler;
   Dart_Port port_id = PortMap::CreatePort(&handler);
-  Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id));
+  Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id));
   EXPECT_VALID(port);
   EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
 
@@ -265,7 +272,7 @@
       "main() {\n"
       "}";
 
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
@@ -286,7 +293,7 @@
   // Build a mock message handler and wrap it in a dart port.
   ServiceTestMessageHandler handler;
   Dart_Port port_id = PortMap::CreatePort(&handler);
-  Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id));
+  Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id));
   EXPECT_VALID(port);
   EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
 
@@ -324,7 +331,7 @@
     "  x();\n"
     "}";
 
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Library& vmlib = Library::Handle();
@@ -348,7 +355,7 @@
   // Build a mock message handler and wrap it in a dart port.
   ServiceTestMessageHandler handler;
   Dart_Port port_id = PortMap::CreatePort(&handler);
-  Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id));
+  Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id));
   EXPECT_VALID(port);
   EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
 
@@ -385,7 +392,7 @@
     "  x();\n"
     "}";
 
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Library& vmlib = Library::Handle();
@@ -409,7 +416,7 @@
   // Build a mock message handler and wrap it in a dart port.
   ServiceTestMessageHandler handler;
   Dart_Port port_id = PortMap::CreatePort(&handler);
-  Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id));
+  Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id));
   EXPECT_VALID(port);
   EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
 
@@ -435,14 +442,14 @@
       "main() {\n"
       "}";
 
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
 
   // Build a mock message handler and wrap it in a dart port.
   ServiceTestMessageHandler handler;
   Dart_Port port_id = PortMap::CreatePort(&handler);
-  Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id));
+  Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id));
   EXPECT_VALID(port);
   EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
 
@@ -516,7 +523,6 @@
   Dart_RegisterRootServiceRequestCallback("alpha", alpha_callback, NULL);
   Dart_RegisterRootServiceRequestCallback("beta", beta_callback, NULL);
 
-  Isolate* isolate = Isolate::Current();
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -525,7 +531,7 @@
   // Build a mock message handler and wrap it in a dart port.
   ServiceTestMessageHandler handler;
   Dart_Port port_id = PortMap::CreatePort(&handler);
-  Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id));
+  Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id));
   EXPECT_VALID(port);
   EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
 
@@ -557,7 +563,7 @@
   Dart_RegisterIsolateServiceRequestCallback("alpha", alpha_callback, NULL);
   Dart_RegisterIsolateServiceRequestCallback("beta", beta_callback, NULL);
 
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -566,7 +572,7 @@
   // Build a mock message handler and wrap it in a dart port.
   ServiceTestMessageHandler handler;
   Dart_Port port_id = PortMap::CreatePort(&handler);
-  Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id));
+  Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id));
   EXPECT_VALID(port);
   EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
 
@@ -596,7 +602,7 @@
       "  x = x / 13;\n"
       "}";
 
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = thread->isolate();
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -605,7 +611,7 @@
   // Build a mock message handler and wrap it in a dart port.
   ServiceTestMessageHandler handler;
   Dart_Port port_id = PortMap::CreatePort(&handler);
-  Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id));
+  Dart_Handle port = Api::NewHandle(thread, SendPort::New(port_id));
   EXPECT_VALID(port);
   EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
 
diff --git a/runtime/vm/signal_handler_android.cc b/runtime/vm/signal_handler_android.cc
index 6540751..a85dbb7 100644
--- a/runtime/vm/signal_handler_android.cc
+++ b/runtime/vm/signal_handler_android.cc
@@ -66,7 +66,7 @@
 #elif defined(HOST_ARCH_ARM)
   sp = static_cast<uintptr_t>(mcontext.arm_sp);
 #elif defined(HOST_ARCH_ARM64)
-  sp = static_cast<uintptr_t>(mcontext.regs[18]);
+  sp = static_cast<uintptr_t>(mcontext.regs[19]);
 #else
 #error Unsupported architecture.
 #endif  // HOST_ARCH_...
diff --git a/runtime/vm/signal_handler_linux.cc b/runtime/vm/signal_handler_linux.cc
index 45fa50d..b49f90a 100644
--- a/runtime/vm/signal_handler_linux.cc
+++ b/runtime/vm/signal_handler_linux.cc
@@ -72,7 +72,7 @@
 
 uintptr_t SignalHandler::GetDartStackPointer(const mcontext_t& mcontext) {
 #if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
-  return static_cast<uintptr_t>(mcontext.regs[18]);
+  return static_cast<uintptr_t>(mcontext.regs[19]);
 #else
   return GetCStackPointer(mcontext);
 #endif
diff --git a/runtime/vm/signal_handler_macos.cc b/runtime/vm/signal_handler_macos.cc
index e0a2a14..ca6e64d 100644
--- a/runtime/vm/signal_handler_macos.cc
+++ b/runtime/vm/signal_handler_macos.cc
@@ -36,7 +36,7 @@
 #elif defined(HOST_ARCH_X64)
   fp = static_cast<uintptr_t>(mcontext->__ss.__rbp);
 #elif defined(HOST_ARCH_ARM)
-  fp = static_cast<uintptr_t>(mcontext->__ss.__r[11]);
+  fp = static_cast<uintptr_t>(mcontext->__ss.__r[7]);
 #elif defined(HOST_ARCH_ARM64)
   fp = static_cast<uintptr_t>(mcontext->__ss.__fp);
 #else
@@ -67,7 +67,11 @@
 
 
 uintptr_t SignalHandler::GetDartStackPointer(const mcontext_t& mcontext) {
+#if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
+  return static_cast<uintptr_t>(mcontext->__ss.__x[19]);
+#else
   return GetCStackPointer(mcontext);
+#endif
 }
 
 
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 531ed4a..b65ae80 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -145,7 +145,7 @@
       R8,  R9,  R10, R11,
       R12, R13, R14, R15,
       PC,  LR,  SP,  IP,
-      FP,  R10, R9
+      FP,  PP,  CTX
   };
   ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
   for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
@@ -700,8 +700,8 @@
   // the size specified by the user and the buffer space needed for
   // handling stack overflow exceptions. To be safe in potential
   // stack underflows we also add some underflow buffer space.
-  stack_ = new char[(Isolate::GetSpecifiedStackSize() +
-                     Isolate::kStackSizeBuffer +
+  stack_ = new char[(OSThread::GetSpecifiedStackSize() +
+                     OSThread::kStackSizeBuffer +
                      kSimulatorStackUnderflowSize)];
   pc_modified_ = false;
   icount_ = 0;
@@ -1171,13 +1171,23 @@
 }
 
 
+uint32_t Simulator::CompareExchangeUint32(uint32_t* address,
+                                          uint32_t compare_value,
+                                          uint32_t new_value) {
+  COMPILE_ASSERT(sizeof(uword) == sizeof(uint32_t));
+  return CompareExchange(reinterpret_cast<uword*>(address),
+                         static_cast<uword>(compare_value),
+                         static_cast<uword>(new_value));
+}
+
+
 // Returns the top of the stack area to enable checking for stack pointer
 // validity.
 uword Simulator::StackTop() const {
   // To be safe in potential stack underflows we leave some buffer above and
   // set the stack top.
   return StackBase() +
-      (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer);
+      (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer);
 }
 
 
@@ -3738,7 +3748,9 @@
   int32_t r6_val = get_register(R6);
   int32_t r7_val = get_register(R7);
   int32_t r8_val = get_register(R8);
+#if !defined(TARGET_OS_MACOS)
   int32_t r9_val = get_register(R9);
+#endif
   int32_t r10_val = get_register(R10);
   int32_t r11_val = get_register(R11);
 
@@ -3770,7 +3782,9 @@
   set_register(R6, callee_saved_value);
   set_register(R7, callee_saved_value);
   set_register(R8, callee_saved_value);
+#if !defined(TARGET_OS_MACOS)
   set_register(R9, callee_saved_value);
+#endif
   set_register(R10, callee_saved_value);
   set_register(R11, callee_saved_value);
 
@@ -3796,7 +3810,9 @@
   ASSERT(callee_saved_value == get_register(R6));
   ASSERT(callee_saved_value == get_register(R7));
   ASSERT(callee_saved_value == get_register(R8));
+#if !defined(TARGET_OS_MACOS)
   ASSERT(callee_saved_value == get_register(R9));
+#endif
   ASSERT(callee_saved_value == get_register(R10));
   ASSERT(callee_saved_value == get_register(R11));
 
@@ -3817,7 +3833,9 @@
   set_register(R6, r6_val);
   set_register(R7, r7_val);
   set_register(R8, r8_val);
+#if !defined(TARGET_OS_MACOS)
   set_register(R9, r9_val);
+#endif
   set_register(R10, r10_val);
   set_register(R11, r11_val);
 
@@ -3862,7 +3880,6 @@
   // 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(thread);
 
   // Unwind the C++ stack and continue simulation in the target frame.
@@ -3873,7 +3890,7 @@
   // Set the tag.
   thread->set_vm_tag(VMTag::kDartTagId);
   // Clear top exit frame.
-  isolate->set_top_exit_frame_info(0);
+  thread->set_top_exit_frame_info(0);
 
   ASSERT(raw_exception != Object::null());
   set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index 3976c0c..af3cb09 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -107,6 +107,9 @@
   static uword CompareExchange(uword* address,
                                uword compare_value,
                                uword new_value);
+  static uint32_t CompareExchangeUint32(uint32_t* address,
+                                        uint32_t compare_value,
+                                        uint32_t new_value);
 
   // Runtime and native call support.
   enum CallKind {
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index ac6fe18..e0df115 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -746,8 +746,8 @@
   // the size specified by the user and the buffer space needed for
   // handling stack overflow exceptions. To be safe in potential
   // stack underflows we also add some underflow buffer space.
-  stack_ = new char[(Isolate::GetSpecifiedStackSize() +
-                     Isolate::kStackSizeBuffer +
+  stack_ = new char[(OSThread::GetSpecifiedStackSize() +
+                     OSThread::kStackSizeBuffer +
                      kSimulatorStackUnderflowSize)];
   pc_modified_ = false;
   icount_ = 0;
@@ -900,6 +900,7 @@
     Instr* instr, Register reg, int64_t value, R31Type r31t) {
   // Register is in range.
   ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
+  ASSERT(instr == NULL || reg != R18);  // R18 is globally reserved on iOS.
   if ((reg != R31) || (r31t != R31IsZR)) {
     registers_[reg] = value;
     // If we're setting CSP, make sure it is 16-byte aligned. In truth, CSP
@@ -1054,7 +1055,7 @@
   // To be safe in potential stack underflows we leave some buffer above and
   // set the stack top.
   return StackBase() +
-      (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer);
+      (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer);
 }
 
 
@@ -1252,6 +1253,26 @@
 }
 
 
+uint32_t Simulator::CompareExchangeUint32(uint32_t* address,
+                                          uint32_t compare_value,
+                                          uint32_t new_value) {
+  MutexLocker ml(exclusive_access_lock_);
+  // We do not get a reservation as it would be guaranteed to be found when
+  // writing below. No other thread is able to make a reservation while we
+  // hold the lock.
+  uint32_t value = *address;
+  if (value == compare_value) {
+    *address = new_value;
+    // Same effect on exclusive access state as a successful STREX.
+    HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address));
+  } else {
+    // Same effect on exclusive access state as an LDREX.
+    SetExclusiveAccess(reinterpret_cast<uword>(address));
+  }
+  return value;
+}
+
+
 // Unsupported instructions use Format to print an error and stop execution.
 void Simulator::Format(Instr* instr, const char* format) {
   OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n",
@@ -1650,24 +1671,24 @@
 
     // Zap caller-saved registers, since the actual runtime call could have
     // used them.
-    set_register(instr, R2, icount_);
-    set_register(instr, R3, icount_);
-    set_register(instr, R4, icount_);
-    set_register(instr, R5, icount_);
-    set_register(instr, R6, icount_);
-    set_register(instr, R7, icount_);
-    set_register(instr, R8, icount_);
-    set_register(instr, R9, icount_);
-    set_register(instr, R10, icount_);
-    set_register(instr, R11, icount_);
-    set_register(instr, R12, icount_);
-    set_register(instr, R13, icount_);
-    set_register(instr, R14, icount_);
-    set_register(instr, R15, icount_);
-    set_register(instr, IP0, icount_);
-    set_register(instr, IP1, icount_);
-    set_register(instr, R18, icount_);
-    set_register(instr, LR, icount_);
+    set_register(NULL, R2, icount_);
+    set_register(NULL, R3, icount_);
+    set_register(NULL, R4, icount_);
+    set_register(NULL, R5, icount_);
+    set_register(NULL, R6, icount_);
+    set_register(NULL, R7, icount_);
+    set_register(NULL, R8, icount_);
+    set_register(NULL, R9, icount_);
+    set_register(NULL, R10, icount_);
+    set_register(NULL, R11, icount_);
+    set_register(NULL, R12, icount_);
+    set_register(NULL, R13, icount_);
+    set_register(NULL, R14, icount_);
+    set_register(NULL, R15, icount_);
+    set_register(NULL, IP0, icount_);
+    set_register(NULL, IP1, icount_);
+    set_register(NULL, R18, icount_);
+    set_register(NULL, LR, icount_);
 
     // TODO(zra): Zap caller-saved fpu registers.
 
@@ -3519,7 +3540,6 @@
   // 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(thread);
 
   // Unwind the C++ stack and continue simulation in the target frame.
@@ -3530,7 +3550,7 @@
   // Set the tag.
   thread->set_vm_tag(VMTag::kDartTagId);
   // Clear top exit frame.
-  isolate->set_top_exit_frame_info(0);
+  thread->set_top_exit_frame_info(0);
 
   ASSERT(raw_exception != Object::null());
   set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception));
diff --git a/runtime/vm/simulator_arm64.h b/runtime/vm/simulator_arm64.h
index d23e83b..d395f6b 100644
--- a/runtime/vm/simulator_arm64.h
+++ b/runtime/vm/simulator_arm64.h
@@ -102,6 +102,9 @@
   static uword CompareExchange(uword* address,
                                uword compare_value,
                                uword new_value);
+  static uint32_t CompareExchangeUint32(uint32_t* address,
+                                        uint32_t compare_value,
+                                        uint32_t new_value);
 
   // Runtime and native call support.
   enum CallKind {
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index a6bd8de..f8007ed 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -699,8 +699,8 @@
   // the size specified by the user and the buffer space needed for
   // handling stack overflow exceptions. To be safe in potential
   // stack underflows we also add some underflow buffer space.
-  stack_ = new char[(Isolate::GetSpecifiedStackSize() +
-                     Isolate::kStackSizeBuffer +
+  stack_ = new char[(OSThread::GetSpecifiedStackSize() +
+                     OSThread::kStackSizeBuffer +
                      kSimulatorStackUnderflowSize)];
   icount_ = 0;
   delay_slot_ = false;
@@ -997,7 +997,7 @@
   // To be safe in potential stack underflows we leave some buffer above and
   // set the stack top.
   return StackBase() +
-      (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer);
+      (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer);
 }
 
 
@@ -1191,6 +1191,16 @@
 }
 
 
+uint32_t Simulator::CompareExchangeUint32(uint32_t* address,
+                                          uint32_t compare_value,
+                                          uint32_t new_value) {
+  COMPILE_ASSERT(sizeof(uword) == sizeof(uint32_t));
+  return CompareExchange(reinterpret_cast<uword*>(address),
+                         static_cast<uword>(compare_value),
+                         static_cast<uword>(new_value));
+}
+
+
 // Calls into the Dart runtime are based on this interface.
 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
 
@@ -1813,6 +1823,12 @@
         set_fregister_double(instr->FdField(), fs_val);
         break;
       }
+      case COP1_NEG: {
+        // Format(instr, "neg.'fmt 'fd, 'fs");
+        ASSERT(instr->FormatField() == FMT_D);
+        set_fregister_double(instr->FdField(), -fs_val);
+        break;
+      }
       case COP1_C_F: {
         ASSERT(instr->FormatField() == FMT_D);  // Only D supported.
         ASSERT(instr->FdField() == F0);
@@ -2467,7 +2483,6 @@
   // 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(thread);
 
   // Unwind the C++ stack and continue simulation in the target frame.
@@ -2478,7 +2493,7 @@
   // Set the tag.
   thread->set_vm_tag(VMTag::kDartTagId);
   // Clear top exit frame.
-  isolate->set_top_exit_frame_info(0);
+  thread->set_top_exit_frame_info(0);
 
   ASSERT(raw_exception != Object::null());
   set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
diff --git a/runtime/vm/simulator_mips.h b/runtime/vm/simulator_mips.h
index b4807bf..8d10c3f 100644
--- a/runtime/vm/simulator_mips.h
+++ b/runtime/vm/simulator_mips.h
@@ -121,6 +121,9 @@
   static uword CompareExchange(uword* address,
                                uword compare_value,
                                uword new_value);
+  static uint32_t CompareExchangeUint32(uint32_t* address,
+                                        uint32_t compare_value,
+                                        uint32_t new_value);
 
   // Runtime and native call support.
   enum CallKind {
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index d496aaa..a57296f 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -194,7 +194,7 @@
       library_(Library::Handle(zone_)),
       type_(AbstractType::Handle(zone_)),
       type_arguments_(TypeArguments::Handle(zone_)),
-      tokens_(Array::Handle(zone_)),
+      tokens_(GrowableObjectArray::Handle(zone_)),
       stream_(TokenStream::Handle(zone_)),
       data_(ExternalTypedData::Handle(zone_)),
       typed_data_(TypedData::Handle(zone_)),
@@ -398,60 +398,25 @@
                                           intptr_t patch_offset) {
   if (IsVMIsolateObject(header_value)) {
     return ReadVMIsolateObject(header_value);
-  } else {
-    if (SerializedHeaderTag::decode(header_value) == kObjectId) {
-      return ReadIndexedObject(SerializedHeaderData::decode(header_value),
-                               patch_object_id,
-                               patch_offset);
-    }
-    ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
-    intptr_t object_id = SerializedHeaderData::decode(header_value);
-    if (object_id == kOmittedObjectId) {
-      object_id = NextAvailableObjectId();
-    }
-
-    // Read the class header information.
-    intptr_t class_header = Read<int32_t>();
-    intptr_t tags = ReadTags();
-    if (as_reference && !RawObject::IsCanonical(tags)) {
-      return ReadObjectRef(object_id,
-                           class_header,
-                           tags,
-                           patch_object_id,
-                           patch_offset);
-    }
-    return ReadInlinedObject(object_id,
-                             class_header,
-                             tags,
+  }
+  if (SerializedHeaderTag::decode(header_value) == kObjectId) {
+    return ReadIndexedObject(SerializedHeaderData::decode(header_value),
                              patch_object_id,
                              patch_offset);
   }
-}
+  ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
+  intptr_t object_id = SerializedHeaderData::decode(header_value);
+  if (object_id == kOmittedObjectId) {
+    object_id = NextAvailableObjectId();
+  }
 
-
-RawObject* SnapshotReader::ReadObjectRef(intptr_t object_id,
-                                         intptr_t class_header,
-                                         intptr_t tags,
-                                         intptr_t patch_object_id,
-                                         intptr_t patch_offset) {
-  // Since we are only reading an object reference, If it is an instance kind
-  // then we only need to figure out the class of the object and allocate an
-  // instance of it. The individual fields will be read later.
+  // Read the class header information.
+  intptr_t class_header = Read<int32_t>();
+  intptr_t tags = ReadTags();
+  bool read_as_reference = as_reference && !RawObject::IsCanonical(tags);
   intptr_t header_id = SerializedHeaderData::decode(class_header);
   if (header_id == kInstanceObjectId) {
-    Instance& result = Instance::ZoneHandle(zone(), Instance::null());
-    AddBackRef(object_id, &result, kIsNotDeserialized);
-
-    cls_ ^= ReadObjectImpl(kAsInlinedObject);  // Read class information.
-    ASSERT(!cls_.IsNull());
-    intptr_t instance_size = cls_.instance_size();
-    ASSERT(instance_size > 0);
-    if (kind_ == Snapshot::kFull) {
-      result ^= AllocateUninitialized(cls_.id(), instance_size);
-    } else {
-      result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_));
-    }
-    return result.raw();
+    return ReadInstance(object_id, tags, read_as_reference);
   } else if (header_id == kStaticImplicitClosureObjectId) {
     // We skip the tags that have been written as the implicit static
     // closure is going to be created in this isolate or the canonical
@@ -460,57 +425,22 @@
   }
   ASSERT((class_header & kSmiTagMask) != kSmiTag);
 
-  // Similarly Array and ImmutableArray objects are also similarly only
-  // allocated here, the individual array elements are read later.
   intptr_t class_id = LookupInternalClass(class_header);
-  if (class_id == kArrayCid) {
-    // Read the length and allocate an object based on the len.
-    intptr_t len = ReadSmiValue();
-    Array& array = Array::ZoneHandle(
-        zone(),
-        ((kind_ == Snapshot::kFull) ?
-         NewArray(len) : Array::New(len, HEAP_SPACE(kind_))));
-    AddBackRef(object_id, &array, kIsNotDeserialized);
-
-    return array.raw();
-  }
-  if (class_id == kImmutableArrayCid) {
-    // Read the length and allocate an object based on the len.
-    intptr_t len = ReadSmiValue();
-    Array& array = Array::ZoneHandle(
-        zone(),
-        (kind_ == Snapshot::kFull) ?
-        NewImmutableArray(len) : ImmutableArray::New(len, HEAP_SPACE(kind_)));
-    AddBackRef(object_id, &array, kIsNotDeserialized);
-
-    return array.raw();
-  }
-  if (class_id == kObjectPoolCid) {
-    ASSERT(kind_ == Snapshot::kFull);
-    // Read the length and allocate an object based on the len.
-    intptr_t len = Read<intptr_t>();
-    ObjectPool& pool = ObjectPool::ZoneHandle(zone(),
-                                              NewObjectPool(len));
-    AddBackRef(object_id, &pool, kIsNotDeserialized);
-
-    return pool.raw();
-  }
-
-  // For all other internal VM classes we read the object inline.
   switch (class_id) {
 #define SNAPSHOT_READ(clazz)                                                   \
     case clazz::kClassId: {                                                    \
-      pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, true);             \
+      pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, read_as_reference);\
       break;                                                                   \
     }
     CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
 #undef SNAPSHOT_READ
 #define SNAPSHOT_READ(clazz)                                                   \
-    case kTypedData##clazz##Cid:                                               \
+        case kTypedData##clazz##Cid:                                           \
 
     CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
       tags = RawObject::ClassIdTag::update(class_id, tags);
-      pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_, true);
+      pobj_ = TypedData::ReadFrom(
+          this, object_id, tags, kind_, read_as_reference);
       break;
     }
 #undef SNAPSHOT_READ
@@ -525,53 +455,58 @@
 #undef SNAPSHOT_READ
     default: UNREACHABLE(); break;
   }
+  if (!read_as_reference) {
+    AddPatchRecord(object_id, patch_object_id, patch_offset);
+  }
   return pobj_.raw();
 }
 
 
-RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id,
-                                             intptr_t class_header,
-                                             intptr_t tags,
-                                             intptr_t patch_object_id,
-                                             intptr_t patch_offset) {
-  // Lookup the class based on the class header information.
-  intptr_t header_id = SerializedHeaderData::decode(class_header);
-  if (header_id == kInstanceObjectId) {
-    // Object is regular dart instance.
-    Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id));
-    intptr_t instance_size = 0;
-    if (result == NULL) {
-      result = &(Instance::ZoneHandle(zone(), Instance::null()));
-      AddBackRef(object_id, result, kIsDeserialized);
-      cls_ ^= ReadObjectImpl(kAsInlinedObject);
-      ASSERT(!cls_.IsNull());
-      instance_size = cls_.instance_size();
-      ASSERT(instance_size > 0);
-      // Allocate the instance and read in all the fields for the object.
-      if (kind_ == Snapshot::kFull) {
-        *result ^= AllocateUninitialized(cls_.id(), instance_size);
-      } else {
-        *result ^= Object::Allocate(cls_.id(),
-                                    instance_size,
-                                    HEAP_SPACE(kind_));
-      }
+RawObject* SnapshotReader::ReadInstance(intptr_t object_id,
+                                        intptr_t tags,
+                                        bool as_reference) {
+  // Object is regular dart instance.
+  intptr_t instance_size = 0;
+  Instance* result = NULL;
+  DeserializeState state;
+  if (!as_reference) {
+    result = reinterpret_cast<Instance*>(GetBackRef(object_id));
+    state = kIsDeserialized;
+  } else {
+    state = kIsNotDeserialized;
+  }
+  if (result == NULL) {
+    result = &(Instance::ZoneHandle(zone(), Instance::null()));
+    AddBackRef(object_id, result, state);
+    cls_ ^= ReadObjectImpl(kAsInlinedObject);
+    ASSERT(!cls_.IsNull());
+    instance_size = cls_.instance_size();
+    ASSERT(instance_size > 0);
+    // Allocate the instance and read in all the fields for the object.
+    if (kind_ == Snapshot::kFull) {
+      *result ^= AllocateUninitialized(cls_.id(), instance_size);
     } else {
-      cls_ ^= ReadObjectImpl(kAsInlinedObject);
-      ASSERT(!cls_.IsNull());
-      instance_size = cls_.instance_size();
+      *result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_));
     }
+  } else {
+    cls_ ^= ReadObjectImpl(kAsInlinedObject);
+    ASSERT(!cls_.IsNull());
+    instance_size = cls_.instance_size();
+  }
+  if (!as_reference) {
+    // Read all the individual fields for inlined objects.
     intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw())
-      ? Closure::InstanceSize() : cls_.next_field_offset();
+        ? Closure::InstanceSize() : cls_.next_field_offset();
 
     intptr_t type_argument_field_offset = cls_.type_arguments_field_offset();
     ASSERT(next_field_offset > 0);
     // Instance::NextFieldOffset() returns the offset of the first field in
     // a Dart object.
-    bool as_reference = RawObject::IsCanonical(tags) ? false : true;
+    bool read_as_reference = RawObject::IsCanonical(tags) ? false : true;
     intptr_t offset = Instance::NextFieldOffset();
     intptr_t result_cid = result->GetClassId();
     while (offset < next_field_offset) {
-      pobj_ = ReadObjectImpl(as_reference);
+      pobj_ = ReadObjectImpl(read_as_reference);
       result->SetFieldAtOffset(offset, pobj_);
       if ((offset != type_argument_field_offset) &&
           (kind_ == Snapshot::kMessage)) {
@@ -606,45 +541,8 @@
         ASSERT(!result->IsNull());
       }
     }
-    return result->raw();
-  } else if (header_id == kStaticImplicitClosureObjectId) {
-    // We do not use the tags as the implicit static closure
-    // is going to be created in this isolate or the canonical
-    // version already created in the isolate will be used.
-    return ReadStaticImplicitClosure(object_id, class_header);
   }
-  ASSERT((class_header & kSmiTagMask) != kSmiTag);
-  intptr_t class_id = LookupInternalClass(class_header);
-  switch (class_id) {
-#define SNAPSHOT_READ(clazz)                                                   \
-    case clazz::kClassId: {                                                    \
-      pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, false);            \
-      break;                                                                   \
-    }
-    CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz)                                                   \
-    case kTypedData##clazz##Cid:                                               \
-
-    CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
-      tags = RawObject::ClassIdTag::update(class_id, tags);
-      pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_, false);
-      break;
-    }
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz)                                                   \
-    case kExternalTypedData##clazz##Cid:                                       \
-
-    CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
-      tags = RawObject::ClassIdTag::update(class_id, tags);
-      pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, false);
-      break;
-    }
-#undef SNAPSHOT_READ
-    default: UNREACHABLE(); break;
-  }
-  AddPatchRecord(object_id, patch_object_id, patch_offset);
-  return pobj_.raw();
+  return result->raw();
 }
 
 
@@ -675,8 +573,8 @@
 
 class HeapLocker : public StackResource {
  public:
-  HeapLocker(Isolate* isolate, PageSpace* page_space)
-      : StackResource(isolate), page_space_(page_space) {
+  HeapLocker(Thread* thread, PageSpace* page_space)
+      : StackResource(thread), page_space_(page_space) {
         page_space_->AcquireDataLock();
   }
   ~HeapLocker() {
@@ -690,7 +588,8 @@
 
 RawApiError* SnapshotReader::ReadFullSnapshot() {
   ASSERT(kind_ == Snapshot::kFull);
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   ObjectStore* object_store = isolate->object_store();
   ASSERT(object_store != NULL);
@@ -707,7 +606,7 @@
   // size for the full snapshot being read.
   {
     NoSafepointScope no_safepoint;
-    HeapLocker hl(isolate, old_space());
+    HeapLocker hl(thread, old_space());
 
     // Read in all the objects stored in the object store.
     RawObject** toobj = snapshot_code() ? object_store->to()
@@ -964,7 +863,7 @@
   ASSERT(kind_ == Snapshot::kFull);
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawInstance* obj = reinterpret_cast<RawInstance*>(
-      AllocateUninitialized(kObjectCid, Instance::InstanceSize()));
+      AllocateUninitialized(kInstanceCid, Instance::InstanceSize()));
   return obj;
 }
 
@@ -1117,6 +1016,16 @@
 }
 
 
+RawWeakProperty* SnapshotReader::NewWeakProperty() {
+  ALLOC_NEW_OBJECT(WeakProperty);
+}
+
+
+RawJSRegExp* SnapshotReader::NewJSRegExp() {
+  ALLOC_NEW_OBJECT(JSRegExp);
+}
+
+
 RawFloat32x4* SnapshotReader::NewFloat32x4(float v0, float v1, float v2,
                                            float v3) {
   ASSERT(kind_ == Snapshot::kFull);
@@ -1393,8 +1302,8 @@
                         Object::transition_sentinel().raw());
   READ_VM_SINGLETON_OBJ(kEmptyArrayObject, Object::empty_array().raw());
   READ_VM_SINGLETON_OBJ(kZeroArrayObject, Object::zero_array().raw());
-  READ_VM_SINGLETON_OBJ(kDynamicType, Object::dynamic_type());
-  READ_VM_SINGLETON_OBJ(kVoidType, Object::void_type());
+  READ_VM_SINGLETON_OBJ(kDynamicType, Object::dynamic_type().raw());
+  READ_VM_SINGLETON_OBJ(kVoidType, Object::void_type().raw());
   READ_VM_SINGLETON_OBJ(kTrueValue, Bool::True().raw());
   READ_VM_SINGLETON_OBJ(kFalseValue, Bool::False().raw());
   READ_VM_SINGLETON_OBJ(kExtractorParameterTypes,
@@ -1429,6 +1338,13 @@
     }
   }
 
+  // Check if it is a singleton ICData array object.
+  for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) {
+    if (object_id == (kCachedICDataArray0 + i)) {
+      return ICData::cached_icdata_arrays_[i];
+    }
+  }
+
   ASSERT(Symbols::IsVMSymbolId(object_id));
   return Symbols::GetVMSymbol(object_id);  // return VM symbol.
 }
@@ -1569,7 +1485,8 @@
 
 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() {
   ASSERT(kind() == Snapshot::kFull);
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   ASSERT(isolate == Dart::vm_isolate());
   ObjectStore* object_store = isolate->object_store();
@@ -1585,7 +1502,7 @@
 
   {
     NoSafepointScope no_safepoint;
-    HeapLocker hl(isolate, old_space());
+    HeapLocker hl(thread, old_space());
 
     // Read in the symbol table.
     object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject());
@@ -1705,6 +1622,7 @@
 
 #define VM_OBJECT_CLASS_LIST(V)                                                \
   V(OneByteString)                                                             \
+  V(TwoByteString)                                                             \
   V(Mint)                                                                      \
   V(Bigint)                                                                    \
   V(Double)                                                                    \
@@ -1732,8 +1650,8 @@
                          kTransitionSentinelObject);
   WRITE_VM_SINGLETON_OBJ(Object::empty_array().raw(), kEmptyArrayObject);
   WRITE_VM_SINGLETON_OBJ(Object::zero_array().raw(), kZeroArrayObject);
-  WRITE_VM_SINGLETON_OBJ(Object::dynamic_type(), kDynamicType);
-  WRITE_VM_SINGLETON_OBJ(Object::void_type(), kVoidType);
+  WRITE_VM_SINGLETON_OBJ(Object::dynamic_type().raw(), kDynamicType);
+  WRITE_VM_SINGLETON_OBJ(Object::void_type().raw(), kVoidType);
   WRITE_VM_SINGLETON_OBJ(Bool::True().raw(), kTrueValue);
   WRITE_VM_SINGLETON_OBJ(Bool::False().raw(), kFalseValue);
   WRITE_VM_SINGLETON_OBJ(Object::extractor_parameter_types().raw(),
@@ -1770,6 +1688,14 @@
     }
   }
 
+  // Check if it is a singleton ICData array object.
+  for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) {
+    if (rawobj == ICData::cached_icdata_arrays_[i]) {
+      WriteVMIsolateObject(kCachedICDataArray0 + i);
+      return true;
+    }
+  }
+
   if (kind() == Snapshot::kFull) {
     // Check it is a predefined symbol in the VM isolate.
     id = Symbols::LookupVMSymbol(rawobj);
@@ -1826,15 +1752,15 @@
 // objects and their accompanying token streams.
 class ScriptVisitor : public ObjectVisitor {
  public:
-  explicit ScriptVisitor(Isolate* isolate) :
-      ObjectVisitor(isolate),
-      objHandle_(Object::Handle(isolate->current_zone())),
+  explicit ScriptVisitor(Thread* thread) :
+      ObjectVisitor(thread->isolate()),
+      objHandle_(Object::Handle(thread->zone())),
       count_(0),
       scripts_(NULL) {}
 
-  ScriptVisitor(Isolate* isolate, const Array* scripts) :
-      ObjectVisitor(isolate),
-      objHandle_(Object::Handle(isolate->current_zone())),
+  ScriptVisitor(Thread* thread, const Array* scripts) :
+      ObjectVisitor(thread->isolate()),
+      objHandle_(Object::Handle(thread->zone())),
       count_(0),
       scripts_(scripts) {}
 
@@ -1894,11 +1820,11 @@
   // 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());
+  ScriptVisitor scripts_counter(thread());
   heap()->IterateOldObjects(&scripts_counter);
   intptr_t count = scripts_counter.count();
   scripts_ = Array::New(count, Heap::kOld);
-  ScriptVisitor script_visitor(isolate(), &scripts_);
+  ScriptVisitor script_visitor(thread(), &scripts_);
   heap()->IterateOldObjects(&script_visitor);
 
   // Stash the symbol table away for writing and reading into the vm isolate,
@@ -2031,6 +1957,15 @@
   if (snapshot_code_) {
     instructions_writer_->WriteAssembly();
     instructions_snapshot_size_ = instructions_writer_->BytesWritten();
+
+    OS::Print("VMIsolate(CodeSize): %" Pd "\n", VmIsolateSnapshotSize());
+    OS::Print("Isolate(CodeSize): %" Pd "\n", IsolateSnapshotSize());
+    OS::Print("Instructions(CodeSize): %" Pd "\n",
+              instructions_writer_->binary_size());
+    intptr_t total = VmIsolateSnapshotSize() +
+                     IsolateSnapshotSize() +
+                     instructions_writer_->binary_size();
+    OS::Print("Total(CodeSize): %" Pd "\n", total);
   }
 }
 
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 949f897..8570a06 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -54,6 +54,7 @@
 class RawImmutableArray;
 class RawInstructions;
 class RawInt32x4;
+class RawJSRegExp;
 class RawLanguageError;
 class RawLibrary;
 class RawLibraryPrefix;
@@ -87,6 +88,7 @@
 class RawTypeRef;
 class RawUnhandledException;
 class RawUnresolvedClass;
+class RawWeakProperty;
 class String;
 class TokenStream;
 class TypeArguments;
@@ -361,7 +363,7 @@
   String* StringHandle() { return &str_; }
   AbstractType* TypeHandle() { return &type_; }
   TypeArguments* TypeArgumentsHandle() { return &type_arguments_; }
-  Array* TokensHandle() { return &tokens_; }
+  GrowableObjectArray* TokensHandle() { return &tokens_; }
   TokenStream* StreamHandle() { return &stream_; }
   ExternalTypedData* DataHandle() { return &data_; }
   TypedData* TypedDataHandle() { return &typed_data_; }
@@ -444,6 +446,8 @@
   RawUnhandledException* NewUnhandledException();
   RawObject* NewInteger(int64_t value);
   RawStacktrace* NewStacktrace();
+  RawWeakProperty* NewWeakProperty();
+  RawJSRegExp* NewJSRegExp();
 
   RawInstructions* GetInstructionsAt(int32_t offset, uword expected_tags) {
     return instructions_reader_->GetInstructionsAt(offset, expected_tags);
@@ -483,19 +487,10 @@
                             intptr_t patch_object_id,
                             intptr_t patch_offset);
 
-  // Read an object reference from the stream.
-  RawObject* ReadObjectRef(intptr_t object_id,
-                           intptr_t class_header,
-                           intptr_t tags,
-                           intptr_t patch_object_id = kInvalidPatchIndex,
-                           intptr_t patch_offset = 0);
-
-  // Read an inlined object from the stream.
-  RawObject* ReadInlinedObject(intptr_t object_id,
-                               intptr_t class_header,
-                               intptr_t tags,
-                               intptr_t patch_object_id,
-                               intptr_t patch_offset);
+  // Read a Dart Instance object.
+  RawObject* ReadInstance(intptr_t object_id,
+                          intptr_t tags,
+                          bool as_reference);
 
   // Read a VM isolate object that was serialized as an Id.
   RawObject* ReadVMIsolateObject(intptr_t object_id);
@@ -546,7 +541,7 @@
   Library& library_;  // Temporary library handle.
   AbstractType& type_;  // Temporary type handle.
   TypeArguments& type_arguments_;  // Temporary type argument handle.
-  Array& tokens_;  // Temporary tokens handle.
+  GrowableObjectArray& tokens_;  // Temporary tokens handle.
   TokenStream& stream_;  // Temporary token stream handle.
   ExternalTypedData& data_;  // Temporary stream data handle.
   TypedData& typed_data_;  // Temporary typed data handle.
@@ -723,7 +718,7 @@
   BaseWriter(uint8_t** buffer,
              ReAlloc alloc,
              intptr_t initial_size)
-      : StackResource(Isolate::Current()),
+      : StackResource(Thread::Current()),
         stream_(buffer, alloc, initial_size) {
     ASSERT(buffer != NULL);
     ASSERT(alloc != NULL);
@@ -811,14 +806,17 @@
                      intptr_t initial_size)
     : stream_(buffer, alloc, initial_size),
       next_offset_(InstructionsSnapshot::kHeaderSize),
+      binary_size_(0),
       instructions_() {
     ASSERT(buffer != NULL);
     ASSERT(alloc != NULL);
   }
 
-  // Size of the snapshot.
+  // Size of the snapshot (assembly code).
   intptr_t BytesWritten() const { return stream_.bytes_written(); }
 
+  intptr_t binary_size() { return binary_size_; }
+
   int32_t GetOffsetFor(RawInstructions* instructions);
 
   void SetInstructionsCode(RawInstructions* insns, RawCode* code) {
@@ -855,10 +853,12 @@
 #else
     stream_.Print(".long 0x%0.8" Px "\n", value);
 #endif
+    binary_size_ += sizeof(value);
   }
 
   WriteStream stream_;
   intptr_t next_offset_;
+  intptr_t binary_size_;
   GrowableArray<InstructionsData> instructions_;
 
   DISALLOW_COPY_AND_ASSIGN(InstructionsWriter);
diff --git a/runtime/vm/snapshot_ids.h b/runtime/vm/snapshot_ids.h
index 856887d..436b2a8 100644
--- a/runtime/vm/snapshot_ids.h
+++ b/runtime/vm/snapshot_ids.h
@@ -54,6 +54,9 @@
   kCachedArgumentsDescriptor0,
   kCachedArgumentsDescriptorN = (kCachedArgumentsDescriptor0 +
       ArgumentsDescriptor::kCachedDescriptorCount - 1),
+  kCachedICDataArray0,
+  kCachedICDataArrayN = (kCachedICDataArray0 +
+      ICData::kCachedICDataArrayCount - 1),
 
   kInstanceObjectId,
   kStaticImplicitClosureObjectId,
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 5103296..c67a8ce 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -869,7 +869,9 @@
   const String& private_key = String::Handle(expected_tokens.PrivateKey());
   Scanner scanner(str, private_key);
   const TokenStream& reconstructed_tokens =
-      TokenStream::Handle(TokenStream::New(scanner.GetStream(), private_key));
+      TokenStream::Handle(TokenStream::New(scanner.GetStream(),
+                                           private_key,
+                                           false));
   expected_iterator.SetCurrentPosition(0);
   TokenStream::Iterator reconstructed_iterator(
       reconstructed_tokens, 0, TokenStream::Iterator::kAllTokens);
@@ -1072,7 +1074,7 @@
     // Create a test library and Load up a test script in it.
     TestCase::LoadTestScript(kScriptChars, NULL);
 
-    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(Isolate::Current()));
+    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(Thread::Current()));
 
     // Write out the script snapshot.
     result = Dart_CreateScriptSnapshot(&buffer, &size);
@@ -1175,7 +1177,7 @@
 
     // Create a test library and Load up a test script in it.
     TestCase::LoadTestScript(kScriptChars, NULL);
-    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(thread->isolate()));
+    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(thread));
     timer1.Stop();
     OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime());
 
@@ -1236,7 +1238,7 @@
 
     // Create a test library and Load up a test script in it.
     Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(thread->isolate()));
+    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(thread));
     timer1.Stop();
     OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime());
 
@@ -1380,7 +1382,7 @@
     EXPECT_VALID(Dart_LibraryImportLibrary(TestCase::lib(),
                                            import_lib,
                                            Dart_Null()));
-    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(Isolate::Current()));
+    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(Thread::Current()));
 
     // Get list of library URLs loaded and save the count.
     Dart_Handle libs = Dart_GetLibraryIds();
@@ -1616,7 +1618,7 @@
     EXPECT_VALID(Dart_LibraryImportLibrary(TestCase::lib(),
                                            import_lib,
                                            Dart_Null()));
-    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(Isolate::Current()));
+    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(Thread::Current()));
 
     // Write out the script snapshot.
     result = Dart_CreateScriptSnapshot(&buffer, &size);
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
new file mode 100644
index 0000000..8c08726
--- /dev/null
+++ b/runtime/vm/source_report.cc
@@ -0,0 +1,333 @@
+// 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.
+
+#include "vm/source_report.h"
+
+#include "vm/compiler.h"
+#include "vm/object.h"
+#include "vm/object_store.h"
+
+namespace dart {
+
+SourceReport::SourceReport(intptr_t report_set, CompileMode compile_mode)
+    : report_set_(report_set),
+      compile_mode_(compile_mode),
+      thread_(NULL),
+      script_(NULL),
+      start_pos_(-1),
+      end_pos_(-1),
+      next_script_index_(0) {
+}
+
+
+void SourceReport::Init(Thread* thread,
+                        const Script* script,
+                        intptr_t start_pos,
+                        intptr_t end_pos) {
+  thread_ = thread;
+  script_ = script;
+  start_pos_ = start_pos;
+  end_pos_ = end_pos;
+  script_table_entries_.Clear();
+  script_table_.Clear();
+  next_script_index_ = 0;
+}
+
+
+bool SourceReport::IsReportRequested(ReportKind report_kind) {
+  return (report_set_ & report_kind) != 0;
+}
+
+
+bool SourceReport::ShouldSkipFunction(const Function& func) {
+  if (script_ != NULL && !script_->IsNull()) {
+    if (func.script() != script_->raw()) {
+      // The function is from the wrong script.
+      return true;
+    }
+    if (((start_pos_ > 0) && (func.end_token_pos() < start_pos_)) ||
+        ((end_pos_ > 0) && (func.token_pos() > end_pos_))) {
+      // The function does not intersect with the requested token range.
+      return true;
+    }
+  }
+
+  switch (func.kind()) {
+    case RawFunction::kRegularFunction:
+    case RawFunction::kClosureFunction:
+    case RawFunction::kGetterFunction:
+    case RawFunction::kSetterFunction:
+    case RawFunction::kConstructor:
+      break;
+    default:
+      return true;
+  }
+  if (func.is_abstract() ||
+      func.IsImplicitConstructor() ||
+      func.IsRedirectingFactory()) {
+    return true;
+  }
+  if (func.IsNonImplicitClosureFunction() &&
+      (func.context_scope() == ContextScope::null())) {
+    // TODO(iposva): This can arise if we attempt to compile an inner function
+    // before we have compiled its enclosing function or if the enclosing
+    // function failed to compile.
+    return true;
+  }
+  return false;
+}
+
+
+intptr_t SourceReport::GetScriptIndex(const Script& script) {
+  const String& url = String::Handle(zone(), script.url());
+  ScriptTableEntry* pair = script_table_.Lookup(&url);
+  if (pair != NULL) {
+    return pair->index;
+  }
+
+  ScriptTableEntry tmp;
+  tmp.key = &url;
+  tmp.index = next_script_index_++;
+  tmp.script = &script;
+  script_table_entries_.Add(tmp);
+  script_table_.Insert(&(script_table_entries_.Last()));
+  return tmp.index;
+}
+
+
+bool SourceReport::ScriptIsLoadedByLibrary(const Script& script,
+                                           const Library& lib) {
+  const Array& scripts = Array::Handle(zone(), lib.LoadedScripts());
+  for (intptr_t j = 0; j < scripts.Length(); j++) {
+    if (scripts.At(j) == script.raw()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+void SourceReport::PrintCallSitesData(JSONObject* jsobj,
+                                      const Function& func,
+                                      const Code& code) {
+  const intptr_t begin_pos = func.token_pos();
+  const intptr_t end_pos = func.end_token_pos();
+
+  ZoneGrowableArray<const ICData*>* ic_data_array =
+      new(zone()) ZoneGrowableArray<const ICData*>();
+  func.RestoreICDataMap(ic_data_array, false /* clone descriptors */);
+  const PcDescriptors& descriptors = PcDescriptors::Handle(
+      zone(), code.pc_descriptors());
+
+  JSONArray sites(jsobj, "callSites");
+
+  PcDescriptors::Iterator iter(
+      descriptors,
+      RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
+  while (iter.MoveNext()) {
+    HANDLESCOPE(thread());
+    const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
+    if (!ic_data->IsNull()) {
+      const intptr_t token_pos = iter.TokenPos();
+      if ((token_pos < begin_pos) || (token_pos > end_pos)) {
+        // Does not correspond to a valid source position.
+        continue;
+      }
+      bool is_static_call = iter.Kind() == RawPcDescriptors::kUnoptStaticCall;
+      ic_data->PrintToJSONArrayNew(sites, token_pos, is_static_call);
+    }
+  }
+}
+
+void SourceReport::PrintCoverageData(JSONObject* jsobj,
+                                     const Function& func,
+                                     const Code& code) {
+  const intptr_t begin_pos = func.token_pos();
+  const intptr_t end_pos = func.end_token_pos();
+
+  ZoneGrowableArray<const ICData*>* ic_data_array =
+      new(zone()) ZoneGrowableArray<const ICData*>();
+  func.RestoreICDataMap(ic_data_array, false /* clone descriptors */);
+  const PcDescriptors& descriptors = PcDescriptors::Handle(
+      zone(), code.pc_descriptors());
+
+  const int kCoverageNone = 0;
+  const int kCoverageMiss = 1;
+  const int kCoverageHit = 2;
+
+  intptr_t func_length = (end_pos - begin_pos) + 1;
+  GrowableArray<char> coverage(func_length);
+  coverage.SetLength(func_length);
+  for (int i = 0; i < func_length; i++) {
+    coverage[i] = kCoverageNone;
+  }
+
+  PcDescriptors::Iterator iter(
+      descriptors,
+      RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
+  while (iter.MoveNext()) {
+    HANDLESCOPE(thread());
+    const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
+    if (!ic_data->IsNull()) {
+      const intptr_t token_pos = iter.TokenPos();
+      if ((token_pos < begin_pos) || (token_pos > end_pos)) {
+        // Does not correspond to a valid source position.
+        continue;
+      }
+      intptr_t count = ic_data->AggregateCount();
+      intptr_t token_offset = token_pos - begin_pos;
+      if (count > 0) {
+        coverage[token_offset] = kCoverageHit;
+      } else {
+        if (coverage[token_offset] == kCoverageNone) {
+          coverage[token_offset] = kCoverageMiss;
+        }
+      }
+    }
+  }
+
+  JSONObject cov(jsobj, "coverage");
+  {
+    JSONArray hits(&cov, "hits");
+    for (int i = 0; i < func_length; i++) {
+      if (coverage[i] == kCoverageHit) {
+        hits.AddValue(begin_pos + i);  // Add the token position of the hit.
+      }
+    }
+  }
+  {
+    JSONArray misses(&cov, "misses");
+    for (int i = 0; i < func_length; i++) {
+      if (coverage[i] == kCoverageMiss) {
+        misses.AddValue(begin_pos + i);  // Add the token position of the miss.
+      }
+    }
+  }
+}
+
+
+void SourceReport::PrintScriptTable(JSONArray* scripts) {
+  for (int i = 0; i < script_table_entries_.length(); i++) {
+    const Script* script = script_table_entries_[i].script;
+    scripts->AddValue(*script);
+  }
+}
+
+
+void SourceReport::VisitFunction(JSONArray* jsarr, const Function& func) {
+  if (ShouldSkipFunction(func)) {
+    return;
+  }
+
+  const Script& script = Script::Handle(zone(), func.script());
+  const intptr_t begin_pos = func.token_pos();
+  const intptr_t end_pos = func.end_token_pos();
+
+  Code& code = Code::Handle(zone(), func.unoptimized_code());
+  if (code.IsNull()) {
+    if (func.HasCode() || (compile_mode_ == kForceCompile)) {
+      if (Compiler::EnsureUnoptimizedCode(thread(), func) != Error::null()) {
+        // Ignore the error and this function entirely.
+        return;
+      }
+      code = func.unoptimized_code();
+    } else {
+      // This function has not been compiled yet.
+      JSONObject range(jsarr);
+      range.AddProperty("scriptIndex", GetScriptIndex(script));
+      range.AddProperty("startPos", begin_pos);
+      range.AddProperty("endPos", end_pos);
+      range.AddProperty("compiled", false);
+      return;
+    }
+  }
+  ASSERT(!code.IsNull());
+
+  // We skip compiled async functions.  Once an async function has
+  // been compiled, there is another function with the same range which
+  // actually contains the user code.
+  if (func.IsAsyncFunction() ||
+      func.IsAsyncGenerator() ||
+      func.IsSyncGenerator()) {
+    return;
+  }
+
+  JSONObject range(jsarr);
+  range.AddProperty("scriptIndex", GetScriptIndex(script));
+  range.AddProperty("startPos", begin_pos);
+  range.AddProperty("endPos", end_pos);
+  range.AddProperty("compiled", true);
+
+  if (IsReportRequested(kCallSites)) {
+    PrintCallSitesData(&range, func, code);
+  }
+  if (IsReportRequested(kCoverage)) {
+    PrintCoverageData(&range, func, code);
+  }
+}
+
+
+void SourceReport::VisitLibrary(JSONArray* jsarr, const Library& lib) {
+  Class& cls = Class::Handle(zone());
+  Array& functions = Array::Handle(zone());
+  Function& func = Function::Handle(zone());
+  ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+  while (it.HasNext()) {
+    cls = it.GetNextClass();
+    functions = cls.functions();
+    for (int i = 0; i < functions.Length(); i++) {
+      func ^= functions.At(i);
+      VisitFunction(jsarr, func);
+    }
+  }
+}
+
+
+void SourceReport::VisitClosures(JSONArray* jsarr) {
+  const GrowableObjectArray& closures = GrowableObjectArray::Handle(
+      thread()->isolate()->object_store()->closure_functions());
+
+  // We need to keep rechecking the length of the closures array, as handling
+  // a closure potentially adds new entries to the end.
+  Function& func = Function::Handle(zone());
+  for (int i = 0; i < closures.Length(); i++) {
+    func ^= closures.At(i);
+    VisitFunction(jsarr, func);
+  }
+}
+
+
+void SourceReport::PrintJSON(JSONStream* js,
+                             const Script& script,
+                             intptr_t start_pos, intptr_t end_pos) {
+  Init(Thread::Current(), &script, start_pos, end_pos);
+
+  JSONObject report(js);
+  report.AddProperty("type", "SourceReport");
+  {
+    JSONArray ranges(&report, "ranges");
+
+    const GrowableObjectArray& libs = GrowableObjectArray::Handle(
+        zone(), thread()->isolate()->object_store()->libraries());
+
+    // We only visit the libraries which actually load the specified script.
+    Library& lib = Library::Handle(zone());
+    for (int i = 0; i < libs.Length(); i++) {
+      lib ^= libs.At(i);
+      if (script.IsNull() || ScriptIsLoadedByLibrary(script, lib)) {
+        VisitLibrary(&ranges, lib);
+      }
+    }
+
+    // Visit all closures for this isolate.
+    VisitClosures(&ranges);
+  }
+
+  // Print the script table.
+  JSONArray scripts(&report, "scripts");
+  PrintScriptTable(&scripts);
+}
+
+
+}  // namespace dart
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
new file mode 100644
index 0000000..09c8092
--- /dev/null
+++ b/runtime/vm/source_report.h
@@ -0,0 +1,109 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_SOURCE_REPORT_H_
+#define VM_SOURCE_REPORT_H_
+
+#include "vm/allocation.h"
+#include "vm/flags.h"
+#include "vm/hash_map.h"
+#include "vm/object.h"
+
+namespace dart {
+
+// A SourceReport object is used to generate reports about the program
+// source code, with information associated with source token
+// positions.  There are multiple possible kinds of reports.
+class SourceReport {
+ public:
+  enum ReportKind {
+    kCallSites = 0x1,
+    kCoverage  = 0x2,
+  };
+
+  enum CompileMode {
+    kNoCompile,
+    kForceCompile
+  };
+
+  // report_set is a bitvector indicating which reports to generate
+  // (e.g. kCallSites | kCoverage).
+  explicit SourceReport(intptr_t report_set,
+                        CompileMode compile = kNoCompile);
+
+  // Generate a source report for (some subrange of) a script.
+  //
+  // If script is null, then the report is generated for all scripts
+  // in the isolate.
+  void PrintJSON(JSONStream* js, const Script& script,
+                 intptr_t start_pos = -1, intptr_t end_pos = -1);
+
+ private:
+  void Init(Thread* thread, const Script* script,
+            intptr_t start_pos, intptr_t end_pos);
+
+  Thread* thread() const { return thread_; }
+  Zone* zone() const { return thread_->zone(); }
+
+  bool IsReportRequested(ReportKind report_kind);
+  bool ShouldSkipFunction(const Function& func);
+  intptr_t GetScriptIndex(const Script& script);
+  bool ScriptIsLoadedByLibrary(const Script& script, const Library& lib);
+
+  void PrintCallSitesData(JSONObject* jsobj,
+                          const Function& func, const Code& code);
+  void PrintCoverageData(JSONObject* jsobj,
+                         const Function& func, const Code& code);
+  void PrintScriptTable(JSONArray* jsarr);
+
+  void VisitFunction(JSONArray* jsarr, const Function& func);
+  void VisitLibrary(JSONArray* jsarr, const Library& lib);
+  void VisitClosures(JSONArray* jsarr);
+
+  // An entry in the script table.
+  struct ScriptTableEntry {
+    ScriptTableEntry() : key(NULL), index(-1), script(NULL) {}
+
+    const String* key;
+    intptr_t index;
+    const Script* script;
+  };
+
+  // Needed for DirectChainedHashMap.
+  struct ScriptTableTrait {
+    typedef ScriptTableEntry* Value;
+    typedef const String* Key;
+    typedef ScriptTableEntry* Pair;
+
+    static Key KeyOf(Pair kv) {
+      return kv->key;
+    }
+
+    static Value ValueOf(Pair kv) {
+      return kv;
+    }
+
+    static inline intptr_t Hashcode(Key key) {
+      return key->Hash();
+    }
+
+    static inline bool IsKeyEqual(Pair kv, Key key) {
+      return kv->key->Equals(*key);
+    }
+  };
+
+  intptr_t report_set_;
+  CompileMode compile_mode_;
+  Thread* thread_;
+  const Script* script_;
+  intptr_t start_pos_;
+  intptr_t end_pos_;
+  GrowableArray<ScriptTableEntry> script_table_entries_;
+  DirectChainedHashMap<ScriptTableTrait> script_table_;
+  intptr_t next_script_index_;
+};
+
+}  // namespace dart
+
+#endif  // VM_SOURCE_REPORT_H_
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
new file mode 100644
index 0000000..0e1bb79
--- /dev/null
+++ b/runtime/vm/source_report_test.cc
@@ -0,0 +1,461 @@
+// 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.
+
+#include "vm/source_report.h"
+#include "vm/dart_api_impl.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+static RawObject* ExecuteScript(const char* script) {
+  Dart_Handle h_lib = TestCase::LoadTestScript(script, NULL);
+  EXPECT_VALID(h_lib);
+  Library& lib = Library::Handle();
+  lib ^= Api::UnwrapHandle(h_lib);
+  EXPECT(!lib.IsNull());
+  Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL);
+  EXPECT_VALID(result);
+  return Api::UnwrapHandle(h_lib);
+}
+
+
+TEST_CASE(SourceReport_Coverage_NoCalls) {
+  char buffer[1024];
+  const char* kScript =
+      "main() {\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCoverage);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("libraries", js.ToCString(), buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":"
+
+      // One compiled range, no hits or misses.
+      "[{\"scriptIndex\":0,\"startPos\":0,\"endPos\":5,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}}],"
+
+      // One script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+
+TEST_CASE(SourceReport_Coverage_SimpleCall) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {}\n"
+      "helper1() {}\n"
+      "main() {\n"
+      "  if (true) {\n"
+      "    helper0();\n"
+      "  } else {\n"
+      "    helper1();\n"
+      "  }\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCoverage);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // One range compiled with no hits or misses (helper0).
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // One range not compiled (helper1).
+      "{\"scriptIndex\":0,\"startPos\":6,\"endPos\":10,\"compiled\":false},"
+
+      // One range with a hit and a miss (main).
+      "{\"scriptIndex\":0,\"startPos\":12,\"endPos\":39,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[23],\"misses\":[32]}}],"
+
+      // Only one script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+
+TEST_CASE(SourceReport_Coverage_ForceCompile) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {}\n"
+      "helper1() {}\n"
+      "main() {\n"
+      "  if (true) {\n"
+      "    helper0();\n"
+      "  } else {\n"
+      "    helper1();\n"
+      "  }\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCoverage, SourceReport::kForceCompile);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // One range compiled with no hits or misses (helper0).
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // This range is compiled even though it wasn't called (helper1).
+      "{\"scriptIndex\":0,\"startPos\":6,\"endPos\":10,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // One range with a hit and a miss (main).
+      "{\"scriptIndex\":0,\"startPos\":12,\"endPos\":39,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[23],\"misses\":[32]}}],"
+
+      // Only one script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+
+TEST_CASE(SourceReport_Coverage_NestedFunctions) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {\n"
+      "  nestedHelper0() {}\n"
+      "  nestedHelper1() {}\n"
+      "  nestedHelper0();\n"
+      "}\n"
+      "helper1() {}\n"
+      "main() {\n"
+      "  if (true) {\n"
+      "    helper0();\n"
+      "  } else {\n"
+      "    helper1();\n"
+      "  }\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCoverage);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // One range compiled with one hit (helper0).
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":22,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[18],\"misses\":[]}},"
+
+      // One range not compiled (helper1).
+      "{\"scriptIndex\":0,\"startPos\":24,\"endPos\":28,\"compiled\":false},"
+
+      // One range with a hit and a miss (main).
+      "{\"scriptIndex\":0,\"startPos\":30,\"endPos\":57,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[41],\"misses\":[50]}},"
+
+      // Nested range compiled (nestedHelper0).
+      "{\"scriptIndex\":0,\"startPos\":5,\"endPos\":9,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // Nested range not compiled (nestedHelper1).
+      "{\"scriptIndex\":0,\"startPos\":11,\"endPos\":15,\"compiled\":false}],"
+
+      // Only one script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+
+TEST_CASE(SourceReport_Coverage_RestrictedRange) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {\n"
+      "  nestedHelper0() {}\n"
+      "  nestedHelper1() {}\n"
+      "  nestedHelper0();\n"
+      "}\n"
+      "helper1() {}\n"
+      "main() {\n"
+      "  if (true) {\n"
+      "    helper0();\n"
+      "  } else {\n"
+      "    helper1();\n"
+      "  }\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+  const Function& helper = Function::Handle(
+      lib.LookupLocalFunction(String::Handle(String::New("helper0"))));
+
+  SourceReport report(SourceReport::kCoverage);
+  JSONStream js;
+  // Restrict the report to only helper0 and it's nested functions.
+  report.PrintJSON(&js, script, helper.token_pos(), helper.end_token_pos());
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // One range compiled with one hit (helper0).
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":22,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[18],\"misses\":[]}},"
+
+      // Nested range compiled (nestedHelper0).
+      "{\"scriptIndex\":0,\"startPos\":5,\"endPos\":9,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // Nested range not compiled (nestedHelper1).
+      "{\"scriptIndex\":0,\"startPos\":11,\"endPos\":15,\"compiled\":false}],"
+
+      // Only one script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+
+TEST_CASE(SourceReport_Coverage_AllFunctions) {
+  const char* kScript =
+      "helper0() {}\n"
+      "helper1() {}\n"
+      "main() {\n"
+      "  if (true) {\n"
+      "    helper0();\n"
+      "  } else {\n"
+      "    helper1();\n"
+      "  }\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+
+  SourceReport report(SourceReport::kCoverage);
+  JSONStream js;
+
+  // We generate a report with all functions in the VM.
+  Script& null_script = Script::Handle();
+  report.PrintJSON(&js, null_script);
+  const char* result = js.ToCString();
+
+  // Sanity check the header.
+  EXPECT_SUBSTRING("{\"type\":\"SourceReport\",\"ranges\":[", result);
+
+  // Make sure that the main function was found.
+  EXPECT_SUBSTRING(
+      "\"startPos\":12,\"endPos\":39,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[23],\"misses\":[32]}",
+      result);
+
+  // More than one script is referenced in the report.
+  EXPECT_SUBSTRING("\"scriptIndex\":0", result);
+  EXPECT_SUBSTRING("\"scriptIndex\":1", result);
+  EXPECT_SUBSTRING("\"scriptIndex\":2", result);
+}
+
+
+TEST_CASE(SourceReport_CallSites_SimpleCall) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {}\n"
+      "helper1() {}\n"
+      "main() {\n"
+      "  helper0();\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCallSites);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // One range compiled with no callsites (helper0).
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+      "\"callSites\":[]},"
+
+      // One range not compiled (helper1).
+      "{\"scriptIndex\":0,\"startPos\":6,\"endPos\":10,\"compiled\":false},"
+
+      // One range compiled with one callsite (main).
+      "{\"scriptIndex\":0,\"startPos\":12,\"endPos\":22,\"compiled\":true,"
+      "\"callSites\":["
+      "{\"name\":\"helper0\",\"tokenPos\":17,\"cacheEntries\":["
+      "{\"target\":{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
+      "\"name\":\"helper0\",\"owner\":{\"type\":\"@Library\",\"fixedId\":true,"
+      "\"id\":\"\",\"name\":\"\",\"uri\":\"test-lib\"},"
+      "\"_kind\":\"RegularFunction\",\"static\":true,\"const\":false,"
+      "\"_intrinsic\":false,\"_native\":false},\"count\":1}]}]}],"
+
+      // One script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+TEST_CASE(SourceReport_CallSites_PolymorphicCall) {
+  char buffer[1024];
+  const char* kScript =
+      "class Common {\n"
+      "  func() {}\n"
+      "}\n"
+      "class Uncommon {\n"
+      "  func() {}\n"
+      "}\n"
+      "helper(arg) {\n"
+      "  arg.func();\n"
+      "}\n"
+      "main() {\n"
+      "  Common common = new Common();\n"
+      "  Uncommon uncommon = new Uncommon();\n"
+      "  helper(common);\n"
+      "  helper(common);\n"
+      "  helper(uncommon);\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+  const Function& helper = Function::Handle(
+      lib.LookupLocalFunction(String::Handle(String::New("helper"))));
+
+  SourceReport report(SourceReport::kCallSites);
+  JSONStream js;
+  report.PrintJSON(&js, script, helper.token_pos(), helper.end_token_pos());
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // One range...
+      "{\"scriptIndex\":0,\"startPos\":24,\"endPos\":37,\"compiled\":true,"
+
+      // With one call site...
+      "\"callSites\":[{\"name\":\"func\",\"tokenPos\":32,\"cacheEntries\":["
+
+      // First receiver: "Common", called twice.
+      "{\"receiver\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+      "\"name\":\"Common\"},"
+
+      "\"target\":{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
+      "\"name\":\"func\","
+      "\"owner\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+      "\"name\":\"Common\"},\"_kind\":\"RegularFunction\","
+      "\"static\":false,\"const\":false,\"_intrinsic\":false,"
+      "\"_native\":false},"
+
+      "\"count\":2},"
+
+      // Second receiver: "Uncommon", called once.
+      "{\"receiver\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+      "\"name\":\"Uncommon\"},"
+
+      "\"target\":{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
+      "\"name\":\"func\","
+      "\"owner\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+      "\"name\":\"Uncommon\"},\"_kind\":\"RegularFunction\","
+      "\"static\":false,\"const\":false,\"_intrinsic\":false,"
+      "\"_native\":false},"
+
+      "\"count\":1}]}]}],"
+
+      // One script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+
+TEST_CASE(SourceReport_MultipleReports) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {}\n"
+      "helper1() {}\n"
+      "main() {\n"
+      "  helper0();\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCallSites|SourceReport::kCoverage);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // One range compiled with no callsites (helper0).
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+      "\"callSites\":[],"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // One range not compiled (helper1).
+      "{\"scriptIndex\":0,\"startPos\":6,\"endPos\":10,\"compiled\":false},"
+
+      // One range compiled with one callsite (main).
+      "{\"scriptIndex\":0,\"startPos\":12,\"endPos\":22,\"compiled\":true,"
+      "\"callSites\":["
+      "{\"name\":\"helper0\",\"tokenPos\":17,\"cacheEntries\":["
+      "{\"target\":{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
+      "\"name\":\"helper0\",\"owner\":{\"type\":\"@Library\",\"fixedId\":true,"
+      "\"id\":\"\",\"name\":\"\",\"uri\":\"test-lib\"},"
+      "\"_kind\":\"RegularFunction\",\"static\":true,\"const\":false,"
+      "\"_intrinsic\":false,\"_native\":false},\"count\":1}]}],"
+      "\"coverage\":{\"hits\":[17],\"misses\":[]}}],"
+
+      // One script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+}  // namespace dart
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 7594b91..65f7c3b 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -35,7 +35,7 @@
 
 
 const char* StackFrame::ToCString() const {
-  ASSERT(isolate_ == Isolate::Current());
+  ASSERT(thread_ == Thread::Current());
   Zone* zone = Thread::Current()->zone();
   if (IsDartFrame()) {
     const Code& code = Code::Handle(LookupDartCode());
@@ -68,7 +68,7 @@
 
 
 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
-  ASSERT(isolate() == Isolate::Current());
+  ASSERT(thread() == Thread::Current());
   // Visit objects between SP and (FP - callee_save_area).
   ASSERT(visitor != NULL);
   RawObject** first = reinterpret_cast<RawObject**>(sp());
@@ -85,7 +85,7 @@
   // these handles are not traversed. The use of handles is mainly to
   // be able to reuse the handle based code and avoid having to add
   // helper functions to the raw object interface.
-  ASSERT(isolate_ == Isolate::Current());
+  ASSERT(thread() == Thread::Current());
   ASSERT(visitor != NULL);
   NoSafepointScope no_safepoint;
   Code code;
@@ -165,7 +165,6 @@
 
 
 RawFunction* StackFrame::LookupDartFunction() const {
-  ASSERT(isolate_ == Isolate::Current());
   const Code& code = Code::Handle(LookupDartCode());
   if (!code.IsNull()) {
     return code.function();
@@ -175,7 +174,6 @@
 
 
 RawCode* StackFrame::LookupDartCode() const {
-  ASSERT(isolate_ == Isolate::Current());
   // We add a no gc scope to ensure that the code below does not trigger
   // a GC as we are handling raw object references here. It is possible
   // that the code is called while a GC is in progress, that is ok.
@@ -261,7 +259,6 @@
 }
 
 
-
 bool StackFrame::IsValid() const {
   if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) {
     return true;
@@ -271,7 +268,8 @@
 
 
 void StackFrameIterator::SetupLastExitFrameData() {
-  uword exit_marker = isolate_->top_exit_frame_info();
+  ASSERT(thread_ != NULL);
+  uword exit_marker = thread_->top_exit_frame_info();
   frames_.fp_ = exit_marker;
 }
 
@@ -287,35 +285,35 @@
 
 // Tell MemorySanitizer that generated code initializes part of the stack.
 // TODO(koda): Limit to frames that are actually written by generated code.
-static void UnpoisonStack(Isolate* isolate, uword fp) {
+static void UnpoisonStack(uword fp) {
   ASSERT(fp != 0);
-  uword size = isolate->GetSpecifiedStackSize();
+  uword size = OSThread::GetSpecifiedStackSize();
   MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size);
 }
 
 
-StackFrameIterator::StackFrameIterator(bool validate, Isolate* isolate)
+StackFrameIterator::StackFrameIterator(bool validate, Thread* thread)
     : validate_(validate),
-      entry_(isolate),
-      exit_(isolate),
-      frames_(isolate),
+      entry_(thread),
+      exit_(thread),
+      frames_(thread),
       current_frame_(NULL),
-      isolate_(isolate) {
-  ASSERT((isolate_ == Isolate::Current()) ||
+      thread_(thread) {
+  ASSERT((thread_ == Thread::Current()) ||
          OS::AllowStackFrameIteratorFromAnotherThread());
   SetupLastExitFrameData();  // Setup data for last exit frame.
 }
 
 
 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate,
-                                       Isolate* isolate)
+                                       Thread* thread)
     : validate_(validate),
-      entry_(isolate),
-      exit_(isolate),
-      frames_(isolate),
+      entry_(thread),
+      exit_(thread),
+      frames_(thread),
       current_frame_(NULL),
-      isolate_(isolate) {
-  ASSERT((isolate_ == Isolate::Current()) ||
+      thread_(thread) {
+  ASSERT((thread_ == Thread::Current()) ||
          OS::AllowStackFrameIteratorFromAnotherThread());
   frames_.fp_ = last_fp;
   frames_.sp_ = 0;
@@ -324,14 +322,14 @@
 
 
 StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc,
-                                       bool validate, Isolate* isolate)
+                                       bool validate, Thread* thread)
     : validate_(validate),
-      entry_(isolate),
-      exit_(isolate),
-      frames_(isolate),
+      entry_(thread),
+      exit_(thread),
+      frames_(thread),
       current_frame_(NULL),
-      isolate_(isolate) {
-  ASSERT((isolate_ == Isolate::Current()) ||
+      thread_(thread) {
+  ASSERT((thread_ == Thread::Current()) ||
          OS::AllowStackFrameIteratorFromAnotherThread());
   frames_.fp_ = fp;
   frames_.sp_ = sp;
@@ -356,7 +354,7 @@
     if (!HasNextFrame()) {
       return NULL;
     }
-    UnpoisonStack(isolate_, frames_.fp_);
+    UnpoisonStack(frames_.fp_);
     if (frames_.pc_ == 0) {
       // Iteration starts from an exit frame given by its fp.
       current_frame_ = NextExitFrame();
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 2889a1e..1c59ccb 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -85,13 +85,15 @@
   intptr_t GetTokenPos() const;
 
  protected:
-  explicit StackFrame(Isolate* isolate)
-      : fp_(0), sp_(0), pc_(0), isolate_(isolate) { }
+  explicit StackFrame(Thread* thread)
+      : fp_(0), sp_(0), pc_(0), thread_(thread) { }
 
   // Name of the frame, used for generic frame printing functionality.
   virtual const char* GetName() const { return IsStubFrame()? "stub" : "dart"; }
 
-  Isolate* isolate() const { return isolate_; }
+  Isolate* isolate() const { return thread_->isolate(); }
+
+  Thread* thread() const { return thread_; }
 
  private:
   RawCode* GetCodeObject() const;
@@ -111,7 +113,7 @@
   uword fp_;
   uword sp_;
   uword pc_;
-  Isolate* isolate_;
+  Thread* thread_;
 
   // The iterators FrameSetIterator and StackFrameIterator set the private
   // fields fp_ and sp_ when they return the respective frame objects.
@@ -137,7 +139,7 @@
   virtual const char* GetName() const { return "exit"; }
 
  private:
-  explicit ExitFrame(Isolate* isolate) : StackFrame(isolate) { }
+  explicit ExitFrame(Thread* thread) : StackFrame(thread) { }
 
   friend class StackFrameIterator;
   DISALLOW_COPY_AND_ASSIGN(ExitFrame);
@@ -162,18 +164,18 @@
   virtual const char* GetName() const { return "entry"; }
 
  private:
-  explicit EntryFrame(Isolate* isolate) : StackFrame(isolate) { }
+  explicit EntryFrame(Thread* thread) : StackFrame(thread) { }
 
   friend class StackFrameIterator;
   DISALLOW_COPY_AND_ASSIGN(EntryFrame);
 };
 
 
-// A StackFrameIterator can be initialized with an isolate other than the
-// current thread's isolate. Because this is generally a bad idea,
-// it is only allowed on Windows- where it is needed for the profiler.
-// It is the responsibility of users of StackFrameIterator to ensure that the
-// isolate given is not running concurrently on another thread.
+// A StackFrameIterator can be initialized with a thread other than the
+// current thread. Because this is generally a bad idea, it is only allowed on
+// Windows- where it is needed for the profiler. It is the responsibility of
+// users of StackFrameIterator to ensure that the thread given is not running
+// concurrently.
 class StackFrameIterator : public ValueObject {
  public:
   static const bool kValidateFrames = true;
@@ -181,15 +183,15 @@
 
   // Iterators for iterating over all frames from the last ExitFrame to the
   // first EntryFrame.
-  explicit StackFrameIterator(bool validate,
-                              Isolate* isolate = Isolate::Current());
+  StackFrameIterator(bool validate,
+                     Thread* thread = Thread::Current());
   StackFrameIterator(uword last_fp, bool validate,
-                     Isolate* isolate = Isolate::Current());
+                     Thread* thread = Thread::Current());
 
   // Iterator for iterating over all frames from the current frame (given by its
   // fp, sp, and pc) to the first EntryFrame.
   StackFrameIterator(uword fp, uword sp, uword pc, bool validate,
-                     Isolate* isolate = Isolate::Current());
+                     Thread* thread = Thread::Current());
 
   // Checks if a next frame exists.
   bool HasNextFrame() const { return frames_.fp_ != 0; }
@@ -218,13 +220,13 @@
     StackFrame* NextFrame(bool validate);
 
    private:
-    explicit FrameSetIterator(Isolate* isolate)
-        : fp_(0), sp_(0), pc_(0), stack_frame_(isolate), isolate_(isolate) { }
+    explicit FrameSetIterator(Thread* thread)
+        : fp_(0), sp_(0), pc_(0), stack_frame_(thread), thread_(thread) { }
     uword fp_;
     uword sp_;
     uword pc_;
     StackFrame stack_frame_;  // Singleton frame returned by NextFrame().
-    Isolate* isolate_;
+    Thread* thread_;
 
     friend class StackFrameIterator;
     DISALLOW_COPY_AND_ASSIGN(FrameSetIterator);
@@ -250,7 +252,7 @@
   ExitFrame exit_;  // Singleton exit frame returned by NextExitFrame().
   FrameSetIterator frames_;
   StackFrame* current_frame_;  // Points to the current frame in the iterator.
-  Isolate* isolate_;
+  Thread* thread_;
 
   DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
 };
@@ -265,16 +267,17 @@
 // isolate given is not running concurrently on another thread.
 class DartFrameIterator : public ValueObject {
  public:
-  explicit DartFrameIterator(Isolate* isolate = Isolate::Current())
-      : frames_(StackFrameIterator::kDontValidateFrames, isolate) { }
+  explicit DartFrameIterator(Thread* thread = Thread::Current())
+      : frames_(StackFrameIterator::kDontValidateFrames, thread) { }
   DartFrameIterator(uword last_fp,
-                    Isolate* isolate = Isolate::Current())
-      : frames_(last_fp, StackFrameIterator::kDontValidateFrames, isolate) { }
+                    Thread* thread = Thread::Current())
+      : frames_(last_fp, StackFrameIterator::kDontValidateFrames, thread) { }
   DartFrameIterator(uword fp,
                     uword sp,
                     uword pc,
-                    Isolate* isolate = Isolate::Current())
-      : frames_(fp, sp, pc, StackFrameIterator::kDontValidateFrames, isolate) {
+                    Thread* thread = Thread::Current())
+      : frames_(fp, sp, pc,
+                StackFrameIterator::kDontValidateFrames, thread) {
   }
   // Get next dart frame.
   StackFrame* NextFrame() {
diff --git a/runtime/vm/stack_frame_arm.h b/runtime/vm/stack_frame_arm.h
index 8f22815..ca89fb5 100644
--- a/runtime/vm/stack_frame_arm.h
+++ b/runtime/vm/stack_frame_arm.h
@@ -43,7 +43,15 @@
 static const int kCallerSpSlotFromFp = 2;
 
 // Entry and exit frame layout.
+#if defined(TARGET_OS_MAC)
+static const int kExitLinkSlotFromEntryFp = -26;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 6);
+COMPILE_ASSERT(kAbiPreservedFpuRegCount == 4);
+#else
 static const int kExitLinkSlotFromEntryFp = -27;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 7);
+COMPILE_ASSERT(kAbiPreservedFpuRegCount == 4);
+#endif
 
 }  // namespace dart
 
diff --git a/runtime/vm/stack_frame_arm64.h b/runtime/vm/stack_frame_arm64.h
index 6733724..a1ca2eb 100644
--- a/runtime/vm/stack_frame_arm64.h
+++ b/runtime/vm/stack_frame_arm64.h
@@ -45,6 +45,8 @@
 
 // Entry and exit frame layout.
 static const int kExitLinkSlotFromEntryFp = -22;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 10);
+COMPILE_ASSERT(kAbiPreservedFpuRegCount == 8);
 
 }  // namespace dart
 
diff --git a/runtime/vm/stack_frame_mips.h b/runtime/vm/stack_frame_mips.h
index 3f7c7e5..35c9aba 100644
--- a/runtime/vm/stack_frame_mips.h
+++ b/runtime/vm/stack_frame_mips.h
@@ -42,6 +42,8 @@
 
 // Entry and exit frame layout.
 static const int kExitLinkSlotFromEntryFp = -24;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 8);
+COMPILE_ASSERT(kAbiPreservedFpuRegCount == 12);
 
 }  // namespace dart
 
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 7c8fe78..ad3c995 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -45,9 +45,13 @@
 
 
 void StubCode::InitOnce() {
+#if !defined(DART_PRECOMPILED)
   // Generate all the stubs.
   Code& code = Code::Handle();
   VM_STUB_CODE_LIST(STUB_CODE_GENERATE);
+#else
+  UNREACHABLE();
+#endif  // DART_PRECOMPILED
 }
 
 
@@ -79,7 +83,16 @@
 }
 
 
+bool StubCode::HasBeenInitialized() {
+  // Use JumpToExceptionHandler and InvokeDart as canaries.
+  const StubEntry* entry_1 = StubCode::JumpToExceptionHandler_entry();
+  const StubEntry* entry_2 = StubCode::InvokeDartCode_entry();
+  return (entry_1 != NULL) && (entry_2 != NULL);
+}
+
+
 bool StubCode::InInvocationStub(uword pc) {
+  ASSERT(HasBeenInitialized());
   uword entry = StubCode::InvokeDartCode_entry()->EntryPoint();
   uword size = StubCode::InvokeDartCodeSize();
   return (pc >= entry) && (pc < (entry + size));
@@ -87,6 +100,7 @@
 
 
 bool StubCode::InJumpToExceptionHandlerStub(uword pc) {
+  ASSERT(HasBeenInitialized());
   uword entry = StubCode::JumpToExceptionHandler_entry()->EntryPoint();
   uword size = StubCode::JumpToExceptionHandlerSize();
   return (pc >= entry) && (pc < (entry + size));
@@ -106,7 +120,7 @@
     Assembler assembler;
     const char* name = cls.ToCString();
     StubCode::GenerateAllocationStubForClass(&assembler, cls);
-    stub ^= Code::FinalizeCode(name, &assembler);
+    stub ^= Code::FinalizeCode(name, &assembler, false /* optimized */);
     stub.set_owner(cls);
     cls.set_allocation_stub(stub);
     if (FLAG_disassemble_stubs) {
@@ -143,7 +157,8 @@
                             void (*GenerateStub)(Assembler* assembler)) {
   Assembler assembler;
   GenerateStub(&assembler);
-  const Code& code = Code::Handle(Code::FinalizeCode(name, &assembler));
+  const Code& code = Code::Handle(
+      Code::FinalizeCode(name, &assembler, false /* optimized */));
   if (FLAG_disassemble_stubs) {
     LogBlock lb;
     THR_Print("Code for stub '%s': {\n", name);
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index e7da564..f451638 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -35,6 +35,7 @@
   V(OptimizeFunction)                                                          \
   V(InvokeDartCode)                                                            \
   V(DebugStepCheck)                                                            \
+  V(ICLookup)                                                                  \
   V(MegamorphicLookup)                                                         \
   V(FixAllocationStubTarget)                                                   \
   V(Deoptimize)                                                                \
@@ -60,7 +61,7 @@
   V(Subtype1TestCache)                                                         \
   V(Subtype2TestCache)                                                         \
   V(Subtype3TestCache)                                                         \
-  V(CallClosureNoSuchMethod)
+  V(CallClosureNoSuchMethod)                                                   \
 
 // Is it permitted for the stubs above to refer to Object::null(), which is
 // allocated in the VM isolate and shared across all isolates.
@@ -109,6 +110,9 @@
 
   static void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
+  // Returns true if stub code has been initialized.
+  static bool HasBeenInitialized();
+
   // Check if specified pc is in the dart invocation stub used for
   // transitioning into dart code.
   static bool InInvocationStub(uword pc);
@@ -136,8 +140,7 @@
 
   static const intptr_t kNoInstantiator = 0;
 
-  static void EmitMegamorphicLookup(
-      Assembler*, Register recv, Register cache, Register target);
+  static void EmitMegamorphicLookup(Assembler* assembler);
 
  private:
   friend class MegamorphicCacheTable;
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 1629107..711c901 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -35,7 +35,7 @@
 //   SP : address of last argument in argument array.
 //   SP + 4*R4 - 4 : address of first argument in argument array.
 //   SP + 4*R4 : address of return value.
-//   R5 : address of the runtime function to call.
+//   R9 : address of the runtime function to call.
 //   R4 : number of arguments to the call.
 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
   const intptr_t thread_offset = NativeArguments::thread_offset();
@@ -52,8 +52,8 @@
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R6, VMTag::kDartTagId);
+    __ LoadFromOffset(kWord, R8, THR, Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -61,7 +61,7 @@
 #endif
 
   // Mark that the thread is executing VM code.
-  __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
+  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
 
   // Reserve space for arguments and align frame before entering C++ world.
   // NativeArguments are passed in registers.
@@ -89,7 +89,7 @@
   __ add(R3, R2, Operand(kWordSize));  // Retval is next to 1st argument.
 
   // Call runtime or redirection via simulator.
-  __ blx(R5);
+  __ blx(R9);
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
@@ -126,7 +126,7 @@
 // Input parameters:
 //   LR : return address.
 //   SP : address of return value.
-//   R5 : address of the native function to call.
+//   R9 : address of the native function to call.
 //   R2 : address of first argument in argument array.
 //   R1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
@@ -144,8 +144,8 @@
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R6, VMTag::kDartTagId);
+    __ LoadFromOffset(kWord, R8, THR, Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -153,7 +153,7 @@
 #endif
 
   // Mark that the thread is executing native code.
-  __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
+  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -185,7 +185,7 @@
   __ stm(IA, SP,  (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3));
   __ mov(R0, Operand(SP));  // Pass the pointer to the NativeArguments.
 
-  __ mov(R1, Operand(R5));  // Pass the function entrypoint to call.
+  __ mov(R1, Operand(R9));  // Pass the function entrypoint to call.
 
   // Call native function invocation wrapper or redirection via simulator.
   __ ldr(LR, Address(THR, Thread::native_call_wrapper_entry_point_offset()));
@@ -207,7 +207,7 @@
 // Input parameters:
 //   LR : return address.
 //   SP : address of return value.
-//   R5 : address of the native function to call.
+//   R9 : address of the native function to call.
 //   R2 : address of first argument in argument array.
 //   R1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
@@ -225,8 +225,8 @@
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R6, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R6, VMTag::kDartTagId);
+    __ LoadFromOffset(kWord, R8, THR, Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -234,7 +234,7 @@
 #endif
 
   // Mark that the thread is executing native code.
-  __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
+  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -267,7 +267,7 @@
   __ mov(R0, Operand(SP));  // Pass the pointer to the NativeArguments.
 
   // Call native function or redirection via simulator.
-  __ blx(R5);
+  __ blx(R9);
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
@@ -543,11 +543,11 @@
   // Load the receiver.
   __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
   __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize));
+  __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize));
   __ PushObject(Object::null_object());
-  __ Push(R6);
-  __ Push(R5);
-  __ Push(R4);
+  __ Push(R8);  // Receiver.
+  __ Push(R9);  // ICData/MegamorphicCache.
+  __ Push(R4);  // Arguments descriptor.
   // R2: Smi-tagged arguments array length.
   PushArgumentsArray(assembler);
   const intptr_t kNumArgs = 4;
@@ -565,24 +565,23 @@
   // Load the receiver.
   __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
   __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize));
+  __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize));
 
   // Preserve IC data and arguments descriptor.
-  __ PushList((1 << R4) | (1 << R5));
+  __ PushList((1 << R4) | (1 << R9));
 
-  // Push space for the return value.
-  // Push the receiver.
-  // Push IC data object.
-  // Push arguments descriptor array.
   __ LoadObject(IP, Object::null_object());
-  __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP));
+  __ Push(IP);  // result
+  __ Push(R8);  // receiver
+  __ Push(R9);  // ICData
+  __ Push(R4);  // arguments descriptor
   __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
   // Remove arguments.
   __ Drop(3);
   __ Pop(R0);  // Get result into R0 (target function).
 
   // Restore IC data and arguments descriptor.
-  __ PopList((1 << R4) | (1 << R5));
+  __ PopList((1 << R4) | (1 << R9));
 
   __ RestoreCodePointer();
   __ LeaveStubFrame();
@@ -633,55 +632,55 @@
                           /* inline_isolate = */ false);
 
   const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
-  __ LoadImmediate(R5, fixed_size);
-  __ add(R5, R5, 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(R5, R5, Operand(kObjectAlignment - 1));
+  __ bic(R9, R9, Operand(kObjectAlignment - 1));
 
-  // R5: Allocation size.
+  // R9: Allocation size.
   Heap::Space space = Heap::SpaceForAllocation(cid);
-  __ LoadIsolate(R6);
-  __ ldr(R6, Address(R6, Isolate::heap_offset()));
+  __ LoadIsolate(R8);
+  __ ldr(R8, Address(R8, Isolate::heap_offset()));
   // Potential new object start.
-  __ ldr(R0, Address(R6, Heap::TopOffset(space)));
-  __ adds(R7, R0, Operand(R5));  // Potential next object start.
+  __ ldr(R0, Address(R8, Heap::TopOffset(space)));
+  __ adds(NOTFP, R0, Operand(R9));  // Potential next object start.
   __ b(&slow_case, CS);  // Branch if unsigned overflow.
 
   // Check if the allocation fits into the remaining space.
   // R0: potential new object start.
-  // R7: potential next object start.
-  // R5: allocation size.
-  __ ldr(R3, Address(R6, Heap::EndOffset(space)));
-  __ cmp(R7, Operand(R3));
+  // NOTFP: potential next object start.
+  // R9: allocation size.
+  __ ldr(R3, Address(R8, Heap::EndOffset(space)));
+  __ cmp(NOTFP, Operand(R3));
   __ b(&slow_case, CS);
 
   // Successfully allocated the object(s), now update top to point to
   // next object start and initialize the object.
   __ LoadAllocationStatsAddress(R3, cid, /* inline_isolate = */ false);
-  __ str(R7, Address(R6, Heap::TopOffset(space)));
+  __ str(NOTFP, Address(R8, Heap::TopOffset(space)));
   __ add(R0, R0, Operand(kHeapObjectTag));
 
   // Initialize the tags.
   // R0: new object start as a tagged pointer.
   // R3: allocation stats address.
-  // R7: new object end address.
-  // R5: allocation size.
+  // NOTFP: new object end address.
+  // R9: allocation size.
   {
     const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
 
-    __ CompareImmediate(R5, RawObject::SizeTag::kMaxSizeTag);
-    __ mov(R6, Operand(R5, LSL, shift), LS);
-    __ mov(R6, Operand(0), HI);
+    __ CompareImmediate(R9, RawObject::SizeTag::kMaxSizeTag);
+    __ mov(R8, Operand(R9, LSL, shift), LS);
+    __ mov(R8, Operand(0), HI);
 
     // Get the class index and insert it into the tags.
-    // R6: size and bit tags.
+    // R8: size and bit tags.
     __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid));
-    __ orr(R6, R6, Operand(TMP));
-    __ str(R6, FieldAddress(R0, Array::tags_offset()));  // Store tags.
+    __ orr(R8, R8, Operand(TMP));
+    __ str(R8, FieldAddress(R0, Array::tags_offset()));  // Store tags.
   }
 
   // R0: new object start as a tagged pointer.
-  // R7: new object end address.
+  // NOTFP: new object end address.
   // Store the type argument field.
   __ InitializeFieldNoBarrier(R0,
                               FieldAddress(R0, Array::type_arguments_offset()),
@@ -695,17 +694,17 @@
   // Initialize all array elements to raw_null.
   // R0: new object start as a tagged pointer.
   // R3: allocation stats address.
-  // R4, R5: null
-  // R6: iterator which initially points to the start of the variable
+  // R8, R9: null
+  // R4: iterator which initially points to the start of the variable
   // data area to be initialized.
-  // R7: new object end address.
-  // R5: allocation size.
-  __ IncrementAllocationStatsWithSize(R3, R5, space);
+  // NOTFP: new object end address.
+  // R9: allocation size.
+  __ IncrementAllocationStatsWithSize(R3, R9, space);
 
-  __ LoadObject(R4, Object::null_object());
-  __ mov(R5, Operand(R4));
-  __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag);
-  __ InitializeFieldsNoBarrier(R0, R6, R7, R4, R5);
+  __ LoadObject(R8, Object::null_object());
+  __ mov(R9, Operand(R8));
+  __ AddImmediate(R4, R0, sizeof(RawArray) - kHeapObjectTag);
+  __ InitializeFieldsNoBarrier(R0, R4, NOTFP, R8, R9);
   __ Ret();  // Returns the newly allocated object in R0.
   // Unable to allocate the array using the fast inline code, just call
   // into the runtime.
@@ -760,32 +759,36 @@
   }
 
   // Save the current VMTag on the stack.
-  __ LoadFromOffset(kWord, R5, THR, Thread::vm_tag_offset());
-  __ Push(R5);
+  __ LoadFromOffset(kWord, R9, THR, Thread::vm_tag_offset());
+  __ Push(R9);
 
   // Mark that the thread is executing Dart code.
-  __ LoadImmediate(R5, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R5, THR, Thread::vm_tag_offset());
+  __ LoadImmediate(R9, VMTag::kDartTagId);
+  __ StoreToOffset(kWord, R9, THR, Thread::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, THR, Thread::top_exit_frame_info_offset());
+  __ LoadFromOffset(kWord, R9, THR, Thread::top_exit_frame_info_offset());
   __ LoadFromOffset(kWord, R4, THR, Thread::top_resource_offset());
-  __ LoadImmediate(R6, 0);
-  __ StoreToOffset(kWord, R6, THR, Thread::top_resource_offset());
-  __ StoreToOffset(kWord, R6, THR, Thread::top_exit_frame_info_offset());
+  __ LoadImmediate(R8, 0);
+  __ StoreToOffset(kWord, R8, THR, Thread::top_resource_offset());
+  __ StoreToOffset(kWord, R8, THR, Thread::top_exit_frame_info_offset());
 
   // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
   __ Push(R4);
+#if defined(TARGET_OS_MAC)
+  ASSERT(kExitLinkSlotFromEntryFp == -26);
+#else
   ASSERT(kExitLinkSlotFromEntryFp == -27);
-  __ Push(R5);
+#endif
+  __ Push(R9);
 
   // Load arguments descriptor array into R4, which is passed to Dart code.
   __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle));
 
-  // Load number of arguments into R5.
-  __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R5);
+  // Load number of arguments into R9.
+  __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+  __ SmiUntag(R9);
 
   // Compute address of 'arguments array' data area into R2.
   __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle));
@@ -794,7 +797,7 @@
   // Set up arguments for the Dart call.
   Label push_arguments;
   Label done_push_arguments;
-  __ CompareImmediate(R5, 0);  // check if there are arguments.
+  __ CompareImmediate(R9, 0);  // check if there are arguments.
   __ b(&done_push_arguments, EQ);
   __ LoadImmediate(R1, 0);
   __ Bind(&push_arguments);
@@ -802,7 +805,7 @@
   __ Push(R3);
   __ AddImmediate(R2, kWordSize);
   __ AddImmediate(R1, 1);
-  __ cmp(R1, Operand(R5));
+  __ cmp(R1, Operand(R9));
   __ b(&push_arguments, LT);
   __ Bind(&done_push_arguments);
 
@@ -816,11 +819,11 @@
   __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
 
   // 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, THR, Thread::top_exit_frame_info_offset());
-  __ Pop(R5);
-  __ StoreToOffset(kWord, R5, THR, Thread::top_resource_offset());
+  // Isolate structure. Uses R9 as a temporary register for this.
+  __ Pop(R9);
+  __ StoreToOffset(kWord, R9, THR, Thread::top_exit_frame_info_offset());
+  __ Pop(R9);
+  __ StoreToOffset(kWord, R9, THR, Thread::top_resource_offset());
 
   // Restore the current VMTag from the stack.
   __ Pop(R4);
@@ -859,24 +862,24 @@
     ASSERT(kSmiTagShift == 1);
     __ bic(R2, R2, Operand(kObjectAlignment - 1));
 
-    __ MaybeTraceAllocation(kContextCid, R4, &slow_case,
+    __ MaybeTraceAllocation(kContextCid, R8, &slow_case,
                             /* inline_isolate = */ false);
     // Now allocate the object.
     // R1: number of context variables.
     // R2: object size.
     const intptr_t cid = kContextCid;
     Heap::Space space = Heap::SpaceForAllocation(cid);
-    __ LoadIsolate(R5);
-    __ ldr(R5, Address(R5, Isolate::heap_offset()));
-    __ ldr(R0, Address(R5, Heap::TopOffset(space)));
+    __ LoadIsolate(R9);
+    __ ldr(R9, Address(R9, Isolate::heap_offset()));
+    __ ldr(R0, Address(R9, Heap::TopOffset(space)));
     __ add(R3, R2, Operand(R0));
     // Check if the allocation fits into the remaining space.
     // R0: potential new object.
     // R1: number of context variables.
     // R2: object size.
     // R3: potential next object start.
-    // R5: heap.
-    __ ldr(IP, Address(R5, Heap::EndOffset(space)));
+    // R9: heap.
+    __ ldr(IP, Address(R9, Heap::EndOffset(space)));
     __ cmp(R3, Operand(IP));
     if (FLAG_use_slow_path) {
       __ b(&slow_case);
@@ -890,9 +893,9 @@
     // R1: number of context variables.
     // R2: object size.
     // R3: next object start.
-    // R5: heap.
-    __ LoadAllocationStatsAddress(R6, cid, /* inline_isolate = */ false);
-    __ str(R3, Address(R5, Heap::TopOffset(space)));
+    // R9: heap.
+    __ LoadAllocationStatsAddress(R4, cid, /* inline_isolate = */ false);
+    __ str(R3, Address(R9, Heap::TopOffset(space)));
     __ add(R0, R0, Operand(kHeapObjectTag));
 
     // Calculate the size tag.
@@ -900,25 +903,25 @@
     // R1: number of context variables.
     // R2: object size.
     // R3: next object start.
-    // R6: allocation stats address.
+    // R4: allocation stats address.
     const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
     __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);
     // If no size tag overflow, shift R2 left, else set R2 to zero.
-    __ mov(R5, Operand(R2, LSL, shift), LS);
-    __ mov(R5, Operand(0), HI);
+    __ mov(R9, Operand(R2, LSL, shift), LS);
+    __ mov(R9, Operand(0), HI);
 
     // Get the class index and insert it into the tags.
-    // R5: size and bit tags.
+    // R9: size and bit tags.
     __ LoadImmediate(IP, RawObject::ClassIdTag::encode(cid));
-    __ orr(R5, R5, Operand(IP));
-    __ str(R5, FieldAddress(R0, Context::tags_offset()));
+    __ orr(R9, R9, Operand(IP));
+    __ str(R9, FieldAddress(R0, Context::tags_offset()));
 
     // Setup up number of context variables field.
     // R0: new object.
     // R1: number of context variables as integer value (not object).
     // R2: object size.
     // R3: next object start.
-    // R6: allocation stats address.
+    // R4: allocation stats address.
     __ str(R1, FieldAddress(R0, Context::num_variables_offset()));
 
     // Setup the parent field.
@@ -926,22 +929,22 @@
     // R1: number of context variables.
     // R2: object size.
     // R3: next object start.
-    // R6: allocation stats address.
-    __ LoadObject(R4, Object::null_object());
+    // R4: allocation stats address.
+    __ LoadObject(R8, Object::null_object());
     __ InitializeFieldNoBarrier(R0, FieldAddress(R0, Context::parent_offset()),
-                                R4);
+                                R8);
 
     // Initialize the context variables.
     // R0: new object.
     // R1: number of context variables.
     // R2: object size.
     // R3: next object start.
-    // R4, R5: raw null.
-    // R6: allocation stats address.
+    // R8, R9: raw null.
+    // R4: allocation stats address.
     Label loop;
-    __ AddImmediate(R7, R0, Context::variable_offset(0) - kHeapObjectTag);
-    __ InitializeFieldsNoBarrier(R0, R7, R3, R4, R5);
-    __ IncrementAllocationStatsWithSize(R6, R2, space);
+    __ AddImmediate(NOTFP, R0, Context::variable_offset(0) - kHeapObjectTag);
+    __ InitializeFieldsNoBarrier(R0, NOTFP, R3, R8, R9);
+    __ IncrementAllocationStatsWithSize(R4, R2, space);
 
     // Done allocating and initializing the context.
     // R0: new object.
@@ -1046,7 +1049,7 @@
 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
                                               const Class& cls) {
   // Must load pool pointer before being able to patch.
-  Register new_pp = R7;
+  Register new_pp = NOTFP;
   __ LoadPoolPointer(new_pp);
   // The generated code is different if the class is parameterized.
   const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
@@ -1065,29 +1068,29 @@
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
     Heap::Space space = Heap::SpaceForAllocation(cls.id());
-    __ ldr(R5, Address(THR, Thread::heap_offset()));
-    __ ldr(R0, Address(R5, Heap::TopOffset(space)));
+    __ ldr(R9, Address(THR, Thread::heap_offset()));
+    __ ldr(R0, Address(R9, Heap::TopOffset(space)));
     __ AddImmediate(R1, R0, instance_size);
     // Check if the allocation fits into the remaining space.
     // R0: potential new object start.
     // R1: potential next object start.
-    // R5: heap.
-    __ ldr(IP, Address(R5, Heap::EndOffset(space)));
+    // R9: heap.
+    __ ldr(IP, Address(R9, Heap::EndOffset(space)));
     __ cmp(R1, Operand(IP));
     if (FLAG_use_slow_path) {
       __ b(&slow_case);
     } else {
       __ b(&slow_case, CS);  // Unsigned higher or equal.
     }
-    __ str(R1, Address(R5, Heap::TopOffset(space)));
+    __ str(R1, Address(R9, Heap::TopOffset(space)));
 
     // Load the address of the allocation stats table. We split up the load
     // and the increment so that the dependent load is not too nearby.
-    __ LoadAllocationStatsAddress(R5, cls.id(), /* inline_isolate = */ false);
+    __ LoadAllocationStatsAddress(R9, cls.id(), /* inline_isolate = */ false);
 
     // R0: new object start.
     // R1: next object start.
-    // R5: allocation stats table.
+    // R9: allocation stats table.
     // Set the tags.
     uword tags = 0;
     tags = RawObject::SizeTag::update(instance_size, tags);
@@ -1103,7 +1106,7 @@
     // R2: raw null.
     // R0: new object (tagged).
     // R1: next object start.
-    // R5: allocation stats table.
+    // R9: allocation stats table.
     // First try inlining the initialization without a loop.
     if (instance_size < (kInlineInstanceSize * kWordSize)) {
       // Small objects are initialized using a consecutive set of writes.
@@ -1125,7 +1128,7 @@
       // R0: new object (tagged).
       // R1: next object start.
       // R4: next word to be initialized.
-      // R5: allocation stats table.
+      // R9: allocation stats table.
       __ InitializeFieldsNoBarrier(R0, R4, R1, R2, R3);
     }
     if (is_cls_parameterized) {
@@ -1137,10 +1140,10 @@
 
     // Done allocating and initializing the instance.
     // R0: new object (tagged).
-    // R5: allocation stats table.
+    // R9: allocation stats table.
 
     // Update allocation stats.
-    __ IncrementAllocationStats(R5, cls.id(), space);
+    __ IncrementAllocationStats(R9, cls.id(), space);
 
     // R0: new object (tagged).
     __ Ret();
@@ -1189,13 +1192,13 @@
   // Load the receiver.
   __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
   __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize));
+  __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize));
 
   // Push space for the return value.
   // Push the receiver.
   // Push arguments descriptor array.
   __ LoadObject(IP, Object::null_object());
-  __ PushList((1 << R4) | (1 << R6) | (1 << IP));
+  __ PushList((1 << R4) | (1 << R8) | (1 << IP));
 
   // R2: Smi-tagged arguments array length.
   PushArgumentsArray(assembler);
@@ -1207,26 +1210,26 @@
 }
 
 
-//  R6: function object.
-//  R5: inline cache data object.
+//  R8: function object.
+//  R9: inline cache data object.
 // Cannot use function object from ICData as it may be the inlined
 // function and not the top-scope function.
 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
-  Register ic_reg = R5;
-  Register func_reg = R6;
+  Register ic_reg = R9;
+  Register func_reg = R8;
   if (FLAG_trace_optimized_ic_calls) {
     __ EnterStubFrame();
-    __ PushList((1 << R5) | (1 << R6));  // Preserve.
+    __ PushList((1 << R9) | (1 << R8));  // Preserve.
     __ Push(ic_reg);  // Argument.
     __ Push(func_reg);  // Argument.
     __ CallRuntime(kTraceICCallRuntimeEntry, 2);
     __ Drop(2);  // Discard argument;
-    __ PopList((1 << R5) | (1 << R6));  // Restore.
+    __ PopList((1 << R9) | (1 << R8));  // Restore.
     __ LeaveStubFrame();
   }
-  __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
-  __ add(R7, R7, Operand(1));
-  __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
+  __ ldr(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
+  __ add(NOTFP, NOTFP, Operand(1));
+  __ str(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
 }
 
 
@@ -1234,19 +1237,19 @@
 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
                                              Register temp_reg) {
   if (FLAG_optimization_counter_threshold >= 0) {
-    Register ic_reg = R5;
+    Register ic_reg = R9;
     Register func_reg = temp_reg;
-    ASSERT(temp_reg == R6);
+    ASSERT(temp_reg == R8);
     __ Comment("Increment function counter");
     __ ldr(func_reg, FieldAddress(ic_reg, ICData::owner_offset()));
-    __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
-    __ add(R7, R7, Operand(1));
-    __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
+    __ ldr(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
+    __ add(NOTFP, NOTFP, Operand(1));
+    __ str(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
   }
 }
 
 
-// Note: R5 must be preserved.
+// Note: R9 must be preserved.
 // Attempt a quick Smi operation for known operations ('kind'). The ICData
 // must have been primed with a Smi/Smi check that will be used for counting
 // the invocations.
@@ -1279,19 +1282,19 @@
     }
     default: UNIMPLEMENTED();
   }
-  // R5: IC data object (preserved).
-  __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
-  // R6: ic_data_array with check entries: classes and target functions.
-  __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
-  // R6: points directly to the first ic data array element.
+  // R9: IC data object (preserved).
+  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
+  // R8: ic_data_array with check entries: classes and target functions.
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: points directly to the first ic data array element.
 #if defined(DEBUG)
   // Check that first entry is for Smi/Smi.
   Label error, ok;
   const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid));
-  __ ldr(R1, Address(R6, 0));
+  __ ldr(R1, Address(R8, 0));
   __ CompareImmediate(R1, imm_smi_cid);
   __ b(&error, NE);
-  __ ldr(R1, Address(R6, kWordSize));
+  __ ldr(R1, Address(R8, kWordSize));
   __ CompareImmediate(R1, imm_smi_cid);
   __ b(&ok, EQ);
   __ Bind(&error);
@@ -1301,10 +1304,10 @@
   if (FLAG_optimization_counter_threshold >= 0) {
     // Update counter.
     const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-    __ LoadFromOffset(kWord, R1, R6, count_offset);
+    __ LoadFromOffset(kWord, R1, R8, count_offset);
     __ adds(R1, R1, Operand(Smi::RawValue(1)));
     __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS);  // Overflow.
-    __ StoreIntoSmiField(Address(R6, count_offset), R1);
+    __ StoreIntoSmiField(Address(R8, count_offset), R1);
   }
   __ Ret();
 }
@@ -1312,7 +1315,7 @@
 
 // Generate inline cache check for 'num_args'.
 //  LR: return address.
-//  R5: inline cache data object.
+//  R9: inline cache data object.
 // Control flow:
 // - If receiver is null -> jump to IC miss.
 // - If receiver is Smi -> load Smi class.
@@ -1333,10 +1336,10 @@
   { Label ok;
     // Check that the IC data array has NumArgsTested() == num_args.
     // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset()));
+    __ ldr(R8, FieldAddress(R9, ICData::state_bits_offset()));
     ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ and_(R6, R6, Operand(ICData::NumArgsTestedMask()));
-    __ CompareImmediate(R6, num_args);
+    __ and_(R8, R8, Operand(ICData::NumArgsTestedMask()));
+    __ CompareImmediate(R8, num_args);
     __ b(&ok, EQ);
     __ Stop("Incorrect stub for IC data");
     __ Bind(&ok);
@@ -1346,9 +1349,9 @@
   Label stepping, done_stepping;
   if (FLAG_support_debugger && !optimized) {
     __ Comment("Check single stepping");
-    __ LoadIsolate(R6);
-    __ ldrb(R6, Address(R6, Isolate::single_step_offset()));
-    __ CompareImmediate(R6, 0);
+    __ LoadIsolate(R8);
+    __ ldrb(R8, Address(R8, Isolate::single_step_offset()));
+    __ CompareImmediate(R8, 0);
     __ b(&stepping, NE);
     __ Bind(&done_stepping);
   }
@@ -1359,11 +1362,11 @@
     ASSERT((num_args == 1) || (num_args == 2));
     if (num_args == 2) {
       __ ldr(R0, Address(SP, 1 * kWordSize));
-      __ UpdateRangeFeedback(R0, 0, R5, R1, R4, &not_smi_or_overflow);
+      __ UpdateRangeFeedback(R0, 0, R9, R1, R4, &not_smi_or_overflow);
     }
 
     __ ldr(R0, Address(SP, 0 * kWordSize));
-    __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, &not_smi_or_overflow);
+    __ UpdateRangeFeedback(R0, num_args - 1, R9, R1, R4, &not_smi_or_overflow);
   }
   if (kind != Token::kILLEGAL) {
     EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
@@ -1372,24 +1375,24 @@
 
   __ Comment("Extract ICData initial values and receiver cid");
   // Load arguments descriptor into R4.
-  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
+  __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
   // Loop that checks if there is an IC data match.
   Label loop, update, test, found;
-  // R5: IC data object (preserved).
-  __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
-  // R6: ic_data_array with check entries: classes and target functions.
-  __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
-  // R6: points directly to the first ic data array element.
+  // R9: IC data object (preserved).
+  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
+  // R8: ic_data_array with check entries: classes and target functions.
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: points directly to the first ic data array element.
 
   // Get the receiver's class ID (first read number of arguments from
   // arguments descriptor array and then access the receiver from the stack).
-  __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ sub(R7, R7, Operand(Smi::RawValue(1)));
-  __ ldr(R0, Address(SP, R7, LSL, 1));  // R7 (argument_count - 1) is smi.
+  __ ldr(NOTFP, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+  __ sub(NOTFP, NOTFP, Operand(Smi::RawValue(1)));
+  __ ldr(R0, Address(SP, NOTFP, LSL, 1));  // NOTFP (argument_count - 1) is smi.
   __ LoadTaggedClassIdMayBeSmi(R0, R0);
-  // R7: argument_count - 1 (smi).
+  // NOTFP: argument_count - 1 (smi).
   // R0: receiver's class ID (smi).
-  __ ldr(R1, Address(R6, 0));  // First class id (smi) to check.
+  __ ldr(R1, Address(R8, 0));  // First class id (smi) to check.
   __ b(&test);
 
   __ Comment("ICData loop");
@@ -1397,11 +1400,11 @@
   for (int i = 0; i < num_args; i++) {
     if (i > 0) {
       // If not the first, load the next argument's class ID.
-      __ AddImmediate(R0, R7, Smi::RawValue(-i));
+      __ AddImmediate(R0, NOTFP, Smi::RawValue(-i));
       __ ldr(R0, Address(SP, R0, LSL, 1));
       __ LoadTaggedClassIdMayBeSmi(R0, R0);
       // R0: next argument class ID (smi).
-      __ LoadFromOffset(kWord, R1, R6, i * kWordSize);
+      __ LoadFromOffset(kWord, R1, R8, i * kWordSize);
       // R1: next class ID to check (smi).
     }
     __ cmp(R0, Operand(R1));  // Class id match?
@@ -1415,13 +1418,13 @@
   __ Bind(&update);
   // Reload receiver class ID.  It has not been destroyed when num_args == 1.
   if (num_args > 1) {
-    __ ldr(R0, Address(SP, R7, LSL, 1));
+    __ ldr(R0, Address(SP, NOTFP, LSL, 1));
     __ LoadTaggedClassIdMayBeSmi(R0, R0);
   }
 
   const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
-  __ AddImmediate(R6, entry_size);  // Next entry.
-  __ ldr(R1, Address(R6, 0));  // Next class ID.
+  __ AddImmediate(R8, entry_size);  // Next entry.
+  __ ldr(R1, Address(R8, 0));  // Next class ID.
 
   __ Bind(&test);
   __ CompareImmediate(R1, Smi::RawValue(kIllegalCid));  // Done?
@@ -1429,29 +1432,29 @@
 
   __ Comment("IC miss");
   // Compute address of arguments.
-  // R7: argument_count - 1 (smi).
-  __ add(R7, SP, Operand(R7, LSL, 1));  // R7 is Smi.
-  // R7: address of receiver.
+  // NOTFP: argument_count - 1 (smi).
+  __ add(NOTFP, SP, Operand(NOTFP, LSL, 1));  // NOTFP is Smi.
+  // NOTFP: address of receiver.
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
   __ LoadObject(R0, Object::null_object());
   // Preserve IC data object and arguments descriptor array and
   // setup space on stack for result (target code object).
-  __ PushList((1 << R0) | (1 << R4) | (1 << R5));
+  __ PushList((1 << R0) | (1 << R4) | (1 << R9));
   // Push call arguments.
   for (intptr_t i = 0; i < num_args; i++) {
-    __ LoadFromOffset(kWord, IP, R7, -i * kWordSize);
+    __ LoadFromOffset(kWord, IP, NOTFP, -i * kWordSize);
     __ Push(IP);
   }
   // Pass IC data object.
-  __ Push(R5);
+  __ Push(R9);
   __ CallRuntime(handle_ic_miss, num_args + 1);
   // Remove the call arguments pushed earlier, including the IC data object.
   __ Drop(num_args + 1);
   // Pop returned function object into R0.
   // Restore arguments descriptor array and IC data array.
-  __ PopList((1 << R0) | (1 << R4) | (1 << R5));
+  __ PopList((1 << R0) | (1 << R4) | (1 << R9));
   if (range_collection_mode == kCollectRanges) {
     __ RestoreCodePointer();
   }
@@ -1464,17 +1467,17 @@
   }
 
   __ Bind(&found);
-  // R6: pointer to an IC data check group.
+  // R8: pointer to an IC data check group.
   const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
   const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-  __ LoadFromOffset(kWord, R0, R6, target_offset);
+  __ LoadFromOffset(kWord, R0, R8, target_offset);
 
   if (FLAG_optimization_counter_threshold >= 0) {
     __ Comment("Update caller's counter");
-    __ LoadFromOffset(kWord, R1, R6, count_offset);
+    __ LoadFromOffset(kWord, R1, R8, count_offset);
     __ adds(R1, R1, Operand(Smi::RawValue(1)));
     __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS);  // Overflow.
-    __ StoreIntoSmiField(Address(R6, count_offset), R1);
+    __ StoreIntoSmiField(Address(R8, count_offset), R1);
   }
 
   __ Comment("Call target");
@@ -1488,16 +1491,16 @@
     }
     __ EnterStubFrame();
     if (num_args == 2) {
-      __ PushList((1 << R1) | (1 << R3) | (1 << R5));
+      __ PushList((1 << R1) | (1 << R3) | (1 << R9));
     } else {
-      __ PushList((1 << R1) | (1 << R5));
+      __ PushList((1 << R1) | (1 << R9));
     }
     __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
     __ blx(R2);
 
     Label done;
-    __ ldr(R5, Address(FP, kFirstLocalSlotFromFp * kWordSize));
-    __ UpdateRangeFeedback(R0, 2, R5, R1, R4, &done);
+    __ ldr(R9, Address(FP, kFirstLocalSlotFromFp * kWordSize));
+    __ UpdateRangeFeedback(R0, 2, R9, R1, R4, &done);
     __ Bind(&done);
     __ RestoreCodePointer();
     __ LeaveStubFrame();
@@ -1510,9 +1513,9 @@
   if (FLAG_support_debugger && !optimized) {
     __ Bind(&stepping);
     __ EnterStubFrame();
-    __ Push(R5);  // Preserve IC data.
+    __ Push(R9);  // Preserve IC data.
     __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-    __ Pop(R5);
+    __ Pop(R9);
     __ RestoreCodePointer();
     __ LeaveStubFrame();
     __ b(&done_stepping);
@@ -1523,7 +1526,7 @@
 // Use inline cache data array to invoke the target or continue in inline
 // cache miss handler. Stub for 1-argument check (receiver class).
 //  LR: return address.
-//  R5: inline cache data object.
+//  R9: inline cache data object.
 // Inline cache data object structure:
 // 0: function-name
 // 1: N, number of arguments checked.
@@ -1531,7 +1534,7 @@
 //   - N classes.
 //   - 1 target function.
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler,
       1,
       kInlineCacheMissHandlerOneArgRuntimeEntry,
@@ -1541,7 +1544,7 @@
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler,
       2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
@@ -1551,7 +1554,7 @@
 
 
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler,
       2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
@@ -1561,7 +1564,7 @@
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
       kCollectRanges);
@@ -1569,7 +1572,7 @@
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
       kIgnoreRanges);
@@ -1578,7 +1581,7 @@
 
 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
     Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
       kInlineCacheMissHandlerOneArgRuntimeEntry,
       Token::kILLEGAL,
@@ -1588,7 +1591,7 @@
 
 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
     Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
       Token::kILLEGAL,
@@ -1616,17 +1619,17 @@
 
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
-// R5: ICData
+// R9: ICData
 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
 #if defined(DEBUG)
   { Label ok;
     // Check that the IC data array has NumArgsTested() == 0.
     // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset()));
+    __ ldr(R8, FieldAddress(R9, ICData::state_bits_offset()));
     ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ and_(R6, R6, Operand(ICData::NumArgsTestedMask()));
-    __ CompareImmediate(R6, 0);
+    __ and_(R8, R8, Operand(ICData::NumArgsTestedMask()));
+    __ CompareImmediate(R8, 0);
     __ b(&ok, EQ);
     __ Stop("Incorrect IC data for unoptimized static call");
     __ Bind(&ok);
@@ -1636,34 +1639,34 @@
   // Check single stepping.
   Label stepping, done_stepping;
   if (FLAG_support_debugger) {
-    __ LoadIsolate(R6);
-    __ ldrb(R6, Address(R6, Isolate::single_step_offset()));
-    __ CompareImmediate(R6, 0);
+    __ LoadIsolate(R8);
+    __ ldrb(R8, Address(R8, Isolate::single_step_offset()));
+    __ CompareImmediate(R8, 0);
     __ b(&stepping, NE);
     __ Bind(&done_stepping);
   }
 
-  // R5: IC data object (preserved).
-  __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
-  // R6: ic_data_array with entries: target functions and count.
-  __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
-  // R6: points directly to the first ic data array element.
+  // R9: IC data object (preserved).
+  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
+  // R8: ic_data_array with entries: target functions and count.
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: points directly to the first ic data array element.
   const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
   const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
 
   if (FLAG_optimization_counter_threshold >= 0) {
     // Increment count for this call.
-    __ LoadFromOffset(kWord, R1, R6, count_offset);
+    __ LoadFromOffset(kWord, R1, R8, count_offset);
     __ adds(R1, R1, Operand(Smi::RawValue(1)));
     __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS);  // Overflow.
-    __ StoreIntoSmiField(Address(R6, count_offset), R1);
+    __ StoreIntoSmiField(Address(R8, count_offset), R1);
   }
 
   // Load arguments descriptor into R4.
-  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
+  __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
 
   // Get function and call it, if possible.
-  __ LoadFromOffset(kWord, R0, R6, target_offset);
+  __ LoadFromOffset(kWord, R0, R8, target_offset);
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
   __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
   __ bx(R2);
@@ -1671,9 +1674,9 @@
   if (FLAG_support_debugger) {
     __ Bind(&stepping);
     __ EnterStubFrame();
-    __ Push(R5);  // Preserve IC data.
+    __ Push(R9);  // Preserve IC data.
     __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-    __ Pop(R5);
+    __ Pop(R9);
     __ RestoreCodePointer();
     __ LeaveStubFrame();
     __ b(&done_stepping);
@@ -1682,7 +1685,7 @@
 
 
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(
       assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
       kIgnoreRanges);
@@ -1690,7 +1693,7 @@
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
       kIgnoreRanges);
@@ -1698,17 +1701,17 @@
 
 
 // Stub for compiling a function and jumping to the compiled code.
-// R5: IC-Data (for methods).
+// R9: IC-Data (for methods).
 // R4: Arguments descriptor.
 // R0: Function.
 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
   // Preserve arg desc. and IC data object.
   __ EnterStubFrame();
-  __ PushList((1 << R4) | (1 << R5));
+  __ PushList((1 << R4) | (1 << R9));
   __ Push(R0);  // Pass function.
   __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
   __ Pop(R0);  // Restore argument.
-  __ PopList((1 << R4) | (1 << R5));  // Restore arg desc. and IC data.
+  __ PopList((1 << R4) | (1 << R9));  // Restore arg desc. and IC data.
   __ LeaveStubFrame();
 
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
@@ -1717,14 +1720,14 @@
 }
 
 
-// R5: Contains an ICData.
+// R9: Contains an ICData.
 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
   __ EnterStubFrame();
   __ LoadObject(R0, Object::null_object());
   // Preserve arguments descriptor and make room for result.
-  __ PushList((1 << R0) | (1 << R5));
+  __ PushList((1 << R0) | (1 << R9));
   __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ PopList((1 << R0) | (1 << R5));
+  __ PopList((1 << R0) | (1 << R9));
   __ LeaveStubFrame();
   __ mov(CODE_REG, Operand(R0));
   __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset()));
@@ -1779,12 +1782,12 @@
     // Compute instance type arguments into R4.
     Label has_no_type_arguments;
     __ LoadObject(R4, Object::null_object());
-    __ ldr(R5, FieldAddress(R3,
+    __ ldr(R9, FieldAddress(R3,
         Class::type_arguments_field_offset_in_words_offset()));
-    __ CompareImmediate(R5, Class::kNoTypeArguments);
+    __ CompareImmediate(R9, Class::kNoTypeArguments);
     __ b(&has_no_type_arguments, EQ);
-    __ add(R5, R0, Operand(R5, LSL, 2));
-    __ ldr(R4, FieldAddress(R5, 0));
+    __ add(R9, R0, Operand(R9, LSL, 2));
+    __ ldr(R4, FieldAddress(R9, 0));
     __ Bind(&has_no_type_arguments);
   }
   __ LoadClassId(R3, R0);
@@ -1802,24 +1805,24 @@
   // R4: instance type arguments.
   __ SmiTag(R3);
   __ Bind(&loop);
-  __ ldr(R5, Address(R2, kWordSize * SubtypeTestCache::kInstanceClassId));
-  __ CompareObject(R5, Object::null_object());
+  __ ldr(R9, Address(R2, kWordSize * SubtypeTestCache::kInstanceClassId));
+  __ CompareObject(R9, Object::null_object());
   __ b(&not_found, EQ);
-  __ cmp(R5, Operand(R3));
+  __ cmp(R9, Operand(R3));
   if (n == 1) {
     __ b(&found, EQ);
   } else {
     __ b(&next_iteration, NE);
-    __ ldr(R5,
+    __ ldr(R9,
            Address(R2, kWordSize * SubtypeTestCache::kInstanceTypeArguments));
-    __ cmp(R5, Operand(R4));
+    __ cmp(R9, Operand(R4));
     if (n == 2) {
       __ b(&found, EQ);
     } else {
       __ b(&next_iteration, NE);
-      __ ldr(R5, Address(R2, kWordSize *
+      __ ldr(R9, Address(R2, kWordSize *
                              SubtypeTestCache::kInstantiatorTypeArguments));
-      __ cmp(R5, Operand(R1));
+      __ cmp(R9, Operand(R1));
       __ b(&found, EQ);
     }
   }
@@ -1907,14 +1910,14 @@
 
 
 // Calls to the runtime to optimize the given function.
-// R6: function to be reoptimized.
+// R8: function to be reoptimized.
 // R4: argument descriptor (preserved).
 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
   __ EnterStubFrame();
   __ Push(R4);
   __ LoadObject(IP, Object::null_object());
   __ Push(IP);  // Setup space on stack for return value.
-  __ Push(R6);
+  __ Push(R8);
   __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
   __ Pop(R0);  // Discard argument.
   __ Pop(R0);  // Get Code object
@@ -2047,18 +2050,18 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != R0) && (cache != R2));
-  __ LoadTaggedClassIdMayBeSmi(R0, receiver);
-  // R0: class ID of the receiver (smi).
-  __ ldr(R2, FieldAddress(cache, MegamorphicCache::buckets_offset()));
-  __ ldr(R1, FieldAddress(R1, MegamorphicCache::mask_offset()));
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(R0, R0);
+  // R0: receiver cid as Smi.
+  __ ldr(R4, FieldAddress(R9, MegamorphicCache::arguments_descriptor_offset()));
+  __ ldr(R2, FieldAddress(R9, MegamorphicCache::buckets_offset()));
+  __ ldr(R1, FieldAddress(R9, MegamorphicCache::mask_offset()));
   // R2: cache buckets array.
   // R1: mask.
   __ mov(R3, Operand(R0));
+  // R3: probe.
 
-  Label loop, update, call_target_function;
+  Label loop, update, load_target_function;
   __ b(&loop);
 
   __ Bind(&update);
@@ -2068,33 +2071,77 @@
   const intptr_t base = Array::data_offset();
   // R3 is smi tagged, but table entries are two words, so LSL 2.
   __ add(IP, R2, Operand(R3, LSL, 2));
-  __ ldr(R4, FieldAddress(IP, base));
+  __ ldr(R6, FieldAddress(IP, base));
 
   ASSERT(kIllegalCid == 0);
-  __ tst(R4, Operand(R4));
-  __ b(&call_target_function, EQ);
-  __ cmp(R4, Operand(R0));
+  __ tst(R6, Operand(R6));
+  __ b(&load_target_function, EQ);
+  __ cmp(R6, Operand(R0));
   __ b(&update, NE);
 
-  __ Bind(&call_target_function);
+  __ Bind(&load_target_function);
   // Call the target found in the cache.  For a class id match, this is a
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ add(IP, R2, Operand(R3, LSL, 2));
   __ ldr(R0, FieldAddress(IP, base + kWordSize));
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ldr(target, FieldAddress(R0, Function::entry_point_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  R0: receiver.
-//  R1: lookup cache.
+//  R0: receiver
+//  R9: MegamorphicCache (preserved)
 // Result:
-//  R1: entry point.
+//  R1: target entry point
+//  CODE_REG: target Code
+//  R4: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, R0, R1, R1);
+  EmitMegamorphicLookup(assembler);
+  __ Ret();
+}
+
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R9: ICData (preserved)
+// Result:
+//  R1: target entry point
+//  CODE_REG: target Code object
+//  R4: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  Label loop, found, miss;
+  __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
+  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(R1, R0);
+  // R1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ ldr(R2, Address(R8, 0));
+  __ cmp(R1, Operand(R2));
+  __ b(&found, EQ);
+  __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
+  __ b(&miss, EQ);
+
+  const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
+  __ AddImmediate(R8, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
+  __ LoadFromOffset(kWord, R0, R8, target_offset);
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
+  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
+  __ Ret();
+
+  __ Bind(&miss);
+  __ LoadIsolate(R2);
+  __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
   __ Ret();
 }
 
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index facc08c..0585653 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -101,7 +101,7 @@
   // We are entering runtime code, so the C stack pointer must be restored from
   // the stack limit to the top of the stack. We cache the stack limit address
   // in a callee-saved register.
-  __ mov(R26, CSP);
+  __ mov(R25, CSP);
   __ mov(CSP, SP);
 
   __ blr(R5);
@@ -109,7 +109,7 @@
 
   // Restore SP and CSP.
   __ mov(SP, CSP);
-  __ mov(CSP, R26);
+  __ mov(CSP, R25);
 
   // Retval is next to 1st argument.
   // Mark that the thread is executing Dart code.
@@ -204,7 +204,7 @@
   // We are entering runtime code, so the C stack pointer must be restored from
   // the stack limit to the top of the stack. We cache the stack limit address
   // in the Dart SP register, which is callee-saved in the C ABI.
-  __ mov(R26, CSP);
+  __ mov(R25, CSP);
   __ mov(CSP, SP);
 
   __ mov(R1, R5);  // Pass the function entrypoint to call.
@@ -215,7 +215,7 @@
 
   // Restore SP and CSP.
   __ mov(SP, CSP);
-  __ mov(CSP, R26);
+  __ mov(CSP, R25);
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
@@ -297,7 +297,7 @@
   // We are entering runtime code, so the C stack pointer must be restored from
   // the stack limit to the top of the stack. We cache the stack limit address
   // in the Dart SP register, which is callee-saved in the C ABI.
-  __ mov(R26, CSP);
+  __ mov(R25, CSP);
   __ mov(CSP, SP);
 
   // Call native function or redirection via simulator.
@@ -305,7 +305,7 @@
 
   // Restore SP and CSP.
   __ mov(SP, CSP);
-  __ mov(CSP, R26);
+  __ mov(CSP, R25);
 
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
@@ -567,9 +567,9 @@
   __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
   __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize);
   __ PushObject(Object::null_object());
-  __ Push(R6);
-  __ Push(R5);
-  __ Push(R4);
+  __ Push(R6);  // Receiver.
+  __ Push(R5);  // ICData/MegamorphicCache.
+  __ Push(R4);  // Arguments descriptor.
   // R2: Smi-tagged arguments array length.
   PushArgumentsArray(assembler);
   const intptr_t kNumArgs = 4;
@@ -786,7 +786,7 @@
 
   // Copy the C stack pointer (R31) into the stack pointer we'll actually use
   // to access the stack, and put the C stack pointer at the stack limit.
-  __ SetupDartSP(Isolate::GetSpecifiedStackSize());
+  __ SetupDartSP(OSThread::GetSpecifiedStackSize());
   __ EnterFrame(0);
 
   // Push code object to PC marker slot.
@@ -2098,18 +2098,18 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != R0) && (cache != R2));
-  __ LoadTaggedClassIdMayBeSmi(R0, receiver);
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(R0, R0);
   // R0: class ID of the receiver (smi).
-  __ LoadFieldFromOffset(R2, cache, MegamorphicCache::buckets_offset());
-  __ LoadFieldFromOffset(R1, cache, MegamorphicCache::mask_offset());
+  __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset()));
+  __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset()));
+  __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset()));
   // R2: cache buckets array.
   // R1: mask.
   __ mov(R3, R0);
+  // R3: probe.
 
-  Label loop, update, call_target_function;
+  Label loop, update, load_target_function;
   __ b(&loop);
 
   __ Bind(&update);
@@ -2119,33 +2119,77 @@
   const intptr_t base = Array::data_offset();
   // R3 is smi tagged, but table entries are 16 bytes, so LSL 3.
   __ add(TMP, R2, Operand(R3, LSL, 3));
-  __ LoadFieldFromOffset(R4, TMP, base);
+  __ ldr(R6, FieldAddress(TMP, base));
 
   ASSERT(kIllegalCid == 0);
-  __ tst(R4, Operand(R4));
-  __ b(&call_target_function, EQ);
-  __ CompareRegisters(R4, R0);
+  __ tst(R6, Operand(R6));
+  __ b(&load_target_function, EQ);
+  __ CompareRegisters(R6, R0);
   __ b(&update, NE);
 
-  __ Bind(&call_target_function);
+  __ Bind(&load_target_function);
   // Call the target found in the cache.  For a class id match, this is a
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ add(TMP, R2, Operand(R3, LSL, 3));
-  __ LoadFieldFromOffset(R0, TMP, base + kWordSize);
-  __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
-  __ LoadFieldFromOffset(R1, R0, Function::entry_point_offset());
+  __ ldr(R0, FieldAddress(TMP, base + kWordSize));
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
+  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  R0: receiver.
-//  R1: lookup cache.
+//  R0: receiver
+//  R5: MegamorphicCache (preserved)
 // Result:
-//  R1: entry point.
+//  R1: target entry point
+//  CODE_REG: target Code
+//  R4: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, R0, R1, R1);
+  EmitMegamorphicLookup(assembler);
+  __ ret();
+}
+
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R5: ICData (preserved)
+// Result:
+//  R1: target entry point
+//  CODE_REG: target Code object
+//  R4: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  Label loop, found, miss;
+  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
+  __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
+  __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
+  // R8: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(R1, R0);
+  // R1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ ldr(R2, Address(R8, 0));
+  __ cmp(R1, Operand(R2));
+  __ b(&found, EQ);
+  __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
+  __ b(&miss, EQ);
+
+  const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
+  __ AddImmediate(R8, R8, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
+  __ ldr(R0, Address(R8, target_offset));
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
+  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
+  __ ret();
+
+  __ Bind(&miss);
+  __ LoadIsolate(R2);
+  __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
   __ ret();
 }
 
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 8ca11ef..b6302d3 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -481,7 +481,7 @@
       EBP, EDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize));
   __ pushl(raw_null);  // Setup space on stack for result.
   __ pushl(EAX);  // Receiver.
-  __ pushl(ECX);
+  __ pushl(ECX);  // ICData/MegamorphicCache.
   __ pushl(EDX);  // Arguments descriptor array.
   __ movl(EDX, EDI);
   // EDX: Smi-tagged arguments array length.
@@ -2022,19 +2022,18 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != EAX) && (cache != EDI));
-  __ LoadTaggedClassIdMayBeSmi(EAX, receiver);
-
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(EAX, EBX);
   // EAX: class ID of the receiver (smi).
-  __ movl(EDI, FieldAddress(cache, MegamorphicCache::buckets_offset()));
-  __ movl(EBX, FieldAddress(cache, MegamorphicCache::mask_offset()));
+  __ movl(EDI, FieldAddress(ECX, MegamorphicCache::buckets_offset()));
+  __ movl(EBX, FieldAddress(ECX, MegamorphicCache::mask_offset()));
   // EDI: cache buckets array.
   // EBX: mask.
+  __ pushl(ECX);  // Spill MegamorphicCache.
   __ movl(ECX, EAX);
+  // ECX: probe.
 
-  Label loop, update, call_target_function;
+  Label loop, update, load_target_function;
   __ jmp(&loop);
 
   __ Bind(&update);
@@ -2047,31 +2046,45 @@
 
   ASSERT(kIllegalCid == 0);
   __ testl(EDX, EDX);
-  __ j(ZERO, &call_target_function, Assembler::kNearJump);
+  __ j(ZERO, &load_target_function, Assembler::kNearJump);
   __ cmpl(EDX, EAX);
   __ j(NOT_EQUAL, &update, Assembler::kNearJump);
 
-  __ Bind(&call_target_function);
+  __ Bind(&load_target_function);
   // Call the target found in the cache.  For a class id match, this is a
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ movl(EAX, FieldAddress(EDI, ECX, TIMES_4, base + kWordSize));
-  __ movl(target, FieldAddress(EAX, Function::entry_point_offset()));
+  __ popl(ECX);  // Restore MegamorphicCache.
+  __ movl(EDX,
+          FieldAddress(ECX, MegamorphicCache::arguments_descriptor_offset()));
+  __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  ECX: receiver.
-//  EBX: lookup cache.
+//  EBX: receiver
+//  ECX: MegamorphicCache (preserved)
 // Result:
-//  EBX: entry point.
+//  EBX: target entry point
+//  EDX: argument descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, ECX, EBX, EBX);
+  EmitMegamorphicLookup(assembler);
   __ ret();
 }
 
 
+// Called from switchable IC calls.
+//  EBX: receiver
+//  ECX: ICData (preserved)
+// Result:
+//  EBX: target entry point
+//  EDX: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  __ int3();
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 30a7cdf..58af418 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -563,7 +563,7 @@
 
   // Push space for the return value.
   // Push the receiver.
-  // Push IC data object.
+  // Push ICData/MegamorphicCache object.
   // Push arguments descriptor array.
   // Push original arguments array.
   __ addiu(SP, SP, Immediate(-4 * kWordSize));
@@ -2211,16 +2211,16 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != T0) && (cache != T2));
-  __ LoadTaggedClassIdMayBeSmi(T0, receiver);
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(T0, T0);
   // T0: class ID of the receiver (smi).
-  __ lw(T2, FieldAddress(cache, MegamorphicCache::buckets_offset()));
-  __ lw(T1, FieldAddress(cache, MegamorphicCache::mask_offset()));
+  __ lw(S4, FieldAddress(S5, MegamorphicCache::arguments_descriptor_offset()));
+  __ lw(T2, FieldAddress(S5, MegamorphicCache::buckets_offset()));
+  __ lw(T1, FieldAddress(S5, MegamorphicCache::mask_offset()));
   // T2: cache buckets array.
   // T1: mask.
   __ mov(T3, T0);
+  // T3: probe.
 
   Label loop, update, call_target_function;
   __ b(&loop);
@@ -2248,18 +2248,61 @@
   __ addu(T1, T2, T1);
   __ lw(T0, FieldAddress(T1, base + kWordSize));
 
+  __ lw(T1, FieldAddress(T0, Function::entry_point_offset()));
   __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
-  __ lw(target, FieldAddress(T0, Function::entry_point_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  T0: receiver.
-//  T1: lookup cache.
+//  T0: receiver
+//  S5: MegamorphicCache (preserved)
 // Result:
-//  T1: entry point.
+//  T1: target entry point
+//  CODE_REG: target Code
+//  S4: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, T0, T1, T1);
+  EmitMegamorphicLookup(assembler);
+  __ Ret();
+}
+
+
+// Called from switchable IC calls.
+//  T0: receiver
+//  S5: ICData (preserved)
+// Result:
+//  T1: target entry point
+//  CODE_REG: target Code object
+//  S4: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  Label loop, found, miss;
+  __ lw(T6, FieldAddress(S5, ICData::ic_data_offset()));
+  __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
+  __ AddImmediate(T6, T6, Array::data_offset() - kHeapObjectTag);
+  // T6: first IC entry.
+  __ LoadTaggedClassIdMayBeSmi(T1, T0);
+  // T1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ lw(T2, Address(T6, 0));
+  __ beq(T1, T2, &found);
+  ASSERT(Smi::RawValue(kIllegalCid) == 0);
+  __ beq(T2, ZR, &miss);
+
+  const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
+  __ AddImmediate(T6, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
+  __ lw(T0, Address(T6, target_offset));
+  __ lw(T1, FieldAddress(T0, Function::entry_point_offset()));
+  __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
+  __ Ret();
+
+  __ Bind(&miss);
+  __ LoadIsolate(T2);
+  __ lw(CODE_REG, Address(T2, Isolate::ic_miss_code_offset()));
+  __ lw(T1, FieldAddress(CODE_REG, Code::entry_point_offset()));
   __ Ret();
 }
 
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 44d5f96..39d8dc9 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -510,7 +510,7 @@
       RBP, RDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize));
   __ PushObject(Object::null_object());  // Setup space on stack for result.
   __ pushq(RAX);  // Receiver.
-  __ pushq(RBX);
+  __ pushq(RBX);  // ICData/MegamorphicCache.
   __ pushq(R10);  // Arguments descriptor array.
   __ movq(R10, RDI);
   // EDX: Smi-tagged arguments array length.
@@ -2088,52 +2088,99 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(
-    Assembler* assembler, Register receiver, Register cache, Register target) {
-  ASSERT((cache != RAX) && (cache != RDI));
-  __ LoadTaggedClassIdMayBeSmi(RAX, receiver);
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
   // RAX: class ID of the receiver (smi).
-  __ movq(RDI, FieldAddress(cache, MegamorphicCache::buckets_offset()));
-  __ movq(RBX, FieldAddress(cache, MegamorphicCache::mask_offset()));
+  __ movq(R10,
+          FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset()));
+  __ movq(RDI, FieldAddress(RBX, MegamorphicCache::buckets_offset()));
+  __ movq(R9, FieldAddress(RBX, MegamorphicCache::mask_offset()));
   // RDI: cache buckets array.
   // RBX: mask.
   __ movq(RCX, RAX);
 
-  Label loop, update, call_target_function;
+  Label loop, update, load_target_function;
   __ jmp(&loop);
 
   __ Bind(&update);
   __ AddImmediate(RCX, Immediate(Smi::RawValue(1)));
   __ Bind(&loop);
-  __ andq(RCX, RBX);
+  __ andq(RCX, R9);
   const intptr_t base = Array::data_offset();
   // RCX is smi tagged, but table entries are two words, so TIMES_8.
   __ movq(RDX, FieldAddress(RDI, RCX, TIMES_8, base));
 
   ASSERT(kIllegalCid == 0);
   __ testq(RDX, RDX);
-  __ j(ZERO, &call_target_function, Assembler::kNearJump);
+  __ j(ZERO, &load_target_function, Assembler::kNearJump);
   __ cmpq(RDX, RAX);
   __ j(NOT_EQUAL, &update, Assembler::kNearJump);
 
-  __ Bind(&call_target_function);
+  __ Bind(&load_target_function);
   // Call the target found in the cache.  For a class id match, this is a
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize));
+  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
   __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ movq(target, FieldAddress(RAX, Function::entry_point_offset()));
 }
 
 
 // Called from megamorphic calls.
-//  RDI: receiver.
-//  RBX: lookup cache.
+//  RDI: receiver
+//  RBX: MegamorphicCache (preserved)
 // Result:
-//  RCX: entry point.
+//  RCX: target entry point
+//  CODE_REG: target Code
+//  R10: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler, RDI, RBX, RCX);
+  EmitMegamorphicLookup(assembler);
+  __ ret();
+}
+
+
+// Called from switchable IC calls.
+//  RDI: receiver
+//  RBX: ICData (preserved)
+// Result:
+//  RCX: target entry point
+//  CODE_REG: target Code object
+//  R10: arguments descriptor
+void StubCode::GenerateICLookupStub(Assembler* assembler) {
+  Label loop, found, miss;
+
+  __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
+  __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
+  __ leaq(R13, FieldAddress(R13, Array::data_offset()));
+  // R13: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
+  // RAX: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ movq(R9, Address(R13, 0));
+  __ cmpq(RAX, R9);
+  __ j(EQUAL, &found, Assembler::kNearJump);
+
+  ASSERT(Smi::RawValue(kIllegalCid) == 0);
+  __ testq(R9, R9);
+  __ j(ZERO, &miss, Assembler::kNearJump);
+
+  const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
+  __ addq(R13, Immediate(entry_length));  // Next entry.
+  __ jmp(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
+  __ movq(RAX, Address(R13, target_offset));
+  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
+  __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
+  __ ret();
+
+  __ Bind(&miss);
+  __ LoadIsolate(RAX);
+  __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset()));
+  __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset()));
   __ ret();
 }
 
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index d59ea20a..1c40fb5 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -57,7 +57,6 @@
   V(AnonymousClosure, "<anonymous closure>")                                   \
   V(ImplicitClosure, "<implicit closure>")                                     \
   V(ClosureParameter, ":closure")                                              \
-  V(PhaseParameter, ":phase")                                                  \
   V(TypeArgumentsParameter, ":type_arguments")                                 \
   V(AssertionError, "_AssertionError")                                         \
   V(CastError, "_CastError")                                                   \
@@ -305,7 +304,6 @@
   V(OutOfMemoryError, "OutOfMemoryError")                                      \
   V(NullThrownError, "NullThrownError")                                        \
   V(IsolateSpawnException, "IsolateSpawnException")                            \
-  V(IsolateUnhandledException, "_IsolateUnhandledException")                   \
   V(JavascriptIntegerOverflowError, "_JavascriptIntegerOverflowError")         \
   V(JavascriptCompatibilityError, "_JavascriptCompatibilityError")             \
   V(BooleanExpression, "boolean expression")                                   \
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 46da230..c220913 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -4,6 +4,7 @@
 
 #include "vm/thread.h"
 
+#include "vm/dart_api_state.h"
 #include "vm/growable_array.h"
 #include "vm/isolate.h"
 #include "vm/lockers.h"
@@ -20,161 +21,12 @@
 
 namespace dart {
 
-// The single thread local key which stores all the thread local data
-// for a thread.
-ThreadLocalKey Thread::thread_key_ = OSThread::kUnsetThreadLocalKey;
-Thread* Thread::thread_list_head_ = NULL;
-Mutex* Thread::thread_list_lock_ = NULL;
-
-// Remove |thread| from each isolate's thread registry.
-class ThreadPruner : public IsolateVisitor {
- public:
-  explicit ThreadPruner(Thread* thread)
-      : thread_(thread) {
-    ASSERT(thread_ != NULL);
-  }
-
-  void VisitIsolate(Isolate* isolate) {
-    ThreadRegistry* registry = isolate->thread_registry();
-    ASSERT(registry != NULL);
-    registry->PruneThread(thread_);
-  }
- private:
-  Thread* thread_;
-};
-
-
-void Thread::AddThreadToList(Thread* thread) {
-  ASSERT(thread != NULL);
-  ASSERT(thread->isolate() == NULL);
-  ASSERT(thread_list_lock_ != NULL);
-  MutexLocker ml(thread_list_lock_);
-
-  ASSERT(thread->thread_list_next_ == NULL);
-
-#if defined(DEBUG)
-  {
-    // Ensure that we aren't already in the list.
-    Thread* current = thread_list_head_;
-    while (current != NULL) {
-      ASSERT(current != thread);
-      current = current->thread_list_next_;
-    }
-  }
-#endif
-
-  // Insert at head of list.
-  thread->thread_list_next_ = thread_list_head_;
-  thread_list_head_ = thread;
-}
-
-
-void Thread::RemoveThreadFromList(Thread* thread) {
-  ASSERT(thread != NULL);
-  ASSERT(thread->isolate() == NULL);
-  ASSERT(thread_list_lock_ != NULL);
-  MutexLocker ml(thread_list_lock_);
-
-  // Handle case where |thread| is head of list.
-  if (thread_list_head_ == thread) {
-    thread_list_head_ = thread->thread_list_next_;
-    thread->thread_list_next_ = NULL;
-    return;
-  }
-
-  Thread* current = thread_list_head_;
-  Thread* previous = NULL;
-
-  // Scan across list and remove |thread|.
-  while (current != NULL) {
-    previous = current;
-    current = current->thread_list_next_;
-    if (current == thread) {
-      // We found |thread|, remove from list.
-      previous->thread_list_next_ = current->thread_list_next_;
-      thread->thread_list_next_ = NULL;
-      return;
-    }
-  }
-
-  UNREACHABLE();
-}
-
-
-static void DeleteThread(void* thread) {
-  delete reinterpret_cast<Thread*>(thread);
-}
-
-
-void Thread::Shutdown() {
-  if (thread_list_lock_ != NULL) {
-    delete thread_list_lock_;
-    thread_list_lock_ = NULL;
-  }
-}
-
-
 Thread::~Thread() {
   // We should cleanly exit any isolate before destruction.
   ASSERT(isolate_ == NULL);
-  // Clear |this| from all isolate's thread registry.
-  ThreadPruner pruner(this);
-  Isolate::VisitIsolates(&pruner);
-  delete log_;
-  log_ = NULL;
-  RemoveThreadFromList(this);
 }
 
 
-void Thread::InitOnceBeforeIsolate() {
-  ASSERT(thread_list_lock_ == NULL);
-  thread_list_lock_ = new Mutex();
-  ASSERT(thread_list_lock_ != NULL);
-  ASSERT(thread_key_ == OSThread::kUnsetThreadLocalKey);
-  thread_key_ = OSThread::CreateThreadLocal(DeleteThread);
-  ASSERT(thread_key_ != OSThread::kUnsetThreadLocalKey);
-  ASSERT(Thread::Current() == NULL);
-  // Allocate a new Thread and postpone initialization of VM constants for
-  // this first thread.
-  Thread* thread = new Thread(false);
-  // Verify that current thread was set.
-  ASSERT(Thread::Current() == thread);
-}
-
-
-void Thread::InitOnceAfterObjectAndStubCode() {
-  Thread* thread = Thread::Current();
-  ASSERT(thread != NULL);
-  ASSERT(thread->isolate() == Dart::vm_isolate());
-  thread->InitVMConstants();
-}
-
-
-void Thread::SetCurrent(Thread* current) {
-  OSThread::SetThreadLocal(thread_key_, reinterpret_cast<uword>(current));
-}
-
-
-void Thread::EnsureInit() {
-  if (Thread::Current() == NULL) {
-    // Allocate a new Thread.
-    Thread* thread = new Thread();
-    // Verify that current thread was set.
-    ASSERT(Thread::Current() == thread);
-  }
-}
-
-
-#if defined(TARGET_OS_WINDOWS)
-void Thread::CleanUp() {
-  Thread* current = Current();
-  if (current != NULL) {
-    SetCurrent(NULL);
-    delete current;
-  }
-}
-#endif
-
 #if defined(DEBUG)
 #define REUSABLE_HANDLE_SCOPE_INIT(object)                                     \
   reusable_##object##_handle_scope_active_(false),
@@ -186,24 +38,32 @@
   object##_handle_(NULL),
 
 
-Thread::Thread(bool init_vm_constants)
-    : id_(OSThread::GetCurrentThreadId()),
-      thread_interrupt_callback_(NULL),
-      thread_interrupt_data_(NULL),
+Thread::Thread(Isolate* isolate)
+    : BaseThread(false),
+      os_thread_(NULL),
       isolate_(NULL),
       heap_(NULL),
+      zone_(NULL),
+      api_reusable_scope_(NULL),
+      api_top_scope_(NULL),
+      top_exit_frame_info_(0),
+      top_resource_(NULL),
+      long_jump_base_(NULL),
       store_buffer_block_(NULL),
-      log_(new class Log()),
-      deopt_id_(0),
-      vm_tag_(0),
-      REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
-      REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
+      no_callback_scope_depth_(0),
+#if defined(DEBUG)
+      top_handle_scope_(NULL),
+      no_handle_scope_depth_(0),
+      no_safepoint_scope_depth_(0),
+#endif
       reusable_handles_(),
       cha_(NULL),
-      no_callback_scope_depth_(0),
-      thread_list_next_(NULL) {
-  ClearState();
-
+      deopt_id_(0),
+      vm_tag_(0),
+      pending_functions_(GrowableObjectArray::null()),
+      REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
+      REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
+      next_(NULL) {
 #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value)    \
   member_name = default_init_value;
 CACHED_CONSTANTS_LIST(DEFAULT_INIT)
@@ -219,14 +79,59 @@
 LEAF_RUNTIME_ENTRY_LIST(DEFAULT_INIT)
 #undef DEFAULT_INIT
 
-  if (init_vm_constants) {
+  // We cannot initialize the VM constants here for the vm isolate thread
+  // due to boot strapping issues.
+  if ((Dart::vm_isolate() != NULL) && (isolate != Dart::vm_isolate())) {
     InitVMConstants();
   }
-  SetCurrent(this);
-  AddThreadToList(this);
 }
 
 
+static const struct ALIGN16 {
+  uint64_t a;
+  uint64_t b;
+} double_negate_constant =
+    {0x8000000000000000LL, 0x8000000000000000LL};
+
+static const struct ALIGN16 {
+  uint64_t a;
+  uint64_t b;
+} double_abs_constant =
+    {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
+
+static const struct ALIGN16 {
+  uint32_t a;
+  uint32_t b;
+  uint32_t c;
+  uint32_t d;
+} float_not_constant =
+    { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+
+static const struct ALIGN16 {
+  uint32_t a;
+  uint32_t b;
+  uint32_t c;
+  uint32_t d;
+} float_negate_constant =
+    { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
+
+static const struct ALIGN16 {
+  uint32_t a;
+  uint32_t b;
+  uint32_t c;
+  uint32_t d;
+} float_absolute_constant =
+    { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
+
+static const struct ALIGN16 {
+  uint32_t a;
+  uint32_t b;
+  uint32_t c;
+  uint32_t d;
+} float_zerow_constant =
+    { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 };
+
+
 void Thread::InitVMConstants() {
 #define ASSERT_VM_HEAP(type_name, member_name, init_expr, default_init_value)  \
   ASSERT((init_expr)->IsOldObject());
@@ -259,110 +164,95 @@
 }
 
 
-void Thread::Schedule(Isolate* isolate, bool bypass_safepoint) {
-  State st;
-  if (isolate->thread_registry()->RestoreStateTo(this, &st, bypass_safepoint)) {
-    ASSERT(isolate->thread_registry()->Contains(this));
-    state_ = st;
+RawGrowableObjectArray* Thread::pending_functions() {
+  if (pending_functions_ == GrowableObjectArray::null()) {
+    pending_functions_ = GrowableObjectArray::New(Heap::kOld);
   }
+  return pending_functions_;
 }
 
 
-void Thread::Unschedule(bool bypass_safepoint) {
-  ThreadRegistry* reg = isolate_->thread_registry();
-  ASSERT(reg->Contains(this));
-  reg->SaveStateFrom(this, state_, bypass_safepoint);
-  ClearState();
-}
-
-
-void Thread::EnterIsolate(Isolate* isolate) {
-  Thread* thread = Thread::Current();
-  ASSERT(thread != NULL);
-  ASSERT(thread->isolate() == NULL);
-  ASSERT(!isolate->HasMutatorThread());
-  thread->isolate_ = isolate;
-  isolate->MakeCurrentThreadMutator(thread);
-  thread->set_vm_tag(VMTag::kVMTagId);
-  ASSERT(thread->store_buffer_block_ == NULL);
-  thread->StoreBufferAcquire();
-  ASSERT(isolate->heap() != NULL);
-  thread->heap_ = isolate->heap();
-  thread->Schedule(isolate);
-  // TODO(koda): Migrate profiler interface to use Thread.
-  Profiler::BeginExecution(isolate);
+bool Thread::EnterIsolate(Isolate* isolate) {
+  const bool kIsMutatorThread = true;
+  const bool kDontBypassSafepoints = false;
+  ThreadRegistry* tr = isolate->thread_registry();
+  Thread* thread = tr->Schedule(
+      isolate, kIsMutatorThread, kDontBypassSafepoints);
+  if (thread != NULL) {
+    isolate->MakeCurrentThreadMutator(thread);
+    thread->set_vm_tag(VMTag::kVMTagId);
+    ASSERT(thread->store_buffer_block_ == NULL);
+    thread->StoreBufferAcquire();
+    return true;
+  }
+  return false;
 }
 
 
 void Thread::ExitIsolate() {
   Thread* thread = Thread::Current();
-  // TODO(koda): Audit callers; they should know whether they're in an isolate.
-  if (thread == NULL || thread->isolate() == NULL) return;
+  ASSERT(thread != NULL);
+  ASSERT(thread->IsMutatorThread());
 #if defined(DEBUG)
   ASSERT(!thread->IsAnyReusableHandleScopeActive());
 #endif  // DEBUG
   // Clear since GC will not visit the thread once it is unscheduled.
   thread->ClearReusableHandles();
-  Isolate* isolate = thread->isolate();
-  Profiler::EndExecution(isolate);
-  thread->Unschedule();
-  // TODO(koda): Move store_buffer_block_ into State.
   thread->StoreBufferRelease();
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
   if (isolate->is_runnable()) {
     thread->set_vm_tag(VMTag::kIdleTagId);
   } else {
     thread->set_vm_tag(VMTag::kLoadWaitTagId);
   }
+  const bool kIsMutatorThread = true;
+  const bool kDontBypassSafepoints = false;
+  ThreadRegistry* tr = isolate->thread_registry();
+  tr->Unschedule(thread, kIsMutatorThread, kDontBypassSafepoints);
   isolate->ClearMutatorThread();
-  thread->isolate_ = NULL;
-  ASSERT(Isolate::Current() == NULL);
-  thread->heap_ = NULL;
 }
 
 
-void Thread::EnterIsolateAsHelper(Isolate* isolate, bool bypass_safepoint) {
-  Thread* thread = Thread::Current();
-  ASSERT(thread != NULL);
-  ASSERT(thread->isolate() == NULL);
-  thread->isolate_ = isolate;
-  ASSERT(thread->store_buffer_block_ == NULL);
-  // TODO(koda): Use StoreBufferAcquire once we properly flush before Scavenge.
-  thread->store_buffer_block_ =
-      thread->isolate()->store_buffer()->PopEmptyBlock();
-  ASSERT(isolate->heap() != NULL);
-  thread->heap_ = isolate->heap();
-  ASSERT(thread->thread_interrupt_callback_ == NULL);
-  ASSERT(thread->thread_interrupt_data_ == NULL);
-  // Do not update isolate->mutator_thread, but perform sanity check:
-  // this thread should not be both the main mutator and helper.
-  ASSERT(!isolate->MutatorThreadIsCurrentThread());
-  thread->Schedule(isolate, bypass_safepoint);
+bool Thread::EnterIsolateAsHelper(Isolate* isolate, bool bypass_safepoint) {
+  const bool kIsNotMutatorThread = false;
+  ThreadRegistry* tr = isolate->thread_registry();
+  Thread* thread = tr->Schedule(isolate, kIsNotMutatorThread, bypass_safepoint);
+  if (thread != NULL) {
+    ASSERT(thread->store_buffer_block_ == NULL);
+    // TODO(koda): Use StoreBufferAcquire once we properly flush
+    // before Scavenge.
+    thread->store_buffer_block_ =
+        thread->isolate()->store_buffer()->PopEmptyBlock();
+    // This thread should not be the main mutator.
+    ASSERT(!thread->IsMutatorThread());
+    return true;
+  }
+  return false;
 }
 
 
 void Thread::ExitIsolateAsHelper(bool bypass_safepoint) {
   Thread* thread = Thread::Current();
+  ASSERT(thread != NULL);
+  ASSERT(!thread->IsMutatorThread());
+  thread->StoreBufferRelease();
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
-  thread->Unschedule(bypass_safepoint);
-  // TODO(koda): Move store_buffer_block_ into State.
-  thread->StoreBufferRelease();
-  thread->isolate_ = NULL;
-  thread->heap_ = NULL;
-  ASSERT(!isolate->MutatorThreadIsCurrentThread());
+  const bool kIsNotMutatorThread = false;
+  ThreadRegistry* tr = isolate->thread_registry();
+  tr->Unschedule(thread, kIsNotMutatorThread, bypass_safepoint);
 }
 
 
-// TODO(koda): Make non-static and invoke in SafepointThreads.
 void Thread::PrepareForGC() {
-  Thread* thread = Thread::Current();
-  // Prevent scheduling another GC.
-  thread->StoreBufferRelease(StoreBuffer::kIgnoreThreshold);
+  ASSERT(isolate()->thread_registry()->AtSafepoint());
+  // Prevent scheduling another GC by ignoring the threshold.
+  StoreBufferRelease(StoreBuffer::kIgnoreThreshold);
   // Make sure to get an *empty* block; the isolate needs all entries
   // at GC time.
   // TODO(koda): Replace with an epilogue (PrepareAfterGC) that acquires.
-  thread->store_buffer_block_ =
-      thread->isolate()->store_buffer()->PopEmptyBlock();
+  store_buffer_block_ = isolate()->store_buffer()->PopEmptyBlock();
 }
 
 
@@ -391,7 +281,7 @@
 void Thread::StoreBufferRelease(StoreBuffer::ThresholdPolicy policy) {
   StoreBufferBlock* block = store_buffer_block_;
   store_buffer_block_ = NULL;
-  isolate_->store_buffer()->PushBlock(block, policy);
+  isolate()->store_buffer()->PushBlock(block, policy);
 }
 
 
@@ -400,20 +290,30 @@
 }
 
 
-CHA* Thread::cha() const {
-  ASSERT(isolate_ != NULL);
-  return cha_;
+bool Thread::IsMutatorThread() const {
+  return ((isolate_ != NULL) && (isolate_->mutator_thread() == this));
 }
 
 
-void Thread::set_cha(CHA* value) {
-  ASSERT(isolate_ != NULL);
-  cha_ = value;
+bool Thread::CanCollectGarbage() const {
+  // We have non mutator threads grow the heap instead of triggering
+  // a garbage collection when they are at a safepoint (e.g: background
+  // compiler thread finalizing and installing code at a safepoint).
+  // Note: This code will change once the new Safepoint logic is in place.
+  return (IsMutatorThread() ||
+          (isolate_ != NULL && !isolate_->thread_registry()->AtSafepoint()));
 }
 
 
-Log* Thread::log() const {
-  return log_;
+bool Thread::IsExecutingDartCode() const {
+  return (top_exit_frame_info() == 0) &&
+         (vm_tag() == VMTag::kDartTagId);
+}
+
+
+bool Thread::HasExitedDartCode() const {
+  return (top_exit_frame_info() != 0) &&
+         (vm_tag() != VMTag::kDartTagId);
 }
 
 
@@ -438,32 +338,19 @@
 
   // Visit objects in thread specific handles area.
   reusable_handles_.VisitObjectPointers(visitor);
-}
 
+  // Visit the pending functions.
+  if (pending_functions_ != GrowableObjectArray::null()) {
+    visitor->VisitPointer(
+        reinterpret_cast<RawObject**>(&pending_functions_));
+  }
 
-void Thread::SetThreadInterrupter(ThreadInterruptCallback callback,
-                                  void* data) {
-  ASSERT(Thread::Current() == this);
-  thread_interrupt_callback_ = callback;
-  thread_interrupt_data_ = data;
-}
-
-
-bool Thread::IsThreadInterrupterEnabled(ThreadInterruptCallback* callback,
-                                        void** data) const {
-#if defined(TARGET_OS_WINDOWS)
-  // On Windows we expect this to be called from the thread interrupter thread.
-  ASSERT(id() != OSThread::GetCurrentThreadId());
-#else
-  // On posix platforms, we expect this to be called from signal handler.
-  ASSERT(id() == OSThread::GetCurrentThreadId());
-#endif
-  ASSERT(callback != NULL);
-  ASSERT(data != NULL);
-  *callback = thread_interrupt_callback_;
-  *data = thread_interrupt_data_;
-  return (*callback != NULL) &&
-         (*data != NULL);
+  // Visit the api local scope as it has all the api local handles.
+  ApiLocalScope* scope = api_top_scope_;
+  while (scope != NULL) {
+    scope->local_handles()->VisitObjectPointers(visitor);
+    scope = scope->previous();
+  }
 }
 
 
@@ -487,6 +374,18 @@
 }
 
 
+bool Thread::ObjectAtOffset(intptr_t offset, Object* object) {
+#define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value)       \
+  if (Thread::member_name##offset() == offset) {                               \
+    *object = expr;                                                            \
+    return true;                                                               \
+  }
+CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET)
+#undef COMPUTE_OFFSET
+  return false;
+}
+
+
 intptr_t Thread::OffsetFromThread(const RuntimeEntry* runtime_entry) {
 #define COMPUTE_OFFSET(name)                                                   \
   if (runtime_entry->function() == k##name##RuntimeEntry.function())         { \
@@ -507,35 +406,70 @@
 }
 
 
-ThreadIterator::ThreadIterator() {
-  ASSERT(Thread::thread_list_lock_ != NULL);
-  // Lock the thread list while iterating.
-  Thread::thread_list_lock_->Lock();
-  next_ = Thread::thread_list_head_;
+bool Thread::IsValidLocalHandle(Dart_Handle object) const {
+  ApiLocalScope* scope = api_top_scope_;
+  while (scope != NULL) {
+    if (scope->local_handles()->IsValidHandle(object)) {
+      return true;
+    }
+    scope = scope->previous();
+  }
+  return false;
 }
 
 
-ThreadIterator::~ThreadIterator() {
-  ASSERT(Thread::thread_list_lock_ != NULL);
-  // Unlock the thread list when done.
-  Thread::thread_list_lock_->Unlock();
+int Thread::CountLocalHandles() const {
+  int total = 0;
+  ApiLocalScope* scope = api_top_scope_;
+  while (scope != NULL) {
+    total += scope->local_handles()->CountHandles();
+    scope = scope->previous();
+  }
+  return total;
 }
 
 
-bool ThreadIterator::HasNext() const {
-  ASSERT(Thread::thread_list_lock_ != NULL);
-  ASSERT(Thread::thread_list_lock_->IsOwnedByCurrentThread());
-  return next_ != NULL;
+int Thread::ZoneSizeInBytes() const {
+  int total = 0;
+  ApiLocalScope* scope = api_top_scope_;
+  while (scope != NULL) {
+    total += scope->zone()->SizeInBytes();
+    scope = scope->previous();
+  }
+  return total;
 }
 
 
-Thread* ThreadIterator::Next() {
-  ASSERT(Thread::thread_list_lock_ != NULL);
-  ASSERT(Thread::thread_list_lock_->IsOwnedByCurrentThread());
-  Thread* current = next_;
-  next_ = next_->thread_list_next_;
-  return current;
+void Thread::UnwindScopes(uword stack_marker) {
+  // Unwind all scopes using the same stack_marker, i.e. all scopes allocated
+  // under the same top_exit_frame_info.
+  ApiLocalScope* scope = api_top_scope_;
+  while (scope != NULL &&
+         scope->stack_marker() != 0 &&
+         scope->stack_marker() == stack_marker) {
+    api_top_scope_ = scope->previous();
+    delete scope;
+    scope = api_top_scope_;
+  }
 }
 
 
+DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread)
+    : StackResource(thread) {
+  if (thread != NULL) {
+    OSThread* os_thread = thread->os_thread();
+    ASSERT(os_thread != NULL);
+    os_thread->DisableThreadInterrupts();
+  }
+}
+
+
+DisableThreadInterruptsScope::~DisableThreadInterruptsScope() {
+  if (thread() != NULL) {
+    OSThread* os_thread = thread()->os_thread();
+    ASSERT(os_thread != NULL);
+    os_thread->EnableThreadInterrupts();
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 210fef1..ad073af 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -5,6 +5,7 @@
 #ifndef VM_THREAD_H_
 #define VM_THREAD_H_
 
+#include "include/dart_api.h"
 #include "vm/globals.h"
 #include "vm/handles.h"
 #include "vm/os_thread.h"
@@ -14,6 +15,7 @@
 namespace dart {
 
 class AbstractType;
+class ApiLocalScope;
 class Array;
 class CHA;
 class Class;
@@ -28,18 +30,18 @@
 class Instance;
 class Isolate;
 class Library;
-class Log;
 class LongJumpScope;
 class Object;
+class OSThread;
 class PcDescriptors;
 class RawBool;
 class RawObject;
 class RawCode;
+class RawGrowableObjectArray;
 class RawString;
 class RuntimeEntry;
 class StackResource;
 class String;
-class TimelineEventBlock;
 class TypeArguments;
 class TypeParameter;
 class Zone;
@@ -77,7 +79,6 @@
   V(RawCode*, invoke_dart_code_stub_,                                          \
     StubCode::InvokeDartCode_entry()->code(), NULL)                            \
 
-
 #define CACHED_ADDRESSES_LIST(V)                                               \
   V(uword, update_store_buffer_entry_point_,                                   \
     StubCode::UpdateStoreBuffer_entry()->EntryPoint(), 0)                      \
@@ -85,49 +86,43 @@
     NativeEntry::NativeCallWrapperEntry(), 0)                                  \
   V(RawString**, predefined_symbols_address_,                                  \
     Symbols::PredefinedAddress(), NULL)                                        \
+  V(uword, double_negate_address_,                                             \
+    reinterpret_cast<uword>(&double_negate_constant), 0)                       \
+  V(uword, double_abs_address_,                                                \
+    reinterpret_cast<uword>(&double_abs_constant), 0)                          \
+  V(uword, float_not_address_,                                                 \
+    reinterpret_cast<uword>(&float_not_constant), 0)                           \
+  V(uword, float_negate_address_,                                              \
+    reinterpret_cast<uword>(&float_negate_constant), 0)                        \
+  V(uword, float_absolute_address_,                                            \
+    reinterpret_cast<uword>(&float_absolute_constant), 0)                      \
+  V(uword, float_zerow_address_,                                               \
+    reinterpret_cast<uword>(&float_zerow_constant), 0)                         \
 
 #define CACHED_CONSTANTS_LIST(V)                                               \
   CACHED_VM_OBJECTS_LIST(V)                                                    \
   CACHED_ADDRESSES_LIST(V)                                                     \
 
-struct InterruptedThreadState {
-  ThreadId tid;
-  uintptr_t pc;
-  uintptr_t csp;
-  uintptr_t dsp;
-  uintptr_t fp;
-  uintptr_t lr;
-};
-
-// When a thread is interrupted the thread specific interrupt callback will be
-// invoked. Each callback is given an InterruptedThreadState and the user data
-// pointer. When inside a thread interrupt callback doing any of the following
-// is forbidden:
-//   * Accessing TLS -- Because on Windows the callback will be running in a
-//                      different thread.
-//   * Allocating memory -- Because this takes locks which may already be held,
-//                          resulting in a dead lock.
-//   * Taking a lock -- See above.
-typedef void (*ThreadInterruptCallback)(const InterruptedThreadState& state,
-                                        void* data);
-
 // A VM thread; may be executing Dart code or performing helper tasks like
 // garbage collection or compilation. The Thread structure associated with
 // a thread is allocated by EnsureInit before entering an isolate, and destroyed
 // automatically when the underlying OS thread exits. NOTE: On Windows, CleanUp
 // must currently be called manually (issue 23474).
-class Thread {
+class Thread : public BaseThread {
  public:
+  ~Thread();
+
   // The currently executing thread, or NULL if not yet initialized.
   static Thread* Current() {
-    return reinterpret_cast<Thread*>(OSThread::GetThreadLocal(thread_key_));
+    BaseThread* thread = OSThread::GetCurrentTLS();
+    if (thread == NULL || thread->is_os_thread()) {
+      return NULL;
+    }
+    return reinterpret_cast<Thread*>(thread);
   }
 
-  // Initializes the current thread as a VM thread, if not already done.
-  static void EnsureInit();
-
   // Makes the current thread enter 'isolate'.
-  static void EnterIsolate(Isolate* isolate);
+  static bool EnterIsolate(Isolate* isolate);
   // Makes the current thread exit its isolate.
   static void ExitIsolate();
 
@@ -135,40 +130,58 @@
   // "helper" to gain limited concurrent access to the isolate. One example is
   // SweeperTask (which uses the class table, which is copy-on-write).
   // TODO(koda): Properly synchronize heap access to expand allowed operations.
-  static void EnterIsolateAsHelper(Isolate* isolate,
+  static bool EnterIsolateAsHelper(Isolate* isolate,
                                    bool bypass_safepoint = false);
   static void ExitIsolateAsHelper(bool bypass_safepoint = false);
 
-  // Called when the current thread transitions from mutator to collector.
   // Empties the store buffer block into the isolate.
-  // TODO(koda): Always run GC in separate thread.
-  static void PrepareForGC();
+  void PrepareForGC();
 
-#if defined(TARGET_OS_WINDOWS)
-  // Clears the state of the current thread and frees the allocation.
-  static void CleanUp();
-#endif
-
-  // Called at VM startup.
-  static void InitOnceBeforeIsolate();
-  static void InitOnceAfterObjectAndStubCode();
-
-  // Called at VM shutdown
-  static void Shutdown();
-  ~Thread();
+  // OSThread corresponding to this thread.
+  OSThread* os_thread() const { return os_thread_; }
+  void set_os_thread(OSThread* os_thread) {
+    os_thread_ = os_thread;
+  }
 
   // The topmost zone used for allocation in this thread.
-  Zone* zone() const { return state_.zone; }
+  Zone* zone() const { return zone_; }
+
+  // The reusable api local scope for this thread.
+  ApiLocalScope* api_reusable_scope() const { return api_reusable_scope_; }
+  void set_api_reusable_scope(ApiLocalScope* value) {
+    ASSERT(value == NULL || api_reusable_scope_ == NULL);
+    api_reusable_scope_ = value;
+  }
+
+  // The api local scope for this thread, this where all local handles
+  // are allocated.
+  ApiLocalScope* api_top_scope() const { return api_top_scope_; }
+  void set_api_top_scope(ApiLocalScope* value) { api_top_scope_ = value; }
 
   // 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_);
   }
+  bool IsMutatorThread() const;
+  bool CanCollectGarbage() const;
+
+  // Is |this| executing Dart code?
+  bool IsExecutingDartCode() const;
+
+  // Has |this| exited Dart code?
+  bool HasExitedDartCode() const;
 
   // The (topmost) CHA for the compilation in this thread.
-  CHA* cha() const;
-  void set_cha(CHA* value);
+  CHA* cha() const {
+    ASSERT(isolate_ != NULL);
+    return cha_;
+  }
+
+  void set_cha(CHA* value) {
+    ASSERT(isolate_ != NULL);
+    cha_ = value;
+  }
 
   int32_t no_callback_scope_depth() const {
     return no_callback_scope_depth_;
@@ -196,26 +209,28 @@
     return OFFSET_OF(Thread, store_buffer_block_);
   }
 
-  uword top_exit_frame_info() const { return state_.top_exit_frame_info; }
+  uword top_exit_frame_info() const { return top_exit_frame_info_; }
   static intptr_t top_exit_frame_info_offset() {
-    return OFFSET_OF(Thread, state_) + OFFSET_OF(State, top_exit_frame_info);
+    return OFFSET_OF(Thread, top_exit_frame_info_);
   }
 
-  StackResource* top_resource() const { return state_.top_resource; }
+  StackResource* top_resource() const { return top_resource_; }
   void set_top_resource(StackResource* value) {
-    state_.top_resource = value;
+    top_resource_ = value;
   }
   static intptr_t top_resource_offset() {
-    return OFFSET_OF(Thread, state_) + OFFSET_OF(State, top_resource);
+    return OFFSET_OF(Thread, top_resource_);
   }
 
+  // Heap of the isolate that this thread is operating on.
+  Heap* heap() const { return heap_; }
   static intptr_t heap_offset() {
     return OFFSET_OF(Thread, heap_);
   }
 
   int32_t no_handle_scope_depth() const {
 #if defined(DEBUG)
-    return state_.no_handle_scope_depth;
+    return no_handle_scope_depth_;
 #else
     return 0;
 #endif
@@ -223,21 +238,21 @@
 
   void IncrementNoHandleScopeDepth() {
 #if defined(DEBUG)
-    ASSERT(state_.no_handle_scope_depth < INT_MAX);
-    state_.no_handle_scope_depth += 1;
+    ASSERT(no_handle_scope_depth_ < INT_MAX);
+    no_handle_scope_depth_ += 1;
 #endif
   }
 
   void DecrementNoHandleScopeDepth() {
 #if defined(DEBUG)
-    ASSERT(state_.no_handle_scope_depth > 0);
-    state_.no_handle_scope_depth -= 1;
+    ASSERT(no_handle_scope_depth_ > 0);
+    no_handle_scope_depth_ -= 1;
 #endif
   }
 
   HandleScope* top_handle_scope() const {
 #if defined(DEBUG)
-    return state_.top_handle_scope;
+    return top_handle_scope_;
 #else
     return 0;
 #endif
@@ -245,13 +260,13 @@
 
   void set_top_handle_scope(HandleScope* handle_scope) {
 #if defined(DEBUG)
-    state_.top_handle_scope = handle_scope;
+    top_handle_scope_ = handle_scope;
 #endif
   }
 
   int32_t no_safepoint_scope_depth() const {
 #if defined(DEBUG)
-    return state_.no_safepoint_scope_depth;
+    return no_safepoint_scope_depth_;
 #else
     return 0;
 #endif
@@ -259,33 +274,18 @@
 
   void IncrementNoSafepointScopeDepth() {
 #if defined(DEBUG)
-    ASSERT(state_.no_safepoint_scope_depth < INT_MAX);
-    state_.no_safepoint_scope_depth += 1;
+    ASSERT(no_safepoint_scope_depth_ < INT_MAX);
+    no_safepoint_scope_depth_ += 1;
 #endif
   }
 
   void DecrementNoSafepointScopeDepth() {
 #if defined(DEBUG)
-    ASSERT(state_.no_safepoint_scope_depth > 0);
-    state_.no_safepoint_scope_depth -= 1;
+    ASSERT(no_safepoint_scope_depth_ > 0);
+    no_safepoint_scope_depth_ -= 1;
 #endif
   }
 
-  // Collection of isolate-specific state of a thread that is saved/restored
-  // on isolate exit/re-entry.
-  struct State {
-    Zone* zone;
-    uword top_exit_frame_info;
-    StackResource* top_resource;
-    TimelineEventBlock* timeline_block;
-    LongJumpScope* long_jump_base;
-#if defined(DEBUG)
-    HandleScope* top_handle_scope;
-    intptr_t no_handle_scope_depth;
-    int32_t no_safepoint_scope_depth;
-#endif
-  };
-
 #define DEFINE_OFFSET_METHOD(type_name, member_name, expr, default_init_value) \
   static intptr_t member_name##offset() {                                      \
     return OFFSET_OF(Thread, member_name);                                     \
@@ -309,24 +309,9 @@
 
   static bool CanLoadFromThread(const Object& object);
   static intptr_t OffsetFromThread(const Object& object);
+  static bool ObjectAtOffset(intptr_t offset, Object* object);
   static intptr_t OffsetFromThread(const RuntimeEntry* runtime_entry);
 
-  Mutex* timeline_block_lock() {
-    return &timeline_block_lock_;
-  }
-
-  // Only safe to access when holding |timeline_block_lock_|.
-  TimelineEventBlock* timeline_block() const {
-    return state_.timeline_block;
-  }
-
-  // Only safe to access when holding |timeline_block_lock_|.
-  void set_timeline_block(TimelineEventBlock* block) {
-    state_.timeline_block = block;
-  }
-
-  class Log* log() const;
-
   static const intptr_t kNoDeoptId = -1;
   static const intptr_t kDeoptIdStep = 2;
   static const intptr_t kDeoptIdBeforeOffset = 0;
@@ -356,9 +341,9 @@
     return (deopt_id % kDeoptIdStep) == kDeoptIdAfterOffset;
   }
 
-  LongJumpScope* long_jump_base() const { return state_.long_jump_base; }
+  LongJumpScope* long_jump_base() const { return long_jump_base_; }
   void set_long_jump_base(LongJumpScope* value) {
-    state_.long_jump_base = value;
+    long_jump_base_ = value;
   }
 
   uword vm_tag() const {
@@ -371,16 +356,6 @@
     return OFFSET_OF(Thread, vm_tag_);
   }
 
-  ThreadId id() const {
-    ASSERT(id_ != OSThread::kInvalidThreadId);
-    return id_;
-  }
-
-  void SetThreadInterrupter(ThreadInterruptCallback callback, void* data);
-
-  bool IsThreadInterrupterEnabled(ThreadInterruptCallback* callback,
-                                  void** data) const;
-
 #if defined(DEBUG)
 #define REUSABLE_HANDLE_SCOPE_ACCESSORS(object)                                \
   void set_reusable_##object##_handle_scope_active(bool value) {               \
@@ -410,24 +385,46 @@
   REUSABLE_HANDLE_LIST(REUSABLE_HANDLE)
 #undef REUSABLE_HANDLE
 
+  RawGrowableObjectArray* pending_functions();
+
+  // Visit all object pointers.
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
+  bool IsValidLocalHandle(Dart_Handle object) const;
+  int CountLocalHandles() const;
+  int ZoneSizeInBytes() const;
+  void UnwindScopes(uword stack_marker);
+
+  void InitVMConstants();
+
  private:
   template<class T> T* AllocateReusableHandle();
 
-  static ThreadLocalKey thread_key_;
-
-  const ThreadId id_;
-  ThreadInterruptCallback thread_interrupt_callback_;
-  void* thread_interrupt_data_;
+  OSThread* os_thread_;
   Isolate* isolate_;
   Heap* heap_;
-  State state_;
-  Mutex timeline_block_lock_;
+  Zone* zone_;
+  ApiLocalScope* api_reusable_scope_;
+  ApiLocalScope* api_top_scope_;
+  uword top_exit_frame_info_;
+  StackResource* top_resource_;
+  LongJumpScope* long_jump_base_;
   StoreBufferBlock* store_buffer_block_;
-  class Log* log_;
+  int32_t no_callback_scope_depth_;
+#if defined(DEBUG)
+  HandleScope* top_handle_scope_;
+  int32_t no_handle_scope_depth_;
+  int32_t no_safepoint_scope_depth_;
+#endif
+  VMHandles reusable_handles_;
+
+  // Compiler state:
+  CHA* cha_;
   intptr_t deopt_id_;  // Compilation specific counter.
   uword vm_tag_;
+  RawGrowableObjectArray* pending_functions_;
+
+  // State that is cached in the TLS for fast access in generated code.
 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value)      \
   type_name member_name;
 CACHED_CONSTANTS_LIST(DECLARE_MEMBERS)
@@ -456,44 +453,25 @@
 #undef REUSABLE_HANDLE_SCOPE_VARIABLE
 #endif  // defined(DEBUG)
 
-  VMHandles reusable_handles_;
+  Thread* next_;  // Used to chain the thread structures in an isolate.
 
-  CHA* cha_;
-  int32_t no_callback_scope_depth_;
-
-  // All |Thread|s are registered in the thread list.
-  Thread* thread_list_next_;
-
-  static Thread* thread_list_head_;
-  static Mutex* thread_list_lock_;
-
-  static void AddThreadToList(Thread* thread);
-  static void RemoveThreadFromList(Thread* thread);
-
-  explicit Thread(bool init_vm_constants = true);
-
-  void InitVMConstants();
-
-  void ClearState() {
-    memset(&state_, 0, sizeof(state_));
-  }
+  explicit Thread(Isolate* isolate);
 
   void StoreBufferRelease(
       StoreBuffer::ThresholdPolicy policy = StoreBuffer::kCheckThreshold);
   void StoreBufferAcquire();
 
   void set_zone(Zone* zone) {
-    state_.zone = zone;
+    zone_ = zone;
   }
 
   void set_top_exit_frame_info(uword top_exit_frame_info) {
-    state_.top_exit_frame_info = top_exit_frame_info;
+    top_exit_frame_info_ = top_exit_frame_info;
   }
 
-  static void SetCurrent(Thread* current);
-
-  void Schedule(Isolate* isolate, bool bypass_safepoint = false);
-  void Unschedule(bool bypass_safepoint = false);
+  static void SetCurrent(Thread* current) {
+    OSThread::SetCurrentTLS(reinterpret_cast<uword>(current));
+  }
 
 #define REUSABLE_FRIEND_DECLARATION(name)                                      \
   friend class Reusable##name##HandleScope;
@@ -502,30 +480,25 @@
 
   friend class ApiZone;
   friend class Isolate;
+  friend class Simulator;
   friend class StackZone;
-  friend class ThreadIterator;
-  friend class ThreadIteratorTestHelper;
   friend class ThreadRegistry;
 
   DISALLOW_COPY_AND_ASSIGN(Thread);
 };
 
 
-// Note that this takes the thread list lock, prohibiting threads from coming
-// on- or off-line.
-class ThreadIterator : public ValueObject {
+#if defined(TARGET_OS_WINDOWS)
+// Clears the state of the current thread and frees the allocation.
+void WindowsThreadCleanUp();
+#endif
+
+
+// Disable thread interrupts.
+class DisableThreadInterruptsScope : public StackResource {
  public:
-  ThreadIterator();
-  ~ThreadIterator();
-
-  // Returns false when there are no more threads left.
-  bool HasNext() const;
-
-  // Returns the current thread and moves forward.
-  Thread* Next();
-
- private:
-  Thread* next_;
+  explicit DisableThreadInterruptsScope(Thread* thread);
+  ~DisableThreadInterruptsScope();
 };
 
 }  // namespace dart
diff --git a/runtime/vm/thread_interrupter.cc b/runtime/vm/thread_interrupter.cc
index 58c94be..920baf6 100644
--- a/runtime/vm/thread_interrupter.cc
+++ b/runtime/vm/thread_interrupter.cc
@@ -51,6 +51,7 @@
 bool ThreadInterrupter::initialized_ = false;
 bool ThreadInterrupter::shutdown_ = false;
 bool ThreadInterrupter::thread_running_ = false;
+bool ThreadInterrupter::woken_up_ = false;
 ThreadJoinId ThreadInterrupter::interrupter_thread_id_ =
     OSThread::kInvalidThreadJoinId;
 Monitor* ThreadInterrupter::monitor_ = NULL;
@@ -74,7 +75,7 @@
   ASSERT(interrupter_thread_id_ == OSThread::kInvalidThreadJoinId);
   {
     MonitorLocker startup_ml(monitor_);
-    OSThread::Start(ThreadMain, 0);
+    OSThread::Start("ThreadInterrupter", ThreadMain, 0);
     while (!thread_running_) {
       startup_ml.Wait();
     }
@@ -112,6 +113,7 @@
   }
 }
 
+
 // Delay between interrupts.
 void ThreadInterrupter::SetInterruptPeriod(intptr_t period) {
   if (shutdown_) {
@@ -124,9 +126,14 @@
 
 
 void ThreadInterrupter::WakeUp() {
+  if (!initialized_) {
+    // Early call.
+    return;
+  }
   ASSERT(initialized_);
   {
     MonitorLocker ml(monitor_);
+    woken_up_ = true;
     if (!InDeepSleep()) {
       // No need to notify, regularly waking up.
       return;
@@ -137,35 +144,6 @@
 }
 
 
-void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data) {
-  // NoOp.
-}
-
-
-class ThreadInterrupterVisitIsolates : public IsolateVisitor {
- public:
-  ThreadInterrupterVisitIsolates() {
-    profiled_thread_count_ = 0;
-  }
-
-  void VisitIsolate(Isolate* isolate) {
-    ASSERT(isolate != NULL);
-    profiled_thread_count_ += isolate->ProfileInterrupt();
-  }
-
-  intptr_t profiled_thread_count() const {
-    return profiled_thread_count_;
-  }
-
-  void set_profiled_thread_count(intptr_t profiled_thread_count) {
-    profiled_thread_count_ = profiled_thread_count;
-  }
-
- private:
-  intptr_t profiled_thread_count_;
-};
-
-
 void ThreadInterrupter::ThreadMain(uword parameters) {
   ASSERT(initialized_);
   InstallSignalHandler();
@@ -175,40 +153,62 @@
   {
     // Signal to main thread we are ready.
     MonitorLocker startup_ml(monitor_);
-    interrupter_thread_id_ = OSThread::GetCurrentThreadJoinId();
+    OSThread* os_thread = OSThread::Current();
+    ASSERT(os_thread != NULL);
+    interrupter_thread_id_ = os_thread->join_id();
     thread_running_ = true;
     startup_ml.Notify();
   }
   {
-    ThreadInterrupterVisitIsolates visitor;
+    intptr_t interrupted_thread_count = 0;
     current_wait_time_ = interrupt_period_;
     MonitorLocker wait_ml(monitor_);
     while (!shutdown_) {
       intptr_t r = wait_ml.WaitMicros(current_wait_time_);
 
-      if ((r == Monitor::kNotified) && shutdown_) {
+      if (shutdown_) {
         break;
       }
 
       if ((r == Monitor::kNotified) && InDeepSleep()) {
         // Woken up from deep sleep.
-        ASSERT(visitor.profiled_thread_count() == 0);
+        ASSERT(interrupted_thread_count == 0);
         // Return to regular interrupts.
         current_wait_time_ = interrupt_period_;
       }
 
-      // Reset count before visiting isolates.
-      visitor.set_profiled_thread_count(0);
-      Isolate::VisitIsolates(&visitor);
+      // Reset count before interrupting any threads.
+      interrupted_thread_count = 0;
 
-      if (visitor.profiled_thread_count() == 0) {
-        // No isolates were profiled. In order to reduce unnecessary CPU
-        // load, we will wait until we are notified before attempting to
-        // interrupt again.
+      // Temporarily drop the monitor while we interrupt threads.
+      monitor_->Exit();
+
+      {
+        OSThreadIterator it;
+        while (it.HasNext()) {
+          OSThread* thread = it.Next();
+          if (thread->ThreadInterruptsEnabled()) {
+            interrupted_thread_count++;
+            InterruptThread(thread);
+          }
+        }
+      }
+
+      // Take the monitor lock again.
+      monitor_->Enter();
+
+      // Now that we have the lock, check if we were signaled to wake up while
+      // interrupting threads.
+      if (!woken_up_ && (interrupted_thread_count == 0)) {
+        // No threads were interrupted and we were not signaled to interrupt
+        // new threads. In order to reduce unnecessary CPU load, we will wait
+        // until we are notified before attempting to interrupt again.
         current_wait_time_ = Monitor::kNoTimeout;
         continue;
       }
 
+      woken_up_ = false;
+
       ASSERT(current_wait_time_ != Monitor::kNoTimeout);
     }
   }
diff --git a/runtime/vm/thread_interrupter.h b/runtime/vm/thread_interrupter.h
index 9d3ccab..82e0474 100644
--- a/runtime/vm/thread_interrupter.h
+++ b/runtime/vm/thread_interrupter.h
@@ -12,6 +12,15 @@
 
 namespace dart {
 
+struct InterruptedThreadState {
+  uintptr_t pc;
+  uintptr_t csp;
+  uintptr_t dsp;
+  uintptr_t fp;
+  uintptr_t lr;
+};
+
+
 class ThreadInterrupter : public AllStatic {
  public:
   static void InitOnce();
@@ -25,21 +34,15 @@
   // Wake up the thread interrupter thread.
   static void WakeUp();
 
-  // Register the currently running thread for interrupts. If the current thread
-  // is already registered, callback and data will be updated.
-  static void Register(ThreadInterruptCallback callback, void* data);
-
-  // Unregister the currently running thread for interrupts.
-  static void Unregister();
-
   // Interrupt a thread.
-  static void InterruptThread(Thread* thread);
+  static void InterruptThread(OSThread* thread);
 
  private:
   static const intptr_t kMaxThreads = 4096;
   static bool initialized_;
   static bool shutdown_;
   static bool thread_running_;
+  static bool woken_up_;
   static ThreadJoinId interrupter_thread_id_;
   static Monitor* monitor_;
   static intptr_t interrupt_period_;
@@ -49,8 +52,6 @@
     return current_wait_time_ == Monitor::kNoTimeout;
   }
 
-  static void UpdateStateObject(ThreadInterruptCallback callback, void* data);
-
   static void ThreadMain(uword parameters);
 
   static void InstallSignalHandler();
@@ -60,8 +61,6 @@
   friend class ThreadInterrupterVisitIsolates;
 };
 
-void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data);
-
 }  // namespace dart
 
 #endif  // VM_THREAD_INTERRUPTER_H_
diff --git a/runtime/vm/thread_interrupter_android.cc b/runtime/vm/thread_interrupter_android.cc
index 5c4092d..6656775 100644
--- a/runtime/vm/thread_interrupter_android.cc
+++ b/runtime/vm/thread_interrupter_android.cc
@@ -6,9 +6,11 @@
 #if defined(TARGET_OS_ANDROID)
 
 #include <sys/syscall.h>  // NOLINT
+#include <errno.h>  // NOLINT
 
 #include "vm/flags.h"
 #include "vm/os.h"
+#include "vm/profiler.h"
 #include "vm/signal_handler.h"
 #include "vm/thread_interrupter.h"
 
@@ -28,33 +30,27 @@
     if (thread == NULL) {
       return;
     }
-    ThreadInterruptCallback callback = NULL;
-    void* callback_data = NULL;
-    if (!thread->IsThreadInterrupterEnabled(&callback, &callback_data)) {
-      return;
-    }
     // Extract thread state.
     ucontext_t* context = reinterpret_cast<ucontext_t*>(context_);
     mcontext_t mcontext = context->uc_mcontext;
     InterruptedThreadState its;
-    its.tid = thread->id();
     its.pc = SignalHandler::GetProgramCounter(mcontext);
     its.fp = SignalHandler::GetFramePointer(mcontext);
     its.csp = SignalHandler::GetCStackPointer(mcontext);
     its.dsp = SignalHandler::GetDartStackPointer(mcontext);
     its.lr = SignalHandler::GetLinkRegister(mcontext);
-    callback(its, callback_data);
+    Profiler::SampleThread(thread, its);
   }
 };
 
 
-void ThreadInterrupter::InterruptThread(Thread* thread) {
+void ThreadInterrupter::InterruptThread(OSThread* thread) {
   if (FLAG_trace_thread_interrupter) {
     OS::Print("ThreadInterrupter interrupting %p\n",
               reinterpret_cast<void*>(thread->id()));
   }
   int result = syscall(__NR_tgkill, getpid(), thread->id(), SIGPROF);
-  ASSERT(result == 0);
+  ASSERT((result == 0) || (result == ESRCH));
 }
 
 
diff --git a/runtime/vm/thread_interrupter_linux.cc b/runtime/vm/thread_interrupter_linux.cc
index d7b9b85..28ec681 100644
--- a/runtime/vm/thread_interrupter_linux.cc
+++ b/runtime/vm/thread_interrupter_linux.cc
@@ -5,8 +5,11 @@
 #include "platform/globals.h"
 #if defined(TARGET_OS_LINUX)
 
+#include <errno.h>  // NOLINT
+
 #include "vm/flags.h"
 #include "vm/os.h"
+#include "vm/profiler.h"
 #include "vm/signal_handler.h"
 #include "vm/thread_interrupter.h"
 
@@ -26,33 +29,27 @@
     if (thread == NULL) {
       return;
     }
-    ThreadInterruptCallback callback = NULL;
-    void* callback_data = NULL;
-    if (!thread->IsThreadInterrupterEnabled(&callback, &callback_data)) {
-      return;
-    }
     // Extract thread state.
     ucontext_t* context = reinterpret_cast<ucontext_t*>(context_);
     mcontext_t mcontext = context->uc_mcontext;
     InterruptedThreadState its;
-    its.tid = thread->id();
     its.pc = SignalHandler::GetProgramCounter(mcontext);
     its.fp = SignalHandler::GetFramePointer(mcontext);
     its.csp = SignalHandler::GetCStackPointer(mcontext);
     its.dsp = SignalHandler::GetDartStackPointer(mcontext);
     its.lr = SignalHandler::GetLinkRegister(mcontext);
-    callback(its, callback_data);
+    Profiler::SampleThread(thread, its);
   }
 };
 
 
-void ThreadInterrupter::InterruptThread(Thread* thread) {
+void ThreadInterrupter::InterruptThread(OSThread* thread) {
   if (FLAG_trace_thread_interrupter) {
     OS::Print("ThreadInterrupter interrupting %p\n",
               reinterpret_cast<void*>(thread->id()));
   }
   int result = pthread_kill(thread->id(), SIGPROF);
-  ASSERT(result == 0);
+  ASSERT((result == 0) || (result == ESRCH));
 }
 
 
diff --git a/runtime/vm/thread_interrupter_macos.cc b/runtime/vm/thread_interrupter_macos.cc
index f1ff45e..a25c3c2 100644
--- a/runtime/vm/thread_interrupter_macos.cc
+++ b/runtime/vm/thread_interrupter_macos.cc
@@ -5,8 +5,11 @@
 #include "platform/globals.h"
 #if defined(TARGET_OS_MACOS)
 
+#include <errno.h>  // NOLINT
+
 #include "vm/flags.h"
 #include "vm/os.h"
+#include "vm/profiler.h"
 #include "vm/signal_handler.h"
 #include "vm/thread_interrupter.h"
 
@@ -26,32 +29,26 @@
     if (thread == NULL) {
       return;
     }
-    ThreadInterruptCallback callback = NULL;
-    void* callback_data = NULL;
-    if (!thread->IsThreadInterrupterEnabled(&callback, &callback_data)) {
-      return;
-    }
     // Extract thread state.
     ucontext_t* context = reinterpret_cast<ucontext_t*>(context_);
     mcontext_t mcontext = context->uc_mcontext;
     InterruptedThreadState its;
-    its.tid = thread->id();
     its.pc = SignalHandler::GetProgramCounter(mcontext);
     its.fp = SignalHandler::GetFramePointer(mcontext);
     its.csp = SignalHandler::GetCStackPointer(mcontext);
     its.dsp = SignalHandler::GetDartStackPointer(mcontext);
     its.lr = SignalHandler::GetLinkRegister(mcontext);
-    callback(its, callback_data);
+    Profiler::SampleThread(thread, its);
   }
 };
 
 
-void ThreadInterrupter::InterruptThread(Thread* thread) {
+void ThreadInterrupter::InterruptThread(OSThread* thread) {
   if (FLAG_trace_thread_interrupter) {
     OS::Print("ThreadInterrupter interrupting %p\n", thread->id());
   }
   int result = pthread_kill(thread->id(), SIGPROF);
-  ASSERT(result == 0);
+  ASSERT((result == 0) || (result == ESRCH));
 }
 
 
@@ -67,4 +64,3 @@
 }  // namespace dart
 
 #endif  // defined(TARGET_OS_MACOS)
-
diff --git a/runtime/vm/thread_interrupter_test.cc b/runtime/vm/thread_interrupter_test.cc
deleted file mode 100644
index aeb9ff1..0000000
--- a/runtime/vm/thread_interrupter_test.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/assert.h"
-
-#include "vm/dart_api_impl.h"
-#include "vm/dart_api_state.h"
-#include "vm/globals.h"
-#include "vm/thread_interrupter.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-class ThreadInterrupterTestHelper : public AllStatic {
- public:
-  static void InterruptTest(const intptr_t run_time, const intptr_t period) {
-    const double allowed_error = 0.25;  // +/- 25%
-    intptr_t count = 0;
-    Thread::EnsureInit();
-    Thread* thread = Thread::Current();
-    thread->SetThreadInterrupter(IncrementCallback, &count);
-    ThreadInterrupter::SetInterruptPeriod(period);
-    OS::Sleep(run_time * kMillisecondsPerSecond);
-    thread->SetThreadInterrupter(NULL, NULL);
-    intptr_t run_time_micros = run_time * kMicrosecondsPerSecond;
-    intptr_t expected_interrupts = run_time_micros / period;
-    intptr_t error = allowed_error * expected_interrupts;
-    intptr_t low_bar = expected_interrupts - error;
-    intptr_t high_bar = expected_interrupts + error;
-    EXPECT_GE(count, low_bar);
-    EXPECT_LE(count, high_bar);
-  }
-
-  static void IncrementCallback(const InterruptedThreadState& state,
-                                void* data) {
-    ASSERT(data != NULL);
-    intptr_t* counter = reinterpret_cast<intptr_t*>(data);
-    *counter = *counter + 1;
-  }
-};
-
-
-TEST_CASE(ThreadInterrupterHigh) {
-  const intptr_t kRunTimeSeconds = 5;
-  const intptr_t kInterruptPeriodMicros = 250;
-  ThreadInterrupterTestHelper::InterruptTest(kRunTimeSeconds,
-                                             kInterruptPeriodMicros);
-}
-
-TEST_CASE(ThreadInterrupterMedium) {
-  const intptr_t kRunTimeSeconds = 5;
-  const intptr_t kInterruptPeriodMicros = 500;
-  ThreadInterrupterTestHelper::InterruptTest(kRunTimeSeconds,
-                                             kInterruptPeriodMicros);
-}
-
-TEST_CASE(ThreadInterrupterLow) {
-  const intptr_t kRunTimeSeconds = 5;
-  const intptr_t kInterruptPeriodMicros = 1000;
-  ThreadInterrupterTestHelper::InterruptTest(kRunTimeSeconds,
-                                             kInterruptPeriodMicros);
-}
-
-
-}  // namespace dart
diff --git a/runtime/vm/thread_interrupter_win.cc b/runtime/vm/thread_interrupter_win.cc
index 70a5e8c..ac613c1 100644
--- a/runtime/vm/thread_interrupter_win.cc
+++ b/runtime/vm/thread_interrupter_win.cc
@@ -7,6 +7,7 @@
 
 #include "vm/flags.h"
 #include "vm/os.h"
+#include "vm/profiler.h"
 #include "vm/thread_interrupter.h"
 
 namespace dart {
@@ -51,39 +52,40 @@
   }
 
 
-  static void Interrupt(Thread* thread) {
-    ASSERT(!OSThread::Compare(GetCurrentThreadId(), thread->id()));
+  static void Interrupt(OSThread* os_thread) {
+    ASSERT(!OSThread::Compare(GetCurrentThreadId(), os_thread->id()));
     HANDLE handle = OpenThread(THREAD_GET_CONTEXT |
                                THREAD_QUERY_INFORMATION |
                                THREAD_SUSPEND_RESUME,
                                false,
-                               thread->id());
+                               os_thread->id());
     ASSERT(handle != NULL);
     DWORD result = SuspendThread(handle);
     if (result == kThreadError) {
       if (FLAG_trace_thread_interrupter) {
         OS::Print("ThreadInterrupter failed to suspend thread %p\n",
-                  reinterpret_cast<void*>(thread->id()));
+                  reinterpret_cast<void*>(os_thread->id()));
       }
       CloseHandle(handle);
       return;
     }
     InterruptedThreadState its;
-    its.tid = thread->id();
     if (!GrabRegisters(handle, &its)) {
       // Failed to get thread registers.
       ResumeThread(handle);
       if (FLAG_trace_thread_interrupter) {
         OS::Print("ThreadInterrupter failed to get registers for %p\n",
-                  reinterpret_cast<void*>(thread->id()));
+                  reinterpret_cast<void*>(os_thread->id()));
       }
       CloseHandle(handle);
       return;
     }
-    ThreadInterruptCallback callback = NULL;
-    void* callback_data = NULL;
-    if (thread->IsThreadInterrupterEnabled(&callback, &callback_data)) {
-      callback(its, callback_data);
+    // Currently we sample only threads that are associated
+    // with an isolate. It is safe to call 'os_thread->thread()'
+    // here as the thread which is being queried is suspended.
+    Thread* thread = os_thread->thread();
+    if (thread != NULL) {
+      Profiler::SampleThread(thread, its);
     }
     ResumeThread(handle);
     CloseHandle(handle);
@@ -91,7 +93,7 @@
 };
 
 
-void ThreadInterrupter::InterruptThread(Thread* thread) {
+void ThreadInterrupter::InterruptThread(OSThread* thread) {
   if (FLAG_trace_thread_interrupter) {
     OS::Print("ThreadInterrupter suspending %p\n",
               reinterpret_cast<void*>(thread->id()));
@@ -117,4 +119,3 @@
 }  // namespace dart
 
 #endif  // defined(TARGET_OS_WINDOWS)
-
diff --git a/runtime/vm/thread_pool.cc b/runtime/vm/thread_pool.cc
index e4453d8..19c0a4d 100644
--- a/runtime/vm/thread_pool.cc
+++ b/runtime/vm/thread_pool.cc
@@ -101,7 +101,9 @@
 
     // First tell all the workers to shut down.
     Worker* current = saved;
-    ThreadId id = OSThread::GetCurrentThreadId();
+    OSThread* os_thread = OSThread::Current();
+    ASSERT(os_thread != NULL);
+    ThreadId id = os_thread->id();
     while (current != NULL) {
       Worker* next = current->all_next_;
       ThreadId currentId = current->id();
@@ -245,7 +247,9 @@
 
   // The thread for worker will exit. Add its ThreadId to the join_list_
   // so that we can join on it at the next opportunity.
-  JoinList::AddLocked(OSThread::GetCurrentThreadJoinId(), &join_list_);
+  OSThread* os_thread = OSThread::Current();
+  ASSERT(os_thread != NULL);
+  JoinList::AddLocked(os_thread->join_id(), &join_list_);
   count_stopped_++;
   count_idle_--;
   return true;
@@ -254,6 +258,7 @@
 
 // Only call while holding the exit_monitor_
 void ThreadPool::AddWorkerToShutdownList(Worker* worker) {
+  ASSERT(exit_monitor_.IsOwnedByCurrentThread());
   worker->shutdown_next_ = shutting_down_workers_;
   shutting_down_workers_ = worker;
 }
@@ -263,6 +268,7 @@
 bool ThreadPool::RemoveWorkerFromShutdownList(Worker* worker) {
   ASSERT(worker != NULL);
   ASSERT(shutting_down_workers_ != NULL);
+  ASSERT(exit_monitor_.IsOwnedByCurrentThread());
 
   // Special case head of list.
   if (shutting_down_workers_ == worker) {
@@ -333,7 +339,9 @@
     ASSERT(task_ != NULL);
   }
 #endif
-  int result = OSThread::Start(&Worker::Main, reinterpret_cast<uword>(this));
+  int result = OSThread::Start("Dart ThreadPool Worker",
+                               &Worker::Main,
+                               reinterpret_cast<uword>(this));
   if (result != 0) {
     FATAL1("Could not start worker thread: result = %d.", result);
   }
@@ -417,10 +425,11 @@
 
 // static
 void ThreadPool::Worker::Main(uword args) {
-  Thread::EnsureInit();
   Worker* worker = reinterpret_cast<Worker*>(args);
-  ThreadId id = OSThread::GetCurrentThreadId();
-  ThreadJoinId join_id = OSThread::GetCurrentThreadJoinId();
+  OSThread* os_thread = OSThread::Current();
+  ASSERT(os_thread != NULL);
+  ThreadId id = os_thread->id();
+  ThreadJoinId join_id = os_thread->join_id();
   ThreadPool* pool;
 
   {
@@ -471,9 +480,6 @@
     // wait for the thread to exit by joining on it in Shutdown().
     delete worker;
   }
-#if defined(TARGET_OS_WINDOWS)
-  Thread::CleanUp();
-#endif
 }
 
 }  // namespace dart
diff --git a/runtime/vm/thread_registry.cc b/runtime/vm/thread_registry.cc
index 44c0d13..2d2dee3 100644
--- a/runtime/vm/thread_registry.cc
+++ b/runtime/vm/thread_registry.cc
@@ -10,7 +10,22 @@
 namespace dart {
 
 ThreadRegistry::~ThreadRegistry() {
-  ReclaimTimelineBlocks();
+  // Go over the free thread list and delete the thread objects.
+  {
+    MonitorLocker ml(monitor_);
+    // At this point the active list should be empty.
+    ASSERT(active_list_ == NULL);
+    // We have cached the mutator thread, delete it.
+    delete mutator_thread_;
+    mutator_thread_ = NULL;
+    // Now delete all the threads in the free list.
+    while (free_list_ != NULL) {
+      Thread* thread = free_list_;
+      free_list_ = thread->next_;
+      delete thread;
+    }
+  }
+
   // Delete monitor.
   delete monitor_;
 }
@@ -31,10 +46,9 @@
   Isolate* isolate = Isolate::Current();
   // We only expect this method to be called from within the isolate itself.
   ASSERT(isolate->thread_registry() == this);
-  // TODO(koda): Rename Thread::PrepareForGC and call it here?
   --remaining_;  // Exclude this thread from the count.
   // Ensure the main mutator will reach a safepoint (could be running Dart).
-  if (!isolate->MutatorThreadIsCurrentThread()) {
+  if (!Thread::Current()->IsMutatorThread()) {
     isolate->ScheduleInterrupts(Isolate::kVMInterrupt);
   }
   while (remaining_ > 0) {
@@ -51,114 +65,155 @@
 }
 
 
-void ThreadRegistry::PruneThread(Thread* thread) {
+Thread* ThreadRegistry::Schedule(Isolate* isolate,
+                                 bool is_mutator,
+                                 bool bypass_safepoint) {
   MonitorLocker ml(monitor_);
-  intptr_t length = entries_.length();
-  if (length == 0) {
-    return;
+  // Wait for any rendezvous in progress.
+  while (!bypass_safepoint && in_rendezvous_) {
+    ml.Wait(Monitor::kNoTimeout);
   }
-  intptr_t found_index = -1;
-  for (intptr_t index = 0; index < length; index++) {
-    if (entries_.At(index).thread == thread) {
-      found_index = index;
+  Thread* thread = NULL;
+  OSThread* os_thread = OSThread::Current();
+  if (os_thread != NULL) {
+    ASSERT(isolate->heap() != NULL);
+    // First get a Thread structure. (we special case the mutator thread
+    // by reusing the cached structure, see comment in 'thread_registry.h').
+    if (is_mutator) {
+      if (mutator_thread_ == NULL) {
+        mutator_thread_ = GetThreadFromFreelist(isolate);
+      }
+      thread = mutator_thread_;
+    } else {
+      thread = GetThreadFromFreelist(isolate);
+      ASSERT(thread->api_top_scope() == NULL);
+    }
+    // Now add this Thread to the active list for the isolate.
+    AddThreadToActiveList(thread);
+    // Set up other values and set the TLS value.
+    thread->isolate_ = isolate;
+    thread->heap_ = isolate->heap();
+    thread->set_os_thread(os_thread);
+    os_thread->set_thread(thread);
+    Thread::SetCurrent(thread);
+    os_thread->EnableThreadInterrupts();
+  }
+  return thread;
+}
+
+
+void ThreadRegistry::Unschedule(Thread* thread,
+                                bool is_mutator,
+                                bool bypass_safepoint) {
+  MonitorLocker ml(monitor_);
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
+  os_thread->DisableThreadInterrupts();
+  os_thread->set_thread(NULL);
+  OSThread::SetCurrent(os_thread);
+  thread->isolate_ = NULL;
+  thread->heap_ = NULL;
+  thread->set_os_thread(NULL);
+  // Remove thread from the active list for the isolate.
+  RemoveThreadFromActiveList(thread);
+  // Return thread to the free list (we special case the mutator
+  // thread by holding on to it, see comment in 'thread_registry.h').
+  if (!is_mutator) {
+    ASSERT(thread->api_top_scope() == NULL);
+    ReturnThreadToFreelist(thread);
+  }
+  if (!bypass_safepoint && in_rendezvous_) {
+    // Don't wait for this thread.
+    ASSERT(remaining_ > 0);
+    if (--remaining_ == 0) {
+      ml.NotifyAll();
+    }
+  }
+}
+
+
+void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor,
+                                         bool validate_frames) {
+  MonitorLocker ml(monitor_);
+  Thread* thread = active_list_;
+  while (thread != NULL) {
+    if (thread->zone() != NULL) {
+      thread->zone()->VisitObjectPointers(visitor);
+    }
+    thread->VisitObjectPointers(visitor);
+    // Iterate over all the stack frames and visit objects on the stack.
+    StackFrameIterator frames_iterator(thread->top_exit_frame_info(),
+                                       validate_frames);
+    StackFrame* frame = frames_iterator.NextFrame();
+    while (frame != NULL) {
+      frame->VisitObjectPointers(visitor);
+      frame = frames_iterator.NextFrame();
+    }
+    thread = thread->next_;
+  }
+}
+
+
+void ThreadRegistry::PrepareForGC() {
+  MonitorLocker ml(monitor_);
+  Thread* thread = active_list_;
+  while (thread != NULL) {
+    thread->PrepareForGC();
+    thread = thread->next_;
+  }
+}
+
+
+void ThreadRegistry::AddThreadToActiveList(Thread* thread) {
+  ASSERT(thread != NULL);
+  ASSERT(monitor_->IsOwnedByCurrentThread());
+  thread->next_ = active_list_;
+  active_list_ = thread;
+}
+
+
+void ThreadRegistry::RemoveThreadFromActiveList(Thread* thread) {
+  ASSERT(thread != NULL);
+  ASSERT(monitor_->IsOwnedByCurrentThread());
+  Thread* prev = NULL;
+  Thread* current = active_list_;
+  while (current != NULL) {
+    if (current == thread) {
+      if (prev == NULL) {
+        active_list_ = current->next_;
+      } else {
+        prev->next_ = current->next_;
+      }
       break;
     }
-  }
-  if (found_index < 0) {
-    return;
-  }
-  {
-    TimelineEventRecorder* recorder = Timeline::recorder();
-    if (recorder != NULL) {
-      // Cleanup entry.
-      Entry& entry_to_remove = entries_[found_index];
-      ReclaimTimelineBlockLocked(&entry_to_remove);
-    }
-  }
-  if (found_index != (length - 1)) {
-    // Swap with last entry.
-    entries_.Swap(found_index, length - 1);
-  }
-  entries_.RemoveLast();
-}
-
-
-void ThreadRegistry::ReclaimTimelineBlocks() {
-  // Each thread that is scheduled in this isolate may have a cached timeline
-  // block. Mark these timeline blocks as finished.
-  MonitorLocker ml(monitor_);
-  TimelineEventRecorder* recorder = Timeline::recorder();
-  if (recorder != NULL) {
-    for (intptr_t i = 0; i < entries_.length(); i++) {
-      // NOTE: It is only safe to access |entry.state| here.
-      Entry& entry = entries_[i];
-      ReclaimTimelineBlockLocked(&entry);
-    }
+    prev = current;
+    current = current->next_;
   }
 }
 
 
-void ThreadRegistry::ReclaimTimelineBlockLocked(Entry* entry) {
-  if (entry == NULL) {
-    return;
+Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) {
+  ASSERT(monitor_->IsOwnedByCurrentThread());
+  Thread* thread = NULL;
+  // Get thread structure from free list or create a new one.
+  if (free_list_ == NULL) {
+    thread = new Thread(isolate);
+  } else {
+    thread = free_list_;
+    free_list_ = thread->next_;
   }
-  TimelineEventRecorder* recorder = Timeline::recorder();
-  if (!entry->scheduled && (entry->state.timeline_block != NULL)) {
-    // Currently unscheduled thread.
-    recorder->FinishBlock(entry->state.timeline_block);
-    entry->state.timeline_block = NULL;
-  } else if (entry->scheduled) {
-    // Currently scheduled thread.
-    Thread* thread = entry->thread;
-    // Take |Thread| lock.
-    MutexLocker thread_lock(thread->timeline_block_lock());
-    recorder->FinishBlock(thread->timeline_block());
-    thread->set_timeline_block(NULL);
-  }
+  return thread;
 }
 
-
-ThreadRegistry::EntryIterator::EntryIterator(ThreadRegistry* registry)
-    : index_(0),
-      registry_(NULL) {
-  Reset(registry);
-}
-
-
-ThreadRegistry::EntryIterator::~EntryIterator() {
-  Reset(NULL);
-}
-
-
-void ThreadRegistry::EntryIterator::Reset(ThreadRegistry* registry) {
-  // Reset index.
-  index_ = 0;
-
-  // Unlock old registry.
-  if (registry_ != NULL) {
-    registry_->monitor_->Exit();
-  }
-
-  registry_ = registry;
-
-  // Lock new registry.
-  if (registry_ != NULL) {
-    registry_->monitor_->Enter();
-  }
-}
-
-
-bool ThreadRegistry::EntryIterator::HasNext() const {
-  if (registry_ == NULL) {
-    return false;
-  }
-  return index_ < registry_->entries_.length();
-}
-
-
-const ThreadRegistry::Entry& ThreadRegistry::EntryIterator::Next() {
-  ASSERT(HasNext());
-  return registry_->entries_.At(index_++);
+void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) {
+  ASSERT(thread != NULL);
+  ASSERT(thread->os_thread_ == NULL);
+  ASSERT(thread->isolate_ == NULL);
+  ASSERT(thread->heap_ == NULL);
+  ASSERT(monitor_->IsOwnedByCurrentThread());
+  // Add thread to the free list.
+  thread->next_ = free_list_;
+  free_list_ = thread;
 }
 
 
@@ -170,7 +225,6 @@
       ASSERT((last_round == -1) || (round_ == (last_round + 1)));
       last_round = round_;
       // Participate in this round.
-      // TODO(koda): Rename Thread::PrepareForGC and call it here?
       if (--remaining_ == 0) {
         // Ensure the organizing thread is notified.
         // TODO(koda): Use separate condition variables and plain 'Notify'.
@@ -190,11 +244,10 @@
 
 intptr_t ThreadRegistry::CountScheduledLocked() {
   intptr_t count = 0;
-  for (int i = 0; i < entries_.length(); ++i) {
-    const Entry& entry = entries_[i];
-    if (entry.scheduled) {
-      ++count;
-    }
+  Thread* current = active_list_;
+  while (current != NULL) {
+    ++count;
+    current = current->next_;
   }
   return count;
 }
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index 90d83f0..555e513 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -19,13 +19,17 @@
  public:
   ThreadRegistry()
       : monitor_(new Monitor()),
-        entries_(),
+        active_list_(NULL),
+        free_list_(NULL),
+        mutator_thread_(NULL),
         in_rendezvous_(false),
         remaining_(0),
         round_(0) {}
 
   ~ThreadRegistry();
 
+  Thread* active_list() const { return active_list_; }
+
   // Bring all threads in this isolate to a safepoint. The caller is
   // expected to be implicitly at a safepoint. The threads will wait
   // until ResumeAllThreads is called. First participates in any
@@ -48,148 +52,17 @@
     CheckSafepointLocked();
   }
 
-  bool RestoreStateTo(Thread* thread, Thread::State* state,
-                      bool bypass_safepoint) {
-    MonitorLocker ml(monitor_);
-    // Wait for any rendezvous in progress.
-    while (!bypass_safepoint && in_rendezvous_) {
-      ml.Wait(Monitor::kNoTimeout);
-    }
-    Entry* entry = FindEntry(thread);
-    if (entry != NULL) {
-      Thread::State st = entry->state;
-      // TODO(koda): Support same thread re-entering same isolate with
-      // Dart frames in between. For now, just assert it doesn't happen.
-      if (st.top_exit_frame_info != thread->top_exit_frame_info()) {
-        ASSERT(thread->top_exit_frame_info() == 0 ||
-               thread->top_exit_frame_info() > st.top_exit_frame_info);
-      }
-      ASSERT(!entry->scheduled);
-      entry->scheduled = true;
-#if defined(DEBUG)
-      // State field is not in use, so zap it.
-      memset(&entry->state, 0xda, sizeof(entry->state));
-#endif
-      *state = st;
-      return true;
-    }
-    Entry new_entry;
-    new_entry.thread = thread;
-    new_entry.scheduled = true;
-#if defined(DEBUG)
-    // State field is not in use, so zap it.
-    memset(&new_entry.state, 0xda, sizeof(new_entry.state));
-#endif
-    entries_.Add(new_entry);
-    return false;
-  }
-
-  void SaveStateFrom(Thread* thread, const Thread::State& state,
-                     bool bypass_safepoint) {
-    MonitorLocker ml(monitor_);
-    Entry* entry = FindEntry(thread);
-    ASSERT(entry != NULL);
-    ASSERT(entry->scheduled);
-    entry->scheduled = false;
-    entry->state = state;
-    if (!bypass_safepoint && in_rendezvous_) {
-      // Don't wait for this thread.
-      ASSERT(remaining_ > 0);
-      if (--remaining_ == 0) {
-        ml.NotifyAll();
-      }
-    }
-  }
-
-  bool Contains(Thread* thread) {
-    MonitorLocker ml(monitor_);
-    return (FindEntry(thread) != NULL);
-  }
-
-  void CheckNotScheduled(Isolate* isolate) {
-    MonitorLocker ml(monitor_);
-    for (int i = 0; i < entries_.length(); ++i) {
-      const Entry& entry = entries_[i];
-      if (entry.scheduled) {
-        FATAL3("Isolate %p still scheduled on %p (whose isolate_ is %p)\n",
-               isolate,
-               entry.thread,
-               entry.thread->isolate());
-      }
-    }
-  }
-
-  void VisitObjectPointers(ObjectPointerVisitor* visitor,
-                           bool validate_frames) {
-    MonitorLocker ml(monitor_);
-    for (int i = 0; i < entries_.length(); ++i) {
-      const Entry& entry = entries_[i];
-      const Thread::State& state =
-          entry.scheduled ? entry.thread->state_ : entry.state;
-      if (state.zone != NULL) {
-        state.zone->VisitObjectPointers(visitor);
-      }
-      if (entry.scheduled) {
-        ASSERT(entry.thread != NULL);
-        entry.thread->VisitObjectPointers(visitor);
-      }
-      // Iterate over all the stack frames and visit objects on the stack.
-      StackFrameIterator frames_iterator(state.top_exit_frame_info,
-                                         validate_frames);
-      StackFrame* frame = frames_iterator.NextFrame();
-      while (frame != NULL) {
-        frame->VisitObjectPointers(visitor);
-        frame = frames_iterator.NextFrame();
-      }
-    }
-  }
-
-  void PruneThread(Thread* thread);
-
-  void ReclaimTimelineBlocks();
-
-  struct Entry {
-    // NOTE: |thread| is deleted automatically when the thread exits.
-    // In other words, it is not safe to dereference |thread| unless you are on
-    // the thread itself.
-    Thread* thread;
-    bool scheduled;
-    Thread::State state;
-  };
-
-  class EntryIterator {
-   public:
-    explicit EntryIterator(ThreadRegistry* registry);
-    ~EntryIterator();
-
-    // Returns false when there are no more entries.
-    bool HasNext() const;
-
-    // Returns the next entry and moves forward.
-    const Entry& Next();
-
-   private:
-    void Reset(ThreadRegistry* registry);
-
-    intptr_t index_;
-    ThreadRegistry* registry_;
-  };
+  bool AtSafepoint() const { return in_rendezvous_; }
+  Thread* Schedule(Isolate* isolate, bool is_mutator, bool bypass_safepoint);
+  void Unschedule(Thread* thread, bool is_mutator, bool bypass_safepoint);
+  void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames);
+  void PrepareForGC();
 
  private:
-  // Returns Entry corresponding to thread in registry or NULL.
-  // Note: Lock should be taken before this function is called.
-  // TODO(koda): Add method Monitor::IsOwnedByCurrentThread.
-  Entry* FindEntry(Thread* thread) {
-    for (int i = 0; i < entries_.length(); ++i) {
-      if (entries_[i].thread == thread) {
-        return &entries_[i];
-      }
-    }
-    return NULL;
-  }
-
-  // NOTE: Lock should be taken before this function is called.
-  void ReclaimTimelineBlockLocked(Entry* entry);
+  void AddThreadToActiveList(Thread* thread);
+  void RemoveThreadFromActiveList(Thread* thread);
+  Thread* GetThreadFromFreelist(Isolate* isolate);
+  void ReturnThreadToFreelist(Thread* thread);
 
   // Note: Lock should be taken before this function is called.
   void CheckSafepointLocked();
@@ -199,7 +72,22 @@
   intptr_t CountScheduledLocked();
 
   Monitor* monitor_;  // All access is synchronized through this monitor.
-  MallocGrowableArray<Entry> entries_;
+  Thread* active_list_;  // List of active threads in the isolate.
+  Thread* free_list_;  // Free list of Thread objects that can be reused.
+  // TODO(asiva): Currently we treat a mutator thread as a special thread
+  // and always schedule execution of Dart code on the same mutator thread
+  // object. The ApiLocalScope has been made thread specific but we still
+  // have scenarios where we do a temporary exit of an Isolate with live
+  // zones/handles in the the API scope :
+  // - Dart_RunLoop()
+  // - IsolateSaver in Dart_NewNativePort
+  // - Isolate spawn (function/uri) under FLAG_i_like_slow_isolate_spawn
+  // We probably need a mechanism to return to the specific thread only
+  // for these specific cases. We should also determine if the embedder
+  // should allow exiting an isolate with live state in zones/handles in
+  // which case a new API for returning to the specific thread needs to be
+  // added.
+  Thread* mutator_thread_;
 
   // Safepoint rendezvous state.
   bool in_rendezvous_;    // A safepoint rendezvous request is in progress.
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 8e78dca..f619d51 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -38,11 +38,9 @@
   // This unit test case needs a running isolate.
   Dart_CreateIsolate(
       NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL);
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
+  OSThread* thread = OSThread::Current();
   // Thread interrupter interferes with this test, disable interrupts.
-  thread->SetThreadInterrupter(NULL, NULL);
-  Profiler::EndExecution(isolate);
+  thread->DisableThreadInterrupts();
   Monitor* monitor = new Monitor();
   monitor->Enter();
   monitor->Exit();
@@ -136,7 +134,6 @@
         // Ensure that our particular zone is visited.
         isolate_->IterateObjectPointers(
             &counter,
-            /* visit_prologue_weak_handles = */ true,
             StackFrameIterator::kValidateFrames);
         EXPECT_EQ(1, counter.count());
       }
@@ -154,7 +151,6 @@
         // Ensure that our particular zone is visited.
         isolate_->IterateObjectPointers(
             &str_counter,
-            /* visit_prologue_weak_handles = */ true,
             StackFrameIterator::kValidateFrames);
         // We should visit the string object exactly once.
         EXPECT_EQ(1, str_counter.count());
@@ -281,7 +277,6 @@
         ObjectCounter counter(isolate_, &smi);
         isolate_->IterateObjectPointers(
             &counter,
-            /* visit_prologue_weak_handles = */ true,
             StackFrameIterator::kValidateFrames);
         {
           MutexLocker ml(mutex_);
@@ -412,18 +407,18 @@
   intptr_t thread_count_1 = 0;
 
   {
-    ThreadIterator ti;
+    OSThreadIterator ti;
     while (ti.HasNext()) {
-      Thread* thread = ti.Next();
+      OSThread* thread = ti.Next();
       EXPECT(thread != NULL);
       thread_count_0++;
     }
   }
 
   {
-    ThreadIterator ti;
+    OSThreadIterator ti;
     while (ti.HasNext()) {
-      Thread* thread = ti.Next();
+      OSThread* thread = ti.Next();
       EXPECT(thread != NULL);
       thread_count_1++;
     }
@@ -435,82 +430,55 @@
 }
 
 
-static bool ThreadInList(Thread* thread) {
-  ThreadIterator it;
-  while (it.HasNext()) {
-    Thread* t = it.Next();
-    if (t == thread) {
-      return true;
-    }
-  }
-  return false;
-}
-
-
 TEST_CASE(ThreadIterator_FindSelf) {
-  Thread* current = Thread::Current();
-  EXPECT(ThreadInList(current));
+  OSThread* current = OSThread::Current();
+  EXPECT(OSThread::IsThreadInList(current->join_id()));
 }
 
 
 struct ThreadIteratorTestParams {
-  Isolate* isolate;
-  Thread* spawned_thread;
-  ThreadJoinId spawned_thread_join_id;
+  ThreadId spawned_thread_join_id;
   Monitor* monitor;
 };
 
 
 void ThreadIteratorTestMain(uword parameter) {
-  Thread::EnsureInit();
   ThreadIteratorTestParams* params =
       reinterpret_cast<ThreadIteratorTestParams*>(parameter);
-  Isolate* isolate = params->isolate;
-  EXPECT(isolate != NULL);
-  Thread* thread = Thread::Current();
+  OSThread* thread = OSThread::Current();
   EXPECT(thread != NULL);
 
   MonitorLocker ml(params->monitor);
-  params->spawned_thread = thread;
-  params->spawned_thread_join_id = OSThread::GetCurrentThreadJoinId();
+  params->spawned_thread_join_id = thread->join_id();
   EXPECT(params->spawned_thread_join_id != OSThread::kInvalidThreadJoinId);
-  EXPECT(ThreadInList(thread));
+  EXPECT(OSThread::IsThreadInList(thread->join_id()));
   ml.Notify();
 }
 
 
+// NOTE: This test case also verifies that known TLS destructors are called
+// on Windows. See |OnDartThreadExit| in os_thread_win.cc for more details.
 TEST_CASE(ThreadIterator_AddFindRemove) {
-  Isolate* isolate = thread->isolate();
   ThreadIteratorTestParams params;
-  params.isolate = isolate;
-  params.spawned_thread = NULL;
   params.spawned_thread_join_id = OSThread::kInvalidThreadJoinId;
   params.monitor = new Monitor();
 
   {
     MonitorLocker ml(params.monitor);
     EXPECT(params.spawned_thread_join_id == OSThread::kInvalidThreadJoinId);
-    EXPECT(params.spawned_thread == NULL);
     // Spawn thread and wait to receive the thread join id.
-    OSThread::Start(ThreadIteratorTestMain, reinterpret_cast<uword>(&params));
+    OSThread::Start("ThreadIteratorTest",
+                    ThreadIteratorTestMain,
+                    reinterpret_cast<uword>(&params));
     while (params.spawned_thread_join_id == OSThread::kInvalidThreadJoinId) {
       ml.Wait();
     }
     EXPECT(params.spawned_thread_join_id != OSThread::kInvalidThreadJoinId);
-    EXPECT(params.spawned_thread != NULL);
     // Join thread.
     OSThread::Join(params.spawned_thread_join_id);
   }
 
-  for (intptr_t i = 0; i < 10; i++) {
-    // Sleep for 10 milliseconds.
-    OS::Sleep(10);
-    if (!ThreadInList(params.spawned_thread)) {
-      break;
-    }
-  }
-
-  EXPECT(!ThreadInList(params.spawned_thread))
+  EXPECT(!OSThread::IsThreadInList(params.spawned_thread_join_id))
 
   delete params.monitor;
 }
@@ -598,11 +566,6 @@
   Monitor done_monitor;
   bool done = false;
   Isolate* isolate = Thread::Current()->isolate();
-  // Flush store buffers, etc.
-  // TODO(koda): Currently, the GC only does this for the current thread, (i.e,
-  // the helper, in this test), but it should be done for all *threads*
-  // while reaching a safepoint.
-  Thread::PrepareForGC();
   Dart::thread_pool()->Run(new AllocAndGCTask(isolate, &done_monitor, &done));
   {
     while (true) {
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 6b96b16..64c7127 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -30,7 +30,7 @@
 //
 // Writing events:
 // |TimelineEvent|s are written into |TimelineEventBlock|s. Each |Thread| caches
-// a |TimelineEventBlock| in TLS so that it can write events without
+// a |TimelineEventBlock| object so that it can write events without
 // synchronizing with other threads in the system. Even though the |Thread| owns
 // the |TimelineEventBlock| the block may need to be reclaimed by the reporting
 // system. To support that, a |Thread| must hold its |timeline_block_lock_|
@@ -41,30 +41,17 @@
 // When requested, the timeline is serialized in the trace-event format
 // (https://goo.gl/hDZw5M). The request can be for a VM-wide timeline or an
 // isolate specific timeline. In both cases it may be that a thread has
-// a |TimelineEventBlock| cached in TLS. In order to report a complete timeline
-// the cached |TimelineEventBlock|s need to be reclaimed.
+// a |TimelineEventBlock| cached in TLS partially filled with events. In order
+// to report a complete timeline the cached |TimelineEventBlock|s need to be
+// reclaimed.
 //
-// Reclaiming open |TimelineEventBlock|s for an isolate:
+// Reclaiming open |TimelineEventBlock|s from threads:
 //
-// Cached |TimelineEventBlock|s can be in two places:
-// 1) In a |Thread| (Thread currently in an |Isolate|)
-// 2) In a |Thread::State| (Thread not currently in an |Isolate|).
+// Each |Thread| can have one |TimelineEventBlock| cached in it.
 //
-// As a |Thread| enters and exits an |Isolate|, a |TimelineEventBlock|
-// will move between (1) and (2).
-//
-// The first case occurs for |Thread|s that are currently running inside an
-// isolate. The second case occurs for |Thread|s that are not currently
-// running inside an isolate.
-//
-// To reclaim the first case, we take the |Thread|'s |timeline_block_lock_|
-// and reclaim the cached block.
-//
-// To reclaim the second case, we can take the |ThreadRegistry| lock and
-// reclaim these blocks.
-//
-// |Timeline::ReclaimIsolateBlocks| and |Timeline::ReclaimAllBlocks| are
-// the two utility methods used to reclaim blocks before reporting.
+// To reclaim blocks, we iterate over all threads and remove the cached
+// |TimelineEventBlock| from each thread. This is safe because we hold the
+// |Thread|'s |timeline_block_lock_| meaning the block can't be being modified.
 //
 // Locking notes:
 // The following locks are used by the timeline system:
@@ -72,14 +59,11 @@
 // |TimelineEventBlock| is being requested or reclaimed.
 // - |Thread::timeline_block_lock_| This lock is held whenever a |Thread|'s
 // cached block is being operated on.
-// - |ThreadRegistry::monitor_| This lock protects the cached block for
-// unscheduled threads of an isolate.
-// - |Isolate::isolates_list_monitor_| This lock protects the list of
-// isolates in the system.
+// - |Thread::thread_list_lock_| This lock is held when iterating over
+// |Thread|s.
 //
 // Locks must always be taken in the following order:
-// |Isolate::isolates_list_monitor_|
-//   |ThreadRegistry::monitor_|
+//   |Thread::thread_list_lock_|
 //     |Thread::timeline_block_lock_|
 //       |TimelineEventRecorder::lock_|
 //
@@ -90,7 +74,7 @@
   const bool use_ring_recorder = true;
   // Some flags require that we use the endless recorder.
   const bool use_endless_recorder =
-      (FLAG_timeline_dir != NULL) || FLAG_timing;
+      (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline;
   if (use_endless_recorder) {
     recorder_ = new TimelineEventEndlessRecorder();
   } else if (use_ring_recorder) {
@@ -98,9 +82,13 @@
   }
   vm_stream_ = new TimelineStream();
   vm_stream_->Init("VM", EnableStreamByDefault("VM"), NULL);
+  vm_api_stream_ = new TimelineStream();
+  vm_api_stream_->Init("API",
+                       EnableStreamByDefault("API"),
+                       &stream_API_enabled_);
   // Global overrides.
 #define ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT(name, not_used)                   \
-  stream_##name##_enabled_ = false;
+  stream_##name##_enabled_ = EnableStreamByDefault(#name);
   ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT)
 #undef ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT
 }
@@ -115,6 +103,8 @@
   recorder_ = NULL;
   delete vm_stream_;
   vm_stream_ = NULL;
+  delete vm_api_stream_;
+  vm_api_stream_ = NULL;
 }
 
 
@@ -125,7 +115,7 @@
 
 bool Timeline::EnableStreamByDefault(const char* stream_name) {
   // TODO(johnmccutchan): Allow for command line control over streams.
-  return (FLAG_timeline_dir != NULL) || FLAG_timing;
+  return (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline;
 }
 
 
@@ -135,49 +125,50 @@
 }
 
 
-void Timeline::ReclaimIsolateBlocks() {
-  ReclaimBlocksForIsolate(Isolate::Current());
+TimelineStream* Timeline::GetVMApiStream() {
+  ASSERT(vm_api_stream_ != NULL);
+  return vm_api_stream_;
 }
 
 
-class ReclaimBlocksIsolateVisitor : public IsolateVisitor {
- public:
-  ReclaimBlocksIsolateVisitor() {}
-
-  virtual void VisitIsolate(Isolate* isolate) {
-    Timeline::ReclaimBlocksForIsolate(isolate);
-  }
-
- private:
-};
-
-
-void Timeline::ReclaimAllBlocks() {
-  if (recorder() == NULL) {
+void Timeline::ReclaimCachedBlocksFromThreads() {
+  TimelineEventRecorder* recorder = Timeline::recorder();
+  if (recorder == NULL) {
     return;
   }
-  // Reclaim all blocks cached for all isolates.
-  ReclaimBlocksIsolateVisitor visitor;
-  Isolate::VisitIsolates(&visitor);
-  // Reclaim the global VM block.
-  recorder()->ReclaimGlobalBlock();
+
+  // Iterate over threads.
+  OSThreadIterator it;
+  while (it.HasNext()) {
+    OSThread* thread = it.Next();
+    MutexLocker ml(thread->timeline_block_lock());
+    // Grab block and clear it.
+    TimelineEventBlock* block = thread->timeline_block();
+    thread->set_timeline_block(NULL);
+    // TODO(johnmccutchan): Consider dropping the timeline_block_lock here
+    // if we can do it everywhere. This would simplify the lock ordering
+    // requirements.
+    recorder->FinishBlock(block);
+  }
 }
 
 
-void Timeline::ReclaimBlocksForIsolate(Isolate* isolate) {
-  if (recorder() == NULL) {
+void Timeline::Clear() {
+  TimelineEventRecorder* recorder = Timeline::recorder();
+  if (recorder == NULL) {
     return;
   }
-  ASSERT(isolate != NULL);
-  isolate->ReclaimTimelineBlocks();
+  ReclaimCachedBlocksFromThreads();
+  recorder->Clear();
 }
 
 
 TimelineEventRecorder* Timeline::recorder_ = NULL;
 TimelineStream* Timeline::vm_stream_ = NULL;
+TimelineStream* Timeline::vm_api_stream_ = NULL;
 
 #define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default)          \
-  bool Timeline::stream_##name##_enabled_ = false;
+  bool Timeline::stream_##name##_enabled_ = enabled_by_default;
   ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DEFINE_FLAG)
 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG
 
@@ -189,7 +180,8 @@
       state_(0),
       label_(NULL),
       category_(""),
-      thread_(OSThread::kInvalidThreadId) {
+      thread_(OSThread::kInvalidThreadId),
+      isolate_id_(ILLEGAL_PORT) {
 }
 
 
@@ -201,53 +193,60 @@
 void TimelineEvent::Reset() {
   set_event_type(kNone);
   thread_ = OSThread::kInvalidThreadId;
-  isolate_ = NULL;
+  isolate_id_ = ILLEGAL_PORT;
   category_ = "";
   label_ = NULL;
   FreeArguments();
 }
 
 
-void TimelineEvent::AsyncBegin(const char* label, int64_t async_id) {
+void TimelineEvent::AsyncBegin(const char* label,
+                               int64_t async_id,
+                               int64_t micros) {
   Init(kAsyncBegin, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(micros);
   // Overload timestamp1_ with the async_id.
-  timestamp1_ = async_id;
+  set_timestamp1(async_id);
 }
 
 
 void TimelineEvent::AsyncInstant(const char* label,
-                                 int64_t async_id) {
+                                 int64_t async_id,
+                                 int64_t micros) {
   Init(kAsyncInstant, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(micros);
   // Overload timestamp1_ with the async_id.
-  timestamp1_ = async_id;
+  set_timestamp1(async_id);
 }
 
 
 void TimelineEvent::AsyncEnd(const char* label,
-                             int64_t async_id) {
+                             int64_t async_id,
+                             int64_t micros) {
   Init(kAsyncEnd, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(micros);
   // Overload timestamp1_ with the async_id.
-  timestamp1_ = async_id;
+  set_timestamp1(async_id);
 }
 
 
-void TimelineEvent::DurationBegin(const char* label) {
+void TimelineEvent::DurationBegin(const char* label,
+                                  int64_t micros) {
   Init(kDuration, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(micros);
 }
 
 
-void TimelineEvent::DurationEnd() {
-  timestamp1_ = OS::GetCurrentTraceMicros();
+void TimelineEvent::DurationEnd(int64_t micros) {
+  ASSERT(timestamp1_ == 0);
+  set_timestamp1(micros);
 }
 
 
-void TimelineEvent::Instant(const char* label) {
+void TimelineEvent::Instant(const char* label,
+                            int64_t micros) {
   Init(kInstant, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(micros);
 }
 
 
@@ -255,22 +254,30 @@
                              int64_t start_micros,
                              int64_t end_micros) {
   Init(kDuration, label);
-  timestamp0_ = start_micros;
-  timestamp1_ = end_micros;
+  set_timestamp0(start_micros);
+  set_timestamp1(end_micros);
 }
 
 
 void TimelineEvent::Begin(const char* label,
                           int64_t micros) {
   Init(kBegin, label);
-  timestamp0_ = micros;
+  set_timestamp0(micros);
 }
 
 
 void TimelineEvent::End(const char* label,
                         int64_t micros) {
   Init(kEnd, label);
-  timestamp0_ = micros;
+  set_timestamp0(micros);
+}
+
+
+void TimelineEvent::CompleteWithPreSerializedJSON(const char* json) {
+  set_pre_serialized_json(true);
+  SetNumArguments(1);
+  CopyArgument(0, "Dart", json);
+  Complete();
 }
 
 
@@ -364,14 +371,58 @@
   set_event_type(event_type);
   timestamp0_ = 0;
   timestamp1_ = 0;
-  thread_ = OSThread::GetCurrentThreadTraceId();
-  isolate_ = Isolate::Current();
+  OSThread* os_thread = OSThread::Current();
+  ASSERT(os_thread != NULL);
+  thread_ = os_thread->trace_id();
+  Isolate* isolate = Isolate::Current();
+  if (isolate != NULL) {
+    isolate_id_ = isolate->main_port();
+  } else {
+    isolate_id_ = ILLEGAL_PORT;
+  }
   label_ = label;
   FreeArguments();
 }
 
 
+bool TimelineEvent::Within(int64_t time_origin_micros,
+                           int64_t time_extent_micros) {
+  if ((time_origin_micros == -1) ||
+      (time_extent_micros == -1)) {
+    // No time range specified.
+    return true;
+  }
+  if (IsFinishedDuration()) {
+    // Event is from e_t0 to e_t1.
+    int64_t e_t0 = TimeOrigin();
+    int64_t e_t1 = TimeEnd();
+    ASSERT(e_t0 <= e_t1);
+    // Range is from r_t0 to r_t1.
+    int64_t r_t0 = time_origin_micros;
+    int64_t r_t1 = time_origin_micros + time_extent_micros;
+    ASSERT(r_t0 <= r_t1);
+    return !((r_t1 < e_t0) || (e_t1 < r_t0));
+  }
+  int64_t delta = TimeOrigin() - time_origin_micros;
+  return (delta >= 0) && (delta <= time_extent_micros);
+}
+
+
+const char* TimelineEvent::GetSerializedJSON() const {
+  ASSERT(pre_serialized_json());
+  ASSERT(arguments_length_ == 1);
+  ASSERT(arguments_ != NULL);
+  return arguments_[0].value;
+}
+
+
 void TimelineEvent::PrintJSON(JSONStream* stream) const {
+  if (pre_serialized_json()) {
+    // Event has already been serialized into JSON- just append the
+    // raw data.
+    stream->AppendSerializedObject(GetSerializedJSON());
+    return;
+  }
   JSONObject obj(stream);
   int64_t pid = OS::ProcessId();
   int64_t tid = OSThread::ThreadIdToIntPtr(thread_);
@@ -424,6 +475,11 @@
       const TimelineEventArgument& arg = arguments_[i];
       args.AddProperty(arg.name, arg.value);
     }
+    if (isolate_id_ != ILLEGAL_PORT) {
+      // If we have one, append the isolate id.
+      args.AddPropertyF("isolateNumber", "%" Pd64 "",
+                        static_cast<int64_t>(isolate_id_));
+    }
   }
 }
 
@@ -441,7 +497,7 @@
 int64_t TimelineEvent::TimeDuration() const {
   if (timestamp1_ == 0) {
     // This duration is still open, use current time as end.
-    return OS::GetCurrentTraceMicros() - timestamp0_;
+    return OS::GetCurrentMonotonicMicros() - timestamp0_;
   }
   return timestamp1_ - timestamp0_;
 }
@@ -477,10 +533,9 @@
 }
 
 
-TimelineDurationScope::TimelineDurationScope(TimelineStream* stream,
-                                             const char* label)
+TimelineEventScope::TimelineEventScope(TimelineStream* stream,
+                                       const char* label)
     : StackResource(reinterpret_cast<Thread*>(NULL)),
-      timestamp_(0),
       stream_(stream),
       label_(label),
       arguments_(NULL),
@@ -490,37 +545,25 @@
 }
 
 
-TimelineDurationScope::TimelineDurationScope(Thread* thread,
-                                             TimelineStream* stream,
-                                             const char* label)
+TimelineEventScope::TimelineEventScope(Thread* thread,
+                                       TimelineStream* stream,
+                                       const char* label)
     : StackResource(thread),
-      timestamp_(0),
       stream_(stream),
       label_(label),
       arguments_(NULL),
       arguments_length_(0),
       enabled_(false) {
-  ASSERT(thread != NULL);
   Init();
 }
 
 
-TimelineDurationScope::~TimelineDurationScope() {
-  if (!enabled_) {
-    FreeArguments();
-    return;
-  }
-  TimelineEvent* event = stream_->StartEvent();
-  ASSERT(event != NULL);
-  event->Duration(label_, timestamp_, OS::GetCurrentTraceMicros());
-  event->StealArguments(arguments_length_, arguments_);
-  event->Complete();
-  arguments_length_ = 0;
-  arguments_ = NULL;
+TimelineEventScope::~TimelineEventScope() {
+  FreeArguments();
 }
 
 
-void TimelineDurationScope::Init() {
+void TimelineEventScope::Init() {
   ASSERT(enabled_ == false);
   ASSERT(label_ != NULL);
   ASSERT(stream_ != NULL);
@@ -528,12 +571,11 @@
     // Stream is not enabled, do nothing.
     return;
   }
-  timestamp_ = OS::GetCurrentTraceMicros();
   enabled_ = true;
 }
 
 
-void TimelineDurationScope::SetNumArguments(intptr_t length) {
+void TimelineEventScope::SetNumArguments(intptr_t length) {
   if (!enabled()) {
     return;
   }
@@ -549,9 +591,9 @@
 
 
 // |name| must be a compile time constant. Takes ownership of |argumentp|.
-void TimelineDurationScope::SetArgument(intptr_t i,
-                                        const char* name,
-                                        char* argument) {
+void TimelineEventScope::SetArgument(intptr_t i,
+                                     const char* name,
+                                     char* argument) {
   if (!enabled()) {
     return;
   }
@@ -563,9 +605,9 @@
 
 
 // |name| must be a compile time constant. Copies |argument|.
-void TimelineDurationScope::CopyArgument(intptr_t i,
-                                         const char* name,
-                                         const char* argument) {
+void TimelineEventScope::CopyArgument(intptr_t i,
+                                      const char* name,
+                                      const char* argument) {
   if (!enabled()) {
     return;
   }
@@ -573,9 +615,9 @@
 }
 
 
-void TimelineDurationScope::FormatArgument(intptr_t i,
-                                           const char* name,
-                                           const char* fmt, ...) {
+void TimelineEventScope::FormatArgument(intptr_t i,
+                                        const char* name,
+                                        const char* fmt, ...) {
   if (!enabled()) {
     return;
   }
@@ -594,7 +636,7 @@
 }
 
 
-void TimelineDurationScope::FreeArguments() {
+void TimelineEventScope::FreeArguments() {
   if (arguments_ == NULL) {
     return;
   }
@@ -607,7 +649,107 @@
 }
 
 
-TimelineEventFilter::TimelineEventFilter() {
+void TimelineEventScope::StealArguments(TimelineEvent* event) {
+  if (event == NULL) {
+    return;
+  }
+  event->StealArguments(arguments_length_, arguments_);
+  arguments_length_ = 0;
+  arguments_ = NULL;
+}
+
+
+TimelineDurationScope::TimelineDurationScope(TimelineStream* stream,
+                                             const char* label)
+    : TimelineEventScope(stream, label) {
+  timestamp_ = OS::GetCurrentMonotonicMicros();
+}
+
+
+TimelineDurationScope::TimelineDurationScope(Thread* thread,
+                                             TimelineStream* stream,
+                                             const char* label)
+    : TimelineEventScope(thread, stream, label) {
+  timestamp_ = OS::GetCurrentMonotonicMicros();
+}
+
+
+TimelineDurationScope::~TimelineDurationScope() {
+  if (!ShouldEmitEvent()) {
+    return;
+  }
+  TimelineEvent* event = stream()->StartEvent();
+  if (event == NULL) {
+    // Stream is now disabled.
+    return;
+  }
+  ASSERT(event != NULL);
+  // Emit a duration event.
+  event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros());
+  StealArguments(event);
+  event->Complete();
+}
+
+
+TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream,
+                                             const char* label)
+    : TimelineEventScope(stream, label) {
+  EmitBegin();
+}
+
+
+TimelineBeginEndScope::TimelineBeginEndScope(Thread* thread,
+                                             TimelineStream* stream,
+                                             const char* label)
+    : TimelineEventScope(thread, stream, label) {
+  EmitBegin();
+}
+
+
+TimelineBeginEndScope::~TimelineBeginEndScope() {
+  EmitEnd();
+}
+
+
+void TimelineBeginEndScope::EmitBegin() {
+  if (!ShouldEmitEvent()) {
+    return;
+  }
+  TimelineEvent* event = stream()->StartEvent();
+  if (event == NULL) {
+    // Stream is now disabled.
+    return;
+  }
+  ASSERT(event != NULL);
+  // Emit a begin event.
+  event->Begin(label());
+  event->Complete();
+}
+
+
+void TimelineBeginEndScope::EmitEnd() {
+  if (!ShouldEmitEvent()) {
+    return;
+  }
+  TimelineEvent* event = stream()->StartEvent();
+  if (event == NULL) {
+    // Stream is now disabled.
+    return;
+  }
+  ASSERT(event != NULL);
+  // Emit an end event.
+  event->End(label());
+  StealArguments(event);
+  event->Complete();
+}
+
+
+TimelineEventFilter::TimelineEventFilter(int64_t time_origin_micros,
+                                         int64_t time_extent_micros)
+    : time_origin_micros_(time_origin_micros),
+      time_extent_micros_(time_extent_micros) {
+  ASSERT(time_origin_micros_ >= -1);
+  ASSERT(time_extent_micros_ >= -1);
 }
 
 
@@ -615,61 +757,60 @@
 }
 
 
-IsolateTimelineEventFilter::IsolateTimelineEventFilter(Isolate* isolate)
-    : isolate_(isolate) {
-}
-
-
-DartTimelineEvent::DartTimelineEvent()
-    : isolate_(NULL),
-      event_as_json_(NULL) {
-}
-
-
-DartTimelineEvent::~DartTimelineEvent() {
-  Clear();
-}
-
-
-void DartTimelineEvent::Clear() {
-  if (isolate_ != NULL) {
-    isolate_ = NULL;
-  }
-  if (event_as_json_ != NULL) {
-    free(event_as_json_);
-    event_as_json_ = NULL;
-  }
-}
-
-
-void DartTimelineEvent::Init(Isolate* isolate, const char* event) {
-  ASSERT(isolate_ == NULL);
-  ASSERT(event != NULL);
-  isolate_ = isolate;
-  event_as_json_ = strdup(event);
+IsolateTimelineEventFilter::IsolateTimelineEventFilter(
+    Dart_Port isolate_id,
+    int64_t time_origin_micros,
+    int64_t time_extent_micros)
+    : TimelineEventFilter(time_origin_micros,
+                          time_extent_micros),
+      isolate_id_(isolate_id) {
 }
 
 
 TimelineEventRecorder::TimelineEventRecorder()
-    : global_block_(NULL),
-      async_id_(0) {
+    : async_id_(0) {
 }
 
 
 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const {
+  OSThreadIterator it;
+  while (it.HasNext()) {
+    OSThread* thread = it.Next();
+    const char* thread_name = thread->name();
+    if (thread_name == NULL) {
+      // Only emit a thread name if one was set.
+      continue;
+    }
+    JSONObject obj(events);
+    int64_t pid = OS::ProcessId();
+    int64_t tid = OSThread::ThreadIdToIntPtr(thread->trace_id());
+    obj.AddProperty("name", "thread_name");
+    obj.AddProperty("ph", "M");
+    obj.AddProperty64("pid", pid);
+    obj.AddProperty64("tid", tid);
+    {
+      JSONObject args(&obj, "args");
+      args.AddPropertyF("name", "%s (%" Pd64 ")", thread_name, tid);
+    }
+  }
 }
 
 
 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() {
   // Grab the current thread.
-  Thread* thread = Thread::Current();
+  OSThread* thread = OSThread::Current();
   ASSERT(thread != NULL);
-  ASSERT(thread->isolate() != NULL);
   Mutex* thread_block_lock = thread->timeline_block_lock();
   ASSERT(thread_block_lock != NULL);
   // We are accessing the thread's timeline block- so take the lock here.
   // This lock will be held until the call to |CompleteEvent| is made.
   thread_block_lock->Lock();
+#if defined(DEBUG)
+  Thread* T = Thread::Current();
+  if (T != NULL) {
+    T->IncrementNoSafepointScopeDepth();
+  }
+#endif  // defined(DEBUG)
 
   TimelineEventBlock* thread_block = thread->timeline_block();
 
@@ -679,102 +820,48 @@
     // 1) Mark it as finished.
     thread_block->Finish();
     // 2) Allocate a new block.
-    thread_block = GetNewBlockLocked(thread->isolate());
+    thread_block = GetNewBlockLocked();
     thread->set_timeline_block(thread_block);
   } else if (thread_block == NULL) {
     MutexLocker ml(&lock_);
     // Thread has no block. Attempt to allocate one.
-    thread_block = GetNewBlockLocked(thread->isolate());
+    thread_block = GetNewBlockLocked();
     thread->set_timeline_block(thread_block);
   }
   if (thread_block != NULL) {
     // NOTE: We are exiting this function with the thread's block lock held.
     ASSERT(!thread_block->IsFull());
     TimelineEvent* event = thread_block->StartEvent();
-    if (event != NULL) {
-      event->set_global_block(false);
-    }
     return event;
   }
   // Drop lock here as no event is being handed out.
+#if defined(DEBUG)
+  if (T != NULL) {
+    T->DecrementNoSafepointScopeDepth();
+  }
+#endif  // defined(DEBUG)
   thread_block_lock->Unlock();
   return NULL;
 }
 
 
-TimelineEvent* TimelineEventRecorder::GlobalBlockStartEvent() {
-  // Take recorder lock. This lock will be held until the call to
-  // |CompleteEvent| is made.
-  lock_.Lock();
-  if (FLAG_trace_timeline) {
-    OS::Print("GlobalBlockStartEvent in block %p for thread %" Px "\n",
-              global_block_, OSThread::CurrentCurrentThreadIdAsIntPtr());
-  }
-  if ((global_block_ != NULL) && global_block_->IsFull()) {
-    // Global block is full.
-    global_block_->Finish();
-    global_block_ = NULL;
-  }
-  if (global_block_ == NULL) {
-    // Allocate a new block.
-    global_block_ = GetNewBlockLocked(NULL);
-    ASSERT(global_block_ != NULL);
-  }
-  if (global_block_ != NULL) {
-    // NOTE: We are exiting this function with the recorder's lock held.
-    ASSERT(!global_block_->IsFull());
-    TimelineEvent* event = global_block_->StartEvent();
-    if (event != NULL) {
-      event->set_global_block(true);
-    }
-    return event;
-  }
-  // Drop lock here as no event is being handed out.
-  lock_.Unlock();
-  return NULL;
-}
-
-
 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) {
   if (event == NULL) {
     return;
   }
-  ASSERT(!event->global_block());
   // Grab the current thread.
-  Thread* thread = Thread::Current();
+  OSThread* thread = OSThread::Current();
   ASSERT(thread != NULL);
-  ASSERT(thread->isolate() != NULL);
-  // This event came from the isolate's thread local block. Unlock the
-  // thread's block lock.
+  // Unlock the thread's block lock.
   Mutex* thread_block_lock = thread->timeline_block_lock();
   ASSERT(thread_block_lock != NULL);
-  thread_block_lock->Unlock();
-}
-
-
-void TimelineEventRecorder::GlobalBlockCompleteEvent(TimelineEvent* event) {
-  if (event == NULL) {
-    return;
+#if defined(DEBUG)
+  Thread* T = Thread::Current();
+  if (T != NULL) {
+    T->DecrementNoSafepointScopeDepth();
   }
-  ASSERT(event->global_block());
-  // This event came from the global block, unlock the recorder's lock now
-  // that the event is filled.
-  lock_.Unlock();
-}
-
-
-// Trims the ']' character.
-static void TrimOutput(char* output,
-                       intptr_t* output_length) {
-  ASSERT(output != NULL);
-  ASSERT(output_length != NULL);
-  ASSERT(*output_length >= 2);
-  // We expect the first character to be the opening of an array.
-  ASSERT(output[0] == '[');
-  // We expect the last character to be the closing of an array.
-  ASSERT(output[*output_length - 1] == ']');
-  // Skip the ].
-  *output_length -= 1;
+#endif  // defined(DEBUG)
+  thread_block_lock->Unlock();
 }
 
 
@@ -788,7 +875,7 @@
   Thread* T = Thread::Current();
   StackZone zone(T);
 
-  Timeline::ReclaimAllBlocks();
+  Timeline::ReclaimCachedBlocksFromThreads();
 
   intptr_t pid = OS::ProcessId();
   char* filename = OS::SCreate(NULL,
@@ -808,47 +895,15 @@
   char* output = NULL;
   intptr_t output_length = 0;
   js.Steal(const_cast<const char**>(&output), &output_length);
-  TrimOutput(output, &output_length);
-  ASSERT(output_length >= 1);
   (*file_write)(output, output_length, file);
   // Free the stolen output.
   free(output);
-
-  const char* dart_events =
-      DartTimelineEventIterator::PrintTraceEvents(this,
-                                                  zone.GetZone(),
-                                                  NULL);
-
-  // If we wrote out vm events and have dart events, write out the comma.
-  if ((output_length > 1) && (dart_events != NULL)) {
-    // Write out the ',' character.
-    const char* comma = ",";
-    (*file_write)(comma, 1, file);
-  }
-
-  // Write out the Dart events.
-  if (dart_events != NULL) {
-    (*file_write)(dart_events, strlen(dart_events), file);
-  }
-
-  // Write out the ']' character.
-  const char* array_close = "]";
-  (*file_write)(array_close, 1, file);
   (*file_close)(file);
 
   return;
 }
 
 
-void TimelineEventRecorder::ReclaimGlobalBlock() {
-  MutexLocker ml(&lock_);
-  if (global_block_ != NULL) {
-    global_block_->Finish();
-    global_block_ = NULL;
-  }
-}
-
-
 int64_t TimelineEventRecorder::GetNextAsyncId() {
   // TODO(johnmccutchan): Gracefully handle wrap around.
   uint32_t next = static_cast<uint32_t>(
@@ -868,7 +923,7 @@
 
 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() {
   MutexLocker ml(&lock_);
-  return GetNewBlockLocked(Isolate::Current());
+  return GetNewBlockLocked();
 }
 
 
@@ -876,10 +931,7 @@
     : blocks_(NULL),
       capacity_(capacity),
       num_blocks_(0),
-      block_cursor_(0),
-      dart_events_(NULL),
-      dart_events_capacity_(capacity),
-      dart_events_cursor_(0) {
+      block_cursor_(0) {
   // Capacity must be a multiple of TimelineEventBlock::kBlockSize
   ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0);
   // Allocate blocks array.
@@ -895,13 +947,6 @@
   for (intptr_t i = 0; i < num_blocks_ - 1; i++) {
     blocks_[i]->set_next(blocks_[i + 1]);
   }
-  // Pre-allocate DartTimelineEvents.
-  dart_events_ =
-      reinterpret_cast<DartTimelineEvent**>(
-          calloc(dart_events_capacity_, sizeof(DartTimelineEvent*)));
-  for (intptr_t i = 0; i < dart_events_capacity_; i++) {
-    dart_events_[i] = new DartTimelineEvent();
-  }
 }
 
 
@@ -912,18 +957,13 @@
     delete block;
   }
   free(blocks_);
-  // Delete all DartTimelineEvents.
-  for (intptr_t i = 0; i < dart_events_capacity_; i++) {
-    DartTimelineEvent* event = dart_events_[i];
-    delete event;
-  }
-  free(dart_events_);
 }
 
 
 void TimelineEventRingRecorder::PrintJSONEvents(
     JSONArray* events,
-    TimelineEventFilter* filter) const {
+    TimelineEventFilter* filter) {
+  MutexLocker ml(&lock_);
   intptr_t block_offset = FindOldestBlockIndex();
   if (block_offset == -1) {
     // All blocks are empty.
@@ -937,7 +977,9 @@
     }
     for (intptr_t event_idx = 0; event_idx < block->length(); event_idx++) {
       TimelineEvent* event = block->At(event_idx);
-      if (filter->IncludeEvent(event)) {
+      if (filter->IncludeEvent(event) &&
+          event->Within(filter->time_origin_micros(),
+                        filter->time_extent_micros())) {
         events->AddValue(event);
       }
     }
@@ -947,7 +989,6 @@
 
 void TimelineEventRingRecorder::PrintJSON(JSONStream* js,
                                           TimelineEventFilter* filter) {
-  MutexLocker ml(&lock_);
   JSONObject topLevel(js);
   topLevel.AddProperty("type", "_Timeline");
   {
@@ -958,33 +999,6 @@
 }
 
 
-void TimelineEventRingRecorder::AppendDartEvent(Isolate* isolate,
-                                                const char* event) {
-  MutexLocker ml(&lock_);
-  // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store
-  // the events.
-  if (dart_events_cursor_ == dart_events_capacity_) {
-    dart_events_cursor_ = 0;
-  }
-  ASSERT(dart_events_[dart_events_cursor_] != NULL);
-  dart_events_[dart_events_cursor_]->Clear();
-  dart_events_[dart_events_cursor_]->Init(isolate, event);
-  dart_events_cursor_++;
-}
-
-
-intptr_t TimelineEventRingRecorder::NumDartEventsLocked() {
-  return dart_events_capacity_;
-}
-
-
-DartTimelineEvent* TimelineEventRingRecorder::DartEventAtLocked(intptr_t i) {
-  ASSERT(i >= 0);
-  ASSERT(i < dart_events_capacity_);
-  return dart_events_[i];
-}
-
-
 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js,
                                                 TimelineEventFilter* filter) {
   JSONArray events(js);
@@ -997,8 +1011,7 @@
 }
 
 
-TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked(
-    Isolate* isolate) {
+TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() {
   // TODO(johnmccutchan): This function should only hand out blocks
   // which have been marked as finished.
   if (block_cursor_ == num_blocks_) {
@@ -1006,11 +1019,20 @@
   }
   TimelineEventBlock* block = blocks_[block_cursor_++];
   block->Reset();
-  block->Open(isolate);
+  block->Open();
   return block;
 }
 
 
+void TimelineEventRingRecorder::Clear() {
+  MutexLocker ml(&lock_);
+  for (intptr_t i = 0; i < num_blocks_; i++) {
+    TimelineEventBlock* block = blocks_[i];
+    block->Reset();
+  }
+}
+
+
 intptr_t TimelineEventRingRecorder::FindOldestBlockIndex() const {
   int64_t earliest_time = kMaxInt64;
   intptr_t earliest_index = -1;
@@ -1030,13 +1052,6 @@
 
 
 TimelineEvent* TimelineEventRingRecorder::StartEvent() {
-  // Grab the current thread.
-  Thread* thread = Thread::Current();
-  ASSERT(thread != NULL);
-  if (thread->isolate() == NULL) {
-    // Non-isolate thread case. This should be infrequent.
-    return GlobalBlockStartEvent();
-  }
   return ThreadBlockStartEvent();
 }
 
@@ -1045,11 +1060,7 @@
   if (event == NULL) {
     return;
   }
-  if (event->global_block()) {
-    GlobalBlockCompleteEvent(event);
-  } else {
-    ThreadBlockCompleteEvent(event);
-  }
+  ThreadBlockCompleteEvent(event);
 }
 
 
@@ -1079,25 +1090,6 @@
 }
 
 
-void TimelineEventStreamingRecorder::AppendDartEvent(Isolate* isolate,
-                                                     const char* event) {
-  if (event != NULL) {
-    StreamDartEvent(event);
-  }
-}
-
-
-intptr_t TimelineEventStreamingRecorder::NumDartEventsLocked() {
-  return 0;
-}
-
-
-DartTimelineEvent* TimelineEventStreamingRecorder::DartEventAtLocked(
-    intptr_t i) {
-  return NULL;
-}
-
-
 TimelineEvent* TimelineEventStreamingRecorder::StartEvent() {
   TimelineEvent* event = new TimelineEvent();
   return event;
@@ -1112,16 +1104,12 @@
 
 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder()
     : head_(NULL),
-      block_index_(0),
-      dart_events_(NULL),
-      dart_events_capacity_(0),
-      dart_events_cursor_(0) {
+      block_index_(0) {
 }
 
 
 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js,
                                              TimelineEventFilter* filter) {
-  MutexLocker ml(&lock_);
   JSONObject topLevel(js);
   topLevel.AddProperty("type", "_Timeline");
   {
@@ -1140,44 +1128,12 @@
 }
 
 
-void TimelineEventEndlessRecorder::AppendDartEvent(Isolate* isolate,
-                                                   const char* event) {
-  MutexLocker ml(&lock_);
-  // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store
-  // the events.
-  if (dart_events_cursor_ == dart_events_capacity_) {
-    // Grow.
-    intptr_t new_capacity =
-        (dart_events_capacity_ == 0) ? 16 : dart_events_capacity_ * 2;
-    dart_events_ = reinterpret_cast<DartTimelineEvent**>(
-        realloc(dart_events_, new_capacity * sizeof(DartTimelineEvent*)));
-    for (intptr_t i = dart_events_capacity_; i < new_capacity; i++) {
-      // Fill with NULLs.
-      dart_events_[i] = NULL;
-    }
-    dart_events_capacity_ = new_capacity;
-  }
-  ASSERT(dart_events_cursor_ < dart_events_capacity_);
-  DartTimelineEvent* dart_event = new DartTimelineEvent();
-  dart_event->Init(isolate, event);
-  ASSERT(dart_events_[dart_events_cursor_] == NULL);
-  dart_events_[dart_events_cursor_++] = dart_event;
-}
-
-
 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() {
   return head_;
 }
 
 
 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() {
-  // Grab the current thread.
-  Thread* thread = Thread::Current();
-  ASSERT(thread != NULL);
-  if (thread->isolate() == NULL) {
-    // Non-isolate thread case. This should be infrequent.
-    return GlobalBlockStartEvent();
-  }
   return ThreadBlockStartEvent();
 }
 
@@ -1186,50 +1142,27 @@
   if (event == NULL) {
     return;
   }
-  if (event->global_block()) {
-    GlobalBlockCompleteEvent(event);
-  } else {
-    ThreadBlockCompleteEvent(event);
-  }
+  ThreadBlockCompleteEvent(event);
 }
 
 
-TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked(
-    Isolate* isolate) {
+TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() {
   TimelineEventBlock* block = new TimelineEventBlock(block_index_++);
   block->set_next(head_);
-  block->Open(isolate);
+  block->Open();
   head_ = block;
   if (FLAG_trace_timeline) {
-    if (isolate != NULL) {
-      OS::Print("Created new isolate block %p for %s\n",
-                block, isolate->name());
-    } else {
-      OS::Print("Created new global block %p\n", block);
-    }
+    OS::Print("Created new block %p\n", block);
   }
   return head_;
 }
 
 
-intptr_t TimelineEventEndlessRecorder::NumDartEventsLocked() {
-  return dart_events_cursor_;
-}
-
-
-DartTimelineEvent* TimelineEventEndlessRecorder::DartEventAtLocked(
-    intptr_t i) {
-  ASSERT(i >= 0);
-  ASSERT(i < dart_events_cursor_);
-  return dart_events_[i];
-}
-
-
 void TimelineEventEndlessRecorder::PrintJSONEvents(
     JSONArray* events,
-    TimelineEventFilter* filter) const {
+    TimelineEventFilter* filter) {
+  MutexLocker ml(&lock_);
   TimelineEventBlock* current = head_;
-
   while (current != NULL) {
     if (!filter->IncludeBlock(current)) {
       current = current->next();
@@ -1238,10 +1171,11 @@
     intptr_t length = current->length();
     for (intptr_t i = 0; i < length; i++) {
       TimelineEvent* event = current->At(i);
-      if (!filter->IncludeEvent(event)) {
-        continue;
+      if (filter->IncludeEvent(event) &&
+          event->Within(filter->time_origin_micros(),
+                        filter->time_extent_micros())) {
+        events->AddValue(event);
       }
-      events->AddValue(event);
     }
     current = current->next();
   }
@@ -1257,7 +1191,7 @@
   }
   head_ = NULL;
   block_index_ = 0;
-  Thread* thread = Thread::Current();
+  OSThread* thread = OSThread::Current();
   thread->set_timeline_block(NULL);
 }
 
@@ -1266,7 +1200,7 @@
     : next_(NULL),
       length_(0),
       block_index_(block_index),
-      isolate_(NULL),
+      thread_id_(OSThread::kInvalidThreadId),
       in_use_(false) {
 }
 
@@ -1279,20 +1213,19 @@
 TimelineEvent* TimelineEventBlock::StartEvent() {
   ASSERT(!IsFull());
   if (FLAG_trace_timeline) {
-    OS::Print("StartEvent in block %p for thread %" Px "\n",
-              this, OSThread::CurrentCurrentThreadIdAsIntPtr());
+    OSThread* os_thread = OSThread::Current();
+    ASSERT(os_thread != NULL);
+    intptr_t tid = OSThread::ThreadIdToIntPtr(os_thread->id());
+    OS::Print("StartEvent in block %p for thread %" Px "\n", this, tid);
   }
   return &events_[length_++];
 }
 
 
-ThreadId TimelineEventBlock::thread() const {
-  ASSERT(length_ > 0);
-  return events_[0].thread();
-}
-
-
 int64_t TimelineEventBlock::LowerTimeBound() const {
+  if (length_ == 0) {
+    return kMaxInt64;
+  }
   ASSERT(length_ > 0);
   return events_[0].TimeOrigin();
 }
@@ -1303,10 +1236,8 @@
     return true;
   }
 
-  // - events in the block come from one thread.
-  ThreadId tid = thread();
   for (intptr_t i = 0; i < length(); i++) {
-    if (At(i)->thread() != tid) {
+    if (At(i)->thread() != thread_id()) {
       return false;
     }
   }
@@ -1330,13 +1261,15 @@
     events_[i].Reset();
   }
   length_ = 0;
-  isolate_ = NULL;
+  thread_id_ = OSThread::kInvalidThreadId;
   in_use_ = false;
 }
 
 
-void TimelineEventBlock::Open(Isolate* isolate) {
-  isolate_ = isolate;
+void TimelineEventBlock::Open() {
+  OSThread* os_thread = OSThread::Current();
+  ASSERT(os_thread != NULL);
+  thread_id_ = os_thread->trace_id();
   in_use_ = true;
 }
 
@@ -1392,80 +1325,4 @@
   return r;
 }
 
-
-DartTimelineEventIterator::DartTimelineEventIterator(
-    TimelineEventRecorder* recorder)
-    : cursor_(0),
-      num_events_(0),
-      recorder_(NULL) {
-  Reset(recorder);
-}
-
-
-DartTimelineEventIterator::~DartTimelineEventIterator() {
-  Reset(NULL);
-}
-
-
-void DartTimelineEventIterator::Reset(TimelineEventRecorder* recorder) {
-  // Clear state.
-  cursor_ = 0;
-  num_events_ = 0;
-  if (recorder_ != NULL) {
-    // Unlock old recorder.
-    recorder_->lock_.Unlock();
-  }
-  recorder_ = recorder;
-  if (recorder_ == NULL) {
-    return;
-  }
-  // Lock new recorder.
-  recorder_->lock_.Lock();
-  cursor_ = 0;
-  num_events_ = recorder_->NumDartEventsLocked();
-}
-
-
-bool DartTimelineEventIterator::HasNext() const {
-  return cursor_ < num_events_;
-}
-
-
-DartTimelineEvent* DartTimelineEventIterator::Next() {
-  ASSERT(cursor_ < num_events_);
-  DartTimelineEvent* r = recorder_->DartEventAtLocked(cursor_);
-  cursor_++;
-  return r;
-}
-
-const char* DartTimelineEventIterator::PrintTraceEvents(
-    TimelineEventRecorder* recorder,
-    Zone* zone,
-    Isolate* isolate) {
-  if (recorder == NULL) {
-    return NULL;
-  }
-
-  if (zone == NULL) {
-    return NULL;
-  }
-
-  char* result = NULL;
-  DartTimelineEventIterator iterator(recorder);
-  while (iterator.HasNext()) {
-    DartTimelineEvent* event = iterator.Next();
-    if (!event->IsValid()) {
-      // Skip invalid
-      continue;
-    }
-    if ((isolate != NULL) && (isolate != event->isolate())) {
-      // If an isolate was specified, skip events from other isolates.
-      continue;
-    }
-    ASSERT(event->event_as_json() != NULL);
-    result = zone->ConcatStrings(result, event->event_as_json());
-  }
-  return result;
-}
-
 }  // namespace dart
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 82ceb18..d0c43e0 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -30,6 +30,7 @@
   V(API, false)                                                                \
   V(Compiler, false)                                                           \
   V(Dart, false)                                                               \
+  V(Debugger, false)                                                           \
   V(Embedder, false)                                                           \
   V(GC, false)                                                                 \
   V(Isolate, false)                                                            \
@@ -49,12 +50,12 @@
 
   static TimelineStream* GetVMStream();
 
-  // Reclaim all |TimelineEventBlock|s that are owned by the current isolate.
-  static void ReclaimIsolateBlocks();
+  static TimelineStream* GetVMApiStream();
 
-  // Reclaim all |TimelineEventBlocks|s that are owned by all isolates and
-  // the global block owned by the VM.
-  static void ReclaimAllBlocks();
+  // Reclaim all |TimelineEventBlocks|s that are cached by threads.
+  static void ReclaimCachedBlocksFromThreads();
+
+  static void Clear();
 
 #define ISOLATE_TIMELINE_STREAM_FLAGS(name, not_used)                          \
   static const bool* Stream##name##EnabledFlag() {                             \
@@ -67,10 +68,9 @@
 #undef ISOLATE_TIMELINE_STREAM_FLAGS
 
  private:
-  static void ReclaimBlocksForIsolate(Isolate* isolate);
-
   static TimelineEventRecorder* recorder_;
   static TimelineStream* vm_stream_;
+  static TimelineStream* vm_api_stream_;
 
 #define ISOLATE_TIMELINE_STREAM_DECLARE_FLAG(name, not_used)                   \
   static bool stream_##name##_enabled_;
@@ -94,6 +94,7 @@
   // Keep in sync with StateBits below.
   enum EventType {
     kNone,
+    kSerializedJSON,  // Events from Dart code.
     kBegin,
     kEnd,
     kDuration,
@@ -114,31 +115,40 @@
   }
 
   // Marks the beginning of an asynchronous operation with |async_id|.
-  void AsyncBegin(const char* label, int64_t async_id);
+  void AsyncBegin(const char* label,
+                  int64_t async_id,
+                  int64_t micros = OS::GetCurrentMonotonicMicros());
   // Marks an instantaneous event associated with |async_id|.
   void AsyncInstant(const char* label,
-                    int64_t async_id);
+                    int64_t async_id,
+                    int64_t micros = OS::GetCurrentMonotonicMicros());
   // Marks the end of an asynchronous operation associated with |async_id|.
   void AsyncEnd(const char* label,
-                int64_t async_id);
+                int64_t async_id,
+                int64_t micros = OS::GetCurrentMonotonicMicros());
 
-  void DurationBegin(const char* label);
-  void DurationEnd();
-  void Instant(const char* label);
+  void DurationBegin(const char* label,
+                     int64_t micros = OS::GetCurrentMonotonicMicros());
+  void DurationEnd(int64_t micros = OS::GetCurrentMonotonicMicros());
+  void Instant(const char* label,
+               int64_t micros = OS::GetCurrentMonotonicMicros());
 
   void Duration(const char* label,
                 int64_t start_micros,
                 int64_t end_micros);
 
   void Begin(const char* label,
-             int64_t micros = OS::GetCurrentTraceMicros());
+             int64_t micros = OS::GetCurrentMonotonicMicros());
 
   void End(const char* label,
-           int64_t micros = OS::GetCurrentTraceMicros());
+           int64_t micros = OS::GetCurrentMonotonicMicros());
+
+  // Completes this event with pre-serialized JSON. Copies |json|.
+  void CompleteWithPreSerializedJSON(const char* json);
 
   // Set the number of arguments in the event.
   void SetNumArguments(intptr_t length);
-  // |name| must be a compile time constant. Takes ownership of |argumentp|.
+  // |name| must be a compile time constant. Takes ownership of |argument|.
   void SetArgument(intptr_t i, const char* name, char* argument);
   // |name| must be a compile time constant. Copies |argument|.
   void CopyArgument(intptr_t i, const char* name, const char* argument);
@@ -174,6 +184,10 @@
     return thread_;
   }
 
+  Dart_Port isolate_id() const {
+    return isolate_id_;
+  }
+
   const char* label() const {
     return label_;
   }
@@ -229,17 +243,12 @@
     }
   }
 
- private:
-  int64_t timestamp0_;
-  int64_t timestamp1_;
-  TimelineEventArgument* arguments_;
-  intptr_t arguments_length_;
-  uword state_;
-  const char* label_;
-  const char* category_;
-  ThreadId thread_;
-  Isolate* isolate_;
+  bool Within(int64_t time_origin_micros,
+              int64_t time_extent_micros);
 
+  const char* GetSerializedJSON() const;
+
+ private:
   void FreeArguments();
 
   void StreamInit(TimelineStream* stream);
@@ -251,23 +260,42 @@
     state_ = EventTypeField::update(event_type, state_);
   }
 
-  void set_global_block(bool global_block) {
-    state_ = GlobalBlockField::update(global_block, state_);
+  void set_timestamp0(int64_t value) {
+    ASSERT(timestamp0_ == 0);
+    timestamp0_ = value;
+  }
+  void set_timestamp1(int64_t value) {
+    ASSERT(timestamp1_ == 0);
+    timestamp1_ = value;
   }
 
-  bool global_block() const {
-    return GlobalBlockField::decode(state_);
+  bool pre_serialized_json() const {
+    return PreSerializedJSON::decode(state_);
+  }
+
+  void set_pre_serialized_json(bool pre_serialized_json) {
+    state_ = PreSerializedJSON::update(pre_serialized_json, state_);
   }
 
   enum StateBits {
     kEventTypeBit = 0,  // reserve 4 bits for type.
-    // Was this event allocated from the global block?
-    kGlobalBlockBit = 4,
+    kPreSerializedJSON = 4,
     kNextBit = 5,
   };
 
   class EventTypeField : public BitField<EventType, kEventTypeBit, 4> {};
-  class GlobalBlockField : public BitField<bool, kGlobalBlockBit, 1> {};
+  class PreSerializedJSON :
+      public BitField<bool, kPreSerializedJSON, 1> {};
+
+  int64_t timestamp0_;
+  int64_t timestamp1_;
+  TimelineEventArgument* arguments_;
+  intptr_t arguments_length_;
+  uword state_;
+  const char* label_;
+  const char* category_;
+  ThreadId thread_;
+  Dart_Port isolate_id_;
 
   friend class TimelineEventRecorder;
   friend class TimelineEventEndlessRecorder;
@@ -326,21 +354,13 @@
     tds.CopyArgument(                                                          \
         0,                                                                     \
         "function",                                                            \
-        const_cast<char*>(function.ToLibNamePrefixedQualifiedCString()));      \
+        function.ToLibNamePrefixedQualifiedCString());                         \
   }
 
 
-class TimelineDurationScope : public StackResource {
+// See |TimelineDurationScope| and |TimelineBeginEndScope|.
+class TimelineEventScope : public StackResource {
  public:
-  TimelineDurationScope(TimelineStream* stream,
-                        const char* label);
-
-  TimelineDurationScope(Thread* thread,
-                        TimelineStream* stream,
-                        const char* label);
-
-  ~TimelineDurationScope();
-
   bool enabled() const {
     return enabled_;
   }
@@ -355,21 +375,81 @@
                       const char* name,
                       const char* fmt, ...)  PRINTF_ATTRIBUTE(4, 5);
 
+ protected:
+  TimelineEventScope(TimelineStream* stream,
+                     const char* label);
+
+  TimelineEventScope(Thread* thread,
+                     TimelineStream* stream,
+                     const char* label);
+
+  bool ShouldEmitEvent() const {
+    return enabled_;
+  }
+
+  const char* label() const {
+    return label_;
+  }
+
+  TimelineStream* stream() const {
+    return stream_;
+  }
+
+  virtual ~TimelineEventScope();
+
+  void StealArguments(TimelineEvent* event);
+
  private:
   void Init();
   void FreeArguments();
 
-  int64_t timestamp_;
   TimelineStream* stream_;
   const char* label_;
   TimelineEventArgument* arguments_;
   intptr_t arguments_length_;
   bool enabled_;
 
+  DISALLOW_COPY_AND_ASSIGN(TimelineEventScope);
+};
+
+
+class TimelineDurationScope : public TimelineEventScope {
+ public:
+  TimelineDurationScope(TimelineStream* stream,
+                        const char* label);
+
+  TimelineDurationScope(Thread* thread,
+                        TimelineStream* stream,
+                        const char* label);
+
+  ~TimelineDurationScope();
+
+ private:
+  int64_t timestamp_;
+
   DISALLOW_COPY_AND_ASSIGN(TimelineDurationScope);
 };
 
 
+class TimelineBeginEndScope : public TimelineEventScope {
+ public:
+  TimelineBeginEndScope(TimelineStream* stream,
+                        const char* label);
+
+  TimelineBeginEndScope(Thread* thread,
+                        TimelineStream* stream,
+                        const char* label);
+
+  ~TimelineBeginEndScope();
+
+ private:
+  void EmitBegin();
+  void EmitEnd();
+
+  DISALLOW_COPY_AND_ASSIGN(TimelineBeginEndScope);
+};
+
+
 // A block of |TimelineEvent|s. Not thread safe.
 class TimelineEventBlock {
  public:
@@ -413,8 +493,6 @@
     return &events_[index];
   }
 
-  // Attempt to sniff a thread id from the first event.
-  ThreadId thread() const;
   // Attempt to sniff the timestamp from the first event.
   int64_t LowerTimeBound() const;
 
@@ -432,8 +510,8 @@
   }
 
   // Only safe to access under the recorder's lock.
-  Isolate* isolate() const {
-    return isolate_;
+  ThreadId thread_id() const {
+    return thread_id_;
   }
 
  protected:
@@ -445,10 +523,10 @@
   intptr_t block_index_;
 
   // Only accessed under the recorder's lock.
-  Isolate* isolate_;
+  ThreadId thread_id_;
   bool in_use_;
 
-  void Open(Isolate* isolate);
+  void Open();
   void Finish();
 
   friend class Thread;
@@ -465,7 +543,9 @@
 
 class TimelineEventFilter : public ValueObject {
  public:
-  TimelineEventFilter();
+  TimelineEventFilter(int64_t time_origin_micros = -1,
+                      int64_t time_extent_micros = -1);
+
   virtual ~TimelineEventFilter();
 
   virtual bool IncludeBlock(TimelineEventBlock* block) {
@@ -483,58 +563,41 @@
     return event->IsValid();
   }
 
+  int64_t time_origin_micros() const {
+    return time_origin_micros_;
+  }
+
+  int64_t time_extent_micros() const {
+    return time_extent_micros_;
+  }
+
  private:
+  int64_t time_origin_micros_;
+  int64_t time_extent_micros_;
 };
 
 
 class IsolateTimelineEventFilter : public TimelineEventFilter {
  public:
-  explicit IsolateTimelineEventFilter(Isolate* isolate);
+  explicit IsolateTimelineEventFilter(Dart_Port isolate_id,
+                                      int64_t time_origin_micros = -1,
+                                      int64_t time_extent_micros = -1);
 
   bool IncludeBlock(TimelineEventBlock* block) {
     if (block == NULL) {
       return false;
     }
     // Not empty, not in use, and isolate match.
-    return !block->IsEmpty() && !block->in_use() &&
-           (block->isolate() == isolate_);
+    return !block->IsEmpty() && !block->in_use();
+  }
+
+  bool IncludeEvent(TimelineEvent* event) {
+    return event->IsValid() &&
+           (event->isolate_id() == isolate_id_);
   }
 
  private:
-  Isolate* isolate_;
-};
-
-
-// Timeline events from Dart code are eagerly converted to JSON and stored
-// as a C string.
-class DartTimelineEvent {
- public:
-  DartTimelineEvent();
-  ~DartTimelineEvent();
-
-  void Clear();
-
-  // This function makes a copy of |event|.
-  void Init(Isolate* isolate, const char* event);
-
-  bool IsValid() const {
-    return (isolate_ != NULL) &&
-           (event_as_json_ != NULL);
-  }
-
-  Isolate* isolate() const {
-    return isolate_;
-  }
-
-  char* event_as_json() const {
-    return event_as_json_;
-  }
-
- private:
-  Isolate* isolate_;
-  char* event_as_json_;
-
-  DISALLOW_COPY_AND_ASSIGN(DartTimelineEvent);
+  Dart_Port isolate_id_;
 };
 
 
@@ -554,9 +617,6 @@
 
   void FinishBlock(TimelineEventBlock* block);
 
-  // Interface method(s) which must be implemented.
-  virtual void AppendDartEvent(Isolate* isolate, const char* event) = 0;
-
  protected:
   void WriteTo(const char* directory);
 
@@ -564,25 +624,17 @@
   virtual TimelineEvent* StartEvent() = 0;
   virtual void CompleteEvent(TimelineEvent* event) = 0;
   virtual TimelineEventBlock* GetHeadBlockLocked() = 0;
-  virtual TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) = 0;
-  virtual intptr_t NumDartEventsLocked() = 0;
-  virtual DartTimelineEvent* DartEventAtLocked(intptr_t i) = 0;
+  virtual TimelineEventBlock* GetNewBlockLocked() = 0;
+  virtual void Clear() = 0;
 
   // Utility method(s).
   void PrintJSONMeta(JSONArray* array) const;
   TimelineEvent* ThreadBlockStartEvent();
-  TimelineEvent* GlobalBlockStartEvent();
   void ThreadBlockCompleteEvent(TimelineEvent* event);
-  void GlobalBlockCompleteEvent(TimelineEvent* event);
 
   Mutex lock_;
-  // Only accessed under |lock_|.
-  TimelineEventBlock* global_block_;
-  void ReclaimGlobalBlock();
-
   uintptr_t async_id_;
 
-  friend class DartTimelineEventIterator;
   friend class TimelineEvent;
   friend class TimelineEventBlockIterator;
   friend class TimelineStream;
@@ -605,27 +657,20 @@
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
 
-  void AppendDartEvent(Isolate* isolate, const char* event);
-
  protected:
   TimelineEvent* StartEvent();
   void CompleteEvent(TimelineEvent* event);
   TimelineEventBlock* GetHeadBlockLocked();
   intptr_t FindOldestBlockIndex() const;
-  TimelineEventBlock* GetNewBlockLocked(Isolate* isolate);
-  intptr_t NumDartEventsLocked();
-  DartTimelineEvent* DartEventAtLocked(intptr_t i);
+  TimelineEventBlock* GetNewBlockLocked();
+  void Clear();
 
-  void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const;
+  void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter);
 
   TimelineEventBlock** blocks_;
   intptr_t capacity_;
   intptr_t num_blocks_;
   intptr_t block_cursor_;
-
-  DartTimelineEvent** dart_events_;
-  intptr_t dart_events_capacity_;
-  intptr_t dart_events_cursor_;
 };
 
 
@@ -638,22 +683,19 @@
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
 
-  void AppendDartEvent(Isolate* isolate, const char* event);
-
   // Called when |event| is ready to be streamed. It is unsafe to keep a
   // reference to |event| as it may be freed as soon as this function returns.
   virtual void StreamEvent(TimelineEvent* event) = 0;
-  virtual void StreamDartEvent(const char* event) = 0;
 
  protected:
-  TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) {
+  TimelineEventBlock* GetNewBlockLocked() {
     return NULL;
   }
   TimelineEventBlock* GetHeadBlockLocked() {
     return NULL;
   }
-  intptr_t NumDartEventsLocked();
-  DartTimelineEvent* DartEventAtLocked(intptr_t i);
+  void Clear() {
+  }
   TimelineEvent* StartEvent();
   void CompleteEvent(TimelineEvent* event);
 };
@@ -669,28 +711,18 @@
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
 
-  void AppendDartEvent(Isolate* isolate, const char* event);
-
  protected:
   TimelineEvent* StartEvent();
   void CompleteEvent(TimelineEvent* event);
-  TimelineEventBlock* GetNewBlockLocked(Isolate* isolate);
+  TimelineEventBlock* GetNewBlockLocked();
   TimelineEventBlock* GetHeadBlockLocked();
-  intptr_t NumDartEventsLocked();
-  DartTimelineEvent* DartEventAtLocked(intptr_t i);
-
-  void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const;
-
-  // Useful only for testing. Only works for one thread.
   void Clear();
 
+  void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter);
+
   TimelineEventBlock* head_;
   intptr_t block_index_;
 
-  DartTimelineEvent** dart_events_;
-  intptr_t dart_events_capacity_;
-  intptr_t dart_events_cursor_;
-
   friend class TimelineTestHelper;
 };
 
@@ -715,32 +747,6 @@
 };
 
 
-// An iterator for timeline events.
-class DartTimelineEventIterator {
- public:
-  explicit DartTimelineEventIterator(TimelineEventRecorder* recorder);
-  ~DartTimelineEventIterator();
-
-  void Reset(TimelineEventRecorder* recorder);
-
-  // Returns true if there is another event.
-  bool HasNext() const;
-
-  // Returns the next event and moves forward.
-  DartTimelineEvent* Next();
-
-  // Returns a zone allocated string of all trace events for isolate.
-  // If isolate is NULL, all isolates' events will be included.
-  static const char* PrintTraceEvents(TimelineEventRecorder* recorder,
-                                      Zone* zone,
-                                      Isolate* isolate);
-
- private:
-  intptr_t cursor_;
-  intptr_t num_events_;
-  TimelineEventRecorder* recorder_;
-};
-
 }  // namespace dart
 
 #endif  // VM_TIMELINE_H_
diff --git a/runtime/vm/timeline_analysis.cc b/runtime/vm/timeline_analysis.cc
index faf2f5e..8a7c6fb 100644
--- a/runtime/vm/timeline_analysis.cc
+++ b/runtime/vm/timeline_analysis.cc
@@ -162,10 +162,6 @@
       // Skip empty blocks.
       continue;
     }
-    if (block->isolate() != isolate_) {
-      // Skip blocks for other isolates.
-      continue;
-    }
     if (!block->CheckBlock()) {
       if (FLAG_trace_timeline_analysis) {
         THR_Print("DiscoverThreads block %" Pd " "
@@ -175,7 +171,7 @@
                "TimelineEventBlock::CheckBlock", block->block_index());
       return;
     }
-    TimelineAnalysisThread* thread = GetOrAddThread(block->thread());
+    TimelineAnalysisThread* thread = GetOrAddThread(block->thread_id());
     ASSERT(thread != NULL);
     thread->AddBlock(block);
   }
@@ -347,6 +343,10 @@
   intptr_t event_count = 0;
   while (!has_error() && it.HasNext()) {
     TimelineEvent* event = it.Next();
+    if (event->isolate_id() != isolate_->main_port()) {
+      // Skip events that do not belong to the isolate.
+      continue;
+    }
     if (event->IsFinishedDuration()) {
       int64_t start = event->TimeOrigin();
       PopFinishedDurations(start);
diff --git a/runtime/vm/timeline_test.cc b/runtime/vm/timeline_test.cc
index 17fea5d..2d9bb57 100644
--- a/runtime/vm/timeline_test.cc
+++ b/runtime/vm/timeline_test.cc
@@ -51,6 +51,11 @@
     }
   }
 
+  static void SetBlockThread(TimelineEventBlock* block,
+                             intptr_t ftid) {
+    block->thread_id_ = OSThread::ThreadIdFromIntPtr(ftid);
+  }
+
   static void FakeDuration(
       TimelineEventRecorder* recorder,
       const char* label,
@@ -242,10 +247,6 @@
     counts_[event->event_type()]++;
   }
 
-  void StreamDartEvent(const char* event) {
-    // NOOP.
-  }
-
   intptr_t CountFor(TimelineEvent::EventType type) {
     return counts_[type];
   }
@@ -324,12 +325,17 @@
   ASSERT(recorder != NULL);
   // Blocks owned by thread "1".
   TimelineEventBlock* block_1_0 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_1_0, 1);
   TimelineEventBlock* block_1_1 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_1_1, 1);
   TimelineEventBlock* block_1_2 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_1_2, 1);
   // Blocks owned by thread "2".
   TimelineEventBlock* block_2_0 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_2_0, 2);
   // Blocks owned by thread "3".
   TimelineEventBlock* block_3_0 = recorder->GetNewBlock();
+  TimelineTestHelper::SetBlockThread(block_3_0, 3);
   USE(block_3_0);
 
   // Add events to each block for thread 1.
@@ -358,6 +364,7 @@
   // Discover threads in recorder.
   TimelineAnalysis ta(zone, isolate, recorder);
   ta.BuildThreads();
+  EXPECT(!ta.has_error());
   // block_3_0 is never used by a thread, so we only have two threads.
   EXPECT_EQ(2, ta.NumThreads());
 
@@ -471,7 +478,9 @@
   ASSERT(recorder != NULL);
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
-  ThreadId tid = OSThread::GetCurrentThreadTraceId();
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
+  ThreadId tid = os_thread->trace_id();
 
   // Test case.
   TimelineTestHelper::FakeDuration(recorder, "a", 0, 10);
@@ -641,7 +650,9 @@
   ASSERT(recorder != NULL);
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
-  ThreadId tid = OSThread::GetCurrentThreadTraceId();
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
+  ThreadId tid = os_thread->trace_id();
 
   // Test case.
   TimelineTestHelper::FakeBegin(recorder, "a", 0);
diff --git a/runtime/vm/timer.h b/runtime/vm/timer.h
index 4738efa..e4ee890 100644
--- a/runtime/vm/timer.h
+++ b/runtime/vm/timer.h
@@ -108,13 +108,6 @@
     Init();
   }
 
-  TimerScope(bool flag, Timer* timer, Isolate* isolate = NULL)
-      : StackResource(isolate),
-        nested_(false),
-        timer_(flag ? timer : NULL) {
-    Init();
-  }
-
   void Init() {
     if (timer_ != NULL) {
       if (!timer_->running()) {
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 9694527..2861fab 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -200,7 +200,7 @@
 void AssemblerTest::Assemble() {
   const String& function_name = String::ZoneHandle(Symbols::New(name_));
   const Class& cls = Class::ZoneHandle(
-      Class::New(function_name, Script::Handle(), Scanner::kNoSourcePos));
+      Class::New(function_name, Script::Handle(), 0));
   const Library& lib = Library::ZoneHandle(Library::New(function_name));
   cls.set_library(lib);
   Function& function = Function::ZoneHandle(
@@ -220,7 +220,7 @@
 
 CodeGenTest::CodeGenTest(const char* name)
   : function_(Function::ZoneHandle()),
-    node_sequence_(new SequenceNode(Scanner::kNoSourcePos,
+    node_sequence_(new SequenceNode(0,
                                     new LocalScope(NULL, 0, 0))),
     default_parameter_values_(new ZoneGrowableArray<const Instance*> ()) {
   ASSERT(name != NULL);
@@ -228,7 +228,7 @@
   // Add function to a class and that class to the class dictionary so that
   // frame walking can be used.
   const Class& cls = Class::ZoneHandle(
-       Class::New(function_name, Script::Handle(), Scanner::kNoSourcePos));
+       Class::New(function_name, Script::Handle(), 0));
   function_ = Function::New(
       function_name, RawFunction::kRegularFunction,
       true, false, false, false, false, cls, 0);
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 6e1ca5c..a8b063a 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -360,36 +360,44 @@
 
   uword entry() const { return code_.EntryPoint(); }
 
-  // Invoke/InvokeWithCode is used to call assembler test functions using the
-  // ABI calling convention.
+  // Invoke/InvokeWithCodeAndThread is used to call assembler test functions
+  // using the ABI calling convention.
   // ResultType is the return type of the assembler test function.
   // ArgNType is the type of the Nth argument.
 #if defined(USING_SIMULATOR)
 
 #if defined(ARCH_IS_64_BIT)
-  // TODO(fschneider): Make InvokeWithCode<> more general and work on 32-bit.
+  // TODO(fschneider): Make InvokeWithCodeAndThread<> more general and work on
+  // 32-bit.
   // Since Simulator::Call always return a int64_t, bit_cast does not work
   // on 32-bit platforms when returning an int32_t. Since template functions
   // don't support partial specialization, we'd need to introduce a helper
   // class to support 32-bit return types.
-  template<typename ResultType> ResultType InvokeWithCode() {
+  template<typename ResultType> ResultType InvokeWithCodeAndThread() {
     const bool fp_return = is_double<ResultType>::value;
     const bool fp_args = false;
+    Thread* thread = Thread::Current();
+    ASSERT(thread != NULL);
     return bit_cast<ResultType, int64_t>(Simulator::Current()->Call(
         bit_cast<intptr_t, uword>(entry()),
-        reinterpret_cast<intptr_t>(&code_), 0, 0, 0, fp_return, fp_args));
+        reinterpret_cast<intptr_t>(&code_),
+        reinterpret_cast<intptr_t>(thread),
+        0, 0, fp_return, fp_args));
   }
   template<typename ResultType, typename Arg1Type>
-  ResultType InvokeWithCode(Arg1Type arg1) {
+  ResultType InvokeWithCodeAndThread(Arg1Type arg1) {
     const bool fp_return = is_double<ResultType>::value;
     const bool fp_args = is_double<Arg1Type>::value;
     // TODO(fschneider): Support double arguments for simulator calls.
     COMPILE_ASSERT(!fp_args);
+    Thread* thread = Thread::Current();
+    ASSERT(thread != NULL);
     return bit_cast<ResultType, int64_t>(Simulator::Current()->Call(
         bit_cast<intptr_t, uword>(entry()),
         reinterpret_cast<intptr_t>(&code_),
+        reinterpret_cast<intptr_t>(thread),
         reinterpret_cast<intptr_t>(arg1),
-        0, 0, fp_return, fp_args));
+        0, fp_return, fp_args));
   }
 #endif  // ARCH_IS_64_BIT
 
@@ -413,15 +421,19 @@
         0, fp_return, fp_args);
   }
 #else
-  template<typename ResultType> ResultType InvokeWithCode() {
-    typedef ResultType (*FunctionType) (const Code&);
-    return reinterpret_cast<FunctionType>(entry())(code_);
+  template<typename ResultType> ResultType InvokeWithCodeAndThread() {
+    Thread* thread = Thread::Current();
+    ASSERT(thread != NULL);
+    typedef ResultType (*FunctionType) (const Code&, Thread*);
+    return reinterpret_cast<FunctionType>(entry())(code_, thread);
   }
 
   template<typename ResultType, typename Arg1Type>
-  ResultType InvokeWithCode(Arg1Type arg1) {
-    typedef ResultType (*FunctionType) (const Code&, Arg1Type);
-    return reinterpret_cast<FunctionType>(entry())(code_, arg1);
+  ResultType InvokeWithCodeAndThread(Arg1Type arg1) {
+    Thread* thread = Thread::Current();
+    ASSERT(thread != NULL);
+    typedef ResultType (*FunctionType) (const Code&, Thread*, Arg1Type);
+    return reinterpret_cast<FunctionType>(entry())(code_, thread, arg1);
   }
 
   template<typename ResultType,
diff --git a/runtime/vm/verifier.cc b/runtime/vm/verifier.cc
index 556a738..18ad438 100644
--- a/runtime/vm/verifier.cc
+++ b/runtime/vm/verifier.cc
@@ -79,12 +79,10 @@
   VerifyPointersVisitor visitor(isolate, allocated_set);
   // Visit all strongly reachable objects.
   isolate->IterateObjectPointers(&visitor,
-                                 false,  // skip prologue weak handles
                                  StackFrameIterator::kValidateFrames);
   VerifyWeakPointersVisitor weak_visitor(&visitor);
   // Visit weak handles and prologue weak handles.
-  isolate->VisitWeakPersistentHandles(&weak_visitor,
-                                      true);  // visit prologue weak handles
+  isolate->VisitWeakPersistentHandles(&weak_visitor);
   delete allocated_set;
 }
 
diff --git a/runtime/vm/virtual_memory.cc b/runtime/vm/virtual_memory.cc
index 2f2c1bc..1ad6c06 100644
--- a/runtime/vm/virtual_memory.cc
+++ b/runtime/vm/virtual_memory.cc
@@ -33,7 +33,9 @@
   // Memory for precompilated instructions was allocated by the embedder, so
   // create a VirtualMemory without allocating.
   MemoryRegion region(pointer, size);
-  return new VirtualMemory(region);
+  VirtualMemory* memory = new VirtualMemory(region);
+  memory->embedder_allocated_ = true;
+  return memory;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/virtual_memory.h b/runtime/vm/virtual_memory.h
index 44f3491..53ba57d 100644
--- a/runtime/vm/virtual_memory.h
+++ b/runtime/vm/virtual_memory.h
@@ -69,6 +69,8 @@
   // Commit a reserved memory area, so that the memory can be accessed.
   bool Commit(uword addr, intptr_t size, bool is_executable);
 
+  bool embedder_allocated() const { return embedder_allocated_; }
+
   static VirtualMemory* ForInstructionsSnapshot(void* pointer, uword size);
 
  private:
@@ -82,7 +84,8 @@
   // It does not reserve any virtual address space on its own.
   explicit VirtualMemory(const MemoryRegion& region) :
       region_(region.pointer(), region.size()),
-      reserved_size_(region.size()) { }
+      reserved_size_(region.size()),
+      embedder_allocated_(false) { }
 
   MemoryRegion region_;
 
@@ -92,6 +95,9 @@
 
   static uword page_size_;
 
+  // True for a region provided by the embedder.
+  bool embedder_allocated_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(VirtualMemory);
 };
 
diff --git a/runtime/vm/virtual_memory_android.cc b/runtime/vm/virtual_memory_android.cc
index b7de39b..0e0c1b2 100644
--- a/runtime/vm/virtual_memory_android.cc
+++ b/runtime/vm/virtual_memory_android.cc
@@ -53,7 +53,9 @@
 
 
 VirtualMemory::~VirtualMemory() {
-  unmap(address(), reserved_size_);
+  if (!embedder_allocated()) {
+    unmap(address(), reserved_size_);
+  }
 }
 
 
diff --git a/runtime/vm/virtual_memory_linux.cc b/runtime/vm/virtual_memory_linux.cc
index 3661fb5..275c0c6 100644
--- a/runtime/vm/virtual_memory_linux.cc
+++ b/runtime/vm/virtual_memory_linux.cc
@@ -8,7 +8,6 @@
 #include "vm/virtual_memory.h"
 
 #include <sys/mman.h>  // NOLINT
-#include <sys/unistd.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 
 #include "platform/assert.h"
@@ -53,7 +52,9 @@
 
 
 VirtualMemory::~VirtualMemory() {
-  unmap(address(), reserved_size_);
+  if (!embedder_allocated()) {
+    unmap(address(), reserved_size_);
+  }
 }
 
 
diff --git a/runtime/vm/virtual_memory_macos.cc b/runtime/vm/virtual_memory_macos.cc
index 331ac4b..f28da35 100644
--- a/runtime/vm/virtual_memory_macos.cc
+++ b/runtime/vm/virtual_memory_macos.cc
@@ -53,7 +53,9 @@
 
 
 VirtualMemory::~VirtualMemory() {
-  unmap(address(), reserved_size_);
+  if (!embedder_allocated()) {
+    unmap(address(), reserved_size_);
+  }
 }
 
 
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc
index 1000417..dd154ac 100644
--- a/runtime/vm/virtual_memory_win.cc
+++ b/runtime/vm/virtual_memory_win.cc
@@ -33,7 +33,7 @@
 
 
 VirtualMemory::~VirtualMemory() {
-  if (reserved_size_ == 0) {
+  if (embedder_allocated() || (reserved_size_ == 0)) {
     return;
   }
   if (VirtualFree(address(), 0, MEM_RELEASE) == 0) {
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index 9771a91..b3df320 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -96,6 +96,69 @@
         }]],
     },
     {
+      'target_name': 'libdart_vm_precompiled',
+      'type': 'static_library',
+      'toolsets':['host', 'target'],
+      'includes': [
+        'vm_sources.gypi',
+        '../platform/platform_headers.gypi',
+        '../platform/platform_sources.gypi',
+      ],
+      'sources/': [
+        # Exclude all _test.[cc|h] files.
+        ['exclude', '_test\\.(cc|h)$'],
+      ],
+      'include_dirs': [
+        '..',
+      ],
+      'defines': [
+        'DART_PRECOMPILED',
+      ],
+      'conditions': [
+        ['OS=="linux"', {
+          'link_settings': {
+            'libraries': [
+              '-lpthread',
+              '-lrt',
+              '-ldl',
+            ],
+          },
+        }],
+        ['OS=="android" and _toolset=="host"', {
+          'link_settings': {
+            'libraries': [
+              '-lpthread',
+              '-lrt',
+              '-ldl',
+            ],
+          },
+        }],
+        ['OS=="win"', {
+          'sources/' : [
+            ['exclude', 'gdbjit.cc'],
+          ],
+       }],
+       ['dart_vtune_support==0', {
+          'sources/' : [
+            ['exclude', 'vtune\\.(cc|h)$'],
+          ],
+       }],
+       ['dart_vtune_support==1', {
+          'include_dirs': ['<(dart_vtune_root)/include'],
+          'defines': ['DART_VTUNE_SUPPORT'],
+          'link_settings': {
+            'conditions': [
+              ['OS=="linux"', {
+                 'libraries': ['-ljitprofiling'],
+              }],
+              ['OS=="win"', {
+                 'libraries': ['-ljitprofiling.lib'],
+              }],
+            ],
+          },
+        }]],
+    },
+    {
       'target_name': 'libdart_vm_nosnapshot',
       'type': 'static_library',
       'toolsets':['host', 'target'],
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 5f5fc57..aa1ee40 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -174,6 +174,7 @@
     'flow_graph_allocator.h',
     'flow_graph_builder.cc',
     'flow_graph_builder.h',
+    'flow_graph_builder_test.cc',
     'flow_graph_compiler.cc',
     'flow_graph_compiler.h',
     'flow_graph_compiler_arm.cc',
@@ -315,6 +316,7 @@
     'os_linux.cc',
     'os_macos.cc',
     'os_test.cc',
+    'os_thread.cc',
     'os_thread.h',
     'os_thread_android.cc',
     'os_thread_android.h',
@@ -415,6 +417,9 @@
     'snapshot.h',
     'snapshot_ids.h',
     'snapshot_test.cc',
+    'source_report.cc',
+    'source_report.h',
+    'source_report_test.cc',
     'spaces.h',
     'stack_frame.cc',
     'stack_frame.h',
@@ -451,7 +456,6 @@
     'thread_interrupter_android.cc',
     'thread_interrupter_linux.cc',
     'thread_interrupter_macos.cc',
-    'thread_interrupter_test.cc',
     'thread_interrupter_win.cc',
     'thread_pool.cc',
     'thread_pool.h',
diff --git a/runtime/vm/weak_code.cc b/runtime/vm/weak_code.cc
index cf1e132..7c817d0 100644
--- a/runtime/vm/weak_code.cc
+++ b/runtime/vm/weak_code.cc
@@ -14,6 +14,11 @@
 
 namespace dart {
 
+bool WeakCodeReferences::HasCodes() const {
+  return !array_.IsNull() && (array_.Length() > 0);
+}
+
+
 void WeakCodeReferences::Register(const Code& value) {
   if (!array_.IsNull()) {
     // Try to find and reuse cleared WeakProperty to avoid allocating new one.
@@ -57,6 +62,7 @@
 
 
 void WeakCodeReferences::DisableCode() {
+  IncrementInvalidationGen();
   const Array& code_objects = Array::Handle(array_.raw());
   if (code_objects.IsNull()) {
     return;
diff --git a/runtime/vm/weak_code.h b/runtime/vm/weak_code.h
index 809d3f8..ea2d9c1 100644
--- a/runtime/vm/weak_code.h
+++ b/runtime/vm/weak_code.h
@@ -25,13 +25,16 @@
   virtual void UpdateArrayTo(const Array& array) = 0;
   virtual void ReportDeoptimization(const Code& code) = 0;
   virtual void ReportSwitchingCode(const Code& code) = 0;
+  virtual void IncrementInvalidationGen() = 0;
 
   static bool IsOptimizedCode(const Array& dependent_code, const Code& code);
 
   void DisableCode();
 
+  bool HasCodes() const;
+
  private:
-  const Array& array_;
+  const Array& array_;  // Array of Code objects.
   DISALLOW_COPY_AND_ASSIGN(WeakCodeReferences);
 };
 
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index 7cb7977..4f9a484 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -9,7 +9,6 @@
 #include "vm/flags.h"
 #include "vm/handles_impl.h"
 #include "vm/heap.h"
-#include "vm/isolate.h"
 #include "vm/os.h"
 
 namespace dart {
diff --git a/samples-dev/samples-dev.status b/samples-dev/samples-dev.status
index c477c13..956b798 100644
--- a/samples-dev/samples-dev.status
+++ b/samples-dev/samples-dev.status
@@ -2,36 +2,37 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $compiler == dart2js && $runtime == drt ]	
+[ $compiler == dart2js && $runtime == drt ]
 swarm/test/swarm_test: Pass, Crash, Fail # Issue 10950
 
-[ $runtime == safari ]	
+[ $runtime == safari ]
 swarm/test/swarm_test: Pass, Fail # Issue 14523
 
-[ $runtime == opera ]	
-swarm/test/swarm_ui_lib/touch/touch_test: Fail	
+[ $runtime == opera ]
+swarm/test/swarm_ui_lib/touch/touch_test: Fail
 swarm/test/swarm_test: Fail
 
 [ $runtime == vm ]
 swarm: Skip
 
-[ $compiler == dart2js && $runtime == chromeOnAndroid ]	
+[ $compiler == dart2js && $runtime == chromeOnAndroid ]
 swarm/test/swarm_test: Fail # TODO(kasperl): Please triage.	
-swarm/test/swarm_ui_lib/layout/layout_test: Fail # TODO(kasperl): Please triage.	
-[ $browser ]	
-# This may be related to issue 157	
+swarm/test/swarm_ui_lib/layout/layout_test: Fail # TODO(kasperl): Please triage.
+
+[ $browser ]
+# This may be related to issue 157
 swarm/test/swarm_ui_lib/touch/touch_test: Fail # Expectation: Solver. Expect.approxEquals(expected:9, actual:8.990625000000001, tolerance:0.0009) fails
 
- [ $compiler == dart2js && $runtime == ff ]	
+ [ $compiler == dart2js && $runtime == ff ]
 swarm/test/swarm_test: Fail # Issue 5633
 
-[ $compiler == dart2js && $runtime == drt && $system == windows ]	
+[ $compiler == dart2js && $runtime == drt && $system == windows ]
 swarm/test/swarm_test: Fail # Issue 4517
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]	
-swarm/test/swarm_test: StaticWarning	
-swarm/test/swarm_ui_lib/layout/layout_test: StaticWarning	
-swarm/test/swarm_ui_lib/observable/observable_test: StaticWarning	
-swarm/test/swarm_ui_lib/touch/touch_test: StaticWarning	
-swarm/test/swarm_ui_lib/util/util_test: StaticWarning	
+[ $compiler == dart2analyzer ]
+swarm/test/swarm_test: StaticWarning
+swarm/test/swarm_ui_lib/layout/layout_test: StaticWarning
+swarm/test/swarm_ui_lib/observable/observable_test: StaticWarning
+swarm/test/swarm_ui_lib/touch/touch_test: StaticWarning
+swarm/test/swarm_ui_lib/util/util_test: StaticWarning
 swarm/test/swarm_ui_lib/view/view_test: StaticWarning
diff --git a/samples/samples.status b/samples/samples.status
index 81d9654..480d3f3 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -24,3 +24,5 @@
 [ $arch == simarm64 ]
 *: Skip
 
+[ $runtime == dart_precompiled ]
+sample_extension: RuntimeError # Platform.executable
diff --git a/samples/third_party/dromaeo/.gitignore b/samples/third_party/dromaeo/.gitignore
deleted file mode 100644
index 378eac2..0000000
--- a/samples/third_party/dromaeo/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/samples/third_party/dromaeo/lib/transformer.dart b/samples/third_party/dromaeo/lib/transformer.dart
deleted file mode 100644
index fa50ea3..0000000
--- a/samples/third_party/dromaeo/lib/transformer.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-library dromaeo.transformer;
-
-import 'dart:async';
-import 'package:barback/barback.dart';
-
-/// Transformer used by `pub build` and `pub serve` to rewrite dromaeo html
-/// files to run performance tests.
-class DromaeoTransformer extends Transformer {
-
-  final BarbackSettings settings;
-
-  DromaeoTransformer.asPlugin(this.settings);
-
-  /// The index.html file and the tests/dom-*-html.html files are the ones we
-  /// apply this transform to.
-  Future<bool> isPrimary(AssetId id) {
-    var reg = new RegExp('(tests/dom-.+-html\.html\$)|(index\.html\$)');
-    return new Future.value(reg.hasMatch(id.path));
-  }
-
-  Future apply(Transform transform) {
-    Asset primaryAsset = transform.primaryInput;
-    AssetId primaryAssetId = primaryAsset.id;
-
-    return primaryAsset.readAsString().then((String fileContents) {
-      var filename = primaryAssetId.toString();
-      var outputFileContents = fileContents;
-
-      if (filename.endsWith('index.html')) {
-        var index = outputFileContents.indexOf(
-            '<script src="packages/browser/dart.js">');
-        outputFileContents = outputFileContents.substring(0, index) +
-            '<script src="packages/browser_controller' +
-            '/perf_test_controller.js"></script>\n' +
-            outputFileContents.substring(index);
-        transform.addOutput(new Asset.fromString(new AssetId.parse(
-            primaryAssetId.toString().replaceAll('.html', '-dart.html')),
-            outputFileContents));
-      }
-
-      outputFileContents = _sourceJsNotDart(outputFileContents);
-      // Rename the script to take the JavaScript source.
-      transform.addOutput(new Asset.fromString(new AssetId.parse(
-          _appendJs(primaryAssetId.toString())),
-          outputFileContents));
-    });
-  }
-
-  String _appendJs(String path) => path.replaceAll('.html', '-js.html');
-
-  /// Given an html file that sources a Dart file, rewrite the html to instead
-  /// source the compiled JavaScript file.
-  String _sourceJsNotDart(String fileContents) {
-    var dartScript = new RegExp(
-        '<script type="application/dart" src="([\\w-]+)\.dart">');
-    var match = dartScript.firstMatch(fileContents);
-    return fileContents.replaceAll(dartScript, '<script type="text/javascript"'
-        ' src="${match.group(1)+ ".dart.js"}" defer>');
-  }
-}
diff --git a/samples/third_party/dromaeo/pubspec.yaml b/samples/third_party/dromaeo/pubspec.yaml
deleted file mode 100644
index 955919d..0000000
--- a/samples/third_party/dromaeo/pubspec.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: dromaeo
-version: 0.00.1-dev
-authors: ["Dart Team <misc@dartlang.org>"]
-homepage: http://www.dartlang.org
-description: >
- Dromaeo test suite, written in Dart.
-dependencies:
-  browser_controller: ">=0.00.1-dev <0.0.2"
-  barback: ">=0.13.0 <0.14.0"
-  browser: ">=0.10.0 <0.10.1"
-environment:
-  sdk: any
-transformers:
-- dromaeo
-- $dart2js:
-    checked: false
-    minify: true #TODO: How do you minify for Dart, too? The docs say you indent two spaces less...
diff --git a/samples/third_party/dromaeo/web/Dromaeo.dart b/samples/third_party/dromaeo/web/Dromaeo.dart
deleted file mode 100644
index bf0e116..0000000
--- a/samples/third_party/dromaeo/web/Dromaeo.dart
+++ /dev/null
@@ -1,243 +0,0 @@
-library dromaeo_test;
-
-import 'dart:html';
-import 'dart:async';
-import "dart:convert";
-import 'dart:math' as Math;
-import 'dart:js' as js;
-import 'Suites.dart';
-
-main() {
-  new Dromaeo().run();
-}
-
-class SuiteController {
-  final SuiteDescription _suiteDescription;
-  final IFrameElement _suiteIframe;
-
-  DivElement _element;
-  double _meanProduct;
-  int _nTests;
-
-  SuiteController(this._suiteDescription, this._suiteIframe)
-      : _meanProduct = 1.0,
-        _nTests = 0 {
-    _make();
-    _init();
-  }
-
-  start() {
-    _suiteIframe.contentWindow.postMessage('start', '*');
-  }
-
-  update(String testName, num mean, num error, double percent) {
-    _meanProduct *= mean;
-    _nTests++;
-
-    final meanAsString = mean.toStringAsFixed(2);
-    final errorAsString = error.toStringAsFixed(2);
-    final Element progressDisplay = _element.nextNode.nextNode;
-    progressDisplay.innerHtml =
-        '${progressDisplay.innerHtml}<li><b>${testName}:</b>'
-        '${meanAsString}<small> runs/s &#177;${errorAsString}%<small></li>';
-    _updateTestPos(percent);
-  }
-
-  _make() {
-    _element = _createDiv('test');
-    // TODO(antonm): add an onclick functionality.
-    _updateTestPos();
-  }
-
-  _updateTestPos([double percent = 1.0]) {
-    String suiteName = _suiteDescription.name;
-    final done = percent >= 100.0;
-    String info = '';
-    if (done) {
-      final parent = _element.parent;
-      parent.attributes['class'] = '${parent.attributes["class"]} done';
-      final mean = Math.pow(_meanProduct, 1.0 / _nTests).toStringAsFixed(2);
-      info = '<span>${mean} runs/s</span>';
-    }
-    _element.innerHtml =
-        '<b>${suiteName}:</b>'
-        '<div class="bar"><div style="width:${percent}%;">${info}</div></div>';
-  }
-
-  _init() {
-    final div = _createDiv('result-item');
-    div.nodes.add(_element);
-    final description = _suiteDescription.description;
-    final originUrl = _suiteDescription.origin.url;
-    final testUrl = '${_suiteDescription.file}';
-    div.innerHtml =
-        '${div.innerHtml}<p>${description}<br/><a href="${originUrl}">Origin</a'
-        '>, <a href="${testUrl}">Source</a>'
-        '<ol class="results"></ol>';
-    // Reread the element, as the previous wrapper get disconnected thanks
-    // to .innerHtml update above.
-    _element = div.nodes[0];
-
-    document.querySelector('#main').nodes.add(div);
-  }
-
-  DivElement _createDiv(String clazz) {
-    final div = new DivElement();
-    div.attributes['class'] = clazz;
-    return div;
-  }
-}
-
-class Dromaeo {
-  final List<SuiteController> _suiteControllers;
-  Function _handler;
-
-  Dromaeo()
-      : _suiteControllers = new List<SuiteController>()
-  {
-    _handler = _createHandler();
-    window.onMessage.listen(
-        (MessageEvent event) {
-          try {
-            final response = JSON.decode(event.data);
-            _handler = _handler(response['command'], response['data']);
-          } catch (e, stacktrace) {
-            if (!(e is FormatException &&
-                (event.data.toString().startsWith('unittest') ||
-                event.data.toString().startsWith('dart')))) {
-              // Hack because unittest also uses post messages to communicate.
-              // So the fact that the event.data is not proper json is not
-              // always an error.
-              print('Exception: ${e}: ${stacktrace}');
-              print(event.data);
-            }
-          }
-        });
-  }
-
-  run() {
-    // TODO(vsm): Initial page should not run.  For now, run all
-    // tests by default.
-    var tags = window.location.search;
-    if (tags.length > 1) {
-      tags = tags.substring(1);
-    } else if (window.navigator.userAgent.contains('(Dart)')) {
-      // TODO(vsm): Update when we change Dart VM detection.
-      tags = 'js|dart&html';
-    } else {
-      tags = 'js|dart2js&html';
-    }
-
-    // TODO(antonm): create Re-run tests href.
-    final Element suiteNameElement = _byId('overview').nodes[0];
-    final category = Suites.getCategory(tags);
-    if (category != null) {
-      suiteNameElement.innerHtml = category;
-    }
-    _css(_byId('tests'), 'display', 'none');
-    for (SuiteDescription suite in Suites.getSuites(tags)) {
-      final iframe = new IFrameElement();
-      _css(iframe, 'height', '1px');
-      _css(iframe, 'width', '1px');
-      iframe.src = '${suite.file}';
-      document.body.nodes.add(iframe);
-
-      _suiteControllers.add(new SuiteController(suite, iframe));
-    }
-  }
-
-  static const double _SECS_PER_TEST = 5.0;
-
-  Function _createHandler() {
-    int suitesLoaded = 0;
-    int totalTests = 0;
-    int currentSuite;
-    double totalTimeSecs, estimatedTimeSecs;
-
-    // TODO(jat): Remove void type below. Bug 5269037.
-    void _updateTime() {
-      final mins = (estimatedTimeSecs / 60).floor();
-      final secs = (estimatedTimeSecs - mins * 60).round();
-      final secsAsString = '${(secs < 10 ? "0" : "")}$secs';
-      _byId('left').innerHtml = '${mins}:${secsAsString}';
-
-      final elapsed = totalTimeSecs - estimatedTimeSecs;
-      final percent = (100 * elapsed / totalTimeSecs).toStringAsFixed(2);
-      _css(_byId('timebar'), 'width', '${percent}%');
-    }
-
-    Function loading, running, done;
-
-    loading = (String command, var data) {
-      assert(command == 'inited');
-      suitesLoaded++;
-      totalTests += data['nTests'];
-      if (suitesLoaded == _suitesTotal) {
-        totalTimeSecs = estimatedTimeSecs = _SECS_PER_TEST * totalTests;
-        _updateTime();
-        currentSuite = 0;
-        _suiteControllers[currentSuite].start();
-        return running;
-      }
-
-      return loading;
-    };
-
-    running = (String command, var data) {
-      switch (command) {
-        case 'result':
-          final testName = data['testName'];
-          final mean = data['mean'];
-          final error = data['error'];
-          final percent = data['percent'];
-          _suiteControllers[currentSuite].update(testName, mean, error, percent);
-          estimatedTimeSecs -= _SECS_PER_TEST;
-          _updateTime();
-          return running;
-
-        case 'over':
-          currentSuite++;
-          if (currentSuite < _suitesTotal) {
-            _suiteControllers[currentSuite].start();
-            return running;
-          }
-          document.body.attributes['class'] = 'alldone';
-
-          var report = js.context['reportPerformanceTestDone'];
-          if (report != null) {
-            report.apply([]);
-          } else {
-            // This is not running as a performance test. Continue as normal.
-            window.console.log('Warning: failed to call '
-                'reportPerformanceTestDone. If this is a performance test, '
-                'please include '
-                'packages/browser_controller/perf_test_controller.js in your '
-                'html file.');
-          }
-          return done;
-
-        default:
-          throw 'Unknown command ${command} [${data}]';
-      }
-    };
-
-    done = (String command, var data) {
-    };
-
-    return loading;
-  }
-
-  _css(Element element, String property, String value) {
-    // TODO(antonm): remove the last argument when CallWithDefaultValue
-    // is implemented.
-    element.style.setProperty(property, value, '');
-  }
-
-  Element _byId(String id) {
-    return document.querySelector('#$id');
-  }
-
-  int get _suitesTotal {
-    return _suiteControllers.length;
-  }
-}
diff --git a/samples/third_party/dromaeo/web/LICENSE b/samples/third_party/dromaeo/web/LICENSE
deleted file mode 100644
index 335edf6..0000000
--- a/samples/third_party/dromaeo/web/LICENSE
+++ /dev/null
@@ -1,30 +0,0 @@
-Dromaeo Test Suite
-Copyright (c) 2008 John Resig
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-----
-
-All tests are the copyright of their respective owners.
- - Tests coming from the Computer Language Shootout are under the Revised BSD license
-    <http://shootout.alioth.debian.org/license.php>.
- - Tests coming from John Resig are under an MIT license.
diff --git a/samples/third_party/dromaeo/web/README b/samples/third_party/dromaeo/web/README
deleted file mode 100644
index 4c6f0aa..0000000
--- a/samples/third_party/dromaeo/web/README
+++ /dev/null
@@ -1,57 +0,0 @@
-This is a port of the Dromaeo benchmark (http://dromaeo.com/) to Dart.
-See the attached LICENSE file in this directory.
-
-To run the native Dart versions on Dartium: 
-
-(1) Use a Dartium chrome binary to open index.html in this directory.
-By default, this will run JS vs a native Dart version (dart:html)
-designed to match the JS for speed.
-
-To run compiled versions on standard browsers:
-
-(1) Execute python ./generate_dart2js_tests.py to create frog
-and dart2js variants.
-
-(2) Use a standard browser to open index-js.html in this directory.
-By default, this will run JS vs a dart2js compiled Dart version
-(dart2js:html) designed to match the JS for speed.
-
--------------------------------------------------------
-
-Note, you can run more variants and at a finer granularity.  Dart
-Dromaeo includes the following modes:
-
-- js : The original JS.
-- dart : Dart, running natively (Dartium only).
-- frog : Dart, compiled to JS with Frog.
-- dart2js : Dart, compiled to JS with dart2js.
-
-It also includes the following versions for Dart modes:
-
-- dom : The old deprecated dart:dom.
-- html : The new dart:html, using fast path APIs to match JS.
-
-Finally, Dart Dromaeo runs the following suites of benchmarks:
-- attributes : Setting and getting DOM node attributes.
-- modify : Creating and injecting DOM nodes into a document.
-- query : Querying DOM elements in a document.
-- traverse : Traversing a DOM structure.
-
-You can specify a disjunction of conjunctions from the three buckets
-above.  Examples:
-
-To run the attributes suite on JS, Dartium, and Dart2JS, load:
-
-- index.html?js&attributes|dart&attributes&html|dart2js&attributes&html
-
-To run the query suite with Dart2JS, load:
-
-- index-js.html?dart&query&html
-
-To run all tests in Dartium, load:
-
-- index.html?js|dart|frog|dart2js
-
-To run all tests (except the native Dart) in a regular browser, load:
-
-- index-js.html?js|frog|dart2js
diff --git a/samples/third_party/dromaeo/web/Suites.dart b/samples/third_party/dromaeo/web/Suites.dart
deleted file mode 100644
index eefe856..0000000
--- a/samples/third_party/dromaeo/web/Suites.dart
+++ /dev/null
@@ -1,174 +0,0 @@
-library Suites;
-
-class Origin {
-  final String author;
-  final String url;
-
-  const Origin(this.author, this.url);
-}
-
-class SuiteDescription {
-  final String file;
-  final String name;
-  final Origin origin;
-  final String description;
-  final List<String> tags;
-  final List testVariants;
-
-  const SuiteDescription(this.file, this.name, this.origin,
-                         this.description, this.tags, this.testVariants);
-}
-
-class Suites {
-  static const JOHN_RESIG = const Origin('John Resig', 'http://ejohn.org/');
-
-  static const CATEGORIES = const {
-    // Platform tags
-    'js': 'DOM Core Tests (JavaScript)',
-    'dart': 'DOM Core Tests (dart)',
-    'dart2js': 'DOM Core Tests (dart2js)',
-
-    // Library tags
-    'html': 'DOM Core Tests (dart:html)',
-  };
-
-  static const _CORE_TEST_OPTIONS = const [
-      // A list of valid combinations for core Dromaeo DOM tests.
-      // Each item in the list is a pair of (platform x [variants]).
-      const ['js', const ['']],
-      const ['dart', const ['html']],
-      const ['dart2js', const ['html']],
-    ];
-
-  static const _CORE_SUITE_DESCRIPTIONS = const [
-      const SuiteDescription(
-          'tests/dom-attr.html',
-          'DOM Attributes',
-          JOHN_RESIG,
-          'Setting and getting DOM node attributes',
-          const ['attributes'],
-          _CORE_TEST_OPTIONS),
-      const SuiteDescription(
-          'tests/dom-modify.html',
-          'DOM Modification',
-          JOHN_RESIG,
-          'Creating and injecting DOM nodes into a document',
-          const ['modify'],
-          _CORE_TEST_OPTIONS),
-      const SuiteDescription(
-          'tests/dom-query.html',
-          'DOM Query',
-          JOHN_RESIG,
-          'Querying DOM elements in a document',
-          const ['query'],
-          _CORE_TEST_OPTIONS),
-      const SuiteDescription(
-          'tests/dom-traverse.html',
-          'DOM Traversal',
-          JOHN_RESIG,
-          'Traversing a DOM structure',
-          const ['traverse'],
-          _CORE_TEST_OPTIONS),
-      const SuiteDescription(
-          '/root_dart/tests/html/dromaeo_smoke.html',
-          'Smoke test',
-          const Origin('', ''),
-          'Dromaeo no-op smoke test',
-          const ['nothing'],
-          _CORE_TEST_OPTIONS),
-  ];
-
-  // Mappings from original path to actual path given platform/library.
-  static _getHtmlPathForVariant(platform, lib, path) {
-    if (lib != '') {
-      lib = '-$lib';
-    }
-    switch (platform) {
-      case 'js':
-      case 'dart':
-        return path.replaceFirst('.html', '$lib.html');
-      case 'dart2js':
-        int i = path.indexOf('/');
-        String topLevelDir = '';
-        if (i != -1) topLevelDir = '${path.substring(0, i)}';
-        return '$topLevelDir/'
-            '${path.substring(i + 1).replaceFirst(".html", "$lib-js.html")}';
-    }
-  }
-
-  static var _SUITE_DESCRIPTIONS;
-
-  static List<SuiteDescription> get SUITE_DESCRIPTIONS {
-    if (_SUITE_DESCRIPTIONS != null) {
-      return _SUITE_DESCRIPTIONS;
-    }
-    _SUITE_DESCRIPTIONS = <SuiteDescription>[];
-
-    // Expand the list to include a unique SuiteDescription for each
-    // tested variant.
-    for (SuiteDescription suite in _CORE_SUITE_DESCRIPTIONS) {
-      List variants = suite.testVariants;
-      for (List variant in variants) {
-        assert(variant.length == 2);
-        String platform = variant[0];
-        List<String> libraries = variant[1];
-        for(String lib in libraries) {
-          String path = _getHtmlPathForVariant(platform, lib, suite.file);
-          final combined = new List.from(suite.tags);
-          combined.add(platform);
-          if (lib != '') {
-            combined.add(lib);
-            lib = ':$lib';
-          }
-          final name = (variant == null)
-              ? suite.name
-              : '${suite.name} ($platform$lib)';
-          _SUITE_DESCRIPTIONS.add(new SuiteDescription(
-                                      path,
-                                      name,
-                                      suite.origin,
-                                      suite.description,
-                                      combined,
-                                      []));
-        }
-      }
-    }
-
-    return _SUITE_DESCRIPTIONS;
-  }
-
-  static List<SuiteDescription> getSuites(String tags) {
-    // Allow AND and OR in place of '&' and '|' for browsers where
-    // those symbols are escaped.
-    tags = tags.replaceAll('OR', '|').replaceAll('AND', '&');
-    // A disjunction of conjunctions (e.g.,
-    // 'js&modify|dart&dom&modify').
-    final taglist = tags.split('|').map((tag) => tag.split('&')).toList();
-
-    bool match(suite) {
-      // If any conjunction matches, return true.
-      for (final tagset in taglist) {
-        if (tagset.every((tag) => suite.tags.indexOf(tag) >= 0)) {
-          return true;
-        }
-      }
-      return false;
-    }
-    final suites = SUITE_DESCRIPTIONS.where(match).toList();
-
-    suites.sort((s1, s2) => s1.name.compareTo(s2.name));
-    return suites;
-  }
-
-  static getCategory(String tags) {
-    if (CATEGORIES.containsKey(tags)) {
-      return CATEGORIES[tags];
-    }
-    for (final suite in _CORE_SUITE_DESCRIPTIONS) {
-      if (suite.tags[0] == tags) {
-        return suite.name;
-      }
-    }
-    return null;
-  }
-}
diff --git a/samples/third_party/dromaeo/web/application.css b/samples/third_party/dromaeo/web/application.css
deleted file mode 100644
index e540dd2..0000000
--- a/samples/third_party/dromaeo/web/application.css
+++ /dev/null
@@ -1,115 +0,0 @@
-ol.results { text-align: left; display: none; font-size: 10px; list-style: none; display: none; }
-.alldone ol.results { display: block; width: 48%; float: left; }
-ol.results li { clear: both; overflow: auto; }
-ol.results b { display: block; width: 200px; float: left; text-align: right; padding-right: 15px; }
-#info { clear:both;width:420px;margin:0 auto;text-align:left; padding: 10px; }
-div.results { width:420px;margin:0 auto;margin-bottom:20px;text-align:left; padding: 10px 10px 10px 10px; }
-#info span { font-weight: bold; padding-top: 8px; }
-h1 { text-align: left; }
-h1 img { float:left;margin-right: 15px;margin-top: -10px; border: 0; }
-h1 small { font-weight:normal; }
-iframe { display: none; }
-div.resultwrap { text-align: center; }
-table.results { font-size: 12px; margin: 0 auto; }
-table.results td, table.results th.name, table.results th { text-align: right; }
-table.results .winner { color: #000; background-color: #c7331d; }
-table.results .tie { color: #000; background-color: #f9f2a1; }
-
-body  {
-	font: normal 11px "Lucida Grande", Helvetica, Arial, sans-serif;
-	background: black url(images/bg.png) repeat-x;
-	margin: 0px auto;
-	padding: 0px; 
-	color: #eee; 
-	text-align: center;
-	line-height: 180%;
-}	
-div, img, form, ul {
-	margin: 0px; 
-	padding: 0px;
-	border: 0px; 
-}
-small			{font-size: 9px;}
-div, span, td, .text_l {text-align: left;}	
-.clear 			{clear: both;}	
-.text_r 		{text-align: right;}
-.text_c 		{text-align: center;}
-a 				{font: normal  "Arial", sans-serif; color: #f9f2a1; }
-.left 			{float: left;}
-.right 			{float: right;}
-
-#wrapper 		{width: 690px; margin: 0px auto; padding: 0px; margin-top: -7px; text-align: center;}
-#content		{margin-bottom: 30px;}
-#main			{padding-bottom: 40px;}
-
-#top			{background: url(images/top.png) repeat-x; height: 250px;}
-#logo			{position: absolute; top: 0; left: 0; width: 100%; text-align: center; z-index: 100;}
-#logo img		{ margin: 0px auto; padding: 0px;}
-.dino1			{position: absolute; top: 105px; right: 300px; z-index: 15;}
-.dino2			{position: absolute; top: 110px; left: 15%;  z-index: 12;}
-.dino3			{position: absolute; top: 120px; left: 400px;  z-index: 31;}
-.dino4			{position: absolute; top: 96px; left: 200px;  z-index: 8;}
-.dino5			{position: absolute; top: 110px; right: 85px;  z-index: 14;}
-.dino6			{position: absolute; top: 105px; left: 30%;  z-index: 14;}
-.dino7			{position: absolute; top: 110px; left: 70%;  z-index: 22;}
-.dino8			{position: absolute; top: 105px; left: 37%;  z-index: 20;}
-.coment			{position: absolute; top: 0px; right: 0px;  z-index: 2; float: right;}
-
-.clouds			{position: absolute; top: 10px; right: 11%;  z-index: 12;}
-.clouds2		{position: absolute; top: 50px; right: 29%;  z-index: 13;}
-.clouds5		{position: absolute; top: 0px; right: 15%;  z-index: 16;}
-.clouds3			{position: absolute; top: 15px; left: 10%;  z-index: 15;}
-.clouds4		{position: absolute; top: 10px; left: 15%;  z-index: 14;}
-
-.water		{position: absolute; top: 110px; right: 9%;  z-index: 13;}
-
-
-/* rendered html stuff */
-
-table.results	{text-align: center; margin: 0px auto; padding: 0px; background: none;}
-table.results td, table.results th 			{padding: 2px;}
-table.results tr.onetest td, table.results tr.onetest th 			{padding: 0px;}
-table.results tr.hidden { display: none; }
-#info			{margin-bottom: 10px;}
-table.results .winner			{background: #58bd79;}
-.name			{font-weight: bold;}
-
-div.resultwrap	{margin: 10px 0 10px 0;}
-div.results		{padding: 10px; margin-bottom: 20px; background: #c7331d;}
-
-div.result-item { position: relative; width: 48%; float: left; overflow: hidden; margin-left: 1%; margin-right: 1%; height: 100px; }
-.alldone div.result-item { width: 98%; height: auto; margin-bottom: 10px; overflow: auto; }
-.alldone div.result-item p { width: 48%; float: left; }
-
-div.result-item p { padding: 0px 4px; }
-
-div.test { overflow: hidden; margin: 4px 0; }
-div.test b { display: block; width: 100%; text-align: left; margin: 0px; background: #c7331d; padding: 4px; }
-/*div.done div.test b {background: #58bd79;}*/
-div.done div.test b {background: #222;}
-div.bar { width: 100px; border: 1px inset #666; background: #c7331d; text-align: left; position: absolute; top: 7px; right: 4px; }
-div.bar div { height: 20px; background: #222; text-align: right; }
-div.done div.bar div {background: #58bd79; color: #000;}
-div.bar span { padding-left: 5px; padding-right: 5px; }
-
-#info { margin: auto; }
-
-h1 { font-size: 28px; border-bottom: 1px solid #AAA; position: relative; padding: 0px 1% 2px 1%;}
-h1 div.bar { font-size: 10px; width: 275px; top: -2px; right: 1%; }
-h1 input { position: absolute; top: 0px; right: 300px; }
-
-h2 { font-size: 20px; border-bottom: 1px solid #AAA; position: relative; padding: 0px 1% 2px 1%;}
-h2 a { color: #FFF; }
-h2 div.bar { font-size: 10px; width: 275px; top: -2px; right: 1%; }
-h2 input { position: absolute; top: 0px; right: 300px; }
-
-ul#tests { clear:both;width:420px;margin:0 auto;text-align:left; padding: 10px; list-style: none; }
-#tests b { background: #c7331d; color: #000; display: block; padding: 4px 0 4px 4px; margin-left: -20px; margin-bottom: 5px; font-size: 1.1em; -webkit-border-radius: 4px; -moz-border-radius: 4px; font-weight: normal; }
-#tests b.recommended { background: #58bd79; }
-#tests a:first-of-type { font-size: 1.2em; }
-#tests b a { font-weight: bold; color: #000; }
-#tests li { padding-left: 10px; padding-bottom: 5px; }
-
-#overview { position: relative; }
-#overview a { font-size: 10px; top: -29px; left: 8px; position: absolute; }
-#overview table a { position: static; }
diff --git a/samples/third_party/dromaeo/web/common/BenchUtil.dart b/samples/third_party/dromaeo/web/common/BenchUtil.dart
deleted file mode 100644
index 5a4b9c7..0000000
--- a/samples/third_party/dromaeo/web/common/BenchUtil.dart
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of common;
-
-// Misc benchmark-related utility functions.
-
-class BenchUtil {
-  static int get now {
-    return new DateTime.now().millisecondsSinceEpoch;
-  }
-
-  static Map<String, Object> deserialize(String data) {
-    return JSON.decode(data);
-  }
-
-  static String serialize(Object obj) {
-    return JSON.encode(obj);
-  }
-
-  // Shuffle a list randomly.
-  static void shuffle(List<Object> list) {
-    int len = list.length - 1;
-    for (int i = 0; i < len; i++) {
-      int index = (Math.random() * (len - i)).toInt() + i;
-      Object tmp = list[i];
-      list[i] = list[index];
-      list[index] = tmp;
-    }
-  }
-
-  static String formatGolemData(String prefix, Map<String, num> results) {
-    List<String> elements = new List<String>();
-    results.forEach((String name, num score) {
-      elements.add('"${prefix}/${name}":${score}');
-    });
-    return serialize(elements);
-  }
-
-  static bool _inRange(int charCode, String start, String end) {
-    return start.codeUnitAt(0) <= charCode && charCode <= end.codeUnitAt(0);
-  }
-
-  static const String DIGITS = '0123456789ABCDEF';
-  static String _asDigit(int value) {
-    return DIGITS[value];
-  }
-
-  static String encodeUri(final String s) {
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < s.length; i++) {
-      final int charCode = s.codeUnitAt(i);
-      final bool noEscape =
-          _inRange(charCode, '0', '9') ||
-          _inRange(charCode, 'a', 'z') ||
-          _inRange(charCode, 'A', 'Z');
-      if (noEscape) {
-        sb.write(s[i]);
-      } else {
-       sb.write('%');
-       sb.write(_asDigit((charCode >> 4) & 0xF));
-       sb.write(_asDigit(charCode & 0xF));
-      }
-    }
-    return sb.toString();
-  }
-
-  // TODO: use corelib implementation.
-  static String replaceAll(String s, String pattern,
-                           String replacement(Match match)) {
-    StringBuffer sb = new StringBuffer();
-
-    int pos = 0;
-    for (Match match in new RegExp(pattern).allMatches(s)) {
-      sb.write(s.substring(pos, match.start));
-      sb.write(replacement(match));
-      pos = match.end;
-    }
-    sb.write(s.substring(pos));
-
-    return sb.toString();
-  }
-}
diff --git a/samples/third_party/dromaeo/web/common/Interval.dart b/samples/third_party/dromaeo/web/common/Interval.dart
deleted file mode 100644
index 50d2d84..0000000
--- a/samples/third_party/dromaeo/web/common/Interval.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of common;
-
-// A utility object for measuring time intervals.
-
-class Interval {
-  int _start, _stop;
-
-  Interval() {
-  }
-
-  void start() {
-    _start = BenchUtil.now;
-  }
-
-  void stop() {
-    _stop = BenchUtil.now;
-  }
-
-  // Microseconds from between start() and stop().
-  int get elapsedMicrosec {
-    return (_stop - _start) * 1000;
-  }
-
-  // Milliseconds from between start() and stop().
-  int get elapsedMillisec {
-    return (_stop - _start);
-  }
-}
diff --git a/samples/third_party/dromaeo/web/common/Math2.dart b/samples/third_party/dromaeo/web/common/Math2.dart
deleted file mode 100644
index 20f08fa..0000000
--- a/samples/third_party/dromaeo/web/common/Math2.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of common;
-
-// Various math-related utility functions.
-
-class Math2 {
-  /// Computes the geometric mean of a set of numbers.
-  /// [minNumber] is optional (defaults to 0.001) anything smaller than this
-  /// will be changed to this value, eliminating infinite results.
-  static double geometricMean(List<double> numbers,
-                              [double minNumber = 0.001]) {
-    double log = 0.0;
-    int nNumbers = 0;
-    for (int i = 0, n = numbers.length; i < n; i++) {
-      double number = numbers[i];
-      if (number < minNumber) {
-        number = minNumber;
-      }
-      nNumbers++;
-      log += Math.log(number);
-    }
-
-    return nNumbers > 0 ? Math.pow(Math.E, log / nNumbers) : 0.0;
-  }
-
-  static int round(double d) {
-    return d.round();
-  }
-
-  static int floor(double d) {
-    return d.floor();
-  }
-
-  // TODO (olonho): use d.toStringAsFixed(precision) when implemented by DartVM
-  static String toStringAsFixed(num d, int precision) {
-    String dStr = d.toString();
-    int pos = dStr.indexOf('.', 0);
-    int end = pos < 0 ? dStr.length : pos + precision;
-    if (precision > 0) {
-      end++;
-    }
-    if (end > dStr.length) {
-      end = dStr.length;
-    }
-
-    return dStr.substring(0, end);
-  }
-}
diff --git a/samples/third_party/dromaeo/web/common/common.dart b/samples/third_party/dromaeo/web/common/common.dart
deleted file mode 100644
index 5a33126..0000000
--- a/samples/third_party/dromaeo/web/common/common.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library common;
-import 'dart:math' as Math;
-import "dart:convert";
-part 'BenchUtil.dart';
-part 'Interval.dart';
-part 'Math2.dart';
diff --git a/samples/third_party/dromaeo/web/favicon.ico b/samples/third_party/dromaeo/web/favicon.ico
deleted file mode 100644
index d444389..0000000
--- a/samples/third_party/dromaeo/web/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/favicon.png b/samples/third_party/dromaeo/web/favicon.png
deleted file mode 100644
index d772102..0000000
--- a/samples/third_party/dromaeo/web/favicon.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/htmlrunner.js b/samples/third_party/dromaeo/web/htmlrunner.js
deleted file mode 100644
index 8f565c4..0000000
--- a/samples/third_party/dromaeo/web/htmlrunner.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// An version of Dromaeo's original htmlrunner adapted for the
-// Dart-based test driver.
-
-var _operations = [];
-var _N_RUNS = 5;
-var _nRanTests = 0;
-var _nTests = 0;
-var _T_DISTRIBUTION = 2.776;
-
-function startTest() {
-  window.addEventListener(
-      'message',
-      function (event) {
-        if (event.data == 'start') {
-          _run();
-        } else {
-          window.alert('Unknown command: ' + event.data);
-        }
-      },
-      false);
-}
-
-function _run() {
-  var currentOperation = 0;
-  function handler() {
-    if (currentOperation < _operations.length) {
-      _operations[currentOperation]();
-      currentOperation++;
-      window.setTimeout(handler, 1);
-    } else {
-      _postMessage('over');
-    }
-  }
-  window.setTimeout(handler, 0);
-}
-
-function _postMessage(command, data) {
-  var payload = { 'command': command };
-  if (data) {
-    payload['data'] = data;
-  }
-  window.parent.postMessage(JSON.stringify(payload), '*');
-}
-
-function test(name, fn) {
-  _nTests++;
-  _operations.push(function () {
-      // List of number of runs in seconds.
-      var runsPerSecond = [];
-      // Run the test several times.
-      try {
-        // TODO(antonm): use .setTimeout to schedule next run as JS
-        // version does.  That allows to report the intermediate results
-        // more smoothly as well.
-        for (var i = 0; i < _N_RUNS; i++) {
-          var runs = 0;
-          var start = Date.now();
-
-          var cur = Date.now();
-          while ((cur - start) < 1000) {
-            fn();
-            cur = Date.now();
-            runs++;
-          }
-
-          runsPerSecond.push((runs * 1000.0) / (cur - start));
-        }
-      } catch(e) {
-        window.alert('Exception : ' + e);
-        return;
-      }
-      _reportTestResults(name, runsPerSecond);
-    });
-}
-
-// Adapted from Dromaeo's webrunner.
-function _compute(times){
-  var results = {runs: times.length}, num = times.length;
-
-  times = times.sort(function(a,b){
-      return a - b;
-    });
-
-  // Make Sum
-  results.sum = 0;
-
-  for ( var i = 0; i < num; i++ )
-    results.sum += times[i];
-
-  // Make Min
-  results.min = times[0];
-
-  // Make Max
-  results.max = times[ num - 1 ];
-
-  // Make Mean
-  results.mean = results.sum / num;
-
-  // Make Median
-  results.median = num % 2 == 0 ?
-      (times[Math.floor(num/2)] + times[Math.ceil(num/2)]) / 2 :
-      times[Math.round(num/2)];
-
-  // Make Variance
-  results.variance = 0;
-
-  for ( var i = 0; i < num; i++ )
-    results.variance += Math.pow(times[i] - results.mean, 2);
-
-  results.variance /= num - 1;
-
-  // Make Standard Deviation
-  results.deviation = Math.sqrt( results.variance );
-
-  // Compute Standard Errors Mean
-  results.sem = (results.deviation / Math.sqrt(results.runs)) * _T_DISTRIBUTION;
-
-  // Error
-  results.error = ((results.sem / results.mean) * 100) || 0;
-
-  return results;
-}
-
-function _reportTestResults(name, times) {
-  _nRanTests++;
-  var results = _compute(times);
-
-  _postMessage('result', {
-      'testName': name,
-      'mean': results.mean,
-      'error': results.error,
-      'percent': (100.0 * _nRanTests / _nTests)
-          });
-}
-
-function endTest() {
-  _postMessage('inited', { 'nTests': _nTests });
-}
-
-function prep(fn) {
-  _operations.push(fn);
-}
diff --git a/samples/third_party/dromaeo/web/images/bg.png b/samples/third_party/dromaeo/web/images/bg.png
deleted file mode 100644
index bd659a8..0000000
--- a/samples/third_party/dromaeo/web/images/bg.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/clouds.png b/samples/third_party/dromaeo/web/images/clouds.png
deleted file mode 100644
index c9f7dc2..0000000
--- a/samples/third_party/dromaeo/web/images/clouds.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/clouds2.png b/samples/third_party/dromaeo/web/images/clouds2.png
deleted file mode 100644
index ac835dc..0000000
--- a/samples/third_party/dromaeo/web/images/clouds2.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/comets.png b/samples/third_party/dromaeo/web/images/comets.png
deleted file mode 100644
index 37dd962..0000000
--- a/samples/third_party/dromaeo/web/images/comets.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino1.png b/samples/third_party/dromaeo/web/images/dino1.png
deleted file mode 100644
index 2dda272..0000000
--- a/samples/third_party/dromaeo/web/images/dino1.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino2.png b/samples/third_party/dromaeo/web/images/dino2.png
deleted file mode 100644
index ccfa15c..0000000
--- a/samples/third_party/dromaeo/web/images/dino2.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino3.png b/samples/third_party/dromaeo/web/images/dino3.png
deleted file mode 100644
index a766b28..0000000
--- a/samples/third_party/dromaeo/web/images/dino3.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino4.png b/samples/third_party/dromaeo/web/images/dino4.png
deleted file mode 100644
index 03301d3..0000000
--- a/samples/third_party/dromaeo/web/images/dino4.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino5.png b/samples/third_party/dromaeo/web/images/dino5.png
deleted file mode 100644
index 5fd028d..0000000
--- a/samples/third_party/dromaeo/web/images/dino5.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino6.png b/samples/third_party/dromaeo/web/images/dino6.png
deleted file mode 100644
index ded8106..0000000
--- a/samples/third_party/dromaeo/web/images/dino6.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino7.png b/samples/third_party/dromaeo/web/images/dino7.png
deleted file mode 100644
index ac2021b..0000000
--- a/samples/third_party/dromaeo/web/images/dino7.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/dino8.png b/samples/third_party/dromaeo/web/images/dino8.png
deleted file mode 100644
index a4b1fe4..0000000
--- a/samples/third_party/dromaeo/web/images/dino8.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/left.png b/samples/third_party/dromaeo/web/images/left.png
deleted file mode 100644
index b688f2b..0000000
--- a/samples/third_party/dromaeo/web/images/left.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/logo.png b/samples/third_party/dromaeo/web/images/logo.png
deleted file mode 100644
index 199fda7..0000000
--- a/samples/third_party/dromaeo/web/images/logo.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/logo2.png b/samples/third_party/dromaeo/web/images/logo2.png
deleted file mode 100644
index 427687f..0000000
--- a/samples/third_party/dromaeo/web/images/logo2.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/logo3.png b/samples/third_party/dromaeo/web/images/logo3.png
deleted file mode 100644
index 306c485..0000000
--- a/samples/third_party/dromaeo/web/images/logo3.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/right.png b/samples/third_party/dromaeo/web/images/right.png
deleted file mode 100644
index 154cb41..0000000
--- a/samples/third_party/dromaeo/web/images/right.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/top.png b/samples/third_party/dromaeo/web/images/top.png
deleted file mode 100644
index 24039c3..0000000
--- a/samples/third_party/dromaeo/web/images/top.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/images/water.png b/samples/third_party/dromaeo/web/images/water.png
deleted file mode 100644
index 40a0f0d..0000000
--- a/samples/third_party/dromaeo/web/images/water.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/dromaeo/web/index.html b/samples/third_party/dromaeo/web/index.html
deleted file mode 100644
index f03b22f..0000000
--- a/samples/third_party/dromaeo/web/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-  <meta http-equiv="Content-Type" content="text/html; utf-8" />
-  <title>Dromaeo: JavaScript Performance Testing</title>
-  <link href="reset.css" rel="stylesheet" type="text/css" />
-  <link href="application.css" rel="stylesheet" type="text/css" />
-  <script type="application/dart" src="Dromaeo.dart"></script>
-  <script src="packages/browser/dart.js"></script>
-</head>
-<body>
-        <div id="top" >
-          <div id="logo">
-            <a href="./"><img src="images/logo3.png" class="png"/></a>
-          </div>
-          <img src="images/dino1.png" class="dino1 png"/>
-          <img src="images/left.png" class="left png"/>
-          <img src="images/dino2.png" class="dino2 png"/>
-          <img src="images/dino2.png" class="dino2 png"/>
-          <img src="images/dino3.png" class="dino3 png"/>
-          <img src="images/dino4.png" class="dino4 png"/>
-          <img src="images/dino5.png" class="dino5 png"/>
-          <img src="images/dino7.png" class="dino7 png"/>
-          <img src="images/dino8.png" class="dino8 png"/>
-          <img src="images/dino6.png" class="dino6 png"/>
-          <img src="images/clouds2.png" class="clouds2 png"/>
-          <img src="images/clouds.png" class="clouds png"/>
-          <img src="images/clouds2.png" class="clouds3 png"/>
-          <img src="images/clouds.png" class="clouds4 png"/>
-          <img src="images/clouds2.png" class="clouds5 png"/>
-          <img src="images/comets.png" class="right png"/>
-        </div>
-        <div id="wrapper">
-        <div id="main">
-<div id="info"><span>Mozilla JavaScript performance test suite.</span><br/>More information about <a href="http://wiki.mozilla.org/Dromaeo">Dromaeo</a> can be found on the Mozilla wiki.</div>
-<h1 id="overview" class="test"><span>Performance Tests</span> <input type="button" id="pause" class="pause" value="Loading..."/><div class="bar"><div id="timebar" style="width:25%;"><span class="left">Est.&nbsp;Time:&nbsp;<strong id="left">0:00</strong></span></div></div><a href="./">&laquo; View All Tests</a></h1><br style="clear:both;"/>
-<ul id="tests">
-  <li><a href="?dom">DOM Core Tests</a><br/>(Tests DOM Querying, Traversing, Manipulation, and Attributes.)</li>
-</ul>
-</div>
-</div>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/reset.css b/samples/third_party/dromaeo/web/reset.css
deleted file mode 100644
index 4a3cf94..0000000
--- a/samples/third_party/dromaeo/web/reset.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -------------------------------------------------------------- 
-  
-   reset.css
-   * Resets default browser CSS.
-   
-   Based on work by Eric Meyer:
-   * meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
-   
--------------------------------------------------------------- */
-
-html, body, div, span, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, code,
-del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	font-weight: inherit;
-	font-style: inherit;
-	font-size: 100%;
-	font-family: inherit;
-	vertical-align: baseline;
-}
-
-
-body { line-height: 1.5; background: #fff; margin:1.5em 0; }
-
-/* Tables still need 'cellspacing="0"' in the markup. */
-caption, th, td { text-align: left; font-weight:400; }
-
-/* Remove possible quote marks (") from <q>, <blockquote>. */
-blockquote:before, blockquote:after, q:before, q:after { content: ""; }
-blockquote, q { quotes: "" ""; }
-
-a img { border: none; }
-
diff --git a/samples/third_party/dromaeo/web/test-head.html b/samples/third_party/dromaeo/web/test-head.html
deleted file mode 100644
index 481251c..0000000
--- a/samples/third_party/dromaeo/web/test-head.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
diff --git a/samples/third_party/dromaeo/web/test-tail.html b/samples/third_party/dromaeo/web/test-tail.html
deleted file mode 100644
index 1b4431b..0000000
--- a/samples/third_party/dromaeo/web/test-tail.html
+++ /dev/null
@@ -1,4 +0,0 @@
-</script>
-</head>
-<body></body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/Common.dart b/samples/third_party/dromaeo/web/tests/Common.dart
deleted file mode 100644
index f763fb9..0000000
--- a/samples/third_party/dromaeo/web/tests/Common.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-part of dromaeo;
-
-class Result {
-  int get runs { return _sorted.length; }
-
-  double get sum {
-    double result = 0.0;
-    _sorted.forEach((double e) { result += e; });
-    return result;
-  }
-
-  double get min { return _sorted[0]; }
-  double get max { return _sorted[runs - 1]; }
-
-  double get mean { return sum / runs; }
-
-  double get median {
-    return (runs % 2 == 0) ?
-        (_sorted[runs ~/ 2] + _sorted[runs ~/ 2 + 1]) / 2 : _sorted[runs ~/ 2];
-  }
-
-  double get variance {
-    double m = mean;
-    double result = 0.0;
-    _sorted.forEach((double e) { result += Math.pow(e - m, 2.0); });
-    return result / (runs - 1);
-  }
-
-  double get deviation { return Math.sqrt(variance); }
-
-  // Compute Standard Errors Mean
-  double get sem { return (deviation / Math.sqrt(runs)) * T_DISTRIBUTION; }
-
-  double get error { return (sem / mean) * 100; }
-
-  // TODO: Implement writeOn.
-  String toString() {
-    return '[Result: mean = ${mean}]';
-  }
-
-  factory Result(List<double> runsPerSecond) {
-    runsPerSecond.sort((a, b) => a.compareTo(b));
-    return new Result._internal(runsPerSecond);
-  }
-
-  Result._internal(this._sorted) {}
-
-  List<double> _sorted;
-
-  // Populated from: http://www.medcalc.be/manual/t-distribution.php
-  // 95% confidence for N - 1 = 4
-  static const double T_DISTRIBUTION = 2.776;
-}
diff --git a/samples/third_party/dromaeo/web/tests/RunnerSuite.dart b/samples/third_party/dromaeo/web/tests/RunnerSuite.dart
deleted file mode 100644
index e1e0945..0000000
--- a/samples/third_party/dromaeo/web/tests/RunnerSuite.dart
+++ /dev/null
@@ -1,132 +0,0 @@
-part of dromaeo;
-
-typedef void Test();
-typedef void Operation();
-typedef void Reporter(Map<String, Result> results);
-
-class Suite {
-  /**
-   * Ctor.
-   *  [:_window:] The window of the suite.
-   *  [:_name:] The name of the suite.
-   */
-  Suite(this._window, this._name) :
-      _operations = new List<Operation>(),
-      _nTests = 0, _nRanTests = 0 {
-    starter(MessageEvent event) {
-      String command = event.data;
-      switch (command) {
-        case 'start':
-          _run();
-          return;
-        default:
-          _window.alert('[${_name}]: unknown command ${command}');
-      }
-    };
-    _window.onMessage.listen(starter);
-  }
-
-  /**
-   * Adds a preparation step to the suite.
-   * [:operation:] The operation to be performed.
-   */
-  Suite prep(Operation operation){
-    return _addOperation(operation);
-  }
-
-  // How many times each individual test should be ran.
-  static const int _N_RUNS = 5;
-
-  /**
-   * Adds another test to the suite.
-   * [:name:] The unique name of the test
-   * [:test:] A function holding the test to run
-   */
-  Suite test(String name, Test test_) {
-    _nTests++;
-    // Don't execute the test immediately.
-    return _addOperation(() {
-      // List of number of runs in seconds.
-      List<double> runsPerSecond = new List<double>();
-
-      // Run the test several times.
-      try {
-        // TODO(antonm): use timer to schedule next run as JS
-        // version does.  That allows to report the intermidiate results
-        // more smoothly as well.
-        for (int i = 0; i < _N_RUNS; i++) {
-          int runs = 0;
-          final int start = new DateTime.now().millisecondsSinceEpoch;
-
-          int cur = new DateTime.now().millisecondsSinceEpoch;
-          while ((cur - start) < 1000) {
-            test_();
-            cur = new DateTime.now().millisecondsSinceEpoch;
-            runs++;
-          }
-
-          runsPerSecond.add((runs * 1000.0) / (cur - start));
-        }
-      } catch (exception, stacktrace) {
-        _window.alert('Exception ${exception}: ${stacktrace}');
-        return;
-      }
-      _reportTestResults(name, new Result(runsPerSecond));
-    });
-  }
-
-  /**
-   * Finalizes the suite.
-   * It might either run the tests immediately or schedule them to be ran later.
-   */
-  void end() {
-    _postMessage('inited', { 'nTests': _nTests });
-
-  }
-
-  _run() {
-    int currentOperation = 0;
-    handler() {
-      if (currentOperation < _operations.length) {
-        _operations[currentOperation]();
-        currentOperation++;
-        new Timer(const Duration(milliseconds: 1), handler);
-      } else {
-        _postMessage('over');
-      }
-    }
-    Timer.run(handler);
-  }
-
-  _reportTestResults(String name, Result result) {
-    _nRanTests++;
-    _postMessage('result', {
-        'testName': name,
-        'mean': result.mean,
-        'error': result.error,
-        'percent': (100.0 * _nRanTests / _nTests)
-    });
-  }
-
-  _postMessage(String command, [var data = null]) {
-    final payload = { 'command': command };
-    if (data != null) {
-      payload['data'] = data;
-    }
-    _window.parent.postMessage(JSON.encode(payload), '*');
-  }
-
-  // Implementation.
-
-  final Window _window;
-  final String _name;
-
-  List<Operation> _operations;
-  int _nTests;
-  int _nRanTests;
-
-  Suite _addOperation(Operation operation) {
-    _operations.add(operation);
-    return this;
-  }
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-attr-html.dart b/samples/third_party/dromaeo/web/tests/dom-attr-html.dart
deleted file mode 100644
index f1b1031..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-attr-html.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-library dromaeo;
-import 'dart:async';
-import 'dart:html';
-import "dart:convert";
-import 'dart:math' as Math;
-part 'Common.dart';
-part 'RunnerSuite.dart';
-
-void main() {
-  final int num = 10240;
-
-  // Try to force real results.
-  var ret;
-
-  Element elem = document.querySelector('#test1');
-  Element a = document.querySelector('a');
-
-  new Suite(window, 'dom-attr')
-    .test('getAttribute', () {
-      for (int i = 0; i < num; i++)
-        ret = elem.getAttribute('id');
-    })
-    .test('element.property', () {
-      for (int i = 0; i < num * 2; i++)
-        ret = elem.id;
-    })
-    .test('setAttribute', () {
-        for (int i = 0; i < num; i++)
-          a.setAttribute('id', 'foo');
-    })
-    .test('element.property = value', () {
-      for (int i = 0; i < num; i++)
-        a.id = 'foo';
-    })
-    .end();
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-attr-html.html b/samples/third_party/dromaeo/web/tests/dom-attr-html.html
deleted file mode 100644
index 62079e6..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-attr-html.html
+++ /dev/null
@@ -1,2900 +0,0 @@
-<html>
-<head>
-<script type="application/dart" src="dom-attr-html.dart"></script>
-<script src="../../../../pkg/browser/lib/dart.js"></script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test1"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test1"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test1 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-attr.html b/samples/third_party/dromaeo/web/tests/dom-attr.html
deleted file mode 100644
index 29ff125..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-attr.html
+++ /dev/null
@@ -1,2946 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
-window.onload = function(){
-startTest("dom-attr");
-
-// Try to force real results
-var ret, tmp;
-
-var elem = document.getElementById("test1");
-var a = document.getElementsByTagName("a")[0];
-var num = 10240;
-	
-	test( "getAttribute", function(){
-		for ( var i = 0; i < num; i++ )
-			ret = elem.getAttribute("id");
-	});
-
-	test( "element.property", function(){
-		for ( var i = 0; i < num * 2; i++ )
-			ret = elem.id;
-	});
-
-	test( "setAttribute", function(){
-		for ( var i = 0; i < num; i++ )
-			a.setAttribute("id", "foo");
-	});
-
-	test( "element.property = value", function(){
-		for ( var i = 0; i < num; i++ )
-			a.id = "foo";
-	});
-
-        // Removing these two as Dart has no expandos.
-        /*
-	test( "element.expando = value", function(){
-		for ( var i = 0; i < num; i++ )
-			a["test" + num] = function(){};
-	});
-
-	test( "element.expando", function(){
-		for ( var i = 0; i < num; i++ )
-			ret = a["test" + num];
-	});
-        */
-
-endTest();
-};
-</script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test1"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test1"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test1 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-modify-html.dart b/samples/third_party/dromaeo/web/tests/dom-modify-html.dart
deleted file mode 100644
index e9cb8be..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-modify-html.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-library dromaeo;
-import 'dart:async';
-import 'dart:html';
-import "dart:convert";
-import 'dart:math' as Math;
-part 'Common.dart';
-part 'RunnerSuite.dart';
-
-void main() {
-  final int num = 400;
-  var random = new Math.Random();
-
-  String str = 'null';
-  // Very ugly way to build up the string, but let's mimic JS version as much as
-  // possible.
-  for (int i = 0; i < 1024; i++) {
-    str += new String.fromCharCode(((25 * random.nextDouble()) + 97).toInt());
-  }
-
-  List<Node> elems = <Node>[];
-
-  // Try to force real results.
-  var ret;
-
-  final htmlstr = document.body.innerHtml;
-
-  new Suite(window, 'dom-modify')
-    .test('createElement', () {
-      for (int i = 0; i < num; i++) {
-        ret = new Element.tag('div');
-        ret = new Element.tag('span');
-        ret = new Element.tag('table');
-        ret = new Element.tag('tr');
-        ret = new Element.tag('select');
-      }
-    })
-    .test('createTextNode', () {
-      for (int i = 0; i < num; i++) {
-        ret = new Text(str);
-        ret = new Text('${str}2');
-        ret = new Text('${str}3');
-        ret = new Text('${str}4');
-        ret = new Text('${str}5');
-      }
-    })
-    .test('innerHtml', () {
-      document.body.innerHtml = htmlstr;
-    })
-    .prep(() {
-      elems = new List<Node>();
-      final telems = document.body.nodes;
-      for (int i = 0; i < telems.length; i++) {
-        elems.add(telems[i]);
-      }
-    })
-    .test('cloneNode', () {
-      for (int i = 0; i < elems.length; i++) {
-        ret = elems[i].clone(false);
-        ret = elems[i].clone(true);
-        ret = elems[i].clone(true);
-        }
-    })
-    .test('appendChild', () {
-      for (int i = 0; i < elems.length; i++)
-        document.body.append(elems[i]);
-    })
-    .test('insertBefore', () {
-      for (int i = 0; i < elems.length; i++)
-        document.body.insertBefore(elems[i], document.body.firstChild);
-    })
-    .end();
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-modify-html.html b/samples/third_party/dromaeo/web/tests/dom-modify-html.html
deleted file mode 100644
index 4663c13..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-modify-html.html
+++ /dev/null
@@ -1,2900 +0,0 @@
-<html>
-<head>
-<script type="application/dart" src="dom-modify-html.dart"></script>
-<script src="../../../../pkg/browser/lib/dart.js"></script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test1"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test1"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test1 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-modify.html b/samples/third_party/dromaeo/web/tests/dom-modify.html
deleted file mode 100644
index 0229892..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-modify.html
+++ /dev/null
@@ -1,2973 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
-window.onload = function(){
-startTest("dom-modify");
-
-// Try to force real results
-var ret, tmp, str;
-
-var elems = [];
-var htmlstr = document.body.innerHTML;
-var div = document.createElement("div");
-var num = 400;
-
-for ( var i = 0; i < 1024; i++ )
-        str += String.fromCharCode( (25 * Math.random()) + 97 );
-
-	test( "createElement", function(){
-		for ( var i = 0; i < num; i++ ) {
-			ret = document.createElement("div");
-			ret = document.createElement("span");
-			ret = document.createElement("table");
-			ret = document.createElement("tr");
-			ret = document.createElement("select");
-		}
-	});
-
-	test( "createTextNode", function(){
-		for ( var i = 0; i < num; i++ ) {
-			ret = document.createTextNode(str);
-			ret = document.createTextNode(str + "2");
-			ret = document.createTextNode(str + "3");
-			ret = document.createTextNode(str + "4");
-			ret = document.createTextNode(str + "5");
-		}
-	});
-
-	/* Need a better way to test this
-	test( "removeChild", function(){
-		while ( document.body.firstChild )
-			document.body.removeChild( document.body.firstChild );
-	});
-	*/
-
-	test( "innerHtml", function(){
-		document.body.innerHTML = htmlstr;
-	});
-
-	prep(function(){
-		elems = [];
-		var telems = document.body.childNodes;
-		for ( var i = 0; i < telems.length; i++ )
-			elems.push( telems[i] );
-	});
-
-	test( "cloneNode", function(){
-		for ( var i = 0; i < elems.length; i++ ) {
-			ret = elems[i].cloneNode(false);
-			ret = elems[i].cloneNode(true);
-			ret = elems[i].cloneNode(true);
-		}
-	});
-
-	test( "appendChild", function(){
-		for ( var i = 0; i < elems.length; i++ )
-			document.body.appendChild( elems[i] );
-	});
-
-	test( "insertBefore", function(){
-		for ( var i = 0; i < elems.length; i++ )
-			document.body.insertBefore( elems[i], document.body.firstChild );
-	});
-
-endTest();
-};
-</script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test1"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
-
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators.
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment:
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element.
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element.
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML
-paragraph that will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag
-sequence. The other lines will be treated as
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt;
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt;
-S
-&lt;/P::first-letter&gt;ome text that
-&lt;/P::first-line&gt;
-ends up on two lines
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree.
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>:
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test1"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-
-<p>Selectors can be used in STTS 3 in two different
-    manners:
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification.
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test1 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-query-html.dart b/samples/third_party/dromaeo/web/tests/dom-query-html.dart
deleted file mode 100644
index cd58782..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-query-html.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-library dromaeo;
-import 'dart:async';
-import 'dart:html';
-import '../common/common.dart';
-import "dart:convert";
-import 'dart:math' as Math;
-part 'Common.dart';
-part 'RunnerSuite.dart';
-
-void main() {
-  final int num = 40;
-
-  // Try to force real results.
-  var ret;
-
-  String html = document.body.innerHtml;
-
-  new Suite(window, 'dom-query')
-    .prep(() {
-      html = BenchUtil.replaceAll(html, 'id="test(\\w).*?"', (Match match) {
-        final group = match.group(1);
-        return 'id="test${group}${num}"';
-      });
-      html = BenchUtil.replaceAll(html, 'name="test.*?"', (Match match) {
-        return 'name="test${num}"';
-      });
-      html = BenchUtil.replaceAll(html, 'class="foo.*?"', (Match match) {
-        return 'class="foo test${num} bar"';
-      });
-      final div = new Element.tag('div');
-      div.innerHtml = html;
-      document.body.append(div);
-    })
-    .test('getElementById', () {
-      for (int i = 0; i < num * 30; i++) {
-        ret = document.getElementById('testA$num').nodeType;
-        ret = document.getElementById('testB$num').nodeType;
-        ret = document.getElementById('testC$num').nodeType;
-        ret = document.getElementById('testD$num').nodeType;
-        ret = document.getElementById('testE$num').nodeType;
-        ret = document.getElementById('testF$num').nodeType;
-      }
-    })
-    .test('getElementById (not in document)', () {
-      for (int i = 0; i < num * 30; i++) {
-        ret = document.getElementById('testA');
-        ret = document.getElementById('testB');
-        ret = document.getElementById('testC');
-        ret = document.getElementById('testD');
-        ret = document.getElementById('testE');
-        ret = document.getElementById('testF');
-      }
-    })
-    .test('getElementsByTagName(div)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('div');
-        ret = elems.last.nodeType;
-      }
-    })
-    .test('getElementsByTagName(p)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('p');
-        ret = elems.last.nodeType;
-      }
-    })
-    .test('getElementsByTagName(a)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('a');
-        ret = elems.last.nodeType;
-      }
-    })
-    .test('getElementsByTagName(*)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('*');
-        ret = elems.last.nodeType;
-      }
-    })
-    .test('getElementsByTagName (not in document)', () {
-      for (int i = 0; i < num; i++) {
-        List<Element> elems = document.getElementsByTagName('strong');
-        ret = elems.length == 0;
-      }
-    })
-    .test('getElementsByName', () {
-      for (int i = 0; i < num * 20; i++) {
-        List<Element> elems = document.getElementsByName('test$num');
-        ret = elems[elems.length-1].nodeType;
-        elems = document.getElementsByName('test$num');
-        ret = elems[elems.length-1].nodeType;
-        elems = document.getElementsByName('test$num');
-        ret = elems[elems.length-1].nodeType;
-        elems = document.getElementsByName('test$num');
-        ret = elems[elems.length-1].nodeType;
-      }
-    })
-    .test('getElementsByName (not in document)', () {
-      for (int i = 0; i < num * 20; i++) {
-        ret = document.getElementsByName('test').length == 0;
-        ret = document.getElementsByName('test').length == 0;
-        ret = document.getElementsByName('test').length == 0;
-        ret = document.getElementsByName('test').length == 0;
-        ret = document.getElementsByName('test').length == 0;
-      }
-    })
-    .end();
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-query-html.html b/samples/third_party/dromaeo/web/tests/dom-query-html.html
deleted file mode 100644
index 27f9333..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-query-html.html
+++ /dev/null
@@ -1,2900 +0,0 @@
-<html>
-<head>
-<script type="application/dart" src="dom-query-html.dart"></script>
-<script src="../../../../pkg/browser/lib/dart.js"></script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="testF10"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2 id="testA10"><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2 id="testB10"><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2 id="testC10"><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2 id="testD10"><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2 id="testE10"><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test10"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test10 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-query.html b/samples/third_party/dromaeo/web/tests/dom-query.html
deleted file mode 100644
index 07acf16..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-query.html
+++ /dev/null
@@ -1,3000 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
-window.onload = function(){
-startTest("dom-query");
-
-// Try to force real results
-var ret, tmp;
-var num = 40;
-var html = document.body.innerHTML;
-
-	prep(function(){
-		html = html.replace(/id="test(\w).*?"/g, 'id="test$1' + num + '"');
-		html = html.replace(/name="test.*?"/g, 'name="test' + num + '"');
-		html = html.replace(/class="foo.*?"/g, 'class="foo test' + num + ' bar"');
-		var div = document.createElement("div");
-		div.innerHTML = html;
-		document.body.appendChild( div );
-	});
-
-	test( "getElementById", function(){
-		for ( var i = 0; i < num * 30; i++ ) {
-			ret = document.getElementById("testA" + num).nodeType;
-			ret = document.getElementById("testB" + num).nodeType;
-			ret = document.getElementById("testC" + num).nodeType;
-			ret = document.getElementById("testD" + num).nodeType;
-			ret = document.getElementById("testE" + num).nodeType;
-			ret = document.getElementById("testF" + num).nodeType;
-		}
-	});
-
-	test( "getElementById (not in document)", function(){
-		for ( var i = 0; i < num * 30; i++ ) {
-			ret = document.getElementById("testA");
-			ret = document.getElementById("testB");
-			ret = document.getElementById("testC");
-			ret = document.getElementById("testD");
-			ret = document.getElementById("testE");
-			ret = document.getElementById("testF");
-		}
-	});
-
-	test( "getElementsByTagName(div)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("div");
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByTagName(p)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("p");
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByTagName(a)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("a");
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByTagName(*)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("*");
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByTagName (not in document)", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var elems = document.getElementsByTagName("strong");
-			ret = elems.length == 0;
-		}
-	});
-
-	test( "getElementsByName", function(){
-		for ( var i = 0; i < num * 20; i++ ) {
-			var elems = document.getElementsByName("test" + num);
-			ret = elems[elems.length-1].nodeType;
-			var elems = document.getElementsByName("test" + num);
-			ret = elems[elems.length-1].nodeType;
-			var elems = document.getElementsByName("test" + num);
-			ret = elems[elems.length-1].nodeType;
-			var elems = document.getElementsByName("test" + num);
-			ret = elems[elems.length-1].nodeType;
-		}
-	});
-
-	test( "getElementsByName (not in document)", function(){
-		for ( var i = 0; i < num * 20; i++ ) {
-			ret = document.getElementsByName("test").length == 0;
-			ret = document.getElementsByName("test").length == 0;
-			ret = document.getElementsByName("test").length == 0;
-			ret = document.getElementsByName("test").length == 0;
-			ret = document.getElementsByName("test").length == 0;
-		}
-	});
-
-endTest();
-};
-</script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="testF10"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2 id="testA10"><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
-
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2 id="testB10"><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2 id="testC10"><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2 id="testD10"><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2 id="testE10"><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators.
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment:
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element.
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element.
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML
-paragraph that will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag
-sequence. The other lines will be treated as
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt;
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt;
-S
-&lt;/P::first-letter&gt;ome text that
-&lt;/P::first-line&gt;
-ends up on two lines
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree.
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>:
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test10"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-
-<p>Selectors can be used in STTS 3 in two different
-    manners:
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification.
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test10 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-traverse-html.dart b/samples/third_party/dromaeo/web/tests/dom-traverse-html.dart
deleted file mode 100644
index 19fb3e5e..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-traverse-html.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-library dromaeo;
-import 'dart:async';
-import 'dart:html';
-import "dart:convert";
-import '../common/common.dart';
-import 'dart:math' as Math;
-part 'Common.dart';
-part 'RunnerSuite.dart';
-
-
-void main() {
-  final int num = 40;
-
-  // Try to force real results.
-  var ret;
-
-  String html = document.body.innerHtml;
-
-  new Suite(window, 'dom-traverse')
-    .prep(() {
-      html = BenchUtil.replaceAll(html, 'id="test(\\w).*?"', (Match match) {
-        final group = match.group(1);
-        return 'id="test${group}${num}"';
-      });
-      html = BenchUtil.replaceAll(html, 'name="test.*?"', (Match match) {
-        return 'name="test${num}"';
-      });
-      html = BenchUtil.replaceAll(html, 'class="foo.*?"', (Match match) {
-        return 'class="foo test${num} bar"';
-      });
-
-      final div = new Element.tag('div');
-      div.innerHtml = html;
-      document.body.append(div);
-    })
-    .test('firstChild', () {
-      final nodes = document.body.childNodes;
-      final nl = nodes.length;
-
-      for (int i = 0; i < num; i++) {
-        for (int j = 0; j < nl; j++) {
-          Node cur = nodes[j];
-          while (cur != null) {
-            cur = cur.firstChild;
-          }
-          ret = cur;
-        }
-      }
-    })
-    .test('lastChild', () {
-      final nodes = document.body.childNodes;
-      final nl = nodes.length;
-
-      for (int i = 0; i < num; i++) {
-        for (int j = 0; j < nl; j++) {
-          Node cur = nodes[j];
-          while (cur != null) {
-            cur = cur.lastChild;
-          }
-          ret = cur;
-        }
-      }
-    })
-    .test('nextSibling', () {
-      for (int i = 0; i < num * 2; i++) {
-        Node cur = document.body.firstChild;
-        while (cur != null) {
-          cur = cur.nextNode;
-        }
-        ret = cur;
-      }
-    })
-    .test('previousSibling', () {
-      for (int i = 0; i < num * 2; i++) {
-        Node cur = document.body.lastChild;
-        while (cur != null) {
-          cur = cur.previousNode;
-        }
-        ret = cur;
-      }
-    })
-    .test('childNodes', () {
-      for (int i = 0; i < num; i++) {
-        final nodes = document.body.childNodes;
-        for (int j = 0; j < nodes.length; j++) {
-          ret = nodes[j];
-        }
-      }
-    })
-    .end();
-}
diff --git a/samples/third_party/dromaeo/web/tests/dom-traverse-html.html b/samples/third_party/dromaeo/web/tests/dom-traverse-html.html
deleted file mode 100644
index ed13976..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-traverse-html.html
+++ /dev/null
@@ -1,2900 +0,0 @@
-<html>
-<head>
-<script type="application/dart" src="dom-traverse-html.dart"></script>
-<script src="../../../../pkg/browser/lib/dart.js"></script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test10"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
- 
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an 
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators. 
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment: 
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element. 
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element. 
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML 
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt; 
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt; 
-S 
-&lt;/P::first-letter&gt;ome text that 
-&lt;/P::first-line&gt; 
-ends up on two lines 
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-      
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree. 
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>: 
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-      
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-      
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test10"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-  
-<p>Selectors can be used in STTS 3 in two different
-    manners: 
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification. 
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test10 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005 
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998 
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/tests/dom-traverse.html b/samples/third_party/dromaeo/web/tests/dom-traverse.html
deleted file mode 100644
index 9b0a098..0000000
--- a/samples/third_party/dromaeo/web/tests/dom-traverse.html
+++ /dev/null
@@ -1,2972 +0,0 @@
-<html>
-<head>
-<script src="../htmlrunner.js"></script>
-<script>
-window.onload = function(){
-startTest("dom-traverse");
-
-// Try to force real results
-var ret, tmp;
-var num = 40;
-var html = document.body.innerHTML;
-
-	prep(function(){
-		html = html.replace(/id="test.*?"/g, 'id="test' + num + '"');
-		html = html.replace(/name="test.*?"/g, 'name="test' + num + '"');
-		html = html.replace(/class="foo.*?"/g, 'class="foo test' + num + ' bar"');
-		var div = document.createElement("div");
-		div.innerHTML = html;
-		document.body.appendChild( div );
-	});
-
-	test( "firstChild", function(){
-		var nodes = document.body.childNodes, nl = nodes.length;
-
-		for ( var i = 0; i < num; i++ ) {
-			for ( var j = 0; j < nl; j++ ) {
-				var cur = nodes[j];
-				while ( cur )
-					cur = cur.firstChild;
-				ret = cur;
-			}
-		}
-	});
-
-	test( "lastChild", function(){
-		var nodes = document.body.childNodes, nl = nodes.length;
-
-		for ( var i = 0; i < num; i++ ) {
-			for ( var j = 0; j < nl; j++ ) {
-				var cur = nodes[j];
-				while ( cur )
-					cur = cur.lastChild;
-				ret = cur;
-			}
-		}
-	});
-
-	test( "nextSibling", function(){
-		for ( var i = 0; i < num * 2; i++ ) {
-			var cur = document.body.firstChild;
-			while ( cur )
-				cur = cur.nextSibling;
-			ret = cur;
-		}
-	});
-
-	test( "previousSibling", function(){
-		for ( var i = 0; i < num * 2; i++ ) {
-			var cur = document.body.lastChild;
-			while ( cur )
-				cur = cur.previousSibling;
-			ret = cur;
-		}
-	});
-
-	test( "childNodes", function(){
-		for ( var i = 0; i < num; i++ ) {
-			var nodes = document.body.childNodes;
-			for ( var j = 0; j < nodes.length; j++ )
-				ret = nodes[j];
-		}
-	});
-
-endTest();
-};
-</script>
-</head>
-<body>
-  <div class="head">
-   <p><a href="http://www.w3.org/"><img height=48 alt=W3C src="http://www.w3.org/Icons/w3c_home" width=72></a>
-
-   <h1 id="title">Selectors</h1>
-
-   <h2>W3C Working Draft 15 December 2005</h2>
-
-   <dl>
-
-    <dt>This version:
-
-    <dd><a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215">
-                 http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a>
-
-    <dt>Latest version:
-
-    <dd><a href="http://www.w3.org/TR/css3-selectors">
-                 http://www.w3.org/TR/css3-selectors</a>
-
-    <dt>Previous version:
-
-    <dd><a href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113">
-                 http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>
-
-    <dt><a name=editors-list></a>Editors:
-
-    <dd class="vcard"><span class="fn">Daniel Glazman</span> (Invited Expert)</dd>
-
-    <dd class="vcard"><a lang="tr" class="url fn" href="http://www.tantek.com/">Tantek &Ccedil;elik</a> (Invited Expert)
-
-    <dd class="vcard"><a href="mailto:ian@hixie.ch" class="url fn">Ian Hickson</a> (<span
-    class="company"><a href="http://www.google.com/">Google</a></span>)
-
-    <dd class="vcard"><span class="fn">Peter Linss</span> (former editor, <span class="company"><a
-    href="http://www.netscape.com/">Netscape/AOL</a></span>)
-
-    <dd class="vcard"><span class="fn">John Williams</span> (former editor, <span class="company"><a
-    href="http://www.quark.com/">Quark, Inc.</a></span>)
-
-   </dl>
-
-   <p class="copyright"><a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">
-   Copyright</a> &copy; 2005 <a href="http://www.w3.org/"><abbr
-   title="World Wide Web Consortium">W3C</abbr></a><sup>&reg;</sup>
-   (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts
-   Institute of Technology">MIT</abbr></a>, <a
-   href="http://www.ercim.org/"><acronym title="European Research
-   Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a
-   href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.  W3C
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,
-   <a
-   href="http://www.w3.org/Consortium/Legal/copyright-documents">document
-   use</a> rules apply.
-
-   <hr title="Separator for header">
-
-  </div>
-
-  <h2><a name=abstract></a>Abstract</h2>
-
-  <p><em>Selectors</em> are patterns that match against elements in a
-  tree. Selectors have been optimized for use with HTML and XML, and
-  are designed to be usable in performance-critical code.</p>
-
-  <p><acronym title="Cascading Style Sheets">CSS</acronym> (Cascading
-  Style Sheets) is a language for describing the rendering of <acronym
-  title="Hypertext Markup Language">HTML</acronym> and <acronym
-  title="Extensible Markup Language">XML</acronym> documents on
-  screen, on paper, in speech, etc. CSS uses Selectors for binding
-  style properties to elements in the document. This document
-  describes extensions to the selectors defined in CSS level 2. These
-  extended selectors will be used by CSS level 3.
-
-  <p>Selectors define the following function:</p>
-
-  <pre>expression &#x2217; element &rarr; boolean</pre>
-
-  <p>That is, given an element and a selector, this specification
-  defines whether that element matches the selector.</p>
-
-  <p>These expressions can also be used, for instance, to select a set
-  of elements, or a single element from a set of elements, by
-  evaluating the expression across all the elements in a
-  subtree. <acronym title="Simple Tree Transformation
-  Sheets">STTS</acronym> (Simple Tree Transformation Sheets), a
-  language for transforming XML trees, uses this mechanism. <a href="#refsSTTS">[STTS]</a></p>
-
-  <h2><a name=status></a>Status of this document</h2>
-
-  <p><em>This section describes the status of this document at the
-  time of its publication. Other documents may supersede this
-  document. A list of current W3C publications and the latest revision
-  of this technical report can be found in the <a
-  href="http://www.w3.org/TR/">W3C technical reports index at
-  http://www.w3.org/TR/.</a></em></p>
-
-  <p>This document describes the selectors that already exist in <a
-  href="#refsCSS1"><abbr title="CSS level 1">CSS1</abbr></a> and <a
-  href="#refsCSS21"><abbr title="CSS level 2">CSS2</abbr></a>, and
-  also proposes new selectors for <abbr title="CSS level
-  3">CSS3</abbr> and other languages that may need them.</p>
-
-  <p>The CSS Working Group doesn't expect that all implementations of
-  CSS3 will have to implement all selectors. Instead, there will
-  probably be a small number of variants of CSS3, called profiles. For
-  example, it may be that only a profile for interactive user agents
-  will include all of the selectors.</p>
-
-  <p>This specification is a last call working draft for the the <a
-  href="http://www.w3.org/Style/CSS/members">CSS Working Group</a>
-  (<a href="/Style/">Style Activity</a>). This
-  document is a revision of the <a
-  href="http://www.w3.org/TR/2001/CR-css3-selectors-20011113/">Candidate
-  Recommendation dated 2001 November 13</a>, and has incorporated
-  implementation feedback received in the past few years. It is
-  expected that this last call will proceed straight to Proposed
-  Recommendation stage since it is believed that interoperability will
-  be demonstrable.</p>
-
-  <p>All persons are encouraged to review and implement this
-  specification and return comments to the (<a
-  href="http://lists.w3.org/Archives/Public/www-style/">archived</a>)
-  public mailing list <a
-  href="http://www.w3.org/Mail/Lists.html#www-style">www-style</a>
-  (see <a href="http://www.w3.org/Mail/Request">instructions</a>). W3C
-  Members can also send comments directly to the CSS Working
-  Group.
-  The deadline for comments is 14 January 2006.</p>
-
-  <p>This is still a draft document and may be updated, replaced, or
-  obsoleted by other documents at any time. It is inappropriate to
-  cite a W3C Working Draft as other than &quot;work in progress&quot;.
-
-  <p>This document may be available in <a
-  href="http://www.w3.org/Style/css3-selectors-updates/translations">translation</a>.
-  The English version of this specification is the only normative
-  version.
-
-  <div class="subtoc">
-
-   <h2 id="test10"><a name=contents>Table of contents</a></h2>
-
-   <ul class="toc">
-    <li class="tocline2"><a href="#context">1. Introduction</a>
-     <ul>
-      <li><a href="#dependencies">1.1. Dependencies</a> </li>
-      <li><a href="#terminology">1.2. Terminology</a> </li>
-      <li><a href="#changesFromCSS2">1.3. Changes from CSS2</a> </li>
-     </ul>
-    <li class="tocline2"><a href="#selectors">2. Selectors</a>
-    <li class="tocline2"><a href="#casesens">3. Case sensitivity</a>
-    <li class="tocline2"><a href="#selector-syntax">4. Selector syntax</a>
-    <li class="tocline2"><a href="#grouping">5. Groups of selectors</a>
-    <li class="tocline2"><a href="#simple-selectors">6. Simple selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#type-selectors">6.1. Type selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#typenmsp">6.1.1. Type selectors and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#universal-selector">6.2. Universal selector</a>
-       <ul>
-        <li><a href="#univnmsp">6.2.1. Universal selector and namespaces</a></li>
-       </ul>
-      <li class="tocline3"><a href="#attribute-selectors">6.3. Attribute selectors</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#attribute-representation">6.3.1. Representation of attributes and attributes values</a>
-        <li><a href="#attribute-substrings">6.3.2. Substring matching attribute selectors</a>
-        <li class="tocline4"><a href="#attrnmsp">6.3.3. Attribute selectors and namespaces</a>
-        <li class="tocline4"><a href="#def-values">6.3.4. Default attribute values in DTDs</a></li>
-       </ul>
-      <li class="tocline3"><a href="#class-html">6.4. Class selectors</a>
-      <li class="tocline3"><a href="#id-selectors">6.5. ID selectors</a>
-      <li class="tocline3"><a href="#pseudo-classes">6.6. Pseudo-classes</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#dynamic-pseudos">6.6.1. Dynamic pseudo-classes</a>
-        <li class="tocline4"><a href="#target-pseudo">6.6.2. The :target pseudo-class</a>
-        <li class="tocline4"><a href="#lang-pseudo">6.6.3. The :lang() pseudo-class</a>
-        <li class="tocline4"><a href="#UIstates">6.6.4. UI element states pseudo-classes</a>
-        <li class="tocline4"><a href="#structural-pseudos">6.6.5. Structural pseudo-classes</a>
-         <ul>
-          <li><a href="#root-pseudo">:root pseudo-class</a>
-          <li><a href="#nth-child-pseudo">:nth-child() pseudo-class</a>
-          <li><a href="#nth-last-child-pseudo">:nth-last-child()</a>
-          <li><a href="#nth-of-type-pseudo">:nth-of-type() pseudo-class</a>
-          <li><a href="#nth-last-of-type-pseudo">:nth-last-of-type()</a>
-          <li><a href="#first-child-pseudo">:first-child pseudo-class</a>
-          <li><a href="#last-child-pseudo">:last-child pseudo-class</a>
-          <li><a href="#first-of-type-pseudo">:first-of-type pseudo-class</a>
-          <li><a href="#last-of-type-pseudo">:last-of-type pseudo-class</a>
-          <li><a href="#only-child-pseudo">:only-child pseudo-class</a>
-          <li><a href="#only-of-type-pseudo">:only-of-type pseudo-class</a>
-          <li><a href="#empty-pseudo">:empty pseudo-class</a></li>
-         </ul>
-        <li class="tocline4"><a href="#negation">6.6.7. The negation pseudo-class</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li><a href="#pseudo-elements">7. Pseudo-elements</a>
-     <ul>
-      <li><a href="#first-line">7.1. The ::first-line pseudo-element</a>
-      <li><a href="#first-letter">7.2. The ::first-letter pseudo-element</a>
-      <li><a href="#UIfragments">7.3. The ::selection pseudo-element</a>
-      <li><a href="#gen-content">7.4. The ::before and ::after pseudo-elements</a></li>
-     </ul>
-    <li class="tocline2"><a href="#combinators">8. Combinators</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#descendant-combinators">8.1. Descendant combinators</a>
-      <li class="tocline3"><a href="#child-combinators">8.2. Child combinators</a>
-      <li class="tocline3"><a href="#sibling-combinators">8.3. Sibling combinators</a>
-       <ul class="toc">
-        <li class="tocline4"><a href="#adjacent-sibling-combinators">8.3.1. Adjacent sibling combinator</a>
-        <li class="tocline4"><a href="#general-sibling-combinators">8.3.2. General sibling combinator</a></li>
-       </ul>
-      </li>
-     </ul>
-    <li class="tocline2"><a href="#specificity">9. Calculating a selector's specificity</a>
-    <li class="tocline2"><a href="#w3cselgrammar">10. The grammar of Selectors</a>
-     <ul class="toc">
-      <li class="tocline3"><a href="#grammar">10.1. Grammar</a>
-      <li class="tocline3"><a href="#lex">10.2. Lexical scanner</a></li>
-     </ul>
-    <li class="tocline2"><a href="#downlevel">11. Namespaces and down-level clients</a>
-    <li class="tocline2"><a href="#profiling">12. Profiles</a>
-    <li><a href="#Conformance">13. Conformance and requirements</a>
-    <li><a href="#Tests">14. Tests</a>
-    <li><a href="#ACKS">15. Acknowledgements</a>
-    <li class="tocline2"><a href="#references">16. References</a>
-   </ul>
-
-  </div>
-
-  <h2><a name=context>1. Introduction</a></h2>
-
-  <h3><a name=dependencies></a>1.1. Dependencies</h3>
-
-  <p>Some features of this specification are specific to CSS, or have
-  particular limitations or rules specific to CSS. In this
-  specification, these have been described in terms of CSS2.1. <a
-  href="#refsCSS21">[CSS21]</a></p>
-
-  <h3><a name=terminology></a>1.2. Terminology</h3>
-
-  <p>All of the text of this specification is normative except
-  examples, notes, and sections explicitly marked as
-  non-normative.</p>
-
-  <h3><a name=changesFromCSS2></a>1.3. Changes from CSS2</h3>
-
-  <p><em>This section is non-normative.</em></p>
-
-  <p>The main differences between the selectors in CSS2 and those in
-  Selectors are:
-
-  <ul>
-
-   <li>the list of basic definitions (selector, group of selectors,
-   simple selector, etc.) has been changed; in particular, what was
-   referred to in CSS2 as a simple selector is now called a sequence
-   of simple selectors, and the term "simple selector" is now used for
-   the components of this sequence</li>
-
-   <li>an optional namespace component is now allowed in type element
-   selectors, the universal selector and attribute selectors</li>
-
-   <li>a <a href="#general-sibling-combinators">new combinator</a> has been introduced</li>
-
-   <li>new simple selectors including substring matching attribute
-   selectors, and new pseudo-classes</li>
-
-   <li>new pseudo-elements, and introduction of the "::" convention
-   for pseudo-elements</li>
-
-   <li>the grammar has been rewritten</li>
-
-   <li>profiles to be added to specifications integrating Selectors
-   and defining the set of selectors which is actually supported by
-   each specification</li>
-
-   <li>Selectors are now a CSS3 Module and an independent
-   specification; other specifications can now refer to this document
-   independently of CSS</li>
-
-   <li>the specification now has its own test suite</li>
-
-  </ul>
-
-<h2><a name=selectors></a>2. Selectors</h2>
-
-<p><em>This section is non-normative, as it merely summarizes the
-following sections.</em></p>
-
-<p>A Selector represents a structure. This structure can be used as a
-condition (e.g. in a CSS rule) that determines which elements a
-selector matches in the document tree, or as a flat description of the
-HTML or XML fragment corresponding to that structure.</p>
-
-<p>Selectors may range from simple element names to rich contextual
-representations.</p>
-
-<p>The following table summarizes the Selector syntax:</p>
-
-<table class="selectorsReview">
-  <thead>
-  <tr>
-    <th class="pattern">Pattern</th>
-    <th class="meaning">Meaning</th>
-    <th class="described">Described in section</th>
-    <th class="origin">First defined in CSS level</th></tr>
-  <tbody>
-  <tr>
-    <td class="pattern">*</td>
-    <td class="meaning">any element</td>
-    <td class="described"><a
-      href="#universal-selector">Universal
-      selector</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E</td>
-    <td class="meaning">an element of type E</td>
-    <td class="described"><a
-      href="#type-selectors">Type selector</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E[foo]</td>
-    <td class="meaning">an E element with a "foo" attribute</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is exactly
-      equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo~="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value is a list of
-      space-separated values, one of which is exactly equal to "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E[foo^="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value begins exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo$="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value ends exactly
-      with the string "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[foo*="bar"]</td>
-    <td class="meaning">an E element whose "foo" attribute value contains the
-      substring "bar"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E[hreflang|="en"]</td>
-    <td class="meaning">an E element whose "hreflang" attribute has a hyphen-separated
-      list of values beginning (from the left) with "en"</td>
-    <td class="described"><a
-      href="#attribute-selectors">Attribute
-      selectors</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:root</td>
-    <td class="meaning">an E element, root of the document</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-child(n)</td>
-    <td class="meaning">an E element, the n-th child of its parent, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:nth-last-of-type(n)</td>
-    <td class="meaning">an E element, the n-th sibling of its type, counting
-      from the last one</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-child</td>
-    <td class="meaning">an E element, first child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:last-child</td>
-    <td class="meaning">an E element, last child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:first-of-type</td>
-    <td class="meaning">an E element, first sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:last-of-type</td>
-    <td class="meaning">an E element, last sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-child</td>
-    <td class="meaning">an E element, only child of its parent</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:only-of-type</td>
-    <td class="meaning">an E element, only sibling of its type</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:empty</td>
-    <td class="meaning">an E element that has no children (including text
-    nodes)</td>
-    <td class="described"><a
-      href="#structural-pseudos">Structural
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:link<br>E:visited</td>
-    <td class="meaning">an E element being the source anchor of a hyperlink of
-      which the target is not yet visited (:link) or already visited
-    (:visited)</td>
-    <td class="described"><a
-      href="#link">The link
-      pseudo-classes</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:active<br>E:hover<br>E:focus</td>
-    <td class="meaning">an E element during certain user actions</td>
-    <td class="described"><a
-      href="#useraction-pseudos">The user
-      action pseudo-classes</a></td>
-    <td class="origin">1 and 2</td></tr>
-  <tr>
-    <td class="pattern">E:target</td>
-    <td class="meaning">an E element being the target of the referring URI</td>
-    <td class="described"><a
-      href="#target-pseudo">The target
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:lang(fr)</td>
-    <td class="meaning">an element of type E in language "fr" (the document
-      language specifies how language is determined)</td>
-    <td class="described"><a
-      href="#lang-pseudo">The :lang()
-      pseudo-class</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E:enabled<br>E:disabled</td>
-    <td class="meaning">a user interface element E which is enabled or
-    disabled</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E:checked<!--<br>E:indeterminate--></td>
-    <td class="meaning">a user interface element E which is checked<!-- or in an
-      indeterminate state--> (for instance a radio-button or checkbox)</td>
-    <td class="described"><a
-      href="#UIstates">The UI element states
-      pseudo-classes</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::first-line</td>
-    <td class="meaning">the first formatted line of an E element</td>
-    <td class="described"><a
-      href="#first-line">The ::first-line
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::first-letter</td>
-    <td class="meaning">the first formatted letter of an E element</td>
-    <td class="described"><a
-      href="#first-letter">The ::first-letter
-      pseudo-element</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E::selection</td>
-    <td class="meaning">the portion of an E element that is currently
-      selected/highlighted by the user</td>
-    <td class="described"><a
-      href="#UIfragments">The UI element
-      fragments pseudo-elements</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E::before</td>
-    <td class="meaning">generated content before an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::before
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E::after</td>
-    <td class="meaning">generated content after an E element</td>
-    <td class="described"><a
-      href="#gen-content">The ::after
-      pseudo-element</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E.warning</td>
-    <td class="meaning">an E element whose class is
-"warning" (the document language specifies how class is determined).</td>
-    <td class="described"><a
-      href="#class-html">Class
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E#myid</td>
-    <td class="meaning">an E element with ID equal to "myid".</td>
-    <td class="described"><a
-      href="#id-selectors">ID
-    selectors</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E:not(s)</td>
-    <td class="meaning">an E element that does not match simple selector s</td>
-    <td class="described"><a
-      href="#negation">Negation
-      pseudo-class</a></td>
-    <td class="origin">3</td></tr>
-  <tr>
-    <td class="pattern">E F</td>
-    <td class="meaning">an F element descendant of an E element</td>
-    <td class="described"><a
-      href="#descendant-combinators">Descendant
-      combinator</a></td>
-    <td class="origin">1</td></tr>
-  <tr>
-    <td class="pattern">E &gt; F</td>
-    <td class="meaning">an F element child of an E element</td>
-    <td class="described"><a
-      href="#child-combinators">Child
-      combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E + F</td>
-    <td class="meaning">an F element immediately preceded by an E element</td>
-    <td class="described"><a
-      href="#adjacent-sibling-combinators">Adjacent sibling combinator</a></td>
-    <td class="origin">2</td></tr>
-  <tr>
-    <td class="pattern">E ~ F</td>
-    <td class="meaning">an F element preceded by an E element</td>
-    <td class="described"><a
-      href="#general-sibling-combinators">General sibling combinator</a></td>
-    <td class="origin">3</td></tr></tbody></table>
-
-<p>The meaning of each selector is derived from the table above by
-prepending "matches" to the contents of each cell in the "Meaning"
-column.</p>
-
-<h2><a name=casesens>3. Case sensitivity</a></h2>
-
-<p>The case sensitivity of document language element names, attribute
-names, and attribute values in selectors depends on the document
-language. For example, in HTML, element names are case-insensitive,
-but in XML, they are case-sensitive.</p>
-
-<h2><a name=selector-syntax>4. Selector syntax</a></h2>
-
-<p>A <dfn><a name=selector>selector</a></dfn> is a chain of one
-or more <a href="#sequence">sequences of simple selectors</a>
-separated by <a href="#combinators">combinators</a>.</p>
-
-<p>A <dfn><a name=sequence>sequence of simple selectors</a></dfn>
-is a chain of <a href="#simple-selectors-dfn">simple selectors</a>
-that are not separated by a <a href="#combinators">combinator</a>. It
-always begins with a <a href="#type-selectors">type selector</a> or a
-<a href="#universal-selector">universal selector</a>. No other type
-selector or universal selector is allowed in the sequence.</p>
-
-<p>A <dfn><a name=simple-selectors-dfn></a><a
-href="#simple-selectors">simple selector</a></dfn> is either a <a
-href="#type-selectors">type selector</a>, <a
-href="#universal-selector">universal selector</a>, <a
-href="#attribute-selectors">attribute selector</a>, <a
-href="#class-html">class selector</a>, <a
-href="#id-selectors">ID selector</a>, <a
-href="#content-selectors">content selector</a>, or <a
-href="#pseudo-classes">pseudo-class</a>. One <a
-href="#pseudo-elements">pseudo-element</a> may be appended to the last
-sequence of simple selectors.</p>
-
-<p><dfn>Combinators</dfn> are: white space, &quot;greater-than
-sign&quot; (U+003E, <code>&gt;</code>), &quot;plus sign&quot; (U+002B,
-<code>+</code>) and &quot;tilde&quot; (U+007E, <code>~</code>).  White
-space may appear between a combinator and the simple selectors around
-it. <a name=whitespace></a>Only the characters "space" (U+0020), "tab"
-(U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form
-feed" (U+000C) can occur in white space. Other space-like characters,
-such as "em-space" (U+2003) and "ideographic space" (U+3000), are
-never part of white space.</p>
-
-<p>The elements of a document tree that are represented by a selector
-are the <dfn><a name=subject></a>subjects of the selector</dfn>. A
-selector consisting of a single sequence of simple selectors
-represents any element satisfying its requirements. Prepending another
-sequence of simple selectors and a combinator to a sequence imposes
-additional matching constraints, so the subjects of a selector are
-always a subset of the elements represented by the last sequence of
-simple selectors.</p>
-
-<p>An empty selector, containing no sequence of simple selectors and
-no pseudo-element, is an <a href="#Conformance">invalid
-selector</a>.</p>
-
-<h2><a name=grouping>5. Groups of selectors</a></h2>
-
-<p>When several selectors share the same declarations, they may be
-grouped into a comma-separated list. (A comma is U+002C.)</p>
-
-<div class="example">
-<p>CSS examples:</p>
-<p>In this example, we condense three rules with identical
-declarations into one. Thus,</p>
-<pre>h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }</pre>
-<p>is equivalent to:</p>
-<pre>h1, h2, h3 { font-family: sans-serif }</pre>
-</div>
-
-<p><strong>Warning</strong>: the equivalence is true in this example
-because all the selectors are valid selectors. If just one of these
-selectors were invalid, the entire group of selectors would be
-invalid. This would invalidate the rule for all three heading
-elements, whereas in the former case only one of the three individual
-heading rules would be invalidated.</p>
-
-
-<h2><a name=simple-selectors>6. Simple selectors</a></h2>
-
-<h3><a name=type-selectors>6.1. Type selector</a></h3>
-
-<p>A <dfn>type selector</dfn> is the name of a document language
-element type. A type selector represents an instance of the element
-type in the document tree.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents an <code>h1</code> element in the document tree:</p>
- <pre>h1</pre>
-</div>
-
-
-<h4><a name=typenmsp>6.1.1. Type selectors and namespaces</a></h4>
-
-<p>Type selectors allow an optional namespace (<a
-href="#refsXMLNAMES">[XMLNAMES]</a>) component. A namespace prefix
-that has been previously declared may be prepended to the element name
-separated by the namespace separator &quot;vertical bar&quot;
-(U+007C, <code>|</code>).</p>
-
-<p>The namespace component may be left empty to indicate that the
-selector is only to represent elements with no declared namespace.</p>
-
-<p>An asterisk may be used for the namespace prefix, indicating that
-the selector represents elements in any namespace (including elements
-with no namespace).</p>
-
-<p>Element type selectors that have no namespace component (no
-namespace separator), represent elements without regard to the
-element's namespace (equivalent to "<code>*|</code>") unless a default
-namespace has been declared. If a default namespace has been declared,
-the selector will represent only elements in the default
-namespace.</p>
-
-<p>A type selector containing a namespace prefix that has not been
-previously declared is an <a href="#Conformance">invalid</a> selector.
-The mechanism for declaring a namespace prefix is left up to the
-language implementing Selectors. In CSS, such a mechanism is defined
-in the General Syntax module.</p>
-
-<p>In a namespace-aware client, element type selectors will only match
-against the <a
-href="http://www.w3.org/TR/REC-xml-names/#NT-LocalPart">local part</a>
-of the element's <a
-href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames">qualified
-name</a>. See <a href="#downlevel">below</a> for notes about matching
-behaviors in down-level clients.</p>
-
-<p>In summary:</p>
-
-<dl>
-  <dt><code>ns|E</code></dt>
-  <dd>elements with name E in namespace ns</dd>
-  <dt><code>*|E</code></dt>
-  <dd>elements with name E in any namespace, including those without any
-  declared namespace</dd>
-  <dt><code>|E</code></dt>
-  <dd>elements with name E without any declared namespace</dd>
-  <dt><code>E</code></dt>
-  <dd>if no default namespace has been specified, this is equivalent to *|E.
-  Otherwise it is equivalent to ns|E where ns is the default namespace.</dd>
-</dl>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <pre>@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }</pre>
-
- <p>The first rule will match only <code>h1</code> elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The second rule will match all elements in the
- "http://www.example.com" namespace.</p>
-
- <p>The third rule will match only <code>h1</code> elements without
- any declared namespace.</p>
-
- <p>The fourth rule will match <code>h1</code> elements in any
- namespace (including those without any declared namespace).</p>
-
- <p>The last rule is equivalent to the fourth rule because no default
- namespace has been defined.</p>
-
-</div>
-
-<h3><a name=universal-selector>6.2. Universal selector</a> </h3>
-
-<p>The <dfn>universal selector</dfn>, written &quot;asterisk&quot;
-(<code>*</code>), represents the qualified name of any element
-type. It represents any single element in the document tree in any
-namespace (including those without any declared namespace) if no
-default namespace has been specified. If a default namespace has been
-specified, see <a href="#univnmsp">Universal selector and
-Namespaces</a> below.</p>
-
-<p>If the universal selector is not the only component of a sequence
-of simple selectors, the <code>*</code> may be omitted.</p>
-
-<div class="example">
- <p>Examples:</p>
- <ul>
-  <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are equivalent,</li>
-  <li><code>*.warning</code> and <code>.warning</code> are equivalent,</li>
-  <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>
- </ul>
-</div>
-
-<p class="note"><strong>Note:</strong> it is recommended that the
-<code>*</code>, representing the universal selector, not be
-omitted.</p>
-
-<h4><a name=univnmsp>6.2.1. Universal selector and namespaces</a></h4>
-
-<p>The universal selector allows an optional namespace component. It
-is used as follows:</p>
-
-<dl>
- <dt><code>ns|*</code></dt>
- <dd>all elements in namespace ns</dd>
- <dt><code>*|*</code></dt>
- <dd>all elements</dd>
- <dt><code>|*</code></dt>
- <dd>all elements without any declared namespace</dd>
- <dt><code>*</code></dt>
- <dd>if no default namespace has been specified, this is equivalent to *|*.
- Otherwise it is equivalent to ns|* where ns is the default namespace.</dd>
-</dl>
-
-<p>A universal selector containing a namespace prefix that has not
-been previously declared is an <a href="#Conformance">invalid</a>
-selector.  The mechanism for declaring a namespace prefix is left up
-to the language implementing Selectors.  In CSS, such a mechanism is
-defined in the General Syntax module.</p>
-
-
-<h3><a name=attribute-selectors>6.3. Attribute selectors</a></h3>
-
-<p>Selectors allow the representation of an element's attributes. When
-a selector is used as an expression to match against an element,
-attribute selectors must be considered to match an element if that
-element has an attribute that matches the attribute represented by the
-attribute selector.</p>
-
-<h4><a name=attribute-representation>6.3.1. Attribute presence and values
-selectors</a></h4>
-
-<p>CSS2 introduced four attribute selectors:</p>
-
-<dl>
-  <dt><code>[att]</code>
-  <dd>Represents an element with the <code>att</code> attribute, whatever the value of
-  the attribute.</dd>
-  <dt><code>[att=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is exactly
-  "val".</dd>
-  <dt><code>[att~=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value is a <a
-  href="#whitespace">whitespace</a>-separated list of words, one of
-  which is exactly "val". If "val" contains whitespace, it will never
-  represent anything (since the words are <em>separated</em> by
-  spaces).</dd>
-  <dt><code>[att|=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute, its value either
-  being exactly "val" or beginning with "val" immediately followed by
-  "-" (U+002D).  This is primarily intended to allow language subcode
-  matches (e.g., the <code>hreflang</code> attribute on the
-  <code>link</code> element in HTML) as described in RFC 3066 (<a
-  href="#refsRFC3066">[RFC3066]</a>).  For <code>lang</code> (or
-  <code>xml:lang</code>) language subcode matching, please see <a
-  href="#lang-pseudo">the <code>:lang</code> pseudo-class</a>.</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names and values in selectors depends on
-the document language.</p>
-
-<div class="example">
-
-  <p>Examples:</p>
-
-  <p>The following attribute selector represents an <code>h1</code>
-  element that carries the <code>title</code> attribute, whatever its
-  value:</p>
-
-  <pre>h1[title]</pre>
-
-  <p>In the following example, the selector represents a
-  <code>span</code> element whose <code>class</code> attribute has
-  exactly the value "example":</p>
-
-  <pre>span[class="example"]</pre>
-
-  <p>Multiple attribute selectors can be used to represent several
-  attributes of an element, or several conditions on the same
-  attribute. Here, the selector represents a <code>span</code> element
-  whose <code>hello</code> attribute has exactly the value "Cleveland"
-  and whose <code>goodbye</code> attribute has exactly the value
-  "Columbus":</p>
-
-  <pre>span[hello="Cleveland"][goodbye="Columbus"]</pre>
-
-  <p>The following selectors illustrate the differences between "="
-  and "~=".  The first selector will represent, for example, the value
-  "copyright copyleft copyeditor" on a <code>rel</code> attribute. The
-  second selector will only represent an <code>a</code> element with
-  an <code>href</code> attribute having the exact value
-  "http://www.w3.org/".</p>
-
-  <pre>a[rel~="copyright"]
-a[href="http://www.w3.org/"]</pre>
-
-  <p>The following selector represents a <code>link</code> element
-  whose <code>hreflang</code> attribute is exactly "fr".</p>
-
-  <pre>link[hreflang=fr]</pre>
-
-  <p>The following selector represents a <code>link</code> element for
-  which the values of the <code>hreflang</code> attribute begins with
-  "en", including "en", "en-US", and "en-cockney":</p>
-
-  <pre>link[hreflang|="en"]</pre>
-
-  <p>Similarly, the following selectors represents a
-  <code>DIALOGUE</code> element whenever it has one of two different
-  values for an attribute <code>character</code>:</p>
-
-  <pre>DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]</pre>
-
-</div>
-
-<h4><a name=attribute-substrings></a>6.3.2. Substring matching attribute
-selectors</h4>
-
-<p>Three additional attribute selectors are provided for matching
-substrings in the value of an attribute:</p>
-
-<dl>
-  <dt><code>[att^=val]</code></dt>
-  <dd>Represents an element with the <code>att</code> attribute whose value begins
-  with the prefix "val".</dd>
-  <dt><code>[att$=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value ends with
-  the suffix "val".</dd>
-  <dt><code>[att*=val]</code>
-  <dd>Represents an element with the <code>att</code> attribute whose value contains
-  at least one instance of the substring "val".</dd>
-</dl>
-
-<p>Attribute values must be identifiers or strings. The
-case-sensitivity of attribute names in selectors depends on the
-document language.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents an HTML <code>object</code>, referencing an
- image:</p>
- <pre>object[type^="image/"]</pre>
- <p>The following selector represents an HTML anchor <code>a</code> with an
- <code>href</code> attribute whose value ends with ".html".</p>
- <pre>a[href$=".html"]</pre>
- <p>The following selector represents an HTML paragraph with a <code>title</code>
- attribute whose value contains the substring "hello"</p>
- <pre>p[title*="hello"]</pre>
-</div>
-
-<h4><a name=attrnmsp>6.3.3. Attribute selectors and namespaces</a></h4>
-
-<p>Attribute selectors allow an optional namespace component to the
-attribute name. A namespace prefix that has been previously declared
-may be prepended to the attribute name separated by the namespace
-separator &quot;vertical bar&quot; (<code>|</code>). In keeping with
-the Namespaces in the XML recommendation, default namespaces do not
-apply to attributes, therefore attribute selectors without a namespace
-component apply only to attributes that have no declared namespace
-(equivalent to "<code>|attr</code>"). An asterisk may be used for the
-namespace prefix indicating that the selector is to match all
-attribute names without regard to the attribute's namespace.
-
-<p>An attribute selector with an attribute name containing a namespace
-prefix that has not been previously declared is an <a
-href="#Conformance">invalid</a> selector.  The mechanism for declaring
-a namespace prefix is left up to the language implementing Selectors.
-In CSS, such a mechanism is defined in the General Syntax module.
-
-<div class="example">
-  <p>CSS examples:</p>
-  <pre>@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }</pre>
-
-  <p>The first rule will match only elements with the attribute
-  <code>att</code> in the "http://www.example.com" namespace with the
-  value "val".</p>
-
-  <p>The second rule will match only elements with the attribute
-  <code>att</code> regardless of the namespace of the attribute
-  (including no declared namespace).</p>
-
-  <p>The last two rules are equivalent and will match only elements
-  with the attribute <code>att</code> where the attribute is not
-  declared to be in a namespace.</p>
-
-</div>
-
-<h4><a name=def-values>6.3.4. Default attribute values in DTDs</a></h4>
-
-<p>Attribute selectors represent explicitly set attribute values in
-the document tree. Default attribute values may be defined in a DTD or
-elsewhere, but cannot always be selected by attribute
-selectors. Selectors should be designed so that they work even if the
-default values are not included in the document tree.</p>
-
-<p>More precisely, a UA is <em>not</em> required to read an "external
-subset" of the DTD but <em>is</em> required to look for default
-attribute values in the document's "internal subset." (See <a
-href="#refsXML10">[XML10]</a> for definitions of these subsets.)</p>
-
-<p>A UA that recognizes an XML namespace <a
-href="#refsXMLNAMES">[XMLNAMES]</a> is not required to use its
-knowledge of that namespace to treat default attribute values as if
-they were present in the document. (For example, an XHTML UA is not
-required to use its built-in knowledge of the XHTML DTD.)</p>
-
-<p class="note"><strong>Note:</strong> Typically, implementations
-choose to ignore external subsets.</p>
-
-<div class="example">
-<p>Example:</p>
-
-<p>Consider an element EXAMPLE with an attribute "notation" that has a
-default value of "decimal". The DTD fragment might be</p>
-
-<pre class="dtd-example">&lt;!ATTLIST EXAMPLE notation (decimal,octal) "decimal"></pre>
-
-<p>If the style sheet contains the rules</p>
-
-<pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>the first rule will not match elements whose "notation" attribute
-is set by default, i.e. not set explicitly. To catch all cases, the
-attribute selector for the default value must be dropped:</p>
-
-<pre>EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>
-
-<p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is
-more specific than the tag
-selector alone, the style declarations in the second rule will override
-those in the first for elements that have a "notation" attribute value
-of "octal". Care has to be taken that all property declarations that
-are to apply only to the default case are overridden in the non-default
-cases' style rules.</p>
-
-</div>
-
-<h3><a name=class-html>6.4. Class selectors</a></h3>
-
-<p>Working with HTML, authors may use the period (U+002E,
-<code>.</code>) notation as an alternative to the <code>~=</code>
-notation when representing the <code>class</code> attribute. Thus, for
-HTML, <code>div.value</code> and <code>div[class~=value]</code> have
-the same meaning. The attribute value must immediately follow the
-&quot;period&quot; (<code>.</code>).</p>
-
-<p>UAs may apply selectors using the period (.) notation in XML
-documents if the UA has namespace-specific knowledge that allows it to
-determine which attribute is the &quot;class&quot; attribute for the
-respective namespace. One such example of namespace-specific knowledge
-is the prose in the specification for a particular namespace (e.g. SVG
-1.0 <a href="#refsSVG">[SVG]</a> describes the <a
-href="http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute">SVG
-&quot;class&quot; attribute</a> and how a UA should interpret it, and
-similarly MathML 1.01 <a href="#refsMATH">[MATH]</a> describes the <a
-href="http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4">MathML
-&quot;class&quot; attribute</a>.)</p>
-
-<div class="example">
- <p>CSS examples:</p>
-
- <p>We can assign style information to all elements with
- <code>class~="pastoral"</code> as follows:</p>
-
-  <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>or just</p>
-
-  <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>
-
-  <p>The following assigns style only to H1 elements with
-  <code>class~="pastoral"</code>:</p>
-
-  <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>
-
-  <p>Given these rules, the first H1 instance below would not have
-  green text, while the second would:</p>
-
-  <pre>&lt;H1&gt;Not green&lt;/H1&gt;
-&lt;H1 class="pastoral"&gt;Very green&lt;/H1&gt;</pre>
-
-</div>
-
-<p>To represent a subset of "class" values, each value must be preceded
-by a ".", in any order.</P>
-
-<div class="example">
-
-  <p>CSS example:</p>
-
-  <p>The following rule matches any P element whose "class" attribute
-  has been assigned a list of <a
-  href="#whitespace">whitespace</a>-separated values that includes
-  "pastoral" and "marine":</p>
-
-  <pre>p.pastoral.marine { color: green }</pre>
-
-  <p>This rule matches when <code>class="pastoral blue aqua
-  marine"</code> but does not match for <code>class="pastoral
-  blue"</code>.</p>
-
-</div>
-
-<p class="note"><strong>Note:</strong> Because CSS gives considerable
-power to the "class" attribute, authors could conceivably design their
-own "document language" based on elements with almost no associated
-presentation (such as DIV and SPAN in HTML) and assigning style
-information through the "class" attribute.  Authors should avoid this
-practice since the structural elements of a document language often
-have recognized and accepted meanings and author-defined classes may
-not.</p>
-
-<p class="note"><strong>Note:</strong> If an element has multiple
-class attributes, their values must be concatenated with spaces
-between the values before searching for the class. As of this time the
-working group is not aware of any manner in which this situation can
-be reached, however, so this behavior is explicitly non-normative in
-this specification.</p>
-
-<h3><a name=id-selectors>6.5. ID selectors</a></h3>
-
-<p>Document languages may contain attributes that are declared to be
-of type ID. What makes attributes of type ID special is that no two
-such attributes can have the same value in a document, regardless of
-the type of the elements that carry them; whatever the document
-language, an ID typed attribute can be used to uniquely identify its
-element. In HTML all ID attributes are named "id"; XML applications
-may name ID attributes differently, but the same restriction
-applies.</p>
-
-<p>An ID-typed attribute of a document language allows authors to
-assign an identifier to one element instance in the document tree. W3C
-ID selectors represent an element instance based on its identifier. An
-ID selector contains a &quot;number sign&quot; (U+0023,
-<code>#</code>) immediately followed by the ID value, which must be an
-identifier.</p>
-
-<p>Selectors does not specify how a UA knows the ID-typed attribute of
-an element. The UA may, e.g., read a document's DTD, have the
-information hard-coded or ask the user.
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following ID selector represents an <code>h1</code> element
-  whose ID-typed attribute has the value "chapter1":</p>
-  <pre>h1#chapter1</pre>
-  <p>The following ID selector represents any element whose ID-typed
-  attribute has the value "chapter1":</p>
-  <pre>#chapter1</pre>
-  <p>The following selector represents any element whose ID-typed
-  attribute has the value "z98y".</p>
-  <pre>*#z98y</pre>
-</div>
-
-<p class="note"><strong>Note.</strong> In XML 1.0 <a
-href="#refsXML10">[XML10]</a>, the information about which attribute
-contains an element's IDs is contained in a DTD or a schema. When
-parsing XML, UAs do not always read the DTD, and thus may not know
-what the ID of an element is (though a UA may have namespace-specific
-knowledge that allows it to determine which attribute is the ID
-attribute for that namespace). If a style sheet designer knows or
-suspects that a UA may not know what the ID of an element is, he
-should use normal attribute selectors instead:
-<code>[name=p371]</code> instead of <code>#p371</code>.  Elements in
-XML 1.0 documents without a DTD do not have IDs at all.</p>
-
-<p>If an element has multiple ID attributes, all of them must be
-treated as IDs for that element for the purposes of the ID
-selector. Such a situation could be reached using mixtures of xml:id,
-DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>
-
-<h3><a name=pseudo-classes>6.6. Pseudo-classes</a></h3>
-
-<p>The pseudo-class concept is introduced to permit selection based on
-information that lies outside of the document tree or that cannot be
-expressed using the other simple selectors.</p>
-
-<p>A pseudo-class always consists of a &quot;colon&quot;
-(<code>:</code>) followed by the name of the pseudo-class and
-optionally by a value between parentheses.</p>
-
-<p>Pseudo-classes are allowed in all sequences of simple selectors
-contained in a selector. Pseudo-classes are allowed anywhere in
-sequences of simple selectors, after the leading type selector or
-universal selector (possibly omitted). Pseudo-class names are
-case-insensitive. Some pseudo-classes are mutually exclusive, while
-others can be applied simultaneously to the same
-element. Pseudo-classes may be dynamic, in the sense that an element
-may acquire or lose a pseudo-class while a user interacts with the
-document.</p>
-
-
-<h4><a name=dynamic-pseudos>6.6.1. Dynamic pseudo-classes</a></h4>
-
-<p>Dynamic pseudo-classes classify elements on characteristics other
-than their name, attributes, or content, in principle characteristics
-that cannot be deduced from the document tree.</p>
-
-<p>Dynamic pseudo-classes do not appear in the document source or
-document tree.</p>
-
-
-<h5>The <a name=link>link pseudo-classes: :link and :visited</a></h5>
-
-<p>User agents commonly display unvisited links differently from
-previously visited ones. Selectors
-provides the pseudo-classes <code>:link</code> and
-<code>:visited</code> to distinguish them:</p>
-
-<ul>
-  <li>The <code>:link</code> pseudo-class applies to links that have
-  not yet been visited.</li>
-  <li>The <code>:visited</code> pseudo-class applies once the link has
-  been visited by the user. </li>
-</ul>
-
-<p>After some amount of time, user agents may choose to return a
-visited link to the (unvisited) ':link' state.</p>
-
-<p>The two states are mutually exclusive.</p>
-
-<div class="example">
-
-  <p>Example:</p>
-
-  <p>The following selector represents links carrying class
-  <code>external</code> and already visited:</p>
-
-  <pre>a.external:visited</pre>
-
-</div>
-
-<p class="note"><strong>Note:</strong> It is possible for style sheet
-authors to abuse the :link and :visited pseudo-classes to determine
-which sites a user has visited without the user's consent.
-
-<p>UAs may therefore treat all links as unvisited links, or implement
-other measures to preserve the user's privacy while rendering visited
-and unvisited links differently.</p>
-
-<h5>The <a name=useraction-pseudos>user action pseudo-classes
-:hover, :active, and :focus</a></h5>
-
-<p>Interactive user agents sometimes change the rendering in response
-to user actions. Selectors provides
-three pseudo-classes for the selection of an element the user is
-acting on.</p>
-
-<ul>
-
-  <li>The <code>:hover</code> pseudo-class applies while the user
-  designates an element with a pointing device, but does not activate
-  it. For example, a visual user agent could apply this pseudo-class
-  when the cursor (mouse pointer) hovers over a box generated by the
-  element. User agents not that do not support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> do not have to support this pseudo-class. Some conforming
-  user agents that support <a
-  href="http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group">interactive
-  media</a> may not be able to support this pseudo-class (e.g., a pen
-  device that does not detect hovering).</li>
-
-  <li>The <code>:active</code> pseudo-class applies while an element
-  is being activated by the user. For example, between the times the
-  user presses the mouse button and releases it.</li>
-
-  <li>The <code>:focus</code> pseudo-class applies while an element
-  has the focus (accepts keyboard or mouse events, or other forms of
-  input). </li>
-
-</ul>
-
-<p>There may be document language or implementation specific limits on
-which elements can become <code>:active</code> or acquire
-<code>:focus</code>.</p>
-
-<p>These pseudo-classes are not mutually exclusive. An element may
-match several pseudo-classes at the same time.</p>
-
-<p>Selectors doesn't define if the parent of an element that is
-':active' or ':hover' is also in that state.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <pre>a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */</pre>
-  <p>An example of combining dynamic pseudo-classes:</p>
-  <pre>a:focus
-a:focus:hover</pre>
-  <p>The last selector matches <code>a</code> elements that are in
-  the pseudo-class :focus and in the pseudo-class :hover.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> An element can be both ':visited'
-and ':active' (or ':link' and ':active').</p>
-
-<h4><a name=target-pseudo>6.6.2. The target pseudo-class :target</a></h4>
-
-<p>Some URIs refer to a location within a resource. This kind of URI
-ends with a &quot;number sign&quot; (#) followed by an anchor
-identifier (called the fragment identifier).</p>
-
-<p>URIs with fragment identifiers link to a certain element within the
-document, known as the target element. For instance, here is a URI
-pointing to an anchor named <code>section_2</code> in an HTML
-document:</p>
-
-<pre>http://example.com/html/top.html#section_2</pre>
-
-<p>A target element can be represented by the <code>:target</code>
-pseudo-class. If the document's URI has no fragment identifier, then
-the document has no target element.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>p.note:target</pre>
- <p>This selector represents a <code>p</code> element of class
- <code>note</code> that is the target element of the referring
- URI.</p>
-</div>
-
-<div class="example">
- <p>CSS example:</p>
- <p>Here, the <code>:target</code> pseudo-class is used to make the
- target element red and place an image before it, if there is one:</p>
- <pre>*:target { color : red }
-*:target::before { content : url(target.png) }</pre>
-</div>
-
-<h4><a name=lang-pseudo>6.6.3. The language pseudo-class :lang</a></h4>
-
-<p>If the document language specifies how the human language of an
-element is determined, it is possible to write selectors that
-represent an element based on its language. For example, in HTML <a
-href="#refsHTML4">[HTML4]</a>, the language is determined by a
-combination of the <code>lang</code> attribute, the <code>meta</code>
-element, and possibly by information from the protocol (such as HTTP
-headers). XML uses an attribute called <code>xml:lang</code>, and
-there may be other document language-specific methods for determining
-the language.</p>
-
-<p>The pseudo-class <code>:lang(C)</code> represents an element that
-is in language C. Whether an element is represented by a
-<code>:lang()</code> selector is based solely on the identifier C
-being either equal to, or a hyphen-separated substring of, the
-element's language value, in the same way as if performed by the <a
-href="#attribute-representation">'|='</a> operator in attribute
-selectors. The identifier C does not have to be a valid language
-name.</p>
-
-<p>C must not be empty. (If it is, the selector is invalid.)</p>
-
-<p class="note"><strong>Note:</strong> It is recommended that
-documents and protocols indicate language using codes from RFC 3066 <a
-href="#refsRFC3066">[RFC3066]</a> or its successor, and by means of
-"xml:lang" attributes in the case of XML-based documents <a
-href="#refsXML10">[XML10]</a>. See <a
-href="http://www.w3.org/International/questions/qa-lang-2or3.html">
-"FAQ: Two-letter or three-letter language codes."</a></p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The two following selectors represent an HTML document that is in
-  Belgian, French, or German. The two next selectors represent
-  <code>q</code> quotations in an arbitrary element in Belgian, French,
-  or German.</p>
-  <pre>html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) &gt; q
-:lang(de) &gt; q</pre>
-</div>
-
-<h4><a name=UIstates>6.6.4. The UI element states pseudo-classes</a></h4>
-
-<h5><a name=enableddisabled>The :enabled and :disabled pseudo-classes</a></h5>
-
-<p>The <code>:enabled</code> pseudo-class allows authors to customize
-the look of user interface elements that are enabled &mdash; which the
-user can select or activate in some fashion (e.g. clicking on a button
-with a mouse).  There is a need for such a pseudo-class because there
-is no way to programmatically specify the default appearance of say,
-an enabled <code>input</code> element without also specifying what it
-would look like when it was disabled.</p>
-
-<p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the
-author to specify precisely how a disabled or inactive user interface
-element should look.</p>
-
-<p>Most elements will be neither enabled nor disabled.  An element is
-enabled if the user can either activate it or transfer the focus to
-it. An element is disabled if it could be enabled, but the user cannot
-presently activate it or transfer focus to it.</p>
-
-
-<h5><a name=checked>The :checked pseudo-class</a></h5>
-
-<p>Radio and checkbox elements can be toggled by the user. Some menu
-items are "checked" when the user selects them. When such elements are
-toggled "on" the <code>:checked</code> pseudo-class applies. The
-<code>:checked</code> pseudo-class initially applies to such elements
-that have the HTML4 <code>selected</code> and <code>checked</code>
-attributes as described in <a
-href="http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1">Section
-17.2.1 of HTML4</a>, but of course the user can toggle "off" such
-elements in which case the <code>:checked</code> pseudo-class would no
-longer apply. While the <code>:checked</code> pseudo-class is dynamic
-in nature, and is altered by user action, since it can also be based
-on the presence of the semantic HTML4 <code>selected</code> and
-<code>checked</code> attributes, it applies to all media.
-
-
-<h5><a name=indeterminate>The :indeterminate pseudo-class</a></h5>
-
-<div class="note">
-
-<p>Radio and checkbox elements can be toggled by the user, but are
-sometimes in an indeterminate state, neither checked nor unchecked.
-This can be due to an element attribute, or DOM manipulation.</p>
-
-<p>A future version of this specification may introduce an
-<code>:indeterminate</code> pseudo-class that applies to such elements.
-<!--While the <code>:indeterminate</code> pseudo-class is dynamic in
-nature, and is altered by user action, since it can also be based on
-the presence of an element attribute, it applies to all media.</p>
-
-<p>Components of a radio-group initialized with no pre-selected choice
-are an example of :indeterminate state.--></p>
-
-</div>
-
-
-<h4><a name=structural-pseudos>6.6.5. Structural pseudo-classes</a></h4>
-
-<p>Selectors introduces the concept of <dfn>structural
-pseudo-classes</dfn> to permit selection based on extra information that lies in
-the document tree but cannot be represented by other simple selectors or
-combinators.
-
-<p>Note that standalone pieces of PCDATA (text nodes in the DOM) are
-not counted when calculating the position of an element in the list of
-children of its parent. When calculating the position of an element in
-the list of children of its parent, the index numbering starts at 1.
-
-
-<h5><a name=root-pseudo>:root pseudo-class</a></h5>
-
-<p>The <code>:root</code> pseudo-class represents an element that is
-the root of the document. In HTML 4, this is always the
-<code>HTML</code> element.
-
-
-<h5><a name=nth-child-pseudo>:nth-child() pseudo-class</a></h5>
-
-<p>The
-<code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>before</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. In
-other words, this matches the <var>b</var>th child of an element after
-all the children have been split into groups of <var>a</var> elements
-each. For example, this allows the selectors to address every other
-row in a table, and could be used to alternate the color
-of paragraph text in a cycle of four. The <var>a</var> and
-<var>b</var> values must be zero, negative integers or positive
-integers. The index of the first child of an element is 1.
-
-<p>In addition to this, <code>:nth-child()</code> can take
-'<code>odd</code>' and '<code>even</code>' as arguments instead.
-'<code>odd</code>' has the same signification as <code>2n+1</code>,
-and '<code>even</code>' has the same signification as <code>2n</code>.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }</pre>
-</div>
-
-<p>When <var>a</var>=0, no repeating is used, so for example
-<code>:nth-child(0n+5)</code> matches only the fifth child. When
-<var>a</var>=0, the <var>a</var><code>n</code> part need not be
-included, so the syntax simplifies to
-<code>:nth-child(<var>b</var>)</code> and the last example simplifies
-to <code>:nth-child(5)</code>.
-
-<div class="example">
-<p>Examples:</p>
-<pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */</pre>
-</div>
-
-<p>When <var>a</var>=1, the number may be omitted from the rule.
-
-<div class="example">
-<p>Examples:</p>
-<p>The following selectors are therefore equivalent:</p>
-<pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */</pre>
-</div>
-
-<p>If <var>b</var>=0, then every <var>a</var>th element is picked. In
-such a case, the <var>b</var> part may be omitted.
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */</pre>
-</div>
-
-<p>If both <var>a</var> and <var>b</var> are equal to zero, the
-pseudo-class represents no element in the document tree.</p>
-
-<p>The value <var>a</var> can be negative, but only the positive
-values of <var>a</var><code>n</code>+<var>b</var>, for
-<code>n</code>&ge;0, may represent an element in the document
-tree.</p>
-
-<div class="example">
-<p>Example:</p>
-<pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>
-</div>
-
-<p>When the value <var>b</var> is negative, the "+" character in the
-expression must be removed (it is effectively replaced by the "-"
-character indicating the negative value of <var>b</var>).</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>
-</div>
-
-
-<h5><a name=nth-last-child-pseudo>:nth-last-child() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings
-<strong>after</strong> it in the document tree, for a given positive
-integer or zero value of <code>n</code>, and has a parent element. See
-<code>:nth-child()</code> pseudo-class for the syntax of its argument.
-It also accepts the '<code>even</code>' and '<code>odd</code>' values
-as arguments.
-
-
-<div class="example">
-<p>Examples:</p>
-<pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */</pre>
-</div>
-
-
-<h5><a name=nth-of-type-pseudo>:nth-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>before</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. In other words, this matches the <var>b</var>th child
-of that type after all the children of that type have been split into
-groups of a elements each. See <code>:nth-child()</code> pseudo-class
-for the syntax of its argument. It also accepts the
-'<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
-<p>CSS example:</p>
-<p>This allows an author to alternate the position of floated images:</p>
-<pre>img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }</pre>
-</div>
-
-
-<h5><a name=nth-last-of-type-pseudo>:nth-last-of-type() pseudo-class</a></h5>
-
-<p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>
-pseudo-class notation represents an element that has
-<var>a</var><code>n</code>+<var>b</var>-1 siblings with the same
-element name <strong>after</strong> it in the document tree, for a
-given zero or positive integer value of <code>n</code>, and has a
-parent element. See <code>:nth-child()</code> pseudo-class for the
-syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>' values.
-
-
-<div class="example">
- <p>Example:</p>
- <p>To represent all <code>h2</code> children of an XHTML
- <code>body</code> except the first and last, one could use the
- following selector:</p>
- <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>
- <p>In this case, one could also use <code>:not()</code>, although the
- selector ends up being just as long:</p>
- <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>
-</div>
-
-
-<h5><a name=first-child-pseudo>:first-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code> pseudo-class
-represents an element that is the first child of some other element.
-
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following selector represents a <code>p</code> element that is
-  the first child of a <code>div</code> element:</p>
-  <pre>div &gt; p:first-child</pre>
-  <p>This selector can represent the <code>p</code> inside the
-  <code>div</code> of the following fragment:</p>
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>but cannot represent the second <code>p</code> in the following
-fragment:
-  <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;
-&lt;div class="note"&gt;
-   &lt;h2&gt; Note &lt;/h2&gt;
-   &lt;p&gt; The first P inside the note.&lt;/p&gt;
-&lt;/div&gt;</pre>
-  <p>The following two selectors are usually equivalent:</p>
-  <pre>* &gt; a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */</pre>
-</div>
-
-<h5><a name=last-child-pseudo>:last-child pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code> pseudo-class
-represents an element that is the last child of some other element.
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents a list item <code>li</code> that
- is the last child of an ordered list <code>ol</code>.
- <pre>ol &gt; li:last-child</pre>
-</div>
-
-<h5><a name=first-of-type-pseudo>:first-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code> pseudo-class
-represents an element that is the first sibling of its type in the list of
-children of its parent element.
-
-<div class="example">
-<p>Example:</p>
-<p>The following selector represents a definition title
-<code>dt</code> inside a definition list <code>dl</code>, this
-<code>dt</code> being the first of its type in the list of children of
-its parent element.</p>
-<pre>dl dt:first-of-type</pre>
-<p>It is a valid description for the first two <code>dt</code>
-elements in the following example but not for the third one:</p>
-<pre>&lt;dl&gt;
- &lt;dt&gt;gigogne&lt;/dt&gt;
- &lt;dd&gt;
-  &lt;dl&gt;
-   &lt;dt&gt;fus&eacute;e&lt;/dt&gt;
-   &lt;dd&gt;multistage rocket&lt;/dd&gt;
-   &lt;dt&gt;table&lt;/dt&gt;
-   &lt;dd&gt;nest of tables&lt;/dd&gt;
-  &lt;/dl&gt;
- &lt;/dd&gt;
-&lt;/dl&gt;</pre>
-</div>
-
-<h5><a name=last-of-type-pseudo>:last-of-type pseudo-class</a></h5>
-
-<p>Same as <code>:nth-last-of-type(1)</code>. The
-<code>:last-of-type</code> pseudo-class represents an element that is
-the last sibling of its type in the list of children of its parent
-element.</p>
-
-<div class="example">
- <p>Example:</p>
- <p>The following selector represents the last data cell
- <code>td</code> of a table row.</p>
- <pre>tr &gt; td:last-of-type</pre>
-</div>
-
-<h5><a name=only-child-pseudo>:only-child pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children. Same as
-<code>:first-child:last-child</code> or
-<code>:nth-child(1):nth-last-child(1)</code>, but with a lower
-specificity.</p>
-
-<h5><a name=only-of-type-pseudo>:only-of-type pseudo-class</a></h5>
-
-<p>Represents an element that has a parent element and whose parent
-element has no other element children with the same element name. Same
-as <code>:first-of-type:last-of-type</code> or
-<code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower
-specificity.</p>
-
-
-<h5><a name=empty-pseudo></a>:empty pseudo-class</h5>
-
-<p>The <code>:empty</code> pseudo-class represents an element that has
-no children at all. In terms of the DOM, only element nodes and text
-nodes (including CDATA nodes and entity references) whose data has a
-non-zero length must be considered as affecting emptiness; comments,
-PIs, and other nodes must not affect whether an element is considered
-empty or not.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p><code>p:empty</code> is a valid representation of the following fragment:</p>
- <pre>&lt;p&gt;&lt;/p&gt;</pre>
- <p><code>foo:empty</code> is not a valid representation for the
- following fragments:</p>
- <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>
- <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>
-</div>
-
-<h4><a name=content-selectors>6.6.6. Blank</a></h4> <!-- It's the Return of Appendix H!!! Run away! -->
-
-<p>This section intentionally left blank.</p>
-<!-- (used to be :contains()) -->
-
-<h4><a name=negation></a>6.6.7. The negation pseudo-class</h4>
-
-<p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a
-functional notation taking a <a href="#simple-selectors-dfn">simple
-selector</a> (excluding the negation pseudo-class itself and
-pseudo-elements) as an argument. It represents an element that is not
-represented by the argument.
-
-<!-- pseudo-elements are not simple selectors, so the above paragraph
-may be a bit confusing -->
-
-<div class="example">
-  <p>Examples:</p>
-  <p>The following CSS selector matches all <code>button</code>
-  elements in an HTML document that are not disabled.</p>
-  <pre>button:not([DISABLED])</pre>
-  <p>The following selector represents all but <code>FOO</code>
-  elements.</p>
-  <pre>*:not(FOO)</pre>
-  <p>The following group of selectors represents all HTML elements
-  except links.</p>
-  <pre>html|*:not(:link):not(:visited)</pre>
-</div>
-
-<p>Default namespace declarations do not affect the argument of the
-negation pseudo-class unless the argument is a universal selector or a
-type selector.</p>
-
-<div class="example">
-  <p>Examples:</p>
-  <p>Assuming that the default namespace is bound to
-  "http://example.com/", the following selector represents all
-  elements that are not in that namespace:</p>
-  <pre>*|*:not(*)</pre>
-  <p>The following CSS selector matches any element being hovered,
-  regardless of its namespace. In particular, it is not limited to
-  only matching elements in the default namespace that are not being
-  hovered, and elements not in the default namespace don't match the
-  rule when they <em>are</em> being hovered.</p>
-  <pre>*|*:not(:hover)</pre>
-</div>
-
-<p class="note"><strong>Note</strong>: the :not() pseudo allows
-useless selectors to be written.  For instance <code>:not(*|*)</code>,
-which represents no element at all, or <code>foo:not(bar)</code>,
-which is equivalent to <code>foo</code> but with a higher
-specificity.</p>
-
-<h3><a name=pseudo-elements>7. Pseudo-elements</a></h3>
-
-<p>Pseudo-elements create abstractions about the document tree beyond
-those specified by the document language. For instance, document
-languages do not offer mechanisms to access the first letter or first
-line of an element's content. Pseudo-elements allow designers to refer
-to this otherwise inaccessible information. Pseudo-elements may also
-provide designers a way to refer to content that does not exist in the
-source document (e.g., the <code>::before</code> and
-<code>::after</code> pseudo-elements give access to generated
-content).</p>
-
-<p>A pseudo-element is made of two colons (<code>::</code>) followed
-by the name of the pseudo-element.</p>
-
-<p>This <code>::</code> notation is introduced by the current document
-in order to establish a discrimination between pseudo-classes and
-pseudo-elements.  For compatibility with existing style sheets, user
-agents must also accept the previous one-colon notation for
-pseudo-elements introduced in CSS levels 1 and 2 (namely,
-<code>:first-line</code>, <code>:first-letter</code>,
-<code>:before</code> and <code>:after</code>). This compatibility is
-not allowed for the new pseudo-elements introduced in CSS level 3.</p>
-
-<p>Only one pseudo-element may appear per selector, and if present it
-must appear after the sequence of simple selectors that represents the
-<a href="#subject">subjects</a> of the selector. <span class="note">A
-future version of this specification may allow multiple
-pesudo-elements per selector.</span></p>
-
-<h4><a name=first-line>7.1. The ::first-line pseudo-element</a></h4>
-
-<p>The <code>::first-line</code> pseudo-element describes the contents
-of the first formatted line of an element.
-
-<div class="example">
-<p>CSS example:</p>
-<pre>p::first-line { text-transform: uppercase }</pre>
-<p>The above rule means "change the letters of the first line of every
-paragraph to uppercase".</p>
-</div>
-
-<p>The selector <code>p::first-line</code> does not match any real
-HTML element. It does match a pseudo-element that conforming user
-agents will insert at the beginning of every paragraph.</p>
-
-<p>Note that the length of the first line depends on a number of
-factors, including the width of the page, the font size, etc.  Thus,
-an ordinary HTML paragraph such as:</p>
-
-<pre>
-&lt;P&gt;This is a somewhat long HTML
-paragraph that will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the lines of which happen to be broken as follows:
-
-<pre>
-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag
-sequence. The other lines will be treated as
-ordinary lines in the paragraph.
-</pre>
-
-<p>This paragraph might be "rewritten" by user agents to include the
-<em>fictional tag sequence</em> for <code>::first-line</code>. This
-fictional tag sequence helps to show how properties are inherited.</p>
-
-<pre>
-&lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML
-paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several
-lines. The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>If a pseudo-element breaks up a real element, the desired effect
-can often be described by a fictional tag sequence that closes and
-then re-opens the element. Thus, if we mark up the previous paragraph
-with a <code>span</code> element:</p>
-
-<pre>
-&lt;P&gt;<b>&lt;SPAN class="test"&gt;</b> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>the user agent could simulate start and end tags for
-<code>span</code> when inserting the fictional tag sequence for
-<code>::first-line</code>.
-
-<pre>
-&lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> This is a
-somewhat long HTML
-paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN class="test"&gt;</b> be
-broken into several
-lines.<b>&lt;/SPAN&gt;</b> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the
-paragraph.&lt;/P&gt;
-</pre>
-
-<p>In CSS, the <code>::first-line</code> pseudo-element can only be
-attached to a block-level element, an inline-block, a table-caption,
-or a table-cell.</p>
-
-<p><a name="first-formatted-line"></a>The "first formatted line" of an
-element may occur inside a
-block-level descendant in the same flow (i.e., a block-level
-descendant that is not positioned and not a float). E.g., the first
-line of the <code>div</code> in <code>&lt;DIV>&lt;P>This
-line...&lt;/P>&lt/DIV></code> is the first line of the <code>p</code> (assuming
-that both <code>p</code> and <code>div</code> are block-level).
-
-<p>The first line of a table-cell or inline-block cannot be the first
-formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first formatted line of the
-<code>div</code> is not the line "Hello".
-
-<p class="note">Note that the first line of the <code>p</code> in this
-fragment: <code>&lt;p&gt&lt;br&gt;First...</code> doesn't contain any
-letters (assuming the default style for <code>br</code> in HTML
-4). The word "First" is not on the first formatted line.
-
-<p>A UA should act as if the fictional start tags of the
-<code>::first-line</code> pseudo-elements were nested just inside the
-innermost enclosing block-level element. (Since CSS1 and CSS2 were
-silent on this case, authors should not rely on this behavior.) Here
-is an example. The fictional tag sequence for</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>First paragraph&lt;/P>
-  &lt;P>Second paragraph&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>is</p>
-
-<pre>
-&lt;DIV>
-  &lt;P>&lt;DIV::first-line>&lt;P::first-line>First paragraph&lt;/P::first-line>&lt;/DIV::first-line>&lt;/P>
-  &lt;P>&lt;P::first-line>Second paragraph&lt;/P::first-line>&lt;/P>
-&lt;/DIV>
-</pre>
-
-<p>The <code>::first-line</code> pseudo-element is similar to an
-inline-level element, but with certain restrictions. In CSS, the
-following properties apply to a <code>::first-line</code>
-pseudo-element: font properties, color property, background
-properties, 'word-spacing', 'letter-spacing', 'text-decoration',
-'vertical-align', 'text-transform', 'line-height'. UAs may apply other
-properties as well.</p>
-
-
-<h4><a name=first-letter>7.2. The ::first-letter pseudo-element</a></h4>
-
-<p>The <code>::first-letter</code> pseudo-element represents the first
-letter of the first line of a block, if it is not preceded by any
-other content (such as images or inline tables) on its line. The
-::first-letter pseudo-element may be used for "initial caps" and "drop
-caps", which are common typographical effects. This type of initial
-letter is similar to an inline-level element if its 'float' property
-is 'none'; otherwise, it is similar to a floated element.</p>
-
-<p>In CSS, these are the properties that apply to <code>::first-letter</code>
-pseudo-elements: font properties, 'text-decoration', 'text-transform',
-'letter-spacing', 'word-spacing' (when appropriate), 'line-height',
-'float', 'vertical-align' (only if 'float' is 'none'), margin
-properties, padding properties, border properties, color property,
-background properties.  UAs may apply other properties as well.  To
-allow UAs to render a typographically correct drop cap or initial cap,
-the UA may choose a line-height, width and height based on the shape
-of the letter, unlike for normal elements.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>This example shows a possible rendering of an initial cap. Note
-that the 'line-height' that is inherited by the <code>::first-letter</code>
-pseudo-element is 1.1, but the UA in this example has computed the
-height of the first letter differently, so that it doesn't cause any
-unnecessary space between the first two lines. Also note that the
-fictional start tag of the first letter is inside the <span>span</span>, and thus
-the font weight of the first letter is normal, not bold as the <span>span</span>:
-<pre>
-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-&lt;p>&lt;span>Het hemelsche&lt;/span> gerecht heeft zich ten lange lesten&lt;br>
-Erbarremt over my en mijn benaeuwde vesten&lt;br>
-En arme burgery, en op mijn volcx gebed&lt;br>
-En dagelix geschrey de bange stad ontzet.
-</pre>
-<div class="figure">
-<p><img src="initial-cap.png" alt="Image illustrating the ::first-letter pseudo-element">
-</div>
-</div>
-
-<div class="example">
-<p>The following CSS will make a drop cap initial letter span about two lines:</p>
-
-<pre>
-&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"&gt;
-&lt;HTML&gt;
- &lt;HEAD&gt;
-  &lt;TITLE&gt;Drop cap initial letter&lt;/TITLE&gt;
-  &lt;STYLE type="text/css"&gt;
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  &lt;/STYLE&gt;
- &lt;/HEAD&gt;
- &lt;BODY&gt;
-  &lt;P&gt;&lt;SPAN&gt;The first&lt;/SPAN&gt; few words of an article
-    in The Economist.&lt;/P&gt;
- &lt;/BODY&gt;
-&lt;/HTML&gt;
-</pre>
-
-<p>This example might be formatted as follows:</p>
-
-<div class="figure">
-<P><img src="first-letter.gif" alt="Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"></p>
-</div>
-
-<p>The <span class="index-inst" title="fictional tag
-sequence">fictional tag sequence</span> is:</p>
-
-<pre>
-&lt;P&gt;
-&lt;SPAN&gt;
-&lt;P::first-letter&gt;
-T
-&lt;/P::first-letter&gt;he first
-&lt;/SPAN&gt;
-few words of an article in the Economist.
-&lt;/P&gt;
-</pre>
-
-<p>Note that the <code>::first-letter</code> pseudo-element tags abut
-the content (i.e., the initial character), while the ::first-line
-pseudo-element start tag is inserted right after the start tag of the
-block element.</p> </div>
-
-<p>In order to achieve traditional drop caps formatting, user agents
-may approximate font sizes, for example to align baselines. Also, the
-glyph outline may be taken into account when formatting.</p>
-
-<p>Punctuation (i.e, characters defined in Unicode in the "open" (Ps),
-"close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po)
-punctuation classes), that precedes or follows the first letter should
-be included. <a href="#refsUNICODE">[UNICODE]</a></p>
-
-<div class="figure">
-<P><img src="first-letter2.gif" alt="Quotes that precede the
-first letter should be included."></p>
-</div>
-
-<p>The <code>::first-letter</code> also applies if the first letter is
-in fact a digit, e.g., the "6" in "67 million dollars is a lot of
-money."</p>
-
-<p>In CSS, the <code>::first-letter</code> pseudo-element applies to
-block, list-item, table-cell, table-caption, and inline-block
-elements. <span class="note">A future version of this specification
-may allow this pesudo-element to apply to more element
-types.</span></p>
-
-<p>The <code>::first-letter</code> pseudo-element can be used with all
-such elements that contain text, or that have a descendant in the same
-flow that contains text. A UA should act as if the fictional start tag
-of the ::first-letter pseudo-element is just before the first text of
-the element, even if that first text is in a descendant.</p>
-
-<div class="example">
-<p>Example:</p>
-<p>The fictional tag sequence for this HTMLfragment:
-<pre>&lt;div>
-&lt;p>The first text.</pre>
-<p>is:
-<pre>&lt;div>
-&lt;p>&lt;div::first-letter>&lt;p::first-letter>T&lt;/...>&lt;/...>he first text.</pre>
-</div>
-
-<p>The first letter of a table-cell or inline-block cannot be the
-first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P
-STYLE="display: inline-block">Hello&lt;BR&gt;Goodbye&lt;/P&gt;
-etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is not the
-letter "H". In fact, the <code>div</code> doesn't have a first letter.
-
-<p>The first letter must occur on the <a
-href="#first-formatted-line">first formatted line.</a> For example, in
-this fragment: <code>&lt;p&gt&lt;br&gt;First...</code> the first line
-doesn't contain any letters and <code>::first-letter</code> doesn't
-match anything (assuming the default style for <code>br</code> in HTML
-4). In particular, it does not match the "F" of "First."
-
-<p>In CSS, if an element is a list item ('display: list-item'), the
-<code>::first-letter</code> applies to the first letter in the
-principal box after the marker. UAs may ignore
-<code>::first-letter</code> on list items with 'list-style-position:
-inside'. If an element has <code>::before</code> or
-<code>::after</code> content, the <code>::first-letter</code> applies
-to the first letter of the element <em>including</em> that content.
-
-<div class="example">
-<p>Example:</p>
-<p>After the rule 'p::before {content: "Note: "}', the selector
-'p::first-letter' matches the "N" of "Note".</p>
-</div>
-
-<p>Some languages may have specific rules about how to treat certain
-letter combinations. In Dutch, for example, if the letter combination
-"ij" appears at the beginning of a word, both letters should be
-considered within the <code>::first-letter</code> pseudo-element.
-
-<p>If the letters that would form the ::first-letter are not in the
-same element, such as "'T" in <code>&lt;p>'&lt;em>T...</code>, the UA
-may create a ::first-letter pseudo-element from one of the elements,
-both elements, or simply not create a pseudo-element.</p>
-
-<p>Similarly, if the first letter(s) of the block are not at the start
-of the line (for example due to bidirectional reordering), then the UA
-need not create the pseudo-element(s).
-
-<div class="example">
-<p>Example:</p>
-<p><a name="overlapping-example">The following example</a> illustrates
-how overlapping pseudo-elements may interact.  The first letter of
-each P element will be green with a font size of '24pt'. The rest of
-the first formatted line will be 'blue' while the rest of the
-paragraph will be 'red'.</p>
-
-<pre>p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-&lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>
-
-<p>Assuming that a line break will occur before the word "ends", the
-<span class="index-inst" title="fictional tag sequence">fictional tag
-sequence</span> for this fragment might be:</p>
-
-<pre>&lt;P&gt;
-&lt;P::first-line&gt;
-&lt;P::first-letter&gt;
-S
-&lt;/P::first-letter&gt;ome text that
-&lt;/P::first-line&gt;
-ends up on two lines
-&lt;/P&gt;</pre>
-
-<p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>
-element.  Properties set on <code>::first-line</code> are inherited by
-<code>::first-letter</code>, but are overridden if the same property is set on
-<code>::first-letter</code>.</p>
-</div>
-
-
-<h4><a name=UIfragments>7.3.</a> <a name=selection>The ::selection pseudo-element</a></h4>
-
-<p>The <code>::selection</code> pseudo-element applies to the portion
-of a document that has been highlighted by the user. This also
-applies, for example, to selected text within an editable text
-field. This pseudo-element should not be confused with the <code><a
-href="#checked">:checked</a></code> pseudo-class (which used to be
-named <code>:selected</code>)
-
-<p>Although the <code>::selection</code> pseudo-element is dynamic in
-nature, and is altered by user action, it is reasonable to expect that
-when a UA re-renders to a static medium (such as a printed page, see
-<a href="#refsCSS21">[CSS21]</a>) which was originally rendered to a
-dynamic medium (like screen), the UA may wish to transfer the current
-<code>::selection</code> state to that other medium, and have all the
-appropriate formatting and rendering take effect as well. This is not
-required &mdash; UAs may omit the <code>::selection</code>
-pseudo-element for static media.
-
-<p>These are the CSS properties that apply to <code>::selection</code>
-pseudo-elements: color, background, cursor (optional), outline
-(optional). The computed value of the 'background-image' property on
-<code>::selection</code> may be ignored.
-
-
-<h4><a name=gen-content>7.4. The ::before and ::after pseudo-elements</a></h4>
-
-<p>The <code>::before</code> and <code>::after</code> pseudo-elements
-can be used to describe generated content before or after an element's
-content. They are explained in CSS 2.1 <a
-href="#refsCSS21">[CSS21]</a>.</p>
-
-<p>When the <code>::first-letter</code> and <code>::first-line</code>
-pseudo-elements are combined with <code>::before</code> and
-<code>::after</code>, they apply to the first letter or line of the
-element including the inserted text.</p>
-
-<h2><a name=combinators>8. Combinators</a></h2>
-
-<h3><a name=descendant-combinators>8.1. Descendant combinator</a></h3>
-
-<p>At times, authors may want selectors to describe an element that is
-the descendant of another element in the document tree (e.g., "an
-<code>EM</code> element that is contained within an <code>H1</code>
-element"). Descendant combinators express such a relationship. A
-descendant combinator is <a href="#whitespace">white space</a> that
-separates two sequences of simple selectors.  A selector of the form
-"<code>A B</code>" represents an element <code>B</code> that is an
-arbitrary descendant of some ancestor element <code>A</code>.
-
-<div class="example">
- <p>Examples:</p>
- <p>For example, consider the following selector:</p>
- <pre>h1 em</pre>
- <p>It represents an <code>em</code> element being the descendant of
- an <code>h1</code> element. It is a correct and valid, but partial,
- description of the following fragment:</p>
- <pre>&lt;h1&gt;This &lt;span class="myclass"&gt;headline
-is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>
- <p>The following selector:</p>
- <pre>div * p</pre>
- <p>represents a <code>p</code> element that is a grandchild or later
- descendant of a <code>div</code> element. Note the whitespace on
- either side of the "*" is not part of the universal selector; the
- whitespace is a combinator indicating that the DIV must be the
- ancestor of some element, and that that element must be an ancestor
- of the P.</p>
- <p>The following selector, which combines descendant combinators and
- <a href="#attribute-selectors">attribute selectors</a>, represents an
- element that (1) has the <code>href</code> attribute set and (2) is
- inside a <code>p</code> that is itself inside a <code>div</code>:</p>
- <pre>div p *[href]</pre>
-</div>
-
-<h3><a name=child-combinators>8.2. Child combinators</a></h3>
-
-<p>A <dfn>child combinator</dfn> describes a childhood relationship
-between two elements. A child combinator is made of the
-&quot;greater-than sign&quot; (<code>&gt;</code>) character and
-separates two sequences of simple selectors.
-
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element that is
- child of <code>body</code>:</p>
- <pre>body &gt; p</pre>
- <p>The following example combines descendant combinators and child
- combinators.</p>
- <pre>div ol&gt;li p</pre><!-- LEAVE THOSE SPACES OUT! see below -->
- <p>It represents a <code>p</code> element that is a descendant of an
- <code>li</code> element; the <code>li</code> element must be the
- child of an <code>ol</code> element; the <code>ol</code> element must
- be a descendant of a <code>div</code>. Notice that the optional white
- space around the "&gt;" combinator has been left out.</p>
-</div>
-
-<p>For information on selecting the first child of an element, please
-see the section on the <code><a
-href="#structural-pseudos">:first-child</a></code> pseudo-class
-above.</p>
-
-<h3><a name=sibling-combinators>8.3. Sibling combinators</a></h3>
-
-<p>There are two different sibling combinators: the adjacent sibling
-combinator and the general sibling combinator. In both cases,
-non-element nodes (e.g. text between elements) are ignored when
-considering adjacency of elements.</p>
-
-<h4><a name=adjacent-sibling-combinators>8.3.1. Adjacent sibling combinator</a></h4>
-
-<p>The adjacent sibling combinator is made of the &quot;plus
-sign&quot; (U+002B, <code>+</code>) character that separates two
-sequences of simple selectors. The elements represented by the two
-sequences share the same parent in the document tree and the element
-represented by the first sequence immediately precedes the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Examples:</p>
- <p>The following selector represents a <code>p</code> element
- immediately following a <code>math</code> element:</p>
- <pre>math + p</pre>
- <p>The following selector is conceptually similar to the one in the
- previous example, except that it adds an attribute selector &mdash; it
- adds a constraint to the <code>h1</code> element, that it must have
- <code>class="opener"</code>:</p>
- <pre>h1.opener + h2</pre>
-</div>
-
-
-<h4><a name=general-sibling-combinators>8.3.2. General sibling combinator</a></h4>
-
-<p>The general sibling combinator is made of the &quot;tilde&quot;
-(U+007E, <code>~</code>) character that separates two sequences of
-simple selectors. The elements represented by the two sequences share
-the same parent in the document tree and the element represented by
-the first sequence precedes (not necessarily immediately) the element
-represented by the second one.</p>
-
-<div class="example">
- <p>Example:</p>
- <pre>h1 ~ pre</pre>
- <p>represents a <code>pre</code> element following an <code>h1</code>. It
- is a correct and valid, but partial, description of:</p>
- <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;
-&lt;p&gt;Function a(x) has to be applied to all figures in the table.&lt;/p&gt;
-&lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>
-</div>
-
-<h2><a name=specificity>9. Calculating a selector's specificity</a></h2>
-
-<p>A selector's specificity is calculated as follows:</p>
-
-<ul>
-  <li>count the number of ID selectors in the selector (= a)</li>
-  <li>count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)</li>
-  <li>count the number of element names in the selector (= c)</li>
-  <li>ignore pseudo-elements</li>
-</ul>
-
-<p>Selectors inside <a href="#negation">the negation pseudo-class</a>
-are counted like any other, but the negation itself does not count as
-a pseudo-class.</p>
-
-<p>Concatenating the three numbers a-b-c (in a number system with a
-large base) gives the specificity.</p>
-
-<div class="example">
-<p>Examples:</p>
-<pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */
-LI              /* a=0 b=0 c=1 -&gt; specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -&gt; specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -&gt; specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -&gt; specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -&gt; specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -&gt; specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -&gt; specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -&gt; specificity = 101 */
-</pre>
-</div>
-
-<p class="note"><strong>Note:</strong> the specificity of the styles
-specified in an HTML <code>style</code> attribute is described in CSS
-2.1. <a href="#refsCSS21">[CSS21]</a>.</p>
-
-<h2><a name=w3cselgrammar>10. The grammar of Selectors</a></h2>
-
-<h3><a name=grammar>10.1. Grammar</a></h3>
-
-<p>The grammar below defines the syntax of Selectors.  It is globally
-LL(1) and can be locally LL(2) (but note that most UA's should not use
-it directly, since it doesn't express the parsing conventions). The
-format of the productions is optimized for human consumption and some
-shorthand notations beyond Yacc (see <a href="#refsYACC">[YACC]</a>)
-are used:</p>
-
-<ul>
-  <li><b>*</b>: 0 or more
-  <li><b>+</b>: 1 or more
-  <li><b>?</b>: 0 or 1
-  <li><b>|</b>: separates alternatives
-  <li><b>[ ]</b>: grouping </li>
-</ul>
-
-<p>The productions are:</p>
-
-<pre>selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;</pre>
-
-
-<h3><a name=lex>10.2. Lexical scanner</a></h3>
-
-<p>The following is the <a name=x3>tokenizer</a>, written in Flex (see
-<a href="#refsFLEX">[FLEX]</a>) notation. The tokenizer is
-case-insensitive.</p>
-
-<p>The two occurrences of "\377" represent the highest character
-number that current versions of Flex can deal with (decimal 255). They
-should be read as "\4177777" (decimal 1114111), which is the highest
-possible code point in Unicode/ISO-10646. <a
-href="#refsUNICODE">[UNICODE]</a></p>
-
-<pre>%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}"&gt;"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"&lt;!--"           return CDO;
-"--&gt;"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;</pre>
-
-
-
-<h2><a name=downlevel>11. Namespaces and down-level clients</a></h2>
-
-<p>An important issue is the interaction of CSS selectors with XML
-documents in web clients that were produced prior to this
-document. Unfortunately, due to the fact that namespaces must be
-matched based on the URI which identifies the namespace, not the
-namespace prefix, some mechanism is required to identify namespaces in
-CSS by their URI as well. Without such a mechanism, it is impossible
-to construct a CSS style sheet which will properly match selectors in
-all cases against a random set of XML documents. However, given
-complete knowledge of the XML document to which a style sheet is to be
-applied, and a limited use of namespaces within the XML document, it
-is possible to construct a style sheet in which selectors would match
-elements and attributes correctly.</p>
-
-<p>It should be noted that a down-level CSS client will (if it
-properly conforms to CSS forward compatible parsing rules) ignore all
-<code>@namespace</code> at-rules, as well as all style rules that make
-use of namespace qualified element type or attribute selectors. The
-syntax of delimiting namespace prefixes in CSS was deliberately chosen
-so that down-level CSS clients would ignore the style rules rather
-than possibly match them incorrectly.</p>
-
-<p>The use of default namespaces in CSS makes it possible to write
-element type selectors that will function in both namespace aware CSS
-clients as well as down-level clients. It should be noted that
-down-level clients may incorrectly match selectors against XML
-elements in other namespaces.</p>
-
-<p>The following are scenarios and examples in which it is possible to
-construct style sheets which would function properly in web clients
-that do not implement this proposal.</p>
-
-<ol>
-  <li>
-
-   <p>The XML document does not use namespaces.</p>
-
-   <ul>
-
-    <li>In this case, it is obviously not necessary to declare or use
-    namespaces in the style sheet. Standard CSS element type and
-    attribute selectors will function adequately in a down-level
-    client.</li>
-
-    <li>In a CSS namespace aware client, the default behavior of
-    element selectors matching without regard to namespace will
-    function properly against all elements, since no namespaces are
-    present. However, the use of specific element type selectors that
-    match only elements that have no namespace ("<code>|name</code>")
-    will guarantee that selectors will match only XML elements that do
-    not have a declared namespace. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document defines a single, default namespace used
-   throughout the document. No namespace prefixes are used in element
-   names.</p>
-
-   <ul>
-
-    <li>In this case, a down-level client will function as if
-    namespaces were not used in the XML document at all. Standard CSS
-    element type and attribute selectors will match against all
-    elements. </li>
-
-   </ul>
-
-  </li>
-
-  <li>
-
-   <p>The XML document does <b>not</b> use a default namespace, all
-   namespace prefixes used are known to the style sheet author, and
-   there is a direct mapping between namespace prefixes and namespace
-   URIs. (A given prefix may only be mapped to one namespace URI
-   throughout the XML document; there may be multiple prefixes mapped
-   to the same URI).</p>
-
-   <ul>
-
-    <li>In this case, the down-level client will view and match
-    element type and attribute selectors based on their fully
-    qualified name, not the local part as outlined in the <a
-    href="#typenmsp">Type selectors and Namespaces</a> section. CSS
-    selectors may be declared using an escaped colon "<code>\:</code>"
-    to describe the fully qualified names, e.g.
-    "<code>html\:h1</code>" will match
-    <code>&lt;html:h1&gt;</code>. Selectors using the qualified name
-    will only match XML elements that use the same prefix. Other
-    namespace prefixes used in the XML that are mapped to the same URI
-    will not match as expected unless additional CSS style rules are
-    declared for them.</li>
-
-    <li>Note that selectors declared in this fashion will
-    <em>only</em> match in down-level clients. A CSS namespace aware
-    client will match element type and attribute selectors based on
-    the name's local part. Selectors declared with the fully
-    qualified name will not match (unless there is no namespace prefix
-    in the fully qualified name).</li>
-
-   </ul>
-
-  </li>
-
- </ol>
-
-<p>In other scenarios: when the namespace prefixes used in the XML are
-not known in advance by the style sheet author; or a combination of
-elements with no namespace are used in conjunction with elements using
-a default namespace; or the same namespace prefix is mapped to
-<em>different</em> namespace URIs within the same document, or in
-different documents; it is impossible to construct a CSS style sheet
-that will function properly against all elements in those documents,
-unless, the style sheet is written using a namespace URI syntax (as
-outlined in this document or similar) and the document is processed by
-a CSS and XML namespace aware client.</p>
-
-<h2><a name=profiling>12. Profiles</a></h2>
-
-<p>Each specification using Selectors must define the subset of W3C
-Selectors it allows and excludes, and describe the local meaning of
-all the components of that subset.</p>
-
-<p>Non normative examples:
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 1</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>class selectors<br>ID selectors<br>:link,
-      :visited and :active pseudo-classes<br>descendant combinator
-     <br>::first-line and ::first-letter pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>universal selector<br>attribute selectors<br>:hover and :focus
-      pseudo-classes<br>:target pseudo-class<br>:lang() pseudo-class<br>all UI
-      element states pseudo-classes<br>all structural
-      pseudo-classes<br>negation pseudo-class<br>all
-      UI element fragments pseudo-elements<br>::before and ::after
-      pseudo-elements<br>child combinators<br>sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>only one class selector allowed per sequence of simple
-  selectors</td></tr></tbody></table><br><br>
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-    <td>CSS level 2</td></tr>
-  <tr>
-    <th>Accepts</th>
-    <td>type selectors<br>universal selector<br>attribute presence and
-      values selectors<br>class selectors<br>ID selectors<br>:link, :visited,
-      :active, :hover, :focus, :lang() and :first-child pseudo-classes
-     <br>descendant combinator<br>child combinator<br>adjacent sibling
-      combinator<br>::first-line and ::first-letter pseudo-elements<br>::before
-      and ::after pseudo-elements</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>
-
-<p>content selectors<br>substring matching attribute
-      selectors<br>:target pseudo-classes<br>all UI element
-      states pseudo-classes<br>all structural pseudo-classes other
-      than :first-child<br>negation pseudo-class<br>all UI element
-      fragments pseudo-elements<br>general sibling combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>more than one class selector per sequence of simple selectors (CSS1
-      constraint) allowed</td></tr></tbody></table>
-
-<p>In CSS, selectors express pattern matching rules that determine which style
-rules apply to elements in the document tree.
-
-<p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>
-with attribute <code>name</code> set inside a section 1 header <code>h1</code>:
-<pre>h1 a[name]</pre>
-
-<p>All CSS declarations attached to such a selector are applied to elements
-matching it. </div>
-
-<div class="profile">
-<table class="tprofile">
-  <tbody>
-  <tr>
-    <th class="title" colspan=2>Selectors profile</th></tr>
-  <tr>
-    <th>Specification</th>
-      <td>STTS 3</td>
-    </tr>
-  <tr>
-    <th>Accepts</th>
-    <td>
-
-<p>type selectors<br>universal selectors<br>attribute selectors<br>class
-      selectors<br>ID selectors<br>all structural pseudo-classes<br>
-          all combinators
-
-<p>namespaces</td></tr>
-  <tr>
-    <th>Excludes</th>
-    <td>non-accepted pseudo-classes<br>pseudo-elements<br></td></tr>
-  <tr>
-    <th>Extra constraints</th>
-    <td>some selectors and combinators are not allowed in fragment
-      descriptions on the right side of STTS declarations.</td></tr></tbody></table>
-<form>
-<input type="text" name="test10"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-<input type="text" name="foo"/>
-</form>
-
-<p>Selectors can be used in STTS 3 in two different
-    manners:
-<ol>
-  <li>a selection mechanism equivalent to CSS selection mechanism: declarations
-  attached to a given selector are applied to elements matching that selector,
-  <li>fragment descriptions that appear on the right side of declarations.
-</li></ol></div>
-
-<h2><a name=Conformance></a>13. Conformance and requirements</h2>
-
-<p>This section defines conformance with the present specification only.
-
-<p>The inability of a user agent to implement part of this specification due to
-the limitations of a particular device (e.g., non interactive user agents will
-probably not implement dynamic pseudo-classes because they make no sense without
-interactivity) does not imply non-conformance.
-
-<p>All specifications reusing Selectors must contain a <a
-href="#profiling">Profile</a> listing the
-subset of Selectors it accepts or excludes, and describing the constraints
-it adds to the current specification.
-
-<p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a token
-which is not allowed at the current parsing point.
-
-<p>User agents must observe the rules for handling parsing errors:
-<ul>
-  <li>a simple selector containing an undeclared namespace prefix is invalid</li>
-  <li>a selector containing an invalid simple selector, an invalid combinator
-    or an invalid token is invalid. </li>
-  <li>a group of selectors containing an invalid selector is invalid.</li>
-</ul>
-
-<p class="foo test10 bar">Specifications reusing Selectors must define how to handle parsing
-errors. (In the case of CSS, the entire rule in which the selector is
-used is dropped.)</p>
-
-<!-- Apparently all these references are out of date:
-<p>Implementations of this specification must behave as
-"recipients of text data" as defined by <a href="#refsCWWW">[CWWW]</a>
-when parsing selectors and attempting matches. (In particular,
-implementations must assume the data is normalized and must not
-normalize it.) Normative rules for matching strings are defined in
-<a href="#refsCWWW">[CWWW]</a> and <a
-href="#refsUNICODE">[UNICODE]</a> and apply to implementations of this
-specification.</p>-->
-
-<h2><a name=Tests></a>14. Tests</h2>
-
-<p>This specification has <a
-href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/">a test
-suite</a> allowing user agents to verify their basic conformance to
-the specification. This test suite does not pretend to be exhaustive
-and does not cover all possible combined cases of Selectors.</p>
-
-<h2><a name=ACKS></a>15. Acknowledgements</h2>
-
-<p>The CSS working group would like to thank everyone who has sent
-comments on this specification over the years.</p>
-
-<p>The working group would like to extend special thanks to Donna
-McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed
-the final editorial review.</p>
-
-<h2><a name=references>16. References</a></h2>
-
-<dl class="refs">
-
-  <dt>[CSS1]
-  <dd><a name=refsCSS1></a> Bert Bos, H&aring;kon Wium Lie; "<cite>Cascading Style Sheets, level 1</cite>", W3C Recommendation, 17 Dec 1996, revised 11 Jan 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-CSS1">http://www.w3.org/TR/REC-CSS1</a></code>)
-
-  <dt>[CSS21]
-  <dd><a name=refsCSS21></a> Bert Bos, Tantek &Ccedil;elik, Ian Hickson, H&aring;kon Wium Lie, editors; "<cite>Cascading Style Sheets, level 2 revision 1</cite>", W3C Working Draft, 13 June 2005
-  <dd>(<code><a href="http://www.w3.org/TR/CSS21">http://www.w3.org/TR/CSS21</a></code>)
-
-  <dt>[CWWW]
-  <dd><a name=refsCWWW></a> Martin J. D&uuml;rst, Fran&ccedil;ois Yergeau, Misha Wolf, Asmus Freytag, Tex Texin, editors; "<cite>Character Model for the World Wide Web</cite>", W3C Recommendation, 15 February 2005
-  <dd>(<code><a href="http://www.w3.org/TR/charmod/">http://www.w3.org/TR/charmod/</a></code>)
-
-  <dt>[FLEX]
-  <dd><a name="refsFLEX"></a> "<cite>Flex: The Lexical Scanner Generator</cite>", Version 2.3.7, ISBN 1882114213
-
-  <dt>[HTML4]
-  <dd><a name="refsHTML4"></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs, editors; "<cite>HTML 4.01 Specification</cite>", W3C Recommendation, 24 December 1999
-  <dd>(<a href="http://www.w3.org/TR/html4/"><code>http://www.w3.org/TR/html4/</code></a>)
-
-  <dt>[MATH]
-  <dd><a name="refsMATH"></a> Patrick Ion, Robert Miner, editors; "<cite>Mathematical Markup Language (MathML) 1.01</cite>", W3C Recommendation, revision of 7 July 1999
-  <dd>(<code><a href="http://www.w3.org/TR/REC-MathML/">http://www.w3.org/TR/REC-MathML/</a></code>)
-
-  <dt>[RFC3066]
-  <dd><a name="refsRFC3066"></a> H. Alvestrand; "<cite>Tags for the Identification of Languages</cite>", Request for Comments 3066, January 2001
-  <dd>(<a href="http://www.ietf.org/rfc/rfc3066.txt"><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)
-
-  <dt>[STTS]
-  <dd><a name=refsSTTS></a> Daniel Glazman; "<cite>Simple Tree Transformation Sheets 3</cite>", Electricit&eacute; de France, submission to the W3C, 11 November 1998
-  <dd>(<code><a href="http://www.w3.org/TR/NOTE-STTS3">http://www.w3.org/TR/NOTE-STTS3</a></code>)
-
-  <dt>[SVG]
-  <dd><a name="refsSVG"></a> Jon Ferraiolo, &#34276;&#27810; &#28147;, Dean Jackson, editors; "<cite>Scalable Vector Graphics (SVG) 1.1 Specification</cite>", W3C Recommendation, 14 January 2003
-  <dd>(<code><a href="http://www.w3.org/TR/SVG/">http://www.w3.org/TR/SVG/</a></code>)
-
-  <dt>[UNICODE]</dt>
-  <dd><a name="refsUNICODE"></a> <cite><a
-   href="http://www.unicode.org/versions/Unicode4.1.0/">The Unicode Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA, Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href="http://www.unicode.org/versions/Unicode4.0.1/">Unicode 4.0.1</a> and <a href="http://www.unicode.org/versions/Unicode4.1.0/">Unicode  4.1.0</a>.
-  <dd>(<code><a href="http://www.unicode.org/versions/">http://www.unicode.org/versions/</a></code>)</dd>
-
-  <dt>[XML10]
-  <dd><a name="refsXML10"></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, Fran&ccedil;ois Yergeau, editors; "<cite>Extensible Markup Language (XML) 1.0 (Third Edition)</cite>", W3C Recommendation, 4 February 2004
-  <dd>(<a href="http://www.w3.org/TR/REC-xml/"><code>http://www.w3.org/TR/REC-xml/</code></a>)
-
-  <dt>[XMLNAMES]
-  <dd><a name="refsXMLNAMES"></a> Tim Bray, Dave Hollander, Andrew Layman, editors; "<cite>Namespaces in XML</cite>", W3C Recommendation, 14 January 1999
-  <dd>(<a href="http://www.w3.org/TR/REC-xml-names/"><code>http://www.w3.org/TR/REC-xml-names/</code></a>)
-
-  <dt>[YACC]
-  <dd><a name="refsYACC"></a> S. C. Johnson; "<cite>YACC &mdash; Yet another compiler compiler</cite>", Technical Report, Murray Hill, 1975
-
-</dl>
-</body>
-</html>
diff --git a/samples/third_party/dromaeo/web/web-style.css b/samples/third_party/dromaeo/web/web-style.css
deleted file mode 100644
index c439dc0..0000000
--- a/samples/third_party/dromaeo/web/web-style.css
+++ /dev/null
@@ -1,24 +0,0 @@
-
-a { color: orange; }
-div.test { overflow: hidden; margin: 4px; }
-div.test b { display: block; float: left; width: 150px; text-align: right; margin-right: 10px; }
-div.bar { float: left; width: 400px; border: 1px inset; text-align: left; }
-div.bar div { height: 1em; background: url(orange-stripe.png); }
-div.bar span { padding-left: 5px; padding-right: 5px; }
-body { font-family: Arial; font-size: 12px; background: url(gray-stripe.png); text-align: center; }
-
-/*#main { margin: 0 auto; width: 600px; padding: 10px; background: #FFF; }*/
-
-ol.results { text-align: left; display: none; font-size: 10px; margin-left: 120px; list-style: none; }
-ol.results li { clear: both; overflow: auto; }
-ol.results b { display: block; width: 200px; float: left; text-align: right; padding-right: 15px; }
-#info, div.results { clear:both;width:420px;margin:10 auto;text-align:left; padding: 10px 10px 10px 110px; }
-#info span { background: #FFF; color: #000; padding: 8px 4px 4px 4px; }
-h1 { text-align: left; }
-h1 img { float:left;margin-right: 15px;margin-top: -10px; border: 0; }
-h1 small { font-weight:normal; }
-iframe { display: none; }
-div.resultwrap { text-align: center; }
-table.results { font-size: 12px; margin: 0 auto; }
-table.results td, table.results th.name { text-align: right; }
-table.results .winner { background-color: #c7331d; }
diff --git a/samples/third_party/todomvc_performance/.gitignore b/samples/third_party/todomvc_performance/.gitignore
deleted file mode 100644
index 378eac2..0000000
--- a/samples/third_party/todomvc_performance/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/samples/third_party/todomvc_performance/AUTHORS b/samples/third_party/todomvc_performance/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/LICENSE b/samples/third_party/todomvc_performance/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/samples/third_party/todomvc_performance/PATENTS b/samples/third_party/todomvc_performance/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/README.md b/samples/third_party/todomvc_performance/README.md
deleted file mode 100644
index c7a053f..0000000
--- a/samples/third_party/todomvc_performance/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Polymer TodoMVC Performance Test
-
-This directory is a copy of samples/third_party/todomvc with some modifications
-to make a performance test and added a pure JS implementation for comparison.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/AUTHORS
deleted file mode 100755
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/CONTRIBUTING.md
deleted file mode 100755
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/LICENSE
deleted file mode 100755
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/PATENTS
deleted file mode 100755
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/README.md b/samples/third_party/todomvc_performance/js_todomvc/README.md
deleted file mode 100755
index da3d1bc..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/README.md
+++ /dev/null
@@ -1,46 +0,0 @@
-This is a snapshot of https://github.com/Polymer/todomvc taken on 3-14-14.
-
-# Polymer TodoMVC Example
-
-> Polymer is a new type of library for the web, built on top of Web Components, and designed to leverage the evolving web platform on modern browsers.
-
-> _[Polymer - www.polymer-project.org](http://www.polymer-project.org/)_
-
-## Learning Polymer
-
-The [Polymer website](http://www.polymer-project.org) is a great resource for getting started.
-
-Here are some links you may find helpful:
-
-* [Getting Started](http://www.polymer-project.org/docs/start/everything.html)
-* [FAQ](http://www.polymer-project.org/resources/faq.html)
-* [Browser Compatibility](http://www.polymer-project.org/resources/compatibility.html)
-
-Get help from Polymer devs and users:
-
-* Find us on IRC on __#polymer__ at freenode.
-* Join the high-traffic [polymer-dev](https://groups.google.com/forum/?fromgroups=#!forum/polymer-dev) Google group or the announcement-only [polymer-announce](https://groups.google.com/forum/?fromgroups=#!forum/polymer-announce) Google group.
-
-## Implementation
-
-The Polymer implementation of TodoMVC has a few key differences with other implementations:
-
-* Since [Web Components](http://w3c.github.io/webcomponents/explainer/) allow you to create new types of DOM elements, the DOM tree is very different from other implementations.
-* The template, styling, and behavior are fully encapsulated in each custom element. Instead of having an overall stylesheet (`base.css` or `app.css`), each element that needs styling has its own stylesheet.
-* Non-visual elements such as the router and the model are also implemented as custom elements and appear in the DOM. Implementing them as custom elements instead of plain objects allows you to take advantage of Polymer data binding and event handling throughout the app.
-
-## Compatibility
-
-Polymer and its polyfills are intended to work in the latest version of [evergreen browsers](http://tomdale.net/2013/05/evergreen-browsers/). IE9 is not supported. Please refer to [Browser Compatibility](http://www.polymer-project.org/resources/compatibility.html) for more details.
-
-## Running this sample
-
-1. Install [node.js](nodejs.org) (required for `bower` client-side package management)
-1. Install bower: `npm install -g bower`
-
-1. From the `todomvc\` folder, run `bower update`
-1. Start a web server in the `todomvc\` folder.  Hint: if you have python installed, you can just run:
-
-     `python -m SimpleHTTPServer`
-
-1. Browse to the server root
diff --git a/samples/third_party/todomvc_performance/js_todomvc/app/app.css b/samples/third_party/todomvc_performance/js_todomvc/app/app.css
deleted file mode 100755
index 12f3666..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/app/app.css
+++ /dev/null
@@ -1,206 +0,0 @@
-/* base.css overrides */
-
-html,
-body {
-	margin: 0;
-	padding: 0;
-}
-
-body {
-	font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
-	line-height: 1.4em;
-	background: #eaeaea url('../components/todomvc-common/bg.png');
-	color: #4d4d4d;
-	width: 550px;
-	margin: 0 auto;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-body > header {
-  padding-top: 22px;
-  margin-bottom: -5px;
-}
-
-h1 {
-  /*	position: absolute;
-	top: -120px;*/
-	width: 100%;
-	font-size: 70px;
-	font-weight: bold;
-	text-align: center;
-	color: #b3b3b3;
-	color: rgba(255, 255, 255, 0.3);
-	text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-	-webkit-text-rendering: optimizeLegibility;
-	-moz-text-rendering: optimizeLegibility;
-	-ms-text-rendering: optimizeLegibility;
-	-o-text-rendering: optimizeLegibility;
-	text-rendering: optimizeLegibility;
-}
-
-#info {
-	margin: 65px auto 0;
-	color: #a6a6a6;
-	font-size: 12px;
-	text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
-	text-align: center;
-}
-
-#info a {
-	color: inherit;
-}
-
-.hidden{
-	display:none;
-}
-
-hr {
-	margin: 20px 0;
-	border: 0;
-	border-top: 1px dashed #C5C5C5;
-	border-bottom: 1px dashed #F7F7F7;
-}
-
-.learn a {
-	font-weight: normal;
-	text-decoration: none;
-	color: #b83f45;
-}
-
-.learn a:hover {
-	text-decoration: underline;
-	color: #787e7e;
-}
-
-.learn h3,
-.learn h4,
-.learn h5 {
-	margin: 10px 0;
-	font-weight: 500;
-	line-height: 1.2;
-	color: #000;
-}
-
-.learn h3 {
-	font-size: 24px;
-}
-
-.learn h4 {
-	font-size: 18px;
-}
-
-.learn h5 {
-	margin-bottom: 0;
-	font-size: 14px;
-}
-
-.learn ul {
-	padding: 0;
-	margin: 0 0 30px 25px;
-}
-
-.learn li {
-	line-height: 20px;
-}
-
-.learn p {
-	font-size: 15px;
-	font-weight: 300;
-	line-height: 1.3;
-	margin-top: 0;
-	margin-bottom: 0;
-}
-
-.quote {
-	border: none;
-	margin: 20px 0 60px 0;
-}
-
-.quote p {
-	font-style: italic;
-}
-
-.quote p:before {
-	content: '“';
-	font-size: 50px;
-	opacity: .15;
-	position: absolute;
-	top: -20px;
-	left: 3px;
-}
-
-.quote p:after {
-	content: '”';
-	font-size: 50px;
-	opacity: .15;
-	position: absolute;
-	bottom: -42px;
-	right: 3px;
-}
-
-.quote footer {
-	position: absolute;
-	bottom: -40px;
-	right: 0;
-}
-
-.quote footer img {
-	border-radius: 3px;
-}
-
-.quote footer a {
-	margin-left: 5px;
-	vertical-align: middle;
-}
-
-.speech-bubble {
-	position: relative;
-	padding: 10px;
-	background: rgba(0, 0, 0, .04);
-	border-radius: 5px;
-}
-
-.speech-bubble:after {
-	content: '';
-	position: absolute;
-	top: 100%;
-	right: 30px;
-	border: 13px solid transparent;
-	border-top-color: rgba(0, 0, 0, .04);
-}
-
-/**body*/.learn-bar > .learn {
-	position: absolute;
-	width: 272px;
-	top: 8px;
-	left: -300px;
-	padding: 10px;
-	border-radius: 5px;
-	background-color: rgba(255, 255, 255, .6);
-	transition-property: left;
-	transition-duration: 500ms;
-}
-
-
-/* IE doesn't support the hidden attribute */
-[hidden] {
-	display: none;
-}
-
-@media (min-width: 899px) {
-	/**body*/.learn-bar {
-		width: auto;
-		margin: 0 0 0 300px;
-	}
-	/**body*/.learn-bar > .learn {
-		left: 8px;
-	}
-	/**body*/.learn-bar #todoapp {
-		width: 550px;
-		margin: 130px auto 40px auto;
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/bower.json b/samples/third_party/todomvc_performance/js_todomvc/bower.json
deleted file mode 100755
index c67d0d1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/bower.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-	"name": "todomvc-template",
-	"version": "0.0.0",
-	"dependencies": {
-		"todomvc-common": "~0.1.4",
-    "polymer-selector": "Polymer/polymer-selector",
-    "flatiron-director": "Polymer/flatiron-director",
-    "polymer-localstorage": "Polymer/polymer-localstorage"
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/.bower.json
deleted file mode 100644
index f221bde..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/.bower.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "flatiron-director",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1",
-  "homepage": "https://github.com/Polymer/flatiron-director",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "d01427ec016607908f939aad6b7ab4164b355a73"
-  },
-  "_source": "git://github.com/Polymer/flatiron-director.git",
-  "_target": "*",
-  "_originalSource": "Polymer/flatiron-director"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/CONTRIBUTING.md
deleted file mode 100644
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/LICENSE
deleted file mode 100644
index a9bb4eb..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/LICENSE
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2011 Nodejitsu Inc.
-// Copyright (c) 2012 The Polymer Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/bower.json
deleted file mode 100644
index f12cefa..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/bower.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "name": "flatiron-director",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/demo.html b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/demo.html
deleted file mode 100644
index ea77ba6..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/demo.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<html>
-  <head>
-    <title>Director</title>
-    <script src="../platform/platform.js"></script>
-    <link rel="import" href="flatiron-director.html">
-  </head>
-  <body>
-    <polymer-element name="x-test">
-      <template>
-        <flatiron-director route="{{route}}" autoHash></flatiron-director>
-        hash: <input value="{{route}}">
-        <a href="#barnacle">Relocate</a>
-      </template>
-      <script>
-        Polymer('x-test', {
-          route: 'hello'
-        });
-      </script>
-    </polymer-element>
-    
-    <x-test></x-test>
-  </body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/LICENSE
deleted file mode 100644
index 1f01e2b..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011 Nodejitsu Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/director.min.js b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/director.min.js
deleted file mode 100644
index 55a8e64..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/director/director.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-//
-// Generated on Fri Dec 27 2013 12:02:11 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon).
-// Version 1.2.2
-//
-(function(a){function k(a,b,c,d){var e=0,f=0,g=0,c=(c||"(").toString(),d=(d||")").toString(),h;for(h=0;h<a.length;h++){var i=a[h];if(i.indexOf(c,e)>i.indexOf(d,e)||~i.indexOf(c,e)&&!~i.indexOf(d,e)||!~i.indexOf(c,e)&&~i.indexOf(d,e)){f=i.indexOf(c,e),g=i.indexOf(d,e);if(~f&&!~g||!~f&&~g){var j=a.slice(0,(h||1)+1).join(b);a=[j].concat(a.slice((h||1)+1))}e=(g>f?g:f)+1,h=0}else e=0}return a}function j(a,b){var c,d=0,e="";while(c=a.substr(d).match(/[^\w\d\- %@&]*\*[^\w\d\- %@&]*/))d=c.index+c[0].length,c[0]=c[0].replace(/^\*/,"([_.()!\\ %@&a-zA-Z0-9-]+)"),e+=a.substr(0,c.index)+c[0];a=e+=a.substr(d);var f=a.match(/:([^\/]+)/ig),g,h;if(f){h=f.length;for(var j=0;j<h;j++)g=f[j],g.slice(0,2)==="::"?a=g.slice(1):a=a.replace(g,i(g,b))}return a}function i(a,b,c){c=a;for(var d in b)if(b.hasOwnProperty(d)){c=b[d](a);if(c!==a)break}return c===a?"([._a-zA-Z0-9-]+)":c}function h(a,b,c){if(!a.length)return c();var d=0;(function e(){b(a[d],function(b){b||b===!1?(c(b),c=function(){}):(d+=1,d===a.length?c():e())})})()}function g(a){var b=[];for(var c=0,d=a.length;c<d;c++)b=b.concat(a[c]);return b}function f(a,b){for(var c=0;c<a.length;c+=1)if(b(a[c],c,a)===!1)return}function c(){return b.hash===""||b.hash==="#"}Array.prototype.filter||(Array.prototype.filter=function(a,b){var c=[],d;for(var e=0,f=this.length;e<f;e++)e in this&&a.call(b,d=this[e],e,this)&&c.push(d);return c}),Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"});var b=document.location,d={mode:"modern",hash:b.hash,history:!1,check:function(){var a=b.hash;a!=this.hash&&(this.hash=a,this.onHashChanged())},fire:function(){this.mode==="modern"?this.history===!0?window.onpopstate():window.onhashchange():this.onHashChanged()},init:function(a,b){function d(a){for(var b=0,c=e.listeners.length;b<c;b++)e.listeners[b](a)}var c=this;this.history=b,e.listeners||(e.listeners=[]);if("onhashchange"in window&&(document.documentMode===undefined||document.documentMode>7))this.history===!0?setTimeout(function(){window.onpopstate=d},500):window.onhashchange=d,this.mode="modern";else{var f=document.createElement("iframe");f.id="state-frame",f.style.display="none",document.body.appendChild(f),this.writeFrame(""),"onpropertychange"in document&&"attachEvent"in document&&document.attachEvent("onpropertychange",function(){event.propertyName==="location"&&c.check()}),window.setInterval(function(){c.check()},50),this.onHashChanged=d,this.mode="legacy"}e.listeners.push(a);return this.mode},destroy:function(a){if(!!e&&!!e.listeners){var b=e.listeners;for(var c=b.length-1;c>=0;c--)b[c]===a&&b.splice(c,1)}},setHash:function(a){this.mode==="legacy"&&this.writeFrame(a),this.history===!0?(window.history.pushState({},document.title,a),this.fire()):b.hash=a[0]==="/"?a:"/"+a;return this},writeFrame:function(a){var b=document.getElementById("state-frame"),c=b.contentDocument||b.contentWindow.document;c.open(),c.write("<script>_hash = '"+a+"'; onload = parent.listener.syncHash;<script>"),c.close()},syncHash:function(){var a=this._hash;a!=b.hash&&(b.hash=a);return this},onHashChanged:function(){}},e=a.Router=function(a){if(this instanceof e)this.params={},this.routes={},this.methods=["on","once","after","before"],this.scope=[],this._methods={},this._insert=this.insert,this.insert=this.insertEx,this.historySupport=(window.history!=null?window.history.pushState:null)!=null,this.configure(),this.mount(a||{});else return new e(a)};e.prototype.init=function(a){var e=this;this.handler=function(a){var b=a&&a.newURL||window.location.hash,c=e.history===!0?e.getPath():b.replace(/.*#/,"");e.dispatch("on",c.charAt(0)==="/"?c:"/"+c)},d.init(this.handler,this.history);if(this.history===!1)c()&&a?b.hash=a:c()||e.dispatch("on","/"+b.hash.replace(/^(#\/|#|\/)/,""));else{var f=c()&&a?a:c()?null:b.hash.replace(/^#/,"");f&&window.history.replaceState({},document.title,f),(f||this.run_in_init===!0)&&this.handler()}return this},e.prototype.explode=function(){var a=this.history===!0?this.getPath():b.hash;a.charAt(1)==="/"&&(a=a.slice(1));return a.slice(1,a.length).split("/")},e.prototype.setRoute=function(a,b,c){var e=this.explode();typeof a=="number"&&typeof b=="string"?e[a]=b:typeof c=="string"?e.splice(a,b,s):e=[a],d.setHash(e.join("/"));return e},e.prototype.insertEx=function(a,b,c,d){a==="once"&&(a="on",c=function(a){var b=!1;return function(){if(!b){b=!0;return a.apply(this,arguments)}}}(c));return this._insert(a,b,c,d)},e.prototype.getRoute=function(a){var b=a;if(typeof a=="number")b=this.explode()[a];else if(typeof a=="string"){var c=this.explode();b=c.indexOf(a)}else b=this.explode();return b},e.prototype.destroy=function(){d.destroy(this.handler);return this},e.prototype.getPath=function(){var a=window.location.pathname;a.substr(0,1)!=="/"&&(a="/"+a);return a},e.prototype.configure=function(a){a=a||{};for(var b=0;b<this.methods.length;b++)this._methods[this.methods[b]]=!0;this.recurse=a.recurse||this.recurse||!1,this.async=a.async||!1,this.delimiter=a.delimiter||"/",this.strict=typeof a.strict=="undefined"?!0:a.strict,this.notfound=a.notfound,this.resource=a.resource,this.history=a.html5history&&this.historySupport||!1,this.run_in_init=this.history===!0&&a.run_handler_in_init!==!1,this.every={after:a.after||null,before:a.before||null,on:a.on||null};return this},e.prototype.param=function(a,b){a[0]!==":"&&(a=":"+a);var c=new RegExp(a,"g");this.params[a]=function(a){return a.replace(c,b.source||b)}},e.prototype.on=e.prototype.route=function(a,b,c){var d=this;!c&&typeof b=="function"&&(c=b,b=a,a="on");if(Array.isArray(b))return b.forEach(function(b){d.on(a,b,c)});b.source&&(b=b.source.replace(/\\\//ig,"/"));if(Array.isArray(a))return a.forEach(function(a){d.on(a.toLowerCase(),b,c)});b=b.split(new RegExp(this.delimiter)),b=k(b,this.delimiter),this.insert(a,this.scope.concat(b),c)},e.prototype.dispatch=function(a,b,c){function h(){d.last=e.after,d.invoke(d.runlist(e),d,c)}var d=this,e=this.traverse(a,b,this.routes,""),f=this._invoked,g;this._invoked=!0;if(!e||e.length===0){this.last=[],typeof this.notfound=="function"&&this.invoke([this.notfound],{method:a,path:b},c);return!1}this.recurse==="forward"&&(e=e.reverse()),g=this.every&&this.every.after?[this.every.after].concat(this.last):[this.last];if(g&&g.length>0&&f){this.async?this.invoke(g,this,h):(this.invoke(g,this),h());return!0}h();return!0},e.prototype.invoke=function(a,b,c){var d=this,e;this.async?(e=function(c,d){if(Array.isArray(c))return h(c,e,d);typeof c=="function"&&c.apply(b,a.captures.concat(d))},h(a,e,function(){c&&c.apply(b,arguments)})):(e=function(c){if(Array.isArray(c))return f(c,e);if(typeof c=="function")return c.apply(b,a.captures||[]);typeof c=="string"&&d.resource&&d.resource[c].apply(b,a.captures||[])},f(a,e))},e.prototype.traverse=function(a,b,c,d,e){function l(a){function c(a){for(var b=a.length-1;b>=0;b--)Array.isArray(a[b])?(c(a[b]),a[b].length===0&&a.splice(b,1)):e(a[b])||a.splice(b,1)}function b(a){var c=[];for(var d=0;d<a.length;d++)c[d]=Array.isArray(a[d])?b(a[d]):a[d];return c}if(!e)return a;var d=b(a);d.matched=a.matched,d.captures=a.captures,d.after=a.after.filter(e),c(d);return d}var f=[],g,h,i,j,k;if(b===this.delimiter&&c[a]){j=[[c.before,c[a]].filter(Boolean)],j.after=[c.after].filter(Boolean),j.matched=!0,j.captures=[];return l(j)}for(var m in c)if(c.hasOwnProperty(m)&&(!this._methods[m]||this._methods[m]&&typeof c[m]=="object"&&!Array.isArray(c[m]))){g=h=d+this.delimiter+m,this.strict||(h+="["+this.delimiter+"]?"),i=b.match(new RegExp("^"+h));if(!i)continue;if(i[0]&&i[0]==b&&c[m][a]){j=[[c[m].before,c[m][a]].filter(Boolean)],j.after=[c[m].after].filter(Boolean),j.matched=!0,j.captures=i.slice(1),this.recurse&&c===this.routes&&(j.push([c.before,c.on].filter(Boolean)),j.after=j.after.concat([c.after].filter(Boolean)));return l(j)}j=this.traverse(a,b,c[m],g);if(j.matched){j.length>0&&(f=f.concat(j)),this.recurse&&(f.push([c[m].before,c[m].on].filter(Boolean)),j.after=j.after.concat([c[m].after].filter(Boolean)),c===this.routes&&(f.push([c.before,c.on].filter(Boolean)),j.after=j.after.concat([c.after].filter(Boolean)))),f.matched=!0,f.captures=j.captures,f.after=j.after;return l(f)}}return!1},e.prototype.insert=function(a,b,c,d){var e,f,g,h,i;b=b.filter(function(a){return a&&a.length>0}),d=d||this.routes,i=b.shift(),/\:|\*/.test(i)&&!/\\d|\\w/.test(i)&&(i=j(i,this.params));if(b.length>0){d[i]=d[i]||{};return this.insert(a,b,c,d[i])}{if(!!i||!!b.length||d!==this.routes){f=typeof d[i],g=Array.isArray(d[i]);if(d[i]&&!g&&f=="object"){e=typeof d[i][a];switch(e){case"function":d[i][a]=[d[i][a],c];return;case"object":d[i][a].push(c);return;case"undefined":d[i][a]=c;return}}else if(f=="undefined"){h={},h[a]=c,d[i]=h;return}throw new Error("Invalid route context: "+f)}e=typeof d[a];switch(e){case"function":d[a]=[d[a],c];return;case"object":d[a].push(c);return;case"undefined":d[a]=c;return}}},e.prototype.extend=function(a){function e(a){b._methods[a]=!0,b[a]=function(){var c=arguments.length===1?[a,""]:[a];b.on.apply(b,c.concat(Array.prototype.slice.call(arguments)))}}var b=this,c=a.length,d;for(d=0;d<c;d++)e(a[d])},e.prototype.runlist=function(a){var b=this.every&&this.every.before?[this.every.before].concat(g(a)):g(a);this.every&&this.every.on&&b.push(this.every.on),b.captures=a.captures,b.source=a.source;return b},e.prototype.mount=function(a,b){function d(b,d){var e=b,f=b.split(c.delimiter),g=typeof a[b],h=f[0]===""||!c._methods[f[0]],i=h?"on":e;h&&(e=e.slice((e.match(new RegExp("^"+c.delimiter))||[""])[0].length),f.shift());h&&g==="object"&&!Array.isArray(a[b])?(d=d.concat(f),c.mount(a[b],d)):(h&&(d=d.concat(e.split(c.delimiter)),d=k(d,c.delimiter)),c.insert(i,d,a[b]))}if(!!a&&typeof a=="object"&&!Array.isArray(a)){var c=this;b=b||[],Array.isArray(b)||(b=b.split(c.delimiter));for(var e in a)a.hasOwnProperty(e)&&d(e,b.slice(0))}}})(typeof exports=="object"?exports:window)
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/flatiron-director.html b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/flatiron-director.html
deleted file mode 100644
index f0538cd..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/flatiron-director.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<link rel="import" href="../polymer/polymer.html">
-<script src="director/director.min.js"></script>
-
-<polymer-element name="flatiron-director" attributes="route autoHash">
-  <script>
-    (function() {
-      var private_router;
-      Polymer('flatiron-director', {
-        autoHash: false,
-        ready: function() {
-          this.router.on(/(.*)/, function(route) {
-            this.route = route;
-          }.bind(this));
-          this.route = this.router.getRoute(0) || '';
-        },
-        routeChanged: function() {
-          if (this.autoHash) {
-            window.location.hash = this.route;
-          }
-          this.fire('director-route', this.route);
-        },
-        get router() {
-          if (!private_router) {
-            private_router = new Router();
-            private_router.init();
-          }
-          return private_router;
-        }
-      });
-    })();
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/index.html b/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/index.html
deleted file mode 100644
index 9bb2721..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/flatiron-director/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer api</title>
-  <style>
-    html, body {
-      font-family: Arial, sans-serif;
-      white-space: nowrap;
-      overflow: hidden;
-    }
-    [noviewer] [ifnoviewer] {
-      display: block;
-    }
-    [detector], [ifnoviewer], [noviewer] [ifviewer] {
-      display: none;
-    }
-    [ifviewer], [ifnoviewer] {
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-    }
-    iframe {
-      border: none;
-      margin: 0;
-      width: 100%;
-      height: 100%;
-    }
-    #remote {
-      position: absolute;
-      top: 0;
-      right: 0;
-    }
-  </style>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="../polymer-home-page/polymer-home-page.html">
-</head>
-<body>
-  <img detector src="../polymer-home-page/bowager-logo.png" onerror="noviewer()">
-  <polymer-home-page ifviewer></polymer-home-page>
-  <div ifnoviewer>
-    <span id="remote">[remote]</span>
-    <iframe></iframe>
-  </div>
-  <!-- -->
-  <script>
-    var remoteDocs = 'http://turbogadgetry.com/bowertopia/components/';
-    // if no local info viewer, load it remotely
-    function noviewer() {
-      document.body.setAttribute('noviewer', '');
-      var path = location.pathname.split('/');
-      var module = path.pop() || path.pop();
-      document.querySelector('iframe').src = remoteDocs + module;
-      document.querySelector('title').textContent = module;
-    }
-    // for testing only
-    var opts = window.location.search;
-    if (opts.indexOf('noviewer') >= 0) {
-      noviewer();
-    }
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/platform/.bower.json
deleted file mode 100644
index 6aa570e..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/.bower.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "name": "platform",
-  "main": "platform.js",
-  "homepage": "https://github.com/Polymer/platform",
-  "authors": [
-    "The Polymer Authors"
-  ],
-  "description": "Integrate platform polyfills: load, build, test",
-  "keywords": [
-    "polymer",
-    "web",
-    "components"
-  ],
-  "license": "BSD",
-  "private": true,
-  "version": "0.2.1",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "961d6f68848b9479d4d778466c37c0835837bc1c"
-  },
-  "_source": "git://github.com/Polymer/platform.git",
-  "_target": "0.2.1",
-  "_originalSource": "Polymer/platform"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/platform/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/platform/CONTRIBUTING.md
deleted file mode 100644
index 1de2f34..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/CONTRIBUTING.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Contributing
-
-Want to contribute to Polymer? Great!
-
-We are more than happy to accept external contributions to the project in the form of [feedback](https://groups.google.com/forum/?fromgroups=#!forum/polymer-dev), [bug reports](../../issues), and pull requests.
-
-## Contributor License Agreement
-
-Before we can accept patches, there's a quick web form you need to fill out.
-
-- If you're contributing as an individual (e.g. you own the intellectual property), fill out [this form](http://code.google.com/legal/individual-cla-v1.0.html).
-- If you're contributing under a company, fill out [this form](http://code.google.com/legal/corporate-cla-v1.0.html) instead.
-
-This CLA asserts that contributions are owned by you and that we can license all work under our [license](LICENSE).
-
-Other projects require a similar agreement: jQuery, Firefox, Apache, Node, and many more.
-
-[More about CLAs](https://www.google.com/search?q=Contributor%20License%20Agreement)
-
-## Initial setup
-
-Here's an easy guide that should get you up and running:
-
-1. Setup Grunt: `sudo npm install -g grunt-cli`
-1. Fork the project on github and pull down your copy.
-   > replace the {{ username }} with your username and {{ repository }} with the repository name
-
-        git clone git@github.com:{{ username }}/{{ repository }}.git --recursive
-
-    Note the `--recursive`. This is necessary for submodules to initialize properly. If you don't do a recursive clone, you'll have to init them manually:
-
-        git submodule init
-        git submodule update
-
-    Download and run the `pull-all.sh` script to install the sibling dependencies.
-
-        git clone git://github.com/Polymer/tools.git && tools/bin/pull-all.sh
-
-1. Test your change
-   > in the repo you've made changes to, run the tests:
-
-        cd $REPO
-        npm install
-        grunt test
-
-1. Commit your code and make a pull request.
-
-That's it for the one time setup. Now you're ready to make a change.
-
-## Submitting a pull request
-
-We iterate fast! To avoid potential merge conflicts, it's a good idea to pull from the main project before making a change and submitting a pull request. The easiest way to do this is setup a remote called `upstream` and do a pull before working on a change:
-
-    git remote add upstream git://github.com/Polymer/{{ repository }}.git
-
-Then before making a change, do a pull from the upstream `master` branch:
-
-    git pull upstream master
-
-To make life easier, add a "pull upstream" alias in your `.gitconfig`:
-
-    [alias]
-      pu = !"git fetch origin -v; git fetch upstream -v; git merge upstream/master"
-
-That will pull in changes from your forked repo, the main (upstream) repo, and merge the two. Then it's just a matter of running `git pu` before a change and pushing to your repo:
-
-    git checkout master
-    git pu
-    # make change
-    git commit -a -m 'Awesome things.'
-    git push
-
-Lastly, don't forget to submit the pull request.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/platform/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/platform/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/README.md b/samples/third_party/todomvc_performance/js_todomvc/components/platform/README.md
deleted file mode 100644
index 65b661e..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Platform
-========
-
-Aggregated polyfills the Polymer platform. 
-
-[![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/platform/README)](https://github.com/igrigorik/ga-beacon)
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/platform/bower.json
deleted file mode 100644
index cc029b9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/bower.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "name": "platform",
-  "main": "platform.js",
-  "homepage": "https://github.com/Polymer/platform",
-  "authors": [
-    "The Polymer Authors"
-  ],
-  "description": "Integrate platform polyfills: load, build, test",
-  "keywords": [
-    "polymer",
-    "web",
-    "components"
-  ],
-  "license": "BSD",
-  "private": true,
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js b/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js
deleted file mode 100644
index 57f1b10..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * @license
- * Copyright (c) 2012-2014 The Polymer Authors. All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *    * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *    * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-// @version: 0.2.1
-function PointerGestureEvent(a,b){var c=b||{},d=document.createEvent("Event"),e={bubbles:Boolean(c.bubbles)===c.bubbles||!0,cancelable:Boolean(c.cancelable)===c.cancelable||!0};d.initEvent(a,e.bubbles,e.cancelable);for(var f,g=Object.keys(c),h=0;h<g.length;h++)f=g[h],d[f]=c[f];return d.preventTap=this.preventTap,d}"undefined"==typeof WeakMap&&!function(){var a=Object.defineProperty,b=Date.now()%1e9,c=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")};c.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]:void 0},"delete":function(a){this.set(a,void 0)}},window.WeakMap=c}(),function(a){"use strict";function b(){function a(a){b=a}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=[],c={};if(Object.observe(c,a),c.id=1,c.id=2,delete c.id,Object.deliverChangeRecords(a),3!==b.length)return!1;if("new"==b[0].type&&"updated"==b[1].type&&"deleted"==b[2].type)L="new",M="updated",N="reconfigured",O="deleted";else if("add"!=b[0].type||"update"!=b[1].type||"delete"!=b[2].type)return console.error("Unexpected change record names for Object.observe. Using dirty-checking instead"),!1;return Object.unobserve(c,a),c=[0],Array.observe(c,a),c[1]=1,c.length=0,Object.deliverChangeRecords(a),2!=b.length?!1:b[0].type!=P||b[1].type!=P?!1:(Array.unobserve(c,a),!0)}function c(){if(a.document&&"securityPolicy"in a.document&&!a.document.securityPolicy.allowsEval)return!1;try{var b=new Function("","return true;");return b()}catch(c){return!1}}function d(a){return+a===a>>>0}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:S(a)&&S(b)?!0:a!==a&&b!==b}function h(a){return"string"!=typeof a?!1:(a=a.trim(),""==a?!0:"."==a[0]?!1:$.test(a))}function i(a,b){if(b!==_)throw Error("Use Path.get to retrieve path objects");return""==a.trim()?this:d(a)?(this.push(a),this):(a.split(/\s*\.\s*/).filter(function(a){return a}).forEach(function(a){this.push(a)},this),void(R&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn())))}function j(a){if(a instanceof i)return a;null==a&&(a=""),"string"!=typeof a&&(a=String(a));var b=ab[a];if(b)return b;if(!h(a))return bb;var b=new i(a,_);return ab[a]=b,b}function k(b){for(var c=0;db>c&&b.check_();)c++;return a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=c),c>0}function l(a){for(var b in a)return!1;return!0}function m(a){return l(a.added)&&l(a.removed)&&l(a.changed)}function n(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function o(){if(!eb.length)return!1;for(var a=0;a<eb.length;a++)eb[a]();return eb.length=0,!0}function p(){function a(a){b&&b.state_===kb&&!d&&b.check_(a)}var b,c,d=!1,e=!0;return{open:function(c){if(b)throw Error("ObservedObject in use");e||Object.deliverChangeRecords(a),b=c,e=!1},observe:function(b,d){c=b,d?Array.observe(c,a):Object.observe(c,a)},deliver:function(b){d=b,Object.deliverChangeRecords(a),d=!1},close:function(){b=void 0,Object.unobserve(c,a),gb.push(this)}}}function q(a,b,c){var d=gb.pop()||p();return d.open(a),d.observe(b,c),d}function r(){function a(b){if(f(b)){var c=j.indexOf(b);c>=0?(j[c]=void 0,i.push(b)):i.indexOf(b)<0&&(i.push(b),Object.observe(b,e)),a(Object.getPrototypeOf(b))}}function b(){var b=j===hb?[]:j;j=i,i=b;var c;for(var d in g)c=g[d],c&&c.state_==kb&&c.iterateObjects_(a);for(var f=0;f<j.length;f++){var h=j[f];h&&Object.unobserve(h,e)}j.length=0}function c(){l=!1,k&&b()}function d(){l||(k=!0,l=!0,fb(c))}function e(){b();var a;for(var c in g)a=g[c],a&&a.state_==kb&&a.check_()}var g=[],h=0,i=[],j=hb,k=!1,l=!1,m={object:void 0,objects:i,open:function(b){g[b.id_]=b,h++,b.iterateObjects_(a)},close:function(a){if(g[a.id_]=void 0,h--,h)return void d();k=!1;for(var b=0;b<i.length;b++)Object.unobserve(i[b],e),t.unobservedCount++;g.length=0,i.length=0,ib.push(this)},reset:d};return m}function s(a,b){return cb&&cb.object===b||(cb=ib.pop()||r(),cb.object=b),cb.open(a),cb}function t(){this.state_=jb,this.callback_=void 0,this.target_=void 0,this.directObserver_=void 0,this.value_=void 0,this.id_=nb++}function u(a){t._allObserversCount++,pb&&ob.push(a)}function v(){t._allObserversCount--}function w(a){t.call(this),this.value_=a,this.oldObject_=void 0}function x(a){if(!Array.isArray(a))throw Error("Provided object is not an Array");w.call(this,a)}function y(a,b){t.call(this),this.object_=a,this.path_=b instanceof i?b:j(b),this.directObserver_=void 0}function z(){t.call(this),this.value_=[],this.directObserver_=void 0,this.observed_=[]}function A(a){return a}function B(a,b,c,d){this.callback_=void 0,this.target_=void 0,this.value_=void 0,this.observable_=a,this.getValueFn_=b||A,this.setValueFn_=c||A,this.dontPassThroughSet_=d}function C(a,b){if("function"==typeof Object.observe){var c=Object.getNotifier(a);return function(d,e){var f={object:a,type:d,name:b};2===arguments.length&&(f.oldValue=e),c.notify(f)}}}function D(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];tb[g.type]?(g.name in c||(c[g.name]=g.oldValue),g.type!=M&&(g.type!=L?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function E(a,b,c){return{index:a,removed:b,addedCount:c}}function F(){}function G(a,b,c,d,e,f){return yb.calcSplices(a,b,c,d,e,f)}function H(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function I(a,b,c,d){for(var e=E(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=H(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function J(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case P:I(c,g.index,g.removed.slice(),g.addedCount);break;case L:case M:case O:if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;I(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function K(a,b){var c=[];return J(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?void(b.removed[0]!==a[b.index]&&c.push(b)):void(c=c.concat(G(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)))}),c}var L="add",M="update",N="reconfigure",O="delete",P="splice",Q=b(),R=c(),S=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},T="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},U="[$_a-zA-Z]",V="[$_a-zA-Z0-9]",W=U+"+"+V+"*",X="(?:[0-9]|[1-9]+[0-9]+)",Y="(?:"+W+"|"+X+")",Z="(?:"+Y+")(?:\\s*\\.\\s*"+Y+")*",$=new RegExp("^"+Z+"$"),_={},ab={};i.get=j,i.prototype=T({__proto__:[],valid:!0,toString:function(){return this.join(".")},getValueFrom:function(a){for(var b=0;b<this.length;b++){if(null==a)return;a=a[this[b]]}return a},iterateObjects:function(a,b){for(var c=0;c<this.length;c++){if(c&&(a=a[this[c-1]]),!a)return;b(a)}},compiledGetValueFromFn:function(){var a=this.map(function(a){return d(a)?'["'+a+'"]':"."+a}),b="",c="obj";b+="if (obj != null";for(var e=0;e<this.length-1;e++){{this[e]}c+=a[e],b+=" &&\n     "+c+" != null"}return b+=")\n",c+=a[e],b+="  return "+c+";\nelse\n  return undefined;",new Function("obj",b)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var bb=new i("",_);bb.valid=!1,bb.getValueFrom=bb.setValueFrom=function(){};var cb,db=1e3,eb=[],fb=Q?function(){var a={pingPong:!0},b=!1;return Object.observe(a,function(){o(),b=!1}),function(c){eb.push(c),b||(b=!0,a.pingPong=!a.pingPong)}}():function(){return function(a){eb.push(a)}}(),gb=[],hb=[],ib=[],jb=0,kb=1,lb=2,mb=3,nb=1;t.prototype={open:function(a,b){if(this.state_!=jb)throw Error("Observer has already been opened.");return u(this),this.callback_=a,this.target_=b,this.state_=kb,this.connect_(),this.value_},close:function(){this.state_==kb&&(v(this),this.state_=lb,this.disconnect_(),this.value_=void 0,this.callback_=void 0,this.target_=void 0)},deliver:function(){this.state_==kb&&k(this)},report_:function(a){try{this.callback_.apply(this.target_,a)}catch(b){t._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},discardChanges:function(){return this.check_(void 0,!0),this.value_}};var ob,pb=!Q;t._allObserversCount=0,pb&&(ob=[]);var qb=!1,rb="function"==typeof Object.deliverAllChangeRecords;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!qb){if(rb)return void Object.deliverAllChangeRecords();if(pb){qb=!0;var b,c,d=0;do{d++,c=ob,ob=[],b=!1;for(var e=0;e<c.length;e++){var f=c[e];f.state_==kb&&(f.check_()&&(b=!0),ob.push(f))}o()&&(b=!0)}while(db>d&&b);a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=d),qb=!1}}},pb&&(a.Platform.clearObservers=function(){ob=[]}),w.prototype=T({__proto__:t.prototype,arrayObserve:!1,connect_:function(){Q?this.directObserver_=q(this,this.value_,this.arrayObserve):this.oldObject_=this.copyObject(this.value_)},copyObject:function(a){var b=Array.isArray(a)?[]:{};for(var c in a)b[c]=a[c];return Array.isArray(a)&&(b.length=a.length),b},check_:function(a){var b,c;if(Q){if(!a)return!1;c={},b=D(this.value_,a,c)}else c=this.oldObject_,b=n(this.value_,this.oldObject_);return m(b)?!1:(Q||(this.oldObject_=this.copyObject(this.value_)),this.report_([b.added||{},b.removed||{},b.changed||{},function(a){return c[a]}]),!0)},disconnect_:function(){Q?(this.directObserver_.close(),this.directObserver_=void 0):this.oldObject_=void 0},deliver:function(){this.state_==kb&&(Q?this.directObserver_.deliver(!1):k(this))},discardChanges:function(){return this.directObserver_?this.directObserver_.deliver(!0):this.oldObject_=this.copyObject(this.value_),this.value_}}),x.prototype=T({__proto__:w.prototype,arrayObserve:!0,copyObject:function(a){return a.slice()},check_:function(a){var b;if(Q){if(!a)return!1;b=K(this.value_,a)}else b=G(this.value_,0,this.value_.length,this.oldObject_,0,this.oldObject_.length);return b&&b.length?(Q||(this.oldObject_=this.copyObject(this.value_)),this.report_([b]),!0):!1}}),x.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})},y.prototype=T({__proto__:t.prototype,connect_:function(){Q&&(this.directObserver_=s(this,this.object_)),this.check_(void 0,!0)},disconnect_:function(){this.value_=void 0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0)},iterateObjects_:function(a){this.path_.iterateObjects(this.object_,a)},check_:function(a,b){var c=this.value_;return this.value_=this.path_.getValueFrom(this.object_),b||g(this.value_,c)?!1:(this.report_([this.value_,c]),!0)},setValue:function(a){this.path_&&this.path_.setValueFrom(this.object_,a)}});var sb={};z.prototype=T({__proto__:t.prototype,connect_:function(){if(this.check_(void 0,!0),Q){for(var a,b=!1,c=0;c<this.observed_.length;c+=2)if(a=this.observed_[c],a!==sb){b=!0;break}return this.directObserver_?b?void this.directObserver_.reset():(this.directObserver_.close(),void(this.directObserver_=void 0)):void(b&&(this.directObserver_=s(this,a)))}},closeObservers_:function(){for(var a=0;a<this.observed_.length;a+=2)this.observed_[a]===sb&&this.observed_[a+1].close();this.observed_.length=0},disconnect_:function(){this.value_=void 0,this.directObserver_&&(this.directObserver_.close(this),this.directObserver_=void 0),this.closeObservers_()},addPath:function(a,b){if(this.state_!=jb&&this.state_!=mb)throw Error("Cannot add paths once started.");this.observed_.push(a,b instanceof i?b:j(b))},addObserver:function(a){if(this.state_!=jb&&this.state_!=mb)throw Error("Cannot add observers once started.");a.open(this.deliver,this),this.observed_.push(sb,a)},startReset:function(){if(this.state_!=kb)throw Error("Can only reset while open");this.state_=mb,this.closeObservers_()},finishReset:function(){if(this.state_!=mb)throw Error("Can only finishReset after startReset");return this.state_=kb,this.connect_(),this.value_},iterateObjects_:function(a){for(var b,c=0;c<this.observed_.length;c+=2)b=this.observed_[c],b!==sb&&this.observed_[c+1].iterateObjects(b,a)},check_:function(a,b){for(var c,d=0;d<this.observed_.length;d+=2){var e=this.observed_[d+1],f=this.observed_[d],h=f===sb?e.discardChanges():e.getValueFrom(f);b?this.value_[d/2]=h:g(h,this.value_[d/2])||(c=c||[],c[d/2]=this.value_[d/2],this.value_[d/2]=h)}return c?(this.report_([this.value_,c,this.observed_]),!0):!1}}),B.prototype={open:function(a,b){return this.callback_=a,this.target_=b,this.value_=this.getValueFn_(this.observable_.open(this.observedCallback_,this)),this.value_},observedCallback_:function(a){if(a=this.getValueFn_(a),!g(a,this.value_)){var b=this.value_;this.value_=a,this.callback_.call(this.target_,this.value_,b)}},discardChanges:function(){return this.value_=this.getValueFn_(this.observable_.discardChanges()),this.value_},deliver:function(){return this.observable_.deliver()},setValue:function(a){return a=this.setValueFn_(a),!this.dontPassThroughSet_&&this.observable_.setValue?this.observable_.setValue(a):void 0},close:function(){this.observable_&&this.observable_.close(),this.callback_=void 0,this.target_=void 0,this.observable_=void 0,this.value_=void 0,this.getValueFn_=void 0,this.setValueFn_=void 0}};var tb={};tb[L]=!0,tb[M]=!0,tb[O]=!0,t.defineComputedProperty=function(a,b,c){var d=C(a,b),e=c.open(function(a,b){e=a,d&&d(M,b)});return Object.defineProperty(a,b,{get:function(){return c.deliver(),e},set:function(a){return c.setValue(a),a},configurable:!0}),{close:function(){c.close(),Object.defineProperty(a,b,{value:e,writable:!0,configurable:!0})}}};var ub=0,vb=1,wb=2,xb=3;F.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(ub):(e.push(vb),d=g),b--,c--):f==h?(e.push(xb),b--,d=h):(e.push(wb),c--,d=i)}else e.push(xb),b--;else e.push(wb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,c-b==0&&f-e==0)return[];if(b==c){for(var j=E(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[E(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case ub:j&&(l.push(j),j=void 0),m++,n++;break;case vb:j||(j=E(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case wb:j||(j=E(m,[],0)),j.addedCount++,m++;break;case xb:j||(j=E(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var yb=new F;a.Observer=t,a.Observer.runEOM_=fb,a.Observer.hasObjectObserve=Q,a.ArrayObserver=x,a.ArrayObserver.calculateSplices=function(a,b){return yb.calculateSplices(a,b)},a.ArraySplice=F,a.ObjectObserver=w,a.PathObserver=y,a.CompoundObserver=z,a.Path=i,a.ObserverTransform=B,a.Observer.changeRecordTypes={add:L,update:M,reconfigure:N,"delete":O,splice:P}}("undefined"!=typeof global&&global&&"undefined"!=typeof module&&module?global:this||window),window.Platform=window.Platform||{},window.logFlags=window.logFlags||{},function(a){var b=a.flags||{};location.search.slice(1).split("&").forEach(function(a){a=a.split("="),a[0]&&(b[a[0]]=a[1]||!0)});var c=document.currentScript||document.querySelector('script[src*="platform.js"]');if(c)for(var d,e=c.attributes,f=0;f<e.length;f++)d=e[f],"src"!==d.name&&(b[d.name]=d.value||!0);b.log&&b.log.split(",").forEach(function(a){window.logFlags[a]=!0}),b.shadow=b.shadow||b.shadowdom||b.polyfill,b.shadow="native"===b.shadow?!1:b.shadow||!HTMLElement.prototype.createShadowRoot,b.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=b.register),b.imports&&(window.HTMLImports=window.HTMLImports||{flags:{}},window.HTMLImports.flags.imports=b.imports),a.flags=b}(Platform),Platform.flags.shadow?(window.ShadowDOMPolyfill={},function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a,b){return L(b).forEach(function(c){K(a,c,M(b,c))}),a}function d(a,b){return L(b).forEach(function(c){switch(c){case"arguments":case"caller":case"length":case"name":case"prototype":case"toString":return}K(a,c,M(b,c))}),a}function e(a,b){for(var c=0;c<b.length;c++)if(b[c]in a)return b[c]}function f(a){var b=a.__proto__||Object.getPrototypeOf(a),c=E.get(b);if(c)return c;var d=f(b),e=t(d);return q(b,e,a),e}function g(a,b){o(a,b,!0)}function h(a,b){o(b,a,!1)}function i(a){return/^on[a-z]+$/.test(a)}function j(a){return/^\w[a-zA-Z_0-9]*$/.test(a)}function k(a){return H&&j(a)?new Function("return this.impl."+a):function(){return this.impl[a]}}function l(a){return H&&j(a)?new Function("v","this.impl."+a+" = v"):function(b){this.impl[a]=b}}function m(a){return H&&j(a)?new Function("return this.impl."+a+".apply(this.impl, arguments)"):function(){return this.impl[a].apply(this.impl,arguments)}}function n(a,b){try{return Object.getOwnPropertyDescriptor(a,b)}catch(c){return O}}function o(b,c,d){for(var e=L(b),f=0;f<e.length;f++){var g=e[f];if("polymerBlackList_"!==g&&!(g in c||b.polymerBlackList_&&b.polymerBlackList_[g])){N&&b.__lookupGetter__(g);var h,j,o=n(b,g);if(d&&"function"==typeof o.value)c[g]=m(g);else{var p=i(g);h=p?a.getEventHandlerGetter(g):k(g),(o.writable||o.set)&&(j=p?a.getEventHandlerSetter(g):l(g)),K(c,g,{get:h,set:j,configurable:o.configurable,enumerable:o.enumerable})}}}}function p(a,b,c){var e=a.prototype;q(e,b,c),d(b,a)}function q(a,c,d){var e=c.prototype;b(void 0===E.get(a)),E.set(a,c),F.set(e,a),g(a,e),d&&h(e,d),K(e,"constructor",{value:c,configurable:!0,enumerable:!1,writable:!0}),c.prototype=e}function r(a,b){return E.get(b.prototype)===a}function s(a){var b=Object.getPrototypeOf(a),c=f(b),d=t(c);return q(b,d,a),d}function t(a){function b(b){a.call(this,b)}var c=Object.create(a.prototype);return c.constructor=b,b.prototype=c,b}function u(a){return a instanceof G.EventTarget||a instanceof G.Event||a instanceof G.Range||a instanceof G.DOMImplementation||a instanceof G.CanvasRenderingContext2D||G.WebGLRenderingContext&&a instanceof G.WebGLRenderingContext}function v(a){return Q&&a instanceof Q||a instanceof S||a instanceof R||a instanceof T||a instanceof U||a instanceof P||a instanceof V||W&&a instanceof W||X&&a instanceof X}function w(a){return null===a?null:(b(v(a)),a.polymerWrapper_||(a.polymerWrapper_=new(f(a))(a)))}function x(a){return null===a?null:(b(u(a)),a.impl)}function y(a){return a&&u(a)?x(a):a}function z(a){return a&&!u(a)?w(a):a}function A(a,c){null!==c&&(b(v(a)),b(void 0===c||u(c)),a.polymerWrapper_=c)}function B(a,b,c){K(a.prototype,b,{get:c,configurable:!0,enumerable:!0})}function C(a,b){B(a,b,function(){return w(this.impl[b])})}function D(a,b){a.forEach(function(a){b.forEach(function(b){a.prototype[b]=function(){var a=z(this);return a[b].apply(a,arguments)}})})}var E=new WeakMap,F=new WeakMap,G=Object.create(null),H=!("securityPolicy"in document)||document.securityPolicy.allowsEval;if(H)try{var I=new Function("","return true;");H=I()}catch(J){H=!1}var K=Object.defineProperty,L=Object.getOwnPropertyNames,M=Object.getOwnPropertyDescriptor;L(window);var N=/Firefox/.test(navigator.userAgent),O={get:function(){},set:function(){},configurable:!0,enumerable:!0},P=window.DOMImplementation,Q=window.EventTarget,R=window.Event,S=window.Node,T=window.Window,U=window.Range,V=window.CanvasRenderingContext2D,W=window.WebGLRenderingContext,X=window.SVGElementInstance;a.assert=b,a.constructorTable=E,a.defineGetter=B,a.defineWrapGetter=C,a.forwardMethodsToWrapper=D,a.isWrapper=u,a.isWrapperFor=r,a.mixin=c,a.nativePrototypeTable=F,a.oneOf=e,a.registerObject=s,a.registerWrapper=p,a.rewrap=A,a.unwrap=x,a.unwrapIfNeeded=y,a.wrap=w,a.wrapIfNeeded=z,a.wrappers=G}(window.ShadowDOMPolyfill),function(a){"use strict";function b(){g=!1;var a=f.slice(0);f=[];for(var b=0;b<a.length;b++)a[b]()}function c(a){f.push(a),g||(g=!0,d(b,0))}var d,e=window.MutationObserver,f=[],g=!1;if(e){var h=1,i=new e(b),j=document.createTextNode(h);i.observe(j,{characterData:!0}),d=function(){h=(h+1)%2,j.data=h}}else d=window.setImmediate||window.setTimeout;a.setEndOfMicrotask=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(){p||(k(c),p=!0)}function c(){p=!1;do for(var a=o.slice(),b=!1,c=0;c<a.length;c++){var d=a[c],e=d.takeRecords();f(d),e.length&&(d.callback_(e,d),b=!0)}while(b)}function d(a,b){this.type=a,this.target=b,this.addedNodes=new m.NodeList,this.removedNodes=new m.NodeList,this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function e(a,b){for(;a;a=a.parentNode){var c=n.get(a);if(c)for(var d=0;d<c.length;d++){var e=c[d];e.options.subtree&&e.addTransientObserver(b)}}}function f(a){for(var b=0;b<a.nodes_.length;b++){var c=a.nodes_[b],d=n.get(c);if(!d)return;for(var e=0;e<d.length;e++){var f=d[e];f.observer===a&&f.removeTransientObservers()}}}function g(a,c,e){for(var f=Object.create(null),g=Object.create(null),h=a;h;h=h.parentNode){var i=n.get(h);if(i)for(var j=0;j<i.length;j++){var k=i[j],l=k.options;if((h===a||l.subtree)&&!("attributes"===c&&!l.attributes||"attributes"===c&&l.attributeFilter&&(null!==e.namespace||-1===l.attributeFilter.indexOf(e.name))||"characterData"===c&&!l.characterData||"childList"===c&&!l.childList)){var m=k.observer;f[m.uid_]=m,("attributes"===c&&l.attributeOldValue||"characterData"===c&&l.characterDataOldValue)&&(g[m.uid_]=e.oldValue)}}}var o=!1;for(var p in f){var m=f[p],q=new d(c,a);"name"in e&&"namespace"in e&&(q.attributeName=e.name,q.attributeNamespace=e.namespace),e.addedNodes&&(q.addedNodes=e.addedNodes),e.removedNodes&&(q.removedNodes=e.removedNodes),e.previousSibling&&(q.previousSibling=e.previousSibling),e.nextSibling&&(q.nextSibling=e.nextSibling),void 0!==g[p]&&(q.oldValue=g[p]),m.records_.push(q),o=!0}o&&b()}function h(a){if(this.childList=!!a.childList,this.subtree=!!a.subtree,this.attributes="attributes"in a||!("attributeOldValue"in a||"attributeFilter"in a)?!!a.attributes:!0,this.characterData="characterDataOldValue"in a&&!("characterData"in a)?!0:!!a.characterData,!this.attributes&&(a.attributeOldValue||"attributeFilter"in a)||!this.characterData&&a.characterDataOldValue)throw new TypeError;if(this.characterData=!!a.characterData,this.attributeOldValue=!!a.attributeOldValue,this.characterDataOldValue=!!a.characterDataOldValue,"attributeFilter"in a){if(null==a.attributeFilter||"object"!=typeof a.attributeFilter)throw new TypeError;this.attributeFilter=q.call(a.attributeFilter)}else this.attributeFilter=null}function i(a){this.callback_=a,this.nodes_=[],this.records_=[],this.uid_=++r,o.push(this)}function j(a,b,c){this.observer=a,this.target=b,this.options=c,this.transientObservedNodes=[]}var k=a.setEndOfMicrotask,l=a.wrapIfNeeded,m=a.wrappers,n=new WeakMap,o=[],p=!1,q=Array.prototype.slice,r=0;i.prototype={observe:function(a,b){a=l(a);var c,d=new h(b),e=n.get(a);e||n.set(a,e=[]);for(var f=0;f<e.length;f++)e[f].observer===this&&(c=e[f],c.removeTransientObservers(),c.options=d);c||(c=new j(this,a,d),e.push(c),this.nodes_.push(a))},disconnect:function(){this.nodes_.forEach(function(a){for(var b=n.get(a),c=0;c<b.length;c++){var d=b[c];if(d.observer===this){b.splice(c,1);break}}},this),this.records_=[]},takeRecords:function(){var a=this.records_;return this.records_=[],a}},j.prototype={addTransientObserver:function(a){if(a!==this.target){this.transientObservedNodes.push(a);var b=n.get(a);b||n.set(a,b=[]),b.push(this)}},removeTransientObservers:function(){var a=this.transientObservedNodes;this.transientObservedNodes=[];for(var b=0;b<a.length;b++)for(var c=a[b],d=n.get(c),e=0;e<d.length;e++)if(d[e]===this){d.splice(e,1);break}}},a.enqueueMutation=g,a.registerTransientObservers=e,a.wrappers.MutationObserver=i,a.wrappers.MutationRecord=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,b){this.root=a,this.parent=b}function c(a,b){if(a.treeScope_!==b){a.treeScope_=b;for(var d=a.firstChild;d;d=d.nextSibling)c(d,b)}}function d(a){if(a.treeScope_)return a.treeScope_;var c,e=a.parentNode;return c=e?d(e):new b(a,null),a.treeScope_=c}b.prototype={get renderer(){return this.root instanceof a.wrappers.ShadowRoot?a.getRendererForHost(this.root.host):null},contains:function(a){for(;a;a=a.parent)if(a===this)return!0;return!1}},a.TreeScope=b,a.getTreeScope=d,a.setTreeScope=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a instanceof P.ShadowRoot}function c(a){var b=a.localName;return"content"===b||"shadow"===b}function d(a){return!!a.shadowRoot}function e(a){var b;return a.parentNode||(b=a.defaultView)&&O(b)||null}function f(f,g,h){if(h.length)return h.shift();if(b(f))return j(f)||f.host;var i=a.eventParentsTable.get(f);if(i){for(var k=1;k<i.length;k++)h[k-1]=i[k];return i[0]}if(g&&c(f)){var l=f.parentNode;if(l&&d(l))for(var m=a.getShadowTrees(l),n=j(g),k=0;k<m.length;k++)if(m[k].contains(n))return n}return e(f)}function g(a){for(var d=[],e=a,g=[],i=[];e;){var j=null;if(c(e)){j=h(d);var k=d[d.length-1]||e;d.push(k)}else d.length||d.push(e);var l=d[d.length-1];g.push({target:l,currentTarget:e}),b(e)&&d.pop(),e=f(e,j,i)}return g}function h(a){for(var b=a.length-1;b>=0;b--)if(!c(a[b]))return a[b];return null}function i(a,d){for(var e=[];a;){for(var g=[],i=d,j=void 0;i;){var m=null;if(g.length){if(c(i)&&(m=h(g),k(j))){var n=g[g.length-1];g.push(n)}}else g.push(i);if(l(i,a))return g[g.length-1];b(i)&&g.pop(),j=i,i=f(i,m,e)}a=b(a)?a.host:a.parentNode}}function j(b){return a.insertionParentTable.get(b)}function k(a){return j(a)}function l(a,b){return K(a)===K(b)}function m(a){return R.get(a)?void 0:(R.set(a,!0),n(O(a),O(a.target)))}function n(b,c){if(S.get(b))throw new Error("InvalidStateError");S.set(b,!0),a.renderAllPending();var d=g(c);return"load"===b.type&&2===d.length&&d[0].target instanceof P.Document&&d.shift(),$.set(b,d),o(b,d)&&p(b,d)&&q(b,d),W.set(b,t.NONE),U.delete(b,null),S.delete(b),b.defaultPrevented}function o(a,b){for(var c,d=b.length-1;d>0;d--){var e=b[d].target,f=b[d].currentTarget;if(e!==f&&(c=t.CAPTURING_PHASE,!r(b[d],a,c)))return!1}return!0}function p(a,b){var c=t.AT_TARGET;return r(b[0],a,c)}function q(a,b){for(var c,d=a.bubbles,e=1;e<b.length;e++){var f=b[e].target,g=b[e].currentTarget;if(f===g)c=t.AT_TARGET;else{if(!d||Y.get(a))continue;c=t.BUBBLING_PHASE}if(!r(b[e],a,c))return}}function r(a,b,c){var d=a.target,e=a.currentTarget,f=Q.get(e);if(!f)return!0;if("relatedTarget"in b){var g=N(b);if(g.relatedTarget){var h=O(g.relatedTarget),j=i(e,h);if(j===d)return!0;V.set(b,j)}}W.set(b,c);var k=b.type,l=!1;T.set(b,d),U.set(b,e);for(var m=0;m<f.length;m++){var n=f[m];if(n.removed)l=!0;else if(!(n.type!==k||!n.capture&&c===t.CAPTURING_PHASE||n.capture&&c===t.BUBBLING_PHASE))try{if("function"==typeof n.handler?n.handler.call(e,b):n.handler.handleEvent(b),Y.get(b))return!1}catch(o){window.onerror?window.onerror(o.message):console.error(o,o.stack)}}if(l){var p=f.slice();f.length=0;for(var m=0;m<p.length;m++)p[m].removed||f.push(p[m])}return!X.get(b)}function s(a,b,c){this.type=a,this.handler=b,this.capture=Boolean(c)}function t(a,b){return a instanceof _?void(this.impl=a):O(x(_,"Event",a,b))}function u(a){return a&&a.relatedTarget?Object.create(a,{relatedTarget:{value:N(a.relatedTarget)}}):a}function v(a,b,c){var d=window[a],e=function(b,c){return b instanceof d?void(this.impl=b):O(x(d,a,b,c))};if(e.prototype=Object.create(b.prototype),c&&L(e.prototype,c),d)try{M(d,e,new d("temp"))}catch(f){M(d,e,document.createEvent(a))}return e}function w(a,b){return function(){arguments[b]=N(arguments[b]);var c=N(this);c[a].apply(c,arguments)}}function x(a,b,c,d){if(ib)return new a(c,u(d));var e=N(document.createEvent(b)),f=hb[b],g=[c];return Object.keys(f).forEach(function(a){var b=null!=d&&a in d?d[a]:f[a];"relatedTarget"===a&&(b=N(b)),g.push(b)}),e["init"+b].apply(e,g),e}function y(){t.call(this)}function z(a){return"function"==typeof a?!0:a&&a.handleEvent}function A(a){switch(a){case"DOMAttrModified":case"DOMAttributeNameChanged":case"DOMCharacterDataModified":case"DOMElementNameChanged":case"DOMNodeInserted":case"DOMNodeInsertedIntoDocument":case"DOMNodeRemoved":case"DOMNodeRemovedFromDocument":case"DOMSubtreeModified":return!0}return!1}function B(a){this.impl=a}function C(a){return a instanceof P.ShadowRoot&&(a=a.host),N(a)}function D(a,b){var c=Q.get(a);if(c)for(var d=0;d<c.length;d++)if(!c[d].removed&&c[d].type===b)return!0;return!1}function E(a,b){for(var c=N(a);c;c=c.parentNode)if(D(O(c),b))return!0;return!1}function F(a){J(a,lb)}function G(b,c,d,e){a.renderAllPending();for(var f=O(mb.call(c.impl,d,e)),h=g(f,this),i=0;i<h.length;i++){var j=h[i];if(j.currentTarget===b)return j.target}return null}function H(a){return function(){var b=Z.get(this);return b&&b[a]&&b[a].value||null}}function I(a){var b=a.slice(2);return function(c){var d=Z.get(this);d||(d=Object.create(null),Z.set(this,d));var e=d[a];if(e&&this.removeEventListener(b,e.wrapped,!1),"function"==typeof c){var f=function(b){var d=c.call(this,b);d===!1?b.preventDefault():"onbeforeunload"===a&&"string"==typeof d&&(b.returnValue=d)};this.addEventListener(b,f,!1),d[a]={value:c,wrapped:f}}}}var J=a.forwardMethodsToWrapper,K=a.getTreeScope,L=a.mixin,M=a.registerWrapper,N=a.unwrap,O=a.wrap,P=a.wrappers,Q=(new WeakMap,new WeakMap),R=new WeakMap,S=new WeakMap,T=new WeakMap,U=new WeakMap,V=new WeakMap,W=new WeakMap,X=new WeakMap,Y=new WeakMap,Z=new WeakMap,$=new WeakMap;s.prototype={equals:function(a){return this.handler===a.handler&&this.type===a.type&&this.capture===a.capture},get removed(){return null===this.handler},remove:function(){this.handler=null}};var _=window.Event;_.prototype.polymerBlackList_={returnValue:!0,keyLocation:!0},t.prototype={get target(){return T.get(this)},get currentTarget(){return U.get(this)},get eventPhase(){return W.get(this)},get path(){var a=new P.NodeList,b=$.get(this);if(b){for(var c=0,d=b.length-1,e=K(U.get(this)),f=0;d>=f;f++){var g=b[f].currentTarget,h=K(g);h.contains(e)&&(f!==d||g instanceof P.Node)&&(a[c++]=g)}a.length=c}return a},stopPropagation:function(){X.set(this,!0)},stopImmediatePropagation:function(){X.set(this,!0),Y.set(this,!0)}},M(_,t,document.createEvent("Event"));
-var ab=v("UIEvent",t),bb=v("CustomEvent",t),cb={get relatedTarget(){return V.get(this)||O(N(this).relatedTarget)}},db=L({initMouseEvent:w("initMouseEvent",14)},cb),eb=L({initFocusEvent:w("initFocusEvent",5)},cb),fb=v("MouseEvent",ab,db),gb=v("FocusEvent",ab,eb),hb=Object.create(null),ib=function(){try{new window.FocusEvent("focus")}catch(a){return!1}return!0}();if(!ib){var jb=function(a,b,c){if(c){var d=hb[c];b=L(L({},d),b)}hb[a]=b};jb("Event",{bubbles:!1,cancelable:!1}),jb("CustomEvent",{detail:null},"Event"),jb("UIEvent",{view:null,detail:0},"Event"),jb("MouseEvent",{screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:null},"UIEvent"),jb("FocusEvent",{relatedTarget:null},"UIEvent")}y.prototype=Object.create(t.prototype),L(y.prototype,{get returnValue(){return this.impl.returnValue},set returnValue(a){this.impl.returnValue=a}});var kb=window.EventTarget,lb=["addEventListener","removeEventListener","dispatchEvent"];[Node,Window].forEach(function(a){var b=a.prototype;lb.forEach(function(a){Object.defineProperty(b,a+"_",{value:b[a]})})}),B.prototype={addEventListener:function(a,b,c){if(z(b)&&!A(a)){var d=new s(a,b,c),e=Q.get(this);if(e){for(var f=0;f<e.length;f++)if(d.equals(e[f]))return}else e=[],Q.set(this,e);e.push(d);var g=C(this);g.addEventListener_(a,m,!0)}},removeEventListener:function(a,b,c){c=Boolean(c);var d=Q.get(this);if(d){for(var e=0,f=!1,g=0;g<d.length;g++)d[g].type===a&&d[g].capture===c&&(e++,d[g].handler===b&&(f=!0,d[g].remove()));if(f&&1===e){var h=C(this);h.removeEventListener_(a,m,!0)}}},dispatchEvent:function(b){var c=N(b),d=c.type;R.set(c,!1),a.renderAllPending();var e;E(this,d)||(e=function(){},this.addEventListener(d,e,!0));try{return N(this).dispatchEvent_(c)}finally{e&&this.removeEventListener(d,e,!0)}}},kb&&M(kb,B);var mb=document.elementFromPoint;a.adjustRelatedTarget=i,a.elementFromPoint=G,a.getEventHandlerGetter=H,a.getEventHandlerSetter=I,a.wrapEventTargetMethods=F,a.wrappers.BeforeUnloadEvent=y,a.wrappers.CustomEvent=bb,a.wrappers.Event=t,a.wrappers.EventTarget=B,a.wrappers.FocusEvent=gb,a.wrappers.MouseEvent=fb,a.wrappers.UIEvent=ab}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,b){Object.defineProperty(a,b,{enumerable:!1})}function c(){this.length=0,b(this,"length")}function d(a){if(null==a)return a;for(var b=new c,d=0,e=a.length;e>d;d++)b[d]=f(a[d]);return b.length=e,b}function e(a,b){a.prototype[b]=function(){return d(this.impl[b].apply(this.impl,arguments))}}var f=a.wrap;c.prototype={item:function(a){return this[a]}},b(c.prototype,"item"),a.wrappers.NodeList=c,a.addWrapNodeListMethod=e,a.wrapNodeList=d}(window.ShadowDOMPolyfill),function(a){"use strict";a.wrapHTMLCollection=a.wrapNodeList,a.wrappers.HTMLCollection=a.wrappers.NodeList}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){A(a instanceof w)}function c(a){var b=new y;return b[0]=a,b.length=1,b}function d(a,b,c){C(b,"childList",{removedNodes:c,previousSibling:a.previousSibling,nextSibling:a.nextSibling})}function e(a,b){C(a,"childList",{removedNodes:b})}function f(a,b,d,e){if(a instanceof DocumentFragment){var f=h(a);N=!0;for(var g=f.length-1;g>=0;g--)a.removeChild(f[g]),f[g].parentNode_=b;N=!1;for(var g=0;g<f.length;g++)f[g].previousSibling_=f[g-1]||d,f[g].nextSibling_=f[g+1]||e;return d&&(d.nextSibling_=f[0]),e&&(e.previousSibling_=f[f.length-1]),f}var f=c(a),i=a.parentNode;return i&&i.removeChild(a),a.parentNode_=b,a.previousSibling_=d,a.nextSibling_=e,d&&(d.nextSibling_=a),e&&(e.previousSibling_=a),f}function g(a){if(a instanceof DocumentFragment)return h(a);var b=c(a),e=a.parentNode;return e&&d(a,e,b),b}function h(a){for(var b=new y,c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b.length=c,e(a,b),b}function i(a){return a}function j(a,b){I(a,b),a.nodeIsInserted_()}function k(a,b){for(var c=D(b),d=0;d<a.length;d++)j(a[d],c)}function l(a){I(a,new z(a,null))}function m(a){for(var b=0;b<a.length;b++)l(a[b])}function n(a,b){var c=a.nodeType===w.DOCUMENT_NODE?a:a.ownerDocument;c!==b.ownerDocument&&c.adoptNode(b)}function o(b,c){if(c.length){var d=b.ownerDocument;if(d!==c[0].ownerDocument)for(var e=0;e<c.length;e++)a.adoptNodeNoRemove(c[e],d)}}function p(a,b){o(a,b);var c=b.length;if(1===c)return J(b[0]);for(var d=J(a.ownerDocument.createDocumentFragment()),e=0;c>e;e++)d.appendChild(J(b[e]));return d}function q(a){if(void 0!==a.firstChild_)for(var b=a.firstChild_;b;){var c=b;b=b.nextSibling_,c.parentNode_=c.previousSibling_=c.nextSibling_=void 0}a.firstChild_=a.lastChild_=void 0}function r(a){if(a.invalidateShadowRenderer()){for(var b=a.firstChild;b;){A(b.parentNode===a);var c=b.nextSibling,d=J(b),e=d.parentNode;e&&U.call(e,d),b.previousSibling_=b.nextSibling_=b.parentNode_=null,b=c}a.firstChild_=a.lastChild_=null}else for(var c,f=J(a),g=f.firstChild;g;)c=g.nextSibling,U.call(f,g),g=c}function s(a){var b=a.parentNode;return b&&b.invalidateShadowRenderer()}function t(a){for(var b,c=0;c<a.length;c++)b=a[c],b.parentNode.removeChild(b)}function u(a,b,c){var d;if(d=K(c?O.call(c,a.impl,!1):P.call(a.impl,!1)),b){for(var e=a.firstChild;e;e=e.nextSibling)d.appendChild(u(e,!0,c));if(a instanceof M.HTMLTemplateElement)for(var f=d.content,e=a.content.firstChild;e;e=e.nextSibling)f.appendChild(u(e,!0,c))}return d}function v(a,b){if(!b||D(a)!==D(b))return!1;for(var c=b;c;c=c.parentNode)if(c===a)return!0;return!1}function w(a){A(a instanceof Q),x.call(this,a),this.parentNode_=void 0,this.firstChild_=void 0,this.lastChild_=void 0,this.nextSibling_=void 0,this.previousSibling_=void 0,this.treeScope_=void 0}var x=a.wrappers.EventTarget,y=a.wrappers.NodeList,z=a.TreeScope,A=a.assert,B=a.defineWrapGetter,C=a.enqueueMutation,D=a.getTreeScope,E=a.isWrapper,F=a.mixin,G=a.registerTransientObservers,H=a.registerWrapper,I=a.setTreeScope,J=a.unwrap,K=a.wrap,L=a.wrapIfNeeded,M=a.wrappers,N=!1,O=document.importNode,P=window.Node.prototype.cloneNode,Q=window.Node,R=window.DocumentFragment,S=(Q.prototype.appendChild,Q.prototype.compareDocumentPosition),T=Q.prototype.insertBefore,U=Q.prototype.removeChild,V=Q.prototype.replaceChild,W=/Trident/.test(navigator.userAgent),X=W?function(a,b){try{U.call(a,b)}catch(c){if(!(a instanceof R))throw c}}:function(a,b){U.call(a,b)};w.prototype=Object.create(x.prototype),F(w.prototype,{appendChild:function(a){return this.insertBefore(a,null)},insertBefore:function(a,c){b(a);var d;c?E(c)?d=J(c):(d=c,c=K(d)):(c=null,d=null),c&&A(c.parentNode===this);var e,h=c?c.previousSibling:this.lastChild,i=!this.invalidateShadowRenderer()&&!s(a);if(e=i?g(a):f(a,this,h,c),i)n(this,a),q(this),T.call(this.impl,J(a),d);else{h||(this.firstChild_=e[0]),c||(this.lastChild_=e[e.length-1]);var j=d?d.parentNode:this.impl;j?T.call(j,p(this,e),d):o(this,e)}return C(this,"childList",{addedNodes:e,nextSibling:c,previousSibling:h}),k(e,this),a},removeChild:function(a){if(b(a),a.parentNode!==this){for(var d=!1,e=(this.childNodes,this.firstChild);e;e=e.nextSibling)if(e===a){d=!0;break}if(!d)throw new Error("NotFoundError")}var f=J(a),g=a.nextSibling,h=a.previousSibling;if(this.invalidateShadowRenderer()){var i=this.firstChild,j=this.lastChild,k=f.parentNode;k&&X(k,f),i===a&&(this.firstChild_=g),j===a&&(this.lastChild_=h),h&&(h.nextSibling_=g),g&&(g.previousSibling_=h),a.previousSibling_=a.nextSibling_=a.parentNode_=void 0}else q(this),X(this.impl,f);return N||C(this,"childList",{removedNodes:c(a),nextSibling:g,previousSibling:h}),G(this,a),a},replaceChild:function(a,d){b(a);var e;if(E(d)?e=J(d):(e=d,d=K(e)),d.parentNode!==this)throw new Error("NotFoundError");var h,i=d.nextSibling,j=d.previousSibling,m=!this.invalidateShadowRenderer()&&!s(a);return m?h=g(a):(i===a&&(i=a.nextSibling),h=f(a,this,j,i)),m?(n(this,a),q(this),V.call(this.impl,J(a),e)):(this.firstChild===d&&(this.firstChild_=h[0]),this.lastChild===d&&(this.lastChild_=h[h.length-1]),d.previousSibling_=d.nextSibling_=d.parentNode_=void 0,e.parentNode&&V.call(e.parentNode,p(this,h),e)),C(this,"childList",{addedNodes:h,removedNodes:c(d),nextSibling:i,previousSibling:j}),l(d),k(h,this),d},nodeIsInserted_:function(){for(var a=this.firstChild;a;a=a.nextSibling)a.nodeIsInserted_()},hasChildNodes:function(){return null!==this.firstChild},get parentNode(){return void 0!==this.parentNode_?this.parentNode_:K(this.impl.parentNode)},get firstChild(){return void 0!==this.firstChild_?this.firstChild_:K(this.impl.firstChild)},get lastChild(){return void 0!==this.lastChild_?this.lastChild_:K(this.impl.lastChild)},get nextSibling(){return void 0!==this.nextSibling_?this.nextSibling_:K(this.impl.nextSibling)},get previousSibling(){return void 0!==this.previousSibling_?this.previousSibling_:K(this.impl.previousSibling)},get parentElement(){for(var a=this.parentNode;a&&a.nodeType!==w.ELEMENT_NODE;)a=a.parentNode;return a},get textContent(){for(var a="",b=this.firstChild;b;b=b.nextSibling)b.nodeType!=w.COMMENT_NODE&&(a+=b.textContent);return a},set textContent(a){var b=i(this.childNodes);if(this.invalidateShadowRenderer()){if(r(this),""!==a){var c=this.impl.ownerDocument.createTextNode(a);this.appendChild(c)}}else q(this),this.impl.textContent=a;var d=i(this.childNodes);C(this,"childList",{addedNodes:d,removedNodes:b}),m(b),k(d,this)},get childNodes(){for(var a=new y,b=0,c=this.firstChild;c;c=c.nextSibling)a[b++]=c;return a.length=b,a},cloneNode:function(a){return u(this,a)},contains:function(a){return v(this,L(a))},compareDocumentPosition:function(a){return S.call(this.impl,J(a))},normalize:function(){for(var a,b,c=i(this.childNodes),d=[],e="",f=0;f<c.length;f++)b=c[f],b.nodeType===w.TEXT_NODE?a||b.data.length?a?(e+=b.data,d.push(b)):a=b:this.removeNode(b):(a&&d.length&&(a.data+=e,cleanUpNodes(d)),d=[],e="",a=null,b.childNodes.length&&b.normalize());a&&d.length&&(a.data+=e,t(d))}}),B(w,"ownerDocument"),H(Q,w,document.createDocumentFragment()),delete w.prototype.querySelector,delete w.prototype.querySelectorAll,w.prototype=F(Object.create(x.prototype),w.prototype),a.cloneNode=u,a.nodeWasAdded=j,a.nodeWasRemoved=l,a.nodesWereAdded=k,a.nodesWereRemoved=m,a.snapshotNodeList=i,a.wrappers.Node=w}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,c){for(var d,e=a.firstElementChild;e;){if(e.matches(c))return e;if(d=b(e,c))return d;e=e.nextElementSibling}return null}function c(a,b,d){for(var e=a.firstElementChild;e;)e.matches(b)&&(d[d.length++]=e),c(e,b,d),e=e.nextElementSibling;return d}var d={querySelector:function(a){return b(this,a)},querySelectorAll:function(a){return c(this,a,new NodeList)}},e={getElementsByTagName:function(a){return this.querySelectorAll(a)},getElementsByClassName:function(a){return this.querySelectorAll("."+a)},getElementsByTagNameNS:function(a,b){if("*"===a)return this.getElementsByTagName(b);for(var c=new NodeList,d=this.getElementsByTagName(b),e=0,f=0;e<d.length;e++)d[e].namespaceURI===a&&(c[f++]=d[e]);return c.length=f,c}};a.GetElementsByInterface=e,a.SelectorsInterface=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}function c(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}var d=a.wrappers.NodeList,e={get firstElementChild(){return b(this.firstChild)},get lastElementChild(){return c(this.lastChild)},get childElementCount(){for(var a=0,b=this.firstElementChild;b;b=b.nextElementSibling)a++;return a},get children(){for(var a=new d,b=0,c=this.firstElementChild;c;c=c.nextElementSibling)a[b++]=c;return a.length=b,a}},f={get nextElementSibling(){return b(this.nextSibling)},get previousElementSibling(){return c(this.previousSibling)}};a.ChildNodeInterface=f,a.ParentNodeInterface=e}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}var c=a.ChildNodeInterface,d=a.wrappers.Node,e=a.enqueueMutation,f=a.mixin,g=a.registerWrapper,h=window.CharacterData;b.prototype=Object.create(d.prototype),f(b.prototype,{get textContent(){return this.data},set textContent(a){this.data=a},get data(){return this.impl.data},set data(a){var b=this.impl.data;e(this,"characterData",{oldValue:b}),this.impl.data=a}}),f(b.prototype,c),g(h,b,document.createTextNode("")),a.wrappers.CharacterData=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a>>>0}function c(a){d.call(this,a)}var d=a.wrappers.CharacterData,e=(a.enqueueMutation,a.mixin),f=a.registerWrapper,g=window.Text;c.prototype=Object.create(d.prototype),e(c.prototype,{splitText:function(a){a=b(a);var c=this.data;if(a>c.length)throw new Error("IndexSizeError");var d=c.slice(0,a),e=c.slice(a);this.data=d;var f=this.ownerDocument.createTextNode(e);return this.parentNode&&this.parentNode.insertBefore(f,this.nextSibling),f}}),f(g,c,document.createTextNode("")),a.wrappers.Text=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(b,c){var d=b.parentNode;if(d&&d.shadowRoot){var e=a.getRendererForHost(d);e.dependsOnAttribute(c)&&e.invalidate()}}function c(a,b,c){k(a,"attributes",{name:b,namespace:null,oldValue:c})}function d(a){h.call(this,a)}function e(a,c,d){var e=d||c;Object.defineProperty(a,c,{get:function(){return this.impl[c]},set:function(a){this.impl[c]=a,b(this,e)},configurable:!0,enumerable:!0})}var f=a.ChildNodeInterface,g=a.GetElementsByInterface,h=a.wrappers.Node,i=a.ParentNodeInterface,j=a.SelectorsInterface,k=(a.addWrapNodeListMethod,a.enqueueMutation),l=a.mixin,m=(a.oneOf,a.registerWrapper),n=a.wrappers,o=window.Element,p=["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"].filter(function(a){return o.prototype[a]}),q=p[0],r=o.prototype[q];d.prototype=Object.create(h.prototype),l(d.prototype,{createShadowRoot:function(){var b=new n.ShadowRoot(this);this.impl.polymerShadowRoot_=b;var c=a.getRendererForHost(this);return c.invalidate(),b},get shadowRoot(){return this.impl.polymerShadowRoot_||null},setAttribute:function(a,d){var e=this.impl.getAttribute(a);this.impl.setAttribute(a,d),c(this,a,e),b(this,a)},removeAttribute:function(a){var d=this.impl.getAttribute(a);this.impl.removeAttribute(a),c(this,a,d),b(this,a)},matches:function(a){return r.call(this.impl,a)}}),p.forEach(function(a){"matches"!==a&&(d.prototype[a]=function(a){return this.matches(a)})}),o.prototype.webkitCreateShadowRoot&&(d.prototype.webkitCreateShadowRoot=d.prototype.createShadowRoot),e(d.prototype,"id"),e(d.prototype,"className","class"),l(d.prototype,f),l(d.prototype,g),l(d.prototype,i),l(d.prototype,j),m(o,d,document.createElementNS(null,"x")),a.matchesNames=p,a.wrappers.Element=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a){case"&":return"&amp;";case"<":return"&lt;";case">":return"&gt;";case'"':return"&quot;";case" ":return"&nbsp;"}}function c(a){return a.replace(z,b)}function d(a){return a.replace(A,b)}function e(a){for(var b={},c=0;c<a.length;c++)b[a[c]]=!0;return b}function f(a,b){switch(a.nodeType){case Node.ELEMENT_NODE:for(var e,f=a.tagName.toLowerCase(),h="<"+f,i=a.attributes,j=0;e=i[j];j++)h+=" "+e.name+'="'+c(e.value)+'"';return h+=">",B[f]?h:h+g(a)+"</"+f+">";case Node.TEXT_NODE:var k=a.data;return b&&C[b.localName]?k:d(k);case Node.COMMENT_NODE:return"<!--"+a.data+"-->";default:throw console.error(a),new Error("not implemented")}}function g(a){a instanceof y.HTMLTemplateElement&&(a=a.content);for(var b="",c=a.firstChild;c;c=c.nextSibling)b+=f(c,a);return b}function h(a,b,c){var d=c||"div";a.textContent="";var e=w(a.ownerDocument.createElement(d));e.innerHTML=b;for(var f;f=e.firstChild;)a.appendChild(x(f))}function i(a){o.call(this,a)}function j(a,b){var c=w(a.cloneNode(!1));c.innerHTML=b;for(var d,e=w(document.createDocumentFragment());d=c.firstChild;)e.appendChild(d);return x(e)}function k(b){return function(){return a.renderAllPending(),this.impl[b]}}function l(a){p(i,a,k(a))}function m(b){Object.defineProperty(i.prototype,b,{get:k(b),set:function(c){a.renderAllPending(),this.impl[b]=c},configurable:!0,enumerable:!0})}function n(b){Object.defineProperty(i.prototype,b,{value:function(){return a.renderAllPending(),this.impl[b].apply(this.impl,arguments)},configurable:!0,enumerable:!0})}var o=a.wrappers.Element,p=a.defineGetter,q=a.enqueueMutation,r=a.mixin,s=a.nodesWereAdded,t=a.nodesWereRemoved,u=a.registerWrapper,v=a.snapshotNodeList,w=a.unwrap,x=a.wrap,y=a.wrappers,z=/[&\u00A0"]/g,A=/[&\u00A0<>]/g,B=e(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),C=e(["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"]),D=/MSIE/.test(navigator.userAgent),E=window.HTMLElement,F=window.HTMLTemplateElement;i.prototype=Object.create(o.prototype),r(i.prototype,{get innerHTML(){return g(this)},set innerHTML(a){if(D&&C[this.localName])return void(this.textContent=a);var b=v(this.childNodes);this.invalidateShadowRenderer()?this instanceof y.HTMLTemplateElement?h(this.content,a):h(this,a,this.tagName):!F&&this instanceof y.HTMLTemplateElement?h(this.content,a):this.impl.innerHTML=a;var c=v(this.childNodes);q(this,"childList",{addedNodes:c,removedNodes:b}),t(b),s(c,this)},get outerHTML(){return f(this,this.parentNode)},set outerHTML(a){var b=this.parentNode;if(b){b.invalidateShadowRenderer();var c=j(b,a);b.replaceChild(c,this)}},insertAdjacentHTML:function(a,b){var c,d;switch(String(a).toLowerCase()){case"beforebegin":c=this.parentNode,d=this;break;case"afterend":c=this.parentNode,d=this.nextSibling;break;case"afterbegin":c=this,d=this.firstChild;break;case"beforeend":c=this,d=null;break;default:return}var e=j(c,b);c.insertBefore(e,d)}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(l),["scrollLeft","scrollTop"].forEach(m),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(n),u(E,i,document.createElement("b")),a.wrappers.HTMLElement=i,a.getInnerHTML=g,a.setInnerHTML=h}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.wrap,g=window.HTMLCanvasElement;b.prototype=Object.create(c.prototype),d(b.prototype,{getContext:function(){var a=this.impl.getContext.apply(this.impl,arguments);return a&&f(a)}}),e(g,b,document.createElement("canvas")),a.wrappers.HTMLCanvasElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLContentElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get select(){return this.getAttribute("select")},set select(a){this.setAttribute("select",a)},setAttribute:function(a,b){c.prototype.setAttribute.call(this,a,b),"select"===String(a).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),f&&e(f,b),a.wrappers.HTMLContentElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}function c(a,b){if(!(this instanceof c))throw new TypeError("DOM object constructor cannot be called as a function.");var e=f(document.createElement("img"));d.call(this,e),g(e,this),void 0!==a&&(e.width=a),void 0!==b&&(e.height=b)}var d=a.wrappers.HTMLElement,e=a.registerWrapper,f=a.unwrap,g=a.rewrap,h=window.HTMLImageElement;b.prototype=Object.create(d.prototype),e(h,b,document.createElement("img")),c.prototype=b.prototype,a.wrappers.HTMLImageElement=b,a.wrappers.Image=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLShadowElement;b.prototype=Object.create(c.prototype),d(b.prototype,{}),f&&e(f,b),a.wrappers.HTMLShadowElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){if(!a.defaultView)return a;var b=k.get(a);if(!b){for(b=a.implementation.createHTMLDocument("");b.lastChild;)b.removeChild(b.lastChild);k.set(a,b)}return b}function c(a){for(var c,d=b(a.ownerDocument),e=h(d.createDocumentFragment());c=a.firstChild;)e.appendChild(c);return e}function d(a){if(e.call(this,a),!l){var b=c(a);j.set(this,i(b))}}var e=a.wrappers.HTMLElement,f=a.mixin,g=a.registerWrapper,h=a.unwrap,i=a.wrap,j=new WeakMap,k=new WeakMap,l=window.HTMLTemplateElement;d.prototype=Object.create(e.prototype),f(d.prototype,{get content(){return l?i(this.impl.content):j.get(this)}}),l&&g(l,d),a.wrappers.HTMLTemplateElement=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.registerWrapper,e=window.HTMLMediaElement;b.prototype=Object.create(c.prototype),d(e,b,document.createElement("audio")),a.wrappers.HTMLMediaElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}function c(a){if(!(this instanceof c))throw new TypeError("DOM object constructor cannot be called as a function.");var b=f(document.createElement("audio"));d.call(this,b),g(b,this),b.setAttribute("preload","auto"),void 0!==a&&b.setAttribute("src",a)}var d=a.wrappers.HTMLMediaElement,e=a.registerWrapper,f=a.unwrap,g=a.rewrap,h=window.HTMLAudioElement;b.prototype=Object.create(d.prototype),e(h,b,document.createElement("audio")),c.prototype=b.prototype,a.wrappers.HTMLAudioElement=b,a.wrappers.Audio=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a.replace(/\s+/g," ").trim()}function c(a){e.call(this,a)}function d(a,b,c,f){if(!(this instanceof d))throw new TypeError("DOM object constructor cannot be called as a function.");var g=i(document.createElement("option"));e.call(this,g),h(g,this),void 0!==a&&(g.text=a),void 0!==b&&g.setAttribute("value",b),c===!0&&g.setAttribute("selected",""),g.selected=f===!0}var e=a.wrappers.HTMLElement,f=a.mixin,g=a.registerWrapper,h=a.rewrap,i=a.unwrap,j=a.wrap,k=window.HTMLOptionElement;c.prototype=Object.create(e.prototype),f(c.prototype,{get text(){return b(this.textContent)},set text(a){this.textContent=b(String(a))},get form(){return j(i(this).form)}}),g(k,c,document.createElement("option")),d.prototype=c.prototype,a.wrappers.HTMLOptionElement=c,a.wrappers.Option=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.unwrap,g=a.wrap,h=window.HTMLSelectElement;b.prototype=Object.create(c.prototype),d(b.prototype,{add:function(a,b){"object"==typeof b&&(b=f(b)),f(this).add(f(a),b)},remove:function(a){"object"==typeof a&&(a=f(a)),f(this).remove(a)},get form(){return g(f(this).form)}}),e(h,b,document.createElement("select")),a.wrappers.HTMLSelectElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.unwrap,g=a.wrap,h=a.wrapHTMLCollection,i=window.HTMLTableElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get caption(){return g(f(this).caption)},createCaption:function(){return g(f(this).createCaption())},get tHead(){return g(f(this).tHead)},createTHead:function(){return g(f(this).createTHead())},createTFoot:function(){return g(f(this).createTFoot())},get tFoot(){return g(f(this).tFoot)},get tBodies(){return h(f(this).tBodies)},createTBody:function(){return g(f(this).createTBody())},get rows(){return h(f(this).rows)},insertRow:function(a){return g(f(this).insertRow(a))}}),e(i,b,document.createElement("table")),a.wrappers.HTMLTableElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.wrapHTMLCollection,g=a.unwrap,h=a.wrap,i=window.HTMLTableSectionElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get rows(){return f(g(this).rows)},insertRow:function(a){return h(g(this).insertRow(a))}}),e(i,b,document.createElement("thead")),a.wrappers.HTMLTableSectionElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.wrapHTMLCollection,g=a.unwrap,h=a.wrap,i=window.HTMLTableRowElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get cells(){return f(g(this).cells)},insertCell:function(a){return h(g(this).insertCell(a))}}),e(i,b,document.createElement("tr")),a.wrappers.HTMLTableRowElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a.localName){case"content":return new c(a);case"shadow":return new e(a);case"template":return new f(a)}d.call(this,a)}var c=a.wrappers.HTMLContentElement,d=a.wrappers.HTMLElement,e=a.wrappers.HTMLShadowElement,f=a.wrappers.HTMLTemplateElement,g=(a.mixin,a.registerWrapper),h=window.HTMLUnknownElement;b.prototype=Object.create(d.prototype),g(h,b),a.wrappers.HTMLUnknownElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";var b=a.registerObject,c="http://www.w3.org/2000/svg",d=document.createElementNS(c,"title"),e=b(d),f=Object.getPrototypeOf(e.prototype).constructor;a.wrappers.SVGElement=f}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){m.call(this,a)}var c=a.mixin,d=a.registerWrapper,e=a.unwrap,f=a.wrap,g=window.SVGUseElement,h="http://www.w3.org/2000/svg",i=f(document.createElementNS(h,"g")),j=document.createElementNS(h,"use"),k=i.constructor,l=Object.getPrototypeOf(k.prototype),m=l.constructor;b.prototype=Object.create(l),"instanceRoot"in j&&c(b.prototype,{get instanceRoot(){return f(e(this).instanceRoot)},get animatedInstanceRoot(){return f(e(this).animatedInstanceRoot)}}),d(g,b,j),a.wrappers.SVGUseElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.EventTarget,d=a.mixin,e=a.registerWrapper,f=a.wrap,g=window.SVGElementInstance;g&&(b.prototype=Object.create(c.prototype),d(b.prototype,{get correspondingElement(){return f(this.impl.correspondingElement)},get correspondingUseElement(){return f(this.impl.correspondingUseElement)},get parentNode(){return f(this.impl.parentNode)},get childNodes(){throw new Error("Not implemented")},get firstChild(){return f(this.impl.firstChild)},get lastChild(){return f(this.impl.lastChild)},get previousSibling(){return f(this.impl.previousSibling)},get nextSibling(){return f(this.impl.nextSibling)}}),e(g,b),a.wrappers.SVGElementInstance=b)}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.mixin,d=a.registerWrapper,e=a.unwrap,f=a.unwrapIfNeeded,g=a.wrap,h=window.CanvasRenderingContext2D;c(b.prototype,{get canvas(){return g(this.impl.canvas)},drawImage:function(){arguments[0]=f(arguments[0]),this.impl.drawImage.apply(this.impl,arguments)},createPattern:function(){return arguments[0]=e(arguments[0]),this.impl.createPattern.apply(this.impl,arguments)}}),d(h,b,document.createElement("canvas").getContext("2d")),a.wrappers.CanvasRenderingContext2D=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.mixin,d=a.registerWrapper,e=a.unwrapIfNeeded,f=a.wrap,g=window.WebGLRenderingContext;if(g){c(b.prototype,{get canvas(){return f(this.impl.canvas)},texImage2D:function(){arguments[5]=e(arguments[5]),this.impl.texImage2D.apply(this.impl,arguments)},texSubImage2D:function(){arguments[6]=e(arguments[6]),this.impl.texSubImage2D.apply(this.impl,arguments)}});var h=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};d(g,b,h),a.wrappers.WebGLRenderingContext=b}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.registerWrapper,d=a.unwrap,e=a.unwrapIfNeeded,f=a.wrap,g=window.Range;b.prototype={get startContainer(){return f(this.impl.startContainer)},get endContainer(){return f(this.impl.endContainer)},get commonAncestorContainer(){return f(this.impl.commonAncestorContainer)},setStart:function(a,b){this.impl.setStart(e(a),b)},setEnd:function(a,b){this.impl.setEnd(e(a),b)},setStartBefore:function(a){this.impl.setStartBefore(e(a))},setStartAfter:function(a){this.impl.setStartAfter(e(a))},setEndBefore:function(a){this.impl.setEndBefore(e(a))},setEndAfter:function(a){this.impl.setEndAfter(e(a))},selectNode:function(a){this.impl.selectNode(e(a))},selectNodeContents:function(a){this.impl.selectNodeContents(e(a))},compareBoundaryPoints:function(a,b){return this.impl.compareBoundaryPoints(a,d(b))},extractContents:function(){return f(this.impl.extractContents())},cloneContents:function(){return f(this.impl.cloneContents())},insertNode:function(a){this.impl.insertNode(e(a))},surroundContents:function(a){this.impl.surroundContents(e(a))},cloneRange:function(){return f(this.impl.cloneRange())},isPointInRange:function(a,b){return this.impl.isPointInRange(e(a),b)},comparePoint:function(a,b){return this.impl.comparePoint(e(a),b)},intersectsNode:function(a){return this.impl.intersectsNode(e(a))},toString:function(){return this.impl.toString()}},g.prototype.createContextualFragment&&(b.prototype.createContextualFragment=function(a){return f(this.impl.createContextualFragment(a))}),c(window.Range,b,document.createRange()),a.wrappers.Range=b}(window.ShadowDOMPolyfill),function(a){"use strict";var b=a.GetElementsByInterface,c=a.ParentNodeInterface,d=a.SelectorsInterface,e=a.mixin,f=a.registerObject,g=f(document.createDocumentFragment());e(g.prototype,c),e(g.prototype,d),e(g.prototype,b);var h=f(document.createComment(""));a.wrappers.Comment=h,a.wrappers.DocumentFragment=g}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=k(a.impl.ownerDocument.createDocumentFragment());c.call(this,b),i(b,this),this.treeScope_=new d(this,g(a));var e=a.shadowRoot;m.set(this,e),l.set(this,a)}var c=a.wrappers.DocumentFragment,d=a.TreeScope,e=a.elementFromPoint,f=a.getInnerHTML,g=a.getTreeScope,h=a.mixin,i=a.rewrap,j=a.setInnerHTML,k=a.unwrap,l=new WeakMap,m=new WeakMap,n=/[ \t\n\r\f]/;b.prototype=Object.create(c.prototype),h(b.prototype,{get innerHTML(){return f(this)},set innerHTML(a){j(this,a),this.invalidateShadowRenderer()},get olderShadowRoot(){return m.get(this)||null},get host(){return l.get(this)||null},invalidateShadowRenderer:function(){return l.get(this).invalidateShadowRenderer()},elementFromPoint:function(a,b){return e(this,this.ownerDocument,a,b)},getElementById:function(a){return n.test(a)?null:this.querySelector('[id="'+a+'"]')}}),a.wrappers.ShadowRoot=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){a.previousSibling_=a.previousSibling,a.nextSibling_=a.nextSibling,a.parentNode_=a.parentNode}function c(a,c,e){var f=G(a),g=G(c),h=e?G(e):null;if(d(c),b(c),e)a.firstChild===e&&(a.firstChild_=e),e.previousSibling_=e.previousSibling;else{a.lastChild_=a.lastChild,a.lastChild===a.firstChild&&(a.firstChild_=a.firstChild);var i=H(f.lastChild);i&&(i.nextSibling_=i.nextSibling)}f.insertBefore(g,h)}function d(a){var c=G(a),d=c.parentNode;if(d){var e=H(d);b(a),a.previousSibling&&(a.previousSibling.nextSibling_=a),a.nextSibling&&(a.nextSibling.previousSibling_=a),e.lastChild===a&&(e.lastChild_=a),e.firstChild===a&&(e.firstChild_=a),d.removeChild(c)}}function e(a,b){g(b).push(a),x(a,b);var c=J.get(a);c||J.set(a,c=[]),c.push(b)}function f(a){I.set(a,[])}function g(a){var b=I.get(a);return b||I.set(a,b=[]),b}function h(a){for(var b=[],c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b}function i(a,b,c){for(var d=a.firstChild;d;d=d.nextSibling)if(b(d)){if(c(d)===!1)return}else i(d,b,c)}function j(a,b){var c=b.getAttribute("select");if(!c)return!0;if(c=c.trim(),!c)return!0;if(!(a instanceof z))return!1;if("*"===c||c===a.localName)return!0;if(!M.test(c))return!1;if(":"===c[0]&&!N.test(c))return!1;try{return a.matches(c)}catch(d){return!1}}function k(){for(var a=0;a<P.length;a++){var b=P[a],c=b.parentRenderer;c&&c.dirty||b.render()}P=[]}function l(){y=null,k()}function m(a){var b=L.get(a);return b||(b=new q(a),L.set(a,b)),b}function n(a){var b=E(a).root;return b instanceof D?b:null}function o(a){return m(a.host)}function p(a){this.skip=!1,this.node=a,this.childNodes=[]}function q(a){this.host=a,this.dirty=!1,this.invalidateAttributes(),this.associateNode(a)}function r(a){return a instanceof A}function s(a){return a instanceof A}function t(a){return a instanceof B}function u(a){return a instanceof B}function v(a){return a.shadowRoot
-}function w(a){for(var b=[],c=a.shadowRoot;c;c=c.olderShadowRoot)b.push(c);return b}function x(a,b){K.set(a,b)}var y,z=a.wrappers.Element,A=a.wrappers.HTMLContentElement,B=a.wrappers.HTMLShadowElement,C=a.wrappers.Node,D=a.wrappers.ShadowRoot,E=(a.assert,a.getTreeScope),F=(a.mixin,a.oneOf),G=a.unwrap,H=a.wrap,I=new WeakMap,J=new WeakMap,K=new WeakMap,L=new WeakMap,M=/^[*.:#[a-zA-Z_|]/,N=new RegExp("^:("+["link","visited","target","enabled","disabled","checked","indeterminate","nth-child","nth-last-child","nth-of-type","nth-last-of-type","first-child","last-child","first-of-type","last-of-type","only-of-type"].join("|")+")"),O=F(window,["requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","setTimeout"]),P=[],Q=new ArraySplice;Q.equals=function(a,b){return G(a.node)===b},p.prototype={append:function(a){var b=new p(a);return this.childNodes.push(b),b},sync:function(a){if(!this.skip){for(var b=this.node,e=this.childNodes,f=h(G(b)),g=a||new WeakMap,i=Q.calculateSplices(e,f),j=0,k=0,l=0,m=0;m<i.length;m++){for(var n=i[m];l<n.index;l++)k++,e[j++].sync(g);for(var o=n.removed.length,p=0;o>p;p++){var q=H(f[k++]);g.get(q)||d(q)}for(var r=n.addedCount,s=f[k]&&H(f[k]),p=0;r>p;p++){var t=e[j++],u=t.node;c(b,u,s),g.set(u,!0),t.sync(g)}l+=r}for(var m=l;m<e.length;m++)e[m].sync(g)}}},q.prototype={render:function(a){if(this.dirty){this.invalidateAttributes(),this.treeComposition();var b=this.host,c=b.shadowRoot;this.associateNode(b);for(var d=!e,e=a||new p(b),f=c.firstChild;f;f=f.nextSibling)this.renderNode(c,e,f,!1);d&&e.sync(),this.dirty=!1}},get parentRenderer(){return E(this.host).renderer},invalidate:function(){if(!this.dirty){if(this.dirty=!0,P.push(this),y)return;y=window[O](l,0)}},renderNode:function(a,b,c,d){if(v(c)){b=b.append(c);var e=m(c);e.dirty=!0,e.render(b)}else r(c)?this.renderInsertionPoint(a,b,c,d):t(c)?this.renderShadowInsertionPoint(a,b,c):this.renderAsAnyDomTree(a,b,c,d)},renderAsAnyDomTree:function(a,b,c,d){if(b=b.append(c),v(c)){var e=m(c);b.skip=!e.dirty,e.render(b)}else for(var f=c.firstChild;f;f=f.nextSibling)this.renderNode(a,b,f,d)},renderInsertionPoint:function(a,b,c,d){var e=g(c);if(e.length){this.associateNode(c);for(var f=0;f<e.length;f++){var h=e[f];r(h)&&d?this.renderInsertionPoint(a,b,h,d):this.renderAsAnyDomTree(a,b,h,d)}}else this.renderFallbackContent(a,b,c);this.associateNode(c.parentNode)},renderShadowInsertionPoint:function(a,b,c){var d=a.olderShadowRoot;if(d){x(d,c),this.associateNode(c.parentNode);for(var e=d.firstChild;e;e=e.nextSibling)this.renderNode(d,b,e,!0)}else this.renderFallbackContent(a,b,c)},renderFallbackContent:function(a,b,c){this.associateNode(c),this.associateNode(c.parentNode);for(var d=c.firstChild;d;d=d.nextSibling)this.renderAsAnyDomTree(a,b,d,!1)},invalidateAttributes:function(){this.attributes=Object.create(null)},updateDependentAttributes:function(a){if(a){var b=this.attributes;/\.\w+/.test(a)&&(b["class"]=!0),/#\w+/.test(a)&&(b.id=!0),a.replace(/\[\s*([^\s=\|~\]]+)/g,function(a,c){b[c]=!0})}},dependsOnAttribute:function(a){return this.attributes[a]},distribute:function(a,b){var c=this;i(a,s,function(a){f(a),c.updateDependentAttributes(a.getAttribute("select"));for(var d=0;d<b.length;d++){var g=b[d];void 0!==g&&j(g,a)&&(e(g,a),b[d]=void 0)}})},treeComposition:function(){for(var a=this.host,b=a.shadowRoot,c=[],d=a.firstChild;d;d=d.nextSibling)if(r(d)){var e=g(d);e&&e.length||(e=h(d)),c.push.apply(c,e)}else c.push(d);for(var f,j;b;){if(f=void 0,i(b,u,function(a){return f=a,!1}),j=f,this.distribute(b,c),j){var k=b.olderShadowRoot;if(k){b=k,x(b,j);continue}break}break}},associateNode:function(a){a.impl.polymerShadowRenderer_=this}},C.prototype.invalidateShadowRenderer=function(){var a=this.impl.polymerShadowRenderer_;return a?(a.invalidate(),!0):!1},A.prototype.getDistributedNodes=function(){return k(),g(this)},B.prototype.nodeIsInserted_=A.prototype.nodeIsInserted_=function(){this.invalidateShadowRenderer();var a,b=n(this);b&&(a=o(b)),this.impl.polymerShadowRenderer_=a,a&&a.invalidate()},a.eventParentsTable=J,a.getRendererForHost=m,a.getShadowTrees=w,a.insertionParentTable=K,a.renderAllPending=k,a.visual={insertBefore:c,remove:d}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(b){if(window[b]){d(!a.wrappers[b]);var i=function(a){c.call(this,a)};i.prototype=Object.create(c.prototype),e(i.prototype,{get form(){return h(g(this).form)}}),f(window[b],i,document.createElement(b.slice(4,-7))),a.wrappers[b]=i}}var c=a.wrappers.HTMLElement,d=a.assert,e=a.mixin,f=a.registerWrapper,g=a.unwrap,h=a.wrap,i=["HTMLButtonElement","HTMLFieldSetElement","HTMLInputElement","HTMLKeygenElement","HTMLLabelElement","HTMLLegendElement","HTMLObjectElement","HTMLOutputElement","HTMLTextAreaElement"];i.forEach(b)}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}{var c=a.registerWrapper,d=a.unwrap,e=a.unwrapIfNeeded,f=a.wrap;window.Selection}b.prototype={get anchorNode(){return f(this.impl.anchorNode)},get focusNode(){return f(this.impl.focusNode)},addRange:function(a){this.impl.addRange(d(a))},collapse:function(a,b){this.impl.collapse(e(a),b)},containsNode:function(a,b){return this.impl.containsNode(e(a),b)},extend:function(a,b){this.impl.extend(e(a),b)},getRangeAt:function(a){return f(this.impl.getRangeAt(a))},removeRange:function(a){this.impl.removeRange(d(a))},selectAllChildren:function(a){this.impl.selectAllChildren(e(a))},toString:function(){return this.impl.toString()}},c(window.Selection,b,window.getSelection()),a.wrappers.Selection=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){k.call(this,a),this.treeScope_=new p(this,null)}function c(a){var c=document[a];b.prototype[a]=function(){return A(c.apply(this.impl,arguments))}}function d(a,b){D.call(b.impl,z(a)),e(a,b)}function e(a,b){a.shadowRoot&&b.adoptNode(a.shadowRoot),a instanceof o&&f(a,b);for(var c=a.firstChild;c;c=c.nextSibling)e(c,b)}function f(a,b){var c=a.olderShadowRoot;c&&b.adoptNode(c)}function g(a){this.impl=a}function h(a,b){var c=document.implementation[b];a.prototype[b]=function(){return A(c.apply(this.impl,arguments))}}function i(a,b){var c=document.implementation[b];a.prototype[b]=function(){return c.apply(this.impl,arguments)}}var j=a.GetElementsByInterface,k=a.wrappers.Node,l=a.ParentNodeInterface,m=a.wrappers.Selection,n=a.SelectorsInterface,o=a.wrappers.ShadowRoot,p=a.TreeScope,q=a.cloneNode,r=a.defineWrapGetter,s=a.elementFromPoint,t=a.forwardMethodsToWrapper,u=a.matchesNames,v=a.mixin,w=a.registerWrapper,x=a.renderAllPending,y=a.rewrap,z=a.unwrap,A=a.wrap,B=a.wrapEventTargetMethods,C=(a.wrapNodeList,new WeakMap);b.prototype=Object.create(k.prototype),r(b,"documentElement"),r(b,"body"),r(b,"head"),["createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","getElementById"].forEach(c);var D=document.adoptNode,E=document.getSelection;if(v(b.prototype,{adoptNode:function(a){return a.parentNode&&a.parentNode.removeChild(a),d(a,this),a},elementFromPoint:function(a,b){return s(this,this,a,b)},importNode:function(a,b){return q(a,b,this.impl)},getSelection:function(){return x(),new m(E.call(z(this)))}}),document.registerElement){var F=document.registerElement;b.prototype.registerElement=function(b,c){function d(a){return a?void(this.impl=a):c.extends?document.createElement(c.extends,b):document.createElement(b)}var e=c.prototype;if(a.nativePrototypeTable.get(e))throw new Error("NotSupportedError");for(var f,g=Object.getPrototypeOf(e),h=[];g&&!(f=a.nativePrototypeTable.get(g));)h.push(g),g=Object.getPrototypeOf(g);if(!f)throw new Error("NotSupportedError");for(var i=Object.create(f),j=h.length-1;j>=0;j--)i=Object.create(i);["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"].forEach(function(a){var b=e[a];b&&(i[a]=function(){A(this)instanceof d||y(this),b.apply(A(this),arguments)})});var k={prototype:i};c.extends&&(k.extends=c.extends),d.prototype=e,d.prototype.constructor=d,a.constructorTable.set(i,d),a.nativePrototypeTable.set(e,i);F.call(z(this),b,k);return d},t([window.HTMLDocument||window.Document],["registerElement"])}t([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild"].concat(u)),t([window.HTMLDocument||window.Document],["adoptNode","importNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById","getSelection"]),v(b.prototype,j),v(b.prototype,l),v(b.prototype,n),v(b.prototype,{get implementation(){var a=C.get(this);return a?a:(a=new g(z(this).implementation),C.set(this,a),a)}}),w(window.Document,b,document.implementation.createHTMLDocument("")),window.HTMLDocument&&w(window.HTMLDocument,b),B([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),h(g,"createDocumentType"),h(g,"createDocument"),h(g,"createHTMLDocument"),i(g,"hasFeature"),w(window.DOMImplementation,g),t([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),a.adoptNodeNoRemove=d,a.wrappers.DOMImplementation=g,a.wrappers.Document=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.EventTarget,d=a.wrappers.Selection,e=a.mixin,f=a.registerWrapper,g=a.renderAllPending,h=a.unwrap,i=a.unwrapIfNeeded,j=a.wrap,k=window.Window,l=window.getComputedStyle,m=window.getSelection;b.prototype=Object.create(c.prototype),k.prototype.getComputedStyle=function(a,b){return j(this||window).getComputedStyle(i(a),b)},k.prototype.getSelection=function(){return j(this||window).getSelection()},delete window.getComputedStyle,delete window.getSelection,["addEventListener","removeEventListener","dispatchEvent"].forEach(function(a){k.prototype[a]=function(){var b=j(this||window);return b[a].apply(b,arguments)},delete window[a]}),e(b.prototype,{getComputedStyle:function(a,b){return g(),l.call(h(this),i(a),b)},getSelection:function(){return g(),new d(m.call(h(this)))}}),f(k,b),a.wrappers.Window=b}(window.ShadowDOMPolyfill),function(a){"use strict";var b=a.unwrap,c=window.DataTransfer||window.Clipboard,d=c.prototype.setDragImage;c.prototype.setDragImage=function(a,c,e){d.call(this,b(a),c,e)}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=c[a],d=window[b];if(d){var e=document.createElement(a),f=e.constructor;window[b]=f}}var c=(a.isWrapperFor,{a:"HTMLAnchorElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",base:"HTMLBaseElement",body:"HTMLBodyElement",br:"HTMLBRElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",content:"HTMLContentElement",data:"HTMLDataElement",datalist:"HTMLDataListElement",del:"HTMLModElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",dl:"HTMLDListElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",h1:"HTMLHeadingElement",head:"HTMLHeadElement",hr:"HTMLHRElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",img:"HTMLImageElement",input:"HTMLInputElement",keygen:"HTMLKeygenElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",li:"HTMLLIElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",object:"HTMLObjectElement",ol:"HTMLOListElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",shadow:"HTMLShadowElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",table:"HTMLTableElement",tbody:"HTMLTableSectionElement",template:"HTMLTemplateElement",textarea:"HTMLTextAreaElement",thead:"HTMLTableSectionElement",time:"HTMLTimeElement",title:"HTMLTitleElement",tr:"HTMLTableRowElement",track:"HTMLTrackElement",ul:"HTMLUListElement",video:"HTMLVideoElement"});Object.keys(c).forEach(b),Object.getOwnPropertyNames(a.wrappers).forEach(function(b){window[b]=a.wrappers[b]})}(window.ShadowDOMPolyfill),function(){window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded,Object.defineProperty(Element.prototype,"webkitShadowRoot",Object.getOwnPropertyDescriptor(Element.prototype,"shadowRoot"));var a=Element.prototype.createShadowRoot;Element.prototype.createShadowRoot=function(){var b=a.call(this);return CustomElements.watchShadow(this),b},Element.prototype.webkitCreateShadowRoot=Element.prototype.createShadowRoot}(),function(a){function b(a,b){var c="";return Array.prototype.forEach.call(a,function(a){c+=a.textContent+"\n\n"}),b||(c=c.replace(l,"")),c}function c(a){var b=document.createElement("style");return b.textContent=a,b}function d(a){var b=c(a);document.head.appendChild(b);var d=[];if(b.sheet)try{d=b.sheet.cssRules}catch(e){}else console.warn("sheet not found",b);return b.parentNode.removeChild(b),d}function e(){v.initialized=!0,document.body.appendChild(v);var a=v.contentDocument,b=a.createElement("base");b.href=document.baseURI,a.head.appendChild(b)}function f(a){v.initialized||e(),document.body.appendChild(v),a(v.contentDocument),document.body.removeChild(v)}function g(a,b){if(b){var e;if(a.match("@import")&&x){var g=c(a);f(function(a){a.head.appendChild(g.impl),e=g.sheet.cssRules,b(e)})}else e=d(a),b(e)}}function h(a){a&&j().appendChild(document.createTextNode(a))}function i(a,b){var d=c(a);d.setAttribute(b,""),d.setAttribute(z,""),document.head.appendChild(d)}function j(){return w||(w=document.createElement("style"),w.setAttribute(z,""),w[z]=!0),w}var k={strictStyling:!1,registry:{},shimStyling:function(a,c,d){var e=this.prepareRoot(a,c,d),f=this.isTypeExtension(d),g=this.makeScopeSelector(c,f),h=b(e,!0);h=this.scopeCssText(h,g),a&&(a.shimmedStyle=h),this.addCssToDocument(h,c)},shimStyle:function(a,b){return this.shimCssText(a.textContent,b)},shimCssText:function(a,b){return a=this.insertDirectives(a),this.scopeCssText(a,b)},makeScopeSelector:function(a,b){return a?b?"[is="+a+"]":a:""},isTypeExtension:function(a){return a&&a.indexOf("-")<0},prepareRoot:function(a,b,c){var d=this.registerRoot(a,b,c);return this.replaceTextInStyles(d.rootStyles,this.insertDirectives),this.removeStyles(a,d.rootStyles),this.strictStyling&&this.applyScopeToContent(a,b),d.scopeStyles},removeStyles:function(a,b){for(var c,d=0,e=b.length;e>d&&(c=b[d]);d++)c.parentNode.removeChild(c)},registerRoot:function(a,b,c){var d=this.registry[b]={root:a,name:b,extendsName:c},e=this.findStyles(a);d.rootStyles=e,d.scopeStyles=d.rootStyles;var f=this.registry[d.extendsName];return!f||a&&!a.querySelector("shadow")||(d.scopeStyles=f.scopeStyles.concat(d.scopeStyles)),d},findStyles:function(a){if(!a)return[];var b=a.querySelectorAll("style");return Array.prototype.filter.call(b,function(a){return!a.hasAttribute(A)})},applyScopeToContent:function(a,b){a&&(Array.prototype.forEach.call(a.querySelectorAll("*"),function(a){a.setAttribute(b,"")}),Array.prototype.forEach.call(a.querySelectorAll("template"),function(a){this.applyScopeToContent(a.content,b)},this))},insertDirectives:function(a){return a=this.insertPolyfillDirectivesInCssText(a),this.insertPolyfillRulesInCssText(a)},insertPolyfillDirectivesInCssText:function(a){return a=a.replace(m,function(a,b){return b.slice(0,-2)+"{"}),a.replace(n,function(a,b){return b+" {"})},insertPolyfillRulesInCssText:function(a){return a=a.replace(o,function(a,b){return b.slice(0,-1)}),a.replace(p,function(a,b,c,d){var e=a.replace(b,"").replace(c,"");return d+e})},scopeCssText:function(a,b){var c=this.extractUnscopedRulesFromCssText(a);if(a=this.insertPolyfillHostInCssText(a),a=this.convertColonHost(a),a=this.convertColonAncestor(a),a=this.convertCombinators(a),b){var a,d=this;g(a,function(c){a=d.scopeRules(c,b)})}return a=a+"\n"+c,a.trim()},extractUnscopedRulesFromCssText:function(a){for(var b,c="";b=q.exec(a);)c+=b[1].slice(0,-1)+"\n\n";for(;b=r.exec(a);)c+=b[0].replace(b[2],"").replace(b[1],b[3])+"\n\n";return c},convertColonHost:function(a){return this.convertColonRule(a,cssColonHostRe,this.colonHostPartReplacer)},convertColonAncestor:function(a){return this.convertColonRule(a,cssColonAncestorRe,this.colonAncestorPartReplacer)},convertColonRule:function(a,b,c){return a.replace(b,function(a,b,d,e){if(b=polyfillHostNoCombinator,d){for(var f,g=d.split(","),h=[],i=0,j=g.length;j>i&&(f=g[i]);i++)f=f.trim(),h.push(c(b,f,e));return h.join(",")}return b+e})},colonAncestorPartReplacer:function(a,b,c){return b.match(s)?this.colonHostPartReplacer(a,b,c):a+b+c+", "+b+" "+a+c},colonHostPartReplacer:function(a,b,c){return a+b.replace(s,"")+c},convertCombinators:function(a){for(var b=0;b<combinatorsRe.length;b++)a=a.replace(combinatorsRe[b]," ");return a},scopeRules:function(a,b){var c="";return a&&Array.prototype.forEach.call(a,function(a){a.selectorText&&a.style&&a.style.cssText?(c+=this.scopeSelector(a.selectorText,b,this.strictStyling)+" {\n	",c+=this.propertiesFromRule(a)+"\n}\n\n"):a.type===CSSRule.MEDIA_RULE?(c+="@media "+a.media.mediaText+" {\n",c+=this.scopeRules(a.cssRules,b),c+="\n}\n\n"):a.cssText&&(c+=a.cssText+"\n\n")},this),c},scopeSelector:function(a,b,c){var d=[],e=a.split(",");return e.forEach(function(a){a=a.trim(),this.selectorNeedsScoping(a,b)&&(a=c&&!a.match(polyfillHostNoCombinator)?this.applyStrictSelectorScope(a,b):this.applySimpleSelectorScope(a,b)),d.push(a)},this),d.join(", ")},selectorNeedsScoping:function(a,b){var c=this.makeScopeMatcher(b);return!a.match(c)},makeScopeMatcher:function(a){return a=a.replace(/\[/g,"\\[").replace(/\[/g,"\\]"),new RegExp("^("+a+")"+selectorReSuffix,"m")},applySimpleSelectorScope:function(a,b){return a.match(polyfillHostRe)?(a=a.replace(polyfillHostNoCombinator,b),a.replace(polyfillHostRe,b+" ")):b+" "+a},applyStrictSelectorScope:function(a,b){b=b.replace(/\[is=([^\]]*)\]/g,"$1");var c=[" ",">","+","~"],d=a,e="["+b+"]";return c.forEach(function(a){var b=d.split(a);d=b.map(function(a){var b=a.trim().replace(polyfillHostRe,"");return b&&c.indexOf(b)<0&&b.indexOf(e)<0&&(a=b.replace(/([^:]*)(:*)(.*)/,"$1"+e+"$2$3")),a}).join(a)}),d},insertPolyfillHostInCssText:function(a){return a.replace(hostRe,s).replace(colonHostRe,s).replace(colonAncestorRe,t)},propertiesFromRule:function(a){return a.style.content&&!a.style.content.match(/['"]+/)?a.style.cssText.replace(/content:[^;]*;/g,"content: '"+a.style.content+"';"):a.style.cssText},replaceTextInStyles:function(a,b){a&&b&&(a instanceof Array||(a=[a]),Array.prototype.forEach.call(a,function(a){a.textContent=b.call(this,a.textContent)},this))},addCssToDocument:function(a,b){a.match("@import")?i(a,b):h(a)}},l=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,m=/\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,n=/polyfill-next-selector[^}]*content\:[\s]*'([^']*)'[^}]*}([^{]*?){/gim,o=/\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,p=/(polyfill-rule)[^}]*(content\:[\s]*'([^']*)'[^;]*;)[^}]*}/gim,q=/\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,r=/(polyfill-unscoped-rule)[^}]*(content\:[\s]*'([^']*)'[^;]*;)[^}]*}/gim,s="-shadowcsshost",t="-shadowcssancestor",u=")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)";cssColonHostRe=new RegExp("("+s+u,"gim"),cssColonAncestorRe=new RegExp("("+t+u,"gim"),selectorReSuffix="([>\\s~+[.,{:][\\s\\S]*)?$",hostRe=/@host/gim,colonHostRe=/\:host/gim,colonAncestorRe=/\:ancestor/gim,polyfillHostNoCombinator=s+"-no-combinator",polyfillHostRe=new RegExp(s,"gim"),polyfillAncestorRe=new RegExp(t,"gim"),combinatorsRe=[/\^\^/g,/\^/g,/\/shadow\//g,/\/shadow-deep\//g];var v=document.createElement("iframe");v.style.display="none";var w,x=navigator.userAgent.match("Chrome"),y="shim-shadowdom",z="shim-shadowdom-css",A="no-shim";if(window.ShadowDOMPolyfill){h("style { display: none !important; }\n");var B=wrap(document),C=B.querySelector("head");C.insertBefore(j(),C.childNodes[0]),document.addEventListener("DOMContentLoaded",function(){var b=a.urlResolver;if(window.HTMLImports&&!HTMLImports.useNative){var c="link[rel=stylesheet]["+y+"]",d="style["+y+"]";HTMLImports.importer.documentPreloadSelectors+=","+c,HTMLImports.importer.importsPreloadSelectors+=","+c,HTMLImports.parser.documentSelectors=[HTMLImports.parser.documentSelectors,c,d].join(",");var e=HTMLImports.parser.parseGeneric;HTMLImports.parser.parseGeneric=function(a){if(!a[z]){var c=a.__importElement||a;if(!c.hasAttribute(y))return void e.call(this,a);a.__resource?(c=a.ownerDocument.createElement("style"),c.textContent=b.resolveCssText(a.__resource,a.href)):b.resolveStyle(c),c.textContent=k.shimStyle(c),c.removeAttribute(y,""),c.setAttribute(z,""),c[z]=!0,c.parentNode!==C&&(a.parentNode===C?C.replaceChild(c,a):C.appendChild(c)),c.__importParsed=!0,this.markParsingComplete(a)}};var f=HTMLImports.parser.hasResource;HTMLImports.parser.hasResource=function(a){return"link"===a.localName&&"stylesheet"===a.rel&&a.hasAttribute(y)?a.__resource:f.call(this,a)}}})}a.ShadowCSS=k}(window.Platform)):!function(){window.templateContent=window.templateContent||function(a){return a.content},window.wrap=window.unwrap=function(a){return a};var a=Element.prototype.webkitCreateShadowRoot;Element.prototype.webkitCreateShadowRoot=function(){var b=this.webkitShadowRoot,c=a.call(this);return c.olderShadowRoot=b,c.host=this,CustomElements.watchShadow(this),c},Object.defineProperties(Element.prototype,{shadowRoot:{get:function(){return this.webkitShadowRoot}},createShadowRoot:{value:function(){return this.webkitCreateShadowRoot()}}}),window.templateContent=function(a){if(window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(a),!a.content&&!a._content){for(var b=document.createDocumentFragment();a.firstChild;)b.appendChild(a.firstChild);a._content=b}return a.content||a._content}}(),function(a){"use strict";function b(a){return void 0!==m[a]}function c(){h.call(this),this._isInvalid=!0}function d(a){return""==a&&c.call(this),a.toLowerCase()}function e(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,63,96].indexOf(b)?a:encodeURIComponent(a)}function f(a){var b=a.charCodeAt(0);return b>32&&127>b&&-1==[34,35,60,62,96].indexOf(b)?a:encodeURIComponent(a)}function g(a,g,h){function i(a){t.push(a)}var j=g||"scheme start",k=0,l="",r=!1,s=!1,t=[];a:for(;(a[k-1]!=o||0==k)&&!this._isInvalid;){var u=a[k];switch(j){case"scheme start":if(!u||!p.test(u)){if(g){i("Invalid scheme.");break a}l="",j="no scheme";continue}l+=u.toLowerCase(),j="scheme";break;case"scheme":if(u&&q.test(u))l+=u.toLowerCase();else{if(":"!=u){if(g){if(o==u)break a;i("Code point not allowed in scheme: "+u);break a}l="",k=0,j="no scheme";continue}if(this._scheme=l,l="",g)break a;b(this._scheme)&&(this._isRelative=!0),j="file"==this._scheme?"relative":this._isRelative&&h&&h._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==u?(query="?",j="query"):"#"==u?(this._fragment="#",j="fragment"):o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._schemeData+=e(u));break;case"no scheme":if(h&&b(h._scheme)){j="relative";continue}i("Missing scheme."),c.call(this);break;case"relative or authority":if("/"!=u||"/"!=a[k+1]){i("Expected /, got: "+u),j="relative";continue}j="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=h._scheme),o==u){this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query;break a}if("/"==u||"\\"==u)"\\"==u&&i("\\ is an invalid code point."),j="relative slash";else if("?"==u)this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query="?",j="query";else{if("#"!=u){var v=a[k+1],w=a[k+2];("file"!=this._scheme||!p.test(u)||":"!=v&&"|"!=v||o!=w&&"/"!=w&&"\\"!=w&&"?"!=w&&"#"!=w)&&(this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._path.pop()),j="relative path";continue}this._host=h._host,this._port=h._port,this._path=h._path.slice(),this._query=h._query,this._fragment="#",j="fragment"}break;case"relative slash":if("/"!=u&&"\\"!=u){"file"!=this._scheme&&(this._host=h._host,this._port=h._port),j="relative path";continue}"\\"==u&&i("\\ is an invalid code point."),j="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=u){i("Expected '/', got: "+u),j="authority ignore slashes";continue}j="authority second slash";break;case"authority second slash":if(j="authority ignore slashes","/"!=u){i("Expected '/', got: "+u);continue}break;case"authority ignore slashes":if("/"!=u&&"\\"!=u){j="authority";continue}i("Expected authority, got: "+u);break;case"authority":if("@"==u){r&&(i("@ already seen."),l+="%40"),r=!0;for(var x=0;x<l.length;x++){var y=l[x];if("	"!=y&&"\n"!=y&&"\r"!=y)if(":"!=y||null!==this._password){var z=e(y);null!==this._password?this._password+=z:this._username+=z}else this._password="";else i("Invalid whitespace in authority.")}l=""}else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){k-=l.length,l="",j="host";continue}l+=u}break;case"file host":if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){2!=l.length||!p.test(l[0])||":"!=l[1]&&"|"!=l[1]?0==l.length?j="relative path start":(this._host=d.call(this,l),l="",j="relative path start"):j="relative path";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid whitespace in file host."):l+=u;break;case"host":case"hostname":if(":"!=u||s){if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u){if(this._host=d.call(this,l),l="",j="relative path start",g)break a;continue}"	"!=u&&"\n"!=u&&"\r"!=u?("["==u?s=!0:"]"==u&&(s=!1),l+=u):i("Invalid code point in host/hostname: "+u)}else if(this._host=d.call(this,l),l="",j="port","hostname"==g)break a;break;case"port":if(/[0-9]/.test(u))l+=u;else{if(o==u||"/"==u||"\\"==u||"?"==u||"#"==u||g){if(""!=l){var A=parseInt(l,10);A!=m[this._scheme]&&(this._port=A+""),l=""}if(g)break a;j="relative path start";continue}"	"==u||"\n"==u||"\r"==u?i("Invalid code point in port: "+u):c.call(this)}break;case"relative path start":if("\\"==u&&i("'\\' not allowed in path."),j="relative path","/"!=u&&"\\"!=u)continue;break;case"relative path":if(o!=u&&"/"!=u&&"\\"!=u&&(g||"?"!=u&&"#"!=u))"	"!=u&&"\n"!=u&&"\r"!=u&&(l+=e(u));else{"\\"==u&&i("\\ not allowed in relative path.");var B;(B=n[l.toLowerCase()])&&(l=B),".."==l?(this._path.pop(),"/"!=u&&"\\"!=u&&this._path.push("")):"."==l&&"/"!=u&&"\\"!=u?this._path.push(""):"."!=l&&("file"==this._scheme&&0==this._path.length&&2==l.length&&p.test(l[0])&&"|"==l[1]&&(l=l[0]+":"),this._path.push(l)),l="","?"==u?(this._query="?",j="query"):"#"==u&&(this._fragment="#",j="fragment")}break;case"query":g||"#"!=u?o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._query+=f(u)):(this._fragment="#",j="fragment");break;case"fragment":o!=u&&"	"!=u&&"\n"!=u&&"\r"!=u&&(this._fragment+=u)}k++}}function h(){this._scheme="",this._schemeData="",this._username="",this._password=null,this._host="",this._port="",this._path=[],this._query="",this._fragment="",this._isInvalid=!1,this._isRelative=!1}function i(a,b){void 0===b||b instanceof i||(b=new i(String(b))),this._url=a,h.call(this);var c=a.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g,"");g.call(this,c,null,b)}var j=!1;if(!a.forceJURL)try{var k=new URL("b","http://a");j="http://a/b"===k.href}catch(l){}if(!j){var m=Object.create(null);m.ftp=21,m.file=0,m.gopher=70,m.http=80,m.https=443,m.ws=80,m.wss=443;var n=Object.create(null);n["%2e"]=".",n[".%2e"]="..",n["%2e."]="..",n["%2e%2e"]="..";var o=void 0,p=/[a-zA-Z]/,q=/[a-zA-Z0-9\+\-\.]/;i.prototype={get href(){if(this._isInvalid)return this._url;var a="";return(""!=this._username||null!=this._password)&&(a=this._username+(null!=this._password?":"+this._password:"")+"@"),this.protocol+(this._isRelative?"//"+a+this.host:"")+this.pathname+this._query+this._fragment},set href(a){h.call(this),g.call(this,a)},get protocol(){return this._scheme+":"},set protocol(a){this._isInvalid||g.call(this,a+":","scheme start")},get host(){return this._isInvalid?"":this._port?this._host+":"+this._port:this._host},set host(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"host")},get hostname(){return this._host},set hostname(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"hostname")},get port(){return this._port},set port(a){!this._isInvalid&&this._isRelative&&g.call(this,a,"port")},get pathname(){return this._isInvalid?"":this._isRelative?"/"+this._path.join("/"):this._schemeData},set pathname(a){!this._isInvalid&&this._isRelative&&(this._path=[],g.call(this,a,"relative path start"))},get search(){return this._isInvalid||!this._query||"?"==this._query?"":this._query},set search(a){!this._isInvalid&&this._isRelative&&(this._query="?","?"==a[0]&&(a=a.slice(1)),g.call(this,a,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fragment},set hash(a){this._isInvalid||(this._fragment="#","#"==a[0]&&(a=a.slice(1)),g.call(this,a,"fragment"))}},a.URL=i}}(window),function(a){function b(a){for(var b=a||{},d=1;d<arguments.length;d++){var e=arguments[d];try{for(var f in e)c(f,e,b)}catch(g){}}return b}function c(a,b,c){var e=d(b,a);Object.defineProperty(c,a,e)}function d(a,b){if(a){var c=Object.getOwnPropertyDescriptor(a,b);return c||d(Object.getPrototypeOf(a),b)}}Function.prototype.bind||(Function.prototype.bind=function(a){var b=this,c=Array.prototype.slice.call(arguments,1);return function(){var d=c.slice();return d.push.apply(d,arguments),b.apply(a,d)}}),a.mixin=b}(window.Platform),function(a){"use strict";function b(a,b,c){var d="string"==typeof a?document.createElement(a):a.cloneNode(!0);if(d.innerHTML=b,c)for(var e in c)d.setAttribute(e,c[e]);return d}var c=DOMTokenList.prototype.add,d=DOMTokenList.prototype.remove;DOMTokenList.prototype.add=function(){for(var a=0;a<arguments.length;a++)c.call(this,arguments[a])},DOMTokenList.prototype.remove=function(){for(var a=0;a<arguments.length;a++)d.call(this,arguments[a])},DOMTokenList.prototype.toggle=function(a,b){1==arguments.length&&(b=!this.contains(a)),b?this.add(a):this.remove(a)},DOMTokenList.prototype.switch=function(a,b){a&&this.remove(a),b&&this.add(b)};var e=function(){return Array.prototype.slice.call(this)},f=window.NamedNodeMap||window.MozNamedAttrMap||{};if(NodeList.prototype.array=e,f.prototype.array=e,HTMLCollection.prototype.array=e,!window.performance){var g=Date.now();window.performance={now:function(){return Date.now()-g}}}window.requestAnimationFrame||(window.requestAnimationFrame=function(){var a=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;return a?function(b){return a(function(){b(performance.now())})}:function(a){return window.setTimeout(a,1e3/60)}}()),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(a){clearTimeout(a)}}());var h=[],i=function(){h.push(arguments)};window.Polymer=i,a.deliverDeclarations=function(){return a.deliverDeclarations=function(){throw"Possible attempt to load Polymer twice"},h},window.addEventListener("DOMContentLoaded",function(){window.Polymer===i&&(window.Polymer=function(){console.error('You tried to use polymer without loading it first. To load polymer, <link rel="import" href="components/polymer/polymer.html">')})}),a.createDOM=b}(window.Platform),window.templateContent=window.templateContent||function(a){return a.content},function(a){a=a||(window.Inspector={});var b;window.sinspect=function(a,d){b||(b=window.open("","ShadowDOM Inspector",null,!0),b.document.write(c),b.api={shadowize:shadowize}),f(a||wrap(document.body),d)};var c=["<!DOCTYPE html>","<html>","  <head>","    <title>ShadowDOM Inspector</title>","    <style>","      body {","      }","      pre {",'        font: 9pt "Courier New", monospace;',"        line-height: 1.5em;","      }","      tag {","        color: purple;","      }","      ul {","         margin: 0;","         padding: 0;","         list-style: none;","      }","      li {","         display: inline-block;","         background-color: #f1f1f1;","         padding: 4px 6px;","         border-radius: 4px;","         margin-right: 4px;","      }","    </style>","  </head>","  <body>",'    <ul id="crumbs">',"    </ul>",'    <div id="tree"></div>',"  </body>","</html>"].join("\n"),d=[],e=function(){var a=b.document,c=a.querySelector("#crumbs");
-c.textContent="";for(var e,g=0;e=d[g];g++){var h=a.createElement("a");h.href="#",h.textContent=e.localName,h.idx=g,h.onclick=function(a){for(var b;d.length>this.idx;)b=d.pop();f(b.shadow||b,b),a.preventDefault()},c.appendChild(a.createElement("li")).appendChild(h)}},f=function(a,c){var f=b.document;k=[];var g=c||a;d.push(g),e(),f.body.querySelector("#tree").innerHTML="<pre>"+j(a,a.childNodes)+"</pre>"},g=Array.prototype.forEach.call.bind(Array.prototype.forEach),h={STYLE:1,SCRIPT:1,"#comment":1,TEMPLATE:1},i=function(a){return h[a.nodeName]},j=function(a,b,c){if(i(a))return"";var d=c||"";if(a.localName||11==a.nodeType){var e=a.localName||"shadow-root",f=d+l(a);"content"==e&&(b=a.getDistributedNodes()),f+="<br/>";var h=d+"&nbsp;&nbsp;";g(b,function(a){f+=j(a,a.childNodes,h)}),f+=d,{br:1}[e]||(f+="<tag>&lt;/"+e+"&gt;</tag>",f+="<br/>")}else{var k=a.textContent.trim();f=k?d+'"'+k+'"<br/>':""}return f},k=[],l=function(a){var b="<tag>&lt;",c=a.localName||"shadow-root";return a.webkitShadowRoot||a.shadowRoot?(b+=' <button idx="'+k.length+'" onclick="api.shadowize.call(this)">'+c+"</button>",k.push(a)):b+=c||"shadow-root",a.attributes&&g(a.attributes,function(a){b+=" "+a.name+(a.value?'="'+a.value+'"':"")}),b+="&gt;</tag>"};shadowize=function(){var a=Number(this.attributes.idx.value),b=k[a];b?f(b.webkitShadowRoot||b.shadowRoot,b):(console.log("bad shadowize node"),console.dir(this))},a.output=j}(window.Inspector),function(){var a=document.createElement("style");a.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; } \n";var b=document.querySelector("head");b.insertBefore(a,b.firstChild)}(Platform),function(a){function b(a,b){return b=b||[],b.map||(b=[b]),a.apply(this,b.map(d))}function c(a,c,d){var e;switch(arguments.length){case 0:return;case 1:e=null;break;case 2:e=c.apply(this);break;default:e=b(d,c)}f[a]=e}function d(a){return f[a]}function e(a,c){HTMLImports.whenImportsReady(function(){b(c,a)})}var f={};a.marshal=d,a.module=c,a.using=e}(window),function(a){function b(a){f.textContent=d++,e.push(a)}function c(){for(;e.length;)e.shift()()}var d=0,e=[],f=document.createTextNode("");new(window.MutationObserver||JsMutationObserver)(c).observe(f,{characterData:!0}),a.endOfMicrotask=b}(Platform),function(a){function b(a,b,d){return a.replace(d,function(a,d,e,f){var g=e.replace(/["']/g,"");return g=c(b,g),d+"'"+g+"'"+f})}function c(a,b){var c=new URL(b,a);return d(c.href)}function d(a){var b=document.baseURI,c=new URL(a,b);return c.host===b.host&&c.port===b.port&&c.protocol===b.protocol?e(b.pathname,c.pathname):a}function e(a,b){for(var c=a.split("/"),d=b.split("/");c.length&&c[0]===d[0];)c.shift(),d.shift();for(var e=0,f=c.length-1;f>e;e++)d.unshift("..");return d.join("/")}var f={resolveDom:function(a,b){b=b||a.ownerDocument.baseURI,this.resolveAttributes(a,b),this.resolveStyles(a,b);var c=a.querySelectorAll("template");if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)d.content&&this.resolveDom(d.content,b)},resolveTemplate:function(a){this.resolveDom(a.content,a.ownerDocument.baseURI)},resolveStyles:function(a,b){var c=a.querySelectorAll("style");if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveStyle(d,b)},resolveStyle:function(a,b){b=b||a.ownerDocument.baseURI,a.textContent=this.resolveCssText(a.textContent,b)},resolveCssText:function(a,c){return a=b(a,c,g),b(a,c,h)},resolveAttributes:function(a,b){a.hasAttributes&&a.hasAttributes()&&this.resolveElementAttributes(a,b);var c=a&&a.querySelectorAll(j);if(c)for(var d,e=0,f=c.length;f>e&&(d=c[e]);e++)this.resolveElementAttributes(d,b)},resolveElementAttributes:function(a,b){b=b||a.ownerDocument.baseURI,i.forEach(function(d){var e=a.attributes[d];if(e&&e.value&&e.value.search(k)<0){var f=c(b,e.value);e.value=f}})}},g=/(url\()([^)]*)(\))/g,h=/(@import[\s]+(?!url\())([^;]*)(;)/g,i=["href","src","action"],j="["+i.join("],[")+"]",k="{{.*}}";a.urlResolver=f}(Platform),function(a){function b(a){u.push(a),t||(t=!0,q(d))}function c(a){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(a)||a}function d(){t=!1;var a=u;u=[],a.sort(function(a,b){return a.uid_-b.uid_});var b=!1;a.forEach(function(a){var c=a.takeRecords();e(a),c.length&&(a.callback_(c,a),b=!0)}),b&&d()}function e(a){a.nodes_.forEach(function(b){var c=p.get(b);c&&c.forEach(function(b){b.observer===a&&b.removeTransientObservers()})})}function f(a,b){for(var c=a;c;c=c.parentNode){var d=p.get(c);if(d)for(var e=0;e<d.length;e++){var f=d[e],g=f.options;if(c===a||g.subtree){var h=b(g);h&&f.enqueue(h)}}}}function g(a){this.callback_=a,this.nodes_=[],this.records_=[],this.uid_=++v}function h(a,b){this.type=a,this.target=b,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function i(a){var b=new h(a.type,a.target);return b.addedNodes=a.addedNodes.slice(),b.removedNodes=a.removedNodes.slice(),b.previousSibling=a.previousSibling,b.nextSibling=a.nextSibling,b.attributeName=a.attributeName,b.attributeNamespace=a.attributeNamespace,b.oldValue=a.oldValue,b}function j(a,b){return w=new h(a,b)}function k(a){return x?x:(x=i(w),x.oldValue=a,x)}function l(){w=x=void 0}function m(a){return a===x||a===w}function n(a,b){return a===b?a:x&&m(a)?x:null}function o(a,b,c){this.observer=a,this.target=b,this.options=c,this.transientObservedNodes=[]}var p=new WeakMap,q=window.msSetImmediate;if(!q){var r=[],s=String(Math.random());window.addEventListener("message",function(a){if(a.data===s){var b=r;r=[],b.forEach(function(a){a()})}}),q=function(a){r.push(a),window.postMessage(s,"*")}}var t=!1,u=[],v=0;g.prototype={observe:function(a,b){if(a=c(a),!b.childList&&!b.attributes&&!b.characterData||b.attributeOldValue&&!b.attributes||b.attributeFilter&&b.attributeFilter.length&&!b.attributes||b.characterDataOldValue&&!b.characterData)throw new SyntaxError;var d=p.get(a);d||p.set(a,d=[]);for(var e,f=0;f<d.length;f++)if(d[f].observer===this){e=d[f],e.removeListeners(),e.options=b;break}e||(e=new o(this,a,b),d.push(e),this.nodes_.push(a)),e.addListeners()},disconnect:function(){this.nodes_.forEach(function(a){for(var b=p.get(a),c=0;c<b.length;c++){var d=b[c];if(d.observer===this){d.removeListeners(),b.splice(c,1);break}}},this),this.records_=[]},takeRecords:function(){var a=this.records_;return this.records_=[],a}};var w,x;o.prototype={enqueue:function(a){var c=this.observer.records_,d=c.length;if(c.length>0){var e=c[d-1],f=n(e,a);if(f)return void(c[d-1]=f)}else b(this.observer);c[d]=a},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(a){var b=this.options;b.attributes&&a.addEventListener("DOMAttrModified",this,!0),b.characterData&&a.addEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.addEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(a){var b=this.options;b.attributes&&a.removeEventListener("DOMAttrModified",this,!0),b.characterData&&a.removeEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.removeEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(a){if(a!==this.target){this.addListeners_(a),this.transientObservedNodes.push(a);var b=p.get(a);b||p.set(a,b=[]),b.push(this)}},removeTransientObservers:function(){var a=this.transientObservedNodes;this.transientObservedNodes=[],a.forEach(function(a){this.removeListeners_(a);for(var b=p.get(a),c=0;c<b.length;c++)if(b[c]===this){b.splice(c,1);break}},this)},handleEvent:function(a){switch(a.stopImmediatePropagation(),a.type){case"DOMAttrModified":var b=a.attrName,c=a.relatedNode.namespaceURI,d=a.target,e=new j("attributes",d);e.attributeName=b,e.attributeNamespace=c;var g=a.attrChange===MutationEvent.ADDITION?null:a.prevValue;f(d,function(a){return!a.attributes||a.attributeFilter&&a.attributeFilter.length&&-1===a.attributeFilter.indexOf(b)&&-1===a.attributeFilter.indexOf(c)?void 0:a.attributeOldValue?k(g):e});break;case"DOMCharacterDataModified":var d=a.target,e=j("characterData",d),g=a.prevValue;f(d,function(a){return a.characterData?a.characterDataOldValue?k(g):e:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(a.target);case"DOMNodeInserted":var h,i,d=a.relatedNode,m=a.target;"DOMNodeInserted"===a.type?(h=[m],i=[]):(h=[],i=[m]);var n=m.previousSibling,o=m.nextSibling,e=j("childList",d);e.addedNodes=h,e.removedNodes=i,e.previousSibling=n,e.nextSibling=o,f(d,function(a){return a.childList?e:void 0})}l()}},a.JsMutationObserver=g,a.MutationObserver||(a.MutationObserver=g)}(this),window.HTMLImports=window.HTMLImports||{flags:{}},function(a){var b=(a.path,a.xhr),c=a.flags,d=function(a,b){this.cache={},this.onload=a,this.oncomplete=b,this.inflight=0,this.pending={}};d.prototype={addNodes:function(a){this.inflight+=a.length;for(var b,c=0,d=a.length;d>c&&(b=a[c]);c++)this.require(b);this.checkDone()},addNode:function(a){this.inflight++,this.require(a),this.checkDone()},require:function(a){var b=a.src||a.href;a.__nodeUrl=b,this.dedupe(b,a)||this.fetch(b,a)},dedupe:function(a,b){if(this.pending[a])return this.pending[a].push(b),!0;return this.cache[a]?(this.onload(a,b,this.cache[a]),this.tail(),!0):(this.pending[a]=[b],!1)},fetch:function(a,d){c.load&&console.log("fetch",a,d);var e=function(b,c){this.receive(a,d,b,c)}.bind(this);b.load(a,e)},receive:function(a,b,c,d){this.cache[a]=d;for(var e,f=this.pending[a],g=0,h=f.length;h>g&&(e=f[g]);g++)this.onload(a,e,d),this.tail();this.pending[a]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},b=b||{async:!0,ok:function(a){return a.status>=200&&a.status<300||304===a.status||0===a.status},load:function(c,d,e){var f=new XMLHttpRequest;return(a.flags.debug||a.flags.bust)&&(c+="?"+Math.random()),f.open("GET",c,b.async),f.addEventListener("readystatechange",function(){4===f.readyState&&d.call(e,!b.ok(f)&&f,f.response||f.responseText,c)}),f.send(),f},loadDocument:function(a,b,c){this.load(a,b,c).responseType="document"}},a.xhr=b,a.Loader=d}(window.HTMLImports),function(a){function b(a){return"link"===a.localName&&a.rel===g}function c(a){var b,c=d(a);try{b=btoa(c)}catch(e){b=btoa(unescape(encodeURIComponent(c))),console.warn("Script contained non-latin characters that were forced to latin. Some characters may be wrong.",a)}return"data:text/javascript;base64,"+b}function d(a){return a.textContent+e(a)}function e(a){var b=a.__nodeUrl;if(!b){b=a.ownerDocument.baseURI;var c="["+Math.floor(1e3*(Math.random()+1))+"]",d=a.textContent.match(/Polymer\(['"]([^'"]*)/);c=d&&d[1]||c,b+="/"+c+".js"}return"\n//# sourceURL="+b+"\n"}function f(a){var b=a.ownerDocument.createElement("style");return b.textContent=a.textContent,n.resolveUrlsInStyle(b),b}var g="import",h=a.flags,i=/Trident/.test(navigator.userAgent),j=window.ShadowDOMPolyfill?window.ShadowDOMPolyfill.wrapIfNeeded(document):document,k={documentSelectors:"link[rel="+g+"]",importsSelectors:["link[rel="+g+"]","link[rel=stylesheet]","style","script:not([type])",'script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},parseNext:function(){var a=this.nextToParse();a&&this.parse(a)},parse:function(a){if(this.isParsed(a))return void(h.parse&&console.log("[%s] is already parsed",a.localName));var b=this[this.map[a.localName]];b&&(this.markParsing(a),b.call(this,a))},markParsing:function(a){h.parse&&console.log("parsing",a),this.parsingElement=a},markParsingComplete:function(a){a.__importParsed=!0,a.__importElement&&(a.__importElement.__importParsed=!0),this.parsingElement=null,h.parse&&console.log("completed",a),this.parseNext()},parseImport:function(a){if(a.import.__importParsed=!0,HTMLImports.__importsParsingHook&&HTMLImports.__importsParsingHook(a),a.dispatchEvent(a.__resource?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),a.__pending)for(var b;a.__pending.length;)b=a.__pending.shift(),b&&b({target:a});this.markParsingComplete(a)},parseLink:function(a){b(a)?this.parseImport(a):(a.href=a.href,this.parseGeneric(a))},parseStyle:function(a){var b=a;a=f(a),a.__importElement=b,this.parseGeneric(a)},parseGeneric:function(a){this.trackElement(a),document.head.appendChild(a)},trackElement:function(a,b){var c=this,d=function(d){b&&b(d),c.markParsingComplete(a)};if(a.addEventListener("load",d),a.addEventListener("error",d),i&&"style"===a.localName){var e=!1;if(-1==a.textContent.indexOf("@import"))e=!0;else if(a.sheet){e=!0;for(var f,g=a.sheet.cssRules,h=g?g.length:0,j=0;h>j&&(f=g[j]);j++)f.type===CSSRule.IMPORT_RULE&&(e=e&&Boolean(f.styleSheet))}e&&a.dispatchEvent(new CustomEvent("load",{bubbles:!1}))}},parseScript:function(b){var d=document.createElement("script");d.__importElement=b,d.src=b.src?b.src:c(b),a.currentScript=b,this.trackElement(d,function(){d.parentNode.removeChild(d),a.currentScript=null}),document.head.appendChild(d)},nextToParse:function(){return!this.parsingElement&&this.nextToParseInDoc(j)},nextToParseInDoc:function(a,c){for(var d,e=a.querySelectorAll(this.parseSelectorsForNode(a)),f=0,g=e.length;g>f&&(d=e[f]);f++)if(!this.isParsed(d))return this.hasResource(d)?b(d)?this.nextToParseInDoc(d.import,d):d:void 0;return c},parseSelectorsForNode:function(a){var b=a.ownerDocument||a;return b===j?this.documentSelectors:this.importsSelectors},isParsed:function(a){return a.__importParsed},hasResource:function(a){return b(a)&&!a.import?!1:!0}},l=/(url\()([^)]*)(\))/g,m=/(@import[\s]+(?!url\())([^;]*)(;)/g,n={resolveUrlsInStyle:function(a){var b=a.ownerDocument,c=b.createElement("a");return a.textContent=this.resolveUrlsInCssText(a.textContent,c),a},resolveUrlsInCssText:function(a,b){var c=this.replaceUrls(a,b,l);return c=this.replaceUrls(c,b,m)},replaceUrls:function(a,b,c){return a.replace(c,function(a,c,d,e){var f=d.replace(/["']/g,"");return b.href=f,f=b.href,c+"'"+f+"'"+e})}};a.parser=k,a.path=n,a.isIE=i}(HTMLImports),function(a){function b(a){return c(a,m)}function c(a,b){return"link"===a.localName&&a.getAttribute("rel")===b}function d(a,b){var c=a;c instanceof Document||(c=document.implementation.createHTMLDocument(m)),c._URL=b;var d=c.createElement("base");d.setAttribute("href",b),c.baseURI||(c.baseURI=b);var e=c.createElement("meta");return e.setAttribute("charset","utf-8"),c.head.appendChild(e),c.head.appendChild(d),a instanceof Document||(c.body.innerHTML=a),window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(c),c}function e(a,b){b=b||n,g(function(){h(a,b)},b)}function f(a){return"complete"===a.readyState||a.readyState===u}function g(a,b){if(f(b))a&&a();else{var c=function(){("complete"===b.readyState||b.readyState===u)&&(b.removeEventListener(v,c),g(a,b))};b.addEventListener(v,c)}}function h(a,b){function c(){f==g&&requestAnimationFrame(a)}function d(){f++,c()}var e=b.querySelectorAll("link[rel=import]"),f=0,g=e.length;if(g)for(var h,j=0;g>j&&(h=e[j]);j++)i(h)?d.call(h):(h.addEventListener("load",d),h.addEventListener("error",d));else c()}function i(a){return k?a.import&&"loading"!==a.import.readyState:a.__importParsed}var j="import"in document.createElement("link"),k=j,l=a.flags,m="import",n=window.ShadowDOMPolyfill?ShadowDOMPolyfill.wrapIfNeeded(document):document;if(k)var o={};else var p=(a.xhr,a.Loader),q=a.parser,o={documents:{},documentPreloadSelectors:"link[rel="+m+"]",importsPreloadSelectors:["link[rel="+m+"]"].join(","),loadNode:function(a){r.addNode(a)},loadSubtree:function(a){var b=this.marshalNodes(a);r.addNodes(b)},marshalNodes:function(a){return a.querySelectorAll(this.loadSelectorsForNode(a))},loadSelectorsForNode:function(a){var b=a.ownerDocument||a;return b===n?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(a,c,e){if(l.load&&console.log("loaded",a,c),c.__resource=e,b(c)){var f=this.documents[a];f||(f=d(e,a),f.__importLink=c,this.bootDocument(f),this.documents[a]=f),c.import=f}q.parseNext()},bootDocument:function(a){this.loadSubtree(a),this.observe(a),q.parseNext()},loadedAll:function(){q.parseNext()}},r=new p(o.loaded.bind(o),o.loadedAll.bind(o));var s={get:function(){return HTMLImports.currentScript||document.currentScript},configurable:!0};if(Object.defineProperty(document,"_currentScript",s),Object.defineProperty(n,"_currentScript",s),!document.baseURI){var t={get:function(){return window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",t),Object.defineProperty(n,"baseURI",t)}var u=HTMLImports.isIE?"complete":"interactive",v="readystatechange";a.hasNative=j,a.useNative=k,a.importer=o,a.whenImportsReady=e,a.IMPORT_LINK_TYPE=m,a.isImportLoaded=i,a.importLoader=r}(window.HTMLImports),function(a){function b(a){for(var b,d=0,e=a.length;e>d&&(b=a[d]);d++)"childList"===b.type&&b.addedNodes.length&&c(b.addedNodes)}function c(a){for(var b,e=0,g=a.length;g>e&&(b=a[e]);e++)d(b)&&f.loadNode(b),b.children&&b.children.length&&c(b.children)}function d(a){return 1===a.nodeType&&g.call(a,f.loadSelectorsForNode(a))}function e(a){h.observe(a,{childList:!0,subtree:!0})}var f=(a.IMPORT_LINK_TYPE,a.importer),g=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector,h=new MutationObserver(b);a.observe=e,f.observe=e}(HTMLImports),function(){function a(){HTMLImports.importer.bootDocument(b)}"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(a,b){var c=document.createEvent("HTMLEvents");return c.initEvent(a,b.bubbles===!1?!1:!0,b.cancelable===!1?!1:!0,b.detail),c});var b=window.ShadowDOMPolyfill?window.ShadowDOMPolyfill.wrapIfNeeded(document):document;HTMLImports.whenImportsReady(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime(),b.dispatchEvent(new CustomEvent("HTMLImportsLoaded",{bubbles:!0}))}),HTMLImports.useNative||("complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?a():document.addEventListener("DOMContentLoaded",a))}(),window.CustomElements=window.CustomElements||{flags:{}},function(a){function b(a,c,d){var e=a.firstElementChild;if(!e)for(e=a.firstChild;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;for(;e;)c(e,d)!==!0&&b(e,c,d),e=e.nextElementSibling;return null}function c(a,b){for(var c=a.shadowRoot;c;)d(c,b),c=c.olderShadowRoot}function d(a,d){b(a,function(a){return d(a)?!0:void c(a,d)}),c(a,d)}function e(a){return h(a)?(i(a),!0):void l(a)}function f(a){d(a,function(a){return e(a)?!0:void 0})}function g(a){return e(a)||f(a)}function h(b){if(!b.__upgraded__&&b.nodeType===Node.ELEMENT_NODE){var c=b.getAttribute("is")||b.localName,d=a.registry[c];if(d)return A.dom&&console.group("upgrade:",b.localName),a.upgrade(b),A.dom&&console.groupEnd(),!0}}function i(a){l(a),r(a)&&d(a,function(a){l(a)})}function j(a){if(E.push(a),!D){D=!0;var b=window.Platform&&window.Platform.endOfMicrotask||setTimeout;b(k)}}function k(){D=!1;for(var a,b=E,c=0,d=b.length;d>c&&(a=b[c]);c++)a();E=[]}function l(a){C?j(function(){m(a)}):m(a)}function m(a){(a.attachedCallback||a.detachedCallback||a.__upgraded__&&A.dom)&&(A.dom&&console.group("inserted:",a.localName),r(a)&&(a.__inserted=(a.__inserted||0)+1,a.__inserted<1&&(a.__inserted=1),a.__inserted>1?A.dom&&console.warn("inserted:",a.localName,"insert/remove count:",a.__inserted):a.attachedCallback&&(A.dom&&console.log("inserted:",a.localName),a.attachedCallback())),A.dom&&console.groupEnd())}function n(a){o(a),d(a,function(a){o(a)})}function o(a){C?j(function(){p(a)}):p(a)}function p(a){(a.attachedCallback||a.detachedCallback||a.__upgraded__&&A.dom)&&(A.dom&&console.group("removed:",a.localName),r(a)||(a.__inserted=(a.__inserted||0)-1,a.__inserted>0&&(a.__inserted=0),a.__inserted<0?A.dom&&console.warn("removed:",a.localName,"insert/remove count:",a.__inserted):a.detachedCallback&&a.detachedCallback()),A.dom&&console.groupEnd())}function q(a){return window.ShadowDOMPolyfill?ShadowDOMPolyfill.wrapIfNeeded(a):a}function r(a){for(var b=a,c=q(document);b;){if(b==c)return!0;b=b.parentNode||b.host}}function s(a){if(a.shadowRoot&&!a.shadowRoot.__watched){A.dom&&console.log("watching shadow-root for: ",a.localName);for(var b=a.shadowRoot;b;)t(b),b=b.olderShadowRoot}}function t(a){a.__watched||(w(a),a.__watched=!0)}function u(a){if(A.dom){var b=a[0];if(b&&"childList"===b.type&&b.addedNodes&&b.addedNodes){for(var c=b.addedNodes[0];c&&c!==document&&!c.host;)c=c.parentNode;var d=c&&(c.URL||c._URL||c.host&&c.host.localName)||"";d=d.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",a.length,d||"")}a.forEach(function(a){"childList"===a.type&&(G(a.addedNodes,function(a){a.localName&&g(a)}),G(a.removedNodes,function(a){a.localName&&n(a)}))}),A.dom&&console.groupEnd()}function v(){u(F.takeRecords()),k()}function w(a){F.observe(a,{childList:!0,subtree:!0})}function x(a){w(a)}function y(a){A.dom&&console.group("upgradeDocument: ",a.baseURI.split("/").pop()),g(a),A.dom&&console.groupEnd()}function z(a){a=q(a);for(var b,c=a.querySelectorAll("link[rel="+B+"]"),d=0,e=c.length;e>d&&(b=c[d]);d++)b.import&&b.import.__parsed&&z(b.import);y(a)}var A=window.logFlags||{},B=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none",C=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;a.hasPolyfillMutations=C;var D=!1,E=[],F=new MutationObserver(u),G=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.IMPORT_LINK_TYPE=B,a.watchShadow=s,a.upgradeDocumentTree=z,a.upgradeAll=g,a.upgradeSubtree=f,a.insertedNode=i,a.observeDocument=x,a.upgradeDocument=y,a.takeRecords=v}(window.CustomElements),function(a){function b(b,f){var g=f||{};if(!b)throw new Error("document.registerElement: first argument `name` must not be empty");if(b.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(b)+"'.");if(m(b))throw new Error("DuplicateDefinitionError: a type with name '"+String(b)+"' is already registered");if(!g.prototype)throw new Error("Options missing required prototype property");return g.__name=b.toLowerCase(),g.lifecycle=g.lifecycle||{},g.ancestry=c(g.extends),d(g),e(g),k(g.prototype),n(g.__name,g),g.ctor=o(g),g.ctor.prototype=g.prototype,g.prototype.constructor=g.ctor,a.ready&&a.upgradeDocumentTree(document),g.ctor}function c(a){var b=m(a);return b?c(b.extends).concat([b]):[]}function d(a){for(var b,c=a.extends,d=0;b=a.ancestry[d];d++)c=b.is&&b.tag;a.tag=c||a.__name,c&&(a.is=a.__name)}function e(a){if(!Object.__proto__){var b=HTMLElement.prototype;if(a.is){var c=document.createElement(a.tag);b=Object.getPrototypeOf(c)}for(var d,e=a.prototype;e&&e!==b;){var d=Object.getPrototypeOf(e);e.__proto__=d,e=d}}a.native=b}function f(a){return g(z(a.tag),a)}function g(b,c){return c.is&&b.setAttribute("is",c.is),b.removeAttribute("unresolved"),h(b,c),b.__upgraded__=!0,j(b),a.insertedNode(b),a.upgradeSubtree(b),b}function h(a,b){Object.__proto__?a.__proto__=b.prototype:(i(a,b.prototype,b.native),a.__proto__=b.prototype)}function i(a,b,c){for(var d={},e=b;e!==c&&e!==HTMLElement.prototype;){for(var f,g=Object.getOwnPropertyNames(e),h=0;f=g[h];h++)d[f]||(Object.defineProperty(a,f,Object.getOwnPropertyDescriptor(e,f)),d[f]=1);e=Object.getPrototypeOf(e)}}function j(a){a.createdCallback&&a.createdCallback()}function k(a){if(!a.setAttribute._polyfilled){var b=a.setAttribute;a.setAttribute=function(a,c){l.call(this,a,c,b)};var c=a.removeAttribute;a.removeAttribute=function(a){l.call(this,a,null,c)},a.setAttribute._polyfilled=!0}}function l(a,b,c){var d=this.getAttribute(a);c.apply(this,arguments);var e=this.getAttribute(a);this.attributeChangedCallback&&e!==d&&this.attributeChangedCallback(a,d,e)}function m(a){return a?x[a.toLowerCase()]:void 0}function n(a,b){x[a]=b}function o(a){return function(){return f(a)}}function p(a,b,c){return a===y?q(b,c):A(a,b)}function q(a,b){var c=m(b||a);if(c){if(a==c.tag&&b==c.is)return new c.ctor;if(!b&&!c.is)return new c.ctor}if(b){var d=q(a);return d.setAttribute("is",b),d}var d=z(a);return a.indexOf("-")>=0&&h(d,HTMLElement),d}function r(a){if(!a.__upgraded__&&a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute("is"),c=m(b||a.localName);if(c){if(b&&c.tag==a.localName)return g(a,c);if(!b&&!c.extends)return g(a,c)}}}function s(b){var c=B.call(this,b);return a.upgradeAll(c),c}a||(a=window.CustomElements={flags:{}});var t=a.flags,u=Boolean(document.registerElement),v=!t.register&&u&&!window.ShadowDOMPolyfill;if(v){var w=function(){};a.registry={},a.upgradeElement=w,a.watchShadow=w,a.upgrade=w,a.upgradeAll=w,a.upgradeSubtree=w,a.observeDocument=w,a.upgradeDocument=w,a.upgradeDocumentTree=w,a.takeRecords=w}else{var x={},y="http://www.w3.org/1999/xhtml",z=document.createElement.bind(document),A=document.createElementNS.bind(document),B=Node.prototype.cloneNode;document.registerElement=b,document.createElement=q,document.createElementNS=p,Node.prototype.cloneNode=s,a.registry=x,a.upgrade=r}var C;C=Object.__proto__||v?function(a,b){return a instanceof b}:function(a,b){for(var c=a;c;){if(c===b.prototype)return!0;c=c.__proto__}return!1},a.instanceof=C,document.register=document.registerElement,a.hasNative=u,a.useNative=v}(window.CustomElements),function(a){function b(a){return"link"===a.localName&&a.getAttribute("rel")===c}var c=a.IMPORT_LINK_TYPE,d={selectors:["link[rel="+c+"]"],map:{link:"parseLink"},parse:function(a){if(!a.__parsed){a.__parsed=!0;var b=a.querySelectorAll(d.selectors);e(b,function(a){d[d.map[a.localName]](a)}),CustomElements.upgradeDocument(a),CustomElements.observeDocument(a)}},parseLink:function(a){b(a)&&this.parseImport(a)},parseImport:function(a){a.import&&d.parse(a.import)}},e=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.parser=d,a.IMPORT_LINK_TYPE=c}(window.CustomElements),function(a){function b(){CustomElements.parser.parse(document),CustomElements.upgradeDocument(document);var a=window.Platform&&Platform.endOfMicrotask?Platform.endOfMicrotask:setTimeout;a(function(){CustomElements.ready=!0,CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0})),window.HTMLImports&&(HTMLImports.__importsParsingHook=function(a){CustomElements.parser.parse(a.import)})})}if("function"!=typeof window.CustomEvent&&(window.CustomEvent=function(a){var b=document.createEvent("HTMLEvents");return b.initEvent(a,!0,!0),b}),"complete"===document.readyState||a.flags.eager)b();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var c=window.HTMLImports&&!HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(c,b)}else b()}(window.CustomElements),function(){if(window.ShadowDOMPolyfill){var a=["upgradeAll","upgradeSubtree","observeDocument","upgradeDocument"],b={};a.forEach(function(a){b[a]=CustomElements[a]}),a.forEach(function(a){CustomElements[a]=function(c){return b[a](wrap(c))}})}}(),function(a){function b(a){this.regex=a}var c=a.endOfMicrotask;b.prototype={extractUrls:function(a,b){for(var c,d,e=[];c=this.regex.exec(a);)d=new URL(c[1],b),e.push({matched:c[0],url:d.href});return e},process:function(a,b,c){var d=this.extractUrls(a,b);this.fetch(d,{},c)},fetch:function(a,b,d){var e=a.length;if(!e)return d(b);for(var f,g,h,i=function(){0===--e&&d(b)},j=function(a,c){var d=c.match,e=d.url;if(a)return b[e]="",i();var f=c.response||c.responseText;b[e]=f,this.fetch(this.extractUrls(f,e),b,i)},k=0;e>k;k++)f=a[k],h=f.url,b[h]?c(i):(g=this.xhr(h,j,this),g.match=f,b[h]=g)},xhr:function(a,b,c){var d=new XMLHttpRequest;return d.open("GET",a,!0),d.send(),d.onload=function(){b.call(c,null,d)},d.onerror=function(){b.call(c,null,d)},d}},a.Loader=b}(window.Platform),function(a){function b(){this.loader=new d(this.regex)}var c=a.urlResolver,d=a.Loader;b.prototype={regex:/@import\s+(?:url)?["'\(]*([^'"\)]*)['"\)]*;/g,resolve:function(a,b,c){var d=function(d){c(this.flatten(a,b,d))}.bind(this);this.loader.process(a,b,d)},resolveNode:function(a,b){var c=a.textContent,d=a.ownerDocument.baseURI,e=function(c){a.textContent=c,b(a)};this.resolve(c,d,e)},flatten:function(a,b,d){for(var e,f,g,h=this.loader.extractUrls(a,b),i=0;i<h.length;i++)e=h[i],f=e.url,g=c.resolveCssText(d[f],f),g=this.flatten(g,f,d),a=a.replace(e.matched,g);return a},loadStyles:function(a,b){function c(){e++,e===f&&b&&b()}for(var d,e=0,f=a.length,g=0;f>g&&(d=a[g]);g++)this.resolveNode(d,c)}};var e=new b;a.styleResolver=e}(window.Platform),function(a){a=a||{},a.external=a.external||{};var b={shadow:function(a){return a?a.shadowRoot||a.webkitShadowRoot:void 0},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);return this.canTarget(b)?b:void 0},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){if(a){var d,e,f=a.elementFromPoint(b,c);for(e=this.targetingShadow(f);e;){if(d=e.elementFromPoint(b,c)){var g=this.targetingShadow(d);return this.searchRoot(g,b,c)||d}e=this.olderShadow(e)}return f}},owner:function(a){for(var b=a;b.parentNode;)b=b.parentNode;return b.nodeType!=Node.DOCUMENT_NODE&&b.nodeType!=Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){var b=a.clientX,c=a.clientY,d=this.owner(a.target);return d.elementFromPoint(b,c)||(d=document),this.searchRoot(d,b,c)}};a.targetFinding=b,a.findTarget=b.findTarget.bind(b),window.PointerEventsPolyfill=a}(window.PointerEventsPolyfill),function(){function a(a){return"body ^^ "+b(a)}function b(a){return'[touch-action="'+a+'"]'}function c(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+"; touch-action-delay: none; }"}var d=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]}],e="";d.forEach(function(d){String(d)===d?(e+=b(d)+c(d)+"\n",e+=a(d)+c(d)+"\n"):(e+=d.selectors.map(b)+c(d.rule)+"\n",e+=d.selectors.map(a)+c(d.rule)+"\n")});var f=document.createElement("style");f.textContent=e,document.head.appendChild(f)}(),function(a){function b(a,e){e=e||{};var f=e.buttons;if(!d&&!f&&"touch"!==a)switch(e.which){case 1:f=1;break;case 2:f=4;break;case 3:f=2;break;default:f=0}var i;if(c)i=new MouseEvent(a,e);else{i=document.createEvent("MouseEvent");for(var j,k={},l=0;l<g.length;l++)j=g[l],k[j]=e[j]||h[l];i.initMouseEvent(a,k.bubbles,k.cancelable,k.view,k.detail,k.screenX,k.screenY,k.clientX,k.clientY,k.ctrlKey,k.altKey,k.shiftKey,k.metaKey,k.button,k.relatedTarget)}i.__proto__=b.prototype,d||Object.defineProperty(i,"buttons",{get:function(){return f},enumerable:!0});var m=0;return m=e.pressure?e.pressure:f?.5:0,Object.defineProperties(i,{pointerId:{value:e.pointerId||0,enumerable:!0},width:{value:e.width||0,enumerable:!0},height:{value:e.height||0,enumerable:!0},pressure:{value:m,enumerable:!0},tiltX:{value:e.tiltX||0,enumerable:!0},tiltY:{value:e.tiltY||0,enumerable:!0},pointerType:{value:e.pointerType||"",enumerable:!0},hwTimestamp:{value:e.hwTimestamp||0,enumerable:!0},isPrimary:{value:e.isPrimary||!1,enumerable:!0}}),i}var c=!1,d=!1;try{var e=new MouseEvent("click",{buttons:1});c=!0,d=1===e.buttons,e=null}catch(f){}var g=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget"],h=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null];b.prototype=Object.create(MouseEvent.prototype),a.PointerEvent||(a.PointerEvent=b)}(window),function(a){function b(){if(c){var a=new Map;return a.pointers=d,a}this.keys=[],this.values=[]}var c=window.Map&&window.Map.prototype.forEach,d=function(){return this.size};b.prototype={set:function(a,b){var c=this.keys.indexOf(a);
-c>-1?this.values[c]=b:(this.keys.push(a),this.values.push(b))},has:function(a){return this.keys.indexOf(a)>-1},"delete":function(a){var b=this.keys.indexOf(a);b>-1&&(this.keys.splice(b,1),this.values.splice(b,1))},get:function(a){var b=this.keys.indexOf(a);return this.values[b]},clear:function(){this.keys.length=0,this.values.length=0},forEach:function(a,b){this.values.forEach(function(c,d){a.call(b,c,this.keys[d],this)},this)},pointers:function(){return this.keys.length}},a.PointerMap=b}(window.PointerEventsPolyfill),function(a){var b=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which"],c=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0],d="undefined"!=typeof SVGElementInstance,e={targets:new WeakMap,handledEvents:new WeakMap,pointermap:new a.PointerMap,eventMap:{},eventSources:{},eventSourceList:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},register:function(a){for(var b,c=this.eventSourceList.length,d=0;c>d&&(b=this.eventSourceList[d]);d++)b.register.call(b,a)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;c>d&&(b=this.eventSourceList[d]);d++)b.unregister.call(b,a)},contains:a.external.contains||function(a,b){return a.contains(b)},down:function(a){a.bubbles=!0,this.fireEvent("pointerdown",a)},move:function(a){a.bubbles=!0,this.fireEvent("pointermove",a)},up:function(a){a.bubbles=!0,this.fireEvent("pointerup",a)},enter:function(a){a.bubbles=!1,this.fireEvent("pointerenter",a)},leave:function(a){a.bubbles=!1,this.fireEvent("pointerleave",a)},over:function(a){a.bubbles=!0,this.fireEvent("pointerover",a)},out:function(a){a.bubbles=!0,this.fireEvent("pointerout",a)},cancel:function(a){a.bubbles=!0,this.fireEvent("pointercancel",a)},leaveOut:function(a){this.out(a),this.contains(a.target,a.relatedTarget)||this.leave(a)},enterOver:function(a){this.over(a),this.contains(a.target,a.relatedTarget)||this.enter(a)},eventHandler:function(a){if(!this.handledEvents.get(a)){var b=a.type,c=this.eventMap&&this.eventMap[b];c&&c(a),this.handledEvents.set(a,!0)}},listen:function(a,b){b.forEach(function(b){this.addEvent(a,b)},this)},unlisten:function(a,b){b.forEach(function(b){this.removeEvent(a,b)},this)},addEvent:a.external.addEvent||function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:a.external.removeEvent||function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(a,b){this.captureInfo&&(b.relatedTarget=null);var c=new PointerEvent(a,b);return b.preventDefault&&(c.preventDefault=b.preventDefault),this.targets.set(c,this.targets.get(b)||b.target),c},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var e,f={},g=0;g<b.length;g++)e=b[g],f[e]=a[e]||c[g],!d||"target"!==e&&"relatedTarget"!==e||f[e]instanceof SVGElementInstance&&(f[e]=f[e].correspondingUseElement);return a.preventDefault&&(f.preventDefault=function(){a.preventDefault()}),f},getTarget:function(a){return this.captureInfo&&this.captureInfo.id===a.pointerId?this.captureInfo.target:this.targets.get(a)},setCapture:function(a,b){this.captureInfo&&this.releaseCapture(this.captureInfo.id),this.captureInfo={id:a,target:b};var c=new PointerEvent("gotpointercapture",{bubbles:!0});this.implicitRelease=this.releaseCapture.bind(this,a),document.addEventListener("pointerup",this.implicitRelease),document.addEventListener("pointercancel",this.implicitRelease),this.targets.set(c,b),this.asyncDispatchEvent(c)},releaseCapture:function(a){if(this.captureInfo&&this.captureInfo.id===a){var b=new PointerEvent("lostpointercapture",{bubbles:!0}),c=this.captureInfo.target;this.captureInfo=null,document.removeEventListener("pointerup",this.implicitRelease),document.removeEventListener("pointercancel",this.implicitRelease),this.targets.set(b,c),this.asyncDispatchEvent(b)}},dispatchEvent:a.external.dispatchEvent||function(a){var b=this.getTarget(a);return b?b.dispatchEvent(a):void 0},asyncDispatchEvent:function(a){setTimeout(this.dispatchEvent.bind(this,a),0)}};e.boundHandler=e.eventHandler.bind(e),a.dispatcher=e,a.register=e.register.bind(e),a.unregister=e.unregister.bind(e)}(window.PointerEventsPolyfill),function(a){function b(a,b,c,d){this.addCallback=a.bind(d),this.removeCallback=b.bind(d),this.changedCallback=c.bind(d),g&&(this.observer=new g(this.mutationWatcher.bind(this)))}var c=Array.prototype.forEach.call.bind(Array.prototype.forEach),d=Array.prototype.map.call.bind(Array.prototype.map),e=Array.prototype.slice.call.bind(Array.prototype.slice),f=Array.prototype.filter.call.bind(Array.prototype.filter),g=window.MutationObserver||window.WebKitMutationObserver,h="[touch-action]",i={subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0,attributeFilter:["touch-action"]};b.prototype={watchSubtree:function(b){a.targetFinding.canTarget(b)&&this.observer.observe(b,i)},enableOnSubtree:function(a){this.watchSubtree(a),a===document&&"complete"!==document.readyState?this.installOnLoad():this.installNewSubtree(a)},installNewSubtree:function(a){c(this.findElements(a),this.addElement,this)},findElements:function(a){return a.querySelectorAll?a.querySelectorAll(h):[]},removeElement:function(a){this.removeCallback(a)},addElement:function(a){this.addCallback(a)},elementChanged:function(a,b){this.changedCallback(a,b)},concatLists:function(a,b){return a.concat(e(b))},installOnLoad:function(){document.addEventListener("readystatechange",function(){"complete"===document.readyState&&this.installNewSubtree(document)}.bind(this))},isElement:function(a){return a.nodeType===Node.ELEMENT_NODE},flattenMutationTree:function(a){var b=d(a,this.findElements,this);return b.push(f(a,this.isElement)),b.reduce(this.concatLists,[])},mutationWatcher:function(a){a.forEach(this.mutationHandler,this)},mutationHandler:function(a){if("childList"===a.type){var b=this.flattenMutationTree(a.addedNodes);b.forEach(this.addElement,this);var c=this.flattenMutationTree(a.removedNodes);c.forEach(this.removeElement,this)}else"attributes"===a.type&&this.elementChanged(a.target,a.oldValue)}},g||(b.prototype.watchSubtree=function(){console.warn("PointerEventsPolyfill: MutationObservers not found, touch-action will not be dynamically detected")}),a.Installer=b}(window.PointerEventsPolyfill),function(a){var b=a.dispatcher,c=b.pointermap,d=25,e={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup","mouseover","mouseout"],register:function(a){b.listen(a,this.events)},unregister:function(a){b.unlisten(a,this.events)},lastTouches:[],isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,e=a.clientX,f=a.clientY,g=0,h=c.length;h>g&&(b=c[g]);g++){var i=Math.abs(e-b.x),j=Math.abs(f-b.y);if(d>=i&&d>=j)return!0}},prepareEvent:function(a){var c=b.cloneEvent(a),d=c.preventDefault;return c.preventDefault=function(){a.preventDefault(),d()},c.pointerId=this.POINTER_ID,c.isPrimary=!0,c.pointerType=this.POINTER_TYPE,c},mousedown:function(a){if(!this.isEventSimulatedFromTouch(a)){var d=c.has(this.POINTER_ID);d&&this.cancel(a);var e=this.prepareEvent(a);c.set(this.POINTER_ID,a),b.down(e)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var c=this.prepareEvent(a);b.move(c)}},mouseup:function(a){if(!this.isEventSimulatedFromTouch(a)){var d=c.get(this.POINTER_ID);if(d&&d.button===a.button){var e=this.prepareEvent(a);b.up(e),this.cleanupMouse()}}},mouseover:function(a){if(!this.isEventSimulatedFromTouch(a)){var c=this.prepareEvent(a);b.enterOver(c)}},mouseout:function(a){if(!this.isEventSimulatedFromTouch(a)){var c=this.prepareEvent(a);b.leaveOut(c)}},cancel:function(a){var c=this.prepareEvent(a);b.cancel(c),this.cleanupMouse()},cleanupMouse:function(){c["delete"](this.POINTER_ID)}};a.mouseEvents=e}(window.PointerEventsPolyfill),function(a){var b,c=a.dispatcher,d=a.findTarget,e=a.targetFinding.allShadows.bind(a.targetFinding),f=c.pointermap,g=Array.prototype.map.call.bind(Array.prototype.map),h=2500,i=200,j="touch-action",k=!1,l={scrollType:new WeakMap,events:["touchstart","touchmove","touchend","touchcancel"],register:function(a){k?c.listen(a,this.events):b.enableOnSubtree(a)},unregister:function(a){k&&c.unlisten(a,this.events)},elementAdded:function(a){var b=a.getAttribute(j),d=this.touchActionToScrollType(b);d&&(this.scrollType.set(a,d),c.listen(a,this.events),e(a).forEach(function(a){this.scrollType.set(a,d),c.listen(a,this.events)},this))},elementRemoved:function(a){this.scrollType["delete"](a),c.unlisten(a,this.events),e(a).forEach(function(a){this.scrollType["delete"](a),c.unlisten(a,this.events)},this)},elementChanged:function(a,b){var c=a.getAttribute(j),d=this.touchActionToScrollType(c),f=this.touchActionToScrollType(b);d&&f?(this.scrollType.set(a,d),e(a).forEach(function(a){this.scrollType.set(a,d)},this)):f?this.elementRemoved(a):d&&this.elementAdded(a)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y",SCROLLER:/^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return"none"===b?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":c.SCROLLER.exec(b)?"XY":void 0},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){(0===f.pointers()||1===f.pointers()&&f.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.scrolling=!1,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,i)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return("touchstart"===a||"touchmove"===a)&&(b=1),b},touchToPointer:function(a){var b=c.cloneEvent(a);return b.pointerId=a.identifier+2,b.target=d(b),b.bubbles=!0,b.cancelable=!0,b.detail=this.clickCount,b.button=0,b.buttons=this.typeToButtons(this.currentTouchEvent),b.width=a.webkitRadiusX||a.radiusX||0,b.height=a.webkitRadiusY||a.radiusY||0,b.pressure=a.webkitForce||a.force||.5,b.isPrimary=this.isPrimaryTouch(a),b.pointerType=this.POINTER_TYPE,b},processTouches:function(a,b){var c=a.changedTouches;this.currentTouchEvent=a.type;var d=g(c,this.touchToPointer,this);d.forEach(function(b){b.preventDefault=function(){this.scrolling=!1,this.firstXY=null,a.preventDefault()}},this),d.forEach(b,this)},shouldScroll:function(a){if(this.firstXY){var b,c=this.scrollType.get(a.currentTarget);if("none"===c)b=!1;else if("XY"===c)b=!0;else{var d=a.changedTouches[0],e=c,f="Y"===c?"X":"Y",g=Math.abs(d["client"+e]-this.firstXY[e]),h=Math.abs(d["client"+f]-this.firstXY[f]);b=g>=h}return this.firstXY=null,b}},findTouch:function(a,b){for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)if(c.identifier===b)return!0},vacuumTouches:function(a){var b=a.touches;if(f.pointers()>=b.length){var c=[];f.forEach(function(a,d){if(1!==d&&!this.findTouch(b,d-2)){var e=a.out;c.push(this.touchToPointer(e))}},this),c.forEach(this.cancelOut,this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.overDown))},overDown:function(a){f.set(a.pointerId,{target:a.target,out:a,outTarget:a.target});c.over(a),c.enter(a),c.down(a)},touchmove:function(a){this.scrolling||(this.shouldScroll(a)?(this.scrolling=!0,this.touchcancel(a)):(a.preventDefault(),this.processTouches(a,this.moveOverOut)))},moveOverOut:function(a){var b=a,d=f.get(b.pointerId);if(d){var e=d.out,g=d.outTarget;c.move(b),e&&g!==b.target&&(e.relatedTarget=b.target,b.relatedTarget=g,e.target=g,b.target?(c.leaveOut(e),c.enterOver(b)):(b.target=g,b.relatedTarget=null,this.cancelOut(b))),d.out=b,d.outTarget=b.target}},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.upOut)},upOut:function(a){this.scrolling||(c.up(a),c.out(a),c.leave(a)),this.cleanUpPointer(a)},touchcancel:function(a){this.processTouches(a,this.cancelOut)},cancelOut:function(a){c.cancel(a),c.out(a),c.leave(a),this.cleanUpPointer(a)},cleanUpPointer:function(a){f["delete"](a.pointerId),this.removePrimaryPointer(a)},dedupSynthMouse:function(b){var c=a.mouseEvents.lastTouches,d=b.changedTouches[0];if(this.isPrimaryTouch(d)){var e={x:d.clientX,y:d.clientY};c.push(e);var f=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,c,e);setTimeout(f,h)}}};k||(b=new a.Installer(l.elementAdded,l.elementRemoved,l.elementChanged,l)),a.touchEvents=l}(window.PointerEventsPolyfill),function(a){var b=a.dispatcher,c=b.pointermap,d=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,e={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerOut","MSPointerOver","MSPointerCancel","MSGotPointerCapture","MSLostPointerCapture"],register:function(a){b.listen(a,this.events)},unregister:function(a){b.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var c=a;return d&&(c=b.cloneEvent(a),c.pointerType=this.POINTER_TYPES[a.pointerType]),c},cleanup:function(a){c["delete"](a)},MSPointerDown:function(a){c.set(a.pointerId,a);var d=this.prepareEvent(a);b.down(d)},MSPointerMove:function(a){var c=this.prepareEvent(a);b.move(c)},MSPointerUp:function(a){var c=this.prepareEvent(a);b.up(c),this.cleanup(a.pointerId)},MSPointerOut:function(a){var c=this.prepareEvent(a);b.leaveOut(c)},MSPointerOver:function(a){var c=this.prepareEvent(a);b.enterOver(c)},MSPointerCancel:function(a){var c=this.prepareEvent(a);b.cancel(c),this.cleanup(a.pointerId)},MSLostPointerCapture:function(a){var c=b.makeEvent("lostpointercapture",a);b.dispatchEvent(c)},MSGotPointerCapture:function(a){var c=b.makeEvent("gotpointercapture",a);b.dispatchEvent(c)}};a.msEvents=e}(window.PointerEventsPolyfill),function(a){var b=a.dispatcher;if(void 0===window.navigator.pointerEnabled){if(Object.defineProperty(window.navigator,"pointerEnabled",{value:!0,enumerable:!0}),window.navigator.msPointerEnabled){var c=window.navigator.msMaxTouchPoints;Object.defineProperty(window.navigator,"maxTouchPoints",{value:c,enumerable:!0}),b.registerSource("ms",a.msEvents)}else b.registerSource("mouse",a.mouseEvents),void 0!==window.ontouchstart&&b.registerSource("touch",a.touchEvents);b.register(document)}}(window.PointerEventsPolyfill),function(a){function b(a){if(!e.pointermap.has(a))throw new Error("InvalidPointerId")}var c,d,e=a.dispatcher,f=window.navigator;f.msPointerEnabled?(c=function(a){b(a),this.msSetPointerCapture(a)},d=function(a){b(a),this.msReleasePointerCapture(a)}):(c=function(a){b(a),e.setCapture(a,this)},d=function(a){b(a),e.releaseCapture(a,this)}),window.Element&&!Element.prototype.setPointerCapture&&Object.defineProperties(Element.prototype,{setPointerCapture:{value:c},releasePointerCapture:{value:d}})}(window.PointerEventsPolyfill),PointerGestureEvent.prototype.preventTap=function(){this.tapPrevented=!0},function(a){a=a||{},a.utils={LCA:{find:function(a,b){if(a===b)return a;if(a.contains){if(a.contains(b))return a;if(b.contains(a))return b}var c=this.depth(a),d=this.depth(b),e=c-d;for(e>0?a=this.walk(a,e):b=this.walk(b,-e);a&&b&&a!==b;)a=this.walk(a,1),b=this.walk(b,1);return a},walk:function(a,b){for(var c=0;b>c;c++)a=a.parentNode;return a},depth:function(a){for(var b=0;a;)b++,a=a.parentNode;return b}}},a.findLCA=function(b,c){return a.utils.LCA.find(b,c)},window.PointerGestures=a}(window.PointerGestures),function(a){function b(){if(c){var a=new Map;return a.pointers=d,a}this.keys=[],this.values=[]}var c=window.Map&&window.Map.prototype.forEach,d=function(){return this.size};b.prototype={set:function(a,b){var c=this.keys.indexOf(a);c>-1?this.values[c]=b:(this.keys.push(a),this.values.push(b))},has:function(a){return this.keys.indexOf(a)>-1},"delete":function(a){var b=this.keys.indexOf(a);b>-1&&(this.keys.splice(b,1),this.values.splice(b,1))},get:function(a){var b=this.keys.indexOf(a);return this.values[b]},clear:function(){this.keys.length=0,this.values.length=0},forEach:function(a,b){this.values.forEach(function(c,d){a.call(b,c,this.keys[d],this)},this)},pointers:function(){return this.keys.length}},a.PointerMap=b}(window.PointerGestures),function(a){var b=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","screenX","screenY","pageX","pageY","tapPrevented"],c=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0],d={handledEvents:new WeakMap,targets:new WeakMap,handlers:{},recognizers:{},events:{},registerRecognizer:function(a,b){var c=b;this.recognizers[a]=c,c.events.forEach(function(a){if(c[a]){this.events[a]=!0;var b=c[a].bind(c);this.addHandler(a,b)}},this)},addHandler:function(a,b){var c=a;this.handlers[c]||(this.handlers[c]=[]),this.handlers[c].push(b)},registerTarget:function(a){this.listen(Object.keys(this.events),a)},unregisterTarget:function(a){this.unlisten(Object.keys(this.events),a)},eventHandler:function(a){if(!this.handledEvents.get(a)){var b=a.type,c=this.handlers[b];c&&this.makeQueue(c,a),this.handledEvents.set(a,!0)}},makeQueue:function(a,b){var c=this.cloneEvent(b);setTimeout(this.runQueue.bind(this,a,c),0)},runQueue:function(a,b){this.currentPointerId=b.pointerId;for(var c,d=0,e=a.length;e>d&&(c=a[d]);d++)c(b);this.currentPointerId=0},listen:function(a,b){a.forEach(function(a){this.addEvent(a,this.boundHandler,!1,b)},this)},unlisten:function(a){a.forEach(function(a){this.removeEvent(a,this.boundHandler,!1,inTarget)},this)},addEvent:function(a,b,c,d){d.addEventListener(a,b,c)},removeEvent:function(a,b,c,d){d.removeEventListener(a,b,c)},makeEvent:function(a,b){return new PointerGestureEvent(a,b)},cloneEvent:function(a){for(var d,e={},f=0;f<b.length;f++)d=b[f],e[d]=a[d]||c[f];return e},dispatchEvent:function(a,b){var c=b||this.targets.get(a);c&&(c.dispatchEvent(a),a.tapPrevented&&this.preventTap(this.currentPointerId))},asyncDispatchEvent:function(a,b){var c=function(){this.dispatchEvent(a,b)}.bind(this);setTimeout(c,0)},preventTap:function(a){var b=this.recognizers.tap;b&&b.preventTap(a)}};d.boundHandler=d.eventHandler.bind(d),d.registerQueue=[],d.immediateRegister=!1,a.dispatcher=d,a.register=function(b){if(d.immediateRegister){var c=window.PointerEventsPolyfill;c&&c.register(b),a.dispatcher.registerTarget(b)}else d.registerQueue.push(b)},a.register(document)}(window.PointerGestures),function(a){var b=a.dispatcher,c={HOLD_DELAY:200,WIGGLE_THRESHOLD:16,events:["pointerdown","pointermove","pointerup","pointercancel"],heldPointer:null,holdJob:null,pulse:function(){var a=Date.now()-this.heldPointer.timeStamp,b=this.held?"holdpulse":"hold";this.fireHold(b,a),this.held=!0},cancel:function(){clearInterval(this.holdJob),this.held&&this.fireHold("release"),this.held=!1,this.heldPointer=null,this.target=null,this.holdJob=null},pointerdown:function(a){a.isPrimary&&!this.heldPointer&&(this.heldPointer=a,this.target=a.target,this.holdJob=setInterval(this.pulse.bind(this),this.HOLD_DELAY))},pointerup:function(a){this.heldPointer&&this.heldPointer.pointerId===a.pointerId&&this.cancel()},pointercancel:function(){this.cancel()},pointermove:function(a){if(this.heldPointer&&this.heldPointer.pointerId===a.pointerId){var b=a.clientX-this.heldPointer.clientX,c=a.clientY-this.heldPointer.clientY;b*b+c*c>this.WIGGLE_THRESHOLD&&this.cancel()}},fireHold:function(a,c){var d={pointerType:this.heldPointer.pointerType,clientX:this.heldPointer.clientX,clientY:this.heldPointer.clientY};c&&(d.holdTime=c);var e=b.makeEvent(a,d);b.dispatchEvent(e,this.target),e.tapPrevented&&b.preventTap(this.heldPointer.pointerId)}};b.registerRecognizer("hold",c)}(window.PointerGestures),function(a){var b=a.dispatcher,c=new a.PointerMap,d={events:["pointerdown","pointermove","pointerup","pointercancel"],WIGGLE_THRESHOLD:4,clampDir:function(a){return a>0?1:-1},calcPositionDelta:function(a,b){var c=0,d=0;return a&&b&&(c=b.pageX-a.pageX,d=b.pageY-a.pageY),{x:c,y:d}},fireTrack:function(a,c,d){var e=d,f=this.calcPositionDelta(e.downEvent,c),g=this.calcPositionDelta(e.lastMoveEvent,c);g.x&&(e.xDirection=this.clampDir(g.x)),g.y&&(e.yDirection=this.clampDir(g.y));var h={dx:f.x,dy:f.y,ddx:g.x,ddy:g.y,clientX:c.clientX,clientY:c.clientY,pageX:c.pageX,pageY:c.pageY,screenX:c.screenX,screenY:c.screenY,xDirection:e.xDirection,yDirection:e.yDirection,trackInfo:e.trackInfo,relatedTarget:c.target,pointerType:c.pointerType},i=b.makeEvent(a,h);e.lastMoveEvent=c,b.dispatchEvent(i,e.downTarget)},pointerdown:function(a){if(a.isPrimary&&("mouse"===a.pointerType?1===a.buttons:!0)){var b={downEvent:a,downTarget:a.target,trackInfo:{},lastMoveEvent:null,xDirection:0,yDirection:0,tracking:!1};c.set(a.pointerId,b)}},pointermove:function(a){var b=c.get(a.pointerId);if(b)if(b.tracking)this.fireTrack("track",a,b);else{var d=this.calcPositionDelta(b.downEvent,a),e=d.x*d.x+d.y*d.y;e>this.WIGGLE_THRESHOLD&&(b.tracking=!0,this.fireTrack("trackstart",b.downEvent,b),this.fireTrack("track",a,b))}},pointerup:function(a){var b=c.get(a.pointerId);b&&(b.tracking&&this.fireTrack("trackend",a,b),c.delete(a.pointerId))},pointercancel:function(a){this.pointerup(a)}};b.registerRecognizer("track",d)}(window.PointerGestures),function(a){var b=a.dispatcher,c={MIN_VELOCITY:.5,MAX_QUEUE:4,moveQueue:[],target:null,pointerId:null,events:["pointerdown","pointermove","pointerup","pointercancel"],pointerdown:function(a){a.isPrimary&&!this.pointerId&&(this.pointerId=a.pointerId,this.target=a.target,this.addMove(a))},pointermove:function(a){a.pointerId===this.pointerId&&this.addMove(a)},pointerup:function(a){a.pointerId===this.pointerId&&this.fireFlick(a),this.cleanup()},pointercancel:function(){this.cleanup()},cleanup:function(){this.moveQueue=[],this.target=null,this.pointerId=null},addMove:function(a){this.moveQueue.length>=this.MAX_QUEUE&&this.moveQueue.shift(),this.moveQueue.push(a)},fireFlick:function(a){for(var c,d,e,f,g,h,i,j=a,k=this.moveQueue.length,l=0,m=0,n=0,o=0;k>o&&(i=this.moveQueue[o]);o++)c=j.timeStamp-i.timeStamp,d=j.clientX-i.clientX,e=j.clientY-i.clientY,f=d/c,g=e/c,h=Math.sqrt(f*f+g*g),h>n&&(l=f,m=g,n=h);var p=Math.abs(l)>Math.abs(m)?"x":"y",q=this.calcAngle(l,m);if(Math.abs(n)>=this.MIN_VELOCITY){var r=b.makeEvent("flick",{xVelocity:l,yVelocity:m,velocity:n,angle:q,majorAxis:p,pointerType:a.pointerType});b.dispatchEvent(r,this.target)}},calcAngle:function(a,b){return 180*Math.atan2(b,a)/Math.PI}};b.registerRecognizer("flick",c)}(window.PointerGestures),function(a){var b=a.dispatcher,c=new a.PointerMap,d=180/Math.PI,e={events:["pointerdown","pointermove","pointerup","pointercancel"],reference:{},pointerdown:function(b){if(c.set(b.pointerId,b),2==c.pointers()){var d=this.calcChord(),e=this.calcAngle(d);this.reference={angle:e,diameter:d.diameter,target:a.findLCA(d.a.target,d.b.target)}}},pointerup:function(a){c.delete(a.pointerId)},pointermove:function(a){c.has(a.pointerId)&&(c.set(a.pointerId,a),c.pointers()>1&&this.calcPinchRotate())},pointercancel:function(a){this.pointerup(a)},dispatchPinch:function(a,c){var d=a/this.reference.diameter,e=b.makeEvent("pinch",{scale:d,centerX:c.center.x,centerY:c.center.y});b.dispatchEvent(e,this.reference.target)},dispatchRotate:function(a,c){var d=Math.round((a-this.reference.angle)%360),e=b.makeEvent("rotate",{angle:d,centerX:c.center.x,centerY:c.center.y});b.dispatchEvent(e,this.reference.target)},calcPinchRotate:function(){var a=this.calcChord(),b=a.diameter,c=this.calcAngle(a);b!=this.reference.diameter&&this.dispatchPinch(b,a),c!=this.reference.angle&&this.dispatchRotate(c,a)},calcChord:function(){var a=[];c.forEach(function(b){a.push(b)});for(var b,d,e,f=0,g={a:a[0],b:a[1]},h=0;h<a.length;h++)for(var i=a[h],j=h+1;j<a.length;j++){var k=a[j];b=Math.abs(i.clientX-k.clientX),d=Math.abs(i.clientY-k.clientY),e=b+d,e>f&&(f=e,g={a:i,b:k})}return b=Math.abs(g.a.clientX+g.b.clientX)/2,d=Math.abs(g.a.clientY+g.b.clientY)/2,g.center={x:b,y:d},g.diameter=f,g},calcAngle:function(a){var b=a.a.clientX-a.b.clientX,c=a.a.clientY-a.b.clientY;return(360+Math.atan2(c,b)*d)%360}};b.registerRecognizer("pinch",e)}(window.PointerGestures),function(a){var b=a.dispatcher,c=new a.PointerMap,d={events:["pointerdown","pointermove","pointerup","pointercancel","keyup"],pointerdown:function(a){a.isPrimary&&!a.tapPrevented&&c.set(a.pointerId,{target:a.target,buttons:a.buttons,x:a.clientX,y:a.clientY})},pointermove:function(a){if(a.isPrimary){var b=c.get(a.pointerId);b&&a.tapPrevented&&c.delete(a.pointerId)}},shouldTap:function(a,b){return a.tapPrevented?void 0:"mouse"===a.pointerType?1===b.buttons:!0},pointerup:function(d){var e=c.get(d.pointerId);if(e&&this.shouldTap(d,e)){var f=a.findLCA(e.target,d.target);if(f){var g=b.makeEvent("tap",{x:d.clientX,y:d.clientY,detail:d.detail,pointerType:d.pointerType});b.dispatchEvent(g,f)}}c.delete(d.pointerId)},pointercancel:function(a){c.delete(a.pointerId)},keyup:function(a){var c=a.keyCode;if(32===c){var d=a.target;d instanceof HTMLInputElement||d instanceof HTMLTextAreaElement||b.dispatchEvent(b.makeEvent("tap",{x:0,y:0,detail:0,pointerType:"unavailable"}),d)}},preventTap:function(a){c.delete(a)}};b.registerRecognizer("tap",d)}(window.PointerGestures),function(a){function b(){c.immediateRegister=!0;var b=c.registerQueue;b.forEach(a.register),b.length=0}var c=a.dispatcher;"complete"===document.readyState?b():document.addEventListener("readystatechange",function(){"complete"===document.readyState&&b()})}(window.PointerGestures),function(){"use strict";function a(a){for(;a.parentNode;)a=a.parentNode;return"function"==typeof a.getElementById?a:null}function b(a,b){var c=a.bindings;if(!c)return void(a.bindings={});var d=c[b];d&&(d.close(),c[b]=void 0)}function c(a){return null==a?"":a}function d(a,b){a.data=c(b)}function e(a){return function(b){return d(a,b)}}function f(a,b,d,e){return d?void(e?a.setAttribute(b,""):a.removeAttribute(b)):void a.setAttribute(b,c(e))}function g(a,b,c){return function(d){f(a,b,c,d)}}function h(a){switch(a.type){case"checkbox":return s;case"radio":case"select-multiple":case"select-one":return"change";case"range":if(/Trident|MSIE/.test(navigator.userAgent))return"change";default:return"input"}}function i(a,b,d,e){a[b]=(e||c)(d)}function j(a,b,c){return function(d){return i(a,b,d,c)}}function k(){}function l(a,b,c,d){function e(){c.setValue(a[b]),c.discardChanges(),(d||k)(a),Platform.performMicrotaskCheckpoint()}var f=h(a);a.addEventListener(f,e);var g=c.close;c.close=function(){g&&(a.removeEventListener(f,e),c.close=g,c.close(),g=void 0)}}function m(a){return Boolean(a)}function n(b){if(b.form)return r(b.form.elements,function(a){return a!=b&&"INPUT"==a.tagName&&"radio"==a.type&&a.name==b.name});var c=a(b);if(!c)return[];var d=c.querySelectorAll('input[type="radio"][name="'+b.name+'"]');return r(d,function(a){return a!=b&&!a.form})}function o(a){"INPUT"===a.tagName&&"radio"===a.type&&n(a).forEach(function(a){var b=a.bindings.checked;b&&b.setValue(!1)})}function p(a,b){var d,e,f,g=a.parentNode;g instanceof HTMLSelectElement&&g.bindings&&g.bindings.value&&(d=g,e=d.bindings.value,f=d.value),a.value=c(b),d&&d.value!=f&&(e.setValue(d.value),e.discardChanges(),Platform.performMicrotaskCheckpoint())}function q(a){return function(b){p(a,b)}}var r=Array.prototype.filter.call.bind(Array.prototype.filter);Node.prototype.bind=function(a,b){console.error("Unhandled binding to Node: ",this,a,b)},Node.prototype.unbind=function(a){b(this,a)},Node.prototype.unbindAll=function(){if(this.bindings){for(var a=Object.keys(this.bindings),b=0;b<a.length;b++){var c=this.bindings[a[b]];c&&c.close()}this.bindings={}}},Text.prototype.bind=function(a,c,f){return"textContent"!==a?Node.prototype.bind.call(this,a,c,f):f?d(this,c):(b(this,"textContent"),d(this,c.open(e(this))),this.bindings.textContent=c)},Element.prototype.bind=function(a,c,d){var e="?"==a[a.length-1];return e&&(this.removeAttribute(a),a=a.slice(0,-1)),d?f(this,a,e,c):(b(this,a),f(this,a,e,c.open(g(this,a,e))),this.bindings[a]=c)};var s;!function(){var a=document.createElement("div"),b=a.appendChild(document.createElement("input"));b.setAttribute("type","checkbox");var c,d=0;b.addEventListener("click",function(){d++,c=c||"click"}),b.addEventListener("change",function(){d++,c=c||"change"});var e=document.createEvent("MouseEvent");e.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),b.dispatchEvent(e),s=1==d?"change":c}(),HTMLInputElement.prototype.bind=function(a,d,e){if("value"!==a&&"checked"!==a)return HTMLElement.prototype.bind.call(this,a,d,e);this.removeAttribute(a);var f="checked"==a?m:c,g="checked"==a?o:k;return e?i(this,a,d,f):(b(this,a),l(this,a,d,g),i(this,a,d.open(j(this,a,f)),f),this.bindings[a]=d)},HTMLTextAreaElement.prototype.bind=function(a,d,e){return"value"!==a?HTMLElement.prototype.bind.call(this,a,d,e):(this.removeAttribute("value"),e?i(this,"value",d):(b(this,"value"),l(this,"value",d),i(this,"value",d.open(j(this,"value",c))),this.bindings.value=d))},HTMLOptionElement.prototype.bind=function(a,c,d){return"value"!==a?HTMLElement.prototype.bind.call(this,a,c,d):(this.removeAttribute("value"),d?p(this,c):(b(this,"value"),l(this,"value",c),p(this,c.open(q(this))),this.bindings.value=c))},HTMLSelectElement.prototype.bind=function(a,c,d){return"selectedindex"===a&&(a="selectedIndex"),"selectedIndex"!==a&&"value"!==a?HTMLElement.prototype.bind.call(this,a,c,d):(this.removeAttribute(a),d?i(this,a,c):(b(this,a),l(this,a,c),i(this,a,c.open(j(this,a))),this.bindings[a]=c))}}(this),function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a){for(var b;b=a.parentNode;)a=b;return a}function d(a,b){if(b){for(var d,e="#"+b;!d&&(a=c(a),a.protoContent_?d=a.protoContent_.querySelector(e):a.getElementById&&(d=a.getElementById(b)),!d&&a.templateCreator_);)a=a.templateCreator_;return d}}function e(a){return"template"==a.tagName&&"http://www.w3.org/2000/svg"==a.namespaceURI}function f(a){return"TEMPLATE"==a.tagName&&"http://www.w3.org/1999/xhtml"==a.namespaceURI}function g(a){return Boolean(J[a.tagName]&&a.hasAttribute("template"))}function h(a){return void 0===a.isTemplate_&&(a.isTemplate_="TEMPLATE"==a.tagName||g(a)),a.isTemplate_}function i(a,b){var c=a.querySelectorAll(L);h(a)&&b(a),E(c,b)}function j(a){function b(a){HTMLTemplateElement.decorate(a)||j(a.content)}i(a,b)}function k(a,b){Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))})}function l(a){var b=a.ownerDocument;if(!b.defaultView)return b;var c=b.templateContentsOwner_;if(!c){for(c=b.implementation.createHTMLDocument("");c.lastChild;)c.removeChild(c.lastChild);b.templateContentsOwner_=c}return c}function m(a){if(!a.stagingDocument_){var b=a.ownerDocument;if(!b.stagingDocument_){b.stagingDocument_=b.implementation.createHTMLDocument("");var c=b.stagingDocument_.createElement("base");c.href=document.baseURI,b.stagingDocument_.head.appendChild(c),b.stagingDocument_.stagingDocument_=b.stagingDocument_}a.stagingDocument_=b.stagingDocument_}return a.stagingDocument_}function n(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];I[e.name]&&("template"!==e.name&&b.setAttribute(e.name,e.value),a.removeAttribute(e.name))}return b}function o(a){var b=a.ownerDocument.createElement("template");a.parentNode.insertBefore(b,a);for(var c=a.attributes,d=c.length;d-->0;){var e=c[d];b.setAttribute(e.name,e.value),a.removeAttribute(e.name)
-}return a.parentNode.removeChild(a),b}function p(a,b,c){var d=a.content;if(c)return void d.appendChild(b);for(var e;e=b.firstChild;)d.appendChild(e)}function q(a){N?a.__proto__=HTMLTemplateElement.prototype:k(a,HTMLTemplateElement.prototype)}function r(a){a.setModelFn_||(a.setModelFn_=function(){a.setModelFnScheduled_=!1;var b=z(a,a.delegate_&&a.delegate_.prepareBinding);w(a,b,a.model_)}),a.setModelFnScheduled_||(a.setModelFnScheduled_=!0,Observer.runEOM_(a.setModelFn_))}function s(a,b,c,d){if(a&&a.length){for(var e,f=a.length,g=0,h=0,i=0,j=!0;f>h;){var g=a.indexOf("{{",h),k=a.indexOf("[[",h),l=!1,m="}}";if(k>=0&&(0>g||g>k)&&(g=k,l=!0,m="]]"),i=0>g?-1:a.indexOf(m,g+2),0>i){if(!e)return;e.push(a.slice(h));break}e=e||[],e.push(a.slice(h,g));var n=a.slice(g+2,i).trim();e.push(l),j=j&&l,e.push(Path.get(n));var o=d&&d(n,b,c);e.push(o),h=i+2}return h===f&&e.push(""),e.hasOnePath=5===e.length,e.isSimplePath=e.hasOnePath&&""==e[0]&&""==e[4],e.onlyOneTime=j,e.combinator=function(a){for(var b=e[0],c=1;c<e.length;c+=4){var d=e.hasOnePath?a:a[(c-1)/4];void 0!==d&&(b+=d),b+=e[c+3]}return b},e}}function t(a,b,c,d){if(b.hasOnePath){var e=b[3],f=e?e(d,c,!0):b[2].getValueFrom(d);return b.isSimplePath?f:b.combinator(f)}for(var g=[],h=1;h<b.length;h+=4){var e=b[h+2];g[(h-1)/4]=e?e(d,c):b[h+1].getValueFrom(d)}return b.combinator(g)}function u(a,b,c,d){var e=b[3],f=e?e(d,c,!1):new PathObserver(d,b[2]);return b.isSimplePath?f:new ObserverTransform(f,b.combinator)}function v(a,b,c,d){if(b.onlyOneTime)return t(a,b,c,d);if(b.hasOnePath)return u(a,b,c,d);for(var e=new CompoundObserver,f=1;f<b.length;f+=4){var g=b[f],h=b[f+2];if(h){var i=h(d,c,g);g?e.addPath(i):e.addObserver(i)}else{var j=b[f+1];g?e.addPath(j.getValueFrom(d)):e.addPath(d,j)}}return new ObserverTransform(e,b.combinator)}function w(a,b,c,d){for(var e=0;e<b.length;e+=2){var f=b[e],g=b[e+1],h=v(f,g,a,c),i=a.bind(f,h,g.onlyOneTime);i&&d&&d.push(i)}if(b.isTemplate){a.model_=c;var j=a.processBindingDirectives_(b);d&&j&&d.push(j)}}function x(a,b,c){var d=a.getAttribute(b);return s(""==d?"{{}}":d,b,a,c)}function y(a,c){b(a);for(var d=[],e=0;e<a.attributes.length;e++){for(var f=a.attributes[e],g=f.name,i=f.value;"_"===g[0];)g=g.substring(1);if(!h(a)||g!==H&&g!==F&&g!==G){var j=s(i,g,a,c);j&&d.push(g,j)}}return h(a)&&(d.isTemplate=!0,d.if=x(a,H,c),d.bind=x(a,F,c),d.repeat=x(a,G,c),!d.if||d.bind||d.repeat||(d.bind=s("{{}}",F,a,c))),d}function z(a,b){if(a.nodeType===Node.ELEMENT_NODE)return y(a,b);if(a.nodeType===Node.TEXT_NODE){var c=s(a.data,"textContent",a,b);if(c)return["textContent",c]}return[]}function A(a,b,c,d,e,f,g){for(var h=b.appendChild(c.importNode(a,!1)),i=0,j=a.firstChild;j;j=j.nextSibling)A(j,h,c,d.children[i++],e,f,g);return d.isTemplate&&(HTMLTemplateElement.decorate(h,a),f&&h.setDelegate_(f)),w(h,d,e,g),h}function B(a,b){var c=z(a,b);c.children={};for(var d=0,e=a.firstChild;e;e=e.nextSibling)c.children[d++]=B(e,b);return c}function C(a){this.closed=!1,this.templateElement_=a,this.terminators=[],this.deps=void 0,this.iteratedValue=[],this.presentValue=void 0,this.arrayObserver=void 0}var D,E=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.Map&&"function"==typeof a.Map.prototype.forEach?D=a.Map:(D=function(){this.keys=[],this.values=[]},D.prototype={set:function(a,b){var c=this.keys.indexOf(a);0>c?(this.keys.push(a),this.values.push(b)):this.values[c]=b},get:function(a){var b=this.keys.indexOf(a);if(!(0>b))return this.values[b]},"delete":function(a){var b=this.keys.indexOf(a);return 0>b?!1:(this.keys.splice(b,1),this.values.splice(b,1),!0)},forEach:function(a,b){for(var c=0;c<this.keys.length;c++)a.call(b||this,this.values[c],this.keys[c],this)}});"function"!=typeof document.contains&&(Document.prototype.contains=function(a){return a===this||a.parentNode===this?!0:this.documentElement.contains(a)});var F="bind",G="repeat",H="if",I={template:!0,repeat:!0,bind:!0,ref:!0},J={THEAD:!0,TBODY:!0,TFOOT:!0,TH:!0,TR:!0,TD:!0,COLGROUP:!0,COL:!0,CAPTION:!0,OPTION:!0,OPTGROUP:!0},K="undefined"!=typeof HTMLTemplateElement;K&&!function(){var a=document.createElement("template"),b=a.content.ownerDocument,c=b.appendChild(b.createElement("html")),d=c.appendChild(b.createElement("head")),e=b.createElement("base");e.href=document.baseURI,d.appendChild(e)}();var L="template, "+Object.keys(J).map(function(a){return a.toLowerCase()+"[template]"}).join(", ");document.addEventListener("DOMContentLoaded",function(){j(document),Platform.performMicrotaskCheckpoint()},!1),K||(a.HTMLTemplateElement=function(){throw TypeError("Illegal constructor")});var M,N="__proto__"in{};"function"==typeof MutationObserver&&(M=new MutationObserver(function(a){for(var b=0;b<a.length;b++)a[b].target.refChanged_()})),HTMLTemplateElement.decorate=function(a,c){if(a.templateIsDecorated_)return!1;var d=a;d.templateIsDecorated_=!0;var h=f(d)&&K,i=h,k=!h,m=!1;if(h||(g(d)?(b(!c),d=n(a),d.templateIsDecorated_=!0,h=K,m=!0):e(d)&&(d=o(a),d.templateIsDecorated_=!0,h=K)),!h){q(d);var r=l(d);d.content_=r.createDocumentFragment()}return c?d.instanceRef_=c:k?p(d,a,m):i&&j(d.content),!0},HTMLTemplateElement.bootstrap=j;var O=a.HTMLUnknownElement||HTMLElement,P={get:function(){return this.content_},enumerable:!0,configurable:!0};K||(HTMLTemplateElement.prototype=Object.create(O.prototype),Object.defineProperty(HTMLTemplateElement.prototype,"content",P)),k(HTMLTemplateElement.prototype,{bind:function(a,b,c){if("ref"!=a)return Element.prototype.bind.call(this,a,b,c);var d=this,e=c?b:b.open(function(a){d.setAttribute("ref",a),d.refChanged_()});return this.setAttribute("ref",e),this.refChanged_(),c?void 0:(this.unbind("ref"),this.bindings.ref=b)},processBindingDirectives_:function(a){return this.iterator_&&this.iterator_.closeDeps(),a.if||a.bind||a.repeat?(this.iterator_||(this.iterator_=new C(this),this.bindings=this.bindings||{},this.bindings.iterator=this.iterator_),this.iterator_.updateDependencies(a,this.model_),M&&M.observe(this,{attributes:!0,attributeFilter:["ref"]}),this.iterator_):void(this.iterator_&&(this.iterator_.close(),this.iterator_=void 0,this.bindings.iterator=void 0))},createInstance:function(a,b,c,d){b&&(c=this.newDelegate_(b)),this.refContent_||(this.refContent_=this.ref_.content);var e=this.refContent_,f=this.bindingMap_;f&&f.content===e||(f=B(e,c&&c.prepareBinding)||[],f.content=e,this.bindingMap_=f);var g=m(this),h=g.createDocumentFragment();h.templateCreator_=this,h.protoContent_=e;for(var i={firstNode:null,lastNode:null,model:a},j=0,k=e.firstChild;k;k=k.nextSibling){var l=A(k,h,g,f.children[j++],a,c,d);l.templateInstance_=i}return i.firstNode=h.firstChild,i.lastNode=h.lastChild,h.templateCreator_=void 0,h.protoContent_=void 0,h},get model(){return this.model_},set model(a){this.model_=a,r(this)},get bindingDelegate(){return this.delegate_&&this.delegate_.raw},refChanged_:function(){this.iterator_&&this.refContent_!==this.ref_.content&&(this.refContent_=void 0,this.iterator_.valueChanged(),this.iterator_.updateIteratedValue())},clear:function(){this.model_=void 0,this.delegate_=void 0,this.bindings_=void 0,this.refContent_=void 0,this.iterator_&&(this.iterator_.valueChanged(),this.iterator_.close(),this.iterator_=void 0)},setDelegate_:function(a){this.delegate_=a,this.bindingMap_=void 0,this.iterator_&&(this.iterator_.instancePositionChangedFn_=void 0,this.iterator_.instanceModelFn_=void 0)},newDelegate_:function(a){function b(b){var c=a&&a[b];if("function"==typeof c)return function(){return c.apply(a,arguments)}}return a?{raw:a,prepareBinding:b("prepareBinding"),prepareInstanceModel:b("prepareInstanceModel"),prepareInstancePositionChanged:b("prepareInstancePositionChanged")}:{}},set bindingDelegate(a){if(this.delegate_)throw Error("Template must be cleared before a new bindingDelegate can be assigned");this.setDelegate_(this.newDelegate_(a))},get ref_(){var a=d(this,this.getAttribute("ref"));if(a||(a=this.instanceRef_),!a)return this;var b=a.ref_;return b?b:a}}),Object.defineProperty(Node.prototype,"templateInstance",{get:function(){var a=this.templateInstance_;return a?a:this.parentNode?this.parentNode.templateInstance:void 0}}),C.prototype={closeDeps:function(){var a=this.deps;a&&(a.ifOneTime===!1&&a.ifValue.close(),a.oneTime===!1&&a.value.close())},updateDependencies:function(a,b){this.closeDeps();var c=this.deps={},d=this.templateElement_;if(a.if){if(c.hasIf=!0,c.ifOneTime=a.if.onlyOneTime,c.ifValue=v(H,a.if,d,b),c.ifOneTime&&!c.ifValue)return void this.updateIteratedValue();c.ifOneTime||c.ifValue.open(this.updateIteratedValue,this)}a.repeat?(c.repeat=!0,c.oneTime=a.repeat.onlyOneTime,c.value=v(G,a.repeat,d,b)):(c.repeat=!1,c.oneTime=a.bind.onlyOneTime,c.value=v(F,a.bind,d,b)),c.oneTime||c.value.open(this.updateIteratedValue,this),this.updateIteratedValue()},updateIteratedValue:function(){if(this.deps.hasIf){var a=this.deps.ifValue;if(this.deps.ifOneTime||(a=a.discardChanges()),!a)return void this.valueChanged()}var b=this.deps.value;this.deps.oneTime||(b=b.discardChanges()),this.deps.repeat||(b=[b]);var c=this.deps.repeat&&!this.deps.oneTime&&Array.isArray(b);this.valueChanged(b,c)},valueChanged:function(a,b){Array.isArray(a)||(a=[]),a!==this.iteratedValue&&(this.unobserve(),this.presentValue=a,b&&(this.arrayObserver=new ArrayObserver(this.presentValue),this.arrayObserver.open(this.handleSplices,this)),this.handleSplices(ArrayObserver.calculateSplices(this.presentValue,this.iteratedValue)))},getTerminatorAt:function(a){if(-1==a)return this.templateElement_;var b=this.terminators[2*a];if(b.nodeType!==Node.ELEMENT_NODE||this.templateElement_===b)return b;var c=b.iterator_;return c?c.getTerminatorAt(c.terminators.length/2-1):b},insertInstanceAt:function(a,b,c,d){var e=this.getTerminatorAt(a-1),f=e;b?f=b.lastChild||f:c&&(f=c[c.length-1]||f),this.terminators.splice(2*a,0,f,d);var g=this.templateElement_.parentNode,h=e.nextSibling;if(b)g.insertBefore(b,h);else if(c)for(var i=0;i<c.length;i++)g.insertBefore(c[i],h)},extractInstanceAt:function(a){var b=[],c=this.getTerminatorAt(a-1),d=this.getTerminatorAt(a);b.instanceBindings=this.terminators[2*a+1],this.terminators.splice(2*a,2);for(var e=this.templateElement_.parentNode;d!==c;){var f=c.nextSibling;f==d&&(d=c),e.removeChild(f),b.push(f)}return b},getDelegateFn:function(a){return a=a&&a(this.templateElement_),"function"==typeof a?a:null},handleSplices:function(a){if(!this.closed&&a.length){var b=this.templateElement_;if(!b.parentNode)return void this.close();ArrayObserver.applySplices(this.iteratedValue,this.presentValue,a);var c=b.delegate_;void 0===this.instanceModelFn_&&(this.instanceModelFn_=this.getDelegateFn(c&&c.prepareInstanceModel)),void 0===this.instancePositionChangedFn_&&(this.instancePositionChangedFn_=this.getDelegateFn(c&&c.prepareInstancePositionChanged));var d=new D,e=0;a.forEach(function(a){a.removed.forEach(function(b){var c=this.extractInstanceAt(a.index+e);d.set(b,c)},this),e-=a.addedCount},this),a.forEach(function(a){for(var e=a.index;e<a.index+a.addedCount;e++){var f,g=this.iteratedValue[e],h=void 0,i=d.get(g);i?(d.delete(g),f=i.instanceBindings):(f=[],this.instanceModelFn_&&(g=this.instanceModelFn_(g)),void 0!==g&&(h=b.createInstance(g,void 0,c,f))),this.insertInstanceAt(e,h,i,f)}},this),d.forEach(function(a){this.closeInstanceBindings(a.instanceBindings)},this),this.instancePositionChangedFn_&&this.reportInstancesMoved(a)}},reportInstanceMoved:function(a){var b=this.getTerminatorAt(a-1),c=this.getTerminatorAt(a);if(b!==c){var d=b.nextSibling.templateInstance;this.instancePositionChangedFn_(d,a)}},reportInstancesMoved:function(a){for(var b=0,c=0,d=0;d<a.length;d++){var e=a[d];if(0!=c)for(;b<e.index;)this.reportInstanceMoved(b),b++;else b=e.index;for(;b<e.index+e.addedCount;)this.reportInstanceMoved(b),b++;c+=e.addedCount-e.removed.length}if(0!=c)for(var f=this.terminators.length/2;f>b;)this.reportInstanceMoved(b),b++},closeInstanceBindings:function(a){for(var b=0;b<a.length;b++)a[b].close()},unobserve:function(){this.arrayObserver&&(this.arrayObserver.close(),this.arrayObserver=void 0)},close:function(){if(!this.closed){this.unobserve();for(var a=1;a<this.terminators.length;a+=2)this.closeInstanceBindings(this.terminators[a]);this.terminators.length=0,this.closeDeps(),this.templateElement_.iterator_=void 0,this.closed=!0}}},HTMLTemplateElement.forAllTemplatesFrom_=i}(this),function(a){"use strict";function b(a,b){if(!a)throw new Error("ASSERT: "+b)}function c(a){return a>=48&&57>=a}function d(a){return 32===a||9===a||11===a||12===a||160===a||a>=5760&&" ᠎              ".indexOf(String.fromCharCode(a))>0}function e(a){return 10===a||13===a||8232===a||8233===a}function f(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a}function g(a){return 36===a||95===a||a>=65&&90>=a||a>=97&&122>=a||a>=48&&57>=a}function h(a){return"this"===a}function i(){for(;Y>X&&d(W.charCodeAt(X));)++X}function j(){var a,b;for(a=X++;Y>X&&(b=W.charCodeAt(X),g(b));)++X;return W.slice(a,X)}function k(){var a,b,c;return a=X,b=j(),c=1===b.length?S.Identifier:h(b)?S.Keyword:"null"===b?S.NullLiteral:"true"===b||"false"===b?S.BooleanLiteral:S.Identifier,{type:c,value:b,range:[a,X]}}function l(){var a,b,c=X,d=W.charCodeAt(X),e=W[X];switch(d){case 46:case 40:case 41:case 59:case 44:case 123:case 125:case 91:case 93:case 58:case 63:return++X,{type:S.Punctuator,value:String.fromCharCode(d),range:[c,X]};default:if(a=W.charCodeAt(X+1),61===a)switch(d){case 37:case 38:case 42:case 43:case 45:case 47:case 60:case 62:case 124:return X+=2,{type:S.Punctuator,value:String.fromCharCode(d)+String.fromCharCode(a),range:[c,X]};case 33:case 61:return X+=2,61===W.charCodeAt(X)&&++X,{type:S.Punctuator,value:W.slice(c,X),range:[c,X]}}}return b=W[X+1],e===b&&"&|".indexOf(e)>=0?(X+=2,{type:S.Punctuator,value:e+b,range:[c,X]}):"<>=!+-*%&|^/".indexOf(e)>=0?(++X,{type:S.Punctuator,value:e,range:[c,X]}):void s({},V.UnexpectedToken,"ILLEGAL")}function m(){var a,d,e;if(e=W[X],b(c(e.charCodeAt(0))||"."===e,"Numeric literal must start with a decimal digit or a decimal point"),d=X,a="","."!==e){for(a=W[X++],e=W[X],"0"===a&&e&&c(e.charCodeAt(0))&&s({},V.UnexpectedToken,"ILLEGAL");c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("."===e){for(a+=W[X++];c(W.charCodeAt(X));)a+=W[X++];e=W[X]}if("e"===e||"E"===e)if(a+=W[X++],e=W[X],("+"===e||"-"===e)&&(a+=W[X++]),c(W.charCodeAt(X)))for(;c(W.charCodeAt(X));)a+=W[X++];else s({},V.UnexpectedToken,"ILLEGAL");return f(W.charCodeAt(X))&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.NumericLiteral,value:parseFloat(a),range:[d,X]}}function n(){var a,c,d,f="",g=!1;for(a=W[X],b("'"===a||'"'===a,"String literal must starts with a quote"),c=X,++X;Y>X;){if(d=W[X++],d===a){a="";break}if("\\"===d)if(d=W[X++],d&&e(d.charCodeAt(0)))"\r"===d&&"\n"===W[X]&&++X;else switch(d){case"n":f+="\n";break;case"r":f+="\r";break;case"t":f+="	";break;case"b":f+="\b";break;case"f":f+="\f";break;case"v":f+="";break;default:f+=d}else{if(e(d.charCodeAt(0)))break;f+=d}}return""!==a&&s({},V.UnexpectedToken,"ILLEGAL"),{type:S.StringLiteral,value:f,octal:g,range:[c,X]}}function o(a){return a.type===S.Identifier||a.type===S.Keyword||a.type===S.BooleanLiteral||a.type===S.NullLiteral}function p(){var a;return i(),X>=Y?{type:S.EOF,range:[X,X]}:(a=W.charCodeAt(X),40===a||41===a||58===a?l():39===a||34===a?n():f(a)?k():46===a?c(W.charCodeAt(X+1))?m():l():c(a)?m():l())}function q(){var a;return a=$,X=a.range[1],$=p(),X=a.range[1],a}function r(){var a;a=X,$=p(),X=a}function s(a,c){var d,e=Array.prototype.slice.call(arguments,2),f=c.replace(/%(\d)/g,function(a,c){return b(c<e.length,"Message reference must be in range"),e[c]});throw d=new Error(f),d.index=X,d.description=f,d}function t(a){s(a,V.UnexpectedToken,a.value)}function u(a){var b=q();(b.type!==S.Punctuator||b.value!==a)&&t(b)}function v(a){return $.type===S.Punctuator&&$.value===a}function w(a){return $.type===S.Keyword&&$.value===a}function x(){var a=[];for(u("[");!v("]");)v(",")?(q(),a.push(null)):(a.push(bb()),v("]")||u(","));return u("]"),Z.createArrayExpression(a)}function y(){var a;return i(),a=q(),a.type===S.StringLiteral||a.type===S.NumericLiteral?Z.createLiteral(a):Z.createIdentifier(a.value)}function z(){var a,b;return a=$,i(),(a.type===S.EOF||a.type===S.Punctuator)&&t(a),b=y(),u(":"),Z.createProperty("init",b,bb())}function A(){var a=[];for(u("{");!v("}");)a.push(z()),v("}")||u(",");return u("}"),Z.createObjectExpression(a)}function B(){var a;return u("("),a=bb(),u(")"),a}function C(){var a,b,c;return v("(")?B():(a=$.type,a===S.Identifier?c=Z.createIdentifier(q().value):a===S.StringLiteral||a===S.NumericLiteral?c=Z.createLiteral(q()):a===S.Keyword?w("this")&&(q(),c=Z.createThisExpression()):a===S.BooleanLiteral?(b=q(),b.value="true"===b.value,c=Z.createLiteral(b)):a===S.NullLiteral?(b=q(),b.value=null,c=Z.createLiteral(b)):v("[")?c=x():v("{")&&(c=A()),c?c:void t(q()))}function D(){var a=[];if(u("("),!v(")"))for(;Y>X&&(a.push(bb()),!v(")"));)u(",");return u(")"),a}function E(){var a;return a=q(),o(a)||t(a),Z.createIdentifier(a.value)}function F(){return u("."),E()}function G(){var a;return u("["),a=bb(),u("]"),a}function H(){var a,b;for(a=C();v(".")||v("[");)v("[")?(b=G(),a=Z.createMemberExpression("[",a,b)):(b=F(),a=Z.createMemberExpression(".",a,b));return a}function I(){var a,b;return $.type!==S.Punctuator&&$.type!==S.Keyword?b=ab():v("+")||v("-")||v("!")?(a=q(),b=I(),b=Z.createUnaryExpression(a.value,b)):w("delete")||w("void")||w("typeof")?s({},V.UnexpectedToken):b=ab(),b}function J(a){var b=0;if(a.type!==S.Punctuator&&a.type!==S.Keyword)return 0;switch(a.value){case"||":b=1;break;case"&&":b=2;break;case"==":case"!=":case"===":case"!==":b=6;break;case"<":case">":case"<=":case">=":case"instanceof":b=7;break;case"in":b=7;break;case"+":case"-":b=9;break;case"*":case"/":case"%":b=11}return b}function K(){var a,b,c,d,e,f,g,h;if(g=I(),b=$,c=J(b),0===c)return g;for(b.prec=c,q(),e=I(),d=[g,b,e];(c=J($))>0;){for(;d.length>2&&c<=d[d.length-2].prec;)e=d.pop(),f=d.pop().value,g=d.pop(),a=Z.createBinaryExpression(f,g,e),d.push(a);b=q(),b.prec=c,d.push(b),a=I(),d.push(a)}for(h=d.length-1,a=d[h];h>1;)a=Z.createBinaryExpression(d[h-1].value,d[h-2],a),h-=2;return a}function L(){var a,b,c;return a=K(),v("?")&&(q(),b=L(),u(":"),c=L(),a=Z.createConditionalExpression(a,b,c)),a}function M(){var a,b;return a=q(),a.type!==S.Identifier&&t(a),b=v("(")?D():[],Z.createFilter(a.value,b)}function N(){for(;v("|");)q(),M()}function O(){i(),r();var a=bb();a&&(","===$.value||"in"==$.value&&a.type===U.Identifier?Q(a):(N(),"as"===$.value?P(a):Z.createTopLevel(a))),$.type!==S.EOF&&t($)}function P(a){q();var b=q().value;Z.createAsExpression(a,b)}function Q(a){var b;","===$.value&&(q(),$.type!==S.Identifier&&t($),b=q().value),q();var c=bb();N(),Z.createInExpression(a.name,b,c)}function R(a,b){return Z=b,W=a,X=0,Y=W.length,$=null,_={labelSet:{}},O()}var S,T,U,V,W,X,Y,Z,$,_;S={BooleanLiteral:1,EOF:2,Identifier:3,Keyword:4,NullLiteral:5,NumericLiteral:6,Punctuator:7,StringLiteral:8},T={},T[S.BooleanLiteral]="Boolean",T[S.EOF]="<end>",T[S.Identifier]="Identifier",T[S.Keyword]="Keyword",T[S.NullLiteral]="Null",T[S.NumericLiteral]="Numeric",T[S.Punctuator]="Punctuator",T[S.StringLiteral]="String",U={ArrayExpression:"ArrayExpression",BinaryExpression:"BinaryExpression",CallExpression:"CallExpression",ConditionalExpression:"ConditionalExpression",EmptyStatement:"EmptyStatement",ExpressionStatement:"ExpressionStatement",Identifier:"Identifier",Literal:"Literal",LabeledStatement:"LabeledStatement",LogicalExpression:"LogicalExpression",MemberExpression:"MemberExpression",ObjectExpression:"ObjectExpression",Program:"Program",Property:"Property",ThisExpression:"ThisExpression",UnaryExpression:"UnaryExpression"},V={UnexpectedToken:"Unexpected token %0",UnknownLabel:"Undefined label '%0'",Redeclaration:"%0 '%1' has already been declared"};var ab=H,bb=L;a.esprima={parse:R}}(this),function(a){"use strict";function b(a,b,d,e){var f;try{if(f=c(a),f.scopeIdent&&(d.nodeType!==Node.ELEMENT_NODE||"TEMPLATE"!==d.tagName||"bind"!==b&&"repeat"!==b))throw Error("as and in can only be used within <template bind/repeat>")}catch(g){return void console.error("Invalid expression syntax: "+a,g)}return function(a,b,c){var d=f.getBinding(a,e,c);return f.scopeIdent&&d&&(b.polymerExpressionScopeIdent_=f.scopeIdent,f.indexIdent&&(b.polymerExpressionIndexIdent_=f.indexIdent)),d}}function c(a){var b=s[a];if(!b){var c=new j;esprima.parse(a,c),b=new l(c),s[a]=b}return b}function d(a){this.value=a,this.valueFn_=void 0}function e(a){this.name=a,this.path=Path.get(a)}function f(a,b,c){"["==c&&b instanceof d&&Path.get(b.value).valid&&(c=".",b=new e(b.value)),this.dynamicDeps="function"==typeof a||a.dynamic,this.dynamic="function"==typeof b||b.dynamic||"["==c,this.simplePath=!this.dynamic&&!this.dynamicDeps&&b instanceof e&&(a instanceof f||a instanceof e),this.object=this.simplePath?a:i(a),this.property="."==c?b:i(b)}function g(a,b){this.name=a,this.args=[];for(var c=0;c<b.length;c++)this.args[c]=i(b[c])}function h(){throw Error("Not Implemented")}function i(a){return"function"==typeof a?a:a.valueFn()}function j(){this.expression=null,this.filters=[],this.deps={},this.currentPath=void 0,this.scopeIdent=void 0,this.indexIdent=void 0,this.dynamicDeps=!1}function k(a){this.value_=a}function l(a){if(this.scopeIdent=a.scopeIdent,this.indexIdent=a.indexIdent,!a.expression)throw Error("No expression found.");this.expression=a.expression,i(this.expression),this.filters=a.filters,this.dynamicDeps=a.dynamicDeps}function m(a){return String(a).replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}function n(a){return"o"===a[0]&&"n"===a[1]&&"-"===a[2]}function o(a,b){for(;a[w]&&!Object.prototype.hasOwnProperty.call(a,b);)a=a[w];return a}function p(a,b){if(0==b.length)return void 0;if(1==b.length)return o(a,b[0]);for(var c=0;null!=a&&c<b.length-1;c++)a=a[b[c]];return a}function q(a,b,c){var d=b.substring(3);return d=v[d]||d,function(b,e,f){function g(){return"{{ "+a+" }}"}var h,i,j;return j="function"==typeof c.resolveEventHandler?function(d){h=h||c.resolveEventHandler(b,a,e),h(d,d.detail,d.currentTarget),Platform&&"function"==typeof Platform.flush&&Platform.flush()}:function(c){h=h||a.getValueFrom(b),i=i||p(b,a,e),h.apply(i,[c,c.detail,c.currentTarget]),Platform&&"function"==typeof Platform.flush&&Platform.flush()},e.addEventListener(d,j),f?void 0:{open:g,discardChanges:g,close:function(){e.removeEventListener(d,j)}}}}function r(){}var s=Object.create(null);d.prototype={valueFn:function(){if(!this.valueFn_){var a=this.value;this.valueFn_=function(){return a}}return this.valueFn_}},e.prototype={valueFn:function(){if(!this.valueFn_){var a=(this.name,this.path);this.valueFn_=function(b,c){return c&&c.addPath(b,a),a.getValueFrom(b)}}return this.valueFn_},setValue:function(a,b){return 1==this.path.length,a=o(a,this.path[0]),this.path.setValueFrom(a,b)}},f.prototype={get fullPath(){if(!this.fullPath_){var a=this.object instanceof e?this.object.name:this.object.fullPath;this.fullPath_=Path.get(a+"."+this.property.name)}return this.fullPath_},valueFn:function(){if(!this.valueFn_){var a=this.object;if(this.simplePath){var b=this.fullPath;this.valueFn_=function(a,c){return c&&c.addPath(a,b),b.getValueFrom(a)}}else if(this.property instanceof e){var b=Path.get(this.property.name);this.valueFn_=function(c,d){var e=a(c,d);return d&&d.addPath(e,b),b.getValueFrom(e)}}else{var c=this.property;this.valueFn_=function(b,d){var e=a(b,d),f=c(b,d);return d&&d.addPath(e,f),e?e[f]:void 0}}}return this.valueFn_},setValue:function(a,b){if(this.simplePath)return this.fullPath.setValueFrom(a,b),b;var c=this.object(a),d=this.property instanceof e?this.property.name:this.property(a);return c[d]=b}},g.prototype={transform:function(a,b,c,d,e){var f=c[this.name],g=d;if(f)g=void 0;else if(f=g[this.name],!f)return void console.error("Cannot find filter: "+this.name);if(b?f=f.toModel:"function"==typeof f.toDOM&&(f=f.toDOM),"function"!=typeof f)return void console.error("No "+(b?"toModel":"toDOM")+" found on"+this.name);for(var h=[a],j=0;j<this.args.length;j++)h[j+1]=i(this.args[j])(d,e);return f.apply(g,h)}};var t={"+":function(a){return+a},"-":function(a){return-a},"!":function(a){return!a}},u={"+":function(a,b){return a+b},"-":function(a,b){return a-b},"*":function(a,b){return a*b},"/":function(a,b){return a/b},"%":function(a,b){return a%b},"<":function(a,b){return b>a},">":function(a,b){return a>b},"<=":function(a,b){return b>=a},">=":function(a,b){return a>=b},"==":function(a,b){return a==b},"!=":function(a,b){return a!=b},"===":function(a,b){return a===b},"!==":function(a,b){return a!==b},"&&":function(a,b){return a&&b},"||":function(a,b){return a||b}};j.prototype={createUnaryExpression:function(a,b){if(!t[a])throw Error("Disallowed operator: "+a);return b=i(b),function(c,d){return t[a](b(c,d))}},createBinaryExpression:function(a,b,c){if(!u[a])throw Error("Disallowed operator: "+a);return b=i(b),c=i(c),function(d,e){return u[a](b(d,e),c(d,e))}},createConditionalExpression:function(a,b,c){return a=i(a),b=i(b),c=i(c),function(d,e){return a(d,e)?b(d,e):c(d,e)}},createIdentifier:function(a){var b=new e(a);return b.type="Identifier",b},createMemberExpression:function(a,b,c){var d=new f(b,c,a);return d.dynamicDeps&&(this.dynamicDeps=!0),d},createLiteral:function(a){return new d(a.value)},createArrayExpression:function(a){for(var b=0;b<a.length;b++)a[b]=i(a[b]);return function(b,c){for(var d=[],e=0;e<a.length;e++)d.push(a[e](b,c));return d}},createProperty:function(a,b,c){return{key:b instanceof e?b.name:b.value,value:c}},createObjectExpression:function(a){for(var b=0;b<a.length;b++)a[b].value=i(a[b].value);return function(b,c){for(var d={},e=0;e<a.length;e++)d[a[e].key]=a[e].value(b,c);return d}},createFilter:function(a,b){this.filters.push(new g(a,b))},createAsExpression:function(a,b){this.expression=a,this.scopeIdent=b},createInExpression:function(a,b,c){this.expression=c,this.scopeIdent=a,this.indexIdent=b},createTopLevel:function(a){this.expression=a},createThisExpression:h},k.prototype={open:function(){return this.value_},discardChanges:function(){return this.value_},deliver:function(){},close:function(){}},l.prototype={getBinding:function(a,b,c){function d(){g.dynamicDeps&&f.startReset();var c=g.getValue(a,g.dynamicDeps?f:void 0,b);return g.dynamicDeps&&f.finishReset(),c}function e(c){return g.setValue(a,c,b),c}if(c)return this.getValue(a,void 0,b);var f=new CompoundObserver;this.getValue(a,f,b);var g=this;return new ObserverTransform(f,d,e,!0)},getValue:function(a,b,c){for(var d=i(this.expression)(a,b),e=0;e<this.filters.length;e++)d=this.filters[e].transform(d,!1,c,a,b);return d},setValue:function(a,b,c){for(var d=this.filters?this.filters.length:0;d-->0;)b=this.filters[d].transform(b,!0,c,a);return this.expression.setValue?this.expression.setValue(a,b):void 0}};var v={};["webkitAnimationStart","webkitAnimationEnd","webkitTransitionEnd","DOMFocusOut","DOMFocusIn","DOMMouseScroll"].forEach(function(a){v[a.toLowerCase()]=a});var w="@"+Math.random().toString(36).slice(2);r.prototype={styleObject:function(a){var b=[];for(var c in a)b.push(m(c)+": "+a[c]);return b.join("; ")},tokenList:function(a){var b=[];for(var c in a)a[c]&&b.push(c);return b.join(" ")},prepareInstancePositionChanged:function(a){var b=a.polymerExpressionIndexIdent_;if(b)return function(a,c){a.model[b]=c}},prepareBinding:function(a,c,d){var e=Path.get(a);if(n(c))return e.valid?q(e,c,this):void console.error("on-* bindings must be simple path expressions");{if(!e.valid)return b(a,c,d,this);if(1==e.length)return function(a,b,c){if(c)return e.getValueFrom(a);var d=o(a,e[0]);return new PathObserver(d,e)}}},prepareInstanceModel:function(a){var b=a.polymerExpressionScopeIdent_;if(b){var c=a.templateInstance?a.templateInstance.model:a.model,d=a.polymerExpressionIndexIdent_;return function(a){var e=Object.create(c);return e[b]=a,e[d]=void 0,e[w]=c,e}}}},a.PolymerExpressions=r,a.exposeGetExpression&&(a.getExpression_=c),a.PolymerExpressions.prepareEventBinding=q}(this),function(a){function b(){e||(e=!0,a.endOfMicrotask(function(){e=!1,logFlags.data&&console.group("Platform.flush()"),a.performMicrotaskCheckpoint(),logFlags.data&&console.groupEnd()}))}var c=document.createElement("style");c.textContent="template {display: none !important;} /* injected by platform.js */";var d=document.querySelector("head");d.insertBefore(c,d.firstChild);var e,f=125;if(window.addEventListener("WebComponentsReady",function(){b(),Observer.hasObjectObserve||(a.flushPoll=setInterval(b,f))}),window.CustomElements&&!CustomElements.useNative){var g=Document.prototype.importNode;Document.prototype.importNode=function(a,b){var c=g.call(this,a,b);return CustomElements.upgradeAll(c),c}}a.flush=b}(window.Platform);
-//# sourceMappingURL=platform.js.map
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js.map b/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js.map
deleted file mode 100644
index 2a16da5..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/platform/platform.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"platform.js","sources":["../PointerGestures/src/PointerGestureEvent.js","../WeakMap/weakmap.js","../observe-js/src/observe.js","build/if-poly.js","../ShadowDOM/src/wrappers.js","../ShadowDOM/src/microtask.js","../ShadowDOM/src/MutationObserver.js","../ShadowDOM/src/TreeScope.js","../ShadowDOM/src/wrappers/events.js","../ShadowDOM/src/wrappers/NodeList.js","../ShadowDOM/src/wrappers/HTMLCollection.js","../ShadowDOM/src/wrappers/Node.js","../ShadowDOM/src/querySelector.js","../ShadowDOM/src/wrappers/node-interfaces.js","../ShadowDOM/src/wrappers/CharacterData.js","../ShadowDOM/src/wrappers/Text.js","../ShadowDOM/src/wrappers/Element.js","../ShadowDOM/src/wrappers/HTMLElement.js","../ShadowDOM/src/wrappers/HTMLCanvasElement.js","../ShadowDOM/src/wrappers/HTMLContentElement.js","../ShadowDOM/src/wrappers/HTMLImageElement.js","../ShadowDOM/src/wrappers/HTMLShadowElement.js","../ShadowDOM/src/wrappers/HTMLTemplateElement.js","../ShadowDOM/src/wrappers/HTMLMediaElement.js","../ShadowDOM/src/wrappers/HTMLAudioElement.js","../ShadowDOM/src/wrappers/HTMLOptionElement.js","../ShadowDOM/src/wrappers/HTMLSelectElement.js","../ShadowDOM/src/wrappers/HTMLTableElement.js","../ShadowDOM/src/wrappers/HTMLTableSectionElement.js","../ShadowDOM/src/wrappers/HTMLTableRowElement.js","../ShadowDOM/src/wrappers/HTMLUnknownElement.js","../ShadowDOM/src/wrappers/SVGElement.js","../ShadowDOM/src/wrappers/SVGUseElement.js","../ShadowDOM/src/wrappers/SVGElementInstance.js","../ShadowDOM/src/wrappers/CanvasRenderingContext2D.js","../ShadowDOM/src/wrappers/WebGLRenderingContext.js","../ShadowDOM/src/wrappers/Range.js","../ShadowDOM/src/wrappers/generic.js","../ShadowDOM/src/wrappers/ShadowRoot.js","../ShadowDOM/src/ShadowRenderer.js","../ShadowDOM/src/wrappers/elements-with-form-property.js","../ShadowDOM/src/wrappers/Selection.js","../ShadowDOM/src/wrappers/Document.js","../ShadowDOM/src/wrappers/Window.js","../ShadowDOM/src/wrappers/DataTransfer.js","../ShadowDOM/src/wrappers/override-constructors.js","src/patches-shadowdom-polyfill.js","src/ShadowCSS.js","src/patches-shadowdom-native.js","../URL/url.js","src/lang.js","src/dom.js","src/template.js","src/inspector.js","src/unresolved.js","src/module.js","src/microtask.js","src/url.js","../MutationObservers/MutationObserver.js","../HTMLImports/src/scope.js","../HTMLImports/src/Loader.js","../HTMLImports/src/Parser.js","../HTMLImports/src/HTMLImports.js","../HTMLImports/src/Observer.js","../HTMLImports/src/boot.js","../CustomElements/src/scope.js","../CustomElements/src/Observer.js","../CustomElements/src/CustomElements.js","../CustomElements/src/Parser.js","../CustomElements/src/boot.js","src/patches-custom-elements.js","src/loader.js","src/styleloader.js","../PointerEvents/src/boot.js","../PointerEvents/src/touch-action.js","../PointerEvents/src/PointerEvent.js","../PointerEvents/src/pointermap.js","../PointerEvents/src/dispatcher.js","../PointerEvents/src/installer.js","../PointerEvents/src/mouse.js","../PointerEvents/src/touch.js","../PointerEvents/src/ms.js","../PointerEvents/src/platform-events.js","../PointerEvents/src/capture.js","../PointerGestures/src/initialize.js","../PointerGestures/src/pointermap.js","../PointerGestures/src/dispatcher.js","../PointerGestures/src/hold.js","../PointerGestures/src/track.js","../PointerGestures/src/flick.js","../PointerGestures/src/pinch.js","../PointerGestures/src/tap.js","../PointerGestures/src/registerScopes.js","../NodeBind/src/NodeBind.js","../TemplateBinding/src/TemplateBinding.js","../polymer-expressions/third_party/esprima/esprima.js","../polymer-expressions/src/polymer-expressions.js","src/patches-mdv.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,QAAA,qBAAA,EAAA,GACA,GAAA,GAAA,MACA,EAAA,SAAA,YAAA,SACA,GACA,QAAA,QAAA,EAAA,WAAA,EAAA,UAAA,EACA,WAAA,QAAA,EAAA,cAAA,EAAA,aAAA,EAGA,GAAA,UAAA,EAAA,EAAA,QAAA,EAAA,WAGA,KAAA,GADA,GAAA,EAAA,OAAA,KAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GACA,EAAA,GAAA,EAAA,EAKA,OAFA,GAAA,WAAA,KAAA,WAEA,EC7BA,mBAAA,WACA,WACA,GAAA,GAAA,OAAA,eACA,EAAA,KAAA,MAAA,IAEA,EAAA,WACA,KAAA,KAAA,QAAA,IAAA,KAAA,WAAA,IAAA,KAAA,MAGA,GAAA,WACA,IAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,KAAA,KACA,IAAA,EAAA,KAAA,EACA,EAAA,GAAA,EAEA,EAAA,EAAA,KAAA,MAAA,OAAA,EAAA,GAAA,UAAA,KAEA,IAAA,SAAA,GACA,GAAA,EACA,QAAA,EAAA,EAAA,KAAA,QAAA,EAAA,KAAA,EACA,EAAA,GAAA,QAEA,SAAA,SAAA,GACA,KAAA,IAAA,EAAA,UAIA,OAAA,QAAA,KCnBA,SAAA,GACA,YASA,SAAA,KAQA,QAAA,GAAA,GACA,EAAA,EARA,GAAA,kBAAA,QAAA,SACA,kBAAA,OAAA,QACA,OAAA,CAGA,IAAA,MAMA,IAMA,IALA,OAAA,QAAA,EAAA,GACA,EAAA,GAAA,EACA,EAAA,GAAA,QACA,GAAA,GACA,OAAA,qBAAA,GACA,IAAA,EAAA,OACA,OAAA,CAIA,IAAA,OAAA,EAAA,GAAA,MACA,WAAA,EAAA,GAAA,MACA,WAAA,EAAA,GAAA,KACA,EAAA,MACA,EAAA,UACA,EAAA,eACA,EAAA,cACA,IAAA,OAAA,EAAA,GAAA,MACA,UAAA,EAAA,GAAA,MACA,UAAA,EAAA,GAAA,KAGA,MAFA,SAAA,MAAA,oFAEA,CASA,OAPA,QAAA,UAAA,EAAA,GAEA,GAAA,GACA,MAAA,QAAA,EAAA,GACA,EAAA,GAAA,EACA,EAAA,OAAA,EACA,OAAA,qBAAA,GACA,GAAA,EAAA,QACA,EACA,EAAA,GAAA,MAAA,GACA,EAAA,GAAA,MAAA,GACA,GAEA,MAAA,UAAA,EAAA,IAEA,GAKA,QAAA,KAIA,GAAA,EAAA,UACA,kBAAA,GAAA,WACA,EAAA,SAAA,eAAA,WACA,OAAA,CAGA,KACA,GAAA,GAAA,GAAA,UAAA,GAAA,eACA,OAAA,KACA,MAAA,GACA,OAAA,GAMA,QAAA,GAAA,GACA,OAAA,IAAA,IAAA,EAGA,QAAA,GAAA,GACA,OAAA,EAGA,QAAA,GAAA,GACA,MAAA,KAAA,OAAA,GAOA,QAAA,GAAA,EAAA,GACA,MAAA,KAAA,EACA,IAAA,GAAA,EAAA,IAAA,EAAA,EACA,EAAA,IAAA,EAAA,IACA,EAEA,IAAA,GAAA,IAAA,EAyBA,QAAA,GAAA,GACA,MAAA,gBAAA,IACA,GACA,EAAA,EAAA,OAEA,IAAA,GACA,EAEA,KAAA,EAAA,IACA,EAEA,EAAA,KAAA,IAKA,QAAA,GAAA,EAAA,GACA,GAAA,IAAA,EACA,KAAA,OAAA,wCAEA,OAAA,IAAA,EAAA,OACA,KAEA,EAAA,IACA,KAAA,KAAA,GACA,OAGA,EAAA,MAAA,YAAA,OAAA,SAAA,GACA,MAAA,KACA,QAAA,SAAA,GACA,KAAA,KAAA,IACA,WAEA,GAAA,KAAA,SACA,KAAA,aAAA,KAAA,4BAOA,QAAA,GAAA,GACA,GAAA,YAAA,GACA,MAAA,EAEA,OAAA,IACA,EAAA,IAEA,gBAAA,KACA,EAAA,OAAA,GAEA,IAAA,GAAA,GAAA,EACA,IAAA,EACA,MAAA,EACA,KAAA,EAAA,GACA,MAAA,GACA,IAAA,GAAA,GAAA,GAAA,EAAA,EAEA,OADA,IAAA,GAAA,EACA,EA8EA,QAAA,GAAA,GAEA,IADA,GAAA,GAAA,EACA,GAAA,GAAA,EAAA,UACA,GAKA,OAHA,GAAA,0BACA,EAAA,qBAAA,GAEA,EAAA,EAGA,QAAA,GAAA,GACA,IAAA,GAAA,KAAA,GACA,OAAA,CACA,QAAA,EAGA,QAAA,GAAA,GACA,MAAA,GAAA,EAAA,QACA,EAAA,EAAA,UACA,EAAA,EAAA,SAGA,QAAA,GAAA,EAAA,GACA,GAAA,MACA,KACA,IAEA,KAAA,GAAA,KAAA,GAAA,CACA,GAAA,GAAA,EAAA,IAEA,SAAA,GAAA,IAAA,EAAA,MAGA,IAAA,GAKA,IAAA,EAAA,KACA,EAAA,GAAA,GALA,EAAA,GAAA,QAQA,IAAA,GAAA,KAAA,GACA,IAAA,KAGA,EAAA,GAAA,EAAA,GAMA,OAHA,OAAA,QAAA,IAAA,EAAA,SAAA,EAAA,SACA,EAAA,OAAA,EAAA,SAGA,MAAA,EACA,QAAA,EACA,QAAA,GAKA,QAAA,KACA,IAAA,GAAA,OACA,OAAA,CAEA,KAAA,GAAA,GAAA,EAAA,EAAA,GAAA,OAAA,IACA,GAAA,IAGA,OADA,IAAA,OAAA,GACA,EA4BA,QAAA,KAMA,QAAA,GAAA,GACA,GAAA,EAAA,SAAA,KAAA,GACA,EAAA,OAAA,GAPA,GAAA,GACA,EACA,GAAA,EACA,GAAA,CAOA,QACA,KAAA,SAAA,GACA,GAAA,EACA,KAAA,OAAA,wBAEA,IACA,OAAA,qBAAA,GAEA,EAAA,EACA,GAAA,GAEA,QAAA,SAAA,EAAA,GACA,EAAA,EACA,EACA,MAAA,QAAA,EAAA,GAEA,OAAA,QAAA,EAAA,IAEA,QAAA,SAAA,GACA,EAAA,EACA,OAAA,qBAAA,GACA,GAAA,GAEA,MAAA,WACA,EAAA,OACA,OAAA,UAAA,EAAA,GACA,GAAA,KAAA,QAKA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,GAAA,OAAA,GAGA,OAFA,GAAA,KAAA,GACA,EAAA,QAAA,EAAA,GACA,EAMA,QAAA,KAQA,QAAA,GAAA,GACA,GAAA,EAAA,GAAA,CAGA,GAAA,GAAA,EAAA,QAAA,EACA,IAAA,GACA,EAAA,GAAA,OACA,EAAA,KAAA,IACA,EAAA,QAAA,GAAA,IACA,EAAA,KAAA,GACA,OAAA,QAAA,EAAA,IAGA,EAAA,OAAA,eAAA,KAGA,QAAA,KACA,GAAA,GAAA,IAAA,MAAA,CACA,GAAA,EACA,EAAA,CAEA,IAAA,EACA,KAAA,GAAA,KAAA,GACA,EAAA,EAAA,GACA,GAAA,EAAA,QAAA,IAGA,EAAA,gBAAA,EAGA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IACA,OAAA,UAAA,EAAA,GAGA,EAAA,OAAA,EAGA,QAAA,KACA,GAAA,EACA,GAGA,IAGA,QAAA,KACA,IAGA,GAAA,EACA,GAAA,EACA,GAAA,IAGA,QAAA,KACA,GAEA,IAAA,EAEA,KAAA,GAAA,KAAA,GACA,EAAA,EAAA,GACA,GAAA,EAAA,QAAA,IAGA,EAAA,SAzEA,GAAA,MACA,EAAA,EACA,KACA,EAAA,GACA,GAAA,EACA,GAAA,EAwEA,GACA,OAAA,OACA,QAAA,EACA,KAAA,SAAA,GACA,EAAA,EAAA,KAAA,EACA,IACA,EAAA,gBAAA,IAEA,MAAA,SAAA,GAMA,GAHA,EAAA,EAAA,KAAA,OACA,IAEA,EAEA,WADA,IAGA,IAAA,CAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,OAAA,UAAA,EAAA,GAAA,GACA,EAAA,iBAGA,GAAA,OAAA,EACA,EAAA,OAAA,EACA,GAAA,KAAA,OAEA,MAAA,EAGA,OAAA,GAKA,QAAA,GAAA,EAAA,GAMA,MALA,KAAA,GAAA,SAAA,IACA,GAAA,GAAA,OAAA,IACA,GAAA,OAAA,GAEA,GAAA,KAAA,GACA,GAUA,QAAA,KACA,KAAA,OAAA,GACA,KAAA,UAAA,OACA,KAAA,QAAA,OACA,KAAA,gBAAA,OACA,KAAA,OAAA,OACA,KAAA,IAAA,KA2DA,QAAA,GAAA,GACA,EAAA,qBACA,IAGA,GAAA,KAAA,GAGA,QAAA,KACA,EAAA,qBA0DA,QAAA,GAAA,GACA,EAAA,KAAA,MACA,KAAA,OAAA,EACA,KAAA,WAAA,OA0FA,QAAA,GAAA,GACA,IAAA,MAAA,QAAA,GACA,KAAA,OAAA,kCACA,GAAA,KAAA,KAAA,GAgDA,QAAA,GAAA,EAAA,GACA,EAAA,KAAA,MAEA,KAAA,QAAA,EACA,KAAA,MAAA,YAAA,GAAA,EAAA,EAAA,GACA,KAAA,gBAAA,OA0CA,QAAA,KACA,EAAA,KAAA,MAEA,KAAA,UACA,KAAA,gBAAA,OACA,KAAA,aAkIA,QAAA,GAAA,GAAA,MAAA,GAEA,QAAA,GAAA,EAAA,EAAA,EACA,GACA,KAAA,UAAA,OACA,KAAA,QAAA,OACA,KAAA,OAAA,OACA,KAAA,YAAA,EACA,KAAA,YAAA,GAAA,EACA,KAAA,YAAA,GAAA,EAGA,KAAA,oBAAA,EAqDA,QAAA,GAAA,EAAA,GACA,GAAA,kBAAA,QAAA,QAAA,CAGA,GAAA,GAAA,OAAA,YAAA,EACA,OAAA,UAAA,EAAA,GACA,GAAA,IACA,OAAA,EACA,KAAA,EACA,KAAA,EAEA,KAAA,UAAA,SACA,EAAA,SAAA,GACA,EAAA,OAAA,KAoCA,QAAA,GAAA,EAAA,EAAA,GAIA,IAAA,GAHA,MACA,KAEA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IAAA,EAAA,OAMA,EAAA,OAAA,KACA,EAAA,EAAA,MAAA,EAAA,UAEA,EAAA,MAAA,IAGA,EAAA,MAAA,EAUA,EAAA,OAAA,UACA,GAAA,EAAA,YACA,GAAA,EAAA,OAEA,EAAA,EAAA,OAAA,EAbA,EAAA,OAAA,SACA,GAAA,EAAA,MAEA,EAAA,EAAA,OAAA,KAfA,QAAA,MAAA,8BAAA,EAAA,MACA,QAAA,MAAA,IA4BA,IAAA,GAAA,KAAA,GACA,EAAA,GAAA,EAAA,EAEA,KAAA,GAAA,KAAA,GACA,EAAA,GAAA,MAEA,IAAA,KACA,KAAA,GAAA,KAAA,GACA,KAAA,IAAA,IAAA,IAAA,IAAA,CAGA,GAAA,GAAA,EAAA,EACA,GAAA,KAAA,IACA,EAAA,GAAA,GAGA,OACA,MAAA,EACA,QAAA,EACA,QAAA,GAIA,QAAA,GAAA,EAAA,EAAA,GACA,OACA,MAAA,EACA,QAAA,EACA,WAAA,GASA,QAAA,MA0OA,QAAA,GAAA,EAAA,EAAA,EACA,EAAA,EAAA,GACA,MAAA,IAAA,YAAA,EAAA,EAAA,EACA,EAAA,EAAA,GAGA,QAAA,GAAA,EAAA,EAAA,EAAA,GAEA,MAAA,GAAA,GAAA,EAAA,EACA,GAGA,GAAA,GAAA,GAAA,EACA,EAGA,EAAA,EACA,EAAA,EACA,EAAA,EAEA,EAAA,EAGA,EAAA,EACA,EAAA,EAEA,EAAA,EAIA,QAAA,GAAA,EAAA,EAAA,EAAA,GAOA,IAAA,GALA,GAAA,EAAA,EAAA,EAAA,GAEA,GAAA,EACA,EAAA,EAEA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EAGA,IAFA,EAAA,OAAA,GAEA,EAAA,CAGA,GAAA,GAAA,EAAA,EAAA,MACA,EAAA,MAAA,EAAA,QAAA,OACA,EAAA,MACA,EAAA,MAAA,EAAA,WAEA,IAAA,GAAA,EAAA,CAGA,EAAA,OAAA,EAAA,GACA,IAEA,GAAA,EAAA,WAAA,EAAA,QAAA,OAEA,EAAA,YAAA,EAAA,WAAA,CACA,IAAA,GAAA,EAAA,QAAA,OACA,EAAA,QAAA,OAAA,CAEA,IAAA,EAAA,YAAA,EAGA,CACA,GAAA,GAAA,EAAA,OAEA,IAAA,EAAA,MAAA,EAAA,MAAA,CAEA,GAAA,GAAA,EAAA,QAAA,MAAA,EAAA,EAAA,MAAA,EAAA,MACA,OAAA,UAAA,KAAA,MAAA,EAAA,GACA,EAAA,EAGA,GAAA,EAAA,MAAA,EAAA,QAAA,OAAA,EAAA,MAAA,EAAA,WAAA,CAEA,GAAA,GAAA,EAAA,QAAA,MAAA,EAAA,MAAA,EAAA,WAAA,EAAA,MACA,OAAA,UAAA,KAAA,MAAA,EAAA,GAGA,EAAA,QAAA,EACA,EAAA,MAAA,EAAA,QACA,EAAA,MAAA,EAAA,WAnBA,IAAA,MAsBA,IAAA,EAAA,MAAA,EAAA,MAAA,CAGA,GAAA,EAEA,EAAA,OAAA,EAAA,EAAA,GACA,GAEA,IAAA,GAAA,EAAA,WAAA,EAAA,QAAA,MACA,GAAA,OAAA,EACA,GAAA,IAIA,GACA,EAAA,KAAA,GAGA,QAAA,GAAA,EAAA,GAGA,IAAA,GAFA,MAEA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,QAAA,EAAA,MACA,IAAA,GACA,EAAA,EAAA,EAAA,MAAA,EAAA,QAAA,QAAA,EAAA,WACA,MACA,KAAA,GACA,IAAA,GACA,IAAA,GACA,IAAA,EAAA,EAAA,MACA,QACA,IAAA,GAAA,EAAA,EAAA,KACA,IAAA,EAAA,EACA,QACA,GAAA,EAAA,GAAA,EAAA,UAAA,EACA,MACA,SACA,QAAA,MAAA,2BAAA,KAAA,UAAA,KAKA,MAAA,GAGA,QAAA,GAAA,EAAA,GACA,GAAA,KAcA,OAZA,GAAA,EAAA,GAAA,QAAA,SAAA,GACA,MAAA,IAAA,EAAA,YAAA,GAAA,EAAA,QAAA,YACA,EAAA,QAAA,KAAA,EAAA,EAAA,QACA,EAAA,KAAA,SAKA,EAAA,EAAA,OAAA,EAAA,EAAA,EAAA,MAAA,EAAA,MAAA,EAAA,WACA,EAAA,QAAA,EAAA,EAAA,QAAA,YAGA,EApiDA,GAAA,GAAA,MACA,EAAA,SACA,EAAA,cACA,EAAA,SACA,EAAA,SA0DA,EAAA,IAoBA,EAAA,IAcA,EAAA,EAAA,OAAA,OAAA,SAAA,GACA,MAAA,gBAAA,IAAA,EAAA,MAAA,IAYA,EAAA,gBACA,SAAA,GAAA,MAAA,IACA,SAAA,GACA,GAAA,GAAA,EAAA,SACA,KAAA,EACA,MAAA,EACA,IAAA,GAAA,OAAA,OAAA,EAKA,OAJA,QAAA,oBAAA,GAAA,QAAA,SAAA,GACA,OAAA,eAAA,EAAA,EACA,OAAA,yBAAA,EAAA,MAEA,GAGA,EAAA,aACA,EAAA,gBACA,EAAA,EAAA,IAAA,EAAA,IACA,EAAA,yBACA,EAAA,MAAA,EAAA,IAAA,EAAA,IACA,EAAA,MAAA,EAAA,kBAAA,EAAA,KACA,EAAA,GAAA,QAAA,IAAA,EAAA,KAgBA,KA0BA,KAsBA,GAAA,IAAA,EAEA,EAAA,UAAA,GACA,aACA,OAAA,EAEA,SAAA,WACA,MAAA,MAAA,KAAA,MAGA,aAAA,SAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,KAAA,OAAA,IAAA,CACA,GAAA,MAAA,EACA,MACA,GAAA,EAAA,KAAA,IAEA,MAAA,IAGA,eAAA,SAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,KAAA,OAAA,IAAA,CAGA,GAFA,IACA,EAAA,EAAA,KAAA,EAAA,MACA,EACA,MACA,GAAA,KAIA,uBAAA,WACA,GAAA,GAAA,KAAA,IAAA,SAAA,GACA,MAAA,GAAA,GAAA,KAAA,EAAA,KAAA,IAAA,IAGA,EAAA,GACA,EAAA,KACA,IAAA,iBAEA,KADA,GAAA,GAAA,EACA,EAAA,KAAA,OAAA,EAAA,IAAA,CACA,CAAA,KAAA,GACA,GAAA,EAAA,GACA,GAAA,aAAA,EAAA,WAOA,MALA,IAAA,MAEA,GAAA,EAAA,GAEA,GAAA,YAAA,EAAA,+BACA,GAAA,UAAA,MAAA,IAGA,aAAA,SAAA,EAAA,GACA,IAAA,KAAA,OACA,OAAA,CAEA,KAAA,GAAA,GAAA,EAAA,EAAA,KAAA,OAAA,EAAA,IAAA,CACA,IAAA,EAAA,GACA,OAAA,CACA,GAAA,EAAA,KAAA,IAGA,MAAA,GAAA,IAGA,EAAA,KAAA,IAAA,GACA,IAHA,IAOA,IAAA,IAAA,GAAA,GAAA,GAAA,EACA,IAAA,OAAA,EACA,GAAA,aAAA,GAAA,aAAA,YAEA,IAwQA,IAxQA,GAAA,IA8DA,MAYA,GAAA,EAAA,WACA,GAAA,IAAA,UAAA,GACA,GAAA,CAOA,OALA,QAAA,QAAA,EAAA,WACA,IACA,GAAA,IAGA,SAAA,GACA,GAAA,KAAA,GACA,IACA,GAAA,EACA,EAAA,UAAA,EAAA,cAIA,WACA,MAAA,UAAA,GACA,GAAA,KAAA,OAIA,MAmDA,MACA,MA8HA,GAAA,EACA,GAAA,EACA,GAAA,EACA,GAAA,EAEA,GAAA,CAWA,GAAA,WACA,KAAA,SAAA,EAAA,GACA,GAAA,KAAA,QAAA,GACA,KAAA,OAAA,oCAOA,OALA,GAAA,MACA,KAAA,UAAA,EACA,KAAA,QAAA,EACA,KAAA,OAAA,GACA,KAAA,WACA,KAAA,QAGA,MAAA,WACA,KAAA,QAAA,KAGA,EAAA,MACA,KAAA,OAAA,GACA,KAAA,cACA,KAAA,OAAA,OACA,KAAA,UAAA,OACA,KAAA,QAAA,SAGA,QAAA,WACA,KAAA,QAAA,IAGA,EAAA,OAGA,QAAA,SAAA,GACA,IACA,KAAA,UAAA,MAAA,KAAA,QAAA,GACA,MAAA,GACA,EAAA,4BAAA,EACA,QAAA,MAAA,+CACA,EAAA,OAAA,MAIA,eAAA,WAEA,MADA,MAAA,OAAA,QAAA,GACA,KAAA,QAIA,IACA,IADA,IAAA,CAEA,GAAA,mBAAA,EAEA,KACA,MAeA,IAAA,KAAA,EAEA,GAAA,kBAAA,QAAA,uBAEA,GAAA,SAAA,EAAA,aAEA,EAAA,SAAA,2BAAA,WACA,IAAA,GAAA,CAGA,GAAA,GAEA,WADA,QAAA,yBAIA,IAAA,GAAA,CAGA,IAAA,CAEA,IACA,GAAA,EADA,EAAA,CAGA,GAAA,CACA,IACA,EAAA,GACA,MACA,GAAA,CAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,QAAA,KAGA,EAAA,WACA,GAAA,GAEA,GAAA,KAAA,IAEA,MACA,GAAA,SACA,GAAA,GAAA,EAEA,GAAA,0BACA,EAAA,qBAAA,GAEA,IAAA,KAGA,KACA,EAAA,SAAA,eAAA,WACA,QAUA,EAAA,UAAA,GACA,UAAA,EAAA,UAEA,cAAA,EAEA,SAAA,WACA,EACA,KAAA,gBAAA,EAAA,KAAA,KAAA,OACA,KAAA,cAEA,KAAA,WAAA,KAAA,WAAA,KAAA,SAKA,WAAA,SAAA,GACA,GAAA,GAAA,MAAA,QAAA,QACA,KAAA,GAAA,KAAA,GACA,EAAA,GAAA,EAAA,EAIA,OAFA,OAAA,QAAA,KACA,EAAA,OAAA,EAAA,QACA,GAGA,OAAA,SAAA,GACA,GAAA,GACA,CACA,IAAA,EAAA,CACA,IAAA,EACA,OAAA,CAEA,MACA,EAAA,EAAA,KAAA,OAAA,EACA,OAEA,GAAA,KAAA,WACA,EAAA,EAAA,KAAA,OAAA,KAAA,WAGA,OAAA,GAAA,IACA,GAEA,IACA,KAAA,WAAA,KAAA,WAAA,KAAA,SAEA,KAAA,SACA,EAAA,UACA,EAAA,YACA,EAAA,YACA,SAAA,GACA,MAAA,GAAA,OAIA,IAGA,YAAA,WACA,GACA,KAAA,gBAAA,QACA,KAAA,gBAAA,QAEA,KAAA,WAAA,QAIA,QAAA,WACA,KAAA,QAAA,KAGA,EACA,KAAA,gBAAA,SAAA,GAEA,EAAA,QAGA,eAAA,WAMA,MALA,MAAA,gBACA,KAAA,gBAAA,SAAA,GAEA,KAAA,WAAA,KAAA,WAAA,KAAA,QAEA,KAAA,UAUA,EAAA,UAAA,GAEA,UAAA,EAAA,UAEA,cAAA,EAEA,WAAA,SAAA,GACA,MAAA,GAAA,SAGA,OAAA,SAAA,GACA,GAAA,EACA,IAAA,EAAA,CACA,IAAA,EACA,OAAA,CACA,GAAA,EAAA,KAAA,OAAA,OAEA,GAAA,EAAA,KAAA,OAAA,EAAA,KAAA,OAAA,OACA,KAAA,WAAA,EAAA,KAAA,WAAA,OAGA,OAAA,IAAA,EAAA,QAGA,IACA,KAAA,WAAA,KAAA,WAAA,KAAA,SAEA,KAAA,SAAA,KACA,IANA,KAUA,EAAA,aAAA,SAAA,EAAA,EAAA,GACA,EAAA,QAAA,SAAA,GAGA,IAFA,GAAA,IAAA,EAAA,MAAA,EAAA,QAAA,QACA,EAAA,EAAA,MACA,EAAA,EAAA,MAAA,EAAA,YACA,EAAA,KAAA,EAAA,IACA,GAGA,OAAA,UAAA,OAAA,MAAA,EAAA,MAYA,EAAA,UAAA,GACA,UAAA,EAAA,UAEA,SAAA,WACA,IACA,KAAA,gBAAA,EAAA,KAAA,KAAA,UAEA,KAAA,OAAA,QAAA,IAGA,YAAA,WACA,KAAA,OAAA,OAEA,KAAA,kBACA,KAAA,gBAAA,MAAA,MACA,KAAA,gBAAA,SAIA,gBAAA,SAAA,GACA,KAAA,MAAA,eAAA,KAAA,QAAA,IAGA,OAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,MAEA,OADA,MAAA,OAAA,KAAA,MAAA,aAAA,KAAA,SACA,GAAA,EAAA,KAAA,OAAA,IACA,GAEA,KAAA,SAAA,KAAA,OAAA,KACA,IAGA,SAAA,SAAA,GACA,KAAA,OACA,KAAA,MAAA,aAAA,KAAA,QAAA,KAYA,IAAA,MAEA,GAAA,UAAA,GACA,UAAA,EAAA,UAEA,SAAA,WAGA,GAFA,KAAA,OAAA,QAAA,GAEA,EAAA,CAKA,IAAA,GAFA,GACA,GAAA,EACA,EAAA,EAAA,EAAA,KAAA,UAAA,OAAA,GAAA,EAEA,GADA,EAAA,KAAA,UAAA,GACA,IAAA,GAAA,CACA,GAAA,CACA,OAIA,MAAA,MAAA,gBACA,MACA,MAAA,gBAAA,SAGA,KAAA,gBAAA,aACA,KAAA,gBAAA,cAIA,IACA,KAAA,gBAAA,EAAA,KAAA,OAGA,gBAAA,WACA,IAAA,GAAA,GAAA,EAAA,EAAA,KAAA,UAAA,OAAA,GAAA,EACA,KAAA,UAAA,KAAA,IACA,KAAA,UAAA,EAAA,GAAA,OAEA,MAAA,UAAA,OAAA,GAGA,YAAA,WACA,KAAA,OAAA,OAEA,KAAA,kBACA,KAAA,gBAAA,MAAA,MACA,KAAA,gBAAA,QAGA,KAAA,mBAGA,QAAA,SAAA,EAAA,GACA,GAAA,KAAA,QAAA,IAAA,KAAA,QAAA,GACA,KAAA,OAAA,iCAEA,MAAA,UAAA,KAAA,EAAA,YAAA,GAAA,EAAA,EAAA,KAGA,YAAA,SAAA,GACA,GAAA,KAAA,QAAA,IAAA,KAAA,QAAA,GACA,KAAA,OAAA,qCAEA,GAAA,KAAA,KAAA,QAAA,MACA,KAAA,UAAA,KAAA,GAAA,IAGA,WAAA,WACA,GAAA,KAAA,QAAA,GACA,KAAA,OAAA,4BAEA,MAAA,OAAA,GACA,KAAA,mBAGA,YAAA,WACA,GAAA,KAAA,QAAA,GACA,KAAA,OAAA,wCAIA,OAHA,MAAA,OAAA,GACA,KAAA,WAEA,KAAA,QAGA,gBAAA,SAAA,GAEA,IAAA,GADA,GACA,EAAA,EAAA,EAAA,KAAA,UAAA,OAAA,GAAA,EACA,EAAA,KAAA,UAAA,GACA,IAAA,IACA,KAAA,UAAA,EAAA,GAAA,eAAA,EAAA,IAIA,OAAA,SAAA,EAAA,GAEA,IAAA,GADA,GACA,EAAA,EAAA,EAAA,KAAA,UAAA,OAAA,GAAA,EAAA,CACA,GAAA,GAAA,KAAA,UAAA,EAAA,GACA,EAAA,KAAA,UAAA,GACA,EAAA,IAAA,GACA,EAAA,iBACA,EAAA,aAAA,EAEA,GACA,KAAA,OAAA,EAAA,GAAA,EAIA,EAAA,EAAA,KAAA,OAAA,EAAA,MAGA,EAAA,MACA,EAAA,EAAA,GAAA,KAAA,OAAA,EAAA,GACA,KAAA,OAAA,EAAA,GAAA,GAGA,MAAA,IAKA,KAAA,SAAA,KAAA,OAAA,EAAA,KAAA,aACA,IALA,KAwBA,EAAA,WACA,KAAA,SAAA,EAAA,GAKA,MAJA,MAAA,UAAA,EACA,KAAA,QAAA,EACA,KAAA,OACA,KAAA,YAAA,KAAA,YAAA,KAAA,KAAA,kBAAA,OACA,KAAA,QAGA,kBAAA,SAAA,GAEA,GADA,EAAA,KAAA,YAAA,IACA,EAAA,EAAA,KAAA,QAAA,CAEA,GAAA,GAAA,KAAA,MACA,MAAA,OAAA,EACA,KAAA,UAAA,KAAA,KAAA,QAAA,KAAA,OAAA,KAGA,eAAA,WAEA,MADA,MAAA,OAAA,KAAA,YAAA,KAAA,YAAA,kBACA,KAAA,QAGA,QAAA,WACA,MAAA,MAAA,YAAA,WAGA,SAAA,SAAA,GAEA,MADA,GAAA,KAAA,YAAA,IACA,KAAA,qBAAA,KAAA,YAAA,SACA,KAAA,YAAA,SAAA,GADA,QAIA,MAAA,WACA,KAAA,aACA,KAAA,YAAA,QACA,KAAA,UAAA,OACA,KAAA,QAAA,OACA,KAAA,YAAA,OACA,KAAA,OAAA,OACA,KAAA,YAAA,OACA,KAAA,YAAA,QAIA,IAAA,MACA,IAAA,IAAA,EACA,GAAA,IAAA,EACA,GAAA,IAAA,EAmBA,EAAA,uBAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,EAAA,GACA,EAAA,EAAA,KAAA,SAAA,EAAA,GACA,EAAA,EACA,GACA,EAAA,EAAA,IAeA,OAZA,QAAA,eAAA,EAAA,GACA,IAAA,WAEA,MADA,GAAA,UACA,GAEA,IAAA,SAAA,GAEA,MADA,GAAA,SAAA,GACA,GAEA,cAAA,KAIA,MAAA,WACA,EAAA,QACA,OAAA,eAAA,EAAA,GACA,MAAA,EACA,UAAA,EACA,cAAA,MAyEA,IAAA,IAAA,EACA,GAAA,EACA,GAAA,EACA,GAAA,CAIA,GAAA,WAaA,kBAAA,SAAA,EAAA,EAAA,EACA,EAAA,EAAA,GAOA,IAAA,GALA,GAAA,EAAA,EAAA,EACA,EAAA,EAAA,EAAA,EACA,EAAA,GAAA,OAAA,GAGA,EAAA,EAAA,EAAA,EAAA,IACA,EAAA,GAAA,GAAA,OAAA,GACA,EAAA,GAAA,GAAA,CAIA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,IACA,EAAA,GAAA,GAAA,CAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,IACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,IACA,GAAA,KAAA,OAAA,EAAA,EAAA,EAAA,GAAA,EAAA,EAAA,EAAA,IACA,EAAA,GAAA,GAAA,EAAA,EAAA,GAAA,EAAA,OACA,CACA,GAAA,GAAA,EAAA,EAAA,GAAA,GAAA,EACA,EAAA,EAAA,GAAA,EAAA,GAAA,CACA,GAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAKA,MAAA,IAMA,kCAAA,SAAA,GAKA,IAJA,GAAA,GAAA,EAAA,OAAA,EACA,EAAA,EAAA,GAAA,OAAA,EACA,EAAA,EAAA,GAAA,GACA,KACA,EAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAKA,GAAA,GAAA,EAAA,CAKA,GAIA,GAJA,EAAA,EAAA,EAAA,GAAA,EAAA,GACA,EAAA,EAAA,EAAA,GAAA,GACA,EAAA,EAAA,GAAA,EAAA,EAIA,GADA,EAAA,EACA,EAAA,EAAA,EAAA,EAEA,EAAA,EAAA,EAAA,EAEA,GAAA,GACA,GAAA,EACA,EAAA,KAAA,KAEA,EAAA,KAAA,IACA,EAAA,GAEA,IACA,KACA,GAAA,GACA,EAAA,KAAA,IACA,IACA,EAAA,IAEA,EAAA,KAAA,IACA,IACA,EAAA,OA9BA,GAAA,KAAA,IACA,QANA,GAAA,KAAA,IACA,GAuCA,OADA,GAAA,UACA,GA2BA,YAAA,SAAA,EAAA,EAAA,EACA,EAAA,EAAA,GACA,GAAA,GAAA,EACA,EAAA,EAEA,EAAA,KAAA,IAAA,EAAA,EAAA,EAAA,EAYA,IAXA,GAAA,GAAA,GAAA,IACA,EAAA,KAAA,aAAA,EAAA,EAAA,IAEA,GAAA,EAAA,QAAA,GAAA,EAAA,SACA,EAAA,KAAA,aAAA,EAAA,EAAA,EAAA,IAEA,GAAA,EACA,GAAA,EACA,GAAA,EACA,GAAA,EAEA,EAAA,GAAA,GAAA,EAAA,GAAA,EACA,QAEA,IAAA,GAAA,EAAA,CAEA,IADA,GAAA,GAAA,EAAA,KAAA,GACA,EAAA,GACA,EAAA,QAAA,KAAA,EAAA,KAEA,QAAA,GACA,GAAA,GAAA,EACA,OAAA,EAAA,KAAA,EAAA,GAUA,KAAA,GARA,GAAA,KAAA,kCACA,KAAA,kBAAA,EAAA,EAAA,EACA,EAAA,EAAA,IAEA,EAAA,OACA,KACA,EAAA,EACA,EAAA,EACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,OAAA,EAAA,IACA,IAAA,IACA,IACA,EAAA,KAAA,GACA,EAAA,QAGA,IACA,GACA,MACA,KAAA,IACA,IACA,EAAA,EAAA,KAAA,IAEA,EAAA,aACA,IAEA,EAAA,QAAA,KAAA,EAAA,IACA,GACA,MACA,KAAA,IACA,IACA,EAAA,EAAA,KAAA,IAEA,EAAA,aACA,GACA,MACA,KAAA,IACA,IACA,EAAA,EAAA,KAAA,IAEA,EAAA,QAAA,KAAA,EAAA,IACA,IAQA,MAHA,IACA,EAAA,KAAA,GAEA,GAGA,aAAA,SAAA,EAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,IACA,IAAA,KAAA,OAAA,EAAA,GAAA,EAAA,IACA,MAAA,EACA,OAAA,IAGA,aAAA,SAAA,EAAA,EAAA,GAIA,IAHA,GAAA,GAAA,EAAA,OACA,EAAA,EAAA,OACA,EAAA,EACA,EAAA,GAAA,KAAA,OAAA,IAAA,GAAA,IAAA,KACA,GAEA,OAAA,IAGA,iBAAA,SAAA,EAAA,GACA,MAAA,MAAA,YAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EACA,EAAA,SAGA,OAAA,SAAA,EAAA,GACA,MAAA,KAAA,GAIA,IAAA,IAAA,GAAA,EAuJA,GAAA,SAAA,EACA,EAAA,SAAA,QAAA,GACA,EAAA,SAAA,iBAAA,EACA,EAAA,cAAA,EACA,EAAA,cAAA,iBAAA,SAAA,EAAA,GACA,MAAA,IAAA,iBAAA,EAAA,IAGA,EAAA,YAAA,EACA,EAAA,eAAA,EACA,EAAA,aAAA,EACA,EAAA,iBAAA,EACA,EAAA,KAAA,EACA,EAAA,kBAAA,EAIA,EAAA,SAAA,mBACA,IAAA,EACA,OAAA,EACA,YAAA,EACA,SAAA,EACA,OAAA,IAEA,mBAAA,SAAA,QAAA,mBAAA,SAAA,OAAA,OAAA,MAAA,QC/kDA,OAAA,SAAA,OAAA,aAEA,OAAA,SAAA,OAAA,aAEA,SAAA,GAEA,GAAA,GAAA,EAAA,SAEA,UAAA,OAAA,MAAA,GAAA,MAAA,KAAA,QAAA,SAAA,GACA,EAAA,EAAA,MAAA,KACA,EAAA,KAAA,EAAA,EAAA,IAAA,EAAA,KAAA,IAEA,IAAA,GAAA,SAAA,eAAA,SAAA,cAAA,6BACA,IAAA,EAEA,IAAA,GAAA,GADA,EAAA,EAAA,WACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GACA,QAAA,EAAA,OACA,EAAA,EAAA,MAAA,EAAA,QAAA,EAIA,GAAA,KACA,EAAA,IAAA,MAAA,KAAA,QAAA,SAAA,GACA,OAAA,SAAA,IAAA,IAMA,EAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,SAEA,EAAA,OADA,WAAA,EAAA,QACA,EAEA,EAAA,SAAA,YAAA,UAAA,iBAIA,EAAA,WACA,OAAA,eAAA,OAAA,iBAAA,UACA,OAAA,eAAA,MAAA,SAAA,EAAA,UAGA,EAAA,UACA,OAAA,YAAA,OAAA,cAAA,UACA,OAAA,YAAA,MAAA,QAAA,EAAA,SAIA,EAAA,MAAA,GACA,UAGA,SAAA,MAAA,QClDA,OAAA,qBAEA,SAAA,GACA,YAoBA,SAAA,GAAA,GACA,IAAA,EACA,KAAA,IAAA,OAAA,oBAOA,QAAA,GAAA,EAAA,GAIA,MAHA,GAAA,GAAA,QAAA,SAAA,GACA,EAAA,EAAA,EAAA,EAAA,EAAA,MAEA,EAGA,QAAA,GAAA,EAAA,GAaA,MAZA,GAAA,GAAA,QAAA,SAAA,GACA,OAAA,GACA,IAAA,YACA,IAAA,SACA,IAAA,SACA,IAAA,OACA,IAAA,YACA,IAAA,WACA,OAEA,EAAA,EAAA,EAAA,EAAA,EAAA,MAEA,EAGA,QAAA,GAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,GAAA,EAAA,IAAA,GACA,MAAA,GAAA,GASA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,WAAA,OAAA,eAAA,GACA,EAAA,EAAA,IAAA,EACA,IAAA,EACA,MAAA,EAEA,IAAA,GAAA,EAAA,GAEA,EAAA,EAAA,EAGA,OAFA,GAAA,EAAA,EAAA,GAEA,EAGA,QAAA,GAAA,EAAA,GACA,EAAA,EAAA,GAAA,GAGA,QAAA,GAAA,EAAA,GACA,EAAA,EAAA,GAAA,GAcA,QAAA,GAAA,GACA,MAAA,aAAA,KAAA,GAGA,QAAA,GAAA,GACA,MAAA,oBAAA,KAAA,GAGA,QAAA,GAAA,GACA,MAAA,IAAA,EAAA,GACA,GAAA,UAAA,oBAAA,GACA,WAAA,MAAA,MAAA,KAAA,IAGA,QAAA,GAAA,GACA,MAAA,IAAA,EAAA,GACA,GAAA,UAAA,IAAA,aAAA,EAAA,QACA,SAAA,GAAA,KAAA,KAAA,GAAA,GAGA,QAAA,GAAA,GACA,MAAA,IAAA,EAAA,GACA,GAAA,UAAA,oBAAA,EACA,gCACA,WAAA,MAAA,MAAA,KAAA,GAAA,MAAA,KAAA,KAAA,YAGA,QAAA,GAAA,EAAA,GACA,IACA,MAAA,QAAA,yBAAA,EAAA,GACA,MAAA,GAIA,MAAA,IAIA,QAAA,GAAA,EAAA,EAAA,GAEA,IAAA,GADA,GAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IAAA,sBAAA,KAGA,IAAA,IAGA,EAAA,mBAAA,EAAA,kBAAA,IAAA,CAGA,GAEA,EAAA,iBAAA,EAEA,IACA,GAAA,EADA,EAAA,EAAA,EAAA,EAEA,IAAA,GAAA,kBAAA,GAAA,MACA,EAAA,GAAA,EAAA,OADA,CAKA,GAAA,GAAA,EAAA,EAEA,GADA,EACA,EAAA,sBAAA,GAEA,EAAA,IAEA,EAAA,UAAA,EAAA,OAEA,EADA,EACA,EAAA,sBAAA,GAEA,EAAA,IAGA,EAAA,EAAA,GACA,IAAA,EACA,IAAA,EACA,aAAA,EAAA,aACA,WAAA,EAAA,gBAWA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,SACA,GAAA,EAAA,EAAA,GACA,EAAA,EAAA,GAGA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,SACA,GAAA,SAAA,EAAA,IAAA,IAEA,EAAA,IAAA,EAAA,GACA,EAAA,IAAA,EAAA,GAEA,EAAA,EAAA,GACA,GACA,EAAA,EAAA,GACA,EAAA,EAAA,eACA,MAAA,EACA,cAAA,EACA,YAAA,EACA,UAAA,IAGA,EAAA,UAAA,EAGA,QAAA,GAAA,EAAA,GACA,MAAA,GAAA,IAAA,EAAA,aACA,EASA,QAAA,GAAA,GACA,GAAA,GAAA,OAAA,eAAA,GAEA,EAAA,EAAA,GACA,EAAA,EAAA,EAGA,OAFA,GAAA,EAAA,EAAA,GAEA,EAGA,QAAA,GAAA,GACA,QAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAEA,GAAA,GAAA,OAAA,OAAA,EAAA,UAIA,OAHA,GAAA,YAAA,EACA,EAAA,UAAA,EAEA,EAaA,QAAA,GAAA,GACA,MAAA,aAAA,GAAA,aACA,YAAA,GAAA,OACA,YAAA,GAAA,OACA,YAAA,GAAA,mBACA,YAAA,GAAA,0BACA,EAAA,uBACA,YAAA,GAAA,sBAGA,QAAA,GAAA,GACA,MAAA,IAAA,YAAA,IACA,YAAA,IACA,YAAA,IACA,YAAA,IACA,YAAA,IACA,YAAA,IACA,YAAA,IACA,GACA,YAAA,IACA,GACA,YAAA,GASA,QAAA,GAAA,GACA,MAAA,QAAA,EACA,MAEA,EAAA,EAAA,IACA,EAAA,kBACA,EAAA,gBAAA,IAAA,EAAA,IAAA,KAQA,QAAA,GAAA,GACA,MAAA,QAAA,EACA,MACA,EAAA,EAAA,IACA,EAAA,MAQA,QAAA,GAAA,GACA,MAAA,IAAA,EAAA,GAAA,EAAA,GAAA,EAQA,QAAA,GAAA,GACA,MAAA,KAAA,EAAA,GAAA,EAAA,GAAA,EASA,QAAA,GAAA,EAAA,GACA,OAAA,IAEA,EAAA,EAAA,IACA,EAAA,SAAA,GAAA,EAAA,IACA,EAAA,gBAAA,GAGA,QAAA,GAAA,EAAA,EAAA,GACA,EAAA,EAAA,UAAA,GACA,IAAA,EACA,cAAA,EACA,YAAA,IAIA,QAAA,GAAA,EAAA,GACA,EAAA,EAAA,EAAA,WACA,MAAA,GAAA,KAAA,KAAA,MAWA,QAAA,GAAA,EAAA,GACA,EAAA,QAAA,SAAA,GACA,EAAA,QAAA,SAAA,GACA,EAAA,UAAA,GAAA,WACA,GAAA,GAAA,EAAA,KACA,OAAA,GAAA,GAAA,MAAA,EAAA,gBA1WA,GAAA,GAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,OAAA,OAAA,MAKA,IAAA,kBAAA,YACA,SAAA,eAAA,UACA,IAAA,EACA,IACA,GAAA,GAAA,GAAA,UAAA,GAAA,eACA,GAAA,IACA,MAAA,GACA,GAAA,EASA,GAAA,GAAA,OAAA,eACA,EAAA,OAAA,oBACA,EAAA,OAAA,wBAmCA,GAAA,OAwBA,IAAA,GAAA,UAAA,KAAA,UAAA,WAIA,GACA,IAAA,aACA,IAAA,aACA,cAAA,EACA,YAAA,GAuJA,EAAA,OAAA,kBACA,EAAA,OAAA,YACA,EAAA,OAAA,MACA,EAAA,OAAA,KACA,EAAA,OAAA,OACA,EAAA,OAAA,MACA,EAAA,OAAA,yBACA,EAAA,OAAA,sBACA,EAAA,OAAA,kBAqHA,GAAA,OAAA,EACA,EAAA,iBAAA,EACA,EAAA,aAAA,EACA,EAAA,iBAAA,EACA,EAAA,wBAAA,EACA,EAAA,UAAA,EACA,EAAA,aAAA,EACA,EAAA,MAAA,EACA,EAAA,qBAAA,EACA,EAAA,MAAA,EACA,EAAA,eAAA,EACA,EAAA,gBAAA,EACA,EAAA,OAAA,EACA,EAAA,OAAA,EACA,EAAA,eAAA,EACA,EAAA,KAAA,EACA,EAAA,aAAA,EACA,EAAA,SAAA,GAEA,OAAA,mBCtYA,SAAA,GACA,YAOA,SAAA,KACA,GAAA,CACA,IAAA,GAAA,EAAA,MAAA,EACA,KACA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,KAmBA,QAAA,GAAA,GACA,EAAA,KAAA,GACA,IAEA,GAAA,EACA,EAAA,EAAA,IAlCA,GAGA,GAHA,EAAA,OAAA,iBACA,KACA,GAAA,CAYA,IAAA,EAAA,CACA,GAAA,GAAA,EACA,EAAA,GAAA,GAAA,GACA,EAAA,SAAA,eAAA,EACA,GAAA,QAAA,GAAA,eAAA,IAEA,EAAA,WACA,GAAA,EAAA,GAAA,EACA,EAAA,KAAA,OAIA,GAAA,OAAA,cAAA,OAAA,UAWA,GAAA,kBAAA,GAEA,OAAA,mBC1CA,SAAA,GACA,YAUA,SAAA,KACA,IAEA,EAAA,GACA,GAAA,GAIA,QAAA,KACA,GAAA,CAEA,GAGA,KAAA,GAFA,GAAA,EAAA,QACA,GAAA,EACA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,aACA,GAAA,GACA,EAAA,SACA,EAAA,UAAA,EAAA,GACA,GAAA,SAGA,GAQA,QAAA,GAAA,EAAA,GACA,KAAA,KAAA,EACA,KAAA,OAAA,EACA,KAAA,WAAA,GAAA,GAAA,SACA,KAAA,aAAA,GAAA,GAAA,SACA,KAAA,gBAAA,KACA,KAAA,YAAA,KACA,KAAA,cAAA,KACA,KAAA,mBAAA,KACA,KAAA,SAAA,KASA,QAAA,GAAA,EAAA,GACA,KAAA,EAAA,EAAA,EAAA,WAAA,CACA,GAAA,GAAA,EAAA,IAAA,EACA,IAAA,EAEA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,QAAA,SACA,EAAA,qBAAA,KAKA,QAAA,GAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,OAAA,GACA,EAAA,EAAA,IAAA,EACA,KAAA,EACA,MACA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,WAAA,GACA,EAAA,6BAMA,QAAA,GAAA,EAAA,EAAA,GAMA,IAAA,GAJA,GAAA,OAAA,OAAA,MACA,EAAA,OAAA,OAAA,MAGA,EAAA,EAAA,EAAA,EAAA,EAAA,WAAA,CAEA,GAAA,GAAA,EAAA,IAAA,EACA,IAAA,EAEA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,OAEA,KAAA,IAAA,GAAA,EAAA,YAIA,eAAA,IAAA,EAAA,YAMA,eAAA,GAAA,EAAA,kBACA,OAAA,EAAA,WACA,KAAA,EAAA,gBAAA,QAAA,EAAA,QAKA,kBAAA,IAAA,EAAA,eAIA,cAAA,IAAA,EAAA,WAAA,CAIA,GAAA,GAAA,EAAA,QACA,GAAA,EAAA,MAAA,GAMA,eAAA,GAAA,EAAA,mBACA,kBAAA,GAAA,EAAA,yBACA,EAAA,EAAA,MAAA,EAAA,YAKA,GAAA,IAAA,CAGA,KAAA,GAAA,KAAA,GAAA,CACA,GAAA,GAAA,EAAA,GACA,EAAA,GAAA,GAAA,EAAA,EAGA,SAAA,IAAA,aAAA,KACA,EAAA,cAAA,EAAA,KACA,EAAA,mBAAA,EAAA,WAIA,EAAA,aACA,EAAA,WAAA,EAAA,YAGA,EAAA,eACA,EAAA,aAAA,EAAA,cAGA,EAAA,kBACA,EAAA,gBAAA,EAAA,iBAGA,EAAA,cACA,EAAA,YAAA,EAAA,aAGA,SAAA,EAAA,KACA,EAAA,SAAA,EAAA,IAGA,EAAA,SAAA,KAAA,GAEA,GAAA,EAGA,GACA,IASA,QAAA,GAAA,GAqBA,GApBA,KAAA,YAAA,EAAA,UACA,KAAA,UAAA,EAAA,QAQA,KAAA,WAJA,cAAA,MACA,qBAAA,IAAA,mBAAA,MAGA,EAAA,YAFA,EAQA,KAAA,cADA,yBAAA,MAAA,iBAAA,KACA,IAEA,EAAA,eAGA,KAAA,aACA,EAAA,mBAAA,mBAAA,MAEA,KAAA,eAAA,EAAA,sBACA,KAAA,IAAA,UAMA,IAHA,KAAA,gBAAA,EAAA,cACA,KAAA,oBAAA,EAAA,kBACA,KAAA,wBAAA,EAAA,sBACA,mBAAA,GAAA,CACA,GAAA,MAAA,EAAA,iBACA,gBAAA,GAAA,gBACA,KAAA,IAAA,UAEA,MAAA,gBAAA,EAAA,KAAA,EAAA,qBAEA,MAAA,gBAAA,KAWA,QAAA,GAAA,GACA,KAAA,UAAA,EACA,KAAA,UACA,KAAA,YACA,KAAA,OAAA,EAGA,EAAA,KAAA,MAiEA,QAAA,GAAA,EAAA,EAAA,GACA,KAAA,SAAA,EACA,KAAA,OAAA,EACA,KAAA,QAAA,EACA,KAAA,0BAzTA,GAAA,GAAA,EAAA,kBACA,EAAA,EAAA,aACA,EAAA,EAAA,SAEA,EAAA,GAAA,SACA,KACA,GAAA,EAgLA,EAAA,MAAA,UAAA,MAgDA,EAAA,CAiBA,GAAA,WAEA,QAAA,SAAA,EAAA,GACA,EAAA,EAAA,EAEA,IAGA,GAHA,EAAA,GAAA,GAAA,GAIA,EAAA,EAAA,IAAA,EACA,IACA,EAAA,IAAA,EAAA,KAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,WAAA,OACA,EAAA,EAAA,GAEA,EAAA,2BAEA,EAAA,QAAA,EAKA,KACA,EAAA,GAAA,GAAA,KAAA,EAAA,GACA,EAAA,KAAA,GACA,KAAA,OAAA,KAAA,KAKA,WAAA,WACA,KAAA,OAAA,QAAA,SAAA,GAEA,IAAA,GADA,GAAA,EAAA,IAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IAAA,EAAA,WAAA,KAAA,CACA,EAAA,OAAA,EAAA,EAGA,UAGA,MACA,KAAA,aAGA,YAAA,WACA,GAAA,GAAA,KAAA,QAEA,OADA,MAAA,YACA,IAkBA,EAAA,WAMA,qBAAA,SAAA,GAGA,GAAA,IAAA,KAAA,OAAA,CAGA,KAAA,uBAAA,KAAA,EACA,IAAA,GAAA,EAAA,IAAA,EACA,IACA,EAAA,IAAA,EAAA,MAIA,EAAA,KAAA,QAGA,yBAAA,WACA,GAAA,GAAA,KAAA,sBACA,MAAA,yBAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAGA,IAAA,GAFA,GAAA,EAAA,GACA,EAAA,EAAA,IAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,GAAA,EAAA,KAAA,KAAA,CACA,EAAA,OAAA,EAAA,EAGA,UAOA,EAAA,gBAAA,EACA,EAAA,2BAAA,EACA,EAAA,SAAA,iBAAA,EACA,EAAA,SAAA,eAAA,GAEA,OAAA,mBC7WA,SAAA,GACA,YAQA,SAAA,GAAA,EAAA,GACA,KAAA,KAAA,EACA,KAAA,OAAA,EAoBA,QAAA,GAAA,EAAA,GACA,GAAA,EAAA,aAAA,EAAA,CACA,EAAA,WAAA,CACA,KAAA,GAAA,GAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,EAAA,IAKA,QAAA,GAAA,GACA,GAAA,EAAA,WACA,MAAA,GAAA,UACA,IACA,GADA,EAAA,EAAA,UAMA,OAHA,GADA,EACA,EAAA,GAEA,GAAA,GAAA,EAAA,MACA,EAAA,WAAA,EAnCA,EAAA,WACA,GAAA,YACA,MAAA,MAAA,eAAA,GAAA,SAAA,WACA,EAAA,mBAAA,KAAA,KAAA,MAEA,MAGA,SAAA,SAAA,GACA,KAAA,EAAA,EAAA,EAAA,OACA,GAAA,IAAA,KACA,OAAA,CAEA,QAAA,IAyBA,EAAA,UAAA,EACA,EAAA,aAAA,EACA,EAAA,aAAA,GAEA,OAAA,mBC1DA,SAAA,GACA,YAuBA,SAAA,GAAA,GACA,MAAA,aAAA,GAAA,WAGA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,SACA,OAAA,YAAA,GAAA,WAAA,EAGA,QAAA,GAAA,GACA,QAAA,EAAA,WAGA,QAAA,GAAA,GACA,GAAA,EACA,OAAA,GAAA,aAAA,EAAA,EAAA,cAAA,EAAA,IAAA,KAIA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,EAAA,OACA,MAAA,GAAA,OAGA,IAAA,EAAA,GACA,MAAA,GAAA,IAAA,EAAA,IAGA,IAAA,GAAA,EAAA,kBAAA,IAAA,EACA,IAAA,EAAA,CAEA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GAAA,EAAA,EAEA,OAAA,GAAA,GAIA,GAAA,GAAA,EAAA,GAAA,CACA,GAAA,GAAA,EAAA,UACA,IAAA,GAAA,EAAA,GAGA,IAAA,GAFA,GAAA,EAAA,eAAA,GACA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,GAAA,EAAA,GAAA,SAAA,GACA,MAAA,GAKA,MAAA,GAAA,GAIA,QAAA,GAAA,GAKA,IAJA,GAAA,MACA,EAAA,EACA,KACA,KACA,GAAA,CACA,GAAA,GAAA,IAGA,IAAA,EAAA,GAAA,CACA,EAAA,EAAA,EACA,IAAA,GAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,KAAA,OACA,GAAA,QACA,EAAA,KAAA,EAEA,IAAA,GAAA,EAAA,EAAA,OAAA,EACA,GAAA,MAAA,OAAA,EAAA,cAAA,IACA,EAAA,IACA,EAAA,MAEA,EAAA,EAAA,EAAA,EAAA,GAEA,MAAA,GAGA,QAAA,GAAA,GACA,IAAA,GAAA,GAAA,EAAA,OAAA,EAAA,GAAA,EAAA,IACA,IAAA,EAAA,EAAA,IACA,MAAA,GAAA,EAEA,OAAA,MAIA,QAAA,GAAA,EAAA,GAEA,IADA,GAAA,MACA,GAAA,CAIA,IAHA,GAAA,MACA,EAAA,EACA,EAAA,OACA,GAAA,CACA,GAAA,GAAA,IACA,IAAA,EAAA,QAGA,GAAA,EAAA,KACA,EAAA,EAAA,GAGA,EAAA,IAAA,CACA,GAAA,GAAA,EAAA,EAAA,OAAA,EACA,GAAA,KAAA,QARA,GAAA,KAAA,EAaA,IAAA,EAAA,EAAA,GACA,MAAA,GAAA,EAAA,OAAA,EAEA,GAAA,IACA,EAAA,MAEA,EAAA,EACA,EAAA,EAAA,EAAA,EAAA,GAGA,EADA,EAAA,GACA,EAAA,KAEA,EAAA,YAIA,QAAA,GAAA,GACA,MAAA,GAAA,qBAAA,IAAA,GAGA,QAAA,GAAA,GACA,MAAA,GAAA,GAGA,QAAA,GAAA,EAAA,GACA,MAAA,GAAA,KAAA,EAAA,GAGA,QAAA,GAAA,GAEA,MAAA,GAAA,IAAA,GAAA,QAEA,EAAA,IAAA,GAAA,GAEA,EAAA,EAAA,GAAA,EAAA,EAAA,UAGA,QAAA,GAAA,EAAA,GACA,GAAA,EAAA,IAAA,GACA,KAAA,IAAA,OAAA,oBACA,GAAA,IAAA,GAAA,GAGA,EAAA,kBACA,IAAA,GAAA,EAAA,EA0BA,OAlBA,SAAA,EAAA,MACA,IAAA,EAAA,QACA,EAAA,GAAA,iBAAA,GAAA,UACA,EAAA,QAGA,EAAA,IAAA,EAAA,GAEA,EAAA,EAAA,IACA,EAAA,EAAA,IACA,EAAA,EAAA,GAIA,EAAA,IAAA,EAAA,EAAA,MACA,EAAA,OAAA,EAAA,MACA,EAAA,OAAA,GAEA,EAAA,iBAGA,QAAA,GAAA,EAAA,GAGA,IAAA,GAFA,GAEA,EAAA,EAAA,OAAA,EAAA,EAAA,EAAA,IAAA,CACA,GAAA,GAAA,EAAA,GAAA,OACA,EAAA,EAAA,GAAA,aACA,IAAA,IAAA,IAGA,EAAA,EAAA,iBACA,EAAA,EAAA,GAAA,EAAA,IACA,OAAA,EAGA,OAAA,EAGA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,SACA,OAAA,GAAA,EAAA,GAAA,EAAA,GAGA,QAAA,GAAA,EAAA,GAIA,IAAA,GAFA,GADA,EAAA,EAAA,QAGA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,GAAA,OACA,EAAA,EAAA,GAAA,aACA,IAAA,IAAA,EACA,EAAA,EAAA,cACA,CAAA,IAAA,GAAA,EAAA,IAAA,GAGA,QAFA,GAAA,EAAA,eAIA,IAAA,EAAA,EAAA,GAAA,EAAA,GACA,QAIA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,OACA,EAAA,EAAA,cAEA,EAAA,EAAA,IAAA,EACA,KAAA,EACA,OAAA,CAEA,IAAA,iBAAA,GAAA,CACA,GAAA,GAAA,EAAA,EAKA,IAAA,EAAA,cAAA,CACA,GAAA,GAAA,EAAA,EAAA,eAEA,EAAA,EAAA,EAAA,EACA,IAAA,IAAA,EACA,OAAA,CAEA,GAAA,IAAA,EAAA,IAIA,EAAA,IAAA,EAAA,EACA,IAAA,GAAA,EAAA,KAEA,GAAA,CACA,GAAA,IAAA,EAAA,GACA,EAAA,IAAA,EAAA,EAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IAAA,EAAA,QACA,GAAA,MAIA,MAAA,EAAA,OAAA,IACA,EAAA,SAAA,IAAA,EAAA,iBACA,EAAA,SAAA,IAAA,EAAA,gBAIA,IAMA,GALA,kBAAA,GAAA,QACA,EAAA,QAAA,KAAA,EAAA,GAEA,EAAA,QAAA,YAAA,GAEA,EAAA,IAAA,GACA,OAAA,EAEA,MAAA,GACA,OAAA,QACA,OAAA,QAAA,EAAA,SAEA,QAAA,MAAA,EAAA,EAAA,QAIA,GAAA,EAAA,CACA,GAAA,GAAA,EAAA,OACA,GAAA,OAAA,CACA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,SACA,EAAA,KAAA,EAAA,IAIA,OAAA,EAAA,IAAA,GAGA,QAAA,GAAA,EAAA,EAAA,GACA,KAAA,KAAA,EACA,KAAA,QAAA,EACA,KAAA,QAAA,QAAA,GA6BA,QAAA,GAAA,EAAA,GACA,MAAA,aAAA,QACA,KAAA,KAAA,GAEA,EAAA,EAAA,EAAA,QAAA,EAAA,IA2CA,QAAA,GAAA,GACA,MAAA,IAAA,EAAA,cAEA,OAAA,OAAA,GACA,eAAA,MAAA,EAAA,EAAA,kBAFA,EAMA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,OAAA,GACA,EAAA,SAAA,EAAA,GACA,MAAA,aAAA,QACA,KAAA,KAAA,GAEA,EAAA,EAAA,EAAA,EAAA,EAAA,IAKA,IAHA,EAAA,UAAA,OAAA,OAAA,EAAA,WACA,GACA,EAAA,EAAA,UAAA,GACA,EAMA,IACA,EAAA,EAAA,EAAA,GAAA,GAAA,SACA,MAAA,GACA,EAAA,EAAA,EACA,SAAA,YAAA,IAGA,MAAA,GAYA,QAAA,GAAA,EAAA,GACA,MAAA,YACA,UAAA,GAAA,EAAA,UAAA,GACA,IAAA,GAAA,EAAA,KACA,GAAA,GAAA,MAAA,EAAA,YAgCA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,GAAA,GACA,MAAA,IAAA,GAAA,EAAA,EAAA,GAGA,IAAA,GAAA,EAAA,SAAA,YAAA,IACA,EAAA,GAAA,GACA,GAAA,EASA,OARA,QAAA,KAAA,GAAA,QAAA,SAAA,GACA,GAAA,GAAA,MAAA,GAAA,IAAA,GACA,EAAA,GAAA,EAAA,EACA,mBAAA,IACA,EAAA,EAAA,IACA,EAAA,KAAA,KAEA,EAAA,OAAA,GAAA,MAAA,EAAA,GACA,EAiCA,QAAA,KACA,EAAA,KAAA,MAYA,QAAA,GAAA,GACA,MAAA,kBAAA,IACA,EACA,GAAA,EAAA,YAGA,QAAA,GAAA,GACA,OAAA,GACA,IAAA,kBACA,IAAA,0BACA,IAAA,2BACA,IAAA,wBACA,IAAA,kBACA,IAAA,8BACA,IAAA,iBACA,IAAA,6BACA,IAAA,qBACA,OAAA,EAEA,OAAA,EAUA,QAAA,GAAA,GACA,KAAA,KAAA,EAkBA,QAAA,GAAA,GAGA,MAFA,aAAA,GAAA,aACA,EAAA,EAAA,MACA,EAAA,GAqFA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,IAAA,EACA,IAAA,EACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,IAAA,EAAA,GAAA,SAAA,EAAA,GAAA,OAAA,EACA,OAAA,CAGA,QAAA,EAGA,QAAA,GAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,GAAA,EAAA,EAAA,EAAA,WACA,GAAA,EAAA,EAAA,GAAA,GACA,OAAA,CAEA,QAAA,EAMA,QAAA,GAAA,GACA,EAAA,EAAA,IAKA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,EAAA,kBAIA,KAAA,GAFA,GAAA,EAAA,GAAA,KAAA,EAAA,KAAA,EAAA,IACA,EAAA,EAAA,EAAA,MACA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IAAA,EAAA,gBAAA,EACA,MAAA,GAAA,OAEA,MAAA,MAQA,QAAA,GAAA,GACA,MAAA,YACA,GAAA,GAAA,EAAA,IAAA,KACA,OAAA,IAAA,EAAA,IACA,EAAA,GAAA,OAAA,MASA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,MAAA,EACA,OAAA,UAAA,GACA,GAAA,GAAA,EAAA,IAAA,KACA,KACA,EAAA,OAAA,OAAA,MACA,EAAA,IAAA,KAAA,GAGA,IAAA,GAAA,EAAA,EAIA,IAHA,GACA,KAAA,oBAAA,EAAA,EAAA,SAAA,GAEA,kBAAA,GAAA,CACA,GAAA,GAAA,SAAA,GACA,GAAA,GAAA,EAAA,KAAA,KAAA,EACA,MAAA,EACA,EAAA,iBACA,mBAAA,GAAA,gBAAA,KACA,EAAA,YAAA,GAKA,MAAA,iBAAA,EAAA,GAAA,GACA,EAAA,IACA,MAAA,EACA,QAAA,KA3vBA,GAAA,GAAA,EAAA,wBACA,EAAA,EAAA,aACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,KACA,EAAA,EAAA,SAGA,GADA,GAAA,SACA,GAAA,UACA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,QAkTA,GAAA,WACA,OAAA,SAAA,GACA,MAAA,MAAA,UAAA,EAAA,SAAA,KAAA,OAAA,EAAA,MACA,KAAA,UAAA,EAAA,SAEA,GAAA,WACA,MAAA,QAAA,KAAA,SAEA,OAAA,WACA,KAAA,QAAA,MAIA,IAAA,GAAA,OAAA,KACA,GAAA,UAAA,mBACA,aAAA,EAGA,aAAA,GAeA,EAAA,WACA,GAAA,UACA,MAAA,GAAA,IAAA,OAEA,GAAA,iBACA,MAAA,GAAA,IAAA,OAEA,GAAA,cACA,MAAA,GAAA,IAAA,OAEA,GAAA,QACA,GAAA,GAAA,GAAA,GAAA,SACA,EAAA,EAAA,IAAA,KACA,IAAA,EAAA,CAKA,IAAA,GAJA,GAAA,EACA,EAAA,EAAA,OAAA,EACA,EAAA,EAAA,EAAA,IAAA,OAEA,EAAA,EAAA,GAAA,EAAA,IAAA,CACA,GAAA,GAAA,EAAA,GAAA,cACA,EAAA,EAAA,EACA,GAAA,SAAA,KAEA,IAAA,GAAA,YAAA,GAAA,QACA,EAAA,KAAA,GAGA,EAAA,OAAA,EAEA,MAAA,IAEA,gBAAA,WACA,EAAA,IAAA,MAAA,IAEA,yBAAA,WACA,EAAA,IAAA,MAAA,GACA,EAAA,IAAA,MAAA,KAGA,EAAA,EAAA,EAAA,SAAA,YAAA,SAqCA;GAAA,IAAA,EAAA,UAAA,GACA,GAAA,EAAA,cAAA,GAEA,IACA,GAAA,iBACA,MAAA,GAAA,IAAA,OAAA,EAAA,EAAA,MAAA,iBAYA,GAAA,GACA,eAAA,EAAA,iBAAA,KACA,IAEA,GAAA,GACA,eAAA,EAAA,iBAAA,IACA,IAEA,GAAA,EAAA,aAAA,GAAA,IACA,GAAA,EAAA,aAAA,GAAA,IAKA,GAAA,OAAA,OAAA,MAEA,GAAA,WACA,IACA,GAAA,QAAA,WAAA,SACA,MAAA,GACA,OAAA,EAEA,OAAA,IAyBA,KAAA,GAAA,CACA,GAAA,IAAA,SAAA,EAAA,EAAA,GACA,GAAA,EAAA,CACA,GAAA,GAAA,GAAA,EACA,GAAA,EAAA,KAAA,GAAA,GAGA,GAAA,GAAA,EAKA,IAAA,SAAA,SAAA,EAAA,YAAA,IACA,GAAA,eAAA,OAAA,MAAA,SACA,GAAA,WAAA,KAAA,KAAA,OAAA,GAAA,SACA,GAAA,cACA,QAAA,EACA,QAAA,EACA,QAAA,EACA,QAAA,EACA,SAAA,EACA,QAAA,EACA,UAAA,EACA,SAAA,EACA,OAAA,EACA,cAAA,MACA,WACA,GAAA,cAAA,cAAA,MAAA,WAMA,EAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,eACA,MAAA,MAAA,KAAA,aAEA,GAAA,aAAA,GACA,KAAA,KAAA,YAAA,IA0BA,IAAA,IAAA,OAAA,YAaA,IACA,mBACA,sBACA,kBAGA,KAAA,QAAA,QAAA,SAAA,GACA,GAAA,GAAA,EAAA,SACA,IAAA,QAAA,SAAA,GACA,OAAA,eAAA,EAAA,EAAA,KAAA,MAAA,EAAA,SAUA,EAAA,WACA,iBAAA,SAAA,EAAA,EAAA,GACA,GAAA,EAAA,KAAA,EAAA,GAAA,CAGA,GAAA,GAAA,GAAA,GAAA,EAAA,EAAA,GACA,EAAA,EAAA,IAAA,KACA,IAAA,GAKA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,GAAA,EAAA,OAAA,EAAA,IACA,WANA,MACA,EAAA,IAAA,KAAA,EASA,GAAA,KAAA,EAEA,IAAA,GAAA,EAAA,KACA,GAAA,kBAAA,EAAA,GAAA,KAEA,oBAAA,SAAA,EAAA,EAAA,GACA,EAAA,QAAA,EACA,IAAA,GAAA,EAAA,IAAA,KACA,IAAA,EAAA,CAGA,IAAA,GADA,GAAA,EAAA,GAAA,EACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,OAAA,GAAA,EAAA,GAAA,UAAA,IACA,IACA,EAAA,GAAA,UAAA,IACA,GAAA,EACA,EAAA,GAAA,UAKA,IAAA,GAAA,IAAA,EAAA,CACA,GAAA,GAAA,EAAA,KACA,GAAA,qBAAA,EAAA,GAAA,MAGA,cAAA,SAAA,GAWA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,IAKA,GAAA,IAAA,GAAA,GAIA,EAAA,kBAEA,IAAA,EACA,GAAA,KAAA,KACA,EAAA,aACA,KAAA,iBAAA,EAAA,GAAA,GAGA,KACA,MAAA,GAAA,MAAA,eAAA,GACA,QACA,GACA,KAAA,oBAAA,EAAA,GAAA,MAwBA,IACA,EAAA,GAAA,EAMA,IAAA,IAAA,SAAA,gBAkEA,GAAA,oBAAA,EACA,EAAA,iBAAA,EACA,EAAA,sBAAA,EACA,EAAA,sBAAA,EACA,EAAA,uBAAA,EACA,EAAA,SAAA,kBAAA,EACA,EAAA,SAAA,YAAA,GACA,EAAA,SAAA,MAAA,EACA,EAAA,SAAA,YAAA,EACA,EAAA,SAAA,WAAA,GACA,EAAA,SAAA,WAAA,GACA,EAAA,SAAA,QAAA,IAEA,OAAA,mBCjxBA,SAAA,GACA,YAIA,SAAA,GAAA,EAAA,GACA,OAAA,eAAA,EAAA,GAAA,YAAA,IAGA,QAAA,KACA,KAAA,OAAA,EACA,EAAA,KAAA,UASA,QAAA,GAAA,GACA,GAAA,MAAA,EACA,MAAA,EAEA,KAAA,GADA,GAAA,GAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,IACA,EAAA,GAAA,EAAA,EAAA,GAGA,OADA,GAAA,OAAA,EACA,EAGA,QAAA,GAAA,EAAA,GACA,EAAA,UAAA,GAAA,WACA,MAAA,GAAA,KAAA,KAAA,GAAA,MAAA,KAAA,KAAA,aA9BA,GAAA,GAAA,EAAA,IAUA,GAAA,WACA,KAAA,SAAA,GACA,MAAA,MAAA,KAGA,EAAA,EAAA,UAAA,QAmBA,EAAA,SAAA,SAAA,EACA,EAAA,sBAAA,EACA,EAAA,aAAA,GAEA,OAAA,mBCvCA,SAAA,GACA,YAIA,GAAA,mBAAA,EAAA,aACA,EAAA,SAAA,eAAA,EAAA,SAAA,UAEA,OAAA,mBCRA,SAAA,GACA,YAmBA,SAAA,GAAA,GACA,EAAA,YAAA,IAGA,QAAA,GAAA,GACA,GAAA,GAAA,GAAA,EAGA,OAFA,GAAA,GAAA,EACA,EAAA,OAAA,EACA,EAYA,QAAA,GAAA,EAAA,EAAA,GACA,EAAA,EAAA,aACA,aAAA,EACA,gBAAA,EAAA,gBACA,YAAA,EAAA,cAIA,QAAA,GAAA,EAAA,GACA,EAAA,EAAA,aACA,aAAA,IAUA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,GAAA,YAAA,kBAAA,CACA,GAAA,GAAA,EAAA,EAGA,IAAA,CACA,KAAA,GAAA,GAAA,EAAA,OAAA,EAAA,GAAA,EAAA,IACA,EAAA,YAAA,EAAA,IACA,EAAA,GAAA,YAAA,CAEA,IAAA,CAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,iBAAA,EAAA,EAAA,IAAA,EACA,EAAA,GAAA,aAAA,EAAA,EAAA,IAAA,CAQA,OALA,KACA,EAAA,aAAA,EAAA,IACA,IACA,EAAA,iBAAA,EAAA,EAAA,OAAA,IAEA,EAGA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,UAcA,OAbA,IAEA,EAAA,YAAA,GAGA,EAAA,YAAA,EACA,EAAA,iBAAA,EACA,EAAA,aAAA,EACA,IACA,EAAA,aAAA,GACA,IACA,EAAA,iBAAA,GAEA,EAGA,QAAA,GAAA,GACA,GAAA,YAAA,kBACA,MAAA,GAAA,EAEA,IAAA,GAAA,EAAA,GACA,EAAA,EAAA,UAGA,OAFA,IACA,EAAA,EAAA,EAAA,GACA,EAGA,QAAA,GAAA,GAGA,IAAA,GAFA,GAAA,GAAA,GACA,EAAA,EACA,EAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,KAAA,CAIA,OAFA,GAAA,OAAA,EACA,EAAA,EAAA,GACA,EAGA,QAAA,GAAA,GAEA,MAAA,GAIA,QAAA,GAAA,EAAA,GACA,EAAA,EAAA,GACA,EAAA,kBAGA,QAAA,GAAA,EAAA,GAEA,IAAA,GADA,GAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GAAA,GAKA,QAAA,GAAA,GACA,EAAA,EAAA,GAAA,GAAA,EAAA,OAGA,QAAA,GAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,IAIA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,WAAA,EAAA,cACA,EAAA,EAAA,aACA,KAAA,EAAA,eACA,EAAA,UAAA,GAGA,QAAA,GAAA,EAAA,GACA,GAAA,EAAA,OAAA,CAGA,GAAA,GAAA,EAAA,aAGA,IAAA,IAAA,EAAA,GAAA,cAGA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,kBAAA,EAAA,GAAA,IAIA,QAAA,GAAA,EAAA,GACA,EAAA,EAAA,EACA,IAAA,GAAA,EAAA,MAEA,IAAA,IAAA,EACA,MAAA,GAAA,EAAA,GAGA,KAAA,GADA,GAAA,EAAA,EAAA,cAAA,0BACA,EAAA,EAAA,EAAA,EAAA,IACA,EAAA,YAAA,EAAA,EAAA,IAEA,OAAA,GAGA,QAAA,GAAA,GACA,GAAA,SAAA,EAAA,YAEA,IADA,GAAA,GAAA,EAAA,YACA,GAAA,CACA,GAAA,GAAA,CACA,GAAA,EAAA,aACA,EAAA,YAAA,EAAA,iBAAA,EAAA,aAAA,OAGA,EAAA,YAAA,EAAA,WAAA,OAGA,QAAA,GAAA,GACA,GAAA,EAAA,2BAAA,CAEA,IADA,GAAA,GAAA,EAAA,WACA,GAAA,CACA,EAAA,EAAA,aAAA,EACA,IAAA,GAAA,EAAA,YACA,EAAA,EAAA,GACA,EAAA,EAAA,UACA,IACA,EAAA,KAAA,EAAA,GACA,EAAA,iBAAA,EAAA,aACA,EAAA,YAAA,KACA,EAAA,EAEA,EAAA,YAAA,EAAA,WAAA,SAKA,KAHA,GAEA,GAFA,EAAA,EAAA,GACA,EAAA,EAAA,WAEA,GACA,EAAA,EAAA,YACA,EAAA,KAAA,EAAA,GACA,EAAA,EAKA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,UACA,OAAA,IAAA,EAAA,2BAGA,QAAA,GAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GACA,EAAA,WAAA,YAAA,GAOA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,EAMA,IAJA,EAAA,EADA,EACA,EAAA,KAAA,EAAA,EAAA,MAAA,GAEA,EAAA,KAAA,EAAA,MAAA,IAEA,EAAA,CACA,IAAA,GAAA,GAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,YAAA,EAAA,GAAA,EAAA,GAGA,IAAA,YAAA,GAAA,oBAEA,IAAA,GADA,GAAA,EAAA,QACA,EAAA,EAAA,QAAA,WACA,EACA,EAAA,EAAA,YACA,EAAA,YAAA,EAAA,GAAA,EAAA,IAKA,MAAA,GAGA,QAAA,GAAA,EAAA,GACA,IAAA,GAAA,EAAA,KAAA,EAAA,GACA,OAAA,CAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,WACA,GAAA,IAAA,EACA,OAAA,CAEA,QAAA,EAWA,QAAA,GAAA,GACA,EAAA,YAAA,IAEA,EAAA,KAAA,KAAA,GAUA,KAAA,YAAA,OAMA,KAAA,YAAA,OAMA,KAAA,WAAA,OAMA,KAAA,aAAA,OAMA,KAAA,iBAAA,OAEA,KAAA,WAAA,OApUA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,SAAA,SACA,EAAA,EAAA,UACA,EAAA,EAAA,OACA,EAAA,EAAA,iBACA,EAAA,EAAA,gBACA,EAAA,EAAA,aACA,EAAA,EAAA,UACA,EAAA,EAAA,MACA,EAAA,EAAA,2BACA,EAAA,EAAA,gBACA,EAAA,EAAA,aACA,EAAA,EAAA,OACA,EAAA,EAAA,KACA,EAAA,EAAA,aACA,EAAA,EAAA,SAaA,GAAA,EAkNA,EAAA,SAAA,WACA,EAAA,OAAA,KAAA,UAAA,UAsCA,EAAA,OAAA,KAkDA,EAAA,OAAA,iBAEA,GADA,EAAA,UAAA,YAEA,EAAA,UAAA,yBACA,EAAA,EAAA,UAAA,aACA,EAAA,EAAA,UAAA,YACA,EAAA,EAAA,UAAA,aAEA,EAAA,UAAA,KAAA,UAAA,WAEA,EAAA,EACA,SAAA,EAAA,GACA,IACA,EAAA,KAAA,EAAA,GACA,MAAA,GACA,KAAA,YAAA,IACA,KAAA,KAGA,SAAA,EAAA,GACA,EAAA,KAAA,EAAA,GAGA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,YAAA,SAAA,GACA,MAAA,MAAA,aAAA,EAAA,OAGA,aAAA,SAAA,EAAA,GACA,EAAA,EAEA,IAAA,EACA,GACA,EAAA,GACA,EAAA,EAAA,IAEA,EAAA,EACA,EAAA,EAAA,KAGA,EAAA,KACA,EAAA,MAGA,GAAA,EAAA,EAAA,aAAA,KAEA,IAAA,GACA,EACA,EAAA,EAAA,gBAAA,KAAA,UAEA,GAAA,KAAA,6BACA,EAAA,EAOA,IAJA,EADA,EACA,EAAA,GAEA,EAAA,EAAA,KAAA,EAAA,GAEA,EACA,EAAA,KAAA,GACA,EAAA,MACA,EAAA,KAAA,KAAA,KAAA,EAAA,GAAA,OACA,CACA,IACA,KAAA,YAAA,EAAA,IACA,IACA,KAAA,WAAA,EAAA,EAAA,OAAA,GAEA,IAAA,GAAA,EAAA,EAAA,WAAA,KAAA,IAGA,GACA,EAAA,KAAA,EACA,EAAA,KAAA,GAAA,GAEA,EAAA,KAAA,GAYA,MARA,GAAA,KAAA,aACA,WAAA,EACA,YAAA,EACA,gBAAA,IAGA,EAAA,EAAA,MAEA,GAGA,YAAA,SAAA,GAEA,GADA,EAAA,GACA,EAAA,aAAA,KAAA,CAIA,IAAA,GAFA,IAAA,EAEA,GADA,KAAA,WACA,KAAA,YAAA,EACA,EAAA,EAAA,YACA,GAAA,IAAA,EAAA,CACA,GAAA,CACA,OAGA,IAAA,EAEA,KAAA,IAAA,OAAA,iBAIA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,YACA,EAAA,EAAA,eAEA,IAAA,KAAA,2BAAA,CAIA,GAAA,GAAA,KAAA,WACA,EAAA,KAAA,UAEA,EAAA,EAAA,UACA,IACA,EAAA,EAAA,GAEA,IAAA,IACA,KAAA,YAAA,GACA,IAAA,IACA,KAAA,WAAA,GACA,IACA,EAAA,aAAA,GACA,IACA,EAAA,iBACA,GAGA,EAAA,iBAAA,EAAA,aACA,EAAA,YAAA,WAEA,GAAA,MACA,EAAA,KAAA,KAAA,EAaA,OAVA,IACA,EAAA,KAAA,aACA,aAAA,EAAA,GACA,YAAA,EACA,gBAAA,IAIA,EAAA,KAAA,GAEA,GAGA,aAAA,SAAA,EAAA,GACA,EAAA,EAEA,IAAA,EAQA,IAPA,EAAA,GACA,EAAA,EAAA,IAEA,EAAA,EACA,EAAA,EAAA,IAGA,EAAA,aAAA,KAEA,KAAA,IAAA,OAAA,gBAGA,IAEA,GAFA,EAAA,EAAA,YACA,EAAA,EAAA,gBAGA,GAAA,KAAA,6BACA,EAAA,EA2CA,OAzCA,GACA,EAAA,EAAA,IAEA,IAAA,IACA,EAAA,EAAA,aACA,EAAA,EAAA,EAAA,KAAA,EAAA,IAGA,GAiBA,EAAA,KAAA,GACA,EAAA,MACA,EAAA,KAAA,KAAA,KAAA,EAAA,GACA,KAnBA,KAAA,aAAA,IACA,KAAA,YAAA,EAAA,IACA,KAAA,YAAA,IACA,KAAA,WAAA,EAAA,EAAA,OAAA,IAEA,EAAA,iBAAA,EAAA,aACA,EAAA,YAAA,OAGA,EAAA,YACA,EAAA,KACA,EAAA,WACA,EAAA,KAAA,GACA,IASA,EAAA,KAAA,aACA,WAAA,EACA,aAAA,EAAA,GACA,YAAA,EACA,gBAAA,IAGA,EAAA,GACA,EAAA,EAAA,MAEA,GAQA,gBAAA,WACA,IAAA,GAAA,GAAA,KAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,mBAIA,cAAA,WACA,MAAA,QAAA,KAAA,YAIA,GAAA,cAEA,MAAA,UAAA,KAAA,YACA,KAAA,YAAA,EAAA,KAAA,KAAA,aAIA,GAAA,cACA,MAAA,UAAA,KAAA,YACA,KAAA,YAAA,EAAA,KAAA,KAAA,aAIA,GAAA,aACA,MAAA,UAAA,KAAA,WACA,KAAA,WAAA,EAAA,KAAA,KAAA,YAIA,GAAA,eACA,MAAA,UAAA,KAAA,aACA,KAAA,aAAA,EAAA,KAAA,KAAA,cAIA,GAAA,mBACA,MAAA,UAAA,KAAA,iBACA,KAAA,iBAAA,EAAA,KAAA,KAAA,kBAGA,GAAA,iBAEA,IADA,GAAA,GAAA,KAAA,WACA,GAAA,EAAA,WAAA,EAAA,cACA,EAAA,EAAA,UAEA,OAAA,IAGA,GAAA,eAIA,IAAA,GADA,GAAA,GACA,EAAA,KAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,UAAA,EAAA,eACA,GAAA,EAAA,YAGA,OAAA,IAEA,GAAA,aAAA,GACA,GAAA,GAAA,EAAA,KAAA,WAEA,IAAA,KAAA,4BAEA,GADA,EAAA,MACA,KAAA,EAAA,CACA,GAAA,GAAA,KAAA,KAAA,cAAA,eAAA,EACA,MAAA,YAAA,QAGA,GAAA,MACA,KAAA,KAAA,YAAA,CAGA,IAAA,GAAA,EAAA,KAAA,WAEA,GAAA,KAAA,aACA,WAAA,EACA,aAAA,IAGA,EAAA,GACA,EAAA,EAAA,OAGA,GAAA,cAGA,IAAA,GAFA,GAAA,GAAA,GACA,EAAA,EACA,EAAA,KAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,KAAA,CAGA,OADA,GAAA,OAAA,EACA,GAGA,UAAA,SAAA,GACA,MAAA,GAAA,KAAA,IAGA,SAAA,SAAA,GACA,MAAA,GAAA,KAAA,EAAA,KAGA,wBAAA,SAAA,GAGA,MAAA,GAAA,KAAA,KAAA,KAAA,EAAA,KAGA,UAAA,WAMA,IAAA,GAFA,GAEA,EALA,EAAA,EAAA,KAAA,YACA,KACA,EAAA,GAGA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GACA,EAAA,WAAA,EAAA,UACA,GAAA,EAAA,KAAA,OAEA,GAGA,GAAA,EAAA,KACA,EAAA,KAAA,IAHA,EAAA,EAFA,KAAA,WAAA,IAQA,GAAA,EAAA,SACA,EAAA,MAAA,EACA,aAAA,IAEA,KACA,EAAA,GACA,EAAA,KACA,EAAA,WAAA,QACA,EAAA,YAKA,IAAA,EAAA,SACA,EAAA,MAAA,EACA,EAAA,OAKA,EAAA,EAAA,iBAKA,EAAA,EAAA,EAAA,SAAA,gCACA,GAAA,UAAA,oBACA,GAAA,UAAA,iBACA,EAAA,UAAA,EAAA,OAAA,OAAA,EAAA,WAAA,EAAA,WAEA,EAAA,UAAA,EACA,EAAA,aAAA,EACA,EAAA,eAAA,EACA,EAAA,eAAA,EACA,EAAA,iBAAA,EACA,EAAA,iBAAA,EACA,EAAA,SAAA,KAAA,GAEA,OAAA,mBCrtBA,SAAA,GACA,YAEA,SAAA,GAAA,EAAA,GAEA,IADA,GAAA,GAAA,EAAA,EAAA,kBACA,GAAA,CACA,GAAA,EAAA,QAAA,GACA,MAAA,EAEA,IADA,EAAA,EAAA,EAAA,GAEA,MAAA,EACA,GAAA,EAAA,mBAEA,MAAA,MAGA,QAAA,GAAA,EAAA,EAAA,GAEA,IADA,GAAA,GAAA,EAAA,kBACA,GACA,EAAA,QAAA,KACA,EAAA,EAAA,UAAA,GACA,EAAA,EAAA,EAAA,GACA,EAAA,EAAA,kBAEA,OAAA,GAOA,GAAA,IACA,cAAA,SAAA,GACA,MAAA,GAAA,KAAA,IAEA,iBAAA,SAAA,GACA,MAAA,GAAA,KAAA,EAAA,GAAA,aAIA,GACA,qBAAA,SAAA,GAEA,MAAA,MAAA,iBAAA,IAEA,uBAAA,SAAA,GAEA,MAAA,MAAA,iBAAA,IAAA,IAEA,uBAAA,SAAA,EAAA,GACA,GAAA,MAAA,EACA,MAAA,MAAA,qBAAA,EAKA,KAAA,GAFA,GAAA,GAAA,UACA,EAAA,KAAA,qBAAA,GACA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,eAAA,IACA,EAAA,KAAA,EAAA,GAGA,OADA,GAAA,OAAA,EACA,GAIA,GAAA,uBAAA,EACA,EAAA,mBAAA,GAEA,OAAA,mBCpEA,SAAA,GACA,YAIA,SAAA,GAAA,GACA,KAAA,GAAA,EAAA,WAAA,KAAA,cACA,EAAA,EAAA,WAEA,OAAA,GAGA,QAAA,GAAA,GACA,KAAA,GAAA,EAAA,WAAA,KAAA,cACA,EAAA,EAAA,eAEA,OAAA,GAbA,GAAA,GAAA,EAAA,SAAA,SAgBA,GACA,GAAA,qBACA,MAAA,GAAA,KAAA,aAGA,GAAA,oBACA,MAAA,GAAA,KAAA,YAGA,GAAA,qBAEA,IAAA,GADA,GAAA,EACA,EAAA,KAAA,kBACA,EACA,EAAA,EAAA,mBACA,GAEA,OAAA,IAGA,GAAA,YAGA,IAAA,GAFA,GAAA,GAAA,GACA,EAAA,EACA,EAAA,KAAA,kBACA,EACA,EAAA,EAAA,mBACA,EAAA,KAAA,CAGA,OADA,GAAA,OAAA,EACA,IAIA,GACA,GAAA,sBACA,MAAA,GAAA,KAAA,cAGA,GAAA,0BACA,MAAA,GAAA,KAAA,kBAIA,GAAA,mBAAA,EACA,EAAA,oBAAA,GAEA,OAAA,mBChEA,SAAA,GACA,YAUA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GATA,GAAA,GAAA,EAAA,mBACA,EAAA,EAAA,SAAA,KACA,EAAA,EAAA,gBACA,EAAA,EAAA,MACA,EAAA,EAAA,gBAEA,EAAA,OAAA,aAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,eACA,MAAA,MAAA,MAEA,GAAA,aAAA,GACA,KAAA,KAAA,GAEA,GAAA,QACA,MAAA,MAAA,KAAA,MAEA,GAAA,MAAA,GACA,GAAA,GAAA,KAAA,KAAA,IACA,GAAA,KAAA,iBACA,SAAA,IAEA,KAAA,KAAA,KAAA,KAIA,EAAA,EAAA,UAAA,GAEA,EAAA,EAAA,EACA,SAAA,eAAA,KAEA,EAAA,SAAA,cAAA,GACA,OAAA,mBCxCA,SAAA,GACA,YAOA,SAAA,GAAA,GACA,MAAA,KAAA,EAKA,QAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAZA,GAAA,GAAA,EAAA,SAAA,cAEA,GADA,EAAA,gBACA,EAAA,OACA,EAAA,EAAA,gBAMA,EAAA,OAAA,IAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,UAAA,SAAA,GACA,EAAA,EAAA,EACA,IAAA,GAAA,KAAA,IACA,IAAA,EAAA,EAAA,OACA,KAAA,IAAA,OAAA,iBACA,IAAA,GAAA,EAAA,MAAA,EAAA,GACA,EAAA,EAAA,MAAA,EACA,MAAA,KAAA,CACA,IAAA,GAAA,KAAA,cAAA,eAAA,EAGA,OAFA,MAAA,YACA,KAAA,WAAA,aAAA,EAAA,KAAA,aACA,KAIA,EAAA,EAAA,EAAA,SAAA,eAAA,KAEA,EAAA,SAAA,KAAA,GACA,OAAA,mBCrCA,SAAA,GACA,YA6BA,SAAA,GAAA,EAAA,GAEA,GAAA,GAAA,EAAA,UACA,IAAA,GAAA,EAAA,WAAA,CAGA,GAAA,GAAA,EAAA,mBAAA,EACA,GAAA,mBAAA,IACA,EAAA,cAGA,QAAA,GAAA,EAAA,EAAA,GAIA,EAAA,EAAA,cACA,KAAA,EACA,UAAA,KACA,SAAA,IAIA,QAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAsDA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,GAAA,CACA,QAAA,eAAA,EAAA,GACA,IAAA,WACA,MAAA,MAAA,KAAA,IAEA,IAAA,SAAA,GACA,KAAA,KAAA,GAAA,EACA,EAAA,KAAA,IAEA,cAAA,EACA,YAAA,IAnHA,GAAA,GAAA,EAAA,mBACA,EAAA,EAAA,uBACA,EAAA,EAAA,SAAA,KACA,EAAA,EAAA,oBACA,EAAA,EAAA,mBAEA,GADA,EAAA,sBACA,EAAA,iBACA,EAAA,EAAA,MAEA,GADA,EAAA,MACA,EAAA,iBACA,EAAA,EAAA,SAEA,EAAA,OAAA,QAEA,GACA,UACA,qBACA,oBACA,yBACA,OAAA,SAAA,GACA,MAAA,GAAA,UAAA,KAGA,EAAA,EAAA,GAEA,EAAA,EAAA,UAAA,EA2BA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,iBAAA,WACA,GAAA,GAAA,GAAA,GAAA,WAAA,KACA,MAAA,KAAA,mBAAA,CAEA,IAAA,GAAA,EAAA,mBAAA,KAGA,OAFA,GAAA,aAEA,GAGA,GAAA,cACA,MAAA,MAAA,KAAA,oBAAA,MAGA,aAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,KAAA,aAAA,EACA,MAAA,KAAA,aAAA,EAAA,GACA,EAAA,KAAA,EAAA,GACA,EAAA,KAAA,IAGA,gBAAA,SAAA,GACA,GAAA,GAAA,KAAA,KAAA,aAAA,EACA,MAAA,KAAA,gBAAA,GACA,EAAA,KAAA,EAAA,GACA,EAAA,KAAA,IAGA,QAAA,SAAA,GACA,MAAA,GAAA,KAAA,KAAA,KAAA,MAIA,EAAA,QAAA,SAAA,GACA,YAAA,IACA,EAAA,UAAA,GAAA,SAAA,GACA,MAAA,MAAA,QAAA,OAKA,EAAA,UAAA,yBACA,EAAA,UAAA,uBACA,EAAA,UAAA,kBAsBA,EAAA,EAAA,UAAA,MACA,EAAA,EAAA,UAAA,YAAA,SAEA,EAAA,EAAA,UAAA,GACA,EAAA,EAAA,UAAA,GACA,EAAA,EAAA,UAAA,GACA,EAAA,EAAA,UAAA,GAEA,EAAA,EAAA,EACA,SAAA,gBAAA,KAAA,MAIA,EAAA,aAAA,EACA,EAAA,SAAA,QAAA,GACA,OAAA,mBCzIA,SAAA,GACA,YAqBA,SAAA,GAAA,GACA,OAAA,GACA,IAAA,IACA,MAAA,OACA,KAAA,IACA,MAAA,MACA,KAAA,IACA,MAAA,MACA,KAAA,IACA,MAAA,QACA,KAAA,IACA,MAAA,UAIA,QAAA,GAAA,GACA,MAAA,GAAA,QAAA,EAAA,GAGA,QAAA,GAAA,GACA,MAAA,GAAA,QAAA,EAAA,GAGA,QAAA,GAAA,GAEA,IAAA,GADA,MACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,KAAA,CAEA,OAAA,GAkCA,QAAA,GAAA,EAAA,GACA,OAAA,EAAA,UACA,IAAA,MAAA,aAIA,IAAA,GAAA,GAHA,EAAA,EAAA,QAAA,cACA,EAAA,IAAA,EACA,EAAA,EAAA,WACA,EAAA,EAAA,EAAA,EAAA,GAAA,IACA,GAAA,IAAA,EAAA,KAAA,KAAA,EAAA,EAAA,OAAA,GAGA,OADA,IAAA,IACA,EAAA,GACA,EAEA,EAAA,EAAA,GAAA,KAAA,EAAA,GAEA,KAAA,MAAA,UACA,GAAA,GAAA,EAAA,IACA,OAAA,IAAA,EAAA,EAAA,WACA,EACA,EAAA,EAEA,KAAA,MAAA,aACA,MAAA,OAAA,EAAA,KAAA,KAEA,SAEA,KADA,SAAA,MAAA,GACA,GAAA,OAAA,oBAIA,QAAA,GAAA,GACA,YAAA,GAAA,sBACA,EAAA,EAAA,QAGA,KAAA,GADA,GAAA,GACA,EAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,GAAA,EAAA,EAAA,EAEA,OAAA,GAGA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,GAAA,KACA,GAAA,YAAA,EACA,IAAA,GAAA,EAAA,EAAA,cAAA,cAAA,GACA,GAAA,UAAA,CAEA,KADA,GAAA,GACA,EAAA,EAAA,YACA,EAAA,YAAA,EAAA,IAUA,QAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAwFA,QAAA,GAAA,EAAA,GAEA,GAAA,GAAA,EAAA,EAAA,WAAA,GACA,GAAA,UAAA,CAGA,KAFA,GACA,GADA,EAAA,EAAA,SAAA,0BAEA,EAAA,EAAA,YACA,EAAA,YAAA,EAEA,OAAA,GAAA,GAGA,QAAA,GAAA,GACA,MAAA,YAEA,MADA,GAAA,mBACA,KAAA,KAAA,IAIA,QAAA,GAAA,GACA,EAAA,EAAA,EAAA,EAAA,IAgBA,QAAA,GAAA,GACA,OAAA,eAAA,EAAA,UAAA,GACA,IAAA,EAAA,GACA,IAAA,SAAA,GACA,EAAA,mBACA,KAAA,KAAA,GAAA,GAEA,cAAA,EACA,YAAA,IASA,QAAA,GAAA,GACA,OAAA,eAAA,EAAA,UAAA,GACA,MAAA,WAEA,MADA,GAAA,mBACA,KAAA,KAAA,GAAA,MAAA,KAAA,KAAA,YAEA,cAAA,EACA,YAAA,IAhSA,GAAA,GAAA,EAAA,SAAA,QACA,EAAA,EAAA,aACA,EAAA,EAAA,gBACA,EAAA,EAAA,MACA,EAAA,EAAA,eACA,EAAA,EAAA,iBACA,EAAA,EAAA,gBACA,EAAA,EAAA,iBACA,EAAA,EAAA,OACA,EAAA,EAAA,KACA,EAAA,EAAA,SAMA,EAAA,cACA,EAAA,eAkCA,EAAA,GACA,OACA,OACA,KACA,MACA,UACA,QACA,KACA,MACA,QACA,SACA,OACA,OACA,QACA,SACA,QACA,QAGA,EAAA,GACA,QACA,SACA,MACA,SACA,UACA,WACA,YACA,aAwDA,EAAA,OAAA,KAAA,UAAA,WAEA,EAAA,OAAA,YACA,EAAA,OAAA,mBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,aACA,MAAA,GAAA,OAEA,GAAA,WAAA,GAOA,GAAA,GAAA,EAAA,KAAA,WAEA,YADA,KAAA,YAAA,EAIA,IAAA,GAAA,EAAA,KAAA,WAEA,MAAA,2BACA,eAAA,GAAA,oBACA,EAAA,KAAA,QAAA,GAEA,EAAA,KAAA,EAAA,KAAA,UAKA,GACA,eAAA,GAAA,oBACA,EAAA,KAAA,QAAA,GAEA,KAAA,KAAA,UAAA,CAGA,IAAA,GAAA,EAAA,KAAA,WAEA,GAAA,KAAA,aACA,WAAA,EACA,aAAA,IAGA,EAAA,GACA,EAAA,EAAA,OAGA,GAAA,aACA,MAAA,GAAA,KAAA,KAAA,aAEA,GAAA,WAAA,GACA,GAAA,GAAA,KAAA,UACA,IAAA,EAAA,CACA,EAAA,0BACA,IAAA,GAAA,EAAA,EAAA,EACA,GAAA,aAAA,EAAA,QAIA,mBAAA,SAAA,EAAA,GACA,GAAA,GAAA,CACA,QAAA,OAAA,GAAA,eACA,IAAA,cACA,EAAA,KAAA,WACA,EAAA,IACA,MACA,KAAA,WACA,EAAA,KAAA,WACA,EAAA,KAAA,WACA,MACA,KAAA,aACA,EAAA,KACA,EAAA,KAAA,UACA,MACA,KAAA,YACA,EAAA,KACA,EAAA,IACA,MACA,SACA,OAGA,GAAA,GAAA,EAAA,EAAA,EACA,GAAA,aAAA,EAAA,OA4BA,eACA,aACA,YACA,cACA,eACA,aACA,YACA,cACA,eACA,eACA,QAAA,IAeA,aACA,aACA,QAAA,IAcA,wBACA,iBACA,kBACA,QAAA,GAGA,EAAA,EAAA,EACA,SAAA,cAAA,MAEA,EAAA,SAAA,YAAA,EAGA,EAAA,aAAA,EACA,EAAA,aAAA,GACA,OAAA,mBCtTA,SAAA,GACA,YASA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GARA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,KAEA,EAAA,OAAA,iBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WAEA,EAAA,EAAA,WACA,WAAA,WACA,GAAA,GAAA,KAAA,KAAA,WAAA,MAAA,KAAA,KAAA,UACA,OAAA,IAAA,EAAA,MAIA,EAAA,EAAA,EACA,SAAA,cAAA,WAEA,EAAA,SAAA,kBAAA,GACA,OAAA,mBC1BA,SAAA,GACA,YAQA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAPA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBAEA,EAAA,OAAA,kBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,UACA,MAAA,MAAA,aAAA,WAEA,GAAA,QAAA,GACA,KAAA,aAAA,SAAA,IAGA,aAAA,SAAA,EAAA,GACA,EAAA,UAAA,aAAA,KAAA,KAAA,EAAA,GACA,WAAA,OAAA,GAAA,eACA,KAAA,0BAAA,MAQA,GACA,EAAA,EAAA,GAEA,EAAA,SAAA,mBAAA,GACA,OAAA,mBCpCA,SAAA,GACA,YASA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAOA,QAAA,GAAA,EAAA,GACA,KAAA,eAAA,IACA,KAAA,IAAA,WACA,yDAGA,IAAA,GAAA,EAAA,SAAA,cAAA,OACA,GAAA,KAAA,KAAA,GACA,EAAA,EAAA,MAEA,SAAA,IACA,EAAA,MAAA,GACA,SAAA,IACA,EAAA,OAAA,GA5BA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,OAEA,EAAA,OAAA,gBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WAEA,EAAA,EAAA,EACA,SAAA,cAAA,QAkBA,EAAA,UAAA,EAAA,UAEA,EAAA,SAAA,iBAAA,EACA,EAAA,SAAA,MAAA,GACA,OAAA,mBCtCA,SAAA,GACA,YAQA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAPA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBAEA,EAAA,OAAA,iBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,cAIA,GACA,EAAA,EAAA,GAEA,EAAA,SAAA,kBAAA,GACA,OAAA,mBCrBA,SAAA,GACA,YAYA,SAAA,GAAA,GACA,IAAA,EAAA,YACA,MAAA,EACA,IAAA,GAAA,EAAA,IAAA,EACA,KAAA,EAAA,CAIA,IADA,EAAA,EAAA,eAAA,mBAAA,IACA,EAAA,WACA,EAAA,YAAA,EAAA,UAEA,GAAA,IAAA,EAAA,GAEA,MAAA,GAGA,QAAA,GAAA,GAKA,IAHA,GAEA,GAFA,EAAA,EAAA,EAAA,eACA,EAAA,EAAA,EAAA,0BAEA,EAAA,EAAA,YACA,EAAA,YAAA,EAEA,OAAA,GAKA,QAAA,GAAA,GAEA,GADA,EAAA,KAAA,KAAA,IACA,EAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,IAAA,KAAA,EAAA,KA3CA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,KAEA,EAAA,GAAA,SACA,EAAA,GAAA,SA8BA,EAAA,OAAA,mBASA,GAAA,UAAA,OAAA,OAAA,EAAA,WAEA,EAAA,EAAA,WACA,GAAA,WACA,MAAA,GACA,EAAA,KAAA,KAAA,SACA,EAAA,IAAA,SAOA,GACA,EAAA,EAAA,GAEA,EAAA,SAAA,oBAAA,GACA,OAAA,mBClEA,SAAA,GACA,YAOA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GANA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,gBAEA,EAAA,OAAA,gBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WAEA,EAAA,EAAA,EACA,SAAA,cAAA,UAEA,EAAA,SAAA,iBAAA,GACA,OAAA,mBCjBA,SAAA,GACA,YASA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAOA,QAAA,GAAA,GACA,KAAA,eAAA,IACA,KAAA,IAAA,WACA,yDAGA,IAAA,GAAA,EAAA,SAAA,cAAA,SACA,GAAA,KAAA,KAAA,GACA,EAAA,EAAA,MAEA,EAAA,aAAA,UAAA,QACA,SAAA,GACA,EAAA,aAAA,MAAA,GA3BA,GAAA,GAAA,EAAA,SAAA,iBACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,OAEA,EAAA,OAAA,gBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WAEA,EAAA,EAAA,EACA,SAAA,cAAA,UAiBA,EAAA,UAAA,EAAA,UAEA,EAAA,SAAA,iBAAA,EACA,EAAA,SAAA,MAAA,GACA,OAAA,mBCrCA,SAAA,GACA,YAWA,SAAA,GAAA,GACA,MAAA,GAAA,QAAA,OAAA,KAAA,OAGA,QAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAkBA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,KAAA,eAAA,IACA,KAAA,IAAA,WACA,yDAGA,IAAA,GAAA,EAAA,SAAA,cAAA,UACA,GAAA,KAAA,KAAA,GACA,EAAA,EAAA,MAEA,SAAA,IACA,EAAA,KAAA,GACA,SAAA,GACA,EAAA,aAAA,QAAA,GACA,KAAA,GACA,EAAA,aAAA,WAAA,IACA,EAAA,SAAA,KAAA,EAhDA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,OACA,EAAA,EAAA,KAEA,EAAA,OAAA,iBASA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,QACA,MAAA,GAAA,KAAA,cAEA,GAAA,MAAA,GACA,KAAA,YAAA,EAAA,OAAA,KAEA,GAAA,QACA,MAAA,GAAA,EAAA,MAAA,SAIA,EAAA,EAAA,EACA,SAAA,cAAA,WAqBA,EAAA,UAAA,EAAA,UAEA,EAAA,SAAA,kBAAA,EACA,EAAA,SAAA,OAAA,GACA,OAAA,mBC1DA,SAAA,GACA,YAUA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GATA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,KAEA,EAAA,OAAA,iBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,IAAA,SAAA,EAAA,GACA,gBAAA,KACA,EAAA,EAAA,IACA,EAAA,MAAA,IAAA,EAAA,GAAA,IAGA,OAAA,SAAA,GAGA,gBAAA,KACA,EAAA,EAAA,IACA,EAAA,MAAA,OAAA,IAGA,GAAA,QACA,MAAA,GAAA,EAAA,MAAA,SAIA,EAAA,EAAA,EACA,SAAA,cAAA,WAEA,EAAA,SAAA,kBAAA,GACA,OAAA,mBCrCA,SAAA,GACA,YAWA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAVA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,KACA,EAAA,EAAA,mBAEA,EAAA,OAAA,gBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,WACA,MAAA,GAAA,EAAA,MAAA,UAEA,cAAA,WACA,MAAA,GAAA,EAAA,MAAA,kBAGA,GAAA,SACA,MAAA,GAAA,EAAA,MAAA,QAEA,YAAA,WACA,MAAA,GAAA,EAAA,MAAA,gBAGA,YAAA,WACA,MAAA,GAAA,EAAA,MAAA,gBAEA,GAAA,SACA,MAAA,GAAA,EAAA,MAAA,QAGA,GAAA,WACA,MAAA,GAAA,EAAA,MAAA,UAEA,YAAA,WACA,MAAA,GAAA,EAAA,MAAA,gBAGA,GAAA,QACA,MAAA,GAAA,EAAA,MAAA,OAEA,UAAA,SAAA,GACA,MAAA,GAAA,EAAA,MAAA,UAAA,OAIA,EAAA,EAAA,EACA,SAAA,cAAA,UAEA,EAAA,SAAA,iBAAA,GACA,OAAA,mBCzDA,SAAA,GACA,YAWA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAVA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,mBACA,EAAA,EAAA,OACA,EAAA,EAAA,KAEA,EAAA,OAAA,uBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,QACA,MAAA,GAAA,EAAA,MAAA,OAEA,UAAA,SAAA,GACA,MAAA,GAAA,EAAA,MAAA,UAAA,OAIA,EAAA,EAAA,EACA,SAAA,cAAA,UAEA,EAAA,SAAA,wBAAA,GACA,OAAA,mBC7BA,SAAA,GACA,YAWA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAVA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,mBACA,EAAA,EAAA,OACA,EAAA,EAAA,KAEA,EAAA,OAAA,mBAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,SACA,MAAA,GAAA,EAAA,MAAA,QAGA,WAAA,SAAA,GACA,MAAA,GAAA,EAAA,MAAA,WAAA,OAIA,EAAA,EAAA,EACA,SAAA,cAAA,OAEA,EAAA,SAAA,oBAAA,GACA,OAAA,mBChCA,SAAA,GACA,YAWA,SAAA,GAAA,GACA,OAAA,EAAA,WACA,IAAA,UACA,MAAA,IAAA,GAAA,EACA,KAAA,SACA,MAAA,IAAA,GAAA,EACA,KAAA,WACA,MAAA,IAAA,GAAA,GAEA,EAAA,KAAA,KAAA,GAlBA,GAAA,GAAA,EAAA,SAAA,mBACA,EAAA,EAAA,SAAA,YACA,EAAA,EAAA,SAAA,kBACA,EAAA,EAAA,SAAA,oBAEA,GADA,EAAA,MACA,EAAA,iBAEA,EAAA,OAAA,kBAaA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,GACA,EAAA,SAAA,mBAAA,GACA,OAAA,mBC1BA,SAAA,GACA,YAEA,IAAA,GAAA,EAAA,eAEA,EAAA,6BACA,EAAA,SAAA,gBAAA,EAAA,SACA,EAAA,EAAA,GACA,EAAA,OAAA,eAAA,EAAA,WAAA,WAEA,GAAA,SAAA,WAAA,GACA,OAAA,mBCXA,SAAA,GACA,YAmBA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAlBA,GAAA,GAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,KAEA,EAAA,OAAA,cAKA,EAAA,6BACA,EAAA,EAAA,SAAA,gBAAA,EAAA,MACA,EAAA,SAAA,gBAAA,EAAA,OACA,EAAA,EAAA,YACA,EAAA,OAAA,eAAA,EAAA,WACA,EAAA,EAAA,WAMA,GAAA,UAAA,OAAA,OAAA,GAGA,gBAAA,IACA,EAAA,EAAA,WACA,GAAA,gBACA,MAAA,GAAA,EAAA,MAAA,eAEA,GAAA,wBACA,MAAA,GAAA,EAAA,MAAA,yBAKA,EAAA,EAAA,EAAA,GAEA,EAAA,SAAA,cAAA,GACA,OAAA,mBCzCA,SAAA,GACA,YAWA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAVA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,KAEA,EAAA,OAAA,kBACA,KAOA,EAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WAEA,GAAA,wBACA,MAAA,GAAA,KAAA,KAAA,uBAIA,GAAA,2BACA,MAAA,GAAA,KAAA,KAAA,0BAIA,GAAA,cACA,MAAA,GAAA,KAAA,KAAA,aAIA,GAAA,cACA,KAAA,IAAA,OAAA,oBAIA,GAAA,cACA,MAAA,GAAA,KAAA,KAAA,aAIA,GAAA,aACA,MAAA,GAAA,KAAA,KAAA,YAIA,GAAA,mBACA,MAAA,GAAA,KAAA,KAAA,kBAIA,GAAA,eACA,MAAA,GAAA,KAAA,KAAA,gBAIA,EAAA,EAAA,GAEA,EAAA,SAAA,mBAAA,IACA,OAAA,mBC9DA,SAAA,GACA,YAUA,SAAA,GAAA,GACA,KAAA,KAAA,EATA,GAAA,GAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,eACA,EAAA,EAAA,KAEA,EAAA,OAAA,wBAMA,GAAA,EAAA,WACA,GAAA,UACA,MAAA,GAAA,KAAA,KAAA,SAGA,UAAA,WACA,UAAA,GAAA,EAAA,UAAA,IACA,KAAA,KAAA,UAAA,MAAA,KAAA,KAAA,YAGA,cAAA,WAEA,MADA,WAAA,GAAA,EAAA,UAAA,IACA,KAAA,KAAA,cAAA,MAAA,KAAA,KAAA,cAIA,EAAA,EAAA,EACA,SAAA,cAAA,UAAA,WAAA,OAEA,EAAA,SAAA,yBAAA,GACA,OAAA,mBCnCA,SAAA,GACA,YAaA,SAAA,GAAA,GACA,KAAA,KAAA,EAZA,GAAA,GAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,eACA,EAAA,EAAA,KAEA,EAAA,OAAA,qBAGA,IAAA,EAAA,CAOA,EAAA,EAAA,WACA,GAAA,UACA,MAAA,GAAA,KAAA,KAAA,SAGA,WAAA,WACA,UAAA,GAAA,EAAA,UAAA,IACA,KAAA,KAAA,WAAA,MAAA,KAAA,KAAA,YAGA,cAAA,WACA,UAAA,GAAA,EAAA,UAAA,IACA,KAAA,KAAA,cAAA,MAAA,KAAA,KAAA,aAQA,IAAA,GAAA,SAAA,KAAA,UAAA,YACA,oBAAA,KAAA,mBAAA,QAEA,GAAA,EAAA,EACA,GAEA,EAAA,SAAA,sBAAA,IACA,OAAA,mBC7CA,SAAA,GACA,YASA,SAAA,GAAA,GACA,KAAA,KAAA,EARA,GAAA,GAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,eACA,EAAA,EAAA,KAEA,EAAA,OAAA,KAKA,GAAA,WACA,GAAA,kBACA,MAAA,GAAA,KAAA,KAAA,iBAEA,GAAA,gBACA,MAAA,GAAA,KAAA,KAAA,eAEA,GAAA,2BACA,MAAA,GAAA,KAAA,KAAA,0BAEA,SAAA,SAAA,EAAA,GACA,KAAA,KAAA,SAAA,EAAA,GAAA,IAEA,OAAA,SAAA,EAAA,GACA,KAAA,KAAA,OAAA,EAAA,GAAA,IAEA,eAAA,SAAA,GACA,KAAA,KAAA,eAAA,EAAA,KAEA,cAAA,SAAA,GACA,KAAA,KAAA,cAAA,EAAA,KAEA,aAAA,SAAA,GACA,KAAA,KAAA,aAAA,EAAA,KAEA,YAAA,SAAA,GACA,KAAA,KAAA,YAAA,EAAA,KAEA,WAAA,SAAA,GACA,KAAA,KAAA,WAAA,EAAA,KAEA,mBAAA,SAAA,GACA,KAAA,KAAA,mBAAA,EAAA,KAEA,sBAAA,SAAA,EAAA,GACA,MAAA,MAAA,KAAA,sBAAA,EAAA,EAAA,KAEA,gBAAA,WACA,MAAA,GAAA,KAAA,KAAA,oBAEA,cAAA,WACA,MAAA,GAAA,KAAA,KAAA,kBAEA,WAAA,SAAA,GACA,KAAA,KAAA,WAAA,EAAA,KAEA,iBAAA,SAAA,GACA,KAAA,KAAA,iBAAA,EAAA,KAEA,WAAA,WACA,MAAA,GAAA,KAAA,KAAA,eAEA,eAAA,SAAA,EAAA,GACA,MAAA,MAAA,KAAA,eAAA,EAAA,GAAA,IAEA,aAAA,SAAA,EAAA,GACA,MAAA,MAAA,KAAA,aAAA,EAAA,GAAA,IAEA,eAAA,SAAA,GACA,MAAA,MAAA,KAAA,eAAA,EAAA,KAEA,SAAA,WACA,MAAA,MAAA,KAAA,aAKA,EAAA,UAAA,2BACA,EAAA,UAAA,yBAAA,SAAA,GACA,MAAA,GAAA,KAAA,KAAA,yBAAA,MAIA,EAAA,OAAA,MAAA,EAAA,SAAA,eAEA,EAAA,SAAA,MAAA,GAEA,OAAA,mBC1FA,SAAA,GACA,YAEA,IAAA,GAAA,EAAA,uBACA,EAAA,EAAA,oBACA,EAAA,EAAA,mBACA,EAAA,EAAA,MACA,EAAA,EAAA,eAEA,EAAA,EAAA,SAAA,yBACA,GAAA,EAAA,UAAA,GACA,EAAA,EAAA,UAAA,GACA,EAAA,EAAA,UAAA,EAEA,IAAA,GAAA,EAAA,SAAA,cAAA,IAEA,GAAA,SAAA,QAAA,EACA,EAAA,SAAA,iBAAA,GAEA,OAAA,mBCnBA,SAAA,GACA,YAiBA,SAAA,GAAA,GACA,GAAA,GAAA,EAAA,EAAA,KAAA,cAAA,yBACA,GAAA,KAAA,KAAA,GAIA,EAAA,EAAA,MAEA,KAAA,WAAA,GAAA,GAAA,KAAA,EAAA,GAEA,IAAA,GAAA,EAAA,UACA,GAAA,IAAA,KAAA,GAEA,EAAA,IAAA,KAAA,GA5BA,GAAA,GAAA,EAAA,SAAA,iBACA,EAAA,EAAA,UACA,EAAA,EAAA,iBACA,EAAA,EAAA,aACA,EAAA,EAAA,aACA,EAAA,EAAA,MACA,EAAA,EAAA,OACA,EAAA,EAAA,aACA,EAAA,EAAA,OAEA,EAAA,GAAA,SACA,EAAA,GAAA,SAEA,EAAA,aAiBA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,aACA,MAAA,GAAA,OAEA,GAAA,WAAA,GACA,EAAA,KAAA,GACA,KAAA,4BAGA,GAAA,mBACA,MAAA,GAAA,IAAA,OAAA,MAGA,GAAA,QACA,MAAA,GAAA,IAAA,OAAA,MAGA,yBAAA,WACA,MAAA,GAAA,IAAA,MAAA,4BAGA,iBAAA,SAAA,EAAA,GACA,MAAA,GAAA,KAAA,KAAA,cAAA,EAAA,IAGA,eAAA,SAAA,GACA,MAAA,GAAA,KAAA,GACA,KACA,KAAA,cAAA,QAAA,EAAA,SAIA,EAAA,SAAA,WAAA,GAEA,OAAA,mBCpEA,SAAA,GACA,YAoBA,SAAA,GAAA,GACA,EAAA,iBAAA,EAAA,gBACA,EAAA,aAAA,EAAA,YACA,EAAA,YAAA,EAAA,WAuBA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,GAAA,IAKA,IAHA,EAAA,GACA,EAAA,GAEA,EASA,EAAA,aAAA,IACA,EAAA,YAAA,GAEA,EAAA,iBAAA,EAAA,oBAZA,CACA,EAAA,WAAA,EAAA,UACA,EAAA,YAAA,EAAA,aACA,EAAA,YAAA,EAAA,WAEA,IAAA,GAAA,EAAA,EAAA,UACA,KACA,EAAA,aAAA,EAAA,aAQA,EAAA,aAAA,EAAA,GAGA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,UACA,IAAA,EAAA,CAGA,GAAA,GAAA,EAAA,EACA,GAAA,GAEA,EAAA,kBACA,EAAA,gBAAA,aAAA,GACA,EAAA,cACA,EAAA,YAAA,iBAAA,GAEA,EAAA,YAAA,IACA,EAAA,WAAA,GACA,EAAA,aAAA,IACA,EAAA,YAAA,GAEA,EAAA,YAAA,IAQA,QAAA,GAAA,EAAA,GACA,EAAA,GAAA,KAAA,GACA,EAAA,EAAA,EAEA,IAAA,GAAA,EAAA,IAAA,EACA,IACA,EAAA,IAAA,EAAA,MACA,EAAA,KAAA,GAGA,QAAA,GAAA,GACA,EAAA,IAAA,MAGA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,IAAA,EAGA,OAFA,IACA,EAAA,IAAA,EAAA,MACA,EAGA,QAAA,GAAA,GAEA,IAAA,GADA,MAAA,EAAA,EACA,EAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,KAAA,CAEA,OAAA,GAUA,QAAA,GAAA,EAAA,EAAA,GAEA,IAAA,GAAA,GAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,GAAA,EAAA,IACA,GAAA,EAAA,MAAA,EACA,WAEA,GAAA,EAAA,EAAA,GAoCA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,aAAA,SACA,KAAA,EACA,OAAA,CAIA,IADA,EAAA,EAAA,QACA,EACA,OAAA,CAEA,MAAA,YAAA,IACA,OAAA,CAMA,IAAA,MAAA,GAAA,IAAA,EAAA,UACA,OAAA,CAGA,KAAA,EAAA,KAAA,GACA,OAAA,CAGA,IAAA,MAAA,EAAA,KAAA,EAAA,KAAA,GACA,OAAA,CAEA,KACA,MAAA,GAAA,QAAA,GACA,MAAA,GAEA,OAAA,GAcA,QAAA,KAGA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,cACA,IAAA,EAAA,OAEA,EAAA,SAGA,KAGA,QAAA,KACA,EAAA,KACA,IAQA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,IAAA,EAKA,OAJA,KACA,EAAA,GAAA,GAAA,GACA,EAAA,IAAA,EAAA,IAEA,EAGA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,GAAA,IACA,OAAA,aAAA,GACA,EACA,KAGA,QAAA,GAAA,GACA,MAAA,GAAA,EAAA,MAaA,QAAA,GAAA,GACA,KAAA,MAAA,EACA,KAAA,KAAA,EACA,KAAA,cA8DA,QAAA,GAAA,GACA,KAAA,KAAA,EACA,KAAA,OAAA,EACA,KAAA,uBACA,KAAA,cAAA,GAoOA,QAAA,GAAA,GAEA,MAAA,aAAA,GAGA,QAAA,GAAA,GAEA,MAAA,aAAA,GAGA,QAAA,GAAA,GACA,MAAA,aAAA,GAGA,QAAA,GAAA,GAEA,MAAA,aAAA,GAGA,QAAA,GAAA,GACA,MAAA,GAAA;CAGA,QAAA,GAAA,GAGA,IAAA,GAFA,MAEA,EAAA,EAAA,WAAA,EAAA,EAAA,EAAA,gBACA,EAAA,KAAA,EAEA,OAAA,GAGA,QAAA,GAAA,EAAA,GACA,EAAA,IAAA,EAAA,GA9lBA,GA4NA,GA5NA,EAAA,EAAA,SAAA,QACA,EAAA,EAAA,SAAA,mBACA,EAAA,EAAA,SAAA,kBACA,EAAA,EAAA,SAAA,KACA,EAAA,EAAA,SAAA,WAEA,GADA,EAAA,OACA,EAAA,cAEA,GADA,EAAA,MACA,EAAA,OACA,EAAA,EAAA,OACA,EAAA,EAAA,KAkFA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,SACA,EAAA,GAAA,SAsDA,EAAA,mBAEA,EAAA,GAAA,QAAA,OACA,OACA,UACA,SACA,UACA,WACA,UACA,gBACA,YACA,iBACA,cACA,mBACA,cACA,aACA,gBACA,eACA,gBACA,KAAA,KAAA,KA4CA,EAAA,EAAA,QACA,wBACA,2BACA,8BACA,eAGA,KA+CA,EAAA,GAAA,YACA,GAAA,OAAA,SAAA,EAAA,GACA,MAAA,GAAA,EAAA,QAAA,GAcA,EAAA,WACA,OAAA,SAAA,GACA,GAAA,GAAA,GAAA,GAAA,EAEA,OADA,MAAA,WAAA,KAAA,GACA,GAGA,KAAA,SAAA,GACA,IAAA,KAAA,KAAA,CAcA,IAAA,GAXA,GAAA,KAAA,KAEA,EAAA,KAAA,WAEA,EAAA,EAAA,EAAA,IACA,EAAA,GAAA,GAAA,SAEA,EAAA,EAAA,iBAAA,EAAA,GAEA,EAAA,EAAA,EAAA,EACA,EAAA,EACA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CAEA,IADA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,MAAA,IACA,IACA,EAAA,KAAA,KAAA,EAIA,KAAA,GADA,GAAA,EAAA,QAAA,OACA,EAAA,EAAA,EAAA,EAAA,IAAA,CACA,GAAA,GAAA,EAAA,EAAA,KACA,GAAA,IAAA,IACA,EAAA,GAKA,IAAA,GAFA,GAAA,EAAA,WACA,EAAA,EAAA,IAAA,EAAA,EAAA,IACA,EAAA,EAAA,EAAA,EAAA,IAAA,CACA,GAAA,GAAA,EAAA,KACA,EAAA,EAAA,IACA,GAAA,EAAA,EAAA,GAIA,EAAA,IAAA,GAAA,GAEA,EAAA,KAAA,GAGA,GAAA,EAGA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,KAAA,MAYA,EAAA,WAGA,OAAA,SAAA,GACA,GAAA,KAAA,MAAA,CAGA,KAAA,uBACA,KAAA,iBAEA,IAAA,GAAA,KAAA,KACA,EAAA,EAAA,UAEA,MAAA,cAAA,EAIA,KAAA,GAHA,IAAA,EACA,EAAA,GAAA,GAAA,GAAA,GAEA,EAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,KAAA,WAAA,EAAA,EAAA,GAAA,EAGA,IACA,EAAA,OAEA,KAAA,OAAA,IAGA,GAAA,kBACA,MAAA,GAAA,KAAA,MAAA,UAGA,WAAA,WACA,IAAA,KAAA,MAAA,CAGA,GAFA,KAAA,OAAA,EACA,EAAA,KAAA,MACA,EACA,MACA,GAAA,OAAA,GAAA,EAAA,KAIA,WAAA,SAAA,EAAA,EAAA,EAAA,GACA,GAAA,EAAA,GAAA,CACA,EAAA,EAAA,OAAA,EACA,IAAA,GAAA,EAAA,EACA,GAAA,OAAA,EACA,EAAA,OAAA,OACA,GAAA,GACA,KAAA,qBAAA,EAAA,EAAA,EAAA,GACA,EAAA,GACA,KAAA,2BAAA,EAAA,EAAA,GAEA,KAAA,mBAAA,EAAA,EAAA,EAAA,IAIA,mBAAA,SAAA,EAAA,EAAA,EAAA,GAGA,GAFA,EAAA,EAAA,OAAA,GAEA,EAAA,GAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,MAAA,EAAA,MACA,EAAA,OAAA,OAEA,KAAA,GAAA,GAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,KAAA,WAAA,EAAA,EAAA,EAAA,IAKA,qBAAA,SAAA,EAAA,EAAA,EACA,GACA,GAAA,GAAA,EAAA,EACA,IAAA,EAAA,OAAA,CACA,KAAA,cAAA,EAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,IAAA,EACA,KAAA,qBAAA,EAAA,EAAA,EAAA,GAEA,KAAA,mBAAA,EAAA,EAAA,EAAA,QAGA,MAAA,sBAAA,EAAA,EAAA,EAEA,MAAA,cAAA,EAAA,aAGA,2BAAA,SAAA,EAAA,EACA,GACA,GAAA,GAAA,EAAA,eACA,IAAA,EAAA,CACA,EAAA,EAAA,GACA,KAAA,cAAA,EAAA,WACA,KAAA,GAAA,GAAA,EAAA,WACA,EACA,EAAA,EAAA,YACA,KAAA,WAAA,EAAA,EAAA,GAAA,OAGA,MAAA,sBAAA,EAAA,EACA,IAIA,sBAAA,SAAA,EAAA,EAAA,GACA,KAAA,cAAA,GACA,KAAA,cAAA,EAAA,WACA,KAAA,GAAA,GAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,KAAA,mBAAA,EAAA,EAAA,GAAA,IAQA,qBAAA,WACA,KAAA,WAAA,OAAA,OAAA,OAQA,0BAAA,SAAA,GACA,GAAA,EAAA,CAGA,GAAA,GAAA,KAAA,UAGA,SAAA,KAAA,KACA,EAAA,UAAA,GAGA,OAAA,KAAA,KACA,EAAA,IAAA,GAEA,EAAA,QAAA,uBAAA,SAAA,EAAA,GACA,EAAA,IAAA,MAMA,mBAAA,SAAA,GACA,MAAA,MAAA,WAAA,IAIA,WAAA,SAAA,EAAA,GACA,GAAA,GAAA,IAEA,GAAA,EAAA,EACA,SAAA,GACA,EAAA,GACA,EAAA,0BACA,EAAA,aAAA,UAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,UAAA,GAEA,EAAA,EAAA,KACA,EAAA,EAAA,GACA,EAAA,GAAA,YAOA,gBAAA,WAKA,IAAA,GAJA,GAAA,KAAA,KACA,EAAA,EAAA,WACA,KAEA,EAAA,EAAA,WACA,EACA,EAAA,EAAA,YACA,GAAA,EAAA,GAAA,CACA,GAAA,GAAA,EAAA,EAEA,IAAA,EAAA,SACA,EAAA,EAAA,IACA,EAAA,KAAA,MAAA,EAAA,OAEA,GAAA,KAAA,EAKA,KADA,GAAA,GAAA,EACA,GAAA,CAUA,GARA,EAAA,OACA,EAAA,EAAA,EAAA,SAAA,GAEA,MADA,GAAA,GACA,IAEA,EAAA,EAEA,KAAA,WAAA,EAAA,GACA,EAAA,CACA,GAAA,GAAA,EAAA,eACA,IAAA,EAEA,CACA,EAAA,EACA,EAAA,EAAA,EACA,UAJA,MAOA,QAKA,cAAA,SAAA,GACA,EAAA,KAAA,uBAAA,OA0DA,EAAA,UAAA,yBAAA,WACA,GAAA,GAAA,KAAA,KAAA,sBACA,OAAA,IACA,EAAA,cACA,IAGA,GAGA,EAAA,UAAA,oBAAA,WAIA,MADA,KACA,EAAA,OAGA,EAAA,UAAA,gBACA,EAAA,UAAA,gBAAA,WAEA,KAAA,0BAEA,IACA,GADA,EAAA,EAAA,KAEA,KACA,EAAA,EAAA,IACA,KAAA,KAAA,uBAAA,EACA,GACA,EAAA,cAGA,EAAA,kBAAA,EACA,EAAA,mBAAA,EACA,EAAA,eAAA,EACA,EAAA,qBAAA,EACA,EAAA,iBAAA,EAGA,EAAA,QACA,aAAA,EACA,OAAA,IAGA,OAAA,mBCjqBA,SAAA,GACA,YAuBA,SAAA,GAAA,GACA,GAAA,OAAA,GAAA,CAIA,GAAA,EAAA,SAAA,GAEA,IAAA,GAAA,SAAA,GAEA,EAAA,KAAA,KAAA,GAEA,GAAA,UAAA,OAAA,OAAA,EAAA,WACA,EAAA,EAAA,WACA,GAAA,QACA,MAAA,GAAA,EAAA,MAAA,SAIA,EAAA,OAAA,GAAA,EACA,SAAA,cAAA,EAAA,MAAA,EAAA,MACA,EAAA,SAAA,GAAA,GAzCA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,OACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,KAEA,GACA,oBACA,sBACA,mBACA,oBACA,mBACA,oBACA,oBAEA,oBAEA,sBA0BA,GAAA,QAAA,IAEA,OAAA,mBCjDA,SAAA,GACA,YASA,SAAA,GAAA,GACA,KAAA,KAAA,EARA,CAAA,GAAA,GAAA,EAAA,gBACA,EAAA,EAAA,OACA,EAAA,EAAA,eACA,EAAA,EAAA,IAEA,QAAA,UAKA,EAAA,WACA,GAAA,cACA,MAAA,GAAA,KAAA,KAAA,aAEA,GAAA,aACA,MAAA,GAAA,KAAA,KAAA,YAEA,SAAA,SAAA,GACA,KAAA,KAAA,SAAA,EAAA,KAEA,SAAA,SAAA,EAAA,GACA,KAAA,KAAA,SAAA,EAAA,GAAA,IAEA,aAAA,SAAA,EAAA,GACA,MAAA,MAAA,KAAA,aAAA,EAAA,GAAA,IAEA,OAAA,SAAA,EAAA,GACA,KAAA,KAAA,OAAA,EAAA,GAAA,IAEA,WAAA,SAAA,GACA,MAAA,GAAA,KAAA,KAAA,WAAA,KAEA,YAAA,SAAA,GACA,KAAA,KAAA,YAAA,EAAA,KAEA,kBAAA,SAAA,GACA,KAAA,KAAA,kBAAA,EAAA,KAEA,SAAA,WACA,MAAA,MAAA,KAAA,aAgBA,EAAA,OAAA,UAAA,EAAA,OAAA,gBAEA,EAAA,SAAA,UAAA,GAEA,OAAA,mBC9DA,SAAA,GACA,YAyBA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GACA,KAAA,WAAA,GAAA,GAAA,KAAA,MAcA,QAAA,GAAA,GACA,GAAA,GAAA,SAAA,EACA,GAAA,UAAA,GAAA,WACA,MAAA,GAAA,EAAA,MAAA,KAAA,KAAA,aAkBA,QAAA,GAAA,EAAA,GACA,EAAA,KAAA,EAAA,KAAA,EAAA,IACA,EAAA,EAAA,GAGA,QAAA,GAAA,EAAA,GACA,EAAA,YACA,EAAA,UAAA,EAAA,YACA,YAAA,IACA,EAAA,EAAA,EACA,KAAA,GAAA,GAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,EAAA,GAIA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,eACA,IACA,EAAA,UAAA,GA8LA,QAAA,GAAA,GACA,KAAA,KAAA,EAGA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,SAAA,eAAA,EACA,GAAA,UAAA,GAAA,WACA,MAAA,GAAA,EAAA,MAAA,KAAA,KAAA,aAIA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,SAAA,eAAA,EACA,GAAA,UAAA,GAAA,WACA,MAAA,GAAA,MAAA,KAAA,KAAA,YA1RA,GAAA,GAAA,EAAA,uBACA,EAAA,EAAA,SAAA,KACA,EAAA,EAAA,oBACA,EAAA,EAAA,SAAA,UACA,EAAA,EAAA,mBACA,EAAA,EAAA,SAAA,WACA,EAAA,EAAA,UACA,EAAA,EAAA,UACA,EAAA,EAAA,iBACA,EAAA,EAAA,iBACA,EAAA,EAAA,wBACA,EAAA,EAAA,aACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,iBACA,EAAA,EAAA,OACA,EAAA,EAAA,OACA,EAAA,EAAA,KACA,EAAA,EAAA,uBAGA,GAFA,EAAA,aAEA,GAAA,SAMA,GAAA,UAAA,OAAA,OAAA,EAAA,WAEA,EAAA,EAAA,mBAIA,EAAA,EAAA,QACA,EAAA,EAAA,SAaA,gBACA,yBACA,gBACA,kBACA,cACA,gBACA,cACA,iBACA,kBACA,QAAA,EAEA,IAAA,GAAA,SAAA,UAuBA,EAAA,SAAA,YAqBA,IAnBA,EAAA,EAAA,WACA,UAAA,SAAA,GAIA,MAHA,GAAA,YACA,EAAA,WAAA,YAAA,GACA,EAAA,EAAA,MACA,GAEA,iBAAA,SAAA,EAAA,GACA,MAAA,GAAA,KAAA,KAAA,EAAA,IAEA,WAAA,SAAA,EAAA,GACA,MAAA,GAAA,EAAA,EAAA,KAAA,OAEA,aAAA,WAEA,MADA,KACA,GAAA,GAAA,EAAA,KAAA,EAAA,WAIA,SAAA,gBAAA,CACA,GAAA,GAAA,SAAA,eACA,GAAA,UAAA,gBAAA,SAAA,EAAA,GAiEA,QAAA,GAAA,GACA,MAAA,QAOA,KAAA,KAAA,GANA,EAAA,QACA,SAAA,cAAA,EAAA,QAAA,GAEA,SAAA,cAAA,GArEA,GAAA,GAAA,EAAA,SAIA,IAAA,EAAA,qBAAA,IAAA,GAEA,KAAA,IAAA,OAAA,oBASA,KAHA,GACA,GADA,EAAA,OAAA,eAAA,GAEA,KACA,KACA,EAAA,EAAA,qBAAA,IAAA,KAGA,EAAA,KAAA,GACA,EAAA,OAAA,eAAA,EAGA,KAAA,EAEA,KAAA,IAAA,OAAA,oBAQA,KAAA,GADA,GAAA,OAAA,OAAA,GACA,EAAA,EAAA,OAAA,EAAA,GAAA,EAAA,IACA,EAAA,OAAA,OAAA,IAQA,kBACA,mBACA,mBACA,4BACA,QAAA,SAAA,GACA,GAAA,GAAA,EAAA,EACA,KAEA,EAAA,GAAA,WAGA,EAAA,eAAA,IACA,EAAA,MAEA,EAAA,MAAA,EAAA,MAAA,cAIA,IAAA,IAAA,UAAA,EACA,GAAA,UACA,EAAA,QAAA,EAAA,SAYA,EAAA,UAAA,EACA,EAAA,UAAA,YAAA,EAEA,EAAA,iBAAA,IAAA,EAAA,GACA,EAAA,qBAAA,IAAA,EAAA,EAGA,GAAA,KAAA,EAAA,MACA,EAAA,EACA,OAAA,IAGA,GACA,OAAA,cAAA,OAAA,WAEA,oBAMA,GACA,OAAA,gBACA,OAAA,cAAA,OAAA,SACA,OAAA,gBACA,OAAA,kBAEA,cACA,0BACA,WACA,yBACA,uBACA,yBACA,eACA,gBACA,mBACA,cACA,gBACA,OAAA,IAEA,GACA,OAAA,cAAA,OAAA,WAEA,YACA,aACA,WACA,gBACA,yBACA,gBACA,kBACA,cACA,gBACA,cACA,iBACA,mBACA,iBACA,iBAGA,EAAA,EAAA,UAAA,GACA,EAAA,EAAA,UAAA,GACA,EAAA,EAAA,UAAA,GAEA,EAAA,EAAA,WACA,GAAA,kBACA,GAAA,GAAA,EAAA,IAAA,KACA,OAAA,GACA,GACA,EACA,GAAA,GAAA,EAAA,MAAA,gBACA,EAAA,IAAA,KAAA,GACA,MAIA,EAAA,OAAA,SAAA,EACA,SAAA,eAAA,mBAAA,KAIA,OAAA,cACA,EAAA,OAAA,aAAA,GAEA,GACA,OAAA,gBACA,OAAA,cAAA,OAAA,SACA,OAAA,kBAqBA,EAAA,EAAA,sBACA,EAAA,EAAA,kBACA,EAAA,EAAA,sBACA,EAAA,EAAA,cAEA,EAAA,OAAA,kBAAA,GAEA,GACA,OAAA,oBAEA,qBACA,iBACA,qBACA,eAGA,EAAA,kBAAA,EACA,EAAA,SAAA,kBAAA,EACA,EAAA,SAAA,SAAA,GAEA,OAAA,mBCrTA,SAAA,GACA,YAeA,SAAA,GAAA,GACA,EAAA,KAAA,KAAA,GAdA,GAAA,GAAA,EAAA,SAAA,YACA,EAAA,EAAA,SAAA,UACA,EAAA,EAAA,MACA,EAAA,EAAA,gBACA,EAAA,EAAA,iBACA,EAAA,EAAA,OACA,EAAA,EAAA,eACA,EAAA,EAAA,KAEA,EAAA,OAAA,OACA,EAAA,OAAA,iBACA,EAAA,OAAA,YAKA,GAAA,UAAA,OAAA,OAAA,EAAA,WAEA,EAAA,UAAA,iBAAA,SAAA,EAAA,GACA,MAAA,GAAA,MAAA,QAAA,iBAAA,EAAA,GAAA,IAGA,EAAA,UAAA,aAAA,WACA,MAAA,GAAA,MAAA,QAAA,sBAIA,QAAA,uBACA,QAAA,cAEA,mBAAA,sBAAA,iBAAA,QACA,SAAA,GACA,EAAA,UAAA,GAAA,WACA,GAAA,GAAA,EAAA,MAAA,OACA,OAAA,GAAA,GAAA,MAAA,EAAA,kBAIA,QAAA,KAGA,EAAA,EAAA,WACA,iBAAA,SAAA,EAAA,GAEA,MADA,KACA,EAAA,KAAA,EAAA,MAAA,EAAA,GACA,IAEA,aAAA,WAEA,MADA,KACA,GAAA,GAAA,EAAA,KAAA,EAAA,WAIA,EAAA,EAAA,GAEA,EAAA,SAAA,OAAA,GAEA,OAAA,mBC1DA,SAAA,GACA,YAEA,IAAA,GAAA,EAAA,OAMA,EAAA,OAAA,cAAA,OAAA,UACA,EACA,EAAA,UAAA,YAEA,GAAA,UAAA,aAAA,SAAA,EAAA,EAAA,GACA,EAAA,KAAA,KAAA,EAAA,GAAA,EAAA,KAGA,OAAA,mBCnBA,SAAA,GACA,YAsFA,SAAA,GAAA,GACA,GAAA,GAAA,EAAA,GACA,EAAA,OAAA,EACA,IAAA,EAAA,CAEA,GAAA,GAAA,SAAA,cAAA,GACA,EAAA,EAAA,WACA,QAAA,GAAA,GA3FA,GAIA,IAJA,EAAA,cAKA,EAAA,oBAKA,KAAA,kBACA,MAAA,mBACA,KAAA,kBACA,KAAA,kBACA,GAAA,gBACA,OAAA,oBACA,OAAA,oBACA,QAAA,0BACA,IAAA,sBAEA,QAAA,qBACA,KAAA,kBACA,SAAA,sBACA,IAAA,iBACA,IAAA,uBACA,IAAA,iBACA,GAAA,mBACA,MAAA,mBACA,SAAA,sBACA,KAAA,kBACA,KAAA,kBACA,MAAA,mBACA,SAAA,sBACA,GAAA,qBACA,KAAA,kBACA,GAAA,gBACA,KAAA,kBACA,OAAA,oBACA,IAAA,mBACA,MAAA,mBACA,OAAA,oBACA,MAAA,mBACA,OAAA,oBACA,GAAA,gBACA,KAAA,kBACA,IAAA,iBACA,QAAA,qBACA,KAAA,kBACA,SAAA,sBACA,KAAA,kBACA,MAAA,mBACA,OAAA,oBACA,GAAA,mBACA,SAAA,sBACA,OAAA,oBACA,OAAA,oBACA,EAAA,uBACA,MAAA,mBACA,IAAA,iBACA,SAAA,sBACA,EAAA,mBACA,OAAA,oBACA,OAAA,oBACA,OAAA,oBACA,OAAA,oBACA,KAAA,kBACA,MAAA,mBACA,MAAA,mBACA,MAAA,0BAKA,SAAA,sBACA,SAAA,sBACA,MAAA,0BACA,KAAA,kBACA,MAAA,mBACA,GAAA,sBACA,MAAA,mBACA,GAAA,mBACA,MAAA,oBAaA,QAAA,KAAA,GAAA,QAAA,GAEA,OAAA,oBAAA,EAAA,UAAA,QAAA,SAAA,GACA,OAAA,GAAA,EAAA,SAAA,MAGA,OAAA,mBCtGA,WAGA,OAAA,KAAA,kBAAA,aACA,OAAA,OAAA,kBAAA,eAkBA,OAAA,eAAA,QAAA,UAAA,mBACA,OAAA,yBAAA,QAAA,UAAA,cAEA,IAAA,GAAA,QAAA,UAAA,gBACA,SAAA,UAAA,iBAAA,WACA,GAAA,GAAA,EAAA,KAAA,KAEA,OADA,gBAAA,YAAA,MACA,GAGA,QAAA,UAAA,uBAAA,QAAA,UAAA,oBCmFA,SAAA,GA2ZA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAQA,OAPA,OAAA,UAAA,QAAA,KAAA,EAAA,SAAA,GACA,GAAA,EAAA,YAAA,SAGA,IACA,EAAA,EAAA,QAAA,EAAA,KAEA,EAGA,QAAA,GAAA,GACA,GAAA,GAAA,SAAA,cAAA,QAEA,OADA,GAAA,YAAA,EACA,EAGA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,EACA,UAAA,KAAA,YAAA,EACA,IAAA,KACA,IAAA,EAAA,MAIA,IACA,EAAA,EAAA,MAAA,SACA,MAAA,QAIA,SAAA,KAAA,kBAAA,EAGA,OADA,GAAA,WAAA,YAAA,GACA,EAMA,QAAA,KACA,EAAA,aAAA,EACA,SAAA,KAAA,YAAA,EACA,IAAA,GAAA,EAAA,gBACA,EAAA,EAAA,cAAA,OACA,GAAA,KAAA,SAAA,QACA,EAAA,KAAA,YAAA,GAGA,QAAA,GAAA,GACA,EAAA,aACA,IAEA,SAAA,KAAA,YAAA,GACA,EAAA,EAAA,iBACA,SAAA,KAAA,YAAA,GAMA,QAAA,GAAA,EAAA,GACA,GAAA,EAAA,CAGA,GAAA,EACA,IAAA,EAAA,MAAA,YAAA,EAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,SAAA,GACA,EAAA,KAAA,YAAA,EAAA,MACA,EAAA,EAAA,MAAA,SACA,EAAA,SAGA,GAAA,EAAA,GACA,EAAA,IAWA,QAAA,GAAA,GACA,GACA,IAAA,YAAA,SAAA,eAAA,IAIA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,EACA,GAAA,aAAA,EAAA,IACA,EAAA,aAAA,EAAA,IACA,SAAA,KAAA,YAAA,GAQA,QAAA,KAMA,MALA,KACA,EAAA,SAAA,cAAA,SACA,EAAA,aAAA,EAAA,IACA,EAAA,IAAA,GAEA,EAxgBA,GAAA,IACA,eAAA,EACA,YAMA,YAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,KAAA,YAAA,EAAA,EAAA,GACA,EAAA,KAAA,gBAAA,GACA,EAAA,KAAA,kBAAA,EAAA,GAGA,EAAA,EAAA,GAAA,EACA,GAAA,KAAA,aAAA,EAAA,GAEA,IACA,EAAA,aAAA,GAGA,KAAA,iBAAA,EAAA,IAMA,UAAA,SAAA,EAAA,GACA,MAAA,MAAA,YAAA,EAAA,YAAA,IAMA,YAAA,SAAA,EAAA,GAEA,MADA,GAAA,KAAA,iBAAA,GACA,KAAA,aAAA,EAAA,IAEA,kBAAA,SAAA,EAAA,GACA,MAAA,GACA,EAAA,OAAA,EAAA,IAAA,EAEA,IAEA,gBAAA,SAAA,GACA,MAAA,IAAA,EAAA,QAAA,KAAA,GAEA,YAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,KAAA,aAAA,EAAA,EAAA,EAQA,OAPA,MAAA,oBAAA,EAAA,WAAA,KAAA,kBAEA,KAAA,aAAA,EAAA,EAAA,YAEA,KAAA,eACA,KAAA,oBAAA,EAAA,GAEA,EAAA,aAEA,aAAA,SAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,EAAA,WAAA,YAAA,IAGA,aAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,KAAA,SAAA,IACA,KAAA,EACA,KAAA,EACA,YAAA,GAEA,EAAA,KAAA,WAAA,EACA,GAAA,WAAA,EACA,EAAA,YAAA,EAAA,UACA,IAAA,GAAA,KAAA,SAAA,EAAA,YAIA,QAHA,GAAA,IAAA,EAAA,cAAA,YACA,EAAA,YAAA,EAAA,YAAA,OAAA,EAAA,cAEA,GAEA,WAAA,SAAA,GACA,IAAA,EACA,QAEA,IAAA,GAAA,EAAA,iBAAA,QACA,OAAA,OAAA,UAAA,OAAA,KAAA,EAAA,SAAA,GACA,OAAA,EAAA,aAAA,MAGA,oBAAA,SAAA,EAAA,GACA,IAEA,MAAA,UAAA,QAAA,KAAA,EAAA,iBAAA,KACA,SAAA,GACA,EAAA,aAAA,EAAA,MAGA,MAAA,UAAA,QAAA,KAAA,EAAA,iBAAA,YACA,SAAA,GACA,KAAA,oBAAA,EAAA,QAAA,IAEA,QAGA,iBAAA,SAAA,GAEA,MADA,GAAA,KAAA,kCAAA,GACA,KAAA,6BAAA,IAgBA,kCAAA,SAAA,GAMA,MAJA,GAAA,EAAA,QAAA,EAAA,SAAA,EAAA,GAEA,MAAA,GAAA,MAAA,EAAA,IAAA,MAEA,EAAA,QAAA,EAAA,SAAA,EAAA,GACA,MAAA,GAAA,QAkBA,6BAAA,SAAA,GAMA,MAJA,GAAA,EAAA,QAAA,EAAA,SAAA,EAAA,GAEA,MAAA,GAAA,MAAA,EAAA,MAEA,EAAA,QAAA,EAAA,SAAA,EAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,QAAA,EAAA,IAAA,QAAA,EAAA,GACA,OAAA,GAAA,KAWA,aAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,gCAAA,EAKA,IAJA,EAAA,KAAA,4BAAA,GACA,EAAA,KAAA,iBAAA,GACA,EAAA,KAAA,qBAAA,GACA,EAAA,KAAA,mBAAA,GACA,EAAA,CACA,GAAA,GAAA,EAAA,IACA,GAAA,EAAA,SAAA,GACA,EAAA,EAAA,WAAA,EAAA,KAKA,MADA,GAAA,EAAA,KAAA,EACA,EAAA,QAgBA,gCAAA,SAAA,GAGA,IADA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,KAAA,IACA,GAAA,EAAA,GAAA,MAAA,EAAA,IAAA,MAEA,MAAA,EAAA,EAAA,KAAA,IACA,GAAA,EAAA,GAAA,QAAA,EAAA,GAAA,IAAA,QAAA,EAAA,GAAA,EAAA,IAAA,MAEA,OAAA,IASA,iBAAA,SAAA,GACA,MAAA,MAAA,iBAAA,EAAA,eACA,KAAA,wBAiBA,qBAAA,SAAA,GACA,MAAA,MAAA,iBAAA,EAAA,mBACA,KAAA,4BAEA,iBAAA,SAAA,EAAA,EAAA,GAEA,MAAA,GAAA,QAAA,EAAA,SAAA,EAAA,EAAA,EAAA,GAEA,GADA,EAAA,yBACA,EAAA,CAEA,IAAA,GAAA,GADA,EAAA,EAAA,MAAA,KAAA,KACA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,EAAA,EAAA,OACA,EAAA,KAAA,EAAA,EAAA,EAAA,GAEA,OAAA,GAAA,KAAA,KAEA,MAAA,GAAA,KAIA,0BAAA,SAAA,EAAA,EAAA,GACA,MAAA,GAAA,MAAA,GACA,KAAA,sBAAA,EAAA,EAAA,GAEA,EAAA,EAAA,EAAA,KAAA,EAAA,IAAA,EAAA,GAGA,sBAAA,SAAA,EAAA,EAAA,GACA,MAAA,GAAA,EAAA,QAAA,EAAA,IAAA,GAKA,mBAAA,SAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,cAAA,OAAA,IACA,EAAA,EAAA,QAAA,cAAA,GAAA,IAEA,OAAA,IAGA,WAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAgBA,OAfA,IACA,MAAA,UAAA,QAAA,KAAA,EAAA,SAAA,GACA,EAAA,cAAA,EAAA,OAAA,EAAA,MAAA,SACA,GAAA,KAAA,cAAA,EAAA,aAAA,EACA,KAAA,eAAA,QACA,GAAA,KAAA,mBAAA,GAAA,WACA,EAAA,OAAA,QAAA,YACA,GAAA,UAAA,EAAA,MAAA,UAAA,OACA,GAAA,KAAA,WAAA,EAAA,SAAA,GACA,GAAA,WACA,EAAA,UACA,GAAA,EAAA,QAAA,SAEA,MAEA,GAEA,cAAA,SAAA,EAAA,EAAA,GACA,GAAA,MAAA,EAAA,EAAA,MAAA,IAUA,OATA,GAAA,QAAA,SAAA,GACA,EAAA,EAAA,OACA,KAAA,qBAAA,EAAA,KACA,EAAA,IAAA,EAAA,MAAA,0BACA,KAAA,yBAAA,EAAA,GACA,KAAA,yBAAA,EAAA,IAEA,EAAA,KAAA,IACA,MACA,EAAA,KAAA,OAEA,qBAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,iBAAA,EACA,QAAA,EAAA,MAAA,IAEA,iBAAA,SAAA,GAEA,MADA,GAAA,EAAA,QAAA,MAAA,OAAA,QAAA,MAAA,OACA,GAAA,QAAA,KAAA,EAAA,IAAA,iBAAA,MAGA,yBAAA,SAAA,EAAA,GACA,MAAA,GAAA,MAAA,iBACA,EAAA,EAAA,QAAA,yBAAA,GACA,EAAA,QAAA,eAAA,EAAA,MAEA,EAAA,IAAA,GAKA,yBAAA,SAAA,EAAA,GACA,EAAA,EAAA,QAAA,mBAAA,KACA,IAAA,IAAA,IAAA,IAAA,IAAA,KACA,EAAA,EACA,EAAA,IAAA,EAAA,GAYA,OAXA,GAAA,QAAA,SAAA,GACA,GAAA,GAAA,EAAA,MAAA,EACA,GAAA,EAAA,IAAA,SAAA,GAEA,GAAA,GAAA,EAAA,OAAA,QAAA,eAAA,GAIA,OAHA,IAAA,EAAA,QAAA,GAAA,GAAA,EAAA,QAAA,GAAA,IACA,EAAA,EAAA,QAAA,kBAAA,KAAA,EAAA,SAEA,IACA,KAAA,KAEA,GAEA,4BAAA,SAAA,GACA,MAAA,GAAA,QAAA,OAAA,GAAA,QAAA,YACA,GAAA,QAAA,gBAAA,IAEA,mBAAA,SAAA,GAGA,MAAA,GAAA,MAAA,UAAA,EAAA,MAAA,QAAA,MAAA,SACA,EAAA,MAAA,QAAA,QAAA,kBAAA,aACA,EAAA,MAAA,QAAA,MAEA,EAAA,MAAA,SAEA,oBAAA,SAAA,EAAA,GACA,GAAA,IACA,YAAA,SACA,GAAA,IAEA,MAAA,UAAA,QAAA,KAAA,EAAA,SAAA,GACA,EAAA,YAAA,EAAA,KAAA,KAAA,EAAA,cACA,QAGA,iBAAA,SAAA,EAAA,GACA,EAAA,MAAA,WACA,EAAA,EAAA,GAEA,EAAA,KAMA,EAAA,oCAEA,EAAA,4DACA,EAAA,uEAEA,EAAA,sDACA,EAAA,+DAEA,EAAA,+DACA,EAAA,wEAIA,EAAA,iBAEA,EAAA,qBACA,EAAA,iDAGA,gBAAA,GAAA,QAAA,IAAA,EAAA,EAAA,OACA,mBAAA,GAAA,QAAA,IAAA,EAAA,EAAA,OACA,iBAAA,6BACA,OAAA,WACA,YAAA,YACA,gBAAA,gBAEA,yBAAA,EAAA,iBACA,eAAA,GAAA,QAAA,EAAA,OACA,mBAAA,GAAA,QAAA,EAAA,OACA,eACA,QACA,MACA,cACA,mBAyCA,IAAA,GAAA,SAAA,cAAA,SACA,GAAA,MAAA,QAAA,MAsBA,IA2CA,GA3CA,EAAA,UAAA,UAAA,MAAA,UAuCA,EAAA,iBACA,EAAA,qBACA,EAAA,SAaA,IAAA,OAAA,kBAAA,CACA,EAAA,wCACA,IAAA,GAAA,KAAA,UACA,EAAA,EAAA,cAAA,OACA,GAAA,aAAA,IAAA,EAAA,WAAA,IAIA,SAAA,iBAAA,mBAAA,WACA,GAAA,GAAA,EAAA,WAEA,IAAA,OAAA,cAAA,YAAA,UAAA,CACA,GAAA,GAAA,wBACA,EAAA,IACA,EAAA,SAAA,EAAA,GACA,aAAA,SAAA,0BAAA,IAAA,EACA,YAAA,SAAA,yBAAA,IAAA,EAEA,YAAA,OAAA,mBACA,YAAA,OAAA,kBACA,EACA,GACA,KAAA,IAEA,IAAA,GAAA,YAAA,OAAA,YAEA,aAAA,OAAA,aAAA,SAAA,GACA,IAAA,EAAA,GAAA,CAGA,GAAA,GAAA,EAAA,iBAAA,CACA,KAAA,EAAA,aAAA,GAEA,WADA,GAAA,KAAA,KAAA,EAGA,GAAA,YACA,EAAA,EAAA,cAAA,cAAA,SACA,EAAA,YAAA,EAAA,eACA,EAAA,WAAA,EAAA,OAEA,EAAA,aAAA,GAEA,EAAA,YAAA,EAAA,UAAA,GACA,EAAA,gBAAA,EAAA,IACA,EAAA,aAAA,EAAA,IACA,EAAA,IAAA,EAEA,EAAA,aAAA,IAEA,EAAA,aAAA,EACA,EAAA,aAAA,EAAA,GAEA,EAAA,YAAA,IAGA,EAAA,gBAAA,EACA,KAAA,oBAAA,IAGA,IAAA,GAAA,YAAA,OAAA,WACA,aAAA,OAAA,YAAA,SAAA,GACA,MAAA,SAAA,EAAA,WAAA,eAAA,EAAA,KACA,EAAA,aAAA,GACA,EAAA,WAEA,EAAA,KAAA,KAAA,OASA,EAAA,UAAA,GAEA,OAAA,YC7sBA,WAGA,OAAA,gBAAA,OAAA,iBAAA,SAAA,GACA,MAAA,GAAA,SAKA,OAAA,KAAA,OAAA,OAAA,SAAA,GACA,MAAA,GAGA,IAAA,GAAA,QAAA,UAAA,sBACA,SAAA,UAAA,uBAAA,WACA,GAAA,GAAA,KAAA,iBACA,EAAA,EAAA,KAAA,KAIA,OAHA,GAAA,gBAAA,EACA,EAAA,KAAA,KACA,eAAA,YAAA,MACA,GAGA,OAAA,iBAAA,QAAA,WACA,YACA,IAAA,WACA,MAAA,MAAA,mBAGA,kBACA,MAAA,WACA,MAAA,MAAA,6BAKA,OAAA,gBAAA,SAAA,GAOA,GALA,OAAA,qBAAA,oBAAA,WACA,oBAAA,UAAA,IAIA,EAAA,UAAA,EAAA,SAAA,CAEA,IADA,GAAA,GAAA,SAAA,yBACA,EAAA,YACA,EAAA,YAAA,EAAA,WAEA,GAAA,SAAA,EAEA,MAAA,GAAA,SAAA,EAAA,aCpDA,SAAA,GACA,YA6BA,SAAA,GAAA,GACA,MAAA,UAAA,EAAA,GAGA,QAAA,KACA,EAAA,KAAA,MACA,KAAA,YAAA,EAGA,QAAA,GAAA,GAKA,MAJA,IAAA,GACA,EAAA,KAAA,MAGA,EAAA,cAGA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,WAAA,EACA,OAAA,GAAA,IACA,IAAA,GAEA,KAAA,GAAA,GAAA,GAAA,GAAA,GAAA,IAAA,QAAA,GAEA,EAEA,mBAAA,GAGA,QAAA,GAAA,GAIA,GAAA,GAAA,EAAA,WAAA,EACA,OAAA,GAAA,IACA,IAAA,GAEA,KAAA,GAAA,GAAA,GAAA,GAAA,IAAA,QAAA,GAEA,EAEA,mBAAA,GAOA,QAAA,GAAA,EAAA,EAAA,GACA,QAAA,GAAA,GACA,EAAA,KAAA,GAGA,GAAA,GAAA,GAAA,eACA,EAAA,EACA,EAAA,GACA,GAAA,EACA,GAAA,EACA,IAEA,GAAA,MAAA,EAAA,EAAA,IAAA,GAAA,GAAA,KAAA,KAAA,YAAA,CACA,GAAA,GAAA,EAAA,EACA,QAAA,GACA,IAAA,eACA,IAAA,IAAA,EAAA,KAAA,GAGA,CAAA,GAAA,EAIA,CACA,EAAA,kBACA,MAAA,GALA,EAAA,GACA,EAAA,WACA,UALA,GAAA,EAAA,cACA,EAAA,QASA,MAEA,KAAA,SACA,GAAA,GAAA,EAAA,KAAA,GACA,GAAA,EAAA,kBACA,CAAA,GAAA,KAAA,EAkBA,CAAA,GAAA,EAKA,CAAA,GAAA,GAAA,EACA,KAAA,EAEA,GAAA,qCAAA,EACA,MAAA,GARA,EAAA,GACA,EAAA,EACA,EAAA,WACA,UAnBA,GAFA,KAAA,QAAA,EACA,EAAA,GACA,EACA,KAAA,EAEA,GAAA,KAAA,WACA,KAAA,aAAA,GAGA,EADA,QAAA,KAAA,QACA,WACA,KAAA,aAAA,GAAA,EAAA,SAAA,KAAA,QACA,wBACA,KAAA,YACA,wBAEA,cAaA,KAEA,KAAA,cACA,KAAA,GACA,MAAA,IACA,EAAA,SACA,KAAA,GACA,KAAA,UAAA,IACA,EAAA,YAGA,GAAA,GAAA,KAAA,GAAA,MAAA,GAAA,MAAA,IACA,KAAA,aAAA,EAAA,GAGA,MAEA,KAAA,YACA,GAAA,GAAA,EAAA,EAAA,SAGA,CACA,EAAA,UACA,UAJA,EAAA,mBACA,EAAA,KAAA,KAKA,MAEA,KAAA,wBACA,GAAA,KAAA,GAAA,KAAA,EAAA,EAAA,GAEA,CACA,EAAA,oBAAA,GACA,EAAA,UACA,UAJA,EAAA,0BAMA,MAEA,KAAA,WAIA,GAHA,KAAA,aAAA,EACA,QAAA,KAAA,UACA,KAAA,QAAA,EAAA,SACA,GAAA,EAAA,CACA,KAAA,MAAA,EAAA,MACA,KAAA,MAAA,EAAA,MACA,KAAA,MAAA,EAAA,MAAA,QACA,KAAA,OAAA,EAAA,MACA,MAAA,GACA,GAAA,KAAA,GAAA,MAAA,EACA,MAAA,GACA,EAAA,gCACA,EAAA,qBACA,IAAA,KAAA,EACA,KAAA,MAAA,EAAA,MACA,KAAA,MAAA,EAAA,MACA,KAAA,MAAA,EAAA,MAAA,QACA,KAAA,OAAA,IACA,EAAA,YACA,CAAA,GAAA,KAAA,EAOA,CACA,GAAA,GAAA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,IAEA,QAAA,KAAA,UAAA,EAAA,KAAA,IACA,KAAA,GAAA,KAAA,GACA,GAAA,GAAA,KAAA,GAAA,MAAA,GAAA,KAAA,GAAA,KAAA,KACA,KAAA,MAAA,EAAA,MACA,KAAA,MAAA,EAAA,MACA,KAAA,MAAA,EAAA,MAAA,QACA,KAAA,MAAA,OAEA,EAAA,eACA,UAnBA,KAAA,MAAA,EAAA,MACA,KAAA,MAAA,EAAA,MACA,KAAA,MAAA,EAAA,MAAA,QACA,KAAA,OAAA,EAAA,OACA,KAAA,UAAA,IACA,EAAA,WAgBA,KAEA,KAAA,iBACA,GAAA,KAAA,GAAA,MAAA,EASA,CACA,QAAA,KAAA,UACA,KAAA,MAAA,EAAA,MACA,KAAA,MAAA,EAAA,OAEA,EAAA,eACA,UAdA,MAAA,GACA,EAAA,gCAGA,EADA,QAAA,KAAA,QACA,YAEA,0BAUA,MAEA,KAAA,wBACA,GAAA,KAAA,EAEA,CACA,EAAA,sBAAA,GACA,EAAA,0BACA,UAJA,EAAA,wBAMA,MAEA,KAAA,yBAEA,GADA,EAAA,2BACA,KAAA,EAAA,CACA,EAAA,sBAAA,EACA,UAEA,KAEA,KAAA,2BACA,GAAA,KAAA,GAAA,MAAA,EAAA,CACA,EAAA,WACA,UAEA,EAAA,4BAAA,EAEA,MAEA,KAAA,YACA,GAAA,KAAA,EAAA,CACA,IACA,EAAA,mBACA,GAAA,OAEA,GAAA,CACA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IAAA,KAAA,GAAA,MAAA,GAAA,MAAA,EAKA,GAAA,KAAA,GAAA,OAAA,KAAA,UAAA,CAIA,GAAA,GAAA,EAAA,EACA,QAAA,KAAA,UAAA,KAAA,WAAA,EAAA,KAAA,WAAA,MAJA,MAAA,UAAA,OALA,GAAA,oCAWA,EAAA,OACA,CAAA,GAAA,GAAA,GAAA,KAAA,GAAA,MAAA,GAAA,KAAA,GAAA,KAAA,EAAA,CACA,GAAA,EAAA,OACA,EAAA,GACA,EAAA,MACA,UAEA,GAAA,EAEA,KAEA,KAAA,YACA,GAAA,GAAA,GAAA,KAAA,GAAA,MAAA,GAAA,KAAA,GAAA,KAAA,EAAA,CACA,GAAA,EAAA,SAAA,EAAA,KAAA,EAAA,KAAA,KAAA,EAAA,IAAA,KAAA,EAAA,GAEA,GAAA,EAAA,OACA,EAAA,uBAEA,KAAA,MAAA,EAAA,KAAA,KAAA,GACA,EAAA,GACA,EAAA,uBANA,EAAA,eAQA,UACA,KAAA,GAAA,MAAA,GAAA,MAAA,EACA,EAAA,oCAEA,GAAA,CAEA,MAEA,KAAA,OACA,IAAA,WACA,GAAA,KAAA,GAAA,EAQA,CAAA,GAAA,GAAA,GAAA,KAAA,GAAA,MAAA,GAAA,KAAA,GAAA,KAAA,EAAA,CAIA,GAHA,KAAA,MAAA,EAAA,KAAA,KAAA,GACA,EAAA,GACA,EAAA,sBACA,EACA,KAAA,EAEA,UACA,KAAA,GAAA,MAAA,GAAA,MAAA,GACA,KAAA,EACA,GAAA,EACA,KAAA,IACA,GAAA,GAEA,GAAA,GAEA,EAAA,wCAAA,OAnBA,IAHA,KAAA,MAAA,EAAA,KAAA,KAAA,GACA,EAAA,GACA,EAAA,OACA,YAAA,EACA,KAAA,EAoBA,MAEA,KAAA,OACA,GAAA,QAAA,KAAA,GACA,GAAA,MACA,CAAA,GAAA,GAAA,GAAA,KAAA,GAAA,MAAA,GAAA,KAAA,GAAA,KAAA,GAAA,EAAA,CACA,GAAA,IAAA,EAAA,CACA,GAAA,GAAA,SAAA,EAAA,GACA,IAAA,EAAA,KAAA,WACA,KAAA,MAAA,EAAA,IAEA,EAAA,GAEA,GAAA,EACA,KAAA,EAEA,GAAA,qBACA,UACA,KAAA,GAAA,MAAA,GAAA,MAAA,EACA,EAAA,+BAAA,GAEA,EAAA,KAAA,MAEA,KAEA,KAAA,sBAIA,GAHA,MAAA,GACA,EAAA,6BACA,EAAA,gBACA,KAAA,GAAA,MAAA,EACA,QAEA,MAEA,KAAA,gBACA,GAAA,GAAA,GAAA,KAAA,GAAA,MAAA,IAAA,GAAA,KAAA,GAAA,KAAA,GA6BA,KAAA,GAAA,MAAA,GAAA,MAAA,IACA,GAAA,EAAA,QA9BA,CACA,MAAA,GACA,EAAA,mCAEA,IAAA,IACA,EAAA,EAAA,EAAA,kBACA,EAAA,GAEA,MAAA,GACA,KAAA,MAAA,MACA,KAAA,GAAA,MAAA,GACA,KAAA,MAAA,KAAA,KAEA,KAAA,GAAA,KAAA,GAAA,MAAA,EACA,KAAA,MAAA,KAAA,IACA,KAAA,IACA,QAAA,KAAA,SAAA,GAAA,KAAA,MAAA,QAAA,GAAA,EAAA,QAAA,EAAA,KAAA,EAAA,KAAA,KAAA,EAAA,KACA,EAAA,EAAA,GAAA,KAEA,KAAA,MAAA,KAAA,IAEA,EAAA,GACA,KAAA,GACA,KAAA,OAAA,IACA,EAAA,SACA,KAAA,IACA,KAAA,UAAA,IACA,EAAA,YAKA,KAEA,KAAA,QACA,GAAA,KAAA,EAGA,GAAA,GAAA,KAAA,GAAA,MAAA,GAAA,MAAA,IACA,KAAA,QAAA,EAAA,KAHA,KAAA,UAAA,IACA,EAAA,WAIA,MAEA,KAAA,WACA,GAAA,GAAA,KAAA,GAAA,MAAA,GAAA,MAAA,IACA,KAAA,WAAA,GAKA,KAIA,QAAA,KACA,KAAA,QAAA,GACA,KAAA,YAAA,GACA,KAAA,UAAA,GACA,KAAA,UAAA,KACA,KAAA,MAAA,GACA,KAAA,MAAA,GACA,KAAA,SACA,KAAA,OAAA,GACA,KAAA,UAAA,GACA,KAAA,YAAA,EACA,KAAA,aAAA,EAKA,QAAA,GAAA,EAAA,GACA,SAAA,GAAA,YAAA,KACA,EAAA,GAAA,GAAA,OAAA,KAEA,KAAA,KAAA,EACA,EAAA,KAAA,KAEA,IAAA,GAAA,EAAA,QAAA,+BAAA,GAGA,GAAA,KAAA,KAAA,EAAA,KAAA,GAzcA,GAAA,IAAA,CACA,KAAA,EAAA,UACA,IACA,GAAA,GAAA,GAAA,KAAA,IAAA,WACA,GAAA,eAAA,EAAA,KACA,MAAA,IAGA,IAAA,EAAA,CAGA,GAAA,GAAA,OAAA,OAAA,KACA,GAAA,IAAA,GACA,EAAA,KAAA,EACA,EAAA,OAAA,GACA,EAAA,KAAA,GACA,EAAA,MAAA,IACA,EAAA,GAAA,GACA,EAAA,IAAA,GAEA,IAAA,GAAA,OAAA,OAAA,KACA,GAAA,OAAA,IACA,EAAA,QAAA,KACA,EAAA,QAAA,KACA,EAAA,UAAA,IA8CA,IAAA,GAAA,OACA,EAAA,WACA,EAAA,mBAoYA,GAAA,WACA,GAAA,QACA,GAAA,KAAA,WACA,MAAA,MAAA,IAEA,IAAA,GAAA,EAMA,QALA,IAAA,KAAA,WAAA,MAAA,KAAA,aACA,EAAA,KAAA,WACA,MAAA,KAAA,UAAA,IAAA,KAAA,UAAA,IAAA,KAGA,KAAA,UACA,KAAA,YAAA,KAAA,EAAA,KAAA,KAAA,IACA,KAAA,SAAA,KAAA,OAAA,KAAA,WAEA,GAAA,MAAA,GACA,EAAA,KAAA,MACA,EAAA,KAAA,KAAA,IAGA,GAAA,YACA,MAAA,MAAA,QAAA,KAEA,GAAA,UAAA,GACA,KAAA,YAEA,EAAA,KAAA,KAAA,EAAA,IAAA,iBAGA,GAAA,QACA,MAAA,MAAA,WAAA,GAAA,KAAA,MACA,KAAA,MAAA,IAAA,KAAA,MAAA,KAAA,OAEA,GAAA,MAAA,IACA,KAAA,YAAA,KAAA,aAEA,EAAA,KAAA,KAAA,EAAA,SAGA,GAAA,YACA,MAAA,MAAA,OAEA,GAAA,UAAA,IACA,KAAA,YAAA,KAAA,aAEA,EAAA,KAAA,KAAA,EAAA,aAGA,GAAA,QACA,MAAA,MAAA,OAEA,GAAA,MAAA,IACA,KAAA,YAAA,KAAA,aAEA,EAAA,KAAA,KAAA,EAAA,SAGA,GAAA,YACA,MAAA,MAAA,WAAA,GAAA,KAAA,YACA,IAAA,KAAA,MAAA,KAAA,KAAA,KAAA,aAEA,GAAA,UAAA,IACA,KAAA,YAAA,KAAA,cAEA,KAAA,SACA,EAAA,KAAA,KAAA,EAAA,yBAGA,GAAA,UACA,MAAA,MAAA,aAAA,KAAA,QAAA,KAAA,KAAA,OACA,GAAA,KAAA,QAEA,GAAA,QAAA,IACA,KAAA,YAAA,KAAA,cAEA,KAAA,OAAA,IACA,KAAA,EAAA,KACA,EAAA,EAAA,MAAA,IACA,EAAA,KAAA,KAAA,EAAA,WAGA,GAAA,QACA,MAAA,MAAA,aAAA,KAAA,WAAA,KAAA,KAAA,UACA,GAAA,KAAA,WAEA,GAAA,MAAA,GACA,KAAA,aAEA,KAAA,UAAA,IACA,KAAA,EAAA,KACA,EAAA,EAAA,MAAA,IACA,EAAA,KAAA,KAAA,EAAA,eAIA,EAAA,IAAA,IAEA,QC9iBA,SAAA,GAmBA,QAAA,GAAA,GAEA,IAAA,GADA,GAAA,MACA,EAAA,EAAA,EAAA,UAAA,OAAA,IAAA,CACA,GAAA,GAAA,UAAA,EACA,KACA,IAAA,GAAA,KAAA,GACA,EAAA,EAAA,EAAA,GAEA,MAAA,KAGA,MAAA,GAIA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,EAAA,EACA,QAAA,eAAA,EAAA,EAAA,GAKA,QAAA,GAAA,EAAA,GACA,GAAA,EAAA,CACA,GAAA,GAAA,OAAA,yBAAA,EAAA,EACA,OAAA,IAAA,EAAA,OAAA,eAAA,GAAA,IAxCA,SAAA,UAAA,OACA,SAAA,UAAA,KAAA,SAAA,GACA,GAAA,GAAA,KACA,EAAA,MAAA,UAAA,MAAA,KAAA,UAAA,EACA,OAAA,YACA,GAAA,GAAA,EAAA,OAEA,OADA,GAAA,KAAA,MAAA,EAAA,WACA,EAAA,MAAA,EAAA,MAuCA,EAAA,MAAA,GAEA,OAAA,UC5CA,SAAA,GAEA,YAiFA,SAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,gBAAA,GACA,SAAA,cAAA,GAAA,EAAA,WAAA,EAEA,IADA,EAAA,UAAA,EACA,EACA,IAAA,GAAA,KAAA,GACA,EAAA,aAAA,EAAA,EAAA,GAGA,OAAA,GAnFA,GAAA,GAAA,aAAA,UAAA,IACA,EAAA,aAAA,UAAA,MACA,cAAA,UAAA,IAAA,WACA,IAAA,GAAA,GAAA,EAAA,EAAA,UAAA,OAAA,IACA,EAAA,KAAA,KAAA,UAAA,KAGA,aAAA,UAAA,OAAA,WACA,IAAA,GAAA,GAAA,EAAA,EAAA,UAAA,OAAA,IACA,EAAA,KAAA,KAAA,UAAA,KAGA,aAAA,UAAA,OAAA,SAAA,EAAA,GACA,GAAA,UAAA,SACA,GAAA,KAAA,SAAA,IAEA,EAAA,KAAA,IAAA,GAAA,KAAA,OAAA,IAEA,aAAA,UAAA,OAAA,SAAA,EAAA,GACA,GAAA,KAAA,OAAA,GACA,GAAA,KAAA,IAAA,GAKA,IAAA,GAAA,WACA,MAAA,OAAA,UAAA,MAAA,KAAA,OAGA,EAAA,OAAA,cAAA,OAAA,mBAQA,IANA,SAAA,UAAA,MAAA,EACA,EAAA,UAAA,MAAA,EACA,eAAA,UAAA,MAAA,GAIA,OAAA,YAAA,CACA,GAAA,GAAA,KAAA,KAEA,QAAA,aAAA,IAAA,WAAA,MAAA,MAAA,MAAA,IAKA,OAAA,wBACA,OAAA,sBAAA,WACA,GAAA,GAAA,OAAA,6BACA,OAAA,wBAEA,OAAA,GACA,SAAA,GACA,MAAA,GAAA,WACA,EAAA,YAAA,UAGA,SAAA,GACA,MAAA,QAAA,WAAA,EAAA,IAAA,SAKA,OAAA,uBACA,OAAA,qBAAA,WACA,MAAA,QAAA,4BACA,OAAA,yBACA,SAAA,GACA,aAAA,OAwBA,IAAA,MAEA,EAAA,WACA,EAAA,KAAA,WAEA,QAAA,QAAA,EAGA,EAAA,oBAAA,WAIA,MAHA,GAAA,oBAAA,WACA,KAAA,0CAEA,GAMA,OAAA,iBAAA,mBAAA,WACA,OAAA,UAAA,IACA,OAAA,QAAA,WACA,QAAA,MAAA,sIAQA,EAAA,UAAA,GAEA,OAAA,UC1IA,OAAA,gBAAA,OAAA,iBAAA,SAAA,GACA,MAAA,GAAA,SCRA,SAAA,GAEA,EAAA,IAAA,OAAA,aAEA,IAAA,EAEA,QAAA,SAAA,SAAA,EAAA,GACA,IACA,EAAA,OAAA,KAAA,GAAA,sBAAA,MAAA,GACA,EAAA,SAAA,MAAA,GAEA,EAAA,KACA,UAAA,YAGA,EAAA,GAAA,KAAA,SAAA,MAAA,GAGA,IAAA,IACA,kBACA,SACA,WACA,yCACA,cACA,eACA,UACA,cACA,8CACA,8BACA,UACA,cACA,yBACA,UACA,aACA,sBACA,uBACA,6BACA,UACA,aACA,kCACA,sCACA,6BACA,+BACA,8BACA,UACA,eACA,YACA,WACA,uBACA,YACA,4BACA,YACA,WACA,KAAA,MAEA,KAEA,EAAA,WAEA,GAAA,GAAA,EAAA,SAEA,EAAA,EAAA,cAAA,UAEA;EAAA,YAAA,EAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,GAAA,IAAA,CACA,GAAA,GAAA,EAAA,cAAA,IACA,GAAA,KAAA,IACA,EAAA,YAAA,EAAA,UACA,EAAA,IAAA,EACA,EAAA,QAAA,SAAA,GAEA,IADA,GAAA,GACA,EAAA,OAAA,KAAA,KACA,EAAA,EAAA,KAEA,GAAA,EAAA,QAAA,EAAA,GACA,EAAA,kBAEA,EAAA,YAAA,EAAA,cAAA,OAAA,YAAA,KAIA,EAAA,SAAA,EAAA,GAEA,GAAA,GAAA,EAAA,QAEA,KAEA,IAAA,GAAA,GAAA,CACA,GAAA,KAAA,GAEA,IAEA,EAAA,KAAA,cAAA,SAAA,UACA,QAAA,EAAA,EAAA,EAAA,YAAA,UAGA,EAAA,MAAA,UAAA,QAAA,KAAA,KAAA,MAAA,UAAA,SAEA,GAAA,MAAA,EAAA,OAAA,EAAA,WAAA,EAAA,SAAA,GACA,EAAA,SAAA,GACA,MAAA,GAAA,EAAA,WAGA,EAAA,SAAA,EAAA,EAAA,GACA,GAAA,EAAA,GACA,MAAA,EAEA,IAAA,GAAA,GAAA,EACA,IAAA,EAAA,WAAA,IAAA,EAAA,SAAA,CACA,GAAA,GAAA,EAAA,WAAA,cAEA,EAAA,EAAA,EAAA,EAOA,YAAA,IACA,EAAA,EAAA,uBAEA,GAAA,OACA,IAAA,GAAA,EAAA,cACA,GAAA,EAAA,SAAA,GACA,GAAA,EAAA,EAAA,EAAA,WAAA,KAEA,GAAA,GAEA,GAAA,GAAA,KACA,GAAA,aAAA,EAAA,aACA,GAAA,aAEA,CACA,GAAA,GAAA,EAAA,YAAA,MACA,GAAA,EAAA,EAAA,IAAA,EAAA,SAAA,GAEA,MAAA,IAWA,KAEA,EAAA,SAAA,GACA,GAAA,GAAA,YACA,EAAA,EAAA,WAAA,aAcA,OAbA,GAAA,kBAAA,EAAA,YACA,GAAA,iBAAA,EAAA,OACA,wCAAA,EAAA,YACA,EAAA,KAAA,IAEA,GAAA,GAAA,cAEA,EAAA,YACA,EAAA,EAAA,WAAA,SAAA,GACA,GAAA,IAAA,EAAA,MAAA,EAAA,MAAA,KAAA,EAAA,MAAA,IAAA,MAGA,GAAA,aAMA,WAAA,WACA,GAAA,GAAA,OAAA,KAAA,WAAA,IAAA,OAEA,EAAA,EAAA,EACA,GACA,EAAA,EAAA,kBAAA,EAAA,WAAA,IAEA,QAAA,IAAA,sBACA,QAAA,IAAA,QAMA,EAAA,OAAA,GAEA,OAAA,WCtLA,WASA,GAAA,GAAA,SAAA,cAAA,QACA,GAAA,YAAA,kHAQA,IAAA,GAAA,SAAA,cAAA,OACA,GAAA,aAAA,EAAA,EAAA,aAEA,UC1BA,SAAA,GAEA,QAAA,GAAA,EAAA,GAKA,MAJA,GAAA,MACA,EAAA,MACA,GAAA,IAEA,EAAA,MAAA,KAAA,EAAA,IAAA,IAGA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,EACA,QAAA,UAAA,QACA,IAAA,GACA,MACA,KAAA,GACA,EAAA,IACA,MACA,KAAA,GACA,EAAA,EAAA,MAAA,KACA,MACA,SACA,EAAA,EAAA,EAAA,GAGA,EAAA,GAAA,EAGA,QAAA,GAAA,GACA,MAAA,GAAA,GAKA,QAAA,GAAA,EAAA,GACA,YAAA,iBAAA,WACA,EAAA,EAAA,KAJA,GAAA,KAUA,GAAA,QAAA,EACA,EAAA,OAAA,EACA,EAAA,MAAA,GAEA,QCzCA,SAAA,GAMA,QAAA,GAAA,GACA,EAAA,YAAA,IACA,EAAA,KAAA,GAGA,QAAA,KACA,KAAA,EAAA,QACA,EAAA,UAXA,GAAA,GAAA,EACA,KACA,EAAA,SAAA,eAAA,GAaA,KAAA,OAAA,kBAAA,oBAAA,GACA,QAAA,GAAA,eAAA,IAKA,EAAA,eAAA,GAEA,UCxBA,SAAA,GAmEA,QAAA,GAAA,EAAA,EAAA,GACA,MAAA,GAAA,QAAA,EAAA,SAAA,EAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,QAAA,QAAA,GAEA,OADA,GAAA,EAAA,EAAA,GACA,EAAA,IAAA,EAAA,IAAA,IAIA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,GAAA,KAAA,EAAA,EACA,OAAA,GAAA,EAAA,MAGA,QAAA,GAAA,GACA,GAAA,GAAA,SAAA,QACA,EAAA,GAAA,KAAA,EAAA,EACA,OAAA,GAAA,OAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MACA,EAAA,WAAA,EAAA,SACA,EAAA,EAAA,SAAA,EAAA,UAEA,EAKA,QAAA,GAAA,EAAA,GAGA,IAFA,GAAA,GAAA,EAAA,MAAA,KACA,EAAA,EAAA,MAAA,KACA,EAAA,QAAA,EAAA,KAAA,EAAA,IACA,EAAA,QACA,EAAA,OAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,EAAA,IACA,EAAA,QAAA,KAEA,OAAA,GAAA,KAAA,KApGA,GAAA,IACA,WAAA,SAAA,EAAA,GACA,EAAA,GAAA,EAAA,cAAA,QACA,KAAA,kBAAA,EAAA,GACA,KAAA,cAAA,EAAA,EAEA,IAAA,GAAA,EAAA,iBAAA,WACA,IAAA,EACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,EAAA,SACA,KAAA,WAAA,EAAA,QAAA,IAKA,gBAAA,SAAA,GACA,KAAA,WAAA,EAAA,QAAA,EAAA,cAAA,UAEA,cAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,iBAAA,QACA,IAAA,EACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,KAAA,aAAA,EAAA,IAIA,aAAA,SAAA,EAAA,GACA,EAAA,GAAA,EAAA,cAAA,QACA,EAAA,YAAA,KAAA,eAAA,EAAA,YAAA,IAEA,eAAA,SAAA,EAAA,GAEA,MADA,GAAA,EAAA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,IAEA,kBAAA,SAAA,EAAA,GACA,EAAA,eAAA,EAAA,iBACA,KAAA,yBAAA,EAAA,EAGA,IAAA,GAAA,GAAA,EAAA,iBAAA,EACA,IAAA,EACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,KAAA,yBAAA,EAAA,IAIA,yBAAA,SAAA,EAAA,GACA,EAAA,GAAA,EAAA,cAAA,QACA,EAAA,QAAA,SAAA,GACA,GAAA,GAAA,EAAA,WAAA,EACA,IAAA,GAAA,EAAA,OACA,EAAA,MAAA,OAAA,GAAA,EAAA,CACA,GAAA,GAAA,EAAA,EAAA,EAAA,MACA,GAAA,MAAA,OAMA,EAAA,sBACA,EAAA,qCACA,GAAA,OAAA,MAAA,UACA,EAAA,IAAA,EAAA,KAAA,OAAA,IACA,EAAA,QAyCA,GAAA,YAAA,GAEA,UC5GA,SAAA,GAoCA,QAAA,GAAA,GACA,EAAA,KAAA,GACA,IACA,GAAA,EACA,EAAA,IAIA,QAAA,GAAA,GACA,MAAA,QAAA,mBACA,OAAA,kBAAA,aAAA,IACA,EAGA,QAAA,KAGA,GAAA,CAEA,IAAA,GAAA,CACA,MAEA,EAAA,KAAA,SAAA,EAAA,GACA,MAAA,GAAA,KAAA,EAAA,MAGA,IAAA,IAAA,CACA,GAAA,QAAA,SAAA,GAGA,GAAA,GAAA,EAAA,aAEA,GAAA,GAGA,EAAA,SACA,EAAA,UAAA,EAAA,GACA,GAAA,KAKA,GACA,IAGA,QAAA,GAAA,GACA,EAAA,OAAA,QAAA,SAAA,GACA,GAAA,GAAA,EAAA,IAAA,EACA,IAEA,EAAA,QAAA,SAAA,GACA,EAAA,WAAA,GACA,EAAA,+BAiBA,QAAA,GAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,WAAA,CACA,GAAA,GAAA,EAAA,IAAA,EAEA,IAAA,EACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,OAGA,IAAA,IAAA,GAAA,EAAA,QAAA,CAGA,GAAA,GAAA,EAAA,EACA,IACA,EAAA,QAAA,MAaA,QAAA,GAAA,GACA,KAAA,UAAA,EACA,KAAA,UACA,KAAA,YACA,KAAA,OAAA,EAoFA,QAAA,GAAA,EAAA,GACA,KAAA,KAAA,EACA,KAAA,OAAA,EACA,KAAA,cACA,KAAA,gBACA,KAAA,gBAAA,KACA,KAAA,YAAA,KACA,KAAA,cAAA,KACA,KAAA,mBAAA,KACA,KAAA,SAAA,KAGA,QAAA,GAAA,GACA,GAAA,GAAA,GAAA,GAAA,EAAA,KAAA,EAAA,OAQA,OAPA,GAAA,WAAA,EAAA,WAAA,QACA,EAAA,aAAA,EAAA,aAAA,QACA,EAAA,gBAAA,EAAA,gBACA,EAAA,YAAA,EAAA,YACA,EAAA,cAAA,EAAA,cACA,EAAA,mBAAA,EAAA,mBACA,EAAA,SAAA,EAAA,SACA,EAYA,QAAA,GAAA,EAAA,GACA,MAAA,GAAA,GAAA,GAAA,EAAA,GAQA,QAAA,GAAA,GACA,MAAA,GACA,GACA,EAAA,EAAA,GACA,EAAA,SAAA,EACA,GAGA,QAAA,KACA,EAAA,EAAA,OAQA,QAAA,GAAA,GACA,MAAA,KAAA,GAAA,IAAA,EAWA,QAAA,GAAA,EAAA,GACA,MAAA,KAAA,EACA,EAIA,GAAA,EAAA,GACA,EAEA,KAUA,QAAA,GAAA,EAAA,EAAA,GACA,KAAA,SAAA,EACA,KAAA,OAAA,EACA,KAAA,QAAA,EACA,KAAA,0BA1TA,GAAA,GAAA,GAAA,SAGA,EAAA,OAAA,cAGA,KAAA,EAAA,CACA,GAAA,MACA,EAAA,OAAA,KAAA,SACA,QAAA,iBAAA,UAAA,SAAA,GACA,GAAA,EAAA,OAAA,EAAA,CACA,GAAA,GAAA,CACA,MACA,EAAA,QAAA,SAAA,GACA,SAIA,EAAA,SAAA,GACA,EAAA,KAAA,GACA,OAAA,YAAA,EAAA,MAKA,GAAA,IAAA,EAGA,KAiGA,EAAA,CAcA,GAAA,WACA,QAAA,SAAA,EAAA,GAIA,GAHA,EAAA,EAAA,IAGA,EAAA,YAAA,EAAA,aAAA,EAAA,eAGA,EAAA,oBAAA,EAAA,YAGA,EAAA,iBAAA,EAAA,gBAAA,SACA,EAAA,YAGA,EAAA,wBAAA,EAAA,cAEA,KAAA,IAAA,YAGA,IAAA,GAAA,EAAA,IAAA,EACA,IACA,EAAA,IAAA,EAAA,KAOA,KAAA,GADA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,GAAA,EAAA,GAAA,WAAA,KAAA,CACA,EAAA,EAAA,GACA,EAAA,kBACA,EAAA,QAAA,CACA,OASA,IACA,EAAA,GAAA,GAAA,KAAA,EAAA,GACA,EAAA,KAAA,GACA,KAAA,OAAA,KAAA,IAGA,EAAA,gBAGA,WAAA,WACA,KAAA,OAAA,QAAA,SAAA,GAEA,IAAA,GADA,GAAA,EAAA,IAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IAAA,EAAA,WAAA,KAAA,CACA,EAAA,kBACA,EAAA,OAAA,EAAA,EAGA,UAGA,MACA,KAAA,aAGA,YAAA,WACA,GAAA,GAAA,KAAA,QAEA,OADA,MAAA,YACA,GAkCA,IAAA,GAAA,CAwEA,GAAA,WACA,QAAA,SAAA,GACA,GAAA,GAAA,KAAA,SAAA,SACA,EAAA,EAAA,MAMA,IAAA,EAAA,OAAA,EAAA,CACA,GAAA,GAAA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,EACA,IAAA,EAEA,YADA,EAAA,EAAA,GAAA,OAIA,GAAA,KAAA,SAGA,GAAA,GAAA,GAGA,aAAA,WACA,KAAA,cAAA,KAAA,SAGA,cAAA,SAAA,GACA,GAAA,GAAA,KAAA,OACA,GAAA,YACA,EAAA,iBAAA,kBAAA,MAAA,GAEA,EAAA,eACA,EAAA,iBAAA,2BAAA,MAAA,GAEA,EAAA,WACA,EAAA,iBAAA,kBAAA,MAAA,IAEA,EAAA,WAAA,EAAA,UACA,EAAA,iBAAA,iBAAA,MAAA,IAGA,gBAAA,WACA,KAAA,iBAAA,KAAA,SAGA,iBAAA,SAAA,GACA,GAAA,GAAA,KAAA,OACA,GAAA,YACA,EAAA,oBAAA,kBAAA,MAAA,GAEA,EAAA,eACA,EAAA,oBAAA,2BAAA,MAAA,GAEA,EAAA,WACA,EAAA,oBAAA,kBAAA,MAAA,IAEA,EAAA,WAAA,EAAA,UACA,EAAA,oBAAA,iBAAA,MAAA,IAQA,qBAAA,SAAA,GAGA,GAAA,IAAA,KAAA,OAAA,CAGA,KAAA,cAAA,GACA,KAAA,uBAAA,KAAA,EACA,IAAA,GAAA,EAAA,IAAA,EACA,IACA,EAAA,IAAA,EAAA,MAIA,EAAA,KAAA,QAGA,yBAAA,WACA,GAAA,GAAA,KAAA,sBACA,MAAA,0BAEA,EAAA,QAAA,SAAA,GAEA,KAAA,iBAAA,EAGA,KAAA,GADA,GAAA,EAAA,IAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,GAAA,EAAA,KAAA,KAAA,CACA,EAAA,OAAA,EAAA,EAGA,SAGA,OAGA,YAAA,SAAA,GAMA,OAFA,EAAA,2BAEA,EAAA,MACA,IAAA,kBAGA,GAAA,GAAA,EAAA,SACA,EAAA,EAAA,YAAA,aACA,EAAA,EAAA,OAGA,EAAA,GAAA,GAAA,aAAA,EACA,GAAA,cAAA,EACA,EAAA,mBAAA,CAGA,IAAA,GACA,EAAA,aAAA,cAAA,SAAA,KAAA,EAAA,SAEA,GAAA,EAAA,SAAA,GAEA,OAAA,EAAA,YAIA,EAAA,iBAAA,EAAA,gBAAA,QACA,KAAA,EAAA,gBAAA,QAAA,IACA,KAAA,EAAA,gBAAA,QAAA,GANA,OAUA,EAAA,kBACA,EAAA,GAGA,GAGA,MAEA,KAAA,2BAEA,GAAA,GAAA,EAAA,OAGA,EAAA,EAAA,gBAAA,GAGA,EAAA,EAAA,SAGA,GAAA,EAAA,SAAA,GAEA,MAAA,GAAA,cAIA,EAAA,sBACA,EAAA,GAGA,EARA,QAWA,MAEA,KAAA,iBACA,KAAA,qBAAA,EAAA,OAEA,KAAA,kBAEA,GAEA,GAAA,EAFA,EAAA,EAAA,YACA,EAAA,EAAA,MAEA,qBAAA,EAAA,MACA,GAAA,GACA,OAGA,KACA,GAAA,GAEA,IAAA,GAAA,EAAA,gBACA,EAAA,EAAA,YAGA,EAAA,EAAA,YAAA,EACA,GAAA,WAAA,EACA,EAAA,aAAA,EACA,EAAA,gBAAA,EACA,EAAA,YAAA,EAEA,EAAA,EAAA,SAAA,GAEA,MAAA,GAAA,UAIA,EAJA,SASA,MAIA,EAAA,mBAAA,EAEA,EAAA,mBACA,EAAA,iBAAA,IAGA,MC5hBA,OAAA,YAAA,OAAA,cAAA,UCCA,SAAA,GAGA,GACA,IADA,EAAA,KACA,EAAA,KACA,EAAA,EAAA,MAMA,EAAA,SAAA,EAAA,GACA,KAAA,SACA,KAAA,OAAA,EACA,KAAA,WAAA,EACA,KAAA,SAAA,EACA,KAAA,WAGA,GAAA,WACA,SAAA,SAAA,GAEA,KAAA,UAAA,EAAA,MAEA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,KAAA,QAAA,EAGA,MAAA,aAEA,QAAA,SAAA,GAEA,KAAA,WAEA,KAAA,QAAA,GAEA,KAAA,aAEA,QAAA,SAAA,GACA,GAAA,GAAA,EAAA,KAAA,EAAA,IAIA,GAAA,UAAA,EAEA,KAAA,OAAA,EAAA,IAEA,KAAA,MAAA,EAAA,IAGA,OAAA,SAAA,EAAA,GACA,GAAA,KAAA,QAAA,GAIA,MAFA,MAAA,QAAA,GAAA,KAAA,IAEA,CAGA,OAAA,MAAA,MAAA,IACA,KAAA,OAAA,EAAA,EAAA,KAAA,MAAA,IAEA,KAAA,QAEA,IAGA,KAAA,QAAA,IAAA,IAEA,IAEA,MAAA,SAAA,EAAA,GACA,EAAA,MAAA,QAAA,IAAA,QAAA,EAAA,EACA,IAAA,GAAA,SAAA,EAAA,GACA,KAAA,QAAA,EAAA,EAAA,EAAA,IACA,KAAA,KACA,GAAA,KAAA,EAAA,IAeA,QAAA,SAAA,EAAA,EAAA,EAAA,GACA,KAAA,MAAA,GAAA,CAEA,KAAA,GAAA,GADA,EAAA,KAAA,QAAA,GACA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IAEA,KAAA,OAAA,EAAA,EAAA,GAEA,KAAA,MAEA,MAAA,QAAA,GAAA,MAEA,KAAA,aACA,KAAA,SACA,KAAA,aAEA,UAAA,WACA,KAAA,UACA,KAAA,eAKA,EAAA,IACA,OAAA,EACA,GAAA,SAAA,GACA,MAAA,GAAA,QAAA,KAAA,EAAA,OAAA,KACA,MAAA,EAAA,QACA,IAAA,EAAA,QAEA,KAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,GAAA,eAYA,QAXA,EAAA,MAAA,OAAA,EAAA,MAAA,QACA,GAAA,IAAA,KAAA,UAEA,EAAA,KAAA,MAAA,EAAA,EAAA,OACA,EAAA,iBAAA,mBAAA,WACA,IAAA,EAAA,YACA,EAAA,KAAA,GAAA,EAAA,GAAA,IAAA,EACA,EAAA,UAAA,EAAA,aAAA,KAGA,EAAA,OACA,GAEA,aAAA,SAAA,EAAA,EAAA,GACA,KAAA,KAAA,EAAA,EAAA,GAAA,aAAA,aAKA,EAAA,IAAA,EACA,EAAA,OAAA,GAEA,OAAA,aC/IA,SAAA,GA4MA,QAAA,GAAA,GACA,MAAA,SAAA,EAAA,WAAA,EAAA,MAAA,EAGA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,EAAA,EACA,KACA,EAAA,KAAA,GACA,MAAA,GACA,EAAA,KAAA,SAAA,mBAAA,KACA,QAAA,KAAA,iGACA,GAEA,MAAA,+BAAA,EAGA,QAAA,GAAA,GACA,MAAA,GAAA,YAAA,EAAA,GAIA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,SACA,KAAA,EAAA,CACA,EAAA,EAAA,cAAA,OAEA,IAAA,GAAA,IAAA,KAAA,MAAA,KAAA,KAAA,SAAA,IAAA,IAGA,EAAA,EAAA,YAAA,MAAA,wBACA,GAAA,GAAA,EAAA,IAAA,EAEA,GAAA,IAAA,EAAA,MAEA,MAAA,mBAAA,EAAA,KAOA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,cAAA,cAAA,QAGA,OAFA,GAAA,YAAA,EAAA,YACA,EAAA,mBAAA,GACA,EAvPA,GAAA,GAAA,SACA,EAAA,EAAA,MACA,EAAA,UAAA,KAAA,UAAA,WAEA,EAAA,OAAA,kBACA,OAAA,kBAAA,aAAA,UAAA,SAUA,GAEA,kBAAA,YAAA,EAAA,IAEA,kBACA,YAAA,EAAA,IACA,uBACA,QACA,qBACA,kCACA,KAAA,KACA,KACA,KAAA,YACA,OAAA,cACA,MAAA,cAGA,UAAA,WACA,GAAA,GAAA,KAAA,aACA,IACA,KAAA,MAAA,IAGA,MAAA,SAAA,GACA,GAAA,KAAA,SAAA,GAEA,YADA,EAAA,OAAA,QAAA,IAAA,yBAAA,EAAA,WAGA,IAAA,GAAA,KAAA,KAAA,IAAA,EAAA,WACA,KACA,KAAA,YAAA,GACA,EAAA,KAAA,KAAA,KAMA,YAAA,SAAA,GACA,EAAA,OAAA,QAAA,IAAA,UAAA,GACA,KAAA,eAAA,GAEA,oBAAA,SAAA,GACA,EAAA,gBAAA,EACA,EAAA,kBACA,EAAA,gBAAA,gBAAA,GAEA,KAAA,eAAA,KACA,EAAA,OAAA,QAAA,IAAA,YAAA,GACA,KAAA,aAEA,YAAA,SAAA,GAgBA,GAfA,EAAA,OAAA,gBAAA,EAIA,YAAA,sBACA,YAAA,qBAAA,GAIA,EAAA,cADA,EAAA,WACA,GAAA,aAAA,QAAA,SAAA,IAEA,GAAA,aAAA,SAAA,SAAA,KAIA,EAAA,UAEA,IADA,GAAA,GACA,EAAA,UAAA,QACA,EAAA,EAAA,UAAA,QACA,GACA,GAAA,OAAA,GAIA,MAAA,oBAAA,IAEA,UAAA,SAAA,GACA,EAAA,GACA,KAAA,YAAA,IAGA,EAAA,KAAA,EAAA,KACA,KAAA,aAAA,KAGA,WAAA,SAAA,GAEA,GAAA,GAAA,CACA,GAAA,EAAA,GACA,EAAA,gBAAA,EACA,KAAA,aAAA,IAEA,aAAA,SAAA,GACA,KAAA,aAAA,GACA,SAAA,KAAA,YAAA,IAGA,aAAA,SAAA,EAAA,GACA,GAAA,GAAA,KACA,EAAA,SAAA,GACA,GACA,EAAA,GAEA,EAAA,oBAAA,GAOA,IALA,EAAA,iBAAA,OAAA,GACA,EAAA,iBAAA,QAAA,GAIA,GAAA,UAAA,EAAA,UAAA,CACA,GAAA,IAAA,CAEA,IAAA,IAAA,EAAA,YAAA,QAAA,WACA,GAAA,MAEA,IAAA,EAAA,MAAA,CACA,GAAA,CAIA,KAAA,GAAA,GAHA,EAAA,EAAA,MAAA,SACA,EAAA,EAAA,EAAA,OAAA,EAEA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,EAAA,OAAA,QAAA,cAEA,EAAA,GAAA,QAAA,EAAA,aAKA,GACA,EAAA,cAAA,GAAA,aAAA,QAAA,SAAA,OAUA,YAAA,SAAA,GACA,GAAA,GAAA,SAAA,cAAA,SACA,GAAA,gBAAA,EACA,EAAA,IAAA,EAAA,IAAA,EAAA,IACA,EAAA,GACA,EAAA,cAAA,EACA,KAAA,aAAA,EAAA,WACA,EAAA,WAAA,YAAA,GACA,EAAA,cAAA,OAEA,SAAA,KAAA,YAAA,IAGA,YAAA,WACA,OAAA,KAAA,gBAAA,KAAA,iBAAA,IAEA,iBAAA,SAAA,EAAA,GAEA,IAAA,GAAA,GADA,EAAA,EAAA,iBAAA,KAAA,sBAAA,IACA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,IAAA,KAAA,SAAA,GACA,MAAA,MAAA,YAAA,GACA,EAAA,GAAA,KAAA,iBAAA,EAAA,OAAA,GAAA,EAEA,MAKA,OAAA,IAGA,sBAAA,SAAA,GACA,GAAA,GAAA,EAAA,eAAA,CACA,OAAA,KAAA,EAAA,KAAA,kBAAA,KAAA,kBAEA,SAAA,SAAA,GACA,MAAA,GAAA,gBAEA,YAAA,SAAA,GACA,MAAA,GAAA,KAAA,EAAA,QACA,GAEA,IAsDA,EAAA,sBACA,EAAA,qCAEA,GACA,mBAAA,SAAA,GACA,GAAA,GAAA,EAAA,cACA,EAAA,EAAA,cAAA,IAEA,OADA,GAAA,YAAA,KAAA,qBAAA,EAAA,YAAA,GACA,GAEA,qBAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,YAAA,EAAA,EAAA,EAEA,OADA,GAAA,KAAA,YAAA,EAAA,EAAA,IAGA,YAAA,SAAA,EAAA,EAAA,GACA,MAAA,GAAA,QAAA,EAAA,SAAA,EAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,QAAA,QAAA,GAGA,OAFA,GAAA,KAAA,EACA,EAAA,EAAA,KACA,EAAA,IAAA,EAAA,IAAA,KAMA,GAAA,OAAA,EACA,EAAA,KAAA,EACA,EAAA,KAAA,GAEA,aC5RA,SAAA,GA0FA,QAAA,GAAA,GACA,MAAA,GAAA,EAAA,GAGA,QAAA,GAAA,EAAA,GACA,MAAA,SAAA,EAAA,WAAA,EAAA,aAAA,SAAA,EAOA,QAAA,GAAA,EAAA,GAEA,GAAA,GAAA,CACA,aAAA,YACA,EAAA,SAAA,eAAA,mBAAA,IAGA,EAAA,KAAA,CAEA,IAAA,GAAA,EAAA,cAAA,OACA,GAAA,aAAA,OAAA,GAEA,EAAA,UACA,EAAA,QAAA,EAGA,IAAA,GAAA,EAAA,cAAA,OAmBA,OAlBA,GAAA,aAAA,UAAA,SAEA,EAAA,KAAA,YAAA,GACA,EAAA,KAAA,YAAA,GAMA,YAAA,YAEA,EAAA,KAAA,UAAA,GAIA,OAAA,qBAAA,oBAAA,WACA,oBAAA,UAAA,GAEA,EAsCA,QAAA,GAAA,EAAA,GACA,EAAA,GAAA,EAEA,EAAA,WACA,EAAA,EAAA,IACA,GAMA,QAAA,GAAA,GACA,MAAA,aAAA,EAAA,YACA,EAAA,aAAA,EAIA,QAAA,GAAA,EAAA,GACA,GAAA,EAAA,GASA,GACA,QAVA,CACA,GAAA,GAAA,YACA,aAAA,EAAA,YACA,EAAA,aAAA,KACA,EAAA,oBAAA,EAAA,GACA,EAAA,EAAA,IAGA,GAAA,iBAAA,EAAA,IAOA,QAAA,GAAA,EAAA,GAGA,QAAA,KACA,GAAA,GAEA,sBAAA,GAGA,QAAA,KACA,IACA,IAVA,GAAA,GAAA,EAAA,iBAAA,oBACA,EAAA,EAAA,EAAA,EAAA,MAWA,IAAA,EACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,EAAA,GACA,EAAA,KAAA,IAEA,EAAA,iBAAA,OAAA,GACA,EAAA,iBAAA,QAAA,QAIA,KAIA,QAAA,GAAA,GACA,MAAA,GAAA,EAAA,QAAA,YAAA,EAAA,OAAA,WACA,EAAA,eA3OA,GAAA,GAAA,UAAA,UAAA,cAAA,QACA,EAAA,EACA,EAAA,EAAA,MACA,EAAA,SAGA,EAAA,OAAA,kBACA,kBAAA,aAAA,UAAA,QAEA,IAAA,EAkIA,GAAA,UA/HA,IACA,IADA,EAAA,IACA,EAAA,QACA,EAAA,EAAA,OAQA,GACA,aAEA,yBAAA,YAAA,EAAA,IAEA,yBACA,YAAA,EAAA,KACA,KAAA,KACA,SAAA,SAAA,GACA,EAAA,QAAA,IAGA,YAAA,SAAA,GACA,GAAA,GAAA,KAAA,aAAA,EAEA,GAAA,SAAA,IAEA,aAAA,SAAA,GAEA,MAAA,GAAA,iBAAA,KAAA,qBAAA,KAGA,qBAAA,SAAA,GACA,GAAA,GAAA,EAAA,eAAA,CACA,OAAA,KAAA,EAAA,KAAA,yBACA,KAAA,yBAEA,OAAA,SAAA,EAAA,EAAA,GAMA,GALA,EAAA,MAAA,QAAA,IAAA,SAAA,EAAA,GAIA,EAAA,WAAA,EACA,EAAA,GAAA,CACA,GAAA,GAAA,KAAA,UAAA,EAEA,KAEA,EAAA,EAAA,EAAA,GACA,EAAA,aAAA,EAGA,KAAA,aAAA,GAEA,KAAA,UAAA,GAAA,GAIA,EAAA,OAAA,EAEA,EAAA,aAEA,aAAA,SAAA,GACA,KAAA,YAAA,GACA,KAAA,QAAA,GACA,EAAA,aAEA,UAAA,WACA,EAAA,cAKA,EAAA,GAAA,GAAA,EAAA,OAAA,KAAA,GACA,EAAA,UAAA,KAAA,GA4DA,IAAA,IACA,IAAA,WACA,MAAA,aAAA,eAAA,SAAA,eAEA,cAAA,EAOA,IAJA,OAAA,eAAA,SAAA,iBAAA,GACA,OAAA,eAAA,EAAA,iBAAA,IAGA,SAAA,QAAA,CACA,GAAA,IACA,IAAA,WACA,MAAA,QAAA,SAAA,MAEA,cAAA,EAGA,QAAA,eAAA,SAAA,UAAA,GACA,OAAA,eAAA,EAAA,UAAA,GAgBA,GAAA,GAAA,YAAA,KAAA,WAAA,cACA,EAAA,kBAwDA,GAAA,UAAA,EACA,EAAA,UAAA,EACA,EAAA,SAAA,EACA,EAAA,iBAAA,EACA,EAAA,iBAAA,EACA,EAAA,eAAA,EACA,EAAA,aAAA,GAEA,OAAA,aCzPA,SAAA,GAOA,QAAA,GAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,cAAA,EAAA,MAAA,EAAA,WAAA,QACA,EAAA,EAAA,YAMA,QAAA,GAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,EAAA,IACA,EAAA,SAAA,GAEA,EAAA,UAAA,EAAA,SAAA,QACA,EAAA,EAAA,UAKA,QAAA,GAAA,GACA,MAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EACA,EAAA,qBAAA,IAaA,QAAA,GAAA,GACA,EAAA,QAAA,GAAA,WAAA,EAAA,SAAA,IAzCA,GAEA,IAFA,EAAA,iBAEA,EAAA,UA6BA,EAAA,YAAA,UAAA,SACA,YAAA,UAAA,iBACA,YAAA,UAAA,uBACA,YAAA,UAAA,oBACA,YAAA,UAAA,kBAEA,EAAA,GAAA,kBAAA,EASA,GAAA,QAAA,EACA,EAAA,QAAA,GAEA,aCpDA,WAmCA,QAAA,KACA,YAAA,SAAA,aAAA,GA/BA,kBAAA,QAAA,cACA,OAAA,YAAA,SAAA,EAAA,GACA,GAAA,GAAA,SAAA,YAAA,aAKA,OAJA,GAAA,UAAA,EACA,EAAA,WAAA,GAAA,GAAA,EACA,EAAA,cAAA,GAAA,GAAA,EACA,EAAA,QACA,GAKA,IAAA,GAAA,OAAA,kBACA,OAAA,kBAAA,aAAA,UAAA,QAMA,aAAA,iBAAA,WACA,YAAA,OAAA,EACA,YAAA,WAAA,GAAA,OAAA,UACA,EAAA,cACA,GAAA,aAAA,qBAAA,SAAA,OAMA,YAAA,YAQA,aAAA,SAAA,YACA,gBAAA,SAAA,aAAA,OAAA,YACA,IAEA,SAAA,iBAAA,mBAAA,OC9CA,OAAA,eAAA,OAAA,iBAAA,UCCA,SAAA,GAQA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,iBACA,KAAA,EAEA,IADA,EAAA,EAAA,WACA,GAAA,EAAA,WAAA,KAAA,cACA,EAAA,EAAA,WAGA,MAAA,GACA,EAAA,EAAA,MAAA,GACA,EAAA,EAAA,EAAA,GAEA,EAAA,EAAA,kBAEA,OAAA,MAIA,QAAA,GAAA,EAAA,GAEA,IADA,GAAA,GAAA,EAAA,WACA,GACA,EAAA,EAAA,GACA,EAAA,EAAA,gBAMA,QAAA,GAAA,EAAA,GAEA,EAAA,EAAA,SAAA,GACA,MAAA,GAAA,IACA,MAEA,GAAA,EAAA,KAEA,EAAA,EAAA,GAKA,QAAA,GAAA,GACA,MAAA,GAAA,IACA,EAAA,IACA,OAEA,GAAA,GAIA,QAAA,GAAA,GACA,EAAA,EAAA,SAAA,GACA,MAAA,GAAA,IACA,EADA,SAOA,QAAA,GAAA,GACA,MAAA,GAAA,IAAA,EAAA,GAIA,QAAA,GAAA,GACA,IAAA,EAAA,cAAA,EAAA,WAAA,KAAA,aAAA,CACA,GAAA,GAAA,EAAA,aAAA,OAAA,EAAA,UACA,EAAA,EAAA,SAAA,EACA,IAAA,EAIA,MAHA,GAAA,KAAA,QAAA,MAAA,WAAA,EAAA,WACA,EAAA,QAAA,GACA,EAAA,KAAA,QAAA,YACA,GAKA,QAAA,GAAA,GACA,EAAA,GACA,EAAA,IACA,EAAA,EAAA,SAAA,GACA,EAAA,KAiBA,QAAA,GAAA,GAEA,GADA,EAAA,KAAA,IACA,EAAA,CACA,GAAA,CACA,IAAA,GAAA,OAAA,UAAA,OAAA,SAAA,gBACA,UACA,GAAA,IAIA,QAAA,KACA,GAAA,CAEA,KAAA,GAAA,GADA,EAAA,EACA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,GAEA,MAGA,QAAA,GAAA,GACA,EACA,EAAA,WACA,EAAA,KAGA,EAAA,GAKA,QAAA,GAAA,IAWA,EAAA,kBAAA,EAAA,kBAAA,EAAA,cAAA,EAAA,OACA,EAAA,KAAA,QAAA,MAAA,YAAA,EAAA,WACA,EAAA,KACA,EAAA,YAAA,EAAA,YAAA,GAAA,EAEA,EAAA,WAAA,IACA,EAAA,WAAA,GAGA,EAAA,WAAA,EACA,EAAA,KAAA,QAAA,KAAA,YAAA,EAAA,UACA,uBAAA,EAAA,YACA,EAAA,mBACA,EAAA,KAAA,QAAA,IAAA,YAAA,EAAA,WACA,EAAA,qBAGA,EAAA,KAAA,QAAA,YAIA,QAAA,GAAA,GACA,EAAA,GACA,EAAA,EAAA,SAAA,GACA,EAAA,KAIA,QAAA,GAAA,GACA,EACA,EAAA,WACA,EAAA,KAGA,EAAA,GAIA,QAAA,GAAA,IAGA,EAAA,kBAAA,EAAA,kBAAA,EAAA,cAAA,EAAA,OACA,EAAA,KAAA,QAAA,MAAA,WAAA,EAAA,WACA,EAAA,KACA,EAAA,YAAA,EAAA,YAAA,GAAA,EAEA,EAAA,WAAA,IACA,EAAA,WAAA,GAGA,EAAA,WAAA,EACA,EAAA,KAAA,QAAA,KAAA,WAAA,EAAA,UACA,uBAAA,EAAA,YACA,EAAA,kBACA,EAAA,oBAGA,EAAA,KAAA,QAAA,YAMA,QAAA,GAAA,GACA,MAAA,QAAA,kBAAA,kBAAA,aAAA,GACA,EAGA,QAAA,GAAA,GAGA,IAFA,GAAA,GAAA,EACA,EAAA,EAAA,UACA,GAAA,CACA,GAAA,GAAA,EACA,OAAA,CAEA,GAAA,EAAA,YAAA,EAAA,MAIA,QAAA,GAAA,GACA,GAAA,EAAA,aAAA,EAAA,WAAA,UAAA,CACA,EAAA,KAAA,QAAA,IAAA,6BAAA,EAAA,UAGA,KADA,GAAA,GAAA,EAAA,WACA,GACA,EAAA,GACA,EAAA,EAAA,iBAKA,QAAA,GAAA,GACA,EAAA,YACA,EAAA,GACA,EAAA,WAAA,GAIA,QAAA,GAAA,GAEA,GAAA,EAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IAAA,GAAA,cAAA,EAAA,MAAA,EAAA,YACA,EAAA,WAAA,CAEA,IADA,GAAA,GAAA,EAAA,WAAA,GACA,GAAA,IAAA,WAAA,EAAA,MACA,EAAA,EAAA,UAEA,IAAA,GAAA,IAAA,EAAA,KAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,YAAA,EACA,GAAA,EAAA,MAAA,MAAA,QAAA,MAAA,KAAA,MAGA,QAAA,MAAA,sBAAA,EAAA,OAAA,GAAA,IAGA,EAAA,QAAA,SAAA,GAEA,cAAA,EAAA,OACA,EAAA,EAAA,WAAA,SAAA,GAEA,EAAA,WAIA,EAAA,KAGA,EAAA,EAAA,aAAA,SAAA,GAEA,EAAA,WAGA,EAAA,QAKA,EAAA,KAAA,QAAA,WAKA,QAAA,KAEA,EAAA,EAAA,eACA,IAKA,QAAA,GAAA,GACA,EAAA,QAAA,GAAA,WAAA,EAAA,SAAA,IAGA,QAAA,GAAA,GACA,EAAA,GAGA,QAAA,GAAA,GACA,EAAA,KAAA,QAAA,MAAA,oBAAA,EAAA,QAAA,MAAA,KAAA,OACA,EAAA,GACA,EAAA,KAAA,QAAA,WAGA,QAAA,GAAA,GACA,EAAA,EAAA,EAIA,KAAA,GAAA,GADA,EAAA,EAAA,iBAAA,YAAA,EAAA,KACA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,EAAA,QAAA,EAAA,OAAA,UACA,EAAA,EAAA,OAGA,GAAA,GA/TA,GAAA,GAAA,OAAA,aACA,EAAA,OAAA,YAAA,YAAA,iBAAA,OAiGA,GAAA,OAAA,kBACA,OAAA,mBAAA,OAAA,kBACA,GAAA,qBAAA,CAEA,IAAA,IAAA,EACA,KAsLA,EAAA,GAAA,kBAAA,GAQA,EAAA,MAAA,UAAA,QAAA,KAAA,KAAA,MAAA,UAAA,QA8BA,GAAA,iBAAA,EACA,EAAA,YAAA,EACA,EAAA,oBAAA,EACA,EAAA,WAAA,EACA,EAAA,eAAA,EACA,EAAA,aAAA,EAEA,EAAA,gBAAA,EACA,EAAA,gBAAA,EAEA,EAAA,YAAA,GAEA,OAAA,gBCvUA,SAAA,GA6EA,QAAA,GAAA,EAAA,GAIA,GAAA,GAAA,KACA,KAAA,EAGA,KAAA,IAAA,OAAA,oEAEA,IAAA,EAAA,QAAA,KAAA,EAGA,KAAA,IAAA,OAAA,uGAAA,OAAA,GAAA,KAGA,IAAA,EAAA,GACA,KAAA,IAAA,OAAA,+CAAA,OAAA,GAAA,0BAIA,KAAA,EAAA,UAGA,KAAA,IAAA,OAAA,8CA+BA,OA5BA,GAAA,OAAA,EAAA,cAEA,EAAA,UAAA,EAAA,cAIA,EAAA,SAAA,EAAA,EAAA,SAGA,EAAA,GAGA,EAAA,GAEA,EAAA,EAAA,WAEA,EAAA,EAAA,OAAA,GAGA,EAAA,KAAA,EAAA,GACA,EAAA,KAAA,UAAA,EAAA,UAEA,EAAA,UAAA,YAAA,EAAA,KAEA,EAAA,OAEA,EAAA,oBAAA,UAEA,EAAA,KAGA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,EACA,OAAA,GACA,EAAA,EAAA,SAAA,QAAA,OAKA,QAAA,GAAA,GAMA,IAAA,GAAA,GAHA,EAAA,EAAA,QAGA,EAAA,EAAA,EAAA,EAAA,SAAA,GAAA,IACA,EAAA,EAAA,IAAA,EAAA,GAGA,GAAA,IAAA,GAAA,EAAA,OACA,IAEA,EAAA,GAAA,EAAA,QAIA,QAAA,GAAA,GAGA,IAAA,OAAA,UAAA,CAEA,GAAA,GAAA,YAAA,SAEA,IAAA,EAAA,GAAA,CACA,GAAA,GAAA,SAAA,cAAA,EAAA,IACA,GAAA,OAAA,eAAA,GAQA,IADA,GAAA,GAAA,EAAA,EAAA,UACA,GAAA,IAAA,GAAA,CACA,GAAA,GAAA,OAAA,eAAA,EACA,GAAA,UAAA,EACA,EAAA,GAIA,EAAA,OAAA,EAKA,QAAA,GAAA,GAOA,MAAA,GAAA,EAAA,EAAA,KAAA,GAGA,QAAA,GAAA,EAAA,GAkBA,MAhBA,GAAA,IACA,EAAA,aAAA,KAAA,EAAA,IAGA,EAAA,gBAAA,cAEA,EAAA,EAAA,GAEA,EAAA,cAAA,EAEA,EAAA,GAEA,EAAA,aAAA,GAEA,EAAA,eAAA,GAEA,EAGA,QAAA,GAAA,EAAA,GAEA,OAAA,UACA,EAAA,UAAA,EAAA,WAKA,EAAA,EAAA,EAAA,UAAA,EAAA,QACA,EAAA,UAAA,EAAA,WAIA,QAAA,GAAA,EAAA,EAAA,GASA,IALA,GAAA,MAEA,EAAA,EAGA,IAAA,GAAA,IAAA,YAAA,WAAA,CAEA,IAAA,GAAA,GADA,EAAA,OAAA,oBAAA,GACA,EAAA,EAAA,EAAA,EAAA,GAAA,IACA,EAAA,KACA,OAAA,eAAA,EAAA,EACA,OAAA,yBAAA,EAAA,IACA,EAAA,GAAA,EAGA,GAAA,OAAA,eAAA,IAIA,QAAA,GAAA,GAEA,EAAA,iBACA,EAAA,kBAMA,QAAA,GAAA,GAIA,IAAA,EAAA,aAAA,YAAA,CAGA,GAAA,GAAA,EAAA,YACA,GAAA,aAAA,SAAA,EAAA,GACA,EAAA,KAAA,KAAA,EAAA,EAAA,GAEA,IAAA,GAAA,EAAA,eACA,GAAA,gBAAA,SAAA,GACA,EAAA,KAAA,KAAA,EAAA,KAAA,IAEA,EAAA,aAAA,aAAA,GAKA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,MAAA,KAAA,UACA,IAAA,GAAA,KAAA,aAAA,EACA,MAAA,0BACA,IAAA,GACA,KAAA,yBAAA,EAAA,EAAA,GAQA,QAAA,GAAA,GACA,MAAA,GACA,EAAA,EAAA,eADA,OAKA,QAAA,GAAA,EAAA,GACA,EAAA,GAAA,EAGA,QAAA,GAAA,GACA,MAAA,YACA,MAAA,GAAA,IAKA,QAAA,GAAA,EAAA,EAAA,GAGA,MAAA,KAAA,EACA,EAAA,EAAA,GAEA,EAAA,EAAA,GAIA,QAAA,GAAA,EAAA,GAGA,GAAA,GAAA,EAAA,GAAA,EACA,IAAA,EAAA,CACA,GAAA,GAAA,EAAA,KAAA,GAAA,EAAA,GACA,MAAA,IAAA,GAAA,IAGA,KAAA,IAAA,EAAA,GACA,MAAA,IAAA,GAAA,KAIA,GAAA,EAAA,CACA,GAAA,GAAA,EAAA,EAEA,OADA,GAAA,aAAA,KAAA,GACA,EAEA,GAAA,GAAA,EAAA,EAKA,OAHA,GAAA,QAAA,MAAA,GACA,EAAA,EAAA,aAEA,EAGA,QAAA,GAAA,GACA,IAAA,EAAA,cAAA,EAAA,WAAA,KAAA,aAAA,CACA,GAAA,GAAA,EAAA,aAAA,MACA,EAAA,EAAA,GAAA,EAAA,UACA,IAAA,EAAA,CACA,GAAA,GAAA,EAAA,KAAA,EAAA,UACA,MAAA,GAAA,EAAA,EACA,KAAA,IAAA,EAAA,QACA,MAAA,GAAA,EAAA,KAMA,QAAA,GAAA,GAEA,GAAA,GAAA,EAAA,KAAA,KAAA,EAIA,OAFA,GAAA,WAAA,GAEA,EAhXA,IACA,EAAA,OAAA,gBAAA,UAEA,IAAA,GAAA,EAAA,MAIA,EAAA,QAAA,SAAA,iBAMA,GAAA,EAAA,UAAA,IAAA,OAAA,iBAEA,IAAA,EAAA,CAGA,GAAA,GAAA,YAGA,GAAA,YACA,EAAA,eAAA,EAEA,EAAA,YAAA,EACA,EAAA,QAAA,EACA,EAAA,WAAA,EACA,EAAA,eAAA,EACA,EAAA,gBAAA,EACA,EAAA,gBAAA,EACA,EAAA,oBAAA,EACA,EAAA,YAAA,MAEA,CAmQA,GAAA,MAkBA,EAAA,+BA8DA,EAAA,SAAA,cAAA,KAAA,UACA,EAAA,SAAA,gBAAA,KAAA,UAIA,EAAA,KAAA,UAAA,SAIA,UAAA,gBAAA,EACA,SAAA,cAAA,EACA,SAAA,gBAAA,EACA,KAAA,UAAA,UAAA,EAEA,EAAA,SAAA,EAaA,EAAA,QAAA,EAKA,GAAA,EAgBA,GAfA,OAAA,WAAA,EAeA,SAAA,EAAA,GACA,MAAA,aAAA,IAfA,SAAA,EAAA,GAEA,IADA,GAAA,GAAA,EACA,GAAA,CAIA,GAAA,IAAA,EAAA,UACA,OAAA,CAEA,GAAA,EAAA,UAEA,OAAA,GASA,EAAA,WAAA,EAGA,SAAA,SAAA,SAAA,gBAEA,EAAA,UAAA,EACA,EAAA,UAAA,GAEA,OAAA,gBChcA,SAAA,GA6CA,QAAA,GAAA,GACA,MAAA,SAAA,EAAA,WACA,EAAA,aAAA,SAAA,EA3CA,GAAA,GAAA,EAAA,iBAIA,GACA,WACA,YAAA,EAAA,KAEA,KACA,KAAA,aAEA,MAAA,SAAA,GACA,IAAA,EAAA,SAAA,CAEA,EAAA,UAAA,CAEA,IAAA,GAAA,EAAA,iBAAA,EAAA,UAEA,GAAA,EAAA,SAAA,GACA,EAAA,EAAA,IAAA,EAAA,YAAA,KAIA,eAAA,gBAAA,GAEA,eAAA,gBAAA,KAGA,UAAA,SAAA,GAEA,EAAA,IACA,KAAA,YAAA,IAGA,YAAA,SAAA,GACA,EAAA,QACA,EAAA,MAAA,EAAA,UAUA,EAAA,MAAA,UAAA,QAAA,KAAA,KAAA,MAAA,UAAA,QAIA,GAAA,OAAA,EACA,EAAA,iBAAA,GAEA,OAAA,gBC1DA,SAAA,GAGA,QAAA,KAEA,eAAA,OAAA,MAAA,UAEA,eAAA,gBAAA,SAEA,IAAA,GAAA,OAAA,UAAA,SAAA,eACA,SAAA,eACA,UACA,GAAA,WAGA,eAAA,OAAA,EAEA,eAAA,UAAA,KAAA,MACA,OAAA,cACA,eAAA,QAAA,eAAA,UAAA,YAAA,WAGA,SAAA,cACA,GAAA,aAAA,sBAAA,SAAA,KAIA,OAAA,cACA,YAAA,qBAAA,SAAA,GACA,eAAA,OAAA,MAAA,EAAA,YAkBA,GAXA,kBAAA,QAAA,cACA,OAAA,YAAA,SAAA,GACA,GAAA,GAAA,SAAA,YAAA,aAEA,OADA,GAAA,UAAA,GAAA,GAAA,GACA,IAOA,aAAA,SAAA,YAAA,EAAA,MAAA,MACA,QAGA,IAAA,gBAAA,SAAA,YAAA,OAAA,aACA,OAAA,cAAA,OAAA,YAAA,MAIA,CACA,GAAA,GAAA,OAAA,cAAA,YAAA,MACA,oBAAA,kBACA,QAAA,iBAAA,EAAA,OANA,MASA,OAAA,gBC9DA,WAEA,GAAA,OAAA,kBAAA,CAGA,GAAA,IAAA,aAAA,iBAAA,kBACA,mBAGA,IACA,GAAA,QAAA,SAAA,GACA,EAAA,GAAA,eAAA,KAIA,EAAA,QAAA,SAAA,GACA,eAAA,GAAA,SAAA,GACA,MAAA,GAAA,GAAA,KAAA,WCjBA,SAAA,GAIA,QAAA,GAAA,GACA,KAAA,MAAA,EAJA,GAAA,GAAA,EAAA,cAMA,GAAA,WAGA,YAAA,SAAA,EAAA,GAGA,IAFA,GACA,GAAA,EADA,KAEA,EAAA,KAAA,MAAA,KAAA,IACA,EAAA,GAAA,KAAA,EAAA,GAAA,GACA,EAAA,MAAA,QAAA,EAAA,GAAA,IAAA,EAAA,MAEA,OAAA,IAIA,QAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,KAAA,YAAA,EAAA,EACA,MAAA,MAAA,KAAA,IAGA,MAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,MAGA,KAAA,EACA,MAAA,GAAA,EAwBA,KAAA,GADA,GAAA,EAAA,EApBA,EAAA,WACA,MAAA,GACA,EAAA,IAKA,EAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,MACA,EAAA,EAAA,GAEA,IAAA,EAEA,MADA,GAAA,GAAA,GACA,GAEA,IAAA,GAAA,EAAA,UAAA,EAAA,YACA,GAAA,GAAA,EACA,KAAA,MAAA,KAAA,YAAA,EAAA,GAAA,EAAA,IAIA,EAAA,EAAA,EAAA,EAAA,IACA,EAAA,EAAA,GACA,EAAA,EAAA,IAEA,EAAA,GAEA,EAAA,IAGA,EAAA,KAAA,IAAA,EAAA,EAAA,MACA,EAAA,MAAA,EAEA,EAAA,GAAA,IAGA,IAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,GAAA,eASA,OARA,GAAA,KAAA,MAAA,GAAA,GACA,EAAA,OACA,EAAA,OAAA,WACA,EAAA,KAAA,EAAA,KAAA,IAEA,EAAA,QAAA,WACA,EAAA,KAAA,EAAA,KAAA,IAEA,IAIA,EAAA,OAAA,GACA,OAAA,UCrFA,SAAA,GAKA,QAAA,KACA,KAAA,OAAA,GAAA,GAAA,KAAA,OAJA,GAAA,GAAA,EAAA,YACA,EAAA,EAAA,MAKA,GAAA,WACA,MAAA,+CAEA,QAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,SAAA,GACA,EAAA,KAAA,QAAA,EAAA,EAAA,KACA,KAAA,KACA,MAAA,OAAA,QAAA,EAAA,EAAA,IAGA,YAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,YACA,EAAA,EAAA,cAAA,QACA,EAAA,SAAA,GACA,EAAA,YAAA,EACA,EAAA,GAEA,MAAA,QAAA,EAAA,EAAA,IAGA,QAAA,SAAA,EAAA,EAAA,GAGA,IAAA,GADA,GAAA,EAAA,EADA,EAAA,KAAA,OAAA,YAAA,EAAA,GAEA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GACA,EAAA,EAAA,IAEA,EAAA,EAAA,eAAA,EAAA,GAAA,GAEA,EAAA,KAAA,QAAA,EAAA,EAAA,GACA,EAAA,EAAA,QAAA,EAAA,QAAA,EAEA,OAAA,IAEA,WAAA,SAAA,EAAA,GAGA,QAAA,KACA,IACA,IAAA,GAAA,GACA,IAGA,IAAA,GAAA,GARA,EAAA,EAAA,EAAA,EAAA,OAQA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,KAAA,YAAA,EAAA,IAKA,IAAA,GAAA,GAAA,EAGA,GAAA,cAAA,GAEA,OAAA,UC7DA,SAAA,GACA,EAAA,MACA,EAAA,SAAA,EAAA,YACA,IAAA,IACA,OAAA,SAAA,GACA,MAAA,GACA,EAAA,YAAA,EAAA,iBADA,QAIA,UAAA,SAAA,GACA,MAAA,IAAA,QAAA,EAAA,mBAEA,gBAAA,SAAA,GACA,GAAA,GAAA,KAAA,OAAA,EACA,OAAA,MAAA,UAAA,GACA,EADA,QAIA,YAAA,SAAA,GACA,GAAA,GAAA,EAAA,eACA,KAAA,EAAA,CACA,GAAA,GAAA,EAAA,cAAA,SACA,KACA,EAAA,EAAA,iBAGA,MAAA,IAEA,WAAA,SAAA,GAEA,IADA,GAAA,MAAA,EAAA,KAAA,OAAA,GACA,GACA,EAAA,KAAA,GACA,EAAA,KAAA,YAAA,EAEA,OAAA,IAEA,WAAA,SAAA,EAAA,EAAA,GACA,GAAA,EAAA,CACA,GACA,GAAA,EADA,EAAA,EAAA,iBAAA,EAAA,EAIA,KADA,EAAA,KAAA,gBAAA,GACA,GAAA,CAGA,GADA,EAAA,EAAA,iBAAA,EAAA,GAIA,CAEA,GAAA,GAAA,KAAA,gBAAA,EACA,OAAA,MAAA,WAAA,EAAA,EAAA,IAAA,EAJA,EAAA,KAAA,YAAA,GAQA,MAAA,KAGA,MAAA,SAAA,GAGA,IAFA,GAAA,GAAA,EAEA,EAAA,YACA,EAAA,EAAA,UAMA,OAHA,GAAA,UAAA,KAAA,eAAA,EAAA,UAAA,KAAA,yBACA,EAAA,UAEA,GAEA,WAAA,SAAA,GACA,GAAA,GAAA,EAAA,QAAA,EAAA,EAAA,QAEA,EAAA,KAAA,MAAA,EAAA,OAKA,OAHA,GAAA,iBAAA,EAAA,KACA,EAAA,UAEA,KAAA,WAAA,EAAA,EAAA,IAGA,GAAA,cAAA,EACA,EAAA,WAAA,EAAA,WAAA,KAAA,GAEA,OAAA,sBAAA,GACA,OAAA,uBCtFA,WACA,QAAA,GAAA,GACA,MAAA,WAAA,EAAA,GAEA,QAAA,GAAA,GACA,MAAA,kBAAA,EAAA,KAEA,QAAA,GAAA,GACA,MAAA,uBAAA,EAAA,mBAAA,EAAA,gCAEA,GAAA,IACA,OACA,OACA,QACA,SAEA,KAAA,cACA,WACA,cACA,iBAIA,EAAA,EACA,GAAA,QAAA,SAAA,GACA,OAAA,KAAA,GACA,GAAA,EAAA,GAAA,EAAA,GAAA,KACA,GAAA,EAAA,GAAA,EAAA,GAAA,OAEA,GAAA,EAAA,UAAA,IAAA,GAAA,EAAA,EAAA,MAAA,KACA,GAAA,EAAA,UAAA,IAAA,GAAA,EAAA,EAAA,MAAA,OAGA,IAAA,GAAA,SAAA,cAAA,QACA,GAAA,YAAA,EACA,SAAA,KAAA,YAAA,MCpBA,SAAA,GA8CA,QAAA,GAAA,EAAA,GACA,EAAA,KAsBA,IAAA,GAAA,EAAA,OAEA,KAAA,IAAA,GAAA,UAAA,EACA,OAAA,EAAA,OACA,IAAA,GAAA,EAAA,CAAA,MACA,KAAA,GAAA,EAAA,CAAA,MACA,KAAA,GAAA,EAAA,CAAA,MACA,SAAA,EAAA,EAIA,GAAA,EACA,IAAA,EACA,EAAA,GAAA,YAAA,EAAA,OACA,CACA,EAAA,SAAA,YAAA,aAIA,KAAA,GADA,GAAA,KACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GACA,EAAA,GAAA,EAAA,IAAA,EAAA,EAIA,GAAA,eACA,EAAA,EAAA,QAAA,EAAA,WAAA,EAAA,KAAA,EAAA,OACA,EAAA,QAAA,EAAA,QAAA,EAAA,QAAA,EAAA,QAAA,EAAA,QACA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,OAAA,EAAA,eAKA,EAAA,UAAA,EAAA,UAGA,GAGA,OAAA,eAAA,EAAA,WAAA,IAAA,WAAA,MAAA,IAAA,YAAA,GAKA,IAAA,GAAA,CAmBA,OAjBA,GADA,EAAA,SACA,EAAA,SAEA,EAAA,GAAA,EAIA,OAAA,iBAAA,GACA,WAAA,MAAA,EAAA,WAAA,EAAA,YAAA,GACA,OAAA,MAAA,EAAA,OAAA,EAAA,YAAA,GACA,QAAA,MAAA,EAAA,QAAA,EAAA,YAAA,GACA,UAAA,MAAA,EAAA,YAAA,GACA,OAAA,MAAA,EAAA,OAAA,EAAA,YAAA,GACA,OAAA,MAAA,EAAA,OAAA,EAAA,YAAA,GACA,aAAA,MAAA,EAAA,aAAA,GAAA,YAAA,GACA,aAAA,MAAA,EAAA,aAAA,EAAA,YAAA,GACA,WAAA,MAAA,EAAA,YAAA,EAAA,YAAA,KAEA,EAlIA,GAAA,IAAA,EACA,GAAA,CACA,KACA,GAAA,GAAA,GAAA,YAAA,SAAA,QAAA,GACA,IAAA,EACA,EAAA,IAAA,EAAA,QACA,EAAA,KACA,MAAA,IAGA,GAAA,IACA,UACA,aACA,OACA,SACA,UACA,UACA,UACA,UACA,UACA,SACA,WACA,UACA,SACA,iBAGA,IACA,GACA,EACA,KACA,KACA,EACA,EACA,EACA,GACA,GACA,GACA,GACA,EACA,EACA,KA6FA,GAAA,UAAA,OAAA,OAAA,WAAA,WAGA,EAAA,eACA,EAAA,aAAA,IAEA,QCzJA,SAAA,GAGA,QAAA,KACA,GAAA,EAAA,CACA,GAAA,GAAA,GAAA,IAEA,OADA,GAAA,SAAA,EACA,EAEA,KAAA,QACA,KAAA,UATA,GAAA,GAAA,OAAA,KAAA,OAAA,IAAA,UAAA,QACA,EAAA,WAAA,MAAA,MAAA,KAYA,GAAA,WACA,IAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,KAAA,QAAA,EACA;EAAA,GACA,KAAA,OAAA,GAAA,GAEA,KAAA,KAAA,KAAA,GACA,KAAA,OAAA,KAAA,KAGA,IAAA,SAAA,GACA,MAAA,MAAA,KAAA,QAAA,GAAA,IAEA,SAAA,SAAA,GACA,GAAA,GAAA,KAAA,KAAA,QAAA,EACA,GAAA,KACA,KAAA,KAAA,OAAA,EAAA,GACA,KAAA,OAAA,OAAA,EAAA,KAGA,IAAA,SAAA,GACA,GAAA,GAAA,KAAA,KAAA,QAAA,EACA,OAAA,MAAA,OAAA,IAEA,MAAA,WACA,KAAA,KAAA,OAAA,EACA,KAAA,OAAA,OAAA,GAGA,QAAA,SAAA,EAAA,GACA,KAAA,OAAA,QAAA,SAAA,EAAA,GACA,EAAA,KAAA,EAAA,EAAA,KAAA,KAAA,GAAA,OACA,OAEA,SAAA,WACA,MAAA,MAAA,KAAA,SAIA,EAAA,WAAA,GACA,OAAA,uBCzDA,SAAA,GACA,GAAA,IAEA,UACA,aACA,OACA,SACA,UACA,UACA,UACA,UACA,UACA,SACA,WACA,UACA,SACA,gBAEA,UAEA,YACA,QACA,SACA,WACA,QACA,QACA,cACA,cACA,YAEA,OACA,SACA,gBACA,SAGA,IAEA,GACA,EACA,KACA,KACA,EACA,EACA,EACA,GACA,GACA,GACA,GACA,EACA,EACA,KAEA,EAEA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,GACA,EAEA,GACA,KACA,KACA,GAGA,EAAA,mBAAA,oBAcA,GACA,QAAA,GAAA,SACA,cAAA,GAAA,SACA,WAAA,GAAA,GAAA,WACA,YAGA,gBACA,mBASA,eAAA,SAAA,EAAA,GACA,GAAA,GAAA,EACA,EAAA,EAAA,MACA,KACA,EAAA,QAAA,SAAA,GACA,EAAA,KACA,KAAA,SAAA,GAAA,EAAA,GAAA,KAAA,KAEA,MACA,KAAA,aAAA,GAAA,EACA,KAAA,gBAAA,KAAA,KAGA,SAAA,SAAA,GAEA,IAAA,GAAA,GADA,EAAA,KAAA,gBAAA,OACA,EAAA,EAAA,EAAA,IAAA,EAAA,KAAA,gBAAA,IAAA,IAEA,EAAA,SAAA,KAAA,EAAA,IAGA,WAAA,SAAA,GAEA,IAAA,GAAA,GADA,EAAA,KAAA,gBAAA,OACA,EAAA,EAAA,EAAA,IAAA,EAAA,KAAA,gBAAA,IAAA,IAEA,EAAA,WAAA,KAAA,EAAA,IAGA,SAAA,EAAA,SAAA,UAAA,SAAA,EAAA,GACA,MAAA,GAAA,SAAA,IAGA,KAAA,SAAA,GACA,EAAA,SAAA,EACA,KAAA,UAAA,cAAA,IAEA,KAAA,SAAA,GACA,EAAA,SAAA,EACA,KAAA,UAAA,cAAA,IAEA,GAAA,SAAA,GACA,EAAA,SAAA,EACA,KAAA,UAAA,YAAA,IAEA,MAAA,SAAA,GACA,EAAA,SAAA,EACA,KAAA,UAAA,eAAA,IAEA,MAAA,SAAA,GACA,EAAA,SAAA,EACA,KAAA,UAAA,eAAA,IAEA,KAAA,SAAA,GACA,EAAA,SAAA,EACA,KAAA,UAAA,cAAA,IAEA,IAAA,SAAA,GACA,EAAA,SAAA,EACA,KAAA,UAAA,aAAA,IAEA,OAAA,SAAA,GACA,EAAA,SAAA,EACA,KAAA,UAAA,gBAAA,IAEA,SAAA,SAAA,GACA,KAAA,IAAA,GACA,KAAA,SAAA,EAAA,OAAA,EAAA,gBACA,KAAA,MAAA,IAGA,UAAA,SAAA,GACA,KAAA,KAAA,GACA,KAAA,SAAA,EAAA,OAAA,EAAA,gBACA,KAAA,MAAA,IAIA,aAAA,SAAA,GAIA,IAAA,KAAA,cAAA,IAAA,GAAA,CAGA,GAAA,GAAA,EAAA,KACA,EAAA,KAAA,UAAA,KAAA,SAAA,EACA,IACA,EAAA,GAEA,KAAA,cAAA,IAAA,GAAA,KAGA,OAAA,SAAA,EAAA,GACA,EAAA,QAAA,SAAA,GACA,KAAA,SAAA,EAAA,IACA,OAGA,SAAA,SAAA,EAAA,GACA,EAAA,QAAA,SAAA,GACA,KAAA,YAAA,EAAA,IACA,OAEA,SAAA,EAAA,SAAA,UAAA,SAAA,EAAA,GACA,EAAA,iBAAA,EAAA,KAAA,eAEA,YAAA,EAAA,SAAA,aAAA,SAAA,EAAA,GACA,EAAA,oBAAA,EAAA,KAAA,eAWA,UAAA,SAAA,EAAA,GAEA,KAAA,cACA,EAAA,cAAA,KAEA,IAAA,GAAA,GAAA,cAAA,EAAA,EAKA,OAJA,GAAA,iBACA,EAAA,eAAA,EAAA,gBAEA,KAAA,QAAA,IAAA,EAAA,KAAA,QAAA,IAAA,IAAA,EAAA,QACA,GAGA,UAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,UAAA,EAAA,EACA,OAAA,MAAA,cAAA,IASA,WAAA,SAAA,GAEA,IAAA,GADA,GAAA,KACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GACA,EAAA,GAAA,EAAA,IAAA,EAAA,IAIA,GAAA,WAAA,GAAA,kBAAA,GACA,EAAA,YAAA,sBACA,EAAA,GAAA,EAAA,GAAA,wBAUA,OALA,GAAA,iBACA,EAAA,eAAA,WACA,EAAA,mBAGA,GAEA,UAAA,SAAA,GAGA,MAAA,MAAA,aACA,KAAA,YAAA,KAAA,EAAA,UACA,KAAA,YAAA,OAGA,KAAA,QAAA,IAAA,IAEA,WAAA,SAAA,EAAA,GACA,KAAA,aACA,KAAA,eAAA,KAAA,YAAA,IAEA,KAAA,aAAA,GAAA,EAAA,OAAA,EACA,IAAA,GAAA,GAAA,cAAA,qBAAA,SAAA,GACA,MAAA,gBAAA,KAAA,eAAA,KAAA,KAAA,GACA,SAAA,iBAAA,YAAA,KAAA,iBACA,SAAA,iBAAA,gBAAA,KAAA,iBACA,KAAA,QAAA,IAAA,EAAA,GACA,KAAA,mBAAA,IAEA,eAAA,SAAA,GACA,GAAA,KAAA,aAAA,KAAA,YAAA,KAAA,EAAA,CACA,GAAA,GAAA,GAAA,cAAA,sBAAA,SAAA,IACA,EAAA,KAAA,YAAA,MACA,MAAA,YAAA,KACA,SAAA,oBAAA,YAAA,KAAA,iBACA,SAAA,oBAAA,gBAAA,KAAA,iBACA,KAAA,QAAA,IAAA,EAAA,GACA,KAAA,mBAAA,KASA,cAAA,EAAA,SAAA,eAAA,SAAA,GACA,GAAA,GAAA,KAAA,UAAA,EACA,OAAA,GACA,EAAA,cAAA,GADA,QAIA,mBAAA,SAAA,GACA,WAAA,KAAA,cAAA,KAAA,KAAA,GAAA,IAGA,GAAA,aAAA,EAAA,aAAA,KAAA,GACA,EAAA,WAAA,EACA,EAAA,SAAA,EAAA,SAAA,KAAA,GACA,EAAA,WAAA,EAAA,WAAA,KAAA,IACA,OAAA,uBCvTA,SAAA,GAeA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,KAAA,YAAA,EAAA,KAAA,GACA,KAAA,eAAA,EAAA,KAAA,GACA,KAAA,gBAAA,EAAA,KAAA,GACA,IACA,KAAA,SAAA,GAAA,GAAA,KAAA,gBAAA,KAAA,QAnBA,GAAA,GAAA,MAAA,UAAA,QAAA,KAAA,KAAA,MAAA,UAAA,SACA,EAAA,MAAA,UAAA,IAAA,KAAA,KAAA,MAAA,UAAA,KACA,EAAA,MAAA,UAAA,MAAA,KAAA,KAAA,MAAA,UAAA,OACA,EAAA,MAAA,UAAA,OAAA,KAAA,KAAA,MAAA,UAAA,QACA,EAAA,OAAA,kBAAA,OAAA,uBACA,EAAA,iBACA,GACA,SAAA,EACA,WAAA,EACA,YAAA,EACA,mBAAA,EACA,iBAAA,gBAYA,GAAA,WACA,aAAA,SAAA,GAQA,EAAA,cAAA,UAAA,IACA,KAAA,SAAA,QAAA,EAAA,IAGA,gBAAA,SAAA,GACA,KAAA,aAAA,GACA,IAAA,UAAA,aAAA,SAAA,WACA,KAAA,gBAEA,KAAA,kBAAA,IAGA,kBAAA,SAAA,GACA,EAAA,KAAA,aAAA,GAAA,KAAA,WAAA,OAEA,aAAA,SAAA,GACA,MAAA,GAAA,iBACA,EAAA,iBAAA,OAIA,cAAA,SAAA,GACA,KAAA,eAAA,IAEA,WAAA,SAAA,GACA,KAAA,YAAA,IAEA,eAAA,SAAA,EAAA,GACA,KAAA,gBAAA,EAAA,IAEA,YAAA,SAAA,EAAA,GACA,MAAA,GAAA,OAAA,EAAA,KAGA,cAAA,WACA,SAAA,iBAAA,mBAAA,WACA,aAAA,SAAA,YACA,KAAA,kBAAA,WAEA,KAAA,QAEA,UAAA,SAAA,GACA,MAAA,GAAA,WAAA,KAAA,cAEA,oBAAA,SAAA,GAEA,GAAA,GAAA,EAAA,EAAA,KAAA,aAAA,KAIA,OAFA,GAAA,KAAA,EAAA,EAAA,KAAA,YAEA,EAAA,OAAA,KAAA,iBAEA,gBAAA,SAAA,GACA,EAAA,QAAA,KAAA,gBAAA,OAEA,gBAAA,SAAA,GACA,GAAA,cAAA,EAAA,KAAA,CACA,GAAA,GAAA,KAAA,oBAAA,EAAA,WACA,GAAA,QAAA,KAAA,WAAA,KACA,IAAA,GAAA,KAAA,oBAAA,EAAA,aACA,GAAA,QAAA,KAAA,cAAA,UACA,eAAA,EAAA,MACA,KAAA,eAAA,EAAA,OAAA,EAAA,YAKA,IACA,EAAA,UAAA,aAAA,WACA,QAAA,KAAA,uGAIA,EAAA,UAAA,GACA,OAAA,uBClHA,SAAA,GACA,GAAA,GAAA,EAAA,WACA,EAAA,EAAA,WAEA,EAAA,GAGA,GACA,WAAA,EACA,aAAA,QACA,QACA,YACA,YACA,UACA,YACA,YAEA,SAAA,SAAA,GACA,EAAA,OAAA,EAAA,KAAA,SAEA,WAAA,SAAA,GACA,EAAA,SAAA,EAAA,KAAA,SAEA,eAEA,0BAAA,SAAA,GAGA,IAAA,GAAA,GAFA,EAAA,KAAA,YACA,EAAA,EAAA,QAAA,EAAA,EAAA,QACA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IAAA,CAEA,GAAA,GAAA,KAAA,IAAA,EAAA,EAAA,GAAA,EAAA,KAAA,IAAA,EAAA,EAAA,EACA,IAAA,GAAA,GAAA,GAAA,EACA,OAAA,IAIA,aAAA,SAAA,GACA,GAAA,GAAA,EAAA,WAAA,GAEA,EAAA,EAAA,cAQA,OAPA,GAAA,eAAA,WACA,EAAA,iBACA,KAEA,EAAA,UAAA,KAAA,WACA,EAAA,WAAA,EACA,EAAA,YAAA,KAAA,aACA,GAEA,UAAA,SAAA,GACA,IAAA,KAAA,0BAAA,GAAA,CACA,GAAA,GAAA,EAAA,IAAA,KAAA,WAGA,IACA,KAAA,OAAA,EAEA,IAAA,GAAA,KAAA,aAAA,EACA,GAAA,IAAA,KAAA,WAAA,GACA,EAAA,KAAA,KAGA,UAAA,SAAA,GACA,IAAA,KAAA,0BAAA,GAAA,CACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,KAAA,KAGA,QAAA,SAAA,GACA,IAAA,KAAA,0BAAA,GAAA,CACA,GAAA,GAAA,EAAA,IAAA,KAAA,WACA,IAAA,GAAA,EAAA,SAAA,EAAA,OAAA,CACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,GAAA,GACA,KAAA,kBAIA,UAAA,SAAA,GACA,IAAA,KAAA,0BAAA,GAAA,CACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,UAAA,KAGA,SAAA,SAAA,GACA,IAAA,KAAA,0BAAA,GAAA,CACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,SAAA,KAGA,OAAA,SAAA,GACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,OAAA,GACA,KAAA,gBAEA,aAAA,WACA,EAAA,UAAA,KAAA,aAIA,GAAA,YAAA,GACA,OAAA,uBCrGA,SAAA,GACA,GASA,GATA,EAAA,EAAA,WACA,EAAA,EAAA,WACA,EAAA,EAAA,cAAA,WAAA,KAAA,EAAA,eACA,EAAA,EAAA,WACA,EAAA,MAAA,UAAA,IAAA,KAAA,KAAA,MAAA,UAAA,KAEA,EAAA,KACA,EAAA,IACA,EAAA,eAOA,GAAA,EAGA,GACA,WAAA,GAAA,SACA,QACA,aACA,YACA,WACA,eAEA,SAAA,SAAA,GACA,EACA,EAAA,OAAA,EAAA,KAAA,QAEA,EAAA,gBAAA,IAGA,WAAA,SAAA,GACA,GACA,EAAA,SAAA,EAAA,KAAA,SAKA,aAAA,SAAA,GACA,GAAA,GAAA,EAAA,aAAA,GACA,EAAA,KAAA,wBAAA,EACA,KACA,KAAA,WAAA,IAAA,EAAA,GACA,EAAA,OAAA,EAAA,KAAA,QAEA,EAAA,GAAA,QAAA,SAAA,GACA,KAAA,WAAA,IAAA,EAAA,GACA,EAAA,OAAA,EAAA,KAAA,SACA,QAGA,eAAA,SAAA,GACA,KAAA,WAAA,UAAA,GACA,EAAA,SAAA,EAAA,KAAA,QAEA,EAAA,GAAA,QAAA,SAAA,GACA,KAAA,WAAA,UAAA,GACA,EAAA,SAAA,EAAA,KAAA,SACA,OAEA,eAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,aAAA,GACA,EAAA,KAAA,wBAAA,GACA,EAAA,KAAA,wBAAA,EAEA,IAAA,GACA,KAAA,WAAA,IAAA,EAAA,GACA,EAAA,GAAA,QAAA,SAAA,GACA,KAAA,WAAA,IAAA,EAAA,IACA,OACA,EACA,KAAA,eAAA,GACA,GACA,KAAA,aAAA,IAGA,aACA,QAAA,OACA,UAAA,QACA,UAAA,QACA,SAAA,0CAEA,wBAAA,SAAA,GACA,GAAA,GAAA,EACA,EAAA,KAAA,WACA,OAAA,SAAA,EACA,OACA,IAAA,EAAA,UACA,IACA,IAAA,EAAA,UACA,IACA,EAAA,SAAA,KAAA,GACA,KADA,QAIA,aAAA,QACA,WAAA,KACA,eAAA,SAAA,GACA,MAAA,MAAA,aAAA,EAAA,YAEA,gBAAA,SAAA,IAEA,IAAA,EAAA,YAAA,IAAA,EAAA,YAAA,EAAA,IAAA,MACA,KAAA,WAAA,EAAA,WACA,KAAA,SAAA,EAAA,EAAA,QAAA,EAAA,EAAA,SACA,KAAA,WAAA,EACA,KAAA,0BAGA,qBAAA,SAAA,GACA,EAAA,YACA,KAAA,WAAA,KACA,KAAA,QAAA,KACA,KAAA,oBAGA,WAAA,EACA,QAAA,KACA,gBAAA,WACA,GAAA,GAAA,WACA,KAAA,WAAA,EACA,KAAA,QAAA,MACA,KAAA,KACA,MAAA,QAAA,WAAA,EAAA,IAEA,sBAAA,WACA,KAAA,SACA,aAAA,KAAA,UAGA,cAAA,SAAA,GACA,GAAA,GAAA,CAIA,QAHA,eAAA,GAAA,cAAA,KACA,EAAA,GAEA,GAEA,eAAA,SAAA,GACA,GAAA,GAAA,EAAA,WAAA,EAgBA,OAZA,GAAA,UAAA,EAAA,WAAA,EACA,EAAA,OAAA,EAAA,GACA,EAAA,SAAA,EACA,EAAA,YAAA,EACA,EAAA,OAAA,KAAA,WACA,EAAA,OAAA,EACA,EAAA,QAAA,KAAA,cAAA,KAAA,mBACA,EAAA,MAAA,EAAA,eAAA,EAAA,SAAA,EACA,EAAA,OAAA,EAAA,eAAA,EAAA,SAAA,EACA,EAAA,SAAA,EAAA,aAAA,EAAA,OAAA,GACA,EAAA,UAAA,KAAA,eAAA,GACA,EAAA,YAAA,KAAA,aACA,GAEA,eAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,cACA,MAAA,kBAAA,EAAA,IACA,IAAA,GAAA,EAAA,EAAA,KAAA,eAAA,KAEA,GAAA,QAAA,SAAA,GACA,EAAA,eAAA,WACA,KAAA,WAAA,EACA,KAAA,QAAA,KACA,EAAA,mBAEA,MACA,EAAA,QAAA,EAAA,OAIA,aAAA,SAAA,GACA,GAAA,KAAA,QAAA,CACA,GAAA,GACA,EAAA,KAAA,WAAA,IAAA,EAAA,cACA,IAAA,SAAA,EAEA,GAAA,MACA,IAAA,OAAA,EAEA,GAAA,MACA,CACA,GAAA,GAAA,EAAA,eAAA,GAEA,EAAA,EACA,EAAA,MAAA,EAAA,IAAA,IACA,EAAA,KAAA,IAAA,EAAA,SAAA,GAAA,KAAA,QAAA,IACA,EAAA,KAAA,IAAA,EAAA,SAAA,GAAA,KAAA,QAAA,GAGA,GAAA,GAAA,EAGA,MADA,MAAA,QAAA,KACA,IAGA,UAAA,SAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,GAAA,EAAA,aAAA,EACA,OAAA,GAUA,cAAA,SAAA,GACA,GAAA,GAAA,EAAA,OAGA,IAAA,EAAA,YAAA,EAAA,OAAA,CACA,GAAA,KACA,GAAA,QAAA,SAAA,EAAA,GAIA,GAAA,IAAA,IAAA,KAAA,UAAA,EAAA,EAAA,GAAA,CACA,GAAA,GAAA,EAAA,GACA,GAAA,KAAA,KAAA,eAAA,MAEA,MACA,EAAA,QAAA,KAAA,UAAA,QAGA,WAAA,SAAA,GACA,KAAA,cAAA,GACA,KAAA,gBAAA,EAAA,eAAA,IACA,KAAA,gBAAA,GACA,KAAA,YACA,KAAA,aACA,KAAA,eAAA,EAAA,KAAA,YAGA,SAAA,SAAA,GACA,EAAA,IAAA,EAAA,WACA,OAAA,EAAA,OACA,IAAA,EACA,UAAA,EAAA,QAEA,GAAA,KAAA,GACA,EAAA,MAAA,GACA,EAAA,KAAA,IAEA,UAAA,SAAA,GACA,KAAA,YACA,KAAA,aAAA,IACA,KAAA,WAAA,EACA,KAAA,YAAA,KAEA,EAAA,iBACA,KAAA,eAAA,EAAA,KAAA,gBAIA,YAAA,SAAA,GACA,GAAA,GAAA,EACA,EAAA,EAAA,IAAA,EAAA,UAEA,IAAA,EAAA,CAGA,GAAA,GAAA,EAAA,IACA,EAAA,EAAA,SACA,GAAA,KAAA,GACA,GAAA,IAAA,EAAA,SACA,EAAA,cAAA,EAAA,OACA,EAAA,cAAA,EAEA,EAAA,OAAA,EACA,EAAA,QACA,EAAA,SAAA,GACA,EAAA,UAAA,KAGA,EAAA,OAAA,EACA,EAAA,cAAA,KACA,KAAA,UAAA,KAGA,EAAA,IAAA,EACA,EAAA,UAAA,EAAA,SAEA,SAAA,SAAA,GACA,KAAA,gBAAA,GACA,KAAA,eAAA,EAAA,KAAA,QAEA,MAAA,SAAA,GACA,KAAA,YACA,EAAA,GAAA,GACA,EAAA,IAAA,GACA,EAAA,MAAA,IAEA,KAAA,eAAA,IAEA,YAAA,SAAA,GACA,KAAA,eAAA,EAAA,KAAA,YAEA,UAAA,SAAA,GACA,EAAA,OAAA,GACA,EAAA,IAAA,GACA,EAAA,MAAA,GACA,KAAA,eAAA,IAEA,eAAA,SAAA,GACA,EAAA,UAAA,EAAA,WACA,KAAA,qBAAA,IAGA,gBAAA,SAAA,GACA,GAAA,GAAA,EAAA,YAAA,YACA,EAAA,EAAA,eAAA,EAEA,IAAA,KAAA,eAAA,GAAA,CAEA,GAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,QACA,GAAA,KAAA,EACA,IAAA,GAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,QAAA,EACA,GAAA,IACA,EAAA,OAAA,EAAA,IAEA,KAAA,KAAA,EAAA,EACA,YAAA,EAAA,KAKA,KACA,EAAA,GAAA,GAAA,UAAA,EAAA,aAAA,EAAA,eAAA,EAAA,eAAA,IAGA,EAAA,YAAA,GACA,OAAA,uBCnVA,SAAA,GACA,GAAA,GAAA,EAAA,WACA,EAAA,EAAA,WACA,EAAA,OAAA,gBAAA,gBAAA,QAAA,eAAA,qBACA,GACA,QACA,gBACA,gBACA,cACA,eACA,gBACA,kBACA,sBACA,wBAEA,SAAA,SAAA,GACA,EAAA,OAAA,EAAA,KAAA,SAEA,WAAA,SAAA,GACA,EAAA,SAAA,EAAA,KAAA,SAEA,eACA,GACA,cACA,QACA,MACA,SAEA,aAAA,SAAA,GACA,GAAA,GAAA,CAKA,OAJA,KACA,EAAA,EAAA,WAAA,GACA,EAAA,YAAA,KAAA,cAAA,EAAA,cAEA,GAEA,QAAA,SAAA,GACA,EAAA,UAAA,IAEA,cAAA,SAAA,GACA,EAAA,IAAA,EAAA,UAAA,EACA,IAAA,GAAA,KAAA,aAAA,EACA,GAAA,KAAA,IAEA,cAAA,SAAA,GACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,KAAA,IAEA,YAAA,SAAA,GACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,GAAA,GACA,KAAA,QAAA,EAAA,YAEA,aAAA,SAAA,GACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,SAAA,IAEA,cAAA,SAAA,GACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,UAAA,IAEA,gBAAA,SAAA,GACA,GAAA,GAAA,KAAA,aAAA,EACA,GAAA,OAAA,GACA,KAAA,QAAA,EAAA,YAEA,qBAAA,SAAA,GACA,GAAA,GAAA,EAAA,UAAA,qBAAA,EACA,GAAA,cAAA,IAEA,oBAAA,SAAA,GACA,GAAA,GAAA,EAAA,UAAA,oBAAA,EACA,GAAA,cAAA,IAIA,GAAA,SAAA,GACA,OAAA,uBCxEA,SAAA,GACA,GAAA,GAAA,EAAA,UAGA,IAAA,SAAA,OAAA,UAAA,eAAA,CAGA,GAFA,OAAA,eAAA,OAAA,UAAA,kBAAA,OAAA,EAAA,YAAA,IAEA,OAAA,UAAA,iBAAA,CACA,GAAA,GAAA,OAAA,UAAA,gBACA,QAAA,eAAA,OAAA,UAAA,kBACA,MAAA,EACA,YAAA,IAEA,EAAA,eAAA,KAAA,EAAA,cAEA,GAAA,eAAA,QAAA,EAAA,aACA,SAAA,OAAA,cACA,EAAA,eAAA,QAAA,EAAA,YAIA,GAAA,SAAA,YAEA,OAAA,uBC5BA,SAAA,GAIA,QAAA,GAAA,GACA,IAAA,EAAA,WAAA,IAAA,GACA,KAAA,IAAA,OAAA,oBALA,GAEA,GAAA,EAFA,EAAA,EAAA,WACA,EAAA,OAAA,SAOA,GAAA,kBACA,EAAA,SAAA,GACA,EAAA,GACA,KAAA,oBAAA,IAEA,EAAA,SAAA,GACA,EAAA,GACA,KAAA,wBAAA,MAGA,EAAA,SAAA,GACA,EAAA,GACA,EAAA,WAAA,EAAA,OAEA,EAAA,SAAA,GACA,EAAA,GACA,EAAA,eAAA,EAAA,QAGA,OAAA,UAAA,QAAA,UAAA,mBACA,OAAA,iBAAA,QAAA,WACA,mBACA,MAAA,GAEA,uBACA,MAAA,MAIA,OAAA,uBnFDA,oBAAA,UAAA,WAAA,WACA,KAAA,cAAA,GoFtCA,SAAA,GAQA,EAAA,MACA,EAAA,OACA,KAEA,KAAA,SAAA,EAAA,GACA,GAAA,IAAA,EACA,MAAA,EAGA,IAAA,EAAA,SAAA,CACA,GAAA,EAAA,SAAA,GACA,MAAA,EAEA,IAAA,EAAA,SAAA,GACA,MAAA,GAGA,GAAA,GAAA,KAAA,MAAA,GACA,EAAA,KAAA,MAAA,GACA,EAAA,EAAA,CAMA,KALA,EAAA,EACA,EAAA,KAAA,KAAA,EAAA,GAEA,EAAA,KAAA,KAAA,GAAA,GAEA,GAAA,GAAA,IAAA,GACA,EAAA,KAAA,KAAA,EAAA,GACA,EAAA,KAAA,KAAA,EAAA,EAEA,OAAA,IAEA,KAAA,SAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,IACA,EAAA,EAAA,UAEA,OAAA,IAEA,MAAA,SAAA,GAEA,IADA,GAAA,GAAA,EACA,GACA,IACA,EAAA,EAAA,UAEA,OAAA,MAIA,EAAA,QAAA,SAAA,EAAA,GACA,MAAA,GAAA,MAAA,IAAA,KAAA,EAAA,IAEA,OAAA,gBAAA,GACA,OAAA,iBCxDA,SAAA,GAGA,QAAA,KACA,GAAA,EAAA,CACA,GAAA,GAAA,GAAA,IAEA,OADA,GAAA,SAAA,EACA,EAEA,KAAA,QACA,KAAA,UATA,GAAA,GAAA,OAAA,KAAA,OAAA,IAAA,UAAA,QACA,EAAA,WAAA,MAAA,MAAA,KAYA,GAAA,WACA,IAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,KAAA,QAAA,EACA,GAAA,GACA,KAAA,OAAA,GAAA,GAEA,KAAA,KAAA,KAAA,GACA,KAAA,OAAA,KAAA,KAGA,IAAA,SAAA,GACA,MAAA,MAAA,KAAA,QAAA,GAAA,IAEA,SAAA,SAAA,GACA,GAAA,GAAA,KAAA,KAAA,QAAA,EACA,GAAA,KACA,KAAA,KAAA,OAAA,EAAA,GACA,KAAA,OAAA,OAAA,EAAA,KAGA,IAAA,SAAA,GACA,GAAA,GAAA,KAAA,KAAA,QAAA,EACA,OAAA,MAAA,OAAA,IAEA,MAAA,WACA,KAAA,KAAA,OAAA,EACA,KAAA,OAAA,OAAA,GAGA,QAAA,SAAA,EAAA,GACA,KAAA,OAAA,QAAA,SAAA,EAAA,GACA,EAAA,KAAA,EAAA,EAAA,KAAA,KAAA,GAAA,OACA,OAEA,SAAA,WACA,MAAA,MAAA,KAAA,SAIA,EAAA,WAAA,GACA,OAAA,iBCzDA,SAAA,GACA,GAAA,IAEA,UACA,aACA,OACA,SACA,UACA,UACA,UACA,UACA,UACA,SACA,WACA,UACA,SACA,gBAEA,UAEA,YACA,QACA,SACA,WACA,QACA,QACA,cACA,cACA,YAEA,OACA,SACA,gBACA,UACA,UACA,QACA,QACA,gBAGA,IAEA,GACA,EACA,KACA,KACA,EACA,EACA,EACA,GACA,GACA,GACA,GACA,EACA,EACA,KAEA,EAEA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,GACA,EAEA,GACA,KACA,KACA,EACA,EACA,EACA,GAGA,GACA,cAAA,GAAA,SACA,QAAA,GAAA,SACA,YACA,eACA,UAGA,mBAAA,SAAA,EAAA,GACA,GAAA,GAAA,CACA,MAAA,YAAA,GAAA,EACA,EAAA,OAAA,QAAA,SAAA,GACA,GAAA,EAAA,GAAA,CACA,KAAA,OAAA,IAAA,CACA,IAAA,GAAA,EAAA,GAAA,KAAA,EACA,MAAA,WAAA,EAAA,KAEA,OAEA,WAAA,SAAA,EAAA,GACA,GAAA,GAAA,CACA,MAAA,SAAA,KACA,KAAA,SAAA,OAEA,KAAA,SAAA,GAAA,KAAA,IAGA,eAAA,SAAA,GACA,KAAA,OAAA,OAAA,KAAA,KAAA,QAAA,IAGA,iBAAA,SAAA,GACA,KAAA,SAAA,OAAA,KAAA,KAAA,QAAA,IAGA,aAAA,SAAA,GACA,IAAA,KAAA,cAAA,IAAA,GAAA,CAGA,GAAA,GAAA,EAAA,KAAA,EAAA,KAAA,SAAA,EACA,IACA,KAAA,UAAA,EAAA,GAEA,KAAA,cAAA,IAAA,GAAA,KAGA,UAAA,SAAA,EAAA,GAGA,GAAA,GAAA,KAAA,WAAA,EACA,YAAA,KAAA,SAAA,KAAA,KAAA,EAAA,GAAA,IAGA,SAAA,SAAA,EAAA,GACA,KAAA,iBAAA,EAAA,SACA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,OAAA,EAAA,IAAA,EAAA,EAAA,IAAA,IACA,EAAA,EAEA,MAAA,iBAAA,GAGA,OAAA,SAAA,EAAA,GACA,EAAA,QAAA,SAAA,GACA,KAAA,SAAA,EAAA,KAAA,cAAA,EAAA,IACA,OAGA,SAAA,SAAA,GACA,EAAA,QAAA,SAAA,GACA,KAAA,YAAA,EAAA,KAAA,cAAA,EAAA,WACA,OAEA,SAAA,SAAA,EAAA,EAAA,EAAA,GACA,EAAA,iBAAA,EAAA,EAAA,IAEA,YAAA,SAAA,EAAA,EAAA,EAAA,GACA,EAAA,oBAAA,EAAA,EAAA,IAKA,UAAA,SAAA,EAAA,GACA,MAAA,IAAA,qBAAA,EAAA,IAUA,WAAA,SAAA,GAEA,IAAA,GADA,GAAA,KACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GACA,EAAA,GAAA,EAAA,IAAA,EAAA,EAEA,OAAA,IAGA,cAAA,SAAA,EAAA,GACA,GAAA,GAAA,GAAA,KAAA,QAAA,IAAA,EACA,KACA,EAAA,cAAA,GACA,EAAA,cACA,KAAA,WAAA,KAAA,oBAIA,mBAAA,SAAA,EAAA,GACA,GAAA,GAAA,WACA,KAAA,cAAA,EAAA,IACA,KAAA,KACA,YAAA,EAAA,IAEA,WAAA,SAAA,GACA,GAAA,GAAA,KAAA,YAAA,GACA,IACA,EAAA,WAAA,IAIA,GAAA,aAAA,EAAA,aAAA,KAAA,GAGA,EAAA,iBACA,EAAA,mBAAA,EACA,EAAA,WAAA,EAUA,EAAA,SAAA,SAAA,GACA,GAAA,EAAA,kBAAA,CACA,GAAA,GAAA,OAAA,qBACA,IACA,EAAA,SAAA,GAEA,EAAA,WAAA,eAAA,OAEA,GAAA,cAAA,KAAA,IAGA,EAAA,SAAA,WACA,OAAA,iBCxLA,SAAA,GACA,GAAA,GAAA,EAAA,WACA,GAEA,WAAA,IAEA,iBAAA,GACA,QACA,cACA,cACA,YACA,iBAEA,YAAA,KACA,QAAA,KACA,MAAA,WACA,GAAA,GAAA,KAAA,MAAA,KAAA,YAAA,UACA,EAAA,KAAA,KAAA,YAAA,MACA,MAAA,SAAA,EAAA,GACA,KAAA,MAAA,GAEA,OAAA,WACA,cAAA,KAAA,SACA,KAAA,MACA,KAAA,SAAA,WAEA,KAAA,MAAA,EACA,KAAA,YAAA,KACA,KAAA,OAAA,KACA,KAAA,QAAA,MAEA,YAAA,SAAA,GACA,EAAA,YAAA,KAAA,cACA,KAAA,YAAA,EACA,KAAA,OAAA,EAAA,OACA,KAAA,QAAA,YAAA,KAAA,MAAA,KAAA,MAAA,KAAA,cAGA,UAAA,SAAA,GACA,KAAA,aAAA,KAAA,YAAA,YAAA,EAAA,WACA,KAAA,UAGA,cAAA,WACA,KAAA,UAEA,YAAA,SAAA,GACA,GAAA,KAAA,aAAA,KAAA,YAAA,YAAA,EAAA,UAAA,CACA,GAAA,GAAA,EAAA,QAAA,KAAA,YAAA,QACA,EAAA,EAAA,QAAA,KAAA,YAAA,OACA,GAAA,EAAA,EAAA,EAAA,KAAA,kBACA,KAAA,WAIA,SAAA,SAAA,EAAA,GACA,GAAA,IACA,YAAA,KAAA,YAAA,YACA,QAAA,KAAA,YAAA,QACA,QAAA,KAAA,YAAA,QAEA,KACA,EAAA,SAAA,EAEA,IAAA,GAAA,EAAA,UAAA,EAAA,EACA,GAAA,cAAA,EAAA,KAAA,QACA,EAAA,cACA,EAAA,WAAA,KAAA,YAAA,YAIA,GAAA,mBAAA,OAAA,IACA,OAAA,iBCpBA,SAAA,GACA,GAAA,GAAA,EAAA,WACA,EAAA,GAAA,GAAA,WACA,GACA,QACA,cACA,cACA,YACA,iBAEA,iBAAA,EACA,SAAA,SAAA,GACA,MAAA,GAAA,EAAA,EAAA,IAEA,kBAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,EAAA,CAKA,OAJA,IAAA,IACA,EAAA,EAAA,MAAA,EAAA,MACA,EAAA,EAAA,MAAA,EAAA,QAEA,EAAA,EAAA,EAAA,IAEA,UAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,EACA,EAAA,KAAA,kBAAA,EAAA,UAAA,GACA,EAAA,KAAA,kBAAA,EAAA,cAAA,EACA,GAAA,IACA,EAAA,WAAA,KAAA,SAAA,EAAA,IAEA,EAAA,IACA,EAAA,WAAA,KAAA,SAAA,EAAA,GAEA,IAAA,IACA,GAAA,EAAA,EACA,GAAA,EAAA,EACA,IAAA,EAAA,EACA,IAAA,EAAA,EACA,QAAA,EAAA,QACA,QAAA,EAAA,QACA,MAAA,EAAA,MACA,MAAA,EAAA,MACA,QAAA,EAAA,QACA,QAAA,EAAA,QACA,WAAA,EAAA,WACA,WAAA,EAAA,WACA,UAAA,EAAA,UACA,cAAA,EAAA,OACA,YAAA,EAAA,aAEA,EAAA,EAAA,UAAA,EAAA,EACA,GAAA,cAAA,EACA,EAAA,cAAA,EAAA,EAAA,aAEA,YAAA,SAAA,GACA,GAAA,EAAA,YAAA,UAAA,EAAA,YAAA,IAAA,EAAA,SAAA,GAAA,CACA,GAAA,IACA,UAAA,EACA,WAAA,EAAA,OACA,aACA,cAAA,KACA,WAAA,EACA,WAAA,EACA,UAAA,EAEA,GAAA,IAAA,EAAA,UAAA,KAGA,YAAA,SAAA,GACA,GAAA,GAAA,EAAA,IAAA,EAAA,UACA,IAAA,EACA,GAAA,EAAA,SAUA,KAAA,UAAA,QAAA,EAAA,OAVA,CACA,GAAA,GAAA,KAAA,kBAAA,EAAA,UAAA,GACA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAEA,GAAA,KAAA,mBACA,EAAA,UAAA,EACA,KAAA,UAAA,aAAA,EAAA,UAAA,GACA,KAAA,UAAA,QAAA,EAAA,MAOA,UAAA,SAAA,GACA,GAAA,GAAA,EAAA,IAAA,EAAA,UACA,KACA,EAAA,UACA,KAAA,UAAA,WAAA,EAAA,GAEA,EAAA,OAAA,EAAA,aAGA,cAAA,SAAA,GACA,KAAA,UAAA,IAGA,GAAA,mBAAA,QAAA,IACA,OAAA,iBCxJA,SAAA,GACA,GAAA,GAAA,EAAA,WACA,GAGA,aAAA,GACA,UAAA,EACA,aACA,OAAA,KACA,UAAA,KACA,QACA,cACA,cACA,YACA,iBAEA,YAAA,SAAA,GACA,EAAA,YAAA,KAAA,YACA,KAAA,UAAA,EAAA,UACA,KAAA,OAAA,EAAA,OACA,KAAA,QAAA,KAGA,YAAA,SAAA,GACA,EAAA,YAAA,KAAA,WACA,KAAA,QAAA,IAGA,UAAA,SAAA,GACA,EAAA,YAAA,KAAA,WACA,KAAA,UAAA,GAEA,KAAA,WAEA,cAAA,WACA,KAAA,WAEA,QAAA,WACA,KAAA,aACA,KAAA,OAAA,KACA,KAAA,UAAA,MAEA,QAAA,SAAA,GACA,KAAA,UAAA,QAAA,KAAA,WACA,KAAA,UAAA,QAEA,KAAA,UAAA,KAAA,IAEA,UAAA,SAAA,GAKA,IAAA,GAFA,GAAA,EAAA,EAAA,EAAA,EAAA,EAEA,EAJA,EAAA,EACA,EAAA,KAAA,UAAA,OACA,EAAA,EAAA,EAAA,EAAA,EAAA,EAEA,EAAA,EAAA,EAAA,IAAA,EAAA,KAAA,UAAA,IAAA,IACA,EAAA,EAAA,UAAA,EAAA,UACA,EAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,QACA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,EAAA,GACA,EAAA,IACA,EAAA,EAAA,EAAA,EAAA,EAAA,EAGA,IAAA,GAAA,KAAA,IAAA,GAAA,KAAA,IAAA,GAAA,IAAA,IACA,EAAA,KAAA,UAAA,EAAA,EACA,IAAA,KAAA,IAAA,IAAA,KAAA,aAAA,CACA,GAAA,GAAA,EAAA,UAAA,SACA,UAAA,EACA,UAAA,EACA,SAAA,EACA,MAAA,EACA,UAAA,EACA,YAAA,EAAA,aAEA,GAAA,cAAA,EAAA,KAAA,UAGA,UAAA,SAAA,EAAA,GACA,MAAA,KAAA,KAAA,MAAA,EAAA,GAAA,KAAA,IAGA,GAAA,mBAAA,QAAA,IACA,OAAA,iBC5EA,SAAA,GACA,GAAA,GAAA,EAAA,WACA,EAAA,GAAA,GAAA,WACA,EAAA,IAAA,KAAA,GACA,GACA,QACA,cACA,cACA,YACA,iBAEA,aACA,YAAA,SAAA,GAEA,GADA,EAAA,IAAA,EAAA,UAAA,GACA,GAAA,EAAA,WAAA,CACA,GAAA,GAAA,KAAA,YACA,EAAA,KAAA,UAAA,EACA,MAAA,WACA,MAAA,EACA,SAAA,EAAA,SACA,OAAA,EAAA,QAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAIA,UAAA,SAAA,GACA,EAAA,OAAA,EAAA,YAEA,YAAA,SAAA,GACA,EAAA,IAAA,EAAA,aACA,EAAA,IAAA,EAAA,UAAA,GACA,EAAA,WAAA,GACA,KAAA,oBAIA,cAAA,SAAA,GACA,KAAA,UAAA,IAEA,cAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,KAAA,UAAA,SACA,EAAA,EAAA,UAAA,SACA,MAAA,EACA,QAAA,EAAA,OAAA,EACA,QAAA,EAAA,OAAA,GAEA,GAAA,cAAA,EAAA,KAAA,UAAA,SAEA,eAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,OAAA,EAAA,KAAA,UAAA,OAAA,KACA,EAAA,EAAA,UAAA,UACA,MAAA,EACA,QAAA,EAAA,OAAA,EACA,QAAA,EAAA,OAAA,GAEA,GAAA,cAAA,EAAA,KAAA,UAAA,SAEA,gBAAA,WACA,GAAA,GAAA,KAAA,YACA,EAAA,EAAA,SACA,EAAA,KAAA,UAAA,EACA,IAAA,KAAA,UAAA,UACA,KAAA,cAAA,EAAA,GAEA,GAAA,KAAA,UAAA,OACA,KAAA,eAAA,EAAA,IAGA,UAAA,WACA,GAAA,KACA,GAAA,QAAA,SAAA,GACA,EAAA,KAAA,IAMA,KAAA,GADA,GAAA,EAAA,EAHA,EAAA,EAEA,GAAA,EAAA,EAAA,GAAA,EAAA,EAAA,IAEA,EAAA,EAAA,EAAA,EAAA,OAAA,IAEA,IAAA,GADA,GAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,KAAA,IAAA,EAAA,QAAA,EAAA,SACA,EAAA,KAAA,IAAA,EAAA,QAAA,EAAA,SACA,EAAA,EAAA,EACA,EAAA,IACA,EAAA,EACA,GAAA,EAAA,EAAA,EAAA,IAQA,MAJA,GAAA,KAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,SAAA,EACA,EAAA,KAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,SAAA,EACA,EAAA,QAAA,EAAA,EAAA,EAAA,GACA,EAAA,SAAA,EACA,GAEA,UAAA,SAAA,GACA,GAAA,GAAA,EAAA,EAAA,QAAA,EAAA,EAAA,QACA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,OACA,QAAA,IAAA,KAAA,MAAA,EAAA,GAAA,GAAA,KAGA,GAAA,mBAAA,QAAA,IACA,OAAA,iBCvHA,SAAA,GACA,GAAA,GAAA,EAAA,WACA,EAAA,GAAA,GAAA,WACA,GACA,QACA,cACA,cACA,YACA,gBACA,SAEA,YAAA,SAAA,GACA,EAAA,YAAA,EAAA,cACA,EAAA,IAAA,EAAA,WACA,OAAA,EAAA,OACA,QAAA,EAAA,QACA,EAAA,EAAA,QACA,EAAA,EAAA,WAIA,YAAA,SAAA,GACA,GAAA,EAAA,UAAA,CACA,GAAA,GAAA,EAAA,IAAA,EAAA,UACA,IACA,EAAA,cACA,EAAA,OAAA,EAAA,aAKA,UAAA,SAAA,EAAA,GACA,MAAA,GAAA,aAAA,OACA,UAAA,EAAA,YAEA,IAAA,EAAA,SAEA,GAIA,UAAA,SAAA,GACA,GAAA,GAAA,EAAA,IAAA,EAAA,UACA,IAAA,GAAA,KAAA,UAAA,EAAA,GAAA,CACA,GAAA,GAAA,EAAA,QAAA,EAAA,OAAA,EAAA,OACA,IAAA,EAAA,CACA,GAAA,GAAA,EAAA,UAAA,OACA,EAAA,EAAA,QACA,EAAA,EAAA,QACA,OAAA,EAAA,OACA,YAAA,EAAA,aAEA,GAAA,cAAA,EAAA,IAGA,EAAA,OAAA,EAAA,YAEA,cAAA,SAAA,GACA,EAAA,OAAA,EAAA,YAEA,MAAA,SAAA,GACA,GAAA,GAAA,EAAA,OAEA,IAAA,KAAA,EAAA,CACA,GAAA,GAAA,EAAA,MACA,aAAA,mBAAA,YAAA,sBACA,EAAA,cAAA,EAAA,UAAA,OACA,EAAA,EACA,EAAA,EACA,OAAA,EACA,YAAA,gBACA,KAIA,WAAA,SAAA,GACA,EAAA,OAAA,IAGA,GAAA,mBAAA,MAAA,IACA,OAAA,iBCzGA,SAAA,GAEA,QAAA,KACA,EAAA,mBAAA,CACA,IAAA,GAAA,EAAA,aACA,GAAA,QAAA,EAAA,UACA,EAAA,OAAA,EALA,GAAA,GAAA,EAAA,UAOA,cAAA,SAAA,WACA,IAIA,SAAA,iBAAA,mBAAA,WACA,aAAA,SAAA,YACA,OAIA,OAAA,iBCfA,WACA,YAIA,SAAA,GAAA,GACA,KAAA,EAAA,YACA,EAAA,EAAA,UAGA,OAAA,kBAAA,GAAA,eAAA,EAAA,KAQA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,QACA,KAAA,EAEA,YADA,EAAA,YAIA,IAAA,GAAA,EAAA,EACA,KAGA,EAAA,QACA,EAAA,GAAA,QAoBA,QAAA,GAAA,GACA,MAAA,OAAA,EAAA,GAAA,EAGA,QAAA,GAAA,EAAA,GACA,EAAA,KAAA,EAAA,GAGA,QAAA,GAAA,GACA,MAAA,UAAA,GACA,MAAA,GAAA,EAAA,IAgBA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,MAAA,QACA,EACA,EAAA,aAAA,EAAA,IAEA,EAAA,gBAAA,QAIA,GAAA,aAAA,EAAA,EAAA,IAGA,QAAA,GAAA,EAAA,EAAA,GACA,MAAA,UAAA,GACA,EAAA,EAAA,EAAA,EAAA,IAgDA,QAAA,GAAA,GACA,OAAA,EAAA,MACA,IAAA,WACA,MAAA,EACA,KAAA,QACA,IAAA,kBACA,IAAA,aACA,MAAA,QACA,KAAA,QACA,GAAA,eAAA,KAAA,UAAA,WACA,MAAA,QACA,SACA,MAAA,SAIA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,EAAA,IAAA,GAAA,GAAA,GAGA,QAAA,GAAA,EAAA,EAAA,GACA,MAAA,UAAA,GACA,MAAA,GAAA,EAAA,EAAA,EAAA,IAIA,QAAA,MAEA,QAAA,GAAA,EAAA,EAAA,EAAA,GAGA,QAAA,KACA,EAAA,SAAA,EAAA,IACA,EAAA,kBACA,GAAA,GAAA,GACA,SAAA,6BANA,GAAA,GAAA,EAAA,EAQA,GAAA,iBAAA,EAAA,EAEA,IAAA,GAAA,EAAA,KACA,GAAA,MAAA,WACA,IAEA,EAAA,oBAAA,EAAA,GAEA,EAAA,MAAA,EACA,EAAA,QACA,EAAA,SAIA,QAAA,GAAA,GACA,MAAA,SAAA,GAYA,QAAA,GAAA,GACA,GAAA,EAAA,KACA,MAAA,GAAA,EAAA,KAAA,SAAA,SAAA,GACA,MAAA,IAAA,GACA,SAAA,EAAA,SACA,SAAA,EAAA,MACA,EAAA,MAAA,EAAA,MAGA,IAAA,GAAA,EAAA,EACA,KAAA,EACA,QACA,IAAA,GAAA,EAAA,iBACA,6BAAA,EAAA,KAAA,KACA,OAAA,GAAA,EAAA,SAAA,GACA,MAAA,IAAA,IAAA,EAAA,OAKA,QAAA,GAAA,GAIA,UAAA,EAAA,SACA,UAAA,EAAA,MACA,EAAA,GAAA,QAAA,SAAA,GACA,GAAA,GAAA,EAAA,SAAA,OACA,IAEA,EAAA,UAAA,KA4CA,QAAA,GAAA,EAAA,GACA,GACA,GACA,EACA,EAHA,EAAA,EAAA,UAIA,aAAA,oBACA,EAAA,UACA,EAAA,SAAA,QACA,EAAA,EACA,EAAA,EAAA,SAAA,MACA,EAAA,EAAA,OAGA,EAAA,MAAA,EAAA,GAEA,GAAA,EAAA,OAAA,IACA,EAAA,SAAA,EAAA,OACA,EAAA,iBACA,SAAA,8BAIA,QAAA,GAAA,GACA,MAAA,UAAA,GACA,EAAA,EAAA,IAzSA,GAAA,GAAA,MAAA,UAAA,OAAA,KAAA,KAAA,MAAA,UAAA,OAWA,MAAA,UAAA,KAAA,SAAA,EAAA,GACA,QAAA,MAAA,8BAAA,KAAA,EAAA,IAkBA,KAAA,UAAA,OAAA,SAAA,GACA,EAAA,KAAA,IAGA,KAAA,UAAA,UAAA,WACA,GAAA,KAAA,SAAA,CAGA,IAAA,GADA,GAAA,OAAA,KAAA,KAAA,UACA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,KAAA,SAAA,EAAA,GACA,IACA,EAAA,QAGA,KAAA,cAiBA,KAAA,UAAA,KAAA,SAAA,EAAA,EAAA,GACA,MAAA,gBAAA,EACA,KAAA,UAAA,KAAA,KAAA,KAAA,EAAA,EAAA,GAEA,EACA,EAAA,KAAA,IAEA,EAAA,KAAA,eACA,EAAA,KAAA,EAAA,KAAA,EAAA,QACA,KAAA,SAAA,YAAA,IAqBA,QAAA,UAAA,KAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,KAAA,EAAA,EAAA,OAAA,EAMA,OALA,KACA,KAAA,gBAAA,GACA,EAAA,EAAA,MAAA,EAAA,KAGA,EACA,EAAA,KAAA,EAAA,EAAA,IAEA,EAAA,KAAA,GACA,EAAA,KAAA,EAAA,EACA,EAAA,KAAA,EAAA,KAAA,EAAA,KAEA,KAAA,SAAA,GAAA,GAGA,IAAA,IACA,WAGA,GAAA,GAAA,SAAA,cAAA,OACA,EAAA,EAAA,YAAA,SAAA,cAAA,SACA,GAAA,aAAA,OAAA,WACA,IAAA,GACA,EAAA,CACA,GAAA,iBAAA,QAAA,WACA,IACA,EAAA,GAAA,UAEA,EAAA,iBAAA,SAAA,WACA,IACA,EAAA,GAAA,UAGA,IAAA,GAAA,SAAA,YAAA,aACA,GAAA,eAAA,SAAA,GAAA,EAAA,OAAA,EAAA,EAAA,EAAA,EAAA,GAAA,GACA,GAAA,GAAA,EAAA,EAAA,MACA,EAAA,cAAA,GAGA,EAAA,GAAA,EAAA,SAAA,KAuGA,iBAAA,UAAA,KAAA,SAAA,EAAA,EAAA,GACA,GAAA,UAAA,GAAA,YAAA,EACA,MAAA,aAAA,UAAA,KAAA,KAAA,KAAA,EAAA,EAAA,EAGA,MAAA,gBAAA,EACA,IAAA,GAAA,WAAA,EAAA,EAAA,EACA,EAAA,WAAA,EAAA,EAAA,CAEA,OAAA,GACA,EAAA,KAAA,EAAA,EAAA,IAEA,EAAA,KAAA,GACA,EAAA,KAAA,EAAA,EAAA,GACA,EAAA,KAAA,EACA,EAAA,KAAA,EAAA,KAAA,EAAA,IACA,GAEA,KAAA,SAAA,GAAA,IAGA,oBAAA,UAAA,KAAA,SAAA,EAAA,EAAA,GACA,MAAA,UAAA,EACA,YAAA,UAAA,KAAA,KAAA,KAAA,EAAA,EAAA,IAEA,KAAA,gBAAA,SAEA,EACA,EAAA,KAAA,QAAA,IAEA,EAAA,KAAA,SACA,EAAA,KAAA,QAAA,GACA,EAAA,KAAA,QACA,EAAA,KAAA,EAAA,KAAA,QAAA,KAEA,KAAA,SAAA,MAAA,KA+BA,kBAAA,UAAA,KAAA,SAAA,EAAA,EAAA,GACA,MAAA,UAAA,EACA,YAAA,UAAA,KAAA,KAAA,KAAA,EAAA,EAAA,IAEA,KAAA,gBAAA,SAEA,EACA,EAAA,KAAA,IAEA,EAAA,KAAA,SACA,EAAA,KAAA,QAAA,GACA,EAAA,KAAA,EAAA,KAAA,EAAA,QACA,KAAA,SAAA,MAAA,KAGA,kBAAA,UAAA,KAAA,SAAA,EAAA,EAAA,GAIA,MAHA,kBAAA,IACA,EAAA,iBAEA,kBAAA,GAAA,UAAA,EACA,YAAA,UAAA,KAAA,KAAA,KAAA,EAAA,EAAA,IAEA,KAAA,gBAAA,GAEA,EACA,EAAA,KAAA,EAAA,IAEA,EAAA,KAAA,GACA,EAAA,KAAA,EAAA,GACA,EAAA,KAAA,EACA,EAAA,KAAA,EAAA,KAAA,KACA,KAAA,SAAA,GAAA,MAEA,MCjVA,SAAA,GACA,YAEA,SAAA,GAAA,GACA,IAAA,EACA,KAAA,IAAA,OAAA,oBAKA,QAAA,GAAA,GAEA,IADA,GAAA,GACA,EAAA,EAAA,YACA,EAAA,CAGA,OAAA,GAGA,QAAA,GAAA,EAAA,GACA,GAAA,EAAA,CAKA,IAFA,GAAA,GACA,EAAA,IAAA,GACA,IACA,EAAA,EAAA,GAEA,EAAA,cACA,EAAA,EAAA,cAAA,cAAA,GACA,EAAA,iBACA,EAAA,EAAA,eAAA,KAEA,GAAA,EAAA,mBAGA,EAAA,EAAA,gBAGA,OAAA,IAiIA,QAAA,GAAA,GACA,MAAA,YAAA,EAAA,SACA,8BAAA,EAAA,aAGA,QAAA,GAAA,GACA,MAAA,YAAA,EAAA,SACA,gCAAA,EAAA,aAGA,QAAA,GAAA,GACA,MAAA,SAAA,EAAA,EAAA,UACA,EAAA,aAAA,aAGA,QAAA,GAAA,GAIA,MAHA,UAAA,EAAA,cACA,EAAA,YAAA,YAAA,EAAA,SAAA,EAAA,IAEA,EAAA,YAYA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,iBAAA,EAEA,GAAA,IACA,EAAA,GACA,EAAA,EAAA,GAGA,QAAA,GAAA,GACA,QAAA,GAAA,GACA,oBAAA,SAAA,IACA,EAAA,EAAA,SAGA,EAAA,EAAA,GAgBA,QAAA,GAAA,EAAA,GACA,OAAA,oBAAA,GAAA,QAAA,SAAA,GACA,OAAA,eAAA,EAAA,EACA,OAAA,yBAAA,EAAA,MAKA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,aACA,KAAA,EAAA,YACA,MAAA,EACA,IAAA,GAAA,EAAA,sBACA,KAAA,EAAA,CAIA,IADA,EAAA,EAAA,eAAA,mBAAA,IACA,EAAA,WACA,EAAA,YAAA,EAAA,UAEA,GAAA,uBAAA,EAEA,MAAA,GAGA,QAAA,GAAA,GACA,IAAA,EAAA,iBAAA,CACA,GAAA,GAAA,EAAA,aACA,KAAA,EAAA,iBAAA,CACA,EAAA,iBAAA,EAAA,eAAA,mBAAA,GAKA,IAAA,GAAA,EAAA,iBAAA,cAAA,OACA,GAAA,KAAA,SAAA,QACA,EAAA,iBAAA,KAAA,YAAA,GAEA,EAAA,iBAAA,iBAAA,EAAA,iBAGA,EAAA,iBAAA,EAAA,iBAGA,MAAA,GAAA,iBAgBA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,cAAA,cAAA,WACA,GAAA,WAAA,aAAA,EAAA,EAIA,KAFA,GAAA,GAAA,EAAA,WACA,EAAA,EAAA,OACA,IAAA,GAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,EAAA,QACA,aAAA,EAAA,MACA,EAAA,aAAA,EAAA,KAAA,EAAA,OACA,EAAA,gBAAA,EAAA,OAIA,MAAA,GAGA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,cAAA,cAAA,WACA,GAAA,WAAA,aAAA,EAAA,EAIA,KAFA,GAAA,GAAA,EAAA,WACA,EAAA,EAAA,OACA,IAAA,GAAA,CACA,GAAA,GAAA,EAAA,EACA,GAAA,aAAA,EAAA,KAAA,EAAA,OACA,EAAA,gBAAA,EAAA;CAIA,MADA,GAAA,WAAA,YAAA,GACA,EAGA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,OACA,IAAA,EAEA,WADA,GAAA,YAAA,EAKA,KADA,GAAA,GACA,EAAA,EAAA,YACA,EAAA,YAAA,GA4FA,QAAA,GAAA,GACA,EACA,EAAA,UAAA,oBAAA,UAEA,EAAA,EAAA,oBAAA,WAGA,QAAA,GAAA,GACA,EAAA,cACA,EAAA,YAAA,WACA,EAAA,sBAAA,CACA,IAAA,GAAA,EAAA,EACA,EAAA,WAAA,EAAA,UAAA,eACA,GAAA,EAAA,EAAA,EAAA,UAIA,EAAA,uBACA,EAAA,sBAAA,EACA,SAAA,QAAA,EAAA,cAkMA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,OAAA,CAOA,IAJA,GAAA,GACA,EAAA,EAAA,OACA,EAAA,EAAA,EAAA,EAAA,EAAA,EACA,GAAA,EACA,EAAA,GAAA,CACA,GAAA,GAAA,EAAA,QAAA,KAAA,GACA,EAAA,EAAA,QAAA,KAAA,GACA,GAAA,EACA,EAAA,IAWA,IATA,GAAA,IACA,EAAA,GAAA,EAAA,KACA,EAAA,EACA,GAAA,EACA,EAAA,MAGA,EAAA,EAAA,EAAA,GAAA,EAAA,QAAA,EAAA,EAAA,GAEA,EAAA,EAAA,CACA,IAAA,EACA,MAEA,GAAA,KAAA,EAAA,MAAA,GACA,OAGA,EAAA,MACA,EAAA,KAAA,EAAA,MAAA,EAAA,GACA,IAAA,GAAA,EAAA,MAAA,EAAA,EAAA,GAAA,MACA,GAAA,KAAA,GACA,EAAA,GAAA,EACA,EAAA,KAAA,KAAA,IAAA,GACA,IAAA,GAAA,GACA,EAAA,EAAA,EAAA,EACA,GAAA,KAAA,GACA,EAAA,EAAA,EAyBA,MAtBA,KAAA,GACA,EAAA,KAAA,IAEA,EAAA,WAAA,IAAA,EAAA,OACA,EAAA,aAAA,EAAA,YACA,IAAA,EAAA,IACA,IAAA,EAAA,GACA,EAAA,YAAA,EAEA,EAAA,WAAA,SAAA,GAGA,IAAA,GAFA,GAAA,EAAA,GAEA,EAAA,EAAA,EAAA,EAAA,OAAA,GAAA,EAAA,CACA,GAAA,GAAA,EAAA,WAAA,EAAA,GAAA,EAAA,GAAA,EACA,UAAA,IACA,GAAA,GACA,GAAA,EAAA,EAAA,GAGA,MAAA,IAGA,GAGA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,GAAA,EAAA,WAAA,CACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAAA,GAAA,GACA,EAAA,GAAA,aAAA,EACA,OAAA,GAAA,aAAA,EAAA,EAAA,WAAA,GAIA,IAAA,GADA,MACA,EAAA,EAAA,EAAA,EAAA,OAAA,GAAA,EAAA,CACA,GAAA,GAAA,EAAA,EAAA,EACA,IAAA,EAAA,GAAA,GAAA,EAAA,EAAA,EAAA,GACA,EAAA,EAAA,GAAA,aAAA,GAGA,MAAA,GAAA,WAAA,GAGA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAAA,GAAA,GACA,GAAA,cAAA,EAAA,EAAA,GAEA,OAAA,GAAA,aAAA,EACA,GAAA,mBAAA,EAAA,EAAA,YAGA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,GAAA,EAAA,YACA,MAAA,GAAA,EAAA,EAAA,EAAA,EAEA,IAAA,EAAA,WACA,MAAA,GAAA,EAAA,EAAA,EAAA,EAIA,KAAA,GAFA,GAAA,GAAA,kBAEA,EAAA,EAAA,EAAA,EAAA,OAAA,GAAA,EAAA,CACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAEA,IAAA,EAAA,CACA,GAAA,GAAA,EAAA,EAAA,EAAA,EACA,GACA,EAAA,QAAA,GAEA,EAAA,YAAA,OALA,CASA,GAAA,GAAA,EAAA,EAAA,EACA,GACA,EAAA,QAAA,EAAA,aAAA,IAEA,EAAA,QAAA,EAAA,IAGA,MAAA,IAAA,mBAAA,EAAA,EAAA,YAGA,QAAA,GAAA,EAAA,EAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,GAAA,EAAA,CACA,GAAA,GAAA,EAAA,GACA,EAAA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAAA,EAAA,GACA,EAAA,EAAA,KAAA,EAAA,EAAA,EAAA,YACA,IAAA,GACA,EAAA,KAAA,GAGA,GAAA,EAAA,WAAA,CAGA,EAAA,OAAA,CACA,IAAA,GAAA,EAAA,0BAAA,EACA,IAAA,GACA,EAAA,KAAA,IAGA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,aAAA,EACA,OAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,EAAA,GAGA,QAAA,GAAA,EAAA,GACA,EAAA,EAMA,KAAA,GAJA,MAIA,EAAA,EAAA,EAAA,EAAA,WAAA,OAAA,IAAA,CAUA,IATA,GAAA,GAAA,EAAA,WAAA,GACA,EAAA,EAAA,KACA,EAAA,EAAA,MAOA,MAAA,EAAA,IACA,EAAA,EAAA,UAAA,EAGA,KAAA,EAAA,IACA,IAAA,GAAA,IAAA,GAAA,IAAA,EADA,CAKA,GAAA,GAAA,EAAA,EAAA,EAAA,EACA,EACA,IAGA,EAAA,KAAA,EAAA,IAaA,MAVA,GAAA,KACA,EAAA,YAAA,EACA,EAAA,GAAA,EAAA,EAAA,EAAA,GACA,EAAA,KAAA,EAAA,EAAA,EAAA,GACA,EAAA,OAAA,EAAA,EAAA,EAAA,IAEA,EAAA,IAAA,EAAA,MAAA,EAAA,SACA,EAAA,KAAA,EAAA,OAAA,EAAA,EAAA,KAGA,EAGA,QAAA,GAAA,EAAA,GACA,GAAA,EAAA,WAAA,KAAA,aACA,MAAA,GAAA,EAAA,EAEA,IAAA,EAAA,WAAA,KAAA,UAAA,CACA,GAAA,GAAA,EAAA,EAAA,KAAA,cAAA,EACA,EACA,IAAA,EACA,OAAA,cAAA,GAGA,SAGA,QAAA,GAAA,EAAA,EAAA,EAAA,EAAA,EACA,EACA,GAKA,IAAA,GAHA,GAAA,EAAA,YAAA,EAAA,WAAA,GAAA,IAEA,EAAA,EACA,EAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,EAAA,EAAA,EACA,EAAA,SAAA,KACA,EACA,EACA,EAUA,OAPA,GAAA,aACA,oBAAA,SAAA,EAAA,GACA,GACA,EAAA,aAAA,IAGA,EAAA,EAAA,EAAA,EAAA,GACA,EAGA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,EAAA,EACA,GAAA,WAEA,KAAA,GADA,GAAA,EACA,EAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YACA,EAAA,SAAA,KAAA,EAAA,EAAA,EAGA,OAAA,GAWA,QAAA,GAAA,GACA,KAAA,QAAA,EACA,KAAA,iBAAA,EAIA,KAAA,eAEA,KAAA,KAAA,OACA,KAAA,iBACA,KAAA,aAAA,OACA,KAAA,cAAA,OAh4BA,GAyCA,GAzCA,EAAA,MAAA,UAAA,QAAA,KAAA,KAAA,MAAA,UAAA,QA0CA,GAAA,KAAA,kBAAA,GAAA,IAAA,UAAA,QACA,EAAA,EAAA,KAEA,EAAA,WACA,KAAA,QACA,KAAA,WAGA,EAAA,WACA,IAAA,SAAA,EAAA,GACA,GAAA,GAAA,KAAA,KAAA,QAAA,EACA,GAAA,GACA,KAAA,KAAA,KAAA,GACA,KAAA,OAAA,KAAA,IAEA,KAAA,OAAA,GAAA,GAIA,IAAA,SAAA,GACA,GAAA,GAAA,KAAA,KAAA,QAAA,EACA,MAAA,EAAA,GAGA,MAAA,MAAA,OAAA,IAGA,SAAA,SAAA,GACA,GAAA,GAAA,KAAA,KAAA,QAAA,EACA,OAAA,GAAA,GACA,GAEA,KAAA,KAAA,OAAA,EAAA,GACA,KAAA,OAAA,OAAA,EAAA,IACA,IAGA,QAAA,SAAA,EAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,KAAA,KAAA,OAAA,IACA,EAAA,KAAA,GAAA,KAAA,KAAA,OAAA,GAAA,KAAA,KAAA,GAAA,QAyBA,mBAAA,UAAA,WACA,SAAA,UAAA,SAAA,SAAA,GACA,MAAA,KAAA,MAAA,EAAA,aAAA,MACA,EACA,KAAA,gBAAA,SAAA,IAIA,IAAA,GAAA,OACA,EAAA,SACA,EAAA,KAEA,GACA,UAAA,EACA,QAAA,EACA,MAAA,EACA,KAAA,GAGA,GACA,OAAA,EACA,OAAA,EACA,OAAA,EACA,IAAA,EACA,IAAA,EACA,IAAA,EACA,UAAA,EACA,KAAA,EACA,SAAA,EACA,QAAA,EACA,UAAA,GAGA,EAAA,mBAAA,oBACA,KAIA,WACA,GAAA,GAAA,SAAA,cAAA,YACA,EAAA,EAAA,QAAA,cACA,EAAA,EAAA,YAAA,EAAA,cAAA,SACA,EAAA,EAAA,YAAA,EAAA,cAAA,SACA,EAAA,EAAA,cAAA,OACA,GAAA,KAAA,SAAA,QACA,EAAA,YAAA,KAIA,IAAA,GAAA,aACA,OAAA,KAAA,GAAA,IAAA,SAAA,GACA,MAAA,GAAA,cAAA,eACA,KAAA,KA2BA,UAAA,iBAAA,mBAAA,WACA,EAAA,UAEA,SAAA,+BACA,GAmBA,IAMA,EAAA,oBAAA,WACA,KAAA,WAAA,wBAIA,IA6GA,GA7GA,EAAA,eA8GA,mBAAA,oBACA,EAAA,GAAA,kBAAA,SAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,OAAA,iBAWA,oBAAA,SAAA,SAAA,EAAA,GACA,GAAA,EAAA,qBACA,OAAA,CAEA,IAAA,GAAA,CACA,GAAA,sBAAA,CAEA,IAAA,GAAA,EAAA,IACA,EACA,EAAA,EACA,GAAA,EACA,GAAA,CAgBA,IAdA,IACA,EAAA,IACA,GAAA,GACA,EAAA,EAAA,GACA,EAAA,sBAAA,EACA,EAAA,EACA,GAAA,GACA,EAAA,KACA,EAAA,EAAA,GACA,EAAA,sBAAA,EACA,EAAA,KAIA,EAAA,CACA,EAAA,EACA,IAAA,GAAA,EAAA,EACA,GAAA,SAAA,EAAA,yBAeA,MAZA,GAGA,EAAA,aAAA,EACA,EACA,EAAA,EACA,EACA,GACA,GACA,EAAA,EAAA,UAGA,GAOA,oBAAA,UAAA,CAEA,IAAA,GAAA,EAAA,oBAAA,YAEA,GACA,IAAA,WACA,MAAA,MAAA,UAEA,YAAA,EACA,cAAA,EAGA,KAGA,oBAAA,UAAA,OAAA,OAAA,EAAA,WAEA,OAAA,eAAA,oBAAA,UAAA,UACA,IA0BA,EAAA,oBAAA,WACA,KAAA,SAAA,EAAA,EAAA,GACA,GAAA,OAAA,EACA,MAAA,SAAA,UAAA,KAAA,KAAA,KAAA,EAAA,EAAA,EAEA,IAAA,GAAA,KACA,EAAA,EAAA,EAAA,EAAA,KAAA,SAAA,GACA,EAAA,aAAA,MAAA,GACA,EAAA,eAKA,OAFA,MAAA,aAAA,MAAA,GACA,KAAA,cACA,EAAA,QAGA,KAAA,OAAA,OACA,KAAA,SAAA,IAAA,IAGA,0BAAA,SAAA,GAIA,MAHA,MAAA,WACA,KAAA,UAAA,YAEA,EAAA,IAAA,EAAA,MAAA,EAAA,QAUA,KAAA,YACA,KAAA,UAAA,GAAA,GAAA,MACA,KAAA,SAAA,KAAA,aACA,KAAA,SAAA,SAAA,KAAA,WAGA,KAAA,UAAA,mBAAA,EAAA,KAAA,QAEA,GACA,EAAA,QAAA,MAAA,YAAA,EACA,iBAAA,SAGA,KAAA,gBAtBA,KAAA,YACA,KAAA,UAAA,QACA,KAAA,UAAA,OACA,KAAA,SAAA,SAAA,UAsBA,eAAA,SAAA,EAAA,EAAA,EACA,GACA,IACA,EAAA,KAAA,aAAA,IAEA,KAAA,cACA,KAAA,YAAA,KAAA,KAAA,QACA,IAAA,GAAA,KAAA,YACA,EAAA,KAAA,WACA,IAAA,EAAA,UAAA,IAGA,EAAA,EAAA,EACA,GAAA,EAAA,oBACA,EAAA,QAAA,EACA,KAAA,YAAA,EAGA,IAAA,GAAA,EAAA,MACA,EAAA,EAAA,wBACA,GAAA,iBAAA,KACA,EAAA,cAAA,CASA,KAAA,GAPA,IACA,UAAA,KACA,SAAA,KACA,MAAA,GAGA,EAAA,EACA,EAAA,EAAA,WAAA,EAAA,EAAA,EAAA,YAAA,CACA,GAAA,GAAA,EAAA,EAAA,EAAA,EACA,EAAA,SAAA,KACA,EACA,EACA,EACA,GAAA,kBAAA,EAOA,MAJA,GAAA,UAAA,EAAA,WACA,EAAA,SAAA,EAAA,UACA,EAAA,iBAAA,OACA,EAAA,cAAA,OACA,GAGA,GAAA,SACA,MAAA,MAAA,QAGA,GAAA,OAAA,GACA,KAAA,OAAA,EACA,EAAA,OAGA,GAAA,mBACA,MAAA,MAAA,WAAA,KAAA,UAAA,KAGA,YAAA,WACA,KAAA,WAAA,KAAA,cAAA,KAAA,KAAA,UAGA,KAAA,YAAA,OACA,KAAA,UAAA,eACA,KAAA,UAAA,wBAGA,MAAA,WACA,KAAA,OAAA,OACA,KAAA,UAAA,OACA,KAAA,UAAA,OACA,KAAA,YAAA,OACA,KAAA,YAEA,KAAA,UAAA,eACA,KAAA,UAAA,QACA,KAAA,UAAA,SAGA,aAAA,SAAA,GACA,KAAA,UAAA,EACA,KAAA,YAAA,OACA,KAAA,YACA,KAAA,UAAA,2BAAA,OACA,KAAA,UAAA,iBAAA,SAIA,aAAA,SAAA,GAIA,QAAA,GAAA,GACA,GAAA,GAAA,GAAA,EAAA,EACA,IAAA,kBAAA,GAGA,MAAA,YACA,MAAA,GAAA,MAAA,EAAA,YATA,MAAA,IAcA,IAAA,EACA,eAAA,EAAA,kBACA,qBAAA,EAAA,wBACA,+BACA,EAAA,uCAOA,GAAA,iBAAA,GACA,GAAA,KAAA,UACA,KAAA,OAAA,wEAIA,MAAA,aAAA,KAAA,aAAA,KAGA,GAAA,QACA,GAAA,GAAA,EAAA,KAAA,KAAA,aAAA,OAIA,IAHA,IACA,EAAA,KAAA,eAEA,EACA,MAAA,KAEA,IAAA,GAAA,EAAA,IACA,OAAA,GAAA,EAAA,KA+PA,OAAA,eAAA,KAAA,UAAA,oBACA,IAAA,WACA,GAAA,GAAA,KAAA,iBACA,OAAA,GAAA,EACA,KAAA,WAAA,KAAA,WAAA,iBAAA,UAkBA,EAAA,WACA,UAAA,WACA,GAAA,GAAA,KAAA,IACA,KACA,EAAA,aAAA,GACA,EAAA,QAAA,QACA,EAAA,WAAA,GACA,EAAA,MAAA,UAIA,mBAAA,SAAA,EAAA,GACA,KAAA,WAEA,IAAA,GAAA,KAAA,QACA,EAAA,KAAA,gBAEA,IAAA,EAAA,GAAA,CAMA,GALA,EAAA,OAAA,EACA,EAAA,UAAA,EAAA,GAAA,YACA,EAAA,QAAA,EAAA,EAAA,EAAA,GAAA,EAAA,GAGA,EAAA,YAAA,EAAA,QAEA,WADA,MAAA,qBAIA,GAAA,WACA,EAAA,QAAA,KAAA,KAAA,oBAAA,MAGA,EAAA,QACA,EAAA,QAAA,EACA,EAAA,QAAA,EAAA,OAAA,YACA,EAAA,MAAA,EAAA,EAAA,EAAA,OAAA,EAAA,KAEA,EAAA,QAAA,EACA,EAAA,QAAA,EAAA,KAAA,YACA,EAAA,MAAA,EAAA,EAAA,EAAA,KAAA,EAAA,IAGA,EAAA,SACA,EAAA,MAAA,KAAA,KAAA,oBAAA,MAEA,KAAA,uBAGA,oBAAA,WACA,GAAA,KAAA,KAAA,MAAA,CACA,GAAA,GAAA,KAAA,KAAA,OAGA,IAFA,KAAA,KAAA,YACA,EAAA,EAAA,mBACA,EAEA,WADA,MAAA,eAKA,GAAA,GAAA,KAAA,KAAA,KACA,MAAA,KAAA,UACA,EAAA,EAAA,kBACA,KAAA,KAAA,SACA,GAAA,GACA,IAAA,GAAA,KAAA,KAAA,SACA,KAAA,KAAA,SACA,MAAA,QAAA,EACA,MAAA,aAAA,EAAA,IAGA,aAAA,SAAA,EAAA,GACA,MAAA,QAAA,KACA,MAEA,IAAA,KAAA,gBAGA,KAAA,YACA,KAAA,aAAA,EACA,IACA,KAAA,cAAA,GAAA,eAAA,KAAA,cACA,KAAA,cAAA,KAAA,KAAA,cAAA,OAGA,KAAA,cAAA,cAAA,iBAAA,KAAA,aACA,KAAA,kBAGA,gBAAA,SAAA,GACA,GAAA,IAAA,EACA,MAAA,MAAA,gBACA,IAAA,GAAA,KAAA,YAAA,EAAA,EACA,IAAA,EAAA,WAAA,KAAA,cACA,KAAA,mBAAA,EACA,MAAA,EAGA,IAAA,GAAA,EAAA,SACA,OAAA,GAGA,EAAA,gBAAA,EAAA,YAAA,OAAA,EAAA,GAFA,GAOA,iBAAA,SAAA,EAAA,EAAA,EACA,GACA,GAAA,GAAA,KAAA,gBAAA,EAAA,GACA,EAAA,CACA,GACA,EAAA,EAAA,WAAA,EACA,IACA,EAAA,EAAA,EAAA,OAAA,IAAA,GAEA,KAAA,YAAA,OAAA,EAAA,EAAA,EAAA,EAAA,EACA,IAAA,GAAA,KAAA,iBAAA,WACA,EAAA,EAAA,WAEA,IAAA,EACA,EAAA,aAAA,EAAA,OACA,IAAA,EACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,aAAA,EAAA,GAAA,IAIA,kBAAA,SAAA,GACA,GAAA,MACA,EAAA,KAAA,gBAAA,EAAA,GACA,EAAA,KAAA,gBAAA,EACA,GAAA,iBAAA,KAAA,YAAA,EAAA,EAAA,GACA,KAAA,YAAA,OAAA,EAAA,EAAA,EAGA,KADA,GAAA,GAAA,KAAA,iBAAA,WACA,IAAA,GAAA,CACA,GAAA,GAAA,EAAA,WACA,IAAA,IACA,EAAA,GAEA,EAAA,YAAA,GACA,EAAA,KAAA,GAGA,MAAA,IAGA,cAAA,SAAA,GAEA,MADA,GAAA,GAAA,EAAA,KAAA,kBACA,kBAAA,GAAA,EAAA,MAGA,cAAA,SAAA,GACA,IAAA,KAAA,QAAA,EAAA,OAAA,CAGA,GAAA,GAAA,KAAA,gBAEA,KAAA,EAAA,WAEA,WADA,MAAA,OAIA,eAAA,aAAA,KAAA,cAAA,KAAA,aACA,EAEA,IAAA,GAAA,EAAA,SACA,UAAA,KAAA,mBACA,KAAA,iBACA,KAAA,cAAA,GAAA,EAAA,uBAGA,SAAA,KAAA,6BACA,KAAA,2BACA,KAAA,cAAA,GACA,EAAA,gCAGA,IAAA,GAAA,GAAA,GACA,EAAA,CACA,GAAA,QAAA,SAAA,GACA,EAAA,QAAA,QAAA,SAAA,GACA,GAAA,GACA,KAAA,kBAAA,EAAA,MAAA,EACA,GAAA,IAAA,EAAA,IACA,MAEA,GAAA,EAAA,YACA,MAEA,EAAA,QAAA,SAAA,GAEA,IADA,GAAA,GAAA,EAAA,MACA,EAAA,EAAA,MAAA,EAAA,WAAA,IAAA,CACA,GAGA,GAHA,EAAA,KAAA,cAAA,GACA,EAAA,OACA,EAAA,EAAA,IAAA,EAEA,IACA,EAAA,OAAA,GACA,EAAA,EAAA,mBAEA,KACA,KAAA,mBACA,EAAA,KAAA,iBAAA,IAEA,SAAA,IACA,EAAA,EAAA,eAAA,EAAA,OAAA,EACA,KAIA,KAAA,iBAAA,EAAA,EAAA,EACA,KAEA,MAEA,EAAA,QAAA,SAAA,GACA,KAAA,sBAAA,EAAA,mBACA,MAEA,KAAA,4BACA,KAAA,qBAAA,KAGA,oBAAA,SAAA,GACA,GAAA,GAAA,KAAA,gBAAA,EAAA,GACA,EAAA,KAAA,gBAAA,EACA,IAAA,IAAA,EAAA,CAOA,GAAA,GAAA,EAAA,YAAA,gBACA,MAAA,2BAAA,EAAA,KAGA,qBAAA,SAAA,GAGA,IAAA,GAFA,GAAA,EACA,EAAA,EACA,EAAA,EAAA,EAAA,EAAA,OAAA,IAAA,CACA,GAAA,GAAA,EAAA,EACA,IAAA,GAAA,EACA,KAAA,EAAA,EAAA,OACA,KAAA,oBAAA,GACA,QAGA,GAAA,EAAA,KAGA,MAAA,EAAA,EAAA,MAAA,EAAA,YACA,KAAA,oBAAA,GACA,GAGA,IAAA,EAAA,WAAA,EAAA,QAAA,OAGA,GAAA,GAAA,EAIA,IADA,GAAA,GAAA,KAAA,YAAA,OAAA,EACA,EAAA,GACA,KAAA,oBAAA,GACA,KAIA,sBAAA,SAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,SAIA,UAAA,WACA,KAAA,gBAGA,KAAA,cAAA,QACA,KAAA,cAAA,SAGA,MAAA,WACA,IAAA,KAAA,OAAA,CAEA,KAAA,WACA,KAAA,GAAA,GAAA,EAAA,EAAA,KAAA,YAAA,OAAA,GAAA,EACA,KAAA,sBAAA,KAAA,YAAA,GAGA,MAAA,YAAA,OAAA,EACA,KAAA,YACA,KAAA,iBAAA,UAAA,OACA,KAAA,QAAA,KAKA,oBAAA,qBAAA,GACA,MCtqCA,SAAA,GACA,YAiEA,SAAA,GAAA,EAAA,GACA,IAAA,EACA,KAAA,IAAA,OAAA,WAAA,GAIA,QAAA,GAAA,GACA,MAAA,IAAA,IAAA,IAAA,EAMA,QAAA,GAAA,GACA,MAAA,MAAA,GACA,IAAA,GACA,KAAA,GACA,KAAA,GACA,MAAA,GACA,GAAA,MAAA,oBAAA,QAAA,OAAA,aAAA,IAAA,EAKA,QAAA,GAAA,GACA,MAAA,MAAA,GAAA,KAAA,GAAA,OAAA,GAAA,OAAA,EAKA,QAAA,GAAA,GACA,MAAA,MAAA,GAAA,KAAA,GACA,GAAA,IAAA,IAAA,GACA,GAAA,IAAA,KAAA,EAGA,QAAA,GAAA,GACA,MAAA,MAAA,GAAA,KAAA,GACA,GAAA,IAAA,IAAA,GACA,GAAA,IAAA,KAAA,GACA,GAAA,IAAA,IAAA,EAKA,QAAA,GAAA,GACA,MAAA,SAAA,EAKA,QAAA,KACA,KAAA,EAAA,GAAA,EAAA,EAAA,WAAA,OACA,EAIA,QAAA,KACA,GAAA,GAAA,CAGA,KADA,EAAA,IACA,EAAA,IACA,EAAA,EAAA,WAAA,GACA,EAAA,OACA,CAMA,OAAA,GAAA,MAAA,EAAA,GAGA,QAAA,KACA,GAAA,GAAA,EAAA,CAoBA,OAlBA,GAAA,EAEA,EAAA,IAKA,EADA,IAAA,EAAA,OACA,EAAA,WACA,EAAA,GACA,EAAA,QACA,SAAA,EACA,EAAA,YACA,SAAA,GAAA,UAAA,EACA,EAAA,eAEA,EAAA,YAIA,KAAA,EACA,MAAA,EACA,OAAA,EAAA,IAOA,QAAA,KACA,GAEA,GAEA,EAJA,EAAA,EACA,EAAA,EAAA,WAAA,GAEA,EAAA,EAAA,EAGA,QAAA,GAGA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,KACA,IAAA,KACA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,IAEA,QADA,GAEA,KAAA,EAAA,WACA,MAAA,OAAA,aAAA,GACA,OAAA,EAAA,GAGA,SAIA,GAHA,EAAA,EAAA,WAAA,EAAA,GAGA,KAAA,EACA,OAAA,GACA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,IACA,IAAA,KAEA,MADA,IAAA,GAEA,KAAA,EAAA,WACA,MAAA,OAAA,aAAA,GAAA,OAAA,aAAA,GACA,OAAA,EAAA,GAGA,KAAA,IACA,IAAA,IAOA,MANA,IAAA,EAGA,KAAA,EAAA,WAAA,MACA,GAGA,KAAA,EAAA,WACA,MAAA,EAAA,MAAA,EAAA,GACA,OAAA,EAAA,KAeA,MAJA,GAAA,EAAA,EAAA,GAIA,IAAA,GAAA,KAAA,QAAA,IAAA,GACA,GAAA,GAEA,KAAA,EAAA,WACA,MAAA,EAAA,EACA,OAAA,EAAA,KAIA,eAAA,QAAA,IAAA,KACA,GAEA,KAAA,EAAA,WACA,MAAA,EACA,OAAA,EAAA,SAIA,MAAA,EAAA,gBAAA,WAIA,QAAA,KACA,GAAA,GAAA,EAAA,CAQA,IANA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,WAAA,KAAA,MAAA,EACA,sEAEA,EAAA,EACA,EAAA,GACA,MAAA,EAAA,CAaA,IAZA,EAAA,EAAA,KACA,EAAA,EAAA,GAIA,MAAA,GAEA,GAAA,EAAA,EAAA,WAAA,KACA,KAAA,EAAA,gBAAA,WAIA,EAAA,EAAA,WAAA,KACA,GAAA,EAAA,IAEA,GAAA,EAAA,GAGA,GAAA,MAAA,EAAA,CAEA,IADA,GAAA,EAAA,KACA,EAAA,EAAA,WAAA,KACA,GAAA,EAAA,IAEA,GAAA,EAAA,GAGA,GAAA,MAAA,GAAA,MAAA,EAOA,GANA,GAAA,EAAA,KAEA,EAAA,EAAA,IACA,MAAA,GAAA,MAAA,KACA,GAAA,EAAA,MAEA,EAAA,EAAA,WAAA,IACA,KAAA,EAAA,EAAA,WAAA,KACA,GAAA,EAAA,SAGA,MAAA,EAAA,gBAAA,UAQA,OAJA,GAAA,EAAA,WAAA,KACA,KAAA,EAAA,gBAAA,YAIA,KAAA,EAAA,eACA,MAAA,WAAA,GACA,OAAA,EAAA,IAMA,QAAA,KACA,GAAA,GAAA,EAAA,EAAA,EAAA,GAAA,GAAA,CASA,KAPA,EAAA,EAAA,GACA,EAAA,MAAA,GAAA,MAAA,EACA,2CAEA,EAAA,IACA,EAEA,EAAA,GAAA,CAGA,GAFA,EAAA,EAAA,KAEA,IAAA,EAAA,CACA,EAAA,EACA,OACA,GAAA,OAAA,EAEA,GADA,EAAA,EAAA,KACA,GAAA,EAAA,EAAA,WAAA,IA0BA,OAAA,GAAA,OAAA,EAAA,MACA,MA1BA,QAAA,GACA,IAAA,IACA,GAAA,IACA,MACA,KAAA,IACA,GAAA,IACA,MACA,KAAA,IACA,GAAA,GACA,MACA,KAAA,IACA,GAAA,IACA,MACA,KAAA,IACA,GAAA,IACA,MACA,KAAA,IACA,GAAA,GACA,MAEA,SACA,GAAA,MAQA,CAAA,GAAA,EAAA,EAAA,WAAA,IACA,KAEA,IAAA,GAQA,MAJA,KAAA,GACA,KAAA,EAAA,gBAAA,YAIA,KAAA,EAAA,cACA,MAAA,EACA,MAAA,EACA,OAAA,EAAA,IAIA,QAAA,GAAA,GACA,MAAA,GAAA,OAAA,EAAA,YACA,EAAA,OAAA,EAAA,SACA,EAAA,OAAA,EAAA,gBACA,EAAA,OAAA,EAAA,YAGA,QAAA,KACA,GAAA,EAIA,OAFA,KAEA,GAAA,GAEA,KAAA,EAAA,IACA,OAAA,EAAA,KAIA,EAAA,EAAA,WAAA,GAGA,KAAA,GAAA,KAAA,GAAA,KAAA,EACA,IAIA,KAAA,GAAA,KAAA,EACA,IAGA,EAAA,GACA,IAKA,KAAA,EACA,EAAA,EAAA,WAAA,EAAA,IACA,IAEA,IAGA,EAAA,GACA,IAGA,KAGA,QAAA,KACA,GAAA,EASA,OAPA,GAAA,EACA,EAAA,EAAA,MAAA,GAEA,EAAA,IAEA,EAAA,EAAA,MAAA,GAEA,EAGA,QAAA,KACA,GAAA,EAEA,GAAA,EACA,EAAA,IACA,EAAA,EAKA,QAAA,GAAA,EAAA,GACA,GAAA,GACA,EAAA,MAAA,UAAA,MAAA,KAAA,UAAA,GACA,EAAA,EAAA,QACA,SACA,SAAA,EAAA,GAEA,MADA,GAAA,EAAA,EAAA,OAAA,sCACA,EAAA,IAOA,MAHA,GAAA,GAAA,OAAA,GACA,EAAA,MAAA,EACA,EAAA,YAAA,EACA,EAKA,QAAA,GAAA,GACA,EAAA,EAAA,EAAA,gBAAA,EAAA,OAMA,QAAA,GAAA,GACA,GAAA,GAAA,KACA,EAAA,OAAA,EAAA,YAAA,EAAA,QAAA,IACA,EAAA,GAMA,QAAA,GAAA,GACA,MAAA,GAAA,OAAA,EAAA,YAAA,EAAA,QAAA,EAKA,QAAA,GAAA,GACA,MAAA,GAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAwBA,QAAA,KACA,GAAA,KAIA,KAFA,EAAA,MAEA,EAAA,MACA,EAAA,MACA,IACA,EAAA,KAAA,QAEA,EAAA,KAAA,MAEA,EAAA,MACA,EAAA,KAOA,OAFA,GAAA,KAEA,EAAA,sBAAA,GAKA,QAAA,KACA,GAAA,EAOA,OALA,KACA,EAAA,IAIA,EAAA,OAAA,EAAA,eAAA,EAAA,OAAA,EAAA,eACA,EAAA,cAAA,GAGA,EAAA,iBAAA,EAAA,OAGA,QAAA,KACA,GAAA,GAAA,CAWA,OATA,GAAA,EACA,KAEA,EAAA,OAAA,EAAA,KAAA,EAAA,OAAA,EAAA,aACA,EAAA,GAGA,EAAA,IACA,EAAA,KACA,EAAA,eAAA,OAAA,EAAA,MAGA,QAAA,KACA,GAAA,KAIA,KAFA,EAAA,MAEA,EAAA,MACA,EAAA,KAAA,KAEA,EAAA,MACA,EAAA,IAMA,OAFA,GAAA,KAEA,EAAA,uBAAA,GAKA,QAAA,KACA,GAAA,EAQA,OANA,GAAA,KAEA,EAAA,KAEA,EAAA,KAEA,EAMA,QAAA,KACA,GAAA,GAAA,EAAA,CAEA,OAAA,GAAA,KACA,KAGA,EAAA,EAAA,KAEA,IAAA,EAAA,WACA,EAAA,EAAA,iBAAA,IAAA,OACA,IAAA,EAAA,eAAA,IAAA,EAAA,eACA,EAAA,EAAA,cAAA,KACA,IAAA,EAAA,QACA,EAAA,UACA,IACA,EAAA,EAAA,wBAEA,IAAA,EAAA,gBACA,EAAA,IACA,EAAA,MAAA,SAAA,EAAA,MACA,EAAA,EAAA,cAAA,IACA,IAAA,EAAA,aACA,EAAA,IACA,EAAA,MAAA,KACA,EAAA,EAAA,cAAA,IACA,EAAA,KACA,EAAA,IACA,EAAA,OACA,EAAA,KAGA,EACA,MAGA,GAAA,MAKA,QAAA,KACA,GAAA,KAIA,IAFA,EAAA,MAEA,EAAA,KACA,KAAA,EAAA,IACA,EAAA,KAAA,OACA,EAAA,OAGA,EAAA,IAMA,OAFA,GAAA,KAEA,EAGA,QAAA,KACA,GAAA,EAQA,OANA,GAAA,IAEA,EAAA,IACA,EAAA,GAGA,EAAA,iBAAA,EAAA,OAGA,QAAA,KAGA,MAFA,GAAA,KAEA,IAGA,QAAA,KACA,GAAA,EAQA,OANA,GAAA,KAEA,EAAA,KAEA,EAAA,KAEA,EAGA,QAAA,KACA,GAAA,GAAA,CAIA,KAFA,EAAA,IAEA,EAAA,MAAA,EAAA,MACA,EAAA,MACA,EAAA,IACA,EAAA,EAAA,uBAAA,IAAA,EAAA,KAEA,EAAA,IACA,EAAA,EAAA,uBAAA,IAAA,EAAA,GAIA,OAAA,GASA,QAAA,KACA,GAAA,GAAA,CAcA,OAZA,GAAA,OAAA,EAAA,YAAA,EAAA,OAAA,EAAA,QACA,EAAA,KACA,EAAA,MAAA,EAAA,MAAA,EAAA,MACA,EAAA,IACA,EAAA,IACA,EAAA,EAAA,sBAAA,EAAA,MAAA,IACA,EAAA,WAAA,EAAA,SAAA,EAAA,UACA,KAAA,EAAA,iBAEA,EAAA,KAGA,EAGA,QAAA,GAAA,GACA,GAAA,GAAA,CAEA,IAAA,EAAA,OAAA,EAAA,YAAA,EAAA,OAAA,EAAA,QACA,MAAA,EAGA,QAAA,EAAA,OACA,IAAA,KACA,EAAA,CACA,MAEA,KAAA,KACA,EAAA,CACA,MAEA,KAAA,KACA,IAAA,KACA,IAAA,MACA,IAAA,MACA,EAAA,CACA,MAEA,KAAA,IACA,IAAA,IACA,IAAA,KACA,IAAA,KACA,IAAA,aACA,EAAA,CACA,MAEA,KAAA,KACA,EAAA,CACA,MAEA,KAAA,IACA,IAAA,IACA,EAAA,CACA,MAEA,KAAA,IACA,IAAA,IACA,IAAA,IACA,EAAA,GAOA,MAAA,GAWA,QAAA,KACA,GAAA,GAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAMA,IAJA,EAAA,IAEA,EAAA,EACA,EAAA,EAAA,GACA,IAAA,EACA,MAAA,EASA,KAPA,EAAA,KAAA,EACA,IAEA,EAAA,IAEA,GAAA,EAAA,EAAA,IAEA,EAAA,EAAA,IAAA,GAAA,CAGA,KAAA,EAAA,OAAA,GAAA,GAAA,EAAA,EAAA,OAAA,GAAA,MACA,EAAA,EAAA,MACA,EAAA,EAAA,MAAA,MACA,EAAA,EAAA,MACA,EAAA,EAAA,uBAAA,EAAA,EAAA,GACA,EAAA,KAAA,EAIA,GAAA,IACA,EAAA,KAAA,EACA,EAAA,KAAA,GACA,EAAA,IACA,EAAA,KAAA,GAMA,IAFA,EAAA,EAAA,OAAA,EACA,EAAA,EAAA,GACA,EAAA,GACA,EAAA,EAAA,uBAAA,EAAA,EAAA,GAAA,MAAA,EAAA,EAAA,GAAA,GACA,GAAA,CAGA,OAAA,GAMA,QAAA,KACA,GAAA,GAAA,EAAA,CAaA,OAXA,GAAA,IAEA,EAAA,OACA,IACA,EAAA,IACA,EAAA,KACA,EAAA,IAEA,EAAA,EAAA,4BAAA,EAAA,EAAA,IAGA,EAaA,QAAA,KACA,GAAA,GAAA,CAUA,OARA,GAAA,IAEA,EAAA,OAAA,EAAA,YACA,EAAA,GAGA,EAAA,EAAA,KAAA,OAEA,EAAA,aAAA,EAAA,MAAA,GAOA,QAAA,KACA,KAAA,EAAA,MACA,IACA,IAqBA,QAAA,KACA,IACA,GAEA,IAAA,GAAA,IACA,KACA,MAAA,EAAA,OAAA,MAAA,EAAA,OACA,EAAA,OAAA,EAAA,WACA,EAAA,IAEA,IACA,OAAA,EAAA,MACA,EAAA,GAEA,EAAA,eAAA,KAKA,EAAA,OAAA,EAAA,KACA,EAAA,GAIA,QAAA,GAAA,GACA,GACA,IAAA,GAAA,IAAA,KACA,GAAA,mBAAA,EAAA,GAGA,QAAA,GAAA,GACA,GAAA,EACA,OAAA,EAAA,QACA,IACA,EAAA,OAAA,EAAA,YACA,EAAA,GACA,EAAA,IAAA,OAGA,GACA,IAAA,GAAA,IACA,KACA,EAAA,mBAAA,EAAA,KAAA,EAAA,GAGA,QAAA,GAAA,EAAA,GAUA,MATA,GAAA,EACA,EAAA,EACA,EAAA,EACA,EAAA,EAAA,OACA,EAAA,KACA,GACA,aAGA,IAn+BA,GAAA,GACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,CAEA,IACA,eAAA,EACA,IAAA,EACA,WAAA,EACA,QAAA,EACA,YAAA,EACA,eAAA,EACA,WAAA,EACA,cAAA,GAGA,KACA,EAAA,EAAA,gBAAA,UACA,EAAA,EAAA,KAAA,QACA,EAAA,EAAA,YAAA,aACA,EAAA,EAAA,SAAA,UACA,EAAA,EAAA,aAAA,OACA,EAAA,EAAA,gBAAA,UACA,EAAA,EAAA,YAAA,aACA,EAAA,EAAA,eAAA,SAEA,GACA,gBAAA,kBACA,iBAAA,mBACA,eAAA,iBACA,sBAAA,wBACA,eAAA,iBACA,oBAAA,sBACA,WAAA,aACA,QAAA,UACA,iBAAA,mBACA,kBAAA,oBACA,iBAAA,mBACA,iBAAA,mBACA,QAAA,UACA,SAAA,WACA,eAAA,iBACA,gBAAA,mBAIA,GACA,gBAAA,sBACA,aAAA,uBACA,cAAA,oCA2qBA,IAAA,IAAA,EAuJA,GAAA,CA6GA,GAAA,SACA,MAAA,IAEA,MC9/BA,SAAA,GACA,YAqBA,SAAA,GAAA,EAAA,EAAA,EAAA,GACA,GAAA,EACA,KAEA,GADA,EAAA,EAAA,GACA,EAAA,aACA,EAAA,WAAA,KAAA,cACA,aAAA,EAAA,SACA,SAAA,GAAA,WAAA,GACA,KAAA,OAAA,4DAEA,MAAA,GAEA,WADA,SAAA,MAAA,8BAAA,EAAA,GAIA,MAAA,UAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,WAAA,EAAA,EAAA,EAOA,OANA,GAAA,YAAA,IACA,EAAA,6BAAA,EAAA,WACA,EAAA,aACA,EAAA,6BAAA,EAAA,aAGA,GAOA,QAAA,GAAA,GACA,GAAA,GAAA,EAAA,EACA,KAAA,EAAA,CACA,GAAA,GAAA,GAAA,EACA,SAAA,MAAA,EAAA,GACA,EAAA,GAAA,GAAA,GACA,EAAA,GAAA,EAEA,MAAA,GAGA,QAAA,GAAA,GACA,KAAA,MAAA,EACA,KAAA,SAAA,OAgBA,QAAA,GAAA,GACA,KAAA,KAAA,EACA,KAAA,KAAA,KAAA,IAAA,GA2BA,QAAA,GAAA,EAAA,EAAA,GAGA,KAAA,GACA,YAAA,IACA,KAAA,IAAA,EAAA,OAAA,QACA,EAAA,IACA,EAAA,GAAA,GAAA,EAAA,QAGA,KAAA,YAAA,kBAAA,IAAA,EAAA,QAEA,KAAA,QAAA,kBAAA,IACA,EAAA,SACA,KAAA,EAEA,KAAA,YACA,KAAA,UACA,KAAA,aACA,YAAA,KACA,YAAA,IAAA,YAAA,IAEA,KAAA,OAAA,KAAA,WAAA,EAAA,EAAA,GACA,KAAA,SAAA,KAAA,EAAA,EAAA,EAAA,GAoEA,QAAA,GAAA,EAAA,GACA,KAAA,KAAA,EACA,KAAA,OACA,KAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,KAAA,KAAA,GAAA,EAAA,EAAA,IA2CA,QAAA,KAAA,KAAA,OAAA,mBA0BA,QAAA,GAAA,GACA,MAAA,kBAAA,GAAA,EAAA,EAAA,UAGA,QAAA,KACA,KAAA,WAAA,KACA,KAAA,WACA,KAAA,QACA,KAAA,YAAA,OACA,KAAA,WAAA,OACA,KAAA,WAAA,OACA,KAAA,aAAA,EA6GA,QAAA,GAAA,GACA,KAAA,OAAA,EAUA,QAAA,GAAA,GAIA,GAHA,KAAA,WAAA,EAAA,WACA,KAAA,WAAA,EAAA,YAEA,EAAA,WACA,KAAA,OAAA,uBAEA,MAAA,WAAA,EAAA,WACA,EAAA,KAAA,YAEA,KAAA,QAAA,EAAA,QACA,KAAA,YAAA,EAAA,YA2DA,QAAA,GAAA,GACA,MAAA,QAAA,GAAA,QAAA,SAAA,SAAA,GACA,MAAA,IAAA,EAAA,gBAIA,QAAA,GAAA,GACA,MAAA,MAAA,EAAA,IACA,MAAA,EAAA,IACA,MAAA,EAAA,GAoBA,QAAA,GAAA,EAAA,GACA,KAAA,EAAA,KACA,OAAA,UAAA,eAAA,KAAA,EAAA,IACA,EAAA,EAAA,EAGA,OAAA,GAGA,QAAA,GAAA,EAAA,GACA,GAAA,GAAA,EAAA,OACA,MAAA,OAEA,IAAA,GAAA,EAAA,OACA,MAAA,GAAA,EAAA,EAAA,GAEA,KAAA,GAAA,GAAA,EAAA,MAAA,GAAA,EAAA,EAAA,OAAA,EAAA,IACA,EAAA,EAAA,EAAA,GAGA,OAAA,GAGA,QAAA,GAAA,EAAA,EAAA,GACA,GAAA,GAAA,EAAA,UAAA,EAGA,OAFA,GAAA,EAAA,IAAA,EAEA,SAAA,EAAA,EAAA,GA2BA,QAAA,KACA,MAAA,MAAA,EAAA,MA3BA,GAAA,GAAA,EAAA,CAuBA,OArBA,GADA,kBAAA,GAAA,oBACA,SAAA,GACA,EAAA,GAAA,EAAA,oBAAA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,OAAA,EAAA,eAEA,UAAA,kBAAA,UAAA,OACA,SAAA,SAGA,SAAA,GACA,EAAA,GAAA,EAAA,aAAA,GACA,EAAA,GAAA,EAAA,EAAA,EAAA,GAEA,EAAA,MAAA,GAAA,EAAA,EAAA,OAAA,EAAA,gBAEA,UAAA,kBAAA,UAAA,OACA,SAAA,SAIA,EAAA,iBAAA,EAAA,GAEA,EAAA,QAQA,KAAA,EACA,eAAA,EACA,MAAA,WACA,EAAA,oBAAA,EAAA,MAMA,QAAA,MApjBA,GA0CA,GAAA,OAAA,OAAA,KAkBA,GAAA,WACA,QAAA,WACA,IAAA,KAAA,SAAA,CACA,GAAA,GAAA,KAAA,KACA,MAAA,SAAA,WACA,MAAA,IAIA,MAAA,MAAA,WASA,EAAA,WACA,QAAA,WACA,IAAA,KAAA,SAAA,CACA,GACA,IADA,KAAA,KACA,KAAA,KACA,MAAA,SAAA,SAAA,EAAA,GAIA,MAHA,IACA,EAAA,QAAA,EAAA,GAEA,EAAA,aAAA,IAIA,MAAA,MAAA,UAGA,SAAA,SAAA,EAAA,GAIA,MAHA,IAAA,KAAA,KAAA,OACA,EAAA,EAAA,EAAA,KAAA,KAAA,IAEA,KAAA,KAAA,aAAA,EAAA,KA8BA,EAAA,WACA,GAAA,YACA,IAAA,KAAA,UAAA,CACA,GAAA,GAAA,KAAA,iBAAA,GACA,KAAA,OAAA,KAAA,KAAA,OAAA,QACA,MAAA,UAAA,KAAA,IAAA,EAAA,IAAA,KAAA,SAAA,MAGA,MAAA,MAAA,WAGA,QAAA,WACA,IAAA,KAAA,SAAA,CACA,GAAA,GAAA,KAAA,MAEA,IAAA,KAAA,WAAA,CACA,GAAA,GAAA,KAAA,QAEA,MAAA,SAAA,SAAA,EAAA,GAIA,MAHA,IACA,EAAA,QAAA,EAAA,GAEA,EAAA,aAAA,QAEA,IAAA,KAAA,mBAAA,GAAA,CACA,GAAA,GAAA,KAAA,IAAA,KAAA,SAAA,KAEA,MAAA,SAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,EAAA,EAKA,OAHA,IACA,EAAA,QAAA,EAAA,GAEA,EAAA,aAAA,QAEA,CAEA,GAAA,GAAA,KAAA,QAEA,MAAA,SAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAIA,OAHA,IACA,EAAA,QAAA,EAAA,GAEA,EAAA,EAAA,GAAA,SAIA,MAAA,MAAA,UAGA,SAAA,SAAA,EAAA,GACA,GAAA,KAAA,WAEA,MADA,MAAA,SAAA,aAAA,EAAA,GACA,CAGA,IAAA,GAAA,KAAA,OAAA,GACA,EAAA,KAAA,mBAAA,GAAA,KAAA,SAAA,KACA,KAAA,SAAA,EACA,OAAA,GAAA,GAAA,IAYA,EAAA,WACA,UAAA,SAAA,EAAA,EAAA,EAAA,EACA,GACA,GAAA,GAAA,EAAA,KAAA,MACA,EAAA,CACA,IAAA,EACA,EAAA,WAGA,IADA,EAAA,EAAA,KAAA,OACA,EAEA,WADA,SAAA,MAAA,uBAAA,KAAA,KAcA,IANA,EACA,EAAA,EAAA,QACA,kBAAA,GAAA,QACA,EAAA,EAAA,OAGA,kBAAA,GAGA,WAFA,SAAA,MAAA,OAAA,EAAA,UAAA,SACA,YAAA,KAAA,KAKA,KAAA,GADA,IAAA,GACA,EAAA,EAAA,EAAA,KAAA,KAAA,OAAA,IACA,EAAA,EAAA,GAAA,EAAA,KAAA,KAAA,IAAA,EAAA,EAGA,OAAA,GAAA,MAAA,EAAA,IAMA,IAAA,IACA,IAAA,SAAA,GAAA,OAAA,GACA,IAAA,SAAA,GAAA,OAAA,GACA,IAAA,SAAA,GAAA,OAAA,IAGA,GACA,IAAA,SAAA,EAAA,GAAA,MAAA,GAAA,GACA,IAAA,SAAA,EAAA,GAAA,MAAA,GAAA,GACA,IAAA,SAAA,EAAA,GAAA,MAAA,GAAA,GACA,IAAA,SAAA,EAAA,GAAA,MAAA,GAAA,GACA,IAAA,SAAA,EAAA,GAAA,MAAA,GAAA,GACA,IAAA,SAAA,EAAA,GAAA,MAAA,GAAA,GACA,IAAA,SAAA,EAAA,GAAA,MAAA,GAAA,GACA,KAAA,SAAA,EAAA,GAAA,MAAA,IAAA,GACA,KAAA,SAAA,EAAA,GAAA,MAAA,IAAA,GACA,KAAA,SAAA,EAAA,GAAA,MAAA,IAAA,GACA,KAAA,SAAA,EAAA,GAAA,MAAA,IAAA,GACA,MAAA,SAAA,EAAA,GAAA,MAAA,KAAA,GACA,MAAA,SAAA,EAAA,GAAA,MAAA,KAAA,GACA,KAAA,SAAA,EAAA,GAAA,MAAA,IAAA,GACA,KAAA,SAAA,EAAA,GAAA,MAAA,IAAA,GAiBA,GAAA,WACA,sBAAA,SAAA,EAAA,GACA,IAAA,EAAA,GACA,KAAA,OAAA,wBAAA,EAIA,OAFA,GAAA,EAAA,GAEA,SAAA,EAAA,GACA,MAAA,GAAA,GAAA,EAAA,EAAA,MAIA,uBAAA,SAAA,EAAA,EAAA,GACA,IAAA,EAAA,GACA,KAAA,OAAA,wBAAA,EAKA,OAHA,GAAA,EAAA,GACA,EAAA,EAAA,GAEA,SAAA,EAAA,GACA,MAAA,GAAA,GAAA,EAAA,EAAA,GACA,EAAA,EAAA,MAIA,4BAAA,SAAA,EAAA,EAAA,GAKA,MAJA,GAAA,EAAA,GACA,EAAA,EAAA,GACA,EAAA,EAAA,GAEA,SAAA,EAAA,GACA,MAAA,GAAA,EAAA,GACA,EAAA,EAAA,GAAA,EAAA,EAAA,KAIA,iBAAA,SAAA,GACA,GAAA,GAAA,GAAA,GAAA,EAEA,OADA,GAAA,KAAA,aACA,GAGA,uBAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,GAAA,GAAA,EAAA,EAAA,EAGA,OAFA,GAAA,cACA,KAAA,aAAA,GACA,GAGA,cAAA,SAAA,GACA,MAAA,IAAA,GAAA,EAAA,QAGA,sBAAA,SAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,EAAA,EAAA,GAEA,OAAA,UAAA,EAAA,GAEA,IAAA,GADA,MACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,KAAA,EAAA,GAAA,EAAA,GACA,OAAA,KAIA,eAAA,SAAA,EAAA,EAAA,GACA,OACA,IAAA,YAAA,GAAA,EAAA,KAAA,EAAA,MACA,MAAA,IAIA,uBAAA,SAAA,GACA,IAAA,GAAA,GAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,GAAA,MAAA,EAAA,EAAA,GAAA,MAEA,OAAA,UAAA,EAAA,GAEA,IAAA,GADA,MACA,EAAA,EAAA,EAAA,EAAA,OAAA,IACA,EAAA,EAAA,GAAA,KAAA,EAAA,GAAA,MAAA,EAAA,EACA,OAAA,KAIA,aAAA,SAAA,EAAA,GACA,KAAA,QAAA,KAAA,GAAA,GAAA,EAAA,KAGA,mBAAA,SAAA,EAAA,GACA,KAAA,WAAA,EACA,KAAA,WAAA,GAGA,mBAAA,SAAA,EAAA,EAAA,GACA,KAAA,WAAA,EACA,KAAA,WAAA,EACA,KAAA,WAAA,GAGA,eAAA,SAAA,GACA,KAAA,WAAA,GAGA,qBAAA,GAOA,EAAA,WACA,KAAA,WAAA,MAAA,MAAA,QACA,eAAA,WAAA,MAAA,MAAA,QACA,QAAA,aACA,MAAA,cAiBA,EAAA,WACA,WAAA,SAAA,EAAA,EAAA,GAQA,QAAA,KACA,EAAA,aACA,EAAA,YAEA,IAAA,GAAA,EAAA,SAAA,EACA,EAAA,YAAA,EAAA,OACA,EAIA,OAHA,GAAA,aACA,EAAA,cAEA,EAGA,QAAA,GAAA,GAEA,MADA,GAAA,SAAA,EAAA,EAAA,GACA,EAtBA,GAAA,EACA,MAAA,MAAA,SAAA,EAAA,OAAA,EAEA,IAAA,GAAA,GAAA,iBACA,MAAA,SAAA,EAAA,EAAA,EACA,IAAA,GAAA,IAoBA,OAAA,IAAA,mBAAA,EAAA,EAAA,GAAA,IAGA,SAAA,SAAA,EAAA,EAAA,GAEA,IAAA,GADA,GAAA,EAAA,KAAA,YAAA,EAAA,GACA,EAAA,EAAA,EAAA,KAAA,QAAA,OAAA,IACA,EAAA,KAAA,QAAA,GAAA,UAAA,GAAA,EAAA,EAAA,EACA,EAGA,OAAA,IAGA,SAAA,SAAA,EAAA,EAAA,GAEA,IADA,GAAA,GAAA,KAAA,QAAA,KAAA,QAAA,OAAA,EACA,IAAA,GACA,EAAA,KAAA,QAAA,GAAA,UAAA,GAAA,EAAA,EACA,EAGA,OAAA,MAAA,WAAA,SACA,KAAA,WAAA,SAAA,EAAA,GADA,QAqBA,IAAA,OAEA,uBACA,qBACA,sBACA,cACA,aACA,kBACA,QAAA,SAAA,GACA,EAAA,EAAA,eAAA,GAGA,IAAA,GAAA,IAAA,KAAA,SAAA,SAAA,IAAA,MAAA,EA2EA,GAAA,WAEA,YAAA,SAAA,GACA,GAAA,KACA,KAAA,GAAA,KAAA,GACA,EAAA,KAAA,EAAA,GAAA,KAAA,EAAA,GAEA,OAAA,GAAA,KAAA,OAGA,UAAA,SAAA,GACA,GAAA,KACA,KAAA,GAAA,KAAA,GACA,EAAA,IACA,EAAA,KAAA,EAEA,OAAA,GAAA,KAAA,MAIA,+BAAA,SAAA,GACA,GAAA,GAAA,EAAA,4BACA,IAAA,EAGA,MAAA,UAAA,EAAA,GACA,EAAA,MAAA,GAAA,IAIA,eAAA,SAAA,EAAA,EAAA,GACA,GAAA,GAAA,KAAA,IAAA,EACA,IAAA,EAAA,GACA,MAAA,GAAA,MAKA,EAAA,EAAA,EAAA,UAJA,SAAA,MAAA,gDAOA,EAAA,IAAA,EAAA,MAcA,MAAA,GAAA,EAAA,EAAA,EAAA,KAbA,IAAA,GAAA,EAAA,OACA,MAAA,UAAA,EAAA,EAAA,GACA,GAAA,EACA,MAAA,GAAA,aAAA,EAEA,IAAA,GAAA,EAAA,EAAA,EAAA,GACA,OAAA,IAAA,cAAA,EAAA,MAUA,qBAAA,SAAA,GACA,GAAA,GAAA,EAAA,4BACA,IAAA,EAAA,CAGA,GAAA,GAAA,EAAA,iBACA,EAAA,iBAAA,MACA,EAAA,MAEA,EAAA,EAAA,4BAEA,OAAA,UAAA,GACA,GAAA,GAAA,OAAA,OAAA,EAIA,OAHA,GAAA,GAAA,EACA,EAAA,GAAA,OACA,EAAA,GAAA,EACA,MAKA,EAAA,mBAAA,EACA,EAAA,sBACA,EAAA,eAAA,GAEA,EAAA,mBAAA,oBAAA,GACA,MC3pBA,SAAA,GAUA,QAAA,KACA,IACA,GAAA,EACA,EAAA,eAAA,WACA,GAAA,EACA,SAAA,MAAA,QAAA,MAAA,oBACA,EAAA,6BACA,SAAA,MAAA,QAAA,cAdA,GAAA,GAAA,SAAA,cAAA,QACA,GAAA,YAAA,oEACA,IAAA,GAAA,SAAA,cAAA,OACA,GAAA,aAAA,EAAA,EAAA,WAGA,IAAA,GAcA,EAAA,GASA,IARA,OAAA,iBAAA,qBAAA,WACA,IAEA,SAAA,mBACA,EAAA,UAAA,YAAA,EAAA,MAIA,OAAA,iBAAA,eAAA,UAAA,CACA,GAAA,GAAA,SAAA,UAAA,UACA,UAAA,UAAA,WAAA,SAAA,EAAA,GACA,GAAA,GAAA,EAAA,KAAA,KAAA,EAAA,EAEA,OADA,gBAAA,WAAA,GACA,GAKA,EAAA,MAAA,GAEA,OAAA","sourcesContent":["/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * PointerGestureEvent is the constructor for all PointerGesture events.\n *\n * @module PointerGestures\n * @class PointerGestureEvent\n * @extends UIEvent\n * @constructor\n * @param {String} inType Event type\n * @param {Object} [inDict] Dictionary of properties to initialize on the event\n */\n\nfunction PointerGestureEvent(inType, inDict) {\n  var dict = inDict || {};\n  var e = document.createEvent('Event');\n  var props = {\n    bubbles: Boolean(dict.bubbles) === dict.bubbles || true,\n    cancelable: Boolean(dict.cancelable) === dict.cancelable || true\n  };\n\n  e.initEvent(inType, props.bubbles, props.cancelable);\n\n  var keys = Object.keys(dict), k;\n  for (var i = 0; i < keys.length; i++) {\n    k = keys[i];\n    e[k] = dict[k];\n  }\n\n  e.preventTap = this.preventTap;\n\n  return e;\n}\n\n/**\n * Allows for any gesture to prevent the tap gesture.\n *\n * @method preventTap\n */\nPointerGestureEvent.prototype.preventTap = function() {\n  this.tapPrevented = true;\n};\n\n","/*\n * Copyright 2012 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nif (typeof WeakMap === 'undefined') {\n  (function() {\n    var defineProperty = Object.defineProperty;\n    var counter = Date.now() % 1e9;\n\n    var WeakMap = function() {\n      this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');\n    };\n\n    WeakMap.prototype = {\n      set: function(key, value) {\n        var entry = key[this.name];\n        if (entry && entry[0] === key)\n          entry[1] = value;\n        else\n          defineProperty(key, this.name, {value: [key, value], writable: true});\n      },\n      get: function(key) {\n        var entry;\n        return (entry = key[this.name]) && entry[0] === key ?\n            entry[1] : undefined;\n      },\n      delete: function(key) {\n        this.set(key, undefined);\n      }\n    };\n\n    window.WeakMap = WeakMap;\n  })();\n}\n","// Copyright 2012 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function(global) {\n  'use strict';\n\n  var PROP_ADD_TYPE = 'add';\n  var PROP_UPDATE_TYPE = 'update';\n  var PROP_RECONFIGURE_TYPE = 'reconfigure';\n  var PROP_DELETE_TYPE = 'delete';\n  var ARRAY_SPLICE_TYPE = 'splice';\n\n  // Detect and do basic sanity checking on Object/Array.observe.\n  function detectObjectObserve() {\n    if (typeof Object.observe !== 'function' ||\n        typeof Array.observe !== 'function') {\n      return false;\n    }\n\n    var records = [];\n\n    function callback(recs) {\n      records = recs;\n    }\n\n    var test = {};\n    Object.observe(test, callback);\n    test.id = 1;\n    test.id = 2;\n    delete test.id;\n    Object.deliverChangeRecords(callback);\n    if (records.length !== 3)\n      return false;\n\n    // TODO(rafaelw): Remove this when new change record type names make it to\n    // chrome release.\n    if (records[0].type == 'new' &&\n        records[1].type == 'updated' &&\n        records[2].type == 'deleted') {\n      PROP_ADD_TYPE = 'new';\n      PROP_UPDATE_TYPE = 'updated';\n      PROP_RECONFIGURE_TYPE = 'reconfigured';\n      PROP_DELETE_TYPE = 'deleted';\n    } else if (records[0].type != 'add' ||\n               records[1].type != 'update' ||\n               records[2].type != 'delete') {\n      console.error('Unexpected change record names for Object.observe. ' +\n                    'Using dirty-checking instead');\n      return false;\n    }\n    Object.unobserve(test, callback);\n\n    test = [0];\n    Array.observe(test, callback);\n    test[1] = 1;\n    test.length = 0;\n    Object.deliverChangeRecords(callback);\n    if (records.length != 2)\n      return false;\n    if (records[0].type != ARRAY_SPLICE_TYPE ||\n        records[1].type != ARRAY_SPLICE_TYPE) {\n      return false;\n    }\n    Array.unobserve(test, callback);\n\n    return true;\n  }\n\n  var hasObserve = detectObjectObserve();\n\n  function detectEval() {\n    // don't test for eval if document has CSP securityPolicy object and we can see that\n    // eval is not supported. This avoids an error message in console even when the exception\n    // is caught\n    if (global.document &&\n        'securityPolicy' in global.document &&\n        !global.document.securityPolicy.allowsEval) {\n      return false;\n    }\n\n    try {\n      var f = new Function('', 'return true;');\n      return f();\n    } catch (ex) {\n      return false;\n    }\n  }\n\n  var hasEval = detectEval();\n\n  function isIndex(s) {\n    return +s === s >>> 0;\n  }\n\n  function toNumber(s) {\n    return +s;\n  }\n\n  function isObject(obj) {\n    return obj === Object(obj);\n  }\n\n  var numberIsNaN = global.Number.isNaN || function isNaN(value) {\n    return typeof value === 'number' && global.isNaN(value);\n  }\n\n  function areSameValue(left, right) {\n    if (left === right)\n      return left !== 0 || 1 / left === 1 / right;\n    if (numberIsNaN(left) && numberIsNaN(right))\n      return true;\n\n    return left !== left && right !== right;\n  }\n\n  var createObject = ('__proto__' in {}) ?\n    function(obj) { return obj; } :\n    function(obj) {\n      var proto = obj.__proto__;\n      if (!proto)\n        return obj;\n      var newObject = Object.create(proto);\n      Object.getOwnPropertyNames(obj).forEach(function(name) {\n        Object.defineProperty(newObject, name,\n                             Object.getOwnPropertyDescriptor(obj, name));\n      });\n      return newObject;\n    };\n\n  var identStart = '[\\$_a-zA-Z]';\n  var identPart = '[\\$_a-zA-Z0-9]';\n  var ident = identStart + '+' + identPart + '*';\n  var elementIndex = '(?:[0-9]|[1-9]+[0-9]+)';\n  var identOrElementIndex = '(?:' + ident + '|' + elementIndex + ')';\n  var path = '(?:' + identOrElementIndex + ')(?:\\\\s*\\\\.\\\\s*' + identOrElementIndex + ')*';\n  var pathRegExp = new RegExp('^' + path + '$');\n\n  function isPathValid(s) {\n    if (typeof s != 'string')\n      return false;\n    s = s.trim();\n\n    if (s == '')\n      return true;\n\n    if (s[0] == '.')\n      return false;\n\n    return pathRegExp.test(s);\n  }\n\n  var constructorIsPrivate = {};\n\n  function Path(s, privateToken) {\n    if (privateToken !== constructorIsPrivate)\n      throw Error('Use Path.get to retrieve path objects');\n\n    if (s.trim() == '')\n      return this;\n\n    if (isIndex(s)) {\n      this.push(s);\n      return this;\n    }\n\n    s.split(/\\s*\\.\\s*/).filter(function(part) {\n      return part;\n    }).forEach(function(part) {\n      this.push(part);\n    }, this);\n\n    if (hasEval && this.length) {\n      this.getValueFrom = this.compiledGetValueFromFn();\n    }\n  }\n\n  // TODO(rafaelw): Make simple LRU cache\n  var pathCache = {};\n\n  function getPath(pathString) {\n    if (pathString instanceof Path)\n      return pathString;\n\n    if (pathString == null)\n      pathString = '';\n\n    if (typeof pathString !== 'string')\n      pathString = String(pathString);\n\n    var path = pathCache[pathString];\n    if (path)\n      return path;\n    if (!isPathValid(pathString))\n      return invalidPath;\n    var path = new Path(pathString, constructorIsPrivate);\n    pathCache[pathString] = path;\n    return path;\n  }\n\n  Path.get = getPath;\n\n  Path.prototype = createObject({\n    __proto__: [],\n    valid: true,\n\n    toString: function() {\n      return this.join('.');\n    },\n\n    getValueFrom: function(obj, directObserver) {\n      for (var i = 0; i < this.length; i++) {\n        if (obj == null)\n          return;\n        obj = obj[this[i]];\n      }\n      return obj;\n    },\n\n    iterateObjects: function(obj, observe) {\n      for (var i = 0; i < this.length; i++) {\n        if (i)\n          obj = obj[this[i - 1]];\n        if (!obj)\n          return;\n        observe(obj);\n      }\n    },\n\n    compiledGetValueFromFn: function() {\n      var accessors = this.map(function(ident) {\n        return isIndex(ident) ? '[\"' + ident + '\"]' : '.' + ident;\n      });\n\n      var str = '';\n      var pathString = 'obj';\n      str += 'if (obj != null';\n      var i = 0;\n      for (; i < (this.length - 1); i++) {\n        var ident = this[i];\n        pathString += accessors[i];\n        str += ' &&\\n     ' + pathString + ' != null';\n      }\n      str += ')\\n';\n\n      pathString += accessors[i];\n\n      str += '  return ' + pathString + ';\\nelse\\n  return undefined;';\n      return new Function('obj', str);\n    },\n\n    setValueFrom: function(obj, value) {\n      if (!this.length)\n        return false;\n\n      for (var i = 0; i < this.length - 1; i++) {\n        if (!isObject(obj))\n          return false;\n        obj = obj[this[i]];\n      }\n\n      if (!isObject(obj))\n        return false;\n\n      obj[this[i]] = value;\n      return true;\n    }\n  });\n\n  var invalidPath = new Path('', constructorIsPrivate);\n  invalidPath.valid = false;\n  invalidPath.getValueFrom = invalidPath.setValueFrom = function() {};\n\n  var MAX_DIRTY_CHECK_CYCLES = 1000;\n\n  function dirtyCheck(observer) {\n    var cycles = 0;\n    while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check_()) {\n      cycles++;\n    }\n    if (global.testingExposeCycleCount)\n      global.dirtyCheckCycleCount = cycles;\n\n    return cycles > 0;\n  }\n\n  function objectIsEmpty(object) {\n    for (var prop in object)\n      return false;\n    return true;\n  }\n\n  function diffIsEmpty(diff) {\n    return objectIsEmpty(diff.added) &&\n           objectIsEmpty(diff.removed) &&\n           objectIsEmpty(diff.changed);\n  }\n\n  function diffObjectFromOldObject(object, oldObject) {\n    var added = {};\n    var removed = {};\n    var changed = {};\n\n    for (var prop in oldObject) {\n      var newValue = object[prop];\n\n      if (newValue !== undefined && newValue === oldObject[prop])\n        continue;\n\n      if (!(prop in object)) {\n        removed[prop] = undefined;\n        continue;\n      }\n\n      if (newValue !== oldObject[prop])\n        changed[prop] = newValue;\n    }\n\n    for (var prop in object) {\n      if (prop in oldObject)\n        continue;\n\n      added[prop] = object[prop];\n    }\n\n    if (Array.isArray(object) && object.length !== oldObject.length)\n      changed.length = object.length;\n\n    return {\n      added: added,\n      removed: removed,\n      changed: changed\n    };\n  }\n\n  var eomTasks = [];\n  function runEOMTasks() {\n    if (!eomTasks.length)\n      return false;\n\n    for (var i = 0; i < eomTasks.length; i++) {\n      eomTasks[i]();\n    }\n    eomTasks.length = 0;\n    return true;\n  }\n\n  var runEOM = hasObserve ? (function(){\n    var eomObj = { pingPong: true };\n    var eomRunScheduled = false;\n\n    Object.observe(eomObj, function() {\n      runEOMTasks();\n      eomRunScheduled = false;\n    });\n\n    return function(fn) {\n      eomTasks.push(fn);\n      if (!eomRunScheduled) {\n        eomRunScheduled = true;\n        eomObj.pingPong = !eomObj.pingPong;\n      }\n    };\n  })() :\n  (function() {\n    return function(fn) {\n      eomTasks.push(fn);\n    };\n  })();\n\n  var observedObjectCache = [];\n\n  function newObservedObject() {\n    var observer;\n    var object;\n    var discardRecords = false;\n    var first = true;\n\n    function callback(records) {\n      if (observer && observer.state_ === OPENED && !discardRecords)\n        observer.check_(records);\n    }\n\n    return {\n      open: function(obs) {\n        if (observer)\n          throw Error('ObservedObject in use');\n\n        if (!first)\n          Object.deliverChangeRecords(callback);\n\n        observer = obs;\n        first = false;\n      },\n      observe: function(obj, arrayObserve) {\n        object = obj;\n        if (arrayObserve)\n          Array.observe(object, callback);\n        else\n          Object.observe(object, callback);\n      },\n      deliver: function(discard) {\n        discardRecords = discard;\n        Object.deliverChangeRecords(callback);\n        discardRecords = false;\n      },\n      close: function() {\n        observer = undefined;\n        Object.unobserve(object, callback);\n        observedObjectCache.push(this);\n      }\n    };\n  }\n\n  function getObservedObject(observer, object, arrayObserve) {\n    var dir = observedObjectCache.pop() || newObservedObject();\n    dir.open(observer);\n    dir.observe(object, arrayObserve);\n    return dir;\n  }\n\n  var emptyArray = [];\n  var observedSetCache = [];\n\n  function newObservedSet() {\n    var observers = [];\n    var observerCount = 0;\n    var objects = [];\n    var toRemove = emptyArray;\n    var resetNeeded = false;\n    var resetScheduled = false;\n\n    function observe(obj) {\n      if (!isObject(obj))\n        return;\n\n      var index = toRemove.indexOf(obj);\n      if (index >= 0) {\n        toRemove[index] = undefined;\n        objects.push(obj);\n      } else if (objects.indexOf(obj) < 0) {\n        objects.push(obj);\n        Object.observe(obj, callback);\n      }\n\n      observe(Object.getPrototypeOf(obj));\n    }\n\n    function reset() {\n      var objs = toRemove === emptyArray ? [] : toRemove;\n      toRemove = objects;\n      objects = objs;\n\n      var observer;\n      for (var id in observers) {\n        observer = observers[id];\n        if (!observer || observer.state_ != OPENED)\n          continue;\n\n        observer.iterateObjects_(observe);\n      }\n\n      for (var i = 0; i < toRemove.length; i++) {\n        var obj = toRemove[i];\n        if (obj)\n          Object.unobserve(obj, callback);\n      }\n\n      toRemove.length = 0;\n    }\n\n    function scheduledReset() {\n      resetScheduled = false;\n      if (!resetNeeded)\n        return;\n\n      reset();\n    }\n\n    function scheduleReset() {\n      if (resetScheduled)\n        return;\n\n      resetNeeded = true;\n      resetScheduled = true;\n      runEOM(scheduledReset);\n    }\n\n    function callback() {\n      reset();\n\n      var observer;\n\n      for (var id in observers) {\n        observer = observers[id];\n        if (!observer || observer.state_ != OPENED)\n          continue;\n\n        observer.check_();\n      }\n    }\n\n    var record = {\n      object: undefined,\n      objects: objects,\n      open: function(obs) {\n        observers[obs.id_] = obs;\n        observerCount++;\n        obs.iterateObjects_(observe);\n      },\n      close: function(obs) {\n        var anyLeft = false;\n\n        observers[obs.id_] = undefined;\n        observerCount--;\n\n        if (observerCount) {\n          scheduleReset();\n          return;\n        }\n        resetNeeded = false;\n\n        for (var i = 0; i < objects.length; i++) {\n          Object.unobserve(objects[i], callback);\n          Observer.unobservedCount++;\n        }\n\n        observers.length = 0;\n        objects.length = 0;\n        observedSetCache.push(this);\n      },\n      reset: scheduleReset\n    };\n\n    return record;\n  }\n\n  var lastObservedSet;\n\n  function getObservedSet(observer, obj) {\n    if (!lastObservedSet || lastObservedSet.object !== obj) {\n      lastObservedSet = observedSetCache.pop() || newObservedSet();\n      lastObservedSet.object = obj;\n    }\n    lastObservedSet.open(observer);\n    return lastObservedSet;\n  }\n\n  var UNOPENED = 0;\n  var OPENED = 1;\n  var CLOSED = 2;\n  var RESETTING = 3;\n\n  var nextObserverId = 1;\n\n  function Observer() {\n    this.state_ = UNOPENED;\n    this.callback_ = undefined;\n    this.target_ = undefined; // TODO(rafaelw): Should be WeakRef\n    this.directObserver_ = undefined;\n    this.value_ = undefined;\n    this.id_ = nextObserverId++;\n  }\n\n  Observer.prototype = {\n    open: function(callback, target) {\n      if (this.state_ != UNOPENED)\n        throw Error('Observer has already been opened.');\n\n      addToAll(this);\n      this.callback_ = callback;\n      this.target_ = target;\n      this.state_ = OPENED;\n      this.connect_();\n      return this.value_;\n    },\n\n    close: function() {\n      if (this.state_ != OPENED)\n        return;\n\n      removeFromAll(this);\n      this.state_ = CLOSED;\n      this.disconnect_();\n      this.value_ = undefined;\n      this.callback_ = undefined;\n      this.target_ = undefined;\n    },\n\n    deliver: function() {\n      if (this.state_ != OPENED)\n        return;\n\n      dirtyCheck(this);\n    },\n\n    report_: function(changes) {\n      try {\n        this.callback_.apply(this.target_, changes);\n      } catch (ex) {\n        Observer._errorThrownDuringCallback = true;\n        console.error('Exception caught during observer callback: ' +\n                       (ex.stack || ex));\n      }\n    },\n\n    discardChanges: function() {\n      this.check_(undefined, true);\n      return this.value_;\n    }\n  }\n\n  var collectObservers = !hasObserve;\n  var allObservers;\n  Observer._allObserversCount = 0;\n\n  if (collectObservers) {\n    allObservers = [];\n  }\n\n  function addToAll(observer) {\n    Observer._allObserversCount++;\n    if (!collectObservers)\n      return;\n\n    allObservers.push(observer);\n  }\n\n  function removeFromAll(observer) {\n    Observer._allObserversCount--;\n  }\n\n  var runningMicrotaskCheckpoint = false;\n\n  var hasDebugForceFullDelivery = typeof Object.deliverAllChangeRecords == 'function';\n\n  global.Platform = global.Platform || {};\n\n  global.Platform.performMicrotaskCheckpoint = function() {\n    if (runningMicrotaskCheckpoint)\n      return;\n\n    if (hasDebugForceFullDelivery) {\n      Object.deliverAllChangeRecords();\n      return;\n    }\n\n    if (!collectObservers)\n      return;\n\n    runningMicrotaskCheckpoint = true;\n\n    var cycles = 0;\n    var anyChanged, toCheck;\n\n    do {\n      cycles++;\n      toCheck = allObservers;\n      allObservers = [];\n      anyChanged = false;\n\n      for (var i = 0; i < toCheck.length; i++) {\n        var observer = toCheck[i];\n        if (observer.state_ != OPENED)\n          continue;\n\n        if (observer.check_())\n          anyChanged = true;\n\n        allObservers.push(observer);\n      }\n      if (runEOMTasks())\n        anyChanged = true;\n    } while (cycles < MAX_DIRTY_CHECK_CYCLES && anyChanged);\n\n    if (global.testingExposeCycleCount)\n      global.dirtyCheckCycleCount = cycles;\n\n    runningMicrotaskCheckpoint = false;\n  };\n\n  if (collectObservers) {\n    global.Platform.clearObservers = function() {\n      allObservers = [];\n    };\n  }\n\n  function ObjectObserver(object) {\n    Observer.call(this);\n    this.value_ = object;\n    this.oldObject_ = undefined;\n  }\n\n  ObjectObserver.prototype = createObject({\n    __proto__: Observer.prototype,\n\n    arrayObserve: false,\n\n    connect_: function(callback, target) {\n      if (hasObserve) {\n        this.directObserver_ = getObservedObject(this, this.value_,\n                                                 this.arrayObserve);\n      } else {\n        this.oldObject_ = this.copyObject(this.value_);\n      }\n\n    },\n\n    copyObject: function(object) {\n      var copy = Array.isArray(object) ? [] : {};\n      for (var prop in object) {\n        copy[prop] = object[prop];\n      };\n      if (Array.isArray(object))\n        copy.length = object.length;\n      return copy;\n    },\n\n    check_: function(changeRecords, skipChanges) {\n      var diff;\n      var oldValues;\n      if (hasObserve) {\n        if (!changeRecords)\n          return false;\n\n        oldValues = {};\n        diff = diffObjectFromChangeRecords(this.value_, changeRecords,\n                                           oldValues);\n      } else {\n        oldValues = this.oldObject_;\n        diff = diffObjectFromOldObject(this.value_, this.oldObject_);\n      }\n\n      if (diffIsEmpty(diff))\n        return false;\n\n      if (!hasObserve)\n        this.oldObject_ = this.copyObject(this.value_);\n\n      this.report_([\n        diff.added || {},\n        diff.removed || {},\n        diff.changed || {},\n        function(property) {\n          return oldValues[property];\n        }\n      ]);\n\n      return true;\n    },\n\n    disconnect_: function() {\n      if (hasObserve) {\n        this.directObserver_.close();\n        this.directObserver_ = undefined;\n      } else {\n        this.oldObject_ = undefined;\n      }\n    },\n\n    deliver: function() {\n      if (this.state_ != OPENED)\n        return;\n\n      if (hasObserve)\n        this.directObserver_.deliver(false);\n      else\n        dirtyCheck(this);\n    },\n\n    discardChanges: function() {\n      if (this.directObserver_)\n        this.directObserver_.deliver(true);\n      else\n        this.oldObject_ = this.copyObject(this.value_);\n\n      return this.value_;\n    }\n  });\n\n  function ArrayObserver(array) {\n    if (!Array.isArray(array))\n      throw Error('Provided object is not an Array');\n    ObjectObserver.call(this, array);\n  }\n\n  ArrayObserver.prototype = createObject({\n\n    __proto__: ObjectObserver.prototype,\n\n    arrayObserve: true,\n\n    copyObject: function(arr) {\n      return arr.slice();\n    },\n\n    check_: function(changeRecords) {\n      var splices;\n      if (hasObserve) {\n        if (!changeRecords)\n          return false;\n        splices = projectArraySplices(this.value_, changeRecords);\n      } else {\n        splices = calcSplices(this.value_, 0, this.value_.length,\n                              this.oldObject_, 0, this.oldObject_.length);\n      }\n\n      if (!splices || !splices.length)\n        return false;\n\n      if (!hasObserve)\n        this.oldObject_ = this.copyObject(this.value_);\n\n      this.report_([splices]);\n      return true;\n    }\n  });\n\n  ArrayObserver.applySplices = function(previous, current, splices) {\n    splices.forEach(function(splice) {\n      var spliceArgs = [splice.index, splice.removed.length];\n      var addIndex = splice.index;\n      while (addIndex < splice.index + splice.addedCount) {\n        spliceArgs.push(current[addIndex]);\n        addIndex++;\n      }\n\n      Array.prototype.splice.apply(previous, spliceArgs);\n    });\n  };\n\n  function PathObserver(object, path) {\n    Observer.call(this);\n\n    this.object_ = object;\n    this.path_ = path instanceof Path ? path : getPath(path);\n    this.directObserver_ = undefined;\n  }\n\n  PathObserver.prototype = createObject({\n    __proto__: Observer.prototype,\n\n    connect_: function() {\n      if (hasObserve)\n        this.directObserver_ = getObservedSet(this, this.object_);\n\n      this.check_(undefined, true);\n    },\n\n    disconnect_: function() {\n      this.value_ = undefined;\n\n      if (this.directObserver_) {\n        this.directObserver_.close(this);\n        this.directObserver_ = undefined;\n      }\n    },\n\n    iterateObjects_: function(observe) {\n      this.path_.iterateObjects(this.object_, observe);\n    },\n\n    check_: function(changeRecords, skipChanges) {\n      var oldValue = this.value_;\n      this.value_ = this.path_.getValueFrom(this.object_);\n      if (skipChanges || areSameValue(this.value_, oldValue))\n        return false;\n\n      this.report_([this.value_, oldValue]);\n      return true;\n    },\n\n    setValue: function(newValue) {\n      if (this.path_)\n        this.path_.setValueFrom(this.object_, newValue);\n    }\n  });\n\n  function CompoundObserver() {\n    Observer.call(this);\n\n    this.value_ = [];\n    this.directObserver_ = undefined;\n    this.observed_ = [];\n  }\n\n  var observerSentinel = {};\n\n  CompoundObserver.prototype = createObject({\n    __proto__: Observer.prototype,\n\n    connect_: function() {\n      this.check_(undefined, true);\n\n      if (!hasObserve)\n        return;\n\n      var object;\n      var needsDirectObserver = false;\n      for (var i = 0; i < this.observed_.length; i += 2) {\n        object = this.observed_[i]\n        if (object !== observerSentinel) {\n          needsDirectObserver = true;\n          break;\n        }\n      }\n\n      if (this.directObserver_) {\n        if (needsDirectObserver) {\n          this.directObserver_.reset();\n          return;\n        }\n        this.directObserver_.close();\n        this.directObserver_ = undefined;\n        return;\n      }\n\n      if (needsDirectObserver)\n        this.directObserver_ = getObservedSet(this, object);\n    },\n\n    closeObservers_: function() {\n      for (var i = 0; i < this.observed_.length; i += 2) {\n        if (this.observed_[i] === observerSentinel)\n          this.observed_[i + 1].close();\n      }\n      this.observed_.length = 0;\n    },\n\n    disconnect_: function() {\n      this.value_ = undefined;\n\n      if (this.directObserver_) {\n        this.directObserver_.close(this);\n        this.directObserver_ = undefined;\n      }\n\n      this.closeObservers_();\n    },\n\n    addPath: function(object, path) {\n      if (this.state_ != UNOPENED && this.state_ != RESETTING)\n        throw Error('Cannot add paths once started.');\n\n      this.observed_.push(object, path instanceof Path ? path : getPath(path));\n    },\n\n    addObserver: function(observer) {\n      if (this.state_ != UNOPENED && this.state_ != RESETTING)\n        throw Error('Cannot add observers once started.');\n\n      observer.open(this.deliver, this);\n      this.observed_.push(observerSentinel, observer);\n    },\n\n    startReset: function() {\n      if (this.state_ != OPENED)\n        throw Error('Can only reset while open');\n\n      this.state_ = RESETTING;\n      this.closeObservers_();\n    },\n\n    finishReset: function() {\n      if (this.state_ != RESETTING)\n        throw Error('Can only finishReset after startReset');\n      this.state_ = OPENED;\n      this.connect_();\n\n      return this.value_;\n    },\n\n    iterateObjects_: function(observe) {\n      var object;\n      for (var i = 0; i < this.observed_.length; i += 2) {\n        object = this.observed_[i]\n        if (object !== observerSentinel)\n          this.observed_[i + 1].iterateObjects(object, observe)\n      }\n    },\n\n    check_: function(changeRecords, skipChanges) {\n      var oldValues;\n      for (var i = 0; i < this.observed_.length; i += 2) {\n        var pathOrObserver = this.observed_[i+1];\n        var object = this.observed_[i];\n        var value = object === observerSentinel ?\n            pathOrObserver.discardChanges() :\n            pathOrObserver.getValueFrom(object)\n\n        if (skipChanges) {\n          this.value_[i / 2] = value;\n          continue;\n        }\n\n        if (areSameValue(value, this.value_[i / 2]))\n          continue;\n\n        oldValues = oldValues || [];\n        oldValues[i / 2] = this.value_[i / 2];\n        this.value_[i / 2] = value;\n      }\n\n      if (!oldValues)\n        return false;\n\n      // TODO(rafaelw): Having observed_ as the third callback arg here is\n      // pretty lame API. Fix.\n      this.report_([this.value_, oldValues, this.observed_]);\n      return true;\n    }\n  });\n\n  function identFn(value) { return value; }\n\n  function ObserverTransform(observable, getValueFn, setValueFn,\n                             dontPassThroughSet) {\n    this.callback_ = undefined;\n    this.target_ = undefined;\n    this.value_ = undefined;\n    this.observable_ = observable;\n    this.getValueFn_ = getValueFn || identFn;\n    this.setValueFn_ = setValueFn || identFn;\n    // TODO(rafaelw): This is a temporary hack. PolymerExpressions needs this\n    // at the moment because of a bug in it's dependency tracking.\n    this.dontPassThroughSet_ = dontPassThroughSet;\n  }\n\n  ObserverTransform.prototype = {\n    open: function(callback, target) {\n      this.callback_ = callback;\n      this.target_ = target;\n      this.value_ =\n          this.getValueFn_(this.observable_.open(this.observedCallback_, this));\n      return this.value_;\n    },\n\n    observedCallback_: function(value) {\n      value = this.getValueFn_(value);\n      if (areSameValue(value, this.value_))\n        return;\n      var oldValue = this.value_;\n      this.value_ = value;\n      this.callback_.call(this.target_, this.value_, oldValue);\n    },\n\n    discardChanges: function() {\n      this.value_ = this.getValueFn_(this.observable_.discardChanges());\n      return this.value_;\n    },\n\n    deliver: function() {\n      return this.observable_.deliver();\n    },\n\n    setValue: function(value) {\n      value = this.setValueFn_(value);\n      if (!this.dontPassThroughSet_ && this.observable_.setValue)\n        return this.observable_.setValue(value);\n    },\n\n    close: function() {\n      if (this.observable_)\n        this.observable_.close();\n      this.callback_ = undefined;\n      this.target_ = undefined;\n      this.observable_ = undefined;\n      this.value_ = undefined;\n      this.getValueFn_ = undefined;\n      this.setValueFn_ = undefined;\n    }\n  }\n\n  var expectedRecordTypes = {};\n  expectedRecordTypes[PROP_ADD_TYPE] = true;\n  expectedRecordTypes[PROP_UPDATE_TYPE] = true;\n  expectedRecordTypes[PROP_DELETE_TYPE] = true;\n\n  function notifyFunction(object, name) {\n    if (typeof Object.observe !== 'function')\n      return;\n\n    var notifier = Object.getNotifier(object);\n    return function(type, oldValue) {\n      var changeRecord = {\n        object: object,\n        type: type,\n        name: name\n      };\n      if (arguments.length === 2)\n        changeRecord.oldValue = oldValue;\n      notifier.notify(changeRecord);\n    }\n  }\n\n  Observer.defineComputedProperty = function(target, name, observable) {\n    var notify = notifyFunction(target, name);\n    var value = observable.open(function(newValue, oldValue) {\n      value = newValue;\n      if (notify)\n        notify(PROP_UPDATE_TYPE, oldValue);\n    });\n\n    Object.defineProperty(target, name, {\n      get: function() {\n        observable.deliver();\n        return value;\n      },\n      set: function(newValue) {\n        observable.setValue(newValue);\n        return newValue;\n      },\n      configurable: true\n    });\n\n    return {\n      close: function() {\n        observable.close();\n        Object.defineProperty(target, name, {\n          value: value,\n          writable: true,\n          configurable: true\n        });\n      }\n    };\n  }\n\n  function diffObjectFromChangeRecords(object, changeRecords, oldValues) {\n    var added = {};\n    var removed = {};\n\n    for (var i = 0; i < changeRecords.length; i++) {\n      var record = changeRecords[i];\n      if (!expectedRecordTypes[record.type]) {\n        console.error('Unknown changeRecord type: ' + record.type);\n        console.error(record);\n        continue;\n      }\n\n      if (!(record.name in oldValues))\n        oldValues[record.name] = record.oldValue;\n\n      if (record.type == PROP_UPDATE_TYPE)\n        continue;\n\n      if (record.type == PROP_ADD_TYPE) {\n        if (record.name in removed)\n          delete removed[record.name];\n        else\n          added[record.name] = true;\n\n        continue;\n      }\n\n      // type = 'delete'\n      if (record.name in added) {\n        delete added[record.name];\n        delete oldValues[record.name];\n      } else {\n        removed[record.name] = true;\n      }\n    }\n\n    for (var prop in added)\n      added[prop] = object[prop];\n\n    for (var prop in removed)\n      removed[prop] = undefined;\n\n    var changed = {};\n    for (var prop in oldValues) {\n      if (prop in added || prop in removed)\n        continue;\n\n      var newValue = object[prop];\n      if (oldValues[prop] !== newValue)\n        changed[prop] = newValue;\n    }\n\n    return {\n      added: added,\n      removed: removed,\n      changed: changed\n    };\n  }\n\n  function newSplice(index, removed, addedCount) {\n    return {\n      index: index,\n      removed: removed,\n      addedCount: addedCount\n    };\n  }\n\n  var EDIT_LEAVE = 0;\n  var EDIT_UPDATE = 1;\n  var EDIT_ADD = 2;\n  var EDIT_DELETE = 3;\n\n  function ArraySplice() {}\n\n  ArraySplice.prototype = {\n\n    // Note: This function is *based* on the computation of the Levenshtein\n    // \"edit\" distance. The one change is that \"updates\" are treated as two\n    // edits - not one. With Array splices, an update is really a delete\n    // followed by an add. By retaining this, we optimize for \"keeping\" the\n    // maximum array items in the original array. For example:\n    //\n    //   'xxxx123' -> '123yyyy'\n    //\n    // With 1-edit updates, the shortest path would be just to update all seven\n    // characters. With 2-edit updates, we delete 4, leave 3, and add 4. This\n    // leaves the substring '123' intact.\n    calcEditDistances: function(current, currentStart, currentEnd,\n                                old, oldStart, oldEnd) {\n      // \"Deletion\" columns\n      var rowCount = oldEnd - oldStart + 1;\n      var columnCount = currentEnd - currentStart + 1;\n      var distances = new Array(rowCount);\n\n      // \"Addition\" rows. Initialize null column.\n      for (var i = 0; i < rowCount; i++) {\n        distances[i] = new Array(columnCount);\n        distances[i][0] = i;\n      }\n\n      // Initialize null row\n      for (var j = 0; j < columnCount; j++)\n        distances[0][j] = j;\n\n      for (var i = 1; i < rowCount; i++) {\n        for (var j = 1; j < columnCount; j++) {\n          if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1]))\n            distances[i][j] = distances[i - 1][j - 1];\n          else {\n            var north = distances[i - 1][j] + 1;\n            var west = distances[i][j - 1] + 1;\n            distances[i][j] = north < west ? north : west;\n          }\n        }\n      }\n\n      return distances;\n    },\n\n    // This starts at the final weight, and walks \"backward\" by finding\n    // the minimum previous weight recursively until the origin of the weight\n    // matrix.\n    spliceOperationsFromEditDistances: function(distances) {\n      var i = distances.length - 1;\n      var j = distances[0].length - 1;\n      var current = distances[i][j];\n      var edits = [];\n      while (i > 0 || j > 0) {\n        if (i == 0) {\n          edits.push(EDIT_ADD);\n          j--;\n          continue;\n        }\n        if (j == 0) {\n          edits.push(EDIT_DELETE);\n          i--;\n          continue;\n        }\n        var northWest = distances[i - 1][j - 1];\n        var west = distances[i - 1][j];\n        var north = distances[i][j - 1];\n\n        var min;\n        if (west < north)\n          min = west < northWest ? west : northWest;\n        else\n          min = north < northWest ? north : northWest;\n\n        if (min == northWest) {\n          if (northWest == current) {\n            edits.push(EDIT_LEAVE);\n          } else {\n            edits.push(EDIT_UPDATE);\n            current = northWest;\n          }\n          i--;\n          j--;\n        } else if (min == west) {\n          edits.push(EDIT_DELETE);\n          i--;\n          current = west;\n        } else {\n          edits.push(EDIT_ADD);\n          j--;\n          current = north;\n        }\n      }\n\n      edits.reverse();\n      return edits;\n    },\n\n    /**\n     * Splice Projection functions:\n     *\n     * A splice map is a representation of how a previous array of items\n     * was transformed into a new array of items. Conceptually it is a list of\n     * tuples of\n     *\n     *   <index, removed, addedCount>\n     *\n     * which are kept in ascending index order of. The tuple represents that at\n     * the |index|, |removed| sequence of items were removed, and counting forward\n     * from |index|, |addedCount| items were added.\n     */\n\n    /**\n     * Lacking individual splice mutation information, the minimal set of\n     * splices can be synthesized given the previous state and final state of an\n     * array. The basic approach is to calculate the edit distance matrix and\n     * choose the shortest path through it.\n     *\n     * Complexity: O(l * p)\n     *   l: The length of the current array\n     *   p: The length of the old array\n     */\n    calcSplices: function(current, currentStart, currentEnd,\n                          old, oldStart, oldEnd) {\n      var prefixCount = 0;\n      var suffixCount = 0;\n\n      var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);\n      if (currentStart == 0 && oldStart == 0)\n        prefixCount = this.sharedPrefix(current, old, minLength);\n\n      if (currentEnd == current.length && oldEnd == old.length)\n        suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);\n\n      currentStart += prefixCount;\n      oldStart += prefixCount;\n      currentEnd -= suffixCount;\n      oldEnd -= suffixCount;\n\n      if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0)\n        return [];\n\n      if (currentStart == currentEnd) {\n        var splice = newSplice(currentStart, [], 0);\n        while (oldStart < oldEnd)\n          splice.removed.push(old[oldStart++]);\n\n        return [ splice ];\n      } else if (oldStart == oldEnd)\n        return [ newSplice(currentStart, [], currentEnd - currentStart) ];\n\n      var ops = this.spliceOperationsFromEditDistances(\n          this.calcEditDistances(current, currentStart, currentEnd,\n                                 old, oldStart, oldEnd));\n\n      var splice = undefined;\n      var splices = [];\n      var index = currentStart;\n      var oldIndex = oldStart;\n      for (var i = 0; i < ops.length; i++) {\n        switch(ops[i]) {\n          case EDIT_LEAVE:\n            if (splice) {\n              splices.push(splice);\n              splice = undefined;\n            }\n\n            index++;\n            oldIndex++;\n            break;\n          case EDIT_UPDATE:\n            if (!splice)\n              splice = newSplice(index, [], 0);\n\n            splice.addedCount++;\n            index++;\n\n            splice.removed.push(old[oldIndex]);\n            oldIndex++;\n            break;\n          case EDIT_ADD:\n            if (!splice)\n              splice = newSplice(index, [], 0);\n\n            splice.addedCount++;\n            index++;\n            break;\n          case EDIT_DELETE:\n            if (!splice)\n              splice = newSplice(index, [], 0);\n\n            splice.removed.push(old[oldIndex]);\n            oldIndex++;\n            break;\n        }\n      }\n\n      if (splice) {\n        splices.push(splice);\n      }\n      return splices;\n    },\n\n    sharedPrefix: function(current, old, searchLength) {\n      for (var i = 0; i < searchLength; i++)\n        if (!this.equals(current[i], old[i]))\n          return i;\n      return searchLength;\n    },\n\n    sharedSuffix: function(current, old, searchLength) {\n      var index1 = current.length;\n      var index2 = old.length;\n      var count = 0;\n      while (count < searchLength && this.equals(current[--index1], old[--index2]))\n        count++;\n\n      return count;\n    },\n\n    calculateSplices: function(current, previous) {\n      return this.calcSplices(current, 0, current.length, previous, 0,\n                              previous.length);\n    },\n\n    equals: function(currentValue, previousValue) {\n      return currentValue === previousValue;\n    }\n  };\n\n  var arraySplice = new ArraySplice();\n\n  function calcSplices(current, currentStart, currentEnd,\n                       old, oldStart, oldEnd) {\n    return arraySplice.calcSplices(current, currentStart, currentEnd,\n                                   old, oldStart, oldEnd);\n  }\n\n  function intersect(start1, end1, start2, end2) {\n    // Disjoint\n    if (end1 < start2 || end2 < start1)\n      return -1;\n\n    // Adjacent\n    if (end1 == start2 || end2 == start1)\n      return 0;\n\n    // Non-zero intersect, span1 first\n    if (start1 < start2) {\n      if (end1 < end2)\n        return end1 - start2; // Overlap\n      else\n        return end2 - start2; // Contained\n    } else {\n      // Non-zero intersect, span2 first\n      if (end2 < end1)\n        return end2 - start1; // Overlap\n      else\n        return end1 - start1; // Contained\n    }\n  }\n\n  function mergeSplice(splices, index, removed, addedCount) {\n\n    var splice = newSplice(index, removed, addedCount);\n\n    var inserted = false;\n    var insertionOffset = 0;\n\n    for (var i = 0; i < splices.length; i++) {\n      var current = splices[i];\n      current.index += insertionOffset;\n\n      if (inserted)\n        continue;\n\n      var intersectCount = intersect(splice.index,\n                                     splice.index + splice.removed.length,\n                                     current.index,\n                                     current.index + current.addedCount);\n\n      if (intersectCount >= 0) {\n        // Merge the two splices\n\n        splices.splice(i, 1);\n        i--;\n\n        insertionOffset -= current.addedCount - current.removed.length;\n\n        splice.addedCount += current.addedCount - intersectCount;\n        var deleteCount = splice.removed.length +\n                          current.removed.length - intersectCount;\n\n        if (!splice.addedCount && !deleteCount) {\n          // merged splice is a noop. discard.\n          inserted = true;\n        } else {\n          var removed = current.removed;\n\n          if (splice.index < current.index) {\n            // some prefix of splice.removed is prepended to current.removed.\n            var prepend = splice.removed.slice(0, current.index - splice.index);\n            Array.prototype.push.apply(prepend, removed);\n            removed = prepend;\n          }\n\n          if (splice.index + splice.removed.length > current.index + current.addedCount) {\n            // some suffix of splice.removed is appended to current.removed.\n            var append = splice.removed.slice(current.index + current.addedCount - splice.index);\n            Array.prototype.push.apply(removed, append);\n          }\n\n          splice.removed = removed;\n          if (current.index < splice.index) {\n            splice.index = current.index;\n          }\n        }\n      } else if (splice.index < current.index) {\n        // Insert splice here.\n\n        inserted = true;\n\n        splices.splice(i, 0, splice);\n        i++;\n\n        var offset = splice.addedCount - splice.removed.length\n        current.index += offset;\n        insertionOffset += offset;\n      }\n    }\n\n    if (!inserted)\n      splices.push(splice);\n  }\n\n  function createInitialSplices(array, changeRecords) {\n    var splices = [];\n\n    for (var i = 0; i < changeRecords.length; i++) {\n      var record = changeRecords[i];\n      switch(record.type) {\n        case ARRAY_SPLICE_TYPE:\n          mergeSplice(splices, record.index, record.removed.slice(), record.addedCount);\n          break;\n        case PROP_ADD_TYPE:\n        case PROP_UPDATE_TYPE:\n        case PROP_DELETE_TYPE:\n          if (!isIndex(record.name))\n            continue;\n          var index = toNumber(record.name);\n          if (index < 0)\n            continue;\n          mergeSplice(splices, index, [record.oldValue], 1);\n          break;\n        default:\n          console.error('Unexpected record type: ' + JSON.stringify(record));\n          break;\n      }\n    }\n\n    return splices;\n  }\n\n  function projectArraySplices(array, changeRecords) {\n    var splices = [];\n\n    createInitialSplices(array, changeRecords).forEach(function(splice) {\n      if (splice.addedCount == 1 && splice.removed.length == 1) {\n        if (splice.removed[0] !== array[splice.index])\n          splices.push(splice);\n\n        return\n      };\n\n      splices = splices.concat(calcSplices(array, splice.index, splice.index + splice.addedCount,\n                                           splice.removed, 0, splice.removed.length));\n    });\n\n    return splices;\n  }\n\n  global.Observer = Observer;\n  global.Observer.runEOM_ = runEOM;\n  global.Observer.hasObjectObserve = hasObserve;\n  global.ArrayObserver = ArrayObserver;\n  global.ArrayObserver.calculateSplices = function(current, previous) {\n    return arraySplice.calculateSplices(current, previous);\n  };\n\n  global.ArraySplice = ArraySplice;\n  global.ObjectObserver = ObjectObserver;\n  global.PathObserver = PathObserver;\n  global.CompoundObserver = CompoundObserver;\n  global.Path = Path;\n  global.ObserverTransform = ObserverTransform;\n\n  // TODO(rafaelw): Only needed for testing until new change record names\n  // make it to release.\n  global.Observer.changeRecordTypes = {\n    add: PROP_ADD_TYPE,\n    update: PROP_UPDATE_TYPE,\n    reconfigure: PROP_RECONFIGURE_TYPE,\n    'delete': PROP_DELETE_TYPE,\n    splice: ARRAY_SPLICE_TYPE\n  };\n})(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);\n","// prepoulate window.Platform.flags for default controls\r\nwindow.Platform = window.Platform || {};\r\n// prepopulate window.logFlags if necessary\r\nwindow.logFlags = window.logFlags || {};\r\n// process flags\r\n(function(scope){\r\n  // import\r\n  var flags = scope.flags || {};\r\n  // populate flags from location\r\n  location.search.slice(1).split('&').forEach(function(o) {\r\n    o = o.split('=');\r\n    o[0] && (flags[o[0]] = o[1] || true);\r\n  });\r\n  var entryPoint = document.currentScript || document.querySelector('script[src*=\"platform.js\"]');\r\n  if (entryPoint) {\r\n    var a = entryPoint.attributes;\r\n    for (var i = 0, n; i < a.length; i++) {\r\n      n = a[i];\r\n      if (n.name !== 'src') {\r\n        flags[n.name] = n.value || true;\r\n      }\r\n    }\r\n  }\r\n  if (flags.log) {\r\n    flags.log.split(',').forEach(function(f) {\r\n      window.logFlags[f] = true;\r\n    });\r\n  }\r\n  // If any of these flags match 'native', then force native ShadowDOM; any\r\n  // other truthy value, or failure to detect native\r\n  // ShadowDOM, results in polyfill\r\n  flags.shadow = (flags.shadow || flags.shadowdom || flags.polyfill);\r\n  if (flags.shadow === 'native') {\r\n    flags.shadow = false;\r\n  } else {\r\n    flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;\r\n  }\r\n\r\n  // CustomElements polyfill flag\r\n  if (flags.register) {\r\n    window.CustomElements = window.CustomElements || {flags: {}};\r\n    window.CustomElements.flags.register = flags.register;\r\n  }\r\n\r\n  if (flags.imports) {\r\n    window.HTMLImports = window.HTMLImports || {flags: {}};\r\n    window.HTMLImports.flags.imports = flags.imports;\r\n  }\r\n\r\n  // export\r\n  scope.flags = flags;\r\n})(Platform);\r\n\r\n// select ShadowDOM impl\r\nif (Platform.flags.shadow) {\r\n","// Copyright 2012 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\nwindow.ShadowDOMPolyfill = {};\n\n(function(scope) {\n  'use strict';\n\n  var constructorTable = new WeakMap();\n  var nativePrototypeTable = new WeakMap();\n  var wrappers = Object.create(null);\n\n  // Don't test for eval if document has CSP securityPolicy object and we can\n  // see that eval is not supported. This avoids an error message in console\n  // even when the exception is caught\n  var hasEval = !('securityPolicy' in document) ||\n      document.securityPolicy.allowsEval;\n  if (hasEval) {\n    try {\n      var f = new Function('', 'return true;');\n      hasEval = f();\n    } catch (ex) {\n      hasEval = false;\n    }\n  }\n\n  function assert(b) {\n    if (!b)\n      throw new Error('Assertion failed');\n  };\n\n  var defineProperty = Object.defineProperty;\n  var getOwnPropertyNames = Object.getOwnPropertyNames;\n  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n  function mixin(to, from) {\n    getOwnPropertyNames(from).forEach(function(name) {\n      defineProperty(to, name, getOwnPropertyDescriptor(from, name));\n    });\n    return to;\n  };\n\n  function mixinStatics(to, from) {\n    getOwnPropertyNames(from).forEach(function(name) {\n      switch (name) {\n        case 'arguments':\n        case 'caller':\n        case 'length':\n        case 'name':\n        case 'prototype':\n        case 'toString':\n          return;\n      }\n      defineProperty(to, name, getOwnPropertyDescriptor(from, name));\n    });\n    return to;\n  };\n\n  function oneOf(object, propertyNames) {\n    for (var i = 0; i < propertyNames.length; i++) {\n      if (propertyNames[i] in object)\n        return propertyNames[i];\n    }\n  }\n\n  // Mozilla's old DOM bindings are bretty busted:\n  // https://bugzilla.mozilla.org/show_bug.cgi?id=855844\n  // Make sure they are create before we start modifying things.\n  getOwnPropertyNames(window);\n\n  function getWrapperConstructor(node) {\n    var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);\n    var wrapperConstructor = constructorTable.get(nativePrototype);\n    if (wrapperConstructor)\n      return wrapperConstructor;\n\n    var parentWrapperConstructor = getWrapperConstructor(nativePrototype);\n\n    var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);\n    registerInternal(nativePrototype, GeneratedWrapper, node);\n\n    return GeneratedWrapper;\n  }\n\n  function addForwardingProperties(nativePrototype, wrapperPrototype) {\n    installProperty(nativePrototype, wrapperPrototype, true);\n  }\n\n  function registerInstanceProperties(wrapperPrototype, instanceObject) {\n    installProperty(instanceObject, wrapperPrototype, false);\n  }\n\n  var isFirefox = /Firefox/.test(navigator.userAgent);\n\n  // This is used as a fallback when getting the descriptor fails in\n  // installProperty.\n  var dummyDescriptor = {\n    get: function() {},\n    set: function(v) {},\n    configurable: true,\n    enumerable: true\n  };\n\n  function isEventHandlerName(name) {\n    return /^on[a-z]+$/.test(name);\n  }\n\n  function isIdentifierName(name) {\n    return /^\\w[a-zA-Z_0-9]*$/.test(name);\n  }\n\n  function getGetter(name) {\n    return hasEval && isIdentifierName(name) ?\n        new Function('return this.impl.' + name) :\n        function() { return this.impl[name]; };\n  }\n\n  function getSetter(name) {\n    return hasEval && isIdentifierName(name) ?\n        new Function('v', 'this.impl.' + name + ' = v') :\n        function(v) { this.impl[name] = v; };\n  }\n\n  function getMethod(name) {\n    return hasEval && isIdentifierName(name) ?\n        new Function('return this.impl.' + name +\n                     '.apply(this.impl, arguments)') :\n        function() { return this.impl[name].apply(this.impl, arguments); };\n  }\n\n  function getDescriptor(source, name) {\n    try {\n      return Object.getOwnPropertyDescriptor(source, name);\n    } catch (ex) {\n      // JSC and V8 both use data properties instead of accessors which can\n      // cause getting the property desciptor to throw an exception.\n      // https://bugs.webkit.org/show_bug.cgi?id=49739\n      return dummyDescriptor;\n    }\n  }\n\n  function installProperty(source, target, allowMethod, opt_blacklist) {\n    var names = getOwnPropertyNames(source);\n    for (var i = 0; i < names.length; i++) {\n      var name = names[i];\n      if (name === 'polymerBlackList_')\n        continue;\n\n      if (name in target)\n        continue;\n\n      if (source.polymerBlackList_ && source.polymerBlackList_[name])\n        continue;\n\n      if (isFirefox) {\n        // Tickle Firefox's old bindings.\n        source.__lookupGetter__(name);\n      }\n      var descriptor = getDescriptor(source, name);\n      var getter, setter;\n      if (allowMethod && typeof descriptor.value === 'function') {\n        target[name] = getMethod(name);\n        continue;\n      }\n\n      var isEvent = isEventHandlerName(name);\n      if (isEvent)\n        getter = scope.getEventHandlerGetter(name);\n      else\n        getter = getGetter(name);\n\n      if (descriptor.writable || descriptor.set) {\n        if (isEvent)\n          setter = scope.getEventHandlerSetter(name);\n        else\n          setter = getSetter(name);\n      }\n\n      defineProperty(target, name, {\n        get: getter,\n        set: setter,\n        configurable: descriptor.configurable,\n        enumerable: descriptor.enumerable\n      });\n    }\n  }\n\n  /**\n   * @param {Function} nativeConstructor\n   * @param {Function} wrapperConstructor\n   * @param {Object=} opt_instance If present, this is used to extract\n   *     properties from an instance object.\n   */\n  function register(nativeConstructor, wrapperConstructor, opt_instance) {\n    var nativePrototype = nativeConstructor.prototype;\n    registerInternal(nativePrototype, wrapperConstructor, opt_instance);\n    mixinStatics(wrapperConstructor, nativeConstructor);\n  }\n\n  function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {\n    var wrapperPrototype = wrapperConstructor.prototype;\n    assert(constructorTable.get(nativePrototype) === undefined);\n\n    constructorTable.set(nativePrototype, wrapperConstructor);\n    nativePrototypeTable.set(wrapperPrototype, nativePrototype);\n\n    addForwardingProperties(nativePrototype, wrapperPrototype);\n    if (opt_instance)\n      registerInstanceProperties(wrapperPrototype, opt_instance);\n    defineProperty(wrapperPrototype, 'constructor', {\n      value: wrapperConstructor,\n      configurable: true,\n      enumerable: false,\n      writable: true\n    });\n    // Set it again. Some VMs optimizes objects that are used as prototypes.\n    wrapperConstructor.prototype = wrapperPrototype;\n  }\n\n  function isWrapperFor(wrapperConstructor, nativeConstructor) {\n    return constructorTable.get(nativeConstructor.prototype) ===\n        wrapperConstructor;\n  }\n\n  /**\n   * Creates a generic wrapper constructor based on |object| and its\n   * constructor.\n   * @param {Node} object\n   * @return {Function} The generated constructor.\n   */\n  function registerObject(object) {\n    var nativePrototype = Object.getPrototypeOf(object);\n\n    var superWrapperConstructor = getWrapperConstructor(nativePrototype);\n    var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);\n    registerInternal(nativePrototype, GeneratedWrapper, object);\n\n    return GeneratedWrapper;\n  }\n\n  function createWrapperConstructor(superWrapperConstructor) {\n    function GeneratedWrapper(node) {\n      superWrapperConstructor.call(this, node);\n    }\n    var p = Object.create(superWrapperConstructor.prototype);\n    p.constructor = GeneratedWrapper;\n    GeneratedWrapper.prototype = p;\n\n    return GeneratedWrapper;\n  }\n\n  var OriginalDOMImplementation = window.DOMImplementation;\n  var OriginalEventTarget = window.EventTarget;\n  var OriginalEvent = window.Event;\n  var OriginalNode = window.Node;\n  var OriginalWindow = window.Window;\n  var OriginalRange = window.Range;\n  var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;\n  var OriginalWebGLRenderingContext = window.WebGLRenderingContext;\n  var OriginalSVGElementInstance = window.SVGElementInstance;\n\n  function isWrapper(object) {\n    return object instanceof wrappers.EventTarget ||\n           object instanceof wrappers.Event ||\n           object instanceof wrappers.Range ||\n           object instanceof wrappers.DOMImplementation ||\n           object instanceof wrappers.CanvasRenderingContext2D ||\n           wrappers.WebGLRenderingContext &&\n               object instanceof wrappers.WebGLRenderingContext;\n  }\n\n  function isNative(object) {\n    return OriginalEventTarget && object instanceof OriginalEventTarget ||\n           object instanceof OriginalNode ||\n           object instanceof OriginalEvent ||\n           object instanceof OriginalWindow ||\n           object instanceof OriginalRange ||\n           object instanceof OriginalDOMImplementation ||\n           object instanceof OriginalCanvasRenderingContext2D ||\n           OriginalWebGLRenderingContext &&\n               object instanceof OriginalWebGLRenderingContext ||\n           OriginalSVGElementInstance &&\n               object instanceof OriginalSVGElementInstance;\n  }\n\n  /**\n   * Wraps a node in a WrapperNode. If there already exists a wrapper for the\n   * |node| that wrapper is returned instead.\n   * @param {Node} node\n   * @return {WrapperNode}\n   */\n  function wrap(impl) {\n    if (impl === null)\n      return null;\n\n    assert(isNative(impl));\n    return impl.polymerWrapper_ ||\n        (impl.polymerWrapper_ = new (getWrapperConstructor(impl))(impl));\n  }\n\n  /**\n   * Unwraps a wrapper and returns the node it is wrapping.\n   * @param {WrapperNode} wrapper\n   * @return {Node}\n   */\n  function unwrap(wrapper) {\n    if (wrapper === null)\n      return null;\n    assert(isWrapper(wrapper));\n    return wrapper.impl;\n  }\n\n  /**\n   * Unwraps object if it is a wrapper.\n   * @param {Object} object\n   * @return {Object} The native implementation object.\n   */\n  function unwrapIfNeeded(object) {\n    return object && isWrapper(object) ? unwrap(object) : object;\n  }\n\n  /**\n   * Wraps object if it is not a wrapper.\n   * @param {Object} object\n   * @return {Object} The wrapper for object.\n   */\n  function wrapIfNeeded(object) {\n    return object && !isWrapper(object) ? wrap(object) : object;\n  }\n\n  /**\n   * Overrides the current wrapper (if any) for node.\n   * @param {Node} node\n   * @param {WrapperNode=} wrapper If left out the wrapper will be created as\n   *     needed next time someone wraps the node.\n   */\n  function rewrap(node, wrapper) {\n    if (wrapper === null)\n      return;\n    assert(isNative(node));\n    assert(wrapper === undefined || isWrapper(wrapper));\n    node.polymerWrapper_ = wrapper;\n  }\n\n  function defineGetter(constructor, name, getter) {\n    defineProperty(constructor.prototype, name, {\n      get: getter,\n      configurable: true,\n      enumerable: true\n    });\n  }\n\n  function defineWrapGetter(constructor, name) {\n    defineGetter(constructor, name, function() {\n      return wrap(this.impl[name]);\n    });\n  }\n\n  /**\n   * Forwards existing methods on the native object to the wrapper methods.\n   * This does not wrap any of the arguments or the return value since the\n   * wrapper implementation already takes care of that.\n   * @param {Array.<Function>} constructors\n   * @parem {Array.<string>} names\n   */\n  function forwardMethodsToWrapper(constructors, names) {\n    constructors.forEach(function(constructor) {\n      names.forEach(function(name) {\n        constructor.prototype[name] = function() {\n          var w = wrapIfNeeded(this);\n          return w[name].apply(w, arguments);\n        };\n      });\n    });\n  }\n\n  scope.assert = assert;\n  scope.constructorTable = constructorTable;\n  scope.defineGetter = defineGetter;\n  scope.defineWrapGetter = defineWrapGetter;\n  scope.forwardMethodsToWrapper = forwardMethodsToWrapper;\n  scope.isWrapper = isWrapper;\n  scope.isWrapperFor = isWrapperFor;\n  scope.mixin = mixin;\n  scope.nativePrototypeTable = nativePrototypeTable;\n  scope.oneOf = oneOf;\n  scope.registerObject = registerObject;\n  scope.registerWrapper = register;\n  scope.rewrap = rewrap;\n  scope.unwrap = unwrap;\n  scope.unwrapIfNeeded = unwrapIfNeeded;\n  scope.wrap = wrap;\n  scope.wrapIfNeeded = wrapIfNeeded;\n  scope.wrappers = wrappers;\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(context) {\n  'use strict';\n\n  var OriginalMutationObserver = window.MutationObserver;\n  var callbacks = [];\n  var pending = false;\n  var timerFunc;\n\n  function handle() {\n    pending = false;\n    var copies = callbacks.slice(0);\n    callbacks = [];\n    for (var i = 0; i < copies.length; i++) {\n      (0, copies[i])();\n    }\n  }\n\n  if (OriginalMutationObserver) {\n    var counter = 1;\n    var observer = new OriginalMutationObserver(handle);\n    var textNode = document.createTextNode(counter);\n    observer.observe(textNode, {characterData: true});\n\n    timerFunc = function() {\n      counter = (counter + 1) % 2;\n      textNode.data = counter;\n    };\n\n  } else {\n    timerFunc = window.setImmediate || window.setTimeout;\n  }\n\n  function setEndOfMicrotask(func) {\n    callbacks.push(func);\n    if (pending)\n      return;\n    pending = true;\n    timerFunc(handle, 0);\n  }\n\n  context.setEndOfMicrotask = setEndOfMicrotask;\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var setEndOfMicrotask = scope.setEndOfMicrotask\n  var wrapIfNeeded = scope.wrapIfNeeded\n  var wrappers = scope.wrappers;\n\n  var registrationsTable = new WeakMap();\n  var globalMutationObservers = [];\n  var isScheduled = false;\n\n  function scheduleCallback(observer) {\n    if (isScheduled)\n      return;\n    setEndOfMicrotask(notifyObservers);\n    isScheduled = true;\n  }\n\n  // http://dom.spec.whatwg.org/#mutation-observers\n  function notifyObservers() {\n    isScheduled = false;\n\n    do {\n      var notifyList = globalMutationObservers.slice();\n      var anyNonEmpty = false;\n      for (var i = 0; i < notifyList.length; i++) {\n        var mo = notifyList[i];\n        var queue = mo.takeRecords();\n        removeTransientObserversFor(mo);\n        if (queue.length) {\n          mo.callback_(queue, mo);\n          anyNonEmpty = true;\n        }\n      }\n    } while (anyNonEmpty);\n  }\n\n  /**\n   * @param {string} type\n   * @param {Node} target\n   * @constructor\n   */\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = new wrappers.NodeList();\n    this.removedNodes = new wrappers.NodeList();\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n\n  /**\n   * Registers transient observers to ancestor and its ancesors for the node\n   * which was removed.\n   * @param {!Node} ancestor\n   * @param {!Node} node\n   */\n  function registerTransientObservers(ancestor, node) {\n    for (; ancestor; ancestor = ancestor.parentNode) {\n      var registrations = registrationsTable.get(ancestor);\n      if (!registrations)\n        continue;\n      for (var i = 0; i < registrations.length; i++) {\n        var registration = registrations[i];\n        if (registration.options.subtree)\n          registration.addTransientObserver(node);\n      }\n    }\n  }\n\n  function removeTransientObserversFor(observer) {\n    for (var i = 0; i < observer.nodes_.length; i++) {\n      var node = observer.nodes_[i];\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        return;\n      for (var j = 0; j < registrations.length; j++) {\n        var registration = registrations[j];\n        if (registration.observer === observer)\n          registration.removeTransientObservers();\n      }\n    }\n  }\n\n  // http://dom.spec.whatwg.org/#queue-a-mutation-record\n  function enqueueMutation(target, type, data) {\n    // 1.\n    var interestedObservers = Object.create(null);\n    var associatedStrings = Object.create(null);\n\n    // 2.\n    for (var node = target; node; node = node.parentNode) {\n      // 3.\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        continue;\n      for (var j = 0; j < registrations.length; j++) {\n        var registration = registrations[j];\n        var options = registration.options;\n        // 1.\n        if (node !== target && !options.subtree)\n          continue;\n\n        // 2.\n        if (type === 'attributes' && !options.attributes)\n          continue;\n\n        // 3. If type is \"attributes\", options's attributeFilter is present, and\n        // either options's attributeFilter does not contain name or namespace\n        // is non-null, continue.\n        if (type === 'attributes' && options.attributeFilter &&\n            (data.namespace !== null ||\n             options.attributeFilter.indexOf(data.name) === -1)) {\n          continue;\n        }\n\n        // 4.\n        if (type === 'characterData' && !options.characterData)\n          continue;\n\n        // 5.\n        if (type === 'childList' && !options.childList)\n          continue;\n\n        // 6.\n        var observer = registration.observer;\n        interestedObservers[observer.uid_] = observer;\n\n        // 7. If either type is \"attributes\" and options's attributeOldValue is\n        // true, or type is \"characterData\" and options's characterDataOldValue\n        // is true, set the paired string of registered observer's observer in\n        // interested observers to oldValue.\n        if (type === 'attributes' && options.attributeOldValue ||\n            type === 'characterData' && options.characterDataOldValue) {\n          associatedStrings[observer.uid_] = data.oldValue;\n        }\n      }\n    }\n\n    var anyRecordsEnqueued = false;\n\n    // 4.\n    for (var uid in interestedObservers) {\n      var observer = interestedObservers[uid];\n      var record = new MutationRecord(type, target);\n\n      // 2.\n      if ('name' in data && 'namespace' in data) {\n        record.attributeName = data.name;\n        record.attributeNamespace = data.namespace;\n      }\n\n      // 3.\n      if (data.addedNodes)\n        record.addedNodes = data.addedNodes;\n\n      // 4.\n      if (data.removedNodes)\n        record.removedNodes = data.removedNodes;\n\n      // 5.\n      if (data.previousSibling)\n        record.previousSibling = data.previousSibling;\n\n      // 6.\n      if (data.nextSibling)\n        record.nextSibling = data.nextSibling;\n\n      // 7.\n      if (associatedStrings[uid] !== undefined)\n        record.oldValue = associatedStrings[uid];\n\n      // 8.\n      observer.records_.push(record);\n\n      anyRecordsEnqueued = true;\n    }\n\n    if (anyRecordsEnqueued)\n      scheduleCallback();\n  }\n\n  var slice = Array.prototype.slice;\n\n  /**\n   * @param {!Object} options\n   * @constructor\n   */\n  function MutationObserverOptions(options) {\n    this.childList = !!options.childList;\n    this.subtree = !!options.subtree;\n\n    // 1. If either options' attributeOldValue or attributeFilter is present\n    // and options' attributes is omitted, set options' attributes to true.\n    if (!('attributes' in options) &&\n        ('attributeOldValue' in options || 'attributeFilter' in options)) {\n      this.attributes = true;\n    } else {\n      this.attributes = !!options.attributes;\n    }\n\n    // 2. If options' characterDataOldValue is present and options'\n    // characterData is omitted, set options' characterData to true.\n    if ('characterDataOldValue' in options && !('characterData' in options))\n      this.characterData = true;\n    else\n      this.characterData = !!options.characterData;\n\n    // 3. & 4.\n    if (!this.attributes &&\n        (options.attributeOldValue || 'attributeFilter' in options) ||\n        // 5.\n        !this.characterData && options.characterDataOldValue) {\n      throw new TypeError();\n    }\n\n    this.characterData = !!options.characterData;\n    this.attributeOldValue = !!options.attributeOldValue;\n    this.characterDataOldValue = !!options.characterDataOldValue;\n    if ('attributeFilter' in options) {\n      if (options.attributeFilter == null ||\n          typeof options.attributeFilter !== 'object') {\n        throw new TypeError();\n      }\n      this.attributeFilter = slice.call(options.attributeFilter);\n    } else {\n      this.attributeFilter = null;\n    }\n  }\n\n  var uidCounter = 0;\n\n  /**\n   * The class that maps to the DOM MutationObserver interface.\n   * @param {Function} callback.\n   * @constructor\n   */\n  function MutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n\n    // This will leak. There is no way to implement this without WeakRefs :'(\n    globalMutationObservers.push(this);\n  }\n\n  MutationObserver.prototype = {\n    // http://dom.spec.whatwg.org/#dom-mutationobserver-observe\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n\n      var newOptions = new MutationObserverOptions(options);\n\n      // 6.\n      var registration;\n      var registrations = registrationsTable.get(target);\n      if (!registrations)\n        registrationsTable.set(target, registrations = []);\n\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          // 6.1.\n          registration.removeTransientObservers();\n          // 6.2.\n          registration.options = newOptions;\n        }\n      }\n\n      // 7.\n      if (!registration) {\n        registration = new Registration(this, target, newOptions);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n    },\n\n    // http://dom.spec.whatwg.org/#dom-mutationobserver-disconnect\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registrations.splice(i, 1);\n            // Each node can only have one registered observer associated with\n            // this observer.\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n\n  /**\n   * Class used to represent a registered observer.\n   * @param {MutationObserver} observer\n   * @param {Node} target\n   * @param {MutationObserverOptions} options\n   * @constructor\n   */\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n\n  Registration.prototype = {\n    /**\n     * Adds a transient observer on node. The transient observer gets removed\n     * next time we deliver the change records.\n     * @param {Node} node\n     */\n    addTransientObserver: function(node) {\n      // Don't add transient observers on the target itself. We already have all\n      // the required listeners set up on the target.\n      if (node === this.target)\n        return;\n\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        registrationsTable.set(node, registrations = []);\n\n      // We know that registrations does not contain this because we already\n      // checked if node === this.target.\n      registrations.push(this);\n    },\n\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n\n      for (var i = 0; i < transientObservedNodes.length; i++) {\n        var node = transientObservedNodes[i];\n        var registrations = registrationsTable.get(node);\n        for (var j = 0; j < registrations.length; j++) {\n          if (registrations[j] === this) {\n            registrations.splice(j, 1);\n            // Each node can only have one registered observer associated with\n            // this observer.\n            break;\n          }\n        }\n      }\n    }\n  };\n\n  scope.enqueueMutation = enqueueMutation;\n  scope.registerTransientObservers = registerTransientObservers;\n  scope.wrappers.MutationObserver = MutationObserver;\n  scope.wrappers.MutationRecord = MutationRecord;\n\n})(window.ShadowDOMPolyfill);\n","/**\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  /**\n   * A tree scope represents the root of a tree. All nodes in a tree point to\n   * the same TreeScope object. The tree scope of a node get set the first time\n   * it is accessed or when a node is added or remove to a tree.\n   * @constructor\n   */\n  function TreeScope(root, parent) {\n    this.root = root;\n    this.parent = parent;\n  }\n\n  TreeScope.prototype = {\n    get renderer() {\n      if (this.root instanceof scope.wrappers.ShadowRoot) {\n        return scope.getRendererForHost(this.root.host);\n      }\n      return null;\n    },\n\n    contains: function(treeScope) {\n      for (; treeScope; treeScope = treeScope.parent) {\n        if (treeScope === this)\n          return true;\n      }\n      return false;\n    }\n  };\n\n  function setTreeScope(node, treeScope) {\n    if (node.treeScope_ !== treeScope) {\n      node.treeScope_ = treeScope;\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        setTreeScope(child, treeScope);\n      }\n    }\n  }\n\n  function getTreeScope(node) {\n    if (node.treeScope_)\n      return node.treeScope_;\n    var parent = node.parentNode;\n    var treeScope;\n    if (parent)\n      treeScope = getTreeScope(parent);\n    else\n      treeScope = new TreeScope(node, null);\n    return node.treeScope_ = treeScope;\n  }\n\n  scope.TreeScope = TreeScope;\n  scope.getTreeScope = getTreeScope;\n  scope.setTreeScope = setTreeScope;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;\n  var getTreeScope = scope.getTreeScope;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrappers = scope.wrappers;\n\n  var wrappedFuns = new WeakMap();\n  var listenersTable = new WeakMap();\n  var handledEventsTable = new WeakMap();\n  var currentlyDispatchingEvents = new WeakMap();\n  var targetTable = new WeakMap();\n  var currentTargetTable = new WeakMap();\n  var relatedTargetTable = new WeakMap();\n  var eventPhaseTable = new WeakMap();\n  var stopPropagationTable = new WeakMap();\n  var stopImmediatePropagationTable = new WeakMap();\n  var eventHandlersTable = new WeakMap();\n  var eventPathTable = new WeakMap();\n\n  function isShadowRoot(node) {\n    return node instanceof wrappers.ShadowRoot;\n  }\n\n  function isInsertionPoint(node) {\n    var localName = node.localName;\n    return localName === 'content' || localName === 'shadow';\n  }\n\n  function isShadowHost(node) {\n    return !!node.shadowRoot;\n  }\n\n  function getEventParent(node) {\n    var dv;\n    return node.parentNode || (dv = node.defaultView) && wrap(dv) || null;\n  }\n\n  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-parent\n  function calculateParents(node, context, ancestors) {\n    if (ancestors.length)\n      return ancestors.shift();\n\n    // 1.\n    if (isShadowRoot(node))\n      return getInsertionParent(node) || node.host;\n\n    // 2.\n    var eventParents = scope.eventParentsTable.get(node);\n    if (eventParents) {\n      // Copy over the remaining event parents for next iteration.\n      for (var i = 1; i < eventParents.length; i++) {\n        ancestors[i - 1] = eventParents[i];\n      }\n      return eventParents[0];\n    }\n\n    // 3.\n    if (context && isInsertionPoint(node)) {\n      var parentNode = node.parentNode;\n      if (parentNode && isShadowHost(parentNode)) {\n        var trees = scope.getShadowTrees(parentNode);\n        var p = getInsertionParent(context);\n        for (var i = 0; i < trees.length; i++) {\n          if (trees[i].contains(p))\n            return p;\n        }\n      }\n    }\n\n    return getEventParent(node);\n  }\n\n  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#event-retargeting\n  function retarget(node) {\n    var stack = [];  // 1.\n    var ancestor = node;  // 2.\n    var targets = [];\n    var ancestors = [];\n    while (ancestor) {  // 3.\n      var context = null;  // 3.2.\n      // TODO(arv): Change order of these. If the stack is empty we always end\n      // up pushing ancestor, no matter what.\n      if (isInsertionPoint(ancestor)) {  // 3.1.\n        context = topMostNotInsertionPoint(stack);  // 3.1.1.\n        var top = stack[stack.length - 1] || ancestor;  // 3.1.2.\n        stack.push(top);\n      } else if (!stack.length) {\n        stack.push(ancestor);  // 3.3.\n      }\n      var target = stack[stack.length - 1];  // 3.4.\n      targets.push({target: target, currentTarget: ancestor});  // 3.5.\n      if (isShadowRoot(ancestor))  // 3.6.\n        stack.pop();  // 3.6.1.\n\n      ancestor = calculateParents(ancestor, context, ancestors);  // 3.7.\n    }\n    return targets;\n  }\n\n  function topMostNotInsertionPoint(stack) {\n    for (var i = stack.length - 1; i >= 0; i--) {\n      if (!isInsertionPoint(stack[i]))\n        return stack[i];\n    }\n    return null;\n  }\n\n  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-related-target\n  function adjustRelatedTarget(target, related) {\n    var ancestors = [];\n    while (target) {  // 3.\n      var stack = [];  // 3.1.\n      var ancestor = related;  // 3.2.\n      var last = undefined;  // 3.3. Needs to be reset every iteration.\n      while (ancestor) {\n        var context = null;\n        if (!stack.length) {\n          stack.push(ancestor);\n        } else {\n          if (isInsertionPoint(ancestor)) {  // 3.4.3.\n            context = topMostNotInsertionPoint(stack);\n            // isDistributed is more general than checking whether last is\n            // assigned into ancestor.\n            if (isDistributed(last)) {  // 3.4.3.2.\n              var head = stack[stack.length - 1];\n              stack.push(head);\n            }\n          }\n        }\n\n        if (inSameTree(ancestor, target))  // 3.4.4.\n          return stack[stack.length - 1];\n\n        if (isShadowRoot(ancestor))  // 3.4.5.\n          stack.pop();\n\n        last = ancestor;  // 3.4.6.\n        ancestor = calculateParents(ancestor, context, ancestors);  // 3.4.7.\n      }\n      if (isShadowRoot(target))  // 3.5.\n        target = target.host;\n      else\n        target = target.parentNode;  // 3.6.\n    }\n  }\n\n  function getInsertionParent(node) {\n    return scope.insertionParentTable.get(node);\n  }\n\n  function isDistributed(node) {\n    return getInsertionParent(node);\n  }\n\n  function inSameTree(a, b) {\n    return getTreeScope(a) === getTreeScope(b);\n  }\n\n  function dispatchOriginalEvent(originalEvent) {\n    // Make sure this event is only dispatched once.\n    if (handledEventsTable.get(originalEvent))\n      return;\n    handledEventsTable.set(originalEvent, true);\n\n    return dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));\n  }\n\n  function dispatchEvent(event, originalWrapperTarget) {\n    if (currentlyDispatchingEvents.get(event))\n      throw new Error('InvalidStateError')\n    currentlyDispatchingEvents.set(event, true);\n\n    // Render to ensure that the event path is correct.\n    scope.renderAllPending();\n    var eventPath = retarget(originalWrapperTarget);\n\n    // For window load events the load event is dispatched at the window but\n    // the target is set to the document.\n    //\n    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end\n    //\n    // TODO(arv): Find a less hacky way to do this.\n    if (event.type === 'load' &&\n        eventPath.length === 2 &&\n        eventPath[0].target instanceof wrappers.Document) {\n      eventPath.shift();\n    }\n\n    eventPathTable.set(event, eventPath);\n\n    if (dispatchCapturing(event, eventPath)) {\n      if (dispatchAtTarget(event, eventPath)) {\n        dispatchBubbling(event, eventPath);\n      }\n    }\n\n    eventPhaseTable.set(event, Event.NONE);\n    currentTargetTable.delete(event, null);\n    currentlyDispatchingEvents.delete(event);\n\n    return event.defaultPrevented;\n  }\n\n  function dispatchCapturing(event, eventPath) {\n    var phase;\n\n    for (var i = eventPath.length - 1; i > 0; i--) {\n      var target = eventPath[i].target;\n      var currentTarget = eventPath[i].currentTarget;\n      if (target === currentTarget)\n        continue;\n\n      phase = Event.CAPTURING_PHASE;\n      if (!invoke(eventPath[i], event, phase))\n        return false;\n    }\n\n    return true;\n  }\n\n  function dispatchAtTarget(event, eventPath) {\n    var phase = Event.AT_TARGET;\n    return invoke(eventPath[0], event, phase);\n  }\n\n  function dispatchBubbling(event, eventPath) {\n    var bubbles = event.bubbles;\n    var phase;\n\n    for (var i = 1; i < eventPath.length; i++) {\n      var target = eventPath[i].target;\n      var currentTarget = eventPath[i].currentTarget;\n      if (target === currentTarget)\n        phase = Event.AT_TARGET;\n      else if (bubbles && !stopImmediatePropagationTable.get(event))\n        phase = Event.BUBBLING_PHASE;\n      else\n        continue;\n\n      if (!invoke(eventPath[i], event, phase))\n        return;\n    }\n  }\n\n  function invoke(tuple, event, phase) {\n    var target = tuple.target;\n    var currentTarget = tuple.currentTarget;\n\n    var listeners = listenersTable.get(currentTarget);\n    if (!listeners)\n      return true;\n\n    if ('relatedTarget' in event) {\n      var originalEvent = unwrap(event);\n      // X-Tag sets relatedTarget on a CustomEvent. If they do that there is no\n      // way to have relatedTarget return the adjusted target but worse is that\n      // the originalEvent might not have a relatedTarget so we hit an assert\n      // when we try to wrap it.\n      if (originalEvent.relatedTarget) {\n        var relatedTarget = wrap(originalEvent.relatedTarget);\n\n        var adjusted = adjustRelatedTarget(currentTarget, relatedTarget);\n        if (adjusted === target)\n          return true;\n\n        relatedTargetTable.set(event, adjusted);\n      }\n    }\n\n    eventPhaseTable.set(event, phase);\n    var type = event.type;\n\n    var anyRemoved = false;\n    targetTable.set(event, target);\n    currentTargetTable.set(event, currentTarget);\n\n    for (var i = 0; i < listeners.length; i++) {\n      var listener = listeners[i];\n      if (listener.removed) {\n        anyRemoved = true;\n        continue;\n      }\n\n      if (listener.type !== type ||\n          !listener.capture && phase === Event.CAPTURING_PHASE ||\n          listener.capture && phase === Event.BUBBLING_PHASE) {\n        continue;\n      }\n\n      try {\n        if (typeof listener.handler === 'function')\n          listener.handler.call(currentTarget, event);\n        else\n          listener.handler.handleEvent(event);\n\n        if (stopImmediatePropagationTable.get(event))\n          return false;\n\n      } catch (ex) {\n        if (window.onerror)\n          window.onerror(ex.message);\n        else\n          console.error(ex, ex.stack);\n      }\n    }\n\n    if (anyRemoved) {\n      var copy = listeners.slice();\n      listeners.length = 0;\n      for (var i = 0; i < copy.length; i++) {\n        if (!copy[i].removed)\n          listeners.push(copy[i]);\n      }\n    }\n\n    return !stopPropagationTable.get(event);\n  }\n\n  function Listener(type, handler, capture) {\n    this.type = type;\n    this.handler = handler;\n    this.capture = Boolean(capture);\n  }\n  Listener.prototype = {\n    equals: function(that) {\n      return this.handler === that.handler && this.type === that.type &&\n          this.capture === that.capture;\n    },\n    get removed() {\n      return this.handler === null;\n    },\n    remove: function() {\n      this.handler = null;\n    }\n  };\n\n  var OriginalEvent = window.Event;\n  OriginalEvent.prototype.polymerBlackList_ = {\n    returnValue: true,\n    // TODO(arv): keyLocation is part of KeyboardEvent but Firefox does not\n    // support constructable KeyboardEvent so we keep it here for now.\n    keyLocation: true\n  };\n\n  /**\n   * Creates a new Event wrapper or wraps an existin native Event object.\n   * @param {string|Event} type\n   * @param {Object=} options\n   * @constructor\n   */\n  function Event(type, options) {\n    if (type instanceof OriginalEvent)\n      this.impl = type;\n    else\n      return wrap(constructEvent(OriginalEvent, 'Event', type, options));\n  }\n  Event.prototype = {\n    get target() {\n      return targetTable.get(this);\n    },\n    get currentTarget() {\n      return currentTargetTable.get(this);\n    },\n    get eventPhase() {\n      return eventPhaseTable.get(this);\n    },\n    get path() {\n      var nodeList = new wrappers.NodeList();\n      var eventPath = eventPathTable.get(this);\n      if (eventPath) {\n        var index = 0;\n        var lastIndex = eventPath.length - 1;\n        var baseRoot = getTreeScope(currentTargetTable.get(this));\n\n        for (var i = 0; i <= lastIndex; i++) {\n          var currentTarget = eventPath[i].currentTarget;\n          var currentRoot = getTreeScope(currentTarget);\n          if (currentRoot.contains(baseRoot) &&\n              // Make sure we do not add Window to the path.\n              (i !== lastIndex || currentTarget instanceof wrappers.Node)) {\n            nodeList[index++] = currentTarget;\n          }\n        }\n        nodeList.length = index;\n      }\n      return nodeList;\n    },\n    stopPropagation: function() {\n      stopPropagationTable.set(this, true);\n    },\n    stopImmediatePropagation: function() {\n      stopPropagationTable.set(this, true);\n      stopImmediatePropagationTable.set(this, true);\n    }\n  };\n  registerWrapper(OriginalEvent, Event, document.createEvent('Event'));\n\n  function unwrapOptions(options) {\n    if (!options || !options.relatedTarget)\n      return options;\n    return Object.create(options, {\n      relatedTarget: {value: unwrap(options.relatedTarget)}\n    });\n  }\n\n  function registerGenericEvent(name, SuperEvent, prototype) {\n    var OriginalEvent = window[name];\n    var GenericEvent = function(type, options) {\n      if (type instanceof OriginalEvent)\n        this.impl = type;\n      else\n        return wrap(constructEvent(OriginalEvent, name, type, options));\n    };\n    GenericEvent.prototype = Object.create(SuperEvent.prototype);\n    if (prototype)\n      mixin(GenericEvent.prototype, prototype);\n    if (OriginalEvent) {\n      // - Old versions of Safari fails on new FocusEvent (and others?).\n      // - IE does not support event constructors.\n      // - createEvent('FocusEvent') throws in Firefox.\n      // => Try the best practice solution first and fallback to the old way\n      // if needed.\n      try {\n        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent('temp'));\n      } catch (ex) {\n        registerWrapper(OriginalEvent, GenericEvent,\n                        document.createEvent(name));\n      }\n    }\n    return GenericEvent;\n  }\n\n  var UIEvent = registerGenericEvent('UIEvent', Event);\n  var CustomEvent = registerGenericEvent('CustomEvent', Event);\n\n  var relatedTargetProto = {\n    get relatedTarget() {\n      return relatedTargetTable.get(this) || wrap(unwrap(this).relatedTarget);\n    }\n  };\n\n  function getInitFunction(name, relatedTargetIndex) {\n    return function() {\n      arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);\n      var impl = unwrap(this);\n      impl[name].apply(impl, arguments);\n    };\n  }\n\n  var mouseEventProto = mixin({\n    initMouseEvent: getInitFunction('initMouseEvent', 14)\n  }, relatedTargetProto);\n\n  var focusEventProto = mixin({\n    initFocusEvent: getInitFunction('initFocusEvent', 5)\n  }, relatedTargetProto);\n\n  var MouseEvent = registerGenericEvent('MouseEvent', UIEvent, mouseEventProto);\n  var FocusEvent = registerGenericEvent('FocusEvent', UIEvent, focusEventProto);\n\n  // In case the browser does not support event constructors we polyfill that\n  // by calling `createEvent('Foo')` and `initFooEvent` where the arguments to\n  // `initFooEvent` are derived from the registered default event init dict.\n  var defaultInitDicts = Object.create(null);\n\n  var supportsEventConstructors = (function() {\n    try {\n      new window.FocusEvent('focus');\n    } catch (ex) {\n      return false;\n    }\n    return true;\n  })();\n\n  /**\n   * Constructs a new native event.\n   */\n  function constructEvent(OriginalEvent, name, type, options) {\n    if (supportsEventConstructors)\n      return new OriginalEvent(type, unwrapOptions(options));\n\n    // Create the arguments from the default dictionary.\n    var event = unwrap(document.createEvent(name));\n    var defaultDict = defaultInitDicts[name];\n    var args = [type];\n    Object.keys(defaultDict).forEach(function(key) {\n      var v = options != null && key in options ?\n          options[key] : defaultDict[key];\n      if (key === 'relatedTarget')\n        v = unwrap(v);\n      args.push(v);\n    });\n    event['init' + name].apply(event, args);\n    return event;\n  }\n\n  if (!supportsEventConstructors) {\n    var configureEventConstructor = function(name, initDict, superName) {\n      if (superName) {\n        var superDict = defaultInitDicts[superName];\n        initDict = mixin(mixin({}, superDict), initDict);\n      }\n\n      defaultInitDicts[name] = initDict;\n    };\n\n    // The order of the default event init dictionary keys is important, the\n    // arguments to initFooEvent is derived from that.\n    configureEventConstructor('Event', {bubbles: false, cancelable: false});\n    configureEventConstructor('CustomEvent', {detail: null}, 'Event');\n    configureEventConstructor('UIEvent', {view: null, detail: 0}, 'Event');\n    configureEventConstructor('MouseEvent', {\n      screenX: 0,\n      screenY: 0,\n      clientX: 0,\n      clientY: 0,\n      ctrlKey: false,\n      altKey: false,\n      shiftKey: false,\n      metaKey: false,\n      button: 0,\n      relatedTarget: null\n    }, 'UIEvent');\n    configureEventConstructor('FocusEvent', {relatedTarget: null}, 'UIEvent');\n  }\n\n  function BeforeUnloadEvent(impl) {\n    Event.call(this);\n  }\n  BeforeUnloadEvent.prototype = Object.create(Event.prototype);\n  mixin(BeforeUnloadEvent.prototype, {\n    get returnValue() {\n      return this.impl.returnValue;\n    },\n    set returnValue(v) {\n      this.impl.returnValue = v;\n    }\n  });\n\n  function isValidListener(fun) {\n    if (typeof fun === 'function')\n      return true;\n    return fun && fun.handleEvent;\n  }\n\n  function isMutationEvent(type) {\n    switch (type) {\n      case 'DOMAttrModified':\n      case 'DOMAttributeNameChanged':\n      case 'DOMCharacterDataModified':\n      case 'DOMElementNameChanged':\n      case 'DOMNodeInserted':\n      case 'DOMNodeInsertedIntoDocument':\n      case 'DOMNodeRemoved':\n      case 'DOMNodeRemovedFromDocument':\n      case 'DOMSubtreeModified':\n        return true;\n    }\n    return false;\n  }\n\n  var OriginalEventTarget = window.EventTarget;\n\n  /**\n   * This represents a wrapper for an EventTarget.\n   * @param {!EventTarget} impl The original event target.\n   * @constructor\n   */\n  function EventTarget(impl) {\n    this.impl = impl;\n  }\n\n  // Node and Window have different internal type checks in WebKit so we cannot\n  // use the same method as the original function.\n  var methodNames = [\n    'addEventListener',\n    'removeEventListener',\n    'dispatchEvent'\n  ];\n\n  [Node, Window].forEach(function(constructor) {\n    var p = constructor.prototype;\n    methodNames.forEach(function(name) {\n      Object.defineProperty(p, name + '_', {value: p[name]});\n    });\n  });\n\n  function getTargetToListenAt(wrapper) {\n    if (wrapper instanceof wrappers.ShadowRoot)\n      wrapper = wrapper.host;\n    return unwrap(wrapper);\n  }\n\n  EventTarget.prototype = {\n    addEventListener: function(type, fun, capture) {\n      if (!isValidListener(fun) || isMutationEvent(type))\n        return;\n\n      var listener = new Listener(type, fun, capture);\n      var listeners = listenersTable.get(this);\n      if (!listeners) {\n        listeners = [];\n        listenersTable.set(this, listeners);\n      } else {\n        // Might have a duplicate.\n        for (var i = 0; i < listeners.length; i++) {\n          if (listener.equals(listeners[i]))\n            return;\n        }\n      }\n\n      listeners.push(listener);\n\n      var target = getTargetToListenAt(this);\n      target.addEventListener_(type, dispatchOriginalEvent, true);\n    },\n    removeEventListener: function(type, fun, capture) {\n      capture = Boolean(capture);\n      var listeners = listenersTable.get(this);\n      if (!listeners)\n        return;\n      var count = 0, found = false;\n      for (var i = 0; i < listeners.length; i++) {\n        if (listeners[i].type === type && listeners[i].capture === capture) {\n          count++;\n          if (listeners[i].handler === fun) {\n            found = true;\n            listeners[i].remove();\n          }\n        }\n      }\n\n      if (found && count === 1) {\n        var target = getTargetToListenAt(this);\n        target.removeEventListener_(type, dispatchOriginalEvent, true);\n      }\n    },\n    dispatchEvent: function(event) {\n      // We want to use the native dispatchEvent because it triggers the default\n      // actions (like checking a checkbox). However, if there are no listeners\n      // in the composed tree then there are no events that will trigger and\n      // listeners in the non composed tree that are part of the event path are\n      // not notified.\n      //\n      // If we find out that there are no listeners in the composed tree we add\n      // a temporary listener to the target which makes us get called back even\n      // in that case.\n\n      var nativeEvent = unwrap(event);\n      var eventType = nativeEvent.type;\n\n      // Allow dispatching the same event again. This is safe because if user\n      // code calls this during an existing dispatch of the same event the\n      // native dispatchEvent throws (that is required by the spec).\n      handledEventsTable.set(nativeEvent, false);\n\n      // Force rendering since we prefer native dispatch and that works on the\n      // composed tree.\n      scope.renderAllPending();\n\n      var tempListener;\n      if (!hasListenerInAncestors(this, eventType)) {\n        tempListener = function() {};\n        this.addEventListener(eventType, tempListener, true);\n      }\n\n      try {\n        return unwrap(this).dispatchEvent_(nativeEvent);\n      } finally {\n        if (tempListener)\n          this.removeEventListener(eventType, tempListener, true);\n      }\n    }\n  };\n\n  function hasListener(node, type) {\n    var listeners = listenersTable.get(node);\n    if (listeners) {\n      for (var i = 0; i < listeners.length; i++) {\n        if (!listeners[i].removed && listeners[i].type === type)\n          return true;\n      }\n    }\n    return false;\n  }\n\n  function hasListenerInAncestors(target, type) {\n    for (var node = unwrap(target); node; node = node.parentNode) {\n      if (hasListener(wrap(node), type))\n        return true;\n    }\n    return false;\n  }\n\n  if (OriginalEventTarget)\n    registerWrapper(OriginalEventTarget, EventTarget);\n\n  function wrapEventTargetMethods(constructors) {\n    forwardMethodsToWrapper(constructors, methodNames);\n  }\n\n  var originalElementFromPoint = document.elementFromPoint;\n\n  function elementFromPoint(self, document, x, y) {\n    scope.renderAllPending();\n\n    var element = wrap(originalElementFromPoint.call(document.impl, x, y));\n    var targets = retarget(element, this)\n    for (var i = 0; i < targets.length; i++) {\n      var target = targets[i];\n      if (target.currentTarget === self)\n        return target.target;\n    }\n    return null;\n  }\n\n  /**\n   * Returns a function that is to be used as a getter for `onfoo` properties.\n   * @param {string} name\n   * @return {Function}\n   */\n  function getEventHandlerGetter(name) {\n    return function() {\n      var inlineEventHandlers = eventHandlersTable.get(this);\n      return inlineEventHandlers && inlineEventHandlers[name] &&\n          inlineEventHandlers[name].value || null;\n     };\n  }\n\n  /**\n   * Returns a function that is to be used as a setter for `onfoo` properties.\n   * @param {string} name\n   * @return {Function}\n   */\n  function getEventHandlerSetter(name) {\n    var eventType = name.slice(2);\n    return function(value) {\n      var inlineEventHandlers = eventHandlersTable.get(this);\n      if (!inlineEventHandlers) {\n        inlineEventHandlers = Object.create(null);\n        eventHandlersTable.set(this, inlineEventHandlers);\n      }\n\n      var old = inlineEventHandlers[name];\n      if (old)\n        this.removeEventListener(eventType, old.wrapped, false);\n\n      if (typeof value === 'function') {\n        var wrapped = function(e) {\n          var rv = value.call(this, e);\n          if (rv === false)\n            e.preventDefault();\n          else if (name === 'onbeforeunload' && typeof rv === 'string')\n            e.returnValue = rv;\n          // mouseover uses true for preventDefault but preventDefault for\n          // mouseover is ignored by browsers these day.\n        };\n\n        this.addEventListener(eventType, wrapped, false);\n        inlineEventHandlers[name] = {\n          value: value,\n          wrapped: wrapped\n        };\n      }\n    };\n  }\n\n  scope.adjustRelatedTarget = adjustRelatedTarget;\n  scope.elementFromPoint = elementFromPoint;\n  scope.getEventHandlerGetter = getEventHandlerGetter;\n  scope.getEventHandlerSetter = getEventHandlerSetter;\n  scope.wrapEventTargetMethods = wrapEventTargetMethods;\n  scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;\n  scope.wrappers.CustomEvent = CustomEvent;\n  scope.wrappers.Event = Event;\n  scope.wrappers.EventTarget = EventTarget;\n  scope.wrappers.FocusEvent = FocusEvent;\n  scope.wrappers.MouseEvent = MouseEvent;\n  scope.wrappers.UIEvent = UIEvent;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2012 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var wrap = scope.wrap;\n\n  function nonEnum(obj, prop) {\n    Object.defineProperty(obj, prop, {enumerable: false});\n  }\n\n  function NodeList() {\n    this.length = 0;\n    nonEnum(this, 'length');\n  }\n  NodeList.prototype = {\n    item: function(index) {\n      return this[index];\n    }\n  };\n  nonEnum(NodeList.prototype, 'item');\n\n  function wrapNodeList(list) {\n    if (list == null)\n      return list;\n    var wrapperList = new NodeList();\n    for (var i = 0, length = list.length; i < length; i++) {\n      wrapperList[i] = wrap(list[i]);\n    }\n    wrapperList.length = length;\n    return wrapperList;\n  }\n\n  function addWrapNodeListMethod(wrapperConstructor, name) {\n    wrapperConstructor.prototype[name] = function() {\n      return wrapNodeList(this.impl[name].apply(this.impl, arguments));\n    };\n  }\n\n  scope.wrappers.NodeList = NodeList;\n  scope.addWrapNodeListMethod = addWrapNodeListMethod;\n  scope.wrapNodeList = wrapNodeList;\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  // TODO(arv): Implement.\n\n  scope.wrapHTMLCollection = scope.wrapNodeList;\n  scope.wrappers.HTMLCollection = scope.wrappers.NodeList;\n\n})(window.ShadowDOMPolyfill);\n","/**\n * Copyright 2012 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var EventTarget = scope.wrappers.EventTarget;\n  var NodeList = scope.wrappers.NodeList;\n  var TreeScope = scope.TreeScope;\n  var assert = scope.assert;\n  var defineWrapGetter = scope.defineWrapGetter;\n  var enqueueMutation = scope.enqueueMutation;\n  var getTreeScope = scope.getTreeScope;\n  var isWrapper = scope.isWrapper;\n  var mixin = scope.mixin;\n  var registerTransientObservers = scope.registerTransientObservers;\n  var registerWrapper = scope.registerWrapper;\n  var setTreeScope = scope.setTreeScope;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrapIfNeeded = scope.wrapIfNeeded;\n  var wrappers = scope.wrappers;\n\n  function assertIsNodeWrapper(node) {\n    assert(node instanceof Node);\n  }\n\n  function createOneElementNodeList(node) {\n    var nodes = new NodeList();\n    nodes[0] = node;\n    nodes.length = 1;\n    return nodes;\n  }\n\n  var surpressMutations = false;\n\n  /**\n   * Called before node is inserted into a node to enqueue its removal from its\n   * old parent.\n   * @param {!Node} node The node that is about to be removed.\n   * @param {!Node} parent The parent node that the node is being removed from.\n   * @param {!NodeList} nodes The collected nodes.\n   */\n  function enqueueRemovalForInsertedNodes(node, parent, nodes) {\n    enqueueMutation(parent, 'childList', {\n      removedNodes: nodes,\n      previousSibling: node.previousSibling,\n      nextSibling: node.nextSibling\n    });\n  }\n\n  function enqueueRemovalForInsertedDocumentFragment(df, nodes) {\n    enqueueMutation(df, 'childList', {\n      removedNodes: nodes\n    });\n  }\n\n  /**\n   * Collects nodes from a DocumentFragment or a Node for removal followed\n   * by an insertion.\n   *\n   * This updates the internal pointers for node, previousNode and nextNode.\n   */\n  function collectNodes(node, parentNode, previousNode, nextNode) {\n    if (node instanceof DocumentFragment) {\n      var nodes = collectNodesForDocumentFragment(node);\n\n      // The extra loop is to work around bugs with DocumentFragments in IE.\n      surpressMutations = true;\n      for (var i = nodes.length - 1; i >= 0; i--) {\n        node.removeChild(nodes[i]);\n        nodes[i].parentNode_ = parentNode;\n      }\n      surpressMutations = false;\n\n      for (var i = 0; i < nodes.length; i++) {\n        nodes[i].previousSibling_ = nodes[i - 1] || previousNode;\n        nodes[i].nextSibling_ = nodes[i + 1] || nextNode;\n      }\n\n      if (previousNode)\n        previousNode.nextSibling_ = nodes[0];\n      if (nextNode)\n        nextNode.previousSibling_ = nodes[nodes.length - 1];\n\n      return nodes;\n    }\n\n    var nodes = createOneElementNodeList(node);\n    var oldParent = node.parentNode;\n    if (oldParent) {\n      // This will enqueue the mutation record for the removal as needed.\n      oldParent.removeChild(node);\n    }\n\n    node.parentNode_ = parentNode;\n    node.previousSibling_ = previousNode;\n    node.nextSibling_ = nextNode;\n    if (previousNode)\n      previousNode.nextSibling_ = node;\n    if (nextNode)\n      nextNode.previousSibling_ = node;\n\n    return nodes;\n  }\n\n  function collectNodesNative(node) {\n    if (node instanceof DocumentFragment)\n      return collectNodesForDocumentFragment(node);\n\n    var nodes = createOneElementNodeList(node);\n    var oldParent = node.parentNode;\n    if (oldParent)\n      enqueueRemovalForInsertedNodes(node, oldParent, nodes);\n    return nodes;\n  }\n\n  function collectNodesForDocumentFragment(node) {\n    var nodes = new NodeList();\n    var i = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      nodes[i++] = child;\n    }\n    nodes.length = i;\n    enqueueRemovalForInsertedDocumentFragment(node, nodes);\n    return nodes;\n  }\n\n  function snapshotNodeList(nodeList) {\n    // NodeLists are not live at the moment so just return the same object.\n    return nodeList;\n  }\n\n  // http://dom.spec.whatwg.org/#node-is-inserted\n  function nodeWasAdded(node, treeScope) {\n    setTreeScope(node, treeScope);\n    node.nodeIsInserted_();\n  }\n\n  function nodesWereAdded(nodes, parent) {\n    var treeScope = getTreeScope(parent);\n    for (var i = 0; i < nodes.length; i++) {\n      nodeWasAdded(nodes[i], treeScope);\n    }\n  }\n\n  // http://dom.spec.whatwg.org/#node-is-removed\n  function nodeWasRemoved(node) {\n    setTreeScope(node, new TreeScope(node, null));\n  }\n\n  function nodesWereRemoved(nodes) {\n    for (var i = 0; i < nodes.length; i++) {\n      nodeWasRemoved(nodes[i]);\n    }\n  }\n\n  function ensureSameOwnerDocument(parent, child) {\n    var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ?\n        parent : parent.ownerDocument;\n    if (ownerDoc !== child.ownerDocument)\n      ownerDoc.adoptNode(child);\n  }\n\n  function adoptNodesIfNeeded(owner, nodes) {\n    if (!nodes.length)\n      return;\n\n    var ownerDoc = owner.ownerDocument;\n\n    // All nodes have the same ownerDocument when we get here.\n    if (ownerDoc === nodes[0].ownerDocument)\n      return;\n\n    for (var i = 0; i < nodes.length; i++) {\n      scope.adoptNodeNoRemove(nodes[i], ownerDoc);\n    }\n  }\n\n  function unwrapNodesForInsertion(owner, nodes) {\n    adoptNodesIfNeeded(owner, nodes);\n    var length = nodes.length;\n\n    if (length === 1)\n      return unwrap(nodes[0]);\n\n    var df = unwrap(owner.ownerDocument.createDocumentFragment());\n    for (var i = 0; i < length; i++) {\n      df.appendChild(unwrap(nodes[i]));\n    }\n    return df;\n  }\n\n  function clearChildNodes(wrapper) {\n    if (wrapper.firstChild_ !== undefined) {\n      var child = wrapper.firstChild_;\n      while (child) {\n        var tmp = child;\n        child = child.nextSibling_;\n        tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;\n      }\n    }\n    wrapper.firstChild_ = wrapper.lastChild_ = undefined;\n  }\n\n  function removeAllChildNodes(wrapper) {\n    if (wrapper.invalidateShadowRenderer()) {\n      var childWrapper = wrapper.firstChild;\n      while (childWrapper) {\n        assert(childWrapper.parentNode === wrapper);\n        var nextSibling = childWrapper.nextSibling;\n        var childNode = unwrap(childWrapper);\n        var parentNode = childNode.parentNode;\n        if (parentNode)\n          originalRemoveChild.call(parentNode, childNode);\n        childWrapper.previousSibling_ = childWrapper.nextSibling_ =\n            childWrapper.parentNode_ = null;\n        childWrapper = nextSibling;\n      }\n      wrapper.firstChild_ = wrapper.lastChild_ = null;\n    } else {\n      var node = unwrap(wrapper);\n      var child = node.firstChild;\n      var nextSibling;\n      while (child) {\n        nextSibling = child.nextSibling;\n        originalRemoveChild.call(node, child);\n        child = nextSibling;\n      }\n    }\n  }\n\n  function invalidateParent(node) {\n    var p = node.parentNode;\n    return p && p.invalidateShadowRenderer();\n  }\n\n  function cleanupNodes(nodes) {\n    for (var i = 0, n; i < nodes.length; i++) {\n      n = nodes[i];\n      n.parentNode.removeChild(n);\n    }\n  }\n\n  var originalImportNode = document.importNode;\n  var originalCloneNode = window.Node.prototype.cloneNode;\n\n  function cloneNode(node, deep, opt_doc) {\n    var clone;\n    if (opt_doc)\n      clone = wrap(originalImportNode.call(opt_doc, node.impl, false));\n    else\n      clone = wrap(originalCloneNode.call(node.impl, false));\n\n    if (deep) {\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        clone.appendChild(cloneNode(child, true, opt_doc));\n      }\n\n      if (node instanceof wrappers.HTMLTemplateElement) {\n        var cloneContent = clone.content;\n        for (var child = node.content.firstChild;\n             child;\n             child = child.nextSibling) {\n         cloneContent.appendChild(cloneNode(child, true, opt_doc));\n        }\n      }\n    }\n    // TODO(arv): Some HTML elements also clone other data like value.\n    return clone;\n  }\n\n  function contains(self, child) {\n    if (!child || getTreeScope(self) !== getTreeScope(child))\n      return false;\n\n    for (var node = child; node; node = node.parentNode) {\n      if (node === self)\n        return true;\n    }\n    return false;\n  }\n\n  var OriginalNode = window.Node;\n\n  /**\n   * This represents a wrapper of a native DOM node.\n   * @param {!Node} original The original DOM node, aka, the visual DOM node.\n   * @constructor\n   * @extends {EventTarget}\n   */\n  function Node(original) {\n    assert(original instanceof OriginalNode);\n\n    EventTarget.call(this, original);\n\n    // These properties are used to override the visual references with the\n    // logical ones. If the value is undefined it means that the logical is the\n    // same as the visual.\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.parentNode_ = undefined;\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.firstChild_ = undefined;\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.lastChild_ = undefined;\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.nextSibling_ = undefined;\n\n    /**\n     * @type {Node|undefined}\n     * @private\n     */\n    this.previousSibling_ = undefined;\n\n    this.treeScope_ = undefined;\n  }\n\n  var OriginalDocumentFragment = window.DocumentFragment;\n  var originalAppendChild = OriginalNode.prototype.appendChild;\n  var originalCompareDocumentPosition =\n      OriginalNode.prototype.compareDocumentPosition;\n  var originalInsertBefore = OriginalNode.prototype.insertBefore;\n  var originalRemoveChild = OriginalNode.prototype.removeChild;\n  var originalReplaceChild = OriginalNode.prototype.replaceChild;\n\n  var isIe = /Trident/.test(navigator.userAgent);\n\n  var removeChildOriginalHelper = isIe ?\n      function(parent, child) {\n        try {\n          originalRemoveChild.call(parent, child);\n        } catch (ex) {\n          if (!(parent instanceof OriginalDocumentFragment))\n            throw ex;\n        }\n      } :\n      function(parent, child) {\n        originalRemoveChild.call(parent, child);\n      };\n\n  Node.prototype = Object.create(EventTarget.prototype);\n  mixin(Node.prototype, {\n    appendChild: function(childWrapper) {\n      return this.insertBefore(childWrapper, null);\n    },\n\n    insertBefore: function(childWrapper, refWrapper) {\n      assertIsNodeWrapper(childWrapper);\n\n      var refNode;\n      if (refWrapper) {\n        if (isWrapper(refWrapper)) {\n          refNode = unwrap(refWrapper);\n        } else {\n          refNode = refWrapper;\n          refWrapper = wrap(refNode);\n        }\n      } else {\n        refWrapper = null;\n        refNode = null;\n      }\n\n      refWrapper && assert(refWrapper.parentNode === this);\n\n      var nodes;\n      var previousNode =\n          refWrapper ? refWrapper.previousSibling : this.lastChild;\n\n      var useNative = !this.invalidateShadowRenderer() &&\n                      !invalidateParent(childWrapper);\n\n      if (useNative)\n        nodes = collectNodesNative(childWrapper);\n      else\n        nodes = collectNodes(childWrapper, this, previousNode, refWrapper);\n\n      if (useNative) {\n        ensureSameOwnerDocument(this, childWrapper);\n        clearChildNodes(this);\n        originalInsertBefore.call(this.impl, unwrap(childWrapper), refNode);\n      } else {\n        if (!previousNode)\n          this.firstChild_ = nodes[0];\n        if (!refWrapper)\n          this.lastChild_ = nodes[nodes.length - 1];\n\n        var parentNode = refNode ? refNode.parentNode : this.impl;\n\n        // insertBefore refWrapper no matter what the parent is?\n        if (parentNode) {\n          originalInsertBefore.call(parentNode,\n              unwrapNodesForInsertion(this, nodes), refNode);\n        } else {\n          adoptNodesIfNeeded(this, nodes);\n        }\n      }\n\n      enqueueMutation(this, 'childList', {\n        addedNodes: nodes,\n        nextSibling: refWrapper,\n        previousSibling: previousNode\n      });\n\n      nodesWereAdded(nodes, this);\n\n      return childWrapper;\n    },\n\n    removeChild: function(childWrapper) {\n      assertIsNodeWrapper(childWrapper);\n      if (childWrapper.parentNode !== this) {\n        // IE has invalid DOM trees at times.\n        var found = false;\n        var childNodes = this.childNodes;\n        for (var ieChild = this.firstChild; ieChild;\n             ieChild = ieChild.nextSibling) {\n          if (ieChild === childWrapper) {\n            found = true;\n            break;\n          }\n        }\n        if (!found) {\n          // TODO(arv): DOMException\n          throw new Error('NotFoundError');\n        }\n      }\n\n      var childNode = unwrap(childWrapper);\n      var childWrapperNextSibling = childWrapper.nextSibling;\n      var childWrapperPreviousSibling = childWrapper.previousSibling;\n\n      if (this.invalidateShadowRenderer()) {\n        // We need to remove the real node from the DOM before updating the\n        // pointers. This is so that that mutation event is dispatched before\n        // the pointers have changed.\n        var thisFirstChild = this.firstChild;\n        var thisLastChild = this.lastChild;\n\n        var parentNode = childNode.parentNode;\n        if (parentNode)\n          removeChildOriginalHelper(parentNode, childNode);\n\n        if (thisFirstChild === childWrapper)\n          this.firstChild_ = childWrapperNextSibling;\n        if (thisLastChild === childWrapper)\n          this.lastChild_ = childWrapperPreviousSibling;\n        if (childWrapperPreviousSibling)\n          childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;\n        if (childWrapperNextSibling) {\n          childWrapperNextSibling.previousSibling_ =\n              childWrapperPreviousSibling;\n        }\n\n        childWrapper.previousSibling_ = childWrapper.nextSibling_ =\n            childWrapper.parentNode_ = undefined;\n      } else {\n        clearChildNodes(this);\n        removeChildOriginalHelper(this.impl, childNode);\n      }\n\n      if (!surpressMutations) {\n        enqueueMutation(this, 'childList', {\n          removedNodes: createOneElementNodeList(childWrapper),\n          nextSibling: childWrapperNextSibling,\n          previousSibling: childWrapperPreviousSibling\n        });\n      }\n\n      registerTransientObservers(this, childWrapper);\n\n      return childWrapper;\n    },\n\n    replaceChild: function(newChildWrapper, oldChildWrapper) {\n      assertIsNodeWrapper(newChildWrapper);\n\n      var oldChildNode;\n      if (isWrapper(oldChildWrapper)) {\n        oldChildNode = unwrap(oldChildWrapper);\n      } else {\n        oldChildNode = oldChildWrapper;\n        oldChildWrapper = wrap(oldChildNode);\n      }\n\n      if (oldChildWrapper.parentNode !== this) {\n        // TODO(arv): DOMException\n        throw new Error('NotFoundError');\n      }\n\n      var nextNode = oldChildWrapper.nextSibling;\n      var previousNode = oldChildWrapper.previousSibling;\n      var nodes;\n\n      var useNative = !this.invalidateShadowRenderer() &&\n                      !invalidateParent(newChildWrapper);\n\n      if (useNative) {\n        nodes = collectNodesNative(newChildWrapper);\n      } else {\n        if (nextNode === newChildWrapper)\n          nextNode = newChildWrapper.nextSibling;\n        nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);\n      }\n\n      if (!useNative) {\n        if (this.firstChild === oldChildWrapper)\n          this.firstChild_ = nodes[0];\n        if (this.lastChild === oldChildWrapper)\n          this.lastChild_ = nodes[nodes.length - 1];\n\n        oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ =\n            oldChildWrapper.parentNode_ = undefined;\n\n        // replaceChild no matter what the parent is?\n        if (oldChildNode.parentNode) {\n          originalReplaceChild.call(\n              oldChildNode.parentNode,\n              unwrapNodesForInsertion(this, nodes),\n              oldChildNode);\n        }\n      } else {\n        ensureSameOwnerDocument(this, newChildWrapper);\n        clearChildNodes(this);\n        originalReplaceChild.call(this.impl, unwrap(newChildWrapper),\n                                  oldChildNode);\n      }\n\n      enqueueMutation(this, 'childList', {\n        addedNodes: nodes,\n        removedNodes: createOneElementNodeList(oldChildWrapper),\n        nextSibling: nextNode,\n        previousSibling: previousNode\n      });\n\n      nodeWasRemoved(oldChildWrapper);\n      nodesWereAdded(nodes, this);\n\n      return oldChildWrapper;\n    },\n\n    /**\n     * Called after a node was inserted. Subclasses override this to invalidate\n     * the renderer as needed.\n     * @private\n     */\n    nodeIsInserted_: function() {\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        child.nodeIsInserted_();\n      }\n    },\n\n    hasChildNodes: function() {\n      return this.firstChild !== null;\n    },\n\n    /** @type {Node} */\n    get parentNode() {\n      // If the parentNode has not been overridden, use the original parentNode.\n      return this.parentNode_ !== undefined ?\n          this.parentNode_ : wrap(this.impl.parentNode);\n    },\n\n    /** @type {Node} */\n    get firstChild() {\n      return this.firstChild_ !== undefined ?\n          this.firstChild_ : wrap(this.impl.firstChild);\n    },\n\n    /** @type {Node} */\n    get lastChild() {\n      return this.lastChild_ !== undefined ?\n          this.lastChild_ : wrap(this.impl.lastChild);\n    },\n\n    /** @type {Node} */\n    get nextSibling() {\n      return this.nextSibling_ !== undefined ?\n          this.nextSibling_ : wrap(this.impl.nextSibling);\n    },\n\n    /** @type {Node} */\n    get previousSibling() {\n      return this.previousSibling_ !== undefined ?\n          this.previousSibling_ : wrap(this.impl.previousSibling);\n    },\n\n    get parentElement() {\n      var p = this.parentNode;\n      while (p && p.nodeType !== Node.ELEMENT_NODE) {\n        p = p.parentNode;\n      }\n      return p;\n    },\n\n    get textContent() {\n      // TODO(arv): This should fallback to this.impl.textContent if there\n      // are no shadow trees below or above the context node.\n      var s = '';\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        if (child.nodeType != Node.COMMENT_NODE) {\n          s += child.textContent;\n        }\n      }\n      return s;\n    },\n    set textContent(textContent) {\n      var removedNodes = snapshotNodeList(this.childNodes);\n\n      if (this.invalidateShadowRenderer()) {\n        removeAllChildNodes(this);\n        if (textContent !== '') {\n          var textNode = this.impl.ownerDocument.createTextNode(textContent);\n          this.appendChild(textNode);\n        }\n      } else {\n        clearChildNodes(this);\n        this.impl.textContent = textContent;\n      }\n\n      var addedNodes = snapshotNodeList(this.childNodes);\n\n      enqueueMutation(this, 'childList', {\n        addedNodes: addedNodes,\n        removedNodes: removedNodes\n      });\n\n      nodesWereRemoved(removedNodes);\n      nodesWereAdded(addedNodes, this);\n    },\n\n    get childNodes() {\n      var wrapperList = new NodeList();\n      var i = 0;\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        wrapperList[i++] = child;\n      }\n      wrapperList.length = i;\n      return wrapperList;\n    },\n\n    cloneNode: function(deep) {\n      return cloneNode(this, deep);\n    },\n\n    contains: function(child) {\n      return contains(this, wrapIfNeeded(child));\n    },\n\n    compareDocumentPosition: function(otherNode) {\n      // This only wraps, it therefore only operates on the composed DOM and not\n      // the logical DOM.\n      return originalCompareDocumentPosition.call(this.impl, unwrap(otherNode));\n    },\n\n    normalize: function() {\n      var nodes = snapshotNodeList(this.childNodes);\n      var remNodes = [];\n      var s = '';\n      var modNode;\n\n      for (var i = 0, n; i < nodes.length; i++) {\n        n = nodes[i];\n        if (n.nodeType === Node.TEXT_NODE) {\n          if (!modNode && !n.data.length)\n            this.removeNode(n);\n          else if (!modNode)\n            modNode = n;\n          else {\n            s += n.data;\n            remNodes.push(n);\n          }\n        } else {\n          if (modNode && remNodes.length) {\n            modNode.data += s;\n            cleanUpNodes(remNodes);\n          }\n          remNodes = [];\n          s = '';\n          modNode = null;\n          if (n.childNodes.length)\n            n.normalize();\n        }\n      }\n\n      // handle case where >1 text nodes are the last children\n      if (modNode && remNodes.length) {\n        modNode.data += s;\n        cleanupNodes(remNodes);\n      }\n    }\n  });\n\n  defineWrapGetter(Node, 'ownerDocument');\n\n  // We use a DocumentFragment as a base and then delete the properties of\n  // DocumentFragment.prototype from the wrapper Node. Since delete makes\n  // objects slow in some JS engines we recreate the prototype object.\n  registerWrapper(OriginalNode, Node, document.createDocumentFragment());\n  delete Node.prototype.querySelector;\n  delete Node.prototype.querySelectorAll;\n  Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);\n\n  scope.cloneNode = cloneNode;\n  scope.nodeWasAdded = nodeWasAdded;\n  scope.nodeWasRemoved = nodeWasRemoved;\n  scope.nodesWereAdded = nodesWereAdded;\n  scope.nodesWereRemoved = nodesWereRemoved;\n  scope.snapshotNodeList = snapshotNodeList;\n  scope.wrappers.Node = Node;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  function findOne(node, selector) {\n    var m, el = node.firstElementChild;\n    while (el) {\n      if (el.matches(selector))\n        return el;\n      m = findOne(el, selector);\n      if (m)\n        return m;\n      el = el.nextElementSibling;\n    }\n    return null;\n  }\n\n  function findAll(node, selector, results) {\n    var el = node.firstElementChild;\n    while (el) {\n      if (el.matches(selector))\n        results[results.length++] = el;\n      findAll(el, selector, results);\n      el = el.nextElementSibling;\n    }\n    return results;\n  }\n\n  // find and findAll will only match Simple Selectors,\n  // Structural Pseudo Classes are not guarenteed to be correct\n  // http://www.w3.org/TR/css3-selectors/#simple-selectors\n\n  var SelectorsInterface = {\n    querySelector: function(selector) {\n      return findOne(this, selector);\n    },\n    querySelectorAll: function(selector) {\n      return findAll(this, selector, new NodeList())\n    }\n  };\n\n  var GetElementsByInterface = {\n    getElementsByTagName: function(tagName) {\n      // TODO(arv): Check tagName?\n      return this.querySelectorAll(tagName);\n    },\n    getElementsByClassName: function(className) {\n      // TODO(arv): Check className?\n      return this.querySelectorAll('.' + className);\n    },\n    getElementsByTagNameNS: function(ns, tagName) {\n      if (ns === '*')\n        return this.getElementsByTagName(tagName);\n\n      // TODO(arv): Check tagName?\n      var result = new NodeList;\n      var els = this.getElementsByTagName(tagName);\n      for (var i = 0, j = 0; i < els.length; i++) {\n        if (els[i].namespaceURI === ns)\n          result[j++] = els[i];\n      }\n      result.length = j;\n      return result;\n    }\n  };\n\n  scope.GetElementsByInterface = GetElementsByInterface;\n  scope.SelectorsInterface = SelectorsInterface;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var NodeList = scope.wrappers.NodeList;\n\n  function forwardElement(node) {\n    while (node && node.nodeType !== Node.ELEMENT_NODE) {\n      node = node.nextSibling;\n    }\n    return node;\n  }\n\n  function backwardsElement(node) {\n    while (node && node.nodeType !== Node.ELEMENT_NODE) {\n      node = node.previousSibling;\n    }\n    return node;\n  }\n\n  var ParentNodeInterface = {\n    get firstElementChild() {\n      return forwardElement(this.firstChild);\n    },\n\n    get lastElementChild() {\n      return backwardsElement(this.lastChild);\n    },\n\n    get childElementCount() {\n      var count = 0;\n      for (var child = this.firstElementChild;\n           child;\n           child = child.nextElementSibling) {\n        count++;\n      }\n      return count;\n    },\n\n    get children() {\n      var wrapperList = new NodeList();\n      var i = 0;\n      for (var child = this.firstElementChild;\n           child;\n           child = child.nextElementSibling) {\n        wrapperList[i++] = child;\n      }\n      wrapperList.length = i;\n      return wrapperList;\n    }\n  };\n\n  var ChildNodeInterface = {\n    get nextElementSibling() {\n      return forwardElement(this.nextSibling);\n    },\n\n    get previousElementSibling() {\n      return backwardsElement(this.previousSibling);\n    }\n  };\n\n  scope.ChildNodeInterface = ChildNodeInterface;\n  scope.ParentNodeInterface = ParentNodeInterface;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var ChildNodeInterface = scope.ChildNodeInterface;\n  var Node = scope.wrappers.Node;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalCharacterData = window.CharacterData;\n\n  function CharacterData(node) {\n    Node.call(this, node);\n  }\n  CharacterData.prototype = Object.create(Node.prototype);\n  mixin(CharacterData.prototype, {\n    get textContent() {\n      return this.data;\n    },\n    set textContent(value) {\n      this.data = value;\n    },\n    get data() {\n      return this.impl.data;\n    },\n    set data(value) {\n      var oldValue = this.impl.data;\n      enqueueMutation(this, 'characterData', {\n        oldValue: oldValue\n      });\n      this.impl.data = value;\n    }\n  });\n\n  mixin(CharacterData.prototype, ChildNodeInterface);\n\n  registerWrapper(OriginalCharacterData, CharacterData,\n                  document.createTextNode(''));\n\n  scope.wrappers.CharacterData = CharacterData;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var CharacterData = scope.wrappers.CharacterData;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  function toUInt32(x) {\n    return x >>> 0;\n  }\n\n  var OriginalText = window.Text;\n\n  function Text(node) {\n    CharacterData.call(this, node);\n  }\n  Text.prototype = Object.create(CharacterData.prototype);\n  mixin(Text.prototype, {\n    splitText: function(offset) {\n      offset = toUInt32(offset);\n      var s = this.data;\n      if (offset > s.length)\n        throw new Error('IndexSizeError');\n      var head = s.slice(0, offset);\n      var tail = s.slice(offset);\n      this.data = head;\n      var newTextNode = this.ownerDocument.createTextNode(tail);\n      if (this.parentNode)\n        this.parentNode.insertBefore(newTextNode, this.nextSibling);\n      return newTextNode;\n    }\n  });\n\n  registerWrapper(OriginalText, Text, document.createTextNode(''));\n\n  scope.wrappers.Text = Text;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var ChildNodeInterface = scope.ChildNodeInterface;\n  var GetElementsByInterface = scope.GetElementsByInterface;\n  var Node = scope.wrappers.Node;\n  var ParentNodeInterface = scope.ParentNodeInterface;\n  var SelectorsInterface = scope.SelectorsInterface;\n  var addWrapNodeListMethod = scope.addWrapNodeListMethod;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var oneOf = scope.oneOf;\n  var registerWrapper = scope.registerWrapper;\n  var wrappers = scope.wrappers;\n\n  var OriginalElement = window.Element;\n\n  var matchesNames = [\n    'matches',  // needs to come first.\n    'mozMatchesSelector',\n    'msMatchesSelector',\n    'webkitMatchesSelector',\n  ].filter(function(name) {\n    return OriginalElement.prototype[name];\n  });\n\n  var matchesName = matchesNames[0];\n\n  var originalMatches = OriginalElement.prototype[matchesName];\n\n  function invalidateRendererBasedOnAttribute(element, name) {\n    // Only invalidate if parent node is a shadow host.\n    var p = element.parentNode;\n    if (!p || !p.shadowRoot)\n      return;\n\n    var renderer = scope.getRendererForHost(p);\n    if (renderer.dependsOnAttribute(name))\n      renderer.invalidate();\n  }\n\n  function enqueAttributeChange(element, name, oldValue) {\n    // This is not fully spec compliant. We should use localName (which might\n    // have a different case than name) and the namespace (which requires us\n    // to get the Attr object).\n    enqueueMutation(element, 'attributes', {\n      name: name,\n      namespace: null,\n      oldValue: oldValue\n    });\n  }\n\n  function Element(node) {\n    Node.call(this, node);\n  }\n  Element.prototype = Object.create(Node.prototype);\n  mixin(Element.prototype, {\n    createShadowRoot: function() {\n      var newShadowRoot = new wrappers.ShadowRoot(this);\n      this.impl.polymerShadowRoot_ = newShadowRoot;\n\n      var renderer = scope.getRendererForHost(this);\n      renderer.invalidate();\n\n      return newShadowRoot;\n    },\n\n    get shadowRoot() {\n      return this.impl.polymerShadowRoot_ || null;\n    },\n\n    setAttribute: function(name, value) {\n      var oldValue = this.impl.getAttribute(name);\n      this.impl.setAttribute(name, value);\n      enqueAttributeChange(this, name, oldValue);\n      invalidateRendererBasedOnAttribute(this, name);\n    },\n\n    removeAttribute: function(name) {\n      var oldValue = this.impl.getAttribute(name);\n      this.impl.removeAttribute(name);\n      enqueAttributeChange(this, name, oldValue);\n      invalidateRendererBasedOnAttribute(this, name);\n    },\n\n    matches: function(selector) {\n      return originalMatches.call(this.impl, selector);\n    }\n  });\n\n  matchesNames.forEach(function(name) {\n    if (name !== 'matches') {\n      Element.prototype[name] = function(selector) {\n        return this.matches(selector);\n      };\n    }\n  });\n\n  if (OriginalElement.prototype.webkitCreateShadowRoot) {\n    Element.prototype.webkitCreateShadowRoot =\n        Element.prototype.createShadowRoot;\n  }\n\n  /**\n   * Useful for generating the accessor pair for a property that reflects an\n   * attribute.\n   */\n  function setterDirtiesAttribute(prototype, propertyName, opt_attrName) {\n    var attrName = opt_attrName || propertyName;\n    Object.defineProperty(prototype, propertyName, {\n      get: function() {\n        return this.impl[propertyName];\n      },\n      set: function(v) {\n        this.impl[propertyName] = v;\n        invalidateRendererBasedOnAttribute(this, attrName);\n      },\n      configurable: true,\n      enumerable: true\n    });\n  }\n\n  setterDirtiesAttribute(Element.prototype, 'id');\n  setterDirtiesAttribute(Element.prototype, 'className', 'class');\n\n  mixin(Element.prototype, ChildNodeInterface);\n  mixin(Element.prototype, GetElementsByInterface);\n  mixin(Element.prototype, ParentNodeInterface);\n  mixin(Element.prototype, SelectorsInterface);\n\n  registerWrapper(OriginalElement, Element,\n                  document.createElementNS(null, 'x'));\n\n  // TODO(arv): Export setterDirtiesAttribute and apply it to more bindings\n  // that reflect attributes.\n  scope.matchesNames = matchesNames;\n  scope.wrappers.Element = Element;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var Element = scope.wrappers.Element;\n  var defineGetter = scope.defineGetter;\n  var enqueueMutation = scope.enqueueMutation;\n  var mixin = scope.mixin;\n  var nodesWereAdded = scope.nodesWereAdded;\n  var nodesWereRemoved = scope.nodesWereRemoved;\n  var registerWrapper = scope.registerWrapper;\n  var snapshotNodeList = scope.snapshotNodeList;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrappers = scope.wrappers;\n\n  /////////////////////////////////////////////////////////////////////////////\n  // innerHTML and outerHTML\n\n  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString\n  var escapeAttrRegExp = /[&\\u00A0\"]/g;\n  var escapeDataRegExp = /[&\\u00A0<>]/g;\n\n  function escapeReplace(c) {\n    switch (c) {\n      case '&':\n        return '&amp;';\n      case '<':\n        return '&lt;';\n      case '>':\n        return '&gt;';\n      case '\"':\n        return '&quot;'\n      case '\\u00A0':\n        return '&nbsp;';\n    }\n  }\n\n  function escapeAttr(s) {\n    return s.replace(escapeAttrRegExp, escapeReplace);\n  }\n\n  function escapeData(s) {\n    return s.replace(escapeDataRegExp, escapeReplace);\n  }\n\n  function makeSet(arr) {\n    var set = {};\n    for (var i = 0; i < arr.length; i++) {\n      set[arr[i]] = true;\n    }\n    return set;\n  }\n\n  // http://www.whatwg.org/specs/web-apps/current-work/#void-elements\n  var voidElements = makeSet([\n    'area',\n    'base',\n    'br',\n    'col',\n    'command',\n    'embed',\n    'hr',\n    'img',\n    'input',\n    'keygen',\n    'link',\n    'meta',\n    'param',\n    'source',\n    'track',\n    'wbr'\n  ]);\n\n  var plaintextParents = makeSet([\n    'style',\n    'script',\n    'xmp',\n    'iframe',\n    'noembed',\n    'noframes',\n    'plaintext',\n    'noscript'\n  ]);\n\n  function getOuterHTML(node, parentNode) {\n    switch (node.nodeType) {\n      case Node.ELEMENT_NODE:\n        var tagName = node.tagName.toLowerCase();\n        var s = '<' + tagName;\n        var attrs = node.attributes;\n        for (var i = 0, attr; attr = attrs[i]; i++) {\n          s += ' ' + attr.name + '=\"' + escapeAttr(attr.value) + '\"';\n        }\n        s += '>';\n        if (voidElements[tagName])\n          return s;\n\n        return s + getInnerHTML(node) + '</' + tagName + '>';\n\n      case Node.TEXT_NODE:\n        var data = node.data;\n        if (parentNode && plaintextParents[parentNode.localName])\n          return data;\n        return escapeData(data);\n\n      case Node.COMMENT_NODE:\n        return '<!--' + node.data + '-->';\n\n      default:\n        console.error(node);\n        throw new Error('not implemented');\n    }\n  }\n\n  function getInnerHTML(node) {\n    if (node instanceof wrappers.HTMLTemplateElement)\n      node = node.content;\n\n    var s = '';\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      s += getOuterHTML(child, node);\n    }\n    return s;\n  }\n\n  function setInnerHTML(node, value, opt_tagName) {\n    var tagName = opt_tagName || 'div';\n    node.textContent = '';\n    var tempElement = unwrap(node.ownerDocument.createElement(tagName));\n    tempElement.innerHTML = value;\n    var firstChild;\n    while (firstChild = tempElement.firstChild) {\n      node.appendChild(wrap(firstChild));\n    }\n  }\n\n  // IE11 does not have MSIE in the user agent string.\n  var oldIe = /MSIE/.test(navigator.userAgent);\n\n  var OriginalHTMLElement = window.HTMLElement;\n  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;\n\n  function HTMLElement(node) {\n    Element.call(this, node);\n  }\n  HTMLElement.prototype = Object.create(Element.prototype);\n  mixin(HTMLElement.prototype, {\n    get innerHTML() {\n      return getInnerHTML(this);\n    },\n    set innerHTML(value) {\n      // IE9 does not handle set innerHTML correctly on plaintextParents. It\n      // creates element children. For example\n      //\n      //   scriptElement.innerHTML = '<a>test</a>'\n      //\n      // Creates a single HTMLAnchorElement child.\n      if (oldIe && plaintextParents[this.localName]) {\n        this.textContent = value;\n        return;\n      }\n\n      var removedNodes = snapshotNodeList(this.childNodes);\n\n      if (this.invalidateShadowRenderer()) {\n        if (this instanceof wrappers.HTMLTemplateElement)\n          setInnerHTML(this.content, value);\n        else\n          setInnerHTML(this, value, this.tagName);\n\n      // If we have a non native template element we need to handle this\n      // manually since setting impl.innerHTML would add the html as direct\n      // children and not be moved over to the content fragment.\n      } else if (!OriginalHTMLTemplateElement &&\n                 this instanceof wrappers.HTMLTemplateElement) {\n        setInnerHTML(this.content, value);\n      } else {\n        this.impl.innerHTML = value;\n      }\n\n      var addedNodes = snapshotNodeList(this.childNodes);\n\n      enqueueMutation(this, 'childList', {\n        addedNodes: addedNodes,\n        removedNodes: removedNodes\n      });\n\n      nodesWereRemoved(removedNodes);\n      nodesWereAdded(addedNodes, this);\n    },\n\n    get outerHTML() {\n      return getOuterHTML(this, this.parentNode);\n    },\n    set outerHTML(value) {\n      var p = this.parentNode;\n      if (p) {\n        p.invalidateShadowRenderer();\n        var df = frag(p, value);\n        p.replaceChild(df, this);\n      }\n    },\n\n    insertAdjacentHTML: function(position, text) {\n      var contextElement, refNode;\n      switch (String(position).toLowerCase()) {\n        case 'beforebegin':\n          contextElement = this.parentNode;\n          refNode = this;\n          break;\n        case 'afterend':\n          contextElement = this.parentNode;\n          refNode = this.nextSibling;\n          break;\n        case 'afterbegin':\n          contextElement = this;\n          refNode = this.firstChild;\n          break;\n        case 'beforeend':\n          contextElement = this;\n          refNode = null;\n          break;\n        default:\n          return;\n      }\n\n      var df = frag(contextElement, text);\n      contextElement.insertBefore(df, refNode);\n    }\n  });\n\n  function frag(contextElement, html) {\n    // TODO(arv): This does not work with SVG and other non HTML elements.\n    var p = unwrap(contextElement.cloneNode(false));\n    p.innerHTML = html;\n    var df = unwrap(document.createDocumentFragment());\n    var c;\n    while (c = p.firstChild) {\n      df.appendChild(c);\n    }\n    return wrap(df);\n  }\n\n  function getter(name) {\n    return function() {\n      scope.renderAllPending();\n      return this.impl[name];\n    };\n  }\n\n  function getterRequiresRendering(name) {\n    defineGetter(HTMLElement, name, getter(name));\n  }\n\n  [\n    'clientHeight',\n    'clientLeft',\n    'clientTop',\n    'clientWidth',\n    'offsetHeight',\n    'offsetLeft',\n    'offsetTop',\n    'offsetWidth',\n    'scrollHeight',\n    'scrollWidth',\n  ].forEach(getterRequiresRendering);\n\n  function getterAndSetterRequiresRendering(name) {\n    Object.defineProperty(HTMLElement.prototype, name, {\n      get: getter(name),\n      set: function(v) {\n        scope.renderAllPending();\n        this.impl[name] = v;\n      },\n      configurable: true,\n      enumerable: true\n    });\n  }\n\n  [\n    'scrollLeft',\n    'scrollTop',\n  ].forEach(getterAndSetterRequiresRendering);\n\n  function methodRequiresRendering(name) {\n    Object.defineProperty(HTMLElement.prototype, name, {\n      value: function() {\n        scope.renderAllPending();\n        return this.impl[name].apply(this.impl, arguments);\n      },\n      configurable: true,\n      enumerable: true\n    });\n  }\n\n  [\n    'getBoundingClientRect',\n    'getClientRects',\n    'scrollIntoView'\n  ].forEach(methodRequiresRendering);\n\n  // HTMLElement is abstract so we use a subclass that has no members.\n  registerWrapper(OriginalHTMLElement, HTMLElement,\n                  document.createElement('b'));\n\n  scope.wrappers.HTMLElement = HTMLElement;\n\n  // TODO: Find a better way to share these two with WrapperShadowRoot.\n  scope.getInnerHTML = getInnerHTML;\n  scope.setInnerHTML = setInnerHTML\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLCanvasElement = window.HTMLCanvasElement;\n\n  function HTMLCanvasElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);\n\n  mixin(HTMLCanvasElement.prototype, {\n    getContext: function() {\n      var context = this.impl.getContext.apply(this.impl, arguments);\n      return context && wrap(context);\n    }\n  });\n\n  registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement,\n                  document.createElement('canvas'));\n\n  scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalHTMLContentElement = window.HTMLContentElement;\n\n  function HTMLContentElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLContentElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLContentElement.prototype, {\n    get select() {\n      return this.getAttribute('select');\n    },\n    set select(value) {\n      this.setAttribute('select', value);\n    },\n\n    setAttribute: function(n, v) {\n      HTMLElement.prototype.setAttribute.call(this, n, v);\n      if (String(n).toLowerCase() === 'select')\n        this.invalidateShadowRenderer(true);\n    }\n\n    // getDistributedNodes is added in ShadowRenderer\n\n    // TODO: attribute boolean resetStyleInheritance;\n  });\n\n  if (OriginalHTMLContentElement)\n    registerWrapper(OriginalHTMLContentElement, HTMLContentElement);\n\n  scope.wrappers.HTMLContentElement = HTMLContentElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var rewrap = scope.rewrap;\n\n  var OriginalHTMLImageElement = window.HTMLImageElement;\n\n  function HTMLImageElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLImageElement.prototype = Object.create(HTMLElement.prototype);\n\n  registerWrapper(OriginalHTMLImageElement, HTMLImageElement,\n                  document.createElement('img'));\n\n  function Image(width, height) {\n    if (!(this instanceof Image)) {\n      throw new TypeError(\n          'DOM object constructor cannot be called as a function.');\n    }\n\n    var node = unwrap(document.createElement('img'));\n    HTMLElement.call(this, node);\n    rewrap(node, this);\n\n    if (width !== undefined)\n      node.width = width;\n    if (height !== undefined)\n      node.height = height;\n  }\n\n  Image.prototype = HTMLImageElement.prototype;\n\n  scope.wrappers.HTMLImageElement = HTMLImageElement;\n  scope.wrappers.Image = Image;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalHTMLShadowElement = window.HTMLShadowElement;\n\n  function HTMLShadowElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLShadowElement.prototype, {\n    // TODO: attribute boolean resetStyleInheritance;\n  });\n\n  if (OriginalHTMLShadowElement)\n    registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);\n\n  scope.wrappers.HTMLShadowElement = HTMLShadowElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var contentTable = new WeakMap();\n  var templateContentsOwnerTable = new WeakMap();\n\n  // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-owner\n  function getTemplateContentsOwner(doc) {\n    if (!doc.defaultView)\n      return doc;\n    var d = templateContentsOwnerTable.get(doc);\n    if (!d) {\n      // TODO(arv): This should either be a Document or HTMLDocument depending\n      // on doc.\n      d = doc.implementation.createHTMLDocument('');\n      while (d.lastChild) {\n        d.removeChild(d.lastChild);\n      }\n      templateContentsOwnerTable.set(doc, d);\n    }\n    return d;\n  }\n\n  function extractContent(templateElement) {\n    // templateElement is not a wrapper here.\n    var doc = getTemplateContentsOwner(templateElement.ownerDocument);\n    var df = unwrap(doc.createDocumentFragment());\n    var child;\n    while (child = templateElement.firstChild) {\n      df.appendChild(child);\n    }\n    return df;\n  }\n\n  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;\n\n  function HTMLTemplateElement(node) {\n    HTMLElement.call(this, node);\n    if (!OriginalHTMLTemplateElement) {\n      var content = extractContent(node);\n      contentTable.set(this, wrap(content));\n    }\n  }\n  HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);\n\n  mixin(HTMLTemplateElement.prototype, {\n    get content() {\n      if (OriginalHTMLTemplateElement)\n        return wrap(this.impl.content);\n      return contentTable.get(this);\n    },\n\n    // TODO(arv): cloneNode needs to clone content.\n\n  });\n\n  if (OriginalHTMLTemplateElement)\n    registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);\n\n  scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalHTMLMediaElement = window.HTMLMediaElement;\n\n  function HTMLMediaElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);\n\n  registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement,\n                  document.createElement('audio'));\n\n  scope.wrappers.HTMLMediaElement = HTMLMediaElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLMediaElement = scope.wrappers.HTMLMediaElement;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var rewrap = scope.rewrap;\n\n  var OriginalHTMLAudioElement = window.HTMLAudioElement;\n\n  function HTMLAudioElement(node) {\n    HTMLMediaElement.call(this, node);\n  }\n  HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);\n\n  registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement,\n                  document.createElement('audio'));\n\n  function Audio(src) {\n    if (!(this instanceof Audio)) {\n      throw new TypeError(\n          'DOM object constructor cannot be called as a function.');\n    }\n\n    var node = unwrap(document.createElement('audio'));\n    HTMLMediaElement.call(this, node);\n    rewrap(node, this);\n\n    node.setAttribute('preload', 'auto');\n    if (src !== undefined)\n      node.setAttribute('src', src);\n  }\n\n  Audio.prototype = HTMLAudioElement.prototype;\n\n  scope.wrappers.HTMLAudioElement = HTMLAudioElement;\n  scope.wrappers.Audio = Audio;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var rewrap = scope.rewrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLOptionElement = window.HTMLOptionElement;\n\n  function trimText(s) {\n    return s.replace(/\\s+/g, ' ').trim();\n  }\n\n  function HTMLOptionElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLOptionElement.prototype, {\n    get text() {\n      return trimText(this.textContent);\n    },\n    set text(value) {\n      this.textContent = trimText(String(value));\n    },\n    get form() {\n      return wrap(unwrap(this).form);\n    }\n  });\n\n  registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement,\n                  document.createElement('option'));\n\n  function Option(text, value, defaultSelected, selected) {\n    if (!(this instanceof Option)) {\n      throw new TypeError(\n          'DOM object constructor cannot be called as a function.');\n    }\n\n    var node = unwrap(document.createElement('option'));\n    HTMLElement.call(this, node);\n    rewrap(node, this);\n\n    if (text !== undefined)\n      node.text = text;\n    if (value !== undefined)\n      node.setAttribute('value', value);\n    if (defaultSelected === true)\n      node.setAttribute('selected', '');\n    node.selected = selected === true;\n  }\n\n  Option.prototype = HTMLOptionElement.prototype;\n\n  scope.wrappers.HTMLOptionElement = HTMLOptionElement;\n  scope.wrappers.Option = Option;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLSelectElement = window.HTMLSelectElement;\n\n  function HTMLSelectElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLSelectElement.prototype, {\n    add: function(element, before) {\n      if (typeof before === 'object')  // also includes null\n        before = unwrap(before);\n      unwrap(this).add(unwrap(element), before);\n    },\n\n    remove: function(indexOrNode) {\n      // Spec only allows index but implementations allow index or node.\n      // remove() is also allowed which is same as remove(undefined)\n      if (typeof indexOrNode === 'object')\n        indexOrNode = unwrap(indexOrNode);\n      unwrap(this).remove(indexOrNode);\n    },\n\n    get form() {\n      return wrap(unwrap(this).form);\n    }\n  });\n\n  registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement,\n                  document.createElement('select'));\n\n  scope.wrappers.HTMLSelectElement = HTMLSelectElement;\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n\n  var OriginalHTMLTableElement = window.HTMLTableElement;\n\n  function HTMLTableElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLTableElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTableElement.prototype, {\n    get caption() {\n      return wrap(unwrap(this).caption);\n    },\n    createCaption: function() {\n      return wrap(unwrap(this).createCaption());\n    },\n\n    get tHead() {\n      return wrap(unwrap(this).tHead);\n    },\n    createTHead: function() {\n      return wrap(unwrap(this).createTHead());\n    },\n\n    createTFoot: function() {\n      return wrap(unwrap(this).createTFoot());\n    },\n    get tFoot() {\n      return wrap(unwrap(this).tFoot);\n    },\n\n    get tBodies() {\n      return wrapHTMLCollection(unwrap(this).tBodies);\n    },\n    createTBody: function() {\n      return wrap(unwrap(this).createTBody());\n    },\n\n    get rows() {\n      return wrapHTMLCollection(unwrap(this).rows);\n    },\n    insertRow: function(index) {\n      return wrap(unwrap(this).insertRow(index));\n    }\n  });\n\n  registerWrapper(OriginalHTMLTableElement, HTMLTableElement,\n                  document.createElement('table'));\n\n  scope.wrappers.HTMLTableElement = HTMLTableElement;\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;\n\n  function HTMLTableSectionElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTableSectionElement.prototype, {\n    get rows() {\n      return wrapHTMLCollection(unwrap(this).rows);\n    },\n    insertRow: function(index) {\n      return wrap(unwrap(this).insertRow(index));\n    }\n  });\n\n  registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement,\n                  document.createElement('thead'));\n\n  scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrapHTMLCollection = scope.wrapHTMLCollection;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalHTMLTableRowElement = window.HTMLTableRowElement;\n\n  function HTMLTableRowElement(node) {\n    HTMLElement.call(this, node);\n  }\n  HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);\n  mixin(HTMLTableRowElement.prototype, {\n    get cells() {\n      return wrapHTMLCollection(unwrap(this).cells);\n    },\n\n    insertCell: function(index) {\n      return wrap(unwrap(this).insertCell(index));\n    }\n  });\n\n  registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement,\n                  document.createElement('tr'));\n\n  scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLContentElement = scope.wrappers.HTMLContentElement;\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;\n  var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n\n  var OriginalHTMLUnknownElement = window.HTMLUnknownElement;\n\n  function HTMLUnknownElement(node) {\n    switch (node.localName) {\n      case 'content':\n        return new HTMLContentElement(node);\n      case 'shadow':\n        return new HTMLShadowElement(node);\n      case 'template':\n        return new HTMLTemplateElement(node);\n    }\n    HTMLElement.call(this, node);\n  }\n  HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);\n  registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);\n  scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var registerObject = scope.registerObject;\n\n  var SVG_NS = 'http://www.w3.org/2000/svg';\n  var svgTitleElement = document.createElementNS(SVG_NS, 'title');\n  var SVGTitleElement = registerObject(svgTitleElement);\n  var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;\n\n  scope.wrappers.SVGElement = SVGElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var OriginalSVGUseElement = window.SVGUseElement;\n\n  // IE uses SVGElement as parent interface, SVG2 (Blink & Gecko) uses\n  // SVGGraphicsElement. Use the <g> element to get the right prototype.\n\n  var SVG_NS = 'http://www.w3.org/2000/svg';\n  var gWrapper = wrap(document.createElementNS(SVG_NS, 'g'));\n  var useElement = document.createElementNS(SVG_NS, 'use');\n  var SVGGElement = gWrapper.constructor;\n  var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);\n  var parentInterface = parentInterfacePrototype.constructor;\n\n  function SVGUseElement(impl) {\n    parentInterface.call(this, impl);\n  }\n\n  SVGUseElement.prototype = Object.create(parentInterfacePrototype);\n\n  // Firefox does not expose instanceRoot.\n  if ('instanceRoot' in useElement) {\n    mixin(SVGUseElement.prototype, {\n      get instanceRoot() {\n        return wrap(unwrap(this).instanceRoot);\n      },\n      get animatedInstanceRoot() {\n        return wrap(unwrap(this).animatedInstanceRoot);\n      },\n    });\n  }\n\n  registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);\n\n  scope.wrappers.SVGUseElement = SVGUseElement;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var EventTarget = scope.wrappers.EventTarget;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var wrap = scope.wrap;\n\n  var OriginalSVGElementInstance = window.SVGElementInstance;\n  if (!OriginalSVGElementInstance)\n    return;\n\n  function SVGElementInstance(impl) {\n    EventTarget.call(this, impl);\n  }\n\n  SVGElementInstance.prototype = Object.create(EventTarget.prototype);\n  mixin(SVGElementInstance.prototype, {\n    /** @type {SVGElement} */\n    get correspondingElement() {\n      return wrap(this.impl.correspondingElement);\n    },\n\n    /** @type {SVGUseElement} */\n    get correspondingUseElement() {\n      return wrap(this.impl.correspondingUseElement);\n    },\n\n    /** @type {SVGElementInstance} */\n    get parentNode() {\n      return wrap(this.impl.parentNode);\n    },\n\n    /** @type {SVGElementInstanceList} */\n    get childNodes() {\n      throw new Error('Not implemented');\n    },\n\n    /** @type {SVGElementInstance} */\n    get firstChild() {\n      return wrap(this.impl.firstChild);\n    },\n\n    /** @type {SVGElementInstance} */\n    get lastChild() {\n      return wrap(this.impl.lastChild);\n    },\n\n    /** @type {SVGElementInstance} */\n    get previousSibling() {\n      return wrap(this.impl.previousSibling);\n    },\n\n    /** @type {SVGElementInstance} */\n    get nextSibling() {\n      return wrap(this.impl.nextSibling);\n    }\n  });\n\n  registerWrapper(OriginalSVGElementInstance, SVGElementInstance);\n\n  scope.wrappers.SVGElementInstance = SVGElementInstance;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;\n\n  function CanvasRenderingContext2D(impl) {\n    this.impl = impl;\n  }\n\n  mixin(CanvasRenderingContext2D.prototype, {\n    get canvas() {\n      return wrap(this.impl.canvas);\n    },\n\n    drawImage: function() {\n      arguments[0] = unwrapIfNeeded(arguments[0]);\n      this.impl.drawImage.apply(this.impl, arguments);\n    },\n\n    createPattern: function() {\n      arguments[0] = unwrap(arguments[0]);\n      return this.impl.createPattern.apply(this.impl, arguments);\n    }\n  });\n\n  registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D,\n                  document.createElement('canvas').getContext('2d'));\n\n  scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalWebGLRenderingContext = window.WebGLRenderingContext;\n\n  // IE10 does not have WebGL.\n  if (!OriginalWebGLRenderingContext)\n    return;\n\n  function WebGLRenderingContext(impl) {\n    this.impl = impl;\n  }\n\n  mixin(WebGLRenderingContext.prototype, {\n    get canvas() {\n      return wrap(this.impl.canvas);\n    },\n\n    texImage2D: function() {\n      arguments[5] = unwrapIfNeeded(arguments[5]);\n      this.impl.texImage2D.apply(this.impl, arguments);\n    },\n\n    texSubImage2D: function() {\n      arguments[6] = unwrapIfNeeded(arguments[6]);\n      this.impl.texSubImage2D.apply(this.impl, arguments);\n    }\n  });\n\n  // Blink/WebKit has broken DOM bindings. Usually we would create an instance\n  // of the object and pass it into registerWrapper as a \"blueprint\" but\n  // creating WebGL contexts is expensive and might fail so we use a dummy\n  // object with dummy instance properties for these broken browsers.\n  var instanceProperties = /WebKit/.test(navigator.userAgent) ?\n      {drawingBufferHeight: null, drawingBufferWidth: null} : {};\n\n  registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext,\n      instanceProperties);\n\n  scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalRange = window.Range;\n\n  function Range(impl) {\n    this.impl = impl;\n  }\n  Range.prototype = {\n    get startContainer() {\n      return wrap(this.impl.startContainer);\n    },\n    get endContainer() {\n      return wrap(this.impl.endContainer);\n    },\n    get commonAncestorContainer() {\n      return wrap(this.impl.commonAncestorContainer);\n    },\n    setStart: function(refNode,offset) {\n      this.impl.setStart(unwrapIfNeeded(refNode), offset);\n    },\n    setEnd: function(refNode,offset) {\n      this.impl.setEnd(unwrapIfNeeded(refNode), offset);\n    },\n    setStartBefore: function(refNode) {\n      this.impl.setStartBefore(unwrapIfNeeded(refNode));\n    },\n    setStartAfter: function(refNode) {\n      this.impl.setStartAfter(unwrapIfNeeded(refNode));\n    },\n    setEndBefore: function(refNode) {\n      this.impl.setEndBefore(unwrapIfNeeded(refNode));\n    },\n    setEndAfter: function(refNode) {\n      this.impl.setEndAfter(unwrapIfNeeded(refNode));\n    },\n    selectNode: function(refNode) {\n      this.impl.selectNode(unwrapIfNeeded(refNode));\n    },\n    selectNodeContents: function(refNode) {\n      this.impl.selectNodeContents(unwrapIfNeeded(refNode));\n    },\n    compareBoundaryPoints: function(how, sourceRange) {\n      return this.impl.compareBoundaryPoints(how, unwrap(sourceRange));\n    },\n    extractContents: function() {\n      return wrap(this.impl.extractContents());\n    },\n    cloneContents: function() {\n      return wrap(this.impl.cloneContents());\n    },\n    insertNode: function(node) {\n      this.impl.insertNode(unwrapIfNeeded(node));\n    },\n    surroundContents: function(newParent) {\n      this.impl.surroundContents(unwrapIfNeeded(newParent));\n    },\n    cloneRange: function() {\n      return wrap(this.impl.cloneRange());\n    },\n    isPointInRange: function(node, offset) {\n      return this.impl.isPointInRange(unwrapIfNeeded(node), offset);\n    },\n    comparePoint: function(node, offset) {\n      return this.impl.comparePoint(unwrapIfNeeded(node), offset);\n    },\n    intersectsNode: function(node) {\n      return this.impl.intersectsNode(unwrapIfNeeded(node));\n    },\n    toString: function() {\n      return this.impl.toString();\n    }\n  };\n\n  // IE9 does not have createContextualFragment.\n  if (OriginalRange.prototype.createContextualFragment) {\n    Range.prototype.createContextualFragment = function(html) {\n      return wrap(this.impl.createContextualFragment(html));\n    };\n  }\n\n  registerWrapper(window.Range, Range, document.createRange());\n\n  scope.wrappers.Range = Range;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var GetElementsByInterface = scope.GetElementsByInterface;\n  var ParentNodeInterface = scope.ParentNodeInterface;\n  var SelectorsInterface = scope.SelectorsInterface;\n  var mixin = scope.mixin;\n  var registerObject = scope.registerObject;\n\n  var DocumentFragment = registerObject(document.createDocumentFragment());\n  mixin(DocumentFragment.prototype, ParentNodeInterface);\n  mixin(DocumentFragment.prototype, SelectorsInterface);\n  mixin(DocumentFragment.prototype, GetElementsByInterface);\n\n  var Comment = registerObject(document.createComment(''));\n\n  scope.wrappers.Comment = Comment;\n  scope.wrappers.DocumentFragment = DocumentFragment;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var DocumentFragment = scope.wrappers.DocumentFragment;\n  var TreeScope = scope.TreeScope;\n  var elementFromPoint = scope.elementFromPoint;\n  var getInnerHTML = scope.getInnerHTML;\n  var getTreeScope = scope.getTreeScope;\n  var mixin = scope.mixin;\n  var rewrap = scope.rewrap;\n  var setInnerHTML = scope.setInnerHTML;\n  var unwrap = scope.unwrap;\n\n  var shadowHostTable = new WeakMap();\n  var nextOlderShadowTreeTable = new WeakMap();\n\n  var spaceCharRe = /[ \\t\\n\\r\\f]/;\n\n  function ShadowRoot(hostWrapper) {\n    var node = unwrap(hostWrapper.impl.ownerDocument.createDocumentFragment());\n    DocumentFragment.call(this, node);\n\n    // createDocumentFragment associates the node with a wrapper\n    // DocumentFragment instance. Override that.\n    rewrap(node, this);\n\n    this.treeScope_ = new TreeScope(this, getTreeScope(hostWrapper));\n\n    var oldShadowRoot = hostWrapper.shadowRoot;\n    nextOlderShadowTreeTable.set(this, oldShadowRoot);\n\n    shadowHostTable.set(this, hostWrapper);\n  }\n  ShadowRoot.prototype = Object.create(DocumentFragment.prototype);\n  mixin(ShadowRoot.prototype, {\n    get innerHTML() {\n      return getInnerHTML(this);\n    },\n    set innerHTML(value) {\n      setInnerHTML(this, value);\n      this.invalidateShadowRenderer();\n    },\n\n    get olderShadowRoot() {\n      return nextOlderShadowTreeTable.get(this) || null;\n    },\n\n    get host() {\n      return shadowHostTable.get(this) || null;\n    },\n\n    invalidateShadowRenderer: function() {\n      return shadowHostTable.get(this).invalidateShadowRenderer();\n    },\n\n    elementFromPoint: function(x, y) {\n      return elementFromPoint(this, this.ownerDocument, x, y);\n    },\n\n    getElementById: function(id) {\n      if (spaceCharRe.test(id))\n        return null;\n      return this.querySelector('[id=\"' + id + '\"]');\n    }\n  });\n\n  scope.wrappers.ShadowRoot = ShadowRoot;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var Element = scope.wrappers.Element;\n  var HTMLContentElement = scope.wrappers.HTMLContentElement;\n  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;\n  var Node = scope.wrappers.Node;\n  var ShadowRoot = scope.wrappers.ShadowRoot;\n  var assert = scope.assert;\n  var getTreeScope = scope.getTreeScope;\n  var mixin = scope.mixin;\n  var oneOf = scope.oneOf;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  /**\n   * Updates the fields of a wrapper to a snapshot of the logical DOM as needed.\n   * Up means parentNode\n   * Sideways means previous and next sibling.\n   * @param {!Node} wrapper\n   */\n  function updateWrapperUpAndSideways(wrapper) {\n    wrapper.previousSibling_ = wrapper.previousSibling;\n    wrapper.nextSibling_ = wrapper.nextSibling;\n    wrapper.parentNode_ = wrapper.parentNode;\n  }\n\n  /**\n   * Updates the fields of a wrapper to a snapshot of the logical DOM as needed.\n   * Down means first and last child\n   * @param {!Node} wrapper\n   */\n  function updateWrapperDown(wrapper) {\n    wrapper.firstChild_ = wrapper.firstChild;\n    wrapper.lastChild_ = wrapper.lastChild;\n  }\n\n  function updateAllChildNodes(parentNodeWrapper) {\n    assert(parentNodeWrapper instanceof Node);\n    for (var childWrapper = parentNodeWrapper.firstChild;\n         childWrapper;\n         childWrapper = childWrapper.nextSibling) {\n      updateWrapperUpAndSideways(childWrapper);\n    }\n    updateWrapperDown(parentNodeWrapper);\n  }\n\n  function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {\n    var parentNode = unwrap(parentNodeWrapper);\n    var newChild = unwrap(newChildWrapper);\n    var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;\n\n    remove(newChildWrapper);\n    updateWrapperUpAndSideways(newChildWrapper);\n\n    if (!refChildWrapper) {\n      parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;\n      if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild)\n        parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;\n\n      var lastChildWrapper = wrap(parentNode.lastChild);\n      if (lastChildWrapper)\n        lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;\n    } else {\n      if (parentNodeWrapper.firstChild === refChildWrapper)\n        parentNodeWrapper.firstChild_ = refChildWrapper;\n\n      refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;\n    }\n\n    parentNode.insertBefore(newChild, refChild);\n  }\n\n  function remove(nodeWrapper) {\n    var node = unwrap(nodeWrapper)\n    var parentNode = node.parentNode;\n    if (!parentNode)\n      return;\n\n    var parentNodeWrapper = wrap(parentNode);\n    updateWrapperUpAndSideways(nodeWrapper);\n\n    if (nodeWrapper.previousSibling)\n      nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;\n    if (nodeWrapper.nextSibling)\n      nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;\n\n    if (parentNodeWrapper.lastChild === nodeWrapper)\n      parentNodeWrapper.lastChild_ = nodeWrapper;\n    if (parentNodeWrapper.firstChild === nodeWrapper)\n      parentNodeWrapper.firstChild_ = nodeWrapper;\n\n    parentNode.removeChild(node);\n  }\n\n  var distributedChildNodesTable = new WeakMap();\n  var eventParentsTable = new WeakMap();\n  var insertionParentTable = new WeakMap();\n  var rendererForHostTable = new WeakMap();\n\n  function distributeChildToInsertionPoint(child, insertionPoint) {\n    getDistributedChildNodes(insertionPoint).push(child);\n    assignToInsertionPoint(child, insertionPoint);\n\n    var eventParents = eventParentsTable.get(child);\n    if (!eventParents)\n      eventParentsTable.set(child, eventParents = []);\n    eventParents.push(insertionPoint);\n  }\n\n  function resetDistributedChildNodes(insertionPoint) {\n    distributedChildNodesTable.set(insertionPoint, []);\n  }\n\n  function getDistributedChildNodes(insertionPoint) {\n    var rv = distributedChildNodesTable.get(insertionPoint);\n    if (!rv)\n      distributedChildNodesTable.set(insertionPoint, rv = []);\n    return rv;\n  }\n\n  function getChildNodesSnapshot(node) {\n    var result = [], i = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      result[i++] = child;\n    }\n    return result;\n  }\n\n  /**\n   * Visits all nodes in the tree that fulfils the |predicate|. If the |visitor|\n   * function returns |false| the traversal is aborted.\n   * @param {!Node} tree\n   * @param {function(!Node) : boolean} predicate\n   * @param {function(!Node) : *} visitor\n   */\n  function visit(tree, predicate, visitor) {\n    // This operates on logical DOM.\n    for (var node = tree.firstChild; node; node = node.nextSibling) {\n      if (predicate(node)) {\n        if (visitor(node) === false)\n          return;\n      } else {\n        visit(node, predicate, visitor);\n      }\n    }\n  }\n\n  // Matching Insertion Points\n  // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#matching-insertion-points\n\n  // TODO(arv): Verify this... I don't remember why I picked this regexp.\n  var selectorMatchRegExp = /^[*.:#[a-zA-Z_|]/;\n\n  var allowedPseudoRegExp = new RegExp('^:(' + [\n    'link',\n    'visited',\n    'target',\n    'enabled',\n    'disabled',\n    'checked',\n    'indeterminate',\n    'nth-child',\n    'nth-last-child',\n    'nth-of-type',\n    'nth-last-of-type',\n    'first-child',\n    'last-child',\n    'first-of-type',\n    'last-of-type',\n    'only-of-type',\n  ].join('|') + ')');\n\n\n  /**\n   * @param {Element} node\n   * @oaram {Element} point The insertion point element.\n   * @return {boolean} Whether the node matches the insertion point.\n   */\n  function matchesCriteria(node, point) {\n    var select = point.getAttribute('select');\n    if (!select)\n      return true;\n\n    // Here we know the select attribute is a non empty string.\n    select = select.trim();\n    if (!select)\n      return true;\n\n    if (!(node instanceof Element))\n      return false;\n\n    // The native matches function in IE9 does not correctly work with elements\n    // that are not in the document.\n    // TODO(arv): Implement matching in JS.\n    // https://github.com/Polymer/ShadowDOM/issues/361\n    if (select === '*' || select === node.localName)\n      return true;\n\n    // TODO(arv): This does not seem right. Need to check for a simple selector.\n    if (!selectorMatchRegExp.test(select))\n      return false;\n\n    // TODO(arv): This no longer matches the spec.\n    if (select[0] === ':' && !allowedPseudoRegExp.test(select))\n      return false;\n\n    try {\n      return node.matches(select);\n    } catch (ex) {\n      // Invalid selector.\n      return false;\n    }\n  }\n\n  var request = oneOf(window, [\n    'requestAnimationFrame',\n    'mozRequestAnimationFrame',\n    'webkitRequestAnimationFrame',\n    'setTimeout'\n  ]);\n\n  var pendingDirtyRenderers = [];\n  var renderTimer;\n\n  function renderAllPending() {\n    // TODO(arv): Order these in document order. That way we do not have to\n    // render something twice.\n    for (var i = 0; i < pendingDirtyRenderers.length; i++) {\n      var renderer = pendingDirtyRenderers[i];\n      var parentRenderer = renderer.parentRenderer;\n      if (parentRenderer && parentRenderer.dirty)\n        continue;\n      renderer.render();\n    }\n\n    pendingDirtyRenderers = [];\n  }\n\n  function handleRequestAnimationFrame() {\n    renderTimer = null;\n    renderAllPending();\n  }\n\n  /**\n   * Returns existing shadow renderer for a host or creates it if it is needed.\n   * @params {!Element} host\n   * @return {!ShadowRenderer}\n   */\n  function getRendererForHost(host) {\n    var renderer = rendererForHostTable.get(host);\n    if (!renderer) {\n      renderer = new ShadowRenderer(host);\n      rendererForHostTable.set(host, renderer);\n    }\n    return renderer;\n  }\n\n  function getShadowRootAncestor(node) {\n    var root = getTreeScope(node).root;\n    if (root instanceof ShadowRoot)\n      return root;\n    return null;\n  }\n\n  function getRendererForShadowRoot(shadowRoot) {\n    return getRendererForHost(shadowRoot.host);\n  }\n\n  var spliceDiff = new ArraySplice();\n  spliceDiff.equals = function(renderNode, rawNode) {\n    return unwrap(renderNode.node) === rawNode;\n  };\n\n  /**\n   * RenderNode is used as an in memory \"render tree\". When we render the\n   * composed tree we create a tree of RenderNodes, then we diff this against\n   * the real DOM tree and make minimal changes as needed.\n   */\n  function RenderNode(node) {\n    this.skip = false;\n    this.node = node;\n    this.childNodes = [];\n  }\n\n  RenderNode.prototype = {\n    append: function(node) {\n      var rv = new RenderNode(node);\n      this.childNodes.push(rv);\n      return rv;\n    },\n\n    sync: function(opt_added) {\n      if (this.skip)\n        return;\n\n      var nodeWrapper = this.node;\n      // plain array of RenderNodes\n      var newChildren = this.childNodes;\n      // plain array of real nodes.\n      var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));\n      var added = opt_added || new WeakMap();\n\n      var splices = spliceDiff.calculateSplices(newChildren, oldChildren);\n\n      var newIndex = 0, oldIndex = 0;\n      var lastIndex = 0;\n      for (var i = 0; i < splices.length; i++) {\n        var splice = splices[i];\n        for (; lastIndex < splice.index; lastIndex++) {\n          oldIndex++;\n          newChildren[newIndex++].sync(added);\n        }\n\n        var removedCount = splice.removed.length;\n        for (var j = 0; j < removedCount; j++) {\n          var wrapper = wrap(oldChildren[oldIndex++]);\n          if (!added.get(wrapper))\n            remove(wrapper);\n        }\n\n        var addedCount = splice.addedCount;\n        var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);\n        for (var j = 0; j < addedCount; j++) {\n          var newChildRenderNode = newChildren[newIndex++];\n          var newChildWrapper = newChildRenderNode.node;\n          insertBefore(nodeWrapper, newChildWrapper, refNode);\n\n          // Keep track of added so that we do not remove the node after it\n          // has been added.\n          added.set(newChildWrapper, true);\n\n          newChildRenderNode.sync(added);\n        }\n\n        lastIndex += addedCount;\n      }\n\n      for (var i = lastIndex; i < newChildren.length; i++) {\n        newChildren[i].sync(added);\n      }\n    }\n  };\n\n  function ShadowRenderer(host) {\n    this.host = host;\n    this.dirty = false;\n    this.invalidateAttributes();\n    this.associateNode(host);\n  }\n\n  ShadowRenderer.prototype = {\n\n    // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#rendering-shadow-trees\n    render: function(opt_renderNode) {\n      if (!this.dirty)\n        return;\n\n      this.invalidateAttributes();\n      this.treeComposition();\n\n      var host = this.host;\n      var shadowRoot = host.shadowRoot;\n\n      this.associateNode(host);\n      var topMostRenderer = !renderNode;\n      var renderNode = opt_renderNode || new RenderNode(host);\n\n      for (var node = shadowRoot.firstChild; node; node = node.nextSibling) {\n        this.renderNode(shadowRoot, renderNode, node, false);\n      }\n\n      if (topMostRenderer)\n        renderNode.sync();\n\n      this.dirty = false;\n    },\n\n    get parentRenderer() {\n      return getTreeScope(this.host).renderer;\n    },\n\n    invalidate: function() {\n      if (!this.dirty) {\n        this.dirty = true;\n        pendingDirtyRenderers.push(this);\n        if (renderTimer)\n          return;\n        renderTimer = window[request](handleRequestAnimationFrame, 0);\n      }\n    },\n\n    renderNode: function(shadowRoot, renderNode, node, isNested) {\n      if (isShadowHost(node)) {\n        renderNode = renderNode.append(node);\n        var renderer = getRendererForHost(node);\n        renderer.dirty = true;  // Need to rerender due to reprojection.\n        renderer.render(renderNode);\n      } else if (isInsertionPoint(node)) {\n        this.renderInsertionPoint(shadowRoot, renderNode, node, isNested);\n      } else if (isShadowInsertionPoint(node)) {\n        this.renderShadowInsertionPoint(shadowRoot, renderNode, node);\n      } else {\n        this.renderAsAnyDomTree(shadowRoot, renderNode, node, isNested);\n      }\n    },\n\n    renderAsAnyDomTree: function(shadowRoot, renderNode, node, isNested) {\n      renderNode = renderNode.append(node);\n\n      if (isShadowHost(node)) {\n        var renderer = getRendererForHost(node);\n        renderNode.skip = !renderer.dirty;\n        renderer.render(renderNode);\n      } else {\n        for (var child = node.firstChild; child; child = child.nextSibling) {\n          this.renderNode(shadowRoot, renderNode, child, isNested);\n        }\n      }\n    },\n\n    renderInsertionPoint: function(shadowRoot, renderNode, insertionPoint,\n                                   isNested) {\n      var distributedChildNodes = getDistributedChildNodes(insertionPoint);\n      if (distributedChildNodes.length) {\n        this.associateNode(insertionPoint);\n\n        for (var i = 0; i < distributedChildNodes.length; i++) {\n          var child = distributedChildNodes[i];\n          if (isInsertionPoint(child) && isNested)\n            this.renderInsertionPoint(shadowRoot, renderNode, child, isNested);\n          else\n            this.renderAsAnyDomTree(shadowRoot, renderNode, child, isNested);\n        }\n      } else {\n        this.renderFallbackContent(shadowRoot, renderNode, insertionPoint);\n      }\n      this.associateNode(insertionPoint.parentNode);\n    },\n\n    renderShadowInsertionPoint: function(shadowRoot, renderNode,\n                                         shadowInsertionPoint) {\n      var nextOlderTree = shadowRoot.olderShadowRoot;\n      if (nextOlderTree) {\n        assignToInsertionPoint(nextOlderTree, shadowInsertionPoint);\n        this.associateNode(shadowInsertionPoint.parentNode);\n        for (var node = nextOlderTree.firstChild;\n             node;\n             node = node.nextSibling) {\n          this.renderNode(nextOlderTree, renderNode, node, true);\n        }\n      } else {\n        this.renderFallbackContent(shadowRoot, renderNode,\n                                   shadowInsertionPoint);\n      }\n    },\n\n    renderFallbackContent: function(shadowRoot, renderNode, fallbackHost) {\n      this.associateNode(fallbackHost);\n      this.associateNode(fallbackHost.parentNode);\n      for (var node = fallbackHost.firstChild; node; node = node.nextSibling) {\n        this.renderAsAnyDomTree(shadowRoot, renderNode, node, false);\n      }\n    },\n\n    /**\n     * Invalidates the attributes used to keep track of which attributes may\n     * cause the renderer to be invalidated.\n     */\n    invalidateAttributes: function() {\n      this.attributes = Object.create(null);\n    },\n\n    /**\n     * Parses the selector and makes this renderer dependent on the attribute\n     * being used in the selector.\n     * @param {string} selector\n     */\n    updateDependentAttributes: function(selector) {\n      if (!selector)\n        return;\n\n      var attributes = this.attributes;\n\n      // .class\n      if (/\\.\\w+/.test(selector))\n        attributes['class'] = true;\n\n      // #id\n      if (/#\\w+/.test(selector))\n        attributes['id'] = true;\n\n      selector.replace(/\\[\\s*([^\\s=\\|~\\]]+)/g, function(_, name) {\n        attributes[name] = true;\n      });\n\n      // Pseudo selectors have been removed from the spec.\n    },\n\n    dependsOnAttribute: function(name) {\n      return this.attributes[name];\n    },\n\n    // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-distribution-algorithm\n    distribute: function(tree, pool) {\n      var self = this;\n\n      visit(tree, isActiveInsertionPoint,\n          function(insertionPoint) {\n            resetDistributedChildNodes(insertionPoint);\n            self.updateDependentAttributes(\n                insertionPoint.getAttribute('select'));\n\n            for (var i = 0; i < pool.length; i++) {  // 1.2\n              var node = pool[i];  // 1.2.1\n              if (node === undefined)  // removed\n                continue;\n              if (matchesCriteria(node, insertionPoint)) {  // 1.2.2\n                distributeChildToInsertionPoint(node, insertionPoint);  // 1.2.2.1\n                pool[i] = undefined;  // 1.2.2.2\n              }\n            }\n          });\n    },\n\n    // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-tree-composition\n    treeComposition: function () {\n      var shadowHost = this.host;\n      var tree = shadowHost.shadowRoot;  // 1.\n      var pool = [];  // 2.\n\n      for (var child = shadowHost.firstChild;\n           child;\n           child = child.nextSibling) {  // 3.\n        if (isInsertionPoint(child)) {  // 3.2.\n          var reprojected = getDistributedChildNodes(child);  // 3.2.1.\n          // if reprojected is undef... reset it?\n          if (!reprojected || !reprojected.length)  // 3.2.2.\n            reprojected = getChildNodesSnapshot(child);\n          pool.push.apply(pool, reprojected);  // 3.2.3.\n        } else {\n          pool.push(child); // 3.3.\n        }\n      }\n\n      var shadowInsertionPoint, point;\n      while (tree) {  // 4.\n        // 4.1.\n        shadowInsertionPoint = undefined;  // Reset every iteration.\n        visit(tree, isActiveShadowInsertionPoint, function(point) {\n          shadowInsertionPoint = point;\n          return false;\n        });\n        point = shadowInsertionPoint;\n\n        this.distribute(tree, pool);  // 4.2.\n        if (point) {  // 4.3.\n          var nextOlderTree = tree.olderShadowRoot;  // 4.3.1.\n          if (!nextOlderTree) {\n            break;  // 4.3.1.1.\n          } else {\n            tree = nextOlderTree;  // 4.3.2.2.\n            assignToInsertionPoint(tree, point);  // 4.3.2.2.\n            continue;  // 4.3.2.3.\n          }\n        } else {\n          break;  // 4.4.\n        }\n      }\n    },\n\n    associateNode: function(node) {\n      node.impl.polymerShadowRenderer_ = this;\n    }\n  };\n\n  function isInsertionPoint(node) {\n    // Should this include <shadow>?\n    return node instanceof HTMLContentElement;\n  }\n\n  function isActiveInsertionPoint(node) {\n    // <content> inside another <content> or <shadow> is considered inactive.\n    return node instanceof HTMLContentElement;\n  }\n\n  function isShadowInsertionPoint(node) {\n    return node instanceof HTMLShadowElement;\n  }\n\n  function isActiveShadowInsertionPoint(node) {\n    // <shadow> inside another <content> or <shadow> is considered inactive.\n    return node instanceof HTMLShadowElement;\n  }\n\n  function isShadowHost(shadowHost) {\n    return shadowHost.shadowRoot;\n  }\n\n  function getShadowTrees(host) {\n    var trees = [];\n\n    for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {\n      trees.push(tree);\n    }\n    return trees;\n  }\n\n  function assignToInsertionPoint(tree, point) {\n    insertionParentTable.set(tree, point);\n  }\n\n  // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#rendering-shadow-trees\n  function render(host) {\n    new ShadowRenderer(host).render();\n  };\n\n  // Need to rerender shadow host when:\n  //\n  // - a direct child to the ShadowRoot is added or removed\n  // - a direct child to the host is added or removed\n  // - a new shadow root is created\n  // - a direct child to a content/shadow element is added or removed\n  // - a sibling to a content/shadow element is added or removed\n  // - content[select] is changed\n  // - an attribute in a direct child to a host is modified\n\n  /**\n   * This gets called when a node was added or removed to it.\n   */\n  Node.prototype.invalidateShadowRenderer = function(force) {\n    var renderer = this.impl.polymerShadowRenderer_;\n    if (renderer) {\n      renderer.invalidate();\n      return true;\n    }\n\n    return false;\n  };\n\n  HTMLContentElement.prototype.getDistributedNodes = function() {\n    // TODO(arv): We should only rerender the dirty ancestor renderers (from\n    // the root and down).\n    renderAllPending();\n    return getDistributedChildNodes(this);\n  };\n\n  HTMLShadowElement.prototype.nodeIsInserted_ =\n  HTMLContentElement.prototype.nodeIsInserted_ = function() {\n    // Invalidate old renderer if any.\n    this.invalidateShadowRenderer();\n\n    var shadowRoot = getShadowRootAncestor(this);\n    var renderer;\n    if (shadowRoot)\n      renderer = getRendererForShadowRoot(shadowRoot);\n    this.impl.polymerShadowRenderer_ = renderer;\n    if (renderer)\n      renderer.invalidate();\n  };\n\n  scope.eventParentsTable = eventParentsTable;\n  scope.getRendererForHost = getRendererForHost;\n  scope.getShadowTrees = getShadowTrees;\n  scope.insertionParentTable = insertionParentTable;\n  scope.renderAllPending = renderAllPending;\n\n  // Exposed for testing\n  scope.visual = {\n    insertBefore: insertBefore,\n    remove: remove,\n  };\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var HTMLElement = scope.wrappers.HTMLElement;\n  var assert = scope.assert;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n\n  var elementsWithFormProperty = [\n    'HTMLButtonElement',\n    'HTMLFieldSetElement',\n    'HTMLInputElement',\n    'HTMLKeygenElement',\n    'HTMLLabelElement',\n    'HTMLLegendElement',\n    'HTMLObjectElement',\n    // HTMLOptionElement is handled in HTMLOptionElement.js\n    'HTMLOutputElement',\n    // HTMLSelectElement is handled in HTMLSelectElement.js\n    'HTMLTextAreaElement',\n  ];\n\n  function createWrapperConstructor(name) {\n    if (!window[name])\n      return;\n\n    // Ensure we are not overriding an already existing constructor.\n    assert(!scope.wrappers[name]);\n\n    var GeneratedWrapper = function(node) {\n      // At this point all of them extend HTMLElement.\n      HTMLElement.call(this, node);\n    }\n    GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);\n    mixin(GeneratedWrapper.prototype, {\n      get form() {\n        return wrap(unwrap(this).form);\n      },\n    });\n\n    registerWrapper(window[name], GeneratedWrapper,\n        document.createElement(name.slice(4, -7)));\n    scope.wrappers[name] = GeneratedWrapper;\n  }\n\n  elementsWithFormProperty.forEach(createWrapperConstructor);\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2014 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var registerWrapper = scope.registerWrapper;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalSelection = window.Selection;\n\n  function Selection(impl) {\n    this.impl = impl;\n  }\n  Selection.prototype = {\n    get anchorNode() {\n      return wrap(this.impl.anchorNode);\n    },\n    get focusNode() {\n      return wrap(this.impl.focusNode);\n    },\n    addRange: function(range) {\n      this.impl.addRange(unwrap(range));\n    },\n    collapse: function(node, index) {\n      this.impl.collapse(unwrapIfNeeded(node), index);\n    },\n    containsNode: function(node, allowPartial) {\n      return this.impl.containsNode(unwrapIfNeeded(node), allowPartial);\n    },\n    extend: function(node, offset) {\n      this.impl.extend(unwrapIfNeeded(node), offset);\n    },\n    getRangeAt: function(index) {\n      return wrap(this.impl.getRangeAt(index));\n    },\n    removeRange: function(range) {\n      this.impl.removeRange(unwrap(range));\n    },\n    selectAllChildren: function(node) {\n      this.impl.selectAllChildren(unwrapIfNeeded(node));\n    },\n    toString: function() {\n      return this.impl.toString();\n    }\n  };\n\n  // WebKit extensions. Not implemented.\n  // readonly attribute Node baseNode;\n  // readonly attribute long baseOffset;\n  // readonly attribute Node extentNode;\n  // readonly attribute long extentOffset;\n  // [RaisesException] void setBaseAndExtent([Default=Undefined] optional Node baseNode,\n  //                       [Default=Undefined] optional long baseOffset,\n  //                       [Default=Undefined] optional Node extentNode,\n  //                       [Default=Undefined] optional long extentOffset);\n  // [RaisesException, ImplementedAs=collapse] void setPosition([Default=Undefined] optional Node node,\n  //                  [Default=Undefined] optional long offset);\n\n  registerWrapper(window.Selection, Selection, window.getSelection());\n\n  scope.wrappers.Selection = Selection;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var GetElementsByInterface = scope.GetElementsByInterface;\n  var Node = scope.wrappers.Node;\n  var ParentNodeInterface = scope.ParentNodeInterface;\n  var Selection = scope.wrappers.Selection;\n  var SelectorsInterface = scope.SelectorsInterface;\n  var ShadowRoot = scope.wrappers.ShadowRoot;\n  var TreeScope = scope.TreeScope;\n  var cloneNode = scope.cloneNode;\n  var defineWrapGetter = scope.defineWrapGetter;\n  var elementFromPoint = scope.elementFromPoint;\n  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;\n  var matchesNames = scope.matchesNames;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var renderAllPending = scope.renderAllPending;\n  var rewrap = scope.rewrap;\n  var unwrap = scope.unwrap;\n  var wrap = scope.wrap;\n  var wrapEventTargetMethods = scope.wrapEventTargetMethods;\n  var wrapNodeList = scope.wrapNodeList;\n\n  var implementationTable = new WeakMap();\n\n  function Document(node) {\n    Node.call(this, node);\n    this.treeScope_ = new TreeScope(this, null);\n  }\n  Document.prototype = Object.create(Node.prototype);\n\n  defineWrapGetter(Document, 'documentElement');\n\n  // Conceptually both body and head can be in a shadow but suporting that seems\n  // overkill at this point.\n  defineWrapGetter(Document, 'body');\n  defineWrapGetter(Document, 'head');\n\n  // document cannot be overridden so we override a bunch of its methods\n  // directly on the instance.\n\n  function wrapMethod(name) {\n    var original = document[name];\n    Document.prototype[name] = function() {\n      return wrap(original.apply(this.impl, arguments));\n    };\n  }\n\n  [\n    'createComment',\n    'createDocumentFragment',\n    'createElement',\n    'createElementNS',\n    'createEvent',\n    'createEventNS',\n    'createRange',\n    'createTextNode',\n    'getElementById'\n  ].forEach(wrapMethod);\n\n  var originalAdoptNode = document.adoptNode;\n\n  function adoptNodeNoRemove(node, doc) {\n    originalAdoptNode.call(doc.impl, unwrap(node));\n    adoptSubtree(node, doc);\n  }\n\n  function adoptSubtree(node, doc) {\n    if (node.shadowRoot)\n      doc.adoptNode(node.shadowRoot);\n    if (node instanceof ShadowRoot)\n      adoptOlderShadowRoots(node, doc);\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      adoptSubtree(child, doc);\n    }\n  }\n\n  function adoptOlderShadowRoots(shadowRoot, doc) {\n    var oldShadowRoot = shadowRoot.olderShadowRoot;\n    if (oldShadowRoot)\n      doc.adoptNode(oldShadowRoot);\n  }\n\n  var originalGetSelection = document.getSelection;\n\n  mixin(Document.prototype, {\n    adoptNode: function(node) {\n      if (node.parentNode)\n        node.parentNode.removeChild(node);\n      adoptNodeNoRemove(node, this);\n      return node;\n    },\n    elementFromPoint: function(x, y) {\n      return elementFromPoint(this, this, x, y);\n    },\n    importNode: function(node, deep) {\n      return cloneNode(node, deep, this.impl);\n    },\n    getSelection: function() {\n      renderAllPending();\n      return new Selection(originalGetSelection.call(unwrap(this)));\n    }\n  });\n\n  if (document.registerElement) {\n    var originalRegisterElement = document.registerElement;\n    Document.prototype.registerElement = function(tagName, object) {\n      var prototype = object.prototype;\n\n      // If we already used the object as a prototype for another custom\n      // element.\n      if (scope.nativePrototypeTable.get(prototype)) {\n        // TODO(arv): DOMException\n        throw new Error('NotSupportedError');\n      }\n\n      // Find first object on the prototype chain that already have a native\n      // prototype. Keep track of all the objects before that so we can create\n      // a similar structure for the native case.\n      var proto = Object.getPrototypeOf(prototype);\n      var nativePrototype;\n      var prototypes = [];\n      while (proto) {\n        nativePrototype = scope.nativePrototypeTable.get(proto);\n        if (nativePrototype)\n          break;\n        prototypes.push(proto);\n        proto = Object.getPrototypeOf(proto);\n      }\n\n      if (!nativePrototype) {\n        // TODO(arv): DOMException\n        throw new Error('NotSupportedError');\n      }\n\n      // This works by creating a new prototype object that is empty, but has\n      // the native prototype as its proto. The original prototype object\n      // passed into register is used as the wrapper prototype.\n\n      var newPrototype = Object.create(nativePrototype);\n      for (var i = prototypes.length - 1; i >= 0; i--) {\n        newPrototype = Object.create(newPrototype);\n      }\n\n      // Add callbacks if present.\n      // Names are taken from:\n      //   https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.cpp&sq=package:chromium&type=cs&l=156\n      // and not from the spec since the spec is out of date.\n      [\n        'createdCallback',\n        'attachedCallback',\n        'detachedCallback',\n        'attributeChangedCallback',\n      ].forEach(function(name) {\n        var f = prototype[name];\n        if (!f)\n          return;\n        newPrototype[name] = function() {\n          // if this element has been wrapped prior to registration,\n          // the wrapper is stale; in this case rewrap\n          if (!(wrap(this) instanceof CustomElementConstructor)) {\n            rewrap(this);\n          }\n          f.apply(wrap(this), arguments);\n        };\n      });\n\n      var p = {prototype: newPrototype};\n      if (object.extends)\n        p.extends = object.extends;\n\n      function CustomElementConstructor(node) {\n        if (!node) {\n          if (object.extends) {\n            return document.createElement(object.extends, tagName);\n          } else {\n            return document.createElement(tagName);\n          }\n        }\n        this.impl = node;\n      }\n      CustomElementConstructor.prototype = prototype;\n      CustomElementConstructor.prototype.constructor = CustomElementConstructor;\n\n      scope.constructorTable.set(newPrototype, CustomElementConstructor);\n      scope.nativePrototypeTable.set(prototype, newPrototype);\n\n      // registration is synchronous so do it last\n      var nativeConstructor = originalRegisterElement.call(unwrap(this),\n          tagName, p);\n      return CustomElementConstructor;\n    };\n\n    forwardMethodsToWrapper([\n      window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument\n    ], [\n      'registerElement',\n    ]);\n  }\n\n  // We also override some of the methods on document.body and document.head\n  // for convenience.\n  forwardMethodsToWrapper([\n    window.HTMLBodyElement,\n    window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument\n    window.HTMLHeadElement,\n    window.HTMLHtmlElement,\n  ], [\n    'appendChild',\n    'compareDocumentPosition',\n    'contains',\n    'getElementsByClassName',\n    'getElementsByTagName',\n    'getElementsByTagNameNS',\n    'insertBefore',\n    'querySelector',\n    'querySelectorAll',\n    'removeChild',\n    'replaceChild',\n  ].concat(matchesNames));\n\n  forwardMethodsToWrapper([\n    window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument\n  ], [\n    'adoptNode',\n    'importNode',\n    'contains',\n    'createComment',\n    'createDocumentFragment',\n    'createElement',\n    'createElementNS',\n    'createEvent',\n    'createEventNS',\n    'createRange',\n    'createTextNode',\n    'elementFromPoint',\n    'getElementById',\n    'getSelection',\n  ]);\n\n  mixin(Document.prototype, GetElementsByInterface);\n  mixin(Document.prototype, ParentNodeInterface);\n  mixin(Document.prototype, SelectorsInterface);\n\n  mixin(Document.prototype, {\n    get implementation() {\n      var implementation = implementationTable.get(this);\n      if (implementation)\n        return implementation;\n      implementation =\n          new DOMImplementation(unwrap(this).implementation);\n      implementationTable.set(this, implementation);\n      return implementation;\n    }\n  });\n\n  registerWrapper(window.Document, Document,\n      document.implementation.createHTMLDocument(''));\n\n  // Both WebKit and Gecko uses HTMLDocument for document. HTML5/DOM only has\n  // one Document interface and IE implements the standard correctly.\n  if (window.HTMLDocument)\n    registerWrapper(window.HTMLDocument, Document);\n\n  wrapEventTargetMethods([\n    window.HTMLBodyElement,\n    window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument\n    window.HTMLHeadElement,\n  ]);\n\n  function DOMImplementation(impl) {\n    this.impl = impl;\n  }\n\n  function wrapImplMethod(constructor, name) {\n    var original = document.implementation[name];\n    constructor.prototype[name] = function() {\n      return wrap(original.apply(this.impl, arguments));\n    };\n  }\n\n  function forwardImplMethod(constructor, name) {\n    var original = document.implementation[name];\n    constructor.prototype[name] = function() {\n      return original.apply(this.impl, arguments);\n    };\n  }\n\n  wrapImplMethod(DOMImplementation, 'createDocumentType');\n  wrapImplMethod(DOMImplementation, 'createDocument');\n  wrapImplMethod(DOMImplementation, 'createHTMLDocument');\n  forwardImplMethod(DOMImplementation, 'hasFeature');\n\n  registerWrapper(window.DOMImplementation, DOMImplementation);\n\n  forwardMethodsToWrapper([\n    window.DOMImplementation,\n  ], [\n    'createDocumentType',\n    'createDocument',\n    'createHTMLDocument',\n    'hasFeature',\n  ]);\n\n  scope.adoptNodeNoRemove = adoptNodeNoRemove;\n  scope.wrappers.DOMImplementation = DOMImplementation;\n  scope.wrappers.Document = Document;\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var EventTarget = scope.wrappers.EventTarget;\n  var Selection = scope.wrappers.Selection;\n  var mixin = scope.mixin;\n  var registerWrapper = scope.registerWrapper;\n  var renderAllPending = scope.renderAllPending;\n  var unwrap = scope.unwrap;\n  var unwrapIfNeeded = scope.unwrapIfNeeded;\n  var wrap = scope.wrap;\n\n  var OriginalWindow = window.Window;\n  var originalGetComputedStyle = window.getComputedStyle;\n  var originalGetSelection = window.getSelection;\n\n  function Window(impl) {\n    EventTarget.call(this, impl);\n  }\n  Window.prototype = Object.create(EventTarget.prototype);\n\n  OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {\n    return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);\n  };\n\n  OriginalWindow.prototype.getSelection = function() {\n    return wrap(this || window).getSelection();\n  };\n\n  // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065\n  delete window.getComputedStyle;\n  delete window.getSelection;\n\n  ['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(\n      function(name) {\n        OriginalWindow.prototype[name] = function() {\n          var w = wrap(this || window);\n          return w[name].apply(w, arguments);\n        };\n\n        // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065\n        delete window[name];\n      });\n\n  mixin(Window.prototype, {\n    getComputedStyle: function(el, pseudo) {\n      renderAllPending();\n      return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el),\n                                           pseudo);\n    },\n    getSelection: function() {\n      renderAllPending();\n      return new Selection(originalGetSelection.call(unwrap(this)));\n    },\n  });\n\n  registerWrapper(OriginalWindow, Window);\n\n  scope.wrappers.Window = Window;\n\n})(window.ShadowDOMPolyfill);\n","/**\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var unwrap = scope.unwrap;\n\n  // DataTransfer (Clipboard in old Blink/WebKit) has a single method that\n  // requires wrapping. Since it is only a method we do not need a real wrapper,\n  // we can just override the method.\n\n  var OriginalDataTransfer = window.DataTransfer || window.Clipboard;\n  var OriginalDataTransferSetDragImage =\n      OriginalDataTransfer.prototype.setDragImage;\n\n  OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {\n    OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);\n  };\n\n})(window.ShadowDOMPolyfill);\n","// Copyright 2013 The Polymer Authors. All rights reserved.\n// Use of this source code is goverened by a BSD-style\n// license that can be found in the LICENSE file.\n\n(function(scope) {\n  'use strict';\n\n  var isWrapperFor = scope.isWrapperFor;\n\n  // This is a list of the elements we currently override the global constructor\n  // for.\n  var elements = {\n    'a': 'HTMLAnchorElement',\n    // Do not create an applet element by default since it shows a warning in\n    // IE.\n    // https://github.com/Polymer/polymer/issues/217\n    // 'applet': 'HTMLAppletElement',\n    'area': 'HTMLAreaElement',\n    'audio': 'HTMLAudioElement',\n    'base': 'HTMLBaseElement',\n    'body': 'HTMLBodyElement',\n    'br': 'HTMLBRElement',\n    'button': 'HTMLButtonElement',\n    'canvas': 'HTMLCanvasElement',\n    'caption': 'HTMLTableCaptionElement',\n    'col': 'HTMLTableColElement',\n    // 'command': 'HTMLCommandElement',  // Not fully implemented in Gecko.\n    'content': 'HTMLContentElement',\n    'data': 'HTMLDataElement',\n    'datalist': 'HTMLDataListElement',\n    'del': 'HTMLModElement',\n    'dir': 'HTMLDirectoryElement',\n    'div': 'HTMLDivElement',\n    'dl': 'HTMLDListElement',\n    'embed': 'HTMLEmbedElement',\n    'fieldset': 'HTMLFieldSetElement',\n    'font': 'HTMLFontElement',\n    'form': 'HTMLFormElement',\n    'frame': 'HTMLFrameElement',\n    'frameset': 'HTMLFrameSetElement',\n    'h1': 'HTMLHeadingElement',\n    'head': 'HTMLHeadElement',\n    'hr': 'HTMLHRElement',\n    'html': 'HTMLHtmlElement',\n    'iframe': 'HTMLIFrameElement',\n    'img': 'HTMLImageElement',\n    'input': 'HTMLInputElement',\n    'keygen': 'HTMLKeygenElement',\n    'label': 'HTMLLabelElement',\n    'legend': 'HTMLLegendElement',\n    'li': 'HTMLLIElement',\n    'link': 'HTMLLinkElement',\n    'map': 'HTMLMapElement',\n    'marquee': 'HTMLMarqueeElement',\n    'menu': 'HTMLMenuElement',\n    'menuitem': 'HTMLMenuItemElement',\n    'meta': 'HTMLMetaElement',\n    'meter': 'HTMLMeterElement',\n    'object': 'HTMLObjectElement',\n    'ol': 'HTMLOListElement',\n    'optgroup': 'HTMLOptGroupElement',\n    'option': 'HTMLOptionElement',\n    'output': 'HTMLOutputElement',\n    'p': 'HTMLParagraphElement',\n    'param': 'HTMLParamElement',\n    'pre': 'HTMLPreElement',\n    'progress': 'HTMLProgressElement',\n    'q': 'HTMLQuoteElement',\n    'script': 'HTMLScriptElement',\n    'select': 'HTMLSelectElement',\n    'shadow': 'HTMLShadowElement',\n    'source': 'HTMLSourceElement',\n    'span': 'HTMLSpanElement',\n    'style': 'HTMLStyleElement',\n    'table': 'HTMLTableElement',\n    'tbody': 'HTMLTableSectionElement',\n    // WebKit and Moz are wrong:\n    // https://bugs.webkit.org/show_bug.cgi?id=111469\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=848096\n    // 'td': 'HTMLTableCellElement',\n    'template': 'HTMLTemplateElement',\n    'textarea': 'HTMLTextAreaElement',\n    'thead': 'HTMLTableSectionElement',\n    'time': 'HTMLTimeElement',\n    'title': 'HTMLTitleElement',\n    'tr': 'HTMLTableRowElement',\n    'track': 'HTMLTrackElement',\n    'ul': 'HTMLUListElement',\n    'video': 'HTMLVideoElement',\n  };\n\n  function overrideConstructor(tagName) {\n    var nativeConstructorName = elements[tagName];\n    var nativeConstructor = window[nativeConstructorName];\n    if (!nativeConstructor)\n      return;\n    var element = document.createElement(tagName);\n    var wrapperConstructor = element.constructor;\n    window[nativeConstructorName] = wrapperConstructor;\n  }\n\n  Object.keys(elements).forEach(overrideConstructor);\n\n  Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {\n    window[name] = scope.wrappers[name]\n  });\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function() {\n\n  // convenient global\n  window.wrap = ShadowDOMPolyfill.wrapIfNeeded;\n  window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;\n\n  // users may want to customize other types\n  // TODO(sjmiles): 'button' is now supported by ShadowDOMPolyfill, but\n  // I've left this code here in case we need to temporarily patch another\n  // type\n  /*\n  (function() {\n    var elts = {HTMLButtonElement: 'button'};\n    for (var c in elts) {\n      window[c] = function() { throw 'Patched Constructor'; };\n      window[c].prototype = Object.getPrototypeOf(\n          document.createElement(elts[c]));\n    }\n  })();\n  */\n\n  // patch in prefixed name\n  Object.defineProperty(Element.prototype, 'webkitShadowRoot',\n      Object.getOwnPropertyDescriptor(Element.prototype, 'shadowRoot'));\n\n  var originalCreateShadowRoot = Element.prototype.createShadowRoot;\n  Element.prototype.createShadowRoot = function() {\n    var root = originalCreateShadowRoot.call(this);\n    CustomElements.watchShadow(this);\n    return root;\n  };\n\n  Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;\n})();\n","/*\n * Copyright 2012 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/*\n  This is a limited shim for ShadowDOM css styling.\n  https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#styles\n  \n  The intention here is to support only the styling features which can be \n  relatively simply implemented. The goal is to allow users to avoid the \n  most obvious pitfalls and do so without compromising performance significantly. \n  For ShadowDOM styling that's not covered here, a set of best practices\n  can be provided that should allow users to accomplish more complex styling.\n\n  The following is a list of specific ShadowDOM styling features and a brief\n  discussion of the approach used to shim.\n\n  Shimmed features:\n\n  * :host, :ancestor: ShadowDOM allows styling of the shadowRoot's host\n  element using the :host rule. To shim this feature, the :host styles are \n  reformatted and prefixed with a given scope name and promoted to a \n  document level stylesheet.\n  For example, given a scope name of .foo, a rule like this:\n  \n    :host {\n        background: red;\n      }\n    }\n  \n  becomes:\n  \n    .foo {\n      background: red;\n    }\n  \n  * encapsultion: Styles defined within ShadowDOM, apply only to \n  dom inside the ShadowDOM. Polymer uses one of two techniques to imlement\n  this feature.\n  \n  By default, rules are prefixed with the host element tag name \n  as a descendant selector. This ensures styling does not leak out of the 'top'\n  of the element's ShadowDOM. For example,\n\n  div {\n      font-weight: bold;\n    }\n  \n  becomes:\n\n  x-foo div {\n      font-weight: bold;\n    }\n  \n  becomes:\n\n\n  Alternatively, if Platform.ShadowCSS.strictStyling is set to true then \n  selectors are scoped by adding an attribute selector suffix to each\n  simple selector that contains the host element tag name. Each element \n  in the element's ShadowDOM template is also given the scope attribute. \n  Thus, these rules match only elements that have the scope attribute.\n  For example, given a scope name of x-foo, a rule like this:\n  \n    div {\n      font-weight: bold;\n    }\n  \n  becomes:\n  \n    div[x-foo] {\n      font-weight: bold;\n    }\n\n  Note that elements that are dynamically added to a scope must have the scope\n  selector added to them manually.\n\n  * upper/lower bound encapsulation: Styles which are defined outside a\n  shadowRoot should not cross the ShadowDOM boundary and should not apply\n  inside a shadowRoot.\n\n  This styling behavior is not emulated. Some possible ways to do this that \n  were rejected due to complexity and/or performance concerns include: (1) reset\n  every possible property for every possible selector for a given scope name;\n  (2) re-implement css in javascript.\n  \n  As an alternative, users should make sure to use selectors\n  specific to the scope in which they are working.\n  \n  * ::distributed: This behavior is not emulated. It's often not necessary\n  to style the contents of a specific insertion point and instead, descendants\n  of the host element can be styled selectively. Users can also create an \n  extra node around an insertion point and style that node's contents\n  via descendent selectors. For example, with a shadowRoot like this:\n  \n    <style>\n      ::content(div) {\n        background: red;\n      }\n    </style>\n    <content></content>\n  \n  could become:\n  \n    <style>\n      / *@polyfill .content-container div * / \n      ::content(div) {\n        background: red;\n      }\n    </style>\n    <div class=\"content-container\">\n      <content></content>\n    </div>\n  \n  Note the use of @polyfill in the comment above a ShadowDOM specific style\n  declaration. This is a directive to the styling shim to use the selector \n  in comments in lieu of the next selector when running under polyfill.\n*/\n(function(scope) {\n\nvar ShadowCSS = {\n  strictStyling: false,\n  registry: {},\n  // Shim styles for a given root associated with a name and extendsName\n  // 1. cache root styles by name\n  // 2. optionally tag root nodes with scope name\n  // 3. shim polyfill directives /* @polyfill */ and /* @polyfill-rule */\n  // 4. shim :host and scoping\n  shimStyling: function(root, name, extendsName) {\n    var scopeStyles = this.prepareRoot(root, name, extendsName);\n    var typeExtension = this.isTypeExtension(extendsName);\n    var scopeSelector = this.makeScopeSelector(name, typeExtension);\n    // use caching to make working with styles nodes easier and to facilitate\n    // lookup of extendee\n    var cssText = stylesToCssText(scopeStyles, true);\n    cssText = this.scopeCssText(cssText, scopeSelector);\n    // cache shimmed css on root for user extensibility\n    if (root) {\n      root.shimmedStyle = cssText;\n    }\n    // add style to document\n    this.addCssToDocument(cssText, name);\n  },\n  /*\n  * Shim a style element with the given selector. Returns cssText that can\n  * be included in the document via Platform.ShadowCSS.addCssToDocument(css).\n  */\n  shimStyle: function(style, selector) {\n    return this.shimCssText(style.textContent, selector);\n  },\n  /*\n  * Shim some cssText with the given selector. Returns cssText that can\n  * be included in the document via Platform.ShadowCSS.addCssToDocument(css).\n  */\n  shimCssText: function(cssText, selector) {\n    cssText = this.insertDirectives(cssText);\n    return this.scopeCssText(cssText, selector);\n  },\n  makeScopeSelector: function(name, typeExtension) {\n    if (name) {\n      return typeExtension ? '[is=' + name + ']' : name;\n    }\n    return '';\n  },\n  isTypeExtension: function(extendsName) {\n    return extendsName && extendsName.indexOf('-') < 0;\n  },\n  prepareRoot: function(root, name, extendsName) {\n    var def = this.registerRoot(root, name, extendsName);\n    this.replaceTextInStyles(def.rootStyles, this.insertDirectives);\n    // remove existing style elements\n    this.removeStyles(root, def.rootStyles);\n    // apply strict attr\n    if (this.strictStyling) {\n      this.applyScopeToContent(root, name);\n    }\n    return def.scopeStyles;\n  },\n  removeStyles: function(root, styles) {\n    for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {\n      s.parentNode.removeChild(s);\n    }\n  },\n  registerRoot: function(root, name, extendsName) {\n    var def = this.registry[name] = {\n      root: root,\n      name: name,\n      extendsName: extendsName\n    }\n    var styles = this.findStyles(root);\n    def.rootStyles = styles;\n    def.scopeStyles = def.rootStyles;\n    var extendee = this.registry[def.extendsName];\n    if (extendee && (!root || root.querySelector('shadow'))) {\n      def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);\n    }\n    return def;\n  },\n  findStyles: function(root) {\n    if (!root) {\n      return [];\n    }\n    var styles = root.querySelectorAll('style');\n    return Array.prototype.filter.call(styles, function(s) {\n      return !s.hasAttribute(NO_SHIM_ATTRIBUTE);\n    });\n  },\n  applyScopeToContent: function(root, name) {\n    if (root) {\n      // add the name attribute to each node in root.\n      Array.prototype.forEach.call(root.querySelectorAll('*'),\n          function(node) {\n            node.setAttribute(name, '');\n          });\n      // and template contents too\n      Array.prototype.forEach.call(root.querySelectorAll('template'),\n          function(template) {\n            this.applyScopeToContent(template.content, name);\n          },\n          this);\n    }\n  },\n  insertDirectives: function(cssText) {\n    cssText = this.insertPolyfillDirectivesInCssText(cssText);\n    return this.insertPolyfillRulesInCssText(cssText);\n  },\n  /*\n   * Process styles to convert native ShadowDOM rules that will trip\n   * up the css parser; we rely on decorating the stylesheet with inert rules.\n   * \n   * For example, we convert this rule:\n   * \n   * polyfill-next-selector { content: ':host menu-item'; }\n   * ::content menu-item {\n   * \n   * to this:\n   * \n   * scopeName menu-item {\n   *\n  **/\n  insertPolyfillDirectivesInCssText: function(cssText) {\n    // TODO(sorvell): remove either content or comment\n    cssText = cssText.replace(cssCommentNextSelectorRe, function(match, p1) {\n      // remove end comment delimiter and add block start\n      return p1.slice(0, -2) + '{';\n    });\n    return cssText.replace(cssContentNextSelectorRe, function(match, p1) {\n      return p1 + ' {';\n    });\n  },\n  /*\n   * Process styles to add rules which will only apply under the polyfill\n   * \n   * For example, we convert this rule:\n   * \n   * polyfill-rule {\n   *   content: ':host menu-item';\n   * ...\n   * }\n   * \n   * to this:\n   * \n   * scopeName menu-item {...}\n   *\n  **/\n  insertPolyfillRulesInCssText: function(cssText) {\n    // TODO(sorvell): remove either content or comment\n    cssText = cssText.replace(cssCommentRuleRe, function(match, p1) {\n      // remove end comment delimiter\n      return p1.slice(0, -1);\n    });\n    return cssText.replace(cssContentRuleRe, function(match, p1, p2, p3) {\n      var rule = match.replace(p1, '').replace(p2, '');\n      return p3 + rule;\n    });\n  },\n  /* Ensure styles are scoped. Pseudo-scoping takes a rule like:\n   * \n   *  .foo {... } \n   *  \n   *  and converts this to\n   *  \n   *  scopeName .foo { ... }\n  */\n  scopeCssText: function(cssText, scopeSelector) {\n    var unscoped = this.extractUnscopedRulesFromCssText(cssText);\n    cssText = this.insertPolyfillHostInCssText(cssText);\n    cssText = this.convertColonHost(cssText);\n    cssText = this.convertColonAncestor(cssText);\n    cssText = this.convertCombinators(cssText);\n    if (scopeSelector) {\n      var self = this, cssText;\n      withCssRules(cssText, function(rules) {\n        cssText = self.scopeRules(rules, scopeSelector);\n      });\n\n    }\n    cssText = cssText + '\\n' + unscoped;\n    return cssText.trim();\n  },\n  /*\n   * Process styles to add rules which will only apply under the polyfill\n   * and do not process via CSSOM. (CSSOM is destructive to rules on rare \n   * occasions, e.g. -webkit-calc on Safari.)\n   * For example, we convert this rule:\n   * \n   * (comment start) @polyfill-unscoped-rule menu-item { \n   * ... } (comment end)\n   * \n   * to this:\n   * \n   * menu-item {...}\n   *\n  **/\n  extractUnscopedRulesFromCssText: function(cssText) {\n    // TODO(sorvell): remove either content or comment\n    var r = '', m;\n    while (m = cssCommentUnscopedRuleRe.exec(cssText)) {\n      r += m[1].slice(0, -1) + '\\n\\n';\n    }\n    while (m = cssContentUnscopedRuleRe.exec(cssText)) {\n      r += m[0].replace(m[2], '').replace(m[1], m[3]) + '\\n\\n';\n    }\n    return r;\n  },\n  /*\n   * convert a rule like :host(.foo) > .bar { }\n   *\n   * to\n   *\n   * scopeName.foo > .bar\n  */\n  convertColonHost: function(cssText) {\n    return this.convertColonRule(cssText, cssColonHostRe,\n        this.colonHostPartReplacer);\n  },\n  /*\n   * convert a rule like :ancestor(.foo) > .bar { }\n   *\n   * to\n   *\n   * scopeName.foo > .bar, .foo scopeName > .bar { }\n   * \n   * and\n   *\n   * :ancestor(.foo:host) .bar { ... }\n   * \n   * to\n   * \n   * scopeName.foo .bar { ... }\n  */\n  convertColonAncestor: function(cssText) {\n    return this.convertColonRule(cssText, cssColonAncestorRe,\n        this.colonAncestorPartReplacer);\n  },\n  convertColonRule: function(cssText, regExp, partReplacer) {\n    // p1 = :host, p2 = contents of (), p3 rest of rule\n    return cssText.replace(regExp, function(m, p1, p2, p3) {\n      p1 = polyfillHostNoCombinator;\n      if (p2) {\n        var parts = p2.split(','), r = [];\n        for (var i=0, l=parts.length, p; (i<l) && (p=parts[i]); i++) {\n          p = p.trim();\n          r.push(partReplacer(p1, p, p3));\n        }\n        return r.join(',');\n      } else {\n        return p1 + p3;\n      }\n    });\n  },\n  colonAncestorPartReplacer: function(host, part, suffix) {\n    if (part.match(polyfillHost)) {\n      return this.colonHostPartReplacer(host, part, suffix);\n    } else {\n      return host + part + suffix + ', ' + part + ' ' + host + suffix;\n    }\n  },\n  colonHostPartReplacer: function(host, part, suffix) {\n    return host + part.replace(polyfillHost, '') + suffix;\n  },\n  /*\n   * Convert ^ and ^^ combinators by replacing with space.\n  */\n  convertCombinators: function(cssText) {\n    for (var i=0; i < combinatorsRe.length; i++) {\n      cssText = cssText.replace(combinatorsRe[i], ' ');\n    }\n    return cssText;\n  },\n  // change a selector like 'div' to 'name div'\n  scopeRules: function(cssRules, scopeSelector) {\n    var cssText = '';\n    if (cssRules) {\n      Array.prototype.forEach.call(cssRules, function(rule) {\n        if (rule.selectorText && (rule.style && rule.style.cssText)) {\n          cssText += this.scopeSelector(rule.selectorText, scopeSelector, \n            this.strictStyling) + ' {\\n\\t';\n          cssText += this.propertiesFromRule(rule) + '\\n}\\n\\n';\n        } else if (rule.type === CSSRule.MEDIA_RULE) {\n          cssText += '@media ' + rule.media.mediaText + ' {\\n';\n          cssText += this.scopeRules(rule.cssRules, scopeSelector);\n          cssText += '\\n}\\n\\n';\n        } else if (rule.cssText) {\n          cssText += rule.cssText + '\\n\\n';\n        }\n      }, this);\n    }\n    return cssText;\n  },\n  scopeSelector: function(selector, scopeSelector, strict) {\n    var r = [], parts = selector.split(',');\n    parts.forEach(function(p) {\n      p = p.trim();\n      if (this.selectorNeedsScoping(p, scopeSelector)) {\n        p = (strict && !p.match(polyfillHostNoCombinator)) ? \n            this.applyStrictSelectorScope(p, scopeSelector) :\n            this.applySimpleSelectorScope(p, scopeSelector);\n      }\n      r.push(p);\n    }, this);\n    return r.join(', ');\n  },\n  selectorNeedsScoping: function(selector, scopeSelector) {\n    var re = this.makeScopeMatcher(scopeSelector);\n    return !selector.match(re);\n  },\n  makeScopeMatcher: function(scopeSelector) {\n    scopeSelector = scopeSelector.replace(/\\[/g, '\\\\[').replace(/\\[/g, '\\\\]');\n    return new RegExp('^(' + scopeSelector + ')' + selectorReSuffix, 'm');\n  },\n  // scope via name and [is=name]\n  applySimpleSelectorScope: function(selector, scopeSelector) {\n    if (selector.match(polyfillHostRe)) {\n      selector = selector.replace(polyfillHostNoCombinator, scopeSelector);\n      return selector.replace(polyfillHostRe, scopeSelector + ' ');\n    } else {\n      return scopeSelector + ' ' + selector;\n    }\n  },\n  // return a selector with [name] suffix on each simple selector\n  // e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name]\n  applyStrictSelectorScope: function(selector, scopeSelector) {\n    scopeSelector = scopeSelector.replace(/\\[is=([^\\]]*)\\]/g, '$1');\n    var splits = [' ', '>', '+', '~'],\n      scoped = selector,\n      attrName = '[' + scopeSelector + ']';\n    splits.forEach(function(sep) {\n      var parts = scoped.split(sep);\n      scoped = parts.map(function(p) {\n        // remove :host since it should be unnecessary\n        var t = p.trim().replace(polyfillHostRe, '');\n        if (t && (splits.indexOf(t) < 0) && (t.indexOf(attrName) < 0)) {\n          p = t.replace(/([^:]*)(:*)(.*)/, '$1' + attrName + '$2$3')\n        }\n        return p;\n      }).join(sep);\n    });\n    return scoped;\n  },\n  insertPolyfillHostInCssText: function(selector) {\n    return selector.replace(hostRe, polyfillHost).replace(colonHostRe,\n        polyfillHost).replace(colonAncestorRe, polyfillAncestor);\n  },\n  propertiesFromRule: function(rule) {\n    // TODO(sorvell): Safari cssom incorrectly removes quotes from the content\n    // property. (https://bugs.webkit.org/show_bug.cgi?id=118045)\n    if (rule.style.content && !rule.style.content.match(/['\"]+/)) {\n      return rule.style.cssText.replace(/content:[^;]*;/g, 'content: \\'' + \n          rule.style.content + '\\';');\n    }\n    return rule.style.cssText;\n  },\n  replaceTextInStyles: function(styles, action) {\n    if (styles && action) {\n      if (!(styles instanceof Array)) {\n        styles = [styles];\n      }\n      Array.prototype.forEach.call(styles, function(s) {\n        s.textContent = action.call(this, s.textContent);\n      }, this);\n    }\n  },\n  addCssToDocument: function(cssText, name) {\n    if (cssText.match('@import')) {\n      addOwnSheet(cssText, name);\n    } else {\n      addCssToDocument(cssText);\n    }\n  }\n};\n\nvar selectorRe = /([^{]*)({[\\s\\S]*?})/gim,\n    cssCommentRe = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//gim,\n    // TODO(sorvell): remove either content or comment\n    cssCommentNextSelectorRe = /\\/\\*\\s*@polyfill ([^*]*\\*+([^/*][^*]*\\*+)*\\/)([^{]*?){/gim,\n    cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\\:[\\s]*'([^']*)'[^}]*}([^{]*?){/gim,\n    // TODO(sorvell): remove either content or comment\n    cssCommentRuleRe = /\\/\\*\\s@polyfill-rule([^*]*\\*+([^/*][^*]*\\*+)*)\\//gim,\n    cssContentRuleRe = /(polyfill-rule)[^}]*(content\\:[\\s]*'([^']*)'[^;]*;)[^}]*}/gim,\n    // TODO(sorvell): remove either content or comment\n    cssCommentUnscopedRuleRe = /\\/\\*\\s@polyfill-unscoped-rule([^*]*\\*+([^/*][^*]*\\*+)*)\\//gim,\n    cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\\:[\\s]*'([^']*)'[^;]*;)[^}]*}/gim,\n    cssPseudoRe = /::(x-[^\\s{,(]*)/gim,\n    cssPartRe = /::part\\(([^)]*)\\)/gim,\n    // note: :host pre-processed to -shadowcsshost.\n    polyfillHost = '-shadowcsshost',\n    // note: :ancestor pre-processed to -shadowcssancestor.\n    polyfillAncestor = '-shadowcssancestor',\n    parenSuffix = ')(?:\\\\((' +\n        '(?:\\\\([^)(]*\\\\)|[^)(]*)+?' +\n        ')\\\\))?([^,{]*)';\n    cssColonHostRe = new RegExp('(' + polyfillHost + parenSuffix, 'gim'),\n    cssColonAncestorRe = new RegExp('(' + polyfillAncestor + parenSuffix, 'gim'),\n    selectorReSuffix = '([>\\\\s~+\\[.,{:][\\\\s\\\\S]*)?$',\n    hostRe = /@host/gim,\n    colonHostRe = /\\:host/gim,\n    colonAncestorRe = /\\:ancestor/gim,\n    /* host name without combinator */\n    polyfillHostNoCombinator = polyfillHost + '-no-combinator',\n    polyfillHostRe = new RegExp(polyfillHost, 'gim'),\n    polyfillAncestorRe = new RegExp(polyfillAncestor, 'gim'),\n    combinatorsRe = [\n      /\\^\\^/g,\n      /\\^/g,\n      /\\/shadow\\//g,\n      /\\/shadow-deep\\//g\n    ];\n\nfunction stylesToCssText(styles, preserveComments) {\n  var cssText = '';\n  Array.prototype.forEach.call(styles, function(s) {\n    cssText += s.textContent + '\\n\\n';\n  });\n  // strip comments for easier processing\n  if (!preserveComments) {\n    cssText = cssText.replace(cssCommentRe, '');\n  }\n  return cssText;\n}\n\nfunction cssTextToStyle(cssText) {\n  var style = document.createElement('style');\n  style.textContent = cssText;\n  return style;\n}\n\nfunction cssToRules(cssText) {\n  var style = cssTextToStyle(cssText);\n  document.head.appendChild(style);\n  var rules = [];\n  if (style.sheet) {\n    // TODO(sorvell): Firefox throws when accessing the rules of a stylesheet\n    // with an @import\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=625013\n    try {\n      rules = style.sheet.cssRules;\n    } catch(e) {\n      //\n    }\n  } else {\n    console.warn('sheet not found', style);\n  }\n  style.parentNode.removeChild(style);\n  return rules;\n}\n\nvar frame = document.createElement('iframe');\nframe.style.display = 'none';\n\nfunction initFrame() {\n  frame.initialized = true;\n  document.body.appendChild(frame);\n  var doc = frame.contentDocument;\n  var base = doc.createElement('base');\n  base.href = document.baseURI;\n  doc.head.appendChild(base);\n}\n\nfunction inFrame(fn) {\n  if (!frame.initialized) {\n    initFrame();\n  }\n  document.body.appendChild(frame);\n  fn(frame.contentDocument);\n  document.body.removeChild(frame);\n}\n\n// TODO(sorvell): use an iframe if the cssText contains an @import to workaround\n// https://code.google.com/p/chromium/issues/detail?id=345114\nvar isChrome = navigator.userAgent.match('Chrome');\nfunction withCssRules(cssText, callback) {\n  if (!callback) {\n    return;\n  }\n  var rules;\n  if (cssText.match('@import') && isChrome) {\n    var style = cssTextToStyle(cssText);\n    inFrame(function(doc) {\n      doc.head.appendChild(style.impl);\n      rules = style.sheet.cssRules;\n      callback(rules);\n    });\n  } else {\n    rules = cssToRules(cssText);\n    callback(rules);\n  }\n}\n\nfunction rulesToCss(cssRules) {\n  for (var i=0, css=[]; i < cssRules.length; i++) {\n    css.push(cssRules[i].cssText);\n  }\n  return css.join('\\n\\n');\n}\n\nfunction addCssToDocument(cssText) {\n  if (cssText) {\n    getSheet().appendChild(document.createTextNode(cssText));\n  }\n}\n\nfunction addOwnSheet(cssText, name) {\n  var style = cssTextToStyle(cssText);\n  style.setAttribute(name, '');\n  style.setAttribute(SHIMMED_ATTRIBUTE, '');\n  document.head.appendChild(style);\n}\n\nvar SHIM_ATTRIBUTE = 'shim-shadowdom';\nvar SHIMMED_ATTRIBUTE = 'shim-shadowdom-css';\nvar NO_SHIM_ATTRIBUTE = 'no-shim';\n\nvar sheet;\nfunction getSheet() {\n  if (!sheet) {\n    sheet = document.createElement(\"style\");\n    sheet.setAttribute(SHIMMED_ATTRIBUTE, '');\n    sheet[SHIMMED_ATTRIBUTE] = true;\n  }\n  return sheet;\n}\n\n// add polyfill stylesheet to document\nif (window.ShadowDOMPolyfill) {\n  addCssToDocument('style { display: none !important; }\\n');\n  var doc = wrap(document);\n  var head = doc.querySelector('head');\n  head.insertBefore(getSheet(), head.childNodes[0]);\n\n  // TODO(sorvell): monkey-patching HTMLImports is abusive;\n  // consider a better solution.\n  document.addEventListener('DOMContentLoaded', function() {\n    var urlResolver = scope.urlResolver;\n    \n    if (window.HTMLImports && !HTMLImports.useNative) {\n      var SHIM_SHEET_SELECTOR = 'link[rel=stylesheet]' +\n          '[' + SHIM_ATTRIBUTE + ']';\n      var SHIM_STYLE_SELECTOR = 'style[' + SHIM_ATTRIBUTE + ']';\n      HTMLImports.importer.documentPreloadSelectors += ',' + SHIM_SHEET_SELECTOR;\n      HTMLImports.importer.importsPreloadSelectors += ',' + SHIM_SHEET_SELECTOR;\n\n      HTMLImports.parser.documentSelectors = [\n        HTMLImports.parser.documentSelectors,\n        SHIM_SHEET_SELECTOR,\n        SHIM_STYLE_SELECTOR\n      ].join(',');\n  \n      var originalParseGeneric = HTMLImports.parser.parseGeneric;\n\n      HTMLImports.parser.parseGeneric = function(elt) {\n        if (elt[SHIMMED_ATTRIBUTE]) {\n          return;\n        }\n        var style = elt.__importElement || elt;\n        if (!style.hasAttribute(SHIM_ATTRIBUTE)) {\n          originalParseGeneric.call(this, elt);\n          return;\n        }\n        if (elt.__resource) {\n          style = elt.ownerDocument.createElement('style');\n          style.textContent = urlResolver.resolveCssText(\n              elt.__resource, elt.href);\n        } else {\n          urlResolver.resolveStyle(style);  \n        }\n        style.textContent = ShadowCSS.shimStyle(style);\n        style.removeAttribute(SHIM_ATTRIBUTE, '');\n        style.setAttribute(SHIMMED_ATTRIBUTE, '');\n        style[SHIMMED_ATTRIBUTE] = true;\n        // place in document\n        if (style.parentNode !== head) {\n          // replace links in head\n          if (elt.parentNode === head) {\n            head.replaceChild(style, elt);\n          } else {\n            head.appendChild(style);\n          }\n        }\n        style.__importParsed = true;\n        this.markParsingComplete(elt);\n      }\n\n      var hasResource = HTMLImports.parser.hasResource;\n      HTMLImports.parser.hasResource = function(node) {\n        if (node.localName === 'link' && node.rel === 'stylesheet' &&\n            node.hasAttribute(SHIM_ATTRIBUTE)) {\n          return (node.__resource);\n        } else {\n          return hasResource.call(this, node);\n        }\n      }\n\n    }\n  });\n}\n\n// exports\nscope.ShadowCSS = ShadowCSS;\n\n})(window.Platform);","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function() {\n\n  // poor man's adapter for template.content on various platform scenarios\n  window.templateContent = window.templateContent || function(inTemplate) {\n    return inTemplate.content;\n  };\n\n  // so we can call wrap/unwrap without testing for ShadowDOMPolyfill\n\n  window.wrap = window.unwrap = function(n){\n    return n;\n  }\n\n  var originalCreateShadowRoot = Element.prototype.webkitCreateShadowRoot;\n  Element.prototype.webkitCreateShadowRoot = function() {\n    var elderRoot = this.webkitShadowRoot;\n    var root = originalCreateShadowRoot.call(this);\n    root.olderShadowRoot = elderRoot;\n    root.host = this;\n    CustomElements.watchShadow(this);\n    return root;\n  }\n\n  Object.defineProperties(Element.prototype, {\n    shadowRoot: {\n      get: function() {\n        return this.webkitShadowRoot;\n      }\n    },\n    createShadowRoot: {\n      value: function() {\n        return this.webkitCreateShadowRoot();\n      }\n    }\n  });\n\n  window.templateContent = function(inTemplate) {\n    // if MDV exists, it may need to boostrap this template to reveal content\n    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {\n      HTMLTemplateElement.bootstrap(inTemplate);\n    }\n    // fallback when there is no Shadow DOM polyfill, no MDV polyfill, and no\n    // native template support\n    if (!inTemplate.content && !inTemplate._content) {\n      var frag = document.createDocumentFragment();\n      while (inTemplate.firstChild) {\n        frag.appendChild(inTemplate.firstChild);\n      }\n      inTemplate._content = frag;\n    }\n    return inTemplate.content || inTemplate._content;\n  };\n\n})();","/* Any copyright is dedicated to the Public Domain.\n * http://creativecommons.org/publicdomain/zero/1.0/ */\n\n(function(scope) {\n  'use strict';\n\n  // feature detect for URL constructor\n  var hasWorkingUrl = false;\n  if (!scope.forceJURL) {\n    try {\n      var u = new URL('b', 'http://a');\n      hasWorkingUrl = u.href === 'http://a/b';\n    } catch(e) {}\n  }\n\n  if (hasWorkingUrl)\n    return;\n\n  var relative = Object.create(null);\n  relative['ftp'] = 21;\n  relative['file'] = 0;\n  relative['gopher'] = 70;\n  relative['http'] = 80;\n  relative['https'] = 443;\n  relative['ws'] = 80;\n  relative['wss'] = 443;\n\n  var relativePathDotMapping = Object.create(null);\n  relativePathDotMapping['%2e'] = '.';\n  relativePathDotMapping['.%2e'] = '..';\n  relativePathDotMapping['%2e.'] = '..';\n  relativePathDotMapping['%2e%2e'] = '..';\n\n  function isRelativeScheme(scheme) {\n    return relative[scheme] !== undefined;\n  }\n\n  function invalid() {\n    clear.call(this);\n    this._isInvalid = true;\n  }\n\n  function IDNAToASCII(h) {\n    if ('' == h) {\n      invalid.call(this)\n    }\n    // XXX\n    return h.toLowerCase()\n  }\n\n  function percentEscape(c) {\n    var unicode = c.charCodeAt(0);\n    if (unicode > 0x20 &&\n       unicode < 0x7F &&\n       // \" # < > ? `\n       [0x22, 0x23, 0x3C, 0x3E, 0x3F, 0x60].indexOf(unicode) == -1\n      ) {\n      return c;\n    }\n    return encodeURIComponent(c);\n  }\n\n  function percentEscapeQuery(c) {\n    // XXX This actually needs to encode c using encoding and then\n    // convert the bytes one-by-one.\n\n    var unicode = c.charCodeAt(0);\n    if (unicode > 0x20 &&\n       unicode < 0x7F &&\n       // \" # < > ` (do not escape '?')\n       [0x22, 0x23, 0x3C, 0x3E, 0x60].indexOf(unicode) == -1\n      ) {\n      return c;\n    }\n    return encodeURIComponent(c);\n  }\n\n  var EOF = undefined,\n      ALPHA = /[a-zA-Z]/,\n      ALPHANUMERIC = /[a-zA-Z0-9\\+\\-\\.]/;\n\n  function parse(input, stateOverride, base) {\n    function err(message) {\n      errors.push(message)\n    }\n\n    var state = stateOverride || 'scheme start',\n        cursor = 0,\n        buffer = '',\n        seenAt = false,\n        seenBracket = false,\n        errors = [];\n\n    loop: while ((input[cursor - 1] != EOF || cursor == 0) && !this._isInvalid) {\n      var c = input[cursor];\n      switch (state) {\n        case 'scheme start':\n          if (c && ALPHA.test(c)) {\n            buffer += c.toLowerCase(); // ASCII-safe\n            state = 'scheme';\n          } else if (!stateOverride) {\n            buffer = '';\n            state = 'no scheme';\n            continue;\n          } else {\n            err('Invalid scheme.');\n            break loop;\n          }\n          break;\n\n        case 'scheme':\n          if (c && ALPHANUMERIC.test(c)) {\n            buffer += c.toLowerCase(); // ASCII-safe\n          } else if (':' == c) {\n            this._scheme = buffer;\n            buffer = '';\n            if (stateOverride) {\n              break loop;\n            }\n            if (isRelativeScheme(this._scheme)) {\n              this._isRelative = true;\n            }\n            if ('file' == this._scheme) {\n              state = 'relative';\n            } else if (this._isRelative && base && base._scheme == this._scheme) {\n              state = 'relative or authority';\n            } else if (this._isRelative) {\n              state = 'authority first slash';\n            } else {\n              state = 'scheme data';\n            }\n          } else if (!stateOverride) {\n            buffer = '';\n            cursor = 0;\n            state = 'no scheme';\n            continue;\n          } else if (EOF == c) {\n            break loop;\n          } else {\n            err('Code point not allowed in scheme: ' + c)\n            break loop;\n          }\n          break;\n\n        case 'scheme data':\n          if ('?' == c) {\n            query = '?';\n            state = 'query';\n          } else if ('#' == c) {\n            this._fragment = '#';\n            state = 'fragment';\n          } else {\n            // XXX error handling\n            if (EOF != c && '\\t' != c && '\\n' != c && '\\r' != c) {\n              this._schemeData += percentEscape(c);\n            }\n          }\n          break;\n\n        case 'no scheme':\n          if (!base || !(isRelativeScheme(base._scheme))) {\n            err('Missing scheme.');\n            invalid.call(this);\n          } else {\n            state = 'relative';\n            continue;\n          }\n          break;\n\n        case 'relative or authority':\n          if ('/' == c && '/' == input[cursor+1]) {\n            state = 'authority ignore slashes';\n          } else {\n            err('Expected /, got: ' + c);\n            state = 'relative';\n            continue\n          }\n          break;\n\n        case 'relative':\n          this._isRelative = true;\n          if ('file' != this._scheme)\n            this._scheme = base._scheme;\n          if (EOF == c) {\n            this._host = base._host;\n            this._port = base._port;\n            this._path = base._path.slice();\n            this._query = base._query;\n            break loop;\n          } else if ('/' == c || '\\\\' == c) {\n            if ('\\\\' == c)\n              err('\\\\ is an invalid code point.');\n            state = 'relative slash';\n          } else if ('?' == c) {\n            this._host = base._host;\n            this._port = base._port;\n            this._path = base._path.slice();\n            this._query = '?';\n            state = 'query';\n          } else if ('#' == c) {\n            this._host = base._host;\n            this._port = base._port;\n            this._path = base._path.slice();\n            this._query = base._query;\n            this._fragment = '#';\n            state = 'fragment';\n          } else {\n            var nextC = input[cursor+1]\n            var nextNextC = input[cursor+2]\n            if (\n              'file' != this._scheme || !ALPHA.test(c) ||\n              (nextC != ':' && nextC != '|') ||\n              (EOF != nextNextC && '/' != nextNextC && '\\\\' != nextNextC && '?' != nextNextC && '#' != nextNextC)) {\n              this._host = base._host;\n              this._port = base._port;\n              this._path = base._path.slice();\n              this._path.pop();\n            }\n            state = 'relative path';\n            continue;\n          }\n          break;\n\n        case 'relative slash':\n          if ('/' == c || '\\\\' == c) {\n            if ('\\\\' == c) {\n              err('\\\\ is an invalid code point.');\n            }\n            if ('file' == this._scheme) {\n              state = 'file host';\n            } else {\n              state = 'authority ignore slashes';\n            }\n          } else {\n            if ('file' != this._scheme) {\n              this._host = base._host;\n              this._port = base._port;\n            }\n            state = 'relative path';\n            continue;\n          }\n          break;\n\n        case 'authority first slash':\n          if ('/' == c) {\n            state = 'authority second slash';\n          } else {\n            err(\"Expected '/', got: \" + c);\n            state = 'authority ignore slashes';\n            continue;\n          }\n          break;\n\n        case 'authority second slash':\n          state = 'authority ignore slashes';\n          if ('/' != c) {\n            err(\"Expected '/', got: \" + c);\n            continue;\n          }\n          break;\n\n        case 'authority ignore slashes':\n          if ('/' != c && '\\\\' != c) {\n            state = 'authority';\n            continue;\n          } else {\n            err('Expected authority, got: ' + c);\n          }\n          break;\n\n        case 'authority':\n          if ('@' == c) {\n            if (seenAt) {\n              err('@ already seen.');\n              buffer += '%40';\n            }\n            seenAt = true;\n            for (var i = 0; i < buffer.length; i++) {\n              var cp = buffer[i];\n              if ('\\t' == cp || '\\n' == cp || '\\r' == cp) {\n                err('Invalid whitespace in authority.');\n                continue;\n              }\n              // XXX check URL code points\n              if (':' == cp && null === this._password) {\n                this._password = '';\n                continue;\n              }\n              var tempC = percentEscape(cp);\n              (null !== this._password) ? this._password += tempC : this._username += tempC;\n            }\n            buffer = '';\n          } else if (EOF == c || '/' == c || '\\\\' == c || '?' == c || '#' == c) {\n            cursor -= buffer.length;\n            buffer = '';\n            state = 'host';\n            continue;\n          } else {\n            buffer += c;\n          }\n          break;\n\n        case 'file host':\n          if (EOF == c || '/' == c || '\\\\' == c || '?' == c || '#' == c) {\n            if (buffer.length == 2 && ALPHA.test(buffer[0]) && (buffer[1] == ':' || buffer[1] == '|')) {\n              state = 'relative path';\n            } else if (buffer.length == 0) {\n              state = 'relative path start';\n            } else {\n              this._host = IDNAToASCII.call(this, buffer);\n              buffer = '';\n              state = 'relative path start';\n            }\n            continue;\n          } else if ('\\t' == c || '\\n' == c || '\\r' == c) {\n            err('Invalid whitespace in file host.');\n          } else {\n            buffer += c;\n          }\n          break;\n\n        case 'host':\n        case 'hostname':\n          if (':' == c && !seenBracket) {\n            // XXX host parsing\n            this._host = IDNAToASCII.call(this, buffer);\n            buffer = '';\n            state = 'port';\n            if ('hostname' == stateOverride) {\n              break loop;\n            }\n          } else if (EOF == c || '/' == c || '\\\\' == c || '?' == c || '#' == c) {\n            this._host = IDNAToASCII.call(this, buffer);\n            buffer = '';\n            state = 'relative path start';\n            if (stateOverride) {\n              break loop;\n            }\n            continue;\n          } else if ('\\t' != c && '\\n' != c && '\\r' != c) {\n            if ('[' == c) {\n              seenBracket = true;\n            } else if (']' == c) {\n              seenBracket = false;\n            }\n            buffer += c;\n          } else {\n            err('Invalid code point in host/hostname: ' + c);\n          }\n          break;\n\n        case 'port':\n          if (/[0-9]/.test(c)) {\n            buffer += c;\n          } else if (EOF == c || '/' == c || '\\\\' == c || '?' == c || '#' == c || stateOverride) {\n            if ('' != buffer) {\n              var temp = parseInt(buffer, 10);\n              if (temp != relative[this._scheme]) {\n                this._port = temp + '';\n              }\n              buffer = '';\n            }\n            if (stateOverride) {\n              break loop;\n            }\n            state = 'relative path start';\n            continue;\n          } else if ('\\t' == c || '\\n' == c || '\\r' == c) {\n            err('Invalid code point in port: ' + c);\n          } else {\n            invalid.call(this);\n          }\n          break;\n\n        case 'relative path start':\n          if ('\\\\' == c)\n            err(\"'\\\\' not allowed in path.\");\n          state = 'relative path';\n          if ('/' != c && '\\\\' != c) {\n            continue;\n          }\n          break;\n\n        case 'relative path':\n          if (EOF == c || '/' == c || '\\\\' == c || (!stateOverride && ('?' == c || '#' == c))) {\n            if ('\\\\' == c) {\n              err('\\\\ not allowed in relative path.');\n            }\n            var tmp;\n            if (tmp = relativePathDotMapping[buffer.toLowerCase()]) {\n              buffer = tmp;\n            }\n            if ('..' == buffer) {\n              this._path.pop();\n              if ('/' != c && '\\\\' != c) {\n                this._path.push('');\n              }\n            } else if ('.' == buffer && '/' != c && '\\\\' != c) {\n              this._path.push('');\n            } else if ('.' != buffer) {\n              if ('file' == this._scheme && this._path.length == 0 && buffer.length == 2 && ALPHA.test(buffer[0]) && buffer[1] == '|') {\n                buffer = buffer[0] + ':';\n              }\n              this._path.push(buffer);\n            }\n            buffer = '';\n            if ('?' == c) {\n              this._query = '?';\n              state = 'query';\n            } else if ('#' == c) {\n              this._fragment = '#';\n              state = 'fragment';\n            }\n          } else if ('\\t' != c && '\\n' != c && '\\r' != c) {\n            buffer += percentEscape(c);\n          }\n          break;\n\n        case 'query':\n          if (!stateOverride && '#' == c) {\n            this._fragment = '#';\n            state = 'fragment';\n          } else if (EOF != c && '\\t' != c && '\\n' != c && '\\r' != c) {\n            this._query += percentEscapeQuery(c);\n          }\n          break;\n\n        case 'fragment':\n          if (EOF != c && '\\t' != c && '\\n' != c && '\\r' != c) {\n            this._fragment += c;\n          }\n          break;\n      }\n\n      cursor++;\n    }\n  }\n\n  function clear() {\n    this._scheme = '';\n    this._schemeData = '';\n    this._username = '';\n    this._password = null;\n    this._host = '';\n    this._port = '';\n    this._path = [];\n    this._query = '';\n    this._fragment = '';\n    this._isInvalid = false;\n    this._isRelative = false;\n  }\n\n  // Does not process domain names or IP addresses.\n  // Does not handle encoding for the query parameter.\n  function jURL(url, base /* , encoding */) {\n    if (base !== undefined && !(base instanceof jURL))\n      base = new jURL(String(base));\n\n    this._url = url;\n    clear.call(this);\n\n    var input = url.replace(/^[ \\t\\r\\n\\f]+|[ \\t\\r\\n\\f]+$/g, '');\n    // encoding = encoding || 'utf-8'\n\n    parse.call(this, input, null, base);\n  }\n\n  jURL.prototype = {\n    get href() {\n      if (this._isInvalid)\n        return this._url;\n\n      var authority = '';\n      if ('' != this._username || null != this._password) {\n        authority = this._username +\n            (null != this._password ? ':' + this._password : '') + '@';\n      }\n\n      return this.protocol +\n          (this._isRelative ? '//' + authority + this.host : '') +\n          this.pathname + this._query + this._fragment;\n    },\n    set href(href) {\n      clear.call(this);\n      parse.call(this, href);\n    },\n\n    get protocol() {\n      return this._scheme + ':';\n    },\n    set protocol(protocol) {\n      if (this._isInvalid)\n        return;\n      parse.call(this, protocol + ':', 'scheme start');\n    },\n\n    get host() {\n      return this._isInvalid ? '' : this._port ?\n          this._host + ':' + this._port : this._host;\n    },\n    set host(host) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      parse.call(this, host, 'host');\n    },\n\n    get hostname() {\n      return this._host;\n    },\n    set hostname(hostname) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      parse.call(this, hostname, 'hostname');\n    },\n\n    get port() {\n      return this._port;\n    },\n    set port(port) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      parse.call(this, port, 'port');\n    },\n\n    get pathname() {\n      return this._isInvalid ? '' : this._isRelative ?\n          '/' + this._path.join('/') : this._schemeData;\n    },\n    set pathname(pathname) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      this._path = [];\n      parse.call(this, pathname, 'relative path start');\n    },\n\n    get search() {\n      return this._isInvalid || !this._query || '?' == this._query ?\n          '' : this._query;\n    },\n    set search(search) {\n      if (this._isInvalid || !this._isRelative)\n        return;\n      this._query = '?';\n      if ('?' == search[0])\n        search = search.slice(1);\n      parse.call(this, search, 'query');\n    },\n\n    get hash() {\n      return this._isInvalid || !this._fragment || '#' == this._fragment ?\n          '' : this._fragment;\n    },\n    set hash(hash) {\n      if (this._isInvalid)\n        return;\n      this._fragment = '#';\n      if ('#' == hash[0])\n        hash = hash.slice(1);\n      parse.call(this, hash, 'fragment');\n    }\n  };\n\n  scope.URL = jURL;\n\n})(window);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n// Old versions of iOS do not have bind.\n\nif (!Function.prototype.bind) {\n  Function.prototype.bind = function(scope) {\n    var self = this;\n    var args = Array.prototype.slice.call(arguments, 1);\n    return function() {\n      var args2 = args.slice();\n      args2.push.apply(args2, arguments);\n      return self.apply(scope, args2);\n    };\n  };\n}\n\n// mixin\n\n// copy all properties from inProps (et al) to inObj\nfunction mixin(inObj/*, inProps, inMoreProps, ...*/) {\n  var obj = inObj || {};\n  for (var i = 1; i < arguments.length; i++) {\n    var p = arguments[i];\n    try {\n      for (var n in p) {\n        copyProperty(n, p, obj);\n      }\n    } catch(x) {\n    }\n  }\n  return obj;\n}\n\n// copy property inName from inSource object to inTarget object\nfunction copyProperty(inName, inSource, inTarget) {\n  var pd = getPropertyDescriptor(inSource, inName);\n  Object.defineProperty(inTarget, inName, pd);\n}\n\n// get property descriptor for inName on inObject, even if\n// inName exists on some link in inObject's prototype chain\nfunction getPropertyDescriptor(inObject, inName) {\n  if (inObject) {\n    var pd = Object.getOwnPropertyDescriptor(inObject, inName);\n    return pd || getPropertyDescriptor(Object.getPrototypeOf(inObject), inName);\n  }\n}\n\n// export\n\nscope.mixin = mixin;\n\n})(window.Platform);","// Copyright 2011 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function(scope) {\n\n  'use strict';\n\n  // polyfill DOMTokenList\n  // * add/remove: allow these methods to take multiple classNames\n  // * toggle: add a 2nd argument which forces the given state rather\n  //  than toggling.\n\n  var add = DOMTokenList.prototype.add;\n  var remove = DOMTokenList.prototype.remove;\n  DOMTokenList.prototype.add = function() {\n    for (var i = 0; i < arguments.length; i++) {\n      add.call(this, arguments[i]);\n    }\n  };\n  DOMTokenList.prototype.remove = function() {\n    for (var i = 0; i < arguments.length; i++) {\n      remove.call(this, arguments[i]);\n    }\n  };\n  DOMTokenList.prototype.toggle = function(name, bool) {\n    if (arguments.length == 1) {\n      bool = !this.contains(name);\n    }\n    bool ? this.add(name) : this.remove(name);\n  };\n  DOMTokenList.prototype.switch = function(oldName, newName) {\n    oldName && this.remove(oldName);\n    newName && this.add(newName);\n  };\n\n  // add array() to NodeList, NamedNodeMap, HTMLCollection\n\n  var ArraySlice = function() {\n    return Array.prototype.slice.call(this);\n  };\n\n  var namedNodeMap = (window.NamedNodeMap || window.MozNamedAttrMap || {});\n\n  NodeList.prototype.array = ArraySlice;\n  namedNodeMap.prototype.array = ArraySlice;\n  HTMLCollection.prototype.array = ArraySlice;\n\n  // polyfill performance.now\n\n  if (!window.performance) {\n    var start = Date.now();\n    // only at millisecond precision\n    window.performance = {now: function(){ return Date.now() - start }};\n  }\n\n  // polyfill for requestAnimationFrame\n\n  if (!window.requestAnimationFrame) {\n    window.requestAnimationFrame = (function() {\n      var nativeRaf = window.webkitRequestAnimationFrame ||\n        window.mozRequestAnimationFrame;\n\n      return nativeRaf ?\n        function(callback) {\n          return nativeRaf(function() {\n            callback(performance.now());\n          });\n        } :\n        function( callback ){\n          return window.setTimeout(callback, 1000 / 60);\n        };\n    })();\n  }\n\n  if (!window.cancelAnimationFrame) {\n    window.cancelAnimationFrame = (function() {\n      return  window.webkitCancelAnimationFrame ||\n        window.mozCancelAnimationFrame ||\n        function(id) {\n          clearTimeout(id);\n        };\n    })();\n  }\n\n  // utility\n\n  function createDOM(inTagOrNode, inHTML, inAttrs) {\n    var dom = typeof inTagOrNode == 'string' ?\n        document.createElement(inTagOrNode) : inTagOrNode.cloneNode(true);\n    dom.innerHTML = inHTML;\n    if (inAttrs) {\n      for (var n in inAttrs) {\n        dom.setAttribute(n, inAttrs[n]);\n      }\n    }\n    return dom;\n  }\n  // Make a stub for Polymer() for polyfill purposes; under the HTMLImports\n  // polyfill, scripts in the main document run before imports. That means\n  // if (1) polymer is imported and (2) Polymer() is called in the main document\n  // in a script after the import, 2 occurs before 1. We correct this here\n  // by specfiically patching Polymer(); this is not necessary under native\n  // HTMLImports.\n  var elementDeclarations = [];\n\n  var polymerStub = function(name, dictionary) {\n    elementDeclarations.push(arguments);\n  }\n  window.Polymer = polymerStub;\n\n  // deliver queued delcarations\n  scope.deliverDeclarations = function() {\n    scope.deliverDeclarations = function() {\n     throw 'Possible attempt to load Polymer twice';\n    };\n    return elementDeclarations;\n  }\n\n  // Once DOMContent has loaded, any main document scripts that depend on\n  // Polymer() should have run. Calling Polymer() now is an error until\n  // polymer is imported.\n  window.addEventListener('DOMContentLoaded', function() {\n    if (window.Polymer === polymerStub) {\n      window.Polymer = function() {\n        console.error('You tried to use polymer without loading it first. To ' +\n          'load polymer, <link rel=\"import\" href=\"' + \n          'components/polymer/polymer.html\">');\n      };\n    }\n  });\n\n  // exports\n  scope.createDOM = createDOM;\n\n})(window.Platform);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n// poor man's adapter for template.content on various platform scenarios\nwindow.templateContent = window.templateContent || function(inTemplate) {\n  return inTemplate.content;\n};","(function(scope) {\n  \n  scope = scope || (window.Inspector = {});\n  \n  var inspector;\n\n  window.sinspect = function(inNode, inProxy) {\n    if (!inspector) {\n      inspector = window.open('', 'ShadowDOM Inspector', null, true);\n      inspector.document.write(inspectorHTML);\n      //inspector.document.close();\n      inspector.api = {\n        shadowize: shadowize\n      };\n    }\n    inspect(inNode || wrap(document.body), inProxy);\n  };\n\n  var inspectorHTML = [\n    '<!DOCTYPE html>',\n    '<html>',\n    '  <head>',\n    '    <title>ShadowDOM Inspector</title>',\n    '    <style>',\n    '      body {',\n    '      }',\n    '      pre {',\n    '        font: 9pt \"Courier New\", monospace;',\n    '        line-height: 1.5em;',\n    '      }',\n    '      tag {',\n    '        color: purple;',\n    '      }',\n    '      ul {',\n    '         margin: 0;',\n    '         padding: 0;',\n    '         list-style: none;',\n    '      }',\n    '      li {',\n    '         display: inline-block;',\n    '         background-color: #f1f1f1;',\n    '         padding: 4px 6px;',\n    '         border-radius: 4px;',\n    '         margin-right: 4px;',\n    '      }',\n    '    </style>',\n    '  </head>',\n    '  <body>',\n    '    <ul id=\"crumbs\">',\n    '    </ul>',\n    '    <div id=\"tree\"></div>',\n    '  </body>',\n    '</html>'\n  ].join('\\n');\n  \n  var crumbs = [];\n\n  var displayCrumbs = function() {\n    // alias our document\n    var d = inspector.document;\n    // get crumbbar\n    var cb = d.querySelector('#crumbs');\n    // clear crumbs\n    cb.textContent = '';\n    // build new crumbs\n    for (var i=0, c; c=crumbs[i]; i++) {\n      var a = d.createElement('a');\n      a.href = '#';\n      a.textContent = c.localName;\n      a.idx = i;\n      a.onclick = function(event) {\n        var c;\n        while (crumbs.length > this.idx) {\n          c = crumbs.pop();\n        }\n        inspect(c.shadow || c, c);\n        event.preventDefault();\n      };\n      cb.appendChild(d.createElement('li')).appendChild(a);\n    }\n  };\n\n  var inspect = function(inNode, inProxy) {\n    // alias our document\n    var d = inspector.document;\n    // reset list of drillable nodes\n    drillable = [];\n    // memoize our crumb proxy\n    var proxy = inProxy || inNode;\n    crumbs.push(proxy);\n    // update crumbs\n    displayCrumbs();\n    // reflect local tree\n    d.body.querySelector('#tree').innerHTML =\n        '<pre>' + output(inNode, inNode.childNodes) + '</pre>';\n  };\n\n  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n\n  var blacklisted = {STYLE:1, SCRIPT:1, \"#comment\": 1, TEMPLATE: 1};\n  var blacklist = function(inNode) {\n    return blacklisted[inNode.nodeName];\n  };\n\n  var output = function(inNode, inChildNodes, inIndent) {\n    if (blacklist(inNode)) {\n      return '';\n    }\n    var indent = inIndent || '';\n    if (inNode.localName || inNode.nodeType == 11) {\n      var name = inNode.localName || 'shadow-root';\n      //inChildNodes = ShadowDOM.localNodes(inNode);\n      var info = indent + describe(inNode);\n      // if only textNodes\n      // TODO(sjmiles): make correct for ShadowDOM\n      /*if (!inNode.children.length && inNode.localName !== 'content' && inNode.localName !== 'shadow') {\n        info += catTextContent(inChildNodes);\n      } else*/ {\n        // TODO(sjmiles): native <shadow> has no reference to its projection\n        if (name == 'content' /*|| name == 'shadow'*/) {\n          inChildNodes = inNode.getDistributedNodes();\n        }\n        info += '<br/>';\n        var ind = indent + '&nbsp;&nbsp;';\n        forEach(inChildNodes, function(n) {\n          info += output(n, n.childNodes, ind);\n        });\n        info += indent;\n      }\n      if (!({br:1}[name])) {\n        info += '<tag>&lt;/' + name + '&gt;</tag>';\n        info += '<br/>';\n      }\n    } else {\n      var text = inNode.textContent.trim();\n      info = text ? indent + '\"' + text + '\"' + '<br/>' : '';\n    }\n    return info;\n  };\n\n  var catTextContent = function(inChildNodes) {\n    var info = '';\n    forEach(inChildNodes, function(n) {\n      info += n.textContent.trim();\n    });\n    return info;\n  };\n\n  var drillable = [];\n\n  var describe = function(inNode) {\n    var tag = '<tag>' + '&lt;';\n    var name = inNode.localName || 'shadow-root';\n    if (inNode.webkitShadowRoot || inNode.shadowRoot) {\n      tag += ' <button idx=\"' + drillable.length +\n        '\" onclick=\"api.shadowize.call(this)\">' + name + '</button>';\n      drillable.push(inNode);\n    } else {\n      tag += name || 'shadow-root';\n    }\n    if (inNode.attributes) {\n      forEach(inNode.attributes, function(a) {\n        tag += ' ' + a.name + (a.value ? '=\"' + a.value + '\"' : '');\n      });\n    }\n    tag += '&gt;'+ '</tag>';\n    return tag;\n  };\n\n  // remote api\n\n  shadowize = function() {\n    var idx = Number(this.attributes.idx.value);\n    //alert(idx);\n    var node = drillable[idx];\n    if (node) {\n      inspect(node.webkitShadowRoot || node.shadowRoot, node)\n    } else {\n      console.log(\"bad shadowize node\");\n      console.dir(this);\n    }\n  };\n  \n  // export\n  \n  scope.output = output;\n  \n})(window.Inspector);\n\n\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // TODO(sorvell): It's desireable to provide a default stylesheet \n  // that's convenient for styling unresolved elements, but\n  // it's cumbersome to have to include this manually in every page.\n  // It would make sense to put inside some HTMLImport but \n  // the HTMLImports polyfill does not allow loading of stylesheets \n  // that block rendering. Therefore this injection is tolerated here.\n\n  var style = document.createElement('style');\n  style.textContent = ''\n      + 'body {'\n      + 'transition: opacity ease-in 0.2s;' \n      + ' } \\n'\n      + 'body[unresolved] {'\n      + 'opacity: 0; display: block; overflow: hidden;' \n      + ' } \\n'\n      ;\n  var head = document.querySelector('head');\n  head.insertBefore(style, head.firstChild);\n\n})(Platform);\n","(function(scope) {\n\n  function withDependencies(task, depends) {\n    depends = depends || [];\n    if (!depends.map) {\n      depends = [depends];\n    }\n    return task.apply(this, depends.map(marshal));\n  }\n\n  function module(name, dependsOrFactory, moduleFactory) {\n    var module;\n    switch (arguments.length) {\n      case 0:\n        return;\n      case 1:\n        module = null;\n        break;\n      case 2:\n        module = dependsOrFactory.apply(this);\n        break;\n      default:\n        module = withDependencies(moduleFactory, dependsOrFactory);\n        break;\n    }\n    modules[name] = module;\n  };\n\n  function marshal(name) {\n    return modules[name];\n  }\n\n  var modules = {};\n\n  function using(depends, task) {\n    HTMLImports.whenImportsReady(function() {\n      withDependencies(task, depends);\n    });\n  };\n\n  // exports\n\n  scope.marshal = marshal;\n  scope.module = module;\n  scope.using = using;\n\n})(window);","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\nvar iterations = 0;\nvar callbacks = [];\nvar twiddle = document.createTextNode('');\n\nfunction endOfMicrotask(callback) {\n  twiddle.textContent = iterations++;\n  callbacks.push(callback);\n}\n\nfunction atEndOfMicrotask() {\n  while (callbacks.length) {\n    callbacks.shift()();\n  }\n}\n\nnew (window.MutationObserver || JsMutationObserver)(atEndOfMicrotask)\n  .observe(twiddle, {characterData: true})\n  ;\n\n// exports\n\nscope.endOfMicrotask = endOfMicrotask;\n\n})(Platform);\n\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\nvar urlResolver = {\n  resolveDom: function(root, url) {\n    url = url || root.ownerDocument.baseURI;\n    this.resolveAttributes(root, url);\n    this.resolveStyles(root, url);\n    // handle template.content\n    var templates = root.querySelectorAll('template');\n    if (templates) {\n      for (var i = 0, l = templates.length, t; (i < l) && (t = templates[i]); i++) {\n        if (t.content) {\n          this.resolveDom(t.content, url);\n        }\n      }\n    }\n  },\n  resolveTemplate: function(template) {\n    this.resolveDom(template.content, template.ownerDocument.baseURI);\n  },\n  resolveStyles: function(root, url) {\n    var styles = root.querySelectorAll('style');\n    if (styles) {\n      for (var i = 0, l = styles.length, s; (i < l) && (s = styles[i]); i++) {\n        this.resolveStyle(s, url);\n      }\n    }\n  },\n  resolveStyle: function(style, url) {\n    url = url || style.ownerDocument.baseURI;\n    style.textContent = this.resolveCssText(style.textContent, url);\n  },\n  resolveCssText: function(cssText, baseUrl) {\n    cssText = replaceUrlsInCssText(cssText, baseUrl, CSS_URL_REGEXP);\n    return replaceUrlsInCssText(cssText, baseUrl, CSS_IMPORT_REGEXP);\n  },\n  resolveAttributes: function(root, url) {\n    if (root.hasAttributes && root.hasAttributes()) {\n      this.resolveElementAttributes(root, url);\n    }\n    // search for attributes that host urls\n    var nodes = root && root.querySelectorAll(URL_ATTRS_SELECTOR);\n    if (nodes) {\n      for (var i = 0, l = nodes.length, n; (i < l) && (n = nodes[i]); i++) {\n        this.resolveElementAttributes(n, url);\n      }\n    }\n  },\n  resolveElementAttributes: function(node, url) {\n    url = url || node.ownerDocument.baseURI;\n    URL_ATTRS.forEach(function(v) {\n      var attr = node.attributes[v];\n      if (attr && attr.value &&\n         (attr.value.search(URL_TEMPLATE_SEARCH) < 0)) {\n        var urlPath = resolveRelativeUrl(url, attr.value);\n        attr.value = urlPath;\n      }\n    });\n  }\n};\n\nvar CSS_URL_REGEXP = /(url\\()([^)]*)(\\))/g;\nvar CSS_IMPORT_REGEXP = /(@import[\\s]+(?!url\\())([^;]*)(;)/g;\nvar URL_ATTRS = ['href', 'src', 'action'];\nvar URL_ATTRS_SELECTOR = '[' + URL_ATTRS.join('],[') + ']';\nvar URL_TEMPLATE_SEARCH = '{{.*}}';\n\nfunction replaceUrlsInCssText(cssText, baseUrl, regexp) {\n  return cssText.replace(regexp, function(m, pre, url, post) {\n    var urlPath = url.replace(/[\"']/g, '');\n    urlPath = resolveRelativeUrl(baseUrl, urlPath);\n    return pre + '\\'' + urlPath + '\\'' + post;\n  });\n}\n\nfunction resolveRelativeUrl(baseUrl, url) {\n  var u = new URL(url, baseUrl);\n  return makeDocumentRelPath(u.href);\n}\n\nfunction makeDocumentRelPath(url) {\n  var root = document.baseURI;\n  var u = new URL(url, root);\n  if (u.host === root.host && u.port === root.port &&\n      u.protocol === root.protocol) {\n    return makeRelPath(root.pathname, u.pathname);\n  } else {\n    return url;\n  }\n}\n\n// make a relative path from source to target\nfunction makeRelPath(source, target) {\n  var s = source.split('/');\n  var t = target.split('/');\n  while (s.length && s[0] === t[0]){\n    s.shift();\n    t.shift();\n  }\n  for (var i = 0, l = s.length - 1; i < l; i++) {\n    t.unshift('..');\n  }\n  return t.join('/');\n}\n\n// exports\nscope.urlResolver = urlResolver;\n\n})(Platform);\n","/*\n * Copyright 2012 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(global) {\n\n  var registrationsTable = new WeakMap();\n\n  // We use setImmediate or postMessage for our future callback.\n  var setImmediate = window.msSetImmediate;\n\n  // Use post message to emulate setImmediate.\n  if (!setImmediate) {\n    var setImmediateQueue = [];\n    var sentinel = String(Math.random());\n    window.addEventListener('message', function(e) {\n      if (e.data === sentinel) {\n        var queue = setImmediateQueue;\n        setImmediateQueue = [];\n        queue.forEach(function(func) {\n          func();\n        });\n      }\n    });\n    setImmediate = function(func) {\n      setImmediateQueue.push(func);\n      window.postMessage(sentinel, '*');\n    };\n  }\n\n  // This is used to ensure that we never schedule 2 callas to setImmediate\n  var isScheduled = false;\n\n  // Keep track of observers that needs to be notified next time.\n  var scheduledObservers = [];\n\n  /**\n   * Schedules |dispatchCallback| to be called in the future.\n   * @param {MutationObserver} observer\n   */\n  function scheduleCallback(observer) {\n    scheduledObservers.push(observer);\n    if (!isScheduled) {\n      isScheduled = true;\n      setImmediate(dispatchCallbacks);\n    }\n  }\n\n  function wrapIfNeeded(node) {\n    return window.ShadowDOMPolyfill &&\n        window.ShadowDOMPolyfill.wrapIfNeeded(node) ||\n        node;\n  }\n\n  function dispatchCallbacks() {\n    // http://dom.spec.whatwg.org/#mutation-observers\n\n    isScheduled = false; // Used to allow a new setImmediate call above.\n\n    var observers = scheduledObservers;\n    scheduledObservers = [];\n    // Sort observers based on their creation UID (incremental).\n    observers.sort(function(o1, o2) {\n      return o1.uid_ - o2.uid_;\n    });\n\n    var anyNonEmpty = false;\n    observers.forEach(function(observer) {\n\n      // 2.1, 2.2\n      var queue = observer.takeRecords();\n      // 2.3. Remove all transient registered observers whose observer is mo.\n      removeTransientObserversFor(observer);\n\n      // 2.4\n      if (queue.length) {\n        observer.callback_(queue, observer);\n        anyNonEmpty = true;\n      }\n    });\n\n    // 3.\n    if (anyNonEmpty)\n      dispatchCallbacks();\n  }\n\n  function removeTransientObserversFor(observer) {\n    observer.nodes_.forEach(function(node) {\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        return;\n      registrations.forEach(function(registration) {\n        if (registration.observer === observer)\n          registration.removeTransientObservers();\n      });\n    });\n  }\n\n  /**\n   * This function is used for the \"For each registered observer observer (with\n   * observer's options as options) in target's list of registered observers,\n   * run these substeps:\" and the \"For each ancestor ancestor of target, and for\n   * each registered observer observer (with options options) in ancestor's list\n   * of registered observers, run these substeps:\" part of the algorithms. The\n   * |options.subtree| is checked to ensure that the callback is called\n   * correctly.\n   *\n   * @param {Node} target\n   * @param {function(MutationObserverInit):MutationRecord} callback\n   */\n  function forEachAncestorAndObserverEnqueueRecord(target, callback) {\n    for (var node = target; node; node = node.parentNode) {\n      var registrations = registrationsTable.get(node);\n\n      if (registrations) {\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          var options = registration.options;\n\n          // Only target ignores subtree.\n          if (node !== target && !options.subtree)\n            continue;\n\n          var record = callback(options);\n          if (record)\n            registration.enqueue(record);\n        }\n      }\n    }\n  }\n\n  var uidCounter = 0;\n\n  /**\n   * The class that maps to the DOM MutationObserver interface.\n   * @param {Function} callback.\n   * @constructor\n   */\n  function JsMutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n  }\n\n  JsMutationObserver.prototype = {\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n\n      // 1.1\n      if (!options.childList && !options.attributes && !options.characterData ||\n\n          // 1.2\n          options.attributeOldValue && !options.attributes ||\n\n          // 1.3\n          options.attributeFilter && options.attributeFilter.length &&\n              !options.attributes ||\n\n          // 1.4\n          options.characterDataOldValue && !options.characterData) {\n\n        throw new SyntaxError();\n      }\n\n      var registrations = registrationsTable.get(target);\n      if (!registrations)\n        registrationsTable.set(target, registrations = []);\n\n      // 2\n      // If target's list of registered observers already includes a registered\n      // observer associated with the context object, replace that registered\n      // observer's options with options.\n      var registration;\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          registration.removeListeners();\n          registration.options = options;\n          break;\n        }\n      }\n\n      // 3.\n      // Otherwise, add a new registered observer to target's list of registered\n      // observers with the context object as the observer and options as the\n      // options, and add target to context object's list of nodes on which it\n      // is registered.\n      if (!registration) {\n        registration = new Registration(this, target, options);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n\n      registration.addListeners();\n    },\n\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registration.removeListeners();\n            registrations.splice(i, 1);\n            // Each node can only have one registered observer associated with\n            // this observer.\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n\n  /**\n   * @param {string} type\n   * @param {Node} target\n   * @constructor\n   */\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = [];\n    this.removedNodes = [];\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n\n  function copyMutationRecord(original) {\n    var record = new MutationRecord(original.type, original.target);\n    record.addedNodes = original.addedNodes.slice();\n    record.removedNodes = original.removedNodes.slice();\n    record.previousSibling = original.previousSibling;\n    record.nextSibling = original.nextSibling;\n    record.attributeName = original.attributeName;\n    record.attributeNamespace = original.attributeNamespace;\n    record.oldValue = original.oldValue;\n    return record;\n  };\n\n  // We keep track of the two (possibly one) records used in a single mutation.\n  var currentRecord, recordWithOldValue;\n\n  /**\n   * Creates a record without |oldValue| and caches it as |currentRecord| for\n   * later use.\n   * @param {string} oldValue\n   * @return {MutationRecord}\n   */\n  function getRecord(type, target) {\n    return currentRecord = new MutationRecord(type, target);\n  }\n\n  /**\n   * Gets or creates a record with |oldValue| based in the |currentRecord|\n   * @param {string} oldValue\n   * @return {MutationRecord}\n   */\n  function getRecordWithOldValue(oldValue) {\n    if (recordWithOldValue)\n      return recordWithOldValue;\n    recordWithOldValue = copyMutationRecord(currentRecord);\n    recordWithOldValue.oldValue = oldValue;\n    return recordWithOldValue;\n  }\n\n  function clearRecords() {\n    currentRecord = recordWithOldValue = undefined;\n  }\n\n  /**\n   * @param {MutationRecord} record\n   * @return {boolean} Whether the record represents a record from the current\n   * mutation event.\n   */\n  function recordRepresentsCurrentMutation(record) {\n    return record === recordWithOldValue || record === currentRecord;\n  }\n\n  /**\n   * Selects which record, if any, to replace the last record in the queue.\n   * This returns |null| if no record should be replaced.\n   *\n   * @param {MutationRecord} lastRecord\n   * @param {MutationRecord} newRecord\n   * @param {MutationRecord}\n   */\n  function selectRecord(lastRecord, newRecord) {\n    if (lastRecord === newRecord)\n      return lastRecord;\n\n    // Check if the the record we are adding represents the same record. If\n    // so, we keep the one with the oldValue in it.\n    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))\n      return recordWithOldValue;\n\n    return null;\n  }\n\n  /**\n   * Class used to represent a registered observer.\n   * @param {MutationObserver} observer\n   * @param {Node} target\n   * @param {MutationObserverInit} options\n   * @constructor\n   */\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n\n  Registration.prototype = {\n    enqueue: function(record) {\n      var records = this.observer.records_;\n      var length = records.length;\n\n      // There are cases where we replace the last record with the new record.\n      // For example if the record represents the same mutation we need to use\n      // the one with the oldValue. If we get same record (this can happen as we\n      // walk up the tree) we ignore the new record.\n      if (records.length > 0) {\n        var lastRecord = records[length - 1];\n        var recordToReplaceLast = selectRecord(lastRecord, record);\n        if (recordToReplaceLast) {\n          records[length - 1] = recordToReplaceLast;\n          return;\n        }\n      } else {\n        scheduleCallback(this.observer);\n      }\n\n      records[length] = record;\n    },\n\n    addListeners: function() {\n      this.addListeners_(this.target);\n    },\n\n    addListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes)\n        node.addEventListener('DOMAttrModified', this, true);\n\n      if (options.characterData)\n        node.addEventListener('DOMCharacterDataModified', this, true);\n\n      if (options.childList)\n        node.addEventListener('DOMNodeInserted', this, true);\n\n      if (options.childList || options.subtree)\n        node.addEventListener('DOMNodeRemoved', this, true);\n    },\n\n    removeListeners: function() {\n      this.removeListeners_(this.target);\n    },\n\n    removeListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes)\n        node.removeEventListener('DOMAttrModified', this, true);\n\n      if (options.characterData)\n        node.removeEventListener('DOMCharacterDataModified', this, true);\n\n      if (options.childList)\n        node.removeEventListener('DOMNodeInserted', this, true);\n\n      if (options.childList || options.subtree)\n        node.removeEventListener('DOMNodeRemoved', this, true);\n    },\n\n    /**\n     * Adds a transient observer on node. The transient observer gets removed\n     * next time we deliver the change records.\n     * @param {Node} node\n     */\n    addTransientObserver: function(node) {\n      // Don't add transient observers on the target itself. We already have all\n      // the required listeners set up on the target.\n      if (node === this.target)\n        return;\n\n      this.addListeners_(node);\n      this.transientObservedNodes.push(node);\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        registrationsTable.set(node, registrations = []);\n\n      // We know that registrations does not contain this because we already\n      // checked if node === this.target.\n      registrations.push(this);\n    },\n\n    removeTransientObservers: function() {\n      var transientObservedNodes = this.transientObservedNodes;\n      this.transientObservedNodes = [];\n\n      transientObservedNodes.forEach(function(node) {\n        // Transient observers are never added to the target.\n        this.removeListeners_(node);\n\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          if (registrations[i] === this) {\n            registrations.splice(i, 1);\n            // Each node can only have one registered observer associated with\n            // this observer.\n            break;\n          }\n        }\n      }, this);\n    },\n\n    handleEvent: function(e) {\n      // Stop propagation since we are managing the propagation manually.\n      // This means that other mutation events on the page will not work\n      // correctly but that is by design.\n      e.stopImmediatePropagation();\n\n      switch (e.type) {\n        case 'DOMAttrModified':\n          // http://dom.spec.whatwg.org/#concept-mo-queue-attributes\n\n          var name = e.attrName;\n          var namespace = e.relatedNode.namespaceURI;\n          var target = e.target;\n\n          // 1.\n          var record = new getRecord('attributes', target);\n          record.attributeName = name;\n          record.attributeNamespace = namespace;\n\n          // 2.\n          var oldValue =\n              e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;\n\n          forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n            // 3.1, 4.2\n            if (!options.attributes)\n              return;\n\n            // 3.2, 4.3\n            if (options.attributeFilter && options.attributeFilter.length &&\n                options.attributeFilter.indexOf(name) === -1 &&\n                options.attributeFilter.indexOf(namespace) === -1) {\n              return;\n            }\n            // 3.3, 4.4\n            if (options.attributeOldValue)\n              return getRecordWithOldValue(oldValue);\n\n            // 3.4, 4.5\n            return record;\n          });\n\n          break;\n\n        case 'DOMCharacterDataModified':\n          // http://dom.spec.whatwg.org/#concept-mo-queue-characterdata\n          var target = e.target;\n\n          // 1.\n          var record = getRecord('characterData', target);\n\n          // 2.\n          var oldValue = e.prevValue;\n\n\n          forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n            // 3.1, 4.2\n            if (!options.characterData)\n              return;\n\n            // 3.2, 4.3\n            if (options.characterDataOldValue)\n              return getRecordWithOldValue(oldValue);\n\n            // 3.3, 4.4\n            return record;\n          });\n\n          break;\n\n        case 'DOMNodeRemoved':\n          this.addTransientObserver(e.target);\n          // Fall through.\n        case 'DOMNodeInserted':\n          // http://dom.spec.whatwg.org/#concept-mo-queue-childlist\n          var target = e.relatedNode;\n          var changedNode = e.target;\n          var addedNodes, removedNodes;\n          if (e.type === 'DOMNodeInserted') {\n            addedNodes = [changedNode];\n            removedNodes = [];\n          } else {\n\n            addedNodes = [];\n            removedNodes = [changedNode];\n          }\n          var previousSibling = changedNode.previousSibling;\n          var nextSibling = changedNode.nextSibling;\n\n          // 1.\n          var record = getRecord('childList', target);\n          record.addedNodes = addedNodes;\n          record.removedNodes = removedNodes;\n          record.previousSibling = previousSibling;\n          record.nextSibling = nextSibling;\n\n          forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n            // 2.1, 3.2\n            if (!options.childList)\n              return;\n\n            // 2.2, 3.3\n            return record;\n          });\n\n      }\n\n      clearRecords();\n    }\n  };\n\n  global.JsMutationObserver = JsMutationObserver;\n\n  if (!global.MutationObserver)\n    global.MutationObserver = JsMutationObserver;\n\n\n})(this);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\nwindow.HTMLImports = window.HTMLImports || {flags:{}};","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n  // imports\n  var path = scope.path;\n  var xhr = scope.xhr;\n  var flags = scope.flags;\n\n  // TODO(sorvell): this loader supports a dynamic list of urls\n  // and an oncomplete callback that is called when the loader is done.\n  // The polyfill currently does *not* need this dynamism or the onComplete\n  // concept. Because of this, the loader could be simplified quite a bit.\n  var Loader = function(onLoad, onComplete) {\n    this.cache = {};\n    this.onload = onLoad;\n    this.oncomplete = onComplete;\n    this.inflight = 0;\n    this.pending = {};\n  };\n\n  Loader.prototype = {\n    addNodes: function(nodes) {\n      // number of transactions to complete\n      this.inflight += nodes.length;\n      // commence transactions\n      for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {\n        this.require(n);\n      }\n      // anything to do?\n      this.checkDone();\n    },\n    addNode: function(node) {\n      // number of transactions to complete\n      this.inflight++;\n      // commence transactions\n      this.require(node);\n      // anything to do?\n      this.checkDone();\n    },\n    require: function(elt) {\n      var url = elt.src || elt.href;\n      // ensure we have a standard url that can be used\n      // reliably for deduping.\n      // TODO(sjmiles): ad-hoc\n      elt.__nodeUrl = url;\n      // deduplication\n      if (!this.dedupe(url, elt)) {\n        // fetch this resource\n        this.fetch(url, elt);\n      }\n    },\n    dedupe: function(url, elt) {\n      if (this.pending[url]) {\n        // add to list of nodes waiting for inUrl\n        this.pending[url].push(elt);\n        // don't need fetch\n        return true;\n      }\n      var resource;\n      if (this.cache[url]) {\n        this.onload(url, elt, this.cache[url]);\n        // finished this transaction\n        this.tail();\n        // don't need fetch\n        return true;\n      }\n      // first node waiting for inUrl\n      this.pending[url] = [elt];\n      // need fetch (not a dupe)\n      return false;\n    },\n    fetch: function(url, elt) {\n      flags.load && console.log('fetch', url, elt);\n      var receiveXhr = function(err, resource) {\n        this.receive(url, elt, err, resource);\n      }.bind(this);\n      xhr.load(url, receiveXhr);\n      // TODO(sorvell): blocked on\n      // https://code.google.com/p/chromium/issues/detail?id=257221\n      // xhr'ing for a document makes scripts in imports runnable; otherwise\n      // they are not; however, it requires that we have doctype=html in\n      // the import which is unacceptable. This is only needed on Chrome\n      // to avoid the bug above.\n      /*\n      if (isDocumentLink(elt)) {\n        xhr.loadDocument(url, receiveXhr);\n      } else {\n        xhr.load(url, receiveXhr);\n      }\n      */\n    },\n    receive: function(url, elt, err, resource) {\n      this.cache[url] = resource;\n      var $p = this.pending[url];\n      for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {\n        //if (!err) {\n          this.onload(url, p, resource);\n        //}\n        this.tail();\n      }\n      this.pending[url] = null;\n    },\n    tail: function() {\n      --this.inflight;\n      this.checkDone();\n    },\n    checkDone: function() {\n      if (!this.inflight) {\n        this.oncomplete();\n      }\n    }\n  };\n\n  xhr = xhr || {\n    async: true,\n    ok: function(request) {\n      return (request.status >= 200 && request.status < 300)\n          || (request.status === 304)\n          || (request.status === 0);\n    },\n    load: function(url, next, nextContext) {\n      var request = new XMLHttpRequest();\n      if (scope.flags.debug || scope.flags.bust) {\n        url += '?' + Math.random();\n      }\n      request.open('GET', url, xhr.async);\n      request.addEventListener('readystatechange', function(e) {\n        if (request.readyState === 4) {\n          next.call(nextContext, !xhr.ok(request) && request,\n              request.response || request.responseText, url);\n        }\n      });\n      request.send();\n      return request;\n    },\n    loadDocument: function(url, next, nextContext) {\n      this.load(url, next, nextContext).responseType = 'document';\n    }\n  };\n\n  // exports\n  scope.xhr = xhr;\n  scope.Loader = Loader;\n\n})(window.HTMLImports);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\nvar IMPORT_LINK_TYPE = 'import';\nvar flags = scope.flags;\nvar isIe = /Trident/.test(navigator.userAgent);\n// TODO(sorvell): SD polyfill intrusion\nvar mainDoc = window.ShadowDOMPolyfill ? \n    window.ShadowDOMPolyfill.wrapIfNeeded(document) : document;\n\n// importParser\n// highlander object to manage parsing of imports\n// parses import related elements\n// and ensures proper parse order\n// parse order is enforced by crawling the tree and monitoring which elements\n// have been parsed; async parsing is also supported.\n\n// highlander object for parsing a document tree\nvar importParser = {\n  // parse selectors for main document elements\n  documentSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']',\n  // parse selectors for import document elements\n  importsSelectors: [\n    'link[rel=' + IMPORT_LINK_TYPE + ']',\n    'link[rel=stylesheet]',\n    'style',\n    'script:not([type])',\n    'script[type=\"text/javascript\"]'\n  ].join(','),\n  map: {\n    link: 'parseLink',\n    script: 'parseScript',\n    style: 'parseStyle'\n  },\n  // try to parse the next import in the tree\n  parseNext: function() {\n    var next = this.nextToParse();\n    if (next) {\n      this.parse(next);\n    }\n  },\n  parse: function(elt) {\n    if (this.isParsed(elt)) {\n      flags.parse && console.log('[%s] is already parsed', elt.localName);\n      return;\n    }\n    var fn = this[this.map[elt.localName]];\n    if (fn) {\n      this.markParsing(elt);\n      fn.call(this, elt);\n    }\n  },\n  // only 1 element may be parsed at a time; parsing is async so, each\n  // parsing implementation must inform the system that parsing is complete\n  // via markParsingComplete.\n  markParsing: function(elt) {\n    flags.parse && console.log('parsing', elt);\n    this.parsingElement = elt;\n  },\n  markParsingComplete: function(elt) {\n    elt.__importParsed = true;\n    if (elt.__importElement) {\n      elt.__importElement.__importParsed = true;\n    }\n    this.parsingElement = null;\n    flags.parse && console.log('completed', elt);\n    this.parseNext();\n  },\n  parseImport: function(elt) {\n    elt.import.__importParsed = true;\n    // TODO(sorvell): consider if there's a better way to do this;\n    // expose an imports parsing hook; this is needed, for example, by the\n    // CustomElements polyfill.\n    if (HTMLImports.__importsParsingHook) {\n      HTMLImports.__importsParsingHook(elt);\n    }\n    // fire load event\n    if (elt.__resource) {\n      elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));    \n    } else {\n      elt.dispatchEvent(new CustomEvent('error', {bubbles: false}));\n    }\n    // TODO(sorvell): workaround for Safari addEventListener not working\n    // for elements not in the main document.\n    if (elt.__pending) {\n      var fn;\n      while (elt.__pending.length) {\n        fn = elt.__pending.shift();\n        if (fn) {\n          fn({target: elt});\n        }\n      }\n    }\n    this.markParsingComplete(elt);\n  },\n  parseLink: function(linkElt) {\n    if (nodeIsImport(linkElt)) {\n      this.parseImport(linkElt);\n    } else {\n      // make href absolute\n      linkElt.href = linkElt.href;\n      this.parseGeneric(linkElt);\n    }\n  },\n  parseStyle: function(elt) {\n    // TODO(sorvell): style element load event can just not fire so clone styles\n    var src = elt;\n    elt = cloneStyle(elt);\n    elt.__importElement = src;\n    this.parseGeneric(elt);\n  },\n  parseGeneric: function(elt) {\n    this.trackElement(elt);\n    document.head.appendChild(elt);\n  },\n  // tracks when a loadable element has loaded\n  trackElement: function(elt, callback) {\n    var self = this;\n    var done = function(e) {\n      if (callback) {\n        callback(e);\n      }\n      self.markParsingComplete(elt);\n    };\n    elt.addEventListener('load', done);\n    elt.addEventListener('error', done);\n\n    // NOTE: IE does not fire \"load\" event for styles that have already loaded\n    // This is in violation of the spec, so we try our hardest to work around it\n    if (isIe && elt.localName === 'style') {\n      var fakeLoad = false;\n      // If there's not @import in the textContent, assume it has loaded\n      if (elt.textContent.indexOf('@import') == -1) {\n        fakeLoad = true;\n      // if we have a sheet, we have been parsed\n      } else if (elt.sheet) {\n        fakeLoad = true;\n        var csr = elt.sheet.cssRules;\n        var len = csr ? csr.length : 0;\n        // search the rules for @import's\n        for (var i = 0, r; (i < len) && (r = csr[i]); i++) {\n          if (r.type === CSSRule.IMPORT_RULE) {\n            // if every @import has resolved, fake the load\n            fakeLoad = fakeLoad && Boolean(r.styleSheet);\n          }\n        }\n      }\n      // dispatch a fake load event and continue parsing\n      if (fakeLoad) {\n        elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));\n      }\n    }\n  },\n  // NOTE: execute scripts by injecting them and watching for the load/error\n  // event. Inline scripts are handled via dataURL's because browsers tend to\n  // provide correct parsing errors in this case. If this has any compatibility\n  // issues, we can switch to injecting the inline script with textContent.\n  // Scripts with dataURL's do not appear to generate load events and therefore\n  // we assume they execute synchronously.\n  parseScript: function(scriptElt) {\n    var script = document.createElement('script');\n    script.__importElement = scriptElt;\n    script.src = scriptElt.src ? scriptElt.src : \n        generateScriptDataUrl(scriptElt);\n    scope.currentScript = scriptElt;\n    this.trackElement(script, function(e) {\n      script.parentNode.removeChild(script);\n      scope.currentScript = null;  \n    });\n    document.head.appendChild(script);\n  },\n  // determine the next element in the tree which should be parsed\n  nextToParse: function() {\n    return !this.parsingElement && this.nextToParseInDoc(mainDoc);\n  },\n  nextToParseInDoc: function(doc, link) {\n    var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));\n    for (var i=0, l=nodes.length, p=0, n; (i<l) && (n=nodes[i]); i++) {\n      if (!this.isParsed(n)) {\n        if (this.hasResource(n)) {\n          return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;\n        } else {\n          return;\n        }\n      }\n    }\n    // all nodes have been parsed, ready to parse import, if any\n    return link;\n  },\n  // return the set of parse selectors relevant for this node.\n  parseSelectorsForNode: function(node) {\n    var doc = node.ownerDocument || node;\n    return doc === mainDoc ? this.documentSelectors : this.importsSelectors;\n  },\n  isParsed: function(node) {\n    return node.__importParsed;\n  },\n  hasResource: function(node) {\n    if (nodeIsImport(node) && !node.import) {\n      return false;\n    }\n    return true;\n  }\n};\n\nfunction nodeIsImport(elt) {\n  return (elt.localName === 'link') && (elt.rel === IMPORT_LINK_TYPE);\n}\n\nfunction generateScriptDataUrl(script) {\n  var scriptContent = generateScriptContent(script), b64;\n  try {\n    b64 = btoa(scriptContent);\n  } catch(e) {\n    b64 = btoa(unescape(encodeURIComponent(scriptContent)));\n    console.warn('Script contained non-latin characters that were forced ' +\n      'to latin. Some characters may be wrong.', script);\n  }\n  return 'data:text/javascript;base64,' + b64;\n}\n\nfunction generateScriptContent(script) {\n  return script.textContent + generateSourceMapHint(script);\n}\n\n// calculate source map hint\nfunction generateSourceMapHint(script) {\n  var moniker = script.__nodeUrl;\n  if (!moniker) {\n    moniker = script.ownerDocument.baseURI;\n    // there could be more than one script this url\n    var tag = '[' + Math.floor((Math.random()+1)*1000) + ']';\n    // TODO(sjmiles): Polymer hack, should be pluggable if we need to allow \n    // this sort of thing\n    var matches = script.textContent.match(/Polymer\\(['\"]([^'\"]*)/);\n    tag = matches && matches[1] || tag;\n    // tag the moniker\n    moniker += '/' + tag + '.js';\n  }\n  return '\\n//# sourceURL=' + moniker + '\\n';\n}\n\n// style/stylesheet handling\n\n// clone style with proper path resolution for main document\n// NOTE: styles are the only elements that require direct path fixup.\nfunction cloneStyle(style) {\n  var clone = style.ownerDocument.createElement('style');\n  clone.textContent = style.textContent;\n  path.resolveUrlsInStyle(clone);\n  return clone;\n}\n\n// path fixup: style elements in imports must be made relative to the main \n// document. We fixup url's in url() and @import.\nvar CSS_URL_REGEXP = /(url\\()([^)]*)(\\))/g;\nvar CSS_IMPORT_REGEXP = /(@import[\\s]+(?!url\\())([^;]*)(;)/g;\n\nvar path = {\n  resolveUrlsInStyle: function(style) {\n    var doc = style.ownerDocument;\n    var resolver = doc.createElement('a');\n    style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);\n    return style;  \n  },\n  resolveUrlsInCssText: function(cssText, urlObj) {\n    var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);\n    r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP);\n    return r;\n  },\n  replaceUrls: function(text, urlObj, regexp) {\n    return text.replace(regexp, function(m, pre, url, post) {\n      var urlPath = url.replace(/[\"']/g, '');\n      urlObj.href = urlPath;\n      urlPath = urlObj.href;\n      return pre + '\\'' + urlPath + '\\'' + post;\n    });    \n  }\n}\n\n// exports\nscope.parser = importParser;\nscope.path = path;\nscope.isIE = isIe;\n\n})(HTMLImports);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\nvar hasNative = ('import' in document.createElement('link'));\nvar useNative = hasNative;\nvar flags = scope.flags;\nvar IMPORT_LINK_TYPE = 'import';\n\n// TODO(sorvell): SD polyfill intrusion\nvar mainDoc = window.ShadowDOMPolyfill ? \n    ShadowDOMPolyfill.wrapIfNeeded(document) : document;\n\nif (!useNative) {\n\n  // imports\n  var xhr = scope.xhr;\n  var Loader = scope.Loader;\n  var parser = scope.parser;\n\n  // importer\n  // highlander object to manage loading of imports\n\n  // for any document, importer:\n  // - loads any linked import documents (with deduping)\n\n  var importer = {\n    documents: {},\n    // nodes to load in the mian document\n    documentPreloadSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']',\n    // nodes to load in imports\n    importsPreloadSelectors: [\n      'link[rel=' + IMPORT_LINK_TYPE + ']'\n    ].join(','),\n    loadNode: function(node) {\n      importLoader.addNode(node);\n    },\n    // load all loadable elements within the parent element\n    loadSubtree: function(parent) {\n      var nodes = this.marshalNodes(parent);\n      // add these nodes to loader's queue\n      importLoader.addNodes(nodes);\n    },\n    marshalNodes: function(parent) {\n      // all preloadable nodes in inDocument\n      return parent.querySelectorAll(this.loadSelectorsForNode(parent));\n    },\n    // find the proper set of load selectors for a given node\n    loadSelectorsForNode: function(node) {\n      var doc = node.ownerDocument || node;\n      return doc === mainDoc ? this.documentPreloadSelectors :\n          this.importsPreloadSelectors;\n    },\n    loaded: function(url, elt, resource) {\n      flags.load && console.log('loaded', url, elt);\n      // store generic resource\n      // TODO(sorvell): fails for nodes inside <template>.content\n      // see https://code.google.com/p/chromium/issues/detail?id=249381.\n      elt.__resource = resource;\n      if (isDocumentLink(elt)) {\n        var doc = this.documents[url];\n        // if we've never seen a document at this url\n        if (!doc) {\n          // generate an HTMLDocument from data\n          doc = makeDocument(resource, url);\n          doc.__importLink = elt;\n          // TODO(sorvell): we cannot use MO to detect parsed nodes because\n          // SD polyfill does not report these as mutations.\n          this.bootDocument(doc);\n          // cache document\n          this.documents[url] = doc;\n        }\n        // don't store import record until we're actually loaded\n        // store document resource\n        elt.import = doc;\n      }\n      parser.parseNext();\n    },\n    bootDocument: function(doc) {\n      this.loadSubtree(doc);\n      this.observe(doc);\n      parser.parseNext();\n    },\n    loadedAll: function() {\n      parser.parseNext();\n    }\n  };\n\n  // loader singleton\n  var importLoader = new Loader(importer.loaded.bind(importer), \n      importer.loadedAll.bind(importer));\n\n  function isDocumentLink(elt) {\n    return isLinkRel(elt, IMPORT_LINK_TYPE);\n  }\n\n  function isLinkRel(elt, rel) {\n    return elt.localName === 'link' && elt.getAttribute('rel') === rel;\n  }\n\n  function isScript(elt) {\n    return elt.localName === 'script';\n  }\n\n  function makeDocument(resource, url) {\n    // create a new HTML document\n    var doc = resource;\n    if (!(doc instanceof Document)) {\n      doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);\n    }\n    // cache the new document's source url\n    doc._URL = url;\n    // establish a relative path via <base>\n    var base = doc.createElement('base');\n    base.setAttribute('href', url);\n    // add baseURI support to browsers (IE) that lack it.\n    if (!doc.baseURI) {\n      doc.baseURI = url;\n    }\n    // ensure UTF-8 charset\n    var meta = doc.createElement('meta');\n    meta.setAttribute('charset', 'utf-8');\n\n    doc.head.appendChild(meta);\n    doc.head.appendChild(base);\n    // install HTML last as it may trigger CustomElement upgrades\n    // TODO(sjmiles): problem wrt to template boostrapping below,\n    // template bootstrapping must (?) come before element upgrade\n    // but we cannot bootstrap templates until they are in a document\n    // which is too late\n    if (!(resource instanceof Document)) {\n      // install html\n      doc.body.innerHTML = resource;\n    }\n    // TODO(sorvell): ideally this code is not aware of Template polyfill,\n    // but for now the polyfill needs help to bootstrap these templates\n    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {\n      HTMLTemplateElement.bootstrap(doc);\n    }\n    return doc;\n  }\n} else {\n  // do nothing if using native imports\n  var importer = {};\n}\n\n// NOTE: We cannot polyfill document.currentScript because it's not possible\n// both to override and maintain the ability to capture the native value;\n// therefore we choose to expose _currentScript both when native imports\n// and the polyfill are in use.\nvar currentScriptDescriptor = {\n  get: function() {\n    return HTMLImports.currentScript || document.currentScript;\n  },\n  configurable: true\n};\n\nObject.defineProperty(document, '_currentScript', currentScriptDescriptor);\nObject.defineProperty(mainDoc, '_currentScript', currentScriptDescriptor);\n\n// Polyfill document.baseURI for browsers without it.\nif (!document.baseURI) {\n  var baseURIDescriptor = {\n    get: function() {\n      return window.location.href;\n    },\n    configurable: true\n  };\n\n  Object.defineProperty(document, 'baseURI', baseURIDescriptor);\n  Object.defineProperty(mainDoc, 'baseURI', baseURIDescriptor);\n}\n\n// call a callback when all HTMLImports in the document at call (or at least\n//  document ready) time have loaded.\n// 1. ensure the document is in a ready state (has dom), then \n// 2. watch for loading of imports and call callback when done\nfunction whenImportsReady(callback, doc) {\n  doc = doc || mainDoc;\n  // if document is loading, wait and try again\n  whenDocumentReady(function() {\n    watchImportsLoad(callback, doc);\n  }, doc);\n}\n\n// call the callback when the document is in a ready state (has dom)\nvar requiredReadyState = HTMLImports.isIE ? 'complete' : 'interactive';\nvar READY_EVENT = 'readystatechange';\nfunction isDocumentReady(doc) {\n  return (doc.readyState === 'complete' ||\n      doc.readyState === requiredReadyState);\n}\n\n// call <callback> when we ensure the document is in a ready state\nfunction whenDocumentReady(callback, doc) {\n  if (!isDocumentReady(doc)) {\n    var checkReady = function() {\n      if (doc.readyState === 'complete' || \n          doc.readyState === requiredReadyState) {\n        doc.removeEventListener(READY_EVENT, checkReady);\n        whenDocumentReady(callback, doc);\n      }\n    }\n    doc.addEventListener(READY_EVENT, checkReady);\n  } else if (callback) {\n    callback();\n  }\n}\n\n// call <callback> when we ensure all imports have loaded\nfunction watchImportsLoad(callback, doc) {\n  var imports = doc.querySelectorAll('link[rel=import]');\n  var loaded = 0, l = imports.length;\n  function checkDone(d) { \n    if (loaded == l) {\n      // go async to ensure parser isn't stuck on a script tag\n      requestAnimationFrame(callback);\n    }\n  }\n  function loadedImport(e) {\n    loaded++;\n    checkDone();\n  }\n  if (l) {\n    for (var i=0, imp; (i<l) && (imp=imports[i]); i++) {\n      if (isImportLoaded(imp)) {\n        loadedImport.call(imp);\n      } else {\n        imp.addEventListener('load', loadedImport);\n        imp.addEventListener('error', loadedImport);\n      }\n    }\n  } else {\n    checkDone();\n  }\n}\n\nfunction isImportLoaded(link) {\n  return useNative ? (link.import && (link.import.readyState !== 'loading')) :\n      link.__importParsed;\n}\n\n// exports\nscope.hasNative = hasNative;\nscope.useNative = useNative;\nscope.importer = importer;\nscope.whenImportsReady = whenImportsReady;\nscope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\nscope.isImportLoaded = isImportLoaded;\nscope.importLoader = importLoader;\n\n})(window.HTMLImports);\n"," /*\nCopyright 2013 The Polymer Authors. All rights reserved.\nUse of this source code is governed by a BSD-style\nlicense that can be found in the LICENSE file.\n*/\n\n(function(scope){\n\nvar IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\nvar importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']';\nvar importer = scope.importer;\n\n// we track mutations for addedNodes, looking for imports\nfunction handler(mutations) {\n  for (var i=0, l=mutations.length, m; (i<l) && (m=mutations[i]); i++) {\n    if (m.type === 'childList' && m.addedNodes.length) {\n      addedNodes(m.addedNodes);\n    }\n  }\n}\n\n// find loadable elements and add them to the importer\nfunction addedNodes(nodes) {\n  for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {\n    if (shouldLoadNode(n)) {\n      importer.loadNode(n);\n    }\n    if (n.children && n.children.length) {\n      addedNodes(n.children);\n    }\n  }\n}\n\nfunction shouldLoadNode(node) {\n  return (node.nodeType === 1) && matches.call(node,\n      importer.loadSelectorsForNode(node));\n}\n\n// x-plat matches\nvar matches = HTMLElement.prototype.matches || \n    HTMLElement.prototype.matchesSelector || \n    HTMLElement.prototype.webkitMatchesSelector ||\n    HTMLElement.prototype.mozMatchesSelector ||\n    HTMLElement.prototype.msMatchesSelector;\n\nvar observer = new MutationObserver(handler);\n\n// observe the given root for loadable elements\nfunction observe(root) {\n  observer.observe(root, {childList: true, subtree: true});\n}\n\n// exports\n// TODO(sorvell): factor so can put on scope\nscope.observe = observe;\nimporter.observe = observe;\n\n})(HTMLImports);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(){\n\n// bootstrap\n\n// IE shim for CustomEvent\nif (typeof window.CustomEvent !== 'function') {\n  window.CustomEvent = function(inType, dictionary) {\n     var e = document.createEvent('HTMLEvents');\n     e.initEvent(inType,\n        dictionary.bubbles === false ? false : true,\n        dictionary.cancelable === false ? false : true,\n        dictionary.detail);\n     return e;\n  };\n}\n\n// TODO(sorvell): SD polyfill intrusion\nvar doc = window.ShadowDOMPolyfill ? \n    window.ShadowDOMPolyfill.wrapIfNeeded(document) : document;\n\n// Fire the 'HTMLImportsLoaded' event when imports in document at load time \n// have loaded. This event is required to simulate the script blocking \n// behavior of native imports. A main document script that needs to be sure\n// imports have loaded should wait for this event.\nHTMLImports.whenImportsReady(function() {\n  HTMLImports.ready = true;\n  HTMLImports.readyTime = new Date().getTime();\n  doc.dispatchEvent(\n    new CustomEvent('HTMLImportsLoaded', {bubbles: true})\n  );\n});\n\n\n// no need to bootstrap the polyfill when native imports is available.\nif (!HTMLImports.useNative) {\n  function bootstrap() {\n    HTMLImports.importer.bootDocument(doc);\n  }\n    \n  // TODO(sorvell): SD polyfill does *not* generate mutations for nodes added\n  // by the parser. For this reason, we must wait until the dom exists to \n  // bootstrap.\n  if (document.readyState === 'complete' ||\n      (document.readyState === 'interactive' && !window.attachEvent)) {\n    bootstrap();\n  } else {\n    document.addEventListener('DOMContentLoaded', bootstrap);\n  }\n}\n\n})();\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\nwindow.CustomElements = window.CustomElements || {flags:{}};"," /*\r\nCopyright 2013 The Polymer Authors. All rights reserved.\r\nUse of this source code is governed by a BSD-style\r\nlicense that can be found in the LICENSE file.\r\n*/\r\n\r\n(function(scope){\r\n\r\nvar logFlags = window.logFlags || {};\r\nvar IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';\r\n\r\n// walk the subtree rooted at node, applying 'find(element, data)' function\r\n// to each element\r\n// if 'find' returns true for 'element', do not search element's subtree\r\nfunction findAll(node, find, data) {\r\n  var e = node.firstElementChild;\r\n  if (!e) {\r\n    e = node.firstChild;\r\n    while (e && e.nodeType !== Node.ELEMENT_NODE) {\r\n      e = e.nextSibling;\r\n    }\r\n  }\r\n  while (e) {\r\n    if (find(e, data) !== true) {\r\n      findAll(e, find, data);\r\n    }\r\n    e = e.nextElementSibling;\r\n  }\r\n  return null;\r\n}\r\n\r\n// walk all shadowRoots on a given node.\r\nfunction forRoots(node, cb) {\r\n  var root = node.shadowRoot;\r\n  while(root) {\r\n    forSubtree(root, cb);\r\n    root = root.olderShadowRoot;\r\n  }\r\n}\r\n\r\n// walk the subtree rooted at node, including descent into shadow-roots,\r\n// applying 'cb' to each element\r\nfunction forSubtree(node, cb) {\r\n  //logFlags.dom && node.childNodes && node.childNodes.length && console.group('subTree: ', node);\r\n  findAll(node, function(e) {\r\n    if (cb(e)) {\r\n      return true;\r\n    }\r\n    forRoots(e, cb);\r\n  });\r\n  forRoots(node, cb);\r\n  //logFlags.dom && node.childNodes && node.childNodes.length && console.groupEnd();\r\n}\r\n\r\n// manage lifecycle on added node\r\nfunction added(node) {\r\n  if (upgrade(node)) {\r\n    insertedNode(node);\r\n    return true;\r\n  }\r\n  inserted(node);\r\n}\r\n\r\n// manage lifecycle on added node's subtree only\r\nfunction addedSubtree(node) {\r\n  forSubtree(node, function(e) {\r\n    if (added(e)) {\r\n      return true;\r\n    }\r\n  });\r\n}\r\n\r\n// manage lifecycle on added node and it's subtree\r\nfunction addedNode(node) {\r\n  return added(node) || addedSubtree(node);\r\n}\r\n\r\n// upgrade custom elements at node, if applicable\r\nfunction upgrade(node) {\r\n  if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {\r\n    var type = node.getAttribute('is') || node.localName;\r\n    var definition = scope.registry[type];\r\n    if (definition) {\r\n      logFlags.dom && console.group('upgrade:', node.localName);\r\n      scope.upgrade(node);\r\n      logFlags.dom && console.groupEnd();\r\n      return true;\r\n    }\r\n  }\r\n}\r\n\r\nfunction insertedNode(node) {\r\n  inserted(node);\r\n  if (inDocument(node)) {\r\n    forSubtree(node, function(e) {\r\n      inserted(e);\r\n    });\r\n  }\r\n}\r\n\r\n// TODO(sorvell): on platforms without MutationObserver, mutations may not be\r\n// reliable and therefore attached/detached are not reliable.\r\n// To make these callbacks less likely to fail, we defer all inserts and removes\r\n// to give a chance for elements to be inserted into dom.\r\n// This ensures attachedCallback fires for elements that are created and\r\n// immediately added to dom.\r\nvar hasPolyfillMutations = (!window.MutationObserver ||\r\n    (window.MutationObserver === window.JsMutationObserver));\r\nscope.hasPolyfillMutations = hasPolyfillMutations;\r\n\r\nvar isPendingMutations = false;\r\nvar pendingMutations = [];\r\nfunction deferMutation(fn) {\r\n  pendingMutations.push(fn);\r\n  if (!isPendingMutations) {\r\n    isPendingMutations = true;\r\n    var async = (window.Platform && window.Platform.endOfMicrotask) ||\r\n        setTimeout;\r\n    async(takeMutations);\r\n  }\r\n}\r\n\r\nfunction takeMutations() {\r\n  isPendingMutations = false;\r\n  var $p = pendingMutations;\r\n  for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {\r\n    p();\r\n  }\r\n  pendingMutations = [];\r\n}\r\n\r\nfunction inserted(element) {\r\n  if (hasPolyfillMutations) {\r\n    deferMutation(function() {\r\n      _inserted(element);\r\n    });\r\n  } else {\r\n    _inserted(element);\r\n  }\r\n}\r\n\r\n// TODO(sjmiles): if there are descents into trees that can never have inDocument(*) true, fix this\r\nfunction _inserted(element) {\r\n  // TODO(sjmiles): it's possible we were inserted and removed in the space\r\n  // of one microtask, in which case we won't be 'inDocument' here\r\n  // But there are other cases where we are testing for inserted without\r\n  // specific knowledge of mutations, and must test 'inDocument' to determine\r\n  // whether to call inserted\r\n  // If we can factor these cases into separate code paths we can have\r\n  // better diagnostics.\r\n  // TODO(sjmiles): when logging, do work on all custom elements so we can\r\n  // track behavior even when callbacks not defined\r\n  //console.log('inserted: ', element.localName);\r\n  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {\r\n    logFlags.dom && console.group('inserted:', element.localName);\r\n    if (inDocument(element)) {\r\n      element.__inserted = (element.__inserted || 0) + 1;\r\n      // if we are in a 'removed' state, bluntly adjust to an 'inserted' state\r\n      if (element.__inserted < 1) {\r\n        element.__inserted = 1;\r\n      }\r\n      // if we are 'over inserted', squelch the callback\r\n      if (element.__inserted > 1) {\r\n        logFlags.dom && console.warn('inserted:', element.localName,\r\n          'insert/remove count:', element.__inserted)\r\n      } else if (element.attachedCallback) {\r\n        logFlags.dom && console.log('inserted:', element.localName);\r\n        element.attachedCallback();\r\n      }\r\n    }\r\n    logFlags.dom && console.groupEnd();\r\n  }\r\n}\r\n\r\nfunction removedNode(node) {\r\n  removed(node);\r\n  forSubtree(node, function(e) {\r\n    removed(e);\r\n  });\r\n}\r\n\r\nfunction removed(element) {\r\n  if (hasPolyfillMutations) {\r\n    deferMutation(function() {\r\n      _removed(element);\r\n    });\r\n  } else {\r\n    _removed(element);\r\n  }\r\n}\r\n\r\nfunction _removed(element) {\r\n  // TODO(sjmiles): temporary: do work on all custom elements so we can track\r\n  // behavior even when callbacks not defined\r\n  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {\r\n    logFlags.dom && console.group('removed:', element.localName);\r\n    if (!inDocument(element)) {\r\n      element.__inserted = (element.__inserted || 0) - 1;\r\n      // if we are in a 'inserted' state, bluntly adjust to an 'removed' state\r\n      if (element.__inserted > 0) {\r\n        element.__inserted = 0;\r\n      }\r\n      // if we are 'over removed', squelch the callback\r\n      if (element.__inserted < 0) {\r\n        logFlags.dom && console.warn('removed:', element.localName,\r\n            'insert/remove count:', element.__inserted)\r\n      } else if (element.detachedCallback) {\r\n        element.detachedCallback();\r\n      }\r\n    }\r\n    logFlags.dom && console.groupEnd();\r\n  }\r\n}\r\n\r\n// SD polyfill intrustion due mainly to the fact that 'document'\r\n// is not entirely wrapped\r\nfunction wrapIfNeeded(node) {\r\n  return window.ShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node)\r\n      : node;\r\n}\r\n\r\nfunction inDocument(element) {\r\n  var p = element;\r\n  var doc = wrapIfNeeded(document);\r\n  while (p) {\r\n    if (p == doc) {\r\n      return true;\r\n    }\r\n    p = p.parentNode || p.host;\r\n  }\r\n}\r\n\r\nfunction watchShadow(node) {\r\n  if (node.shadowRoot && !node.shadowRoot.__watched) {\r\n    logFlags.dom && console.log('watching shadow-root for: ', node.localName);\r\n    // watch all unwatched roots...\r\n    var root = node.shadowRoot;\r\n    while (root) {\r\n      watchRoot(root);\r\n      root = root.olderShadowRoot;\r\n    }\r\n  }\r\n}\r\n\r\nfunction watchRoot(root) {\r\n  if (!root.__watched) {\r\n    observe(root);\r\n    root.__watched = true;\r\n  }\r\n}\r\n\r\nfunction handler(mutations) {\r\n  //\r\n  if (logFlags.dom) {\r\n    var mx = mutations[0];\r\n    if (mx && mx.type === 'childList' && mx.addedNodes) {\r\n        if (mx.addedNodes) {\r\n          var d = mx.addedNodes[0];\r\n          while (d && d !== document && !d.host) {\r\n            d = d.parentNode;\r\n          }\r\n          var u = d && (d.URL || d._URL || (d.host && d.host.localName)) || '';\r\n          u = u.split('/?').shift().split('/').pop();\r\n        }\r\n    }\r\n    console.group('mutations (%d) [%s]', mutations.length, u || '');\r\n  }\r\n  //\r\n  mutations.forEach(function(mx) {\r\n    //logFlags.dom && console.group('mutation');\r\n    if (mx.type === 'childList') {\r\n      forEach(mx.addedNodes, function(n) {\r\n        //logFlags.dom && console.log(n.localName);\r\n        if (!n.localName) {\r\n          return;\r\n        }\r\n        // nodes added may need lifecycle management\r\n        addedNode(n);\r\n      });\r\n      // removed nodes may need lifecycle management\r\n      forEach(mx.removedNodes, function(n) {\r\n        //logFlags.dom && console.log(n.localName);\r\n        if (!n.localName) {\r\n          return;\r\n        }\r\n        removedNode(n);\r\n      });\r\n    }\r\n    //logFlags.dom && console.groupEnd();\r\n  });\r\n  logFlags.dom && console.groupEnd();\r\n};\r\n\r\nvar observer = new MutationObserver(handler);\r\n\r\nfunction takeRecords() {\r\n  // TODO(sjmiles): ask Raf why we have to call handler ourselves\r\n  handler(observer.takeRecords());\r\n  takeMutations();\r\n}\r\n\r\nvar forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\r\n\r\nfunction observe(inRoot) {\r\n  observer.observe(inRoot, {childList: true, subtree: true});\r\n}\r\n\r\nfunction observeDocument(doc) {\r\n  observe(doc);\r\n}\r\n\r\nfunction upgradeDocument(doc) {\r\n  logFlags.dom && console.group('upgradeDocument: ', (doc.baseURI).split('/').pop());\r\n  addedNode(doc);\r\n  logFlags.dom && console.groupEnd();\r\n}\r\n\r\nfunction upgradeDocumentTree(doc) {\r\n  doc = wrapIfNeeded(doc);\r\n  //console.log('upgradeDocumentTree: ', (doc.baseURI).split('/').pop());\r\n  // upgrade contained imported documents\r\n  var imports = doc.querySelectorAll('link[rel=' + IMPORT_LINK_TYPE + ']');\r\n  for (var i=0, l=imports.length, n; (i<l) && (n=imports[i]); i++) {\r\n    if (n.import && n.import.__parsed) {\r\n      upgradeDocumentTree(n.import);\r\n    }\r\n  }\r\n  upgradeDocument(doc);\r\n}\r\n\r\n// exports\r\nscope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\r\nscope.watchShadow = watchShadow;\r\nscope.upgradeDocumentTree = upgradeDocumentTree;\r\nscope.upgradeAll = addedNode;\r\nscope.upgradeSubtree = addedSubtree;\r\nscope.insertedNode = insertedNode;\r\n\r\nscope.observeDocument = observeDocument;\r\nscope.upgradeDocument = upgradeDocument;\r\n\r\nscope.takeRecords = takeRecords;\r\n\r\n})(window.CustomElements);\r\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * Implements `document.register`\n * @module CustomElements\n*/\n\n/**\n * Polyfilled extensions to the `document` object.\n * @class Document\n*/\n\n(function(scope) {\n\n// imports\n\nif (!scope) {\n  scope = window.CustomElements = {flags:{}};\n}\nvar flags = scope.flags;\n\n// native document.registerElement?\n\nvar hasNative = Boolean(document.registerElement);\n// TODO(sorvell): See https://github.com/Polymer/polymer/issues/399\n// we'll address this by defaulting to CE polyfill in the presence of the SD\n// polyfill. This will avoid spamming excess attached/detached callbacks.\n// If there is a compelling need to run CE native with SD polyfill,\n// we'll need to fix this issue.\nvar useNative = !flags.register && hasNative && !window.ShadowDOMPolyfill;\n\nif (useNative) {\n\n  // stub\n  var nop = function() {};\n\n  // exports\n  scope.registry = {};\n  scope.upgradeElement = nop;\n\n  scope.watchShadow = nop;\n  scope.upgrade = nop;\n  scope.upgradeAll = nop;\n  scope.upgradeSubtree = nop;\n  scope.observeDocument = nop;\n  scope.upgradeDocument = nop;\n  scope.upgradeDocumentTree = nop;\n  scope.takeRecords = nop;\n\n} else {\n\n  /**\n   * Registers a custom tag name with the document.\n   *\n   * When a registered element is created, a `readyCallback` method is called\n   * in the scope of the element. The `readyCallback` method can be specified on\n   * either `options.prototype` or `options.lifecycle` with the latter taking\n   * precedence.\n   *\n   * @method register\n   * @param {String} name The tag name to register. Must include a dash ('-'),\n   *    for example 'x-component'.\n   * @param {Object} options\n   *    @param {String} [options.extends]\n   *      (_off spec_) Tag name of an element to extend (or blank for a new\n   *      element). This parameter is not part of the specification, but instead\n   *      is a hint for the polyfill because the extendee is difficult to infer.\n   *      Remember that the input prototype must chain to the extended element's\n   *      prototype (or HTMLElement.prototype) regardless of the value of\n   *      `extends`.\n   *    @param {Object} options.prototype The prototype to use for the new\n   *      element. The prototype must inherit from HTMLElement.\n   *    @param {Object} [options.lifecycle]\n   *      Callbacks that fire at important phases in the life of the custom\n   *      element.\n   *\n   * @example\n   *      FancyButton = document.registerElement(\"fancy-button\", {\n   *        extends: 'button',\n   *        prototype: Object.create(HTMLButtonElement.prototype, {\n   *          readyCallback: {\n   *            value: function() {\n   *              console.log(\"a fancy-button was created\",\n   *            }\n   *          }\n   *        })\n   *      });\n   * @return {Function} Constructor for the newly registered type.\n   */\n  function register(name, options) {\n    //console.warn('document.registerElement(\"' + name + '\", ', options, ')');\n    // construct a defintion out of options\n    // TODO(sjmiles): probably should clone options instead of mutating it\n    var definition = options || {};\n    if (!name) {\n      // TODO(sjmiles): replace with more appropriate error (EricB can probably\n      // offer guidance)\n      throw new Error('document.registerElement: first argument `name` must not be empty');\n    }\n    if (name.indexOf('-') < 0) {\n      // TODO(sjmiles): replace with more appropriate error (EricB can probably\n      // offer guidance)\n      throw new Error('document.registerElement: first argument (\\'name\\') must contain a dash (\\'-\\'). Argument provided was \\'' + String(name) + '\\'.');\n    }\n    // elements may only be registered once\n    if (getRegisteredDefinition(name)) {\n      throw new Error('DuplicateDefinitionError: a type with name \\'' + String(name) + '\\' is already registered');\n    }\n    // must have a prototype, default to an extension of HTMLElement\n    // TODO(sjmiles): probably should throw if no prototype, check spec\n    if (!definition.prototype) {\n      // TODO(sjmiles): replace with more appropriate error (EricB can probably\n      // offer guidance)\n      throw new Error('Options missing required prototype property');\n    }\n    // record name\n    definition.__name = name.toLowerCase();\n    // ensure a lifecycle object so we don't have to null test it\n    definition.lifecycle = definition.lifecycle || {};\n    // build a list of ancestral custom elements (for native base detection)\n    // TODO(sjmiles): we used to need to store this, but current code only\n    // uses it in 'resolveTagName': it should probably be inlined\n    definition.ancestry = ancestry(definition.extends);\n    // extensions of native specializations of HTMLElement require localName\n    // to remain native, and use secondary 'is' specifier for extension type\n    resolveTagName(definition);\n    // some platforms require modifications to the user-supplied prototype\n    // chain\n    resolvePrototypeChain(definition);\n    // overrides to implement attributeChanged callback\n    overrideAttributeApi(definition.prototype);\n    // 7.1.5: Register the DEFINITION with DOCUMENT\n    registerDefinition(definition.__name, definition);\n    // 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE\n    // 7.1.8. Return the output of the previous step.\n    definition.ctor = generateConstructor(definition);\n    definition.ctor.prototype = definition.prototype;\n    // force our .constructor to be our actual constructor\n    definition.prototype.constructor = definition.ctor;\n    // if initial parsing is complete\n    if (scope.ready) {\n      // upgrade any pre-existing nodes of this type\n      scope.upgradeDocumentTree(document);\n    }\n    return definition.ctor;\n  }\n\n  function ancestry(extnds) {\n    var extendee = getRegisteredDefinition(extnds);\n    if (extendee) {\n      return ancestry(extendee.extends).concat([extendee]);\n    }\n    return [];\n  }\n\n  function resolveTagName(definition) {\n    // if we are explicitly extending something, that thing is our\n    // baseTag, unless it represents a custom component\n    var baseTag = definition.extends;\n    // if our ancestry includes custom components, we only have a\n    // baseTag if one of them does\n    for (var i=0, a; (a=definition.ancestry[i]); i++) {\n      baseTag = a.is && a.tag;\n    }\n    // our tag is our baseTag, if it exists, and otherwise just our name\n    definition.tag = baseTag || definition.__name;\n    if (baseTag) {\n      // if there is a base tag, use secondary 'is' specifier\n      definition.is = definition.__name;\n    }\n  }\n\n  function resolvePrototypeChain(definition) {\n    // if we don't support __proto__ we need to locate the native level\n    // prototype for precise mixing in\n    if (!Object.__proto__) {\n      // default prototype\n      var nativePrototype = HTMLElement.prototype;\n      // work out prototype when using type-extension\n      if (definition.is) {\n        var inst = document.createElement(definition.tag);\n        nativePrototype = Object.getPrototypeOf(inst);\n      }\n      // ensure __proto__ reference is installed at each point on the prototype\n      // chain.\n      // NOTE: On platforms without __proto__, a mixin strategy is used instead\n      // of prototype swizzling. In this case, this generated __proto__ provides\n      // limited support for prototype traversal.\n      var proto = definition.prototype, ancestor;\n      while (proto && (proto !== nativePrototype)) {\n        var ancestor = Object.getPrototypeOf(proto);\n        proto.__proto__ = ancestor;\n        proto = ancestor;\n      }\n    }\n    // cache this in case of mixin\n    definition.native = nativePrototype;\n  }\n\n  // SECTION 4\n\n  function instantiate(definition) {\n    // 4.a.1. Create a new object that implements PROTOTYPE\n    // 4.a.2. Let ELEMENT by this new object\n    //\n    // the custom element instantiation algorithm must also ensure that the\n    // output is a valid DOM element with the proper wrapper in place.\n    //\n    return upgrade(domCreateElement(definition.tag), definition);\n  }\n\n  function upgrade(element, definition) {\n    // some definitions specify an 'is' attribute\n    if (definition.is) {\n      element.setAttribute('is', definition.is);\n    }\n    // remove 'unresolved' attr, which is a standin for :unresolved.\n    element.removeAttribute('unresolved');\n    // make 'element' implement definition.prototype\n    implement(element, definition);\n    // flag as upgraded\n    element.__upgraded__ = true;\n    // lifecycle management\n    created(element);\n    // attachedCallback fires in tree order, call before recursing\n    scope.insertedNode(element);\n    // there should never be a shadow root on element at this point\n    scope.upgradeSubtree(element);\n    // OUTPUT\n    return element;\n  }\n\n  function implement(element, definition) {\n    // prototype swizzling is best\n    if (Object.__proto__) {\n      element.__proto__ = definition.prototype;\n    } else {\n      // where above we can re-acquire inPrototype via\n      // getPrototypeOf(Element), we cannot do so when\n      // we use mixin, so we install a magic reference\n      customMixin(element, definition.prototype, definition.native);\n      element.__proto__ = definition.prototype;\n    }\n  }\n\n  function customMixin(inTarget, inSrc, inNative) {\n    // TODO(sjmiles): 'used' allows us to only copy the 'youngest' version of\n    // any property. This set should be precalculated. We also need to\n    // consider this for supporting 'super'.\n    var used = {};\n    // start with inSrc\n    var p = inSrc;\n    // The default is HTMLElement.prototype, so we add a test to avoid mixing in\n    // native prototypes\n    while (p !== inNative && p !== HTMLElement.prototype) {\n      var keys = Object.getOwnPropertyNames(p);\n      for (var i=0, k; k=keys[i]; i++) {\n        if (!used[k]) {\n          Object.defineProperty(inTarget, k,\n              Object.getOwnPropertyDescriptor(p, k));\n          used[k] = 1;\n        }\n      }\n      p = Object.getPrototypeOf(p);\n    }\n  }\n\n  function created(element) {\n    // invoke createdCallback\n    if (element.createdCallback) {\n      element.createdCallback();\n    }\n  }\n\n  // attribute watching\n\n  function overrideAttributeApi(prototype) {\n    // overrides to implement callbacks\n    // TODO(sjmiles): should support access via .attributes NamedNodeMap\n    // TODO(sjmiles): preserves user defined overrides, if any\n    if (prototype.setAttribute._polyfilled) {\n      return;\n    }\n    var setAttribute = prototype.setAttribute;\n    prototype.setAttribute = function(name, value) {\n      changeAttribute.call(this, name, value, setAttribute);\n    }\n    var removeAttribute = prototype.removeAttribute;\n    prototype.removeAttribute = function(name) {\n      changeAttribute.call(this, name, null, removeAttribute);\n    }\n    prototype.setAttribute._polyfilled = true;\n  }\n\n  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/\n  // index.html#dfn-attribute-changed-callback\n  function changeAttribute(name, value, operation) {\n    var oldValue = this.getAttribute(name);\n    operation.apply(this, arguments);\n    var newValue = this.getAttribute(name);\n    if (this.attributeChangedCallback\n        && (newValue !== oldValue)) {\n      this.attributeChangedCallback(name, oldValue, newValue);\n    }\n  }\n\n  // element registry (maps tag names to definitions)\n\n  var registry = {};\n\n  function getRegisteredDefinition(name) {\n    if (name) {\n      return registry[name.toLowerCase()];\n    }\n  }\n\n  function registerDefinition(name, definition) {\n    registry[name] = definition;\n  }\n\n  function generateConstructor(definition) {\n    return function() {\n      return instantiate(definition);\n    };\n  }\n\n  var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n  function createElementNS(namespace, tag, typeExtension) {\n    // NOTE: we do not support non-HTML elements,\n    // just call createElementNS for non HTML Elements\n    if (namespace === HTML_NAMESPACE) {\n      return createElement(tag, typeExtension);\n    } else {\n      return domCreateElementNS(namespace, tag);\n    }\n  }\n\n  function createElement(tag, typeExtension) {\n    // TODO(sjmiles): ignore 'tag' when using 'typeExtension', we could\n    // error check it, or perhaps there should only ever be one argument\n    var definition = getRegisteredDefinition(typeExtension || tag);\n    if (definition) {\n      if (tag == definition.tag && typeExtension == definition.is) {\n        return new definition.ctor();\n      }\n      // Handle empty string for type extension.\n      if (!typeExtension && !definition.is) {\n        return new definition.ctor();\n      }\n    }\n\n    if (typeExtension) {\n      var element = createElement(tag);\n      element.setAttribute('is', typeExtension);\n      return element;\n    }\n    var element = domCreateElement(tag);\n    // Custom tags should be HTMLElements even if not upgraded.\n    if (tag.indexOf('-') >= 0) {\n      implement(element, HTMLElement);\n    }\n    return element;\n  }\n\n  function upgradeElement(element) {\n    if (!element.__upgraded__ && (element.nodeType === Node.ELEMENT_NODE)) {\n      var is = element.getAttribute('is');\n      var definition = getRegisteredDefinition(is || element.localName);\n      if (definition) {\n        if (is && definition.tag == element.localName) {\n          return upgrade(element, definition);\n        } else if (!is && !definition.extends) {\n          return upgrade(element, definition);\n        }\n      }\n    }\n  }\n\n  function cloneNode(deep) {\n    // call original clone\n    var n = domCloneNode.call(this, deep);\n    // upgrade the element and subtree\n    scope.upgradeAll(n);\n    // return the clone\n    return n;\n  }\n  // capture native createElement before we override it\n\n  var domCreateElement = document.createElement.bind(document);\n  var domCreateElementNS = document.createElementNS.bind(document);\n\n  // capture native cloneNode before we override it\n\n  var domCloneNode = Node.prototype.cloneNode;\n\n  // exports\n\n  document.registerElement = register;\n  document.createElement = createElement; // override\n  document.createElementNS = createElementNS; // override\n  Node.prototype.cloneNode = cloneNode; // override\n\n  scope.registry = registry;\n\n  /**\n   * Upgrade an element to a custom element. Upgrading an element\n   * causes the custom prototype to be applied, an `is` attribute\n   * to be attached (as needed), and invocation of the `readyCallback`.\n   * `upgrade` does nothing if the element is already upgraded, or\n   * if it matches no registered custom tag name.\n   *\n   * @method ugprade\n   * @param {Element} element The element to upgrade.\n   * @return {Element} The upgraded element.\n   */\n  scope.upgrade = upgradeElement;\n}\n\n// Create a custom 'instanceof'. This is necessary when CustomElements\n// are implemented via a mixin strategy, as for example on IE10.\nvar isInstance;\nif (!Object.__proto__ && !useNative) {\n  isInstance = function(obj, ctor) {\n    var p = obj;\n    while (p) {\n      // NOTE: this is not technically correct since we're not checking if\n      // an object is an instance of a constructor; however, this should\n      // be good enough for the mixin strategy.\n      if (p === ctor.prototype) {\n        return true;\n      }\n      p = p.__proto__;\n    }\n    return false;\n  }\n} else {\n  isInstance = function(obj, base) {\n    return obj instanceof base;\n  }\n}\n\n// exports\nscope.instanceof = isInstance;\n\n// bc\ndocument.register = document.registerElement;\n\nscope.hasNative = hasNative;\nscope.useNative = useNative;\n\n})(window.CustomElements);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n// import\n\nvar IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\n\n// highlander object for parsing a document tree\n\nvar parser = {\n  selectors: [\n    'link[rel=' + IMPORT_LINK_TYPE + ']'\n  ],\n  map: {\n    link: 'parseLink'\n  },\n  parse: function(inDocument) {\n    if (!inDocument.__parsed) {\n      // only parse once\n      inDocument.__parsed = true;\n      // all parsable elements in inDocument (depth-first pre-order traversal)\n      var elts = inDocument.querySelectorAll(parser.selectors);\n      // for each parsable node type, call the mapped parsing method\n      forEach(elts, function(e) {\n        parser[parser.map[e.localName]](e);\n      });\n      // upgrade all upgradeable static elements, anything dynamically\n      // created should be caught by observer\n      CustomElements.upgradeDocument(inDocument);\n      // observe document for dom changes\n      CustomElements.observeDocument(inDocument);\n    }\n  },\n  parseLink: function(linkElt) {\n    // imports\n    if (isDocumentLink(linkElt)) {\n      this.parseImport(linkElt);\n    }\n  },\n  parseImport: function(linkElt) {\n    if (linkElt.import) {\n      parser.parse(linkElt.import);\n    }\n  }\n};\n\nfunction isDocumentLink(inElt) {\n  return (inElt.localName === 'link'\n      && inElt.getAttribute('rel') === IMPORT_LINK_TYPE);\n}\n\nvar forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n\n// exports\n\nscope.parser = parser;\nscope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\n\n})(window.CustomElements);","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope){\n\n// bootstrap parsing\nfunction bootstrap() {\n  // parse document\n  CustomElements.parser.parse(document);\n  // one more pass before register is 'live'\n  CustomElements.upgradeDocument(document);\n  // choose async\n  var async = window.Platform && Platform.endOfMicrotask ? \n    Platform.endOfMicrotask :\n    setTimeout;\n  async(function() {\n    // set internal 'ready' flag, now document.registerElement will trigger \n    // synchronous upgrades\n    CustomElements.ready = true;\n    // capture blunt profiling data\n    CustomElements.readyTime = Date.now();\n    if (window.HTMLImports) {\n      CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;\n    }\n    // notify the system that we are bootstrapped\n    document.dispatchEvent(\n      new CustomEvent('WebComponentsReady', {bubbles: true})\n    );\n\n    // install upgrade hook if HTMLImports are available\n    if (window.HTMLImports) {\n      HTMLImports.__importsParsingHook = function(elt) {\n        CustomElements.parser.parse(elt.import);\n      }\n    }\n  });\n}\n\n// CustomEvent shim for IE\nif (typeof window.CustomEvent !== 'function') {\n  window.CustomEvent = function(inType) {\n    var e = document.createEvent('HTMLEvents');\n    e.initEvent(inType, true, true);\n    return e;\n  };\n}\n\n// When loading at readyState complete time (or via flag), boot custom elements\n// immediately.\n// If relevant, HTMLImports must already be loaded.\nif (document.readyState === 'complete' || scope.flags.eager) {\n  bootstrap();\n// When loading at readyState interactive time, bootstrap only if HTMLImports\n// are not pending. Also avoid IE as the semantics of this state are unreliable.\n} else if (document.readyState === 'interactive' && !window.attachEvent &&\n    (!window.HTMLImports || window.HTMLImports.ready)) {\n  bootstrap();\n// When loading at other readyStates, wait for the appropriate DOM event to \n// bootstrap.\n} else {\n  var loadEvent = window.HTMLImports && !HTMLImports.ready ?\n      'HTMLImportsLoaded' : 'DOMContentLoaded';\n  window.addEventListener(loadEvent, bootstrap);\n}\n\n})(window.CustomElements);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function() {\n\nif (window.ShadowDOMPolyfill) {\n\n  // ensure wrapped inputs for these functions\n  var fns = ['upgradeAll', 'upgradeSubtree', 'observeDocument',\n      'upgradeDocument'];\n\n  // cache originals\n  var original = {};\n  fns.forEach(function(fn) {\n    original[fn] = CustomElements[fn];\n  });\n\n  // override\n  fns.forEach(function(fn) {\n    CustomElements[fn] = function(inNode) {\n      return original[fn](wrap(inNode));\n    };\n  });\n\n}\n\n})();\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n  var endOfMicrotask = scope.endOfMicrotask;\n\n  // Generic url loader\n  function Loader(regex) {\n    this.regex = regex;\n  }\n  Loader.prototype = {\n    // TODO(dfreedm): there may be a better factoring here\n    // extract absolute urls from the text (full of relative urls)\n    extractUrls: function(text, base) {\n      var matches = [];\n      var matched, u;\n      while ((matched = this.regex.exec(text))) {\n        u = new URL(matched[1], base);\n        matches.push({matched: matched[0], url: u.href});\n      }\n      return matches;\n    },\n    // take a text blob, a root url, and a callback and load all the urls found within the text\n    // returns a map of absolute url to text\n    process: function(text, root, callback) {\n      var matches = this.extractUrls(text, root);\n      this.fetch(matches, {}, callback);\n    },\n    // build a mapping of url -> text from matches\n    fetch: function(matches, map, callback) {\n      var inflight = matches.length;\n\n      // return early if there is no fetching to be done\n      if (!inflight) {\n        return callback(map);\n      }\n\n      var done = function() {\n        if (--inflight === 0) {\n          callback(map);\n        }\n      };\n\n      // map url -> responseText\n      var handleXhr = function(err, request) {\n        var match = request.match;\n        var key = match.url;\n        // handle errors with an empty string\n        if (err) {\n          map[key] = '';\n          return done();\n        }\n        var response = request.response || request.responseText;\n        map[key] = response;\n        this.fetch(this.extractUrls(response, key), map, done);\n      };\n\n      var m, req, url;\n      for (var i = 0; i < inflight; i++) {\n        m = matches[i];\n        url = m.url;\n        // if this url has already been requested, skip requesting it again\n        if (map[url]) {\n          // Async call to done to simplify the inflight logic\n          endOfMicrotask(done);\n          continue;\n        }\n        req = this.xhr(url, handleXhr, this);\n        req.match = m;\n        // tag the map with an XHR request to deduplicate at the same level\n        map[url] = req;\n      }\n    },\n    xhr: function(url, callback, scope) {\n      var request = new XMLHttpRequest();\n      request.open('GET', url, true);\n      request.send();\n      request.onload = function() {\n        callback.call(scope, null, request);\n      };\n      request.onerror = function() {\n        callback.call(scope, null, request);\n      };\n      return request;\n    }\n  };\n\n  scope.Loader = Loader;\n})(window.Platform);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\nvar urlResolver = scope.urlResolver;\nvar Loader = scope.Loader;\n\nfunction StyleResolver() {\n  this.loader = new Loader(this.regex);\n}\nStyleResolver.prototype = {\n  regex: /@import\\s+(?:url)?[\"'\\(]*([^'\"\\)]*)['\"\\)]*;/g,\n  // Recursively replace @imports with the text at that url\n  resolve: function(text, url, callback) {\n    var done = function(map) {\n      callback(this.flatten(text, url, map));\n    }.bind(this);\n    this.loader.process(text, url, done);\n  },\n  // resolve the textContent of a style node\n  resolveNode: function(style, callback) {\n    var text = style.textContent;\n    var url = style.ownerDocument.baseURI;\n    var done = function(text) {\n      style.textContent = text;\n      callback(style);\n    };\n    this.resolve(text, url, done);\n  },\n  // flatten all the @imports to text\n  flatten: function(text, base, map) {\n    var matches = this.loader.extractUrls(text, base);\n    var match, url, intermediate;\n    for (var i = 0; i < matches.length; i++) {\n      match = matches[i];\n      url = match.url;\n      // resolve any css text to be relative to the importer\n      intermediate = urlResolver.resolveCssText(map[url], url);\n      // flatten intermediate @imports\n      intermediate = this.flatten(intermediate, url, map);\n      text = text.replace(match.matched, intermediate);\n    }\n    return text;\n  },\n  loadStyles: function(styles, callback) {\n    var loaded=0, l = styles.length;\n    // called in the context of the style\n    function loadedStyle(style) {\n      loaded++;\n      if (loaded === l && callback) {\n        callback();\n      }\n    }\n    for (var i=0, s; (i<l) && (s=styles[i]); i++) {\n      this.resolveNode(s, loadedStyle);\n    }\n  }\n};\n\nvar styleResolver = new StyleResolver();\n\n// exports\nscope.styleResolver = styleResolver;\n\n})(window.Platform);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  scope = scope || {};\n  scope.external = scope.external || {};\n  var target = {\n    shadow: function(inEl) {\n      if (inEl) {\n        return inEl.shadowRoot || inEl.webkitShadowRoot;\n      }\n    },\n    canTarget: function(shadow) {\n      return shadow && Boolean(shadow.elementFromPoint);\n    },\n    targetingShadow: function(inEl) {\n      var s = this.shadow(inEl);\n      if (this.canTarget(s)) {\n        return s;\n      }\n    },\n    olderShadow: function(shadow) {\n      var os = shadow.olderShadowRoot;\n      if (!os) {\n        var se = shadow.querySelector('shadow');\n        if (se) {\n          os = se.olderShadowRoot;\n        }\n      }\n      return os;\n    },\n    allShadows: function(element) {\n      var shadows = [], s = this.shadow(element);\n      while(s) {\n        shadows.push(s);\n        s = this.olderShadow(s);\n      }\n      return shadows;\n    },\n    searchRoot: function(inRoot, x, y) {\n      if (inRoot) {\n        var t = inRoot.elementFromPoint(x, y);\n        var st, sr, os;\n        // is element a shadow host?\n        sr = this.targetingShadow(t);\n        while (sr) {\n          // find the the element inside the shadow root\n          st = sr.elementFromPoint(x, y);\n          if (!st) {\n            // check for older shadows\n            sr = this.olderShadow(sr);\n          } else {\n            // shadowed element may contain a shadow root\n            var ssr = this.targetingShadow(st);\n            return this.searchRoot(ssr, x, y) || st;\n          }\n        }\n        // light dom element is the target\n        return t;\n      }\n    },\n    owner: function(element) {\n      var s = element;\n      // walk up until you hit the shadow root or document\n      while (s.parentNode) {\n        s = s.parentNode;\n      }\n      // the owner element is expected to be a Document or ShadowRoot\n      if (s.nodeType != Node.DOCUMENT_NODE && s.nodeType != Node.DOCUMENT_FRAGMENT_NODE) {\n        s = document;\n      }\n      return s;\n    },\n    findTarget: function(inEvent) {\n      var x = inEvent.clientX, y = inEvent.clientY;\n      // if the listener is in the shadow root, it is much faster to start there\n      var s = this.owner(inEvent.target);\n      // if x, y is not in this root, fall back to document search\n      if (!s.elementFromPoint(x, y)) {\n        s = document;\n      }\n      return this.searchRoot(s, x, y);\n    }\n  };\n  scope.targetFinding = target;\n  scope.findTarget = target.findTarget.bind(target);\n\n  window.PointerEventsPolyfill = scope;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function() {\n  function shadowSelector(v) {\n    return 'body ^^ ' + selector(v);\n  }\n  function selector(v) {\n    return '[touch-action=\"' + v + '\"]';\n  }\n  function rule(v) {\n    return '{ -ms-touch-action: ' + v + '; touch-action: ' + v + '; touch-action-delay: none; }';\n  }\n  var attrib2css = [\n    'none',\n    'auto',\n    'pan-x',\n    'pan-y',\n    {\n      rule: 'pan-x pan-y',\n      selectors: [\n        'pan-x pan-y',\n        'pan-y pan-x'\n      ]\n    }\n  ];\n  var styles = '';\n  attrib2css.forEach(function(r) {\n    if (String(r) === r) {\n      styles += selector(r) + rule(r) + '\\n';\n      styles += shadowSelector(r) + rule(r) + '\\n';\n    } else {\n      styles += r.selectors.map(selector) + rule(r.rule) + '\\n';\n      styles += r.selectors.map(shadowSelector) + rule(r.rule) + '\\n';\n    }\n  });\n  var el = document.createElement('style');\n  el.textContent = styles;\n  document.head.appendChild(el);\n})();\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This is the constructor for new PointerEvents.\n *\n * New Pointer Events must be given a type, and an optional dictionary of\n * initialization properties.\n *\n * Due to certain platform requirements, events returned from the constructor\n * identify as MouseEvents.\n *\n * @constructor\n * @param {String} inType The type of the event to create.\n * @param {Object} [inDict] An optional dictionary of initial event properties.\n * @return {Event} A new PointerEvent of type `inType` and initialized with properties from `inDict`.\n */\n(function(scope) {\n  // test for DOM Level 4 Events\n  var NEW_MOUSE_EVENT = false;\n  var HAS_BUTTONS = false;\n  try {\n    var ev = new MouseEvent('click', {buttons: 1});\n    NEW_MOUSE_EVENT = true;\n    HAS_BUTTONS = ev.buttons === 1;\n    ev = null;\n  } catch(e) {\n  }\n\n  var MOUSE_PROPS = [\n    'bubbles',\n    'cancelable',\n    'view',\n    'detail',\n    'screenX',\n    'screenY',\n    'clientX',\n    'clientY',\n    'ctrlKey',\n    'altKey',\n    'shiftKey',\n    'metaKey',\n    'button',\n    'relatedTarget',\n  ];\n\n  var MOUSE_DEFAULTS = [\n    false,\n    false,\n    null,\n    null,\n    0,\n    0,\n    0,\n    0,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null\n  ];\n\n  function PointerEvent(inType, inDict) {\n    inDict = inDict || {};\n    // According to the w3c spec,\n    // http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-button\n    // MouseEvent.button == 0 can mean either no mouse button depressed, or the\n    // left mouse button depressed.\n    //\n    // As of now, the only way to distinguish between the two states of\n    // MouseEvent.button is by using the deprecated MouseEvent.which property, as\n    // this maps mouse buttons to positive integers > 0, and uses 0 to mean that\n    // no mouse button is held.\n    //\n    // MouseEvent.which is derived from MouseEvent.button at MouseEvent creation,\n    // but initMouseEvent does not expose an argument with which to set\n    // MouseEvent.which. Calling initMouseEvent with a buttonArg of 0 will set\n    // MouseEvent.button == 0 and MouseEvent.which == 1, breaking the expectations\n    // of app developers.\n    //\n    // The only way to propagate the correct state of MouseEvent.which and\n    // MouseEvent.button to a new MouseEvent.button == 0 and MouseEvent.which == 0\n    // is to call initMouseEvent with a buttonArg value of -1.\n    //\n    // This is fixed with DOM Level 4's use of buttons\n    var buttons = inDict.buttons;\n    // touch has two possible buttons state: 0 and 1, rely on being told the right one\n    if (!HAS_BUTTONS && !buttons && inType !== 'touch') {\n      switch (inDict.which) {\n        case 1: buttons = 1; break;\n        case 2: buttons = 4; break;\n        case 3: buttons = 2; break;\n        default: buttons = 0;\n      }\n    }\n\n    var e;\n    if (NEW_MOUSE_EVENT) {\n      e = new MouseEvent(inType, inDict);\n    } else {\n      e = document.createEvent('MouseEvent');\n\n      // import values from the given dictionary\n      var props = {}, p;\n      for(var i = 0; i < MOUSE_PROPS.length; i++) {\n        p = MOUSE_PROPS[i];\n        props[p] = inDict[p] || MOUSE_DEFAULTS[i];\n      }\n\n      // define the properties inherited from MouseEvent\n      e.initMouseEvent(\n        inType, props.bubbles, props.cancelable, props.view, props.detail,\n        props.screenX, props.screenY, props.clientX, props.clientY, props.ctrlKey,\n        props.altKey, props.shiftKey, props.metaKey, props.button, props.relatedTarget\n      );\n    }\n\n    // make the event pass instanceof checks\n    e.__proto__ = PointerEvent.prototype;\n\n    // define the buttons property according to DOM Level 3 spec\n    if (!HAS_BUTTONS) {\n      // IE 10 has buttons on MouseEvent.prototype as a getter w/o any setting\n      // mechanism\n      Object.defineProperty(e, 'buttons', {get: function(){ return buttons; }, enumerable: true});\n    }\n\n    // Spec requires that pointers without pressure specified use 0.5 for down\n    // state and 0 for up state.\n    var pressure = 0;\n    if (inDict.pressure) {\n      pressure = inDict.pressure;\n    } else {\n      pressure = buttons ? 0.5 : 0;\n    }\n\n    // define the properties of the PointerEvent interface\n    Object.defineProperties(e, {\n      pointerId: { value: inDict.pointerId || 0, enumerable: true },\n      width: { value: inDict.width || 0, enumerable: true },\n      height: { value: inDict.height || 0, enumerable: true },\n      pressure: { value: pressure, enumerable: true },\n      tiltX: { value: inDict.tiltX || 0, enumerable: true },\n      tiltY: { value: inDict.tiltY || 0, enumerable: true },\n      pointerType: { value: inDict.pointerType || '', enumerable: true },\n      hwTimestamp: { value: inDict.hwTimestamp || 0, enumerable: true },\n      isPrimary: { value: inDict.isPrimary || false, enumerable: true }\n    });\n    return e;\n  }\n\n  // PointerEvent extends MouseEvent\n  PointerEvent.prototype = Object.create(MouseEvent.prototype);\n\n  // attach to window\n  if (!scope.PointerEvent) {\n    scope.PointerEvent = PointerEvent;\n  }\n})(window);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This module implements an map of pointer states\n */\n(function(scope) {\n  var USE_MAP = window.Map && window.Map.prototype.forEach;\n  var POINTERS_FN = function(){ return this.size; };\n  function PointerMap() {\n    if (USE_MAP) {\n      var m = new Map();\n      m.pointers = POINTERS_FN;\n      return m;\n    } else {\n      this.keys = [];\n      this.values = [];\n    }\n  }\n\n  PointerMap.prototype = {\n    set: function(inId, inEvent) {\n      var i = this.keys.indexOf(inId);\n      if (i > -1) {\n        this.values[i] = inEvent;\n      } else {\n        this.keys.push(inId);\n        this.values.push(inEvent);\n      }\n    },\n    has: function(inId) {\n      return this.keys.indexOf(inId) > -1;\n    },\n    'delete': function(inId) {\n      var i = this.keys.indexOf(inId);\n      if (i > -1) {\n        this.keys.splice(i, 1);\n        this.values.splice(i, 1);\n      }\n    },\n    get: function(inId) {\n      var i = this.keys.indexOf(inId);\n      return this.values[i];\n    },\n    clear: function() {\n      this.keys.length = 0;\n      this.values.length = 0;\n    },\n    // return value, key, map\n    forEach: function(callback, thisArg) {\n      this.values.forEach(function(v, i) {\n        callback.call(thisArg, v, this.keys[i], this);\n      }, this);\n    },\n    pointers: function() {\n      return this.keys.length;\n    }\n  };\n\n  scope.PointerMap = PointerMap;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var CLONE_PROPS = [\n    // MouseEvent\n    'bubbles',\n    'cancelable',\n    'view',\n    'detail',\n    'screenX',\n    'screenY',\n    'clientX',\n    'clientY',\n    'ctrlKey',\n    'altKey',\n    'shiftKey',\n    'metaKey',\n    'button',\n    'relatedTarget',\n    // DOM Level 3\n    'buttons',\n    // PointerEvent\n    'pointerId',\n    'width',\n    'height',\n    'pressure',\n    'tiltX',\n    'tiltY',\n    'pointerType',\n    'hwTimestamp',\n    'isPrimary',\n    // event instance\n    'type',\n    'target',\n    'currentTarget',\n    'which'\n  ];\n\n  var CLONE_DEFAULTS = [\n    // MouseEvent\n    false,\n    false,\n    null,\n    null,\n    0,\n    0,\n    0,\n    0,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null,\n    // DOM Level 3\n    0,\n    // PointerEvent\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    '',\n    0,\n    false,\n    // event instance\n    '',\n    null,\n    null,\n    0\n  ];\n\n  var HAS_SVG_INSTANCE = (typeof SVGElementInstance !== 'undefined');\n\n  /**\n   * This module is for normalizing events. Mouse and Touch events will be\n   * collected here, and fire PointerEvents that have the same semantics, no\n   * matter the source.\n   * Events fired:\n   *   - pointerdown: a pointing is added\n   *   - pointerup: a pointer is removed\n   *   - pointermove: a pointer is moved\n   *   - pointerover: a pointer crosses into an element\n   *   - pointerout: a pointer leaves an element\n   *   - pointercancel: a pointer will no longer generate events\n   */\n  var dispatcher = {\n    targets: new WeakMap(),\n    handledEvents: new WeakMap(),\n    pointermap: new scope.PointerMap(),\n    eventMap: {},\n    // Scope objects for native events.\n    // This exists for ease of testing.\n    eventSources: {},\n    eventSourceList: [],\n    /**\n     * Add a new event source that will generate pointer events.\n     *\n     * `inSource` must contain an array of event names named `events`, and\n     * functions with the names specified in the `events` array.\n     * @param {string} name A name for the event source\n     * @param {Object} source A new source of platform events.\n     */\n    registerSource: function(name, source) {\n      var s = source;\n      var newEvents = s.events;\n      if (newEvents) {\n        newEvents.forEach(function(e) {\n          if (s[e]) {\n            this.eventMap[e] = s[e].bind(s);\n          }\n        }, this);\n        this.eventSources[name] = s;\n        this.eventSourceList.push(s);\n      }\n    },\n    register: function(element) {\n      var l = this.eventSourceList.length;\n      for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) {\n        // call eventsource register\n        es.register.call(es, element);\n      }\n    },\n    unregister: function(element) {\n      var l = this.eventSourceList.length;\n      for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) {\n        // call eventsource register\n        es.unregister.call(es, element);\n      }\n    },\n    contains: scope.external.contains || function(container, contained) {\n      return container.contains(contained);\n    },\n    // EVENTS\n    down: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointerdown', inEvent);\n    },\n    move: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointermove', inEvent);\n    },\n    up: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointerup', inEvent);\n    },\n    enter: function(inEvent) {\n      inEvent.bubbles = false;\n      this.fireEvent('pointerenter', inEvent);\n    },\n    leave: function(inEvent) {\n      inEvent.bubbles = false;\n      this.fireEvent('pointerleave', inEvent);\n    },\n    over: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointerover', inEvent);\n    },\n    out: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointerout', inEvent);\n    },\n    cancel: function(inEvent) {\n      inEvent.bubbles = true;\n      this.fireEvent('pointercancel', inEvent);\n    },\n    leaveOut: function(event) {\n      this.out(event);\n      if (!this.contains(event.target, event.relatedTarget)) {\n        this.leave(event);\n      }\n    },\n    enterOver: function(event) {\n      this.over(event);\n      if (!this.contains(event.target, event.relatedTarget)) {\n        this.enter(event);\n      }\n    },\n    // LISTENER LOGIC\n    eventHandler: function(inEvent) {\n      // This is used to prevent multiple dispatch of pointerevents from\n      // platform events. This can happen when two elements in different scopes\n      // are set up to create pointer events, which is relevant to Shadow DOM.\n      if (this.handledEvents.get(inEvent)) {\n        return;\n      }\n      var type = inEvent.type;\n      var fn = this.eventMap && this.eventMap[type];\n      if (fn) {\n        fn(inEvent);\n      }\n      this.handledEvents.set(inEvent, true);\n    },\n    // set up event listeners\n    listen: function(target, events) {\n      events.forEach(function(e) {\n        this.addEvent(target, e);\n      }, this);\n    },\n    // remove event listeners\n    unlisten: function(target, events) {\n      events.forEach(function(e) {\n        this.removeEvent(target, e);\n      }, this);\n    },\n    addEvent: scope.external.addEvent || function(target, eventName) {\n      target.addEventListener(eventName, this.boundHandler);\n    },\n    removeEvent: scope.external.removeEvent || function(target, eventName) {\n      target.removeEventListener(eventName, this.boundHandler);\n    },\n    // EVENT CREATION AND TRACKING\n    /**\n     * Creates a new Event of type `inType`, based on the information in\n     * `inEvent`.\n     *\n     * @param {string} inType A string representing the type of event to create\n     * @param {Event} inEvent A platform event with a target\n     * @return {Event} A PointerEvent of type `inType`\n     */\n    makeEvent: function(inType, inEvent) {\n      // relatedTarget must be null if pointer is captured\n      if (this.captureInfo) {\n        inEvent.relatedTarget = null;\n      }\n      var e = new PointerEvent(inType, inEvent);\n      if (inEvent.preventDefault) {\n        e.preventDefault = inEvent.preventDefault;\n      }\n      this.targets.set(e, this.targets.get(inEvent) || inEvent.target);\n      return e;\n    },\n    // make and dispatch an event in one call\n    fireEvent: function(inType, inEvent) {\n      var e = this.makeEvent(inType, inEvent);\n      return this.dispatchEvent(e);\n    },\n    /**\n     * Returns a snapshot of inEvent, with writable properties.\n     *\n     * @param {Event} inEvent An event that contains properties to copy.\n     * @return {Object} An object containing shallow copies of `inEvent`'s\n     *    properties.\n     */\n    cloneEvent: function(inEvent) {\n      var eventCopy = {}, p;\n      for (var i = 0; i < CLONE_PROPS.length; i++) {\n        p = CLONE_PROPS[i];\n        eventCopy[p] = inEvent[p] || CLONE_DEFAULTS[i];\n        // Work around SVGInstanceElement shadow tree\n        // Return the <use> element that is represented by the instance for Safari, Chrome, IE.\n        // This is the behavior implemented by Firefox.\n        if (HAS_SVG_INSTANCE && (p === 'target' || p === 'relatedTarget')) {\n          if (eventCopy[p] instanceof SVGElementInstance) {\n            eventCopy[p] = eventCopy[p].correspondingUseElement;\n          }\n        }\n      }\n      // keep the semantics of preventDefault\n      if (inEvent.preventDefault) {\n        eventCopy.preventDefault = function() {\n          inEvent.preventDefault();\n        };\n      }\n      return eventCopy;\n    },\n    getTarget: function(inEvent) {\n      // if pointer capture is set, route all events for the specified pointerId\n      // to the capture target\n      if (this.captureInfo) {\n        if (this.captureInfo.id === inEvent.pointerId) {\n          return this.captureInfo.target;\n        }\n      }\n      return this.targets.get(inEvent);\n    },\n    setCapture: function(inPointerId, inTarget) {\n      if (this.captureInfo) {\n        this.releaseCapture(this.captureInfo.id);\n      }\n      this.captureInfo = {id: inPointerId, target: inTarget};\n      var e = new PointerEvent('gotpointercapture', { bubbles: true });\n      this.implicitRelease = this.releaseCapture.bind(this, inPointerId);\n      document.addEventListener('pointerup', this.implicitRelease);\n      document.addEventListener('pointercancel', this.implicitRelease);\n      this.targets.set(e, inTarget);\n      this.asyncDispatchEvent(e);\n    },\n    releaseCapture: function(inPointerId) {\n      if (this.captureInfo && this.captureInfo.id === inPointerId) {\n        var e = new PointerEvent('lostpointercapture', { bubbles: true });\n        var t = this.captureInfo.target;\n        this.captureInfo = null;\n        document.removeEventListener('pointerup', this.implicitRelease);\n        document.removeEventListener('pointercancel', this.implicitRelease);\n        this.targets.set(e, t);\n        this.asyncDispatchEvent(e);\n      }\n    },\n    /**\n     * Dispatches the event to its target.\n     *\n     * @param {Event} inEvent The event to be dispatched.\n     * @return {Boolean} True if an event handler returns true, false otherwise.\n     */\n    dispatchEvent: scope.external.dispatchEvent || function(inEvent) {\n      var t = this.getTarget(inEvent);\n      if (t) {\n        return t.dispatchEvent(inEvent);\n      }\n    },\n    asyncDispatchEvent: function(inEvent) {\n      setTimeout(this.dispatchEvent.bind(this, inEvent), 0);\n    }\n  };\n  dispatcher.boundHandler = dispatcher.eventHandler.bind(dispatcher);\n  scope.dispatcher = dispatcher;\n  scope.register = dispatcher.register.bind(dispatcher);\n  scope.unregister = dispatcher.unregister.bind(dispatcher);\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This module uses Mutation Observers to dynamically adjust which nodes will\n * generate Pointer Events.\n *\n * All nodes that wish to generate Pointer Events must have the attribute\n * `touch-action` set to `none`.\n */\n(function(scope) {\n  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n  var map = Array.prototype.map.call.bind(Array.prototype.map);\n  var toArray = Array.prototype.slice.call.bind(Array.prototype.slice);\n  var filter = Array.prototype.filter.call.bind(Array.prototype.filter);\n  var MO = window.MutationObserver || window.WebKitMutationObserver;\n  var SELECTOR = '[touch-action]';\n  var OBSERVER_INIT = {\n    subtree: true,\n    childList: true,\n    attributes: true,\n    attributeOldValue: true,\n    attributeFilter: ['touch-action']\n  };\n\n  function Installer(add, remove, changed, binder) {\n    this.addCallback = add.bind(binder);\n    this.removeCallback = remove.bind(binder);\n    this.changedCallback = changed.bind(binder);\n    if (MO) {\n      this.observer = new MO(this.mutationWatcher.bind(this));\n    }\n  }\n\n  Installer.prototype = {\n    watchSubtree: function(target) {\n      // Only watch scopes that can target find, as these are top-level.\n      // Otherwise we can see duplicate additions and removals that add noise.\n      //\n      // TODO(dfreedman): For some instances with ShadowDOMPolyfill, we can see\n      // a removal without an insertion when a node is redistributed among\n      // shadows. Since it all ends up correct in the document, watching only\n      // the document will yield the correct mutations to watch.\n      if (scope.targetFinding.canTarget(target)) {\n        this.observer.observe(target, OBSERVER_INIT);\n      }\n    },\n    enableOnSubtree: function(target) {\n      this.watchSubtree(target);\n      if (target === document && document.readyState !== 'complete') {\n        this.installOnLoad();\n      } else {\n        this.installNewSubtree(target);\n      }\n    },\n    installNewSubtree: function(target) {\n      forEach(this.findElements(target), this.addElement, this);\n    },\n    findElements: function(target) {\n      if (target.querySelectorAll) {\n        return target.querySelectorAll(SELECTOR);\n      }\n      return [];\n    },\n    removeElement: function(el) {\n      this.removeCallback(el);\n    },\n    addElement: function(el) {\n      this.addCallback(el);\n    },\n    elementChanged: function(el, oldValue) {\n      this.changedCallback(el, oldValue);\n    },\n    concatLists: function(accum, list) {\n      return accum.concat(toArray(list));\n    },\n    // register all touch-action = none nodes on document load\n    installOnLoad: function() {\n      document.addEventListener('readystatechange', function() {\n        if (document.readyState === 'complete') {\n          this.installNewSubtree(document);\n        }\n      }.bind(this));\n    },\n    isElement: function(n) {\n      return n.nodeType === Node.ELEMENT_NODE;\n    },\n    flattenMutationTree: function(inNodes) {\n      // find children with touch-action\n      var tree = map(inNodes, this.findElements, this);\n      // make sure the added nodes are accounted for\n      tree.push(filter(inNodes, this.isElement));\n      // flatten the list\n      return tree.reduce(this.concatLists, []);\n    },\n    mutationWatcher: function(mutations) {\n      mutations.forEach(this.mutationHandler, this);\n    },\n    mutationHandler: function(m) {\n      if (m.type === 'childList') {\n        var added = this.flattenMutationTree(m.addedNodes);\n        added.forEach(this.addElement, this);\n        var removed = this.flattenMutationTree(m.removedNodes);\n        removed.forEach(this.removeElement, this);\n      } else if (m.type === 'attributes') {\n        this.elementChanged(m.target, m.oldValue);\n      }\n    }\n  };\n\n  if (!MO) {\n    Installer.prototype.watchSubtree = function(){\n      console.warn('PointerEventsPolyfill: MutationObservers not found, touch-action will not be dynamically detected');\n    };\n  }\n\n  scope.Installer = Installer;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function (scope) {\n  var dispatcher = scope.dispatcher;\n  var pointermap = dispatcher.pointermap;\n  // radius around touchend that swallows mouse events\n  var DEDUP_DIST = 25;\n\n  // handler block for native mouse events\n  var mouseEvents = {\n    POINTER_ID: 1,\n    POINTER_TYPE: 'mouse',\n    events: [\n      'mousedown',\n      'mousemove',\n      'mouseup',\n      'mouseover',\n      'mouseout'\n    ],\n    register: function(target) {\n      dispatcher.listen(target, this.events);\n    },\n    unregister: function(target) {\n      dispatcher.unlisten(target, this.events);\n    },\n    lastTouches: [],\n    // collide with the global mouse listener\n    isEventSimulatedFromTouch: function(inEvent) {\n      var lts = this.lastTouches;\n      var x = inEvent.clientX, y = inEvent.clientY;\n      for (var i = 0, l = lts.length, t; i < l && (t = lts[i]); i++) {\n        // simulated mouse events will be swallowed near a primary touchend\n        var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);\n        if (dx <= DEDUP_DIST && dy <= DEDUP_DIST) {\n          return true;\n        }\n      }\n    },\n    prepareEvent: function(inEvent) {\n      var e = dispatcher.cloneEvent(inEvent);\n      // forward mouse preventDefault\n      var pd = e.preventDefault;\n      e.preventDefault = function() {\n        inEvent.preventDefault();\n        pd();\n      };\n      e.pointerId = this.POINTER_ID;\n      e.isPrimary = true;\n      e.pointerType = this.POINTER_TYPE;\n      return e;\n    },\n    mousedown: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var p = pointermap.has(this.POINTER_ID);\n        // TODO(dfreedman) workaround for some elements not sending mouseup\n        // http://crbug/149091\n        if (p) {\n          this.cancel(inEvent);\n        }\n        var e = this.prepareEvent(inEvent);\n        pointermap.set(this.POINTER_ID, inEvent);\n        dispatcher.down(e);\n      }\n    },\n    mousemove: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var e = this.prepareEvent(inEvent);\n        dispatcher.move(e);\n      }\n    },\n    mouseup: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var p = pointermap.get(this.POINTER_ID);\n        if (p && p.button === inEvent.button) {\n          var e = this.prepareEvent(inEvent);\n          dispatcher.up(e);\n          this.cleanupMouse();\n        }\n      }\n    },\n    mouseover: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var e = this.prepareEvent(inEvent);\n        dispatcher.enterOver(e);\n      }\n    },\n    mouseout: function(inEvent) {\n      if (!this.isEventSimulatedFromTouch(inEvent)) {\n        var e = this.prepareEvent(inEvent);\n        dispatcher.leaveOut(e);\n      }\n    },\n    cancel: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.cancel(e);\n      this.cleanupMouse();\n    },\n    cleanupMouse: function() {\n      pointermap['delete'](this.POINTER_ID);\n    }\n  };\n\n  scope.mouseEvents = mouseEvents;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var findTarget = scope.findTarget;\n  var allShadows = scope.targetFinding.allShadows.bind(scope.targetFinding);\n  var pointermap = dispatcher.pointermap;\n  var touchMap = Array.prototype.map.call.bind(Array.prototype.map);\n  // This should be long enough to ignore compat mouse events made by touch\n  var DEDUP_TIMEOUT = 2500;\n  var CLICK_COUNT_TIMEOUT = 200;\n  var ATTRIB = 'touch-action';\n  var INSTALLER;\n  // The presence of touch event handlers blocks scrolling, and so we must be careful to\n  // avoid adding handlers unnecessarily.  Chrome plans to add a touch-action-delay property\n  // (crbug.com/329559) to address this, and once we have that we can opt-in to a simpler\n  // handler registration mechanism.  Rather than try to predict how exactly to opt-in to\n  // that we'll just leave this disabled until there is a build of Chrome to test.\n  var HAS_TOUCH_ACTION_DELAY = false;\n  \n  // handler block for native touch events\n  var touchEvents = {\n    scrollType: new WeakMap(),\n    events: [\n      'touchstart',\n      'touchmove',\n      'touchend',\n      'touchcancel'\n    ],\n    register: function(target) {\n      if (HAS_TOUCH_ACTION_DELAY) {\n        dispatcher.listen(target, this.events);\n      } else {\n        INSTALLER.enableOnSubtree(target);\n      }\n    },\n    unregister: function(target) {\n      if (HAS_TOUCH_ACTION_DELAY) {\n        dispatcher.unlisten(target, this.events);\n      } else {\n        // TODO(dfreedman): is it worth it to disconnect the MO?\n      }\n    },\n    elementAdded: function(el) {\n      var a = el.getAttribute(ATTRIB);\n      var st = this.touchActionToScrollType(a);\n      if (st) {\n        this.scrollType.set(el, st);\n        dispatcher.listen(el, this.events);\n        // set touch-action on shadows as well\n        allShadows(el).forEach(function(s) {\n          this.scrollType.set(s, st);\n          dispatcher.listen(s, this.events);\n        }, this);\n      }\n    },\n    elementRemoved: function(el) {\n      this.scrollType['delete'](el);\n      dispatcher.unlisten(el, this.events);\n      // remove touch-action from shadow\n      allShadows(el).forEach(function(s) {\n        this.scrollType['delete'](s);\n        dispatcher.unlisten(s, this.events);\n      }, this);\n    },\n    elementChanged: function(el, oldValue) {\n      var a = el.getAttribute(ATTRIB);\n      var st = this.touchActionToScrollType(a);\n      var oldSt = this.touchActionToScrollType(oldValue);\n      // simply update scrollType if listeners are already established\n      if (st && oldSt) {\n        this.scrollType.set(el, st);\n        allShadows(el).forEach(function(s) {\n          this.scrollType.set(s, st);\n        }, this);\n      } else if (oldSt) {\n        this.elementRemoved(el);\n      } else if (st) {\n        this.elementAdded(el);\n      }\n    },\n    scrollTypes: {\n      EMITTER: 'none',\n      XSCROLLER: 'pan-x',\n      YSCROLLER: 'pan-y',\n      SCROLLER: /^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/\n    },\n    touchActionToScrollType: function(touchAction) {\n      var t = touchAction;\n      var st = this.scrollTypes;\n      if (t === 'none') {\n        return 'none';\n      } else if (t === st.XSCROLLER) {\n        return 'X';\n      } else if (t === st.YSCROLLER) {\n        return 'Y';\n      } else if (st.SCROLLER.exec(t)) {\n        return 'XY';\n      }\n    },\n    POINTER_TYPE: 'touch',\n    firstTouch: null,\n    isPrimaryTouch: function(inTouch) {\n      return this.firstTouch === inTouch.identifier;\n    },\n    setPrimaryTouch: function(inTouch) {\n      // set primary touch if there no pointers, or the only pointer is the mouse\n      if (pointermap.pointers() === 0 || (pointermap.pointers() === 1 && pointermap.has(1))) {\n        this.firstTouch = inTouch.identifier;\n        this.firstXY = {X: inTouch.clientX, Y: inTouch.clientY};\n        this.scrolling = false;\n        this.cancelResetClickCount();\n      }\n    },\n    removePrimaryPointer: function(inPointer) {\n      if (inPointer.isPrimary) {\n        this.firstTouch = null;\n        this.firstXY = null;\n        this.resetClickCount();\n      }\n    },\n    clickCount: 0,\n    resetId: null,\n    resetClickCount: function() {\n      var fn = function() {\n        this.clickCount = 0;\n        this.resetId = null;\n      }.bind(this);\n      this.resetId = setTimeout(fn, CLICK_COUNT_TIMEOUT);\n    },\n    cancelResetClickCount: function() {\n      if (this.resetId) {\n        clearTimeout(this.resetId);\n      }\n    },\n    typeToButtons: function(type) {\n      var ret = 0;\n      if (type === 'touchstart' || type === 'touchmove') {\n        ret = 1;\n      }\n      return ret;\n    },\n    touchToPointer: function(inTouch) {\n      var e = dispatcher.cloneEvent(inTouch);\n      // Spec specifies that pointerId 1 is reserved for Mouse.\n      // Touch identifiers can start at 0.\n      // Add 2 to the touch identifier for compatibility.\n      e.pointerId = inTouch.identifier + 2;\n      e.target = findTarget(e);\n      e.bubbles = true;\n      e.cancelable = true;\n      e.detail = this.clickCount;\n      e.button = 0;\n      e.buttons = this.typeToButtons(this.currentTouchEvent);\n      e.width = inTouch.webkitRadiusX || inTouch.radiusX || 0;\n      e.height = inTouch.webkitRadiusY || inTouch.radiusY || 0;\n      e.pressure = inTouch.webkitForce || inTouch.force || 0.5;\n      e.isPrimary = this.isPrimaryTouch(inTouch);\n      e.pointerType = this.POINTER_TYPE;\n      return e;\n    },\n    processTouches: function(inEvent, inFunction) {\n      var tl = inEvent.changedTouches;\n      this.currentTouchEvent = inEvent.type;\n      var pointers = touchMap(tl, this.touchToPointer, this);\n      // forward touch preventDefaults\n      pointers.forEach(function(p) {\n        p.preventDefault = function() {\n          this.scrolling = false;\n          this.firstXY = null;\n          inEvent.preventDefault();\n        };\n      }, this);\n      pointers.forEach(inFunction, this);\n    },\n    // For single axis scrollers, determines whether the element should emit\n    // pointer events or behave as a scroller\n    shouldScroll: function(inEvent) {\n      if (this.firstXY) {\n        var ret;\n        var scrollAxis = this.scrollType.get(inEvent.currentTarget);\n        if (scrollAxis === 'none') {\n          // this element is a touch-action: none, should never scroll\n          ret = false;\n        } else if (scrollAxis === 'XY') {\n          // this element should always scroll\n          ret = true;\n        } else {\n          var t = inEvent.changedTouches[0];\n          // check the intended scroll axis, and other axis\n          var a = scrollAxis;\n          var oa = scrollAxis === 'Y' ? 'X' : 'Y';\n          var da = Math.abs(t['client' + a] - this.firstXY[a]);\n          var doa = Math.abs(t['client' + oa] - this.firstXY[oa]);\n          // if delta in the scroll axis > delta other axis, scroll instead of\n          // making events\n          ret = da >= doa;\n        }\n        this.firstXY = null;\n        return ret;\n      }\n    },\n    findTouch: function(inTL, inId) {\n      for (var i = 0, l = inTL.length, t; i < l && (t = inTL[i]); i++) {\n        if (t.identifier === inId) {\n          return true;\n        }\n      }\n    },\n    // In some instances, a touchstart can happen without a touchend. This\n    // leaves the pointermap in a broken state.\n    // Therefore, on every touchstart, we remove the touches that did not fire a\n    // touchend event.\n    // To keep state globally consistent, we fire a\n    // pointercancel for this \"abandoned\" touch\n    vacuumTouches: function(inEvent) {\n      var tl = inEvent.touches;\n      // pointermap.pointers() should be < tl.length here, as the touchstart has not\n      // been processed yet.\n      if (pointermap.pointers() >= tl.length) {\n        var d = [];\n        pointermap.forEach(function(value, key) {\n          // Never remove pointerId == 1, which is mouse.\n          // Touch identifiers are 2 smaller than their pointerId, which is the\n          // index in pointermap.\n          if (key !== 1 && !this.findTouch(tl, key - 2)) {\n            var p = value.out;\n            d.push(this.touchToPointer(p));\n          }\n        }, this);\n        d.forEach(this.cancelOut, this);\n      }\n    },\n    touchstart: function(inEvent) {\n      this.vacuumTouches(inEvent);\n      this.setPrimaryTouch(inEvent.changedTouches[0]);\n      this.dedupSynthMouse(inEvent);\n      if (!this.scrolling) {\n        this.clickCount++;\n        this.processTouches(inEvent, this.overDown);\n      }\n    },\n    overDown: function(inPointer) {\n      var p = pointermap.set(inPointer.pointerId, {\n        target: inPointer.target,\n        out: inPointer,\n        outTarget: inPointer.target\n      });\n      dispatcher.over(inPointer);\n      dispatcher.enter(inPointer);\n      dispatcher.down(inPointer);\n    },\n    touchmove: function(inEvent) {\n      if (!this.scrolling) {\n        if (this.shouldScroll(inEvent)) {\n          this.scrolling = true;\n          this.touchcancel(inEvent);\n        } else {\n          inEvent.preventDefault();\n          this.processTouches(inEvent, this.moveOverOut);\n        }\n      }\n    },\n    moveOverOut: function(inPointer) {\n      var event = inPointer;\n      var pointer = pointermap.get(event.pointerId);\n      // a finger drifted off the screen, ignore it\n      if (!pointer) {\n        return;\n      }\n      var outEvent = pointer.out;\n      var outTarget = pointer.outTarget;\n      dispatcher.move(event);\n      if (outEvent && outTarget !== event.target) {\n        outEvent.relatedTarget = event.target;\n        event.relatedTarget = outTarget;\n        // recover from retargeting by shadow\n        outEvent.target = outTarget;\n        if (event.target) {\n          dispatcher.leaveOut(outEvent);\n          dispatcher.enterOver(event);\n        } else {\n          // clean up case when finger leaves the screen\n          event.target = outTarget;\n          event.relatedTarget = null;\n          this.cancelOut(event);\n        }\n      }\n      pointer.out = event;\n      pointer.outTarget = event.target;\n    },\n    touchend: function(inEvent) {\n      this.dedupSynthMouse(inEvent);\n      this.processTouches(inEvent, this.upOut);\n    },\n    upOut: function(inPointer) {\n      if (!this.scrolling) {\n        dispatcher.up(inPointer);\n        dispatcher.out(inPointer);\n        dispatcher.leave(inPointer);\n      }\n      this.cleanUpPointer(inPointer);\n    },\n    touchcancel: function(inEvent) {\n      this.processTouches(inEvent, this.cancelOut);\n    },\n    cancelOut: function(inPointer) {\n      dispatcher.cancel(inPointer);\n      dispatcher.out(inPointer);\n      dispatcher.leave(inPointer);\n      this.cleanUpPointer(inPointer);\n    },\n    cleanUpPointer: function(inPointer) {\n      pointermap['delete'](inPointer.pointerId);\n      this.removePrimaryPointer(inPointer);\n    },\n    // prevent synth mouse events from creating pointer events\n    dedupSynthMouse: function(inEvent) {\n      var lts = scope.mouseEvents.lastTouches;\n      var t = inEvent.changedTouches[0];\n      // only the primary finger will synth mouse events\n      if (this.isPrimaryTouch(t)) {\n        // remember x/y of last touch\n        var lt = {x: t.clientX, y: t.clientY};\n        lts.push(lt);\n        var fn = (function(lts, lt){\n          var i = lts.indexOf(lt);\n          if (i > -1) {\n            lts.splice(i, 1);\n          }\n        }).bind(null, lts, lt);\n        setTimeout(fn, DEDUP_TIMEOUT);\n      }\n    }\n  };\n\n  if (!HAS_TOUCH_ACTION_DELAY) {\n    INSTALLER = new scope.Installer(touchEvents.elementAdded, touchEvents.elementRemoved, touchEvents.elementChanged, touchEvents);\n  }\n\n  scope.touchEvents = touchEvents;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var pointermap = dispatcher.pointermap;\n  var HAS_BITMAP_TYPE = window.MSPointerEvent && typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE === 'number';\n  var msEvents = {\n    events: [\n      'MSPointerDown',\n      'MSPointerMove',\n      'MSPointerUp',\n      'MSPointerOut',\n      'MSPointerOver',\n      'MSPointerCancel',\n      'MSGotPointerCapture',\n      'MSLostPointerCapture'\n    ],\n    register: function(target) {\n      dispatcher.listen(target, this.events);\n    },\n    unregister: function(target) {\n      dispatcher.unlisten(target, this.events);\n    },\n    POINTER_TYPES: [\n      '',\n      'unavailable',\n      'touch',\n      'pen',\n      'mouse'\n    ],\n    prepareEvent: function(inEvent) {\n      var e = inEvent;\n      if (HAS_BITMAP_TYPE) {\n        e = dispatcher.cloneEvent(inEvent);\n        e.pointerType = this.POINTER_TYPES[inEvent.pointerType];\n      }\n      return e;\n    },\n    cleanup: function(id) {\n      pointermap['delete'](id);\n    },\n    MSPointerDown: function(inEvent) {\n      pointermap.set(inEvent.pointerId, inEvent);\n      var e = this.prepareEvent(inEvent);\n      dispatcher.down(e);\n    },\n    MSPointerMove: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.move(e);\n    },\n    MSPointerUp: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.up(e);\n      this.cleanup(inEvent.pointerId);\n    },\n    MSPointerOut: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.leaveOut(e);\n    },\n    MSPointerOver: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.enterOver(e);\n    },\n    MSPointerCancel: function(inEvent) {\n      var e = this.prepareEvent(inEvent);\n      dispatcher.cancel(e);\n      this.cleanup(inEvent.pointerId);\n    },\n    MSLostPointerCapture: function(inEvent) {\n      var e = dispatcher.makeEvent('lostpointercapture', inEvent);\n      dispatcher.dispatchEvent(e);\n    },\n    MSGotPointerCapture: function(inEvent) {\n      var e = dispatcher.makeEvent('gotpointercapture', inEvent);\n      dispatcher.dispatchEvent(e);\n    }\n  };\n\n  scope.msEvents = msEvents;\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This module contains the handlers for native platform events.\n * From here, the dispatcher is called to create unified pointer events.\n * Included are touch events (v1), mouse events, and MSPointerEvents.\n */\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n\n  // only activate if this platform does not have pointer events\n  if (window.navigator.pointerEnabled === undefined) {\n    Object.defineProperty(window.navigator, 'pointerEnabled', {value: true, enumerable: true});\n\n    if (window.navigator.msPointerEnabled) {\n      var tp = window.navigator.msMaxTouchPoints;\n      Object.defineProperty(window.navigator, 'maxTouchPoints', {\n        value: tp,\n        enumerable: true\n      });\n      dispatcher.registerSource('ms', scope.msEvents);\n    } else {\n      dispatcher.registerSource('mouse', scope.mouseEvents);\n      if (window.ontouchstart !== undefined) {\n        dispatcher.registerSource('touch', scope.touchEvents);\n      }\n    }\n\n    dispatcher.register(document);\n  }\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var n = window.navigator;\n  var s, r;\n  function assertDown(id) {\n    if (!dispatcher.pointermap.has(id)) {\n      throw new Error('InvalidPointerId');\n    }\n  }\n  if (n.msPointerEnabled) {\n    s = function(pointerId) {\n      assertDown(pointerId);\n      this.msSetPointerCapture(pointerId);\n    };\n    r = function(pointerId) {\n      assertDown(pointerId);\n      this.msReleasePointerCapture(pointerId);\n    };\n  } else {\n    s = function setPointerCapture(pointerId) {\n      assertDown(pointerId);\n      dispatcher.setCapture(pointerId, this);\n    };\n    r = function releasePointerCapture(pointerId) {\n      assertDown(pointerId);\n      dispatcher.releaseCapture(pointerId, this);\n    };\n  }\n  if (window.Element && !Element.prototype.setPointerCapture) {\n    Object.defineProperties(Element.prototype, {\n      'setPointerCapture': {\n        value: s\n      },\n      'releasePointerCapture': {\n        value: r\n      }\n    });\n  }\n})(window.PointerEventsPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  /**\n   * This class contains the gesture recognizers that create the PointerGesture\n   * events.\n   *\n   * @class PointerGestures\n   * @static\n   */\n  scope = scope || {};\n  scope.utils = {\n    LCA: {\n      // Determines the lowest node in the ancestor chain of a and b\n      find: function(a, b) {\n        if (a === b) {\n          return a;\n        }\n        // fast case, a is a direct descendant of b or vice versa\n        if (a.contains) {\n          if (a.contains(b)) {\n            return a;\n          }\n          if (b.contains(a)) {\n            return b;\n          }\n        }\n        var adepth = this.depth(a);\n        var bdepth = this.depth(b);\n        var d = adepth - bdepth;\n        if (d > 0) {\n          a = this.walk(a, d);\n        } else {\n          b = this.walk(b, -d);\n        }\n        while(a && b && a !== b) {\n          a = this.walk(a, 1);\n          b = this.walk(b, 1);\n        }\n        return a;\n      },\n      walk: function(n, u) {\n        for (var i = 0; i < u; i++) {\n          n = n.parentNode;\n        }\n        return n;\n      },\n      depth: function(n) {\n        var d = 0;\n        while(n) {\n          d++;\n          n = n.parentNode;\n        }\n        return d;\n      }\n    }\n  };\n  scope.findLCA = function(a, b) {\n    return scope.utils.LCA.find(a, b);\n  }\n  window.PointerGestures = scope;\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This module implements an map of pointer states\n */\n(function(scope) {\n  var USE_MAP = window.Map && window.Map.prototype.forEach;\n  var POINTERS_FN = function(){ return this.size; };\n  function PointerMap() {\n    if (USE_MAP) {\n      var m = new Map();\n      m.pointers = POINTERS_FN;\n      return m;\n    } else {\n      this.keys = [];\n      this.values = [];\n    }\n  }\n\n  PointerMap.prototype = {\n    set: function(inId, inEvent) {\n      var i = this.keys.indexOf(inId);\n      if (i > -1) {\n        this.values[i] = inEvent;\n      } else {\n        this.keys.push(inId);\n        this.values.push(inEvent);\n      }\n    },\n    has: function(inId) {\n      return this.keys.indexOf(inId) > -1;\n    },\n    'delete': function(inId) {\n      var i = this.keys.indexOf(inId);\n      if (i > -1) {\n        this.keys.splice(i, 1);\n        this.values.splice(i, 1);\n      }\n    },\n    get: function(inId) {\n      var i = this.keys.indexOf(inId);\n      return this.values[i];\n    },\n    clear: function() {\n      this.keys.length = 0;\n      this.values.length = 0;\n    },\n    // return value, key, map\n    forEach: function(callback, thisArg) {\n      this.values.forEach(function(v, i) {\n        callback.call(thisArg, v, this.keys[i], this);\n      }, this);\n    },\n    pointers: function() {\n      return this.keys.length;\n    }\n  };\n\n  scope.PointerMap = PointerMap;\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  var CLONE_PROPS = [\n    // MouseEvent\n    'bubbles',\n    'cancelable',\n    'view',\n    'detail',\n    'screenX',\n    'screenY',\n    'clientX',\n    'clientY',\n    'ctrlKey',\n    'altKey',\n    'shiftKey',\n    'metaKey',\n    'button',\n    'relatedTarget',\n    // DOM Level 3\n    'buttons',\n    // PointerEvent\n    'pointerId',\n    'width',\n    'height',\n    'pressure',\n    'tiltX',\n    'tiltY',\n    'pointerType',\n    'hwTimestamp',\n    'isPrimary',\n    // event instance\n    'type',\n    'target',\n    'currentTarget',\n    'screenX',\n    'screenY',\n    'pageX',\n    'pageY',\n    'tapPrevented'\n  ];\n\n  var CLONE_DEFAULTS = [\n    // MouseEvent\n    false,\n    false,\n    null,\n    null,\n    0,\n    0,\n    0,\n    0,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null,\n    // DOM Level 3\n    0,\n    // PointerEvent\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    '',\n    0,\n    false,\n    // event instance\n    '',\n    null,\n    null,\n    0,\n    0,\n    0,\n    0\n  ];\n\n  var dispatcher = {\n    handledEvents: new WeakMap(),\n    targets: new WeakMap(),\n    handlers: {},\n    recognizers: {},\n    events: {},\n    // Add a new gesture recognizer to the event listeners.\n    // Recognizer needs an `events` property.\n    registerRecognizer: function(inName, inRecognizer) {\n      var r = inRecognizer;\n      this.recognizers[inName] = r;\n      r.events.forEach(function(e) {\n        if (r[e]) {\n          this.events[e] = true;\n          var f = r[e].bind(r);\n          this.addHandler(e, f);\n        }\n      }, this);\n    },\n    addHandler: function(inEvent, inFn) {\n      var e = inEvent;\n      if (!this.handlers[e]) {\n        this.handlers[e] = [];\n      }\n      this.handlers[e].push(inFn);\n    },\n    // add event listeners for inTarget\n    registerTarget: function(inTarget) {\n      this.listen(Object.keys(this.events), inTarget);\n    },\n    // remove event listeners for inTarget\n    unregisterTarget: function(inTarget) {\n      this.unlisten(Object.keys(this.events), inTarget);\n    },\n    // LISTENER LOGIC\n    eventHandler: function(inEvent) {\n      if (this.handledEvents.get(inEvent)) {\n        return;\n      }\n      var type = inEvent.type, fns = this.handlers[type];\n      if (fns) {\n        this.makeQueue(fns, inEvent);\n      }\n      this.handledEvents.set(inEvent, true);\n    },\n    // queue event for async dispatch\n    makeQueue: function(inHandlerFns, inEvent) {\n      // must clone events to keep the (possibly shadowed) target correct for\n      // async dispatching\n      var e = this.cloneEvent(inEvent);\n      setTimeout(this.runQueue.bind(this, inHandlerFns, e), 0);\n    },\n    // Dispatch the queued events\n    runQueue: function(inHandlers, inEvent) {\n      this.currentPointerId = inEvent.pointerId;\n      for (var i = 0, f, l = inHandlers.length; (i < l) && (f = inHandlers[i]); i++) {\n        f(inEvent);\n      }\n      this.currentPointerId = 0;\n    },\n    // set up event listeners\n    listen: function(inEvents, inTarget) {\n      inEvents.forEach(function(e) {\n        this.addEvent(e, this.boundHandler, false, inTarget);\n      }, this);\n    },\n    // remove event listeners\n    unlisten: function(inEvents) {\n      inEvents.forEach(function(e) {\n        this.removeEvent(e, this.boundHandler, false, inTarget);\n      }, this);\n    },\n    addEvent: function(inEventName, inEventHandler, inCapture, inTarget) {\n      inTarget.addEventListener(inEventName, inEventHandler, inCapture);\n    },\n    removeEvent: function(inEventName, inEventHandler, inCapture, inTarget) {\n      inTarget.removeEventListener(inEventName, inEventHandler, inCapture);\n    },\n    // EVENT CREATION AND TRACKING\n    // Creates a new Event of type `inType`, based on the information in\n    // `inEvent`.\n    makeEvent: function(inType, inDict) {\n      return new PointerGestureEvent(inType, inDict);\n    },\n    /*\n     * Returns a snapshot of inEvent, with writable properties.\n     *\n     * @method cloneEvent\n     * @param {Event} inEvent An event that contains properties to copy.\n     * @return {Object} An object containing shallow copies of `inEvent`'s\n     *    properties.\n     */\n    cloneEvent: function(inEvent) {\n      var eventCopy = {}, p;\n      for (var i = 0; i < CLONE_PROPS.length; i++) {\n        p = CLONE_PROPS[i];\n        eventCopy[p] = inEvent[p] || CLONE_DEFAULTS[i];\n      }\n      return eventCopy;\n    },\n    // Dispatches the event to its target.\n    dispatchEvent: function(inEvent, inTarget) {\n      var t = inTarget || this.targets.get(inEvent);\n      if (t) {\n        t.dispatchEvent(inEvent);\n        if (inEvent.tapPrevented) {\n          this.preventTap(this.currentPointerId);\n        }\n      }\n    },\n    asyncDispatchEvent: function(inEvent, inTarget) {\n      var fn = function() {\n        this.dispatchEvent(inEvent, inTarget);\n      }.bind(this);\n      setTimeout(fn, 0);\n    },\n    preventTap: function(inPointerId) {\n      var t = this.recognizers.tap;\n      if (t){\n        t.preventTap(inPointerId);\n      }\n    }\n  };\n  dispatcher.boundHandler = dispatcher.eventHandler.bind(dispatcher);\n  // recognizers call into the dispatcher and load later\n  // solve the chicken and egg problem by having registerScopes module run last\n  dispatcher.registerQueue = [];\n  dispatcher.immediateRegister = false;\n  scope.dispatcher = dispatcher;\n  /**\n   * Enable gesture events for a given scope, typically\n   * [ShadowRoots](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#shadow-root-object).\n   *\n   * @for PointerGestures\n   * @method register\n   * @param {ShadowRoot} scope A top level scope to enable gesture\n   * support on.\n   */\n  scope.register = function(inScope) {\n    if (dispatcher.immediateRegister) {\n      var pe = window.PointerEventsPolyfill;\n      if (pe) {\n        pe.register(inScope);\n      }\n      scope.dispatcher.registerTarget(inScope);\n    } else {\n      dispatcher.registerQueue.push(inScope);\n    }\n  };\n  scope.register(document);\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This event is fired when a pointer is held down for 200ms.\n *\n * @module PointerGestures\n * @submodule Events\n * @class hold\n */\n/**\n * Type of pointer that made the holding event.\n * @type String\n * @property pointerType\n */\n/**\n * Screen X axis position of the held pointer\n * @type Number\n * @property clientX\n */\n/**\n * Screen Y axis position of the held pointer\n * @type Number\n * @property clientY\n */\n/**\n * Type of pointer that made the holding event.\n * @type String\n * @property pointerType\n */\n/**\n * This event is fired every 200ms while a pointer is held down.\n *\n * @class holdpulse\n * @extends hold\n */\n/**\n * Milliseconds pointer has been held down.\n * @type Number\n * @property holdTime\n */\n/**\n * This event is fired when a held pointer is released or moved.\n *\n * @class released\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var hold = {\n    // wait at least HOLD_DELAY ms between hold and pulse events\n    HOLD_DELAY: 200,\n    // pointer can move WIGGLE_THRESHOLD pixels before not counting as a hold\n    WIGGLE_THRESHOLD: 16,\n    events: [\n      'pointerdown',\n      'pointermove',\n      'pointerup',\n      'pointercancel'\n    ],\n    heldPointer: null,\n    holdJob: null,\n    pulse: function() {\n      var hold = Date.now() - this.heldPointer.timeStamp;\n      var type = this.held ? 'holdpulse' : 'hold';\n      this.fireHold(type, hold);\n      this.held = true;\n    },\n    cancel: function() {\n      clearInterval(this.holdJob);\n      if (this.held) {\n        this.fireHold('release');\n      }\n      this.held = false;\n      this.heldPointer = null;\n      this.target = null;\n      this.holdJob = null;\n    },\n    pointerdown: function(inEvent) {\n      if (inEvent.isPrimary && !this.heldPointer) {\n        this.heldPointer = inEvent;\n        this.target = inEvent.target;\n        this.holdJob = setInterval(this.pulse.bind(this), this.HOLD_DELAY);\n      }\n    },\n    pointerup: function(inEvent) {\n      if (this.heldPointer && this.heldPointer.pointerId === inEvent.pointerId) {\n        this.cancel();\n      }\n    },\n    pointercancel: function(inEvent) {\n      this.cancel();\n    },\n    pointermove: function(inEvent) {\n      if (this.heldPointer && this.heldPointer.pointerId === inEvent.pointerId) {\n        var x = inEvent.clientX - this.heldPointer.clientX;\n        var y = inEvent.clientY - this.heldPointer.clientY;\n        if ((x * x + y * y) > this.WIGGLE_THRESHOLD) {\n          this.cancel();\n        }\n      }\n    },\n    fireHold: function(inType, inHoldTime) {\n      var p = {\n        pointerType: this.heldPointer.pointerType,\n        clientX: this.heldPointer.clientX,\n        clientY: this.heldPointer.clientY\n      };\n      if (inHoldTime) {\n        p.holdTime = inHoldTime;\n      }\n      var e = dispatcher.makeEvent(inType, p);\n      dispatcher.dispatchEvent(e, this.target);\n      if (e.tapPrevented) {\n        dispatcher.preventTap(this.heldPointer.pointerId);\n      }\n    }\n  };\n  dispatcher.registerRecognizer('hold', hold);\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This event denotes the beginning of a series of tracking events.\n *\n * @module PointerGestures\n * @submodule Events\n * @class trackstart\n */\n/**\n * Pixels moved in the x direction since trackstart.\n * @type Number\n * @property dx\n */\n/**\n * Pixes moved in the y direction since trackstart.\n * @type Number\n * @property dy\n */\n/**\n * Pixels moved in the x direction since the last track.\n * @type Number\n * @property ddx\n */\n/**\n * Pixles moved in the y direction since the last track.\n * @type Number\n * @property ddy\n */\n/**\n * The clientX position of the track gesture.\n * @type Number\n * @property clientX\n */\n/**\n * The clientY position of the track gesture.\n * @type Number\n * @property clientY\n */\n/**\n * The pageX position of the track gesture.\n * @type Number\n * @property pageX\n */\n/**\n * The pageY position of the track gesture.\n * @type Number\n * @property pageY\n */\n/**\n * The screenX position of the track gesture.\n * @type Number\n * @property screenX\n */\n/**\n * The screenY position of the track gesture.\n * @type Number\n * @property screenY\n */\n/**\n * The last x axis direction of the pointer.\n * @type Number\n * @property xDirection\n */\n/**\n * The last y axis direction of the pointer.\n * @type Number\n * @property yDirection\n */\n/**\n * A shared object between all tracking events.\n * @type Object\n * @property trackInfo\n */\n/**\n * The element currently under the pointer.\n * @type Element\n * @property relatedTarget\n */\n/**\n * The type of pointer that make the track gesture.\n * @type String\n * @property pointerType\n */\n/**\n *\n * This event fires for all pointer movement being tracked.\n *\n * @class track\n * @extends trackstart\n */\n/**\n * This event fires when the pointer is no longer being tracked.\n *\n * @class trackend\n * @extends trackstart\n */\n\n (function(scope) {\n   var dispatcher = scope.dispatcher;\n   var pointermap = new scope.PointerMap();\n   var track = {\n     events: [\n       'pointerdown',\n       'pointermove',\n       'pointerup',\n       'pointercancel'\n     ],\n     WIGGLE_THRESHOLD: 4,\n     clampDir: function(inDelta) {\n       return inDelta > 0 ? 1 : -1;\n     },\n     calcPositionDelta: function(inA, inB) {\n       var x = 0, y = 0;\n       if (inA && inB) {\n         x = inB.pageX - inA.pageX;\n         y = inB.pageY - inA.pageY;\n       }\n       return {x: x, y: y};\n     },\n     fireTrack: function(inType, inEvent, inTrackingData) {\n       var t = inTrackingData;\n       var d = this.calcPositionDelta(t.downEvent, inEvent);\n       var dd = this.calcPositionDelta(t.lastMoveEvent, inEvent);\n       if (dd.x) {\n         t.xDirection = this.clampDir(dd.x);\n       }\n       if (dd.y) {\n         t.yDirection = this.clampDir(dd.y);\n       }\n       var trackData = {\n         dx: d.x,\n         dy: d.y,\n         ddx: dd.x,\n         ddy: dd.y,\n         clientX: inEvent.clientX,\n         clientY: inEvent.clientY,\n         pageX: inEvent.pageX,\n         pageY: inEvent.pageY,\n         screenX: inEvent.screenX,\n         screenY: inEvent.screenY,\n         xDirection: t.xDirection,\n         yDirection: t.yDirection,\n         trackInfo: t.trackInfo,\n         relatedTarget: inEvent.target,\n         pointerType: inEvent.pointerType\n       };\n       var e = dispatcher.makeEvent(inType, trackData);\n       t.lastMoveEvent = inEvent;\n       dispatcher.dispatchEvent(e, t.downTarget);\n     },\n     pointerdown: function(inEvent) {\n       if (inEvent.isPrimary && (inEvent.pointerType === 'mouse' ? inEvent.buttons === 1 : true)) {\n         var p = {\n           downEvent: inEvent,\n           downTarget: inEvent.target,\n           trackInfo: {},\n           lastMoveEvent: null,\n           xDirection: 0,\n           yDirection: 0,\n           tracking: false\n         };\n         pointermap.set(inEvent.pointerId, p);\n       }\n     },\n     pointermove: function(inEvent) {\n       var p = pointermap.get(inEvent.pointerId);\n       if (p) {\n         if (!p.tracking) {\n           var d = this.calcPositionDelta(p.downEvent, inEvent);\n           var move = d.x * d.x + d.y * d.y;\n           // start tracking only if finger moves more than WIGGLE_THRESHOLD\n           if (move > this.WIGGLE_THRESHOLD) {\n             p.tracking = true;\n             this.fireTrack('trackstart', p.downEvent, p);\n             this.fireTrack('track', inEvent, p);\n           }\n         } else {\n           this.fireTrack('track', inEvent, p);\n         }\n       }\n     },\n     pointerup: function(inEvent) {\n       var p = pointermap.get(inEvent.pointerId);\n       if (p) {\n         if (p.tracking) {\n           this.fireTrack('trackend', inEvent, p);\n         }\n         pointermap.delete(inEvent.pointerId);\n       }\n     },\n     pointercancel: function(inEvent) {\n       this.pointerup(inEvent);\n     }\n   };\n   dispatcher.registerRecognizer('track', track);\n })(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This event denotes a rapid down/move/up sequence from a pointer.\n *\n * The event is sent to the first element the pointer went down on.\n *\n * @module PointerGestures\n * @submodule Events\n * @class flick\n */\n/**\n * Signed velocity of the flick in the x direction.\n * @property xVelocity\n * @type Number\n */\n/**\n * Signed velocity of the flick in the y direction.\n * @type Number\n * @property yVelocity\n */\n/**\n * Unsigned total velocity of the flick.\n * @type Number\n * @property velocity\n */\n/**\n * Angle of the flick in degrees, with 0 along the\n * positive x axis.\n * @type Number\n * @property angle\n */\n/**\n * Axis with the greatest absolute velocity. Denoted\n * with 'x' or 'y'.\n * @type String\n * @property majorAxis\n */\n/**\n * Type of the pointer that made the flick.\n * @type String\n * @property pointerType\n */\n\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var flick = {\n    // TODO(dfreedman): value should be low enough for low speed flicks, but\n    // high enough to remove accidental flicks\n    MIN_VELOCITY: 0.5 /* px/ms */,\n    MAX_QUEUE: 4,\n    moveQueue: [],\n    target: null,\n    pointerId: null,\n    events: [\n      'pointerdown',\n      'pointermove',\n      'pointerup',\n      'pointercancel'\n    ],\n    pointerdown: function(inEvent) {\n      if (inEvent.isPrimary && !this.pointerId) {\n        this.pointerId = inEvent.pointerId;\n        this.target = inEvent.target;\n        this.addMove(inEvent);\n      }\n    },\n    pointermove: function(inEvent) {\n      if (inEvent.pointerId === this.pointerId) {\n        this.addMove(inEvent);\n      }\n    },\n    pointerup: function(inEvent) {\n      if (inEvent.pointerId === this.pointerId) {\n        this.fireFlick(inEvent);\n      }\n      this.cleanup();\n    },\n    pointercancel: function(inEvent) {\n      this.cleanup();\n    },\n    cleanup: function() {\n      this.moveQueue = [];\n      this.target = null;\n      this.pointerId = null;\n    },\n    addMove: function(inEvent) {\n      if (this.moveQueue.length >= this.MAX_QUEUE) {\n        this.moveQueue.shift();\n      }\n      this.moveQueue.push(inEvent);\n    },\n    fireFlick: function(inEvent) {\n      var e = inEvent;\n      var l = this.moveQueue.length;\n      var dt, dx, dy, tx, ty, tv, x = 0, y = 0, v = 0;\n      // flick based off the fastest segment of movement\n      for (var i = 0, m; i < l && (m = this.moveQueue[i]); i++) {\n        dt = e.timeStamp - m.timeStamp;\n        dx = e.clientX - m.clientX, dy = e.clientY - m.clientY;\n        tx = dx / dt, ty = dy / dt, tv = Math.sqrt(tx * tx + ty * ty);\n        if (tv > v) {\n          x = tx, y = ty, v = tv;\n        }\n      }\n      var ma = Math.abs(x) > Math.abs(y) ? 'x' : 'y';\n      var a = this.calcAngle(x, y);\n      if (Math.abs(v) >= this.MIN_VELOCITY) {\n        var ev = dispatcher.makeEvent('flick', {\n          xVelocity: x,\n          yVelocity: y,\n          velocity: v,\n          angle: a,\n          majorAxis: ma,\n          pointerType: inEvent.pointerType\n        });\n        dispatcher.dispatchEvent(ev, this.target);\n      }\n    },\n    calcAngle: function(inX, inY) {\n      return (Math.atan2(inY, inX) * 180 / Math.PI);\n    }\n  };\n  dispatcher.registerRecognizer('flick', flick);\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/*\n * Basic strategy: find the farthest apart points, use as diameter of circle\n * react to size change and rotation of the chord\n */\n\n/**\n * @module PointerGestures\n * @submodule Events\n * @class pinch\n */\n/**\n * Scale of the pinch zoom gesture\n * @property scale\n * @type Number\n */\n/**\n * Center X position of pointers causing pinch\n * @property centerX\n * @type Number\n */\n/**\n * Center Y position of pointers causing pinch\n * @property centerY\n * @type Number\n */\n\n/**\n * @module PointerGestures\n * @submodule Events\n * @class rotate\n */\n/**\n * Angle (in degrees) of rotation. Measured from starting positions of pointers.\n * @property angle\n * @type Number\n */\n/**\n * Center X position of pointers causing rotation\n * @property centerX\n * @type Number\n */\n/**\n * Center Y position of pointers causing rotation\n * @property centerY\n * @type Number\n */\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var pointermap = new scope.PointerMap();\n  var RAD_TO_DEG = 180 / Math.PI;\n  var pinch = {\n    events: [\n      'pointerdown',\n      'pointermove',\n      'pointerup',\n      'pointercancel'\n    ],\n    reference: {},\n    pointerdown: function(ev) {\n      pointermap.set(ev.pointerId, ev);\n      if (pointermap.pointers() == 2) {\n        var points = this.calcChord();\n        var angle = this.calcAngle(points);\n        this.reference = {\n          angle: angle,\n          diameter: points.diameter,\n          target: scope.findLCA(points.a.target, points.b.target)\n        };\n      }\n    },\n    pointerup: function(ev) {\n      pointermap.delete(ev.pointerId);\n    },\n    pointermove: function(ev) {\n      if (pointermap.has(ev.pointerId)) {\n        pointermap.set(ev.pointerId, ev);\n        if (pointermap.pointers() > 1) {\n          this.calcPinchRotate();\n        }\n      }\n    },\n    pointercancel: function(ev) {\n      this.pointerup(ev);\n    },\n    dispatchPinch: function(diameter, points) {\n      var zoom = diameter / this.reference.diameter;\n      var ev = dispatcher.makeEvent('pinch', {\n        scale: zoom,\n        centerX: points.center.x,\n        centerY: points.center.y\n      });\n      dispatcher.dispatchEvent(ev, this.reference.target);\n    },\n    dispatchRotate: function(angle, points) {\n      var diff = Math.round((angle - this.reference.angle) % 360);\n      var ev = dispatcher.makeEvent('rotate', {\n        angle: diff,\n        centerX: points.center.x,\n        centerY: points.center.y\n      });\n      dispatcher.dispatchEvent(ev, this.reference.target);\n    },\n    calcPinchRotate: function() {\n      var points = this.calcChord();\n      var diameter = points.diameter;\n      var angle = this.calcAngle(points);\n      if (diameter != this.reference.diameter) {\n        this.dispatchPinch(diameter, points);\n      }\n      if (angle != this.reference.angle) {\n        this.dispatchRotate(angle, points);\n      }\n    },\n    calcChord: function() {\n      var pointers = [];\n      pointermap.forEach(function(p) {\n        pointers.push(p);\n      });\n      var dist = 0;\n      // start with at least two pointers\n      var points = {a: pointers[0], b: pointers[1]};\n      var x, y, d;\n      for (var i = 0; i < pointers.length; i++) {\n        var a = pointers[i];\n        for (var j = i + 1; j < pointers.length; j++) {\n          var b = pointers[j];\n          x = Math.abs(a.clientX - b.clientX);\n          y = Math.abs(a.clientY - b.clientY);\n          d = x + y;\n          if (d > dist) {\n            dist = d;\n            points = {a: a, b: b};\n          }\n        }\n      }\n      x = Math.abs(points.a.clientX + points.b.clientX) / 2;\n      y = Math.abs(points.a.clientY + points.b.clientY) / 2;\n      points.center = { x: x, y: y };\n      points.diameter = dist;\n      return points;\n    },\n    calcAngle: function(points) {\n      var x = points.a.clientX - points.b.clientX;\n      var y = points.a.clientY - points.b.clientY;\n      return (360 + Math.atan2(y, x) * RAD_TO_DEG) % 360;\n    },\n  };\n  dispatcher.registerRecognizer('pinch', pinch);\n})(window.PointerGestures);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This event is fired when a pointer quickly goes down and up, and is used to\n * denote activation.\n *\n * Any gesture event can prevent the tap event from being created by calling\n * `event.preventTap`.\n *\n * Any pointer event can prevent the tap by setting the `tapPrevented` property\n * on itself.\n *\n * @module PointerGestures\n * @submodule Events\n * @class tap\n */\n/**\n * X axis position of the tap.\n * @property x\n * @type Number\n */\n/**\n * Y axis position of the tap.\n * @property y\n * @type Number\n */\n/**\n * Type of the pointer that made the tap.\n * @property pointerType\n * @type String\n */\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  var pointermap = new scope.PointerMap();\n  var tap = {\n    events: [\n      'pointerdown',\n      'pointermove',\n      'pointerup',\n      'pointercancel',\n      'keyup'\n    ],\n    pointerdown: function(inEvent) {\n      if (inEvent.isPrimary && !inEvent.tapPrevented) {\n        pointermap.set(inEvent.pointerId, {\n          target: inEvent.target,\n          buttons: inEvent.buttons,\n          x: inEvent.clientX,\n          y: inEvent.clientY\n        });\n      }\n    },\n    pointermove: function(inEvent) {\n      if (inEvent.isPrimary) {\n        var start = pointermap.get(inEvent.pointerId);\n        if (start) {\n          if (inEvent.tapPrevented) {\n            pointermap.delete(inEvent.pointerId);\n          }\n        }\n      }\n    },\n    shouldTap: function(e, downState) {\n      if (!e.tapPrevented) {\n        if (e.pointerType === 'mouse') {\n          // only allow left click to tap for mouse\n          return downState.buttons === 1;\n        } else {\n          return true;\n        }\n      }\n    },\n    pointerup: function(inEvent) {\n      var start = pointermap.get(inEvent.pointerId);\n      if (start && this.shouldTap(inEvent, start)) {\n        var t = scope.findLCA(start.target, inEvent.target);\n        if (t) {\n          var e = dispatcher.makeEvent('tap', {\n            x: inEvent.clientX,\n            y: inEvent.clientY,\n            detail: inEvent.detail,\n            pointerType: inEvent.pointerType\n          });\n          dispatcher.dispatchEvent(e, t);\n        }\n      }\n      pointermap.delete(inEvent.pointerId);\n    },\n    pointercancel: function(inEvent) {\n      pointermap.delete(inEvent.pointerId);\n    },\n    keyup: function(inEvent) {\n      var code = inEvent.keyCode;\n      // 32 == spacebar\n      if (code === 32) {\n        var t = inEvent.target;\n        if (!(t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement)) {\n          dispatcher.dispatchEvent(dispatcher.makeEvent('tap', {\n            x: 0,\n            y: 0,\n            detail: 0,\n            pointerType: 'unavailable'\n          }), t);\n        }\n      }\n    },\n    preventTap: function(inPointerId) {\n      pointermap.delete(inPointerId);\n    }\n  };\n  dispatcher.registerRecognizer('tap', tap);\n})(window.PointerGestures);\n","/*\n * Copyright 2014 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * Because recognizers are loaded after dispatcher, we have to wait to register\n * scopes until after all the recognizers.\n */\n(function(scope) {\n  var dispatcher = scope.dispatcher;\n  function registerScopes() {\n    dispatcher.immediateRegister = true;\n    var rq = dispatcher.registerQueue;\n    rq.forEach(scope.register);\n    rq.length = 0;\n  }\n  if (document.readyState === 'complete') {\n    registerScopes();\n  } else {\n    // register scopes after a steadystate is reached\n    // less MutationObserver churn\n    document.addEventListener('readystatechange', function() {\n      if (document.readyState === 'complete') {\n        registerScopes();\n      }\n    });\n  }\n})(window.PointerGestures);\n","// Copyright 2011 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function(global) {\n  'use strict';\n\n  var filter = Array.prototype.filter.call.bind(Array.prototype.filter);\n\n  function getTreeScope(node) {\n    while (node.parentNode) {\n      node = node.parentNode;\n    }\n\n    return typeof node.getElementById === 'function' ? node : null;\n  }\n\n\n  Node.prototype.bind = function(name, observable) {\n    console.error('Unhandled binding to Node: ', this, name, observable);\n  };\n\n  function unbind(node, name) {\n    var bindings = node.bindings;\n    if (!bindings) {\n      node.bindings = {};\n      return;\n    }\n\n    var binding = bindings[name];\n    if (!binding)\n      return;\n\n    binding.close();\n    bindings[name] = undefined;\n  }\n\n  Node.prototype.unbind = function(name) {\n    unbind(this, name);\n  };\n\n  Node.prototype.unbindAll = function() {\n    if (!this.bindings)\n      return;\n    var names = Object.keys(this.bindings);\n    for (var i = 0; i < names.length; i++) {\n      var binding = this.bindings[names[i]];\n      if (binding)\n        binding.close();\n    }\n\n    this.bindings = {};\n  };\n\n  function sanitizeValue(value) {\n    return value == null ? '' : value;\n  }\n\n  function updateText(node, value) {\n    node.data = sanitizeValue(value);\n  }\n\n  function textBinding(node) {\n    return function(value) {\n      return updateText(node, value);\n    };\n  }\n\n  Text.prototype.bind = function(name, value, oneTime) {\n    if (name !== 'textContent')\n      return Node.prototype.bind.call(this, name, value, oneTime);\n\n    if (oneTime)\n      return updateText(this, value);\n\n    unbind(this, 'textContent');\n    updateText(this, value.open(textBinding(this)));\n    return this.bindings.textContent = value;\n  }\n\n  function updateAttribute(el, name, conditional, value) {\n    if (conditional) {\n      if (value)\n        el.setAttribute(name, '');\n      else\n        el.removeAttribute(name);\n      return;\n    }\n\n    el.setAttribute(name, sanitizeValue(value));\n  }\n\n  function attributeBinding(el, name, conditional) {\n    return function(value) {\n      updateAttribute(el, name, conditional, value);\n    };\n  }\n\n  Element.prototype.bind = function(name, value, oneTime) {\n    var conditional = name[name.length - 1] == '?';\n    if (conditional) {\n      this.removeAttribute(name);\n      name = name.slice(0, -1);\n    }\n\n    if (oneTime)\n      return updateAttribute(this, name, conditional, value);\n\n    unbind(this, name);\n    updateAttribute(this, name, conditional,\n        value.open(attributeBinding(this, name, conditional)));\n\n    return this.bindings[name] = value;\n  };\n\n  var checkboxEventType;\n  (function() {\n    // Attempt to feature-detect which event (change or click) is fired first\n    // for checkboxes.\n    var div = document.createElement('div');\n    var checkbox = div.appendChild(document.createElement('input'));\n    checkbox.setAttribute('type', 'checkbox');\n    var first;\n    var count = 0;\n    checkbox.addEventListener('click', function(e) {\n      count++;\n      first = first || 'click';\n    });\n    checkbox.addEventListener('change', function() {\n      count++;\n      first = first || 'change';\n    });\n\n    var event = document.createEvent('MouseEvent');\n    event.initMouseEvent(\"click\", true, true, window, 0, 0, 0, 0, 0, false,\n        false, false, false, 0, null);\n    checkbox.dispatchEvent(event);\n    // WebKit/Blink don't fire the change event if the element is outside the\n    // document, so assume 'change' for that case.\n    checkboxEventType = count == 1 ? 'change' : first;\n  })();\n\n  function getEventForInputType(element) {\n    switch (element.type) {\n      case 'checkbox':\n        return checkboxEventType;\n      case 'radio':\n      case 'select-multiple':\n      case 'select-one':\n        return 'change';\n      case 'range':\n        if (/Trident|MSIE/.test(navigator.userAgent))\n          return 'change';\n      default:\n        return 'input';\n    }\n  }\n\n  function updateInput(input, property, value, santizeFn) {\n    input[property] = (santizeFn || sanitizeValue)(value);\n  }\n\n  function inputBinding(input, property, santizeFn) {\n    return function(value) {\n      return updateInput(input, property, value, santizeFn);\n    }\n  }\n\n  function noop() {}\n\n  function bindInputEvent(input, property, observable, postEventFn) {\n    var eventType = getEventForInputType(input);\n\n    function eventHandler() {\n      observable.setValue(input[property]);\n      observable.discardChanges();\n      (postEventFn || noop)(input);\n      Platform.performMicrotaskCheckpoint();\n    }\n    input.addEventListener(eventType, eventHandler);\n\n    var capturedClose = observable.close;\n    observable.close = function() {\n      if (!capturedClose)\n        return;\n      input.removeEventListener(eventType, eventHandler);\n\n      observable.close = capturedClose;\n      observable.close();\n      capturedClose = undefined;\n    }\n  }\n\n  function booleanSanitize(value) {\n    return Boolean(value);\n  }\n\n  // |element| is assumed to be an HTMLInputElement with |type| == 'radio'.\n  // Returns an array containing all radio buttons other than |element| that\n  // have the same |name|, either in the form that |element| belongs to or,\n  // if no form, in the document tree to which |element| belongs.\n  //\n  // This implementation is based upon the HTML spec definition of a\n  // \"radio button group\":\n  //   http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#radio-button-group\n  //\n  function getAssociatedRadioButtons(element) {\n    if (element.form) {\n      return filter(element.form.elements, function(el) {\n        return el != element &&\n            el.tagName == 'INPUT' &&\n            el.type == 'radio' &&\n            el.name == element.name;\n      });\n    } else {\n      var treeScope = getTreeScope(element);\n      if (!treeScope)\n        return [];\n      var radios = treeScope.querySelectorAll(\n          'input[type=\"radio\"][name=\"' + element.name + '\"]');\n      return filter(radios, function(el) {\n        return el != element && !el.form;\n      });\n    }\n  }\n\n  function checkedPostEvent(input) {\n    // Only the radio button that is getting checked gets an event. We\n    // therefore find all the associated radio buttons and update their\n    // check binding manually.\n    if (input.tagName === 'INPUT' &&\n        input.type === 'radio') {\n      getAssociatedRadioButtons(input).forEach(function(radio) {\n        var checkedBinding = radio.bindings.checked;\n        if (checkedBinding) {\n          // Set the value directly to avoid an infinite call stack.\n          checkedBinding.setValue(false);\n        }\n      });\n    }\n  }\n\n  HTMLInputElement.prototype.bind = function(name, value, oneTime) {\n    if (name !== 'value' && name !== 'checked')\n      return HTMLElement.prototype.bind.call(this, name, value, oneTime);\n\n\n    this.removeAttribute(name);\n    var sanitizeFn = name == 'checked' ? booleanSanitize : sanitizeValue;\n    var postEventFn = name == 'checked' ? checkedPostEvent : noop;\n\n    if (oneTime)\n      return updateInput(this, name, value, sanitizeFn);\n\n    unbind(this, name);\n    bindInputEvent(this, name, value, postEventFn);\n    updateInput(this, name,\n                value.open(inputBinding(this, name, sanitizeFn)),\n                sanitizeFn);\n\n    return this.bindings[name] = value;\n  }\n\n  HTMLTextAreaElement.prototype.bind = function(name, value, oneTime) {\n    if (name !== 'value')\n      return HTMLElement.prototype.bind.call(this, name, value, oneTime);\n\n    this.removeAttribute('value');\n\n    if (oneTime)\n      return updateInput(this, 'value', value);\n\n    unbind(this, 'value');\n    bindInputEvent(this, 'value', value);\n    updateInput(this, 'value',\n                value.open(inputBinding(this, 'value', sanitizeValue)));\n\n    return this.bindings.value = value;\n  }\n\n  function updateOption(option, value) {\n    var parentNode = option.parentNode;;\n    var select;\n    var selectBinding;\n    var oldValue;\n    if (parentNode instanceof HTMLSelectElement &&\n        parentNode.bindings &&\n        parentNode.bindings.value) {\n      select = parentNode;\n      selectBinding = select.bindings.value;\n      oldValue = select.value;\n    }\n\n    option.value = sanitizeValue(value);\n\n    if (select && select.value != oldValue) {\n      selectBinding.setValue(select.value);\n      selectBinding.discardChanges();\n      Platform.performMicrotaskCheckpoint();\n    }\n  }\n\n  function optionBinding(option) {\n    return function(value) {\n      updateOption(option, value);\n    }\n  }\n\n  HTMLOptionElement.prototype.bind = function(name, value, oneTime) {\n    if (name !== 'value')\n      return HTMLElement.prototype.bind.call(this, name, value, oneTime);\n\n    this.removeAttribute('value');\n\n    if (oneTime)\n      return updateOption(this, value);\n\n    unbind(this, 'value');\n    bindInputEvent(this, 'value', value);\n    updateOption(this, value.open(optionBinding(this)));\n    return this.bindings.value = value;\n  }\n\n  HTMLSelectElement.prototype.bind = function(name, value, oneTime) {\n    if (name === 'selectedindex')\n      name = 'selectedIndex';\n\n    if (name !== 'selectedIndex' && name !== 'value')\n      return HTMLElement.prototype.bind.call(this, name, value, oneTime);\n\n    this.removeAttribute(name);\n\n    if (oneTime)\n      return updateInput(this, name, value);\n\n    unbind(this, name);\n    bindInputEvent(this, name, value);\n    updateInput(this, name,\n                value.open(inputBinding(this, name)));\n    return this.bindings[name] = value;\n  }\n})(this);\n","// Copyright 2011 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function(global) {\n  'use strict';\n\n  function assert(v) {\n    if (!v)\n      throw new Error('Assertion failed');\n  }\n\n  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\n\n  function getFragmentRoot(node) {\n    var p;\n    while (p = node.parentNode) {\n      node = p;\n    }\n\n    return node;\n  }\n\n  function searchRefId(node, id) {\n    if (!id)\n      return;\n\n    var ref;\n    var selector = '#' + id;\n    while (!ref) {\n      node = getFragmentRoot(node);\n\n      if (node.protoContent_)\n        ref = node.protoContent_.querySelector(selector);\n      else if (node.getElementById)\n        ref = node.getElementById(id);\n\n      if (ref || !node.templateCreator_)\n        break\n\n      node = node.templateCreator_;\n    }\n\n    return ref;\n  }\n\n  function getInstanceRoot(node) {\n    while (node.parentNode) {\n      node = node.parentNode;\n    }\n    return node.templateCreator_ ? node : null;\n  }\n\n  var Map;\n  if (global.Map && typeof global.Map.prototype.forEach === 'function') {\n    Map = global.Map;\n  } else {\n    Map = function() {\n      this.keys = [];\n      this.values = [];\n    };\n\n    Map.prototype = {\n      set: function(key, value) {\n        var index = this.keys.indexOf(key);\n        if (index < 0) {\n          this.keys.push(key);\n          this.values.push(value);\n        } else {\n          this.values[index] = value;\n        }\n      },\n\n      get: function(key) {\n        var index = this.keys.indexOf(key);\n        if (index < 0)\n          return;\n\n        return this.values[index];\n      },\n\n      delete: function(key, value) {\n        var index = this.keys.indexOf(key);\n        if (index < 0)\n          return false;\n\n        this.keys.splice(index, 1);\n        this.values.splice(index, 1);\n        return true;\n      },\n\n      forEach: function(f, opt_this) {\n        for (var i = 0; i < this.keys.length; i++)\n          f.call(opt_this || this, this.values[i], this.keys[i], this);\n      }\n    };\n  }\n\n  // JScript does not have __proto__. We wrap all object literals with\n  // createObject which uses Object.create, Object.defineProperty and\n  // Object.getOwnPropertyDescriptor to create a new object that does the exact\n  // same thing. The main downside to this solution is that we have to extract\n  // all those property descriptors for IE.\n  var createObject = ('__proto__' in {}) ?\n      function(obj) { return obj; } :\n      function(obj) {\n        var proto = obj.__proto__;\n        if (!proto)\n          return obj;\n        var newObject = Object.create(proto);\n        Object.getOwnPropertyNames(obj).forEach(function(name) {\n          Object.defineProperty(newObject, name,\n                               Object.getOwnPropertyDescriptor(obj, name));\n        });\n        return newObject;\n      };\n\n  // IE does not support have Document.prototype.contains.\n  if (typeof document.contains != 'function') {\n    Document.prototype.contains = function(node) {\n      if (node === this || node.parentNode === this)\n        return true;\n      return this.documentElement.contains(node);\n    }\n  }\n\n  var BIND = 'bind';\n  var REPEAT = 'repeat';\n  var IF = 'if';\n\n  var templateAttributeDirectives = {\n    'template': true,\n    'repeat': true,\n    'bind': true,\n    'ref': true\n  };\n\n  var semanticTemplateElements = {\n    'THEAD': true,\n    'TBODY': true,\n    'TFOOT': true,\n    'TH': true,\n    'TR': true,\n    'TD': true,\n    'COLGROUP': true,\n    'COL': true,\n    'CAPTION': true,\n    'OPTION': true,\n    'OPTGROUP': true\n  };\n\n  var hasTemplateElement = typeof HTMLTemplateElement !== 'undefined';\n  if (hasTemplateElement) {\n    // TODO(rafaelw): Remove when fix for\n    // https://codereview.chromium.org/164803002/\n    // makes it to Chrome release.\n    (function() {\n      var t = document.createElement('template');\n      var d = t.content.ownerDocument;\n      var html = d.appendChild(d.createElement('html'));\n      var head = html.appendChild(d.createElement('head'));\n      var base = d.createElement('base');\n      base.href = document.baseURI;\n      head.appendChild(base);\n    })();\n  }\n\n  var allTemplatesSelectors = 'template, ' +\n      Object.keys(semanticTemplateElements).map(function(tagName) {\n        return tagName.toLowerCase() + '[template]';\n      }).join(', ');\n\n  function isSVGTemplate(el) {\n    return el.tagName == 'template' &&\n           el.namespaceURI == 'http://www.w3.org/2000/svg';\n  }\n\n  function isHTMLTemplate(el) {\n    return el.tagName == 'TEMPLATE' &&\n           el.namespaceURI == 'http://www.w3.org/1999/xhtml';\n  }\n\n  function isAttributeTemplate(el) {\n    return Boolean(semanticTemplateElements[el.tagName] &&\n                   el.hasAttribute('template'));\n  }\n\n  function isTemplate(el) {\n    if (el.isTemplate_ === undefined)\n      el.isTemplate_ = el.tagName == 'TEMPLATE' || isAttributeTemplate(el);\n\n    return el.isTemplate_;\n  }\n\n  // FIXME: Observe templates being added/removed from documents\n  // FIXME: Expose imperative API to decorate and observe templates in\n  // \"disconnected tress\" (e.g. ShadowRoot)\n  document.addEventListener('DOMContentLoaded', function(e) {\n    bootstrapTemplatesRecursivelyFrom(document);\n    // FIXME: Is this needed? Seems like it shouldn't be.\n    Platform.performMicrotaskCheckpoint();\n  }, false);\n\n  function forAllTemplatesFrom(node, fn) {\n    var subTemplates = node.querySelectorAll(allTemplatesSelectors);\n\n    if (isTemplate(node))\n      fn(node)\n    forEach(subTemplates, fn);\n  }\n\n  function bootstrapTemplatesRecursivelyFrom(node) {\n    function bootstrap(template) {\n      if (!HTMLTemplateElement.decorate(template))\n        bootstrapTemplatesRecursivelyFrom(template.content);\n    }\n\n    forAllTemplatesFrom(node, bootstrap);\n  }\n\n  if (!hasTemplateElement) {\n    /**\n     * This represents a <template> element.\n     * @constructor\n     * @extends {HTMLElement}\n     */\n    global.HTMLTemplateElement = function() {\n      throw TypeError('Illegal constructor');\n    };\n  }\n\n  var hasProto = '__proto__' in {};\n\n  function mixin(to, from) {\n    Object.getOwnPropertyNames(from).forEach(function(name) {\n      Object.defineProperty(to, name,\n                            Object.getOwnPropertyDescriptor(from, name));\n    });\n  }\n\n  // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-owner\n  function getOrCreateTemplateContentsOwner(template) {\n    var doc = template.ownerDocument\n    if (!doc.defaultView)\n      return doc;\n    var d = doc.templateContentsOwner_;\n    if (!d) {\n      // TODO(arv): This should either be a Document or HTMLDocument depending\n      // on doc.\n      d = doc.implementation.createHTMLDocument('');\n      while (d.lastChild) {\n        d.removeChild(d.lastChild);\n      }\n      doc.templateContentsOwner_ = d;\n    }\n    return d;\n  }\n\n  function getTemplateStagingDocument(template) {\n    if (!template.stagingDocument_) {\n      var owner = template.ownerDocument;\n      if (!owner.stagingDocument_) {\n        owner.stagingDocument_ = owner.implementation.createHTMLDocument('');\n\n        // TODO(rafaelw): Remove when fix for\n        // https://codereview.chromium.org/164803002/\n        // makes it to Chrome release.\n        var base = owner.stagingDocument_.createElement('base');\n        base.href = document.baseURI;\n        owner.stagingDocument_.head.appendChild(base);\n\n        owner.stagingDocument_.stagingDocument_ = owner.stagingDocument_;\n      }\n\n      template.stagingDocument_ = owner.stagingDocument_;\n    }\n\n    return template.stagingDocument_;\n  }\n\n  // For non-template browsers, the parser will disallow <template> in certain\n  // locations, so we allow \"attribute templates\" which combine the template\n  // element with the top-level container node of the content, e.g.\n  //\n  //   <tr template repeat=\"{{ foo }}\"\" class=\"bar\"><td>Bar</td></tr>\n  //\n  // becomes\n  //\n  //   <template repeat=\"{{ foo }}\">\n  //   + #document-fragment\n  //     + <tr class=\"bar\">\n  //       + <td>Bar</td>\n  //\n  function extractTemplateFromAttributeTemplate(el) {\n    var template = el.ownerDocument.createElement('template');\n    el.parentNode.insertBefore(template, el);\n\n    var attribs = el.attributes;\n    var count = attribs.length;\n    while (count-- > 0) {\n      var attrib = attribs[count];\n      if (templateAttributeDirectives[attrib.name]) {\n        if (attrib.name !== 'template')\n          template.setAttribute(attrib.name, attrib.value);\n        el.removeAttribute(attrib.name);\n      }\n    }\n\n    return template;\n  }\n\n  function extractTemplateFromSVGTemplate(el) {\n    var template = el.ownerDocument.createElement('template');\n    el.parentNode.insertBefore(template, el);\n\n    var attribs = el.attributes;\n    var count = attribs.length;\n    while (count-- > 0) {\n      var attrib = attribs[count];\n      template.setAttribute(attrib.name, attrib.value);\n      el.removeAttribute(attrib.name);\n    }\n\n    el.parentNode.removeChild(el);\n    return template;\n  }\n\n  function liftNonNativeTemplateChildrenIntoContent(template, el, useRoot) {\n    var content = template.content;\n    if (useRoot) {\n      content.appendChild(el);\n      return;\n    }\n\n    var child;\n    while (child = el.firstChild) {\n      content.appendChild(child);\n    }\n  }\n\n  var templateObserver;\n  if (typeof MutationObserver == 'function') {\n    templateObserver = new MutationObserver(function(records) {\n      for (var i = 0; i < records.length; i++) {\n        records[i].target.refChanged_();\n      }\n    });\n  }\n\n  /**\n   * Ensures proper API and content model for template elements.\n   * @param {HTMLTemplateElement} opt_instanceRef The template element which\n   *     |el| template element will return as the value of its ref(), and whose\n   *     content will be used as source when createInstance() is invoked.\n   */\n  HTMLTemplateElement.decorate = function(el, opt_instanceRef) {\n    if (el.templateIsDecorated_)\n      return false;\n\n    var templateElement = el;\n    templateElement.templateIsDecorated_ = true;\n\n    var isNativeHTMLTemplate = isHTMLTemplate(templateElement) &&\n                               hasTemplateElement;\n    var bootstrapContents = isNativeHTMLTemplate;\n    var liftContents = !isNativeHTMLTemplate;\n    var liftRoot = false;\n\n    if (!isNativeHTMLTemplate) {\n      if (isAttributeTemplate(templateElement)) {\n        assert(!opt_instanceRef);\n        templateElement = extractTemplateFromAttributeTemplate(el);\n        templateElement.templateIsDecorated_ = true;\n        isNativeHTMLTemplate = hasTemplateElement;\n        liftRoot = true;\n      } else if (isSVGTemplate(templateElement)) {\n        templateElement = extractTemplateFromSVGTemplate(el);\n        templateElement.templateIsDecorated_ = true;\n        isNativeHTMLTemplate = hasTemplateElement;\n      }\n    }\n\n    if (!isNativeHTMLTemplate) {\n      fixTemplateElementPrototype(templateElement);\n      var doc = getOrCreateTemplateContentsOwner(templateElement);\n      templateElement.content_ = doc.createDocumentFragment();\n    }\n\n    if (opt_instanceRef) {\n      // template is contained within an instance, its direct content must be\n      // empty\n      templateElement.instanceRef_ = opt_instanceRef;\n    } else if (liftContents) {\n      liftNonNativeTemplateChildrenIntoContent(templateElement,\n                                               el,\n                                               liftRoot);\n    } else if (bootstrapContents) {\n      bootstrapTemplatesRecursivelyFrom(templateElement.content);\n    }\n\n    return true;\n  };\n\n  // TODO(rafaelw): This used to decorate recursively all templates from a given\n  // node. This happens by default on 'DOMContentLoaded', but may be needed\n  // in subtrees not descendent from document (e.g. ShadowRoot).\n  // Review whether this is the right public API.\n  HTMLTemplateElement.bootstrap = bootstrapTemplatesRecursivelyFrom;\n\n  var htmlElement = global.HTMLUnknownElement || HTMLElement;\n\n  var contentDescriptor = {\n    get: function() {\n      return this.content_;\n    },\n    enumerable: true,\n    configurable: true\n  };\n\n  if (!hasTemplateElement) {\n    // Gecko is more picky with the prototype than WebKit. Make sure to use the\n    // same prototype as created in the constructor.\n    HTMLTemplateElement.prototype = Object.create(htmlElement.prototype);\n\n    Object.defineProperty(HTMLTemplateElement.prototype, 'content',\n                          contentDescriptor);\n  }\n\n  function fixTemplateElementPrototype(el) {\n    if (hasProto)\n      el.__proto__ = HTMLTemplateElement.prototype;\n    else\n      mixin(el, HTMLTemplateElement.prototype);\n  }\n\n  function ensureSetModelScheduled(template) {\n    if (!template.setModelFn_) {\n      template.setModelFn_ = function() {\n        template.setModelFnScheduled_ = false;\n        var map = getBindings(template,\n            template.delegate_ && template.delegate_.prepareBinding);\n        processBindings(template, map, template.model_);\n      };\n    }\n\n    if (!template.setModelFnScheduled_) {\n      template.setModelFnScheduled_ = true;\n      Observer.runEOM_(template.setModelFn_);\n    }\n  }\n\n  mixin(HTMLTemplateElement.prototype, {\n    bind: function(name, value, oneTime) {\n      if (name != 'ref')\n        return Element.prototype.bind.call(this, name, value, oneTime);\n\n      var self = this;\n      var ref = oneTime ? value : value.open(function(ref) {\n        self.setAttribute('ref', ref);\n        self.refChanged_();\n      });\n\n      this.setAttribute('ref', ref);\n      this.refChanged_();\n      if (oneTime)\n        return;\n\n      this.unbind('ref');\n      return this.bindings.ref = value;\n    },\n\n    processBindingDirectives_: function(directives) {\n      if (this.iterator_)\n        this.iterator_.closeDeps();\n\n      if (!directives.if && !directives.bind && !directives.repeat) {\n        if (this.iterator_) {\n          this.iterator_.close();\n          this.iterator_ = undefined;\n          this.bindings.iterator = undefined;\n        }\n\n        return;\n      }\n\n      if (!this.iterator_) {\n        this.iterator_ = new TemplateIterator(this);\n        this.bindings = this.bindings || {};\n        this.bindings.iterator = this.iterator_;\n      }\n\n      this.iterator_.updateDependencies(directives, this.model_);\n\n      if (templateObserver) {\n        templateObserver.observe(this, { attributes: true,\n                                         attributeFilter: ['ref'] });\n      }\n\n      return this.iterator_;\n    },\n\n    createInstance: function(model, bindingDelegate, delegate_,\n                             instanceBindings_) {\n      if (bindingDelegate)\n        delegate_ = this.newDelegate_(bindingDelegate);\n\n      if (!this.refContent_)\n        this.refContent_ = this.ref_.content;\n      var content = this.refContent_;\n      var map = this.bindingMap_;\n      if (!map || map.content !== content) {\n        // TODO(rafaelw): Setup a MutationObserver on content to detect\n        // when the instanceMap is invalid.\n        map = createInstanceBindingMap(content,\n            delegate_ && delegate_.prepareBinding) || [];\n        map.content = content;\n        this.bindingMap_ = map;\n      }\n\n      var stagingDocument = getTemplateStagingDocument(this);\n      var instance = stagingDocument.createDocumentFragment();\n      instance.templateCreator_ = this;\n      instance.protoContent_ = content;\n\n      var instanceRecord = {\n        firstNode: null,\n        lastNode: null,\n        model: model\n      };\n\n      var i = 0;\n      for (var child = content.firstChild; child; child = child.nextSibling) {\n        var clone = cloneAndBindInstance(child, instance, stagingDocument,\n                                         map.children[i++],\n                                         model,\n                                         delegate_,\n                                         instanceBindings_);\n        clone.templateInstance_ = instanceRecord;\n      }\n\n      instanceRecord.firstNode = instance.firstChild;\n      instanceRecord.lastNode = instance.lastChild;\n      instance.templateCreator_ = undefined;\n      instance.protoContent_ = undefined;\n      return instance;\n    },\n\n    get model() {\n      return this.model_;\n    },\n\n    set model(model) {\n      this.model_ = model;\n      ensureSetModelScheduled(this);\n    },\n\n    get bindingDelegate() {\n      return this.delegate_ && this.delegate_.raw;\n    },\n\n    refChanged_: function() {\n      if (!this.iterator_ || this.refContent_ === this.ref_.content)\n        return;\n\n      this.refContent_ = undefined;\n      this.iterator_.valueChanged();\n      this.iterator_.updateIteratedValue();\n    },\n\n    clear: function() {\n      this.model_ = undefined;\n      this.delegate_ = undefined;\n      this.bindings_ = undefined;\n      this.refContent_ = undefined;\n      if (!this.iterator_)\n        return;\n      this.iterator_.valueChanged();\n      this.iterator_.close()\n      this.iterator_ = undefined;\n    },\n\n    setDelegate_: function(delegate) {\n      this.delegate_ = delegate;\n      this.bindingMap_ = undefined;\n      if (this.iterator_) {\n        this.iterator_.instancePositionChangedFn_ = undefined;\n        this.iterator_.instanceModelFn_ = undefined;\n      }\n    },\n\n    newDelegate_: function(bindingDelegate) {\n      if (!bindingDelegate)\n        return {};\n\n      function delegateFn(name) {\n        var fn = bindingDelegate && bindingDelegate[name];\n        if (typeof fn != 'function')\n          return;\n\n        return function() {\n          return fn.apply(bindingDelegate, arguments);\n        };\n      }\n\n      return {\n        raw: bindingDelegate,\n        prepareBinding: delegateFn('prepareBinding'),\n        prepareInstanceModel: delegateFn('prepareInstanceModel'),\n        prepareInstancePositionChanged:\n            delegateFn('prepareInstancePositionChanged')\n      };\n    },\n\n    // TODO(rafaelw): Assigning .bindingDelegate always succeeds. It may\n    // make sense to issue a warning or even throw if the template is already\n    // \"activated\", since this would be a strange thing to do.\n    set bindingDelegate(bindingDelegate) {\n      if (this.delegate_) {\n        throw Error('Template must be cleared before a new bindingDelegate ' +\n                    'can be assigned');\n      }\n\n      this.setDelegate_(this.newDelegate_(bindingDelegate));\n    },\n\n    get ref_() {\n      var ref = searchRefId(this, this.getAttribute('ref'));\n      if (!ref)\n        ref = this.instanceRef_;\n\n      if (!ref)\n        return this;\n\n      var nextRef = ref.ref_;\n      return nextRef ? nextRef : ref;\n    }\n  });\n\n  // Returns\n  //   a) undefined if there are no mustaches.\n  //   b) [TEXT, (ONE_TIME?, PATH, DELEGATE_FN, TEXT)+] if there is at least one mustache.\n  function parseMustaches(s, name, node, prepareBindingFn) {\n    if (!s || !s.length)\n      return;\n\n    var tokens;\n    var length = s.length;\n    var startIndex = 0, lastIndex = 0, endIndex = 0;\n    var onlyOneTime = true;\n    while (lastIndex < length) {\n      var startIndex = s.indexOf('{{', lastIndex);\n      var oneTimeStart = s.indexOf('[[', lastIndex);\n      var oneTime = false;\n      var terminator = '}}';\n\n      if (oneTimeStart >= 0 &&\n          (startIndex < 0 || oneTimeStart < startIndex)) {\n        startIndex = oneTimeStart;\n        oneTime = true;\n        terminator = ']]';\n      }\n\n      endIndex = startIndex < 0 ? -1 : s.indexOf(terminator, startIndex + 2);\n\n      if (endIndex < 0) {\n        if (!tokens)\n          return;\n\n        tokens.push(s.slice(lastIndex)); // TEXT\n        break;\n      }\n\n      tokens = tokens || [];\n      tokens.push(s.slice(lastIndex, startIndex)); // TEXT\n      var pathString = s.slice(startIndex + 2, endIndex).trim();\n      tokens.push(oneTime); // ONE_TIME?\n      onlyOneTime = onlyOneTime && oneTime;\n      tokens.push(Path.get(pathString)); // PATH\n      var delegateFn = prepareBindingFn &&\n                       prepareBindingFn(pathString, name, node);\n      tokens.push(delegateFn); // DELEGATE_FN\n      lastIndex = endIndex + 2;\n    }\n\n    if (lastIndex === length)\n      tokens.push(''); // TEXT\n\n    tokens.hasOnePath = tokens.length === 5;\n    tokens.isSimplePath = tokens.hasOnePath &&\n                          tokens[0] == '' &&\n                          tokens[4] == '';\n    tokens.onlyOneTime = onlyOneTime;\n\n    tokens.combinator = function(values) {\n      var newValue = tokens[0];\n\n      for (var i = 1; i < tokens.length; i += 4) {\n        var value = tokens.hasOnePath ? values : values[(i - 1) / 4];\n        if (value !== undefined)\n          newValue += value;\n        newValue += tokens[i + 3];\n      }\n\n      return newValue;\n    }\n\n    return tokens;\n  };\n\n  function processOneTimeBinding(name, tokens, node, model) {\n    if (tokens.hasOnePath) {\n      var delegateFn = tokens[3];\n      var value = delegateFn ? delegateFn(model, node, true) :\n                               tokens[2].getValueFrom(model);\n      return tokens.isSimplePath ? value : tokens.combinator(value);\n    }\n\n    var values = [];\n    for (var i = 1; i < tokens.length; i += 4) {\n      var delegateFn = tokens[i + 2];\n      values[(i - 1) / 4] = delegateFn ? delegateFn(model, node) :\n          tokens[i + 1].getValueFrom(model);\n    }\n\n    return tokens.combinator(values);\n  }\n\n  function processSinglePathBinding(name, tokens, node, model) {\n    var delegateFn = tokens[3];\n    var observer = delegateFn ? delegateFn(model, node, false) :\n        new PathObserver(model, tokens[2]);\n\n    return tokens.isSimplePath ? observer :\n        new ObserverTransform(observer, tokens.combinator);\n  }\n\n  function processBinding(name, tokens, node, model) {\n    if (tokens.onlyOneTime)\n      return processOneTimeBinding(name, tokens, node, model);\n\n    if (tokens.hasOnePath)\n      return processSinglePathBinding(name, tokens, node, model);\n\n    var observer = new CompoundObserver();\n\n    for (var i = 1; i < tokens.length; i += 4) {\n      var oneTime = tokens[i];\n      var delegateFn = tokens[i + 2];\n\n      if (delegateFn) {\n        var value = delegateFn(model, node, oneTime);\n        if (oneTime)\n          observer.addPath(value)\n        else\n          observer.addObserver(value);\n        continue;\n      }\n\n      var path = tokens[i + 1];\n      if (oneTime)\n        observer.addPath(path.getValueFrom(model))\n      else\n        observer.addPath(model, path);\n    }\n\n    return new ObserverTransform(observer, tokens.combinator);\n  }\n\n  function processBindings(node, bindings, model, instanceBindings) {\n    for (var i = 0; i < bindings.length; i += 2) {\n      var name = bindings[i]\n      var tokens = bindings[i + 1];\n      var value = processBinding(name, tokens, node, model);\n      var binding = node.bind(name, value, tokens.onlyOneTime);\n      if (binding && instanceBindings)\n        instanceBindings.push(binding);\n    }\n\n    if (!bindings.isTemplate)\n      return;\n\n    node.model_ = model;\n    var iter = node.processBindingDirectives_(bindings);\n    if (instanceBindings && iter)\n      instanceBindings.push(iter);\n  }\n\n  function parseWithDefault(el, name, prepareBindingFn) {\n    var v = el.getAttribute(name);\n    return parseMustaches(v == '' ? '{{}}' : v, name, el, prepareBindingFn);\n  }\n\n  function parseAttributeBindings(element, prepareBindingFn) {\n    assert(element);\n\n    var bindings = [];\n    var ifFound = false;\n    var bindFound = false;\n\n    for (var i = 0; i < element.attributes.length; i++) {\n      var attr = element.attributes[i];\n      var name = attr.name;\n      var value = attr.value;\n\n      // Allow bindings expressed in attributes to be prefixed with underbars.\n      // We do this to allow correct semantics for browsers that don't implement\n      // <template> where certain attributes might trigger side-effects -- and\n      // for IE which sanitizes certain attributes, disallowing mustache\n      // replacements in their text.\n      while (name[0] === '_') {\n        name = name.substring(1);\n      }\n\n      if (isTemplate(element) &&\n          (name === IF || name === BIND || name === REPEAT)) {\n        continue;\n      }\n\n      var tokens = parseMustaches(value, name, element,\n                                  prepareBindingFn);\n      if (!tokens)\n        continue;\n\n      bindings.push(name, tokens);\n    }\n\n    if (isTemplate(element)) {\n      bindings.isTemplate = true;\n      bindings.if = parseWithDefault(element, IF, prepareBindingFn);\n      bindings.bind = parseWithDefault(element, BIND, prepareBindingFn);\n      bindings.repeat = parseWithDefault(element, REPEAT, prepareBindingFn);\n\n      if (bindings.if && !bindings.bind && !bindings.repeat)\n        bindings.bind = parseMustaches('{{}}', BIND, element, prepareBindingFn);\n    }\n\n    return bindings;\n  }\n\n  function getBindings(node, prepareBindingFn) {\n    if (node.nodeType === Node.ELEMENT_NODE)\n      return parseAttributeBindings(node, prepareBindingFn);\n\n    if (node.nodeType === Node.TEXT_NODE) {\n      var tokens = parseMustaches(node.data, 'textContent', node,\n                                  prepareBindingFn);\n      if (tokens)\n        return ['textContent', tokens];\n    }\n\n    return [];\n  }\n\n  function cloneAndBindInstance(node, parent, stagingDocument, bindings, model,\n                                delegate,\n                                instanceBindings,\n                                instanceRecord) {\n    var clone = parent.appendChild(stagingDocument.importNode(node, false));\n\n    var i = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      cloneAndBindInstance(child, clone, stagingDocument,\n                            bindings.children[i++],\n                            model,\n                            delegate,\n                            instanceBindings);\n    }\n\n    if (bindings.isTemplate) {\n      HTMLTemplateElement.decorate(clone, node);\n      if (delegate)\n        clone.setDelegate_(delegate);\n    }\n\n    processBindings(clone, bindings, model, instanceBindings);\n    return clone;\n  }\n\n  function createInstanceBindingMap(node, prepareBindingFn) {\n    var map = getBindings(node, prepareBindingFn);\n    map.children = {};\n    var index = 0;\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      map.children[index++] = createInstanceBindingMap(child, prepareBindingFn);\n    }\n\n    return map;\n  }\n\n  Object.defineProperty(Node.prototype, 'templateInstance', {\n    get: function() {\n      var instance = this.templateInstance_;\n      return instance ? instance :\n          (this.parentNode ? this.parentNode.templateInstance : undefined);\n    }\n  });\n\n  function TemplateIterator(templateElement) {\n    this.closed = false;\n    this.templateElement_ = templateElement;\n\n    // Flattened array of tuples:\n    //   <instanceTerminatorNode, [bindingsSetupByInstance]>\n    this.terminators = [];\n\n    this.deps = undefined;\n    this.iteratedValue = [];\n    this.presentValue = undefined;\n    this.arrayObserver = undefined;\n  }\n\n  TemplateIterator.prototype = {\n    closeDeps: function() {\n      var deps = this.deps;\n      if (deps) {\n        if (deps.ifOneTime === false)\n          deps.ifValue.close();\n        if (deps.oneTime === false)\n          deps.value.close();\n      }\n    },\n\n    updateDependencies: function(directives, model) {\n      this.closeDeps();\n\n      var deps = this.deps = {};\n      var template = this.templateElement_;\n\n      if (directives.if) {\n        deps.hasIf = true;\n        deps.ifOneTime = directives.if.onlyOneTime;\n        deps.ifValue = processBinding(IF, directives.if, template, model);\n\n        // oneTime if & predicate is false. nothing else to do.\n        if (deps.ifOneTime && !deps.ifValue) {\n          this.updateIteratedValue();\n          return;\n        }\n\n        if (!deps.ifOneTime)\n          deps.ifValue.open(this.updateIteratedValue, this);\n      }\n\n      if (directives.repeat) {\n        deps.repeat = true;\n        deps.oneTime = directives.repeat.onlyOneTime;\n        deps.value = processBinding(REPEAT, directives.repeat, template, model);\n      } else {\n        deps.repeat = false;\n        deps.oneTime = directives.bind.onlyOneTime;\n        deps.value = processBinding(BIND, directives.bind, template, model);\n      }\n\n      if (!deps.oneTime)\n        deps.value.open(this.updateIteratedValue, this);\n\n      this.updateIteratedValue();\n    },\n\n    updateIteratedValue: function() {\n      if (this.deps.hasIf) {\n        var ifValue = this.deps.ifValue;\n        if (!this.deps.ifOneTime)\n          ifValue = ifValue.discardChanges();\n        if (!ifValue) {\n          this.valueChanged();\n          return;\n        }\n      }\n\n      var value = this.deps.value;\n      if (!this.deps.oneTime)\n        value = value.discardChanges();\n      if (!this.deps.repeat)\n        value = [value];\n      var observe = this.deps.repeat &&\n                    !this.deps.oneTime &&\n                    Array.isArray(value);\n      this.valueChanged(value, observe);\n    },\n\n    valueChanged: function(value, observeValue) {\n      if (!Array.isArray(value))\n        value = [];\n\n      if (value === this.iteratedValue)\n        return;\n\n      this.unobserve();\n      this.presentValue = value;\n      if (observeValue) {\n        this.arrayObserver = new ArrayObserver(this.presentValue);\n        this.arrayObserver.open(this.handleSplices, this);\n      }\n\n      this.handleSplices(ArrayObserver.calculateSplices(this.presentValue,\n                                                        this.iteratedValue));\n    },\n\n    getTerminatorAt: function(index) {\n      if (index == -1)\n        return this.templateElement_;\n      var terminator = this.terminators[index*2];\n      if (terminator.nodeType !== Node.ELEMENT_NODE ||\n          this.templateElement_ === terminator) {\n        return terminator;\n      }\n\n      var subIterator = terminator.iterator_;\n      if (!subIterator)\n        return terminator;\n\n      return subIterator.getTerminatorAt(subIterator.terminators.length/2 - 1);\n    },\n\n    // TODO(rafaelw): If we inserting sequences of instances we can probably\n    // avoid lots of calls to getTerminatorAt(), or cache its result.\n    insertInstanceAt: function(index, fragment, instanceNodes,\n                               instanceBindings) {\n      var previousTerminator = this.getTerminatorAt(index - 1);\n      var terminator = previousTerminator;\n      if (fragment)\n        terminator = fragment.lastChild || terminator;\n      else if (instanceNodes)\n        terminator = instanceNodes[instanceNodes.length - 1] || terminator;\n\n      this.terminators.splice(index*2, 0, terminator, instanceBindings);\n      var parent = this.templateElement_.parentNode;\n      var insertBeforeNode = previousTerminator.nextSibling;\n\n      if (fragment) {\n        parent.insertBefore(fragment, insertBeforeNode);\n      } else if (instanceNodes) {\n        for (var i = 0; i < instanceNodes.length; i++)\n          parent.insertBefore(instanceNodes[i], insertBeforeNode);\n      }\n    },\n\n    extractInstanceAt: function(index) {\n      var instanceNodes = [];\n      var previousTerminator = this.getTerminatorAt(index - 1);\n      var terminator = this.getTerminatorAt(index);\n      instanceNodes.instanceBindings = this.terminators[index*2 + 1];\n      this.terminators.splice(index*2, 2);\n\n      var parent = this.templateElement_.parentNode;\n      while (terminator !== previousTerminator) {\n        var node = previousTerminator.nextSibling;\n        if (node == terminator)\n          terminator = previousTerminator;\n\n        parent.removeChild(node);\n        instanceNodes.push(node);\n      }\n\n      return instanceNodes;\n    },\n\n    getDelegateFn: function(fn) {\n      fn = fn && fn(this.templateElement_);\n      return typeof fn === 'function' ? fn : null;\n    },\n\n    handleSplices: function(splices) {\n      if (this.closed || !splices.length)\n        return;\n\n      var template = this.templateElement_;\n\n      if (!template.parentNode) {\n        this.close();\n        return;\n      }\n\n      ArrayObserver.applySplices(this.iteratedValue, this.presentValue,\n                                 splices);\n\n      var delegate = template.delegate_;\n      if (this.instanceModelFn_ === undefined) {\n        this.instanceModelFn_ =\n            this.getDelegateFn(delegate && delegate.prepareInstanceModel);\n      }\n\n      if (this.instancePositionChangedFn_ === undefined) {\n        this.instancePositionChangedFn_ =\n            this.getDelegateFn(delegate &&\n                               delegate.prepareInstancePositionChanged);\n      }\n\n      var instanceCache = new Map;\n      var removeDelta = 0;\n      splices.forEach(function(splice) {\n        splice.removed.forEach(function(model) {\n          var instanceNodes =\n              this.extractInstanceAt(splice.index + removeDelta);\n          instanceCache.set(model, instanceNodes);\n        }, this);\n\n        removeDelta -= splice.addedCount;\n      }, this);\n\n      splices.forEach(function(splice) {\n        var addIndex = splice.index;\n        for (; addIndex < splice.index + splice.addedCount; addIndex++) {\n          var model = this.iteratedValue[addIndex];\n          var fragment = undefined;\n          var instanceNodes = instanceCache.get(model);\n          var instanceBindings;\n          if (instanceNodes) {\n            instanceCache.delete(model);\n            instanceBindings = instanceNodes.instanceBindings;\n          } else {\n            instanceBindings = [];\n            if (this.instanceModelFn_)\n              model = this.instanceModelFn_(model);\n\n            if (model !== undefined) {\n              fragment = template.createInstance(model, undefined, delegate,\n                                                 instanceBindings);\n            }\n          }\n\n          this.insertInstanceAt(addIndex, fragment, instanceNodes,\n                                instanceBindings);\n        }\n      }, this);\n\n      instanceCache.forEach(function(instanceNodes) {\n        this.closeInstanceBindings(instanceNodes.instanceBindings);\n      }, this);\n\n      if (this.instancePositionChangedFn_)\n        this.reportInstancesMoved(splices);\n    },\n\n    reportInstanceMoved: function(index) {\n      var previousTerminator = this.getTerminatorAt(index - 1);\n      var terminator = this.getTerminatorAt(index);\n      if (previousTerminator === terminator)\n        return; // instance has zero nodes.\n\n      // We must use the first node of the instance, because any subsequent\n      // nodes may have been generated by sub-templates.\n      // TODO(rafaelw): This is brittle WRT instance mutation -- e.g. if the\n      // first node was removed by script.\n      var templateInstance = previousTerminator.nextSibling.templateInstance;\n      this.instancePositionChangedFn_(templateInstance, index);\n    },\n\n    reportInstancesMoved: function(splices) {\n      var index = 0;\n      var offset = 0;\n      for (var i = 0; i < splices.length; i++) {\n        var splice = splices[i];\n        if (offset != 0) {\n          while (index < splice.index) {\n            this.reportInstanceMoved(index);\n            index++;\n          }\n        } else {\n          index = splice.index;\n        }\n\n        while (index < splice.index + splice.addedCount) {\n          this.reportInstanceMoved(index);\n          index++;\n        }\n\n        offset += splice.addedCount - splice.removed.length;\n      }\n\n      if (offset == 0)\n        return;\n\n      var length = this.terminators.length / 2;\n      while (index < length) {\n        this.reportInstanceMoved(index);\n        index++;\n      }\n    },\n\n    closeInstanceBindings: function(instanceBindings) {\n      for (var i = 0; i < instanceBindings.length; i++) {\n        instanceBindings[i].close();\n      }\n    },\n\n    unobserve: function() {\n      if (!this.arrayObserver)\n        return;\n\n      this.arrayObserver.close();\n      this.arrayObserver = undefined;\n    },\n\n    close: function() {\n      if (this.closed)\n        return;\n      this.unobserve();\n      for (var i = 1; i < this.terminators.length; i += 2) {\n        this.closeInstanceBindings(this.terminators[i]);\n      }\n\n      this.terminators.length = 0;\n      this.closeDeps();\n      this.templateElement_.iterator_ = undefined;\n      this.closed = true;\n    }\n  };\n\n  // Polyfill-specific API.\n  HTMLTemplateElement.forAllTemplatesFrom_ = forAllTemplatesFrom;\n})(this);\n","/*\n  Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>\n  Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>\n  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>\n  Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>\n  Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>\n  Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>\n  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>\n  Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>\n  Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n(function (global) {\n    'use strict';\n\n    var Token,\n        TokenName,\n        Syntax,\n        Messages,\n        source,\n        index,\n        length,\n        delegate,\n        lookahead,\n        state;\n\n    Token = {\n        BooleanLiteral: 1,\n        EOF: 2,\n        Identifier: 3,\n        Keyword: 4,\n        NullLiteral: 5,\n        NumericLiteral: 6,\n        Punctuator: 7,\n        StringLiteral: 8\n    };\n\n    TokenName = {};\n    TokenName[Token.BooleanLiteral] = 'Boolean';\n    TokenName[Token.EOF] = '<end>';\n    TokenName[Token.Identifier] = 'Identifier';\n    TokenName[Token.Keyword] = 'Keyword';\n    TokenName[Token.NullLiteral] = 'Null';\n    TokenName[Token.NumericLiteral] = 'Numeric';\n    TokenName[Token.Punctuator] = 'Punctuator';\n    TokenName[Token.StringLiteral] = 'String';\n\n    Syntax = {\n        ArrayExpression: 'ArrayExpression',\n        BinaryExpression: 'BinaryExpression',\n        CallExpression: 'CallExpression',\n        ConditionalExpression: 'ConditionalExpression',\n        EmptyStatement: 'EmptyStatement',\n        ExpressionStatement: 'ExpressionStatement',\n        Identifier: 'Identifier',\n        Literal: 'Literal',\n        LabeledStatement: 'LabeledStatement',\n        LogicalExpression: 'LogicalExpression',\n        MemberExpression: 'MemberExpression',\n        ObjectExpression: 'ObjectExpression',\n        Program: 'Program',\n        Property: 'Property',\n        ThisExpression: 'ThisExpression',\n        UnaryExpression: 'UnaryExpression'\n    };\n\n    // Error messages should be identical to V8.\n    Messages = {\n        UnexpectedToken:  'Unexpected token %0',\n        UnknownLabel: 'Undefined label \\'%0\\'',\n        Redeclaration: '%0 \\'%1\\' has already been declared'\n    };\n\n    // Ensure the condition is true, otherwise throw an error.\n    // This is only to have a better contract semantic, i.e. another safety net\n    // to catch a logic error. The condition shall be fulfilled in normal case.\n    // Do NOT use this to enforce a certain condition on any user input.\n\n    function assert(condition, message) {\n        if (!condition) {\n            throw new Error('ASSERT: ' + message);\n        }\n    }\n\n    function isDecimalDigit(ch) {\n        return (ch >= 48 && ch <= 57);   // 0..9\n    }\n\n\n    // 7.2 White Space\n\n    function isWhiteSpace(ch) {\n        return (ch === 32) ||  // space\n            (ch === 9) ||      // tab\n            (ch === 0xB) ||\n            (ch === 0xC) ||\n            (ch === 0xA0) ||\n            (ch >= 0x1680 && '\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\uFEFF'.indexOf(String.fromCharCode(ch)) > 0);\n    }\n\n    // 7.3 Line Terminators\n\n    function isLineTerminator(ch) {\n        return (ch === 10) || (ch === 13) || (ch === 0x2028) || (ch === 0x2029);\n    }\n\n    // 7.6 Identifier Names and Identifiers\n\n    function isIdentifierStart(ch) {\n        return (ch === 36) || (ch === 95) ||  // $ (dollar) and _ (underscore)\n            (ch >= 65 && ch <= 90) ||         // A..Z\n            (ch >= 97 && ch <= 122);          // a..z\n    }\n\n    function isIdentifierPart(ch) {\n        return (ch === 36) || (ch === 95) ||  // $ (dollar) and _ (underscore)\n            (ch >= 65 && ch <= 90) ||         // A..Z\n            (ch >= 97 && ch <= 122) ||        // a..z\n            (ch >= 48 && ch <= 57);           // 0..9\n    }\n\n    // 7.6.1.1 Keywords\n\n    function isKeyword(id) {\n        return (id === 'this')\n    }\n\n    // 7.4 Comments\n\n    function skipWhitespace() {\n        while (index < length && isWhiteSpace(source.charCodeAt(index))) {\n           ++index;\n        }\n    }\n\n    function getIdentifier() {\n        var start, ch;\n\n        start = index++;\n        while (index < length) {\n            ch = source.charCodeAt(index);\n            if (isIdentifierPart(ch)) {\n                ++index;\n            } else {\n                break;\n            }\n        }\n\n        return source.slice(start, index);\n    }\n\n    function scanIdentifier() {\n        var start, id, type;\n\n        start = index;\n\n        id = getIdentifier();\n\n        // There is no keyword or literal with only one character.\n        // Thus, it must be an identifier.\n        if (id.length === 1) {\n            type = Token.Identifier;\n        } else if (isKeyword(id)) {\n            type = Token.Keyword;\n        } else if (id === 'null') {\n            type = Token.NullLiteral;\n        } else if (id === 'true' || id === 'false') {\n            type = Token.BooleanLiteral;\n        } else {\n            type = Token.Identifier;\n        }\n\n        return {\n            type: type,\n            value: id,\n            range: [start, index]\n        };\n    }\n\n\n    // 7.7 Punctuators\n\n    function scanPunctuator() {\n        var start = index,\n            code = source.charCodeAt(index),\n            code2,\n            ch1 = source[index],\n            ch2;\n\n        switch (code) {\n\n        // Check for most common single-character punctuators.\n        case 46:   // . dot\n        case 40:   // ( open bracket\n        case 41:   // ) close bracket\n        case 59:   // ; semicolon\n        case 44:   // , comma\n        case 123:  // { open curly brace\n        case 125:  // } close curly brace\n        case 91:   // [\n        case 93:   // ]\n        case 58:   // :\n        case 63:   // ?\n            ++index;\n            return {\n                type: Token.Punctuator,\n                value: String.fromCharCode(code),\n                range: [start, index]\n            };\n\n        default:\n            code2 = source.charCodeAt(index + 1);\n\n            // '=' (char #61) marks an assignment or comparison operator.\n            if (code2 === 61) {\n                switch (code) {\n                case 37:  // %\n                case 38:  // &\n                case 42:  // *:\n                case 43:  // +\n                case 45:  // -\n                case 47:  // /\n                case 60:  // <\n                case 62:  // >\n                case 124: // |\n                    index += 2;\n                    return {\n                        type: Token.Punctuator,\n                        value: String.fromCharCode(code) + String.fromCharCode(code2),\n                        range: [start, index]\n                    };\n\n                case 33: // !\n                case 61: // =\n                    index += 2;\n\n                    // !== and ===\n                    if (source.charCodeAt(index) === 61) {\n                        ++index;\n                    }\n                    return {\n                        type: Token.Punctuator,\n                        value: source.slice(start, index),\n                        range: [start, index]\n                    };\n                default:\n                    break;\n                }\n            }\n            break;\n        }\n\n        // Peek more characters.\n\n        ch2 = source[index + 1];\n\n        // Other 2-character punctuators: && ||\n\n        if (ch1 === ch2 && ('&|'.indexOf(ch1) >= 0)) {\n            index += 2;\n            return {\n                type: Token.Punctuator,\n                value: ch1 + ch2,\n                range: [start, index]\n            };\n        }\n\n        if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {\n            ++index;\n            return {\n                type: Token.Punctuator,\n                value: ch1,\n                range: [start, index]\n            };\n        }\n\n        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n    }\n\n    // 7.8.3 Numeric Literals\n    function scanNumericLiteral() {\n        var number, start, ch;\n\n        ch = source[index];\n        assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),\n            'Numeric literal must start with a decimal digit or a decimal point');\n\n        start = index;\n        number = '';\n        if (ch !== '.') {\n            number = source[index++];\n            ch = source[index];\n\n            // Hex number starts with '0x'.\n            // Octal number starts with '0'.\n            if (number === '0') {\n                // decimal number starts with '0' such as '09' is illegal.\n                if (ch && isDecimalDigit(ch.charCodeAt(0))) {\n                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                }\n            }\n\n            while (isDecimalDigit(source.charCodeAt(index))) {\n                number += source[index++];\n            }\n            ch = source[index];\n        }\n\n        if (ch === '.') {\n            number += source[index++];\n            while (isDecimalDigit(source.charCodeAt(index))) {\n                number += source[index++];\n            }\n            ch = source[index];\n        }\n\n        if (ch === 'e' || ch === 'E') {\n            number += source[index++];\n\n            ch = source[index];\n            if (ch === '+' || ch === '-') {\n                number += source[index++];\n            }\n            if (isDecimalDigit(source.charCodeAt(index))) {\n                while (isDecimalDigit(source.charCodeAt(index))) {\n                    number += source[index++];\n                }\n            } else {\n                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n            }\n        }\n\n        if (isIdentifierStart(source.charCodeAt(index))) {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n\n        return {\n            type: Token.NumericLiteral,\n            value: parseFloat(number),\n            range: [start, index]\n        };\n    }\n\n    // 7.8.4 String Literals\n\n    function scanStringLiteral() {\n        var str = '', quote, start, ch, octal = false;\n\n        quote = source[index];\n        assert((quote === '\\'' || quote === '\"'),\n            'String literal must starts with a quote');\n\n        start = index;\n        ++index;\n\n        while (index < length) {\n            ch = source[index++];\n\n            if (ch === quote) {\n                quote = '';\n                break;\n            } else if (ch === '\\\\') {\n                ch = source[index++];\n                if (!ch || !isLineTerminator(ch.charCodeAt(0))) {\n                    switch (ch) {\n                    case 'n':\n                        str += '\\n';\n                        break;\n                    case 'r':\n                        str += '\\r';\n                        break;\n                    case 't':\n                        str += '\\t';\n                        break;\n                    case 'b':\n                        str += '\\b';\n                        break;\n                    case 'f':\n                        str += '\\f';\n                        break;\n                    case 'v':\n                        str += '\\x0B';\n                        break;\n\n                    default:\n                        str += ch;\n                        break;\n                    }\n                } else {\n                    if (ch ===  '\\r' && source[index] === '\\n') {\n                        ++index;\n                    }\n                }\n            } else if (isLineTerminator(ch.charCodeAt(0))) {\n                break;\n            } else {\n                str += ch;\n            }\n        }\n\n        if (quote !== '') {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n\n        return {\n            type: Token.StringLiteral,\n            value: str,\n            octal: octal,\n            range: [start, index]\n        };\n    }\n\n    function isIdentifierName(token) {\n        return token.type === Token.Identifier ||\n            token.type === Token.Keyword ||\n            token.type === Token.BooleanLiteral ||\n            token.type === Token.NullLiteral;\n    }\n\n    function advance() {\n        var ch;\n\n        skipWhitespace();\n\n        if (index >= length) {\n            return {\n                type: Token.EOF,\n                range: [index, index]\n            };\n        }\n\n        ch = source.charCodeAt(index);\n\n        // Very common: ( and ) and ;\n        if (ch === 40 || ch === 41 || ch === 58) {\n            return scanPunctuator();\n        }\n\n        // String literal starts with single quote (#39) or double quote (#34).\n        if (ch === 39 || ch === 34) {\n            return scanStringLiteral();\n        }\n\n        if (isIdentifierStart(ch)) {\n            return scanIdentifier();\n        }\n\n        // Dot (.) char #46 can also start a floating-point number, hence the need\n        // to check the next character.\n        if (ch === 46) {\n            if (isDecimalDigit(source.charCodeAt(index + 1))) {\n                return scanNumericLiteral();\n            }\n            return scanPunctuator();\n        }\n\n        if (isDecimalDigit(ch)) {\n            return scanNumericLiteral();\n        }\n\n        return scanPunctuator();\n    }\n\n    function lex() {\n        var token;\n\n        token = lookahead;\n        index = token.range[1];\n\n        lookahead = advance();\n\n        index = token.range[1];\n\n        return token;\n    }\n\n    function peek() {\n        var pos;\n\n        pos = index;\n        lookahead = advance();\n        index = pos;\n    }\n\n    // Throw an exception\n\n    function throwError(token, messageFormat) {\n        var error,\n            args = Array.prototype.slice.call(arguments, 2),\n            msg = messageFormat.replace(\n                /%(\\d)/g,\n                function (whole, index) {\n                    assert(index < args.length, 'Message reference must be in range');\n                    return args[index];\n                }\n            );\n\n        error = new Error(msg);\n        error.index = index;\n        error.description = msg;\n        throw error;\n    }\n\n    // Throw an exception because of the token.\n\n    function throwUnexpected(token) {\n        throwError(token, Messages.UnexpectedToken, token.value);\n    }\n\n    // Expect the next token to match the specified punctuator.\n    // If not, an exception will be thrown.\n\n    function expect(value) {\n        var token = lex();\n        if (token.type !== Token.Punctuator || token.value !== value) {\n            throwUnexpected(token);\n        }\n    }\n\n    // Return true if the next token matches the specified punctuator.\n\n    function match(value) {\n        return lookahead.type === Token.Punctuator && lookahead.value === value;\n    }\n\n    // Return true if the next token matches the specified keyword\n\n    function matchKeyword(keyword) {\n        return lookahead.type === Token.Keyword && lookahead.value === keyword;\n    }\n\n    function consumeSemicolon() {\n        // Catch the very common case first: immediately a semicolon (char #59).\n        if (source.charCodeAt(index) === 59) {\n            lex();\n            return;\n        }\n\n        skipWhitespace();\n\n        if (match(';')) {\n            lex();\n            return;\n        }\n\n        if (lookahead.type !== Token.EOF && !match('}')) {\n            throwUnexpected(lookahead);\n        }\n    }\n\n    // 11.1.4 Array Initialiser\n\n    function parseArrayInitialiser() {\n        var elements = [];\n\n        expect('[');\n\n        while (!match(']')) {\n            if (match(',')) {\n                lex();\n                elements.push(null);\n            } else {\n                elements.push(parseExpression());\n\n                if (!match(']')) {\n                    expect(',');\n                }\n            }\n        }\n\n        expect(']');\n\n        return delegate.createArrayExpression(elements);\n    }\n\n    // 11.1.5 Object Initialiser\n\n    function parseObjectPropertyKey() {\n        var token;\n\n        skipWhitespace();\n        token = lex();\n\n        // Note: This function is called only from parseObjectProperty(), where\n        // EOF and Punctuator tokens are already filtered out.\n        if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {\n            return delegate.createLiteral(token);\n        }\n\n        return delegate.createIdentifier(token.value);\n    }\n\n    function parseObjectProperty() {\n        var token, key;\n\n        token = lookahead;\n        skipWhitespace();\n\n        if (token.type === Token.EOF || token.type === Token.Punctuator) {\n            throwUnexpected(token);\n        }\n\n        key = parseObjectPropertyKey();\n        expect(':');\n        return delegate.createProperty('init', key, parseExpression());\n    }\n\n    function parseObjectInitialiser() {\n        var properties = [];\n\n        expect('{');\n\n        while (!match('}')) {\n            properties.push(parseObjectProperty());\n\n            if (!match('}')) {\n                expect(',');\n            }\n        }\n\n        expect('}');\n\n        return delegate.createObjectExpression(properties);\n    }\n\n    // 11.1.6 The Grouping Operator\n\n    function parseGroupExpression() {\n        var expr;\n\n        expect('(');\n\n        expr = parseExpression();\n\n        expect(')');\n\n        return expr;\n    }\n\n\n    // 11.1 Primary Expressions\n\n    function parsePrimaryExpression() {\n        var type, token, expr;\n\n        if (match('(')) {\n            return parseGroupExpression();\n        }\n\n        type = lookahead.type;\n\n        if (type === Token.Identifier) {\n            expr = delegate.createIdentifier(lex().value);\n        } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {\n            expr = delegate.createLiteral(lex());\n        } else if (type === Token.Keyword) {\n            if (matchKeyword('this')) {\n                lex();\n                expr = delegate.createThisExpression();\n            }\n        } else if (type === Token.BooleanLiteral) {\n            token = lex();\n            token.value = (token.value === 'true');\n            expr = delegate.createLiteral(token);\n        } else if (type === Token.NullLiteral) {\n            token = lex();\n            token.value = null;\n            expr = delegate.createLiteral(token);\n        } else if (match('[')) {\n            expr = parseArrayInitialiser();\n        } else if (match('{')) {\n            expr = parseObjectInitialiser();\n        }\n\n        if (expr) {\n            return expr;\n        }\n\n        throwUnexpected(lex());\n    }\n\n    // 11.2 Left-Hand-Side Expressions\n\n    function parseArguments() {\n        var args = [];\n\n        expect('(');\n\n        if (!match(')')) {\n            while (index < length) {\n                args.push(parseExpression());\n                if (match(')')) {\n                    break;\n                }\n                expect(',');\n            }\n        }\n\n        expect(')');\n\n        return args;\n    }\n\n    function parseNonComputedProperty() {\n        var token;\n\n        token = lex();\n\n        if (!isIdentifierName(token)) {\n            throwUnexpected(token);\n        }\n\n        return delegate.createIdentifier(token.value);\n    }\n\n    function parseNonComputedMember() {\n        expect('.');\n\n        return parseNonComputedProperty();\n    }\n\n    function parseComputedMember() {\n        var expr;\n\n        expect('[');\n\n        expr = parseExpression();\n\n        expect(']');\n\n        return expr;\n    }\n\n    function parseLeftHandSideExpression() {\n        var expr, property;\n\n        expr = parsePrimaryExpression();\n\n        while (match('.') || match('[')) {\n            if (match('[')) {\n                property = parseComputedMember();\n                expr = delegate.createMemberExpression('[', expr, property);\n            } else {\n                property = parseNonComputedMember();\n                expr = delegate.createMemberExpression('.', expr, property);\n            }\n        }\n\n        return expr;\n    }\n\n    // 11.3 Postfix Expressions\n\n    var parsePostfixExpression = parseLeftHandSideExpression;\n\n    // 11.4 Unary Operators\n\n    function parseUnaryExpression() {\n        var token, expr;\n\n        if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {\n            expr = parsePostfixExpression();\n        } else if (match('+') || match('-') || match('!')) {\n            token = lex();\n            expr = parseUnaryExpression();\n            expr = delegate.createUnaryExpression(token.value, expr);\n        } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {\n            throwError({}, Messages.UnexpectedToken);\n        } else {\n            expr = parsePostfixExpression();\n        }\n\n        return expr;\n    }\n\n    function binaryPrecedence(token) {\n        var prec = 0;\n\n        if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {\n            return 0;\n        }\n\n        switch (token.value) {\n        case '||':\n            prec = 1;\n            break;\n\n        case '&&':\n            prec = 2;\n            break;\n\n        case '==':\n        case '!=':\n        case '===':\n        case '!==':\n            prec = 6;\n            break;\n\n        case '<':\n        case '>':\n        case '<=':\n        case '>=':\n        case 'instanceof':\n            prec = 7;\n            break;\n\n        case 'in':\n            prec = 7;\n            break;\n\n        case '+':\n        case '-':\n            prec = 9;\n            break;\n\n        case '*':\n        case '/':\n        case '%':\n            prec = 11;\n            break;\n\n        default:\n            break;\n        }\n\n        return prec;\n    }\n\n    // 11.5 Multiplicative Operators\n    // 11.6 Additive Operators\n    // 11.7 Bitwise Shift Operators\n    // 11.8 Relational Operators\n    // 11.9 Equality Operators\n    // 11.10 Binary Bitwise Operators\n    // 11.11 Binary Logical Operators\n\n    function parseBinaryExpression() {\n        var expr, token, prec, stack, right, operator, left, i;\n\n        left = parseUnaryExpression();\n\n        token = lookahead;\n        prec = binaryPrecedence(token);\n        if (prec === 0) {\n            return left;\n        }\n        token.prec = prec;\n        lex();\n\n        right = parseUnaryExpression();\n\n        stack = [left, token, right];\n\n        while ((prec = binaryPrecedence(lookahead)) > 0) {\n\n            // Reduce: make a binary expression from the three topmost entries.\n            while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {\n                right = stack.pop();\n                operator = stack.pop().value;\n                left = stack.pop();\n                expr = delegate.createBinaryExpression(operator, left, right);\n                stack.push(expr);\n            }\n\n            // Shift.\n            token = lex();\n            token.prec = prec;\n            stack.push(token);\n            expr = parseUnaryExpression();\n            stack.push(expr);\n        }\n\n        // Final reduce to clean-up the stack.\n        i = stack.length - 1;\n        expr = stack[i];\n        while (i > 1) {\n            expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);\n            i -= 2;\n        }\n\n        return expr;\n    }\n\n\n    // 11.12 Conditional Operator\n\n    function parseConditionalExpression() {\n        var expr, consequent, alternate;\n\n        expr = parseBinaryExpression();\n\n        if (match('?')) {\n            lex();\n            consequent = parseConditionalExpression();\n            expect(':');\n            alternate = parseConditionalExpression();\n\n            expr = delegate.createConditionalExpression(expr, consequent, alternate);\n        }\n\n        return expr;\n    }\n\n    // Simplification since we do not support AssignmentExpression.\n    var parseExpression = parseConditionalExpression;\n\n    // Polymer Syntax extensions\n\n    // Filter ::\n    //   Identifier\n    //   Identifier \"(\" \")\"\n    //   Identifier \"(\" FilterArguments \")\"\n\n    function parseFilter() {\n        var identifier, args;\n\n        identifier = lex();\n\n        if (identifier.type !== Token.Identifier) {\n            throwUnexpected(identifier);\n        }\n\n        args = match('(') ? parseArguments() : [];\n\n        return delegate.createFilter(identifier.value, args);\n    }\n\n    // Filters ::\n    //   \"|\" Filter\n    //   Filters \"|\" Filter\n\n    function parseFilters() {\n        while (match('|')) {\n            lex();\n            parseFilter();\n        }\n    }\n\n    // TopLevel ::\n    //   LabelledExpressions\n    //   AsExpression\n    //   InExpression\n    //   FilterExpression\n\n    // AsExpression ::\n    //   FilterExpression as Identifier\n\n    // InExpression ::\n    //   Identifier, Identifier in FilterExpression\n    //   Identifier in FilterExpression\n\n    // FilterExpression ::\n    //   Expression\n    //   Expression Filters\n\n    function parseTopLevel() {\n        skipWhitespace();\n        peek();\n\n        var expr = parseExpression();\n        if (expr) {\n            if (lookahead.value === ',' || lookahead.value == 'in' &&\n                       expr.type === Syntax.Identifier) {\n                parseInExpression(expr);\n            } else {\n                parseFilters();\n                if (lookahead.value === 'as') {\n                    parseAsExpression(expr);\n                } else {\n                    delegate.createTopLevel(expr);\n                }\n            }\n        }\n\n        if (lookahead.type !== Token.EOF) {\n            throwUnexpected(lookahead);\n        }\n    }\n\n    function parseAsExpression(expr) {\n        lex();  // as\n        var identifier = lex().value;\n        delegate.createAsExpression(expr, identifier);\n    }\n\n    function parseInExpression(identifier) {\n        var indexName;\n        if (lookahead.value === ',') {\n            lex();\n            if (lookahead.type !== Token.Identifier)\n                throwUnexpected(lookahead);\n            indexName = lex().value;\n        }\n\n        lex();  // in\n        var expr = parseExpression();\n        parseFilters();\n        delegate.createInExpression(identifier.name, indexName, expr);\n    }\n\n    function parse(code, inDelegate) {\n        delegate = inDelegate;\n        source = code;\n        index = 0;\n        length = source.length;\n        lookahead = null;\n        state = {\n            labelSet: {}\n        };\n\n        return parseTopLevel();\n    }\n\n    global.esprima = {\n        parse: parse\n    };\n})(this);\n","// Copyright 2013 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n(function (global) {\n  'use strict';\n\n  // JScript does not have __proto__. We wrap all object literals with\n  // createObject which uses Object.create, Object.defineProperty and\n  // Object.getOwnPropertyDescriptor to create a new object that does the exact\n  // same thing. The main downside to this solution is that we have to extract\n  // all those property descriptors for IE.\n  var createObject = ('__proto__' in {}) ?\n      function(obj) { return obj; } :\n      function(obj) {\n        var proto = obj.__proto__;\n        if (!proto)\n          return obj;\n        var newObject = Object.create(proto);\n        Object.getOwnPropertyNames(obj).forEach(function(name) {\n          Object.defineProperty(newObject, name,\n                               Object.getOwnPropertyDescriptor(obj, name));\n        });\n        return newObject;\n      };\n\n  function prepareBinding(expressionText, name, node, filterRegistry) {\n    var expression;\n    try {\n      expression = getExpression(expressionText);\n      if (expression.scopeIdent &&\n          (node.nodeType !== Node.ELEMENT_NODE ||\n           node.tagName !== 'TEMPLATE' ||\n           (name !== 'bind' && name !== 'repeat'))) {\n        throw Error('as and in can only be used within <template bind/repeat>');\n      }\n    } catch (ex) {\n      console.error('Invalid expression syntax: ' + expressionText, ex);\n      return;\n    }\n\n    return function(model, node, oneTime) {\n      var binding = expression.getBinding(model, filterRegistry, oneTime);\n      if (expression.scopeIdent && binding) {\n        node.polymerExpressionScopeIdent_ = expression.scopeIdent;\n        if (expression.indexIdent)\n          node.polymerExpressionIndexIdent_ = expression.indexIdent;\n      }\n\n      return binding;\n    }\n  }\n\n  // TODO(rafaelw): Implement simple LRU.\n  var expressionParseCache = Object.create(null);\n\n  function getExpression(expressionText) {\n    var expression = expressionParseCache[expressionText];\n    if (!expression) {\n      var delegate = new ASTDelegate();\n      esprima.parse(expressionText, delegate);\n      expression = new Expression(delegate);\n      expressionParseCache[expressionText] = expression;\n    }\n    return expression;\n  }\n\n  function Literal(value) {\n    this.value = value;\n    this.valueFn_ = undefined;\n  }\n\n  Literal.prototype = {\n    valueFn: function() {\n      if (!this.valueFn_) {\n        var value = this.value;\n        this.valueFn_ = function() {\n          return value;\n        }\n      }\n\n      return this.valueFn_;\n    }\n  }\n\n  function IdentPath(name) {\n    this.name = name;\n    this.path = Path.get(name);\n  }\n\n  IdentPath.prototype = {\n    valueFn: function() {\n      if (!this.valueFn_) {\n        var name = this.name;\n        var path = this.path;\n        this.valueFn_ = function(model, observer) {\n          if (observer)\n            observer.addPath(model, path);\n\n          return path.getValueFrom(model);\n        }\n      }\n\n      return this.valueFn_;\n    },\n\n    setValue: function(model, newValue) {\n      if (this.path.length == 1);\n        model = findScope(model, this.path[0]);\n\n      return this.path.setValueFrom(model, newValue);\n    }\n  };\n\n  function MemberExpression(object, property, accessor) {\n    // convert literal computed property access where literal value is a value\n    // path to ident dot-access.\n    if (accessor == '[' &&\n        property instanceof Literal &&\n        Path.get(property.value).valid) {\n      accessor = '.';\n      property = new IdentPath(property.value);\n    }\n\n    this.dynamicDeps = typeof object == 'function' || object.dynamic;\n\n    this.dynamic = typeof property == 'function' ||\n                   property.dynamic ||\n                   accessor == '[';\n\n    this.simplePath =\n        !this.dynamic &&\n        !this.dynamicDeps &&\n        property instanceof IdentPath &&\n        (object instanceof MemberExpression || object instanceof IdentPath);\n\n    this.object = this.simplePath ? object : getFn(object);\n    this.property = accessor == '.' ? property : getFn(property);\n  }\n\n  MemberExpression.prototype = {\n    get fullPath() {\n      if (!this.fullPath_) {\n        var last = this.object instanceof IdentPath ?\n            this.object.name : this.object.fullPath;\n        this.fullPath_ = Path.get(last + '.' + this.property.name);\n      }\n\n      return this.fullPath_;\n    },\n\n    valueFn: function() {\n      if (!this.valueFn_) {\n        var object = this.object;\n\n        if (this.simplePath) {\n          var path = this.fullPath;\n\n          this.valueFn_ = function(model, observer) {\n            if (observer)\n              observer.addPath(model, path);\n\n            return path.getValueFrom(model);\n          };\n        } else if (this.property instanceof IdentPath) {\n          var path = Path.get(this.property.name);\n\n          this.valueFn_ = function(model, observer) {\n            var context = object(model, observer);\n\n            if (observer)\n              observer.addPath(context, path);\n\n            return path.getValueFrom(context);\n          }\n        } else {\n          // Computed property.\n          var property = this.property;\n\n          this.valueFn_ = function(model, observer) {\n            var context = object(model, observer);\n            var propName = property(model, observer);\n            if (observer)\n              observer.addPath(context, propName);\n\n            return context ? context[propName] : undefined;\n          };\n        }\n      }\n      return this.valueFn_;\n    },\n\n    setValue: function(model, newValue) {\n      if (this.simplePath) {\n        this.fullPath.setValueFrom(model, newValue);\n        return newValue;\n      }\n\n      var object = this.object(model);\n      var propName = this.property instanceof IdentPath ? this.property.name :\n          this.property(model);\n      return object[propName] = newValue;\n    }\n  };\n\n  function Filter(name, args) {\n    this.name = name;\n    this.args = [];\n    for (var i = 0; i < args.length; i++) {\n      this.args[i] = getFn(args[i]);\n    }\n  }\n\n  Filter.prototype = {\n    transform: function(value, toModelDirection, filterRegistry, model,\n                        observer) {\n      var fn = filterRegistry[this.name];\n      var context = model;\n      if (fn) {\n        context = undefined;\n      } else {\n        fn = context[this.name];\n        if (!fn) {\n          console.error('Cannot find filter: ' + this.name);\n          return;\n        }\n      }\n\n      // If toModelDirection is falsey, then the \"normal\" (dom-bound) direction\n      // is used. Otherwise, it looks for a 'toModel' property function on the\n      // object.\n      if (toModelDirection) {\n        fn = fn.toModel;\n      } else if (typeof fn.toDOM == 'function') {\n        fn = fn.toDOM;\n      }\n\n      if (typeof fn != 'function') {\n        console.error('No ' + (toModelDirection ? 'toModel' : 'toDOM') +\n                      ' found on' + this.name);\n        return;\n      }\n\n      var args = [value];\n      for (var i = 0; i < this.args.length; i++) {\n        args[i + 1] = getFn(this.args[i])(model, observer);\n      }\n\n      return fn.apply(context, args);\n    }\n  };\n\n  function notImplemented() { throw Error('Not Implemented'); }\n\n  var unaryOperators = {\n    '+': function(v) { return +v; },\n    '-': function(v) { return -v; },\n    '!': function(v) { return !v; }\n  };\n\n  var binaryOperators = {\n    '+': function(l, r) { return l+r; },\n    '-': function(l, r) { return l-r; },\n    '*': function(l, r) { return l*r; },\n    '/': function(l, r) { return l/r; },\n    '%': function(l, r) { return l%r; },\n    '<': function(l, r) { return l<r; },\n    '>': function(l, r) { return l>r; },\n    '<=': function(l, r) { return l<=r; },\n    '>=': function(l, r) { return l>=r; },\n    '==': function(l, r) { return l==r; },\n    '!=': function(l, r) { return l!=r; },\n    '===': function(l, r) { return l===r; },\n    '!==': function(l, r) { return l!==r; },\n    '&&': function(l, r) { return l&&r; },\n    '||': function(l, r) { return l||r; },\n  };\n\n  function getFn(arg) {\n    return typeof arg == 'function' ? arg : arg.valueFn();\n  }\n\n  function ASTDelegate() {\n    this.expression = null;\n    this.filters = [];\n    this.deps = {};\n    this.currentPath = undefined;\n    this.scopeIdent = undefined;\n    this.indexIdent = undefined;\n    this.dynamicDeps = false;\n  }\n\n  ASTDelegate.prototype = {\n    createUnaryExpression: function(op, argument) {\n      if (!unaryOperators[op])\n        throw Error('Disallowed operator: ' + op);\n\n      argument = getFn(argument);\n\n      return function(model, observer) {\n        return unaryOperators[op](argument(model, observer));\n      };\n    },\n\n    createBinaryExpression: function(op, left, right) {\n      if (!binaryOperators[op])\n        throw Error('Disallowed operator: ' + op);\n\n      left = getFn(left);\n      right = getFn(right);\n\n      return function(model, observer) {\n        return binaryOperators[op](left(model, observer),\n                                   right(model, observer));\n      };\n    },\n\n    createConditionalExpression: function(test, consequent, alternate) {\n      test = getFn(test);\n      consequent = getFn(consequent);\n      alternate = getFn(alternate);\n\n      return function(model, observer) {\n        return test(model, observer) ?\n            consequent(model, observer) : alternate(model, observer);\n      }\n    },\n\n    createIdentifier: function(name) {\n      var ident = new IdentPath(name);\n      ident.type = 'Identifier';\n      return ident;\n    },\n\n    createMemberExpression: function(accessor, object, property) {\n      var ex = new MemberExpression(object, property, accessor);\n      if (ex.dynamicDeps)\n        this.dynamicDeps = true;\n      return ex;\n    },\n\n    createLiteral: function(token) {\n      return new Literal(token.value);\n    },\n\n    createArrayExpression: function(elements) {\n      for (var i = 0; i < elements.length; i++)\n        elements[i] = getFn(elements[i]);\n\n      return function(model, observer) {\n        var arr = []\n        for (var i = 0; i < elements.length; i++)\n          arr.push(elements[i](model, observer));\n        return arr;\n      }\n    },\n\n    createProperty: function(kind, key, value) {\n      return {\n        key: key instanceof IdentPath ? key.name : key.value,\n        value: value\n      };\n    },\n\n    createObjectExpression: function(properties) {\n      for (var i = 0; i < properties.length; i++)\n        properties[i].value = getFn(properties[i].value);\n\n      return function(model, observer) {\n        var obj = {};\n        for (var i = 0; i < properties.length; i++)\n          obj[properties[i].key] = properties[i].value(model, observer);\n        return obj;\n      }\n    },\n\n    createFilter: function(name, args) {\n      this.filters.push(new Filter(name, args));\n    },\n\n    createAsExpression: function(expression, scopeIdent) {\n      this.expression = expression;\n      this.scopeIdent = scopeIdent;\n    },\n\n    createInExpression: function(scopeIdent, indexIdent, expression) {\n      this.expression = expression;\n      this.scopeIdent = scopeIdent;\n      this.indexIdent = indexIdent;\n    },\n\n    createTopLevel: function(expression) {\n      this.expression = expression;\n    },\n\n    createThisExpression: notImplemented\n  }\n\n  function ConstantObservable(value) {\n    this.value_ = value;\n  }\n\n  ConstantObservable.prototype = {\n    open: function() { return this.value_; },\n    discardChanges: function() { return this.value_; },\n    deliver: function() {},\n    close: function() {},\n  }\n\n  function Expression(delegate) {\n    this.scopeIdent = delegate.scopeIdent;\n    this.indexIdent = delegate.indexIdent;\n\n    if (!delegate.expression)\n      throw Error('No expression found.');\n\n    this.expression = delegate.expression;\n    getFn(this.expression); // forces enumeration of path dependencies\n\n    this.filters = delegate.filters;\n    this.dynamicDeps = delegate.dynamicDeps;\n  }\n\n  Expression.prototype = {\n    getBinding: function(model, filterRegistry, oneTime) {\n      if (oneTime)\n        return this.getValue(model, undefined, filterRegistry);\n\n      var observer = new CompoundObserver();\n      this.getValue(model, observer, filterRegistry);  // captures deps.\n      var self = this;\n\n      function valueFn() {\n        if (self.dynamicDeps)\n          observer.startReset();\n\n        var value = self.getValue(model,\n                                  self.dynamicDeps ? observer : undefined,\n                                  filterRegistry);\n        if (self.dynamicDeps)\n          observer.finishReset();\n\n        return value;\n      }\n\n      function setValueFn(newValue) {\n        self.setValue(model, newValue, filterRegistry);\n        return newValue;\n      }\n\n      return new ObserverTransform(observer, valueFn, setValueFn, true);\n    },\n\n    getValue: function(model, observer, filterRegistry) {\n      var value = getFn(this.expression)(model, observer);\n      for (var i = 0; i < this.filters.length; i++) {\n        value = this.filters[i].transform(value, false, filterRegistry, model,\n                                          observer);\n      }\n\n      return value;\n    },\n\n    setValue: function(model, newValue, filterRegistry) {\n      var count = this.filters ? this.filters.length : 0;\n      while (count-- > 0) {\n        newValue = this.filters[count].transform(newValue, true, filterRegistry,\n                                                 model);\n      }\n\n      if (this.expression.setValue)\n        return this.expression.setValue(model, newValue);\n    }\n  }\n\n  /**\n   * Converts a style property name to a css property name. For example:\n   * \"WebkitUserSelect\" to \"-webkit-user-select\"\n   */\n  function convertStylePropertyName(name) {\n    return String(name).replace(/[A-Z]/g, function(c) {\n      return '-' + c.toLowerCase();\n    });\n  }\n\n  function isEventHandler(name) {\n    return name[0] === 'o' &&\n           name[1] === 'n' &&\n           name[2] === '-';\n  }\n\n  var mixedCaseEventTypes = {};\n  [\n    'webkitAnimationStart',\n    'webkitAnimationEnd',\n    'webkitTransitionEnd',\n    'DOMFocusOut',\n    'DOMFocusIn',\n    'DOMMouseScroll'\n  ].forEach(function(e) {\n    mixedCaseEventTypes[e.toLowerCase()] = e;\n  });\n\n  var parentScopeName = '@' + Math.random().toString(36).slice(2);\n\n  // Single ident paths must bind directly to the appropriate scope object.\n  // I.e. Pushed values in two-bindings need to be assigned to the actual model\n  // object.\n  function findScope(model, prop) {\n    while (model[parentScopeName] &&\n           !Object.prototype.hasOwnProperty.call(model, prop)) {\n      model = model[parentScopeName];\n    }\n\n    return model;\n  }\n\n  function resolveEventReceiver(model, path, node) {\n    if (path.length == 0)\n      return undefined;\n\n    if (path.length == 1)\n      return findScope(model, path[0]);\n\n    for (var i = 0; model != null && i < path.length - 1; i++) {\n      model = model[path[i]];\n    }\n\n    return model;\n  }\n\n  function prepareEventBinding(path, name, polymerExpressions) {\n    var eventType = name.substring(3);\n    eventType = mixedCaseEventTypes[eventType] || eventType;\n\n    return function(model, node, oneTime) {\n      var fn, receiver, handler;\n      if (typeof polymerExpressions.resolveEventHandler == 'function') {\n        handler = function(e) {\n          fn = fn || polymerExpressions.resolveEventHandler(model, path, node);\n          fn(e, e.detail, e.currentTarget);\n\n          if (Platform && typeof Platform.flush == 'function')\n            Platform.flush();\n        };\n      } else {\n        handler = function(e) {\n          fn = fn || path.getValueFrom(model);\n          receiver = receiver || resolveEventReceiver(model, path, node);\n\n          fn.apply(receiver, [e, e.detail, e.currentTarget]);\n\n          if (Platform && typeof Platform.flush == 'function')\n            Platform.flush();\n        };\n      }\n\n      node.addEventListener(eventType, handler);\n\n      if (oneTime)\n        return;\n\n      function bindingValue() {\n        return '{{ ' + path + ' }}';\n      }\n\n      return {\n        open: bindingValue,\n        discardChanges: bindingValue,\n        close: function() {\n          node.removeEventListener(eventType, handler);\n        }\n      };\n    }\n  }\n\n  function PolymerExpressions() {}\n\n  PolymerExpressions.prototype = {\n    // \"built-in\" filters\n    styleObject: function(value) {\n      var parts = [];\n      for (var key in value) {\n        parts.push(convertStylePropertyName(key) + ': ' + value[key]);\n      }\n      return parts.join('; ');\n    },\n\n    tokenList: function(value) {\n      var tokens = [];\n      for (var key in value) {\n        if (value[key])\n          tokens.push(key);\n      }\n      return tokens.join(' ');\n    },\n\n    // binding delegate API\n    prepareInstancePositionChanged: function(template) {\n      var indexIdent = template.polymerExpressionIndexIdent_;\n      if (!indexIdent)\n        return;\n\n      return function(templateInstance, index) {\n        templateInstance.model[indexIdent] = index;\n      };\n    },\n\n    prepareBinding: function(pathString, name, node) {\n      var path = Path.get(pathString);\n      if (isEventHandler(name)) {\n        if (!path.valid) {\n          console.error('on-* bindings must be simple path expressions');\n          return;\n        }\n\n        return prepareEventBinding(path, name, this);\n      }\n\n      if (path.valid) {\n        if (path.length == 1) {\n          return function(model, node, oneTime) {\n            if (oneTime)\n              return path.getValueFrom(model);\n\n            var scope = findScope(model, path[0]);\n            return new PathObserver(scope, path);\n          }\n        }\n\n        return; // bail out early if pathString is simple path.\n      }\n\n      return prepareBinding(pathString, name, node, this);\n    },\n\n    prepareInstanceModel: function(template) {\n      var scopeName = template.polymerExpressionScopeIdent_;\n      if (!scopeName)\n        return;\n\n      var parentScope = template.templateInstance ?\n          template.templateInstance.model :\n          template.model;\n\n      var indexName = template.polymerExpressionIndexIdent_;\n\n      return function(model) {\n        var scope = Object.create(parentScope);\n        scope[scopeName] = model;\n        scope[indexName] = undefined;\n        scope[parentScopeName] = parentScope;\n        return scope;\n      };\n    }\n  };\n\n  global.PolymerExpressions = PolymerExpressions;\n  if (global.exposeGetExpression)\n    global.getExpression_ = getExpression;\n\n  global.PolymerExpressions.prepareEventBinding = prepareEventBinding;\n})(this);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n// inject style sheet\nvar style = document.createElement('style');\nstyle.textContent = 'template {display: none !important;} /* injected by platform.js */';\nvar head = document.querySelector('head');\nhead.insertBefore(style, head.firstChild);\n\n// flush (with logging)\nvar flushing;\nfunction flush() {\n  if (!flushing) {\n    flushing = true;\n    scope.endOfMicrotask(function() {\n      flushing = false;\n      logFlags.data && console.group('Platform.flush()');\n      scope.performMicrotaskCheckpoint();\n      logFlags.data && console.groupEnd();\n    });\n  }\n};\n\n// polling dirty checker\nvar FLUSH_POLL_INTERVAL = 125;\nwindow.addEventListener('WebComponentsReady', function() {\n  flush();\n  // flush periodically if platform does not have object observe.\n  if (!Observer.hasObjectObserve) {\n    scope.flushPoll = setInterval(flush, FLUSH_POLL_INTERVAL);\n  }\n});\n\nif (window.CustomElements && !CustomElements.useNative) {\n  var originalImportNode = Document.prototype.importNode;\n  Document.prototype.importNode = function(node, deep) {\n    var imported = originalImportNode.call(this, node, deep);\n    CustomElements.upgradeAll(imported);\n    return imported;\n  }\n}\n\n// exports\nscope.flush = flush;\n\n})(window.Platform);\n\n"]}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/.bower.json
deleted file mode 100644
index 9830dd6..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/.bower.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "polymer-localstorage",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1",
-  "homepage": "https://github.com/Polymer/polymer-localstorage",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "19e87468b2a977bf79db60db247e0b4e8672e920"
-  },
-  "_source": "git://github.com/Polymer/polymer-localstorage.git",
-  "_target": "*",
-  "_originalSource": "Polymer/polymer-localstorage"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/CONTRIBUTING.md
deleted file mode 100644
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/bower.json
deleted file mode 100644
index 1006bc1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/bower.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "name": "polymer-localstorage",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/demo.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/demo.html
deleted file mode 100644
index 139675b..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/demo.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>polymer-localstorage</title>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="polymer-localstorage.html">
-  <link rel="import" href="../polymer-ui-toggle-button/polymer-ui-toggle-button.html">
-</head>
-<body>
-  <polymer-element name="x-test1">
-    <template>
-      string entered below will be stored in localStorage and automatically retrived from localStorage when the page is reloaded<br>
-      <input value="{{value}}">
-      <polymer-localstorage name="polymer-localstorage-x-test1" value="{{value}}"></polymer-localstorage>
-    </template>
-    <script>
-      Polymer('x-test1');
-    </script>
-  </polymer-element>
-  
-  <x-test1></x-test1>
-  <br><br>
-  
-  <polymer-element name="x-test2">
-    <template>
-      <polymer-ui-toggle-button value="{{mode}}"></polymer-ui-toggle-button>
-      <polymer-localstorage name="polymer-localstorage-x-test2" value="{{mode}}"></polymer-localstorage>
-    </template>
-    <script>
-      Polymer('x-test2', {
-        mode: false
-      });
-    </script>
-  </polymer-element>
-  
-  <x-test2></x-test2>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/index.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/index.html
deleted file mode 100644
index 9bb2721..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer api</title>
-  <style>
-    html, body {
-      font-family: Arial, sans-serif;
-      white-space: nowrap;
-      overflow: hidden;
-    }
-    [noviewer] [ifnoviewer] {
-      display: block;
-    }
-    [detector], [ifnoviewer], [noviewer] [ifviewer] {
-      display: none;
-    }
-    [ifviewer], [ifnoviewer] {
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-    }
-    iframe {
-      border: none;
-      margin: 0;
-      width: 100%;
-      height: 100%;
-    }
-    #remote {
-      position: absolute;
-      top: 0;
-      right: 0;
-    }
-  </style>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="../polymer-home-page/polymer-home-page.html">
-</head>
-<body>
-  <img detector src="../polymer-home-page/bowager-logo.png" onerror="noviewer()">
-  <polymer-home-page ifviewer></polymer-home-page>
-  <div ifnoviewer>
-    <span id="remote">[remote]</span>
-    <iframe></iframe>
-  </div>
-  <!-- -->
-  <script>
-    var remoteDocs = 'http://turbogadgetry.com/bowertopia/components/';
-    // if no local info viewer, load it remotely
-    function noviewer() {
-      document.body.setAttribute('noviewer', '');
-      var path = location.pathname.split('/');
-      var module = path.pop() || path.pop();
-      document.querySelector('iframe').src = remoteDocs + module;
-      document.querySelector('title').textContent = module;
-    }
-    // for testing only
-    var opts = window.location.search;
-    if (opts.indexOf('noviewer') >= 0) {
-      noviewer();
-    }
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/polymer-localstorage.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/polymer-localstorage.html
deleted file mode 100644
index 0bfc203..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/polymer-localstorage.html
+++ /dev/null
@@ -1,127 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
-/**
- * Element access to localStorage.  The "name" property
- * is the key to the data ("value" property) stored in localStorage.
- *
- * polymer-localstorage automatically saves the value to localStorage when
- * value is changed.  Note that if value is an object auto-save will be
- * triggered only when value is a different instance.
- *
- * Example:
- *
- *     <polymer-localstorage name="my-app-storage" value="{{value}}"></polymer-localstorage>
- *
- * @class polymer-localstorage
- * @blurb Element access to localStorage.
- * @snap http://polymer.github.io/polymer-localstorage/snap.png
- * @author The Polymer Authors
- * @categories Data
- *
- */
-/**
- * Fired after it is loaded from localStorage.
- * 
- * @event polymer-localstorage-load
- */
--->
-<link rel="import" href="../polymer/polymer.html">
-
-<polymer-element name="polymer-localstorage" attributes="name value useRaw autoSaveDisabled">
-  <template>
-    <style>
-      :host {
-        display: none;
-      }
-    </style>
-  </template>
-  <script>
-    Polymer('polymer-localstorage', {
-      /**
-       * The key to the data stored in localStorage.
-       *
-       * @attribute name
-       * @type string
-       * @default null
-       */
-      name: '',
-      /**
-       * The data associated with the specified name.
-       *
-       * @attribute value
-       * @type object
-       * @default null
-       */
-      value: null,
-      /**
-       * If true, the value is stored and retrieved without JSON processing.
-       *
-       * @attribute useRaw
-       * @type boolean
-       * @default false
-       */
-      useRaw: false,
-      /**
-       * If true, auto save is disabled.
-       *
-       * @attribute autoSaveDisabled
-       * @type boolean
-       * @default false
-       */
-      autoSaveDisabled: false,
-      enteredView: function() {
-        // wait for bindings are all setup
-        this.async('load');
-      },
-      valueChanged: function() {
-        if (this.loaded && !this.autoSaveDisabled) {
-          this.save();
-        }
-      },
-      load: function() {
-        var v = localStorage.getItem(this.name);
-        if (this.useRaw) {
-          this.value = v;
-        } else {
-          // localStorage has a flaw that makes it difficult to determine
-          // if a key actually exists or not (getItem returns null if the
-          // key doesn't exist, which is not distinguishable from a stored
-          // null value)
-          // however, if not `useRaw`, an (unparsed) null value unambiguously
-          // signals that there is no value in storage (a stored null value would
-          // be escaped, i.e. "null")
-          // in this case we save any non-null current (default) value
-          if (v === null) {
-            if (this.value !== null) {
-              this.save();
-            }
-          } else {
-            try {
-              v = JSON.parse(v);
-            } catch(x) {
-            }
-            this.value = v;
-          }
-        }
-        this.loaded = true;
-        this.asyncFire('polymer-localstorage-load');
-      },
-      /** 
-       * Saves the value to localStorage.
-       *
-       * @method save
-       */
-      save: function() {
-        var v = this.useRaw ? this.value : JSON.stringify(this.value);
-        localStorage.setItem(this.name, v);
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/html/polymer-localstorage.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/html/polymer-localstorage.html
deleted file mode 100644
index 7234dbe..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/html/polymer-localstorage.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-localstorage</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-localstorage.html">
-</head>
-<body>
-
-  <polymer-localstorage id="localstorage" name="polymer-localstorage-test" useRaw></polymer-localstorage>
-  
-  <script>
-    var assert = chai.assert;
-    document.addEventListener('polymer-ready', function() {
-      var s = document.querySelector('#localstorage');
-      var m = 'hello wold';
-      window.localStorage.setItem(s.name, m);
-      s.load();
-      assert.equal(s.value, m);
-      s.value = 'goodbye';
-      assert.equal(window.localStorage.getItem(s.name), m);
-      done();
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/js/polymer-localstorage.js b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/js/polymer-localstorage.js
deleted file mode 100644
index 9bba7a1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/js/polymer-localstorage.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Copyright 2013 The Polymer Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
-
-htmlSuite('polymer-localstorage', function() {
-  htmlTest('html/polymer-localstorage.html');
-});
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/runner.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/runner.html
deleted file mode 100644
index 65ef121..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-localstorage/test/runner.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<html>
-  <head>
-    <title>polymer-localstorage Test Runner (Mocha)</title>
-    <meta charset="UTF-8">
-    <!-- -->
-    <link rel="stylesheet" href="../../tools/test/mocha/mocha.css" />
-    <script src="../../tools/test/mocha/mocha.js"></script>
-    <script src="../../tools/test/chai/chai.js"></script>
-    <script src="../../tools/test/mocha-htmltest.js"></script>
-    <!-- -->
-    <script src="../../platform/platform.js"></script>
-  </head>
-  <body>
-    <div id="mocha"></div>
-    <script>
-      mocha.setup({ui: 'tdd', slow: 1000, htmlbase: ''});
-    </script>
-    <!-- -->
-    <script src="js/polymer-localstorage.js"></script>
-    <!-- -->
-    <script>
-      mocha.run();
-    </script>
-  </body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/.bower.json
deleted file mode 100644
index dd32aa8..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/.bower.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "polymer-selection",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1",
-  "homepage": "https://github.com/Polymer/polymer-selection",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "414b5314477367acb821fc515279f18bc66e4897"
-  },
-  "_source": "git://github.com/Polymer/polymer-selection.git",
-  "_target": "0.2.1",
-  "_originalSource": "Polymer/polymer-selection"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/CONTRIBUTING.md
deleted file mode 100644
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/bower.json
deleted file mode 100644
index 118451d..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/bower.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "name": "polymer-selection",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/demo.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/demo.html
deleted file mode 100644
index c7994a2..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/demo.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>Selection</title>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="polymer-selection.html">
-</head>
-<body>
-<polymer-element name="selection-example">
-  <template>
-    <style>
-      /* @polyfill ul > * */
-      ::-webkit-distributed(> *) {
-        cursor: pointer;
-      }
-
-      /* @polyfill ul > .selected */
-      ::-webkit-distributed(> .selected) {
-        font-weight: bold;
-        font-style: italic;
-      }
-    </style>
-    <ul on-tap="{{itemTapAction}}">
-      <content></content>
-    </ul>
-    <polymer-selection id="selection" multi on-polymer-select="{{selectAction}}"></polymer-selection>
-    </template>
-    <script>
-    Polymer('selection-example', {
-      itemTapAction: function(e) {
-        this.$.selection.select(e.target);
-      },
-      selectAction: function(e, detail) {
-        detail.item.classList.toggle('selected', detail.isSelected);
-      }
-    });
-    </script>
-  </polymer-element>
-
-  <selection-example>
-    <li>Red</li>
-    <li>Green</li>
-    <li>Blue</li>
-  </selection-example>
-  
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/index.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/index.html
deleted file mode 100644
index 9bb2721..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer api</title>
-  <style>
-    html, body {
-      font-family: Arial, sans-serif;
-      white-space: nowrap;
-      overflow: hidden;
-    }
-    [noviewer] [ifnoviewer] {
-      display: block;
-    }
-    [detector], [ifnoviewer], [noviewer] [ifviewer] {
-      display: none;
-    }
-    [ifviewer], [ifnoviewer] {
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-    }
-    iframe {
-      border: none;
-      margin: 0;
-      width: 100%;
-      height: 100%;
-    }
-    #remote {
-      position: absolute;
-      top: 0;
-      right: 0;
-    }
-  </style>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="../polymer-home-page/polymer-home-page.html">
-</head>
-<body>
-  <img detector src="../polymer-home-page/bowager-logo.png" onerror="noviewer()">
-  <polymer-home-page ifviewer></polymer-home-page>
-  <div ifnoviewer>
-    <span id="remote">[remote]</span>
-    <iframe></iframe>
-  </div>
-  <!-- -->
-  <script>
-    var remoteDocs = 'http://turbogadgetry.com/bowertopia/components/';
-    // if no local info viewer, load it remotely
-    function noviewer() {
-      document.body.setAttribute('noviewer', '');
-      var path = location.pathname.split('/');
-      var module = path.pop() || path.pop();
-      document.querySelector('iframe').src = remoteDocs + module;
-      document.querySelector('title').textContent = module;
-    }
-    // for testing only
-    var opts = window.location.search;
-    if (opts.indexOf('noviewer') >= 0) {
-      noviewer();
-    }
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/polymer-selection.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/polymer-selection.html
deleted file mode 100644
index d29fae4..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/polymer-selection.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
--->
-<!--
-/**
- * The polymer-selection element is used to manage selection state. It has no
- * visual appearance and is typically used in conjuneciton with another element.
- * For example, <a href="polymer-selector.html">polymer-selector</a>
- * use a polymer-selection to manage selection.
- *
- * To mark an item as selected, call the select(item) method on 
- * polymer-selection. Notice that the item itself is an argument to this method.
- * The polymer-selection element manages selection state for any given set of
- * items. When an item is selected, the `polymer-select` event is fired.
- * The attribute "multi" indicates if multiple items can be selected at once.
- * 
- * Example:
- *
- *     <polymer-element name="selection-example">
- *        <template>
- *          <style>
- *            ::-webkit-distributed(> .selected) {
- *              font-weight: bold;
- *              font-style: italic;
- *            }
- *          </style>
- *          <ul on-tap="{{itemTapAction}}">
- *            <content></content>
- *          </ul>
- *          <polymer-selection id="selection" multi on-polymer-select="{{selectAction}}"></polymer-selection>
- *        </template>
- *        <script>
- *          Polymer('selection-example', {
- *            itemTapAction: function(e) {
- *              this.$.selection.select(e.target);
- *            },
- *            selectAction: function(e, detail) {
- *              detail.item.classList.toggle('selected', detail.isSelected);
- *            }
- *          });
- *        </script>
- *     </polymer-element>
- *
- *     <selection-example>
- *       <li>Red</li>
- *       <li>Green</li>
- *       <li>Blue</li>
- *     </selection-example>
- *
- * @class polymer-selection
- */
- /**
- * Fired when an item's selection state is changed. This event is fired both
- * when an item is selected or deselected. The `isSelected` detail property
- * contains the selection state.
- * 
- * @event polymer-select
- * @param {Object} detail
- *   @param {boolean} detail.isSelected true for selection and false for deselection
- *   @param {Object} detail.item the item element
- */
--->
-<link rel="import" href="../polymer/polymer.html">
-
-<polymer-element name="polymer-selection" attributes="multi">
-  <template>
-    <style>
-      :host {
-        display: none !important;
-      }
-    </style>
-  </template>
-  <script>
-    Polymer('polymer-selection', {
-      /**
-       * If true, multiple selections are allowed.
-       *
-       * @attribute multi
-       * @type boolean
-       * @default false
-       */
-      multi: false,
-      ready: function() {
-        this.clear();
-      },
-      clear: function() {
-        this.selection = [];
-      },
-      /**
-       * Retrieves the selected item(s).
-       * @method getSelection
-       * @returns Returns the selected item(s). If the multi property is true,
-       * getSelection will return an array, otherwise it will return 
-       * the selected item or undefined if there is no selection.
-      */
-      getSelection: function() {
-        return this.multi ? this.selection : this.selection[0];
-      },
-      /**
-       * Indicates if a given item is selected.
-       * @method isSelected
-       * @param {any} item The item whose selection state should be checked.
-       * @returns Returns true if `item` is selected.
-      */
-      isSelected: function(item) {
-        return this.selection.indexOf(item) >= 0;
-      },
-      setItemSelected: function(item, isSelected) {
-        if (item !== undefined && item !== null) {
-          if (isSelected) {
-            this.selection.push(item);
-          } else {
-            var i = this.selection.indexOf(item);
-            if (i >= 0) {
-              this.selection.splice(i, 1);
-            }
-          }
-          this.fire("polymer-select", {isSelected: isSelected, item: item});
-        }
-      },
-      /**
-       * Set the selection state for a given `item`. If the multi property
-       * is true, then the selected state of `item` will be toggled; otherwise
-       * the `item` will be selected.
-       * @method select
-       * @param {any} item: The item to select.
-      */
-      select: function(item) {
-        if (this.multi) {
-          this.toggle(item);
-        } else if (this.getSelection() !== item) {
-          this.setItemSelected(this.getSelection(), false);
-          this.setItemSelected(item, true);
-        }
-      },
-      /**
-       * Toggles the selection state for `item`.
-       * @method toggle
-       * @param {any} item: The item to toggle.
-      */
-      toggle: function(item) {
-        this.setItemSelected(item, !this.isSelected(item));
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection-multi.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection-multi.html
deleted file mode 100644
index ebc02f6..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection-multi.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selection-multi</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selection.html">
-</head>
-<body>
-
-  <polymer-selection multi></polymer-selection>
-  
-  <script>
-    var assert = chai.assert;
-    document.addEventListener('polymer-ready', function() {
-      var s = document.querySelector('polymer-selection');
-      s.addEventListener("polymer-select", function(event) {
-        if (test === 1) {
-          // check test1
-          assert.isTrue(event.detail.isSelected);
-          assert.equal(event.detail.item, '(item1)');
-          assert.isTrue(s.isSelected(event.detail.item));
-          assert.equal(s.getSelection().length, 1);
-          // test2
-          test++;
-          s.select('(item2)');
-        } else if (test === 2) {
-          // check test2
-          assert.isTrue(event.detail.isSelected);
-          assert.equal(event.detail.item, '(item2)');
-          assert.isTrue(s.isSelected(event.detail.item));
-          assert.equal(s.getSelection().length, 2);
-          done();
-        }
-      });
-      // test1
-      var test = 1;
-      s.select('(item1)');
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection.html
deleted file mode 100644
index 1149890..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/html/polymer-selection.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selection</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selection.html">
-</head>
-<body>
-
-  <polymer-selection></polymer-selection>
-  
-  <script>
-    var assert = chai.assert;
-    document.addEventListener('polymer-ready', function() {
-      var s = document.querySelector('polymer-selection');
-      s.addEventListener("polymer-select", function(event) {
-        if (test === 1) {
-          // check test1
-          assert.isTrue(event.detail.isSelected);
-          assert.equal(event.detail.item, '(item)');
-          assert.isTrue(s.isSelected(event.detail.item));
-          assert.isFalse(s.isSelected('(some_item_not_selected)'));
-          // test2
-          test++;
-          s.select(null);
-        } else if (test === 2) {
-          // check test2
-          assert.isFalse(event.detail.isSelected);
-          assert.equal(event.detail.item, '(item)');
-          assert.isFalse(s.isSelected(event.detail.item));
-          done();
-        }
-      });
-      // test1
-      var test = 1;
-      s.select('(item)');
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/js/polymer-selection.js b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/js/polymer-selection.js
deleted file mode 100644
index 023e495..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/js/polymer-selection.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*

- * Copyright 2013 The Polymer Authors. All rights reserved.

- * Use of this source code is governed by a BSD-style

- * license that can be found in the LICENSE file.

- */

-

-htmlSuite('polymer-selection', function() {

-  htmlTest('html/polymer-selection.html');

-  htmlTest('html/polymer-selection-multi.html');

-});
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/runner.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/runner.html
deleted file mode 100644
index 5667519..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selection/test/runner.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<html>
-  <head>
-    <title>polymer-selection Test Runner (Mocha)</title>
-    <meta charset="UTF-8">
-    <!-- -->
-    <link rel="stylesheet" href="../../tools/test/mocha/mocha.css" />
-    <script src="../../tools/test/mocha/mocha.js"></script>
-    <script src="../../tools/test/chai/chai.js"></script>
-    <script src="../../tools/test/mocha-htmltest.js"></script>
-    <!-- -->
-    <script src="../../platform/platform.js"></script>
-  </head>
-  <body>
-    <div id="mocha"></div>
-    <script>
-      mocha.setup({ui: 'tdd', slow: 1000, htmlbase: ''});
-    </script>
-    <!-- -->
-    <script src="js/polymer-selection.js"></script>
-    <!-- -->
-    <script>
-      mocha.run();
-    </script>
-  </body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/.bower.json
deleted file mode 100644
index 726b021..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/.bower.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "polymer-selector",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1",
-    "polymer-selection": "Polymer/polymer-selection#0.2.1"
-  },
-  "version": "0.2.1",
-  "homepage": "https://github.com/Polymer/polymer-selector",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "cd84d37c050e2badb90fd621061866bcdde48515"
-  },
-  "_source": "git://github.com/Polymer/polymer-selector.git",
-  "_target": "*",
-  "_originalSource": "Polymer/polymer-selector"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/CONTRIBUTING.md
deleted file mode 100644
index 6f3aca9..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-See https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/README.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/README.md
deleted file mode 100644
index ed4a600..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-polymer-selector
-================
-
-[LICENSE](https://raw.github.com/Polymer/polymer/master/LICENSE)
-
-[PATENTS](https://raw.github.com/Polymer/polymer/master/PATENTS)
-
-[CONTRIBUTING](https://github.com/Polymer/polymer/blob/master/CONTRIBUTING.md)
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/bower.json
deleted file mode 100644
index f9d24cd..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/bower.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "name": "polymer-selector",
-  "private": true,
-  "dependencies": {
-    "polymer": "Polymer/polymer#0.2.1",
-    "polymer-selection": "Polymer/polymer-selection#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/demo.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/demo.html
deleted file mode 100644
index 730de55..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/demo.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>Selector</title>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="polymer-selector.html">
-</head>
-<body unresolved>
-  <polymer-element name="selector-examples">
-    <template>
-      <style>
-        .list {
-          display: block;
-          border: 1px solid #ccc;
-          border-bottom: none;
-          background: #666;
-          color: white;
-          list-style: none;
-          margin: 0;
-          padding: 0;
-        }
-        
-        .list > * {
-          height: 40px;
-          line-height: 40px;
-          padding: 0 20px;
-          border-bottom: 1px solid #ccc;
-        }
-        
-        .list > *.polymer-selected {
-          background: #333;
-        }
-        
-        li {
-          height: 30px;
-        }
-        
-        li.polymer-selected:after {
-          content: "\2713";
-          position: absolute;
-          padding-left: 10px;
-        }
-      </style>
-      
-      <h2>basic</h2>
-      <polymer-selector class="list" selected="0">
-        <div>Item 0</div>
-        <div>Item 1</div>
-        <div>Item 2</div>
-        <div>Item 3</div>
-        <div>Item 4</div>
-      </polymer-selector>
-      
-      <h2>multi-selection</h2>
-      <polymer-selector class="list" selected="{{multiSelected}}" multi>
-        <div>Item 0</div>
-        <div>Item 1</div>
-        <div>Item 2</div>
-        <div>Item 3</div>
-        <div>Item 4</div>
-      </polymer-selector>
-      
-      <h2>list</h2>
-      <polymer-selector target="{{$.list}}" selected="0"></polymer-selector>
-      <ul id="list">
-        <li>Item 0</li>
-        <li>Item 1</li>
-        <li>Item 2</li>
-        <li>Item 3</li>
-        <li>Item 4</li>
-      </ul>
-      
-      <h2>binding of a group of radio buttons to a variable</h2>
-      <polymer-selector target="{{$.myForm}}" itemsSelector="input[type=radio]" 
-          selected="{{color}}" valueattr="value" selectedProperty="checked" 
-          activateEvent="change"></polymer-selector>
-      <form id="myForm">
-        <label><input type="radio" name="color" value="red"> Red</label> <br>
-        <label><input type="radio" name="color" value="green"> Green</label> <br>
-        <label><input type="radio" name="color" value="blue"> Blue</label> <br>
-        <p>color = {{color}}</p>
-      </form>
-      
-    </template>
-
-    <script>
-      Polymer('selector-examples', {
-        ready: function() {
-          this.multiSelected = [1, 3];
-          this.color = 'green';
-        }
-      });
-    </script>
-  </polymer-element>
-  
-  <selector-examples></selector-examples>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/docs.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/docs.json
deleted file mode 100644
index 9f4f0a1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/docs.json
+++ /dev/null
@@ -1,224 +0,0 @@
-{
-    "project": {
-        "name": "Docs",
-        "description": "Docs"
-    },
-    "files": {
-        "../../polymer-selector/polymer-selector.html": {
-            "name": "../../polymer-selector/polymer-selector.html",
-            "modules": {
-                "Polymer Elements": 1
-            },
-            "classes": {
-                "polymer-selector": 1
-            },
-            "fors": {},
-            "namespaces": {}
-        }
-    },
-    "modules": {
-        "Polymer Elements": {
-            "name": "Polymer Elements",
-            "submodules": {},
-            "classes": {
-                "polymer-selector": 1
-            },
-            "fors": {},
-            "namespaces": {},
-            "tag": "module",
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 10
-        }
-    },
-    "classes": {
-        "polymer-selector": {
-            "name": "polymer-selector",
-            "shortname": "polymer-selector",
-            "classitems": [],
-            "plugins": [],
-            "extensions": [],
-            "plugin_for": [],
-            "extension_for": [],
-            "module": "Polymer Elements",
-            "namespace": "",
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 10,
-            "description": "polymer-selector is used to manage a list of elements that can be selected.\nThe attribute \"selected\" indicates which item element is being selected.\nThe attribute \"multi\" indicates if multiple items can be selected at once.\nTapping on the item element would fire \"polymer-activate\" event. Use\n\"polymer-select\" event to listen for selection changes.\n\nExample:\n\n    <polymer-selector selected=\"0\">\n      <div>Item 1</div>\n      <div>Item 2</div>\n      <div>Item 3</div>\n    </polymer-selector>\n\npolymer-selector is not styled.  So one needs to use \"polymer-selected\" CSS\nclass to style the selected element.\n\n    <style>\n      .item.polymer-selected {\n        background: #eee;\n      }\n    </style>\n    ...\n    <polymer-selector>\n      <div class=\"item\">Item 1</div>\n      <div class=\"item\">Item 2</div>\n      <div class=\"item\">Item 3</div>\n    </polymer-selector>"
-        }
-    },
-    "classitems": [
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 42,
-            "description": "Fired when an item's selection state is changed. This event is fired both\nwhen an item is selected or deselected. The `isSelected` detail property\ncontains the selection state.",
-            "itemtype": "event",
-            "name": "polymer-select",
-            "params": [
-                {
-                    "name": "detail",
-                    "description": "",
-                    "type": "Object",
-                    "props": [
-                        {
-                            "name": "isSelected",
-                            "description": "true for selection and false for deselection",
-                            "type": "Boolean"
-                        },
-                        {
-                            "name": "item",
-                            "description": "the item element",
-                            "type": "Object"
-                        }
-                    ]
-                }
-            ],
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 52,
-            "description": "Fired when an item element is tapped.",
-            "itemtype": "event",
-            "name": "polymer-activate",
-            "params": [
-                {
-                    "name": "detail",
-                    "description": "",
-                    "type": "Object",
-                    "props": [
-                        {
-                            "name": "item",
-                            "description": "the item element",
-                            "type": "Object"
-                        }
-                    ]
-                }
-            ],
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 71,
-            "description": "Gets or sets the selected element.  Default to use the index\nof the item element.\n\nIf you want a specific attribute value of the element to be\nused instead of index, set \"valueattr\" to that attribute name.\n\nExample:\n\n    <polymer-selector valueattr=\"label\" selected=\"foo\">\n      <div label=\"foo\"></div>\n      <div label=\"bar\"></div>\n      <div label=\"zot\"></div>\n    </polymer-selector>\n\nIn multi-selection this should be an array of values.\n\nExample:\n\n    <polymer-selector id=\"selector\" valueattr=\"label\" multi>\n      <div label=\"foo\"></div>\n      <div label=\"bar\"></div>\n      <div label=\"zot\"></div>\n    </polymer-selector>\n\n    this.$.selector.selected = ['foo', 'zot'];",
-            "itemtype": "attribute",
-            "name": "selected",
-            "type": "Object",
-            "default": "null",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 103,
-            "description": "If true, multiple selections are allowed.",
-            "itemtype": "attribute",
-            "name": "multi",
-            "type": "boolean",
-            "default": "false",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 111,
-            "description": "Specifies the attribute to be used for \"selected\" attribute.",
-            "itemtype": "attribute",
-            "name": "valueattr",
-            "type": "string",
-            "default": "'name'",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 119,
-            "description": "Specifies the CSS class to be used to add to the selected element.",
-            "itemtype": "attribute",
-            "name": "selectedClass",
-            "type": "string",
-            "default": "'polymer-selected'",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 127,
-            "description": "Specifies the property to be used to set on the selected element\nto indicate its active state.",
-            "itemtype": "attribute",
-            "name": "selectedProperty",
-            "type": "string",
-            "default": "'active'",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 136,
-            "description": "Returns the currently selected element. In multi-selection this returns\nan array of selected elements.",
-            "itemtype": "attribute",
-            "name": "selectedItem",
-            "type": "Object",
-            "default": "null",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 145,
-            "description": "In single selection, this returns the model associated with the\nselected element.",
-            "itemtype": "attribute",
-            "name": "selectedModel",
-            "type": "Object",
-            "default": "null",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 154,
-            "description": "In single selection, this returns the selected index.",
-            "itemtype": "attribute",
-            "name": "selectedIndex",
-            "type": "number",
-            "default": "-1",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 162,
-            "description": "The target element that contains items.  If this is not set \npolymer-selector is the container.",
-            "itemtype": "attribute",
-            "name": "target",
-            "type": "Object",
-            "default": "null",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 171,
-            "description": "This can be used to query nodes from the target node to be used for \nselection items.  Note this only works if the 'target' property is set.\n\nExample:\n\n    <polymer-selector target=\"{{$.myForm}}\" itemsSelector=\"input[type=radio]\"></polymer-selector>\n    <form id=\"myForm\">\n      <label><input type=\"radio\" name=\"color\" value=\"red\"> Red</label> <br>\n      <label><input type=\"radio\" name=\"color\" value=\"green\"> Green</label> <br>\n      <label><input type=\"radio\" name=\"color\" value=\"blue\"> Blue</label> <br>\n      <p>color = {{color}}</p>\n    </form>",
-            "itemtype": "attribute",
-            "name": "itemSelector",
-            "type": "string",
-            "default": "''",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        },
-        {
-            "file": "../../polymer-selector/polymer-selector.html",
-            "line": 190,
-            "description": "The event that would be fired from the item element to indicate\nit is being selected.",
-            "itemtype": "attribute",
-            "name": "activateEvent",
-            "type": "string",
-            "default": "'tap'",
-            "class": "polymer-selector",
-            "module": "Polymer Elements"
-        }
-    ],
-    "warnings": []
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/index.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/index.html
deleted file mode 100644
index 9bb2721..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer api</title>
-  <style>
-    html, body {
-      font-family: Arial, sans-serif;
-      white-space: nowrap;
-      overflow: hidden;
-    }
-    [noviewer] [ifnoviewer] {
-      display: block;
-    }
-    [detector], [ifnoviewer], [noviewer] [ifviewer] {
-      display: none;
-    }
-    [ifviewer], [ifnoviewer] {
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-    }
-    iframe {
-      border: none;
-      margin: 0;
-      width: 100%;
-      height: 100%;
-    }
-    #remote {
-      position: absolute;
-      top: 0;
-      right: 0;
-    }
-  </style>
-  <script src="../platform/platform.js"></script>
-  <link rel="import" href="../polymer-home-page/polymer-home-page.html">
-</head>
-<body>
-  <img detector src="../polymer-home-page/bowager-logo.png" onerror="noviewer()">
-  <polymer-home-page ifviewer></polymer-home-page>
-  <div ifnoviewer>
-    <span id="remote">[remote]</span>
-    <iframe></iframe>
-  </div>
-  <!-- -->
-  <script>
-    var remoteDocs = 'http://turbogadgetry.com/bowertopia/components/';
-    // if no local info viewer, load it remotely
-    function noviewer() {
-      document.body.setAttribute('noviewer', '');
-      var path = location.pathname.split('/');
-      var module = path.pop() || path.pop();
-      document.querySelector('iframe').src = remoteDocs + module;
-      document.querySelector('title').textContent = module;
-    }
-    // for testing only
-    var opts = window.location.search;
-    if (opts.indexOf('noviewer') >= 0) {
-      noviewer();
-    }
-  </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/polymer-selector.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/polymer-selector.html
deleted file mode 100644
index a1dcac2..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/polymer-selector.html
+++ /dev/null
@@ -1,371 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
-/**
- * polymer-selector is used to manage a list of elements that can be selected.
- * The attribute "selected" indicates which item element is being selected.
- * The attribute "multi" indicates if multiple items can be selected at once.
- * Tapping on the item element would fire "polymer-activate" event. Use
- * "polymer-select" event to listen for selection changes.
- *
- * Example:
- *
- *     <polymer-selector selected="0">
- *       <div>Item 1</div>
- *       <div>Item 2</div>
- *       <div>Item 3</div>
- *     </polymer-selector>
- *
- * polymer-selector is not styled.  So one needs to use "polymer-selected" CSS
- * class to style the selected element.
- * 
- *     <style>
- *       .item.polymer-selected {
- *         background: #eee;
- *       }
- *     </style>
- *     ...
- *     <polymer-selector>
- *       <div class="item">Item 1</div>
- *       <div class="item">Item 2</div>
- *       <div class="item">Item 3</div>
- *     </polymer-selector>
- *
- * @class polymer-selector
- * @status stable
- */
-/**
- * Fired when an item's selection state is changed. This event is fired both
- * when an item is selected or deselected. The `isSelected` detail property
- * contains the selection state.
- * 
- * @event polymer-select
- * @param {Object} detail
- *   @param {boolean} detail.isSelected true for selection and false for deselection
- *   @param {Object} detail.item the item element
- */
-/**
- * Fired when an item element is tapped.
- * 
- * @event polymer-activate
- * @param {Object} detail
- *   @param {Object} detail.item the item element
- */
--->
-<link rel="import" href="../polymer/polymer.html">
-<link rel="import" href="../polymer-selection/polymer-selection.html">
-
-<polymer-element name="polymer-selector"
-    attributes="selected multi valueattr selectedClass selectedProperty selectedAttribute selectedItem selectedModel selectedIndex notap target itemsSelector activateEvent">
-  <template>
-    <polymer-selection id="selection" multi="{{multi}}" on-polymer-select="{{selectionSelect}}"></polymer-selection>
-    <content id="items" select="*"></content>
-  </template>
-  <script>
-    Polymer('polymer-selector', {
-      /**
-       * Gets or sets the selected element.  Default to use the index
-       * of the item element.
-       *
-       * If you want a specific attribute value of the element to be
-       * used instead of index, set "valueattr" to that attribute name.
-       *
-       * Example:
-       *
-       *     <polymer-selector valueattr="label" selected="foo">
-       *       <div label="foo"></div>
-       *       <div label="bar"></div>
-       *       <div label="zot"></div>
-       *     </polymer-selector>
-       *
-       * In multi-selection this should be an array of values.
-       *
-       * Example:
-       *
-       *     <polymer-selector id="selector" valueattr="label" multi>
-       *       <div label="foo"></div>
-       *       <div label="bar"></div>
-       *       <div label="zot"></div>
-       *     </polymer-selector>
-       *
-       *     this.$.selector.selected = ['foo', 'zot'];
-       *
-       * @attribute selected
-       * @type Object
-       * @default null
-       */
-      selected: null,
-      /**
-       * If true, multiple selections are allowed.
-       *
-       * @attribute multi
-       * @type boolean
-       * @default false
-       */
-      multi: false,
-      /**
-       * Specifies the attribute to be used for "selected" attribute.
-       *
-       * @attribute valueattr
-       * @type string
-       * @default 'name'
-       */
-      valueattr: 'name',
-      /**
-       * Specifies the CSS class to be used to add to the selected element.
-       * 
-       * @attribute selectedClass
-       * @type string
-       * @default 'polymer-selected'
-       */
-      selectedClass: 'polymer-selected',
-      /**
-       * Specifies the property to be used to set on the selected element
-       * to indicate its active state.
-       *
-       * @attribute selectedProperty
-       * @type string
-       * @default ''
-       */
-      selectedProperty: '',
-      /**
-       * Specifies the property to be used to set on the selected element
-       * to indicate its active state.
-       *
-       * @attribute selectedProperty
-       * @type string
-       * @default 'active'
-       */
-      selectedAttribute: 'active',
-      /**
-       * Returns the currently selected element. In multi-selection this returns
-       * an array of selected elements.
-       * 
-       * @attribute selectedItem
-       * @type Object
-       * @default null
-       */
-      selectedItem: null,
-      /**
-       * In single selection, this returns the model associated with the
-       * selected element.
-       * 
-       * @attribute selectedModel
-       * @type Object
-       * @default null
-       */
-      selectedModel: null,
-      /**
-       * In single selection, this returns the selected index.
-       *
-       * @attribute selectedIndex
-       * @type number
-       * @default -1
-       */
-      selectedIndex: -1,
-      /**
-       * The target element that contains items.  If this is not set 
-       * polymer-selector is the container.
-       * 
-       * @attribute target
-       * @type Object
-       * @default null
-       */
-      target: null,
-      /**
-       * This can be used to query nodes from the target node to be used for 
-       * selection items.  Note this only works if the 'target' property is set.
-       *
-       * Example:
-       *
-       *     <polymer-selector target="{{$.myForm}}" itemsSelector="input[type=radio]"></polymer-selector>
-       *     <form id="myForm">
-       *       <label><input type="radio" name="color" value="red"> Red</label> <br>
-       *       <label><input type="radio" name="color" value="green"> Green</label> <br>
-       *       <label><input type="radio" name="color" value="blue"> Blue</label> <br>
-       *       <p>color = {{color}}</p>
-       *     </form>
-       * 
-       * @attribute itemSelector
-       * @type string
-       * @default ''
-       */
-      itemsSelector: '',
-      /**
-       * The event that would be fired from the item element to indicate
-       * it is being selected.
-       *
-       * @attribute activateEvent
-       * @type string
-       * @default 'tap'
-       */
-      activateEvent: 'tap',
-      notap: false,
-      ready: function() {
-        this.activateListener = this.activateHandler.bind(this);
-        this.observer = new MutationObserver(this.updateSelected.bind(this));
-        if (!this.target) {
-          this.target = this;
-        }
-      },
-      get items() {
-        var nodes = this.target !== this ? (this.itemsSelector ? 
-            this.target.querySelectorAll(this.itemsSelector) : 
-                this.target.children) : this.$.items.getDistributedNodes();
-        return Array.prototype.filter.call(nodes || [], function(n) {
-          return n && n.localName !== 'template';
-        });
-      },
-      targetChanged: function(old) {
-        if (old) {
-          this.removeListener(old);
-          this.observer.disconnect();
-        }
-        if (this.target) {
-          this.addListener(this.target);
-          this.observer.observe(this.target, {childList: true});
-        }
-      },
-      addListener: function(node) {
-        node.addEventListener(this.activateEvent, this.activateListener);
-      },
-      removeListener: function(node) {
-        node.removeEventListener(this.activateEvent, this.activateListener);
-      },
-      get selection() {
-        return this.$.selection.getSelection();
-      },
-      selectedChanged: function() {
-        this.updateSelected();
-      },
-      updateSelected: function() {
-        this.validateSelected();
-        if (this.multi) {
-          this.clearSelection();
-          this.selected && this.selected.forEach(function(s) {
-            this.valueToSelection(s);
-          }, this);
-        } else {
-          this.valueToSelection(this.selected);
-        }
-      },
-      validateSelected: function() {
-        // convert to an array for multi-selection
-        if (this.multi && !Array.isArray(this.selected) && 
-            this.selected !== null && this.selected !== undefined) {
-          this.selected = [this.selected];
-        }
-      },
-      clearSelection: function() {
-        if (this.multi) {
-          this.selection.slice().forEach(function(s) {
-            this.$.selection.setItemSelected(s, false);
-          }, this);
-        } else {
-          this.$.selection.setItemSelected(this.selection, false);
-        }
-        this.selectedItem = null;
-        this.$.selection.clear();
-      },
-      valueToSelection: function(value) {
-        var item = (value === null || value === undefined) ? 
-            null : this.items[this.valueToIndex(value)];
-        this.$.selection.select(item);
-      },
-      updateSelectedItem: function() {
-        this.selectedItem = this.selection;
-      },
-      selectedItemChanged: function() {
-        if (this.selectedItem) {
-          var t = this.selectedItem.templateInstance;
-          this.selectedModel = t ? t.model : undefined;
-        } else {
-          this.selectedModel = null;
-        }
-        this.selectedIndex = this.selectedItem ? 
-            parseInt(this.valueToIndex(this.selected)) : -1;
-      },
-      valueToIndex: function(value) {
-        // find an item with value == value and return it's index
-        for (var i=0, items=this.items, c; (c=items[i]); i++) {
-          if (this.valueForNode(c) == value) {
-            return i;
-          }
-        }
-        // if no item found, the value itself is probably the index
-        return value;
-      },
-      valueForNode: function(node) {
-        return node[this.valueattr] || node.getAttribute(this.valueattr);
-      },
-      // events fired from <polymer-selection> object
-      selectionSelect: function(e, detail) {
-        this.updateSelectedItem();
-        if (detail.item) {
-          this.applySelection(detail.item, detail.isSelected);
-        }
-      },
-      applySelection: function(item, isSelected) {
-        if (this.selectedClass) {
-          item.classList.toggle(this.selectedClass, isSelected);
-        }
-        if (this.selectedProperty) {
-          item[this.selectedProperty] = isSelected;
-        }
-        if (this.selectedAttribute && item.setAttribute) {
-          if (isSelected) {
-            item.setAttribute(this.selectedAttribute, '');
-          } else {
-            item.removeAttribute(this.selectedAttribute);
-          }
-        }
-      },
-      // event fired from host
-      activateHandler: function(e) {
-        if (!this.notap) {
-          var i = this.findDistributedTarget(e.target, this.items);
-          if (i >= 0) {
-            var item = this.items[i];
-            var s = this.valueForNode(item) || i;
-            if (this.multi) {
-              if (this.selected) {
-                this.addRemoveSelected(s);
-              } else {
-                this.selected = [s];
-              }
-            } else {
-              this.selected = s;
-            }
-            this.asyncFire('polymer-activate', {item: item});
-          }
-        }
-      },
-      addRemoveSelected: function(value) {
-        var i = this.selected.indexOf(value);
-        if (i >= 0) {
-          this.selected.splice(i, 1);
-        } else {
-          this.selected.push(value);
-        }
-        this.valueToSelection(value);
-      },
-      findDistributedTarget: function(target, nodes) {
-        // find first ancestor of target (including itself) that
-        // is in nodes, if any
-        while (target && target != this) {
-          var i = Array.prototype.indexOf.call(nodes, target);
-          if (i >= 0) {
-            return i;
-          }
-          target = target.parentNode;
-        }
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-activate-event.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-activate-event.html
deleted file mode 100644
index a552a68..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-activate-event.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selector-activate-event</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selector.html">
-  <style>
-    .polymer-selected {
-      background: #ccc;
-    }
-  </style>
-</head>
-<body>
-
-  <polymer-selector id="selector" selected="0">
-    <div>Item 1</div>
-    <div>Item 2</div>
-    <div>Item 3</div>
-    <div>Item 4</div>
-    <div>Item 5</div>
-  </polymer-selector>
-  
-  <script>
-    var assert = chai.assert;
-    document.addEventListener('polymer-ready', function() {
-      var s = document.querySelector('#selector');
-      s.addEventListener("polymer-activate", function(event) {
-        assert.equal(event.detail.item, s.children[1]);
-        assert.equal(s.selected, 1);
-        done();
-      });
-      assert.equal(s.selected, '0');
-      requestAnimationFrame(function() {
-        s.children[1].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
-      });
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-basic.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-basic.html
deleted file mode 100644
index 37d57eb..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-basic.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selector-basic</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selector.html">
-  <style>
-    .polymer-selected {
-      background: #ccc;
-    }
-    
-    .my-selected {
-      background: red;
-    }
-  </style>
-</head>
-<body>
-
-  <polymer-selector id="selector1">
-    <div>Item 1</div>
-    <div>Item 2</div>
-    <div>Item 3</div>
-    <div>Item 4</div>
-    <div>Item 5</div>
-  </polymer-selector>
-  
-  <br><br>
-  
-  <polymer-selector id="selector2" selected="item3" selectedClass="my-selected" valueattr="id">
-    <div id="item1">Item 1</div>
-    <div id="item2">Item 2</div>
-    <div id="item3">Item 3</div>
-    <div id="item4">Item 4</div>
-    <div id="item5">Item 5</div>
-  </polymer-selector>
-  
-  <script>
-    var assert = chai.assert;
-    var async = requestAnimationFrame;
-    
-    function oneMutation(node, options, cb) {
-      var o = new MutationObserver(function() {
-        cb();
-        o.disconnect();
-      });
-      o.observe(node, options);
-    }
-    
-    document.addEventListener('polymer-ready', function() {
-      // selector1
-      var s = document.querySelector('#selector1');
-      assert.equal(s.selected, null);
-      assert.equal(s.selectedClass, 'polymer-selected');
-      assert.isFalse(s.multi);
-      assert.equal(s.valueattr, 'name');
-      assert.equal(s.items.length, 5);
-      // selector2
-      s = document.querySelector('#selector2');
-      assert.equal(s.selected, "item3");
-      assert.equal(s.selectedClass, 'my-selected');
-      // setup listener for polymer-select event
-      var selectEventCounter = 0;
-      s.addEventListener('polymer-select', function(e) {
-        if (e.detail.isSelected) {
-          selectEventCounter++;
-          // selectedItem and detail.item should be the same
-          assert.equal(e.detail.item, s.selectedItem);
-        }
-      });
-      // set selected
-      s.selected = 'item5';
-      Platform.flush();
-      oneMutation(s, {attributes: true}, function() {
-        // check polymer-select event
-        assert.equal(selectEventCounter, 1);
-        // check selected class
-        assert.isTrue(s.children[4].classList.contains('my-selected'));
-        // check selectedItem
-        assert.equal(s.selectedItem, s.children[4]);
-        // selecting the same value shouldn't fire polymer-select
-        selectEventCounter = 0;
-        s.selected = 'item5';
-        Platform.flush();
-        // TODO(ffu): would be better to wait for something to happen
-        // instead of not to happen
-        setTimeout(function() {
-          assert.equal(selectEventCounter, 0);
-          done();
-        }, 50);
-      });
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-multi.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-multi.html
deleted file mode 100644
index 755e7fd..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/html/polymer-selector-multi.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>polymer-selector-multi</title>
-  <script src="../../../platform/platform.js"></script>
-  <script src="../../../tools/test/htmltest.js"></script>
-  <script src="../../../tools/test/chai/chai.js"></script>
-  <link rel="import" href="../../polymer-selector.html">
-  <style>
-    .polymer-selected {
-      background: #ccc;
-    }
-  </style>
-</head>
-<body>
-
-  <polymer-selector id="selector" multi>
-    <div>Item 1</div>
-    <div>Item 2</div>
-    <div>Item 3</div>
-    <div>Item 4</div>
-    <div>Item 5</div>
-  </polymer-selector>
-  
-  <script>
-    var assert = chai.assert;
-    
-    function oneMutation(node, options, cb) {
-      var o = new MutationObserver(function() {
-        cb();
-        o.disconnect();
-      });
-      o.observe(node, options);
-    }
-    
-    document.addEventListener('polymer-ready', function() {
-      //
-      var s = document.querySelector('#selector');
-      assert.equal(s.selected, null);
-      assert.equal(s.selectedClass, 'polymer-selected');
-      assert.isTrue(s.multi);
-      assert.equal(s.valueattr, 'name');
-      assert.equal(s.items.length, 5);
-      // setup listener for polymer-select event
-      var selectEventCounter = 0;
-      s.addEventListener('polymer-select', function(e) {
-        if (e.detail.isSelected) {
-          selectEventCounter++;
-        } else {
-          selectEventCounter--;
-        }
-        // check selectedItem in polymer-select event
-        assert.equal(this.selectedItem.length, selectEventCounter);
-      });
-      // set selected
-      s.selected = [0, 2];
-      Platform.flush();
-      oneMutation(s, {attributes: true}, function() {
-        // check polymer-select event
-        assert.equal(selectEventCounter, 2);
-        // check selected class
-        assert.isTrue(s.children[0].classList.contains('polymer-selected'));
-        assert.isTrue(s.children[2].classList.contains('polymer-selected'));
-        // check selectedItem
-        assert.equal(s.selectedItem.length, 2);
-        assert.equal(s.selectedItem[0], s.children[0]);
-        assert.equal(s.selectedItem[1], s.children[2]);
-        // tap on already selected element should unselect it
-        s.children[0].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
-        // check selected
-        assert.equal(s.selected.length, 1);
-        assert.isFalse(s.children[0].classList.contains('polymer-selected'));
-        done();
-      });
-    });
-  </script>
-</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/js/polymer-selector.js b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/js/polymer-selector.js
deleted file mode 100644
index 537fa39..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/js/polymer-selector.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/*

- * Copyright 2013 The Polymer Authors. All rights reserved.

- * Use of this source code is governed by a BSD-style

- * license that can be found in the LICENSE file.

- */

-

-htmlSuite('polymer-selector', function() {

-  htmlTest('html/polymer-selector-basic.html');

-  htmlTest('html/polymer-selector-activate-event.html');

-  htmlTest('html/polymer-selector-multi.html');

-});
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/runner.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/runner.html
deleted file mode 100644
index 378815f..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer-selector/test/runner.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<html>
-  <head>
-    <title>polymer-selector Test Runner (Mocha)</title>
-    <meta charset="UTF-8">
-    <!-- -->
-    <link rel="stylesheet" href="../../tools/test/mocha/mocha.css" />
-    <script src="../../tools/test/mocha/mocha.js"></script>
-    <script src="../../tools/test/chai/chai.js"></script>
-    <script src="../../tools/test/mocha-htmltest.js"></script>
-    <!-- -->
-    <script src="../../platform/platform.js"></script>
-  </head>
-  <body>
-    <div id="mocha"></div>
-    <script>
-      mocha.setup({ui: 'tdd', slow: 1000, htmlbase: ''});
-    </script>
-    <!-- -->
-    <script src="js/polymer-selector.js"></script>
-    <!-- -->
-    <script>
-      mocha.run();
-    </script>
-  </body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/.bower.json
deleted file mode 100644
index 86c1530..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/.bower.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-  "name": "polymer",
-  "description": "Polymer is a new type of library for the web, built on top of Web Components, and designed to leverage the evolving web platform on modern browsers.",
-  "homepage": "http://www.polymer-project.org/",
-  "keywords": [
-    "util",
-    "client",
-    "browser",
-    "web components",
-    "web-components"
-  ],
-  "author": "Polymer Authors <polymer-dev@googlegroups.com>",
-  "main": [
-    "polymer.js"
-  ],
-  "dependencies": {
-    "platform": "Polymer/platform#0.2.1"
-  },
-  "version": "0.2.1",
-  "_release": "0.2.1",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.2.1",
-    "commit": "62ec4216813ccd9344cf419da846b623892f0884"
-  },
-  "_source": "git://github.com/Polymer/polymer.git",
-  "_target": "0.2.1",
-  "_originalSource": "Polymer/polymer"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/AUTHORS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/CONTRIBUTING.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/CONTRIBUTING.md
deleted file mode 100644
index 1de2f34..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/CONTRIBUTING.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Contributing
-
-Want to contribute to Polymer? Great!
-
-We are more than happy to accept external contributions to the project in the form of [feedback](https://groups.google.com/forum/?fromgroups=#!forum/polymer-dev), [bug reports](../../issues), and pull requests.
-
-## Contributor License Agreement
-
-Before we can accept patches, there's a quick web form you need to fill out.
-
-- If you're contributing as an individual (e.g. you own the intellectual property), fill out [this form](http://code.google.com/legal/individual-cla-v1.0.html).
-- If you're contributing under a company, fill out [this form](http://code.google.com/legal/corporate-cla-v1.0.html) instead.
-
-This CLA asserts that contributions are owned by you and that we can license all work under our [license](LICENSE).
-
-Other projects require a similar agreement: jQuery, Firefox, Apache, Node, and many more.
-
-[More about CLAs](https://www.google.com/search?q=Contributor%20License%20Agreement)
-
-## Initial setup
-
-Here's an easy guide that should get you up and running:
-
-1. Setup Grunt: `sudo npm install -g grunt-cli`
-1. Fork the project on github and pull down your copy.
-   > replace the {{ username }} with your username and {{ repository }} with the repository name
-
-        git clone git@github.com:{{ username }}/{{ repository }}.git --recursive
-
-    Note the `--recursive`. This is necessary for submodules to initialize properly. If you don't do a recursive clone, you'll have to init them manually:
-
-        git submodule init
-        git submodule update
-
-    Download and run the `pull-all.sh` script to install the sibling dependencies.
-
-        git clone git://github.com/Polymer/tools.git && tools/bin/pull-all.sh
-
-1. Test your change
-   > in the repo you've made changes to, run the tests:
-
-        cd $REPO
-        npm install
-        grunt test
-
-1. Commit your code and make a pull request.
-
-That's it for the one time setup. Now you're ready to make a change.
-
-## Submitting a pull request
-
-We iterate fast! To avoid potential merge conflicts, it's a good idea to pull from the main project before making a change and submitting a pull request. The easiest way to do this is setup a remote called `upstream` and do a pull before working on a change:
-
-    git remote add upstream git://github.com/Polymer/{{ repository }}.git
-
-Then before making a change, do a pull from the upstream `master` branch:
-
-    git pull upstream master
-
-To make life easier, add a "pull upstream" alias in your `.gitconfig`:
-
-    [alias]
-      pu = !"git fetch origin -v; git fetch upstream -v; git merge upstream/master"
-
-That will pull in changes from your forked repo, the main (upstream) repo, and merge the two. Then it's just a matter of running `git pu` before a change and pushing to your repo:
-
-    git checkout master
-    git pu
-    # make change
-    git commit -a -m 'Awesome things.'
-    git push
-
-Lastly, don't forget to submit the pull request.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/LICENSE b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/LICENSE
deleted file mode 100644
index 95987ba..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2014 The Polymer Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/PATENTS b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/README.md b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/README.md
deleted file mode 100644
index 236a88c..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Polymer
-
-[![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/polymer/README)](https://github.com/igrigorik/ga-beacon)
-
-Build Status: [http://build.chromium.org/p/client.polymer/waterfall](http://build.chromium.org/p/client.polymer/waterfall)
-
-## Brief Overview
-
-For more detailed info goto [http://polymer-project.org/](http://polymer-project.org/).
-
-Polymer is a new type of library for the web, designed to leverage the existing browser infrastructure to provide the encapsulation and extendability currently only available in JS libraries.
-
-Polymer is based on a set of future technologies, including [Shadow DOM](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html), [Custom Elements](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html) and Model Driven Views. Currently these technologies are implemented as polyfills or shims, but as browsers adopt these features natively, the platform code that drives Polymer evacipates, leaving only the value-adds.
-
-## Tools & Testing
-
-For running tests or building minified files, consult the [tooling information](http://www.polymer-project.org/resources/tooling-strategy.html).
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/bower.json
deleted file mode 100644
index bd7a8ea..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/bower.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "name": "polymer",
-  "description": "Polymer is a new type of library for the web, built on top of Web Components, and designed to leverage the evolving web platform on modern browsers.",
-  "homepage": "http://www.polymer-project.org/",
-  "keywords": [
-    "util",
-    "client",
-    "browser",
-    "web components",
-    "web-components"
-  ],
-  "author": "Polymer Authors <polymer-dev@googlegroups.com>",
-  "main": [
-    "polymer.js"
-  ],
-  "dependencies": {
-    "platform": "Polymer/platform#0.2.1"
-  },
-  "version": "0.2.1"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer-body.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer-body.html
deleted file mode 100644
index 5f07a01..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer-body.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<polymer-element name="polymer-body" extends="body">
-
-  <script>
-
-  // upgrade polymer-body last so that it can contain other imported elements
-  document.addEventListener('polymer-ready', function() {
-    
-    Polymer('polymer-body', Platform.mixin({
-
-      created: function() {
-        this.template = document.createElement('template');
-        var body = wrap(document).body;
-        var c$ = body.childNodes.array();
-        for (var i=0, c; (c=c$[i]); i++) {
-          if (c.localName !== 'script') {
-            this.template.content.appendChild(c);
-          }
-        }
-        // snarf up user defined model
-        window.model = this;
-      },
-
-      parseDeclaration: function(elementElement) {
-        this.lightFromTemplate(this.template);
-      }
-
-    }, window.model));
-
-  });
-
-  </script>
-
-</polymer-element>
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.html b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.html
deleted file mode 100644
index ae23866..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!--
- Copyright 2013 The Polymer Authors. All rights reserved.
- Use of this source code is governed by a BSD-style
- license that can be found in the LICENSE file.
--->
-<script src="polymer.js"></script>
-<!-- <link rel="import" href="../polymer-dev/polymer.html"> -->
-<link rel="import" href="polymer-body.html">
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js
deleted file mode 100644
index f4d249f..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @license
- * Copyright (c) 2012-2014 The Polymer Authors. All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- *    * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *    * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-// @version: 0.2.1
-Polymer={},"function"==typeof window.Polymer&&(Polymer={}),function(a){function b(a,b){return a&&b&&Object.getOwnPropertyNames(b).forEach(function(c){var d=Object.getOwnPropertyDescriptor(b,c);d&&(Object.defineProperty(a,c,d),"function"==typeof d.value&&(d.value.nom=c))}),a}a.extend=b}(Polymer),function(a){function b(a,b,d){return a?a.stop():a=new c(this),a.go(b,d),a}var c=function(a){this.context=a,this.boundComplete=this.complete.bind(this)};c.prototype={go:function(a,b){this.callback=a;var c;b?(c=setTimeout(this.boundComplete,b),this.handle=function(){clearTimeout(c)}):(c=requestAnimationFrame(this.boundComplete),this.handle=function(){cancelAnimationFrame(c)})},stop:function(){this.handle&&(this.handle(),this.handle=null)},complete:function(){this.handle&&(this.stop(),this.callback.call(this.context))}},a.job=b}(Polymer),function(){var a={};HTMLElement.register=function(b,c){a[b]=c},HTMLElement.getPrototypeForTag=function(b){var c=b?a[b]:HTMLElement.prototype;return c||Object.getPrototypeOf(document.createElement(b))};var b=Event.prototype.stopPropagation;Event.prototype.stopPropagation=function(){this.cancelBubble=!0,b.apply(this,arguments)}}(Polymer),function(a){function b(a){var c=b.caller,g=c.nom,h=c._super;if(h||(g||(g=c.nom=e.call(this,c)),g||console.warn("called super() on a method not installed declaratively (has no .nom property)"),h=d(c,g,f(this))),h){var i=h[g];return i._super||d(i,g,h),i.apply(this,a||[])}}function c(a,b,c){for(;a;){if(a[b]!==c&&a[b])return a;a=f(a)}}function d(a,b,d){return a._super=c(d,b,a),a._super&&(a._super[b].nom=b),a._super}function e(a){for(var b=this.__proto__;b&&b!==HTMLElement.prototype;){for(var c,d=Object.getOwnPropertyNames(b),e=0,f=d.length;f>e&&(c=d[e]);e++){var g=Object.getOwnPropertyDescriptor(b,c);if("function"==typeof g.value&&g.value===a)return c}b=b.__proto__}}function f(a){return a.__proto__}a.super=b}(Polymer),function(a){function b(a,b){var d=typeof b;return b instanceof Date&&(d="date"),c[d](a,b)}var c={string:function(a){return a},date:function(a){return new Date(Date.parse(a)||Date.now())},"boolean":function(a){return""===a?!0:"false"===a?!1:!!a},number:function(a){var b=parseFloat(a);return 0===b&&(b=parseInt(a)),isNaN(b)?a:b},object:function(a,b){if(null===b)return a;try{return JSON.parse(a.replace(/'/g,'"'))}catch(c){return a}},"function":function(a,b){return b}};a.deserializeValue=b}(Polymer),function(a){var b=a.extend,c={};c.declaration={},c.instance={},c.publish=function(a,c){for(var d in a)b(c,a[d])},a.api=c}(Polymer),function(a){var b={async:function(a,b,c){Platform.flush(),b=b&&b.length?b:[b];var d=function(){(this[a]||a).apply(this,b)}.bind(this),e=c?setTimeout(d,c):requestAnimationFrame(d);return c?e:1/e},cancelAsync:function(a){1>a?cancelAnimationFrame(Math.round(1/a)):clearTimeout(a)},fire:function(a,b,c,d,e){var f=c||this,b=b||{},g=new CustomEvent(a,{bubbles:void 0!==d?d:!0,cancelable:void 0!==e?e:!0,detail:b});return f.dispatchEvent(g),g},asyncFire:function(){this.async("fire",arguments)},classFollows:function(a,b,c){b&&b.classList.remove(c),a&&a.classList.add(c)}},c=function(){},d={};b.asyncMethod=b.async,a.api.instance.utils=b,a.nop=c,a.nob=d}(Polymer),function(a){var b=window.logFlags||{},c="on-",d={EVENT_PREFIX:c,addHostListeners:function(){var a=this.eventDelegates;b.events&&Object.keys(a).length>0&&console.log("[%s] addHostListeners:",this.localName,a);var d,e,f=this;for(var g in a)e=c+g,(d=PolymerExpressions.prepareEventBinding(Path.get(a[g]),e,{resolveEventHandler:function(a,b){var c=b.getValueFrom(f);return c?c.bind(f):void 0}}))(this,this,!1)},dispatchMethod:function(a,c,d){if(a){b.events&&console.group("[%s] dispatch [%s]",a.localName,c);var e="function"==typeof c?c:a[c];e&&e[d?"apply":"call"](a,d),b.events&&console.groupEnd(),Platform.flush()}}};a.api.instance.events=d}(Polymer),function(a){var b={copyInstanceAttributes:function(){var a=this._instanceAttributes;for(var b in a)this.hasAttribute(b)||this.setAttribute(b,a[b])},takeAttributes:function(){if(this._publishLC)for(var a,b=0,c=this.attributes,d=c.length;(a=c[b])&&d>b;b++)this.attributeToProperty(a.name,a.value)},attributeToProperty:function(b,c){var b=this.propertyForAttribute(b);if(b){if(c&&c.search(a.bindPattern)>=0)return;var d=this[b],c=this.deserializeValue(c,d);c!==d&&(this[b]=c)}},propertyForAttribute:function(a){var b=this._publishLC&&this._publishLC[a];return b},deserializeValue:function(b,c){return a.deserializeValue(b,c)},serializeValue:function(a,b){return"boolean"===b?a?"":void 0:"object"!==b&&"function"!==b&&void 0!==a?a:void 0},reflectPropertyToAttribute:function(a){var b=typeof this[a],c=this.serializeValue(this[a],b);void 0!==c?this.setAttribute(a,c):"boolean"===b&&this.removeAttribute(a)}};a.api.instance.attributes=b}(Polymer),function(a){function b(a,b,d){c.bind&&console.log(e,inB.localName||"object",inPath,a.localName,b);var f=d.discardChanges();return(null===f||void 0===f)&&d.setValue(a[b]),Observer.defineComputedProperty(a,b,d)}var c=window.logFlags||{},d={observeProperties:function(){var a=this._observeNames,b=this._publishNames;if(a&&a.length||b&&b.length){for(var c,d=this._propertyObserver=new CompoundObserver,e=0,f=a.length;f>e&&(c=a[e]);e++){d.addPath(this,c);var g=Object.getOwnPropertyDescriptor(this.__proto__,c);g&&g.value&&this.observeArrayValue(c,g.value,null)}for(var c,e=0,f=b.length;f>e&&(c=b[e]);e++)this.observe&&void 0!==this.observe[c]||d.addPath(this,c);d.open(this.notifyPropertyChanges,this)}},notifyPropertyChanges:function(a,b,c){var d,e,f={};for(var g in b)d=c[2*g+1],void 0!==this.publish[d]&&this.reflectPropertyToAttribute(d),e=this.observe[d],e&&(this.observeArrayValue(d,a[g],b[g]),f[e]||(f[e]=!0,this.invokeMethod(e,[b[g],a[g],arguments])))},observeArrayValue:function(a,b,d){var e=this.observe[a];if(e&&(Array.isArray(d)&&(c.observe&&console.log("[%s] observeArrayValue: unregister observer [%s]",this.localName,a),this.unregisterObserver(a+"__array")),Array.isArray(b))){c.observe&&console.log("[%s] observeArrayValue: register observer [%s]",this.localName,a,b);var f=new ArrayObserver(b);f.open(function(a,b){this.invokeMethod(e,[b])},this),this.registerObserver(a+"__array",f)}},bindProperty:function(a,c){return b(this,a,c)},unbindAllProperties:function(){this._propertyObserver&&this._propertyObserver.close(),this.unregisterObservers()},unbindProperty:function(a){return this.unregisterObserver(a)},invokeMethod:function(a,b){var c=this[a]||a;"function"==typeof c&&c.apply(this,b)},registerObserver:function(a,b){var c=this._observers||(this._observers={});c[a]=b},unregisterObserver:function(a){var b=this._observers;return b&&b[a]?(b[a].close(),b[a]=null,!0):void 0},unregisterObservers:function(){if(this._observers){for(var a,b,c=Object.keys(this._observers),d=0,e=c.length;e>d&&(a=c[d]);d++)b=this._observers[a],b.close();this._observers={}}}},e="[%s]: bindProperties: [%s] to [%s].[%s]";a.api.instance.properties=d}(Polymer),function(a){function b(a){for(;a.parentNode;){if(a.lightDomController)return a;a=a.parentNode}return a.host}function c(a){e(a,d)}function d(a){a.unbindAll()}function e(a,b){if(a){b(a);for(var c=a.firstChild;c;c=c.nextSibling)e(c,b)}}var f=window.logFlags||0,g=(a.api.instance.events,new PolymerExpressions);g.resolveEventHandler=function(a,c,d){var e=b(d);if(e){var f=c.getValueFrom(e);if(f)return f.bind(e)}};var h={syntax:g,instanceTemplate:function(a){return a.createInstance(this,this.syntax)},bind:function(a,b){this._elementPrepared||this.prepareElement();var c=this.propertyForAttribute(a);if(c){this.unbind(a);var d=this.bindProperty(c,b);return d.path=b.path_,this.reflectPropertyToAttribute(c),this.bindings[a]=d}return this.mixinSuper(arguments)},asyncUnbindAll:function(){this._unbound||(f.unbind&&console.log("[%s] asyncUnbindAll",this.localName),this._unbindAllJob=this.job(this._unbindAllJob,this.unbindAll,0))},unbindAll:function(){if(!this._unbound){this.unbindAllProperties(),this.super();for(var a=this.shadowRoot;a;)c(a),a=a.olderShadowRoot;this._unbound=!0}},cancelUnbindAll:function(a){return this._unbound?void(f.unbind&&console.warn("[%s] already unbound, cannot cancel unbindAll",this.localName)):(f.unbind&&console.log("[%s] cancelUnbindAll",this.localName),this._unbindAllJob&&(this._unbindAllJob=this._unbindAllJob.stop()),void(a||e(this.shadowRoot,function(a){a.cancelUnbindAll&&a.cancelUnbindAll()})))}},i=/\{\{([^{}]*)}}/;a.bindPattern=i,a.api.instance.mdv=h}(Polymer),function(a){function b(a){return a.hasOwnProperty("PolymerBase")}function c(){}var d=0,e={PolymerBase:!0,job:Polymer.job,"super":Polymer.super,created:function(){},ready:function(){},createdCallback:function(){this.created(),(this.ownerDocument.defaultView||this.alwaysPrepare||d>0)&&this.prepareElement()},prepareElement:function(){this._elementPrepared=!0,this.shadowRoots={},this.observeProperties(),this.copyInstanceAttributes(),this.takeAttributes(),this.addHostListeners(),d++,this.parseDeclarations(this.__proto__),d--,this.removeAttribute("unresolved"),this.ready()},attachedCallback:function(){this._elementPrepared||this.prepareElement(),this.cancelUnbindAll(!0),this.attached&&this.attached(),this.enteredView&&this.enteredView(),this.hasBeenAttached||(this.hasBeenAttached=!0,this.domReady&&this.async("domReady"))},detachedCallback:function(){this.preventDispose||this.asyncUnbindAll(),this.detached&&this.detached(),this.leftView&&this.leftView()},enteredViewCallback:function(){this.attachedCallback()},leftViewCallback:function(){this.detachedCallback()},enteredDocumentCallback:function(){this.attachedCallback()},leftDocumentCallback:function(){this.detachedCallback()},parseDeclarations:function(a){a&&a.element&&(this.parseDeclarations(a.__proto__),a.parseDeclaration.call(this,a.element))},parseDeclaration:function(a){var b=this.fetchTemplate(a);if(b){var c=this.shadowFromTemplate(b);this.shadowRoots[a.name]=c}},fetchTemplate:function(a){return a.querySelector("template")},shadowFromTemplate:function(a){if(a){var b=this.createShadowRoot();b.resetStyleInheritance=this.resetStyleInheritance;var c=this.instanceTemplate(a);return b.appendChild(c),this.shadowRootReady(b,a),b}},lightFromTemplate:function(a){if(a){this.lightDomController=!0;var b=this.instanceTemplate(a);return this.appendChild(b),this.shadowRootReady(this,a),b}},shadowRootReady:function(a){this.marshalNodeReferences(a),PointerGestures.register(a)},marshalNodeReferences:function(a){var b=this.$=this.$||{};if(a)for(var c,d=a.querySelectorAll("[id]"),e=0,f=d.length;f>e&&(c=d[e]);e++)b[c.id]=c},attributeChangedCallback:function(a){"class"!==a&&"style"!==a&&this.attributeToProperty(a,this.getAttribute(a)),this.attributeChanged&&this.attributeChanged.apply(this,arguments)},onMutation:function(a,b){var c=new MutationObserver(function(a){b.call(this,c,a),c.disconnect()}.bind(this));c.observe(a,{childList:!0,subtree:!0})}};c.prototype=e,e.constructor=c,a.Base=c,a.isBase=b,a.api.instance.base=e}(Polymer),function(a){function b(a){return a.__proto__}function c(a,b){var c="",d=!1;b&&(c=b.localName,d=b.hasAttribute("is"));var e=Platform.ShadowCSS.makeScopeSelector(c,d);return Platform.ShadowCSS.shimCssText(a,e)}var d=(window.logFlags||{},"element"),e="controller",f={STYLE_SCOPE_ATTRIBUTE:d,installControllerStyles:function(){var a=this.findStyleScope();if(a&&!this.scopeHasNamedStyle(a,this.localName)){for(var c=b(this),d="";c&&c.element;)d+=c.element.cssTextForScope(e),c=b(c);d&&this.installScopeCssText(d,a)}},installScopeStyle:function(a,b){var c=this.findStyleScope(),b=b||"";if(c&&!this.scopeHasNamedStyle(c,this.localName+b)){var d="";if(a instanceof Array)for(var e,f=0,g=a.length;g>f&&(e=a[f]);f++)d+=e.textContent+"\n\n";else d=a.textContent;this.installScopeCssText(d,c,b)}},installScopeCssText:function(a,b,d){if(b=b||this.findStyleScope(),d=d||"",b){window.ShadowDOMPolyfill&&(a=c(a,b.host));var f=this.element.cssTextToScopeStyle(a,e);Polymer.applyStyleToScope(f,b),b._scopeStyles[this.localName+d]=!0}},findStyleScope:function(){for(var a=this;a.parentNode;)a=a.parentNode;return a},scopeHasNamedStyle:function(a,b){return a._scopeStyles=a._scopeStyles||{},a._scopeStyles[b]}};a.api.instance.styles=f}(Polymer),function(a){function b(a,b){if(f[a])throw"Already registered (Polymer) prototype for element "+a;e(a,b),d(a)}function c(a,b){h[a]=b}function d(a){h[a]&&(h[a].registerWhenReady(),delete h[a])}function e(a,b){return i[a]=b||{}}function f(a){return i[a]}var g=a.extend,h=(a.api,{}),i={};a.getRegisteredPrototype=f,a.waitingForPrototype=c,window.Polymer=b,g(Polymer,a);var j=Platform.deliverDeclarations();if(j)for(var k,l=0,m=j.length;m>l&&(k=j[l]);l++)b.apply(null,k)}(Polymer),function(a){var b={resolveElementPaths:function(a){Platform.urlResolver.resolveDom(a)},addResolvePathApi:function(){var a=this.getAttribute("assetpath")||"",b=new URL(a,this.ownerDocument.baseURI);this.prototype.resolvePath=function(a,c){var d=new URL(a,c||b);return d.href}}};a.api.declaration.path=b}(Polymer),function(a){function b(a,b){var c=new URL(a.getAttribute("href"),b).href;return"@import '"+c+"';"}function c(a,b){if(a){b===document&&(b=document.head),window.ShadowDOMPolyfill&&(b=document.head);var c=d(a.textContent),e=a.getAttribute(h);e&&c.setAttribute(h,e),b.appendChild(c)}}function d(a,b){b=b||document,b=b.createElement?b:b.ownerDocument;var c=b.createElement("style");return c.textContent=a,c}function e(a){return a&&a.__resource||""}function f(a,b){return p?p.call(a,b):void 0}var g=(window.logFlags||{},a.api.instance.styles),h=g.STYLE_SCOPE_ATTRIBUTE,i="style",j="@import",k="link[rel=stylesheet]",l="global",m="polymer-scope",n={loadStyles:function(a){var b=this.templateContent();b&&this.convertSheetsToStyles(b);var c=this.findLoadableStyles(b);c.length?Platform.styleResolver.loadStyles(c,a):a&&a()},convertSheetsToStyles:function(a){for(var c,e,f=a.querySelectorAll(k),g=0,h=f.length;h>g&&(c=f[g]);g++)e=d(b(c,this.ownerDocument.baseURI),this.ownerDocument),this.copySheetAttributes(e,c),c.parentNode.replaceChild(e,c)},copySheetAttributes:function(a,b){for(var c,d=0,e=b.attributes,f=e.length;(c=e[d])&&f>d;d++)"rel"!==c.name&&"href"!==c.name&&a.setAttribute(c.name,c.value)},findLoadableStyles:function(a){var b=[];if(a)for(var c,d=a.querySelectorAll(i),e=0,f=d.length;f>e&&(c=d[e]);e++)c.textContent.match(j)&&b.push(c);return b},installSheets:function(){this.cacheSheets(),this.cacheStyles(),this.installLocalSheets(),this.installGlobalStyles()},cacheSheets:function(){this.sheets=this.findNodes(k),this.sheets.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},cacheStyles:function(){this.styles=this.findNodes(i+"["+m+"]"),this.styles.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)})},installLocalSheets:function(){var a=this.sheets.filter(function(a){return!a.hasAttribute(m)}),b=this.templateContent();if(b){var c="";if(a.forEach(function(a){c+=e(a)+"\n"}),c){var f=d(c,this.ownerDocument);b.insertBefore(f,b.firstChild)}}},findNodes:function(a,b){var c=this.querySelectorAll(a).array(),d=this.templateContent();if(d){var e=d.querySelectorAll(a).array();c=c.concat(e)}return b?c.filter(b):c},templateContent:function(){var a=this.querySelector("template");return a&&templateContent(a)},installGlobalStyles:function(){var a=this.styleForScope(l);c(a,document.head)},cssTextForScope:function(a){var b="",c="["+m+"="+a+"]",d=function(a){return f(a,c)},g=this.sheets.filter(d);g.forEach(function(a){b+=e(a)+"\n\n"});var h=this.styles.filter(d);return h.forEach(function(a){b+=a.textContent+"\n\n"}),b},styleForScope:function(a){var b=this.cssTextForScope(a);return this.cssTextToScopeStyle(b,a)},cssTextToScopeStyle:function(a,b){if(a){var c=d(a);return c.setAttribute(h,this.getAttribute("name")+"-"+b),c}}},o=HTMLElement.prototype,p=o.matches||o.matchesSelector||o.webkitMatchesSelector||o.mozMatchesSelector;a.api.declaration.styles=n,a.applyStyleToScope=c}(Polymer),function(a){var b=(window.logFlags||{},a.api.instance.events),c=b.EVENT_PREFIX,d={parseHostEvents:function(){var a=this.prototype.eventDelegates;this.addAttributeDelegates(a)},addAttributeDelegates:function(a){for(var b,c=0;b=this.attributes[c];c++)this.hasEventPrefix(b.name)&&(a[this.removeEventPrefix(b.name)]=b.value.replace("{{","").replace("}}","").trim())},hasEventPrefix:function(a){return a&&"o"===a[0]&&"n"===a[1]&&"-"===a[2]},removeEventPrefix:function(a){return a.slice(e)}},e=c.length;a.api.declaration.events=d}(Polymer),function(a){var b={inferObservers:function(a){var b,c=a.observe;for(var d in a)"Changed"===d.slice(-7)&&(c||(c=a.observe={}),b=d.slice(0,-7),c[b]=c[b]||d)},explodeObservers:function(a){var b=a.observe;if(b){var c={};for(var d in b)for(var e,f=d.split(" "),g=0;e=f[g];g++)c[e]=b[d];a.observe=c}},optimizePropertyMaps:function(a){if(a.observe){var b=a._observeNames=[];for(var c in a.observe)for(var d,e=c.split(" "),f=0;d=e[f];f++)b.push(d)}if(a.publish){var b=a._publishNames=[];for(var c in a.publish)b.push(c)}},publishProperties:function(a,b){var c=a.publish;c&&(this.requireProperties(c,a,b),a._publishLC=this.lowerCaseMap(c))},requireProperties:function(a,b,c){for(var d in a)void 0===b[d]&&void 0===c[d]&&(b[d]=a[d])},lowerCaseMap:function(a){var b={};for(var c in a)b[c.toLowerCase()]=c;return b}};a.api.declaration.properties=b}(Polymer),function(a){var b="attributes",c=/\s|,/,d={inheritAttributesObjects:function(a){this.inheritObject(a,"publishLC"),this.inheritObject(a,"_instanceAttributes")},publishAttributes:function(a,d){var e=this.getAttribute(b);if(e)for(var f,g=a.publish||(a.publish={}),h=e.split(c),i=0,j=h.length;j>i;i++)f=h[i].trim(),f&&void 0===g[f]&&void 0===d[f]&&(g[f]=null)},accumulateInstanceAttributes:function(){for(var a,b=this.prototype._instanceAttributes,c=this.attributes,d=0,e=c.length;e>d&&(a=c[d]);d++)this.isInstanceAttribute(a.name)&&(b[a.name]=a.value)},isInstanceAttribute:function(a){return!this.blackList[a]&&"on-"!==a.slice(0,3)},blackList:{name:1,"extends":1,constructor:1,noscript:1,assetpath:1,"cache-csstext":1}};d.blackList[b]=1,a.api.declaration.attributes=d}(Polymer),function(a){function b(a){if(!Object.__proto__){var b=Object.getPrototypeOf(a);a.__proto__=b,d(b)&&(b.__proto__=Object.getPrototypeOf(b))}}var c=a.api,d=a.isBase,e=a.extend,f={register:function(a,b){this.buildPrototype(a,b),this.registerPrototype(a,b),this.publishConstructor()},buildPrototype:function(b,c){var d=a.getRegisteredPrototype(b),e=this.generateBasePrototype(c);this.desugarBeforeChaining(d,e),this.prototype=this.chainPrototypes(d,e),this.desugarAfterChaining(b,c)},desugarBeforeChaining:function(a,b){a.element=this,this.publishAttributes(a,b),this.publishProperties(a,b),this.inferObservers(a),this.explodeObservers(a)},chainPrototypes:function(a,c){this.inheritMetaData(a,c);var d=this.chainObject(a,c);return b(d),d},inheritMetaData:function(a,b){this.inheritObject("observe",a,b),this.inheritObject("publish",a,b),this.inheritObject("_publishLC",a,b),this.inheritObject("_instanceAttributes",a,b),this.inheritObject("eventDelegates",a,b)},desugarAfterChaining:function(a,b){this.optimizePropertyMaps(this.prototype),this.installSheets(),this.resolveElementPaths(this),this.accumulateInstanceAttributes(),this.parseHostEvents(),this.addResolvePathApi(),window.ShadowDOMPolyfill&&Platform.ShadowCSS.shimStyling(this.templateContent(),a,b),this.prototype.registerCallback&&this.prototype.registerCallback(this)},publishConstructor:function(){var a=this.getAttribute("constructor");a&&(window[a]=this.ctor)},generateBasePrototype:function(a){var b=this.findBasePrototype(a);if(!b){var b=HTMLElement.getPrototypeForTag(a);b=this.ensureBaseApi(b),g[a]=b}return b},findBasePrototype:function(a){return g[a]},ensureBaseApi:function(a){if(a.PolymerBase)return a;var b=Object.create(a);return c.publish(c.instance,b),this.mixinMethod(b,a,c.instance.mdv,"bind"),b},mixinMethod:function(a,b,c,d){var e=function(a){return b[d].apply(this,a)};a[d]=function(){return this.mixinSuper=e,c[d].apply(this,arguments)}},inheritObject:function(a,b,c){var d=b[a]||{};b[a]=this.chainObject(d,c[a])},registerPrototype:function(a,b){var c={prototype:this.prototype},d=this.findTypeExtension(b);d&&(c.extends=d),HTMLElement.register(a,this.prototype),this.ctor=document.registerElement(a,c)},findTypeExtension:function(a){if(a&&a.indexOf("-")<0)return a;var b=this.findBasePrototype(a);return b.element?this.findTypeExtension(b.element.extends):void 0}},g={};f.chainObject=Object.__proto__?function(a,b){return a&&b&&a!==b&&(a.__proto__=b),a}:function(a,b){if(a&&b&&a!==b){var c=Object.create(b);a=e(c,a)}return a},c.declaration.prototype=f}(Polymer),function(a){function b(a){return document.contains(a)?g:f}function c(){return f.length?f[0]:g[0]}function d(a){e.waitToReady=!0,CustomElements.ready=!1,HTMLImports.whenImportsReady(function(){e.addReadyCallback(a),e.waitToReady=!1,e.check()})}var e={wait:function(a,b,c){return-1===this.indexOf(a)&&(this.add(a),a.__check=b,a.__go=c),0!==this.indexOf(a)},add:function(a){b(a).push(a)},indexOf:function(a){var c=b(a).indexOf(a);return c>=0&&document.contains(a)&&(c+=HTMLImports.useNative||HTMLImports.ready?f.length:1e9),c},go:function(a){var b=this.remove(a);b&&(b.__go.call(b),b.__check=b.__go=null,this.check())},remove:function(a){var c=this.indexOf(a);if(0===c)return b(a).shift()},check:function(){var a=this.nextElement();return a&&a.__check.call(a),this.canReady()?(this.ready(),!0):void 0},nextElement:function(){return c()},canReady:function(){return!this.waitToReady&&this.isEmpty()},isEmpty:function(){return!f.length&&!g.length},ready:function(){if(CustomElements.ready===!1&&(CustomElements.upgradeDocumentTree(document),CustomElements.ready=!0),h)for(var a;h.length;)(a=h.shift())()},addReadyCallback:function(a){a&&h.push(a)},waitToReady:!0},f=[],g=[],h=[];document.addEventListener("WebComponentsReady",function(){CustomElements.ready=!1}),a.queue=e,a.whenPolymerReady=d}(Polymer),function(a){function b(a,b){a?(document.head.appendChild(a),d(b)):b&&b()}function c(a,c){if(a&&a.length){for(var d,e,f=document.createDocumentFragment(),g=0,h=a.length;h>g&&(d=a[g]);g++)e=document.createElement("link"),e.rel="import",e.href=d,f.appendChild(e);b(f,c)}else c&&c()}var d=a.whenPolymerReady;a.import=c,a.importElements=b}(Polymer),function(a){function b(a){return Boolean(HTMLElement.getPrototypeForTag(a))}function c(a){return a&&a.indexOf("-")>=0}var d=a.extend,e=a.api,f=a.queue,g=a.whenPolymerReady,h=a.getRegisteredPrototype,i=a.waitingForPrototype,j=d(Object.create(HTMLElement.prototype),{createdCallback:function(){this.getAttribute("name")&&this.init()},init:function(){this.name=this.getAttribute("name"),this.extends=this.getAttribute("extends"),this.loadResources(),this.registerWhenReady()},registerWhenReady:function(){this.registered||this.waitingForPrototype(this.name)||this.waitingForQueue()||this.waitingForResources()||f.go(this)},_register:function(){c(this.extends)&&!b(this.extends)&&console.warn("%s is attempting to extend %s, an unregistered element or one that was not registered with Polymer.",this.name,this.extends),this.register(this.name,this.extends),this.registered=!0},waitingForPrototype:function(a){return h(a)?void 0:(i(a,this),this.handleNoScript(a),!0)},handleNoScript:function(a){if(this.hasAttribute("noscript")&&!this.noscript)if(this.noscript=!0,window.CustomElements&&!CustomElements.useNative)Polymer(a);else{var b=document.createElement("script");b.textContent="Polymer('"+a+"');",this.appendChild(b)}},waitingForResources:function(){return this._needsResources},waitingForQueue:function(){return f.wait(this,this.registerWhenReady,this._register)},loadResources:function(){this._needsResources=!0,this.loadStyles(function(){this._needsResources=!1,this.registerWhenReady()}.bind(this))}});e.publish(e.declaration,j),a.getRegisteredPrototype=h,g(function(){document.body.removeAttribute("unresolved"),document.dispatchEvent(new CustomEvent("polymer-ready",{bubbles:!0}))}),document.registerElement("polymer-element",{prototype:j})}(Polymer);
-//# sourceMappingURL=polymer.js.map
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js.map b/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js.map
deleted file mode 100644
index e9c9cfa..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/polymer/polymer.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"polymer.js","sources":["../src/polymer.js","../src/boot.js","../src/lib/lang.js","../src/lib/job.js","../src/lib/dom.js","../src/lib/super.js","../src/lib/deserialize.js","../src/api.js","../src/instance/utils.js","../src/instance/events.js","../src/instance/attributes.js","../src/instance/properties.js","../src/instance/mdv.js","../src/instance/base.js","../src/instance/styles.js","../src/declaration/polymer.js","../src/declaration/path.js","../src/declaration/styles.js","../src/declaration/events.js","../src/declaration/properties.js","../src/declaration/attributes.js","../src/declaration/prototype.js","../src/declaration/queue.js","../src/declaration/import.js","../src/declaration/polymer-element.js"],"names":["Polymer","window","scope","extend","prototype","api","Object","getOwnPropertyNames","forEach","n","pd","getOwnPropertyDescriptor","defineProperty","value","nom","job","callback","wait","stop","Job","this","go","inContext","context","boundComplete","complete","bind","h","setTimeout","handle","clearTimeout","requestAnimationFrame","cancelAnimationFrame","call","registry","HTMLElement","register","tag","getPrototypeForTag","getPrototypeOf","document","createElement","originalStopPropagation","Event","stopPropagation","cancelBubble","apply","arguments","$super","arrayOfArgs","caller","_super","nameInThis","console","warn","memoizeSuper","fn","nextSuper","proto","name","method","p","__proto__","n$","i","l","length","d","super","deserializeValue","currentValue","inferredType","Date","typeHandlers","string","date","parse","now","boolean","number","parseFloat","parseInt","isNaN","object","JSON","replace","e","function","declaration","instance","publish","apis","utils","async","args","timeout","Platform","flush","cancelAsync","Math","round","fire","type","detail","onNode","bubbles","cancelable","node","event","CustomEvent","undefined","dispatchEvent","asyncFire","classFollows","anew","old","className","classList","remove","add","nop","nob","asyncMethod","log","logFlags","EVENT_PREFIX","events","addHostListeners","eventDelegates","keys","localName","bindable","eventName","self","PolymerExpressions","prepareEventBinding","Path","get","resolveEventHandler","model","path","getValueFrom","dispatchMethod","obj","group","groupEnd","attributes","copyInstanceAttributes","a$","_instanceAttributes","k","hasAttribute","setAttribute","takeAttributes","_publishLC","a","attributeToProperty","propertyForAttribute","search","bindPattern","match","stringValue","serializeValue","reflectPropertyToAttribute","serializedValue","removeAttribute","bindProperties","inA","inProperty","observable","LOG_BIND_PROPS","inB","inPath","v","discardChanges","setValue","Observer","defineComputedProperty","properties","observeProperties","_observeNames","pn$","_publishNames","o","_propertyObserver","CompoundObserver","addPath","observeArrayValue","observe","open","notifyPropertyChanges","newValues","oldValues","paths","called","invokeMethod","callbackName","Array","isArray","unregisterObserver","observer","ArrayObserver","registerObserver","bindProperty","property","unbindAllProperties","close","unregisterObservers","unbindProperty","o$","_observers","findEventController","parentNode","lightDomController","host","unbindNodeTree","forNodeTree","_nodeUnbindAll","unbindAll","child","firstChild","nextSibling","syntax","ctlr","mdv","instanceTemplate","template","createInstance","_elementPrepared","prepareElement","unbind","path_","bindings","mixinSuper","asyncUnbindAll","_unbound","_unbindAllJob","root","shadowRoot","olderShadowRoot","cancelUnbindAll","preventCascade","mustachePattern","isBase","hasOwnProperty","PolymerBase","preparingElements","base","created","ready","createdCallback","ownerDocument","defaultView","alwaysPrepare","shadowRoots","parseDeclarations","attachedCallback","attached","enteredView","hasBeenAttached","domReady","detachedCallback","preventDispose","detached","leftView","enteredViewCallback","leftViewCallback","enteredDocumentCallback","leftDocumentCallback","element","parseDeclaration","elementElement","fetchTemplate","shadowFromTemplate","querySelector","createShadowRoot","resetStyleInheritance","dom","appendChild","shadowRootReady","lightFromTemplate","marshalNodeReferences","PointerGestures","$","querySelectorAll","id","attributeChangedCallback","getAttribute","attributeChanged","onMutation","listener","MutationObserver","mutations","disconnect","childList","subtree","constructor","Base","shimCssText","cssText","is","selector","ShadowCSS","makeScopeSelector","STYLE_SCOPE_ATTRIBUTE","STYLE_CONTROLLER_SCOPE","styles","installControllerStyles","findStyleScope","scopeHasNamedStyle","cssTextForScope","installScopeCssText","installScopeStyle","style","s","textContent","ShadowDOMPolyfill","cssTextToScopeStyle","applyStyleToScope","_scopeStyles","getRegisteredPrototype","registerPrototype","notifyPrototype","waitingForPrototype","client","waitPrototype","registerWhenReady","prototypesByName","declarations","deliverDeclarations","resolveElementPaths","urlResolver","resolveDom","addResolvePathApi","assetPath","URL","baseURI","resolvePath","urlPath","u","href","importRuleForSheet","sheet","baseUrl","head","clone","createStyleElement","attr","cssTextFromSheet","__resource","matchesSelector","inSelector","matches","STYLE_SELECTOR","STYLE_LOADABLE_MATCH","SHEET_SELECTOR","STYLE_GLOBAL_SCOPE","SCOPE_ATTR","loadStyles","content","templateContent","convertSheetsToStyles","findLoadableStyles","styleResolver","c","s$","copySheetAttributes","replaceChild","link","loadables","push","installSheets","cacheSheets","cacheStyles","installLocalSheets","installGlobalStyles","sheets","findNodes","removeChild","filter","insertBefore","matcher","nodes","array","templateNodes","concat","styleForScope","scopeDescriptor","webkitMatchesSelector","mozMatchesSelector","parseHostEvents","delegates","addAttributeDelegates","hasEventPrefix","removeEventPrefix","trim","slice","prefixLength","inferObservers","explodeObservers","exploded","ni","names","split","optimizePropertyMaps","publishProperties","requireProperties","lowerCaseMap","map","toLowerCase","ATTRIBUTES_ATTRIBUTE","ATTRIBUTES_REGEX","inheritAttributesObjects","inheritObject","publishAttributes","accumulateInstanceAttributes","clonable","isInstanceAttribute","blackList","extends","noscript","assetpath","cache-csstext","ensurePrototypeTraversal","ancestor","extendeeName","buildPrototype","publishConstructor","extension","generateBasePrototype","desugarBeforeChaining","chainPrototypes","desugarAfterChaining","inheritMetaData","chained","chainObject","extendee","shimStyling","registerCallback","symbol","ctor","extnds","findBasePrototype","ensureBaseApi","memoizedBases","extended","create","mixinMethod","source","info","typeExtension","findTypeExtension","registerElement","indexOf","inherited","queueForElement","contains","mainQueue","importQueue","nextQueued","whenPolymerReady","queue","waitToReady","CustomElements","HTMLImports","whenImportsReady","addReadyCallback","check","__check","__go","useNative","readied","shift","nextElement","canReady","isEmpty","upgradeDocumentTree","readyCallbacks","addEventListener","importElements","elementOrFragment","importUrls","urls","url","frag","createDocumentFragment","rel","import","isRegistered","Boolean","isCustomTag","init","loadResources","registered","waitingForQueue","waitingForResources","_register","handleNoScript","script","_needsResources","body"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKAA,WCI8B,kBAAnBC,QAAOD,UAChBA,YCLF,SAAUE,GAGR,QAASC,GAAOC,EAAWC,GAiBzB,MAhBID,IAAaC,GAEfC,OAAOC,oBAAoBF,GAAKG,QAAQ,SAASC,GAE/C,GAAIC,GAAKJ,OAAOK,yBAAyBN,EAAKI,EAC1CC,KAEFJ,OAAOM,eAAeR,EAAWK,EAAGC,GAEb,kBAAZA,GAAGG,QAEZH,EAAGG,MAAMC,IAAML,MAKhBL,EAKTF,EAAMC,OAASA,GAEdH,SC1BH,SAAUE,GA6CR,QAASa,GAAIA,EAAKC,EAAUC,GAO1B,MANIF,GACFA,EAAIG,OAEJH,EAAM,GAAII,GAAIC,MAEhBL,EAAIM,GAAGL,EAAUC,GACVF,EAzCT,GAAII,GAAM,SAASG,GACjBF,KAAKG,QAAUD,EACfF,KAAKI,cAAgBJ,KAAKK,SAASC,KAAKN,MAE1CD,GAAIf,WACFiB,GAAI,SAASL,EAAUC,GACrBG,KAAKJ,SAAWA,CAChB,IAAIW,EACCV,IAMHU,EAAIC,WAAWR,KAAKI,cAAeP,GACnCG,KAAKS,OAAS,WACZC,aAAaH,MAPfA,EAAII,sBAAsBX,KAAKI,eAC/BJ,KAAKS,OAAS,WACZG,qBAAqBL,MAS3BT,KAAM,WACAE,KAAKS,SACPT,KAAKS,SACLT,KAAKS,OAAS,OAGlBJ,SAAU,WACJL,KAAKS,SACPT,KAAKF,OACLE,KAAKJ,SAASiB,KAAKb,KAAKG,YAiB9BrB,EAAMa,IAAMA,GAEXf,SC5DH,WAEE,GAAIkC,KAEJC,aAAYC,SAAW,SAASC,EAAKjC,GACnC8B,EAASG,GAAOjC,GAIlB+B,YAAYG,mBAAqB,SAASD,GACxC,GAAIjC,GAAaiC,EAA8BH,EAASG,GAAjCF,YAAY/B,SAEnC,OAAOA,IAAaE,OAAOiC,eAAeC,SAASC,cAAcJ,IAInE,IAAIK,GAA0BC,MAAMvC,UAAUwC,eAC9CD,OAAMvC,UAAUwC,gBAAkB,WAChCxB,KAAKyB,cAAe,EACpBH,EAAwBI,MAAM1B,KAAM2B,aASrC/C,SC5BF,SAAUE,GAgBP,QAAS8C,GAAOC,GAMd,GAAIC,GAASF,EAAOE,OAEhBpC,EAAMoC,EAAOpC,IAEbqC,EAASD,EAAOC,MAYpB,IAXKA,IACErC,IACHA,EAAMoC,EAAOpC,IAAMsC,EAAWnB,KAAKb,KAAM8B,IAEtCpC,GACHuC,QAAQC,KAAK,iFAIfH,EAASI,EAAaL,EAAQpC,EAAKyB,EAAenB,QAE/C+B,EAGE,CAEL,GAAIK,GAAKL,EAAOrC,EAOhB,OALK0C,GAAGL,QACNI,EAAaC,EAAI1C,EAAKqC,GAIjBK,EAAGV,MAAM1B,KAAM6B,QAI1B,QAASQ,GAAUC,EAAOC,EAAMT,GAE9B,KAAOQ,GAAO,CACZ,GAAKA,EAAMC,KAAUT,GAAWQ,EAAMC,GACpC,MAAOD,EAETA,GAAQnB,EAAemB,IAI3B,QAASH,GAAaK,EAAQD,EAAMD,GAUlC,MANAE,GAAOT,OAASM,EAAUC,EAAOC,EAAMC,GACnCA,EAAOT,SAGTS,EAAOT,OAAOQ,GAAM7C,IAAM6C,GAErBC,EAAOT,OAGhB,QAASC,GAAWvC,GAElB,IADA,GAAIgD,GAAIzC,KAAK0C,UACND,GAAKA,IAAM1B,YAAY/B,WAAW,CAGvC,IAAK,GAAsBK,GADvBsD,EAAKzD,OAAOC,oBAAoBsD,GAC3BG,EAAE,EAAGC,EAAEF,EAAGG,OAAaD,EAAFD,IAAQvD,EAAEsD,EAAGC,IAAKA,IAAK,CACnD,GAAIG,GAAI7D,OAAOK,yBAAyBkD,EAAGpD,EAC3C,IAAuB,kBAAZ0D,GAAEtD,OAAwBsD,EAAEtD,QAAUA,EAC/C,MAAOJ,GAGXoD,EAAIA,EAAEC,WAOV,QAASvB,GAAenC,GACtB,MAAOA,GAAU0D,UAkBnB5D,EAAMkE,MAAQpB,GAEfhD,SCnHH,SAAUE,GA8CR,QAASmE,GAAiBxD,EAAOyD,GAE/B,GAAIC,SAAsBD,EAM1B,OAJIA,aAAwBE,QAC1BD,EAAe,QAGVE,EAAaF,GAAc1D,EAAOyD,GApD3C,GAAIG,IACFC,OAAQ,SAAS7D,GACf,MAAOA,IAET8D,KAAM,SAAS9D,GACb,MAAO,IAAI2D,MAAKA,KAAKI,MAAM/D,IAAU2D,KAAKK,QAE5CC,UAAS,SAASjE,GAChB,MAAc,KAAVA,GACK,EAEQ,UAAVA,GAAoB,IAAUA,GAEvCkE,OAAQ,SAASlE,GACf,GAAIJ,GAAIuE,WAAWnE,EAKnB,OAHU,KAANJ,IACFA,EAAIwE,SAASpE,IAERqE,MAAMzE,GAAKI,EAAQJ,GAK5B0E,OAAQ,SAAStE,EAAOyD,GACtB,GAAqB,OAAjBA,EACF,MAAOzD,EAET,KAIE,MAAOuE,MAAKR,MAAM/D,EAAMwE,QAAQ,KAAM,MACtC,MAAMC,GAEN,MAAOzE,KAIX0E,WAAY,SAAS1E,EAAOyD,GAC1B,MAAOA,IAiBXpE,GAAMmE,iBAAmBA,GAExBrE,SC9DH,SAAUE,GAIR,GAAIC,GAASD,EAAMC,OAIfE,IAEJA,GAAImF,eACJnF,EAAIoF,YAEJpF,EAAIqF,QAAU,SAASC,EAAMvF,GAC3B,IAAK,GAAIK,KAAKkF,GACZxF,EAAOC,EAAWuF,EAAKlF,KAM3BP,EAAMG,IAAMA,GAEXL,SCvBH,SAAUE,GAER,GAAI0F,IASFC,MAAO,SAASjC,EAAQkC,EAAMC,GAG5BC,SAASC,QAETH,EAAQA,GAAQA,EAAK5B,OAAU4B,GAAQA,EAEvC,IAAItC,GAAK,YACNpC,KAAKwC,IAAWA,GAAQd,MAAM1B,KAAM0E,IACrCpE,KAAKN,MAEHS,EAASkE,EAAUnE,WAAW4B,EAAIuC,GAClChE,sBAAsByB,EAE1B,OAAOuC,GAAUlE,EAAS,EAAIA,GAEhCqE,YAAa,SAASrE,GACP,EAATA,EACFG,qBAAqBmE,KAAKC,MAAM,EAAIvE,IAEpCC,aAAaD,IAWjBwE,KAAM,SAASC,EAAMC,EAAQC,EAAQC,EAASC,GAC5C,GAAIC,GAAOH,GAAUpF,KACjBmF,EAASA,MACTK,EAAQ,GAAIC,aAAYP,GAC1BG,QAAsBK,SAAZL,EAAwBA,GAAU,EAC5CC,WAA4BI,SAAfJ,EAA2BA,GAAa,EACrDH,OAAQA,GAGV,OADAI,GAAKI,cAAcH,GACZA,GASTI,UAAW,WACT5F,KAAKyE,MAAM,OAAQ9C,YASrBkE,aAAc,SAASC,EAAMC,EAAKC,GAC5BD,GACFA,EAAIE,UAAUC,OAAOF,GAEnBF,GACFA,EAAKG,UAAUE,IAAIH,KAMrBI,EAAM,aAGNC,IAIJ7B,GAAM8B,YAAc9B,EAAMC,MAI1B3F,EAAMG,IAAIoF,SAASG,MAAQA,EAC3B1F,EAAMsH,IAAMA,EACZtH,EAAMuH,IAAMA,GAEXzH,SC/FH,SAAUE,GAIR,GAAIyH,GAAM1H,OAAO2H,aACbC,EAAe,MAGfC,GAEFD,aAAcA,EAEdE,iBAAkB,WAChB,GAAID,GAAS1G,KAAK4G,cAClBL,GAAIG,QAAWxH,OAAO2H,KAAKH,GAAQ5D,OAAS,GAAMb,QAAQsE,IAAI,yBAA0BvG,KAAK8G,UAAWJ,EAOxG,IAAiBK,GAAUC,EAAvBC,EAAOjH,IACX,KAAK,GAAIX,KAAKqH,GACZM,EAAYP,EAAepH,GAC3B0H,EAAWG,mBAAmBC,oBAC5BC,KAAKC,IAAIX,EAAOrH,IAChB2H,GAEEM,oBAAqB,SAASC,EAAOC,GACnC,GAAIpF,GAAKoF,EAAKC,aAAaR,EAC3B,OAAI7E,GACKA,EAAG9B,KAAK2G,GADjB,WAMGjH,KAAMA,MAAM,IAIzB0H,eAAgB,SAASC,EAAKnF,EAAQkC,GACpC,GAAIiD,EAAK,CACPpB,EAAIG,QAAUzE,QAAQ2F,MAAM,qBAAsBD,EAAIb,UAAWtE,EACjE,IAAIJ,GAAuB,kBAAXI,GAAwBA,EAASmF,EAAInF,EACjDJ,IACFA,EAAGsC,EAAO,QAAU,QAAQiD,EAAKjD,GAEnC6B,EAAIG,QAAUzE,QAAQ4F,WACtBjD,SAASC,UAOf/F,GAAMG,IAAIoF,SAASqC,OAASA,GAE3B9H,SC1DH,SAAUE,GAIR,GAAIgJ,IACFC,uBAAwB,WACtB,GAAIC,GAAKhI,KAAKiI,mBACd,KAAK,GAAIC,KAAKF,GACPhI,KAAKmI,aAAaD,IACrBlI,KAAKoI,aAAaF,EAAGF,EAAGE,KAK9BG,eAAgB,WAGd,GAAIrI,KAAKsI,WACP,IAAK,GAA0CC,GAAtC3F,EAAE,EAAGoF,EAAGhI,KAAK8H,WAAYjF,EAAEmF,EAAGlF,QAAYyF,EAAEP,EAAGpF,KAASC,EAAFD,EAAKA,IAClE5C,KAAKwI,oBAAoBD,EAAEhG,KAAMgG,EAAE9I,QAMzC+I,oBAAqB,SAASjG,EAAM9C,GAGlC,GAAI8C,GAAOvC,KAAKyI,qBAAqBlG,EACrC,IAAIA,EAAM,CAIR,GAAI9C,GAASA,EAAMiJ,OAAO5J,EAAM6J,cAAgB,EAC9C,MAGF,IAAIzF,GAAelD,KAAKuC,GAEpB9C,EAAQO,KAAKiD,iBAAiBxD,EAAOyD,EAErCzD,KAAUyD,IAEZlD,KAAKuC,GAAQ9C,KAKnBgJ,qBAAsB,SAASlG,GAC7B,GAAIqG,GAAQ5I,KAAKsI,YAActI,KAAKsI,WAAW/F,EAE/C,OAAOqG,IAGT3F,iBAAkB,SAAS4F,EAAa3F,GACtC,MAAOpE,GAAMmE,iBAAiB4F,EAAa3F,IAE7C4F,eAAgB,SAASrJ,EAAO0D,GAC9B,MAAqB,YAAjBA,EACK1D,EAAQ,GAAKiG,OACM,WAAjBvC,GAA8C,aAAjBA,GACvBuC,SAAVjG,EACEA,EAFF,QAKTsJ,2BAA4B,SAASxG,GACnC,GAAIY,SAAsBnD,MAAKuC,GAE3ByG,EAAkBhJ,KAAK8I,eAAe9I,KAAKuC,GAAOY,EAE9BuC,UAApBsD,EACFhJ,KAAKoI,aAAa7F,EAAMyG,GAME,YAAjB7F,GACTnD,KAAKiJ,gBAAgB1G,IAO3BzD,GAAMG,IAAIoF,SAASyD,WAAaA,GAE/BlJ,SCvFH,SAAUE,GA0HR,QAASoK,GAAeC,EAAKC,EAAYC,GACvC9C,EAAIjG,MAAQ2B,QAAQsE,IAAI+C,EAAgBC,IAAIzC,WAAa,SAAU0C,OAAQL,EAAIrC,UAAWsC,EAI1F,IAAIK,GAAIJ,EAAWK,gBAInB,QAHU,OAAND,GAAoB/D,SAAN+D,IAChBJ,EAAWM,SAASR,EAAIC,IAEnBQ,SAASC,uBAAuBV,EAAKC,EAAYC,GA/H1D,GAAI9C,GAAM1H,OAAO2H,aAUbsD,GACFC,kBAAmB,WACjB,GAAIpH,GAAK3C,KAAKgK,cAAeC,EAAMjK,KAAKkK,aACxC,IAAKvH,GAAMA,EAAGG,QAAYmH,GAAOA,EAAInH,OAAS,CAG5C,IAAK,GAAsBzD,GADvB8K,EAAInK,KAAKoK,kBAAoB,GAAIC,kBAC5BzH,EAAE,EAAGC,EAAEF,EAAGG,OAAcD,EAAFD,IAASvD,EAAEsD,EAAGC,IAAKA,IAAK,CACrDuH,EAAEG,QAAQtK,KAAMX,EAEhB,IAAIC,GAAKJ,OAAOK,yBAAyBS,KAAK0C,UAAWrD,EACrDC,IAAMA,EAAGG,OACXO,KAAKuK,kBAAkBlL,EAAGC,EAAGG,MAAO,MAGxC,IAAK,GAAuBJ,GAAnBuD,EAAE,EAAGC,EAAEoH,EAAInH,OAAcD,EAAFD,IAASvD,EAAE4K,EAAIrH,IAAKA,IAC7C5C,KAAKwK,SAAgC9E,SAApB1F,KAAKwK,QAAQnL,IACjC8K,EAAEG,QAAQtK,KAAMX,EAGpB8K,GAAEM,KAAKzK,KAAK0K,sBAAuB1K,QAGvC0K,sBAAuB,SAASC,EAAWC,EAAWC,GACpD,GAAItI,GAAMC,EAAQsI,IAClB,KAAK,GAAIlI,KAAKgI,GAEZrI,EAAOsI,EAAM,EAAIjI,EAAI,GACM8C,SAAvB1F,KAAKsE,QAAQ/B,IACfvC,KAAK+I,2BAA2BxG,GAElCC,EAASxC,KAAKwK,QAAQjI,GAClBC,IACFxC,KAAKuK,kBAAkBhI,EAAMoI,EAAU/H,GAAIgI,EAAUhI,IAChDkI,EAAOtI,KACVsI,EAAOtI,IAAU,EAEjBxC,KAAK+K,aAAavI,GAASoI,EAAUhI,GAAI+H,EAAU/H,GAAIjB,eAK/D4I,kBAAmB,SAAShI,EAAM9C,EAAOsG,GAEvC,GAAIiF,GAAehL,KAAKwK,QAAQjI,EAChC,IAAIyI,IAEEC,MAAMC,QAAQnF,KAChBQ,EAAIiE,SAAWvI,QAAQsE,IAAI,mDAAoDvG,KAAK8G,UAAWvE,GAC/FvC,KAAKmL,mBAAmB5I,EAAO,YAG7B0I,MAAMC,QAAQzL,IAAQ,CACxB8G,EAAIiE,SAAWvI,QAAQsE,IAAI,iDAAkDvG,KAAK8G,UAAWvE,EAAM9C,EACnG,IAAI2L,GAAW,GAAIC,eAAc5L,EACjC2L,GAASX,KAAK,SAAShL,EAAOsG,GAC5B/F,KAAK+K,aAAaC,GAAejF,KAChC/F,MACHA,KAAKsL,iBAAiB/I,EAAO,UAAW6I,KAI9CG,aAAc,SAASC,EAAUnC,GAE/B,MAAOH,GAAelJ,KAAMwL,EAAUnC,IAExCoC,oBAAqB,WACfzL,KAAKoK,mBACPpK,KAAKoK,kBAAkBsB,QAEzB1L,KAAK2L,uBAEPC,eAAgB,SAASrJ,GACvB,MAAOvC,MAAKmL,mBAAmB5I,IAEjCwI,aAAc,SAASvI,EAAQkC,GAC7B,GAAItC,GAAKpC,KAAKwC,IAAWA,CACP,mBAAPJ,IACTA,EAAGV,MAAM1B,KAAM0E,IAInB4G,iBAAkB,SAAS/I,EAAM6I,GAC/B,GAAIS,GAAK7L,KAAK8L,aAAe9L,KAAK8L,cAClCD,GAAGtJ,GAAQ6I,GAEbD,mBAAoB,SAAS5I,GAC3B,GAAIsJ,GAAK7L,KAAK8L,UACd,OAAID,IAAMA,EAAGtJ,IACXsJ,EAAGtJ,GAAMmJ,QACTG,EAAGtJ,GAAQ,MACJ,GAHT,QAMFoJ,oBAAqB,WACnB,GAAI3L,KAAK8L,WAAY,CAEnB,IAAK,GAAwB5D,GAAGiC,EAD5BtD,EAAK3H,OAAO2H,KAAK7G,KAAK8L,YACjBlJ,EAAE,EAAGC,EAAEgE,EAAK/D,OAAmBD,EAAJD,IAAWsF,EAAErB,EAAKjE,IAAKA,IACzDuH,EAAInK,KAAK8L,WAAW5D,GACpBiC,EAAEuB,OAEJ1L,MAAK8L,iBAwBPxC,EAAiB,yCAIrBxK,GAAMG,IAAIoF,SAASyF,WAAaA,GAE/BlL,SChJH,SAAUE,GAqBR,QAASiN,GAAoBxG,GAC3B,KAAOA,EAAKyG,YAAY,CACtB,GAAIzG,EAAK0G,mBACP,MAAO1G,EAETA,GAAOA,EAAKyG,WAEd,MAAOzG,GAAK2G,KA2Ed,QAASC,GAAe5G,GACtB6G,EAAY7G,EAAM8G,GAGpB,QAASA,GAAe9G,GACtBA,EAAK+G,YAGP,QAASF,GAAY7G,EAAM3F,GACzB,GAAI2F,EAAM,CACR3F,EAAS2F,EACT,KAAK,GAAIgH,GAAQhH,EAAKiH,WAAYD,EAAOA,EAAQA,EAAME,YACrDL,EAAYG,EAAO3M,IA/GzB,GAAI2G,GAAM1H,OAAO2H,UAAY,EAGzBkG,GAFS5N,EAAMG,IAAIoF,SAASqC,OAEnB,GAAIQ,oBACjBwF,GAAOpF,oBAAsB,SAASC,EAAOC,EAAMjC,GACjD,GAAIoH,GAAOZ,EAAoBxG,EAC/B,IAAIoH,EAAM,CACR,GAAIvK,GAAKoF,EAAKC,aAAakF,EAC3B,IAAIvK,EACF,MAAOA,GAAG9B,KAAKqM,IAoBrB,IAAIC,IACFF,OAAQA,EACRG,iBAAkB,SAASC,GACzB,MAAOA,GAASC,eAAe/M,KAAMA,KAAK0M,SAE5CpM,KAAM,SAASiC,EAAM8G,GAGdrJ,KAAKgN,kBACRhN,KAAKiN,gBAEP,IAAIzB,GAAWxL,KAAKyI,qBAAqBlG,EACzC,IAAKiJ,EAIE,CAELxL,KAAKkN,OAAO3K,EAEZ,IAAI6I,GAAWpL,KAAKuL,aAAaC,EAAUnC,EAO3C,OALA+B,GAAS5D,KAAO6B,EAAW8D,MAI3BnN,KAAK+I,2BAA2ByC,GACzBxL,KAAKoN,SAAS7K,GAAQ6I,EAZ7B,MAAOpL,MAAKqN,WAAW1L,YAe3B2L,eAAgB,WACTtN,KAAKuN,WACRhH,EAAI2G,QAAUjL,QAAQsE,IAAI,sBAAuBvG,KAAK8G,WACtD9G,KAAKwN,cAAgBxN,KAAKL,IAAIK,KAAKwN,cAAexN,KAAKsM,UAAW,KAGtEA,UAAW,WACT,IAAKtM,KAAKuN,SAAU,CAClBvN,KAAKyL,sBACLzL,KAAKgD,OAGL,KADA,GAAIyK,GAAOzN,KAAK0N,WACTD,GACLtB,EAAesB,GACfA,EAAOA,EAAKE,eAEd3N,MAAKuN,UAAW,IAGpBK,gBAAiB,SAASC,GACxB,MAAI7N,MAAKuN,cACPhH,EAAI2G,QAAUjL,QAAQC,KAAK,gDAAiDlC,KAAK8G,aAGnFP,EAAI2G,QAAUjL,QAAQsE,IAAI,uBAAwBvG,KAAK8G,WACnD9G,KAAKwN,gBACPxN,KAAKwN,cAAgBxN,KAAKwN,cAAc1N,aAIrC+N,GACHzB,EAAYpM,KAAK0N,WAAY,SAASrO,GAChCA,EAAEuO,iBACJvO,EAAEuO,wBAwBRE,EAAkB,gBAItBhP,GAAM6J,YAAcmF,EACpBhP,EAAMG,IAAIoF,SAASuI,IAAMA,GAExBhO,SC/HH,SAAUE,GAsMR,QAASiP,GAAOhK,GACd,MAAOA,GAAOiK,eAAe,eAK/B,QAASC,MA3MT,GAAIC,GAAoB,EAEpBC,GACFF,aAAa,EACbtO,IAAKf,QAAQe,IACbqD,QAAOpE,QAAQoE,MAEfoL,QAAS,aAITC,MAAO,aAEPC,gBAAiB,WACftO,KAAKoO,WACDpO,KAAKuO,cAAcC,aAAexO,KAAKyO,eACvCP,EAAoB,IACtBlO,KAAKiN,kBAITA,eAAgB,WACdjN,KAAKgN,kBAAmB,EAExBhN,KAAK0O,eAEL1O,KAAK+J,oBAEL/J,KAAK+H,yBAEL/H,KAAKqI,iBAELrI,KAAK2G,mBAGLuH,IAEAlO,KAAK2O,kBAAkB3O,KAAK0C,WAE5BwL,IAIAlO,KAAKiJ,gBAAgB,cAErBjJ,KAAKqO,SAEPO,iBAAkB,WACX5O,KAAKgN,kBACRhN,KAAKiN,iBAEPjN,KAAK4N,iBAAgB,GAEjB5N,KAAK6O,UACP7O,KAAK6O,WAGH7O,KAAK8O,aACP9O,KAAK8O,cAMF9O,KAAK+O,kBACR/O,KAAK+O,iBAAkB,EACnB/O,KAAKgP,UACPhP,KAAKyE,MAAM,cAIjBwK,iBAAkB,WACXjP,KAAKkP,gBACRlP,KAAKsN,iBAGHtN,KAAKmP,UACPnP,KAAKmP,WAGHnP,KAAKoP,UACPpP,KAAKoP,YAITC,oBAAqB,WACnBrP,KAAK4O,oBAGPU,iBAAkB,WAChBtP,KAAKiP,oBAGPM,wBAAyB,WACvBvP,KAAK4O,oBAGPY,qBAAsB,WACpBxP,KAAKiP,oBAGPN,kBAAmB,SAASlM,GACtBA,GAAKA,EAAEgN,UACTzP,KAAK2O,kBAAkBlM,EAAEC,WACzBD,EAAEiN,iBAAiB7O,KAAKb,KAAMyC,EAAEgN,WAIpCC,iBAAkB,SAASC,GACzB,GAAI7C,GAAW9M,KAAK4P,cAAcD,EAClC,IAAI7C,EAAU,CACZ,GAAIW,GAAOzN,KAAK6P,mBAAmB/C,EACnC9M,MAAK0O,YAAYiB,EAAepN,MAAQkL,IAI5CmC,cAAe,SAASD,GACtB,MAAOA,GAAeG,cAAc,aAGtCD,mBAAoB,SAAS/C,GAC3B,GAAIA,EAAU,CAEZ,GAAIW,GAAOzN,KAAK+P,kBAEhBtC,GAAKuC,sBAAwBhQ,KAAKgQ,qBAKlC,IAAIC,GAAMjQ,KAAK6M,iBAAiBC,EAMhC,OAJAW,GAAKyC,YAAYD,GAEjBjQ,KAAKmQ,gBAAgB1C,EAAMX,GAEpBW,IAIX2C,kBAAmB,SAAStD,GAC1B,GAAIA,EAAU,CAKZ9M,KAAKiM,oBAAqB,CAK1B,IAAIgE,GAAMjQ,KAAK6M,iBAAiBC,EAMhC,OAJA9M,MAAKkQ,YAAYD,GAEjBjQ,KAAKmQ,gBAAgBnQ,KAAM8M,GAEpBmD,IAGXE,gBAAiB,SAAS1C,GAExBzN,KAAKqQ,sBAAsB5C,GAE3B6C,gBAAgBtP,SAASyM,IAG3B4C,sBAAuB,SAAS5C,GAE9B,GAAI8C,GAAIvQ,KAAKuQ,EAAIvQ,KAAKuQ,KAEtB,IAAI9C,EAEF,IAAK,GAAsBpO,GADvBsD,EAAK8K,EAAK+C,iBAAiB,QACtB5N,EAAE,EAAGC,EAAEF,EAAGG,OAAcD,EAAFD,IAASvD,EAAEsD,EAAGC,IAAKA,IAChD2N,EAAElR,EAAEoR,IAAMpR,GAIhBqR,yBAA0B,SAASnO,GAEpB,UAATA,GAA6B,UAATA,GACtBvC,KAAKwI,oBAAoBjG,EAAMvC,KAAK2Q,aAAapO,IAE/CvC,KAAK4Q,kBACP5Q,KAAK4Q,iBAAiBlP,MAAM1B,KAAM2B,YAGtCkP,WAAY,SAAStL,EAAMuL,GACzB,GAAI1F,GAAW,GAAI2F,kBAAiB,SAASC,GAC3CF,EAASjQ,KAAKb,KAAMoL,EAAU4F,GAC9B5F,EAAS6F,cACT3Q,KAAKN,MACPoL,GAASZ,QAAQjF,GAAO2L,WAAW,EAAMC,SAAS,KAYtDlD,GAAYjP,UAAYmP,EACxBA,EAAKiD,YAAcnD,EAInBnP,EAAMuS,KAAOpD,EACbnP,EAAMiP,OAASA,EACfjP,EAAMG,IAAIoF,SAAS8J,KAAOA,GAEzBvP,SCtNH,SAAUE,GA8ER,QAASqC,GAAenC,GACtB,MAAOA,GAAU0D,UAGnB,QAAS4O,GAAYC,EAASrF,GAC5B,GAAI3J,GAAO,GAAIiP,GAAK,CAChBtF,KACF3J,EAAO2J,EAAKpF,UACZ0K,EAAKtF,EAAK/D,aAAa,MAEzB,IAAIsJ,GAAW7M,SAAS8M,UAAUC,kBAAkBpP,EAAMiP,EAC1D,OAAO5M,UAAS8M,UAAUJ,YAAYC,EAASE,GArFjD,GAIIG,IAJM/S,OAAO2H,aAIW,WACxBqL,EAAyB,aAEzBC,GACFF,sBAAuBA,EAMvBG,wBAAyB,WAEvB,GAAIjT,GAAQkB,KAAKgS,gBACjB,IAAIlT,IAAUkB,KAAKiS,mBAAmBnT,EAAOkB,KAAK8G,WAAY,CAG5D,IADA,GAAIxE,GAAQnB,EAAenB,MAAOuR,EAAU,GACrCjP,GAASA,EAAMmN,SACpB8B,GAAWjP,EAAMmN,QAAQyC,gBAAgBL,GACzCvP,EAAQnB,EAAemB,EAErBiP,IACFvR,KAAKmS,oBAAoBZ,EAASzS,KAIxCsT,kBAAmB,SAASC,EAAO9P,GACjC,GAAIzD,GAAQkB,KAAKgS,iBAAkBzP,EAAOA,GAAQ,EAClD,IAAIzD,IAAUkB,KAAKiS,mBAAmBnT,EAAOkB,KAAK8G,UAAYvE,GAAO,CACnE,GAAIgP,GAAU,EACd,IAAIc,YAAiBpH,OACnB,IAAK,GAAyBqH,GAArB1P,EAAE,EAAGC,EAAEwP,EAAMvP,OAAcD,EAAFD,IAAS0P,EAAED,EAAMzP,IAAKA,IACtD2O,GAAWe,EAAEC,YAAc,WAG7BhB,GAAUc,EAAME,WAElBvS,MAAKmS,oBAAoBZ,EAASzS,EAAOyD,KAG7C4P,oBAAqB,SAASZ,EAASzS,EAAOyD,GAG5C,GAFAzD,EAAQA,GAASkB,KAAKgS,iBACtBzP,EAAOA,GAAQ,GACVzD,EAAL,CAGID,OAAO2T,oBACTjB,EAAUD,EAAYC,EAASzS,EAAMoN,MAEvC,IAAImG,GAAQrS,KAAKyP,QAAQgD,oBAAoBlB,EACzCM,EACJjT,SAAQ8T,kBAAkBL,EAAOvT,GAEjCA,EAAM6T,aAAa3S,KAAK8G,UAAYvE,IAAQ,IAE9CyP,eAAgB,WAGd,IADA,GAAI3S,GAAIW,KACDX,EAAE2M,YACP3M,EAAIA,EAAE2M,UAER,OAAO3M,IAET4S,mBAAoB,SAASnT,EAAOyD,GAElC,MADAzD,GAAM6T,aAAe7T,EAAM6T,iBACpB7T,EAAM6T,aAAapQ,IAsB9BzD,GAAMG,IAAIoF,SAASyN,OAASA,GAE3BlT,SChGH,SAAUE,GAUR,QAAS2Q,GAAQlN,EAAMvD,GACrB,GAAI4T,EAAuBrQ,GACzB,KAAM,sDAAwDA,CAGhEsQ,GAAkBtQ,EAAMvD,GAExB8T,EAAgBvQ,GAKlB,QAASwQ,GAAoBxQ,EAAMyQ,GACjCC,EAAc1Q,GAAQyQ,EAKxB,QAASF,GAAgBvQ,GACnB0Q,EAAc1Q,KAChB0Q,EAAc1Q,GAAM2Q,0BACbD,GAAc1Q,IAgBzB,QAASsQ,GAAkBtQ,EAAMvD,GAC/B,MAAOmU,GAAiB5Q,GAAQvD,MAGlC,QAAS4T,GAAuBrQ,GAC9B,MAAO4Q,GAAiB5Q,GAhD1B,GAAIxD,GAASD,EAAMC,OAsBfkU,GArBMnU,EAAMG,QAwCZkU,IAYJrU,GAAM8T,uBAAyBA,EAC/B9T,EAAMiU,oBAAsBA,EAO5BlU,OAAOD,QAAU6Q,EAKjB1Q,EAAOH,QAASE,EAOhB,IAAIsU,GAAexO,SAASyO,qBAC5B,IAAID,EACF,IAAK,GAAgCrQ,GAA5BH,EAAE,EAAGC,EAAEuQ,EAAatQ,OAAcD,EAAFD,IAASG,EAAEqQ,EAAaxQ,IAAKA,IACpE6M,EAAQ/N,MAAM,KAAMqB,IAIvBnE,SCnFH,SAAUE,GAEV,GAAI0I,IACF8L,oBAAqB,SAAS/N,GAC5BX,SAAS2O,YAAYC,WAAWjO,IAElCkO,kBAAmB,WAEjB,GAAIC,GAAY1T,KAAK2Q,aAAa,cAAgB,GAC9ClD,EAAO,GAAIkG,KAAID,EAAW1T,KAAKuO,cAAcqF,QACjD5T,MAAKhB,UAAU6U,YAAc,SAASC,EAAS3F,GAC7C,GAAI4F,GAAI,GAAIJ,KAAIG,EAAS3F,GAAQV,EACjC,OAAOsG,GAAEC,OAMflV,GAAMG,IAAImF,YAAYoD,KAAOA,GAE1B5I,SCrBH,SAAUE,GA2KR,QAASmV,GAAmBC,EAAOC,GACjC,GAAIH,GAAO,GAAIL,KAAIO,EAAMvD,aAAa,QAASwD,GAASH,IACxD,OAAO,YAAeA,EAAO,KAG/B,QAAStB,GAAkBL,EAAOvT,GAChC,GAAIuT,EAAO,CACLvT,IAAUsC,WACZtC,EAAQsC,SAASgT,MAEfvV,OAAO2T,oBACT1T,EAAQsC,SAASgT,KAOnB,IAAIC,GAAQC,EAAmBjC,EAAME,aACjCgC,EAAOlC,EAAM1B,aAAaiB,EAC1B2C,IACFF,EAAMjM,aAAawJ,EAAuB2C,GAE5CzV,EAAMoR,YAAYmE,IAItB,QAASC,GAAmB/C,EAASzS,GACnCA,EAAQA,GAASsC,SACjBtC,EAAQA,EAAMuC,cAAgBvC,EAAQA,EAAMyP,aAC5C,IAAI8D,GAAQvT,EAAMuC,cAAc,QAEhC,OADAgR,GAAME,YAAchB,EACbc,EAGT,QAASmC,GAAiBN,GACxB,MAAQA,IAASA,EAAMO,YAAe,GAGxC,QAASC,GAAgBnP,EAAMoP,GAC7B,MAAIC,GACKA,EAAQ/T,KAAK0E,EAAMoP,GAD5B,OA/MF,GACI1V,IADMJ,OAAO2H,aACP1H,EAAMG,IAAIoF,SAASyN,QACzBF,EAAwB3S,EAAI2S,sBAI5BiD,EAAiB,QACjBC,EAAuB,UACvBC,EAAiB,uBACjBC,EAAqB,SACrBC,EAAa,gBAEbnD,GAEFoD,WAAY,SAAStV,GACnB,GAAIuV,GAAUnV,KAAKoV,iBACfD,IACFnV,KAAKqV,sBAAsBF,EAE7B,IAAIrD,GAAS9R,KAAKsV,mBAAmBH,EACjCrD,GAAOhP,OACT8B,SAAS2Q,cAAcL,WAAWpD,EAAQlS,GACjCA,GACTA,KAGJyV,sBAAuB,SAAS5H,GAE9B,IAAK,GAAsB6E,GAAGkD,EAD1BC,EAAKhI,EAAK+C,iBAAiBuE,GACtBnS,EAAE,EAAGC,EAAE4S,EAAG3S,OAAiBD,EAAFD,IAAS0P,EAAEmD,EAAG7S,IAAKA,IACnD4S,EAAIlB,EAAmBL,EAAmB3B,EAAGtS,KAAKuO,cAAcqF,SAC5D5T,KAAKuO,eACTvO,KAAK0V,oBAAoBF,EAAGlD,GAC5BA,EAAEtG,WAAW2J,aAAaH,EAAGlD,IAGjCoD,oBAAqB,SAASrD,EAAOuD,GACnC,IAAK,GAA0CrN,GAAtC3F,EAAE,EAAGoF,EAAG4N,EAAK9N,WAAYjF,EAAEmF,EAAGlF,QAAYyF,EAAEP,EAAGpF,KAASC,EAAFD,EAAKA,IACnD,QAAX2F,EAAEhG,MAA6B,SAAXgG,EAAEhG,MACxB8P,EAAMjK,aAAaG,EAAEhG,KAAMgG,EAAE9I,QAInC6V,mBAAoB,SAAS7H,GAC3B,GAAIoI,KACJ,IAAIpI,EAEF,IAAK,GAAsB6E,GADvBmD,EAAKhI,EAAK+C,iBAAiBqE,GACtBjS,EAAE,EAAGC,EAAE4S,EAAG3S,OAAcD,EAAFD,IAAS0P,EAAEmD,EAAG7S,IAAKA,IAC5C0P,EAAEC,YAAY3J,MAAMkM,IACtBe,EAAUC,KAAKxD,EAIrB,OAAOuD,IAOTE,cAAe,WACb/V,KAAKgW,cACLhW,KAAKiW,cACLjW,KAAKkW,qBACLlW,KAAKmW,uBAKPH,YAAa,WACXhW,KAAKoW,OAASpW,KAAKqW,UAAUtB,GAC7B/U,KAAKoW,OAAOhX,QAAQ,SAASkT,GACvBA,EAAEtG,YACJsG,EAAEtG,WAAWsK,YAAYhE,MAI/B2D,YAAa,WACXjW,KAAK8R,OAAS9R,KAAKqW,UAAUxB,EAAiB,IAAMI,EAAa,KACjEjV,KAAK8R,OAAO1S,QAAQ,SAASkT,GACvBA,EAAEtG,YACJsG,EAAEtG,WAAWsK,YAAYhE,MAa/B4D,mBAAoB,WAClB,GAAIE,GAASpW,KAAKoW,OAAOG,OAAO,SAASjE,GACvC,OAAQA,EAAEnK,aAAa8M,KAErBE,EAAUnV,KAAKoV,iBACnB,IAAID,EAAS,CACX,GAAI5D,GAAU,EAId,IAHA6E,EAAOhX,QAAQ,SAAS8U,GACtB3C,GAAWiD,EAAiBN,GAAS,OAEnC3C,EAAS,CACX,GAAIc,GAAQiC,EAAmB/C,EAASvR,KAAKuO,cAC7C4G,GAAQqB,aAAanE,EAAO8C,EAAQ3I,eAI1C6J,UAAW,SAAS5E,EAAUgF,GAC5B,GAAIC,GAAQ1W,KAAKwQ,iBAAiBiB,GAAUkF,QACxCxB,EAAUnV,KAAKoV,iBACnB,IAAID,EAAS,CACX,GAAIyB,GAAgBzB,EAAQ3E,iBAAiBiB,GAAUkF,OACvDD,GAAQA,EAAMG,OAAOD,GAEvB,MAAOH,GAAUC,EAAMH,OAAOE,GAAWC,GAE3CtB,gBAAiB,WACf,GAAItI,GAAW9M,KAAK8P,cAAc,WAClC,OAAOhD,IAAYsI,gBAAgBtI,IAWrCqJ,oBAAqB,WACnB,GAAI9D,GAAQrS,KAAK8W,cAAc9B,EAC/BtC,GAAkBL,EAAOjR,SAASgT,OAEpClC,gBAAiB,SAAS6E,GACxB,GAAIxF,GAAU,GAEVE,EAAW,IAAMwD,EAAa,IAAM8B,EAAkB,IACtDN,EAAU,SAASnE,GACrB,MAAOoC,GAAgBpC,EAAGb,IAExB2E,EAASpW,KAAKoW,OAAOG,OAAOE,EAChCL,GAAOhX,QAAQ,SAAS8U,GACtB3C,GAAWiD,EAAiBN,GAAS,QAGvC,IAAIpC,GAAS9R,KAAK8R,OAAOyE,OAAOE,EAIhC,OAHA3E,GAAO1S,QAAQ,SAASiT,GACtBd,GAAWc,EAAME,YAAc,SAE1BhB,GAETuF,cAAe,SAASC,GACtB,GAAIxF,GAAUvR,KAAKkS,gBAAgB6E,EACnC,OAAO/W,MAAKyS,oBAAoBlB,EAASwF,IAE3CtE,oBAAqB,SAASlB,EAASwF,GACrC,GAAIxF,EAAS,CACX,GAAIc,GAAQiC,EAAmB/C,EAG/B,OAFAc,GAAMjK,aAAawJ,EAAuB5R,KAAK2Q,aAAa,QACxD,IAAMoG,GACH1E,KAiDT5P,EAAI1B,YAAY/B,UAChB4V,EAAUnS,EAAEmS,SAAWnS,EAAEiS,iBAAmBjS,EAAEuU,uBAC3CvU,EAAEwU,kBAITnY,GAAMG,IAAImF,YAAY0N,OAASA,EAC/BhT,EAAM4T,kBAAoBA,GAEzB9T,SC/NH,SAAUE,GAIR,GACIG,IADMJ,OAAO2H,aACP1H,EAAMG,IAAIoF,SAASqC,QACzBD,EAAexH,EAAIwH,aAGnBC,GACFwQ,gBAAiB,WAEf,GAAIC,GAAYnX,KAAKhB,UAAU4H,cAE/B5G,MAAKoX,sBAAsBD,IAE7BC,sBAAuB,SAASD,GAE9B,IAAK,GAAS5O,GAAL3F,EAAE,EAAM2F,EAAEvI,KAAK8H,WAAWlF,GAAIA,IAEjC5C,KAAKqX,eAAe9O,EAAEhG,QAExB4U,EAAUnX,KAAKsX,kBAAkB/O,EAAEhG,OAASgG,EAAE9I,MAAMwE,QAAQ,KAAM,IAC7DA,QAAQ,KAAM,IAAIsT,SAK7BF,eAAgB,SAAUhY,GACxB,MAAOA,IAAe,MAATA,EAAE,IAAyB,MAATA,EAAE,IAAyB,MAATA,EAAE,IAErDiY,kBAAmB,SAASjY,GAC1B,MAAOA,GAAEmY,MAAMC,KAIfA,EAAehR,EAAa3D,MAGhChE,GAAMG,IAAImF,YAAYsC,OAASA,GAE9B9H,SC1CH,SAAUE,GAIR,GAAIgL,IACF4N,eAAgB,SAAS1Y,GAEvB,GAAiCwM,GAA7BhB,EAAUxL,EAAUwL,OACxB,KAAK,GAAInL,KAAKL,GACQ,YAAhBK,EAAEmY,MAAM,MACLhN,IACHA,EAAYxL,EAAUwL,YAExBgB,EAAWnM,EAAEmY,MAAM,EAAG,IACtBhN,EAAQgB,GAAYhB,EAAQgB,IAAanM,IAI/CsY,iBAAkB,SAAS3Y,GAEzB,GAAImL,GAAInL,EAAUwL,OAClB,IAAIL,EAAG,CACL,GAAIyN,KACJ,KAAK,GAAIvY,KAAK8K,GAEZ,IAAK,GAAS0N,GADVC,EAAQzY,EAAE0Y,MAAM,KACXnV,EAAE,EAAOiV,EAAGC,EAAMlV,GAAIA,IAC7BgV,EAASC,GAAM1N,EAAE9K,EAGrBL,GAAUwL,QAAUoN,IAGxBI,qBAAsB,SAAShZ,GAC7B,GAAIA,EAAUwL,QAAS,CAErB,GAAIjC,GAAIvJ,EAAUgL,gBAClB,KAAK,GAAI3K,KAAKL,GAAUwL,QAEtB,IAAK,GAASqN,GADVC,EAAQzY,EAAE0Y,MAAM,KACXnV,EAAE,EAAOiV,EAAGC,EAAMlV,GAAIA,IAC7B2F,EAAEuN,KAAK+B,GAKb,GAAI7Y,EAAUsF,QAAS,CAErB,GAAIiE,GAAIvJ,EAAUkL,gBAClB,KAAK,GAAI7K,KAAKL,GAAUsF,QACtBiE,EAAEuN,KAAKzW,KAIb4Y,kBAAmB,SAASjZ,EAAWmP,GAErC,GAAI7J,GAAUtF,EAAUsF,OACpBA,KAEFtE,KAAKkY,kBAAkB5T,EAAStF,EAAWmP,GAE3CnP,EAAUsJ,WAAatI,KAAKmY,aAAa7T,KAG7C4T,kBAAmB,SAASpO,EAAY9K,EAAWmP,GAEjD,IAAK,GAAI9O,KAAKyK,GACSpE,SAAjB1G,EAAUK,IAAgCqG,SAAZyI,EAAK9O,KACrCL,EAAUK,GAAKyK,EAAWzK,KAIhC8Y,aAAc,SAASrO,GACrB,GAAIsO,KACJ,KAAK,GAAI/Y,KAAKyK,GACZsO,EAAI/Y,EAAEgZ,eAAiBhZ,CAEzB,OAAO+Y,IAMXtZ,GAAMG,IAAImF,YAAY0F,WAAaA,GAElClL,SCnFH,SAAUE,GAIR,GAAIwZ,GAAuB,aACvBC,EAAmB,OAInBzQ,GACF0Q,yBAA0B,SAASxZ,GAEjCgB,KAAKyY,cAAczZ,EAAW,aAE9BgB,KAAKyY,cAAczZ,EAAW,wBAEhC0Z,kBAAmB,SAAS1Z,EAAWmP,GAErC,GAAIrG,GAAa9H,KAAK2Q,aAAa2H,EACnC,IAAIxQ,EAMF,IAAK,GAAyBzI,GAJ1BiF,EAAUtF,EAAUsF,UAAYtF,EAAUsF,YAE1CwT,EAAQhQ,EAAWiQ,MAAMQ,GAEpB3V,EAAE,EAAGC,EAAEiV,EAAMhV,OAAaD,EAAFD,EAAKA,IAEpCvD,EAAIyY,EAAMlV,GAAG2U,OAETlY,GAAoBqG,SAAfpB,EAAQjF,IAAgCqG,SAAZyI,EAAK9O,KACxCiF,EAAQjF,GAAK,OAMrBsZ,6BAA8B,WAK5B,IAAK,GAAsBpQ,GAHvBqQ,EAAW5Y,KAAKhB,UAAUiJ,oBAE1BD,EAAKhI,KAAK8H,WACLlF,EAAE,EAAGC,EAAEmF,EAAGlF,OAAcD,EAAFD,IAAS2F,EAAEP,EAAGpF,IAAKA,IAC5C5C,KAAK6Y,oBAAoBtQ,EAAEhG,QAC7BqW,EAASrQ,EAAEhG,MAAQgG,EAAE9I,QAI3BoZ,oBAAqB,SAAStW,GAC5B,OAAQvC,KAAK8Y,UAAUvW,IAA6B,QAApBA,EAAKiV,MAAM,EAAE,IAG/CsB,WACEvW,KAAM,EACNwW,UAAW,EACX3H,YAAa,EACb4H,SAAU,EACVC,UAAW,EACXC,gBAAiB,GAKrBpR,GAAWgR,UAAUR,GAAwB,EAI7CxZ,EAAMG,IAAImF,YAAY0D,WAAaA,GAElClJ,SCpEH,SAAUE,GA+NR,QAASqa,GAAyBna,GAChC,IAAKE,OAAOwD,UAAW,CACrB,GAAI0W,GAAWla,OAAOiC,eAAenC,EACrCA,GAAU0D,UAAY0W,EAClBrL,EAAOqL,KACTA,EAAS1W,UAAYxD,OAAOiC,eAAeiY,KAhOjD,GAAIna,GAAMH,EAAMG,IACZ8O,EAASjP,EAAMiP,OACfhP,EAASD,EAAMC,OAIfC,GAEFgC,SAAU,SAASuB,EAAM8W,GAEvBrZ,KAAKsZ,eAAe/W,EAAM8W,GAE1BrZ,KAAK6S,kBAAkBtQ,EAAM8W,GAE7BrZ,KAAKuZ,sBAGPD,eAAgB,SAAS/W,EAAM8W,GAE7B,GAAIG,GAAY1a,EAAM8T,uBAAuBrQ,GAEzC4L,EAAOnO,KAAKyZ,sBAAsBJ,EAEtCrZ,MAAK0Z,sBAAsBF,EAAWrL,GAEtCnO,KAAKhB,UAAYgB,KAAK2Z,gBAAgBH,EAAWrL,GAEjDnO,KAAK4Z,qBAAqBrX,EAAM8W,IAGlCK,sBAAuB,SAAS1a,EAAWmP,GAGzCnP,EAAUyQ,QAAUzP,KAEpBA,KAAK0Y,kBAAkB1Z,EAAWmP,GAElCnO,KAAKiY,kBAAkBjZ,EAAWmP,GAElCnO,KAAK0X,eAAe1Y,GAEpBgB,KAAK2X,iBAAiB3Y,IAGxB2a,gBAAiB,SAAS3a,EAAWmP,GAEnCnO,KAAK6Z,gBAAgB7a,EAAWmP,EAEhC,IAAI2L,GAAU9Z,KAAK+Z,YAAY/a,EAAWmP,EAG1C,OADAgL,GAAyBW,GAClBA,GAGTD,gBAAiB,SAAS7a,EAAWmP,GAEnCnO,KAAKyY,cAAc,UAAWzZ,EAAWmP,GAEzCnO,KAAKyY,cAAc,UAAWzZ,EAAWmP,GAEzCnO,KAAKyY,cAAc,aAAczZ,EAAWmP,GAE5CnO,KAAKyY,cAAc,sBAAuBzZ,EAAWmP,GAErDnO,KAAKyY,cAAc,iBAAkBzZ,EAAWmP,IAIlDyL,qBAAsB,SAASrX,EAAMyX,GAEnCha,KAAKgY,qBAAqBhY,KAAKhB,WAE/BgB,KAAK+V,gBAEL/V,KAAKsT,oBAAoBtT,MAEzBA,KAAK2Y,+BAEL3Y,KAAKkX,kBAKLlX,KAAKyT,oBAED5U,OAAO2T,mBACT5N,SAAS8M,UAAUuI,YAAYja,KAAKoV,kBAAmB7S,EAAMyX,GAG3Dha,KAAKhB,UAAUkb,kBACjBla,KAAKhB,UAAUkb,iBAAiBla,OAMpCuZ,mBAAoB,WAClB,GAAIY,GAASna,KAAK2Q,aAAa,cAC3BwJ,KACFtb,OAAOsb,GAAUna,KAAKoa,OAK1BX,sBAAuB,SAASY,GAC9B,GAAIrb,GAAYgB,KAAKsa,kBAAkBD,EACvC,KAAKrb,EAAW,CAEd,GAAIA,GAAY+B,YAAYG,mBAAmBmZ,EAE/Crb,GAAYgB,KAAKua,cAAcvb,GAE/Bwb,EAAcH,GAAUrb,EAE1B,MAAOA,IAGTsb,kBAAmB,SAAS/X,GAC1B,MAAOiY,GAAcjY,IAIvBgY,cAAe,SAASvb,GACtB,GAAIA,EAAUiP,YACZ,MAAOjP,EAET,IAAIyb,GAAWvb,OAAOwb,OAAO1b,EAkB7B,OAfAC,GAAIqF,QAAQrF,EAAIoF,SAAUoW,GAa1Bza,KAAK2a,YAAYF,EAAUzb,EAAWC,EAAIoF,SAASuI,IAAK,QAEjD6N,GAGTE,YAAa,SAASF,EAAUzb,EAAWC,EAAKsD,GAC9C,GAAIX,GAAS,SAAS8C,GACpB,MAAO1F,GAAUuD,GAAMb,MAAM1B,KAAM0E,GAErC+V,GAASlY,GAAQ,WAEf,MADAvC,MAAKqN,WAAazL,EACX3C,EAAIsD,GAAMb,MAAM1B,KAAM2B,aAKjC8W,cAAe,SAASlW,EAAMvD,EAAWmP,GAEvC,GAAIyM,GAAS5b,EAAUuD,MAEvBvD,GAAUuD,GAAQvC,KAAK+Z,YAAYa,EAAQzM,EAAK5L,KAIlDsQ,kBAAmB,SAAStQ,EAAMyX,GAChC,GAAIa,IACF7b,UAAWgB,KAAKhB,WAGd8b,EAAgB9a,KAAK+a,kBAAkBf,EACvCc,KACFD,EAAK9B,QAAU+B,GAGjB/Z,YAAYC,SAASuB,EAAMvC,KAAKhB,WAEhCgB,KAAKoa,KAAOhZ,SAAS4Z,gBAAgBzY,EAAMsY,IAG7CE,kBAAmB,SAASxY,GAC1B,GAAIA,GAAQA,EAAK0Y,QAAQ,KAAO,EAC9B,MAAO1Y,EAEP,IAAIE,GAAIzC,KAAKsa,kBAAkB/X,EAC/B,OAAIE,GAAEgN,QACGzP,KAAK+a,kBAAkBtY,EAAEgN,QAAQsJ,SAD1C,SASFyB,IAIFxb,GAAU+a,YADR7a,OAAOwD,UACe,SAASqB,EAAQmX,GAIvC,MAHInX,IAAUmX,GAAanX,IAAWmX,IACpCnX,EAAOrB,UAAYwY,GAEdnX,GAGe,SAASA,EAAQmX,GACvC,GAAInX,GAAUmX,GAAanX,IAAWmX,EAAW,CAC/C,GAAIpB,GAAU5a,OAAOwb,OAAOQ,EAC5BnX,GAAShF,EAAO+a,EAAS/V,GAE3B,MAAOA,IAoBX9E,EAAImF,YAAYpF,UAAYA,GAE3BJ,SC7OH,SAAUE,GA4FR,QAASqc,GAAgB1L,GACvB,MAAOrO,UAASga,SAAS3L,GAAW4L,EAAYC,EAGlD,QAASC,KACP,MAAOD,GAAYxY,OAASwY,EAAY,GAAKD,EAAU,GASzD,QAASG,GAAiB5b,GACxB6b,EAAMC,aAAc,EACpBC,eAAetN,OAAQ,EACvBuN,YAAYC,iBAAiB,WAC3BJ,EAAMK,iBAAiBlc,GACvB6b,EAAMC,aAAc,EACpBD,EAAMM,UA9GV,GAAIN,IAEF5b,KAAM,SAAS4P,EAASsM,EAAO9b,GAM7B,MAL8B,KAA1BD,KAAKib,QAAQxL,KACfzP,KAAKmG,IAAIsJ,GACTA,EAAQuM,QAAUD,EAClBtM,EAAQwM,KAAOhc,GAEiB,IAA1BD,KAAKib,QAAQxL,IAEvBtJ,IAAK,SAASsJ,GAEZ0L,EAAgB1L,GAASqG,KAAKrG,IAEhCwL,QAAS,SAASxL,GAChB,GAAI7M,GAAIuY,EAAgB1L,GAASwL,QAAQxL,EAKzC,OAJI7M,IAAK,GAAKxB,SAASga,SAAS3L,KAC9B7M,GAAMgZ,YAAYM,WAAaN,YAAYvN,MAASiN,EAAYxY,OAC5D,KAECF,GAGT3C,GAAI,SAASwP,GACX,GAAI0M,GAAUnc,KAAKkG,OAAOuJ,EACtB0M,KACFA,EAAQF,KAAKpb,KAAKsb,GAClBA,EAAQH,QAAUG,EAAQF,KAAO,KACjCjc,KAAK+b,UAGT7V,OAAQ,SAASuJ,GACf,GAAI7M,GAAI5C,KAAKib,QAAQxL,EACrB,IAAU,IAAN7M,EAIJ,MAAOuY,GAAgB1L,GAAS2M,SAElCL,MAAO,WAEL,GAAItM,GAAUzP,KAAKqc,aAInB,OAHI5M,IACFA,EAAQuM,QAAQnb,KAAK4O,GAEnBzP,KAAKsc,YACPtc,KAAKqO,SACE,GAFT,QAKFgO,YAAa,WACX,MAAOd,MAETe,SAAU,WACR,OAAQtc,KAAK0b,aAAe1b,KAAKuc,WAEnCA,QAAS,WACP,OAAQjB,EAAYxY,SAAWuY,EAAUvY,QAE3CuL,MAAO,WAWL,GAJIsN,eAAetN,SAAU,IAC3BsN,eAAea,oBAAoBpb,UACnCua,eAAetN,OAAQ,GAErBoO,EAEF,IADA,GAAIra,GACGqa,EAAe3Z,SACpBV,EAAKqa,EAAeL,YAK1BN,iBAAkB,SAASlc,GACrBA,GACF6c,EAAe3G,KAAKlW,IAGxB8b,aAAa,GAGXJ,KACAD,KACAoB,IAYJrb,UAASsb,iBAAiB,qBAAsB,WAC9Cf,eAAetN,OAAQ,IAczBvP,EAAM2c,MAAQA,EACd3c,EAAM0c,iBAAmBA,GACxB5c,SCvHH,SAAUE,GAIR,QAAS6d,GAAeC,EAAmBhd,GACrCgd,GACFxb,SAASgT,KAAKlE,YAAY0M,GAC1BpB,EAAiB5b,IACRA,GACTA,IAIJ,QAASid,GAAWC,EAAMld,GACxB,GAAIkd,GAAQA,EAAKha,OAAQ,CAErB,IAAK,GAAwBia,GAAKnH,EAD9BoH,EAAO5b,SAAS6b,yBACXra,EAAE,EAAGC,EAAEia,EAAKha,OAAsBD,EAAFD,IAASma,EAAID,EAAKla,IAAKA,IAC9DgT,EAAOxU,SAASC,cAAc,QAC9BuU,EAAKsH,IAAM,SACXtH,EAAK5B,KAAO+I,EACZC,EAAK9M,YAAY0F,EAEnB+G,GAAeK,EAAMpd,OACdA,IACTA,IAtBJ,GAAI4b,GAAmB1c,EAAM0c,gBA2B7B1c,GAAMqe,OAASN,EACf/d,EAAM6d,eAAiBA,GAEtB/d,SChCH,SAAUE,GAsHR,QAASse,GAAa7a,GACpB,MAAO8a,SAAQtc,YAAYG,mBAAmBqB,IAGhD,QAAS+a,GAAY/a,GACnB,MAAQA,IAAQA,EAAK0Y,QAAQ,MAAQ,EAvHvC,GAAIlc,GAASD,EAAMC,OACfE,EAAMH,EAAMG,IACZwc,EAAQ3c,EAAM2c,MACdD,EAAmB1c,EAAM0c,iBACzB5I,EAAyB9T,EAAM8T,uBAC/BG,EAAsBjU,EAAMiU,oBAI5B/T,EAAYD,EAAOG,OAAOwb,OAAO3Z,YAAY/B,YAE/CsP,gBAAiB,WACXtO,KAAK2Q,aAAa,SACpB3Q,KAAKud,QAITA,KAAM,WAEJvd,KAAKuC,KAAOvC,KAAK2Q,aAAa,QAC9B3Q,KAAK+Y,QAAU/Y,KAAK2Q,aAAa,WAEjC3Q,KAAKwd,gBAELxd,KAAKkT,qBAGPA,kBAAmB,WACdlT,KAAKyd,YACJzd,KAAK+S,oBAAoB/S,KAAKuC,OAC9BvC,KAAK0d,mBACL1d,KAAK2d,uBAGTlC,EAAMxb,GAAGD,OAMX4d,UAAW,WAILN,EAAYtd,KAAK+Y,WAAaqE,EAAapd,KAAK+Y,UAClD9W,QAAQC,KAAK,sGACuClC,KAAKuC,KACrDvC,KAAK+Y,SAEX/Y,KAAKgB,SAAShB,KAAKuC,KAAMvC,KAAK+Y,SAC9B/Y,KAAKyd,YAAa,GAIpB1K,oBAAqB,SAASxQ,GAC5B,MAAKqQ,GAAuBrQ,GAA5B,QAEEwQ,EAAoBxQ,EAAMvC,MAE1BA,KAAK6d,eAAetb,IAEb,IAIXsb,eAAgB,SAAStb,GAEvB,GAAIvC,KAAKmI,aAAa,cAAgBnI,KAAKgZ,SAQzC,GAPAhZ,KAAKgZ,UAAW,EAOZna,OAAO8c,iBAAmBA,eAAeO,UAC3Ctd,QAAQ2D,OACH,CACL,GAAIub,GAAS1c,SAASC,cAAc,SACpCyc,GAAOvL,YAAc,YAAehQ,EAAO,MAC3CvC,KAAKkQ,YAAY4N,KAKvBH,oBAAqB,WACnB,MAAO3d,MAAK+d,iBAMdL,gBAAiB,WACf,MAAOjC,GAAM5b,KAAKG,KAAMA,KAAKkT,kBAAmBlT,KAAK4d,YAGvDJ,cAAe,WACbxd,KAAK+d,iBAAkB,EACvB/d,KAAKkV,WAAW,WACdlV,KAAK+d,iBAAkB,EACvB/d,KAAKkT,qBACL5S,KAAKN,SASXf,GAAIqF,QAAQrF,EAAImF,YAAapF,GAc7BF,EAAM8T,uBAAyBA,EAI/B4I,EAAiB,WACfpa,SAAS4c,KAAK/U,gBAAgB,cAC9B7H,SAASuE,cACP,GAAIF,aAAY,iBAAkBJ,SAAS,OAM/CjE,SAAS4Z,gBAAgB,mBAAoBhc,UAAWA,KAEvDJ","sourcesContent":["/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\nPolymer = {};\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n// TODO(sorvell): this ensures Polymer is an object and not a function\n// Platform is currently defining it as a function to allow for async loading\n// of polymer; once we refine the loading process this likely goes away.\nif (typeof window.Polymer === 'function') {\n  Polymer = {};\n}\n\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // copy own properties from 'api' to 'prototype, with name hinting for 'super'\n  function extend(prototype, api) {\n    if (prototype && api) {\n      // use only own properties of 'api'\n      Object.getOwnPropertyNames(api).forEach(function(n) {\n        // acquire property descriptor\n        var pd = Object.getOwnPropertyDescriptor(api, n);\n        if (pd) {\n          // clone property via descriptor\n          Object.defineProperty(prototype, n, pd);\n          // cache name-of-method for 'super' engine\n          if (typeof pd.value == 'function') {\n            // hint the 'super' engine\n            pd.value.nom = n;\n          }\n        }\n      });\n    }\n    return prototype;\n  }\n  \n  // exports\n\n  scope.extend = extend;\n\n})(Polymer);\n","/* \n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  \n  // usage\n  \n  // invoke cb.call(this) in 100ms, unless the job is re-registered,\n  // which resets the timer\n  // \n  // this.myJob = this.job(this.myJob, cb, 100)\n  //\n  // returns a job handle which can be used to re-register a job\n\n  var Job = function(inContext) {\n    this.context = inContext;\n    this.boundComplete = this.complete.bind(this)\n  };\n  Job.prototype = {\n    go: function(callback, wait) {\n      this.callback = callback;\n      var h;\n      if (!wait) {\n        h = requestAnimationFrame(this.boundComplete);\n        this.handle = function() {\n          cancelAnimationFrame(h);\n        }\n      } else {\n        h = setTimeout(this.boundComplete, wait);\n        this.handle = function() {\n          clearTimeout(h);\n        }\n      }\n    },\n    stop: function() {\n      if (this.handle) {\n        this.handle();\n        this.handle = null;\n      }\n    },\n    complete: function() {\n      if (this.handle) {\n        this.stop();\n        this.callback.call(this.context);\n      }\n    }\n  };\n  \n  function job(job, callback, wait) {\n    if (job) {\n      job.stop();\n    } else {\n      job = new Job(this);\n    }\n    job.go(callback, wait);\n    return job;\n  }\n  \n  // exports \n\n  scope.job = job;\n  \n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  var registry = {};\n\n  HTMLElement.register = function(tag, prototype) {\n    registry[tag] = prototype;\n  }\n\n  // get prototype mapped to node <tag>\n  HTMLElement.getPrototypeForTag = function(tag) {\n    var prototype = !tag ? HTMLElement.prototype : registry[tag];\n    // TODO(sjmiles): creating <tag> is likely to have wasteful side-effects\n    return prototype || Object.getPrototypeOf(document.createElement(tag));\n  };\n\n  // we have to flag propagation stoppage for the event dispatcher\n  var originalStopPropagation = Event.prototype.stopPropagation;\n  Event.prototype.stopPropagation = function() {\n    this.cancelBubble = true;\n    originalStopPropagation.apply(this, arguments);\n  };\n  \n  // TODO(sorvell): remove when we're sure imports does not need\n  // to load stylesheets\n  /*\n  HTMLImports.importer.preloadSelectors += \n      ', polymer-element link[rel=stylesheet]';\n  */\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n (function(scope) {\n    // super\n\n    // `arrayOfArgs` is an optional array of args like one might pass\n    // to `Function.apply`\n\n    // TODO(sjmiles):\n    //    $super must be installed on an instance or prototype chain\n    //    as `super`, and invoked via `this`, e.g.\n    //      `this.super();`\n\n    //    will not work if function objects are not unique, for example,\n    //    when using mixins.\n    //    The memoization strategy assumes each function exists on only one \n    //    prototype chain i.e. we use the function object for memoizing)\n    //    perhaps we can bookkeep on the prototype itself instead\n    function $super(arrayOfArgs) {\n      // since we are thunking a method call, performance is important here: \n      // memoize all lookups, once memoized the fast path calls no other \n      // functions\n      //\n      // find the caller (cannot be `strict` because of 'caller')\n      var caller = $super.caller;\n      // memoized 'name of method' \n      var nom = caller.nom;\n      // memoized next implementation prototype\n      var _super = caller._super;\n      if (!_super) {\n        if (!nom) {\n          nom = caller.nom = nameInThis.call(this, caller);\n        }\n        if (!nom) {\n          console.warn('called super() on a method not installed declaratively (has no .nom property)');\n        }\n        // super prototype is either cached or we have to find it\n        // by searching __proto__ (at the 'top')\n        _super = memoizeSuper(caller, nom, getPrototypeOf(this));\n      }\n      if (!_super) {\n        // if _super is falsey, there is no super implementation\n        //console.warn('called $super(' + nom + ') where there is no super implementation');\n      } else {\n        // our super function\n        var fn = _super[nom];\n        // memoize information so 'fn' can call 'super'\n        if (!fn._super) {\n          memoizeSuper(fn, nom, _super);\n        }\n        // invoke the inherited method\n        // if 'fn' is not function valued, this will throw\n        return fn.apply(this, arrayOfArgs || []);\n      }\n    }\n\n    function nextSuper(proto, name, caller) {\n      // look for an inherited prototype that implements name\n      while (proto) {\n        if ((proto[name] !== caller) && proto[name]) {\n          return proto;\n        }\n        proto = getPrototypeOf(proto);\n      }\n    }\n\n    function memoizeSuper(method, name, proto) {\n      // find and cache next prototype containing `name`\n      // we need the prototype so we can do another lookup\n      // from here\n      method._super = nextSuper(proto, name, method);\n      if (method._super) {\n        // _super is a prototype, the actual method is _super[name]\n        // tag super method with it's name for further lookups\n        method._super[name].nom = name;\n      }\n      return method._super;\n    }\n\n    function nameInThis(value) {\n      var p = this.__proto__;\n      while (p && p !== HTMLElement.prototype) {\n        // TODO(sjmiles): getOwnPropertyNames is absurdly expensive\n        var n$ = Object.getOwnPropertyNames(p);\n        for (var i=0, l=n$.length, n; i<l && (n=n$[i]); i++) {\n          var d = Object.getOwnPropertyDescriptor(p, n);\n          if (typeof d.value === 'function' && d.value === value) {\n            return n;\n          }\n        }\n        p = p.__proto__;\n      }\n    }\n\n    // NOTE: In some platforms (IE10) the prototype chain is faked via \n    // __proto__. Therefore, always get prototype via __proto__ instead of\n    // the more standard Object.getPrototypeOf.\n    function getPrototypeOf(prototype) {\n      return prototype.__proto__;\n    }\n\n    // utility function to precompute name tags for functions\n    // in a (unchained) prototype\n    function hintSuper(prototype) {\n      // tag functions with their prototype name to optimize\n      // super call invocations\n      for (var n in prototype) {\n        var pd = Object.getOwnPropertyDescriptor(prototype, n);\n        if (pd && typeof pd.value === 'function') {\n          pd.value.nom = n;\n        }\n      }\n    }\n\n    // exports\n\n    scope.super = $super;\n\n})(Polymer);\n","/* \n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n  var typeHandlers = {\n    string: function(value) {\n      return value;\n    },\n    date: function(value) {\n      return new Date(Date.parse(value) || Date.now());\n    },\n    boolean: function(value) {\n      if (value === '') {\n        return true;\n      }\n      return value === 'false' ? false : !!value;\n    },\n    number: function(value) {\n      var n = parseFloat(value);\n      // hex values like \"0xFFFF\" parseFloat as 0\n      if (n === 0) {\n        n = parseInt(value);\n      }\n      return isNaN(n) ? value : n;\n      // this code disabled because encoded values (like \"0xFFFF\")\n      // do not round trip to their original format\n      //return (String(floatVal) === value) ? floatVal : value;\n    },\n    object: function(value, currentValue) {\n      if (currentValue === null) {\n        return value;\n      }\n      try {\n        // If the string is an object, we can parse is with the JSON library.\n        // include convenience replace for single-quotes. If the author omits\n        // quotes altogether, parse will fail.\n        return JSON.parse(value.replace(/'/g, '\"'));\n      } catch(e) {\n        // The object isn't valid JSON, return the raw value\n        return value;\n      }\n    },\n    // avoid deserialization of functions\n    'function': function(value, currentValue) {\n      return currentValue;\n    }\n  };\n\n  function deserializeValue(value, currentValue) {\n    // attempt to infer type from default value\n    var inferredType = typeof currentValue;\n    // invent 'date' type value for Date\n    if (currentValue instanceof Date) {\n      inferredType = 'date';\n    }\n    // delegate deserialization via type string\n    return typeHandlers[inferredType](value, currentValue);\n  }\n\n  // exports\n\n  scope.deserializeValue = deserializeValue;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var extend = scope.extend;\n\n  // module\n\n  var api = {};\n\n  api.declaration = {};\n  api.instance = {};\n\n  api.publish = function(apis, prototype) {\n    for (var n in apis) {\n      extend(prototype, apis[n]);\n    }\n  }\n\n  // exports\n\n  scope.api = api;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  var utils = {\n    /**\n      * Invokes a function asynchronously. The context of the callback\n      * function is bound to 'this' automatically.\n      * @method async\n      * @param {Function|String} method\n      * @param {any|Array} args\n      * @param {number} timeout\n      */\n    async: function(method, args, timeout) {\n      // when polyfilling Object.observe, ensure changes \n      // propagate before executing the async method\n      Platform.flush();\n      // second argument to `apply` must be an array\n      args = (args && args.length) ? args : [args];\n      // function to invoke\n      var fn = function() {\n        (this[method] || method).apply(this, args);\n      }.bind(this);\n      // execute `fn` sooner or later\n      var handle = timeout ? setTimeout(fn, timeout) :\n          requestAnimationFrame(fn);\n      // NOTE: switch on inverting handle to determine which time is used.\n      return timeout ? handle : 1 / handle;\n    },\n    cancelAsync: function(handle) {\n      if (handle < 1) {\n        cancelAnimationFrame(Math.round(1 / handle));\n      } else {\n        clearTimeout(handle);\n      }\n    },\n    /**\n      * Fire an event.\n      * @method fire\n      * @returns {Object} event\n      * @param {string} type An event name.\n      * @param {any} detail\n      * @param {Node} onNode Target node.\n      */\n    fire: function(type, detail, onNode, bubbles, cancelable) {\n      var node = onNode || this;\n      var detail = detail || {};\n      var event = new CustomEvent(type, {\n        bubbles: (bubbles !== undefined ? bubbles : true), \n        cancelable: (cancelable !== undefined ? cancelable : true), \n        detail: detail\n      });\n      node.dispatchEvent(event);\n      return event;\n    },\n    /**\n      * Fire an event asynchronously.\n      * @method asyncFire\n      * @param {string} type An event name.\n      * @param detail\n      * @param {Node} toNode Target node.\n      */\n    asyncFire: function(/*inType, inDetail*/) {\n      this.async(\"fire\", arguments);\n    },\n    /**\n      * Remove class from old, add class to anew, if they exist\n      * @param classFollows\n      * @param anew A node.\n      * @param old A node\n      * @param className\n      */\n    classFollows: function(anew, old, className) {\n      if (old) {\n        old.classList.remove(className);\n      }\n      if (anew) {\n        anew.classList.add(className);\n      }\n    }\n  };\n\n  // no-operation function for handy stubs\n  var nop = function() {};\n\n  // null-object for handy stubs\n  var nob = {};\n\n  // deprecated\n\n  utils.asyncMethod = utils.async;\n\n  // exports\n\n  scope.api.instance.utils = utils;\n  scope.nop = nop;\n  scope.nob = nob;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n  var EVENT_PREFIX = 'on-';\n\n  // instance events api\n  var events = {\n    // read-only\n    EVENT_PREFIX: EVENT_PREFIX,\n    // event listeners on host\n    addHostListeners: function() {\n      var events = this.eventDelegates;\n      log.events && (Object.keys(events).length > 0) && console.log('[%s] addHostListeners:', this.localName, events);\n      // NOTE: host events look like bindings but really are not;\n      // (1) we don't want the attribute to be set and (2) we want to support\n      // multiple event listeners ('host' and 'instance') and Node.bind\n      // by default supports 1 thing being bound.\n      // We do, however, leverage the event hookup code in PolymerExpressions\n      // so that we have a common code path for handling declarative events.\n      var self = this, bindable, eventName;\n      for (var n in events) {\n        eventName = EVENT_PREFIX + n;\n        bindable = PolymerExpressions.prepareEventBinding(\n          Path.get(events[n]),\n          eventName, \n          {\n            resolveEventHandler: function(model, path, node) {\n              var fn = path.getValueFrom(self);\n              if (fn) {\n                return fn.bind(self);\n              }\n            }\n          }\n        );\n        bindable(this, this, false);\n      }\n    },\n    // call 'method' or function method on 'obj' with 'args', if the method exists\n    dispatchMethod: function(obj, method, args) {\n      if (obj) {\n        log.events && console.group('[%s] dispatch [%s]', obj.localName, method);\n        var fn = typeof method === 'function' ? method : obj[method];\n        if (fn) {\n          fn[args ? 'apply' : 'call'](obj, args);\n        }\n        log.events && console.groupEnd();\n        Platform.flush();\n      }\n    }\n  };\n\n  // exports\n\n  scope.api.instance.events = events;\n\n})(Polymer);\n","/*\r\n * Copyright 2013 The Polymer Authors. All rights reserved.\r\n * Use of this source code is governed by a BSD-style\r\n * license that can be found in the LICENSE file.\r\n */\r\n(function(scope) {\r\n\r\n  // instance api for attributes\r\n\r\n  var attributes = {\r\n    copyInstanceAttributes: function () {\r\n      var a$ = this._instanceAttributes;\r\n      for (var k in a$) {\r\n        if (!this.hasAttribute(k)) {\r\n          this.setAttribute(k, a$[k]);\r\n        }\r\n      }\r\n    },\r\n    // for each attribute on this, deserialize value to property as needed\r\n    takeAttributes: function() {\r\n      // if we have no publish lookup table, we have no attributes to take\r\n      // TODO(sjmiles): ad hoc\r\n      if (this._publishLC) {\r\n        for (var i=0, a$=this.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) {\r\n          this.attributeToProperty(a.name, a.value);\r\n        }\r\n      }\r\n    },\r\n    // if attribute 'name' is mapped to a property, deserialize\r\n    // 'value' into that property\r\n    attributeToProperty: function(name, value) {\r\n      // try to match this attribute to a property (attributes are\r\n      // all lower-case, so this is case-insensitive search)\r\n      var name = this.propertyForAttribute(name);\r\n      if (name) {\r\n        // filter out 'mustached' values, these are to be\r\n        // replaced with bound-data and are not yet values\r\n        // themselves\r\n        if (value && value.search(scope.bindPattern) >= 0) {\r\n          return;\r\n        }\r\n        // get original value\r\n        var currentValue = this[name];\r\n        // deserialize Boolean or Number values from attribute\r\n        var value = this.deserializeValue(value, currentValue);\r\n        // only act if the value has changed\r\n        if (value !== currentValue) {\r\n          // install new value (has side-effects)\r\n          this[name] = value;\r\n        }\r\n      }\r\n    },\r\n    // return the published property matching name, or undefined\r\n    propertyForAttribute: function(name) {\r\n      var match = this._publishLC && this._publishLC[name];\r\n      //console.log('propertyForAttribute:', name, 'matches', match);\r\n      return match;\r\n    },\r\n    // convert representation of 'stringValue' based on type of 'currentValue'\r\n    deserializeValue: function(stringValue, currentValue) {\r\n      return scope.deserializeValue(stringValue, currentValue);\r\n    },\r\n    serializeValue: function(value, inferredType) {\r\n      if (inferredType === 'boolean') {\r\n        return value ? '' : undefined;\r\n      } else if (inferredType !== 'object' && inferredType !== 'function'\r\n          && value !== undefined) {\r\n        return value;\r\n      }\r\n    },\r\n    reflectPropertyToAttribute: function(name) {\r\n      var inferredType = typeof this[name];\r\n      // try to intelligently serialize property value\r\n      var serializedValue = this.serializeValue(this[name], inferredType);\r\n      // boolean properties must reflect as boolean attributes\r\n      if (serializedValue !== undefined) {\r\n        this.setAttribute(name, serializedValue);\r\n        // TODO(sorvell): we should remove attr for all properties\r\n        // that have undefined serialization; however, we will need to\r\n        // refine the attr reflection system to achieve this; pica, for example,\r\n        // relies on having inferredType object properties not removed as\r\n        // attrs.\r\n      } else if (inferredType === 'boolean') {\r\n        this.removeAttribute(name);\r\n      }\r\n    }\r\n  };\r\n\r\n  // exports\r\n\r\n  scope.api.instance.attributes = attributes;\r\n\r\n})(Polymer);\r\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n\n  // magic words\n\n  var OBSERVE_SUFFIX = 'Changed';\n\n  // element api\n\n  var empty = [];\n\n  var properties = {\n    observeProperties: function() {\n      var n$ = this._observeNames, pn$ = this._publishNames;\n      if ((n$ && n$.length) || (pn$ && pn$.length)) {\n        var self = this;\n        var o = this._propertyObserver = new CompoundObserver();\n        for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {\n          o.addPath(this, n);\n          // observer array properties\n          var pd = Object.getOwnPropertyDescriptor(this.__proto__, n);\n          if (pd && pd.value) {\n            this.observeArrayValue(n, pd.value, null);\n          }\n        }\n        for (var i=0, l=pn$.length, n; (i<l) && (n=pn$[i]); i++) {\n          if (!this.observe || (this.observe[n] === undefined)) {\n            o.addPath(this, n);\n          }\n        }\n        o.open(this.notifyPropertyChanges, this);\n      }\n    },\n    notifyPropertyChanges: function(newValues, oldValues, paths) {\n      var name, method, called = {};\n      for (var i in oldValues) {\n        // note: paths is of form [object, path, object, path]\n        name = paths[2 * i + 1];\n        if (this.publish[name] !== undefined) {\n          this.reflectPropertyToAttribute(name);\n        }\n        method = this.observe[name];\n        if (method) {\n          this.observeArrayValue(name, newValues[i], oldValues[i]);\n          if (!called[method]) {\n            called[method] = true;\n            // observes the value if it is an array\n            this.invokeMethod(method, [oldValues[i], newValues[i], arguments]);\n          }\n        }\n      }\n    },\n    observeArrayValue: function(name, value, old) {\n      // we only care if there are registered side-effects\n      var callbackName = this.observe[name];\n      if (callbackName) {\n        // if we are observing the previous value, stop\n        if (Array.isArray(old)) {\n          log.observe && console.log('[%s] observeArrayValue: unregister observer [%s]', this.localName, name);\n          this.unregisterObserver(name + '__array');\n        }\n        // if the new value is an array, being observing it\n        if (Array.isArray(value)) {\n          log.observe && console.log('[%s] observeArrayValue: register observer [%s]', this.localName, name, value);\n          var observer = new ArrayObserver(value);\n          observer.open(function(value, old) {\n            this.invokeMethod(callbackName, [old]);\n          }, this);\n          this.registerObserver(name + '__array', observer);\n        }\n      }\n    },\n    bindProperty: function(property, observable) {\n      // apply Polymer two-way reference binding\n      return bindProperties(this, property, observable);\n    },\n    unbindAllProperties: function() {\n      if (this._propertyObserver) {\n        this._propertyObserver.close();\n      }\n      this.unregisterObservers();\n    },\n    unbindProperty: function(name) {\n      return this.unregisterObserver(name);\n    },\n    invokeMethod: function(method, args) {\n      var fn = this[method] || method;\n      if (typeof fn === 'function') {\n        fn.apply(this, args);\n      }\n    },\n    // bookkeeping observers for memory management\n    registerObserver: function(name, observer) {\n      var o$ = this._observers || (this._observers = {});\n      o$[name] = observer;\n    },\n    unregisterObserver: function(name) {\n      var o$ = this._observers;\n      if (o$ && o$[name]) {\n        o$[name].close();\n        o$[name] = null;\n        return true;\n      }\n    },\n    unregisterObservers: function() {\n      if (this._observers) {\n        var keys=Object.keys(this._observers);\n        for (var i=0, l=keys.length, k, o; (i < l) && (k=keys[i]); i++) {\n          o = this._observers[k];\n          o.close();\n        }\n        this._observers = {};\n      }\n    }\n  };\n\n  // property binding\n  // bind a property in A to a path in B by converting A[property] to a\n  // getter/setter pair that accesses B[...path...]\n  function bindProperties(inA, inProperty, observable) {\n    log.bind && console.log(LOG_BIND_PROPS, inB.localName || 'object', inPath, inA.localName, inProperty);\n    // capture A's value if B's value is null or undefined,\n    // otherwise use B's value\n    // TODO(sorvell): need to review, can do with ObserverTransform\n    var v = observable.discardChanges();\n    if (v === null || v === undefined) {\n      observable.setValue(inA[inProperty]);\n    }\n    return Observer.defineComputedProperty(inA, inProperty, observable);\n  }\n\n  // logging\n  var LOG_OBSERVE = '[%s] watching [%s]';\n  var LOG_OBSERVED = '[%s#%s] watch: [%s] now [%s] was [%s]';\n  var LOG_CHANGED = '[%s#%s] propertyChanged: [%s] now [%s] was [%s]';\n  var LOG_BIND_PROPS = \"[%s]: bindProperties: [%s] to [%s].[%s]\";\n\n  // exports\n\n  scope.api.instance.properties = properties;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || 0;\n  var events = scope.api.instance.events;\n\n  var syntax = new PolymerExpressions();\n  syntax.resolveEventHandler = function(model, path, node) {\n    var ctlr = findEventController(node);\n    if (ctlr) {\n      var fn = path.getValueFrom(ctlr);\n      if (fn) {\n        return fn.bind(ctlr);\n      }\n    }\n  }\n\n  // An event controller is the host element for the shadowRoot in which \n  // the node exists, or the first ancestor with a 'lightDomController'\n  // property.\n  function findEventController(node) {\n    while (node.parentNode) {\n      if (node.lightDomController) {\n        return node;\n      }\n      node = node.parentNode;\n    }\n    return node.host;\n  };\n\n  // element api supporting mdv\n\n  var mdv = {\n    syntax: syntax,\n    instanceTemplate: function(template) {\n      return template.createInstance(this, this.syntax);\n    },\n    bind: function(name, observable, oneTime) {\n      // note: binding is a prepare signal. This allows us to be sure that any\n      // property changes that occur as a result of binding will be observed.\n      if (!this._elementPrepared) {\n        this.prepareElement();\n      }\n      var property = this.propertyForAttribute(name);\n      if (!property) {\n        // TODO(sjmiles): this mixin method must use the special form\n        // of `super` installed by `mixinMethod` in declaration/prototype.js\n        return this.mixinSuper(arguments);\n      } else {\n        // clean out the closets\n        this.unbind(name);\n        // use n-way Polymer binding\n        var observer = this.bindProperty(property, observable);\n        // stick path on observer so it's available via this.bindings\n        observer.path = observable.path_;\n        // reflect bound property to attribute when binding\n        // to ensure binding is not left on attribute if property\n        // does not update due to not changing.\n        this.reflectPropertyToAttribute(property);\n        return this.bindings[name] = observer;\n      }\n    },\n    asyncUnbindAll: function() {\n      if (!this._unbound) {\n        log.unbind && console.log('[%s] asyncUnbindAll', this.localName);\n        this._unbindAllJob = this.job(this._unbindAllJob, this.unbindAll, 0);\n      }\n    },\n    unbindAll: function() {\n      if (!this._unbound) {\n        this.unbindAllProperties();\n        this.super();\n        // unbind shadowRoot\n        var root = this.shadowRoot;\n        while (root) {\n          unbindNodeTree(root);\n          root = root.olderShadowRoot;\n        }\n        this._unbound = true;\n      }\n    },\n    cancelUnbindAll: function(preventCascade) {\n      if (this._unbound) {\n        log.unbind && console.warn('[%s] already unbound, cannot cancel unbindAll', this.localName);\n        return;\n      }\n      log.unbind && console.log('[%s] cancelUnbindAll', this.localName);\n      if (this._unbindAllJob) {\n        this._unbindAllJob = this._unbindAllJob.stop();\n      }\n      // cancel unbinding our shadow tree iff we're not in the process of\n      // cascading our tree (as we do, for example, when the element is inserted).\n      if (!preventCascade) {\n        forNodeTree(this.shadowRoot, function(n) {\n          if (n.cancelUnbindAll) {\n            n.cancelUnbindAll();\n          }\n        });\n      }\n    }\n  };\n\n  function unbindNodeTree(node) {\n    forNodeTree(node, _nodeUnbindAll);\n  }\n\n  function _nodeUnbindAll(node) {\n    node.unbindAll();\n  }\n\n  function forNodeTree(node, callback) {\n    if (node) {\n      callback(node);\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        forNodeTree(child, callback);\n      }\n    }\n  }\n\n  var mustachePattern = /\\{\\{([^{}]*)}}/;\n\n  // exports\n\n  scope.bindPattern = mustachePattern;\n  scope.api.instance.mdv = mdv;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n  var preparingElements = 0;\n\n  var base = {\n    PolymerBase: true,\n    job: Polymer.job,\n    super: Polymer.super,\n    // user entry point for element has had its createdCallback called\n    created: function() {\n    },\n    // user entry point for element has shadowRoot and is ready for\n    // api interaction\n    ready: function() {\n    },\n    createdCallback: function() {\n      this.created();\n      if (this.ownerDocument.defaultView || this.alwaysPrepare ||\n          preparingElements > 0) {\n        this.prepareElement();\n      }\n    },\n    // system entry point, do not override\n    prepareElement: function() {\n      this._elementPrepared = true;\n      // install shadowRoots storage\n      this.shadowRoots = {};\n      // install property observers\n      this.observeProperties();\n      // install boilerplate attributes\n      this.copyInstanceAttributes();\n      // process input attributes\n      this.takeAttributes();\n      // add event listeners\n      this.addHostListeners();\n      // guarantees that while preparing, any\n      // sub-elements are also prepared\n      preparingElements++;\n      // process declarative resources\n      this.parseDeclarations(this.__proto__);\n      // decrement semaphore\n      preparingElements--;\n      // TODO(sorvell): CE polyfill uses unresolved attribute to simulate\n      // :unresolved; remove this attribute to be compatible with native\n      // CE.\n      this.removeAttribute('unresolved');\n      // user entry point\n      this.ready();\n    },\n    attachedCallback: function() {\n      if (!this._elementPrepared) {\n        this.prepareElement();\n      }\n      this.cancelUnbindAll(true);\n      // invoke user action\n      if (this.attached) {\n        this.attached();\n      }\n      // TODO(sorvell): bc\n      if (this.enteredView) {\n        this.enteredView();\n      }\n      // NOTE: domReady can be used to access elements in dom (descendants, \n      // ancestors, siblings) such that the developer is enured to upgrade\n      // ordering. If the element definitions have loaded, domReady\n      // can be used to access upgraded elements.\n      if (!this.hasBeenAttached) {\n        this.hasBeenAttached = true;\n        if (this.domReady) {\n          this.async('domReady');\n        }\n      }\n    },\n    detachedCallback: function() {\n      if (!this.preventDispose) {\n        this.asyncUnbindAll();\n      }\n      // invoke user action\n      if (this.detached) {\n        this.detached();\n      }\n      // TODO(sorvell): bc\n      if (this.leftView) {\n        this.leftView();\n      }\n    },\n    // TODO(sorvell): bc\n    enteredViewCallback: function() {\n      this.attachedCallback();\n    },\n    // TODO(sorvell): bc\n    leftViewCallback: function() {\n      this.detachedCallback();\n    },\n    // TODO(sorvell): bc\n    enteredDocumentCallback: function() {\n      this.attachedCallback();\n    },\n    // TODO(sorvell): bc\n    leftDocumentCallback: function() {\n      this.detachedCallback();\n    },\n    // recursive ancestral <element> initialization, oldest first\n    parseDeclarations: function(p) {\n      if (p && p.element) {\n        this.parseDeclarations(p.__proto__);\n        p.parseDeclaration.call(this, p.element);\n      }\n    },\n    // parse input <element> as needed, override for custom behavior\n    parseDeclaration: function(elementElement) {\n      var template = this.fetchTemplate(elementElement);\n      if (template) {\n        var root = this.shadowFromTemplate(template);\n        this.shadowRoots[elementElement.name] = root;        \n      }\n    },\n    // return a shadow-root template (if desired), override for custom behavior\n    fetchTemplate: function(elementElement) {\n      return elementElement.querySelector('template');\n    },\n    // utility function that creates a shadow root from a <template>\n    shadowFromTemplate: function(template) {\n      if (template) {\n        // make a shadow root\n        var root = this.createShadowRoot();\n        // migrate flag(s)\n        root.resetStyleInheritance = this.resetStyleInheritance;\n        // stamp template\n        // which includes parsing and applying MDV bindings before being \n        // inserted (to avoid {{}} in attribute values)\n        // e.g. to prevent <img src=\"images/{{icon}}\"> from generating a 404.\n        var dom = this.instanceTemplate(template);\n        // append to shadow dom\n        root.appendChild(dom);\n        // perform post-construction initialization tasks on shadow root\n        this.shadowRootReady(root, template);\n        // return the created shadow root\n        return root;\n      }\n    },\n    // utility function that stamps a <template> into light-dom\n    lightFromTemplate: function(template) {\n      if (template) {\n        // TODO(sorvell): mark this element as a lightDOMController so that\n        // event listeners on bound nodes inside it will be called on it.\n        // Note, the expectation here is that events on all descendants \n        // should be handled by this element.\n        this.lightDomController = true;\n        // stamp template\n        // which includes parsing and applying MDV bindings before being \n        // inserted (to avoid {{}} in attribute values)\n        // e.g. to prevent <img src=\"images/{{icon}}\"> from generating a 404.\n        var dom = this.instanceTemplate(template);\n        // append to shadow dom\n        this.appendChild(dom);\n        // perform post-construction initialization tasks on ahem, light root\n        this.shadowRootReady(this, template);\n        // return the created shadow root\n        return dom;\n      }\n    },\n    shadowRootReady: function(root, template) {\n      // locate nodes with id and store references to them in this.$ hash\n      this.marshalNodeReferences(root);\n      // set up pointer gestures\n      PointerGestures.register(root);\n    },\n    // locate nodes with id and store references to them in this.$ hash\n    marshalNodeReferences: function(root) {\n      // establish $ instance variable\n      var $ = this.$ = this.$ || {};\n      // populate $ from nodes with ID from the LOCAL tree\n      if (root) {\n        var n$ = root.querySelectorAll(\"[id]\");\n        for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {\n          $[n.id] = n;\n        };\n      }\n    },\n    attributeChangedCallback: function(name, oldValue) {\n      // TODO(sjmiles): adhoc filter\n      if (name !== 'class' && name !== 'style') {\n        this.attributeToProperty(name, this.getAttribute(name));\n      }\n      if (this.attributeChanged) {\n        this.attributeChanged.apply(this, arguments);\n      }\n    },\n    onMutation: function(node, listener) {\n      var observer = new MutationObserver(function(mutations) {\n        listener.call(this, observer, mutations);\n        observer.disconnect();\n      }.bind(this));\n      observer.observe(node, {childList: true, subtree: true});\n    }\n  };\n\n  // true if object has own PolymerBase api\n  function isBase(object) {\n    return object.hasOwnProperty('PolymerBase') \n  }\n\n  // name a base constructor for dev tools\n\n  function PolymerBase() {};\n  PolymerBase.prototype = base;\n  base.constructor = PolymerBase;\n  \n  // exports\n\n  scope.Base = PolymerBase;\n  scope.isBase = isBase;\n  scope.api.instance.base = base;\n  \n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n  \n  // magic words\n  \n  var STYLE_SCOPE_ATTRIBUTE = 'element';\n  var STYLE_CONTROLLER_SCOPE = 'controller';\n  \n  var styles = {\n    STYLE_SCOPE_ATTRIBUTE: STYLE_SCOPE_ATTRIBUTE,\n    /**\n     * Installs external stylesheets and <style> elements with the attribute \n     * polymer-scope='controller' into the scope of element. This is intended\n     * to be a called during custom element construction.\n    */\n    installControllerStyles: function() {\n      // apply controller styles, but only if they are not yet applied\n      var scope = this.findStyleScope();\n      if (scope && !this.scopeHasNamedStyle(scope, this.localName)) {\n        // allow inherited controller styles\n        var proto = getPrototypeOf(this), cssText = '';\n        while (proto && proto.element) {\n          cssText += proto.element.cssTextForScope(STYLE_CONTROLLER_SCOPE);\n          proto = getPrototypeOf(proto);\n        }\n        if (cssText) {\n          this.installScopeCssText(cssText, scope);\n        }\n      }\n    },\n    installScopeStyle: function(style, name) {\n      var scope = this.findStyleScope(), name = name || '';\n      if (scope && !this.scopeHasNamedStyle(scope, this.localName + name)) {\n        var cssText = '';\n        if (style instanceof Array) {\n          for (var i=0, l=style.length, s; (i<l) && (s=style[i]); i++) {\n            cssText += s.textContent + '\\n\\n';\n          }\n        } else {\n          cssText = style.textContent;\n        }\n        this.installScopeCssText(cssText, scope, name);\n      }\n    },\n    installScopeCssText: function(cssText, scope, name) {\n      scope = scope || this.findStyleScope();\n      name = name || '';\n      if (!scope) {\n        return;\n      }\n      if (window.ShadowDOMPolyfill) {\n        cssText = shimCssText(cssText, scope.host);\n      }\n      var style = this.element.cssTextToScopeStyle(cssText,\n          STYLE_CONTROLLER_SCOPE);\n      Polymer.applyStyleToScope(style, scope);\n      // cache that this style has been applied\n      scope._scopeStyles[this.localName + name] = true;\n    },\n    findStyleScope: function() {\n      // find the shadow root that contains this element\n      var n = this;\n      while (n.parentNode) {\n        n = n.parentNode;\n      }\n      return n;\n    },\n    scopeHasNamedStyle: function(scope, name) {\n      scope._scopeStyles = scope._scopeStyles || {};\n      return scope._scopeStyles[name];\n    }\n  };\n  \n  // NOTE: use raw prototype traversal so that we ensure correct traversal\n  // on platforms where the protoype chain is simulated via __proto__ (IE10)\n  function getPrototypeOf(prototype) {\n    return prototype.__proto__;\n  }\n\n  function shimCssText(cssText, host) {\n    var name = '', is = false;\n    if (host) {\n      name = host.localName;\n      is = host.hasAttribute('is');\n    }\n    var selector = Platform.ShadowCSS.makeScopeSelector(name, is);\n    return Platform.ShadowCSS.shimCssText(cssText, selector);\n  }\n\n  // exports\n\n  scope.api.instance.styles = styles;\n  \n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var extend = scope.extend;\n  var api = scope.api;\n\n  // imperative implementation: Polymer()\n\n  // specify an 'own' prototype for tag `name`\n  function element(name, prototype) {\n    if (getRegisteredPrototype[name]) {\n      throw 'Already registered (Polymer) prototype for element ' + name;\n    }\n    // cache the prototype\n    registerPrototype(name, prototype);\n    // notify the registrar waiting for 'name', if any\n    notifyPrototype(name);\n  }\n\n  // async prototype source\n\n  function waitingForPrototype(name, client) {\n    waitPrototype[name] = client;\n  }\n\n  var waitPrototype = {};\n\n  function notifyPrototype(name) {\n    if (waitPrototype[name]) {\n      waitPrototype[name].registerWhenReady();\n      delete waitPrototype[name];\n    }\n  }\n\n  // utility and bookkeeping\n\n  // maps tag names to prototypes, as registered with\n  // Polymer. Prototypes associated with a tag name\n  // using document.registerElement are available from\n  // HTMLElement.getPrototypeForTag().\n  // If an element was fully registered by Polymer, then\n  // Polymer.getRegisteredPrototype(name) === \n  //   HTMLElement.getPrototypeForTag(name)\n\n  var prototypesByName = {};\n\n  function registerPrototype(name, prototype) {\n    return prototypesByName[name] = prototype || {};\n  }\n\n  function getRegisteredPrototype(name) {\n    return prototypesByName[name];\n  }\n\n  // exports\n\n  scope.getRegisteredPrototype = getRegisteredPrototype;\n  scope.waitingForPrototype = waitingForPrototype;\n\n  // namespace shenanigans so we can expose our scope on the registration \n  // function\n\n  // make window.Polymer reference `element()`\n\n  window.Polymer = element;\n\n  // TODO(sjmiles): find a way to do this that is less terrible\n  // copy window.Polymer properties onto `element()`\n\n  extend(Polymer, scope);\n\n  // Under the HTMLImports polyfill, scripts in the main document\n  // do not block on imports; we want to allow calls to Polymer in the main\n  // document. Platform collects those calls until we can process them, which\n  // we do here.\n\n  var declarations = Platform.deliverDeclarations();\n  if (declarations) {\n    for (var i=0, l=declarations.length, d; (i<l) && (d=declarations[i]); i++) {\n      element.apply(null, d);\n    }\n  }\n\n})(Polymer);\n","/* \n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\nvar path = {\n  resolveElementPaths: function(node) {\n    Platform.urlResolver.resolveDom(node);\n  },\n  addResolvePathApi: function() {\n    // let assetpath attribute modify the resolve path\n    var assetPath = this.getAttribute('assetpath') || '';\n    var root = new URL(assetPath, this.ownerDocument.baseURI);\n    this.prototype.resolvePath = function(urlPath, base) {\n      var u = new URL(urlPath, base || root);\n      return u.href;\n    };\n  }\n};\n\n// exports\nscope.api.declaration.path = path;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n  var api = scope.api.instance.styles;\n  var STYLE_SCOPE_ATTRIBUTE = api.STYLE_SCOPE_ATTRIBUTE;\n\n  // magic words\n\n  var STYLE_SELECTOR = 'style';\n  var STYLE_LOADABLE_MATCH = '@import';\n  var SHEET_SELECTOR = 'link[rel=stylesheet]';\n  var STYLE_GLOBAL_SCOPE = 'global';\n  var SCOPE_ATTR = 'polymer-scope';\n\n  var styles = {\n    // returns true if resources are loading\n    loadStyles: function(callback) {\n      var content = this.templateContent();\n      if (content) {\n        this.convertSheetsToStyles(content);\n      }\n      var styles = this.findLoadableStyles(content);\n      if (styles.length) {\n        Platform.styleResolver.loadStyles(styles, callback);\n      } else if (callback) {\n        callback();\n      }\n    },\n    convertSheetsToStyles: function(root) {\n      var s$ = root.querySelectorAll(SHEET_SELECTOR);\n      for (var i=0, l=s$.length, s, c; (i<l) && (s=s$[i]); i++) {\n        c = createStyleElement(importRuleForSheet(s, this.ownerDocument.baseURI),\n            this.ownerDocument);\n        this.copySheetAttributes(c, s);\n        s.parentNode.replaceChild(c, s);\n      }\n    },\n    copySheetAttributes: function(style, link) {\n      for (var i=0, a$=link.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) {\n        if (a.name !== 'rel' && a.name !== 'href') {\n          style.setAttribute(a.name, a.value);\n        }\n      }\n    },\n    findLoadableStyles: function(root) {\n      var loadables = [];\n      if (root) {\n        var s$ = root.querySelectorAll(STYLE_SELECTOR);\n        for (var i=0, l=s$.length, s; (i<l) && (s=s$[i]); i++) {\n          if (s.textContent.match(STYLE_LOADABLE_MATCH)) {\n            loadables.push(s);\n          }\n        }\n      }\n      return loadables;\n    },\n    /**\n     * Install external stylesheets loaded in <polymer-element> elements into the \n     * element's template.\n     * @param elementElement The <element> element to style.\n     */\n    installSheets: function() {\n      this.cacheSheets();\n      this.cacheStyles();\n      this.installLocalSheets();\n      this.installGlobalStyles();\n    },\n    /**\n     * Remove all sheets from element and store for later use.\n     */\n    cacheSheets: function() {\n      this.sheets = this.findNodes(SHEET_SELECTOR);\n      this.sheets.forEach(function(s) {\n        if (s.parentNode) {\n          s.parentNode.removeChild(s);\n        }\n      });\n    },\n    cacheStyles: function() {\n      this.styles = this.findNodes(STYLE_SELECTOR + '[' + SCOPE_ATTR + ']');\n      this.styles.forEach(function(s) {\n        if (s.parentNode) {\n          s.parentNode.removeChild(s);\n        }\n      });\n    },\n    /**\n     * Takes external stylesheets loaded in an <element> element and moves\n     * their content into a <style> element inside the <element>'s template.\n     * The sheet is then removed from the <element>. This is done only so \n     * that if the element is loaded in the main document, the sheet does\n     * not become active.\n     * Note, ignores sheets with the attribute 'polymer-scope'.\n     * @param elementElement The <element> element to style.\n     */\n    installLocalSheets: function () {\n      var sheets = this.sheets.filter(function(s) {\n        return !s.hasAttribute(SCOPE_ATTR);\n      });\n      var content = this.templateContent();\n      if (content) {\n        var cssText = '';\n        sheets.forEach(function(sheet) {\n          cssText += cssTextFromSheet(sheet) + '\\n';\n        });\n        if (cssText) {\n          var style = createStyleElement(cssText, this.ownerDocument);\n          content.insertBefore(style, content.firstChild);\n        }\n      }\n    },\n    findNodes: function(selector, matcher) {\n      var nodes = this.querySelectorAll(selector).array();\n      var content = this.templateContent();\n      if (content) {\n        var templateNodes = content.querySelectorAll(selector).array();\n        nodes = nodes.concat(templateNodes);\n      }\n      return matcher ? nodes.filter(matcher) : nodes;\n    },\n    templateContent: function() {\n      var template = this.querySelector('template');\n      return template && templateContent(template);\n    },\n    /**\n     * Promotes external stylesheets and <style> elements with the attribute \n     * polymer-scope='global' into global scope.\n     * This is particularly useful for defining @keyframe rules which \n     * currently do not function in scoped or shadow style elements.\n     * (See wkb.ug/72462)\n     * @param elementElement The <element> element to style.\n    */\n    // TODO(sorvell): remove when wkb.ug/72462 is addressed.\n    installGlobalStyles: function() {\n      var style = this.styleForScope(STYLE_GLOBAL_SCOPE);\n      applyStyleToScope(style, document.head);\n    },\n    cssTextForScope: function(scopeDescriptor) {\n      var cssText = '';\n      // handle stylesheets\n      var selector = '[' + SCOPE_ATTR + '=' + scopeDescriptor + ']';\n      var matcher = function(s) {\n        return matchesSelector(s, selector);\n      };\n      var sheets = this.sheets.filter(matcher);\n      sheets.forEach(function(sheet) {\n        cssText += cssTextFromSheet(sheet) + '\\n\\n';\n      });\n      // handle cached style elements\n      var styles = this.styles.filter(matcher);\n      styles.forEach(function(style) {\n        cssText += style.textContent + '\\n\\n';\n      });\n      return cssText;\n    },\n    styleForScope: function(scopeDescriptor) {\n      var cssText = this.cssTextForScope(scopeDescriptor);\n      return this.cssTextToScopeStyle(cssText, scopeDescriptor);\n    },\n    cssTextToScopeStyle: function(cssText, scopeDescriptor) {\n      if (cssText) {\n        var style = createStyleElement(cssText);\n        style.setAttribute(STYLE_SCOPE_ATTRIBUTE, this.getAttribute('name') +\n            '-' + scopeDescriptor);\n        return style;\n      }\n    }\n  };\n\n  function importRuleForSheet(sheet, baseUrl) {\n    var href = new URL(sheet.getAttribute('href'), baseUrl).href;\n    return '@import \\'' + href + '\\';';\n  }\n\n  function applyStyleToScope(style, scope) {\n    if (style) {\n      if (scope === document) {\n        scope = document.head;\n      }\n      if (window.ShadowDOMPolyfill) {\n        scope = document.head;\n      }\n      // TODO(sorvell): necessary for IE\n      // see https://connect.microsoft.com/IE/feedback/details/790212/\n      // cloning-a-style-element-and-adding-to-document-produces\n      // -unexpected-result#details\n      // var clone = style.cloneNode(true);\n      var clone = createStyleElement(style.textContent);\n      var attr = style.getAttribute(STYLE_SCOPE_ATTRIBUTE);\n      if (attr) {\n        clone.setAttribute(STYLE_SCOPE_ATTRIBUTE, attr);\n      }\n      scope.appendChild(clone);\n    }\n  }\n\n  function createStyleElement(cssText, scope) {\n    scope = scope || document;\n    scope = scope.createElement ? scope : scope.ownerDocument;\n    var style = scope.createElement('style');\n    style.textContent = cssText;\n    return style;\n  }\n\n  function cssTextFromSheet(sheet) {\n    return (sheet && sheet.__resource) || '';\n  }\n\n  function matchesSelector(node, inSelector) {\n    if (matches) {\n      return matches.call(node, inSelector);\n    }\n  }\n  var p = HTMLElement.prototype;\n  var matches = p.matches || p.matchesSelector || p.webkitMatchesSelector \n      || p.mozMatchesSelector;\n  \n  // exports\n\n  scope.api.declaration.styles = styles;\n  scope.applyStyleToScope = applyStyleToScope;\n  \n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\n  // imports\n\n  var log = window.logFlags || {};\n  var api = scope.api.instance.events;\n  var EVENT_PREFIX = api.EVENT_PREFIX;\n  // polymer-element declarative api: events feature\n\n  var events = { \n    parseHostEvents: function() {\n      // our delegates map\n      var delegates = this.prototype.eventDelegates;\n      // extract data from attributes into delegates\n      this.addAttributeDelegates(delegates);\n    },\n    addAttributeDelegates: function(delegates) {\n      // for each attribute\n      for (var i=0, a; a=this.attributes[i]; i++) {\n        // does it have magic marker identifying it as an event delegate?\n        if (this.hasEventPrefix(a.name)) {\n          // if so, add the info to delegates\n          delegates[this.removeEventPrefix(a.name)] = a.value.replace('{{', '')\n              .replace('}}', '').trim();\n        }\n      }\n    },\n    // starts with 'on-'\n    hasEventPrefix: function (n) {\n      return n && (n[0] === 'o') && (n[1] === 'n') && (n[2] === '-');\n    },\n    removeEventPrefix: function(n) {\n      return n.slice(prefixLength);\n    }\n  };\n\n  var prefixLength = EVENT_PREFIX.length;\n\n  // exports\n  scope.api.declaration.events = events;\n\n})(Polymer);","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // element api\n\n  var properties = {\n    inferObservers: function(prototype) {\n      // called before prototype.observe is chained to inherited object\n      var observe = prototype.observe, property;\n      for (var n in prototype) {\n        if (n.slice(-7) === 'Changed') {\n          if (!observe) {\n            observe  = (prototype.observe = {});\n          }\n          property = n.slice(0, -7)\n          observe[property] = observe[property] || n;\n        }\n      }\n    },\n    explodeObservers: function(prototype) {\n      // called before prototype.observe is chained to inherited object\n      var o = prototype.observe;\n      if (o) {\n        var exploded = {};\n        for (var n in o) {\n          var names = n.split(' ');\n          for (var i=0, ni; ni=names[i]; i++) {\n            exploded[ni] = o[n];\n          }\n        }\n        prototype.observe = exploded;\n      }\n    },\n    optimizePropertyMaps: function(prototype) {\n      if (prototype.observe) {\n        // construct name list\n        var a = prototype._observeNames = [];\n        for (var n in prototype.observe) {\n          var names = n.split(' ');\n          for (var i=0, ni; ni=names[i]; i++) {\n            a.push(ni);\n          }\n          //a.push(n);\n        }\n      }\n      if (prototype.publish) {\n        // construct name list\n        var a = prototype._publishNames = [];\n        for (var n in prototype.publish) {\n          a.push(n);\n        }\n      }\n    },\n    publishProperties: function(prototype, base) {\n      // if we have any properties to publish\n      var publish = prototype.publish;\n      if (publish) {\n        // transcribe `publish` entries onto own prototype\n        this.requireProperties(publish, prototype, base);\n        // construct map of lower-cased property names\n        prototype._publishLC = this.lowerCaseMap(publish);\n      }\n    },\n    requireProperties: function(properties, prototype, base) {\n      // ensure a prototype value for each property\n      for (var n in properties) {\n        if (prototype[n] === undefined && base[n] === undefined) {\n          prototype[n] = properties[n];\n        }\n      }\n    },\n    lowerCaseMap: function(properties) {\n      var map = {};\n      for (var n in properties) {\n        map[n.toLowerCase()] = n;\n      }\n      return map;\n    }\n  };\n\n  // exports\n\n  scope.api.declaration.properties = properties;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // magic words\n\n  var ATTRIBUTES_ATTRIBUTE = 'attributes';\n  var ATTRIBUTES_REGEX = /\\s|,/;\n\n  // attributes api\n\n  var attributes = {\n    inheritAttributesObjects: function(prototype) {\n      // chain our lower-cased publish map to the inherited version\n      this.inheritObject(prototype, 'publishLC');\n      // chain our instance attributes map to the inherited version\n      this.inheritObject(prototype, '_instanceAttributes');\n    },\n    publishAttributes: function(prototype, base) {\n      // merge names from 'attributes' attribute\n      var attributes = this.getAttribute(ATTRIBUTES_ATTRIBUTE);\n      if (attributes) {\n        // get properties to publish\n        var publish = prototype.publish || (prototype.publish = {});\n        // names='a b c' or names='a,b,c'\n        var names = attributes.split(ATTRIBUTES_REGEX);\n        // record each name for publishing\n        for (var i=0, l=names.length, n; i<l; i++) {\n          // remove excess ws\n          n = names[i].trim();\n          // do not override explicit entries\n          if (n && publish[n] === undefined && base[n] === undefined) {\n            publish[n] = null;\n          }\n        }\n      }\n    },\n    // record clonable attributes from <element>\n    accumulateInstanceAttributes: function() {\n      // inherit instance attributes\n      var clonable = this.prototype._instanceAttributes;\n      // merge attributes from element\n      var a$ = this.attributes;\n      for (var i=0, l=a$.length, a; (i<l) && (a=a$[i]); i++) {  \n        if (this.isInstanceAttribute(a.name)) {\n          clonable[a.name] = a.value;\n        }\n      }\n    },\n    isInstanceAttribute: function(name) {\n      return !this.blackList[name] && name.slice(0,3) !== 'on-';\n    },\n    // do not clone these attributes onto instances\n    blackList: {\n      name: 1,\n      'extends': 1,\n      constructor: 1,\n      noscript: 1,\n      assetpath: 1,\n      'cache-csstext': 1\n    }\n  };\n\n  // add ATTRIBUTES_ATTRIBUTE to the blacklist\n  attributes.blackList[ATTRIBUTES_ATTRIBUTE] = 1;\n\n  // exports\n\n  scope.api.declaration.attributes = attributes;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n  \n  var api = scope.api;\n  var isBase = scope.isBase;\n  var extend = scope.extend;\n\n  // prototype api\n\n  var prototype = {\n\n    register: function(name, extendeeName) {\n      // build prototype combining extendee, Polymer base, and named api\n      this.buildPrototype(name, extendeeName);\n      // register our custom element with the platform\n      this.registerPrototype(name, extendeeName);\n      // reference constructor in a global named by 'constructor' attribute\n      this.publishConstructor();\n    },\n\n    buildPrototype: function(name, extendeeName) {\n      // get our custom prototype (before chaining)\n      var extension = scope.getRegisteredPrototype(name);\n      // get basal prototype\n      var base = this.generateBasePrototype(extendeeName);\n      // implement declarative features\n      this.desugarBeforeChaining(extension, base);\n      // join prototypes\n      this.prototype = this.chainPrototypes(extension, base);\n      // more declarative features\n      this.desugarAfterChaining(name, extendeeName);\n    },\n\n    desugarBeforeChaining: function(prototype, base) {\n      // back reference declaration element\n      // TODO(sjmiles): replace `element` with `elementElement` or `declaration`\n      prototype.element = this;\n      // transcribe `attributes` declarations onto own prototype's `publish`\n      this.publishAttributes(prototype, base);\n      // `publish` properties to the prototype and to attribute watch\n      this.publishProperties(prototype, base);\n      // infer observers for `observe` list based on method names\n      this.inferObservers(prototype);\n      // desugar compound observer syntax, e.g. 'a b c' \n      this.explodeObservers(prototype);\n    },\n\n    chainPrototypes: function(prototype, base) {\n      // chain various meta-data objects to inherited versions\n      this.inheritMetaData(prototype, base);\n      // chain custom api to inherited\n      var chained = this.chainObject(prototype, base);\n      // x-platform fixup\n      ensurePrototypeTraversal(chained);\n      return chained;\n    },\n\n    inheritMetaData: function(prototype, base) {\n      // chain observe object to inherited\n      this.inheritObject('observe', prototype, base);\n      // chain publish object to inherited\n      this.inheritObject('publish', prototype, base);\n      // chain our lower-cased publish map to the inherited version\n      this.inheritObject('_publishLC', prototype, base);\n      // chain our instance attributes map to the inherited version\n      this.inheritObject('_instanceAttributes', prototype, base);\n      // chain our event delegates map to the inherited version\n      this.inheritObject('eventDelegates', prototype, base);\n    },\n\n    // implement various declarative features\n    desugarAfterChaining: function(name, extendee) {\n      // build side-chained lists to optimize iterations\n      this.optimizePropertyMaps(this.prototype);\n      // install external stylesheets as if they are inline\n      this.installSheets();\n      // adjust any paths in dom from imports\n      this.resolveElementPaths(this);\n      // compile list of attributes to copy to instances\n      this.accumulateInstanceAttributes();\n      // parse on-* delegates declared on `this` element\n      this.parseHostEvents();\n      //\n      // install a helper method this.resolvePath to aid in \n      // setting resource urls. e.g.\n      // this.$.image.src = this.resolvePath('images/foo.png')\n      this.addResolvePathApi();\n      // under ShadowDOMPolyfill, transforms to approximate missing CSS features\n      if (window.ShadowDOMPolyfill) {\n        Platform.ShadowCSS.shimStyling(this.templateContent(), name, extendee);\n      }\n      // allow custom element access to the declarative context\n      if (this.prototype.registerCallback) {\n        this.prototype.registerCallback(this);\n      }\n    },\n\n    // if a named constructor is requested in element, map a reference\n    // to the constructor to the given symbol\n    publishConstructor: function() {\n      var symbol = this.getAttribute('constructor');\n      if (symbol) {\n        window[symbol] = this.ctor;\n      }\n    },\n\n    // build prototype combining extendee, Polymer base, and named api\n    generateBasePrototype: function(extnds) {\n      var prototype = this.findBasePrototype(extnds);\n      if (!prototype) {\n        // create a prototype based on tag-name extension\n        var prototype = HTMLElement.getPrototypeForTag(extnds);\n        // insert base api in inheritance chain (if needed)\n        prototype = this.ensureBaseApi(prototype);\n        // memoize this base\n        memoizedBases[extnds] = prototype;\n      }\n      return prototype;\n    },\n\n    findBasePrototype: function(name) {\n      return memoizedBases[name];\n    },\n\n    // install Polymer instance api into prototype chain, as needed \n    ensureBaseApi: function(prototype) {\n      if (prototype.PolymerBase) {\n        return prototype;\n      }\n      var extended = Object.create(prototype);\n      // we need a unique copy of base api for each base prototype\n      // therefore we 'extend' here instead of simply chaining\n      api.publish(api.instance, extended);\n      // TODO(sjmiles): sharing methods across prototype chains is\n      // not supported by 'super' implementation which optimizes\n      // by memoizing prototype relationships.\n      // Probably we should have a version of 'extend' that is \n      // share-aware: it could study the text of each function,\n      // look for usage of 'super', and wrap those functions in\n      // closures.\n      // As of now, there is only one problematic method, so \n      // we just patch it manually.\n      // To avoid re-entrancy problems, the special super method\n      // installed is called `mixinSuper` and the mixin method\n      // must use this method instead of the default `super`.\n      this.mixinMethod(extended, prototype, api.instance.mdv, 'bind');\n      // return buffed-up prototype\n      return extended;\n    },\n\n    mixinMethod: function(extended, prototype, api, name) {\n      var $super = function(args) {\n        return prototype[name].apply(this, args);\n      };\n      extended[name] = function() {\n        this.mixinSuper = $super;\n        return api[name].apply(this, arguments);\n      }\n    },\n\n    // ensure prototype[name] inherits from a prototype.prototype[name]\n    inheritObject: function(name, prototype, base) {\n      // require an object\n      var source = prototype[name] || {};\n      // chain inherited properties onto a new object\n      prototype[name] = this.chainObject(source, base[name]);\n    },\n\n    // register 'prototype' to custom element 'name', store constructor \n    registerPrototype: function(name, extendee) { \n      var info = {\n        prototype: this.prototype\n      }\n      // native element must be specified in extends\n      var typeExtension = this.findTypeExtension(extendee);\n      if (typeExtension) {\n        info.extends = typeExtension;\n      }\n      // register the prototype with HTMLElement for name lookup\n      HTMLElement.register(name, this.prototype);\n      // register the custom type\n      this.ctor = document.registerElement(name, info);\n    },\n\n    findTypeExtension: function(name) {\n      if (name && name.indexOf('-') < 0) {\n        return name;\n      } else {\n        var p = this.findBasePrototype(name);\n        if (p.element) {\n          return this.findTypeExtension(p.element.extends);\n        }\n      }\n    }\n\n  };\n\n  // memoize base prototypes\n  var memoizedBases = {};\n\n  // implementation of 'chainObject' depends on support for __proto__\n  if (Object.__proto__) {\n    prototype.chainObject = function(object, inherited) {\n      if (object && inherited && object !== inherited) {\n        object.__proto__ = inherited;\n      }\n      return object;\n    }\n  } else {\n    prototype.chainObject = function(object, inherited) {\n      if (object && inherited && object !== inherited) {\n        var chained = Object.create(inherited);\n        object = extend(chained, object);\n      }\n      return object;\n    }\n  }\n\n  // On platforms that do not support __proto__ (versions of IE), the prototype\n  // chain of a custom element is simulated via installation of __proto__.\n  // Although custom elements manages this, we install it here so it's\n  // available during desugaring.\n  function ensurePrototypeTraversal(prototype) {\n    if (!Object.__proto__) {\n      var ancestor = Object.getPrototypeOf(prototype);\n      prototype.__proto__ = ancestor;\n      if (isBase(ancestor)) {\n        ancestor.__proto__ = Object.getPrototypeOf(ancestor);\n      }\n    }\n  }\n\n  // exports\n\n  api.declaration.prototype = prototype;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  var queue = {\n    // tell the queue to wait for an element to be ready\n    wait: function(element, check, go) {\n      if (this.indexOf(element) === -1) {\n        this.add(element);\n        element.__check = check;\n        element.__go = go;\n      }\n      return (this.indexOf(element) !== 0);\n    },\n    add: function(element) {\n      //console.log('queueing', element.name);\n      queueForElement(element).push(element);\n    },\n    indexOf: function(element) {\n      var i = queueForElement(element).indexOf(element);\n      if (i >= 0 && document.contains(element)) {\n        i += (HTMLImports.useNative || HTMLImports.ready) ? importQueue.length :\n            1e9;\n      }\n      return i;  \n    },\n    // tell the queue an element is ready to be registered\n    go: function(element) {\n      var readied = this.remove(element);\n      if (readied) {\n        readied.__go.call(readied);\n        readied.__check = readied.__go = null;\n        this.check();\n      }\n    },\n    remove: function(element) {\n      var i = this.indexOf(element);\n      if (i !== 0) {\n        //console.warn('queue order wrong', i);\n        return;\n      }\n      return queueForElement(element).shift();  \n    },\n    check: function() {\n      // next\n      var element = this.nextElement();\n      if (element) {\n        element.__check.call(element);\n      }\n      if (this.canReady()) {\n        this.ready();\n        return true;\n      }\n    },\n    nextElement: function() {\n      return nextQueued();\n    },\n    canReady: function() {\n      return !this.waitToReady && this.isEmpty();\n    },\n    isEmpty: function() {\n      return !importQueue.length && !mainQueue.length;\n    },\n    ready: function() {\n      // TODO(sorvell): As an optimization, turn off CE polyfill upgrading\n      // while registering. This way we avoid having to upgrade each document\n      // piecemeal per registration and can instead register all elements\n      // and upgrade once in a batch. Without this optimization, upgrade time\n      // degrades significantly when SD polyfill is used. This is mainly because\n      // querying the document tree for elements is slow under the SD polyfill.\n      if (CustomElements.ready === false) {\n        CustomElements.upgradeDocumentTree(document);\n        CustomElements.ready = true;\n      }\n      if (readyCallbacks) {\n        var fn;\n        while (readyCallbacks.length) {\n          fn = readyCallbacks.shift();\n          fn();\n        }\n      }\n    },\n    addReadyCallback: function(callback) {\n      if (callback) {\n        readyCallbacks.push(callback);\n      }\n    },\n    waitToReady: true\n  };\n\n  var importQueue = [];\n  var mainQueue = [];\n  var readyCallbacks = [];\n\n  function queueForElement(element) {\n    return document.contains(element) ? mainQueue : importQueue;\n  }\n\n  function nextQueued() {\n    return importQueue.length ? importQueue[0] : mainQueue[0];\n  }\n\n  var polymerReadied = false; \n\n  document.addEventListener('WebComponentsReady', function() {\n    CustomElements.ready = false;\n  });\n  \n  function whenPolymerReady(callback) {\n    queue.waitToReady = true;\n    CustomElements.ready = false;\n    HTMLImports.whenImportsReady(function() {\n      queue.addReadyCallback(callback);\n      queue.waitToReady = false;\n      queue.check();\n    });\n  }\n\n  // exports\n  scope.queue = queue;\n  scope.whenPolymerReady = whenPolymerReady;\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  var whenPolymerReady = scope.whenPolymerReady;\n\n  function importElements(elementOrFragment, callback) {\n    if (elementOrFragment) {\n      document.head.appendChild(elementOrFragment);\n      whenPolymerReady(callback);\n    } else if (callback) {\n      callback();\n    }\n  }\n\n  function importUrls(urls, callback) {\n    if (urls && urls.length) {\n        var frag = document.createDocumentFragment();\n        for (var i=0, l=urls.length, url, link; (i<l) && (url=urls[i]); i++) {\n          link = document.createElement('link');\n          link.rel = 'import';\n          link.href = url;\n          frag.appendChild(link);\n        }\n        importElements(frag, callback);\n    } else if (callback) {\n      callback();\n    }\n  }\n\n  // exports\n  scope.import = importUrls;\n  scope.importElements = importElements;\n\n})(Polymer);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(scope) {\n\n  // imports\n\n  var extend = scope.extend;\n  var api = scope.api;\n  var queue = scope.queue;\n  var whenPolymerReady = scope.whenPolymerReady;\n  var getRegisteredPrototype = scope.getRegisteredPrototype;\n  var waitingForPrototype = scope.waitingForPrototype;\n\n  // declarative implementation: <polymer-element>\n\n  var prototype = extend(Object.create(HTMLElement.prototype), {\n\n    createdCallback: function() {\n      if (this.getAttribute('name')) {\n        this.init();\n      }\n    },\n\n    init: function() {\n      // fetch declared values\n      this.name = this.getAttribute('name');\n      this.extends = this.getAttribute('extends');\n      // initiate any async resource fetches\n      this.loadResources();\n      // register when all constraints are met\n      this.registerWhenReady();\n    },\n\n    registerWhenReady: function() {\n     if (this.registered\n       || this.waitingForPrototype(this.name)\n       || this.waitingForQueue()\n       || this.waitingForResources()) {\n          return;\n      }\n      queue.go(this);\n    },\n\n\n    // TODO(sorvell): refactor, this method is private-ish, but it's being\n    // called by the queue object.\n    _register: function() {\n      //console.log('registering', this.name);\n      //console.group('registering', this.name);\n      // warn if extending from a custom element not registered via Polymer\n      if (isCustomTag(this.extends) && !isRegistered(this.extends)) {\n        console.warn('%s is attempting to extend %s, an unregistered element ' +\n            'or one that was not registered with Polymer.', this.name,\n            this.extends);\n      }\n      this.register(this.name, this.extends);\n      this.registered = true;\n      //console.groupEnd();\n    },\n\n    waitingForPrototype: function(name) {\n      if (!getRegisteredPrototype(name)) {\n        // then wait for a prototype\n        waitingForPrototype(name, this);\n        // emulate script if user is not supplying one\n        this.handleNoScript(name);\n        // prototype not ready yet\n        return true;\n      }\n    },\n\n    handleNoScript: function(name) {\n      // if explicitly marked as 'noscript'\n      if (this.hasAttribute('noscript') && !this.noscript) {\n        this.noscript = true;\n        // TODO(sorvell): CustomElements polyfill awareness:\n        // noscript elements should upgrade in logical order\n        // script injection ensures this under native custom elements;\n        // under imports + ce polyfills, scripts run before upgrades.\n        // dependencies should be ready at upgrade time so register\n        // prototype at this time.\n        if (window.CustomElements && !CustomElements.useNative) {\n          Polymer(name);\n        } else {\n          var script = document.createElement('script');\n          script.textContent = 'Polymer(\\'' + name + '\\');';\n          this.appendChild(script);\n        }\n      }\n    },\n\n    waitingForResources: function() {\n      return this._needsResources;\n    },\n\n    // NOTE: Elements must be queued in proper order for inheritance/composition\n    // dependency resolution. Previously this was enforced for inheritance,\n    // and by rule for composition. It's now entirely by rule.\n    waitingForQueue: function() {\n      return queue.wait(this, this.registerWhenReady, this._register);\n    },\n\n    loadResources: function() {\n      this._needsResources = true;\n      this.loadStyles(function() {\n        this._needsResources = false;\n        this.registerWhenReady();\n      }.bind(this));\n    }\n\n  });\n\n  // semi-pluggable APIs \n\n  // TODO(sjmiles): should be fully pluggable (aka decoupled, currently\n  // the various plugins are allowed to depend on each other directly)\n  api.publish(api.declaration, prototype);\n\n  // utility and bookkeeping\n\n  function isRegistered(name) {\n    return Boolean(HTMLElement.getPrototypeForTag(name));\n  }\n\n  function isCustomTag(name) {\n    return (name && name.indexOf('-') >= 0);\n  }\n\n  // exports\n\n  scope.getRegisteredPrototype = getRegisteredPrototype;\n  \n  // boot tasks\n\n  whenPolymerReady(function() {\n    document.body.removeAttribute('unresolved');\n    document.dispatchEvent(\n      new CustomEvent('polymer-ready', {bubbles: true})\n    );\n  });\n\n  // register polymer-element with document\n\n  document.registerElement('polymer-element', {prototype: prototype});\n\n})(Polymer);\n"]}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/.bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/.bower.json
deleted file mode 100644
index 16d4ea6..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/.bower.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "name": "todomvc-common",
-  "version": "0.1.9",
-  "homepage": "https://github.com/tastejs/todomvc-common",
-  "_release": "0.1.9",
-  "_resolution": {
-    "type": "version",
-    "tag": "v0.1.9",
-    "commit": "7dd61b0ebf56c020e719a69444442cc7ae7242ff"
-  },
-  "_source": "git://github.com/tastejs/todomvc-common.git",
-  "_target": "~0.1.4",
-  "_originalSource": "todomvc-common"
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.css b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.css
deleted file mode 100644
index d151ede..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.css
+++ /dev/null
@@ -1,556 +0,0 @@
-html,
-body {
-	margin: 0;
-	padding: 0;
-}
-
-button {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	background: none;
-	font-size: 100%;
-	vertical-align: baseline;
-	font-family: inherit;
-	color: inherit;
-	-webkit-appearance: none;
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-body {
-	font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
-	line-height: 1.4em;
-	background: #eaeaea url('bg.png');
-	color: #4d4d4d;
-	width: 550px;
-	margin: 0 auto;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-button,
-input[type="checkbox"] {
-  outline: none;
-}
-
-#todoapp {
-	background: #fff;
-	background: rgba(255, 255, 255, 0.9);
-	margin: 130px 0 40px 0;
-	border: 1px solid #ccc;
-	position: relative;
-	border-top-left-radius: 2px;
-	border-top-right-radius: 2px;
-	box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
-				0 25px 50px 0 rgba(0, 0, 0, 0.15);
-}
-
-#todoapp:before {
-	content: '';
-	border-left: 1px solid #f5d6d6;
-	border-right: 1px solid #f5d6d6;
-	width: 2px;
-	position: absolute;
-	top: 0;
-	left: 40px;
-	height: 100%;
-}
-
-#todoapp input::-webkit-input-placeholder {
-	font-style: italic;
-}
-
-#todoapp input::-moz-placeholder {
-	font-style: italic;
-	color: #a9a9a9;
-}
-
-#todoapp h1 {
-	position: absolute;
-	top: -120px;
-	width: 100%;
-	font-size: 70px;
-	font-weight: bold;
-	text-align: center;
-	color: #b3b3b3;
-	color: rgba(255, 255, 255, 0.3);
-	text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-	-webkit-text-rendering: optimizeLegibility;
-	-moz-text-rendering: optimizeLegibility;
-	-ms-text-rendering: optimizeLegibility;
-	-o-text-rendering: optimizeLegibility;
-	text-rendering: optimizeLegibility;
-}
-
-#header {
-	padding-top: 15px;
-	border-radius: inherit;
-}
-
-#header:before {
-	content: '';
-	position: absolute;
-	top: 0;
-	right: 0;
-	left: 0;
-	height: 15px;
-	z-index: 2;
-	border-bottom: 1px solid #6c615c;
-	background: #8d7d77;
-	background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
-	background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
-	border-top-left-radius: 1px;
-	border-top-right-radius: 1px;
-}
-
-#new-todo,
-.edit {
-	position: relative;
-	margin: 0;
-	width: 100%;
-	font-size: 24px;
-	font-family: inherit;
-	line-height: 1.4em;
-	border: 0;
-	outline: none;
-	color: inherit;
-	padding: 6px;
-	border: 1px solid #999;
-	box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-	-moz-box-sizing: border-box;
-	-ms-box-sizing: border-box;
-	-o-box-sizing: border-box;
-	box-sizing: border-box;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-#new-todo {
-	padding: 16px 16px 16px 60px;
-	border: none;
-	background: rgba(0, 0, 0, 0.02);
-	z-index: 2;
-	box-shadow: none;
-}
-
-#main {
-	position: relative;
-	z-index: 2;
-	border-top: 1px dotted #adadad;
-}
-
-label[for='toggle-all'] {
-	display: none;
-}
-
-#toggle-all {
-	position: absolute;
-	top: -42px;
-	left: -4px;
-	width: 40px;
-	text-align: center;
-	/* Mobile Safari */
-	border: none;
-}
-
-#toggle-all:before {
-	content: '»';
-	font-size: 28px;
-	color: #d9d9d9;
-	padding: 0 25px 7px;
-}
-
-#toggle-all:checked:before {
-	color: #737373;
-}
-
-#todo-list {
-	margin: 0;
-	padding: 0;
-	list-style: none;
-}
-
-#todo-list li {
-	position: relative;
-	font-size: 24px;
-	border-bottom: 1px dotted #ccc;
-}
-
-#todo-list li:last-child {
-	border-bottom: none;
-}
-
-#todo-list li.editing {
-	border-bottom: none;
-	padding: 0;
-}
-
-#todo-list li.editing .edit {
-	display: block;
-	width: 506px;
-	padding: 13px 17px 12px 17px;
-	margin: 0 0 0 43px;
-}
-
-#todo-list li.editing .view {
-	display: none;
-}
-
-#todo-list li .toggle {
-	text-align: center;
-	width: 40px;
-	/* auto, since non-WebKit browsers doesn't support input styling */
-	height: auto;
-	position: absolute;
-	top: 0;
-	bottom: 0;
-	margin: auto 0;
-	/* Mobile Safari */
-	border: none;
-	-webkit-appearance: none;
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-#todo-list li .toggle:after {
-	content: '✔';
-	/* 40 + a couple of pixels visual adjustment */
-	line-height: 43px;
-	font-size: 20px;
-	color: #d9d9d9;
-	text-shadow: 0 -1px 0 #bfbfbf;
-}
-
-#todo-list li .toggle:checked:after {
-	color: #85ada7;
-	text-shadow: 0 1px 0 #669991;
-	bottom: 1px;
-	position: relative;
-}
-
-#todo-list li label {
-	white-space: pre;
-	word-break: break-word;
-	padding: 15px 60px 15px 15px;
-	margin-left: 45px;
-	display: block;
-	line-height: 1.2;
-	-webkit-transition: color 0.4s;
-	transition: color 0.4s;
-}
-
-#todo-list li.completed label {
-	color: #a9a9a9;
-	text-decoration: line-through;
-}
-
-#todo-list li .destroy {
-	display: none;
-	position: absolute;
-	top: 0;
-	right: 10px;
-	bottom: 0;
-	width: 40px;
-	height: 40px;
-	margin: auto 0;
-	font-size: 22px;
-	color: #a88a8a;
-	-webkit-transition: all 0.2s;
-	transition: all 0.2s;
-}
-
-#todo-list li .destroy:hover {
-	text-shadow: 0 0 1px #000,
-				 0 0 10px rgba(199, 107, 107, 0.8);
-	-webkit-transform: scale(1.3);
-	-ms-transform: scale(1.3);
-	transform: scale(1.3);
-}
-
-#todo-list li .destroy:after {
-	content: '✖';
-}
-
-#todo-list li:hover .destroy {
-	display: block;
-}
-
-#todo-list li .edit {
-	display: none;
-}
-
-#todo-list li.editing:last-child {
-	margin-bottom: -1px;
-}
-
-#footer {
-	color: #777;
-	padding: 0 15px;
-	position: absolute;
-	right: 0;
-	bottom: -31px;
-	left: 0;
-	height: 20px;
-	z-index: 1;
-	text-align: center;
-}
-
-#footer:before {
-	content: '';
-	position: absolute;
-	right: 0;
-	bottom: 31px;
-	left: 0;
-	height: 50px;
-	z-index: -1;
-	box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
-				0 6px 0 -3px rgba(255, 255, 255, 0.8),
-				0 7px 1px -3px rgba(0, 0, 0, 0.3),
-				0 43px 0 -6px rgba(255, 255, 255, 0.8),
-				0 44px 2px -6px rgba(0, 0, 0, 0.2);
-}
-
-#todo-count {
-	float: left;
-	text-align: left;
-}
-
-#filters {
-	margin: 0;
-	padding: 0;
-	list-style: none;
-	position: absolute;
-	right: 0;
-	left: 0;
-}
-
-#filters li {
-	display: inline;
-}
-
-#filters li a {
-	color: #83756f;
-	margin: 2px;
-	text-decoration: none;
-}
-
-#filters li a.selected {
-	font-weight: bold;
-}
-
-#clear-completed {
-	float: right;
-	position: relative;
-	line-height: 20px;
-	text-decoration: none;
-	background: rgba(0, 0, 0, 0.1);
-	font-size: 11px;
-	padding: 0 10px;
-	border-radius: 3px;
-	box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
-}
-
-#clear-completed:hover {
-	background: rgba(0, 0, 0, 0.15);
-	box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
-}
-
-#info {
-	margin: 65px auto 0;
-	color: #a6a6a6;
-	font-size: 12px;
-	text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
-	text-align: center;
-}
-
-#info a {
-	color: inherit;
-}
-
-/*
-	Hack to remove background from Mobile Safari.
-	Can't use it globally since it destroys checkboxes in Firefox and Opera
-*/
-
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-	#toggle-all,
-	#todo-list li .toggle {
-		background: none;
-	}
-
-	#todo-list li .toggle {
-		height: 40px;
-	}
-
-	#toggle-all {
-		top: -56px;
-		left: -15px;
-		width: 65px;
-		height: 41px;
-		-webkit-transform: rotate(90deg);
-		-ms-transform: rotate(90deg);
-		transform: rotate(90deg);
-		-webkit-appearance: none;
-		appearance: none;
-	}
-}
-
-.hidden {
-	display: none;
-}
-
-hr {
-	margin: 20px 0;
-	border: 0;
-	border-top: 1px dashed #C5C5C5;
-	border-bottom: 1px dashed #F7F7F7;
-}
-
-.learn a {
-	font-weight: normal;
-	text-decoration: none;
-	color: #b83f45;
-}
-
-.learn a:hover {
-	text-decoration: underline;
-	color: #787e7e;
-}
-
-.learn h3,
-.learn h4,
-.learn h5 {
-	margin: 10px 0;
-	font-weight: 500;
-	line-height: 1.2;
-	color: #000;
-}
-
-.learn h3 {
-	font-size: 24px;
-}
-
-.learn h4 {
-	font-size: 18px;
-}
-
-.learn h5 {
-	margin-bottom: 0;
-	font-size: 14px;
-}
-
-.learn ul {
-	padding: 0;
-	margin: 0 0 30px 25px;
-}
-
-.learn li {
-	line-height: 20px;
-}
-
-.learn p {
-	font-size: 15px;
-	font-weight: 300;
-	line-height: 1.3;
-	margin-top: 0;
-	margin-bottom: 0;
-}
-
-.quote {
-	border: none;
-	margin: 20px 0 60px 0;
-}
-
-.quote p {
-	font-style: italic;
-}
-
-.quote p:before {
-	content: '“';
-	font-size: 50px;
-	opacity: .15;
-	position: absolute;
-	top: -20px;
-	left: 3px;
-}
-
-.quote p:after {
-	content: '”';
-	font-size: 50px;
-	opacity: .15;
-	position: absolute;
-	bottom: -42px;
-	right: 3px;
-}
-
-.quote footer {
-	position: absolute;
-	bottom: -40px;
-	right: 0;
-}
-
-.quote footer img {
-	border-radius: 3px;
-}
-
-.quote footer a {
-	margin-left: 5px;
-	vertical-align: middle;
-}
-
-.speech-bubble {
-	position: relative;
-	padding: 10px;
-	background: rgba(0, 0, 0, .04);
-	border-radius: 5px;
-}
-
-.speech-bubble:after {
-	content: '';
-	position: absolute;
-	top: 100%;
-	right: 30px;
-	border: 13px solid transparent;
-	border-top-color: rgba(0, 0, 0, .04);
-}
-
-.learn-bar > .learn {
-	position: absolute;
-	width: 272px;
-	top: 8px;
-	left: -300px;
-	padding: 10px;
-	border-radius: 5px;
-	background-color: rgba(255, 255, 255, .6);
-	-webkit-transition-property: left;
-	transition-property: left;
-	-webkit-transition-duration: 500ms;
-	transition-duration: 500ms;
-}
-
-@media (min-width: 899px) {
-	.learn-bar {
-		width: auto;
-		margin: 0 0 0 300px;
-	}
-
-	.learn-bar > .learn {
-		left: 8px;
-	}
-
-	.learn-bar #todoapp {
-		width: 550px;
-		margin: 130px auto 40px auto;
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.js b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.js
deleted file mode 100644
index 099da60..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/base.js
+++ /dev/null
@@ -1,209 +0,0 @@
-(function () {
-	'use strict';
-
-	// Underscore's Template Module
-	// Courtesy of underscorejs.org
-	var _ = (function (_) {
-		_.defaults = function (object) {
-			if (!object) {
-				return object;
-			}
-			for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
-				var iterable = arguments[argsIndex];
-				if (iterable) {
-					for (var key in iterable) {
-						if (object[key] == null) {
-							object[key] = iterable[key];
-						}
-					}
-				}
-			}
-			return object;
-		}
-
-		// By default, Underscore uses ERB-style template delimiters, change the
-		// following template settings to use alternative delimiters.
-		_.templateSettings = {
-			evaluate    : /<%([\s\S]+?)%>/g,
-			interpolate : /<%=([\s\S]+?)%>/g,
-			escape      : /<%-([\s\S]+?)%>/g
-		};
-
-		// When customizing `templateSettings`, if you don't want to define an
-		// interpolation, evaluation or escaping regex, we need one that is
-		// guaranteed not to match.
-		var noMatch = /(.)^/;
-
-		// Certain characters need to be escaped so that they can be put into a
-		// string literal.
-		var escapes = {
-			"'":      "'",
-			'\\':     '\\',
-			'\r':     'r',
-			'\n':     'n',
-			'\t':     't',
-			'\u2028': 'u2028',
-			'\u2029': 'u2029'
-		};
-
-		var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
-
-		// JavaScript micro-templating, similar to John Resig's implementation.
-		// Underscore templating handles arbitrary delimiters, preserves whitespace,
-		// and correctly escapes quotes within interpolated code.
-		_.template = function(text, data, settings) {
-			var render;
-			settings = _.defaults({}, settings, _.templateSettings);
-
-			// Combine delimiters into one regular expression via alternation.
-			var matcher = new RegExp([
-				(settings.escape || noMatch).source,
-				(settings.interpolate || noMatch).source,
-				(settings.evaluate || noMatch).source
-			].join('|') + '|$', 'g');
-
-			// Compile the template source, escaping string literals appropriately.
-			var index = 0;
-			var source = "__p+='";
-			text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
-				source += text.slice(index, offset)
-					.replace(escaper, function(match) { return '\\' + escapes[match]; });
-
-				if (escape) {
-					source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
-				}
-				if (interpolate) {
-					source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
-				}
-				if (evaluate) {
-					source += "';\n" + evaluate + "\n__p+='";
-				}
-				index = offset + match.length;
-				return match;
-			});
-			source += "';\n";
-
-			// If a variable is not specified, place data values in local scope.
-			if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
-
-			source = "var __t,__p='',__j=Array.prototype.join," +
-				"print=function(){__p+=__j.call(arguments,'');};\n" +
-				source + "return __p;\n";
-
-			try {
-				render = new Function(settings.variable || 'obj', '_', source);
-			} catch (e) {
-				e.source = source;
-				throw e;
-			}
-
-			if (data) return render(data, _);
-			var template = function(data) {
-				return render.call(this, data, _);
-			};
-
-			// Provide the compiled function source as a convenience for precompilation.
-			template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
-
-			return template;
-		};
-
-		return _;
-	})({});
-
-	if (location.hostname === 'todomvc.com') {
-		window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
-	}
-
-	function redirect() {
-		if (location.hostname === 'tastejs.github.io') {
-			location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
-		}
-	}
-
-	function findRoot() {
-		var base;
-
-		[/labs/, /\w*-examples/].forEach(function (href) {
-			var match = location.href.match(href);
-
-			if (!base && match) {
-				base = location.href.indexOf(match);
-			}
-		});
-
-		return location.href.substr(0, base);
-	}
-
-	function getFile(file, callback) {
-		if (!location.host) {
-			return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
-		}
-
-		var xhr = new XMLHttpRequest();
-
-		xhr.open('GET', findRoot() + file, true);
-		xhr.send();
-
-		xhr.onload = function () {
-			if (xhr.status === 200 && callback) {
-				callback(xhr.responseText);
-			}
-		};
-	}
-
-	function Learn(learnJSON, config) {
-		if (!(this instanceof Learn)) {
-			return new Learn(learnJSON, config);
-		}
-
-		var template, framework;
-
-		if (typeof learnJSON !== 'object') {
-			try {
-				learnJSON = JSON.parse(learnJSON);
-			} catch (e) {
-				return;
-			}
-		}
-
-		if (config) {
-			template = config.template;
-			framework = config.framework;
-		}
-
-		if (!template && learnJSON.templates) {
-			template = learnJSON.templates.todomvc;
-		}
-
-		if (!framework && document.querySelector('[data-framework]')) {
-			framework = document.querySelector('[data-framework]').getAttribute('data-framework');
-		}
-
-
-		if (template && learnJSON[framework]) {
-			this.frameworkJSON = learnJSON[framework];
-			this.template = template;
-
-			this.append();
-		}
-	}
-
-	Learn.prototype.append = function () {
-		var aside = document.createElement('aside');
-		aside.innerHTML = _.template(this.template, this.frameworkJSON);
-		aside.className = 'learn';
-
-		// Localize demo links
-		var demoLinks = aside.querySelectorAll('.demo-link');
-		Array.prototype.forEach.call(demoLinks, function (demoLink) {
-			demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
-		});
-
-		document.body.className = (document.body.className + ' learn-bar').trim();
-		document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
-	};
-
-	redirect();
-	getFile('learn.json', Learn);
-})();
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bg.png b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bg.png
deleted file mode 100644
index b2a7600..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bg.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bower.json b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bower.json
deleted file mode 100644
index cdc4a43..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/bower.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "todomvc-common",
-  "version": "0.1.9"
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/readme.md b/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/readme.md
deleted file mode 100644
index 566a64c..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/components/todomvc-common/readme.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# todomvc-common
-
-> Bower component for some common utilities we use in every app
-
-
-## License
-
-MIT
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-input.html b/samples/third_party/todomvc_performance/js_todomvc/elements/td-input.html
deleted file mode 100755
index 5679be1..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-input.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<link rel="import" href="../components/polymer/polymer.html">
-
-<polymer-element name="td-input" extends="input" on-keyup="{{keyupAction}}" on-keypress="{{keypressAction}}">
-	<script>
-		(function() {
-			var ENTER_KEY = 13;
-			var ESC_KEY = 27;
-			Polymer('td-input', {
-				keypressAction: function(e, detail, sender) {
-					// Listen for enter on keypress but esc on keyup, because
-					// IE doesn't fire keyup for enter.
-					if (e.keyCode === ENTER_KEY) {
-						this.fire('td-input-commit');
-					}
-				},
-				keyupAction: function(e, detail, sender) {
-					if (e.keyCode === ESC_KEY) {
-						this.fire('td-input-cancel');
-					}
-				}
-			});
-		})();
-	</script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.css b/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.css
deleted file mode 100755
index c3768aef..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.css
+++ /dev/null
@@ -1,161 +0,0 @@
-/* base.css overrides */
-@host {
-	.editing {
-		border-bottom: none;
-		padding: 0;
-	}
-}
-
-button {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	background-color: transparent;
-	background-image: none;
-	font-size: 100%;
-	vertical-align: baseline;
-	font-family: inherit;
-	color: inherit;
-	-webkit-appearance: none;
-	/*-moz-appearance: none;*/
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-
-.edit {
-	position: relative;
-	margin: 0;
-	width: 100%;
-	font-size: 24px;
-	font-family: inherit;
-	line-height: 1.4em;
-	border: 0;
-	outline: none;
-	color: inherit;
-	padding: 6px;
-	border: 1px solid #999;
-	box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-	-webkit-box-sizing: border-box;
-	-moz-box-sizing: border-box;
-	-ms-box-sizing: border-box;
-	-o-box-sizing: border-box;
-	box-sizing: border-box;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-.edit {
-	width: 506px;
-	padding: 13px 17px 12px 17px;
-	margin: 0 0 0 43px;
-}
-
-.toggle {
-	text-align: center;
-	width: 40px;
-	/* auto, since non-WebKit browsers doesn't support input styling */
-	height: auto;
-	position: absolute;
-	top: 0;
-	bottom: 0;
-	margin: auto 0;
-	border: none; /* Mobile Safari */
-	-webkit-appearance: none;
-	/*-moz-appearance: none;*/
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-.toggle:after {
-	content: '✔';
-	line-height: 43px; /* 40 + a couple of pixels visual adjustment */
-	font-size: 20px;
-	color: #d9d9d9;
-	text-shadow: 0 -1px 0 #bfbfbf;
-}
-
-.toggle:checked:after {
-	color: #85ada7;
-	text-shadow: 0 1px 0 #669991;
-	bottom: 1px;
-	position: relative;
-}
-
-label {
-	word-break: break-word;
-	padding: 15px;
-	margin-left: 45px;
-	display: block;
-	line-height: 1.2;
-	-webkit-transition: color 0.4s;
-	-moz-transition: color 0.4s;
-	-ms-transition: color 0.4s;
-	-o-transition: color 0.4s;
-	transition: color 0.4s;
-}
-
-.completed label {
-	color: #a9a9a9;
-	text-decoration: line-through;
-}
-
-.destroy {
-	display: none;
-	position: absolute;
-	top: 0;
-	right: 10px;
-	bottom: 0;
-	width: 40px;
-	height: 40px;
-	margin: auto 0;
-	font-size: 22px;
-	color: #a88a8a;
-	-webkit-transition: all 0.2s;
-	-moz-transition: all 0.2s;
-	-ms-transition: all 0.2s;
-	-o-transition: all 0.2s;
-	transition: all 0.2s;
-}
-
-.destroy:hover {
-	text-shadow: 0 0 1px #000,
-				 0 0 10px rgba(199, 107, 107, 0.8);
-	-webkit-transform: scale(1.3);
-	-moz-transform: scale(1.3);
-	-ms-transform: scale(1.3);
-	-o-transform: scale(1.3);
-	transform: scale(1.3);
-}
-
-.destroy:after {
-	content: '✖';
-}
-
-.view:hover .destroy {
-	display: block;
-}
-
-/*
-	Hack to remove background from Mobile Safari.
-	Can't use it globally since it destroys checkboxes in Firefox and Opera
-*/
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-	.toggle {
-		background: none;
-    /* 
-      ShadowDOM Polyfill work around for webkit/blink bug 
-      https://code.google.com/p/chromium/issues/detail?id=251510
-    */
-    background-color: transparent;
-	}
-
-	.toggle {
-		height: 40px;
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.html b/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.html
deleted file mode 100755
index 2cc13a3..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-item.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<link rel="import" href="../components/polymer/polymer.html">
-<link rel="import" href="td-input.html">
-
-<polymer-element name="td-item" extends="li" attributes="item editing" on-blur="{{commitAction}}">
-	<template>
-		<link rel="stylesheet" href="td-item.css">
-		<div class="view {{ {completed: item.completed, editing: editing} | tokenList }}" hidden?="{{editing}}" on-dblclick="{{editAction}}">
-			<input type="checkbox" class="toggle" checked="{{item.completed}}" on-click="{{itemChangeAction}}">
-			<label>{{item.title}}</label>
-			<button class="destroy" on-click="{{destroyAction}}"></button>
-		</div>
-		<input is="td-input" id="edit" class="edit" value="{{item.title}}" hidden?="{{!editing}}" on-td-input-commit="{{commitAction}}" on-td-input-cancel="{{cancelAction}}">
-	</template>
-	<script>
-		(function() {
-			Polymer('td-item', {
-				editing: false,
-				editAction: function() {
-					this.editing = true;
-					// schedule focus for the end of microtask, when the input will be visible
-					this.asyncMethod(function() {
-						this.$.edit.focus();
-					});
-				},
-				commitAction: function() {
-					if (this.editing) {
-						this.editing = false;
-						this.item.title = this.item.title.trim();
-						if (this.item.title === '') {
-							this.destroyAction();
-						}
-						this.fire('td-item-changed');
-					}
-				},
-				cancelAction: function() {
-					this.editing = false;
-				},
-				itemChangeAction: function() {
-					this.fire('td-item-changed');
-				},
-				destroyAction: function() {
-					this.fire('td-destroy-item', this.item);
-				}
-			});
-		})();
-	</script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-model.html b/samples/third_party/todomvc_performance/js_todomvc/elements/td-model.html
deleted file mode 100755
index 19f3d22..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-model.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<link rel="import" href="../components/polymer/polymer.html">
-
-<polymer-element name="td-model" attributes="filter items storageId">
-	<script>
-		Polymer('td-model', {
-			filtered: null,
-			completedCount: 0,
-			activeCount: 0,
-			allCompleted: false,
-			ready: function() {
-				this.asyncMethod(function() {
-					this.items = this.items || [];
-				});
-			},
-			filterChanged: function() {
-				this.filterItems();
-			},
-			itemsChanged: function() {
-				this.completedCount =
-					this.items.filter(this.filters.completed).length;
-				this.activeCount = this.items.length - this.completedCount;
-				this.allCompleted = this.completedCount && !this.activeCount;
-				this.filterItems();
-				if (this.storage) {
-					this.storage.value = this.items;
-					this.storage.save();
-				}
-			},
-			storageIdChanged: function() {
-				this.storage = document.querySelector('#' + this.storageId);
-				this.storage && (this.items = this.storage.value);
-			},
-			filterItems: function() {
-				var fn = this.filters[this.filter];
-				this.filtered = fn ? this.items.filter(fn) : this.items;
-			},
-			newItem: function(title) {
-				title = String(title).trim();
-				if (title) {
-					var item = {
-						title: title,
-						completed: false
-					};
-					this.items.push(item);
-					this.itemsChanged();
-				}
-			},
-			destroyItem: function(item) {
-				var i = this.items.indexOf(item);
-				if (i >= 0) {
-					this.items.splice(i, 1);
-				}
-				this.itemsChanged();
-			},
-			clearItems: function(){
-				this.items = this.items.filter(this.filters.active);
-			},
-			setItemsCompleted: function(completed) {
-				this.items.forEach(function(item) {
-					item.completed = completed;
-				});
-				this.itemsChanged();
-			},
-			filters: {
-				active: function(item) {
-					return !item.completed;
-				},
-				completed: function(item) {
-					return item.completed;
-				}
-			}
-	 });
-	</script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.css b/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.css
deleted file mode 100755
index 913d98b..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.css
+++ /dev/null
@@ -1,267 +0,0 @@
-/* base.css overrides */
-
-@host { 
-	* { 
-		display: block;
-		position: relative;
-	}
-}
-
-button {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	background: none;
-	font-size: 100%;
-	vertical-align: baseline;
-	font-family: inherit;
-	color: inherit;
-	-webkit-appearance: none;
-	/*-moz-appearance: none;*/
-	-ms-appearance: none;
-	-o-appearance: none;
-	appearance: none;
-}
-
-input::-webkit-input-placeholder {
-	font-style: italic;
-}
-
-input::-moz-placeholder {
-	font-style: italic;
-	color: #a9a9a9;
-}
-
-input:-ms-input-placeholder, #new-todo:-ms-input-placeholder {
-	font-style: italic;
-	color: #a9a9a9;
-}
-
-#todoapp {
-	background: #fff;
-	background: rgba(255, 255, 255, 0.9);
-	/*margin: 130px 0 40px 0;*/
-	margin: 0 0 40px 0;
-	border: 1px solid #ccc;
-	position: relative;
-	border-top-left-radius: 2px;
-	border-top-right-radius: 2px;
-	box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
-				0 25px 50px 0 rgba(0, 0, 0, 0.15);
-}
-
-#todoapp:before {
-	content: '';
-	border-left: 1px solid #f5d6d6;
-	border-right: 1px solid #f5d6d6;
-	width: 2px;
-	position: absolute;
-	top: 0;
-	left: 40px;
-	height: 100%;
-}
-
-#header {
-	padding-top: 15px;
-	border-radius: inherit;
-}
-
-#header:before {
-	content: '';
-	position: absolute;
-	top: 0;
-	right: 0;
-	left: 0;
-	height: 15px;
-	z-index: 2;
-	border-bottom: 1px solid #6c615c;
-	background: #8d7d77;
-	background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
-	background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
-	border-top-left-radius: 1px;
-	border-top-right-radius: 1px;
-}
-
-#new-todo,
-.edit {
-	position: relative;
-	margin: 0;
-	width: 100%;
-	font-size: 24px;
-	font-family: inherit;
-	line-height: 1.4em;
-	border: 0;
-	outline: none;
-	color: inherit;
-	padding: 6px;
-	border: 1px solid #999;
-	box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-	-webkit-box-sizing: border-box;
-	-moz-box-sizing: border-box;
-	-ms-box-sizing: border-box;
-	-o-box-sizing: border-box;
-	box-sizing: border-box;
-	-webkit-font-smoothing: antialiased;
-	-moz-font-smoothing: antialiased;
-	-ms-font-smoothing: antialiased;
-	-o-font-smoothing: antialiased;
-	font-smoothing: antialiased;
-}
-
-#new-todo {
-	padding: 16px 16px 16px 60px;
-	border: none;
-	background: rgba(0, 0, 0, 0.02);
-	z-index: 2;
-	box-shadow: none;
-}
-
-#main {
-	position: relative;
-	z-index: 2;
-	border-top: 1px dotted #adadad;
-}
-
-label[for='toggle-all'] {
-	display: none;
-}
-
-#toggle-all {
-	position: absolute;
-	top: -42px;
-	left: -4px;
-	width: 40px;
-	text-align: center;
-	border: none; /* Mobile Safari */
-}
-
-#toggle-all:before {
-	content: '»';
-	font-size: 28px;
-	color: #d9d9d9;
-	padding: 0 25px 7px;
-}
-
-#toggle-all:checked:before {
-	color: #737373;
-}
-
-#todo-list {
-	margin: 0;
-	padding: 0;
-	list-style: none;
-}
-
-#todo-list li {
-	position: relative;
-	font-size: 24px;
-	border-bottom: 1px dotted #ccc;
-}
-
-#todo-list li:last-child {
-	border-bottom: none;
-}
-
-#todo-list li.editing {
-	border-bottom: none;
-	padding: 0;
-}
-
-#footer {
-	color: #777;
-	padding: 0 15px;
-	position: absolute;
-	right: 0;
-	bottom: -31px;
-	left: 0;
-	height: 20px;
-	z-index: 1;
-	text-align: center;
-}
-
-#footer:before {
-	content: '';
-	position: absolute;
-	right: 0;
-	bottom: 31px;
-	left: 0;
-	height: 50px;
-	z-index: -1;
-	box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
-				0 6px 0 -3px rgba(255, 255, 255, 0.8),
-				0 7px 1px -3px rgba(0, 0, 0, 0.3),
-				0 43px 0 -6px rgba(255, 255, 255, 0.8),
-				0 44px 2px -6px rgba(0, 0, 0, 0.2);
-}
-
-#todo-count {
-	float: left;
-	text-align: left;
-}
-
-#filters {
-	margin: 0;
-	padding: 0;
-	list-style: none;
-	position: absolute;
-	right: 0;
-	left: 0;
-}
-
-#filters li {
-	display: inline;
-}
-
-#filters li a {
-	color: #83756f;
-	margin: 2px;
-	text-decoration: none;
-}
-
-#filters li.polymer-selected a {
-	font-weight: bold;
-}
-
-#clear-completed {
-	float: right;
-	position: relative;
-	line-height: 20px;
-	text-decoration: none;
-	background: rgba(0, 0, 0, 0.1);
-	font-size: 11px;
-	padding: 0 10px;
-	border-radius: 3px;
-	box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
-}
-
-#clear-completed:hover {
-	background: rgba(0, 0, 0, 0.15);
-	box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
-}
-
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-	#toggle-all {
-		background: none;
-    /* 
-      ShadowDOM Polyfill work around for webkit/blink bug 
-      https://code.google.com/p/chromium/issues/detail?id=251510
-    */
-    background-color: transparent;
-	}
-
-	#toggle-all {
-		top: -56px;
-		left: -15px;
-		width: 65px;
-		height: 41px;
-		-webkit-transform: rotate(90deg);
-		transform: rotate(90deg);
-		-webkit-appearance: none;
-		appearance: none;
-	}
-}
diff --git a/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.html b/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.html
deleted file mode 100755
index 2dc1ce5..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/elements/td-todos.html
+++ /dev/null
@@ -1,79 +0,0 @@
-
-<link rel="import" href="../components/polymer/polymer.html">
-<link rel="import" href="../components/polymer-selector/polymer-selector.html">
-<link rel="import" href="../components/flatiron-director/flatiron-director.html">
-<link rel="import" href="td-input.html">
-<link rel="import" href="td-item.html">
-
-<polymer-element name="td-todos" attributes="route modelId">
-	<template>
-		<link rel="stylesheet" href="td-todos.css">
-		<flatiron-director route="{{route}}"></flatiron-director>
-		<section id="todoapp">
-			<header id="header">
-				<input is="td-input" id="new-todo" placeholder="What needs to be done?" autofocus on-td-input-commit="{{addTodoAction}}" on-td-input-cancel="{{cancelAddTodoAction}}">
-			</header>
-			<section id="main" hidden?="{{model.items.length == 0}}">
-				<input id="toggle-all" type="checkbox" on-change="{{toggleAllCompletedAction}}" checked="{{model.allCompleted}}">
-				<label for="toggle-all">Mark all as complete</label>
-				<ul id="todo-list" on-td-item-changed="{{itemChangedAction}}" on-td-destroy-item="{{destroyItemAction}}">
-					<template repeat="{{model.filtered}}">
-						<li is="td-item" item="{{}}"></li>
-					</template>
-				</ul>
-			</section>
-			<footer id="footer" hidden?="{{model.items.length == 0}}">
-				<span id="todo-count"><strong>{{model.activeCount}}</strong> {{model.activeCount == 1 ? 'item' : 'items'}} left</span>
-				<polymer-selector id="filters" selected="{{route || 'all'}}">
-					<li name="all">
-						<a href="../#/">All</a>
-					</li>
-					<li name="active">
-						<a href="../#/active">Active</a>
-					</li>
-					<li name="completed">
-						<a href="../#/completed">Completed</a>
-					</li>
-				</polymer-selector>
-				<button hidden?="{{model.completedCount == 0}}" id="clear-completed" on-click="{{clearCompletedAction}}">Clear completed ({{model.completedCount}})</button>
-			</footer>
-		</section>
-	</template>
-
-	<script>
-		(function() {
-			var ENTER_KEY = 13;
-			var ESC_KEY = 27;
-			Polymer('td-todos', {
-				modelIdChanged: function() {
-					this.model = document.querySelector('#' + this.modelId);
-				},
-				routeChanged: function() {
-					this.model && (this.model.filter = this.route);
-				},
-				addTodoAction: function() {
-					this.model.newItem(this.$['new-todo'].value);
-					// when polyfilling Object.observe, make sure we update immediately
-					Platform.flush();
-					this.$['new-todo'].value = '';
-				},
-				cancelAddTodoAction: function() {
-					this.$['new-todo'].value = '';
-				},
-				itemChangedAction: function() {
-					this.model && this.model.itemsChanged();
-				},
-				destroyItemAction: function(e, detail) {
-					this.model.destroyItem(detail);
-				},
-				toggleAllCompletedAction: function(e, detail, sender) {
-					this.model.setItemsCompleted(sender.checked);
-				},
-				clearCompletedAction: function() {
-					this.model.clearItems();
-				}
-			});
-		})();
-	</script>
-
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/index.html b/samples/third_party/todomvc_performance/js_todomvc/index.html
deleted file mode 100755
index 8d21059..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/index.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!doctype html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8">
-		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-		<title>Polymer • TodoMVC</title>
-		<link rel="stylesheet" href="app/app.css">
-		<script src="components/platform/platform.js"></script>
-		<link rel="import" href="components/polymer-localstorage/polymer-localstorage.html">
-		<link rel="import" href="elements/td-model.html">
-		<link rel="import" href="elements/td-todos.html">
-    <script src="packages/browser_controller/perf_test_controller.js"></script>
-    <script type="application/javascript">
-      var startTime = new Date().getTime();
-
-      window.addEventListener('polymer-ready', function(e) {
-        var endTime = new Date().getTime();
-        var startupTime = endTime - startTime;
-        document.body.innerHTML = 'The startup time is ' + startupTime + ' milliseconds.';
-        reportPerformanceTestDone();
-      });
-    </script>
-	</head>
-	<body>
-		<header>
-			<h1>todos</h1>
-		</header>
-		<polymer-localstorage id="storage" name="todos-polymer"></polymer-localstorage>
-		<td-model id="model" storageId="storage"></td-model>
-		<td-todos modelId="model"></td-todos>
-		<footer id="info">
-			<p>Double-click to edit a todo</p>
-			<p>Created by <a href="http://www.polymer-project.org">The Polymer Authors</a></p>
-			<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
-		</footer>
-	</body>
-</html>
diff --git a/samples/third_party/todomvc_performance/js_todomvc/pubspec.yaml b/samples/third_party/todomvc_performance/js_todomvc/pubspec.yaml
deleted file mode 100644
index 61ed39d..0000000
--- a/samples/third_party/todomvc_performance/js_todomvc/pubspec.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: js_todomvc
-description: A snapshot of https://github.com/Polymer/todomvc
-version: 0.00.1
-dependencies:
-  browser_controller: ">=0.00.2-dev <0.0.2"
-environment:
-  sdk: ">=1.2.0 <2.0.0"
diff --git a/samples/third_party/todomvc_performance/pubspec.yaml b/samples/third_party/todomvc_performance/pubspec.yaml
deleted file mode 100644
index 6bbc539..0000000
--- a/samples/third_party/todomvc_performance/pubspec.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: todomvc
-description: TodoMVC built with the polymer.dart package
-version: 0.15.0
-dependencies:
-  polymer: ">=0.10.0-pre.1 <0.11.0"
-  browser_controller: ">=0.00.2-dev <0.0.3"
-transformers:
-- polymer:
-    entry_points: web/startup-performance.html
-    minify: true
-dev_dependencies:
-  unittest: ">=0.10.0 <0.11.0"
-environment:
-  sdk: ">=1.2.0 <2.0.0"
diff --git a/samples/third_party/todomvc_performance/web/app/app.css b/samples/third_party/todomvc_performance/web/app/app.css
deleted file mode 100644
index 68a1468..0000000
--- a/samples/third_party/todomvc_performance/web/app/app.css
+++ /dev/null
@@ -1,206 +0,0 @@
-/* base.css overrides */
-
-html,
-body {
-  margin: 0;
-  padding: 0;
-}
-
-body {
-  font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
-  line-height: 1.4em;
-  background: #eaeaea url('bg.png');
-  color: #4d4d4d;
-  width: 550px;
-  margin: 0 auto;
-  -webkit-font-smoothing: antialiased;
-  -moz-font-smoothing: antialiased;
-  -ms-font-smoothing: antialiased;
-  -o-font-smoothing: antialiased;
-  font-smoothing: antialiased;
-}
-
-body > header {
-  padding-top: 22px;
-  margin-bottom: -5px;
-}
-
-h1 {
-  /*  position: absolute;
-  top: -120px;*/
-  width: 100%;
-  font-size: 70px;
-  font-weight: bold;
-  text-align: center;
-  color: #b3b3b3;
-  color: rgba(255, 255, 255, 0.3);
-  text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-  -webkit-text-rendering: optimizeLegibility;
-  -moz-text-rendering: optimizeLegibility;
-  -ms-text-rendering: optimizeLegibility;
-  -o-text-rendering: optimizeLegibility;
-  text-rendering: optimizeLegibility;
-}
-
-#info {
-  margin: 65px auto 0;
-  color: #a6a6a6;
-  font-size: 12px;
-  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
-  text-align: center;
-}
-
-#info a {
-  color: inherit;
-}
-
-.hidden{
-  display:none;
-}
-
-hr {
-  margin: 20px 0;
-  border: 0;
-  border-top: 1px dashed #C5C5C5;
-  border-bottom: 1px dashed #F7F7F7;
-}
-
-.learn a {
-  font-weight: normal;
-  text-decoration: none;
-  color: #b83f45;
-}
-
-.learn a:hover {
-  text-decoration: underline;
-  color: #787e7e;
-}
-
-.learn h3,
-.learn h4,
-.learn h5 {
-  margin: 10px 0;
-  font-weight: 500;
-  line-height: 1.2;
-  color: #000;
-}
-
-.learn h3 {
-  font-size: 24px;
-}
-
-.learn h4 {
-  font-size: 18px;
-}
-
-.learn h5 {
-  margin-bottom: 0;
-  font-size: 14px;
-}
-
-.learn ul {
-  padding: 0;
-  margin: 0 0 30px 25px;
-}
-
-.learn li {
-  line-height: 20px;
-}
-
-.learn p {
-  font-size: 15px;
-  font-weight: 300;
-  line-height: 1.3;
-  margin-top: 0;
-  margin-bottom: 0;
-}
-
-.quote {
-  border: none;
-  margin: 20px 0 60px 0;
-}
-
-.quote p {
-  font-style: italic;
-}
-
-.quote p:before {
-  content: '“';
-  font-size: 50px;
-  opacity: .15;
-  position: absolute;
-  top: -20px;
-  left: 3px;
-}
-
-.quote p:after {
-  content: '”';
-  font-size: 50px;
-  opacity: .15;
-  position: absolute;
-  bottom: -42px;
-  right: 3px;
-}
-
-.quote footer {
-  position: absolute;
-  bottom: -40px;
-  right: 0;
-}
-
-.quote footer img {
-  border-radius: 3px;
-}
-
-.quote footer a {
-  margin-left: 5px;
-  vertical-align: middle;
-}
-
-.speech-bubble {
-  position: relative;
-  padding: 10px;
-  background: rgba(0, 0, 0, .04);
-  border-radius: 5px;
-}
-
-.speech-bubble:after {
-  content: '';
-  position: absolute;
-  top: 100%;
-  right: 30px;
-  border: 13px solid transparent;
-  border-top-color: rgba(0, 0, 0, .04);
-}
-
-/**body*/.learn-bar > .learn {
-  position: absolute;
-  width: 272px;
-  top: 8px;
-  left: -300px;
-  padding: 10px;
-  border-radius: 5px;
-  background-color: rgba(255, 255, 255, .6);
-  transition-property: left;
-  transition-duration: 500ms;
-}
-
-
-/* IE doesn't support the hidden attribute */
-[hidden] {
-  display: none;
-}
-
-@media (min-width: 899px) {
-  /**body*/.learn-bar {
-    width: auto;
-    margin: 0 0 0 300px;
-  }
-  /**body*/.learn-bar > .learn {
-    left: 8px;
-  }
-  /**body*/.learn-bar #todoapp {
-    width: 550px;
-    margin: 130px auto 40px auto;
-  }
-}
\ No newline at end of file
diff --git a/samples/third_party/todomvc_performance/web/app/bg.png b/samples/third_party/todomvc_performance/web/app/bg.png
deleted file mode 100644
index b2a7600..0000000
--- a/samples/third_party/todomvc_performance/web/app/bg.png
+++ /dev/null
Binary files differ
diff --git a/samples/third_party/todomvc_performance/web/elements/td_input.dart b/samples/third_party/todomvc_performance/web/elements/td_input.dart
deleted file mode 100644
index fc3211f..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_input.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-library todomvc.web.elements.td_input;
-
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-
-@CustomTag('td-input')
-class TodoInput extends InputElement with Polymer, Observable {
-  factory TodoInput() => new Element.tag('input', 'td-input');
-  TodoInput.created() : super.created() {
-    polymerCreated();
-  }
-
-  keypressAction(e) {
-    // Listen for enter on keypress but esc on keyup, because
-    // IE doesn't fire keyup for enter.
-    if (e.keyCode == KeyCode.ENTER) {
-      e.preventDefault();
-      fire('td-input-commit');
-    }
-  }
-
-  keyupAction(e) {
-    if (e.keyCode == KeyCode.ESC) {
-      fire('td-input-cancel');
-    }
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_input.html b/samples/third_party/todomvc_performance/web/elements/td_input.html
deleted file mode 100644
index 3190dc8..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_input.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<polymer-element name="td-input" extends="input"
-    on-keyup="{{keyupAction}}" on-keypress="{{keypressAction}}">
-  <script type="application/dart" src="td_input.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/elements/td_item.css b/samples/third_party/todomvc_performance/web/elements/td_item.css
deleted file mode 100644
index 61feb6c..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_item.css
+++ /dev/null
@@ -1,161 +0,0 @@
-/* base.css overrides */
-@host {
-  .editing {
-    border-bottom: none;
-    padding: 0;
-  }
-}
-
-button {
-  margin: 0;
-  padding: 0;
-  border: 0;
-  background-color: transparent;
-  background-image: none;
-  font-size: 100%;
-  vertical-align: baseline;
-  font-family: inherit;
-  color: inherit;
-  -webkit-appearance: none;
-  /*-moz-appearance: none;*/
-  -ms-appearance: none;
-  -o-appearance: none;
-  appearance: none;
-}
-
-
-.edit {
-  position: relative;
-  margin: 0;
-  width: 100%;
-  font-size: 24px;
-  font-family: inherit;
-  line-height: 1.4em;
-  border: 0;
-  outline: none;
-  color: inherit;
-  padding: 6px;
-  border: 1px solid #999;
-  box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  -ms-box-sizing: border-box;
-  -o-box-sizing: border-box;
-  box-sizing: border-box;
-  -webkit-font-smoothing: antialiased;
-  -moz-font-smoothing: antialiased;
-  -ms-font-smoothing: antialiased;
-  -o-font-smoothing: antialiased;
-  font-smoothing: antialiased;
-}
-
-.edit {
-  width: 506px;
-  padding: 13px 17px 12px 17px;
-  margin: 0 0 0 43px;
-}
-
-.toggle {
-  text-align: center;
-  width: 40px;
-  /* auto, since non-WebKit browsers doesn't support input styling */
-  height: auto;
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  margin: auto 0;
-  border: none; /* Mobile Safari */
-  -webkit-appearance: none;
-  /*-moz-appearance: none;*/
-  -ms-appearance: none;
-  -o-appearance: none;
-  appearance: none;
-}
-
-.toggle:after {
-  content: '✔';
-  line-height: 43px; /* 40 + a couple of pixels visual adjustment */
-  font-size: 20px;
-  color: #d9d9d9;
-  text-shadow: 0 -1px 0 #bfbfbf;
-}
-
-.toggle:checked:after {
-  color: #85ada7;
-  text-shadow: 0 1px 0 #669991;
-  bottom: 1px;
-  position: relative;
-}
-
-label {
-  word-break: break-word;
-  padding: 15px;
-  margin-left: 45px;
-  display: block;
-  line-height: 1.2;
-  -webkit-transition: color 0.4s;
-  -moz-transition: color 0.4s;
-  -ms-transition: color 0.4s;
-  -o-transition: color 0.4s;
-  transition: color 0.4s;
-}
-
-.completed label {
-  color: #a9a9a9;
-  text-decoration: line-through;
-}
-
-.destroy {
-  display: none;
-  position: absolute;
-  top: 0;
-  right: 10px;
-  bottom: 0;
-  width: 40px;
-  height: 40px;
-  margin: auto 0;
-  font-size: 22px;
-  color: #a88a8a;
-  -webkit-transition: all 0.2s;
-  -moz-transition: all 0.2s;
-  -ms-transition: all 0.2s;
-  -o-transition: all 0.2s;
-  transition: all 0.2s;
-}
-
-.destroy:hover {
-  text-shadow: 0 0 1px #000,
-         0 0 10px rgba(199, 107, 107, 0.8);
-  -webkit-transform: scale(1.3);
-  -moz-transform: scale(1.3);
-  -ms-transform: scale(1.3);
-  -o-transform: scale(1.3);
-  transform: scale(1.3);
-}
-
-.destroy:after {
-  content: '✖';
-}
-
-.view:hover .destroy {
-  display: block;
-}
-
-/*
-  Hack to remove background from Mobile Safari.
-  Can't use it globally since it destroys checkboxes in Firefox and Opera
-*/
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-  .toggle {
-    background: none;
-    /*
-      ShadowDOM Polyfill work around for webkit/blink bug
-      https://code.google.com/p/chromium/issues/detail?id=251510
-    */
-    background-color: transparent;
-  }
-
-  .toggle {
-    height: 40px;
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_item.dart b/samples/third_party/todomvc_performance/web/elements/td_item.dart
deleted file mode 100644
index 8970fe5..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_item.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-library todomvc.web.elements.td_item;
-
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-import 'td_model.dart';
-
-@CustomTag('td-item')
-class TodoItem extends LIElement with Polymer, Observable {
-  @published bool editing = false;
-  @published Todo item;
-
-  factory TodoItem() => new Element.tag('li', 'td-item');
-  TodoItem.created() : super.created() { polymerCreated(); }
-
-  editAction() {
-    editing = true;
-    // schedule focus for the end of microtask, when the input will be visible
-    async((_) => $['edit'].focus());
-  }
-
-  commitAction() {
-    if (editing) {
-      editing = false;
-      item.title = item.title.trim();
-      if (item.title == '') {
-        destroyAction();
-      }
-      fire('td-item-changed');
-    }
-  }
-
-  cancelAction() {
-    editing = false;
-  }
-
-  itemChangeAction() {
-    // TODO(jmesserly): asyncFire is needed because "click" fires before
-    // "item.checked" is updated on Firefox. Need to check Polymer.js.
-    asyncFire('td-item-changed');
-  }
-
-  destroyAction() {
-    fire('td-destroy-item', detail: item);
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_item.html b/samples/third_party/todomvc_performance/web/elements/td_item.html
deleted file mode 100644
index 8d5dd0d..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_item.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<link rel="import" href="td_input.html">
-<polymer-element name="td-item" extends="li" on-blur="{{commitAction}}">
-  <template>
-    <link rel="stylesheet" href="td_item.css">
-    <div class="view {{ {'completed': item.completed, 'editing': editing} }}"
-        hidden?="{{editing}}" on-dblclick="{{editAction}}">
-      <input type="checkbox" class="toggle" checked="{{item.completed}}"
-          on-click="{{itemChangeAction}}">
-      <label>{{item.title}}</label>
-      <button class="destroy" on-click="{{destroyAction}}"></button>
-    </div>
-    <input is="td-input" id="edit" class="edit" value="{{item.title}}"
-        hidden?="{{!editing}}" on-td-input-commit="{{commitAction}}"
-        on-td-input-cancel="{{cancelAction}}">
-  </template>
-  <script type="application/dart" src="td_item.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/elements/td_model.dart b/samples/third_party/todomvc_performance/web/elements/td_model.dart
deleted file mode 100644
index 40fe756..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_model.dart
+++ /dev/null
@@ -1,101 +0,0 @@
-library todomvc.web.elements.td_model;
-
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-import '../lib-elements/polymer_localstorage.dart';
-
-class Todo extends Observable {
-  @observable String title;
-  @observable bool completed = false;
-
-  Todo(this.title);
-
-  Todo.fromJson(Map json)
-      : title = json['title'], completed = json['completed'];
-
-  Map toJson() => { 'title': title, 'completed': completed };
-
-  String toString() => "$title (${completed ? '' : 'not '}done)";
-}
-
-@CustomTag('td-model')
-class TodoModel extends PolymerElement {
-  @published ObservableList<Todo> items;
-  @published Iterable<Todo> filtered;
-  @published String storageId;
-
-  @observable int completedCount = 0;
-  @observable int activeCount = 0;
-  @observable bool allCompleted = false;
-  @observable PolymerLocalStorage storage;
-  @observable String filter;
-  @observable String activeItemWord;
-
-  final filters = {
-    'active': (item) => !item.completed,
-    'completed': (item) => item.completed
-  };
-
-  factory TodoModel() => new Element.tag('td-model');
-  TodoModel.created() : super.created();
-
-  void ready() {
-    async((_) {
-      if (items == null) items = new ObservableList<Todo>();
-    });
-  }
-
-  void filterChanged() {
-    filterItems();
-  }
-
-  void itemsChanged() {
-    completedCount = items.where(filters['completed']).length;
-    activeCount = items.length - completedCount;
-    allCompleted = completedCount > 0 && activeCount == 0;
-
-    filterItems();
-    if (storage != null) {
-      storage.value = items;
-      storage.save();
-    }
-
-    // TODO(jmesserly): polymer_expressions lacks ternary operator.
-    activeItemWord = activeCount == 1 ? 'item' : 'items';
-  }
-
-  void storageIdChanged() {
-    storage = document.querySelector('#$storageId');
-    if (storage != null && storage.value != null) {
-      items = toObservable(storage.value.map((i) => new Todo.fromJson(i)));
-    }
-  }
-
-  void filterItems() {
-    var fn = filters[filter];
-    filtered = fn != null ? items.where(fn) : items;
-  }
-
-  void newItem(String title) {
-    title = title.trim();
-    if (title != '') {
-      items.add(new Todo(title));
-      itemsChanged();
-    }
-  }
-
-  void destroyItem(Todo item) {
-    if (items.remove(item)) itemsChanged();
-  }
-
-  void clearItems() {
-    items.removeWhere(filters['completed']);
-  }
-
-  void setItemsCompleted(bool completed) {
-    for (var item in items) {
-      item.completed = completed;
-    }
-    itemsChanged();
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_model.html b/samples/third_party/todomvc_performance/web/elements/td_model.html
deleted file mode 100644
index 7c83535..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_model.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<polymer-element name="td-model">
-  <script type="application/dart" src="td_model.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/elements/td_todos.css b/samples/third_party/todomvc_performance/web/elements/td_todos.css
deleted file mode 100644
index 4806384..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_todos.css
+++ /dev/null
@@ -1,267 +0,0 @@
-/* base.css overrides */
-
-@host {
-  * {
-    display: block;
-    position: relative;
-  }
-}
-
-button {
-  margin: 0;
-  padding: 0;
-  border: 0;
-  background: none;
-  font-size: 100%;
-  vertical-align: baseline;
-  font-family: inherit;
-  color: inherit;
-  -webkit-appearance: none;
-  /*-moz-appearance: none;*/
-  -ms-appearance: none;
-  -o-appearance: none;
-  appearance: none;
-}
-
-input::-webkit-input-placeholder {
-  font-style: italic;
-}
-
-input::-moz-placeholder {
-  font-style: italic;
-  color: #a9a9a9;
-}
-
-input:-ms-input-placeholder, #new-todo:-ms-input-placeholder {
-  font-style: italic;
-  color: #a9a9a9;
-}
-
-#todoapp {
-  background: #fff;
-  background: rgba(255, 255, 255, 0.9);
-  /*margin: 130px 0 40px 0;*/
-  margin: 0 0 40px 0;
-  border: 1px solid #ccc;
-  position: relative;
-  border-top-left-radius: 2px;
-  border-top-right-radius: 2px;
-  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
-        0 25px 50px 0 rgba(0, 0, 0, 0.15);
-}
-
-#todoapp:before {
-  content: '';
-  border-left: 1px solid #f5d6d6;
-  border-right: 1px solid #f5d6d6;
-  width: 2px;
-  position: absolute;
-  top: 0;
-  left: 40px;
-  height: 100%;
-}
-
-#header {
-  padding-top: 15px;
-  border-radius: inherit;
-}
-
-#header:before {
-  content: '';
-  position: absolute;
-  top: 0;
-  right: 0;
-  left: 0;
-  height: 15px;
-  z-index: 2;
-  border-bottom: 1px solid #6c615c;
-  background: #8d7d77;
-  background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
-  background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
-  border-top-left-radius: 1px;
-  border-top-right-radius: 1px;
-}
-
-#new-todo,
-.edit {
-  position: relative;
-  margin: 0;
-  width: 100%;
-  font-size: 24px;
-  font-family: inherit;
-  line-height: 1.4em;
-  border: 0;
-  outline: none;
-  color: inherit;
-  padding: 6px;
-  border: 1px solid #999;
-  box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  -ms-box-sizing: border-box;
-  -o-box-sizing: border-box;
-  box-sizing: border-box;
-  -webkit-font-smoothing: antialiased;
-  -moz-font-smoothing: antialiased;
-  -ms-font-smoothing: antialiased;
-  -o-font-smoothing: antialiased;
-  /* font-smoothing: antialiased; */
-}
-
-#new-todo {
-  padding: 16px 16px 16px 60px;
-  border: none;
-  background: rgba(0, 0, 0, 0.02);
-  z-index: 2;
-  box-shadow: none;
-}
-
-#main {
-  position: relative;
-  z-index: 2;
-  border-top: 1px dotted #adadad;
-}
-
-label[for='toggle-all'] {
-  display: none;
-}
-
-#toggle-all {
-  position: absolute;
-  top: -42px;
-  left: -4px;
-  width: 40px;
-  text-align: center;
-  border: none; /* Mobile Safari */
-}
-
-#toggle-all:before {
-  content: '»';
-  font-size: 28px;
-  color: #d9d9d9;
-  padding: 0 25px 7px;
-}
-
-#toggle-all:checked:before {
-  color: #737373;
-}
-
-#todo-list {
-  margin: 0;
-  padding: 0;
-  list-style: none;
-}
-
-#todo-list li {
-  position: relative;
-  font-size: 24px;
-  border-bottom: 1px dotted #ccc;
-}
-
-#todo-list li:last-child {
-  border-bottom: none;
-}
-
-#todo-list li.editing {
-  border-bottom: none;
-  padding: 0;
-}
-
-#footer {
-  color: #777;
-  padding: 0 15px;
-  position: absolute;
-  right: 0;
-  bottom: -31px;
-  left: 0;
-  height: 20px;
-  z-index: 1;
-  text-align: center;
-}
-
-#footer:before {
-  content: '';
-  position: absolute;
-  right: 0;
-  bottom: 31px;
-  left: 0;
-  height: 50px;
-  z-index: -1;
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
-        0 6px 0 -3px rgba(255, 255, 255, 0.8),
-        0 7px 1px -3px rgba(0, 0, 0, 0.3),
-        0 43px 0 -6px rgba(255, 255, 255, 0.8),
-        0 44px 2px -6px rgba(0, 0, 0, 0.2);
-}
-
-#todo-count {
-  float: left;
-  text-align: left;
-}
-
-#filters {
-  margin: 0;
-  padding: 0;
-  list-style: none;
-  position: absolute;
-  right: 0;
-  left: 0;
-}
-
-#filters li {
-  display: inline;
-}
-
-#filters li a {
-  color: #83756f;
-  margin: 2px;
-  text-decoration: none;
-}
-
-#filters li.polymer-selected a {
-  font-weight: bold;
-}
-
-#clear-completed {
-  float: right;
-  position: relative;
-  line-height: 20px;
-  text-decoration: none;
-  background: rgba(0, 0, 0, 0.1);
-  font-size: 11px;
-  padding: 0 10px;
-  border-radius: 3px;
-  box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
-}
-
-#clear-completed:hover {
-  background: rgba(0, 0, 0, 0.15);
-  box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
-}
-
-@media screen and (-webkit-min-device-pixel-ratio:0) {
-  #toggle-all {
-    background: none;
-    /*
-      ShadowDOM Polyfill work around for webkit/blink bug
-      https://code.google.com/p/chromium/issues/detail?id=251510
-    */
-    background-color: transparent;
-  }
-
-  #toggle-all {
-    top: -56px;
-    left: -15px;
-    width: 65px;
-    height: 41px;
-    -webkit-transform: rotate(90deg);
-    transform: rotate(90deg);
-    -webkit-appearance: none;
-    appearance: none;
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_todos.dart b/samples/third_party/todomvc_performance/web/elements/td_todos.dart
deleted file mode 100644
index f0ac238..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_todos.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-library todomvc.web.elements.td_todos;
-
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-import 'td_input.dart';
-import 'td_model.dart';
-
-@CustomTag('td-todos')
-class TodoList extends PolymerElement {
-  @published String modelId;
-
-  @observable TodoModel model;
-  @observable String activeRoute;
-
-  factory TodoList() => new Element.tag('td-todos');
-  TodoList.created() : super.created();
-
-  TodoInput get _newTodo => $['new-todo'];
-
-  void modelIdChanged() {
-    model = document.querySelector('#$modelId');
-  }
-
-  void routeAction(e, route) {
-    if (model != null) model.filter = route;
-
-    // TODO(jmesserly): polymer_expressions lacks boolean conversions.
-    activeRoute = (route != null && route != '') ? route : 'all';
-  }
-
-  void addTodoAction() {
-    model.newItem(_newTodo.value);
-    // when polyfilling Object.observe, make sure we update immediately
-    Observable.dirtyCheck();
-    _newTodo.value = '';
-  }
-
-  void cancelAddTodoAction() {
-    _newTodo.value = '';
-  }
-
-  void itemChangedAction() {
-    if (model != null) model.itemsChanged();
-  }
-
-  void destroyItemAction(e, detail) {
-    model.destroyItem(detail);
-  }
-
-  void toggleAllCompletedAction(e, detail, sender) {
-    model.setItemsCompleted(sender.checked);
-  }
-
-  void clearCompletedAction() {
-    model.clearItems();
-  }
-
-  // TODO(jmesserly): workaround for HTML Imports not setting correct baseURI
-  String get baseUri =>
-      declaration.element.ownerDocument == document ? '../' : '';
-}
diff --git a/samples/third_party/todomvc_performance/web/elements/td_todos.html b/samples/third_party/todomvc_performance/web/elements/td_todos.html
deleted file mode 100644
index 4d84f60..0000000
--- a/samples/third_party/todomvc_performance/web/elements/td_todos.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<link rel="import" href="../lib-elements/polymer-selector.html">
-<link rel="import" href="../lib-elements/simple_router.html">
-<link rel="import" href="td_input.html">
-<link rel="import" href="td_item.html">
-
-<polymer-element name="td-todos">
-  <template>
-    <link rel="stylesheet" href="td_todos.css">
-    <simple-router on-route="{{routeAction}}"></simple-router>
-    <section id="todoapp">
-      <header id="header">
-        <input is="td-input" id="new-todo" placeholder="What needs to be done?"
-            autofocus on-td-input-commit="{{addTodoAction}}"
-            on-td-input-cancel="{{cancelAddTodoAction}}">
-      </header>
-      <section id="main" hidden?="{{model.items.length == 0}}">
-        <input id="toggle-all" type="checkbox"
-            on-change="{{toggleAllCompletedAction}}"
-            checked="{{model.allCompleted}}">
-        <label for="toggle-all">Mark all as complete</label>
-        <ul id="todo-list" on-td-item-changed="{{itemChangedAction}}"
-            on-td-destroy-item="{{destroyItemAction}}">
-          <template repeat="{{model.filtered}}">
-            <li is="td-item" item="{{}}"></li>
-          </template>
-        </ul>
-      </section>
-      <footer id="footer" hidden?="{{model.items.length == 0}}">
-        <span id="todo-count"><strong>{{model.activeCount}}</strong>
-            {{model.activeItemWord}} left</span>
-        <polymer-selector id="filters" selected="{{activeRoute}}">
-          <li label="all">
-            <a href="{{baseUri}}#/">All</a>
-          </li>
-          <li label="active">
-            <a href="{{baseUri}}#/active">Active</a>
-          </li>
-          <li label="completed">
-            <a href="{{baseUri}}#/completed">Completed</a>
-          </li>
-        </polymer-selector>
-        <button hidden?="{{model.completedCount == 0}}" id="clear-completed"
-            on-click="{{clearCompletedAction}}">Clear completed
-            ({{model.completedCount}})</button>
-      </footer>
-    </section>
-  </template>
-
-  <script type="application/dart" src="td_todos.dart"></script>
-
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/polymer-selection.html b/samples/third_party/todomvc_performance/web/lib-elements/polymer-selection.html
deleted file mode 100644
index 609ced3..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/polymer-selection.html
+++ /dev/null
@@ -1,151 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
--->
-<!--
-/**
- * The polymer-selection element is used to manage selection state. It has no
- * visual appearance and is typically used in conjuneciton with another element.
- * For example, <a href="polymer-selector.html">polymer-selector</a>
- * use a polymer-selection to manage selection.
- *
- * To mark an item as selected, call the select(item) method on
- * polymer-selection. Notice that the item itself is an argument to this method.
- * The polymer-selection element manages selection state for any given set of
- * items. When an item is selected, the `polymer-select` event is fired.
- * The attribute "multi" indicates if multiple items can be selected at once.
- *
- * Example:
- *
- *     <polymer-element name="selection-example">
- *        <template>
- *          <style>
- *            ::-webkit-distributed(> .selected) {
- *              font-weight: bold;
- *              font-style: italic;
- *            }
- *          </style>
- *          <ul on-tap="{{itemTapAction}}">
- *            <content></content>
- *          </ul>
- *          <polymer-selection id="selection" multi on-polymer-select="{{selectAction}}"></polymer-selection>
- *        </template>
- *        <script>
- *          Polymer('selection-example', {
- *            itemTapAction: function(e) {
- *              this.$.selection.select(e.target);
- *            },
- *            selectAction: function(e, detail) {
- *              detail.item.classList.toggle('selected', detail.isSelected);
- *            }
- *          });
- *        </script>
- *     </polymer-element>
- *
- *     <selection-example>
- *       <li>Red</li>
- *       <li>Green</li>
- *       <li>Blue</li>
- *     </selection-example>
- *
- * @class polymer-selection
- */
- /**
- * Fired when an item's selection state is changed. This event is fired both
- * when an item is selected or deselected. The `isSelected` detail property
- * contains the selection state.
- *
- * @event polymer-select
- * @param {Object} detail
- *   @param {boolean} detail.isSelected true for selection and false for deselection
- *   @param {Object} detail.item the item element
- */
--->
-<polymer-element name="polymer-selection" attributes="multi">
-  <template>
-    <style>
-      :host {
-        display: none !important;
-      }
-    </style>
-  </template>
-  <script>
-    Polymer('polymer-selection', {
-      /**
-       * If true, multiple selections are allowed.
-       *
-       * @attribute multi
-       * @type boolean
-       * @default false
-       */
-      multi: false,
-      ready: function() {
-        this.clear();
-      },
-      clear: function() {
-        this.selection = [];
-      },
-      /**
-       * Retrieves the selected item(s).
-       * @method getSelection
-       * @returns Returns the selected item(s). If the multi property is true,
-       * getSelection will return an array, otherwise it will return
-       * the selected item or undefined if there is no selection.
-      */
-      getSelection: function() {
-        return this.multi ? this.selection : this.selection[0];
-      },
-      /**
-       * Indicates if a given item is selected.
-       * @method isSelected
-       * @param {any} item The item whose selection state should be checked.
-       * @returns Returns true if `item` is selected.
-      */
-      isSelected: function(item) {
-        return this.selection.indexOf(item) >= 0;
-      },
-      setItemSelected: function(item, isSelected) {
-        if (item !== undefined && item !== null) {
-          if (isSelected) {
-            this.selection.push(item);
-          } else {
-            var i = this.selection.indexOf(item);
-            if (i >= 0) {
-              this.selection.splice(i, 1);
-            }
-          }
-          this.fire("polymer-select", {isSelected: isSelected, item: item});
-        }
-      },
-      /**
-       * Set the selection state for a given `item`. If the multi property
-       * is true, then the selected state of `item` will be toggled; otherwise
-       * the `item` will be selected.
-       * @method select
-       * @param {any} item: The item to select.
-      */
-      select: function(item) {
-        if (this.multi) {
-          this.toggle(item);
-        } else if (this.getSelection() !== item) {
-          this.setItemSelected(this.getSelection(), false);
-          this.setItemSelected(item, true);
-        }
-      },
-      /**
-       * Toggles the selection state for `item`.
-       * @method toggle
-       * @param {any} item: The item to toggle.
-      */
-      toggle: function(item) {
-        this.setItemSelected(item, !this.isSelected(item));
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/polymer-selector.html b/samples/third_party/todomvc_performance/web/lib-elements/polymer-selector.html
deleted file mode 100644
index 9fd5074..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/polymer-selector.html
+++ /dev/null
@@ -1,353 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * @module Polymer Elements
- */
-/**
- * polymer-selector is used to manage a list of elements that can be selected.
- * The attribute "selected" indicates which item element is being selected.
- * The attribute "multi" indicates if multiple items can be selected at once.
- * Tapping on the item element would fire "polymer-activate" event. Use
- * "polymer-select" event to listen for selection changes.
- *
- * Example:
- *
- *     <polymer-selector selected="0">
- *       <div>Item 1</div>
- *       <div>Item 2</div>
- *       <div>Item 3</div>
- *     </polymer-selector>
- *
- * polymer-selector is not styled.  So one needs to use "polymer-selected" CSS
- * class to style the selected element.
- *
- *     <style>
- *       .item.polymer-selected {
- *         background: #eee;
- *       }
- *     </style>
- *     ...
- *     <polymer-selector>
- *       <div class="item">Item 1</div>
- *       <div class="item">Item 2</div>
- *       <div class="item">Item 3</div>
- *     </polymer-selector>
- *
- * @class polymer-selector
- */
-/**
- * Fired when an item's selection state is changed. This event is fired both
- * when an item is selected or deselected. The `isSelected` detail property
- * contains the selection state.
- *
- * @event polymer-select
- * @param {Object} detail
- *   @param {boolean} detail.isSelected true for selection and false for deselection
- *   @param {Object} detail.item the item element
- */
-/**
- * Fired when an item element is tapped.
- *
- * @event polymer-activate
- * @param {Object} detail
- *   @param {Object} detail.item the item element
- */
--->
-<link rel="import" href="polymer-selection.html">
-
-<polymer-element name="polymer-selector"
-    attributes="selected multi valueattr selectedClass selectedProperty selectedItem selectedModel selectedIndex notap target itemsSelector activateEvent">
-  <template>
-    <polymer-selection id="selection" multi="{{multi}}" on-polymer-select="{{selectionSelect}}"></polymer-selection>
-    <content id="items" select="*"></content>
-  </template>
-  <script>
-    Polymer('polymer-selector', {
-      /**
-       * Gets or sets the selected element.  Default to use the index
-       * of the item element.
-       *
-       * If you want a specific attribute value of the element to be
-       * used instead of index, set "valueattr" to that attribute name.
-       *
-       * Example:
-       *
-       *     <polymer-selector valueattr="label" selected="foo">
-       *       <div label="foo"></div>
-       *       <div label="bar"></div>
-       *       <div label="zot"></div>
-       *     </polymer-selector>
-       *
-       * In multi-selection this should be an array of values.
-       *
-       * Example:
-       *
-       *     <polymer-selector id="selector" valueattr="label" multi>
-       *       <div label="foo"></div>
-       *       <div label="bar"></div>
-       *       <div label="zot"></div>
-       *     </polymer-selector>
-       *
-       *     this.$.selector.selected = ['foo', 'zot'];
-       *
-       * @attribute selected
-       * @type Object
-       * @default null
-       */
-      selected: null,
-      /**
-       * If true, multiple selections are allowed.
-       *
-       * @attribute multi
-       * @type boolean
-       * @default false
-       */
-      multi: false,
-      /**
-       * Specifies the attribute to be used for "selected" attribute.
-       *
-       * @attribute valueattr
-       * @type string
-       * @default 'name'
-       */
-      valueattr: 'name',
-      /**
-       * Specifies the CSS class to be used to add to the selected element.
-       *
-       * @attribute selectedClass
-       * @type string
-       * @default 'polymer-selected'
-       */
-      selectedClass: 'polymer-selected',
-      /**
-       * Specifies the property to be used to set on the selected element
-       * to indicate its active state.
-       *
-       * @attribute selectedProperty
-       * @type string
-       * @default 'active'
-       */
-      selectedProperty: 'active',
-      /**
-       * Returns the currently selected element. In multi-selection this returns
-       * an array of selected elements.
-       *
-       * @attribute selectedItem
-       * @type Object
-       * @default null
-       */
-      selectedItem: null,
-      /**
-       * In single selection, this returns the model associated with the
-       * selected element.
-       *
-       * @attribute selectedModel
-       * @type Object
-       * @default null
-       */
-      selectedModel: null,
-      /**
-       * In single selection, this returns the selected index.
-       *
-       * @attribute selectedIndex
-       * @type number
-       * @default -1
-       */
-      selectedIndex: -1,
-      /**
-       * The target element that contains items.  If this is not set
-       * polymer-selector is the container.
-       *
-       * @attribute target
-       * @type Object
-       * @default null
-       */
-      target: null,
-      /**
-       * This can be used to query nodes from the target node to be used for
-       * selection items.  Note this only works if the 'target' property is set.
-       *
-       * Example:
-       *
-       *     <polymer-selector target="{{$.myForm}}" itemsSelector="input[type=radio]"></polymer-selector>
-       *     <form id="myForm">
-       *       <label><input type="radio" name="color" value="red"> Red</label> <br>
-       *       <label><input type="radio" name="color" value="green"> Green</label> <br>
-       *       <label><input type="radio" name="color" value="blue"> Blue</label> <br>
-       *       <p>color = {{color}}</p>
-       *     </form>
-       *
-       * @attribute itemSelector
-       * @type string
-       * @default ''
-       */
-      itemsSelector: '',
-      /**
-       * The event that would be fired from the item element to indicate
-       * it is being selected.
-       *
-       * @attribute activateEvent
-       * @type string
-       * @default 'tap'
-       */
-      activateEvent: 'tap',
-      notap: false,
-      ready: function() {
-        this.activateListener = this.activateHandler.bind(this);
-        this.observer = new MutationObserver(this.updateSelected.bind(this));
-        if (!this.target) {
-          this.target = this;
-        }
-      },
-      get items() {
-        var nodes = this.target !== this ? (this.itemsSelector ?
-            this.target.querySelectorAll(this.itemsSelector) :
-                this.target.children) : this.$.items.getDistributedNodes();
-        return Array.prototype.filter.call(nodes || [], function(n) {
-          return n && n.localName !== 'template';
-        });
-      },
-      targetChanged: function(old) {
-        if (old) {
-          this.removeListener(old);
-          this.observer.disconnect();
-        }
-        if (this.target) {
-          this.addListener(this.target);
-          this.observer.observe(this.target, {childList: true});
-        }
-      },
-      addListener: function(node) {
-        node.addEventListener(this.activateEvent, this.activateListener);
-      },
-      removeListener: function(node) {
-        node.removeEventListener(this.activateEvent, this.activateListener);
-      },
-      get selection() {
-        return this.$.selection.getSelection();
-      },
-      selectedChanged: function() {
-        this.updateSelected();
-      },
-      updateSelected: function() {
-        this.validateSelected();
-        if (this.multi) {
-          this.clearSelection();
-          this.selected && this.selected.forEach(function(s) {
-            this.valueToSelection(s);
-          }, this);
-        } else {
-          this.valueToSelection(this.selected);
-        }
-      },
-      validateSelected: function() {
-        // convert to an array for multi-selection
-        if (this.multi && !Array.isArray(this.selected) &&
-            this.selected !== null && this.selected !== undefined) {
-          this.selected = [this.selected];
-        }
-      },
-      clearSelection: function() {
-        if (this.multi) {
-          this.selection.slice().forEach(function(s) {
-            this.$.selection.setItemSelected(s, false);
-          }, this);
-        } else {
-          this.$.selection.setItemSelected(this.selection, false);
-        }
-        this.selectedItem = null;
-        this.$.selection.clear();
-      },
-      valueToSelection: function(value) {
-        var item = (value === null || value === undefined) ?
-            null : this.items[this.valueToIndex(value)];
-        this.$.selection.select(item);
-      },
-      updateSelectedItem: function() {
-        this.selectedItem = this.selection;
-      },
-      selectedItemChanged: function() {
-        if (this.selectedItem) {
-          var t = this.selectedItem.templateInstance;
-          this.selectedModel = t ? t.model : undefined;
-        } else {
-          this.selectedModel = null;
-        }
-        this.selectedIndex = this.selectedItem ?
-            parseInt(this.valueToIndex(this.selected)) : -1;
-      },
-      valueToIndex: function(value) {
-        // find an item with value == value and return it's index
-        for (var i=0, items=this.items, c; (c=items[i]); i++) {
-          if (this.valueForNode(c) == value) {
-            return i;
-          }
-        }
-        // if no item found, the value itself is probably the index
-        return value;
-      },
-      valueForNode: function(node) {
-        return node[this.valueattr] || node.getAttribute(this.valueattr);
-      },
-      // events fired from <polymer-selection> object
-      selectionSelect: function(e, detail) {
-        this.updateSelectedItem();
-        if (detail.item) {
-          this.applySelection(detail.item, detail.isSelected)
-        }
-      },
-      applySelection: function(item, isSelected) {
-        if (this.selectedClass) {
-          item.classList.toggle(this.selectedClass, isSelected);
-        }
-        if (this.selectedProperty) {
-          item[this.selectedProperty] = isSelected;
-        }
-      },
-      // event fired from host
-      activateHandler: function(e) {
-        if (!this.notap) {
-          var i = this.findDistributedTarget(e.target, this.items);
-          if (i >= 0) {
-            var item = this.items[i];
-            var s = this.valueForNode(item) || i;
-            if (this.multi) {
-              if (this.selected) {
-                this.addRemoveSelected(s);
-              } else {
-                this.selected = [s];
-              }
-            } else {
-              this.selected = s;
-            }
-            this.asyncFire('polymer-activate', {item: item});
-          }
-        }
-      },
-      addRemoveSelected: function(value) {
-        var i = this.selected.indexOf(value);
-        if (i >= 0) {
-          this.selected.splice(i, 1);
-        } else {
-          this.selected.push(value);
-        }
-        this.valueToSelection(value);
-      },
-      findDistributedTarget: function(target, nodes) {
-        // find first ancestor of target (including itself) that
-        // is in nodes, if any
-        while (target && target != this) {
-          var i = Array.prototype.indexOf.call(nodes, target);
-          if (i >= 0) {
-            return i;
-          }
-          target = target.parentNode;
-        }
-      }
-    });
-  </script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.dart b/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.dart
deleted file mode 100644
index 218aac4..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2013 The Polymer Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-library todomvc.web.lib_elements.polymer_localstorage;
-
-import 'dart:convert' show JSON;
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-
-// TODO(jmesserly): replace with interop to <polymer-localstorage>.
-@CustomTag('polymer-localstorage')
-class PolymerLocalStorage extends PolymerElement {
-  @published String name;
-  @published var value;
-  @published bool useRaw = false;
-
-  factory PolymerLocalStorage() => new Element.tag('polymer-localstorage');
-  PolymerLocalStorage.created() : super.created();
-
-  void ready() {
-    load();
-  }
-
-  void valueChanged() {
-    save();
-  }
-
-  void load() {
-    var s = window.localStorage[name];
-    if (s != null && !useRaw) {
-      value = JSON.decode(s);
-    } else {
-      value = s;
-    }
-  }
-
-  void save() {
-    window.localStorage[name] = useRaw ? value : JSON.encode(value);
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.html b/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.html
deleted file mode 100644
index 804d50a..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/polymer_localstorage.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<!--
-/**
- * polymer-localstorage provides access to localStorage.
- *
- * Example:
- *
- *     <polymer-localstorage name="my-app-storage" value="{{value}}">
- *     </polymer-localstorage>
- */
--->
-<polymer-element name="polymer-localstorage">
-  <template>
-    <style>
-      @host {
-        * {
-          display: none;
-        }
-      }
-    </style>
-  </template>
-  <script type="application/dart" src="polymer_localstorage.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/simple_router.dart b/samples/third_party/todomvc_performance/web/lib-elements/simple_router.dart
deleted file mode 100644
index 1337a26..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/simple_router.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 The Polymer Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-library todomvc.web.lib_elements.simple_router;
-
-import 'dart:async';
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-
-// A very simple router for TodoMVC. Real app should use package:route, but it
-// does not currently support Shadow DOM.
-@CustomTag('simple-router')
-class SimpleRouter extends PolymerElement {
-  @published String route = '';
-
-  StreamSubscription _sub;
-
-  factory SimpleRouter() => new Element.tag('simple-router');
-  SimpleRouter.created() : super.created();
-
-  attached() {
-    super.attached();
-    _sub = windowLocation.changes.listen((_) {
-      var hash = window.location.hash;
-      if (hash.startsWith('#/')) hash = hash.substring(2);
-      // TODO(jmesserly): empty string is not triggering a call to TodoList
-      // routeChanged after deployment. Use 'all' as a workaround.
-      if (hash == '') hash = 'all';
-      route = hash;
-    });
-  }
-
-  detached() {
-    super.detached();
-    _sub.cancel();
-  }
-
-  routeChanged() {
-    fire('route', detail: route);
-  }
-}
diff --git a/samples/third_party/todomvc_performance/web/lib-elements/simple_router.html b/samples/third_party/todomvc_performance/web/lib-elements/simple_router.html
deleted file mode 100644
index 909036e..0000000
--- a/samples/third_party/todomvc_performance/web/lib-elements/simple_router.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!--
-Copyright 2013 The Polymer Authors. All rights reserved.
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file.
--->
-<polymer-element name="simple-router">
-  <script type="application/dart" src="simple_router.dart"></script>
-</polymer-element>
diff --git a/samples/third_party/todomvc_performance/web/performance.dart b/samples/third_party/todomvc_performance/web/performance.dart
deleted file mode 100644
index 93ce1dc..0000000
--- a/samples/third_party/todomvc_performance/web/performance.dart
+++ /dev/null
@@ -1,23 +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 todomvc_performance;
-
-import 'dart:async';
-import 'dart:html';
-import 'dart:js' as js;
-import 'package:polymer/polymer.dart';
-import 'package:web_components/polyfill.dart';
-import 'elements/td_model.dart';
-
-/**
- * This test determines how fast the TodoMVC app has loaded.
- */
-main() {
-  initPolymer();
-  Polymer.onReady.then((_) {
-    var endInitTime = new DateTime.now();
-    window.postMessage(endInitTime.millisecondsSinceEpoch, '*');
-  });
-}
diff --git a/samples/third_party/todomvc_performance/web/startup-performance.html b/samples/third_party/todomvc_performance/web/startup-performance.html
deleted file mode 100644
index 7aeb547..0000000
--- a/samples/third_party/todomvc_performance/web/startup-performance.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!doctype html>
-
-<!--
-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.
--->	
-
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-
-    <script type="application/javascript">
-
-      // TODO(efortuna): Revisit in a bit -- should we use
-      // performance.timing.navigationStart?
-      // navigationStart may be a bit noisy. Re-evaluate after we have more
-      // data. Note: performance.timing.domLoading would be nice, but
-      // performance.timing seems to be null on Safari 7.0.2. (Issue 17923)
-      var startTime = new Date().getTime();
-      function onReceive(e) {
-        // Listen for a timestamp signifying when app startup is complete.
-        var endTime = e.data;
-        var startupTime = endTime - startTime;
-        document.body.innerHTML = 'The startup time is ' + startupTime + 
-            ' milliseconds.';
-        reportPerformanceTestDone();
-      }
-      window.addEventListener('message', onReceive, true);
-    </script>
-
-    <script src="packages/browser_controller/perf_test_controller.js"></script>
-    <title> TodoMVC • Startup Performance </title>
-    <link rel="stylesheet" href="app/app.css">
-    <link rel="import" href="packages/polymer/polymer.html">
-    <link rel="import" href="lib-elements/polymer_localstorage.html">
-    <link rel="import" href="elements/td_model.html">
-    <link rel="import" href="elements/td_todos.html">
-  </head>
-  <body>
-    <header>
-      <h1>todos</h1>
-    </header>
-    <polymer-localstorage id="storage" name="todos-polymer">
-    </polymer-localstorage>
-    <td-model id="model" storageId="storage"></td-model>
-    <td-todos modelId="model"></td-todos>
-    <script type="application/dart" src="performance.dart"></script> 
-    <footer id="info">
-      <p>Double-click to edit a todo</p>
-      <p>Created by <a href="https://www.dartlang.org/polymer-dart/">
-          The Polymer.dart Authors</a></p>
-      <p>This example was built using a pre-alpha version of Polymer.dart.</p>
-      <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
-    </footer>
-  </body>
-</html>
diff --git a/sdk/bin/dart b/sdk/bin/dart
index 3de8c25..7dd1e92 100755
--- a/sdk/bin/dart
+++ b/sdk/bin/dart
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
@@ -29,7 +29,7 @@
 then
   DIRS=$( ls "$OUT_DIR" )
   # list of possible configurations in decreasing desirability
-  CONFIGS=("ReleaseIA32" "ReleaseX64" "DebugIA32" "DebugX64"
+  CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
     "ReleaseARM"    "ReleaseARM64"    "ReleaseARMV5TE"    "ReleaseMIPS"
     "DebugARM"      "DebugARM64"      "DebugARMV5TE"      "DebugMIPS")
   DART_CONFIGURATION="None"
diff --git a/sdk/bin/dart.bat b/sdk/bin/dart.bat
index eee051c..9458999 100644
--- a/sdk/bin/dart.bat
+++ b/sdk/bin/dart.bat
@@ -8,8 +8,8 @@
 REM Does the path have a trailing slash? If so, remove it.
 if %SCRIPTPATH:~-1%== set SCRIPTPATH=%SCRIPTPATH:~0,-1%
 
-REM DART_CONFIGURATION defaults to ReleaseIA32
-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32
+REM DART_CONFIGURATION defaults to ReleaseX64
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
 
 set arguments=%*
 
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index f448ba8..988a6fe 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
@@ -54,7 +54,7 @@
 
 if [ -z "$DART_CONFIGURATION" ];
 then
-  DART_CONFIGURATION="ReleaseIA32"
+  DART_CONFIGURATION="ReleaseX64"
 fi
 
 if [[ `uname` == 'Darwin' ]]; then
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index 9e765d9..19f9ddb 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -39,8 +39,8 @@
 
 set DART2JS=%DART_ROOT%\pkg\compiler\lib\src\dart2js.dart
 
-rem DART_CONFIGURATION defaults to ReleaseIA32
-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32
+rem DART_CONFIGURATION defaults to ReleaseX64
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
 
 set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
 
diff --git a/sdk/bin/dart2js_developer b/sdk/bin/dart2js_developer
index 948cb4a..226d1a9 100755
--- a/sdk/bin/dart2js_developer
+++ b/sdk/bin/dart2js_developer
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/sdk/bin/dart2js_sdk b/sdk/bin/dart2js_sdk
index 36b42a4..286859a 100755
--- a/sdk/bin/dart2js_sdk
+++ b/sdk/bin/dart2js_sdk
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/sdk/bin/dartanalyzer b/sdk/bin/dartanalyzer
index 9b4a2ab..8f2274c 100755
--- a/sdk/bin/dartanalyzer
+++ b/sdk/bin/dartanalyzer
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
@@ -43,7 +43,7 @@
 
 DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)"
 
-ANALYZER="$DART_ROOT/third_party/pkg/analyzer_cli/bin/analyzer.dart"
+ANALYZER="$DART_ROOT/pkg/analyzer_cli/bin/analyzer.dart"
 
 if [[ `uname` == 'Darwin' ]];
 then
@@ -56,7 +56,7 @@
 then
   DIRS=$( ls "$OUT_DIR" )
   # list of possible configurations in decreasing desirability
-  CONFIGS=("ReleaseIA32" "ReleaseX64" "DebugIA32" "DebugX64"
+  CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
     "ReleaseARM"    "ReleaseARM64"    "ReleaseARMV5TE"    "ReleaseMIPS"
     "DebugARM"      "DebugARM64"      "DebugARMV5TE"      "DebugMIPS")
   DART_CONFIGURATION="None"
diff --git a/sdk/bin/dartanalyzer.bat b/sdk/bin/dartanalyzer.bat
index ef041b0..a73427e 100644
--- a/sdk/bin/dartanalyzer.bat
+++ b/sdk/bin/dartanalyzer.bat
@@ -38,10 +38,10 @@
 rem Remove trailing backslash if there is one
 if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1%
 
-set ANALYZER=%DART_ROOT%\third_party\pkg\analyzer_cli\bin\analyzer.dart
+set ANALYZER=%DART_ROOT%\pkg\analyzer_cli\bin\analyzer.dart
 
-rem DART_CONFIGURATION defaults to ReleaseIA32
-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32
+rem DART_CONFIGURATION defaults to ReleaseX64
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
 
 set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
 
diff --git a/sdk/bin/dartanalyzer_developer b/sdk/bin/dartanalyzer_developer
index 0eeaf73..373dc67 100755
--- a/sdk/bin/dartanalyzer_developer
+++ b/sdk/bin/dartanalyzer_developer
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/sdk/bin/dartanalyzer_java b/sdk/bin/dartanalyzer_java
deleted file mode 100755
index d2839b5..0000000
--- a/sdk/bin/dartanalyzer_java
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# This file is used to execute the analyzer by running the jar file.
-# It is a simple wrapper enabling us to have simpler command lines in
-# the testing infrastructure.
-set -e
-
-FOUND_BATCH=0
-for ARG in "$@"
-do
-  case $ARG in
-    -batch|--batch)
-      FOUND_BATCH=1
-      ;;
-    *)
-      ;;
-  esac
-done
-
-function follow_links() {
-  file="$1"
-  while [ -h "$file" ]; do
-    # On Mac OS, readlink -f doesn't work.
-    file="$(readlink "$file")"
-  done
-  echo "$file"
-}
-
-# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
-PROG_NAME="$(follow_links "$BASH_SOURCE")"
-
-# Handle the case where dart-sdk/bin has been symlinked to.
-BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
-
-SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
-
-if [ -z "$DART_CONFIGURATION" ];
-then
-  DART_CONFIGURATION="ReleaseIA32"
-fi
-
-if [ `uname` == 'Darwin' ];
-then
-  JAR_DIR="$BIN_DIR"/../../xcodebuild/$DART_CONFIGURATION/dartanalyzer
-else
-  JAR_DIR="$BIN_DIR"/../../out/$DART_CONFIGURATION/dartanalyzer
-fi
-
-JAR_FILE="$JAR_DIR/dartanalyzer.jar"
-
-EXTRA_JVMARGS="-Xss2M "
-OS=`uname | tr "[A-Z]" "[a-z]"`
-if [ "$OS" == "darwin" ] ; then
-  # Bump up the heap on Mac VMs, some of which default to 128M or less.
-  EXTRA_JVMARGS+=" -Xmx512M -client "
-else
-  # On other architectures
-  # -batch invocations will do better with a server vm
-  # invocations for analyzing a single file do better with a client vm
-  if [ $FOUND_BATCH -eq 0 ] ; then
-    EXTRA_JVMARGS+=" -client "
-  fi
-fi
-
-exec java $EXTRA_JVMARGS -jar "$JAR_FILE" --dart-sdk "$SDK_DIR" "$@"
diff --git a/sdk/bin/dartanalyzer_java.bat b/sdk/bin/dartanalyzer_java.bat
deleted file mode 100644
index 86f47a8..0000000
--- a/sdk/bin/dartanalyzer_java.bat
+++ /dev/null
@@ -1,27 +0,0 @@
-@echo off

-rem Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file

-rem for details. All rights reserved. Use of this source code is governed by a

-rem BSD-style license that can be found in the LICENSE file.

-rem 

-

-rem This file is used to execute the analyzer by running the jar file.

-rem It is a simple wrapper enabling us to have simpler command lines in

-rem the testing infrastructure.

-

-set SCRIPTPATH=%~dp0

-

-rem Does the path have a trailing slash? If so, remove it.

-if %SCRIPTPATH:~-1%==\ set SCRIPTPATH=%SCRIPTPATH:~0,-1%

-

-rem DART_CONFIGURATION defaults to ReleaseIA32

-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32

-

-set arguments=%*

-

-set "SDK_DIR=%SCRIPTPATH%\..\..\build\%DART_CONFIGURATION%\dart-sdk"

-

-set "JAR_DIR=%SCRIPTPATH%\..\..\build\%DART_CONFIGURATION%\dartanalyzer"

-

-set "JAR_FILE=%JAR_DIR%\dartanalyzer.jar"

-

-java -jar "%JAR_FILE%" --dart-sdk "%SDK_DIR%" %arguments%

diff --git a/sdk/bin/dartanalyzer_sdk b/sdk/bin/dartanalyzer_sdk
index cc49a5c..28f37ab 100755
--- a/sdk/bin/dartanalyzer_sdk
+++ b/sdk/bin/dartanalyzer_sdk
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/sdk/bin/dartdoc b/sdk/bin/dartdoc
index 319df02..caff494 100755
--- a/sdk/bin/dartdoc
+++ b/sdk/bin/dartdoc
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/sdk/bin/dartfmt b/sdk/bin/dartfmt
index e4de89c..ded1eac 100755
--- a/sdk/bin/dartfmt
+++ b/sdk/bin/dartfmt
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
@@ -30,7 +30,7 @@
 
 if [ -z "$DART_CONFIGURATION" ];
 then
-  DART_CONFIGURATION="ReleaseIA32"
+  DART_CONFIGURATION="ReleaseX64"
 fi
 
 if [[ `uname` == 'Darwin' ]]; then
diff --git a/sdk/bin/dartfmt.bat b/sdk/bin/dartfmt.bat
index 5613b3a..321efe5 100644
--- a/sdk/bin/dartfmt.bat
+++ b/sdk/bin/dartfmt.bat
@@ -27,8 +27,8 @@
 
 set DARTFMT=%DART_ROOT%\third_party\pkg_tested\dart_style\bin\format.dart
 
-rem DART_CONFIGURATION defaults to ReleaseIA32
-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32
+rem DART_CONFIGURATION defaults to ReleaseX64
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
 
 set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
 
diff --git a/sdk/bin/dartfmt_sdk b/sdk/bin/dartfmt_sdk
index 0a9cbef..273733c 100755
--- a/sdk/bin/dartfmt_sdk
+++ b/sdk/bin/dartfmt_sdk
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/sdk/bin/pub b/sdk/bin/pub
index e927731..50f0d1d 100755
--- a/sdk/bin/pub
+++ b/sdk/bin/pub
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
@@ -37,7 +37,7 @@
 
 if [ -z "$DART_CONFIGURATION" ];
 then
-  DART_CONFIGURATION="ReleaseIA32"
+  DART_CONFIGURATION="ReleaseX64"
 fi
 
 if [[ `uname` == 'Darwin' ]];
diff --git a/sdk/bin/pub.bat b/sdk/bin/pub.bat
index 1326b57..06ba5f3 100644
--- a/sdk/bin/pub.bat
+++ b/sdk/bin/pub.bat
@@ -30,7 +30,7 @@
 
 rem Use the Dart binary in the built SDK so pub can find the version file next
 rem to it.
-set BUILD_DIR=%SDK_DIR%\..\build\ReleaseIA32
+set BUILD_DIR=%SDK_DIR%\..\build\ReleaseX64
 set PACKAGES_DIR=%BUILD_DIR%\packages
 set DART=%BUILD_DIR%\dart-sdk\bin\dart
 
diff --git a/sdk/bin/pub_sdk b/sdk/bin/pub_sdk
index bf48a16..f42f609 100755
--- a/sdk/bin/pub_sdk
+++ b/sdk/bin/pub_sdk
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 450e30b..4d91d79 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -28,11 +28,11 @@
 class _AsyncRun {
   @patch
   static void _scheduleImmediate(void callback()) {
-    scheduleImmediateClosure(callback);
+    _scheduleImmediateClosure(callback);
   }
 
   // Lazily initialized.
-  static final Function scheduleImmediateClosure =
+  static final Function _scheduleImmediateClosure =
       _initializeScheduleImmediate();
 
   static Function _initializeScheduleImmediate() {
@@ -196,22 +196,28 @@
 typedef void _WrappedAsyncBody(int errorCode, dynamic result);
 
 _WrappedAsyncBody _wrapJsFunctionForAsync(dynamic /* js function */ function) {
-  var protected = JS('', """
-    // Invokes [function] with [errorCode] and [result].
-    //
-    // If (and as long as) the invocation throws, calls [function] again,
-    // with an error-code.
-    function(errorCode, result) {
-      while (true) {
-        try {
-          #(errorCode, result);
-          break;
-        } catch (error) {
-          result = error;
-          errorCode = #;
-        }
-      }
-    }""", function, async_error_codes.ERROR);
+  var protected = JS(
+      '',
+      """
+        (function (fn, ERROR) {
+          // Invokes [function] with [errorCode] and [result].
+          //
+          // If (and as long as) the invocation throws, calls [function] again,
+          // with an error-code.
+          return function(errorCode, result) {
+            while (true) {
+              try {
+                fn(errorCode, result);
+                break;
+              } catch (error) {
+                result = error;
+                errorCode = ERROR;
+              }
+            }
+          }
+        })(#, #)""",
+      function, async_error_codes.ERROR);
+
   return Zone.current.registerBinaryCallback((int errorCode, dynamic result) {
     JS('', '#(#, #)', protected, errorCode, result);
   });
@@ -445,22 +451,25 @@
   _SyncStarIterator(this._body);
 
   _runBody() {
-    return JS('', '''
-// Invokes [body] with [errorCode] and [result].
-//
-// If (and as long as) the invocation throws, calls [function] again,
-// with an error-code.
-(function(body) {
-  var errorValue, errorCode = #;
-  while (true) {
-    try {
-      return body(errorCode, errorValue);
-    } catch (error) {
-      errorValue = error;
-      errorCode = #
-    }
-  }
-})(#)''', async_error_codes.SUCCESS, async_error_codes.ERROR, _body);
+    // TODO(sra): Find a way to hard-wire SUCCESS and ERROR codes.
+    return JS('',
+        '''
+        // Invokes [body] with [errorCode] and [result].
+        //
+        // If (and as long as) the invocation throws, calls [function] again,
+        // with an error-code.
+        (function(body, SUCCESS, ERROR) {
+          var errorValue, errorCode = SUCCESS;
+          while (true) {
+            try {
+              return body(errorCode, errorValue);
+            } catch (error) {
+              errorValue = error;
+              errorCode = ERROR;
+            }
+          }
+        })(#, #, #)''',
+        _body, async_error_codes.SUCCESS, async_error_codes.ERROR);
   }
 
 
diff --git a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
index 74582ba..7d15ab8 100644
--- a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -76,7 +76,7 @@
   bool get isNotEmpty => !isEmpty;
 
   Iterable<K> get keys {
-    return new HashMapKeyIterable<K>(this);
+    return new _HashMapKeyIterable<K>(this);
   }
 
   Iterable<V> get values {
@@ -431,16 +431,16 @@
   String toString() => Maps.mapToString(this);
 }
 
-class HashMapKeyIterable<E> extends Iterable<E>
-                            implements EfficientLength {
+class _HashMapKeyIterable<E> extends Iterable<E>
+                             implements EfficientLength {
   final _map;
-  HashMapKeyIterable(this._map);
+  _HashMapKeyIterable(this._map);
 
   int get length => _map._length;
   bool get isEmpty => _map._length == 0;
 
   Iterator<E> get iterator {
-    return new HashMapKeyIterator<E>(_map, _map._computeKeys());
+    return new _HashMapKeyIterator<E>(_map, _map._computeKeys());
   }
 
   bool contains(Object element) {
@@ -458,13 +458,13 @@
   }
 }
 
-class HashMapKeyIterator<E> implements Iterator<E> {
+class _HashMapKeyIterator<E> implements Iterator<E> {
   final _map;
   final List _keys;
   int _offset = 0;
   E _current;
 
-  HashMapKeyIterator(this._map, this._keys);
+  _HashMapKeyIterator(this._map, this._keys);
 
   E get current => _current;
 
@@ -849,7 +849,7 @@
 
   // Iterable.
   Iterator<E> get iterator {
-    return new HashSetIterator<E>(this, _computeElements());
+    return new _HashSetIterator<E>(this, _computeElements());
   }
 
   int get length => _length;
@@ -1160,14 +1160,14 @@
   }
 }
 
-// TODO(kasperl): Share this code with HashMapKeyIterator<E>?
-class HashSetIterator<E> implements Iterator<E> {
+// TODO(kasperl): Share this code with _HashMapKeyIterator<E>?
+class _HashSetIterator<E> implements Iterator<E> {
   final _set;
   final List _elements;
   int _offset = 0;
   E _current;
 
-  HashSetIterator(this._set, this._elements);
+  _HashSetIterator(this._set, this._elements);
 
   E get current => _current;
 
@@ -1244,8 +1244,8 @@
 
   // The elements are stored in cells that are linked together
   // to form a double linked list.
-  LinkedHashSetCell _first;
-  LinkedHashSetCell _last;
+  _LinkedHashSetCell _first;
+  _LinkedHashSetCell _last;
 
   // We track the number of modifications done to the element set to
   // be able to throw when the set is modified while being iterated
@@ -1262,7 +1262,7 @@
 
   // Iterable.
   Iterator<E> get iterator {
-    return new LinkedHashSetIterator(this, _modifications);
+    return new _LinkedHashSetIterator(this, _modifications);
   }
 
   int get length => _length;
@@ -1273,12 +1273,12 @@
     if (_isStringElement(object)) {
       var strings = _strings;
       if (strings == null) return false;
-      LinkedHashSetCell cell = _getTableEntry(strings, object);
+      _LinkedHashSetCell cell = _getTableEntry(strings, object);
       return cell != null;
     } else if (_isNumericElement(object)) {
       var nums = _nums;
       if (nums == null) return false;
-      LinkedHashSetCell cell = _getTableEntry(nums, object);
+      _LinkedHashSetCell cell = _getTableEntry(nums, object);
       return cell != null;
     } else {
       return _contains(object);
@@ -1310,7 +1310,7 @@
   }
 
   void forEach(void action(E element)) {
-    LinkedHashSetCell cell = _first;
+    _LinkedHashSetCell cell = _first;
     int modifications = _modifications;
     while (cell != null) {
       action(cell._element);
@@ -1352,12 +1352,12 @@
     var hash = _computeHashCode(element);
     var bucket = JS('var', '#[#]', rest, hash);
     if (bucket == null) {
-      LinkedHashSetCell cell = _newLinkedCell(element);
+      _LinkedHashSetCell cell = _newLinkedCell(element);
       _setTableEntry(rest, hash, JS('var', '[#]', cell));
     } else {
       int index = _findBucketIndex(bucket, element);
       if (index >= 0) return false;
-      LinkedHashSetCell cell = _newLinkedCell(element);
+      _LinkedHashSetCell cell = _newLinkedCell(element);
       JS('void', '#.push(#)', bucket, cell);
     }
     return true;
@@ -1381,7 +1381,7 @@
     if (index < 0) return false;
     // Use splice to remove the [cell] element at the index and
     // unlink it.
-    LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
+    _LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
     _unlinkCell(cell);
     return true;
   }
@@ -1395,10 +1395,10 @@
   }
 
   void _filterWhere(bool test(E element), bool removeMatching) {
-    LinkedHashSetCell cell = _first;
+    _LinkedHashSetCell cell = _first;
     while (cell != null) {
       E element = cell._element;
-      LinkedHashSetCell next = cell._next;
+      _LinkedHashSetCell next = cell._next;
       int modifications = _modifications;
       bool shouldRemove = (removeMatching == test(element));
       if (modifications != _modifications) {
@@ -1418,7 +1418,7 @@
   }
 
   bool _addHashTableEntry(var table, E element) {
-    LinkedHashSetCell cell = _getTableEntry(table, element);
+    _LinkedHashSetCell cell = _getTableEntry(table, element);
     if (cell != null) return false;
     _setTableEntry(table, element, _newLinkedCell(element));
     return true;
@@ -1426,7 +1426,7 @@
 
   bool _removeHashTableEntry(var table, Object element) {
     if (table == null) return false;
-    LinkedHashSetCell cell = _getTableEntry(table, element);
+    _LinkedHashSetCell cell = _getTableEntry(table, element);
     if (cell == null) return false;
     _unlinkCell(cell);
     _deleteTableEntry(table, element);
@@ -1441,12 +1441,12 @@
   }
 
   // Create a new cell and link it in as the last one in the list.
-  LinkedHashSetCell _newLinkedCell(E element) {
-    LinkedHashSetCell cell = new LinkedHashSetCell(element);
+  _LinkedHashSetCell _newLinkedCell(E element) {
+    _LinkedHashSetCell cell = new _LinkedHashSetCell(element);
     if (_first == null) {
       _first = _last = cell;
     } else {
-      LinkedHashSetCell last = _last;
+      _LinkedHashSetCell last = _last;
       cell._previous = last;
       _last = last._next = cell;
     }
@@ -1456,9 +1456,9 @@
   }
 
   // Unlink the given cell from the linked list of cells.
-  void _unlinkCell(LinkedHashSetCell cell) {
-    LinkedHashSetCell previous = cell._previous;
-    LinkedHashSetCell next = cell._next;
+  void _unlinkCell(_LinkedHashSetCell cell) {
+    _LinkedHashSetCell previous = cell._previous;
+    _LinkedHashSetCell next = cell._next;
     if (previous == null) {
       assert(cell == _first);
       _first = next;
@@ -1517,7 +1517,7 @@
     if (bucket == null) return -1;
     int length = JS('int', '#.length', bucket);
     for (int i = 0; i < length; i++) {
-      LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
       if (cell._element == element) return i;
     }
     return -1;
@@ -1551,7 +1551,7 @@
     if (bucket == null) return -1;
     int length = JS('int', '#.length', bucket);
     for (int i = 0; i < length; i++) {
-      LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
       if (identical(cell._element, element)) return i;
     }
     return -1;
@@ -1573,7 +1573,7 @@
     if (bucket == null) return -1;
     int length = JS('int', '#.length', bucket);
     for (int i = 0; i < length; i++) {
-      LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      _LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
       if (_equality(cell._element, element)) return i;
     }
     return -1;
@@ -1620,23 +1620,23 @@
   }
 }
 
-class LinkedHashSetCell {
+class _LinkedHashSetCell {
   final _element;
 
-  LinkedHashSetCell _next;
-  LinkedHashSetCell _previous;
+  _LinkedHashSetCell _next;
+  _LinkedHashSetCell _previous;
 
-  LinkedHashSetCell(this._element);
+  _LinkedHashSetCell(this._element);
 }
 
 // TODO(kasperl): Share this code with LinkedHashMapKeyIterator<E>?
-class LinkedHashSetIterator<E> implements Iterator<E> {
+class _LinkedHashSetIterator<E> implements Iterator<E> {
   final _set;
   final int _modifications;
-  LinkedHashSetCell _cell;
+  _LinkedHashSetCell _cell;
   E _current;
 
-  LinkedHashSetIterator(this._set, this._modifications) {
+  _LinkedHashSetIterator(this._set, this._modifications) {
     _cell = _set._first;
   }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/constant_map.dart b/sdk/lib/_internal/js_runtime/lib/constant_map.dart
index 8a6a5c9..9e98b13 100644
--- a/sdk/lib/_internal/js_runtime/lib/constant_map.dart
+++ b/sdk/lib/_internal/js_runtime/lib/constant_map.dart
@@ -67,14 +67,18 @@
 
   // This constructor is not used for actual compile-time constants.
   // The instantiation of constant maps is shortcut by the compiler.
-  const ConstantStringMap._(this.length, this._jsObject, this._keys)
+  const ConstantStringMap._(this._length, this._jsObject, this._keys)
       : super._();
 
-  final int length;
+  // TODO(18131): Ensure type inference knows the precise types of the fields.
+  final int _length;
   // A constant map is backed by a JavaScript object.
   final _jsObject;
   final List<K> _keys;
 
+  int get length => JS('JSUInt31', '#', _length);
+  List get _keysArray => JS('JSUnmodifiableArray', '#', _keys);
+
   bool containsValue(Object needle) {
     return values.any((V value) => value == needle);
   }
@@ -97,7 +101,7 @@
     // Use a JS 'cast' to get efficient loop.  Type inferrence doesn't get this
     // since constant map representation is chosen after type inferrence and the
     // instantiation is shortcut by the compiler.
-    var keys = JS('JSArray', '#', _keys);
+    var keys = _keysArray;
     for (int i = 0; i < keys.length; i++) {
       var key = keys[i];
       f(key, _fetch(key));
@@ -109,7 +113,7 @@
   }
 
   Iterable<V> get values {
-    return new MappedIterable<K, V>(_keys, (key) => _fetch(key));
+    return new MappedIterable<K, V>(_keysArray, (key) => _fetch(key));
   }
 }
 
@@ -135,9 +139,9 @@
   ConstantStringMap<K, dynamic> _map;
   _ConstantMapKeyIterable(this._map);
 
-  Iterator<K> get iterator => _map._keys.iterator;
+  Iterator<K> get iterator => _map._keysArray.iterator;
 
-  int get length => _map._keys.length;
+  int get length => _map._keysArray.length;
 }
 
 class GeneralConstantMap<K, V> extends ConstantMap<K, V> {
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 7d6ad7c..dfed0df 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -5,21 +5,22 @@
 // Patch file for dart:core classes.
 import "dart:_internal" as _symbol_dev;
 import 'dart:_interceptors';
-import 'dart:_js_helper' show patch,
+import 'dart:_js_helper' show checkInt,
+                              Closure,
+                              ConstantMap,
+                              getRuntimeType,
+                              JsLinkedHashMap,
+                              jsonEncodeNative,
+                              JSSyntaxRegExp,
+                              NoInline,
+                              objectHashCode,
+                              patch,
                               patch_full,
                               patch_lazy,
                               patch_startup,
-                              checkInt,
-                              getRuntimeType,
-                              jsonEncodeNative,
-                              JSSyntaxRegExp,
                               Primitives,
-                              ConstantMap,
-                              stringJoinUnchecked,
-                              objectHashCode,
-                              Closure,
                               readHttp,
-                              JsLinkedHashMap;
+                              stringJoinUnchecked;
 
 import 'dart:_foreign_helper' show JS;
 
@@ -185,6 +186,18 @@
 @patch
 class DateTime {
   @patch
+  DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+                                      {bool isUtc: false})
+      : this._withValue(millisecondsSinceEpoch, isUtc: isUtc);
+
+  @patch
+  DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+                                      {bool isUtc: false})
+      : this._withValue(
+          _microsecondInRoundedMilliseconds(microsecondsSinceEpoch),
+          isUtc: isUtc);
+
+  @patch
   DateTime._internal(int year,
                      int month,
                      int day,
@@ -192,26 +205,38 @@
                      int minute,
                      int second,
                      int millisecond,
+                     int microsecond,
                      bool isUtc)
         // checkBool is manually inlined here because dart2js doesn't inline it
         // and [isUtc] is usually a constant.
       : this.isUtc = isUtc is bool
             ? isUtc
             : throw new ArgumentError.value(isUtc, 'isUtc'),
-        millisecondsSinceEpoch = checkInt(Primitives.valueFromDecomposedDate(
-            year, month, day, hour, minute, second, millisecond, isUtc));
+        _value = checkInt(Primitives.valueFromDecomposedDate(
+            year, month, day, hour, minute, second,
+            millisecond + _microsecondInRoundedMilliseconds(microsecond),
+            isUtc));
 
   @patch
   DateTime._now()
       : isUtc = false,
-        millisecondsSinceEpoch = Primitives.dateNow();
+        _value = Primitives.dateNow();
+
+  /// Rounds the given [microsecond] to the nearest milliseconds value.
+  ///
+  /// For example, invoked with argument `2600` returns `3`.
+  static int _microsecondInRoundedMilliseconds(int microsecond) {
+    return (microsecond / 1000).round();
+  }
 
   @patch
-  static int _brokenDownDateToMillisecondsSinceEpoch(
+  static int _brokenDownDateToValue(
       int year, int month, int day, int hour, int minute, int second,
-      int millisecond, bool isUtc) {
+      int millisecond, int microsecond, bool isUtc) {
     return Primitives.valueFromDecomposedDate(
-        year, month, day, hour, minute, second, millisecond, isUtc);
+        year, month, day, hour, minute, second,
+        millisecond + _microsecondInRoundedMilliseconds(microsecond),
+        isUtc);
   }
 
   @patch
@@ -227,6 +252,29 @@
   }
 
   @patch
+  DateTime add(Duration duration) {
+    return new DateTime._withValue(
+        _value + duration.inMilliseconds, isUtc: isUtc);
+  }
+
+  @patch
+  DateTime subtract(Duration duration) {
+    return new DateTime._withValue(
+        _value - duration.inMilliseconds, isUtc: isUtc);
+  }
+
+  @patch
+  Duration difference(DateTime other) {
+    return new Duration(milliseconds: _value - other._value);
+  }
+
+  @patch
+  int get millisecondsSinceEpoch => _value;
+
+  @patch
+  int get microsecondsSinceEpoch => _value * 1000;
+
+  @patch
   int get year => Primitives.getYear(this);
 
   @patch
@@ -248,6 +296,9 @@
   int get millisecond => Primitives.getMilliseconds(this);
 
   @patch
+  int get microsecond => 0;
+
+  @patch
   int get weekday => Primitives.getWeekday(this);
 }
 
@@ -281,8 +332,9 @@
   }
 
   @patch
-  factory List.filled(int length, E fill) {
-    List result = new JSArray<E>.fixed(length);
+  factory List.filled(int length, E fill, {bool growable: false}) {
+    List result = growable ? new JSArray<E>.growable(length)
+                           : new JSArray<E>.fixed(length);
     if (length != 0 && fill != null) {
       for (int i = 0; i < result.length; i++) {
         result[i] = fill;
@@ -527,6 +579,47 @@
     if (uri != null) return Uri.parse(uri);
     throw new UnsupportedError("'Uri.base' is not supported");
   }
+
+
+  // Matches a String that _uriEncodes to itself regardless of the kind of
+  // component.  This corresponds to [_unreservedTable], i.e. characters that
+  // are not encoded by any encoding table.
+  static final RegExp _needsNoEncoding = new RegExp(r'^[\-\.0-9A-Z_a-z~]*$');
+
+  /**
+   * This is the internal implementation of JavaScript's encodeURI function.
+   * It encodes all characters in the string [text] except for those
+   * that appear in [canonicalTable], and returns the escaped string.
+   */
+  @patch
+  static String _uriEncode(List<int> canonicalTable,
+                           String text,
+                           Encoding encoding,
+                           bool spaceToPlus) {
+    if (identical(encoding, UTF8) && _needsNoEncoding.hasMatch(text)) {
+      return text;
+    }
+
+    // Encode the string into bytes then generate an ASCII only string
+    // by percent encoding selected bytes.
+    StringBuffer result = new StringBuffer();
+    var bytes = encoding.encode(text);
+    for (int i = 0; i < bytes.length; i++) {
+      int byte = bytes[i];
+      if (byte < 128 &&
+          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+        result.writeCharCode(byte);
+      } else if (spaceToPlus && byte == _SPACE) {
+        result.write('+');
+      } else {
+        const String hexDigits = '0123456789ABCDEF';
+        result.write('%');
+        result.write(hexDigits[(byte >> 4) & 0x0f]);
+        result.write(hexDigits[byte & 0x0f]);
+      }
+    }
+    return result.toString();
+  }
 }
 
 @patch
@@ -629,3 +722,24 @@
     });
   }
 }
+
+@patch
+class StackTrace {
+  @patch
+  @NoInline()
+  static StackTrace get current {
+    var error = JS('', 'new Error()');
+    var stack = JS('String|Null', '#.stack', error);
+    if (stack is String) return new StackTrace.fromString(stack);
+    if (JS('', 'Error.captureStackTrace') != null) {
+      JS('void', 'Error.captureStackTrace(#)', error);
+      var stack = JS('String|Null', '#.stack', error);
+      if (stack is String) return new StackTrace.fromString(stack);
+    }
+    try {
+      throw 0;
+    } catch (_, stackTrace) {
+      return stackTrace;
+    }
+  }
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
index e13f580..d56f946 100644
--- a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
@@ -46,6 +46,12 @@
 }
 
 @patch
+_postEvent(String eventKind, String eventData) {
+  // TODO.
+}
+
+
+@patch
 int _getTraceClock() {
   // TODO.
   return _clockValue++;
@@ -62,11 +68,24 @@
 }
 
 @patch
+void _reportInstantEvent(int start,
+                         String category,
+                         String name,
+                         String argumentsAsJson) {
+  // TODO.
+}
+
+@patch
 int _getNextAsyncId() {
   return 0;
 }
 
 @patch
+int _getIsolateNum() {
+  return 0;
+}
+
+@patch
 void _reportTaskEvent(int start,
                       int taskId,
                       String phase,
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index 23f4708..350ab96 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -233,6 +233,10 @@
     throw new UnsupportedError("Platform._packageRoot");
   }
   @patch
+  static String _packageConfig() {
+    throw new UnsupportedError("Platform._packageConfig");
+  }
+  @patch
   static _environment() {
     throw new UnsupportedError("Platform._environment");
   }
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
index ac8b537..79931ba 100644
--- a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
@@ -20,6 +20,21 @@
   static Isolate get current => _currentIsolateCache;
 
   @patch
+  static Future<Uri> get packageRoot {
+    throw new UnsupportedError("Isolate.packageRoot");
+  }
+
+  @patch
+  static Future<Uri> get packageConfig {
+    throw new UnsupportedError("Isolate.packageConfig");
+  }
+
+  @patch
+  static Future<Uri> resolvePackageUri(Uri packageUri) {
+    throw new UnsupportedError("Isolate.resolvePackageUri");
+  }
+
+  @patch
   static Future<Isolate> spawn(void entryPoint(message), var message,
                                {bool paused: false, bool errorsAreFatal,
                                 SendPort onExit, SendPort onError}) {
@@ -66,9 +81,14 @@
        bool errorsAreFatal,
        bool checked,
        Map<String, String> environment,
-       Uri packageRoot}) {
+       Uri packageRoot,
+       Uri packageConfig,
+       bool automaticPackageResolution: false}) {
     if (environment != null) throw new UnimplementedError("environment");
     if (packageRoot != null) throw new UnimplementedError("packageRoot");
+    if (packageConfig != null) throw new UnimplementedError("packageConfig");
+    // TODO(lrn): Figure out how to handle the automaticPackageResolution
+    // parameter.
     bool forcePause = (errorsAreFatal != null) ||
                       (onExit != null) ||
                       (onError != null);
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 8b3020a..4976562 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -891,9 +891,9 @@
         // an identifier, we use that instead of the very generic 'Object'.
         var objectConstructor = JS('', '#.constructor', object);
         if (JS('bool', 'typeof # == "function"', objectConstructor)) {
-          var decompiledName =
-              JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)[1]',
-                  JS('var', r'String(#)', objectConstructor));
+          var match = JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)',
+              JS('var', r'String(#)', objectConstructor));
+          var decompiledName = match == null ? null : JS('var', r'#[1]', match);
           if (decompiledName is String &&
               JS('bool', r'/^\w+$/.test(#)', decompiledName)) {
             name = decompiledName;
@@ -1017,13 +1017,15 @@
   static String stringFromCharCode(charCode) {
     if (0 <= charCode) {
       if (charCode <= 0xffff) {
-        return JS('String', 'String.fromCharCode(#)', charCode);
+        return JS('returns:String;effects:none;depends:none',
+                  'String.fromCharCode(#)', charCode);
       }
       if (charCode <= 0x10ffff) {
         var bits = charCode - 0x10000;
         var low = 0xDC00 | (bits & 0x3ff);
         var high = 0xD800 | (bits >> 10);
-        return  JS('String', 'String.fromCharCode(#, #)', high, low);
+        return JS('returns:String;effects:none;depends:none',
+                  'String.fromCharCode(#, #)', high, low);
       }
     }
     throw new RangeError.range(charCode, 0, 0x10ffff);
@@ -1930,8 +1932,7 @@
 
     // Since we want to create a new regular expression from an unknown string,
     // we must escape all regular expression syntax.
-    message = JS('String', r"#.replace(new RegExp(#, 'g'), '\\$&')",
-                 message, ESCAPE_REGEXP);
+    message = quoteStringForRegExp(message);
 
     // Look for the special pattern \$camelCase\$ (all the $ symbols
     // have been escaped already), as we will soon be inserting
@@ -2367,20 +2368,19 @@
               var arg2,
               var arg3,
               var arg4) {
-  if (numberOfArguments == 0) {
-    return JS_CALL_IN_ISOLATE(isolate, () => closure());
-  } else if (numberOfArguments == 1) {
-    return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1));
-  } else if (numberOfArguments == 2) {
-    return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2));
-  } else if (numberOfArguments == 3) {
-    return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2, arg3));
-  } else if (numberOfArguments == 4) {
-    return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2, arg3, arg4));
-  } else {
-    throw new Exception(
-        'Unsupported number of arguments for wrapped closure');
+  switch (numberOfArguments) {
+    case 0:
+      return JS_CALL_IN_ISOLATE(isolate, () => closure());
+    case 1:
+      return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1));
+    case 2:
+      return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2));
+    case 3:
+      return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2, arg3));
+    case 4:
+      return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2, arg3, arg4));
   }
+  throw new Exception('Unsupported number of arguments for wrapped closure');
 }
 
 /**
@@ -2392,21 +2392,18 @@
   var function = JS('var', r'#.$identity', closure);
   if (JS('bool', r'!!#', function)) return function;
 
-  // We use $0 and $1 to not clash with variable names used by the
-  // compiler and/or minifier.
-  function = JS('var',
-                '(function(closure, arity, context, invoke) {'
-                '  return function(a1, a2, a3, a4) {'
-                '     return invoke(closure, context, arity, a1, a2, a3, a4);'
-                '  };'
-                '})(#,#,#,#)',
-                closure,
-                arity,
-                // Capture the current isolate now.  Remember that "#"
-                // in JS is simply textual substitution of compiled
-                // expressions.
-                JS_CURRENT_ISOLATE_CONTEXT(),
-                DART_CLOSURE_TO_JS(invokeClosure));
+  function = JS(
+      'var',
+      r'''
+        (function(closure, arity, context, invoke) {
+          return function(a1, a2, a3, a4) {
+            return invoke(closure, context, arity, a1, a2, a3, a4);
+          };
+        })(#,#,#,#)''',
+      closure,
+      arity,
+      JS_CURRENT_ISOLATE_CONTEXT(),
+      DART_CLOSURE_TO_JS(invokeClosure));
 
   JS('void', r'#.$identity = #', closure, function);
   return function;
@@ -2568,9 +2565,9 @@
       // captured variable `functionType` isn't reused.
       signatureFunction =
           JS('',
-             '''(function(t) {
-                    return function(){ return #(t); };
-                })(#)''',
+             '''(function(getType, t) {
+                    return function(){ return getType(t); };
+                })(#, #)''',
              RAW_DART_FUNCTION_REF(getType),
              functionType);
     } else if (!isStatic
@@ -2896,10 +2893,9 @@
   bool operator==(other) {
     if (identical(this, other)) return true;
     if (other is! BoundClosure) return false;
-    return JS('bool', '# === # && # === # && # === #',
-        _self, other._self,
-        _target, other._target,
-        _receiver, other._receiver);
+    return JS('bool', '# === #', _self, other._self) &&
+           JS('bool', '# === #', _target, other._target) &&
+           JS('bool', '# === #', _receiver, other._receiver);
   }
 
   int get hashCode {
@@ -3751,7 +3747,7 @@
   bool get _hasReturnType => JS('bool', '"ret" in #', _typeData);
   get _returnType => JS('', '#.ret', _typeData);
 
-  bool get _isVoid => JS('bool', '!!#.void', _typeData);
+  bool get _isVoid => JS('bool', '!!#.v', _typeData);
 
   bool get _hasArguments => JS('bool', '"args" in #', _typeData);
   List get _arguments => JS('JSExtendableArray', '#.args', _typeData);
diff --git a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
index fc78e72..4cbb163 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
@@ -2245,19 +2245,25 @@
     disableTreeShaking();
     // TODO(ahe): What about optional parameters (named or not).
     String callPrefix = "${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$";
-    var extractCallName = JS('', r'''
-function(reflectee) {
-  var properties = Object.keys(reflectee.constructor.prototype);
-  for (var i = 0; i < properties.length; i++) {
-    var property = properties[i];
-    if (# == property.substring(0, #) &&
-        property[#] >= '0' &&
-        property[#] <= '9') return property;
-  }
-  return null;
-}
-''', callPrefix, callPrefix.length, callPrefix.length, callPrefix.length);
-    String callName = JS('String|Null', '#(#)', extractCallName, reflectee);
+
+    String callName = JS(
+        'String|Null',
+        r'''
+          (function(reflectee, callPrefix) {
+            var properties = Object.keys(reflectee.constructor.prototype);
+            var callPrefixLength = callPrefix.length;
+            for (var i = 0; i < properties.length; i++) {
+              var property = properties[i];
+              if (callPrefix == property.substring(0, callPrefixLength) &&
+                  property[callPrefixLength] >= "0" &&
+                  property[callPrefixLength] <= "9") {
+                return property;
+              }
+            }
+            return null;
+          })(#, #)''',
+        reflectee, callPrefix);
+
     if (callName == null) {
       throw new RuntimeError('Cannot find callName on "$reflectee"');
     }
diff --git a/sdk/lib/_internal/js_runtime/lib/js_names.dart b/sdk/lib/_internal/js_runtime/lib/js_names.dart
index 708b873..a0fe67f 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_names.dart
@@ -165,9 +165,14 @@
 }
 
 String unmangleAllIdentifiersIfPreservedAnyways(String str) {
-  return JS("String",
-            r"(#).replace(/[^<,> ]+/g,"
-            r"function(m) { return #[m] || m; })",
-            str,
-            JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES));
-}
\ No newline at end of file
+  return JS(
+      'String',
+      r'''
+        (function(str, names) {
+          return str.replace(
+              /[^<,> ]+/g,
+              function(m) { return names[m] || m; });
+        })(#, #)''',
+      str,
+      JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES));
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/math_patch.dart b/sdk/lib/_internal/js_runtime/lib/math_patch.dart
index 34476f2..fc54f63 100644
--- a/sdk/lib/_internal/js_runtime/lib/math_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/math_patch.dart
@@ -5,6 +5,7 @@
 // Patch file for dart:math library.
 import 'dart:_foreign_helper' show JS;
 import 'dart:_js_helper' show patch, checkNum;
+import 'dart:typed_data' show ByteData;
 
 @patch
 double sqrt(num x)
@@ -57,9 +58,14 @@
 
 @patch
 class Random {
+  static final _secureRandom = new _JSSecureRandom();
+
   @patch
   factory Random([int seed]) =>
       (seed == null) ? const _JSRandom() : new _Random(seed);
+
+  @patch
+  factory Random.secure() => _secureRandom;
 }
 
 class _JSRandom implements Random {
@@ -236,3 +242,89 @@
     return (_lo & 1) == 0;
   }
 }
+
+
+class _JSSecureRandom implements Random {
+  // Reused buffer with room enough for a double.
+  final _buffer = new ByteData(8);
+
+  _JSSecureRandom() {
+    var crypto = JS("", "self.crypto");
+    if (crypto != null) {
+      var getRandomValues = JS("", "#.getRandomValues", crypto);
+      if (getRandomValues != null) {
+        return;
+      }
+    }
+    throw new UnsupportedError(
+        "No source of cryptographically secure random numbers available.");
+  }
+
+  /// Fill _buffer from [start] to `start + length` with random bytes.
+  void _getRandomBytes(int start, int length) {
+    JS("void", "crypto.getRandomValues(#)",
+       _buffer.buffer.asUint8List(start, length));
+  }
+
+  bool nextBool() {
+    _getRandomBytes(0, 1);
+    return _buffer.getUint8(0).isOdd;
+  }
+
+  double nextDouble() {
+    _getRandomBytes(1, 7);
+    // Set top bits 12 of double to 0x3FF which is the exponent for numbers
+    // between 1.0 and 2.0.
+    _buffer.setUint8(0, 0x3F);
+    int highByte = _buffer.getUint8(1);
+    _buffer.setUint8(1, highByte | 0xF0);
+
+    // Buffer now contains double in the range [1.0-2.0)
+    // with 52 bits of entropy (not 53).
+    // To get 53 bits, we extract the 53rd bit from higthByte before
+    // overwriting it, and add that as a least significant bit.
+    // The getFloat64 method is big-endian as default.
+    double result = _buffer.getFloat64(0) - 1.0;
+    if (highByte & 0x10 != 0) {
+      result += 1.1102230246251565e-16;  // pow(2,-53).
+    }
+    return result;
+  }
+
+  int nextInt(int max) {
+    if (max <= 0 || max > _POW2_32) {
+      throw new RangeError("max must be in range 0 < max ≤ 2^32, was $max");
+    }
+    int byteCount = 1;
+    if (max > 0xFF) {
+      byteCount++;
+      if (max > 0xFFFF) {
+        byteCount++;
+        if (max > 0xFFFFFF) {
+          byteCount++;
+        }
+      }
+    }
+    _buffer.setUint32(0, 0);
+    int start = 4 - byteCount;
+    int randomLimit = pow(256, byteCount);
+    while (true) {
+      _getRandomBytes(start, byteCount);
+      // The getUint32 method is big-endian as default.
+      int random = _buffer.getUint32(0);
+      if (max & (max - 1) == 0) {
+        // Max is power of 2.
+        return random & (max - 1);
+      }
+      int result = random.remainder(max);
+      // Ensure results have equal probability by rejecting values in the
+      // last range of k*max .. 256**byteCount.
+      // TODO: Consider picking a higher byte count if the last range is a
+      // significant portion of the entire range - a 50% chance of having
+      // to use two more bytes is no worse than always using one more.
+      if (random - result + max < randomLimit) {
+        return result;
+      }
+    }
+  }
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/native_helper.dart b/sdk/lib/_internal/js_runtime/lib/native_helper.dart
index e87ace9..30d3ba7 100644
--- a/sdk/lib/_internal/js_runtime/lib/native_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/native_helper.dart
@@ -164,6 +164,7 @@
  * A dispatch record is cached according to the specification of the dispatch
  * tag for [obj].
  */
+@NoInline()
 lookupAndCacheInterceptor(obj) {
   assert(!isDartObject(obj));
   String tag = getTagFunction(obj);
@@ -288,12 +289,14 @@
 
 var initNativeDispatchFlag;  // null or true
 
+@NoInline()
 void initNativeDispatch() {
   if (true == initNativeDispatchFlag) return;
   initNativeDispatchFlag = true;
   initNativeDispatchContinue();
 }
 
+@NoInline()
 void initNativeDispatchContinue() {
 
   dispatchRecordsForInstanceTags = JS('', 'Object.create(null)');
diff --git a/sdk/lib/_internal/js_runtime/lib/preambles/d8.js b/sdk/lib/_internal/js_runtime/lib/preambles/d8.js
index 18823e1..b67593a 100644
--- a/sdk/lib/_internal/js_runtime/lib/preambles/d8.js
+++ b/sdk/lib/_internal/js_runtime/lib/preambles/d8.js
@@ -327,4 +327,11 @@
       errorCallback(error);
     }
   };
+
+  // Mock cryptographically secure random by using plain random.
+  self.crypto = {getRandomValues: function(array) {
+    for (var i = 0; i < array.length; i++) {
+      array[i] = Math.random() * 256;
+    }
+  }};
 })(self);
diff --git a/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js b/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
index a33a58f..9f136c2 100644
--- a/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
+++ b/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
@@ -67,6 +67,13 @@
       errorCallback(error);
     }
   };
+
+  // Mock cryptographically secure random by using plain random.
+  self.crypto = {getRandomValues: function(array) {
+    for (var i = 0; i < array.length; i++) {
+      array[i] = Math.random() * 256;
+    }
+  }};
 })(this)
 
 var getKeys = function(obj){
diff --git a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
index 9b44116c..35a42d1c 100644
--- a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
@@ -85,23 +85,24 @@
     String m = multiLine == true ? 'm' : '';
     String i = caseSensitive == true ? '' : 'i';
     String g = global ? 'g' : '';
-    // We're using the JavaScript's try catch instead of the Dart one
-    // to avoid dragging in Dart runtime support just because of using
-    // RegExp.
+    // We're using the JavaScript's try catch instead of the Dart one to avoid
+    // dragging in Dart runtime support just because of using RegExp.
     var regexp = JS('',
-        '(function() {'
-         'try {'
-          'return new RegExp(#, # + # + #);'
-         '} catch (e) {'
-           'return e;'
-         '}'
-        '})()', source, m, i, g);
+        r'''
+          (function(source, modifiers) {
+            try {
+              return new RegExp(source, modifiers);
+            } catch (e) {
+              return e;
+            }
+          })(#, # + # + #)''',
+        source, m, i, g);
     if (JS('bool', '# instanceof RegExp', regexp)) return regexp;
     // The returned value is the JavaScript exception. Turn it into a
     // Dart exception.
     String errorMessage = JS('String', r'String(#)', regexp);
     throw new FormatException(
-        "Illegal RegExp pattern ($errorMessage)", source);
+        'Illegal RegExp pattern ($errorMessage)', source);
   }
 
   Match firstMatch(String string) {
diff --git a/sdk/lib/_internal/js_runtime/lib/string_helper.dart b/sdk/lib/_internal/js_runtime/lib/string_helper.dart
index 9ce91f8..24e21f7 100644
--- a/sdk/lib/_internal/js_runtime/lib/string_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/string_helper.dart
@@ -130,7 +130,12 @@
   return stringReplaceRangeUnchecked(receiver, start, end, replacement);
 }
 
-const String ESCAPE_REGEXP = r'[[\]{}()*+?.\\^$|]';
+
+/// Returns a string for a RegExp pattern that matches [string]. This is done by
+/// escaping all RegExp metacharacters.
+quoteStringForRegExp(string) {
+  return JS('String', r'#.replace(/[[\]{}()*+?.\\^$|]/g, "\\$&")', string);
+}
 
 stringReplaceAllUnchecked(receiver, pattern, replacement) {
   checkString(replacement);
@@ -149,8 +154,7 @@
         return result.toString();
       }
     } else {
-      var quoter = JS('', "new RegExp(#, 'g')", ESCAPE_REGEXP);
-      var quoted = JS('String', r'#.replace(#, "\\$&")', pattern, quoter);
+      var quoted = quoteStringForRegExp(pattern);
       var replacer = JS('', "new RegExp(#, 'g')", quoted);
       return stringReplaceJS(receiver, replacer, replacement);
     }
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index ac205be..5d1e2c7 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -67,26 +67,27 @@
  *
  * ## Other resources
  *
- * * The [dart:async section of the library tour]
- * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-asynchronous-programming):
- * A brief overview of asynchronous programming.
+ * * The [dart:async section of the library tour][asynchronous-programming]:
+ *   A brief overview of asynchronous programming.
  *
- * * [Use Future-Based APIs]
- * (https://www.dartlang.org/docs/tutorials/futures/): A closer look at
- * Futures and how to use them to write asynchronous Dart code.
+ * * [Use Future-Based APIs][futures-tutorial]: A closer look at Futures and
+ *   how to use them to write asynchronous Dart code.
  *
- * * [Futures and Error Handling]
- * (https://www.dartlang.org/articles/futures-and-error-handling/): Everything
- * you wanted to know about handling errors and exceptions when working with
- * Futures (but were afraid to ask).
+ * * [Futures and Error Handling][futures-error-handling]: Everything you
+ *   wanted to know about handling errors and exceptions when working with
+ *   Futures (but were afraid to ask).
  *
  * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/):
- * Learn how Dart handles the event queue and microtask queue, so you can write
- * better asynchronous code with fewer surprises.
+ *   Learn how Dart handles the event queue and microtask queue, so you can
+ *   write better asynchronous code with fewer surprises.
  *
- * * [Asynchronous Unit Testing with Dart]
- * (https://www.dartlang.org/articles/dart-unit-tests/#asynchronous-tests): How
- * to test asynchronous code.
+ * * [test package: Asynchronous Tests][test-readme]: How to test asynchronous
+ *   code.
+ *
+ * [asynchronous-programming]: https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartasync---asynchronous-programming
+ * [futures-tutorial]: https://www.dartlang.org/docs/tutorials/futures/
+ * [futures-error-handling]: https://www.dartlang.org/articles/futures-and-error-handling/
+ * [test-readme]: https://pub.dartlang.org/packages/test
  */
 library dart.async;
 
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 30016f7..48f968f 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -254,9 +254,9 @@
    * The call to `cleanUp` should not throw. If it does, the error will be an
    * uncaught asynchronous error.
    */
-  static Future<List> wait(Iterable<Future> futures,
+  static Future<List/*<T>*/> wait/*<T>*/(Iterable<Future/*<T>*/> futures,
                            {bool eagerError: false,
-                            void cleanUp(successValue)}) {
+                            void cleanUp(/*=T*/ successValue)}) {
     final _Future<List> result = new _Future<List>();
     List values;  // Collects the values. Set to null on error.
     int remaining = 0;  // How many futures are we waiting for.
@@ -317,6 +317,31 @@
   }
 
   /**
+   * Returns the result of the first future in [futures] to complete.
+   *
+   * The returned future is completed with the result of the first
+   * future in [futures] to report that it is complete.
+   * The results of all the other futures are discarded.
+   *
+   * If [futures] is empty, or if none of its futures complete,
+   * the returned future never completes.
+   */
+  static Future/*<T>*/ any/*<T>*/(Iterable<Future/*<T>*/> futures) {
+    var completer = new Completer.sync();
+    var onValue = (value) {
+      if (!completer.isCompleted) completer.complete(value);
+    };
+    var onError = (error, stack) {
+      if (!completer.isCompleted) completer.completeError(error, stack);
+    };
+    for (var future in futures) {
+      future.then(onValue, onError: onError);
+    }
+    return completer.future;
+  }
+
+
+  /**
    * Perform an async operation for each element of the iterable, in turn.
    *
    * Runs [f] for each element in [input] in order, moving to the next element
@@ -407,7 +432,7 @@
    * with a `test` parameter, instead of handling both value and error in a
    * single [then] call.
    */
-  Future then(onValue(T value), { Function onError });
+  Future/*<S>*/ then/*<S>*/(/*=S*/ onValue(T value), { Function onError });
 
   /**
    * Handles errors emitted by this [Future].
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 35dfd119..68dbbc0 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -95,11 +95,6 @@
         errorCallback = null,
         state = STATE_WHENCOMPLETE;
 
-  _FutureListener.chain(this.result)
-      : callback = null,
-        errorCallback = null,
-        state = STATE_CHAIN;
-
   Zone get _zone => result._zone;
 
   bool get handlesValue => (state & MASK_VALUE != 0);
@@ -133,8 +128,7 @@
   static const int _PENDING_COMPLETE = 1;
   /// The future has been chained to another future. The result of that
   /// other future becomes the result of this future as well.
-  // TODO(floitsch): we don't really need a special "_CHAINED" state. We could
-  // just use the PENDING_COMPLETE state instead.
+  /// [resultOrListeners] contains the source future.
   static const int _CHAINED = 2;
   /// The future has been completed with a value result.
   static const int _VALUE = 4;
@@ -167,11 +161,6 @@
    * is waiting for the other future to complete, and when it does, this future
    * will complete with the same result.
    * All listeners are forwarded to the other future.
-   *
-   * The cases are disjoint - incomplete and unchained ([_INCOMPLETE]),
-   * incomplete and chained ([_CHAINED]), or completed with value or error
-   * ([_VALUE] or [_ERROR]) - so the field only needs to hold
-   * one value at a time.
    */
   var _resultOrListeners;
 
@@ -187,20 +176,17 @@
     _asyncCompleteError(error, stackTrace);
   }
 
-  bool get _mayComplete => _state == _INCOMPLETE;
-  bool get _isChained => _state == _CHAINED;
-  bool get _isComplete => _state >= _VALUE;
-  bool get _hasValue => _state == _VALUE;
-  bool get _hasError => _state == _ERROR;
+  bool get _mayComplete       => _state == _INCOMPLETE;
+  bool get _isPendingComplete => _state == _PENDING_COMPLETE;
+  bool get _mayAddListener    => _state <= _PENDING_COMPLETE;
+  bool get _isChained         => _state == _CHAINED;
+  bool get _isComplete        => _state >= _VALUE;
+  bool get _hasError          => _state == _ERROR;
 
-  set _isChained(bool value) {
-    if (value) {
-      assert(!_isComplete);
-      _state = _CHAINED;
-    } else {
-      assert(_isChained);
-      _state = _INCOMPLETE;
-    }
+  void _setChained(_Future source) {
+    assert(_mayAddListener);
+    _state = _CHAINED;
+    _resultOrListeners = source;
   }
 
   Future then(f(T value), { Function onError }) {
@@ -242,18 +228,18 @@
 
   Stream<T> asStream() => new Stream<T>.fromFuture(this);
 
-  void _markPendingCompletion() {
-    if (!_mayComplete) throw new StateError("Future already completed");
+  void _setPendingComplete() {
+    assert(_mayComplete);
     _state = _PENDING_COMPLETE;
   }
 
-  T get _value {
-    assert(_isComplete && _hasValue);
+  AsyncError get _error {
+    assert(_hasError);
     return _resultOrListeners;
   }
 
-  AsyncError get _error {
-    assert(_isComplete && _hasError);
+  _Future get _chainSource {
+    assert(_isChained);
     return _resultOrListeners;
   }
 
@@ -274,16 +260,70 @@
     _setErrorObject(new AsyncError(error, stackTrace));
   }
 
+  /// Copy the completion result of [source] into this future.
+  ///
+  /// Used when a chained future notices that its source is completed.
+  void _cloneResult(_Future source) {
+    assert(!_isComplete);
+    assert(source._isComplete);
+    _state = source._state;
+    _resultOrListeners = source._resultOrListeners;
+  }
+
   void _addListener(_FutureListener listener) {
     assert(listener._nextListener == null);
-    if (_isComplete) {
+    if (_mayAddListener) {
+      listener._nextListener = _resultOrListeners;
+      _resultOrListeners = listener;
+    } else {
+      if (_isChained) {
+        // Delegate listeners to chained source future.
+        // If the source is complete, instead copy its values and
+        // drop the chaining.
+        _Future source = _chainSource;
+        if (!source._isComplete) {
+          source._addListener(listener);
+          return;
+        }
+        _cloneResult(source);
+      }
+      assert(_isComplete);
       // Handle late listeners asynchronously.
       _zone.scheduleMicrotask(() {
         _propagateToListeners(this, listener);
       });
+    }
+  }
+
+  void _prependListeners(_FutureListener listeners) {
+    if (listeners == null) return;
+    if (_mayAddListener) {
+      _FutureListener existingListeners = _resultOrListeners;
+      _resultOrListeners = listeners;
+      if (existingListeners != null) {
+        _FutureListener cursor = listeners;
+        while (cursor._nextListener != null) {
+          cursor = cursor._nextListener;
+        }
+        cursor._nextListener = existingListeners;
+      }
     } else {
-      listener._nextListener = _resultOrListeners;
-      _resultOrListeners = listener;
+      if (_isChained) {
+        // Delegate listeners to chained source future.
+        // If the source is complete, instead copy its values and
+        // drop the chaining.
+        _Future source = _chainSource;
+        if (!source._isComplete) {
+          source._prependListeners(listeners);
+          return;
+        }
+        _cloneResult(source);
+      }
+      assert(_isComplete);
+      listeners = _reverseListeners(listeners);
+      _zone.scheduleMicrotask(() {
+        _propagateToListeners(this, listeners);
+      });
     }
   }
 
@@ -293,7 +333,12 @@
     assert(!_isComplete);
     _FutureListener current = _resultOrListeners;
     _resultOrListeners = null;
+    return _reverseListeners(current);
+  }
+
+  _FutureListener _reverseListeners(_FutureListener listeners) {
     _FutureListener prev = null;
+    _FutureListener current = listeners;
     while (current != null) {
       _FutureListener next = current._nextListener;
       current._nextListener = prev;
@@ -304,17 +349,18 @@
   }
 
   // Take the value (when completed) of source and complete target with that
-  // value (or error). This function can chain all Futures, but is slower
-  // for _Future than _chainCoreFuture - Use _chainCoreFuture in that case.
+  // value (or error). This function could chain all Futures, but is slower
+  // for _Future than _chainCoreFuture, so you must use _chainCoreFuture
+  // in that case.
   static void _chainForeignFuture(Future source, _Future target) {
     assert(!target._isComplete);
     assert(source is! _Future);
 
     // Mark the target as chained (and as such half-completed).
-    target._isChained = true;
+    target._setPendingComplete();
     try {
       source.then((value) {
-          assert(target._isChained);
+          assert(target._isPendingComplete);
           target._completeWithValue(value);
         },
         // TODO(floitsch): eventually we would like to make this non-optional
@@ -322,7 +368,7 @@
         // the target future's listeners want to have the stack trace we don't
         // need a trace.
         onError: (error, [stackTrace]) {
-          assert(target._isChained);
+          assert(target._isPendingComplete);
           target._completeError(error, stackTrace);
         });
     } catch (e, s) {
@@ -339,16 +385,18 @@
   // Take the value (when completed) of source and complete target with that
   // value (or error). This function expects that source is a _Future.
   static void _chainCoreFuture(_Future source, _Future target) {
-    assert(!target._isComplete);
-    assert(source is _Future);
-
-    // Mark the target as chained (and as such half-completed).
-    target._isChained = true;
-    _FutureListener listener = new _FutureListener.chain(target);
+    assert(target._mayAddListener);  // Not completed, not already chained.
+    while (source._isChained) {
+      source = source._chainSource;
+    }
     if (source._isComplete) {
-      _propagateToListeners(source, listener);
+      _FutureListener listeners = target._removeListeners();
+      target._cloneResult(source);
+      _propagateToListeners(target, listeners);
     } else {
-      source._addListener(listener);
+      _FutureListener listeners = target._resultOrListeners;
+      target._setChained(source);
+      source._prependListeners(listeners);
     }
   }
 
@@ -404,10 +452,10 @@
       Future<T> typedFuture = value;
       if (typedFuture is _Future) {
         _Future<T> coreFuture = typedFuture;
-        if (coreFuture._isComplete && coreFuture._hasError) {
+        if (coreFuture._hasError) {
           // Case 1 from above. Delay completion to enable the user to register
           // callbacks.
-          _markPendingCompletion();
+          _setPendingComplete();
           _zone.scheduleMicrotask(() {
             _chainCoreFuture(coreFuture, this);
           });
@@ -423,9 +471,10 @@
       return;
     } else {
       T typedValue = value;
+      assert(typedValue is T);  // Avoid warning that typedValue is unused.
     }
 
-    _markPendingCompletion();
+    _setPendingComplete();
     _zone.scheduleMicrotask(() {
       _completeWithValue(value);
     });
@@ -434,7 +483,7 @@
   void _asyncCompleteError(error, StackTrace stackTrace) {
     assert(!_isComplete);
 
-    _markPendingCompletion();
+    _setPendingComplete();
     _zone.scheduleMicrotask(() {
       _completeError(error, stackTrace);
     });
@@ -466,22 +515,21 @@
         _propagateToListeners(source, listener);
       }
       _FutureListener listener = listeners;
+      final sourceResult = source._resultOrListeners;
       // Do the actual propagation.
-      // Set initial state of listenerHasValue and listenerValueOrError. These
-      // variables are updated, with the outcome of potential callbacks.
-      bool listenerHasValue = true;
-      final sourceValue = hasError ? null : source._value;
-      var listenerValueOrError = sourceValue;
-      // Set to true if a whenComplete needs to wait for a future.
-      // The whenComplete action will resume the propagation by itself.
-      bool isPropagationAborted = false;
-      // TODO(floitsch): mark the listener as pending completion. Currently
-      // we can't do this, since the markPendingCompletion verifies that
-      // the future is not already marked (or chained).
+      // Set initial state of listenerHasError and listenerValueOrError. These
+      // variables are updated with the outcome of potential callbacks.
+      // Non-error results, including futures, are stored in
+      // listenerValueOrError and listenerHasError is set to false. Errors
+      // are stored in listenerValueOrError as an [AsyncError] and
+      // listenerHasError is set to true.
+      bool listenerHasError = hasError;
+      var listenerValueOrError = sourceResult;
+
       // Only if we either have an error or callbacks, go into this, somewhat
       // expensive, branch. Here we'll enter/leave the zone. Many futures
-      // doesn't have callbacks, so this is a significant optimization.
-      if (hasError || (listener.handlesValue || listener.handlesComplete)) {
+      // don't have callbacks, so this is a significant optimization.
+      if (hasError || listener.handlesValue || listener.handlesComplete) {
         Zone zone = listener._zone;
         if (hasError && !source._zone.inSameErrorZone(zone)) {
           // Don't cross zone boundaries with errors.
@@ -497,14 +545,15 @@
           oldZone = Zone._enter(zone);
         }
 
-        bool handleValueCallback() {
+        void handleValueCallback() {
+          assert(!hasError);
           try {
             listenerValueOrError = zone.runUnary(listener._onValue,
-                                                 sourceValue);
-            return true;
+                                                 sourceResult);
+            listenerHasError = false;
           } catch (e, s) {
             listenerValueOrError = new AsyncError(e, s);
-            return false;
+            listenerHasError = true;
           }
         }
 
@@ -516,9 +565,10 @@
             try {
               matchesTest = zone.runUnary(test, asyncError.error);
             } catch (e, s) {
-              listenerValueOrError = identical(asyncError.error, e) ?
-                  asyncError : new AsyncError(e, s);
-              listenerHasValue = false;
+              listenerValueOrError = identical(asyncError.error, e)
+                  ? asyncError
+                  : new AsyncError(e, s);
+              listenerHasError = true;
               return;
             }
           }
@@ -533,21 +583,18 @@
                 listenerValueOrError = zone.runUnary(errorCallback,
                                                      asyncError.error);
               }
+              listenerHasError = false;
             } catch (e, s) {
-              listenerValueOrError = identical(asyncError.error, e) ?
-                  asyncError : new AsyncError(e, s);
-              listenerHasValue = false;
-              return;
+              listenerValueOrError = identical(asyncError.error, e)
+                  ? asyncError
+                  : new AsyncError(e, s);
+              listenerHasError = true;
             }
-            listenerHasValue = true;
-          } else {
-            // Copy over the error from the source.
-            listenerValueOrError = asyncError;
-            listenerHasValue = false;
           }
         }
 
         void handleWhenCompleteCallback() {
+          assert(!listener.handlesError);
           var completeResult;
           try {
             completeResult = zone.run(listener._whenCompleteAction);
@@ -557,59 +604,59 @@
             } else {
               listenerValueOrError = new AsyncError(e, s);
             }
-            listenerHasValue = false;
+            listenerHasError = true;
             return;
           }
           if (completeResult is Future) {
-            _Future result = listener.result;
-            result._isChained = true;
-            isPropagationAborted = true;
-            completeResult.then((ignored) {
-              _propagateToListeners(source, new _FutureListener.chain(result));
-            }, onError: (error, [stackTrace]) {
-              // When there is an error, we have to make the error the new
-              // result of the current listener.
-              if (completeResult is! _Future) {
-                // This should be a rare case.
-                completeResult = new _Future();
-                completeResult._setError(error, stackTrace);
+            if (completeResult is _Future && completeResult._isComplete) {
+              if (completeResult._hasError) {
+                listenerValueOrError = completeResult._error;
+                listenerHasError = true;
               }
-              _propagateToListeners(completeResult,
-                                    new _FutureListener.chain(result));
-            });
+              // Otherwise use the existing result of source.
+              return;
+            }
+            // We have to wait for the completeResult future to complete
+            // before knowing if it's an error or we should use the result
+            // of source.
+            var originalSource = source;
+            listenerValueOrError = completeResult.then((_) => originalSource);
+            listenerHasError = false;
           }
         }
 
-        if (!hasError) {
+        if (listener.handlesComplete) {
+          // The whenComplete-handler is not combined with normal value/error
+          // handling. This means at most one handleX method is called per
+          // listener.
+          assert(!listener.handlesValue);
+          assert(!listener.handlesError);
+          handleWhenCompleteCallback();
+        } else if (!hasError) {
           if (listener.handlesValue) {
-            listenerHasValue = handleValueCallback();
+            handleValueCallback();
           }
         } else {
-          handleError();
+          if (listener.handlesError) {
+            handleError();
+          }
         }
-        if (listener.handlesComplete) {
-          handleWhenCompleteCallback();
-        }
+
         // If we changed zone, oldZone will not be null.
         if (oldZone != null) Zone._leave(oldZone);
 
-        if (isPropagationAborted) return;
         // If the listener's value is a future we need to chain it. Note that
-        // this can only happen if there is a callback. Since 'is' checks
-        // can be expensive, we're trying to avoid it.
-        if (listenerHasValue &&
-            !identical(sourceValue, listenerValueOrError) &&
-            listenerValueOrError is Future) {
+        // this can only happen if there is a callback.
+        if (listenerValueOrError is Future) {
           Future chainSource = listenerValueOrError;
           // Shortcut if the chain-source is already completed. Just continue
           // the loop.
           _Future result = listener.result;
           if (chainSource is _Future) {
             if (chainSource._isComplete) {
-              // propagate the value (simulating a tail call).
-              result._isChained = true;
+              listeners = result._removeListeners();
+              result._cloneResult(chainSource);
               source = chainSource;
-              listeners = new _FutureListener.chain(result);
               continue;
             } else {
               _chainCoreFuture(chainSource, result);
@@ -622,7 +669,7 @@
       }
       _Future result = listener.result;
       listeners = result._removeListeners();
-      if (listenerHasValue) {
+      if (!listenerHasError) {
         result._setValue(listenerValueOrError);
       } else {
         AsyncError asyncError = listenerValueOrError;
diff --git a/sdk/lib/async/schedule_microtask.dart b/sdk/lib/async/schedule_microtask.dart
index acc4036..fac3f7f 100644
--- a/sdk/lib/async/schedule_microtask.dart
+++ b/sdk/lib/async/schedule_microtask.dart
@@ -8,9 +8,8 @@
 
 class _AsyncCallbackEntry {
   final _AsyncCallback callback;
-  final Zone zone;
   _AsyncCallbackEntry next;
-  _AsyncCallbackEntry(this.callback, this.zone);
+  _AsyncCallbackEntry(this.callback);
 }
 
 /** Head of single linked list of pending callbacks. */
@@ -39,23 +38,21 @@
     _AsyncCallbackEntry entry = _nextCallback;
     _nextCallback = entry.next;
     if (_nextCallback == null) _lastCallback = null;
-    Zone._current = entry.zone;
-    entry.callback();
+    (entry.callback)();
   }
 }
 
-void _microtaskLoopEntry() {
+void _startMicrotaskLoop() {
   _isInCallbackLoop = true;
   try {
     // Moved to separate function because try-finally prevents
     // good optimization.
     _microtaskLoop();
   } finally {
-    Zone._current = _ROOT_ZONE;
     _lastPriorityCallback = null;
     _isInCallbackLoop = false;
     if (_nextCallback != null) {
-      _AsyncRun._scheduleImmediate(_microtaskLoopEntry);
+      _AsyncRun._scheduleImmediate(_startMicrotaskLoop);
     }
   }
 }
@@ -66,11 +63,12 @@
  * The microtask is called after all other currently scheduled
  * microtasks, but as part of the current system event.
  */
-void _scheduleAsyncCallback(_AsyncCallbackEntry newEntry) {
+void _scheduleAsyncCallback(_AsyncCallback callback) {
+  _AsyncCallbackEntry newEntry = new _AsyncCallbackEntry(callback);
   if (_nextCallback == null) {
     _nextCallback = _lastCallback = newEntry;
     if (!_isInCallbackLoop) {
-      _AsyncRun._scheduleImmediate(_microtaskLoopEntry);
+      _AsyncRun._scheduleImmediate(_startMicrotaskLoop);
     }
   } else {
     _lastCallback.next = newEntry;
@@ -87,12 +85,13 @@
  * Is always run in the root zone.
  */
 void _schedulePriorityAsyncCallback(callback) {
-  _AsyncCallbackEntry entry =
-      new _AsyncCallbackEntry(callback, _ROOT_ZONE);
   if (_nextCallback == null) {
-    _scheduleAsyncCallback(entry);
+    _scheduleAsyncCallback(callback);
     _lastPriorityCallback = _lastCallback;
-  } else if (_lastPriorityCallback == null) {
+    return;
+  }
+  _AsyncCallbackEntry entry = new _AsyncCallbackEntry(callback);
+  if (_lastPriorityCallback == null) {
     entry.next = _nextCallback;
     _nextCallback = _lastPriorityCallback = entry;
   } else {
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 232d8db..c2b6c68 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -113,6 +113,47 @@
   }
 
   /**
+   * Create a stream from a group of futures.
+   *
+   * The stream reports the results of the futures on the stream in the order
+   * in which the futures complete.
+   *
+   * If some futures have completed before calling `Stream.fromFutures`,
+   * their result will be output on the created stream in some unspecified
+   * order.
+   *
+   * When all futures have completed, the stream is closed.
+   *
+   * If no future is passed, the stream closes as soon as possible.
+   */
+  factory Stream.fromFutures(Iterable<Future<T>> futures) {
+    var controller = new StreamController<T>(sync: true);
+    int count = 0;
+    var onValue = (value) {
+      if (!controller.isClosed) {
+        controller._add(value);
+        if (--count == 0) controller._closeUnchecked();
+      }
+    };
+    var onError = (error, stack) {
+      if (!controller.isClosed) {
+        controller._addError(error, stack);
+        if (--count == 0) controller._closeUnchecked();
+      }
+    };
+    // The futures are already running, so start listening to them immediately
+    // (instead of waiting for the stream to be listened on).
+    // If we wait, we might not catch errors in the futures in time.
+    for (var future in futures) {
+      count++;
+      future.then(onValue, onError: onError);
+    }
+    // Use schedule microtask since controller is sync.
+    if (count == 0) scheduleMicrotask(controller.close);
+    return controller.stream;
+  }
+
+  /**
    * Creates a single-subscription stream that gets its data from [data].
    *
    * The iterable is iterated when the stream receives a listener, and stops
@@ -139,8 +180,6 @@
    */
   factory Stream.periodic(Duration period,
                           [T computation(int computationCount)]) {
-    if (computation == null) computation = ((i) => null);
-
     Timer timer;
     int computationCount = 0;
     StreamController<T> controller;
@@ -149,7 +188,15 @@
 
     void sendEvent() {
       watch.reset();
-      T data = computation(computationCount++);
+      T data;
+      if (computation != null) {
+        try {
+          data = computation(computationCount++);
+        } catch (e, s) {
+          controller.addError(e, s);
+          return;
+        }
+      }
       controller.add(data);
     }
 
@@ -307,12 +354,20 @@
    * Creates a new stream that converts each element of this stream
    * to a new value using the [convert] function.
    *
+   * For each data event, `o`, in this stream, the returned stream
+   * provides a data event with the value `convert(o)`.
+   * If [convert] throws, the returned stream reports the exception as an error
+   * event instead.
+   *
+   * Error and done events are passed through unchanged to the returned stream.
+   *
    * The returned stream is a broadcast stream if this stream is.
+   * The [convert] function is called once per data event per listener.
    * If a broadcast stream is listened to more than once, each subscription
-   * will individually execute `map` for each event.
+   * will individually call [convert] on each data event.
    */
-  Stream map(convert(T event)) {
-    return new _MapStream<T, dynamic>(this, convert);
+  Stream/*<S>*/ map/*<S>*/(/*=S*/ convert(T event)) {
+    return new _MapStream<T, dynamic/*=S*/>(this, convert);
   }
 
   /**
@@ -473,8 +528,8 @@
    * If a broadcast stream is listened to more than once, each subscription
    * will individually call `convert` and expand the events.
    */
-  Stream expand(Iterable convert(T value)) {
-    return new _ExpandStream<T, dynamic>(this, convert);
+  Stream/*<S>*/ expand(Iterable/*<S>*/ convert(T value)) {
+    return new _ExpandStream<T, dynamic/*=S*/>(this, convert);
   }
 
   /**
@@ -548,7 +603,9 @@
   }
 
   /** Reduces a sequence of values by repeatedly applying [combine]. */
-  Future fold(var initialValue, combine(var previous, T element)) {
+  Future/*<S>*/ fold/*<S>*/(var/*=S*/ initialValue,
+      /*=S*/ combine(var/*=S*/ previous, T element)) {
+
     _Future result = new _Future();
     var value = initialValue;
     StreamSubscription subscription;
@@ -898,7 +955,7 @@
    * Skips data events if they are equal to the previous data event.
    *
    * The returned stream provides the same events as this stream, except
-   * that it never provides two consequtive data events that are equal.
+   * that it never provides two consecutive data events that are equal.
    *
    * Equality is determined by the provided [equals] method. If that is
    * omitted, the '==' operator on the last provided data element is used.
@@ -1451,7 +1508,7 @@
 /**
  * Abstract interface for a "sink" accepting multiple entire streams.
  *
- * A consumer can accept a number of consequtive streams using [addStream],
+ * A consumer can accept a number of consecutive streams using [addStream],
  * and when no further data need to be added, the [close] method tells the
  * consumer to complete its work and shut down.
  *
@@ -1485,7 +1542,7 @@
   Future addStream(Stream<S> stream);
 
   /**
-   * Tells the consumer that no futher streams will be added.
+   * Tells the consumer that no further streams will be added.
    *
    * This allows the consumer to complete any remaining work and release
    * resources that are no longer needed
@@ -1519,7 +1576,7 @@
  */
 abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
   /**
-   * Tells the stream sink that no futher streams will be added.
+   * Tells the stream sink that no further streams will be added.
    *
    * This allows the stream sink to complete any remaining work and release
    * resources that are no longer needed
@@ -1622,9 +1679,9 @@
    *                 onDone: controller.close,
    *                 cancelOnError: cancelOnError);
    *             },
-   *             onPause: () => subscription.pause(),
-   *             onResume: () => subscription.resume(),
-   *             onCancel: () => subscription.cancel(),
+   *             onPause: () { subscription.pause(); },
+   *             onResume: () { subscription.resume(); },
+   *             onCancel: () { subscription.cancel(); },
    *             sync: true);
    *           return controller.stream.listen(null);
    *         });
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 2520f4d..d84f01b 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -958,7 +958,7 @@
     // Use root zone as event zone if the function is already bound.
     zone = _ROOT_ZONE;
   }
-  _scheduleAsyncCallback(new _AsyncCallbackEntry(f, zone));
+  _scheduleAsyncCallback(f);
 }
 
 Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone,
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index fb9a94b..5756544 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -12,7 +12,13 @@
  */
 class UnmodifiableListView<E> extends UnmodifiableListBase<E> {
   final Iterable<E> _source;
-  /** Create an unmodifiable list backed by [source]. */
+
+  /**
+   * Creates an unmodifiable list backed by [source].
+   *
+   * The [source] of the elements may be a [List] or any [Iterable] with
+   * efficient [Iterable.length] and [Iterable.elementAt].
+   */
   UnmodifiableListView(Iterable<E> source) : _source = source;
   int get length => _source.length;
   E operator[](int index) => _source.elementAt(index);
diff --git a/sdk/lib/collection/iterable.dart b/sdk/lib/collection/iterable.dart
index e89acc6f..c0d2ee0 100644
--- a/sdk/lib/collection/iterable.dart
+++ b/sdk/lib/collection/iterable.dart
@@ -15,12 +15,13 @@
   // - SetMixin
   // If changing a method here, also change the other copies.
 
-  Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+  Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) =>
+      new MappedIterable<E, dynamic/*=T*/>(this, f);
 
   Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
 
-  Iterable expand(Iterable f(E element)) =>
-      new ExpandIterable<E, dynamic>(this, f);
+  Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element)) =>
+      new ExpandIterable<E, dynamic/*=T*/>(this, f);
 
   bool contains(Object element) {
     for (E e in this) {
@@ -45,8 +46,8 @@
     return value;
   }
 
-  dynamic fold(var initialValue,
-               dynamic combine(var previousValue, E element)) {
+  dynamic/*=T*/ fold/*<T>*/(var/*=T*/ initialValue,
+               dynamic/*=T*/ combine(var/*=T*/ previousValue, E element)) {
     var value = initialValue;
     for (E element in this) value = combine(value, element);
     return value;
diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart
index 77f7158..66c1f0c 100644
--- a/sdk/lib/convert/base64.dart
+++ b/sdk/lib/convert/base64.dart
@@ -307,12 +307,12 @@
 class Base64Decoder extends Converter<String, List<int>> {
   const Base64Decoder();
 
-  List<int> convert(String input) {
-    if (input.isEmpty) return new Uint8List(0);
-    int length = input.length;
+  List<int> convert(String input, [int start = 0, int end]) {
+    end = RangeError.checkValidRange(start, end, input.length);
+    if (start == end) return new Uint8List(0);
     var decoder = new _Base64Decoder();
-    Uint8List buffer = decoder.decode(input, 0, input.length);
-    decoder.close(input, input.length);
+    Uint8List buffer = decoder.decode(input, start, end);
+    decoder.close(input, end);
     return buffer;
   }
 
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 8b1a1e0..287d8ec 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -335,7 +335,7 @@
     // of codeUnits.
     String result = _convertIntercepted(_allowMalformed, codeUnits, start, end);
     if (result != null) {
-      return null;
+      return result;
     }
 
     int length = codeUnits.length;
diff --git a/sdk/lib/core/annotations.dart b/sdk/lib/core/annotations.dart
index 5ceed34..6a596c6 100644
--- a/sdk/lib/core/annotations.dart
+++ b/sdk/lib/core/annotations.dart
@@ -113,26 +113,37 @@
 }
 
 /**
- * The annotation `@proxy` marks a class as implementing interfaces and members
- * dynamically through `noSuchMethod`.
+ * The annotation `@proxy` marks a class as implementing members dynamically
+ * through `noSuchMethod`.
  *
  * The annotation applies to any class. It is inherited by subclasses from both
  * superclass and interfaces.
  *
  * If a class is annotated with `@proxy`, or it implements any class that is
- * annotated, then the class is considered to implement any interface and
- * any member with regard to static type analysis. As such, it is not a static
- * type warning to assign the object to a variable of any type, and it is not
- * a static type warning to access any member of the object.
+ * annotated, then the class is considered to implement any member with regard
+ * to static type analysis.
+ * As such, it is not a static type warning to access any member of the object
+ * which is not implemented by the class, or to call a method with a different
+ * number of parameters than it is declared with.
  *
- * This only applies to static type warnings. The runtime type of the object
- * is unaffected. It is not considered to implement any special interfaces at
- * runtime, so assigning it to a typed variable may fail in checked mode, and
- * testing it with the `is` operator will not work for any type except the
- * ones it actually implements.
+ * The annotation does not change which classes the annotated class implements,
+ * and does not prevent static warnings for assigning an object to a variable
+ * with a static type not implemented by the object.
  *
- * Tools that understand `@proxy` should tell the user if a class using `@proxy`
- * does not override the `noSuchMethod` declared on [Object].
+ * The suppression of warnings only affect static type warnings about
+ * member access.
+ * The runtime type of the object is unaffected.
+ * It is not considered to implement any special interfaces,
+ * so assigning it to a typed variable may fail in checked mode,
+ * and testing it with the `is` operator
+ * will only return true for types it actually implements or extends.
+ * Accessing a member which isn't implemented by the classs
+ * will cause the `noSuchMethod` method to be called normally,
+ * the `@proxy` annotation merely states the intent to handle (some of) those
+ * `noSuchMethod` calls gracefully.
+ *
+ * A class that marked as `@proxy` should override the `noSuchMethod`
+ * declared on [Object].
  *
  * The intent of the `@proxy` notation is to create objects that implement a
  * type (or multiple types) that are not known at compile time. If the types
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index a33c8fa..3bd3dab 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -137,13 +137,13 @@
  *
  * ## Other documentation
  *
- * For more information about how to use the built-in types, refer to
- * [Built-in Types](http://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#built-in-types)
+ * For more information about how to use the built-in types, refer to [Built-in
+ * Types](http://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#built-in-types)
  * in Chapter 2 of
  * [Dart: Up and Running](http://www.dartlang.org/docs/dart-up-and-running/).
  *
- * Also, see
- * [dart:core - Numbers, Collections, Strings, and More](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartcore---strings-collections-and-more)
+ * Also, see [dart:core - Numbers, Collections, Strings, and
+ * More](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartcore---numbers-collections-strings-and-more)
  * for more coverage of classes in this package.
  *
  * The
@@ -155,9 +155,12 @@
 import "dart:collection";
 import "dart:_internal" hide Symbol;
 import "dart:_internal" as internal show Symbol;
-import "dart:convert" show UTF8, LATIN1, Encoding;
+import "dart:convert" show
+  Encoding, ASCII, LATIN1, UTF8,
+  BASE64, StringConversionSink, ChunkedConversionSink;
 import "dart:math" show Random;  // Used by List.shuffle.
 import "dart:async" show Stream, Future;  // Used by Resource.
+import "dart:typed_data" show Uint8List;
 
 part "annotations.dart";
 part "bool.dart";
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 1e89080..28ece3f 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -129,17 +129,13 @@
   static const int MONTHS_PER_YEAR = 12;
 
   /**
-   * The number of milliseconds since
-   * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+   * The value of this DateTime.
    *
-   * This value is independent of the time zone.
-   *
-   * This value is at most
-   * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
-   * In other words: [:millisecondsSinceEpoch.abs() <= 8640000000000000:].
-   *
+   * The content of this field is implementation dependent. On JavaScript it is
+   * equal to [millisecondsSinceEpoch]. On the VM it is equal to
+   * [microsecondsSinceEpoch].
    */
-  final int millisecondsSinceEpoch;
+  final int _value;
 
   /**
    * True if this [DateTime] is set to UTC time.
@@ -164,9 +160,11 @@
             int hour = 0,
             int minute = 0,
             int second = 0,
-            int millisecond = 0])
+            int millisecond = 0,
+            int microsecond = 0])
       : this._internal(
-            year, month, day, hour, minute, second, millisecond, false);
+            year, month, day, hour, minute, second, millisecond, microsecond,
+            false);
 
   /**
    * Constructs a [DateTime] instance specified in the UTC time zone.
@@ -179,9 +177,11 @@
                 int hour = 0,
                 int minute = 0,
                 int second = 0,
-                int millisecond = 0])
+                int millisecond = 0,
+                int microsecond = 0])
     : this._internal(
-          year, month, day, hour, minute, second, millisecond, true);
+          year, month, day, hour, minute, second, millisecond, microsecond,
+          true);
 
   /**
    * Constructs a [DateTime] instance with current date and time in the
@@ -256,7 +256,7 @@
      * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt
      * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt
      * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt
-     * millis_opt ::= <empty> | '.' digit{1,6}
+     * micros_opt ::= <empty> | '.' digit{1,6}
      * timezone_opt ::= <empty> | space_opt timezone
      * space_opt :: ' ' | <empty>
      * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt
@@ -274,35 +274,20 @@
         return int.parse(matched);
       }
 
-      // Parses fractional second digits of '.(\d{1,6})' into milliseconds.
-      // Uses first three digits (assumed to be zero if not there), and
-      // rounds up if fourth digit is 5 or greater.
-      // Should be equivalent to `(double.parse(".$matchd")*1000).round()`.
-      int parseMilliseconds(String matched) {
+      // Parses fractional second digits of '.(\d{1,6})' into the combined
+      // microseconds.
+      int parseMilliAndMicroseconds(String matched) {
         if (matched == null) return 0;
         int length = matched.length;
         assert(length >= 1);
         assert(length <= 6);
 
-        int result = (matched.codeUnitAt(0) ^ 0x30);
-        if (length <= 3) {
-          int i = 1;
-          while (i < length) {
-            result *= 10;
+        int result = 0;
+        for (int i = 0; i < 6; i++) {
+          result *= 10;
+          if (i < matched.length) {
             result += matched.codeUnitAt(i) ^ 0x30;
-            i++;
           }
-          while (i < 3) {
-            result *= 10;
-            i++;
-          }
-          return result;
-        }
-        // Parse the prefix from 0..3 without creating a new substring.
-        result = result * 10 + (matched.codeUnitAt(1) ^ 0x30);
-        result = result * 10 + (matched.codeUnitAt(2) ^ 0x30);
-        if (matched.codeUnitAt(3) >= 0x35) {
-          result += 1;
         }
         return result;
       }
@@ -314,11 +299,11 @@
       int minute = parseIntOrZero(match[5]);
       int second = parseIntOrZero(match[6]);
       bool addOneMillisecond = false;
-      int millisecond = parseMilliseconds(match[7]);
-      if (millisecond == 1000) {
-        addOneMillisecond = true;
-        millisecond = 999;
-      }
+      int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]);
+      int millisecond =
+          milliAndMicroseconds ~/ Duration.MICROSECONDS_PER_MILLISECOND;
+      int microsecond =
+          milliAndMicroseconds.remainder(Duration.MICROSECONDS_PER_MILLISECOND);
       bool isUtc = false;
       if (match[8] != null) {  // timezone part
         isUtc = true;
@@ -331,14 +316,13 @@
           minute -= sign * minuteDifference;
         }
       }
-      int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
-          years, month, day, hour, minute, second, millisecond, isUtc);
-      if (millisecondsSinceEpoch == null) {
+      int value = _brokenDownDateToValue(
+          years, month, day, hour, minute, second, millisecond, microsecond,
+          isUtc);
+      if (value == null) {
         throw new FormatException("Time out of range", formattedString);
       }
-      if (addOneMillisecond) millisecondsSinceEpoch++;
-      return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
-                                                     isUtc: isUtc);
+      return new DateTime._withValue(value, isUtc: isUtc);
     } else {
       throw new FormatException("Invalid date format", formattedString);
     }
@@ -356,11 +340,31 @@
    * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given
    * time zone (local or UTC).
    */
-  DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
-                                      {bool isUtc: false})
-      : this.millisecondsSinceEpoch = millisecondsSinceEpoch,
-        this.isUtc = isUtc {
-    if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) {
+  external DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+                                              {bool isUtc: false});
+
+  /**
+   * Constructs a new [DateTime] instance
+   * with the given [microsecondsSinceEpoch].
+   *
+   * If [isUtc] is false then the date is in the local time zone.
+   *
+   * The constructed [DateTime] represents
+   * 1970-01-01T00:00:00Z + [microsecondsSinceEpoch] us in the given
+   * time zone (local or UTC).
+   */
+  external DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+                                               {bool isUtc: false});
+
+  /**
+   * Constructs a new [DateTime] instance with the given value.
+   *
+   * If [isUtc] is false then the date is in the local time zone.
+   */
+  DateTime._withValue(this._value, {this.isUtc}) {
+    if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH ||
+        (millisecondsSinceEpoch.abs() == _MAX_MILLISECONDS_SINCE_EPOCH &&
+         microsecond != 0)) {
       throw new ArgumentError(millisecondsSinceEpoch);
     }
     if (isUtc == null) throw new ArgumentError(isUtc);
@@ -379,8 +383,7 @@
    */
   bool operator ==(other) {
     if (!(other is DateTime)) return false;
-    return (millisecondsSinceEpoch == other.millisecondsSinceEpoch &&
-            isUtc == other.isUtc);
+    return (_value == other._value && isUtc == other.isUtc);
   }
 
   /**
@@ -396,7 +399,7 @@
    *
    */
   bool isBefore(DateTime other) {
-    return millisecondsSinceEpoch < other.millisecondsSinceEpoch;
+    return _value < other._value;
   }
 
   /**
@@ -412,7 +415,7 @@
    *
    */
   bool isAfter(DateTime other) {
-    return millisecondsSinceEpoch > other.millisecondsSinceEpoch;
+    return _value > other._value;
   }
 
   /**
@@ -427,7 +430,7 @@
    *     assert(berlinWallFell.isAtSameMomentAs(moonLanding) == false);
    */
   bool isAtSameMomentAs(DateTime other) {
-    return millisecondsSinceEpoch == other.millisecondsSinceEpoch;
+    return _value == other._value;
   }
 
   /**
@@ -438,10 +441,9 @@
    * if this DateTime is smaller (earlier) than [other],
    * or a positive integer if it is greater (later).
    */
-  int compareTo(DateTime other)
-      => millisecondsSinceEpoch.compareTo(other.millisecondsSinceEpoch);
+  int compareTo(DateTime other) => _value.compareTo(other._value);
 
-  int get hashCode => millisecondsSinceEpoch;
+  int get hashCode => (_value ^ (_value >> 30)) & 0x3FFFFFFF;
 
   /**
    * Returns this DateTime value in the local time zone.
@@ -449,13 +451,12 @@
    * Returns [this] if it is already in the local time zone.
    * Otherwise this method is equivalent to:
    *
-   *     new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
+   *     new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
    *                                             isUtc: false)
    */
   DateTime toLocal() {
     if (isUtc) {
-      return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
-                                                     isUtc: false);
+      return new DateTime._withValue(_value, isUtc: false);
     }
     return this;
   }
@@ -466,13 +467,12 @@
    * Returns [this] if it is already in UTC.
    * Otherwise this method is equivalent to:
    *
-   *     new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
+   *     new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
    *                                             isUtc: true)
    */
   DateTime toUtc() {
     if (isUtc) return this;
-    return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
-                                                   isUtc: true);
+    return new DateTime._withValue(_value, isUtc: true);
   }
 
   static String _fourDigits(int n) {
@@ -522,18 +522,19 @@
     String min = _twoDigits(minute);
     String sec = _twoDigits(second);
     String ms = _threeDigits(millisecond);
+    String us = microsecond == 0 ? "" : _threeDigits(microsecond);
     if (isUtc) {
-      return "$y-$m-$d $h:$min:$sec.${ms}Z";
+      return "$y-$m-$d $h:$min:$sec.$ms${us}Z";
     } else {
-      return "$y-$m-$d $h:$min:$sec.$ms";
+      return "$y-$m-$d $h:$min:$sec.$ms$us";
     }
   }
 
   /**
    * Returns an ISO-8601 full-precision extended format representation.
    *
-   * The format is `yyyy-MM-ddTHH:mm:ss.sssZ` for UTC time, and
-   * `yyyy-MM-ddTHH:mm:ss.sss` (no trailing "Z") for local/non-UTC time,
+   * The format is `yyyy-MM-ddTHH:mm:ss.mmmuuuZ` for UTC time, and
+   * `yyyy-MM-ddTHH:mm:ss.mmmuuu` (no trailing "Z") for local/non-UTC time,
    * where:
    *
    * * `yyyy` is a, possibly negative, four digit representation of the year,
@@ -543,8 +544,10 @@
    * * `dd` is the day of the month in the range 01 to 31,
    * * `HH` are hours in the range 00 to 23,
    * * `mm` are minutes in the range 00 to 59,
-   * * `ss` are seconds in the range 00 to 59 (no leap seconds), and
-   * * `sss` are milliseconds in the range 000 to 999.
+   * * `ss` are seconds in the range 00 to 59 (no leap seconds),
+   * * `mmm` are microseconds in the range 000 to 999, and
+   * * `uuu` are microseconds in the range 001 to 999. If [microsecond] equals
+   *   0, then this part is omitted.
    *
    * The resulting string can be parsed back using [parse].
    */
@@ -557,10 +560,11 @@
     String min = _twoDigits(minute);
     String sec = _twoDigits(second);
     String ms = _threeDigits(millisecond);
+    String us = microsecond == 0 ? "" : _threeDigits(microsecond);
     if (isUtc) {
-      return "$y-$m-${d}T$h:$min:$sec.${ms}Z";
+      return "$y-$m-${d}T$h:$min:$sec.$ms${us}Z";
     } else {
-      return "$y-$m-${d}T$h:$min:$sec.$ms";
+      return "$y-$m-${d}T$h:$min:$sec.$ms$us";
     }
   }
 
@@ -570,39 +574,49 @@
    *     DateTime today = new DateTime.now();
    *     DateTime sixtyDaysFromNow = today.add(new Duration(days: 60));
    */
-  DateTime add(Duration duration) {
-    int ms = millisecondsSinceEpoch;
-    return new DateTime.fromMillisecondsSinceEpoch(
-        ms + duration.inMilliseconds, isUtc: isUtc);
-  }
+  external DateTime add(Duration duration);
 
   /**
    * Returns a new [DateTime] instance with [duration] subtracted from [this].
    *
    *     DateTime today = new DateTime.now();
-   *     DateTime sixtyDaysAgo = today.subtract(new Duration(days: 60));
+   *     DateTime sixtyDaysAgo = today.subtract(new Duration(days: 30));
+   *
+   * Notice that duration being subtracted is actually 30 * 24 * 60 * 60 seconds
+   * and if that crosses a daylight saving time change, the resulting `DateTime`
+   * won't have the same time of day as `today`, and may not actually hit the
+   * calendar date 30 days earlier. Be careful when working with dates in local
+   * time.
    */
-  DateTime subtract(Duration duration) {
-    int ms = millisecondsSinceEpoch;
-    return new DateTime.fromMillisecondsSinceEpoch(
-        ms - duration.inMilliseconds, isUtc: isUtc);
-  }
+  external DateTime subtract(Duration duration);
 
   /**
    * Returns a [Duration] with the difference between [this] and [other].
    *
-   *     DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9);
-   *     DateTime dDay = new DateTime(1944, DateTime.JUNE, 6);
+   *     DateTime berlinWallFell = new DateTime.utc(1989, DateTime.NOVEMBER, 9);
+   *     DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6);
    *
    *     Duration difference = berlinWallFell.difference(dDay);
    *     assert(difference.inDays == 16592);
+   *
+   * The difference is measured in seconds and fractions of seconds.
+   * The difference above counts the number of fractional seconds between
+   * midnight at the beginning of those dates.
+   * If the dates above had been in local time, not UTC, then the difference
+   * between two midnights may not be a multiple of 24 hours due to daylight
+   * saving differences.
+   *
+   * For example, in Australia, similar code using local time instead of UTC:
+   *
+   *     DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9);
+   *     DateTime dDay = new DateTime(1944, DateTime.JUNE, 6);
+   *     Duration difference = berlinWallFell.difference(dDay);
+   *     assert(difference.inDays == 16592);
+   *
+   * will fail because the difference is actually 16591 days and 23 hours, and
+   * [Duration.inDays] only returns the number of whole days.
    */
-
-  Duration difference(DateTime other) {
-    int ms = millisecondsSinceEpoch;
-    int otherMs = other.millisecondsSinceEpoch;
-    return new Duration(milliseconds: ms - otherMs);
-  }
+  external Duration difference(DateTime other);
 
   external DateTime._internal(int year,
                               int month,
@@ -611,13 +625,43 @@
                               int minute,
                               int second,
                               int millisecond,
+                              int microsecond,
                               bool isUtc);
+
   external DateTime._now();
-  /// Returns the time as milliseconds since epoch, or null if the
-  /// values are out of range.
-  external static int _brokenDownDateToMillisecondsSinceEpoch(
+
+  /// Returns the time as value (millisecond or microsecond since epoch), or
+  /// null if the values are out of range.
+  external static int _brokenDownDateToValue(
       int year, int month, int day, int hour, int minute, int second,
-      int millisecond, bool isUtc);
+      int millisecond, int microsecond, bool isUtc);
+
+  /**
+   * The number of milliseconds since
+   * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+   *
+   * This value is independent of the time zone.
+   *
+   * This value is at most
+   * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
+   * In other words: `millisecondsSinceEpoch.abs() <= 8640000000000000`.
+   */
+  external int get millisecondsSinceEpoch;
+
+  /**
+   * The number of microseconds since
+   * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+   *
+   * This value is independent of the time zone.
+   *
+   * This value is at most
+   * 8,640,000,000,000,000,000us (100,000,000 days) from the Unix epoch.
+   * In other words: `microsecondsSinceEpoch.abs() <= 8640000000000000000`.
+   *
+   * Note that this value does not fit into 53 bits (the size of a IEEE double).
+   * A JavaScript number is not able to hold this value.
+   */
+  external int get microsecondsSinceEpoch;
 
   /**
    * The abbreviated time zone name&mdash;for example,
@@ -695,6 +739,14 @@
   external int get millisecond;
 
   /**
+   * The microsecond [0...999].
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.microsecond == 0);
+   */
+  external int get microsecond;
+
+  /**
    * The day of the week [MONDAY]..[SUNDAY].
    *
    * In accordance with ISO 8601
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index 0229732..a47838b 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -165,12 +165,11 @@
 
   /**
    * Create an argument error for a `null` argument that must not be `null`.
-   *
-   * Shorthand for calling [ArgumentError.value] with a `null` value and a
-   * message of `"Must not be null"`.
    */
-  ArgumentError.notNull([String name])
-      : this.value(null, name, "Must not be null");
+  ArgumentError.notNull([this.name])
+      : _hasValue = false,
+        message = "Must not be null",
+        invalidValue = null;
 
   // Helper functions for toString overridden in subclasses.
   String get _errorName => "Invalid argument${!_hasValue ? "(s)" : ""}";
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 98f7da8..fdc7727 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -170,7 +170,7 @@
    * non-negative number (i.e. unsigned representation).  The returned value has
    * zeros in all bit positions higher than [width].
    *
-   *     (-1).toUnsigned(5) == 32   // 11111111  ->  00011111
+   *     (-1).toUnsigned(5) == 31   // 11111111  ->  00011111
    *
    * This operation can be used to simulate arithmetic from low level languages.
    * For example, to increment an 8 bit quantity:
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 78efa1b..dd19502 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -156,7 +156,8 @@
    * on any element where the result isn't needed.
    * For example, [elementAt] may call `f` only once.
    */
-  Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+  Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E e)) =>
+      new MappedIterable<E, dynamic/*=T*/>(this, f);
 
   /**
    * Returns a new lazy [Iterable] with all elements that satisfy the
@@ -174,7 +175,7 @@
   Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
 
   /**
-   * Expands each element of this [Iterable]into zero or more elements.
+   * Expands each element of this [Iterable] into zero or more elements.
    *
    * The resulting Iterable runs through the elements returned
    * by [f] for each element of this, in iteration order.
@@ -182,8 +183,8 @@
    * The returned [Iterable] is lazy, and calls [f] for each element
    * of this every time it's iterated.
    */
-  Iterable expand(Iterable f(E element)) =>
-      new ExpandIterable<E, dynamic>(this, f);
+  Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element)) =>
+      new ExpandIterable<E, dynamic/*=T*/>(this, f);
 
   /**
    * Returns true if the collection contains an element equal to [element].
@@ -270,8 +271,8 @@
    *     iterable.fold(0, (prev, element) => prev + element);
    *
    */
-  dynamic fold(var initialValue,
-               dynamic combine(var previousValue, E element)) {
+  dynamic/*=T*/ fold/*<T>*/(var/*=T*/ initialValue,
+               dynamic/*=T*/ combine(var/*=T*/ previousValue, E element)) {
     var value = initialValue;
     for (E element in this) value = combine(value, element);
     return value;
diff --git a/sdk/lib/core/iterator.dart b/sdk/lib/core/iterator.dart
index 34a7f49..cd0ad32 100644
--- a/sdk/lib/core/iterator.dart
+++ b/sdk/lib/core/iterator.dart
@@ -26,10 +26,9 @@
  *       use(it.current);
  *     }
  *
- * **See also:** [Iteration]
- * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-iteration)
- * in the [library tour]
- * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html)
+ * **See also:**
+ * [Iteration](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#iteration)
+ * in the [library tour](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html)
  */
 abstract class Iterator<E> {
   /**
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 50a5f58..9d25927 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -82,9 +82,14 @@
    *
    *     new List<int>.filled(3, 0); // [0, 0, 0]
    *
-   * The [length] must not be negative or null.
+   * The [length] must be a non-negative integer.
+   *
+   * If the list is growable, changing its length will not initialize new
+   * entries with [fill]. After being created and filled, the list is
+   * no different from any other growable or fixed-length list
+   * created using [List].
    */
-  external factory List.filled(int length, E fill);
+  external factory List.filled(int length, E fill, {bool growable: false});
 
   /**
    * Creates a list containing all [elements].
@@ -187,17 +192,26 @@
    *
    * The [compare] function must act as a [Comparator].
    *
-   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     List<String> numbers = ['two', 'three', 'four'];
    *     // Sort from shortest to longest.
-   *     numbers.sort((x, y) => x.length.compareTo(y.length));
-   *     numbers.join(', '); // 'one, two, four, three'
+   *     numbers.sort((a, b) => a.length.compareTo(b.length));
+   *     print(numbers);  // [two, four, three]
    *
    * The default List implementations use [Comparable.compare] if
    * [compare] is omitted.
    *
    *     List<int> nums = [13, 2, -11];
    *     nums.sort();
-   *     nums.join(', '); // '-11, 2, 13'
+   *     print(nums);  // [-11, 2, 13]
+   *
+   * A [Comparator] may compare objects as equal (return zero), even if they
+   * are distinct objects.
+   * The sort function is not guaranteed to be stable, so distinct objects
+   * that compare as equal may occur in any order in the result:
+   *
+   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     numbers.sort((a, b) => a.length.compareTo(b.length));
+   *     print(numbers);  // [one, two, four, three] OR [two, one, four, three]
    */
   void sort([int compare(E a, E b)]);
 
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index 2951a73..ae0431e 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.dart
@@ -13,10 +13,10 @@
  * When you define a class, you should override [toString]
  * to return a string describing an instance of that class.
  * You might also need to define [hashCode] and [==], as described in the
- * [Implementing map keys]
- * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-implementing-map-keys)
- * section of the [library tour]
- * (http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html).
+ * [Implementing map
+ * keys](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#implementing-map-keys)
+ * section of the [library
+ * tour](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html).
  */
 class Object {
   /**
@@ -78,14 +78,13 @@
   external String toString();
 
   /**
-   * [noSuchMethod] is invoked when users invoke a non-existent method
-   * on an object. The name of the method and the arguments of the
-   * invocation are passed to [noSuchMethod] in an [Invocation].
-   * If [noSuchMethod] returns a value, that value becomes the result of
-   * the original invocation.
+   * Invoked when a non-existent method or property is accessed.
    *
-   * The default behavior of [noSuchMethod] is to throw a
-   * [NoSuchMethodError].
+   * Classes can override [noSuchMethod] to provide custom behavior.
+   *
+   * If a value is returned, it becomes the result of the original invocation.
+   *
+   * The default behavior is to throw a [NoSuchMethodError].
    */
   external dynamic noSuchMethod(Invocation invocation);
 
diff --git a/sdk/lib/core/pattern.dart b/sdk/lib/core/pattern.dart
index f47ba15..7f32c72 100644
--- a/sdk/lib/core/pattern.dart
+++ b/sdk/lib/core/pattern.dart
@@ -42,3 +42,90 @@
    */
   Match matchAsPrefix(String string, [int start = 0]);
 }
+
+/**
+ * A result from searching within a string.
+ *
+ * A Match or an [Iterable] of Match objects is returned from [Pattern]
+ * matching methods.
+ *
+ * The following example finds all matches of a [RegExp] in a [String]
+ * and iterates through the returned iterable of Match objects.
+ *
+ *     RegExp exp = new RegExp(r"(\w+)");
+ *     String str = "Parse my string";
+ *     Iterable<Match> matches = exp.allMatches(str);
+ *     for (Match m in matches) {
+ *       String match = m.group(0);
+ *       print(match);
+ *     }
+ *
+ * The output of the example is:
+ *
+ *     Parse
+ *     my
+ *     string
+ *
+ * Some patterns, regular expressions in particular, may record subtrings
+ * that were part of the matching. These are called _groups_ in the Match
+ * object. Some patterns may never have any groups, and their matches always
+ * have zero [groupCount].
+ */
+abstract class Match {
+  /**
+   * Returns the index in the string where the match starts.
+   */
+  int get start;
+
+  /**
+   * Returns the index in the string after the last character of the
+   * match.
+   */
+  int get end;
+
+  /**
+   * Returns the string matched by the given [group].
+   *
+   * If [group] is 0, returns the match of the pattern.
+   *
+   * The result may be `null` if the pattern didn't assign a value to it
+   * as part of this match.
+   */
+  String group(int group);
+
+  /**
+   * Returns the string matched by the given [group].
+   *
+   * If [group] is 0, returns the match of the pattern.
+   *
+   * Short alias for [Match.group].
+   */
+  String operator [](int group);
+
+  /**
+   * Returns a list of the groups with the given indices.
+   *
+   * The list contains the strings returned by [group] for each index in
+   * [groupIndices].
+   */
+  List<String> groups(List<int> groupIndices);
+
+  /**
+   * Returns the number of captured groups in the match.
+   *
+   * Some patterns may capture parts of the input that was used to
+   * compute the full match. This is the number of captured groups,
+   * which is also the maximal allowed argument to the [group] method.
+   */
+  int get groupCount;
+
+  /**
+   * The string on which this match was computed.
+   */
+  String get input;
+
+  /**
+   * The pattern used to search in [input].
+   */
+  Pattern get pattern;
+}
\ No newline at end of file
diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart
index 049ff97..0d92345 100644
--- a/sdk/lib/core/regexp.dart
+++ b/sdk/lib/core/regexp.dart
@@ -5,94 +5,6 @@
 part of dart.core;
 
 /**
- * A result from searching within a string.
- *
- * A Match or an [Iterable] of Match objects is returned from [Pattern]
- * matching methods.
- *
- * The following example finds all matches of a [RegExp] in a [String]
- * and iterates through the returned iterable of Match objects.
- *
- *     RegExp exp = new RegExp(r"(\w+)");
- *     String str = "Parse my string";
- *     Iterable<Match> matches = exp.allMatches(str);
- *     for (Match m in matches) {
- *       String match = m.group(0);
- *       print(match);
- *     }
- *
- * The output of the example is:
- *
- *     Parse
- *     my
- *     string
- *
- * Some patterns, regular expressions in particular, may record subtrings
- * that were part of the matching. These are called _groups_ in the Match
- * object. Some patterns may never have any groups, and their matches always
- * have zero [groupCount].
- */
-abstract class Match {
-  /**
-   * Returns the index in the string where the match starts.
-   */
-  int get start;
-
-  /**
-   * Returns the index in the string after the last character of the
-   * match.
-   */
-  int get end;
-
-  /**
-   * Returns the string matched by the given [group].
-   *
-   * If [group] is 0, returns the match of the pattern.
-   *
-   * The result may be `null` if the pattern didn't assign a value to it
-   * as part of this match.
-   */
-  String group(int group);
-
-  /**
-   * Returns the string matched by the given [group].
-   *
-   * If [group] is 0, returns the match of the pattern.
-   *
-   * Short alias for [Match.group].
-   */
-  String operator [](int group);
-
-  /**
-   * Returns a list of the groups with the given indices.
-   *
-   * The list contains the strings returned by [group] for each index in
-   * [groupIndices].
-   */
-  List<String> groups(List<int> groupIndices);
-
-  /**
-   * Returns the number of captured groups in the match.
-   *
-   * Some patterns may capture parts of the input that was used to
-   * compute the full match. This is the number of captured groups,
-   * which is also the maximal allowed argument to the [group] method.
-   */
-  int get groupCount;
-
-  /**
-   * The string on which this match was computed.
-   */
-  String get input;
-
-  /**
-   * The pattern used to search in [input].
-   */
-  Pattern get pattern;
-}
-
-
-/**
  * A regular expression pattern.
  *
  * Regular expressions are [Pattern]s, and can as such be used to match strings
diff --git a/sdk/lib/core/stacktrace.dart b/sdk/lib/core/stacktrace.dart
index c8540dc..17abd38 100644
--- a/sdk/lib/core/stacktrace.dart
+++ b/sdk/lib/core/stacktrace.dart
@@ -31,6 +31,18 @@
   factory StackTrace.fromString(String stackTraceString) = _StringStackTrace;
 
   /**
+   * Returns a representation of the current stack trace.
+   *
+   * This is similar to what can be achieved by doing:
+   *
+   *     try { throw 0; } catch (_, stack) { return stack; }
+   *
+   * The getter achieves this without throwing, except on platforms that
+   * have no other way to get a stack trace.
+   */
+  external static StackTrace get current;
+
+  /**
    * Returns a [String] representation of the stack trace.
    *
    * The string represents the full stack trace starting from
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 599ad0f..39641df 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -86,9 +86,8 @@
  * Also see:
 
  * * [Dart Cookbook](https://www.dartlang.org/docs/cookbook/#strings)
- * for String examples and recipes.
- * * [Dart Up and Running]
- * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-strings-and-regular-expressions)
+ *   for String examples and recipes.
+ * * [Dart Up and Running](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#strings-and-regular-expressions)
  */
 abstract class String implements Comparable<String>, Pattern {
   /**
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 2cd5f8a..e4a31aa 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -12,8 +12,8 @@
  * * [URIs][uris] in the [library tour][libtour]
  * * [RFC-3986](http://tools.ietf.org/html/rfc3986)
  *
- * [uris]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-uri
- * [libtour]: http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
+ * [uris]: https://www.dartlang.org/docs/dart-up-and-running/ch03.html#uris
+ * [libtour]: https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
  */
 class Uri {
   /**
@@ -386,9 +386,6 @@
     // query         = *( pchar / "/" / "?" )
     //
     // fragment      = *( pchar / "/" / "?" )
-    bool isRegName(int ch) {
-      return ch < 128 && ((_regNameTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
-    }
     const int EOI = -1;
 
     String scheme = "";
@@ -748,6 +745,74 @@
   }
 
   /**
+   * Creates a `data:` URI containing the [content] string.
+   *
+   * Converts the content to a bytes using [encoding] or the charset specified
+   * in [parameters] (defaulting to US-ASCII if not specified or unrecognized),
+   * then encodes the bytes into the resulting data URI.
+   *
+   * Defaults to encoding using percent-encoding (any non-ASCII or non-URI-valid
+   * bytes is replaced by a percent encoding). If [base64] is true, the bytes
+   * are instead encoded using [BASE64].
+   *
+   * If [encoding] is not provided and [parameters] has a `charset` entry,
+   * that name is looked up using [Encoding.getByName],
+   * and if the lookup returns an encoding, that encoding is used to convert
+   * [content] to bytes.
+   * If providing both an [encoding] and a charset [parameter], they should
+   * agree, otherwise decoding won't be able to use the charset parameter
+   * to determine the encoding.
+   *
+   * If [mimeType] and/or [parameters] are supplied, they are added to the
+   * created URI. If any of these contain characters that are not allowed
+   * in the data URI, the character is percent-escaped. If the character is
+   * non-ASCII, it is first UTF-8 encoded and then the bytes are percent
+   * encoded. An omitted [mimeType] in a data URI means `text/plain`, just
+   * as an omitted `charset` parameter defaults to meaning `US-ASCII`.
+   *
+   * To read the content back, use [UriData.contentAsString].
+   */
+  factory Uri.dataFromString(String content,
+                             {String mimeType,
+                              Encoding encoding,
+                              Map<String, String> parameters,
+                              bool base64: false}) {
+    UriData data =  new UriData.fromString(content,
+                                           mimeType: mimeType,
+                                           encoding: encoding,
+                                           parameters: parameters,
+                                           base64: base64);
+    return data.uri;
+  }
+
+  /**
+   * Creates a `data:` URI containing an encoding of [bytes].
+   *
+   * Defaults to Base64 encoding the bytes, but if [percentEncoded]
+   * is `true`, the bytes will instead be percent encoded (any non-ASCII
+   * or non-valid-ASCII-character byte is replaced by a percent encoding).
+   *
+   * To read the bytes back, use [UriData.contentAsBytes].
+   *
+   * It defaults to having the mime-type `application/octet-stream`.
+   * The [mimeType] and [parameters] are added to the created URI.
+   * If any of these contain characters that are not allowed
+   * in the data URI, the character is percent-escaped. If the character is
+   * non-ASCII, it is first UTF-8 encoded and then the bytes are percent
+   * encoded.
+   */
+  factory Uri.dataFromBytes(List<int> bytes,
+                            {mimeType: "application/octet-stream",
+                             Map<String, String> parameters,
+                             percentEncoded: false}) {
+    UriData data = new UriData.fromBytes(bytes,
+                                         mimeType: mimeType,
+                                         parameters: parameters,
+                                         percentEncoded: percentEncoded);
+    return data.uri;
+  }
+
+  /**
    * Returns the natural base URI for the current platform.
    *
    * When running in a browser this is the current URL (from
@@ -1012,34 +1077,35 @@
   }
 
   /**
-   * Returns the URI path split into its segments. Each of the
-   * segments in the returned list have been decoded. If the path is
-   * empty the empty list will be returned. A leading slash `/` does
-   * not affect the segments returned.
+   * Returns the URI path split into its segments. Each of the segments in the
+   * returned list have been decoded. If the path is empty the empty list will
+   * be returned. A leading slash `/` does not affect the segments returned.
    *
    * The returned list is unmodifiable and will throw [UnsupportedError] on any
    * calls that would mutate it.
    */
   List<String> get pathSegments {
-    if (_pathSegments == null) {
-      var pathToSplit = !path.isEmpty && path.codeUnitAt(0) == _SLASH
-                        ? path.substring(1)
-                        : path;
-      _pathSegments = new UnmodifiableListView(
-        pathToSplit == "" ? const<String>[]
-                          : pathToSplit.split("/")
-                                       .map(Uri.decodeComponent)
-                                       .toList(growable: false));
+    var result = _pathSegments;
+    if (result != null) return result;
+
+    var pathToSplit = path;
+    if (pathToSplit.isNotEmpty && pathToSplit.codeUnitAt(0) == _SLASH) {
+      pathToSplit = pathToSplit.substring(1);
     }
-    return _pathSegments;
+    result = (pathToSplit == "")
+        ? const<String>[]
+        : new List<String>.unmodifiable(
+              pathToSplit.split("/").map(Uri.decodeComponent));
+    _pathSegments = result;
+    return result;
   }
 
   /**
    * Returns the URI query split into a map according to the rules
-   * specified for FORM post in the [HTML 4.01 specification section 17.13.4]
-   * (http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4
-   * "HTML 4.01 section 17.13.4"). Each key and value in the returned map
-   * has been decoded. If there is no query the empty map is returned.
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded. If there is no
+   * query the empty map is returned.
    *
    * Keys in the query string that have no value are mapped to the
    * empty string.
@@ -1245,7 +1311,8 @@
     if (path != null) {
       result = _normalize(path, start, end, _pathCharOrSlashTable);
     } else {
-      result = pathSegments.map((s) => _uriEncode(_pathCharTable, s)).join("/");
+      result = pathSegments.map((s) =>
+          _uriEncode(_pathCharTable, s, UTF8, false)).join("/");
     }
     if (result.isEmpty) {
       if (isFile) return "/";
@@ -1299,19 +1366,6 @@
 
   static int _stringOrNullLength(String s) => (s == null) ? 0 : s.length;
 
-  static bool _isHexDigit(int char) {
-    if (_NINE >= char) return _ZERO <= char;
-    char |= 0x20;
-    return _LOWER_CASE_A <= char && _LOWER_CASE_F >= char;
-  }
-
-  static int _hexValue(int char) {
-    assert(_isHexDigit(char));
-    if (_NINE >= char) return char - _ZERO;
-    char |= 0x20;
-    return char - (_LOWER_CASE_A - 10);
-  }
-
   /**
    * Performs RFC 3986 Percent-Encoding Normalization.
    *
@@ -1332,10 +1386,12 @@
     }
     int firstDigit = source.codeUnitAt(index + 1);
     int secondDigit = source.codeUnitAt(index + 2);
-    if (!_isHexDigit(firstDigit) || !_isHexDigit(secondDigit)) {
+    int firstDigitValue = _parseHexDigit(firstDigit);
+    int secondDigitValue = _parseHexDigit(secondDigit);
+    if (firstDigitValue < 0 || secondDigitValue < 0) {
       return "%";  // Marks the escape as invalid.
     }
-    int value = _hexValue(firstDigit) * 16 + _hexValue(secondDigit);
+    int value = firstDigitValue * 16 + secondDigitValue;
     if (_isUnreservedChar(value)) {
       if (lowerCase && _UPPER_CASE_A <= value && _UPPER_CASE_Z >= value) {
         value |= 0x20;
@@ -1351,21 +1407,27 @@
     return null;
   }
 
-  static bool _isUnreservedChar(int ch) {
-    return ch < 127 &&
-           ((_unreservedTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
+  // Converts a UTF-16 code-unit to its value as a hex digit.
+  // Returns -1 for non-hex digits.
+  static int _parseHexDigit(int char) {
+    int digit = char ^ Uri._ZERO;
+    if (digit <= 9) return digit;
+    int lowerCase = char | 0x20;
+    if (Uri._LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_F) {
+      return lowerCase - (_LOWER_CASE_A - 10);
+    }
+    return -1;
   }
 
-  static String _escapeChar(char) {
+  static String _escapeChar(int char) {
     assert(char <= 0x10ffff);  // It's a valid unicode code point.
-    const hexDigits = "0123456789ABCDEF";
     List codeUnits;
     if (char < 0x80) {
       // ASCII, a single percent encoded sequence.
       codeUnits = new List(3);
       codeUnits[0] = _PERCENT;
-      codeUnits[1] = hexDigits.codeUnitAt(char >> 4);
-      codeUnits[2] = hexDigits.codeUnitAt(char & 0xf);
+      codeUnits[1] = _hexDigits.codeUnitAt(char >> 4);
+      codeUnits[2] = _hexDigits.codeUnitAt(char & 0xf);
     } else {
       // Do UTF-8 encoding of character, then percent encode bytes.
       int flag = 0xc0;  // The high-bit markers on the first byte of UTF-8.
@@ -1383,8 +1445,8 @@
       while (--encodedBytes >= 0) {
         int byte = ((char >> (6 * encodedBytes)) & 0x3f) | flag;
         codeUnits[index] = _PERCENT;
-        codeUnits[index + 1] = hexDigits.codeUnitAt(byte >> 4);
-        codeUnits[index + 2] = hexDigits.codeUnitAt(byte & 0xf);
+        codeUnits[index + 1] = _hexDigits.codeUnitAt(byte >> 4);
+        codeUnits[index + 2] = _hexDigits.codeUnitAt(byte & 0xf);
         index += 3;
         flag = 0x80;  // Following bytes have only high bit set.
       }
@@ -1605,9 +1667,8 @@
    *
    * Returns the resolved URI.
    *
-   * The algorithm "Transform Reference" for resolving a reference is
-   * described in [RFC-3986 Section 5]
-   * (http://tools.ietf.org/html/rfc3986#section-5 "RFC-1123").
+   * The algorithm "Transform Reference" for resolving a reference is described
+   * in [RFC-3986 Section 5](http://tools.ietf.org/html/rfc3986#section-5 "RFC-1123").
    *
    * Updated to handle the case where the base URI is just a relative path -
    * that is: when it has no scheme or authority and the path does not start
@@ -1887,6 +1948,16 @@
     }
   }
 
+  /**
+   * Access the structure of a `data:` URI.
+   *
+   * Returns a [UriData] object for `data:` URIs and `null` for all other
+   * URIs.
+   * The [UriData] object can be used to access the media type and data
+   * of a `data:` URI.
+   */
+  UriData get data => (scheme == "data") ? new UriData.fromUri(this) : null;
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     _addIfNonEmpty(sb, scheme, scheme, ':');
@@ -1905,16 +1976,16 @@
   bool operator==(other) {
     if (other is! Uri) return false;
     Uri uri = other;
-    return scheme == uri.scheme &&
-        hasAuthority == uri.hasAuthority &&
-        userInfo == uri.userInfo &&
-        host == uri.host &&
-        port == uri.port &&
-        path == uri.path &&
-        hasQuery == uri.hasQuery &&
-        query == uri.query &&
-        hasFragment == uri.hasFragment &&
-        fragment == uri.fragment;
+    return scheme       == uri.scheme       &&
+           hasAuthority == uri.hasAuthority &&
+           userInfo     == uri.userInfo     &&
+           host         == uri.host         &&
+           port         == uri.port         &&
+           path         == uri.path         &&
+           hasQuery     == uri.hasQuery     &&
+           query        == uri.query        &&
+           hasFragment  == uri.hasFragment  &&
+           fragment     == uri.fragment;
   }
 
   int get hashCode {
@@ -1955,7 +2026,7 @@
    * a [Uri].
    */
   static String encodeComponent(String component) {
-    return _uriEncode(_unreserved2396Table, component);
+    return _uriEncode(_unreserved2396Table, component, UTF8, false);
   }
 
   /**
@@ -1993,8 +2064,7 @@
    */
   static String encodeQueryComponent(String component,
                                      {Encoding encoding: UTF8}) {
-    return _uriEncode(
-        _unreservedTable, component, encoding: encoding, spaceToPlus: true);
+    return _uriEncode(_unreservedTable, component, encoding, true);
   }
 
   /**
@@ -2011,7 +2081,8 @@
    * decoded component.
    */
   static String decodeComponent(String encodedComponent) {
-    return _uriDecode(encodedComponent);
+    return _uriDecode(encodedComponent, 0, encodedComponent.length,
+                      UTF8, false);
   }
 
   /**
@@ -2025,7 +2096,8 @@
   static String decodeQueryComponent(
       String encodedComponent,
       {Encoding encoding: UTF8}) {
-    return _uriDecode(encodedComponent, plusToSpace: true, encoding: encoding);
+    return _uriDecode(encodedComponent, 0, encodedComponent.length,
+                      encoding, true);
   }
 
   /**
@@ -2038,7 +2110,7 @@
    * the encodeURI function .
    */
   static String encodeFull(String uri) {
-    return _uriEncode(_encodeFullTable, uri);
+    return _uriEncode(_encodeFullTable, uri, UTF8, false);
   }
 
   /**
@@ -2050,16 +2122,14 @@
    * [Uri.parse] before decoding the separate components.
    */
   static String decodeFull(String uri) {
-    return _uriDecode(uri);
+    return _uriDecode(uri, 0, uri.length, UTF8, false);
   }
 
   /**
    * Returns the [query] split into a map according to the rules
-   * specified for FORM post in the
-   * [HTML 4.01 specification section 17.13.4]
-   * (http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4
-   * "HTML 4.01 section 17.13.4"). Each key and value in the returned
-   * map has been decoded. If the [query]
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded. If the [query]
    * is the empty string an empty map is returned.
    *
    * Keys in the query string that have no value are mapped to the
@@ -2254,39 +2324,12 @@
   static const int _LOWER_CASE_Z = 0x7A;
   static const int _BAR = 0x7C;
 
-  /**
-   * This is the internal implementation of JavaScript's encodeURI function.
-   * It encodes all characters in the string [text] except for those
-   * that appear in [canonicalTable], and returns the escaped string.
-   */
-  static String _uriEncode(List<int> canonicalTable,
-                           String text,
-                           {Encoding encoding: UTF8,
-                            bool spaceToPlus: false}) {
-    byteToHex(byte, buffer) {
-      const String hex = '0123456789ABCDEF';
-      buffer.writeCharCode(hex.codeUnitAt(byte >> 4));
-      buffer.writeCharCode(hex.codeUnitAt(byte & 0x0f));
-    }
+  static const String _hexDigits = "0123456789ABCDEF";
 
-    // Encode the string into bytes then generate an ASCII only string
-    // by percent encoding selected bytes.
-    StringBuffer result = new StringBuffer();
-    var bytes = encoding.encode(text);
-    for (int i = 0; i < bytes.length; i++) {
-      int byte = bytes[i];
-      if (byte < 128 &&
-          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
-        result.writeCharCode(byte);
-      } else if (spaceToPlus && byte == _SPACE) {
-        result.writeCharCode(_PLUS);
-      } else {
-        result.writeCharCode(_PERCENT);
-        byteToHex(byte, result);
-      }
-    }
-    return result.toString();
-  }
+  external static String _uriEncode(List<int> canonicalTable,
+                                    String text,
+                                    Encoding encoding,
+                                    bool spaceToPlus);
 
   /**
    * Convert a byte (2 character hex sequence) in string [s] starting
@@ -2324,24 +2367,35 @@
    * decode the byte-list using [encoding]. The default encodingis UTF-8.
    */
   static String _uriDecode(String text,
-                           {bool plusToSpace: false,
-                            Encoding encoding: UTF8}) {
+                           int start,
+                           int end,
+                           Encoding encoding,
+                           bool plusToSpace) {
+    assert(0 <= start);
+    assert(start <= end);
+    assert(end <= text.length);
+    assert(encoding != null);
     // First check whether there is any characters which need special handling.
     bool simple = true;
-    for (int i = 0; i < text.length && simple; i++) {
+    for (int i = start; i < end; i++) {
       var codeUnit = text.codeUnitAt(i);
-      simple = codeUnit != _PERCENT && codeUnit != _PLUS;
+      if (codeUnit > 127 ||
+          codeUnit == _PERCENT ||
+          (plusToSpace && codeUnit == _PLUS)) {
+        simple = false;
+        break;
+      }
     }
     List<int> bytes;
     if (simple) {
-      if (encoding == UTF8 || encoding == LATIN1) {
-        return text;
+      if (UTF8 == encoding || LATIN1 == encoding || ASCII == encoding) {
+        return text.substring(start, end);
       } else {
-        bytes = text.codeUnits;
+        bytes = text.substring(start, end).codeUnits;
       }
     } else {
       bytes = new List();
-      for (int i = 0; i < text.length; i++) {
+      for (int i = start; i < end; i++) {
         var codeUnit = text.codeUnitAt(i);
         if (codeUnit > 127) {
           throw new ArgumentError("Illegal percent encoding in URI");
@@ -2362,9 +2416,15 @@
     return encoding.decode(bytes);
   }
 
-  static bool _isAlphabeticCharacter(int codeUnit)
-    => (codeUnit >= _LOWER_CASE_A && codeUnit <= _LOWER_CASE_Z) ||
-       (codeUnit >= _UPPER_CASE_A && codeUnit <= _UPPER_CASE_Z);
+  static bool _isAlphabeticCharacter(int codeUnit) {
+    var lowerCase = codeUnit | 0x20;
+    return (_LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_Z);
+  }
+
+  static bool _isUnreservedChar(int char) {
+    return char < 127 &&
+           ((_unreservedTable[char >> 4] & (1 << (char & 0x0f))) != 0);
+  }
 
   // Tables of char-codes organized as a bit vector of 128 bits where
   // each bit indicate whether a character code on the 0-127 needs to
@@ -2613,4 +2673,594 @@
       0xfffe,   // 0x60 - 0x6f  0111111111111111
                 //              pqrstuvwxyz   ~
       0x47ff];  // 0x70 - 0x7f  1111111111100010
+
+}
+
+// --------------------------------------------------------------------
+// Data URI
+// --------------------------------------------------------------------
+
+/**
+ * A way to access the structure of a `data:` URI.
+ *
+ * Data URIs are non-hierarchical URIs that can contain any binary data.
+ * They are defined by [RFC 2397](https://tools.ietf.org/html/rfc2397).
+ *
+ * This class allows parsing the URI text and extracting individual parts of the
+ * URI, as well as building the URI text from structured parts.
+ */
+class UriData {
+  static const int _noScheme = -1;
+  /**
+   * Contains the text content of a `data:` URI, with or without a
+   * leading `data:`.
+   *
+   * If [_separatorIndices] starts with `4` (the index of the `:`), then
+   * there is a leading `data:`, otherwise [_separatorIndices] starts with
+   * `-1`.
+   */
+  final String _text;
+
+  /**
+   * List of the separators (';', '=' and ',') in the text.
+   *
+   * Starts with the index of the `:` in `data:` of the mimeType.
+   * That is always either -1 or 4, depending on whether `_text` includes the
+   * `data:` scheme or not.
+   *
+   * The first speparator ends the mime type. We don't bother with finding
+   * the '/' inside the mime type.
+   *
+   * Each two separators after that marks a parameter key and value.
+   *
+   * If there is a single separator left, it ends the "base64" marker.
+   *
+   * So the following separators are found for a text:
+   *
+   *     data:text/plain;foo=bar;base64,ARGLEBARGLE=
+   *         ^          ^   ^   ^      ^
+   *
+   */
+  final List<int> _separatorIndices;
+
+  /**
+   * Cache of the result returned by [uri].
+   */
+  Uri _uriCache;
+
+  UriData._(this._text, this._separatorIndices, this._uriCache);
+
+  /**
+   * Creates a `data:` URI containing the [content] string.
+   *
+   * Equivalent to `new Uri.dataFromString(...).data`, but may
+   * be more efficient if the [uri] itself isn't used.
+   */
+  factory UriData.fromString(String content,
+                             {String mimeType,
+                              Encoding encoding,
+                              Map<String, String> parameters,
+                              bool base64: false}) {
+    StringBuffer buffer = new StringBuffer();
+    List indices = [_noScheme];
+    String charsetName;
+    String encodingName;
+    if (parameters != null) charsetName = parameters["charset"];
+    if (encoding == null) {
+      if (charsetName != null) {
+        encoding = Encoding.getByName(charsetName);
+      }
+    } else if (charsetName == null) {
+      // Non-null only if parameters does not contain "charset".
+      encodingName = encoding.name;
+    }
+    encoding ??= ASCII;
+    _writeUri(mimeType, encodingName, parameters, buffer, indices);
+    indices.add(buffer.length);
+    if (base64) {
+      buffer.write(';base64,');
+      indices.add(buffer.length - 1);
+      buffer.write(encoding.fuse(BASE64).encode(content));
+    } else {
+      buffer.write(',');
+      _uriEncodeBytes(_uricTable, encoding.encode(content), buffer);
+    }
+    return new UriData._(buffer.toString(), indices, null);
+  }
+
+  /**
+   * Creates a `data:` URI containing an encoding of [bytes].
+   *
+   * Equivalent to `new Uri.dataFromBytes(...).data`, but may
+   * be more efficient if the [uri] itself isn't used.
+   */
+  factory UriData.fromBytes(List<int> bytes,
+                            {mimeType: "application/octet-stream",
+                             Map<String, String> parameters,
+                             percentEncoded: false}) {
+    StringBuffer buffer = new StringBuffer();
+    List indices = [_noScheme];
+    _writeUri(mimeType, null, parameters, buffer, indices);
+    indices.add(buffer.length);
+    if (percentEncoded) {
+      buffer.write(',');
+      _uriEncodeBytes(_uricTable, bytes, buffer);
+    } else {
+      buffer.write(';base64,');
+      indices.add(buffer.length - 1);
+      BASE64.encoder
+            .startChunkedConversion(
+                new StringConversionSink.fromStringSink(buffer))
+            .addSlice(bytes, 0, bytes.length, true);
+    }
+
+    return new UriData._(buffer.toString(), indices, null);
+  }
+
+  /**
+   * Creates a `DataUri` from a [Uri] which must have `data` as [Uri.scheme].
+   *
+   * The [uri] must have scheme `data` and no authority or fragment,
+   * and the path (concatenated with the query, if there is one) must be valid
+   * as data URI content with the same rules as [parse].
+   */
+  factory UriData.fromUri(Uri uri) {
+    if (uri.scheme != "data") {
+      throw new ArgumentError.value(uri, "uri",
+                                    "Scheme must be 'data'");
+    }
+    if (uri.hasAuthority) {
+      throw new ArgumentError.value(uri, "uri",
+                                    "Data uri must not have authority");
+    }
+    if (uri.hasFragment) {
+      throw new ArgumentError.value(uri, "uri",
+                                    "Data uri must not have a fragment part");
+    }
+    if (!uri.hasQuery) {
+      return _parse(uri.path, 0, uri);
+    }
+    // Includes path and query (and leading "data:").
+    return _parse("$uri", 5, uri);
+  }
+
+  /**
+   * Writes the initial part of a `data:` uri, from after the "data:"
+   * until just before the ',' before the data, or before a `;base64,`
+   * marker.
+   *
+   * Of an [indices] list is passed, separator indices are stored in that
+   * list.
+   */
+  static void _writeUri(String mimeType,
+                        String charsetName,
+                        Map<String, String> parameters,
+                        StringBuffer buffer, List indices) {
+    if (mimeType == null || mimeType == "text/plain") {
+      mimeType = "";
+    }
+    if (mimeType.isEmpty || identical(mimeType, "application/octet-stream")) {
+      buffer.write(mimeType);  // Common cases need no escaping.
+    } else {
+      int slashIndex = _validateMimeType(mimeType);
+      if (slashIndex < 0) {
+        throw new ArgumentError.value(mimeType, "mimeType",
+                                      "Invalid MIME type");
+      }
+      buffer.write(Uri._uriEncode(_tokenCharTable,
+                                  mimeType.substring(0, slashIndex),
+                                  UTF8, false));
+      buffer.write("/");
+      buffer.write(Uri._uriEncode(_tokenCharTable,
+                                  mimeType.substring(slashIndex + 1),
+                                  UTF8, false));
+    }
+    if (charsetName != null) {
+      if (indices != null) {
+        indices..add(buffer.length)
+               ..add(buffer.length + 8);
+      }
+      buffer.write(";charset=");
+      buffer.write(Uri._uriEncode(_tokenCharTable, charsetName, UTF8, false));
+    }
+    parameters?.forEach((var key, var value) {
+      if (key.isEmpty) {
+        throw new ArgumentError.value("", "Parameter names must not be empty");
+      }
+      if (value.isEmpty) {
+        throw new ArgumentError.value("", "Parameter values must not be empty",
+                                      'parameters["$key"]');
+      }
+      if (indices != null) indices.add(buffer.length);
+      buffer.write(';');
+      // Encode any non-RFC2045-token character and both '%' and '#'.
+      buffer.write(Uri._uriEncode(_tokenCharTable, key, UTF8, false));
+      if (indices != null) indices.add(buffer.length);
+      buffer.write('=');
+      buffer.write(Uri._uriEncode(_tokenCharTable, value, UTF8, false));
+    });
+  }
+
+  /**
+   * Checks mimeType is valid-ish (`token '/' token`).
+   *
+   * Returns the index of the slash, or -1 if the mime type is not
+   * considered valid.
+   *
+   * Currently only looks for slashes, all other characters will be
+   * percent-encoded as UTF-8 if necessary.
+   */
+  static int _validateMimeType(String mimeType) {
+    int slashIndex = -1;
+    for (int i = 0; i < mimeType.length; i++) {
+      var char = mimeType.codeUnitAt(i);
+      if (char != Uri._SLASH) continue;
+      if (slashIndex < 0) {
+        slashIndex = i;
+        continue;
+      }
+      return -1;
+    }
+    return slashIndex;
+  }
+
+  /**
+   * Parses a string as a `data` URI.
+   *
+   * The string must have the format:
+   *
+   * ```
+   * 'data:' (type '/' subtype)? (';' attribute '=' value)* (';base64')? ',' data
+   * ````
+   *
+   * where `type`, `subtype`, `attribute` and `value` are specified in RFC-2045,
+   * and `data` is a sequnce of URI-characters (RFC-2396 `uric`).
+   *
+   * This means that all the characters must be ASCII, but the URI may contain
+   * percent-escapes for non-ASCII byte values that need an interpretation
+   * to be converted to the corresponding string.
+   *
+   * Parsing doesn't check the validity of any part, it just checks that the
+   * input has the correct structure with the correct sequence of `/`, `;`, `=`
+   * and `,` delimiters.
+   *
+   * Accessing the individual parts may fail later if they turn out to have
+   * content that can't be decoded sucessfully as a string.
+   */
+  static UriData parse(String uri) {
+    if (!uri.startsWith("data:")) {
+      throw new FormatException("Does not start with 'data:'", uri, 0);
+    }
+    return _parse(uri, 5, null);
+  }
+
+  /**
+   * The [Uri] that this `UriData` is giving access to.
+   *
+   * Returns a `Uri` with scheme `data` and the remainder of the data URI
+   * as path.
+   */
+  Uri get uri {
+    if (_uriCache != null) return _uriCache;
+    String path = _text;
+    String query = null;
+    int colonIndex = _separatorIndices[0];
+    int queryIndex = _text.indexOf('?', colonIndex + 1);
+    int end = null;
+    if (queryIndex >= 0) {
+      query = _text.substring(queryIndex + 1);
+      end = queryIndex;
+    }
+    path = _text.substring(colonIndex + 1, end);
+    // TODO(lrn): This is probably too simple. We should ensure URI
+    // normalization before passing in the raw strings, maybe using
+    // Uri._makePath, Uri._makeQuery.
+    _uriCache = new Uri._internal("data", "", null, null, path, query, null);
+    return _uriCache;
+  }
+
+  /**
+   * The MIME type of the data URI.
+   *
+   * A data URI consists of a "media type" followed by data.
+   * The media type starts with a MIME type and can be followed by
+   * extra parameters.
+   *
+   * Example:
+   *
+   *     data:text/plain;charset=utf-8,Hello%20World!
+   *
+   * This data URI has the media type `text/plain;charset=utf-8`, which is the
+   * MIME type `text/plain` with the parameter `charset` with value `utf-8`.
+   * See [RFC 2045](https://tools.ietf.org/html/rfc2045) for more detail.
+   *
+   * If the first part of the data URI is empty, it defaults to `text/plain`.
+   */
+  String get mimeType {
+    int start = _separatorIndices[0] + 1;
+    int end = _separatorIndices[1];
+    if (start == end) return "text/plain";
+    return Uri._uriDecode(_text, start, end, UTF8, false);
+  }
+
+  /**
+   * The charset parameter of the media type.
+   *
+   * If the parameters of the media type contains a `charset` parameter
+   * then this returns its value, otherwise it returns `US-ASCII`,
+   * which is the default charset for data URIs.
+   */
+  String get charset {
+    int parameterStart = 1;
+    int parameterEnd = _separatorIndices.length - 1;  // The ',' before data.
+    if (isBase64) {
+      // There is a ";base64" separator, so subtract one for that as well.
+      parameterEnd -= 1;
+    }
+    for (int i = parameterStart; i < parameterEnd; i += 2) {
+      var keyStart = _separatorIndices[i] + 1;
+      var keyEnd = _separatorIndices[i + 1];
+      if (keyEnd == keyStart + 7 && _text.startsWith("charset", keyStart)) {
+        return Uri._uriDecode(_text, keyEnd + 1, _separatorIndices[i + 2],
+                              UTF8, false);
+      }
+    }
+    return "US-ASCII";
+  }
+
+  /**
+   * Whether the data is Base64 encoded or not.
+   */
+  bool get isBase64 => _separatorIndices.length.isOdd;
+
+  /**
+   * The content part of the data URI, as its actual representation.
+   *
+   * This string may contain percent escapes.
+   */
+  String get contentText => _text.substring(_separatorIndices.last + 1);
+
+  /**
+   * The content part of the data URI as bytes.
+   *
+   * If the data is Base64 encoded, it will be decoded to bytes.
+   *
+   * If the data is not Base64 encoded, it will be decoded by unescaping
+   * percent-escaped characters and returning byte values of each unescaped
+   * character. The bytes will not be, e.g., UTF-8 decoded.
+   */
+  List<int> contentAsBytes() {
+    String text = _text;
+    int start = _separatorIndices.last + 1;
+    if (isBase64) {
+      return BASE64.decoder.convert(text, start);
+    }
+
+    // Not base64, do percent-decoding and return the remaining bytes.
+    // Compute result size.
+    const int percent = 0x25;
+    int length = text.length - start;
+    for (int i = start; i < text.length; i++) {
+      var codeUnit = text.codeUnitAt(i);
+      if (codeUnit == percent) {
+        i += 2;
+        length -= 2;
+      }
+    }
+    // Fill result array.
+    Uint8List result = new Uint8List(length);
+    if (length == text.length) {
+      result.setRange(0, length, text.codeUnits, start);
+      return result;
+    }
+    int index = 0;
+    for (int i = start; i < text.length; i++) {
+      var codeUnit = text.codeUnitAt(i);
+      if (codeUnit != percent) {
+        result[index++] = codeUnit;
+      } else {
+        if (i + 2 < text.length) {
+          var digit1 = Uri._parseHexDigit(text.codeUnitAt(i + 1));
+          var digit2 = Uri._parseHexDigit(text.codeUnitAt(i + 2));
+          if (digit1 >= 0 && digit2 >= 0) {
+            int byte = digit1 * 16 + digit2;
+            result[index++] = byte;
+            i += 2;
+            continue;
+          }
+        }
+        throw new FormatException("Invalid percent escape", text, i);
+      }
+    }
+    assert(index == result.length);
+    return result;
+  }
+
+  /**
+   * Returns a string created from the content of the data URI.
+   *
+   * If the content is Base64 encoded, it will be decoded to bytes and then
+   * decoded to a string using [encoding].
+   * If encoding is omitted, the value of a `charset` parameter is used
+   * if it is recongized by [Encoding.getByName], otherwise it defaults to
+   * the [ASCII] encoding, which is the default encoding for data URIs
+   * that do not specify an encoding.
+   *
+   * If the content is not Base64 encoded, it will first have percent-escapes
+   * converted to bytes and then the character codes and byte values are
+   * decoded using [encoding].
+   */
+  String contentAsString({Encoding encoding}) {
+    if (encoding == null) {
+      var charset = this.charset;  // Returns "US-ASCII" if not present.
+      encoding = Encoding.getByName(charset);
+      if (encoding == null) {
+        throw new UnsupportedError("Unknown charset: $charset");
+      }
+    }
+    String text = _text;
+    int start = _separatorIndices.last + 1;
+    if (isBase64) {
+      var converter = BASE64.decoder.fuse(encoding.decoder);
+      return converter.convert(text.substring(start));
+    }
+    return Uri._uriDecode(text, start, text.length, encoding, false);
+  }
+
+  /**
+   * A map representing the parameters of the media type.
+   *
+   * A data URI may contain parameters between the the MIME type and the
+   * data. This converts these parameters to a map from parameter name
+   * to parameter value.
+   * The map only contains parameters that actually occur in the URI.
+   * The `charset` parameter has a default value even if it doesn't occur
+   * in the URI, which is reflected by the [charset] getter. This means that
+   * [charset] may return a value even if `parameters["charset"]` is `null`.
+   *
+   * If the values contain non-ASCII values or percent escapes, they default
+   * to being decoded as UTF-8.
+   */
+  Map<String, String> get parameters {
+    var result = <String, String>{};
+    for (int i = 3; i < _separatorIndices.length; i += 2) {
+      var start = _separatorIndices[i - 2] + 1;
+      var equals = _separatorIndices[i - 1];
+      var end = _separatorIndices[i];
+      String key = Uri._uriDecode(_text, start, equals, UTF8, false);
+      String value = Uri._uriDecode(_text,equals + 1, end, UTF8, false);
+      result[key] = value;
+    }
+    return result;
+  }
+
+  static UriData _parse(String text, int start, Uri sourceUri) {
+    assert(start == 0 || start == 5);
+    assert((start == 5) == text.startsWith("data:"));
+
+    /// Character codes.
+    const int comma     = 0x2c;
+    const int slash     = 0x2f;
+    const int semicolon = 0x3b;
+    const int equals    = 0x3d;
+    List indices = [start - 1];
+    int slashIndex = -1;
+    var char;
+    int i = start;
+    for (; i < text.length; i++) {
+      char = text.codeUnitAt(i);
+      if (char == comma || char == semicolon) break;
+      if (char == slash) {
+        if (slashIndex < 0) {
+          slashIndex = i;
+          continue;
+        }
+        throw new FormatException("Invalid MIME type", text, i);
+      }
+    }
+    if (slashIndex < 0 && i > start) {
+      // An empty MIME type is allowed, but if non-empty it must contain
+      // exactly one slash.
+      throw new FormatException("Invalid MIME type", text, i);
+    }
+    while (char != comma) {
+      // Parse parameters and/or "base64".
+      indices.add(i);
+      i++;
+      int equalsIndex = -1;
+      for (; i < text.length; i++) {
+        char = text.codeUnitAt(i);
+        if (char == equals) {
+          if (equalsIndex < 0) equalsIndex = i;
+        } else if (char == semicolon || char == comma) {
+          break;
+        }
+      }
+      if (equalsIndex >= 0) {
+        indices.add(equalsIndex);
+      } else {
+        // Have to be final "base64".
+        var lastSeparator = indices.last;
+        if (char != comma ||
+            i != lastSeparator + 7 /* "base64,".length */ ||
+            !text.startsWith("base64", lastSeparator + 1)) {
+          throw new FormatException("Expecting '='", text, i);
+        }
+        break;
+      }
+    }
+    indices.add(i);
+    return new UriData._(text, indices, sourceUri);
+  }
+
+  /**
+   * Like [Uri._uriEncode] but takes the input as bytes, not a string.
+   *
+   * Encodes into [buffer] instead of creating its own buffer.
+   */
+  static void _uriEncodeBytes(List<int> canonicalTable,
+                              List<int> bytes,
+                              StringSink buffer) {
+    // Encode the string into bytes then generate an ASCII only string
+    // by percent encoding selected bytes.
+    int byteOr = 0;
+    for (int i = 0; i < bytes.length; i++) {
+      int byte = bytes[i];
+      byteOr |= byte;
+      if (byte < 128 &&
+          ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+        buffer.writeCharCode(byte);
+      } else {
+        buffer.writeCharCode(Uri._PERCENT);
+        buffer.writeCharCode(Uri._hexDigits.codeUnitAt(byte >> 4));
+        buffer.writeCharCode(Uri._hexDigits.codeUnitAt(byte & 0x0f));
+      }
+    }
+    if ((byteOr & ~0xFF) != 0) {
+      for (int i = 0; i < bytes.length; i++) {
+        var byte = bytes[i];
+        if (byte < 0 || byte > 255) {
+          throw new ArgumentError.value(byte, "non-byte value");
+        }
+      }
+    }
+  }
+
+  String toString() =>
+      (_separatorIndices[0] == _noScheme) ? "data:$_text" : _text;
+
+  // Table of the `token` characters of RFC 2045 in a URI.
+  //
+  // A token is any US-ASCII character except SPACE, control characters and
+  // `tspecial` characters. The `tspecial` category is:
+  // '(', ')', '<', '>', '@', ',', ';', ':', '\', '"', '/', '[, ']', '?', '='.
+  //
+  // In a data URI, we also need to escape '%' and '#' characters.
+  static const _tokenCharTable = const [
+                //             LSB             MSB
+                //              |               |
+      0x0000,   // 0x00 - 0x0f  00000000 00000000
+      0x0000,   // 0x10 - 0x1f  00000000 00000000
+                //               !  $ &'   *+ -.
+      0x6cd2,   // 0x20 - 0x2f  01001011 00110110
+                //              01234567 89
+      0x03ff,   // 0x30 - 0x3f  11111111 11000000
+                //               ABCDEFG HIJKLMNO
+      0xfffe,   // 0x40 - 0x4f  01111111 11111111
+                //              PQRSTUVW XYZ   ^_
+      0xc7ff,   // 0x50 - 0x5f  11111111 11100011
+                //              `abcdefg hijklmno
+      0xffff,   // 0x60 - 0x6f  11111111 11111111
+                //              pqrstuvw xyz{|}~
+      0x7fff];  // 0x70 - 0x7f  11111111 11111110
+
+  // All non-escape RFC-2396 uric characters.
+  //
+  //  uric        =  reserved | unreserved | escaped
+  //  reserved    =  ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
+  //  unreserved  =  alphanum | mark
+  //  mark        =  "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+  //
+  // This is the same characters as in a URI query (which is URI pchar plus '?')
+  static const _uricTable = Uri._queryCharTable;
 }
diff --git a/sdk/lib/dart2dart.platform b/sdk/lib/dart2dart.platform
new file mode 100644
index 0000000..fd9d8ed
--- /dev/null
+++ b/sdk/lib/dart2dart.platform
@@ -0,0 +1,48 @@
+# Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# The platform when compiling with dart2js for dart2dart.
+#
+# Includes the _mirror_helpers private libraries
+
+[dart-spec]
+spec:3rd edition.
+
+[features]
+# No extra features.
+
+[libraries]
+async: async/async.dart
+_chrome: _chrome/dart2js/chrome_dart2js.dart
+collection: collection/collection.dart
+convert: convert/convert.dart
+core: core/core.dart
+developer: developer/developer.dart
+html: html/dart2js/html_dart2js.dart
+html_common: html/html_common/html_common_dart2js.dart
+indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
+io: io/io.dart
+isolate: isolate/isolate.dart
+js: js/dart2js/js_dart2js.dart
+math: math/math.dart
+mirrors: mirrors/mirrors.dart
+nativewrappers: html/dart2js/nativewrappers.dart
+typed_data: typed_data/typed_data.dart
+_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart
+svg: svg/dart2js/svg_dart2js.dart
+web_audio: web_audio/dart2js/web_audio_dart2js.dart
+web_gl: web_gl/dart2js/web_gl_dart2js.dart
+web_sql: web_sql/dart2js/web_sql_dart2js.dart
+_internal: internal/internal.dart
+_js_helper: _internal/js_runtime/lib/js_helper.dart
+_interceptors: _internal/js_runtime/lib/interceptors.dart
+_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
+_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
+_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
+_js_names: _internal/js_runtime/lib/js_names.dart
+_js_primitives: _internal/js_runtime/lib/js_primitives.dart
+_mirror_helper: _internal/js_runtime/lib/mirror_helper.dart
+_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
+_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart
+_metadata: html/html_common/metadata.dart
diff --git a/sdk/lib/dart_client.platform b/sdk/lib/dart_client.platform
new file mode 100644
index 0000000..2e01cd9
--- /dev/null
+++ b/sdk/lib/dart_client.platform
@@ -0,0 +1,49 @@
+# 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.
+
+# The platform for running dart on the web with dart2js.
+#
+# Includes dart:html and associated libraries.
+# Does not include dart:io.
+
+[dart-spec]
+spec: 3rd edition.
+
+[features]
+# No extra features.
+
+[libraries]
+async: async/async.dart
+_chrome: _chrome/dart2js/chrome_dart2js.dart
+collection: collection/collection.dart
+convert: convert/convert.dart
+core: core/core.dart
+developer: developer/developer.dart
+html: html/dart2js/html_dart2js.dart
+html_common: html/html_common/html_common_dart2js.dart
+indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
+io: unsupported:
+isolate: isolate/isolate.dart
+js: js/dart2js/js_dart2js.dart
+math: math/math.dart
+mirrors: mirrors/mirrors.dart
+nativewrappers: html/dart2js/nativewrappers.dart
+typed_data: typed_data/typed_data.dart
+_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart
+svg: svg/dart2js/svg_dart2js.dart
+web_audio: web_audio/dart2js/web_audio_dart2js.dart
+web_gl: web_gl/dart2js/web_gl_dart2js.dart
+web_sql: web_sql/dart2js/web_sql_dart2js.dart
+_internal: internal/internal.dart
+_js_helper: _internal/js_runtime/lib/js_helper.dart
+_interceptors: _internal/js_runtime/lib/interceptors.dart
+_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
+_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
+_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
+_js_names: _internal/js_runtime/lib/js_names.dart
+_js_primitives: _internal/js_runtime/lib/js_primitives.dart
+_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
+_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart
+_metadata: html/html_common/metadata.dart
+_mirror_helper: unsupported:
diff --git a/sdk/lib/dart_server.platform b/sdk/lib/dart_server.platform
new file mode 100644
index 0000000..821a175
--- /dev/null
+++ b/sdk/lib/dart_server.platform
@@ -0,0 +1,49 @@
+# 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.
+
+# The platform for dart on the server with dart2js.
+#
+# Includes dart:io.
+# Does not include dart:html and associated libraries.
+
+[dart-spec]
+spec:3rd edition.
+
+[features]
+# No extra features.
+
+[libraries]
+async: async/async.dart
+collection: collection/collection.dart
+convert: convert/convert.dart
+core: core/core.dart
+developer: developer/developer.dart
+io: io/io.dart
+isolate: isolate/isolate.dart
+math: math/math.dart
+mirrors: mirrors/mirrors.dart
+nativewrappers: html/dart2js/nativewrappers.dart
+typed_data: typed_data/typed_data.dart
+_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart
+html: unsupported:
+html_common: unsupported:
+indexed_db: unsupported:
+svg: unsupported:
+web_audio: unsupported:
+web_gl: unsupported:
+web_sql: unsupported:
+_chrome: unsupported:
+js: unsupported:
+_mirror_helper: unsupported:
+_internal: internal/internal.dart
+_js_helper: _internal/js_runtime/lib/js_helper.dart
+_interceptors: _internal/js_runtime/lib/interceptors.dart
+_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
+_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
+_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
+_js_names: _internal/js_runtime/lib/js_names.dart
+_js_primitives: _internal/js_runtime/lib/js_primitives.dart
+_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
+_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart
+_metadata: html/html_common/metadata.dart
diff --git a/sdk/lib/dart_shared.platform b/sdk/lib/dart_shared.platform
new file mode 100644
index 0000000..539b868
--- /dev/null
+++ b/sdk/lib/dart_shared.platform
@@ -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.
+
+# A combination of the libraries for dart on the server and client.
+# For testing purposes only.
+
+[dart-spec]
+spec:3rd edition.
+
+[features]
+# No extra features.
+
+[libraries]
+async: async/async.dart
+_chrome: _chrome/dart2js/chrome_dart2js.dart
+collection: collection/collection.dart
+convert: convert/convert.dart
+core: core/core.dart
+developer: developer/developer.dart
+html: html/dart2js/html_dart2js.dart
+html_common: html/html_common/html_common_dart2js.dart
+indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
+io: io/io.dart
+isolate: isolate/isolate.dart
+js: js/dart2js/js_dart2js.dart
+math: math/math.dart
+mirrors: mirrors/mirrors.dart
+nativewrappers: html/dart2js/nativewrappers.dart
+typed_data: typed_data/typed_data.dart
+_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart
+svg: svg/dart2js/svg_dart2js.dart
+web_audio: web_audio/dart2js/web_audio_dart2js.dart
+web_gl: web_gl/dart2js/web_gl_dart2js.dart
+web_sql: web_sql/dart2js/web_sql_dart2js.dart
+_internal: internal/internal.dart
+_js_helper: _internal/js_runtime/lib/js_helper.dart
+_interceptors: _internal/js_runtime/lib/interceptors.dart
+_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
+_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
+_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
+_js_names: _internal/js_runtime/lib/js_names.dart
+_js_primitives: _internal/js_runtime/lib/js_primitives.dart
+_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
+_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart
+_metadata: html/html_common/metadata.dart
+_mirror_helper: unsupported:
diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart
index 722819c..435c50d 100644
--- a/sdk/lib/developer/developer.dart
+++ b/sdk/lib/developer/developer.dart
@@ -13,7 +13,6 @@
 
 import 'dart:async';
 import 'dart:convert';
-import 'dart:isolate' show SendPort;
 
 part 'extension.dart';
 part 'profiler.dart';
diff --git a/sdk/lib/developer/extension.dart b/sdk/lib/developer/extension.dart
index 05eeae7..309dca2 100644
--- a/sdk/lib/developer/extension.dart
+++ b/sdk/lib/developer/extension.dart
@@ -81,13 +81,17 @@
 ///
 /// Must complete to a [ServiceExtensionResponse].
 ///
-/// [method] - the method name.
-/// [parameters] - the parameters.
+/// [method] - the method name of the service protocol request.
+/// [parameters] - A map holding the parameters to the service protocol request.
+///
+/// *NOTE*: All parameter names and values are **encoded as strings**.
 typedef Future<ServiceExtensionResponse>
-    ServiceExtensionHandler(String method, Map parameters);
+    ServiceExtensionHandler(String method, Map<String, String> parameters);
 
 /// Register a [ServiceExtensionHandler] that will be invoked in this isolate
-/// for [method].
+/// for [method]. *NOTE*: Service protocol extensions must be registered
+/// in each isolate and users of extensions must always specify a target
+/// isolate.
 void registerExtension(String method, ServiceExtensionHandler handler) {
   if (method is! String) {
     throw new ArgumentError.value(method,
@@ -105,6 +109,25 @@
   _registerExtension(method, handler);
 }
 
+/// Post an event of [eventKind] with payload of [eventData] to the `Extension`
+/// event stream.
+void postEvent(String eventKind, Map eventData) {
+  if (eventKind is! String) {
+    throw new ArgumentError.value(eventKind,
+                                  'eventKind',
+                                  'Must be a String');
+  }
+  if (eventData is! Map) {
+    throw new ArgumentError.value(eventData,
+                                  'eventData',
+                                  'Must be a Map');
+  }
+  String eventDataAsString = JSON.encode(eventData);
+  _postEvent(eventKind, eventDataAsString);
+}
+
+external _postEvent(String eventKind, String eventData);
+
 // Both of these functions are written inside C++ to avoid updating the data
 // structures in Dart, getting an OOB, and observing stale state. Do not move
 // these into Dart code unless you can ensure that the operations will can be
@@ -112,80 +135,3 @@
 // LookupServiceExtensionHandler and RegisterServiceExtensionHandler.
 external ServiceExtensionHandler _lookupExtension(String method);
 external _registerExtension(String method, ServiceExtensionHandler handler);
-
-// This code is only invoked when there is no other Dart code on the stack.
-_runExtension(ServiceExtensionHandler handler,
-              String method,
-              List<String> parameterKeys,
-              List<String> parameterValues,
-              SendPort replyPort,
-              Object id) {
-  var parameters = {};
-  for (var i = 0; i < parameterKeys.length; i++) {
-    parameters[parameterKeys[i]] = parameterValues[i];
-  }
-  var response;
-  try {
-    response = handler(method, parameters);
-  } catch (e, st) {
-    var errorDetails = (st == null) ? '$e' : '$e\n$st';
-    response = new ServiceExtensionResponse.error(
-        ServiceExtensionResponse.kExtensionError,
-        errorDetails);
-    _postResponse(replyPort, id, response);
-    return;
-  }
-  if (response is! Future) {
-    response = new ServiceExtensionResponse.error(
-          ServiceExtensionResponse.kExtensionError,
-          "Extension handler must return a Future");
-    _postResponse(replyPort, id, response);
-    return;
-  }
-  response.catchError((e, st) {
-    // Catch any errors eagerly and wrap them in a ServiceExtensionResponse.
-    var errorDetails = (st == null) ? '$e' : '$e\n$st';
-    return new ServiceExtensionResponse.error(
-        ServiceExtensionResponse.kExtensionError,
-        errorDetails);
-  }).then((response) {
-    // Post the valid response or the wrapped error after verifying that
-    // the response is a ServiceExtensionResponse.
-    if (response is! ServiceExtensionResponse) {
-      response = new ServiceExtensionResponse.error(
-          ServiceExtensionResponse.kExtensionError,
-          "Extension handler must complete to a ServiceExtensionResponse");
-    }
-    _postResponse(replyPort, id, response);
-  }).catchError((e, st) {
-    // We do not expect any errors to occur in the .then or .catchError blocks
-    // but, suppress them just in case.
-  });
-}
-
-// This code is only invoked by _runExtension.
-_postResponse(SendPort replyPort,
-              Object id,
-              ServiceExtensionResponse response) {
-  assert(replyPort != null);
-  if (id == null) {
-    // No id -> no response.
-    replyPort.send(null);
-    return;
-  }
-  assert(id != null);
-  StringBuffer sb = new StringBuffer();
-  sb.write('{"jsonrpc":"2.0",');
-  if (response._isError()) {
-    sb.write('"error":');
-  } else {
-    sb.write('"result":');
-  }
-  sb.write('${response._toString()},');
-  if (id is String) {
-    sb.write('"id":"$id"}');
-  } else {
-    sb.write('"id":$id}');
-  }
-  replyPort.send(sb.toString());
-}
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index 2753add..c463d8b 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -5,6 +5,7 @@
 part of dart.developer;
 
 typedef dynamic TimelineSyncFunction();
+typedef Future TimelineAsyncFunction();
 
 /// Add to the timeline.
 class Timeline {
@@ -36,6 +37,24 @@
     block.finish();
   }
 
+  /// Emit an instant event.
+  static void instantSync(String name, {Map arguments}) {
+    if (name is! String) {
+      throw new ArgumentError.value(name,
+                                    'name',
+                                    'Must be a String');
+    }
+    Map instantArguments;
+    if (arguments is Map) {
+      instantArguments = new Map.from(arguments);
+    }
+    _reportInstantEvent(_getTraceClock(),
+                        'Dart',
+                        name,
+                        _argumentsAsJson(instantArguments));
+  }
+
+
   /// A utility method to time a synchronous [function]. Internally calls
   /// [function] bracketed by calls to [startSync] and [finishSync].
   static dynamic timeSync(String name,
@@ -49,77 +68,103 @@
     }
   }
 
+  /// The current time stamp from the clock used by the timeline. Units are
+  /// microseconds.
+  static int get now => _getTraceClock();
   static final List<_SyncBlock> _stack = new List<_SyncBlock>();
+  static final int _isolateId = _getIsolateNum();
+  static final String _isolateIdString = _isolateId.toString();
 }
 
-/// An asynchronous task on the timeline. Asynchronous tasks can live
-/// longer than the current event and can even be shared between isolates.
-/// An asynchronous task can have many (nested) blocks. To share a
-/// [_TimelineTask] across isolates, you must construct a [_TimelineTask] in
-/// both isolates using the same [taskId] and [category].
-class _TimelineTask {
+/// An asynchronous task on the timeline. An asynchronous task can have many
+/// (nested) synchronous operations. Synchronous operations can live longer than
+/// the current isolate event. To pass a [TimelineTask] to another isolate,
+/// you must first call [pass] to get the task id and then construct a new
+/// [TimelineTask] in the other isolate.
+class TimelineTask {
   /// Create a task. [taskId] will be set by the system.
-  /// Optionally you can specify a [category] name.
-  _TimelineTask({String category: 'Dart'})
-      : _taskId = _getNextAsyncId(),
-        category = category {
-    if (category is! String) {
-      throw new ArgumentError.value(category,
-                                    'category',
-                                    'Must be a String');
-    }
+  TimelineTask()
+      : _taskId = _getNextAsyncId() {
   }
 
   /// Create a task with an explicit [taskId]. This is useful if you are
-  /// passing a task between isolates. Optionally you can specify a [category]
-  /// name.
-  _TimelineTask.withTaskId(int taskId, {String category: 'Dart'})
-      : _taskId = taskId,
-        category = category {
+  /// passing a task from one isolate to another.
+  TimelineTask.withTaskId(int taskId)
+      : _taskId = taskId {
     if (taskId is! int) {
       throw new ArgumentError.value(taskId,
                                     'taskId',
                                     'Must be an int');
     }
-    if (category is! String) {
-      throw new ArgumentError.value(category,
-                                    'category',
-                                    'Must be a String');
-    }
   }
 
-  /// Start a block in this task named [name]. Optionally takes
-  /// a [Map] of [arguments].
-  /// Returns an [_AsyncBlock] which is used to finish this block.
-  _AsyncBlock start(String name, {Map arguments}) {
+  /// Start a synchronous operation within this task named [name].
+  /// Optionally takes a [Map] of [arguments].
+  void start(String name, {Map arguments}) {
     if (name is! String) {
       throw new ArgumentError.value(name,
                                     'name',
                                     'Must be a String');
     }
-    var block = new _AsyncBlock._(name, _taskId, category);
+    var block = new _AsyncBlock._(name, _taskId);
     if (arguments is Map) {
       block.arguments.addAll(arguments);
     }
-    /// Emit start event.
+    _stack.add(block);
     block._start();
-    return block;
   }
 
-  /// Retrieve the asynchronous task's id. Can be used to construct a
-  /// [_TimelineTask] in another isolate.
-  int get taskId => _taskId;
+  /// Emit an instant event for this task.
+  void instant(String name, {Map arguments}) {
+    if (name is! String) {
+      throw new ArgumentError.value(name,
+                                    'name',
+                                    'Must be a String');
+    }
+    Map instantArguments;
+    if (arguments is Map) {
+      instantArguments = new Map.from(arguments);
+    }
+    _reportTaskEvent(_getTraceClock(),
+                     _taskId,
+                     'n',
+                     'Dart',
+                     name,
+                     _argumentsAsJson(instantArguments));
+  }
+
+  /// Finish the last synchronous operation that was started.
+  void finish() {
+    if (_stack.length == 0) {
+      throw new StateError(
+          'Uneven calls to start and finish');
+    }
+    // Pop top item off of stack.
+    var block = _stack.removeLast();
+    block._finish();
+  }
+
+  /// Retrieve the [TimelineTask]'s task id. Will throw an exception if the
+  /// stack is not empty.
+  int pass() {
+    if (_stack.length > 0) {
+      throw new StateError(
+          'You cannot pass a TimelineTask without finishing all started '
+          'operations');
+    }
+    int r = _taskId;
+    return r;
+  }
+
   final int _taskId;
-  /// Retrieve the asynchronous task's category. Can be used to construct a
-  /// [_TimelineTask] in another isolate.
-  final String category;
+  final List<_AsyncBlock> _stack = [];
 }
 
 /// An asynchronous block of time on the timeline. This block can be kept
 /// open across isolate messages.
 class _AsyncBlock {
   /// The category this block belongs to.
-  final String category;
+  final String category = 'Dart';
   /// The name of this block.
   final String name;
   /// The asynchronous task id.
@@ -127,19 +172,17 @@
   /// An (optional) set of arguments which will be serialized to JSON and
   /// associated with this block.
   final Map arguments = {};
-  bool _finished = false;
 
-  _AsyncBlock._(this.name, this._taskId, this.category);
+  _AsyncBlock._(this.name, this._taskId);
 
   // Emit the start event.
   void _start() {
-    String argumentsAsJson = JSON.encode(arguments);
     _reportTaskEvent(_getTraceClock(),
                      _taskId,
                      'b',
                      category,
                      name,
-                     argumentsAsJson);
+                     _argumentsAsJson(arguments));
   }
 
   // Emit the finish event.
@@ -149,30 +192,7 @@
                      'e',
                      category,
                      name,
-                     JSON.encode({}));
-  }
-
-  /// Finish this block. Cannot be called twice.
-  void finish() {
-    if (_finished) {
-      throw new StateError(
-          'It is illegal to call finish twice on the same _AsyncBlock');
-    }
-    _finished = true;
-    _finish();
-  }
-
-  /// Finishes this block when [future] completes. Returns a [Future]
-  /// chained to [future].
-  Future finishWhenComplete(Future future) {
-    if (future is! Future) {
-      throw new ArgumentError.value(future,
-                                    'future',
-                                    'Must be a Future');
-    }
-    return future.whenComplete(() {
-      finish();
-    });
+                     _argumentsAsJson(null));
   }
 }
 
@@ -195,26 +215,38 @@
   /// Finish this block of time. At this point, this block can no longer be
   /// used.
   void finish() {
-    var end = _getTraceClock();
-
-    // Encode arguments map as JSON before reporting.
-    var argumentsAsJson = JSON.encode(arguments);
-
     // Report event to runtime.
     _reportCompleteEvent(_start,
-                         end,
+                         _getTraceClock(),
                          category,
                          name,
-                         argumentsAsJson);
+                         _argumentsAsJson(arguments));
   }
 }
 
+String _fastPathArguments;
+String _argumentsAsJson(Map arguments) {
+  if ((arguments == null) || (arguments.length == 0)) {
+    // Fast path no arguments. Avoid calling JSON.encode.
+    if (_fastPathArguments == null) {
+      _fastPathArguments = '{"isolateNumber":"${Timeline._isolateId}"}';
+    }
+    return _fastPathArguments;
+  }
+  // Add isolateNumber to arguments map.
+  arguments['isolateNumber'] = Timeline._isolateIdString;
+  return JSON.encode(arguments);
+}
+
 /// Returns the next async task id.
 external int _getNextAsyncId();
 
 /// Returns the current value from the trace clock.
 external int _getTraceClock();
 
+/// Returns the isolate's main port number.
+external int _getIsolateNum();
+
 /// Reports an event for a task.
 external void _reportTaskEvent(int start,
                                int taskId,
@@ -229,3 +261,9 @@
                                    String category,
                                    String name,
                                    String argumentsAsJson);
+
+/// Reports an instant event.
+external void _reportInstantEvent(int start,
+                                  String category,
+                                  String name,
+                                  String argumentsAsJson);
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 4983498..88d2b88 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -727,7 +727,7 @@
  *
  * See also:
  *
- * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
+ * * [`<area>`](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
  * on MDN.
  */
 @DomName('HTMLAreaElement')
@@ -1627,10 +1627,9 @@
    *
    * ## Other resources
    *
-   * * [WebGL fundamentals]
-   * (http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/) from
-   * HTML5Rocks.
-   * * [WebGL homepage] (http://get.webgl.org/).
+   * * [WebGL fundamentals](http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/)
+   *   from HTML5Rocks.
+   * * [WebGL homepage](http://get.webgl.org/).
    */
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -1729,7 +1728,8 @@
  * See also:
  *
  * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
- * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
+ * * [CanvasGradient](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)
+ *   from WHATWG.
  * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
  */
 @DomName('CanvasGradient')
@@ -1781,7 +1781,8 @@
  *
  * See also:
  * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
- * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
+ * * [CanvasPattern](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)
+ *   from WHATWG.
  * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
  */
 @DomName('CanvasPattern')
@@ -1849,9 +1850,9 @@
    *
    * ## Other resources
    *
-   * * [Image smoothing]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)
-   * from WHATWG.
+   * * [Image
+   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
+   *   from WHATWG.
    */
   @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
   @DocsEditable()
@@ -8463,7 +8464,26 @@
   @DomName('DedicatedWorkerGlobalScope.postMessage')
   @DocsEditable()
   @Experimental() // untriaged
-  void postMessage(Object message, [List<MessagePort> transfer]) native;
+  void postMessage(/*any*/ message, [List<MessagePort> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
+    return;
+  }
+  @JSName('postMessage')
+  @DomName('DedicatedWorkerGlobalScope.postMessage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void _postMessage_1(message, List<MessagePort> transfer) native;
+  @JSName('postMessage')
+  @DomName('DedicatedWorkerGlobalScope.postMessage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void _postMessage_2(message) native;
 
   /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope].
   @DomName('DedicatedWorkerGlobalScope.onmessage')
@@ -8971,7 +8991,7 @@
  *
  * See also:
  *
- * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
+ * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.
  * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
  * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
  */
@@ -9845,32 +9865,29 @@
 
   @DomName('Document.createElement')
   Element createElement(String tagName, [String typeExtension]) {
-    if (typeExtension == null) {
-      return _createElement_2(tagName);
-    } else {
-      return _createElement(tagName, typeExtension);
-    }
+    return (typeExtension == null)
+        ? _createElement_2(tagName)
+        : _createElement(tagName, typeExtension);
   }
 
   // The two-argument version of this is automatically generated, but we need to
   // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
   @DomName('Document.createElement')
-  _createElement_2(String tagName) => JS('', '#.createElement(#)', this, tagName);
+  _createElement_2(String tagName) =>
+      JS('Element', '#.createElement(#)', this, tagName);
 
   // The three-argument version of this is automatically generated, but we need to
   // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
   @DomName('Document.createElementNS')
   _createElementNS_2(String namespaceURI, String qualifiedName) =>
-      JS('', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName);
+      JS('Element', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName);
 
   @DomName('Document.createElementNS')
   @DocsEditable()
   Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) {
-    if (typeExtension == null) {
-      return _createElementNS_2(namespaceURI, qualifiedName);
-    } else {
-      return _createElementNS(namespaceURI, qualifiedName, typeExtension);
-    }
+    return (typeExtension == null)
+        ? _createElementNS_2(namespaceURI, qualifiedName)
+        : _createElementNS(namespaceURI, qualifiedName, typeExtension);
   }
 
   @DomName('Document.createNodeIterator')
@@ -11318,13 +11335,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -11336,13 +11353,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -11354,13 +11371,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -11372,13 +11389,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -11390,13 +11407,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -11408,13 +11425,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -11426,13 +11443,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -11850,13 +11867,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -11868,13 +11885,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -11886,13 +11903,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -11904,13 +11921,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -11922,13 +11939,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -11940,13 +11957,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -11958,13 +11975,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -12583,7 +12600,8 @@
    *
    * See also:
    *
-   * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
+   * * [Custom data
+   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
    */
   Map<String, String> get dataset =>
     new _DataAttributeMap(attributes);
@@ -12796,8 +12814,8 @@
    *
    * ## Other resources
    *
-   * * [Node.namespaceURI]
-   * (http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) from W3C.
+   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
+   *   from W3C.
    */
   @DomName('Element.namespaceUri')
   String get namespaceUri => _namespaceUri;
@@ -13014,11 +13032,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM 101]
-   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
-   * from HTML5Rocks.
-   * * [Shadow DOM specification]
-   * (http://www.w3.org/TR/shadow-dom/) from W3C.
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/) from W3C.
    */
   @DomName('Element.createShadowRoot')
   @SupportedBrowser(SupportedBrowser.CHROME, '25')
@@ -13034,11 +13050,10 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM 101]
-   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
-   * from HTML5Rocks.
-   * * [Shadow DOM specification]
-   * (http://www.w3.org/TR/shadow-dom/) from W3C.
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/)
+   *   from W3C.
    */
   @DomName('Element.shadowRoot')
   @SupportedBrowser(SupportedBrowser.CHROME, '25')
@@ -13569,13 +13584,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragEvent')
   @DocsEditable()
@@ -13587,13 +13602,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragendEvent')
   @DocsEditable()
@@ -13605,13 +13620,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragenterEvent')
   @DocsEditable()
@@ -13623,13 +13638,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragleaveEvent')
   @DocsEditable()
@@ -13641,13 +13656,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragoverEvent')
   @DocsEditable()
@@ -13658,13 +13673,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragstartEvent')
   @DocsEditable()
@@ -13676,13 +13691,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dropEvent')
   @DocsEditable()
@@ -14116,13 +14131,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.draggable')
   @DocsEditable()
@@ -14133,9 +14148,9 @@
    *
    * ## Other resources
    *
-   * * [Hidden attribute specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#the-hidden-attribute)
-   * from WHATWG.
+   * * [Hidden attribute
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute)
+   *   from WHATWG.
    */
   @DomName('Element.hidden')
   @DocsEditable()
@@ -14169,9 +14184,9 @@
    *
    * ## Other resources
    *
-   * * [The translate attribute]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-translate-attribute)
-   * from WHATWG.
+   * * [The translate
+   *   attribute](https://html.spec.whatwg.org/multipage/dom.html#the-translate-attribute)
+   *   from WHATWG.
    */
   @DomName('Element.translate')
   @DocsEditable()
@@ -14186,13 +14201,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.webkitdropzone')
   @DocsEditable()
@@ -14336,12 +14351,11 @@
    *
    * ## Other resources
    *
-   * * [Element.getBoundingClientRect]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
-   * from MDN.
-   * * [The getBoundingClientRect() method]
-   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
-   * from W3C.
+   * * [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
+   *   from MDN.
+   * * [The getBoundingClientRect()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
    */
   @DomName('Element.getBoundingClientRect')
   @DocsEditable()
@@ -14353,12 +14367,11 @@
    *
    * ## Other resources
    *
-   * * [Element.getClientRects]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
-   * from MDN.
-   * * [The getClientRects() method]
-   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
-   * from W3C.
+   * * [Element.getClientRects](https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
+   *   from MDN.
+   * * [The getClientRects()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
    */
   @DomName('Element.getClientRects')
   @DocsEditable()
@@ -14372,9 +14385,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM specification]
-   * (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
-   * from W3C.
+   * * [Shadow DOM
+   *   specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
+   *   from W3C.
    */
   @DomName('Element.getDestinationInsertionPoints')
   @DocsEditable()
@@ -14388,11 +14401,9 @@
    *
    * ## Other resources
    *
-   * * [getElementsByClassName]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
-   * from MDN.
-   * * [DOM specification]
-   * (http://www.w3.org/TR/domcore/) from W3C.
+   * * [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
+   *   from MDN.
+   * * [DOM specification](http://www.w3.org/TR/domcore/) from W3C.
    */
   @DomName('Element.getElementsByClassName')
   @DocsEditable()
@@ -14592,13 +14603,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -14610,13 +14621,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -14628,13 +14639,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -14646,13 +14657,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -14664,13 +14675,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -14682,13 +14693,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -14700,13 +14711,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -15340,8 +15351,8 @@
    *
    * ## Other resources
    *
-   * * [Target phase] (http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
-   * from W3C.
+   * * [Target phase](http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
+   *   from W3C.
    */
   @DomName('Event.AT_TARGET')
   @DocsEditable()
@@ -15352,8 +15363,8 @@
    *
    * ## Other resources
    *
-   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
-   * from W3C.
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
    */
   @DomName('Event.BUBBLING_PHASE')
   @DocsEditable()
@@ -15365,8 +15376,8 @@
    *
    * ## Other resources
    *
-   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
-   * from W3C.
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
    */
   @DomName('Event.CAPTURING_PHASE')
   @DocsEditable()
@@ -15385,8 +15396,8 @@
    *
    * ## Other resources
    *
-   * * [clipboardData specification]
-   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.
+   * * [clipboardData specification](http://www.w3.org/TR/clipboard-apis/#attributes)
+   *   from W3C.
    */
   @DomName('Event.clipboardData')
   @DocsEditable()
@@ -15421,9 +15432,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   @DomName('Event.path')
   @DocsEditable()
@@ -17095,10 +17106,19 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+// We implement EventTarget and have stubs for its methods because it's tricky to
+// convince the scripts to make our instance methods abstract, and the bodies that
+// get generated require `this` to be an EventTarget.
 @DocsEditable()
 @DomName('GlobalEventHandlers')
 @Experimental() // untriaged
-abstract class GlobalEventHandlers extends EventTarget {
+abstract class GlobalEventHandlers implements EventTarget {
+
+  void addEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  bool dispatchEvent(Event event);
+  void removeEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  Events get on;
+
   // To suppress missing implicit constructor warnings.
   factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }
 
@@ -17668,10 +17688,17 @@
   factory HashChangeEvent(String type,
       {bool canBubble: true, bool cancelable: true, String oldUrl,
       String newUrl}) {
-    var event = document._createEvent("HashChangeEvent");
-    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
-    return event;
+
+    var options = {
+      'canBubble' : canBubble,
+      'cancelable' : cancelable,
+      'oldURL': oldUrl,
+      'newURL': newUrl,
+    };
+    return JS('HashChangeEvent', 'new HashChangeEvent(#, #)',
+        type, convertDartToNative_Dictionary(options));
   }
+
   // To suppress missing implicit constructor warnings.
   factory HashChangeEvent._() { throw new UnsupportedError("Not supported"); }
 
@@ -17864,7 +17891,32 @@
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  void pushState(Object data, String title, [String url]) native;
+  void pushState(/*any*/ data, String title, [String url]) {
+    if (url != null) {
+      var data_1 = convertDartToNative_SerializedScriptValue(data);
+      _pushState_1(data_1, title, url);
+      return;
+    }
+    var data_1 = convertDartToNative_SerializedScriptValue(data);
+    _pushState_2(data_1, title);
+    return;
+  }
+  @JSName('pushState')
+  @DomName('History.pushState')
+  @DocsEditable()
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _pushState_1(data, title, url) native;
+  @JSName('pushState')
+  @DomName('History.pushState')
+  @DocsEditable()
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _pushState_2(data, title) native;
 
   @DomName('History.replaceState')
   @DocsEditable()
@@ -17872,7 +17924,32 @@
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  void replaceState(Object data, String title, [String url]) native;
+  void replaceState(/*any*/ data, String title, [String url]) {
+    if (url != null) {
+      var data_1 = convertDartToNative_SerializedScriptValue(data);
+      _replaceState_1(data_1, title, url);
+      return;
+    }
+    var data_1 = convertDartToNative_SerializedScriptValue(data);
+    _replaceState_2(data_1, title);
+    return;
+  }
+  @JSName('replaceState')
+  @DomName('History.replaceState')
+  @DocsEditable()
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _replaceState_1(data, title, url) native;
+  @JSName('replaceState')
+  @DomName('History.replaceState')
+  @DocsEditable()
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  void _replaceState_2(data, title) native;
 }
 // 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
@@ -17959,7 +18036,9 @@
   @DomName('Document.body')
   BodyElement body;
 
+  /// UNSTABLE: Chrome-only - create a Range from the given point.
   @DomName('Document.caretRangeFromPoint')
+  @Unstable()
   Range caretRangeFromPoint(int x, int y) {
     return _caretRangeFromPoint(x, y);
   }
@@ -18045,11 +18124,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitExitFullscreen')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -18073,11 +18151,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -18090,11 +18167,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenEnabled')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -18797,7 +18873,8 @@
    * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
    * `responseType` is set while performing a synchronous request.
    *
-   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+   * See also: [MDN
+   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
    */
   @DomName('XMLHttpRequest.responseType')
   @DocsEditable()
@@ -18822,8 +18899,8 @@
   final Document responseXml;
 
   /**
-   * The http result code from the request (200, 404, etc).
-   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   * The HTTP result code from the request (200, 404, etc).
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
    */
   @DomName('XMLHttpRequest.status')
   @DocsEditable()
@@ -18831,7 +18908,7 @@
 
   /**
    * The request response string (such as \"200 OK\").
-   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
    */
   @DomName('XMLHttpRequest.statusText')
   @DocsEditable()
@@ -18846,12 +18923,10 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.timeout]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
-   * from MDN.
-   * * [The timeout attribute]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
-   * from W3C.
+   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)
+   *   from MDN.
+   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.timeout')
   @DocsEditable()
@@ -18895,7 +18970,8 @@
    * `getAllResponseHeaders` will return the response headers for the current
    * part of the request.
    *
-   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
    * for a list of common response headers.
    */
   @DomName('XMLHttpRequest.getAllResponseHeaders')
@@ -18906,7 +18982,8 @@
   /**
    * Return the response header named `header`, or null if not found.
    *
-   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
    * for a list of common response headers.
    */
   @DomName('XMLHttpRequest.getResponseHeader')
@@ -18919,7 +18996,7 @@
    * response.
    *
    * This value must be set before the request has been sent. See also the list
-   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
+   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml)
    */
   @DomName('XMLHttpRequest.overrideMimeType')
   @DocsEditable()
@@ -18938,9 +19015,8 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.send]
-   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
-   * from MDN.
+   * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
+   *   from MDN.
    */
   @DomName('XMLHttpRequest.send')
   @DocsEditable()
@@ -18957,12 +19033,11 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.setRequestHeader]
-   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
-   * from MDN.
-   * * [The setRequestHeader() method]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from
-   * W3C.
+   * * [XMLHttpRequest.setRequestHeader](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader())
+   *   from MDN.
+   * * [The setRequestHeader()
+   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.setRequestHeader')
   @DocsEditable()
@@ -23817,9 +23892,8 @@
    *
    * ## Other resources
    *
-   * * [Node.childNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
-   * from MDN.
+   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
+   *   from MDN.
    */
   @DomName('Node.childNodes')
   @DocsEditable()
@@ -23888,9 +23962,8 @@
    *
    * ## Other resources
    *
-   * * [Node.firstChild]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
-   * from MDN.
+   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
+   *   from MDN.
    */
   @DomName('Node.firstChild')
   @DocsEditable()
@@ -23901,9 +23974,8 @@
    *
    * ## Other resources
    *
-   * * [Node.lastChild]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
-   * from MDN.
+   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
+   *   from MDN.
    */
   @DomName('Node.lastChild')
   @DocsEditable()
@@ -23925,9 +23997,8 @@
    *
    * ## Other resources
    *
-   * * [Node.nextSibling]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
-   * from MDN.
+   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
+   *   from MDN.
    */
   @DomName('Node.nextSibling')
   @DocsEditable()
@@ -23940,10 +24011,9 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeName]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
-   * from MDN. This page contains a table of [nodeName] values for each
-   * [nodeType].
+   * * [Node.nodeName](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
+   *   from MDN. This page contains a table of [nodeName] values for each
+   *   [nodeType].
    */
   @DomName('Node.nodeName')
   @DocsEditable()
@@ -23969,8 +24039,8 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeType]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType) from MDN.
+   * * [Node.nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType)
+   *   from MDN.
    */
   @DomName('Node.nodeType')
   @DocsEditable()
@@ -23983,10 +24053,9 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeValue]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
-   * from MDN. This page contains a table of [nodeValue] values for each
-   * [nodeType].
+   * * [Node.nodeValue](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
+   *   from MDN. This page contains a table of [nodeValue] values for each
+   *   [nodeType].
    */
   @DomName('Node.nodeValue')
   @DocsEditable()
@@ -23999,9 +24068,8 @@
    *
    * ## Other resources
    *
-   * * [Node.ownerDocument]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument) from
-   * MDN.
+   * * [Node.ownerDocument](https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument)
+   *   from MDN.
    */
   @DomName('Node.ownerDocument')
   @DocsEditable()
@@ -24016,9 +24084,8 @@
    *
    * ## Other resources
    *
-   * * [Node.parentElement]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement) from
-   * W3C.
+   * * [Node.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement)
+   *   from W3C.
    */
   @DomName('Node.parentElement')
   @DocsEditable()
@@ -24029,9 +24096,8 @@
    *
    * ## Other resources
    *
-   * * [Node.parentNode]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode) from
-   * MDN.
+   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)
+   *   from MDN.
    */
   @DomName('Node.parentNode')
   @DocsEditable()
@@ -24043,9 +24109,8 @@
    *
    * ## Other resources
    *
-   * * [Node.previousSibling]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
-   * from MDN.
+   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
+   *   from MDN.
    */
   @DomName('Node.previousSibling')
   @DocsEditable()
@@ -24057,9 +24122,8 @@
    *
    * ## Other resources
    *
-   * * [Node.textContent]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
-   * MDN.
+   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
+   *   from MDN.
    */
   @DomName('Node.textContent')
   @DocsEditable()
@@ -24088,9 +24152,8 @@
    *
    * ## Other resources
    *
-   * * [Node.cloneNode]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from
-   * MDN.
+   * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode)
+   *   from MDN.
    */
   @DomName('Node.cloneNode')
   @DocsEditable()
@@ -24101,8 +24164,8 @@
    *
    * ## Other resources
    *
-   * * [Node.contains]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.contains) from MDN.
+   * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)
+   *   from MDN.
    */
   @DomName('Node.contains')
   @DocsEditable()
@@ -24113,9 +24176,8 @@
    *
    * ## Other resources
    *
-   * * [Node.hasChildNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes) from
-   * MDN.
+   * * [Node.hasChildNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes)
+   *   from MDN.
    */
   @DomName('Node.hasChildNodes')
   @DocsEditable()
@@ -24126,9 +24188,8 @@
    *
    * ## Other resources
    *
-   * * [Node.insertBefore]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) from
-   * MDN.
+   * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore)
+   *   from MDN.
    */
   @DomName('Node.insertBefore')
   @DocsEditable()
@@ -27394,7 +27455,26 @@
   @DomName('ServiceWorkerClient.postMessage')
   @DocsEditable()
   @Experimental() // untriaged
-  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) native;
+  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
+    return;
+  }
+  @JSName('postMessage')
+  @DomName('ServiceWorkerClient.postMessage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void _postMessage_1(message, List<MessagePort> transfer) native;
+  @JSName('postMessage')
+  @DomName('ServiceWorkerClient.postMessage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void _postMessage_2(message) native;
 }
 // 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
@@ -31885,26 +31965,27 @@
    *
    * ## Other resources
    *
-   * * [Loading web pages]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
-   * from WHATWG.
+   * * [Loading web
+   *   pages](https://html.spec.whatwg.org/multipage/browsers.html)
+   *   from WHATWG.
    */
   Document get document => JS('Document', '#.document', this);
 
-  WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);
+  WindowBase _open2(url, name) =>
+      JS('Window|Null', '#.open(#,#)', this, url, name);
 
   WindowBase _open3(url, name, options) =>
-      JS('Window', '#.open(#,#,#)', this, url, name, options);
+      JS('Window|Null', '#.open(#,#,#)', this, url, name, options);
 
   /**
    * Opens a new window.
    *
    * ## Other resources
    *
-   * * [Window.open]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.open) from MDN.
-   * * [Window open]
-   * (http://docs.webplatform.org/wiki/dom/methods/open) from WebPlatform.org.
+   * * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
+   *   from MDN.
+   * * [Window open](http://docs.webplatform.org/wiki/dom/methods/open)
+   *   from WebPlatform.org.
    */
   WindowBase open(String url, String name, [String options]) {
     if (options == null) {
@@ -31966,8 +32047,8 @@
    *
    * ## Other resources
    *
-   * * [Window.cancelAnimationFrame]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame) from MDN.
+   * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
+   *   from MDN.
    */
   void cancelAnimationFrame(int id) {
     _ensureRequestAnimationFrame();
@@ -32223,10 +32304,11 @@
    *
    * ## Other resources
    *
-   * * [Exploring the FileSystem APIs]
-   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
-   * * [File API]
-   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)
+   *   from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
    */
   @DomName('Window.PERSISTENT')
   @DocsEditable()
@@ -32239,10 +32321,10 @@
    *
    * ## Other resources
    *
-   * * [Exploring the FileSystem APIs]
-   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
-   * * [File API]
-   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
    */
   @DomName('Window.TEMPORARY')
   @DocsEditable()
@@ -32267,11 +32349,12 @@
    *
    * ## Other resources
    *
-   * * [A beginner's guide to using the application cache]
-   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.
-   * * [Application cache API]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)
-   * from WHATWG.
+   * * [A beginner's guide to using the application
+   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)
+   *   from HTML5Rocks.
+   * * [Application cache
+   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)
+   *   from WHATWG.
    */
   @DomName('Window.applicationCache')
   @DocsEditable()
@@ -32311,12 +32394,10 @@
    *
    * ## Other resources
    *
-   * * [devicePixelRatio]
-   * (http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html) from
-   * quirksmode.
-   * * [More about devicePixelRatio]
-   * (http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html) from
-   * quirksmode.
+   * * [devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)
+   *   from quirksmode.
+   * * [More about devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html)
+   *   from quirksmode.
    */
   @DomName('Window.devicePixelRatio')
   @DocsEditable()
@@ -32329,9 +32410,8 @@
    *
    * ## Other resources
    *
-   * * [Loading web pages]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
-   * from WHATWG.
+   * * [Loading web pages](https://html.spec.whatwg.org/multipage/browsers.html)
+   *   from WHATWG.
    */
   @DomName('Window.history')
   @DocsEditable()
@@ -32342,9 +32422,8 @@
    *
    * ## Other resources
    *
-   * * [innerHeight]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight) from
-   * WebPlatform.org.
+   * * [innerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight)
+   *   from WebPlatform.org.
    */
   @DomName('Window.innerHeight')
   @DocsEditable()
@@ -32355,9 +32434,8 @@
    *
    * ## Other resources
    *
-   * * [innerWidth]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth) from
-   * WebPlatform.org.
+   * * [innerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth)
+   *   from WebPlatform.org.
    */
   @DomName('Window.innerWidth')
   @DocsEditable()
@@ -32368,13 +32446,12 @@
    *
    * ## Other resources
    *
-   * * [DOM storage guide]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
-   * MDN.
-   * * [The past, present & future of local storage for web applications]
-   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
-   * * [Local storage specification]
-   * (http://www.w3.org/TR/webstorage/#the-localstorage-attribute) from W3C.
+   * * [DOM storage guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage specification](http://www.w3.org/TR/webstorage/#the-localstorage-attribute)
+   *   from W3C.
    */
   @DomName('Window.localStorage')
   @DocsEditable()
@@ -32385,9 +32462,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.locationbar')
   @DocsEditable()
@@ -32398,9 +32475,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.menubar')
   @DocsEditable()
@@ -32411,9 +32488,8 @@
    *
    * ## Other resources
    *
-   * * [Window name]
-   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from
-   * WebPlatform.org.
+   * * [Window name](http://docs.webplatform.org/wiki/html/attributes/name_(window))
+   *   from WebPlatform.org.
    */
   @DomName('Window.name')
   @DocsEditable()
@@ -32424,9 +32500,9 @@
    *
    * ## Other resources
    *
-   * * [The navigator object]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#the-navigator-object)
-   * from WHATWG.
+   * * [The navigator
+   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
+   *   from WHATWG.
    */
   @DomName('Window.navigator')
   @DocsEditable()
@@ -32437,9 +32513,8 @@
    *
    * ## Other resources
    *
-   * * [offscreenBuffering]
-   * (http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering) from
-   * WebPlatform.org.
+   * * [offscreenBuffering](http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering)
+   *   from WebPlatform.org.
    */
   @DomName('Window.offscreenBuffering')
   @DocsEditable()
@@ -32470,9 +32545,8 @@
    *
    * ## Other resources
    *
-   * * [outerHeight]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight) from
-   * WebPlatform.org.
+   * * [outerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight)
+   *   from WebPlatform.org.
    */
   @DomName('Window.outerHeight')
   @DocsEditable()
@@ -32483,9 +32557,8 @@
    *
    * ## Other resources
    *
-   * * [outerWidth]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth) from
-   * WebPlatform.org.
+   * * [outerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth)
+   *   from WebPlatform.org.
    */
   @DomName('Window.outerWidth')
   @DocsEditable()
@@ -32499,10 +32572,11 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollX and pageXOffset]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollX and
+   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
+   *   from MDN.
    */
   @DomName('Window.pageXOffset')
   @DocsEditable()
@@ -32516,10 +32590,11 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollY and pageYOffset]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollY and
+   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
+   *   from MDN.
    */
   @DomName('Window.pageYOffset')
   @DocsEditable()
@@ -32540,11 +32615,11 @@
    *
    * ## Other resources
    *
-   * * [Measuring page load speed with navigation timeing]
-   * (http://www.html5rocks.com/en/tutorials/webperformance/basics/) from
-   * HTML5Rocks.
-   * * [Navigation timing specification]
-   * (http://www.w3.org/TR/navigation-timing/) from W3C.
+   * * [Measuring page load speed with navigation
+   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)
+   *   from HTML5Rocks.
+   * * [Navigation timing
+   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.
    */
   @DomName('Window.performance')
   @DocsEditable()
@@ -32558,8 +32633,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screen')
   @DocsEditable()
@@ -32571,8 +32646,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenLeft')
   @DocsEditable()
@@ -32583,8 +32658,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenTop')
   @DocsEditable()
@@ -32595,8 +32670,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenX')
   @DocsEditable()
@@ -32607,8 +32682,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenY')
   @DocsEditable()
@@ -32619,9 +32694,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.scrollbars')
   @DocsEditable()
@@ -32632,8 +32707,8 @@
    *
    * ## Other resources
    *
-   * * [Window.self]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
+   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
+   *   from MDN.
    */
   @DomName('Window.self')
   @DocsEditable()
@@ -32644,8 +32719,8 @@
    *
    * ## Other resources
    *
-   * * [Window.self]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
+   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
+   *   from MDN.
    */
   @DomName('Window.self')
   @DocsEditable()
@@ -32658,13 +32733,13 @@
    *
    * ## Other resources
    *
-   * * [DOM storage guide]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
-   * MDN.
-   * * [The past, present & future of local storage for web applications]
-   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
-   * * [Local storage specification]
-   * (http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
+   * * [DOM storage
+   *   guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage
+   *   specification](http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
    */
   @DomName('Window.sessionStorage')
   @DocsEditable()
@@ -32675,9 +32750,9 @@
    *
    * ## Other resources
    *
-   * * [Web speech specification]
-   * (https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
-   * from W3C.
+   * * [Web speech
+   *   specification](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
+   *   from W3C.
    */
   @DomName('Window.speechSynthesis')
   @DocsEditable()
@@ -32695,9 +32770,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.statusbar')
   @DocsEditable()
@@ -32708,9 +32783,9 @@
    *
    * ## Other resources
    *
-   * * [StyleMedia class reference]
-   * (https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html)
-   * from Safari Developer Library.
+   * * [StyleMedia class
+   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)
+   *   from Safari Developer Library.
    */
   @DomName('Window.styleMedia')
   @DocsEditable()
@@ -32723,9 +32798,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.toolbar')
   @DocsEditable()
@@ -32746,8 +32821,8 @@
    *
    * ## Other resources
    *
-   * * [Window.window]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
+   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
+   *   from MDN.
    */
   @DomName('Window.window')
   @DocsEditable()
@@ -32758,8 +32833,8 @@
    *
    * ## Other resources
    *
-   * * [Window.window]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
+   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
+   *   from MDN.
    */
   @DomName('Window.window')
   @DocsEditable()
@@ -32798,9 +32873,8 @@
    *
    * ## Other resources
    *
-   * * [User prompts]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)
-   * from WHATWG.
+   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
+   *   from WHATWG.
    */
   @DomName('Window.alert')
   @DocsEditable()
@@ -32815,9 +32889,8 @@
    *
    * ## Other resources
    *
-   * * [User prompts]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)
-   * from WHATWG.
+   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
+   *   from WHATWG.
    */
   @DomName('Window.confirm')
   @DocsEditable()
@@ -32828,8 +32901,8 @@
    *
    * ## Other resources
    *
-   * * [Window.find]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.find) from MDN.
+   * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find)
+   *   from MDN.
    */
   @DomName('Window.find')
   @DocsEditable()
@@ -32857,9 +32930,8 @@
    *
    * ## Other resources
    *
-   * * [Window.getSelection]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
-   * from MDN.
+   * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
+   *   from MDN.
    */
   @DomName('Window.getSelection')
   @DocsEditable()
@@ -32870,11 +32942,11 @@
    *
    * ## Other resources
    *
-   * * [Testing media queries]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
-   * from MDN.
-   * * [The MediaQueryList specification]
-   * (http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
+   * * [Testing media
+   *   queries](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
+   *   from MDN.
+   * * [The MediaQueryList
+   *   specification](http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
    */
   @DomName('Window.matchMedia')
   @DocsEditable()
@@ -32887,10 +32959,9 @@
    *
    * ## Other resources
    *
-   * * [Window.moveBy]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy) from MDN.
-   * * [Window.moveBy]
-   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
+   * * [Window.moveBy](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy)
+   *   from MDN.
+   * * [Window.moveBy](http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
    */
   @DomName('Window.moveBy')
   @DocsEditable()
@@ -32938,8 +33009,8 @@
    *
    * ## Other resources
    *
-   * * [Window.print]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.print) from MDN.
+   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)
+   *   from MDN.
    */
   @DomName('Window.print')
   @DocsEditable()
@@ -32950,8 +33021,8 @@
    *
    * ## Other resources
    *
-   * * [Window resizeBy] (http://docs.webplatform.org/wiki/dom/methods/resizeBy)
-   * from WebPlatform.org.
+   * * [Window resizeBy](http://docs.webplatform.org/wiki/dom/methods/resizeBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.resizeBy')
   @DocsEditable()
@@ -32962,8 +33033,8 @@
    *
    * ## Other resources
    *
-   * * [Window resizeTo] (http://docs.webplatform.org/wiki/dom/methods/resizeTo)
-   * from WebPlatform.org.
+   * * [Window resizeTo](http://docs.webplatform.org/wiki/dom/methods/resizeTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.resizeTo')
   @DocsEditable()
@@ -32976,8 +33047,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33010,8 +33081,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33024,8 +33095,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33038,8 +33109,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33052,8 +33123,8 @@
    *
    * ## Other resources
    *
-   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
-   * from WebPlatform.org.
+   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scroll')
   @DocsEditable()
@@ -33064,8 +33135,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33096,8 +33167,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33108,8 +33179,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33120,8 +33191,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33132,8 +33203,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
-   * from WebPlatform.org.
+   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollBy')
   @DocsEditable()
@@ -33146,8 +33217,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33180,8 +33251,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33194,8 +33265,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33208,8 +33279,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33222,8 +33293,8 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
-   * from WebPlatform.org.
+   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.scrollTo')
   @DocsEditable()
@@ -33234,9 +33305,9 @@
    *
    * ## Other resources
    *
-   * * [Dialogs implemented using separate documents]
-   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
-   * from W3C.
+   * * [Dialogs implemented using separate
+   *   documents](http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
+   *   from W3C.
    */
   @DomName('Window.showModalDialog')
   @DocsEditable()
@@ -33248,9 +33319,9 @@
    *
    * ## Other resources
    *
-   * * [The Window object]
-   * (http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
-   * from W3C.
+   * * [The Window
+   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
+   *   from W3C.
    */
   @DomName('Window.stop')
   @DocsEditable()
@@ -33284,8 +33355,8 @@
    *
    * ## Other resources
    *
-   * * [Obtaining access to file system entry points]
-   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
+   * * [Obtaining access to file system entry
+   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
    * from W3C.
    */
   @DomName('Window.webkitResolveLocalFileSystemURL')
@@ -33301,8 +33372,8 @@
    *
    * ## Other resources
    *
-   * * [Obtaining access to file system entry points]
-   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
+   * * [Obtaining access to file system entry
+   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
    * from W3C.
    */
   @DomName('Window.webkitResolveLocalFileSystemURL')
@@ -33746,10 +33817,10 @@
    *
    * ## Other resources
    *
-   * * [Window.moveTo]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo) from MDN.
-   * * [Window.moveTo]
-   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveto) from W3C.
+   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
+   *   from MDN.
+   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
+   *   from W3C.
    */
   void moveTo(Point p) {
     _moveTo(p.x, p.y);
@@ -33768,10 +33839,10 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollX]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
+   *   from MDN.
    */
   @DomName('Window.scrollX')
   @DocsEditable()
@@ -33784,10 +33855,10 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollY]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
+   *   from MDN.
    */
   @DomName('Window.scrollY')
   @DocsEditable()
@@ -33994,7 +34065,24 @@
 
   @DomName('Worker.postMessage')
   @DocsEditable()
-  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) native;
+  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
+    return;
+  }
+  @JSName('postMessage')
+  @DomName('Worker.postMessage')
+  @DocsEditable()
+  void _postMessage_1(message, List<MessagePort> transfer) native;
+  @JSName('postMessage')
+  @DomName('Worker.postMessage')
+  @DocsEditable()
+  void _postMessage_2(message) native;
 
   @DomName('Worker.terminate')
   @DocsEditable()
@@ -36229,12 +36317,11 @@
  *
  * ## Other resources
  *
- * * [Image sources for 2D rendering contexts]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
- * from WHATWG.
- * * [Drawing images]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
- * from WHATWG.
+ * * [Image sources for 2D rendering
+ *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
+ *   from WHATWG.
+ * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
+ *   from WHATWG.
  */
 abstract class CanvasImageSource {}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -36277,9 +36364,9 @@
    *
    * ## Other resources
    *
-   * * [Session history and navigation specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
-   * from WHATWG.
+   * * [Session history and navigation
+   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
+   *   from WHATWG.
    */
   HistoryBase get history;
 
@@ -36372,12 +36459,10 @@
    *
    * ## Other resources
    *
-   * * [window.postMessage]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
-   * MDN.
-   * * [Cross-document messaging]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
-   * from WHATWG.
+   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
+   *   from MDN.
+   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
+   *   from WHATWG.
    */
   void postMessage(var message, String targetOrigin, [List messagePorts]);
 }
@@ -37221,9 +37306,8 @@
    *
    * ## Other resources
    *
-   * * [Event Capture]
-   * (http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
-   * from the W3C DOM Events specification.
+   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
+   *   from the W3C DOM Events specification.
    */
   StreamSubscription<T> capture(void onData(T event));
 }
@@ -37781,6 +37865,7 @@
     'INPUT::align',
     'INPUT::alt',
     'INPUT::autocomplete',
+    'INPUT::autofocus',
     'INPUT::checked',
     'INPUT::disabled',
     'INPUT::inputmode',
@@ -40630,9 +40715,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
   @Experimental()
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 109eca3..3ef584b 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -1160,32 +1160,6 @@
 
 }
 
-/// Upgrade a Dart HtmlElement to the user's Dart custom element class.
-_upgradeHtmlElement(dartInstance) {
-  // Only try upgrading HtmlElement (Dart class) if there is a failure then
-  // don't try it again - one failure is enough.
-  if (dartInstance.runtimeType == HtmlElement && !dartInstance.isBadUpgrade) {
-    // Must be exactly HtmlElement not something derived from it.
-
-    var customElementClass = getCustomElementType(dartInstance);
-
-    // Custom Element to upgrade.
-    if (customElementClass != null) {
-      var jsObject = dartInstance.blink_jsObject;
-      try {
-        dartInstance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
-      } catch (e) {
-        dartInstance._badUpgrade();
-      } finally {
-        dartInstance.blink_jsObject = jsObject;
-        js.setDartHtmlWrapperFor(jsObject, dartInstance);
-     }
-   }
-  }
-
-  return dartInstance;
-}
-
 @Deprecated("Internal Use Only")
 class DebugAssertException implements Exception {
   String message;
@@ -1235,7 +1209,12 @@
   try {
     dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
   } catch (e) {
-    dartClass._badUpgrade();
+    // Did the dartClass get allocated but the created failed?  Otherwise, other
+    // components inside of this failed somewhere (could be JS custom element).
+    if (dartClass != null) {
+      // Yes, mark as didn't upgrade.
+      dartClass._badUpgrade();
+    }
     throw e;
   } finally {
     // Need to remember the Dart class that was created for this custom so
@@ -2093,7 +2072,7 @@
  *
  * See also:
  *
- * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
+ * * [`<area>`](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
  * on MDN.
  */
 @DomName('HTMLAreaElement')
@@ -3386,10 +3365,9 @@
    *
    * ## Other resources
    *
-   * * [WebGL fundamentals]
-   * (http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/) from
-   * HTML5Rocks.
-   * * [WebGL homepage] (http://get.webgl.org/).
+   * * [WebGL fundamentals](http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/)
+   *   from HTML5Rocks.
+   * * [WebGL homepage](http://get.webgl.org/).
    */
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -3490,7 +3468,8 @@
  * See also:
  *
  * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
- * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
+ * * [CanvasGradient](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)
+ *   from WHATWG.
  * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
  */
 @DomName('CanvasGradient')
@@ -3559,7 +3538,8 @@
  *
  * See also:
  * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
- * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
+ * * [CanvasPattern](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)
+ *   from WHATWG.
  * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
  */
 @DomName('CanvasPattern')
@@ -3680,9 +3660,9 @@
    *
    * ## Other resources
    *
-   * * [Image smoothing]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)
-   * from WHATWG.
+   * * [Image
+   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
+   *   from WHATWG.
    */
   @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
   @DocsEditable()
@@ -3695,9 +3675,9 @@
    *
    * ## Other resources
    *
-   * * [Image smoothing]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)
-   * from WHATWG.
+   * * [Image
+   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
+   *   from WHATWG.
    */
   @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
   @DocsEditable()
@@ -9555,7 +9535,7 @@
   @DomName('DedicatedWorkerGlobalScope.postMessage')
   @DocsEditable()
   @Experimental() // untriaged
-  void postMessage(Object message, [List<MessagePort> transfer]) => _blink.BlinkDedicatedWorkerGlobalScope.instance.postMessage_Callback_2_(unwrap_jso(this), message, transfer);
+  void postMessage(Object message, [List<MessagePort> transfer]) => _blink.BlinkDedicatedWorkerGlobalScope.instance.postMessage_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
   
   /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope].
   @DomName('DedicatedWorkerGlobalScope.onmessage')
@@ -10235,7 +10215,7 @@
  *
  * See also:
  *
- * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
+ * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.
  * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
  * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
  */
@@ -12970,13 +12950,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -12988,13 +12968,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -13006,13 +12986,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -13024,13 +13004,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -13042,13 +13022,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -13060,13 +13040,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -13078,13 +13058,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -13506,13 +13486,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -13524,13 +13504,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -13542,13 +13522,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -13560,13 +13540,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -13578,13 +13558,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -13596,13 +13576,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -13614,13 +13594,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -14238,7 +14218,8 @@
    *
    * See also:
    *
-   * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
+   * * [Custom data
+   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
    */
   Map<String, String> get dataset =>
     new _DataAttributeMap(attributes);
@@ -14445,8 +14426,8 @@
    *
    * ## Other resources
    *
-   * * [Node.namespaceURI]
-   * (http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) from W3C.
+   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
+   *   from W3C.
    */
   @DomName('Element.namespaceUri')
   String get namespaceUri => _namespaceUri;
@@ -15067,13 +15048,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragEvent')
   @DocsEditable()
@@ -15085,13 +15066,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragendEvent')
   @DocsEditable()
@@ -15103,13 +15084,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragenterEvent')
   @DocsEditable()
@@ -15121,13 +15102,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragleaveEvent')
   @DocsEditable()
@@ -15139,13 +15120,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragoverEvent')
   @DocsEditable()
@@ -15156,13 +15137,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dragstartEvent')
   @DocsEditable()
@@ -15174,13 +15155,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.dropEvent')
   @DocsEditable()
@@ -15799,12 +15780,11 @@
    *
    * ## Other resources
    *
-   * * [Element.getBoundingClientRect]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
-   * from MDN.
-   * * [The getBoundingClientRect() method]
-   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
-   * from W3C.
+   * * [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
+   *   from MDN.
+   * * [The getBoundingClientRect()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
    */
   @DomName('Element.getBoundingClientRect')
   @DocsEditable()
@@ -15816,12 +15796,11 @@
    *
    * ## Other resources
    *
-   * * [Element.getClientRects]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
-   * from MDN.
-   * * [The getClientRects() method]
-   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
-   * from W3C.
+   * * [Element.getClientRects](https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
+   *   from MDN.
+   * * [The getClientRects()
+   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
+   *   from W3C.
    */
   @DomName('Element.getClientRects')
   @DocsEditable()
@@ -15833,9 +15812,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM specification]
-   * (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
-   * from W3C.
+   * * [Shadow DOM
+   *   specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
+   *   from W3C.
    */
   @DomName('Element.getDestinationInsertionPoints')
   @DocsEditable()
@@ -15847,11 +15826,9 @@
    *
    * ## Other resources
    *
-   * * [getElementsByClassName]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
-   * from MDN.
-   * * [DOM specification]
-   * (http://www.w3.org/TR/domcore/) from W3C.
+   * * [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
+   *   from MDN.
+   * * [DOM specification](http://www.w3.org/TR/domcore/) from W3C.
    */
   @DomName('Element.getElementsByClassName')
   @DocsEditable()
@@ -16059,13 +16036,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrag')
   @DocsEditable()
@@ -16077,13 +16054,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragend')
   @DocsEditable()
@@ -16095,13 +16072,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragenter')
   @DocsEditable()
@@ -16113,13 +16090,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragleave')
   @DocsEditable()
@@ -16131,13 +16108,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragover')
   @DocsEditable()
@@ -16149,13 +16126,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondragstart')
   @DocsEditable()
@@ -16167,13 +16144,13 @@
    *
    * ## Other resources
    *
-   * * [Drag and drop sample]
-   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
-   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
-   * from HTML5Rocks.
-   * * [Drag and drop specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
-   * from WHATWG.
+   * * [Drag and drop
+   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
+   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
+   *   from HTML5Rocks.
+   * * [Drag and drop
+   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
+   *   from WHATWG.
    */
   @DomName('Element.ondrop')
   @DocsEditable()
@@ -16905,8 +16882,8 @@
    *
    * ## Other resources
    *
-   * * [Target phase] (http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
-   * from W3C.
+   * * [Target phase](http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
+   *   from W3C.
    */
   @DomName('Event.AT_TARGET')
   @DocsEditable()
@@ -16917,8 +16894,8 @@
    *
    * ## Other resources
    *
-   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
-   * from W3C.
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
    */
   @DomName('Event.BUBBLING_PHASE')
   @DocsEditable()
@@ -16930,8 +16907,8 @@
    *
    * ## Other resources
    *
-   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
-   * from W3C.
+   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
+   *   from W3C.
    */
   @DomName('Event.CAPTURING_PHASE')
   @DocsEditable()
@@ -16950,8 +16927,8 @@
    *
    * ## Other resources
    *
-   * * [clipboardData specification]
-   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.
+   * * [clipboardData specification](http://www.w3.org/TR/clipboard-apis/#attributes)
+   *   from W3C.
    */
   @DomName('Event.clipboardData')
   @DocsEditable()
@@ -16980,9 +16957,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   @DomName('Event.path')
   @DocsEditable()
@@ -19123,10 +19100,19 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+// We implement EventTarget and have stubs for its methods because it's tricky to
+// convince the scripts to make our instance methods abstract, and the bodies that
+// get generated require `this` to be an EventTarget.
 @DocsEditable()
 @DomName('GlobalEventHandlers')
 @Experimental() // untriaged
-abstract class GlobalEventHandlers extends EventTarget {
+abstract class GlobalEventHandlers implements EventTarget {
+
+  void addEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  bool dispatchEvent(Event event);
+  void removeEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  Events get on;
+
   // To suppress missing implicit constructor warnings.
   factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }
 
@@ -19716,10 +19702,14 @@
   factory HashChangeEvent(String type,
       {bool canBubble: true, bool cancelable: true, String oldUrl,
       String newUrl}) {
+
+    // TODO(alanknight): This is required while we're on Dartium 39, but will need
+    // to look like dart2js with later versions when initHashChange is removed.
     var event = document._createEvent("HashChangeEvent");
     event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
     return event;
   }
+
   // To suppress missing implicit constructor warnings.
   factory HashChangeEvent._() { throw new UnsupportedError("Not supported"); }
 
@@ -19961,7 +19951,7 @@
   
   @DomName('History.state')
   @DocsEditable()
-  dynamic get state => _blink.BlinkHistory.instance.state_Getter_(unwrap_jso(this));
+  dynamic get state => wrap_jso(_blink.BlinkHistory.instance.state_Getter_(unwrap_jso(this)));
   
   @DomName('History.back')
   @DocsEditable()
@@ -19981,7 +19971,7 @@
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  void pushState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.pushState_Callback_3_(unwrap_jso(this), data, title, url);
+  void pushState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.pushState_Callback_3_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(data), title, url);
   
   @DomName('History.replaceState')
   @DocsEditable()
@@ -19989,7 +19979,7 @@
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @SupportedBrowser(SupportedBrowser.IE, '10')
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  void replaceState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.replaceState_Callback_3_(unwrap_jso(this), data, title, url);
+  void replaceState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.replaceState_Callback_3_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(data), title, url);
   }
 // 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
@@ -20113,7 +20103,9 @@
     _body = value;
   }
 
+  /// UNSTABLE: Chrome-only - create a Range from the given point.
   @DomName('Document.caretRangeFromPoint')
+  @Unstable()
   Range caretRangeFromPoint(int x, int y) {
     return _caretRangeFromPoint(x, y);
   }
@@ -20198,11 +20190,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitExitFullscreen')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -20226,11 +20217,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -20243,11 +20233,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenEnabled')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -20377,16 +20366,9 @@
             createdParametersValid = createdParametersValid && parameter.isOptional;
           });
         }
-
-        // Get the created constructor source and look at the initializer;
-        // Must call super.created() if not its as an error.
-        var createdSource = methodMirror.source;
-        superCreatedCalled = createdSource.contains("super.created(");
       }
 
-      if (!superCreatedCalled) {
-        throw new DomException.jsInterop('created constructor initializer must call super.created()');
-      } else if (!createdParametersValid) {
+      if (!createdParametersValid) {
         throw new DomException.jsInterop('created constructor must have no parameters');
       }
 
@@ -21903,7 +21885,8 @@
    * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
    * `responseType` is set while performing a synchronous request.
    *
-   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+   * See also: [MDN
+   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
    */
   @DomName('XMLHttpRequest.responseType')
   @DocsEditable()
@@ -21917,7 +21900,8 @@
    * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
    * `responseType` is set while performing a synchronous request.
    *
-   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+   * See also: [MDN
+   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
    */
   @DomName('XMLHttpRequest.responseType')
   @DocsEditable()
@@ -21940,8 +21924,8 @@
   Document get responseXml => wrap_jso(_blink.BlinkXMLHttpRequest.instance.responseXML_Getter_(unwrap_jso(this)));
   
   /**
-   * The http result code from the request (200, 404, etc).
-   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   * The HTTP result code from the request (200, 404, etc).
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
    */
   @DomName('XMLHttpRequest.status')
   @DocsEditable()
@@ -21949,7 +21933,7 @@
   
   /**
    * The request response string (such as \"200 OK\").
-   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
    */
   @DomName('XMLHttpRequest.statusText')
   @DocsEditable()
@@ -21964,12 +21948,10 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.timeout]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
-   * from MDN.
-   * * [The timeout attribute]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
-   * from W3C.
+   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)
+   *   from MDN.
+   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.timeout')
   @DocsEditable()
@@ -21985,12 +21967,10 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.timeout]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
-   * from MDN.
-   * * [The timeout attribute]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
-   * from W3C.
+   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)
+   *   from MDN.
+   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.timeout')
   @DocsEditable()
@@ -22044,7 +22024,8 @@
    * `getAllResponseHeaders` will return the response headers for the current
    * part of the request.
    *
-   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
    * for a list of common response headers.
    */
   @DomName('XMLHttpRequest.getAllResponseHeaders')
@@ -22055,7 +22036,8 @@
   /**
    * Return the response header named `header`, or null if not found.
    *
-   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * See also [HTTP response
+   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
    * for a list of common response headers.
    */
   @DomName('XMLHttpRequest.getResponseHeader')
@@ -22068,7 +22050,7 @@
    * response.
    *
    * This value must be set before the request has been sent. See also the list
-   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
+   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml)
    */
   @DomName('XMLHttpRequest.overrideMimeType')
   @DocsEditable()
@@ -22087,9 +22069,8 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.send]
-   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
-   * from MDN.
+   * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
+   *   from MDN.
    */
   @DomName('XMLHttpRequest.send')
   @DocsEditable()
@@ -22106,12 +22087,11 @@
    *
    * ## Other resources
    *
-   * * [XMLHttpRequest.setRequestHeader]
-   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
-   * from MDN.
-   * * [The setRequestHeader() method]
-   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from
-   * W3C.
+   * * [XMLHttpRequest.setRequestHeader](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader())
+   *   from MDN.
+   * * [The setRequestHeader()
+   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)
+   *   from W3C.
    */
   @DomName('XMLHttpRequest.setRequestHeader')
   @DocsEditable()
@@ -28425,9 +28405,8 @@
    *
    * ## Other resources
    *
-   * * [Node.childNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
-   * from MDN.
+   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
+   *   from MDN.
    */
   @DomName('Node.childNodes')
   @DocsEditable()
@@ -28506,9 +28485,8 @@
    *
    * ## Other resources
    *
-   * * [Node.firstChild]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
-   * from MDN.
+   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
+   *   from MDN.
    */
   @DomName('Node.firstChild')
   @DocsEditable()
@@ -28519,9 +28497,8 @@
    *
    * ## Other resources
    *
-   * * [Node.lastChild]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
-   * from MDN.
+   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
+   *   from MDN.
    */
   @DomName('Node.lastChild')
   @DocsEditable()
@@ -28540,9 +28517,8 @@
    *
    * ## Other resources
    *
-   * * [Node.nextSibling]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
-   * from MDN.
+   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
+   *   from MDN.
    */
   @DomName('Node.nextSibling')
   @DocsEditable()
@@ -28555,10 +28531,9 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeName]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
-   * from MDN. This page contains a table of [nodeName] values for each
-   * [nodeType].
+   * * [Node.nodeName](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
+   *   from MDN. This page contains a table of [nodeName] values for each
+   *   [nodeType].
    */
   @DomName('Node.nodeName')
   @DocsEditable()
@@ -28584,8 +28559,8 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeType]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType) from MDN.
+   * * [Node.nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType)
+   *   from MDN.
    */
   @DomName('Node.nodeType')
   @DocsEditable()
@@ -28598,10 +28573,9 @@
    *
    * ## Other resources
    *
-   * * [Node.nodeValue]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
-   * from MDN. This page contains a table of [nodeValue] values for each
-   * [nodeType].
+   * * [Node.nodeValue](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
+   *   from MDN. This page contains a table of [nodeValue] values for each
+   *   [nodeType].
    */
   @DomName('Node.nodeValue')
   @DocsEditable()
@@ -28614,9 +28588,8 @@
    *
    * ## Other resources
    *
-   * * [Node.ownerDocument]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument) from
-   * MDN.
+   * * [Node.ownerDocument](https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument)
+   *   from MDN.
    */
   @DomName('Node.ownerDocument')
   @DocsEditable()
@@ -28630,9 +28603,8 @@
    *
    * ## Other resources
    *
-   * * [Node.parentElement]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement) from
-   * W3C.
+   * * [Node.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement)
+   *   from W3C.
    */
   @DomName('Node.parentElement')
   @DocsEditable()
@@ -28643,9 +28615,8 @@
    *
    * ## Other resources
    *
-   * * [Node.parentNode]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode) from
-   * MDN.
+   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)
+   *   from MDN.
    */
   @DomName('Node.parentNode')
   @DocsEditable()
@@ -28656,9 +28627,8 @@
    *
    * ## Other resources
    *
-   * * [Node.previousSibling]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
-   * from MDN.
+   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
+   *   from MDN.
    */
   @DomName('Node.previousSibling')
   @DocsEditable()
@@ -28669,9 +28639,8 @@
    *
    * ## Other resources
    *
-   * * [Node.textContent]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
-   * MDN.
+   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
+   *   from MDN.
    */
   @DomName('Node.textContent')
   @DocsEditable()
@@ -28682,9 +28651,8 @@
    *
    * ## Other resources
    *
-   * * [Node.textContent]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
-   * MDN.
+   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
+   *   from MDN.
    */
   @DomName('Node.textContent')
   @DocsEditable()
@@ -28711,9 +28679,8 @@
    *
    * ## Other resources
    *
-   * * [Node.cloneNode]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from
-   * MDN.
+   * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode)
+   *   from MDN.
    */
   @DomName('Node.cloneNode')
   @DocsEditable()
@@ -28724,8 +28691,8 @@
    *
    * ## Other resources
    *
-   * * [Node.contains]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.contains) from MDN.
+   * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)
+   *   from MDN.
    */
   @DomName('Node.contains')
   @DocsEditable()
@@ -28736,9 +28703,8 @@
    *
    * ## Other resources
    *
-   * * [Node.hasChildNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes) from
-   * MDN.
+   * * [Node.hasChildNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes)
+   *   from MDN.
    */
   @DomName('Node.hasChildNodes')
   @DocsEditable()
@@ -28749,9 +28715,8 @@
    *
    * ## Other resources
    *
-   * * [Node.insertBefore]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) from
-   * MDN.
+   * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore)
+   *   from MDN.
    */
   @DomName('Node.insertBefore')
   @DocsEditable()
@@ -33053,7 +33018,7 @@
   @DomName('ServiceWorkerClient.postMessage')
   @DocsEditable()
   @Experimental() // untriaged
-  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) => _blink.BlinkServiceWorkerClient.instance.postMessage_Callback_2_(unwrap_jso(this), message, transfer);
+  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) => _blink.BlinkServiceWorkerClient.instance.postMessage_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
   
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -39242,10 +39207,11 @@
    *
    * ## Other resources
    *
-   * * [Exploring the FileSystem APIs]
-   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
-   * * [File API]
-   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)
+   *   from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
    */
   @DomName('Window.PERSISTENT')
   @DocsEditable()
@@ -39258,10 +39224,10 @@
    *
    * ## Other resources
    *
-   * * [Exploring the FileSystem APIs]
-   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
-   * * [File API]
-   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
+   * * [Exploring the FileSystem
+   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
+   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
+   *   from W3C.
    */
   @DomName('Window.TEMPORARY')
   @DocsEditable()
@@ -39285,11 +39251,12 @@
    *
    * ## Other resources
    *
-   * * [A beginner's guide to using the application cache]
-   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.
-   * * [Application cache API]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)
-   * from WHATWG.
+   * * [A beginner's guide to using the application
+   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)
+   *   from HTML5Rocks.
+   * * [Application cache
+   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)
+   *   from WHATWG.
    */
   @DomName('Window.applicationCache')
   @DocsEditable()
@@ -39345,12 +39312,10 @@
    *
    * ## Other resources
    *
-   * * [devicePixelRatio]
-   * (http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html) from
-   * quirksmode.
-   * * [More about devicePixelRatio]
-   * (http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html) from
-   * quirksmode.
+   * * [devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)
+   *   from quirksmode.
+   * * [More about devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html)
+   *   from quirksmode.
    */
   @DomName('Window.devicePixelRatio')
   @DocsEditable()
@@ -39367,9 +39332,8 @@
    *
    * ## Other resources
    *
-   * * [Loading web pages]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
-   * from WHATWG.
+   * * [Loading web pages](https://html.spec.whatwg.org/multipage/browsers.html)
+   *   from WHATWG.
    */
   @DomName('Window.history')
   @DocsEditable()
@@ -39388,9 +39352,8 @@
    *
    * ## Other resources
    *
-   * * [innerHeight]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight) from
-   * WebPlatform.org.
+   * * [innerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight)
+   *   from WebPlatform.org.
    */
   @DomName('Window.innerHeight')
   @DocsEditable()
@@ -39401,9 +39364,8 @@
    *
    * ## Other resources
    *
-   * * [innerWidth]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth) from
-   * WebPlatform.org.
+   * * [innerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth)
+   *   from WebPlatform.org.
    */
   @DomName('Window.innerWidth')
   @DocsEditable()
@@ -39414,13 +39376,12 @@
    *
    * ## Other resources
    *
-   * * [DOM storage guide]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
-   * MDN.
-   * * [The past, present & future of local storage for web applications]
-   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
-   * * [Local storage specification]
-   * (http://www.w3.org/TR/webstorage/#the-localstorage-attribute) from W3C.
+   * * [DOM storage guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage specification](http://www.w3.org/TR/webstorage/#the-localstorage-attribute)
+   *   from W3C.
    */
   @DomName('Window.localStorage')
   @DocsEditable()
@@ -39435,9 +39396,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.locationbar')
   @DocsEditable()
@@ -39448,9 +39409,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.menubar')
   @DocsEditable()
@@ -39461,9 +39422,8 @@
    *
    * ## Other resources
    *
-   * * [Window name]
-   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from
-   * WebPlatform.org.
+   * * [Window name](http://docs.webplatform.org/wiki/html/attributes/name_(window))
+   *   from WebPlatform.org.
    */
   @DomName('Window.name')
   @DocsEditable()
@@ -39474,9 +39434,8 @@
    *
    * ## Other resources
    *
-   * * [Window name]
-   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from
-   * WebPlatform.org.
+   * * [Window name](http://docs.webplatform.org/wiki/html/attributes/name_(window))
+   *   from WebPlatform.org.
    */
   @DomName('Window.name')
   @DocsEditable()
@@ -39487,9 +39446,9 @@
    *
    * ## Other resources
    *
-   * * [The navigator object]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#the-navigator-object)
-   * from WHATWG.
+   * * [The navigator
+   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
+   *   from WHATWG.
    */
   @DomName('Window.navigator')
   @DocsEditable()
@@ -39500,9 +39459,8 @@
    *
    * ## Other resources
    *
-   * * [offscreenBuffering]
-   * (http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering) from
-   * WebPlatform.org.
+   * * [offscreenBuffering](http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering)
+   *   from WebPlatform.org.
    */
   @DomName('Window.offscreenBuffering')
   @DocsEditable()
@@ -39527,9 +39485,8 @@
    *
    * ## Other resources
    *
-   * * [outerHeight]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight) from
-   * WebPlatform.org.
+   * * [outerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight)
+   *   from WebPlatform.org.
    */
   @DomName('Window.outerHeight')
   @DocsEditable()
@@ -39540,9 +39497,8 @@
    *
    * ## Other resources
    *
-   * * [outerWidth]
-   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth) from
-   * WebPlatform.org.
+   * * [outerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth)
+   *   from WebPlatform.org.
    */
   @DomName('Window.outerWidth')
   @DocsEditable()
@@ -39555,10 +39511,11 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollX and pageXOffset]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollX and
+   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
+   *   from MDN.
    */
   @DomName('Window.pageXOffset')
   @DocsEditable()
@@ -39571,10 +39528,11 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollY and pageYOffset]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollY and
+   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
+   *   from MDN.
    */
   @DomName('Window.pageYOffset')
   @DocsEditable()
@@ -39589,11 +39547,11 @@
    *
    * ## Other resources
    *
-   * * [Measuring page load speed with navigation timeing]
-   * (http://www.html5rocks.com/en/tutorials/webperformance/basics/) from
-   * HTML5Rocks.
-   * * [Navigation timing specification]
-   * (http://www.w3.org/TR/navigation-timing/) from W3C.
+   * * [Measuring page load speed with navigation
+   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)
+   *   from HTML5Rocks.
+   * * [Navigation timing
+   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.
    */
   @DomName('Window.performance')
   @DocsEditable()
@@ -39607,8 +39565,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screen')
   @DocsEditable()
@@ -39620,8 +39578,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenLeft')
   @DocsEditable()
@@ -39632,8 +39590,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenTop')
   @DocsEditable()
@@ -39644,8 +39602,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenX')
   @DocsEditable()
@@ -39656,8 +39614,8 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
+   *   from W3C.
    */
   @DomName('Window.screenY')
   @DocsEditable()
@@ -39676,9 +39634,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.scrollbars')
   @DocsEditable()
@@ -39689,8 +39647,8 @@
    *
    * ## Other resources
    *
-   * * [Window.self]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
+   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
+   *   from MDN.
    */
   @DomName('Window.self')
   @DocsEditable()
@@ -39701,13 +39659,13 @@
    *
    * ## Other resources
    *
-   * * [DOM storage guide]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
-   * MDN.
-   * * [The past, present & future of local storage for web applications]
-   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
-   * * [Local storage specification]
-   * (http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
+   * * [DOM storage
+   *   guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
+   *   from MDN.
+   * * [The past, present & future of local storage for web
+   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
+   * * [Local storage
+   *   specification](http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
    */
   @DomName('Window.sessionStorage')
   @DocsEditable()
@@ -39718,9 +39676,9 @@
    *
    * ## Other resources
    *
-   * * [Web speech specification]
-   * (https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
-   * from W3C.
+   * * [Web speech
+   *   specification](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
+   *   from W3C.
    */
   @DomName('Window.speechSynthesis')
   @DocsEditable()
@@ -39743,9 +39701,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.statusbar')
   @DocsEditable()
@@ -39756,9 +39714,9 @@
    *
    * ## Other resources
    *
-   * * [StyleMedia class reference]
-   * (https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html)
-   * from Safari Developer Library.
+   * * [StyleMedia class
+   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)
+   *   from Safari Developer Library.
    */
   @DomName('Window.styleMedia')
   @DocsEditable()
@@ -39771,9 +39729,9 @@
    *
    * ## Other resources
    *
-   * * [Browser interface elements]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
-   * from WHATWG.
+   * * [Browser interface
+   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
+   *   from WHATWG.
    */
   @DomName('Window.toolbar')
   @DocsEditable()
@@ -39788,8 +39746,8 @@
    *
    * ## Other resources
    *
-   * * [Window.window]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
+   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
+   *   from MDN.
    */
   @DomName('Window.window')
   @DocsEditable()
@@ -39834,8 +39792,8 @@
    *
    * ## Other resources
    *
-   * * [Window.find]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.find) from MDN.
+   * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find)
+   *   from MDN.
    */
   @DomName('Window.find')
   @DocsEditable()
@@ -39859,9 +39817,8 @@
    *
    * ## Other resources
    *
-   * * [Window.getSelection]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
-   * from MDN.
+   * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
+   *   from MDN.
    */
   @DomName('Window.getSelection')
   @DocsEditable()
@@ -39872,11 +39829,11 @@
    *
    * ## Other resources
    *
-   * * [Testing media queries]
-   * (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
-   * from MDN.
-   * * [The MediaQueryList specification]
-   * (http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
+   * * [Testing media
+   *   queries](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
+   *   from MDN.
+   * * [The MediaQueryList
+   *   specification](http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
    */
   @DomName('Window.matchMedia')
   @DocsEditable()
@@ -39889,10 +39846,9 @@
    *
    * ## Other resources
    *
-   * * [Window.moveBy]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy) from MDN.
-   * * [Window.moveBy]
-   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
+   * * [Window.moveBy](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy)
+   *   from MDN.
+   * * [Window.moveBy](http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
    */
   @DomName('Window.moveBy')
   @DocsEditable()
@@ -39922,8 +39878,8 @@
    *
    * ## Other resources
    *
-   * * [Window.print]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.print) from MDN.
+   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)
+   *   from MDN.
    */
   @DomName('Window.print')
   @DocsEditable()
@@ -39938,8 +39894,8 @@
    *
    * ## Other resources
    *
-   * * [Window resizeBy] (http://docs.webplatform.org/wiki/dom/methods/resizeBy)
-   * from WebPlatform.org.
+   * * [Window resizeBy](http://docs.webplatform.org/wiki/dom/methods/resizeBy)
+   *   from WebPlatform.org.
    */
   @DomName('Window.resizeBy')
   @DocsEditable()
@@ -39950,8 +39906,8 @@
    *
    * ## Other resources
    *
-   * * [Window resizeTo] (http://docs.webplatform.org/wiki/dom/methods/resizeTo)
-   * from WebPlatform.org.
+   * * [Window resizeTo](http://docs.webplatform.org/wiki/dom/methods/resizeTo)
+   *   from WebPlatform.org.
    */
   @DomName('Window.resizeTo')
   @DocsEditable()
@@ -40022,9 +39978,9 @@
    *
    * ## Other resources
    *
-   * * [Dialogs implemented using separate documents]
-   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
-   * from W3C.
+   * * [Dialogs implemented using separate
+   *   documents](http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
+   *   from W3C.
    */
   @DomName('Window.showModalDialog')
   @DocsEditable()
@@ -40035,9 +39991,9 @@
    *
    * ## Other resources
    *
-   * * [The Window object]
-   * (http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
-   * from W3C.
+   * * [The Window
+   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
+   *   from W3C.
    */
   @DomName('Window.stop')
   @DocsEditable()
@@ -40497,10 +40453,10 @@
    *
    * ## Other resources
    *
-   * * [Window.moveTo]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo) from MDN.
-   * * [Window.moveTo]
-   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveto) from W3C.
+   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
+   *   from MDN.
+   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
+   *   from W3C.
    */
   void moveTo(Point p) {
     _moveTo(p.x, p.y);
@@ -40720,7 +40676,7 @@
 
   @DomName('Worker.postMessage')
   @DocsEditable()
-  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) => _blink.BlinkWorker.instance.postMessage_Callback_2_(unwrap_jso(this), message, transfer);
+  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) => _blink.BlinkWorker.instance.postMessage_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
   
   @DomName('Worker.terminate')
   @DocsEditable()
@@ -43887,12 +43843,11 @@
  *
  * ## Other resources
  *
- * * [Image sources for 2D rendering contexts]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
- * from WHATWG.
- * * [Drawing images]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
- * from WHATWG.
+ * * [Image sources for 2D rendering
+ *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
+ *   from WHATWG.
+ * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
+ *   from WHATWG.
  */
 abstract class CanvasImageSource {}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -43935,9 +43890,9 @@
    *
    * ## Other resources
    *
-   * * [Session history and navigation specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
-   * from WHATWG.
+   * * [Session history and navigation
+   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
+   *   from WHATWG.
    */
   HistoryBase get history;
 
@@ -44030,12 +43985,10 @@
    *
    * ## Other resources
    *
-   * * [window.postMessage]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
-   * MDN.
-   * * [Cross-document messaging]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
-   * from WHATWG.
+   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
+   *   from MDN.
+   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
+   *   from WHATWG.
    */
   void postMessage(var message, String targetOrigin, [List messagePorts]);
 }
@@ -44710,9 +44663,8 @@
    *
    * ## Other resources
    *
-   * * [Event Capture]
-   * (http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
-   * from the W3C DOM Events specification.
+   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
+   *   from the W3C DOM Events specification.
    */
   StreamSubscription<T> capture(void onData(T event));
 }
@@ -45270,6 +45222,7 @@
     'INPUT::align',
     'INPUT::alt',
     'INPUT::autocomplete',
+    'INPUT::autofocus',
     'INPUT::checked',
     'INPUT::disabled',
     'INPUT::inputmode',
@@ -48110,9 +48063,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
   @Experimental()
@@ -48463,6 +48416,9 @@
       // 'this' needs to be handled by calling Dart_EvaluateExpr with
       // 'this' as the target rather than by passing it as an argument.
       if (arg == 'this') return;
+      // Avoid being broken by bogus ':async_op' local passed in when within
+      // an async method.
+      if (arg.startsWith(':')) return;
       if (args.isNotEmpty) {
         sb.write(", ");
       }
diff --git a/sdk/lib/html/html_common/conversions_dart2js.dart b/sdk/lib/html/html_common/conversions_dart2js.dart
index 3b3a8ad..b7f3d7c 100644
--- a/sdk/lib/html/html_common/conversions_dart2js.dart
+++ b/sdk/lib/html/html_common/conversions_dart2js.dart
@@ -88,7 +88,7 @@
   var completer = new Completer();
   var then = convertDartClosureToJS((result) => completer.complete(result), 1);
   var error = convertDartClosureToJS((result) => completer.completeError(result), 1);
-  var newPromise = JS('', '#.then(#).catch(#)', promise, then, error);
+  var newPromise = JS('', '#.then(#)["catch"](#)', promise, then, error);
   return completer.future;
 }
 
diff --git a/sdk/lib/html/html_common/conversions_dartium.dart b/sdk/lib/html/html_common/conversions_dartium.dart
index 56ed9d5..2403387 100644
--- a/sdk/lib/html/html_common/conversions_dartium.dart
+++ b/sdk/lib/html/html_common/conversions_dartium.dart
@@ -121,7 +121,7 @@
 
     var wrapper = js.getDartHtmlWrapperFor(jsObject);
     // if we have a wrapper return the Dart instance.
-    if (wrapper != null && wrapper is! js.JsObject) {
+    if (wrapper != null) {
       return wrapper;
     }
 
@@ -236,6 +236,13 @@
       return wrapper;
     }
 
+    // TODO(jacobr): auomatically wrapping JsArray here is fundamentally broken
+    // as it hijacks adding custom methods on JS Array classes as part of the
+    // new typed DartJsInterop.
+    // To make this work we really need to make DartHtmlWrappingList extend
+    // JsArrayImpl. Fixing this issue needs to be part of a broader refactor
+    // that allows calling custom typed JS interop methods on all dart:html
+    // classes.
     if (jsObject is js.JsArray) {
       var wrappingList = new DartHtmlWrappingList(jsObject);
       js.setDartHtmlWrapperFor(jsObject, wrappingList);
@@ -380,7 +387,7 @@
 
   final js.JsArray blink_jsObject;
 
-  operator [](int index) => wrap_jso(js.JsNative.getArrayIndex(blink_jsObject, index));
+  operator [](int index) => wrap_jso_no_SerializedScriptvalue(js.JsNative.getArrayIndex(blink_jsObject, index));
 
   operator []=(int index, value) => blink_jsObject[index] = value;
 
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 034b2ce..1f80c9d 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -380,7 +380,7 @@
     List storeNames_1 = convertDartToNative_StringArray(storeNames);
     return _transaction(storeNames_1, mode);
   }
-  
+
   Transaction transactionStores(DomStringList storeNames, String mode) {
     if (mode != 'readonly' && mode != 'readwrite') {
       throw new ArgumentError(mode);
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index c75130a..4ab3e30 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -292,6 +292,27 @@
     return _createObjectStore(name, options);
   }
 
+  Transaction transaction(storeName_OR_storeNames, String mode) {
+    if (mode != 'readonly' && mode != 'readwrite') {
+      throw new ArgumentError("Invalid transaction mode $mode");
+    }
+    var names;
+    if (storeName_OR_storeNames == null) {
+      throw new ArgumentError("stores may not be null in transaction");
+    } else if (storeName_OR_storeNames is String || storeName_OR_storeNames is DomStringList) {
+      names = unwrap_jso(storeName_OR_storeNames);
+    } else if (storeName_OR_storeNames is List<String>) {
+      names = convertDartToNative_List(storeName_OR_storeNames);
+    } else {
+      throw new ArgumentError("Invalid store(s) $store_Name_OR_storeNames");
+    }
+
+    return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), names, mode));
+  }
+
+  Transaction transactionList(List<String> storeNames, String mode) => transaction(storeNames, mode);
+  Transaction transactionStores(List<String> storeNames, String mode) => transaction(storeNames, mode);
+  Transaction transactionStore(String storeName, String mode) => transaction(storeName, mode);
 
   // To suppress missing implicit constructor warnings.
   factory Database._() { throw new UnsupportedError("Not supported"); }
@@ -379,49 +400,6 @@
   @DocsEditable()
   void deleteObjectStore(String name) => _blink.BlinkIDBDatabase.instance.deleteObjectStore_Callback_1_(unwrap_jso(this), name);
   
-  Transaction transaction(storeName_OR_storeNames, [String mode]) {
-    if ((storeName_OR_storeNames is String || storeName_OR_storeNames == null) && mode == null) {
-      return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_1_(unwrap_jso(this), unwrap_jso(storeName_OR_storeNames)));
-    }
-    if ((mode is String || mode == null) && (storeName_OR_storeNames is String || storeName_OR_storeNames == null)) {
-      return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), unwrap_jso(storeName_OR_storeNames), mode));
-    }
-    if ((storeName_OR_storeNames is List<String> || storeName_OR_storeNames == null) && mode == null) {
-      return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_1_(unwrap_jso(this), unwrap_jso(storeName_OR_storeNames)));
-    }
-    if ((mode is String || mode == null) && (storeName_OR_storeNames is List<String> || storeName_OR_storeNames == null)) {
-      return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), unwrap_jso(storeName_OR_storeNames), mode));
-    }
-    if ((storeName_OR_storeNames is DomStringList || storeName_OR_storeNames == null) && mode == null) {
-      return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_1_(unwrap_jso(this), unwrap_jso(storeName_OR_storeNames)));
-    }
-    if ((mode is String || mode == null) && (storeName_OR_storeNames is DomStringList || storeName_OR_storeNames == null)) {
-      return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), unwrap_jso(storeName_OR_storeNames), mode));
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-
-  Transaction transactionList(List<String> storeNames, [String mode]) {
-    if (mode != null) {
-      return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), convertDartToNative_StringArray(storeNames), mode));
-    }
-    return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_1_(unwrap_jso(this), convertDartToNative_StringArray(storeNames)));
-  }
-
-  Transaction transactionStore(String storeName, [String mode]) {
-    if (mode != null) {
-      return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), storeName, mode));
-    }
-    return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_1_(unwrap_jso(this), storeName));
-  }
-
-  Transaction transactionStores(List<String> storeNames, [String mode]) {
-    if (mode != null) {
-      return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), unwrap_jso(storeNames), mode));
-    }
-    return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_1_(unwrap_jso(this), unwrap_jso(storeNames)));
-  }
-
   /// Stream of `abort` events handled by this [Database].
   @DomName('IDBDatabase.onabort')
   @DocsEditable()
diff --git a/sdk/lib/internal/iterable.dart b/sdk/lib/internal/iterable.dart
index 47c94f8..9a5f29f 100644
--- a/sdk/lib/internal/iterable.dart
+++ b/sdk/lib/internal/iterable.dart
@@ -465,9 +465,6 @@
 
   ExpandIterator(this._iterator, Iterable<T> this._f(S element));
 
-  void _nextExpansion() {
-  }
-
   T get current => _current;
 
   bool moveNext() {
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 8005726..2ff3928 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -100,16 +100,16 @@
  * ## Other resources
  *
  * * [Dart by Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
- * provides additional task-oriented code samples that show how to use
- * various API from the Directory class and the related [File] class.
+ *   provides additional task-oriented code samples that show how to use
+ *   various API from the Directory class and the related [File] class.
  *
- * * [I/O for Command-Line Apps](https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartio---file-and-socket-io-for-command-line-apps)
- * a section from _A Tour of the Dart Libraries_
- * covers files and directories.
+ * * [I/O for Command-Line
+ *   Apps](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps)
+ *   a section from _A Tour of the Dart Libraries_ covers files and directories.
  *
  * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
- * a tutorial about writing command-line apps, includes information
- * about files and directories.
+ *   a tutorial about writing command-line apps, includes information about
+ *   files and directories.
  */
 abstract class Directory implements FileSystemEntity {
   /**
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 691d783..d9b2cb4 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -184,17 +184,16 @@
  * ## Other resources
  *
  * * [Dart by Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
- * provides additional task-oriented code samples that show how to use
- * various API from the Directory class and the related [File] class.
+ *   provides additional task-oriented code samples that show how to use
+ *   various API from the Directory class and the related [File] class.
  *
- * * [I/O for Command-Line Apps](https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartio---file-and-socket-io-for-command-line-apps)
- * a section from _A Tour of the Dart Libraries_
- * covers files and directories.
+ * * [I/O for Command-Line
+ *   Apps](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps)
+ *   a section from _A Tour of the Dart Libraries_ covers files and directories.
  *
  * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
- * a tutorial about writing command-line apps, includes information
- * about files and directories.
-
+ *   a tutorial about writing command-line apps, includes information about
+ *   files and directories.
  */
 abstract class File implements FileSystemEntity {
   /**
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index 7e8b0dd..f39eafd 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -197,19 +197,19 @@
  *
  * ## Other resources
  *
- * [Dart by Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
- * provides additional task-oriented code samples that show how to use
- * various API from the [Directory] class and the [File] class,
- * both subclasses of FileSystemEntity.
+ * * [Dart by
+ *   Example](https://www.dartlang.org/dart-by-example/#files-directories-and-symlinks)
+ *   provides additional task-oriented code samples that show how to use various
+ *   API from the [Directory] class and the [File] class, both subclasses of
+ *   FileSystemEntity.
  *
- * * [I/O for Command-Line Apps](https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartio---file-and-socket-io-for-command-line-apps)
- * a section from _A Tour of the Dart Libraries_
- * covers files and directories.
+ * * [I/O for Command-Line
+ *   Apps](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps),
+ *   a section from _A Tour of the Dart Libraries_ covers files and directories.
  *
  * * [Write Command-Line Apps](https://www.dartlang.org/docs/tutorials/cmdline/),
- * a tutorial about writing command-line apps, includes information
- * about files and directories.
-
+ *   a tutorial about writing command-line apps, includes information about
+ *   files and directories.
  */
 abstract class FileSystemEntity {
   String get path;
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index deae6dc..c63d28b 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -683,9 +683,11 @@
    */
   static HeaderValue parse(String value,
                            {String parameterSeparator: ";",
+                            String valueSeparator: null,
                             bool preserveBackslash: false}) {
     return _HeaderValue.parse(value,
                               parameterSeparator: parameterSeparator,
+                              valueSeparator: valueSeparator,
                               preserveBackslash: preserveBackslash);
   }
 
diff --git a/sdk/lib/io/http_date.dart b/sdk/lib/io/http_date.dart
index 9bf8197..7f69613 100644
--- a/sdk/lib/io/http_date.dart
+++ b/sdk/lib/io/http_date.dart
@@ -72,8 +72,8 @@
    *     Thursday, 1-Jan-1970 00:00:00 GMT
    *     Thu Jan  1 00:00:00 1970
    *
-   * For more information see [RFC-2616 section 3.1.1]
-   * (http://tools.ietf.org/html/rfc2616#section-3.3.1
+   * For more information see [RFC-2616 section
+   * 3.1.1](http://tools.ietf.org/html/rfc2616#section-3.3.1
    * "RFC-2616 section 3.1.1").
    */
   static DateTime parse(String date) {
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 4700128..6b14ae2 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -630,10 +630,11 @@
 
   static _HeaderValue parse(String value,
                             {parameterSeparator: ";",
+                             valueSeparator: null,
                              preserveBackslash: false}) {
     // Parse the string.
     var result = new _HeaderValue();
-    result._parse(value, parameterSeparator, preserveBackslash);
+    result._parse(value, parameterSeparator, valueSeparator, preserveBackslash);
     return result;
   }
 
@@ -664,7 +665,10 @@
     return sb.toString();
   }
 
-  void _parse(String s, String parameterSeparator, bool preserveBackslash) {
+  void _parse(String s,
+        String parameterSeparator,
+        String valueSeparator,
+        bool preserveBackslash) {
     int index = 0;
 
     bool done() => index == s.length;
@@ -681,6 +685,7 @@
       while (!done()) {
         if (s[index] == " " ||
             s[index] == "\t" ||
+            s[index] == valueSeparator ||
             s[index] == parameterSeparator) break;
         index++;
       }
@@ -705,14 +710,18 @@
       String parseParameterName() {
         int start = index;
         while (!done()) {
-          if (s[index] == " " || s[index] == "\t" || s[index] == "=") break;
+          if (s[index] == " " ||
+              s[index] == "\t" ||
+              s[index] == "=" ||
+              s[index] == parameterSeparator ||
+              s[index] == valueSeparator) break;
           index++;
         }
         return s.substring(start, index).toLowerCase();
       }
 
       String parseParameterValue() {
-        if (s[index] == "\"") {
+        if (!done() && s[index] == "\"") {
           // Parse quoted value.
           StringBuffer sb = new StringBuffer();
           index++;
@@ -735,7 +744,8 @@
           return sb.toString();
         } else {
           // Parse non-quoted value.
-          return parseValue();
+          var val = parseValue();
+          return val == "" ? null : val;
         }
       }
 
@@ -744,8 +754,16 @@
         if (done()) return;
         String name = parseParameterName();
         skipWS();
-        expect("=");
+        if (done()) {
+          parameters[name] = null;
+          return;
+        }
+        maybeExpect("=");
         skipWS();
+        if(done()) {
+          parameters[name] = null;
+          return;
+        }
         String value = parseParameterValue();
         if (name == 'charset' && this is _ContentType) {
           // Charset parameter of ContentTypes are always lower-case.
@@ -754,6 +772,8 @@
         parameters[name] = value;
         skipWS();
         if (done()) return;
+        // TODO: Implement support for multi-valued parameters.
+        if(s[index] == valueSeparator) return;
         expect(parameterSeparator);
       }
     }
@@ -800,7 +820,7 @@
 
   static _ContentType parse(String value) {
     var result = new _ContentType._();
-    result._parse(value, ";", false);
+    result._parse(value, ";", null, false);
     int index = result._value.indexOf("/");
     if (index == -1 || index == (result._value.length - 1)) {
       result._primaryType = result._value.trim().toLowerCase();
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index aea1b5b..04cc6f2 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -186,13 +186,11 @@
  *
  * ## Other resources
  *
- * For an introduction to I/O in Dart, see the
- * [dart:io section of the library tour]
- * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartio---file-and-socket-io-for-command-line-apps).
+ * For an introduction to I/O in Dart, see the [dart:io section of the library
+ * tour](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#dartio---io-for-command-line-apps).
  *
- * To learn more about I/O in Dart, refer to the
- * [tutorial about writing command-line apps]
- * (https://www.dartlang.org/docs/tutorials/io/).
+ * To learn more about I/O in Dart, refer to the [tutorial about writing
+ * command-line apps](https://www.dartlang.org/docs/tutorials/io/).
  */
 library dart.io;
 
diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
index 2d6719d..b1c05a0 100644
--- a/sdk/lib/io/io_sink.dart
+++ b/sdk/lib/io/io_sink.dart
@@ -5,20 +5,27 @@
 part of dart.io;
 
 /**
- * Helper class to wrap a [StreamConsumer<List<int>>] and provide
- * utility functions for writing to the StreamConsumer directly. The
- * [IOSink] buffers the input given by all [StringSink] methods and will delay
- * an [addStream] until the buffer is flushed.
+ * A combined byte and text output.
  *
- * When the [IOSink] is bound to a stream (through [addStream]) any call
- * to the [IOSink] will throw a [StateError]. When the [addStream] completes,
- * the [IOSink] will again be open for all calls.
+ * An [IOSink] combines a [StreamSink] of bytes with a [StringSink],
+ * and allows easy output of both bytes and text.
+ *
+ * Writing text ([write]) and adding bytes ([add]) may be interleaved freely.
+ *
+ * While a stream is being added using [addStream], any further attempts
+ * to add or write to the [IOSink] will fail until the [addStream] completes.
  *
  * If data is added to the [IOSink] after the sink is closed, the data will be
  * ignored. Use the [done] future to be notified when the [IOSink] is closed.
  */
 abstract class IOSink implements StreamSink<List<int>>, StringSink {
-  // TODO(ajohnsen): Make _encodingMutable an argument.
+
+  /**
+   * Create an [IOSink] that outputs to a [target] [StreamConsumer] of bytes.
+   *
+   * Text written to [StreamSink] methods is encoded to bytes using [encoding]
+   * before being output on [target].
+   */
   factory IOSink(StreamConsumer<List<int>> target,
                  {Encoding encoding: UTF8})
       => new _IOSinkImpl(target, encoding);
@@ -30,7 +37,7 @@
   Encoding encoding;
 
   /**
-   * Adds [data] to the target consumer, ignoring [encoding].
+   * Adds byte [data] to the target consumer, ignoring [encoding].
    *
    * The [encoding] does not apply to this method, and the `data` list is passed
    * directly to the target consumer as a stream event.
@@ -58,7 +65,7 @@
    * Iterates over the given [objects] and [write]s them in sequence.
    *
    * If [separator] is provided, a `write` with the `separator` is performed
-   * between any two elements of `objects`.
+   * between any two elements of objects`.
    *
    * This operation is non-blocking. See [flush] or [done] for how to get any
    * errors generated by this call.
@@ -75,7 +82,7 @@
   void writeln([Object obj = ""]);
 
   /**
-   * Writes the [charCode] to `this`.
+   * Writes the character of [charCode].
    *
    * This method is equivalent to `write(new String.fromCharCode(charCode))`.
    *
@@ -107,7 +114,7 @@
    * Returns a [Future] that completes once all buffered data is accepted by the
    * to underlying [StreamConsumer].
    *
-   * It's an error to call this method, while an [addStream] is incomplete.
+   * This method must not be called while an [addStream] is incomplete.
    *
    * NOTE: This is not necessarily the same as the data being flushed by the
    * operating system.
@@ -129,17 +136,14 @@
 
 class _StreamSinkImpl<T> implements StreamSink<T> {
   final StreamConsumer<T> _target;
-  Completer _doneCompleter = new Completer();
-  Future _doneFuture;
+  final Completer _doneCompleter = new Completer();
   StreamController<T> _controllerInstance;
   Completer _controllerCompleter;
   bool _isClosed = false;
   bool _isBound = false;
   bool _hasError = false;
 
-  _StreamSinkImpl(this._target) {
-    _doneFuture = _doneCompleter.future;
-  }
+  _StreamSinkImpl(this._target);
 
   void add(T data) {
     if (_isClosed) return;
@@ -180,8 +184,8 @@
     var future = _controllerCompleter.future;
     _controllerInstance.close();
     return future.whenComplete(() {
-          _isBound = false;
-        });
+      _isBound = false;
+    });
   }
 
   Future close() {
@@ -203,19 +207,19 @@
     _target.close().then(_completeDoneValue, onError: _completeDoneError);
   }
 
-  Future get done => _doneFuture;
+  Future get done => _doneCompleter.future;
 
   void _completeDoneValue(value) {
-    if (_doneCompleter == null) return;
-    _doneCompleter.complete(value);
-    _doneCompleter = null;
+    if (!_doneCompleter.isCompleted) {
+      _doneCompleter.complete(value);
+    }
   }
 
   void _completeDoneError(error, StackTrace stackTrace) {
-    if (_doneCompleter == null) return;
-    _hasError = true;
-    _doneCompleter.completeError(error, stackTrace);
-    _doneCompleter = null;
+    if (!_doneCompleter.isCompleted) {
+      _hasError = true;
+      _doneCompleter.completeError(error, stackTrace);
+    }
   }
 
   StreamController<T> get _controller {
@@ -228,32 +232,29 @@
     if (_controllerInstance == null) {
       _controllerInstance = new StreamController<T>(sync: true);
       _controllerCompleter = new Completer();
-      _target.addStream(_controller.stream)
-          .then(
-              (_) {
-                if (_isBound) {
-                  // A new stream takes over - forward values to that stream.
-                  _controllerCompleter.complete(this);
-                  _controllerCompleter = null;
-                  _controllerInstance = null;
-                } else {
-                  // No new stream, .close was called. Close _target.
-                  _closeTarget();
-                }
-              },
-              onError: (error, stackTrace) {
-                if (_isBound) {
-                  // A new stream takes over - forward errors to that stream.
-                  _controllerCompleter.completeError(error, stackTrace);
-                  _controllerCompleter = null;
-                  _controllerInstance = null;
-                } else {
-                  // No new stream. No need to close target, as it have already
-                  // failed.
-                  _completeDoneError(error, stackTrace);
-                }
-              });
-    }
+      _target.addStream(_controller.stream).then((_) {
+        if (_isBound) {
+          // A new stream takes over - forward values to that stream.
+          _controllerCompleter.complete(this);
+          _controllerCompleter = null;
+          _controllerInstance = null;
+        } else {
+          // No new stream, .close was called. Close _target.
+          _closeTarget();
+        }
+      }, onError: (error, stackTrace) {
+        if (_isBound) {
+          // A new stream takes over - forward errors to that stream.
+          _controllerCompleter.completeError(error, stackTrace);
+          _controllerCompleter = null;
+          _controllerInstance = null;
+        } else {
+          // No new stream. No need to close target, as it has already
+          // failed.
+          _completeDoneError(error, stackTrace);
+        }
+      });
+   }
     return _controllerInstance;
   }
 }
@@ -297,8 +298,8 @@
     }
   }
 
-  void writeln([Object obj = ""]) {
-    write(obj);
+  void writeln([Object object = ""]) {
+    write(object);
     write("\n");
   }
 
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 56ddea0..326597f 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -84,7 +84,7 @@
   static String get pathSeparator => _pathSeparator;
 
   /**
-   * Get a string (`linux`, `macos`, `windows` or `android`)
+   * Get a string (`linux`, `macos`, `windows`, `android`, or `ios`)
    * representing the operating system.
    */
   static String get operatingSystem => _operatingSystem;
@@ -115,6 +115,11 @@
   static final bool isAndroid = (_operatingSystem == "android");
 
   /**
+   * Returns true if the operating system is iOS.
+   */
+  static final bool isIOS = (_operatingSystem == "ios");
+
+  /**
    * Get the environment for this process.
    *
    * The returned environment is an unmodifiable map which content is
@@ -180,10 +185,19 @@
    * used to run the script in this isolate.  This is the directory in which
    * Dart packages are looked up.
    *
-   * If there is no --package-root flag, then the empty string is returned.
+   * If there is no --package-root flag, then null is returned.
    */
   static String get packageRoot => _Platform.packageRoot;
 
+/**
+ * Returns the value of the --packages flag passed to the executable
+ * used to run the script in this isolate.  This is the configuration which
+ * specifies how Dart packages are looked up.
+ *
+ * If there is no --packages flag, then the null is returned.
+ */
+  static String get packageConfig => _Platform.packageConfig;
+
   /**
    * Returns the version of the current Dart runtime.
    *
diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart
index 6380e0d..d7e722f 100644
--- a/sdk/lib/io/platform_impl.dart
+++ b/sdk/lib/io/platform_impl.dart
@@ -29,11 +29,13 @@
   external static _environment();
   external static List<String> _executableArguments();
   external static String _packageRoot();
+  external static String _packageConfig();
   external static String _version();
 
   static String executable = _executable();
   static String resolvedExecutable = _resolvedExecutable();
   static String packageRoot = _packageRoot();
+  static String packageConfig = _packageConfig();
 
   // Cache the OS environemnt. This can be an OSError instance if
   // retrieving the environment failed.
@@ -44,20 +46,6 @@
   static String get operatingSystem => _operatingSystem();
   static Uri script;
 
-  // This script singleton is written to by the embedder if applicable.
-  static void set _nativeScript(String path) {
-    if (path.startsWith('http:') ||
-        path.startsWith('https:') ||
-        path.startsWith('package:') ||
-        path.startsWith('dart:') ||
-        path.startsWith('data:') ||
-        path.startsWith('file:')) {
-      script = Uri.parse(path);
-    } else {
-      script = Uri.base.resolveUri(new Uri.file(path));
-    }
-  }
-
   static String get localHostname {
     var result = _localHostname();
     if (result is OSError) {
diff --git a/sdk/lib/io/websocket.dart b/sdk/lib/io/websocket.dart
index 599e295..183714f 100644
--- a/sdk/lib/io/websocket.dart
+++ b/sdk/lib/io/websocket.dart
@@ -12,7 +12,7 @@
   static const int GOING_AWAY = 1001;
   static const int PROTOCOL_ERROR = 1002;
   static const int UNSUPPORTED_DATA = 1003;
-  static const int RESERVED_1004  = 1004;
+  static const int RESERVED_1004 = 1004;
   static const int NO_STATUS_RECEIVED = 1005;
   static const int ABNORMAL_CLOSURE = 1006;
   static const int INVALID_FRAME_PAYLOAD_DATA = 1007;
@@ -24,6 +24,151 @@
 }
 
 /**
+ * The [CompressionOptions] class allows you to control
+ * the options of WebSocket compression.
+ */
+class CompressionOptions {
+  /**
+   * Default WebSocket Compression options.
+   * Compression will be enabled with the following options:
+   * clientNoContextTakeover: false
+   * serverNoContextTakeover: false
+   * clientMaxWindowBits: 15
+   * serverMaxWindowBits: 15
+   */
+  static const CompressionOptions DEFAULT = const CompressionOptions();
+
+  /**
+   * Disables WebSocket Compression.
+   */
+  static const CompressionOptions OFF =
+      const CompressionOptions(enabled: false);
+
+  /**
+   * Control whether the client will reuse it's compression instances.
+   */
+  final bool clientNoContextTakeover;
+
+  /**
+   * Control whether the server will reuse it's compression instances.
+   */
+  final bool serverNoContextTakeover;
+
+  /**
+   * Sets the Max Window Bits for the Client.
+   */
+  final int clientMaxWindowBits;
+
+  /**
+   * Sets the Max Window Bits for the Server.
+   */
+  final int serverMaxWindowBits;
+
+  /**
+   * Enables or disables WebSocket compression.
+   */
+  final bool enabled;
+
+  const CompressionOptions(
+      {this.clientNoContextTakeover: false,
+      this.serverNoContextTakeover: false,
+      this.clientMaxWindowBits,
+      this.serverMaxWindowBits,
+      this.enabled: true});
+
+  /// Parses list of requested server headers to return server compression
+  /// response headers. Uses [serverMaxWindowBits] value if set, otherwise will
+  /// attempt to use value from headers. Defaults to
+  /// [WebSocket.DEFAULT_WINDOW_BITS]. Returns a [_CompressionMaxWindowBits]
+  /// object which contains the response headers and negotiated max window bits.
+  _CompressionMaxWindowBits _createServerResponseHeader(HeaderValue requested) {
+    var info = new _CompressionMaxWindowBits();
+
+    int mwb;
+    String part;
+    if (requested?.parameters != null) {
+      part = requested.parameters[_serverMaxWindowBits];
+    }
+    if (part != null) {
+      if (part.length >= 2 && part.startsWith('0')) {
+        throw new ArgumentError("Illegal 0 padding on value.");
+      } else {
+        mwb = serverMaxWindowBits == null
+            ? int.parse(part,
+                        onError: (source) => _WebSocketImpl.DEFAULT_WINDOW_BITS)
+            : serverMaxWindowBits;
+        info.headerValue = "; server_max_window_bits=${mwb}";
+        info.maxWindowBits = mwb;
+      }
+    } else {
+      info.headerValue = "";
+      info.maxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS;
+    }
+    return info;
+  }
+
+  /// Returns default values for client compression request headers.
+  String _createClientRequestHeader(HeaderValue requested, int size) {
+    var info = "";
+
+    // If responding to a valid request, specify size
+    if (requested != null) {
+      info = "; client_max_window_bits=$size";
+    } else {
+      // Client request. Specify default
+      if (clientMaxWindowBits == null) {
+        info = "; client_max_window_bits";
+      } else {
+        info = "; client_max_window_bits=$clientMaxWindowBits";
+      }
+      if (serverMaxWindowBits != null) {
+        info += "; server_max_window_bits=$serverMaxWindowBits";
+      }
+    }
+
+    return info;
+  }
+
+  /// Create a Compression Header. If [requested] is null or contains
+  /// client request headers, returns Client compression request headers with
+  /// default settings for `client_max_window_bits` header value.
+  /// If [requested] contains server response headers this method returns
+  /// a Server compression response header negotiating the max window bits
+  /// for both client and server as requested server_max_window_bits value.
+  /// This method returns a [_CompressionMaxWindowBits] object with the
+  /// response headers and negotiated maxWindowBits value.
+  _CompressionMaxWindowBits _createHeader([HeaderValue requested]) {
+    var info = new _CompressionMaxWindowBits("", 0);
+    if (!enabled) {
+      return info;
+    }
+
+    info.headerValue = _WebSocketImpl.PER_MESSAGE_DEFLATE;
+
+    if (clientNoContextTakeover &&
+        (requested == null || (requested != null &&
+            requested.parameters.containsKey(_clientNoContextTakeover)))) {
+      info.headerValue += "; client_no_context_takeover";
+    }
+
+    if (serverNoContextTakeover &&
+        (requested == null || (requested != null &&
+            requested.parameters.containsKey(_serverNoContextTakeover)))) {
+      info.headerValue += "; server_no_context_takeover";
+    }
+
+    var headerList = _createServerResponseHeader(requested);
+    info.headerValue += headerList.headerValue;
+    info.maxWindowBits = headerList.maxWindowBits;
+
+    info.headerValue +=
+        _createClientRequestHeader(requested, info.maxWindowBits);
+
+    return info;
+  }
+}
+
+/**
  * The [WebSocketTransformer] provides the ability to upgrade a
  * [HttpRequest] to a [WebSocket] connection. It supports both
  * upgrading a single [HttpRequest] and upgrading a stream of
@@ -53,7 +198,6 @@
  */
 abstract class WebSocketTransformer
     implements StreamTransformer<HttpRequest, WebSocket> {
-
   /**
    * Create a new [WebSocketTransformer].
    *
@@ -62,9 +206,15 @@
    * [protocolSelector] is should return either a [String] or a [Future]
    * completing with a [String]. The [String] must exist in the list of
    * protocols.
+   *
+   * If [compression] is provided, the [WebSocket] created will be configured
+   * to negotiate with the specified [CompressionOptions]. If none is specified
+   * then the [WebSocket] will be created with the default [CompressionOptions].
    */
-  factory WebSocketTransformer({protocolSelector(List<String> protocols)})
-      => new _WebSocketTransformerImpl(protocolSelector);
+  factory WebSocketTransformer(
+          {protocolSelector(List<String> protocols),
+          CompressionOptions compression: CompressionOptions.DEFAULT}) =>
+      new _WebSocketTransformerImpl(protocolSelector, compression);
 
   /**
    * Upgrades a [HttpRequest] to a [WebSocket] connection. If the
@@ -78,10 +228,16 @@
    * [protocolSelector] is should return either a [String] or a [Future]
    * completing with a [String]. The [String] must exist in the list of
    * protocols.
+   *
+   * If [compression] is provided, the [WebSocket] created will be configured
+   * to negotiate with the specified [CompressionOptions]. If none is specified
+   * then the [WebSocket] will be created with the default [CompressionOptions].
    */
   static Future<WebSocket> upgrade(HttpRequest request,
-                                   {protocolSelector(List<String> protocols)}) {
-    return _WebSocketTransformerImpl._upgrade(request, protocolSelector);
+      {protocolSelector(List<String> protocols),
+      CompressionOptions compression: CompressionOptions.DEFAULT}) {
+    return _WebSocketTransformerImpl._upgrade(
+        request, protocolSelector, compression);
   }
 
   /**
@@ -92,7 +248,6 @@
   }
 }
 
-
 /**
  * A two-way HTTP communication object for client or server applications.
  *
@@ -152,9 +307,10 @@
    * authentication when setting up the connection.
    */
   static Future<WebSocket> connect(String url,
-                                   {Iterable<String> protocols,
-                                    Map<String, dynamic> headers}) =>
-      _WebSocketImpl.connect(url, protocols, headers);
+          {Iterable<String> protocols,
+          Map<String, dynamic> headers,
+          CompressionOptions compression: CompressionOptions.DEFAULT}) =>
+      _WebSocketImpl.connect(url, protocols, headers, compression: compression);
 
   @Deprecated('This constructor will be removed in Dart 2.0. Use `implements`'
       ' instead of `extends` if implementing this abstract class.')
@@ -174,14 +330,21 @@
    * [serverSide] must be passed explicitly. If it's `false`, the WebSocket will
    * act as the client and mask the messages it sends. If it's `true`, it will
    * act as the server and will not mask its messages.
+   *
+   * If [compression] is provided, the [WebSocket] created will be configured
+   * to negotiate with the specified [CompressionOptions]. If none is specified
+   * then the [WebSocket] will be created with the default [CompressionOptions].
    */
-  factory WebSocket.fromUpgradedSocket(Socket socket, {String protocol,
-        bool serverSide}) {
+  factory WebSocket.fromUpgradedSocket(Socket socket,
+      {String protocol,
+      bool serverSide,
+      CompressionOptions compression: CompressionOptions.DEFAULT}) {
     if (serverSide == null) {
       throw new ArgumentError("The serverSide argument must be passed "
           "explicitly to WebSocket.fromUpgradedSocket.");
     }
-    return new _WebSocketImpl._fromSocket(socket, protocol, serverSide);
+    return new _WebSocketImpl._fromSocket(
+        socket, protocol, compression, serverSide);
   }
 
   /**
@@ -238,9 +401,10 @@
   Future addStream(Stream stream);
 }
 
-
 class WebSocketException implements IOException {
   final String message;
+
   const WebSocketException([this.message = ""]);
+
   String toString() => "WebSocketException: $message";
 }
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index cc68544..2aa894c 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -5,6 +5,10 @@
 part of dart.io;
 
 const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+const String _clientNoContextTakeover = "client_no_context_takeover";
+const String _serverNoContextTakeover = "server_no_context_takeover";
+const String _clientMaxWindowBits = "client_max_window_bits";
+const String _serverMaxWindowBits = "server_max_window_bits";
 
 // Matches _WebSocketOpcode.
 class _WebSocketMessageType {
@@ -13,7 +17,6 @@
   static const int BINARY = 2;
 }
 
-
 class _WebSocketOpcode {
   static const int CONTINUATION = 0;
   static const int TEXT = 1;
@@ -34,12 +37,24 @@
 }
 
 /**
+ *  Stores the header and integer value derived from negotiation of
+ *  client_max_window_bits and server_max_window_bits. headerValue will be
+ *  set in the Websocket response headers.
+ */
+class _CompressionMaxWindowBits {
+  String headerValue;
+  int maxWindowBits;
+  _CompressionMaxWindowBits([this.headerValue, this.maxWindowBits]);
+  String toString() => headerValue;
+}
+
+/**
  * The web socket protocol transformer handles the protocol byte stream
  * which is supplied through the [:handleData:]. As the protocol is processed,
  * it'll output frame data as either a List<int> or String.
  *
- * Important infomation about usage: Be sure you use cancelOnError, so the
- * socket will be closed when the processer encounter an error. Not using it
+ * Important information about usage: Be sure you use cancelOnError, so the
+ * socket will be closed when the processor encounter an error. Not using it
  * will lead to undefined behaviour.
  */
 // TODO(ajohnsen): make this transformer reusable?
@@ -51,9 +66,15 @@
   static const int PAYLOAD = 4;
   static const int CLOSED = 5;
   static const int FAILURE = 6;
+  static const int FIN = 0x80;
+  static const int RSV1 = 0x40;
+  static const int RSV2 = 0x20;
+  static const int RSV3 = 0x10;
+  static const int OPCODE = 0xF;
 
   int _state = START;
   bool _fin = false;
+  bool _compressed = false;
   int _opcode = -1;
   int _len = -1;
   bool _masked = false;
@@ -71,18 +92,17 @@
   final List _maskingBytes = new List(4);
   final BytesBuilder _payload = new BytesBuilder(copy: false);
 
-  _WebSocketProtocolTransformer([this._serverSide = false]);
+  _WebSocketPerMessageDeflate _deflate;
+  _WebSocketProtocolTransformer([this._serverSide = false, this._deflate]);
 
   Stream bind(Stream stream) {
-    return new Stream.eventTransformed(
-        stream,
-        (EventSink eventSink) {
-          if (_eventSink != null) {
-            throw new StateError("WebSocket transformer already used.");
-          }
-          _eventSink = eventSink;
-          return this;
-        });
+    return new Stream.eventTransformed(stream, (EventSink eventSink) {
+      if (_eventSink != null) {
+        throw new StateError("WebSocket transformer already used.");
+      }
+      _eventSink = eventSink;
+      return this;
+    });
   }
 
   void addError(Object error, [StackTrace stackTrace]) =>
@@ -94,9 +114,8 @@
    * Process data received from the underlying communication channel.
    */
   void add(Uint8List buffer) {
-    int count = buffer.length;
     int index = 0;
-    int lastIndex = count;
+    int lastIndex = buffer.length;
     if (_state == CLOSED) {
       throw new WebSocketException("Data on closed connection");
     }
@@ -107,12 +126,23 @@
       int byte = buffer[index];
       if (_state <= LEN_REST) {
         if (_state == START) {
-          _fin = (byte & 0x80) != 0;
-          if ((byte & 0x70) != 0) {
-            // The RSV1, RSV2 bits RSV3 must be all zero.
+          _fin = (byte & FIN) != 0;
+
+          if((byte & (RSV2 | RSV3)) != 0) {
+            // The RSV2, RSV3 bits must both be zero.
             throw new WebSocketException("Protocol error");
           }
-          _opcode = (byte & 0xF);
+
+          _opcode = (byte & OPCODE);
+
+          if (_opcode != _WebSocketOpcode.CONTINUATION) {
+            if ((byte & RSV1) != 0) {
+              _compressed = true;
+            } else {
+              _compressed = false;
+            }
+          }
+
           if (_opcode <= _WebSocketOpcode.BINARY) {
             if (_opcode == _WebSocketOpcode.CONTINUATION) {
               if (_currentMessageType == _WebSocketMessageType.NONE) {
@@ -120,14 +150,14 @@
               }
             } else {
               assert(_opcode == _WebSocketOpcode.TEXT ||
-                     _opcode == _WebSocketOpcode.BINARY);
+                  _opcode == _WebSocketOpcode.BINARY);
               if (_currentMessageType != _WebSocketMessageType.NONE) {
                 throw new WebSocketException("Protocol error");
               }
               _currentMessageType = _opcode;
             }
           } else if (_opcode >= _WebSocketOpcode.CLOSE &&
-                     _opcode <= _WebSocketOpcode.PONG) {
+              _opcode <= _WebSocketOpcode.PONG) {
             // Control frames cannot be fragmented.
             if (!_fin) throw new WebSocketException("Protocol error");
           } else {
@@ -176,15 +206,14 @@
             _unmask(index, payloadLength, buffer);
           }
           // Control frame and data frame share _payloads.
-          _payload.add(
-              new Uint8List.view(buffer.buffer, index, payloadLength));
+          _payload.add(new Uint8List.view(buffer.buffer, index, payloadLength));
           index += payloadLength;
           if (_isControlFrame()) {
             if (_remainingPayloadBytes == 0) _controlFrameEnd();
           } else {
             if (_currentMessageType != _WebSocketMessageType.TEXT &&
                 _currentMessageType != _WebSocketMessageType.BINARY) {
-                throw new WebSocketException("Protocol error");
+              throw new WebSocketException("Protocol error");
             }
             if (_remainingPayloadBytes == 0) _messageFrameEnd();
           }
@@ -219,8 +248,8 @@
           mask = (mask << 8) | _maskingBytes[(_unmaskingIndex + i) & 3];
         }
         Int32x4 blockMask = new Int32x4(mask, mask, mask, mask);
-        Int32x4List blockBuffer = new Int32x4List.view(
-            buffer.buffer, index, blockCount);
+        Int32x4List blockBuffer =
+            new Int32x4List.view(buffer.buffer, index, blockCount);
         for (int i = 0; i < blockBuffer.length; i++) {
           blockBuffer[i] ^= blockMask;
         }
@@ -284,12 +313,17 @@
 
   void _messageFrameEnd() {
     if (_fin) {
+      var bytes = _payload.takeBytes();
+      if (_deflate != null && _compressed) {
+        bytes = _deflate.processIncomingMessage(bytes);
+      }
+
       switch (_currentMessageType) {
         case _WebSocketMessageType.TEXT:
-          _eventSink.add(UTF8.decode(_payload.takeBytes()));
+          _eventSink.add(UTF8.decode(bytes));
           break;
         case _WebSocketMessageType.BINARY:
-          _eventSink.add(_payload.takeBytes());
+          _eventSink.add(bytes);
           break;
       }
       _currentMessageType = _WebSocketMessageType.NONE;
@@ -331,8 +365,8 @@
 
   bool _isControlFrame() {
     return _opcode == _WebSocketOpcode.CLOSE ||
-           _opcode == _WebSocketOpcode.PING ||
-           _opcode == _WebSocketOpcode.PONG;
+        _opcode == _WebSocketOpcode.PING ||
+        _opcode == _WebSocketOpcode.PONG;
   }
 
   void _prepareForNextFrame() {
@@ -347,31 +381,29 @@
   }
 }
 
-
 class _WebSocketPing {
   final List<int> payload;
   _WebSocketPing([this.payload = null]);
 }
 
-
 class _WebSocketPong {
   final List<int> payload;
   _WebSocketPong([this.payload = null]);
 }
 
-
 class _WebSocketTransformerImpl implements WebSocketTransformer {
   final StreamController<WebSocket> _controller =
       new StreamController<WebSocket>(sync: true);
   final Function _protocolSelector;
+  final CompressionOptions _compression;
 
-  _WebSocketTransformerImpl(this._protocolSelector);
+  _WebSocketTransformerImpl(this._protocolSelector, this._compression);
 
   Stream<WebSocket> bind(Stream<HttpRequest> stream) {
     stream.listen((request) {
-        _upgrade(request, _protocolSelector)
-            .then((WebSocket webSocket) => _controller.add(webSocket))
-            .catchError(_controller.addError);
+      _upgrade(request, _protocolSelector, _compression)
+          .then((WebSocket webSocket) => _controller.add(webSocket))
+          .catchError(_controller.addError);
     }, onDone: () {
       _controller.close();
     });
@@ -379,13 +411,14 @@
     return _controller.stream;
   }
 
-  static Future<WebSocket> _upgrade(HttpRequest request, _protocolSelector) {
+  static Future<WebSocket> _upgrade(
+      HttpRequest request, _protocolSelector, CompressionOptions compression) {
     var response = request.response;
     if (!_isUpgradeRequest(request)) {
       // Send error response.
       response
-          ..statusCode = HttpStatus.BAD_REQUEST
-          ..close();
+        ..statusCode = HttpStatus.BAD_REQUEST
+        ..close();
       return new Future.error(
           new WebSocketException("Invalid WebSocket upgrade request"));
     }
@@ -393,9 +426,9 @@
     Future upgrade(String protocol) {
       // Send the upgrade response.
       response
-          ..statusCode = HttpStatus.SWITCHING_PROTOCOLS
-          ..headers.add(HttpHeaders.CONNECTION, "Upgrade")
-          ..headers.add(HttpHeaders.UPGRADE, "websocket");
+        ..statusCode = HttpStatus.SWITCHING_PROTOCOLS
+        ..headers.add(HttpHeaders.CONNECTION, "Upgrade")
+        ..headers.add(HttpHeaders.UPGRADE, "websocket");
       String key = request.headers.value("Sec-WebSocket-Key");
       _SHA1 sha1 = new _SHA1();
       sha1.add("$key$_webSocketGUID".codeUnits);
@@ -404,10 +437,13 @@
       if (protocol != null) {
         response.headers.add("Sec-WebSocket-Protocol", protocol);
       }
+
+      var deflate = _negotiateCompression(request, response, compression);
+
       response.headers.contentLength = 0;
-      return response.detachSocket()
-          .then((socket) => new _WebSocketImpl._fromSocket(
-                socket, protocol, true));
+      return response.detachSocket().then((socket) =>
+          new _WebSocketImpl._fromSocket(
+              socket, protocol, compression, true, deflate));
     }
 
     var protocols = request.headers['Sec-WebSocket-Protocol'];
@@ -416,26 +452,53 @@
       // consisting of multiple protocols. To unify all of them, first join
       // the lists with ', ' and then tokenize.
       protocols = _HttpParser._tokenizeFieldValue(protocols.join(', '));
-      return new Future(() => _protocolSelector(protocols))
-        .then((protocol) {
-          if (protocols.indexOf(protocol) < 0) {
-            throw new WebSocketException(
-                "Selected protocol is not in the list of available protocols");
-          }
-          return protocol;
-        })
-        .catchError((error) {
-          response
-              ..statusCode = HttpStatus.INTERNAL_SERVER_ERROR
-              ..close();
-          throw error;
-        })
-        .then(upgrade);
+      return new Future(() => _protocolSelector(protocols)).then((protocol) {
+        if (protocols.indexOf(protocol) < 0) {
+          throw new WebSocketException(
+              "Selected protocol is not in the list of available protocols");
+        }
+        return protocol;
+      }).catchError((error) {
+        response
+          ..statusCode = HttpStatus.INTERNAL_SERVER_ERROR
+          ..close();
+        throw error;
+      }).then(upgrade);
     } else {
       return upgrade(null);
     }
   }
 
+  static _WebSocketPerMessageDeflate _negotiateCompression(HttpRequest request,
+      HttpResponse response, CompressionOptions compression) {
+    var extensionHeader = request.headers.value("Sec-WebSocket-Extensions");
+
+    extensionHeader ??= "";
+
+    var hv = HeaderValue.parse(extensionHeader, valueSeparator: ',');
+    if (compression.enabled && hv.value == _WebSocketImpl.PER_MESSAGE_DEFLATE) {
+      var info = compression._createHeader(hv);
+
+      response.headers.add("Sec-WebSocket-Extensions", info.headerValue);
+      var serverNoContextTakeover =
+          (hv.parameters.containsKey(_serverNoContextTakeover) &&
+            compression.serverNoContextTakeover);
+      var clientNoContextTakeover =
+          (hv.parameters.containsKey(_clientNoContextTakeover) &&
+            compression.clientNoContextTakeover);
+      var deflate = new _WebSocketPerMessageDeflate(
+          serverNoContextTakeover: serverNoContextTakeover,
+          clientNoContextTakeover: clientNoContextTakeover,
+          serverMaxWindowBits: info.maxWindowBits,
+          clientMaxWindowBits: info.maxWindowBits,
+          serverSide: true);
+
+      return deflate;
+    }
+
+    return null;
+  }
+
   static bool _isUpgradeRequest(HttpRequest request) {
     if (request.method != "GET") {
       return false;
@@ -464,24 +527,124 @@
   }
 }
 
+class _WebSocketPerMessageDeflate {
+  bool serverNoContextTakeover;
+  bool clientNoContextTakeover;
+  int clientMaxWindowBits;
+  int serverMaxWindowBits;
+  bool serverSide;
+
+  _Filter decoder;
+  _Filter encoder;
+
+  _WebSocketPerMessageDeflate(
+      {this.clientMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS,
+       this.serverMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS,
+       this.serverNoContextTakeover: false,
+       this.clientNoContextTakeover: false,
+       this.serverSide: false});
+
+  void _ensureDecoder() {
+    if (decoder == null) {
+      decoder = _Filter._newZLibInflateFilter(
+          serverSide ? clientMaxWindowBits : serverMaxWindowBits, null, true);
+    }
+  }
+
+  void _ensureEncoder() {
+    if (encoder == null) {
+      encoder = _Filter._newZLibDeflateFilter(
+          false,
+          ZLibOption.DEFAULT_LEVEL,
+          serverSide ? serverMaxWindowBits : clientMaxWindowBits,
+          ZLibOption.DEFAULT_MEM_LEVEL,
+          ZLibOption.STRATEGY_DEFAULT,
+          null,
+          true);
+    }
+  }
+
+  Uint8List processIncomingMessage(List<int> msg) {
+    _ensureDecoder();
+
+    var data = [];
+    data.addAll(msg);
+    data.addAll(const [0x00, 0x00, 0xff, 0xff]);
+
+    decoder.process(data, 0, data.length);
+    var result = [];
+    var out;
+
+    while ((out = decoder.processed()) != null) {
+      result.addAll(out);
+    }
+
+    if ((serverSide && clientNoContextTakeover) ||
+        (!serverSide && serverNoContextTakeover)) {
+      decoder.end();
+      decoder = null;
+    }
+
+    return new Uint8List.fromList(result);
+  }
+
+  List<int> processOutgoingMessage(List<int> msg) {
+    _ensureEncoder();
+    var result = [];
+    Uint8List buffer;
+    var out;
+
+    if (msg is! Uint8List) {
+      for (var i = 0; i < msg.length; i++) {
+        if (msg[i] < 0 || 255 < msg[i]) {
+          throw new ArgumentError("List element is not a byte value "
+              "(value ${msg[i]} at index $i)");
+        }
+      }
+      buffer = new Uint8List.fromList(msg);
+    } else {
+      buffer = msg;
+    }
+
+    encoder.process(buffer, 0, buffer.length);
+
+    while ((out = encoder.processed()) != null) {
+      result.addAll(out);
+    }
+
+    if ((!serverSide && clientNoContextTakeover) ||
+        (serverSide && serverNoContextTakeover)) {
+      encoder.end();
+      encoder = null;
+    }
+
+    if (result.length > 4) {
+      result = result.sublist(0, result.length - 4);
+    }
+
+    return result;
+  }
+}
 
 // TODO(ajohnsen): Make this transformer reusable.
 class _WebSocketOutgoingTransformer implements StreamTransformer, EventSink {
   final _WebSocketImpl webSocket;
   EventSink _eventSink;
 
-  _WebSocketOutgoingTransformer(this.webSocket);
+  _WebSocketPerMessageDeflate _deflateHelper;
+
+  _WebSocketOutgoingTransformer(this.webSocket) {
+    _deflateHelper = webSocket._deflate;
+  }
 
   Stream bind(Stream stream) {
-    return new Stream.eventTransformed(
-        stream,
-        (EventSink eventSink) {
-          if (_eventSink != null) {
-            throw new StateError("WebSocket transformer already used");
-          }
-          _eventSink = eventSink;
-          return this;
-        });
+    return new Stream.eventTransformed(stream, (EventSink eventSink) {
+      if (_eventSink != null) {
+        throw new StateError("WebSocket transformer already used");
+      }
+      _eventSink = eventSink;
+      return this;
+    });
   }
 
   void add(message) {
@@ -500,12 +663,16 @@
         opcode = _WebSocketOpcode.TEXT;
         data = UTF8.encode(message);
       } else {
-        if (message is !List<int>) {
+        if (message is! List<int>) {
           throw new ArgumentError(message);
         }
         opcode = _WebSocketOpcode.BINARY;
         data = message;
       }
+
+      if (_deflateHelper != null) {
+        data = _deflateHelper.processOutgoingMessage(data);
+      }
     } else {
       opcode = _WebSocketOpcode.TEXT;
     }
@@ -531,11 +698,19 @@
     _eventSink.close();
   }
 
-  void addFrame(int opcode, List<int> data) =>
-      createFrame(opcode, data, webSocket._serverSide).forEach(_eventSink.add);
+  void addFrame(int opcode, List<int> data) => createFrame(
+          opcode,
+          data,
+          webSocket._serverSide,
+          _deflateHelper != null &&
+              (opcode == _WebSocketOpcode.TEXT ||
+                  opcode == _WebSocketOpcode.BINARY)).forEach((e) {
+        _eventSink.add(e);
+      });
 
-  static Iterable createFrame(int opcode, List<int> data, bool serverSide) {
-    bool mask = !serverSide;  // Masking not implemented for server.
+  static Iterable createFrame(
+      int opcode, List<int> data, bool serverSide, bool compressed) {
+    bool mask = !serverSide; // Masking not implemented for server.
     int dataLength = data == null ? 0 : data.length;
     // Determine the header size.
     int headerSize = (mask) ? 6 : 2;
@@ -546,11 +721,15 @@
     }
     Uint8List header = new Uint8List(headerSize);
     int index = 0;
+
     // Set FIN and opcode.
-    header[index++] = 0x80 | opcode;
+    var hoc = _WebSocketProtocolTransformer.FIN
+              | (compressed ? _WebSocketProtocolTransformer.RSV1 : 0)
+              | (opcode & _WebSocketProtocolTransformer.OPCODE);
+
+    header[index++] = hoc;
     // Determine size and position of length field.
     int lengthBytes = 1;
-    int firstLengthByte = 1;
     if (dataLength > 65535) {
       header[index++] = 127;
       lengthBytes = 8;
@@ -580,8 +759,7 @@
             list = new Uint8List(data.length);
             for (int i = 0; i < data.length; i++) {
               if (data[i] < 0 || 255 < data[i]) {
-                throw new ArgumentError(
-                    "List element is not a byte value "
+                throw new ArgumentError("List element is not a byte value "
                     "(value ${data[i]} at index $i)");
               }
               list[i] = data[i];
@@ -597,8 +775,8 @@
             mask = (mask << 8) | maskBytes[i];
           }
           Int32x4 blockMask = new Int32x4(mask, mask, mask, mask);
-          Int32x4List blockBuffer = new Int32x4List.view(
-              list.buffer, 0, blockCount);
+          Int32x4List blockBuffer =
+              new Int32x4List.view(list.buffer, 0, blockCount);
           for (int i = 0; i < blockBuffer.length; i++) {
             blockBuffer[i] ^= blockMask;
           }
@@ -619,7 +797,6 @@
   }
 }
 
-
 class _WebSocketConsumer implements StreamConsumer {
   final _WebSocketImpl webSocket;
   final Socket socket;
@@ -664,28 +841,28 @@
 
   _ensureController() {
     if (_controller != null) return;
-    _controller = new StreamController(sync: true,
-                                       onPause: _onPause,
-                                       onResume: _onResume,
-                                       onCancel: _onListen);
-    var stream = _controller.stream.transform(
-        new _WebSocketOutgoingTransformer(webSocket));
-    socket.addStream(stream)
-        .then((_) {
-          _done();
-          _closeCompleter.complete(webSocket);
-        }, onError: (error, StackTrace stackTrace) {
-          _closed = true;
-          _cancel();
-          if (error is ArgumentError) {
-            if (!_done(error, stackTrace)) {
-              _closeCompleter.completeError(error, stackTrace);
-            }
-          } else {
-            _done();
-            _closeCompleter.complete(webSocket);
-          }
-        });
+    _controller = new StreamController(
+        sync: true,
+        onPause: _onPause,
+        onResume: _onResume,
+        onCancel: _onListen);
+    var stream = _controller.stream
+        .transform(new _WebSocketOutgoingTransformer(webSocket));
+    socket.addStream(stream).then((_) {
+      _done();
+      _closeCompleter.complete(webSocket);
+    }, onError: (error, StackTrace stackTrace) {
+      _closed = true;
+      _cancel();
+      if (error is ArgumentError) {
+        if (!_done(error, stackTrace)) {
+          _closeCompleter.completeError(error, stackTrace);
+        }
+      } else {
+        _done();
+        _closeCompleter.complete(webSocket);
+      }
+    });
   }
 
   bool _done([error, StackTrace stackTrace]) {
@@ -706,13 +883,9 @@
     }
     _ensureController();
     _completer = new Completer();
-    _subscription = stream.listen(
-        (data) {
-          _controller.add(data);
-        },
-        onDone: _done,
-        onError: _done,
-        cancelOnError: true);
+    _subscription = stream.listen((data) {
+      _controller.add(data);
+    }, onDone: _done, onError: _done, cancelOnError: true);
     if (_issuedPause) {
       _subscription.pause();
       _issuedPause = false;
@@ -742,10 +915,11 @@
   }
 }
 
-
 class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
   // Use default Map so we keep order.
   static Map<int, _WebSocketImpl> _webSockets = new Map<int, _WebSocketImpl>();
+  static const int DEFAULT_WINDOW_BITS = 15;
+  static const String PER_MESSAGE_DEFLATE = "permessage-deflate";
 
   final String protocol;
 
@@ -766,11 +940,13 @@
   int _outCloseCode;
   String _outCloseReason;
   Timer _closeTimer;
+  _WebSocketPerMessageDeflate _deflate;
 
   static final HttpClient _httpClient = new HttpClient();
 
   static Future<WebSocket> connect(
-      String url, Iterable<String> protocols, Map<String, dynamic> headers) {
+      String url, Iterable<String> protocols, Map<String, dynamic> headers,
+      {CompressionOptions compression: CompressionOptions.DEFAULT}) {
     Uri uri = Uri.parse(url);
     if (uri.scheme != "ws" && uri.scheme != "wss") {
       throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'");
@@ -784,144 +960,182 @@
     }
     String nonce = _CryptoUtils.bytesToBase64(nonceData);
 
-    uri = new Uri(scheme: uri.scheme == "wss" ? "https" : "http",
-                  userInfo: uri.userInfo,
-                  host: uri.host,
-                  port: uri.port,
-                  path: uri.path,
-                  query: uri.query,
-                  fragment: uri.fragment);
-    return _httpClient.openUrl("GET", uri)
-      .then((request) {
-        if (uri.userInfo != null && !uri.userInfo.isEmpty) {
-          // If the URL contains user information use that for basic
-          // authorization.
-          String auth =
-          _CryptoUtils.bytesToBase64(UTF8.encode(uri.userInfo));
-          request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
-        }
-        if (headers != null) {
-          headers.forEach((field, value) => request.headers.add(field, value));
-        }
-        // Setup the initial handshake.
+    uri = new Uri(
+        scheme: uri.scheme == "wss" ? "https" : "http",
+        userInfo: uri.userInfo,
+        host: uri.host,
+        port: uri.port,
+        path: uri.path,
+        query: uri.query,
+        fragment: uri.fragment);
+    return _httpClient.openUrl("GET", uri).then((request) {
+      if (uri.userInfo != null && !uri.userInfo.isEmpty) {
+        // If the URL contains user information use that for basic
+        // authorization.
+        String auth = _CryptoUtils.bytesToBase64(UTF8.encode(uri.userInfo));
+        request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
+      }
+      if (headers != null) {
+        headers.forEach((field, value) => request.headers.add(field, value));
+      }
+      // Setup the initial handshake.
+      request.headers
+        ..set(HttpHeaders.CONNECTION, "Upgrade")
+        ..set(HttpHeaders.UPGRADE, "websocket")
+        ..set("Sec-WebSocket-Key", nonce)
+        ..set("Cache-Control", "no-cache")
+        ..set("Sec-WebSocket-Version", "13");
+      if (protocols != null) {
+        request.headers.add("Sec-WebSocket-Protocol", protocols.toList());
+      }
+
+      if (compression.enabled) {
         request.headers
-            ..set(HttpHeaders.CONNECTION, "Upgrade")
-            ..set(HttpHeaders.UPGRADE, "websocket")
-            ..set("Sec-WebSocket-Key", nonce)
-            ..set("Cache-Control", "no-cache")
-            ..set("Sec-WebSocket-Version", "13");
-        if (protocols != null) {
-          request.headers.add("Sec-WebSocket-Protocol", protocols.toList());
+            .add("Sec-WebSocket-Extensions", compression._createHeader());
+      }
+
+      return request.close();
+    }).then((response) {
+      void error(String message) {
+        // Flush data.
+        response.detachSocket().then((socket) {
+          socket.destroy();
+        });
+        throw new WebSocketException(message);
+      }
+      if (response.statusCode != HttpStatus.SWITCHING_PROTOCOLS ||
+          response.headers[HttpHeaders.CONNECTION] == null ||
+          !response.headers[HttpHeaders.CONNECTION]
+              .any((value) => value.toLowerCase() == "upgrade") ||
+          response.headers.value(HttpHeaders.UPGRADE).toLowerCase() !=
+              "websocket") {
+        error("Connection to '$uri' was not upgraded to websocket");
+      }
+      String accept = response.headers.value("Sec-WebSocket-Accept");
+      if (accept == null) {
+        error("Response did not contain a 'Sec-WebSocket-Accept' header");
+      }
+      _SHA1 sha1 = new _SHA1();
+      sha1.add("$nonce$_webSocketGUID".codeUnits);
+      List<int> expectedAccept = sha1.close();
+      List<int> receivedAccept = _CryptoUtils.base64StringToBytes(accept);
+      if (expectedAccept.length != receivedAccept.length) {
+        error("Reasponse header 'Sec-WebSocket-Accept' is the wrong length");
+      }
+      for (int i = 0; i < expectedAccept.length; i++) {
+        if (expectedAccept[i] != receivedAccept[i]) {
+          error("Bad response 'Sec-WebSocket-Accept' header");
         }
-        return request.close();
-      })
-      .then((response) {
-        void error(String message) {
-          // Flush data.
-          response.detachSocket().then((socket) {
-            socket.destroy();
-          });
-          throw new WebSocketException(message);
-        }
-        if (response.statusCode != HttpStatus.SWITCHING_PROTOCOLS ||
-            response.headers[HttpHeaders.CONNECTION] == null ||
-            !response.headers[HttpHeaders.CONNECTION].any(
-                (value) => value.toLowerCase() == "upgrade") ||
-            response.headers.value(HttpHeaders.UPGRADE).toLowerCase() !=
-                "websocket") {
-          error("Connection to '$uri' was not upgraded to websocket");
-        }
-        String accept = response.headers.value("Sec-WebSocket-Accept");
-        if (accept == null) {
-          error("Response did not contain a 'Sec-WebSocket-Accept' header");
-        }
-        _SHA1 sha1 = new _SHA1();
-        sha1.add("$nonce$_webSocketGUID".codeUnits);
-        List<int> expectedAccept = sha1.close();
-        List<int> receivedAccept = _CryptoUtils.base64StringToBytes(accept);
-        if (expectedAccept.length != receivedAccept.length) {
-          error("Reasponse header 'Sec-WebSocket-Accept' is the wrong length");
-        }
-        for (int i = 0; i < expectedAccept.length; i++) {
-          if (expectedAccept[i] != receivedAccept[i]) {
-            error("Bad response 'Sec-WebSocket-Accept' header");
-          }
-        }
-        var protocol = response.headers.value('Sec-WebSocket-Protocol');
-        return response.detachSocket()
-            .then((socket) => new _WebSocketImpl._fromSocket(socket, protocol));
-      });
+      }
+      var protocol = response.headers.value('Sec-WebSocket-Protocol');
+
+      _WebSocketPerMessageDeflate deflate =
+          negotiateClientCompression(response, compression);
+
+      return response.detachSocket().then((socket) =>
+          new _WebSocketImpl._fromSocket(
+              socket, protocol, compression, false, deflate));
+    });
   }
 
-  _WebSocketImpl._fromSocket(this._socket, this.protocol,
-                             [this._serverSide = false]) {
+  static _WebSocketPerMessageDeflate negotiateClientCompression(
+      HttpClientResponse response, CompressionOptions compression) {
+    String extensionHeader = response.headers.value('Sec-WebSocket-Extensions');
+
+    if (extensionHeader == null) {
+      extensionHeader = "";
+    }
+
+    var hv = HeaderValue.parse(extensionHeader, valueSeparator: ',');
+
+    if (compression.enabled && hv.value == PER_MESSAGE_DEFLATE) {
+      var serverNoContextTakeover =
+          hv.parameters.containsKey(_serverNoContextTakeover);
+      var clientNoContextTakeover =
+          hv.parameters.containsKey(_clientNoContextTakeover);
+
+      int getWindowBits(String type) {
+        var o = hv.parameters[type];
+        if (o == null) {
+          return DEFAULT_WINDOW_BITS;
+        }
+
+        o = int.parse(o, onError: (s) => DEFAULT_WINDOW_BITS);
+        return o;
+      }
+
+      return new _WebSocketPerMessageDeflate(
+          clientMaxWindowBits: getWindowBits(_clientMaxWindowBits),
+          serverMaxWindowBits: getWindowBits(_serverMaxWindowBits),
+          clientNoContextTakeover: clientNoContextTakeover,
+          serverNoContextTakeover: serverNoContextTakeover);
+    }
+
+    return null;
+  }
+
+  _WebSocketImpl._fromSocket(
+      this._socket, this.protocol, CompressionOptions compression,
+      [this._serverSide = false, _WebSocketPerMessageDeflate deflate]) {
     _consumer = new _WebSocketConsumer(this, _socket);
     _sink = new _StreamSinkImpl(_consumer);
     _readyState = WebSocket.OPEN;
+    _deflate = deflate;
 
-    var transformer = new _WebSocketProtocolTransformer(_serverSide);
-    _subscription = _socket.transform(transformer).listen(
-        (data) {
-          if (data is _WebSocketPing) {
-            if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload));
-          } else if (data is _WebSocketPong) {
-            // Simply set pingInterval, as it'll cancel any timers.
-            pingInterval = _pingInterval;
-          } else {
-            _controller.add(data);
-          }
-        },
-        onError: (error) {
-          if (_closeTimer != null) _closeTimer.cancel();
-          if (error is FormatException) {
-            _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
-          } else {
-            _close(WebSocketStatus.PROTOCOL_ERROR);
-          }
-          // An error happened, set the close code set above.
-          _closeCode = _outCloseCode;
-          _closeReason = _outCloseReason;
-          _controller.close();
-        },
-        onDone: () {
-          if (_closeTimer != null) _closeTimer.cancel();
-          if (_readyState == WebSocket.OPEN) {
-            _readyState = WebSocket.CLOSING;
-            if (!_isReservedStatusCode(transformer.closeCode)) {
-              _close(transformer.closeCode, transformer.closeReason);
-            } else {
-              _close();
-            }
-            _readyState = WebSocket.CLOSED;
-          }
-          // Protocol close, use close code from transformer.
-          _closeCode = transformer.closeCode;
-          _closeReason = transformer.closeReason;
-          _controller.close();
-        },
-        cancelOnError: true);
+    var transformer = new _WebSocketProtocolTransformer(_serverSide, _deflate);
+    _subscription = _socket.transform(transformer).listen((data) {
+      if (data is _WebSocketPing) {
+        if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload));
+      } else if (data is _WebSocketPong) {
+        // Simply set pingInterval, as it'll cancel any timers.
+        pingInterval = _pingInterval;
+      } else {
+        _controller.add(data);
+      }
+    }, onError: (error, stackTrace) {
+      if (_closeTimer != null) _closeTimer.cancel();
+      if (error is FormatException) {
+        _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
+      } else {
+        _close(WebSocketStatus.PROTOCOL_ERROR);
+      }
+      // An error happened, set the close code set above.
+      _closeCode = _outCloseCode;
+      _closeReason = _outCloseReason;
+      _controller.close();
+    }, onDone: () {
+      if (_closeTimer != null) _closeTimer.cancel();
+      if (_readyState == WebSocket.OPEN) {
+        _readyState = WebSocket.CLOSING;
+        if (!_isReservedStatusCode(transformer.closeCode)) {
+          _close(transformer.closeCode, transformer.closeReason);
+        } else {
+          _close();
+        }
+        _readyState = WebSocket.CLOSED;
+      }
+      // Protocol close, use close code from transformer.
+      _closeCode = transformer.closeCode;
+      _closeReason = transformer.closeReason;
+      _controller.close();
+    }, cancelOnError: true);
     _subscription.pause();
-    _controller = new StreamController(sync: true,
-                                       onListen: _subscription.resume,
-                                       onCancel: () {
-                                         _subscription.cancel();
-                                         _subscription = null;
-                                       },
-                                       onPause: _subscription.pause,
-                                       onResume: _subscription.resume);
+    _controller = new StreamController(
+        sync: true, onListen: _subscription.resume, onCancel: () {
+      _subscription.cancel();
+      _subscription = null;
+    }, onPause: _subscription.pause, onResume: _subscription.resume);
 
     _webSockets[_serviceId] = this;
-    try { _socket._owner = this; } catch (_) {}
+    try {
+      _socket._owner = this;
+    } catch (_) {}
   }
 
   StreamSubscription listen(void onData(message),
-                            {Function onError,
-                             void onDone(),
-                             bool cancelOnError}) {
+      {Function onError, void onDone(), bool cancelOnError}) {
     return _controller.stream.listen(onData,
-                                     onError: onError,
-                                     onDone: onDone,
-                                     cancelOnError: cancelOnError);
+        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
   }
 
   Duration get pingInterval => _pingInterval;
@@ -1027,13 +1241,12 @@
 
   static bool _isReservedStatusCode(int code) {
     return code != null &&
-           (code < WebSocketStatus.NORMAL_CLOSURE ||
+        (code < WebSocketStatus.NORMAL_CLOSURE ||
             code == WebSocketStatus.RESERVED_1004 ||
             code == WebSocketStatus.NO_STATUS_RECEIVED ||
             code == WebSocketStatus.ABNORMAL_CLOSURE ||
             (code > WebSocketStatus.INTERNAL_SERVER_ERROR &&
-             code < WebSocketStatus.RESERVED_1015) ||
-            (code >= WebSocketStatus.RESERVED_1015 &&
-             code < 3000));
+                code < WebSocketStatus.RESERVED_1015) ||
+            (code >= WebSocketStatus.RESERVED_1015 && code < 3000));
   }
 }
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 8d284d2..a0bfa67 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -127,6 +127,34 @@
   external static Isolate get current;
 
   /**
+   * Returns the package root of the current isolate, if any.
+   *
+   * If the isolate is using a [packageConfig] or the isolate has not been
+   * setup for package resolution, this getter returns `null`, otherwise it
+   * returns the package root - a directory that package URIs are resolved
+   * against.
+   */
+  external static Future<Uri> get packageRoot;
+
+  /**
+   * Returns the package root of the current isolate, if any.
+   *
+   * If the isolate is using a [packageRoot] or the isolate has not been
+   * setup for package resolution, this getter returns `null`, otherwise it
+   * returns the package config URI.
+   */
+  external static Future<Uri> get packageConfig;
+
+  /**
+   * Maps a package: URI to a non-package Uri.
+   *
+   * If there is no valid mapping from the package: URI in the current
+   * isolate, then this call returns `null`. Non-package: URIs are
+   * returned unmodified.
+   */
+  external static Future<Uri> resolvePackageUri(Uri packageUri);
+
+  /**
    * Creates and spawns an isolate that shares the same code as the current
    * isolate.
    *
@@ -222,6 +250,14 @@
    * resolved against this location, as by
    * `packageRoot.resolve("foo/bar.dart")`.
    *
+   * If the [packageConfig] parameter is provided, then it is used to find the
+   * location of a package resolution configuration file for the spawned
+   * isolate.
+   *
+   * If the [automaticPackageResolution] parameter is provided, then the
+   * location of the package sources in the spawned isolate is automatically
+   * determined.
+   *
    * The [environment] is a mapping from strings to strings which the
    * spawned isolate uses when looking up [String.fromEnvironment] values.
    * The system may add its own entries to environment as well.
@@ -244,7 +280,9 @@
        bool errorsAreFatal,
        bool checked,
        Map<String, String> environment,
-       Uri packageRoot});
+       Uri packageRoot,
+       Uri packageConfig,
+       bool automaticPackageResolution: false});
 
   /**
    * Requests the isolate to pause.
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index b01dce0..ce2c5a2 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -310,8 +310,24 @@
 final _JS_LIBRARY_PREFIX = "js_library";
 final _UNDEFINED_VAR = "_UNDEFINED_JS_CONST";
 
-String _accessJsPath(String path) =>
-    "${_JS_LIBRARY_PREFIX}.context${path.split(".").map((p) => "['$p']").join('')}";
+String _accessJsPath(String path) => _accessJsPathHelper(path.split("."));
+
+String _accessJsPathHelper(Iterable<String> parts) {
+  var sb = new StringBuffer();
+  sb
+    ..write('${_JS_LIBRARY_PREFIX}.JsNative.getProperty(' * parts.length)
+    ..write("${_JS_LIBRARY_PREFIX}.context");
+  for (var p in parts) {
+    sb.write(", '$p')");
+  }
+  return sb.toString();
+}
+
+String _accessJsPathSetter(String path) {
+  var parts = path.split(".");
+  return "${_JS_LIBRARY_PREFIX}.JsNative.setProperty(${_accessJsPathHelper(parts.getRange(0, parts.length - 1))
+      }, '${parts.last}', v)";
+}
 
 @Deprecated("Internal Use Only")
 void addMemberHelper(
@@ -331,9 +347,9 @@
   }
   sb.write(" ");
   if (declaration.isGetter) {
-    sb.write("get $name => ${_accessJsPath(path)};");
+    sb.write("get $name => ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPath(path)});");
   } else if (declaration.isSetter) {
-    sb.write("set $name(v) => ${_accessJsPath(path)} = v;");
+    sb.write("set $name(v) => ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPathSetter(path)});");
   } else {
     sb.write("$name(");
     bool hasOptional = false;
@@ -362,6 +378,7 @@
     }
     // TODO(jacobr):
     sb.write(") => ");
+    sb.write('${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(');
     if (declaration.isConstructor) {
       sb.write("new ${_JS_LIBRARY_PREFIX}.JsObject(");
     }
@@ -373,18 +390,17 @@
     if (hasOptional) {
       sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()");
     }
-    sb.write(");");
+    sb.write("));");
   }
   sb.write("\n");
 }
 
-// TODO(jacobr): make this check more robust.
-bool _isExternal(mirrors.Mirror mirror) {
-  /*
-  var source = mirror.source;
-  return source != null && source.startsWith("external ");
-  */
-  return mirror.isExternal;
+bool _isExternal(mirrors.MethodMirror mirror) {
+  // This try-catch block is a workaround for BUG:24834.
+  try {
+    return mirror.isExternal;
+  } catch (e) { }
+  return false;
 }
 
 List<String> _generateExternalMethods() {
@@ -853,6 +869,10 @@
   return _cachedContext;
 }
 
+@Deprecated("Internal Use Only")
+maybeWrapTypedInterop(o) =>
+    html_common.wrap_jso_no_SerializedScriptvalue(o);
+
 _maybeWrap(o) {
   var wrapped = html_common.wrap_jso_no_SerializedScriptvalue(o);
   if (identical(wrapped, o)) return o;
@@ -1102,7 +1122,7 @@
         throwError();
       } else {
         // TODO(jacobr): should we throw if the JavaScript object doesn't have the property?
-        return this[name];
+        return maybeWrapTypedInterop(this._operator_getter(name));
       }
     } else if (invocation.isSetter) {
       if (CHECK_JS_INVOCATIONS) {
@@ -1112,7 +1132,8 @@
       }
       assert(name.endsWith("="));
       name = name.substring(0, name.length - 1);
-      return this[name] = invocation.positionalArguments.first;
+      return maybeWrapTypedInterop(_operator_setter(
+          name, invocation.positionalArguments.first));
     } else {
       // TODO(jacobr): also allow calling getters that look like functions.
       var matches;
@@ -1121,7 +1142,7 @@
         if (matches == null ||
             !matches.checkInvocation(invocation)) throwError();
       }
-      var ret = this.callMethod(name, _buildArgs(invocation));
+      var ret = maybeWrapTypedInterop(this._callMethod(name, _buildArgs(invocation)));
       if (CHECK_JS_INVOCATIONS) {
         if (!matches._checkReturnType(ret)) throwError();
       }
@@ -1136,12 +1157,17 @@
 // Warning: this API is not exposed to dart:js.
 @Deprecated("Internal Use Only")
 class JsNative {
-  static getProperty(JsObject o, name) {
-    return o._operator_getter(name);
+  static getProperty(o, name) {
+    o = unwrap_jso(o);
+    return o != null ? o._operator_getter(name) : null;
   }
 
-  static callMethod(JsObject o, String method, List args) {
-    return o._callMethod(method, args);
+  static setProperty(o, name, value) {
+    return unwrap_jso(o)._operator_setter(name, value);
+  }
+
+  static callMethod(o, String method, List args) {
+    return unwrap_jso(o)._callMethod(method, args);
   }
 
   static getArrayIndex(JsArray array, int index) {
diff --git a/sdk/lib/math/math.dart b/sdk/lib/math/math.dart
index d167d80..7073e4d 100644
--- a/sdk/lib/math/math.dart
+++ b/sdk/lib/math/math.dart
@@ -58,12 +58,12 @@
   * Returns the lesser of two numbers.
   *
   * Returns NaN if either argument is NaN.
-  * The lesser of [:-0.0:] and [:0.0:] is [:-0.0:].
+  * The lesser of `-0.0` and `0.0` is `-0.0`.
   * If the arguments are otherwise equal (including int and doubles with the
   * same mathematical value) then it is unspecified which of the two arguments
   * is returned.
   */
-num min(num a, num b) {
+num/*=T*/ min/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) {
   // These partially redundant type checks improve code quality for dart2js.
   // Most of the improvement is at call sites from the inferred non-null num
   // return type.
@@ -94,11 +94,11 @@
   * Returns the larger of two numbers.
   *
   * Returns NaN if either argument is NaN.
-  * The larger of [:-0.0:] and [:0.0:] is [:0.0:]. If the arguments are
+  * The larger of `-0.0` and `0.0` is `0.0`. If the arguments are
   * otherwise equal (including int and doubles with the same mathematical value)
   * then it is unspecified which of the two arguments is returned.
   */
-num max(num a, num b) {
+num/*=T*/ max/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) {
   // These partially redundant type checks improve code quality for dart2js.
   // Most of the improvement is at call sites from the inferred non-null num
   // return type.
@@ -135,7 +135,7 @@
  * Returns the angle between the positive x-axis and the vector ([b],[a]).
  * The result, in radians, is in the range -PI..PI.
  *
- * If [b] is positive, this is the same as [:atan(b/a):].
+ * If [b] is positive, this is the same as `atan(b/a)`.
  *
  * The result is negative when [a] is negative (including when [a] is the
  * double -0.0).
@@ -204,8 +204,8 @@
 /**
  * Converts [x] to a double and returns the tangent of the value.
  *
- * The tangent function is equivalent to [:sin(x)/cos(x):] and may be
- * infinite (positive or negative) when [:cos(x):] is equal to zero.
+ * The tangent function is equivalent to `sin(x)/cos(x)` and may be
+ * infinite (positive or negative) when `cos(x)` is equal to zero.
  * If [x] is not a finite number, the result is NaN.
  */
 external double tan(num x);
@@ -213,22 +213,22 @@
 /**
  * Converts [x] to a double and returns the arc cosine of the value.
  *
- * Returns a value in the range -PI..PI, or NaN if [x] is outside
+ * Returns a value in the range 0..PI, or NaN if [x] is outside
  * the range -1..1.
  */
 external double acos(num x);
 
 /**
  * Converts [x] to a double and returns the arc sine of the value.
- * 
- * Returns a value in the range -PI..PI, or  NaN if [x] is outside
+ *
+ * Returns a value in the range -PI/2..PI/2, or NaN if [x] is outside
  * the range -1..1.
  */
 external double asin(num x);
 
 /**
- * Converts [x] to a dobule and returns the arc tangent of the value.
- * 
+ * Converts [x] to a double and returns the arc tangent of the value.
+ *
  * Returns a value in the range -PI/2..PI/2, or NaN if [x] is NaN.
  */
 external double atan(num x);
@@ -243,14 +243,14 @@
 /**
  * Converts [x] to a double and returns the natural exponent, [E],
  * to the power [x].
- * 
+ *
  * Returns NaN if [x] is NaN.
  */
 external double exp(num x);
 
 /**
  * Converts [x] to a double and returns the natural logarithm of the value.
- * 
+ *
  * Returns negative infinity if [x] is equal to zero.
  * Returns NaN if [x] is NaN or less than zero.
  */
diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart
index 0c1c76c..47c5582 100644
--- a/sdk/lib/math/random.dart
+++ b/sdk/lib/math/random.dart
@@ -9,23 +9,34 @@
  *
  * The default implementation supplies a stream of
  * pseudo-random bits that are not suitable for cryptographic purposes.
+ *
+ * Use the Random.secure() constructor for cryptographic
+ * purposes.
  */
 abstract class Random {
   /**
    * Creates a random number generator.
    *
-   * The optional parameter [seed] is used
-   * to initialize the internal state of the generator. The implementation of
-   * the random stream can change between releases of the library.
+   * The optional parameter [seed] is used to initialize the
+   * internal state of the generator. The implementation of the
+   * random stream can change between releases of the library.
    */
   external factory Random([int seed]);
 
   /**
+   * Creates a cryptographically secure random number generator.
+   *
+   * If the program cannot provide a cryptographically secure
+   * source of random numbers, it throws an [UnsupportedError].
+   */
+  external factory Random.secure();
+
+  /**
    * Generates a non-negative random integer uniformly distributed in the range
    * from 0, inclusive, to [max], exclusive.
    *
    * Implementation note: The default implementation supports [max] values
-   * between 1 and ((1<<32) - 1) inclusive.
+   * between 1 and (1<<32) inclusive.
    */
   int nextInt(int max);
 
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index b04675c..d972b62 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -10,7 +10,7 @@
 
 /**
  * A sequence of bytes underlying a typed data object.
- * 
+ *
  * Used to process large quantities of binary or numerical data
  * more efficiently using a typed view.
  */
@@ -404,7 +404,7 @@
  * A fixed-length, random-access sequence of bytes that also provides random
  * and unaligned access to the fixed-width integers and floating point
  * numbers represented by those bytes.
- * 
+ *
  * `ByteData` may be used to pack and unpack data from external sources
  * (such as networks or files systems), and to process large quantities
  * of numerical data more efficiently than would be possible
@@ -451,7 +451,7 @@
    * Returns the (possibly negative) integer represented by the byte at the
    * specified [byteOffset] in this object, in two's complement binary
    * representation.
-   * 
+   *
    * The return value will be between -128 and 127, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -463,7 +463,7 @@
    * Sets the byte at the specified [byteOffset] in this object to the
    * two's complement binary representation of the specified [value], which
    * must fit in a single byte.
-   * 
+   *
    * In other words, [value] must be between -128 and 127, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -474,7 +474,7 @@
   /**
    * Returns the positive integer represented by the byte at the specified
    * [byteOffset] in this object, in unsigned binary form.
-   * 
+   *
    * The return value will be between 0 and 255, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -486,7 +486,7 @@
    * Sets the byte at the specified [byteOffset] in this object to the
    * unsigned binary representation of the specified [value], which must fit
    * in a single byte.
-   * 
+   *
    * In other words, [value] must be between 0 and 255, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative,
@@ -498,7 +498,7 @@
    * Returns the (possibly negative) integer represented by the two bytes at
    * the specified [byteOffset] in this object, in two's complement binary
    * form.
-   * 
+   *
    * The return value will be between 2<sup>15</sup> and 2<sup>15</sup> - 1,
    * inclusive.
    *
@@ -511,7 +511,7 @@
    * Sets the two bytes starting at the specified [byteOffset] in this
    * object to the two's complement binary representation of the specified
    * [value], which must fit in two bytes.
-   * 
+   *
    * In other words, [value] must lie
    * between 2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
    *
@@ -526,7 +526,7 @@
    * Returns the positive integer represented by the two bytes starting
    * at the specified [byteOffset] in this object, in unsigned binary
    * form.
-   * 
+   *
    * The return value will be between 0 and  2<sup>16</sup> - 1, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -538,7 +538,7 @@
    * Sets the two bytes starting at the specified [byteOffset] in this object
    * to the unsigned binary representation of the specified [value],
    * which must fit in two bytes.
-   * 
+   *
    * In other words, [value] must be between
    * 0 and 2<sup>16</sup> - 1, inclusive.
    *
@@ -553,7 +553,7 @@
    * Returns the (possibly negative) integer represented by the four bytes at
    * the specified [byteOffset] in this object, in two's complement binary
    * form.
-   * 
+   *
    * The return value will be between 2<sup>31</sup> and 2<sup>31</sup> - 1,
    * inclusive.
    *
@@ -566,7 +566,7 @@
    * Sets the four bytes starting at the specified [byteOffset] in this
    * object to the two's complement binary representation of the specified
    * [value], which must fit in four bytes.
-   * 
+   *
    * In other words, [value] must lie
    * between 2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
    *
@@ -581,7 +581,7 @@
    * Returns the positive integer represented by the four bytes starting
    * at the specified [byteOffset] in this object, in unsigned binary
    * form.
-   * 
+   *
    * The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -593,7 +593,7 @@
    * Sets the four bytes starting at the specified [byteOffset] in this object
    * to the unsigned binary representation of the specified [value],
    * which must fit in four bytes.
-   * 
+   *
    * In other words, [value] must be between
    * 0 and 2<sup>32</sup> - 1, inclusive.
    *
@@ -608,7 +608,7 @@
    * Returns the (possibly negative) integer represented by the eight bytes at
    * the specified [byteOffset] in this object, in two's complement binary
    * form.
-   * 
+   *
    * The return value will be between 2<sup>63</sup> and 2<sup>63</sup> - 1,
    * inclusive.
    *
@@ -621,7 +621,7 @@
    * Sets the eight bytes starting at the specified [byteOffset] in this
    * object to the two's complement binary representation of the specified
    * [value], which must fit in eight bytes.
-   * 
+   *
    * In other words, [value] must lie
    * between 2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
    *
@@ -636,7 +636,7 @@
    * Returns the positive integer represented by the eight bytes starting
    * at the specified [byteOffset] in this object, in unsigned binary
    * form.
-   * 
+   *
    * The return value will be between 0 and  2<sup>64</sup> - 1, inclusive.
    *
    * Throws [RangeError] if [byteOffset] is negative, or
@@ -648,7 +648,7 @@
    * Sets the eight bytes starting at the specified [byteOffset] in this object
    * to the unsigned binary representation of the specified [value],
    * which must fit in eight bytes.
-   * 
+   *
    * In other words, [value] must be between
    * 0 and 2<sup>64</sup> - 1, inclusive.
    *
@@ -718,9 +718,13 @@
 
 /**
  * A fixed-length list of 8-bit signed integers.
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low eight bits,
+ * interpreted as a signed 8-bit two's complement integer with values in the
+ * range -128 to +127.
  */
 abstract class Int8List implements List<int>, TypedData {
   /**
@@ -732,6 +736,9 @@
   /**
    * Creates a [Int8List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Int8List.fromList(List<int> elements);
 
@@ -760,9 +767,13 @@
 
 /**
  * A fixed-length list of 8-bit unsigned integers.
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low eight bits,
+ * interpreted as an unsigned 8-bit integer with values in the
+ * range 0 to 255.
  */
 abstract class Uint8List implements List<int>, TypedData {
   /**
@@ -774,6 +785,9 @@
   /**
    * Creates a [Uint8List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Uint8List.fromList(List<int> elements);
 
@@ -802,10 +816,13 @@
 
 /**
  * A fixed-length list of 8-bit unsigned integers.
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
- * Indexed store clamps the value to range 0..0xFF.
+ *
+ * Integers stored in the list are clamped to an unsigned eight bit value.
+ * That is, all values below zero are stored as zero
+ * and all values above 255 are stored as 255.
  */
 abstract class Uint8ClampedList implements List<int>, TypedData {
   /**
@@ -817,6 +834,9 @@
   /**
    * Creates a [Uint8ClampedList] of the same size as the [elements]
    * list and copies over the values clamping when needed.
+   *
+   * Values are clamped to fit in the list when they are copied,
+   * the same way storing values clamps them.
    */
   external factory Uint8ClampedList.fromList(List<int> elements);
 
@@ -847,9 +867,13 @@
 /**
  * A fixed-length list of 16-bit signed integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 16 bits,
+ * interpreted as a signed 16-bit two's complement integer with values in the
+ * range -32768 to +32767.
  */
 abstract class Int16List implements List<int>, TypedData {
   /**
@@ -861,6 +885,9 @@
   /**
    * Creates a [Int16List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Int16List.fromList(List<int> elements);
 
@@ -893,9 +920,13 @@
 /**
  * A fixed-length list of 16-bit unsigned integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 16 bits,
+ * interpreted as an unsigned 16-bit integer with values in the
+ * range 0 to 65536.
  */
 abstract class Uint16List implements List<int>, TypedData {
   /**
@@ -907,6 +938,9 @@
   /**
    * Creates a [Uint16List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Uint16List.fromList(List<int> elements);
 
@@ -940,9 +974,13 @@
 /**
  * A fixed-length list of 32-bit signed integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 32 bits,
+ * interpreted as a signed 32-bit two's complement integer with values in the
+ * range -2147483648 to 2147483647.
  */
 abstract class Int32List implements List<int>, TypedData {
   /**
@@ -954,6 +992,9 @@
   /**
    * Creates a [Int32List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Int32List.fromList(List<int> elements);
 
@@ -986,9 +1027,13 @@
 /**
  * A fixed-length list of 32-bit unsigned integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 32 bits,
+ * interpreted as an unsigned 32-bit integer with values in the
+ * range 0 to 4294967295.
  */
 abstract class Uint32List implements List<int>, TypedData {
   /**
@@ -1000,6 +1045,9 @@
   /**
    * Creates a [Uint32List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Uint32List.fromList(List<int> elements);
 
@@ -1033,9 +1081,13 @@
 /**
  * A fixed-length list of 64-bit signed integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 64 bits,
+ * interpreted as a signed 64-bit two's complement integer with values in the
+ * range -9223372036854775808 to +9223372036854775807.
  */
 abstract class Int64List implements List<int>, TypedData {
   /**
@@ -1047,6 +1099,9 @@
   /**
    * Creates a [Int64List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Int64List.fromList(List<int> elements);
 
@@ -1079,9 +1134,13 @@
 /**
  * A fixed-length list of 64-bit unsigned integers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation can be considerably
  * more space- and time-efficient than the default [List] implementation.
+ *
+ * Integers stored in the list are truncated to their low 64 bits,
+ * interpreted as an unsigned 64-bit integer with values in the
+ * range 0 to 18446744073709551616.
  */
 abstract class Uint64List implements List<int>, TypedData {
   /**
@@ -1093,6 +1152,9 @@
   /**
    * Creates a [Uint64List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Uint64List.fromList(List<int> elements);
 
@@ -1125,11 +1187,15 @@
 
 /**
  * A fixed-length list of IEEE 754 single-precision binary floating-point
- * numbers  that is viewable as a [TypedData].
- * 
+ * numbers that is viewable as a [TypedData].
+ *
  * For long lists, this
  * implementation can be considerably more space- and time-efficient than
  * the default [List] implementation.
+ *
+ * Double values stored in the list are converted to the nearest
+ * single-precision value. Values read are converted to a double
+ * value with the same value.
  */
 abstract class Float32List implements List<double>, TypedData {
   /**
@@ -1141,6 +1207,9 @@
   /**
    * Creates a [Float32List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * Values are truncated to fit in the list when they are copied,
+   * the same way storing values truncates them.
    */
   external factory Float32List.fromList(List<double> elements);
 
@@ -1173,7 +1242,7 @@
 /**
  * A fixed-length list of IEEE 754 double-precision binary floating-point
  * numbers  that is viewable as a [TypedData].
- * 
+ *
  * For long lists, this
  * implementation can be considerably more space- and time-efficient than
  * the default [List] implementation.
@@ -1220,7 +1289,7 @@
 /**
  * A fixed-length list of Float32x4 numbers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation will be considerably more
  * space- and time-efficient than the default [List] implementation.
  */
@@ -1266,7 +1335,7 @@
 /**
  * A fixed-length list of Int32x4 numbers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation will be considerably more
  * space- and time-efficient than the default [List] implementation.
  */
@@ -1312,7 +1381,7 @@
 /**
  * A fixed-length list of Float64x2 numbers that is viewable as a
  * [TypedData].
- * 
+ *
  * For long lists, this implementation will be considerably more
  * space- and time-efficient than the default [List] implementation.
  */
@@ -1357,7 +1426,7 @@
 
 /**
  * Float32x4 immutable value type and operations.
- * 
+ *
  * Float32x4 stores 4 32-bit floating point values in "lanes".
  * The lanes are "x", "y", "z", and "w" respectively.
  */
@@ -1712,7 +1781,7 @@
 
 /**
  * Int32x4 and operations.
- * 
+ *
  * Int32x4 stores 4 32-bit bit-masks in "lanes".
  * The lanes are "x", "y", "z", and "w" respectively.
  */
@@ -2049,7 +2118,7 @@
 
 /**
  * Float64x2 immutable value type and operations.
- * 
+ *
  * Float64x2 stores 2 64-bit floating point values in "lanes".
  * The lanes are "x" and "y" respectively.
  */
diff --git a/sdk/lib/vmservice/asset.dart b/sdk/lib/vmservice/asset.dart
new file mode 100644
index 0000000..8155e8a
--- /dev/null
+++ b/sdk/lib/vmservice/asset.dart
@@ -0,0 +1,205 @@
+// 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 dart._vmservice;
+
+class Asset {
+  final String name;
+  final Uint8List data;
+
+  Asset(this.name, this.data);
+
+  String get mimeType {
+    var extensionStart = name.lastIndexOf('.');
+    var extension = name.substring(extensionStart+1);
+    switch (extension) {
+      case 'html':
+        return 'text/html; charset=UTF-8';
+      case 'dart':
+        return 'application/dart; charset=UTF-8';
+      case 'js':
+        return 'application/javascript; charset=UTF-8';
+      case 'css':
+        return 'text/css; charset=UTF-8';
+      case 'gif':
+        return 'image/gif';
+      case 'png':
+        return 'image/png';
+      case 'jpg':
+        return 'image/jpeg';
+      case 'jpeg':
+        return 'image/jpeg';
+      case 'svg':
+        return 'image/svg+xml';
+      default:
+        return 'text/plain';
+    }
+  }
+
+  /// Call to request assets from the embedder.
+  static HashMap<String, Asset> request() {
+    HashMap<String, Asset> assets = new HashMap<String, Asset>();
+    Uint8List tarBytes = _requestAssets();
+    if (tarBytes == null) {
+      return assets;
+    }
+    _TarArchive archive = new _TarArchive(tarBytes);
+    while (archive.hasNext()) {
+      Asset asset = archive.next();
+      if (asset == null) {
+        // Skip over special files.
+        continue;
+      }
+      assets[asset.name] = asset;
+    }
+    return assets;
+  }
+
+  String toString() => '$name ($mimeType)';
+}
+
+
+class _ByteStream {
+  final Uint8List bytes;
+  final int offset;
+  int get length => bytes.length - offset;
+  int _cursor = 0;
+
+  _ByteStream(this.bytes, [this.offset = 0]);
+
+  void reset() {
+    _cursor = 0;
+  }
+
+  int peekByte([int index = 0]) => bytes[offset + _cursor + index];
+
+  int readByte() {
+    int r = peekByte();
+    _advance(1);
+    return r;
+  }
+
+  void skip(int bytes) => _advance(bytes);
+
+  void seekToNextBlock(int blockSize) {
+    int remainder = blockSize - (_cursor % blockSize);
+    _advance(remainder);
+  }
+
+  void _advance(int bytes) {
+    _cursor += bytes;
+    if (_cursor > length) {
+      _cursor = length;
+    }
+  }
+
+  int get remaining => length - _cursor;
+  bool get hasMore => remaining > 0;
+  int get cursor => _cursor;
+  void set cursor(int cursor) {
+    _cursor = cursor;
+    if (_cursor > length) {
+      _cursor = length;
+    }
+  }
+}
+
+class _TarArchive {
+  static const List<int> tarMagic = const [ 0x75, 0x73, 0x74, 0x61, 0x72, 0 ];
+  static const List<int> tarVersion = const [ 0x30, 0x30 ];
+  static const int tarHeaderSize = 512;
+  static const int tarHeaderFilenameSize = 100;
+  static const int tarHeaderFilenameOffset = 0;
+  static const int tarHeaderSizeSize = 12;
+  static const int tarHeaderSizeOffset = 124;
+  static const int tarHeaderTypeSize = 1;
+  static const int tarHeaderTypeOffset = 156;
+  static const int tarHeaderFileType = 0x30;
+
+  static String _readCString(_ByteStream bs, int length) {
+    StringBuffer sb = new StringBuffer();
+    int count = 0;
+    while (bs.hasMore && count < length) {
+      if (bs.peekByte() == 0) {
+        // Null character.
+        break;
+      }
+      sb.writeCharCode(bs.readByte());
+      count++;
+    }
+    return sb.toString();
+  }
+
+  static String _readFilename(_ByteStream bs) {
+    String filename = _readCString(bs, tarHeaderFilenameSize);
+    if (filename.startsWith('/')) {
+      return filename;
+    }
+    return '/' + filename;
+  }
+
+  static Uint8List _readContents(_ByteStream bs, int size) {
+    Uint8List result = new Uint8List(size);
+    int i = 0;
+    while (bs.hasMore && i < size) {
+      result[i] = bs.readByte();
+      i++;
+    }
+    bs.seekToNextBlock(tarHeaderSize);
+    return result;
+  }
+
+  static void _skipContents(_ByteStream bs, int size) {
+    bs.skip(size);
+    bs.seekToNextBlock(tarHeaderSize);
+  }
+
+  static int _readSize(_ByteStream bs) {
+    String octalSize = _readCString(bs, tarHeaderSizeSize);
+    return int.parse(octalSize,
+                     radix: 8,
+                     onError: (_) => 0);
+  }
+
+  static int _readType(_ByteStream bs) {
+    return bs.readByte();
+  }
+
+  static bool _endOfArchive(_ByteStream bs) {
+    if (bs.remaining < (tarHeaderSize * 2)) {
+      return true;
+    }
+    for (int i = 0; i < (tarHeaderSize * 2); i++) {
+      if (bs.peekByte(i) != 0) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  final _ByteStream _bs;
+
+  _TarArchive(Uint8List bytes)
+      : _bs = new _ByteStream(bytes);
+
+  bool hasNext() {
+    return !_endOfArchive(_bs);
+  }
+
+  Asset next() {
+    int startOfBlock = _bs.cursor;
+    String filename = _readFilename(_bs);
+    _bs.cursor = startOfBlock + tarHeaderSizeOffset;
+    int size = _readSize(_bs);
+    _bs.cursor = startOfBlock + tarHeaderTypeOffset;
+    int type = _readType(_bs);
+    _bs.seekToNextBlock(tarHeaderSize);
+    if (type != tarHeaderFileType) {
+      _skipContents(_bs, size);
+      return null;
+    }
+    Uint8List bytes = _readContents(_bs, size);
+    return new Asset(filename, bytes);
+  }
+}
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index eda4504..fa7790f 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -5,10 +5,12 @@
 library dart._vmservice;
 
 import 'dart:async';
+import 'dart:collection';
 import 'dart:convert';
 import 'dart:isolate';
 import 'dart:typed_data';
 
+part 'asset.dart';
 part 'client.dart';
 part 'constants.dart';
 part 'running_isolate.dart';
@@ -329,3 +331,4 @@
 
 external void _vmCancelStream(String streamId);
 
+external Uint8List _requestAssets();
diff --git a/sdk/lib/vmservice/vmservice_sources.gypi b/sdk/lib/vmservice/vmservice_sources.gypi
index 97b2582..869e304 100644
--- a/sdk/lib/vmservice/vmservice_sources.gypi
+++ b/sdk/lib/vmservice/vmservice_sources.gypi
@@ -8,6 +8,7 @@
   'sources': [
     'vmservice.dart',
     # The above file needs to be first as it imports required libraries.
+    'asset.dart',
     'client.dart',
     'constants.dart',
     'running_isolate.dart',
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index 34838d5..433459d 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -103,6 +103,8 @@
    *
    * [oldVersion] should match the database's current [version] exactly.
    *
+   * See also:
+   *
    * * [Database.changeVersion](http://www.w3.org/TR/webdatabase/#dom-database-changeversion) from W3C.
    */
   @DomName('Database.changeVersion')
diff --git a/site/try/build_try.gyp b/site/try/build_try.gyp
index ae1125b..c421c85 100644
--- a/site/try/build_try.gyp
+++ b/site/try/build_try.gyp
@@ -33,10 +33,6 @@
           'dart-iphone5.png', # iPhone 5 splash screen.
           'dart-icon-196px.png', # Android icon.
           'try-dart-screenshot.png', # Google+ screen shot.
-
-          '../../third_party/font-awesome/font-awesome-4.0.3/'
-          'fonts/fontawesome-webfont.woff',
-
           'favicon.ico',
 
           '<(SHARED_INTERMEDIATE_DIR)/leap.dart.js',
diff --git a/site/try/create_manifest.sh b/site/try/create_manifest.sh
index c445833..0f145ac 100644
--- a/site/try/create_manifest.sh
+++ b/site/try/create_manifest.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/site/try/index.html b/site/try/index.html
index 5e05395..9b318d2 100644
--- a/site/try/index.html
+++ b/site/try/index.html
@@ -14,7 +14,7 @@
 
 See: http://www.google.com/fonts#UsePlace:use/Collection:Open+Sans:400,600,700,800,300
 -->
-<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
+
 <link href='//fonts.googleapis.com/css?family=Open+Sans:400,600,700,800,300' rel='stylesheet' type='text/css'>
 <link rel="stylesheet" type="text/css" href="dartlang-style.css">
 <link rel="alternate stylesheet" type="text/css" href="line_numbers.css" title="line_numbers">
@@ -211,7 +211,7 @@
 <a class="brand" href="//www.dartlang.org/" title="Dart Homepage" target="_blank">
 <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAMAAACeyVWkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJxQTFRFAAAAAIvMdsvDAIvMdsvDAIvMdsvDLaTJAIvMOqnHdsvDAIvMdsvDAIvMKaLJdsvDAIvMAIvMdsvDAIvMdsvDdsvDAIvMAIvMAZnFdsvDAILHAIPHAITIAIXJAIfKAIjKAIrLAIrMAIvMAJXHAJjFC5i/I6HENr2yOb6zPr+0TsK4UsO5WbnEWcW8Xsa9Yse+Zsi/asjAc8rCdsvDdt4SRQAAABp0Uk5TABAQICAwMFBgYGBwcICAgI+vr7+/z9/v7+97IXGnAAAAqUlEQVQYV13QxxaCQBBE0VZkjBgAGVEBaVEUM/P//yaTGg5vV3dZANTCZ9BvFAoR93kVC9FnthW6uIPTJ7UkdHaXvS2LXKNBURInyDXPsShbzjU7XCpxhooDVGo5QcQAJmjUco64AY/UcIrowYCTaj5KBZeTaj5JBTc6l11OlQKMf497y1ahefFb3TQfcqtM/fipJF/X9gnDon6/ah/aDDfNOgosNA2b8QdGciZlh/U93AAAAABJRU5ErkJggg==" alt="Dart">
 </a>
-<ul class="nav pull-right"><li><a href="https://code.google.com/p/dart/issues/entry?template=Try+Dart+Bug" target="_blank"><i class="fa fa-bug"></i></a></li><li><a href="#" id="settings"><i class="icon-cog"></i></a></li></ul>
+<ul class="nav pull-right"><li><a href="https://code.google.com/p/dart/issues/entry?template=Try+Dart+Bug" target="_blank"><i></i></a></li><li><a href="#" id="settings"><i class="icon-cog"></i></a></li></ul>
 
 <ul class="nav hidden-phone">
 <li class="active"><a>Try Dart!</a></li>
diff --git a/site/try/poi/poi.dart b/site/try/poi/poi.dart
index b9f7753..be98153 100644
--- a/site/try/poi/poi.dart
+++ b/site/try/poi/poi.dart
@@ -392,8 +392,7 @@
     api.DiagnosticHandler handler) {
   Stopwatch sw = new Stopwatch()..start();
   Uri libraryRoot = Uri.base.resolve('sdk/');
-  Uri packageRoot = Uri.base.resolveUri(
-      new Uri.file('${io.Platform.packageRoot}/'));
+  Uri packageRoot = Uri.base.resolve(io.Platform.packageRoot);
 
   var options = [
       '--analyze-main',
diff --git a/tests/README b/tests/README
index a9e3bb6..bbc3ee4 100644
--- a/tests/README
+++ b/tests/README
@@ -39,5 +39,5 @@
   int x = "not an int"; /// 01: static type warning
   ...
 
-as part of a test will only pass the "--compiler dartanalyzer" test if
+as part of a test will only pass the "--compiler dart2analyzer" test if
 the assignment generates a static type warning.
diff --git a/tests/benchmark_smoke/benchmark_smoke.status b/tests/benchmark_smoke/benchmark_smoke.status
index d3fe9a3..a83fd89 100644
--- a/tests/benchmark_smoke/benchmark_smoke.status
+++ b/tests/benchmark_smoke/benchmark_smoke.status
@@ -2,7 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $runtime == vm ]
+[ ($runtime == vm || $runtime == dart_precompiled) ]
 *: Skip
 
 [ $compiler == dart2js && $runtime == none ]
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
deleted file mode 100644
index c11877e..0000000
--- a/tests/co19/co19-analyzer.status
+++ /dev/null
@@ -1,294 +0,0 @@
-# Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-[ $compiler == dartanalyzer ]
-
-WebPlatformTest/html/semantics/forms/the-textarea-element/textarea-type_t01: fail
-LayoutTests/fast/forms/checkValidity-001_t01: fail
-
-# TBF: infinite look: class A {const A();final m = const A();}
-Language/12_Expressions/01_Constants_A17_t03: fail
-
-# TBF: when we override "foo([x = 0]) {}" with "foo([x]) {}" we should report warning - different default value
-Language/07_Classes/1_Instance_Methods_A04_t02: MissingStaticWarning
-Language/07_Classes/4_Abstract_Instance_Members_A07_t04: MissingStaticWarning
-
-# TBF: Static members should not be accessible via subclasses.
-Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A01_t05: MissingStaticWarning
-
-# co19 issue #442, undefined name "Expect"
-Language/15_Types/4_Interface_Types_A08_t03: fail, OK
-
-# co19 issue #438, Static variables are initialized lazily, need not be constants
-Language/12_Expressions/01_Constants_A16_t01: fail, OK
-Language/12_Expressions/01_Constants_A16_t02: fail, OK
-
-# co19 issue #543: invocation of a non-function
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
-
-# co19 issue #564: URI can be any number adjacent string literals
-Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail, OK
-Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail, OK
-
-# co19 issue #615: Expect import missing
-LibTest/collection/LinkedList/LinkedList_A01_t01: Fail, OK
-
-LibTest/isolate/IsolateStream/any_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/contains_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/first_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/first_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/first_A02_t02: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/isBroadcast_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/isBroadcast_A01_t02: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/isEmpty_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/last_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/last_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/length_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/single_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/single_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/receive_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/receive_A01_t03: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/toSendPort_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/toSendPort_A01_t03: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/call_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t04: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t03: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t05: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t06: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A03_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A03_t02: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/any_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/contains_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/receive_A01_t02: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/toSendPort_A01_t02: Fail # co19-roll r706: Please triage this failure.
-
-# co19 issue 642, The argument type 'int' cannot be assigned to the parameter type 'Iterable'
-LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: Fail, OK
-LibTest/collection/ListQueue/ListQueue_class_A01_t01: Fail, OK
-LibTest/collection/Queue/Queue_class_A01_t01: Fail, OK
-
-
-Language/12_Expressions/15_Method_Invocation/2_Cascaded_Invocation_A01_t19: MissingStaticWarning
-Language/12_Expressions/29_Assignable_Expressions_A01_t09: MissingStaticWarning
-Language/13_Statements/06_For/1_For_Loop_A01_t07: MissingStaticWarning
-Language/13_Statements/06_For/1_For_Loop_A01_t08: MissingStaticWarning
-Language/13_Statements/09_Switch_A10_t03: MissingStaticWarning
-Language/13_Statements/15_Assert_A04_t04: MissingStaticWarning
-
-Language/05_Variables/05_Variables_A05_t04: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t05: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t06: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t07: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t01: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t02: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t03: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
-
-Language/07_Classes/10_Superinterfaces_A07_t05: StaticWarning # co19-roll r667: Please triage this failure
-LibTest/convert/JsonEncoder/JsonEncoder_A01_t01: StaticWarning # co19-roll r667: Please triage this failure
-
-# co19 issue 656
-LibTest/typed_data/Float32x4/equal_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/notEqual_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/greaterThan_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/greaterThanOrEqual_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/lessThan_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/lessThanOrEqual_A01_t01: Skip # co19 issue 656
-
-WebPlatformTest/custom-elements/*: Pass, StaticWarning # Issue 18095.
-
-# co19 roll to r706: Please triage all these issues.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t03: StaticWarning # co19-roll r706: Please triage this failure.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t04: StaticWarning # co19-roll r706: Please triage this failure.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t05: StaticWarning # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A02_t04: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A04_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/4_Scripts_A01_t16: CompileTimeError # co19-roll r706: Please triage this failure.
-LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/dom/DOMImplementation/createDocumentType-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/dom/Element/scrollWidth_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/html/article-element_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/html/aside-element_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/html/imports/import-events_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-LayoutTests/fast/html/text-field-input-types_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Document/adoptNode_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Document/childNodes_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Document/importNode_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Document/securityPolicy_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/HttpRequest/responseText_A01_t02: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/HttpRequest/responseType_A01_t03: CompileTimeError # co19-roll r706: Please triage this failure.
-LibTest/html/IFrameElement/attributeChanged_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/IFrameElement/contentWindow_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/IFrameElement/enteredView_A01_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-LibTest/html/IFrameElement/getNamespacedAttributes_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/document_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/moveBy_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/moveTo_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/moveTo_A02_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/postMessage_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/postMessage_A01_t02: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/requestFileSystem_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/requestFileSystem_A01_t02: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/requestFileSystem_A02_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/resizeBy_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/resizeTo_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/sendPort_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/math/Point/operator_addition_A02_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/math/Point/operator_mult_A03_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/math/Point/operator_subtraction_A02_t01: StaticWarning # co19-roll r706: Please triage this failure.
-WebPlatformTest/dom/events/event_constants/constants_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-
-# co19-roll r722
-LayoutTests/fast/dom/HTMLAnchorElement/anchor-ismap-crash_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-rebase_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLBaseElement/href-attribute-resolves-with-respect-to-document_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/inert-does-not-match-disabled-selector_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDocument/clone-node_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLInputElement/size-attribute_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLabelElement/label-control_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/IFrameElement/outerHtml_setter_A01_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/Node/childNodes_A01_t02: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/Node/contains_A01_t02: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/Node/dispatchEvent_A01_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/Node/nodes_A01_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/isURLAttribute_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/script-async-attr_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: StaticWarning
-LayoutTests/fast/dom/HTMLTableElement/createCaption_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTableElement/insert-row_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTemplateElement/inertContents_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTemplateElement/no-form-association_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/clear-transient-without-delivery_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/disconnect-cancel-pending_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/document-fragment-insertion_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/mutation-record-constructor_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/observe-exceptions_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/NodeList/nodelist-reachable_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/missing-arguments_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/surroundContents-check-boundary-points_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/collections/emptyName_A01_t03: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createDocument_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: CompileTimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElement-namespace_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElement_t01: CompileTimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: CompileTimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-appendChild_t02: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-contains_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-isEqualNode_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-parentNode_t01: StaticWarning # co19-roll r722: Please triage this failure.
-
-# co19-roll r738
-Language/07_Classes/4_Abstract_Instance_Members_A07_t02: MissingStaticWarning # co19-roll r738: Please triage this failure.
-Language/07_Classes/07_Classes_A03_t06: MissingStaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/removed-stylesheet-rule-deleted-parent-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/TreeWalker/TreeWalker-basic_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/atob-btoa_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/replaceable_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-scroll-arguments_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/characterdata-api-arguments_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-cached-import-rule_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-insert-import-rule-twice_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-insert-import-rule_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-mediarule-deleteRule-update_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-mediarule-functions_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-mediarule-insertRule-update_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-rule-functions_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/destroy-selected-radio-button-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/icon-url-change_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/icon-url-list_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/implementation-api-args_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/javascript-backslash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/location-missing-arguments_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/option-properties_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/remove-named-attribute-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/content-pseudo-element-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/content-pseudo-element-relative-selector-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/host-context-pseudo-class-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/host-pseudo-class-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/Event.bubbles.false_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-text/load-text-plain_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-getter_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-setter_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.head_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t07: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-delete_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-get_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/the-audio-element/audio_constructor_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-datalist-element/datalistelement_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-datalist-element/datalistoptions_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-fieldset-element/disabled_t01: StaticWarning # co19-roll r738: Please triage this failure.
-
-# co19-roll r761
-LayoutTests/fast/animation/request-animation-frame-missing-arguments_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/backgrounds/001_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: StaticWarning # Issue 20939
-LayoutTests/fast/canvas/canvas-createImageBitmap-animated_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/webgl-specific_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/dom/text-api-arguments_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/html/imports/import-events_t01: StaticWarning # co19-roll r761: Please triage this failure.
-
-# co19-roll r786
-LayoutTests/fast/events/initkeyboardevent-crash_t01: StaticWarning # co19-roll r786: Please triage this failure.
-
-# co19-roll r801
-LayoutTests/fast/html/select-dropdown-consistent-background-color_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/boundingBox-with-continuation_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/about-blank-hash-kept_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/hashchange-event-properties_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/media-query-list-syntax_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-append-delete_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-color-index_t02: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-js-media-except_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-js-media-except_t02: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-parsing_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/ruby/after-doesnt-crash_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t02: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t01: StaticWarning # co19-roll r801: Please triage this failure.
-
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: StaticWarning # co19 issue 703
-WebPlatformTest/dom/Node-replaceChild_t01: CompileTimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/email_t02: StaticWarning # co19 issue 701
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: MissingCompileTimeError # Issue 22010
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: MissingCompileTimeError # Issue 22010
-
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index aa341d6..3c67e8e 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -6,29 +6,25 @@
 
 WebPlatformTest/html/semantics/forms/the-textarea-element/textarea-type_t01: fail
 LayoutTests/fast/forms/checkValidity-001_t01: fail
-Language/12_Expressions/29_Assignable_Expressions_A01_t08: StaticWarning
-Language/14_Libraries_and_Scripts/3_Parts_A03_t11: fail, pass # Issue 23595
+Language/Expressions/Assignable_Expressions/syntax_t08: StaticWarning
+Language/Libraries_and_Scripts/Parts/compilation_t15: fail, pass # Issue 23595
 
 # TBF: Static members should not be accessible via subclasses.
-Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A01_t05: MissingStaticWarning
-
-# TBF: noSuchMethod can now be inherited
-Language/07_Classes/4_Abstract_Instance_Members_A02_t03: fail, OK
-Language/07_Classes/4_Abstract_Instance_Members_A02_t04: fail, OK
+Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t05: MissingStaticWarning
 
 # co19 issue #442, undefined name "Expect"
-Language/15_Types/4_Interface_Types_A08_t03: fail, OK
+Language/Types/Interface_Types/subtype_t12: fail, OK
 
 # co19 issue #438, Static variables are initialized lazily, need not be constants
-Language/12_Expressions/01_Constants_A16_t01: fail, OK
-Language/12_Expressions/01_Constants_A16_t02: fail, OK
+Language/Expressions/Constants/exception_t01: fail, OK
+Language/Expressions/Constants/exception_t02: fail, OK
 
 # co19 issue #543: invocation of a non-function
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
+Language/Expressions/Function_Invocation/Function_Expression_Invocation/static_type_t02: fail, OK
 
 # co19 issue #564: URI can be any number adjacent string literals
-Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail, OK
-Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail, OK
+Language/Libraries_and_Scripts/URIs/syntax_t14: fail, OK
+Language/Libraries_and_Scripts/URIs/syntax_t15: fail, OK
 
 # co19 issue #615: Expect import missing
 LibTest/collection/LinkedList/LinkedList_A01_t01: Fail, OK
@@ -69,23 +65,23 @@
 LibTest/collection/Queue/Queue_class_A01_t01: Fail, OK
 
 
-Language/12_Expressions/15_Method_Invocation/2_Cascaded_Invocation_A01_t19: MissingStaticWarning
-Language/13_Statements/06_For/1_For_Loop_A01_t07: MissingStaticWarning
-Language/13_Statements/06_For/1_For_Loop_A01_t08: MissingStaticWarning
-Language/13_Statements/09_Switch_A10_t03: MissingStaticWarning
-Language/13_Statements/15_Assert_A04_t04: MissingStaticWarning
+Language/Expressions/Method_Invocation/Cascaded_Invocations/syntax_t19: MissingStaticWarning
+Language/Statements/For/For_Loop/execution_t07: MissingStaticWarning
+Language/Statements/For/For_Loop/execution_t08: MissingStaticWarning
+Language/Statements/Switch/last_statement_t03: MissingStaticWarning
+Language/Statements/Assert/type_t04: MissingStaticWarning
 
-Language/05_Variables/05_Variables_A05_t04: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t05: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t06: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A05_t07: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t01: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t02: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/05_Variables/05_Variables_A06_t03: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t04: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t05: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t06: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_t07: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_or_static_initialization_t01: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_or_static_initialization_t02: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Variables/final_or_static_initialization_t03: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
+Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
 
-Language/07_Classes/10_Superinterfaces_A07_t05: StaticWarning # co19-roll r667: Please triage this failure
+Language/Classes/Superinterfaces/no_member_t05: StaticWarning # co19-roll r667: Please triage this failure
 LibTest/convert/JsonEncoder/JsonEncoder_A01_t01: StaticWarning # co19-roll r667: Please triage this failure
 
 # co19 issue 656
@@ -99,12 +95,12 @@
 WebPlatformTest/custom-elements/*: Pass, StaticWarning # Issue 18095.
 
 # co19 roll to r706: Please triage all these issues.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t03: StaticWarning # co19-roll r706: Please triage this failure.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t04: StaticWarning # co19-roll r706: Please triage this failure.
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t05: StaticWarning # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A02_t04: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A04_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/14_Libraries_and_Scripts/4_Scripts_A01_t16: CompileTimeError # co19-roll r706: Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t03: StaticWarning # co19-roll r706: Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t04: StaticWarning # co19-roll r706: Please triage this failure.
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t05: StaticWarning # co19-roll r706: Please triage this failure.
+Language/Libraries_and_Scripts/Parts/compilation_t04: CompileTimeError # co19-roll r706: Please triage this failure.
+Language/Libraries_and_Scripts/Parts/static_warning_t01: CompileTimeError # co19-roll r706: Please triage this failure.
+Language/Libraries_and_Scripts/Scripts/syntax_t11: CompileTimeError # co19-roll r706: Please triage this failure.
 LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
 LayoutTests/fast/dom/DOMImplementation/createDocumentType-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: StaticWarning # co19-roll r706: Please triage this failure.
@@ -190,7 +186,7 @@
 WebPlatformTest/dom/nodes/Node-parentNode_t01: StaticWarning # co19-roll r722: Please triage this failure.
 
 # co19-roll r738
-Language/07_Classes/07_Classes_A03_t06: MissingStaticWarning # co19-roll r738: Please triage this failure.
+Language/Classes/Classes/method_definition_t06: MissingStaticWarning # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
@@ -286,34 +282,119 @@
 LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: StaticWarning # co19 issue 703
 WebPlatformTest/dom/Node-replaceChild_t01: CompileTimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/html/semantics/forms/the-input-element/email_t02: StaticWarning # co19 issue 701
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: MissingCompileTimeError # Issue 22010
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: MissingCompileTimeError # Issue 22010
-Language/15_Types/4_Interface_Types_A10_t03: StaticWarning # co19 issue 745
-Language/15_Types/4_Interface_Types_A10_t07: StaticWarning # co19 issue 745
-Language/15_Types/4_Interface_Types_A10_t09: StaticWarning # co19 issue 745
-Language/13_Statements/15_Assert_A04_t07: StaticWarning # Issue 23663
-Language/13_Statements/15_Assert_A03_t08: StaticWarning # Issue 23663
+Language/Expressions/Instance_Creation/Const/abstract_class_t01: MissingCompileTimeError # Issue 22010
+Language/Expressions/Instance_Creation/Const/abstract_class_t03: MissingCompileTimeError # Issue 22010
+Language/Types/Interface_Types/subtype_t19: StaticWarning # co19 issue 745
+Language/Types/Interface_Types/subtype_t22: StaticWarning # co19 issue 745
+Language/Types/Interface_Types/subtype_t24: StaticWarning # co19 issue 745
+Language/Statements/Assert/type_t07: StaticWarning # Issue 23663
+Language/Statements/Assert/execution_t08: StaticWarning # Issue 23663
 
 # isProtocolHandlerRegistered and unregisterProtocolHandler don't exist
-LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: StaticWarning
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: StaticWarning
-LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: StaticWarning
+LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: StaticWarning # Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: StaticWarning # Please triage this failure.
+LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: StaticWarning # Please triage this failure.
 
 # Missing concrete implementation of setter 'XPathNSResolver.blink_jsObject' and getter 'XPathNSResolver.blink_jsObject'
 # TODO(terry): Dartium only because of implements instead of extends consider fixing by making blink_jsObject private
 #              with private wrap_jso and unwrap_jso in each library that delegates to the public wrap/unwrap_jso.
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: StaticWarning
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: StaticWarning
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: StaticWarning
-LayoutTests/fast/xpath/attr-namespace_t01: StaticWarning
-LayoutTests/fast/xpath/attr-namespace_t02: StaticWarning
-LayoutTests/fast/xpath/node-name-case-sensitivity_t01: StaticWarning
-LayoutTests/fast/xpath/node-name-case-sensitivity_t02: StaticWarning
-LayoutTests/fast/xpath/py-dom-xpath/data_t01: StaticWarning
-LayoutTests/fast/svg/getbbox_t01: StaticWarning
+LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/attr-namespace_t01: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/attr-namespace_t02: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t01: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t02: StaticWarning # Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/data_t01: StaticWarning # Please triage this failure.
+LayoutTests/fast/svg/getbbox_t01: StaticWarning # Please triage this failure.
 
+# co19 roll to Sep 29 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0)
+Language/Classes/Abstract_Instance_Members/invocation_t03: MissingStaticWarning # Please triage this failure.
+Language/Classes/Abstract_Instance_Members/invocation_t04: MissingStaticWarning # Please triage this failure.
+Language/Classes/Getters/static_t01: StaticWarning # Please triage this failure.
+Language/Classes/Getters/type_object_t01: StaticWarning # Please triage this failure.
+Language/Classes/Getters/type_object_t02: StaticWarning # Please triage this failure.
+Language/Classes/Instance_Variables/definition_t03: StaticWarning # Please triage this failure.
+Language/Classes/Setters/syntax_t04: StaticWarning # Please triage this failure.
+Language/Classes/Setters/type_object_t01: StaticWarning # Please triage this failure.
+Language/Classes/Setters/type_object_t02: StaticWarning # Please triage this failure.
+Language/Classes/Static_Methods/same_name_method_and_setter_t01: MissingStaticWarning # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t01: StaticWarning # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t02: StaticWarning # Please triage this failure.
+Language/Classes/method_definition_t06: MissingStaticWarning # Please triage this failure.
+Language/Enums/declaration_equivalent_t03: StaticWarning # Please triage this failure.
+Language/Enums/declaration_equivalent_t05: StaticWarning # Please triage this failure.
+Language/Enums/declaration_equivalent_t08: StaticWarning # Please triage this failure.
+Language/Expressions/Lookup/Method_Lookup/superclass_t07: StaticWarning # Please triage this failure.
+Language/Expressions/Lookup/Method_Lookup/superclass_t08: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t05: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t06: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t07: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t08: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t04: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t05: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t01: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t02: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t03: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t04: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t05: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t06: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t07: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/expression_evaluation_t07: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/no_such_method_t01: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/proxy_annotation_t05: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/proxy_annotation_t06: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/proxy_annotation_t07: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/proxy_annotation_t08: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/deferred_type_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t02: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t03: CompileTimeError # Please triage this failure.
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/static_type_t01: StaticWarning # Please triage this failure.
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/static_type_t02: StaticWarning # Please triage this failure.
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t03: StaticWarning # Please triage this failure.
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t07: StaticWarning # Please triage this failure.
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure.
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/Imports/namespace_changes_t10: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t04: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t05: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t09: CompileTimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t10: CompileTimeError # Please triage this failure.
+Language/Mixins/Mixin_Application/abstract_t01: StaticWarning # Please triage this failure.
+Language/Mixins/Mixin_Application/abstract_t02: StaticWarning # Please triage this failure.
+Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure.
+Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure.
+Language/Mixins/Mixin_Application/warning_t01: MissingStaticWarning # Please triage this failure.
+Language/Mixins/Mixin_Application/warning_t02: MissingStaticWarning # Please triage this failure.
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index c28d8d8..81419e9 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -14,6 +14,12 @@
 [ $runtime == vm || $runtime != vm ]
 # Tests that fail everywhere, including the analyzer.
 
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: Pass, Fail, OK # co19 issue 18
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: Pass, Fail, OK # co19 issue 18
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: Pass, Fail, OK # co19 issue 18
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t01: Pass, Fail, OK # co19 issue 18
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t02: Pass, Fail, OK # co19 issue 18
+
 # Super is now allowed in mixins and mixins may now extend a subclass of Object.
 Language/09_Mixins/09_Mixins_A01_t01: Skip # co19 issue 9.
 Language/09_Mixins/09_Mixins_A03_t01: Skip # co19 issue 9.
@@ -22,7 +28,6 @@
 Language/12_Expressions/30_Identifier_Reference_A01_t03: Skip
 
 LibTest/typed_data/ByteData/buffer_A01_t01: Fail # co19 r736 bug - sent comment.
-LayoutTests/fast/mediastream/getusermedia_t01: Fail # co19 issue 738.
 
 LibTest/core/RegExp/firstMatch_A01_t01: Fail # co19 issue 742
 
@@ -33,7 +38,7 @@
 # These tests are broken in both Javascript and Dart (co19 folks contacted to fix).
 WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-004_t01: Skip # Issue 21115
 
-[ $compiler != dartanalyzer && $compiler != dart2analyzer ]
+[ $compiler != dart2analyzer ]
 # Tests that fail on every runtime, but not on the analyzer.
 
 LibTest/async/Future/Future.error_A01_t01: RuntimeError # co19 issue 712
@@ -43,16 +48,16 @@
 
 LibTest/core/Symbol/Symbol_A01_t04: RuntimeError # co19-roll r607: Please triage this failure
 
-Language/07_Classes/07_Classes_A13_t01: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
-Language/07_Classes/07_Classes_A13_t04: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
-Language/07_Classes/07_Classes_A13_t07: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
+Language/Classes/same_name_type_variable_t01: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
+Language/Classes/same_name_type_variable_t04: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
+Language/Classes/same_name_type_variable_t07: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
 
 LibTest/math/acos_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/asin_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/atan_A01_t01: PASS, FAIL, OK # co19 issue 44
 
 LibTest/math/cos_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/tan_A01_t01: PASS, FAIL, OK  # co19 issue 44
+LibTest/math/tan_A01_t01: PASS, FAIL, OK # co19 issue 44
 
 LibTest/core/Expando/Expando_A03_t01: RuntimeError # Issue 17735
 LibTest/core/Expando/Expando_A03_t03: RuntimeError # Issue 17735
@@ -94,7 +99,7 @@
 
 ### CHECKED MODE FAILURES ###
 
-[ $compiler != dartanalyzer && $compiler != dart2analyzer && $checked ]
+[ $compiler != dart2analyzer && $checked ]
 LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 LibTest/collection/LinkedList/lastWhere_A02_t01: RuntimeError # co19 issue 737
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index ee0adbe..a5781a6 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -3,48 +3,138 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t02: RuntimeError # Issue 1533 (int/double related)
-Language/03_Overview/1_Scoping_A02_t05: RuntimeError # co19 issue 3
-Language/03_Overview/1_Scoping_A02_t06: RuntimeError # co19 issue 3
-Language/03_Overview/1_Scoping_A02_t28: fail # Issue 21092 and co19 issue 713
-Language/05_Variables/05_Variables_A05_t01: fail # Issue 21093
-Language/05_Variables/05_Variables_A05_t02: fail # Issue 21093
-Language/05_Variables/05_Variables_A11_t01: MissingCompileTimeError # Issue 21050
-Language/06_Functions/4_External_Functions_A01_t01: CompileTimeError, OK # Issue 5021
-Language/07_Classes/07_Classes_A13_t02: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t03: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t05: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t06: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t08: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/07_Classes_A13_t09: Fail # Missing CT error on member with same name a type parameter
-Language/07_Classes/1_Instance_Methods_A07_t01: fail # Issue 21201
-Language/07_Classes/3_Setters_A04_t01: CompileTimeError # Issue 5023
-Language/07_Classes/3_Setters_A04_t02: CompileTimeError # Issue 5023
-Language/07_Classes/3_Setters_A04_t03: RuntimeError # Issue 5023
-Language/07_Classes/3_Setters_A04_t07: CompileTimeError # Issue 5023
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail # Issue 13363
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: RuntimeError # compiler cancelled: cannot resolve type T
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: RuntimeError, OK # co19 issue 258
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail # Issue 13363
-Language/10_Generics/09_Generics_A01_t17: fail # Issue 21203
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A02_t02: fail # Issue 11551, also related to issue 563, 18738
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A06_t01: fail # Issue 11551, also related to issue 563, 18738
-Language/12_Expressions/01_Constants_A03_t01: CompileTimeError # Issue 13652
-Language/12_Expressions/03_Numbers_A01_t06: fail # Issue 21098
-Language/12_Expressions/03_Numbers_A01_t09: fail # Issue 21098
-Language/12_Expressions/07_Maps_A11_t01: CompileTimeError # Maybe ok. Issue 17207
-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/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
-Language/14_Libraries_and_Scripts/1_Imports_A03_t08: fail # Issue 21171
-Language/14_Libraries_and_Scripts/1_Imports_A03_t28: fail # Issue 21171
-Language/15_Types/4_Interface_Types_A11_t01: crash # Issue 21174
-Language/15_Types/4_Interface_Types_A11_t02: crash # Issue 21174
-Language/15_Types/4_Interface_Types_A11_t04: fail # Issue 14654
-Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: MissingCompileTimeError # Checks that other Unicode whitespaces are not allowed:  check NO-BREAK SPACE (U+00A0)
-Language/16_Reference/1_Lexical_Rules_A02_t06: MissingCompileTimeError # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
+Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError # compiler cancelled: cannot resolve type T
+Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError, OK # co19 issue 258
+Language/Classes/Constructors/Generative_Constructors/execution_of_an_initializer_t02: fail # Issue 13363
+Language/Classes/Constructors/Generative_Constructors/initializing_formals_execution_t02: fail # Issue 13363
+Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Instance_Methods/same_name_setter_t01: fail # Issue 21201
+Language/Classes/Setters/name_t01: CompileTimeError # Issue 5023
+Language/Classes/Setters/name_t02: CompileTimeError # Issue 5023
+Language/Classes/Setters/name_t03: RuntimeError # Issue 5023
+Language/Classes/Setters/name_t07: CompileTimeError # Issue 5023
+Language/Classes/Setters/syntax_t04: RuntimeError # Please triage this failure
+Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Static_Methods/same_name_method_and_setter_t01: CompileTimeError # Please triage this failure
+Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Static_Methods/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Superclasses/wrong_superclass_t04: MissingCompileTimeError # Please triage this failure
+Language/Classes/Superclasses/wrong_superclass_t07: MissingCompileTimeError # Please triage this failure
+Language/Classes/Superclasses/wrong_superclass_t08: MissingCompileTimeError # Please triage this failure
+Language/Classes/Superinterfaces/wrong_type_t04: MissingCompileTimeError # Please triage this failure
+Language/Classes/Superinterfaces/wrong_type_t05: MissingCompileTimeError # Please triage this failure
+Language/Classes/same_name_type_variable_t02: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t03: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t05: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t06: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t08: Fail # Missing CT error on member with same name a type parameter
+Language/Classes/same_name_type_variable_t09: Fail # Missing CT error on member with same name a type parameter
+Language/Enums/restrictions_t01: MissingCompileTimeError # Please triage this failure
+Language/Enums/restrictions_t02: MissingCompileTimeError # Please triage this failure
+Language/Enums/restrictions_t05: MissingCompileTimeError # Please triage this failure
+Language/Enums/restrictions_t06: MissingCompileTimeError # Please triage this failure
+Language/Enums/restrictions_t07: MissingCompileTimeError # Please triage this failure
+Language/Enums/syntax_t02: MissingCompileTimeError # Please triage this failure
+Language/Errors_and_Warnings/compile_error_t06: MissingCompileTimeError # Please triage this failure
+Language/Errors_and_Warnings/compile_error_t07: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Identifier_Reference/syntax_built_in_t01: fail # Issue 21154
+Language/Expressions/Maps/static_type_dynamic_t01: CompileTimeError # Maybe ok. Issue 17207
+Language/Expressions/Numbers/syntax_t06: fail # Issue 21098
+Language/Expressions/Numbers/syntax_t09: fail # Issue 21098
+Language/Expressions/Object_Identity/Object_Identity/constant_objects_t01: fail # Issue 11551, also related to issue 563, 18738
+Language/Expressions/Object_Identity/Object_Identity/double_t02: fail # Issue 11551, also related to issue 563, 18738
+Language/Expressions/Object_Identity/constant_objects_t01: RuntimeError # Please triage this failure
+Language/Expressions/Object_Identity/double_t02: RuntimeError # Please triage this failure
+Language/Expressions/Object_Identity/object_t02: RuntimeError # Issue 1533 (int/double related)
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t06: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t08: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t01: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t02: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t03: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t04: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t05: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t06: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t07: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/expression_evaluation_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/no_such_method_t01: RuntimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/deferred_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: RuntimeError # Please triage this failure
+Language/Functions/External_Functions/not_connected_to_a_body_t01: CompileTimeError, OK # Issue 5021
+Language/Generics/syntax_t17: fail # Issue 21203
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/Imports/namespace_changes_t10: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t04: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t05: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t09: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t10: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t14: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t15: CompileTimeError # Please triage this failure
+Language/Metadata/before_export_t01: RuntimeError # Please triage this failure
+Language/Metadata/before_import_t01: RuntimeError # Please triage this failure
+Language/Metadata/before_library_t01: RuntimeError # Please triage this failure
+Language/Metadata/before_param_t09: RuntimeError # Please triage this failure
+Language/Metadata/before_type_param_t01: CompileTimeError # Please triage this failure
+Language/Metadata/before_typedef_t01: RuntimeError # Please triage this failure
+Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure
+Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_mixin_type_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_mixin_type_t02: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_mixin_type_t03: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_mixin_type_t04: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_type_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/wrong_type_t02: MissingCompileTimeError # Please triage this failure
+Language/Mixins/declaring_constructor_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/deferred_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/not_object_superclass_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/reference_to_super_t01: MissingCompileTimeError # Please triage this failure
+Language/Reference/Lexical_Rules/Reserved_Words/whitespace_t04: MissingCompileTimeError # Checks that other Unicode whitespaces are not allowed:  check NO-BREAK SPACE (U+00A0)
+Language/Reference/Lexical_Rules/whitespace_t06: MissingCompileTimeError # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
+Language/Statements/Local_Function_Declaration/reference_before_declaration_t01: MissingCompileTimeError # Issue 21050
+Language/Statements/Local_Function_Declaration/reference_before_declaration_t03: MissingCompileTimeError # Issue 21050
+Language/Types/Interface_Types/subtype_t27: Skip # Times out or crashes. Issue 21174
+Language/Types/Interface_Types/subtype_t30: fail # Issue 14654
+Language/Types/Interface_Types/subtype_t28: Pass, Fail, Crash # Stack overflow. Issue 25282
+Language/Variables/final_t01: fail # Issue 21093
+Language/Variables/final_t02: fail # Issue 21093
+Language/Variables/local_variable_t01: MissingCompileTimeError # Issue 21050
+LayoutTests/fast/dom/css-innerHTML_t01: SkipByDesign # Test is incorrect.
+LayoutTests/fast/loader/loadInProgress_t01: Skip # Issue 23466
 LibTest/collection/LinkedList/add_A01_t01: Pass, Slow # Slow tests that needs extra time to finish.
 LibTest/collection/ListBase/ListBase_class_A01_t01: RuntimeError # Please triage this failure
 LibTest/collection/ListMixin/ListMixin_class_A01_t01: RuntimeError # Please triage this failure
@@ -198,19 +288,23 @@
 LibTest/typed_data/Uint8List/Uint8List_A02_t01: fail # co19-roll r576: Please triage this failure
 Utils/tests/Expect/identical_A01_t01: fail # co19-roll r546: Please triage this failure
 WebPlatformTest/Utils/test/testFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElement_t01: CompileTimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: CompileTimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-createElement_t01: CompileTimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: CompileTimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Pass, Slow
-LayoutTests/fast/loader/loadInProgress_t01: Skip # Issue 23466
-LayoutTests/fast/dom/css-innerHTML_t01: SkipByDesign # Test is incorrect.
 
 [ $compiler == dart2js && $checked ]
-Language/13_Statements/09_Switch_A05_t01: Fail # Missing type check in switch expression
-Language/13_Statements/09_Switch_A09_t01: RuntimeError # Issue 16089
-Language/15_Types/1_Static_Types_A03_t01: RuntimeError # Issue 21089
-Language/15_Types/2_Dynamic_Type_System_A01_t02: RuntimeError # Issue 21088
-Language/15_Types/8_Parameterized_Types_A03_t07: RuntimeError # Issue 21088
+Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t05: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t06: RuntimeError # Please triage this failure
+Language/Statements/Switch/execution_t01: Fail # Missing type check in switch expression
+Language/Statements/Switch/type_t01: RuntimeError # Issue 16089
+Language/Types/Static_Types/malformed_type_t01: RuntimeError # Issue 21089
+Language/Types/Dynamic_Type_System/malbounded_type_error_t01: RuntimeError # Issue 21088
+Language/Types/Parameterized_Types/malbounded_t06: RuntimeError # Issue 21088
 LibTest/core/Map/Map_class_A01_t04: Slow, Pass
 LibTest/core/Uri/Uri_A06_t03: Slow, Pass
 LibTest/math/Point/operator_mult_A02_t01: RuntimeError # Issue 1533
@@ -322,6 +416,9 @@
 *: Skip
 
 [ $compiler == dart2js && $browser ]
+Language/Classes/deсlarations_t01: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t34: Skip # Times out. Please triage this failure.
+LayoutTests/fast/mediastream/getusermedia_t01: Pass, RuntimeError, Timeout # Please triage this failure.
 LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/HTMLButtonElement/change-type_t01: Skip # Test reloads itself. Issue 18558.
@@ -331,7 +428,7 @@
 LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/shadow/form-in-shadow_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/form-submission-create-crash_t01.dart: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/form-submission-create-crash_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-input-2_t01: Skip # Test reloads itself. Issue 18558.
@@ -341,7 +438,6 @@
 LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-nonhtml-ancestor_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/submit-nil-value-field-assert_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/textarea-submit-crash_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/innerHTML/innerHTML-svg-write_t01: Fail # Test uses foreignObject tag, which sanitizer removes. co19 issue #746
 LibTest/html/IFrameElement/appendHtml_A01_t01: Pass, RuntimeError # Issue 23462
 LibTest/html/IFrameElement/appendHtml_A01_t02: Pass, RuntimeError # Issue 23462
 #
@@ -372,16 +468,8 @@
 LayoutTests/fast/multicol/vertical-lr/break-properties_t01: RuntimeError
 LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError
 LayoutTests/fast/multicol/zeroColumnCount_t01: RuntimeError
-LayoutTests/fast/media/media-query-serialization_t01: RuntimeError
-LayoutTests/fast/media/mq-append-delete_t01: RuntimeError
-LayoutTests/fast/media/mq-color-index_t02: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t02: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t01: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t03: RuntimeError
-LayoutTests/fast/media/mq-js-update-media_t01: RuntimeError
 LayoutTests/fast/media/mq-parsing_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue.
 LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475
-LayoutTests/fast/loader/local-css-allowed-in-strict-mode_t01: RuntimeError
 LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # False pass on Safari
 LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError
 LayoutTests/fast/lists/item-not-in-list-line-wrapping_t01: RuntimeError
@@ -408,16 +496,12 @@
 LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError
 LayoutTests/fast/text/line-breaks-after-ideographic-comma-or-full-stop_t01: RuntimeError
 LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail
-LayoutTests/fast/text-autosizing/inline-width_t01: RuntimeError
-LayoutTests/fast/text-autosizing/text-removal_t01: RuntimeError
-LayoutTests/fast/text-autosizing/table-inline-width_t01: RuntimeError
 LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError
 LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError
 LayoutTests/fast/text/font-ligatures-linebreak_t01: Skip
 LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip
 LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError
 LayoutTests/fast/text/pre-wrap-trailing-tab_t01: RuntimeError
-LayoutTests/fast/text-autosizing/display-type-change-lineHeight_t01: RuntimeError
 LayoutTests/fast/url/trivial_t01: RuntimeError
 LayoutTests/fast/url/trivial-segments_t01: RuntimeError
 LayoutTests/fast/url/scheme_t01: RuntimeError
@@ -446,39 +530,18 @@
 LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Skip
 LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: Skip
 LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError
-LayoutTests/fast/table/table-size-integer-overflow_t01: RuntimeError
 LayoutTests/fast/table/table-sections-border-spacing_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout_t01: RuntimeError
 LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError
 LayoutTests/fast/table/resize-table-row_t01: RuntimeError
-LayoutTests/fast/table/resize-table-cell_t01: RuntimeError
-LayoutTests/fast/table/resize-table-binding-cell_t01: RuntimeError
 LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError
 LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError
 LayoutTests/fast/table/html-table-width-max-width-constrained_t01: Pass, RuntimeError
 LayoutTests/fast/table/fixed-table-layout-width-change_t01: Pass, RuntimeError # False passes on Firefox
-LayoutTests/fast/table/fixed-table-with-percent-width-inside-extra-large-div_t01: RuntimeError
 LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-length_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-number_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-length-invalid_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-angle_t01: RuntimeError
-LayoutTests/fast/svg/tabindex-focus_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-integer_t01: RuntimeError
-LayoutTests/fast/sub-pixel/shadows-computed-style_t01: RuntimeError
-LayoutTests/fast/sub-pixel/tiled-canvas-elements_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-list-inside_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-with-margin-in-container_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-percentage-widths_t01: RuntimeError
-LayoutTests/fast/sub-pixel/computedstylemargin_t01: RuntimeError
-LayoutTests/fast/sub-pixel/block-preferred-widths-with-sub-pixel-floats_t01: RuntimeError
-LayoutTests/fast/sub-pixel/auto-table-layout-should-avoid-text-wrapping_t01: RuntimeError
 LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError
 LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Fails on Safari, false pass on others
 LayoutTests/fast/selectors/style-sharing-last-child_t01: RuntimeError
 LayoutTests/fast/selectors/specificity-overflow_t01: RuntimeError
-LayoutTests/fast/scrolling/scroll-element-into-view_t01: RuntimeError
 LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError
 LayoutTests/fast/replaced/table-replaced-element_t01: RuntimeError
 LayoutTests/fast/replaced/table-percent-height-text-controls_t01: RuntimeError
@@ -491,7 +554,6 @@
 LayoutTests/fast/parser/stray-param_t01: RuntimeError
 LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError
 LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError
-LayoutTests/fast/overflow/height-during-simplified-layout_t01: RuntimeError
 LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError
 WebPlatformTest/html-imports/link-import-null_t01: RuntimeError
 WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError
@@ -518,7 +580,7 @@
 #
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
-Language/12_Expressions/05_Strings_A06_t01: Pass, Slow # Please triage this failure.
+Language/Expressions/Strings/escape_backspace_t01: Pass, Slow # Please triage this failure.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 22200.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 22200.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue 22200.
@@ -557,7 +619,10 @@
 LayoutTests/fast/animation/request-animation-frame-timestamps_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/animation/request-animation-frame-within-callback_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style_t01: RuntimeError # co19 issue 14
+LayoutTests/fast/backgrounds/multiple-backgrounds-computed-style_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/borders/border-width-percent_t01: RuntimeError # Issue 25155
 LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # Please triage this failure
@@ -676,6 +741,9 @@
 LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/background-serialize_t01: RuntimeError # https://github.com/dart-lang/co19/issues/14
+LayoutTests/fast/css/css-selector-text_t01: RuntimeError # co19 Issue 15
+LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Issue 23506
@@ -692,6 +760,8 @@
 LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/csstext-of-content-string_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/css/cursor-parsing_t01: RuntimeError # co19 issue 14
+LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/ex-unit-with-no-x-height_t01: Pass, RuntimeError # Please triage this failure
@@ -705,6 +775,8 @@
 LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-events_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-loadingdone_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/css/getComputedStyle/computed-style-border-image_t01: RuntimeError # co19 issue 14
+LayoutTests/fast/css/getComputedStyle/computed-style-cross-fade_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/getComputedStyle/computed-style-properties_t01: RuntimeError # Issue 23506
 LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # Please triage this failure
@@ -754,8 +826,7 @@
 LayoutTests/fast/css/transform-origin-parsing_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/word-break-user-modify-allowed-values_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last-inherited_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/url-with-multi-byte-unicode-escape_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-color_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-line_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-style_t01: RuntimeError # Please triage this failure
@@ -764,6 +835,7 @@
 LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/click-method-on-html-element_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/DOMException/XPathException_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # Please triage this failure
@@ -801,8 +873,10 @@
 LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # Issue 18010
 LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLObjectElement/form/test1_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # Please triage this failure
@@ -856,6 +930,7 @@
 LayoutTests/fast/dom/fragment-activation-focuses-target_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/getElementsByClassName/011_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/getElementsByClassName/dumpNodeList_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/getelementsbyname-invalidation-cache_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # Please triage this failure
@@ -863,6 +938,7 @@
 LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # API not supported.
 LayoutTests/fast/dom/navigatorcontentutils/register-protocol-handler_t01: Skip # API not supported.
 LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: Skip # API not supported.
+LayoutTests/fast/dom/object-plugin-hides-properties_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/option-properties_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # Please triage this failure
@@ -876,6 +952,7 @@
 LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/shadow-disable_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/dom/shadow/shadow-element-inactive_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: Pass, RuntimeError # Please triage this failure
@@ -885,6 +962,7 @@
 LayoutTests/fast/dynamic/crash-generated-quote_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dynamic/crash-generated-text_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dynamic/insertAdjacentElement_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dynamic/insertAdjacentHTML-allowed-parents_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dynamic/recursive-layout_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/encoding/css-charset-dom_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/events/add-event-without-document_t01: RuntimeError # Please triage this failure
@@ -932,13 +1010,16 @@
 LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/forms/button-baseline-and-collapsing_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/button/button-disabled-blur_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/forms/checkValidity-001_t01: RuntimeError # Issue 25155
 LayoutTests/fast/forms/clone-input-with-dirty-value_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/date/input-valueasdate-date_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/datetimelocal/input-valueasdate-datetimelocal_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/fieldset/fieldset-elements_t01: RuntimeError # Issue 25155
 LayoutTests/fast/forms/file/file-input-capture_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/forms/form-attribute_t01: RuntimeError # Issue 25155
 LayoutTests/fast/forms/input-appearance-elementFromPoint_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/input-inputmode_t01: RuntimeError # Please triage this failure
@@ -958,10 +1039,14 @@
 LayoutTests/fast/forms/select-clientheight-with-multiple-attr_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/select-max-length_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/setCustomValidity-existence_t01: RuntimeError # Issue 25155
 LayoutTests/fast/forms/setrangetext_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/submit-form-attributes_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/forms/textarea-paste-newline_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/forms/validationMessage_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/validity-property_t01: RuntimeError # Issue 25155
+LayoutTests/fast/forms/willvalidate_t01: RuntimeError # Issue 25155
 LayoutTests/fast/html/hidden-attr_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/html/imports/import-events_t01: RuntimeError # Please triage this failure
@@ -973,6 +1058,7 @@
 LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. Please triage this failure
@@ -982,6 +1068,8 @@
 LayoutTests/fast/loader/scroll-position-restored-on-back_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # co19 issue 14
+LayoutTests/fast/masking/parsing-clip-path-iri_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/masking/parsing-clip-path-shape_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/masking/parsing-mask_t01: RuntimeError # Please triage this failure
@@ -1023,6 +1111,7 @@
 LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left_t01: RuntimeError # Please triage this failure
@@ -1155,6 +1244,7 @@
 LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # Issue 16395
 LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Please triage this failure
+LibTest/html/Element/isTagSupported_A01_t01: RuntimeError # Issue 25155
 LibTest/html/Element/marginEdge_A01_t01: RuntimeError # Issue 16574
 LibTest/html/Element/mouseWheelEvent_A01_t01: Skip # Times out. Please triage this failure
 LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out. Please triage this failure
@@ -1162,6 +1252,7 @@
 LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # Issue 16574
 LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # Please triage this failure
 LibTest/html/Element/replaceWith_A01_t02: RuntimeError # Please triage this failure
+LibTest/html/Element/tagName_A01_t01: RuntimeError # Issue 25155
 LibTest/html/Element/transitionEndEvent_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/HttpRequest/getAllResponseHeaders_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/HttpRequest/getResponseHeader_A01_t01: RuntimeError # Please triage this failure
@@ -1232,6 +1323,12 @@
 WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/createElement_A02_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElement_A03_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElementNS_A03_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t02: RuntimeError # Issue 25155
 WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # Please triage this failure
 WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Skip # Times out. Please triage this failure
 WebPlatformTest/dom/events/type_A01_t01: RuntimeError # Please triage this failure
@@ -1279,7 +1376,6 @@
 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
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # Please triage this failure
@@ -1372,6 +1468,8 @@
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-005_t01: RuntimeError # Issue 25155
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-007_t01: RuntimeError # Issue 25155
 WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # Please triage this failure
 WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # Please triage this failure
 
@@ -1544,36 +1642,6 @@
 LayoutTests/fast/text/regional-indicator-symobls_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
 
-[ $compiler == dart2js && $runtime == chrome && $system == windows ]
-LayoutTests/fast/canvas/canvas-blend-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blend-solid_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-clipping_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-color-over-color_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-color-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-color-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-color-over-pattern_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-fill-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-global-alpha_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-color_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-pattern_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-image-over-color_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-image-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-image-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-image-over-pattern_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-color_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-pattern_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-shadow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-transforms_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-alpha_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-canvas_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-stroke-alpha_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError # Please triage this failure
-
 [ $compiler == dart2js && $runtime == chrome && $system != linux ]
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Issue 24398
 
@@ -1581,7 +1649,7 @@
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
 
 [ $compiler == dart2js && $runtime == ff ]
-Language/12_Expressions/28_Postfix_Expressions_A07_t02: Skip # Times out. Please triage this failure
+Language/Expressions/Postfix_Expressions/property_decrement_t02: Skip # Times out. Please triage this failure
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -1613,7 +1681,6 @@
 LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-composite-canvas_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-composite-image_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-css-crazy_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-currentColor_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is not implemented.
@@ -1654,7 +1721,6 @@
 LayoutTests/fast/canvas/canvas-toDataURL-crash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/crash-set-font_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/drawImage-with-negative-source-destination_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/drawImage-with-valid-image_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/rgba-parsing_t01: RuntimeError # Please triage this failure
@@ -2024,7 +2090,6 @@
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-host_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hostname_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-port_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-protocol_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-search_t01: RuntimeError # Please triage this failure
@@ -2410,7 +2475,6 @@
 LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/forms/button/button-disabled-blur_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/forms/button-baseline-and-collapsing_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/forms/change-form-element-document-crash_t01: RuntimeError # Dartium JSInterop failure, or else Firefox roll error. Issue 24409
 LayoutTests/fast/forms/checkValidity-001_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/checkValidity-002_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/checkValidity-004_t01: Pass, RuntimeError # Please triage this failure
@@ -3096,9 +3160,14 @@
 [ $compiler == dart2js && $runtime == ff && $system != windows ]
 LayoutTests/fast/canvas/canvas-resetTransform_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-setTransform_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/drawImage-with-negative-source-destination_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
 
+[ $compiler == dart2js && $runtime == ff && $system == linux]
+LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError # co19 issue 16
+
 [ $compiler == dart2js && $runtime == safari ]
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
@@ -5666,7 +5735,7 @@
 LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError, Pass # Issue 22752. Please triage this failure.
 
 [ $compiler == dart2js && $runtime == ie10 ]
-Language/12_Expressions/17_Getter_Invocation_A03_t02: Skip # Times out. Please triage this failure
+Language/Expressions/Top_level_Getter_Invocation/17_Getter_Invocation_A03_t02: Skip # Times out. Please triage this failure
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -7687,13 +7756,13 @@
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
 
 [ $compiler == dart2js && $runtime == ie11 ]
-Language/05_Variables/05_Variables_A14_t07: Skip # Times out. Please triage this failure
-Language/06_Functions/2_Formal_Parameters_A02_t01: Skip # Times out. Please triage this failure
-Language/12_Expressions/19_Conditional_A06_t04: Skip # Times out. Please triage this failure
-Language/12_Expressions/30_Identifier_Reference_A10_t02: Skip # Times out. Please triage this failure
-Language/13_Statements/03_Variable_Declaration_A01_t18: Skip # Times out. Please triage this failure
-Language/15_Types/4_Interface_Types_A12_t07: Skip # Times out. Please triage this failure
-Language/15_Types/5_Function_Types_A01_t03: Skip # Times out. Please triage this failure
+Language/Variables/implicit_setter_void_t07: Skip # Times out. Please triage this failure
+Language/Functions/Formal_Parameters/scope_t01: Skip # Times out. Please triage this failure
+Language/Expressions/Conditional/type_t04: Skip # Times out. Please triage this failure
+Language/Expressions/Identifier_Reference/evaluation_function_t02: Skip # Times out. Please triage this failure
+Language/Statements/Local_Variable_Declaration/syntax_t18: Skip # Times out. Please triage this failure
+Language/Types/Interface_Types/subtype_t37: Skip # Times out. Please triage this failure
+Language/Types/Function_Types/subtype_no_args_t03: Skip # Times out. Please triage this failure
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -9547,18 +9616,10 @@
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
 
 [ $compiler == dart2js && $cps_ir ]
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: RuntimeError # Please triage this failure.
-Language/12_Expressions/13_Property_Extraction_A03_t01: RuntimeError # Cannot read property 'call' of undefined
-Language/12_Expressions/13_Property_Extraction_A03_t02: RuntimeError # Cannot read property 'call' of undefined
-Language/12_Expressions/13_Property_Extraction_A03_t03: RuntimeError # Cannot read property 'call' of undefined
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A01_t01: RuntimeError # Cannot read property 'call' of undefined
-Language/12_Expressions/30_Identifier_Reference_A09_t03: Crash # (i=0): For-loop variable captured in loop header
-Language/13_Statements/06_For_A01_t07: Crash # unsupported operation on erroneous element
-Language/13_Statements/12_Labels_A03_t04: Crash # (switch (i){L:case 0:flag=true;break;case 2:continue L;}): continue to a labeled switch case
-Language/13_Statements/14_Continue_A02_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
-Language/13_Statements/14_Continue_A02_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
-Language/15_Types/4_Interface_Types_A12_t09: RuntimeError # Please triage this failure.
-LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: Crash # (lazy.method()): deferred access is not implemented
+Language/Statements/Labels/scope_t04: Crash # (switch (i){L:case 0:flag=true;break;case 2:continue L;}): continue to a labeled switch case
+Language/Statements/Continue/label_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
+Language/Statements/Continue/label_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
+Language/Types/Interface_Types/subtype_t39: RuntimeError # Please triage this failure.
 LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
 LibTest/core/Invocation/isAccessor_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 LibTest/core/Invocation/isGetter_A01_t01: RuntimeError # Please triage this failure.
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 5136124..f97f79d 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -13,6 +13,7 @@
 
 [ $compiler == none && $runtime == dartium && $system == windows ]
 LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Issue 21605
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: RuntimeError # Please triage this failure.
 
 [ $compiler == none && $runtime == dartium ]
 LayoutTests/fast/dom/custom/document-register-basic_t01: RuntimeError # Bad test can't register HtmlElement.
@@ -27,424 +28,75 @@
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Pass, RuntimeError # Flaky with Dartium JsInterop. Seems like timing issues in the test.
 LibTest/html/IFrameElement/IFrameElement.created_A01_t01: RuntimeError # Issue 24568
 LibTest/html/Window/requestFileSystem_A02_t01: Skip # Issue 24585.
+LibTest/html/Window/document_A01_t01: Skip # accesses window.document from a cross-frame window
+WebPlatformTest/html/browsers/browsing-the-web/read-text/load-text-plain_t01: Skip # accesses window.document from a cross-frame window
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Pass, Fail # https://github.com/dart-lang/co19/issues/12
 
 [ $compiler == none && $runtime == dartium && $checked ]
 LayoutTests/fast/css/style-scoped/style-scoped-scoping-nodes-different-order_t01: RuntimeError # Dartium JSInterop failure
 
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Issue 20540
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Issue 20540
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Issue 20540
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Issue 20540
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: Fail # Issue 22007
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: Fail # Issue 22007
-Language/14_Libraries_and_Scripts/3_Parts_A01_t05: Skip # Times out flakily. Issue 20881
-LayoutTests/fast/speechsynthesis/*: Skip # Times out on Dartium. Fails elsewhere. Issue 22017
-LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Issue 22111
-
-LayoutTests/fast/borders/border-radius-child_t01: Skip # co19 issue 732.
-LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Skip # co19 issue 732.
-LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: Skip # co19 issue 732.
-LayoutTests/fast/events/document-elementFromPoint_t01: Skip # co19 issue 732.
-LayoutTests/fast/innerHTML/innerHTML-svg-write_t01: Fail # Test uses foreignObject tag, which sanitizer removes. co19 issue #746
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: Skip # co19 issue 732.
-LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: Skip # co19 issue 732.
-LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 732.
-LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/international/rtl-text-wrapping_t01: Skip # co19 issue 732.
-LayoutTests/fast/writing-mode/positionForPoint_t01: Skip # co19 issue 732.
-LayoutTests/fast/css/computed-offset-with-zoom_t01: Skip # co19 issue 732.
-LayoutTests/fast/sub-pixel/inline-block-with-padding_t01: Skip # co19 issue 732.
-LayoutTests/fast/sub-pixel/size-of-span-with-different-positions_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/international/complex-text-rectangle_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: Skip # co19 issue 732.
-LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/HTMLButtonElement/change-type_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/cssTarget-crash_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/shadow/form-in-shadow_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/form-submission-create-crash_t01.dart: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/formmethod-attribute-input-2_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/missing-action_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/submit-form-with-dirname-attribute_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-ancestor-dir-attribute_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-nonhtml-ancestor_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/submit-nil-value-field-assert_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/textarea-submit-crash_t01: Skip # Test reloads itself. Issue 18558.
-
-LayoutTests/fast/mediastream/getusermedia_t01: Skip # co19 issue 738
-
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Pass, Fail #: Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A02_t02: Skip # Please triage this failure.
-Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: Pass # Issue 14478: This should break.
-LibTest/async/Completer/completeError_A02_t01: Pass, Fail # Please triage this failure.
-LibTest/core/int/operator_left_shift_A01_t02: Pass, Fail # Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t01: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t04: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t05: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t06: Fail # Issue 13921
-LibTest/isolate/Isolate/spawnUri_A01_t01: RuntimeError # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A01_t02: Skip # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A01_t03: Skip # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A01_t04: RuntimeError # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A01_t05: RuntimeError # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A02_t01: RuntimeError # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A02_t04: Skip # Dart issue 15974
-
-LibTest/isolate/RawReceivePort/RawReceivePort_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/RawReceivePort/RawReceivePort_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/RawReceivePort/close_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/RawReceivePort/handler_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/RawReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
-
-LibTest/isolate/ReceivePort/any_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/any_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t03: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t04: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t03: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/close_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/close_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/contains_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/distinct_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/distinct_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/drain_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/drain_A02_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/elementAt_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/elementAt_A03_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/every_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/expand_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/firstWhere_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/firstWhere_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/firstWhere_A03_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/first_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/first_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/first_A02_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/fold_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/fold_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/forEach_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/isEmpty_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/join_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/join_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/lastWhere_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/lastWhere_A04_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/last_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/last_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/length_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/listen_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/map_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/pipe_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/reduce_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/reduce_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/reduce_A01_t03: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/singleWhere_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/singleWhere_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/single_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/single_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/skipWhile_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/skip_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/takeWhile_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/take_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/take_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/take_A01_t03: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/toList_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/toSet_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/transform_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/transform_A01_t02: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/where_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/where_A01_t02: RuntimeError # Issue 13921
-LibTest/html/Element/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/enteredView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/leftView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/responseText_A01_t02: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-WebPlatformTest/dom/events/event_constants/constants_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-WebPlatformTest/dom/events/event_constructors/Event_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-WebPlatformTest/dom/events/event_constructors/Event_A02_t01: Skip # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/hittest-relative-to-viewport_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Element/setAttributeNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/hidden-attr_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/imports/import-events_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/childNodes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/clone_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/securityPolicy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/contentEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/dataset_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/getAttributeNS_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
-LibTest/html/Element/getAttributeNS_A01_t02: RuntimeError # Please triage this failure.
-LibTest/html/Element/getClientRects_A01_t02: RuntimeError # co19-roll r706.  Issue 16575
-LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
-LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/replaceWith_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/responseType_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/responseType_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/statusText_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/appendHtml_A01_t01: RuntimeError # Issue 23462
-LibTest/html/IFrameElement/appendHtml_A01_t02: RuntimeError # Issue 23462
-LibTest/html/IFrameElement/attributeChanged_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/attributes_setter_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/IFrameElement/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createFragment_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createFragment_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createFragment_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createShadowRoot_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/getClientRects_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/innerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/IFrameElement/offsetTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/setInnerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/close_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/find_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/find_A03_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/find_A06_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/moveTo_A01_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/moveTo_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/postMessage_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/resizeBy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/resizeTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/isolate/SendPort/send_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/isolate/SendPort/send_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/isolate/SendPort/send_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/isolate/SendPort/send_A01_t04: RuntimeError # co19-roll r706.  Please triage this failure.
-Language/12_Expressions/13_Spawning_an_Isolate_A01_t01: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t01: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t02: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t03: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t04: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError # co19-roll r667: Please triage this failure
-LibTest/async/Timer/Timer_A01_t01: RuntimeError, Pass # Issue 16475
-LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-host_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hostname_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-port_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-protocol_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-search_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-autofocus_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unfocusable_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unselectable_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/multiple-centered-dialogs_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Issue 18931
-LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLElement/set-inner-outer-optimization_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLElement/spellcheck_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLFormElement/move-option-between-documents_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLImageElement/image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLImageElement/parse-src_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLInputElement/input-image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # co19-roll r722: Issue 18010
-LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LibTest/html/IFrameElement/outerHtml_setter_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/IFrameElement/paddingEdge_A01_t01: RuntimeError # co19-roll r722: Issue 16574
-LibTest/html/Node/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/append_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/nodes_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/nodes_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/parent_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/previousNode_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/innerhtml-on-templates/innerhtml_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/additions-to-the-in-head-insertion-mode/generating-of-implied-end-tags_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-006_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-005_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: RuntimeError # Not clear that any of this works. Also suppressed in dart2js
-WebPlatformTest/shadow-dom/events/event-retargeting/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t02: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-003_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/custom-pseudo-elements/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/html/Window/requestFileSystem_A01_t02: RuntimeError,Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLSelectElement/selected-index-preserved-when-option-text-changes_t01: RuntimeError # co19-roll r722: Issue 18127
-LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: RuntimeError # co19-roll r722: Issue 18250
-LayoutTests/fast/dom/HTMLTemplateElement/innerHTML_t01: RuntimeError # co19-roll r722: Issue 18249
-LayoutTests/fast/dom/HTMLTemplateElement/ownerDocumentXHTML_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/observe-childList_t01: RuntimeError # co19-roll r722: Issue 18253
-LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Node/initial-values_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19-roll r722: Please triage this failure.
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/asyncTestFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/asyncTestFail_t02: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/testFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/events/type_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createDocumentType_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-adoptNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElement_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElementNS_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-getElementsByTagName_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Element-childElementCount_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-appendChild_t02: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-insertBefore_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-isEqualNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-nodeName_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/dom/nodes/Node-replaceChild_t01: RuntimeError # co19-roll r722: Please triage this failure
-WebPlatformTest/dom/nodes/Node-textContent_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A06_t03: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t02: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t03: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A08_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttribute_A03_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-005_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-006_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure.
-
-LayoutTests/fast/dom/css-innerHTML_t01: RuntimeError # Test is incorrect.
-
-# co19-roll r738.
-WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out. co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.LayoutTests/fast/dom/Window/window-resize-contents_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-resize-contents_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/blur-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/custom/document-register-svg-extends_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/dataset-xhtml_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/dataset_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/option-properties_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/EventObject.after.dispatchEvenr_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/EventObject.multiple.dispatchEvent_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/addEventListener.optional.useCapture_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-getter_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-setter_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-namespace_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t05: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t07: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t02: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-delete_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-get_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.  Pass on macos.
-WebPlatformTest/html/semantics/forms/the-button-element/button-validation_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-fieldset-element/disabled_t01: RuntimeError # co19-roll r738: Please triage this failure.
-
-# co19-roll r761
+Language/Classes/Constructors/Generative_Constructors/final_variables_t01: Pass, Fail #: Please triage this failure.
+Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure.
+Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure.
+Language/Classes/Setters/syntax_t04: RuntimeError # Please triage this failure.
+Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure.
+Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t02: RuntimeError # Please triage this failure.
+Language/Classes/deсlarations_t01: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t02: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t03: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t04: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t06: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t08: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t12: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t13: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t14: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t15: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t16: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t17: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t18: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t19: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t20: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t21: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t22: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t23: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t24: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t25: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t26: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t27: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t28: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t29: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t30: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t31: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t32: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t33: Skip # Times out. Please triage this failure.
+Language/Classes/deсlarations_t34: Skip # Times out. Please triage this failure.
+Language/Expressions/Instance_Creation/Const/abstract_class_t01: Fail # Issue 22007
+Language/Expressions/Instance_Creation/Const/abstract_class_t03: Fail # Issue 22007
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: RuntimeError # Please triage this failure.
+Language/Expressions/Spawning_an_Isolate/new_isolate_t01: RuntimeError, OK  # Uses Isolate.spawn.
+Language/Libraries_and_Scripts/Imports/namespace_changes_t10: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/Parts/compilation_t02: Skip # Please triage this failure.
+Language/Libraries_and_Scripts/Parts/syntax_t05: Skip # Times out flakily. Issue 20881
+Language/Libraries_and_Scripts/Scripts/top_level_main_t03: Pass # Issue 14478: This should break.
+Language/Libraries_and_Scripts/Scripts/top_level_main_t03: RuntimeError # co19-roll r786: Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t04: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t05: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t09: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t10: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t14: RuntimeError # Please triage this failure.
+Language/Libraries_and_Scripts/URIs/syntax_t15: RuntimeError # Please triage this failure.
+Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure.
+Language/Mixins/not_object_superclass_t01: Fail # Please triage this failure.
+Language/Mixins/reference_to_super_t01: Fail # Please triage this failure.
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/borders/border-radius-child_t01: Skip # co19 issue 732.
 LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # co19-roll r761: Please triage this failure.
@@ -463,6 +115,7 @@
 LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Skip # Causes following tests to fail. co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/canvas-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/context-lost_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # co19-roll r761: Please triage this failure.
@@ -472,129 +125,20 @@
 LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Issue 20540
 LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/content/content-none_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/content/content-normal_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/counters/complex-before_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: Pass, RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-1_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-2_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-3_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-4_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-5_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/pseudo-any_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-001_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-002_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-003_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-004_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/sticky/parsing-position-sticky_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Borrowed/cz_20030217_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Borrowed/namespace-nodes_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/ambiguous-operators_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/position_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # co19-roll r761: Please triage this failure.
-LibTest/html/IFrameElement/querySelector_A01_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/dom/Node-replaceChild_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html-imports/link-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html-imports/link-import_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html-imports/loading-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-autocomplete_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-elements-matches_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-elements-nameditem_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/date_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/datetime-local_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/datetime_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/datetime_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/email_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/email_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/input-textselection_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/month_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/range_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/time_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/time_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/type-change-state_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/url_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/week_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-meter-element/meter_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-option-element/option-text-recurse_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-option-element/option-text-spaces_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/grouping-content/the-blockquote-element/grouping-blockquote_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-close_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-showModal_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/scripting-1/the-script-element/script-text_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/checked_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/default_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/dir_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/enabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/indeterminate_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/inrange-outofrange_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/tabular-data/the-tr-element/rowIndex_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/syntax/serializing-html-fragments/outerHTML_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: RuntimeError # Tests APIs that aren't yet visible. Tests should be deleted.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/webstorage/event_local_key_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/webstorage/event_session_key_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
-WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
-
-# co19-roll r786
-Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Skip # co19 issue 732.
 LayoutTests/fast/css-generated-content/malformed-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-generated-content/pseudo-transition_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -639,9 +183,55 @@
 LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: Skip # co19 issue 732.
+LayoutTests/fast/css/computed-offset-with-zoom_t01: Skip # co19 issue 732.
+LayoutTests/fast/css/content/content-none_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/content/content-normal_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/counters/complex-before_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: Pass, RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-1_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-2_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-3_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-4_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-5_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-any_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-001_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-002_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-003_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-004_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/sticky/parsing-position-sticky_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out. co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/style-scoped/style-scoped-nested_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css/style-scoped/style-scoped-with-dom-operation_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css/style-scoped/style-scoped-with-important-rule_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last-inherited_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-color_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -651,17 +241,125 @@
 LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent-inherited_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/hittest-relative-to-viewport_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Element/setAttributeNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-host_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hostname_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-port_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-protocol_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-search_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLButtonElement/change-type_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/HTMLDialogElement/dialog-autofocus_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unfocusable_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unselectable_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/multiple-centered-dialogs_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLElement/insertAdjacentHTML-errors_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/dom/HTMLElement/set-inner-outer-optimization_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLElement/spellcheck_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLFormElement/move-option-between-documents_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLImageElement/image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLImageElement/parse-src_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLInputElement/input-image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # co19-roll r722: Issue 18010
+LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Issue 18931
+LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLSelectElement/selected-index-preserved-when-option-text-changes_t01: RuntimeError # co19-roll r722: Issue 18127
+LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: RuntimeError # co19-roll r722: Issue 18250
+LayoutTests/fast/dom/HTMLTemplateElement/innerHTML_t01: RuntimeError # co19-roll r722: Issue 18249
+LayoutTests/fast/dom/HTMLTemplateElement/ownerDocumentXHTML_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/MutationObserver/database-callback-delivery_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/dom/MutationObserver/observe-childList_t01: RuntimeError # co19-roll r722: Issue 18253
+LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/Node/fragment-mutation_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Node/initial-values_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/insertNode-empty-fragment-crash_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/mutation_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-constructor_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-expand_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-insertNode-separate-endContainer_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/Window/window-resize-contents_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/blur-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/css-innerHTML_t01: RuntimeError # Test is incorrect.
+LayoutTests/fast/dom/cssTarget-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/custom/document-register-svg-extends_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/dataset-xhtml_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/dataset_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/document-importNode-arguments_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/getElementsByClassName/011_t01: RuntimeError # Chrome 39 roll. Please triage this failure
+LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/option-properties_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/form-in-shadow_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dynamic/crash-generated-counter_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/dynamic/crash-generated-image_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/dynamic/crash-generated-quote_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/dynamic/crash-generated-text_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/dynamic/insertAdjacentElement_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/insertAdjacentHTML_t01: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/dynamic/recursive-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/add-event-without-document_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/events/clipboard-clearData_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/div-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/document-elementFromPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/document-elementFromPoint_t01: Skip # co19 issue 732.
 LayoutTests/fast/events/event-creation_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/event-listener-html-non-html-confusion_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/initkeyboardevent-crash_t01: RuntimeError, Timeout # co19-roll r786: Please triage this failure.
@@ -682,118 +380,14 @@
 LayoutTests/fast/files/xhr-response-blob_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/async-operations_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/directory-entry-to-uri_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/filesystem/file-entry-to-uri_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/filesystem-reference_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/storage/disallowed-storage_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/anonymous-table-section-removed_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/caption-orthogonal-writing-mode-sizing_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/col-width-span-expand_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/computeLogicalWidth-table-needsSectionRecalc_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/css-table-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/css-table-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/css-table-width-with-border-padding_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/large-shrink-wrapped-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/margins-perpendicular-containing-block_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-css-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-css-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-html-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-html-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-colgroup-present-after-table-row_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-rowspan-cell-with-empty-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-with-content-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/find-soft-hyphen_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/find-spaces_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/font-ligatures-linebreak_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/cjk-segmentation_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/rtl-text-wrapping_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/thai-offsetForPosition-inside-character_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/remove-zero-length-run_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-pixel_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-rtl_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-webfont_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/transforms/hit-test-large-scale_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/file-http-base_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/file_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/host_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/idna2003_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/idna2008_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/invalid-urls-utf8_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/ipv4_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/ipv6_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/path_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/query_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/relative-unix_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/relative-win_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/relative_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/segments-from-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/standard-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/auto-sizing-orthogonal-flows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/py-dom-xpath/data_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/py-dom-xpath/expressions_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xsl/default-html_t01: RuntimeError # co19-roll r786: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/password_t01: RuntimeError # co19-roll r786: Please triage this failure.
-WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Node/fragment-mutation_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/insertNode-empty-fragment-crash_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/mutation_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-constructor_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-expand_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-insertNode-separate-endContainer_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/document-importNode-arguments_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure.
-
-
-# co19-roll r801
-LayoutTests/fast/canvas/webgl/canvas-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/database-callback-delivery_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/filesystem/file-writer-abort-continue_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/filesystem/file-writer-abort-depth_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/filesystem/file-writer-events_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/filesystem/file-writer-gc-blob_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/filesystem/file-writer-write-overlapped_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/filesystem-reference_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/read-directory-many_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/filesystem/simple-readonly_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/HTMLOptionElement_selected2_t01: Skip # Times out. co19-roll r801: Please triage this failure.
@@ -807,10 +401,15 @@
 LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/form-submission-create-crash_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/formmethod-attribute-input-2_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/input-appearance-elementFromPoint_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -819,6 +418,7 @@
 LayoutTests/fast/forms/menulist-disabled-selected-option_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/menulist-selection-reset_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/menulist-submit-without-selection_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/missing-action_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/multiple-selected-options-innerHTML_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/option-change-single-selected_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/option-strip-unicode-spaces_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -828,18 +428,41 @@
 LayoutTests/fast/forms/select-clientheight-large-size_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/select-clientheight-with-multiple-attr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-ancestor-dir-attribute_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-nonhtml-ancestor_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/submit-form-with-dirname-attribute_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/submit-nil-value-field-assert_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/submit-nil-value-field-assert_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/textarea-scrollbar-height_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/textarea-submit-crash_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/html/adjacent-html-context-element_t01:RuntimeError # co19 issue 11.
+LayoutTests/fast/html/hidden-attr_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/imports/import-element-removed-flag_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/html/imports/import-events_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LayoutTests/fast/html/select-dropdown-consistent-background-color_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/inline/boundingBox-with-continuation_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/fixed-pos-moves-with-abspos-inline-parent_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/inline/inline-position-top-align_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/inline-relative-offset-boundingbox_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/inline/inline-with-empty-inline-children_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/reattach-inlines-in-anonymous-blocks-with-out-of-flow-siblings_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/innerHTML/innerHTML-special-elements_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/lists/item-not-in-list-line-wrapping_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/lists/list-style-position-inside_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
 LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out. co19-roll r801: Please triage this failure.
 LayoutTests/fast/loader/hashchange-event-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -852,48 +475,90 @@
 LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/masking/parsing-mask_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/media/media-query-list-syntax_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/media/mq-parsing_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue. # co19 issue 11.
+LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Issue 22111
+LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475 # co19 issue 11.
+LayoutTests/fast/mediastream/getusermedia_t01: Skip # co19 issue 738
 LayoutTests/fast/multicol/balance-short-trailing-empty-block_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/balance-trailing-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/balance-trailing-border_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/balance-unbreakable_t01: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/column-width-zero_t01: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/hit-test-above-or-below_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/inherit-column-values_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance-maxheight_t02: RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t02: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t05: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t06: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t07: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/newmulticol/balance_t07: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t08: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/newmulticol/balance_t08: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t09: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/newmulticol/balance_t09: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t10: Pass, RuntimeError # I don't understand how, but sometimes passes. # co19 issue 11.
 LayoutTests/fast/multicol/newmulticol/balance_t10: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/vertical-lr/break-properties_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/vertical-rl/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/widows_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/zeroColumnCount_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/overflow/overflow-rtl-vertical-origin_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue. # co19 issue 11.
+LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # False pass on Safari # co19 issue 11.
 LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/overflow/scrollbar-restored_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/stray-param_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass # False pass # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
 LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError, Pass # Spurious intermittent pass. # co19 issue 11.
 LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
 LayoutTests/fast/replaced/preferred-widths_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/table-percent-height-text-controls_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/replaced/table-percent-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/table-replaced-element_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/selectors/specificity-overflow_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/selectors/style-sharing-last-child_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -905,211 +570,519 @@
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-right_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/speechsynthesis/*: Skip # Times out on Dartium. Fails elsewhere. Issue 22017
+LayoutTests/fast/storage/disallowed-storage_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: Skip # co19 issue 732.
+LayoutTests/fast/sub-pixel/inline-block-with-padding_t01: Skip # co19 issue 732.
+LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Fails on Safari, false pass on others # co19 issue 11.
+LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/size-of-span-with-different-positions_t01: Skip # co19 issue 732.
+LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: Skip # co19 issue 732.
+LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/anonymous-table-section-removed_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/anonymous-table-section-removed_t01: Skip # co19 issue 11.
+LayoutTests/fast/table/caption-orthogonal-writing-mode-sizing_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/col-width-span-expand_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 11.
+LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 732.
+LayoutTests/fast/table/computeLogicalWidth-table-needsSectionRecalc_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/css-table-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/css-table-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/css-table-width-with-border-padding_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/fixed-table-layout-width-change_t01: Pass, RuntimeError # False passes on Firefox # co19 issue 11.
+LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Skip # co19 issue 11.
+LayoutTests/fast/table/hittest-tablecell-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/html-table-width-max-width-constrained_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/large-shrink-wrapped-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/margins-perpendicular-containing-block_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/min-width-css-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-width-css-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-width-html-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-width-html-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/nested-tables-with-div-offset_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/dom/getElementsByClassName/011_t01: RuntimeError # Chrome 39 roll. Please triage this failure
-
-#
-# Everything below this point is associated with co19 Issue 747
-#
-LayoutTests/fast/dynamic/insertAdjacentHTML_t01: Pass, RuntimeError
-LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError
-LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError
-LayoutTests/fast/multicol/balance-unbreakable_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError
-LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError
-LayoutTests/fast/multicol/inherit-column-values_t01: RuntimeError
-LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance-maxheight_t02: RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t02: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t05: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t06: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t07: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t08: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t09: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance_t10: Pass, RuntimeError # I don't understand how, but sometimes passes.
-LayoutTests/fast/multicol/column-width-zero_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/vertical-lr/break-properties_t01: RuntimeError
-LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/zeroColumnCount_t01: RuntimeError
-LayoutTests/fast/media/media-query-serialization_t01: RuntimeError
-LayoutTests/fast/media/mq-append-delete_t01: RuntimeError
-LayoutTests/fast/media/mq-color-index_t02: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t02: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t01: RuntimeError
-LayoutTests/fast/media/mq-js-media-except_t03: RuntimeError
-LayoutTests/fast/media/mq-js-update-media_t01: RuntimeError
-LayoutTests/fast/media/mq-parsing_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue.
-LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475
-LayoutTests/fast/loader/local-css-allowed-in-strict-mode_t01: RuntimeError
-LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # False pass on Safari
-LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError
-LayoutTests/fast/lists/item-not-in-list-line-wrapping_t01: RuntimeError
-LayoutTests/fast/lists/list-style-position-inside_t01: Pass, RuntimeError
-LayoutTests/fast/innerHTML/innerHTML-special-elements_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-inline-parent_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor_t01: RuntimeError
-LayoutTests/fast/inline/inline-relative-offset-boundingbox_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent_t01: RuntimeError
-LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError
-LayoutTests/fast/inline/reattach-inlines-in-anonymous-blocks-with-out-of-flow-siblings_t01: RuntimeError
-LayoutTests/fast/overflow/overflow-rtl-vertical-origin_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass # False pass
-LayoutTests/fast/table/col-width-span-expand_t01: Skip
-LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError
-LayoutTests/fast/text/font-fallback-synthetic-italics_t01: Pass, RuntimeError
-LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError
-LayoutTests/fast/text/glyph-reordering_t01: Pass, RuntimeError # This is a false pass. The font gets sanitized, so whether it works or not probably depends on default sizes.
-LayoutTests/fast/text/international/rtl-text-wrapping_t01: Pass # This is a false pass. All the content gets sanitized, so there's nothing to assert fail on. If the code did anything it would fail.
-LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: Pass, RuntimeError
-LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError
-LayoutTests/fast/text/line-breaks-after-closing-punctuations_t01: RuntimeError
-LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError
-LayoutTests/fast/text/line-breaks-after-ideographic-comma-or-full-stop_t01: RuntimeError
-LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail
-LayoutTests/fast/text-autosizing/inline-width_t01: RuntimeError
-LayoutTests/fast/text-autosizing/text-removal_t01: RuntimeError
-LayoutTests/fast/text-autosizing/table-inline-width_t01: RuntimeError
-LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError
-LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError
-LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip
-LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError
-LayoutTests/fast/text/pre-wrap-trailing-tab_t01: RuntimeError
-LayoutTests/fast/text-autosizing/display-type-change-lineHeight_t01: RuntimeError
-LayoutTests/fast/url/trivial_t01: RuntimeError
-LayoutTests/fast/url/trivial-segments_t01: RuntimeError
-LayoutTests/fast/url/scheme_t01: RuntimeError
-LayoutTests/fast/url/host-lowercase-per-scheme_t01: RuntimeError
-LayoutTests/fast/url/safari-extension_t01: RuntimeError
-LayoutTests/fast/url/safari-extension_t01: RuntimeError
-LayoutTests/fast/url/port_t01: RuntimeError
-LayoutTests/fast/url/mailto_t01: RuntimeError
-LayoutTests/fast/url/path-url_t01: RuntimeError
-LayoutTests/fast/url/anchor_t01: RuntimeError
-LayoutTests/fast/writing-mode/auto-margins-across-boundaries_t01: RuntimeError
-LayoutTests/fast/writing-mode/display-mutation_t01: RuntimeError
-LayoutTests/fast/writing-mode/percentage-padding_t01: RuntimeError
-LayoutTests/fast/writing-mode/relative-positioning-percentages_t01: RuntimeError
-LayoutTests/fast/writing-mode/block-formatting-context_t01: RuntimeError
-LayoutTests/fast/writing-mode/percentage-margins-absolute-replaced_t01: Pass, RuntimeError
-LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip
-LayoutTests/fast/html/adjacent-html-context-element_t01:RuntimeError
-LayoutTests/fast/dom/HTMLElement/insertAdjacentHTML-errors_t01: RuntimeError
-LayoutTests/fast/transforms/transform-inside-overflow-scroll_t01: RuntimeError
-LayoutTests/fast/transforms/transform-hit-test-flipped_t01: Pass, RuntimeError # Passes on Firefox, but is clearly not testing what it's trying to test.
-LayoutTests/fast/transforms/scrollIntoView-transformed_t01: Pass, RuntimeError # False passes on Firefox.
-LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError, Pass # Erratic, but only passes because divs have been entirely removed.
-LayoutTests/fast/transforms/topmost-becomes-bottomost-for-scrolling_t01: RuntimeError
-LayoutTests/fast/table/anonymous-table-section-removed_t01: Skip
-LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Skip
-LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError
-LayoutTests/fast/table/table-size-integer-overflow_t01: RuntimeError
-LayoutTests/fast/table/table-sections-border-spacing_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError
-LayoutTests/fast/table/resize-table-row_t01: RuntimeError
-LayoutTests/fast/table/resize-table-cell_t01: RuntimeError
-LayoutTests/fast/table/resize-table-binding-cell_t01: RuntimeError
-LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError
-LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError
-LayoutTests/fast/table/html-table-width-max-width-constrained_t01: Pass, RuntimeError
-LayoutTests/fast/table/fixed-table-layout-width-change_t01: Pass, RuntimeError # False passes on Firefox
-LayoutTests/fast/table/fixed-table-with-percent-width-inside-extra-large-div_t01: RuntimeError
-LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-length_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-number_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-length-invalid_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-angle_t01: RuntimeError
-LayoutTests/fast/svg/tabindex-focus_t01: RuntimeError
-LayoutTests/fast/svg/whitespace-integer_t01: RuntimeError
-LayoutTests/fast/sub-pixel/shadows-computed-style_t01: RuntimeError
-LayoutTests/fast/sub-pixel/tiled-canvas-elements_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-list-inside_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-with-margin-in-container_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-percentage-widths_t01: RuntimeError
-LayoutTests/fast/sub-pixel/computedstylemargin_t01: RuntimeError
-LayoutTests/fast/sub-pixel/block-preferred-widths-with-sub-pixel-floats_t01: RuntimeError
-LayoutTests/fast/sub-pixel/auto-table-layout-should-avoid-text-wrapping_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError
-LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Fails on Safari, false pass on others
-LayoutTests/fast/selectors/style-sharing-last-child_t01: RuntimeError
-LayoutTests/fast/selectors/specificity-overflow_t01: RuntimeError
-LayoutTests/fast/scrolling/scroll-element-into-view_t01: RuntimeError
-LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError
-LayoutTests/fast/replaced/table-replaced-element_t01: RuntimeError
-LayoutTests/fast/replaced/table-percent-height-text-controls_t01: RuntimeError
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError, Pass # Spurious intermittent pass
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError, Pass # Spurious intermittent pass.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: RuntimeError, Pass # Spurious intermittent pass
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: RuntimeError, Pass # Spurious intermittent pass
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError
-LayoutTests/fast/parser/stray-param_t01: RuntimeError
-LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError
-LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError
-LayoutTests/fast/overflow/height-during-simplified-layout_t01: RuntimeError
-LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError
-WebPlatformTest/html-imports/link-import-null_t01: RuntimeError
-WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError
-WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError
-WebPlatformTest/html/syntax/parsing/math-parse_t01: RuntimeError
-WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError
-WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: Skip
-WebPlatformTest/html/semantics/text-level-semantics/the-a-element/a.text-getter_t01: RuntimeError
-WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: Skip
-WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: Pass, RuntimeError # Spurious pass
-WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError
-WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError
-WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError
-WebPlatformTest/html/semantics/forms/the-input-element/pattern_attribute_t01: RuntimeError
-WebPlatformTest/html/semantics/forms/the-form-element/form-nameditem_t01: RuntimeError
-WebPlatformTest/html/semantics/disabled-elements/disabledElement_t01: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t03: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t05: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-param_t01: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-newelements_t01: RuntimeError
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-case_t01: RuntimeError
-#
-# End of Issue 747
-#
+LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/resize-table-row_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-colgroup-present-after-table-row_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-rowspan-cell-with-empty-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-sections-border-spacing_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/table-with-content-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/find-soft-hyphen_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/find-spaces_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/font-fallback-synthetic-italics_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # co19 issue 11.
+LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # co19 issue 11.
+LayoutTests/fast/text/font-ligatures-linebreak_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/glyph-reordering_t01: Pass, RuntimeError # This is a false pass. The font gets sanitized, so whether it works or not probably depends on default sizes. # co19 issue 11.
+LayoutTests/fast/text/international/cjk-segmentation_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/international/complex-text-rectangle_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: Pass # This is a false pass. All the content gets sanitized, so there's nothing to assert fail on. If the code did anything it would fail. # co19 issue 11.
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/international/thai-offsetForPosition-inside-character_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/line-breaks-after-closing-punctuations_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/line-breaks-after-ideographic-comma-or-full-stop_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/pre-wrap-trailing-tab_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail # co19 issue 11.
+LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/remove-zero-length-run_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-pixel_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-rtl_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-webfont_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError, Pass # Erratic, but only passes because divs have been entirely removed. # co19 issue 11.
+LayoutTests/fast/transforms/hit-test-large-scale_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/transforms/scrollIntoView-transformed_t01: Pass, RuntimeError # False passes on Firefox. # co19 issue 11.
+LayoutTests/fast/transforms/topmost-becomes-bottomost-for-scrolling_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/transforms/transform-hit-test-flipped_t01: Pass, RuntimeError # Passes on Firefox, but is clearly not testing what it's trying to test. # co19 issue 11.
+LayoutTests/fast/transforms/transform-inside-overflow-scroll_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/anchor_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/file-http-base_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/file_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/host-lowercase-per-scheme_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/host_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/idna2003_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/idna2008_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/invalid-urls-utf8_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/ipv4_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/ipv6_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/mailto_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/path-url_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/path_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/port_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/query_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/relative-unix_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/relative-win_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/relative_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/safari-extension_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/safari-extension_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/scheme_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/segments-from-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/standard-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/trivial-segments_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/url/trivial_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/auto-margins-across-boundaries_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/auto-sizing-orthogonal-flows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/writing-mode/block-formatting-context_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/display-mutation_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/percentage-margins-absolute-replaced_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/percentage-padding_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/writing-mode/positionForPoint_t01: Skip # co19 issue 732.
+LayoutTests/fast/writing-mode/relative-positioning-percentages_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Borrowed/cz_20030217_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Borrowed/namespace-nodes_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/ambiguous-operators_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/position_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/data_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/expressions_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xsl/default-html_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LibTest/async/Completer/completeError_A02_t01: Pass, Fail # Please triage this failure.
+LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/async/Timer/Timer_A01_t01: RuntimeError, Pass # Issue 16475
+LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19-roll r722: Please triage this failure.
+LibTest/core/int/operator_left_shift_A01_t02: Pass, Fail # Please triage this failure.
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Document/childNodes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/clone_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/securityPolicy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/contentEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/dataset_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/getAttributeNS_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
+LibTest/html/Element/getAttributeNS_A01_t02: RuntimeError # Please triage this failure.
+LibTest/html/Element/getClientRects_A01_t02: RuntimeError # co19-roll r706.  Issue 16575
+LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
+LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # co19-roll r761: Please triage this failure.
+LibTest/html/Element/replaceWith_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/responseText_A01_t02: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/responseType_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/responseType_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/statusText_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # co19-roll r706.  Please triage this failure.
 LibTest/html/IFrameElement/appendHtml_A01_t01: Pass, RuntimeError # Issue 23462
+LibTest/html/IFrameElement/appendHtml_A01_t01: RuntimeError # Issue 23462
 LibTest/html/IFrameElement/appendHtml_A01_t02: Pass, RuntimeError # Issue 23462
+LibTest/html/IFrameElement/appendHtml_A01_t02: RuntimeError # Issue 23462
+LibTest/html/IFrameElement/attributeChanged_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/attributes_setter_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/IFrameElement/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createFragment_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createFragment_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createFragment_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createShadowRoot_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/enteredView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/getClientRects_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/innerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/leftView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/IFrameElement/offsetTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/outerHtml_setter_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/IFrameElement/paddingEdge_A01_t01: RuntimeError # co19-roll r722: Issue 16574
+LibTest/html/IFrameElement/querySelector_A01_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LibTest/html/IFrameElement/setInnerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Node/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/append_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/nodes_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/nodes_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/parent_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/previousNode_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Window/close_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/find_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/find_A03_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/find_A06_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/moveTo_A01_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/moveTo_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/postMessage_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/requestFileSystem_A01_t02: RuntimeError,Pass # co19-roll r722: Please triage this failure.
+LibTest/html/Window/resizeBy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/resizeTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/isolate/Isolate/spawnUri_A01_t01: RuntimeError # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t02: Skip # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t03: Skip # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t04: RuntimeError # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t05: RuntimeError # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A02_t01: RuntimeError # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A02_t04: Skip # Dart issue 15974
+LibTest/isolate/Isolate/spawn_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/RawReceivePort/RawReceivePort_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/RawReceivePort/RawReceivePort_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/RawReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/RawReceivePort/handler_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/RawReceivePort/sendPort_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/any_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/any_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A04_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A04_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/contains_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/distinct_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/distinct_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/drain_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/drain_A02_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/elementAt_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/elementAt_A03_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/every_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/expand_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/firstWhere_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/firstWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/firstWhere_A03_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/first_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/first_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/first_A02_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/fold_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/fold_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/forEach_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/isEmpty_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/join_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/join_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/lastWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/lastWhere_A04_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/last_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/last_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/length_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/listen_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/map_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/pipe_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/reduce_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/reduce_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/reduce_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/singleWhere_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/singleWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/single_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/single_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/skipWhile_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/skip_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/takeWhile_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/take_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/take_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/take_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/toList_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/toSet_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/transform_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/transform_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/where_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/where_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A01_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/asBroadcastStream_A02_t01: RuntimeError # Issue 13921
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t03: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/close_A02_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
+LibTest/isolate/SendPort/send_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A02_t04: Fail # Issue 13921
+LibTest/isolate/SendPort/send_A02_t05: Fail # Issue 13921
+LibTest/isolate/SendPort/send_A02_t06: Fail # Issue 13921
+WebPlatformTest/DOMEvents/approved/EventObject.after.dispatchEvenr_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/DOMEvents/approved/EventObject.multiple.dispatchEvent_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out. co19-roll r738: Please triage this failure.
+WebPlatformTest/DOMEvents/approved/addEventListener.optional.useCapture_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/Utils/test/asyncTestFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/Utils/test/asyncTestFail_t02: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/Utils/test/testFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/Node-replaceChild_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/dom/events/event_constants/constants_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+WebPlatformTest/dom/events/event_constructors/Event_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+WebPlatformTest/dom/events/event_constructors/Event_A02_t01: Skip # co19-roll r706.  Please triage this failure.
+WebPlatformTest/dom/events/type_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/DOMImplementation-createDocumentType_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/DOMImplementation-createDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-adoptNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-createElementNS_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-createElement_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-getElementsByTagName_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Element-childElementCount_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-appendChild_t02: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-insertBefore_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-isEqualNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-nodeName_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/dom/nodes/Node-replaceChild_t01: RuntimeError # co19-roll r722: Please triage this failure
+WebPlatformTest/dom/nodes/Node-textContent_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A06_t03: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t02: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t03: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A08_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttribute_A03_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-imports/link-import-null_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html-imports/link-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html-imports/link-import_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html-imports/loading-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html-templates/innerhtml-on-templates/innerhtml_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/additions-to-the-in-head-insertion-mode/generating-of-implied-end-tags_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-getter_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-setter_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-case_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-namespace_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-newelements_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-param_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t05: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t07: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t02: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t03: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t05: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-delete_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-get_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/disabled-elements/disabledElement_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.LayoutTests/fast/dom/Window/window-resize-contents_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.  Pass on macos.
+WebPlatformTest/html/semantics/forms/the-button-element/button-validation_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-fieldset-element/disabled_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-autocomplete_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-elements-matches_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-elements-nameditem_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-nameditem_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/forms/the-input-element/date_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/datetime-local_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/datetime_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/datetime_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/email_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/email_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/input-textselection_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/month_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/password_t01: RuntimeError # co19-roll r786: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/pattern_attribute_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/forms/the-input-element/range_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/time_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/time_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/type-change-state_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/url_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/week_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-meter-element/meter_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-option-element/option-text-recurse_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-option-element/option-text-spaces_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/grouping-content/the-blockquote-element/grouping-blockquote_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: Skip # co19 issue 11.
+WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-close_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-showModal_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: Skip # co19 issue 11.
+WebPlatformTest/html/semantics/scripting-1/the-script-element/script-text_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/checked_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/default_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/dir_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: Pass, RuntimeError # Spurious pass # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/enabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/indeterminate_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/inrange-outofrange_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/tabular-data/the-tr-element/rowIndex_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/text-level-semantics/the-a-element/a.text-getter_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t02: RuntimeError # co19-roll r786: Please triage this failure.
+WebPlatformTest/html/syntax/parsing/math-parse_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/serializing-html-fragments/outerHTML_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: RuntimeError # Tests APIs that aren't yet visible. Tests should be deleted.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-005_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-006_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-006_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-005_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: RuntimeError # Not clear that any of this works. Also suppressed in dart2js
+WebPlatformTest/shadow-dom/events/event-retargeting/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t02: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-003_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/custom-pseudo-elements/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/webstorage/event_local_key_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/webstorage/event_session_key_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
+WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
 
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid ) && $checked ]
-LayoutTests/fast/html/article-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/aside-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/innerHTML/innerHTML-svg-read_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTableElement/insert-row_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # co19-roll r722: Issue 18251
-WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-
-# co19-roll r738
-WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-enumeration_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/custom/type-extensions_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-
-# co19-roll r761
+Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t05: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t06: RuntimeError # Please triage this failure.
 LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/box-sizing-border-box-dynamic-padding-border-update_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/display-inline-block-scrollbar_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # co19-roll r761: Please triage this failure.
-
-# co19-roll r786
 LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-blocks_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -1119,6 +1092,15 @@
 LayoutTests/fast/css-intrinsic-dimensions/multicol_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-intrinsic-dimensions/tables_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/box-sizing-border-box-dynamic-padding-border-update_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/display-inline-block-scrollbar_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLTableElement/insert-row_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/custom/type-extensions_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
 LayoutTests/fast/filesystem/file-writer-abort_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/file-writer-events_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/op-copy_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -1131,6 +1113,25 @@
 LayoutTests/fast/filesystem/op-restricted-chars_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/op-restricted-names_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/op-restricted-unicode_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/flexbox/flexing-overflow-scroll-item_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/html/article-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/aside-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/innerHTML/innerHTML-svg-read_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-image-threshold_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/css-table-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/fixed-table-layout-width-change_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -1138,33 +1139,26 @@
 LayoutTests/fast/table/margins-flipped-text-direction_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/min-max-width-preferred-size_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/nested-tables-with-div-offset_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/table/table-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/url/trivial-segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/url/trivial_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: RuntimeError # Please triage this failure.
-
-# co19 roll r801
-LayoutTests/fast/flexbox/flexing-overflow-scroll-item_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-image-threshold_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # co19-roll r722: Issue 18251
+WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-enumeration_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
 
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $mode == debug ]
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: Skip # Issue 19495.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index e4edb77..a11b526 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -3,7 +3,12 @@
 # BSD-style license that can be found in the LICENSE file.
 
 
-[ $compiler == none && ($runtime == vm || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler) && (($runtime == vm || $runtime == dart_precompiled) || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+
+# Failures ok in tests below. VM moves super initializer to end of list.
+Language/Classes/Constructors/Generative_Constructors/execution_t03: Fail, OK
+Language/Expressions/Instance_Creation/New/execution_t04: Fail, OK
+Language/Expressions/Instance_Creation/New/execution_t06: Fail, OK
 
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 22200
@@ -11,19 +16,19 @@
 
 LibTest/core/int/toRadixString_A01_t01: Fail # co19 issue 492
 
-Language/03_Overview/1_Scoping_A02_t28: RuntimeError # Issue 21163
-Language/13_Statements/09_Switch_A01_t02: fail # Dart issue 12908
-Language/13_Statements/12_Labels_A01_t03: fail # Dart issue 2238
-Language/14_Libraries_and_Scripts/2_Exports_A04_t02: fail # Dart issue 12916
-Language/14_Libraries_and_Scripts/2_Exports_A04_t03: fail # Dart issue 12916
+Language/Statements/Switch/syntax_t02: fail # Dart issue 12908
+Language/Statements/Labels/syntax_t03: fail # Dart issue 2238
+Language/Libraries_and_Scripts/Exports/reexport_t01: fail # Dart issue 12916
+Language/Libraries_and_Scripts/Exports/reexport_t02: fail # Dart issue 12916
 
-Language/13_Statements/15_Assert_A03_t02: skip # co19 issue 734
-Language/13_Statements/15_Assert_A03_t03: skip # co19 issue 734
-Language/13_Statements/15_Assert_A04_t02: skip # co19 issue 734
-Language/13_Statements/15_Assert_A04_t05: skip # co19 issue 734
+Language/Statements/Assert/execution_t02: skip # co19 issue 734
+Language/Statements/Assert/execution_t03: skip # co19 issue 734
+Language/Statements/Assert/type_t02: skip # co19 issue 734
+Language/Statements/Assert/type_t05: skip # co19 issue 734
 
 
 LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
+LibTest/core/DateTime/parse_A01_t02: Fail # co19 issue 17.
 
 LibTest/core/DateTime/DateTime.now_A01_t02: Pass, Fail # co19 issue 709
 
@@ -38,26 +43,26 @@
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Issue 13596
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Issue 13596
 
-[ $compiler == none && $runtime == vm ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
 LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # co19 issue 599
 LibTest/typed_data/Float32x4/reciprocal_A01_t01: Pass, Fail # co19 issue 599
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: MissingCompileTimeError # Issue 22007
-Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: MissingCompileTimeError # Issue 22007
+Language/Expressions/Instance_Creation/Const/abstract_class_t01: MissingCompileTimeError # Issue 22007
+Language/Expressions/Instance_Creation/Const/abstract_class_t03: MissingCompileTimeError # Issue 22007
 # With asynchronous loading, the load errors in these tests are no longer recognized as compile errors:
-Language/14_Libraries_and_Scripts/1_Imports_A04_t02: Fail
-Language/14_Libraries_and_Scripts/2_Exports_A05_t02: Fail
-Language/14_Libraries_and_Scripts/3_Parts_A01_t06: Fail
+Language/Libraries_and_Scripts/Imports/invalid_uri_t02: Fail
+Language/Libraries_and_Scripts/Exports/invalid_uri_t02: Fail
+Language/Libraries_and_Scripts/Parts/syntax_t06: Fail
 
-[ $runtime == vm ]
+[ ($runtime == vm || $runtime == dart_precompiled) ]
 LibTest/math/MutableRectangle/MutableRectangle.fromPoints_A01_t01: Pass, RuntimeError # co19-roll r607: Please triage this failure
 
-[ $compiler == none && $runtime == vm && $mode == debug ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $mode == debug ]
 LibTest/core/List/List_class_A01_t02: Pass, Slow
 
-[ $compiler == none && $runtime == vm && ($arch != x64 && $arch != simarm64) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch != x64 && $arch != simarm64) ]
 LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
 
-[ $compiler == none && $runtime == vm && $arch == mips ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $arch == mips ]
 LibTest/core/double/toInt_A01_t01: Fail
 # These tests take too much memory (300 MB) for our 1 GB test machine.
 # co19 issue 673. http://code.google.com/p/co19/issues/detail?id=673
@@ -65,25 +70,92 @@
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19 issue 673
 LibTest/collection/ListBase/ListBase_class_A01_t02: Skip # co19 issue 673
 
-[ $compiler == none && $runtime == vm && $arch == mips && $mode == debug ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $mode == debug ]
 LibTest/isolate/Isolate/spawnUri_A01_t04: Crash, Pass # Issue 17440
 LibTest/isolate/Isolate/spawn_A01_t04: Crash, Pass # Issue 17440
 
-[ $compiler == none && $runtime == vm && ($arch == simarm || $arch == simarmv5te || $arch == simmips || $arch == simarm64) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch == simarm || $arch == simarmv5te || $arch == simmips || $arch == simarm64) ]
 LibTest/core/Uri/Uri_A06_t03: Skip  # Timeout
 LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip  # Timeout
 LibTest/collection/ListBase/ListBase_class_A01_t01: Skip  # Timeout
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip  # Timeout
 LibTest/collection/ListBase/ListBase_class_A01_t02: Skip  # Timeout
 
-[ $runtime == vm ]
+[ ($compiler == none || $compiler == precompiler) && $system == windows ]
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Pass, Slow
+LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Slow
+
+[ ($runtime == vm || $runtime == dart_precompiled) ]
 LibTest/isolate/Isolate/spawn_A02_t01: Skip # co19 issue 667
 LibTest/html/*: SkipByDesign # dart:html not supported on VM.
 LayoutTests/fast/*: SkipByDesign # DOM not supported on VM.
 WebPlatformTest/*: SkipByDesign # dart:html not supported on VM.
 
-[ $runtime == vm && $mode == debug && $builder_tag == asan ]
-Language/15_Types/4_Interface_Types_A11_t01: Skip  # Issue 21174.
+[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $builder_tag == asan ]
+Language/Types/Interface_Types/subtype_t27: Skip  # Issue 21174.
 
-[ $runtime == vm && $arch == arm ]
+[ ($runtime == vm || $runtime == dart_precompiled) && $arch == arm ]
 LibTest/typed_data/Float32x4/operator_multiplication_A01_t01: Fail # Dart issue 24416
+
+[ ($runtime == vm || $runtime == dart_precompiled) ]
+# co19 update Sep 29, 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0)
+Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Setters/syntax_t04: RuntimeError # Please triage this failure
+Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure
+Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure
+Language/Classes/Static_Methods/type_object_t02: RuntimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t01: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t02: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t03: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t04: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t05: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/class_object_member_t06: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t01: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t02: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t03: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t04: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t05: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t06: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t07: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/Imports/namespace_changes_t10: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/Parts/compilation_t09: MissingCompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t04: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t05: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t09: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t10: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t14: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/URIs/syntax_t15: RuntimeError # Please triage this failure
+Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure
+Language/Mixins/declaring_constructor_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/not_object_superclass_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/reference_to_super_t01: MissingCompileTimeError # Please triage this failure
+
+[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug ]
+Language/Mixins/Mixin_Application/wrong_type_t02: Crash # Please triage this failure
+
+[ ($runtime == vm || $runtime == dart_precompiled) && $checked ]
+Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t05: RuntimeError # Please triage this failure
+Language/Errors_and_Warnings/static_warning_t06: RuntimeError # Please triage this failure
+
+[ ($noopt || $compiler == precompiler) ]
+LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Pass, Timeout
+LibTest/core/Map/Map_class_A01_t04: Pass, Timeout
+LibTest/core/Uri/encodeQueryComponent_A01_t02: Pass, Timeout
+Language/Mixins/Mixin_Application/error_t01: Pass
+Language/Mixins/Mixin_Application/error_t02: Pass
+Language/Mixins/declaring_constructor_t01: Pass
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/deferred_type_t01: Pass
+Language/Metadata/*: Skip # Uses dart:mirrors
+
+[ $runtime == dart_precompiled ]
+LibTest/isolate/Isolate/spawnUri*: RuntimeError # Isolate.spawnUri
diff --git a/tests/compiler/dart2js/analyze_all_test.dart b/tests/compiler/dart2js/analyze_all_test.dart
index 2d72c76..7039f93 100644
--- a/tests/compiler/dart2js/analyze_all_test.dart
+++ b/tests/compiler/dart2js/analyze_all_test.dart
@@ -2,9 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import "package:expect/expect.dart";
-import "compiler_helper.dart";
-import "package:async_helper/async_helper.dart";
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/diagnostics/messages.dart';
+import 'package:expect/expect.dart';
+import 'memory_compiler.dart';
 
 const String SOURCE = """
 class Foo {
@@ -27,30 +30,85 @@
 }
 """;
 
+Future<DiagnosticCollector> run(
+    String source,
+    {bool analyzeAll,
+     bool expectSuccess}) async {
+  DiagnosticCollector collector = new DiagnosticCollector();
+
+  List<String> options = [];
+  if (analyzeAll) {
+    options.add(Flags.analyzeAll);
+  } else {
+    options.add(Flags.analyzeOnly);
+  }
+  CompilationResult result = await runCompiler(
+      memorySourceFiles: {'main.dart': source},
+      diagnosticHandler: collector,
+      options: options);
+  Expect.equals(expectSuccess, result.isSuccess);
+  return collector;
+}
+
+test1() async {
+  DiagnosticCollector collector =
+      await run(SOURCE, analyzeAll: false, expectSuccess: true);
+  Expect.isTrue(collector.warnings.isEmpty,
+      'Unexpected warnings: ${collector.warnings}');
+  Expect.isTrue(collector.errors.isEmpty,
+      'Unexpected errors: ${collector.errors}');
+}
+
+test2() async {
+  DiagnosticCollector collector =
+      await run(SOURCE, analyzeAll: true, expectSuccess: false);
+
+  Expect.isTrue(collector.warnings.isEmpty,
+                'unexpected warnings: ${collector.warnings}');
+  Expect.equals(2, collector.errors.length,
+                'expected exactly two errors, but got ${collector.errors}');
+
+  CollectedMessage first = collector.errors.first;
+  Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST, first.message.kind);
+  Expect.equals("Foo", SOURCE.substring(first.begin, first.end));
+
+  CollectedMessage second = collector.errors.elementAt(1);
+  Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST, second.message.kind);
+  Expect.equals("Foo", SOURCE.substring(second.begin, second.end));
+}
+
+// This is a regression test, testing that we can handle annotations on
+// malformed elements. Depending on the order of analysis, annotations on such
+// elements might not be resolved which caused a crash when trying to detect
+// a `@NoInline()` annotation.
+test3() async {
+  String source = '''
+import 'package:expect/expect.dart';
+
+class A {
+  @NoInline
+  m() {
+    => print(0);
+  }
+}
+
+@NoInline()
+main() => new A().m();
+''';
+
+  DiagnosticCollector collector =
+      await run(source, analyzeAll: true, expectSuccess: false);
+
+  Expect.isTrue(collector.warnings.isEmpty,
+                'unexpected warnings: ${collector.warnings}');
+  Expect.equals(1, collector.errors.length,
+                'expected exactly one error, but got ${collector.errors}');
+}
+
 main() {
-  Uri uri = Uri.parse('test:code');
-  var compiler1 = compilerFor(SOURCE, uri, analyzeAll: false);
-  asyncTest(() => compiler1.runCompiler(uri).then((_) {
-    Expect.isFalse(compiler1.compilationFailed);
-    print(compiler1.warnings);
-    Expect.isTrue(compiler1.warnings.isEmpty, 'unexpected warnings');
-    Expect.isTrue(compiler1.errors.isEmpty, 'unexpected errors');
-  }));
-
-  var compiler2 = compilerFor(SOURCE, uri, analyzeAll: true);
-  asyncTest(() => compiler2.runCompiler(uri).then((_) {
-    Expect.isTrue(compiler2.compilationFailed);
-    Expect.isTrue(compiler2.warnings.isEmpty,
-                  'unexpected warnings: ${compiler2.warnings}');
-    Expect.equals(2, compiler2.errors.length,
-                  'expected exactly two errors, but got ${compiler2.errors}');
-
-    Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST,
-                  compiler2.errors[0].message.kind);
-    Expect.equals("Foo", compiler2.errors[0].node.toString());
-
-    Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST,
-                  compiler2.errors[1].message.kind);
-    Expect.equals("Foo", compiler2.errors[1].node.toString());
-  }));
+  asyncTest(() async {
+    await test1();
+    await test2();
+    await test3();
+  });
 }
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index 91b4ae2..d4f2f9f 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -29,5 +29,5 @@
       uriList.add(new Uri(scheme: 'dart', path: name));
     }
   });
-  asyncTest(() => analyze(uriList, WHITE_LIST));
+  asyncTest(() => analyze(uriList, WHITE_LIST, mode: AnalysisMode.ALL));
 }
diff --git a/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart b/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
index 0787dd3..e4b9326 100644
--- a/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
+++ b/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/compiler_new.dart' show
     Diagnostic;
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/constants/expressions.dart' show
     ConstructedConstantExpression;
@@ -44,7 +44,7 @@
     options.add(Flags.verbose);
   }
   asyncTest(() async {
-    Compiler compiler = compilerFor(
+    CompilerImpl compiler = compilerFor(
         options: options, showDiagnostics: verbose);
     FormattingDiagnosticHandler diagnostics =
         new FormattingDiagnosticHandler(compiler.provider);
diff --git a/tests/compiler/dart2js/analyze_helper.dart b/tests/compiler/dart2js/analyze_helper.dart
index 7d84392..41dc321 100644
--- a/tests/compiler/dart2js/analyze_helper.dart
+++ b/tests/compiler/dart2js/analyze_helper.dart
@@ -10,7 +10,8 @@
 import 'package:compiler/src/apiimpl.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/diagnostics/messages.dart' show
-    Message;
+    Message,
+    MessageKind;
 import 'package:compiler/src/filenames.dart';
 import 'package:compiler/src/source_file_provider.dart';
 import 'package:compiler/src/util/uri_extras.dart';
@@ -33,15 +34,16 @@
   bool hasErrors = false;
   bool lastWasWhitelisted = false;
 
-  Map<String, Map<String, int>> whiteListMap
-      = new Map<String, Map<String, int>>();
+  Map<String, Map<dynamic/*String|MessageKind*/, int>> whiteListMap
+      = new Map<String, Map<dynamic/*String|MessageKind*/, int>>();
 
-  CollectingDiagnosticHandler(Map<String, List<String>> whiteList,
-                              SourceFileProvider provider)
+  CollectingDiagnosticHandler(
+      Map<String, List/*<String|MessageKind>*/> whiteList,
+      SourceFileProvider provider)
       : super(provider) {
-    whiteList.forEach((String file, List<String> messageParts) {
-      var useMap = new Map<String,int>();
-      for (String messagePart in messageParts) {
+    whiteList.forEach((String file, List/*<String|MessageKind>*/ messageParts) {
+      var useMap = new Map<dynamic/*String|MessageKind*/, int>();
+      for (var messagePart in messageParts) {
         useMap[messagePart] = 0;
       }
       whiteListMap[file] = useMap;
@@ -57,7 +59,7 @@
   bool checkWhiteListUse() {
     bool allUsed = true;
     for (String file in whiteListMap.keys) {
-      for (String messagePart in whiteListMap[file].keys) {
+      for (var messagePart in whiteListMap[file].keys) {
         if (whiteListMap[file][messagePart] == 0) {
           print("Whitelisting '$messagePart' is unused in '$file'. "
                 "Remove the whitelisting from the whitelist map.");
@@ -70,7 +72,7 @@
 
   void reportWhiteListUse() {
     for (String file in whiteListMap.keys) {
-      for (String messagePart in whiteListMap[file].keys) {
+      for (var messagePart in whiteListMap[file].keys) {
         int useCount = whiteListMap[file][messagePart];
         print("Whitelisted message '$messagePart' suppressed $useCount "
               "time(s) in '$file'.");
@@ -78,15 +80,22 @@
     }
   }
 
-  bool checkWhiteList(Uri uri, String message) {
+  bool checkWhiteList(Uri uri, Message message, String text) {
     if (uri == null) {
       return false;
     }
     String path = uri.path;
     for (String file in whiteListMap.keys) {
       if (path.contains(file)) {
-        for (String messagePart in whiteListMap[file].keys) {
-          if (message.contains(messagePart)) {
+        for (var messagePart in whiteListMap[file].keys) {
+          bool found = false;
+          if (messagePart is String) {
+            found = text.contains(messagePart);
+          } else {
+            assert(messagePart is MessageKind);
+            found = message.kind == messagePart;
+          }
+          if (found) {
             whiteListMap[file][messagePart]++;
             return true;
           }
@@ -100,7 +109,7 @@
   void report(Message message, Uri uri, int begin, int end, String text,
               api.Diagnostic kind) {
     if (kind == api.Diagnostic.WARNING) {
-      if (checkWhiteList(uri, text)) {
+      if (checkWhiteList(uri, message, text)) {
         // Suppress whitelisted warnings.
         lastWasWhitelisted = true;
         return;
@@ -108,7 +117,7 @@
       hasWarnings = true;
     }
     if (kind == api.Diagnostic.HINT) {
-      if (checkWhiteList(uri, text)) {
+      if (checkWhiteList(uri, message, text)) {
         // Suppress whitelisted hints.
         lastWasWhitelisted = true;
         return;
@@ -116,7 +125,7 @@
       hasHint = true;
     }
     if (kind == api.Diagnostic.ERROR) {
-      if (checkWhiteList(uri, text)) {
+      if (checkWhiteList(uri, message, text)) {
         // Suppress whitelisted errors.
         lastWasWhitelisted = true;
         return;
@@ -131,14 +140,25 @@
   }
 }
 
-typedef bool CheckResults(Compiler compiler,
+typedef bool CheckResults(CompilerImpl compiler,
                           CollectingDiagnosticHandler handler);
 
+enum AnalysisMode {
+  /// Analyze all declarations in all libraries in one go.
+  ALL,
+  /// Analyze all declarations in the main library.
+  MAIN,
+  /// Analyze all declarations in the given URIs one at a time. This mode can
+  /// handle URIs for parts (i.e. skips these).
+  URI,
+  /// Analyze all declarations reachable from the entry point.
+  TREE_SHAKING,
+}
+
 Future analyze(List<Uri> uriList,
-               Map<String, List<String>> whiteList,
-               {bool analyzeAll: true,
-                bool analyzeMain: false,
-                CheckResults checkResults}) {
+               Map<String, List/*<String|MessageKind>*/> whiteList,
+               {AnalysisMode mode: AnalysisMode.ALL,
+                CheckResults checkResults}) async {
   String testFileName =
       relativize(Uri.base, Platform.script, Platform.isWindows);
 
@@ -154,14 +174,23 @@
 
   var libraryRoot = currentDirectory.resolve('sdk/');
   var packageRoot =
-      currentDirectory.resolveUri(new Uri.file('${Platform.packageRoot}/'));
+      currentDirectory.resolve(Platform.packageRoot);
   var provider = new CompilerSourceFileProvider();
   var handler = new CollectingDiagnosticHandler(whiteList, provider);
   var options = <String>[Flags.analyzeOnly, '--categories=Client,Server',
       Flags.showPackageWarnings];
-  if (analyzeAll) options.add(Flags.analyzeAll);
-  if (analyzeMain) options.add(Flags.analyzeMain);
-  var compiler = new Compiler(
+  switch (mode) {
+    case AnalysisMode.URI:
+    case AnalysisMode.MAIN:
+      options.add(Flags.analyzeMain);
+      break;
+    case AnalysisMode.ALL:
+      options.add(Flags.analyzeAll);
+      break;
+    case AnalysisMode.TREE_SHAKING:
+      break;
+  }
+  var compiler = new CompilerImpl(
       provider,
       null,
       handler,
@@ -179,22 +208,25 @@
 ===
 """;
 
-  void onCompletion(_) {
-    bool result;
-    if (checkResults != null) {
-      result = checkResults(compiler, handler);
-    } else {
-      result = handler.checkResults();
+  if (mode == AnalysisMode.URI) {
+    for (Uri uri in uriList) {
+      await compiler.analyzeUri(uri);
     }
-    if (!result) {
-      print(MESSAGE);
-      exit(1);
-    }
-  }
-  if (analyzeAll || analyzeMain) {
+  } else if (mode != AnalysisMode.TREE_SHAKING) {
     compiler.librariesToAnalyzeWhenRun = uriList;
-    return compiler.run(null).then(onCompletion);
+    await compiler.run(null);
   } else {
-    return compiler.run(uriList.single).then(onCompletion);
+    await compiler.run(uriList.single);
+  }
+
+  bool result;
+  if (checkResults != null) {
+    result = checkResults(compiler, handler);
+  } else {
+    result = handler.checkResults();
+  }
+  if (!result) {
+    print(MESSAGE);
+    exit(1);
   }
 }
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index 08100a6..2d771fb 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -49,8 +49,8 @@
               localProvider, localHandler, options, outputCollector);
   result.then((_) {
     onValue(outputCollector.getOutput('', 'js'), errors, warnings);
-  }, onError: (e) {
-    throw 'Compilation failed: ${Error.safeToString(e)}';
+  }, onError: (e, st) {
+    throw 'Compilation failed: ${e} ${st}';
   }).then(asyncSuccess).catchError((error, stack) {
     print('\n\n-----------------------------------------------');
     print('main source:\n$main');
diff --git a/tests/compiler/dart2js/analyze_test_test.dart b/tests/compiler/dart2js/analyze_test_test.dart
new file mode 100644
index 0000000..f2565ac
--- /dev/null
+++ b/tests/compiler/dart2js/analyze_test_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.analyze_test.test;
+
+import 'dart:io';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/apiimpl.dart' show
+    CompilerImpl;
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/diagnostics/messages.dart' show
+    MessageKind;
+import 'package:compiler/src/filenames.dart' show
+    nativeToUriPath;
+
+import 'analyze_helper.dart';
+import 'memory_compiler.dart';
+
+/**
+ * Map of white-listed warnings and errors.
+ *
+ * Use an identifiable suffix of the file uri as key. Use a fixed substring of
+ * the error/warning message in the list of white-listings for each file.
+ */
+// TODO(johnniwinther): Support canonical URIs as keys and message kinds as
+// values.
+const Map<String, List/*<String|MessageKind>*/> WHITE_LIST = const {
+  // Several tests import mirrors; any of these might trigger the warning.
+  ".dart": const [
+      MessageKind.IMPORT_EXPERIMENTAL_MIRRORS,
+  ],
+  "/test/src/util/": const [
+      "Library 'package:async/async.dart' doesn't export a "
+      "'ForkableStream' declaration.",
+  ],
+  "mirrors_test.dart": const [
+      MessageKind.INVALID_SYMBOL,
+      MessageKind.PRIVATE_IDENTIFIER,
+  ],
+};
+
+const List<String> SKIP_LIST = const <String>[
+  // Helper files:
+  "dart2js_batch2_run.dart",
+  "http_launch_data/",
+  "mirrors_helper.dart",
+  "path%20with%20spaces/",
+  "one_line_dart_program.dart",
+  "sourcemaps/invokes_test_file.dart",
+  "cps_ir/input/",
+  // No longer maintained:
+  "backend_dart/",
+  // Broken tests:
+  "http_test.dart",
+];
+
+main(List<String> arguments) {
+  bool verbose = arguments.contains('-v');
+
+  List<String> options = <String>[
+    Flags.analyzeOnly,
+    Flags.analyzeMain,
+    '--categories=Client,Server'];
+  if (verbose) {
+    options.add(Flags.verbose);
+  }
+  asyncTest(() async {
+    List<Uri> uriList = <Uri>[];
+    Directory dir =
+        new Directory.fromUri(Uri.base.resolve('tests/compiler/dart2js/'));
+    for (FileSystemEntity entity in dir.listSync(recursive: true)) {
+      if (entity is File && entity.path.endsWith('.dart')) {
+        Uri file = Uri.base.resolve(nativeToUriPath(entity.path));
+        if (!SKIP_LIST.any((skip) => file.path.contains(skip))) {
+          uriList.add(file);
+        }
+      }
+    }
+    await analyze(uriList, WHITE_LIST, mode: AnalysisMode.URI);
+  });
+}
diff --git a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
index 90fc59b2..8106a06 100644
--- a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
@@ -76,7 +76,7 @@
       // TODO(johnniwinther): Use [WHITE_LIST] again when
       // [Compiler.reportUnusedCode] is reenabled.
       const {}, // WHITE_LIST
-      analyzeAll: false,
+      mode: AnalysisMode.TREE_SHAKING,
       checkResults: checkResults));
 }
 
diff --git a/tests/compiler/dart2js/async_await_js_transform_test.dart b/tests/compiler/dart2js/async_await_js_transform_test.dart
index d0f4c85..40c9eb6 100644
--- a/tests/compiler/dart2js/async_await_js_transform_test.dart
+++ b/tests/compiler/dart2js/async_await_js_transform_test.dart
@@ -64,12 +64,13 @@
       switch (__goto) {
         case 0:
           // Function start
+          closures = [new A.main_closure()];
           __goto = 2;
-        closures = [new A.main_closure()];
-        return thenHelper(closures, body, __completer);
+          return thenHelper(closures, body, __completer);
         case 2:
           // returning from await.
-          v0 = __result, v1 = 0;
+          v0 = __result;
+          v1 = 0;
           if (v1 < 0 || v1 >= v0.length)
             H.ioore(v0, v1);
           else
diff --git a/tests/compiler/dart2js/async_await_syntax_test.dart b/tests/compiler/dart2js/async_await_syntax_test.dart
index fd21a0d..af4ae5a 100644
--- a/tests/compiler/dart2js/async_await_syntax_test.dart
+++ b/tests/compiler/dart2js/async_await_syntax_test.dart
@@ -14,9 +14,9 @@
 /// includes the multitest in 'language/async_await_syntax_test.dart' but
 /// expects the subtests 'a03b' and 'a04c' to fail.
 const Map<String, List<String>> TESTS = const <String, List<String>>{
-  'language/async_await_syntax_test.dart': const ['a05h', 'c11a', 'c11b'],
+  'language/async_await_syntax_test.dart': const [],
 };
 
 void main(List<String> arguments) {
-  check(TESTS, arguments: arguments, options: ['--enable-async']);
+  check(TESTS, arguments: arguments, options: []);
 }
diff --git a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart b/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
index 597f056..5db4160 100644
--- a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
+++ b/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
@@ -4,6 +4,7 @@
 
 import "package:expect/expect.dart";
 import 'dart:async';
+import 'dart:io' as io;
 import "package:async_helper/async_helper.dart";
 import '../mock_compiler.dart';
 import '../mock_libraries.dart';
@@ -58,7 +59,9 @@
     if (uri.toString() == libUri.toString()) {
       return new Future.value(librarySrc);
     }
-    if (uri.path.endsWith('/core.dart')) {
+    if (uri.path.endsWith('/dart2dart.platform')) {
+      return new io.File.fromUri(uri).readAsBytes();
+    } else if (uri.path.endsWith('/core.dart')) {
       return new Future.value(buildLibrarySource(DEFAULT_CORE_LIBRARY));
     } else if (uri.path.endsWith('/core_patch.dart')) {
       return new Future.value(DEFAULT_PATCH_CORE_SOURCE);
@@ -87,7 +90,6 @@
 
   final options = <String>['--output-type=dart'];
   // Some tests below are using dart:io.
-  options.add('--categories=Client,Server');
   if (minify) options.add('--minify');
   if (stripTypes) options.add('--force-strip=types');
 
@@ -95,7 +97,7 @@
     OutputCollector outputCollector = new OutputCollector();
     return compile(
         scriptUri,
-        fileUri('libraryRoot/'),
+        Uri.base.resolve('sdk/'),
         fileUri('packageRoot/'),
         provider,
         handler,
diff --git a/tests/compiler/dart2js/bad_loop_test.dart b/tests/compiler/dart2js/bad_loop_test.dart
index bd1053c..c1b2a6d 100644
--- a/tests/compiler/dart2js/bad_loop_test.dart
+++ b/tests/compiler/dart2js/bad_loop_test.dart
@@ -33,7 +33,7 @@
     }
   }
 
-  Compiler compiler = new Compiler(
+  CompilerImpl compiler = new CompilerImpl(
       new LegacyCompilerInput(provider.readStringFromUri),
       new LegacyCompilerOutput(),
       new LegacyCompilerDiagnostics(diagnosticHandler),
diff --git a/tests/compiler/dart2js/bad_output_io_test.dart b/tests/compiler/dart2js/bad_output_io_test.dart
index 7815b59..6f11981 100644
--- a/tests/compiler/dart2js/bad_output_io_test.dart
+++ b/tests/compiler/dart2js/bad_output_io_test.dart
@@ -4,7 +4,7 @@
 
 // Test that the compiler can handle imports when package root has not been set.
 
-library dart2js.test.missing_file;
+library dart2js.test.bad_output_io;
 
 import 'dart:io' show exit;
 import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/benign_error_test.dart b/tests/compiler/dart2js/benign_error_test.dart
new file mode 100644
index 0000000..28c84dd
--- /dev/null
+++ b/tests/compiler/dart2js/benign_error_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that benign error do not prevent compilation.
+
+import 'memory_compiler.dart';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/diagnostics/messages.dart';
+import 'package:compiler/src/js_backend/js_backend.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  asyncTest(() async {
+    for (MessageKind kind in Compiler.BENIGN_ERRORS) {
+      await testExamples(kind);
+    }
+  });
+}
+
+testExamples(MessageKind kind) async {
+  MessageTemplate template = MessageTemplate.TEMPLATES[kind];
+  for (var example in template.examples) {
+    if (example is! Map) {
+      example = {'main.dart': example};
+    }
+    DiagnosticCollector collector = new DiagnosticCollector();
+    CompilationResult result = await runCompiler(
+        memorySourceFiles: example,
+        diagnosticHandler: collector);
+    Expect.isTrue(result.isSuccess);
+    Expect.isTrue(
+        collector.errors.any((message) => message.messageKind == kind));
+    Compiler compiler = result.compiler;
+    JavaScriptBackend backend = compiler.backend;
+    Expect.isNotNull(backend.generatedCode[compiler.mainFunction]);
+  }
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/boolify_test.dart b/tests/compiler/dart2js/boolify_test.dart
index 6536386..7d2a7b9 100644
--- a/tests/compiler/dart2js/boolify_test.dart
+++ b/tests/compiler/dart2js/boolify_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library boolified_operator_test;
+library boolify_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
diff --git a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
index 41ed1ba..517a347 100644
--- a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
@@ -16,7 +16,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(code, uri);
   compiler.disableInlining = disableInlining;
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var cls = findElement(compiler, className);
     var member = cls.lookupLocalMember(memberName);
     return check(compiler, member);
diff --git a/tests/compiler/dart2js/categories_test.dart b/tests/compiler/dart2js/categories_test.dart
index 3b22453..677d1a8 100644
--- a/tests/compiler/dart2js/categories_test.dart
+++ b/tests/compiler/dart2js/categories_test.dart
@@ -19,17 +19,13 @@
 
 void main() {
   asyncTest(() async {
-    await runTest("import 'dart:async'; main() {}", "Embedded", 1);
     await runTest("import 'dart:async'; main() {}", "Client", 0);
     await runTest("import 'dart:async'; main() {}", "Server", 0);
-    await runTest("import 'dart:html'; main() {}", "Embedded", 1);
     await runTest("import 'dart:html'; main() {}", "Client", 0);
     await runTest("import 'dart:html'; main() {}", "Server", 1);
-    await runTest("import 'dart:io'; main() {}", "Embedded", 1);
     await runTest("import 'dart:io'; main() {}", "Client", 1);
     await runTest("import 'dart:io'; main() {}", "Server", 0);
-    await runTest("import 'dart:_internal'; main() {}", "Embedded", 2);
-    await runTest("import 'dart:_internal'; main() {}", "Client", 2);
-    await runTest("import 'dart:_internal'; main() {}", "Server", 2);
+    await runTest("import 'dart:_internal'; main() {}", "Client", 1);
+    await runTest("import 'dart:_internal'; main() {}", "Server", 1);
   });
 }
diff --git a/tests/compiler/dart2js/check_elements_invariants_test.dart b/tests/compiler/dart2js/check_elements_invariants_test.dart
index bc1314f..7216a05 100644
--- a/tests/compiler/dart2js/check_elements_invariants_test.dart
+++ b/tests/compiler/dart2js/check_elements_invariants_test.dart
@@ -20,7 +20,7 @@
       '--disable-type-inference'
     ];
 
-Iterable<ClassElement> computeLiveClasses(Compiler compiler) {
+Iterable<ClassElement> computeLiveClasses(CompilerImpl compiler) {
   return new Set<ClassElement>()
       ..addAll(compiler.resolverWorld.directlyInstantiatedClasses)
       ..addAll(compiler.codegenWorld.directlyInstantiatedClasses);
diff --git a/tests/compiler/dart2js/check_members_test.dart b/tests/compiler/dart2js/check_members_test.dart
index fff8a93..a8271be 100644
--- a/tests/compiler/dart2js/check_members_test.dart
+++ b/tests/compiler/dart2js/check_members_test.dart
@@ -14,38 +14,61 @@
 /// the warnings of each category.
 const Map<String, dynamic> TESTS = const {
   // Instance methods.
-    'co19/src/Language/07_Classes/1_Instance_Methods_A01_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A01_t02.dart': null,
-
     'language/check_method_override_test.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A06_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A06_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_more_parameters_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_more_parameters_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_fewer_parameters_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_fewer_parameters_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t03.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t04.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t05.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_named_parameters_t06.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t03.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t04.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t05.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'override_subtype_t06.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t01.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t02.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t04.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t05.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t06.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t07.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t08.dart': null,
+    'co19/src/Language/Classes/Instance_Methods/'
+        'same_name_static_member_in_superclass_t09.dart': null,
 
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t02.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t03.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t04.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t05.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t06.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t02.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t03.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t04.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t05.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t06.dart': null,
-
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t01.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t02.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t04.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t05.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t06.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t07.dart': null,
-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t08.dart': null,
   // Getters.
-    'co19/src/Language/07_Classes/2_Getters_A05_t01.dart': null,
-    'co19/src/Language/07_Classes/2_Getters_A05_t02.dart': null,
-    'co19/src/Language/07_Classes/2_Getters_A05_t03.dart': null,
-    'co19/src/Language/07_Classes/2_Getters_A05_t04.dart': null,
+    'co19/src/Language/Classes/Getters/override_t01.dart': null,
+    'co19/src/Language/Classes/Getters/override_t02.dart': null,
+    'co19/src/Language/Classes/Getters/override_t03.dart': null,
+    'co19/src/Language/Classes/Getters/override_t04.dart': null,
 };
 
 void main() {
diff --git a/tests/compiler/dart2js/class_set_test.dart b/tests/compiler/dart2js/class_set_test.dart
index c3ee031..d88745d 100644
--- a/tests/compiler/dart2js/class_set_test.dart
+++ b/tests/compiler/dart2js/class_set_test.dart
@@ -4,7 +4,7 @@
 
 // Test for iterators on for [SubclassNode].
 
-library world_test;
+library class_set_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
@@ -12,6 +12,7 @@
 import 'package:compiler/src/elements/elements.dart'
        show Element, ClassElement;
 import 'package:compiler/src/universe/class_set.dart';
+import 'package:compiler/src/util/enumset.dart';
 import 'package:compiler/src/util/util.dart';
 import 'package:compiler/src/world.dart';
 
@@ -131,7 +132,8 @@
     }
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(G)).iterator;
+        world.getClassHierarchyNode(G),
+        ClassHierarchyNode.ALL).iterator;
     checkState(G, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -143,6 +145,7 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(G),
+        ClassHierarchyNode.ALL,
         includeRoot: false).iterator;
     checkState(G, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
@@ -151,7 +154,8 @@
     Expect.isNull(iterator.current);
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(C)).iterator;
+        world.getClassHierarchyNode(C),
+        ClassHierarchyNode.ALL).iterator;
     checkState(C, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -171,7 +175,8 @@
     Expect.isNull(iterator.current);
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(D)).iterator;
+        world.getClassHierarchyNode(D),
+        ClassHierarchyNode.ALL).iterator;
     checkState(D, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -182,7 +187,8 @@
     Expect.isNull(iterator.current);
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(B)).iterator;
+        world.getClassHierarchyNode(B),
+        ClassHierarchyNode.ALL).iterator;
     checkState(B, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -197,6 +203,7 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(B),
+        ClassHierarchyNode.ALL,
         includeRoot: false).iterator;
     checkState(B, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
@@ -209,7 +216,9 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(B),
-        includeIndirectlyInstantiated: false).iterator;
+        new EnumSet<Instantiation>.fromValues(<Instantiation>[
+            Instantiation.DIRECTLY_INSTANTIATED,
+            Instantiation.UNINSTANTIATED])).iterator;
     checkState(B, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -220,7 +229,8 @@
     Expect.isNull(iterator.current);
 
     iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(A)).iterator;
+        world.getClassHierarchyNode(A),
+        ClassHierarchyNode.ALL).iterator;
     checkState(A, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -250,6 +260,7 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(A),
+        ClassHierarchyNode.ALL,
         includeRoot: false).iterator;
     checkState(A, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
@@ -277,7 +288,9 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(A),
-        includeIndirectlyInstantiated: false).iterator;
+        new EnumSet<Instantiation>.fromValues(<Instantiation>[
+            Instantiation.DIRECTLY_INSTANTIATED,
+            Instantiation.UNINSTANTIATED])).iterator;
     checkState(A, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -304,8 +317,10 @@
 
     iterator = new ClassHierarchyNodeIterable(
         world.getClassHierarchyNode(A),
-        includeRoot: false,
-        includeIndirectlyInstantiated: false).iterator;
+        new EnumSet<Instantiation>.fromValues(<Instantiation>[
+            Instantiation.DIRECTLY_INSTANTIATED,
+            Instantiation.UNINSTANTIATED]),
+        includeRoot: false).iterator;
     checkState(A, currentNode: null, stack: null);
     Expect.isNull(iterator.current);
     Expect.isTrue(iterator.moveNext());
@@ -328,3 +343,4 @@
     Expect.isNull(iterator.current);
   }));
 }
+
diff --git a/tests/compiler/dart2js/closure_tracer_test.dart b/tests/compiler/dart2js/closure_tracer_test.dart
index 8053c01..86d1e2f 100644
--- a/tests/compiler/dart2js/closure_tracer_test.dart
+++ b/tests/compiler/dart2js/closure_tracer_test.dart
@@ -153,7 +153,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
diff --git a/tests/compiler/dart2js/codegen_helper.dart b/tests/compiler/dart2js/codegen_helper.dart
index 36fadff..c99fc49 100644
--- a/tests/compiler/dart2js/codegen_helper.dart
+++ b/tests/compiler/dart2js/codegen_helper.dart
@@ -16,7 +16,7 @@
   var provider = new MemorySourceFileProvider({ 'main.dart': code });
   var handler = new FormattingDiagnosticHandler(provider);
 
-  Compiler compiler = new Compiler(provider,
+  CompilerImpl compiler = new CompilerImpl(provider,
                                    const NullCompilerOutput(),
                                    handler,
                                    libraryRoot,
diff --git a/tests/compiler/dart2js/compile_with_empty_libraries_test.dart b/tests/compiler/dart2js/compile_with_empty_libraries_test.dart
index b133d85..6f6a94a 100644
--- a/tests/compiler/dart2js/compile_with_empty_libraries_test.dart
+++ b/tests/compiler/dart2js/compile_with_empty_libraries_test.dart
@@ -14,5 +14,5 @@
   Uri uri = new Uri(scheme: 'source');
   MockCompiler compiler =
     new MockCompiler.internal(librariesOverride: (_) => '');
-  asyncTest(() => compiler.runCompiler(uri));
+  asyncTest(() => compiler.run(uri));
 }
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index 2604401..bef0984 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -156,9 +156,10 @@
       expectedWarnings: expectedWarnings,
       outputProvider: outputCollector);
   compiler.diagnosticHandler = createHandler(compiler, code);
-  return compiler.runCompiler(uri).then((_) {
-    Expect.isFalse(compiler.compilationFailed,
-                   'Unexpected compilation error(s): ${compiler.errors}');
+  return compiler.run(uri).then((compilationSucceded) {
+    Expect.isTrue(compilationSucceded,
+                  'Unexpected compilation error(s): '
+                  '${compiler.diagnosticCollector.errors}');
     return outputCollector.getOutput('', 'js');
   });
 }
@@ -171,7 +172,7 @@
   MockCompiler compiler = compilerFor(code, uri,
       expectedErrors: expectedErrors,
       expectedWarnings: expectedWarnings);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     lego.Element element = findElement(compiler, name);
     return check(compiler, element);
   });
@@ -189,7 +190,7 @@
     compiler.registerSource(base.resolve(path), code);
   });
 
-  return compiler.runCompiler(mainUri).then((_) {
+  return compiler.run(mainUri).then((_) {
     return check(compiler);
   });
 }
@@ -210,7 +211,7 @@
   var sourceName = name;
   var element = compiler.mainApp.find(sourceName);
   if (element == null) {
-    element = compiler.backend.interceptorsLibrary.find(sourceName);
+    element = compiler.backend.helpers.interceptorsLibrary.find(sourceName);
   }
   if (element == null) {
     element = compiler.coreLibrary.find(sourceName);
diff --git a/tests/compiler/dart2js/compiler_test.dart b/tests/compiler/dart2js/compiler_test.dart
index 74f9b17..691b86b 100644
--- a/tests/compiler/dart2js/compiler_test.dart
+++ b/tests/compiler/dart2js/compiler_test.dart
@@ -62,7 +62,7 @@
     compiler.reporter.setOnWarning(
         (c, n, m) => Expect.equals(foo, compiler.currentElement));
     foo.computeType(compiler.resolution);
-    Expect.equals(1, compiler.warnings.length);
+    Expect.equals(1, compiler.diagnosticCollector.warnings.length);
   });
 }
 
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index 8a53a44..c245deb 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -11,7 +11,7 @@
                     check(compiler, element)) {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(code, uri);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     var element = findElement(compiler, name);
     check(compiler, element);
   });
diff --git a/tests/compiler/dart2js/cps_ir/README.md b/tests/compiler/dart2js/cps_ir/README.md
new file mode 100644
index 0000000..1106a72
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/README.md
@@ -0,0 +1,78 @@
+# CPS IR unit tests
+
+This folder contains unit tests of the CPS IR. These tests run the compiler with
+the cps IR and check for the output of a specific function (typically main).
+
+To make our lives easier, most files here are autogenerated. You should never
+have to edit a file under `expected/` or any file with an `AUTOGENERATED` header
+(including the `_test.dart` files).
+
+See instructions below to add or update tests.
+
+### Adding a new test
+
+Every test has 3 files: an input file, a test runner file, and an expectation
+file. The last two are auto-generated.  Here is how:
+
+* add a file under `input/` with a unique name, such as `foo_bar.dart`. Do not
+  include `_test` in the name of this file, otherwise the test framework will
+  think this test needs to be run directly in the vm and in a browser, that's
+  not our goal.
+
+* generate the corresponding test file, by running the `up_to_date_test.dart`
+  passing `update` as an argument:
+
+```bash
+dart tests/compiler/dart2js/cps_ir/up_to_date_test.dart update
+```
+
+  This will generate a file `foo_bar_test.dart` on this folder.
+
+* generate the expectations of the test file by running the generated test file
+  with `update` as an argument:
+
+```bash
+dart --package-root=out/ReleaseX64/packages tests/compiler/dart2js/cps_ir/foo_bar_test.dart update
+```
+
+  This will generate a file `expected/foo_bar.js` with the expected output.
+
+### Checking a method other than main
+
+By default, the test expectations will be generated to contain just the body of
+the main function. If you wish to check for a different element, include a
+comment at the top of the input test like this:
+```dart
+// Method to test: function(foo)
+```
+The trailing text should match the string representation of a compiler element.
+
+**Note**: this format will likely change in the future. We would like to have a
+canonical way to refer to elements that is independent of the internal compiler
+implementation, we also want a way to specify more than just one element, and a
+way to specify that an element has been tree-shaken.
+
+### Updating a single test expectation
+
+To update the expectations of a test, simply regenerate it by running the test
+file with `update` as an argument:
+
+```bash
+dart --package-root=out/ReleaseX64/packages tests/compiler/dart2js/cps_ir/foo_bar_test.dart update
+```
+
+This will override the file `expected/foo_bar.js` file with the new output.
+
+If a test fails because the expectations are out of date, you'll see this
+suggestion in the failure message too.
+
+### Updating all test expectations
+
+For convenience, we also provide a script to update all expectations at once.
+
+```bash
+dart --package-root=out/ReleaseX64/packages tests/compiler/dart2js/cps_ir/update_all.dart
+```
+
+It is equivalent to update each test individually. This script can be handy when
+making cross-cutting changes that affect the output of most tests.
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_10_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_10_test.dart
new file mode 100644
index 0000000..7e6129f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_11_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_11_test.dart
new file mode 100644
index 0000000..90e4293
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_12_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_12_test.dart
new file mode 100644
index 0000000..a170a0a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_13_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_13_test.dart
new file mode 100644
index 0000000..262f833
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_14_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_14_test.dart
new file mode 100644
index 0000000..5e081e0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_15_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_15_test.dart
new file mode 100644
index 0000000..32a89c7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_15_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_15.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_15.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_16_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_16_test.dart
new file mode 100644
index 0000000..7ec112f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_16_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_16.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_16.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_17_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_17_test.dart
new file mode 100644
index 0000000..41533c9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_17_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_17.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_17.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_18_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_18_test.dart
new file mode 100644
index 0000000..abda443
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_18_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_18.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_18.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_19_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_19_test.dart
new file mode 100644
index 0000000..03d2e0d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_19_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_19.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_19.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_1_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_1_test.dart
new file mode 100644
index 0000000..cbd95ce
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_20_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_20_test.dart
new file mode 100644
index 0000000..8421f29
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_20_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_20.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_20.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_21_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_21_test.dart
new file mode 100644
index 0000000..d65f1d2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_21_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_21.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_21.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_22_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_22_test.dart
new file mode 100644
index 0000000..b6fff18
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_22_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_22.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_22.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_23_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_23_test.dart
new file mode 100644
index 0000000..71083d4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_23_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_23.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_23.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_24_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_24_test.dart
new file mode 100644
index 0000000..ed56ade
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_24_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_24.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_24.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_25_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_25_test.dart
new file mode 100644
index 0000000..d3aa3a8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_25_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_25.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_25.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_26_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_26_test.dart
new file mode 100644
index 0000000..348162f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_26_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_26.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_26.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_27_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_27_test.dart
new file mode 100644
index 0000000..545ed60
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_27_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_27.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_27.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_28_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_28_test.dart
new file mode 100644
index 0000000..4777d3d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_28_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_28.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_28.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_2_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_2_test.dart
new file mode 100644
index 0000000..82dfbed
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_3_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_3_test.dart
new file mode 100644
index 0000000..3fa5714
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_4_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_4_test.dart
new file mode 100644
index 0000000..f254f71
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_5_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_5_test.dart
new file mode 100644
index 0000000..d90713c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_6_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_6_test.dart
new file mode 100644
index 0000000..1a35cbe
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_7_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_7_test.dart
new file mode 100644
index 0000000..6069711
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_8_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_8_test.dart
new file mode 100644
index 0000000..082bb9b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_9_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_9_test.dart
new file mode 100644
index 0000000..49c5202
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_10_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_10_test.dart
new file mode 100644
index 0000000..4b2600c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_11_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_11_test.dart
new file mode 100644
index 0000000..e8f6b2c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_12_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_12_test.dart
new file mode 100644
index 0000000..5a5810c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_13_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_13_test.dart
new file mode 100644
index 0000000..a72d96b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_14_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_14_test.dart
new file mode 100644
index 0000000..9453955
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_15_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_15_test.dart
new file mode 100644
index 0000000..3fcdc5d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_15_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_15.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_15.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_16_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_16_test.dart
new file mode 100644
index 0000000..6c55492
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_16_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_16.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_16.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_17_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_17_test.dart
new file mode 100644
index 0000000..59f9881
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_17_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_17.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_17.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_1_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_1_test.dart
new file mode 100644
index 0000000..89d6903
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_2_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_2_test.dart
new file mode 100644
index 0000000..9aaee58
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_3_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_3_test.dart
new file mode 100644
index 0000000..1f2613c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_4_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_4_test.dart
new file mode 100644
index 0000000..5248eae
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_5_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_5_test.dart
new file mode 100644
index 0000000..ae259b3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_6_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_6_test.dart
new file mode 100644
index 0000000..315b8ba
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_7_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_7_test.dart
new file mode 100644
index 0000000..b3b060d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_8_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_8_test.dart
new file mode 100644
index 0000000..803d019
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_9 b/tests/compiler/dart2js/cps_ir/argument_refinement_num_9
new file mode 100644
index 0000000..86963e3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_9
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.cps_ir_test;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_9", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/argument_refinement_num_9_test.dart b/tests/compiler/dart2js/cps_ir/argument_refinement_num_9_test.dart
new file mode 100644
index 0000000..f6cbe34
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/argument_refinement_num_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.argument_refinement_num_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("argument_refinement_num_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_10_test.dart b/tests/compiler/dart2js/cps_ir/basic_10_test.dart
new file mode 100644
index 0000000..3d6ab6f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_11_test.dart b/tests/compiler/dart2js/cps_ir/basic_11_test.dart
new file mode 100644
index 0000000..eed3081
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_12_test.dart b/tests/compiler/dart2js/cps_ir/basic_12_test.dart
new file mode 100644
index 0000000..cbdbd19
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_13_test.dart b/tests/compiler/dart2js/cps_ir/basic_13_test.dart
new file mode 100644
index 0000000..e867b76
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_14_test.dart b/tests/compiler/dart2js/cps_ir/basic_14_test.dart
new file mode 100644
index 0000000..814bf20
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_15_test.dart b/tests/compiler/dart2js/cps_ir/basic_15_test.dart
new file mode 100644
index 0000000..72c06fe
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_15_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_15.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_15.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_16_test.dart b/tests/compiler/dart2js/cps_ir/basic_16_test.dart
new file mode 100644
index 0000000..559ad5c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_16_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_16.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_16.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_1_test.dart b/tests/compiler/dart2js/cps_ir/basic_1_test.dart
new file mode 100644
index 0000000..711cb33
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_2_test.dart b/tests/compiler/dart2js/cps_ir/basic_2_test.dart
new file mode 100644
index 0000000..f5eb5b3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_3_test.dart b/tests/compiler/dart2js/cps_ir/basic_3_test.dart
new file mode 100644
index 0000000..5476c1f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_4_test.dart b/tests/compiler/dart2js/cps_ir/basic_4_test.dart
new file mode 100644
index 0000000..9cd8d85
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_5_test.dart b/tests/compiler/dart2js/cps_ir/basic_5_test.dart
new file mode 100644
index 0000000..e38ea0b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_6_test.dart b/tests/compiler/dart2js/cps_ir/basic_6_test.dart
new file mode 100644
index 0000000..0a79e84
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_7_test.dart b/tests/compiler/dart2js/cps_ir/basic_7_test.dart
new file mode 100644
index 0000000..b411ab8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_8_test.dart b/tests/compiler/dart2js/cps_ir/basic_8_test.dart
new file mode 100644
index 0000000..03bc57c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/basic_9_test.dart b/tests/compiler/dart2js/cps_ir/basic_9_test.dart
new file mode 100644
index 0000000..dd02afb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/basic_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.basic_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("basic_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_10_test.dart b/tests/compiler/dart2js/cps_ir/closures_10_test.dart
new file mode 100644
index 0000000..e5d99a8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_11_test.dart b/tests/compiler/dart2js/cps_ir/closures_11_test.dart
new file mode 100644
index 0000000..6012079
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_12_test.dart b/tests/compiler/dart2js/cps_ir/closures_12_test.dart
new file mode 100644
index 0000000..4bf040d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_13_test.dart b/tests/compiler/dart2js/cps_ir/closures_13_test.dart
new file mode 100644
index 0000000..f4c83b9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_14_test.dart b/tests/compiler/dart2js/cps_ir/closures_14_test.dart
new file mode 100644
index 0000000..c5198e2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_15_test.dart b/tests/compiler/dart2js/cps_ir/closures_15_test.dart
new file mode 100644
index 0000000..f78f7a9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_15_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_15.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_15.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_1_test.dart b/tests/compiler/dart2js/cps_ir/closures_1_test.dart
new file mode 100644
index 0000000..9eb7749
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_2_test.dart b/tests/compiler/dart2js/cps_ir/closures_2_test.dart
new file mode 100644
index 0000000..ff5b698
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_3_test.dart b/tests/compiler/dart2js/cps_ir/closures_3_test.dart
new file mode 100644
index 0000000..cb19e78
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_4_test.dart b/tests/compiler/dart2js/cps_ir/closures_4_test.dart
new file mode 100644
index 0000000..66142a4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_5_test.dart b/tests/compiler/dart2js/cps_ir/closures_5_test.dart
new file mode 100644
index 0000000..5910347
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_6_test.dart b/tests/compiler/dart2js/cps_ir/closures_6_test.dart
new file mode 100644
index 0000000..9616d62
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_7_test.dart b/tests/compiler/dart2js/cps_ir/closures_7_test.dart
new file mode 100644
index 0000000..a95b1b2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_8_test.dart b/tests/compiler/dart2js/cps_ir/closures_8_test.dart
new file mode 100644
index 0000000..03b05f1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_9_test.dart b/tests/compiler/dart2js/cps_ir/closures_9_test.dart
new file mode 100644
index 0000000..3cf10ca
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/codeUnitAt_1_test.dart b/tests/compiler/dart2js/cps_ir/codeUnitAt_1_test.dart
new file mode 100644
index 0000000..e765c1d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/codeUnitAt_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.codeUnitAt_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("codeUnitAt_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/codeUnitAt_2_test.dart b/tests/compiler/dart2js/cps_ir/codeUnitAt_2_test.dart
new file mode 100644
index 0000000..9838b61
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/codeUnitAt_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.codeUnitAt_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("codeUnitAt_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_10_test.dart b/tests/compiler/dart2js/cps_ir/constructor_10_test.dart
new file mode 100644
index 0000000..ee3d425
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_10_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_10.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_10.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_11_test.dart b/tests/compiler/dart2js/cps_ir/constructor_11_test.dart
new file mode 100644
index 0000000..0b3002d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_11_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_11.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_11.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_12_test.dart b/tests/compiler/dart2js/cps_ir/constructor_12_test.dart
new file mode 100644
index 0000000..16442e3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_12_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_12.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_12.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_13_test.dart b/tests/compiler/dart2js/cps_ir/constructor_13_test.dart
new file mode 100644
index 0000000..084f2ef
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_13_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_13.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_13.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_14_test.dart b/tests/compiler/dart2js/cps_ir/constructor_14_test.dart
new file mode 100644
index 0000000..41903ef
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_14_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_14.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_14.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_1_test.dart b/tests/compiler/dart2js/cps_ir/constructor_1_test.dart
new file mode 100644
index 0000000..1acf661
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_2_test.dart b/tests/compiler/dart2js/cps_ir/constructor_2_test.dart
new file mode 100644
index 0000000..11fd0f8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_3_test.dart b/tests/compiler/dart2js/cps_ir/constructor_3_test.dart
new file mode 100644
index 0000000..46c02be
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_4_test.dart b/tests/compiler/dart2js/cps_ir/constructor_4_test.dart
new file mode 100644
index 0000000..11a392b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_5_test.dart b/tests/compiler/dart2js/cps_ir/constructor_5_test.dart
new file mode 100644
index 0000000..f95c26b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_6_test.dart b/tests/compiler/dart2js/cps_ir/constructor_6_test.dart
new file mode 100644
index 0000000..c37314b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_7_test.dart b/tests/compiler/dart2js/cps_ir/constructor_7_test.dart
new file mode 100644
index 0000000..0aeca1c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_8_test.dart b/tests/compiler/dart2js/cps_ir/constructor_8_test.dart
new file mode 100644
index 0000000..b22a96d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/constructor_9_test.dart b/tests/compiler/dart2js/cps_ir/constructor_9_test.dart
new file mode 100644
index 0000000..9fe1d90
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/constructor_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.constructor_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("constructor_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_1_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_1_test.dart
new file mode 100644
index 0000000..3efea51
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_2_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_2_test.dart
new file mode 100644
index 0000000..04ab770
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_3_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_3_test.dart
new file mode 100644
index 0000000..c3cd858
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_4_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_4_test.dart
new file mode 100644
index 0000000..b355d84
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_5_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_5_test.dart
new file mode 100644
index 0000000..37ab62c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_6_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_6_test.dart
new file mode 100644
index 0000000..341be8e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_7_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_7_test.dart
new file mode 100644
index 0000000..3b9f94c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_8_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_8_test.dart
new file mode 100644
index 0000000..9a64a8c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/control_flow_9_test.dart b/tests/compiler/dart2js/cps_ir/control_flow_9_test.dart
new file mode 100644
index 0000000..7328a45
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/control_flow_9_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.control_flow_9.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("control_flow_9.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_1.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_1.js
new file mode 100644
index 0000000..758c03c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_1.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x - y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$sub$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_10.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_10.js
new file mode 100644
index 0000000..8679a25
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_10.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x > y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$gt$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_11.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_11.js
new file mode 100644
index 0000000..b5ff041a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_11.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x < y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$lt$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_12.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_12.js
new file mode 100644
index 0000000..525a5d00
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_12.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x >= y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$ge$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_13.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_13.js
new file mode 100644
index 0000000..f434bb7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_13.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x <= y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$le$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_14.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_14.js
new file mode 100644
index 0000000..642f48b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_14.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x.remainder(y));
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.remainder$1$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_15.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_15.js
new file mode 100644
index 0000000..aa6f727
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_15.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   var z = int.parse('1235');
+//   print(x is num);
+//   print(y is num);
+//   print(z is num);
+//   print(x.clamp(y, z));
+//   print(x is num);
+//   print(y is num);
+//   print(z is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), z = P.int_parse("1235", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(typeof z === "number");
+  P.print(J.clamp$2$n(x, y, z));
+  P.print(true);
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_16.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_16.js
new file mode 100644
index 0000000..0ba4b75
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_16.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x + y);
+//   print(x is num);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.$add$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_17.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_17.js
new file mode 100644
index 0000000..1fb2867
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_17.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x * y);
+//   print(x is num);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.$mul$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_18.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_18.js
new file mode 100644
index 0000000..0e73f85
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_18.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x.compareTo(y));
+//   print(x is num);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.compareTo$1$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_19.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_19.js
new file mode 100644
index 0000000..c614b75
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_19.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x / 2);
+//   print(x is num);
+//   print(y is num);
+//   print(x + y);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof y === "number";
+  P.print(J.$div$n(x, 2));
+  P.print(true);
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(y));
+  P.print(x + y);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_2.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_2.js
new file mode 100644
index 0000000..33c7bf9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_2.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x / y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$div$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_20.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_20.js
new file mode 100644
index 0000000..915d2371
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_20.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x / 2);
+//   print(x is num);
+//   print(y is num);
+//   print(x * y);
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof y === "number";
+  P.print(J.$div$n(x, 2));
+  P.print(true);
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(y));
+  P.print(x * y);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js
new file mode 100644
index 0000000..589d358
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js
@@ -0,0 +1,30 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x / 2);
+//   print(x is num);
+//   print(y is num);
+//   print(x.compareTo(y));
+//   print(y is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof y === "number";
+  P.print(J.$div$n(x, 2));
+  P.print(true);
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(y));
+  if (x < y)
+    v0 = -1;
+  else if (x > y)
+    v0 = 1;
+  else if (x === y) {
+    v0 = x === 0;
+    v0 = v0 ? (y === 0 ? 1 / y < 0 : y < 0) === (v0 ? 1 / x < 0 : x < 0) ? 0 : (v0 ? 1 / x < 0 : x < 0) ? -1 : 1 : 0;
+  } else
+    v0 = isNaN(x) ? isNaN(y) ? 0 : 1 : -1;
+  P.print(v0);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_22.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_22.js
new file mode 100644
index 0000000..3948378
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_22.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is int);
+//   print(y is int);
+//   print(x.toSigned(y));
+//   print(x is int);
+//   print(y is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(J.toSigned$1$i(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_23.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_23.js
new file mode 100644
index 0000000..e2e290d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_23.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is int);
+//   print(y is int);
+//   print(x.toUnsigned(y));
+//   print(x is int);
+//   print(y is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(J.toUnsigned$1$i(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_24.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_24.js
new file mode 100644
index 0000000..f251917
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_24.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is int);
+//   print(y is int);
+//   print(x.modInverse(y));
+//   print(x is int);
+//   print(y is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(J.modInverse$1$i(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_25.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_25.js
new file mode 100644
index 0000000..9ebb55a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_25.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is int);
+//   print(y is int);
+//   print(x.gcd(y));
+//   print(x is int);
+//   print(y is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(J.gcd$1$i(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_26.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_26.js
new file mode 100644
index 0000000..9294a75
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_26.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   var z = int.parse('1235');
+//   print(x is int);
+//   print(y is int);
+//   print(z is int);
+//   print(x.modPow(y, z));
+//   print(x is int);
+//   print(y is int);
+//   print(z is int);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), z = P.int_parse("1235", null, null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "number" && Math.floor(y) === y);
+  P.print(typeof z === "number" && Math.floor(z) === z);
+  P.print(J.modPow$2$i(x, y, z));
+  P.print(true);
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_27.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_27.js
new file mode 100644
index 0000000..484f6a1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_27.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('3');
+//   var y = int.parse('a', onError: (e) => 'abcde');
+//   print(x is int);
+//   print(y is String);
+//   print(y.codeUnitAt(x));
+//   print(x is int);
+//   print(y is String);
+// }
+
+function() {
+  var x = P.int_parse("3", null, null), y = P.int_parse("a", new V.main_closure(), null);
+  P.print(typeof x === "number" && Math.floor(x) === x);
+  P.print(typeof y === "string");
+  P.print(J.codeUnitAt$1$s(y, x));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_28.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_28.js
new file mode 100644
index 0000000..b5ab697
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_28.js
@@ -0,0 +1,47 @@
+// Expectation for test: 
+// import 'dart:math';
+// main() {
+//   var x = int.parse('3');
+//   var y = int.parse('1234');
+//   var z = int.parse('1236');
+//   var w = int.parse('2');
+//   print(x is num);
+//   print(sin(x));
+//   print(x is num);
+// 
+//   print(y is num);
+//   print(log(y));
+//   print(y is num);
+// 
+//   print(z is num);
+//   print(w is num);
+//   print(pow(z, w));
+//   print(z is num);
+//   print(w is num);
+// }
+
+function() {
+  var x = P.int_parse("3", null, null), y = P.int_parse("1234", null, null), z = P.int_parse("1236", null, null), w = P.int_parse("2", null, null), v0 = typeof x === "number", v1;
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(x));
+  P.print(Math.sin(x));
+  P.print(true);
+  v0 = typeof y === "number";
+  P.print(v0);
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(y));
+  P.print(Math.log(y));
+  P.print(true);
+  v1 = typeof z === "number";
+  P.print(v1);
+  v0 = typeof w === "number";
+  P.print(v0);
+  if (!v1)
+    throw H.wrapException(H.argumentErrorValue(z));
+  if (!v0)
+    throw H.wrapException(H.argumentErrorValue(w));
+  P.print(Math.pow(z, w));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_3.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_3.js
new file mode 100644
index 0000000..5d7d8a8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_3.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x % y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$mod$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_4.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_4.js
new file mode 100644
index 0000000..43dfc17
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_4.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x ~/ y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$tdiv$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_5.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_5.js
new file mode 100644
index 0000000..049ef54
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_5.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x >> y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$shr$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_6.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_6.js
new file mode 100644
index 0000000..953fc10
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_6.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x << y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$shl$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_7.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_7.js
new file mode 100644
index 0000000..6e152f7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_7.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x & y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$and$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_8.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_8.js
new file mode 100644
index 0000000..438d6dc7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_8.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x | y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$or$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_9.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_9.js
new file mode 100644
index 0000000..43418b5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_9.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x ^ y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$xor$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_1.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_1.js
new file mode 100644
index 0000000..758c03c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_1.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x - y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$sub$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_10.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_10.js
new file mode 100644
index 0000000..b5ff041a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_10.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x < y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$lt$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_11.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_11.js
new file mode 100644
index 0000000..8679a25
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_11.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x > y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$gt$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_12.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_12.js
new file mode 100644
index 0000000..f434bb7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_12.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x <= y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$le$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_13.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_13.js
new file mode 100644
index 0000000..525a5d00
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_13.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x >= y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$ge$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_14.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_14.js
new file mode 100644
index 0000000..642f48b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_14.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x.remainder(y));
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.remainder$1$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_15.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_15.js
new file mode 100644
index 0000000..3ce06f4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_15.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   var z = int.parse('1236');
+//   print(x is num);
+//   print(y is num);
+//   print(z is num);
+//   print(x.clamp(y, z));
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+//   print(z is num);
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), z = P.int_parse("1236", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(typeof z === "number");
+  P.print(J.clamp$2$n(x, y, z));
+  P.print(true);
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_16.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_16.js
new file mode 100644
index 0000000..10c7792
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_16.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x + y);
+//   print(x is num);
+//   print(y is num); // will stay as is-num because String could be a target of +
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.$add$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_17.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_17.js
new file mode 100644
index 0000000..4fa1574
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_17.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x * y);
+//   print(x is num);
+//   print(y is num); // will stay as is-num because String could be a target of *
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null), v0 = typeof x === "number", v1 = typeof y === "number";
+  P.print(v0);
+  P.print(v1);
+  P.print(J.$mul$ns(x, y));
+  P.print(v0);
+  P.print(v1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_2.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_2.js
new file mode 100644
index 0000000..33c7bf9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_2.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x / y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$div$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_3.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_3.js
new file mode 100644
index 0000000..5d7d8a8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_3.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x % y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$mod$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_4.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_4.js
new file mode 100644
index 0000000..43dfc17
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_4.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x ~/ y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$tdiv$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_5.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_5.js
new file mode 100644
index 0000000..049ef54
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_5.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x >> y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$shr$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_6.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_6.js
new file mode 100644
index 0000000..953fc10
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_6.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x << y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$shl$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_7.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_7.js
new file mode 100644
index 0000000..6e152f7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_7.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x & y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$and$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_8.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_8.js
new file mode 100644
index 0000000..438d6dc7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_8.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x | y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$or$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_9.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_9.js
new file mode 100644
index 0000000..43418b5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_9.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// main() {
+//   var x = int.parse('1233');
+//   var y = int.parse('1234');
+//   print(x is num);
+//   print(y is num);
+//   print(x ^ y);
+//   print(x is num);
+//   print(y is num); // will be compiled to `true` if we know the type of `y`.
+// }
+
+function() {
+  var x = P.int_parse("1233", null, null), y = P.int_parse("1234", null, null);
+  P.print(typeof x === "number");
+  P.print(typeof y === "number");
+  P.print(J.$xor$n(x, y));
+  P.print(true);
+  P.print(true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_1.js b/tests/compiler/dart2js/cps_ir/expected/basic_1.js
new file mode 100644
index 0000000..1cf4ed5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_1.js
@@ -0,0 +1,27 @@
+// Expectation for test: 
+// main() {
+//   var e = 1;
+//   var l = [1, 2, 3];
+//   var m = {'s': 1};
+// 
+//   print('(' ')');
+//   print('(${true})');
+//   print('(${1})');
+//   print('(${[1, 2, 3]})');
+//   print('(${{'s': 1}})');
+//   print('($e)');
+//   print('($l)');
+//   print('($m)');
+// }
+
+function() {
+  var l = [1, 2, 3], m = P.LinkedHashMap_LinkedHashMap$_literal(["s", 1]);
+  P.print("()");
+  P.print("(true)");
+  P.print("(1)");
+  P.print("(" + P.IterableBase_iterableToFullString([1, 2, 3], "[", "]") + ")");
+  P.print("(" + P.Maps_mapToString(P.LinkedHashMap_LinkedHashMap$_literal(["s", 1])) + ")");
+  P.print("(1)");
+  P.print("(" + P.IterableBase_iterableToFullString(l, "[", "]") + ")");
+  P.print("(" + P.Maps_mapToString(m) + ")");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_10.js b/tests/compiler/dart2js/cps_ir/expected/basic_10.js
new file mode 100644
index 0000000..cfd6571
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_10.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// main() {
+//   print(new DateTime.now().isBefore(new DateTime.now()));
+// }
+
+function() {
+  var v0 = Date.now() < Date.now(), line = v0 ? "true" : false === v0 ? "false" : String(v0);
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_11.js b/tests/compiler/dart2js/cps_ir/expected/basic_11.js
new file mode 100644
index 0000000..5f26f1c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_11.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// foo() { print(42); }
+// main() { foo(); }
+
+function() {
+  var line = "" + 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_12.js b/tests/compiler/dart2js/cps_ir/expected/basic_12.js
new file mode 100644
index 0000000..084681f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_12.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// var foo = 42;
+// main() { print(foo); }
+
+function() {
+  var v0 = $.foo, line = v0 === 0 ? 1 / v0 < 0 ? "-0.0" : "" + v0 : "" + v0;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_13.js b/tests/compiler/dart2js/cps_ir/expected/basic_13.js
new file mode 100644
index 0000000..218ba31
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_13.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// get foo { print(42); }
+// main() { foo; }
+
+function() {
+  var line = "" + 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_14.js b/tests/compiler/dart2js/cps_ir/expected/basic_14.js
new file mode 100644
index 0000000..a42876b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_14.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// var foo = 0;
+// main() { print(foo = 42); }
+
+function() {
+  var line = "" + 42;
+  $.foo = 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_15.js b/tests/compiler/dart2js/cps_ir/expected/basic_15.js
new file mode 100644
index 0000000..ea86609
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_15.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// set foo(x) { print(x); }
+// main() { foo = 42; }
+
+function() {
+  var line = "" + 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_16.js b/tests/compiler/dart2js/cps_ir/expected/basic_16.js
new file mode 100644
index 0000000..0442443
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_16.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// foo() { print('X'); }
+// main() {
+//   assert(true);
+//   assert(false);
+//   assert(foo());
+//   print('Done');
+// }
+
+function() {
+  P.print("Done");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_2.js b/tests/compiler/dart2js/cps_ir/expected/basic_2.js
new file mode 100644
index 0000000..3f579fc
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_2.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// foo(a, [b = "b"]) { print(b); return b; }
+// bar(a, {b: "b", c: "c"}) { print(c); return c; }
+// main() {
+//   foo(0);
+//   foo(1, 2);
+//   bar(3);
+//   bar(4, b: 5);
+//   bar(6, c: 7);
+//   bar(8, b: 9, c: 10);
+// }
+
+function() {
+  P.print("b");
+  P.print(2);
+  P.print("c");
+  P.print("c");
+  P.print(7);
+  P.print(10);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_3.js b/tests/compiler/dart2js/cps_ir/expected/basic_3.js
new file mode 100644
index 0000000..3d8269f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_3.js
@@ -0,0 +1,25 @@
+// Expectation for test: 
+// foo(a) {
+//   print(a);
+//   return a;
+// }
+// main() {
+//   var a = 10;
+//   var b = 1;
+//   var t;
+//   t = a;
+//   a = b;
+//   b = t;
+//   print(a);
+//   print(b);
+//   print(b);
+//   print(foo(a));
+// }
+
+function() {
+  P.print(1);
+  P.print(10);
+  P.print(10);
+  P.print(1);
+  P.print(1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_4.js b/tests/compiler/dart2js/cps_ir/expected/basic_4.js
new file mode 100644
index 0000000..68f024f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_4.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// foo() { print(42); return 42; }
+// main() { return foo(); }
+
+function() {
+  var line = "" + 42;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+  return 42;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_5.js b/tests/compiler/dart2js/cps_ir/expected/basic_5.js
new file mode 100644
index 0000000..9027244
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_5.js
@@ -0,0 +1,5 @@
+// Expectation for test: 
+// main() {}
+
+function() {
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_6.js b/tests/compiler/dart2js/cps_ir/expected/basic_6.js
new file mode 100644
index 0000000..a6a2296
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_6.js
@@ -0,0 +1,6 @@
+// Expectation for test: 
+// main() { return 42; }
+
+function() {
+  return 42;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_7.js b/tests/compiler/dart2js/cps_ir/expected/basic_7.js
new file mode 100644
index 0000000..cd112ad
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_7.js
@@ -0,0 +1,5 @@
+// Expectation for test: 
+// main() { return; }
+
+function() {
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_8.js b/tests/compiler/dart2js/cps_ir/expected/basic_8.js
new file mode 100644
index 0000000..1d8cccd
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_8.js
@@ -0,0 +1,10 @@
+// Expectation for test: 
+// main() {
+//   print(new Set());
+//   print(new Set.from([1, 2, 3]));
+// }
+
+function() {
+  P.print(P._LinkedHashSet$(null));
+  P.print(P.LinkedHashSet_LinkedHashSet$from([1, 2, 3], null));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_9.js b/tests/compiler/dart2js/cps_ir/expected/basic_9.js
new file mode 100644
index 0000000..b47ad6a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_9.js
@@ -0,0 +1,18 @@
+// Expectation for test: 
+// class C {}
+// main() {
+//   print(new C());
+// }
+
+function() {
+  var res = "Instance of '" + H.Primitives_objectTypeName(V.C$()) + "'";
+  if (typeof dartPrint == "function")
+    dartPrint(res);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(res);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(res);
+    print(res);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_1.js b/tests/compiler/dart2js/cps_ir/expected/closures_1.js
new file mode 100644
index 0000000..e8cc7ab
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_1.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// main(x) {
+//   a() {
+//     return x;
+//   }
+//   x = x + '1';
+//   print(a());
+// }
+
+function(x) {
+  P.print(J.$add$ns(x, "1"));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_10.js b/tests/compiler/dart2js/cps_ir/expected/closures_10.js
new file mode 100644
index 0000000..a628815
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_10.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// class A {
+//   a() => 1;
+//   b() => () => a();
+// }
+// main() {
+//   print(new A().b()());
+// }
+
+function() {
+  var line = H.S(new V.A_b_closure(V.A$()).call$0());
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_11.js b/tests/compiler/dart2js/cps_ir/expected/closures_11.js
new file mode 100644
index 0000000..e547d06
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_11.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// staticMethod(x) { print(x); return x; }
+// main(x) {
+//   var tearOff = staticMethod;
+//   print(tearOff(123));
+// }
+
+function(x) {
+  P.print(123);
+  P.print(123);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_12.js b/tests/compiler/dart2js/cps_ir/expected/closures_12.js
new file mode 100644
index 0000000..5078169
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_12.js
@@ -0,0 +1,13 @@
+// Expectation for test: 
+// class Foo {
+//   instanceMethod(x) => x;
+// }
+// main(x) {
+//   var tearOff = new Foo().instanceMethod;
+//   print(tearOff(123));
+// }
+
+function(x) {
+  V.Foo$();
+  P.print(123);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_13.js b/tests/compiler/dart2js/cps_ir/expected/closures_13.js
new file mode 100644
index 0000000..5a61827
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_13.js
@@ -0,0 +1,15 @@
+// Expectation for test: 
+// class Foo {
+//   instanceMethod(x) => x;
+// }
+// main(x) {
+//   var tearOff = new Foo().instanceMethod;
+//   print(tearOff(123));
+//   print(tearOff(321));
+// }
+
+function(x) {
+  V.Foo$();
+  P.print(123);
+  P.print(321);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_14.js b/tests/compiler/dart2js/cps_ir/expected/closures_14.js
new file mode 100644
index 0000000..5c27c7b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_14.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// class Foo {
+//   get getter {
+//     print('getter');
+//     return (x) => x;
+//   }
+// }
+// main(x) {
+//   var notTearOff = new Foo().getter;
+//   print(notTearOff(123));
+//   print(notTearOff(321));
+// }
+
+function(x) {
+  var notTearOff = new V.Foo_getter_closure();
+  V.Foo$();
+  P.print("getter");
+  P.print(notTearOff.call$1(123));
+  P.print(notTearOff.call$1(321));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_15.js b/tests/compiler/dart2js/cps_ir/expected/closures_15.js
new file mode 100644
index 0000000..46c7d38
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_15.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// class Foo {
+//   get getter {
+//     print('getter');
+//     return (x) => x;
+//   }
+// }
+// main(x) {
+//   var notTearOff = new Foo().getter;
+//   print(notTearOff(123));
+// }
+
+function(x) {
+  V.Foo$();
+  P.print("getter");
+  P.print(new V.Foo_getter_closure().call$1(123));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_2.js b/tests/compiler/dart2js/cps_ir/expected/closures_2.js
new file mode 100644
index 0000000..b5ffeebd
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_2.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// main(x) {
+//   a() {
+//     return x;
+//   }
+//   x = x + '1';
+//   print(a());
+//   return a;
+// }
+
+function(x) {
+  var _box_0 = {}, a = new V.main_a(_box_0);
+  _box_0.x = x;
+  _box_0.x = J.$add$ns(_box_0.x, "1");
+  P.print(a.call$0());
+  return a;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_3.js b/tests/compiler/dart2js/cps_ir/expected/closures_3.js
new file mode 100644
index 0000000..69425f1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_3.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// main(x) {
+//   a() {
+//     return x;
+//   }
+//   print(a());
+// }
+
+function(x) {
+  P.print(x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_4.js b/tests/compiler/dart2js/cps_ir/expected/closures_4.js
new file mode 100644
index 0000000..02027fe
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_4.js
@@ -0,0 +1,14 @@
+// Expectation for test: 
+// main(x) {
+//   a() {
+//     return x;
+//   }
+//   print(a());
+//   return a;
+// }
+
+function(x) {
+  var a = new V.main_a(x);
+  P.print(a.call$0());
+  return a;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_5.js b/tests/compiler/dart2js/cps_ir/expected/closures_5.js
new file mode 100644
index 0000000..959b14a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_5.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// main() {
+//   var x = 122;
+//   var a = () => x;
+//   x = x + 1;
+//   print(a());
+// }
+
+function() {
+  var _captured_x_0 = 122 + 1, line = _captured_x_0 === 0 ? 1 / _captured_x_0 < 0 ? "-0.0" : "" + _captured_x_0 : "" + _captured_x_0;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_6.js b/tests/compiler/dart2js/cps_ir/expected/closures_6.js
new file mode 100644
index 0000000..3ff087a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_6.js
@@ -0,0 +1,25 @@
+// Expectation for test: 
+// main() {
+//   var x = 122;
+//   var a = () => x;
+//   x = x + 1;
+//   print(a());
+//   return a;
+// }
+
+function() {
+  var _box_0 = {}, a = new V.main_closure(_box_0), line;
+  _box_0.x = 122;
+  ++_box_0.x;
+  line = H.S(a.call$0());
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+  return a;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_7.js b/tests/compiler/dart2js/cps_ir/expected/closures_7.js
new file mode 100644
index 0000000..4a16c92
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_7.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// main() {
+//   var x = 122;
+//   var a = () {
+//     var y = x;
+//     return () => y;
+//   };
+//   x = x + 1;
+//   print(a()());
+// }
+
+function() {
+  var _captured_x_0 = 122 + 1, line = _captured_x_0 === 0 ? 1 / _captured_x_0 < 0 ? "-0.0" : "" + _captured_x_0 : "" + _captured_x_0;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_8.js b/tests/compiler/dart2js/cps_ir/expected/closures_8.js
new file mode 100644
index 0000000..35d033f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_8.js
@@ -0,0 +1,28 @@
+// Expectation for test: 
+// main() {
+//   var x = 122;
+//   var a = () {
+//     var y = x;
+//     return () => y;
+//   };
+//   x = x + 1;
+//   print(a()());
+//   return a;
+// }
+
+function() {
+  var _box_0 = {}, a = new V.main_closure(_box_0), line;
+  _box_0.x = 122;
+  ++_box_0.x;
+  line = H.S(a.call$0().call$0());
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+  return a;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_9.js b/tests/compiler/dart2js/cps_ir/expected/closures_9.js
new file mode 100644
index 0000000..c11aa2d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_9.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// main() {
+//   var a;
+//   for (var i=0; i<10; i++) {
+//     a = () => i;
+//   }
+//   print(a());
+// }
+
+function() {
+  var a = null, i = 0, line;
+  for (; i < 10; a = new V.main_closure(i), ++i)
+    ;
+  line = H.S(a.call$0());
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_1.js b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_1.js
new file mode 100644
index 0000000..92a1969
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_1.js
@@ -0,0 +1,18 @@
+// Expectation for test: 
+// // Constant folding
+// main() {
+//   print('A'.codeUnitAt(0));
+// }
+
+function() {
+  var line = "" + 65;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js
new file mode 100644
index 0000000..73e278b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// // Bounds checking
+// foo(s) {
+//   var sum = 0;
+//   for (int i = 0; i < s.length; i++) sum += s.codeUnitAt(i);
+//   return sum;
+// }
+// main() {
+//   print(foo('ABC'));
+//   print(foo('Hello'));
+// }
+
+function() {
+  var v0 = "ABC".length, sum = 0, i = 0;
+  for (; i < v0; sum += "ABC".charCodeAt(i), ++i)
+    ;
+  P.print(sum);
+  v0 = "Hello".length;
+  sum = 0;
+  for (i = 0; i < v0; sum += "Hello".charCodeAt(i), ++i)
+    ;
+  P.print(sum);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_1.js b/tests/compiler/dart2js/cps_ir/expected/constructor_1.js
new file mode 100644
index 0000000..21493c2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_1.js
@@ -0,0 +1,25 @@
+// Expectation for test: 
+// class Base {
+//   var x;
+//   Base(this.x);
+// }
+// class Sub extends Base {
+//   var y;
+//   Sub(x, this.y) : super(x);
+// }
+// main() {
+//   print(new Sub(1, 2).x);
+// }
+
+function() {
+  var line = 1 === 0 ? 1 / 1 < 0 ? "-0.0" : "" + 1 : "" + 1;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_10.js b/tests/compiler/dart2js/cps_ir/expected/constructor_10.js
new file mode 100644
index 0000000..c2148d0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_10.js
@@ -0,0 +1,16 @@
+// Expectation for test: 
+// // Method to test: generative_constructor(C#)
+// class C<T> {
+//   var x;
+//   C() : x = new D<T>();
+// }
+// class D<T> {
+//   foo() => T;
+// }
+// main() {
+//   print(new C<int>().x.foo());
+// }
+
+function($T) {
+  return H.setRuntimeTypeInfo(new V.C(V.D$($T)), [$T]);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_11.js b/tests/compiler/dart2js/cps_ir/expected/constructor_11.js
new file mode 100644
index 0000000..9c0d6d0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_11.js
@@ -0,0 +1,22 @@
+// Expectation for test: 
+// class A {
+//   var x;
+//   A() : this.b(1);
+//   A.b(this.x);
+// }
+// main() {
+//   print(new A().x);
+// }
+
+function() {
+  var line = 1 === 0 ? 1 / 1 < 0 ? "-0.0" : "" + 1 : "" + 1;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_12.js b/tests/compiler/dart2js/cps_ir/expected/constructor_12.js
new file mode 100644
index 0000000..d892327
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_12.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// class Foo {
+//   factory Foo.make(x) {
+//     print('Foo');
+//     return new Foo.create(x);
+//   }
+//   var x;
+//   Foo.create(this.x);
+// }
+// main() {
+//   print(new Foo.make(5));
+// }
+
+function() {
+  P.print("Foo");
+  P.print(new V.Foo(5));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_13.js b/tests/compiler/dart2js/cps_ir/expected/constructor_13.js
new file mode 100644
index 0000000..074cf69
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_13.js
@@ -0,0 +1,22 @@
+// Expectation for test: 
+// class Foo {
+//   factory Foo.make(x) = Foo.create;
+//   var x;
+//   Foo.create(this.x);
+// }
+// main() {
+//   print(new Foo.make(5));
+// }
+
+function() {
+  var res = "Instance of '" + H.Primitives_objectTypeName(new V.Foo(5)) + "'";
+  if (typeof dartPrint == "function")
+    dartPrint(res);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(res);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(res);
+    print(res);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_14.js b/tests/compiler/dart2js/cps_ir/expected/constructor_14.js
new file mode 100644
index 0000000..fe479f9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_14.js
@@ -0,0 +1,18 @@
+// Expectation for test: 
+// class A {
+//   factory A(x) = B<int>;
+//   get typevar;
+// }
+// class B<T> implements A {
+//   var x;
+//   B(this.x);
+// 
+//   get typevar => T;
+// }
+// main() {
+//   new A(5).typevar;
+// }
+
+function() {
+  V.B$(5, P.$int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_2.js b/tests/compiler/dart2js/cps_ir/expected/constructor_2.js
new file mode 100644
index 0000000..94d3b4e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_2.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// class Base {
+//   var x;
+//   Base(this.x);
+// }
+// class Sub extends Base {
+//   var y;
+//   Sub(x, this.y) : super(x) {
+//     print(x);
+//   }
+// }
+// main() {
+//   print(new Sub(1, 2).x);
+// }
+
+function() {
+  P.print(1);
+  P.print(1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_3.js b/tests/compiler/dart2js/cps_ir/expected/constructor_3.js
new file mode 100644
index 0000000..0f14d28
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_3.js
@@ -0,0 +1,25 @@
+// Expectation for test: 
+// class Base0 {
+//   Base0() {
+//     print('Base0');
+//   }
+// }
+// class Base extends Base0 {
+//   var x;
+//   Base(this.x);
+// }
+// class Sub extends Base {
+//   var y;
+//   Sub(x, this.y) : super(x) {
+//     print(x);
+//   }
+// }
+// main() {
+//   print(new Sub(1, 2).x);
+// }
+
+function() {
+  P.print("Base0");
+  P.print(1);
+  P.print(1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_4.js b/tests/compiler/dart2js/cps_ir/expected/constructor_4.js
new file mode 100644
index 0000000..7253134
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_4.js
@@ -0,0 +1,30 @@
+// Expectation for test: 
+// class Base0 {
+//   Base0() {
+//     print('Base0');
+//   }
+// }
+// class Base extends Base0 {
+//   var x;
+//   Base(x1) : x = (() => ++x1) {
+//     print(x1); // use boxed x1
+//   }
+// }
+// class Sub extends Base {
+//   var y;
+//   Sub(x, this.y) : super(x) {
+//     print(x);
+//   }
+// }
+// main() {
+//   print(new Sub(1, 2).x);
+// }
+
+function() {
+  var _box_0 = {};
+  _box_0.x1 = 1;
+  P.print("Base0");
+  P.print(_box_0.x1);
+  P.print(1);
+  P.print(new V.Base_closure(_box_0));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_5.js b/tests/compiler/dart2js/cps_ir/expected/constructor_5.js
new file mode 100644
index 0000000..ed704e1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_5.js
@@ -0,0 +1,28 @@
+// Expectation for test: 
+// foo(x) {
+//   print(x);
+// }
+// class Base {
+//   var x1 = foo('x1');
+//   var x2;
+//   var x3 = foo('x3');
+//   Base() : x2 = foo('x2');
+// }
+// class Sub extends Base {
+//   var y1 = foo('y1');
+//   var y2;
+//   var y3;
+//   Sub() : y2 = foo('y2'), super(), y3 = foo('y3');
+// }
+// main() {
+//   new Sub();
+// }
+
+function() {
+  V.foo("y1");
+  V.foo("y2");
+  V.foo("x1");
+  V.foo("x3");
+  V.foo("x2");
+  V.foo("y3");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_6.js b/tests/compiler/dart2js/cps_ir/expected/constructor_6.js
new file mode 100644
index 0000000..66d5ae5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_6.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// class Bar {
+//   Bar(x, {y, z: 'z', w: '_', q}) {
+//     print(x);
+//     print(y);
+//     print(z);
+//     print(w);
+//     print(q);
+//   }
+// }
+// class Foo extends Bar {
+//   Foo() : super('x', y: 'y', w: 'w');
+// }
+// main() {
+//   new Foo();
+// }
+
+function() {
+  P.print("x");
+  P.print("y");
+  P.print("z");
+  P.print("w");
+  P.print(null);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_7.js b/tests/compiler/dart2js/cps_ir/expected/constructor_7.js
new file mode 100644
index 0000000..8474ee4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_7.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// class C<T> {
+//   foo() => T;
+// }
+// main() {
+//   print(new C<int>().foo());
+// }
+
+function() {
+  var line = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getTypeArgumentByIndex(V.C$(P.$int), 0))));
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_8.js b/tests/compiler/dart2js/cps_ir/expected/constructor_8.js
new file mode 100644
index 0000000..e4a2ea6
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_8.js
@@ -0,0 +1,22 @@
+// Expectation for test: 
+// class C<T> {
+//   foo() => C;
+// }
+// main() {
+//   print(new C<int>().foo());
+// }
+
+function() {
+  var line;
+  V.C$();
+  line = H.S(C.Type_C_cdS);
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_9.js b/tests/compiler/dart2js/cps_ir/expected/constructor_9.js
new file mode 100644
index 0000000..05928b3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/constructor_9.js
@@ -0,0 +1,15 @@
+// Expectation for test: 
+// // Method to test: generative_constructor(C#)
+// class C<T> {
+//   C() { print(T); }
+//   foo() => print(T);
+// }
+// main() {
+//   new C<int>();
+// }
+
+function($T) {
+  var v0 = H.setRuntimeTypeInfo(new V.C(), [$T]);
+  v0.C$0();
+  return v0;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js
new file mode 100644
index 0000000..950d594
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js
@@ -0,0 +1,9 @@
+// Expectation for test: 
+// main() {
+//   while (true);
+// }
+
+function() {
+  while (true)
+    ;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js
new file mode 100644
index 0000000..79c2ddd
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js
@@ -0,0 +1,33 @@
+// Expectation for test: 
+// foo(a) { print(a); return a; }
+// 
+// main() {
+//   while (true) {
+//     l: while (true) {
+//       while (foo(true)) {
+//         if (foo(false)) break l;
+//       }
+//       print(1);
+//     }
+//     print(2);
+//   }
+// }
+
+function() {
+  L1:
+    while (true)
+      L0:
+        while (true)
+          while (true) {
+            P.print(true);
+            if (false) {
+              P.print(1);
+              continue L0;
+            }
+            P.print(false);
+            if (false) {
+              P.print(2);
+              continue L1;
+            }
+          }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js
new file mode 100644
index 0000000..514ed7b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js
@@ -0,0 +1,26 @@
+// Expectation for test: 
+// foo(a) { print(a); return a; }
+// 
+// main() {
+//   for (int i = 0; foo(true); i = foo(i)) {
+//     print(1);
+//     if (foo(false)) break;
+//   }
+//   print(2);
+// }
+
+function() {
+  while (true) {
+    P.print(true);
+    if (true === true) {
+      P.print(1);
+      P.print(false);
+      if (false !== true) {
+        P.print(0);
+        continue;
+      }
+    }
+    P.print(2);
+    return null;
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js
new file mode 100644
index 0000000..00099d0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js
@@ -0,0 +1,19 @@
+// Expectation for test: 
+// foo(a) { print(a); return a; }
+// 
+// main() {
+//  foo(false);
+//  if (foo(true)) {
+//    print(1);
+//  } else {
+//    print(2);
+//  }
+//  print(3);
+// }
+
+function() {
+  P.print(false);
+  P.print(true);
+  true ? P.print(1) : P.print(2);
+  P.print(3);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js
new file mode 100644
index 0000000..78c0641
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js
@@ -0,0 +1,27 @@
+// Expectation for test: 
+// foo(a) { print(a); return a; }
+// 
+// main() {
+//  foo(false);
+//  if (foo(true)) {
+//    print(1);
+//    print(1);
+//  } else {
+//    print(2);
+//    print(2);
+//  }
+//  print(3);
+// }
+
+function() {
+  P.print(false);
+  P.print(true);
+  if (true) {
+    P.print(1);
+    P.print(1);
+  } else {
+    P.print(2);
+    P.print(2);
+  }
+  P.print(3);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_6.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_6.js
new file mode 100644
index 0000000..4530b7e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_6.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// main() {
+//   if (1) {
+//     print('bad');
+//   } else {
+//     print('good');
+//   }
+// }
+
+function() {
+  P.print("good");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_7.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_7.js
new file mode 100644
index 0000000..e4f20e1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_7.js
@@ -0,0 +1,14 @@
+// Expectation for test: 
+// foo() { print('2'); return 2; }
+// main() {
+//   if (foo()) {
+//     print('bad');
+//   } else {
+//     print('good');
+//   }
+// }
+
+function() {
+  P.print("2");
+  P.print("good");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_8.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_8.js
new file mode 100644
index 0000000..bcb67d3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_8.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// main() {
+//   var list = [1,2,3,4,5,6];
+//   for (var x in list) {
+//     print(x);
+//   }
+// }
+
+function() {
+  var list = [1, 2, 3, 4, 5, 6], i = 0, line;
+  for (; i < 6; ++i) {
+    line = H.S(list[i]);
+    if (typeof dartPrint == "function")
+      dartPrint(line);
+    else if (typeof console == "object" && typeof console.log != "undefined")
+      console.log(line);
+    else if (!(typeof window == "object")) {
+      if (!(typeof print == "function"))
+        throw "Unable to print message: " + String(line);
+      print(line);
+    }
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_9.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_9.js
new file mode 100644
index 0000000..637d654
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_9.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// main() {
+//   var xs = ['x', 'y', 'z'], ys = ['A', 'B', 'C'];
+//   var xit = xs.iterator, yit = ys.iterator;
+//   while (xit.moveNext() && yit.moveNext()) {
+//     print(xit.current);
+//     print(yit.current);
+//   }
+// }
+
+function() {
+  var xs = ["x", "y", "z"], ys = ["A", "B", "C"], i = 0, i1 = 0, current, current1;
+  for (; i < 3; ++i, ++i1) {
+    current = xs[i];
+    if (!(i1 < 3))
+      break;
+    current1 = ys[i1];
+    P.print(current);
+    P.print(current1);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/gvn_1.js b/tests/compiler/dart2js/cps_ir/expected/gvn_1.js
new file mode 100644
index 0000000..1307a74
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/gvn_1.js
@@ -0,0 +1,58 @@
+// Expectation for test: 
+// foo(x, list) {
+//   var sum = 0;
+//   for (int k = 0; k < 10; k++) {
+//     // Everything can be hoisted out up to the index access which is
+//     // blocked by the bounds check.
+//     var a = x.left.left;
+//     var b = x.left.right;
+//     var c = x.right.left;
+//     var d = x.right.right;
+//     var i = a.value + c.value;
+//     var j = b.value + d.value;
+//     var z = list[i * j] + i;
+//     sum += z;
+//   }
+//   return sum;
+// }
+// // Use a different class for each level in the tree, so type inference
+// // is not confused.
+// class Root {
+//   Branch left, right;
+//   Root(this.left, this.right);
+// }
+// class Branch {
+//   Leaf left, right;
+//   Branch(this.left, this.right);
+// }
+// class Leaf {
+//   int value;
+//   Leaf(this.value);
+// }
+// main() {
+//   var x1 = new Leaf(1);
+//   var x2 = new Leaf(10);
+//   var x3 = new Leaf(20);
+//   var x4 = new Leaf(-10);
+//   var y1 = new Branch(x1, x2);
+//   var y2 = new Branch(x3, x4);
+//   var z  = new Root(y1, y2);
+//   print(foo(z, [1,2,3,4,5,6,7,8,9,10]));
+// }
+
+function() {
+  var v0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], i = 1 + 20, v1 = i * (10 + -10), sum = 0, k = 0, line;
+  for (; k < 10; sum += i + v0[v1], ++k)
+    if (v1 < 0 || v1 >= 10)
+      return H.ioore(v0, v1);
+  line = sum === 0 ? 1 / sum < 0 ? "-0.0" : "" + sum : "" + sum;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/interceptors_1.js b/tests/compiler/dart2js/cps_ir/expected/interceptors_1.js
new file mode 100644
index 0000000..ed58ff0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/interceptors_1.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// main() {
+//   var g = 1;
+// 
+//   var x = g + 3;
+//   print(x);
+// }
+
+function() {
+  var line = "" + 4;
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/interceptors_2.js b/tests/compiler/dart2js/cps_ir/expected/interceptors_2.js
new file mode 100644
index 0000000..fdb0701
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/interceptors_2.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// main() {
+//   var l = ['hest', ['h', 'e', 's', 't']];
+//   print(l.length);
+//   for (int i  = 0; i < l.length; i++) {
+//     var x = l[i];
+//     for (int j = 0; j < x.length; j++) {
+//       print(x[j]);
+//     }
+//   }
+// }
+
+function() {
+  var l = ["hest", ["h", "e", "s", "t"]], i = 0, x, j;
+  for (P.print(2); i < 2; ++i) {
+    x = l[i];
+    for (j = 0; j < x.length; ++j)
+      P.print(x[j]);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/literals_1.js b/tests/compiler/dart2js/cps_ir/expected/literals_1.js
new file mode 100644
index 0000000..ef654f5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/literals_1.js
@@ -0,0 +1,20 @@
+// Expectation for test: 
+// main() {
+//   print([]);
+//   print([1]);
+//   print([1, 2]);
+//   print([1, [1, 2]]);
+//   print({});
+//   print({1: 2});
+//   print({[1, 2]: [3, 4]});
+// }
+
+function() {
+  P.print([]);
+  P.print([1]);
+  P.print([1, 2]);
+  P.print([1, [1, 2]]);
+  P.print(P.LinkedHashMap_LinkedHashMap$_empty());
+  P.print(P.LinkedHashMap_LinkedHashMap$_literal([1, 2]));
+  P.print(P.LinkedHashMap_LinkedHashMap$_literal([[1, 2], [3, 4]]));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_1.js b/tests/compiler/dart2js/cps_ir/expected/operators2_1.js
new file mode 100644
index 0000000..5e39b1e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_1.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a, b) => ((a & 0xff0000) >> 1) & b;
+// main() {
+//   print(foo(123, 234));
+//   print(foo(0, 2));
+// }
+
+function() {
+  P.print((123 & 16711680) >>> 1 & 234);
+  P.print((0 & 16711680) >>> 1 & 2);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_2.js b/tests/compiler/dart2js/cps_ir/expected/operators2_2.js
new file mode 100644
index 0000000..8d6d52d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_2.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a) => ~a;
+// main() {
+//   print(foo(1));
+//   print(foo(10));
+// }
+
+function() {
+  P.print(~1 >>> 0);
+  P.print(~10 >>> 0);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_3.js b/tests/compiler/dart2js/cps_ir/expected/operators2_3.js
new file mode 100644
index 0000000..ff5d25d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_3.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// // Method to test: function(foo)
+// foo(a) => a % 13;
+// main() {
+//   print(foo(5));
+//   print(foo(-100));
+// }
+
+function(a) {
+  var result = a % 13;
+  return result === 0 ? 0 : result > 0 ? result : 13 < 0 ? result - 13 : result + 13;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_4.js b/tests/compiler/dart2js/cps_ir/expected/operators2_4.js
new file mode 100644
index 0000000..4f5c0f0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_4.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a) => a % 13;
+// main() {
+//   print(foo(5));
+//   print(foo(100));
+// }
+
+function() {
+  P.print(5 % 13);
+  P.print(100 % 13);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_5.js b/tests/compiler/dart2js/cps_ir/expected/operators2_5.js
new file mode 100644
index 0000000..a07d368
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_5.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a) => a.remainder(13);
+// main() {
+//   print(foo(5));
+//   print(foo(-100));
+// }
+
+function() {
+  P.print(5 % 13);
+  P.print(-100 % 13);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_6.js b/tests/compiler/dart2js/cps_ir/expected/operators2_6.js
new file mode 100644
index 0000000..79fe43a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_6.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// // Method to test: function(foo)
+// foo(a) => a ~/ 13;
+// main() {
+//   print(foo(5));
+//   print(foo(-100));
+// }
+
+function(a) {
+  return (a | 0) === a && (13 | 0) === 13 ? a / 13 | 0 : C.JSNumber_methods.toInt$0(a / 13);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_7.js b/tests/compiler/dart2js/cps_ir/expected/operators2_7.js
new file mode 100644
index 0000000..837393f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_7.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// foo(a) => a ~/ 13;
+// main() {
+//   print(foo(5));
+//   print(foo(100));
+// }
+
+function() {
+  P.print(5 / 13 | 0);
+  P.print(100 / 13 | 0);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_8.js b/tests/compiler/dart2js/cps_ir/expected/operators2_8.js
new file mode 100644
index 0000000..2f1ce60
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_8.js
@@ -0,0 +1,11 @@
+// Expectation for test: 
+// // Method to test: function(foo)
+// foo(a) => a ~/ 13;
+// main() {
+//   print(foo(5));
+//   print(foo(8000000000));
+// }
+
+function(a) {
+  return (a | 0) === a && (13 | 0) === 13 ? a / 13 | 0 : C.JSNumber_methods.toInt$0(a / 13);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_1.js b/tests/compiler/dart2js/cps_ir/expected/operators_1.js
new file mode 100644
index 0000000..dd0ddca
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_1.js
@@ -0,0 +1,6 @@
+// Expectation for test: 
+// main() { return true ? 42 : 'foo'; }
+
+function() {
+  return 42;
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_2.js b/tests/compiler/dart2js/cps_ir/expected/operators_2.js
new file mode 100644
index 0000000..4b6236b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_2.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// var x = 1;
+// foo() => ++x > 10;
+// main() {
+//   print(foo() ? "hello world" : "bad bad");
+// }
+
+function() {
+  var v0 = $.x + 1;
+  $.x = v0;
+  v0 = v0 > 10 ? "hello world" : "bad bad";
+  if (typeof dartPrint == "function")
+    dartPrint(v0);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(v0);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(v0);
+    print(v0);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_3.js b/tests/compiler/dart2js/cps_ir/expected/operators_3.js
new file mode 100644
index 0000000..525b95f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_3.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// var x = 1;
+// get foo => ++x > 10;
+// main() {
+//   print(foo ? "hello world" : "bad bad");
+// }
+
+function() {
+  var v0 = $.x + 1;
+  $.x = v0;
+  v0 = v0 > 10 ? "hello world" : "bad bad";
+  if (typeof dartPrint == "function")
+    dartPrint(v0);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(v0);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(v0);
+    print(v0);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_4.js b/tests/compiler/dart2js/cps_ir/expected/operators_4.js
new file mode 100644
index 0000000..f86a490
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_4.js
@@ -0,0 +1,30 @@
+// Expectation for test: 
+// var x = 1;
+// get foo => ++x > 10;
+// main() { print(foo && foo); }
+
+function() {
+  var v0 = $.x + 1, line;
+  $.x = v0;
+  L0: {
+    if (v0 > 10) {
+      $.x = v0 = $.x + 1;
+      if (v0 > 10) {
+        line = "true";
+        break L0;
+      }
+      v0 = false;
+    } else
+      v0 = false;
+    line = false === v0 ? "false" : String(v0);
+  }
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_5.js b/tests/compiler/dart2js/cps_ir/expected/operators_5.js
new file mode 100644
index 0000000..3ff812c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_5.js
@@ -0,0 +1,28 @@
+// Expectation for test: 
+// var x = 1;
+// get foo => ++x > 10;
+// main() { print(foo || foo); }
+
+function() {
+  var v0 = $.x + 1, line;
+  $.x = v0;
+  L0: {
+    if (!(v0 > 10)) {
+      $.x = v0 = $.x + 1;
+      if (!(v0 > 10)) {
+        line = false === false ? "false" : String(false);
+        break L0;
+      }
+    }
+    line = "true";
+  }
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_6.js b/tests/compiler/dart2js/cps_ir/expected/operators_6.js
new file mode 100644
index 0000000..10e71da
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_6.js
@@ -0,0 +1,7 @@
+// Expectation for test: 
+// get foo => foo;
+// main() { print(foo || foo); }
+
+function() {
+  V.foo();
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_7.js b/tests/compiler/dart2js/cps_ir/expected/operators_7.js
new file mode 100644
index 0000000..b81aaa9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_7.js
@@ -0,0 +1,24 @@
+// Expectation for test: 
+// class Foo {
+//   operator[]=(index, value) {
+//     print(value);
+//   }
+// }
+// main() {
+//   var foo = new Foo();
+//   foo[5] = 6;
+// }
+
+function() {
+  var line = "" + 6;
+  V.Foo$();
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_8.js b/tests/compiler/dart2js/cps_ir/expected/operators_8.js
new file mode 100644
index 0000000..3f1c27e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_8.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// main() {
+//   var list = [1, 2, 3];
+//   list[1] = 6;
+//   print(list);
+// }
+
+function() {
+  var list = [1, 2, 3], res;
+  list[1] = 6;
+  res = P.IterableBase_iterableToFullString(list, "[", "]");
+  if (typeof dartPrint == "function")
+    dartPrint(res);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(res);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(res);
+    print(res);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/runtime_types_1.js b/tests/compiler/dart2js/cps_ir/expected/runtime_types_1.js
new file mode 100644
index 0000000..914008d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/runtime_types_1.js
@@ -0,0 +1,21 @@
+// Expectation for test: 
+// class C<T> {
+//   foo() => print(T);
+// }
+// 
+// main() {
+//   new C<int>().foo();
+// }
+
+function() {
+  var line = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getTypeArgumentByIndex(V.C$(P.$int), 0))));
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/runtime_types_2.js b/tests/compiler/dart2js/cps_ir/expected/runtime_types_2.js
new file mode 100644
index 0000000..d22895f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/runtime_types_2.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// class C<T, U> {
+//   foo() => print(U);
+// }
+// 
+// class D extends C<int, double> {}
+// 
+// main() {
+//   new D().foo();
+// }
+
+function() {
+  var line = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getRuntimeTypeArgument(V.D$(), "C", 1))));
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/runtime_types_3.js b/tests/compiler/dart2js/cps_ir/expected/runtime_types_3.js
new file mode 100644
index 0000000..435bb62
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/runtime_types_3.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// class C<T> {
+//   foo() => new D<C<T>>();
+// }
+// class D<T> {
+//   bar() => T;
+// }
+// main() {
+//   print(new C<int>().foo().bar());
+// }
+
+function() {
+  var line = H.S(H.createRuntimeType(H.runtimeTypeToString(H.getTypeArgumentByIndex(V.D$([V.C, H.getTypeArgumentByIndex(V.C$(P.$int), 0)]), 0))));
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/runtime_types_4.js b/tests/compiler/dart2js/cps_ir/expected/runtime_types_4.js
new file mode 100644
index 0000000..823dbe9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/runtime_types_4.js
@@ -0,0 +1,12 @@
+// Expectation for test: 
+// // Method to test: generative_constructor(C#)
+// class C<X, Y, Z> {
+//   foo() => 'C<$X $Y, $Z>';
+// }
+// main() {
+//   new C<C, int, String>().foo();
+// }
+
+function($X, $Y, $Z) {
+  return H.setRuntimeTypeInfo(new V.C(), [$X, $Y, $Z]);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_1.js b/tests/compiler/dart2js/cps_ir/expected/supercall_1.js
new file mode 100644
index 0000000..4c7ee26
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/supercall_1.js
@@ -0,0 +1,26 @@
+// Expectation for test: 
+// class Base {
+//   m(x) {
+//     print(x+1);
+//   }
+// }
+// class Sub extends Base {
+//   m(x) => super.m(x+10);
+// }
+// main() {
+//   new Sub().m(100);
+// }
+
+function() {
+  var line = "" + (100 + 10 + 1);
+  V.Sub$();
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_2.js b/tests/compiler/dart2js/cps_ir/expected/supercall_2.js
new file mode 100644
index 0000000..13b1d21
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/supercall_2.js
@@ -0,0 +1,29 @@
+// Expectation for test: 
+// // TODO(sigmund): change this to check method "function(Sub#+)" once we provide
+// // a way to disable inlining of Sub#+, which is compiled to something like:
+// // function(x) {
+// //   var v0, v1, v2;
+// //   v0 = 1;
+// //   v1 = J.getInterceptor$ns(x).$add(x, v0);
+// //   v2 = this;
+// //   return V.Base.prototype.$add.call(null, v2, v1);
+// // }
+// 
+// class Base {
+//   m(x) {
+//     print(x+1000);
+//   }
+//   operator+(x) => m(x+10);
+// }
+// class Sub extends Base {
+//   m(x) => super.m(x+100);
+//   operator+(x) => super + (x+1);
+// }
+// main() {
+//   new Sub() + 10000;
+// }
+
+function() {
+  var v0 = V.Sub$();
+  V.Base.prototype.$add.call(v0, v0, 10000 + 1);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_3.js b/tests/compiler/dart2js/cps_ir/expected/supercall_3.js
new file mode 100644
index 0000000..ffc1752
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/supercall_3.js
@@ -0,0 +1,23 @@
+// Expectation for test: 
+// class Base {
+//   var field = 123;
+// }
+// class Sub extends Base {
+//   m(x) => x + super.field;
+// }
+// main() {
+//   print(new Sub().m(10));
+// }
+
+function() {
+  var line = "" + (10 + V.Sub$().field);
+  if (typeof dartPrint == "function")
+    dartPrint(line);
+  else if (typeof console == "object" && typeof console.log != "undefined")
+    console.log(line);
+  else if (!(typeof window == "object")) {
+    if (!(typeof print == "function"))
+      throw "Unable to print message: " + String(line);
+    print(line);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/gvn_1_test.dart b/tests/compiler/dart2js/cps_ir/gvn_1_test.dart
new file mode 100644
index 0000000..e341e5d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/gvn_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.gvn_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("gvn_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_1.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_1.dart
new file mode 100644
index 0000000..e807927
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_1.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x - y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_10.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_10.dart
new file mode 100644
index 0000000..85143eb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_10.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x > y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_11.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_11.dart
new file mode 100644
index 0000000..eca7811
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_11.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x < y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_12.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_12.dart
new file mode 100644
index 0000000..7ad1e67
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_12.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x >= y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_13.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_13.dart
new file mode 100644
index 0000000..6083767
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_13.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x <= y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_14.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_14.dart
new file mode 100644
index 0000000..09c8e76
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_14.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x.remainder(y));
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_15.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_15.dart
new file mode 100644
index 0000000..5724188
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_15.dart
@@ -0,0 +1,12 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  var z = int.parse('1235');
+  print(x is num);
+  print(y is num);
+  print(z is num);
+  print(x.clamp(y, z));
+  print(x is num);
+  print(y is num);
+  print(z is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_16.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_16.dart
new file mode 100644
index 0000000..f7655f4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_16.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x + y);
+  print(x is num);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_17.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_17.dart
new file mode 100644
index 0000000..20dd689
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_17.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x * y);
+  print(x is num);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_18.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_18.dart
new file mode 100644
index 0000000..aae68b8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_18.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x.compareTo(y));
+  print(x is num);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_19.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_19.dart
new file mode 100644
index 0000000..a61936e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_19.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x / 2);
+  print(x is num);
+  print(y is num);
+  print(x + y);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_2.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_2.dart
new file mode 100644
index 0000000..2021ca9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_2.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x / y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_20.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_20.dart
new file mode 100644
index 0000000..d8a5b4d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_20.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x / 2);
+  print(x is num);
+  print(y is num);
+  print(x * y);
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_21.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_21.dart
new file mode 100644
index 0000000..ae28a0e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_21.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x / 2);
+  print(x is num);
+  print(y is num);
+  print(x.compareTo(y));
+  print(y is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_22.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_22.dart
new file mode 100644
index 0000000..988edd7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_22.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is int);
+  print(y is int);
+  print(x.toSigned(y));
+  print(x is int);
+  print(y is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_23.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_23.dart
new file mode 100644
index 0000000..c727aa8
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_23.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is int);
+  print(y is int);
+  print(x.toUnsigned(y));
+  print(x is int);
+  print(y is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_24.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_24.dart
new file mode 100644
index 0000000..1b2aef6
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_24.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is int);
+  print(y is int);
+  print(x.modInverse(y));
+  print(x is int);
+  print(y is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_25.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_25.dart
new file mode 100644
index 0000000..740bb92
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_25.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is int);
+  print(y is int);
+  print(x.gcd(y));
+  print(x is int);
+  print(y is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_26.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_26.dart
new file mode 100644
index 0000000..dfdd56b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_26.dart
@@ -0,0 +1,12 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  var z = int.parse('1235');
+  print(x is int);
+  print(y is int);
+  print(z is int);
+  print(x.modPow(y, z));
+  print(x is int);
+  print(y is int);
+  print(z is int);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_27.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_27.dart
new file mode 100644
index 0000000..b53d2df
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_27.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('3');
+  var y = int.parse('a', onError: (e) => 'abcde');
+  print(x is int);
+  print(y is String);
+  print(y.codeUnitAt(x));
+  print(x is int);
+  print(y is String);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_28.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_28.dart
new file mode 100644
index 0000000..cbea9617
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_28.dart
@@ -0,0 +1,20 @@
+import 'dart:math';
+main() {
+  var x = int.parse('3');
+  var y = int.parse('1234');
+  var z = int.parse('1236');
+  var w = int.parse('2');
+  print(x is num);
+  print(sin(x));
+  print(x is num);
+
+  print(y is num);
+  print(log(y));
+  print(y is num);
+
+  print(z is num);
+  print(w is num);
+  print(pow(z, w));
+  print(z is num);
+  print(w is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_3.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_3.dart
new file mode 100644
index 0000000..8353ddf
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_3.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x % y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_4.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_4.dart
new file mode 100644
index 0000000..958363a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_4.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x ~/ y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_5.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_5.dart
new file mode 100644
index 0000000..c46235b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_5.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x >> y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_6.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_6.dart
new file mode 100644
index 0000000..461da84
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_6.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x << y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_7.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_7.dart
new file mode 100644
index 0000000..c5f7d72
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_7.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x & y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_8.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_8.dart
new file mode 100644
index 0000000..9aef9e2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_8.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x | y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_9.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_9.dart
new file mode 100644
index 0000000..22266c7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_9.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x ^ y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_1.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_1.dart
new file mode 100644
index 0000000..e807927
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_1.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x - y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_10.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_10.dart
new file mode 100644
index 0000000..eca7811
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_10.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x < y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_11.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_11.dart
new file mode 100644
index 0000000..85143eb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_11.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x > y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_12.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_12.dart
new file mode 100644
index 0000000..6083767
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_12.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x <= y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_13.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_13.dart
new file mode 100644
index 0000000..7ad1e67
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_13.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x >= y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_14.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_14.dart
new file mode 100644
index 0000000..09c8e76
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_14.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x.remainder(y));
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_15.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_15.dart
new file mode 100644
index 0000000..227e62e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_15.dart
@@ -0,0 +1,12 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  var z = int.parse('1236');
+  print(x is num);
+  print(y is num);
+  print(z is num);
+  print(x.clamp(y, z));
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+  print(z is num);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_16.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_16.dart
new file mode 100644
index 0000000..c757d08
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_16.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x + y);
+  print(x is num);
+  print(y is num); // will stay as is-num because String could be a target of +
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_17.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_17.dart
new file mode 100644
index 0000000..9dd57c3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_17.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x * y);
+  print(x is num);
+  print(y is num); // will stay as is-num because String could be a target of *
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_2.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_2.dart
new file mode 100644
index 0000000..2021ca9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_2.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x / y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_3.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_3.dart
new file mode 100644
index 0000000..8353ddf
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_3.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x % y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_4.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_4.dart
new file mode 100644
index 0000000..958363a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_4.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x ~/ y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_5.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_5.dart
new file mode 100644
index 0000000..c46235b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_5.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x >> y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_6.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_6.dart
new file mode 100644
index 0000000..461da84
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_6.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x << y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_7.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_7.dart
new file mode 100644
index 0000000..c5f7d72
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_7.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x & y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_8.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_8.dart
new file mode 100644
index 0000000..9aef9e2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_8.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x | y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_9.dart b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_9.dart
new file mode 100644
index 0000000..22266c7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_9.dart
@@ -0,0 +1,9 @@
+main() {
+  var x = int.parse('1233');
+  var y = int.parse('1234');
+  print(x is num);
+  print(y is num);
+  print(x ^ y);
+  print(x is num);
+  print(y is num); // will be compiled to `true` if we know the type of `y`.
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_1.dart b/tests/compiler/dart2js/cps_ir/input/basic_1.dart
new file mode 100644
index 0000000..ee77081
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_1.dart
@@ -0,0 +1,14 @@
+main() {
+  var e = 1;
+  var l = [1, 2, 3];
+  var m = {'s': 1};
+
+  print('(' ')');
+  print('(${true})');
+  print('(${1})');
+  print('(${[1, 2, 3]})');
+  print('(${{'s': 1}})');
+  print('($e)');
+  print('($l)');
+  print('($m)');
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_10.dart b/tests/compiler/dart2js/cps_ir/input/basic_10.dart
new file mode 100644
index 0000000..e5a56a0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_10.dart
@@ -0,0 +1,3 @@
+main() {
+  print(new DateTime.now().isBefore(new DateTime.now()));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_11.dart b/tests/compiler/dart2js/cps_ir/input/basic_11.dart
new file mode 100644
index 0000000..34c8802
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_11.dart
@@ -0,0 +1,3 @@
+foo() { print(42); }
+main() { foo(); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_12.dart b/tests/compiler/dart2js/cps_ir/input/basic_12.dart
new file mode 100644
index 0000000..d48fb05
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_12.dart
@@ -0,0 +1,3 @@
+var foo = 42;
+main() { print(foo); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_13.dart b/tests/compiler/dart2js/cps_ir/input/basic_13.dart
new file mode 100644
index 0000000..3582183
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_13.dart
@@ -0,0 +1,3 @@
+get foo { print(42); }
+main() { foo; }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_14.dart b/tests/compiler/dart2js/cps_ir/input/basic_14.dart
new file mode 100644
index 0000000..f39e531
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_14.dart
@@ -0,0 +1,3 @@
+var foo = 0;
+main() { print(foo = 42); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_15.dart b/tests/compiler/dart2js/cps_ir/input/basic_15.dart
new file mode 100644
index 0000000..5ecc7ac
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_15.dart
@@ -0,0 +1,3 @@
+set foo(x) { print(x); }
+main() { foo = 42; }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_16.dart b/tests/compiler/dart2js/cps_ir/input/basic_16.dart
new file mode 100644
index 0000000..749ce68
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_16.dart
@@ -0,0 +1,7 @@
+foo() { print('X'); }
+main() {
+  assert(true);
+  assert(false);
+  assert(foo());
+  print('Done');
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_2.dart b/tests/compiler/dart2js/cps_ir/input/basic_2.dart
new file mode 100644
index 0000000..6305610
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_2.dart
@@ -0,0 +1,11 @@
+foo(a, [b = "b"]) { print(b); return b; }
+bar(a, {b: "b", c: "c"}) { print(c); return c; }
+main() {
+  foo(0);
+  foo(1, 2);
+  bar(3);
+  bar(4, b: 5);
+  bar(6, c: 7);
+  bar(8, b: 9, c: 10);
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_3.dart b/tests/compiler/dart2js/cps_ir/input/basic_3.dart
new file mode 100644
index 0000000..95ffd22
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_3.dart
@@ -0,0 +1,17 @@
+foo(a) {
+  print(a);
+  return a;
+}
+main() {
+  var a = 10;
+  var b = 1;
+  var t;
+  t = a;
+  a = b;
+  b = t;
+  print(a);
+  print(b);
+  print(b);
+  print(foo(a));
+}
+  
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_4.dart b/tests/compiler/dart2js/cps_ir/input/basic_4.dart
new file mode 100644
index 0000000..1e74c32
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_4.dart
@@ -0,0 +1,3 @@
+foo() { print(42); return 42; }
+main() { return foo(); }
+  
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_5.dart b/tests/compiler/dart2js/cps_ir/input/basic_5.dart
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_5.dart
@@ -0,0 +1 @@
+main() {}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_6.dart b/tests/compiler/dart2js/cps_ir/input/basic_6.dart
new file mode 100644
index 0000000..f55f628
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_6.dart
@@ -0,0 +1 @@
+main() { return 42; }
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_7.dart b/tests/compiler/dart2js/cps_ir/input/basic_7.dart
new file mode 100644
index 0000000..98b304d
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_7.dart
@@ -0,0 +1 @@
+main() { return; }
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_8.dart b/tests/compiler/dart2js/cps_ir/input/basic_8.dart
new file mode 100644
index 0000000..e6ebb66
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_8.dart
@@ -0,0 +1,4 @@
+main() {
+  print(new Set());
+  print(new Set.from([1, 2, 3]));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_9.dart b/tests/compiler/dart2js/cps_ir/input/basic_9.dart
new file mode 100644
index 0000000..15a7643
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/basic_9.dart
@@ -0,0 +1,4 @@
+class C {}
+main() {
+  print(new C());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_1.dart b/tests/compiler/dart2js/cps_ir/input/closures_1.dart
new file mode 100644
index 0000000..f47a0a0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_1.dart
@@ -0,0 +1,8 @@
+main(x) {
+  a() {
+    return x;
+  }
+  x = x + '1';
+  print(a());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_10.dart b/tests/compiler/dart2js/cps_ir/input/closures_10.dart
new file mode 100644
index 0000000..542d012
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_10.dart
@@ -0,0 +1,8 @@
+class A {
+  a() => 1;
+  b() => () => a();
+}
+main() {
+  print(new A().b()());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_11.dart b/tests/compiler/dart2js/cps_ir/input/closures_11.dart
new file mode 100644
index 0000000..cd8e049
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_11.dart
@@ -0,0 +1,6 @@
+staticMethod(x) { print(x); return x; }
+main(x) {
+  var tearOff = staticMethod;
+  print(tearOff(123));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_12.dart b/tests/compiler/dart2js/cps_ir/input/closures_12.dart
new file mode 100644
index 0000000..9e787fa
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_12.dart
@@ -0,0 +1,8 @@
+class Foo {
+  instanceMethod(x) => x;
+}
+main(x) {
+  var tearOff = new Foo().instanceMethod;
+  print(tearOff(123));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_13.dart b/tests/compiler/dart2js/cps_ir/input/closures_13.dart
new file mode 100644
index 0000000..9994ca3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_13.dart
@@ -0,0 +1,9 @@
+class Foo {
+  instanceMethod(x) => x;
+}
+main(x) {
+  var tearOff = new Foo().instanceMethod;
+  print(tearOff(123));
+  print(tearOff(321));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_14.dart b/tests/compiler/dart2js/cps_ir/input/closures_14.dart
new file mode 100644
index 0000000..5ef8e6c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_14.dart
@@ -0,0 +1,12 @@
+class Foo {
+  get getter {
+    print('getter');
+    return (x) => x;
+  }
+}
+main(x) {
+  var notTearOff = new Foo().getter;
+  print(notTearOff(123));
+  print(notTearOff(321));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_15.dart b/tests/compiler/dart2js/cps_ir/input/closures_15.dart
new file mode 100644
index 0000000..55e1263
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_15.dart
@@ -0,0 +1,11 @@
+class Foo {
+  get getter {
+    print('getter');
+    return (x) => x;
+  }
+}
+main(x) {
+  var notTearOff = new Foo().getter;
+  print(notTearOff(123));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_2.dart b/tests/compiler/dart2js/cps_ir/input/closures_2.dart
new file mode 100644
index 0000000..7c8ad36
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_2.dart
@@ -0,0 +1,9 @@
+main(x) {
+  a() {
+    return x;
+  }
+  x = x + '1';
+  print(a());
+  return a;
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_3.dart b/tests/compiler/dart2js/cps_ir/input/closures_3.dart
new file mode 100644
index 0000000..6e4f5d9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_3.dart
@@ -0,0 +1,7 @@
+main(x) {
+  a() {
+    return x;
+  }
+  print(a());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_4.dart b/tests/compiler/dart2js/cps_ir/input/closures_4.dart
new file mode 100644
index 0000000..e6be22c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_4.dart
@@ -0,0 +1,8 @@
+main(x) {
+  a() {
+    return x;
+  }
+  print(a());
+  return a;
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_5.dart b/tests/compiler/dart2js/cps_ir/input/closures_5.dart
new file mode 100644
index 0000000..3e35ec0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_5.dart
@@ -0,0 +1,7 @@
+main() {
+  var x = 122;
+  var a = () => x;
+  x = x + 1;
+  print(a());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_6.dart b/tests/compiler/dart2js/cps_ir/input/closures_6.dart
new file mode 100644
index 0000000..e9ff65b
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_6.dart
@@ -0,0 +1,8 @@
+main() {
+  var x = 122;
+  var a = () => x;
+  x = x + 1;
+  print(a());
+  return a;
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_7.dart b/tests/compiler/dart2js/cps_ir/input/closures_7.dart
new file mode 100644
index 0000000..05087ca
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_7.dart
@@ -0,0 +1,10 @@
+main() {
+  var x = 122;
+  var a = () {
+    var y = x;
+    return () => y;
+  };
+  x = x + 1;
+  print(a()());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_8.dart b/tests/compiler/dart2js/cps_ir/input/closures_8.dart
new file mode 100644
index 0000000..2b6e8c5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_8.dart
@@ -0,0 +1,11 @@
+main() {
+  var x = 122;
+  var a = () {
+    var y = x;
+    return () => y;
+  };
+  x = x + 1;
+  print(a()());
+  return a;
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_9.dart b/tests/compiler/dart2js/cps_ir/input/closures_9.dart
new file mode 100644
index 0000000..185576a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_9.dart
@@ -0,0 +1,8 @@
+main() {
+  var a;
+  for (var i=0; i<10; i++) {
+    a = () => i;
+  }
+  print(a());
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/codeUnitAt_1.dart b/tests/compiler/dart2js/cps_ir/input/codeUnitAt_1.dart
new file mode 100644
index 0000000..c39bc74
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/codeUnitAt_1.dart
@@ -0,0 +1,4 @@
+// Constant folding
+main() {
+  print('A'.codeUnitAt(0));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/codeUnitAt_2.dart b/tests/compiler/dart2js/cps_ir/input/codeUnitAt_2.dart
new file mode 100644
index 0000000..a26c359
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/codeUnitAt_2.dart
@@ -0,0 +1,10 @@
+// Bounds checking
+foo(s) {
+  var sum = 0;
+  for (int i = 0; i < s.length; i++) sum += s.codeUnitAt(i);
+  return sum;
+}
+main() {
+  print(foo('ABC'));
+  print(foo('Hello'));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_1.dart b/tests/compiler/dart2js/cps_ir/input/constructor_1.dart
new file mode 100644
index 0000000..1cc265a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_1.dart
@@ -0,0 +1,11 @@
+class Base {
+  var x;
+  Base(this.x);
+}
+class Sub extends Base {
+  var y;
+  Sub(x, this.y) : super(x);
+}
+main() {
+  print(new Sub(1, 2).x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_10.dart b/tests/compiler/dart2js/cps_ir/input/constructor_10.dart
new file mode 100644
index 0000000..1e3dddc
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_10.dart
@@ -0,0 +1,11 @@
+// Method to test: generative_constructor(C#)
+class C<T> {
+  var x;
+  C() : x = new D<T>();
+}
+class D<T> {
+  foo() => T;
+}
+main() {
+  print(new C<int>().x.foo());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_11.dart b/tests/compiler/dart2js/cps_ir/input/constructor_11.dart
new file mode 100644
index 0000000..c4ee04c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_11.dart
@@ -0,0 +1,8 @@
+class A {
+  var x;
+  A() : this.b(1);
+  A.b(this.x);
+}
+main() {
+  print(new A().x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_12.dart b/tests/compiler/dart2js/cps_ir/input/constructor_12.dart
new file mode 100644
index 0000000..efafb99
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_12.dart
@@ -0,0 +1,11 @@
+class Foo {
+  factory Foo.make(x) {
+    print('Foo');
+    return new Foo.create(x);
+  }
+  var x;
+  Foo.create(this.x);
+}
+main() {
+  print(new Foo.make(5));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_13.dart b/tests/compiler/dart2js/cps_ir/input/constructor_13.dart
new file mode 100644
index 0000000..dcba070
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_13.dart
@@ -0,0 +1,8 @@
+class Foo {
+  factory Foo.make(x) = Foo.create;
+  var x;
+  Foo.create(this.x);
+}
+main() {
+  print(new Foo.make(5));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_14.dart b/tests/compiler/dart2js/cps_ir/input/constructor_14.dart
new file mode 100644
index 0000000..b22bbcb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_14.dart
@@ -0,0 +1,13 @@
+class A {
+  factory A(x) = B<int>;
+  get typevar;
+}
+class B<T> implements A {
+  var x;
+  B(this.x);
+
+  get typevar => T;
+}
+main() {
+  new A(5).typevar;
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_2.dart b/tests/compiler/dart2js/cps_ir/input/constructor_2.dart
new file mode 100644
index 0000000..23ac512
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_2.dart
@@ -0,0 +1,13 @@
+class Base {
+  var x;
+  Base(this.x);
+}
+class Sub extends Base {
+  var y;
+  Sub(x, this.y) : super(x) {
+    print(x);
+  }
+}
+main() {
+  print(new Sub(1, 2).x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_3.dart b/tests/compiler/dart2js/cps_ir/input/constructor_3.dart
new file mode 100644
index 0000000..7a532a3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_3.dart
@@ -0,0 +1,18 @@
+class Base0 {
+  Base0() {
+    print('Base0');
+  }
+}
+class Base extends Base0 {
+  var x;
+  Base(this.x);
+}
+class Sub extends Base {
+  var y;
+  Sub(x, this.y) : super(x) {
+    print(x);
+  }
+}
+main() {
+  print(new Sub(1, 2).x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_4.dart b/tests/compiler/dart2js/cps_ir/input/constructor_4.dart
new file mode 100644
index 0000000..5f14854
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_4.dart
@@ -0,0 +1,20 @@
+class Base0 {
+  Base0() {
+    print('Base0');
+  }
+}
+class Base extends Base0 {
+  var x;
+  Base(x1) : x = (() => ++x1) {
+    print(x1); // use boxed x1
+  }
+}
+class Sub extends Base {
+  var y;
+  Sub(x, this.y) : super(x) {
+    print(x);
+  }
+}
+main() {
+  print(new Sub(1, 2).x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_5.dart b/tests/compiler/dart2js/cps_ir/input/constructor_5.dart
new file mode 100644
index 0000000..f615668
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_5.dart
@@ -0,0 +1,19 @@
+foo(x) {
+  print(x);
+}
+class Base {
+  var x1 = foo('x1');
+  var x2;
+  var x3 = foo('x3');
+  Base() : x2 = foo('x2');
+}
+class Sub extends Base {
+  var y1 = foo('y1');
+  var y2;
+  var y3;
+  Sub() : y2 = foo('y2'), super(), y3 = foo('y3');
+}
+main() {
+  new Sub();
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_6.dart b/tests/compiler/dart2js/cps_ir/input/constructor_6.dart
new file mode 100644
index 0000000..f1c6b51
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_6.dart
@@ -0,0 +1,16 @@
+class Bar {
+  Bar(x, {y, z: 'z', w: '_', q}) {
+    print(x);
+    print(y);
+    print(z);
+    print(w);
+    print(q);
+  }
+}
+class Foo extends Bar {
+  Foo() : super('x', y: 'y', w: 'w');
+}
+main() {
+  new Foo();
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_7.dart b/tests/compiler/dart2js/cps_ir/input/constructor_7.dart
new file mode 100644
index 0000000..32af53c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_7.dart
@@ -0,0 +1,6 @@
+class C<T> {
+  foo() => T;
+}
+main() {
+  print(new C<int>().foo());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_8.dart b/tests/compiler/dart2js/cps_ir/input/constructor_8.dart
new file mode 100644
index 0000000..3e72ab1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_8.dart
@@ -0,0 +1,6 @@
+class C<T> {
+  foo() => C;
+}
+main() {
+  print(new C<int>().foo());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_9.dart b/tests/compiler/dart2js/cps_ir/input/constructor_9.dart
new file mode 100644
index 0000000..fe8dfbf
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/constructor_9.dart
@@ -0,0 +1,8 @@
+// Method to test: generative_constructor(C#)
+class C<T> {
+  C() { print(T); }
+  foo() => print(T);
+}
+main() {
+  new C<int>();
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_1.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_1.dart
new file mode 100644
index 0000000..72e7e7c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_1.dart
@@ -0,0 +1,4 @@
+main() {
+  while (true);
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart
new file mode 100644
index 0000000..dd06bed
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart
@@ -0,0 +1,14 @@
+foo(a) { print(a); return a; }
+
+main() {
+  while (true) {
+    l: while (true) {
+      while (foo(true)) {
+        if (foo(false)) break l;
+      }
+      print(1);
+    }
+    print(2);
+  }
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart
new file mode 100644
index 0000000..51cead4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart
@@ -0,0 +1,9 @@
+foo(a) { print(a); return a; }
+
+main() {
+  for (int i = 0; foo(true); i = foo(i)) {
+    print(1);
+    if (foo(false)) break;
+  }
+  print(2);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart
new file mode 100644
index 0000000..881d8ce
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart
@@ -0,0 +1,11 @@
+foo(a) { print(a); return a; }
+
+main() {
+ foo(false);
+ if (foo(true)) {
+   print(1);
+ } else {
+   print(2);
+ }
+ print(3);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart
new file mode 100644
index 0000000..6efe03c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart
@@ -0,0 +1,13 @@
+foo(a) { print(a); return a; }
+
+main() {
+ foo(false);
+ if (foo(true)) {
+   print(1);
+   print(1);
+ } else {
+   print(2);
+   print(2);
+ }
+ print(3);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_6.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_6.dart
new file mode 100644
index 0000000..58550fe
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_6.dart
@@ -0,0 +1,7 @@
+main() {
+  if (1) {
+    print('bad');
+  } else {
+    print('good');
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_7.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_7.dart
new file mode 100644
index 0000000..66709ff
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_7.dart
@@ -0,0 +1,8 @@
+foo() { print('2'); return 2; }
+main() {
+  if (foo()) {
+    print('bad');
+  } else {
+    print('good');
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_8.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_8.dart
new file mode 100644
index 0000000..62c6fed
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_8.dart
@@ -0,0 +1,6 @@
+main() {
+  var list = [1,2,3,4,5,6];
+  for (var x in list) {
+    print(x);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_9.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_9.dart
new file mode 100644
index 0000000..7e59e5a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_9.dart
@@ -0,0 +1,8 @@
+main() {
+  var xs = ['x', 'y', 'z'], ys = ['A', 'B', 'C'];
+  var xit = xs.iterator, yit = ys.iterator;
+  while (xit.moveNext() && yit.moveNext()) {
+    print(xit.current);
+    print(yit.current);
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/gvn_1.dart b/tests/compiler/dart2js/cps_ir/input/gvn_1.dart
new file mode 100644
index 0000000..4953cb9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/gvn_1.dart
@@ -0,0 +1,41 @@
+foo(x, list) {
+  var sum = 0;
+  for (int k = 0; k < 10; k++) {
+    // Everything can be hoisted out up to the index access which is
+    // blocked by the bounds check.
+    var a = x.left.left;
+    var b = x.left.right;
+    var c = x.right.left;
+    var d = x.right.right;
+    var i = a.value + c.value;
+    var j = b.value + d.value;
+    var z = list[i * j] + i;
+    sum += z;
+  }
+  return sum;
+}
+// Use a different class for each level in the tree, so type inference
+// is not confused.
+class Root {
+  Branch left, right;
+  Root(this.left, this.right);
+}
+class Branch {
+  Leaf left, right;
+  Branch(this.left, this.right);
+}
+class Leaf {
+  int value;
+  Leaf(this.value);
+}
+main() {
+  var x1 = new Leaf(1);
+  var x2 = new Leaf(10);
+  var x3 = new Leaf(20);
+  var x4 = new Leaf(-10);
+  var y1 = new Branch(x1, x2);
+  var y2 = new Branch(x3, x4);
+  var z  = new Root(y1, y2);
+  print(foo(z, [1,2,3,4,5,6,7,8,9,10]));
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/interceptors_1.dart b/tests/compiler/dart2js/cps_ir/input/interceptors_1.dart
new file mode 100644
index 0000000..6363521
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/interceptors_1.dart
@@ -0,0 +1,6 @@
+main() {
+  var g = 1;
+
+  var x = g + 3;
+  print(x);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/interceptors_2.dart b/tests/compiler/dart2js/cps_ir/input/interceptors_2.dart
new file mode 100644
index 0000000..7853486
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/interceptors_2.dart
@@ -0,0 +1,10 @@
+main() {
+  var l = ['hest', ['h', 'e', 's', 't']];
+  print(l.length);
+  for (int i  = 0; i < l.length; i++) {
+    var x = l[i];
+    for (int j = 0; j < x.length; j++) {
+      print(x[j]);
+    }
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/literals_1.dart b/tests/compiler/dart2js/cps_ir/input/literals_1.dart
new file mode 100644
index 0000000..a5d7294
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/literals_1.dart
@@ -0,0 +1,10 @@
+main() {
+  print([]);
+  print([1]);
+  print([1, 2]);
+  print([1, [1, 2]]);
+  print({});
+  print({1: 2});
+  print({[1, 2]: [3, 4]});
+}
+
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_1.dart b/tests/compiler/dart2js/cps_ir/input/operators2_1.dart
new file mode 100644
index 0000000..05da19c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_1.dart
@@ -0,0 +1,5 @@
+foo(a, b) => ((a & 0xff0000) >> 1) & b;
+main() {
+  print(foo(123, 234));
+  print(foo(0, 2));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_2.dart b/tests/compiler/dart2js/cps_ir/input/operators2_2.dart
new file mode 100644
index 0000000..56bebd9
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_2.dart
@@ -0,0 +1,5 @@
+foo(a) => ~a;
+main() {
+  print(foo(1));
+  print(foo(10));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_3.dart b/tests/compiler/dart2js/cps_ir/input/operators2_3.dart
new file mode 100644
index 0000000..f1dc5ac
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_3.dart
@@ -0,0 +1,6 @@
+// Method to test: function(foo)
+foo(a) => a % 13;
+main() {
+  print(foo(5));
+  print(foo(-100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_4.dart b/tests/compiler/dart2js/cps_ir/input/operators2_4.dart
new file mode 100644
index 0000000..b9f5be2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_4.dart
@@ -0,0 +1,5 @@
+foo(a) => a % 13;
+main() {
+  print(foo(5));
+  print(foo(100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_5.dart b/tests/compiler/dart2js/cps_ir/input/operators2_5.dart
new file mode 100644
index 0000000..3ece837
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_5.dart
@@ -0,0 +1,5 @@
+foo(a) => a.remainder(13);
+main() {
+  print(foo(5));
+  print(foo(-100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_6.dart b/tests/compiler/dart2js/cps_ir/input/operators2_6.dart
new file mode 100644
index 0000000..4b763a6
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_6.dart
@@ -0,0 +1,6 @@
+// Method to test: function(foo)
+foo(a) => a ~/ 13;
+main() {
+  print(foo(5));
+  print(foo(-100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_7.dart b/tests/compiler/dart2js/cps_ir/input/operators2_7.dart
new file mode 100644
index 0000000..f2c68ee
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_7.dart
@@ -0,0 +1,5 @@
+foo(a) => a ~/ 13;
+main() {
+  print(foo(5));
+  print(foo(100));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_8.dart b/tests/compiler/dart2js/cps_ir/input/operators2_8.dart
new file mode 100644
index 0000000..05e3bb0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_8.dart
@@ -0,0 +1,6 @@
+// Method to test: function(foo)
+foo(a) => a ~/ 13;
+main() {
+  print(foo(5));
+  print(foo(8000000000));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_1.dart b/tests/compiler/dart2js/cps_ir/input/operators_1.dart
new file mode 100644
index 0000000..52e587e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_1.dart
@@ -0,0 +1 @@
+main() { return true ? 42 : 'foo'; }
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_2.dart b/tests/compiler/dart2js/cps_ir/input/operators_2.dart
new file mode 100644
index 0000000..c9049ed
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_2.dart
@@ -0,0 +1,5 @@
+var x = 1;
+foo() => ++x > 10;
+main() {
+  print(foo() ? "hello world" : "bad bad");
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_3.dart b/tests/compiler/dart2js/cps_ir/input/operators_3.dart
new file mode 100644
index 0000000..42ceb0e
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_3.dart
@@ -0,0 +1,5 @@
+var x = 1;
+get foo => ++x > 10;
+main() {
+  print(foo ? "hello world" : "bad bad");
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_4.dart b/tests/compiler/dart2js/cps_ir/input/operators_4.dart
new file mode 100644
index 0000000..3f07752
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_4.dart
@@ -0,0 +1,4 @@
+var x = 1;
+get foo => ++x > 10;
+main() { print(foo && foo); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_5.dart b/tests/compiler/dart2js/cps_ir/input/operators_5.dart
new file mode 100644
index 0000000..98756b6
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_5.dart
@@ -0,0 +1,4 @@
+var x = 1;
+get foo => ++x > 10;
+main() { print(foo || foo); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_6.dart b/tests/compiler/dart2js/cps_ir/input/operators_6.dart
new file mode 100644
index 0000000..36e7d9f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_6.dart
@@ -0,0 +1,3 @@
+get foo => foo;
+main() { print(foo || foo); }
+
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_7.dart b/tests/compiler/dart2js/cps_ir/input/operators_7.dart
new file mode 100644
index 0000000..8838126
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_7.dart
@@ -0,0 +1,9 @@
+class Foo {
+  operator[]=(index, value) {
+    print(value);
+  }
+}
+main() {
+  var foo = new Foo();
+  foo[5] = 6;
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/operators_8.dart b/tests/compiler/dart2js/cps_ir/input/operators_8.dart
new file mode 100644
index 0000000..c5b66d3
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/operators_8.dart
@@ -0,0 +1,5 @@
+main() {
+  var list = [1, 2, 3];
+  list[1] = 6;
+  print(list);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/runtime_types_1.dart b/tests/compiler/dart2js/cps_ir/input/runtime_types_1.dart
new file mode 100644
index 0000000..f67e4d3a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/runtime_types_1.dart
@@ -0,0 +1,7 @@
+class C<T> {
+  foo() => print(T);
+}
+
+main() {
+  new C<int>().foo();
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/runtime_types_2.dart b/tests/compiler/dart2js/cps_ir/input/runtime_types_2.dart
new file mode 100644
index 0000000..a225509
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/runtime_types_2.dart
@@ -0,0 +1,9 @@
+class C<T, U> {
+  foo() => print(U);
+}
+
+class D extends C<int, double> {}
+
+main() {
+  new D().foo();
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/runtime_types_3.dart b/tests/compiler/dart2js/cps_ir/input/runtime_types_3.dart
new file mode 100644
index 0000000..c9253bb
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/runtime_types_3.dart
@@ -0,0 +1,9 @@
+class C<T> {
+  foo() => new D<C<T>>();
+}
+class D<T> {
+  bar() => T;
+}
+main() {
+  print(new C<int>().foo().bar());
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/runtime_types_4.dart b/tests/compiler/dart2js/cps_ir/input/runtime_types_4.dart
new file mode 100644
index 0000000..f45e59c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/runtime_types_4.dart
@@ -0,0 +1,7 @@
+// Method to test: generative_constructor(C#)
+class C<X, Y, Z> {
+  foo() => 'C<$X $Y, $Z>';
+}
+main() {
+  new C<C, int, String>().foo();
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/supercall_1.dart b/tests/compiler/dart2js/cps_ir/input/supercall_1.dart
new file mode 100644
index 0000000..04d5817
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/supercall_1.dart
@@ -0,0 +1,11 @@
+class Base {
+  m(x) {
+    print(x+1);
+  }
+}
+class Sub extends Base {
+  m(x) => super.m(x+10);
+}
+main() {
+  new Sub().m(100);
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/supercall_2.dart b/tests/compiler/dart2js/cps_ir/input/supercall_2.dart
new file mode 100644
index 0000000..1a2f726
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/supercall_2.dart
@@ -0,0 +1,23 @@
+// TODO(sigmund): change this to check method "function(Sub#+)" once we provide
+// a way to disable inlining of Sub#+, which is compiled to something like:
+// function(x) {
+//   var v0, v1, v2;
+//   v0 = 1;
+//   v1 = J.getInterceptor$ns(x).$add(x, v0);
+//   v2 = this;
+//   return V.Base.prototype.$add.call(null, v2, v1);
+// }
+
+class Base {
+  m(x) {
+    print(x+1000);
+  }
+  operator+(x) => m(x+10);
+}
+class Sub extends Base {
+  m(x) => super.m(x+100);
+  operator+(x) => super + (x+1);
+}
+main() {
+  new Sub() + 10000;
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/supercall_3.dart b/tests/compiler/dart2js/cps_ir/input/supercall_3.dart
new file mode 100644
index 0000000..dd2edfc
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/supercall_3.dart
@@ -0,0 +1,9 @@
+class Base {
+  var field = 123;
+}
+class Sub extends Base {
+  m(x) => x + super.field;
+}
+main() {
+  print(new Sub().m(10));
+}
diff --git a/tests/compiler/dart2js/cps_ir/interceptors_1_test.dart b/tests/compiler/dart2js/cps_ir/interceptors_1_test.dart
new file mode 100644
index 0000000..98d813a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/interceptors_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.interceptors_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("interceptors_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/interceptors_2_test.dart b/tests/compiler/dart2js/cps_ir/interceptors_2_test.dart
new file mode 100644
index 0000000..2562d63
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/interceptors_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.interceptors_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("interceptors_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/literals_1_test.dart b/tests/compiler/dart2js/cps_ir/literals_1_test.dart
new file mode 100644
index 0000000..86e1f1d5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/literals_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.literals_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("literals_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_1_test.dart b/tests/compiler/dart2js/cps_ir/operators2_1_test.dart
new file mode 100644
index 0000000..acf42c2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_2_test.dart b/tests/compiler/dart2js/cps_ir/operators2_2_test.dart
new file mode 100644
index 0000000..75f6bb7
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_3_test.dart b/tests/compiler/dart2js/cps_ir/operators2_3_test.dart
new file mode 100644
index 0000000..7fc2f50
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_4_test.dart b/tests/compiler/dart2js/cps_ir/operators2_4_test.dart
new file mode 100644
index 0000000..9315168
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_5_test.dart b/tests/compiler/dart2js/cps_ir/operators2_5_test.dart
new file mode 100644
index 0000000..03544c1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_6_test.dart b/tests/compiler/dart2js/cps_ir/operators2_6_test.dart
new file mode 100644
index 0000000..e11bd8a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_7_test.dart b/tests/compiler/dart2js/cps_ir/operators2_7_test.dart
new file mode 100644
index 0000000..13480a4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators2_8_test.dart b/tests/compiler/dart2js/cps_ir/operators2_8_test.dart
new file mode 100644
index 0000000..d39aa5f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators2_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators2_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators2_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_1_test.dart b/tests/compiler/dart2js/cps_ir/operators_1_test.dart
new file mode 100644
index 0000000..9e457ac
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_2_test.dart b/tests/compiler/dart2js/cps_ir/operators_2_test.dart
new file mode 100644
index 0000000..99dd439
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_3_test.dart b/tests/compiler/dart2js/cps_ir/operators_3_test.dart
new file mode 100644
index 0000000..57ebc5a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_4_test.dart b/tests/compiler/dart2js/cps_ir/operators_4_test.dart
new file mode 100644
index 0000000..c7fed55
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_5_test.dart b/tests/compiler/dart2js/cps_ir/operators_5_test.dart
new file mode 100644
index 0000000..c412522
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_5_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_5.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_5.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_6_test.dart b/tests/compiler/dart2js/cps_ir/operators_6_test.dart
new file mode 100644
index 0000000..01246e2
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_6_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_6.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_6.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_7_test.dart b/tests/compiler/dart2js/cps_ir/operators_7_test.dart
new file mode 100644
index 0000000..2864e6f
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_7_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_7.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_7.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/operators_8_test.dart b/tests/compiler/dart2js/cps_ir/operators_8_test.dart
new file mode 100644
index 0000000..6c2d67c
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/operators_8_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.operators_8.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("operators_8.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/runner.dart b/tests/compiler/dart2js/cps_ir/runner.dart
new file mode 100644
index 0000000..a71bd9a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runner.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that the CPS IR code generator compiles programs and produces the
+// the expected output.
+
+import 'dart:io';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/apiimpl.dart' show
+    CompilerImpl;
+import '../memory_compiler.dart';
+import 'package:compiler/src/js/js.dart' as js;
+import 'package:compiler/src/elements/elements.dart' show
+    ClassElement,
+    Element;
+
+// Regular experession used to extract the method name that is used to match the
+// test output. By default we match the output of main.
+final RegExp elementNameRegExp = new RegExp(r'^// Method to test: (.*)$',
+    multiLine: true);
+
+runTest(String filename, {bool update: false}) {
+  var outputname = filename.replaceFirst('.dart', '.js');
+  String source = new File.fromUri(Platform.script.resolve('input/$filename'))
+      .readAsStringSync();
+  var expectedFile =
+      new File.fromUri(Platform.script.resolve('expected/$outputname'));
+  String expected = expectedFile.existsSync()
+    ? expectedFile.readAsStringSync() : '';
+  var match = elementNameRegExp.firstMatch(source);
+  var elementName = match?.group(1);
+
+  Map files = {TEST_MAIN_FILE: source};
+  asyncTest(() async {
+    Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
+    String found = null;
+    try {
+      CompilationResult result = await runCompiler(
+          entryPoint: uri,
+          memorySourceFiles: files,
+          options: <String>['--use-cps-ir']);
+      Expect.isTrue(result.isSuccess);
+      CompilerImpl compiler = result.compiler;
+      if (expected != null) {
+        String output = elementName == null
+            ? _getCodeForMain(compiler)
+            : _getCodeForMethod(compiler, elementName);
+        // Include the input in a comment of the expected file to make it easier
+        // to see the relation between input and output in code reviews.
+        found = '// Expectation for test: \n'
+            '// ${source.trim().replaceAll('\n', '\n// ')}\n\n'
+            '$output\n';
+      }
+    } catch (e, st) {
+      print(e);
+      print(st);
+      var message = 'The following test failed to compile:\n'
+                    '${_formatTest(files)}';
+      if (update) {
+        print('\n\n$message\n');
+        return;
+      } else {
+        Expect.fail(message);
+      }
+    }
+    if (expected != found) {
+      if (update) {
+        expectedFile.writeAsStringSync(found);
+        print('INFO: $expectedFile was updated');
+      } else {
+        Expect.fail('Unexpected output for test:\n  '
+            '${_formatTest(files).replaceAll('\n', '\n  ')}\n'
+            'Expected:\n  ${expected.replaceAll('\n', '\n  ')}\n'
+            'but found:\n  ${found?.replaceAll('\n', '\n  ')}\n'
+            '$regenerateCommand');
+      }
+    }
+  });
+}
+
+String get regenerateCommand {
+  var flags = Platform.packageRoot == null
+    ? '' : '--package-root=${Platform.packageRoot} ';
+  return '''
+If you wish to update the test expectations, rerun this test passing "update" as
+an argument, as follows:
+
+  dart $flags${Platform.script} update
+
+If you want to update more than one test at once, run:
+  dart $flags${Platform.script.resolve('update_all.dart')}
+
+''';
+}
+
+const String TEST_MAIN_FILE = 'test.dart';
+
+String _formatTest(Map test) {
+  return test[TEST_MAIN_FILE];
+}
+
+String _getCodeForMain(CompilerImpl compiler) {
+  Element mainFunction = compiler.mainFunction;
+  js.Node ast = compiler.enqueuer.codegen.generatedCode[mainFunction];
+  return js.prettyPrint(ast, compiler).getText();
+}
+
+String _getCodeForMethod(CompilerImpl compiler,
+                        String name) {
+  Element foundElement;
+  for (Element element in compiler.enqueuer.codegen.generatedCode.keys) {
+    if (element.toString() == name) {
+      if (foundElement != null) {
+        Expect.fail('Multiple compiled elements are called $name');
+      }
+      foundElement = element;
+    }
+  }
+
+  if (foundElement == null) {
+    Expect.fail('There is no compiled element called $name');
+  }
+
+  js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement];
+  return js.prettyPrint(ast, compiler).getText();
+}
diff --git a/tests/compiler/dart2js/cps_ir/runtime_types_1_test.dart b/tests/compiler/dart2js/cps_ir/runtime_types_1_test.dart
new file mode 100644
index 0000000..f5336f1
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runtime_types_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.runtime_types_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("runtime_types_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/runtime_types_2_test.dart b/tests/compiler/dart2js/cps_ir/runtime_types_2_test.dart
new file mode 100644
index 0000000..978f612
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runtime_types_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.runtime_types_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("runtime_types_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/runtime_types_3_test.dart b/tests/compiler/dart2js/cps_ir/runtime_types_3_test.dart
new file mode 100644
index 0000000..43a3349
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runtime_types_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.runtime_types_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("runtime_types_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/runtime_types_4_test.dart b/tests/compiler/dart2js/cps_ir/runtime_types_4_test.dart
new file mode 100644
index 0000000..eaf7937
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/runtime_types_4_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.runtime_types_4.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("runtime_types_4.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/supercall_1_test.dart b/tests/compiler/dart2js/cps_ir/supercall_1_test.dart
new file mode 100644
index 0000000..caf3030
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/supercall_1_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.supercall_1.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("supercall_1.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/supercall_2_test.dart b/tests/compiler/dart2js/cps_ir/supercall_2_test.dart
new file mode 100644
index 0000000..6f40662
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/supercall_2_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.supercall_2.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("supercall_2.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/supercall_3_test.dart b/tests/compiler/dart2js/cps_ir/supercall_3_test.dart
new file mode 100644
index 0000000..9b96977
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/supercall_3_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.supercall_3.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("supercall_3.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/up_to_date_test.dart b/tests/compiler/dart2js/cps_ir/up_to_date_test.dart
new file mode 100644
index 0000000..a9508a4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/up_to_date_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test that cps_ir/update_all.dart and every cps_ir/*_test.dart file are up to
+/// date. There should be a line in update_all and a file in the cps_ir folder
+/// for each test file in the `input/` folder.
+library tests.compiler.dart2js.cps_ir.up_to_date_test;
+
+import 'dart:io';
+
+main(args) {
+  bool update = args.length > 0 && args[0] == 'update';
+  var inputDir = new Directory.fromUri(Platform.script.resolve('input'));
+
+  bool errorsFound = false;
+
+  // Note: we create a test file per input file because invoking dart2js many
+  // times on a single test often makes test.py timeout.
+  //
+  // We tried using multi-tests for this, but it is unfortunately brittle. For
+  // example, multi-tests can't import code from one folder above the current
+  // directory, which prevents us from putting generated tests under a different
+  // folder than the rest of the helpers (like memory_compiler.dart)
+  var files = inputDir.listSync().map((f) => f.uri.pathSegments.last).toList();
+  files.sort();
+  for (var file in files) {
+    var testFilename = file.replaceAll('.dart', '_test.dart');
+    var contents = generateTestFile(file);
+    if (checkAndMaybeUpdate(testFilename, contents, update)) errorsFound = true;
+  }
+
+  var updateAllContents = generateUpdateAllFile(files);
+  if (checkAndMaybeUpdate('update_all.dart', updateAllContents, update)) {
+    errorsFound = true;
+  }
+
+  if (errorsFound) {
+    print(regenerateMessage);
+    exit(1);
+  }
+}
+
+/// Checks and if [update] is true, updates an autogenerated test file.
+///
+/// This doesn't update an actual test expectation, that's done by executing the
+/// files that we generate here.
+bool checkAndMaybeUpdate(String filename, String contents,
+    bool update) {
+  var testFile = new File.fromUri(Platform.script.resolve(filename));
+  bool exists = testFile.existsSync();
+  var isUpToDate = exists && testFile.readAsStringSync() == contents;
+  if (isUpToDate) {
+    print('PASS: ${filename} is up to date.');
+  } else if (update) {
+    testFile.writeAsStringSync(contents);
+    print('INFO: ${filename} was updated.');
+  } else {
+    print("FAILED: ${filename} is ${exists ? 'out of date' : 'missing'}");
+    return true;
+  }
+  return false;
+}
+
+String generateUpdateAllFile(List<String> files) {
+  var lines = files.map((f) => "runTest('$f', update: true);");
+  return '''
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/${Platform.script.pathSegments.last} update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.update_all;
+
+import 'runner.dart';
+
+main(args) {
+  ${lines.join('\n  ')}
+}
+''';
+}
+
+String generateTestFile(String file) => '''
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/${Platform.script.pathSegments.last} update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.$file;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("$file", update: args.length > 0 && args[0] == "update");
+}
+''';
+
+
+String get regenerateMessage {
+  var flags = Platform.packageRoot == null
+    ? '' : '--package-root=${Platform.packageRoot} ';
+  return '''
+
+To regenerate the test files, please run:
+  dart $flags${Platform.script} update''';
+}
diff --git a/tests/compiler/dart2js/cps_ir/update_all.dart b/tests/compiler/dart2js/cps_ir/update_all.dart
new file mode 100644
index 0000000..726f2e4
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/update_all.dart
@@ -0,0 +1,142 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.update_all;
+
+import 'runner.dart';
+
+main(args) {
+  runTest('argument_refinement_1.dart', update: true);
+  runTest('argument_refinement_10.dart', update: true);
+  runTest('argument_refinement_11.dart', update: true);
+  runTest('argument_refinement_12.dart', update: true);
+  runTest('argument_refinement_13.dart', update: true);
+  runTest('argument_refinement_14.dart', update: true);
+  runTest('argument_refinement_15.dart', update: true);
+  runTest('argument_refinement_16.dart', update: true);
+  runTest('argument_refinement_17.dart', update: true);
+  runTest('argument_refinement_18.dart', update: true);
+  runTest('argument_refinement_19.dart', update: true);
+  runTest('argument_refinement_2.dart', update: true);
+  runTest('argument_refinement_20.dart', update: true);
+  runTest('argument_refinement_21.dart', update: true);
+  runTest('argument_refinement_22.dart', update: true);
+  runTest('argument_refinement_23.dart', update: true);
+  runTest('argument_refinement_24.dart', update: true);
+  runTest('argument_refinement_25.dart', update: true);
+  runTest('argument_refinement_26.dart', update: true);
+  runTest('argument_refinement_27.dart', update: true);
+  runTest('argument_refinement_28.dart', update: true);
+  runTest('argument_refinement_3.dart', update: true);
+  runTest('argument_refinement_4.dart', update: true);
+  runTest('argument_refinement_5.dart', update: true);
+  runTest('argument_refinement_6.dart', update: true);
+  runTest('argument_refinement_7.dart', update: true);
+  runTest('argument_refinement_8.dart', update: true);
+  runTest('argument_refinement_9.dart', update: true);
+  runTest('argument_refinement_num_1.dart', update: true);
+  runTest('argument_refinement_num_10.dart', update: true);
+  runTest('argument_refinement_num_11.dart', update: true);
+  runTest('argument_refinement_num_12.dart', update: true);
+  runTest('argument_refinement_num_13.dart', update: true);
+  runTest('argument_refinement_num_14.dart', update: true);
+  runTest('argument_refinement_num_15.dart', update: true);
+  runTest('argument_refinement_num_16.dart', update: true);
+  runTest('argument_refinement_num_17.dart', update: true);
+  runTest('argument_refinement_num_2.dart', update: true);
+  runTest('argument_refinement_num_3.dart', update: true);
+  runTest('argument_refinement_num_4.dart', update: true);
+  runTest('argument_refinement_num_5.dart', update: true);
+  runTest('argument_refinement_num_6.dart', update: true);
+  runTest('argument_refinement_num_7.dart', update: true);
+  runTest('argument_refinement_num_8.dart', update: true);
+  runTest('argument_refinement_num_9.dart', update: true);
+  runTest('basic_1.dart', update: true);
+  runTest('basic_10.dart', update: true);
+  runTest('basic_11.dart', update: true);
+  runTest('basic_12.dart', update: true);
+  runTest('basic_13.dart', update: true);
+  runTest('basic_14.dart', update: true);
+  runTest('basic_15.dart', update: true);
+  runTest('basic_16.dart', update: true);
+  runTest('basic_2.dart', update: true);
+  runTest('basic_3.dart', update: true);
+  runTest('basic_4.dart', update: true);
+  runTest('basic_5.dart', update: true);
+  runTest('basic_6.dart', update: true);
+  runTest('basic_7.dart', update: true);
+  runTest('basic_8.dart', update: true);
+  runTest('basic_9.dart', update: true);
+  runTest('closures_1.dart', update: true);
+  runTest('closures_10.dart', update: true);
+  runTest('closures_11.dart', update: true);
+  runTest('closures_12.dart', update: true);
+  runTest('closures_13.dart', update: true);
+  runTest('closures_14.dart', update: true);
+  runTest('closures_15.dart', update: true);
+  runTest('closures_2.dart', update: true);
+  runTest('closures_3.dart', update: true);
+  runTest('closures_4.dart', update: true);
+  runTest('closures_5.dart', update: true);
+  runTest('closures_6.dart', update: true);
+  runTest('closures_7.dart', update: true);
+  runTest('closures_8.dart', update: true);
+  runTest('closures_9.dart', update: true);
+  runTest('codeUnitAt_1.dart', update: true);
+  runTest('codeUnitAt_2.dart', update: true);
+  runTest('constructor_1.dart', update: true);
+  runTest('constructor_10.dart', update: true);
+  runTest('constructor_11.dart', update: true);
+  runTest('constructor_12.dart', update: true);
+  runTest('constructor_13.dart', update: true);
+  runTest('constructor_14.dart', update: true);
+  runTest('constructor_2.dart', update: true);
+  runTest('constructor_3.dart', update: true);
+  runTest('constructor_4.dart', update: true);
+  runTest('constructor_5.dart', update: true);
+  runTest('constructor_6.dart', update: true);
+  runTest('constructor_7.dart', update: true);
+  runTest('constructor_8.dart', update: true);
+  runTest('constructor_9.dart', update: true);
+  runTest('control_flow_1.dart', update: true);
+  runTest('control_flow_2.dart', update: true);
+  runTest('control_flow_3.dart', update: true);
+  runTest('control_flow_4.dart', update: true);
+  runTest('control_flow_5.dart', update: true);
+  runTest('control_flow_6.dart', update: true);
+  runTest('control_flow_7.dart', update: true);
+  runTest('control_flow_8.dart', update: true);
+  runTest('control_flow_9.dart', update: true);
+  runTest('gvn_1.dart', update: true);
+  runTest('interceptors_1.dart', update: true);
+  runTest('interceptors_2.dart', update: true);
+  runTest('literals_1.dart', update: true);
+  runTest('operators2_1.dart', update: true);
+  runTest('operators2_2.dart', update: true);
+  runTest('operators2_3.dart', update: true);
+  runTest('operators2_4.dart', update: true);
+  runTest('operators2_5.dart', update: true);
+  runTest('operators2_6.dart', update: true);
+  runTest('operators2_7.dart', update: true);
+  runTest('operators2_8.dart', update: true);
+  runTest('operators_1.dart', update: true);
+  runTest('operators_2.dart', update: true);
+  runTest('operators_3.dart', update: true);
+  runTest('operators_4.dart', update: true);
+  runTest('operators_5.dart', update: true);
+  runTest('operators_6.dart', update: true);
+  runTest('operators_7.dart', update: true);
+  runTest('operators_8.dart', update: true);
+  runTest('runtime_types_1.dart', update: true);
+  runTest('runtime_types_2.dart', update: true);
+  runTest('runtime_types_3.dart', update: true);
+  runTest('runtime_types_4.dart', update: true);
+  runTest('supercall_1.dart', update: true);
+  runTest('supercall_2.dart', update: true);
+  runTest('supercall_3.dart', update: true);
+}
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 3b0aae1..3d0330e 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -6,8 +6,6 @@
 
 boolified_operator_test: Fail # Issue 8001
 
-async_await_js_transform_test/01: RuntimeError # Issue 23997
-
 # Don't mark these tests as failing. Instead, fix the errors/warnings that they
 # report or update the whitelist in the test-files to temporarily allow
 # digression.
@@ -37,6 +35,7 @@
 patch_test/bug: RuntimeError # Issue 21132
 
 http_test: Pass, Slow
+inference_stats_test: Pass, Slow
 
 # These tests are for the now-deleted dart2dart variant of the CPS IR.
 # We want to adapt them to test the JS variant of the CPS IR instead,
@@ -48,21 +47,27 @@
 backend_dart/opt_shrinking_test: Skip
 backend_dart/opt_redundant_phi_test: Skip
 
-# These tests run the compiler multiple times.
-js_backend_cps_ir_basic_test: Pass, Slow
-js_backend_cps_ir_closures_test: Pass, Slow
-js_backend_cps_ir_constructor_test: Pass, Slow
+# Source information is not correct due to inlining.
+js_backend_cps_ir_source_information_test: Fail
+sourcemaps/source_mapping_operators_test: Fail # Issue 25304 for checked mode, was: Pass, Slow
+
+check_elements_invariants_test: Slow, Pass, Timeout # Slow due to inlining in the CPS backend
 
 [ $unchecked ]
 exit_code_test: Skip # This tests requires checked mode.
 
 [ $checked ]
-uri_retention_test: Pass, Slow
+analyze_dart2js_helpers_test: Pass, Slow
+analyze_dart2js_test: Pass, Slow
+analyze_unused_dart2js_test: Pass, Slow
 deferred_mirrors_test: Pass, Slow
-mirror_final_field_inferrer2_test: Pass, Slow
-check_elements_invariants_test: Slow, Pass
-import_mirrors_test: Slow, Pass
+duplicate_library_test: Pass, Slow
 exit_code_test: Pass, Slow
+import_mirrors_test: Slow, Pass
+interop_anonymous_unreachable_test: Pass, Slow
+mirror_final_field_inferrer2_test: Pass, Slow
+source_map_pub_build_validity_test: Pass, Slow
+uri_retention_test: Pass, Slow
 value_range_test: Pass, Slow
 
 [ $mode == debug ]
diff --git a/tests/compiler/dart2js/deferred_load_mapping_test.dart b/tests/compiler/dart2js/deferred_load_mapping_test.dart
index 4cb51d13..34ba2e8 100644
--- a/tests/compiler/dart2js/deferred_load_mapping_test.dart
+++ b/tests/compiler/dart2js/deferred_load_mapping_test.dart
@@ -14,7 +14,7 @@
         memorySourceFiles: MEMORY_SOURCE_FILES,
         options: ['--deferred-map=deferred_map.json'],
         outputProvider: collector);
-    Compiler compiler = result.compiler;
+    CompilerImpl compiler = result.compiler;
     // Ensure a mapping file is output.
     Expect.isNotNull(
         collector.getOutput("deferred_map.json", "deferred_map"));
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index 09e8706..12e574c 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -17,17 +17,22 @@
       options: ['--analyze-all']);
 
     List<String> diagnostics = <String>[];
-    collector.messages.forEach((DiagnosticMessage message) {
+    collector.messages.forEach((CollectedMessage message) {
       if (message.kind == Diagnostic.VERBOSE_INFO) return;
       diagnostics.add(message.toString());
     });
     diagnostics.sort();
     var expected = [
-        "memory:exporter.dart:43:47:'hest' is defined here.:info",
-        "memory:library.dart:41:45:'hest' is defined here.:info",
-        "memory:main.dart:0:22:'hest' is imported here.:info",
-        "memory:main.dart:23:46:'hest' is imported here.:info",
-        "memory:main.dart:86:92:Duplicate import of 'hest'.:warning",
+        "MessageKind.AMBIGUOUS_LOCATION:"
+            "memory:exporter.dart:43:47:'hest' is defined here.:info",
+        "MessageKind.AMBIGUOUS_LOCATION:"
+            "memory:library.dart:41:45:'hest' is defined here.:info",
+        "MessageKind.DUPLICATE_IMPORT:"
+            "memory:main.dart:86:92:Duplicate import of 'hest'.:warning",
+        "MessageKind.IMPORTED_HERE:"
+            "memory:main.dart:0:22:'hest' is imported here.:info",
+        "MessageKind.IMPORTED_HERE:"
+            "memory:main.dart:23:46:'hest' is imported here.:info",
     ];
     Expect.listEquals(expected, diagnostics);
     Expect.isTrue(result.isSuccess);
diff --git a/tests/compiler/dart2js/diagnostic_helper.dart b/tests/compiler/dart2js/diagnostic_helper.dart
new file mode 100644
index 0000000..26dac30
--- /dev/null
+++ b/tests/compiler/dart2js/diagnostic_helper.dart
@@ -0,0 +1,194 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.test.diagnostic_helper;
+
+import 'dart:collection';
+
+import 'package:compiler/compiler_new.dart' show
+    CompilerDiagnostics,
+    Diagnostic;
+import 'package:compiler/src/diagnostics/messages.dart' show
+    Message,
+    MessageKind;
+import 'package:expect/expect.dart';
+
+class CollectedMessage {
+  final Message message;
+  final Uri uri;
+  final int begin;
+  final int end;
+  final String text;
+  final Diagnostic kind;
+
+  CollectedMessage(
+      this.message, this.uri, this.begin, this.end, this.text, this.kind);
+
+  MessageKind get messageKind => message.kind;
+
+  String toString() {
+    return '${message != null ? message.kind : ''}'
+           ':$uri:$begin:$end:$text:$kind';
+  }
+}
+
+class DiagnosticCollector implements CompilerDiagnostics {
+  List<CollectedMessage> messages = <CollectedMessage>[];
+
+  void call(Uri uri, int begin, int end, String message, Diagnostic kind) {
+    throw '';
+    report(null, uri, begin, end, message, kind);
+  }
+
+  @override
+  void report(Message message,
+              Uri uri, int begin, int end, String text, Diagnostic kind) {
+    messages.add(new CollectedMessage(message, uri, begin, end, text, kind));
+  }
+
+  Iterable<CollectedMessage> filterMessagesByKinds(List<Diagnostic> kinds) {
+    return messages.where(
+      (CollectedMessage message) => kinds.contains(message.kind));
+  }
+
+  Iterable<CollectedMessage> get errors {
+    return filterMessagesByKinds([Diagnostic.ERROR]);
+  }
+
+  Iterable<CollectedMessage> get warnings {
+    return filterMessagesByKinds([Diagnostic.WARNING]);
+  }
+
+  Iterable<CollectedMessage> get hints {
+    return filterMessagesByKinds([Diagnostic.HINT]);
+  }
+
+  Iterable<CollectedMessage> get infos {
+    return filterMessagesByKinds([Diagnostic.INFO]);
+  }
+
+  Iterable<CollectedMessage> get crashes {
+    return filterMessagesByKinds([Diagnostic.CRASH]);
+  }
+
+  /// `true` if non-verbose messages has been collected.
+  bool get hasRegularMessages {
+    return messages.any((m) => m.kind != Diagnostic.VERBOSE_INFO);
+  }
+
+  void clear() {
+    messages.clear();
+  }
+
+  void checkMessages(List<Expected> expectedMessages) {
+    int index = 0;
+    Iterable<CollectedMessage> messages =
+        filterMessagesByKinds(
+            [Diagnostic.ERROR,
+             Diagnostic.WARNING,
+             Diagnostic.HINT,
+             Diagnostic.INFO]);
+    for (CollectedMessage message in messages) {
+      if (index >= expectedMessages.length) {
+        Expect.fail("Unexpected messages:\n "
+                    "${messages.skip(index).join('\n ')}");
+      } else {
+        Expected expected = expectedMessages[index];
+        Expect.equals(expected.messageKind, message.messageKind,
+            "Unexpected message kind in:\n ${messages.join('\n ')}");
+        Expect.equals(expected.diagnosticKind, message.kind,
+            "Unexpected diagnostic kind in\n ${messages.join('\n ')}");
+        index++;
+      }
+    }
+  }
+}
+
+class Expected {
+  final MessageKind messageKind;
+  final Diagnostic diagnosticKind;
+
+  const Expected(this.messageKind, this.diagnosticKind);
+
+  const Expected.error(MessageKind messageKind)
+      : this(messageKind, Diagnostic.ERROR);
+
+  const Expected.warning(MessageKind messageKind)
+      : this(messageKind, Diagnostic.WARNING);
+
+  const Expected.hint(MessageKind messageKind)
+      : this(messageKind, Diagnostic.HINT);
+
+  const Expected.info(MessageKind messageKind)
+      : this(messageKind, Diagnostic.INFO);
+}
+
+
+void compareWarningKinds(String text,
+                         List expectedWarnings,
+                         Iterable<CollectedMessage> foundWarnings) {
+  compareMessageKinds(text, expectedWarnings, foundWarnings, 'warning');
+}
+
+/// [expectedMessages] must be a list of either [MessageKind] or [CheckMessage].
+void compareMessageKinds(String text,
+                         List expectedMessages,
+                         Iterable<CollectedMessage> foundMessages,
+                         String kind) {
+  var fail = (message) => Expect.fail('$text: $message');
+  HasNextIterator expectedIterator =
+      new HasNextIterator(expectedMessages.iterator);
+  HasNextIterator<CollectedMessage> foundIterator =
+      new HasNextIterator(foundMessages.iterator);
+  while (expectedIterator.hasNext && foundIterator.hasNext) {
+    var expected = expectedIterator.next();
+    var found = foundIterator.next();
+    if (expected is MessageKind) {
+      Expect.equals(expected, found.message.kind);
+    } else if (expected is CheckMessage) {
+      String error = expected(found.message);
+      Expect.isNull(error, error);
+    } else {
+      Expect.fail("Unexpected $kind value: $expected.");
+    }
+  }
+  if (expectedIterator.hasNext) {
+    do {
+      var expected = expectedIterator.next();
+      if (expected is CheckMessage) expected = expected(null);
+      print('Expected $kind "${expected}" did not occur');
+    } while (expectedIterator.hasNext);
+    fail('Too few ${kind}s');
+  }
+  if (foundIterator.hasNext) {
+    do {
+      CollectedMessage message = foundIterator.next();
+      print('Additional $kind "${message}: ${message.message}"');
+    } while (foundIterator.hasNext);
+    fail('Too many ${kind}s');
+  }
+}
+
+/// A function the checks [message]. If the check fails or if [message] is
+/// `null`, an error string is returned. Otherwise `null` is returned.
+typedef String CheckMessage(Message message);
+
+CheckMessage checkMessage(MessageKind kind, Map arguments) {
+  return (Message message) {
+    if (message == null) return '$kind';
+    if (message.kind != kind) return 'Expected message $kind, found $message.';
+    for (var key in arguments.keys) {
+      if (!message.arguments.containsKey(key)) {
+        return 'Expected argument $key not found in $message.kind.';
+      }
+      String expectedValue = '${arguments[key]}';
+      String foundValue = '${message.arguments[key]}';
+      if (expectedValue != foundValue) {
+        return 'Expected argument $key with value $expectedValue, '
+               'found $foundValue.';
+      }
+    }
+    return null;
+  };
+}
diff --git a/tests/compiler/dart2js/duplicate_library_test.dart b/tests/compiler/dart2js/duplicate_library_test.dart
index 80aa6fe..5a2a708 100644
--- a/tests/compiler/dart2js/duplicate_library_test.dart
+++ b/tests/compiler/dart2js/duplicate_library_test.dart
@@ -13,13 +13,13 @@
 import 'memory_compiler.dart';
 
 void check(String kind,
-           Iterable<DiagnosticMessage> messages,
+           Iterable<CollectedMessage> messages,
            List<MessageKind> expectedMessageKinds) {
   Expect.equals(messages.length, expectedMessageKinds.length,
       "Unexpected $kind count: $messages");
   int i = 0;
-  messages.forEach((DiagnosticMessage message) {
-    Expect.equals(expectedMessageKinds[i++], message.message.kind);
+  messages.forEach((CollectedMessage message) {
+    Expect.equals(expectedMessageKinds[i++], message.messageKind);
   });
 }
 
diff --git a/tests/compiler/dart2js/embedded_category_api_boundary_test.dart b/tests/compiler/dart2js/embedded_category_api_boundary_test.dart
index cbd973e..76db27b 100644
--- a/tests/compiler/dart2js/embedded_category_api_boundary_test.dart
+++ b/tests/compiler/dart2js/embedded_category_api_boundary_test.dart
@@ -24,7 +24,8 @@
   });
   asyncTest(() async {
     analyze(uriList, {},
-        checkResults: checkResults, analyzeMain: true, analyzeAll: false);
+        checkResults: checkResults,
+        mode: AnalysisMode.MAIN);
   });
 }
 
diff --git a/tests/compiler/dart2js/enumset_test.dart b/tests/compiler/dart2js/enumset_test.dart
new file mode 100644
index 0000000..66fad2e
--- /dev/null
+++ b/tests/compiler/dart2js/enumset_test.dart
@@ -0,0 +1,150 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library enumset.test;
+
+import 'package:compiler/src/util/enumset.dart';
+import 'package:expect/expect.dart';
+
+enum Enum { A, B, C, D, E, F, }
+
+main() {
+  testAddRemoveContains();
+  testConstructorsIntersects();
+}
+
+
+void checkEnumSet(EnumSet<Enum> enumSet,
+                 int expectedValue,
+                 List<Enum> expectedValues,
+                 String expectedToString) {
+  Expect.equals(expectedValue, enumSet.value,
+      "Unexpected EnumSet.value for ${enumSet.iterable(Enum.values)}");
+  Expect.listEquals(expectedValues, enumSet.iterable(Enum.values).toList(),
+      "Unexpected values: ${enumSet.iterable(Enum.values)}");
+  Expect.equals(expectedValues.isEmpty, enumSet.isEmpty,
+      "Unexpected EnumSet.isEmpty for ${enumSet.iterable(Enum.values)}");
+  Expect.equals(expectedToString, enumSet.toString(),
+      "Unexpected EnumSet.toString for ${enumSet.iterable(Enum.values)}");
+  for (Enum value in Enum.values) {
+    Expect.equals(expectedValues.contains(value), enumSet.contains(value),
+        "Unexpected EnumSet.contains for $value in "
+        "${enumSet.iterable(Enum.values)}");
+  }
+}
+
+void testAddRemoveContains() {
+  EnumSet<Enum> enumSet = new EnumSet<Enum>();
+
+  void check(int expectedValue,
+             List<Enum> expectedValues,
+             String expectedToString) {
+    checkEnumSet(enumSet, expectedValue, expectedValues, expectedToString);
+  }
+
+  check(0, [], '0');
+
+  enumSet.add(Enum.B);
+  check(2, [Enum.B], '10');
+
+  enumSet.add(Enum.F);
+  check(34, [Enum.F, Enum.B], '100010');
+
+  enumSet.add(Enum.A);
+  check(35, [Enum.F, Enum.B, Enum.A], '100011');
+
+  enumSet.add(Enum.A);
+  check(35, [Enum.F, Enum.B, Enum.A], '100011');
+
+  enumSet.remove(Enum.C);
+  check(35, [Enum.F, Enum.B, Enum.A], '100011');
+
+  enumSet.remove(Enum.B);
+  check(33, [Enum.F, Enum.A], '100001');
+
+  enumSet.remove(Enum.A);
+  check(32, [Enum.F], '100000');
+
+  enumSet.clear();
+  check(0, [], '0');
+
+  enumSet.add(Enum.A);
+  enumSet.add(Enum.B);
+  enumSet.add(Enum.C);
+  enumSet.add(Enum.D);
+  enumSet.add(Enum.E);
+  enumSet.add(Enum.F);
+  check(63, [Enum.F, Enum.E, Enum.D, Enum.C, Enum.B, Enum.A], '111111');
+}
+
+void testConstructorsIntersects() {
+  EnumSet<Enum> emptyA = new EnumSet<Enum>();
+  EnumSet<Enum> emptyB = new EnumSet<Enum>.fromValue(0);
+  EnumSet<Enum> emptyC = const EnumSet<Enum>.fixed(0);
+  EnumSet<Enum> emptyD = new EnumSet<Enum>.fixed(0);
+
+
+  void checkIntersects(EnumSet<Enum> a, EnumSet<Enum> b, bool expectedValue) {
+    Expect.equals(expectedValue, a.intersects(b),
+        "Unexpected intersects of $a and $b");
+    Expect.equals(a.intersects(b), b.intersects(a),
+        "Unsymmetric intersects of $a and $b");
+  }
+
+  void check(EnumSet<Enum> a, EnumSet<Enum> b) {
+    Expect.equals(a.value, b.value,
+        "Unexpected values of $a and $b");
+    Expect.equals(a.hashCode, b.hashCode,
+        "Unexpected hash codes of $a and $b");
+    Expect.equals(a, b,
+        "Unexpected equality of $a and $b");
+    checkIntersects(a, b, !a.isEmpty);
+  }
+
+  check(emptyA, emptyA);
+  check(emptyA, emptyB);
+  check(emptyA, emptyC);
+  check(emptyA, emptyD);
+
+  EnumSet<Enum> singleA = new EnumSet<Enum>()..add(Enum.C);
+  EnumSet<Enum> singleB = new EnumSet<Enum>.fromValue(4);
+  EnumSet<Enum> singleC = const EnumSet<Enum>.fixed(4);
+  EnumSet<Enum> singleD = new EnumSet<Enum>.fixed(4);
+  EnumSet<Enum> singleE = new EnumSet<Enum>.fromValues([Enum.C]);
+  EnumSet<Enum> singleF = new EnumSet<Enum>.fromValues([Enum.C], fixed: true);
+
+  check(singleA, singleA);
+  check(singleA, singleB);
+  check(singleA, singleC);
+  check(singleA, singleD);
+  check(singleA, singleE);
+  check(singleA, singleF);
+
+  EnumSet<Enum> multiA = new EnumSet<Enum>()
+      ..add(Enum.A)..add(Enum.D)..add(Enum.F);
+  EnumSet<Enum> multiB = new EnumSet<Enum>.fromValue(41);
+  EnumSet<Enum> multiC = const EnumSet<Enum>.fixed(41);
+  EnumSet<Enum> multiD = new EnumSet<Enum>.fixed(41);
+  EnumSet<Enum> multiE = new EnumSet<Enum>.fromValues([Enum.F, Enum.A, Enum.D]);
+  EnumSet<Enum> multiF =
+      new EnumSet<Enum>.fromValues([Enum.F, Enum.A, Enum.D], fixed: true);
+
+  check(multiA, multiA);
+  check(multiA, multiB);
+  check(multiA, multiC);
+  check(multiA, multiD);
+  check(multiA, multiE);
+  check(multiA, multiF);
+
+  EnumSet<Enum> multi2 = new EnumSet<Enum>.fromValues([Enum.F, Enum.A, Enum.C]);
+
+  checkIntersects(emptyA, singleA, false);
+  checkIntersects(emptyA, multiA, false);
+  checkIntersects(emptyA, multi2, false);
+
+  checkIntersects(singleA, multiA, false);
+  checkIntersects(singleA, multi2, true);
+
+  checkIntersects(multiA, multi2, true);
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/exit_code_test.dart
index ff03975..e5263e4 100644
--- a/tests/compiler/dart2js/exit_code_test.dart
+++ b/tests/compiler/dart2js/exit_code_test.dart
@@ -29,9 +29,10 @@
 import 'package:compiler/src/old_to_new_api.dart';
 import 'package:compiler/src/resolution/resolution.dart';
 import 'package:compiler/src/scanner/scanner_task.dart';
+import 'package:compiler/src/universe/world_impact.dart';
 import 'diagnostic_reporter_helper.dart';
 
-class TestCompiler extends apiimpl.Compiler {
+class TestCompiler extends apiimpl.CompilerImpl {
   final String testMarker;
   final String testType;
   final Function onTest;
diff --git a/tests/compiler/dart2js/expect_annotations_test.dart b/tests/compiler/dart2js/expect_annotations_test.dart
index 62e29ae..7c4605a 100644
--- a/tests/compiler/dart2js/expect_annotations_test.dart
+++ b/tests/compiler/dart2js/expect_annotations_test.dart
@@ -105,8 +105,8 @@
 
     TypeMask jsStringType = compiler.typesTask.stringType;
     TypeMask jsIntType = compiler.typesTask.intType;
-    TypeMask coreStringType = new TypeMask.subtype(compiler.stringClass,
-        compiler.world);
+    TypeMask coreStringType = new TypeMask.subtype(
+        compiler.coreClasses.stringClass, compiler.world);
 
     test('method');
     test('methodAssumeDynamic', expectAssumeDynamic: true);
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 2a33d95..7eeb5f9 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -17,7 +17,7 @@
                     check(compiler, element)) {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(code, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     compiler.disableInlining = disableInlining;
     var cls = findElement(compiler, className);
     var member = cls.lookupMember(memberName);
@@ -531,7 +531,7 @@
   runTest(TEST_14, {'f': (types) => types.uint31Type});
   runTest(TEST_15, {'f': (types) {
                             ClassElement cls =
-                                types.compiler.backend.jsIndexableClass;
+                                types.compiler.backend.helpers.jsIndexableClass;
                             return new TypeMask.nonNullSubtype(cls,
                                 types.compiler.world);
                          }});
diff --git a/tests/compiler/dart2js/flatten_test.dart b/tests/compiler/dart2js/flatten_test.dart
index cc28c2f..0275ee7 100644
--- a/tests/compiler/dart2js/flatten_test.dart
+++ b/tests/compiler/dart2js/flatten_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library subtype_test;
+library flatten_test;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
index 350dcc4..cb9e4c8 100644
--- a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
+++ b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
@@ -25,7 +25,7 @@
 main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     String generated = compiler.assembledCode;
     RegExp regexp = new RegExp(r"get\$foo");
     Iterator matches = regexp.allMatches(generated).iterator;
@@ -35,7 +35,7 @@
     String name = 'foo';
     var element = cls.lookupLocalMember(name);
     Expect.isNotNull(element);
-    Selector selector = new Selector.getter(name, null);
+    Selector selector = new Selector.getter(new PublicName(name));
     Expect.isFalse(compiler.world.hasAnyUserDefinedGetter(selector, null));
   }));
 }
diff --git a/tests/compiler/dart2js/import_mirrors_test.dart b/tests/compiler/dart2js/import_mirrors_test.dart
index 514bedb..9c42114 100644
--- a/tests/compiler/dart2js/import_mirrors_test.dart
+++ b/tests/compiler/dart2js/import_mirrors_test.dart
@@ -5,7 +5,7 @@
 // Test that the compiler emits a warning on import of 'dart:mirrors' unless
 // the flag --enable-experimental-mirrors is used.
 
-library dart2js.test.import;
+library dart2js.test.import_mirrors;
 
 import 'dart:async';
 import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/import_test.dart b/tests/compiler/dart2js/import_test.dart
index ddd4992..0fbe10e 100644
--- a/tests/compiler/dart2js/import_test.dart
+++ b/tests/compiler/dart2js/import_test.dart
@@ -9,6 +9,8 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/diagnostics/messages.dart';
+import 'package:compiler/compiler.dart';
 import 'memory_compiler.dart';
 
 const MEMORY_SOURCE_FILES = const {
@@ -26,15 +28,55 @@
   int i = "";
 }
 ''',
+    'part.dart': '''
+part of lib;
+
+main() {}
+''',
+    'lib.dart': '''
+library lib;
+
+import 'part.dart';
+
+part 'part.dart';
+''',
 };
 
+testEntryPointIsPart() async {
+  var collector = new DiagnosticCollector();
+  await runCompiler(
+      entryPoint: Uri.parse('memory:part.dart'),
+      memorySourceFiles: MEMORY_SOURCE_FILES,
+      diagnosticHandler: collector);
+
+  collector.checkMessages([
+      const Expected.error(MessageKind.MAIN_HAS_PART_OF)]);
+}
+
+testImportPart() async {
+  var collector = new DiagnosticCollector();
+  await runCompiler(
+      entryPoint: Uri.parse('memory:lib.dart'),
+      memorySourceFiles: MEMORY_SOURCE_FILES,
+      diagnosticHandler: collector);
+
+  collector.checkMessages([
+      const Expected.error(MessageKind.IMPORT_PART_OF),
+      const Expected.info(MessageKind.IMPORT_PART_OF_HERE)]);
+}
+
 testMissingImports() async {
   var collector = new DiagnosticCollector();
   await runCompiler(
       memorySourceFiles: MEMORY_SOURCE_FILES,
       diagnosticHandler: collector);
-  Expect.equals(4, collector.errors.length);
-  Expect.equals(1, collector.warnings.length);
+
+  collector.checkMessages([
+      const Expected.error(MessageKind.READ_SCRIPT_ERROR),
+      const Expected.error(MessageKind.LIBRARY_NOT_FOUND),
+      const Expected.error(MessageKind.READ_SCRIPT_ERROR),
+      const Expected.error(MessageKind.READ_SCRIPT_ERROR),
+      const Expected.warning(MessageKind.NOT_ASSIGNABLE)]);
 }
 
 testMissingMain() async {
@@ -42,12 +84,14 @@
   await runCompiler(
       entryPoint: Uri.parse('memory:missing.dart'),
       diagnosticHandler: collector);
-  Expect.equals(1, collector.errors.length);
-  Expect.equals(0, collector.warnings.length);
+  collector.checkMessages([
+      const Expected.error(MessageKind.READ_SELF_ERROR)]);
 }
 
 void main() {
   asyncTest(() async {
+    await testEntryPointIsPart();
+    await testImportPart();
     await testMissingImports();
     await testMissingMain();
   });
diff --git a/tests/compiler/dart2js/incremental/compile_all.dart b/tests/compiler/dart2js/incremental/compile_all.dart
index a89ec32..9d62061 100644
--- a/tests/compiler/dart2js/incremental/compile_all.dart
+++ b/tests/compiler/dart2js/incremental/compile_all.dart
@@ -18,7 +18,7 @@
     FormattingDiagnosticHandler;
 
 import '../memory_source_file_helper.dart' show
-    Compiler;
+    CompilerImpl;
 
 import '../memory_compiler.dart' show
     compilerFor;
@@ -43,7 +43,7 @@
   int testCount = 0;
   int skipCount = 0;
   Set<String> crashes = new Set<String>();
-  Compiler memoryCompiler = compilerFor(memorySourceFiles: sources);
+  CompilerImpl memoryCompiler = compilerFor(memorySourceFiles: sources);
   FormattingDiagnosticHandler handler = memoryCompiler.handler;
   handler.verbose = verbose;
   var options = ['--analyze-main'];
diff --git a/tests/compiler/dart2js/incremental/hello_test.dart b/tests/compiler/dart2js/incremental/hello_test.dart
index 83215dc..e47ef9d 100644
--- a/tests/compiler/dart2js/incremental/hello_test.dart
+++ b/tests/compiler/dart2js/incremental/hello_test.dart
@@ -85,8 +85,7 @@
 
 main() {
   Uri libraryRoot = Uri.base.resolve('sdk/');
-  Uri packageRoot = Uri.base.resolveUri(
-      new Uri.file('${Platform.packageRoot}/'));
+  Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
   MemorySourceFileProvider provider =
       new MemorySourceFileProvider(tests);
   asyncTest(() => runTests(libraryRoot, packageRoot, provider));
diff --git a/tests/compiler/dart2js/inference_stats_test.dart b/tests/compiler/dart2js/inference_stats_test.dart
index e742b0a..a85ca39 100644
--- a/tests/compiler/dart2js/inference_stats_test.dart
+++ b/tests/compiler/dart2js/inference_stats_test.dart
@@ -9,8 +9,9 @@
 import 'dart:async';
 import 'package:test/test.dart';
 import 'package:dart2js_info/info.dart';
+import 'package:dart2js_info/src/util.dart' show
+    recursiveDiagnosticString;
 import 'memory_compiler.dart';
-import 'dart:io';
 
 main() {
   test('nothing is reachable, nothing to count', () {
diff --git a/tests/compiler/dart2js/issue13354_test.dart b/tests/compiler/dart2js/issue13354_test.dart
index 3402206..c275bfe 100644
--- a/tests/compiler/dart2js/issue13354_test.dart
+++ b/tests/compiler/dart2js/issue13354_test.dart
@@ -28,7 +28,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
diff --git a/tests/compiler/dart2js/js_backend_cps_ir.dart b/tests/compiler/dart2js/js_backend_cps_ir.dart
deleted file mode 100644
index 95852f1..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir.dart
+++ /dev/null
@@ -1,92 +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.
-
-// Test that the CPS IR code generator compiles programs and produces the
-// the expected output.
-
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
-import 'memory_compiler.dart';
-import 'package:compiler/src/js/js.dart' as js;
-import 'package:compiler/src/elements/elements.dart' show
-    ClassElement,
-    Element;
-
-const String TEST_MAIN_FILE = 'test.dart';
-
-class TestEntry {
-  final String source;
-  final String expectation;
-  final String elementName;
-
-  const TestEntry(this.source, [this.expectation])
-    : elementName = null;
-
-  const TestEntry.forMethod(this.elementName,
-      this.source, this.expectation);
-}
-
-String formatTest(Map test) {
-  return test[TEST_MAIN_FILE];
-}
-
-String getCodeForMain(Compiler compiler) {
-  Element mainFunction = compiler.mainFunction;
-  js.Node ast = compiler.enqueuer.codegen.generatedCode[mainFunction];
-  return js.prettyPrint(ast, compiler).getText();
-}
-
-String getCodeForMethod(Compiler compiler,
-                        String name) {
-  Element foundElement;
-  for (Element element in compiler.enqueuer.codegen.generatedCode.keys) {
-    if (element.toString() == name) {
-      if (foundElement != null) {
-        Expect.fail('Multiple compiled elements are called $name');
-      }
-      foundElement = element;
-    }
-  }
-
-  if (foundElement == null) {
-    Expect.fail('There is no compiled element called $name');
-  }
-
-  js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement];
-  return js.prettyPrint(ast, compiler).getText();
-}
-
-runTests(List<TestEntry> tests) {
-  for (TestEntry test in tests) {
-    Map files = {TEST_MAIN_FILE: test.source};
-    asyncTest(() async {
-      Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
-      try {
-        CompilationResult result = await runCompiler(
-            entryPoint: uri,
-            memorySourceFiles: files,
-            options: <String>['--use-cps-ir']);
-        Expect.isTrue(result.isSuccess);
-        Compiler compiler = result.compiler;
-        String expectation = test.expectation;
-        if (expectation != null) {
-          String expected = test.expectation;
-          String found = test.elementName == null
-              ? getCodeForMain(compiler)
-              : getCodeForMethod(compiler, test.elementName);
-          if (expected != found) {
-            Expect.fail('Expected:\n$expected\nbut found\n$found');
-          }
-        }
-      } catch (e, st) {
-        print(e);
-        print(st);
-        Expect.fail('The following test failed to compile:\n'
-                    '${formatTest(files)}');
-      }
-    });
-  }
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
deleted file mode 100644
index 51d2762..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
+++ /dev/null
@@ -1,180 +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.
-
-// Tests for basic functionality.
-
-library basic_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry(r"""
-main() {
-  var e = 1;
-  var l = [1, 2, 3];
-  var m = {'s': 1};
-
-  print('(' ')');
-  print('(${true})');
-  print('(${1})');
-  print('(${[1, 2, 3]})');
-  print('(${{'s': 1}})');
-  print('($e)');
-  print('($l)');
-  print('($m)');
-}""",r"""
-function() {
-  var l = [1, 2, 3], m = P.LinkedHashMap_LinkedHashMap$_literal(["s", 1]);
-  P.print("()");
-  P.print("(true)");
-  P.print("(1)");
-  P.print("(" + H.S([1, 2, 3]) + ")");
-  P.print("(" + H.S(P.LinkedHashMap_LinkedHashMap$_literal(["s", 1])) + ")");
-  P.print("(1)");
-  P.print("(" + H.S(l) + ")");
-  P.print("(" + H.S(m) + ")");
-}"""),
-  const TestEntry("""
-foo(a, [b = "b"]) { print(b); return b; }
-bar(a, {b: "b", c: "c"}) { print(c); return c; }
-main() {
-  foo(0);
-  foo(1, 2);
-  bar(3);
-  bar(4, b: 5);
-  bar(6, c: 7);
-  bar(8, b: 9, c: 10);
-}
-""",
-"""
-function() {
-  V.foo(0, "b");
-  V.foo(1, 2);
-  V.bar(3, "b", "c");
-  V.bar(4, 5, "c");
-  V.bar(6, "b", 7);
-  V.bar(8, 9, 10);
-}"""),
-  const TestEntry(
-  """
-foo(a) {
-  print(a);
-  return a;
-}
-main() {
-  var a = 10;
-  var b = 1;
-  var t;
-  t = a;
-  a = b;
-  b = t;
-  print(a);
-  print(b);
-  print(b);
-  print(foo(a));
-}
-  """,
-  """
-function() {
-  var a = 10, b = 1;
-  P.print(b);
-  P.print(a);
-  P.print(a);
-  P.print(V.foo(b));
-}"""),
-  const TestEntry(
-  """
-foo() { print(42); return 42; }
-main() { return foo(); }
-  """,
-  """function() {
-  return V.foo();
-}"""),
-  const TestEntry("main() {}"),
-  const TestEntry("main() { return 42; }"),
-  const TestEntry("main() { return; }", """
-function() {
-}"""),
-  // Constructor invocation
-  const TestEntry("""
-main() {
-  print(new Set());
-  print(new Set.from([1, 2, 3]));
-}""", r"""
-function() {
-  P.print(P.LinkedHashSet_LinkedHashSet(null, null, null, null));
-  P.print(P.LinkedHashSet_LinkedHashSet$from([1, 2, 3], null));
-}"""),
-  // Call synthetic constructor.
-  const TestEntry("""
-class C {}
-main() {
-  print(new C());
-}"""),
-  // Method invocation
-  const TestEntry("""
-main() {
-  print(new DateTime.now().isBefore(new DateTime.now()));
-}""", r"""
-function() {
-  P.print(P.DateTime$now().isBefore$1(P.DateTime$now()));
-}"""),
-  // Static calls
-  const TestEntry("""
-foo() { print(42); }
-main() { foo(); }
-""", r"""
-function() {
-  V.foo();
-}"""),
-  // Static getters
-  const TestEntry("""
-var foo = 42;
-main() { print(foo); }
-""", r"""
-function() {
-  P.print($.foo);
-}"""),
-  const TestEntry("""
-get foo { print(42); }
-main() { foo; }
-""", r"""
-function() {
-  V.foo();
-}"""),
-  // Static setters
-  const TestEntry("""
-var foo = 0;
-main() { print(foo = 42); }
-""", r"""
-function() {
-  var v0 = 42;
-  $.foo = v0;
-  P.print(v0);
-}"""),
-  const TestEntry("""
-set foo(x) { print(x); }
-main() { foo = 42; }
-""", r"""
-function() {
-  V.foo(42);
-}"""),
-  // Assert
-  const TestEntry("""
-foo() { print('X'); }
-main() {
-  assert(true);
-  assert(false);
-  assert(foo());
-  print('Done');
-}""", r"""
-function() {
-  P.print("Done");
-}""")
-];
-
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
deleted file mode 100644
index 820be3e..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
+++ /dev/null
@@ -1,256 +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.
-
-// Tests of closures.
-
-library closures_test;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-main(x) {
-  a() {
-    return x;
-  }
-  x = x + '1';
-  print(a());
-}
-""",
-r"""
-function(x) {
-  P.print(J.getInterceptor$ns(x).$add(x, "1"));
-}"""),
-
-  const TestEntry("""
-main(x) {
-  a() {
-    return x;
-  }
-  x = x + '1';
-  print(a());
-  return a;
-}
-""",
-r"""
-function(x) {
-  var _box_0 = {}, a = new V.main_a(_box_0);
-  _box_0._captured_x_0 = x;
-  _box_0._captured_x_0 = J.getInterceptor$ns(x = _box_0._captured_x_0).$add(x, "1");
-  P.print(a.call$0());
-  return a;
-}"""),
-
-  const TestEntry("""
-main(x) {
-  a() {
-    return x;
-  }
-  print(a());
-}
-""",
-r"""
-function(x) {
-  P.print(x);
-}"""),
-
-  const TestEntry("""
-main(x) {
-  a() {
-    return x;
-  }
-  print(a());
-  return a;
-}
-""",
-r"""
-function(x) {
-  var a = new V.main_a(x);
-  P.print(a.call$0());
-  return a;
-}"""),
-
-  const TestEntry("""
-main() {
-  var x = 122;
-  var a = () => x;
-  x = x + 1;
-  print(a());
-}
-""",
-r"""
-function() {
-  P.print(122 + 1);
-}"""),
-
-  const TestEntry("""
-main() {
-  var x = 122;
-  var a = () => x;
-  x = x + 1;
-  print(a());
-  return a;
-}
-""",
-r"""
-function() {
-  var _box_0 = {}, a = new V.main_closure(_box_0);
-  _box_0._captured_x_0 = 122;
-  _box_0._captured_x_0 = _box_0._captured_x_0 + 1;
-  P.print(a.call$0());
-  return a;
-}"""),
-
-  const TestEntry("""
-main() {
-  var x = 122;
-  var a = () {
-    var y = x;
-    return () => y;
-  };
-  x = x + 1;
-  print(a()());
-}
-""",
-r"""
-function() {
-  P.print(122 + 1);
-}"""),
-
-  const TestEntry("""
-main() {
-  var x = 122;
-  var a = () {
-    var y = x;
-    return () => y;
-  };
-  x = x + 1;
-  print(a()());
-  return a;
-}
-""",
-r"""
-function() {
-  var _box_0 = {}, a = new V.main_closure(_box_0);
-  _box_0._captured_x_0 = 122;
-  _box_0._captured_x_0 = _box_0._captured_x_0 + 1;
-  P.print(a.call$0().call$0());
-  return a;
-}"""),
-
-  const TestEntry("""
-main() {
-  var a;
-  for (var i=0; i<10; i++) {
-    a = () => i;
-  }
-  print(a());
-}
-""",
-r"""
-function() {
-  var a = null, i = 0;
-  for (; i < 10; a = new V.main_closure(i), i = i + 1)
-    ;
-  P.print(a.call$0());
-}"""),
-
-  const TestEntry.forMethod('function(A#b)', """
-class A {
-  a() => 1;
-  b() => () => a();
-}
-main() {
-  print(new A().b()());
-}
-""",
-r"""
-function() {
-  return new V.A_b_closure(this);
-}"""),
-
-  const TestEntry("""
-staticMethod(x) { print(x); return x; }
-main(x) {
-  var tearOff = staticMethod;
-  print(tearOff(123));
-}
-""",
-r"""
-function(x) {
-  P.print(V.staticMethod(123));
-}"""),
-
-  const TestEntry("""
-class Foo {
-  instanceMethod(x) => x;
-}
-main(x) {
-  var tearOff = new Foo().instanceMethod;
-  print(tearOff(123));
-}
-""",
-r"""
-function(x) {
-  P.print(V.Foo$().instanceMethod$1(123));
-}"""),
-
-  const TestEntry("""
-class Foo {
-  instanceMethod(x) => x;
-}
-main(x) {
-  var tearOff = new Foo().instanceMethod;
-  print(tearOff(123));
-  print(tearOff(321));
-}
-""",
-r"""
-function(x) {
-  var v0 = V.Foo$();
-  P.print(v0.instanceMethod$1(123));
-  P.print(v0.instanceMethod$1(321));
-}"""),
-
-  const TestEntry("""
-class Foo {
-  get getter {
-    print('getter');
-    return (x) => x;
-  }
-}
-main(x) {
-  var notTearOff = new Foo().getter;
-  print(notTearOff(123));
-  print(notTearOff(321));
-}
-""",
-r"""
-function(x) {
-  var notTearOff = V.Foo$().get$getter();
-  P.print(notTearOff.call$1(123));
-  P.print(notTearOff.call$1(321));
-}"""),
-
-  const TestEntry("""
-class Foo {
-  get getter {
-    print('getter');
-    return (x) => x;
-  }
-}
-main(x) {
-  var notTearOff = new Foo().getter;
-  print(notTearOff(123));
-}
-""",
-r"""
-function(x) {
-  P.print(V.Foo$().getter$1(123));
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
deleted file mode 100644
index b724218..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
+++ /dev/null
@@ -1,268 +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.
-
-// Tests of interceptors.
-
-library constructor_test;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry.forMethod('generative_constructor(Sub#)', """
-class Base {
-  var x;
-  Base(this.x);
-}
-class Sub extends Base {
-  var y;
-  Sub(x, this.y) : super(x);
-}
-main() {
-  print(new Sub(1, 2).x);
-}""",
-r"""
-function(x, y) {
-  return new V.Sub(y, x);
-}"""),
-
-  const TestEntry.forMethod('generative_constructor_body(Sub#)', """
-class Base {
-  var x;
-  Base(this.x);
-}
-class Sub extends Base {
-  var y;
-  Sub(x, this.y) : super(x) {
-    print(x);
-  }
-}
-main() {
-  print(new Sub(1, 2).x);
-}""",
-r"""
-function(x, y) {
-  P.print(x);
-}"""),
-
-  const TestEntry.forMethod('generative_constructor(Sub#)', """
-class Base0 {
-  Base0() {
-    print('Base0');
-  }
-}
-class Base extends Base0 {
-  var x;
-  Base(this.x);
-}
-class Sub extends Base {
-  var y;
-  Sub(x, this.y) : super(x) {
-    print(x);
-  }
-}
-main() {
-  print(new Sub(1, 2).x);
-}""",
-r"""
-function(x, y) {
-  var v0 = new V.Sub(y, x);
-  v0.Base0$0();
-  v0.Sub$2(x, y);
-  return v0;
-}"""),
-
-  const TestEntry.forMethod('generative_constructor(Sub#)', """
-class Base0 {
-  Base0() {
-    print('Base0');
-  }
-}
-class Base extends Base0 {
-  var x;
-  Base(x1) : x = (() => ++x1) {
-    print(x1); // use boxed x1
-  }
-}
-class Sub extends Base {
-  var y;
-  Sub(x, this.y) : super(x) {
-    print(x);
-  }
-}
-main() {
-  print(new Sub(1, 2).x);
-}""",
-r"""
-function(x, y) {
-  var _box_0 = {}, v0 = new V.Sub(y, new V.Base_closure(_box_0));
-  _box_0._captured_x1_0 = x;
-  v0.Base0$0();
-  v0.Base$1(_box_0);
-  v0.Sub$2(x, y);
-  return v0;
-}"""),
-
-  const TestEntry.forMethod('generative_constructor(Sub#)', """
-foo(x) {
-  print(x);
-}
-class Base {
-  var x1 = foo('x1');
-  var x2;
-  var x3 = foo('x3');
-  Base() : x2 = foo('x2');
-}
-class Sub extends Base {
-  var y1 = foo('y1');
-  var y2;
-  var y3;
-  Sub() : y2 = foo('y2'), super(), y3 = foo('y3');
-}
-main() {
-  new Sub();
-}
-""",
-r"""
-function() {
-  var v0 = V.foo("y1"), v1 = V.foo("y2"), v2 = V.foo("x1"), v3 = V.foo("x3"), v4 = V.foo("x2");
-  return new V.Sub(v0, v1, V.foo("y3"), v2, v4, v3);
-}"""),
-
-
-  const TestEntry.forMethod('generative_constructor(Foo#)', """
-class Bar {
-  Bar(x, {y, z: 'z', w: '_', q}) {
-    print(x);
-    print(y);
-    print(z);
-    print(w);
-    print(q);
-  }
-}
-class Foo extends Bar {
-  Foo() : super('x', y: 'y', w: 'w');
-}
-main() {
-  new Foo();
-}
-""",
-r"""
-function() {
-  var v0 = new V.Foo();
-  v0.Bar$5$q$w$y$z("x", null, "w", "y", "z");
-  return v0;
-}"""),
-  const TestEntry(r"""
-class C<T> {
-  foo() => T;
-}
-main() {
-  print(new C<int>().foo());
-}""", r"""
-function() {
-  P.print(V.C$(P.$int).foo$0());
-}"""),
-  const TestEntry(r"""
-class C<T> {
-  foo() => C;
-}
-main() {
-  print(new C<int>().foo());
-}""", r"""
-function() {
-  P.print(V.C$().foo$0());
-}"""),
-  const TestEntry.forMethod('generative_constructor(C#)', r"""
-class C<T> {
-  C() { print(T); }
-  foo() => print(T);
-}
-main() {
-  new C<int>();
-}""", r"""
-function($T) {
-  var v0 = H.setRuntimeTypeInfo(new V.C(), [$T]);
-  v0.C$0();
-  return v0;
-}"""),
-  const TestEntry.forMethod('generative_constructor(C#)', r"""
-class C<T> {
-  var x;
-  C() : x = new D<T>();
-}
-class D<T> {
-  foo() => T;
-}
-main() {
-  print(new C<int>().x.foo());
-}""", r"""
-function($T) {
-  return H.setRuntimeTypeInfo(new V.C(V.D$($T)), [$T]);
-}"""),
-
-
-  const TestEntry.forMethod('generative_constructor(A#)', r"""
-class A {
-  var x;
-  A() : this.b(1);
-  A.b(this.x);
-}
-main() {
-  print(new A().x);
-}""", r"""
-function() {
-  return new V.A(1);
-}"""),
-
-
-const TestEntry.forMethod('function(Foo#make)', r"""
-class Foo {
-  factory Foo.make(x) {
-    print('Foo');
-    return new Foo.create(x);
-  }
-  var x;
-  Foo.create(this.x);
-}
-main() {
-  print(new Foo.make(5));
-}""", r"""
-function(x) {
-  P.print("Foo");
-  return V.Foo$create(x);
-}"""),
-const TestEntry(r"""
-class Foo {
-  factory Foo.make(x) = Foo.create;
-  var x;
-  Foo.create(this.x);
-}
-main() {
-  print(new Foo.make(5));
-}""", r"""
-function() {
-  P.print(V.Foo$create(5));
-}"""),
-const TestEntry(r"""
-class A {
-  factory A(x) = B<int>;
-  get typevar;
-}
-class B<T> implements A {
-  var x;
-  B(this.x);
-
-  get typevar => T;
-}
-main() {
-  new A(5).typevar;
-}""", r"""
-function() {
-  V.B$(5, P.$int).get$typevar();
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
deleted file mode 100644
index 2365d4f..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
+++ /dev/null
@@ -1,176 +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.
-
-// Tests of control flow statements.
-
-library control_flow_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-main() {
-  while (true);
-}
-""", """
-function() {
-  while (true)
-    ;
-}"""),
-  const TestEntry("""
-foo(a) { print(a); return a; }
-
-main() {
-  while (true) {
-    l: while (true) {
-      while (foo(true)) {
-        if (foo(false)) break l;
-      }
-      print(1);
-    }
-    print(2);
-  }
-}
-""", """
-function() {
-  L0:
-    while (true)
-      while (true) {
-        while (V.foo(true))
-          if (V.foo(false)) {
-            P.print(2);
-            continue L0;
-          }
-        P.print(1);
-      }
-}"""),
-  const TestEntry("""
-foo(a) { print(a); return a; }
-
-main() {
-  for (int i = 0; foo(true); i = foo(i)) {
-    print(1);
-    if (foo(false)) break;
-  }
-  print(2);
-}""", """
-function() {
-  var i = 0;
-  for (; V.foo(true) === true; i = V.foo(i)) {
-    P.print(1);
-    if (V.foo(false) === true)
-      break;
-  }
-  P.print(2);
-}"""),
-const TestEntry("""
-foo(a) { print(a); return a; }
-
-main() {
- foo(false);
- if (foo(true)) {
-   print(1);
- } else {
-   print(2);
- }
- print(3);
-}""", """
-function() {
-  V.foo(false);
-  V.foo(true) ? P.print(1) : P.print(2);
-  P.print(3);
-}"""),
-const TestEntry("""
-foo(a) { print(a); return a; }
-
-main() {
- foo(false);
- if (foo(true)) {
-   print(1);
-   print(1);
- } else {
-   print(2);
-   print(2);
- }
- print(3);
-}""", """
-function() {
-  V.foo(false);
-  if (V.foo(true)) {
-    P.print(1);
-    P.print(1);
-  } else {
-    P.print(2);
-    P.print(2);
-  }
-  P.print(3);
-}"""),
-const TestEntry("""
-main() {
-  if (1) {
-    print('bad');
-  } else {
-    print('good');
-  }
-}""","""
-function() {
-  P.print("good");
-}"""),
-  const TestEntry("""
-foo() { print('2'); return 2; }
-main() {
-  if (foo()) {
-    print('bad');
-  } else {
-    print('good');
-  }
-}""","""
-function() {
-  V.foo();
-  P.print("good");
-}"""),
-  const TestEntry("""
-main() {
-  var list = [1,2,3,4,5,6];
-  for (var x in list) {
-    print(x);
-  }
-}""",r"""
-function() {
-  var list = [1, 2, 3, 4, 5, 6], $length = list.length, i = 0;
-  for (; i < list.length; i = i + 1) {
-    P.print(list[i]);
-    if ($length !== list.length)
-      H.throwConcurrentModificationError(list);
-  }
-}"""),
-  const TestEntry("""
-main() {
-  var xs = ['x', 'y', 'z'], ys = ['A', 'B', 'C'];
-  var xit = xs.iterator, yit = ys.iterator;
-  while (xit.moveNext() && yit.moveNext()) {
-    print(xit.current);
-    print(yit.current);
-  }
-}""",r"""
-function() {
-  var xs = ["x", "y", "z"], ys = ["A", "B", "C"], $length = xs.length, length1 = ys.length, i = 0, i1 = 0, current, current1;
-  for (; i < xs.length; i = i + 1, i1 = i1 + 1) {
-    current = xs[i];
-    if (length1 !== ys.length)
-      H.throwConcurrentModificationError(ys);
-    if (!(i1 < ys.length))
-      break;
-    current1 = ys[i1];
-    P.print(current);
-    P.print(current1);
-    if ($length !== xs.length)
-      H.throwConcurrentModificationError(xs);
-  }
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
deleted file mode 100644
index 947d919..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
+++ /dev/null
@@ -1,51 +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.
-
-// Tests of interceptors.
-
-library interceptors_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-main() {
-  var g = 1;
-
-  var x = g + 3;
-  print(x);
-}""",
-r"""
-function() {
-  P.print(4);
-}"""),
-  const TestEntry("""
-main() {
-  var l = ['hest', ['h', 'e', 's', 't']];
-  print(l.length);
-  for (int i  = 0; i < l.length; i++) {
-    var x = l[i];
-    for (int j = 0; j < x.length; j++) {
-      print(x[j]);
-    }
-  }
-}""",
-r"""
-function() {
-  var l = ["hest", ["h", "e", "s", "t"]], i = 0, x_, x, j;
-  for (P.print(l.length); i < l.length; i = i + 1) {
-    x_ = J.getInterceptor$as(x = l[i]);
-    for (j = 0; j < x_.get$length(x); j = j + 1) {
-      if (j >= x.length)
-        H.ioore(x, j);
-      P.print(x[j]);
-    }
-  }
-}"""),
-];
-
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
deleted file mode 100644
index ad9d2e7..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
+++ /dev/null
@@ -1,37 +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.
-
-// Tests of literals.
-
-library literals_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-main() {
-  print([]);
-  print([1]);
-  print([1, 2]);
-  print([1, [1, 2]]);
-  print({});
-  print({1: 2});
-  print({[1, 2]: [3, 4]});
-}
-""",
-r"""
-function() {
-  P.print([]);
-  P.print([1]);
-  P.print([1, 2]);
-  P.print([1, [1, 2]]);
-  P.print(P.LinkedHashMap_LinkedHashMap$_empty());
-  P.print(P.LinkedHashMap_LinkedHashMap$_literal([1, 2]));
-  P.print(P.LinkedHashMap_LinkedHashMap$_literal([[1, 2], [3, 4]]));
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
deleted file mode 100644
index a6d7a1c..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
+++ /dev/null
@@ -1,95 +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.
-
-// Tests of operators.
-
-library operators_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry("main() { return true ? 42 : 'foo'; }"),
-  const TestEntry("""
-var x = 1;
-foo() => ++x > 10;
-main() {
-  print(foo() ? "hello world" : "bad bad");
-}""","""
-function() {
-  P.print(V.foo() ? "hello world" : "bad bad");
-}"""),
-  const TestEntry("""
-var x = 1;
-foo() => ++x > 10;
-main() {
-  print(foo() ? "hello world" : "bad bad");
-}""","""
-function() {
-  P.print(V.foo() ? "hello world" : "bad bad");
-}"""),
-  const TestEntry("""
-var x = 1;
-get foo => ++x > 10;
-main() {
-  print(foo ? "hello world" : "bad bad");
-}""","""
-function() {
-  P.print(V.foo() ? "hello world" : "bad bad");
-}"""),
-  const TestEntry("""
-var x = 1;
-get foo => ++x > 10;
-main() { print(foo && foo); }
-""", """
-function() {
-  P.print(V.foo() ? !!V.foo() : false);
-}"""),
-  const TestEntry("""
-var x = 1;
-get foo => ++x > 10;
-main() { print(foo || foo); }
-""","""
-function() {
-  P.print(V.foo() ? true : !!V.foo());
-}"""),
-const TestEntry("""
-get foo => foo;
-main() { print(foo || foo); }
-""","""
-function() {
-  V.foo();
-}"""),
-
-// Needs interceptor calling convention
-//const TestEntry("""
-//class Foo {
-//  operator[]=(index, value) {
-//    print(value);
-//  }
-//}
-//main() {
-//  var foo = new Foo();
-//  foo[5] = 6;
-//}""", r"""
-//function() {
-//  V.Foo$().$indexSet(5, 6);
-//}
-//"""),
-
-const TestEntry("""
-main() {
-  var list = [1, 2, 3];
-  list[1] = 6;
-  print(list);
-}""", r"""
-function() {
-  var list = [1, 2, 3];
-  list[1] = 6;
-  P.print(list);
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
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
deleted file mode 100644
index 4353b69..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart
+++ /dev/null
@@ -1,72 +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.
-
-// Tests for the runtime type implementation.
-
-library basic_tests;
-
-import 'js_backend_cps_ir.dart';
-
-const String getTypeArgument = r'H.getTypeArgumentByIndex';
-const String getSubstitutedTypeArgument = 'H.getRuntimeTypeArgument';
-const String typeToString = r'H.runtimeTypeToString';
-const String createType = r'H.createRuntimeType';
-
-const List<TestEntry> tests = const [
-    const TestEntry.forMethod("function(C#foo)",
-r"""
-class C<T> {
-  foo() => print(T);
-}
-
-main() {
-  new C<int>().foo();
-}""",
-"""
-function() {
-  return P.print($createType($typeToString($getTypeArgument(this, 0))));
-}"""),
-    const TestEntry.forMethod("function(C#foo)",
-r"""
-class C<T, U> {
-  foo() => print(U);
-}
-
-class D extends C<int, double> {}
-
-main() {
-  new D().foo();
-}""",
-"""
-function() {
-  return P.print($createType($typeToString($getSubstitutedTypeArgument(this, "C", 1))));
-}"""),
-  const TestEntry.forMethod('function(C#foo)', r"""
-class C<T> {
-  foo() => new D<C<T>>();
-}
-class D<T> {
-  bar() => T;
-}
-main() {
-  print(new C<int>().foo().bar());
-}""", """
-function() {
-  return V.D\$([V.C, $getTypeArgument(this, 0)]);
-}"""),
-    const TestEntry.forMethod('generative_constructor(C#)', r"""
-class C<X, Y, Z> {
-  foo() => 'C<$X $Y, $Z>';
-}
-main() {
-  new C<C, int, String>().foo();
-}""", r"""
-function($X, $Y, $Z) {
-  return H.setRuntimeTypeInfo(new V.C(), [$X, $Y, $Z]);
-}"""),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
index bbfbdd6..2c68f48 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
@@ -9,11 +9,12 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'package:compiler/src/apiimpl.dart'
-       show Compiler;
+       show CompilerImpl;
 import 'memory_compiler.dart';
 import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
 import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart' as ir;
 import 'package:compiler/src/js/js.dart' as js;
+import 'package:compiler/src/js_backend/js_backend.dart';
 import 'package:compiler/src/elements/elements.dart';
 
 const String TEST_MAIN_FILE = 'test.dart';
@@ -34,16 +35,16 @@
   return test[TEST_MAIN_FILE];
 }
 
-js.Node getCodeForMain(Compiler compiler) {
+js.Node getCodeForMain(CompilerImpl compiler) {
   Element mainFunction = compiler.mainFunction;
   return compiler.enqueuer.codegen.generatedCode[mainFunction];
 }
 
-js.Node getJsNodeForElement(Compiler compiler, Element element) {
+js.Node getJsNodeForElement(CompilerImpl compiler, Element element) {
   return compiler.enqueuer.codegen.generatedCode[element];
 }
 
-String getCodeForMethod(Compiler compiler, String name) {
+String getCodeForMethod(CompilerImpl compiler, String name) {
   Element foundElement;
   for (Element element in compiler.enqueuer.codegen.generatedCode.keys) {
     if (element.toString() == name) {
@@ -66,7 +67,7 @@
   for (TestEntry test in tests) {
     Map files = {TEST_MAIN_FILE: test.source};
     asyncTest(() {
-      Compiler compiler = compilerFor(
+      CompilerImpl compiler = compilerFor(
           memorySourceFiles: files, options: <String>['--use-cps-ir']);
       ir.FunctionDefinition irNodeForMain;
 
@@ -78,8 +79,9 @@
       }
 
       Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
-      compiler.backend.functionCompiler.cpsBuilderTask.builderCallback =
-          cacheIrNodeForMain;
+      JavaScriptBackend backend = compiler.backend;
+      var functionCompiler = backend.functionCompiler;
+      functionCompiler.cpsBuilderTask.builderCallback = cacheIrNodeForMain;
 
       return compiler.run(uri).then((bool success) {
         Expect.isTrue(success);
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_supercall_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_supercall_test.dart
deleted file mode 100644
index 7d9283e..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_supercall_test.dart
+++ /dev/null
@@ -1,74 +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.
-
-// Tests of interceptors.
-
-library supercall_test;
-
-import 'js_backend_cps_ir.dart';
-
-const List<TestEntry> tests = const [
-  const TestEntry.forMethod('function(Sub#m)', """
-class Base {
-  m(x) {
-    print(x+1);
-  }
-}
-class Sub extends Base {
-  m(x) => super.m(x+10);
-}
-main() {
-  new Sub().m(100);
-}""",
-r"""
-function(x) {
-  return V.Base.prototype.m$1.call(this, x + 10);
-}"""),
-
-  // Reenable when we support compiling functions that
-  // need interceptor calling convention.
-// const TestEntry.forMethod('function(Sub#+)', """
-// class Base {
-//   m(x) {
-//     print(x+1000);
-//   }
-//   operator+(x) => m(x+10);
-// }
-// class Sub extends Base {
-//   m(x) => super.m(x+100);
-//   operator+(x) => super + (x+1);
-// }
-// main() {
-//   new Sub() + 10000;
-// }""",
-// r"""
-// function(x) {
-//   var v0, v1, v2;
-//   v0 = 1;
-//   v1 = J.getInterceptor$ns(x).$add(x, v0);
-//   v2 = this;
-//   return V.Base.prototype.$add.call(null, v2, v1);
-// }"""),
-
-const TestEntry.forMethod('function(Sub#m)', """
-class Base {
-  var field = 123;
-}
-class Sub extends Base {
-  m(x) => x + super.field;
-}
-main() {
-  print(new Sub().m(10));
-}""",
-r"""
-function(x) {
-  return x + this.field;
-}"""),
-
-
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/js_constant_test.dart b/tests/compiler/dart2js/js_constant_test.dart
new file mode 100644
index 0000000..6165cfa
--- /dev/null
+++ b/tests/compiler/dart2js/js_constant_test.dart
@@ -0,0 +1,52 @@
+// 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'compiler_helper.dart';
+
+const String TEST_1 = r"""
+  import 'dart:_foreign_helper';
+  main() {
+    JS('', '#.toString()', -5);
+    // absent: "5.toString"
+    // present: "(-5).toString"
+  }
+""";
+
+
+main() {
+  RegExp directivePattern = new RegExp(
+      //      \1                    \2        \3
+      r'''// *(present|absent): (?:"([^"]*)"|'([^'']*)')''',
+      multiLine: true);
+
+  Future check(String test) {
+    Uri uri = new Uri(scheme: 'dart', path: 'test');
+    var compiler = compilerFor(test, uri, expectedErrors: 0);
+    return compiler.run(uri).then((_) {
+      var element = findElement(compiler, 'main');
+      var backend = compiler.backend;
+      String generated = backend.getGeneratedCode(element);
+
+      for (Match match in directivePattern.allMatches(test)) {
+        String directive = match.group(1);
+        String pattern = match.groups([2, 3]).where((s) => s != null).single;
+        if (directive == 'present') {
+          Expect.isTrue(generated.contains(pattern),
+              "Cannot find '$pattern' in:\n$generated");
+        } else {
+          assert(directive == 'absent');
+          Expect.isFalse(generated.contains(pattern),
+              "Must not find '$pattern' in:\n$generated");
+        }
+      }
+    });
+  }
+
+  asyncTest(() => Future.wait([
+    check(TEST_1),
+  ]));
+}
diff --git a/tests/compiler/dart2js/js_safety_test.dart b/tests/compiler/dart2js/js_safety_test.dart
new file mode 100644
index 0000000..140f4b6
--- /dev/null
+++ b/tests/compiler/dart2js/js_safety_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:compiler/src/js/js.dart' as js;
+import 'package:compiler/src/js/placeholder_safety.dart';
+
+void test(String source, int expected, {List notNull: const[]}) {
+  var predicate = (int pos) => ! notNull.contains(pos);
+  js.Template template = js.js.parseForeignJS(source);
+  int actual = PlaceholderSafetyAnalysis.analyze(template.ast, predicate);
+  Expect.equals(expected, actual, 'source: "$source", notNull: $notNull');
+}
+
+
+void main() {
+  test('0', 0);
+
+  test('#.x', 1);
+  test('!!#.x', 1);
+  test('#.x + 1', 1);
+  test('1 + #.x', 1);
+  test('#[#] + 2', 2);
+  test('2 + #[#]', 2);
+  test('(# & #) >>> 0', 2);
+
+  test('#.a + #.b + #.c', 1);
+  test('#.b + #.b + #.c', 2, notNull: [0]);
+  test('#.c + #.b + #.c', 3, notNull: [0, 1]);
+  test('#.d + #.b + #.c', 1, notNull: [1]);
+
+  test('typeof(#) == "string"', 1);
+  test('"object" === typeof #', 1);
+
+  test('# == 1 || # == 2 || # == 3', 1);
+  test('# != 1 && # != 2 && # != 3', 1);
+
+  test('#.x == 1 || # == 1', 1);
+  test('# == 1 || #.x == 1', 1);
+
+  test('(# || 1, #)', 1);  // Could also be 2.
+
+  test('(#, null.a, #)', 1);
+  test('(#, undefined.a, #)', 1);
+  test('(#, (void 0).a, #)', 1);
+  test('(#, "a".a, #)', 2);
+  test('((#, "a").a, #)', 2);
+
+  test('#[#][#][#][#]', 2);
+  test('#[#][#][#][#]', 3, notNull: [0]);
+  test('#[#][#][#][#]', 3, notNull: [0, 1, 2, 3]);
+
+  test('#.a = #', 2);
+  test('#.a.b = #', 1);
+  test('#[1] = #', 2);
+  test('#[1][1] = #', 1);
+
+  test('#.a = #.a + #.a + #.a', 2);
+  test('#.a = #.a + #.a + #.a', 2, notNull: [0]);
+  test('#.a = #.a + #.a + #.a', 3, notNull: [1]);
+  test('#.a = #.a + #.a + #.a', 4, notNull: [1, 2]);
+
+  test('#()', 1);
+  test('#(#, #)', 3);
+  test('#.f(#, #)', 1);
+  test('#.f(#, #)', 3, notNull: [0]);
+
+  test('(#.a+=1, #)', 1);
+  test('(#.a++, #)', 1);
+  test('(++#.a, #)', 1);
+
+  test('new Array(#)', 1);
+  test('new Date(#)', 1);
+  test('new Function(#)', 1);
+  test('new RegExp(#)', 1);
+  test('new xxx(#)', 0);
+  test('String(#)', 1);
+  test('# in #', 2);
+
+  test('Object.keys(#)', 1);
+
+  test('typeof #', 1);
+  test('typeof #.foo', 1);
+  test('typeof foo.#', 0);
+  test('typeof Array.#', 1);
+
+  test('throw #', 1);
+  test('throw #.x', 1);
+
+  test('(function(){})()', 0);
+  test('(function(a,b){#})(#, #)', 0);
+  // Placeholders in an immediate call are ok.
+  test('(function(a,b){a++;b++;return a+b})(#, #)', 2);
+
+  test('# ? # : #', 1);
+  test('(# ? 1 : #, #)', 1);
+  test('(# ? # : 2, #)', 1);
+  test('(# ? 1 : 2, #)', 1);  // Could also be 4.
+
+  test('{A:#, B:#, C:#}', 3);
+  test('[#,#,#,#]', 4);
+  test('[,,,,#,#,,,]', 2);
+}
diff --git a/tests/compiler/dart2js/js_spec_optimization_test.dart b/tests/compiler/dart2js/js_spec_optimization_test.dart
index 8c83b3b..3c03c09 100644
--- a/tests/compiler/dart2js/js_spec_optimization_test.dart
+++ b/tests/compiler/dart2js/js_spec_optimization_test.dart
@@ -67,7 +67,7 @@
   Future check(String test) {
     Uri uri = new Uri(scheme: 'dart', path: 'test');
     var compiler = compilerFor(test, uri, expectedErrors: 0);
-    return compiler.runCompiler(uri).then((_) {
+    return compiler.run(uri).then((_) {
       var element = findElement(compiler, 'main');
       var backend = compiler.backend;
       String generated = backend.getGeneratedCode(element);
diff --git a/tests/compiler/dart2js/js_spec_string_test.dart b/tests/compiler/dart2js/js_spec_string_test.dart
index 1481da4..01c9f64 100644
--- a/tests/compiler/dart2js/js_spec_string_test.dart
+++ b/tests/compiler/dart2js/js_spec_string_test.dart
@@ -64,10 +64,11 @@
         typesReturned: actualReturns, typesInstantiated: actualCreates,
         objectType: OBJECT, nullType: NULL);
   } catch (e) {
-    Expect.isTrue(expectError);
-    Expect.isNotNull(listener.errorMessage, 'Error expected.');
+    Expect.isTrue(expectError, 'Unexpected error "$specString"');
+    Expect.isNotNull(listener.errorMessage, 'Error message expected.');
     return;
   }
+  Expect.isFalse(expectError, 'Missing error for "$specString".');
   Expect.isNull(listener.errorMessage, 'Unexpected error.');
   if (returns != null) {
     Expect.listEquals(returns, actualReturns, 'Unexpected returns.');
@@ -217,17 +218,24 @@
   test('returns:void;', returns: [], creates: []);
   test('returns:;', returns: [OBJECT, NULL], creates: []);
   test('returns:var;', returns: [OBJECT, NULL], creates: []);
-  test('returns:A;', returns: ['A'], creates: []);
-  test('returns:A|B;', returns: ['A', 'B'], creates: []);
-  test('returns:A|B|C;', returns: ['A', 'B', 'C'], creates: []);
+  test('returns:A;', returns: ['A'], creates: ['A']);
+  test('returns:A|B;', returns: ['A', 'B'], creates: ['A', 'B']);
+  test('returns:A|B|C;', returns: ['A', 'B', 'C'], creates: ['A', 'B', 'C']);
 
   test('creates:void;', expectError: true);
-  test('creates:;', expectError: true);
-  test('creates:var;', expectError: true);
+  test('creates:;', creates: []);
+  test('creates:var;', creates: []);
   test('creates:A;', returns: [], creates: ['A']);
   test('creates:A|B;', returns: [], creates: ['A', 'B']);
   test('creates:A|B|C;', returns: [], creates: ['A', 'B', 'C']);
 
+  test('returns:void;creates:', returns: [], creates: []);
+  test('returns:;creates:', returns: [OBJECT, NULL], creates: []);
+  test('returns:var;creates:', returns: [OBJECT, NULL], creates: []);
+  test('returns:A;creates:', returns: ['A'], creates: []);
+  test('returns:A|B;creates:;', returns: ['A', 'B'], creates: []);
+  test('returns:A|B|C;creates:;', returns: ['A', 'B', 'C'], creates: []);
+
   test('returns:void;creates:A;', returns: [], creates: ['A']);
   test('returns:;creates:A|B;', returns: [OBJECT, NULL], creates: ['A', 'B']);
   test('returns:var;creates:A|B|C;',
@@ -242,19 +250,32 @@
   testWithSideEffects('returns:void;', returns: [], creates: []);
   testWithSideEffects('returns:;', returns: [OBJECT, NULL], creates: []);
   testWithSideEffects('returns:var;', returns: [OBJECT, NULL], creates: []);
-  testWithSideEffects('returns:A;', returns: ['A'], creates: []);
-  testWithSideEffects('returns:A|B;', returns: ['A', 'B'], creates: []);
-  testWithSideEffects('returns:A|B|C;', returns: ['A', 'B', 'C'], creates: []);
+  testWithSideEffects('returns:A;', returns: ['A'], creates: ['A']);
+  testWithSideEffects('returns:A|B;',
+      returns: ['A', 'B'], creates: ['A', 'B']);
+  testWithSideEffects('returns:A|B|C;',
+      returns: ['A', 'B', 'C'], creates: ['A', 'B', 'C']);
   testWithSideEffects('returns: A| B |C ;',
-      returns: ['A', 'B', 'C'], creates: []);
+      returns: ['A', 'B', 'C'], creates: ['A', 'B', 'C']);
 
   testWithSideEffects('creates:void;', expectError: true);
-  testWithSideEffects('creates:;', expectError: true);
-  testWithSideEffects('creates:var;', expectError: true);
+  testWithSideEffects('creates:;', creates: []);
+  testWithSideEffects('creates:var;', creates: []);
   testWithSideEffects('creates:A;', returns: [], creates: ['A']);
   testWithSideEffects('creates:A|B;', returns: [], creates: ['A', 'B']);
   testWithSideEffects('creates:A|B|C;', returns: [], creates: ['A', 'B', 'C']);
 
+  testWithSideEffects('returns:void;creates:;', returns: [], creates: []);
+  testWithSideEffects('returns:;creates:;',
+      returns: [OBJECT, NULL], creates: []);
+  testWithSideEffects('returns:var;creates:;',
+      returns: [OBJECT, NULL], creates: []);
+  testWithSideEffects('returns:A;creates:;', returns: ['A'], creates: []);
+  testWithSideEffects('returns:A|B;creates:;',
+      returns: ['A', 'B'], creates: []);
+  testWithSideEffects('returns:A|B|C;creates:;',
+      returns: ['A', 'B', 'C'], creates: []);
+
   testWithSideEffects('returns:void;creates:A;', returns: [], creates: ['A']);
   testWithSideEffects('returns:;creates:A|B;',
       returns: [OBJECT, NULL], creates: ['A', 'B']);
diff --git a/tests/compiler/dart2js/least_upper_bound_test.dart b/tests/compiler/dart2js/least_upper_bound_test.dart
index c4706bf..7f15f88 100644
--- a/tests/compiler/dart2js/least_upper_bound_test.dart
+++ b/tests/compiler/dart2js/least_upper_bound_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library subtype_test;
+library least_upper_bound_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
diff --git a/tests/compiler/dart2js/library_resolution_test.dart b/tests/compiler/dart2js/library_resolution_test.dart
index 3d6c035..28ad567 100644
--- a/tests/compiler/dart2js/library_resolution_test.dart
+++ b/tests/compiler/dart2js/library_resolution_test.dart
@@ -14,92 +14,58 @@
 
 import "package:async_helper/async_helper.dart";
 
-import 'package:expect/expect.dart' show
-    Expect;
+import 'package:expect/expect.dart' show Expect;
 
-import 'package:compiler/src/diagnostics/messages.dart' show
-    MessageKind,
-    MessageTemplate;
+import 'package:compiler/src/diagnostics/messages.dart'
+    show MessageKind, MessageTemplate;
 
-import 'package:compiler/src/elements/elements.dart' show
-    LibraryElement;
+import 'package:compiler/src/elements/elements.dart' show LibraryElement;
 
-import 'package:compiler/src/null_compiler_output.dart' show
-    NullCompilerOutput;
+import 'package:compiler/src/null_compiler_output.dart' show NullCompilerOutput;
 
-import 'package:compiler/src/old_to_new_api.dart' show
-    LegacyCompilerDiagnostics,
-    LegacyCompilerInput;
+import 'package:compiler/src/old_to_new_api.dart'
+    show LegacyCompilerDiagnostics, LegacyCompilerInput;
 
-import 'package:sdk_library_metadata/libraries.dart' show
-    DART2JS_PLATFORM,
-    LibraryInfo;
+Uri sdkRoot = Uri.base.resolve("sdk/");
+Uri mock1LibraryUri = sdkRoot.resolve("lib/mock1.dart");
+Uri mock2LibraryUri = sdkRoot.resolve("lib/mock2.dart");
 
-const LibraryInfo mock1LibraryInfo = const LibraryInfo(
-    "mock1.dart",
-    categories: "Client,Embedded",
-    documented: false,
-    platforms: DART2JS_PLATFORM);
+class CustomCompiler extends CompilerImpl {
+  CustomCompiler(provider, handler, libraryRoot,
+      packageRoot, options, environment)
+      : super(provider, const NullCompilerOutput(), handler, libraryRoot,
+            packageRoot, options, environment);
 
-const LibraryInfo mock2LibraryInfo = const LibraryInfo(
-    "mock2.dart",
-    categories: "Client,Embedded",
-    documented: false,
-    platforms: DART2JS_PLATFORM);
-
-
-class CustomCompiler extends Compiler {
-  final Map<String, LibraryInfo> customLibraryInfo;
-
-  CustomCompiler(
-      this.customLibraryInfo,
-      provider,
-      handler,
-      libraryRoot,
-      packageRoot,
-      options,
-      environment)
-      : super(
-          provider,
-          const NullCompilerOutput(),
-          handler,
-          libraryRoot,
-          packageRoot,
-          options,
-          environment);
-
-  LibraryInfo lookupLibraryInfo(String name) {
-    if (name == "m_o_c_k_1") return mock1LibraryInfo;
-    if (name == "m_o_c_k_2") return mock2LibraryInfo;
-    return super.lookupLibraryInfo(name);
+  Uri lookupLibraryUri(String libraryName) {
+    if (libraryName == "m_o_c_k_1") return mock1LibraryUri;
+    if (libraryName == "m_o_c_k_2") return mock2LibraryUri;
+    return super.lookupLibraryUri(libraryName);
   }
 }
 
-main() {
-  Uri sdkRoot = Uri.base.resolve("sdk/");
+main() async {
   Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
 
   var provider = new MemorySourceFileProvider(MEMORY_SOURCE_FILES);
   var handler = new FormattingDiagnosticHandler(provider);
 
   Future wrappedProvider(Uri uri) {
-    if (uri == sdkRoot.resolve('lib/mock1.dart')) {
+    if (uri == mock1LibraryUri) {
       return provider.readStringFromUri(Uri.parse('memory:mock1.dart'));
     }
-    if (uri == sdkRoot.resolve('lib/mock2.dart')) {
+    if (uri == mock2LibraryUri) {
       return provider.readStringFromUri(Uri.parse('memory:mock2.dart'));
     }
     return provider.readStringFromUri(uri);
   }
 
-  String expectedMessage =
-      MessageTemplate.TEMPLATES[MessageKind.LIBRARY_NOT_FOUND].message(
-          {'resolvedUri': 'dart:mock2.dart'}).computeMessage();
+  String expectedMessage = MessageTemplate.TEMPLATES[
+          MessageKind.LIBRARY_NOT_FOUND]
+      .message({'resolvedUri': 'dart:mock2.dart'}).computeMessage();
 
   int actualMessageCount = 0;
 
-  wrappedHandler(
-      Uri uri, int begin, int end, String message, kind) {
+  wrappedHandler(Uri uri, int begin, int end, String message, kind) {
     if (message == expectedMessage) {
       actualMessageCount++;
     } else {
@@ -111,8 +77,7 @@
     Expect.equals(1, actualMessageCount);
   }
 
-  Compiler compiler = new CustomCompiler(
-      {},
+  CompilerImpl compiler = new CustomCompiler(
       new LegacyCompilerInput(wrappedProvider),
       new LegacyCompilerDiagnostics(wrappedHandler),
       sdkRoot,
@@ -121,9 +86,11 @@
       {});
 
   asyncStart();
-  compiler.libraryLoader.loadLibrary(Uri.parse("dart:m_o_c_k_1"))
-      .then(checkLibrary)
-      .then(asyncSuccess);
+  await compiler.setupSdk();
+  var library =
+      await compiler.libraryLoader.loadLibrary(Uri.parse("dart:m_o_c_k_1"));
+  await checkLibrary(library);
+  asyncSuccess(null);
 }
 
 const Map MEMORY_SOURCE_FILES = const {
diff --git a/tests/compiler/dart2js/list_tracer2_test.dart b/tests/compiler/dart2js/list_tracer2_test.dart
index 5c60954..76ee4b5a 100644
--- a/tests/compiler/dart2js/list_tracer2_test.dart
+++ b/tests/compiler/dart2js/list_tracer2_test.dart
@@ -24,7 +24,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkType(String name, type) {
diff --git a/tests/compiler/dart2js/list_tracer3_test.dart b/tests/compiler/dart2js/list_tracer3_test.dart
index e9decd9..3ef45d2 100644
--- a/tests/compiler/dart2js/list_tracer3_test.dart
+++ b/tests/compiler/dart2js/list_tracer3_test.dart
@@ -27,7 +27,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkType(String name, type) {
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/list_tracer_test.dart
index d6edb88..24d7ae0 100644
--- a/tests/compiler/dart2js/list_tracer_test.dart
+++ b/tests/compiler/dart2js/list_tracer_test.dart
@@ -198,7 +198,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(generateTest(allocation), uri,
       expectedErrors: 0, expectedWarnings: 1);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
diff --git a/tests/compiler/dart2js/lookup_member_test.dart b/tests/compiler/dart2js/lookup_member_test.dart
index d43bcd0..aec363a 100644
--- a/tests/compiler/dart2js/lookup_member_test.dart
+++ b/tests/compiler/dart2js/lookup_member_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library subtype_test;
+library lookup_member_test;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/map_tracer_const_test.dart b/tests/compiler/dart2js/map_tracer_const_test.dart
index 8389de6..1365349 100644
--- a/tests/compiler/dart2js/map_tracer_const_test.dart
+++ b/tests/compiler/dart2js/map_tracer_const_test.dart
@@ -33,7 +33,7 @@
   var compiler = compilerFor(TEST, uri,
       expectedErrors: 0, expectedWarnings: 0);
   compiler.stopAfterTypeInference = true;
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var element = findElement(compiler, 'closure');
diff --git a/tests/compiler/dart2js/map_tracer_keys_test.dart b/tests/compiler/dart2js/map_tracer_keys_test.dart
index 0c2edb7..da6f9fa 100644
--- a/tests/compiler/dart2js/map_tracer_keys_test.dart
+++ b/tests/compiler/dart2js/map_tracer_keys_test.dart
@@ -54,7 +54,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(generateTest(key, value, initial), uri,
       expectedErrors: 0, expectedWarnings: 0);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var aDoubleType =
diff --git a/tests/compiler/dart2js/map_tracer_test.dart b/tests/compiler/dart2js/map_tracer_test.dart
index c45370a..d7aa366 100644
--- a/tests/compiler/dart2js/map_tracer_test.dart
+++ b/tests/compiler/dart2js/map_tracer_test.dart
@@ -215,7 +215,7 @@
   var compiler = compilerFor(generateTest(allocation), uri,
       expectedErrors: 0, expectedWarnings: 1);
   var classWorld = compiler.world;
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var keyType, valueType;
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
diff --git a/tests/compiler/dart2js/members_test.dart b/tests/compiler/dart2js/members_test.dart
index d4be7ab..0856b32 100644
--- a/tests/compiler/dart2js/members_test.dart
+++ b/tests/compiler/dart2js/members_test.dart
@@ -8,11 +8,18 @@
 import "package:async_helper/async_helper.dart";
 import 'type_test_helper.dart';
 import 'package:compiler/src/dart_types.dart';
-import "package:compiler/src/elements/elements.dart"
-       show Element, ClassElement, MemberSignature, Name, PublicName,
-            DeclaredMember, Member;
-import "package:compiler/src/resolution/class_members.dart"
-  show DeclaredMember, ErroneousMember, SyntheticMember;
+import "package:compiler/src/elements/elements.dart" show
+    Element,
+    ClassElement,
+    MemberSignature,
+    Name,
+    PublicName,
+    Member;
+import "package:compiler/src/resolution/class_members.dart" show
+    MembersCreator,
+    DeclaredMember,
+    ErroneousMember,
+    SyntheticMember;
 
 void main() {
   testClassMembers();
@@ -212,6 +219,8 @@
                 functionType: env.functionType(String_, []));
 
     InterfaceType A = env['A'];
+    MembersCreator.computeAllClassMembers(env.compiler, A.element);
+
     checkMemberCount(A, 5 /*inherited*/ + 9 /*non-static declared*/,
                      interfaceMembers: true);
     checkMemberCount(A, 5 /*inherited*/ + 9 /*non-abstract declared*/ +
@@ -255,6 +264,7 @@
                 isStatic: true, functionType: env.functionType(dynamic_, []));
 
     ClassElement B = env.getElement('B');
+    MembersCreator.computeAllClassMembers(env.compiler, B);
     InterfaceType B_this = B.thisType;
     TypeVariableType B_T = B_this.typeArguments.first;
     checkMemberCount(B_this, 4 /*inherited*/ + 4 /*non-static declared*/,
@@ -280,6 +290,7 @@
                                                optionalParameters: [B_T]));
 
     ClassElement C = env.getElement('C');
+    MembersCreator.computeAllClassMembers(env.compiler, C);
     InterfaceType C_this = C.thisType;
     TypeVariableType C_S = C_this.typeArguments.first;
     checkMemberCount(C_this, 8 /*inherited*/, interfaceMembers: true);
@@ -306,6 +317,7 @@
                                                optionalParameters: [C_S]));
 
     InterfaceType D = env['D'];
+    MembersCreator.computeAllClassMembers(env.compiler, D.element);
     checkMemberCount(D, 8 /*inherited*/, interfaceMembers: true);
     checkMemberCount(D, 8 /*inherited*/, interfaceMembers: false);
     InterfaceType B_int = instantiate(B, [int_]);
@@ -330,6 +342,7 @@
                                                optionalParameters: [int_]));
 
     InterfaceType E = env['E'];
+    MembersCreator.computeAllClassMembers(env.compiler, E.element);
     checkMemberCount(E, 8 /*inherited*/, interfaceMembers: true);
     checkMemberCount(E, 8 /*inherited*/, interfaceMembers: false);
 
@@ -411,6 +424,9 @@
     InterfaceType C = env['C'];
     InterfaceType D = env['D'];
 
+    // Ensure that members have been computed on all classes.
+    MembersCreator.computeAllClassMembers(env.compiler, D.element);
+
     // A: num method1()
     // B: int method1()
     // D: dynamic method1() -- synthesized from A and B.
@@ -576,6 +592,9 @@
     InterfaceType B = env['B'];
     InterfaceType C = env['C'];
 
+    // Ensure that members have been computed on all classes.
+    MembersCreator.computeAllClassMembers(env.compiler, C.element);
+
     // A: method1()
     // B: method1()
     // C class: method1() -- inherited from A.
@@ -634,6 +653,9 @@
     InterfaceType A_U = instantiate(A, [C_U]);
     InterfaceType B_V = instantiate(B, [C_V]);
 
+    // Ensure that members have been computed on all classes.
+    MembersCreator.computeAllClassMembers(env.compiler, C);
+
     // A: method1()
     // B: method1()
     // C class: method1() -- inherited from A.
@@ -702,6 +724,9 @@
     InterfaceType B = env['B'];
     InterfaceType C = env['C'];
 
+    // Ensure that members have been computed on all classes.
+    MembersCreator.computeAllClassMembers(env.compiler, C.element);
+
     checkMember(C, 'm', checkType: NO_CLASS_MEMBER,
                 inheritedFrom: A,
                 functionType: env.functionType(dynamic_ , []));
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index be6780f..fa69df7 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -28,64 +28,7 @@
 export 'output_collector.dart';
 export 'package:compiler/compiler_new.dart' show
     CompilationResult;
-
-class DiagnosticMessage {
-  final Message message;
-  final Uri uri;
-  final int begin;
-  final int end;
-  final String text;
-  final Diagnostic kind;
-
-  DiagnosticMessage(
-      this.message, this.uri, this.begin, this.end, this.text, this.kind);
-
-  String toString() => '$uri:$begin:$end:$text:$kind';
-}
-
-class DiagnosticCollector implements CompilerDiagnostics {
-  List<DiagnosticMessage> messages = <DiagnosticMessage>[];
-
-  void call(Uri uri, int begin, int end, String message, Diagnostic kind) {
-    report(null, uri, begin, end, message, kind);
-  }
-
-  @override
-  void report(Message message,
-              Uri uri, int begin, int end, String text, Diagnostic kind) {
-    messages.add(new DiagnosticMessage(message, uri, begin, end, text, kind));
-  }
-
-  Iterable<DiagnosticMessage> filterMessagesByKinds(List<Diagnostic> kinds) {
-    return messages.where(
-      (DiagnosticMessage message) => kinds.contains(message.kind));
-  }
-
-  Iterable<DiagnosticMessage> get errors {
-    return filterMessagesByKinds([Diagnostic.ERROR]);
-  }
-
-  Iterable<DiagnosticMessage> get warnings {
-    return filterMessagesByKinds([Diagnostic.WARNING]);
-  }
-
-  Iterable<DiagnosticMessage> get hints {
-    return filterMessagesByKinds([Diagnostic.HINT]);
-  }
-
-  Iterable<DiagnosticMessage> get infos {
-    return filterMessagesByKinds([Diagnostic.INFO]);
-  }
-
-  /// `true` if non-verbose messages has been collected.
-  bool get hasRegularMessages {
-    return messages.any((m) => m.kind != Diagnostic.VERBOSE_INFO);
-  }
-
-  void clear() {
-    messages.clear();
-  }
-}
+export 'diagnostic_helper.dart';
 
 class MultiDiagnostics implements CompilerDiagnostics {
   final List<CompilerDiagnostics> diagnosticsList;
@@ -131,16 +74,16 @@
      CompilerDiagnostics diagnosticHandler,
      CompilerOutput outputProvider,
      List<String> options: const <String>[],
-     Compiler cachedCompiler,
+     CompilerImpl cachedCompiler,
      bool showDiagnostics: true,
      Uri packageRoot,
      Uri packageConfig,
      PackagesDiscoveryProvider packagesDiscoveryProvider,
-     void beforeRun(Compiler compiler)}) async {
+     void beforeRun(CompilerImpl compiler)}) async {
   if (entryPoint == null) {
     entryPoint = Uri.parse('memory:main.dart');
   }
-  Compiler compiler = compilerFor(
+  CompilerImpl compiler = compilerFor(
       memorySourceFiles: memorySourceFiles,
       diagnosticHandler: diagnosticHandler,
       outputProvider: outputProvider,
@@ -158,12 +101,12 @@
   return new CompilationResult(compiler, isSuccess: isSuccess);
 }
 
-Compiler compilerFor(
+CompilerImpl compilerFor(
     {Map<String, String> memorySourceFiles: const <String, String>{},
      CompilerDiagnostics diagnosticHandler,
      CompilerOutput outputProvider,
      List<String> options: const <String>[],
-     Compiler cachedCompiler,
+     CompilerImpl cachedCompiler,
      bool showDiagnostics: true,
      Uri packageRoot,
      Uri packageConfig,
@@ -172,7 +115,7 @@
   if (packageRoot == null &&
       packageConfig == null &&
       packagesDiscoveryProvider == null) {
-    packageRoot = Uri.base.resolveUri(new Uri.file('${Platform.packageRoot}/'));
+    packageRoot = Uri.base.resolve(Platform.packageRoot);
   }
 
   MemorySourceFileProvider provider;
@@ -196,7 +139,7 @@
     outputProvider = const NullCompilerOutput();
   }
 
-  Compiler compiler = new Compiler(
+  CompilerImpl compiler = new CompilerImpl(
       provider,
       outputProvider,
       diagnosticHandler,
@@ -322,8 +265,7 @@
                                       List<String> options: const [],
                                       bool showDiagnostics: true}) {
   Uri libraryRoot = Uri.base.resolve('sdk/');
-  Uri packageRoot = Uri.base.resolveUri(
-      new Uri.file('${Platform.packageRoot}/'));
+  Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
 
   var provider = new MemorySourceFileProvider(memorySourceFiles);
   var handler =
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 3ff2ba5..2efa806 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -8,7 +8,7 @@
 export 'dart:io' show Platform;
 
 export 'package:compiler/src/apiimpl.dart'
-       show Compiler;
+       show CompilerImpl;
 
 export 'package:compiler/src/filenames.dart'
        show currentDirectory;
diff --git a/tests/compiler/dart2js/message_kind_helper.dart b/tests/compiler/dart2js/message_kind_helper.dart
index 9d60632..ad46907 100644
--- a/tests/compiler/dart2js/message_kind_helper.dart
+++ b/tests/compiler/dart2js/message_kind_helper.dart
@@ -15,8 +15,8 @@
 import 'package:compiler/src/diagnostics/messages.dart' show
     MessageKind,
     MessageTemplate;
-import 'package:compiler/src/old_to_new_api.dart' show
-    LegacyCompilerDiagnostics;
+import 'package:compiler/compiler_new.dart' show
+    Diagnostic;
 
 import 'memory_compiler.dart';
 
@@ -33,6 +33,7 @@
     MessageKind.CANNOT_IMPLEMENT_MALFORMED,
     MessageKind.CANNOT_MIXIN,
     MessageKind.CANNOT_MIXIN_MALFORMED,
+    MessageKind.CANNOT_INSTANTIATE_ENUM,
     MessageKind.CYCLIC_TYPEDEF_ONE,
     MessageKind.EQUAL_MAP_ENTRY_KEY,
     MessageKind.FINAL_FUNCTION_TYPE_PARAMETER,
@@ -68,13 +69,7 @@
       Expect.isTrue(example.containsKey('main.dart'),
                     "Example map must contain a 'main.dart' entry.");
     }
-    List<String> messages = <String>[];
-    void collect(Uri uri, int begin, int end, String message, kind) {
-      if (kind.name == 'verbose info' || kind.name == 'info') {
-        return;
-      }
-      messages.add(message);
-    }
+    DiagnosticCollector collector = new DiagnosticCollector();
 
     bool oldBackendIsDart;
     if (cachedCompiler != null) {
@@ -84,7 +79,7 @@
 
     Compiler compiler = compilerFor(
         memorySourceFiles: example,
-        diagnosticHandler: new LegacyCompilerDiagnostics(collect),
+        diagnosticHandler: collector,
         options: [Flags.analyzeOnly,
                   Flags.enableExperimentalMirrors]..addAll(template.options),
         cachedCompiler:
@@ -93,6 +88,11 @@
              oldBackendIsDart == newBackendIsDart ? cachedCompiler : null);
 
     return compiler.run(Uri.parse('memory:main.dart')).then((_) {
+      Iterable<CollectedMessage> messages = collector.filterMessagesByKinds(
+          [Diagnostic.ERROR,
+           Diagnostic.WARNING,
+           Diagnostic.HINT,
+           Diagnostic.CRASH]);
 
       Expect.isFalse(messages.isEmpty, 'No messages in """$example"""');
 
@@ -102,21 +102,32 @@
           new RegExp(ESCAPE_REGEXP), (m) => '\\${m[0]}');
       pattern = pattern.replaceAll(new RegExp(r'#\\\{[^}]*\\\}'), '.*');
 
+      bool checkMessage(CollectedMessage message) {
+        if (message.message.kind != MessageKind.GENERIC) {
+          return message.message.kind == template.kind;
+        } else {
+          return new RegExp('^$pattern\$').hasMatch(message.text);
+        }
+      }
+
       // TODO(johnniwinther): Extend MessageKind to contain information on
       // where info messages are expected.
       bool messageFound = false;
       List unexpectedMessages = [];
-      for (String message in messages) {
-        if (!messageFound && new RegExp('^$pattern\$').hasMatch(message)) {
+      for (CollectedMessage message in messages) {
+        if (!messageFound && checkMessage(message)) {
           messageFound = true;
         } else {
           unexpectedMessages.add(message);
         }
       }
-      Expect.isTrue(messageFound, '"$pattern" does not match any in $messages');
-      Expect.isFalse(compiler.reporter.hasCrashed);
+      Expect.isTrue(messageFound,
+          '${template.kind}} does not match any in\n '
+          '${messages.join('\n ')}');
+      var reporter = compiler.reporter;
+      Expect.isFalse(reporter.hasCrashed);
       if (!unexpectedMessages.isEmpty) {
-        for (String message in unexpectedMessages) {
+        for (CollectedMessage message in unexpectedMessages) {
           print("Unexpected message: $message");
         }
         if (!kindsWithExtraMessages.contains(template.kind)) {
diff --git a/tests/compiler/dart2js/metadata_test.dart b/tests/compiler/dart2js/metadata_test.dart
index 0f1e9fd..9255a75 100644
--- a/tests/compiler/dart2js/metadata_test.dart
+++ b/tests/compiler/dart2js/metadata_test.dart
@@ -176,7 +176,7 @@
         ..registerSource(partUri, partSource)
         ..registerSource(libUri, libSource);
 
-    asyncTest(() => compiler.runCompiler(uri).then((_) {
+    asyncTest(() => compiler.run(uri).then((_) {
       compiler.enqueuer.resolution.queueIsClosed = false;
       LibraryElement element = compiler.libraryLoader.lookupLibrary(uri);
       Expect.isNotNull(element, 'Cannot find $uri');
diff --git a/tests/compiler/dart2js/minimal_resolution_test.dart b/tests/compiler/dart2js/minimal_resolution_test.dart
index b46b340..7de35a3 100644
--- a/tests/compiler/dart2js/minimal_resolution_test.dart
+++ b/tests/compiler/dart2js/minimal_resolution_test.dart
@@ -8,7 +8,7 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/enqueue.dart';
-import 'package:compiler/src/js_backend/js_backend.dart';
+import 'package:compiler/src/js_backend/backend_helpers.dart';
 import 'package:expect/expect.dart';
 import 'memory_compiler.dart';
 
@@ -50,7 +50,7 @@
       compiler, compiler.coreLibrary.find('Deprecated'), deprecatedClass);
 
   LibraryElement jsHelperLibrary =
-      compiler.libraryLoader.lookupLibrary(JavaScriptBackend.DART_JS_HELPER);
+      compiler.libraryLoader.lookupLibrary(BackendHelpers.DART_JS_HELPER);
   jsHelperLibrary.forEachLocalMember((Element element) {
     Uri uri = element.compilationUnit.script.resourceUri;
     if (element.isClass && uri.path.endsWith('annotations.dart')) {
diff --git a/tests/compiler/dart2js/mirror_helper_rename_test.dart b/tests/compiler/dart2js/mirror_helper_rename_test.dart
index 76d3adb..80edc15 100644
--- a/tests/compiler/dart2js/mirror_helper_rename_test.dart
+++ b/tests/compiler/dart2js/mirror_helper_rename_test.dart
@@ -7,7 +7,7 @@
 import "package:async_helper/async_helper.dart";
 import 'memory_compiler.dart' show runCompiler, OutputCollector;
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 import 'package:compiler/src/tree/tree.dart' show
     Node;
 import 'package:compiler/src/dart_backend/dart_backend.dart';
@@ -22,7 +22,7 @@
   });
 }
 
-Future<Compiler> run({OutputCollector outputCollector,
+Future<CompilerImpl> run({OutputCollector outputCollector,
                       bool useMirrorHelperLibrary: false,
                       bool minify: false}) async {
   List<String> options = ['--output-type=dart'];
@@ -33,7 +33,7 @@
       memorySourceFiles: MEMORY_SOURCE_FILES,
       outputProvider: outputCollector,
       options: options,
-      beforeRun: (Compiler compiler) {
+      beforeRun: (CompilerImpl compiler) {
         DartBackend backend = compiler.backend;
         backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
       });
@@ -42,7 +42,7 @@
 
 Future testWithMirrorHelperLibrary({bool minify}) async {
   OutputCollector outputCollector = new OutputCollector();
-  Compiler compiler = await run(
+  CompilerImpl compiler = await run(
       outputCollector: outputCollector,
       useMirrorHelperLibrary: true,
       minify: minify);
@@ -83,7 +83,8 @@
 }
 
 Future testWithoutMirrorHelperLibrary({bool minify}) async {
-  Compiler compiler = await run(useMirrorHelperLibrary: false, minify: minify);
+  CompilerImpl compiler =
+      await run(useMirrorHelperLibrary: false, minify: minify);
   DartBackend backend = compiler.backend;
   MirrorRenamer mirrorRenamer = backend.mirrorRenamer;
 
diff --git a/tests/compiler/dart2js/mirror_helper_test.dart b/tests/compiler/dart2js/mirror_helper_test.dart
index e823b8b..ce257c7 100644
--- a/tests/compiler/dart2js/mirror_helper_test.dart
+++ b/tests/compiler/dart2js/mirror_helper_test.dart
@@ -7,7 +7,7 @@
 import "package:async_helper/async_helper.dart";
 import 'memory_compiler.dart' show runCompiler;
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 import 'package:compiler/src/elements/elements.dart' show
     Element, LibraryElement, ClassElement;
 import 'package:compiler/src/tree/tree.dart' show
@@ -26,7 +26,7 @@
   });
 }
 
-Future<Compiler> run({useMirrorHelperLibrary: false, minify: false}) async {
+Future<CompilerImpl> run({useMirrorHelperLibrary: false, minify: false}) async {
   List<String> options = ['--output-type=dart'];
   if (minify) {
     options.add('--minify');
@@ -34,7 +34,7 @@
   var result = await runCompiler(
       memorySourceFiles: MEMORY_SOURCE_FILES,
       options: options,
-      beforeRun: (Compiler compiler) {
+      beforeRun: (CompilerImpl compiler) {
         DartBackend backend = compiler.backend;
         backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
       });
@@ -42,7 +42,8 @@
 }
 
 Future testWithMirrorRenaming({bool minify}) async {
-  Compiler compiler = await run(useMirrorHelperLibrary: true, minify: minify);
+  CompilerImpl compiler =
+      await run(useMirrorHelperLibrary: true, minify: minify);
   DartBackend backend = compiler.backend;
   MirrorRenamerImpl mirrorRenamer = backend.mirrorRenamer;
   Map<Node, String> renames = backend.placeholderRenamer.renames;
@@ -62,7 +63,8 @@
 }
 
 Future testWithoutMirrorRenaming({bool minify}) async {
-  Compiler compiler = await run(useMirrorHelperLibrary: false, minify: minify);
+  CompilerImpl compiler =
+      await run(useMirrorHelperLibrary: false, minify: minify);
   DartBackend backend = compiler.backend;
   Map<Node, String> renames = backend.placeholderRenamer.renames;
   Iterable<LibraryElement> imports =
diff --git a/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart b/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
index 47c8145..bec8f9f 100644
--- a/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
+++ b/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
@@ -7,7 +7,7 @@
 import "package:async_helper/async_helper.dart";
 import 'memory_compiler.dart' show runCompiler;
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 import 'package:compiler/src/dart_backend/dart_backend.dart' show
     DartBackend;
 import 'package:compiler/src/tree/tree.dart' show
@@ -22,7 +22,7 @@
   });
 }
 
-Future<Compiler> run({useMirrorHelperLibrary: false, minify: false}) async {
+Future<CompilerImpl> run({useMirrorHelperLibrary: false, minify: false}) async {
   List<String> options = ['--output-type=dart'];
   if (minify) {
     options.add('--minify');
@@ -30,7 +30,7 @@
   var result = await runCompiler(
       memorySourceFiles: MEMORY_SOURCE_FILES,
       options: options,
-      beforeRun: (Compiler compiler) {
+      beforeRun: (CompilerImpl compiler) {
         DartBackend backend = compiler.backend;
         backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
       });
@@ -38,7 +38,7 @@
 }
 
 Future testUniqueMinification() async {
-  Compiler compiler = await run(useMirrorHelperLibrary: true, minify: true);
+  CompilerImpl compiler = await run(useMirrorHelperLibrary: true, minify: true);
   DartBackend backend = compiler.backend;
   MirrorRenamerImpl mirrorRenamer = backend.mirrorRenamer;
   Map<Node, String> renames = backend.placeholderRenamer.renames;
@@ -63,7 +63,8 @@
 }
 
 Future testNoUniqueMinification() async {
-  Compiler compiler = await run(useMirrorHelperLibrary: false, minify: true);
+  CompilerImpl compiler =
+      await run(useMirrorHelperLibrary: false, minify: true);
   DartBackend backend = compiler.backend;
   Map<Node, String> renames = backend.placeholderRenamer.renames;
 
diff --git a/tests/compiler/dart2js/mirror_system_helper.dart b/tests/compiler/dart2js/mirror_system_helper.dart
index 7c97ebd..323ff8e 100644
--- a/tests/compiler/dart2js/mirror_system_helper.dart
+++ b/tests/compiler/dart2js/mirror_system_helper.dart
@@ -23,7 +23,7 @@
       preserveComments: true);
     compiler.registerSource(SOURCE_URI, source);
     compiler.librariesToAnalyzeWhenRun = <Uri>[SOURCE_URI];
-  return compiler.runCompiler(null).then((_) {
+  return compiler.run(null).then((_) {
     return new Dart2JsMirrorSystem(compiler);
   });
 }
diff --git a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart b/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
index 3059fd1..ed8d8fd 100644
--- a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
+++ b/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
@@ -27,7 +27,8 @@
     try {
       return f();
     } on SpannableAssertionFailure catch (e) {
-      mirrorSystem.compiler.reportAssertionFailure(e);
+      var reporter = mirrorSystem.compiler.reporter;
+      reporter.reportAssertionFailure(e);
       rethrow;
     }
   }
diff --git a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart b/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
index 0aa116f..c308dae 100644
--- a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
+++ b/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
@@ -24,8 +24,7 @@
 Future<MirrorSystem> analyzeUri(Uri testUri) {
   Uri repository = Platform.script.resolve('../../../../');
   Uri libraryRoot = repository.resolve('sdk/');
-  Uri packageRoot = Uri.base.resolveUri(
-      new Uri.file('${Platform.packageRoot}/'));
+  Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
   var provider = new CompilerSourceFileProvider();
   var handler = new FormattingDiagnosticHandler(provider);
   return source_mirrors.analyze(
@@ -34,4 +33,4 @@
       packageRoot,
       provider,
       handler);
-}
\ No newline at end of file
+}
diff --git a/tests/compiler/dart2js/mirrors_helper.dart b/tests/compiler/dart2js/mirrors_helper.dart
index 30910d5..7ffae11 100644
--- a/tests/compiler/dart2js/mirrors_helper.dart
+++ b/tests/compiler/dart2js/mirrors_helper.dart
@@ -15,10 +15,9 @@
 }
 
 /// Singleline doc comment.
-@Metadata // This is intentionally the type literal.
+@Metadata(null)
 // Singleline comment 1.
 // Singleline comment 2.
-@Metadata(null)
 @Metadata(true)
 @Metadata(false)
 @Metadata(0)
diff --git a/tests/compiler/dart2js/mirrors_lookup_test.dart b/tests/compiler/dart2js/mirrors_lookup_test.dart
index 2e8802f..32e04e1 100644
--- a/tests/compiler/dart2js/mirrors_lookup_test.dart
+++ b/tests/compiler/dart2js/mirrors_lookup_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library dart2js.test.memory_source_file_helper;
+library dart2js.test.mirrors_lookup;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/mirrors_test.dart b/tests/compiler/dart2js/mirrors_test.dart
index 7d3c48c..ef815e9 100644
--- a/tests/compiler/dart2js/mirrors_test.dart
+++ b/tests/compiler/dart2js/mirrors_test.dart
@@ -169,7 +169,7 @@
 
   var metadataList = fooClass.metadata;
   Expect.isNotNull(metadataList);
-  Expect.equals(16, metadataList.length);
+  Expect.equals(14, metadataList.length);
   var metadataListIndex = 0;
   var metadata;
 
@@ -192,28 +192,17 @@
   Expect.stringEquals(
       "Singleline doc comment.", metadata.trimmedText);
 
-  // @Metadata
+  // @Metadata(null)
   metadata = metadataList[metadataListIndex++];
+  var metadataType = metadata.type;
   Expect.isTrue(metadata is InstanceMirror);
   Expect.isFalse(metadata.hasReflectee);
   Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadata is TypeInstanceMirror);
-  var metadataType = metadata.representedType;
-  Expect.isNotNull(metadataType);
-  Expect.equals(#Metadata, metadataType.simpleName);
-
-  // // This is intentionally the type literal.
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadata is CommentInstanceMirror);
-  Expect.equals(commentType.originalDeclaration, metadata.type);
-  Expect.isFalse(metadata.isDocComment);
-  Expect.stringEquals(
-      "// This is intentionally the type literal.", metadata.text);
-  Expect.stringEquals(
-      "This is intentionally the type literal.", metadata.trimmedText);
+  Expect.isTrue(metadataType.isOriginalDeclaration);
+  InstanceMirror data = metadata.getField(#data);
+  Expect.isNotNull(data);
+  Expect.isTrue(data.hasReflectee);
+  Expect.isNull(data.reflectee);
 
   // Singleline comment 1.
   metadata = metadataList[metadataListIndex++];
@@ -241,17 +230,6 @@
   Expect.stringEquals(
       "Singleline comment 2.", metadata.trimmedText);
 
-  // @Metadata(null)
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  InstanceMirror data = metadata.getField(#data);
-  Expect.isNotNull(data);
-  Expect.isTrue(data.hasReflectee);
-  Expect.isNull(data.reflectee);
-
   // @Metadata(true)
   metadata = metadataList[metadataListIndex++];
   Expect.isTrue(metadata is InstanceMirror);
@@ -398,7 +376,7 @@
   // leading comment.
   Expect.equals(376, fooClassLocation.offset, "Unexpected offset");
   // Expect the location to end with the class body.
-  Expect.equals(351, fooClassLocation.length, "Unexpected length");
+  Expect.equals(298, fooClassLocation.length, "Unexpected length");
   Expect.equals(18, fooClassLocation.line, "Unexpected line");
   Expect.equals(1, fooClassLocation.column, "Unexpected column");
 
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index c68281f..0844273 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -13,7 +13,7 @@
     runCompiler;
 
 import 'package:compiler/src/apiimpl.dart' show
-    Compiler;
+    CompilerImpl;
 
 import 'package:compiler/src/constants/values.dart' show
     ConstantValue,
@@ -55,7 +55,7 @@
       memorySourceFiles: MEMORY_SOURCE_FILES,
       diagnosticHandler: new LegacyCompilerDiagnostics(expectOnlyVerboseInfo),
       options: ['--enable-experimental-mirrors']);
-    Compiler compiler = result.compiler;
+    CompilerImpl compiler = result.compiler;
     print('');
     List generatedCode =
         Elements.sortedByPosition(compiler.enqueuer.codegen.generatedCode.keys);
@@ -88,9 +88,13 @@
 
     // We always include the names of some native classes.
     List<Element> nativeClasses = [
-          compiler.intClass, compiler.doubleClass, compiler.numClass,
-          compiler.stringClass, compiler.boolClass, compiler.nullClass,
-          compiler.listClass
+          compiler.coreClasses.intClass,
+          compiler.coreClasses.doubleClass,
+          compiler.coreClasses.numClass,
+          compiler.coreClasses.stringClass,
+          compiler.coreClasses.boolClass,
+          compiler.coreClasses.nullClass,
+          compiler.coreClasses.listClass
         ];
     JavaScriptBackend backend = compiler.backend;
     Iterable<String> nativeNames = nativeClasses.map(backend.namer.className);
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 2195fe6..11b450d 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -13,12 +13,13 @@
     Uris;
 import 'package:compiler/src/constants/expressions.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
-import 'package:compiler/src/diagnostics/messages.dart';
 import 'package:compiler/src/diagnostics/source_span.dart';
 import 'package:compiler/src/diagnostics/spannable.dart';
 import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/js_backend/js_backend.dart'
-    show JavaScriptBackend;
+import 'package:compiler/src/js_backend/backend_helpers.dart'
+    show BackendHelpers;
+import 'package:compiler/src/js_backend/lookup_map_analysis.dart'
+    show LookupMapAnalysis;
 import 'package:compiler/src/io/source_file.dart';
 import 'package:compiler/src/resolution/members.dart';
 import 'package:compiler/src/resolution/registry.dart';
@@ -42,14 +43,9 @@
          OutputUnit;
 
 import 'mock_libraries.dart';
+import 'diagnostic_helper.dart';
 
-class WarningMessage {
-  Spannable node;
-  Message message;
-  WarningMessage(this.node, this.message);
-
-  toString() => message.kind.toString();
-}
+export 'diagnostic_helper.dart';
 
 final Uri PATCH_CORE = new Uri(scheme: 'patch', path: 'core');
 
@@ -57,11 +53,6 @@
 
 class MockCompiler extends Compiler {
   api.DiagnosticHandler diagnosticHandler;
-  List<WarningMessage> warnings;
-  List<WarningMessage> errors;
-  List<WarningMessage> hints;
-  List<WarningMessage> infos;
-  List<WarningMessage> crashes;
   /// Expected number of warnings. If `null`, the number of warnings is
   /// not checked.
   final int expectedWarnings;
@@ -71,6 +62,7 @@
   Node parsedTree;
   final String testedPatchVersion;
   final LibrarySourceProvider librariesOverride;
+  final DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
 
   MockCompiler.internal(
       {Map<String, String> coreSource,
@@ -109,28 +101,26 @@
               trustTypeAnnotations: trustTypeAnnotations,
               trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations,
               diagnosticOptions:
-                  new DiagnosticOptions(showPackageWarnings: true),
+                  new DiagnosticOptions(shownPackageWarnings: const []),
               outputProvider: new LegacyCompilerOutput(outputProvider)) {
     this.disableInlining = disableInlining;
 
     deferredLoadTask = new MockDeferredLoadTask(this);
 
-    clearMessages();
-
     registerSource(Uris.dart_core,
                    buildLibrarySource(DEFAULT_CORE_LIBRARY, coreSource));
     registerSource(PATCH_CORE, DEFAULT_PATCH_CORE_SOURCE);
 
-    registerSource(JavaScriptBackend.DART_JS_HELPER,
+    registerSource(BackendHelpers.DART_JS_HELPER,
                    buildLibrarySource(DEFAULT_JS_HELPER_LIBRARY));
-    registerSource(JavaScriptBackend.DART_FOREIGN_HELPER,
+    registerSource(BackendHelpers.DART_FOREIGN_HELPER,
                    buildLibrarySource(DEFAULT_FOREIGN_HELPER_LIBRARY));
-    registerSource(JavaScriptBackend.DART_INTERCEPTORS,
+    registerSource(BackendHelpers.DART_INTERCEPTORS,
                    buildLibrarySource(DEFAULT_INTERCEPTORS_LIBRARY));
-    registerSource(JavaScriptBackend.DART_ISOLATE_HELPER,
+    registerSource(BackendHelpers.DART_ISOLATE_HELPER,
                    buildLibrarySource(DEFAULT_ISOLATE_HELPER_LIBRARY));
     registerSource(Uris.dart_mirrors, DEFAULT_MIRRORS_SOURCE);
-    registerSource(JavaScriptBackend.DART_JS_MIRRORS,
+    registerSource(BackendHelpers.DART_JS_MIRRORS,
         DEFAULT_JS_MIRRORS_SOURCE);
 
     Map<String, String> asyncLibrarySource = <String, String>{};
@@ -140,7 +130,7 @@
     }
     registerSource(Uris.dart_async,
                    buildLibrarySource(asyncLibrarySource));
-    registerSource(JavaScriptBackend.PACKAGE_LOOKUP_MAP,
+    registerSource(LookupMapAnalysis.PACKAGE_LOOKUP_MAP,
                    buildLibrarySource(DEFAULT_LOOKUP_MAP_LIBRARY));
   }
 
@@ -159,20 +149,22 @@
       // dynamic invocation the ArgumentTypesRegistry eventually iterates over
       // the interfaces of the Object class which would be 'null' if the class
       // wasn't resolved.
-      objectClass.ensureResolved(resolution);
+      coreClasses.objectClass.ensureResolved(resolution);
     }).then((_) => uri);
   }
 
-  Future runCompiler(Uri uri, [String mainSource = ""]) {
+  Future run(Uri uri, [String mainSource = ""]) {
     return init(mainSource).then((Uri mainUri) {
-      return super.runCompiler(uri == null ? mainUri : uri);
+      return super.run(uri == null ? mainUri : uri);
     }).then((result) {
       if (expectedErrors != null &&
-          expectedErrors != errors.length) {
-        throw "unexpected error during compilation ${errors}";
+          expectedErrors != diagnosticCollector.errors.length) {
+        throw "unexpected error during compilation "
+              "${diagnosticCollector.errors}";
       } else if (expectedWarnings != null &&
-                 expectedWarnings != warnings.length) {
-        throw "unexpected warnings during compilation ${warnings}";
+                 expectedWarnings != diagnosticCollector.warnings.length) {
+        throw "unexpected warnings during compilation "
+              "${diagnosticCollector.warnings}";
       } else {
         return result;
       }
@@ -194,39 +186,24 @@
     sourceFiles[uri.toString()] = new MockFile(source);
   }
 
-  // TODO(johnniwinther): Remove this when we don't filter certain type checker
-  // warnings.
-  void reportWarning(
-      DiagnosticMessage message,
-      [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
-    reportDiagnostic(message, infos, api.Diagnostic.WARNING);
-  }
-
   void reportDiagnostic(DiagnosticMessage message,
                         List<DiagnosticMessage> infoMessages,
                         api.Diagnostic kind) {
 
     void processMessage(DiagnosticMessage message, api.Diagnostic kind) {
-      var diagnostic = new WarningMessage(message.spannable, message.message);
-      if (kind == api.Diagnostic.CRASH) {
-        crashes.add(diagnostic);
-      } else if (kind == api.Diagnostic.ERROR) {
-        errors.add(diagnostic);
-      } else if (kind == api.Diagnostic.WARNING) {
-        warnings.add(diagnostic);
-      } else if (kind == api.Diagnostic.INFO) {
-        infos.add(diagnostic);
-      } else if (kind == api.Diagnostic.HINT) {
-        hints.add(diagnostic);
+      SourceSpan span = message.sourceSpan;
+      Uri uri;
+      int begin;
+      int end;
+      String text = '${message.message}';
+      if (span != null) {
+        uri = span.uri;
+        begin = span.begin;
+        end = span.end;
       }
+      diagnosticCollector.report(message.message, uri, begin, end, text, kind);
       if (diagnosticHandler != null) {
-        SourceSpan span = message.sourceSpan;
-        if (span != null) {
-          diagnosticHandler(
-              span.uri, span.begin, span.end, '${message.message}', kind);
-        } else {
-          diagnosticHandler(null, null, null, '${message.message}', kind);
-        }
+        diagnosticHandler(uri, begin, end, text, kind);
       }
     }
 
@@ -234,16 +211,6 @@
     infoMessages.forEach((i) => processMessage(i, api.Diagnostic.INFO));
   }
 
-  bool get compilationFailed => !crashes.isEmpty || !errors.isEmpty;
-
-  void clearMessages() {
-    warnings = [];
-    errors = [];
-    hints = [];
-    infos = [];
-    crashes = [];
-  }
-
   CollectingTreeElements resolveStatement(String text) {
     parsedTree = parseStatement(text);
     return resolveNodeStatement(parsedTree, new MockElement(mainApp));
@@ -319,74 +286,6 @@
   }
 }
 
-/// A function the checks [message]. If the check fails or if [message] is
-/// `null`, an error string is returned. Otherwise `null` is returned.
-typedef String CheckMessage(Message message);
-
-CheckMessage checkMessage(MessageKind kind, Map arguments) {
-  return (Message message) {
-    if (message == null) return '$kind';
-    if (message.kind != kind) return 'Expected message $kind, found $message.';
-    for (var key in arguments.keys) {
-      if (!message.arguments.containsKey(key)) {
-        return 'Expected argument $key not found in $message.kind.';
-      }
-      String expectedValue = '${arguments[key]}';
-      String foundValue = '${message.arguments[key]}';
-      if (expectedValue != foundValue) {
-        return 'Expected argument $key with value $expectedValue, '
-               'found $foundValue.';
-      }
-    }
-    return null;
-  };
-}
-
-void compareWarningKinds(String text,
-                         List expectedWarnings,
-                         List<WarningMessage> foundWarnings) {
-  compareMessageKinds(text, expectedWarnings, foundWarnings, 'warning');
-}
-
-/// [expectedMessages] must be a list of either [MessageKind] or [CheckMessage].
-void compareMessageKinds(String text,
-                         List expectedMessages,
-                         List<WarningMessage> foundMessages,
-                         String kind) {
-  var fail = (message) => Expect.fail('$text: $message');
-  HasNextIterator expectedIterator =
-      new HasNextIterator(expectedMessages.iterator);
-  HasNextIterator<WarningMessage> foundIterator =
-      new HasNextIterator(foundMessages.iterator);
-  while (expectedIterator.hasNext && foundIterator.hasNext) {
-    var expected = expectedIterator.next();
-    var found = foundIterator.next();
-    if (expected is MessageKind) {
-      Expect.equals(expected, found.message.kind);
-    } else if (expected is CheckMessage) {
-      String error = expected(found.message);
-      Expect.isNull(error, error);
-    } else {
-      Expect.fail("Unexpected $kind value: $expected.");
-    }
-  }
-  if (expectedIterator.hasNext) {
-    do {
-      var expected = expectedIterator.next();
-      if (expected is CheckMessage) expected = expected(null);
-      print('Expected $kind "${expected}" did not occur');
-    } while (expectedIterator.hasNext);
-    fail('Too few ${kind}s');
-  }
-  if (foundIterator.hasNext) {
-    do {
-      WarningMessage message = foundIterator.next();
-      print('Additional $kind "${message}: ${message.message}"');
-    } while (foundIterator.hasNext);
-    fail('Too many ${kind}s');
-  }
-}
-
 class CollectingTreeElements extends TreeElementMapping {
   final Map<Node, Element> map = new LinkedHashMap<Node, Element>();
 
diff --git a/tests/compiler/dart2js/mock_libraries.dart b/tests/compiler/dart2js/mock_libraries.dart
index 37135b2..1141416 100644
--- a/tests/compiler/dart2js/mock_libraries.dart
+++ b/tests/compiler/dart2js/mock_libraries.dart
@@ -6,6 +6,15 @@
 
 library mock_libraries;
 
+const DEFAULT_PLATFORM_CONFIG = """
+[libraries]
+core:core/core.dart
+async:async/async.dart
+_js_helper:_internal/js_runtime/lib/js_helper.dart
+_interceptors:_internal/js_runtime/lib/interceptors.dart
+_isolate_helper:_internal/js_runtime/lib/isolate_helper.dart
+""";
+
 String buildLibrarySource(
     Map<String, String> elementMap,
     [Map<String, String> additionalElementMap = const <String, String>{}]) {
@@ -54,11 +63,7 @@
           E get current => null;
       }''',
   'LinkedHashMap': r'''
-      class LinkedHashMap {
-        factory LinkedHashMap._empty() => null;
-        factory LinkedHashMap._literal(elements) => null;
-        static _makeEmpty() => null;
-        static _makeLiteral(elements) => null;
+      class LinkedHashMap<K, V> implements Map<K, V> {
       }''',
   'List': r'''
       class List<E> extends Iterable<E> {
@@ -104,6 +109,14 @@
 import 'dart:_interceptors';
 import 'dart:_isolate_helper';
 import 'dart:async';
+
+@patch
+class LinkedHashMap<K, V> {
+  factory LinkedHashMap._empty() => null;
+  factory LinkedHashMap._literal(elements) => null;
+  static _makeEmpty() => null;
+  static _makeLiteral(elements) => null;
+}
 ''';
 
 const Map<String, String> DEFAULT_JS_HELPER_LIBRARY = const <String, String>{
diff --git a/tests/compiler/dart2js/no_such_method_codegen_test.dart b/tests/compiler/dart2js/no_such_method_codegen_test.dart
index 85777ad..b40d311 100644
--- a/tests/compiler/dart2js/no_such_method_codegen_test.dart
+++ b/tests/compiler/dart2js/no_such_method_codegen_test.dart
@@ -20,5 +20,5 @@
 main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  compiler.runCompiler(uri);
+  compiler.run(uri);
 }
diff --git a/tests/compiler/dart2js/no_such_method_enabled_test.dart b/tests/compiler/dart2js/no_such_method_enabled_test.dart
index cb994a9..2f5f9c7 100644
--- a/tests/compiler/dart2js/no_such_method_enabled_test.dart
+++ b/tests/compiler/dart2js/no_such_method_enabled_test.dart
@@ -18,7 +18,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -40,7 +40,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -64,7 +64,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -88,7 +88,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -116,7 +116,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -140,7 +140,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -160,7 +160,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isFalse(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -180,7 +180,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -200,7 +200,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -222,7 +222,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -245,7 +245,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
@@ -270,7 +270,7 @@
 """;
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(source, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     Expect.isTrue(compiler.backend.enabledNoSuchMethod);
     ClassElement clsA = findElement(compiler, 'A');
     Expect.isTrue(
diff --git a/tests/compiler/dart2js/octagon_test.dart b/tests/compiler/dart2js/octagon_test.dart
index 2644c0e..59ea0c0 100644
--- a/tests/compiler/dart2js/octagon_test.dart
+++ b/tests/compiler/dart2js/octagon_test.dart
@@ -233,17 +233,35 @@
 }
 
 lower_bounds_check() {
+  setup();
   SignedVariable w = octagon.makeVariable(0, 1000);
   pushConstraint(w, w, -1);
   Expect.isTrue(octagon.isUnsolvable, 'Value in range 0..1000 is not <= -1');
 }
 
 upper_bounds_check() {
+  setup();
   SignedVariable w = octagon.makeVariable(0, 1000);
   pushConstraint(w.negated, w.negated, -5000);
   Expect.isTrue(octagon.isUnsolvable, 'Value in range 0..1000 is not >= 5000');
 }
 
+diamond_graph() {
+  setup();
+  pushConstraint(v1, v2.negated, 10);
+  pushConstraint(v1, v3.negated, 1);
+  pushConstraint(v2, v3.negated, 1);
+  pushConstraint(v2, v4.negated, 2);
+  pushConstraint(v3, v2.negated, 0);
+  pushConstraint(v3, v4.negated, 100);
+  Expect.isTrue(octagon.isSolvable, 'v1 <= v4 + 3');
+  var c = pushConstraint(v4, v1.negated, -4);
+  Expect.isTrue(octagon.isUnsolvable, 'v4 <= v1 - 4 should be a contradiction');
+  popConstraint(c);
+  pushConstraint(v1.negated, v4, -4); // Check converse constraint.
+  Expect.isTrue(octagon.isUnsolvable, 'v4 <= v1 - 4 should be a contradiction');
+}
+
 void main() {
   negative_loop1();
   negative_loop2();
@@ -261,4 +279,5 @@
   contradict2();
   lower_bounds_check();
   upper_bounds_check();
+  diamond_graph();
 }
diff --git a/tests/compiler/dart2js/override_inheritance_test.dart b/tests/compiler/dart2js/override_inheritance_test.dart
index c71e6b2..628f625 100644
--- a/tests/compiler/dart2js/override_inheritance_test.dart
+++ b/tests/compiler/dart2js/override_inheritance_test.dart
@@ -34,16 +34,24 @@
 
     toList(o) => o == null ? [] : o is List ? o : [o];
 
-    compareMessageKinds(source, toList(errors), compiler.errors, 'error');
+    compareMessageKinds(
+        source, toList(errors),
+        compiler.diagnosticCollector.errors, 'error');
 
-    compareMessageKinds(source, toList(warnings), compiler.warnings, 'warning');
+    compareMessageKinds(
+        source, toList(warnings),
+        compiler.diagnosticCollector.warnings, 'warning');
 
     if (infos != null) {
-      compareMessageKinds(source, toList(infos), compiler.infos, 'info');
+      compareMessageKinds(
+          source, toList(infos),
+          compiler.diagnosticCollector.infos, 'info');
     }
 
     if (hints != null) {
-      compareMessageKinds(source, toList(hints), compiler.hints, 'hint');
+      compareMessageKinds(
+          source, toList(hints),
+          compiler.diagnosticCollector.hints, 'hint');
     }
   });
 }
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index 572a082..202e6f2 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -99,10 +99,10 @@
   Uri uri = new Uri(scheme: "source");
   Script script = new Script(uri, uri,new MockFile(text));
   LibraryElement library = new LibraryElementX(script);
-  library.canUseNative = true;
-  NodeListener listener =
-      new NodeListener(reporter, library.entryCompilationUnit);
-  Parser parser = new Parser(listener);
+  NodeListener listener = new NodeListener(
+      new ScannerOptions(canUseNative: true),
+      reporter, library.entryCompilationUnit);
+  Parser parser = new Parser(listener, enableConditionalDirectives: true);
   Token endToken = parseMethod(parser, tokens);
   assert(endToken.kind == EOF_TOKEN);
   Node node = listener.popNode();
@@ -147,7 +147,9 @@
   var unit = new CompilationUnitElementX(script, library);
   int id = 0;
   DiagnosticReporter reporter = compiler.reporter;
-  ElementListener listener = new ElementListener(reporter, unit, () => id++);
+  ElementListener listener = new ElementListener(
+      compiler.parsing.getScannerOptionsFor(library),
+      reporter, unit, () => id++);
   PartialParser parser = new PartialParser(listener);
   reporter.withCurrentElement(unit, () => parser.parseUnit(tokens));
   return unit.localMembers;
diff --git a/tests/compiler/dart2js/parser_test.dart b/tests/compiler/dart2js/parser_test.dart
index 4674201..2ee3d9e 100644
--- a/tests/compiler/dart2js/parser_test.dart
+++ b/tests/compiler/dart2js/parser_test.dart
@@ -155,19 +155,23 @@
 }
 
 void testNullOperators() {
-  Expression node = parseStatement("a ?? b;").expression;
+  ExpressionStatement statement = parseStatement("a ?? b;");
+  Expression node = statement.expression;
   Expect.isNotNull(node.asSend());
   Expect.isTrue(node.asSend().isIfNull);
 
-  node = parseStatement("a ??= b;").expression;
+  statement = parseStatement("a ??= b;");
+  node = statement.expression;
   Expect.isNotNull(node.asSendSet());
   Expect.isTrue(node.asSendSet().isIfNullAssignment);
 
-  node = parseStatement("a?.b;").expression;
+  statement = parseStatement("a?.b;");
+  node = statement.expression;
   Expect.isNotNull(node.asSend());
   Expect.isTrue(node.asSend().isConditional);
 
-  node = parseStatement("a?.m();").expression;
+  statement = parseStatement("a?.m();");
+  node = statement.expression;
   Expect.isNotNull(node.asSend());
   Expect.isTrue(node.asSend().isConditional);
 }
diff --git a/tests/compiler/dart2js/part_of_test.dart b/tests/compiler/dart2js/part_of_test.dart
index 979d9ca..3a134dc 100644
--- a/tests/compiler/dart2js/part_of_test.dart
+++ b/tests/compiler/dart2js/part_of_test.dart
@@ -27,13 +27,14 @@
   compiler.registerSource(partUri, PART_SOURCE);
 
   asyncTest(() => compiler.libraryLoader.loadLibrary(libraryUri).then((_) {
-    print('errors: ${compiler.errors}');
-    print('warnings: ${compiler.warnings}');
-    Expect.isTrue(compiler.errors.isEmpty);
-    Expect.equals(1, compiler.warnings.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    print('errors: ${collector.errors}');
+    print('warnings: ${collector.warnings}');
+    Expect.isTrue(collector.errors.isEmpty);
+    Expect.equals(1, collector.warnings.length);
     Expect.equals(MessageKind.LIBRARY_NAME_MISMATCH,
-                  compiler.warnings[0].message.kind);
+        collector.warnings.first.messageKind);
     Expect.equals('foo',
-        compiler.warnings[0].message.arguments['libraryName'].toString());
+        collector.warnings.first.message.arguments['libraryName'].toString());
   }));
 }
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 660a803..9f20998 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -37,7 +37,7 @@
   compiler.registerSource(uri, "$DEFAULT_PATCH_CORE_SOURCE\n$patch");
   var future;
   if (runCompiler) {
-    future = compiler.runCompiler(null, main);
+    future = compiler.run(null, main);
   } else {
     future = compiler.init(main);
   }
@@ -135,10 +135,11 @@
   ensure(compiler, "test", compiler.coreLibrary.patch.find,
          expectIsPatch: true, checkHasBody: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testPatchFunctionMetadata() async {
@@ -148,18 +149,19 @@
       @a external test();
       """,
       """
-      const b = 1;
-      @patch @b test() {}
+      const _b = 1;
+      @patch @_b test() {}
       """);
   Element origin = ensure(compiler, "test", compiler.coreLibrary.find,
          expectIsPatched: true, checkHasBody: true);
   Element patch = ensure(compiler, "test", compiler.coreLibrary.patch.find,
          expectIsPatch: true, checkHasBody: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 
   Expect.equals(1, origin.metadata.length,
                 "Unexpected origin metadata: ${origin.metadata}.");
@@ -206,14 +208,15 @@
         compiler.analyzeElement(origin);
         compiler.enqueuer.resolution.emptyDeferredTaskQueue();
 
-        Expect.isTrue(compiler.warnings.isEmpty,
-                      "Unexpected warnings: ${compiler.warnings}");
+        DiagnosticCollector collector = compiler.diagnosticCollector;
+        Expect.isTrue(collector.warnings.isEmpty,
+                      "Unexpected warnings: ${collector.warnings}");
         if (expectedError != null) {
           Expect.equals(expectedError,
-                        compiler.errors[0].message.toString());
+                        collector.errors.first.message.toString());
         } else {
-          Expect.isTrue(compiler.errors.isEmpty,
-                        "Unexpected errors: ${compiler.errors}");
+          Expect.isTrue(collector.errors.isEmpty,
+                        "Unexpected errors: ${collector.errors}");
         }
       }).catchError((error) {
         if (expectedInternalError != null) {
@@ -265,10 +268,11 @@
   Expect.equals(constructorPatch, constructorOrigin.patch);
   Expect.equals(constructorOrigin, constructorPatch.origin);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testPatchRedirectingConstructor() async {
@@ -311,10 +315,11 @@
 
   compiler.resolver.resolve(constructorRedirecting);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testPatchMember() async {
@@ -340,10 +345,11 @@
   ensure(compiler, "toString", container.patch.lookupLocalMember,
          expectIsPatch: true, checkHasBody: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testPatchGetter() async {
@@ -374,10 +380,11 @@
          expectIsPatch: true,
          checkHasBody: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
 Future testRegularMember() async {
@@ -402,13 +409,14 @@
   ensure(compiler, "regular", container.patch.lookupLocalMember,
          checkHasBody: true, expectIsRegular: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
-Future testGhostMember() async {
+Future testInjectedMember() async {
   var compiler = await applyPatch(
       """
       class Class {
@@ -416,7 +424,7 @@
       """,
       """
       @patch class Class {
-        void ghost() {}
+        void _injected() {}
       }
       """);
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
@@ -425,18 +433,51 @@
   ensure(compiler, "Class", compiler.coreLibrary.patch.find,
          expectIsPatch: true);
 
-  ensure(compiler, "ghost", container.lookupLocalMember,
+  ensure(compiler, "_injected", container.lookupLocalMember,
          expectIsFound: false);
-  ensure(compiler, "ghost", container.patch.lookupLocalMember,
+  ensure(compiler, "_injected", container.patch.lookupLocalMember,
          checkHasBody: true, expectIsRegular: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
 }
 
-Future testInjectFunction() async {
+Future testInjectedPublicMember() async {
+  var compiler = await applyPatch(
+      """
+      class Class {
+      }
+      """,
+      """
+      @patch class Class {
+        void injected() {}
+      }
+      """);
+  var container = ensure(compiler, "Class", compiler.coreLibrary.find,
+                         expectIsPatched: true);
+  container.parseNode(compiler.parsing);
+  ensure(compiler, "Class", compiler.coreLibrary.patch.find,
+         expectIsPatch: true);
+
+  ensure(compiler, "injected", container.lookupLocalMember,
+         expectIsFound: false);
+  ensure(compiler, "injected", container.patch.lookupLocalMember,
+         checkHasBody: true, expectIsRegular: true);
+
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.equals(1, collector.errors.length,
+                "Unexpected errors: ${collector.errors}");
+  Expect.isTrue(
+      collector.errors.first.message.kind ==
+          MessageKind.INJECTED_PUBLIC_MEMBER);
+}
+
+Future testInjectedFunction() async {
   var compiler = await applyPatch(
       "",
       "int _function() => 5;");
@@ -449,10 +490,34 @@
          compiler.coreLibrary.patch.find,
          checkHasBody: true, expectIsRegular: true);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  Expect.isTrue(compiler.errors.isEmpty,
-                "Unexpected errors: ${compiler.errors}");
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.isTrue(collector.errors.isEmpty,
+                "Unexpected errors: ${collector.errors}");
+}
+
+Future testInjectedPublicFunction() async {
+  var compiler = await applyPatch(
+      "",
+      "int function() => 5;");
+  ensure(compiler,
+         "function",
+         compiler.coreLibrary.find,
+         expectIsFound: false);
+  ensure(compiler,
+         "function",
+         compiler.coreLibrary.patch.find,
+         checkHasBody: true, expectIsRegular: true);
+
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  Expect.equals(1, collector.errors.length,
+                "Unexpected errors: ${collector.errors}");
+  Expect.isTrue(
+      collector.errors.first.message.kind ==
+          MessageKind.INJECTED_PUBLIC_MEMBER);
 }
 
 Future testPatchSignatureCheck() async {
@@ -491,22 +556,23 @@
                          expectIsPatched: true);
   container.ensureResolved(compiler.resolution);
   container.parseNode(compiler.parsing);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
 
   void expect(String methodName, List infos, List errors) {
-    compiler.clearMessages();
+    collector.clear();
     compiler.resolver.resolveMethodElement(
         ensure(compiler, methodName, container.lookupLocalMember,
             expectIsPatched: true, checkHasBody: true));
-    Expect.equals(0, compiler.warnings.length);
-    Expect.equals(infos.length, compiler.infos.length,
-                  "Unexpected infos: ${compiler.infos} on $methodName");
+    Expect.equals(0, collector.warnings.length);
+    Expect.equals(infos.length, collector.infos.length,
+                  "Unexpected infos: ${collector.infos} on $methodName");
     for (int i = 0 ; i < infos.length ; i++) {
-      Expect.equals(infos[i], compiler.infos[i].message.kind);
+      Expect.equals(infos[i], collector.infos.elementAt(i).message.kind);
     }
-    Expect.equals(errors.length, compiler.errors.length,
-                  "Unexpected errors: ${compiler.errors} on $methodName");
+    Expect.equals(errors.length, collector.errors.length,
+                  "Unexpected errors: ${collector.errors} on $methodName");
     for (int i = 0 ; i < errors.length ; i++) {
-      Expect.equals(errors[i], compiler.errors[i].message.kind);
+      Expect.equals(errors[i], collector.errors.elementAt(i).message.kind);
     }
   }
 
@@ -543,15 +609,16 @@
       """);
   var function = ensure(compiler, "foo", compiler.coreLibrary.find);
   compiler.resolver.resolve(function);
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testExternalWithoutImplementationTopLevel:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testExternalWithoutImplementationTopLevel:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind ==
+      collector.errors.first.message.kind ==
           MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
   Expect.stringEquals('External method without an implementation.',
-                      compiler.errors[0].message.toString());
+                      collector.errors.first.message.toString());
 }
 
 Future testExternalWithoutImplementationMember() async {
@@ -569,20 +636,19 @@
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                          expectIsPatched: true);
   container.parseNode(compiler.parsing);
-
-  compiler.warnings.clear();
-  compiler.errors.clear();
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  collector.clear();
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "foo", container.lookupLocalMember));
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testExternalWithoutImplementationMember:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testExternalWithoutImplementationMember:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind ==
+      collector.errors.first.message.kind ==
           MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
   Expect.stringEquals('External method without an implementation.',
-                      compiler.errors[0].message.toString());
+                      collector.errors.first.message.toString());
 }
 
 Future testIsSubclass() async {
@@ -609,12 +675,13 @@
       """
       @patch class Class {}
       """);
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testPatchNonExistingTopLevel:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testPatchNonExistingTopLevel:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXISTING);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXISTING);
 }
 
 Future testPatchNonExistingMember() async {
@@ -630,13 +697,14 @@
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                          expectIsPatched: true);
   container.parseNode(compiler.parsing);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testPatchNonExistingMember:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testPatchNonExistingMember:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXISTING);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXISTING);
 }
 
 Future testPatchNonPatchablePatch() async {
@@ -649,12 +717,13 @@
       """);
   ensure(compiler, "foo", compiler.coreLibrary.find);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testPatchNonPatchablePatch:${compiler.errors}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testPatchNonPatchablePatch:${collector.errors}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NONPATCHABLE);
+      collector.errors.first.message.kind == MessageKind.PATCH_NONPATCHABLE);
 }
 
 Future testPatchNonPatchableOrigin() async {
@@ -667,16 +736,18 @@
       """);
   ensure(compiler, "foo", compiler.coreLibrary.find);
 
-  Expect.isTrue(compiler.warnings.isEmpty,
-                "Unexpected warnings: ${compiler.warnings}");
-  print('testPatchNonPatchableOrigin:${compiler.errors}');
-  Expect.equals(2, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  Expect.isTrue(collector.warnings.isEmpty,
+                "Unexpected warnings: ${collector.warnings}");
+  print('testPatchNonPatchableOrigin:${collector.errors}');
+  Expect.equals(2, collector.errors.length);
   Expect.equals(
-      MessageKind.EXTRANEOUS_MODIFIER, compiler.errors[0].message.kind);
+      MessageKind.EXTRANEOUS_MODIFIER, collector.errors.first.message.kind);
   Expect.equals(
       // TODO(ahe): Eventually, this error should be removed as it will be
       // handled by the regular parser.
-      MessageKind.PATCH_NONPATCHABLE, compiler.errors[1].message.kind);
+      MessageKind.PATCH_NONPATCHABLE,
+      collector.errors.elementAt(1).message.kind);
 }
 
 Future testPatchNonExternalTopLevel() async {
@@ -687,14 +758,15 @@
       """
       @patch void foo() {}
       """);
-  print('testPatchNonExternalTopLevel.errors:${compiler.errors}');
-  print('testPatchNonExternalTopLevel.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonExternalTopLevel.errors:${collector.errors}');
+  print('testPatchNonExternalTopLevel.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXTERNAL);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
-  Expect.isTrue(compiler.infos[0].message.kind ==
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXTERNAL);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
+  Expect.isTrue(collector.infos.first.message.kind ==
       MessageKind.PATCH_POINT_TO_FUNCTION);
 }
 
@@ -714,14 +786,15 @@
                          expectIsPatched: true);
   container.parseNode(compiler.parsing);
 
-  print('testPatchNonExternalMember.errors:${compiler.errors}');
-  print('testPatchNonExternalMember.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonExternalMember.errors:${collector.errors}');
+  print('testPatchNonExternalMember.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXTERNAL);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
-  Expect.isTrue(compiler.infos[0].message.kind ==
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXTERNAL);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
+  Expect.isTrue(collector.infos.first.message.kind ==
       MessageKind.PATCH_POINT_TO_FUNCTION);
 }
 
@@ -733,15 +806,16 @@
       """
       @patch class Class {}
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_CLASS);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_CLASS);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_CLASS);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_CLASS);
 }
 
 Future testPatchNonGetter() async {
@@ -752,15 +826,16 @@
       """
       @patch get foo => 0;
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_GETTER);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_GETTER);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_GETTER);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_GETTER);
 }
 
 Future testPatchNoGetter() async {
@@ -771,15 +846,16 @@
       """
       @patch get foo => 0;
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NO_GETTER);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NO_GETTER);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_GETTER);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_GETTER);
 }
 
 Future testPatchNonSetter() async {
@@ -790,15 +866,16 @@
       """
       @patch set foo(var value) {}
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_SETTER);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_SETTER);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_SETTER);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_SETTER);
 }
 
 Future testPatchNoSetter() async {
@@ -809,15 +886,16 @@
       """
       @patch set foo(var value) {}
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NO_SETTER);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NO_SETTER);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_SETTER);
+      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_SETTER);
 }
 
 Future testPatchNonFunction() async {
@@ -828,15 +906,16 @@
       """
       @patch void foo() {}
       """);
-  print('testPatchNonClass.errors:${compiler.errors}');
-  print('testPatchNonClass.warnings:${compiler.warnings}');
-  Expect.equals(1, compiler.errors.length);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  print('testPatchNonClass.errors:${collector.errors}');
+  print('testPatchNonClass.warnings:${collector.warnings}');
+  Expect.equals(1, collector.errors.length);
   Expect.isTrue(
-      compiler.errors[0].message.kind == MessageKind.PATCH_NON_FUNCTION);
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.infos.length);
+      collector.errors.first.message.kind == MessageKind.PATCH_NON_FUNCTION);
+  Expect.equals(0, collector.warnings.length);
+  Expect.equals(1, collector.infos.length);
   Expect.isTrue(
-      compiler.infos[0].message.kind ==
+      collector.infos.first.message.kind ==
           MessageKind.PATCH_POINT_TO_FUNCTION);
 }
 
@@ -863,6 +942,7 @@
       """,
       runCompiler: true, analyzeOnly: true);
   World world = compiler.world;
+  world.populate();
 
   ClassElement cls = ensure(compiler, "A", compiler.coreLibrary.find,
                             expectIsPatched: true);
@@ -915,8 +995,9 @@
     var compiler = await applyPatch('', patchText, analyzeAll: true,
                analyzeOnly: true);
       compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
-    await compiler.runCompiler(null);
-    compareWarningKinds(patchText, expectedWarnings, compiler.warnings);
+    await compiler.run(null);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    compareWarningKinds(patchText, expectedWarnings, collector.warnings);
   }
 
   await expect('String s = 0;', MessageKind.NOT_ASSIGNABLE);
@@ -972,7 +1053,7 @@
 
   ConstructorElement forwardTwo = clsA.lookupConstructor("forwardTwo");
   target = forwardTwo.effectiveTarget;
-  Expect.isFalse(forwardTwo.isErroneous);
+  Expect.isFalse(forwardTwo.isMalformed);
   Expect.isFalse(target.isPatch);
   Expect.equals("originTarget", target.name);
 }
@@ -987,9 +1068,10 @@
   var compiler = await applyPatch(originText, patchText,
              analyzeAll: true, analyzeOnly: true);
   compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
-  await compiler.runCompiler(null);
+  await compiler.run(null);
+  DiagnosticCollector collector = compiler.diagnosticCollector;
   compareWarningKinds(patchText,
-      [MessageKind.NOT_ASSIGNABLE], compiler.warnings);
+      [MessageKind.NOT_ASSIGNABLE], collector.warnings);
 }
 
 main() {
@@ -1001,8 +1083,10 @@
     await testPatchMember();
     await testPatchGetter();
     await testRegularMember();
-    await testGhostMember();
-    await testInjectFunction();
+    await testInjectedMember();
+    await testInjectedPublicMember();
+    await testInjectedFunction();
+    await testInjectedPublicFunction();
     await testPatchSignatureCheck();
 
     await testPatchVersioned();
diff --git a/tests/compiler/dart2js/platform_config_parser_test.dart b/tests/compiler/dart2js/platform_config_parser_test.dart
new file mode 100644
index 0000000..a25e2da
--- /dev/null
+++ b/tests/compiler/dart2js/platform_config_parser_test.dart
@@ -0,0 +1,130 @@
+// 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:compiler/src/platform_configuration.dart";
+import "package:expect/expect.dart";
+
+/// Runs the parser on [input] and compares it with [expectedResult]
+///
+/// A '*' in [input] indicates that the parser will report an error at the
+/// given point (On [input] with the "*" removed).
+test(String input, [Map<String, Map<String, String>> expectedOutput]) {
+  int starIndex = input.indexOf("*");
+  String inputWithoutStar = input.replaceFirst("*", "");
+
+  parse() => parseIni(inputWithoutStar.codeUnits,
+      allowedSections: new Set.from(["AA", "BB"]));
+
+  if (starIndex != -1) {
+    Expect.equals(expectedOutput, null);
+    Expect.throws(parse, (e) {
+      Expect.isTrue(e is FormatException);
+      Expect.equals(starIndex, e.offset);
+      return e is FormatException;
+    });
+  } else {
+    Map<String, Map<String, String>> result = parse();
+    Expect.equals(expectedOutput.length, result.length);
+    expectedOutput.forEach((String name, Map<String, String> properties) {
+      Expect.isTrue(expectedOutput.containsKey(name), "Missing section $name");
+      Expect.mapEquals(expectedOutput[name], properties);
+    });
+  }
+}
+
+main() {
+  // Empty file.
+  test(
+      """
+# Nothing here
+""",
+      {});
+
+  // Text outside section.
+  test("""
+*aaa
+""");
+
+  // Malformed header.
+  test("""
+*[AABC
+name:value
+""");
+
+  // Text after header.
+  test("""
+[AABC]*abcde
+""");
+
+  // Empty section name.
+  test("""
+[*]
+""");
+
+  // Duplicate section name.
+  test("""
+[AA]
+[BB]
+[*AA]
+""");
+
+  // Unrecognized section name.
+  test("""
+[*CC]
+""");
+
+  // Empty property name.
+  test("""
+[AA]
+*:value
+name:value
+""");
+
+  // Ok.
+  test(
+      """
+[AA]
+name:value
+[BB]
+name:value
+name2:value2
+""",
+      {
+    "AA": {"name": "value"},
+    "BB": {"name": "value", "name2": "value2"}
+  });
+
+  // Ok, file not ending in newline.
+  test(
+      """
+[AA]
+name:value""",
+      {
+    "A": {"name": "value"}
+  });
+
+  // Ok, whitespace is trimmed away.
+  test(
+      """
+[ AA ]
+ name\t:  value """,
+      {
+        "A": {"name": "value"}
+      });
+
+  // Duplicate property name.
+  test("""
+[AA]
+a:b
+b:c
+*a:c
+""");
+
+  // No ':' on property line.
+  test("""
+[AA]
+*name1
+name2:value
+""");
+}
diff --git a/tests/compiler/dart2js/platform_consistency_test.dart b/tests/compiler/dart2js/platform_consistency_test.dart
new file mode 100644
index 0000000..e946c16
--- /dev/null
+++ b/tests/compiler/dart2js/platform_consistency_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import "package:compiler/src/platform_configuration.dart";
+import "package:compiler/src/source_file_provider.dart";
+import "package:compiler/compiler_new.dart";
+import "package:expect/expect.dart";
+
+Uri unsupported =  Uri.parse("unsupported:");
+
+main() async {
+  CompilerInput input = new CompilerSourceFileProvider();
+  Map<String, Uri> client = await load(
+      Uri.base.resolve("sdk/lib/dart_client.platform"),
+      input);
+  Map<String, Uri> server = await load(
+      Uri.base.resolve("sdk/lib/dart_server.platform"),
+      input);
+  Map<String, Uri> shared = await load(
+      Uri.base.resolve("sdk/lib/dart_shared.platform"),
+      input);
+  Map<String, Uri> dart2dart = await load(
+      Uri.base.resolve("sdk/lib/dart2dart.platform"),
+      input);
+  Expect.setEquals(new Set.from(shared.keys), new Set.from(client.keys));
+  Expect.setEquals(new Set.from(shared.keys), new Set.from(server.keys));
+  Expect.setEquals(new Set.from(shared.keys), new Set.from(dart2dart.keys));
+
+  for (String libraryName in shared.keys) {
+    test(Map<String, Uri> m) {
+      if (m[libraryName] != unsupported &&
+          shared[libraryName] != unsupported) {
+        Expect.equals(shared[libraryName], m[libraryName]);
+      }
+    }
+    test(client);
+    test(server);
+    test(dart2dart);
+  }
+ }
diff --git a/tests/compiler/dart2js/private_test.dart b/tests/compiler/dart2js/private_test.dart
index ed55d66..fbfba80 100644
--- a/tests/compiler/dart2js/private_test.dart
+++ b/tests/compiler/dart2js/private_test.dart
@@ -71,8 +71,9 @@
                     ''';
     Uri uri = Uri.parse('src:public');
     compiler.registerSource(uri, source);
-    return compiler.runCompiler(uri).then((_) {
-      compareWarningKinds(text, expectedWarnings, compiler.warnings);
+    return compiler.run(uri).then((_) {
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      compareWarningKinds(text, expectedWarnings, collector.warnings);
     });
   };
 }
diff --git a/tests/compiler/dart2js/related_types.dart b/tests/compiler/dart2js/related_types.dart
index d4d26d2..12b60c5 100644
--- a/tests/compiler/dart2js/related_types.dart
+++ b/tests/compiler/dart2js/related_types.dart
@@ -78,6 +78,8 @@
 
   ClassWorld get world => compiler.world;
 
+  CoreClasses get coreClasses => compiler.coreClasses;
+
   CoreTypes get coreTypes => compiler.coreTypes;
 
   DiagnosticReporter get reporter => compiler.reporter;
@@ -167,7 +169,7 @@
 
   /// Returns the supertype of [receiver] that implements `Iterable`, if any.
   InterfaceType findIterableType(DartType receiver) {
-    return findClassType(receiver, compiler.iterableClass);
+    return findClassType(receiver, coreClasses.iterableClass);
   }
 
   /// Returns the element type of the supertype of [receiver] that implements
@@ -179,7 +181,7 @@
 
   /// Returns the supertype of [receiver] that implements `Map`, if any.
   InterfaceType findMapType(DartType receiver) {
-    return findClassType(receiver, compiler.mapClass);
+    return findClassType(receiver, coreClasses.mapClass);
   }
 
   /// Returns the key type of the supertype of [receiver] that implements
@@ -198,7 +200,7 @@
 
   /// Returns the supertype of [receiver] that implements `List`, if any.
   InterfaceType findListType(DartType receiver) {
-    return findClassType(receiver, compiler.listClass);
+    return findClassType(receiver, coreClasses.listClass);
   }
 
   /// Returns the element type of the supertype of [receiver] that implements
diff --git a/tests/compiler/dart2js/related_types_test.dart b/tests/compiler/dart2js/related_types_test.dart
index dfb50b4..63b424a 100644
--- a/tests/compiler/dart2js/related_types_test.dart
+++ b/tests/compiler/dart2js/related_types_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library related_types;
+library related_types.test;
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/resolution_test.dart b/tests/compiler/dart2js/resolution_test.dart
index 639755a..3087ee1 100644
--- a/tests/compiler/dart2js/resolution_test.dart
+++ b/tests/compiler/dart2js/resolution_test.dart
@@ -92,24 +92,24 @@
 }
 """;
 
-void test(String code, void check(Compiler compiler)) {
+void test(String code, void check(CompilerImpl compiler)) {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(code, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     check(compiler);
   }));
 }
 
 void testHasRuntimeType(String code) {
   test(code, (compiler) {
-    var element = compiler.backend.findHelper('createRuntimeType');
+    var element = compiler.backend.helpers.createRuntimeType;
     Expect.isTrue(compiler.enqueuer.resolution.isProcessed(element));
   });
 }
 
 main() {
   test(NO_RUNTIME_TYPE, (compiler) {
-    var element = compiler.backend.findHelper('createRuntimeType');
+    var element = compiler.backend.helpers.createRuntimeType;
     Expect.isFalse(compiler.enqueuer.resolution.isProcessed(element));
   });
 
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index 236b0bd..3396e53 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -132,11 +132,12 @@
 """);
       compiler.resolveStatement("Bar bar;");
       ClassElement classBar = compiler.mainApp.find("Bar");
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.MULTI_INHERITANCE,
-                    compiler.errors[0].message.kind);
-      Expect.equals(0, compiler.crashes.length);
+                    collector.errors.first.message.kind);
+      Expect.equals(0, collector.crashes.length);
     }),
   ]);
 }
@@ -163,7 +164,8 @@
       compiler.parseScript('class Foo<T, U> {}');
       ClassElement foo = compiler.mainApp.find('Foo');
       matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo',
-                         [compiler.intClass, compiler.stringClass]);
+                         [compiler.coreClasses.intClass,
+                          compiler.coreClasses.stringClass]);
       matchResolvedTypes(visitor, 'Foo<Foo, Foo> x;', 'Foo',
                          [foo, foo]);
     }),
@@ -171,19 +173,21 @@
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript('class Foo<T, U> {}');
       compiler.resolveStatement('Foo<notype, int> x;');
-      Expect.equals(1, compiler.warnings.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.warnings.length);
       Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
-                    compiler.warnings[0].message.kind);
-      Expect.equals(0, compiler.errors.length);
+                    collector.warnings.first.message.kind);
+      Expect.equals(0, collector.errors.length);
     }),
 
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript('class Foo<T, U> {}');
       compiler.resolveStatement('var x = new Foo<notype, int>();');
-      Expect.equals(1, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
-                    compiler.warnings[0].message.kind);
+                    collector.warnings.first.message.kind);
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -194,11 +198,14 @@
                            '}');
       ClassElement foo = compiler.mainApp.find('Foo');
       foo.ensureResolved(compiler.resolution);
-      foo.lookupLocalMember('t').computeType(compiler.resolution);
-      foo.lookupLocalMember('foo').computeType(compiler.resolution);
+      MemberElement tMember = foo.lookupLocalMember('t');
+      tMember.computeType(compiler.resolution);
+      MemberElement fooMember = foo.lookupLocalMember('foo');
+      fooMember.computeType(compiler.resolution);
       compiler.resolver.resolve(foo.lookupLocalMember('bar'));
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
     }),
   ]);
 }
@@ -239,15 +246,16 @@
     ClassElement fooElement = compiler.mainApp.find("Foo");
     FunctionElement funElement = fooElement.lookupLocalMember("foo");
     compiler.processQueue(compiler.enqueuer.resolution, funElement);
-    Expect.equals(0, compiler.warnings.length);
-    Expect.equals(1, compiler.errors.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(0, collector.warnings.length);
+    Expect.equals(1, collector.errors.length);
     Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
-                  compiler.errors[0].message.kind);
-    Expect.equals(2, compiler.infos.length);
+                  collector.errors.first.message.kind);
+    Expect.equals(2, collector.infos.length);
     Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
-                  compiler.infos[0].message.kind);
+                  collector.infos.first.message.kind);
     Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
-                  compiler.infos[1].message.kind);
+                  collector.infos.elementAt(1).message.kind);
   });
 }
 
@@ -267,15 +275,17 @@
       visitor.visit(function.body);
       Map mapping = map(visitor);
       List<Element> values = mapping.values.toList();
+      DiagnosticCollector collector = compiler.diagnosticCollector;
       Expect.equals(0, mapping.length);
-      Expect.equals(0, compiler.warnings.length);
+      Expect.equals(0, collector.warnings.length);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.resolveStatement("main() { return this; }");
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("class Foo { static foo() { return this; } }");
@@ -288,10 +298,11 @@
       FunctionExpression function =
           (funElement as FunctionElementX).parseNode(compiler.parsing);
       visitor.visit(function.body);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
   ]);
 }
@@ -312,12 +323,13 @@
 
       () => testLocals([["foo", false], ["foo", false]])
           .then((MockCompiler compiler) {
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.errors.length);
       Expect.equals(
           new Message(
               MessageTemplate.TEMPLATES[MessageKind.DUPLICATE_DEFINITION],
               {'name': 'foo'}, false),
-          compiler.errors[0].message);
+          collector.errors.first.message);
     })], (f) => f());
 }
 
@@ -485,29 +497,26 @@
     Map mapping = compiler.resolveStatement(statement).map;
 
     Expect.equals(1, mapping.length); // Only [bar] has an element.
-    Expect.equals(1, compiler.warnings.length);
-
-    Node warningNode = compiler.warnings[0].node;
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(1, collector.warnings.length);
 
     Expect.equals(
         new Message(
             MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
             {'typeName': 'Foo'}, false),
-        compiler.warnings[0].message);
-    VariableDefinitions definition = compiler.parsedTree;
-    Expect.equals(warningNode, definition.type);
-    compiler.clearMessages();
+        collector.warnings.first.message);
+    collector.clear();
 
     // Test that there is no warning after defining Foo.
     compiler.parseScript("class Foo {}");
     mapping = compiler.resolveStatement(statement).map;
     Expect.equals(1, mapping.length);
-    Expect.equals(0, compiler.warnings.length);
+    Expect.equals(0, collector.warnings.length);
 
     // Test that 'var' does not create a warning.
     mapping = compiler.resolveStatement("var foo;").map;
     Expect.equals(1, mapping.length);
-    Expect.equals(0, compiler.warnings.length);
+    Expect.equals(0, collector.warnings.length);
   });
 }
 
@@ -516,12 +525,13 @@
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("class Foo extends Bar {}");
       compiler.resolveStatement("Foo bar;");
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.errors.length);
       var cannotResolveBar = new Message(
           MessageTemplate.TEMPLATES[MessageKind.CANNOT_EXTEND_MALFORMED],
           {'className': 'Foo', 'malformedType': 'Bar'}, false);
-      Expect.equals(cannotResolveBar, compiler.errors[0].message);
-      compiler.clearMessages();
+      Expect.equals(cannotResolveBar, collector.errors.first.message);
+      collector.clear();
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("class Foo extends Bar {}");
@@ -543,13 +553,14 @@
   return MockCompiler.create((MockCompiler compiler) {
     compiler.parseScript("class Foo extends var {}");
     compiler.resolveStatement("Foo bar;");
-    Expect.equals(1, compiler.errors.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(1, collector.errors.length);
     Expect.equals(
         new Message(
             MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
             {'typeName': 'var'}, false),
-        compiler.errors[0].message);
-    compiler.clearMessages();
+        collector.errors.first.message);
+    collector.clear();
   });
 }
 
@@ -557,13 +568,14 @@
   return MockCompiler.create((MockCompiler compiler) {
     compiler.parseScript("class Foo implements Bar {}");
     compiler.resolveStatement("Foo bar;");
-    Expect.equals(1, compiler.errors.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(1, collector.errors.length);
     Expect.equals(
         new Message(
             MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
             {'typeName': 'bar'}, false),
-        compiler.errors[0].message);
-    compiler.clearMessages();
+        collector.errors.first.message);
+    collector.clear();
 
     // Add the abstract class to the world and make sure everything is setup
     // correctly.
@@ -698,9 +710,10 @@
     Expect.equals(expectedElementCount, map(visitor).length,
         "${map(visitor).values} for '$statement' in context of `$script`");
 
-    compareWarningKinds(script, expectedWarnings, compiler.warnings);
-    compareWarningKinds(script, expectedErrors, compiler.errors);
-    compareWarningKinds(script, expectedInfos, compiler.infos);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    compareWarningKinds(script, expectedWarnings, collector.warnings);
+    compareWarningKinds(script, expectedErrors, collector.errors);
+    compareWarningKinds(script, expectedInfos, collector.infos);
   });
 }
 
@@ -712,10 +725,11 @@
                               main() { return new A(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("""class A extends B {}
@@ -723,12 +737,13 @@
                               main() { return new A(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(2, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(2, collector.errors.length);
       Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
-                    compiler.errors[0].message.kind);
-      Expect.equals(MessageKind.CANNOT_FIND_CONSTRUCTOR,
-                    compiler.errors[1].message.kind);
+                    collector.errors.first.message.kind);
+      Expect.equals(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR,
+                    collector.errors.elementAt(1).message.kind);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("""abstract class A extends B {}
@@ -737,10 +752,11 @@
                               main() { return new C(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
     MockCompiler.create((MockCompiler compiler) {
       compiler.parseScript("""class A extends B {}
@@ -749,8 +765,9 @@
                               main() { return new A(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       ClassElement aElement = compiler.mainApp.find("A");
       Link<DartType> supertypes = aElement.allSupertypes;
       Expect.equals(<String>['B', 'C', 'Object'].toString(),
@@ -765,8 +782,9 @@
                               main() { return new C(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       ClassElement aElement = compiler.mainApp.find("C");
       Link<DartType> supertypes = aElement.allSupertypes;
       // Object is once per inheritance path, that is from both A and I.
@@ -781,8 +799,9 @@
                               main() { return new E(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       ClassElement aElement = compiler.mainApp.find("E");
       Link<DartType> supertypes = aElement.allSupertypes;
       Expect.equals(<String>['A<E>', 'D', 'Object'].toString(),
@@ -794,11 +813,12 @@
                               main() { return new D(); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(1, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(1, collector.errors.length);
       Expect.equals(MessageKind.MULTI_INHERITANCE,
-                    compiler.errors[0].message.kind);
-      Expect.equals(0, compiler.crashes.length);
+                    collector.errors.first.message.kind);
+      Expect.equals(0, collector.crashes.length);
     }),
   ]);
 }
@@ -811,10 +831,11 @@
                               main() { Enum e; }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(1, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(1, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -822,10 +843,11 @@
                               main() { Enum e = Enum.A; }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(0, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(0, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -833,12 +855,13 @@
                               main() { Enum e = Enum.B; }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(1, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(1, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
       Expect.equals(MessageKind.MEMBER_NOT_FOUND,
-                    compiler.warnings[0].message.kind);
-      Expect.equals(0, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+                    collector.warnings.first.message.kind);
+      Expect.equals(0, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -846,10 +869,11 @@
                               main() { List values = Enum.values; }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(0, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(0, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -857,12 +881,13 @@
                               main() { new Enum(0, ''); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(1, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(1, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
       Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
 
     MockCompiler.create((MockCompiler compiler) {
@@ -870,12 +895,13 @@
                               main() { const Enum(0, ''); }""");
       FunctionElement mainElement = compiler.mainApp.find(MAIN);
       compiler.resolver.resolve(mainElement);
-      Expect.equals(0, compiler.warnings.length,
-                    'Unexpected warnings: ${compiler.warnings}');
-      Expect.equals(1, compiler.errors.length,
-                    'Unexpected errors: ${compiler.errors}');
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length,
+                    'Unexpected warnings: ${collector.warnings}');
+      Expect.equals(1, collector.errors.length,
+                    'Unexpected errors: ${collector.errors}');
       Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM,
-                    compiler.errors[0].message.kind);
+                    collector.errors.first.message.kind);
     }),
   ]);
 }
@@ -1038,8 +1064,9 @@
       CollectingTreeElements elements =
           compiler.resolveStatement("main() => $constant;");
       List<String> expectedConstants = testedConstants[constant];
-      Expect.equals(0, compiler.warnings.length);
-      Expect.equals(0, compiler.errors.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.warnings.length);
+      Expect.equals(0, collector.errors.length);
       List<ConstantExpression> constants = elements.constants;
       String constantsText =
           '[${constants.map((c) => c.getText()).join(', ')}]';
@@ -1073,7 +1100,7 @@
   Uri uri = new Uri(scheme: 'source');
   MockCompiler compiler = compilerFor(source, uri);
   compiler.diagnosticHandler = createHandler(compiler, source);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     return compiler;
   });
 }
@@ -1147,25 +1174,27 @@
         new A() == new B();
       }""";
   asyncTest(() => compileScript(script).then((compiler) {
-    Expect.equals(0, compiler.warnings.length);
-    Expect.equals(0, compiler.infos.length);
-    Expect.equals(1, compiler.hints.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(0, collector.warnings.length);
+    Expect.equals(0, collector.infos.length);
+    Expect.equals(1, collector.hints.length);
     Expect.equals(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
-                  compiler.hints[0].message.kind);
-    Expect.equals(0, compiler.errors.length);
+                  collector.hints.first.message.kind);
+    Expect.equals(0, collector.errors.length);
   }));
 }
 
 testConstConstructorAndNonFinalFields() {
   void expect(compiler, List errors, List infos) {
-    Expect.equals(errors.length, compiler.errors.length);
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(errors.length, collector.errors.length);
     for (int i = 0 ; i < errors.length ; i++) {
-      Expect.equals(errors[i], compiler.errors[i].message.kind);
+      Expect.equals(errors[i], collector.errors.elementAt(i).message.kind);
     }
-    Expect.equals(0, compiler.warnings.length);
-    Expect.equals(infos.length, compiler.infos.length);
+    Expect.equals(0, collector.warnings.length);
+    Expect.equals(infos.length, collector.infos.length);
     for (int i = 0 ; i < infos.length ; i++) {
-      Expect.equals(infos[i], compiler.infos[i].message.kind);
+      Expect.equals(infos[i], collector.infos.elementAt(i).message.kind);
     }
   }
 
@@ -1369,13 +1398,14 @@
 checkWarningOn(String script, List<MessageKind> warnings) {
   Expect.isTrue(warnings.length >= 0 && warnings.length <= 2);
   asyncTest(() => compileScript(script).then((compiler) {
-    Expect.equals(0, compiler.errors.length,
-        'Unexpected errors in\n$script\n${compiler.errors}');
-    Expect.equals(warnings.length, compiler.warnings.length,
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    Expect.equals(0, collector.errors.length,
+        'Unexpected errors in\n$script\n${collector.errors}');
+    Expect.equals(warnings.length, collector.warnings.length,
         'Unexpected warnings in\n$script\n'
-        'Expected:$warnings\nFound:${compiler.warnings}');
+        'Expected:$warnings\nFound:${collector.warnings}');
     for (int i = 0; i < warnings.length; i++) {
-      Expect.equals(warnings[i], compiler.warnings[i].message.kind);
+      Expect.equals(warnings[i], collector.warnings.elementAt(i).message.kind);
     }
   }));
 }
@@ -1388,11 +1418,12 @@
     var where = functionName == null
         ? 'the enclosing function' : "'$functionName'";
     asyncTest(() => compileScript(script).then((compiler) {
-      Expect.equals(0, compiler.errors.length);
-      Expect.equals(1, compiler.warnings.length);
+      DiagnosticCollector collector = compiler.diagnosticCollector;
+      Expect.equals(0, collector.errors.length);
+      Expect.equals(1, collector.warnings.length);
       Expect.equals("$prefix.\n"
           "Did you mean to add the 'async' marker to $where?",
-          '${compiler.warnings[0].message}');
+          '${collector.warnings.first.message}');
     }));
   }
   check('main() { await -3; }', functionName: 'main');
diff --git a/tests/compiler/dart2js/semantic_visitor_test.dart b/tests/compiler/dart2js/semantic_visitor_test.dart
index f8ea57f..72f93e1 100644
--- a/tests/compiler/dart2js/semantic_visitor_test.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test.dart
@@ -313,14 +313,14 @@
     }
     var expectedVisits = test.expectedVisits;
     if (expectedVisits == null) {
-      Expect.isTrue(element.isErroneous,
+      Expect.isTrue(element.isMalformed,
           "Element '$method' expected to be have parse errors in:\n"
           "${library.compilationUnit.script.text}");
       return;
     } else if (expectedVisits is! List) {
       expectedVisits = [expectedVisits];
     }
-    Expect.isFalse(element.isErroneous,
+    Expect.isFalse(element.isMalformed,
         "Element '$method' is not expected to be have parse errors in:\n"
         "${library.compilationUnit.script.text}");
 
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
index f31b688..1019d8c 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
@@ -536,7 +536,7 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
               body: '=>null;'),
           const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
@@ -556,7 +556,7 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
               target: 'generative_constructor(C#_)',
               type: 'C'),
@@ -579,7 +579,7 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
               target: 'generative_constructor(D#)',
               type: 'D'),
@@ -602,7 +602,7 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
               target: 'generative_constructor(D#)',
               type: 'D<int>'),
@@ -628,9 +628,9 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
-              element: 'function(C#)',
+              element: 'factory_constructor(C#)',
               parameters: '(a,b)',
-              target: 'function(D#)',
+              target: 'factory_constructor(D#)',
               type: 'D<int>'),
           const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
               element: 'parameter(#a)',
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
index c407766..a0fd164 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
@@ -803,6 +803,13 @@
         const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
                     element: 'field(o)',
                     rhs: '42')),
+    const Test.prefix(
+        '''
+        ''',
+        'm() { p = 42; }',
+        const Visit(VisitKind.ERROR_INVALID_SET,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    rhs: '42')),
     const Test(
         '''
         final o = 0;
@@ -851,6 +858,13 @@
         const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
                     element: 'field(o)',
                     arguments: '(null,42)')),
+    const Test.prefix(
+        '''
+        ''',
+        'm() { p(null, 42); }',
+        const Visit(VisitKind.ERROR_INVALID_INVOKE,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    arguments: '(null,42)')),
     const Test(
         '''
         m() => o;
@@ -2414,6 +2428,16 @@
                     error: MessageKind.NO_INSTANCE_AVAILABLE,
                     operator: '+=',
                     rhs: '42')),
+    const Test.prefix(
+        '''
+        ''',
+        '''
+        m() { p += 42; }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_COMPOUND,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    operator: '+=',
+                    rhs: '42')),
     const Test(
         '''
         class C {
@@ -2933,6 +2957,15 @@
         const Visit(VisitKind.ERROR_INVALID_PREFIX,
                     error: MessageKind.NO_INSTANCE_AVAILABLE,
                     operator: '++')),
+    const Test.prefix(
+        '''
+        ''',
+        '''
+        m() { ++p; }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_PREFIX,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    operator: '++')),
     const Test(
         '''
         class C {
@@ -3318,6 +3351,15 @@
         const Visit(VisitKind.ERROR_INVALID_POSTFIX,
                     error: MessageKind.NO_INSTANCE_AVAILABLE,
                     operator: '--')),
+    const Test.prefix(
+        '''
+        ''',
+        '''
+        m() { p--; }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_POSTFIX,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    operator: '--')),
     const Test(
         '''
         class C {
@@ -3715,7 +3757,7 @@
         m() => new Class(true, 42);
         ''',
         const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3728,7 +3770,7 @@
         m() => new Class(true, 42);
         ''',
         const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3742,7 +3784,7 @@
         m() => new Class<double>(true, 42);
         ''',
         const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class<double>',
             target: 'generative_constructor(Class#b)',
@@ -3758,7 +3800,7 @@
         m() => new Class<double>(true, 42);
         ''',
         const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class<double>',
             target: 'generative_constructor(Class#b)',
@@ -3774,7 +3816,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3789,7 +3831,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class<double>',
             selector: 'CallStructure(arity=2)')),
@@ -3830,7 +3872,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3843,7 +3885,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3857,7 +3899,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -3873,7 +3915,7 @@
         ''',
         const Visit(
             VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-            element: 'function(Class#)',
+            element: 'factory_constructor(Class#)',
             arguments: '(true,42)',
             type: 'Class',
             selector: 'CallStructure(arity=2)')),
@@ -4122,6 +4164,15 @@
         const Visit(VisitKind.ERROR_INVALID_SET_IF_NULL,
                     error: MessageKind.NO_INSTANCE_AVAILABLE,
                     rhs: '42')),
+    const Test.prefix(
+        '''
+        ''',
+        '''
+        m() { p ??= 42; }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_SET_IF_NULL,
+                    error: MessageKind.PREFIX_AS_EXPRESSION,
+                    rhs: '42')),
     const Test(
         '''
         class C {
diff --git a/tests/compiler/dart2js/serialization_analysis_test.dart b/tests/compiler/dart2js/serialization_analysis_test.dart
index 445ea45..ffef134 100644
--- a/tests/compiler/dart2js/serialization_analysis_test.dart
+++ b/tests/compiler/dart2js/serialization_analysis_test.dart
@@ -10,11 +10,11 @@
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/enqueue.dart';
 import 'package:compiler/src/filenames.dart';
 import 'package:compiler/src/serialization/serialization.dart';
 import 'package:compiler/src/serialization/json_serializer.dart';
 import 'package:compiler/src/serialization/task.dart';
+import 'package:compiler/src/universe/world_impact.dart';
 import 'memory_compiler.dart';
 
 const List<Test> TESTS = const <Test>[
@@ -204,7 +204,7 @@
 Future<String> serializeDartCore() async {
   Compiler compiler = compilerFor(
       options: ['--analyze-all', '--output-type=dart']);
-  await compiler.runCompiler(Uri.parse('dart:core'));
+  await compiler.run(Uri.parse('dart:core'));
   return serialize(compiler.libraryLoader.libraries);
 }
 
diff --git a/tests/compiler/dart2js/show_package_warnings_test.dart b/tests/compiler/dart2js/show_package_warnings_test.dart
index e94983c..cc05018 100644
--- a/tests/compiler/dart2js/show_package_warnings_test.dart
+++ b/tests/compiler/dart2js/show_package_warnings_test.dart
@@ -20,47 +20,81 @@
 
 const SOURCE = const {
   'main.dart': """
-import 'package:pkg_error1/pkg_error1.dart';
-import 'package:pkg_error2/pkg_error2.dart';
-import 'package:pkg_noerror/pkg_noerror.dart';
-import 'error.dart';
+import 'package:pkg_error1/pkg_error1.dart' as pkg1;
+import 'package:pkg_error2/pkg_error2.dart' as pkg2;
+import 'package:pkg_noerror/pkg_noerror.dart' as pkg3;
+import 'error.dart' as error;
+
+main() {
+  pkg1.m(null);
+  pkg2.m(null);
+  pkg3.m(null);
+  error.m(null);
+}
 """,
 
   'error.dart': ERROR_CODE,
 
   'pkg/pkg_error1/pkg_error1.dart': """
-import 'package:pkg_error2/pkg_error2.dart';
-import 'package:pkg_noerror/pkg_noerror.dart';
-$ERROR_CODE""",
+import 'package:pkg_error2/pkg_error2.dart' as pkg2;
+import 'package:pkg_noerror/pkg_noerror.dart' as pkg3;
+$ERROR_CODE
+
+main() {
+  m(null);
+  pkg2.m(null);
+  pkg3.m(null);
+}
+""",
 
   'pkg/pkg_error2/pkg_error2.dart': """
-import 'package:pkg_error1/pkg_error1.dart';
-import 'package:pkg_noerror/pkg_noerror.dart';
-$ERROR_CODE""",
+import 'package:pkg_error1/pkg_error1.dart' as pkg1;
+import 'package:pkg_noerror/pkg_noerror.dart' as pkg3;
+$ERROR_CODE
+
+main() {
+  pkg1.m(null);
+  m(null);
+  pkg3.m(null);
+}
+""",
 
   'pkg/pkg_noerror/pkg_noerror.dart': """
-import 'package:pkg_error1/pkg_error1.dart';
-import 'package:pkg_error2/pkg_error2.dart';
+import 'package:pkg_error1/pkg_error1.dart' as pkg1;
+import 'package:pkg_error2/pkg_error2.dart' as pkg2;
+m(o) {}
+
+main() {
+  pkg1.m(null);
+  m(null);
+  pkg2.m(null);
+}
 """};
 
 Future test(Uri entryPoint,
-            {bool showPackageWarnings: false,
+            {List<String> showPackageWarnings: null,
              int warnings: 0,
              int hints: 0,
              int infos: 0}) async {
-  var options = [Flags.analyzeOnly, Flags.analyzeAll];
-  if (showPackageWarnings) {
-    options.add(Flags.showPackageWarnings);
+  var options = [Flags.analyzeOnly];
+  if (showPackageWarnings != null) {
+    if (showPackageWarnings.isEmpty) {
+      options.add(Flags.showPackageWarnings);
+    } else {
+      options.add(
+          '${Flags.showPackageWarnings}=${showPackageWarnings.join(',')}');
+    }
   }
   var collector = new DiagnosticCollector();
+  print('==================================================================');
+  print('test: $entryPoint showPackageWarnings=$showPackageWarnings');
+  print('------------------------------------------------------------------');
   await runCompiler(
       entryPoint: entryPoint,
       memorySourceFiles: SOURCE,
       options: options,
       packageRoot: Uri.parse('memory:pkg/'),
       diagnosticHandler: collector);
-  print('==================================================================');
-  print('test: $entryPoint showPackageWarnings=$showPackageWarnings');
   Expect.equals(0, collector.errors.length,
                 'Unexpected errors: ${collector.errors}');
   Expect.equals(warnings, collector.warnings.length,
@@ -72,11 +106,10 @@
   Expect.equals(infos, collector.infos.length,
                 'Unexpected infos: ${collector.infos}');
   checkUriSchemes(collector.infos);
-  print('==================================================================');
 }
 
-void checkUriSchemes(Iterable<DiagnosticMessage> messages) {
-  for (DiagnosticMessage message in messages) {
+void checkUriSchemes(Iterable<CollectedMessage> messages) {
+  for (CollectedMessage message in messages) {
     if (message.uri != null) {
       Expect.notEquals('package', message.uri.scheme,
           "Unexpected package uri `${message.uri}` in message: $message");
@@ -88,32 +121,52 @@
   asyncTest(() async {
     await test(
         Uri.parse('memory:main.dart'),
-        showPackageWarnings: true,
+        showPackageWarnings: [],
         // From error.dart, package:pkg_error1 and package:pkg_error2:
         warnings: 3, hints: 3, infos: 3);
     await test(
         Uri.parse('memory:main.dart'),
-        showPackageWarnings: false,
+        showPackageWarnings: ['pkg_error1'],
+        // From error.dart and package:pkg_error1:
+        warnings: 2, hints: 2 + 1 /* from summary */, infos: 2);
+    await test(
+        Uri.parse('memory:main.dart'),
+        showPackageWarnings: ['pkg_error1', 'pkg_error2'],
+        // From error.dart, package:pkg_error1 and package:pkg_error2:
+        warnings: 3, hints: 3, infos: 3);
+    await test(
+        Uri.parse('memory:main.dart'),
+        showPackageWarnings: [],
+        // From error.dart, package:pkg_error1 and package:pkg_error2:
+        warnings: 3, hints: 3, infos: 3);
+    await test(
+        Uri.parse('memory:main.dart'),
+        showPackageWarnings: null,
         // From error.dart only:
         warnings: 1, hints: 1 + 2 /* from summary */, infos: 1);
     await test(
         Uri.parse('package:pkg_error1/pkg_error1.dart'),
-        showPackageWarnings: true,
+        showPackageWarnings: [],
         // From package:pkg_error1 and package:pkg_error2:
         warnings: 2, hints: 2, infos: 2);
     await test(
         Uri.parse('package:pkg_error1/pkg_error1.dart'),
-        showPackageWarnings: false,
+        showPackageWarnings: null,
         // From package:pkg_error1/pkg_error1.dart only:
         warnings: 1, hints: 1 + 1 /* from summary */, infos: 1);
     await test(
         Uri.parse('package:pkg_noerror/pkg_noerror.dart'),
-        showPackageWarnings: true,
+        showPackageWarnings: [],
         // From package:pkg_error1 and package:pkg_error2:
         warnings: 2, hints: 2, infos: 2);
     await test(
         Uri.parse('package:pkg_noerror/pkg_noerror.dart'),
-        showPackageWarnings: false,
+        showPackageWarnings: ['pkg_error1'],
+        // From package:pkg_error1:
+        warnings: 1, hints: 1 + 1 /* from summary */, infos: 1);
+    await test(
+        Uri.parse('package:pkg_noerror/pkg_noerror.dart'),
+        showPackageWarnings: null,
         hints: 2 /* from summary */);
   });
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
index dea4f69..306392c 100644
--- a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
@@ -96,7 +96,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_callers_test.dart b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
index 4f2e5a8..2242d55 100644
--- a/tests/compiler/dart2js/simple_inferrer_callers_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
@@ -38,7 +38,7 @@
   var compiler = compilerFor(TEST, uri);
   var inferrer = new MyInferrer(compiler);
   compiler.typesTask.typesInferrer = inferrer;
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var mainElement = findElement(compiler, 'main');
     var classA = findElement(compiler, 'A');
     var fieldA = classA.lookupLocalMember('field');
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index c9776f1..9eaefa2 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -118,7 +118,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
index d8bdeb3..c12eff3 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
@@ -28,7 +28,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
index 8e1ef62..225d204 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
@@ -28,7 +28,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
index 9a2fb7c..b52e17a 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
@@ -29,7 +29,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
index 50d6f2a..9b550e5 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
@@ -29,7 +29,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
index b5bc4e6..f83a4d9 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
@@ -44,7 +44,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
index 7b7be1a..3f3056c 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
@@ -37,7 +37,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
index 36019136..8147f14 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
@@ -27,7 +27,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkFieldTypeInClass(String className, String fieldName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
index e010677..ffb277d 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
@@ -26,7 +26,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkFieldTypeInClass(String className, String fieldName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
index 7e5853c..1b74240 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
@@ -30,7 +30,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkFieldTypeInClass(String className, String fieldName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart b/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
index 2d673f1..07156f81 100644
--- a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
@@ -28,7 +28,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkArgument(String functionName, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
index fcfa00c9..bfae05a 100644
--- a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
@@ -37,7 +37,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturn(String name, type) {
diff --git a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
index f3e44d4..3dc9993 100644
--- a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
@@ -173,7 +173,7 @@
   }
 
   var compiler1 = compilerFor(TEST1, uri);
-  asyncTest(() => compiler1.runCompiler(uri).then((_) {
+  asyncTest(() => compiler1.run(uri).then((_) {
     checkReturn(compiler1, 'test1', compiler1.typesTask.uint31Type);
     checkReturn(compiler1, 'test2',
         compiler1.typesTask.dynamicType.nonNullable());
@@ -186,7 +186,7 @@
   }));
 
   var compiler2 = compilerFor(TEST2, uri);
-  asyncTest(() => compiler2.runCompiler(uri).then((_) {
+  asyncTest(() => compiler2.run(uri).then((_) {
     checkReturn(compiler2, 'test1', compiler2.typesTask.mapType.nonNullable());
     checkReturn(compiler2, 'test2', compiler2.typesTask.mapType);
     checkReturn(compiler2, 'test3', compiler2.typesTask.mapType);
@@ -202,7 +202,7 @@
   }));
 
   var compiler3 = compilerFor(TEST3, uri);
-  asyncTest(() => compiler3.runCompiler(uri).then((_) {
+  asyncTest(() => compiler3.run(uri).then((_) {
     checkReturn(compiler3, 'test1', const TypeMask.nonNullEmpty());
     checkReturn(compiler3, 'test2', compiler3.typesTask.mapType);
     checkReturn(compiler3, 'test3', compiler3.typesTask.mapType);
@@ -212,7 +212,7 @@
   }));
 
   var compiler4 = compilerFor(TEST4, uri);
-  asyncTest(() => compiler4.runCompiler(uri).then((_) {
+  asyncTest(() => compiler4.run(uri).then((_) {
     checkReturn(compiler4, 'test1', const TypeMask.nonNullEmpty());
     checkReturn(compiler4, 'test2', compiler4.typesTask.mapType);
     checkReturn(compiler4, 'test3', compiler4.typesTask.mapType);
diff --git a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
index c26104d..f55f609 100644
--- a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
@@ -65,7 +65,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index 1bc1cf5..d552ccd 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -726,7 +726,7 @@
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
   compiler.diagnosticHandler = createHandler(compiler, TEST);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var world = compiler.world;
@@ -757,8 +757,8 @@
     checkReturn('returnInt8', typesTask.positiveIntType);
     checkReturn('returnEmpty1', const TypeMask.nonNullEmpty());
     checkReturn('returnEmpty2', const TypeMask.nonNullEmpty());
-    TypeMask intType = new TypeMask.nonNullSubtype(compiler.intClass,
-        compiler.world);
+    TypeMask intType = new TypeMask.nonNullSubtype(
+        compiler.coreClasses.intClass, compiler.world);
     checkReturn('testIsCheck1', intType);
     checkReturn('testIsCheck2', intType);
     checkReturn('testIsCheck3', intType.nullable());
@@ -778,7 +778,7 @@
     checkReturn('testIsCheck17', intType);
     checkReturn('testIsCheck18', typesTask.dynamicType);
     checkReturn('testIsCheck19', typesTask.dynamicType);
-    checkReturn('testIsCheck20', typesTask.dynamicType.nonNullable());
+    checkReturn('testIsCheck20', interceptorType);
     checkReturn('testIsCheck21', typesTask.dynamicType);
     checkReturn('testIsCheck22', typesTask.dynamicType);
     checkReturn('testIsCheck23', intType);
@@ -790,8 +790,8 @@
     checkReturn('testIsCheck29', typesTask.dynamicType);
     checkReturn('testIf1', typesTask.uint31Type.nullable());
     checkReturn('testIf2', typesTask.uint31Type.nullable());
-    checkReturn('returnAsString',
-        new TypeMask.subtype(compiler.stringClass, compiler.world));
+    checkReturn('returnAsString', new TypeMask.subtype(
+        compiler.coreClasses.stringClass, compiler.world));
     checkReturn('returnIntAsNum', typesTask.uint31Type);
     checkReturn('returnAsTypedef', typesTask.functionType.nullable());
     checkReturn('returnTopLevelGetter', typesTask.uint31Type);
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index 19053d8..82ec5ed 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -168,7 +168,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
 
@@ -183,8 +183,8 @@
     checkReturn('returnInt3', typesTask.uint31Type);
     checkReturn('returnInt4', typesTask.uint31Type);
     checkReturn('returnInt5', typesTask.uint31Type);
-    checkReturn('returnInt6',
-        new TypeMask.nonNullSubtype(compiler.intClass, compiler.world));
+    checkReturn('returnInt6', new TypeMask.nonNullSubtype(
+        compiler.coreClasses.intClass, compiler.world));
 
     var subclassOfInterceptor =
         findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
diff --git a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
index 06bba80..6cf04020 100644
--- a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
@@ -32,7 +32,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     checkReturnInClass(String className, String methodName, type) {
diff --git a/tests/compiler/dart2js/size_test.dart b/tests/compiler/dart2js/size_test.dart
index c7604f7..48bf71b 100644
--- a/tests/compiler/dart2js/size_test.dart
+++ b/tests/compiler/dart2js/size_test.dart
@@ -9,9 +9,9 @@
 const String TEST = "main() => [];";
 
 const Map<String, String> DEFAULT_CORELIB_WITH_LIST = const <String, String>{
-  'Object': 'class Object { Object(); }',
+  'Object': 'class Object { const Object(); }',
   'bool': 'class bool {}',
-  'List': 'abstract class List {}',
+  'List': 'abstract class List<E> {}',
   'num': 'class num {}',
   'int': 'class int {}',
   'double': 'class double {}',
diff --git a/tests/compiler/dart2js/source_map_d2js_validity_test.dart b/tests/compiler/dart2js/source_map_d2js_validity_test.dart
index ac24952..062a35a 100644
--- a/tests/compiler/dart2js/source_map_d2js_validity_test.dart
+++ b/tests/compiler/dart2js/source_map_d2js_validity_test.dart
@@ -23,7 +23,7 @@
          '-o${tmpDir.path}/out.js',
          '--library-root=sdk']);
       return result.then((CompilationResult result) {
-        Compiler compiler = result.compiler;
+        CompilerImpl compiler = result.compiler;
         Uri uri =
             new Uri.file('${tmpDir.path}/out.js', windows: Platform.isWindows);
         validateSourceMap(uri,
diff --git a/tests/compiler/dart2js/source_map_deferred_d2js_validity_test.dart b/tests/compiler/dart2js/source_map_deferred_d2js_validity_test.dart
index 19c8f71..36a4878 100644
--- a/tests/compiler/dart2js/source_map_deferred_d2js_validity_test.dart
+++ b/tests/compiler/dart2js/source_map_deferred_d2js_validity_test.dart
@@ -22,7 +22,7 @@
          '-o${tmpDir.path}/out.js',
          '--library-root=sdk']);
       return result.then((CompilationResult result) {
-        Compiler compiler = result.compiler;
+        CompilerImpl compiler = result.compiler;
         Uri mainUri = new Uri.file('${tmpDir.path}/out.js',
                                    windows: Platform.isWindows);
         Uri deferredUri = new Uri.file('${tmpDir.path}/out.js_1.part.js',
diff --git a/tests/compiler/dart2js/source_map_validator_helper.dart b/tests/compiler/dart2js/source_map_validator_helper.dart
index e8ca28c..ef0aff1 100644
--- a/tests/compiler/dart2js/source_map_validator_helper.dart
+++ b/tests/compiler/dart2js/source_map_validator_helper.dart
@@ -8,7 +8,7 @@
 
 import 'package:path/path.dart' as path;
 import 'package:expect/expect.dart';
-import 'package:source_maps/source_maps.dart' hide SourceFile;
+import 'package:source_maps/source_maps.dart';
 import 'package:compiler/src/apiimpl.dart';
 import 'package:compiler/src/elements/elements.dart'
     show AstElement,
@@ -25,7 +25,7 @@
 validateSourceMap(Uri targetUri,
                   {Uri mainUri,
                    Position mainPosition,
-                   Compiler compiler}) {
+                   CompilerImpl compiler}) {
   Uri mapUri = getMapUri(targetUri);
   List<String> targetLines = new File.fromUri(targetUri).readAsLinesSync();
   SingleMapping sourceMap = getSourceMap(mapUri);
@@ -100,7 +100,7 @@
 }
 
 checkNames(Uri targetUri, Uri mapUri,
-           SingleMapping sourceMap, Compiler compiler) {
+           SingleMapping sourceMap, CompilerImpl compiler) {
   Map<Uri, CompilationUnitElement> compilationUnitMap = {};
 
   void mapCompilationUnits(LibraryElement library) {
diff --git a/tests/compiler/dart2js/source_mapping_test.dart b/tests/compiler/dart2js/source_mapping_test.dart
index 6c7b46f..c061f99 100644
--- a/tests/compiler/dart2js/source_mapping_test.dart
+++ b/tests/compiler/dart2js/source_mapping_test.dart
@@ -19,7 +19,7 @@
   Uri uri = new Uri(path: sourceFile.filename);
   compiler.sourceFiles[uri.toString()] = sourceFile;
   JavaScriptBackend backend = compiler.backend;
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     // TODO(floitsch): the outputBuffers are only accessible in the full
     // emitter.
     full.Emitter fullEmitter = backend.emitter.emitter;
diff --git a/tests/compiler/dart2js/sourcemaps/colors.dart b/tests/compiler/dart2js/sourcemaps/colors.dart
index 10aa511..b6fa6b4 100644
--- a/tests/compiler/dart2js/sourcemaps/colors.dart
+++ b/tests/compiler/dart2js/sourcemaps/colors.dart
@@ -4,7 +4,7 @@
 
 /// Utility library for creating web colors.
 
-library colors;
+library sourcemaps.colors;
 
 /// A web color.
 abstract class Color {
diff --git a/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart b/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
index eac4637..9cb53e5 100644
--- a/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
@@ -120,7 +120,7 @@
       if (verbose) print('Using the new source information system.');
       useNewSourceInfo = true;
     }
-    api.Compiler compiler = await compilerFor(
+    api.CompilerImpl compiler = await compilerFor(
         outputProvider: outputProvider,
         // TODO(johnniwinther): Use [verbose] to avoid showing diagnostics.
         options: ['--out=$targetUri', '--source-map=$sourceMapFileUri']
@@ -134,7 +134,7 @@
     var handler = compiler.handler;
     SourceFileProvider sourceFileProvider = handler.provider;
     sourceFileManager = new ProviderSourceFileManager(sourceFileProvider);
-    await compiler.runCompiler(inputUri);
+    await compiler.run(inputUri);
 
     List<SourceMapInfo> infoList = <SourceMapInfo>[];
     backend.generatedCode.forEach((Element element, js.Expression node) {
diff --git a/tests/compiler/dart2js/subtypeset_test.dart b/tests/compiler/dart2js/subtypeset_test.dart
index 6673041..1853a8b 100644
--- a/tests/compiler/dart2js/subtypeset_test.dart
+++ b/tests/compiler/dart2js/subtypeset_test.dart
@@ -4,7 +4,7 @@
 
 // Test for iterators on for [SubclassNode].
 
-library world_test;
+library subtypeset_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
diff --git a/tests/compiler/dart2js/trust_type_annotations_test.dart b/tests/compiler/dart2js/trust_type_annotations_test.dart
index 301d061..f165166 100644
--- a/tests/compiler/dart2js/trust_type_annotations_test.dart
+++ b/tests/compiler/dart2js/trust_type_annotations_test.dart
@@ -49,7 +49,7 @@
 void main() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri, trustTypeAnnotations: true);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var typesInferrer = compiler.typesTask.typesInferrer;
 
     ClassElement classA = findElement(compiler, "A");
@@ -66,7 +66,8 @@
                 typesInferrer.getTypeOfElement(element), compiler.world));
     }
 
-    var intMask = new TypeMask.subtype(compiler.intClass, compiler.world);
+    var intMask = new TypeMask.subtype(
+        compiler.coreClasses.intClass, compiler.world);
 
     checkReturn('foo', intMask);
     checkReturn('faa', intMask);
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 045d2be..9406ea9 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -19,6 +19,7 @@
 import 'package:compiler/src/resolution/tree_elements.dart' show
     TreeElements,
     TreeElementMapping;
+import 'package:compiler/src/parser/element_listener.dart';
 import 'package:compiler/src/tree/tree.dart';
 import 'package:compiler/src/typechecker.dart';
 import 'package:compiler/src/script.dart';
@@ -75,11 +76,10 @@
     Expect.equals(type, analyzeType(compiler, code));
   }
 
-  checkType(compiler.intClass.computeType(compiler.resolution), "3");
-  checkType(compiler.boolClass.computeType(compiler.resolution), "false");
-  checkType(compiler.boolClass.computeType(compiler.resolution), "true");
-  checkType(
-      compiler.stringClass.computeType(compiler.resolution), "'hestfisk'");
+  checkType(compiler.coreTypes.intType, "3");
+  checkType(compiler.coreTypes.boolType, "false");
+  checkType(compiler.coreTypes.boolType, "true");
+  checkType(compiler.coreTypes.stringType, "'hestfisk'");
 }
 
 Future testReturn(MockCompiler compiler) {
@@ -2524,9 +2524,10 @@
     // Type check last class declaration or member.
     TypeCheckerVisitor checker =
         new TypeCheckerVisitor(compiler, mapping, compiler.types);
-    compiler.clearMessages();
+    DiagnosticCollector collector = compiler.diagnosticCollector;
+    collector.clear();
     checker.analyze(node);
-    compareWarningKinds(text, expectedWarnings, compiler.warnings);
+    compareWarningKinds(text, expectedWarnings, collector.warnings);
 
     compiler.diagnosticHandler = null;
   });
@@ -2550,7 +2551,8 @@
   compiler.diagnosticHandler = createHandler(compiler, text);
 
   Token tokens = scan(text);
-  NodeListener listener = new NodeListener(compiler.reporter, null);
+  NodeListener listener = new NodeListener(
+      const ScannerOptions(), compiler.reporter, null);
   Parser parser = new Parser(listener);
   parser.parseStatement(tokens);
   Node node = listener.popNode();
@@ -2561,25 +2563,23 @@
   compiler.enqueuer.resolution.emptyDeferredTaskQueue();
   TypeCheckerVisitor checker = new TypeCheckerVisitor(
       compiler, elements, compiler.types);
-  compiler.clearMessages();
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  collector.clear();
   checker.analyze(node);
   if (flushDeferred) {
     compiler.enqueuer.resolution.emptyDeferredTaskQueue();
   }
-  compareWarningKinds(text, warnings, compiler.warnings);
-  compareWarningKinds(text, errors, compiler.errors);
-  if (hints != null) compareWarningKinds(text, hints, compiler.hints);
-  if (infos != null) compareWarningKinds(text, infos, compiler.infos);
+  compareWarningKinds(text, warnings, collector.warnings);
+  compareWarningKinds(text, errors, collector.errors);
+  if (hints != null) compareWarningKinds(text, hints, collector.hints);
+  if (infos != null) compareWarningKinds(text, infos, collector.infos);
   compiler.diagnosticHandler = null;
 }
 
 void generateOutput(MockCompiler compiler, String text) {
-  for (WarningMessage message in compiler.warnings) {
-    Node node = message.node;
-    var beginToken = node.getBeginToken();
-    var endToken = node.getEndToken();
-    int begin = beginToken.charOffset;
-    int end = endToken.charOffset + endToken.charCount;
+  for (CollectedMessage message in compiler.diagnosticCollector.warnings) {
+    int begin = message.begin;
+    int end = message.end;
     SourceFile sourceFile = new StringSourceFile.fromName('analysis', text);
     print(sourceFile.getLocationMessage(message.message.toString(),
                                         begin, end));
@@ -2597,18 +2597,19 @@
 
   compiler.resolver.resolve(element);
   Token tokens = scan(text);
-  NodeListener listener = new NodeListener(compiler.reporter, null);
+  NodeListener listener = new NodeListener(
+      const ScannerOptions(), compiler.reporter, null);
   Parser parser = new Parser(listener,
-      yieldIsKeyword: element.asyncMarker.isYielding,
-      awaitIsKeyword: element.asyncMarker.isAsync);
+      asyncAwaitKeywordsEnabled: element.asyncMarker != AsyncMarker.SYNC);
   parser.parseStatement(tokens);
   Node node = listener.popNode();
   TreeElements elements = compiler.resolveNodeStatement(node, element);
   TypeCheckerVisitor checker = new TypeCheckerVisitor(
       compiler, elements, compiler.types);
-  compiler.clearMessages();
+  DiagnosticCollector collector = compiler.diagnosticCollector;
+  collector.clear();
   checker.analyze(node);
   generateOutput(compiler, text);
-  compareWarningKinds(text, warnings, compiler.warnings);
-  compareWarningKinds(text, hints, compiler.hints);
+  compareWarningKinds(text, warnings, collector.warnings);
+  compareWarningKinds(text, hints, collector.hints);
 }
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index c75ad56..3aef5f8 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
+import 'package:compiler/src/js_backend/backend_helpers.dart';
 import 'package:compiler/src/js_backend/js_backend.dart';
 import 'package:compiler/src/types/types.dart';
 import 'package:compiler/src/world.dart';
@@ -75,8 +76,9 @@
 
     var r1 = operate(type1, type2);
     var r2 = operate(type2, type1);
-    Expect.equals(result, r1);
-    Expect.equals(r1, r2, 'symmetry violation');
+    Expect.equals(result, r1,
+        "Unexpected result of $name($type1,$type2)");
+    Expect.equals(r1, r2, 'Symmetry violation of $name($type1,$type2)');
   }
 
   void check(type1, type2, predicate) {
@@ -412,6 +414,7 @@
 
 void testIntersection(MockCompiler compiler) {
   JavaScriptBackend backend = compiler.backend;
+  BackendHelpers helpers = backend.helpers;
   RuleSet ruleSet = new RuleSet('intersection',
       (t1, t2) => t1.intersection(t2, compiler.world));
   rule(type1, type2, result) => ruleSet.rule(type1, type2, result);
@@ -554,9 +557,9 @@
   rule(jsIndexable, nonPrimitive1, emptyType);
   rule(jsIndexable, nonPrimitive2, emptyType);
   rule(jsIndexable, potentialArray, new TypeMask.nonNullSubtype(
-      backend.jsArrayClass, compiler.world));
+      helpers.jsArrayClass, compiler.world));
   rule(jsIndexable, potentialString, new TypeMask.nonNullSubtype(
-      backend.jsStringClass, compiler.world));
+      helpers.jsStringClass, compiler.world));
   rule(jsIndexable, jsBooleanOrNull, emptyType);
   rule(jsIndexable, jsNumberOrNull, emptyType);
   rule(jsIndexable, jsIntegerOrNull, emptyType);
@@ -729,10 +732,15 @@
 }
 
 void main() {
-  asyncTest(() => MockCompiler.create((MockCompiler compiler) {
+  asyncTest(() async {
+    MockCompiler compiler = new MockCompiler.internal();
+    await compiler.init("""
+    class PatternImpl implements Pattern {}
+    """);
     JavaScriptBackend backend = compiler.backend;
+    BackendHelpers helpers = backend.helpers;
     World world = compiler.world;
-    backend.interceptorsLibrary.forEachLocalMember((element) {
+    helpers.interceptorsLibrary.forEachLocalMember((element) {
       if (element.isClass) {
         element.ensureResolved(compiler.resolution);
         backend.registerInstantiatedType(
@@ -741,6 +749,9 @@
             compiler.globalDependencies);
       }
     });
+    ClassElement patternImplClass = compiler.mainApp.find('PatternImpl');
+    patternImplClass.ensureResolved(compiler.resolution);
+
     backend.registerInstantiatedType(
         compiler.coreTypes.mapType(),
         compiler.enqueuer.resolution,
@@ -749,6 +760,10 @@
         compiler.coreTypes.functionType,
         compiler.enqueuer.resolution,
         compiler.globalDependencies);
+    backend.registerInstantiatedType(
+        patternImplClass.rawType,
+        compiler.enqueuer.resolution,
+        compiler.globalDependencies);
     compiler.world.populate();
 
     // Grab hold of a supertype for String so we can produce potential
@@ -756,54 +771,61 @@
     patternClass = compiler.coreLibrary.find('Pattern');
 
     nonPrimitive1 = new TypeMask.nonNullSubtype(
-        compiler.mapClass, world);
+        compiler.coreClasses.mapClass, world);
     nonPrimitive2 = new TypeMask.nonNullSubtype(
-        compiler.functionClass, world);
+        compiler.coreClasses.functionClass, world);
     potentialArray = new TypeMask.subtype(
-        compiler.listClass, world);
+        compiler.coreClasses.listClass, world);
     potentialString = new TypeMask.subtype(patternClass, world);
-    jsInterceptor = new TypeMask.nonNullSubclass(backend.jsInterceptorClass,
+    jsInterceptor = new TypeMask.nonNullSubclass(helpers.jsInterceptorClass,
         world);
-    jsArrayOrNull = new TypeMask.subclass(backend.jsArrayClass, world);
-    jsReadableArray = new TypeMask.nonNullSubclass(backend.jsArrayClass,
+    jsArrayOrNull = new TypeMask.subclass(helpers.jsArrayClass, world);
+    jsReadableArray = new TypeMask.nonNullSubclass(helpers.jsArrayClass,
         world);
-    jsMutableArrayOrNull = new TypeMask.subclass(backend.jsMutableArrayClass,
+    jsMutableArrayOrNull = new TypeMask.subclass(helpers.jsMutableArrayClass,
         world);
-    jsMutableArray = new TypeMask.nonNullSubclass(backend.jsMutableArrayClass,
+    jsMutableArray = new TypeMask.nonNullSubclass(helpers.jsMutableArrayClass,
         world);
-    jsFixedArrayOrNull = new TypeMask.exact(backend.jsFixedArrayClass, world);
-    jsFixedArray = new TypeMask.nonNullExact(backend.jsFixedArrayClass, world);
-    jsExtendableArrayOrNull = new TypeMask.exact(backend.jsExtendableArrayClass,
+    jsFixedArrayOrNull = new TypeMask.exact(helpers.jsFixedArrayClass, world);
+    jsFixedArray = new TypeMask.nonNullExact(helpers.jsFixedArrayClass, world);
+    jsExtendableArrayOrNull = new TypeMask.exact(helpers.jsExtendableArrayClass,
         world);
     jsExtendableArray = new TypeMask.nonNullExact(
-        backend.jsExtendableArrayClass, world);
+        helpers.jsExtendableArrayClass, world);
     jsUnmodifiableArrayOrNull =
-        new TypeMask.exact(backend.jsUnmodifiableArrayClass, world);
+        new TypeMask.exact(helpers.jsUnmodifiableArrayClass, world);
     jsUnmodifiableArray =
-        new TypeMask.nonNullExact(backend.jsUnmodifiableArrayClass, world);
-    jsIndexableOrNull = new TypeMask.subtype(backend.jsIndexableClass, world);
-    jsIndexable = new TypeMask.nonNullSubtype(backend.jsIndexableClass, world);
-    jsInterceptorOrNull = new TypeMask.subclass(backend.jsInterceptorClass,
+        new TypeMask.nonNullExact(helpers.jsUnmodifiableArrayClass, world);
+    jsIndexableOrNull = new TypeMask.subtype(helpers.jsIndexableClass, world);
+    jsIndexable = new TypeMask.nonNullSubtype(helpers.jsIndexableClass, world);
+    jsInterceptorOrNull = new TypeMask.subclass(helpers.jsInterceptorClass,
         world);
-    jsStringOrNull = new TypeMask.exact(backend.jsStringClass, world);
-    jsString = new TypeMask.nonNullExact(backend.jsStringClass, world);
-    jsBoolean = new TypeMask.nonNullExact(backend.jsBoolClass, world);
-    jsNumber = new TypeMask.nonNullSubclass(backend.jsNumberClass, world);
-    jsInteger = new TypeMask.nonNullExact(backend.jsIntClass, world);
-    jsDouble = new TypeMask.nonNullExact(backend.jsDoubleClass, world);
-    jsBooleanOrNull = new TypeMask.exact(backend.jsBoolClass, world);
-    jsNumberOrNull = new TypeMask.subclass(backend.jsNumberClass, world);
-    jsIntegerOrNull = new TypeMask.exact(backend.jsIntClass, world);
-    jsDoubleOrNull = new TypeMask.exact(backend.jsDoubleClass, world);
+    jsStringOrNull = new TypeMask.exact(helpers.jsStringClass, world);
+    jsString = new TypeMask.nonNullExact(helpers.jsStringClass, world);
+    jsBoolean = new TypeMask.nonNullExact(helpers.jsBoolClass, world);
+    jsNumber = new TypeMask.nonNullSubclass(helpers.jsNumberClass, world);
+    jsInteger = new TypeMask.nonNullExact(helpers.jsIntClass, world);
+    jsDouble = new TypeMask.nonNullExact(helpers.jsDoubleClass, world);
+    jsBooleanOrNull = new TypeMask.exact(helpers.jsBoolClass, world);
+    jsNumberOrNull = new TypeMask.subclass(helpers.jsNumberClass, world);
+    jsIntegerOrNull = new TypeMask.exact(helpers.jsIntClass, world);
+    jsDoubleOrNull = new TypeMask.exact(helpers.jsDoubleClass, world);
     nullType = const TypeMask.empty();
     objectType = new TypeMask.nonNullSubclass(
-        compiler.objectClass, world);
+        compiler.coreClasses.objectClass, world);
     emptyType = const TypeMask.nonNullEmpty();
     dynamicType = new TypeMask.subclass(
-        compiler.objectClass, world);
+        compiler.coreClasses.objectClass, world);
+
+    Expect.notEquals(emptyType, nonPrimitive1,
+        "nonPrimitive1 expected to be non-empty.");
+    Expect.notEquals(jsStringOrNull, potentialString,
+        "potentialString expected not to be exact JSString");
+    Expect.notEquals(jsArrayOrNull, potentialArray,
+        "potentialArray expected not to be JSArray subclass");
 
     testUnion(compiler);
     testIntersection(compiler);
     testRegressions(compiler);
-  }));
+  });
 }
diff --git a/tests/compiler/dart2js/type_equals_test.dart b/tests/compiler/dart2js/type_equals_test.dart
index 0911d60..edeacdc 100644
--- a/tests/compiler/dart2js/type_equals_test.dart
+++ b/tests/compiler/dart2js/type_equals_test.dart
@@ -89,7 +89,7 @@
       """,
       uri,
       analyzeAll: true, analyzeOnly: true);
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     test(compiler, "void1", "void2", expect: true);
     test(compiler, "int1", "int2", expect: true);
     test(compiler, "String1", "String2", expect: true);
diff --git a/tests/compiler/dart2js/type_inference6_test.dart b/tests/compiler/dart2js/type_inference6_test.dart
index d0da1e7..bfee36c 100644
--- a/tests/compiler/dart2js/type_inference6_test.dart
+++ b/tests/compiler/dart2js/type_inference6_test.dart
@@ -23,7 +23,7 @@
 Future runTest() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST, uri);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var element = findElement(compiler, "foo");
diff --git a/tests/compiler/dart2js/type_inference7_test.dart b/tests/compiler/dart2js/type_inference7_test.dart
index 64b8cbc..072d42d 100644
--- a/tests/compiler/dart2js/type_inference7_test.dart
+++ b/tests/compiler/dart2js/type_inference7_test.dart
@@ -22,7 +22,7 @@
   {
     // Assertions enabled:
     var compiler = compilerFor(TEST, uri, enableUserAssertions: true);
-    await compiler.runCompiler(uri);
+    await compiler.run(uri);
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var foo = findElement(compiler, "foo");
@@ -51,7 +51,7 @@
   {
     // Assertions disabled:
     var compiler = compilerFor(TEST, uri, enableUserAssertions: false);
-    await compiler.runCompiler(uri);
+    await compiler.run(uri);
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var foo = findElement(compiler, "foo");
diff --git a/tests/compiler/dart2js/type_inference8_test.dart b/tests/compiler/dart2js/type_inference8_test.dart
index 570e43a..001b1aa 100644
--- a/tests/compiler/dart2js/type_inference8_test.dart
+++ b/tests/compiler/dart2js/type_inference8_test.dart
@@ -33,7 +33,7 @@
 Future runTest1() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST1, uri);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var element = findElement(compiler, "foo");
@@ -76,7 +76,7 @@
 Future runTest2() {
   Uri uri = new Uri(scheme: 'source');
   var compiler = compilerFor(TEST2, uri);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;
     var element = findElement(compiler, "foo");
diff --git a/tests/compiler/dart2js/type_inference_switch_test.dart b/tests/compiler/dart2js/type_inference_switch_test.dart
new file mode 100644
index 0000000..795684c
--- /dev/null
+++ b/tests/compiler/dart2js/type_inference_switch_test.dart
@@ -0,0 +1,159 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import 'compiler_helper.dart';
+import 'type_mask_test_helper.dart';
+
+import 'dart:async';
+
+const String TEST1 = r"""
+foo(int x) {
+  var a = "one";
+  switch (x) {
+    case 1:
+      a = "two";
+      break;
+    case 2:
+      break;
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST2 = r"""
+foo(int x) {
+  var a;
+  switch (x) {
+    case 1:
+      a = "two";
+      break;
+    case 2:
+      break;
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST3 = r"""
+foo(int x) {
+  var a;
+  switch (x) {
+    case 1:
+      a = 1;
+    case 2:  // illegal fall through
+      a = 2;
+      break;
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST4 = r"""
+foo(int x) {
+  var a;
+  switch (x) {
+    case 1:
+      a = 1;
+    case 2:  // illegal fall through
+      a = 2;
+      break;
+    default:
+      a = 0;
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST5 = r"""
+foo(int x) {
+  var a;
+  switch (x) {
+    case 1:
+      a = 1;
+      break;
+    case 2:
+      a = 2;
+      break;
+    default:
+  }
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+const String TEST6 = r"""
+foo(int x) {
+  var a;
+  do {  // add extra locals scope
+    switch (x) {
+      case 1:
+        a = 1;
+        break;
+      case 2:
+        a = 2;
+        break;
+    }
+  } while (false);
+
+  return a;
+}
+
+main() {
+  foo(new DateTime.now().millisecondsSinceEpoch);
+}
+""";
+
+Future runTest(String test, checker) {
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(test, uri);
+
+  checkTypeOf(String name, TypeMask type) {
+    var typesTask = compiler.typesTask;
+    var typesInferrer = typesTask.typesInferrer;
+    var element = findElement(compiler, name);
+    var mask = typesInferrer.getReturnTypeOfElement(element);
+    Expect.equals(type, simplify(mask, compiler));
+  }
+
+  return compiler.run(uri).then((_) {
+    checker(compiler.typesTask, checkTypeOf);
+  });
+}
+
+main() {
+  asyncTest(() async {
+    await runTest(TEST1, (t, c) => c("foo", t.stringType));
+    await runTest(TEST2, (t, c) => c("foo", t.stringType.nullable()));
+    await runTest(TEST3, (t, c) => c("foo", t.uint31Type.nullable()));
+    await runTest(TEST4, (t, c) => c("foo", t.uint31Type));
+    await runTest(TEST5, (t, c) => c("foo", t.uint31Type.nullable()));
+    await runTest(TEST6, (t, c) => c("foo", t.uint31Type.nullable()));
+  });
+}
diff --git a/tests/compiler/dart2js/type_mask2_test.dart b/tests/compiler/dart2js/type_mask2_test.dart
index 25c19e1..03db580 100644
--- a/tests/compiler/dart2js/type_mask2_test.dart
+++ b/tests/compiler/dart2js/type_mask2_test.dart
@@ -4,12 +4,15 @@
 
 library type_mask2_test;
 
+import 'dart:async';
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import 'type_test_helper.dart';
 import 'package:compiler/src/elements/elements.dart'
        show Element, ClassElement;
 import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/world.dart' show
+    ClassWorld;
 
 isCheckedMode() {
   try {
@@ -22,11 +25,67 @@
 }
 
 void main() {
-  testUnionTypeMaskFlatten();
+  asyncTest(() async {
+    await testUnionTypeMaskFlatten();
+    await testStringSubtypes();
+  });
 }
 
-void testUnionTypeMaskFlatten() {
-  asyncTest(() => TypeEnvironment.create(r"""
+checkMasks(ClassWorld classWorld,
+           List<ClassElement> allClasses,
+           List<FlatTypeMask> masks,
+           {FlatTypeMask result,
+            List<FlatTypeMask> disjointMasks,
+            FlatTypeMask flattened,
+            List<ClassElement> containedClasses}) {
+  List<FlatTypeMask> disjoint = <FlatTypeMask>[];
+  UnionTypeMask.unionOfHelper(masks, disjoint, classWorld);
+  Expect.listEquals(disjointMasks, disjoint,
+      'Unexpected disjoint masks: $disjoint, expected $disjointMasks.');
+  if (flattened == null) {
+    // We only do the invalid call to flatten in checked mode, as flatten's
+    // behaviour in unchecked mode is not defined and thus cannot be
+    // reliably tested.
+    if (isCheckedMode()) {
+      Expect.throws(() => UnionTypeMask.flatten(disjoint, classWorld),
+        (e) => e is AssertionError,
+        'Expect assertion failure on flattening of $disjoint.');
+    }
+  } else {
+    TypeMask flattenResult =
+        UnionTypeMask.flatten(disjoint, classWorld);
+    Expect.equals(flattened, flattenResult,
+        'Unexpected flattening of $disjoint: '
+        '$flattenResult, expected $flattened.');
+  }
+  var union = UnionTypeMask.unionOf(masks, classWorld);
+  if (result == null) {
+    Expect.isTrue(union is UnionTypeMask,
+        'Expected union of $masks to be a union-type: $union.');
+    Expect.listEquals(disjointMasks, union.disjointMasks,
+        'Unexpected union masks: '
+        '${union.disjointMasks}, expected $disjointMasks.');
+  } else {
+    Expect.equals(result, union,
+        'Unexpected union of $masks: $union, expected $result.');
+  }
+  if (containedClasses != null) {
+    for (ClassElement cls in allClasses) {
+      if (containedClasses.contains(cls)) {
+        Expect.isTrue(union.contains(cls, classWorld),
+            'Expected $union to contain $cls.');
+      } else {
+        Expect.isFalse(union.contains(cls, classWorld),
+            '$union not expected to contain $cls.');
+      }
+    }
+
+  }
+  return union;
+}
+
+Future testUnionTypeMaskFlatten() async  {
+  TypeEnvironment env = await TypeEnvironment.create(r"""
       class A {}
       class B {}
       class C extends A {}
@@ -42,153 +101,158 @@
         new E();
       }
       """,
-      useMockCompiler: false).then((env) {
+      useMockCompiler: false);
+
+  ClassWorld classWorld = env.compiler.world;
+
+  ClassElement Object_ = env.getElement("Object");
+  ClassElement A = env.getElement("A");
+  ClassElement B = env.getElement("B");
+  ClassElement C = env.getElement("C");
+  ClassElement D = env.getElement("D");
+  ClassElement E = env.getElement("E");
+
+  List<ClassElement> allClasses = <ClassElement>[Object_, A, B, C, D, E];
+
+  check(List<FlatTypeMask> masks,
+        {FlatTypeMask result,
+         List<FlatTypeMask> disjointMasks,
+         FlatTypeMask flattened,
+         List<ClassElement> containedClasses}) {
+    return checkMasks(
+        classWorld,
+        allClasses,
+        masks,
+        result: result,
+        disjointMasks: disjointMasks,
+        flattened: flattened,
+        containedClasses: containedClasses);
+  }
+
+  TypeMask empty = const TypeMask.nonNullEmpty();
+  TypeMask subclassObject = new TypeMask.nonNullSubclass(Object_, classWorld);
+  TypeMask exactA = new TypeMask.nonNullExact(A, classWorld);
+  TypeMask subclassA = new TypeMask.nonNullSubclass(A, classWorld);
+  TypeMask subtypeA = new TypeMask.nonNullSubtype(A, classWorld);
+  TypeMask exactB = new TypeMask.nonNullExact(B, classWorld);
+  TypeMask subclassB = new TypeMask.nonNullSubclass(B, classWorld);
+  TypeMask exactC = new TypeMask.nonNullExact(C, classWorld);
+  TypeMask exactD = new TypeMask.nonNullExact(D, classWorld);
+  TypeMask exactE = new TypeMask.nonNullExact(E, classWorld);
+
+  check([],
+        result: empty,
+        disjointMasks: [],
+        containedClasses: []);
+
+  check([exactA],
+        result: exactA,
+        disjointMasks: [exactA],
+        containedClasses: [A]);
+
+  check([exactA, exactA],
+        result: exactA,
+        disjointMasks: [exactA],
+        containedClasses: [A]);
+
+  check([exactA, exactB],
+        disjointMasks: [exactA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B]);
+
+  check([subclassObject],
+        result: subclassObject,
+        disjointMasks: [subclassObject],
+        containedClasses: [Object_, A, B, C, D, E]);
+
+  check([subclassObject, exactA],
+        disjointMasks: [subclassObject],
+        result: subclassObject,
+        containedClasses: [Object_, A, B, C, D, E]);
+
+  check([exactA, exactC],
+        disjointMasks: [subclassA],
+        result: subclassA,
+        containedClasses: [A, C]);
+
+  check([exactA, exactB, exactC],
+        disjointMasks: [subclassA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B, C]);
+
+  check([exactA, exactD],
+        disjointMasks: [subtypeA],
+        result: subtypeA,
+        containedClasses: [A, C, D, E]);
+
+  check([exactA, exactB, exactD],
+        disjointMasks: [subtypeA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B, C, D, E]);
+
+  check([exactA, exactE],
+        disjointMasks: [subtypeA],
+        result: subtypeA,
+        containedClasses: [A, C, D, E]);
+
+  check([exactA, exactB, exactE],
+        disjointMasks: [subtypeA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B, C, D, E]);
+
+  check([exactB, exactE, exactA],
+        disjointMasks: [subclassB, exactA],
+        flattened: subclassObject,
+        containedClasses: [A, B, E]);
+
+  check([exactE, exactA, exactB],
+        disjointMasks: [subtypeA, exactB],
+        flattened: subclassObject,
+        containedClasses: [A, B, C, D, E]);
+
+  check([exactE, exactB, exactA],
+        disjointMasks: [subclassB, exactA],
+        flattened: subclassObject,
+        containedClasses: [A, B, E]);
+}
+
+Future testStringSubtypes() async {
+  TypeEnvironment env = await TypeEnvironment.create('',
+      mainSource: r"""
+      main() {
+        '' is String;
+      }
+      """,
+      useMockCompiler: false);
     var classWorld = env.compiler.world;
+    var backend = env.compiler.backend;
 
     ClassElement Object_ = env.getElement("Object");
-    ClassElement A = env.getElement("A");
-    ClassElement B = env.getElement("B");
-    ClassElement C = env.getElement("C");
-    ClassElement D = env.getElement("D");
-    ClassElement E = env.getElement("E");
+    ClassElement String_ = env.getElement("String");
+    ClassElement JSString = backend.helpers.jsStringClass;
 
-    List<ClassElement> allClasses = <ClassElement>[Object_, A, B, C, D, E];
+    List<ClassElement> allClasses = <ClassElement>[Object_, String_];
 
-    check(List<FlatTypeMask> masks,
-          {FlatTypeMask result,
-           List<FlatTypeMask> disjointMasks,
-           FlatTypeMask flattened,
-           List<ClassElement> containedClasses}) {
-      List<FlatTypeMask> disjoint = <FlatTypeMask>[];
-      UnionTypeMask.unionOfHelper(masks, disjoint, classWorld);
-      Expect.listEquals(disjointMasks, disjoint,
-          'Unexpected disjoint masks: $disjoint, expected $disjointMasks.');
-      if (flattened == null) {
-        // We only do the invalid call to flatten in checked mode, as flatten's
-        // brehaviour in unchecked more is not defined and thus cannot be
-        // reliably tested.
-        if (isCheckedMode()) {
-          Expect.throws(() => UnionTypeMask.flatten(disjoint, classWorld),
-            (e) => e is AssertionError,
-            'Expect assertion failure on flattening of $disjoint.');
-        }
-      } else {
-        TypeMask flattenResult =
-            UnionTypeMask.flatten(disjoint, classWorld);
-        Expect.equals(flattened, flattenResult,
-            'Unexpected flattening of $disjoint: '
-            '$flattenResult, expected $flattened.');
-      }
-      var union = UnionTypeMask.unionOf(masks, classWorld);
-      if (result == null) {
-        Expect.isTrue(union is UnionTypeMask,
-            'Expected union of $masks to be a union-type: $union.');
-        Expect.listEquals(disjointMasks, union.disjointMasks,
-            'Unexpected union masks: '
-            '${union.disjointMasks}, expected $disjointMasks.');
-      } else {
-        Expect.equals(result, union,
-            'Unexpected union of $masks: $union, expected $result.');
-      }
-      if (containedClasses != null) {
-        for (ClassElement cls in allClasses) {
-          if (containedClasses.contains(cls)) {
-            Expect.isTrue(union.contains(cls, classWorld),
-                'Expected $union to contain $cls.');
-          } else {
-            Expect.isFalse(union.contains(cls, classWorld),
-                '$union not expected to contain $cls.');
-          }
-        }
+    Expect.isFalse(classWorld.isDirectlyInstantiated(Object_));
+    Expect.isTrue(classWorld.isIndirectlyInstantiated(Object_));
+    Expect.isTrue(classWorld.isInstantiated(Object_));
 
-      }
-      return union;
-    }
+    Expect.isFalse(classWorld.isDirectlyInstantiated(String_));
+    Expect.isFalse(classWorld.isIndirectlyInstantiated(String_));
+    Expect.isFalse(classWorld.isInstantiated(String_));
 
-    TypeMask empty = const TypeMask.nonNullEmpty();
-    TypeMask subclassObject = new TypeMask.nonNullSubclass(Object_, classWorld);
-    TypeMask exactA = new TypeMask.nonNullExact(A, classWorld);
-    TypeMask subclassA = new TypeMask.nonNullSubclass(A, classWorld);
-    TypeMask subtypeA = new TypeMask.nonNullSubtype(A, classWorld);
-    TypeMask exactB = new TypeMask.nonNullExact(B, classWorld);
-    TypeMask subclassB = new TypeMask.nonNullSubclass(B, classWorld);
-    TypeMask exactC = new TypeMask.nonNullExact(C, classWorld);
-    TypeMask exactD = new TypeMask.nonNullExact(D, classWorld);
-    TypeMask exactE = new TypeMask.nonNullExact(E, classWorld);
+    Expect.isTrue(classWorld.isDirectlyInstantiated(JSString));
+    Expect.isFalse(classWorld.isIndirectlyInstantiated(JSString));
+    Expect.isTrue(classWorld.isInstantiated(JSString));
 
-    check([],
-          result: empty,
-          disjointMasks: [],
-          containedClasses: []);
+    TypeMask subtypeString = new TypeMask.nonNullSubtype(String_, classWorld);
+    TypeMask exactJSString = new TypeMask.nonNullExact(JSString, classWorld);
+    TypeMask subtypeJSString =
+        new TypeMask.nonNullSubtype(JSString, classWorld);
+    TypeMask subclassJSString =
+        new TypeMask.nonNullSubclass(JSString, classWorld);
 
-    check([exactA],
-          result: exactA,
-          disjointMasks: [exactA],
-          containedClasses: [A]);
-
-    check([exactA, exactA],
-          result: exactA,
-          disjointMasks: [exactA],
-          containedClasses: [A]);
-
-    check([exactA, exactB],
-          disjointMasks: [exactA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B]);
-
-    check([subclassObject],
-          result: subclassObject,
-          disjointMasks: [subclassObject],
-          containedClasses: [Object_, A, B, C, D, E]);
-
-    check([subclassObject, exactA],
-          disjointMasks: [subclassObject],
-          result: subclassObject,
-          containedClasses: [Object_, A, B, C, D, E]);
-
-    check([exactA, exactC],
-          disjointMasks: [subclassA],
-          result: subclassA,
-          containedClasses: [A, C]);
-
-    check([exactA, exactB, exactC],
-          disjointMasks: [subclassA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B, C]);
-
-    check([exactA, exactD],
-          disjointMasks: [subtypeA],
-          result: subtypeA,
-          containedClasses: [A, C, D, E]);
-
-    check([exactA, exactB, exactD],
-          disjointMasks: [subtypeA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B, C, D, E]);
-
-    check([exactA, exactE],
-          disjointMasks: [subtypeA],
-          result: subtypeA,
-          containedClasses: [A, C, D, E]);
-
-    check([exactA, exactB, exactE],
-          disjointMasks: [subtypeA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B, C, D, E]);
-
-    check([exactB, exactE, exactA],
-          disjointMasks: [subclassB, exactA],
-          flattened: subclassObject,
-          containedClasses: [A, B, E]);
-
-    check([exactE, exactA, exactB],
-          disjointMasks: [subtypeA, exactB],
-          flattened: subclassObject,
-          containedClasses: [A, B, C, D, E]);
-
-    check([exactE, exactB, exactA],
-          disjointMasks: [subclassB, exactA],
-          flattened: subclassObject,
-          containedClasses: [A, B, E]);
-  }));
+    Expect.equals(exactJSString, subtypeString);
+    Expect.equals(exactJSString, subtypeJSString);
+    Expect.equals(exactJSString, subclassJSString);
 }
diff --git a/tests/compiler/dart2js/type_mask_test.dart b/tests/compiler/dart2js/type_mask_test.dart
index fa7d108..0547260 100644
--- a/tests/compiler/dart2js/type_mask_test.dart
+++ b/tests/compiler/dart2js/type_mask_test.dart
@@ -23,7 +23,7 @@
   var compiler = compilerFor(CODE, uri);
   var classWorld = compiler.world;
 
-  asyncTest(() => compiler.runCompiler(uri).then((_) {
+  asyncTest(() => compiler.run(uri).then((_) {
     var classA = findElement(compiler, 'A');
     var classB = findElement(compiler, 'B');
     var classC = findElement(compiler, 'C');
@@ -37,8 +37,8 @@
     var subclassA = new TypeMask.nonNullSubclass(classA, classWorld);
     var subtypeA = new TypeMask.nonNullSubtype(classA, classWorld);
 
-    var subclassObject = new TypeMask.nonNullSubclass(compiler.objectClass,
-        classWorld);
+    var subclassObject = new TypeMask.nonNullSubclass(
+        compiler.coreClasses.objectClass, classWorld);
 
     var unionABC = UnionTypeMask.unionOf([exactA, exactB, exactC], classWorld);
     var unionABnC = UnionTypeMask.unionOf([exactA, exactB.nullable(), exactC],
diff --git a/tests/compiler/dart2js/type_order_test.dart b/tests/compiler/dart2js/type_order_test.dart
index dff24fc..87c2aa2 100644
--- a/tests/compiler/dart2js/type_order_test.dart
+++ b/tests/compiler/dart2js/type_order_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library subtype_test;
+library type_order_test;
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index 83f4806..0a2d4e0 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library subtype_test;
+library type_representation_test;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index 32ed3ff..fc04a58 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -14,6 +14,7 @@
     show Compiler;
 import 'package:compiler/src/elements/elements.dart'
     show Element,
+         MemberElement,
          TypeDeclarationElement,
          ClassElement;
 
@@ -37,8 +38,6 @@
                       bool stopAfterTypeInference: false,
                       String mainSource}) {
     Uri uri;
-    Function getErrors;
-    Function getWarnings;
     Compiler compiler;
     bool stopAfterTypeInference = mainSource != null;
     if (mainSource == null) {
@@ -48,6 +47,7 @@
     } else {
       source = '$mainSource\n$source';
     }
+    memory.DiagnosticCollector collector;
     if (useMockCompiler) {
       uri = new Uri(scheme: 'source');
       mock.MockCompiler mockCompiler = mock.compilerFor(
@@ -56,29 +56,26 @@
           analyzeAll: !stopAfterTypeInference,
           analyzeOnly: !stopAfterTypeInference);
       mockCompiler.diagnosticHandler = mock.createHandler(mockCompiler, source);
-      getErrors = () => mockCompiler.errors;
-      getWarnings = () => mockCompiler.warnings;
+      collector = mockCompiler.diagnosticCollector;
       compiler = mockCompiler;
     } else {
-      memory.DiagnosticCollector collector = new memory.DiagnosticCollector();
+      collector = new memory.DiagnosticCollector();
       uri = Uri.parse('memory:main.dart');
       compiler = memory.compilerFor(
           memorySourceFiles: {'main.dart': source},
           diagnosticHandler: collector,
           options: stopAfterTypeInference
               ? [] : [Flags.analyzeAll, Flags.analyzeOnly]);
-      getErrors = () => collector.errors;
-      getWarnings = () => collector.warnings;
     }
     compiler.stopAfterTypeInference = stopAfterTypeInference;
-    return compiler.runCompiler(uri).then((_) {
+    return compiler.run(uri).then((_) {
       if (expectNoErrors || expectNoWarningsOrErrors) {
-        var errors = getErrors();
+        var errors = collector.errors;
         Expect.isTrue(errors.isEmpty,
             'Unexpected errors: ${errors}');
       }
       if (expectNoWarningsOrErrors) {
-        var warnings = getWarnings();
+        var warnings = collector.warnings;
         Expect.isTrue(warnings.isEmpty,
             'Unexpected warnings: ${warnings}');
       }
@@ -100,7 +97,8 @@
   }
 
   DartType getElementType(String name) {
-    return getElement(name).computeType(compiler.resolution);
+    var element = getElement(name);
+    return element.computeType(compiler.resolution);
   }
 
   DartType operator[] (String name) {
@@ -110,7 +108,7 @@
   }
 
   DartType getMemberType(ClassElement element, String name) {
-    Element member = element.localLookup(name);
+    MemberElement member = element.localLookup(name);
     return member.computeType(compiler.resolution);
   }
 
diff --git a/tests/compiler/dart2js/type_variable_bound_test.dart b/tests/compiler/dart2js/type_variable_bound_test.dart
index b93c42d..d8a6903 100644
--- a/tests/compiler/dart2js/type_variable_bound_test.dart
+++ b/tests/compiler/dart2js/type_variable_bound_test.dart
@@ -12,7 +12,7 @@
   var compiler =
       compilerFor(source, uri, analyzeOnly: true, enableTypeAssertions: true);
   compiler.diagnosticHandler = createHandler(compiler, source);
-  return compiler.runCompiler(uri).then((_) {
+  return compiler.run(uri).then((_) {
     return compiler;
   });
 }
@@ -23,19 +23,20 @@
   if (warnings == null) warnings = [];
   if (warnings is! List) warnings = [warnings];
   asyncTest(() => compile(source).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.equals(!errors.isEmpty, compiler.compilationFailed);
-    Expect.equals(errors.length, compiler.errors.length,
-                  'unexpected error count: ${compiler.errors.length} '
+    Expect.equals(errors.length, collector.errors.length,
+                  'unexpected error count: ${collector.errors.length} '
                   'expected ${errors.length}');
-    Expect.equals(warnings.length, compiler.warnings.length,
-                  'unexpected warning count: ${compiler.warnings.length} '
+    Expect.equals(warnings.length, collector.warnings.length,
+                  'unexpected warning count: ${collector.warnings.length} '
                   'expected ${warnings.length}');
 
     for (int i = 0 ; i < errors.length ; i++) {
-      Expect.equals(errors[i], compiler.errors[i].message.kind);
+      Expect.equals(errors[i], collector.errors.elementAt(i).message.kind);
     }
     for (int i = 0 ; i < warnings.length ; i++) {
-      Expect.equals(warnings[i], compiler.warnings[i].message.kind);
+      Expect.equals(warnings[i], collector.warnings.elementAt(i).message.kind);
     }
   }));
 }
@@ -48,15 +49,18 @@
   new A();
 }
 """).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.isFalse(compiler.compilationFailed);
-    Expect.isTrue(compiler.errors.isEmpty,
-                  'unexpected errors: ${compiler.errors}');
-    Expect.equals(1, compiler.warnings.length,
-                  'expected exactly one warning, but got ${compiler.warnings}');
+    Expect.isTrue(collector.errors.isEmpty,
+                  'unexpected errors: ${collector.errors}');
+    Expect.equals(1, collector.warnings.length,
+                  'expected exactly one warning, but got ${collector.warnings}');
 
+    print(collector.warnings.elementAt(0));
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[0].message.kind);
-    Expect.equals("T", compiler.warnings[0].node.toString());
+                  collector.warnings.elementAt(0).message.kind);
+    Expect.equals("T",
+        collector.warnings.elementAt(0).message.arguments['typeVariableName']);
   }));
 }
 
@@ -68,19 +72,22 @@
   new B();
 }
 """).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.isFalse(compiler.compilationFailed);
-    print(compiler.errors);
-    Expect.isTrue(compiler.errors.isEmpty, 'unexpected errors');
-    Expect.equals(2, compiler.warnings.length,
-                  'expected exactly two errors, but got ${compiler.warnings}');
+    print(collector.errors);
+    Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
+    Expect.equals(2, collector.warnings.length,
+                  'expected exactly two errors, but got ${collector.warnings}');
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[0].message.kind);
-    Expect.equals("T", compiler.warnings[0].node.toString());
+                  collector.warnings.elementAt(0).message.kind);
+    Expect.equals("T",
+        collector.warnings.elementAt(0).message.arguments['typeVariableName']);
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[1].message.kind);
-    Expect.equals("S", compiler.warnings[1].node.toString());
+                  collector.warnings.elementAt(1).message.kind);
+    Expect.equals("S",
+        collector.warnings.elementAt(1).message.arguments['typeVariableName']);
   }));
 }
 
@@ -92,23 +99,27 @@
   new C();
 }
 """).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.isFalse(compiler.compilationFailed);
-    print(compiler.errors);
-    Expect.isTrue(compiler.errors.isEmpty, 'unexpected errors');
-    Expect.equals(3, compiler.warnings.length,
-                  'expected exactly one error, but got ${compiler.warnings}');
+    print(collector.errors);
+    Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
+    Expect.equals(3, collector.warnings.length,
+                  'expected exactly one error, but got ${collector.warnings}');
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[0].message.kind);
-    Expect.equals("T", compiler.warnings[0].node.toString());
+                  collector.warnings.elementAt(0).message.kind);
+    Expect.equals("T",
+        collector.warnings.elementAt(0).message.arguments['typeVariableName']);
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[1].message.kind);
-    Expect.equals("S", compiler.warnings[1].node.toString());
+                  collector.warnings.elementAt(1).message.kind);
+    Expect.equals("S",
+        collector.warnings.elementAt(1).message.arguments['typeVariableName']);
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[2].message.kind);
-    Expect.equals("U", compiler.warnings[2].node.toString());
+                  collector.warnings.elementAt(2).message.kind);
+    Expect.equals("U",
+        collector.warnings.elementAt(2).message.arguments['typeVariableName']);
   }));
 }
 
@@ -120,19 +131,22 @@
   new D();
 }
 """).then((compiler) {
+    DiagnosticCollector collector = compiler.diagnosticCollector;
     Expect.isFalse(compiler.compilationFailed);
-    print(compiler.errors);
-    Expect.isTrue(compiler.errors.isEmpty, 'unexpected errors');
-    Expect.equals(2, compiler.warnings.length,
-                  'expected exactly one error, but got ${compiler.warnings}');
+    print(collector.errors);
+    Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
+    Expect.equals(2, collector.warnings.length,
+                  'expected exactly one error, but got ${collector.warnings}');
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[0].message.kind);
-    Expect.equals("S", compiler.warnings[0].node.toString());
+                  collector.warnings.elementAt(0).message.kind);
+    Expect.equals("S",
+        collector.warnings.elementAt(0).message.arguments['typeVariableName']);
 
     Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
-                  compiler.warnings[1].message.kind);
-    Expect.equals("U", compiler.warnings[1].node.toString());
+                  collector.warnings.elementAt(1).message.kind);
+    Expect.equals("U",
+        collector.warnings.elementAt(1).message.arguments['typeVariableName']);
   }));
 }
 
diff --git a/tests/compiler/dart2js/type_variable_occurrence_test.dart b/tests/compiler/dart2js/type_variable_occurrence_test.dart
index a198cd4..a30a552 100644
--- a/tests/compiler/dart2js/type_variable_occurrence_test.dart
+++ b/tests/compiler/dart2js/type_variable_occurrence_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library subtype_test;
+library type_variable_occurrence_test;
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/union_type_test.dart b/tests/compiler/dart2js/union_type_test.dart
index c103d6f..4ae2dac 100644
--- a/tests/compiler/dart2js/union_type_test.dart
+++ b/tests/compiler/dart2js/union_type_test.dart
@@ -5,22 +5,29 @@
 import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
 import "package:compiler/src/types/types.dart";
-
-import "compiler_helper.dart";
+import "package:compiler/src/world.dart";
+import 'type_test_helper.dart';
 
 main() {
-  MockCompiler compiler = new MockCompiler.internal(analyzeOnly: true);
-  asyncTest(() => compiler.runCompiler(null, """
+
+  asyncTest(() async {
+    TypeEnvironment env = await TypeEnvironment.create(r"""
+      class A {}
+      class B {}
+      """,
+      mainSource: r"""
       main() {
-        print(2); print("Hello");
+        new A();
+        new B();
       }
-    """).then((_) {
-    FlatTypeMask mask1 =
-        new FlatTypeMask.exact(compiler.intClass);
-    FlatTypeMask mask2 =
-        new FlatTypeMask.exact(compiler.stringClass);
-    UnionTypeMask union1 = mask1.nonNullable().union(mask2, compiler.world);
-    UnionTypeMask union2 = mask2.nonNullable().union(mask1, compiler.world);
+      """,
+      useMockCompiler: false);
+    World world = env.compiler.world;
+    world.populate();
+    FlatTypeMask mask1 = new FlatTypeMask.exact(env.getElement('A'));
+    FlatTypeMask mask2 = new FlatTypeMask.exact(env.getElement('B'));
+    UnionTypeMask union1 = mask1.nonNullable().union(mask2, world);
+    UnionTypeMask union2 = mask2.nonNullable().union(mask1, world);
     Expect.equals(union1, union2);
-  }));
+  });
 }
diff --git a/tests/compiler/dart2js/unparser2_test.dart b/tests/compiler/dart2js/unparser2_test.dart
index 91e13aa..8ede8c9 100644
--- a/tests/compiler/dart2js/unparser2_test.dart
+++ b/tests/compiler/dart2js/unparser2_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import "package:compiler/src/parser/element_listener.dart";
 import "package:compiler/src/parser/node_listener.dart";
 import "package:compiler/src/parser/parser.dart";
 import "package:compiler/src/scanner/string_scanner.dart";
@@ -91,7 +92,8 @@
   CompilationUnitElement element = new CompilationUnitElementX(script, lib);
   StringScanner scanner = new StringScanner.fromString(source);
   Token beginToken = scanner.tokenize();
-  NodeListener listener = new NodeListener(diagnosticListener, element);
+  NodeListener listener = new NodeListener(
+      const ScannerOptions(), diagnosticListener, element);
   Parser parser = new Parser(listener);
   parser.parseUnit(beginToken);
   Node node = listener.popNode();
diff --git a/tests/compiler/dart2js/unparser_test.dart b/tests/compiler/dart2js/unparser_test.dart
index 4b9a815..e19ed0d 100644
--- a/tests/compiler/dart2js/unparser_test.dart
+++ b/tests/compiler/dart2js/unparser_test.dart
@@ -98,6 +98,57 @@
   testUnparseTopLevelWithMetadata('export "søhest";');
 }
 
+testConditionalImport() {
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(some.dotted.id)"other";');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(id=="some str")"other";');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2";');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(some.dotted.id)"other" as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(id=="some str")"other" as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2"'
+      ' as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(some.dotted.id)"other" deferred as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(id=="some str")"other" deferred as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2"'
+      ' deferred as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2"'
+      ' deferred as fiskehest'
+      ' show foo,bar;');
+}
+
+testConditionalExport() {
+  testUnparseTopLevelWithMetadata(
+      'export "søhest" if(some.dotted.id)"other";');
+  testUnparseTopLevelWithMetadata(
+      'export "søhest" if(id=="some str")"other";');
+  testUnparseTopLevelWithMetadata(
+      'export "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2";');
+  testUnparseTopLevelWithMetadata(
+      'export "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2"'
+      ' show foo,bar;');
+}
+
 testPart() {
   testUnparseTopLevelWithMetadata('part "søhest";');
 }
@@ -383,6 +434,8 @@
   testLibraryName();
   testImport();
   testExport();
+  testConditionalImport();
+  testConditionalExport();
   testPart();
   testPartOf();
   testCombinators();
diff --git a/tests/compiler/dart2js/warnings_checker.dart b/tests/compiler/dart2js/warnings_checker.dart
index 1652a1e..3e50eae 100644
--- a/tests/compiler/dart2js/warnings_checker.dart
+++ b/tests/compiler/dart2js/warnings_checker.dart
@@ -55,7 +55,7 @@
     if (statusMap != null && statusMap.containsKey('missing')) {
       missingStatus = statusMap['missing'];
     }
-    for (DiagnosticMessage message in collector.warnings) {
+    for (CollectedMessage message in collector.warnings) {
       Expect.equals(uri, message.uri);
       int lineNo = file.getLine(message.begin);
       if (expectedWarnings.containsKey(lineNo)) {
diff --git a/tests/compiler/dart2js_extra/23404_test.dart b/tests/compiler/dart2js_extra/23404_test.dart
index 113d78a..bfd52ba 100644
--- a/tests/compiler/dart2js_extra/23404_test.dart
+++ b/tests/compiler/dart2js_extra/23404_test.dart
@@ -11,8 +11,8 @@
 foo([a='\u00a0']) => a;
 bar() => '';
 
-@NoInline
-@AssumeDynamic
+@NoInline()
+@AssumeDynamic()
 confuse(x) => x;
 
 main() {
diff --git a/tests/compiler/dart2js_extra/23828_test.dart b/tests/compiler/dart2js_extra/23828_test.dart
index b6312a3..53c2221 100644
--- a/tests/compiler/dart2js_extra/23828_test.dart
+++ b/tests/compiler/dart2js_extra/23828_test.dart
@@ -6,7 +6,9 @@
 // Used to fail when methods contain a name starting with `get`
 import 'package:expect/expect.dart';
 
-confuse(x) { return x; return x; }
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 class MA {
   noSuchMethod(i) => Expect.equals(i.positionalArguments.length, 1);
diff --git a/tests/compiler/dart2js_extra/big_allocation_expression_test.dart b/tests/compiler/dart2js_extra/big_allocation_expression_test.dart
new file mode 100644
index 0000000..586376a
--- /dev/null
+++ b/tests/compiler/dart2js_extra/big_allocation_expression_test.dart
@@ -0,0 +1,4140 @@
+// 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 program crashes the SSA backend. http://dartbug.com/24635.
+
+import "package:expect/expect.dart";
+
+class A {
+  var a;
+  var b;
+
+  factory A(a, x) = A.q;
+
+  // @NoInline()  // This annotation causes the test to compile on SSA backend.
+  A.q(this.a, x) : b = x == null ? null : new W(x);
+}
+
+class W {
+  var a;
+  W(this.a);
+}
+
+measure(x, m) {
+  if (x == null) {
+    m['null']++;
+  } else if (x is W) {
+    m['W']++;
+    measure(x.a, m);
+  } else if (x is A) {
+    m['A']++;
+    measure(x.a, m);
+    measure(x.b, m);
+  }
+  return m;
+}
+
+main() {
+  // 4095 'new A'(...)' expressions, 12 calls deep.
+  var e = new A(
+      new A(
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))))),
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))))),
+      new A(
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))))),
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null),
+                                              new A(null, null))))))))))));
+
+  var m = measure(e, {'null': 0, 'A': 0, 'W': 0});
+  Expect.equals(4096, m['null']);
+  Expect.equals(4095, m['A']);
+  Expect.equals(2047, m['W']);
+}
diff --git a/tests/compiler/dart2js_extra/consistent_add_error_test.dart b/tests/compiler/dart2js_extra/consistent_add_error_test.dart
new file mode 100644
index 0000000..22927e2
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_add_error_test.dart
@@ -0,0 +1,187 @@
+// 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";
+
+// Test that optimized '+' and slow path '+' produce the same error.
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6, f7]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+  if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+  if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+  if (f7 != null) check2(name, 'f1', f1, 'f7', f7);
+}
+
+class IntPlusNull {
+  static f1() {
+    return confuse(1) + confuse(null);
+  }
+
+  static f2() {
+    return confuse(1) + null;
+  }
+
+  static f3() {
+    return (confuse(1) as int) + confuse(null);
+  }
+
+  static f4() {
+    return (confuse(1) as int) + null;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a + confuse(null);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a + null;
+  }
+
+  static f7() {
+    return 1 + null;
+  }
+
+  static test() {
+    check('IntPlusNull', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class StringPlusNull {
+  static f1() {
+    return confuse('a') + confuse(null);
+  }
+
+  static f2() {
+    return confuse('a') + null;
+  }
+
+  static f3() {
+    return (confuse('a') as String) + confuse(null);
+  }
+
+  static f4() {
+    return (confuse('a') as String) + null;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + confuse(null);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + null;
+  }
+
+  static f7() {
+    return 'a' + null;
+  }
+
+  static test() {
+    check('StringPlusNull', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class IntPlusString {
+  static f1() {
+    return confuse(1) + confuse('a');
+  }
+
+  static f2() {
+    return confuse(1) + 'a';
+  }
+
+  static f3() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a + confuse('a');
+  }
+
+  static f4() {
+    return (confuse(1) as int) + confuse('a');
+  }
+
+  static f5() {
+    return (confuse(1) as int) + 'a';
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a + 'a';
+  }
+
+  static f7() {
+    return 1 + 'a';
+  }
+
+  static test() {
+    check('IntPlusString', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class StringPlusInt {
+  static f1() {
+    return confuse('a') + confuse(1);
+  }
+
+  static f2() {
+    return confuse('a') + 1;
+  }
+
+  static f3() {
+    return (confuse('a') as String) + confuse(1);
+  }
+
+  static f4() {
+    return (confuse('a') as String) + 1;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + confuse(1);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + 1;
+  }
+
+  static f7() {
+    return 'a' + 1;
+  }
+
+  static test() {
+    check('StringPlusInt', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+main() {
+  IntPlusNull.test();
+  StringPlusNull.test();
+  IntPlusString.test();
+  StringPlusInt.test();
+}
diff --git a/tests/compiler/dart2js_extra/consistent_codeUnitAt_error_test.dart b/tests/compiler/dart2js_extra/consistent_codeUnitAt_error_test.dart
new file mode 100644
index 0000000..8d3929f
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_codeUnitAt_error_test.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that optimized codeUnitAt and slow path codeUnitAt produce the same
+// error.
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+}
+
+
+class TooHigh {
+  static f1() {
+    return confuse('AB').codeUnitAt(3);  // dynamic receiver.
+  }
+
+  static f2() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';  // String with unknown length.
+    var i = confuse(3);
+    return a.codeUnitAt(i);
+  }
+
+  static f3() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';  // String with unknown length.
+    return a.codeUnitAt(3);
+  }
+
+  static test() {
+    check('TooHigh', f1, f2, f3);
+  }
+}
+
+class Negative {
+  static f1() {
+    return confuse('AB').codeUnitAt(-3);  // dynamic receiver.
+  }
+
+  static f2() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';  // String with unknown length.
+    var i = confuse(-3);
+    return a.codeUnitAt(i);
+  }
+
+  static f3() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';  // String with unknown length.
+    var i = confuse(true) ? -3 : 0;
+    return a.codeUnitAt(i);
+  }
+
+  static f4() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';  // String with unknown length.
+    return a.codeUnitAt(-3);
+  }
+
+  static test() {
+    check('Negative', f1, f2, f3, f4);
+  }
+}
+
+class Empty {
+  static f1() {
+    return confuse('').codeUnitAt(0);  // dynamic receiver.
+  }
+
+  static f2() {
+    var a = confuse(true) ? '' : 'ABCDE';  // Empty String with unknown length.
+    var i = confuse(true) ? 0 : 1;
+    return a.codeUnitAt(i);
+  }
+
+  static f3() {
+    var a = confuse(true) ? '' : 'ABCDE';  // Empty String with unknown length.
+    return a.codeUnitAt(0);
+  }
+
+  static test() {
+    check('Empty', f1, f2, f3);
+  }
+}
+
+class BadType {
+  static f1() {
+    return confuse('AB').codeUnitAt('a');  // dynamic receiver.
+  }
+
+  static f2() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';  // String with unknown length.
+    var i = confuse('a');
+    return a.codeUnitAt(i);
+  }
+
+  static f3() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';  // String with unknown length.
+    return a.codeUnitAt('a');
+  }
+
+  static test() {
+    check('BadType', f1, f2, f3);
+  }
+}
+
+main() {
+  TooHigh.test();
+  Negative.test();
+  Empty.test();
+  BadType.test();
+}
diff --git a/tests/compiler/dart2js_extra/consistent_null_add_error_test.dart b/tests/compiler/dart2js_extra/consistent_null_add_error_test.dart
new file mode 100644
index 0000000..2c47018
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_null_add_error_test.dart
@@ -0,0 +1,82 @@
+// 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";
+
+// Test that optimized 'null + x' and slow path '+' produce the same error.
+//
+// They don't, sometimes we generate null.$add, sometimes JSNull_methods.$add.
+
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+  if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+  if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+}
+
+
+class NullPlusInt {
+  static f1() {
+    return confuse(null) + confuse(1);
+  }
+
+  static f2() {
+    return confuse(null) + 1;
+  }
+
+  static f3() {
+    return (confuse(null) as int) + confuse(1);
+  }
+
+  static f4() {
+    return (confuse(null) as int) + 1;
+  }
+
+  static f5() {
+    var a = null;
+    return a + confuse(1);
+  }
+
+  static f6() {
+    var a = null;
+    return a + 1;
+  }
+
+  static test() {
+    // Sometimes we generate null.$add, sometimes JSNull_methods.$add. The best
+    // we can do is check there is an error.
+    check('NullPlusInt', f1, f1);
+    check('NullPlusInt', f2, f2);
+    check('NullPlusInt', f3, f3);
+    check('NullPlusInt', f4, f4);
+    check('NullPlusInt', f5, f5);
+    check('NullPlusInt', f6, f6);
+  }
+}
+
+main() {
+  NullPlusInt.test();
+}
diff --git a/tests/compiler/dart2js_extra/consistent_subtract_error_test.dart b/tests/compiler/dart2js_extra/consistent_subtract_error_test.dart
new file mode 100644
index 0000000..757c37d
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_subtract_error_test.dart
@@ -0,0 +1,113 @@
+// 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";
+
+// Test that optimized '-' and slow path '-' produce the same error.
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6, f7]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+  if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+  if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+  if (f7 != null) check2(name, 'f1', f1, 'f7', f7);
+}
+
+class IntMinusNull {
+  static f1() {
+    return confuse(1) - confuse(null);
+  }
+
+  static f2() {
+    return confuse(1) - null;
+  }
+
+  static f3() {
+    return (confuse(1) as int) - confuse(null);
+  }
+
+  static f4() {
+    return (confuse(1) as int) - null;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a - confuse(null);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a - null;
+  }
+
+  static f7() {
+    return 1 - null;
+  }
+
+  static test() {
+    check('IntMinusNull', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class IntMinusString {
+  static f1() {
+    return confuse(1) - confuse('a');
+  }
+
+  static f2() {
+    return confuse(1) - 'a';
+  }
+
+  static f3() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a - confuse('a');
+  }
+
+  static f4() {
+    return (confuse(1) as int) - confuse('a');
+  }
+
+  static f5() {
+    return (confuse(1) as int) - 'a';
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a - 'a';
+  }
+
+  static f7() {
+    return 1 - 'a';
+  }
+
+  static test() {
+    check('IntMinusString', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+main() {
+  IntMinusNull.test();
+  IntMinusString.test();
+}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index c530b1e..3d00167 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -60,24 +60,14 @@
 deferred_fail_and_retry_test: SkipByDesign # Uses eval to simulate failed loading.
 deferred_fail_and_retry_worker_test: SkipByDesign # Uses eval to simulate failed loading.
 
-[ $host_checked && $compiler == dart2js && $cps_ir ]
-21724_test: Crash # Please triage this failure.
-
 [ $compiler == none && $runtime == vm ]
 invalid_annotation_test/01: MissingCompileTimeError, OK # vm is lazy
 lookup_map/dead_entry_through_mirrors_test: SkipByDesign # Test for tree-shaking, vm never tree-shakes
 
+[ $compiler == dart2js && $cps_ir == false ]
+big_allocation_expression_test: Crash # Issue 24635
+
 [ $compiler == dart2js && $cps_ir ]
 16407_test: Pass # Please triage this failure.
-23432_test: RuntimeError # Issue 23432
 async_stacktrace_test/asyncStar: Crash # (foo()async*{try {tr...  cannot handle sync*/async* functions
-closure_capture5_test: Crash # (i=0): For-loop variable captured in loop header
-deferred/deferred_class_test: RuntimeError # Z.loadLibrary is not a function
-deferred/deferred_constant2_test: RuntimeError # U.loadLibrary is not a function
-deferred/deferred_constant3_test: RuntimeError # Y.loadLibrary is not a function
-deferred/deferred_constant4_test: RuntimeError # B.loadLibrary is not a function
-deferred/deferred_function_test: Crash # (lib.foo('a')): deferred access is not implemented
-deferred/deferred_mirrors1_test: RuntimeError # U.loadLibrary is not a function
-deferred/deferred_overlapping_test: RuntimeError # E.loadLibrary is not a function
-deferred_split_test: RuntimeError # Z.loadLibrary is not a function
 switch_test/none: Crash # (switch (val){foo:ba...  continue to a labeled switch case
diff --git a/tests/compiler/dart2js_extra/hash_code_test.dart b/tests/compiler/dart2js_extra/hash_code_test.dart
index 0c5c4b3..3329a38 100644
--- a/tests/compiler/dart2js_extra/hash_code_test.dart
+++ b/tests/compiler/dart2js_extra/hash_code_test.dart
@@ -7,9 +7,11 @@
 // dart2js specific test to make sure hashCode on intercepted types behaves as
 // intended.
 
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 class Hasher {
-  confuse(x) => [1, 'x', true, null, x].last;
   hash(x) => confuse(x).hashCode;
 }
 
diff --git a/tests/compiler/dart2js_extra/many_constants_test.dart b/tests/compiler/dart2js_extra/many_constants_test.dart
new file mode 100644
index 0000000..5027b50
--- /dev/null
+++ b/tests/compiler/dart2js_extra/many_constants_test.dart
@@ -0,0 +1,87 @@
+// 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 program has many similar constants that should all have distinct
+// identities. They are sufficiently similar to have name collisions and need
+// ordering by constant value.
+
+import "package:expect/expect.dart";
+
+enum E { A, B, C, D }
+
+class Z {
+  final a, b, c, d, e, f;
+  const Z({this.a: 1, this.b: 1, this.c: 1, this.d: 1, this.e: 1, this.f: 1});
+}
+
+const c1 = const {};
+const c2 = const <int, int>{};
+const c3 = const <dynamic, int>{};
+const c4 = const <int, dynamic>{};
+const l1 = const [];
+const l2 = const <int>[];
+const l3 = const <String>[];
+const l4 = const <num>[];
+
+const ll1 = const [1, 2, 3, 4, 5, 6, 7];
+const ll2 = const [1, 8, 3, 4, 5, 6, 7];
+const ll3 = const [1, 2, 8, 4, 5, 6, 7];
+const ll4 = const [1, 2, 3, 4, 8, 6, 7];
+
+const m1 = const {1: 1, 2: 2};
+const m2 = const {1: 2, 2: 1};
+const m3 = const {1: 1, 2: 1};
+const m4 = const {1: 2, 2: 2};
+const m5 = const {2: 1, 1: 2};
+const m6 = const {2: 2, 1: 1};
+const m7 = const {2: 1, 1: 1};
+const m8 = const {2: 2, 1: 2};
+const m9 = const <int,int>{1: 1, 2: 2};
+const mA = const <int,int>{1: 2, 2: 1};
+const mB = const <int,int>{1: 1, 2: 1};
+const mC = const <int,int>{1: 2, 2: 2};
+
+const mE1 = const {E.A: E.B};
+const mE2 = const {E.A: E.C};
+const mE3 = const {E.A: 0, E.B: 0};
+const mE4 = const {E.A: 0, E.C: 0};
+const mE5 = const {E.A: 0, E.B: 0, E.C: 4};
+const mE6 = const {E.A: 0, E.B: 0, E.C: 2};
+const mE7 = const {E.A: 0, E.B: 0, E.C: 3};
+const mE8 = const {E.A: 0, E.B: 0, E.C: 1};
+
+const z1 = const Z(f: 3);
+const z2 = const Z(f: 2);
+const z3 = const Z(f: 1);
+const z4 = const Z(e: 2);
+const z5 = const Z(d: 3);
+const z6 = const Z(d: 2);
+
+makeAll() => {
+  'E.A': E.A, 'E.B': E.B, 'E.C': E.C, 'E.D': E.D,
+  'c1': c1, 'c2': c2, 'c3': c3, 'c4': c4,
+  'l1': l1, 'l2': l2, 'l3': l3, 'l4': l4,
+  'll1': ll1, 'll2': ll2, 'll3': ll3, 'l4': ll4,
+  'm1': m1, 'm2': m2, 'm3': m3, 'm4': m4,
+  'm5': m5, 'm6': m6, 'm7': m7, 'm8': m8,
+  'm9': m9, 'mA': mA, 'mB': mB, 'mC': mC,
+  'mE1': mE1, 'mE2': mE2, 'mE3': mE3, 'mE4': mE4,
+  'mE5': mE5, 'mE6': mE6, 'mE7': mE7, 'mE8': mE8,
+  'z1': z1, 'z2': z2, 'z3': z3, 'z4': z4, 'z5': z5, 'z6': z6,
+};
+
+main() {
+  var all1 = makeAll();
+  var all2 = makeAll();
+
+  for (var name1 in all1.keys) {
+    var e1 = all1[name1];
+    for (var name2 in all2.keys) {
+      if (name1 == name2) continue;
+      var e2 = all2[name2];
+      Expect.isFalse(identical(e1, e2),
+                     'Different instances  $name1: $e1  $name2: $e2');
+    }
+  }
+}
diff --git a/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart b/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart
index 9b6d8d2..49b74cf 100644
--- a/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart
@@ -17,7 +17,7 @@
 class C {
   foo() => 1;
 
-  @DontInline
+  @NoInline()
   // Use a closure to prevent inlining until the annotation is implemented.
   bar() => () => 2;
 }
diff --git a/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart b/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart
index e142253..4236b3f 100644
--- a/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart
@@ -17,7 +17,7 @@
 class C {
   static foo() => 1;
 
-  @DontInline
+  @NoInline()
   // Use a closure to prevent inlining until the annotation is implemented.
   static bar() => () => 2;
 }
diff --git a/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart b/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart
index 09e8d65..35df0e0 100644
--- a/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart
@@ -16,7 +16,7 @@
 
 foo() => 1;
 
-@DontInline
+@NoInline()
 // Use a closure to prevent inlining until the annotation is implemented.
 bar() => () => 2;
 
diff --git a/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart b/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart
index 28c19a8..12551cf 100644
--- a/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart
+++ b/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart
@@ -18,12 +18,9 @@
   bar() => 33;
 }
 
-// Uses DateTime.now to make it impossible to predict.
-// Uses recursive call to make it harder to inline.
-confuse(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x + 1);
-  return x;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 main() {
   var f = [new A(), new B()][confuse(0)].bar;
diff --git a/tests/compiler/dart2js_extra/operator_test.dart b/tests/compiler/dart2js_extra/operator_test.dart
index 225976f..96ee9dc 100644
--- a/tests/compiler/dart2js_extra/operator_test.dart
+++ b/tests/compiler/dart2js_extra/operator_test.dart
@@ -3,22 +3,80 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
 
+@NoInline()
+asNum(x) {
+  var result = confuse(x);
+  if (result is num) return result;
+  throw new ArgumentError.value(x);
+}
+
+@NoInline()
+uint31(x) {
+  var result = confuse(x);
+  if (x is int) {
+    var masked = 0x7fffffff & x;  // inferred uint31 type.
+    if (masked == x) return masked;
+  }
+  throw new ArgumentError('Not uint31: $x');
+}
+
+@NoInline()
+uint32(x) {
+  var result = confuse(x);
+  if (x is int) {
+    var masked = 0xffffffff & x;  // inferred uint32 type.
+    if (masked == x) return masked;
+  }
+  throw new ArgumentError('Not uint32: $x');
+}
+
+@NoInline()
 int zero() { return 0; }
+
+@NoInline()
 int one() { return 1; }
+
+@NoInline()
 int minus1() { return 0 - 1; }
+
+@NoInline()
+int minus2() { return 0 - 2; }
+
+@NoInline()
 int two() { return 2; }
+
+@NoInline()
 int three() { return 3; }
+
+@NoInline()
 int five() { return 5; }
+
+@NoInline()
 int minus5() { return 0 - 5; }
+
+@NoInline()
 int ninetyNine() { return 99; }
+
+@NoInline()
 int four99() { return 499; }
+
+@NoInline()
 int four99times99() { return 499 * 99; }
+
+@NoInline()
 int four99times99plus1() { return 499 * 99 + 1; }
 
+@NoInline()
 void addTest() {
   var m1 = 0 - 1;
   Expect.equals(0, 0 + 0);
+  Expect.equals(0, confuse(0) + 0);
+  Expect.equals(0, asNum(0) + 0);
+  Expect.equals(0, uint31(0) + 0);
+
   Expect.equals(m1, m1 + 0);
   Expect.equals(0, m1 + 1);
   Expect.equals(499, 400 + 99);
@@ -27,6 +85,7 @@
   Expect.equals(2, one() + one());
 }
 
+@NoInline()
 void subTest() {
   var m1 = 0 - 1;
   Expect.equals(0, 0 - 0);
@@ -38,6 +97,7 @@
   Expect.equals(0, one() - one());
 }
 
+@NoInline()
 void mulTest() {
   var m1 = 0 - 1;
   Expect.equals(0, 0 * 0);
@@ -49,23 +109,30 @@
   Expect.equals(49401, four99() * 99);
 }
 
+@NoInline()
 void divTest() {
   var m1 = 0.0 - 1.0;
   var m2 = 0 - 2;
   Expect.equals(1.0, 2 / 2);
   Expect.equals(m1, m2 / 2);
+  Expect.equals(m1, minus2() / 2);
   Expect.equals(0.5, 1 / 2);
   Expect.equals(499.0, 49401 / 99);
 
   Expect.equals(1.0, two() / 2);
   Expect.equals(1.0, 2 / two());
   Expect.equals(m1, m2 / two());
+  Expect.equals(m1, minus2() / two());
   Expect.equals(m1, two() / m2);
+  Expect.equals(m1, two() / minus2());
   Expect.equals(0.5, 1 / two());
   Expect.equals(0.5, one() / 2);
   Expect.equals(499.0, four99times99() / 99);
+
+  Expect.equals(1.5, confuse(150) / confuse(100));
 }
 
+@NoInline()
 void tdivTest() {
   var m1 = 0 - 1;
   var m2 = 0 - 2;
@@ -84,8 +151,62 @@
   Expect.equals(0, one() ~/ 2);
   Expect.equals(499, four99times99() ~/ 99);
   Expect.equals(499, four99times99plus1() ~/ 99);
+
+  Expect.equals(-33, -100 ~/ 3);
+  Expect.equals(-33, asNum(-100) ~/ 3);
+  Expect.equals(33, -100 ~/ -3);
+  Expect.equals(33, asNum(-100) ~/ -3);
+
+  // Signed int32 boundary is involved in optimizations.
+
+  Expect.equals(-0x80000000,  -0x80000000 ~/ 1.0);
+  Expect.equals(-0x80000000,  -0x80000000 ~/ 1.0000000000000001);
+  Expect.equals(-0x7fffffff,  -0x80000000 ~/ 1.0000000000000002);
+
+  Expect.equals(-0x80000000,  asNum(-0x80000000) ~/ 1.0);
+  Expect.equals(-0x80000000,  asNum(-0x80000000) ~/ 1.0000000000000001);
+  Expect.equals(-0x7fffffff,  asNum(-0x80000000) ~/ 1.0000000000000002);
+
+  Expect.equals(-0x80000000,  asNum(0x80000000) ~/ -1.0);
+  Expect.equals(-0x80000000,  asNum(0x80000000) ~/ -1.0000000000000001);
+  Expect.equals(-0x7fffffff,  asNum(0x80000000) ~/ -1.0000000000000002);
+
+  Expect.equals(0x7fffffff,  0x10000000 ~/ .12500000000000002);
+  Expect.equals(0x80000000,  0x10000000 ~/ .125);
+  Expect.equals(-0x7fffffff,  0x10000000 ~/ -.12500000000000002);
+  Expect.equals(-0x80000000,  0x10000000 ~/ -.125);
+
+  Expect.equals(0x7fffffff,  uint31(0x10000000) ~/ .12500000000000002);
+  Expect.equals(0x80000000,  uint31(0x10000000) ~/ .125);
+  Expect.equals(-0x7fffffff,  uint31(0x10000000) ~/ -.12500000000000002);
+  Expect.equals(-0x80000000,  uint31(0x10000000) ~/ -.125);
+
+  // These can be compiled to `(a / 2) | 0`.
+  Expect.equals(100,  uint31(200) ~/ 2);
+  Expect.equals(100,  uint32(200) ~/ 2);
+
+  Expect.equals(100,  asNum(200) ~/ 2);
+  Expect.equals(100,  confuse(200) ~/ 2);
+  Expect.equals(-100,  uint31(200) ~/ -2);
+  Expect.equals(-100,  uint32(200) ~/ -2);
+  Expect.equals(-100,  asNum(200) ~/ -2);
+  Expect.equals(-100,  confuse(200) ~/ -2);
+
+  // These can be compiled to `((a + b) / 2) | 0`.
+  Expect.equals(100,  (uint31(100) + uint31(100)) ~/ 2);
+  Expect.equals(0x7fffffff,  (uint31(0x7fffffff) + uint31(0x7fffffff)) ~/ 2);
+
+  // NaN and Infinity results are errors.
+  Expect.throws(() => -1 ~/ 0);
+  Expect.throws(() => 1.5 ~/ 0);
+  Expect.throws(() => 1e200 ~/ 1e-200);
+  Expect.throws(() => -1e200 ~/ 1e-200);
+  Expect.throws(() => 1e200 ~/ -1e-200);
+  Expect.throws(() => -1e200 ~/ -1e-200);
+  Expect.throws(() => double.NAN ~/ 2);
 }
 
+@NoInline()
 void modTest() {
   var m5 = 0 - 5;
   var m3 = 0 - 3;
@@ -103,6 +224,36 @@
   Expect.equals(2, five() % m3);
 }
 
+@NoInline()
+void remainderTest() {
+  var m5 = 0 - 5;
+  Expect.equals(2, confuse(5).remainder(3));
+  Expect.equals(0, confuse(49401).remainder(99));
+  Expect.equals(1, confuse(49402).remainder(99));
+  Expect.equals(-2, confuse(m5).remainder(3));
+  Expect.equals(2, confuse(5).remainder(-3));
+
+  Expect.equals(2, uint32(5).remainder(3));
+  Expect.equals(0, uint32(49401).remainder(99));
+  Expect.equals(1, uint32(49402).remainder(99));
+  Expect.equals(-2, (-5).remainder(uint32(3)));
+  Expect.equals(2, uint32(5).remainder(-3));
+
+  Expect.equals(2, 5.remainder(3));
+  Expect.equals(0, 49401.remainder(99));
+  Expect.equals(1, 49402.remainder(99));
+  Expect.equals(-2, (-5).remainder(3));
+  Expect.equals(2, 5.remainder(-3));
+
+  Expect.equals(2, five().remainder(3));
+  Expect.equals(2, 5.remainder(three()));
+  Expect.equals(0, four99times99().remainder(99));
+  Expect.equals(1, four99times99plus1().remainder(99));
+  Expect.equals(-2, minus5().remainder(3));
+  Expect.equals(2, five().remainder(-3));
+}
+
+@NoInline()
 void shlTest() {
   Expect.equals(2, 1 << 1);
   Expect.equals(8, 1 << 3);
@@ -110,17 +261,38 @@
 
   Expect.equals(10, five() << 1);
   Expect.equals(24, 3 << three());
+
+  Expect.equals(10, confuse(5) << 1);
+  Expect.equals(24, 3 << confuse(3));
+
+  Expect.equals(10, uint31(5) << 1);
+  Expect.equals(24, 3 << uint31(3));
+
+  Expect.equals(10, asNum(5) << 1);
+  Expect.equals(24, 3 << asNum(3));
 }
 
+@NoInline()
 void shrTest() {
   Expect.equals(1, 2 >> 1);
   Expect.equals(1, 8 >> 3);
   Expect.equals(3, 6 >> 1);
 
-  var x = 0 - ninetyNine();
   Expect.equals(6, ninetyNine() >> 4);
+  Expect.equals(6, confuse(99) >> 4);
+  Expect.equals(6, asNum(99) >> 4);
+  Expect.equals(6, uint31(99) >> 4);
+
+  Expect.equals(6, 99 >> 4);
+  Expect.equals(6, 99 >> confuse(4));
+  Expect.equals(6, 99 >> asNum(4));
+  Expect.equals(6, 99 >> uint31(4));
+
+  Expect.equals(0, uint31(1) >> 31);
+  Expect.equals(0, asNum(0xffffffff) >> 32);
 }
 
+@NoInline()
 void andTest() {
   Expect.equals(2, 10 & 3);
   Expect.equals(7, 15 & 7);
@@ -129,8 +301,12 @@
   Expect.equals(99, ninetyNine() & ninetyNine());
   Expect.equals(34, four99() & 42);
   Expect.equals(3, minus5() & 7);
+
+  Expect.equals(0,  uint31(0x7ffffffe) & uint31(1));
+  Expect.equals(0,  asNum(0x7ffffffe) & asNum(1));
 }
 
+@NoInline()
 void orTest() {
   Expect.equals(11, 10 | 3);
   Expect.equals(15, 15 | 7);
@@ -138,8 +314,13 @@
 
   Expect.equals(99, ninetyNine() | ninetyNine());
   Expect.equals(507, four99() | 42);
+
+  Expect.equals(11, asNum(10) | 3);
+  Expect.equals(15, asNum(15) | 7);
+  Expect.equals(10, asNum(10) | 10);
 }
 
+@NoInline()
 void xorTest() {
   Expect.equals(9, 10 ^ 3);
   Expect.equals(8, 15 ^ 7);
@@ -151,21 +332,26 @@
   Expect.equals(6, minus5() ^ -3);
 }
 
+@NoInline()
 void notTest() {
   Expect.equals(4, ~minus5());
 }
 
+@NoInline()
 void negateTest() {
   Expect.equals(minus5(), -5);
   Expect.equals(-5, -five());
   Expect.equals(5, -minus5());
-  var x = 3;
-  if (false) x = 5;
-  Expect.equals(-3, -x);
-  var y = -5;
-  Expect.equals(8, x - y);
+
+  Expect.equals(-3, -confuse(3));
+  Expect.equals(-3, -asNum(3));
+  Expect.equals(-3, -uint31(3));
+
+  Expect.equals(3, -confuse(-3));
+  Expect.equals(3, -asNum(-3));
 }
 
+@NoInline()
 void equalsTest() {
   // Equality of normal numbers is already well tested with "Expect.equals".
   Expect.equals(true, true == true);
@@ -209,6 +395,7 @@
   Expect.equals(false, null == falseValue);
 }
 
+@NoInline()
 void lessTest() {
   var m1 = minus1();
   Expect.equals(true, 1 < 2);
@@ -230,8 +417,13 @@
   Expect.equals(true, m1 < 0);
   Expect.equals(false, 0 < m1);
   Expect.equals(false, m1 < m1);
+
+  Expect.equals(true, minus1() < 0);
+  Expect.equals(false, 0 < minus1());
+  Expect.equals(false, minus1() < minus1());
 }
 
+@NoInline()
 void lessEqualTest() {
   var m1 = minus1();
   Expect.equals(true, 1 <= 2);
@@ -242,6 +434,14 @@
   Expect.equals(false, 1 <= 0);
   Expect.equals(true, 0 <= 0);
 
+  Expect.equals(true, confuse(1) <= 2);
+  Expect.equals(false, confuse(2) <= 1);
+  Expect.equals(true, confuse(1) <= 1);
+
+  Expect.equals(true, confuse(0) <= 1);
+  Expect.equals(false, confuse(1) <= 0);
+  Expect.equals(true, confuse(0) <= 0);
+
   Expect.equals(true, one() <= 2);
   Expect.equals(false, 2 <= one());
   Expect.equals(true, 1 <= one());
@@ -253,8 +453,13 @@
   Expect.equals(true, m1 <= 0);
   Expect.equals(false, 0 <= m1);
   Expect.equals(true, m1 <= m1);
+
+  Expect.equals(true, minus1() <= 0);
+  Expect.equals(false, 0 <= minus1());
+  Expect.equals(true, minus1() <= minus1());
 }
 
+@NoInline()
 void greaterTest() {
   var m1 = minus1();
   Expect.equals(false, 1 > 2);
@@ -276,8 +481,13 @@
   Expect.equals(false, m1 > 0);
   Expect.equals(true, 0 > m1);
   Expect.equals(false, m1 > m1);
+
+  Expect.equals(false, minus1() > 0);
+  Expect.equals(true, 0 > minus1());
+  Expect.equals(false, minus1() > minus1());
 }
 
+@NoInline()
 void greaterEqualTest() {
   var m1 = minus1();
   Expect.equals(false, 1 >= 2);
@@ -299,6 +509,10 @@
   Expect.equals(false, m1 >= 0);
   Expect.equals(true, 0 >= m1);
   Expect.equals(true, m1 >= m1);
+
+  Expect.equals(false, minus1() >= 0);
+  Expect.equals(true, 0 >= minus1());
+  Expect.equals(true, minus1() >= minus1());
 }
 
 void main() {
@@ -308,6 +522,7 @@
   divTest();
   tdivTest();
   modTest();
+  remainderTest();
   shlTest();
   shrTest();
   andTest();
diff --git a/tests/compiler/dart2js_extra/useful_error_message_1_test.dart b/tests/compiler/dart2js_extra/useful_error_message_1_test.dart
index 59a3bc913..07a6de0 100644
--- a/tests/compiler/dart2js_extra/useful_error_message_1_test.dart
+++ b/tests/compiler/dart2js_extra/useful_error_message_1_test.dart
@@ -7,8 +7,8 @@
 
 import "package:expect/expect.dart";
 
-@NoInline
-@AssumeDynamic
+@NoInline()
+@AssumeDynamic()
 confuse(x) => x;
 
 class CCCC {
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index 2066a92..dfe56d3 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -6,12 +6,12 @@
 *: Skip
 
 [ $compiler == dart2js ]
-bound_closure_super_test: Fail
 call_on_native_class_test: CompileTimeError # Issue 14813
 native_no_such_method_exception4_frog_test: CompileTimeError # Issue 9631
 native_no_such_method_exception5_frog_test: CompileTimeError # Issue 9631
 
-[ $compiler == dart2js ]
+[ $compiler == dart2js && $cps_ir == false ]
+bound_closure_super_test: Fail
 fake_thing_test: Fail # Issue 13010
 
 [ $compiler == dart2js && $minified ]
@@ -22,10 +22,5 @@
 
 [ $compiler == dart2js && $cps_ir ]
 native_exception_test: RuntimeError # Issue 24421
-native_method_inlining_test: RuntimeError # Please triage this failure.
-native_no_such_method_exception3_frog_test: RuntimeError # Please triage this failure.
 optimization_hints_test: RuntimeError # Please triage this failure.
-subclassing_constructor_1_test: RuntimeError # Please triage this failure.
 subclassing_constructor_2_test: RuntimeError # Please triage this failure.
-subclassing_super_field_1_test: RuntimeError # Please triage this failure.
-subclassing_super_field_2_test: RuntimeError # Please triage this failure.
diff --git a/tests/compiler/dart2js_native/js_constant_test.dart b/tests/compiler/dart2js_native/js_constant_test.dart
new file mode 100644
index 0000000..19b2e6f
--- /dev/null
+++ b/tests/compiler/dart2js_native/js_constant_test.dart
@@ -0,0 +1,44 @@
+// 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:_foreign_helper' show JS;
+import "package:expect/expect.dart";
+
+// Negative constant numbers must be generated as negation, not just a literal
+// with a sign, i.e.
+//
+//     (-5).toString()
+//
+// not
+//
+//     -5 .toString()
+//
+// The unparethesized version is `-(5 .toString())`, which creates the string
+// `"5"`, then converts it to a number for negation, giving a number result
+// instead of a string result.
+
+@NoInline()
+checkString(r) {
+  Expect.isTrue(r is String,
+      'Expected string, found ${r} of type ${r.runtimeType}');
+}
+
+test1() {
+  checkString(JS('', '#.toString()', -5));
+}
+
+test2() {
+  checkString(JS('', '#.toString()', -1.5));
+}
+
+test3() {
+  checkString(JS('', '#.toString()', -0.0));
+}
+
+
+main() {
+  test1();
+  test2();
+  test3();
+}
diff --git a/tests/corelib/apply_test.dart b/tests/corelib/apply_test.dart
index e06cf6d..0ad85b1 100644
--- a/tests/corelib/apply_test.dart
+++ b/tests/corelib/apply_test.dart
@@ -25,14 +25,9 @@
   int call(int x, int y) => x + y;
 }
 
-confuse() {
-  try {
-    throw [Function.apply];
-  } catch (e) {
-    return e[0];
-  }
-  return null;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 main() {
   testMap(res, func, map) {
@@ -62,7 +57,7 @@
   testList(42, cfoo, [32]);
 
   // Test that apply works even with a different name.
-  var app = confuse();
+  var app = confuse(Function.apply);
   Expect.equals(42, app(test2, [22, 20]));
 
   // Test that apply can itself be applied.
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 9bda275..88b3ccd 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -2,7 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 bool_from_environment2_test: Skip
 bool_from_environment_test: Skip
 from_environment_const_type_test: Skip
@@ -14,18 +14,18 @@
 string_from_environment3_test: Skip
 string_from_environment_test: Skip
 
-[ $compiler == none ]
+[ ($compiler == none || $compiler == precompiler) ]
 unicode_test: Fail        # Bug 6706
 compare_to2_test: Fail    # Bug 4018
 
 symbol_test/01: Fail, Pass # bug 11669
 
 # #void should be a valid symbol.
-[ $compiler == none || $compiler == dart2js ]
+[ ($compiler == none || $compiler == precompiler) || $compiler == dart2js ]
 symbol_reserved_word_test/02: CompileTimeError # bug 20191
 symbol_reserved_word_test/05: CompileTimeError # bug 20191
 
-[ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 symbol_reserved_word_test/02: RuntimeError # bug 20191 / dartium/drt cannot detect CompileTimeErrors
 symbol_reserved_word_test/05: RuntimeError # bug 20191 / dartium/drt cannot detect CompileTimeErrors
 
@@ -42,27 +42,27 @@
 
 # With the exception of 'void', const Symbol() should not accept reserved
 # words.
-[ $compiler == none || $compiler == dart2js ]
+[ ($compiler == none || $compiler == precompiler) || $compiler == dart2js ]
 symbol_reserved_word_test/04: MissingCompileTimeError # bug 11669, 19972
 symbol_reserved_word_test/07: MissingCompileTimeError # bug 11669, 19972
 symbol_reserved_word_test/10: MissingCompileTimeError # bug 11669, 19972
 
-[ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 symbol_reserved_word_test/04: Fail # bug 11669, 19972 / dartium/drt cannot detect CompileTimeErrors
 symbol_reserved_word_test/07: Fail # bug 11669, 19972 / dartium/drt cannot detect CompileTimeErrors
 symbol_reserved_word_test/10: Fail # bug 11669, 19972 / dartium/drt cannot detect CompileTimeErrors
 
 # With the exception of 'void', new Symbol() should not accept reserved words.
-[ $compiler == none ]
+[ ($compiler == none || $compiler == precompiler) ]
 symbol_reserved_word_test/06: RuntimeError # bug 11669
 symbol_reserved_word_test/09: RuntimeError # bug 11669
 symbol_reserved_word_test/12: RuntimeError # bug 11669
 
-[ $compiler == none && $runtime != dartium && $runtime != drt && $runtime != ContentShellOnAndroid ]
+[ ($compiler == none || $compiler == precompiler) && $runtime != dartium && $runtime != drt && $runtime != ContentShellOnAndroid ]
 symbol_test/02: MissingCompileTimeError # bug 11669
 symbol_test/03: MissingCompileTimeError # bug 11669
 
-[ $compiler == none ]
+[ ($compiler == none || $compiler == precompiler) ]
 symbol_test/none: Fail # bug 11669
 symbol_operator_test/03: Fail # bug 11669
 string_case_test/01: Fail # Bug 18061
@@ -70,10 +70,10 @@
 iterable_return_type_test/01: RuntimeError # Issue 13646
 iterable_return_type_test/02: RuntimeError # Issue 13646
 
-[ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 main_test: Fail  # Dartium needs to check for both main() and main(args).
 
-[ $compiler == none && $runtime == ContentShellOnAndroid ]
+[ ($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
 core_runtime_types_test: Pass, Fail # Issue 20525
 
 [ $runtime == ff || $runtime == jsshell ]
@@ -139,35 +139,6 @@
 string_case_test/02: Fail, OK  # Bug in dartium version of V8.
 string_case_test/03: Fail, OK  # Bug in dartium version of V8.
 
-[ $compiler == dartanalyzer ]
-from_environment_const_type_test: Skip # The -D option that defines a constant
-# for the Dart vm is not accepted by the deprecated java dartanalyzer.
-int_parse_radix_test: Fail, OK # Test contains errors but doesn’t mark them as expected
-list_insert_test: Fail, OK # Test contains errors but doesn’t mark them as expected
-list_removeat_test: Fail, OK # Test contains errors but doesn’t mark them as expected
-
-# Issue 16391. These tests are supposed to produce a compile time
-# error in checked mode, but they don't:
-[ $compiler == dartanalyzer && $checked ]
-from_environment_const_type_test/02: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/03: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/04: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/06: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/07: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/08: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/09: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/11: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/12: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/13: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/14: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/16: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/02: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/03: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/04: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/06: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/07: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/08: MissingCompileTimeError # Issue 16391
-
 # Analyzer's implementation of fromEnvironment assumes that undefined
 # environment variables have an unspecified value (rather than being
 # null) because it is expected that the user will supply a value when
@@ -185,8 +156,6 @@
 int_parse_radix_test: fail
 list_insert_test: fail
 list_removeat_test: fail
-
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 hash_set_type_check_test: StaticWarning, OK # Tests failing type tests.
 error_stack_trace_test: StaticWarning, OK # Test generates errors on purpose.
 iterable_element_at_test: StaticWarning, OK # Test generates errors on purpose.
@@ -201,10 +170,10 @@
 # The regexp tests are not verified to work on non d8/vm platforms yet.
 regexp/*: Skip
 
-[ $runtime == vm ]
+[ ($runtime == vm || $runtime == dart_precompiled) ]
 regexp/global_test: Skip # Timeout. Issue 21709 and 21708
 
-[ $runtime != vm && $compiler != dartanalyzer && $compiler != dart2analyzer]
+[ $runtime != vm && $compiler != dart2analyzer]
 package_resource_test: RuntimeError # Issue 23825 (not implemented yet).
 data_resource_test: RuntimeError # Issue 23825 (not implemented yet).
 file_resource_test: Skip, OK # VM specific test, uses dart:io.
@@ -213,7 +182,7 @@
 [ $mode == debug ]
 regexp/pcre_test: Pass, Slow # Timeout. Issue 22008
 
-[ $runtime == vm && $arch == simarmv5te ]
+[ ($runtime == vm || $runtime == dart_precompiled) && $arch == simarmv5te ]
 int_parse_radix_test/*: Pass, Slow
 big_integer_parsed_mul_div_vm_test: Pass, Slow
 
@@ -232,7 +201,7 @@
 map_values4_test: RuntimeError # Please triage this failure.
 package_resource_test: Crash # (await for(var byteSlice in resource.openRead()){streamBytes.addAll(byteSlice);}): await for
 regexp/pcre_test: Crash # Stack Overflow in LoopHierarchy.
-symbol_operator_test/03: RuntimeError # Please triage this failure.
+symbol_operator_test/03: RuntimeError # Issue 24878
 symbol_reserved_word_test/03: Pass # Please triage this failure.
 symbol_reserved_word_test/06: RuntimeError # Please triage this failure.
 symbol_reserved_word_test/09: RuntimeError # Please triage this failure.
@@ -241,3 +210,10 @@
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 regexp/pcre_test: Crash # Stack Overflow
+
+[ ($noopt || $compiler == precompiler) ]
+apply3_test: CompileTimeError # Imports dart:mirrors
+regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
+big_integer_huge_mul_vm_test: Pass, Timeout # --no_intrinsify
+big_integer_parsed_mul_div_vm_test: Pass, Timeout # --no_intrinsify
+int_parse_radix_test: Pass, Timeout # --no_intrinsify
diff --git a/tests/corelib/data_uri_test.dart b/tests/corelib/data_uri_test.dart
new file mode 100644
index 0000000..1a21be1
--- /dev/null
+++ b/tests/corelib/data_uri_test.dart
@@ -0,0 +1,252 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:convert";
+import "dart:typed_data";
+
+main() {
+  testMediaType();
+
+  testRoundTrip("");
+  testRoundTrip("a");
+  testRoundTrip("ab");
+  testRoundTrip("abc");
+  testRoundTrip("abcd");
+  testRoundTrip("Content with special%25 characters: # ? = % # ? = %");
+  testRoundTrip("blåbærgrød", UTF8);
+  testRoundTrip("blåbærgrød", LATIN1);
+
+  testUtf8Encoding("\u1000\uffff");
+  testBytes();
+  testInvalidCharacters();
+  testErrors();
+}
+
+void testMediaType() {
+  for (var mimeType in ["", "text/plain", "text/javascript"]) {
+    for (var charset in ["", ";charset=US-ASCII", ";charset=UTF-8"]) {
+      for (var base64 in ["", ";base64"]) {
+        bool isBase64 = base64.isNotEmpty;
+        var text = "data:$mimeType$charset$base64,";
+        var uri = UriData.parse(text);
+
+        String expectedCharset =
+            charset.isEmpty ? "US-ASCII" : charset.substring(9);
+        String expectedMimeType =
+            mimeType.isEmpty ? "text/plain" : mimeType;
+
+        Expect.equals(text, "$uri");
+        Expect.equals(expectedMimeType, uri.mimeType);
+        Expect.equals(expectedCharset, uri.charset);
+        Expect.equals(isBase64, uri.isBase64);
+      }
+    }
+  }
+}
+
+void testRoundTrip(String content, [Encoding encoding]) {
+  UriData dataUri =
+      new UriData.fromString(content, encoding: encoding);
+  Expect.isFalse(dataUri.isBase64);
+  Uri uri = dataUri.uri;
+  expectUriEquals(new Uri.dataFromString(content, encoding: encoding), uri);
+
+  if (encoding != null) {
+    UriData dataUriParams = new UriData.fromString(
+        content, parameters: {"charset" : encoding.name});
+    Expect.equals("$dataUri", "$dataUriParams");
+  }
+
+  Expect.equals(encoding ?? ASCII, Encoding.getByName(dataUri.charset));
+  Expect.equals(content, dataUri.contentAsString(encoding: encoding));
+  Expect.equals(content, dataUri.contentAsString());
+  Expect.equals(content, (encoding ?? ASCII).decode(dataUri.contentAsBytes()));
+
+  uri = dataUri.uri;
+  Expect.equals(uri.toString(), dataUri.toString());
+  Expect.equals(dataUri.toString(), new UriData.fromUri(uri).toString());
+
+  dataUri = new UriData.fromBytes(content.codeUnits);
+  Expect.listEquals(content.codeUnits, dataUri.contentAsBytes());
+  Expect.equals(content, dataUri.contentAsString(encoding: LATIN1));
+
+  uri = dataUri.uri;
+  Expect.equals(uri.toString(), dataUri.toString());
+  Expect.equals(dataUri.toString(), new UriData.fromUri(uri).toString());
+  // Check that the URI is properly normalized.
+  expectUriEquals(uri, Uri.parse("$uri"));
+}
+
+void testUtf8Encoding(String content) {
+  UriData uri = new UriData.fromString(content, encoding: UTF8);
+  Expect.equals(content, uri.contentAsString(encoding: UTF8));
+  Expect.listEquals(UTF8.encode(content), uri.contentAsBytes());
+}
+
+void testInvalidCharacters() {
+  // SPACE, CTL and tspecial, plus '%' and '#' (URI gen-delim)
+  // This contains all ASCII character that are not valid in attribute/value
+  // parts.
+  var invalid =
+    '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x7f'
+    ' ()<>@,;:"/[]?=%#\x80\u{1000}\u{10000}';
+  var invalidNoSlash = invalid.replaceAll('/', '');
+  var dataUri = new UriData.fromString(
+      invalid,
+      encoding: UTF8,
+      mimeType: "$invalidNoSlash/$invalidNoSlash",
+      parameters: {invalid: invalid});
+
+  Expect.equals(invalid, dataUri.contentAsString());
+  Expect.equals("$invalidNoSlash/$invalidNoSlash", dataUri.mimeType);
+  Expect.equals(invalid, dataUri.parameters[invalid]);
+
+  var uri = dataUri.uri;
+  Expect.equals("$uri", "$dataUri");
+  expectUriEquals(uri, Uri.parse("$uri"));  // Check that it's canonicalized.
+  Expect.equals("$dataUri", new UriData.fromUri(uri).toString());
+}
+
+void testBytes() {
+  void testList(List<int> list) {
+    var dataUri = new UriData.fromBytes(list);
+    Expect.equals("application/octet-stream", dataUri.mimeType);
+    Expect.isTrue(dataUri.isBase64);
+    Expect.listEquals(list, dataUri.contentAsBytes());
+
+    dataUri = new UriData.fromBytes(list, percentEncoded: true);
+    Expect.equals("application/octet-stream", dataUri.mimeType);
+    Expect.isFalse(dataUri.isBase64);
+    Expect.listEquals(list, dataUri.contentAsBytes());
+
+    var string = new String.fromCharCodes(list);
+
+    dataUri = new UriData.fromString(string, encoding: LATIN1);
+    Expect.equals("text/plain", dataUri.mimeType);
+    Expect.isFalse(dataUri.isBase64);
+    Expect.listEquals(list, dataUri.contentAsBytes());
+
+    dataUri =
+        new UriData.fromString(string, encoding: LATIN1, base64: true);
+    Expect.equals("text/plain", dataUri.mimeType);
+    Expect.isTrue(dataUri.isBase64);
+    Expect.listEquals(list, dataUri.contentAsBytes());
+  }
+
+  void testLists(List<int> list) {
+    testList(list);
+    for (int i = 0; i < 27; i++) {
+      testList(list.sublist(i, i + i));  // All lengths from 0 to 27.
+    }
+  }
+
+  var bytes = new Uint8List(512);
+  for (int i = 0; i < bytes.length; i++) {
+    bytes[i] = i;
+  }
+  testLists(bytes);
+  testLists(new List.from(bytes));
+  testLists(new List.unmodifiable(bytes));
+}
+
+bool badArgument(e) => e is ArgumentError;
+bool badFormat(e) => e is FormatException;
+
+void testErrors() {
+  // Invalid constructor parameters.
+  Expect.throws(() { new UriData.fromBytes([], mimeType: "noslash"); },
+                badArgument);
+  Expect.throws(() { new UriData.fromBytes([257]); },
+                badArgument);
+  Expect.throws(() { new UriData.fromBytes([-1]); },
+                badArgument);
+  Expect.throws(() { new UriData.fromBytes([0x10000000]); },
+                badArgument);
+  Expect.throws(() { new UriData.fromString("", mimeType: "noslash"); },
+                badArgument);
+
+  Expect.throws(() { new Uri.dataFromBytes([], mimeType: "noslash"); },
+                badArgument);
+  Expect.throws(() { new Uri.dataFromBytes([257]); },
+                badArgument);
+  Expect.throws(() { new Uri.dataFromBytes([-1]); },
+                badArgument);
+  Expect.throws(() { new Uri.dataFromBytes([0x10000000]); },
+                badArgument);
+  Expect.throws(() { new Uri.dataFromString("", mimeType: "noslash"); },
+                badArgument);
+
+  // Empty parameters allowed, not an error.
+  var uri = new UriData.fromString("", mimeType: "", parameters: {});
+  Expect.equals("data:,", "$uri");
+  // Empty parameter key or value is an error.
+  Expect.throws(() =>  new UriData.fromString("", parameters: {"": "X"}),
+                badArgument);
+  Expect.throws(() =>  new UriData.fromString("", parameters: {"X": ""}),
+                badArgument);
+
+  // Not recognizing charset is an error.
+  uri = UriData.parse("data:;charset=arglebargle,X");
+  Expect.throws(() {
+    uri.contentAsString();
+  });
+  // Doesn't throw if we specify the encoding.
+  Expect.equals("X", uri.contentAsString(encoding: ASCII));
+
+  // Parse format.
+  Expect.throws(() { UriData.parse("notdata:,");}, badFormat);
+  Expect.throws(() { UriData.parse("text/plain,noscheme");}, badFormat);
+  Expect.throws(() { UriData.parse("data:noseparator");}, badFormat);
+  Expect.throws(() { UriData.parse("data:noslash,text");}, badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;noequals,text");},
+                badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;knocomma=");},
+                badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;k=v;nocomma");},
+                badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;k=nocomma");},
+                badFormat);
+  Expect.throws(() { UriData.parse("data:type/sub;k=v;base64");},
+                badFormat);
+
+  // Invalid base64 format (only detected when decodeing).
+  for (var a = 0; a <= 4; a++) {
+    for (var p = 0; p <= 4; p++) {
+      // Base-64 encoding must have length divisible by four and no more
+      // than two padding characters at the end.
+      if (p < 3 && (a + p) % 4 == 0) continue;
+      uri = UriData.parse("data:;base64," + "A" * a + "=" * p);
+      Expect.throws(uri.contentAsBytes, badFormat);
+    }
+  }
+  // Invalid base64 encoding: padding not at end.
+  uri = UriData.parse("data:;base64,AA=A");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,A=AA");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,=AAA");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,A==A");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,==AA");
+  Expect.throws(uri.contentAsBytes, badFormat);
+  uri = UriData.parse("data:;base64,===A");
+  Expect.throws(uri.contentAsBytes, badFormat);
+}
+
+/// Checks that two [Uri]s are exactly the same.
+expectUriEquals(Uri expect, Uri actual) {
+  Expect.equals(expect.scheme, actual.scheme, "scheme");
+  Expect.equals(expect.hasAuthority, actual.hasAuthority, "hasAuthority");
+  Expect.equals(expect.userInfo, actual.userInfo, "userInfo");
+  Expect.equals(expect.host, actual.host, "host");
+  Expect.equals(expect.hasPort, actual.hasPort, "hasPort");
+  Expect.equals(expect.port, actual.port, "port");
+  Expect.equals(expect.port, actual.port, "port");
+  Expect.equals(expect.hasQuery, actual.hasQuery, "hasQuery");
+  Expect.equals(expect.query, actual.query, "query");
+  Expect.equals(expect.hasFragment, actual.hasFragment, "hasFragment");
+  Expect.equals(expect.fragment, actual.fragment, "fragment");
+}
diff --git a/tests/corelib/date_time4_test.dart b/tests/corelib/date_time4_test.dart
index 7e936ff..46c1c10 100644
--- a/tests/corelib/date_time4_test.dart
+++ b/tests/corelib/date_time4_test.dart
@@ -6,11 +6,21 @@
 
 // Test fromString with 6 digits after the decimal point.
 
+bool get supportsMicroseconds =>
+    new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
+
 main() {
+  if (supportsMicroseconds) {
+    testMicrosecondPrecision();
+  } else {
+    testMillisecondPrecision();
+  }
+}
+
+void testMillisecondPrecision() {
   // We only support milliseconds. If the user supplies more data (the "51"
   // here), we round.
-  // If (eventually) we support more than just milliseconds this test could
-  // fail. Please update the test in this case.
   DateTime dt1 = DateTime.parse("1999-01-02 23:59:59.999519");
   Expect.equals(1999, dt1.year);
   Expect.equals(1, dt1.month);
@@ -48,5 +58,48 @@
   Expect.equals(13, dt1.second);
   Expect.equals(752, dt1.millisecond);
   Expect.equals(true, dt1.isUtc);
-  
+}
+
+void testMicrosecondPrecision() {
+  DateTime dt1 = DateTime.parse("1999-01-02 23:59:59.999519");
+  Expect.equals(1999, dt1.year);
+  Expect.equals(1, dt1.month);
+  Expect.equals(2, dt1.day);
+  Expect.equals(23, dt1.hour);
+  Expect.equals(59, dt1.minute);
+  Expect.equals(59, dt1.second);
+  Expect.equals(999, dt1.millisecond);
+  Expect.equals(519, dt1.microsecond);
+  Expect.equals(false, dt1.isUtc);
+  dt1 = DateTime.parse("1999-01-02 23:58:59.999519Z");
+  Expect.equals(1999, dt1.year);
+  Expect.equals(1, dt1.month);
+  Expect.equals(2, dt1.day);
+  Expect.equals(23, dt1.hour);
+  Expect.equals(58, dt1.minute);
+  Expect.equals(59, dt1.second);
+  Expect.equals(999, dt1.millisecond);
+  Expect.equals(519, dt1.microsecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009411Z");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(9, dt1.day);
+  Expect.equals(9, dt1.hour);
+  Expect.equals(9, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(411, dt1.microsecond);
+  Expect.equals(true, dt1.isUtc);
+  String svnDate = "2012-03-30T04:28:13.752341Z";
+  dt1 = DateTime.parse(svnDate);
+  Expect.equals(2012, dt1.year);
+  Expect.equals(3, dt1.month);
+  Expect.equals(30, dt1.day);
+  Expect.equals(4, dt1.hour);
+  Expect.equals(28, dt1.minute);
+  Expect.equals(13, dt1.second);
+  Expect.equals(752, dt1.millisecond);
+  Expect.equals(341, dt1.microsecond);
+  Expect.equals(true, dt1.isUtc);
 }
diff --git a/tests/corelib/date_time_parse_test.dart b/tests/corelib/date_time_parse_test.dart
index 2f48923..85f183a 100644
--- a/tests/corelib/date_time_parse_test.dart
+++ b/tests/corelib/date_time_parse_test.dart
@@ -9,10 +9,19 @@
   Expect.equals(expected, actual);  // Only checks if they are at the same time.
   Expect.equals(expected.isUtc, actual.isUtc);
 }
+
+bool get supportsMicroseconds =>
+    new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
 main() {
   check(new DateTime(2012, 02, 27, 13, 27), "2012-02-27 13:27:00");
-  check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123),
-        "2012-02-27 13:27:00.123456z");
+  if (supportsMicroseconds) {
+    check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
+          "2012-02-27 13:27:00.123456z");
+  } else {
+    check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
+          "2012-02-27 13:27:00.123z");
+  }
   check(new DateTime(2012, 02, 27, 13, 27), "20120227 13:27:00");
   check(new DateTime(2012, 02, 27, 13, 27), "20120227T132700");
   check(new DateTime(2012, 02, 27), "20120227");
@@ -31,8 +40,15 @@
   check(new DateTime.utc(2015, 02, 14, 13, 0, 0, 0),
         "2015-02-15T00:00:00+11:00");
 
-  check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 501),
-        "2015-02-15T00:00:00.5005Z");
-  check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 512),
-        "2015-02-15T00:00:00.5115Z");
+  if (supportsMicroseconds) {
+    check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 500, 500),
+        "2015-02-15T00:00:00.500500Z");
+    check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 511, 500),
+        "2015-02-15T00:00:00.511500Z");
+  } else {
+    check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 501),
+        "2015-02-15T00:00:00.501Z");
+    check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 512),
+        "2015-02-15T00:00:00.512Z");
+  }
 }
diff --git a/tests/corelib/date_time_test.dart b/tests/corelib/date_time_test.dart
index 79dcdd9..efb2206 100644
--- a/tests/corelib/date_time_test.dart
+++ b/tests/corelib/date_time_test.dart
@@ -6,6 +6,9 @@
 
 // Dart test program for DateTime.
 
+bool get supportsMicroseconds =>
+    new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
 // Identical to _MAX_MILLISECONDS_SINCE_EPOCH in date_time.dart
 const int _MAX_MILLISECONDS = 8640000000000000;
 
@@ -26,13 +29,25 @@
   Expect.isFalse(t1.isUtc);
 }
 
-void testValue() {
+void testMillisecondsSinceEpoch() {
   var dt1 = new DateTime.now();
   var millisecondsSinceEpoch = dt1.millisecondsSinceEpoch;
   var dt2 = new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
   Expect.equals(millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
 }
 
+void testMicrosecondsSinceEpoch() {
+  var dt1 = new DateTime.fromMillisecondsSinceEpoch(1);
+  var microsecondsSinceEpoch = dt1.microsecondsSinceEpoch;
+  var dt2 = new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch);
+  Expect.equals(microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
+
+  dt1 = new DateTime.now();
+  microsecondsSinceEpoch = dt1.microsecondsSinceEpoch;
+  dt2 = new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch);
+  Expect.equals(microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
+}
+
 void testFarAwayDates() {
   DateTime dt =
       new DateTime.fromMillisecondsSinceEpoch(1000000000000001, isUtc: true);
@@ -43,6 +58,7 @@
   Expect.equals(46, dt.minute);
   Expect.equals(40, dt.second);
   Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001, isUtc: true);
   Expect.equals(-29719, dt.year);
   Expect.equals(4, dt.month);
@@ -51,6 +67,7 @@
   Expect.equals(13, dt.minute);
   Expect.equals(19, dt.second);
   Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   // Same with local zone.
   dt = new DateTime.fromMillisecondsSinceEpoch(1000000000000001);
   Expect.equals(33658, dt.year);
@@ -62,6 +79,7 @@
   Expect.equals(true, dt.minute % 15 == 46 % 15);
   Expect.equals(40, dt.second);
   Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001);
   Expect.equals(-29719, dt.year);
   Expect.equals(4, dt.month);
@@ -72,6 +90,52 @@
   Expect.equals(true, dt.minute % 15 == 13);
   Expect.equals(19, dt.second);
   Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
+  if (!supportsMicroseconds) return;
+  dt =
+      new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001, isUtc: true);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(27, dt.day);
+  Expect.equals(1, dt.hour);
+  Expect.equals(46, dt.minute);
+  Expect.equals(40, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(
+      -1000000000000000001, isUtc: true);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(5, dt.day);
+  Expect.equals(22, dt.hour);
+  Expect.equals(13, dt.minute);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(999, dt.microsecond);
+  // Same with local zone.
+  dt = new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(true, dt.day == 27 || dt.day == 26);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 46 % 15);
+  Expect.equals(40, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(true, 5 == dt.day || 6 == dt.day);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 13);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(999, dt.microsecond);
 }
 
 void testEquivalentYears() {
@@ -86,6 +150,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-63108000000, isUtc: true);
   Expect.equals(1968, dt.year);
   Expect.equals(1, dt.month);
@@ -94,6 +159,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-94644000000, isUtc: true);
   Expect.equals(1967, dt.year);
   Expect.equals(1, dt.month);
@@ -102,6 +168,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-126180000000, isUtc: true);
   Expect.equals(1966, dt.year);
   Expect.equals(1, dt.month);
@@ -110,6 +177,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-157716000000, isUtc: true);
   Expect.equals(1965, dt.year);
   Expect.equals(1, dt.month);
@@ -118,6 +186,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-2177402400000, isUtc: true);
   Expect.equals(1901, dt.year);
   Expect.equals(1, dt.month);
@@ -126,6 +195,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-5333076000000, isUtc: true);
   Expect.equals(1801, dt.year);
   Expect.equals(1, dt.month);
@@ -134,6 +204,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-8520285600000, isUtc: true);
   Expect.equals(1700, dt.year);
   Expect.equals(1, dt.month);
@@ -142,6 +213,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-14831719200000, isUtc: true);
   Expect.equals(1500, dt.year);
   Expect.equals(1, dt.month);
@@ -150,6 +222,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-59011408800000, isUtc: true);
   Expect.equals(100, dt.year);
   Expect.equals(1, dt.month);
@@ -158,6 +231,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-62011408800000, isUtc: true);
   Expect.equals(4, dt.year);
   Expect.equals(12, dt.month);
@@ -166,6 +240,7 @@
   Expect.equals(40, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-64011408800000, isUtc: true);
   Expect.equals(-59, dt.year);
   Expect.equals(7, dt.month);
@@ -174,6 +249,7 @@
   Expect.equals(6, dt.minute);
   Expect.equals(40, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   final int SECONDS_YEAR_2035 = 2051222400;
   dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 + 1,
                                            isUtc: true);
@@ -184,6 +260,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 - 1,
                                            isUtc: true);
   Expect.equals(2034, dt.year);
@@ -193,6 +270,8 @@
   Expect.equals(59, dt.minute);
   Expect.equals(59, dt.second);
   Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
   dt = new DateTime.utc(2035, 1, 1, 0, 0, 0, 1);
   Expect.equals(SECONDS_YEAR_2035 * 1000 + 1, dt.millisecondsSinceEpoch);
   dt = new DateTime.utc(2034, 12, 31, 23, 59, 59, 999);
@@ -211,6 +290,8 @@
                       (2034 == dt.year && 12 == dt.month && 31 == dt.day));
   Expect.equals(59, dt.second);
   Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
   dt2 = new DateTime(
       dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
       dt.millisecond);
@@ -223,6 +304,8 @@
   Expect.equals(20, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
   // Internally this will use the maximum value for the native calls.
   dt = new DateTime(2036, 7, 18, 13, 20);
   Expect.equals(2036, dt.year);
@@ -232,7 +315,46 @@
   Expect.equals(20, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   Expect.equals("2036-07-18 13:20:00.000", dt.toString());
+
+  if (!supportsMicroseconds) return;
+
+  dt = new DateTime.utc(2035, 1, 1, 0, 0, 0, 0, 1);
+  Expect.equals(SECONDS_YEAR_2035 * 1000000 + 1, dt.microsecondsSinceEpoch);
+  dt = new DateTime.utc(2034, 12, 31, 23, 59, 59, 999, 999);
+  Expect.equals(SECONDS_YEAR_2035 * 1000000 - 1, dt.microsecondsSinceEpoch);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(SECONDS_YEAR_2035 * 1000000 + 1);
+  Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
+                      (2034 == dt.year && 12 == dt.month && 31 == dt.day));
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
+  dt2 = new DateTime(
+      dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
+      dt.millisecond, dt.microsecond);
+  Expect.equals(dt.microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(SECONDS_YEAR_2035 * 1000000 - 1);
+  Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
+                      (2034 == dt.year && 12 == dt.month && 31 == dt.day));
+  Expect.equals(59, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(999, dt.microsecond);
+
+  dt2 = new DateTime(
+      dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
+      dt.millisecond, dt.microsecond);
+  Expect.equals(dt.millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(2100000000 * 1000000,
+      isUtc: true);
+  Expect.equals(2036, dt.year);
+  Expect.equals(7, dt.month);
+  Expect.equals(18, dt.day);
+  Expect.equals(13, dt.hour);
+  Expect.equals(20, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
 }
 
 void testExtremes() {
@@ -245,6 +367,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
   Expect.equals(-271821, dt.year);
   Expect.equals(4, dt.month);
@@ -253,6 +376,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   // Make sure that we can build the extreme dates in local too.
   dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
   dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
@@ -280,6 +404,35 @@
   dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
   Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
                                    dt.hour, dt.minute, 0, -1));
+
+  if (!supportsMicroseconds) return;
+
+  dt = new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(-_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      _MAX_MILLISECONDS * 1000 + 1, isUtc: true));
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      -_MAX_MILLISECONDS * 1000 - 1, isUtc: true));
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      _MAX_MILLISECONDS * 1000 + 1));
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      -_MAX_MILLISECONDS * 1000 - 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
+  Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
+                               dt.hour, dt.minute, 0, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
+  Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
+                                   dt.hour, dt.minute, 0, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
+  Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
+                               dt.hour, dt.minute, 0, 0, -1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
+  Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
+                                   dt.hour, dt.minute, 0, 0, -1));
 }
 
 void testUTCGetters() {
@@ -291,6 +444,7 @@
   Expect.equals(58, dt.minute);
   Expect.equals(35, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   Expect.equals(true, dt.isUtc);
   Expect.equals(1305140315000, dt.millisecondsSinceEpoch);
   dt = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
@@ -301,12 +455,26 @@
   Expect.equals(13, dt.minute);
   Expect.equals(20, dt.second);
   Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
+  if (!supportsMicroseconds) return;
+
+  dt = new DateTime.fromMicrosecondsSinceEpoch(-9999999999, isUtc: true);
+  Expect.equals(1969, dt.year);
+  Expect.equals(12, dt.month);
+  Expect.equals(31, dt.day);
+  Expect.equals(21, dt.hour);
+  Expect.equals(13, dt.minute);
+  Expect.equals(20, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
 }
 
 void testLocalGetters() {
   var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
   var dt2 = new DateTime.utc(dt1.year, dt1.month, dt1.day,
-                         dt1.hour, dt1.minute, dt1.second, dt1.millisecond);
+                         dt1.hour, dt1.minute, dt1.second, dt1.millisecond,
+                         dt1.microsecond);
   Duration zoneOffset = dt1.difference(dt2);
   Expect.equals(true, zoneOffset.inDays == 0);
   Expect.equals(true, zoneOffset.inHours.abs() <= 12);
@@ -321,34 +489,40 @@
                 ((dt1.minute - dt2.minute).abs() == 15));
   Expect.equals(dt1.second, dt2.second);
   Expect.equals(dt1.millisecond, dt2.millisecond);
+  Expect.equals(dt1.microsecond, dt2.microsecond);
 }
 
 void testConstructors() {
-  var dt0 = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0);
-  var dt0b = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0).toLocal();
+  var dt0 = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0, 0);
+  var dt0b = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0, 0).toLocal();
   Expect.equals(1305140315000, dt0.millisecondsSinceEpoch);
   var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
   Expect.equals(dt1.millisecondsSinceEpoch, dt0.millisecondsSinceEpoch);
+  Expect.equals(dt1.microsecondsSinceEpoch, dt0.microsecondsSinceEpoch);
   Expect.equals(false, dt1 == dt0);
   Expect.equals(true, dt1 == dt0b);
   var dt3 = new DateTime(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
-                     dt1.second, dt1.millisecond);
+                     dt1.second, dt1.millisecond, dt1.microsecond);
   Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(dt1.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
   Expect.equals(false, dt3 == dt0);
   Expect.equals(true, dt1 == dt3);
   dt3 = new DateTime(
       dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
-      dt1.second, dt1.millisecond);
+      dt1.second, dt1.millisecond, dt1.microsecond);
   Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(dt1.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
   Expect.equals(true, dt1 == dt3);
   var dt2 = dt1.toLocal();
-  dt3 = new DateTime(2011, 5, dt1.day, dt1.hour, dt1.minute, 35, 0);
+  dt3 = new DateTime(2011, 5, dt1.day, dt1.hour, dt1.minute, 35, 0, 0);
   Expect.equals(dt2.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(dt2.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
   Expect.equals(true, dt2 == dt3);
   dt1 = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
   dt3 = new DateTime.utc(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
                      dt1.second, dt1.millisecond);
   Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(dt1.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
   dt3 = new DateTime.utc(99, 1, 2, 10, 11, 12, 0);
   Expect.equals(99, dt3.year);
   Expect.equals(1, dt3.month);
@@ -357,6 +531,7 @@
   Expect.equals(11, dt3.minute);
   Expect.equals(12, dt3.second);
   Expect.equals(0, dt3.millisecond);
+  Expect.equals(0, dt3.microsecond);
   Expect.equals(true, dt3.isUtc);
   var dt4 = new DateTime(99, 1, 2);
   Expect.equals(99, dt4.year);
@@ -366,6 +541,7 @@
   Expect.equals(0, dt4.minute);
   Expect.equals(0, dt4.second);
   Expect.equals(0, dt4.millisecond);
+  Expect.equals(0, dt4.microsecond);
   Expect.isFalse(dt4.isUtc);
   var dt5 = new DateTime.utc(99, 1, 2);
   Expect.equals(99, dt5.year);
@@ -375,6 +551,7 @@
   Expect.equals(0, dt5.minute);
   Expect.equals(0, dt5.second);
   Expect.equals(0, dt5.millisecond);
+  Expect.equals(0, dt5.microsecond);
   Expect.isTrue(dt5.isUtc);
   var dt6 = new DateTime(2012, 2, 27, 13, 27, 0);
   Expect.equals(2012, dt6.year);
@@ -384,6 +561,7 @@
   Expect.equals(27, dt6.minute);
   Expect.equals(0, dt6.second);
   Expect.equals(0, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   Expect.isFalse(dt6.isUtc);
   var dt7 = new DateTime.utc(2012, 2, 27, 13, 27, 0);
   Expect.equals(2012, dt7.year);
@@ -393,6 +571,7 @@
   Expect.equals(27, dt7.minute);
   Expect.equals(0, dt7.second);
   Expect.equals(0, dt7.millisecond);
+  Expect.equals(0, dt7.microsecond);
   Expect.isTrue(dt7.isUtc);
 }
 
@@ -409,6 +588,7 @@
   Expect.equals(dt2.minute, dt3.minute);
   Expect.equals(dt2.second, dt3.second);
   Expect.equals(dt2.millisecond, dt3.millisecond);
+  Expect.equals(dt2.microsecond, dt3.microsecond);
   var dt4 = dt3.toLocal();
   Expect.equals(dt1.year, dt4.year);
   Expect.equals(dt1.month, dt4.month);
@@ -417,6 +597,7 @@
   Expect.equals(dt1.minute, dt4.minute);
   Expect.equals(dt1.second, dt4.second);
   Expect.equals(dt1.millisecond, dt4.millisecond);
+  Expect.equals(dt1.microsecond, dt4.microsecond);
 }
 
 void testSubAdd() {
@@ -430,19 +611,39 @@
   Expect.equals(dt1.minute, dt2.minute);
   Expect.equals(dt1.second + 3, dt2.second);
   Expect.equals(dt1.millisecond + 5, dt2.millisecond);
+  Expect.equals(dt1.microsecond, dt2.microsecond);
   var dt3 = dt2.subtract(new Duration(milliseconds:
       3 * Duration.MILLISECONDS_PER_SECOND + 5));
   Expect.equals(true, dt1 == dt3);
   Expect.equals(false, dt1 == dt2);
+
+  if (!supportsMicroseconds) return;
+
+  dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
+  dt2 = dt1.add(new Duration(microseconds:
+      3 * Duration.MICROSECONDS_PER_SECOND + 5));
+  Expect.equals(dt1.year, dt2.year);
+  Expect.equals(dt1.month, dt2.month);
+  Expect.equals(dt1.day, dt2.day);
+  Expect.equals(dt1.hour, dt2.hour);
+  Expect.equals(dt1.minute, dt2.minute);
+  Expect.equals(dt1.second + 3, dt2.second);
+  Expect.equals(dt1.millisecond, dt2.millisecond);
+  Expect.equals(dt1.microsecond + 5, dt2.microsecond);
+  dt3 = dt2.subtract(new Duration(microseconds:
+      3 * Duration.MICROSECONDS_PER_SECOND + 5));
+  Expect.equals(true, dt1 == dt3);
+  Expect.equals(false, dt1 == dt2);
 }
 
 void testUnderflowAndOverflow() {
-  final dtBase = new DateTime(2012, 6, 20, 12, 30, 30, 500);
+  int microsecond = supportsMicroseconds ? 499 : 0;
+  final dtBase = new DateTime(2012, 6, 20, 12, 30, 30, 500, microsecond);
 
   // Millisecond
   print("  >>> Millisecond+");
   var dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                    dtBase.minute, dtBase.second, 1000);
+                    dtBase.minute, dtBase.second, 1000, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -450,10 +651,11 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second + 1, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Millisecond-");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                dtBase.minute, dtBase.second, -1000);
+                dtBase.minute, dtBase.second, -1000, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -461,11 +663,12 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second - 1, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Second
   print("  >>> Second+");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                dtBase.minute, 60, dtBase.millisecond);
+                dtBase.minute, 60, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -473,10 +676,11 @@
   Expect.equals(dtBase.minute + 1, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Second-");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                dtBase.minute, -60, dtBase.millisecond);
+                dtBase.minute, -60, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -484,11 +688,12 @@
   Expect.equals(dtBase.minute - 1, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Minute
   print("  >>> Minute+");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, 60,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -496,10 +701,11 @@
   Expect.equals(0, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Minute-");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, -60,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -507,11 +713,12 @@
   Expect.equals(0, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Hour
   print("  >>> Hour+");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, 24, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day + 1, dt.day);
@@ -519,10 +726,11 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Hour-");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, -24, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day - 1, dt.day);
@@ -530,11 +738,12 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Day
   print("  >>> Day+");
   dt = new DateTime(dtBase.year, dtBase.month, 31, dtBase.hour, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month + 1, dt.month);
   Expect.equals(1, dt.day);
@@ -542,10 +751,11 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Day-");
   dt = new DateTime(dtBase.year, dtBase.month, -30, dtBase.hour, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month - 1, dt.month);
   Expect.equals(1, dt.day);
@@ -553,11 +763,12 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Month
   print("  >>> Month+");
   dt = new DateTime(dtBase.year, 13, dtBase.day, dtBase.hour, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year + 1, dt.year);
   Expect.equals(1, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -565,10 +776,11 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Month-");
   dt = new DateTime(dtBase.year, -11, dtBase.day, dtBase.hour, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year - 1, dt.year);
   Expect.equals(1, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -576,13 +788,14 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Flowing all the way up the chain.
   print("  >>> Flow+");
-  var dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999);
+  var dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999, 000);
   var dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day,
                         dtBase1.hour, dtBase1.minute, dtBase1.second,
-                        dtBase1.millisecond + 1);
+                        dtBase1.millisecond + 1, dtBase1.microsecond);
   Expect.equals(dtBase1.year + 1, dtTick.year);
   Expect.equals(1, dtTick.month);
   Expect.equals(1, dtTick.day);
@@ -590,11 +803,13 @@
   Expect.equals(0, dtTick.minute);
   Expect.equals(0, dtTick.second);
   Expect.equals(0, dtTick.millisecond);
+  Expect.equals(0, dtTick.microsecond);
 
   print("  >>> Flow-");
   dtBase1 = new DateTime(2012, 1, 1, 0, 0, 0, 0);
   dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, dtBase1.hour,
-                    dtBase1.minute, dtBase1.second, dtBase1.millisecond - 1);
+                    dtBase1.minute, dtBase1.second, dtBase1.millisecond - 1,
+                    dtBase1.microsecond);
   Expect.equals(dtBase1.year - 1, dtTick.year);
   Expect.equals(12, dtTick.month);
   Expect.equals(31, dtTick.day);
@@ -602,10 +817,12 @@
   Expect.equals(59, dtTick.minute);
   Expect.equals(59, dtTick.second);
   Expect.equals(999, dtTick.millisecond);
+  Expect.equals(0, dtTick.microsecond);
 
   print("  >>> extra underflow");
   dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, -17520,
-                    dtBase1.minute, dtBase1.second, dtBase1.millisecond);
+                    dtBase1.minute, dtBase1.second, dtBase1.millisecond,
+                    dtBase1.microsecond);
   Expect.equals(dtBase1.year - 2, dtTick.year);
   Expect.equals(dtBase1.month, dtTick.month);
   Expect.equals(dtBase1.day, dtTick.day);
@@ -613,6 +830,63 @@
   Expect.equals(dtBase1.minute, dtTick.minute);
   Expect.equals(dtBase1.second, dtTick.second);
   Expect.equals(dtBase1.millisecond, dtTick.millisecond);
+  Expect.equals(dtBase1.microsecond, dtTick.microsecond);
+
+  if (!supportsMicroseconds) return;
+
+  // Microsecond
+  print("  >>> Microsecond+");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+                    dtBase.minute, dtBase.second, dtBase.millisecond, 1000);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond + 1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
+  print("  >>> Microsecond-");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+                dtBase.minute, dtBase.second, dtBase.millisecond, -1000);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond - 1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
+  // Flowing all the way up the chain.
+  print("  >>> Flow+ 2");
+  dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999, 999);
+  dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day,
+                        dtBase1.hour, dtBase1.minute, dtBase1.second,
+                        dtBase1.millisecond, dtBase1.microsecond + 1);
+  Expect.equals(dtBase1.year + 1, dtTick.year);
+  Expect.equals(1, dtTick.month);
+  Expect.equals(1, dtTick.day);
+  Expect.equals(0, dtTick.hour);
+  Expect.equals(0, dtTick.minute);
+  Expect.equals(0, dtTick.second);
+  Expect.equals(0, dtTick.millisecond);
+  Expect.equals(0, dtTick.microsecond);
+
+  print("  >>> Flow- 2");
+  dtBase1 = new DateTime(2012, 1, 1, 0, 0, 0, 0, 0);
+  dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, dtBase1.hour,
+                    dtBase1.minute, dtBase1.second, dtBase1.millisecond,
+                    dtBase1.microsecond - 1);
+  Expect.equals(dtBase1.year - 1, dtTick.year);
+  Expect.equals(12, dtTick.month);
+  Expect.equals(31, dtTick.day);
+  Expect.equals(23, dtTick.hour);
+  Expect.equals(59, dtTick.minute);
+  Expect.equals(59, dtTick.second);
+  Expect.equals(999, dtTick.millisecond);
+  Expect.equals(999, dtTick.microsecond);
 }
 
 void testDateStrings() {
@@ -640,6 +914,7 @@
   Expect.equals(0, dt4.minute);
   Expect.equals(0, dt4.second);
   Expect.equals(0, dt4.millisecond);
+  Expect.equals(0, dt4.microsecond);
   Expect.isTrue(dt4.isUtc);
   var dt5 = DateTime.parse("0099-01-02");
   Expect.equals(99, dt5.year);
@@ -649,17 +924,23 @@
   Expect.equals(0, dt5.minute);
   Expect.equals(0, dt5.second);
   Expect.equals(0, dt5.millisecond);
+  Expect.equals(0, dt5.microsecond);
   Expect.isFalse(dt5.isUtc);
   var dt6 = DateTime.parse("2012-01-01 00:00:10.012");
   Expect.equals(12, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   dt6 = DateTime.parse("2012-01-01 00:00:10.003");
   Expect.equals(3, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   dt6 = DateTime.parse("2012-01-01 00:00:10.5");
   Expect.equals(500, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   dt6 = DateTime.parse("2012-01-01 00:00:10.003Z");
   Expect.equals(3, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   dt6 = DateTime.parse("2012-01-01 00:00:10.5z");
   Expect.equals(500, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   var dt7 = DateTime.parse("2011-05-11T18:58:35Z");
   Expect.equals(1305140315000, dt7.millisecondsSinceEpoch);
   var dt8 = DateTime.parse("-1234-01-01T00:00:00Z");
@@ -670,6 +951,7 @@
   Expect.equals(0, dt8.minute);
   Expect.equals(0, dt8.second);
   Expect.equals(0, dt8.millisecond);
+  Expect.equals(0, dt8.microsecond);
   Expect.isTrue(dt8.isUtc);
   var dt9 = DateTime.parse("-1234-01-01T00:00:00");
   Expect.equals(-1234, dt9.year);
@@ -679,6 +961,7 @@
   Expect.equals(0, dt9.minute);
   Expect.equals(0, dt9.second);
   Expect.equals(0, dt9.millisecond);
+  Expect.equals(0, dt9.microsecond);
   Expect.isFalse(dt9.isUtc);
   var dt10 = DateTime.parse("-12340101");
   Expect.equals(-1234, dt10.year);
@@ -688,6 +971,7 @@
   Expect.equals(0, dt10.minute);
   Expect.equals(0, dt10.second);
   Expect.equals(0, dt10.millisecond);
+  Expect.equals(0, dt10.microsecond);
   Expect.isFalse(dt10.isUtc);
   dt1 = DateTime.parse("2012-02-27 13:27:00");
   Expect.equals(2012, dt1.year);
@@ -697,6 +981,7 @@
   Expect.equals(27, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("2012-02-27 13:27:00.423z");
   Expect.equals(2012, dt1.year);
@@ -706,6 +991,7 @@
   Expect.equals(27, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(423, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(true, dt1.isUtc);
   dt1 = DateTime.parse("20120227 13:27:00");
   Expect.equals(2012, dt1.year);
@@ -715,6 +1001,7 @@
   Expect.equals(27, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("20120227T132700");
   Expect.equals(2012, dt1.year);
@@ -724,6 +1011,7 @@
   Expect.equals(27, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("20120227");
   Expect.equals(2012, dt1.year);
@@ -733,6 +1021,7 @@
   Expect.equals(0, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("2012-02-27T14Z");
   Expect.equals(2012, dt1.year);
@@ -742,6 +1031,7 @@
   Expect.equals(0, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(true, dt1.isUtc);
   dt1 = DateTime.parse("-123450101 00:00:00 Z");
   Expect.equals(-12345, dt1.year);
@@ -751,28 +1041,51 @@
   Expect.equals(0, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(true, dt1.isUtc);
-  // We only support millisecond. If the user supplies more data (the "51"
-  // here), we round.
-  // If (eventually) we support more than just millisecond this test could
-  // fail. Please update the test in this case.
   dt1 = DateTime.parse("1999-01-02 23:59:59.99951");
-  Expect.equals(1999, dt1.year);
-  Expect.equals(1, dt1.month);
-  Expect.equals(3, dt1.day);
-  Expect.equals(0, dt1.hour);
-  Expect.equals(0, dt1.minute);
-  Expect.equals(0, dt1.second);
-  Expect.equals(0, dt1.millisecond);
+  if (supportsMicroseconds) {
+    Expect.equals(1999, dt1.year);
+    Expect.equals(1, dt1.month);
+    Expect.equals(2, dt1.day);
+    Expect.equals(23, dt1.hour);
+    Expect.equals(59, dt1.minute);
+    Expect.equals(59, dt1.second);
+    Expect.equals(999, dt1.millisecond);
+    Expect.equals(510, dt1.microsecond);
+  } else {
+    // We only support millisecond. If the user supplies more data (the "51"
+    // here), we round.
+    Expect.equals(1999, dt1.year);
+    Expect.equals(1, dt1.month);
+    Expect.equals(3, dt1.day);
+    Expect.equals(0, dt1.hour);
+    Expect.equals(0, dt1.minute);
+    Expect.equals(0, dt1.second);
+    Expect.equals(0, dt1.millisecond);
+    Expect.equals(0, dt1.microsecond);
+  }
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("1999-01-02 23:58:59.99951Z");
-  Expect.equals(1999, dt1.year);
-  Expect.equals(1, dt1.month);
-  Expect.equals(2, dt1.day);
-  Expect.equals(23, dt1.hour);
-  Expect.equals(59, dt1.minute);
-  Expect.equals(0, dt1.second);
-  Expect.equals(0, dt1.millisecond);
+  if (supportsMicroseconds) {
+    Expect.equals(1999, dt1.year);
+    Expect.equals(1, dt1.month);
+    Expect.equals(2, dt1.day);
+    Expect.equals(23, dt1.hour);
+    Expect.equals(58, dt1.minute);
+    Expect.equals(59, dt1.second);
+    Expect.equals(999, dt1.millisecond);
+    Expect.equals(510, dt1.microsecond);
+  } else {
+    Expect.equals(1999, dt1.year);
+    Expect.equals(1, dt1.month);
+    Expect.equals(2, dt1.day);
+    Expect.equals(23, dt1.hour);
+    Expect.equals(59, dt1.minute);
+    Expect.equals(0, dt1.second);
+    Expect.equals(0, dt1.millisecond);
+    Expect.equals(0, dt1.microsecond);
+  }
   Expect.equals(true, dt1.isUtc);
   dt1 = DateTime.parse("0009-09-09 09:09:09.009Z");
   Expect.equals(9, dt1.year);
@@ -866,11 +1179,22 @@
                 (e) => e is FormatException);
   Expect.throws(() => DateTime.parse("275760-09-13T00:00:00.001Z"),
                 (e) => e is FormatException);
+  if (supportsMicroseconds) {
+    Expect.throws(() => DateTime.parse("275760-09-13T00:00:00.000001Z"),
+                  (e) => e is FormatException);
+  } else {
+    dt1 = DateTime.parse("275760-09-13T00:00:00.000001Z");
+  }
 
   // first valid time; should not throw.
   dt1 = DateTime.parse("-271821-04-20T00:00:00.000Z");
   Expect.throws(() => DateTime.parse("-271821-04-19T23:59:59.999Z"),
                 (e) => e is FormatException);
+
+  if (supportsMicroseconds) {
+    Expect.throws(() => DateTime.parse("-271821-04-19T23:59:59.999999Z"),
+                  (e) => e is FormatException);
+  }
 }
 
 void testWeekday() {
@@ -932,6 +1256,14 @@
   test("1970-01-01", "00:00:00.000");
   test("1969-12-31", "23:59:59.999");
   test("1969-09-09", "00:09:09.009");
+
+  if (supportsMicroseconds) {
+    test("2000-01-01", "12:00:00.000001");
+    test("-2000-01-01", "12:00:00.000001");
+    test("1970-01-01", "00:00:00.000001");
+    test("1969-12-31", "23:59:59.999999");
+    test("1969-09-09", "00:09:09.009999");
+  }
 }
 
 void testIsoString() {
@@ -952,11 +1284,50 @@
   Expect.equals("+010000-01-01T23:59:59.999Z", d.toIso8601String());
   d = new DateTime.utc(-10000, 1, 1, 23, 59, 59, 999);
   Expect.equals("-010000-01-01T23:59:59.999Z", d.toIso8601String());
+
+  if (!supportsMicroseconds) return;
+
+  d = new DateTime(9999, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("9999-01-01T23:59:59.999999", d.toIso8601String());
+  d = new DateTime(-9999, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("-9999-01-01T23:59:59.999999", d.toIso8601String());
+  d = new DateTime.utc(9999, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("9999-01-01T23:59:59.999999Z", d.toIso8601String());
+  d = new DateTime.utc(-9999, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("-9999-01-01T23:59:59.999999Z", d.toIso8601String());
+
+  d = new DateTime(10000, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("+010000-01-01T23:59:59.999999", d.toIso8601String());
+  d = new DateTime(-10000, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("-010000-01-01T23:59:59.999999", d.toIso8601String());
+  d = new DateTime.utc(10000, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("+010000-01-01T23:59:59.999999Z", d.toIso8601String());
+  d = new DateTime.utc(-10000, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("-010000-01-01T23:59:59.999999Z", d.toIso8601String());
+
+  d = new DateTime(9999, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("9999-01-01T23:49:59.989979", d.toIso8601String());
+  d = new DateTime(-9999, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("-9999-01-01T23:49:59.989979", d.toIso8601String());
+  d = new DateTime.utc(9999, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("9999-01-01T23:49:59.989979Z", d.toIso8601String());
+  d = new DateTime.utc(-9999, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("-9999-01-01T23:49:59.989979Z", d.toIso8601String());
+
+  d = new DateTime(10000, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("+010000-01-01T23:49:59.989979", d.toIso8601String());
+  d = new DateTime(-10000, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("-010000-01-01T23:49:59.989979", d.toIso8601String());
+  d = new DateTime.utc(10000, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("+010000-01-01T23:49:59.989979Z", d.toIso8601String());
+  d = new DateTime.utc(-10000, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("-010000-01-01T23:49:59.989979Z", d.toIso8601String());
 }
 
 void main() {
   testNow();
-  testValue();
+  testMillisecondsSinceEpoch();
+  testMicrosecondsSinceEpoch();
   testConstructors();
   testUTCGetters();
   testLocalGetters();
diff --git a/tests/corelib/errors_test.dart b/tests/corelib/errors_test.dart
index edfa761..c980d44 100644
--- a/tests/corelib/errors_test.dart
+++ b/tests/corelib/errors_test.dart
@@ -25,9 +25,9 @@
                 new ArgumentError.value(42, "foo", "message").toString());
   Expect.equals("Invalid argument: message: 42",
                 new ArgumentError.value(42, null, "message").toString());
-  Expect.equals("Invalid argument: Must not be null: null",
+  Expect.equals("Invalid argument(s): Must not be null",
                 new ArgumentError.notNull().toString());
-  Expect.equals("Invalid argument (foo): Must not be null: null",
+  Expect.equals("Invalid argument(s) (foo): Must not be null",
                 new ArgumentError.notNull("foo").toString());
 
   Expect.equals("RangeError",
diff --git a/tests/corelib/growable_list_test.dart b/tests/corelib/growable_list_test.dart
index b1d6e09..4b125bf 100644
--- a/tests/corelib/growable_list_test.dart
+++ b/tests/corelib/growable_list_test.dart
@@ -88,8 +88,10 @@
   }
   testFixedLength(new List<int>(0));
   testFixedLength(new List<int>(5));
+  testFixedLength(new List<int>.filled(5, null));  // default growable: false.
   testGrowable(new List<int>());
   testGrowable(new List<int>()..length = 5);
+  testGrowable(new List<int>.filled(5, null, growable: true));
   Expect.throws(() => new List<int>(-1), (e) => e is ArgumentError, "-1");
   // There must be limits. Fix this test if we ever allow 10^30 elements.
   Expect.throws(() => new List<int>(0x1000000000000000000000000000000),
diff --git a/tests/corelib/int_parse_radix_test.dart b/tests/corelib/int_parse_radix_test.dart
index ce68a79..fbe9205 100644
--- a/tests/corelib/int_parse_radix_test.dart
+++ b/tests/corelib/int_parse_radix_test.dart
@@ -20,7 +20,6 @@
 
   for (int i = 0; i < whiteSpace.length; i++) {
     var ws = whiteSpace[i];
-    print(ws.codeUnitAt(0).toRadixString(16));
     Expect.equals(0, int.parse("${ws}0${ws}", radix: 2));
   }
 
@@ -55,8 +54,8 @@
     Expect.equals(-result, int.parse("-$zeros$radixString", radix: radix), m);
   }
 
-  for (int i = 0; i <= 36 * 36; i++) {
-    for (int r = 2; r <= 36; r++) {
+  for (int r = 2; r <= 36; r++) {
+    for (int i = 0; i <= r * r; i++) {
       String radixString = i.toRadixString(r);
       testParse(i, radixString, r);
     }
@@ -89,13 +88,14 @@
   void testFails(String source, int radix) {
     Expect.throws(() { throw int.parse(source, radix: radix,
                                        onError: (s) { throw "FAIL"; }); },
-                  (e) => e == "FAIL",
+                  isFail,
                   "$source/$radix");
     Expect.equals(-999, int.parse(source, radix: radix, onError: (s) => -999));
   }
   for (int i = 2; i < 36; i++) {
-    testFails(i.toRadixString(36).toLowerCase(), i);
-    testFails(i.toRadixString(36).toUpperCase(), i);
+    var char = i.toRadixString(36);
+    testFails(char.toLowerCase(), i);
+    testFails(char.toUpperCase(), i);
   }
   testFails("", 2);
   testFails("+ 1", 2);  // No space between sign and digits.
@@ -141,3 +141,5 @@
   Expect.throws(() => int.parse("9", radix: 8, onError: () => 42));
   Expect.throws(() => int.parse("9", radix: 8, onError: (v1, v2) => 42));
 }
+
+bool isFail(e) => e == "FAIL";
diff --git a/tests/corelib/list_filled_type_argument_test.dart b/tests/corelib/list_filled_type_argument_test.dart
index 6d361cc..1c3aff4 100644
--- a/tests/corelib/list_filled_type_argument_test.dart
+++ b/tests/corelib/list_filled_type_argument_test.dart
@@ -8,4 +8,8 @@
   var a = new List<int>.filled(42, 42);
   Expect.isTrue(a is List<int>);
   Expect.isFalse(a is List<String>);
+
+  a = new List<int>.filled(42, 42, growable: true);
+  Expect.isTrue(a is List<int>);
+  Expect.isFalse(a is List<String>);
 }
diff --git a/tests/corelib/list_test.dart b/tests/corelib/list_test.dart
index c26c1cf..a72a189 100644
--- a/tests/corelib/list_test.dart
+++ b/tests/corelib/list_test.dart
@@ -33,6 +33,7 @@
   testGrowableList(new List());
   testGrowableList(new List().toList());
   testGrowableList(new List(0).toList());
+  testGrowableList(new List.filled(0, null, growable: true));
   testGrowableList([]);
   testGrowableList((const []).toList());
   testGrowableList(new MyList([]));
diff --git a/tests/corelib/stacktrace_current_test.dart b/tests/corelib/stacktrace_current_test.dart
new file mode 100644
index 0000000..f68ba32
--- /dev/null
+++ b/tests/corelib/stacktrace_current_test.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.
+
+import "dart:convert" show LineSplitter;
+
+import "package:expect/expect.dart";
+
+void main() {
+  var st0;
+  var st1;
+  // Primitive way to get stack trace,.
+  try { throw 0; } catch (_, s) { st0 = s; }
+  st1 = StackTrace.current;
+
+  var st0s = findMain(st0);
+  var st1s = findMain(st1);
+  // Stack traces are not equal (contains at least a different line number,
+  // and possible different frame numbers).
+  // They are *similar*, so check that they agree on everything but numbers.
+  var digits = new RegExp(r"\d+");
+  Expect.equals(st0s.replaceAll(digits, "0"), st1s.replaceAll(digits, "0"));
+}
+
+String findMain(StackTrace stack) {
+  var string = "$stack";
+  var lines = LineSplitter.split(string).toList();
+  while (lines.isNotEmpty && !lines.first.contains("main")) {
+    lines.removeAt(0);
+  }
+  return lines.join("\n");
+}
diff --git a/tests/corelib/string_replace_all_test.dart b/tests/corelib/string_replace_all_test.dart
index 299d56a..f63a9f7 100644
--- a/tests/corelib/string_replace_all_test.dart
+++ b/tests/corelib/string_replace_all_test.dart
@@ -46,6 +46,16 @@
 
   // Test replacing the empty string.
   Expect.equals("toAtoBtoCto", "ABC".replaceAll("", "to"));
+
+  // Pattern strings containing RegExp metacharacters - these are not
+  // interpreted as RegExps.
+  Expect.equals(r"$$", "||".replaceAll("|", r"$"));
+  Expect.equals(r"$$$$", "||".replaceAll("|", r"$$"));
+  Expect.equals(r"x$|x", "x|.|x".replaceAll("|.", r"$"));
+  Expect.equals(r"$$", "..".replaceAll(".", r"$"));
+  Expect.equals(r"[$$$$]", "[..]".replaceAll(".", r"$$"));
+  Expect.equals(r"[$]", "[..]".replaceAll("..", r"$"));
+  Expect.equals(r"$$", r"\\".replaceAll(r"\", r"$"));
 }
 
 testReplaceAllMapped() {
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart b/tests/html/dromaeo_noop/dromaeo_smoke.dart
deleted file mode 100644
index 0a1e13e..0000000
--- a/tests/html/dromaeo_noop/dromaeo_smoke.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dromaeo;
-
-import 'dart:async';
-import "dart:convert";
-import 'dart:html';
-import 'dart:math' as Math;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import '../../../samples/third_party/dromaeo/common/common.dart';
-
-part '../../../samples/third_party/dromaeo/tests/Common.dart';
-part '../../../samples/third_party/dromaeo/tests/RunnerSuite.dart';
-
-/**
- * The smoketest equivalent of an individual test run, much like
- * dom-attr-html.dart, dom-modify-html.dart, dom-query-html.dart and others.
- */
-void main() {
-  new Suite(window, 'dom-nothing')
-    .prep(() {})
-    .test('no-op', () {})
-    .end();
-}
-
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart.js b/tests/html/dromaeo_noop/dromaeo_smoke.dart.js
deleted file mode 100644
index d1f3214..0000000
--- a/tests/html/dromaeo_noop/dromaeo_smoke.dart.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-window.onload = function(){
-  startTest("dom-nothing");
-  test( "no-op", function(){});
-  endTest();
-};
diff --git a/tests/html/dromaeo_smoke-html.html b/tests/html/dromaeo_smoke-html.html
deleted file mode 100644
index 1cbeca4..0000000
--- a/tests/html/dromaeo_smoke-html.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<!-- The inner smoketest iframe, corresponds to dom-attr-html.html,
-dom-modify-html.html and others in the dromaeo tests directory. -->
-<html>
-<head>
-<script type="application/dart" src="dromaeo_noop/dromaeo_smoke.dart"></script>
-<script src='/root_dart/pkg/browser/lib/dart.js'></script>
-<script src='/root_dart/samples/third_party/dromaeo/htmlrunner.js'></script>
-</head>
-<body>
-</body>
-</html>
diff --git a/tests/html/dromaeo_smoke_test.dart b/tests/html/dromaeo_smoke_test.dart
deleted file mode 100644
index 2f71f9b6..0000000
--- a/tests/html/dromaeo_smoke_test.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dromaeo;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import '../../samples/third_party/dromaeo/web/Dromaeo.dart' as originalTest;
-import 'dart:html';
-import 'dart:async';
-
-/** A variant of the Dromaeo test shoehorned into a unit test. */
-void main() {
-  var combo = '?dartANDhtmlANDnothing';
-  if (!window.location.search.toString().contains(combo)) {
-    if (window.location.href.toString().indexOf("?") == -1) {
-      window.location.href = '${window.location.href}${combo}';
-    } else {
-      window.location.href = '${window.location.href.toString().substring(0,
-          window.location.href.toString().indexOf("?"))}${combo}';
-    }
-  }
-
-  useHtmlConfiguration();
-
-  var scriptSrc = new ScriptElement();
-  scriptSrc.src = '/root_dart/pkg/browser/lib/dart.js';
-  document.head.children.add(scriptSrc);
-  document.body.innerHtml = '''${document.body.innerHtml}
-  <div id="main">
-    <h1 id="overview" class="test"><span>Performance Tests</span>
-    <input type="button" id="pause" class="pause" value="Loading..."/>
-    <div class="bar">
-      <div id="timebar" style="width:25%;">
-        <span class="left">Est.&nbsp;Time:&nbsp;<strong id="left">0:00</strong>
-        </span>
-      </div>
-    </div>
-    <ul id="tests">
-      <li><a href="?dom">Smoke Tests</a></li>
-    </ul>
-  </div>''';
-
-  bool isDone = false;
-  originalTest.main();
-
-  test('dromaeo runs', () {
-    new Timer.periodic(new Duration(milliseconds: 500),
-                       expectAsyncUntil((timer) {
-      if (document.query('.alldone') != null) {
-        timer.cancel();
-        isDone = true;
-      }
-    }, () => isDone));
-  });
-}
diff --git a/tests/html/history_test.dart b/tests/html/history_test.dart
index 893fb77..d801a72 100644
--- a/tests/html/history_test.dart
+++ b/tests/html/history_test.dart
@@ -34,6 +34,17 @@
       }, expectation);
     });
 
+    test('pushState with data', () {
+      expect(() {
+        window.history.pushState({'one' : 1}, document.title, '?dummy');
+        expect(window.history.state, equals({'one' : 1}));
+        window.history.pushState(null, document.title, '?foo=bar');
+
+        expect(window.location.href.endsWith('foo=bar'), isTrue);
+
+      }, expectation);
+    });
+
     test('back', () {
       expect(() {
         window.history.pushState(null, document.title, '?dummy1');
diff --git a/tests/html/html.status b/tests/html/html.status
index bba61dd..cf5e043 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 interactive_test: Skip # Must be run manually.
-dromaeo_smoke_test: Skip # Issue 14521, 8257
 cross_frame_test: Skip # Test reloads itself. Issue 18558
 
 [ $compiler == none && ($runtime == dartium || $runtime == drt) ]
@@ -33,7 +32,9 @@
 
 [ $compiler == dart2js && $checked ]
 js_function_getter_trust_types_test: Skip # --trust-type-annotations incompatible with --checked
-js_typed_interop_test: Pass, Fail # Issue 24822
+
+[ $compiler == dart2js && $checked && $browser ]
+js_typed_interop_test/method: Fail # Issue 24822
 
 [ $compiler == dart2js && $csp && $browser ]
 custom/js_custom_test: Fail # Issue 14643
@@ -56,10 +57,10 @@
 # postMessage in dartium always transfers the typed array buffer, never a view
 postmessage_structured_test/typed_arrays: Fail
 # Dartium seems to lose the data from the dispatchEvent.
-async_test: Fail # Uses spawn, not implemented from a DOM isolate in Dartium
 keyboard_event_test: Fail # Issue 13902
-isolates_test: Fail # Issue 13921
 fileapi_test/getFile: Pass, Fail # Issue 20488
+async_test: RuntimeError, OK  # Uses Isolate.spawn.
+isolates_test: RuntimeError, OK  # Uses Isolate.spawn.
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium ) && $mode == debug ]
 websocket_test/websocket: Skip # Issue 17666
@@ -104,6 +105,8 @@
 element_animate_test/omit_timing: RuntimeError # Also timing out on MacOS. Issue 23507
 element_animate_test/timing_dict: RuntimeError # Also timing out on MacOS. Issue 23507
 element_animate_test/simple_timing: RuntimeError # Please triage this failure
+element_types_test/supported_object: RuntimeError # Issue 25155
+element_types_test/supported_embed: RuntimeError # Issue 25155
 
 [ $runtime == chrome && $system == macos ]
 canvasrenderingcontext2d_test/drawImage_video_element: Skip # Times out. Please triage this failure.
@@ -345,7 +348,6 @@
 xhr_test/xhr: Pass, Fail # Issue 11602
 dart_object_local_storage_test: Skip  # sessionStorage NS_ERROR_DOM_NOT_SUPPORTED_ERR
 webgl_1_test: Pass, Fail   # Issue 8219
-canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Pass, Fail # Firefox pre-38 does not like dataUrl videos for drawImage Issue 23479
 text_event_test: Fail # Issue 17893
 
 # Firefox Feature support statuses-
@@ -370,9 +372,13 @@
 touchevent_test/supported: Fail
 websql_test/supported: Fail
 
+[ $compiler == dart2js && $runtime == ff && $system == windows ]
+mediasource_test/supported: Pass
+mediasource_test/functional: RuntimeError # Issue 24838
+
 # 'html' tests import the HTML library, so they only make sense in
 # a browser environment.
-[ $runtime == vm ]
+[ $runtime == vm || $runtime == dart_precompiled ]
 *: Skip
 
 [ $compiler == dart2js && ($runtime == drt || $runtime == ff) ]
@@ -401,7 +407,7 @@
 [ (($runtime == dartium || $runtime == drt) && $system == macos) || $system == windows ]
 xhr_test/xhr: Skip # Times out.  Issue 21527
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 custom/document_register_basic_test: StaticWarning
 custom/element_upgrade_test: StaticWarning
 datalistelement_test: StaticWarning
diff --git a/tests/html/js_typed_interop_test.dart b/tests/html/js_typed_interop_test.dart
index 0e7cd0c..14d931f 100644
--- a/tests/html/js_typed_interop_test.dart
+++ b/tests/html/js_typed_interop_test.dart
@@ -86,6 +86,11 @@
       return this.str.charCodeAt(index);
     }
   };
+  function getCanvasContext() {
+    return document.createElement('canvas').getContext('2d');
+  }
+  window.windowProperty = 42;
+  document.documentProperty = 45;
 """);
 }
 
@@ -176,6 +181,15 @@
 @JS()
 external confuse(obj);
 
+@JS()
+external CanvasRenderingContext2D getCanvasContext();
+
+@JS('window.window.document.documentProperty')
+external num get propertyOnDocument;
+
+@JS('window.self.window.window.windowProperty')
+external num get propertyOnWindow;
+
 main() {
   _injectJs();
 
@@ -374,4 +388,13 @@
       expect(selection is List, isTrue);
     });
   });
+  group('html', () {
+    test('return html type', () {
+      expect(getCanvasContext() is CanvasRenderingContext2D, isTrue);
+    });
+    test('js path contains html types', () {
+      expect(propertyOnWindow, equals(42));
+      expect(propertyOnDocument, equals(45));
+    });
+  });
 }
diff --git a/tests/html/websocket_test.dart b/tests/html/websocket_test.dart
index f8ba1ba..1715c88 100644
--- a/tests/html/websocket_test.dart
+++ b/tests/html/websocket_test.dart
@@ -35,6 +35,16 @@
 
         return socket.onMessage.first.then((MessageEvent e) {
           expect(e.data, 'hello!');
+          socket.close();
+        });
+      });
+
+      test('error handling', () {
+        var socket = new WebSocket('ws://${window.location.host}/ws');
+        socket.onOpen.first.then((_) => socket.send('close-with-error'));
+        return socket.onError.first.then((e) {
+          print('$e was caught, yay!');
+          socket.close();
         });
       });
     }
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 95b36d0..e11f91a 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -2,25 +2,25 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $runtime == vm ]
+[ ($runtime == vm || $runtime == dart_precompiled) ]
 browser/*: SkipByDesign  # Browser specific tests
 isolate_stress_test: Fail # Issue 12588: This should be able to pass when we have wrapper-less tests.
 
 [ $runtime != vm ]
 checked_test: Skip # Unsupported.
 
-[ $runtime == vm && $arch == mips && $mode == debug ]
+[ ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $mode == debug ]
 mandel_isolate_test: Skip # Uses 600 MB Ram on our 1 GB test device.
 
-[ $compiler == none ]
+[ ($compiler == none || $compiler == precompiler) ]
 compile_time_error_test/01: Skip # Issue 12587
 ping_test: Skip           # Resolve test issues
 ping_pause_test: Skip     # Resolve test issues
 kill3_test: Pass, Fail    # Bad test: expects total message order
 
-message3_test/int32x4: Crash # Issue 21818
+message3_test/int32x4: Crash, Timeout # Issue 21818
 
-[ $compiler == none && $runtime == ContentShellOnAndroid ]
+[ ($compiler == none) && $runtime == ContentShellOnAndroid ]
 *: Skip # Isolate tests are timing out flakily on Android content_shell.  Issue 19795
 
 [ $compiler == dart2js && $runtime == safarimobilesim ]
@@ -56,6 +56,9 @@
 browser/issue_12474_test: CompileTimeError # Issue 22529
 enum_const_test/02: RuntimeError # Issue 21817
 
+[ $compiler == dart2js && $cps_ir ]
+isolate_current_test: RuntimeError # Please triage this failure.
+
 [ $compiler == dart2js && $runtime != d8 ]
 error_exit_at_spawn_test: Skip # Issue 23876
 error_at_spawn_test: Skip # Issue 23876
@@ -78,47 +81,30 @@
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 unresolved_ports_test: Pass, Timeout # Issue 15610
 
-[ $compiler == none && $runtime == drt ]
+[ ($compiler == none) && $runtime == drt ]
 spawn_uri_nested_vm_test: Skip # Issue 14463
 
 [ $jscl ]
 spawn_uri_multi_test/none: RuntimeError # Issue 13544
 
-[ $compiler == none && ($runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
-pause_test: Fail         # Not implemented yet
-
-[ $compiler == none && $runtime == ContentShellOnAndroid ]
+[ ($compiler == none) && $runtime == ContentShellOnAndroid ]
 nested_spawn2_test: Skip # Issue 19127: This test is timing out.
 
-[ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none) && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
 spawn_uri_nested_vm_test: Skip # Issue 14479: This test is timing out.
 
-[ $compiler == none && ( $runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
-typed_message_test: Crash, Fail # Issue 13921, 14400
-message_enum_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-compile_time_error_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-isolate_import_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-issue_21398_parent_isolate_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-issue_21398_parent_isolate1_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
+[ ($compiler == none) && $runtime == dartium && $arch == x64 ]
+isolate/spawn_uri_multi_test/01: Skip # Times out. Issue 24795
+
+[ ($compiler == none) && ( $runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
+typed_message_test: Skip # Issue 13921, 14400
 isolate_stress_test: Skip # Issue 13921 Dom isolates don't support spawnFunction
-message3_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-start_paused_test: Fail, OK   # Issue 13921 Dom isolates don't support spawnFunction
-object_leak_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-simple_message_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-spawn_uri_missing_from_isolate_test: RuntimeError # Issue 17649
+object_leak_test: Skip # Issue 13921 Dom isolates don't support spawnFunction
+spawn_uri_missing_from_isolate_test: Skip # Issue 17649
 spawn_uri_missing_test: SkipSlow # Times out.
-isolate_current_test: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
-function_send_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-ondone_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-kill_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-kill2_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
 kill3_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-kill_self_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-handle_error_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-handle_error2_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
-handle_error3_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
 timer_isolate_test: Fail, Pass # Issue 15487. Issue 13921: Dom isolates don't support spawnFunction
-deferred_in_isolate2_test: Fail, OK  # Issue 16209, 13921 Dom isolates don't support spawnFunction
+deferred_in_isolate2_test: Skip  # Issue 16209, 13921 Dom isolates don't support spawnFunction
 bool_from_environment_default_value_test: Skip
 int_from_environment_default_value_test: Skip
 string_from_environment_default_value_test: Skip
@@ -128,16 +114,79 @@
 error_exit_at_spawnuri_test: SkipByDesign  # 13921 Dom isolates don't support spawnFunction
 error_at_spawnuri_test: SkipByDesign  # 13921 Dom isolates don't support spawnFunction
 exit_at_spawnuri_test: SkipByDesign  # 13921 Dom isolates don't support spawnFunction
+issue_21398_parent_isolate2_test/01: SkipByDesign  # Uses spawnFunction
+compile_time_error_test/none: RuntimeError, OK  # Uses Isolate.spawn.
+function_send_test: RuntimeError, OK  # Uses Isolate.spawn.
+handle_error2_test: RuntimeError, OK  # Uses Isolate.spawn.
+handle_error3_test: RuntimeError, OK  # Uses Isolate.spawn.
+handle_error_test: RuntimeError, OK  # Uses Isolate.spawn.
+isolate_current_test: RuntimeError, OK  # Uses Isolate.spawn.
+isolate_import_test/none: RuntimeError, OK  # Uses Isolate.spawn.
+issue_21398_parent_isolate1_test: RuntimeError, OK  # Uses Isolate.spawn.
+issue_21398_parent_isolate_test: RuntimeError, OK  # Uses Isolate.spawn.
+kill2_test: RuntimeError, OK  # Uses Isolate.spawn.
+kill_self_test: RuntimeError, OK  # Uses Isolate.spawn.
+kill_test: RuntimeError, OK  # Uses Isolate.spawn.
+message3_test/byteBuffer: RuntimeError, OK  # Uses Isolate.spawn.
+message3_test/constInstance: RuntimeError, OK  # Uses Isolate.spawn.
+message3_test/constList: RuntimeError, OK  # Uses Isolate.spawn.
+message3_test/constList_identical: RuntimeError, OK  # Uses Isolate.spawn.
+message3_test/constMap: RuntimeError, OK  # Uses Isolate.spawn.
+message3_test/fun: RuntimeError, OK  # Uses Isolate.spawn.
+message3_test/none: RuntimeError, OK  # Uses Isolate.spawn.
+message_enum_test: RuntimeError, OK  # Uses Isolate.spawn.
+ondone_test: RuntimeError, OK  # Uses Isolate.spawn.
+pause_test: RuntimeError, OK  # Uses Isolate.spawn.
+simple_message_test/none: RuntimeError, OK  # Uses Isolate.spawn.
+start_paused_test: RuntimeError, OK  # Uses Isolate.spawn.
+message3_test/int32x4: RuntimeError, OK  # Uses Isolate.spawn.
 
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 browser/typed_data_message_test: StaticWarning
 mint_maker_test: StaticWarning
 
 [ $compiler != none || $runtime != vm ]
 package_root_test: SkipByDesign  # Uses Isolate.packageRoot
-package_map_test: SkipByDesign  # Uses Isolate.packageMap
+package_config_test: SkipByDesign  # Uses Isolate.packageConfig
+package_resolve_test: SkipByDesign  # Uses Isolate.resolvePackageUri
+spawn_uri_fail_test: SkipByDesign  # Uses dart:io.
+scenarios/*: SkipByDesign  # Use automatic package resolution, spawnFunction and .dart URIs.
 
-[ $compiler == dart2js && $cps_ir ]
-deferred_in_isolate2_test: RuntimeError # A.loadLibrary is not a function
-isolate_current_test: RuntimeError # Please triage this failure.
+[ ($noopt || $compiler == precompiler) ]
+# Imports dart:mirrors
+count_test: CompileTimeError
+cross_isolate_message_test: CompileTimeError
+illegal_msg_function_test: CompileTimeError
+illegal_msg_mirror_test: CompileTimeError
+isolate_complex_messages_test: CompileTimeError
+mandel_isolate_test: CompileTimeError
+message2_test: CompileTimeError
+message_test: CompileTimeError
+mint_maker_test: CompileTimeError
+nested_spawn2_test: CompileTimeError
+nested_spawn_test: CompileTimeError
+raw_port_test: CompileTimeError
+request_reply_test: CompileTimeError
+spawn_function_custom_class_test: CompileTimeError
+spawn_function_test: CompileTimeError
+stacktrace_message_test: CompileTimeError
+stacktrace_message_test: CompileTimeError
+static_function_test: CompileTimeError
+unresolved_ports_test: CompileTimeError
+
+[ $runtime == dart_precompiled ]
+deferred_in_isolate_test: Skip # Isolate.spawnUri
+deferred_in_isolate2_test: Skip # Isolate.spawnUri
+exit_at_spawnuri_test: Skip # Isolate.spawnUri
+error_exit_at_spawnuri_test: Skip # Isolate.spawnUri
+issue_24243_parent_isolate_test: Skip # Isolate.spawnUri
+issue_21398_parent_isolate1_test: Skip # Isolate.spawnUri
+spawn_uri_exported_main_test: Skip # Isolate.spawnUri
+spawn_uri_test: Skip # Isolate.spawnUri
+spawn_uri_nested_vm_test: Skip # Isolate.spawnUri
+deferred_in_isolate_test: Skip # Isolate.spawnUri
+spawn_uri_multi_test: Skip # Isolate.spawnUri
+spawn_uri_vm_test: Skip # Isolate.spawnUri
+issue_21398_parent_isolate_test: Skip # Isolate.spawnUri
+error_at_spawnuri_test: Skip # Isolate.spawnUri
diff --git a/tests/isolate/isolate_import_test.dart b/tests/isolate/isolate_import_test.dart
index 5fa0f32..8d9f6a1 100644
--- a/tests/isolate/isolate_import_test.dart
+++ b/tests/isolate/isolate_import_test.dart
@@ -7,10 +7,11 @@
 /*  /// 01: runtime error, static type warning
 import 'dart:isolate';
 */  /// 01: continued
+import 'package:async_helper/async_helper.dart';
 
 void entry(msg) {}
 
 main() {
-  Isolate.spawn(entry, null);
+  asyncStart();
+  Isolate.spawn(entry, null).whenComplete(asyncEnd);
 }
-
diff --git a/tests/isolate/issue_21398_parent_isolate1_test.dart b/tests/isolate/issue_21398_parent_isolate1_test.dart
index 1c3aeb8..6f036bd 100644
--- a/tests/isolate/issue_21398_parent_isolate1_test.dart
+++ b/tests/isolate/issue_21398_parent_isolate1_test.dart
@@ -10,6 +10,7 @@
 import 'dart:isolate';
 import 'dart:async';
 import "package:expect/expect.dart";
+import 'package:async_helper/async_helper.dart';
 
 class FromMainIsolate {
   String toString() => 'from main isolate';
@@ -25,6 +26,7 @@
       Expect.isTrue(msg is FromMainIsolate);
       Expect.equals(10, msg.fld);
       receivePort.close();
+      sendPort.send("done");
     },
     onError: (e) => print('$e')
   );
@@ -57,37 +59,44 @@
   // create a receivePort and send it's sendPort back and then it will just
   // sit there listening for a message from the second isolate spawned
   // using spawnFunction.
-  Isolate.spawn(func1Child, [receive1.sendPort]).then(
+  asyncStart();
+  return Isolate.spawn(func1Child, [receive1.sendPort]).then(
     (isolate) {
       receive1.listen(
         (msg) {
-          Expect.isTrue(msg is SendPort);
-          spawnFunctionIsolate1SendPort = msg;
-          receive1.close();
+          if (msg is SendPort) {
+            spawnFunctionIsolate1SendPort = msg;
 
-          // Now spawn the second isolate using spawnFunction, this isolate
-          // will create a receivePort and send it's sendPort back and then
-          // wait for the third isolate spawned using spawnUri to send it
-          // a sendPort to which it will try and send a non "literal-like"
-          // object.
-          Isolate.spawn(func2Child, [receive2.sendPort]).then(
-            (isolate) {
-              receive2.listen(
-                (msg) {
-                  spawnFunctionIsolate2SendPort = msg;
-                  receive2.close();
+            // Now spawn the second isolate using spawnFunction, this isolate
+            // will create a receivePort and send it's sendPort back and then
+            // wait for the third isolate spawned using spawnUri to send it
+            // a sendPort to which it will try and send a non "literal-like"
+            // object.
+            Isolate.spawn(func2Child, [receive2.sendPort]).then(
+              (isolate) {
+                receive2.listen(
+                  (msg) {
+                    spawnFunctionIsolate2SendPort = msg;
+                    receive2.close();
 
-                  // Now spawn an isolate using spawnUri and send these send
-                  // ports over to it. This isolate will send one of the
-                  // sendports over to the other.
-                  Isolate.spawnUri(Uri.parse('issue_21398_child_isolate1.dart'),
-                                   [spawnFunctionIsolate1SendPort,
-                                    spawnFunctionIsolate2SendPort], "no-msg");
-                },
-                onError: (e) => print('$e')
-              );
-            }
-          );
+                    // Now spawn an isolate using spawnUri and send these send
+                    // ports over to it. This isolate will send one of the
+                    // sendports over to the other.
+                    Isolate
+                        .spawnUri(Uri.parse('issue_21398_child_isolate1.dart'),
+                                     [spawnFunctionIsolate1SendPort,
+                                       spawnFunctionIsolate2SendPort], "no-msg");
+                  },
+                  onError: (e) => print('$e')
+                );
+              }
+            );
+        } else  if (msg == "done") {
+            receive1.close();
+            asyncEnd();
+          } else {
+            Expect.fail("Invalid message received: $msg");
+          }
         },
         onError: (e) => print('$e')
       );
@@ -105,6 +114,7 @@
       Expect.isTrue(msg is String);
       Expect.equals("Invalid Argument(s).", msg);
       receivePort.close();
+      sendPort.send("done");
     },
     onError: (e) => print('$e')
   );
@@ -122,13 +132,13 @@
   // create a receivePort and send it's sendPort back and then it will just
   // sit there listening for a message from the second isolate spawned
   // using spawnFunction.
+  asyncStart();
   Isolate.spawn(uriChild, [receive1.sendPort]).then(
     (isolate) {
       receive1.listen(
         (msg) {
-          Expect.isTrue(msg is SendPort);
-          spawnFunctionIsolateSendPort = msg;
-          receive1.close();
+          if (msg is SendPort) {
+            spawnFunctionIsolateSendPort = msg;
 
           // Now spawn the second isolate using spawnUri, this isolate
           // will create a receivePort and send it's sendPort back and then
@@ -149,12 +159,18 @@
                   // sendports over to the other.
                   Isolate.spawnUri(Uri.parse('issue_21398_child_isolate1.dart'),
                                    [spawnFunctionIsolateSendPort,
-                                    spawnUriIsolateSendPort], "no-msg");
+                                     spawnUriIsolateSendPort], "no-msg");
                 },
                 onError: (e) => print('$e')
               );
             }
           );
+          } else if (msg == "done") {
+            receive1.close();
+            asyncEnd();
+          } else {
+            Expect.fail("Invalid message received: $msg");
+          }
         },
         onError: (e) => print('$e')
       );
diff --git a/tests/isolate/issue_21398_parent_isolate2_test.dart b/tests/isolate/issue_21398_parent_isolate2_test.dart
index 92754fd..da94b56 100644
--- a/tests/isolate/issue_21398_parent_isolate2_test.dart
+++ b/tests/isolate/issue_21398_parent_isolate2_test.dart
@@ -9,6 +9,7 @@
 import 'dart:isolate';
 import 'dart:async';
 import "package:expect/expect.dart";
+import 'package:async_helper/async_helper.dart';
 
 import "deferred_loaded_lib.dart" deferred as lib;
 
@@ -27,6 +28,7 @@
 
 void helperFunction() {
   var receivePort = new ReceivePort();
+  asyncStart();
 
   // Spawn an isolate using spawnFunction.
   Isolate.spawn(funcChild, [receivePort.sendPort]).then(
@@ -36,12 +38,14 @@
           // We don't expect to receive any valid messages.
           Expect.fail("We don't expect to receive any valid messages");
           receivePort.close();
+          asyncEnd();
         },
         onError: (e) {
           // We don't expect to receive any error messages, per spec listen
           // does not receive an error object.
           Expect.fail("We don't expect to receive any error messages");
           receivePort.close();
+          asyncEnd();
         }
       );
     }
diff --git a/tests/isolate/issue_21398_parent_isolate_test.dart b/tests/isolate/issue_21398_parent_isolate_test.dart
index fb4b0fb..76e7e0d 100644
--- a/tests/isolate/issue_21398_parent_isolate_test.dart
+++ b/tests/isolate/issue_21398_parent_isolate_test.dart
@@ -9,6 +9,7 @@
 import 'dart:isolate';
 import 'dart:async';
 import "package:expect/expect.dart";
+import 'package:async_helper/async_helper.dart';
 
 class FromMainIsolate {
   String toString() => 'from main isolate';
@@ -29,13 +30,16 @@
 
   // First spawn an isolate using spawnURI and have it
   // send back a "non-literal" like object.
+  asyncStart();
   Isolate.spawnUri(Uri.parse('issue_21398_child_isolate.dart'),
                    [],
                    [new FromMainIsolate(), receive1.sendPort]).catchError(
     (error) {
       Expect.isTrue(error is ArgumentError);
+      asyncEnd();
     }
   );
+  asyncStart();
   Isolate.spawnUri(Uri.parse('issue_21398_child_isolate.dart'),
                    [],
                    receive1.sendPort).then(
@@ -44,6 +48,7 @@
         (msg) {
           Expect.stringEquals(msg, "Invalid Argument(s).");
           receive1.close();
+          asyncEnd();
         },
         onError: (e) => print('$e')
       );
@@ -53,7 +58,8 @@
   // Now spawn an isolate using spawnFunction and send it a "non-literal"
   // like object and also have the child isolate send back a "non-literal"
   // like object.
-  Isolate.spawn(funcChild, 
+  asyncStart();
+  Isolate.spawn(funcChild,
                 [new FromMainIsolate(), receive2.sendPort]).then(
     (isolate) {
       receive2.listen(
@@ -61,6 +67,7 @@
           Expect.isTrue(msg is FromMainIsolate);
           Expect.equals(10, msg.fld);
           receive2.close();
+          asyncEnd();
         },
         onError: (e) => print('$e')
       );
diff --git a/tests/isolate/message_enum_test.dart b/tests/isolate/message_enum_test.dart
index 7dbaec3..b06dfc3 100644
--- a/tests/isolate/message_enum_test.dart
+++ b/tests/isolate/message_enum_test.dart
@@ -5,6 +5,7 @@
 // SharedOptions=--enable-enum
 
 import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
 import "dart:isolate";
 
 enum Foo { BAR, BAZ }
@@ -18,7 +19,8 @@
     Expect.equals(42, map[key]);
     p.close();
   });
-  Isolate.spawn(sendIt, p.sendPort);
+  asyncStart();
+  Isolate.spawn(sendIt, p.sendPort).whenComplete(asyncEnd);
 }
 
 void sendIt(port) {
diff --git a/tests/isolate/package_config_test.dart b/tests/isolate/package_config_test.dart
new file mode 100644
index 0000000..1b55194
--- /dev/null
+++ b/tests/isolate/package_config_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final SPAWN_PACKAGE_CONFIG = "foobar:///no/such/file/";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageConfig(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   packageConfig: Uri.parse(SPAWN_PACKAGE_CONFIG));
+  p.handler = (msg) {
+    p.close();
+    if (msg[0] != SPAWN_PACKAGE_CONFIG) {
+      throw "Bad package config in child isolate: ${msg[0]}";
+    }
+    if (msg[1] != null) {
+      throw "Non-null loaded package config in isolate: ${msg[1]}";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package config: ${await Isolate.packageConfig}");
+}
+
+testPackageConfig(port) async {
+  var packageConfigStr = Platform.packageConfig;
+  var packageConfig = await Isolate.packageConfig;
+  print("Spawned isolate's package config flag: $packageConfigStr");
+  print("Spawned isolate's loaded package config: $packageConfig");
+  port.send([packageConfigStr, packageConfig?.toString()]);
+}
diff --git a/tests/isolate/package_resolve_test.dart b/tests/isolate/package_resolve_test.dart
new file mode 100644
index 0000000..4a1b584
--- /dev/null
+++ b/tests/isolate/package_resolve_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.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final SPAWN_PACKAGE_ROOT = "file:///no/such/package/root/";
+final PACKAGE_URI = "package:foo/bar.dart";
+final PACKAGE_PATH = "file:///no/such/package/root/foo/bar.dart";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageResolution(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   packageRoot: Uri.parse(SPAWN_PACKAGE_ROOT));
+  p.handler = (msg) {
+    p.close();
+    if (msg is! List) {
+      print(msg.runtimeType);
+      throw "Failure return from spawned isolate:\n\n$msg";
+    }
+    if (msg[0] != SPAWN_PACKAGE_ROOT) {
+      throw "Bad package root in child isolate: ${msg[0]}";
+    }
+    if (msg[1] != PACKAGE_PATH) {
+      throw "Package path not matching: ${msg[1]}";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+}
+
+testPackageResolution(port) async {
+  try {
+    var packageRootStr = Platform.packageRoot;
+    var packageRoot = await Isolate.packageRoot;
+    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
+    print("Spawned isolate's package root flag: $packageRootStr");
+    print("Spawned isolate's loaded package root: $packageRoot");
+    print("Spawned isolate's resolved package path: $resolvedPkg");
+    port.send([packageRoot?.toString(), resolvedPkg?.toString()]);
+  } catch (e, s) {
+    port.send("$e\n$s\n");
+  }
+}
diff --git a/tests/isolate/package_root_test.dart b/tests/isolate/package_root_test.dart
new file mode 100644
index 0000000..79b1c35
--- /dev/null
+++ b/tests/isolate/package_root_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final SPAWN_PACKAGE_ROOT = "file:///no/such/file/";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageRoot(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   packageRoot: Uri.parse(SPAWN_PACKAGE_ROOT));
+  p.handler = (msg) {
+    p.close();
+    if (msg != SPAWN_PACKAGE_ROOT) {
+      throw "Bad package root in child isolate: $msg";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+}
+
+testPackageRoot(port) async {
+  var packageRoot = await Isolate.packageRoot;
+  print("Spawned isolate's package root: $packageRoot");
+  port.send(packageRoot.toString());
+}
diff --git a/tests/isolate/scenarios/automatic_resolution_root/package_resolve_test.dart b/tests/isolate/scenarios/automatic_resolution_root/package_resolve_test.dart
new file mode 100644
index 0000000..889763c
--- /dev/null
+++ b/tests/isolate/scenarios/automatic_resolution_root/package_resolve_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final PACKAGE_URI = "package:foo/bar.dart";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageResolution(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   automaticPackageResolution: true);
+  p.handler = (msg) {
+    p.close();
+    if (msg is! List) {
+      print(msg.runtimeType);
+      throw "Failure return from spawned isolate:\n\n$msg";
+    }
+    var child_pkg_root = Platform.script.resolve("packages/");
+    if (msg[0] != child_pkg_root.toString()) {
+      throw "Bad package root in child isolate: ${msg[0]}.\n"
+            "Expected: $child_pkg_root";
+    }
+    var child_pkg_path = child_pkg_root.resolve("foo/bar.dart");
+    if (msg[1] != child_pkg_path.toString()) {
+      throw "Package path not matching: ${msg[1]}\n"
+            "Expected $child_pkg_path";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+}
+
+testPackageResolution(port) async {
+  try {
+    var packageRootStr = Platform.packageRoot;
+    var packageConfigStr = Platform.packageConfig;
+    var packageRoot = await Isolate.packageRoot;
+    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
+    print("Spawned isolate's package root flag: $packageRootStr");
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package root: $packageRoot");
+    print("Spawned isolate's resolved package path: $resolvedPkg");
+    port.send([packageRoot?.toString(), resolvedPkg?.toString()]);
+  } catch (e, s) {
+    port.send("$e\n$s\n");
+  }
+}
diff --git a/tests/isolate/scenarios/automatic_resolution_root/packages/empty_file b/tests/isolate/scenarios/automatic_resolution_root/packages/empty_file
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/isolate/scenarios/automatic_resolution_root/packages/empty_file
diff --git a/tests/isolate/scenarios/automatic_resolution_spec/.packages b/tests/isolate/scenarios/automatic_resolution_spec/.packages
new file mode 100644
index 0000000..79bcf43
--- /dev/null
+++ b/tests/isolate/scenarios/automatic_resolution_spec/.packages
@@ -0,0 +1 @@
+foo:file:///no/such/directory/
diff --git a/tests/isolate/scenarios/automatic_resolution_spec/package_resolve_test.dart b/tests/isolate/scenarios/automatic_resolution_spec/package_resolve_test.dart
new file mode 100644
index 0000000..67b4d1e
--- /dev/null
+++ b/tests/isolate/scenarios/automatic_resolution_spec/package_resolve_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final PACKAGE_URI = "package:foo/bar.dart";
+final PACKAGE_PATH = "file:///no/such/directory/bar.dart";
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageResolution(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   automaticPackageResolution: true);
+  p.handler = (msg) {
+    p.close();
+    if (msg is! List) {
+      print(msg.runtimeType);
+      throw "Failure return from spawned isolate:\n\n$msg";
+    }
+    var child_pkg_config = Platform.script.resolve(".packages");
+    if (msg[0] != child_pkg_config.toString()) {
+      throw "Bad package config in child isolate: ${msg[0]}\n"
+            "Expected: $child_pkg_config";
+    }
+    if (msg[1] != PACKAGE_PATH) {
+      throw "Package path not matching: ${msg[1]}";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+}
+
+testPackageResolution(port) async {
+  try {
+    var packageRootStr = Platform.packageRoot;
+    var packageConfigStr = Platform.packageConfig;
+    var packageConfig = await Isolate.packageConfig;
+    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
+    print("Spawned isolate's package root flag: $packageRootStr");
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package config: $packageConfig");
+    print("Spawned isolate's resolved package path: $resolvedPkg");
+    port.send([packageConfig?.toString(), resolvedPkg?.toString()]);
+  } catch (e, s) {
+    port.send("$e\n$s\n");
+  }
+}
diff --git a/tests/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart b/tests/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
new file mode 100644
index 0000000..8884d4e
--- /dev/null
+++ b/tests/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:isolate';
+
+final PACKAGE_URI = "package:foo/bar.dart";
+final PACKAGE_PATH = "file:///no/such/directory/bar.dart";
+
+final PACKAGE_SPEC = """
+# This is the content of a .packages file.
+foo:file:///no/such/directory/
+""";
+
+
+main([args, port]) async {
+  if (port != null) {
+    testPackageResolution(port);
+    return;
+  }
+  var data = new Uri.dataFromString(PACKAGE_SPEC);
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   packageConfig: data);
+  p.handler = (msg) {
+    p.close();
+    if (msg is! List) {
+      print(msg.runtimeType);
+      throw "Failure return from spawned isolate:\n\n$msg";
+    }
+    if (msg[0] != data.toString()) {
+      throw "Bad package config in child isolate: ${msg[0]}\n"
+            "Expected: $data";
+    }
+    if (msg[1] != PACKAGE_PATH) {
+      throw "Package path not matching: ${msg[1]}";
+    }
+    print("SUCCESS");
+  };
+  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+}
+
+testPackageResolution(port) async {
+  try {
+    var packageRootStr = Platform.packageRoot;
+    var packageConfigStr = Platform.packageConfig;
+    var packageConfig = await Isolate.packageConfig;
+    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
+    print("Spawned isolate's package root flag: $packageRootStr");
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package config: $packageConfig");
+    print("Spawned isolate's resolved package path: $resolvedPkg");
+    port.send([packageConfig?.toString(), resolvedPkg?.toString()]);
+  } catch (e, s) {
+    port.send("$e\n$s\n");
+  }
+}
diff --git a/tests/isolate/scenarios/package_relative_root/package_relative_root_test.dart b/tests/isolate/scenarios/package_relative_root/package_relative_root_test.dart
new file mode 100644
index 0000000..a3a8533
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_root/package_relative_root_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// PackageRoot=none
+
+import 'dart:io';
+import 'dart:isolate';
+
+import "package:foo/foo.dart";
+import "package:bar/bar.dart";
+
+var CONFIG_URI = "package:bar/spawned_packages/";
+
+main([args, port]) async {
+  if (port != null) {
+    testCorrectBarPackage(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   packageRoot: Uri.parse(CONFIG_URI));
+  p.handler = (msg) {
+    p.close();
+    if (msg is! List) {
+      print(msg.runtimeType);
+      throw "Failure return from spawned isolate:\n\n$msg";
+    }
+    if (msg[0] != "Foo") {
+      throw "Bad package config in child isolate: ${msg[0]}\n"
+            "Expected: 'Foo'";
+    }
+    if (msg[1] != "Bar2") {
+      throw "Package path not matching: ${msg[1]}\n"
+            "Expected: 'Bar2'";
+    }
+    print("SUCCESS");
+  };
+  if (Bar.value != "Bar1") {
+    throw "Spawning isolate package:bar invalid.";
+  }
+  print("Spawned isolate resolved $CONFIG_URI to: "
+        "${await Isolate.resolvePackageUri(Uri.parse(CONFIG_URI))}");
+}
+
+testCorrectBarPackage(port) async {
+  try {
+    var packageRootStr = Platform.packageRoot;
+    var packageConfigStr = Platform.packageConfig;
+    var packageConfig = await Isolate.packageConfig;
+    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(CONFIG_URI));
+    print("Spawned isolate's package root flag: $packageRootStr");
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package config: $packageConfig");
+    print("Spawned isolate's resolved package path: $resolvedPkg");
+    port.send([Foo.value, Bar.value]);
+  } catch (e, s) {
+    port.send("$e\n$s\n");
+  }
+}
diff --git a/tests/isolate/scenarios/package_relative_root/packages/bar/bar.dart b/tests/isolate/scenarios/package_relative_root/packages/bar/bar.dart
new file mode 100644
index 0000000..7fb99e2
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_root/packages/bar/bar.dart
@@ -0,0 +1,3 @@
+class Bar {
+  static var value = "Bar1";
+}
diff --git a/tests/isolate/scenarios/package_relative_root/packages/bar/spawned_packages/bar/bar.dart b/tests/isolate/scenarios/package_relative_root/packages/bar/spawned_packages/bar/bar.dart
new file mode 100644
index 0000000..cd6723a
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_root/packages/bar/spawned_packages/bar/bar.dart
@@ -0,0 +1,3 @@
+class Bar {
+  static var value = "Bar2";
+}
diff --git a/tests/isolate/scenarios/package_relative_root/packages/bar/spawned_packages/foo/foo.dart b/tests/isolate/scenarios/package_relative_root/packages/bar/spawned_packages/foo/foo.dart
new file mode 100644
index 0000000..ba907d1
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_root/packages/bar/spawned_packages/foo/foo.dart
@@ -0,0 +1,3 @@
+class Foo {
+  static var value = "Foo";
+}
diff --git a/tests/isolate/scenarios/package_relative_root/packages/foo/foo.dart b/tests/isolate/scenarios/package_relative_root/packages/foo/foo.dart
new file mode 100644
index 0000000..ba907d1
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_root/packages/foo/foo.dart
@@ -0,0 +1,3 @@
+class Foo {
+  static var value = "Foo";
+}
diff --git a/tests/isolate/scenarios/package_relative_spec/.packages b/tests/isolate/scenarios/package_relative_spec/.packages
new file mode 100644
index 0000000..d7a0d92
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_spec/.packages
@@ -0,0 +1,4 @@
+# This is the package spec for the spawning isolate.
+
+foo:foo_package/
+bar:bar1_package/
diff --git a/tests/isolate/scenarios/package_relative_spec/bar1_package/bar.dart b/tests/isolate/scenarios/package_relative_spec/bar1_package/bar.dart
new file mode 100644
index 0000000..7fb99e2
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_spec/bar1_package/bar.dart
@@ -0,0 +1,3 @@
+class Bar {
+  static var value = "Bar1";
+}
diff --git a/tests/isolate/scenarios/package_relative_spec/bar1_package/package.config b/tests/isolate/scenarios/package_relative_spec/bar1_package/package.config
new file mode 100644
index 0000000..b580fe3
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_spec/bar1_package/package.config
@@ -0,0 +1,4 @@
+# This is the package spec for the spawned isolate.
+
+foo:../foo_package/
+bar:../bar2_package/
diff --git a/tests/isolate/scenarios/package_relative_spec/bar2_package/bar.dart b/tests/isolate/scenarios/package_relative_spec/bar2_package/bar.dart
new file mode 100644
index 0000000..cd6723a
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_spec/bar2_package/bar.dart
@@ -0,0 +1,3 @@
+class Bar {
+  static var value = "Bar2";
+}
diff --git a/tests/isolate/scenarios/package_relative_spec/foo_package/foo.dart b/tests/isolate/scenarios/package_relative_spec/foo_package/foo.dart
new file mode 100644
index 0000000..ba907d1
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_spec/foo_package/foo.dart
@@ -0,0 +1,3 @@
+class Foo {
+  static var value = "Foo";
+}
diff --git a/tests/isolate/scenarios/package_relative_spec/package_relative_spec_test.dart b/tests/isolate/scenarios/package_relative_spec/package_relative_spec_test.dart
new file mode 100644
index 0000000..e22d3ef
--- /dev/null
+++ b/tests/isolate/scenarios/package_relative_spec/package_relative_spec_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// PackageRoot=none
+
+import 'dart:io';
+import 'dart:isolate';
+
+import "package:foo/foo.dart";
+import "package:bar/bar.dart";
+
+var CONFIG_URI = "package:bar/package.config";
+
+main([args, port]) async {
+  if (port != null) {
+    testCorrectBarPackage(port);
+    return;
+  }
+  var p = new RawReceivePort();
+  Isolate.spawnUri(Platform.script,
+                   [],
+                   p.sendPort,
+                   packageConfig: Uri.parse(CONFIG_URI));
+  p.handler = (msg) {
+    p.close();
+    if (msg is! List) {
+      print(msg.runtimeType);
+      throw "Failure return from spawned isolate:\n\n$msg";
+    }
+    if (msg[0] != "Foo") {
+      throw "Bad package config in child isolate: ${msg[0]}\n"
+            "Expected: 'Foo'";
+    }
+    if (msg[1] != "Bar2") {
+      throw "Package path not matching: ${msg[1]}\n"
+            "Expected: 'Bar2'";
+    }
+    print("SUCCESS");
+  };
+  if (Bar.value != "Bar1") {
+    throw "Spawning isolate package:bar invalid.";
+  }
+  print("Spawned isolate resolved $CONFIG_URI to: "
+        "${await Isolate.resolvePackageUri(Uri.parse(CONFIG_URI))}");
+}
+
+testCorrectBarPackage(port) async {
+  try {
+    var packageRootStr = Platform.packageRoot;
+    var packageConfigStr = Platform.packageConfig;
+    var packageConfig = await Isolate.packageConfig;
+    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(CONFIG_URI));
+    print("Spawned isolate's package root flag: $packageRootStr");
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package config: $packageConfig");
+    print("Spawned isolate's resolved package path: $resolvedPkg");
+    port.send([Foo.value, Bar.value]);
+  } catch (e, s) {
+    port.send("$e\n$s\n");
+  }
+}
diff --git a/tests/isolate/spawn_uri_fail_test.dart b/tests/isolate/spawn_uri_fail_test.dart
new file mode 100644
index 0000000..659a798
--- /dev/null
+++ b/tests/isolate/spawn_uri_fail_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "dart:isolate";
+import "package:expect/expect.dart";
+
+main() async {
+  var pkgRoot = Uri.parse("file:///no/such/directory/");
+  var pkgConfig = Uri.parse("file:///no/such/.packages");
+  try {
+    var i = await Isolate.spawnUri(Platform.script, [], null,
+        packageRoot: pkgRoot, packageConfig: pkgConfig);
+  } catch (e) {
+    print(e);
+    Expect.isTrue(e is ArgumentError);
+  }
+  try {
+    var i = await Isolate.spawnUri(Platform.script, [], null,
+        packageRoot: pkgRoot, automaticPackageResolution: true);
+  } catch (e) {
+    print(e);
+    Expect.isTrue(e is ArgumentError);
+  }
+  try {
+    var i = await Isolate.spawnUri(Platform.script, [], null,
+        packageConfig: pkgConfig, automaticPackageResolution: true);
+  } catch (e) {
+    print(e);
+    Expect.isTrue(e is ArgumentError);
+  }
+  try {
+    var i = await Isolate.spawnUri(Platform.script, [], null,
+        packageRoot: pkgRoot, packageConfig: pkgConfig,
+        automaticPackageResolution: true);
+  } catch (e) {
+    print(e);
+    Expect.isTrue(e is ArgumentError);
+  }
+}
diff --git a/tests/language/abstract_beats_arguments_test.dart b/tests/language/abstract_beats_arguments_test.dart
new file mode 100644
index 0000000..9fa33e2
--- /dev/null
+++ b/tests/language/abstract_beats_arguments_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";
+
+// When an instantiation of an abstract class has the wrong arguments, an
+// AbstractClassInstantiationError is thrown, not a NoSuchMethodError.
+
+abstract class A {
+  A() { }
+}
+
+class B {
+  B() { }
+}
+
+bool isAbstractClassInstantiationError(e) =>
+    e is AbstractClassInstantiationError;
+
+bool isNoSuchMethodError(e) => e is NoSuchMethodError;
+
+void main() {
+  Expect.throws(() => new A(), isAbstractClassInstantiationError);
+
+  Expect.throws(() => new B(1), isNoSuchMethodError);
+  Expect.throws(() => new A(1), isAbstractClassInstantiationError);
+}
diff --git a/tests/language/and_operation_on_non_integer_operand_test.dart b/tests/language/and_operation_on_non_integer_operand_test.dart
deleted file mode 100644
index 9d7b067..0000000
--- a/tests/language/and_operation_on_non_integer_operand_test.dart
+++ /dev/null
@@ -1,20 +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.
-
-// Regression test for dart2js that used to miscompile boolean add operations 
-// if one of the operands was an int and the other was not (issue 22427).
-
-import "package:expect/expect.dart";
-
-class NotAnInt {
-  NotAnInt operator&(b) => this;
-}
-
-@AssumeDynamic() @NoInline()
-id(x) => x;
-
-main () {
-  var a = id(new NotAnInt());
-  Expect.equals(a, a & 5 & 2);
-}
diff --git a/tests/language/await_null_aware_test.dart b/tests/language/await_null_aware_test.dart
new file mode 100644
index 0000000..483d9dd
--- /dev/null
+++ b/tests/language/await_null_aware_test.dart
@@ -0,0 +1,23 @@
+// 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 issue dartbug.com/24392
+
+import 'package:expect/expect.dart';
+import 'dart:async';
+
+Future<int> f() async {
+  // Unreachable.
+  Expect.isTrue(false);
+}
+
+main() async {
+  int x = 1;
+  x ??= await f();
+  Expect.equals(1, x);
+
+  int y = 1;
+  y = y ?? await f();
+  Expect.equals(1, y);
+}
diff --git a/tests/language/config_import_lib1a.dart b/tests/language/config_import_lib1a.dart
new file mode 100644
index 0000000..814c15e
--- /dev/null
+++ b/tests/language/config_import_lib1a.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.
+
+String lib1() => "a";
diff --git a/tests/language/config_import_lib1b.dart b/tests/language/config_import_lib1b.dart
new file mode 100644
index 0000000..59212de
--- /dev/null
+++ b/tests/language/config_import_lib1b.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.
+
+String lib1() => "b";
diff --git a/tests/language/config_import_lib1c.dart b/tests/language/config_import_lib1c.dart
new file mode 100644
index 0000000..86fd9e9
--- /dev/null
+++ b/tests/language/config_import_lib1c.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.
+
+String lib1() => "c";
diff --git a/tests/language/config_import_lib2a.dart b/tests/language/config_import_lib2a.dart
new file mode 100644
index 0000000..00665dd
--- /dev/null
+++ b/tests/language/config_import_lib2a.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.
+
+String lib2() => "a";
diff --git a/tests/language/config_import_lib2b.dart b/tests/language/config_import_lib2b.dart
new file mode 100644
index 0000000..6d91daf
--- /dev/null
+++ b/tests/language/config_import_lib2b.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.
+
+String lib2() => "b";
diff --git a/tests/language/config_import_lib2c.dart b/tests/language/config_import_lib2c.dart
new file mode 100644
index 0000000..6ed0235
--- /dev/null
+++ b/tests/language/config_import_lib2c.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.
+
+String lib2() => "c";
diff --git a/tests/language/config_import_lib3a.dart b/tests/language/config_import_lib3a.dart
new file mode 100644
index 0000000..c2f9fec
--- /dev/null
+++ b/tests/language/config_import_lib3a.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.
+
+String lib3() => "a";
diff --git a/tests/language/config_import_lib3b.dart b/tests/language/config_import_lib3b.dart
new file mode 100644
index 0000000..b6d5afc
--- /dev/null
+++ b/tests/language/config_import_lib3b.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.
+
+String lib3() => "b";
diff --git a/tests/language/config_import_lib3c.dart b/tests/language/config_import_lib3c.dart
new file mode 100644
index 0000000..b984783
--- /dev/null
+++ b/tests/language/config_import_lib3c.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.
+
+String lib3() => "c";
diff --git a/tests/language/config_import_lib4a.dart b/tests/language/config_import_lib4a.dart
new file mode 100644
index 0000000..1607f07
--- /dev/null
+++ b/tests/language/config_import_lib4a.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.
+
+String lib4() => "a";
diff --git a/tests/language/config_import_lib4b.dart b/tests/language/config_import_lib4b.dart
new file mode 100644
index 0000000..9e2f08c
--- /dev/null
+++ b/tests/language/config_import_lib4b.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.
+
+String lib4() => "b";
diff --git a/tests/language/config_import_lib4c.dart b/tests/language/config_import_lib4c.dart
new file mode 100644
index 0000000..f4a1972
--- /dev/null
+++ b/tests/language/config_import_lib4c.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.
+
+String lib4() => "c";
diff --git a/tests/language/config_import_test.dart b/tests/language/config_import_test.dart
new file mode 100644
index 0000000..96cf3e3
--- /dev/null
+++ b/tests/language/config_import_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.
+//
+// DartOptions=-Did=true -Ddotted.id=some_string -Dlots.of.dots.In.id=false --conditional-directives
+// VMOptions=-Did=true -Ddotted.id=some_string -Dlots.of.dots.In.id=false --conditional-directives
+
+import 'package:expect/expect.dart';
+
+import 'config_import_lib1a.dart'
+  if (id) 'config_import_lib1b.dart'
+  if (not.set.id) 'config_import_lib1c.dart';
+
+import 'config_import_lib2a.dart'
+  if (not.set.id) 'config_import_lib2b.dart'
+  if (not.set.either) 'config_import_lib2c.dart';
+
+import 'config_import_lib3a.dart'
+  if (dotted.id == "some_string") 'config_import_lib3b.dart'
+  if (id) 'config_import_lib3c.dart';
+
+import 'config_import_lib4a.dart'
+  if (lots.of.dots.In.id == "other") 'config_import_lib4b.dart'
+  if (lots.of.dots.In.id == "false") 'config_import_lib4c.dart';
+
+main() {
+  Expect.equals("b", lib1());
+  Expect.equals("a", lib2());
+  Expect.equals("b", lib3());
+  Expect.equals("c", lib4());
+}
diff --git a/tests/language/const_for_in_variable_test.dart b/tests/language/const_for_in_variable_test.dart
new file mode 100644
index 0000000..a12cd55
--- /dev/null
+++ b/tests/language/const_for_in_variable_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+  for(
+      const                           /// 01: compile-time error
+      final                           /// 02: ok
+      int x in const [1, 2, 3]) {
+    break;
+  }
+}
\ No newline at end of file
diff --git a/tests/language/const_getter_test.dart b/tests/language/const_getter_test.dart
new file mode 100644
index 0000000..97717e8
--- /dev/null
+++ b/tests/language/const_getter_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that const getters are not allowed.
+
+import 'package:expect/expect.dart';
+
+class C {
+  const C();
+
+  const /// 01: compile-time error
+  get x => 1;
+}
+
+const /// 02: compile-time error
+get y => 2;
+
+main() {
+  Expect.equals(1, const C().x);
+  Expect.equals(2, y);
+}
diff --git a/tests/language/const_map2_test.dart b/tests/language/const_map2_test.dart
index 6b599f7..d32ca5b 100644
--- a/tests/language/const_map2_test.dart
+++ b/tests/language/const_map2_test.dart
@@ -14,10 +14,8 @@
   operator ==(o) => true;  /// 00: compile-time error
 }
 
-confuse(x) {
-  if (new DateTime.now() == 42) return confuse(2);
-  return x;
-}
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
 
 main() {
   // It is a compile-time error if the key type overrides operator ==.
diff --git a/tests/language/const_map_test.dart b/tests/language/const_map_test.dart
index 96db1d6..9cc0d5b 100644
--- a/tests/language/const_map_test.dart
+++ b/tests/language/const_map_test.dart
@@ -7,11 +7,8 @@
 /// Returns its argument.
 ///
 /// Prevents static optimizations and inlining.
-confuse(x) {
-  // DateTime.now() cannot be predicted statically.
-  if (new DateTime.now() == 42) return confuse(2);
-  return x;
-}
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
 
 main() {
   // Make sure that const maps use the == operator and not identical. The
diff --git a/tests/language/const_qq_test.dart b/tests/language/const_qq_test.dart
new file mode 100644
index 0000000..d1c1642
--- /dev/null
+++ b/tests/language/const_qq_test.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that ?? is compile-time constant.
+
+import "package:expect/expect.dart";
+
+const theNull = null;
+const notNull = const Object();
+
+// Top-level const field initializer.
+const test1 = theNull ?? notNull;
+const test2 = notNull ?? theNull;
+const test3 = theNull ?? theNull ?? notNull;
+const test4 = theNull ?? theNull ?? theNull;
+
+class P {
+  final v;
+  const P(this.v);
+}
+
+// Annotation parameter (not checked by test!)
+@P(theNull ?? notNull)
+@P(notNull ?? theNull)
+@P(theNull ?? theNull ?? notNull)
+@P(theNull ?? theNull ?? theNull)
+class C {
+  // Static const field initializer.
+  static const test5 = theNull ?? notNull;
+  static const test6 = notNull ?? theNull;
+  static const test7 = theNull ?? theNull ?? notNull;
+  static const test8 = theNull ?? theNull ?? theNull;
+
+  // (Constructor) parameter defaults.
+  final test9;
+  final test10;
+  final test11;
+  final test12;
+
+  // Const constructor initializer list.
+  final test13;
+  final test14;
+  final test15;
+  final test16;
+  final test17;
+
+  const C(x,
+          [this.test9  = theNull ?? notNull,
+           this.test10 = notNull ?? theNull,
+           this.test11 = theNull ?? theNull ?? notNull,
+           this.test12 = theNull ?? theNull ?? theNull])
+      : test13 = theNull ?? x,
+        test14 = notNull ?? x,
+        test15 = x ?? notNull,
+        test16 = theNull ?? theNull ?? x,
+        test17 = theNull ?? x ?? notNull;
+
+  List methodLocal() {
+    // Method local const variable initializer.
+    const test18 = theNull ?? notNull;
+    const test19 = notNull ?? theNull;
+    const test20 = theNull ?? theNull ?? notNull;
+    const test21 = theNull ?? theNull ?? theNull;
+
+    return const [test18, test19, test20, test21];
+  }
+
+  List expressionLocal() {
+    // Constant expression sub-expression.
+    return const [theNull ?? notNull,
+                  notNull ?? theNull,
+                  theNull ?? theNull ?? notNull,
+                  theNull ?? theNull ?? theNull];
+  }
+}
+
+main() {
+  Expect.identical(notNull, test1, "test1");
+  Expect.identical(notNull, test2, "test2");
+  Expect.identical(notNull, test3, "test3");
+  Expect.identical(theNull, test4, "test4");
+
+  Expect.identical(notNull, C.test5, "test5");
+  Expect.identical(notNull, C.test6, "test6");
+  Expect.identical(notNull, C.test7, "test7");
+  Expect.identical(theNull, C.test8, "test8");
+
+  const c1 = const C(null);
+  Expect.identical(notNull, c1.test9, "test9");
+  Expect.identical(notNull, c1.test10, "test10");
+  Expect.identical(notNull, c1.test11, "test11");
+  Expect.identical(theNull, c1.test12, "test12");
+
+  Expect.identical(theNull, c1.test13, "test13");
+  Expect.identical(notNull, c1.test14, "test14");
+  Expect.identical(notNull, c1.test15, "test15");
+  Expect.identical(theNull, c1.test16, "test16");
+  Expect.identical(notNull, c1.test17, "test17");
+
+  var list = c1.methodLocal();
+  Expect.identical(notNull, list[0], "test18");
+  Expect.identical(notNull, list[1], "test19");
+  Expect.identical(notNull, list[2], "test20");
+  Expect.identical(theNull, list[3], "test21");
+
+  list = c1.expressionLocal();
+  Expect.identical(notNull, list[0], "test22");
+  Expect.identical(notNull, list[1], "test23");
+  Expect.identical(notNull, list[2], "test24");
+  Expect.identical(theNull, list[3], "test25");
+
+  const c2 = const C(42);
+  Expect.identical(notNull, c2.test9, "test26");
+  Expect.identical(notNull, c2.test10, "test27");
+  Expect.identical(notNull, c2.test11, "test28");
+  Expect.identical(theNull, c2.test12, "test29");
+
+  Expect.identical(42     , c2.test13, "test30");
+  Expect.identical(notNull, c2.test14, "test31");
+  Expect.identical(42     , c2.test15, "test32");
+  Expect.identical(42     , c2.test16, "test33");
+  Expect.identical(42     , c2.test17, "test34");
+
+  list = c2.methodLocal();
+  Expect.identical(notNull, list[0], "test35");
+  Expect.identical(notNull, list[1], "test36");
+  Expect.identical(notNull, list[2], "test37");
+  Expect.identical(theNull, list[3], "test38");
+
+  list = c2.expressionLocal();
+  Expect.identical(notNull, list[0], "test39");
+  Expect.identical(notNull, list[1], "test40");
+  Expect.identical(notNull, list[2], "test41");
+  Expect.identical(theNull, list[3], "test42");
+}
diff --git a/tests/language/const_string_test.dart b/tests/language/const_string_test.dart
index 4736ca4..13f1a9c 100644
--- a/tests/language/const_string_test.dart
+++ b/tests/language/const_string_test.dart
@@ -6,6 +6,8 @@
 
 // Exercises compile-time string constants
 
+const yz = "y" + "z";
+
 main() {
   // Constant comparisons are independent of the quotes used.
   Expect.isTrue(identical("abcd", 'abcd'));
@@ -34,4 +36,16 @@
   Expect.isTrue(identical('a\'b\'cd', "a" "'b'" 'c' "d"));
   Expect.isTrue(identical('a"b"cd', 'a' '"b"' 'c' "d"));
   Expect.isTrue(identical("a\"b\"cd", 'a' '"b"' 'c' "d"));
+
+  const a = identical("ab", "a" + "b");
+  Expect.isTrue(a);
+
+  const b = identical("xyz", "x" + yz);
+  Expect.isTrue(b);
+
+  const c = identical("12", "1" "2");
+  Expect.isTrue(c);
+
+  const d = identical("zyz", "z$yz");
+  Expect.isTrue(d);
 }
diff --git a/tests/language/constant_string_interpolation2_test.dart b/tests/language/constant_string_interpolation2_test.dart
new file mode 100644
index 0000000..9853b0e
--- /dev/null
+++ b/tests/language/constant_string_interpolation2_test.dart
@@ -0,0 +1,97 @@
+// 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";
+
+// Regression test for issue #24839 - http://dartbug.com/24839
+
+const u1 = null;
+const int u2 = null;
+const List u3 = null;
+const u4 = const String.fromEnvironment("XXXXX");
+const u5 = const int.fromEnvironment("XXXXX");
+const u6 = const bool.fromEnvironment("XXXXX", defaultValue: null);
+const n1 = 42;
+const n2 = 3.1415;
+const int n3 = 37;
+const double n4 = 4.6692;
+const num n5 = b3 ? 1 : 2.71828;
+const n6 = const int.fromEnvironment("XXXXX", defaultValue: 87);
+const s1 = "s1";
+const String s2 = "s2";
+const String s3 = "$s1$s2";
+const s4 = const String.fromEnvironment("XXXXX", defaultValue: "s4");
+const b1 = true;
+const b2 = false;
+const b3 = b1 && (b2 || !b1);
+const b4 = const bool.fromEnvironment("XXXXX", defaultValue: true);
+
+// Individually
+const su1 = "$u1";
+const su2 = "$u2";
+const su3 = "$u3";
+const su4 = "$u4";
+const su5 = "$u5";
+const su6 = "$u6";
+const sn1 = "$n1";
+const sn2 = "$n2";
+const sn3 = "$n3";
+const sn4 = "$n4";
+const sn5 = "$n5";
+const sn6 = "$n6";
+const ss1 = "$s1";
+const ss2 = "$s2";
+const ss3 = "$s3";
+const ss4 = "$s4";
+const sb1 = "$b1";
+const sb2 = "$b2";
+const sb3 = "$b3";
+const sb4 = "$b4";
+
+// Constant variables in interpolation.
+const interpolation1 =
+  "$u1 $u2 $u3 $u4 $u5 $u6 $n1 $n2 $n3 $n4 $n5 $n6 $s1 $s2 $s3 $s4 $b1 $b2 $b3 $b4";
+// Constant expressions in interpolation.
+// (Single string, the linebreak to fit this into 80 chars is inside an
+// interpolation, which is allowed, even for single-line strings).
+const interpolation2 =
+    "${u1} ${u2} ${u3} ${u4} ${u5} ${u6} ${n1} ${n2} ${n3} ${n4} ${n5} ${n6} ${
+     s1} ${s2} ${s3} ${s4} ${b1} ${b2} ${b3} ${b4}";
+// Adjacent string literals are combined.
+const interpolation3 =
+  "$u1 $u2 $u3 $u4 $u5 " '$u6 $n1 $n2 $n3 $n4 '
+  """$n5 $n6 $s1 $s2 $s3 """ '''$s4 $b1 $b2 $b3 $b4''';
+// Nested interpolations.
+const interpolation4 =
+  "${"$u1 $u2 $u3 $u4 $u5 " '$u6 $n1 $n2 $n3 $n4'} ${
+     """$n5 $n6 $s1 $s2 $s3 """ '''$s4 $b1 $b2 $b3 $b4'''}";
+
+main() {
+  Expect.equals(u1.toString(), su1);
+  Expect.equals(u2.toString(), su2);
+  Expect.equals(u3.toString(), su3);
+  Expect.equals(u4.toString(), su4);
+  Expect.equals(u5.toString(), su5);
+  Expect.equals(u6.toString(), su6);
+  Expect.equals(n1.toString(), sn1);
+  Expect.equals(n2.toString(), sn2);
+  Expect.equals(n3.toString(), sn3);
+  Expect.equals(n4.toString(), sn4);
+  Expect.equals(n5.toString(), sn5);
+  Expect.equals(n6.toString(), sn6);
+  Expect.equals(s1.toString(), ss1);
+  Expect.equals(s2.toString(), ss2);
+  Expect.equals(s3.toString(), ss3);
+  Expect.equals(s4.toString(), ss4);
+  Expect.equals(b1.toString(), sb1);
+  Expect.equals(b2.toString(), sb2);
+  Expect.equals(b3.toString(), sb3);
+  Expect.equals(b4.toString(), sb4);
+  var expect = "null null null null null null 42 3.1415 37 4.6692 2.71828 87 "
+               "s1 s2 s1s2 s4 true false false true";
+  Expect.equals(expect, interpolation1);
+  Expect.equals(expect, interpolation2);
+  Expect.equals(expect, interpolation3);
+  Expect.equals(expect, interpolation4);
+}
diff --git a/tests/language/constructor_redirect2_test.dart b/tests/language/constructor_redirect2_test.dart
index e0ceb8d..b8d8db4 100644
--- a/tests/language/constructor_redirect2_test.dart
+++ b/tests/language/constructor_redirect2_test.dart
@@ -23,7 +23,7 @@
 main() {
   new A(3);
   new A.illegalBody(10);         /// 01: continued
-  new A.illegalInit(10);         /// 02: continued
+  new A.illegalInit();           /// 02: continued
   new A.illegalFormal(10);       /// 03: continued
-  new A.illegalSuper(10);        /// 04: continued
+  new A.illegalSuper();          /// 04: continued
 }
diff --git a/tests/language/enum_test.dart b/tests/language/enum_test.dart
index 84daba1..0e41965 100644
--- a/tests/language/enum_test.dart
+++ b/tests/language/enum_test.dart
@@ -11,6 +11,7 @@
 enum Enum3 { B, C }
 enum Enum4 { D, E, }
 enum Enum5 { F, G, H }
+enum _Enum6 { I, _J }
 
 main() {
   Expect.equals('Enum1._', Enum1._.toString());
@@ -21,6 +22,7 @@
   Expect.equals('Enum2.A', Enum2.A.toString());
   Expect.equals(0, Enum2.A.index);
   Expect.listEquals([Enum2.A], Enum2.values);
+  Expect.identical(const [Enum2.A], Enum2.values);
   Enum2.values.forEach(test2);
 
   Expect.equals('Enum3.B', Enum3.B.toString());
@@ -45,6 +47,9 @@
   Expect.equals(2, Enum5.H.index);
   Expect.listEquals([Enum5.F, Enum5.G, Enum5.H], Enum5.values);
   Enum5.values.forEach(test5);
+
+  Expect.equals('_Enum6.I', _Enum6.I.toString());
+  Expect.equals('_Enum6._J', _Enum6._J.toString());
 }
 
 test1(Enum1 e) {
diff --git a/tests/language/generic_instanceof4_test.dart b/tests/language/generic_instanceof4_test.dart
index 15896cb..95ff9bb 100644
--- a/tests/language/generic_instanceof4_test.dart
+++ b/tests/language/generic_instanceof4_test.dart
@@ -6,9 +6,8 @@
 import "package:expect/expect.dart";
 
 class A<T> {
+  @NoInline()
   foo(x) {
-    // Don't inline.
-    if (new DateTime.now().millisecondsSinceEpoch == 42) return foo(x);
     return x is T;
   }
 }
@@ -16,9 +15,8 @@
 class BB {}
 
 class B<T> implements BB {
+  @NoInline()
   foo() {
-    // Don't inline.
-    if (new DateTime.now().millisecondsSinceEpoch == 42) return foo();
     return new A<T>().foo(new B());
   }
 }
diff --git a/tests/language/issue23244_test.dart b/tests/language/issue23244_test.dart
index b155769..f8a3f32 100644
--- a/tests/language/issue23244_test.dart
+++ b/tests/language/issue23244_test.dart
@@ -5,6 +5,7 @@
 // Regression test case for http://dartbug.com/23244
 import 'dart:async';
 import 'dart:isolate';
+import 'package:async_helper/async_helper.dart';
 
 enum Fisk {
   torsk,
@@ -27,6 +28,7 @@
 
 main() async {
   var port = new ReceivePort();
+  asyncStart();
   await Isolate.spawn(isolate1, port.sendPort);
   Completer completer1 = new Completer();
   port.listen((message) {
@@ -53,6 +55,7 @@
     port.close();
     expectTorsk(message[0]);
     expectTorsk(message[1]);
+    asyncEnd();
   });
 }
 
@@ -61,4 +64,3 @@
     throw "$fisk isn't a ${Fisk.torsk}";
   }
 }
-
diff --git a/tests/language/language.status b/tests/language/language.status
index 28dedba..65a750e 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -5,15 +5,22 @@
 # This directory contains tests that are intended to show the
 # current state of the language.
 
-[ $compiler == none ]
+[ ($compiler == none || $compiler == precompiler) ]
 built_in_identifier_prefix_test: Fail # Issue 6970
 tearoff_constructor_basic_test: Skip # Crashes in checked mode -- hausner investigating
+const_qq_test: Fail
 
 # These bugs refer currently ongoing language discussions.
-constructor_initializer_test/none: Fail # Issue 12633
 constructor5_test: Fail # Issue 6422
 constructor6_test: Fail # Issue 6422
-closure_in_initializer_test: Fail # Issue 6422
+
+# Failures related to super call in ctor initializer list
+super_test: Fail, OK
+final_field_initialization_order_test: Fail, OK
+field_initialization_order_test: Fail, OK
+example_constructor_test: Fail, OK
+constructor3_test: Fail, OK
+constructor2_test: Fail, OK
 
 # Regular bugs which should be fixed.
 duplicate_export_negative_test: Fail # Issue 6134
@@ -31,24 +38,24 @@
 async_star_cancel_while_paused_test: RuntimeError
 async_star_await_pauses_test: Skip # Times out. Issue 23996
 
-[ $compiler == none && $runtime == vm ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
 unicode_bom_test: Fail # Issue 16067
 vm/debug_break_enabled_vm_test/01: Crash, OK # Expected to hit breakpoint.
 try_catch_optimized1_test: Skip # Srdjan investigating
 
-[ $compiler == none && $checked ]
+[ ($compiler == none || $compiler == precompiler) && $checked ]
 type_variable_bounds4_test/01: Fail # Issue 14006
 
-[ $compiler == none ]
+[ ($compiler == none || $compiler == precompiler) ]
 dynamic_prefix_core_test/01: RuntimeError # Issue 12478
 multiline_strings_test: Fail # Issue 23020
 
-[ $compiler == none && ($runtime == vm || $runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler) && (($runtime == vm || $runtime == dart_precompiled) || $runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 dynamic_prefix_core_test/none: Fail # Issue 12478
 export_ambiguous_main_negative_test: Fail # Issue 14763
 
-[ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $unchecked ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $unchecked ]
 assertion_test: Fail # Issue 14651.
 generic_test: Fail # Issue 14651.
 list_literal4_test: Fail # Issue 14651.
@@ -61,9 +68,10 @@
 type_checks_in_factory_method_test: Fail # Issue 14651.
 vm/type_vm_test: Fail # Issue 14651.
 
-[ $compiler == none && ( $runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler) && ( $runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
 issue13474_test: Pass, Fail # Issue 14651.
-vm/optimized_guarded_field_isolates_test: Fail # Issue 13921.
+config_import_test: Fail # Issue 14651.
+vm/optimized_guarded_field_isolates_test: RuntimeError, OK  # Uses Isolate.spawn.
 main_test/01: Fail # Issue 20028
 main_test/02: Fail # Issue 20028
 main_test/04: Fail # Issue 20028
@@ -73,31 +81,72 @@
 mirror_in_static_init_test: Fail # Issue 22071
 vm/debug_break_enabled_vm_test/*: Skip # Issue 14651.
 
-[ $compiler == none && $runtime == dartium && $system == linux && $arch != x64 ]
+[ ($compiler == none || $compiler == precompiler) && $runtime == dartium && $system == linux && $arch != x64 ]
 issue_22780_test/01 : Pass, Timeout # Issue 24473
 
-[ $compiler == none && $runtime == drt ]
+[ ($compiler == none || $compiler == precompiler) && $runtime == drt ]
 disassemble_test: Pass, Fail # Issue 18122
 
-[ $compiler == none && $runtime == vm && $arch == mips && $checked ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $checked ]
 generic_instanceof3_test: Pass, Crash # Issue 17440.
 
-[ $compiler == none && $runtime == vm && $arch == mips && $mode == debug ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $mode == debug ]
 stack_overflow_test: Skip # Crashes. Issue 17440.
 stack_overflow_stacktrace_test: Skip # Crashes. Issue 17440.
 large_class_declaration_test: SkipSlow # Times out. Issue 20352
 
-[ $compiler == none && ($runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) && $mode == debug ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) && $mode == debug ]
 large_class_declaration_test: SkipSlow # Times out. Issue 20352
 
-[ $compiler == none && $runtime == ContentShellOnAndroid ]
+[ ($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
 gc_test: SkipSlow # Times out flakily. Issue 20956
 
-[ $compiler == none && $runtime == vm && ( $arch == simarm || $arch == arm || $arch == simarmv5te || $arch == armv5te || $arch == simarm64 || $arch == arm64 || $arch == simmips || $arch == mips) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ( $arch == simarm || $arch == arm || $arch == simarmv5te || $arch == armv5te || $arch == simarm64 || $arch == arm64 || $arch == simmips || $arch == mips) ]
 vm/load_to_load_unaligned_forwarding_vm_test: Pass, Crash # Unaligned offset. Issue 22151
 
-[ $compiler == none && ( $runtime == dartium || $runtime == drt ) ]
-issue23244_test: Fail # Can't run spawnFunction on dartium.
+[ ($compiler == none || $compiler == precompiler) && $runtime == dartium ]
+issue23244_test: Fail # Issue 23244
 
-[ $compiler == none && ($runtime == vm || $runtime == drt || $runtime == dartium) && $arch == ia32 ]
+[ ($compiler == none || $compiler == precompiler) && (($runtime == vm || $runtime == dart_precompiled) || $runtime == drt || $runtime == dartium) && $arch == ia32 ]
 vm/regress_24517_test: Pass, Fail # Issue 24517.
+
+[ ($noopt || $compiler == precompiler) ]
+# Imports dart:mirrors
+const_evaluation_test: CompileTimeError
+deferred_constraints_constants_test: CompileTimeError
+enum_mirror_test: CompileTimeError
+field_increment_bailout_test: CompileTimeError
+instance_creation_in_function_annotation_test: CompileTimeError
+invocation_mirror2_test: CompileTimeError
+invocation_mirror_invoke_on2_test: CompileTimeError
+invocation_mirror_invoke_on_test: CompileTimeError
+issue21079_test: CompileTimeError
+many_overridden_no_such_method_test: CompileTimeError
+no_such_method_test: CompileTimeError
+null_test/none: CompileTimeError
+overridden_no_such_method_test: CompileTimeError
+regress_13462_0_test: CompileTimeError
+regress_13462_1_test: CompileTimeError
+regress_18535_test: CompileTimeError
+super_call4_test: CompileTimeError
+super_getter_setter_test: CompileTimeError
+vm/reflect_core_vm_test: CompileTimeError
+redirecting_factory_reflection_test: CompileTimeError
+deferred_constraints_constants_test: Skip # multitest gets confused
+vm/type_vm_test: RuntimeError # Expects line and column numbers
+
+# Deferred loading happens eagerly
+regress_23408_test: RuntimeError
+deferred_global_test: RuntimeError
+deferred_inheritance_constraints_test: Skip
+deferred_load_constants_test: Skip # multitest gets confused
+
+deopt_inlined_function_lazy_test: Pass, Crash # Incompatible flag: --deoptimize-alot
+tearoff_basic_test: RuntimeError, Crash # Conflicting flag.
+vm/type_cast_vm_test: RuntimeError # Line number mismatch.
+
+[ $runtime == dart_precompiled ]
+ct_const2_test: Pass, Crash # Incompatible flag --compile_all
+hello_dart_test: Pass, Crash # Incompatible flag --compile_all
+
+implicit_closure_test: Pass, Crash # --use_slow_path
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
deleted file mode 100644
index a5f91bf..0000000
--- a/tests/language/language_analyzer.status
+++ /dev/null
@@ -1,606 +0,0 @@
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-[ $compiler == dartanalyzer ]
-async_return_types_test/wrongTypeParameter: MissingStaticWarning # Issue 22410
-async_return_types_test/wrongReturnType: MissingStaticWarning # Issue 22410
-async_or_generator_return_type_stacktrace_test/01: MissingStaticWarning # Issue 22410
-async_or_generator_return_type_stacktrace_test/02: MissingStaticWarning # Issue 22410
-async_return_types_test/nestedFuture: MissingStaticWarning # Issue 22410
-await_backwards_compatibility_test/none: CompileTimeError # Issue 22052
-await_test: CompileTimeError # Issue 22052
-async_await_test/02: CompileTimeError # Issue 22052
-regress_17382_test: Skip # don't care about the static warning.
-regress_23408_test: Skip # don't care about the warning.
-regress_23038_test/01: Skip # Issue 23038
-getter_setter_in_lib_test: Fail # issue 23286
-
-issue13179_test: CompileTimeError # Issue 13179
-tearoff_basic_test: Skip # Tear-off not supported
-tearoff_constructor_basic_test: Skip # Tear-off not supported
-
-sync_generator2_test/01: MissingCompileTimeError # Issue 22252
-sync_generator2_test/02: MissingCompileTimeError # Issue 22252
-sync_generator2_test/03: MissingCompileTimeError # Issue 22252
-sync_generator2_test/04: MissingCompileTimeError # Issue 22252
-sync_generator2_test/05: MissingCompileTimeError # Issue 22252
-sync_generator2_test/06: MissingCompileTimeError # Issue 22252
-sync_generator2_test/07: MissingCompileTimeError # Issue 22252
-sync_generator2_test/10: MissingCompileTimeError # Issue 22252
-
-async_test/type-mismatch2: MissingStaticWarning # Issue 22053
-async_test/type-mismatch3: MissingStaticWarning # Issue 22053
-async_test/type-mismatch4: MissingStaticWarning # Issue 22053
-
-async_await_syntax_test/a05c: CompileTimeError
-async_await_syntax_test/a05e: CompileTimeError
-async_await_syntax_test/a05f: MissingCompileTimeError
-async_await_syntax_test/a10a: MissingStaticWarning
-async_await_syntax_test/b10a: MissingStaticWarning
-async_await_syntax_test/c10a: MissingStaticWarning
-async_await_syntax_test/d10a: MissingStaticWarning
-
-assign_to_type_test/01: MissingStaticWarning
-assign_to_type_test/02: MissingStaticWarning
-assign_to_type_test/03: MissingStaticWarning
-assign_to_type_test/04: MissingStaticWarning
-
-# Runtime negative test. No static errors or warnings.
-closure_call_wrong_argument_count_negative_test: skip
-
-compile_time_constant_c_test/01: Fail # Issue 21000
-compile_time_constant12_test: Fail # Issue 21000
-
-enum_syntax_test/02: Fail # 21649
-enum_syntax_test/03: Fail # 21649
-enum_syntax_test/04: Fail # 21649
-enum_syntax_test/05: Fail # 21649
-enum_syntax_test/06: Fail # 21649
-
-# Test issue 12694 (was analyzer issue), (1) when "abstract" is import prefix using it as type is warning; (2) currently analyzer resolves prefix as field (don't ask)
-built_in_identifier_prefix_test: CompileTimeError # Issue 12694
-
-# TBF: we should check conflicts not only for methods, but for accessors too
-override_field_test/03: fail
-method_override7_test/03: Fail # Issue 11496
-
-external_test/21: Fail
-external_test/24: Fail
-external_test/25: Fail
-constructor_duplicate_final_test/03: Fail
-identical_const_test: Fail # Issue 21177
-super_bound_closure_test/01: MissingStaticWarning # Issue 18914
-mixin_forwarding_constructor4_test/01: MissingCompileTimeError # Issue 19576
-mixin_forwarding_constructor4_test/02: MissingCompileTimeError # Issue 19576
-mixin_forwarding_constructor4_test/03: MissingCompileTimeError # Issue 19576
-mixin_super_constructor_named_test/01: MissingCompileTimeError # Issue 19576
-mixin_super_constructor_positionals_test/01: MissingCompileTimeError # Issue 19576
-reify_typevar_static_test/00: MissingCompileTimeError # Issue 21565
-
-multiline_newline_test/01: CompileTimeError # Issue 23888
-multiline_newline_test/02: CompileTimeError # Issue 23888
-multiline_newline_test/03: CompileTimeError # Issue 23888
-multiline_newline_test/04: MissingCompileTimeError # Issue 23888
-multiline_newline_test/05: MissingCompileTimeError # Issue 23888
-multiline_newline_test/06: MissingCompileTimeError # Issue 23888
-
-# Please add new failing tests before this line.
-# Section below is for invalid tests.
-#
-#
-
-ref_before_declaration_test/none: fail # test issue 14879, "P" is not defined
-bad_initializer2_negative_test: fail # Issue 14880, Analyzer reports compile-time error, but test runner is not satisfied
-
-# test issue 11124, It is warning, not error to don't initialize final field
-field3a_negative_test: Fail # Issue 11124
-final_syntax_test/01: Fail # Issue 11124
-final_syntax_test/04: Fail # Issue 11124
-final_syntax_test/02: Fail # Issue 11124
-final_syntax_test/03: Fail # Issue 11124
-
-# Test issue 11545, using not existing constructor name in annotation
-metadata_test: fail
-
-# test issue 11575, classes with abstract members are not marked as abstract
-get_set_syntax_test/none: fail # Issue 11575
-implicit_this_test/none: fail # Issue 11575
-interface_test/none: fail # Issue 11575
-syntax_test/none: fail # Issue 11575
-
-# test issue 11576
-bad_constructor_test/none: fail # Issue 11576
-
-# test issue 11577, has return type for []=
-cascade_test/none: fail # Issue 11577
-
-# test issue 11578, redirecting factory with not subtype
-factory5_test/none: fail # Issue 11578
-type_variable_bounds_test/none: fail # Issue 11578
-type_variable_scope_test/none: fail # Issue 11578
-factory_implementation_test/none: fail # Issue 11578
-malbounded_redirecting_factory_test/none: fail # Issue 11578
-malbounded_redirecting_factory2_test/none: fail # Issue 11578
-
-# test issue 11579, assignment, no setter
-getter_no_setter_test/none: fail
-
-# test issue 11584, positional arguments cannot be used for named parameters
-compile_time_constant_e_test: fail # Test Issue 11584
-
-# test issue 11585, static warning, not negative test
-constructor3_negative_test: fail
-constructor_call_wrong_argument_count_negative_test: fail
-instance_call_wrong_argument_count_negative_test: fail
-
-# test issue 11590, runtime only negative test
-field_method4_negative_test: fail
-
-# test issue 11594, Reference to a not resolve identifier is static warning
-import_combinators_negative_test: fail
-interface_static_non_final_fields_negative_test: fail
-
-# test issue 11962, it is warning, not error to reference undeclared identifier
-prefix1_negative_test: fail
-prefix2_negative_test: fail
-prefix4_negative_test: fail
-prefix5_negative_test: fail
-prefix12_negative_test: fail
-
-# test issue 11964, Any use of a malformed type gives rise to a static warning.
-prefix8_negative_test: fail
-prefix11_negative_test: fail
-
-# test issue 12156, fails only at runtime
-static_call_wrong_argument_count_negative_test: fail
-
-# test issue 12160, not annotated warnings for type variables from static member
-type_parameter_test/none: fail
-# test issue 12161, type variable in static, malformed type, static warning
-type_variable_static_context_negative_test: fail
-
-# test issue 12163, unresolved identifier is static warning in static context
-unresolved_in_factory_negative_test: fail # Issue 12163
-unresolved_top_level_var_negative_test: fail # Issue 12163
-
-# test issue 12191, ambiguous import is always warning now
-prefix3_negative_test: fail # Issue 12191
-
-# test issue 12289, assignment in assert statement
-type_error_test: fail # Issue 12289
-
-# test issue 12381, It is compile-time error to invoke not existing function
-issue11724_test: fail # Issue 12381
-
-# test issue 12541; there shouldn't be a static warning
-static_field_test/01: fail # Issue 12541
-static_field_test/02: fail # Issue 12541
-static_field_test/03: fail # Issue 12541
-static_field_test/04: fail # Issue 12541
-
-# test issue 13916, Looks as no warning should be in this redirecting factory
-redirecting_factory_infinite_steps_test/01: fail
-
-# test issue 14471, has (legitimate) static warning; but not annotated
-redirecting_factory_default_values_test/none: StaticWarning # Test issue 14471; has (legitimate) static warning; but not annotated
-
-# test issue 13956, It is a static type warning if any of the type arguments to k' are not subtypes of the bounds of the corresponding formal type parameters of type.
-default_factory2_test/none: fail
-
-# test issue 14021, it is warning, not an error to reference private (undefined) identifier
-private_member1_negative_test: fail
-private_member2_negative_test: fail
-private_member3_negative_test: fail
-
-# test issue 14079
-malformed_test/none: fail # test issue 14079, legit warnings for malformed type
-malformed_test/05: fail # test issue 14079, it is not error, but warning to instantiate malformed type
-malformed_test/06: fail # test issue 14079, it is not error, but warning to use malformed type in "try-on" clause
-regress_22438_test: fail # test issue 14079, it is not error, but warning to use malformed type in "try-on" clause
-
-# test issue 14228
-black_listed_test/none: fail # test issue 14228, warnings are required but not expected
-
-# test issue 14410, "typedef C = " is now really illegal syntax
-mixin_illegal_syntax_test/none: fail
-
-# test issue 14736, It is a static warning if a class C declares an instance method named n and has a setter named n=.
-setter4_test: StaticWarning
-
-# test issue 15467
-proxy_test/05: StaticWarning # Issue 15467
-proxy_test/06: StaticWarning # Issue 15467
-proxy3_test/03: StaticWarning # Issue 15467
-proxy3_test/04: StaticWarning # Issue 15467
-
-# test issue 18230
-factory_redirection_test/02: StaticWarning # Issue 18230
-factory_redirection_test/08: StaticWarning # Issue 18230
-factory_redirection_test/09: StaticWarning # Issue 18230
-factory_redirection_test/10: StaticWarning # Issue 18230
-factory_redirection_test/11: StaticWarning # Issue 18230
-factory_redirection_test/12: StaticWarning # Issue 18230
-factory_redirection_test/13: StaticWarning # Issue 18230
-factory_redirection_test/14: StaticWarning # Issue 18230
-factory_redirection_test/none: StaticWarning # Issue 18230
-
-# analyzer does not handle @proxy and noSuchMethod correctly
-override_inheritance_no_such_method_test/03: StaticWarning # Issue 16132
-override_inheritance_no_such_method_test/04: StaticWarning # Issue 16132
-override_inheritance_no_such_method_test/05: StaticWarning # Issue 16132
-
-# test issue 20074
-regress_20074_test: CompileTimeError # Issue 20074
-
-# The following tests are currently assumed to be failing because the test is wrong.
-#
-application_negative_test: CompileTimeError # Test Issue 14528
-bad_constructor_test/05: CompileTimeError # Test Issue 5337
-bad_initializer1_negative_test: CompileTimeError # Test Issue 14529
-bad_named_constructor_negative_test: CompileTimeError # Test Issue 18693
-body_less_constructor_wrong_arg_negative_test: CompileTimeError # Test Issue 18695
-empty_block_case_test: StaticWarning # Test Issue 18701
-error_stacktrace_test: StaticWarning # Test Issue 18702
-
-const_counter_negative_test: CompileTimeError
-const_optional_args_negative_test: CompileTimeError
-constructor_redirect1_negative_test: CompileTimeError
-constructor_redirect2_negative_test: CompileTimeError
-constructor_setter_negative_test: CompileTimeError
-duplicate_export_negative_test: CompileTimeError
-duplicate_interface_negative_test: CompileTimeError
-export_ambiguous_main_negative_test: CompileTimeError
-extend_type_parameter2_negative_test: CompileTimeError
-extend_type_parameter_negative_test: CompileTimeError
-factory2_negative_test: CompileTimeError
-factory2_test: StaticWarning # Test Issue 18727
-factory3_negative_test: CompileTimeError
-factory3_test: StaticWarning # Test Issue 18727
-factory4_test: StaticWarning # Test Issue 18727
-factory_implementation_test/00: StaticWarning
-factory_negative_test: CompileTimeError
-factory_redirection_test/01: StaticWarning # Test Issue 11578
-factory_redirection_test/03: StaticWarning # Test Issue 11578
-factory_redirection_test/05: StaticWarning # Test Issue 11578
-factory_redirection_test/06: StaticWarning # Test Issue 11578
-factory_return_type_checked_test: StaticWarning # Test Issue 18728
-f_bounded_quantification4_test: StaticWarning
-f_bounded_quantification5_test: StaticWarning
-field1_negative_test: CompileTimeError
-field2_negative_test: CompileTimeError
-field3_negative_test: CompileTimeError
-field4_negative_test: CompileTimeError
-field5_negative_test: CompileTimeError
-field6a_negative_test: CompileTimeError
-field6_negative_test: CompileTimeError
-first_class_types_literals_test/08: MissingStaticWarning # Issue 18731
-first_class_types_literals_test/09: MissingStaticWarning # Issue 18731
-first_class_types_literals_test/10: MissingStaticWarning # Issue 18731
-first_class_types_literals_test/11: MissingStaticWarning # Issue 18731
-first_class_types_literals_test/12: MissingStaticWarning # Issue 18731
-function_malformed_result_type_test: StaticWarning
-function_subtype_bound_closure7_test: StaticWarning
-function_subtype_checked0_test: StaticWarning
-function_subtype_closure0_test: StaticWarning
-function_subtype_closure1_test: StaticWarning
-function_subtype_factory1_test: StaticWarning
-function_subtype_inline1_test: StaticWarning
-function_type2_test: StaticWarning
-function_type_parameter2_negative_test: CompileTimeError
-function_type_parameter_negative_test: CompileTimeError
-generic_list_checked_test: StaticWarning
-generics_test: StaticWarning
-generic_test: StaticWarning
-getter_declaration_negative_test: CompileTimeError
-getter_no_setter2_test/01: StaticWarning
-getter_no_setter_test/01: StaticWarning
-illegal_invocation_test/01: StaticWarning
-implicit_this_test/02: StaticWarning
-implied_interface_test: StaticWarning
-import_combinators_test: StaticWarning
-import_core_prefix_test: StaticWarning
-inferrer_this_access_test: StaticWarning
-inlined_throw_test: StaticWarning
-instance_method2_negative_test: CompileTimeError
-instance_method_negative_test: CompileTimeError
-instanceof3_test: StaticWarning
-instantiate_type_variable_test/01: StaticWarning
-inst_field_initializer1_negative_test: CompileTimeError
-interceptor6_test: StaticWarning
-interface2_negative_test: CompileTimeError
-interface_inherit_field_test: StaticWarning
-interface_injection1_negative_test: CompileTimeError
-interface_injection2_negative_test: CompileTimeError
-interface_static_method_negative_test: CompileTimeError
-invocation_mirror_test: StaticWarning
-is_not_class1_negative_test: CompileTimeError
-is_not_class2_test: StaticWarning
-is_not_class4_negative_test: CompileTimeError
-isnot_malformed_type_test: StaticWarning
-issue1363_test: StaticWarning
-issue1578_negative_test: CompileTimeError
-label2_negative_test: CompileTimeError
-label3_negative_test: CompileTimeError
-label5_negative_test: CompileTimeError
-label6_negative_test: CompileTimeError
-label8_negative_test: CompileTimeError
-label_test: StaticWarning
-library_ambiguous_test/00: StaticWarning
-library_ambiguous_test/01: StaticWarning
-library_ambiguous_test/02: StaticWarning
-library_ambiguous_test/03: StaticWarning
-library_negative_test: CompileTimeError
-list_literal2_negative_test: CompileTimeError
-list_literal4_test: StaticWarning
-list_literal_negative_test: CompileTimeError
-list_test: StaticWarning
-malbounded_type_cast_test: StaticWarning
-malbounded_type_cast2_test: StaticWarning
-malbounded_type_literal_test: StaticWarning
-malbounded_type_test2_test: StaticWarning
-malformed_type_test: StaticWarning
-map_literal2_negative_test: CompileTimeError
-map_literal3_test: StaticWarning
-map_literal4_test: StaticWarning
-map_literal6_test: StaticWarning
-map_literal8_test: StaticWarning
-map_literal_negative_test: CompileTimeError
-method_override4_test: StaticWarning
-method_override5_test: StaticWarning
-method_override6_test: StaticWarning
-method_override_test: StaticWarning
-mixin_illegal_static_access_test: StaticWarning
-mixin_illegal_syntax_test/13: CompileTimeError
-mixin_type_parameters_mixin_extends_test: StaticWarning
-mixin_type_parameters_mixin_test: StaticWarning
-mixin_type_parameters_super_extends_test: StaticWarning
-mixin_type_parameters_super_test: StaticWarning
-mixin_with_two_implicit_constructors_test: StaticWarning
-mixin_invalid_bound_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated
-mixin_invalid_bound2_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated
-mixin_super_bound_test: StaticWarning # legitimate StaticWarning, cannot be annotated
-mixin_super_bound2_test: CompileTimeError # Issue 23772
-mixin_super_test: CompileTimeError # Issue 23772
-mixin_super_2_test: CompileTimeError # Issue 23772
-mixin_super_use_test: CompileTimeError # Issue 23772
-mixin_superclass_test: CompileTimeError # Issue 23772
-named_constructor_test/01: StaticWarning
-named_constructor_test/03: StaticWarning
-named_parameters2_test: StaticWarning
-named_parameters3_test: StaticWarning
-named_parameters4_test: StaticWarning
-named_parameters_test/01: StaticWarning
-named_parameters_test/02: StaticWarning
-named_parameters_test/03: StaticWarning
-named_parameters_test/04: StaticWarning
-named_parameters_test/05: StaticWarning
-named_parameters_test/06: StaticWarning
-named_parameters_test/07: StaticWarning
-named_parameters_test/08: StaticWarning
-named_parameters_test/09: StaticWarning
-named_parameters_test/10: StaticWarning
-named_parameters_type_test/01: StaticWarning
-new_expression1_negative_test: CompileTimeError
-new_expression2_negative_test: CompileTimeError
-new_expression3_negative_test: CompileTimeError
-non_const_super_negative_test: CompileTimeError
-non_parameterized_factory2_test: StaticWarning
-non_parameterized_factory_test: StaticWarning
-no_such_constructor2_test: StaticWarning
-no_such_method2_test: StaticWarning
-no_such_method_dispatcher_test: StaticWarning
-not_enough_positional_arguments_test/00: StaticWarning
-not_enough_positional_arguments_test/01: CompileTimeError
-not_enough_positional_arguments_test/02: StaticWarning
-not_enough_positional_arguments_test/03: StaticWarning
-not_enough_positional_arguments_test/05: StaticWarning
-not_enough_positional_arguments_test/06: StaticWarning
-not_enough_positional_arguments_test/07: StaticWarning
-number_identifier_test/08: StaticWarning
-number_identifier_test/09: StaticWarning
-on_catch_malformed_type_test: StaticWarning
-operator1_negative_test: CompileTimeError
-operator2_negative_test: CompileTimeError
-operator_equals_test: StaticWarning
-optional_named_parameters_test/01: StaticWarning
-optional_named_parameters_test/02: StaticWarning
-optional_named_parameters_test/03: StaticWarning
-optional_named_parameters_test/04: StaticWarning
-optional_named_parameters_test/05: StaticWarning
-optional_named_parameters_test/06: StaticWarning
-optional_named_parameters_test/07: StaticWarning
-optional_named_parameters_test/08: StaticWarning
-optional_named_parameters_test/09: StaticWarning
-override_field_method1_negative_test: CompileTimeError
-override_field_method2_negative_test: CompileTimeError
-override_field_method4_negative_test: CompileTimeError
-override_field_method5_negative_test: CompileTimeError
-parameter_initializer1_negative_test: CompileTimeError
-parameter_initializer2_negative_test: CompileTimeError
-parameter_initializer3_negative_test: CompileTimeError
-parameter_initializer4_negative_test: CompileTimeError
-parameter_initializer5_negative_test: CompileTimeError
-parameter_initializer6_negative_test: CompileTimeError
-parser_quirks_test: StaticWarning
-part2_test: StaticWarning
-positional_parameters_type_test/01: StaticWarning
-prefix13_negative_test: CompileTimeError
-prefix14_test: StaticWarning
-prefix15_negative_test: CompileTimeError
-prefix15_test: StaticWarning
-prefix16_test: StaticWarning
-prefix17_test: StaticWarning
-prefix18_negative_test: CompileTimeError
-prefix22_test: StaticWarning
-prefix23_test: StaticWarning
-prefix7_negative_test: CompileTimeError
-property_field_override_test: StaticWarning
-redirecting_factory_incompatible_signature_test: StaticWarning
-regress_13494_test: StaticWarning
-return_type_test: StaticWarning
-script1_negative_test: CompileTimeError
-script2_negative_test: CompileTimeError
-setter_declaration2_negative_test: CompileTimeError
-setter_declaration_negative_test: CompileTimeError
-setter_no_getter_call_test/01: StaticWarning
-source_self_negative_test: CompileTimeError
-static_initializer_type_error_test: StaticWarning
-string_escape4_negative_test: CompileTimeError
-string_interpolate1_negative_test: CompileTimeError
-string_interpolate2_negative_test: CompileTimeError
-string_interpolate_test: StaticWarning
-string_interpolation1_negative_test: CompileTimeError
-string_interpolation2_negative_test: CompileTimeError
-string_interpolation3_negative_test: CompileTimeError
-string_interpolation4_negative_test: CompileTimeError
-string_interpolation5_negative_test: CompileTimeError
-string_interpolation6_negative_test: CompileTimeError
-string_test: StaticWarning
-string_unicode1_negative_test: CompileTimeError
-string_unicode2_negative_test: CompileTimeError
-string_unicode3_negative_test: CompileTimeError
-string_unicode4_negative_test: CompileTimeError
-super_assign_test: StaticWarning
-super_call4_test: StaticWarning
-super_getter_setter_test: StaticWarning
-super_operator_index5_test: StaticWarning
-super_operator_index6_test: StaticWarning
-super_operator_index7_test: StaticWarning
-super_operator_index8_test: StaticWarning
-super_operator_test: StaticWarning
-super_setter_test: StaticWarning
-switch1_negative_test: CompileTimeError
-switch3_negative_test: CompileTimeError
-switch4_negative_test: CompileTimeError
-switch5_negative_test: CompileTimeError
-switch6_test: StaticWarning
-switch7_negative_test: CompileTimeError
-switch_fallthru_test: StaticWarning
-test_negative_test: CompileTimeError
-top_level_non_prefixed_library_test: StaticWarning
-try_catch4_test: StaticWarning
-try_catch5_test: StaticWarning
-type_argument_in_super_type_test: StaticWarning
-typed_selector2_test: StaticWarning
-type_variable_identifier_expression_test: StaticWarning
-type_variable_scope2_test: StaticWarning
-type_variable_conflict2_test/02: MissingCompileTimeError
-type_variable_conflict2_test/06: MissingCompileTimeError
-type_variable_conflict2_test/08: MissingCompileTimeError
-type_variable_conflict2_test/10: MissingCompileTimeError
-unary_plus_negative_test: CompileTimeError
-unbound_getter_test: StaticWarning
-unhandled_exception_negative_test: CompileTimeError
-unresolved_top_level_method_negative_test: StaticWarning
-vm/debug_break_enabled_vm_test: CompileTimeError, OK
-vm/type_cast_vm_test: StaticWarning
-vm/type_vm_test: StaticWarning
-void_type_test: StaticWarning
-
-issue13474_test: StaticWarning, OK # Test Issue
-
-
-# The following lines have been left in to quickly switch back to having deferred loading
-# off by default again.
-# Deferred loading support, tests marked as failing until support is enabled by default.
-#deferred_closurize_load_library_test: Pass, Fail
-#deferred_not_loaded_check_test/*: Pass, Fail
-#deferred_shadow_load_library_test: Pass, Fail
-#deferred_constraints_constants_test/*: Pass, Fail
-#deferred_load_library_wrong_args_test/*: Pass, Fail
-#deferred_constraints_type_annotation_test/*: Pass, Fail
-#deferred_load_inval_code_test: Pass, Fail
-#deferred_not_loaded_check_test: Pass, Fail
-
-# Issues to be fixed now that type parameters have been fixed
-# (issues 14221, 15553)
-factory1_test/00: StaticWarning # Test Issue 18726
-factory1_test/01: StaticWarning # Test Issue 18726
-factory1_test/none: StaticWarning # Test Issue 18726
-generic_closure_test: StaticWarning
-local_function2_test: StaticWarning
-redirecting_factory_long_test: StaticWarning
-
-# This test uses "const Symbol('_setAt')"
-vm/reflect_core_vm_test: CompileTimeError
-
-# This test is expected to have warnings because of noSuchMethod overriding.
-regress_12561_test: StaticWarning
-
-main_not_a_function_test/01: Fail # Issue 20030
-main_test/03: Fail # Issue 20030
-no_main_test/01: Fail # Issue 20030
-
-compile_time_constant10_test/none: CompileTimeError # Issue 21177
-
-const_dynamic_type_literal_test: CompileTimeError # Issue 22989
-
-regress_21912_test/02: StaticWarning # Issue 21912
-regress_22976_test/02: StaticWarning # Issue 22976
-
-variable_declaration_metadata_test/02: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/03: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/04: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/06: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/08: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/09: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/10: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/12: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/13: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/14: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/16: MissingCompileTimeError # Issue 23204
-
-# Null-aware operators aren't implemented in the Java-based analyzer.
-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
-
-# This test is expected to generate a warning, since it's
-# intentionally referring to a variable that's not in scope.
-transitive_private_library_access_test: StaticWarning
-
-# Issue 16391. These tests are supposed to produce a compile time
-# error in checked mode, but they don't:
-[ $compiler == dartanalyzer && $checked ]
-assign_static_type_test/02: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked2_test/02: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked2_test/03: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked2_test/04: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked2_test/06: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked3_test/02: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked3_test/03: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked3_test/04: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked3_test/06: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked4_test/01: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked4_test/02: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked4_test/03: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked_test/02: MissingCompileTimeError # Issue 16391
-const_constructor2_test/13: MissingCompileTimeError # Issue 16391
-const_constructor2_test/14: MissingCompileTimeError # Issue 16391
-const_constructor2_test/15: MissingCompileTimeError # Issue 16391
-const_constructor2_test/16: MissingCompileTimeError # Issue 16391
-const_constructor2_test/17: MissingCompileTimeError # Issue 16391
-const_constructor2_test/20: MissingCompileTimeError # Issue 16391
-const_constructor2_test/22: MissingCompileTimeError # Issue 16391
-const_constructor2_test/24: MissingCompileTimeError # Issue 16391
-const_constructor3_test/02: MissingCompileTimeError # Issue 16391
-const_constructor3_test/04: MissingCompileTimeError # Issue 16391
-const_init2_test/02: MissingCompileTimeError # Issue 16391
-malformed2_test/01: MissingCompileTimeError # Issue 16391
-type_check_const_function_typedef2_test/00: MissingCompileTimeError # Issue 16391
-type_parameter_test/05: MissingCompileTimeError # Issue 16391
-
-compile_time_constant_checked5_test/03: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/04: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/08: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/09: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/13: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/14: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/18: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/19: MissingCompileTimeError # Issue 23292
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index a51dda3..5ea3d0a 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -15,6 +15,7 @@
 
 regress_17382_test: Skip # don't care about the static warning.
 regress_23408_test: Skip # don't care about the static warning.
+regress_25246_test: Skip
 getter_setter_in_lib_test: Fail # issue 23286
 
 # Test issue 12694 (was analyzer issue), (1) when "abstract" is import prefix using it as type is warning; (2) currently analyzer resolves prefix as field (don't ask)
@@ -22,7 +23,7 @@
 
 # TBF: we should check conflicts not only for methods, but for accessors too
 override_field_test/03: fail
-method_override7_test/03: Fail # Issue 11496
+method_override7_test/03: Fail # Issue 11497
 
 external_test/21: Fail
 external_test/24: Fail
@@ -37,6 +38,11 @@
 multiline_newline_test/05: MissingCompileTimeError # Issue 23888
 multiline_newline_test/06: MissingCompileTimeError # Issue 23888
 
+const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
+
+# Unsupported configuration specific imports.
+config_import_test: CompileTimeError # Issue 24579
+
 # Please add new failing tests before this line.
 # Section below is for invalid tests.
 #
@@ -187,6 +193,7 @@
 empty_block_case_test: StaticWarning # Test Issue 18701
 error_stacktrace_test: StaticWarning # Test Issue 18702
 
+abstract_beats_arguments_test: StaticWarning
 const_counter_negative_test: CompileTimeError
 const_optional_args_negative_test: CompileTimeError
 constructor_redirect1_negative_test: CompileTimeError
@@ -475,3 +482,5 @@
 # This test is expected to generate a warning, since it's
 # intentionally referring to a variable that's not in scope.
 transitive_private_library_access_test: StaticWarning
+
+const_qq_test: Fail
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index a0c0638..2dbad85 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -3,9 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-sync_generator2_test/07: MissingCompileTimeError # Issue 22324
-sync_generator2_test/08: MissingCompileTimeError # Issue 22324
-sync_generator2_test/10: MissingCompileTimeError # Issue 22324
 getter_setter_in_lib_test: Fail # Issue 23288
 
 async_star_cancel_while_paused_test: RuntimeError # Issue 22853
@@ -22,6 +19,9 @@
 await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
 async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
 
+[ $compiler == dart2js && $browser ]
+config_import_test: Fail # Test flag is not passed to the compiler.
+
 [ $compiler == dart2js ]
 invocation_mirror_empty_arguments_test: Fail # Issue 24331
 nan_identical_test: Fail # Issue 11551
@@ -68,11 +68,6 @@
 if_null_assignment_behavior_test/13: Crash # Issue 23491
 if_null_assignment_behavior_test/14: Crash # Issue 23491
 
-if_null_assignment_behavior_test/29: Crash # Issue 23611
-prefix_assignment_test/01: Crash # Issue 23611
-prefix_assignment_test/02: Crash # Issue 23611
-prefix_identifier_reference_test/05: Crash # Issue 23611
-
 const_error_multiply_initialized_test/02: CompileTimeError # Issue 23618
 const_error_multiply_initialized_test/04: CompileTimeError # Issue 23618
 
@@ -136,10 +131,6 @@
 symbol_conflict_test: RuntimeError # Issue 23857
 
 [ $compiler == dart2js ]
-async_await_syntax_test/a05h: Fail # 23716
-async_await_syntax_test/c11a: Fail # 23716
-async_await_syntax_test/c11b: Fail # 23716
-
 malformed_test/none: Fail # Expect failure in lib/_internal/js_runtime/lib/preambles/d8.js
 
 type_variable_conflict2_test/01: RuntimeError # Issue 19725
@@ -153,9 +144,7 @@
 mint_arithmetic_test: RuntimeError # Issue 1533
 left_shift_test: RuntimeError # Issue 1533
 regress_24283_test: RuntimeError # Issue 1533
-bad_override_test/01: CompileTimeError # Issue 11496
-bad_override_test/02: CompileTimeError # Issue 11496
-constructor_named_arguments_test/01: CompileTimeError # Issue 5519
+constructor_named_arguments_test/01: CompileTimeError # Issue 25225
 not_enough_positional_arguments_test/01: CompileTimeError # Issue 12838
 not_enough_positional_arguments_test/02: CompileTimeError # Issue 12838
 not_enough_positional_arguments_test/05: CompileTimeError # Issue 12838
@@ -175,10 +164,7 @@
 const_dynamic_type_literal_test/02: CompileTimeError # Issue 23009
 const_dynamic_type_literal_test/03: CompileTimeError # Issue 23009
 
-generic_field_mixin4_test: Crash # Issue 18651
-
 # Compilation errors.
-method_override5_test: RuntimeError # Issue 12809
 external_test/10: CompileTimeError # Issue 12887
 external_test/13: CompileTimeError # Issue 12887
 external_test/20: CompileTimeError # Issue 12887
@@ -227,14 +213,15 @@
 regress_22443_test: Pass,RuntimeError # Issue 17458
 
 [ $compiler == dart2js && $cps_ir == false ]
+generic_field_mixin4_test: Crash # Issue 18651
 generic_field_mixin5_test: Crash # Issue 18651
 many_method_calls_test: Crash # Stack overflow in HGraphVisitor.visitPostDominatorTree.visitBasicBlockAndSuccessors
+method_override5_test: RuntimeError # Issue 12809
 
-[ $compiler == dart2js && ($runtime == d8 || $runtime == jsshell) ]
+[ $compiler == dart2js && $runtime != drt && $runtime != dartium ]
 issue23244_test: RuntimeError # 23244
 
 [ $compiler == dart2js && $cps_ir ]
-assert_assignable_type_test: Crash # Internal Error: Pending statics.
 async_await_syntax_test/a03a: Crash # (a03a()async*{}): cannot handle sync*/async* functions
 async_await_syntax_test/a03b: Crash # (a03b()async*{}): cannot handle sync*/async* functions
 async_await_syntax_test/a06a: Crash # (await for(var o in st){}): await for
@@ -272,7 +259,6 @@
 async_star_stream_take_test: Crash # (Stream makeStream(i...  cannot handle sync*/async* functions
 async_star_take_reyield_test: Crash # (fivePartialSums(Str...  cannot handle sync*/async* functions
 async_star_test: Crash # (f()async*{}): cannot handle sync*/async* functions
-async_this_bound_test: RuntimeError # Cannot read property 'set$f' of undefined
 asyncstar_concat_test: Crash # (concat(a,b)async*{yield* a;yield* b;}): cannot handle sync*/async* functions
 asyncstar_throw_in_catch_test: Crash # (foo4(Tracer tracer)...  cannot handle sync*/async* functions
 asyncstar_yield_test: Crash # (Stream<int> foo4()a...  cannot handle sync*/async* functions
@@ -280,91 +266,29 @@
 await_for_cancel_test: Crash # (await for(var x in controller.stream){for(int j=0;j<10;j++ ){if(j==5)continue outer;}}): await for
 await_for_test: Crash # (await for(var x in infiniteStream()){i++ ;if(i>10)break;t4.record(x);}): await for
 await_for_use_local_test: Crash # (await for(var v in s){accum+= v;}): await for
-await_future_test: RuntimeError # Cannot read property '_await_future_test$_box_0' of undefined
-await_postfix_expr_test: RuntimeError # Please triage this failure.
-await_regression_test: RuntimeError # "Obelix".then$1 is not a function
-await_test: RuntimeError # Cannot read property '$add' of undefined
-cha_deopt1_test: Crash # (d.make_u()): deferred access is not implemented
-cha_deopt2_test: Crash # (d.make_u()): deferred access is not implemented
-cha_deopt3_test: Crash # (d.make_u()): deferred access is not implemented
+call_closurization_test: RuntimeError # Bad type inference for ".call" tear-off.
 closure_in_constructor_test: RuntimeError # Please triage this failure.
 closures_initializer_test: RuntimeError # Please triage this failure.
 constructor12_test: RuntimeError # Please triage this failure.
-crash_6725_test/01: Crash # unsupported operation on erroneous element
-cyclic_default_values_test: RuntimeError # Z.cyclic_default_values_test__foo$closure is not a function
-deferred_call_empty_before_load_test: Crash # (lib1.thefun()): deferred access is not implemented
-deferred_closurize_load_library_test: RuntimeError # D.loadLibrary is not a function
-deferred_constant_list_test: RuntimeError # K.loadLibrary is not a function
-deferred_constraints_constants_test/none: RuntimeError # S.loadLibrary is not a function
-deferred_constraints_constants_test/reference_after_load: RuntimeError # G.loadLibrary is not a function
-deferred_constraints_type_annotation_test/as_operation: RuntimeError # Z.loadLibrary is not a function
-deferred_constraints_type_annotation_test/catch_check: RuntimeError # D.loadLibrary is not a function
-deferred_constraints_type_annotation_test/is_check: RuntimeError # L.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new: RuntimeError # R.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new_before_load: RuntimeError # K.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new_generic1: RuntimeError # R.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new_generic2: RuntimeError # X.loadLibrary is not a function
-deferred_constraints_type_annotation_test/new_generic3: RuntimeError # K.loadLibrary is not a function
-deferred_constraints_type_annotation_test/none: RuntimeError # D.loadLibrary is not a function
-deferred_constraints_type_annotation_test/static_method: RuntimeError # F.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation1: RuntimeError # K.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_generic1: RuntimeError # T.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_generic2: RuntimeError # Q.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_generic3: RuntimeError # Z.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_generic4: RuntimeError # Q.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_non_deferred: RuntimeError # R.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_null: RuntimeError # Z.loadLibrary is not a function
-deferred_constraints_type_annotation_test/type_annotation_top_level: RuntimeError # U.loadLibrary is not a function
-deferred_function_type_test: RuntimeError # N.loadLibrary is not a function
-deferred_global_test: RuntimeError # Y.loadLibrary is not a function
-deferred_inlined_test: Crash # (lib.foo()): deferred access is not implemented
-deferred_load_constants_test/none: Crash # (foo.toplevel): deferred access is not implemented
-deferred_load_inval_code_test: Crash # (d.foo()): deferred access is not implemented
-deferred_load_library_wrong_args_test/none: RuntimeError # Y.loadLibrary is not a function
-deferred_mixin_test: RuntimeError # X.loadLibrary is not a function
-deferred_no_such_method_test: RuntimeError # D.loadLibrary is not a function
-deferred_not_loaded_check_test: Crash # (lib.closure(sideEffect())): deferred access is not implemented
-deferred_only_constant_test: RuntimeError # O.loadLibrary is not a function
-deferred_optimized_test: Crash # (lib.foo()): deferred access is not implemented
-deferred_redirecting_factory_test: Crash # (lib1.loadLib2()): deferred access is not implemented
-deferred_regression_22995_test: RuntimeError # U.loadLibrary is not a function
-deferred_shadow_load_library_test: RuntimeError # Y.loadLibrary is not a function
-deferred_shared_and_unshared_classes_test: RuntimeError # U.loadLibrary is not a function
-deferred_static_seperate_test: RuntimeError # L.loadLibrary is not a function
-deferred_super_dependency_test/01: RuntimeError # $async$temp1.loadLibrary is not a function
-deferred_type_dependency_test/as: Crash # (lib1.fooAs("string")): deferred access is not implemented
-deferred_type_dependency_test/is: Crash # (lib1.fooIs("string")): deferred access is not implemented
-deferred_type_dependency_test/none: Crash # (lib2.getInstance()): deferred access is not implemented
-deferred_type_dependency_test/type_annotation: Crash # (lib1.fooAnnotation("string")): deferred access is not implemented
+deferred_super_dependency_test/01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 field3a_negative_test: Fail # Bogus result from type inference in case of invalid program.
 first_class_types_test: RuntimeError # Please triage this failure.
-for2_test: Crash # The null object does not have a getter 'field'.
-for_variable_capture_test: Crash # (i=0): For-loop variable captured in loop header
 generic2_test: RuntimeError # Please triage this failure.
-generic_field_mixin3_test: RuntimeError # Please triage this failure.
 generic_instanceof_test: RuntimeError # Please triage this failure.
 generic_native_test: RuntimeError # Please triage this failure.
+gc_test: Crash # Internal Error: Pending statics (see above).
 infinite_switch_label_test: Crash # (switch (target){l0:...  continue to a labeled switch case
 instanceof2_test: RuntimeError # Please triage this failure.
 instanceof4_test/01: RuntimeError # Please triage this failure.
-invocation_mirror_invoke_on_test: RuntimeError # Please triage this failure.
 invocation_mirror_test: Crash # (super[37]=42): visitUnresolvedSuperIndexSet
-issue_1751477_test: RuntimeError # O.loadLibrary is not a function
 list_is_test: RuntimeError # Please triage this failure.
 list_test: RuntimeError # Please triage this failure.
 many_generic_instanceof_test: RuntimeError # Please triage this failure.
-many_overridden_no_such_method_test: RuntimeError # Please triage this failure.
 nested_switch_label_test: Crash # (switch (target){out...  continue to a labeled switch case
-no_such_method_test: RuntimeError # Please triage this failure.
-overridden_no_such_method_test: RuntimeError # Please triage this failure.
-regress_22443_test: RuntimeError # M.loadLibrary is not a function
-regress_23408_test: RuntimeError # G.loadLibrary is not a function
 regress_23500_test/01: Crash # (await for(var c in new Stream.fromIterable([] )){}): await for
-super_bound_closure_test/01: RuntimeError # Cannot read property 'call' of undefined
-super_bound_closure_test/none: RuntimeError # Cannot read property 'call' of undefined
+stack_trace_test: Fail # Stack trace not preserved when inlining?
 super_call4_test: RuntimeError # Please triage this failure.
 super_getter_setter_test: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
-super_implicit_closure_test: RuntimeError # Cannot read property 'call' of undefined
 super_operator_index5_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
 super_operator_index7_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
 super_operator_index8_test: Crash # (super[f()]=g()): visitUnresolvedSuperIndexSet
@@ -373,17 +297,14 @@
 switch_label2_test: Crash # (switch (target){cas...  continue to a labeled switch case
 switch_label_test: Crash # (switch (animal){cas...  continue to a labeled switch case
 switch_try_catch_test: Crash # (switch (0){_0:case ...  continue to a labeled switch case
-sync_generator1_test/01: RuntimeError # Expect.equals(expected: <(1, 2, 3, 5, [6])>, actual: <(1)>) fails.
-sync_generator1_test/none: RuntimeError # Expect.equals(expected: <(1, 2, 3, 5, [6])>, actual: <(1)>) fails.
-sync_generator3_test/test1: RuntimeError # Please triage this failure.
-sync_generator3_test/test2: RuntimeError # Please triage this failure.
-syncstar_yield_test/copyParameters: RuntimeError # Please triage this failure.
-syncstar_yield_test/none: RuntimeError # Please triage this failure.
-syncstar_yieldstar_test: RuntimeError # Please triage this failure.
-type_variable_closure2_test: RuntimeError # Please triage this failure.
-type_variable_field_initializer_closure_test: RuntimeError # Please triage this failure.
-type_variable_field_initializer_test: RuntimeError # Please triage this failure.
-type_variable_nested_test: RuntimeError # Please triage this failure.
+type_variable_closure2_test: RuntimeError # Issue 25309: T lost in List<T>
+type_variable_closure4_test: RuntimeError # T lost in <T,T>{}
+type_variable_field_initializer_closure_test: RuntimeError # Issue 25309: T lost in List<T>
+type_variable_field_initializer_test: RuntimeError # Issue 25309: T lost in List<T>
+type_variable_nested_test: RuntimeError # Issue 25309: T lost in List<T>
+
+[ $compiler == dart2js && $cps_ir && $host_checked == false ]
+regress_21795_test: Pass, RuntimeError # Due to inlining?
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 async_throw_in_catch_test/forceAwait: Crash # Issue 24485
diff --git a/tests/language/nan_identical_test.dart b/tests/language/nan_identical_test.dart
index b4bba9a..a567f80 100644
--- a/tests/language/nan_identical_test.dart
+++ b/tests/language/nan_identical_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 // Test a new statement by itself.
-// VMOptions=--optimization-counter-threshold=4 --no-use-osr
+// VMOptions=--optimization-counter-threshold=4
 
 import 'dart:typed_data';
 
@@ -48,4 +48,4 @@
   }
 }
 
-checkIdentical(a, b) => identical(a, b);
\ No newline at end of file
+checkIdentical(a, b) => identical(a, b);
diff --git a/tests/language/null2_test.dart b/tests/language/null2_test.dart
index 16d3a83..000eed6 100644
--- a/tests/language/null2_test.dart
+++ b/tests/language/null2_test.dart
@@ -5,16 +5,9 @@
 
 import "package:expect/expect.dart";
 
-// Magic incantation to avoid the compiler recognizing the constant values
-// at compile time. If the result is computed at compile time, the dynamic code
-// will not be tested.
-confuse(x) {
-  try {
-    if (new DateTime.now().millisecondsSinceEpoch == 42) x = 42;
-    throw [x];
-  } on dynamic catch (e) { return e[0]; }
-  return 42;
-}
+@AssumeDynamic()
+@NoInline()
+confuse(x) => x;
 
 main() {
   Expect.equals("Null", null.runtimeType.toString());
diff --git a/tests/language/null_test.dart b/tests/language/null_test.dart
index 83ffd7b..ecb2e00 100644
--- a/tests/language/null_test.dart
+++ b/tests/language/null_test.dart
@@ -36,13 +36,9 @@
 // Magic incantation to avoid the compiler recognizing the constant values
 // at compile time. If the result is computed at compile time, the dynamic code
 // will not be tested.
-confuse(x) {
-  try {
-    if (new DateTime.now().millisecondsSinceEpoch == 42) x = 42;
-    throw [x];
-  } on dynamic catch (e) { return e[0]; }
-  return 42;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 void main() {
   for (int i = 0; i < 10; i++) {
diff --git a/tests/language/operations_on_non_num_operand_test.dart b/tests/language/operations_on_non_num_operand_test.dart
new file mode 100644
index 0000000..9f990ad
--- /dev/null
+++ b/tests/language/operations_on_non_num_operand_test.dart
@@ -0,0 +1,129 @@
+// 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 dart2js that used to miscompile boolean and operations 
+/// if one of the operands was an int and the other was not (issue 22427).
+///
+/// Extended to all operations as there is a risk of similar bugs with other
+/// operators, e.g. `a % 2` _looks_ like it might be 0 or 1.
+
+import "package:expect/expect.dart";
+
+@AssumeDynamic() @NoInline()
+confuse(x) => x;
+
+class Thing1 {
+  operator&(b) => this;
+  operator|(b) => this;
+  operator^(b) => this;
+  operator<<(b) => this;
+  operator>>(b) => this;
+
+  operator+(b) => this;
+  operator-(b) => this;
+  operator*(b) => this;
+  operator/(b) => this;
+  operator~/(b) => this;
+  operator%(b) => this;
+  remainder(b) => this;
+
+  operator<(b) => this;
+  operator<=(b) => this;
+  operator>(b) => this;
+  operator>=(b) => this;
+}
+
+class Thing2 {
+  @NoInline() operator&(b) => this;
+  @NoInline() operator|(b) => this;
+  @NoInline() operator^(b) => this;
+  @NoInline() operator<<(b) => this;
+  @NoInline() operator>>(b) => this;
+
+  @NoInline() operator+(b) => this;
+  @NoInline() operator-(b) => this;
+  @NoInline() operator*(b) => this;
+  @NoInline() operator/(b) => this;
+  @NoInline() operator~/(b) => this;
+  @NoInline() operator%(b) => this;
+  @NoInline() remainder(b) => this;
+
+  @NoInline() operator<(b) => this;
+  @NoInline() operator<=(b) => this;
+  @NoInline() operator>(b) => this;
+  @NoInline() operator>=(b) => this;
+}
+
+
+confused() {
+  var a = new Thing1();
+  Expect.equals(a, confuse(a) & 5 & 2);
+  Expect.equals(a, confuse(a) | 5 | 2);
+  Expect.equals(a, confuse(a) ^ 5 ^ 2);
+  Expect.equals(a, confuse(a) << 5 << 2);
+  Expect.equals(a, confuse(a) >> 5 >> 2);
+
+  Expect.equals(a, confuse(a) + 5 + 2);
+  Expect.equals(a, confuse(a) - 5 - 2);
+  Expect.equals(a, confuse(a) * 5 * 2);
+  Expect.equals(a, confuse(a) / 5 / 2);
+  Expect.equals(a, confuse(a) % 5 % 2);
+  Expect.equals(a, confuse(a) ~/ 5 ~/ 2);
+  Expect.equals(a, confuse(a).remainder(5).remainder(2));
+
+  Expect.equals(a, (confuse(a) < 5) < 2);
+  Expect.equals(a, (confuse(a) <= 5) <= 2);
+  Expect.equals(a, (confuse(a) > 5) > 2);
+  Expect.equals(a, (confuse(a) >= 5) >= 2);
+}
+
+direct1() {
+  var a = new Thing1();
+  Expect.equals(a, a & 5 & 2);
+  Expect.equals(a, a | 5 | 2);
+  Expect.equals(a, a ^ 5 ^ 2);
+  Expect.equals(a, a << 5 << 2);
+  Expect.equals(a, a >> 5 >> 2);
+
+  Expect.equals(a, a + 5 + 2);
+  Expect.equals(a, a - 5 - 2);
+  Expect.equals(a, a * 5 * 2);
+  Expect.equals(a, a / 5 / 2);
+  Expect.equals(a, a % 5 % 2);
+  Expect.equals(a, a ~/ 5 ~/ 2);
+  Expect.equals(a, a.remainder(5).remainder(2));
+
+  Expect.equals(a, (a < 5) < 2);
+  Expect.equals(a, (a <= 5) <= 2);
+  Expect.equals(a, (a > 5) > 2);
+  Expect.equals(a, (a >= 5) >= 2);
+}
+
+direct2() {
+  var a = new Thing2();
+  Expect.equals(a, a & 5 & 2);
+  Expect.equals(a, a | 5 | 2);
+  Expect.equals(a, a ^ 5 ^ 2);
+  Expect.equals(a, a << 5 << 2);
+  Expect.equals(a, a >> 5 >> 2);
+
+  Expect.equals(a, a + 5 + 2);
+  Expect.equals(a, a - 5 - 2);
+  Expect.equals(a, a * 5 * 2);
+  Expect.equals(a, a / 5 / 2);
+  Expect.equals(a, a % 5 % 2);
+  Expect.equals(a, a ~/ 5 ~/ 2);
+  Expect.equals(a, a.remainder(5).remainder(2));
+
+  Expect.equals(a, (a < 5) < 2);
+  Expect.equals(a, (a <= 5) <= 2);
+  Expect.equals(a, (a > 5) > 2);
+  Expect.equals(a, (a >= 5) >= 2);
+}
+
+main () {
+  confused();
+  direct1();
+  direct2();
+}
diff --git a/tests/language/pure_function2_test.dart b/tests/language/pure_function2_test.dart
index 1fdf5f0..c63d053 100644
--- a/tests/language/pure_function2_test.dart
+++ b/tests/language/pure_function2_test.dart
@@ -6,10 +6,9 @@
 
 // Regression test for issue 17483.
 
-confuse(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x);
-  return x;
-}
+
+@AssumeDynamic() @NoInline()
+confuse(x) => x;
 
 foo(trace) {
   trace.add("foo");
diff --git a/tests/language/range_analysis3_test.dart b/tests/language/range_analysis3_test.dart
index 5628e46..8777212 100644
--- a/tests/language/range_analysis3_test.dart
+++ b/tests/language/range_analysis3_test.dart
@@ -4,14 +4,9 @@
 
 import "package:expect/expect.dart";
 
-confuse(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 0) {
-    return confuse(x + 1);
-  } else if (new DateTime.now().millisecondsSinceEpoch == 0) {
-    return confuse(x - 1);
-  }
-  return x;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x is int ? x : 0;
 
 test1() {
   int x = 0;
@@ -207,4 +202,4 @@
   test3b();
   test4a();
   test4b();
-}
\ No newline at end of file
+}
diff --git a/tests/language/regress_25122_test.dart b/tests/language/regress_25122_test.dart
new file mode 100644
index 0000000..b7d4068
--- /dev/null
+++ b/tests/language/regress_25122_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {}
+
+class AbstractListMember<E, M extends AbstractListMember<E, M>> {}
+
+class RepoListMember<M extends RepoListMember<M>>
+    extends AbstractListMember<String, M> {}
diff --git a/tests/language/regress_25246_1_test.dart b/tests/language/regress_25246_1_test.dart
new file mode 100644
index 0000000..e392e89
--- /dev/null
+++ b/tests/language/regress_25246_1_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 'regress_25246_2.dart';
+
+class ConcreteClass extends Object with MixIn { }
+
+void main() {
+  new ConcreteClass().test();
+}
diff --git a/tests/language/regress_25246_2.dart b/tests/language/regress_25246_2.dart
new file mode 100644
index 0000000..84c9cfb
--- /dev/null
+++ b/tests/language/regress_25246_2.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'regress_25246_3.dart';
+
+class MixIn {
+  var test3 = new Test3(() { });
+  void test() {
+    test3.test();
+  }
+}
diff --git a/tests/language/regress_25246_3.dart b/tests/language/regress_25246_3.dart
new file mode 100644
index 0000000..ce61a2e
--- /dev/null
+++ b/tests/language/regress_25246_3.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Test3 {
+  final fn;
+  Test3(this.fn);
+  void test() {
+    fn();
+  }
+}
diff --git a/tests/language/regress_25389_part.dart b/tests/language/regress_25389_part.dart
new file mode 100644
index 0000000..c14d2b1
--- /dev/null
+++ b/tests/language/regress_25389_part.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of regress_25389;
+
+abstract class ComponentState<S extends ComponentState> {}
+
+abstract class AbstractListEditorState<D,
+    S extends AbstractListEditorState<D, S>> extends ComponentState<S> {}
+
+class IssueListEditorState
+    extends AbstractListEditorState<String, IssueListEditorState>
+    implements ComponentState<IssueListEditorState> {}
+
diff --git a/tests/language/regress_25389_test.dart b/tests/language/regress_25389_test.dart
new file mode 100644
index 0000000..8bcd79a
--- /dev/null
+++ b/tests/language/regress_25389_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--error-on-bad-type
+
+library regress_25389;
+
+part 'regress_25389_part.dart';
+
+main() {
+  new IssueListEditorState();
+}
+
+abstract class AbstractListEditor<D, S extends AbstractListEditorState<D, S>> {}
+
diff --git a/tests/language/stacktrace_test.dart b/tests/language/stacktrace_test.dart
index e39f151..7ad6eee 100644
--- a/tests/language/stacktrace_test.dart
+++ b/tests/language/stacktrace_test.dart
@@ -1,4 +1,3 @@
-
 // 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.
diff --git a/tests/language/super_bound_closure_test.dart b/tests/language/super_bound_closure_test.dart
index 1663c93..992d492 100644
--- a/tests/language/super_bound_closure_test.dart
+++ b/tests/language/super_bound_closure_test.dart
@@ -4,6 +4,10 @@
 
 import "package:expect/expect.dart";
 
+@AssumeDynamic()
+@NoInline()
+confuse(x) => x;
+
 class A {
   bar([var optional = 1]) => 498 + optional;
   bar2({ namedOptional: 2 }) => 40 + namedOptional;
@@ -93,11 +97,6 @@
   lastWhere(x, { orElse: 555 }) => -1;
 }
 
-confuse(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x - 1);
-  return x;
-}
-
 main() {
   var list = [new A(), new B(), [], "foo" ];
   var a = list[confuse(0)];
diff --git a/tests/language/syncstar_less_than_test.dart b/tests/language/syncstar_less_than_test.dart
index b0551a8..db2f6f3 100644
--- a/tests/language/syncstar_less_than_test.dart
+++ b/tests/language/syncstar_less_than_test.dart
@@ -4,7 +4,8 @@
 
 import "package:expect/expect.dart";
 
-confuse(x) => [1, 'x', true, null, x].last;
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
 
 Iterable<int> foo() sync* {
  var a = confuse(1);
@@ -15,4 +16,4 @@
 
 main() {
   Expect.listEquals(foo().toList(), [2]);
-}
\ No newline at end of file
+}
diff --git a/tests/language/try_finally_regress_25333_test.dart b/tests/language/try_finally_regress_25333_test.dart
new file mode 100644
index 0000000..1feb510
--- /dev/null
+++ b/tests/language/try_finally_regress_25333_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test correct handling of try-catch inside try-finally.
+
+import "package:expect/expect.dart";
+
+void main() {
+  print("== test1 ==");
+  bool caught = false;
+  try {
+    test1();
+    print("Unexpected 1"); // should never go here
+    Expect.isTrue(false);
+  } catch (e) {
+    caught = true;
+    print("main catch 1: $e");
+    Expect.equals(e, "Ball");
+  }
+  Expect.isTrue(caught);
+  print("== test2 ==");
+  caught = false;
+  try {
+    test2();
+    print("Unexpected 2"); // should never go here
+    Expect.isTrue(false);
+  } catch (e) {
+    caught = true;
+    print("main catch 2: $e");
+    Expect.equals(e, "Ball");
+  }
+  Expect.isTrue(caught);
+}
+
+void test1() {
+  try {
+    throw "Ball";
+  } finally {
+    try {
+      throw "Frisbee";
+    } catch(e) {
+      print("test 1 catch: $e");
+      Expect.equals(e, "Frisbee");
+    }
+  }
+}
+
+void test2() {
+  try {
+    throwError(); // call a method that throws an error
+  } finally {
+    try {
+      throw "Frisbee";
+    } catch(e) {
+      print("test 2 catch: $e");
+      Expect.equals(e, "Frisbee");
+    }
+  }
+}
+
+
+void throwError() {
+  throw "Ball";
+}
diff --git a/tests/language/type_variable_closure2_test.dart b/tests/language/type_variable_closure2_test.dart
index 1b55ff9..83e246b 100644
--- a/tests/language/type_variable_closure2_test.dart
+++ b/tests/language/type_variable_closure2_test.dart
@@ -7,25 +7,12 @@
 class A<T> {}
 
 class C<T> {
-  a() {
-    return () => new A<T>();
-  }
-
   list() {
     return () => <T>[];
   }
-
-  map() {
-    return () => <T, T>{};
-  }
 }
 
 main() {
-  Expect.isTrue(new C<int>().a()() is A<int>);
-  Expect.isFalse(new C<int>().a()() is A<String>);
   Expect.isTrue(new C<int>().list()() is List<int>);
   Expect.isFalse(new C<int>().list()() is List<String>);
-  Expect.isTrue(new C<int>().map()() is Map<int, int>);
-  Expect.isFalse(new C<int>().map()() is Map<String, int>);
-  Expect.isFalse(new C<int>().map()() is Map<int, String>);
 }
diff --git a/tests/language/type_variable_closure3_test.dart b/tests/language/type_variable_closure3_test.dart
new file mode 100644
index 0000000..ecb1c39
--- /dev/null
+++ b/tests/language/type_variable_closure3_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A<T> {}
+
+class C<T> {
+  a() {
+    return () => new A<T>();
+  }
+}
+
+main() {
+  Expect.isTrue(new C<int>().a()() is A<int>);
+  Expect.isFalse(new C<int>().a()() is A<String>);
+}
diff --git a/tests/language/type_variable_closure4_test.dart b/tests/language/type_variable_closure4_test.dart
new file mode 100644
index 0000000..e75bc08
--- /dev/null
+++ b/tests/language/type_variable_closure4_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A<T> {}
+
+class C<T> {
+  map() {
+    return () => <T, T>{};
+  }
+}
+
+main() {
+  Expect.isTrue(new C<int>().map()() is Map<int, int>);
+  Expect.isFalse(new C<int>().map()() is Map<String, int>);
+  Expect.isFalse(new C<int>().map()() is Map<int, String>);
+}
diff --git a/tests/language/type_variable_field_initializer2_test.dart b/tests/language/type_variable_field_initializer2_test.dart
new file mode 100644
index 0000000..098d9e3
--- /dev/null
+++ b/tests/language/type_variable_field_initializer2_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that an inlined field initializer has access to the enclosing
+// type variables.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  var c = new X<T>();
+}
+
+class B<T> extends A<T> {
+}
+
+class X<T> {}
+
+main() {
+  Expect.isTrue(new B<int>().c is X<int>);
+  Expect.isFalse(new B<String>().c is X<int>);
+}
diff --git a/tests/language/type_variable_field_initializer_closure2_test.dart b/tests/language/type_variable_field_initializer_closure2_test.dart
new file mode 100644
index 0000000..eaefd18
--- /dev/null
+++ b/tests/language/type_variable_field_initializer_closure2_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that an inlined field closure has access to the enclosing
+// type variables.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  var c = (() => new X<T>())();
+}
+
+class B<T> extends A<T> {
+}
+
+class X<T> {}
+
+main() {
+  Expect.isTrue(new B<int>().c is X<int>);
+  Expect.isFalse(new B<String>().c is X<int>);
+}
diff --git a/tests/language/vm/load_elimination_any_use_creates_alias_test.dart b/tests/language/vm/load_elimination_any_use_creates_alias_test.dart
index 1ad73c1..dd7341d 100644
--- a/tests/language/vm/load_elimination_any_use_creates_alias_test.dart
+++ b/tests/language/vm/load_elimination_any_use_creates_alias_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test correctness of side effects tracking used by load to load forwarding.
 
-// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations
+// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations --no-background-compilation
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/vm/load_elimination_has_loads_from_place_test.dart b/tests/language/vm/load_elimination_has_loads_from_place_test.dart
index 24414eb..cc01ad7 100644
--- a/tests/language/vm/load_elimination_has_loads_from_place_test.dart
+++ b/tests/language/vm/load_elimination_has_loads_from_place_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test correctness of side effects tracking used by load to load forwarding.
 
-// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations --no-background-compilation
 
 // Tests correct handling of redefinitions in aliasing computation.
 
diff --git a/tests/language/vm/load_elimination_mark_stored_values_escaping_test.dart b/tests/language/vm/load_elimination_mark_stored_values_escaping_test.dart
index 3ea4271..1c079af 100644
--- a/tests/language/vm/load_elimination_mark_stored_values_escaping_test.dart
+++ b/tests/language/vm/load_elimination_mark_stored_values_escaping_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test correctness of side effects tracking used by load to load forwarding.
 
-// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations
+// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations --no-background-compilation
 
 // Tests correct handling of redefinitions in aliasing computation.
 
diff --git a/tests/language/vm/load_elimination_two_redefinitions_test.dart b/tests/language/vm/load_elimination_two_redefinitions_test.dart
index 58a8f17..9e15ebc 100644
--- a/tests/language/vm/load_elimination_two_redefinitions_test.dart
+++ b/tests/language/vm/load_elimination_two_redefinitions_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test correctness of side effects tracking used by load to load forwarding.
 
-// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations --no-background-compilation
 
 // Tests correct handling of redefinitions in aliasing computation.
 
diff --git a/tests/language/vm/optimized_guarded_field_isolates_test.dart b/tests/language/vm/optimized_guarded_field_isolates_test.dart
index fc5e915..a150656 100644
--- a/tests/language/vm/optimized_guarded_field_isolates_test.dart
+++ b/tests/language/vm/optimized_guarded_field_isolates_test.dart
@@ -9,6 +9,7 @@
 import "dart:isolate";
 import "dart:async";
 import "package:expect/expect.dart";
+import 'package:async_helper/async_helper.dart';
 
 class A {
   A(this.a);
@@ -29,6 +30,7 @@
 
 test_field_type() {
   var receive_port = new ReceivePort();
+  asyncStart();
   Future<Isolate> isolate = Isolate.spawn(f1, receive_port.sendPort);
   B b = new B(1, 2);
   for (var i = 0; i < 200; i++) { test_b(b); }
@@ -37,6 +39,7 @@
   item.then((B value) {
       Expect.equals("foobar", test_b(value));
       receive_port.close();
+      asyncEnd();
   });
 }
 
@@ -53,6 +56,7 @@
 
 test_list_length() {
   var receive_port = new ReceivePort();
+  asyncStart();
   Future<Isolate> isolate = Isolate.spawn(f2, receive_port.sendPort);
   C c = new C(new List(10000));
   for (var i = 0; i < 200; i++) { test_c(c); }
@@ -61,6 +65,7 @@
   item.then((C value) {
       Expect.throws(() => test_c(value), (e) => e is RangeError);
       receive_port.close();
+      asyncEnd();
   });
 }
 
diff --git a/tests/language/vm/optimized_stacktrace_test.dart b/tests/language/vm/optimized_stacktrace_test.dart
index c5f98c9..3ad73f1 100644
--- a/tests/language/vm/optimized_stacktrace_test.dart
+++ b/tests/language/vm/optimized_stacktrace_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--stacktrace-every=3 --optimization-counter-threshold=10 --enable-inlining-annotations
+// VMOptions=--stacktrace-every=3 --optimization-counter-threshold=10 --enable-inlining-annotations --no-background-compilation
 
 // Test generating stacktraces with inlining and deferred code.
 // Regression test for issue dartbug.com/22331
diff --git a/tests/language/vm/precompiled_static_initializer_test.dart b/tests/language/vm/precompiled_static_initializer_test.dart
new file mode 100644
index 0000000..195e07d
--- /dev/null
+++ b/tests/language/vm/precompiled_static_initializer_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test optimizations with static fields with precompilation.
+// VMOptions=--inlining-hotness=0
+
+import 'package:expect/expect.dart';
+
+init() => 123;
+
+final a = init();
+
+main() {
+  var s = 0;
+  for (var i = 0; i < 10; i++) {
+    s += a;
+  }
+  Expect.equals(10 * 123, s);
+}
diff --git a/tests/language/vm/type_propagation_test.dart b/tests/language/vm/type_propagation_test.dart
index 935c096..2783654 100644
--- a/tests/language/vm/type_propagation_test.dart
+++ b/tests/language/vm/type_propagation_test.dart
@@ -12,7 +12,7 @@
 }
 
 class C {
-  final f0;
+  final f0 = null;
 
   final a;
   C() : a = new B(0);
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 030340d..e8387bf 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -926,6 +926,74 @@
   testType("Future.error", new Future<int>.error("ERR")..catchError((_){}));
 }
 
+void testAnyValue() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var result = Future.any(cs.map((x) => x.future));
+
+  result.then((v) {
+    Expect.equals(42, v);
+    asyncEnd();
+  }, onError: (e, s) {
+    Expect.fail("Unexpected error: $e");
+  });
+
+  cs[1].complete(42);
+  cs[2].complete(10);
+  cs[0].complete(20);
+}
+
+void testAnyError() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var result = Future.any(cs.map((x) => x.future));
+
+  result.then((v) {
+    Expect.fail("Unexpected value: $v");
+  }, onError: (e, s) {
+    Expect.equals(42, e);
+    asyncEnd();
+  });
+
+  cs[1].completeError(42);
+  cs[2].complete(10);
+  cs[0].complete(20);
+}
+
+void testAnyIgnoreIncomplete() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var result = Future.any(cs.map((x) => x.future));
+
+  result.then((v) {
+    Expect.equals(42, v);
+    asyncEnd();
+  }, onError: (e, s) {
+    Expect.fail("Unexpected error: $e");
+  });
+
+  cs[1].complete(42);
+  // The other two futures never complete.
+}
+
+void testAnyIgnoreError() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var result = Future.any(cs.map((x) => x.future));
+
+  result.then((v) {
+    Expect.equals(42, v);
+    asyncEnd();
+  }, onError: (e, s) {
+    Expect.fail("Unexpected error: $e");
+  });
+
+  cs[1].complete(42);
+  // The errors are ignored, not uncaught.
+  cs[2].completeError("BAD");
+  cs[0].completeError("BAD");
+}
+
 main() {
   asyncStart();
 
@@ -989,6 +1057,11 @@
 
   testTypes();
 
+  testAnyValue();
+  testAnyError();
+  testAnyIgnoreIncomplete();
+  testAnyIgnoreError();
+
   asyncEnd();
 }
 
diff --git a/tests/lib/async/stream_from_futures_test.dart b/tests/lib/async/stream_from_futures_test.dart
new file mode 100644
index 0000000..e4eaef5
--- /dev/null
+++ b/tests/lib/async/stream_from_futures_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import 'package:async_helper/async_helper.dart';
+
+main() {
+  asyncStart();
+
+  testValues();
+  testErrors();
+  testMixed();
+  testOrdering();
+  testEmpty();
+  testPrecompleted();
+
+  asyncEnd();
+}
+
+void testValues() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var stream = new Stream.fromFutures(cs.map((x) => x.future));
+  var result = stream.toList();
+
+  result.then((list) {
+    Expect.listEquals([1, 2, 3], list);
+    asyncEnd();
+  });
+
+  cs[1].complete(1);
+  cs[2].complete(2);
+  cs[0].complete(3);
+}
+
+void testErrors() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var stream = new Stream.fromFutures(cs.map((x) => x.future));
+
+  int counter = 0;
+  stream.listen((_) {
+    Expect.fail("unexpected value");
+  }, onError: (e) {
+    Expect.equals(++counter, e);
+  }, onDone: () {
+    Expect.equals(3, counter);
+    asyncEnd();
+  });
+
+  cs[1].completeError(1);
+  cs[2].completeError(2);
+  cs[0].completeError(3);
+}
+
+void testMixed() {
+  asyncStart();
+  var cs = new List.generate(3, (_) => new Completer());
+  var stream = new Stream.fromFutures(cs.map((x) => x.future));
+
+  int counter = 0;
+  stream.listen((v) {
+    Expect.isTrue(counter == 0 || counter == 2);
+    Expect.equals(++counter, v);
+  }, onError: (e) {
+    Expect.equals(++counter, 2);
+    Expect.equals(2, e);
+  }, onDone: () {
+    Expect.equals(3, counter);
+    asyncEnd();
+  });
+
+  cs[1].complete(1);
+  cs[2].completeError(2);
+  cs[0].complete(3);
+}
+
+void testOrdering() {
+  // The output is in completion order, not affected by the input future order.
+  test(n1, n2, n3) {
+    asyncStart();
+    var cs = new List.generate(3, (_) => new Completer());
+    var stream = new Stream.fromFutures(cs.map((x) => x.future));
+    var result = stream.toList();
+
+    result.then((list) {
+      Expect.listEquals([1, 2, 3], list);
+      asyncEnd();
+    });
+
+    cs[n1].complete(1);
+    cs[n2].complete(2);
+    cs[n3].complete(3);
+  }
+  test(0, 1, 2);
+  test(0, 2, 1);
+  test(1, 0, 2);
+  test(1, 2, 0);
+  test(2, 0, 1);
+  test(2, 1, 0);
+}
+
+void testEmpty() {
+  asyncStart();
+  var stream = new Stream.fromFutures([]);
+
+  stream.listen((_) {
+    Expect.fail("unexpected value");
+  }, onError: (e) {
+    Expect.fail("unexpected error");
+  }, onDone: () {
+    asyncEnd();
+  });
+}
+
+void testPrecompleted() {
+  asyncStart();
+  var stream = new Stream.fromFutures(
+      new Iterable.generate(3, (v) => new Future.value(v + 1)));
+  var expected = new Set.from([1, 2, 3]);
+  stream.listen((v) {
+    Expect.isTrue(expected.contains(v));
+    expected.remove(v);
+  }, onDone: () {
+    Expect.isTrue(expected.isEmpty);
+    asyncEnd();
+  });
+}
diff --git a/tests/lib/async/stream_periodic3_test.dart b/tests/lib/async/stream_periodic3_test.dart
index 437a8a6..b25ae27 100644
--- a/tests/lib/async/stream_periodic3_test.dart
+++ b/tests/lib/async/stream_periodic3_test.dart
@@ -21,7 +21,7 @@
                                         (x) => x);
     stream.take(10).listen((_) { }, onDone: expectAsync(() {
       int millis = watch.elapsedMilliseconds + safetyMargin;
-      expect(millis, greaterThan(10));
+      expect(millis, greaterThanOrEqualTo(10));
     }));
   });
 }
diff --git a/tests/lib/async/stream_periodic6_test.dart b/tests/lib/async/stream_periodic6_test.dart
new file mode 100644
index 0000000..1d4ffa3
--- /dev/null
+++ b/tests/lib/async/stream_periodic6_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test merging streams.
+library dart.test.stream_from_iterable;
+
+import "dart:async";
+import 'package:unittest/unittest.dart';
+
+main() {
+  test("stream-periodic1", () {
+    Stream stream = new Stream.periodic(const Duration(milliseconds: 1),
+                                        (i) {
+                                          if (i == 3) throw 42;
+                                          return i;
+                                        });
+    int expected = 0;
+    var subscription;
+    subscription = stream.listen(expectAsync((data) {
+      expect(data, expected++);
+      if (expected == 5) subscription.cancel();
+    }, count: 4),
+    onError: expectAsync((e, s) {
+      expect(e, 42);
+      expected++;
+    }));
+  });
+}
diff --git a/tests/lib/developer/timeline_test.dart b/tests/lib/developer/timeline_test.dart
new file mode 100644
index 0000000..fab8e93
--- /dev/null
+++ b/tests/lib/developer/timeline_test.dart
@@ -0,0 +1,23 @@
+// 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:developer';
+import 'package:expect/expect.dart';
+
+void testUnbalancedStartFinish() {
+  Timeline.startSync('A');
+  Timeline.finishSync();
+
+  bool exceptionCaught = false;
+  try {
+    Timeline.finishSync();
+  } catch (e) {
+    exceptionCaught = true;
+  }
+  Expect.isTrue(exceptionCaught);
+}
+
+void main() {
+  testUnbalancedStartFinish();
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 886da8b..d4cdafe 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -64,12 +64,6 @@
 mirrors/load_library_test: RuntimeError # Issue 6335
 mirrors/local_function_is_static_test: RuntimeError # Issue 6335
 mirrors/lru_test: Skip # dart2js_native/lru_test is used instead
-mirrors/metadata_allowed_values_test/01: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/05: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/10: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/11: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/13: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/14: MissingCompileTimeError # Issue 14548
 mirrors/metadata_scope_test/none: CompileTimeError # Issue 10905
 mirrors/method_mirror_name_test: RuntimeError # Issue 6335
 mirrors/method_mirror_properties_test: RuntimeError # Issue 11861
@@ -147,6 +141,7 @@
 async/stream_periodic3_test: RuntimeError # Timer interface not supported; Issue 7728.
 async/stream_periodic4_test: RuntimeError # Timer interface not supported; Issue 7728.
 async/stream_periodic5_test: RuntimeError # Timer interface not supported; Issue 7728.
+async/stream_periodic6_test: RuntimeError # Timer interface not supported; Issue 7728.
 async/run_zoned7_test: RuntimeError # Timer interface not supported: Issue 7728.
 async/catch_errors22_test: RuntimeError # Timer interface not supported: Issue 7728.
 async/timer_isActive_test: RuntimeError # Timer interface not supported: Issue 7728.
@@ -191,7 +186,7 @@
 
 # 'js' tests import the dart:js library, so they only make sense in
 # a browser environment.
-[ $runtime == vm ]
+[ ($runtime == vm || $runtime == dart_precompiled) ]
 js/*: Skip
 
 [ $compiler == dart2js && $minified ]
@@ -228,19 +223,19 @@
 # TODO(efortuna): Investigate.
 async/timer_test: Fail, Pass
 
-[ $runtime == vm ]
+[ ($runtime == vm || $runtime == dart_precompiled) ]
 async/timer_not_available_test: Fail, OK
 mirrors/native_class_test: Fail, OK # This test is meant to run in a browser.
 mirrors/deferred_type_test: CompileTimeError, OK # Don't have a multitest marker for dynamic compile time errors.
 
-[ $compiler == none ]
+[ ($compiler == none || $compiler == precompiler) ]
 async/timer_not_available_test: SkipByDesign # only meant to test when there is no way to implement timer (currently only in d8)
 
 mirrors/symbol_validation_test: RuntimeError # Issue 13596
 
 mirrors/mirrors_used*: SkipByDesign # Invalid tests. MirrorsUsed does not have a specification, and dart:mirrors is not required to hide declarations that are not covered by any MirrorsUsed annotation.
 
-[ $compiler == none && ( $runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler) && ( $runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 async/schedule_microtask6_test: Fail # Issue 10910
 async/timer_test: Fail, Pass # Issue 15487
 async/multiple_timer_test: Fail, Pass # Issue 15487
@@ -253,14 +248,14 @@
 mirrors/local_isolate_test: RuntimeError # Issue 12188
 mirrors/deferred_type_test: RuntimeError, OK # Should be CompileTimeError. Issue 22072
 
-[ $compiler == none && $runtime == drt && $system == windows ]
+[ ($compiler == none || $compiler == precompiler) && $runtime == drt && $system == windows ]
 async/multiple_timer_test: Fail, Pass # See Issue 10982
 async/timer_test: Fail, Pass # See Issue 10982
 
-[ $compiler == none && $runtime == drt && $checked ]
+[ ($compiler == none || $compiler == precompiler) && $runtime == drt && $checked ]
 async/slow_consumer_test: Fail, Pass # Dartium JsInterop failure, dartbug.com/24460
 
-[$compiler == none && $runtime == ContentShellOnAndroid ]
+[($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
 async/stream_timeout_test: RuntimeError, Pass # Issue 19127
 async/slow_consumer3_test: SkipSlow # Times out flakily. Issue 20956
 async/slow_consumer2_test: SkipSlow # Times out flakily. Issue 20956
@@ -297,6 +292,9 @@
 profiler/metrics_test: Fail # Issue 20309
 profiler/metrics_num_test: Fail # Issue 20309
 
+[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+mirrors/metadata_allowed_values_test/29: Crash # Issue 25287
+
 [ ($compiler == dartanalyzer || $compiler == dart2analyzer) && $checked ]
 mirrors/regress_16321_test/01: MissingCompileTimeError # Issue 16391
 
@@ -307,7 +305,7 @@
 [ $compiler == dart2js && $mode == debug ]
 mirrors/native_class_test: Pass, Slow
 
-[ $compiler == none && $arch == mips ]
+[ ($compiler == none || $compiler == precompiler) && $arch == mips ]
 async/timer_regress22626_test: Pass, RuntimeError # Issue 22626
 
 [ $arch == simarm || $arch == simarmv5te ]
@@ -319,6 +317,7 @@
 
 [ $compiler == dart2js ]
 developer/metrics_num_test: Skip # Because of a int / double type test.
+developer/timeline_test: Skip # Not supported
 
 [ $arch == simarm64 ]
 convert/utf85_test: Skip # Pass, Slow Issue 20111.
@@ -326,30 +325,23 @@
 [ $mode == debug && $arch == ia32 && $system == windows ]
 convert/streamed_conversion_json_utf8_decode_test: Skip  # Verification OOM.
 
-[ $runtime == vm && $mode == debug && $arch == x64 && $system == windows ]
+[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $arch == x64 && $system == windows ]
 convert/streamed_conversion_json_utf8_decode_test: Pass, Slow
 
+[ ($runtime == vm || $runtime == dart_precompiled) && $mode == release && $arch == ia32 && $system == windows ]
+convert/json_test: RuntimeError # Issue 24908
+
 [ $mode == debug && $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv5te ]
 convert/streamed_conversion_json_utf8_decode_test: Skip  # Verification not yet implemented.
 
-[ $runtime == vm && $mode == debug && $builder_tag == asan ]
+[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $builder_tag == asan ]
 mirrors/immutable_collections_test: SkipSlow  # Timeout.
 convert/streamed_conversion_json_utf8_decode_test: Skip  # Timeout.
 
 [ $compiler == dart2js && $cps_ir ]
 async/async_await_zones_test: Crash # (await for(var x in bar().take(100)){sum+= x;}): await for
-async/stream_empty_test: RuntimeError # $async$temp1.runTest_unreachable is not a function
 async/stream_iterator_test: Crash # (Stream createCancel...  cannot handle sync*/async* functions
-convert/json_pretty_test: RuntimeError # Please triage this failure.
-convert/line_splitter_test: RuntimeError # Please triage this failure.
-mirrors/deferred_mirrors_metadata_test: RuntimeError # U.loadLibrary is not a function
-mirrors/deferred_mirrors_metatarget_test: RuntimeError # X.loadLibrary is not a function
-mirrors/deferred_mirrors_update_test: RuntimeError # U.loadLibrary is not a function
-mirrors/delegate_call_through_getter_test: RuntimeError # Please triage this failure.
-mirrors/delegate_test: RuntimeError # Please triage this failure.
-mirrors/library_enumeration_deferred_loading_test: RuntimeError # L.loadLibrary is not a function
 mirrors/symbol_validation_test/none: RuntimeError # Please triage this failure.
-mirrors/typedef_deferred_library_test: RuntimeError # G.loadLibrary is not a function
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 mirrors/circular_factory_redirection_test/02: Crash # Assertion failure: Constant constructor already computed for generative_constructor(A#circular2)
@@ -359,3 +351,8 @@
 
 [ $compiler != dart2js ]
 async/dart2js_uncaught_error_test: Skip  # JS-integration only test
+
+[ ($noopt || $compiler == precompiler) ]
+mirrors/*: SkipByDesign
+convert/chunked_conversion_utf88_test: Pass, Timeout
+convert/utf85_test: Pass, Timeout
diff --git a/tests/lib/math/random_secure_test.dart b/tests/lib/math/random_secure_test.dart
new file mode 100644
index 0000000..33a563e
--- /dev/null
+++ b/tests/lib/math/random_secure_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that the secure random generator does not systematically generates
+// duplicates. Note that this test is flaky by definition, since duplicates
+// can occur. They should be extremely rare, though.
+
+// Library tag to allow Dartium to run the test.
+library random_secure;
+
+import "package:expect/expect.dart";
+import 'dart:math';
+
+main() {
+  var results;
+  var rng0;
+  var rng1;
+  var checkInt = (max) {
+    var intVal0 = rng0.nextInt(max);
+    var intVal1 = rng1.nextInt(max);
+    if (max > (1 << 28)) {
+      Expect.isFalse(results.contains(intVal0));
+      results.add(intVal0);
+      Expect.isFalse(results.contains(intVal1));
+      results.add(intVal1);
+    }
+  };
+  results = [];
+  rng0 = new Random.secure();
+  for(var i = 0; i <= 32; i++) {
+    rng1 = new Random.secure();
+    checkInt(pow(2, 32));
+    checkInt(pow(2, 32 - i));
+    checkInt(1000000000);
+  }
+  var checkDouble = () {
+    var doubleVal0 = rng0.nextDouble();
+    var doubleVal1 = rng1.nextDouble();
+    Expect.isFalse(results.contains(doubleVal0));
+    results.add(doubleVal0);
+    Expect.isFalse(results.contains(doubleVal1));
+    results.add(doubleVal1);
+  };
+  results = [];
+  rng0 = new Random.secure();
+  for(var i = 0; i < 32; i++) {
+    rng1 = new Random.secure();
+    checkDouble();
+  }
+  var cnt0 = 0;
+  var cnt1 = 0;
+  rng0 = new Random.secure();
+  for(var i = 0; i < 32; i++) {
+    rng1 = new Random.secure();
+    cnt0 += rng0.nextBool() ? 1 : 0;
+    cnt1 += rng1.nextBool() ? 1 : 0;
+  }
+  Expect.isTrue((cnt0 > 0) && (cnt0 < 32));
+  Expect.isTrue((cnt1 > 0) && (cnt1 < 32));
+}
+
diff --git a/tests/lib/mirrors/library_exports_hidden_test.dart b/tests/lib/mirrors/library_exports_hidden_test.dart
index 990dbb1..cdfe5fe 100644
--- a/tests/lib/mirrors/library_exports_hidden_test.dart
+++ b/tests/lib/mirrors/library_exports_hidden_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.library_imports;
+library test.library_exports_hidden;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_exports_shown_test.dart b/tests/lib/mirrors/library_exports_shown_test.dart
index 66592f1..4cdded1 100644
--- a/tests/lib/mirrors/library_exports_shown_test.dart
+++ b/tests/lib/mirrors/library_exports_shown_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.library_imports;
+library test.library_exports_shown;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_imports_hidden_test.dart b/tests/lib/mirrors/library_imports_hidden_test.dart
index 3f1dcb0..7d08e1f 100644
--- a/tests/lib/mirrors/library_imports_hidden_test.dart
+++ b/tests/lib/mirrors/library_imports_hidden_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.library_imports;
+library test.library_imports_hidden;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart b/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart
index eb865a1..d18f361 100644
--- a/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart
+++ b/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.library_imports;
+library test.library_imports_prefixed_show_hide;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_imports_prefixed_test.dart b/tests/lib/mirrors/library_imports_prefixed_test.dart
index beda171..1db1799 100644
--- a/tests/lib/mirrors/library_imports_prefixed_test.dart
+++ b/tests/lib/mirrors/library_imports_prefixed_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.library_imports;
+library test.library_imports_prefixed;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/library_imports_shown_test.dart b/tests/lib/mirrors/library_imports_shown_test.dart
index fb16df2..208e570 100644
--- a/tests/lib/mirrors/library_imports_shown_test.dart
+++ b/tests/lib/mirrors/library_imports_shown_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.library_imports;
+library test.library_imports_shown;
 
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/metadata_allowed_values_test.dart b/tests/lib/mirrors/metadata_allowed_values_test.dart
index ce1011b..76a5c58 100644
--- a/tests/lib/mirrors/metadata_allowed_values_test.dart
+++ b/tests/lib/mirrors/metadata_allowed_values_test.dart
@@ -149,6 +149,30 @@
 }
 get kk => const KK();
 
+@LL(() => 42)  /// 28: compile-time error
+class LL {
+  final field;
+  const LL(this.field);
+}
+
+@MM((x) => 42)  /// 29: compile-time error
+class MM {
+  final field;
+  const MM(this.field);
+}
+
+@NN(() {})  /// 30: compile-time error
+class NN {
+  final field;
+  const NN(this.field);
+}
+
+@OO(() { () {} })  /// 31: compile-time error
+class OO {
+  final field;
+  const OO(this.field);
+}
+
 checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
   Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata);
 }
@@ -191,4 +215,8 @@
   reflectClass(II).metadata;
   reflectClass(JJ).metadata;
   reflectClass(KK).metadata;
+  reflectClass(LL).metadata;
+  reflectClass(MM).metadata;
+  reflectClass(NN).metadata;
+  reflectClass(OO).metadata;
 }
diff --git a/tests/standalone/array_bounds_check_generalization_test.dart b/tests/standalone/array_bounds_check_generalization_test.dart
index bfd0cce..2b6099d 100644
--- a/tests/standalone/array_bounds_check_generalization_test.dart
+++ b/tests/standalone/array_bounds_check_generalization_test.dart
@@ -2,7 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 //
-// VMOptions=--optimization_counter_threshold=10 --no-use-osr
+// We are using --complete-timeline below to ensure that we get timeline events
+// generated during all phases of compilation and deoptimization.
+// VMOptions=--optimization_counter_threshold=10 --no-use-osr --complete-timeline
 
 import "package:expect/expect.dart";
 
diff --git a/tests/standalone/coverage_test.dart b/tests/standalone/coverage_test.dart
deleted file mode 100644
index 1ec4af4..0000000
--- a/tests/standalone/coverage_test.dart
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test forks a second vm process that runs the script tools/coverage.dart
-// and verifies that the coverage tool produces its expected output.
-// This test is mainly here to ensure that the coverage tool compiles and
-// runs.
-
-import "dart:async";
-import "dart:convert";
-import "dart:io";
-
-import "package:path/path.dart";
-
-// Coverage tool script relative to the path of this test.
-var coverageToolScript = "../../tools/coverage.dart";
-
-// Coverage target script relative to this test.
-var coverageTargetScript = "../language/hello_dart_test.dart";
-var targPath;
-
-Process coverageToolProcess;
-List sourceLines;
-int nextLineToMatch = 0;
-
-void onCoverageOutput(String line) {
-  print("COV: $line");
-  if (nextLineToMatch < sourceLines.length) {
-    if (line.endsWith("|" + sourceLines[nextLineToMatch])) {
-      nextLineToMatch++;
-    }
-  }
-}
-
-bool checkExitCode(exitCode) {
-  var pid = coverageToolProcess.pid;
-  print("Coverage tool process (pid $pid) terminated with "
-        "exit code $exitCode.");
-  return exitCode == 0;
-}
-
-void checkSuccess() {
-  if (nextLineToMatch == sourceLines.length) {
-    print("Successfully matched all lines of '$targPath'");
-  } else {
-    print("Error: could not match all source code lines of '$targPath'");
-    exit(-1);
-  }
-}
-
-void main() {
-  // Compute paths for coverage tool and coverage target relative
-  // the the path of this script.
-  var scriptPath = dirname(Platform.script.toFilePath());
-  var toolPath = normalize(join(scriptPath, coverageToolScript));
-  targPath = normalize(join(scriptPath, coverageTargetScript));
-
-  sourceLines = new File(targPath).readAsLinesSync();
-  assert(sourceLines != null);
-
-  var processOpts = [ "--compile_all", toolPath, targPath ];
-
-  Process.start(Platform.executable, processOpts).then((Process process) {
-    coverageToolProcess = process;
-    coverageToolProcess.stdin.close();
-    var stdoutStringStream = coverageToolProcess.stdout
-        .transform(UTF8.decoder)
-        .transform(new LineSplitter());
-
-    var stderrStringStream = coverageToolProcess.stderr
-        .transform(UTF8.decoder)
-        .transform(new LineSplitter());
-
-    // Wait for 3 future events: stdout and stderr streams of the coverage
-    // tool process closed, and coverage tool process terminated.
-    var futures = [];
-    var subscription = stdoutStringStream.listen(onCoverageOutput);
-    futures.add(subscription.asFuture(true));
-    subscription = stderrStringStream.listen(onCoverageOutput);
-    futures.add(subscription.asFuture(true));
-    futures.add(coverageToolProcess.exitCode.then(checkExitCode));
-    Future.wait(futures).then((results) {
-      checkSuccess();
-      if (results.contains(false)) exit(-1);
-    });
-  });
-}
diff --git a/tests/standalone/debugger/basic_debugger_test.dart b/tests/standalone/debugger/basic_debugger_test.dart
deleted file mode 100644
index 9dfded6..0000000
--- a/tests/standalone/debugger/basic_debugger_test.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test forks a second vm process that runs this dart script as
-// a debug target.
-// Run this test with option --wire to see the json messages sent
-// between the processes.
-// Run this test with option --verbose to see the stdout and stderr output
-// of the debug target process.
-
-import "debug_lib.dart";
-
-bar(x) {
-  var localStr = "foo";
-  int localInt = 1;
-  double localDouble = 1.1;
-
-  print(x);
-}
-
-bam(a) => bar(a);
-
-foo(i) {
-  bar("baz");
-  print(i);
-}
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  print("Hello from debuggee");
-  foo(42);
-  bam("bam");
-  print("Hello again");
-}
-
-
-// Expected debugger events and commands.
-var testScript = [
-  MatchFrame(0, "main"),  // Top frame in trace is function "main".
-  Step(),
-  MatchFrame(0, "main"),  // Should still be in "main".
-  SetBreakpoint(19),  // Set breakpoint a line 19, in function bar.
-  Resume(),
-  MatchFrames(["bar", "foo", "main"]),
-  MatchFrame(1, "foo"),
-  MatchLocals({"localStr": '"foo"', "localInt": "1", "localDouble": "1.1", 
-      "x": '"baz"'}),
-  SetBreakpoint(22),  // Set breakpoint a line 22, in function bam.
-  Resume(),
-  MatchFrames(["bam", "main"]),
-  Resume(),
-  MatchFrames(["bar", "bam", "main"]),
-  Resume(),
-];
diff --git a/tests/standalone/debugger/break_at_equals_test.dart b/tests/standalone/debugger/break_at_equals_test.dart
deleted file mode 100644
index 5000e6d..0000000
--- a/tests/standalone/debugger/break_at_equals_test.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "debug_lib.dart";
-
-class MyClass {
-  operator ==(other) {
-    print(other);
-    return true;  // Breakpoint #3.
-  }
-}
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  var a = new MyClass();
-  var b = null;
-  a == b;  // Breakpoint #1.
-  print("after 1");
-  b = 123;
-  a == b;  // Breakpoint #2.
-  print("after 2");
-  a == null;  // Breakpoint #4.
-  print("after 4");
-  if (null == a) {
-    throw "unreachable";
-  }
-  print("ok");
-}
-
-// Checks that debugger can stop at calls to == even if one
-// of the operands is null.
-
-var testScript = [
-  MatchFrames(["main"]),
-  MatchLine(14),
-  SetBreakpoint(18),
-  SetBreakpoint(21),
-  SetBreakpoint(10),
-  SetBreakpoint(23),
-  Resume(),
-  MatchFrames(["main"]),
-  MatchLine(18),  // At breakpoint #1.
-  Resume(),
-  MatchLine(21),  // At breakpoint #2; didn't hit breakpoint in MyClass.==.
-  Resume(),
-  MatchFrames(["MyClass.==", "main"]),
-  MatchLine(10),  // At breakpoint #3 in MyClass.==.
-  Resume(),
-  MatchLine(23),  // At breakpoint #4.
-  Resume()
-];
diff --git a/tests/standalone/debugger/breakpoint_resolved_test.dart b/tests/standalone/debugger/breakpoint_resolved_test.dart
deleted file mode 100644
index 14c2827..0000000
--- a/tests/standalone/debugger/breakpoint_resolved_test.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "debug_lib.dart";
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-
-  bar();
-
-  print("Hello from debuggee");
-}
-
-bar() {
-  // Attempt to set breakpoint in this empty line does not
-  // result in a resolved breakpoint.
-  print("bar");
-}
-
-var testScript = [
-  MatchFrame(0, "main"),
-  SetBreakpoint(10),
-  SetBreakpoint(12),
-  SetBreakpoint(16),
-  Resume(),
-  MatchFrame(0, "main"),
-  Resume(),  // Next breakpoint expected in main, when bar() returns.
-  MatchFrame(0, "main"),
-  // Only two breakpoint resolved events expected.
-  ExpectEvent("breakpointResolved", {"breakpointId": 2}),
-  ExpectEvent("breakpointResolved", {"breakpointId": 3}),
-  Resume(),
-];
diff --git a/tests/standalone/debugger/closure_bp_test.dart b/tests/standalone/debugger/closure_bp_test.dart
deleted file mode 100644
index 2eb2bfd..0000000
--- a/tests/standalone/debugger/closure_bp_test.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test forks a second vm process that runs this dart script as
-// a debug target.
-// Run this test with option --wire to see the json messages sent
-// between the processes.
-// Run this test with option --verbose to see the stdout and stderr output
-// of the debug target process.
-
-import "debug_lib.dart";
-
-bar(x) {
-  print(x);
-}
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  print("Hello from debuggee");
-  [1,2].forEach(bar);  // Causes implicit closure of bar to be compiled.
-  print("stop here");  // Stop here and set breakpoint in bar.
-  [3,4].forEach(bar);  // Call bar closure and observe breakpoints being hit.
-  print("done");
-}
-
-
-// Expected debugger events and commands.
-var testScript = [
-  MatchFrame(0, "main"),  // Top frame in trace is function "main".
-  SetBreakpoint(22),      // Set breakpoint a line 22, after bar closure is compiled.
-  Resume(),
-  MatchFrame(0, "main"),  // Should be at line 22 in main.
-  MatchLine(22),
-  SetBreakpoint(15),      // Set breakpoint in function bar. Bar has not been called
-                          // through a regular function call at this point, only
-                          // through a closure from forEach().
-  Resume(),
-  MatchFrames(["bar", "forEach", "main"]),  // Should be in closure function now.
-  MatchLine(15),
-  MatchLocals({"x": "3"}),
-  Resume(),
-  MatchFrames(["bar", "forEach", "main"]),  // Should be in closure function now.
-  MatchLine(15),
-  MatchLocals({"x": "4"}),
-  Resume(),
-];
diff --git a/tests/standalone/debugger/closure_debugger_test.dart b/tests/standalone/debugger/closure_debugger_test.dart
deleted file mode 100644
index 7562a8c..0000000
--- a/tests/standalone/debugger/closure_debugger_test.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test forks a second vm process that runs this dart script as
-// a debug target.
-// Run this test with option --wire to see the json messages sent
-// between the processes.
-// Run this test with option --verbose to see the stdout and stderr output
-// of the debug target process.
-
-import "debug_lib.dart";
-
-bar(x) {
-  print(x);
-}
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  print("Hello from debuggee");
-  var f = bar;
-  f("closure call");
-  bar(12);
-  var a = new A();
-  for (var i = 0; i < 2; ++i) {
-    a.foo(i);
-  }
-}
-
-class A {
-  A() {
-    foo =
-      (x) => print(x);
-  }
-  var foo;
-}
-
-// Expected debugger events and commands.
-var testScript = [
-  MatchFrame(0, "main"),  // Top frame in trace is function "main".
-  SetBreakpoint(22),      // Set breakpoint a line 22, at the closure call.
-  Resume(),
-  MatchFrame(0, "main"),  // Should be at closure call.
-  StepInto(),
-  MatchFrames(["bar", "main"]),  // Should be in closure function now.
-  StepOut(),
-  MatchFrame(0, "main"),  // Back in main, before static call to bar().
-  SetBreakpoint(15),      // Breakpoint in bar();
-  Resume(),
-  MatchFrames(["bar", "main"]),
-  SetBreakpoint(26),      // Breakpoint in main() at a.field(i).
-  SetBreakpoint(33),      // Breakpoint in closure.
-  Resume(),
-  MatchFrame(0, "main"),  // Should be in main().
-  MatchLocals({"i": "0"}),
-  StepInto(),
-  StepInto(),
-  MatchFrames(["A.<anonymous closure>", "main"]),  // In closure function.
-  Resume(),
-  MatchFrame(0, "main"),  // Back in main().
-  MatchLocals({"i": "1"}),
-  Resume(),
-  MatchFrames(["A.<anonymous closure>", "main"]),  // In closure function.
-  Resume()
-];
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
deleted file mode 100644
index 92a0d10..0000000
--- a/tests/standalone/debugger/debug_lib.dart
+++ /dev/null
@@ -1,749 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Library used by debugger wire protocol tests (standalone VM debugging).
-
-library DartDebugger;
-
-import "dart:async";
-import "dart:convert";
-import "dart:io";
-import "dart:math";
-
-// Whether or not to print the debugger wire messages on the console.
-var verboseWire = false;
-
-// Class to buffer wire protocol data from debug target and
-// break it down to individual json messages.
-class JsonBuffer {
-  String buffer = null;
-
-  append(String s) {
-    if (buffer == null || buffer.length == 0) {
-      buffer = s;
-    } else {
-      buffer += s;
-    }
-  }
-
-  String getNextMessage() {
-    if (buffer == null) return null;
-    int msgLen = objectLength();
-    if (msgLen == 0) return null;
-    String msg = null;
-    if (msgLen == buffer.length) {
-      msg = buffer;
-      buffer = null;
-    } else {
-      assert(msgLen < buffer.length);
-      msg = buffer.substring(0, msgLen);
-      buffer = buffer.substring(msgLen);
-    }
-    return msg;
-  }
-
-  bool haveGarbage() {
-    if (buffer == null || buffer.length == 0) return false;
-    var i = 0, char = " ";
-    while (i < buffer.length) {
-      char = buffer[i];
-      if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
-      i++;
-    }
-    if (i >= buffer.length) {
-      return false;
-    } else {
-      return char != "{";
-    }
-  }
-
-  // Returns the character length of the next json message in the
-  // buffer, or 0 if there is only a partial message in the buffer.
-  // The object value must start with '{' and continues to the
-  // matching '}'. No attempt is made to otherwise validate the contents
-  // as JSON. If it is invalid, a later JSON.decode() will fail.
-  int objectLength() {
-    int skipWhitespace(int index) {
-      while (index < buffer.length) {
-        String char = buffer[index];
-        if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
-        index++;
-      }
-      return index;
-    }
-    int skipString(int index) {
-      assert(buffer[index - 1] == '"');
-      while (index < buffer.length) {
-        String char = buffer[index];
-        if (char == '"') return index + 1;
-        if (char == r'\') index++;
-        if (index == buffer.length) return index;
-        index++;
-      }
-      return index;
-    }
-    int index = 0;
-    index = skipWhitespace(index);
-    // Bail out if the first non-whitespace character isn't '{'.
-    if (index == buffer.length || buffer[index] != '{') return 0;
-    int nesting = 0;
-    while (index < buffer.length) {
-      String char = buffer[index++];
-      if (char == '{') {
-        nesting++;
-      } else if (char == '}') {
-        nesting--;
-        if (nesting == 0) return index;
-      } else if (char == '"') {
-        // Strings can contain braces. Skip their content.
-        index = skipString(index);
-      }
-    }
-    return 0;
-  }
-}
-
-
-getJsonValue(Map jsonMsg, String path) {
-  List properties = path.split(new RegExp(":"));
-  assert(properties.length >= 1);
-  var node = jsonMsg;
-  for (int i = 0; i < properties.length; i++) {
-    if (node == null) return null;
-    String property = properties[i];
-    var index = null;
-    if (property.endsWith("]")) {
-      var bracketPos = property.lastIndexOf("[");
-      if (bracketPos <= 0) return null;
-      var indexStr = property.substring(bracketPos + 1, property.length - 1);
-      try {
-        index = int.parse(indexStr);
-      } on FormatException {
-        print("$indexStr is not a valid array index");
-        return null;
-      }
-      property = property.substring(0, bracketPos);
-    }
-    if (node is Map) {
-      node = node[property];
-    } else {
-      return null;
-    }
-    if (index != null) {
-      if (node is List && node.length > index) {
-        node = node[index];
-      } else {
-        return null;
-      }
-    }
-  }
-  return node;
-}
-
-
-// Returns true if [template] is a subset of [map].
-bool matchMaps(Map template, Map msg) {
-  bool isMatch = true;
-  template.forEach((k, v) {
-    if (msg.containsKey(k)) {
-      var receivedValue = msg[k];
-      if ((v is Map) && (receivedValue is Map)) {
-        if (!matchMaps(v, receivedValue)) isMatch = false;
-      } else if (v == null) {
-        // null in the template matches everything.
-      } else if (v != receivedValue) {
-        isMatch = false;
-      }
-    } else {
-      isMatch = false;
-    }
-  });
-  return isMatch;
-}
-
-
-class Command {
-  var template;
-
-  void send(Debugger debugger) {
-    debugger.sendMessage(template);
-  }
-
-  void matchResponse(Debugger debugger) {
-    Map response = debugger.currentMessage;
-    var id = template["id"];
-    assert(id != null && id >= 0);
-    if (response["id"] != id) {
-      debugger.error("Error: expected messaged id $id but got ${response["id"]}.");
-    }
-  }
-}
-
-class GetLineTableCmd extends Command {
-  GetLineTableCmd() {
-    template = {"id": 0,
-                "command": "getLineNumberTable",
-                "params": {"isolateId": 0, "libraryId": 0, "url": ""}};
-  }
-
-  void send(Debugger debugger) {
-    assert(debugger.scriptUrl != null);
-    template["params"]["url"] = debugger.scriptUrl;
-    template["params"]["libraryId"] = debugger.libraryId;
-    debugger.sendMessage(template);
-  }
-
-  void matchResponse(Debugger debugger) {
-    super.matchResponse(debugger);
-    List<List<int>> table = getJsonValue(debugger.currentMessage, "result:lines");
-    debugger.tokenToLine = {};
-    for (var line in table) {
-      // Each entry begins with a line number...
-      var lineNumber = line[0];
-      for (var pos = 1; pos < line.length; pos += 2) {
-        // ...and is followed by (token offset, col number) pairs.
-        var tokenOffset = line[pos];
-        debugger.tokenToLine[tokenOffset] = lineNumber;
-      }
-    }
-  }
-}
-
-
-class LineMatcher extends Command {
-  int expectedLineNumber;
-
-  LineMatcher(this.expectedLineNumber) {
-    template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}};
-  }
-
-  void matchResponse(Debugger debugger) {
-    assert(debugger.tokenToLine != null);
-    super.matchResponse(debugger);
-    var msg = debugger.currentMessage;
-    List frames = getJsonValue(msg, "result:callFrames");
-    assert(frames != null);
-    var tokenOffset = frames[0]["location"]["tokenOffset"];
-    assert(tokenOffset != null);
-    var lineNumber = debugger.tokenToLine[tokenOffset];
-    assert(lineNumber != null);
-    if (expectedLineNumber != lineNumber) {
-      debugger.error("Error: expected pause at line $expectedLineNumber "
-                     "but reported line is $lineNumber.");
-      return;
-    }
-    print("Matched line number $lineNumber");
-  }
-}
-
-MatchLine(lineNumber) {
-  return new LineMatcher(lineNumber);
-}
-
-
-class FrameMatcher extends Command {
-  int frameIndex;
-  List<String> functionNames;
-  bool exactMatch;
-
-  FrameMatcher(this.frameIndex, this.functionNames, this.exactMatch) {
-    template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}};
-  }
-
-  void matchResponse(Debugger debugger) {
-    super.matchResponse(debugger);
-    var msg = debugger.currentMessage;
-    List frames = getJsonValue(msg, "result:callFrames");
-    assert(frames != null);
-    if (debugger.scriptUrl == null) {
-      var name = frames[0]["functionName"];
-      if (name == "main") {
-        // Extract script url of debugged script.
-        debugger.scriptUrl = frames[0]["location"]["url"];
-        assert(debugger.scriptUrl != null);
-        debugger.libraryId = frames[0]["location"]["libraryId"];
-        assert(debugger.libraryId != null);
-      }
-    }
-    if (frames.length < functionNames.length) {
-      debugger.error("Error: stack trace not long enough "
-                     "to match ${functionNames.length} frames");
-      return;
-    }
-    for (int i = 0; i < functionNames.length; i++) {
-      var idx = i + frameIndex;
-      var name = frames[idx]["functionName"];
-      assert(name != null);
-      bool isMatch = exactMatch ? name == functionNames[i]
-                                : name.contains(functionNames[i]);
-      if (!isMatch) {
-        debugger.error("Error: call frame $idx: "
-          "expected function name '${functionNames[i]}' but found '$name'");
-        return;
-      }
-    }
-    print("Matched frames: $functionNames");
-  }
-}
-
-
-MatchFrame(int frameIndex, String functionName, {exactMatch: false}) {
-  return new FrameMatcher(frameIndex, [functionName], exactMatch);
-}
-
-MatchFrames(List<String> functionNames, {exactMatch: false}) {
-  return new FrameMatcher(0, functionNames, exactMatch);
-}
-
-
-class LocalsMatcher extends Command {
-  Map locals = {};
-
-  LocalsMatcher(this.locals) {
-    template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}};
-  }
-
-  void matchResponse(Debugger debugger) {
-    super.matchResponse(debugger);
-
-    List frames = getJsonValue(debugger.currentMessage, "result:callFrames");
-    assert(frames != null);
-
-    String functionName = frames[0]['functionName'];
-    List localsList = frames[0]['locals'];
-    Map reportedLocals = {};
-    localsList.forEach((local) => reportedLocals[local['name']] = local['value']);
-    for (String key in locals.keys) {
-      if (reportedLocals[key] == null) {
-        debugger.error("Error in $functionName(): no value reported for local "
-            "variable $key");
-        return;
-      }
-      String expected = locals[key];
-      String actual = reportedLocals[key]['text'];
-      if (expected != actual) {
-        debugger.error("Error in $functionName(): got '$actual' for local "
-            "variable $key, but expected '$expected'");
-        return;
-      }
-    }
-    print("Matched locals ${locals.keys}");
-  }
-}
-
-
-MatchLocals(Map localValues) {
-  return new LocalsMatcher(localValues);
-}
-
-
-// Used to check if local variables are visible.
-class AssertLocalsNotVisibleMatcher extends Command {
-  List<String> locals;
-  int frame_index;
-
-  AssertLocalsNotVisibleMatcher(this.locals, this.frame_index) {
-    template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}};
-  }
-
-  void matchResponse(Debugger debugger) {
-    super.matchResponse(debugger);
-
-    List frames = getJsonValue(debugger.currentMessage, "result:callFrames");
-    assert(frames != null);
-
-    String functionName = frames[frame_index]['functionName'];
-    List localsList = frames[frame_index]['locals'];
-    Map reportedLocals = {};
-    localsList.forEach((local) => reportedLocals[local['name']] = local['value']);
-    for (String key in locals) {
-      if (reportedLocals[key] != null) {
-        debugger.error("Error in $functionName(): local variable $key not "
-                       "expected in scope (reported value "
-                       "${reportedLocals[key]['text']})");
-        return;
-      }
-    }
-    print("Matched locals $locals");
-  }
-}
-
-
-AssertLocalsNotVisible(List<String> locals, [int frame_index = 0]) {
-  return new AssertLocalsNotVisibleMatcher(locals, frame_index);
-}
-
-
-class EventMatcher {
-  String eventName;
-  Map params;
-
-  EventMatcher(this.eventName, this.params);
-
-  void matchEvent(Debugger debugger) {
-    for (Event event in debugger.events) {
-      if (event.name == eventName) {
-        if (params == null || matchMaps(params, event.params)) {
-          // Remove the matched event, so we don't match against it in the future.
-          debugger.events.remove(event);
-          return;
-        }
-      }
-    }
-
-    String msg = params == null ? '' : params.toString();
-    debugger.error("Error: could not match event $eventName $msg");
-  }
-}
-
-
-ExpectEvent(String eventName, [Map params]) {
-  return new EventMatcher(eventName, params);
-}
-
-
-class RunCommand extends Command {
-  RunCommand.resume() {
-    template = {"id": 0, "command": "resume", "params": {"isolateId": 0}};
-  }
-  RunCommand.step() {
-    template = {"id": 0, "command": "stepOver", "params": {"isolateId": 0}};
-  }
-  RunCommand.stepInto() {
-    template = {"id": 0, "command": "stepInto", "params": {"isolateId": 0}};
-  }
-  RunCommand.stepOut() {
-    template = {"id": 0, "command": "stepOut", "params": {"isolateId": 0}};
-  }
-  void send(Debugger debugger) {
-    debugger.sendMessage(template);
-    debugger.isPaused = false;
-  }
-  void matchResponse(Debugger debugger) {
-    super.matchResponse(debugger);
-    print("Command: ${template['command']}");
-  }
-}
-
-
-Resume() => new RunCommand.resume();
-Step() => new RunCommand.step();
-StepInto() => new RunCommand.stepInto();
-StepOut() => new RunCommand.stepOut();
-
-class SetBreakpointCommand extends Command {
-  int line;
-  String url;
-  SetBreakpointCommand(this.line, this.url) {
-    template = {"id": 0,
-                "command": "setBreakpoint",
-                "params": { "isolateId": 0,
-                            "url": null,
-                            "line": null }};
-  }
-
-  void send(Debugger debugger) {
-    assert(debugger.scriptUrl != null);
-    if (url == null) {
-      url = debugger.scriptUrl;
-    }
-    template["params"]["url"] = url;
-    template["params"]["line"] = line;
-    debugger.sendMessage(template);
-  }
-
-  void matchResponse(Debugger debugger) {
-    super.matchResponse(debugger);
-    print("Set breakpoint at line $line in $url");
-  }
-}
-
-SetBreakpoint(int line, {String url}) => new SetBreakpointCommand(line, url);
-
-class Event {
-  String name;
-  Map params;
-
-  Event(Map json) {
-    name = json['event'];
-    params = json['params'];
-  }
-}
-
-
-// A debug script is a list of Command objects.
-class DebugScript {
-  List entries;
-  DebugScript(List scriptEntries) {
-    entries = new List.from(scriptEntries.reversed);
-    entries.add(new GetLineTableCmd());
-    entries.add(MatchFrame(0, "main"));
-  }
-  bool get isEmpty => entries.isEmpty;
-  bool get isNextEventMatcher => !isEmpty && currentEntry is EventMatcher;
-  get currentEntry => entries.last;
-  advance() => entries.removeLast();
-  add(entry) => entries.add(entry);
-}
-
-
-class Debugger {
-  // Debug target process properties.
-  Process targetProcess;
-  Socket socket;
-  JsonBuffer responses = new JsonBuffer();
-
-  DebugScript script;
-  int seqNr = 0;  // Sequence number of next debugger command message.
-  Command lastCommand = null;  // Most recent command sent to target.
-  List<String> errors = new List();
-  List<Event> events = new List();
-  bool cleanupDone = false;
-
-  // Data collected from debug target.
-  Map currentMessage = null;  // Currently handled message sent by target.
-  String scriptUrl = null;
-  int libraryId = null;
-  Map<int,int> tokenToLine = null;
-  bool shutdownEventSeen = false;
-  int isolateId = 0;
-  bool isPaused = false;
-
-  Debugger(this.targetProcess, this.script) {
-    var stdoutStringStream = targetProcess.stdout
-        .transform(UTF8.decoder)
-        .transform(new LineSplitter());
-    stdoutStringStream.listen((line) {
-      print("TARG: $line");
-      if (line.startsWith("Debugger listening")) {
-        RegExp portExpr = new RegExp(r"\d+");
-        var port = portExpr.stringMatch(line);
-        print("Debug target found listening at port '$port'");
-        openConnection(int.parse(port));
-      }
-    });
-
-    var stderrStringStream = targetProcess.stderr
-        .transform(UTF8.decoder)
-        .transform(new LineSplitter());
-    stderrStringStream.listen((line) {
-      print("TARG: $line");
-    });
-  }
-
-  // Handle debugger events, updating the debugger state.
-  void handleEvent(Map<String,dynamic> msg) {
-    events.add(new Event(msg));
-
-    if (msg["event"] == "isolate") {
-      if (msg["params"]["reason"] == "created") {
-        isolateId = msg["params"]["id"];
-        assert(isolateId != null);
-        print("Debuggee isolate id $isolateId created.");
-      } else if (msg["params"]["reason"] == "shutdown") {
-        print("Debuggee isolate id ${msg["params"]["id"]} shut down.");
-        shutdownEventSeen = true;
-        if (!script.isEmpty) {
-          error("Error: premature isolate shutdown event seen.");
-          error("Next expected event: ${script.currentEntry}");
-        }
-      }
-    } else if (msg["event"] == "breakpointResolved") {
-      var bpId = msg["params"]["breakpointId"];
-      assert(bpId != null);
-      var isolateId = msg["params"]["isolateId"];
-      assert(isolateId != null);
-      var location = msg["params"]["location"];
-      assert(location != null);
-      print("Isolate $isolateId: breakpoint $bpId resolved"
-            " at location $location");
-      // We may want to maintain a table of breakpoints in the future.
-    } else if (msg["event"] == "paused") {
-      isPaused = true;
-    } else {
-      error("Error: unknown debugger event received");
-    }
-  }
-
-  // Handle one JSON message object and match it to the
-  // expected events and responses in the debugging script.
-  void handleMessage(Map<String,dynamic> receivedMsg) {
-    currentMessage = receivedMsg;
-    if (receivedMsg["event"] != null) {
-      handleEvent(receivedMsg);
-      if (errorsDetected) {
-        error("Error while handling debugger event");
-        error("Event received from debug target: $receivedMsg");
-      }
-    } else if (receivedMsg["id"] != null) {
-      // This is a response to the last command we sent.
-      assert(lastCommand != null);
-      lastCommand.matchResponse(this);
-      lastCommand = null;
-      if (errorsDetected) {
-        error("Error while matching response to debugger command");
-        error("Response received from debug target: $receivedMsg");
-      }
-    }
-  }
-
-  // Send next debugger command in the script, if a response
-  // from the last command has been received and processed.
-  void sendNextCommand() {
-    while (script.isNextEventMatcher) {
-      EventMatcher matcher = script.currentEntry;
-      script.advance();
-      matcher.matchEvent(this);
-    }
-
-    if (lastCommand == null) {
-      if (script.currentEntry is Command) {
-        script.currentEntry.send(this);
-        lastCommand = script.currentEntry;
-        seqNr++;
-        script.advance();
-      }
-    }
-  }
-
-  // Handle data received over the wire from the debug target
-  // process. Split input from JSON wire format into individual
-  // message objects (maps).
-  void handleMessages() {
-    var msg = responses.getNextMessage();
-    while (msg != null) {
-      if (verboseWire) print("RECV: $msg");
-      if (responses.haveGarbage()) {
-        error("Error: leftover text after message: '${responses.buffer}'");
-        error("Previous message may be malformed, was: '$msg'");
-        cleanup();
-        return;
-      }
-      var msgObj = JSON.decode(msg);
-      handleMessage(msgObj);
-      if (errorsDetected) {
-        error("Error while handling script entry");
-        error("Message received from debug target: $msg");
-        cleanup();
-        return;
-      }
-      if (shutdownEventSeen) {
-        cleanup();
-        return;
-      }
-      if (isPaused) sendNextCommand();
-      msg = responses.getNextMessage();
-    }
-  }
-
-  // Send a debugger command to the target VM.
-  void sendMessage(Map<String,dynamic> msg) {
-    if (msg["id"] != null) {
-      msg["id"] = seqNr;
-    }
-    if (msg["params"] != null && msg["params"]["isolateId"] != null) {
-      msg["params"]["isolateId"] = isolateId;
-    }
-    String jsonMsg = JSON.encode(msg);
-    if (verboseWire) print("SEND: $jsonMsg");
-    socket.write(jsonMsg);
-  }
-
-  bool get errorsDetected => errors.length > 0;
-
-  // Record error message.
-  void error(String s) {
-    errors.add(s);
-  }
-
-  void openConnection(int portNumber) {
-    Socket.connect("127.0.0.1", portNumber).then((s) {
-        s.setOption(SocketOption.TCP_NODELAY, true);
-        this.socket = s;
-        var stringStream = socket.transform(UTF8.decoder);
-        stringStream.listen((str) {
-            try {
-              responses.append(str);
-              handleMessages();
-            } catch(e, trace) {
-              print("Unexpected exception:\n$e\n$trace");
-              cleanup();
-            }
-          },
-          onDone: () {
-            print("Connection closed by debug target");
-            cleanup();
-          },
-          onError: (e, trace) {
-            print("Error '$e' detected in input stream from debug target");
-            if (trace != null) print("StackTrace: $trace");
-            cleanup();
-          });
-      },
-      onError: (e, trace) {
-        String msg = "Error while connecting to debugee: $e";
-        if (trace != null) msg += "\nStackTrace: $trace";
-        error(msg);
-        cleanup();
-      });
-  }
-
-  void cleanup() {
-    if (cleanupDone) return;
-    if (socket != null) {
-      socket.close().catchError((error) {
-        // Print this directly in addition to adding it to the
-        // error message queue, in case the error message queue
-        // gets printed before this error handler is called.
-        print("Error occurred while closing socket: $error");
-        error("Error while closing socket: $error");
-      });
-    }
-    var targetPid = targetProcess.pid;
-    if (errorsDetected || !shutdownEventSeen) {
-      print("Sending kill signal to process $targetPid...");
-      targetProcess.kill();
-    }
-    // If the process was already dead, exitCode is
-    // available and we call exit() in the next event loop cycle.
-    // Otherwise this will wait for the process to exit.
-    targetProcess.exitCode.then((exitCode) {
-      print("process $targetPid terminated with exit code $exitCode.");
-      if (exitCode != 0) {
-        error("Error: target process died with exit code $exitCode");
-      }
-      if (errorsDetected) {
-        print("\n===== Errors detected: =====");
-        for (int i = 0; i < errors.length; i++) print(errors[i]);
-        print("============================\n");
-      }
-      exit(errors.length);
-    });
-    cleanupDone = true;
-  }
-}
-
-
-bool RunScript(List script, List<String> arguments) {
-  if (arguments.contains("--debuggee")) {
-    return false;
-  }
-  verboseWire = arguments.contains("--wire");
-
-  // Port number 0 means debug target picks a free port dynamically.
-  var targetOpts = [ "--debug:0" ];
-  if (arguments.contains("--verbose")) {
-    targetOpts.add("--verbose_debug");
-  }
-  targetOpts.add(Platform.script.toFilePath());
-  targetOpts.add("--debuggee");
-  print('args: ${targetOpts.join(" ")}');
-
-  Process.start(Platform.executable, targetOpts).then((Process process) {
-    print("Debug target process started, pid ${process.pid}.");
-    process.stdin.close();
-    var debugger = new Debugger(process, new DebugScript(script));
-  });
-  return true;
-}
diff --git a/tests/standalone/debugger/deferred_code_lib.dart b/tests/standalone/debugger/deferred_code_lib.dart
deleted file mode 100644
index 4506217..0000000
--- a/tests/standalone/debugger/deferred_code_lib.dart
+++ /dev/null
@@ -1,11 +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 lazyCode;
-
-void stopTheBuck() {
-  // Line number of print call must match breakpoint request
-  // in deferred_code_test.dart.
-  print("The debugger stops here.");
-}
diff --git a/tests/standalone/debugger/deferred_code_test.dart b/tests/standalone/debugger/deferred_code_test.dart
deleted file mode 100644
index c4578ab..0000000
--- a/tests/standalone/debugger/deferred_code_test.dart
+++ /dev/null
@@ -1,50 +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.
-
-// Test to verify that a breakpoint can be set in code that is not yet
-// loaded, i.e. in a deferred library.
-//
-// This test forks a second vm process that runs this dart script as
-// a debug target.
-// Run this test with option --wire to see the json messages sent
-// between the processes.
-// Run this test with option --verbose to see the stdout and stderr output
-// of the debug target process.
-
-import "debug_lib.dart";
-import "deferred_code_lib.dart" deferred as D;
-
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  var loaded = false;
-  print("Hello from debuggee");
-  D.loadLibrary().then((_) {
-    loaded = true;
-    print("Done loading deferred library");
-    D.stopTheBuck();
-  });
-  print("main terminates");
-}
-
-
-// Expected debugger events and commands.
-var testScript = [
-  MatchFrame(0, "main"),  // Top frame in trace is function "main".
-  SetBreakpoint(22),  // Breakpoint just before call to loadLibrary().
-  Resume(),
-  // Set BP in deferred library code before the loadLibrary() call is executed.
-  MatchFrame(0, "main"),
-  MatchLine(22),
-  MatchLocals({"loaded": "false"}),
-  SetBreakpoint(10, url: "deferred_code_lib.dart"),
-  // Regression test: we used to have a bug that hung the debugger when
-  // processing latent brakepoints for urls that have no match.
-  // The BP below will not match any loaded file.
-  SetBreakpoint(10, url: "non_existing_file.dart"),
-  Resume(),
-  MatchFrame(0, "stopTheBuck"),  // Expect to be stopped in deferred library code.
-  // MatchLine(10), // Line matching only works for the main script.
-  Resume(),
-];
diff --git a/tests/standalone/debugger/local_function_test.dart b/tests/standalone/debugger/local_function_test.dart
deleted file mode 100644
index 98df8fe..0000000
--- a/tests/standalone/debugger/local_function_test.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test forks a second vm process that runs this dart script as
-// a debug target.
-// Run this test with option --wire to see the json messages sent
-// between the processes.
-// Run this test with option --verbose to see the stdout and stderr output
-// of the debug target process.
-
-import "debug_lib.dart";
-
-// Check that if a breakpoint is requested on the line containing the
-// one-liner with a local function below, the breakpoint gets set in
-// the outer function.
-foo(x) => (n) => x * n;  // Breakpoint 1 on this line.
-
-// Check that if a breakpoint is requested on the line "return n*x"
-// below, the breakpoint is set in the local function (closure).
-bar(x) {
-  return (n) {
-    return n * x;  // Breakpoint 2 on this line.
-  };
-}
-
-// Check that setting a breakpoint works in the case where the
-// class has not been parsed yet.
-// No reference to class C must appear in main(), so that the class is not
-// yet parsed when the breakpoint in the closure nested in the constructor
-// is set.
-class C {
-  var closure;
-  C() {
-    closure = () {
-      var z = 10;  // Breakpoint 3 on this line.
-      z = z * 2;
-      return z;
-    };
-  }
-}
-
-checkBpInLazilyParsedClass() {
-  var c = new C();
-  c.closure(); // Expected to hit breakpoint.
-}
-
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  print("Hello from debuggee");
-  var f = foo(10);  // Hits breakpoint.
-  print(f(5));
-  var b = bar(10);
-  print(b(10)); // Hits breakpoint.
-  checkBpInLazilyParsedClass();
-}
-
-// Expected debugger events and commands.
-var testScript = [
-  MatchFrame(0, "main"),  // Top frame in trace is function "main".
-  SetBreakpoint(17),      // Breakpoint 1 in function foo.
-  SetBreakpoint(23),      // Breakpoint 2 in local function inside bar.
-  SetBreakpoint(36),      // Breakpoint 3 in local function inside constructor C.
-  Resume(),
-  MatchFrames(["foo", "main"]),
-  Resume(),
-  MatchFrames(["<anonymous closure>", "main"]),
-  Resume(),
-  MatchFrames(["C.<anonymous closure>", "checkBpInLazilyParsedClass"]),
-  Resume(),
-];
diff --git a/tests/standalone/debugger/local_variables_test.dart b/tests/standalone/debugger/local_variables_test.dart
deleted file mode 100644
index b7871d4..0000000
--- a/tests/standalone/debugger/local_variables_test.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test forks a second vm process that runs this dart script as
-// a debug target.
-// Run this test with option --wire to see the json messages sent
-// between the processes.
-// Run this test with option --verbose to see the stdout and stderr output
-// of the debug target process.
-
-import "debug_lib.dart";
-
-foo() {
-  var y;  // Breakpoint
-  return 123;
-}
-
-test() {
-  if (true) {
-    var temp = 777;
-  }
-  if (true) {
-    var a = foo();  // Breakpoint
-    if (true) {
-      var s = 456;
-      print(s);
-    }
-  }
-}
-
-test_no_init() {
-  if (true) {
-    var temp = 777;
-  }
-  if (true) {
-    var a;  // Breakpoint
-    if (true) {
-      var s = 456;
-      print(s);
-    }
-  }
-}
-
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  print("Hello from debuggee");
-  test();
-  test_no_init();
-  print("Hello again");
-}
-
-
-// Expected debugger events and commands.
-var testScript = [
-  MatchFrame(0, "main"),  // Top frame in trace is function "main".
-  Step(),
-  MatchFrame(0, "main"),  // Should still be in "main".
-  SetBreakpoint(15),  // Set breakpoint in function foo.
-  SetBreakpoint(24),  // Set breakpoint in function test.
-  SetBreakpoint(37),  // Set breakpoint in function test_no_init.
-  Resume(),
-  MatchFrames(["test", "main"]),
-  AssertLocalsNotVisible(["a"]),  // Here, a is not in scope yet.
-  Resume(),
-  MatchFrames(["foo", "test", "main"]),
-  AssertLocalsNotVisible(["a"], 1),  // In the caller, a is not in scope.
-  Step(),
-  MatchLocals({"y": "null"}),  // Expect y initialized to null.
-  Resume(),
-  MatchFrames(["test_no_init", "main"]),
-  AssertLocalsNotVisible(["a"]),  // a is not in scope.
-  Step(),
-  MatchLocals({"a": "null"}),
-  Resume()
-];
diff --git a/tests/standalone/debugger/mixin_closure_debugger_test.dart b/tests/standalone/debugger/mixin_closure_debugger_test.dart
deleted file mode 100644
index 5e6fd5e..0000000
--- a/tests/standalone/debugger/mixin_closure_debugger_test.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test forks a second vm process that runs this dart script as
-// a debug target.
-// Run this test with option --wire to see the json messages sent
-// between the processes.
-// Run this test with option --verbose to see the stdout and stderr output
-// of the debug target process.
-
-// This test checks that a breakpoint can be set and is hit in a closure
-// inside a mixin function. Regression test for issue 15325.
-
-import "debug_lib.dart";
-
-class S { }
-
-class M {
-  m()  {
-    var sum = 0;
-    [1,2,3].forEach((e) {
-      sum += e;  // Breakpoint here.
-    });
-    return sum;
-  }
-}
-
-class A = S with M;
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  var a = new A();
-  print(a.m());
-}
-
-// Expected debugger events and commands.
-var testScript = [
-  MatchFrame(0, "main"),  // Top frame in trace is function "main".
-  SetBreakpoint(23),      // Set breakpoint inside the forEach closure.
-  Resume(),
-  MatchFrames(["S&M.<anonymous closure>", "forEach", "S&M.m"],
-              exactMatch: false),  // First iteration.
-  MatchLocals({"e": "1"}),
-  Resume(),
-  MatchFrames(["S&M.<anonymous closure>", "forEach", "S&M.m"],
-              exactMatch: false),  // Second iteration.
-  MatchLocals({"e": "2"}),
-  Resume(),
-  MatchFrames(["S&M.<anonymous closure>", "forEach", "S&M.m"],
-              exactMatch: false),  // Third iteration.
-  MatchLocals({"e": "3"}),
-  Resume(),
-];
diff --git a/tests/standalone/debugger/nosuchmethod_debugger_test.dart b/tests/standalone/debugger/nosuchmethod_debugger_test.dart
deleted file mode 100644
index 10b6855..0000000
--- a/tests/standalone/debugger/nosuchmethod_debugger_test.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test forks a second vm process that runs this dart script as
-// a debug target.
-// Run this test with option --wire to see the json messages sent
-// between the processes.
-// Run this test with option --verbose to see the stdout and stderr output
-// of the debug target process.
-
-import "debug_lib.dart";
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  print("Hello from debuggee");
-  var a = new A();
-  for (var i = 0; i < 2; ++i) {
-    a.foo(i);
-  }
-}
-
-class A {
-  noSuchMethod(m) {
-    print(m.positionalArguments[0]);
-  }
-}
-
-// Expected debugger events and commands.
-var testScript = [
-  MatchFrame(0, "main"),  // Top frame in trace is function "main".
-  SetBreakpoint(19),      // Set breakpoint at a.foo(i).
-  Resume(),
-  MatchFrame(0, "main"),  // Should be at closure call.
-  MatchLocals({"i": "0"}),
-  StepInto(),
-  StepInto(),
-  MatchFrames(["A.noSuchMethod", "main"]),
-  StepOut(),
-  MatchFrame(0, "main"),  // Back in main.
-  Resume(),
-  MatchFrame(0, "main"),  // Still in main back at a.foo(i).
-  MatchLocals({"i": "1"}),
-  StepInto(),
-  StepInto(),
-  MatchFrames(["A.noSuchMethod", "main"]),  // Second invocation.
-  Resume()
-];
diff --git a/tests/standalone/debugger/step_inout_test.dart b/tests/standalone/debugger/step_inout_test.dart
deleted file mode 100644
index 421c212..0000000
--- a/tests/standalone/debugger/step_inout_test.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "debug_lib.dart";
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-
-  foo('foo1');
-  foo('foo2');
-  foo('foo3');
-}
-
-void foo(String str) {
-  print(str);
-}
-
-/**
- * Set a breakpoint, resume to that breakpoint, step into a method, step out,
- * step over the next line, and resume execution.
- */
-var testScript = [
-  MatchFrames(["main"]),
-  SetBreakpoint(10),
-  Resume(),
-  MatchFrames(["main"]),
-  StepInto(),
-  MatchFrames(["foo", "main"]),
-  StepOut(),
-  MatchFrames(["main"]),
-  Step(),
-  MatchFrames(["main"]),
-  Resume(),
-];
diff --git a/tests/standalone/debugger/stepping_test.dart b/tests/standalone/debugger/stepping_test.dart
deleted file mode 100644
index d8f37d2..0000000
--- a/tests/standalone/debugger/stepping_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "debug_lib.dart";
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-
-  bar();
-}
-
-void bar() {
-  print('foo1');
-  print('foo2');
-  print('foo3');
-}
-
-/**
- * Set a breakpoint, resume to that breakpoint, step once, and verify that the
- * step worked.
- */
-var testScript = [
-  MatchFrames(["main"]),
-  SetBreakpoint(15),
-  Resume(),
-  MatchFrames(["bar"]),
-  Step(),
-  MatchFrames(["bar"]),
-  Resume(),
-];
diff --git a/tests/standalone/debugger/tostring_throws_test.dart b/tests/standalone/debugger/tostring_throws_test.dart
deleted file mode 100644
index 7214bb2..0000000
--- a/tests/standalone/debugger/tostring_throws_test.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "debug_lib.dart";
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-
-  Foo foo = new Foo();
-
-  print("Hello from debuggee");
-}
-
-class Foo {
-  String toString() {
-    throw 'I always throw';
-  }
-}
-
-// Make sure Foo.toString() does not get called.
-var testScript = [
-  MatchFrame(0, "main"),
-  SetBreakpoint(12),
-  Resume(),
-  MatchFrame(0, "main"),
-  MatchLocals({"foo": "object of type Foo"}),
-  Resume(),
-];
diff --git a/tests/standalone/io/create_sample_certificates.sh b/tests/standalone/io/create_sample_certificates.sh
index 7ab6f75..cabe747 100755
--- a/tests/standalone/io/create_sample_certificates.sh
+++ b/tests/standalone/io/create_sample_certificates.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index 6dbdcd4..1c84cd5 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -296,6 +296,8 @@
     "  attachment  ;filename=genome.jpeg  ;"
     "modification-date = \"Wed, 12 February 1997 16:29:51 -0500\""  );
   check(headerValue, "attachment", parameters);
+  headerValue = HeaderValue.parse("xxx; aaa; bbb; ccc");
+  check(headerValue, "xxx", {"aaa": null, "bbb": null, "ccc": null});
 }
 
 void testContentType() {
diff --git a/tests/standalone/io/platform_test.dart b/tests/standalone/io/platform_test.dart
index f074750..308d5d0 100644
--- a/tests/standalone/io/platform_test.dart
+++ b/tests/standalone/io/platform_test.dart
@@ -48,11 +48,20 @@
   Expect.isTrue(Platform.script.toFilePath().startsWith(oldDir.path));
   // Restore dir.
   Directory.current = oldDir;
-  Directory packageRoot = new Directory(Platform.packageRoot);
+  var pkgRootString = Platform.packageRoot;
+  Directory packageRoot = new Directory.fromUri(Uri.parse(pkgRootString));
   Expect.isTrue(packageRoot.existsSync());
   Expect.isTrue(new Directory("${packageRoot.path}/expect").existsSync());
   Expect.isTrue(Platform.executableArguments.any(
-      (arg) => arg.contains(Platform.packageRoot)));
+      (arg) {
+        if (!arg.startsWith("--package-root=")) {
+          return false;
+        }
+        // Cut out the '--package-root=' prefix.
+        arg = arg.substring(15);
+        return pkgRootString.contains(arg);
+      }
+  ));
 }
 
 void f(reply) {
diff --git a/tests/standalone/io/web_socket_compression_test.dart b/tests/standalone/io/web_socket_compression_test.dart
new file mode 100644
index 0000000..912b855
--- /dev/null
+++ b/tests/standalone/io/web_socket_compression_test.dart
@@ -0,0 +1,323 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=
+// VMOptions=--short_socket_read
+// VMOptions=--short_socket_write
+// VMOptions=--short_socket_read --short_socket_write
+
+import "dart:async";
+import "dart:convert";
+import "dart:io";
+import "dart:typed_data";
+import "dart:math";
+
+import "package:async_helper/async_helper.dart";
+import "package:crypto/crypto.dart";
+import "package:expect/expect.dart";
+import "package:path/path.dart";
+
+const WEB_SOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+const String HOST_NAME = 'localhost';
+
+String localFile(path) => Platform.script.resolve(path).toFilePath();
+
+SecurityContext serverContext = new SecurityContext()
+  ..useCertificateChain(localFile('certificates/server_chain.pem'))
+  ..usePrivateKey(localFile('certificates/server_key.pem'),
+                  password: 'dartdart');
+
+class SecurityConfiguration {
+  final bool secure;
+
+  SecurityConfiguration({bool this.secure});
+
+  Future<HttpServer> createServer({int backlog: 0}) =>
+      secure ? HttpServer.bindSecure(HOST_NAME,
+          0,
+          serverContext,
+          backlog: backlog)
+          : HttpServer.bind(HOST_NAME,
+          0,
+          backlog: backlog);
+
+  Future<WebSocket> createClient(int port) =>
+      // TODO(whesse): Add client context argument to WebSocket.connect
+      WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
+
+  Future<HttpClientResponse> createWebsocket(String url, String headerValue) {
+    HttpClient _httpClient = new HttpClient();
+    Uri uri = Uri.parse(url);
+
+    Random random = new Random();
+    // Generate 16 random bytes.
+    Uint8List nonceData = new Uint8List(16);
+    for (int i = 0; i < 16; i++) {
+      nonceData[i] = random.nextInt(256);
+    }
+    String nonce = CryptoUtils.bytesToBase64(nonceData);
+
+    uri = new Uri(
+        scheme: uri.scheme == "wss" ? "https" : "http",
+        userInfo: uri.userInfo,
+        host: uri.host,
+        port: uri.port,
+        path: uri.path,
+        query: uri.query,
+        fragment: uri.fragment);
+    return _httpClient.openUrl("GET", uri).then((request) {
+      if (uri.userInfo != null && !uri.userInfo.isEmpty) {
+        // If the URL contains user information use that for basic
+        // authorization.
+        String auth = CryptoUtils.bytesToBase64(UTF8.encode(uri.userInfo));
+        request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
+      }
+      // Setup the initial handshake.
+      request.headers
+        ..set(HttpHeaders.CONNECTION, "Upgrade")
+        ..set(HttpHeaders.UPGRADE, "websocket")
+        ..set("Sec-WebSocket-Key", nonce)
+        ..set("Cache-Control", "no-cache")
+        ..set("Sec-WebSocket-Version", "13")
+        ..set("Sec-WebSocket-Extensions", headerValue);
+
+      return request.close();
+    });
+  }
+
+  void testCompressionSupport({server: false,
+        client: false,
+        contextTakeover: false}) {
+    asyncStart();
+
+    var clientOptions = new CompressionOptions(
+        enabled: client,
+        serverNoContextTakeover: contextTakeover,
+        clientNoContextTakeover: contextTakeover);
+    var serverOptions = new CompressionOptions(
+        enabled: server,
+        serverNoContextTakeover: contextTakeover,
+        clientNoContextTakeover: contextTakeover);
+
+    createServer().then((server) {
+      server.listen((request) {
+        Expect.isTrue(WebSocketTransformer.isUpgradeRequest(request));
+        WebSocketTransformer.upgrade(request, compression: serverOptions)
+                            .then((webSocket) {
+            webSocket.listen((message) {
+              Expect.equals("Hello World", message);
+
+              webSocket.add(message);
+              webSocket.close();
+            });
+            webSocket.add("Hello World");
+        });
+      });
+
+      var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
+      WebSocket.connect(url, compression: clientOptions).then((websocket) {
+        var future = websocket.listen((message) {
+          Expect.equals("Hello World", message);
+        }).asFuture();
+        websocket.add("Hello World");
+        return future;
+      }).then((_) {
+        server.close();
+        asyncEnd();
+      });
+    });
+  }
+
+  void testCompressionHeaders() {
+    asyncStart();
+    createServer().then((server) {
+      server.listen((request) {
+        Expect.equals('Upgrade', request.headers.value(HttpHeaders.CONNECTION));
+        Expect.equals('websocket', request.headers.value(HttpHeaders.UPGRADE));
+
+        var key = request.headers.value('Sec-WebSocket-Key');
+        var sha1 = new SHA1()..add("$key$WEB_SOCKET_GUID".codeUnits);
+        var accept = CryptoUtils.bytesToBase64(sha1.close());
+        request.response
+            ..statusCode = HttpStatus.SWITCHING_PROTOCOLS
+            ..headers.add(HttpHeaders.CONNECTION, "Upgrade")
+            ..headers.add(HttpHeaders.UPGRADE, "websocket")
+            ..headers.add("Sec-WebSocket-Accept", accept)
+            ..headers.add("Sec-WebSocket-Extensions",
+              "permessage-deflate;"
+              // Test quoted values and space padded =
+              'server_max_window_bits="10"; client_max_window_bits = 12'
+              'client_no_context_takeover; server_no_context_takeover');
+        request.response.contentLength = 0;
+        request.response.detachSocket().then((socket) {
+          return new WebSocket.fromUpgradedSocket(socket, serverSide: true);
+        }).then((websocket) {
+          websocket.add("Hello");
+          websocket.close();
+          asyncEnd();
+        });
+      });
+
+      var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
+
+      WebSocket.connect(url).then((websocket) {
+        return websocket.listen((message) {
+          Expect.equals("Hello", message);
+          websocket.close();
+        }).asFuture();
+      }).then((_) => server.close());
+    });
+  }
+
+  void testReturnHeaders(String headerValue, String expected, {
+    CompressionOptions serverCompression: CompressionOptions.DEFAULT}) {
+    asyncStart();
+    createServer().then((server) {
+      server.listen((request) {
+        // Stuff
+        Expect.isTrue(WebSocketTransformer.isUpgradeRequest(request));
+        WebSocketTransformer.upgrade(request, compression: serverCompression)
+          .then((webSocket) {
+            webSocket.listen((message) {
+              Expect.equals("Hello World", message);
+
+              webSocket.add(message);
+              webSocket.close();
+            });
+        });
+      });
+
+      var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
+      createWebsocket(url, headerValue)
+        .then((HttpClientResponse response) {
+          Expect.equals(response.statusCode, HttpStatus.SWITCHING_PROTOCOLS);
+          print(response.headers.value('Sec-WebSocket-Extensions'));
+          Expect.equals(response.headers.value("Sec-WebSocket-Extensions"),
+            expected);
+
+          String accept = response.headers.value("Sec-WebSocket-Accept");
+          Expect.isNotNull(accept);
+
+          var protocol = response.headers.value('Sec-WebSocket-Protocol');
+          return response.detachSocket().then((socket) =>
+              new WebSocket.fromUpgradedSocket(
+                  socket, protocol: protocol, serverSide: false));
+        }).then((websocket) {
+          var future = websocket.listen((message) {
+            Expect.equals("Hello", message);
+            websocket.close();
+          }).asFuture();
+          websocket.add("Hello World");
+          return future;
+        }).then((_) {
+          server.close();
+          asyncEnd();
+        });
+    }); // End createServer
+  }
+
+  void testClientRequestHeaders(CompressionOptions compression) {
+    asyncStart();
+    createServer().then((server) {
+      server.listen((request) {
+        var extensionHeader = request.headers.value('Sec-WebSocket-Extensions');
+        var hv = HeaderValue.parse(extensionHeader);
+        Expect.equals(compression.serverNoContextTakeover,
+            hv.parameters.containsKey('server_no_context_takeover'));
+        Expect.equals(compression.clientNoContextTakeover,
+            hv.parameters.containsKey('client_no_context_takeover'));
+        Expect.equals(compression.serverMaxWindowBits?.toString(),
+            hv.parameters['server_max_window_bits']);
+        Expect.equals(compression.clientMaxWindowBits?.toString(),
+            hv.parameters['client_max_window_bits']);
+
+        WebSocketTransformer.upgrade(request).then((webSocket) {
+            webSocket.listen((message) {
+              Expect.equals('Hello World', message);
+
+              webSocket.add(message);
+              webSocket.close();
+            });
+        });
+      });
+
+      var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
+
+      WebSocket.connect(url, compression: compression).then((websocket) {
+        var future = websocket.listen((message) {
+          Expect.equals('Hello World', message);
+          websocket.close();
+        }).asFuture();
+        websocket.add('Hello World');
+        return future;
+      }).then((_) {
+        server.close();
+        asyncEnd();
+      });
+    });
+  }
+
+  void runTests() {
+    // No compression or takeover
+    testCompressionSupport();
+    // compression no takeover
+    testCompressionSupport(server: true, client: true);
+    // compression and context takeover.
+    testCompressionSupport(server: true, client: true, contextTakeover: true);
+    // Compression on client but not server. No take over
+    testCompressionSupport(client: true);
+    // Compression on server but not client.
+    testCompressionSupport(server: true);
+
+    testCompressionHeaders();
+    // Chrome headers
+    testReturnHeaders('permessage-deflate; client_max_window_bits',
+                      "permessage-deflate; client_max_window_bits=15");
+    // Firefox headers
+    testReturnHeaders('permessage-deflate',
+                      "permessage-deflate; client_max_window_bits=15");
+    // Ensure max_window_bits resize appropriately.
+    testReturnHeaders('permessage-deflate; server_max_window_bits=10',
+                      "permessage-deflate;"
+                      " server_max_window_bits=10;"
+                      " client_max_window_bits=10");
+    // Don't provider context takeover if requested but not enabled.
+    // Default is not enabled.
+    testReturnHeaders('permessage-deflate; client_max_window_bits;'
+                      'client_no_context_takeover',
+                      'permessage-deflate; client_max_window_bits=15');
+    // Enable context Takeover and provide if requested.
+    var compression = new CompressionOptions(clientNoContextTakeover: true,
+        serverNoContextTakeover: true);
+    testReturnHeaders('permessage-deflate; client_max_window_bits; '
+                      'client_no_context_takeover',
+                      'permessage-deflate; client_no_context_takeover; '
+                      'client_max_window_bits=15',
+                      serverCompression: compression);
+    // Enable context takeover and don't provide if not requested
+    compression = new CompressionOptions(clientNoContextTakeover: true,
+        serverNoContextTakeover: true);
+    testReturnHeaders('permessage-deflate; client_max_window_bits; ',
+                      'permessage-deflate; client_max_window_bits=15',
+                      serverCompression: compression);
+
+    compression = CompressionOptions.DEFAULT;
+    testClientRequestHeaders(compression);
+    compression = new CompressionOptions(clientNoContextTakeover: true,
+        serverNoContextTakeover: true);
+    testClientRequestHeaders(compression);
+    compression = new CompressionOptions(clientNoContextTakeover: true,
+        serverNoContextTakeover: true,
+        clientMaxWindowBits: 8,
+        serverMaxWindowBits: 8);
+    testClientRequestHeaders(compression);
+  }
+}
+
+main() {
+  new SecurityConfiguration(secure: false).runTests();
+  // TODO(whesse): Make WebSocket.connect() take an optional context: parameter.
+  // new SecurityConfiguration(secure: true).runTests();
+}
diff --git a/tests/standalone/io/web_socket_typed_data_test.dart b/tests/standalone/io/web_socket_typed_data_test.dart
index d65bedc..571b57d 100644
--- a/tests/standalone/io/web_socket_typed_data_test.dart
+++ b/tests/standalone/io/web_socket_typed_data_test.dart
@@ -15,13 +15,17 @@
 
 Future<HttpServer> createServer() => HttpServer.bind("127.0.0.1", 0);
 
-Future<WebSocket> createClient(int port) =>
-  WebSocket.connect('ws://127.0.0.1:$port/');
+Future<WebSocket> createClient(int port, bool compression) =>
+  compression ? WebSocket.connect('ws://127.0.0.1:$port/')
+    : WebSocket.connect('ws://127.0.0.1:$port/',
+        compression: CompressionOptions.OFF);
 
-void test(expected, testData) {
+void test(expected, testData, compression) {
   createServer().then((server) {
     var messageCount = 0;
-    server.transform(new WebSocketTransformer()).listen((webSocket) {
+    var transformer = compression ? new WebSocketTransformer()
+        : new WebSocketTransformer(compression: CompressionOptions.OFF);
+    server.transform(transformer).listen((webSocket) {
       webSocket.listen(
           (message) {
             Expect.listEquals(expected, message);
@@ -31,7 +35,7 @@
           onDone: () => Expect.equals(testData.length, messageCount));
     });
 
-    createClient(server.port).then((webSocket) {
+    createClient(server.port, compression).then((webSocket) {
       var messageCount = 0;
       webSocket.listen(
           (message) {
@@ -45,7 +49,7 @@
   });
 }
 
-testUintLists() {
+testUintLists({bool compression: false}) {
   var fillData = new List.generate(256, (index) => index);
   var testData = [
     new Uint8List(256),
@@ -55,10 +59,10 @@
     new Uint64List(256),
   ];
   testData.forEach((list) => list.setAll(0, fillData));
-  test(fillData, testData);
+  test(fillData, testData, compression);
 }
 
-testIntLists() {
+testIntLists({bool compression: false}) {
   var fillData = new List.generate(128, (index) => index);
   var testData = [
     new Int8List(128),
@@ -67,18 +71,20 @@
     new Int64List(128),
   ];
   testData.forEach((list) => list.setAll(0, fillData));
-  test(fillData, testData);
+  test(fillData, testData, compression);
 }
 
-void testOutOfRangeClient() {
+void testOutOfRangeClient({bool compression: false}) {
   createServer().then((server) {
     var messageCount = 0;
-    server.transform(new WebSocketTransformer()).listen((webSocket) {
+    var transformer = compression ? new WebSocketTransformer()
+        : new WebSocketTransformer(compression: CompressionOptions.OFF);
+    server.transform(transformer).listen((webSocket) {
       webSocket.listen((message) => Expect.fail("No message expected"));
     });
 
     Future clientError(data) {
-      return createClient(server.port).then((webSocket) {
+      return createClient(server.port, compression).then((webSocket) {
         var messageCount = 0;
         webSocket.listen((message) => Expect.fail("No message expected"));
         webSocket.add(data);
@@ -129,7 +135,7 @@
   });
 }
 
-void testOutOfRangeServer() {
+void testOutOfRangeServer({bool compression: false}) {
   var futures = [];
   var testData = [];
   var data;
@@ -175,7 +181,9 @@
 
   createServer().then((server) {
     var messageCount = 0;
-    server.transform(new WebSocketTransformer()).listen((webSocket) {
+    var transformer = compression ? new WebSocketTransformer()
+        : new WebSocketTransformer(compression: CompressionOptions.OFF);
+    server.transform(transformer).listen((webSocket) {
       webSocket.listen((message) {
         messageCount++;
         webSocket.add(testData[message[0]]);
@@ -187,7 +195,7 @@
 
     Future x(int i) {
       var completer = new Completer();
-      createClient(server.port).then((webSocket) {
+      createClient(server.port, compression).then((webSocket) {
           webSocket.listen((message) => Expect.fail("No message expected"),
                            onDone: () => completer.complete(true),
                            onError: (e) => completer.completeError(e));
@@ -204,7 +212,11 @@
 
 main() {
   testUintLists();
+  testUintLists(compression: true);
   testIntLists();
+  testIntLists(compression: true);
   testOutOfRangeClient();
+  testOutOfRangeClient(compression: true);
   // testOutOfRangeServer();
+  // testOutOfRangeServer(compression: true);
 }
diff --git a/tests/standalone/precompilation_dart2js_test.dart b/tests/standalone/precompilation_dart2js_test.dart
new file mode 100644
index 0000000..5d3900e
--- /dev/null
+++ b/tests/standalone/precompilation_dart2js_test.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test generating and running a simple precompiled snapshot of this script.
+
+import 'dart:io';
+
+main(List args) {
+  if (args.length > 0 && args[0] == "--hello") {
+    print("Hello");
+    return;
+  }
+
+  var cc, cc_flags, shared, libname;
+  if (Platform.isLinux) {
+    cc = 'gcc';
+    shared = '-shared';
+    libname = 'libprecompiled.so';
+  } else if (Platform.isMacOS) {
+    cc = 'clang';
+    shared = '-dynamiclib';
+    libname = 'libprecompiled.dylib';
+  } else {
+    print("Test only supports Linux and Mac");
+    return;
+  }
+
+  if (Platform.version.contains("x64")) {
+    cc_flags = "-m64";
+  } else if (Platform.version.contains("simarm64")) {
+    cc_flags = "-m64";
+  } else if (Platform.version.contains("simarm")) {
+    cc_flags = "-m32";
+  } else if (Platform.version.contains("simmips")) {
+    cc_flags = "-m32";
+  } else if (Platform.version.contains("arm")) {
+    cc_flags = "";
+  } else if (Platform.version.contains("mips")) {
+    cc_flags = "-EL";
+  } else {
+    print("Architecture not supported: ${Platform.version}");
+    return;
+  }
+
+  var abs_package_root = Uri.parse(Platform.packageRoot).toFilePath();
+  var dart_executable =
+      Directory.current.path + Platform.pathSeparator + Platform.executable;
+  Directory tmp;
+  try {
+    tmp = Directory.current.createTempSync("temp_precompilation_test");
+    var exec = "${dart_executable}_no_snapshot";
+    var args = ["--package-root=$abs_package_root",
+                "--gen-precompiled-snapshot",
+                "${abs_package_root}compiler/src/dart2js.dart"];
+    print("$exec ${args.join(' ')}");
+    var result = Process.runSync(exec, args, workingDirectory: tmp.path);
+    if (result.exitCode != 0) {
+      print(result.stdout);
+      print(result.stderr);
+      throw "Snapshot generation failed.";
+    }
+
+    // Check if gcc is present, and skip test if it is not.
+    try {
+      result = Process.runSync(
+          cc,
+          ["--version"],
+          workingDirectory: tmp.path);
+      if (result.exitCode != 0) {
+        throw "$cc --version failed.";
+      }
+    } catch(e) {
+      print("Skipping test because $cc is not present: $e");
+      return;
+    }
+
+    result = Process.runSync(
+        cc,
+        [shared, cc_flags, "-o", libname, "precompiled.S"],
+        workingDirectory: tmp.path);
+    if (result.exitCode != 0) {
+      print(result.stdout);
+      print(result.stderr);
+      throw "Shared library creation failed!";
+    }
+
+    var ld_library_path = new String.fromEnvironment("LD_LIBRARY_PATH");
+    ld_library_path = "${ld_library_path}:${tmp.path}";
+    exec = "${dart_executable}_precompiled";
+    args = ["--run-precompiled-snapshot", "ignored_script", "--version"];
+    print("LD_LIBRARY_PATH=$ld_library_path $exec ${args.join(' ')}");
+    result = Process.runSync(exec, args,
+       workingDirectory: tmp.path,
+       environment: {"LD_LIBRARY_PATH": ld_library_path});
+    if (result.exitCode != 0) {
+      print(result.stdout);
+      print(result.stderr);
+      throw "Precompiled binary failed.";
+    }
+    print(result.stdout);
+    if (!result.stdout.contains("Dart-to-JavaScript compiler")) {
+      throw "Precompiled binary output mismatch.";
+    }
+  } finally {
+    tmp?.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/standalone/precompilation_test.dart b/tests/standalone/precompilation_test.dart
index 047ac0d..751682e 100644
--- a/tests/standalone/precompilation_test.dart
+++ b/tests/standalone/precompilation_test.dart
@@ -86,7 +86,7 @@
     ld_library_path = "${ld_library_path}:${tmp.path}";
 
     result = Process.runSync(
-       "${dart_executable}",
+       "${dart_executable}_precompiled",
        ["--run-precompiled-snapshot", "ignored_script", "--hello"],
        workingDirectory: tmp.path,
        environment: {"LD_LIBRARY_PATH": ld_library_path});
diff --git a/tests/standalone/regress_25335_test.dart b/tests/standalone/regress_25335_test.dart
new file mode 100644
index 0000000..e4551a2
--- /dev/null
+++ b/tests/standalone/regress_25335_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Test that canonicalization inserts constants with correct representation.
+// VMOptions=--optimization-counter-threshold=10 --optimization-filter=bar
+
+import 'dart:typed_data';
+
+toSigned(v, width) {
+  var signMask = 1 << (width - 1);
+  return (v & (signMask - 1)) - (v & signMask);
+}
+
+foo(value) {
+  return value >> 32;
+}
+
+bar(td) {
+  return toSigned(foo(td[0]), 64);
+}
+
+main() {
+  toSigned(1 << 1, 32);
+  toSigned(1 << 32, 32);
+
+  var l = new Int64List(1);
+  l[0] = 0xf8f7f6f5f4f3f2f1;
+
+  for (var i = 0; i < 20; i++) {
+    bar(l);
+  }
+}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 2831a9c..590489e 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -11,21 +11,23 @@
 package/scenarios/packages_file_strange_formatting/empty_package_dir_test: Fail, OK # CompileTimeErrors intentionally
 package/scenarios/empty_packages_file/empty_packages_file_discovery_test: Fail, OK # CompileTimeErrors intentionally
 package/scenarios/empty_packages_file/empty_packages_file_option_test: Fail, OK # CompileTimeErrors intentionally
-package/scenarios/invalid/*: Fail, OK # CompileTimeErrors intentionally
+package/scenarios/invalid/invalid_package_name_test: RuntimeError, CompileTimeError # Errors intentionally
+package/scenarios/invalid/same_package_twice_test.dart: RuntimeError, CompileTimeError # Errors intentionally
+
 
 issue14236_test: Pass # Do not remove this line. It serves as a marker for Issue 14516 comment #4.
 
 javascript_compatibility_errors_test/none: Fail, OK  # Not possible to exclude or annotate with '/// none:'
 
-[ $runtime != vm && ($runtime != drt || $compiler != none)) ]
+[ ($runtime != vm && $runtime != dart_precompiled) && ($runtime != drt || $compiler != none)) ]
 no_assert_test: Fail, OK # This is testing a vm flag.
 
-[ $runtime == vm ]
+[ ($runtime == vm || $runtime == dart_precompiled) ]
 package/package_isolate_test: Fail # Issue 12474
 io/observatory_test: Fail
 package/scenarios/invalid/same_package_twice_test: Pass # Issue 24119
 
-[ $runtime == vm && $checked ]
+[ ($runtime == vm || $runtime == dart_precompiled) && $checked ]
 # These tests have type errors on purpose.
 io/process_invalid_arguments_test: Fail, OK
 io/directory_invalid_arguments_test: Fail, OK
@@ -38,20 +40,18 @@
 io/file_fuzz_test: Skip
 io/directory_fuzz_test: Skip
 
-[ $runtime == vm && $system == macos ]
+[ ($runtime == vm || $runtime == dart_precompiled) && $system == macos ]
 # This test fails with "Too many open files" on the Mac OS buildbot.
 # This is expected as MacOS by default runs with a very low number
 # of allowed open files ('ulimit -n' says something like 256).
 io/socket_many_connections_test: Skip
 
-[ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
-typed_array_test: Fail # Issue 13921
-typed_array_int64_uint64_test: Fail # Issue 13921
+[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+typed_array_test: RuntimeError, OK  # Uses Isolate.spawn
+typed_array_int64_uint64_test: RuntimeError, OK  # Uses Isolate.spawn
 typed_data_isolate_test: SkipByDesign # This test uses dart:io
 io/*: SkipByDesign # Don't run tests using dart:io in the browser
 package/*: Skip # Do not run those in Dartium.
-debugger/*: SkipByDesign # Do not run standalone debugger tests in browser.
-coverage_test: Skip
 full_coverage_test: Skip
 http_launch_test: Skip
 vmservice/*: SkipByDesign # Do not run standalone vm service tests in browser.
@@ -62,6 +62,7 @@
 out_of_memory_test: Skip
 verbose_gc_to_bmu_test: Skip
 precompilation_test: Skip # Standalone only test.
+precompilation_dart2js_test: Skip # Standalone only test.
 noopt_test: Skip # Standalone only test.
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
@@ -90,7 +91,7 @@
 package/package_isolate_test: Skip # spawnUri does not work in dart2js. See issue 3051
 package/package_test: Fail, OK # dart2js does not support 'package:foo.dart' imports
 package/package1_test: Fail, OK # dart2js does not support 'package:foo.dart' imports
-debugger/*: Skip # Do not run standalone vm debugger tests with dart2js.
+package/scenarios/invalid/*: CompileTimeError  # Negative tests expecting CompileTimeErrors.
 full_coverage_test: Skip
 left_shift_bit_and_op_test: Skip # Integers exceed dart2js precision.
 pow_test: Skip # Precision > 53 bits.
@@ -106,14 +107,24 @@
 unboxed_int_converter_test: Skip
 pair_location_remapping_test: Skip
 precompilation_test: Skip # Standalone only test.
+precompilation_dart2js_test: Skip # Standalone only test.
 noopt_test: Skip # Standalone only test.
+regress_25335_test: Skip # Int64List not supported.
 
-[ $runtime == vm && $arch == ia32]
+[ $runtime == vm && $mode == debug ]
+precompilation_dart2js_test: Pass, Slow
+
+[ $runtime == vm && $arch == ia32 ]
 precompilation_test: Skip # Not expected to pass on ia32.
+precompilation_dart2js_test: Skip # Not expected to pass on ia32.
 noopt_test: Skip # Not expected to pass on ia32.
 
-[ $runtime == vm && $arch == arm]
+[ $runtime == vm && $arch == arm ]
 precompilation_test: Skip # Issue 24427
+precompilation_dart2js_test: Skip # Issue 24427
+
+[ $runtime == vm && $arch == mips ]
+precompilation_dart2js_test: SkipSlow
 
 [ $compiler == dart2js && $jscl ]
 assert_test: RuntimeError, OK # Assumes unspecified fields on the AssertionError.
@@ -129,7 +140,7 @@
 [ $compiler == dart2js && $browser ]
 *: Skip
 
-[ $arch == simarm || $arch == simarmv5te || $arch == simmips]
+[ $arch == simarm || $arch == simarmv5te || $arch == simmips ]
 out_of_memory_test: Skip # passes on Mac, crashes on Linux
 oom_error_stacktrace_test: Skip # Fails on Linux
 
@@ -150,10 +161,10 @@
 full_coverage_test: SkipSlow # Times out. Issue 20352
 io/http_client_stays_alive_test: Skip # Timing dependent test, MIPS machine too slow.
 
-[ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $unchecked ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $unchecked ]
 assert_test: Fail # Issue 14651.
 
-[ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
 javascript_int_overflow_literal_test/01: Fail # Issue 14651.
 javascript_int_overflow_test: Fail # Issue 14651.
 
@@ -193,21 +204,68 @@
 io/skipping_dart2js_compilations_test: Fail # Issue 19551.
 verbose_gc_to_bmu_test: Skip
 io/platform_resolved_executable_test/06: RuntimeError  # Issue 23641
+io/process_sync_test: Pass, Timeout  # Issue 24596
 
 [ $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv5te && $mode == debug ]
 verified_mem_test: Skip  # Not yet implemented.
 
-[ $runtime == vm && $mode == debug && $builder_tag == asan ]
+[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $builder_tag == asan ]
 full_coverage_test: Skip  # Timeout.
 io/file_lock_test: Skip  # Timeout.
 io/test_runner_test: Skip  # Timeout.
 io/http_client_stays_alive_test: Skip  # Timeout.
 
-[ $runtime == vm ]
+[ ($runtime == vm || $runtime == dart_precompiled) ]
 # Failures in secure networking while NSS is replaced with BoringSSL
 io/https_client_certificate_test: RuntimeError # Issue 24070
 io/secure_socket_renegotiate_test: RuntimeError
 io/secure_socket_bad_data_test: RuntimeError  # An error in a secure connection just puts a READ_CLOSED on the stream, rather than signaling an error on the stream.
 
-[ $compiler == dart2js && $cps_ir ]
-priority_queue_stress_test: RuntimeError # Cannot read property 'length' of undefined
+[ ($noopt || $compiler == precompiler) ]
+map_literal_oom_test: Pass, Crash # Issue 24678
+javascript*: SkipByDesign # JS overflow flag unsupported
+io/web_socket_test: Pass, RuntimeError # Issue 24674
+assert_test: RuntimeError # Expects line and column numbers
+
+[ $runtime == dart_precompiled ]
+debugger/*: Skip
+noopt_test: Skip
+precompilation_dart2js_test: Skip
+
+full_coverage_test: RuntimeError # Platform.executable
+http_launch_test: RuntimeError # Platform.executable
+io/addlatexhash_test: RuntimeError # Platform.executable
+io/compile_all_test: Crash # Incompatible flag --compile_all
+io/file_read_special_device_test: RuntimeError # Platform.executable
+io/file_stream_test: RuntimeError # Platform.executable
+io/file_test: RuntimeError # Platform.executable
+io/http_cross_process_test: RuntimeError # Platform.executable
+io/https_unauthorized_test: RuntimeError # Platform.executable
+io/platform_resolved_executable_test: RuntimeError # Platform.resolvedExecutable
+io/skipping_dart2js_compilations_test: RuntimeError # Platform.executable
+io/snapshot_fail_test: RuntimeError # Platform.executable
+io/stdin_sync_test: RuntimeError # Platform.executable
+io/test_extension_fail_test: RuntimeError # Platform.executable
+precompilation_test: RuntimeError # Platform.executable
+standalone/io/file_read_special_device_test: RuntimeError # Platform.executable
+verbose_gc_to_bmu_test: RuntimeError # Platform.executable
+io/http_server_close_response_after_error_test: RuntimeError # Platform.executable
+io/http_client_stays_alive_test: RuntimeError # Platform.executable
+io/print_sync_test: RuntimeError # Platform.executable
+io/signals_test: RuntimeError # Platform.executable
+io/stdio_nonblocking_test: RuntimeError # Platform.executable
+io/regress_7191_test: RuntimeError # Platform.executable
+io/secure_unauthorized_test: RuntimeError # Platform.executable
+io/dart_std_io_pipe_test: RuntimeError # Platform.executable
+io/platform_test: RuntimeError # Platform.executable
+io/socket_cross_process_test: RuntimeError # Platform.executable
+io/test_runner_test: RuntimeError # Platform.executable
+io/file_lock_test: RuntimeError # Platform.executable
+io/code_collection_test: RuntimeError # Platform.executable
+io/file_lock_test: RuntimeError # Platform.executable
+io/code_collection_test: RuntimeError # Platform.executable
+io/raw_socket_cross_process_test: RuntimeError # Platform.executable
+io/test_extension_test: RuntimeError # Platform.executable
+io/regress_7679_test: RuntimeError # Platform.executable
+
+io/process_*: Skip # Most use Platform.executable
\ No newline at end of file
diff --git a/tests/standalone/typed_array_int64_uint64_test.dart b/tests/standalone/typed_array_int64_uint64_test.dart
index 3decb92..f62ab53 100644
--- a/tests/standalone/typed_array_int64_uint64_test.dart
+++ b/tests/standalone/typed_array_int64_uint64_test.dart
@@ -7,12 +7,19 @@
 // Library tag to be able to run in html test framework.
 library TypedArray;
 import "package:expect/expect.dart";
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
 import 'dart:isolate';
 import 'dart:typed_data';
 
-void main() {
-  int64_receiver();
-  uint64_receiver();
+main() {
+  test(int64_receiver);
+  test(uint64_receiver);
+}
+
+test(f) {
+  asyncStart();
+  return f().whenComplete(asyncEnd);
 }
 
 // Int64 array.
@@ -24,15 +31,17 @@
 }
 Int64List int64 = initInt64();
 
-void int64_receiver() {
+int64_receiver() {
   var response = new ReceivePort();
   var remote = Isolate.spawn(int64_sender, [int64.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(int64.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(int64[i], a[i]);
     }
     print("int64_receiver");
+    asyncEnd();
   });
 }
 
@@ -57,15 +66,17 @@
 }
 Uint64List uint64 = initUint64();
 
-void uint64_receiver() {
+uint64_receiver() {
   var response = new ReceivePort();
   var remote = Isolate.spawn(uint64_sender, [uint64.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(uint64.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(uint64[i], a[i]);
     }
     print("uint64_receiver");
+    asyncEnd();
   });
 }
 
diff --git a/tests/standalone/typed_array_test.dart b/tests/standalone/typed_array_test.dart
index 9643e13e..0c4c2b1 100644
--- a/tests/standalone/typed_array_test.dart
+++ b/tests/standalone/typed_array_test.dart
@@ -8,19 +8,25 @@
 // Library tag to be able to run in html test framework.
 library TypedArray;
 import "package:expect/expect.dart";
+import 'package:async_helper/async_helper.dart';
 import 'dart:isolate';
 import 'dart:typed_data';
 
 void main() {
-  int8_receiver();
-  uint8_receiver();
-  int16_receiver();
-  uint16_receiver();
-  int32_receiver();
-  uint32_receiver();
+  test(int8_receiver);
+  test(uint8_receiver);
+  test(int16_receiver);
+  test(uint16_receiver);
+  test(int32_receiver);
+  test(uint32_receiver);
   // int64 and uint64 in separate test.
-  float32_receiver();
-  float64_receiver();
+  test(float32_receiver);
+  test(float64_receiver);
+}
+
+test(f) {
+  asyncStart();
+  return f().whenComplete(asyncEnd);
 }
 
 // Int8 array.
@@ -32,15 +38,17 @@
 }
 Int8List int8 = initInt8();
 
-void int8_receiver() {
+int8_receiver() {
   var response = new ReceivePort();
   var remote = Isolate.spawn(int8_sender, [int8.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(int8.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(int8[i], a[i]);
     }
     print("int8_receiver");
+    asyncEnd();
   });
 }
 
@@ -65,15 +73,17 @@
 }
 Uint8List uint8 = initUint8();
 
-void uint8_receiver() {
+uint8_receiver() {
   var response = new ReceivePort();
   var remote = Isolate.spawn(uint8_sender, [uint8.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(uint8.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(uint8[i], a[i]);
     }
     print("uint8_receiver");
+    asyncEnd();
   });
 }
 
@@ -98,15 +108,17 @@
 }
 Int16List int16 = initInt16();
 
-void int16_receiver() {
+int16_receiver() {
   var response = new ReceivePort();
   var remote = Isolate.spawn(int16_sender, [int16.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(int16.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(int16[i], a[i]);
     }
     print("int16_receiver");
+    asyncEnd();
   });
 }
 
@@ -131,15 +143,17 @@
 }
 Uint16List uint16 = initUint16();
 
-void uint16_receiver() {
+uint16_receiver() {
   var response = new ReceivePort();
   var remote = Isolate.spawn(uint16_sender, [uint16.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(uint16.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(uint16[i], a[i]);
     }
     print("uint16_receiver");
+    asyncEnd();
   });
 }
 
@@ -164,15 +178,17 @@
 }
 Int32List int32 = initInt32();
 
-void int32_receiver() {
+int32_receiver() {
   var response = new ReceivePort();
   var remote = Isolate.spawn(int32_sender, [int32.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(int32.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(int32[i], a[i]);
     }
     print("int32_receiver");
+    asyncEnd();
   });
 }
 
@@ -197,15 +213,17 @@
 }
 Uint32List uint32 = initUint32();
 
-void uint32_receiver() {
+uint32_receiver() {
   var response = new ReceivePort();
   var remote = Isolate.spawn(uint32_sender, [uint32.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(uint32.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(uint32[i], a[i]);
     }
     print("uint32_receiver");
+    asyncEnd();
   });
 }
 
@@ -230,16 +248,18 @@
 }
 Float32List float32 = initFloat32();
 
-void float32_receiver() {
+float32_receiver() {
   var response = new ReceivePort();
   var remote =
       Isolate.spawn(float32_sender, [float32.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(float32.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(float32[i], a[i]);
     }
     print("float32_receiver");
+    asyncEnd();
   });
 }
 
@@ -264,16 +284,18 @@
 }
 Float64List float64 = initFloat64();
 
-void float64_receiver() {
+float64_receiver() {
   var response = new ReceivePort();
   var remote =
       Isolate.spawn(float64_sender, [float64.length, response.sendPort]);
-  response.first.then((a) {
+  asyncStart();
+  return response.first.then((a) {
     Expect.equals(float64.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(float64[i], a[i]);
     }
     print("float64_receiver");
+    asyncEnd();
   });
 }
 
diff --git a/tests/try/poi/compiler_test_case.dart b/tests/try/poi/compiler_test_case.dart
index a1df70a..711e47e 100644
--- a/tests/try/poi/compiler_test_case.dart
+++ b/tests/try/poi/compiler_test_case.dart
@@ -78,7 +78,7 @@
   /// Returns a future for the mainApp after running the compiler.
   Future<LibraryElement> compile() {
     return loadMainApp().then((LibraryElement library) {
-      return compiler.runCompiler(scriptUri).then((_) => library);
+      return compiler.run(scriptUri).then((_) => library);
     });
   }
 
diff --git a/tests/try/poi/forget_element_test.dart b/tests/try/poi/forget_element_test.dart
index 22b61ce..095b52c 100644
--- a/tests/try/poi/forget_element_test.dart
+++ b/tests/try/poi/forget_element_test.dart
@@ -260,12 +260,12 @@
   }
 
   Iterable codegenSeenClassesIn(LibraryElement library) {
-    return compiler.codegenWorld.allInstantiatedClasses.where(
+    return compiler.enqueuer.codegen.processedClasses.where(
         (e) => e.library == library);
   }
 
   Iterable resolutionSeenClassesIn(LibraryElement library) {
-    return compiler.resolverWorld.allInstantiatedClasses.where(
+    return compiler.enqueuer.resolution.processedClasses.where(
         (e) => e.library == library);
   }
 }
diff --git a/tests/try/poi/serialize_test.dart b/tests/try/poi/serialize_test.dart
index 87f4d7b..c890b8b 100644
--- a/tests/try/poi/serialize_test.dart
+++ b/tests/try/poi/serialize_test.dart
@@ -519,15 +519,15 @@
     "kind": "class"
   },
   {
+    "name": "Match",
+    "kind": "class"
+  },
+  {
     "name": "print",
     "kind": "function",
     "type": "(Object) -> void"
   },
   {
-    "name": "Match",
-    "kind": "class"
-  },
-  {
     "name": "RegExp",
     "kind": "class"
   },
@@ -582,6 +582,10 @@
   {
     "name": "Uri",
     "kind": "class"
+  },
+  {
+    "name": "UriData",
+    "kind": "class"
   }
 ];
 
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index 43a79c5..608e099 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -15,7 +15,9 @@
 import '../compiler/dart2js/mock_libraries.dart';
 
 String libProvider(Uri uri) {
-  if (uri.path.endsWith("/core.dart")) {
+  if (uri.path.endsWith(".platform")) {
+    return DEFAULT_PLATFORM_CONFIG;
+  } if (uri.path.endsWith("/core.dart")) {
     return buildLibrarySource(DEFAULT_CORE_LIBRARY);
   } else if (uri.path.endsWith('core_patch.dart')) {
     return DEFAULT_PATCH_CORE_SOURCE;
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 43fb007..bf69360 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -10,20 +10,17 @@
 recursive_import_test: Slow, Pass
 source_mirrors_test: Slow, Pass
 
-[ $compiler == none && $runtime == drt ]
-dummy_compiler_test: Skip # Issue 7233
-
 [ $compiler == dart2js && $browser ]
 *: Skip
 
-[ $compiler == none && $runtime != vm ]
+[ ($compiler == none || $compiler == precompiler) && $runtime != vm ]
 dart2js_test: SkipByDesign # Uses dart:io.
 
 
 [ $compiler == dart2js && $mode == debug ]
 dummy_compiler_test: Slow, Pass
 
-[ $compiler == none && $runtime == ContentShellOnAndroid ]
+[ ($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
 dummy_compiler_test: Pass, RuntimeError # Issue 17662
 recursive_import_test: Pass, RuntimeError # Issue 17662
 source_mirrors_test: Pass, RuntimeError # Issue 17662
@@ -32,3 +29,6 @@
 dummy_compiler_test: Crash # (switch (function.na...  continue to a labeled switch case
 recursive_import_test: Crash # (switch (function.na...  continue to a labeled switch case
 source_mirrors_test: Crash, Slow # (switch (function.na...  continue to a labeled switch case
+
+[ ($noopt || $compiler == precompiler) ]
+source_mirrors_test: SkipByDesign # Imports dart:mirrors
diff --git a/third_party/.gitignore b/third_party/.gitignore
index a55ad28..3f481f1 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -6,4 +6,9 @@
 !pkg
 !pkg_tested
 !boringssl
+!drt_resources
 !d8
+!7zip.tar.gz.sha1
+!firefox_jsshell
+!gsutil.tar.gz.sha1
+!clang.tar.gz.sha1
\ No newline at end of file
diff --git a/third_party/7zip.tar.gz.sha1 b/third_party/7zip.tar.gz.sha1
new file mode 100644
index 0000000..83e790b
--- /dev/null
+++ b/third_party/7zip.tar.gz.sha1
@@ -0,0 +1 @@
+22fe352b3c39c4281a599cf8576abef80ec44cc9
\ No newline at end of file
diff --git a/third_party/clang.tar.gz.sha1 b/third_party/clang.tar.gz.sha1
new file mode 100644
index 0000000..027ff64
--- /dev/null
+++ b/third_party/clang.tar.gz.sha1
@@ -0,0 +1 @@
+9eec86b20d62ad8d5bc6af617e91f01ae4354166
\ No newline at end of file
diff --git a/third_party/drt_resources/.gitignore b/third_party/drt_resources/.gitignore
new file mode 100644
index 0000000..7912236
--- /dev/null
+++ b/third_party/drt_resources/.gitignore
@@ -0,0 +1 @@
+AHEM____.TTF
diff --git a/third_party/drt_resources/AHEM____.TTF.sha1 b/third_party/drt_resources/AHEM____.TTF.sha1
new file mode 100644
index 0000000..bba0dbc
--- /dev/null
+++ b/third_party/drt_resources/AHEM____.TTF.sha1
@@ -0,0 +1 @@
+8cdc9e68594fbb6db8c7b4bff643ab2432b51db6
\ No newline at end of file
diff --git a/third_party/drt_resources/README.md b/third_party/drt_resources/README.md
new file mode 100644
index 0000000..c981e5b
--- /dev/null
+++ b/third_party/drt_resources/README.md
@@ -0,0 +1,6 @@
+# Content-shell resources
+
+The layout tests of content_shell (formerly called DumpRenderTree, drt)
+require a font called AHEM____.TTF on Windows. This resource is downloaded
+from cloud storage, using the hash in AHEM____.TTF.sha1, by a hook
+in the DEPS file, that is run by gclient sync or gclient runhooks.
diff --git a/third_party/firefox_jsshell/README.google b/third_party/firefox_jsshell/README.google
new file mode 100644
index 0000000..08b90f8
--- /dev/null
+++ b/third_party/firefox_jsshell/README.google
@@ -0,0 +1,12 @@
+Name: Firefox command line javascript shell.
+Short Name: js-shell
+URL: http://ftp.mozilla.org/pub/mozilla.org/firefox/candidates/38-candidates/build2/
+Version: JavaScript-C38
+Date: May 05 2015
+License: MPL, http://www.mozilla.org/MPL
+
+Description:
+This directory contains the firefox js-shell binaries for Windows, Mac and
+Linux.
+The binaries are used for testing dart code compiled to javascript.
+
diff --git a/third_party/firefox_jsshell/linux/jsshell.tar.gz.sha1 b/third_party/firefox_jsshell/linux/jsshell.tar.gz.sha1
new file mode 100644
index 0000000..8f8d719
--- /dev/null
+++ b/third_party/firefox_jsshell/linux/jsshell.tar.gz.sha1
@@ -0,0 +1 @@
+624241d790b53c24ea67997ed658f31f1ed9292d
\ No newline at end of file
diff --git a/third_party/firefox_jsshell/mac/jsshell.tar.gz.sha1 b/third_party/firefox_jsshell/mac/jsshell.tar.gz.sha1
new file mode 100644
index 0000000..a5c645a
--- /dev/null
+++ b/third_party/firefox_jsshell/mac/jsshell.tar.gz.sha1
@@ -0,0 +1 @@
+16c59a086b713720df0154cd4ceaed2ee8cf0d33
\ No newline at end of file
diff --git a/third_party/firefox_jsshell/win/jsshell.tar.gz.sha1 b/third_party/firefox_jsshell/win/jsshell.tar.gz.sha1
new file mode 100644
index 0000000..d43fcd1
--- /dev/null
+++ b/third_party/firefox_jsshell/win/jsshell.tar.gz.sha1
@@ -0,0 +1 @@
+a7ed194f518813a9915f67026ef138dd96adfec1
\ No newline at end of file
diff --git a/third_party/gsutil.tar.gz.sha1 b/third_party/gsutil.tar.gz.sha1
new file mode 100644
index 0000000..cfc510a
--- /dev/null
+++ b/third_party/gsutil.tar.gz.sha1
@@ -0,0 +1 @@
+99b82a42b98b78fc2a3f155995a16d8d7517b657
\ No newline at end of file
diff --git a/third_party/pkg/petitparser.tar.gz.sha1 b/third_party/pkg/petitparser.tar.gz.sha1
new file mode 100644
index 0000000..20b3196
--- /dev/null
+++ b/third_party/pkg/petitparser.tar.gz.sha1
@@ -0,0 +1 @@
+9626eed1ad9963e782f55a943ee8a1f82ff251a1
\ No newline at end of file
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index 59a3d33..4a2c46d 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -14,3 +14,5 @@
 Trigger bots on github pull
 Trigger bots 
 Purple is the new green.
+googlecode back up
+CIT outage - all slaves rebooted
diff --git a/tools/VERSION b/tools/VERSION
index 6cc2096..39452fb 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
 #
 CHANNEL stable
 MAJOR 1
-MINOR 13
-PATCH 2
+MINOR 14
+PATCH 0
 PRERELEASE 0
 PRERELEASE_PATCH 0
diff --git a/tools/apps/update_homebrew/bin/ssh_with_key b/tools/apps/update_homebrew/bin/ssh_with_key
index 210ad1c..6df4a04 100755
--- a/tools/apps/update_homebrew/bin/ssh_with_key
+++ b/tools/apps/update_homebrew/bin/ssh_with_key
@@ -1,2 +1,2 @@
-#!/bin/bash
+#!/usr/bin/env bash
 ssh -i $SSH_KEY_PATH $@
diff --git a/tools/apps/update_homebrew/bin/update_homebrew.dart b/tools/apps/update_homebrew/bin/update_homebrew.dart
index 50474c93..4623e9a 100644
--- a/tools/apps/update_homebrew/bin/update_homebrew.dart
+++ b/tools/apps/update_homebrew/bin/update_homebrew.dart
@@ -186,7 +186,7 @@
 
   def shim_script target
     <<-EOS.undent
-      #!/bin/bash
+      #!/usr/bin/env bash
       exec "#{prefix}/#{target}" "\$@"
     EOS
   end
diff --git a/tools/bots/android.py b/tools/bots/android.py
index 39cbb25..21b6978 100644
--- a/tools/bots/android.py
+++ b/tools/bots/android.py
@@ -52,7 +52,9 @@
     if os.path.exists('./out/lastHooksTargetOS.txt'):
       os.remove('./out/lastHooksTargetOS.txt')
     targets = ['runtime']
-    args = [sys.executable, './tools/build.py', '--mode=' + build_info.mode,
+    args = [sys.executable, './tools/build.py',
+            '--arch=' + build_info.arch,
+            '--mode=' + build_info.mode,
             '--os=android'] + targets
     print 'Building Android: %s' % (' '.join(args))
     bot.RunProcess(args)
diff --git a/tools/bots/bot.py b/tools/bots/bot.py
index ed20c5d..cfd9076 100644
--- a/tools/bots/bot.py
+++ b/tools/bots/bot.py
@@ -241,6 +241,7 @@
     cmd.extend(targets)
 
     print 'Running: %s' % (' '.join(map(lambda arg: '"%s"' % arg, cmd)))
+    sys.stdout.flush()
     RunProcess(cmd)
 
 
diff --git a/tools/bots/bot_utils.py b/tools/bots/bot_utils.py
index da166aa..53bd1ca 100644
--- a/tools/bots/bot_utils.py
+++ b/tools/bots/bot_utils.py
@@ -71,7 +71,7 @@
 
   Under every base path, the following structure is used:
     - /VERSION
-    - /api-docs/{dart-api-docs.zip,dartdocs-gen-api.zip}
+    - /api-docs/dartdocs-gen-api.zip
     - /dartium/{chromedriver,content_shell,dartium}
          -{linux,macos,windows}-{ia32,x64}-release.zip
     - /sdk/dartsdk-{linux,macos,windows}-{ia32,x64}-release.zip
@@ -119,6 +119,10 @@
     return '/'.join([self.dartium_directory(revision),
       self.dartium_variant_zipfilename(name, system, arch, mode)])
 
+  def apidocs_zipfilepath(self, revision):
+    return '/'.join([self.apidocs_directory(revision),
+      self.dartdocs_zipfilename()])
+
   def dartium_android_apk_filepath(self, revision, name, arch, mode):
     return '/'.join([self.dartium_android_directory(revision),
       self.dartium_android_apk_filename(name, arch, mode)])
@@ -162,9 +166,6 @@
   def dartium_android_apk_filename(self, name, arch, mode):
     return '%s-%s-%s.apk' % (name, arch, mode)
 
-  def apidocs_zipfilename(self):
-    return 'dart-api-docs.zip'
-
   def dartdocs_zipfilename(self):
     return 'dartdocs-gen-api.zip'
 
diff --git a/tools/bots/dart2js_dump_info.py b/tools/bots/dart2js_dump_info.py
index e213954..eb86385 100644
--- a/tools/bots/dart2js_dump_info.py
+++ b/tools/bots/dart2js_dump_info.py
@@ -43,6 +43,7 @@
     dump_compilations = os.path.join(temp_dir, 'dump')
     normal_compilation_command = [sys.executable,
                                   './tools/test.py',
+                                  '--arch=ia32',
                                   '--mode=%s' % build_info.mode,
                                   '-cdart2js',
                                   '-rnone',
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py
index decf876..7952885 100644
--- a/tools/bots/dart_sdk.py
+++ b/tools/bots/dart_sdk.py
@@ -39,11 +39,9 @@
                               'tools', 'bots', 'dartdoc_footer.html')
   url = 'https://api.dartlang.org/stable'
   with bot.BuildStep('Build API docs by dartdoc'):
-    subprocess.call([dart_exe, '--package-root=' + packages_dir, dartdoc_dart, 
-                    '--sdk-docs','--output', dirname, '--dart-sdk', dart_sdk, 
-                    '--footer' , footer_file,
-                    '--rel-canonical-prefix=' + url], 
-                     stdout=open(os.devnull, 'wb'))
+    bot_utils.run([dart_exe, '--package-root=' + packages_dir, dartdoc_dart, 
+                  '--sdk-docs','--output', dirname, '--dart-sdk', dart_sdk, 
+                  '--footer' , footer_file, '--rel-canonical-prefix=' + url])
 
 def CreateUploadVersionFile():
   file_path = os.path.join(bot_utils.DART_DIR,
diff --git a/tools/bots/pkg.py b/tools/bots/pkg.py
index b3e22a7..7dad673 100644
--- a/tools/bots/pkg.py
+++ b/tools/bots/pkg.py
@@ -44,7 +44,8 @@
     common_args.append('--builder-tag=%s' % build_info.builder_tag)
 
   # There are a number of big/integration tests in pkg, run with bigger timeout
-  common_args.append('--timeout=120')
+  timeout = 300 if build_info.mode == 'debug' else 120
+  common_args.append('--timeout=%s' % timeout)
   # We have some unreproducible vm crashes on these bots
   common_args.append('--copy-coredumps')
 
@@ -53,7 +54,7 @@
   if build_info.system == 'windows':
     common_args.append('-j1')
 
-  bot.RunTest('pkg ', build_info,
+  bot.RunTest('pkg', build_info,
               common_args + ['pkg', 'docs'],
               swallow_error=True)
 
diff --git a/tools/bots/pub.py b/tools/bots/pub.py
index cdd8a8b..7f177e0 100755
--- a/tools/bots/pub.py
+++ b/tools/bots/pub.py
@@ -33,7 +33,7 @@
   mode = 'release'
   if system == 'win': system = 'windows'
 
-  return bot.BuildInfo('none', 'vm', mode, system, checked=True)
+  return bot.BuildInfo('none', 'vm', mode, system, checked=True, arch='x64')
 
 def PubSteps(build_info):
   pub_location = os.path.join('third_party', 'pkg', 'pub')
diff --git a/tools/bots/run_android_tests.sh b/tools/bots/run_android_tests.sh
index 6bd2034..4b05094 100755
--- a/tools/bots/run_android_tests.sh
+++ b/tools/bots/run_android_tests.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/tools/build.py b/tools/build.py
index 0c5e235..dac178f 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -153,8 +153,10 @@
   if arch == 'arm':
     # To use a non-hf compiler, specify on the command line with --toolchain.
     return (DEFAULT_ARM_CROSS_COMPILER_PATH + "/arm-linux-gnueabihf")
+  if arch == 'arm64':
+    return (DEFAULT_ARM_CROSS_COMPILER_PATH + "/aarch64-linux-gnu")
 
-  # TODO(zra): Find default MIPS and ARM64 Linux cross-compilers.
+  # TODO(zra): Find default MIPS Linux cross-compiler.
 
   return None
 
diff --git a/tools/canary.dart b/tools/canary.dart
index cca1f90..0df9f70 100644
--- a/tools/canary.dart
+++ b/tools/canary.dart
@@ -2,10 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Script which exits with code 42.
-
-import 'dart:io';
-
 void main() {
-  exitCode = 42;
+  print("Success running the canary.");
 }
diff --git a/tools/coverage.dart b/tools/coverage.dart
deleted file mode 100644
index b5cc618..0000000
--- a/tools/coverage.dart
+++ /dev/null
@@ -1,545 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test forks a second vm process that runs a dart script as
-// a debug target, single stepping through the entire program, and
-// recording each breakpoint. At the end, a coverage map of the source
-// is printed.
-//
-// Usage: dart coverage.dart [--wire] [--verbose] target_script.dart
-//
-//   --wire      see json messages sent between the processes.
-//   --verbose   see the stdout and stderr output of the debug
-//               target process.
-
-import "dart:convert";
-import "dart:io";
-
-
-// Whether or not to print debug target process on the console.
-var showDebuggeeOutput = false;
-
-// Whether or not to print the debugger wire messages on the console.
-var verboseWire = false;
-
-var debugger = null;
-
-class Program {
-  static int numBps = 0;
-
-  // Maps source code url to source.
-  static var sources = new Map<String, Source>();
-
-  // Takes a JSON Debugger response and increments the count for
-  // the source position.
-  static void recordBp(Map<String,dynamic> msg) {
-    // Progress indicator.
-    if (++numBps % 1000 == 0) print(numBps);
-    var location = msg["params"]["location"];
-    if (location == null) return;
-    String url = location["url"];
-    assert(url != null);
-    int libId = location["libraryId"];
-    assert(libId != null);
-    int tokenPos = location["tokenOffset"];;
-    Source s = sources[url];
-    if (s == null) {
-      debugger.getLineNumberTable(url, libId);
-      s = new Source(url);
-      sources[url] = s;
-    }
-    s.recordBp(tokenPos);
-  }
-
-  // Prints the annotated source code.
-  static void printCoverage() {
-    print("Coverage info collected from $numBps breakpoints:");
-    for(Source s in sources.values) s.printCoverage();
-  }
-}
-
-
-class Source {
-  final String url;
-
-  // Maps token position to breakpoint count.
-  final tokenCounts = new Map<int,int>();
-
-  // Maps token position to line number.
-  final tokenPosToLine = new Map<int,int>();
-
-  Source(this.url);
-
-  void recordBp(int tokenPos) {
-    var count = tokenCounts[tokenPos];
-    tokenCounts[tokenPos] = count == null ? 1 : count + 1;
-  }
-
-  void SetLineInfo(List lineInfoTable) {
-    // Each line is encoded as an array with first element being the line
-    // number, followed by pairs of (tokenPosition, columnNumber).
-    lineInfoTable.forEach((List<int> line) {
-      int lineNumber = line[0];
-      for (int t = 1; t < line.length; t += 2) {
-        assert(tokenPosToLine[line[t]] == null);
-        tokenPosToLine[line[t]] = lineNumber;
-      }
-    });
-  }
-
-  // Print out the annotated source code. For each line that has seen
-  // a breakpoint, print out the maximum breakpoint count for all
-  // tokens in the line.
-  void printCoverage() {
-    var lineCounts = new Map<int,int>();  // BP counts for each line.
-    print(url);
-    tokenCounts.forEach((tp, bpCount) {
-      int lineNumber = tokenPosToLine[tp];
-      var lineCount = lineCounts[lineNumber];
-      // Remember maximum breakpoint count of all tokens in this line.
-      if (lineCount == null || lineCount < bpCount) {
-        lineCounts[lineNumber] = bpCount;
-      }
-    });
-
-    String srcPath = Uri.parse(url).toFilePath();
-    List lines = new File(srcPath).readAsLinesSync();
-    for (int line = 1; line <= lines.length; line++) {
-      String prefix = "      ";
-      if (lineCounts.containsKey(line)) {
-        prefix = lineCounts[line].toString();
-        StringBuffer b = new StringBuffer();
-        for (int i = prefix.length; i < 6; i++) b.write(" ");
-        b.write(prefix);
-        prefix = b.toString();
-      }
-      print("${prefix}|${lines[line-1]}");
-    }
-  }
-}
-
-
-class StepCmd {
-  Map msg;
-  StepCmd(int isolateId) {
-    msg = {"id": 0, "command": "stepInto", "params": {"isolateId": isolateId}};
-  }
-  void handleResponse(Map response) {}
-}
-
-
-class GetLineTableCmd {
-  Map msg;
-  GetLineTableCmd(int isolateId, int libraryId, String url) {
-    msg = { "id": 0,
-            "command":  "getLineNumberTable",
-            "params": { "isolateId" : isolateId,
-                        "libraryId": libraryId,
-                        "url": url } };
-  }
-
-  void handleResponse(Map response) {
-    var url = msg["params"]["url"];
-    Source s = Program.sources[url];
-    assert(s != null);
-    s.SetLineInfo(response["result"]["lines"]);
-  }
-}
-
-
-class GetLibrariesCmd {
-  Map msg;
-  GetLibrariesCmd(int isolateId) {
-    msg = { "id": 0,
-            "command":  "getLibraries",
-            "params": { "isolateId" : isolateId } };
-  }
-
-  void handleResponse(Map response) {
-    List libs = response["result"]["libraries"];
-    for (var lib in libs) {
-      String url = lib["url"];
-      int libraryId = lib["id"];
-      bool enable = !url.startsWith("dart:") && !url.startsWith("package:");
-      if (enable) {
-        print("Enable stepping for '$url'");
-        debugger.enableDebugging(libraryId, true);
-      }
-    }
-  }
-}
-
-
-class SetLibraryPropertiesCmd {
-  Map msg;
-  SetLibraryPropertiesCmd(int isolateId, int libraryId, bool enableDebugging) {
-    // Note that in the debugger protocol, boolean values true and false
-    // must be sent as string literals.
-    msg = { "id": 0,
-            "command":  "setLibraryProperties",
-            "params": { "isolateId" : isolateId,
-                        "libraryId": libraryId,
-                        "debuggingEnabled": "$enableDebugging" } };
-  }
-
-  void handleResponse(Map response) {
-    // Nothing to do.
-  }
-}
-
-
-class Debugger {
-  // Debug target process properties.
-  Process targetProcess;
-  Socket socket;
-  bool cleanupDone = false;
-  JsonBuffer responses = new JsonBuffer();
-  List<String> errors = new List();
-
-  // Data collected from debug target.
-  Map currentMessage = null;  // Currently handled message sent by target.
-  var outstandingCommand = null;
-  var queuedCommands = new List();
-  String scriptUrl = null;
-  bool shutdownEventSeen = false;
-  int isolateId = 0;
-  int libraryId = null;
-
-  int nextMessageId = 0;
-  bool isPaused = false;
-  bool pendingAck = false;
-
-  Debugger(this.targetProcess) {
-    var stdoutStringStream = targetProcess.stdout
-        .transform(UTF8.decoder)
-        .transform(new LineSplitter());
-    stdoutStringStream.listen((line) {
-      if (showDebuggeeOutput) {
-        print("TARG: $line");
-      }
-      if (line.startsWith("Debugger listening")) {
-        RegExp portExpr = new RegExp(r"\d+");
-        var port = portExpr.stringMatch(line);
-        var pid = targetProcess.pid;
-        print("Coverage target process (pid $pid) found "
-              "listening on port $port.");
-        openConnection(int.parse(port));
-      }
-    });
-
-    var stderrStringStream = targetProcess.stderr
-        .transform(UTF8.decoder)
-        .transform(new LineSplitter());
-    stderrStringStream.listen((line) {
-      if (showDebuggeeOutput) {
-        print("TARG: $line");
-      }
-    });
-  }
-
-  // Handle debugger events, updating the debugger state.
-  void handleEvent(Map<String,dynamic> msg) {
-    if (msg["event"] == "isolate") {
-      if (msg["params"]["reason"] == "created") {
-        isolateId = msg["params"]["id"];
-        assert(isolateId != null);
-        print("Debuggee isolate id $isolateId created.");
-      } else if (msg["params"]["reason"] == "shutdown") {
-        print("Debuggee isolate id ${msg["params"]["id"]} shut down.");
-        shutdownEventSeen = true;
-      }
-    } else if (msg["event"] == "breakpointResolved") {
-      var bpId = msg["params"]["breakpointId"];
-      assert(bpId != null);
-      var isolateId = msg["params"]["isolateId"];
-      assert(isolateId != null);
-      var location = msg["params"]["location"];
-      assert(location != null);
-      print("Isolate $isolateId: breakpoint $bpId resolved"
-            " at location $location");
-      // We may want to maintain a table of breakpoints in the future.
-    } else if (msg["event"] == "paused") {
-      isPaused = true;
-      if (libraryId == null) {
-        libraryId = msg["params"]["location"]["libraryId"];
-        assert(libraryId != null);
-        // This is the first paused event we got. Get all libraries from
-        // the debugger so we can turn on debugging events for them.
-        getLibraries();
-      }
-      if (msg["params"]["reason"] == "breakpoint") {
-        Program.recordBp(msg);
-      }
-    } else {
-      error("Error: unknown debugger event received");
-    }
-  }
-
-  // Handle one JSON message object.
-  void handleMessage(Map<String,dynamic> receivedMsg) {
-    currentMessage = receivedMsg;
-    if (receivedMsg["event"] != null) {
-      handleEvent(receivedMsg);
-      if (errorsDetected) {
-        error("Error while handling event message");
-        error("Event received from coverage target: $receivedMsg");
-      }
-    } else if (receivedMsg["id"] != null) {
-      // This is a response to the last command we sent.
-      int id = receivedMsg["id"];
-      assert(outstandingCommand != null);
-      assert(outstandingCommand.msg["id"] == id);
-      outstandingCommand.handleResponse(receivedMsg);
-      outstandingCommand = null;
-    } else {
-      error("Unexpected message from target");
-    }
-  }
-
-  // Handle data received over the wire from the coverage target
-  // process. Split input from JSON wire format into individual
-  // message objects (maps).
-  void handleMessages() {
-    var msg = responses.getNextMessage();
-    while (msg != null) {
-      if (verboseWire) print("RECV: $msg");
-      if (responses.haveGarbage()) {
-        error("Error: leftover text after message: '${responses.buffer}'");
-        error("Previous message may be malformed, was: '$msg'");
-        cleanup();
-        return;
-      }
-      var msgObj = JSON.decode(msg);
-      handleMessage(msgObj);
-      if (errorsDetected) {
-        error("Error while handling message from coverage target");
-        error("Message received from coverage target: $msg");
-        cleanup();
-        return;
-      }
-      if (shutdownEventSeen) {
-        if (outstandingCommand != null) {
-          error("Error: outstanding command when shutdown received");
-        }
-        cleanup();
-        return;
-      }
-      if (isPaused && (outstandingCommand == null)) {
-        var cmd = queuedCommands.length > 0 ? queuedCommands.removeAt(0) : null;
-        if (cmd == null) {
-          cmd = new StepCmd(isolateId);
-          isPaused = false;
-        }
-        sendMessage(cmd.msg);
-        outstandingCommand = cmd;
-      }
-      msg = responses.getNextMessage();
-    }
-  }
-
-  // Send a debugger command to the target VM.
-  void sendMessage(Map<String,dynamic> msg) {
-    assert(msg["id"] != null);
-    msg["id"] = nextMessageId++;
-    String jsonMsg = JSON.encode(msg);
-    if (verboseWire) print("SEND: $jsonMsg");
-    socket.write(jsonMsg);
-  }
-
-  void getLineNumberTable(String url, int libId) {
-    queuedCommands.add(new GetLineTableCmd(isolateId, libId, url));
-  }
-
-  void getLibraries() {
-    queuedCommands.add(new GetLibrariesCmd(isolateId));
-  }
-
-  void enableDebugging(libraryId, enable) {
-    queuedCommands.add(new SetLibraryPropertiesCmd(isolateId, libraryId, enable));
-  }
-
-  bool get errorsDetected => errors.length > 0;
-
-  // Record error message.
-  void error(String s) {
-    errors.add(s);
-  }
-
-  void openConnection(int portNumber) {
-    Socket.connect("127.0.0.1", portNumber).then((s) {
-      socket = s;
-      socket.setOption(SocketOption.TCP_NODELAY, true);
-      var stringStream = socket.transform(UTF8.decoder);
-      stringStream.listen(
-          (str) {
-            try {
-              responses.append(str);
-              handleMessages();
-            } catch(e, trace) {
-              print("Unexpected exception:\n$e\n$trace");
-              cleanup();
-            }
-          },
-          onDone: () {
-            print("Connection closed by coverage target");
-            cleanup();
-          },
-          onError: (e) {
-            print("Error '$e' detected in input stream from coverage target");
-            cleanup();
-          });
-      },
-      onError: (e, trace) {
-        String msg = "Error while connecting to coverage target: $e";
-        if (trace != null) msg += "\nStackTrace: $trace";
-        error(msg);
-        cleanup();
-     });
-  }
-
-  void cleanup() {
-    if (cleanupDone) return;
-    if (socket != null) {
-      socket.close().catchError((error) {
-        // Print this directly in addition to adding it to the
-        // error message queue, in case the error message queue
-        // gets printed before this error handler is called.
-        print("Error occurred while closing socket: $error");
-        error("Error while closing socket: $error");
-      });
-    }
-    var targetPid = targetProcess.pid;
-    print("Sending kill signal to process $targetPid.");
-    targetProcess.kill();
-    // If the process was already dead exitCode is already
-    // available and we call exit() in the next event loop cycle.
-    // Otherwise this will wait for the process to exit.
-
-    targetProcess.exitCode.then((exitCode) {
-      print("Process $targetPid terminated with exit code $exitCode.");
-      if (errorsDetected) {
-        print("\n===== Errors detected: =====");
-        for (int i = 0; i < errors.length; i++) print(errors[i]);
-        print("============================\n");
-      }
-      Program.printCoverage();
-      exit(errors.length);
-    });
-    cleanupDone = true;
-  }
-}
-
-
-// Class to buffer wire protocol data from coverage target and
-// break it down to individual json messages.
-class JsonBuffer {
-  String buffer = null;
-
-  append(String s) {
-    if (buffer == null || buffer.length == 0) {
-      buffer = s;
-    } else {
-      buffer = buffer + s;
-    }
-  }
-
-  String getNextMessage() {
-    if (buffer == null) return null;
-    int msgLen = objectLength();
-    if (msgLen == 0) return null;
-    String msg = null;
-    if (msgLen == buffer.length) {
-      msg = buffer;
-      buffer = null;
-    } else {
-      assert(msgLen < buffer.length);
-      msg = buffer.substring(0, msgLen);
-      buffer = buffer.substring(msgLen);
-    }
-    return msg;
-  }
-
-  bool haveGarbage() {
-    if (buffer == null || buffer.length == 0) return false;
-    var i = 0, char = " ";
-    while (i < buffer.length) {
-      char = buffer[i];
-      if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
-      i++;
-    }
-    if (i >= buffer.length) {
-      return false;
-    } else {
-      return char != "{";
-    }
-  }
-
-  // Returns the character length of the next json message in the
-  // buffer, or 0 if there is only a partial message in the buffer.
-  // The object value must start with '{' and continues to the
-  // matching '}'. No attempt is made to otherwise validate the contents
-  // as JSON. If it is invalid, a later JSON.decode() will fail.
-  int objectLength() {
-    int skipWhitespace(int index) {
-      while (index < buffer.length) {
-        String char = buffer[index];
-        if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
-        index++;
-      }
-      return index;
-    }
-    int skipString(int index) {
-      assert(buffer[index - 1] == '"');
-      while (index < buffer.length) {
-        String char = buffer[index];
-        if (char == '"') return index + 1;
-        if (char == r'\') index++;
-        if (index == buffer.length) return index;
-        index++;
-      }
-      return index;
-    }
-    int index = 0;
-    index = skipWhitespace(index);
-    // Bail out if the first non-whitespace character isn't '{'.
-    if (index == buffer.length || buffer[index] != '{') return 0;
-    int nesting = 0;
-    while (index < buffer.length) {
-      String char = buffer[index++];
-      if (char == '{') {
-        nesting++;
-      } else if (char == '}') {
-        nesting--;
-        if (nesting == 0) return index;
-      } else if (char == '"') {
-        // Strings can contain braces. Skip their content.
-        index = skipString(index);
-      }
-    }
-    return 0;
-  }
-}
-
-
-void main(List<String> arguments) {
-  var targetOpts = [ "--debug:0" ];
-  for (String str in arguments) {
-    switch (str) {
-      case "--verbose":
-        showDebuggeeOutput = true;
-        break;
-      case "--wire":
-        verboseWire = true;
-        break;
-      default:
-        targetOpts.add(str);
-        break;
-    }
-  }
-
-  Process.start(Platform.executable, targetOpts).then((Process process) {
-    process.stdin.close();
-    debugger = new Debugger(process);
-  });
-}
diff --git a/tools/create_debian_chroot.sh b/tools/create_debian_chroot.sh
index fdb1cf2..0f42c3e3 100755
--- a/tools/create_debian_chroot.sh
+++ b/tools/create_debian_chroot.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # 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
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index f377798..5cf2b1a 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -39,6 +39,10 @@
 # ......dart_native_api.h
 # ......dart_tools_api.h
 # ....lib/
+# ......dart_client.platform
+# ......dart_server.platform
+# ......dart_shared.platform
+# ......dart2dart.platform
 # ......_internal/
 # ......async/
 # ......collection/
@@ -241,6 +245,13 @@
              ignore=ignore_patterns('*.svn', 'doc', '*.py', '*.gypi', '*.sh',
                                     '.gitignore'))
 
+  # Copy the platform descriptors.
+  for file_name in ["dart_client.platform",
+                    "dart_server.platform",
+                    "dart_shared.platform",
+                    "dart2dart.platform"]:
+    copyfile(join(HOME, 'sdk', 'lib', file_name), join(LIB, file_name));
+
   # Copy libraries.dart to lib/_internal/libraries.dart for backwards
   # compatibility.
   #
diff --git a/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS b/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS
index 2e2224a..b797e77 100644
--- a/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS
+++ b/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS
@@ -1 +1 @@
-da6def3772e22665c381306fd5f8be30a60c2058
+e1d7bdcfe7f25156c8a462452db5367b68a02df6
diff --git a/tools/dartium/download_shellscript_template.sh b/tools/dartium/download_shellscript_template.sh
index 3399945..5e44053 100644
--- a/tools/dartium/download_shellscript_template.sh
+++ b/tools/dartium/download_shellscript_template.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
diff --git a/tools/dartium/start_dartium_roll.sh b/tools/dartium/start_dartium_roll.sh
index 41aebbf..d908620 100755
--- a/tools/dartium/start_dartium_roll.sh
+++ b/tools/dartium/start_dartium_roll.sh
@@ -1,4 +1,6 @@
-#!/bin/bash -e
+#!/usr/bin/env bash
+
+set -e
 
 # Requirements:
 #    sudo apt-get install xclip
diff --git a/tools/dartium/update_deps.py b/tools/dartium/update_deps.py
index a8b1b4b..6e27437 100755
--- a/tools/dartium/update_deps.py
+++ b/tools/dartium/update_deps.py
@@ -79,14 +79,14 @@
 # used to generated the commit message.
 REPOSITORY_INFO = {
     'webkit': (
-        'http://src.chromium.org/blink/branches/%s',
-        'http://src.chromium.org/viewvc/blink?view=rev&revision=%s'),
+        'https://src.chromium.org/blink/branches/%s',
+        'https://src.chromium.org/viewvc/blink?view=rev&revision=%s'),
     'blink': (
-        'http://src.chromium.org/blink/branches/%s',
-        'http://src.chromium.org/viewvc/blink?view=rev&revision=%s'),
+        'https://src.chromium.org/blink/branches/%s',
+        'https://src.chromium.org/viewvc/blink?view=rev&revision=%s'),
     'chromium': (
-        'http://src.chromium.org/chrome/branches/%s',
-        'http://src.chromium.org/viewvc/chrome?view=rev&revision=%s'),
+        'https://src.chromium.org/chrome/branches/%s',
+        'https://src.chromium.org/viewvc/chrome?view=rev&revision=%s'),
 }
 
 REPOSITORIES = REPOSITORY_INFO.keys()
diff --git a/tools/ddbg.dart b/tools/ddbg.dart
deleted file mode 100644
index 1d1199b..0000000
--- a/tools/ddbg.dart
+++ /dev/null
@@ -1,1496 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Simple interactive debugger shell that connects to the Dart VM's debugger
-// connection port.
-
-import "dart:convert";
-import "dart:io";
-import "dart:async";
-import "dart:math";
-
-import "ddbg/lib/commando.dart";
-
-class TargetScript {
-  // The text of a script.
-  String source = null;
-
-  // A mapping from line number to source text.
-  List<String> lineToSource = null;
-
-  // A mapping from token offset to line number.
-  Map<int,int> tokenToLine = null;
-}
-
-const UnknownLocation = const {};
-
-class TargetIsolate {
-  int id;
-  // The location of the last paused event.
-  Map pausedLocation = null;
-
-  TargetIsolate(this.id);
-  bool get isPaused => pausedLocation != null;
-  String get pausedUrl => pausedLocation != null ? pausedLocation["url"] : null;
-
-  Map<String, TargetScript> scripts = {};
-}
-
-Map<int, TargetIsolate> targetIsolates= new Map<int, TargetIsolate>();
-
-Map<int, Completer> outstandingCommands;
-
-Socket vmSock;
-String vmData;
-var cmdSubscription;
-Commando cmdo;
-var vmSubscription;
-int seqNum = 0;
-
-bool isDebugging = false;
-Process targetProcess = null;
-bool suppressNextExitCode = false;
-
-final verbose = false;
-final printMessages = false;
-
-TargetIsolate currentIsolate;
-TargetIsolate mainIsolate;
-
-int debugPort = 5858;
-
-String formatLocation(Map location) {
-  if (location == null) return "";
-  var fileName = location["url"].split("/").last;
-  return "file: $fileName lib: ${location['libraryId']} token: ${location['tokenOffset']}";
-}
-
-
-Future sendCmd(Map<String, dynamic> cmd) {
-  var completer = new Completer.sync();
-  int id = cmd["id"];
-  outstandingCommands[id] = completer;
-  if (verbose) {
-    print("sending: '${JSON.encode(cmd)}'");
-  }
-  vmSock.write(JSON.encode(cmd));
-  return completer.future;
-}
-
-
-bool checkCurrentIsolate() {
-  if (vmSock == null) {
-    print("There is no active script.  Try 'help run'.");
-    return false;
-  }
-  if (currentIsolate == null) {
-    print('There is no current isolate.');
-    return false;
-  }
-  return true;
-}
-
-
-void setCurrentIsolate(TargetIsolate isolate) {
-  if (isolate != currentIsolate) {
-    currentIsolate = isolate;
-    if (mainIsolate == null) {
-      print("Main isolate is ${isolate.id}");
-      mainIsolate = isolate;
-    }
-    print("Current isolate is now ${isolate.id}");
-  }
-}
-
-
-bool checkPaused() {
-  if (!checkCurrentIsolate()) return false;
-  if (currentIsolate.isPaused) return true;
-  print("Current isolate must be paused");
-  return false;
-}
-
-// These settings are allowed in the 'set' and 'show' debugger commands.
-var validSettings = ['vm', 'vmargs', 'script', 'args'];
-
-// The current values for all settings.
-var settings = new Map();
-
-String _leftJustify(text, int width) {
-  StringBuffer buffer = new StringBuffer();
-  buffer.write(text);
-  while (buffer.length < width) {
-    buffer.write(' ');
-  }
-  return buffer.toString();
-}
-
-// TODO(turnidge): Move all commands here.
-List<Command> commandList =
-    [ new HelpCommand(),
-      new QuitCommand(),
-      new RunCommand(),
-      new KillCommand(),
-      new ConnectCommand(),
-      new DisconnectCommand(),
-      new SetCommand(),
-      new ShowCommand() ];
-
-
-List<Command> matchCommand(String commandName, bool exactMatchWins) {
-  List matches = [];
-  for (var command in commandList) {
-    if (command.name.startsWith(commandName)) {
-      if (exactMatchWins && command.name == commandName) {
-        // Exact match
-        return [command];
-      } else {
-        matches.add(command);
-      }
-    }
-  }
-  return matches;
-}
-
-abstract class Command {
-  String get name;
-  Future run(List<String> args);
-}
-
-class HelpCommand extends Command {
-  final name = 'help';
-  final helpShort = 'Show a list of debugger commands';
-  final helpLong ="""
-Show a list of debugger commands or get more information about a
-particular command.
-
-Usage:
-  help
-  help <command>
-""";
-
-  Future run(List<String> args) {
-    if (args.length == 1) {
-      print("Debugger commands:\n");
-      for (var command in commandList) {
-        print('  ${_leftJustify(command.name, 11)} ${command.helpShort}');
-      }
-
-      // TODO(turnidge): Convert all commands to use the Command class.
-      print("""
-  bt          Show backtrace
-  r           Resume execution
-  s           Single step
-  so          Step over
-  si          Step into
-  sbp [<file>] <line> Set breakpoint
-  rbp <id>    Remove breakpoint with given id
-  po <id>     Print object info for given id
-  eval fr  <n> <expr> Evaluate expr on stack frame index n
-  eval obj <id> <expr> Evaluate expr on object id
-  eval cls <id> <expr> Evaluate expr on class id
-  eval lib <id> <expr> Evaluate expr in toplevel of library id
-  pl <id> <idx> [<len>] Print list element/slice
-  pc <id>     Print class info for given id
-  ll          List loaded libraries
-  plib <id>   Print library info for given library id
-  slib <id> <true|false> Set library id debuggable
-  pg <id>     Print all global variables visible within given library id
-  ls <lib_id> List loaded scripts in library
-  gs <lib_id> <script_url> Get source text of script in library
-  tok <lib_id> <script_url> Get line and token table of script in library
-  epi <none|all|unhandled>  Set exception pause info
-  li          List ids of all isolates in the VM
-  sci <id>    Set current target isolate
-  i <id>      Interrupt execution of given isolate id
-""");
-
-      print("For more information about a particular command, type:\n\n"
-            "  help <command>\n");
-
-      print("Commands may be abbreviated: e.g. type 'h' for 'help.\n");
-    } else if (args.length == 2) {
-      var commandName = args[1];
-      var matches = matchCommand(commandName, true);
-      if (matches.length == 0) {
-        print("Command '$commandName' not recognized.  "
-              "Try 'help' for a list of commands.");
-      } else {
-        for (var command in matches) {
-          print("---- ${command.name} ----\n${command.helpLong}");
-        }
-      }
-    } else {
-      print("Command '$command' not recognized.  "
-            "Try 'help' for a list of commands.");
-    }
-
-    return new Future.value();
-  }
-}
-
-
-class QuitCommand extends Command {
-  final name = 'quit';
-  final helpShort = 'Quit the debugger.';
-  final helpLong ="""
-Quit the debugger.
-
-Usage:
-  quit
-""";
-
-  Future run(List<String> args) {
-    if (args.length > 1) {
-      print("Unexpected arguments to $name command.");
-      return new Future.value();
-    }
-    return debuggerQuit();
-  }
-}
-
-class SetCommand extends Command {
-  final name = 'set';
-  final helpShort = 'Change the value of a debugger setting.';
-  final helpLong ="""
-Change the value of a debugger setting.
-
-Usage:
-  set <setting> <value>
-
-Valid settings are:
-  ${validSettings.join('\n  ')}.
-
-See also 'help show'.
-""";
-
-  Future run(List<String> args) {
-    if (args.length < 3 || !validSettings.contains(args[1])) {
-      print("Undefined $name command.  Try 'help $name'.");
-      return new Future.value();
-    }
-    var option = args[1];
-    var value = args.getRange(2, args.length).join(' ');
-    settings[option] = value;
-    return new Future.value();
-  }
-}
-
-class ShowCommand extends Command {
-  final name = 'show';
-  final helpShort = 'Show the current value of a debugger setting.';
-  final helpLong ="""
-Show the current value of a debugger setting.
-
-Usage:
-  show
-  show <setting>
-
-If no <setting> is specified, all current settings are shown.
-
-Valid settings are:
-  ${validSettings.join('\n  ')}.
-
-See also 'help set'.
-""";
-
-  Future run(List<String> args) {
-    if (args.length == 1) {
-      for (var option in validSettings) {
-        var value = settings[option];
-        print("$option = '$value'");
-      }
-    } else if (args.length == 2 && validSettings.contains(args[1])) {
-      var option = args[1];
-      var value = settings[option];
-      if (value == null) {
-        print('$option has not been set.');
-      } else {
-        print("$option = '$value'");
-      }
-      return new Future.value();
-    } else {
-      print("Undefined $name command.  Try 'help $name'.");
-    }
-    return new Future.value();
-  }
-}
-
-class RunCommand extends Command {
-  final name = 'run';
-  final helpShort = "Run the currrent script.";
-  final helpLong ="""
-Runs the current script.
-
-Usage:
-  run
-  run <args>
-
-The current script will be run on the current vm.  The 'vm' and
-'vmargs' settings are used to specify the current vm and vm arguments.
-The 'script' and 'args' settings are used to specify the current
-script and script arguments.
-
-For more information on settings type 'help show' or 'help set'.
-
-If <args> are provided to the run command, it is the same as typing
-'set args <args>' followed by 'run'.
-""";
-
-  Future run(List<String> cmdArgs) {
-    if (isDebugging) {
-      // TODO(turnidge): Implement modal y/n dialog to stop running script.
-      print("There is already a running dart process.  "
-            "Try 'kill'.");
-      return new Future.value();
-    }
-    assert(targetProcess == null);
-    if (settings['script'] == null) {
-      print("There is no script specified.  "
-            "Use 'set script' to set the current script.");
-      return new Future.value();
-    }
-    if (cmdArgs.length > 1) {
-      settings['args'] = cmdArgs.getRange(1, cmdArgs.length);
-    }
-
-    // Build the process arguments.
-    var processArgs = ['--debug:$debugPort'];
-    if (verbose) {
-      processArgs.add('--verbose_debug');
-    }
-    if (settings['vmargs'] != null) {
-      processArgs.addAll(settings['vmargs'].split(' '));
-    }
-    processArgs.add(settings['script']);
-    if (settings['args'] != null) {
-      processArgs.addAll(settings['args'].split(' '));
-    }
-    String vm = settings['vm'];
-
-    isDebugging = true;
-    cmdo.hide();
-    return Process.start(vm, processArgs).then((process) {
-        print("Started process ${process.pid} '$vm ${processArgs.join(' ')}'");
-        targetProcess = process;
-        process.stdin.close();
-
-        // TODO(turnidge): For now we only show full lines of output
-        // from the debugged process.  Should show each character.
-        process.stdout
-            .transform(UTF8.decoder)
-            .transform(new LineSplitter())
-            .listen((String line) {
-                cmdo.hide();
-                // TODO(turnidge): Escape output in any way?
-                print(line);
-                cmdo.show();
-              });
-
-        process.stderr
-            .transform(UTF8.decoder)
-            .transform(new LineSplitter())
-            .listen((String line) {
-                cmdo.hide();
-                print(line);
-                cmdo.show();
-              });
-
-        process.exitCode.then((int exitCode) {
-            cmdo.hide();
-            if (suppressNextExitCode) {
-              suppressNextExitCode = false;
-            } else {
-              if (exitCode == 0) {
-                print('Process exited normally.');
-              } else {
-                print('Process exited with code $exitCode.');
-              }
-            }
-            targetProcess = null;
-            cmdo.show();
-          });
-
-        // Wait for the vm to open the debugging port.
-        return openVmSocket(0);
-      });
-  }
-}
-
-class KillCommand extends Command {
-  final name = 'kill';
-  final helpShort = 'Kill the currently executing script.';
-  final helpLong ="""
-Kill the currently executing script.
-
-Usage:
-  kill
-""";
-
-  Future run(List<String> cmdArgs) {
-    if (!isDebugging) {
-      print('There is no running script.');
-      return new Future.value();
-    }
-    if (targetProcess == null) {
-      print("The active dart process was not started with 'run'. "
-            "Try 'disconnect' instead.");
-      return new Future.value();
-    }
-    assert(targetProcess != null);
-    bool result = targetProcess.kill();
-    if (result) {
-      print('Process killed.');
-      suppressNextExitCode = true;
-    } else {
-      print('Unable to kill process ${targetProcess.pid}');
-    }
-    return new Future.value();
-  }
-}
-
-class ConnectCommand extends Command {
-  final name = 'connect';
-  final helpShort = "Connect to a running dart script.";
-  final helpLong ="""
-Connect to a running dart script.
-
-Usage:
-  connect
-  connect <port>
-
-The debugger will connect to a dart script which has already been
-started with the --debug option.  If no port is provided, the debugger
-will attempt to connect on the default debugger port.
-""";
-
-  Future run(List<String> cmdArgs) {
-    if (cmdArgs.length > 2) {
-      print("Too many arguments to 'connect'.");
-    }
-    if (isDebugging) {
-      // TODO(turnidge): Implement modal y/n dialog to stop running script.
-      print("There is already a running dart process.  "
-            "Try 'kill'.");
-      return new Future.value();
-    }
-    assert(targetProcess == null);
-    if (cmdArgs.length == 2) {
-      debugPort = int.parse(cmdArgs[1]);
-    }
-
-    isDebugging = true;
-    cmdo.hide();
-    return openVmSocket(0);
-  }
-}
-
-class DisconnectCommand extends Command {
-  final name = 'disconnect';
-  final helpShort = "Disconnect from a running dart script.";
-  final helpLong ="""
-Disconnect from a running dart script.
-
-Usage:
-  disconnect
-
-The debugger will disconnect from a dart script's debugging port.  The
-script must have been connected to earlier with the 'connect' command.
-""";
-
-  Future run(List<String> cmdArgs) {
-    if (cmdArgs.length > 1) {
-      print("Too many arguments to 'disconnect'.");
-    }
-    if (!isDebugging) {
-      // TODO(turnidge): Implement modal y/n dialog to stop running script.
-      print("There is no active dart process.  "
-            "Try 'connect'.");
-      return new Future.value();
-    }
-    if (targetProcess != null) {
-      print("The active dart process was started with 'run'.  "
-            "Try 'kill'.");
-    }
-
-    cmdo.hide();
-    return closeVmSocket();
-  }
-}
-
-typedef void HandlerType(Map response);
-
-HandlerType showPromptAfter(void handler(Map response)) {
-  return (response) {
-    handler(response);
-    cmdo.show();
-  };
-}
-
-void processCommand(String cmdLine) {
-  void huh() {
-    print("'$cmdLine' not understood, try 'help' for help.");
-  }
-
-  cmdo.hide();
-  seqNum++;
-  cmdLine = cmdLine.trim();
-  var args = cmdLine.split(' ');
-  if (args.length == 0) {
-    return;
-  }
-  var command = args[0];
-
-  var resume_commands =
-      { 'r':'resume', 's':'stepOver', 'si':'stepInto', 'so':'stepOut'};
-  if (resume_commands[command] != null) {
-    if (!checkPaused()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": resume_commands[command],
-                "params": { "isolateId" : currentIsolate.id } };
-    sendCmd(cmd).then(showPromptAfter(handleResumedResponse));
-  } else if (command == "bt") {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "getStackTrace",
-                "params": { "isolateId" : currentIsolate.id } };
-    sendCmd(cmd).then(showPromptAfter(handleStackTraceResponse));
-  } else if (command == "ll") {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "getLibraries",
-                "params": { "isolateId" : currentIsolate.id } };
-    sendCmd(cmd).then(showPromptAfter(handleGetLibraryResponse));
-  } else if (command == "sbp" && args.length >= 2) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var url, line;
-    if (args.length == 2 && currentIsolate.pausedUrl != null) {
-      url = currentIsolate.pausedUrl;
-      line = int.parse(args[1]);
-    } else {
-      url = args[1];
-      line = int.parse(args[2]);
-    }
-    var cmd = { "id": seqNum,
-                "command": "setBreakpoint",
-                "params": { "isolateId" : currentIsolate.id,
-                            "url": url,
-                            "line": line }};
-    sendCmd(cmd).then(showPromptAfter(handleSetBpResponse));
-  } else if (command == "rbp" && args.length == 2) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "removeBreakpoint",
-                "params": { "isolateId" : currentIsolate.id,
-                            "breakpointId": int.parse(args[1]) } };
-    sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
-  } else if (command == "ls" && args.length == 2) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "getScriptURLs",
-                "params": { "isolateId" : currentIsolate.id,
-                            "libraryId": int.parse(args[1]) } };
-    sendCmd(cmd).then(showPromptAfter(handleGetScriptsResponse));
-  } else if (command == "eval" && args.length > 3) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var expr = args.getRange(3, args.length).join(" ");
-    var target = args[1];
-    if (target == "obj") {
-      target = "objectId";
-    } else if (target == "cls") {
-      target = "classId";
-    } else if (target == "lib") {
-      target = "libraryId";
-    } else if (target == "fr") {
-      target = "frameId";
-    } else {
-      huh();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "evaluateExpr",
-                "params": { "isolateId": currentIsolate.id,
-                            target: int.parse(args[2]),
-                            "expression": expr } };
-    sendCmd(cmd).then(showPromptAfter(handleEvalResponse));
-  } else if (command == "po" && args.length == 2) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "getObjectProperties",
-                "params": { "isolateId" : currentIsolate.id,
-                            "objectId": int.parse(args[1]) } };
-    sendCmd(cmd).then(showPromptAfter(handleGetObjPropsResponse));
-  } else if (command == "pl" && args.length >= 3) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd;
-    if (args.length == 3) {
-      cmd = { "id": seqNum,
-              "command": "getListElements",
-              "params": { "isolateId" : currentIsolate.id,
-                          "objectId": int.parse(args[1]),
-                          "index": int.parse(args[2]) } };
-    } else {
-      cmd = { "id": seqNum,
-              "command": "getListElements",
-              "params": { "isolateId" : currentIsolate.id,
-                          "objectId": int.parse(args[1]),
-                          "index": int.parse(args[2]),
-                          "length": int.parse(args[3]) } };
-    }
-    sendCmd(cmd).then(showPromptAfter(handleGetListResponse));
-  } else if (command == "pc" && args.length == 2) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "getClassProperties",
-                "params": { "isolateId" : currentIsolate.id,
-                            "classId": int.parse(args[1]) } };
-    sendCmd(cmd).then(showPromptAfter(handleGetClassPropsResponse));
-  } else if (command == "plib" && args.length == 2) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "getLibraryProperties",
-                "params": {"isolateId" : currentIsolate.id,
-                           "libraryId": int.parse(args[1]) } };
-    sendCmd(cmd).then(showPromptAfter(handleGetLibraryPropsResponse));
-  } else if (command == "slib" && args.length == 3) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "setLibraryProperties",
-                "params": {"isolateId" : currentIsolate.id,
-                           "libraryId": int.parse(args[1]),
-                           "debuggingEnabled": args[2] } };
-    sendCmd(cmd).then(showPromptAfter(handleSetLibraryPropsResponse));
-  } else if (command == "pg" && args.length == 2) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command": "getGlobalVariables",
-                "params": { "isolateId" : currentIsolate.id,
-                            "libraryId": int.parse(args[1]) } };
-    sendCmd(cmd).then(showPromptAfter(handleGetGlobalVarsResponse));
-  } else if (command == "gs" && args.length == 3) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command":  "getScriptSource",
-                "params": { "isolateId" : currentIsolate.id,
-                            "libraryId": int.parse(args[1]),
-                            "url": args[2] } };
-    sendCmd(cmd).then(showPromptAfter(handleGetSourceResponse));
-  } else if (command == "tok" && args.length == 3) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command":  "getLineNumberTable",
-                "params": { "isolateId" : currentIsolate.id,
-                            "libraryId": int.parse(args[1]),
-                            "url": args[2] } };
-    sendCmd(cmd).then(showPromptAfter(handleGetLineTableResponse));
-  } else if (command == "epi" && args.length == 2) {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum,
-                "command":  "setPauseOnException",
-                "params": { "isolateId" : currentIsolate.id,
-                            "exceptions": args[1] } };
-    sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
-  } else if (command == "li") {
-    if (!checkCurrentIsolate()) {
-      cmdo.show();
-      return;
-    }
-    var cmd = { "id": seqNum, "command": "getIsolateIds" };
-    sendCmd(cmd).then(showPromptAfter(handleGetIsolatesResponse));
-  } else if (command == "sci" && args.length == 2) {
-    var id = int.parse(args[1]);
-    if (targetIsolates[id] != null) {
-      setCurrentIsolate(targetIsolates[id]);
-    } else {
-      print("$id is not a valid isolate id");
-    }
-    cmdo.show();
-  } else if (command == "i" && args.length == 2) {
-    var cmd = { "id": seqNum,
-                "command": "interrupt",
-                "params": { "isolateId": int.parse(args[1]) } };
-    sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
-  } else if (command.length == 0) {
-    huh();
-    cmdo.show();
-  } else {
-    // TODO(turnidge): Use this for all commands.
-    var matches = matchCommand(command, true);
-    if (matches.length == 0) {
-      huh();
-      cmdo.show();
-    } else if (matches.length == 1) {
-      matches[0].run(args).then((_) {
-          cmdo.show();
-        });
-    } else {
-      var matchNames = matches.map((handler) => handler.name);
-      print("Ambigous command '$command' : ${matchNames.toList()}");
-      cmdo.show();
-    }
-  }
-}
-
-
-void processError(error, trace) {
-  cmdo.hide();
-  print("\nInternal error:\n$error\n$trace");
-  cmdo.show();
-}
-
-
-void processDone() {
-  debuggerQuit();
-}
-
-
-String remoteObject(value) {
-  var kind = value["kind"];
-  var text = value["text"];
-  var id = value["objectId"];
-  if (kind == "string") {
-    return "(string, id $id) '$text'";
-  } else if (kind == "list") {
-    var len = value["length"];
-    return "(list, id $id, len $len) $text";
-  } else if (kind == "object") {
-    return "(obj, id $id) $text";
-  } else if (kind == "function") {
-    var location = formatLocation(value['location']);
-    var name = value['name'];
-    var signature = value['signature'];
-    return "(closure ${name}${signature} $location)";
-  } else {
-    return "$text";
-  }
-}
-
-
-printNamedObject(obj) {
-  var name = obj["name"];
-  var value = obj["value"];
-  print("  $name = ${remoteObject(value)}");
-}
-
-
-handleGetObjPropsResponse(Map response) {
-  Map props = response["result"];
-  int class_id = props["classId"];
-  if (class_id == -1) {
-    print("  null");
-    return;
-  }
-  List fields = props["fields"];
-  print("  class id: $class_id");
-  for (int i = 0; i < fields.length; i++) {
-    printNamedObject(fields[i]);
-  }
-}
-
-handleGetListResponse(Map response) {
-  Map result = response["result"];
-  if (result["elements"] != null) {
-    // List slice.
-    var index = result["index"];
-    var length = result["length"];
-    List elements = result["elements"];
-    assert(length == elements.length);
-    for (int i = 0; i < length; i++) {
-      var kind = elements[i]["kind"];
-      var text = elements[i]["text"];
-      print("  ${index + i}: ($kind) $text");
-    }
-  } else {
-    // One element, a remote object.
-    print(result);
-    print("  ${remoteObject(result)}");
-  }
-}
-
-
-handleGetClassPropsResponse(Map response) {
-  Map props = response["result"];
-  assert(props["name"] != null);
-  int libId = props["libraryId"];
-  assert(libId != null);
-  print("  class ${props["name"]} (library id: $libId)");
-  List fields = props["fields"];
-  if (fields.length > 0) {
-    print("  static fields:");
-    for (int i = 0; i < fields.length; i++) {
-      printNamedObject(fields[i]);
-    }
-  }
-}
-
-
-handleGetLibraryPropsResponse(Map response) {
-  Map props = response["result"];
-  assert(props["url"] != null);
-  print("  library url: ${props["url"]}");
-  assert(props["debuggingEnabled"] != null);
-  print("  debugging enabled: ${props["debuggingEnabled"]}");
-  List imports = props["imports"];
-  assert(imports != null);
-  if (imports.length > 0) {
-    print("  imports:");
-    for (int i = 0; i < imports.length; i++) {
-      print("    id ${imports[i]["libraryId"]} prefix ${imports[i]["prefix"]}");
-    }
-  }
-  List globals = props["globals"];
-  assert(globals != null);
-  if (globals.length > 0) {
-    print("  global variables:");
-    for (int i = 0; i < globals.length; i++) {
-      printNamedObject(globals[i]);
-    }
-  }
-}
-
-
-handleSetLibraryPropsResponse(Map response) {
-  Map props = response["result"];
-  assert(props["debuggingEnabled"] != null);
-  print("  debugging enabled: ${props["debuggingEnabled"]}");
-}
-
-
-handleGetGlobalVarsResponse(Map response) {
-  List globals = response["result"]["globals"];
-  for (int i = 0; i < globals.length; i++) {
-    printNamedObject(globals[i]);
-  }
-}
-
-
-handleGetSourceResponse(Map response) {
-  Map result = response["result"];
-  String source = result["text"];
-  print("Source text:\n$source\n--------");
-}
-
-
-handleGetLineTableResponse(Map response) {
-  Map result = response["result"];
-  var info = result["lines"];
-  print("Line info table:\n$info");
-}
-
-
-void handleGetIsolatesResponse(Map response) {
-  Map result = response["result"];
-  List ids = result["isolateIds"];
-  assert(ids != null);
-  print("List of isolates:");
-  for (int id in ids) {
-    TargetIsolate isolate = targetIsolates[id];
-    var state = (isolate != null) ? "running" : "<unknown isolate>";
-    if (isolate != null && isolate.isPaused) {
-      var loc = formatLocation(isolate.pausedLocation);
-      state = "paused at $loc";
-    }
-    var marker = " ";
-    if (currentIsolate != null && id == currentIsolate.id) {
-      marker = "*";
-    }
-    print("$marker $id $state");
-  }
-}
-
-
-void handleGetLibraryResponse(Map response) {
-  Map result = response["result"];
-  List libs = result["libraries"];
-  print("Loaded libraries:");
-  print(libs);
-  for (int i = 0; i < libs.length; i++) {
-    print("  ${libs[i]["id"]} ${libs[i]["url"]}");
-  }
-}
-
-
-void handleGetScriptsResponse(Map response) {
-  Map result = response["result"];
-  List urls = result["urls"];
-  print("Loaded scripts:");
-  for (int i = 0; i < urls.length; i++) {
-    print("  $i ${urls[i]}");
-  }
-}
-
-
-void handleEvalResponse(Map response) {
-  Map result = response["result"];
-  print(remoteObject(result));
-}
-
-
-void handleSetBpResponse(Map response) {
-  Map result = response["result"];
-  var id = result["breakpointId"];
-  assert(id != null);
-  print("Set BP $id");
-}
-
-
-void handleGenericResponse(Map response) {
-  if (response["error"] != null) {
-    print("Error: ${response["error"]}");
-  }
-}
-
-void handleResumedResponse(Map response) {
-  if (response["error"] != null) {
-    print("Error: ${response["error"]}");
-    return;
-  }
-  assert(currentIsolate != null);
-  currentIsolate.pausedLocation = null;
-}
-
-
-void handleStackTraceResponse(Map response) {
-  Map result = response["result"];
-  List callFrames = result["callFrames"];
-  assert(callFrames != null);
-  printStackTrace(callFrames);
-}
-
-
-void printStackFrame(frame_num, Map frame) {
-  var fname = frame["functionName"];
-  var loc = formatLocation(frame["location"]);
-  print("#${_leftJustify(frame_num,2)} $fname at $loc");
-  List locals = frame["locals"];
-  for (int i = 0; i < locals.length; i++) {
-    printNamedObject(locals[i]);
-  }
-}
-
-
-void printStackTrace(List frames) {
-  for (int i = 0; i < frames.length; i++) {
-    printStackFrame(i, frames[i]);
-  }
-}
-
-
-Map<int, int> parseLineNumberTable(List<List<int>> table) {
-  Map tokenToLine = {};
-  for (var line in table) {
-    // Each entry begins with a line number...
-    var lineNumber = line[0];
-    for (var pos = 1; pos < line.length; pos += 2) {
-      // ...and is followed by (token offset, col number) pairs.
-      // We ignore the column numbers.
-      var tokenOffset = line[pos];
-      tokenToLine[tokenOffset] = lineNumber;
-    }
-  }
-  return tokenToLine;
-}
-
-
-Future<TargetScript> getTargetScript(Map location) {
-  var isolate = targetIsolates[currentIsolate.id];
-  var url = location['url'];
-  var script = isolate.scripts[url];
-  if (script != null) {
-    return new Future.value(script);
-  }
-  script = new TargetScript();
-
-  // Ask the vm for the source and line number table.
-  var sourceCmd = {
-    "id": seqNum++,
-    "command":  "getScriptSource",
-    "params": { "isolateId": currentIsolate.id,
-                "libraryId": location['libraryId'],
-                "url": url } };
-
-  var lineNumberCmd = {
-    "id": seqNum++,
-    "command":  "getLineNumberTable",
-    "params": { "isolateId": currentIsolate.id,
-                "libraryId": location['libraryId'],
-                "url": url } };
-
-  // Send the source command
-  var sourceResponse = sendCmd(sourceCmd).then((response) {
-      Map result = response["result"];
-      script.source = result['text'];
-      // Line numbers are 1-based so add a dummy for line 0.
-      script.lineToSource = [''];
-      script.lineToSource.addAll(script.source.split('\n'));
-    });
-
-  // Send the line numbers command
-  var lineNumberResponse = sendCmd(lineNumberCmd).then((response) {
-      Map result = response["result"];
-      script.tokenToLine = parseLineNumberTable(result['lines']);
-    });
-
-  return Future.wait([sourceResponse, lineNumberResponse]).then((_) {
-      // When both commands complete, cache the result.
-      isolate.scripts[url] = script;
-      return script;
-    });
-}
-
-
-Future printLocation(String label, Map location) {
-  // Figure out the line number.
-  return getTargetScript(location).then((script) {
-      var lineNumber = script.tokenToLine[location['tokenOffset']];
-      var text = script.lineToSource[lineNumber];
-      if (label != null) {
-        var fileName = location['url'].split("/").last;
-        print("$label \n"
-              "    at $fileName:$lineNumber");
-      }
-      print("${_leftJustify(lineNumber, 8)}$text");
-    });
-}
-
-
-Future handlePausedEvent(msg) {
-  assert(msg["params"] != null);
-  var reason = msg["params"]["reason"];
-  int isolateId = msg["params"]["isolateId"];
-  assert(isolateId != null);
-  var isolate = targetIsolates[isolateId];
-  assert(isolate != null);
-  assert(!isolate.isPaused);
-  var location = msg["params"]["location"];;
-  setCurrentIsolate(isolate);
-  isolate.pausedLocation = (location == null) ? UnknownLocation : location;
-  if (reason == "breakpoint") {
-    assert(location != null);
-    var bpId = (msg["params"]["breakpointId"]);
-    var label = (bpId != null) ? "Breakpoint $bpId" : null;
-    return printLocation(label, location);
-  } else if (reason == "interrupted") {
-    assert(location != null);
-    return printLocation("Interrupted", location);
-  } else {
-    assert(reason == "exception");
-    var excObj = msg["params"]["exception"];
-    print("Isolate $isolateId paused on exception");
-    print(remoteObject(excObj));
-    return new Future.value();
-  }
-}
-
-void handleIsolateEvent(msg) {
-  Map params = msg["params"];
-  assert(params != null);
-  var isolateId = params["id"];
-  var reason = params["reason"];
-  if (reason == "created") {
-    print("Isolate $isolateId has been created.");
-    assert(targetIsolates[isolateId] == null);
-    targetIsolates[isolateId] = new TargetIsolate(isolateId);
-  } else {
-    assert(reason == "shutdown");
-    var isolate = targetIsolates.remove(isolateId);
-    assert(isolate != null);
-    if (isolate == mainIsolate) {
-      mainIsolate = null;
-      print("Main isolate ${isolate.id} has terminated.");
-    } else {
-      print("Isolate ${isolate.id} has terminated.");
-    }
-    if (isolate == currentIsolate) {
-      currentIsolate = mainIsolate;
-      if (currentIsolate == null && !targetIsolates.isEmpty) {
-        currentIsolate = targetIsolates.values.first;
-      }
-      if (currentIsolate != null) {
-        print("Setting current isolate to ${currentIsolate.id}.");
-      } else {
-        print("All isolates have terminated.");
-      }
-    }
-  }
-}
-
-void processVmMessage(String jsonString) {
-  var msg = JSON.decode(jsonString);
-  if (msg == null) {
-    return;
-  }
-  var event = msg["event"];
-  if (event == "isolate") {
-    cmdo.hide();
-    handleIsolateEvent(msg);
-    cmdo.show();
-    return;
-  }
-  if (event == "paused") {
-    cmdo.hide();
-    handlePausedEvent(msg).then((_) {
-        cmdo.show();
-      });
-    return;
-  }
-  if (event == "breakpointResolved") {
-    Map params = msg["params"];
-    assert(params != null);
-    var isolateId = params["isolateId"];
-    var location = formatLocation(params["location"]);
-    cmdo.hide();
-    print("Breakpoint ${params["breakpointId"]} resolved in isolate $isolateId"
-          " at $location.");
-    cmdo.show();
-    return;
-  }
-  if (msg["id"] != null) {
-    var id = msg["id"];
-    if (outstandingCommands.containsKey(id)) {
-      var completer = outstandingCommands.remove(id);
-      if (msg["error"] != null) {
-        print("VM says: ${msg["error"]}");
-        // TODO(turnidge): Rework how hide/show happens.  For now we
-        // show here explicitly.
-        cmdo.show();
-      } else {
-        completer.complete(msg);
-      }
-    }
-  }
-}
-
-bool haveGarbageVmData() {
-  if (vmData == null || vmData.length == 0) return false;
-  var i = 0, char = " ";
-  while (i < vmData.length) {
-    char = vmData[i];
-    if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
-    i++;
-  }
-  if (i >= vmData.length) {
-    return false;
-  } else {
-    return char != "{";
-  }
-}
-
-
-void processVmData(String data) {
-  if (vmData == null || vmData.length == 0) {
-    vmData = data;
-  } else {
-    vmData = vmData + data;
-  }
-  if (haveGarbageVmData()) {
-    print("Error: have garbage data from VM: '$vmData'");
-    return;
-  }
-  int msg_len = jsonObjectLength(vmData);
-  if (printMessages && msg_len == 0) {
-    print("have partial or illegal json message"
-          " of ${vmData.length} chars:\n'$vmData'");
-    return;
-  }
-  while (msg_len > 0 && msg_len <= vmData.length) {
-    if (msg_len == vmData.length) {
-      if (printMessages) { print("have one full message:\n$vmData"); }
-      processVmMessage(vmData);
-      vmData = null;
-      return;
-    }
-    if (printMessages) { print("at least one message: '$vmData'"); }
-    var msg = vmData.substring(0, msg_len);
-    if (printMessages) { print("first message: $msg"); }
-    vmData = vmData.substring(msg_len);
-    if (haveGarbageVmData()) {
-      print("Error: garbage data after previous message: '$vmData'");
-      print("Previous message was: '$msg'");
-      return;
-    }
-    processVmMessage(msg);
-    msg_len = jsonObjectLength(vmData);
-  }
-  if (printMessages) { print("leftover vm data '$vmData'"); }
-}
-
-/**
- * Skip past a JSON object value.
- * The object value must start with '{' and continues to the
- * matching '}'. No attempt is made to otherwise validate the contents
- * as JSON. If it is invalid, a later [parseJson] will fail.
- */
-int jsonObjectLength(String string) {
-  int skipWhitespace(int index) {
-    while (index < string.length) {
-      String char = string[index];
-      if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
-      index++;
-    }
-    return index;
-  }
-  int skipString(int index) {
-    assert(string[index - 1] == '"');
-    while (index < string.length) {
-      String char = string[index];
-      if (char == '"') return index + 1;
-      if (char == r'\') index++;
-      if (index == string.length) return index;
-      index++;
-    }
-    return index;
-  }
-  int index = 0;
-  index = skipWhitespace(index);
-  // Bail out if the first non-whitespace character isn't '{'.
-  if (index == string.length || string[index] != '{') return 0;
-  int nesting = 0;
-  while (index < string.length) {
-    String char = string[index++];
-    if (char == '{') {
-      nesting++;
-    } else if (char == '}') {
-      nesting--;
-      if (nesting == 0) return index;
-    } else if (char == '"') {
-      // Strings can contain braces. Skip their content.
-      index = skipString(index);
-    }
-  }
-  return 0;
-}
-
-List<String> debuggerCommandCompleter(List<String> commandParts) {
-  List<String> completions = new List<String>();
-
-  // TODO(turnidge): Have a global command table and use it to for
-  // help messages, command completion, and command dispatching.  For now
-  // we hardcode the list here.
-  //
-  // TODO(turnidge): Implement completion for arguments as well.
-  List<String> oldCommands = ['bt', 'r', 's', 'so', 'si', 'sbp', 'rbp',
-                              'po', 'eval', 'pl', 'pc', 'll', 'plib', 'slib',
-                              'pg', 'ls', 'gs', 'tok', 'epi', 'li', 'i' ];
-
-  // Completion of first word in the command.
-  if (commandParts.length == 1) {
-    String prefix = commandParts.last;
-    for (var command in oldCommands) {
-      if (command.startsWith(prefix)) {
-        completions.add(command);
-      }
-    }
-    for (var command in commandList) {
-      if (command.name.startsWith(prefix)) {
-        completions.add(command.name);
-      }
-    }
-  }
-
-  return completions;
-}
-
-Future closeCommando() {
-  var subscription = cmdSubscription;
-  cmdSubscription = null;
-  cmdo = null;
-
-  var future = subscription.cancel();
-  if (future != null) {
-    return future;
-  } else {
-    return new Future.value();
-  }
-}
-
-
-Future openVmSocket(int attempt) {
-  return Socket.connect("127.0.0.1", debugPort).then(
-      setupVmSocket,
-      onError: (e) {
-        // We were unable to connect to the debugger's port.  Try again.
-        retryOpenVmSocket(e, attempt);
-      });
-}
-
-
-void setupVmSocket(Socket s) {
-  vmSock = s;
-  vmSock.setOption(SocketOption.TCP_NODELAY, true);
-  var stringStream = vmSock.transform(UTF8.decoder);
-  outstandingCommands = new Map<int, Completer>();
-  vmSubscription = stringStream.listen(
-      (String data) {
-        processVmData(data);
-      },
-      onDone: () {
-        cmdo.hide();
-        if (verbose) {
-          print("VM debugger connection closed");
-        }
-        closeVmSocket().then((_) {
-            cmdo.show();
-          });
-      },
-      onError: (err) {
-        cmdo.hide();
-        // TODO(floitsch): do we want to print the stack trace?
-        print("Error in debug connection: $err");
-
-        // TODO(turnidge): Kill the debugged process here?
-        closeVmSocket().then((_) {
-            cmdo.show();
-          });
-      });
-}
-
-
-Future retryOpenVmSocket(error, int attempt) {
-  var delay;
-  if (attempt < 10) {
-    delay = new Duration(milliseconds:10);
-  } else if (attempt < 20) {
-    delay = new Duration(seconds:1);
-  } else {
-    // Too many retries.  Give up.
-    //
-    // TODO(turnidge): Kill the debugged process here?
-    print('Timed out waiting for debugger to start.\nError: $e');
-    return closeVmSocket();
-  }
-  // Wait and retry.
-  return new Future.delayed(delay, () {
-      openVmSocket(attempt + 1);
-    });
-}
-
-
-Future closeVmSocket() {
-  if (vmSubscription == null) {
-    // Already closed, nothing to do.
-    assert(vmSock == null);
-    return new Future.value();
-  }
-
-  isDebugging = false;
-  var subscription = vmSubscription;
-  var sock = vmSock;
-
-  // Wait for the socket to close and the subscription to be
-  // cancelled.  Perhaps overkill, but it means we know these will be
-  // done.
-  //
-  // This is uglier than it needs to be since cancel can return null.
-  var cleanupFutures = [sock.close()];
-  var future = subscription.cancel();
-  if (future != null) {
-    cleanupFutures.add(future);
-  }
-
-  vmSubscription = null;
-  vmSock = null;
-  outstandingCommands = null;
-  return Future.wait(cleanupFutures);
-}
-
-void debuggerError(self, parent, zone, error, StackTrace trace) {
-  print('\n--------\nExiting due to unexpected error:\n'
-        '  $error\n$trace\n');
-  debuggerQuit();
-}
-
-Future debuggerQuit() {
-  // Kill target process, if any.
-  if (targetProcess != null) {
-    if (!targetProcess.kill()) {
-      print('Unable to kill process ${targetProcess.pid}');
-    }
-  }
-
-  // Restore terminal settings, close connections.
-  return Future.wait([closeCommando(), closeVmSocket()]).then((_) {
-      exit(0);
-
-      // Unreachable.
-      return new Future.value();
-    });
-}
-
-
-void parseArgs(List<String> args) {
-  int pos = 0;
-  settings['vm'] = Platform.executable;
-  while (pos < args.length && args[pos].startsWith('-')) {
-    pos++;
-  }
-  if (pos < args.length) {
-    settings['vmargs'] = args.getRange(0, pos).join(' ');
-    settings['script'] = args[pos];
-    settings['args'] = args.getRange(pos + 1, args.length).join(' ');
-  }
-}
-
-void main(List<String> args) {
-  // Setup a zone which will exit the debugger cleanly on any uncaught
-  // exception.
-  var zone = Zone.ROOT.fork(specification:new ZoneSpecification(
-      handleUncaughtError: debuggerError));
-
-  zone.run(() {
-      parseArgs(args);
-      cmdo = new Commando(completer: debuggerCommandCompleter);
-      cmdSubscription = cmdo.commands.listen(processCommand,
-                                             onError: processError,
-                                             onDone: processDone);
-    });
-}
diff --git a/tools/ddbg/lib/commando.dart b/tools/ddbg/lib/commando.dart
deleted file mode 100644
index f3ff3ea..0000000
--- a/tools/ddbg/lib/commando.dart
+++ /dev/null
@@ -1,731 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math';
-
-import 'terminfo.dart';
-
-typedef List<String> CommandCompleter(List<String> commandParts);
-
-class Commando {
-  // Ctrl keys
-  static const runeCtrlA   = 0x01;
-  static const runeCtrlB   = 0x02;
-  static const runeCtrlD   = 0x04;
-  static const runeCtrlE   = 0x05;
-  static const runeCtrlF   = 0x06;
-  static const runeTAB     = 0x09;
-  static const runeNewline = 0x0a;
-  static const runeCtrlK   = 0x0b;
-  static const runeCtrlL   = 0x0c;
-  static const runeCtrlN   = 0x0e;
-  static const runeCtrlP   = 0x10;
-  static const runeCtrlU   = 0x15;
-  static const runeCtrlY   = 0x19;
-  static const runeESC     = 0x1b;
-  static const runeSpace   = 0x20;
-  static const runeDEL     = 0x7F;
-
-  StreamController<String> _commandController;
-
-  Stream get commands => _commandController.stream;
-
-  Commando({consoleIn,
-            consoleOut,
-            this.prompt : '> ',
-          this.completer : null}) {
-    _stdin = (consoleIn != null ? consoleIn : stdin);
-    _stdout = (consoleOut != null ? consoleOut : stdout);
-    _commandController = new StreamController<String>(
-        onCancel: _onCancel);
-    _stdin.echoMode = false;
-    _stdin.lineMode = false;
-    _screenWidth = _term.cols - 1;
-    _writePrompt();
-    // TODO(turnidge): Handle errors in _stdin here.
-    _stdinSubscription =
-        _stdin.transform(UTF8.decoder).listen(_handleText, onDone:_done);
-  }
-
-  Future _onCancel() {
-    _stdin.echoMode = true;
-    _stdin.lineMode = true;
-    var future = _stdinSubscription.cancel();
-    if (future != null) {
-      return future;
-    } else {
-      return new Future.value();
-    }
-  }
-
-  // Before terminating, call close() to restore terminal settings.
-  void _done() {
-    _onCancel().then((_) {
-        _commandController.close();
-      });
-  }
-  
-  void _handleText(String text) {
-    try {
-      if (!_promptShown) {
-        _bufferedInput.write(text);
-        return;
-      }
-
-      var runes = text.runes.toList();
-      var pos = 0;
-      while (pos < runes.length) {
-        if (!_promptShown) {
-          // A command was processed which hid the prompt.  Buffer
-          // the rest of the input.
-          //
-          // TODO(turnidge): Here and elsewhere in the file I pass
-          // runes to String.fromCharCodes.  Does this work?
-          _bufferedInput.write(
-              new String.fromCharCodes(runes.skip(pos)));
-          return;
-        }
-
-        var rune = runes[pos];
-
-        // Count consecutive tabs because double-tab is meaningful.
-        if (rune == runeTAB) {
-          _tabCount++;
-        } else {
-          _tabCount = 0;
-        }
-
-        if (_isControlRune(rune)) {
-          pos += _handleControlSequence(runes, pos);
-        } else {
-          pos += _handleRegularSequence(runes, pos);
-        }
-      }
-    } catch(e, trace) {
-      _commandController.addError(e, trace);
-    }
-  }
-
-  int _handleControlSequence(List<int> runes, int pos) {
-    var runesConsumed = 1;  // Most common result.
-    var char = runes[pos];
-    switch (char) {
-      case runeCtrlA:
-        _home();
-        break;
-           
-      case runeCtrlB:
-        _leftArrow();
-        break;
-
-      case runeCtrlD:
-        if (_currentLine.length == 0) {
-          // ^D on an empty line means quit.
-          _stdout.writeln("^D");
-          _done();
-        } else {
-          _delete();
-        }
-        break;
-           
-      case runeCtrlE:
-        _end();
-        break;
-           
-      case runeCtrlF:
-        _rightArrow();
-        break;
-
-      case runeTAB:
-        if (_complete(_tabCount > 1)) {
-          _tabCount = 0;
-        }
-        break;
-      
-      case runeNewline:
-        _newline();
-        break;
-      
-      case runeCtrlK:
-        _kill();
-        break;
-           
-      case runeCtrlL:
-        _clearScreen();
-        break;
-           
-      case runeCtrlN:
-        _historyNext();
-        break;
-
-      case runeCtrlP:
-        _historyPrevious();
-        break;
-
-      case runeCtrlU:
-        _clearLine();
-        break;
-           
-      case runeCtrlY:
-        _yank();
-        break;
-           
-      case runeESC:
-        // Check to see if this is an arrow key.
-        if (pos + 2 < runes.length &&  // must be a 3 char sequence.
-            runes[pos + 1] == 0x5b) {  // second char must be '['.
-          switch (runes[pos + 2]) {
-            case 0x41:  // ^[[A = up arrow
-              _historyPrevious();
-              runesConsumed = 3;
-              break;
-
-            case 0x42:  // ^[[B = down arrow
-              _historyNext();
-              runesConsumed = 3;
-              break;
-
-            case 0x43:  // ^[[C = right arrow
-              _rightArrow();
-              runesConsumed = 3;
-              break;
-        
-            case 0x44:  // ^[[D = left arrow
-              _leftArrow();
-              runesConsumed = 3;
-              break;
-
-            default:
-              // Ignore the escape character.
-              break;
-          }
-        }
-        break;
-
-      case runeDEL:
-        _backspace();
-        break;
-
-      default:
-        // Ignore the escape character.
-        break;
-    }
-    return runesConsumed;
-  }
-
-  int _handleRegularSequence(List<int> runes, int pos) {
-    var len = pos + 1;
-    while (len < runes.length && !_isControlRune(runes[len])) {
-      len++;
-    }
-    _addChars(runes.getRange(pos, len));
-    return len;
-  }
-
-  bool _isControlRune(int char) {
-    return (char >= 0x00 && char < 0x20) || (char == 0x7f);
-  }
-
-  void _writePromptAndLine() {
-    _writePrompt();
-    var pos = _writeRange(_currentLine, 0, _currentLine.length);
-    _cursorPos = _move(pos, _cursorPos);
-  }
-
-  void _writePrompt() {
-    _stdout.write(prompt);
-  }
-
-  void _addChars(Iterable<int> chars) {
-    var newLine = [];
-    newLine..addAll(_currentLine.take(_cursorPos))
-           ..addAll(chars)
-           ..addAll(_currentLine.skip(_cursorPos));
-    _update(newLine, (_cursorPos + chars.length));
-  }
-
-  void _backspace() {
-    if (_cursorPos == 0) {
-      return;
-    }
-
-    var newLine = [];
-    newLine..addAll(_currentLine.take(_cursorPos - 1))
-           ..addAll(_currentLine.skip(_cursorPos));
-    _update(newLine, (_cursorPos - 1));
-  }
-
-  void _delete() {
-    if (_cursorPos == _currentLine.length) {
-      return;
-    }
-
-    var newLine = [];
-    newLine..addAll(_currentLine.take(_cursorPos))
-           ..addAll(_currentLine.skip(_cursorPos + 1));
-    _update(newLine, _cursorPos);
-  }
-
-  void _home() {
-    _updatePos(0);
-  }
-
-  void _end() {
-    _updatePos(_currentLine.length);
-  }
-
-  void _clearScreen() {
-    _stdout.write(_term.clear);
-    _term.resize();
-    _screenWidth = _term.cols - 1;
-    _writePromptAndLine();
-  }
-
-  void _kill() {
-    var newLine = [];
-    newLine.addAll(_currentLine.take(_cursorPos));
-    _killBuffer = _currentLine.skip(_cursorPos).toList();
-    _update(newLine, _cursorPos);
-  }
-
-  void _clearLine() {
-    _update([], 0);
-  }
-
-  void _yank() {
-    var newLine = [];
-    newLine..addAll(_currentLine.take(_cursorPos))
-           ..addAll(_killBuffer)
-           ..addAll(_currentLine.skip(_cursorPos));
-    _update(newLine, (_cursorPos + _killBuffer.length));
-  }
-
-  static String _trimLeadingSpaces(String line) {
-    bool _isSpace(int rune) {
-      return rune == runeSpace;
-    }
-    return new String.fromCharCodes(line.runes.skipWhile(_isSpace));
-  }
-
-  static String _sharedPrefix(String one, String two) {
-    var len = min(one.length, two.length);
-    var runesOne = one.runes.toList();
-    var runesTwo = two.runes.toList();
-    var pos;
-    for (pos = 0; pos < len; pos++) {
-      if (runesOne[pos] != runesTwo[pos]) {
-        break;
-      }
-    }
-    var shared =  new String.fromCharCodes(runesOne.take(pos));
-    return shared;
-  }
-
-  bool _complete(bool showCompletions) {
-    if (completer == null) {
-      return false;
-    }
-
-    var linePrefix = _currentLine.take(_cursorPos).toList();
-    List<String> commandParts =
-        _trimLeadingSpaces(new String.fromCharCodes(linePrefix)).split(' ');
-    List<String> completionList = completer(commandParts);
-    var completion = '';
-
-    if (completionList.length == 0) {
-      // The current line admits no possible completion.
-      return false;
-
-    } else if (completionList.length == 1) {
-      // There is a single, non-ambiguous completion for the current line.
-      completion = completionList[0];
-
-      // If we are at the end of the line, add a space to signal that
-      // the completion is unambiguous.
-      if (_currentLine.length == _cursorPos) {
-        completion = completion + ' ';
-      }
-    } else {
-      // There are ambiguous completions. Find the longest common
-      // shared prefix of all of the completions.
-      completion = completionList.fold(completionList[0], _sharedPrefix);
-    }
-
-    var lastWord = commandParts.last;
-    if (completion == lastWord) {
-      // The completion does not add anything.
-      if (showCompletions) {
-        // User hit double-TAB.  Show them all possible completions.
-        _move(_cursorPos, _currentLine.length);
-        _stdout.writeln();
-        _stdout.writeln(completionList);
-        _writePromptAndLine();
-      }
-      return false;
-    } else {
-      // Apply the current completion.
-      var completionRunes = completion.runes.toList();
-
-      var newLine = [];
-      newLine..addAll(linePrefix)
-             ..addAll(completionRunes.skip(lastWord.length))
-             ..addAll(_currentLine.skip(_cursorPos));
-      _update(newLine, _cursorPos + completionRunes.length - lastWord.length);
-      return true;
-    }
-  }
-
-  void _newline() {
-    _addLineToHistory(_currentLine);
-    _linePos = _lines.length;
-
-    _end();
-    _stdout.writeln();
-
-    // Call the user's command handler.
-    _commandController.add(new String.fromCharCodes(_currentLine));
-    
-    _currentLine = [];
-    _cursorPos = 0;
-    if (_promptShown) {
-      _writePrompt();
-    }
-  }
-
-  void _leftArrow() {
-    _updatePos(_cursorPos - 1);
-  }
-
-  void _rightArrow() {
-    _updatePos(_cursorPos + 1);
-  }
-
-  void _addLineToHistory(List<int> line) {
-    if (_tempLineAdded) {
-      _lines.removeLast();
-      _tempLineAdded = false;
-    }
-    if (line.length > 0) {
-      _lines.add(line);
-    }
-  }
-
-  void _addTempLineToHistory(List<int> line) {
-    _lines.add(line);
-    _tempLineAdded = true;
-  }
-
-  void _replaceHistory(List<int> line, int linePos) {
-    _lines[linePos] = line;
-  }
-
-  void _historyPrevious() {
-    if (_linePos == 0) {
-      return;
-    }
-
-    if (_linePos == _lines.length) {
-      // The current in-progress line gets temporarily stored in history.
-      _addTempLineToHistory(_currentLine);
-    } else {
-      // Any edits get committed to history.
-      _replaceHistory(_currentLine, _linePos);
-    }
-
-    _linePos -= 1;
-    var line = _lines[_linePos];
-    _update(line, line.length);
-  }
-
-  void _historyNext() {
-    // For the very first command, _linePos (0) will exceed
-    // (_lines.length - 1) (-1) so we use a ">=" here instead of an "==".
-    if (_linePos >= (_lines.length - 1)) {
-      return;
-    }
-
-    // Any edits get committed to history.
-    _replaceHistory(_currentLine, _linePos);
-
-    _linePos += 1;
-    var line = _lines[_linePos];
-    _update(line, line.length);
-  }
-
-  void _updatePos(int newCursorPos) {
-    if (newCursorPos < 0) {
-      return;
-    }
-    if (newCursorPos > _currentLine.length) {
-      return;
-    }
-
-    _cursorPos = _move(_cursorPos, newCursorPos);
-  }
-
-  void _update(List<int> newLine, int newCursorPos) {
-    var pos = _cursorPos;
-    var diffPos;
-    var sharedLen = min(_currentLine.length, newLine.length);
-
-    // Find first difference.
-    for (diffPos = 0; diffPos < sharedLen; diffPos++) {
-      if (_currentLine[diffPos] != newLine[diffPos]) {
-        break;
-      }
-    }
-
-    // Move the cursor to where the difference begins.
-    pos = _move(pos, diffPos);
-
-    // Write the new text.
-    pos = _writeRange(newLine, pos, newLine.length);
-
-    // Clear any extra characters at the end.
-    pos = _clearRange(pos, _currentLine.length);
-
-    // Move the cursor back to the input point.
-    _cursorPos = _move(pos, newCursorPos);
-    _currentLine = newLine;    
-  }
-  
-  void hide() {
-    if (!_promptShown) {
-      return;
-    }
-    _promptShown = false;
-    // We need to erase everything, including the prompt.
-    var curLine = _getLine(_cursorPos);
-    var lastLine = _getLine(_currentLine.length);
-
-    // Go to last line.
-    if (curLine < lastLine) {
-      for (var i = 0; i < (lastLine - curLine); i++) {
-        // This moves us to column 0.
-        _stdout.write(_term.cursorDown);
-      }
-      curLine = lastLine;
-    } else {
-      // Move to column 0.
-      _stdout.write('\r');
-    }
-
-    // Work our way up, clearing lines.
-    while (true) {
-      _stdout.write(_term.clrEOL);
-      if (curLine > 0) {
-        _stdout.write(_term.cursorUp);
-      } else {
-        break;
-      }
-    }
-  }
-
-  void show() {
-    if (_promptShown) {
-      return;
-    }
-    _promptShown = true;
-    _writePromptAndLine();
-
-    // If input was buffered while the prompt was hidden, process it
-    // now.
-    if (!_bufferedInput.isEmpty) {
-      var input = _bufferedInput.toString();
-      _bufferedInput.clear();
-      _handleText(input);
-    }
-  }
-
-  int _writeRange(List<int> text, int pos, int writeToPos) {
-    if (pos >= writeToPos) {
-      return pos;
-    }
-    while (pos < writeToPos) {
-      var margin = _nextMargin(pos);
-      var limit = min(writeToPos, margin);
-      _stdout.write(new String.fromCharCodes(text.getRange(pos, limit)));
-      pos = limit;
-      if (pos == margin) {
-        _stdout.write('\n');
-      }
-    }
-    return pos;
-  }
-
-  int _clearRange(int pos, int clearToPos) {
-    if (pos >= clearToPos) {
-      return pos;
-    }
-    while (true) {
-      var limit = _nextMargin(pos);
-      _stdout.write(_term.clrEOL);
-      if (limit >= clearToPos) {
-        return pos;
-      }
-      _stdout.write('\n');
-      pos = limit;
-    }
-  }
-
-  int _move(int pos, int newPos) {
-    if (pos == newPos) {
-      return pos;
-    }
-
-    var curCol = _getCol(pos);
-    var curLine = _getLine(pos);
-    var newCol = _getCol(newPos);
-    var newLine = _getLine(newPos);
-
-    if (curLine > newLine) {
-      for (var i = 0; i < (curLine - newLine); i++) {
-        _stdout.write(_term.cursorUp);
-      }
-    }
-    if (curLine < newLine) {
-      for (var i = 0; i < (newLine - curLine); i++) {
-        _stdout.write(_term.cursorDown);
-      }
-
-      // Moving down resets column to zero, oddly.
-      curCol = 0;
-    }
-    if (curCol > newCol) {
-      for (var i = 0; i < (curCol - newCol); i++) {
-        _stdout.write(_term.cursorBack);
-      }
-    }
-    if (curCol < newCol) {
-      for (var i = 0; i < (newCol - curCol); i++) {
-        _stdout.write(_term.cursorForward);
-      }
-    }
-
-    return newPos;
-  }
-        
-  int _nextMargin(int pos) {
-    var truePos = pos + prompt.length;
-    return ((truePos ~/ _screenWidth) + 1) * _screenWidth - prompt.length;
-  }
-
-  int _getLine(int pos) {
-    var truePos = pos + prompt.length;
-    return truePos ~/ _screenWidth;
-  }
-
-  int _getCol(int pos) {
-    var truePos = pos + prompt.length;
-    return truePos % _screenWidth;
-  }
-
-  Stdin _stdin;
-  StreamSubscription _stdinSubscription;
-  IOSink _stdout;
-  final String prompt;
-  bool _promptShown = true;
-  final CommandCompleter completer;
-  TermInfo _term = new TermInfo();
-
-  // TODO(turnidge): See if we can get screen resize events.
-  int _screenWidth;
-  List<int> _currentLine = [];  // A list of runes.
-  StringBuffer _bufferedInput = new StringBuffer();
-  List<List<int>> _lines = [];
-
-  // When using the command history, the current line is temporarily
-  // added to the history to allow the user to return to it.  This
-  // values tracks whether the history has a temporary line at the end.
-  bool _tempLineAdded = false;
-  int _linePos = 0;
-  int _cursorPos = 0;
-  int _tabCount = 0;
-  List<int> _killBuffer = [];
-}
-
-
-// Demo code.
-
-
-List<String> _myCompleter(List<String> commandTokens) {
-  List<String> completions = new List<String>();
-
-  // First word completions.
-  if (commandTokens.length <= 1) {
-    String prefix = '';
-    if (commandTokens.length == 1) {
-      prefix = commandTokens.first;
-    }
-    if ('quit'.startsWith(prefix)) {
-      completions.add('quit');
-    }
-    if ('help'.startsWith(prefix)) {
-      completions.add('help');
-    }
-    if ('happyface'.startsWith(prefix)) {
-      completions.add('happyface');
-    }
-  }
-
-  // Complete 'foobar' or 'gondola' anywhere in string.
-  String lastWord = commandTokens.last;
-  if ('foobar'.startsWith(lastWord)) {
-    completions.add('foobar');
-  }
-  if ('gondola'.startsWith(lastWord)) {
-    completions.add('gondola');
-  }
-
-  return completions;
-}
-
-
-int _helpCount = 0;
-Commando cmdo;
-
-
-void _handleCommand(String rawCommand) {
-  String command = rawCommand.trim();
-  cmdo.hide();
-  if (command == 'quit') {
-    cmdo.close().then((_) {
-        print('Exiting');
-      });
-  } else if (command == 'help') {
-    switch (_helpCount) {
-      case 0:
-        print('I will not help you.');
-        break;
-      case 1:
-        print('I mean it.');
-        break;
-      case 2:
-        print('Seriously.');
-        break;
-      case 100:
-        print('Well now.');
-        break;
-      default:
-        print("Okay.  Type 'quit' to quit");
-        break;
-    }
-    _helpCount++;
-  } else if (command == 'happyface') {
-    print(':-)');
-  } else {
-    print('Received command($command)');
-  }
-  cmdo.show();
-}
-
-
-void main() {
-  print('[Commando demo]');
-  cmdo = new Commando(completer:_myCompleter);
-  cmdo.commands.listen(_handleCommand);
-}
diff --git a/tools/ddbg/lib/terminfo.dart b/tools/ddbg/lib/terminfo.dart
deleted file mode 100644
index 4521031..0000000
--- a/tools/ddbg/lib/terminfo.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:io';
-
-int _tputGetInteger(String capName) {
-  var result = Process.runSync('tput',  ['$capName'], stdoutEncoding:UTF8);
-  if (result.exitCode != 0) {
-    return 0;
-  }
-  return int.parse(result.stdout);
-}
-
-String _tputGetSequence(String capName) {
-  var result = Process.runSync('tput',  ['$capName'], stdoutEncoding:UTF8);
-  if (result.exitCode != 0) {
-    return '';
-  }
-  return result.stdout;
-}
-
-class TermInfo {
-  TermInfo() {
-    resize();
-  }
-
-  int get lines => _lines;
-  int get cols => _cols;
-
-  int _lines;
-  int _cols;
-
-  void resize() {
-    _lines = _tputGetInteger('lines');
-    _cols = _tputGetInteger('cols');
-  }
-
-  // Back one character.
-  final String cursorBack = _tputGetSequence('cub1');
-
-  // Forward one character.
-  final String cursorForward = _tputGetSequence('cuf1');
-
-  // Up one character.
-  final String cursorUp = _tputGetSequence('cuu1');
-
-  // Down one character.
-  final String cursorDown = _tputGetSequence('cud1');
-
-  // Clear to end of line.
-  final String clrEOL = _tputGetSequence('el');
-
-  // Clear screen and home cursor.
-  final String clear = _tputGetSequence('clear');
-}
diff --git a/tools/ddbg_service/HACKING.txt b/tools/ddbg_service/HACKING.txt
deleted file mode 100644
index 27c47d7..0000000
--- a/tools/ddbg_service/HACKING.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-ddbg_service
----
-
-ddbg_service is a command line debugger for the Dart VM implemented
-using the Dart VM Service.  It is still being written and is not ready
-for use.
-
-Assumptions:
-You are running pub from the latest dev channel release of Dart Editor.
-
-Before running ddbg_service, you will need to run get packages from pub:
-
-    pub upgrade
-
-Then launch ddbg_service:
-
-    dart bin/ddbg_service.dart
diff --git a/tools/ddbg_service/bin/ddbg_service.dart b/tools/ddbg_service/bin/ddbg_service.dart
deleted file mode 100644
index 0023ba3..0000000
--- a/tools/ddbg_service/bin/ddbg_service.dart
+++ /dev/null
@@ -1,34 +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.
-
-// A command line debugger implemented using the VM Service protocol.
-
-library ddbg2;
-
-import "dart:async";
-
-import 'package:ddbg/debugger.dart';
-
-Debugger debugger;
-
-void onError(self, parent, zone, error, StackTrace trace) {
-  if (debugger != null) {
-    debugger.onUncaughtError(error, trace);
-  } else {
-    print('\n--------\nExiting due to unexpected error:\n'
-          '  $error\n$trace\n');
-    exit();
-  }
-}
-
-void main(List<String> args) {
-  // Setup a zone which will exit the debugger cleanly on any uncaught
-  // exception.
-  var zone = Zone.ROOT.fork(specification:new ZoneSpecification(
-      handleUncaughtError: onError));
-  
-  zone.run(() {
-      debugger = new Debugger();
-  });
-}
diff --git a/tools/ddbg_service/lib/commando.dart b/tools/ddbg_service/lib/commando.dart
deleted file mode 100644
index 3996880..0000000
--- a/tools/ddbg_service/lib/commando.dart
+++ /dev/null
@@ -1,750 +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 commando;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math';
-
-import 'package:ddbg/terminfo.dart';
-
-typedef List<String> CommandCompleter(List<String> commandParts);
-
-class Commando {
-  // Ctrl keys
-  static const runeCtrlA   = 0x01;
-  static const runeCtrlB   = 0x02;
-  static const runeCtrlD   = 0x04;
-  static const runeCtrlE   = 0x05;
-  static const runeCtrlF   = 0x06;
-  static const runeTAB     = 0x09;
-  static const runeNewline = 0x0a;
-  static const runeCtrlK   = 0x0b;
-  static const runeCtrlL   = 0x0c;
-  static const runeCtrlN   = 0x0e;
-  static const runeCtrlP   = 0x10;
-  static const runeCtrlU   = 0x15;
-  static const runeCtrlY   = 0x19;
-  static const runeESC     = 0x1b;
-  static const runeSpace   = 0x20;
-  static const runeDEL     = 0x7F;
-
-  StreamController<String> _commandController;
-
-  Stream get commands => _commandController.stream;
-
-  Commando({consoleIn,
-            consoleOut,
-            this.prompt : '> ',
-          this.completer : null}) {
-    _stdin = (consoleIn != null ? consoleIn : stdin);
-    _stdout = (consoleOut != null ? consoleOut : stdout);
-    _commandController = new StreamController<String>(
-        onCancel: _onCancel);
-    _stdin.echoMode = false;
-    _stdin.lineMode = false;
-    _screenWidth = _term.cols - 1;
-    _writePrompt();
-    // TODO(turnidge): Handle errors in _stdin here.
-    _stdinSubscription =
-        _stdin.transform(UTF8.decoder).listen(_handleText, onDone:_done);
-  }
-
-  Future _onCancel() {
-    _stdin.echoMode = true;
-    _stdin.lineMode = true;
-    var future = _stdinSubscription.cancel();
-    if (future != null) {
-      return future;
-    } else {
-      return new Future.value();
-    }
-  }
-
-  // Before terminating, call close() to restore terminal settings.
-  void _done() {
-    _onCancel().then((_) {
-        _commandController.close();
-      });
-  }
-  
-  void _handleText(String text) {
-    try {
-      if (!_promptShown) {
-        _bufferedInput.write(text);
-        return;
-      }
-
-      var runes = text.runes.toList();
-      var pos = 0;
-      while (pos < runes.length) {
-        if (!_promptShown) {
-          // A command was processed which hid the prompt.  Buffer
-          // the rest of the input.
-          //
-          // TODO(turnidge): Here and elsewhere in the file I pass
-          // runes to String.fromCharCodes.  Does this work?
-          _bufferedInput.write(
-              new String.fromCharCodes(runes.skip(pos)));
-          return;
-        }
-
-        var rune = runes[pos];
-
-        // Count consecutive tabs because double-tab is meaningful.
-        if (rune == runeTAB) {
-          _tabCount++;
-        } else {
-          _tabCount = 0;
-        }
-
-        if (_isControlRune(rune)) {
-          pos += _handleControlSequence(runes, pos);
-        } else {
-          pos += _handleRegularSequence(runes, pos);
-        }
-      }
-    } catch(e, trace) {
-      _commandController.addError(e, trace);
-    }
-  }
-
-  int _handleControlSequence(List<int> runes, int pos) {
-    var runesConsumed = 1;  // Most common result.
-    var char = runes[pos];
-    switch (char) {
-      case runeCtrlA:
-        _home();
-        break;
-           
-      case runeCtrlB:
-        _leftArrow();
-        break;
-
-      case runeCtrlD:
-        if (_currentLine.length == 0) {
-          // ^D on an empty line means quit.
-          _stdout.writeln("^D");
-          _done();
-        } else {
-          _delete();
-        }
-        break;
-           
-      case runeCtrlE:
-        _end();
-        break;
-           
-      case runeCtrlF:
-        _rightArrow();
-        break;
-
-      case runeTAB:
-        _complete(_tabCount > 1);
-        break;
-      
-      case runeNewline:
-        _newline();
-        break;
-      
-      case runeCtrlK:
-        _kill();
-        break;
-           
-      case runeCtrlL:
-        _clearScreen();
-        break;
-           
-      case runeCtrlN:
-        _historyNext();
-        break;
-
-      case runeCtrlP:
-        _historyPrevious();
-        break;
-
-      case runeCtrlU:
-        _clearLine();
-        break;
-           
-      case runeCtrlY:
-        _yank();
-        break;
-           
-      case runeESC:
-        // Check to see if this is an arrow key.
-        if (pos + 2 < runes.length &&  // must be a 3 char sequence.
-            runes[pos + 1] == 0x5b) {  // second char must be '['.
-          switch (runes[pos + 2]) {
-            case 0x41:  // ^[[A = up arrow
-              _historyPrevious();
-              runesConsumed = 3;
-              break;
-
-            case 0x42:  // ^[[B = down arrow
-              _historyNext();
-              runesConsumed = 3;
-              break;
-
-            case 0x43:  // ^[[C = right arrow
-              _rightArrow();
-              runesConsumed = 3;
-              break;
-        
-            case 0x44:  // ^[[D = left arrow
-              _leftArrow();
-              runesConsumed = 3;
-              break;
-
-            default:
-              // Ignore the escape character.
-              break;
-          }
-        }
-        break;
-
-      case runeDEL:
-        _backspace();
-        break;
-
-      default:
-        // Ignore the escape character.
-        break;
-    }
-    return runesConsumed;
-  }
-
-  int _handleRegularSequence(List<int> runes, int pos) {
-    var len = pos + 1;
-    while (len < runes.length && !_isControlRune(runes[len])) {
-      len++;
-    }
-    _addChars(runes.getRange(pos, len));
-    return len;
-  }
-
-  bool _isControlRune(int char) {
-    return (char >= 0x00 && char < 0x20) || (char == 0x7f);
-  }
-
-  void _writePromptAndLine() {
-    _writePrompt();
-    var pos = _writeRange(_currentLine, 0, _currentLine.length);
-    _cursorPos = _move(pos, _cursorPos);
-  }
-
-  void _writePrompt() {
-    _stdout.write(prompt);
-  }
-
-  void _addChars(Iterable<int> chars) {
-    var newLine = [];
-    newLine..addAll(_currentLine.take(_cursorPos))
-           ..addAll(chars)
-           ..addAll(_currentLine.skip(_cursorPos));
-    _update(newLine, (_cursorPos + chars.length));
-  }
-
-  void _backspace() {
-    if (_cursorPos == 0) {
-      return;
-    }
-
-    var newLine = [];
-    newLine..addAll(_currentLine.take(_cursorPos - 1))
-           ..addAll(_currentLine.skip(_cursorPos));
-    _update(newLine, (_cursorPos - 1));
-  }
-
-  void _delete() {
-    if (_cursorPos == _currentLine.length) {
-      return;
-    }
-
-    var newLine = [];
-    newLine..addAll(_currentLine.take(_cursorPos))
-           ..addAll(_currentLine.skip(_cursorPos + 1));
-    _update(newLine, _cursorPos);
-  }
-
-  void _home() {
-    _updatePos(0);
-  }
-
-  void _end() {
-    _updatePos(_currentLine.length);
-  }
-
-  void _clearScreen() {
-    _stdout.write(_term.clear);
-    _term.resize();
-    _screenWidth = _term.cols - 1;
-    _writePromptAndLine();
-  }
-
-  void _kill() {
-    var newLine = [];
-    newLine.addAll(_currentLine.take(_cursorPos));
-    _killBuffer = _currentLine.skip(_cursorPos).toList();
-    _update(newLine, _cursorPos);
-  }
-
-  void _clearLine() {
-    _update([], 0);
-  }
-
-  void _yank() {
-    var newLine = [];
-    newLine..addAll(_currentLine.take(_cursorPos))
-           ..addAll(_killBuffer)
-           ..addAll(_currentLine.skip(_cursorPos));
-    _update(newLine, (_cursorPos + _killBuffer.length));
-  }
-
-  static String _trimLeadingSpaces(String line) {
-    bool _isSpace(int rune) {
-      return rune == runeSpace;
-    }
-    return new String.fromCharCodes(line.runes.skipWhile(_isSpace));
-  }
-
-  static String _sharedPrefix(String one, String two) {
-    var len = min(one.length, two.length);
-    var runesOne = one.runes.toList();
-    var runesTwo = two.runes.toList();
-    var pos;
-    for (pos = 0; pos < len; pos++) {
-      if (runesOne[pos] != runesTwo[pos]) {
-        break;
-      }
-    }
-    var shared =  new String.fromCharCodes(runesOne.take(pos));
-    return shared;
-  }
-
-  void _complete(bool showCompletions) {
-    if (completer == null) {
-      return;
-    }
-
-    var linePrefix = _currentLine.take(_cursorPos).toList();
-    var lineAsString = new String.fromCharCodes(linePrefix);
-    var commandParts = new List.from(lineAsString.split(' ').where((line) {
-          return line != ' ' && line != '';
-        }));
-    if (lineAsString.endsWith(' ')) {
-      // If the current line ends with a space, they are hoping to
-      // complete the next word in the command.  Add an empty string
-      // to the commandParts to signal this to the completer.
-      commandParts.add('');
-    }
-    List<String> completionList = completer(commandParts);
-    var completion = null;
-
-    if (completionList.length == 0) {
-      // The current line admits no possible completion.
-      return;
-
-    } else if (completionList.length == 1) {
-      // There is a single, non-ambiguous completion for the current line.
-      completion = completionList[0];
-
-    } else {
-      // There are ambiguous completions. Find the longest common
-      // shared prefix of all of the completions.
-      completion = completionList.fold(completionList[0], _sharedPrefix);
-    }
-
-    if (showCompletions) {
-      // User hit double-TAB.  Show them all possible completions.
-      completionList.sort((a,b) => a.compareTo(b));
-      _move(_cursorPos, _currentLine.length);
-      _stdout.writeln();
-      _stdout.writeln(completionList);
-      _writePromptAndLine();
-      return;
-
-    } else {
-      // Apply the current completion.
-      var completionRunes = completion.runes.toList();
-
-      var newLine = [];
-      newLine..addAll(completionRunes)
-             ..addAll(_currentLine.skip(_cursorPos));
-      _update(newLine, completionRunes.length);
-      return;
-    }
-  }
-
-  void _newline() {
-    _addLineToHistory(_currentLine);
-    _linePos = _lines.length;
-
-    _end();
-    _stdout.writeln();
-
-    // Call the user's command handler.
-    _commandController.add(new String.fromCharCodes(_currentLine));
-    
-    _currentLine = [];
-    _cursorPos = 0;
-    if (_promptShown) {
-      _writePrompt();
-    }
-  }
-
-  void _leftArrow() {
-    _updatePos(_cursorPos - 1);
-  }
-
-  void _rightArrow() {
-    _updatePos(_cursorPos + 1);
-  }
-
-  void _addLineToHistory(List<int> line) {
-    if (_tempLineAdded) {
-      _lines.removeLast();
-      _tempLineAdded = false;
-    }
-    if (line.length > 0) {
-      _lines.add(line);
-    }
-  }
-
-  void _addTempLineToHistory(List<int> line) {
-    _lines.add(line);
-    _tempLineAdded = true;
-  }
-
-  void _replaceHistory(List<int> line, int linePos) {
-    _lines[linePos] = line;
-  }
-
-  void _historyPrevious() {
-    if (_linePos == 0) {
-      return;
-    }
-
-    if (_linePos == _lines.length) {
-      // The current in-progress line gets temporarily stored in history.
-      _addTempLineToHistory(_currentLine);
-    } else {
-      // Any edits get committed to history.
-      _replaceHistory(_currentLine, _linePos);
-    }
-
-    _linePos -= 1;
-    var line = _lines[_linePos];
-    _update(line, line.length);
-  }
-
-  void _historyNext() {
-    // For the very first command, _linePos (0) will exceed
-    // (_lines.length - 1) (-1) so we use a ">=" here instead of an "==".
-    if (_linePos >= (_lines.length - 1)) {
-      return;
-    }
-
-    // Any edits get committed to history.
-    _replaceHistory(_currentLine, _linePos);
-
-    _linePos += 1;
-    var line = _lines[_linePos];
-    _update(line, line.length);
-  }
-
-  void _updatePos(int newCursorPos) {
-    if (newCursorPos < 0) {
-      return;
-    }
-    if (newCursorPos > _currentLine.length) {
-      return;
-    }
-
-    _cursorPos = _move(_cursorPos, newCursorPos);
-  }
-
-  void _update(List<int> newLine, int newCursorPos) {
-    var pos = _cursorPos;
-    var diffPos;
-    var sharedLen = min(_currentLine.length, newLine.length);
-
-    // Find first difference.
-    for (diffPos = 0; diffPos < sharedLen; diffPos++) {
-      if (_currentLine[diffPos] != newLine[diffPos]) {
-        break;
-      }
-    }
-
-    // Move the cursor to where the difference begins.
-    pos = _move(pos, diffPos);
-
-    // Write the new text.
-    pos = _writeRange(newLine, pos, newLine.length);
-
-    // Clear any extra characters at the end.
-    pos = _clearRange(pos, _currentLine.length);
-
-    // Move the cursor back to the input point.
-    _cursorPos = _move(pos, newCursorPos);
-    _currentLine = newLine;    
-  }
-
-  void print(String text) {
-    bool togglePrompt = _promptShown;
-    if (togglePrompt) {
-      hide();
-    }
-    _stdout.writeln(text);
-    if (togglePrompt) {
-      show();
-    }
-  }
-  
-  void hide() {
-    if (!_promptShown) {
-      return;
-    }
-    _promptShown = false;
-    // We need to erase everything, including the prompt.
-    var curLine = _getLine(_cursorPos);
-    var lastLine = _getLine(_currentLine.length);
-
-    // Go to last line.
-    if (curLine < lastLine) {
-      for (var i = 0; i < (lastLine - curLine); i++) {
-        // This moves us to column 0.
-        _stdout.write(_term.cursorDown);
-      }
-      curLine = lastLine;
-    } else {
-      // Move to column 0.
-      _stdout.write('\r');
-    }
-
-    // Work our way up, clearing lines.
-    while (true) {
-      _stdout.write(_term.clrEOL);
-      if (curLine > 0) {
-        _stdout.write(_term.cursorUp);
-      } else {
-        break;
-      }
-    }
-  }
-
-  void show() {
-    if (_promptShown) {
-      return;
-    }
-    _promptShown = true;
-    _writePromptAndLine();
-
-    // If input was buffered while the prompt was hidden, process it
-    // now.
-    if (!_bufferedInput.isEmpty) {
-      var input = _bufferedInput.toString();
-      _bufferedInput.clear();
-      _handleText(input);
-    }
-  }
-
-  int _writeRange(List<int> text, int pos, int writeToPos) {
-    if (pos >= writeToPos) {
-      return pos;
-    }
-    while (pos < writeToPos) {
-      var margin = _nextMargin(pos);
-      var limit = min(writeToPos, margin);
-      _stdout.write(new String.fromCharCodes(text.getRange(pos, limit)));
-      pos = limit;
-      if (pos == margin) {
-        _stdout.write('\n');
-      }
-    }
-    return pos;
-  }
-
-  int _clearRange(int pos, int clearToPos) {
-    if (pos >= clearToPos) {
-      return pos;
-    }
-    while (true) {
-      var limit = _nextMargin(pos);
-      _stdout.write(_term.clrEOL);
-      if (limit >= clearToPos) {
-        return pos;
-      }
-      _stdout.write('\n');
-      pos = limit;
-    }
-  }
-
-  int _move(int pos, int newPos) {
-    if (pos == newPos) {
-      return pos;
-    }
-
-    var curCol = _getCol(pos);
-    var curLine = _getLine(pos);
-    var newCol = _getCol(newPos);
-    var newLine = _getLine(newPos);
-
-    if (curLine > newLine) {
-      for (var i = 0; i < (curLine - newLine); i++) {
-        _stdout.write(_term.cursorUp);
-      }
-    }
-    if (curLine < newLine) {
-      for (var i = 0; i < (newLine - curLine); i++) {
-        _stdout.write(_term.cursorDown);
-      }
-
-      // Moving down resets column to zero, oddly.
-      curCol = 0;
-    }
-    if (curCol > newCol) {
-      for (var i = 0; i < (curCol - newCol); i++) {
-        _stdout.write(_term.cursorBack);
-      }
-    }
-    if (curCol < newCol) {
-      for (var i = 0; i < (newCol - curCol); i++) {
-        _stdout.write(_term.cursorForward);
-      }
-    }
-
-    return newPos;
-  }
-        
-  int _nextMargin(int pos) {
-    var truePos = pos + prompt.length;
-    return ((truePos ~/ _screenWidth) + 1) * _screenWidth - prompt.length;
-  }
-
-  int _getLine(int pos) {
-    var truePos = pos + prompt.length;
-    return truePos ~/ _screenWidth;
-  }
-
-  int _getCol(int pos) {
-    var truePos = pos + prompt.length;
-    return truePos % _screenWidth;
-  }
-
-  Stdin _stdin;
-  StreamSubscription _stdinSubscription;
-  IOSink _stdout;
-  final String prompt;
-  bool _promptShown = true;
-  final CommandCompleter completer;
-  TermInfo _term = new TermInfo();
-
-  // TODO(turnidge): See if we can get screen resize events.
-  int _screenWidth;
-  List<int> _currentLine = [];  // A list of runes.
-  StringBuffer _bufferedInput = new StringBuffer();
-  List<List<int>> _lines = [];
-
-  // When using the command history, the current line is temporarily
-  // added to the history to allow the user to return to it.  This
-  // values tracks whether the history has a temporary line at the end.
-  bool _tempLineAdded = false;
-  int _linePos = 0;
-  int _cursorPos = 0;
-  int _tabCount = 0;
-  List<int> _killBuffer = [];
-}
-
-
-// Demo code.
-
-
-List<String> _myCompleter(List<String> commandTokens) {
-  List<String> completions = new List<String>();
-
-  // First word completions.
-  if (commandTokens.length <= 1) {
-    String prefix = '';
-    if (commandTokens.length == 1) {
-      prefix = commandTokens.first;
-    }
-    if ('quit'.startsWith(prefix)) {
-      completions.add('quit');
-    }
-    if ('help'.startsWith(prefix)) {
-      completions.add('help');
-    }
-    if ('happyface'.startsWith(prefix)) {
-      completions.add('happyface');
-    }
-  }
-
-  // Complete 'foobar' or 'gondola' anywhere in string.
-  String lastWord = commandTokens.last;
-  if ('foobar'.startsWith(lastWord)) {
-    completions.add('foobar');
-  }
-  if ('gondola'.startsWith(lastWord)) {
-    completions.add('gondola');
-  }
-
-  return completions;
-}
-
-
-int _helpCount = 0;
-Commando cmdo;
-var cmdoSubscription;
-
-
-void _handleCommand(String rawCommand) {
-  String command = rawCommand.trim();
-  cmdo.hide();
-  if (command == 'quit') {
-    var future = cmdoSubscription.cancel();
-    if (future != null) {
-      future.then((_) {
-          print('Exiting');
-          exit(0);
-        });
-    } else {
-      print('Exiting');
-      exit(0);
-    }
-  } else if (command == 'help') {
-    switch (_helpCount) {
-      case 0:
-        print('I will not help you.');
-        break;
-      case 1:
-        print('I mean it.');
-        break;
-      case 2:
-        print('Seriously.');
-        break;
-      case 100:
-        print('Well now.');
-        break;
-      default:
-        print("Okay.  Type 'quit' to quit");
-        break;
-    }
-    _helpCount++;
-  } else if (command == 'happyface') {
-    print(':-)');
-  } else {
-    print('Received command($command)');
-  }
-  cmdo.show();
-}
-
-
-void main() {
-  print('[Commando demo]');
-  cmdo = new Commando(completer:_myCompleter);
-  cmdoSubscription = cmdo.commands.listen(_handleCommand);
-}
diff --git a/tools/ddbg_service/lib/debugger.dart b/tools/ddbg_service/lib/debugger.dart
deleted file mode 100644
index d3b0f9c..0000000
--- a/tools/ddbg_service/lib/debugger.dart
+++ /dev/null
@@ -1,478 +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 debugger;
-
-import "dart:async";
-import "dart:io";
-
-import "package:ddbg/commando.dart";
-import "package:observatory/service_io.dart";
-
-class Debugger {
-  Commando cmdo;
-  var _cmdoSubscription;
-
-  CommandList _commands;
-
-  VM _vm;
-  VM get vm => _vm;
-  set vm(VM vm) {
-    if (_vm == vm) {
-      // Do nothing.
-      return;
-    }
-    if (_vm != null) {
-      _vm.disconnect();
-    }
-    if (vm != null) {
-      vm.onConnect.then(_vmConnected);
-      vm.onDisconnect.then(_vmDisconnected);
-      vm.errors.stream.listen(_onServiceError);
-      vm.exceptions.stream.listen(_onServiceException);
-      vm.events.stream.listen(_onServiceEvent);
-    }
-    _vm = vm;
-  }
-
-  _vmConnected(VM vm) {
-    cmdo.print('Connected to vm');
-  }
-
-  _vmDisconnected(VM vm) {
-    cmdo.print('Disconnected from vm');
-  }
-
-  _onServiceError(ServiceError error) {
-    cmdo.print('error $error');
-  }
-
-  _onServiceException(ServiceException exception) {
-    cmdo.print('${exception.message}');
-  }
-
-  _onServiceEvent(ServiceEvent event) {
-    switch (event.eventType) {
-      case 'GC':
-        // Ignore GC events for now.
-        break;
-      default:
-        cmdo.print('event $event');
-        break;
-    }
-  }
-
-  VM _isolate;
-  VM get isolate => _isolate;
-  set isolate(Isolate isolate) {
-    _isolate = isolate;
-    cmdo.print('Current isolate is now isolate ${getIsolateIndex(_isolate)}');
-  }
-
-  Map _isolateIndexMap = new Map();
-  int _nextIsolateIndex = 0;
-  int getIsolateIndex(Isolate isolate) {
-    var index = _isolateIndexMap[isolate.id];
-    if (index == null) {
-      index = _nextIsolateIndex++;
-      _isolateIndexMap[isolate.id] = index;
-    }
-    return index;
-  }
-
-  void onUncaughtError(error, StackTrace trace) {
-    if (error is ServiceException ||
-        error is ServiceError) {
-      // These are handled elsewhere.  Ignore.
-      return;
-    }
-    cmdo.print('\n--------\nExiting due to unexpected error:\n'
-                '  $error\n$trace\n');
-    quit();
-  }
-
-  Debugger() {
-    cmdo = new Commando(completer: _completeCommand);
-    _cmdoSubscription = cmdo.commands.listen(_processCommand,
-                                             onError: _cmdoError,
-                                             onDone: _cmdoDone);
-    _commands = new CommandList();
-    _commands.register(new AttachCommand());
-    _commands.register(new DetachCommand());
-    _commands.register(new HelpCommand(_commands));
-    _commands.register(new IsolateCommand());
-    _commands.register(new QuitCommand());
-  }
-
-  Future _closeCmdo() {
-    var sub = _cmdoSubscription;
-    _cmdoSubscription = null;
-    cmdo = null;
-
-    var future = sub.cancel();
-    if (future != null) {
-      return future;
-    } else {
-      return new Future.value();
-    }
-  }
-
-  Future quit() {
-    return Future.wait([_closeCmdo()]).then((_) {
-        exit(0);
-      });
-  }
-
-  void _cmdoError(error, StackTrace trace) {
-    cmdo.print('\n--------\nExiting due to unexpected error:\n'
-               '  $error\n$trace\n');
-    quit();
-  }
-
-  void _cmdoDone() {
-    quit();
-  }
-
-  List<String> _completeCommand(List<String> commandParts) {
-    return _commands.complete(commandParts);
-  }
-
-  void _processCommand(String cmdLine) {
-    void huh() {
-      cmdo.print("'$cmdLine' not understood, try 'help' for help.");
-    }
-
-    cmdo.hide();
-    cmdLine = cmdLine.trim();
-    var args = cmdLine.split(' ');
-    if (args.length == 0) {
-      return;
-    }
-    var command = args[0];
-    var matches  = _commands.match(command, true);
-    if (matches.length == 0) {
-      huh();
-      cmdo.show();
-    } else if (matches.length == 1) {
-      matches[0].run(this, args).then((_) {
-          cmdo.show();
-        });
-    } else {
-      var matchNames = matches.map((handler) => handler.name);
-      cmdo.print("Ambigous command '$command' : ${matchNames.toList()}");
-      cmdo.show();
-    }
-  }
-
-}
-
-// Every debugger command extends this base class.
-abstract class Command {
-  String get name;
-  String get helpShort;
-  void printHelp(Debugger debugger, List<String> args);
-  Future run(Debugger debugger, List<String> args);
-  List<String> complete(List<String> commandParts) {
-    return ["$name ${commandParts.join(' ')}"];
-
-  }
-}
-
-class AttachCommand extends Command {
-  final name = 'attach';
-  final helpShort = 'Attach to a running Dart VM';
-  void printHelp(Debugger debugger, List<String> args) {
-    debugger.cmdo.print('''
------ attach -----
-
-Attach to the Dart VM running at the indicated host:port. If no
-host:port is provided, attach to the VM running on the default port.
-
-Usage:
-  attach
-  attach <host:port>
-''');
-  }
-
-  Future run(Debugger debugger, List<String> args) {
-    var cmdo = debugger.cmdo;
-    if (args.length > 2) {
-      cmdo.print('$name expects 0 or 1 arguments');
-      return new Future.value();
-    }
-    String hostPort = 'localhost:8181';
-    if (args.length > 1) {
-      hostPort = args[1];
-    }
-
-    debugger.vm = new WebSocketVM(new WebSocketVMTarget('ws://${hostPort}/ws'));
-    return debugger.vm.load().then((vm) {
-        if (debugger.isolate == null) {
-          for (var isolate in vm.isolates) {
-            if (isolate.name == 'root') {
-              debugger.isolate = isolate;
-            }
-          }
-        }
-      });
-  }
-}
-
-class CommandList {
-  List _commands = new List<Command>();
-
-  void register(Command cmd) {
-    _commands.add(cmd);
-  }
-
-  List<Command> match(String commandName, bool exactMatchWins) {
-    var matches = [];
-    for (var command in _commands) {
-      if (command.name.startsWith(commandName)) {
-        if (exactMatchWins && command.name == commandName) {
-          // Exact match
-          return [command];
-        } else {
-          matches.add(command);
-        }
-      }
-    }
-    return matches;
-  }
-
-  List<String> complete(List<String> commandParts) {
-    var completions = new List<String>();
-    String prefix = commandParts[0];
-    for (var command in _commands) {
-      if (command.name.startsWith(prefix)) {
-        completions.addAll(command.complete(commandParts.sublist(1)));
-      }
-    }
-    return completions;
-  }
-
-  void printHelp(Debugger debugger, List<String> args) {
-    var cmdo = debugger.cmdo;
-    if (args.length <= 1) {
-      cmdo.print("\nDebugger commands:\n");
-      for (var command in _commands) {
-        cmdo.print('  ${command.name.padRight(11)} ${command.helpShort}');
-      }
-      cmdo.print("For more information about a particular command, type:\n\n"
-                  "  help <command>\n");
-
-      cmdo.print("Commands may be abbreviated: e.g. type 'h' for 'help.\n");
-    } else {
-      var commandName = args[1];
-      var matches =match(commandName, true);
-      if (matches.length == 0) {
-        cmdo.print("Command '$commandName' not recognized.  "
-                    "Try 'help' for a list of commands.");
-      } else {
-        for (var command in matches) {
-          command.printHelp(debugger, args);
-        }
-      }
-    }
-  }
-}
-
-class DetachCommand extends Command {
-  final name = 'detach';
-  final helpShort = 'Detach from a running Dart VM';
-  void printHelp(Debugger debugger, List<String> args) {
-    debugger.cmdo.print('''
------ detach -----
-
-Detach from the Dart VM.
-
-Usage:
-  detach
-''');
-  }
-
-  Future run(Debugger debugger, List<String> args) {
-    var cmdo = debugger.cmdo;
-    if (args.length > 1) {
-      cmdo.print('$name expects no arguments');
-      return new Future.value();
-    }
-    if (debugger.vm == null) {
-      cmdo.print('No VM is attached');
-    } else {
-      debugger.vm = null;
-    }
-    return new Future.value();
-  }
-}
-
-class HelpCommand extends Command {
-  HelpCommand(this._commands);
-  final CommandList _commands;
-
-  final name = 'help';
-  final helpShort = 'Show a list of debugger commands';
-  void printHelp(Debugger debugger, List<String> args) {
-    debugger.cmdo.print('''
------ help -----
-
-Show a list of debugger commands or get more information about a
-particular command.
-
-Usage:
-  help
-  help <command>
-''');
-  }
-
-  Future run(Debugger debugger, List<String> args) {
-    _commands.printHelp(debugger, args);
-    return new Future.value();
-  }
-
-  List<String> complete(List<String> commandParts) {
-    if (commandParts.isEmpty) {
-      return ['$name '];
-    }
-    return _commands.complete(commandParts).map((value) {
-        return '$name $value';
-      });
-  }
-}
-
-class IsolateCommand extends Command {
-  final name = 'isolate';
-  final helpShort = 'Isolate control';
-  void printHelp(Debugger debugger, List<String> args) {
-    debugger.cmdo.print('''
------ isolate -----
-
-List all isolates.
-
-Usage:
-  isolate
-  isolate list
-
-Set current isolate.
-
-Usage:
-  isolate <id>
-''');
-  }
-
-  Future run(Debugger debugger, List<String> args) {
-    var cmdo = debugger.cmdo;
-    if (args.length == 1 ||
-        (args.length == 2 && args[1] == 'list')) {
-      return _listIsolates(debugger);
-    } else if (args.length == 2) {
-      cmdo.print('UNIMPLEMENTED');
-      return new Future.value();
-    } else {
-      if (args.length > 1) {
-        cmdo.print('Unrecognized isolate command');
-        printHelp(debugger, []);
-        return new Future.value();
-      }
-    }
-  }
-    
-  Future _listIsolates(Debugger debugger) {
-    var cmdo = debugger.cmdo;
-    if (debugger.vm == null) {
-      cmdo.print('No VM is attached');
-      return new Future.value();
-    }
-    return debugger.vm.reload().then((vm) {
-        // Sort the isolates by their indices.
-        var isolates = vm.isolates.toList();
-        isolates.sort((iso1, iso2) {
-            return (debugger.getIsolateIndex(iso1) -
-                    debugger.getIsolateIndex(iso2));
-          });
-
-        StringBuffer sb = new StringBuffer();
-        cmdo.print('  ID       NAME         STATE');
-        cmdo.print('-----------------------------------------------');
-        for (var isolate in isolates) {
-          if (isolate == debugger.isolate) {
-            sb.write('* ');
-          } else {
-            sb.write('  ');
-          }
-          sb.write(debugger.getIsolateIndex(isolate).toString().padRight(8));
-          sb.write(' ');
-          sb.write(isolate.name.padRight(12));
-          sb.write(' ');
-          if (isolate.pauseEvent != null) {
-            switch (isolate.pauseEvent.eventType) {
-              case 'IsolateCreated':
-                sb.write('paused at isolate start');
-                break;
-              case 'IsolateShutdown':
-                sb.write('paused at isolate exit');
-                break;
-              case 'IsolateInterrupted':
-                sb.write('paused');
-                break;
-              case 'BreakpointReached':
-                sb.write('paused by breakpoint');
-                break;
-              case 'ExceptionThrown':
-                sb.write('paused by exception');
-                break;
-              default:
-                sb.write('paused by unknown cause');
-                break;
-            }
-          } else if (isolate.running) {
-            sb.write('running');
-          } else if (isolate.idle) {
-            sb.write('idle');
-          } else if (isolate.loading) {
-            // TODO(turnidge): This is weird in a command line debugger.
-            sb.write('(not available)');
-          }
-          sb.write('\n');
-        }
-        cmdo.print(sb);
-      });
-    return new Future.value();
-  }
-
-  List<String> complete(List<String> commandParts) {
-    if (commandParts.isEmpty) {
-      return ['$name ${commandParts.join(" ")}'];
-    } else {
-      var completions =  _commands.complete(commandParts);
-      return completions.map((completion) {
-          return '$name $completion';
-        });
-    }
-  }
-}
-
-class QuitCommand extends Command {
-  final name = 'quit';
-  final helpShort = 'Quit the debugger.';
-  void printHelp(Debugger debugger, List<String> args) {
-    debugger.cmdo.print('''
------ quit -----
-
-Quit the debugger.
-
-Usage:
-  quit
-''');
-  }
-
-  Future run(Debugger debugger, List<String> args) {
-    var cmdo = debugger.cmdo;
-    if (args.length > 1) {
-      cmdo.print("Unexpected arguments to $name command.");
-      return new Future.value();
-    }
-    return debugger.quit();
-  }
-}
diff --git a/tools/ddbg_service/lib/terminfo.dart b/tools/ddbg_service/lib/terminfo.dart
deleted file mode 100644
index 0ec8860..0000000
--- a/tools/ddbg_service/lib/terminfo.dart
+++ /dev/null
@@ -1,59 +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 terminfo;
-
-import 'dart:convert';
-import 'dart:io';
-
-int _tputGetInteger(String capName) {
-  var result = Process.runSync('tput',  ['$capName'], stdoutEncoding:UTF8);
-  if (result.exitCode != 0) {
-    return 0;
-  }
-  return int.parse(result.stdout);
-}
-
-String _tputGetSequence(String capName) {
-  var result = Process.runSync('tput',  ['$capName'], stdoutEncoding:UTF8);
-  if (result.exitCode != 0) {
-    return '';
-  }
-  return result.stdout;
-}
-
-class TermInfo {
-  TermInfo() {
-    resize();
-  }
-
-  int get lines => _lines;
-  int get cols => _cols;
-
-  int _lines;
-  int _cols;
-
-  void resize() {
-    _lines = _tputGetInteger('lines');
-    _cols = _tputGetInteger('cols');
-  }
-
-  // Back one character.
-  final String cursorBack = _tputGetSequence('cub1');
-
-  // Forward one character.
-  final String cursorForward = _tputGetSequence('cuf1');
-
-  // Up one character.
-  final String cursorUp = _tputGetSequence('cuu1');
-
-  // Down one character.
-  final String cursorDown = _tputGetSequence('cud1');
-
-  // Clear to end of line.
-  final String clrEOL = _tputGetSequence('el');
-
-  // Clear screen and home cursor.
-  final String clear = _tputGetSequence('clear');
-}
diff --git a/tools/ddbg_service/pubspec.yaml b/tools/ddbg_service/pubspec.yaml
deleted file mode 100644
index f6b93de..0000000
--- a/tools/ddbg_service/pubspec.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: ddbg
-description: A command-line Dart debugger
-dependencies:
-  logging: any
-  observatory:
-    path: /Users/turnidge/ws/dart-repo/dart/runtime/bin/vmservice/observatory
-#dev_dependencies:
-#  unittest: any
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 3ec5f48..fbb0e6b 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -13,8 +13,8 @@
   "dartium_chromium_branch": "master",
   "dartium_chromium_commit": "62a7524d4f71c9e0858d24b0aa1bbff3a2d09bff",
   "chromium_base_revision": "297060",
-  "dartium_webkit_branch": "/blink/branches/dart/2171_4",
-  "dartium_webkit_revision": "202698",
+  "dartium_webkit_branch": "/blink/branches/dart/dartium",
+  "dartium_webkit_revision": "202748",
 
   # We use mirrors of all github repos to guarantee reproducibility and
   # consistency between what users see and what the bots see.
@@ -33,10 +33,10 @@
   "args_tag": "@0.13.0",
   "barback_rev" : "@29ee90dbcf77cfd64632fa2797a4c8a4f29a4b51",
   "charcode_tag": "@1.1.0",
-  "collection_rev": "@1da9a07f32efa2ba0c391b289e2037391e31da0e",
+  "collection_rev": "@f6135e6350c63eb3f4dd12953b8d4363faff16fc",
   "crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
   "csslib_tag" : "@0.12.0",
-  "dart2js_info_rev" : "@c4ad464717e3a304fb0d44a6937c25ff2049b863",
+  "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
   "html_tag" : "@0.12.1+1",
   "http_rev" : "@9b93e1542c753090c50b46ef1592d44bc858bfe7",
@@ -49,13 +49,14 @@
   "mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
   "metatest_rev": "@e5aa8e4e19fc4188ac2f6d38368a47d8f07c3df1",
   "oauth2_rev": "@1bff41f4d54505c36f2d1a001b83b8b745c452f5",
-  "observatory_pub_packages_rev": "@5c199c5954146747f75ed127871207718dc87786",
+  "observatory_pub_packages_rev": "@cf90eb9077177d3d6b3fd5e8289477c2385c026a",
   "package_config_rev": "@0.1.3",
   "path_rev": "@b657c0854d1cf41c014986fa9d2321f1173df805",
   "plugin_tag": "@0.1.0",
   "pool_rev": "@22e12aeb16ad0b626900dbe79e4a25391ddfb28c",
   "pub_rev": "@9d707158fedc86fc2b02f62cdfe804902b098d9d",
   "pub_semver_tag": "@1.2.0",
+  "quiver_tag": "@0.21.4",
   "shelf_rev": "@1e87b79b21ac5e6fa2f93576d6c06eaa65285ef4",
   "shelf_web_socket_rev": "@ff170cec2c0e4e5722cdf47c557be63b5035a602",
   "source_span_rev": "@42501132e43599a151ba6727d340e44442f86c05",
@@ -68,9 +69,9 @@
   "yaml_rev": "@563a5ffd4a800a2897b8f4dd6b19f2a370df2f2b",
   "zlib_rev": "@c3d0a6190f2f8c924a05ab6cc97b8f975bddd33f",
   "web_components_rev": "@0e636b534d9b12c9e96f841e6679398e91a986ec",
+  "WebCore_rev": "@4f90b41b0165f23f412cecdba07b7d81d3fbb5b5",
 
-  "co19_rev": "@ead3698f33d2cd41e75b6ce5d4a1203767cedd50",
-  "fake_async_rev": "@38614",
+  "co19_rev": "@3ed795ea02e022ef19c77cf1b6095b7c8f5584d0",
 })
 
 def massage_deps(deps):
@@ -156,6 +157,10 @@
       (Var("github_mirror") % "pub") + Var("pub_rev"),
   "src/dart/third_party/pkg/pub_semver":
       (Var("github_mirror") % "pub_semver") + Var("pub_semver_tag"),
+  "src/dart/third_party/pkg/quiver":
+      Var("chromium_git")
+      + "/external/github.com/google/quiver-dart.git"
+      + Var("quiver_tag"),
   "src/dart/third_party/pkg/shelf":
       (Var("github_mirror") % "shelf") + Var("shelf_rev"),
   "src/dart/third_party/pkg/shelf_web_socket":
@@ -182,11 +187,7 @@
       (Var("github_mirror") % "test") + Var("unittest_tag"),
 
   "src/dart/third_party/WebCore":
-    "http://dart.googlecode.com/svn/third_party/WebCore",
-
-  "src/dart/third_party/pkg/fake_async":
-    "http://dart.googlecode.com/svn/third_party/fake_async" +
-    Var("fake_async_rev"),
+    "https://github.com/dart-lang/webcore.git" + Var("WebCore_rev"),
 
   "src/dart/tests/co19/src":
       (Var("github_mirror") % "co19") + Var("co19_rev"),
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index cbe7eb3..5b936a6 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -140,7 +140,8 @@
         " * See also:",
         " *",
         " * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.",
-        " * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.",
+        " * * [CanvasGradient](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)",
+        " *   from WHATWG.",
         " * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.",
         " */"
       ],
@@ -184,7 +185,8 @@
         " *",
         " * See also:",
         " * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.",
-        " * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.",
+        " * * [CanvasPattern](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)",
+        " *   from WHATWG.",
         " * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.",
         " */"
       ]
@@ -212,9 +214,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Current default path]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#current-default-path)",
-          "   * from WHATWG.",
+          "   * * [Current default",
+          "   *   path](https://html.spec.whatwg.org/multipage/scripting.html#current-default-path)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "imageSmoothingEnabled": [
@@ -224,9 +226,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Image smoothing]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)",
-          "   * from WHATWG.",
+          "   * * [Image",
+          "   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "webkitBackingStorePixelRatio": [
@@ -236,8 +238,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [High DPI Canvas tutorial]",
-          "   * (http://www.html5rocks.com/en/tutorials/canvas/hidpi/) from HTML5Rocks.",
+          "   * * [High DPI Canvas",
+          "   *   tutorial](http://www.html5rocks.com/en/tutorials/canvas/hidpi/)",
+          "   *   from HTML5Rocks.",
           "   */"
         ]
       }
@@ -629,13 +632,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragenterEvent": [
@@ -645,13 +648,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragEvent": [
@@ -664,13 +667,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "draggable": [
@@ -679,13 +682,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragleaveEvent": [
@@ -695,13 +698,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragoverEvent": [
@@ -711,13 +714,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dragstartEvent": [
@@ -726,13 +729,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "dropEvent": [
@@ -742,13 +745,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "errorEvent": [
@@ -774,12 +777,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Element.getBoundingClientRect]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)",
-          "   * from MDN.",
-          "   * * [The getBoundingClientRect() method]",
-          "   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)",
-          "   * from W3C.",
+          "   * * [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)",
+          "   *   from MDN.",
+          "   * * [The getBoundingClientRect()",
+          "   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)",
+          "   *   from W3C.",
           "   */"
         ],
         "getClientRects": [
@@ -789,12 +791,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Element.getClientRects]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)",
-          "   * from MDN.",
-          "   * * [The getClientRects() method]",
-          "   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)",
-          "   * from W3C.",
+          "   * * [Element.getClientRects](https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)",
+          "   *   from MDN.",
+          "   * * [The getClientRects()",
+          "   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)",
+          "   *   from W3C.",
           "   */"
         ],
         "getDestinationInsertionPoints": [
@@ -804,9 +805,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Shadow DOM specification]",
-          "   * (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)",
-          "   * from W3C.",
+          "   * * [Shadow DOM",
+          "   *   specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)",
+          "   *   from W3C.",
           "   */"
         ],
         "getElementsByClassName": [
@@ -815,11 +816,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [getElementsByClassName]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)",
-          "   * from MDN.",
-          "   * * [DOM specification]",
-          "   * (http://www.w3.org/TR/domcore/) from W3C.",
+          "   * * [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)",
+          "   *   from MDN.",
+          "   * * [DOM specification](http://www.w3.org/TR/domcore/) from W3C.",
           "   */"
         ],
         "hidden": [
@@ -828,9 +827,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Hidden attribute specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#the-hidden-attribute)",
-          "   * from WHATWG.",
+          "   * * [Hidden attribute",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "inputEvent": [
@@ -847,8 +846,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Input method editor specification]",
-          "   * (http://www.w3.org/TR/ime-api/) from W3C.",
+          "   * * [Input method editor",
+          "   *   specification](http://www.w3.org/TR/ime-api/) from W3C.",
           "   */"
         ],
         "invalidEvent": [
@@ -990,13 +989,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragend": [
@@ -1006,13 +1005,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragenter": [
@@ -1022,13 +1021,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragleave": [
@@ -1038,13 +1037,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragover": [
@@ -1054,13 +1053,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondragstart": [
@@ -1070,13 +1069,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "ondrop": [
@@ -1086,13 +1085,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "onerror": [
@@ -1207,11 +1206,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Using custom pseudo elements]",
-          "   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/#toc-custom-pseduo)",
-          "   * from HTML5Rocks.",
-          "   * * [Custom pseudo-elements]",
-          "   * (http://www.w3.org/TR/shadow-dom/#custom-pseudo-elements) from W3C.",
+          "   * * [Using custom pseudo",
+          "   *   elements](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/#toc-custom-pseduo)",
+          "   *   from HTML5Rocks.",
+          "   * * [Custom pseudo-elements](http://www.w3.org/TR/shadow-dom/#custom-pseudo-elements)",
+          "   *   from W3C.",
           "   */"
         ],
         "querySelector": [
@@ -1246,8 +1245,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [scrollByLines]",
-          "   * (http://docs.webplatform.org/wiki/dom/methods/scrollByLines) from WebPlatform.org.",
+          "   * * [scrollByLines](http://docs.webplatform.org/wiki/dom/methods/scrollByLines)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "scrollByPages": [
@@ -1256,8 +1255,7 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [scrollByPages]",
-          "   * (http://docs.webplatform.org/wiki/dom/methods/scrollByPages) from WebPlatform.org.",
+          "   * * [scrollByPages](http://docs.webplatform.org/wiki/dom/methods/scrollByPages) from WebPlatform.org.",
           "   */"
         ],
         "scrollEvent": [
@@ -1355,9 +1353,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The translate attribute]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-translate-attribute)",
-          "   * from WHATWG.",
+          "   * * [The translate",
+          "   *   attribute](https://html.spec.whatwg.org/multipage/dom.html#the-translate-attribute)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "webkitdropzone": [
@@ -1367,13 +1365,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Drag and drop sample]",
-          "   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)",
-          "   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
-          "   * from HTML5Rocks.",
-          "   * * [Drag and drop specification]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)",
-          "   * from WHATWG.",
+          "   * * [Drag and drop",
+          "   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)",
+          "   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Drag and drop",
+          "   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "webkitfullscreenchangeEvent": [
@@ -1398,11 +1396,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [CSS regions and exclusions tutorial]",
-          "   * (http://www.html5rocks.com/en/tutorials/regions/adobe/) from HTML5Rocks.",
-          "   * * [Regions](http://html.adobe.com/webplatform/layout/regions/) from Adobe.",
-          "   * * [CSS regions specification]",
-          "   * (http://www.w3.org/TR/css3-regions/) from W3C.",
+          "   * * [CSS regions and exclusions",
+          "   *   tutorial](http://www.html5rocks.com/en/tutorials/regions/adobe/) from HTML5Rocks.",
+          "   * * [Regions](http://webplatform.adobe.com/regions/) from Adobe.",
+          "   * * [CSS regions specification](http://www.w3.org/TR/css3-regions/) from W3C.",
           "   */"
         ],
         "webkitRegionOverset": [
@@ -1416,11 +1413,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [CSS regions and exclusions tutorial]",
-          "   * (http://www.html5rocks.com/en/tutorials/regions/adobe/) from HTML5Rocks.",
-          "   * * [Regions](http://html.adobe.com/webplatform/layout/regions/) from Adobe.",
-          "   * * [CSS regions specification]",
-          "   * (http://www.w3.org/TR/css3-regions/) from W3C.",
+          "   * * [CSS regions and exclusions",
+          "   *   tutorial](http://www.html5rocks.com/en/tutorials/regions/adobe/) from HTML5Rocks.",
+          "   * * [Regions](http://webplatform.adobe.com/regions/) from Adobe.",
+          "   * * [CSS regions specification](http://www.w3.org/TR/css3-regions/) from W3C.",
           "   */"
         ],
         "webkitRequestFullscreen": [
@@ -1429,11 +1425,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Using the fullscreen API]",
-          "   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)",
-          "   * tutorial from WebPlatform.org.",
-          "   * * [Fullscreen specification]",
-          "   * (http://www.w3.org/TR/fullscreen/) from W3C.",
+          "   * * [Using the fullscreen",
+          "   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)",
+          "   *   tutorial from WebPlatform.org.",
+          "   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.",
           "   */"
         ],
         "webkitRequestPointerLock": [
@@ -1442,12 +1437,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Pointer lock and first person shooter controls]",
-          "   * (http://www.html5rocks.com/en/tutorials/pointerlock/intro/) tutorial from",
-          "   * HTML5Rocks.",
-          "   *",
-          "   * * [Pointer lock specification]",
-          "   * (http://www.w3.org/TR/pointerlock/) from W3C.",
+          "   * * [Pointer lock and first person shooter",
+          "   *   controls](http://www.html5rocks.com/en/tutorials/pointerlock/intro/)",
+          "   *   tutorial from HTML5Rocks.",
+          "   * * [Pointer lock specification](http://www.w3.org/TR/pointerlock/)",
+          "   *   from W3C.",
           "   */"
         ]
       }
@@ -1460,8 +1454,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Target phase] (http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)",
-          "   * from W3C.",
+          "   * * [Target phase](http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)",
+          "   *   from W3C.",
           "   */"
         ],
         "BUBBLING_PHASE": [
@@ -1470,8 +1464,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)",
-          "   * from W3C.",
+          "   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)",
+          "   *   from W3C.",
           "   */"
         ],
         "CAPTURING_PHASE": [
@@ -1481,8 +1475,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)",
-          "   * from W3C.",
+          "   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)",
+          "   *   from W3C.",
           "   */"
         ],
         "clipboardData": [
@@ -1491,8 +1485,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [clipboardData specification]",
-          "   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.",
+          "   * * [clipboardData specification](http://www.w3.org/TR/clipboard-apis/#attributes)",
+          "   *   from W3C.",
           "   */"
         ],
         "path": [
@@ -1501,9 +1495,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Shadow DOM extensions to Event]",
-          "   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from",
-          "   * W3C.",
+          "   * * [Shadow DOM extensions to",
+          "   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)",
+          "   *   from W3C.",
           "   */"
         ]
       }
@@ -1694,7 +1688,7 @@
         " *",
         " * See also:",
         " *",
-        " * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)",
+        " * * [`<area>`](https://developer.mozilla.org/en-US/docs/HTML/Element/area)",
         " * on MDN.",
         " */"
       ]
@@ -1887,7 +1881,7 @@
         " *",
         " * See also:",
         " *",
-        " * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.",
+        " * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.",
         " * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.",
         " * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.",
         " */"
@@ -2457,9 +2451,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.childNodes]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)",
-          "   * from MDN.",
+          "   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)",
+          "   *   from MDN.",
           "   */"
         ],
         "cloneNode": [
@@ -2471,9 +2464,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.cloneNode]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from",
-          "   * MDN.",
+          "   * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode)",
+          "   *   from MDN.",
           "   */"
         ],
         "contains": [
@@ -2482,8 +2474,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.contains]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.contains) from MDN.",
+          "   * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)",
+          "   *   from MDN.",
           "   */"
         ],
         "firstChild": [
@@ -2492,9 +2484,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.firstChild]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)",
-          "   * from MDN.",
+          "   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)",
+          "   *   from MDN.",
           "   */"
         ],
         "hasChildNodes": [
@@ -2503,9 +2494,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.hasChildNodes]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes) from",
-          "   * MDN.",
+          "   * * [Node.hasChildNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes)",
+          "   *   from MDN.",
           "   */"
         ],
         "insertBefore": [
@@ -2514,9 +2504,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.insertBefore]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) from",
-          "   * MDN.",
+          "   * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore)",
+          "   *   from MDN.",
           "   */"
         ],
         "lastChild": [
@@ -2525,9 +2514,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.lastChild]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)",
-          "   * from MDN.",
+          "   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)",
+          "   *   from MDN.",
           "   */"
         ],
         "nextSibling": [
@@ -2536,9 +2524,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.nextSibling]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)",
-          "   * from MDN.",
+          "   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)",
+          "   *   from MDN.",
           "   */"
         ],
         "nodeName": [
@@ -2549,10 +2536,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.nodeName]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)",
-          "   * from MDN. This page contains a table of [nodeName] values for each",
-          "   * [nodeType].",
+          "   * * [Node.nodeName](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)",
+          "   *   from MDN. This page contains a table of [nodeName] values for each",
+          "   *   [nodeType].",
           "   */"
         ],
         "nodeType": [
@@ -2576,8 +2562,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.nodeType]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType) from MDN.",
+          "   * * [Node.nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType)",
+          "   *   from MDN.",
           "   */"
         ],
         "nodeValue": [
@@ -2588,10 +2574,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.nodeValue]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)",
-          "   * from MDN. This page contains a table of [nodeValue] values for each",
-          "   * [nodeType].",
+          "   * * [Node.nodeValue](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)",
+          "   *   from MDN. This page contains a table of [nodeValue] values for each",
+          "   *   [nodeType].",
           "   */"
         ],
         "ownerDocument": [
@@ -2602,9 +2587,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.ownerDocument]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument) from",
-          "   * MDN.",
+          "   * * [Node.ownerDocument](https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument)",
+          "   *   from MDN.",
           "   */"
         ],
         "parentElement": [
@@ -2616,9 +2600,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.parentElement]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement) from",
-          "   * W3C.",
+          "   * * [Node.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement)",
+          "   *   from W3C.",
           "   */"
         ],
         "parentNode": [
@@ -2627,9 +2610,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.parentNode]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode) from",
-          "   * MDN.",
+          "   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)",
+          "   *   from MDN.",
           "   */"
         ],
         "previousSibling": [
@@ -2638,9 +2620,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.previousSibling]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)",
-          "   * from MDN.",
+          "   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)",
+          "   *   from MDN.",
           "   */"
         ],
         "textContent": [
@@ -2649,9 +2630,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Node.textContent]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from",
-          "   * MDN.",
+          "   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)",
+          "   *   from MDN.",
           "   */"
         ]
       }
@@ -3287,9 +3267,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [User prompts]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)",
-          "   * from WHATWG.",
+          "   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "applicationCache": [
@@ -3298,11 +3277,12 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [A beginner's guide to using the application cache]",
-          "   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.",
-          "   * * [Application cache API]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)",
-          "   * from WHATWG.",
+          "   * * [A beginner's guide to using the application",
+          "   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)",
+          "   *   from HTML5Rocks.",
+          "   * * [Application cache",
+          "   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "confirm": [
@@ -3311,9 +3291,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [User prompts]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)",
-          "   * from WHATWG.",
+          "   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "crypto": [
@@ -3362,12 +3341,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [devicePixelRatio]",
-          "   * (http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html) from",
-          "   * quirksmode.",
-          "   * * [More about devicePixelRatio]",
-          "   * (http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html) from",
-          "   * quirksmode.",
+          "   * * [devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)",
+          "   *   from quirksmode.",
+          "   * * [More about devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html)",
+          "   *   from quirksmode.",
           "   */"
         ],
         "DOMContentLoadedEvent": [
@@ -3384,8 +3361,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.find]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.find) from MDN.",
+          "   * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find)",
+          "   *   from MDN.",
           "   */"
         ],
         "getMatchedCSSRules": [
@@ -3399,9 +3376,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.getSelection]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)",
-          "   * from MDN.",
+          "   * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)",
+          "   *   from MDN.",
           "   */"
         ],
         "hashchangeEvent": [
@@ -3418,9 +3394,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Loading web pages]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)",
-          "   * from WHATWG.",
+          "   * * [Loading web pages](https://html.spec.whatwg.org/multipage/browsers.html)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "innerHeight": [
@@ -3429,9 +3404,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [innerHeight]",
-          "   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight) from",
-          "   * WebPlatform.org.",
+          "   * * [innerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "innerWidth": [
@@ -3440,9 +3414,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [innerWidth]",
-          "   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth) from",
-          "   * WebPlatform.org.",
+          "   * * [innerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "localStorage": [
@@ -3451,13 +3424,12 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [DOM storage guide]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from",
-          "   * MDN.",
-          "   * * [The past, present & future of local storage for web applications]",
-          "   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.",
-          "   * * [Local storage specification]",
-          "   * (http://www.w3.org/TR/webstorage/#the-localstorage-attribute) from W3C.",
+          "   * * [DOM storage guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)",
+          "   *   from MDN.",
+          "   * * [The past, present & future of local storage for web",
+          "   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.",
+          "   * * [Local storage specification](http://www.w3.org/TR/webstorage/#the-localstorage-attribute)",
+          "   *   from W3C.",
           "   */"
         ],
         "locationbar": [
@@ -3466,9 +3438,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "matchMedia": [
@@ -3477,11 +3449,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Testing media queries]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)",
-          "   * from MDN.",
-          "   * * [The MediaQueryList specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.",
+          "   * * [Testing media",
+          "   *   queries](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)",
+          "   *   from MDN.",
+          "   * * [The MediaQueryList",
+          "   *   specification](http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.",
           "   */"
         ],
         "menubar": [
@@ -3490,9 +3462,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "messageEvent": [
@@ -3511,10 +3483,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.moveBy]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy) from MDN.",
-          "   * * [Window.moveBy]",
-          "   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.",
+          "   * * [Window.moveBy](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy)",
+          "   *   from MDN.",
+          "   * * [Window.moveBy](http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.",
           "   */"
         ],
         "name": [
@@ -3523,9 +3494,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window name]",
-          "   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from",
-          "   * WebPlatform.org.",
+          "   * * [Window name](http://docs.webplatform.org/wiki/html/attributes/name_(window))",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "navigator": [
@@ -3534,9 +3504,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The navigator object]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#the-navigator-object)",
-          "   * from WHATWG.",
+          "   * * [The navigator",
+          "   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "offlineEvent": [
@@ -3553,9 +3523,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [offscreenBuffering]",
-          "   * (http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering) from",
-          "   * WebPlatform.org.",
+          "   * * [offscreenBuffering](http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "onabort": [
@@ -3740,9 +3709,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [outerHeight]",
-          "   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight) from",
-          "   * WebPlatform.org.",
+          "   * * [outerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "outerWidth": [
@@ -3751,9 +3719,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [outerWidth]",
-          "   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth) from",
-          "   * WebPlatform.org.",
+          "   * * [outerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "pagehideEvent": [
@@ -3780,10 +3747,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
-          "   * * [scrollX and pageXOffset]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.",
+          "   * * [The Screen interface",
+          "   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [scrollX and",
+          "   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)",
+          "   *   from MDN.",
           "   */"
         ],
         "pageYOffset": [
@@ -3794,10 +3762,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
-          "   * * [scrollY and pageYOffset]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.",
+          "   * * [The Screen interface",
+          "   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [scrollY and",
+          "   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)",
+          "   *   from MDN.",
           "   */"
         ],
         "performance": [
@@ -3806,11 +3775,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Measuring page load speed with navigation timeing]",
-          "   * (http://www.html5rocks.com/en/tutorials/webperformance/basics/) from",
-          "   * HTML5Rocks.",
-          "   * * [Navigation timing specification]",
-          "   * (http://www.w3.org/TR/navigation-timing/) from W3C.",
+          "   * * [Measuring page load speed with navigation",
+          "   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)",
+          "   *   from HTML5Rocks.",
+          "   * * [Navigation timing",
+          "   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.",
           "   */"
         ],
         "PERSISTENT": [
@@ -3820,10 +3789,11 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Exploring the FileSystem APIs]",
-          "   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.",
-          "   * * [File API]",
-          "   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.",
+          "   * * [Exploring the FileSystem",
+          "   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)",
+          "   *   from HTML5Rocks.",
+          "   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)",
+          "   *   from W3C.",
           "   */"
         ],
         "popstateEvent": [
@@ -3840,8 +3810,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.print]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.print) from MDN.",
+          "   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)",
+          "   *   from MDN.",
           "   */"
         ],
         "resizeBy": [
@@ -3850,8 +3820,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window resizeBy] (http://docs.webplatform.org/wiki/dom/methods/resizeBy)",
-          "   * from WebPlatform.org.",
+          "   * * [Window resizeBy](http://docs.webplatform.org/wiki/dom/methods/resizeBy)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "resizeEvent": [
@@ -3868,8 +3838,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window resizeTo] (http://docs.webplatform.org/wiki/dom/methods/resizeTo)",
-          "   * from WebPlatform.org.",
+          "   * * [Window resizeTo](http://docs.webplatform.org/wiki/dom/methods/resizeTo)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "screen": [
@@ -3878,8 +3848,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "screenLeft": [
@@ -3889,8 +3859,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "screenTop": [
@@ -3899,8 +3869,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "screenX": [
@@ -3909,8 +3879,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "screenY": [
@@ -3919,8 +3889,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Screen interface specification]",
-          "   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.",
+          "   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)",
+          "   *   from W3C.",
           "   */"
         ],
         "scroll": [
@@ -3931,8 +3901,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)",
-          "   * from WebPlatform.org.",
+          "   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "scrollbars": [
@@ -3941,9 +3911,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "scrollBy": [
@@ -3952,8 +3922,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)",
-          "   * from WebPlatform.org.",
+          "   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "scrollTo": [
@@ -3964,8 +3934,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)",
-          "   * from WebPlatform.org.",
+          "   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)",
+          "   *   from WebPlatform.org.",
           "   */"
         ],
         "self": [
@@ -3974,8 +3944,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.self]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.",
+          "   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)",
+          "   *   from MDN.",
           "   */"
         ],
         "sessionStorage": [
@@ -3984,13 +3954,13 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [DOM storage guide]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from",
-          "   * MDN.",
-          "   * * [The past, present & future of local storage for web applications]",
-          "   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.",
-          "   * * [Local storage specification]",
-          "   * (http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.",
+          "   * * [DOM storage",
+          "   *   guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)",
+          "   *   from MDN.",
+          "   * * [The past, present & future of local storage for web",
+          "   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.",
+          "   * * [Local storage",
+          "   *   specification](http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.",
           "   */"
         ],
         "showModalDialog": [
@@ -3999,9 +3969,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Dialogs implemented using separate documents]",
-          "   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)",
-          "   * from W3C.",
+          "   * * [Dialogs implemented using separate",
+          "   *   documents](http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)",
+          "   *   from W3C.",
           "   */"
         ],
         "speechSynthesis": [
@@ -4010,9 +3980,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Web speech specification]",
-          "   * (https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)",
-          "   * from W3C.",
+          "   * * [Web speech",
+          "   *   specification](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)",
+          "   *   from W3C.",
           "   */"
         ],
         "status": [
@@ -4024,9 +3994,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "stop": [
@@ -4035,9 +4005,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [The Window object]",
-          "   * (http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)",
-          "   * from W3C.",
+          "   * * [The Window",
+          "   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)",
+          "   *   from W3C.",
           "   */"
         ],
         "storageEvent": [
@@ -4054,9 +4024,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [StyleMedia class reference]",
-          "   * (https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html)",
-          "   * from Safari Developer Library.",
+          "   * * [StyleMedia class",
+          "   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)",
+          "   *   from Safari Developer Library.",
           "   */"
         ],
         "TEMPORARY": [
@@ -4065,10 +4035,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Exploring the FileSystem APIs]",
-          "   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.",
-          "   * * [File API]",
-          "   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.",
+          "   * * [Exploring the FileSystem",
+          "   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.",
+          "   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)",
+          "   *   from W3C.",
           "   */"
         ],
         "toolbar": [
@@ -4077,9 +4047,9 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Browser interface elements]",
-          "   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)",
-          "   * from WHATWG.",
+          "   * * [Browser interface",
+          "   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)",
+          "   *   from WHATWG.",
           "   */"
         ],
         "unloadEvent": [
@@ -4120,8 +4090,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Obtaining access to file system entry points]",
-          "   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)",
+          "   * * [Obtaining access to file system entry",
+          "   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)",
           "   * from W3C.",
           "   */"
         ],
@@ -4131,8 +4101,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [Window.window]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.",
+          "   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)",
+          "   *   from MDN.",
           "   */"
         ]
       }
@@ -4197,7 +4167,8 @@
           "   * `getAllResponseHeaders` will return the response headers for the current",
           "   * part of the request.",
           "   *",
-          "   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)",
+          "   * See also [HTTP response",
+          "   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)",
           "   * for a list of common response headers.",
           "   */"
         ],
@@ -4205,7 +4176,8 @@
           "/**",
           "   * Return the response header named `header`, or null if not found.",
           "   *",
-          "   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)",
+          "   * See also [HTTP response",
+          "   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)",
           "   * for a list of common response headers.",
           "   */"
         ],
@@ -4239,7 +4211,7 @@
           "   * response.",
           "   *",
           "   * This value must be set before the request has been sent. See also the list",
-          "   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)",
+          "   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml)",
           "   */"
         ],
         "readyState": [
@@ -4307,7 +4279,8 @@
           "   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if",
           "   * `responseType` is set while performing a synchronous request.",
           "   *",
-          "   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)",
+          "   * See also: [MDN",
+          "   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)",
           "   */"
         ],
         "responseXML": [
@@ -4330,9 +4303,8 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [XMLHttpRequest.send]",
-          "   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)",
-          "   * from MDN.",
+          "   * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)",
+          "   *   from MDN.",
           "   */"
         ],
         "setRequestHeader": [
@@ -4347,24 +4319,23 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [XMLHttpRequest.setRequestHeader]",
-          "   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)",
-          "   * from MDN.",
-          "   * * [The setRequestHeader() method]",
-          "   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from",
-          "   * W3C.",
+          "   * * [XMLHttpRequest.setRequestHeader](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader())",
+          "   *   from MDN.",
+          "   * * [The setRequestHeader()",
+          "   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)",
+          "   *   from W3C.",
           "   */"
         ],
         "status": [
           "/**",
-          "   * The http result code from the request (200, 404, etc).",
-          "   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
+          "   * The HTTP result code from the request (200, 404, etc).",
+          "   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
           "   */"
         ],
         "statusText": [
           "/**",
           "   * The request response string (such as \\\"200 OK\\\").",
-          "   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
+          "   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
           "   */"
         ],
         "timeout": [
@@ -4377,12 +4348,10 @@
           "   *",
           "   * ## Other resources",
           "   *",
-          "   * * [XMLHttpRequest.timeout]",
-          "   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)",
-          "   * from MDN.",
-          "   * * [The timeout attribute]",
-          "   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)",
-          "   * from W3C.",
+          "   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)",
+          "   *   from MDN.",
+          "   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)",
+          "   *   from W3C.",
           "   */"
         ],
         "upload": [
@@ -5267,6 +5236,8 @@
           "   *",
           "   * [oldVersion] should match the database's current [version] exactly.",
           "   *",
+          "   * See also:",
+          "   *",
           "   * * [Database.changeVersion](http://www.w3.org/TR/webdatabase/#dom-database-changeversion) from W3C.",
           "   */"
         ]
diff --git a/tools/dom/dom.py b/tools/dom/dom.py
index e0bbfdd..c69d065 100755
--- a/tools/dom/dom.py
+++ b/tools/dom/dom.py
@@ -139,7 +139,7 @@
   return call(cmd)
 
 def test_server():
-  start_test_server(5400, os.path.join('out', 'ReleaseIA32'))
+  start_test_server(5400, os.path.join('out', 'ReleaseX64'))
 
 def test_server_dartium():
   start_test_server(5500, os.path.join('..', 'out', 'Release'))
diff --git a/tools/dom/scripts/chromegenerator.py b/tools/dom/scripts/chromegenerator.py
deleted file mode 100755
index e537c85..0000000
--- a/tools/dom/scripts/chromegenerator.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-"""This module generates Dart Chrome APIs from the Chrome IDL files."""
-
-import sys
-import os
-
-# The path to the JSON Schema Compiler, which can be run to generate the files.
-# Lives in the Chromium repository, so needs to be pulled in somehow.
-COMPILER = "../../../third_party/chrome/tools/json_schema_compiler/compiler.py"
-
-# The path to the Chrome IDL files. They live in the Chromium repository, so
-# need to be pulled in somehow.
-API_DIR = "../../../third_party/chrome/idl/"
-
-# The path to the custom overrides directory, containing override files.
-OVERRIDES_DIR = "../src/_chrome/custom_dart/"
-
-# The path to where the generated .dart files should be saved.
-OUTPUT_DIR = "../src/_chrome/"
-
-# The path to where the output template file is. This file will be populated
-# with TEMPLATE_CONTENT, followed by the list of generated .dart files.
-OUTPUT_TEMPLATE = "../templates/html/dart2js/chrome_dart2js.darttemplate"
-
-# The content to fill OUTPUT_TEMPLATE with. Will be followed by a list of the
-# names of the generated .dart files.
-TEMPLATE_CONTENT = """
-// 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.
-
-// DO NOT EDIT
-// Auto-generated dart:_chrome library.
-
-/// Native wrappers for the Chrome packaged app APIs.
-///
-/// These functions allow direct access to the chrome.* APIs, allowing
-/// Chrome packaged apps to be written using Dart.
-///
-/// For more information on these APIs, see the
-/// [chrome.* API documentation](http://developer.chrome.com/apps/api_index.html).
-library _chrome;
-
-import 'dart:_foreign_helper' show JS;
-/* TODO(sashab): Add "show convertDartClosureToJS" once 'show' works. */
-import 'dart:_js_helper';
-import 'dart:html_common';
-import 'dart:html';
-
-part "$AUXILIARY_DIR/_chrome/utils.dart";
-part "$AUXILIARY_DIR/_chrome/_chrome.dart";
-
-// Generated files below this line.
-"""
-
-# The format for adding files to TEMPLATE_CONTENT. Will be substituted with the
-# filename (not including the extension) of the IDL/JSON file.
-TEMPLATE_FILE_FORMAT = 'part "$AUXILIARY_DIR/_chrome/%s.dart";'
-
-# A list of schema files to generate.
-# TODO(sashab): Later, use the ones from API_DIR/api.gyp and
-# API_DIR/_permission_features.json (for 'platform_apps').
-API_FILES = [
-    "app_window.idl",
-    "app_runtime.idl",
-    "file_system.idl",
-]
-
-if __name__ == "__main__":
-  # Generate each file.
-  for filename in API_FILES:
-    result = os.system('python "%s" -g dart -D "%s" -d "%s" -r "%s" "%s"' % (
-        COMPILER, OVERRIDES_DIR, OUTPUT_DIR, API_DIR,
-        os.path.join(API_DIR, filename)))
-    if result != 0:
-        print "Error occurred during generation of %s" % (
-            os.path.join(API_DIR, filename))
-        sys.exit(1)
-    else:
-      print "Generated %s successfully to %s.dart" % (
-          os.path.join(API_DIR, filename),
-          os.path.join(OUTPUT_DIR, os.path.splitext(filename)[0]))
-
-  # Generate the template.
-  files_to_add = (TEMPLATE_FILE_FORMAT % os.path.splitext(f)[0]
-                  for f in API_FILES)
-  with open(OUTPUT_TEMPLATE, 'w') as template_file:
-    template_file.write(TEMPLATE_CONTENT)
-    template_file.write('\n'.join(files_to_add))
-  print "Generated template succesfully."
-
-
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 2cdc750..92a5ed0 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -722,6 +722,9 @@
     # postMessage
     'any set MessagePort.postMessage': _serialize_SSV,
     'SerializedScriptValue set Window.postMessage': _serialize_SSV,
+    'SerializedScriptValue set Worker.postMessage': _serialize_SSV,
+    'any set DedicatedWorkerGlobalScope.postMessage' : _serialize_SSV,
+    'SerializedScriptValue set ServiceWorkerClient.postMessage': _serialize_SSV,
 
     '* get CustomEvent.detail':
       Conversion('convertNativeToDart_SerializedScriptValue',
@@ -732,6 +735,12 @@
       Conversion('convertNativeToDart_SerializedScriptValue',
                  'dynamic', 'dynamic'),
 
+    # TODO(alanknight): This generates two variations for dart2js, because of
+    # the optional argument, but not in Dartium. Should do the same for both.
+    'any set History.pushState': _serialize_SSV,
+
+    'any set History.replaceState': _serialize_SSV,
+
     '* get History.state':
       Conversion('convertNativeToDart_SerializedScriptValue',
                  'dynamic', 'dynamic'),
@@ -1443,6 +1452,7 @@
         return_type = return_type.replace('Html', 'HTML', 1)
     return (type_registry.HasInterface(return_type) or not(return_type) or
             return_type == 'Object' or
+            return_type == 'dynamic' or
             return_type == 'Future' or
             return_type == 'SqlDatabase' or # renamed to Database
             return_type == 'HTMLElement' or
diff --git a/tools/dom/scripts/go.sh b/tools/dom/scripts/go.sh
index 946bdb9..c17719f 100755
--- a/tools/dom/scripts/go.sh
+++ b/tools/dom/scripts/go.sh
@@ -1,5 +1,8 @@
-#!/bin/bash -x
+#!/usr/bin/env bash
 #
+
+set -x
+
 #   go.sh [systems]
 #
 # Convenience script to generate systems.  Do not call from build steps or tests
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index e207e79..78193a5 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -439,12 +439,6 @@
   'DataTransferItemList.add(DOMString data, DOMString type)': 'addData',
   'FormData.append(DOMString name, Blob value, DOMString filename)':
       'appendBlob',
-  'IDBDatabase.transaction(DOMStringList storeNames, IDBTransactionMode mode)':
-      'transactionStores',
-  'IDBDatabase.transaction(sequence<DOMString> storeNames, IDBTransactionMode mode)':
-      'transactionList',
-  'IDBDatabase.transaction(DOMString storeName, IDBTransactionMode mode)':
-      'transactionStore',
   'RTCDataChannel.send(ArrayBuffer data)': 'sendByteBuffer',
   'RTCDataChannel.send(ArrayBufferView data)': 'sendTypedData',
   'RTCDataChannel.send(Blob data)': 'sendBlob',
@@ -777,6 +771,7 @@
     'HTMLTitleElement.text',
     'HTMLUListElement.compact',
     'HTMLUListElement.type',
+    'IDBDatabase.transaction', # We do this in a template without the generated implementation at all.
     'Location.valueOf',
     'MessageEvent.ports',
     'MessageEvent.webkitInitMessageEvent',
diff --git a/tools/dom/src/CanvasImageSource.dart b/tools/dom/src/CanvasImageSource.dart
index e030533..ffcd34a 100644
--- a/tools/dom/src/CanvasImageSource.dart
+++ b/tools/dom/src/CanvasImageSource.dart
@@ -33,11 +33,10 @@
  *
  * ## Other resources
  *
- * * [Image sources for 2D rendering contexts]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
- * from WHATWG.
- * * [Drawing images]
- * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
- * from WHATWG.
+ * * [Image sources for 2D rendering
+ *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
+ *   from WHATWG.
+ * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
+ *   from WHATWG.
  */
 abstract class CanvasImageSource {}
diff --git a/tools/dom/src/CrossFrameTypes.dart b/tools/dom/src/CrossFrameTypes.dart
index cda5957..a923377 100644
--- a/tools/dom/src/CrossFrameTypes.dart
+++ b/tools/dom/src/CrossFrameTypes.dart
@@ -39,9 +39,9 @@
    *
    * ## Other resources
    *
-   * * [Session history and navigation specification]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
-   * from WHATWG.
+   * * [Session history and navigation
+   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
+   *   from WHATWG.
    */
   HistoryBase get history;
 
@@ -134,12 +134,10 @@
    *
    * ## Other resources
    *
-   * * [window.postMessage]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
-   * MDN.
-   * * [Cross-document messaging]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
-   * from WHATWG.
+   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
+   *   from MDN.
+   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
+   *   from WHATWG.
    */
   void postMessage(var message, String targetOrigin, [List messagePorts]);
 }
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index ea66285..3b41f51 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -112,9 +112,8 @@
    *
    * ## Other resources
    *
-   * * [Event Capture]
-   * (http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
-   * from the W3C DOM Events specification.
+   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
+   *   from the W3C DOM Events specification.
    */
   StreamSubscription<T> capture(void onData(T event));
 }
diff --git a/tools/dom/src/Html5NodeValidator.dart b/tools/dom/src/Html5NodeValidator.dart
index 2bbaf41..01ce4f8 100644
--- a/tools/dom/src/Html5NodeValidator.dart
+++ b/tools/dom/src/Html5NodeValidator.dart
@@ -239,6 +239,7 @@
     'INPUT::align',
     'INPUT::alt',
     'INPUT::autocomplete',
+    'INPUT::autofocus',
     'INPUT::checked',
     'INPUT::disabled',
     'INPUT::inputmode',
diff --git a/tools/dom/src/dart2js_WrappedEvent.dart b/tools/dom/src/dart2js_WrappedEvent.dart
index 4f30af9..e7e21a0 100644
--- a/tools/dom/src/dart2js_WrappedEvent.dart
+++ b/tools/dom/src/dart2js_WrappedEvent.dart
@@ -76,9 +76,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
   @Experimental()
diff --git a/tools/dom/src/dartium_WrappedEvent.dart b/tools/dom/src/dartium_WrappedEvent.dart
index 9fa56fd..18c43f0 100644
--- a/tools/dom/src/dartium_WrappedEvent.dart
+++ b/tools/dom/src/dartium_WrappedEvent.dart
@@ -83,9 +83,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM extensions to Event]
-   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
-   * W3C.
+   * * [Shadow DOM extensions to
+   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
+   *   from W3C.
    */
   // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
   @Experimental()
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index b18a026..e9e3720 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -266,6 +266,9 @@
       // 'this' needs to be handled by calling Dart_EvaluateExpr with
       // 'this' as the target rather than by passing it as an argument.
       if (arg == 'this') return;
+      // Avoid being broken by bogus ':async_op' local passed in when within
+      // an async method.
+      if (arg.startsWith(':')) return;
       if (args.isNotEmpty) {
         sb.write(", ");
       }
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 0e029f2..c82e9b5 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -405,32 +405,6 @@
 
 }
 
-/// Upgrade a Dart HtmlElement to the user's Dart custom element class.
-_upgradeHtmlElement(dartInstance) {
-  // Only try upgrading HtmlElement (Dart class) if there is a failure then
-  // don't try it again - one failure is enough.
-  if (dartInstance.runtimeType == HtmlElement && !dartInstance.isBadUpgrade) {
-    // Must be exactly HtmlElement not something derived from it.
-
-    var customElementClass = getCustomElementType(dartInstance);
-
-    // Custom Element to upgrade.
-    if (customElementClass != null) {
-      var jsObject = dartInstance.blink_jsObject;
-      try {
-        dartInstance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
-      } catch (e) {
-        dartInstance._badUpgrade();
-      } finally {
-        dartInstance.blink_jsObject = jsObject;
-        js.setDartHtmlWrapperFor(jsObject, dartInstance);
-     }
-   }
-  }
-
-  return dartInstance;
-}
-
 @Deprecated("Internal Use Only")
 class DebugAssertException implements Exception {
   String message;
@@ -480,7 +454,12 @@
   try {
     dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
   } catch (e) {
-    dartClass._badUpgrade();
+    // Did the dartClass get allocated but the created failed?  Otherwise, other
+    // components inside of this failed somewhere (could be JS custom element).
+    if (dartClass != null) {
+      // Yes, mark as didn't upgrade.
+      dartClass._badUpgrade();
+    }
     throw e;
   } finally {
     // Need to remember the Dart class that was created for this custom so
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index 2060813..ca0705a 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -64,11 +64,9 @@
   @DomName('Document.createElement')
   Element createElement(String tagName, [String typeExtension]) {
 $if DART2JS
-    if (typeExtension == null) {
-      return _createElement_2(tagName);
-    } else {
-      return _createElement(tagName, typeExtension);
-    }
+    return (typeExtension == null)
+        ? _createElement_2(tagName)
+        : _createElement(tagName, typeExtension);
 $else
     var newElement = (typeExtension == null) ?
       _blink.BlinkDocument.instance.createElement_Callback_1_(unwrap_jso(this), tagName) :
@@ -94,24 +92,23 @@
   // The two-argument version of this is automatically generated, but we need to
   // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
   @DomName('Document.createElement')
-  _createElement_2(String tagName) => JS('', '#.createElement(#)', this, tagName);
+  _createElement_2(String tagName) =>
+      JS('Element', '#.createElement(#)', this, tagName);
 
   // The three-argument version of this is automatically generated, but we need to
   // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
   @DomName('Document.createElementNS')
   _createElementNS_2(String namespaceURI, String qualifiedName) =>
-      JS('', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName);
+      JS('Element', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName);
 
 $endif
   @DomName('Document.createElementNS')
   @DocsEditable()
   Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) {
 $if DART2JS
-    if (typeExtension == null) {
-      return _createElementNS_2(namespaceURI, qualifiedName);
-    } else {
-      return _createElementNS(namespaceURI, qualifiedName, typeExtension);
-    }
+    return (typeExtension == null)
+        ? _createElementNS_2(namespaceURI, qualifiedName)
+        : _createElementNS(namespaceURI, qualifiedName, typeExtension);
 $else
     var newElement = (typeExtension == null) ?
       _blink.BlinkDocument.instance.createElementNS_Callback_2_(unwrap_jso(this), namespaceURI, qualifiedName) :
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 25608df..03539f5 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -666,7 +666,8 @@
    *
    * See also:
    *
-   * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
+   * * [Custom data
+   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
    */
   Map<String, String> get dataset =>
     new _DataAttributeMap(attributes);
@@ -892,8 +893,8 @@
    *
    * ## Other resources
    *
-   * * [Node.namespaceURI]
-   * (http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) from W3C.
+   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
+   *   from W3C.
    */
   @DomName('Element.namespaceUri')
   String get namespaceUri => _namespaceUri;
@@ -1122,11 +1123,9 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM 101]
-   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
-   * from HTML5Rocks.
-   * * [Shadow DOM specification]
-   * (http://www.w3.org/TR/shadow-dom/) from W3C.
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/) from W3C.
    */
   @DomName('Element.createShadowRoot')
   @SupportedBrowser(SupportedBrowser.CHROME, '25')
@@ -1142,11 +1141,10 @@
    *
    * ## Other resources
    *
-   * * [Shadow DOM 101]
-   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
-   * from HTML5Rocks.
-   * * [Shadow DOM specification]
-   * (http://www.w3.org/TR/shadow-dom/) from W3C.
+   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
+   *   from HTML5Rocks.
+   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/)
+   *   from W3C.
    */
   @DomName('Element.shadowRoot')
   @SupportedBrowser(SupportedBrowser.CHROME, '25')
diff --git a/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate b/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate
index d1b4f83..af140f7 100644
--- a/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate
+++ b/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate
@@ -4,6 +4,15 @@
 
 part of $LIBRARYNAME;
 
+// We implement EventTarget and have stubs for its methods because it's tricky to
+// convince the scripts to make our instance methods abstract, and the bodies that
+// get generated require `this` to be an EventTarget.
 @DocsEditable()
-$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME extends EventTarget {
+$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME implements EventTarget {
+
+  void addEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  bool dispatchEvent(Event event);
+  void removeEventListener(String type, dynamic listener(Event event), [bool useCapture]);
+  Events get on;
+
 $!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
index 3d49d69..41ecdb9 100644
--- a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
@@ -19,10 +19,9 @@
    *
    * ## Other resources
    *
-   * * [WebGL fundamentals]
-   * (http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/) from
-   * HTML5Rocks.
-   * * [WebGL homepage] (http://get.webgl.org/).
+   * * [WebGL fundamentals](http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/)
+   *   from HTML5Rocks.
+   * * [WebGL homepage](http://get.webgl.org/).
    */
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index 6cbf883..61fc715 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -22,7 +22,9 @@
   }
 $endif
 
+  /// UNSTABLE: Chrome-only - create a Range from the given point.
   @DomName('Document.caretRangeFromPoint')
+  @Unstable()
   Range caretRangeFromPoint(int x, int y) {
     return _caretRangeFromPoint(x, y);
   }
@@ -112,11 +114,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitExitFullscreen')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -140,11 +141,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -157,11 +157,10 @@
    *
    * ## Other resources
    *
-   * * [Using the fullscreen API]
-   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
-   * WebPlatform.org.
-   * * [Fullscreen specification]
-   * (http://www.w3.org/TR/fullscreen/) from W3C.
+   * * [Using the fullscreen
+   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
+   *   from WebPlatform.org.
+   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
    */
   @DomName('Document.webkitFullscreenEnabled')
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -298,16 +297,9 @@
             createdParametersValid = createdParametersValid && parameter.isOptional;
           });
         }
-
-        // Get the created constructor source and look at the initializer;
-        // Must call super.created() if not its as an error.
-        var createdSource = methodMirror.source;
-        superCreatedCalled = createdSource.contains("super.created(");
       }
 
-      if (!superCreatedCalled) {
-        throw new DomException.jsInterop('created constructor initializer must call super.created()');
-      } else if (!createdParametersValid) {
+      if (!createdParametersValid) {
         throw new DomException.jsInterop('created constructor must have no parameters');
       }
 
diff --git a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
index b9fd424..bf7bd07 100644
--- a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
@@ -9,9 +9,24 @@
   factory $CLASSNAME(String type,
       {bool canBubble: true, bool cancelable: true, String oldUrl,
       String newUrl}) {
+
+$if DART2JS
+    var options = {
+      'canBubble' : canBubble,
+      'cancelable' : cancelable,
+      'oldURL': oldUrl,
+      'newURL': newUrl,
+    };
+    return JS('HashChangeEvent', 'new HashChangeEvent(#, #)',
+        type, convertDartToNative_Dictionary(options));
+$else
+    // TODO(alanknight): This is required while we're on Dartium 39, but will need
+    // to look like dart2js with later versions when initHashChange is removed.
     var event = document._createEvent("HashChangeEvent");
     event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
     return event;
+$endif
   }
+
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_IDBDatabase.darttemplate b/tools/dom/templates/html/impl/impl_IDBDatabase.darttemplate
index c89c29a..8a74ad3 100644
--- a/tools/dom/templates/html/impl/impl_IDBDatabase.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBDatabase.darttemplate
@@ -53,7 +53,7 @@
     List storeNames_1 = convertDartToNative_StringArray(storeNames);
     return _transaction(storeNames_1, mode);
   }
-  
+
   Transaction transactionStores(DomStringList storeNames, String mode) {
     if (mode != 'readonly' && mode != 'readwrite') {
       throw new ArgumentError(mode);
@@ -63,6 +63,28 @@
 
   @JSName('transaction')
   Transaction _transaction(stores, mode) native;
+$else
+  Transaction transaction(storeName_OR_storeNames, String mode) {
+    if (mode != 'readonly' && mode != 'readwrite') {
+      throw new ArgumentError("Invalid transaction mode $mode");
+    }
+    var names;
+    if (storeName_OR_storeNames == null) {
+      throw new ArgumentError("stores may not be null in transaction");
+    } else if (storeName_OR_storeNames is String || storeName_OR_storeNames is DomStringList) {
+      names = unwrap_jso(storeName_OR_storeNames);
+    } else if (storeName_OR_storeNames is List<String>) {
+      names = convertDartToNative_List(storeName_OR_storeNames);
+    } else {
+      throw new ArgumentError("Invalid store(s) $store_Name_OR_storeNames");
+    }
+
+    return wrap_jso(_blink.BlinkIDBDatabase.instance.transaction_Callback_2_(unwrap_jso(this), names, mode));
+  }
+
+  Transaction transactionList(List<String> storeNames, String mode) => transaction(storeNames, mode);
+  Transaction transactionStores(List<String> storeNames, String mode) => transaction(storeNames, mode);
+  Transaction transactionStore(String storeName, String mode) => transaction(storeName, mode);
 $endif
 
 $!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index 23b4afe..17bc601 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -299,9 +299,8 @@
    *
    * ## Other resources
    *
-   * * [Node.childNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
-   * from MDN.
+   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
+   *   from MDN.
    */
   @DomName('Node.childNodes')
   @DocsEditable()
@@ -312,9 +311,8 @@
    *
    * ## Other resources
    *
-   * * [Node.childNodes]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
-   * from MDN.
+   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
+   *   from MDN.
    */
   @DomName('Node.childNodes')
   @DocsEditable()
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index 36dfc9a..d891762 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -41,26 +41,27 @@
    *
    * ## Other resources
    *
-   * * [Loading web pages]
-   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
-   * from WHATWG.
+   * * [Loading web
+   *   pages](https://html.spec.whatwg.org/multipage/browsers.html)
+   *   from WHATWG.
    */
   Document get document => JS('Document', '#.document', this);
 
-  WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);
+  WindowBase _open2(url, name) =>
+      JS('Window|Null', '#.open(#,#)', this, url, name);
 
   WindowBase _open3(url, name, options) =>
-      JS('Window', '#.open(#,#,#)', this, url, name, options);
+      JS('Window|Null', '#.open(#,#,#)', this, url, name, options);
 
   /**
    * Opens a new window.
    *
    * ## Other resources
    *
-   * * [Window.open]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.open) from MDN.
-   * * [Window open]
-   * (http://docs.webplatform.org/wiki/dom/methods/open) from WebPlatform.org.
+   * * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
+   *   from MDN.
+   * * [Window open](http://docs.webplatform.org/wiki/dom/methods/open)
+   *   from WebPlatform.org.
    */
   WindowBase open(String url, String name, [String options]) {
     if (options == null) {
@@ -122,8 +123,8 @@
    *
    * ## Other resources
    *
-   * * [Window.cancelAnimationFrame]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame) from MDN.
+   * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
+   *   from MDN.
    */
   void cancelAnimationFrame(int id) {
     _ensureRequestAnimationFrame();
@@ -244,10 +245,10 @@
    *
    * ## Other resources
    *
-   * * [Window.moveTo]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo) from MDN.
-   * * [Window.moveTo]
-   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveto) from W3C.
+   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
+   *   from MDN.
+   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
+   *   from W3C.
    */
   void moveTo(Point p) {
     _moveTo(p.x, p.y);
@@ -267,10 +268,10 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollX]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
+   *   from MDN.
    */
   @DomName('Window.scrollX')
   @DocsEditable()
@@ -283,10 +284,10 @@
    *
    * ## Other resources
    *
-   * * [The Screen interface specification]
-   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
-   * * [scrollY]
-   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
+   * * [The Screen interface
+   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
+   * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
+   *   from MDN.
    */
   @DomName('Window.scrollY')
   @DocsEditable()
diff --git a/tools/full-coverage.dart b/tools/full-coverage.dart
index 2963574..d7ff76f 100644
--- a/tools/full-coverage.dart
+++ b/tools/full-coverage.dart
@@ -462,9 +462,11 @@
 
   env.pkgRoot = args["package-root"];
   if (env.pkgRoot != null) {
-    env.pkgRoot = absolute(normalize(args["package-root"]));
-    if (!FileSystemEntity.isDirectorySync(env.pkgRoot)) {
-      fail("Provided package root '${args["package-root"]}' is not directory.");
+    var pkgRootUri = Uri.parse(env.pkgRoot);
+    if (pkgRootUri.scheme == "file") {
+      if (!FileSystemEntity.isDirectorySync(pkgRootUri.toFilePath())) {
+        fail("Provided package root '${args["package-root"]}' is not directory.");
+      }
     }
   } else {
     env.pkgRoot = Platform.packageRoot;
diff --git a/tools/gyp/configurations_make.gypi b/tools/gyp/configurations_make.gypi
index 683ca51..ebaf935 100644
--- a/tools/gyp/configurations_make.gypi
+++ b/tools/gyp/configurations_make.gypi
@@ -29,9 +29,10 @@
           # '-fvisibility=hidden',
           # '-fvisibility-inlines-hidden',
           '-fstack-protector',
+          '-Wa,--noexecstack',
         ],
         'ldflags': [
-          '-Wa,--noexecstack',
+          '-Wl,-z,noexecstack',
           '-Wl,-z,now',
           '-Wl,-z,relro',
         ],
@@ -236,6 +237,10 @@
         ],
         'cflags': [
           '-O3',
+          '-ffunction-sections',
+        ],
+        'ldflags': [
+          '-Wl,--gc-sections',
         ],
       },
     },
diff --git a/tools/gyp/configurations_xcode.gypi b/tools/gyp/configurations_xcode.gypi
index 3f22df5..f709727 100644
--- a/tools/gyp/configurations_xcode.gypi
+++ b/tools/gyp/configurations_xcode.gypi
@@ -25,6 +25,7 @@
           'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
           'GCC_DEBUGGING_SYMBOLS': 'default', # -g
           'GCC_GENERATE_DEBUGGING_SYMBOLS': 'YES', # Do not strip symbols
+          'DEAD_CODE_STRIPPING': 'YES',  # -Wl,-dead_strip
           'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
           'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES', # -fvisibility-inlines-hidden
           'GCC_WARN_NON_VIRTUAL_DESTRUCTOR': 'YES', # -Wnon-virtual-dtor
diff --git a/tools/make_links.py b/tools/make_links.py
index 58bc9cb..157008a 100644
--- a/tools/make_links.py
+++ b/tools/make_links.py
@@ -29,8 +29,9 @@
 import utils
 
 # Useful messages when we find orphaned checkouts.
-old_directories = {'package_config':
-  'Please remove third_party/pkg/package_config.'}
+old_directories = {
+    'package_config': 'Please remove third_party/pkg/package_config.',
+    'analyzer_cli': 'Please remove third_party/pkg/analyzer_cli.'}
 
 def get_options():
   result = optparse.OptionParser()
diff --git a/tools/observatory_tool.py b/tools/observatory_tool.py
index 5b1c7c5..a8595dc 100755
--- a/tools/observatory_tool.py
+++ b/tools/observatory_tool.py
@@ -36,11 +36,28 @@
   result.add_argument("--pub-executable", help="pub executable", default=None)
   result.add_argument("--directory", help="observatory root", default=None)
   result.add_argument("--command", help="[get, build, deploy]", default=None)
-  result.add_argument("--silent", help="silence all output", default=False)
-  result.add_argument("--sdk", help="Use prebuilt sdk", default=False)
+  result.add_argument("--silent", help="silence all output", default=None)
+  result.add_argument("--sdk", help="Use prebuilt sdk", default=None)
   return result
 
 def ProcessOptions(options, args):
+  # Fix broken boolean parsing in argparse, where False ends up being True.
+  if (options.silent is not None) and (options.silent == "True"):
+    options.silent = True
+  elif (options.silent is None) or (options.silent == "False"):
+    options.silent = False
+  else:
+    print "--silent expects 'True' or 'False' argument."
+    return False
+
+  if (options.sdk is not None) and (options.sdk == "True"):
+    options.sdk = True
+  elif (options.sdk is None) or (options.sdk == "False"):
+    options.sdk = False
+  else:
+    print "--sdk expects 'True' or 'False' argument."
+    return False
+
   with open(os.devnull, 'wb') as silent_sink:
     # Required options.
     if options.command is None or options.directory is None:
@@ -61,7 +78,7 @@
         pass
     options.pub_executable = None
 
-    if options.sdk is not None and utils.CheckedInSdkCheckExecutable():
+    if options.sdk and utils.CheckedInSdkCheckExecutable():
       # Use the checked in pub executable.
       options.pub_snapshot = os.path.join(utils.CheckedInSdkPath(),
                                           'bin',
@@ -93,7 +110,10 @@
 bootstrap Dart executable will make debug builds slow.
 Please see the Wiki for instructions on replacing the checked-in Dart SDK.
 
-https://github.com/dart-lang/sdk/wiki/The-checked-in-SDK-in--tools
+https://github.com/dart-lang/sdk/wiki/The-checked-in-SDK-in-tools
+
+To use the dart_bootstrap binary please update the PubCommand function
+in the tools/observatory_tool.py script.
 
 """
 
@@ -111,6 +131,10 @@
     else:
       DisplayBootstrapWarning()
       executable = [dart_executable, '--package-root=' + pkg_root, PUB_PATH]
+      # Prevent the bootstrap Dart executable from running in regular
+      # development flow.
+      # REMOVE THE FOLLOWING LINE TO USE the dart_bootstrap binary.
+      # return False
     return subprocess.call(executable + command,
                            stdout=silent_sink if silent else None,
                            stderr=silent_sink if silent else None)
diff --git a/tools/precompilation/precompiler.dart b/tools/precompilation/precompiler.dart
new file mode 100755
index 0000000..419875a
--- /dev/null
+++ b/tools/precompilation/precompiler.dart
@@ -0,0 +1,64 @@
+// 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 precompiler;
+
+import 'dart:io';
+
+void run(String executable, String arguments, [String workingDirectory]) {
+  print("+ $executable ${arguments.join(' ')}");
+  var result = Process.runSync(executable, arguments,
+                               workingDirectory: workingDirectory);
+  stdout.write(result.stdout);
+  stderr.write(result.stderr);
+  if (result.exitCode != 0) {
+    exit(result.exitCode);
+  }
+}
+
+void main(List<String> args) {
+  var configuration = Platform.environment["DART_CONFIGURATION"];
+
+  var cc, cc_flags, shared, libname;
+  if (Platform.isLinux) {
+    cc = 'gcc';
+    shared = '-shared';
+    libname = 'libprecompiled.so';
+  } else if (Platform.isMacOS) {
+    cc = 'clang';
+    shared = '-dynamiclib';
+    libname = 'libprecompiled.dylib';
+  } else {
+    print("Test only supports Linux and Mac");
+    return;
+  }
+
+  if (configuration.endsWith("X64")) {
+    cc_flags = "-m64";
+  } else if (configuration.endsWith("SIMARM64")) {
+    cc_flags = "-m64";
+  } else if (configuration.endsWith("SIMARM")) {
+    cc_flags = "-m32";
+  } else if (configuration.endsWith("SIMMIPS")) {
+    cc_flags = "-m32";
+  } else if (configuration.endsWith("ARM")) {
+    cc_flags = "";
+  } else if (configuration.endsWith("MIPS")) {
+    cc_flags = "-EL";
+  } else {
+    print("Architecture not supported: $configuration");
+    return;
+  }
+
+  var tmpDir;
+  for (var arg in args) {
+    if (arg.startsWith("--gen-precompiled-snapshot")) {
+      tmpDir = arg.substring("--gen-precompiled-snapshot".length + 1);
+    }
+  }
+  print("Using directory $tmpDir");
+
+  run(args[0], args.sublist(1));
+  run(cc, [shared, cc_flags, "-o", libname, "precompiled.S"], tmpDir);
+}
diff --git a/tools/precompilation/test_linux.sh b/tools/precompilation/test_linux.sh
index e8839e1..553dc18b 100755
--- a/tools/precompilation/test_linux.sh
+++ b/tools/precompilation/test_linux.sh
@@ -1,13 +1,15 @@
-#!/bin/bash -ex
+#!/usr/bin/env bash
+
+set -ex
 
 # Usage:
 #   cd sdk
-#   ./tools/precompilation/test_linux.sh
+#   ./tools/precompilation/test_linux.sh <dart-script-file>
 
 ./tools/build.py -mdebug -ax64 runtime
 
-./out/DebugX64/dart_no_snapshot --gen-precompiled-snapshot ~/hello.dart
+./out/DebugX64/dart_no_snapshot --gen-precompiled-snapshot --package-root=out/DebugX64/packages/ "$1"
 
 gcc -m64 -shared -Wl,-soname,libprecompiled.so -o libprecompiled.so precompiled.S
 
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugX64/dart --run-precompiled-snapshot not_used.dart
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugX64/dart_precompiled --run-precompiled-snapshot not_used.dart
diff --git a/tools/precompilation/test_linux_simarm.sh b/tools/precompilation/test_linux_simarm.sh
index b55a5e9..e61b58b 100755
--- a/tools/precompilation/test_linux_simarm.sh
+++ b/tools/precompilation/test_linux_simarm.sh
@@ -1,13 +1,15 @@
-#!/bin/bash -ex
+#!/usr/bin/env bash
+
+set -ex
 
 # Usage:
 #   cd sdk
-#   ./tools/precompilation/test_linux.sh
+#   ./tools/precompilation/test_linux.sh <dart-script-file>
 
 ./tools/build.py -mdebug -asimarm runtime
 
-./out/DebugSIMARM/dart_no_snapshot --gen-precompiled-snapshot ~/hello.dart
+./out/DebugSIMARM/dart_no_snapshot --gen-precompiled-snapshot --package-root=out/DebugX64/packages/ "$1"
 
 gcc -m32 -shared -Wl,-soname,libprecompiled.so -o libprecompiled.so precompiled.S
 
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugSIMARM/dart --run-precompiled-snapshot not_used.dart
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugSIMARM/dart_precompiled --run-precompiled-snapshot not_used.dart
diff --git a/tools/precompilation/test_macos.sh b/tools/precompilation/test_macos.sh
index 48e318d..57e02dc 100755
--- a/tools/precompilation/test_macos.sh
+++ b/tools/precompilation/test_macos.sh
@@ -1,13 +1,15 @@
-#!/bin/bash -ex
+#!/usr/bin/env bash
+
+set -ex
 
 # Usage:
 #   cd sdk
-#   ./tools/precompilation/test_macos.sh
+#   ./tools/precompilation/test_macos.sh <dart-script-file>
 
 ./tools/build.py -mdebug -ax64 runtime
 
-./xcodebuild/DebugX64/dart_no_snapshot --gen-precompiled-snapshot ~/hello.dart
+./xcodebuild/DebugX64/dart_no_snapshot --gen-precompiled-snapshot --package-root=xcodebuild/DebugX64/packages/ "$1"
 
 clang -m64 -dynamiclib -o libprecompiled.dylib precompiled.S
 
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" lldb -- ./xcodebuild/DebugX64/dart --run-precompiled-snapshot not_used.dart
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" lldb -- ./xcodebuild/DebugX64/dart_precompiled --run-precompiled-snapshot not_used.dart
diff --git a/tools/presubmit.sh b/tools/presubmit.sh
index a3e6f8a..bedee8b 100755
--- a/tools/presubmit.sh
+++ b/tools/presubmit.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 #
 # Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
 # for details. All rights reserved. Use of this source code is governed by a
diff --git a/tools/promote.py b/tools/promote.py
index d3013ab..81ab402 100644
--- a/tools/promote.py
+++ b/tools/promote.py
@@ -131,11 +131,10 @@
     remove_gs_directory(to_loc)
     Gsutil(['-m', 'cp', '-a', 'public-read', '-R', from_loc, to_loc])
 
-    # Copy api-docs directory.
-    from_loc = raw_namer.apidocs_directory(revision)
-    to_loc = release_namer.apidocs_directory(to_revision)
-    remove_gs_directory(to_loc)
-    Gsutil(['-m', 'cp', '-a', 'public-read', '-R', from_loc, to_loc])
+    # Copy api-docs zipfile.
+    from_loc = raw_namer.apidocs_zipfilepath(revision)
+    to_loc = release_namer.apidocs_zipfilepath(to_revision)
+    Gsutil(['-m', 'cp', '-a', 'public-read', from_loc, to_loc])
 
     # Copy dartium directory.
     from_loc = raw_namer.dartium_directory(revision)
diff --git a/tools/sdks/linux/dart-sdk.tar.gz.sha1 b/tools/sdks/linux/dart-sdk.tar.gz.sha1
index b9db509..90b6e73 100644
--- a/tools/sdks/linux/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/linux/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-e525a9271e840f53382edfab773ad330384d8caa
\ No newline at end of file
+2709941a74b808414feb005dfa50986680f9bd20
\ No newline at end of file
diff --git a/tools/sdks/mac/dart-sdk.tar.gz.sha1 b/tools/sdks/mac/dart-sdk.tar.gz.sha1
index d88e4ae..9f3c196 100644
--- a/tools/sdks/mac/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/mac/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-b80cd51c9fe293de25273102de5b2721aacc8aba
\ No newline at end of file
+8d928e400289862483a11e798743e49815c06c43
\ No newline at end of file
diff --git a/tools/sdks/win/dart-sdk.tar.gz.sha1 b/tools/sdks/win/dart-sdk.tar.gz.sha1
index 97a2743..a5b7f6a 100644
--- a/tools/sdks/win/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/win/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-e098625fb19d40c9554f88e3306987c2c5988963
\ No newline at end of file
+90d43da115a1eafe707f6f5c5c0d718ff716c227
\ No newline at end of file
diff --git a/tools/task_kill.py b/tools/task_kill.py
index 4a54965..ab07e8a 100755
--- a/tools/task_kill.py
+++ b/tools/task_kill.py
@@ -206,7 +206,11 @@
   options = GetOptions()
   status = 0
   if options.kill_dart:
-    status += KillDart()
+    if os_name == "win32":
+      # TODO(24086): Add result of KillDart into status once pub hang is fixed.
+      KillDart()
+    else:
+      status += KillDart()
   if options.kill_fletch:
     status += KillFletch()
   if options.kill_vc:
diff --git a/tools/testing/bin/jsshell b/tools/testing/bin/jsshell
index 359950d..c9dc261 100755
--- a/tools/testing/bin/jsshell
+++ b/tools/testing/bin/jsshell
@@ -1,16 +1,17 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # 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.
 
+JSDIR=${0%/*}/../../../third_party/firefox_jsshell
 
 case $OSTYPE in
     *[Dd]arwin*)
-        exec ${0%/*}/../../../third_party/firefox_jsshell/macos/js "$@"
+        exec $JSDIR/mac/jsshell/js "$@"
         ;;
     *[Ll]inux*)
-        LD_LIBRARY_PATH=${0%/*}/../../../third_party/firefox_jsshell/linux/ \
-            exec ${0%/*}/../../../third_party/firefox_jsshell/linux/js "$@"
+        LD_LIBRARY_PATH=$JSDIR/linux/jsshell/ \
+            exec $JSDIR/linux/jsshell/js "$@"
         ;;
     *)
         echo No jsshell binary for $(uname) >2
diff --git a/tools/testing/bin/jsshell.bat b/tools/testing/bin/jsshell.bat
index e99335f..0666885 100644
--- a/tools/testing/bin/jsshell.bat
+++ b/tools/testing/bin/jsshell.bat
@@ -10,4 +10,4 @@
 

 set arguments=%*

 

-"%SCRIPTPATH%..\..\..\third_party\firefox_jsshell\windows\js.exe" %arguments%

+"%SCRIPTPATH%..\..\..\third_party\firefox_jsshell\win\jsshell\js.exe" %arguments%

diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index 7c7b27e..f138688e 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -28,7 +28,6 @@
 const List<List<String>> COMMAND_LINES = const <List<String>>[
     const <String>['-mrelease,debug', '-rvm', '-cnone'],
     const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
-    const <String>['-mrelease', '-rnone', '-cdartanalyzer'],
     const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
     const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
     const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 9ec90f0..a89aad5 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -61,14 +61,11 @@
     bool useSdk = configuration['use_sdk'];
     bool isCsp = configuration['csp'];
     bool useCps = configuration['cps_ir'];
+    bool useNoopt = configuration['noopt'];
 
     switch (compiler) {
-      case 'dartanalyzer':
-        return new AnalyzerCompilerConfiguration(
-            'dartanalyzer', isDebug: isDebug, isChecked: isChecked,
-            isHostChecked: isHostChecked, useSdk: useSdk);
       case 'dart2analyzer':
-        return new DartBasedAnalyzerCompilerConfiguration(
+        return new AnalyzerCompilerConfiguration(
             isDebug: isDebug, isChecked: isChecked,
             isHostChecked: isHostChecked, useSdk: useSdk);
       case 'dart2js':
@@ -77,10 +74,13 @@
             isHostChecked: isHostChecked, useCps: useCps, useSdk: useSdk,
             isCsp: isCsp, extraDart2jsOptions:
                 TestUtils.getExtraOptions(configuration, 'dart2js_options'));
+      case 'precompiler':
+        return new PrecompilerCompilerConfiguration(
+            isDebug: isDebug, isChecked: isChecked);
       case 'none':
         return new NoneCompilerConfiguration(
             isDebug: isDebug, isChecked: isChecked,
-            isHostChecked: isHostChecked, useSdk: useSdk);
+            isHostChecked: isHostChecked, useSdk: useSdk, useNoopt: useNoopt);
       default:
         throw "Unknown compiler '$compiler'";
     }
@@ -122,6 +122,12 @@
     return new CommandArtifact([], null, null);
   }
 
+  List<String> computeCompilerArguments(vmOptions, sharedOptions, args) {
+    return new List<String>()
+        ..addAll(sharedOptions)
+        ..addAll(args);
+  }
+
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
       String buildDir,
@@ -136,14 +142,17 @@
 
 /// The "none" compiler.
 class NoneCompilerConfiguration extends CompilerConfiguration {
+  final bool useNoopt;
+
   NoneCompilerConfiguration({
       bool isDebug,
       bool isChecked,
       bool isHostChecked,
-      bool useSdk})
+      bool useSdk,
+      bool useNoopt})
       : super._subclass(
           isDebug: isDebug, isChecked: isChecked,
-          isHostChecked: isHostChecked, useSdk: useSdk);
+          isHostChecked: isHostChecked, useSdk: useSdk), useNoopt = useNoopt;
 
   bool get hasCompiler => false;
 
@@ -160,6 +169,9 @@
       args.add('--enable_asserts');
       args.add('--enable_type_checks');
     }
+    if (useNoopt) {
+      args.add('--noopt');
+    }
     return args
         ..addAll(vmOptions)
         ..addAll(sharedOptions)
@@ -291,12 +303,94 @@
   }
 }
 
-/// Common configuration for analyzer-based tools, such as, dartanalyzer.
-class AnalyzerCompilerConfiguration extends CompilerConfiguration {
-  final String moniker;
 
+class PrecompilerCompilerConfiguration extends CompilerConfiguration {
+  PrecompilerCompilerConfiguration({
+      bool isDebug,
+      bool isChecked})
+      : super._subclass(isDebug: isDebug, isChecked: isChecked);
+
+  int computeTimeoutMultiplier() {
+    int multiplier = 2;
+    if (isDebug) multiplier *= 4;
+    if (isChecked) multiplier *= 2;
+    return multiplier;
+  }
+
+  CommandArtifact computeCompilationArtifact(
+      String buildDir,
+      String tempDir,
+      CommandBuilder commandBuilder,
+      List arguments,
+      Map<String, String> environmentOverrides) {
+    return new CommandArtifact(
+        <Command>[
+            this.computeCompilationCommand(
+                tempDir,
+                buildDir,
+                CommandBuilder.instance,
+                arguments,
+                environmentOverrides)],
+        '$tempDir',
+        'application/dart-precompiled');
+  }
+
+  CompilationCommand computeCompilationCommand(
+      String tempDir,
+      String buildDir,
+      CommandBuilder commandBuilder,
+      List arguments,
+      Map<String, String> environmentOverrides) {
+    var exec = "$buildDir/dart";
+    var args = new List();
+    args.add("tools/precompilation/precompiler.dart");
+    args.add("$buildDir/dart_no_snapshot");
+    args.add("--gen-precompiled-snapshot=$tempDir");
+    args.addAll(arguments);
+
+    return commandBuilder.getCompilationCommand(
+        'precompiler.dart', tempDir, !useSdk,
+        bootstrapDependencies(buildDir),
+        exec, args, environmentOverrides);
+  }
+
+  List<String> computeCompilerArguments(vmOptions,
+                                        sharedOptions,
+                                        originalArguments) {
+    List<String> args = [];
+    if (isChecked) {
+      args.add('--enable_asserts');
+      args.add('--enable_type_checks');
+    }
+    return args
+        ..addAll(vmOptions)
+        ..addAll(sharedOptions)
+        ..addAll(originalArguments);
+  }
+
+  List<String> computeRuntimeArguments(
+      RuntimeConfiguration runtimeConfiguration,
+      String buildDir,
+      TestInformation info,
+      List<String> vmOptions,
+      List<String> sharedOptions,
+      List<String> originalArguments,
+      CommandArtifact artifact) {
+    List<String> args = [];
+    if (isChecked) {
+      args.add('--enable_asserts');
+      args.add('--enable_type_checks');
+    }
+    return args
+        ..addAll(vmOptions)
+        ..addAll(sharedOptions)
+        ..addAll(originalArguments);
+  }
+}
+
+
+class AnalyzerCompilerConfiguration extends CompilerConfiguration {
   AnalyzerCompilerConfiguration(
-      this.moniker,
       {bool isDebug,
       bool isChecked,
       bool isHostChecked,
@@ -310,54 +404,6 @@
   }
 
   String computeCompilerPath(String buildDir) {
-    String suffix = executableScriptSuffix;
-    return 'sdk/bin/dartanalyzer_java$suffix';
-  }
-
-  CommandArtifact computeCompilationArtifact(
-      String buildDir,
-      String tempDir,
-      CommandBuilder commandBuilder,
-      List arguments,
-      Map<String, String> environmentOverrides) {
-    arguments = new List.from(arguments);
-    if (isChecked) {
-      arguments.add('--enable_type_checks');
-    }
-    return new CommandArtifact(
-        <Command>[
-            commandBuilder.getAnalysisCommand(
-                moniker, computeCompilerPath(buildDir), arguments,
-                environmentOverrides,
-                flavor: moniker)],
-        null, null); // Since this is not a real compilation, no artifacts are
-                     // produced.
-  }
-
-  List<String> computeRuntimeArguments(
-      RuntimeConfiguration runtimeConfiguration,
-      String buildDir,
-      TestInformation info,
-      List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> originalArguments,
-      CommandArtifact artifact) {
-    return <String>[];
-  }
-}
-
-class DartBasedAnalyzerCompilerConfiguration
-    extends AnalyzerCompilerConfiguration {
-  DartBasedAnalyzerCompilerConfiguration({
-      bool isDebug,
-      bool isChecked,
-      bool isHostChecked,
-      bool useSdk})
-      : super(
-          'dart2analyzer', isDebug: isDebug, isChecked: isChecked,
-          isHostChecked: isHostChecked, useSdk: useSdk);
-
-  String computeCompilerPath(String buildDir) {
     var prefix = 'sdk/bin';
     String suffix = executableScriptSuffix;
     if (isHostChecked) {
@@ -374,4 +420,35 @@
     }
     return '$prefix/dartanalyzer$suffix';
   }
+
+  CommandArtifact computeCompilationArtifact(
+      String buildDir,
+      String tempDir,
+      CommandBuilder commandBuilder,
+      List arguments,
+      Map<String, String> environmentOverrides) {
+    arguments = new List.from(arguments);
+    if (isChecked) {
+      arguments.add('--enable_type_checks');
+    }
+    return new CommandArtifact(
+        <Command>[
+            commandBuilder.getAnalysisCommand(
+                'dart2analyzer', computeCompilerPath(buildDir), arguments,
+                environmentOverrides,
+                flavor: 'dart2analyzer')],
+        null, null); // Since this is not a real compilation, no artifacts are
+                     // produced.
+  }
+
+  List<String> computeRuntimeArguments(
+      RuntimeConfiguration runtimeConfiguration,
+      String buildDir,
+      TestInformation info,
+      List<String> vmOptions,
+      List<String> sharedOptions,
+      List<String> originalArguments,
+      CommandArtifact artifact) {
+    return <String>[];
+  }
 }
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 7f5fae7..843aaaf 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -260,7 +260,13 @@
       websocket.done.catchError((_) {});
       websocket.listen((data) {
         websocket.add(data);
-        websocket.close();
+        if (data == 'close-with-error') {
+          // Note: according to the web-sockets spec, a reason longer than 123
+          // bytes will produce a SyntaxError on the client.
+          websocket.close(WebSocketStatus.UNSUPPORTED_DATA, 'X' * 124);
+        } else {
+          websocket.close();
+        }
       }, onError: (e) {
         DebugLogger.warning('HttpServer: error while echoing to WebSocket', e);
       });
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index 1fbf54d..55810eb 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -52,6 +52,9 @@
       case 'vm':
         return new StandaloneDartRuntimeConfiguration();
 
+      case 'dart_precompiled':
+        return new DartPrecompiledRuntimeConfiguration();
+
       case 'drt':
         return new DrtRuntimeConfiguration();
 
@@ -218,6 +221,32 @@
   }
 }
 
+
+class DartPrecompiledRuntimeConfiguration extends DartVmRuntimeConfiguration {
+  List<Command> computeRuntimeCommands(
+      TestSuite suite,
+      CommandBuilder commandBuilder,
+      CommandArtifact artifact,
+      List<String> arguments,
+      Map<String, String> environmentOverrides) {
+    String script = artifact.filename;
+    String type = artifact.mimeType;
+    if (script != null && type != 'application/dart-precompiled') {
+      throw "dart_precompiled cannot run files of type '$type'.";
+    }
+
+    var augmentedArgs = new List();
+    augmentedArgs.add("--run-precompiled-snapshot=${artifact.filename}");
+    augmentedArgs.addAll(arguments);
+
+    var augmentedEnv = new Map.from(environmentOverrides);
+    augmentedEnv['LD_LIBRARY_PATH'] = artifact.filename;
+
+    return <Command>[commandBuilder.getVmCommand(
+          suite.dartPrecompiledBinaryFileName, augmentedArgs, augmentedEnv)];
+  }
+}
+
 /// Temporary runtime configuration for browser runtimes that haven't been
 /// migrated yet.
 // TODO(ahe): Remove this class.
diff --git a/tools/testing/dart/status_reporter.dart b/tools/testing/dart/status_reporter.dart
index 0e744d0..5841052 100644
--- a/tools/testing/dart/status_reporter.dart
+++ b/tools/testing/dart/status_reporter.dart
@@ -9,8 +9,8 @@
     {
       'runtimes' : ['none'],
       'modes' : ['release'],
-      'archs' : ['ia32'],
-      'compiler' : 'dartanalyzer'
+      'archs' : ['x64'],
+      'compiler' : 'dart2analyzer'
     },
     {
       'runtimes' : ['vm'],
diff --git a/tools/testing/dart/test_configurations.dart b/tools/testing/dart/test_configurations.dart
index c552282..f4ea6d6 100644
--- a/tools/testing/dart/test_configurations.dart
+++ b/tools/testing/dart/test_configurations.dart
@@ -99,6 +99,7 @@
       List settings = ['compiler', 'runtime', 'mode', 'arch']
           .map((name) => conf[name]).toList();
       if (conf['checked']) settings.add('checked');
+      if (conf['noopt']) settings.add('noopt');
       output_words.add(settings.join('_'));
     }
     print(output_words.join(' '));
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index ca0adad..92514fe 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -64,11 +64,10 @@
          safari, ie9, ie10, ie11, firefox, opera, chromeOnAndroid,
          none (compile only)),
 
-   dartanalyzer: Perform static analysis on Dart code by running the analyzer on Java.
-   dart2analyzer: Perform static analysis on Dart code by running the analyzer on Dart.
+   dart2analyzer: Perform static analysis on Dart code by running the analyzer
           (only valid with the following runtimes: none)''',
               ['-c', '--compiler'],
-              ['none', 'dart2js', 'dartanalyzer', 'dart2analyzer'],
+              ['none', 'precompiler', 'dart2js', 'dart2analyzer'],
               'none'),
           // TODO(antonm): fix the option drt.
           new _TestOptionSpecification(
@@ -76,6 +75,9 @@
               '''Where the tests should be run.
     vm: Run Dart code on the standalone dart vm.
 
+    dart_precompiled: Run a precompiled snapshot on a variant of the standalone
+                      dart vm lacking a JIT.
+
     d8: Run JavaScript from the command line using v8.
 
     jsshell: Run JavaScript from the command line using firefox js-shell.
@@ -93,10 +95,11 @@
     [ff | chrome | safari | ie9 | ie10 | ie11 | opera | chromeOnAndroid]:
         Run JavaScript in the specified browser.
 
-    none: No runtime, compile only (for example, used for dartanalyzer static
+    none: No runtime, compile only (for example, used for dart2analyzer static
           analysis tests).''',
               ['-r', '--runtime'],
-              ['vm', 'd8', 'jsshell', 'drt', 'dartium', 'ff', 'firefox',
+              ['vm', 'dart_precompiled', 'd8', 'jsshell', 'drt', 'dartium',
+               'ff', 'firefox',
                'chrome', 'safari', 'ie9', 'ie10', 'ie11', 'opera',
                'chromeOnAndroid', 'safarimobilesim',
                'ContentShellOnAndroid', 'DartiumOnAndroid', 'none'],
@@ -107,7 +110,7 @@
               ['-a', '--arch'],
               ['all', 'ia32', 'x64', 'arm', 'armv5te', 'arm64', 'mips',
                'simarm', 'simarmv5te', 'simarm64', 'simmips'],
-              'ia32'),
+              'x64'),
           new _TestOptionSpecification(
               'system',
               'The operating system to run tests on',
@@ -150,6 +153,13 @@
               false,
               type: 'bool'),
           new _TestOptionSpecification(
+              'noopt',
+              'Run an in-place precompilation',
+              ['--noopt'],
+              [],
+              false,
+              type: 'bool'),
+          new _TestOptionSpecification(
               'timeout',
               'Timeout in seconds',
               ['-t', '--timeout'],
@@ -635,10 +645,12 @@
                                'ff', 'chrome', 'safari', 'ie9', 'ie10', 'ie11',
                                'opera', 'chromeOnAndroid', 'safarimobilesim'];
         break;
-      case 'dartanalyzer':
       case 'dart2analyzer':
         validRuntimes = const ['none'];
         break;
+      case 'precompiler':
+        validRuntimes = const ['dart_precompiled'];
+        break;
       case 'none':
         validRuntimes = const ['vm', 'drt', 'dartium',
                                'ContentShellOnAndroid', 'DartiumOnAndroid'];
@@ -875,7 +887,7 @@
    */
   _TestOptionSpecification _getSpecification(String name) {
     for (var option in _options) {
-      if (option.keys.any((key) => key == name)) {
+      if (option.keys.contains(name)) {
         return option;
       }
     }
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 97ad17a..ffd9921 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -610,7 +610,7 @@
 
   AnalysisCommand getAnalysisCommand(
       String displayName, executable, arguments, environmentOverrides,
-      {String flavor: 'dartanalyzer'}) {
+      {String flavor: 'dart2analyzer'}) {
     var command = new AnalysisCommand._(
         flavor, displayName, executable, arguments, environmentOverrides);
     return _getUniqueCommand(command);
@@ -1679,6 +1679,10 @@
     return new VmCommandOutputImpl(
         command, exitCode, timedOut, stdout, stderr, time, pid);
   } else if (command is CompilationCommand) {
+    if (command.displayName == 'precompiler.dart') {
+      return new VmCommandOutputImpl(
+          command, exitCode, timedOut, stdout, stderr, time, pid);
+    }
     return new CompilationCommandOutputImpl(
         command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
   } else if (command is JSCommandlineCommand) {
@@ -2450,7 +2454,8 @@
   final int maxProcesses;
   final int maxBrowserProcesses;
 
-  // For dartanalyzer batch processing we keep a list of batch processes.
+  // For dart2js and analyzer batch processing,
+  // we keep a list of batch processes.
   final _batchProcesses = new Map<String, List<BatchRunnerProcess>>();
   // We keep a BrowserTestRunner for every configuration.
   final _browserTestRunners = new Map<Map, BrowserTestRunner>();
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index b4e7b53..533c01c 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -212,6 +212,19 @@
     return dartExecutable;
   }
 
+  String get dartPrecompiledBinaryFileName {
+    // Controlled by user with the option "--dart_precompiled".
+    String dartExecutable = configuration['dart_precompiled'];
+
+    if (dartExecutable == null || dartExecutable == '') {
+      String suffix = executableBinarySuffix;
+      dartExecutable = '$buildDir/dart_precompiled$suffix';
+    }
+
+    TestUtils.ensureExists(dartExecutable, configuration);
+    return dartExecutable;
+  }
+
   String get d8FileName {
     var suffix = getExecutableSuffix('d8');
     var d8Dir = TestUtils.dartDir.append('third_party/d8');
@@ -224,7 +237,7 @@
   String get jsShellFileName {
     var executableSuffix = getExecutableSuffix('jsshell');
     var executable = 'jsshell$executableSuffix';
-    var jsshellDir = '${TestUtils.dartDir}/tools/testing/bin';
+    var jsshellDir = '${TestUtils.dartDir.toNativePath()}/tools/testing/bin';
     return '$jsshellDir/$executable';
   }
 
@@ -674,7 +687,6 @@
     var status_paths = ['$directory/$name.status',
                         '$directory/.status',
                         '$directory/${name}_dart2js.status',
-                        '$directory/${name}_analyzer.status',
                         '$directory/${name}_analyzer2.status'];
 
     return new StandardTestSuite(configuration,
@@ -883,6 +895,12 @@
       var packageDirectories = {};
       if (configuration['use_repository_packages']) {
         packageDirectories = new Map.from(localPackageDirectories);
+
+        // Don't create a dependency override for pub, since it's an application
+        // package and it has a dependency on compiler_unsupported which isn't
+        // in the repo.
+        packageDirectories.remove('pub');
+
         // Do not create an dependency override for the package itself.
         if (packageDirectories.containsKey(packageName)) {
           packageDirectories.remove(packageName);
@@ -1010,9 +1028,10 @@
     List<String> compileTimeArguments = <String>[];
     String tempDir;
     if (compilerConfiguration.hasCompiler) {
-      compileTimeArguments
-          ..addAll(sharedOptions)
-          ..addAll(args);
+      compileTimeArguments =
+          compilerConfiguration.computeCompilerArguments(vmOptions,
+                                                         sharedOptions,
+                                                         args);
       // Avoid doing this for analyzer.
       tempDir = createCompilationOutputDirectory(info.filePath);
     }
@@ -1502,7 +1521,6 @@
       case 'none':
         return 'application/dart';
       case 'dart2js':
-      case 'dartanalyzer':
       case 'dart2analyzer':
         return 'text/javascript';
       default:
@@ -1551,8 +1569,7 @@
       args.add('--no-hints');
     }
 
-    if ((configuration["compiler"] == "dartanalyzer" ||
-        configuration["compiler"] == "dart2analyzer") &&
+    if (configuration["compiler"] == "dart2analyzer" &&
         (filePath.filename.contains("dart2js") ||
         filePath.directoryPath.segments().last.contains('html_common'))) {
       args.add("--use-dart2js-libraries");
@@ -1775,8 +1792,8 @@
   }
 
   List<List<String>> getVmOptions(Map optionsFromFile) {
-    var COMPILERS = const ['none'];
-    var RUNTIMES = const ['none', 'vm', 'drt', 'dartium',
+    var COMPILERS = const ['none', 'precompiler'];
+    var RUNTIMES = const ['none', 'dart_precompiled', 'vm', 'drt', 'dartium',
                           'ContentShellOnAndroid', 'DartiumOnAndroid'];
     var needsVmOptions = COMPILERS.contains(configuration['compiler']) &&
                          RUNTIMES.contains(configuration['runtime']);
@@ -1977,6 +1994,12 @@
         var packageDirectories = {};
         if (!configuration['use_public_packages']) {
           packageDirectories = new Map.from(localPackageDirectories);
+
+          // Don't create a dependency override for pub, since it's an
+          // application package and it has a dependency on compiler_unsupported
+          // which isn't in the repo.
+          packageDirectories.remove('pub');
+
           if (packageDirectories.containsKey(packageName)) {
             packageDirectories.remove(packageName);
           }
@@ -2247,7 +2270,7 @@
     if (compiler == "dart2js" && configuration["cps_ir"]) {
       args.add("--use-cps-ir");
     }
-    if (compiler == "dartanalyzer" || compiler == "dart2analyzer") {
+    if (compiler == "dart2analyzer") {
       args.add("--show-package-warnings");
       args.add("--enable-async");
     }
@@ -2277,7 +2300,7 @@
       const ['d8', 'jsshell'].contains(runtime);
 
   static bool isCommandLineAnalyzer(String compiler) =>
-      compiler == 'dartanalyzer' || compiler == 'dart2analyzer';
+      compiler == 'dart2analyzer';
 
   static String buildDir(Map configuration) {
     // FIXME(kustermann,ricow): Our code assumes that the returned 'buildDir'
diff --git a/tools/testing/perf_testing/appengine/app.yaml b/tools/testing/perf_testing/appengine/app.yaml
deleted file mode 100644
index 3fd8832..0000000
--- a/tools/testing/perf_testing/appengine/app.yaml
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-application: google.com:dartperf
-version: 1
-runtime: python
-api_version: 1
-
-handlers:
-- url: /(.*\.html)
-  mime_type: text/html
-  static_files: static/\1
-  upload: static/(.*\.html)
-
-- url: /(.*\.js)
-  mime_type: text/javascript
-  static_files: static/\1
-  upload: static/(.*\.js)
-
-- url: /(.*\.txt)
-  mime_type: text/html
-  static_files: static/\1
-  upload: static/(.*\.txt)
-
-- url: /(.*\.json)
-  mime_type: application/json
-  static_files: static/\1
-  upload: static/(.*\.json)
-
-# image files
-- url: /(.*\.(bmp|gif|ico|jpeg|jpg|png))
-  static_files: static/\1
-  upload: static/(.*\.(bmp|gif|ico|jpeg|jpg|png))
-
-# index files
-- url: /(.+)/
-  static_files: static/\1/index.html
-  upload: static/(.+)/index.html
-  expiration: "15m"
-
-- url: /(.+)
-  static_files: static/\1/index.html
-  upload: static/(.+)/index.html
-  expiration: "15m"
-
-- url: /graphs
-  static_dir: static/graphs
-
-- url: /graphs/(.*)
-  static_files: static/graphs/\1
-  upload: static/graphs/(.*)
-
-- url: /data/browser-perf/macos/(.*)
-  static_files: static/data/browser-perf/macos/\1
-  upload: static/data/browser-perf/macos/(.*)
-
-- url: /data/code-time-size/macos/(.*)
-  static_files: static/data/code-time-size/macos/\1
-  upload: static/data/code-time-size/macos/(.*)
-
-- url: /data/cl-results/macos/(.*)
-  static_files: static/data/cl-results/macos/\1
-  upload: static/data/cl-results/macos/(.*)
-
-# site root
-- url: /
-  static_files: static/index.html
-  upload: static/index.html
-  expiration: "15m"
diff --git a/tools/testing/perf_testing/calc_and_send_mail.py b/tools/testing/perf_testing/calc_and_send_mail.py
deleted file mode 100644
index 090b70e..0000000
--- a/tools/testing/perf_testing/calc_and_send_mail.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import create_graph
-from create_graph import BROWSER_CORRECTNESS
-from create_graph import BROWSER_PERF
-from create_graph import CL_PERF
-from create_graph import COMMAND_LINE
-from create_graph import CORRECTNESS
-from create_graph import FROG
-from create_graph import FROG_MEAN
-from create_graph import TIME_SIZE
-from create_graph import V8_AND_FROG
-
-import get_current_stats
-import os
-from os.path import dirname, abspath
-import pickle
-import sys
-
-"""Compare the current performance statistics with the statistics 24 hours ago,
-and send out an email summarizing the differences."""
-
-def calculate_stats():
-  """Compare the numbers that were available at the start of the day to what the
-  current numbers are.
-
-  Returns:
-    A string providing an update on the latest perfromance numbers."""
-  test_runner_dict = pickle.load(open(get_current_stats.PICKLE_FILENAME, 'r'))
-  test_runner_dict = get_current_stats.populate_stats_dict(test_runner_dict)
-
-  browser_perf = test_runner_dict[BROWSER_PERF]
-  time_size = test_runner_dict[TIME_SIZE]
-  cl = test_runner_dict[CL_PERF]
-  correctness = test_runner_dict[BROWSER_CORRECTNESS]
-  output = summary_stats(browser_perf, time_size, cl, correctness)
-  output += specific_stats(browser_perf, time_size, cl)
-  return output
-
-def summary_stats(browser_perf, time_size, cl, correctness):
-  """Return the summarized stats report.
-
-  Args:
-    browser_perf: BrowserPerformanceTestRunner object. Holds browser perf stats.
-    time_size: CompileTimeSizeTestRunner object. 
-    cl: CommandLinePerformanceTestRunner object.
-    correctness: BrowserCorrectnessTestRunner object.
-  """
-  output = "Summary of changes in the last 24 hours: \n\nBrowser " + \
-      "performance: (revision %d)\n" % \
-      browser_perf.revision_dict[create_graph.get_browsers()[0]][FROG]\
-      [browser_perf.values_list[0]][1]
-  for browser in create_graph.get_browsers():
-    geo_mean_list = browser_perf.values_dict[browser][FROG][FROG_MEAN]
-    # TODO(efortuna): deal with the fact that the latest of all browsers may not
-    # be available.
-    output += "  %s%s\n" % ((browser + ':').ljust(25), 
-        str(geo_mean_list[1] - geo_mean_list[0]).rjust(10))
-
-  output += "\nCompile Size and Time: (revision %d)\n" % \
-      time_size.revision_dict[COMMAND_LINE][FROG][time_size.values_list[0]][1]
-  for metric in time_size.values_list:
-    metric_list = time_size.values_dict[COMMAND_LINE][FROG][metric]
-    output += "  %s%s\n" % ((metric + ':').ljust(25), 
-        str(metric_list[1] - metric_list[0]).rjust(10))
-
-  output += "\nPercentage of language tests passing (revision %d)\n" % \
-      correctness.revision_dict['chrome'][FROG][correctness.values_list[0]][1]
-  for browser in create_graph.get_browsers():
-    num_correct = correctness.values_dict[browser][FROG][CORRECTNESS]
-    output += "  %s%s%%  more passing\n" % ((browser + ':').ljust(25), 
-        str(num_correct[1] - num_correct[0]).rjust(10))
-
-  output += "\nCommandline performance: (revision %d)\n" % \
-      cl.revision_dict[COMMAND_LINE][FROG][cl.values_list[0]][1]
-  for benchmark in cl.values_list:
-    bench_list = cl.values_dict[COMMAND_LINE][FROG][benchmark]
-    output += "  %s%s\n" % ((benchmark + ':').ljust(25), 
-        str(bench_list[1] - bench_list[0]).rjust(10))
-  return output
-
-def specific_stats(browser_perf, time_size, cl):
-  """Return a string detailing all of the gory details and specifics on 
-  benchmark numbers and individual benchmark changes.
-
-  Args:
-    browser_perf: BrowserPerformanceTestRunner object. Holds browser perf stats.
-    time_size: CompileTimeSizeTestRunner object. 
-    cl: CommandLinePerformanceTestRunner object.
-  """
-  output = "\n\n---------------------------------------------\nThe latest " + \
-      "current raw numbers (and changes) for those " + \
-      "interested:\nBrowser performance:\n"
-  for v8_or_frog in V8_AND_FROG:
-    for browser in create_graph.get_browsers():
-      output += "  %s %s:\n" % (browser, v8_or_frog)
-      for benchmark in create_graph.get_benchmarks():
-        bench_list = browser_perf.values_dict[browser][v8_or_frog][benchmark]
-        output += "    %s %s%s\n" % ((benchmark + ':').ljust(25), 
-            str(bench_list[1]).rjust(10), get_amount_changed(bench_list))
-
-  output += "\nCompile Size and Time for frog:\n" 
-  for metric in time_size.values_list:
-    metric_list = time_size.values_dict[COMMAND_LINE][FROG][metric]
-    output += "    %s %s%s\n" % ((metric + ':').ljust(25), 
-        str(metric_list[1]).rjust(10), get_amount_changed(metric_list))
-
-  output += "\nCommandline performance:\n"
-  for v8_or_frog in V8_AND_FROG:
-    output += '  %s:\n' % v8_or_frog
-    for benchmark in cl.values_list:
-      bench_list = cl.values_dict[COMMAND_LINE][v8_or_frog][benchmark]
-      output += "    %s %s%s\n" % ((benchmark + ':').ljust(25), 
-          str(bench_list[1]).rjust(10), get_amount_changed(bench_list))
-
-  return output
-
-def get_amount_changed(values_tuple):
-  """Return a formatted string indicating the amount of change (positive or
-  negative) in the benchmark since the last run.
-
-  Args:
-    values_tuple: the tuple of values we are comparing the difference 
-    between."""
-  difference = values_tuple[1] - values_tuple[0]
-  prefix = '+' 
-  if difference < 0:
-    prefix = '-'
-  return ("(%s%s)" % (prefix, str(difference))).rjust(10)
-
-
-def main():
-  stats = calculate_stats()
-  print stats
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/testing/perf_testing/data.html b/tools/testing/perf_testing/data.html
deleted file mode 100644
index daa8ba9..0000000
--- a/tools/testing/perf_testing/data.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-<head>
-<title>raw data</title>
-<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-</head>
-<body>
-  <ul>
-    <li><a href="browser-perf-macos.html">Mac Browser Performance</a></li>
-    <li><a href="browser-perf-win32.html">Windows Browser Performance
-          (data not available yet)</a></li>
-    <li><a href="cl-results-macos.html">Mac Command Line Performance</a></li>
-    <li><a href="code-time-size-macos.html">Mac Compilation Time and Output Size</a></li>
-  </ul>
-</body>
-</html>
diff --git a/tools/testing/perf_testing/dromaeo.html b/tools/testing/perf_testing/dromaeo.html
deleted file mode 100644
index aee032d..0000000
--- a/tools/testing/perf_testing/dromaeo.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-<head>
-<title>Dart DOM metrics</title>
-<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-</head>
-<body>
-<p><a href="data.html">Raw Data Logs</a></p>
-<img src="graphs/avg2dromaeo.png" />
-<img src="graphs/avg3dromaeo.png" />
-<img src="graphs/avg4dromaeo.png" />
-<img src="graphs/avg5dromaeo.png" />
-<img src="graphs/avg6dromaeo.png" />
-<img src="graphs/2dromaeo-size.png" />
-<br />
-
-<hr />
-
-<p> Individual Dromaeo benchmark performance </p>
-
-<p> Attributes benchmarks: </p>
-<img src="graphs/getAttributedromaeo.png" />
-<img src="graphs/element.propertydromaeo.png" />
-<img src="graphs/setAttributedromaeo.png" />
-<img src="graphs/element.property_ASSIGN_valuedromaeo.png" />
-
-<p> Modify benchmarks: </p>
-<img src="graphs/createElementdromaeo.png" />
-<img src="graphs/createTextNodedromaeo.png" />
-<img src="graphs/innerHTMLdromaeo.png" />
-<img src="graphs/cloneNodedromaeo.png" />
-<img src="graphs/appendChilddromaeo.png" />
-<img src="graphs/insertBeforedromaeo.png" />
-
-<p> Query benchmarks: </p>
-<img src="graphs/getElementByIddromaeo.png" />
-<img src="graphs/getElementById__not_in_document_dromaeo.png" />
-<img src="graphs/getElementsByTagName_div_dromaeo.png" />
-<img src="graphs/getElementsByTagName_p_dromaeo.png" />
-<img src="graphs/getElementsByTagName_a_dromaeo.png" />
-<img src="graphs/getElementsByTagName_ALL_dromaeo.png" />
-<img src="graphs/getElementsByTagName__not_in_document_dromaeo.png" />
-<img src="graphs/getElementsByNamedromaeo.png" />
-<img src="graphs/getElementsByName__not_in_document_dromaeo.png" />
-
-<p> Traverse benchmarks: </p>
-<img src="graphs/firstChilddromaeo.png" />
-<img src="graphs/lastChilddromaeo.png" />
-<img src="graphs/nextSiblingdromaeo.png" />
-<img src="graphs/previousSiblingdromaeo.png" />
-<img src="graphs/childNodesdromaeo.png" />
-
-</body>
-</html>
diff --git a/tools/testing/perf_testing/get_current_stats.py b/tools/testing/perf_testing/get_current_stats.py
deleted file mode 100644
index 4481501..0000000
--- a/tools/testing/perf_testing/get_current_stats.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-from create_graph import BROWSER_CORRECTNESS
-from create_graph import BrowserCorrectnessTest
-from create_graph import BROWSER_PERF
-from create_graph import BrowserPerformanceTest
-from create_graph import CL_PERF
-from create_graph import CommandLinePerformanceTest
-from create_graph import CompileTimeAndSizeTest
-from create_graph import TIME_SIZE
-
-import os
-from os.path import dirname, abspath
-import pickle
-import re
-import sys
-
-"""Find the most recent performance files, and store the stats."""
-
-# TODO(efortuna): turn these into proper appengine tasks, using the app engine 
-# datastore instead of files.
-
-DIRECTORIES = [BROWSER_CORRECTNESS, BROWSER_PERF, CL_PERF, TIME_SIZE]
-PICKLE_FILENAME = 'start_stats.txt'
-
-def find_latest_data_files(directory):
-  """Given a directory, find the files with the latest timestamp, indicating the
-  latest results.
-
-  Args:
-    directory: name of the directory we should look inside.
-
-  Returns:
-    A list of the most recent files in the particular directory."""
-  path = dirname(abspath(__file__))
-  files = os.listdir(os.path.join(path, directory))
-  files.sort()
-  f = files.pop()
-  match = re.search('[1-9]', f)
-  trace_name = f[:match.start()]
-  timestamp_and_data = f[match.start():]
-  latest_files = [f]
-  if trace_name == 'correctness' or trace_name == 'perf-':
-    index = timestamp_and_data.find('-')
-    timestamp = timestamp_and_data[:index]
-    f = files.pop()
-    while f[match.start() : match.start() + index] == timestamp:
-      latest_files.append(f)
-      f = files.pop()
-  return latest_files
-
-def populate_stats_dict(test_runner_dict = None):
-  """Find the latest files in each directory, and process those latest files
-  using the appropriate TestRunner.
-
-  Args:
-    test_runner_dict: Optional agument storing previous data in runners to which
-    we should add our data."""
-  cur_runner_dict = dict()
-  if test_runner_dict:
-    cur_runner_dict = test_runner_dict
-  for directory in DIRECTORIES:
-    test_runner = None
-    latest_files = find_latest_data_files(directory)
-    
-    if test_runner_dict:
-      test_runner = cur_runner_dict[directory]
-    else:
-      if directory == BROWSER_CORRECTNESS:
-        test_runner = BrowserCorrectnessTest('language', directory)
-      elif directory == BROWSER_PERF:
-        test_runner = BrowserPerformanceTest(directory)
-      elif directory == TIME_SIZE:
-        test_runner = CompileTimeAndSizeTest(directory)
-      elif directory == CL_PERF:
-        test_runner = CommandLinePerformanceTest(directory)
-      cur_runner_dict[directory] = test_runner
-    
-    for f in latest_files:
-      test_runner.process_file(f)
-  return cur_runner_dict
-
-def main():
-  test_runner_dict = populate_stats_dict()
-  f = open(PICKLE_FILENAME, 'w')
-  pickle.dump(test_runner_dict, f)
-  f.close()
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/testing/perf_testing/index.html b/tools/testing/perf_testing/index.html
deleted file mode 100644
index 171dab1..0000000
--- a/tools/testing/perf_testing/index.html
+++ /dev/null
@@ -1,100 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-<head>
-<title>frog metrics</title>
-<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
-</head>
-<body>
-<p><a href="data.html">Raw Data Logs</a></p>
-
-<p><a href="dromaeo.html">Dromaeo Results</a></p>
-
-<img src="graphs/avg2browser-perf.png" />
-<img src="win/avg2browser-perf.png" />
-<img src="graphs/code-time-size.png" />
-<img src="graphs/2code-time-size.png" />
-<img src="graphs/avg2cl-results.png" />
-<img src="graphs/avg2dromaeo.png" />
-<img src="graphs/2dromaeo-size.png" />
-<br />
-
-<hr />
-
-<p> Individual benchmark performance in the Browser on Mac:</p>
-
-<img src="graphs/Fannkuchbrowser-perf.png" />
-<img src="graphs/NBodybrowser-perf.png" />
-<img src="graphs/Richardsbrowser-perf.png" />
-<img src="graphs/Towersbrowser-perf.png" />
-<img src="graphs/Fibonaccibrowser-perf.png" />
-<img src="graphs/Permutebrowser-perf.png" />
-<img src="graphs/Sievebrowser-perf.png" />
-<img src="graphs/TreeSortbrowser-perf.png" />
-<img src="graphs/BinaryTreesbrowser-perf.png" />
-<img src="graphs/Loopbrowser-perf.png" />
-<img src="graphs/Queensbrowser-perf.png" />
-<img src="graphs/Sumbrowser-perf.png" />
-<img src="graphs/BubbleSortbrowser-perf.png" />
-<img src="graphs/Mandelbrotbrowser-perf.png" />
-<img src="graphs/QuickSortbrowser-perf.png" />
-<img src="graphs/browser-perf.png" />
-<img src="graphs/DeltaBluebrowser-perf.png" />
-<img src="graphs/Meteorbrowser-perf.png" />
-<img src="graphs/Recursebrowser-perf.png" />
-<img src="graphs/Taklbrowser-perf.png" />
-<img src="graphs/Takbrowser-perf.png" />
-
-<hr />
-<p> Individual benchmark performance in the Browser on Windows:</p>
-
-<img src="win/Fannkuchbrowser-perf.png" />
-<img src="win/NBodybrowser-perf.png" />
-<img src="win/Richardsbrowser-perf.png" />
-<img src="win/Towersbrowser-perf.png" />
-<img src="win/Fibonaccibrowser-perf.png" />
-<img src="win/Permutebrowser-perf.png" />
-<img src="win/Sievebrowser-perf.png" />
-<img src="win/TreeSortbrowser-perf.png" />
-<img src="win/BinaryTreesbrowser-perf.png" />
-<img src="win/Loopbrowser-perf.png" />
-<img src="win/Queensbrowser-perf.png" />
-<img src="win/Sumbrowser-perf.png" />
-<img src="win/BubbleSortbrowser-perf.png" />
-<img src="win/Mandelbrotbrowser-perf.png" />
-<img src="win/QuickSortbrowser-perf.png" />
-<img src="win/browser-perf.png" />
-<img src="win/DeltaBluebrowser-perf.png" />
-<img src="win/Meteorbrowser-perf.png" />
-<img src="win/Recursebrowser-perf.png" />
-<img src="win/Taklbrowser-perf.png" />
-<img src="win/Takbrowser-perf.png" />
-
-<hr />
-<p> Individual Command Line benchmark performance: </p>
-
-<img src="graphs/Fannkuchcl-results.png" />
-<img src="graphs/NBodycl-results.png" />
-<img src="graphs/Richardscl-results.png" />
-<img src="graphs/Towerscl-results.png" />
-<img src="graphs/3code-time-size.png" />
-<img src="graphs/Fibonaccicl-results.png" />
-<img src="graphs/Permutecl-results.png" />
-<img src="graphs/Sievecl-results.png" />
-<img src="graphs/TreeSortcl-results.png" />
-<img src="graphs/BinaryTreescl-results.png" />
-<img src="graphs/Loopcl-results.png" />
-<img src="graphs/Queenscl-results.png" />
-<img src="graphs/Sumcl-results.png" />
-<img src="graphs/BubbleSortcl-results.png" />
-<img src="graphs/Mandelbrotcl-results.png" />
-<img src="graphs/QuickSortcl-results.png" />
-<img src="graphs/Takcl-results.png" />
-<img src="graphs/cl-results.png" />
-<img src="graphs/DeltaBluecl-results.png" />
-<img src="graphs/Meteorcl-results.png" />
-<img src="graphs/Recursecl-results.png" />
-<img src="graphs/Taklcl-results.png" />
-<img src="graphs/code-time-size.png" />
-</body>
-</html>
diff --git a/tools/testing/perf_testing/run_perf_tests.py b/tools/testing/perf_testing/run_perf_tests.py
deleted file mode 100755
index 194bbbc..0000000
--- a/tools/testing/perf_testing/run_perf_tests.py
+++ /dev/null
@@ -1,1087 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import datetime
-import math
-import optparse
-import os
-from os.path import dirname, abspath
-import pickle
-import platform
-import random
-import re
-import shutil
-import stat
-import subprocess
-import sys
-import time
-
-TOOLS_PATH = os.path.join(dirname(dirname(dirname(abspath(__file__)))))
-TOP_LEVEL_DIR = abspath(os.path.join(dirname(abspath(__file__)), '..', '..',
-                                             '..'))
-DART_REPO_LOC = abspath(os.path.join(dirname(abspath(__file__)), '..', '..',
-                                             '..', '..', '..',
-                                             'dart_checkout_for_perf_testing',
-                                             'dart'))
-# How far back in time we want to test.
-EARLIEST_REVISION = 33076
-sys.path.append(TOOLS_PATH)
-sys.path.append(os.path.join(TOP_LEVEL_DIR, 'internal', 'tests'))
-import post_results
-import utils
-
-"""This script runs to track performance and size progress of
-different svn revisions. It tests to see if there a newer version of the code on
-the server, and will sync and run the performance tests if so."""
-class TestRunner(object):
-
-  def __init__(self):
-    self.verbose = False
-    self.has_shell = False
-    if platform.system() == 'Windows':
-      # On Windows, shell must be true to get the correct environment variables.
-      self.has_shell = True
-    self.current_revision_num = None
-
-  def RunCmd(self, cmd_list, outfile=None, append=False, std_in=''):
-    """Run the specified command and print out any output to stdout.
-
-    Args:
-      cmd_list: a list of strings that make up the command to run
-      outfile: a string indicating the name of the file that we should write
-         stdout to
-      append: True if we want to append to the file instead of overwriting it
-      std_in: a string that should be written to the process executing to
-         interact with it (if needed)"""
-    if self.verbose:
-      print ' '.join(cmd_list)
-    out = subprocess.PIPE
-    if outfile:
-      mode = 'w'
-      if append:
-        mode = 'a+'
-      out = open(outfile, mode)
-      if append:
-        # Annoying Windows "feature" -- append doesn't actually append unless
-        # you explicitly go to the end of the file.
-        # http://mail.python.org/pipermail/python-list/2009-October/1221859.html
-        out.seek(0, os.SEEK_END)
-    p = subprocess.Popen(cmd_list, stdout = out, stderr=subprocess.PIPE,
-                         stdin=subprocess.PIPE, shell=self.has_shell)
-    output, stderr = p.communicate(std_in)
-    if output:
-      print output
-    if stderr:
-      print stderr
-    return output, stderr
-
-  def RunBrowserPerfRunnerCmd(self, browser, url_path, file_path_to_test_code,
-      trace_file, code_root=''):
-    command_list = [os.path.join(DART_REPO_LOC, utils.GetBuildRoot(
-        utils.GuessOS(), 'release', 'ia32'), 'dart-sdk', 'bin', 'dart'),
-        '--package-root=%s' % os.path.join(file_path_to_test_code, 'packages'),
-        os.path.join(file_path_to_test_code, 'packages',
-        'browser_controller', 'browser_perf_testing.dart'), '--browser',
-        browser, '--test_path=%s' % url_path]
-    if code_root != '':
-      command_list += ['--code_root=%s' % code_root]
-
-    if browser == 'dartium':
-      dartium_path = os.path.join(DART_REPO_LOC, 'client', 'tests', 'dartium')
-      if platform.system() == 'Windows':
-        dartium_path = os.path.join(dartium_path, 'chrome.exe');
-      elif platform.system() == 'Darwin':
-        dartium_path = os.path.join(dartium_path, 'Chromium.app', 'Contents',
-            'MacOS', 'Chromium')
-      else:
-        dartium_path = os.path.join(dartium_path, 'chrome')
-      command_list += ['--executable=%s' % dartium_path]
-
-    self.RunCmd(command_list, trace_file, append=True)
-
-  def TimeCmd(self, cmd):
-    """Determine the amount of (real) time it takes to execute a given
-    command."""
-    start = time.time()
-    self.RunCmd(cmd)
-    return time.time() - start
-
-  def ClearOutUnversionedFiles(self):
-    """Remove all files that are unversioned by svn."""
-    if os.path.exists(DART_REPO_LOC):
-      os.chdir(DART_REPO_LOC)
-      results, _ = self.RunCmd(['svn', 'st'])
-      for line in results.split('\n'):
-        if line.startswith('?'):
-          to_remove = line.split()[1]
-          if os.path.isdir(to_remove):
-            shutil.rmtree(to_remove, onerror=TestRunner._OnRmError)
-          else:
-            os.remove(to_remove)
-        elif any(line.startswith(status) for status in ['A', 'M', 'C', 'D']):
-          self.RunCmd(['svn', 'revert', line.split()[1]])
-
-  def GetArchive(self, archive_name):
-    """Wrapper around the pulling down a specific archive from Google Storage.
-    Adds a specific revision argument as needed.
-    Returns: A tuple of a boolean (True if we successfully downloaded the
-    binary), and the stdout and stderr from running this command."""
-    num_fails = 0
-    while True:
-      cmd = ['python', os.path.join(DART_REPO_LOC, 'tools', 'get_archive.py'),
-             archive_name]
-      if int(self.current_revision_num) != -1:
-        cmd += ['-r', str(self.current_revision_num)]
-      stdout, stderr = self.RunCmd(cmd)
-      if 'Please try again later' in stdout and num_fails < 20:
-        time.sleep(100)
-        num_fails += 1
-      else:
-        break
-    return (num_fails < 20, stdout, stderr)
-
-  def _Sync(self, revision_num=None):
-    """Update the repository to the latest or specified revision."""
-    os.chdir(dirname(DART_REPO_LOC))
-    self.ClearOutUnversionedFiles()
-    if not revision_num:
-      self.RunCmd(['gclient', 'sync'])
-    else:
-      self.RunCmd(['gclient', 'sync', '-r', str(revision_num), '-t'])
-
-    shutil.copytree(os.path.join(TOP_LEVEL_DIR, 'internal'),
-                    os.path.join(DART_REPO_LOC, 'internal'))
-    shutil.rmtree(os.path.join(DART_REPO_LOC, 'third_party', 'gsutil'),
-                  onerror=TestRunner._OnRmError)
-    shutil.copytree(os.path.join(TOP_LEVEL_DIR, 'third_party', 'gsutil'),
-                    os.path.join(DART_REPO_LOC, 'third_party', 'gsutil'))
-    shutil.copy(os.path.join(TOP_LEVEL_DIR, 'tools', 'get_archive.py'),
-                    os.path.join(DART_REPO_LOC, 'tools', 'get_archive.py'))
-    shutil.copy(
-        os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'run_selenium.py'),
-        os.path.join(DART_REPO_LOC, 'tools', 'testing', 'run_selenium.py'))
-
-  @staticmethod
-  def _OnRmError(func, path, exc_info):
-    """On Windows, the output directory is marked as "Read Only," which causes
-    an error to be thrown when we use shutil.rmtree. This helper function
-    changes the permissions so we can still delete the directory."""
-    if os.path.exists(path):
-      os.chmod(path, stat.S_IWRITE)
-      os.unlink(path)
-
-  def SyncAndBuild(self, suites, revision_num=None):
-    """Make sure we have the latest version of of the repo, and build it. We
-    begin and end standing in DART_REPO_LOC.
-
-    Args:
-      suites: The set of suites that we wish to build.
-
-    Returns:
-      err_code = 1 if there was a problem building."""
-    self._Sync(revision_num)
-    if not revision_num:
-      revision_num = SearchForRevision()
-
-    self.current_revision_num = revision_num
-    success, stdout, stderr = self.GetArchive('sdk')
-    if (not os.path.exists(os.path.join(
-        DART_REPO_LOC, 'tools', 'get_archive.py')) or not success
-        or 'InvalidUriError' in stderr or "Couldn't download" in stdout or
-        'Unable to download' in stdout):
-      # Couldn't find the SDK on Google Storage. Build it locally.
-
-      # TODO(efortuna): Currently always building ia32 architecture because we
-      # don't have test statistics for what's passing on x64. Eliminate arch
-      # specification when we have tests running on x64, too.
-      shutil.rmtree(os.path.join(os.getcwd(),
-                    utils.GetBuildRoot(utils.GuessOS())),
-                    onerror=TestRunner._OnRmError)
-      lines = self.RunCmd(['python', os.path.join('tools', 'build.py'), '-m',
-                            'release', '--arch=ia32', 'create_sdk'])
-
-      for line in lines:
-        if 'BUILD FAILED' in line:
-          # Someone checked in a broken build! Stop trying to make it work
-          # and wait to try again.
-          print 'Broken Build'
-          return 1
-    return 0
-
-  def EnsureOutputDirectory(self, dir_name):
-    """Test that the listed directory name exists, and if not, create one for
-    our output to be placed.
-
-    Args:
-      dir_name: the directory we will create if it does not exist."""
-    dir_path = os.path.join(TOP_LEVEL_DIR, 'tools',
-                            'testing', 'perf_testing', dir_name)
-    if not os.path.exists(dir_path):
-      os.makedirs(dir_path)
-      print 'Creating output directory ', dir_path
-
-  def HasInterestingCode(self, revision_num=None):
-    """Tests if there are any versions of files that might change performance
-    results on the server.
-
-    Returns:
-       (False, None): There is no interesting code to run.
-       (True, revisionNumber): There is interesting code to run at revision
-                              revisionNumber.
-       (True, None): There is interesting code to run by syncing to the
-                     tip-of-tree."""
-    if not os.path.exists(DART_REPO_LOC):
-      self._Sync()
-    os.chdir(DART_REPO_LOC)
-    no_effect = ['dart/client', 'dart/compiler', 'dart/editor',
-                 'dart/lib/html/doc', 'dart/pkg', 'dart/tests', 'dart/samples',
-                 'dart/lib/dartdoc', 'dart/lib/i18n', 'dart/lib/unittest',
-                 'dart/tools/dartc', 'dart/tools/get_archive.py',
-                 'dart/tools/test.py', 'dart/tools/testing',
-                 'dart/tools/utils', 'dart/third_party', 'dart/utils']
-    definitely_yes = ['dart/samples/third_party/dromaeo',
-                      'dart/lib/html/dart2js', 'dart/lib/html/dartium',
-                      'dart/lib/scripts', 'dart/lib/src',
-                      'dart/third_party/WebCore']
-    def GetFileList(revision):
-      """Determine the set of files that were changed for a particular
-      revision."""
-      # TODO(efortuna): This assumes you're using svn. Have a git fallback as
-      # well. Pass 'p' in if we have a new certificate for the svn server, we
-      # want to (p)ermanently accept it.
-      results, _ = self.RunCmd([
-          'svn', 'log', 'http://dart.googlecode.com/svn/branches/bleeding_edge',
-          '-v', '-r', str(revision)], std_in='p\r\n')
-      results = results.split('\n')
-      if len(results) <= 3:
-        return []
-      else:
-        # Trim off the details about revision number and commit message. We're
-        # only interested in the files that are changed.
-        results = results[3:]
-        changed_files = []
-        for result in results:
-          if len(result) <= 1:
-            break
-          tokens = result.split()
-          if len(tokens) > 1:
-            changed_files += [tokens[1].replace('/branches/bleeding_edge/', '')]
-        return changed_files
-
-    def HasPerfAffectingResults(files_list):
-      """Determine if this set of changed files might effect performance
-      tests."""
-      def IsSafeFile(f):
-        if not any(f.startswith(prefix) for prefix in definitely_yes):
-          return any(f.startswith(prefix) for prefix in no_effect)
-        return False
-      return not all(IsSafeFile(f) for f in files_list)
-
-    if revision_num:
-      return (HasPerfAffectingResults(GetFileList(
-          revision_num)), revision_num)
-    else:
-      latest_interesting_server_rev = None
-      while not latest_interesting_server_rev:
-        results, _ = self.RunCmd(['svn', 'st', '-u'], std_in='p\r\n')
-        if len(results.split('\n')) >= 2:
-          latest_interesting_server_rev = int(
-              results.split('\n')[-2].split()[-1])
-      if self.backfill:
-        done_cls = list(UpdateSetOfDoneCls())
-        done_cls.sort()
-        if done_cls:
-          last_done_cl = int(done_cls[-1])
-        else:
-          last_done_cl = EARLIEST_REVISION
-        while latest_interesting_server_rev >= last_done_cl:
-          file_list = GetFileList(latest_interesting_server_rev)
-          if HasPerfAffectingResults(file_list):
-            return (True, latest_interesting_server_rev)
-          else:
-            UpdateSetOfDoneCls(latest_interesting_server_rev)
-          latest_interesting_server_rev -= 1
-      else:
-        last_done_cl = int(SearchForRevision(DART_REPO_LOC)) + 1
-        while last_done_cl <= latest_interesting_server_rev:
-          file_list = GetFileList(last_done_cl)
-          if HasPerfAffectingResults(file_list):
-            return (True, last_done_cl)
-          else:
-            UpdateSetOfDoneCls(last_done_cl)
-          last_done_cl += 1
-      return (False, None)
-
-  def GetOsDirectory(self):
-    """Specifies the name of the directory for the testing build of dart, which
-    has yet a different naming convention from utils.getBuildRoot(...)."""
-    if platform.system() == 'Windows':
-      return 'windows'
-    elif platform.system() == 'Darwin':
-      return 'macos'
-    else:
-      return 'linux'
-
-  def ParseArgs(self):
-    parser = optparse.OptionParser()
-    parser.add_option('--suites', '-s', dest='suites', help='Run the specified '
-                      'comma-separated test suites from set: %s' % \
-                      ','.join(TestBuilder.AvailableSuiteNames()),
-                      action='store', default=None)
-    parser.add_option('--forever', '-f', dest='continuous', help='Run this scri'
-                      'pt forever, always checking for the next svn checkin',
-                      action='store_true', default=False)
-    parser.add_option('--nobuild', '-n', dest='no_build', action='store_true',
-                      help='Do not sync with the repository and do not '
-                      'rebuild.', default=False)
-    parser.add_option('--noupload', '-u', dest='no_upload', action='store_true',
-                      help='Do not post the results of the run.', default=False)
-    parser.add_option('--notest', '-t', dest='no_test', action='store_true',
-                      help='Do not run the tests.', default=False)
-    parser.add_option('--verbose', '-v', dest='verbose',
-                      help='Print extra debug output', action='store_true',
-                      default=False)
-    parser.add_option('--backfill', '-b', dest='backfill',
-                      help='Backfill earlier CLs with additional results when '
-                      'there is idle time.', action='store_true',
-                      default=False)
-
-    args, ignored = parser.parse_args()
-
-    if not args.suites:
-      suites = TestBuilder.AvailableSuiteNames()
-    else:
-      suites = []
-      suitelist = args.suites.split(',')
-      for name in suitelist:
-        if name in TestBuilder.AvailableSuiteNames():
-          suites.append(name)
-        else:
-          print ('Error: Invalid suite %s not in ' % name) + \
-              '%s' % ','.join(TestBuilder.AvailableSuiteNames())
-          sys.exit(1)
-    self.suite_names = suites
-    self.no_build = args.no_build
-    self.no_upload = args.no_upload
-    self.no_test = args.no_test
-    self.verbose = args.verbose
-    self.backfill = args.backfill
-    return args.continuous
-
-  def RunTestSequence(self, revision_num=None, num_reruns=1):
-    """Run the set of commands to (possibly) build, run, and post the results
-    of our tests. Returns 0 on a successful run, 1 if we fail to post results or
-    the run failed, -1 if the build is broken.
-    """
-    suites = []
-    success = True
-    if not self.no_build and self.SyncAndBuild(suites, revision_num) == 1:
-      return -1 # The build is broken.
-
-    if not self.current_revision_num:
-      self.current_revision_num = SearchForRevision(DART_REPO_LOC)
-
-    for name in self.suite_names:
-      for run in range(num_reruns):
-        suites += [TestBuilder.MakeTest(name, self)]
-
-    for test in suites:
-      success = success and test.Run()
-    if success:
-      return 0
-    else:
-      return 1
-
-
-class Test(object):
-  """The base class to provide shared code for different tests we will run and
-  post. At a high level, each test has three visitors (the tester and the
-  file_processor) that perform operations on the test object."""
-
-  def __init__(self, result_folder_name, platform_list, variants,
-               values_list, test_runner, tester, file_processor,
-               extra_metrics=['Geo-Mean']):
-    """Args:
-         result_folder_name: The name of the folder where a tracefile of
-             performance results will be stored.
-         platform_list: A list containing the platform(s) that our data has been
-             run on. (command line, firefox, chrome, etc)
-         variants: A list specifying whether we hold data about Frog
-             generated code, plain JS code, or a combination of both, or
-             Dart depending on the test.
-         values_list: A list containing the type of data we will be graphing
-             (benchmarks, percentage passing, etc).
-         test_runner: Reference to the parent test runner object that notifies a
-             test when to run.
-         tester: The visitor that actually performs the test running mechanics.
-         file_processor: The visitor that processes files in the format
-             appropriate for this test.
-         extra_metrics: A list of any additional measurements we wish to keep
-             track of (such as the geometric mean of a set, the sum, etc)."""
-    self.result_folder_name = result_folder_name
-    # cur_time is used as a timestamp of when this performance test was run.
-    self.cur_time = str(time.mktime(datetime.datetime.now().timetuple()))
-    self.values_list = values_list
-    self.platform_list = platform_list
-    self.test_runner = test_runner
-    self.tester = tester
-    self.file_processor = file_processor
-    self.revision_dict = dict()
-    self.values_dict = dict()
-    self.extra_metrics = extra_metrics
-    # Initialize our values store.
-    for platform in platform_list:
-      self.revision_dict[platform] = dict()
-      self.values_dict[platform] = dict()
-      for f in variants:
-        self.revision_dict[platform][f] = dict()
-        self.values_dict[platform][f] = dict()
-        for val in values_list:
-          self.revision_dict[platform][f][val] = []
-          self.values_dict[platform][f][val] = []
-        for extra_metric in extra_metrics:
-          self.revision_dict[platform][f][extra_metric] = []
-          self.values_dict[platform][f][extra_metric] = []
-
-  def IsValidCombination(self, platform, variant):
-    """Check whether data should be captured for this platform/variant
-    combination.
-    """
-    if variant == 'dart_html' and platform != 'dartium':
-      return False
-    if platform == 'dartium' and (variant == 'js' or variant == 'dart2js_html'):
-      # Testing JavaScript performance on Dartium is a waste of time. Should be
-      # same as Chrome.
-      return False
-    if (platform == 'safari' and variant == 'dart2js' and
-        int(self.test_runner.current_revision_num) < 10193):
-      # In revision 10193 we fixed a bug that allows Safari 6 to run dart2js
-      # code. Since we can't change the Safari version on the machine, we're
-      # just not running
-      # for this case.
-      return False
-    return True
-
-  def Run(self):
-    """Run the benchmarks/tests from the command line and plot the
-    results.
-    """
-    for visitor in [self.tester, self.file_processor]:
-      visitor.Prepare()
-
-    os.chdir(TOP_LEVEL_DIR)
-    self.test_runner.EnsureOutputDirectory(self.result_folder_name)
-    self.test_runner.EnsureOutputDirectory(os.path.join(
-        'old', self.result_folder_name))
-    os.chdir(DART_REPO_LOC)
-    if not self.test_runner.no_test:
-      self.tester.RunTests()
-
-    os.chdir(os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'perf_testing'))
-
-    files = os.listdir(self.result_folder_name)
-    post_success = True
-    for afile in files:
-      if not afile.startswith('.'):
-        should_move_file = self.file_processor.ProcessFile(afile, True)
-        if should_move_file:
-          shutil.move(os.path.join(self.result_folder_name, afile),
-                      os.path.join('old', self.result_folder_name, afile))
-        else:
-          post_success = False
-
-    return post_success
-
-
-class Tester(object):
-  """The base level visitor class that runs tests. It contains convenience
-  methods that many Tester objects use. Any class that would like to be a
-  TesterVisitor must implement the RunTests() method."""
-
-  def __init__(self, test):
-    self.test = test
-
-  def Prepare(self):
-    """Perform any initial setup required before the test is run."""
-    pass
-
-  def AddSvnRevisionToTrace(self, outfile, browser = None):
-    """Add the svn version number to the provided tracefile."""
-    def get_dartium_revision():
-      version_file_name = os.path.join(DART_REPO_LOC, 'client', 'tests',
-                                       'dartium', 'LAST_VERSION')
-      try:
-        version_file = open(version_file_name, 'r')
-        version = version_file.read().split('.')[-3].split('-')[-1]
-        version_file.close()
-        return version
-      except IOError as e:
-        dartium_dir = os.path.join(DART_REPO_LOC, 'client', 'tests', 'dartium')
-        if (os.path.exists(os.path.join(dartium_dir, 'Chromium.app', 'Contents',
-            'MacOS', 'Chromium') or os.path.exists(os.path.join(dartium_dir,
-            'chrome.exe'))) or
-            os.path.exists(os.path.join(dartium_dir, 'chrome'))):
-          print "Error: VERSION file wasn't found."
-          return SearchForRevision()
-        else:
-          raise
-
-    if browser and browser == 'dartium':
-      revision = get_dartium_revision()
-      self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile)
-    else:
-      revision = SearchForRevision()
-      self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile)
-
-
-class Processor(object):
-  """The base level vistor class that processes tests. It contains convenience
-  methods that many File Processor objects use. Any class that would like to be
-  a ProcessorVisitor must implement the ProcessFile() method."""
-
-  SCORE = 'Score'
-  COMPILE_TIME = 'CompileTime'
-  CODE_SIZE = 'CodeSize'
-
-  def __init__(self, test):
-    self.test = test
-
-  def Prepare(self):
-    """Perform any initial setup required before the test is run."""
-    pass
-
-  def OpenTraceFile(self, afile, not_yet_uploaded):
-    """Find the correct location for the trace file, and open it.
-    Args:
-      afile: The tracefile name.
-      not_yet_uploaded: True if this file is to be found in a directory that
-         contains un-uploaded data.
-    Returns: A file object corresponding to the given file name."""
-    file_path = os.path.join(self.test.result_folder_name, afile)
-    if not not_yet_uploaded:
-      file_path = os.path.join('old', file_path)
-    return open(file_path)
-
-  def ReportResults(self, benchmark_name, score, platform, variant,
-                     revision_number, metric):
-    """Store the results of the benchmark run.
-    Args:
-      benchmark_name: The name of the individual benchmark.
-      score: The numerical value of this benchmark.
-      platform: The platform the test was run on (firefox, command line, etc).
-      variant: Specifies whether the data was about generated Frog, js, a
-          combination of both, or Dart depending on the test.
-      revision_number: The revision of the code (and sometimes the revision of
-          dartium).
-
-    Returns: True if the post was successful file."""
-    return post_results.report_results(benchmark_name, score, platform, variant,
-                                       revision_number, metric)
-
-  def CalculateGeometricMean(self, platform, variant, svn_revision):
-    """Calculate the aggregate geometric mean for JS and dart2js benchmark sets,
-    given two benchmark dictionaries."""
-    geo_mean = 0
-    if self.test.IsValidCombination(platform, variant):
-      for benchmark in self.test.values_list:
-        if not self.test.values_dict[platform][variant][benchmark]:
-          print 'Error determining mean for %s %s %s' % (platform, variant,
-                                                         benchmark)
-          continue
-        geo_mean += math.log(
-            self.test.values_dict[platform][variant][benchmark][-1])
-
-    self.test.values_dict[platform][variant]['Geo-Mean'] += \
-        [math.pow(math.e, geo_mean / len(self.test.values_list))]
-    self.test.revision_dict[platform][variant]['Geo-Mean'] += [svn_revision]
-
-  def GetScoreType(self, benchmark_name):
-    """Determine the type of score for posting -- default is 'Score' (aka
-    Runtime), other options are CompileTime and CodeSize."""
-    return self.SCORE
-
-
-class RuntimePerformanceTest(Test):
-  """Super class for all runtime performance testing."""
-
-  def __init__(self, result_folder_name, platform_list, platform_type,
-               versions, benchmarks, test_runner, tester, file_processor):
-    """Args:
-        result_folder_name: The name of the folder where a tracefile of
-            performance results will be stored.
-        platform_list: A list containing the platform(s) that our data has been
-            run on. (command line, firefox, chrome, etc)
-        variants: A list specifying whether we hold data about Frog
-            generated code, plain JS code, or a combination of both, or
-            Dart depending on the test.
-        values_list: A list containing the type of data we will be graphing
-            (benchmarks, percentage passing, etc).
-        test_runner: Reference to the parent test runner object that notifies a
-            test when to run.
-        tester: The visitor that actually performs the test running mechanics.
-        file_processor: The visitor that processes files in the format
-            appropriate for this test.
-        extra_metrics: A list of any additional measurements we wish to keep
-            track of (such as the geometric mean of a set, the sum, etc)."""
-    super(RuntimePerformanceTest, self).__init__(result_folder_name,
-          platform_list, versions, benchmarks, test_runner, tester,
-          file_processor)
-    self.platform_list = platform_list
-    self.platform_type = platform_type
-    self.versions = versions
-    self.benchmarks = benchmarks
-
-
-class BrowserTester(Tester):
-  @staticmethod
-  def GetBrowsers(add_dartium=True):
-    browsers = ['ff', 'chrome']
-    if add_dartium:
-      browsers += ['dartium']
-    has_shell = False
-    if platform.system() == 'Darwin':
-      browsers += ['safari']
-    if platform.system() == 'Windows':
-      browsers += ['ie']
-      has_shell = True
-    return browsers
-
-
-class DromaeoTester(Tester):
-  DROMAEO_BENCHMARKS = {
-      'attr': ('attributes', [
-          'getAttribute',
-          'element.property',
-          'setAttribute',
-          'element.property = value']),
-      'modify': ('modify', [
-          'createElement',
-          'createTextNode',
-          'innerHTML',
-          'cloneNode',
-          'appendChild',
-          'insertBefore']),
-      'query': ('query', [
-          'getElementById',
-          'getElementById (not in document)',
-          'getElementsByTagName(div)',
-          'getElementsByTagName(p)',
-          'getElementsByTagName(a)',
-          'getElementsByTagName(*)',
-          'getElementsByTagName (not in document)',
-          'getElementsByName',
-          'getElementsByName (not in document)']),
-      'traverse': ('traverse', [
-          'firstChild',
-          'lastChild',
-          'nextSibling',
-          'previousSibling',
-          'childNodes'])
-  }
-
-  # Use filenames that don't have unusual characters for benchmark names.
-  @staticmethod
-  def LegalizeFilename(str):
-    remap = {
-        ' ': '_',
-        '(': '_',
-        ')': '_',
-        '*': 'ALL',
-        '=': 'ASSIGN',
-        }
-    for (old, new) in remap.iteritems():
-      str = str.replace(old, new)
-    return str
-
-  # TODO(vsm): This is a hack to skip breaking tests.  Triage this
-  # failure properly.  The modify suite fails on 32-bit chrome, which
-  # is the default on mac and win.
-  @staticmethod
-  def GetValidDromaeoTags():
-    tags = [tag for (tag, _) in DromaeoTester.DROMAEO_BENCHMARKS.values()]
-    if platform.system() == 'Darwin' or platform.system() == 'Windows':
-      tags.remove('modify')
-    return tags
-
-  @staticmethod
-  def GetDromaeoBenchmarks():
-    valid = DromaeoTester.GetValidDromaeoTags()
-    benchmarks = reduce(lambda l1,l2: l1+l2,
-                        [tests for (tag, tests) in
-                         DromaeoTester.DROMAEO_BENCHMARKS.values()
-                         if tag in valid])
-    return map(DromaeoTester.LegalizeFilename, benchmarks)
-
-  @staticmethod
-  def GetDromaeoVersions():
-    return ['js', 'dart2js_html', 'dart_html']
-
-
-class DromaeoTest(RuntimePerformanceTest):
-  """Runs Dromaeo tests, in the browser."""
-  def __init__(self, test_runner):
-    super(DromaeoTest, self).__init__(
-        self.Name(),
-        BrowserTester.GetBrowsers(True),
-        'browser',
-        DromaeoTester.GetDromaeoVersions(),
-        DromaeoTester.GetDromaeoBenchmarks(), test_runner,
-        self.DromaeoPerfTester(self),
-        self.DromaeoFileProcessor(self))
-
-  @staticmethod
-  def Name():
-    return 'dromaeo'
-
-  class DromaeoPerfTester(DromaeoTester):
-    def RunTests(self):
-      """Run dromaeo in the browser."""
-      success, _, _ = self.test.test_runner.GetArchive('dartium')
-      if not success:
-        # Unable to download dartium. Try later.
-        return
-
-      # Build tests.
-      current_path = os.getcwd()
-      os.chdir(os.path.join(DART_REPO_LOC, 'samples', 'third_party',
-          'dromaeo'))
-      # Note: This uses debug on purpose, so that we can also run performance
-      # tests on pure Dart applications in Dartium. Pub --debug simply also
-      # moves the .dart files to the build directory. To ensure effective
-      # comparison, though, ensure that minify: true is set in your transformer
-      # compilation step in your pubspec.
-      stdout, _ = self.test.test_runner.RunCmd([os.path.join(DART_REPO_LOC,
-          utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'),
-          'dart-sdk', 'bin', 'pub'), 'build', '--mode=debug'])
-      os.chdir(current_path)
-      if 'failed' in stdout:
-        return
-
-      versions = DromaeoTester.GetDromaeoVersions()
-
-      for browser in BrowserTester.GetBrowsers():
-        for version_name in versions:
-          if not self.test.IsValidCombination(browser, version_name):
-            continue
-          version = DromaeoTest.DromaeoPerfTester.GetDromaeoUrlQuery(
-              browser, version_name)
-          self.test.trace_file = os.path.join(TOP_LEVEL_DIR,
-              'tools', 'testing', 'perf_testing', self.test.result_folder_name,
-              'dromaeo-%s-%s-%s' % (self.test.cur_time, browser, version_name))
-          self.AddSvnRevisionToTrace(self.test.trace_file, browser)
-          url_path = '/'.join(['/code_root', 'build', 'web', 'index%s.html?%s'%(
-              '-dart' if version_name == 'dart_html' else '-js',
-              version)])
-
-          self.test.test_runner.RunBrowserPerfRunnerCmd(browser, url_path,
-              os.path.join(DART_REPO_LOC, 'samples', 'third_party', 'dromaeo'),
-              self.test.trace_file)
-
-    @staticmethod
-    def GetDromaeoUrlQuery(browser, version):
-      version = version.replace('_','AND')
-      tags = DromaeoTester.GetValidDromaeoTags()
-      return 'OR'.join([ '%sAND%s' % (version, tag) for tag in tags])
-
-
-  class DromaeoFileProcessor(Processor):
-    def ProcessFile(self, afile, should_post_file):
-      """Comb through the html to find the performance results.
-      Returns: True if we successfully posted our data to storage."""
-      parts = afile.split('-')
-      browser = parts[2]
-      version = parts[3]
-
-      bench_dict = self.test.values_dict[browser][version]
-
-      f = self.OpenTraceFile(afile, should_post_file)
-      lines = f.readlines()
-      i = 0
-      revision_num = 0
-      revision_pattern = r'Revision: (\d+)'
-      suite_pattern = r'<div class="result-item done">(.+?)</ol></div>'
-      result_pattern = r'<b>(.+?)</b>(.+?)<small> runs/s(.+)'
-
-      upload_success = True
-      for line in lines:
-        rev = re.match(revision_pattern, line.strip().replace('"', ''))
-        if rev:
-          revision_num = int(rev.group(1))
-          continue
-
-        suite_results = re.findall(suite_pattern, line)
-        if suite_results:
-          for suite_result in suite_results:
-            results = re.findall(r'<li>(.*?)</li>', suite_result)
-            if results:
-              for result in results:
-                r = re.match(result_pattern, result)
-                name = DromaeoTester.LegalizeFilename(r.group(1).strip(':'))
-                score = float(r.group(2))
-                bench_dict[name] += [float(score)]
-                self.test.revision_dict[browser][version][name] += \
-                    [revision_num]
-                if not self.test.test_runner.no_upload and should_post_file:
-                  upload_success = upload_success and self.ReportResults(
-                      name, score, browser, version, revision_num,
-                      self.GetScoreType(name))
-                else:
-                  upload_success = False
-
-      f.close()
-      self.CalculateGeometricMean(browser, version, revision_num)
-      return upload_success
-
-class TodoMVCTester(BrowserTester):
-    @staticmethod
-    def GetVersions():
-      return ['js', 'dart2js_html', 'dart_html']
-
-    @staticmethod
-    def GetBenchmarks():
-      return ['TodoMVCstartup']
-
-class TodoMVCStartupTest(RuntimePerformanceTest):
-  """Start up TodoMVC and see how long it takes to start."""
-  def __init__(self, test_runner):
-    super(TodoMVCStartupTest, self).__init__(
-        self.Name(),
-        BrowserTester.GetBrowsers(True),
-        'browser',
-        TodoMVCTester.GetVersions(),
-        TodoMVCTester.GetBenchmarks(), test_runner,
-        self.TodoMVCStartupTester(self),
-        self.TodoMVCFileProcessor(self))
-
-  @staticmethod
-  def Name():
-    return 'todoMvcStartup'
-
-  class TodoMVCStartupTester(BrowserTester):
-    def RunTests(self):
-      """Run dromaeo in the browser."""
-      success, _, _ = self.test.test_runner.GetArchive('dartium')
-      if not success:
-        # Unable to download dartium. Try later.
-        return
-
-      dromaeo_path = os.path.join('samples', 'third_party', 'dromaeo')
-      current_path = os.getcwd()
-
-      os.chdir(os.path.join(DART_REPO_LOC, 'samples', 'third_party',
-          'todomvc_performance'))
-      self.test.test_runner.RunCmd([os.path.join(DART_REPO_LOC,
-          utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'),
-          'dart-sdk', 'bin', 'pub'), 'build', '--mode=debug'])
-      os.chdir('js_todomvc');
-      self.test.test_runner.RunCmd([os.path.join(DART_REPO_LOC,
-          utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'),
-          'dart-sdk', 'bin', 'pub'), 'get'])
-
-      versions = TodoMVCTester.GetVersions()
-
-      for browser in BrowserTester.GetBrowsers():
-        for version_name in versions:
-          if not self.test.IsValidCombination(browser, version_name):
-            continue
-          self.test.trace_file = os.path.join(TOP_LEVEL_DIR,
-              'tools', 'testing', 'perf_testing', self.test.result_folder_name,
-              'todoMvcStartup-%s-%s-%s' % (self.test.cur_time, browser,
-              version_name))
-          self.AddSvnRevisionToTrace(self.test.trace_file, browser)
-
-          if version_name == 'js':
-            code_root = os.path.join(DART_REPO_LOC, 'samples', 'third_party',
-                'todomvc_performance', 'js_todomvc')
-            self.test.test_runner.RunBrowserPerfRunnerCmd(browser,
-                '/code_root/index.html', code_root, self.test.trace_file,
-                code_root)
-          else:
-            self.test.test_runner.RunBrowserPerfRunnerCmd(browser,
-                '/code_root/build/web/startup-performance.html', os.path.join(
-                DART_REPO_LOC, 'samples', 'third_party', 'todomvc_performance'),
-                self.test.trace_file)
-
-  class TodoMVCFileProcessor(Processor):
-    def ProcessFile(self, afile, should_post_file):
-      """Comb through the html to find the performance results.
-      Returns: True if we successfully posted our data to storage."""
-      parts = afile.split('-')
-      browser = parts[2]
-      version = parts[3]
-
-      bench_dict = self.test.values_dict[browser][version]
-
-      f = self.OpenTraceFile(afile, should_post_file)
-      lines = f.readlines()
-      i = 0
-      revision_num = 0
-      revision_pattern = r'Revision: (\d+)'
-      result_pattern = r'The startup time is (\d+)'
-
-      upload_success = True
-      for line in lines:
-        rev = re.match(revision_pattern, line.strip().replace('"', ''))
-        if rev:
-          revision_num = int(rev.group(1))
-          continue
-
-        results = re.search(result_pattern, line)
-        if results:
-          score = float(results.group(1))
-          name = TodoMVCTester.GetBenchmarks()[0]
-          bench_dict[name] += [float(score)]
-          self.test.revision_dict[browser][version][name] += \
-              [revision_num]
-          if not self.test.test_runner.no_upload and should_post_file:
-            upload_success = upload_success and self.ReportResults(
-                name, score, browser, version, revision_num,
-                self.GetScoreType(name))
-
-      f.close()
-      self.CalculateGeometricMean(browser, version, revision_num)
-      return upload_success
-
-
-class TestBuilder(object):
-  """Construct the desired test object."""
-  available_suites = dict((suite.Name(), suite) for suite in [
-      DromaeoTest, TodoMVCStartupTest])
-
-  @staticmethod
-  def MakeTest(test_name, test_runner):
-    return TestBuilder.available_suites[test_name](test_runner)
-
-  @staticmethod
-  def AvailableSuiteNames():
-    return TestBuilder.available_suites.keys()
-
-
-def SearchForRevision(directory = None):
-  """Find the current revision number in the desired directory. If directory is
-  None, find the revision number in the current directory."""
-  def FindRevision(svn_info_command):
-    p = subprocess.Popen(svn_info_command, stdout = subprocess.PIPE,
-                         stderr = subprocess.STDOUT,
-                         shell = (platform.system() == 'Windows'))
-    output, _ = p.communicate()
-    for line in output.split('\n'):
-      if 'Revision' in line:
-        return int(line.split()[1])
-    return -1
-
-  cwd = os.getcwd()
-  if not directory:
-    directory = cwd
-  os.chdir(directory)
-  revision_num = int(FindRevision(['svn', 'info']))
-  if revision_num == -1:
-    revision_num = int(FindRevision(['git', 'svn', 'info']))
-  os.chdir(cwd)
-  return str(revision_num)
-
-
-def UpdateSetOfDoneCls(revision_num=None):
-  """Update the set of CLs that do not need additional performance runs.
-  Args:
-  revision_num: an additional number to be added to the 'done set'
-  """
-  filename = os.path.join(TOP_LEVEL_DIR, 'cached_results.txt')
-  if not os.path.exists(filename):
-    f = open(filename, 'w')
-    results = set()
-    pickle.dump(results, f)
-    f.close()
-  f = open(filename, 'r+')
-  result_set = pickle.load(f)
-  if revision_num:
-    f.seek(0)
-    result_set.add(revision_num)
-    pickle.dump(result_set, f)
-  f.close()
-  return result_set
-
-
-def FillInBackHistory(results_set, runner):
-  """Fill in back history performance data. This is done one of two ways, with
-  equal probability of trying each way (falling back on the sequential version
-  as our data becomes more densely populated)."""
-  revision_num = int(SearchForRevision(DART_REPO_LOC))
-  has_run_extra = False
-
-  def TryToRunAdditional(revision_number):
-    """Determine the number of results we have stored for a particular revision
-    number, and if it is less than 10, run some extra tests.
-    Args:
-      - revision_number: the revision whose performance we want to potentially
-        test.
-    Returns: True if we successfully ran some additional tests."""
-    if not runner.HasInterestingCode(revision_number)[0]:
-      results_set = UpdateSetOfDoneCls(revision_number)
-      return False
-    a_test = TestBuilder.MakeTest(runner.suite_names[0], runner)
-    benchmark_name = a_test.values_list[0]
-    platform_name = a_test.platform_list[0]
-    variant = a_test.values_dict[platform_name].keys()[0]
-    num_results = post_results.get_num_results(benchmark_name,
-        platform_name, variant, revision_number,
-        a_test.file_processor.GetScoreType(benchmark_name))
-    if num_results < 10:
-      # Run at most two more times.
-      if num_results > 8:
-        reruns = 10 - num_results
-      else:
-        reruns = 2
-      run = runner.RunTestSequence(revision_num=str(revision_number),
-          num_reruns=reruns)
-    if num_results >= 10 or run == 0 and num_results + reruns >= 10:
-      results_set = UpdateSetOfDoneCls(revision_number)
-    elif run != 0:
-      return False
-    return True
-
-  # Try to get up to 10 runs of each CL, starting with the most recent
-  # CL that does not yet have 10 runs. But only perform a set of extra
-  # runs at most 2 at a time before checking to see if new code has been
-  # checked in.
-  while revision_num > EARLIEST_REVISION and not has_run_extra:
-    if revision_num not in results_set:
-      has_run_extra = TryToRunAdditional(revision_num)
-    revision_num -= 1
-  if not has_run_extra:
-    # No more extra back-runs to do (for now). Wait for new code.
-    time.sleep(200)
-  return results_set
-
-
-def main():
-  runner = TestRunner()
-  continuous = runner.ParseArgs()
-
-  if not os.path.exists(DART_REPO_LOC):
-    os.mkdir(dirname(DART_REPO_LOC))
-    os.chdir(dirname(DART_REPO_LOC))
-    p = subprocess.Popen('gclient config https://dart.googlecode.com/svn/' +
-                         'branches/bleeding_edge/deps/all.deps',
-                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                         shell=True)
-    p.communicate()
-  if continuous:
-    while True:
-      results_set = UpdateSetOfDoneCls()
-      (is_interesting, interesting_rev_num) = runner.HasInterestingCode()
-      if is_interesting:
-        runner.RunTestSequence(interesting_rev_num)
-      else:
-        if runner.backfill:
-          results_set = FillInBackHistory(results_set, runner)
-        else:
-          time.sleep(200)
-  else:
-    runner.RunTestSequence()
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/testing/run_selenium.py b/tools/testing/run_selenium.py
index ba4cc6d..e270619 100755
--- a/tools/testing/run_selenium.py
+++ b/tools/testing/run_selenium.py
@@ -60,16 +60,10 @@
   source = source[index + len(string):end_index]
   return 'Score:' in source
 
-def dromaeo_test_done(source):
-  """Tests to see if our performance test is done by printing a score."""
-  #TODO(efortuna): Access these elements in a nicer way using DOM parser.
-  return '<body class="alldone">' in source
-
 # TODO(vsm): Ideally, this wouldn't live in this file.
 CONFIGURATIONS = {
     'correctness': correctness_test_done,
-    'perf': perf_test_done,
-    'dromaeo': dromaeo_test_done
+    'perf': perf_test_done
 }
 
 def run_test_in_browser(browser, html_out, timeout, mode, refresh):
@@ -247,7 +241,6 @@
   browser.quit()
 
 def report_results(mode, source, browser):
-  # TODO(vsm): Add a failure check for Dromaeo.
   if mode != 'correctness':
     # We're running a performance test.
     print source.encode('utf8')
diff --git a/tools/utils.py b/tools/utils.py
index 7b203aa..aaef94c 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -58,12 +58,12 @@
     return 'arm64'
   elif os_id.startswith('mips'):
     return 'mips'
+  elif '64' in os_id:
+    return 'x64'
   elif (not os_id) or (not re.match('(x|i[3-6])86', os_id) is None):
     return 'ia32'
   elif os_id == 'i86pc':
     return 'ia32'
-  elif '64' in os_id:
-    return 'x64'
   else:
     guess_os = GuessOS()
     print "Warning: Guessing architecture %s based on os %s\n"\
@@ -626,6 +626,8 @@
       name = 'dart-mips'
     elif arch == 'arm':
       name = 'dart-arm'
+    elif arch == 'arm64':
+      name = 'dart-arm'
   return os.path.join(CheckedInSdkPath(), 'bin', name)
 
 
@@ -634,8 +636,9 @@
   canary_script = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                'canary.dart')
   try:
-    if 42 == subprocess.call([executable, canary_script]):
-      return True
+    with open(os.devnull, 'wb') as silent_sink:
+      if 0 == subprocess.call([executable, canary_script], stdout=silent_sink):
+        return True
   except OSError as e:
     pass
   return False
diff --git a/utils/dartanalyzer/dartanalyzer.gyp b/utils/dartanalyzer/dartanalyzer.gyp
index 93dc15f..9617f05 100644
--- a/utils/dartanalyzer/dartanalyzer.gyp
+++ b/utils/dartanalyzer/dartanalyzer.gyp
@@ -18,7 +18,7 @@
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
             '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
             '<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
-            '<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../third_party/pkg/analyzer_cli"])',
+            '<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../pkg/analyzer_cli"])',
           ],
           'outputs': [
             '<(SHARED_INTERMEDIATE_DIR)/dartanalyzer.dart.snapshot',
@@ -27,7 +27,7 @@
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
             '--snapshot=<(SHARED_INTERMEDIATE_DIR)/dartanalyzer.dart.snapshot',
             '--package-root=<(PRODUCT_DIR)/packages/',
-            '../../third_party/pkg/analyzer_cli/bin/analyzer.dart',
+            '../../pkg/analyzer_cli/bin/analyzer.dart',
           ],
         },
       ],